From maz at kernel.org  Sun Dec  1 01:27:02 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun,  1 Dec 2024 09:27:02 +0000
Subject: [PATCH v2] arch_numa: Restore nid checks before registering a memblock with a node
Message-ID: <20241201092702.3792845-1-maz@kernel.org>

Commit 767507654c22 ("arch_numa: switch over to numa_memblks")
significantly cleaned up the NUMA registration code, but also
dropped a significant check that was refusing to accept to
configure a memblock with an invalid nid.

On "quality hardware" such as my ThunderX machine, this results
in a kernel that dies immediately:

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x431f0a10]
[    0.000000] Linux version 6.12.0-00013-g8920d74cf8db (maz at valley-girl) (gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #3872 SMP PREEMPT Wed Nov 27 15:25:49 GMT 2024
[    0.000000] KASLR disabled due to lack of seed
[    0.000000] Machine model: Cavium ThunderX CN88XX board
[    0.000000] efi: EFI v2.4 by American Megatrends
[    0.000000] efi: ESRT=0xffce0ff18 SMBIOS 3.0=0xfffb0000 ACPI 2.0=0xffec60000 MEMRESERVE=0xffc905d98
[    0.000000] esrt: Reserving ESRT space from 0x0000000ffce0ff18 to 0x0000000ffce0ff50.
[    0.000000] earlycon: pl11 at MMIO 0x000087e024000000 (options '115200n8')
[    0.000000] printk: legacy bootconsole [pl11] enabled
[    0.000000] NODE_DATA(0) allocated [mem 0xff6754580-0xff67566bf]
[    0.000000] Unable to handle kernel paging request at virtual address 0000000000001d40
[    0.000000] Mem abort info:
[    0.000000]   ESR = 0x0000000096000004
[    0.000000]   EC = 0x25: DABT (current EL), IL = 32 bits
[    0.000000]   SET = 0, FnV = 0
[    0.000000]   EA = 0, S1PTW = 0
[    0.000000]   FSC = 0x04: level 0 translation fault
[    0.000000] Data abort info:
[    0.000000]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[    0.000000]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[    0.000000]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[    0.000000] [0000000000001d40] user address but active_mm is swapper
[    0.000000] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.12.0-00013-g8920d74cf8db #3872
[    0.000000] Hardware name: Cavium ThunderX CN88XX board (DT)
[    0.000000] pstate: a00000c5 (NzCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[    0.000000] pc : sparse_init_nid+0x54/0x428
[    0.000000] lr : sparse_init+0x118/0x240
[    0.000000] sp : ffff800081da3cb0
[    0.000000] x29: ffff800081da3cb0 x28: 0000000fedbab10c x27: 0000000000000001
[    0.000000] x26: 0000000ffee250f8 x25: 0000000000000001 x24: ffff800082102cd0
[    0.000000] x23: 0000000000000001 x22: 0000000000000000 x21: 00000000001fffff
[    0.000000] x20: 0000000000000001 x19: 0000000000000000 x18: ffffffffffffffff
[    0.000000] x17: 0000000001b00000 x16: 0000000ffd130000 x15: 0000000000000000
[    0.000000] x14: 00000000003e0000 x13: 00000000000001c8 x12: 0000000000000014
[    0.000000] x11: ffff800081e82860 x10: ffff8000820fb2c8 x9 : ffff8000820fb490
[    0.000000] x8 : 0000000000ffed20 x7 : 0000000000000014 x6 : 00000000001fffff
[    0.000000] x5 : 00000000ffffffff x4 : 0000000000000000 x3 : 0000000000000000
[    0.000000] x2 : 0000000000000000 x1 : 0000000000000040 x0 : 0000000000000007
[    0.000000] Call trace:
[    0.000000]  sparse_init_nid+0x54/0x428
[    0.000000]  sparse_init+0x118/0x240
[    0.000000]  bootmem_init+0x70/0x1c8
[    0.000000]  setup_arch+0x184/0x270
[    0.000000]  start_kernel+0x74/0x670
[    0.000000]  __primary_switched+0x80/0x90
[    0.000000] Code: f865d804 d37df060 cb030000 d2800003 (b95d4084)
[    0.000000] ---[ end trace 0000000000000000 ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---

while previous kernel versions were able to recognise how brain-damaged
the machine is, and only build a fake node.

Use the memblock_validate_numa_coverage() helper to restore some sanity
and a "working" system.

Fixes: 767507654c22 ("arch_numa: switch over to numa_memblks")
Suggested-by: Mike Rapoport <rppt at kernel.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Zi Yan <ziy at nvidia.com>
Cc: Dan Williams <dan.j.williams at intel.com>
Cc: David Hildenbrand <david at redhat.com>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: stable at vger.kernel.org
---
 drivers/base/arch_numa.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
index e187016764265..c63a72a1fed64 100644
--- a/drivers/base/arch_numa.c
+++ b/drivers/base/arch_numa.c
@@ -208,6 +208,10 @@ static int __init numa_register_nodes(void)
 {
 	int nid;
 
+	/* Check the validity of the memblock/node mapping */
+	if (!memblock_validate_numa_coverage(1))
+		return -EINVAL;
+
 	/* Finally register nodes. */
 	for_each_node_mask(nid, numa_nodes_parsed) {
 		unsigned long start_pfn, end_pfn;
-- 
2.39.2



From tglx at linutronix.de  Sun Dec  1 03:19:34 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Sun, 01 Dec 2024 12:19:34 +0100
Subject: [PATCH v4 1/2] kexec: Consolidate
 machine_kexec_mask_interrupts() implementation
In-Reply-To: <cd8809e379dc4dd089350ec2d1f8c210@amazon.com>
References: <cd8809e379dc4dd089350ec2d1f8c210@amazon.com>
Message-ID: <87frn7wszd.ffs@tglx>

On Sat, Nov 30 2024 at 20:08, Eliav Farber wrote:
> On 11/29/2024 3:30 PM, Thomas Gleixner wrote:
>> Looking deeper. This function actually cannot be called from this
>> context. It does:
>>
>>           irq_get_desc_buslock(irq, &flags, 0);
>>
>> which means for any interrupt which has an actual buslock implementation
>> it will end up in a sleepable function and deadlock in the worst case.
>>
>> Marc?
> I will wait for Marc's response regarding this issue.
> Regardless, if any changes are required, I believe it would be better
> to address them in a separate patch, as this behavior existed before my
> modification.

Correct.


From maz at kernel.org  Sun Dec  1 04:21:29 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Dec 2024 12:21:29 +0000
Subject: [PATCH] KVM: arm64: Make the exposed feature bits in AA64DFR0_EL1 writable from userspace
In-Reply-To: <c879fda9-db5a-4743-805d-03c0acba8060@redhat.com>
References: <20240813142835.77180-1-shameerali.kolothum.thodi@huawei.com>
	<86v804z3lk.wl-maz@kernel.org>
	<b2dad37ac5464384abe4edf76cb6b546@huawei.com>
	<4d3a7dde-e085-fa70-8859-ba153c93b615@redhat.com>
	<87zfllssji.wl-maz@kernel.org>
	<c879fda9-db5a-4743-805d-03c0acba8060@redhat.com>
Message-ID: <865xo3vbjq.wl-maz@kernel.org>

Hey Eric,

On Thu, 28 Nov 2024 09:31:08 +0000,
Eric Auger <eauger at redhat.com> wrote:
> 
> Hi Marc,
> 
> On 11/26/24 20:29, Marc Zyngier wrote:
> > Finally, who is going to ensure this keeps working in the foreseeable
> > future? Because while this is nice, that's not what gets deployed in
> > production, as it leads to unpredictable performances. My take is that
> > this thing will eventually bitrot and die.
> In the context of our works to define qemu vcpu models for ARM
> (https://lore.kernel.org/all/20241025101959.601048-1-eric.auger at redhat.com/)
> , our current approach is to try migrating between modern HW we have
> access to. The case above is migration between AmpereOne and Grace which
> both should be prevalent systems. Do you think this does not make sense
> at all to try migrating between those, alhough this may be challenging?

I don't mind the challenge. But I'm worried this is something that
looks like a reasonable idea that doesn't get any traction in
practice.

And the example you mention is pretty striking: who in their right
mind would migrate between these two systems? If you deploy a Grace
system, that's because you are making use of the GPU, and your VM is
likely to require it. Conversely, if you run on an Ampere system, you
don't want to use a valuable (read: bloody expensive) slot on a Grace
machine.

> Other cases we have looked at are migration within Ampere Altra Max
> system family (which should be hopefully fine now with have CTR_EL0
> works from Sebastian upstream), mig between Graviton hosts. Wrt Ampere
> Altra Max to AmpereOne, Oliver pointed out the cntfrq issue which is
> blocking.
> 
> Do you think we should restrict our studies to systems which are
> "closer" to each other in terms of ARM spec rev. We throught that
> migration bewteen AmpereOne And Grace would be an interesting POC and
> not totally irrelevant in terms of industry.

These two implementations may be close in terms of CPU features. But
as systems, they are massively different, and I very much doubt they
have the same deployment story. If they have one at all.

The Graviton story may have more traction, but these folks have their
own way of doing things, and in my experience do not give upstream
much consideration.

To sum it up, I'm not opposed to this work. But if we are going to
carry this sort of complex emulation, I want someone to step up and
promise that they will test it for the next 10 years, at the very
least. Because I'm very unlikely to ever have access to any of these
machines, let alone both, and I don't see people using it in practice.

Thanks,

	M.

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


From jic23 at kernel.org  Sun Dec  1 04:55:18 2024
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 1 Dec 2024 12:55:18 +0000
Subject: [PATCH v5] iio: trigger: stm32-timer-trigger: Add check for
 clk_enable()
In-Reply-To: <20241123220149.30655-1-jiashengjiangcool@gmail.com>
References: <20241123220149.30655-1-jiashengjiangcool@gmail.com>
Message-ID: <20241201125518.29373281@jic23-huawei>

On Sat, 23 Nov 2024 22:01:49 +0000
Jiasheng Jiang <jiashengjiangcool at gmail.com> wrote:

> Add check for the return value of clk_enable() in order to catch the
> potential exception.
> 
> Reviewed-by: David Lechner <dlechner at baylibre.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
Applied.

thanks,

Jonathan

> ---
> Changelog:
> 
> v4 -> v5:
> 
> 1. Add a default in the switch.
> 
> v3 -> v4:
> 
> 1. Place braces around the case body.
> 
> v2 -> v3:
> 
> 1. Use guard() to simplify the resulting code.
> 
> v1 -> v2:
> 
> 1. Remove unsuitable dev_err_probe().
> ---
>  drivers/iio/trigger/stm32-timer-trigger.c | 49 ++++++++++++++---------
>  1 file changed, 29 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c
> index 0684329956d9..67528ec7d0a5 100644
> --- a/drivers/iio/trigger/stm32-timer-trigger.c
> +++ b/drivers/iio/trigger/stm32-timer-trigger.c
> @@ -119,7 +119,7 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
>  			     unsigned int frequency)
>  {
>  	unsigned long long prd, div;
> -	int prescaler = 0;
> +	int prescaler = 0, ret;
>  	u32 ccer;
>  
>  	/* Period and prescaler values depends of clock rate */
> @@ -150,10 +150,12 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
>  	if (ccer & TIM_CCER_CCXE)
>  		return -EBUSY;
>  
> -	mutex_lock(&priv->lock);
> +	guard(mutex)(&priv->lock);
>  	if (!priv->enabled) {
>  		priv->enabled = true;
> -		clk_enable(priv->clk);
> +		ret = clk_enable(priv->clk);
> +		if (ret)
> +			return ret;
>  	}
>  
>  	regmap_write(priv->regmap, TIM_PSC, prescaler);
> @@ -173,7 +175,6 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
>  
>  	/* Enable controller */
>  	regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
> -	mutex_unlock(&priv->lock);
>  
>  	return 0;
>  }
> @@ -307,7 +308,7 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
>  	struct stm32_timer_trigger *priv = dev_get_drvdata(dev);
>  	struct iio_trigger *trig = to_iio_trigger(dev);
>  	u32 mask, shift, master_mode_max;
> -	int i;
> +	int i, ret;
>  
>  	if (stm32_timer_is_trgo2_name(trig->name)) {
>  		mask = TIM_CR2_MMS2;
> @@ -322,15 +323,16 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
>  	for (i = 0; i <= master_mode_max; i++) {
>  		if (!strncmp(master_mode_table[i], buf,
>  			     strlen(master_mode_table[i]))) {
> -			mutex_lock(&priv->lock);
> +			guard(mutex)(&priv->lock);
>  			if (!priv->enabled) {
>  				/* Clock should be enabled first */
>  				priv->enabled = true;
> -				clk_enable(priv->clk);
> +				ret = clk_enable(priv->clk);
> +				if (ret)
> +					return ret;
>  			}
>  			regmap_update_bits(priv->regmap, TIM_CR2, mask,
>  					   i << shift);
> -			mutex_unlock(&priv->lock);
>  			return len;
>  		}
>  	}
> @@ -482,6 +484,7 @@ static int stm32_counter_write_raw(struct iio_dev *indio_dev,
>  				   int val, int val2, long mask)
>  {
>  	struct stm32_timer_trigger *priv = iio_priv(indio_dev);
> +	int ret;
>  
>  	switch (mask) {
>  	case IIO_CHAN_INFO_RAW:
> @@ -491,12 +494,14 @@ static int stm32_counter_write_raw(struct iio_dev *indio_dev,
>  		/* fixed scale */
>  		return -EINVAL;
>  
> -	case IIO_CHAN_INFO_ENABLE:
> -		mutex_lock(&priv->lock);
> +	case IIO_CHAN_INFO_ENABLE: {
> +		guard(mutex)(&priv->lock);
>  		if (val) {
>  			if (!priv->enabled) {
>  				priv->enabled = true;
> -				clk_enable(priv->clk);
> +				ret = clk_enable(priv->clk);
> +				if (ret)
> +					return ret;
>  			}
>  			regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN);
>  		} else {
> @@ -506,11 +511,12 @@ static int stm32_counter_write_raw(struct iio_dev *indio_dev,
>  				clk_disable(priv->clk);
>  			}
>  		}
> -		mutex_unlock(&priv->lock);
> +
>  		return 0;
>  	}
> -
> -	return -EINVAL;
> +	default:
> +		return -EINVAL;
> +	}
>  }
>  
>  static int stm32_counter_validate_trigger(struct iio_dev *indio_dev,
> @@ -601,7 +607,7 @@ static int stm32_set_enable_mode(struct iio_dev *indio_dev,
>  				 unsigned int mode)
>  {
>  	struct stm32_timer_trigger *priv = iio_priv(indio_dev);
> -	int sms = stm32_enable_mode2sms(mode);
> +	int sms = stm32_enable_mode2sms(mode), ret;
>  
>  	if (sms < 0)
>  		return sms;
> @@ -609,12 +615,15 @@ static int stm32_set_enable_mode(struct iio_dev *indio_dev,
>  	 * Triggered mode sets CEN bit automatically by hardware. So, first
>  	 * enable counter clock, so it can use it. Keeps it in sync with CEN.
>  	 */
> -	mutex_lock(&priv->lock);
> -	if (sms == 6 && !priv->enabled) {
> -		clk_enable(priv->clk);
> -		priv->enabled = true;
> +	scoped_guard(mutex, &priv->lock) {
> +		if (sms == 6 && !priv->enabled) {
> +			ret = clk_enable(priv->clk);
> +			if (ret)
> +				return ret;
> +
> +			priv->enabled = true;
> +		}
>  	}
> -	mutex_unlock(&priv->lock);
>  
>  	regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms);
>  



From maz at kernel.org  Sun Dec  1 04:58:47 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Dec 2024 12:58:47 +0000
Subject: [PATCH v3 14/15] KVM: arm64: Convert the SVE guest vcpu flag to a vm flag
In-Reply-To: <20241128123515.1709777-15-tabba@google.com>
References: <20241128123515.1709777-1-tabba@google.com>
	<20241128123515.1709777-15-tabba@google.com>
Message-ID: <864j3nv9tk.wl-maz@kernel.org>

On Thu, 28 Nov 2024 12:35:14 +0000,
Fuad Tabba <tabba at google.com> wrote:
> 
> The vcpu flag GUEST_HAS_SVE is per-vcpu, but it is based on what
> is now a per-vm feature. Make the flag per-vm.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_emulate.h    |  6 +++---
>  arch/arm64/include/asm/kvm_host.h       | 10 ++++++----
>  arch/arm64/kvm/hyp/include/hyp/switch.h |  2 +-
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  2 +-
>  arch/arm64/kvm/hyp/nvhe/pkvm.c          | 11 +++++++----
>  arch/arm64/kvm/hyp/nvhe/switch.c        |  8 ++++----
>  arch/arm64/kvm/hyp/vhe/switch.c         |  2 +-
>  arch/arm64/kvm/reset.c                  |  2 +-
>  8 files changed, 24 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index 406e99a452bf..ae6d0dc0e4ff 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -620,7 +620,7 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
>  }
>  
>  /* Resets the value of cptr_el2 when returning to the host. */
> -static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> +static __always_inline void kvm_reset_cptr_el2(struct kvm *kvm)

I'd rather you avoid the resulting churn:

static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
{
	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
	[...]

which does the trick at zero cost. It is also more logical to keep the
vcpu as a parameter, as the per-VM-ness is only an implementation
detail.

>  {
>  	u64 val;
>  
> @@ -631,14 +631,14 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
>  	} else if (has_hvhe()) {
>  		val = CPACR_ELx_FPEN;
>  
> -		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
> +		if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
>  			val |= CPACR_ELx_ZEN;
>  		if (cpus_have_final_cap(ARM64_SME))
>  			val |= CPACR_ELx_SMEN;
>  	} else {
>  		val = CPTR_NVHE_EL2_RES1;
>  
> -		if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
> +		if (kvm_has_sve(kvm) && guest_owns_fp_regs())
>  			val |= CPTR_EL2_TZ;
>  		if (!cpus_have_final_cap(ARM64_SME))
>  			val |= CPTR_EL2_TSM;
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 680ecef1d7aa..c5c80c789ad0 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -331,6 +331,8 @@ struct kvm_arch {
>  #define KVM_ARCH_FLAG_ID_REGS_INITIALIZED		7
>  	/* Fine-Grained UNDEF initialised */
>  #define KVM_ARCH_FLAG_FGU_INITIALIZED			8
> +	/* SVE exposed to guest */
> +#define KVM_ARCH_FLAG_GUEST_HAS_SVE			9
>  	unsigned long flags;
>  
>  	/* VM-wide vCPU feature set */
> @@ -862,8 +864,6 @@ struct kvm_vcpu_arch {
>  #define vcpu_set_flag(v, ...)	__vcpu_set_flag((v), __VA_ARGS__)
>  #define vcpu_clear_flag(v, ...)	__vcpu_clear_flag((v), __VA_ARGS__)
>  
> -/* SVE exposed to guest */
> -#define GUEST_HAS_SVE		__vcpu_single_flag(cflags, BIT(0))
>  /* SVE config completed */
>  #define VCPU_SVE_FINALIZED	__vcpu_single_flag(cflags, BIT(1))
>  /* KVM_ARM_VCPU_INIT completed */
> @@ -956,8 +956,10 @@ struct kvm_vcpu_arch {
>  				 KVM_GUESTDBG_USE_HW | \
>  				 KVM_GUESTDBG_SINGLESTEP)
>  
> -#define vcpu_has_sve(vcpu) (system_supports_sve() &&			\
> -			    vcpu_get_flag(vcpu, GUEST_HAS_SVE))
> +#define kvm_has_sve(kvm)	\
> +	test_bit(KVM_ARCH_FLAG_GUEST_HAS_SVE, &(kvm)->arch.flags)
> +#define vcpu_has_sve(vcpu)	\
> +	kvm_has_sve((vcpu)->kvm)

Two things:

- it is definitely worth keeping the system_supports_sve() helper, so
  that we avoid checking flags for nothing

- Since you preserve the vcpu_has_sve(), how about writing it as:

#ifdef __KVM_NVHE_HYPERVISOR__
#define vcpu_has_sve(v)		kvm_has_sve(kern_hyp_va((v)->kvm))
#else
#define vcpu_has_sve(v)		kvm_has_sve((v)->kvm)
#endif

  which will avoid the churn in this patch, and makes it hard to get
  it wrong?

Thanks,

	M.

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


From maz at kernel.org  Sun Dec  1 04:59:57 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Dec 2024 12:59:57 +0000
Subject: [PATCH v3 15/15] KVM: arm64: Renumber remaining vcpu guest configuration flags
In-Reply-To: <20241128123515.1709777-16-tabba@google.com>
References: <20241128123515.1709777-1-tabba@google.com>
	<20241128123515.1709777-16-tabba@google.com>
Message-ID: <8634j7v9rm.wl-maz@kernel.org>

On Thu, 28 Nov 2024 12:35:15 +0000,
Fuad Tabba <tabba at google.com> wrote:
> 
> With the vcpu's SVE and PtrAuth configuration flags removed,
> there are gaps in the numbering of the cflag bits. Renumber
> VCPU_INITIALIZED to bit 0 to remove the gaps.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_host.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index c5c80c789ad0..2e4afec09728 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -864,10 +864,10 @@ struct kvm_vcpu_arch {
>  #define vcpu_set_flag(v, ...)	__vcpu_set_flag((v), __VA_ARGS__)
>  #define vcpu_clear_flag(v, ...)	__vcpu_clear_flag((v), __VA_ARGS__)
>  
> +/* KVM_ARM_VCPU_INIT completed */
> +#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(0))
>  /* SVE config completed */
>  #define VCPU_SVE_FINALIZED	__vcpu_single_flag(cflags, BIT(1))
> -/* KVM_ARM_VCPU_INIT completed */
> -#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(3))
>  
>  /* Exception pending */
>  #define PENDING_EXCEPTION	__vcpu_single_flag(iflags, BIT(0))

Please fold this with the relevant patches, even if that makes two
consecutive renumbering patches.

Thanks,

	M.

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


From maz at kernel.org  Sun Dec  1 05:16:34 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Dec 2024 13:16:34 +0000
Subject: [PATCH v2] KVM: arm/arm64: vgic-its: Add error handling in vgic_its_cache_translation
In-Reply-To: <20241130144952.23729-1-keisuke.nishimura@inria.fr>
References: <20241130144952.23729-1-keisuke.nishimura@inria.fr>
Message-ID: <861pyrv8zx.wl-maz@kernel.org>

On Sat, 30 Nov 2024 14:49:53 +0000,
Keisuke Nishimura <keisuke.nishimura at inria.fr> wrote:
> 
> The return value of xa_store() needs to be checked. This fix adds an
> error handling path that resolves the kref inconsistency on failure. As
> suggested by Oliver Upton, this function does not return the error code
> intentionally because the translation cache is best effort.
> 
> Fixes: 8201d1028caa ("KVM: arm64: vgic-its: Maintain a translation cache per ITS")
> Signed-off-by: Keisuke Nishimura <keisuke.nishimura at inria.fr>
> ---
>  arch/arm64/kvm/vgic/vgic-its.c | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
> index 198296933e7e..a08835d00aba 100644
> --- a/arch/arm64/kvm/vgic/vgic-its.c
> +++ b/arch/arm64/kvm/vgic/vgic-its.c
> @@ -573,12 +573,22 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
>  	lockdep_assert_held(&its->its_lock);
>  	vgic_get_irq_kref(irq);
>  
> +	old = xa_store(&its->translation_cache, cache_key, irq, GFP_KERNEL_ACCOUNT);
> +
> +	/*
> +	 * Put the reference taken on @irq if the store fails. Intentionally do
> +	 * not return the error as the translation cache is best effort.
> +	 */
> +	if (xa_is_err(old)) {
> +		vgic_put_irq(kvm, irq);
> +		return;
> +	}
> +
>  	/*
>  	 * We could have raced with another CPU caching the same
>  	 * translation behind our back, ensure we don't leak a
>  	 * reference if that is the case.
>  	 */
> -	old = xa_store(&its->translation_cache, cache_key, irq, GFP_KERNEL_ACCOUNT);
>  	if (old)
>  		vgic_put_irq(kvm, old);
>  }

Suggested-by: Oliver Upton <oliver.upton at linux.dev>
Acked-by: Marc Zyngier <maz at kernel.org>

	M.

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


From towinchenmi at gmail.com  Sun Dec  1 07:56:37 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:37 +0800
Subject: [PATCH v4 00/10] Add PMGR nodes for Apple A7-A11 SoCs
Message-ID: <20241201155820.29259-1-towinchenmi@gmail.com>

This series adds the PMGR nodes and all known power state subnodes for
Apple A7-A11 SoCs, along with the associated dt-bindings.

Changes since v3:
- Add "apple,always-on" property to "ps_spmi" in t8015 power domains.
This is required for cpufreq to function correctly which will be added
in a later series.

Changes since v2:
- Removed "apple,always-on" property from "ps_pmp" from s8001, t8011,
t8015 power domains. It is not on at boot. (Mixed up with ps_pms which
is required to be on)
- Add asahi-soc/dt back into the subject prefix, missing from v2.

Link to v2: https://lore.kernel.org/asahi/20241102011004.59339-1-towinchenmi at gmail.com

Changes since v1:
- Removed "framebuffer0" dt aliases. It is not standard and not needed.

Link to v1: https://lore.kernel.org/asahi/20241029010526.42052-1-towinchenmi at gmail.com

Nick Chan
---

Nick Chan (10):
  dt-bindings: arm: apple: apple,pmgr: Add A7-A11 compatibles
  dt-bindings: arm: apple: apple,pmgr-pwrstate: Add A7-A11 compatibles
  arm64: dts: apple: s5l8960x: Add PMGR node
  arm64: dts: apple: t7000: Add PMGR node
  arm64: dts: apple: t7001: Add PMGR node
  arm64: dts: apple: s8000: Add PMGR nodes
  arm64: dts: apple: s8001: Add PMGR nodes
  arm64: dts: apple: t8010: Add PMGR nodes
  arm64: dts: apple: t8011: Add PMGR nodes
  arm64: dts: apple: t8015: Add PMGR nodes

 .../bindings/arm/apple/apple,pmgr.yaml        |   5 +
 .../bindings/power/apple,pmgr-pwrstate.yaml   |   5 +
 arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi  |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi  | 610 ++++++++++++
 arch/arm64/boot/dts/apple/s5l8960x.dtsi       |  13 +
 arch/arm64/boot/dts/apple/s8000-pmgr.dtsi     | 757 ++++++++++++++
 arch/arm64/boot/dts/apple/s8000.dtsi          |  22 +
 arch/arm64/boot/dts/apple/s8001-common.dtsi   |   1 +
 .../arm64/boot/dts/apple/s8001-j98a-j99a.dtsi |  26 +
 arch/arm64/boot/dts/apple/s8001-j98a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-j99a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi     | 822 ++++++++++++++++
 arch/arm64/boot/dts/apple/s8001.dtsi          |  22 +
 arch/arm64/boot/dts/apple/s800x-6s.dtsi       |   4 +
 arch/arm64/boot/dts/apple/s800x-ipad5.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s800x-se.dtsi       |   4 +
 arch/arm64/boot/dts/apple/t7000-6.dtsi        |   4 +
 arch/arm64/boot/dts/apple/t7000-j42d.dts      |   1 +
 arch/arm64/boot/dts/apple/t7000-mini4.dtsi    |   4 +
 arch/arm64/boot/dts/apple/t7000-n102.dts      |   4 +
 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi     | 641 ++++++++++++
 arch/arm64/boot/dts/apple/t7000.dtsi          |  14 +
 arch/arm64/boot/dts/apple/t7001-air2.dtsi     |   1 +
 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi     | 650 ++++++++++++
 arch/arm64/boot/dts/apple/t7001.dtsi          |  13 +
 arch/arm64/boot/dts/apple/t8010-7.dtsi        |   4 +
 arch/arm64/boot/dts/apple/t8010-ipad6.dtsi    |   4 +
 arch/arm64/boot/dts/apple/t8010-n112.dts      |   4 +
 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi     | 772 +++++++++++++++
 arch/arm64/boot/dts/apple/t8010.dtsi          |  22 +
 arch/arm64/boot/dts/apple/t8011-common.dtsi   |   1 +
 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi     | 806 +++++++++++++++
 arch/arm64/boot/dts/apple/t8011-pro2.dtsi     |   8 +
 arch/arm64/boot/dts/apple/t8011.dtsi          |  22 +
 arch/arm64/boot/dts/apple/t8015-common.dtsi   |   1 +
 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi     | 931 ++++++++++++++++++
 arch/arm64/boot/dts/apple/t8015.dtsi          |  21 +
 39 files changed, 6237 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8000-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi


base-commit: 9ad55a67a788c0806b0fe23be36fae6dbfbc3fc5
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:38 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:38 +0800
Subject: [PATCH v4 01/10] dt-bindings: arm: apple: apple,pmgr: Add A7-A11 compatibles
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-2-towinchenmi@gmail.com>

The blocks found on Apple A7-A11 SoCs are compatible with the existing
driver so add their per-SoC compatibles.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
index 673277a7a224..5001f4d5a0dc 100644
--- a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
+++ b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
@@ -22,6 +22,11 @@ properties:
   compatible:
     items:
       - enum:
+          - apple,s5l8960x-pmgr
+          - apple,t7000-pmgr
+          - apple,s8000-pmgr
+          - apple,t8010-pmgr
+          - apple,t8015-pmgr
           - apple,t8103-pmgr
           - apple,t8112-pmgr
           - apple,t6000-pmgr
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:43 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:43 +0800
Subject: [PATCH v4 06/10] arm64: dts: apple: s8000: Add PMGR nodes
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-7-towinchenmi@gmail.com>

This adds the two PMGR nodes and all known power state subnodes. Since
there are a large number of them, let's put them in a separate file to
include.

Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s8000-pmgr.dtsi  | 757 +++++++++++++++++++++
 arch/arm64/boot/dts/apple/s8000.dtsi       |  22 +
 arch/arm64/boot/dts/apple/s800x-6s.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s800x-ipad5.dtsi |   4 +
 arch/arm64/boot/dts/apple/s800x-se.dtsi    |   4 +
 5 files changed, 791 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s8000-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/s8000-pmgr.dtsi b/arch/arm64/boot/dts/apple/s8000-pmgr.dtsi
new file mode 100644
index 000000000000..196b8e745a95
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s8000-pmgr.dtsi
@@ -0,0 +1,757 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple S8000/3 "A9" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80150 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80158 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80168 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80170 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80178 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80180 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80188 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 80190 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 80198 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801a0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801b0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 801f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 801f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80160 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_hsic1_phy: power-controller at 80130 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_isp_sens0: power-controller at 80138 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80140 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_usb: power-controller at 80250 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80258 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80260 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80270 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 80280 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 802c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 802e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 802b0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_pmp: power-controller at 802e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 802f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_uart5: power-controller at 80200 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80208 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80210 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80218 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 80220 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80228 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80230 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80238 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80240 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80248 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80268 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usb2host1_ohci: power-controller at 80278 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1_ohci";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_usb2host2_ohci: power-controller at 80288 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2_ohci";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_usbotg: power-controller at 80290 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 80298 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_dp: power-controller at 802c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_vdec: power-controller at 802f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc: power-controller at 80308 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 80310 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80318 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_pcie_link0: power-controller at 80320 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link0";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link1: power-controller at 80328 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link1";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link2: power-controller at 80330 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link2";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link3: power-controller at 80338 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link3";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_gfx: power-controller at 80340 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80340 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_venc_pipe: power-controller at 88000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 88008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_busif &ps_aop_cpu &ps_aop_filter>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+		power-domains = <&ps_aop>;
+	};
+
+	ps_aop_cpu: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80048 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80050 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s8000.dtsi b/arch/arm64/boot/dts/apple/s8000.dtsi
index 6e9046ea106c..84d6b4939ac4 100644
--- a/arch/arm64/boot/dts/apple/s8000.dtsi
+++ b/arch/arm64/boot/dts/apple/s8000.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,s8000-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -95,6 +106,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +125,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 119 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,s8000-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -132,6 +152,8 @@ timer {
 	};
 };
 
+#include "s8000-pmgr.dtsi"
+
 /*
  * The A9 was made by two separate fabs on two different process
  * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
diff --git a/arch/arm64/boot/dts/apple/s800x-6s.dtsi b/arch/arm64/boot/dts/apple/s800x-6s.dtsi
index 49b04db310c6..1dcf80cc2920 100644
--- a/arch/arm64/boot/dts/apple/s800x-6s.dtsi
+++ b/arch/arm64/boot/dts/apple/s800x-6s.dtsi
@@ -47,3 +47,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi
index 32570ed3cdf0..c1701e81f0c1 100644
--- a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi
+++ b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi
@@ -41,3 +41,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/s800x-se.dtsi b/arch/arm64/boot/dts/apple/s800x-se.dtsi
index a1a5690e8371..deb7c7cc90f6 100644
--- a/arch/arm64/boot/dts/apple/s800x-se.dtsi
+++ b/arch/arm64/boot/dts/apple/s800x-se.dtsi
@@ -47,3 +47,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:44 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:44 +0800
Subject: [PATCH v4 07/10] arm64: dts: apple: s8001: Add PMGR nodes
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-8-towinchenmi@gmail.com>

This adds the two PMGR nodes and all known power state subnodes. Since
there are a large number of them, let's put them in a separate file to
include.

Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s8001-common.dtsi   |   1 +
 .../arm64/boot/dts/apple/s8001-j98a-j99a.dtsi |  26 +
 arch/arm64/boot/dts/apple/s8001-j98a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-j99a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi     | 822 ++++++++++++++++++
 arch/arm64/boot/dts/apple/s8001.dtsi          |  22 +
 6 files changed, 873 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/s8001-common.dtsi b/arch/arm64/boot/dts/apple/s8001-common.dtsi
index e94d0e77653a..91b06e113894 100644
--- a/arch/arm64/boot/dts/apple/s8001-common.dtsi
+++ b/arch/arm64/boot/dts/apple/s8001-common.dtsi
@@ -24,6 +24,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0 &ps_dp0>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi b/arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
new file mode 100644
index 000000000000..e66a4c1c138f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple iPad Pro (12.9-inch)
+ *
+ * This file contains parts common to iPad Pro (12.9-inch).
+ *
+ * target-type: J98a, J99a
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+&ps_dcs4 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs5 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs6 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs7 {
+	apple,always-on; /* LPDDR4 interface */
+};
diff --git a/arch/arm64/boot/dts/apple/s8001-j98a.dts b/arch/arm64/boot/dts/apple/s8001-j98a.dts
index 6d6b841e7ab0..162eca05c2d9 100644
--- a/arch/arm64/boot/dts/apple/s8001-j98a.dts
+++ b/arch/arm64/boot/dts/apple/s8001-j98a.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s8001-pro.dtsi"
+#include "s8001-j98a-j99a.dtsi"
 
 / {
 	compatible = "apple,j98a", "apple,s8001", "apple,arm-platform";
diff --git a/arch/arm64/boot/dts/apple/s8001-j99a.dts b/arch/arm64/boot/dts/apple/s8001-j99a.dts
index d20194b1cae7..7b765820c69e 100644
--- a/arch/arm64/boot/dts/apple/s8001-j99a.dts
+++ b/arch/arm64/boot/dts/apple/s8001-j99a.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s8001-pro.dtsi"
+#include "s8001-j98a-j99a.dtsi"
 
 / {
 	compatible = "apple,j99a", "apple,s8001", "apple,arm-platform";
diff --git a/arch/arm64/boot/dts/apple/s8001-pmgr.dtsi b/arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
new file mode 100644
index 000000000000..859ab77ae92b
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
@@ -0,0 +1,822 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple S8001 "A9X" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80148 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80150 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pcie_ref: power-controller at 80140 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80160 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80168 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80170 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80178 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80180 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 80188 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 80190 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 80198 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801a0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801b0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 801e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 801f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 801f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80158 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_isp_sens0: power-controller at 80130 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80138 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb: power-controller at 80278 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80280 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80288 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80298 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 802a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_disp1mux: power-controller at 802e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1mux";
+	};
+
+	ps_disp0: power-controller at 802d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp1: power-controller at 802f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp1mux>;
+	};
+
+	ps_uart6: power-controller at 80200 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80208 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80210 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 80218 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80230 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80238 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80240 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80248 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80250 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs4: power-controller at 80258 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs4";
+	};
+
+	ps_dcs5: power-controller at 80260 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs5";
+	};
+
+	ps_dcs6: power-controller at 80268 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs6";
+	};
+
+	ps_dcs7: power-controller at 80270 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs7";
+	};
+
+	ps_usb2host0_ohci: power-controller at 80290 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 802b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 802c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_dp0: power-controller at 802e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp0";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_dp1: power-controller at 802f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp1";
+		power-domains = <&ps_disp1>;
+	};
+
+	ps_dpa0: power-controller at 80220 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa0";
+	};
+
+	ps_dpa1: power-controller at 80228 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa1";
+	};
+
+	ps_media: power-controller at 80308 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 80300 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 80318 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 80310 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc: power-controller at 80340 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80340 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 80348 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80348 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_srs: power-controller at 80390 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80390 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "srs";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie_aux: power-controller at 80350 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80350 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_pcie_link0: power-controller at 80358 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80358 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link0";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link1: power-controller at 80360 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80360 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link1";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link2: power-controller at 80368 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80368 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link2";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link3: power-controller at 80370 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80370 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link3";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link4: power-controller at 80378 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80378 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link4";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link5: power-controller at 80380 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80380 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link5";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_vdec: power-controller at 80330 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80388 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80388 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_pmp: power-controller at 80320 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 80328 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on*/
+	};
+
+	ps_venc_pipe: power-controller at 88000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 88008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_cpu &ps_aop_filter &ps_aop_busif>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+	};
+
+	ps_aop_cpu: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80048 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80050 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s8001.dtsi b/arch/arm64/boot/dts/apple/s8001.dtsi
index 23ee3238844d..3963c6d8ca5e 100644
--- a/arch/arm64/boot/dts/apple/s8001.dtsi
+++ b/arch/arm64/boot/dts/apple/s8001.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,s8000-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -95,6 +106,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +125,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 134 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,s8000-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -131,3 +151,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "s8001-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:45 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:45 +0800
Subject: [PATCH v4 08/10] arm64: dts: apple: t8010: Add PMGR nodes
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-9-towinchenmi@gmail.com>

This adds the two PMGR nodes and all known power state subnodes. Since
there are a large number of them, let's put them in a separate file to
include.

Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8010-7.dtsi     |   4 +
 arch/arm64/boot/dts/apple/t8010-ipad6.dtsi |   4 +
 arch/arm64/boot/dts/apple/t8010-n112.dts   |   4 +
 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi  | 772 +++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8010.dtsi       |  22 +
 5 files changed, 806 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8010-7.dtsi b/arch/arm64/boot/dts/apple/t8010-7.dtsi
index 1332fd73f50f..91fae47d25d0 100644
--- a/arch/arm64/boot/dts/apple/t8010-7.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010-7.dtsi
@@ -41,3 +41,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
index 81696c6e302c..b83fe153763e 100644
--- a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
@@ -42,3 +42,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0_fe &ps_disp0_be &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-n112.dts b/arch/arm64/boot/dts/apple/t8010-n112.dts
index 6e71c3cb5d92..48fdbedf74da 100644
--- a/arch/arm64/boot/dts/apple/t8010-n112.dts
+++ b/arch/arm64/boot/dts/apple/t8010-n112.dts
@@ -45,3 +45,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
new file mode 100644
index 000000000000..6d451088616a
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
@@ -0,0 +1,772 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8010 "A10" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80160 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80168 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_socuvd: power-controller at 80150 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "socuvd";
+	};
+
+	ps_mca0: power-controller at 80178 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80180 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80188 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80190 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80170 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_isp_sens0: power-controller at 80130 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80138 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_isp_sens2: power-controller at 80140 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens2";
+	};
+
+	ps_usb: power-controller at 80268 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80270 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80278 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80288 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp_sys: power-controller at 802d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 802e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp0_be: power-controller at 802b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_pmp: power-controller at 802f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 802f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_uart3: power-controller at 80200 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80208 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 80210 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80218 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80220 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80228 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80238 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80240 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80248 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80250 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80258 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80260 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80280 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 80290 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 80298 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_dp: power-controller at 802c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_venc_sys: power-controller at 80310 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 80318 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80320 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_vdec0: power-controller at 80300 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec0";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80328 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_dprx: power-controller at 84028 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dprx";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_pipe4: power-controller at 88000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_pipe5: power-controller at 88008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_me0: power-controller at 88010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_cpu &ps_aop_busif &ps_aop_filter>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+	};
+
+	ps_aop_cpu: power-controller at 80048 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80050 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80058 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8010.dtsi b/arch/arm64/boot/dts/apple/t8010.dtsi
index e3d6a8354103..ac1dda92f890 100644
--- a/arch/arm64/boot/dts/apple/t8010.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,t8010-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -95,6 +106,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +125,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 134 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,t8010-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -131,3 +151,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8010-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:46 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:46 +0800
Subject: [PATCH v4 09/10] arm64: dts: apple: t8011: Add PMGR nodes
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-10-towinchenmi@gmail.com>

This adds the two PMGR nodes and all known power state subnodes. Since
there are a large number of them, let's put them in a separate file to
include.

Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8011-common.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi   | 806 ++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8011-pro2.dtsi   |   8 +
 arch/arm64/boot/dts/apple/t8011.dtsi        |  22 +
 4 files changed, 837 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8011-common.dtsi b/arch/arm64/boot/dts/apple/t8011-common.dtsi
index 44a0d0ea2ee3..2010b56246f1 100644
--- a/arch/arm64/boot/dts/apple/t8011-common.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011-common.dtsi
@@ -22,6 +22,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0_fe &ps_disp0_be &ps_dp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t8011-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
new file mode 100644
index 000000000000..c44e3f9d7087
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
@@ -0,0 +1,806 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8011 "A10X" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu2: power-controller at 80010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu2";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80158 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80160 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80170 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80178 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80180 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80188 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80190 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 801f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80168 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb3host>;
+	};
+
+	ps_isp_sens0: power-controller at 80130 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80138 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_isp_sens2: power-controller at 80140 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens2";
+	};
+
+	ps_usb: power-controller at 80288 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80290 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host: power-controller at 80298 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2dev: power-controller at 802a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2dev";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb3host: power-controller at 802a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb3host";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb3dev: power-controller at 802b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb3dev";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_media: power-controller at 802e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp_sys: power-controller at 802e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+	};
+
+	ps_msr: power-controller at 802f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+	};
+
+	ps_disp0_be: power-controller at 802d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_dpa: power-controller at 80230 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80200 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 80208 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80210 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80218 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80220 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80238 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80240 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80248 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80250 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80258 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80260 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs4: power-controller at 80268 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs4";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs5: power-controller at 80270 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs5";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs6: power-controller at 80278 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs6";
+	};
+
+	ps_dcs7: power-controller at 80280 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs7";
+	};
+
+	ps_smx: power-controller at 802b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_dp: power-controller at 802d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_venc_sys: power-controller at 80320 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_srs: power-controller at 80390 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80390 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "srs";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pms_sram: power-controller at 80308 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_pmp: power-controller at 80300 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pcie: power-controller at 80328 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80330 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_vdec0: power-controller at 80310 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec0";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80338 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_dprx: power-controller at 84028 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dprx";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_pipe4: power-controller at 88000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_pipe5: power-controller at 88008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_me0: power-controller at 88010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_cpu &ps_aop_filter &ps_aop_busif>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+	};
+
+	ps_aop_cpu: power-controller at 80048 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80050 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80058 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8011-pro2.dtsi b/arch/arm64/boot/dts/apple/t8011-pro2.dtsi
index f4e707415003..5eaa0a73350f 100644
--- a/arch/arm64/boot/dts/apple/t8011-pro2.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011-pro2.dtsi
@@ -40,3 +40,11 @@ button-volup {
 		};
 	};
 };
+
+&ps_dcs6 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs7 {
+	apple,always-on; /* LPDDR4 interface */
+};
diff --git a/arch/arm64/boot/dts/apple/t8011.dtsi b/arch/arm64/boot/dts/apple/t8011.dtsi
index 6c4ed9dc4a50..b845fa6f6d64 100644
--- a/arch/arm64/boot/dts/apple/t8011.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011.dtsi
@@ -69,19 +69,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,t8010-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -103,6 +114,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -121,6 +133,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 131 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,t8010-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -139,3 +159,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8011-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:47 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:47 +0800
Subject: [PATCH v4 10/10] arm64: dts: apple: t8015: Add PMGR nodes
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-11-towinchenmi@gmail.com>

This adds the two PMGR nodes and all known power state subnodes. Since
there are a large number of them, let's put them in a separate file to
include.

Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8015-common.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi   | 931 ++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8015.dtsi        |  21 +
 3 files changed, 953 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8015-common.dtsi b/arch/arm64/boot/dts/apple/t8015-common.dtsi
index 69258a33ea50..498f58fb9715 100644
--- a/arch/arm64/boot/dts/apple/t8015-common.dtsi
+++ b/arch/arm64/boot/dts/apple/t8015-common.dtsi
@@ -24,6 +24,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0_be &ps_mipi_dsi &ps_disp0_hilo &ps_disp0_ppp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi
new file mode 100644
index 000000000000..e238c2d2732f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi
@@ -0,0 +1,931 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8015 "A11" SoC
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu2: power-controller at 80010 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu2";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu3: power-controller at 80018 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu3";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu4: power-controller at 80020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu4";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu5: power-controller at 80028 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu5";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80158 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80160 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80170 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80178 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80180 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80188 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80190 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 801a0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801b0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801c0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801c8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801d0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801d8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801e0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801e8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801f0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801f8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80168 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsicphy: power-controller at 80128 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsicphy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_ispsens0: power-controller at 80130 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 80138 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_ispsens2: power-controller at 80140 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens2";
+	};
+
+	ps_mca5: power-controller at 80198 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_usb: power-controller at 80270 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctlreg: power-controller at 80278 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctlreg";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80280 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctlreg>;
+	};
+
+	ps_usb2host1: power-controller at 80290 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctlreg>;
+	};
+
+	ps_rtmux: power-controller at 802b0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802f0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_jpg: power-controller at 802f8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802b8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp0_be: power-controller at 802c0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_disp0_gp: power-controller at 802c8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_gp";
+		power-domains = <&ps_disp0_be>;
+		status = "disabled";
+	};
+
+	ps_uart3: power-controller at 80200 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80208 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 80210 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80218 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80220 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80228 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80238 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80248 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80250 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_dcs1: power-controller at 80258 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_dcs2: power-controller at 80260 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_dcs3: power-controller at 80268 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80288 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usb2dev: power-controller at 80298 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2dev";
+		power-domains = <&ps_usbctlreg>;
+	};
+
+	ps_smx: power-controller at 802a0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802d8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_dp: power-controller at 802e0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_dpa: power-controller at 80230 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa";
+	};
+
+	ps_disp0_be_2x: power-controller at 802d0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be_2x";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_isp_sys: power-controller at 80350 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80350 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 80300 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc_sys: power-controller at 80398 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80398 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pmp: power-controller at 80308 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 80310 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_pcie: power-controller at 80318 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80320 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_vdec0: power-controller at 80388 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80388 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec0";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80338 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_ans2: power-controller at 80328 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans2";
+		apple,always-on;
+	};
+
+	ps_pcie_direct: power-controller at 80330 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_direct";
+		apple,always-on;
+	};
+
+	ps_avd_sys: power-controller at 803a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x803a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "avd_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_disp0_gp0: power-controller at 80830 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80830 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_gp0";
+		power-domains = <&ps_disp0_gp>;
+		status = "disabled";
+	};
+
+	ps_disp0_gp1: power-controller at 80838 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80838 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_gp1";
+		status = "disabled";
+	};
+
+	ps_disp0_ppp: power-controller at 80840 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80840 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_ppp";
+	};
+
+	ps_disp0_hilo: power-controller at 80848 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80848 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_hilo";
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_dprx: power-controller at 84028 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dprx";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_cnv: power-controller at 84030 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_cnv";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_dma: power-controller at 88000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_dma";
+	};
+
+	ps_venc_pipe4: power-controller at 88010 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+	};
+
+	ps_venc_pipe5: power-controller at 88018 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+	};
+
+	ps_venc_me0: power-controller at 88020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88028 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop_base: power-controller at 80008 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_base";
+		power-domains = <&ps_aop_cpu &ps_aop_filter>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80050 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_cpu: power-controller at 80020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_spmi: power-controller at 80058 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spmi";
+		apple,always-on; /* System Power Management Interface */
+	};
+
+	ps_smc_i2cm1: power-controller at 800a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x800a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_i2cm1";
+	};
+
+	ps_smc_fabric: power-controller at 80030 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_fabric";
+	};
+
+	ps_smc_cpu: power-controller at 80140 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_cpu";
+		power-domains = <&ps_smc_fabric &ps_smc_i2cm1>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8015.dtsi b/arch/arm64/boot/dts/apple/t8015.dtsi
index 8828d830e5be..fbff3a6c0ba4 100644
--- a/arch/arm64/boot/dts/apple/t8015.dtsi
+++ b/arch/arm64/boot/dts/apple/t8015.dtsi
@@ -119,6 +119,7 @@ serial0: serial at 22e600000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
@@ -127,11 +128,21 @@ aic: interrupt-controller at 232100000 {
 			reg = <0x2 0x32100000 0x0 0x8000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
+		};
+
+		pmgr: power-management at 232000000 {
+			compatible = "apple,t8015-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x32000000 0 0x8c000>;
 		};
 
 		pinctrl_ap: pinctrl at 233100000 {
 			compatible = "apple,t8015-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x33100000 0x0 0x1000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -188,6 +199,14 @@ pinctrl_nub: pinctrl at 2351f0000 {
 				     <AIC_IRQ 170 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 235200000 {
+			compatible = "apple,t8015-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x35200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2352b0000 {
 			compatible = "apple,t8015-wdt", "apple,wdt";
 			reg = <0x2 0x352b0000 0x0 0x4000>;
@@ -232,3 +251,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8015-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:39 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:39 +0800
Subject: [PATCH v4 02/10] dt-bindings: arm: apple: apple,pmgr-pwrstate: Add A7-A11 compatibles
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-3-towinchenmi@gmail.com>

The blocks found on Apple A7-A11 SoCs are compatible with the existing
driver so add their per-SoC compatible.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../devicetree/bindings/power/apple,pmgr-pwrstate.yaml       | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
index 59a6af735a21..6e9a670eaf56 100644
--- a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
+++ b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
@@ -31,6 +31,11 @@ properties:
   compatible:
     items:
       - enum:
+          - apple,s5l8960x-pmgr-pwrstate
+          - apple,t7000-pmgr-pwrstate
+          - apple,s8000-pmgr-pwrstate
+          - apple,t8010-pmgr-pwrstate
+          - apple,t8015-pmgr-pwrstate
           - apple,t8103-pmgr-pwrstate
           - apple,t8112-pmgr-pwrstate
           - apple,t6000-pmgr-pwrstate
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:40 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:40 +0800
Subject: [PATCH v4 03/10] arm64: dts: apple: s5l8960x: Add PMGR node
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-4-towinchenmi@gmail.com>

This adds the PMGR node and all known power state subnodes. Since there
are a large number of them, let's put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi  |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi  | 610 ++++++++++++++++++
 arch/arm64/boot/dts/apple/s5l8960x.dtsi       |  13 +
 5 files changed, 635 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
index 0b16adf07f79..51c081923657 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
index 741c5a9f21dd..7d6e799c933a 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
index b27ef5680626..2ba846db2266 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
new file mode 100644
index 000000000000..da265f484307
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
@@ -0,0 +1,610 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple S5L8960X "A7" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 20000 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 20008 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_secuart0: power-controller at 200f0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "secuart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_secuart1: power-controller at 200f8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "secuart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_cpm: power-controller at 20010 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_lio: power-controller at 20018 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "lio";
+		apple,always-on; /* Core device */
+	};
+
+	ps_iomux: power-controller at 20020 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_aic: power-controller at 20028 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_debug: power-controller at 20030 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_dwi: power-controller at 20038 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20038 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 20040 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_mca0: power-controller at 20048 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 20050 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 20058 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 20060 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20060 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 20068 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20068 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 20070 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20070 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 20078 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20078 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 20080 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20080 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 20088 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20088 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 20090 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20090 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 20098 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20098 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 200a0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 200a8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 200b0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 200b8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 200c0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 200c8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 200d0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 200d8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 200e0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 200e8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio_p: power-controller at 20110 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+	};
+
+	ps_usb: power-controller at 20158 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 20160 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 20170 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 20180 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_disp_busmux: power-controller at 201a8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp_busmux";
+	};
+
+	ps_media: power-controller at 201d8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 201d0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+	};
+
+	ps_msr: power-controller at 201e0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 201e8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 201b0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_aes0: power-controller at 20100 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 20108 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 20118 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_hsic1_phy: power-controller at 20120 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_hsic2_phy: power-controller at 20128 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic2_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_ispsens0: power-controller at 20130 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 20138 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_mcc: power-controller at 20140 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Core device */
+	};
+
+	ps_mcu: power-controller at 20148 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcu";
+		apple,always-on; /* Core device */
+	};
+
+	ps_amp: power-controller at 20150 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "amp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb2host0_ohci: power-controller at 20168 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usb2host1_ohci: power-controller at 20178 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1_ohci";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_usbotg: power-controller at 20188 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 20190 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 20198 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_cp: power-controller at 201a0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_mipi_dsi: power-controller at 201b8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_dp: power-controller at 201c0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_disp1: power-controller at 201c8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_vdec: power-controller at 201f0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc: power-controller at 201f8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans: power-controller at 20200 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans";
+	};
+
+	ps_ans_dll: power-controller at 20208 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans_dll";
+		power-domains = <&ps_ans>;
+	};
+
+	ps_gfx: power-controller at 20218 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 20268 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		power-domains = <&ps_secuart1>, <&ps_secuart0>;
+		apple,always-on; /* Locked on */
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x.dtsi b/arch/arm64/boot/dts/apple/s5l8960x.dtsi
index 0218ecac1d83..7705215fbdc7 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x.dtsi
@@ -62,9 +62,18 @@ serial0: serial at 20a0a0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s5l8960x-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x24000>;
+		};
+
 		wdt: watchdog at 20e027000 {
 			compatible = "apple,s5l8960x-wdt", "apple,wdt";
 			reg = <0x2 0x0e027000 0x0 0x1000>;
@@ -78,11 +87,13 @@ aic: interrupt-controller at 20e100000 {
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl: pinctrl at 20e300000 {
 			compatible = "apple,s5l8960x-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0e300000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -111,3 +122,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "s5l8960x-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:41 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:41 +0800
Subject: [PATCH v4 04/10] arm64: dts: apple: t7000: Add PMGR node
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-5-towinchenmi@gmail.com>

This adds the PMGR node and all known power state subnodes. Since there
are a large number of them, let's put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t7000-6.dtsi     |   4 +
 arch/arm64/boot/dts/apple/t7000-j42d.dts   |   1 +
 arch/arm64/boot/dts/apple/t7000-mini4.dtsi |   4 +
 arch/arm64/boot/dts/apple/t7000-n102.dts   |   4 +
 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi  | 641 +++++++++++++++++++++
 arch/arm64/boot/dts/apple/t7000.dtsi       |  14 +
 6 files changed, 668 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t7000-6.dtsi b/arch/arm64/boot/dts/apple/t7000-6.dtsi
index f60ea4a4a387..77d74d6af1c4 100644
--- a/arch/arm64/boot/dts/apple/t7000-6.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000-6.dtsi
@@ -48,3 +48,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-j42d.dts b/arch/arm64/boot/dts/apple/t7000-j42d.dts
index 2231db6a739d..4de5e6a3f230 100644
--- a/arch/arm64/boot/dts/apple/t7000-j42d.dts
+++ b/arch/arm64/boot/dts/apple/t7000-j42d.dts
@@ -20,6 +20,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0 &ps_dp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
index c64ddc402fda..e5a9656045f2 100644
--- a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-n102.dts b/arch/arm64/boot/dts/apple/t7000-n102.dts
index 9c55d339ba4e..99eb8a2b8c73 100644
--- a/arch/arm64/boot/dts/apple/t7000-n102.dts
+++ b/arch/arm64/boot/dts/apple/t7000-n102.dts
@@ -46,3 +46,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-pmgr.dtsi b/arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
new file mode 100644
index 000000000000..5948fa7afffc
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
@@ -0,0 +1,641 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T7000 "A8" SoC
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+&pmgr {
+	ps_cpu0: power-controller at 20000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 20008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 20040 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_p: power-controller at 201f8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+	};
+
+	ps_lio: power-controller at 20100 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "lio";
+		apple,always-on; /* Core device */
+	};
+
+	ps_iomux: power-controller at 20108 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_aic: power-controller at 20110 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_debug: power-controller at 20118 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_dwi: power-controller at 20120 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 20128 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_mca0: power-controller at 20130 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 20138 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 20140 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 20148 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 20150 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 20158 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 20160 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 20168 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 20170 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 20178 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 20180 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 20188 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 20190 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 20198 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 201a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 201a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 201b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 201b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 201c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 201c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 201d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 201d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 201e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 201e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 201f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb: power-controller at 20248 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 20250 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 20258 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 20268 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 20278 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_disp_busmux: power-controller at 202a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp_busmux";
+	};
+
+	ps_media: power-controller at 202d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 202d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+	};
+
+	ps_msr: power-controller at 202e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 202e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 202b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_disp1: power-controller at 202c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_pcie_ref: power-controller at 20220 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_hsic0_phy: power-controller at 20200 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_hsic1_phy: power-controller at 20208 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_ispsens0: power-controller at 20210 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 20218 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_mcc: power-controller at 20230 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_mcu: power-controller at 20238 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcu";
+		apple,always-on; /* Core device */
+	};
+
+	ps_amp: power-controller at 20240 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "amp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb2host0_ohci: power-controller at 20260 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 20288 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 20290 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple Fabric, critical block */
+	};
+
+	ps_sf: power-controller at 20298 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple Fabric, critical block */
+	};
+
+	ps_cp: power-controller at 202a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_mipi_dsi: power-controller at 202b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_dp: power-controller at 202c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_vdec: power-controller at 202f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans: power-controller at 20318 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans";
+	};
+
+	ps_venc: power-controller at 20300 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 20308 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 20310 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_gfx: power-controller at 20320 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 20400 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_venc_pipe: power-controller at 21000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 21008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me1: power-controller at 21010 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+		power-domains = <&ps_venc>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t7000.dtsi b/arch/arm64/boot/dts/apple/t7000.dtsi
index a7cc29e84c84..ed1e9a62ba05 100644
--- a/arch/arm64/boot/dts/apple/t7000.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000.dtsi
@@ -62,6 +62,7 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
@@ -74,9 +75,18 @@ serial6: serial at 20a0d8000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart6>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t7000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x24000>;
+		};
+
 		wdt: watchdog at 20e027000 {
 			compatible = "apple,t7000-wdt", "apple,wdt";
 			reg = <0x2 0x0e027000 0x0 0x1000>;
@@ -90,11 +100,13 @@ aic: interrupt-controller at 20e100000 {
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl: pinctrl at 20e300000 {
 			compatible = "apple,t7000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0e300000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -123,3 +135,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t7000-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 07:56:42 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun,  1 Dec 2024 23:56:42 +0800
Subject: [PATCH v4 05/10] arm64: dts: apple: t7001: Add PMGR node
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <20241201155820.29259-6-towinchenmi@gmail.com>

This adds the PMGR node and all known power state subnodes. Since there
are a large number of them, let's put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t7001-air2.dtsi |   1 +
 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi | 650 ++++++++++++++++++++++
 arch/arm64/boot/dts/apple/t7001.dtsi      |  13 +
 3 files changed, 664 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t7001-air2.dtsi b/arch/arm64/boot/dts/apple/t7001-air2.dtsi
index 19fabd425c52..e4ec8c1977de 100644
--- a/arch/arm64/boot/dts/apple/t7001-air2.dtsi
+++ b/arch/arm64/boot/dts/apple/t7001-air2.dtsi
@@ -20,6 +20,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0 &ps_dp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t7001-pmgr.dtsi b/arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
new file mode 100644
index 000000000000..7321cfdcd189
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
@@ -0,0 +1,650 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T7001 "A8X" SoC
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 20000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 20008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu2: power-controller at 20010 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu2";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 20040 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_p: power-controller at 201f8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+	};
+
+	ps_lio: power-controller at 20100 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "lio";
+		apple,always-on; /* Core device */
+	};
+
+	ps_iomux: power-controller at 20108 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_aic: power-controller at 20110 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_debug: power-controller at 20118 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_dwi: power-controller at 20120 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 20128 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_mca0: power-controller at 20130 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 20138 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 20140 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 20148 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 20150 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 20158 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 20160 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 20168 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 20170 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 20178 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 20180 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 20188 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 20190 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 20198 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 201a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 201a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 201b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 201b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 201c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 201c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 201d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 201d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 201e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 201e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 201f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb: power-controller at 20248 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 20250 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 20258 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 20268 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 20278 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_disp_busmux: power-controller at 202a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp_busmux";
+	};
+
+	ps_disp1_busmux: power-controller at 202c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1_busmux";
+	};
+
+	ps_media: power-controller at 202d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 202d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+	};
+
+	ps_msr: power-controller at 202e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 202e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 202b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_disp1: power-controller at 202c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp1_busmux>;
+	};
+
+	ps_pcie_ref: power-controller at 20220 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_hsic0_phy: power-controller at 20200 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_hsic1_phy: power-controller at 20208 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_ispsens0: power-controller at 20210 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 20218 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_mcc: power-controller at 20230 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_mcu: power-controller at 20238 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcu";
+		apple,always-on; /* Core device */
+	};
+
+	ps_amp: power-controller at 20240 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "amp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb2host0_ohci: power-controller at 20260 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 20288 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 20290 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 20298 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_cp: power-controller at 202a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dp: power-controller at 202b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_vdec: power-controller at 202f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans: power-controller at 20318 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans";
+	};
+
+	ps_venc: power-controller at 20300 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 20308 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 20310 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_gfx: power-controller at 20320 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 20400 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_venc_pipe: power-controller at 21000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 21008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me1: power-controller at 21010 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+		power-domains = <&ps_venc>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t7001.dtsi b/arch/arm64/boot/dts/apple/t7001.dtsi
index a76e034c85e3..c471f57cca0e 100644
--- a/arch/arm64/boot/dts/apple/t7001.dtsi
+++ b/arch/arm64/boot/dts/apple/t7001.dtsi
@@ -72,9 +72,18 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t7000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x24000>;
+		};
+
 		wdt: watchdog at 20e027000 {
 			compatible = "apple,t7000-wdt", "apple,wdt";
 			reg = <0x2 0x0e027000 0x0 0x1000>;
@@ -88,11 +97,13 @@ aic: interrupt-controller at 20e100000 {
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl: pinctrl at 20e300000 {
 			compatible = "apple,t7000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0e300000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -121,3 +132,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t7001-pmgr.dtsi"
-- 
2.47.1



From tabba at google.com  Sun Dec  1 08:01:39 2024
From: tabba at google.com (Fuad Tabba)
Date: Sun, 1 Dec 2024 16:01:39 +0000
Subject: [PATCH v3 14/15] KVM: arm64: Convert the SVE guest vcpu flag to a
 vm flag
In-Reply-To: <864j3nv9tk.wl-maz@kernel.org>
References: <20241128123515.1709777-1-tabba@google.com> <20241128123515.1709777-15-tabba@google.com>
 <864j3nv9tk.wl-maz@kernel.org>
Message-ID: <CA+EHjTyXj6NhUcxTfER=zPz3VOtd+HgqpfmyfR88cVyiXoxqwA@mail.gmail.com>

Hi Marc,


On Sun, 1 Dec 2024 at 12:58, Marc Zyngier <maz at kernel.org> wrote:
>
> On Thu, 28 Nov 2024 12:35:14 +0000,
> Fuad Tabba <tabba at google.com> wrote:
> >
> > The vcpu flag GUEST_HAS_SVE is per-vcpu, but it is based on what
> > is now a per-vm feature. Make the flag per-vm.
> >
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_emulate.h    |  6 +++---
> >  arch/arm64/include/asm/kvm_host.h       | 10 ++++++----
> >  arch/arm64/kvm/hyp/include/hyp/switch.h |  2 +-
> >  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  2 +-
> >  arch/arm64/kvm/hyp/nvhe/pkvm.c          | 11 +++++++----
> >  arch/arm64/kvm/hyp/nvhe/switch.c        |  8 ++++----
> >  arch/arm64/kvm/hyp/vhe/switch.c         |  2 +-
> >  arch/arm64/kvm/reset.c                  |  2 +-
> >  8 files changed, 24 insertions(+), 19 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > index 406e99a452bf..ae6d0dc0e4ff 100644
> > --- a/arch/arm64/include/asm/kvm_emulate.h
> > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > @@ -620,7 +620,7 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
> >  }
> >
> >  /* Resets the value of cptr_el2 when returning to the host. */
> > -static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> > +static __always_inline void kvm_reset_cptr_el2(struct kvm *kvm)
>
> I'd rather you avoid the resulting churn:
>
> static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> {
>         struct kvm *kvm = kern_hyp_va(vcpu->kvm);
>         [...]
>
> which does the trick at zero cost. It is also more logical to keep the
> vcpu as a parameter, as the per-VM-ness is only an implementation
> detail.

The reason for the churn (here and below for vcpu_has_sve()), which in
hindsight I should have mentioned in the commit message or as a note,
is that this code is called by the host kernel (e.g., in reset.c), and
by the hypervisor). For nvhe, we need kern_hyp_va(), but not for the
host. Should I gate the va conversion with is_hyp_nvhe()?

> >  {
> >       u64 val;
> >
> > @@ -631,14 +631,14 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> >       } else if (has_hvhe()) {
> >               val = CPACR_ELx_FPEN;
> >
> > -             if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
> > +             if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
> >                       val |= CPACR_ELx_ZEN;
> >               if (cpus_have_final_cap(ARM64_SME))
> >                       val |= CPACR_ELx_SMEN;
> >       } else {
> >               val = CPTR_NVHE_EL2_RES1;
> >
> > -             if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
> > +             if (kvm_has_sve(kvm) && guest_owns_fp_regs())
> >                       val |= CPTR_EL2_TZ;
> >               if (!cpus_have_final_cap(ARM64_SME))
> >                       val |= CPTR_EL2_TSM;
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 680ecef1d7aa..c5c80c789ad0 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -331,6 +331,8 @@ struct kvm_arch {
> >  #define KVM_ARCH_FLAG_ID_REGS_INITIALIZED            7
> >       /* Fine-Grained UNDEF initialised */
> >  #define KVM_ARCH_FLAG_FGU_INITIALIZED                        8
> > +     /* SVE exposed to guest */
> > +#define KVM_ARCH_FLAG_GUEST_HAS_SVE                  9
> >       unsigned long flags;
> >
> >       /* VM-wide vCPU feature set */
> > @@ -862,8 +864,6 @@ struct kvm_vcpu_arch {
> >  #define vcpu_set_flag(v, ...)        __vcpu_set_flag((v), __VA_ARGS__)
> >  #define vcpu_clear_flag(v, ...)      __vcpu_clear_flag((v), __VA_ARGS__)
> >
> > -/* SVE exposed to guest */
> > -#define GUEST_HAS_SVE                __vcpu_single_flag(cflags, BIT(0))
> >  /* SVE config completed */
> >  #define VCPU_SVE_FINALIZED   __vcpu_single_flag(cflags, BIT(1))
> >  /* KVM_ARM_VCPU_INIT completed */
> > @@ -956,8 +956,10 @@ struct kvm_vcpu_arch {
> >                                KVM_GUESTDBG_USE_HW | \
> >                                KVM_GUESTDBG_SINGLESTEP)
> >
> > -#define vcpu_has_sve(vcpu) (system_supports_sve() &&                 \
> > -                         vcpu_get_flag(vcpu, GUEST_HAS_SVE))
> > +#define kvm_has_sve(kvm)     \
> > +     test_bit(KVM_ARCH_FLAG_GUEST_HAS_SVE, &(kvm)->arch.flags)
> > +#define vcpu_has_sve(vcpu)   \
> > +     kvm_has_sve((vcpu)->kvm)
>
> Two things:
>
> - it is definitely worth keeping the system_supports_sve() helper, so
>   that we avoid checking flags for nothing

Ack

> - Since you preserve the vcpu_has_sve(), how about writing it as:
>
> #ifdef __KVM_NVHE_HYPERVISOR__
> #define vcpu_has_sve(v)         kvm_has_sve(kern_hyp_va((v)->kvm))
> #else
> #define vcpu_has_sve(v)         kvm_has_sve((v)->kvm)
> #endif
>
>   which will avoid the churn in this patch, and makes it hard to get
>   it wrong?

Same as I mentioned above. This macro is even used in more places by
the host kernel.

Thanks,
/fuad

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


From towinchenmi at gmail.com  Sun Dec  1 08:18:41 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon,  2 Dec 2024 00:18:41 +0800
Subject: [PATCH 1/3] dt-bindings: arm: apple: Add T2 devices
In-Reply-To: <20241201161942.36027-1-towinchenmi@gmail.com>
References: <20241201161942.36027-1-towinchenmi@gmail.com>
Message-ID: <20241201161942.36027-2-towinchenmi@gmail.com>

This adds the following apple,t8012 based platforms:

- Apple T2 MacBookPro15,2 (j132)
- Apple T2 iMacPro1,1 (j137)
- Apple T2 MacBookAir8,2 (j140a)
- Apple T2 MacBookAir8,1 (j140k)
- Apple T2 MacBookPro16,1 (j152f)
- Apple T2 MacPro7,1 (j160)
- Apple T2 Macmini8,1 (j174)
- Apple T2 iMac20,1 (j185)
- Apple T2 iMac20,2 (j185f)
- Apple T2 MacBookPro15,4 (j213)
- Apple T2 MacBookPro16,2 (j214k)
- Apple T2 MacBookPro16,4 (j215)
- Apple T2 MacBookPro16,3 (j223)
- Apple T2 MacBookAir9,1 (j230k)
- Apple T2 MacBookPro15,1 (j680)
- Apple T2 MacBookPro15,3 (j780)

These devices have no offical names, the naming scheme is from
libirecovery.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../devicetree/bindings/arm/apple.yaml        | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/apple.yaml b/Documentation/devicetree/bindings/arm/apple.yaml
index dc9aab19ff11..da60e9de1cfb 100644
--- a/Documentation/devicetree/bindings/arm/apple.yaml
+++ b/Documentation/devicetree/bindings/arm/apple.yaml
@@ -57,6 +57,25 @@ description: |
   - iPad Pro (2nd Generation) (10.5 Inch)
   - iPad Pro (2nd Generation) (12.9 Inch)
 
+  Devices based on the "T2" SoC:
+
+  - Apple T2 MacBookPro15,2 (j132)
+  - Apple T2 iMacPro1,1 (j137)
+  - Apple T2 MacBookAir8,2 (j140a)
+  - Apple T2 MacBookAir8,1 (j140k)
+  - Apple T2 MacBookPro16,1 (j152f)
+  - Apple T2 MacPro7,1 (j160)
+  - Apple T2 Macmini8,1 (j174)
+  - Apple T2 iMac20,1 (j185)
+  - Apple T2 iMac20,2 (j185f)
+  - Apple T2 MacBookPro15,4 (j213)
+  - Apple T2 MacBookPro16,2 (j214k)
+  - Apple T2 MacBookPro16,4 (j215)
+  - Apple T2 MacBookPro16,3 (j223)
+  - Apple T2 MacBookAir9,1 (j230k)
+  - Apple T2 MacBookPro15,1 (j680)
+  - Apple T2 MacBookPro15,3 (j780)
+
   Devices based on the "A11" SoC:
 
   - iPhone 8
@@ -211,6 +230,28 @@ properties:
           - const: apple,t8011
           - const: apple,arm-platform
 
+      - description: Apple T2 SoC based platforms
+        items:
+          - enum:
+              - apple,j132  # Apple T2 MacBookPro15,2 (j132)
+              - apple,j137  # Apple T2 iMacPro1,1 (j137)
+              - apple,j140a # Apple T2 MacBookAir8,2 (j140a)
+              - apple,j140k # Apple T2 MacBookAir8,1 (j140k)
+              - apple,j152f # Apple T2 MacBookPro16,1 (j152f)
+              - apple,j160  # Apple T2 MacPro7,1 (j160)
+              - apple,j174  # Apple T2 Macmini8,1 (j174)
+              - apple,j185  # Apple T2 iMac20,1 (j185)
+              - apple,j185f # Apple T2 iMac20,2 (j185f)
+              - apple,j213  # Apple T2 MacBookPro15,4 (j213)
+              - apple,j214k # Apple T2 MacBookPro16,2 (j214k)
+              - apple,j215  # Apple T2 MacBookPro16,4 (j215)
+              - apple,j223  # Apple T2 MacBookPro16,3 (j223)
+              - apple,j230k # Apple T2 MacBookAir9,1 (j230k)
+              - apple,j680  # Apple T2 MacBookPro15,1 (j680)
+              - apple,j780  # Apple T2 MacBookPro15,3 (j780)
+          - const: apple,t8012
+          - const: apple,arm-platform
+
       - description: Apple A11 SoC based platforms
         items:
           - enum:
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 08:18:42 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon,  2 Dec 2024 00:18:42 +0800
Subject: [PATCH 2/3] arm64: dts: apple: Add T2 devices
In-Reply-To: <20241201161942.36027-1-towinchenmi@gmail.com>
References: <20241201161942.36027-1-towinchenmi@gmail.com>
Message-ID: <20241201161942.36027-3-towinchenmi@gmail.com>

Add DTS files for the T2 SoC and the following devices based on it:

- Apple T2 MacBookPro15,2 (j132)
- Apple T2 iMacPro1,1 (j137)
- Apple T2 MacBookAir8,2 (j140a)
- Apple T2 MacBookAir8,1 (j140k)
- Apple T2 MacBookPro16,1 (j152f)
- Apple T2 MacPro7,1 (j160)
- Apple T2 Macmini8,1 (j174)
- Apple T2 iMac20,1 (j185)
- Apple T2 iMac20,2 (j185f)
- Apple T2 MacBookPro15,4 (j213)
- Apple T2 MacBookPro16,2 (j214k)
- Apple T2 MacBookPro16,4 (j215)
- Apple T2 MacBookPro16,3 (j223)
- Apple T2 MacBookAir9,1 (j230k)
- Apple T2 MacBookPro15,1 (j680)
- Apple T2 MacBookPro15,3 (j780)

The Apple T2 is an A10-based security chip found on some Intel Macs
from 2017 onwards. On models with a touchbar, the touchbar's
display is wired to it. These devices have no offical names, the
naming scheme is from libirecovery.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/Makefile            |  16 ++
 arch/arm64/boot/dts/apple/t8012-j132.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j137.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j140a.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j140k.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j152f.dts     |  15 ++
 arch/arm64/boot/dts/apple/t8012-j160.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j174.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j185.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j185f.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j213.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j214k.dts     |  15 ++
 arch/arm64/boot/dts/apple/t8012-j215.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j223.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j230k.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j680.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j780.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi     |  44 +++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |  19 ++
 arch/arm64/boot/dts/apple/t8012.dtsi          | 176 ++++++++++++++++++
 20 files changed, 486 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j132.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j137.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140a.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j152f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j160.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j174.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j213.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j214k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j215.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j223.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j230k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j680.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j780.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012.dtsi

diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
index ab6ebb53218a..4f337bff36cd 100644
--- a/arch/arm64/boot/dts/apple/Makefile
+++ b/arch/arm64/boot/dts/apple/Makefile
@@ -46,6 +46,22 @@ dtb-$(CONFIG_ARCH_APPLE) += t8011-j120.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8011-j121.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8011-j207.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8011-j208.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j132.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j137.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j140a.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j140k.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j152f.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j160.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j174.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j185.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j185f.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j213.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j215.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j223.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j230k.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j214k.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j680.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j780.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8015-d201.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8015-d20.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8015-d211.dtb
diff --git a/arch/arm64/boot/dts/apple/t8012-j132.dts b/arch/arm64/boot/dts/apple/t8012-j132.dts
new file mode 100644
index 000000000000..778a69be18dd
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j132.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,2 (j132), J132, iBridge2,4
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,2 (j132)";
+	compatible = "apple,j132", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j137.dts b/arch/arm64/boot/dts/apple/t8012-j137.dts
new file mode 100644
index 000000000000..dbde1ad7ce14
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j137.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 iMacPro1,1 (j137), J137, iBridge2,1
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 iMacPro1,1 (j137)";
+	compatible = "apple,j137", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j140a.dts b/arch/arm64/boot/dts/apple/t8012-j140a.dts
new file mode 100644
index 000000000000..5df1ff74d2df
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j140a.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookAir8,2 (j140a), J140a, iBridge2,12
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookAir8,2 (j140a)";
+	compatible = "apple,j140a", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j140k.dts b/arch/arm64/boot/dts/apple/t8012-j140k.dts
new file mode 100644
index 000000000000..a0ef1585e5c2
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j140k.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookAir8,1 (j140k), J140k, iBridge2,8
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookAir8,1 (j140k)";
+	compatible = "apple,j140k", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j152f.dts b/arch/arm64/boot/dts/apple/t8012-j152f.dts
new file mode 100644
index 000000000000..261416eaf97e
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j152f.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,1 (j152f), J152f, iBridge2,14
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,1 (j152f)";
+	compatible = "apple,j152f", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j160.dts b/arch/arm64/boot/dts/apple/t8012-j160.dts
new file mode 100644
index 000000000000..fbcc0604f4a0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j160.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacPro7,1 (j160), J160, iBridge2,6
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacPro7,1 (j160)";
+	compatible = "apple,j160", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j174.dts b/arch/arm64/boot/dts/apple/t8012-j174.dts
new file mode 100644
index 000000000000..d11c70f84a71
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j174.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 Macmini8,1 (j174), J174, iBridge2,5
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 Macmini8,1 (j174)";
+	compatible = "apple,j174", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j185.dts b/arch/arm64/boot/dts/apple/t8012-j185.dts
new file mode 100644
index 000000000000..33492f5db46d
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j185.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 iMac20,1 (j185), J185, iBridge2,19
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 iMac20,1 (j185)";
+	compatible = "apple,j185", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j185f.dts b/arch/arm64/boot/dts/apple/t8012-j185f.dts
new file mode 100644
index 000000000000..3a4abdd8f7d7
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j185f.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 iMac20,2 (j185f), J185f, iBridge2,20
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 iMac20,2 (j185f)";
+	compatible = "apple,j185f", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j213.dts b/arch/arm64/boot/dts/apple/t8012-j213.dts
new file mode 100644
index 000000000000..8270812b9a68
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j213.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,4 (j213), J213, iBridge2,10
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,4 (j213)";
+	compatible = "apple,j213", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j214k.dts b/arch/arm64/boot/dts/apple/t8012-j214k.dts
new file mode 100644
index 000000000000..5b8e42512060
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j214k.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,2 (j214k), J214k, iBridge2,16
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,2 (j214k)";
+	compatible = "apple,j214k", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j215.dts b/arch/arm64/boot/dts/apple/t8012-j215.dts
new file mode 100644
index 000000000000..ad574fbf7f92
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j215.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,4 (j215), J215, iBridge2,22
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,4 (j215)";
+	compatible = "apple,j215", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j223.dts b/arch/arm64/boot/dts/apple/t8012-j223.dts
new file mode 100644
index 000000000000..de75d775aac5
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j223.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,3 (j223), J223, iBridge2,21
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,3 (j223)";
+	compatible = "apple,j223", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j230k.dts b/arch/arm64/boot/dts/apple/t8012-j230k.dts
new file mode 100644
index 000000000000..4b19bc70ab0f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j230k.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookAir9,1 (j230k), J230k, iBridge2,15
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookAir9,1 (j230k)";
+	compatible = "apple,j230k", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j680.dts b/arch/arm64/boot/dts/apple/t8012-j680.dts
new file mode 100644
index 000000000000..aa5a72e07d3f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j680.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,1 (j680), J680, iBridge2,3
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,1 (j680)";
+	compatible = "apple,j680", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j780.dts b/arch/arm64/boot/dts/apple/t8012-j780.dts
new file mode 100644
index 000000000000..9cee891cb16d
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j780.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,3 (j780), J780, iBridge2,7
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,3 (j780)";
+	compatible = "apple,j780", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
new file mode 100644
index 000000000000..36e82633bc52
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Common Device Tree for all T2 devices
+ *
+ * target-type: J132, J137, J140a, J140k, J152f, J160, J174, J185, J185f
+ * J213, J214k, J215, J223, J230k, J680, J780
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include "t8012.dtsi"
+
+/ {
+	chassis-type = "embedded";
+
+	aliases {
+		serial0 = &serial0;
+	};
+
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		stdout-path = "serial0";
+	};
+
+	memory at 800000000 {
+		device_type = "memory";
+		reg = <0x8 0 0 0>; /* To be filled by loader */
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* To be filled by loader */
+	};
+};
+
+&serial0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
new file mode 100644
index 000000000000..f4a8b12437f0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Common Device Tree for T2 devices with a Touch Bar
+ *
+ * target-type: J152f, J213, J214k, J215, J223, J680, J780
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/ {
+	chosen {
+		framebuffer0: framebuffer at 0 {
+			compatible = "apple,simple-framebuffer", "simple-framebuffer";
+			reg = <0 0 0 0>; /* To be filled by loader */
+			/* Format properties will be added by loader */
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8012.dtsi b/arch/arm64/boot/dts/apple/t8012.dtsi
new file mode 100644
index 000000000000..45d24ca091b0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012.dtsi
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T8012 "T2" SoC
+ *
+ * Other names: H9M, "Gibraltar"
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/apple.h>
+
+/ {
+	interrupt-parent = <&aic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clkref: clock-ref {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "clkref";
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 10000 {
+			compatible = "apple,hurricane-zephyr";
+			reg = <0x0 0x10000>;
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+
+		cpu1: cpu at 10001 {
+			compatible = "apple,hurricane-zephyr";
+			reg = <0x0 0x10001>;
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		nonposted-mmio;
+		ranges;
+
+		serial0: serial at 20a600000 {
+			compatible = "apple,s5l-uart";
+			reg = <0x2 0x0a600000 0x0 0x4000>;
+			reg-io-width = <4>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 271 IRQ_TYPE_LEVEL_HIGH>;
+			/* Use the bootloader-enabled clocks for now. */
+			clocks = <&clkref>, <&clkref>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		aic: interrupt-controller at 20e100000 {
+			compatible = "apple,t8010-aic", "apple,aic";
+			reg = <0x2 0x0e100000 0x0 0x100000>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+		};
+
+		pinctrl_ap: pinctrl at 20f100000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x0f100000 0x0 0x100000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_ap 0 0 221>;
+			apple,npins = <221>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 51 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_aop: pinctrl at 2100f0000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x0100f0000 0x0 0x10000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_aop 0 0 41>;
+			apple,npins = <41>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 131 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 132 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 133 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 134 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 135 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 136 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 137 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_nub: pinctrl at 2111f0000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x111f0000 0x0 0x1000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_nub 0 0 19>;
+			apple,npins = <19>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 164 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 165 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 166 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		wdt: watchdog at 2112b0000 {
+			compatible = "apple,t8010-wdt", "apple,wdt";
+			reg = <0x2 0x112b0000 0x0 0x4000>;
+			clocks = <&clkref>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 168 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_smc: pinctrl at 212024000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x12024000 0x0 0x1000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_smc 0 0 81>;
+			apple,npins = <81>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 195 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 196 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 197 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 198 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 199 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 200 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 201 IRQ_TYPE_LEVEL_HIGH>;
+			/*
+			 * SMC is not yet supported and accessing this pinctrl while SMC is
+			 * suspended results in a hang.
+			 */
+			status = "disabled";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&aic>;
+		interrupt-names = "phys", "virt";
+		/* Note that T2 doesn't actually have a hypervisor (EL2 is not implemented). */
+		interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>,
+			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 08:18:40 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon,  2 Dec 2024 00:18:40 +0800
Subject: [PATCH 0/3] Device Tree for Apple T2 (T8012) SoC devices
Message-ID: <20241201161942.36027-1-towinchenmi@gmail.com>

This series adds device trees for the Apple T2 Security Chip found on
some Intel Macs released after 2017. This SoC is based on Apple A10
(T8010) SoC and, for many hardware blocks, can share the A10 compatibles.

This series requires the PMGR power domains series for A7-A11[1] for
the "apple,t8010-pmgr-pwrstate" and "apple,t8010-pmgr" compaibles,
but otherwise can be applied cleanly.

[1]: https://lore.kernel.org/asahi/20241201155820.29259-1-towinchenmi at gmail.com/T

Nick Chan
---

Nick Chan (3):
  dt-bindings: arm: apple: Add T2 devices
  arm64: dts: apple: Add T2 devices
  arm64: dts: apple: t8012: Add PMGR nodes

 .../devicetree/bindings/arm/apple.yaml        |  41 +
 arch/arm64/boot/dts/apple/Makefile            |  16 +
 arch/arm64/boot/dts/apple/t8012-j132.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j137.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j140a.dts     |  14 +
 arch/arm64/boot/dts/apple/t8012-j140k.dts     |  14 +
 arch/arm64/boot/dts/apple/t8012-j152f.dts     |  15 +
 arch/arm64/boot/dts/apple/t8012-j160.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j174.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j185.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j185f.dts     |  14 +
 arch/arm64/boot/dts/apple/t8012-j213.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-j214k.dts     |  15 +
 arch/arm64/boot/dts/apple/t8012-j215.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-j223.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-j230k.dts     |  14 +
 arch/arm64/boot/dts/apple/t8012-j680.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-j780.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi     |  44 +
 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi     | 837 ++++++++++++++++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |  20 +
 arch/arm64/boot/dts/apple/t8012.dtsi          | 198 +++++
 22 files changed, 1387 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j132.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j137.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140a.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j152f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j160.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j174.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j213.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j214k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j215.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j223.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j230k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j680.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j780.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012.dtsi


base-commit: fb4ec083bbf366f092f9064b18531be92756745b
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  1 08:18:43 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon,  2 Dec 2024 00:18:43 +0800
Subject: [PATCH 3/3] arm64: dts: apple: t8012: Add PMGR nodes
In-Reply-To: <20241201161942.36027-1-towinchenmi@gmail.com>
References: <20241201161942.36027-1-towinchenmi@gmail.com>
Message-ID: <20241201161942.36027-4-towinchenmi@gmail.com>

This adds the two PMGR nodes and all known power state subnodes. Since
there are a large number of them, let's put them in a separate file to
include.

On models with only 1 GB of memory, only two memory channels are used,
and on models with 2 GB of memory, four memory channels are used. The
"apple,always-on" property of the extra memory channel power domains
(ps_dcs2, ps_dcs3) will be removed by loader on models with 1 GB of
memory.

The amount of memory depends on the storage configuration of the Mac.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi     | 837 ++++++++++++++++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8012.dtsi          |  22 +
 3 files changed, 860 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8012-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8012-pmgr.dtsi
new file mode 100644
index 000000000000..35a462edd4af
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-pmgr.dtsi
@@ -0,0 +1,837 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8012 "T2" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80158 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80160 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_iomux: power-controller at 80150 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_gpio: power-controller at 80110 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pcie_down_ref: power-controller at 80138 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_down_ref";
+	};
+
+	ps_pcie_stg0_ref: power-controller at 80140 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg0_ref";
+	};
+
+	ps_pcie_stg1_ref: power-controller at 80148 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg1_ref";
+	};
+
+	ps_mca0: power-controller at 80170 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80178 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80180 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80188 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80190 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca5: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80168 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_isp_sens0: power-controller at 80120 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80128 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_isp_sens2: power-controller at 80130 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens2";
+	};
+
+	ps_pms: power-controller at 80118 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_i2c4: power-controller at 801c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c5: power-controller at 801d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c6: power-controller at 801d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_usb: power-controller at 80268 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80270 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80278 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80288 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp_sys: power-controller at 802d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 802e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp0_be: power-controller at 802b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_uart0: power-controller at 80200 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 80208 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 80210 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 80218 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80220 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_dpa: power-controller at 80228 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80230 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80240 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80248 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80250 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80258 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		/* Not used on some devicecs, to be disabled by loader */
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80260 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		/* Not used on some devicecs, to be disabled by loader */
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80280 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 80290 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 80298 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_pmp: power-controller at 802f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 802f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_pcie_up_af: power-controller at 80320 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_up_af";
+		power-domains = <&ps_iomux>;
+	};
+
+	ps_pcie_up: power-controller at 80328 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_up";
+		power-domains = <&ps_pcie_up_af>;
+	};
+
+	ps_venc_sys: power-controller at 80300 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans2: power-controller at 80308 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans2";
+		power-domains = <&ps_iomux>;
+	};
+
+	ps_pcie_down: power-controller at 80310 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_down";
+		power-domains = <&ps_iomux>;
+	};
+
+	ps_pcie_down_aux: power-controller at 80318 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_down_aux";
+	};
+
+	ps_pcie_up_aux: power-controller at 80330 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_up_aux";
+		power-domains = <&ps_pcie_up>;
+	};
+
+	ps_pcie_stg0: power-controller at 80338 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg0";
+		power-domains = <&ps_ans2>;
+	};
+
+	ps_pcie_stg0_aux: power-controller at 80340 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80340 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg0_aux";
+	};
+
+	ps_pcie_stg1: power-controller at 80348 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80348 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg1";
+		power-domains = <&ps_ans2>;
+	};
+
+	ps_pcie_stg1_aux: power-controller at 80350 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80350 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg1_aux";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_pipe4: power-controller at 88000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+	};
+
+	ps_venc_pipe5: power-controller at 88008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+	};
+
+	ps_venc_me0: power-controller at 88010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_spmi: power-controller at 80058 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spmi";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_nub_aon: power-controller at 80060 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80060 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "nub_aon";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_smc_fabric: power-controller at 80030 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_fabric";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_smc_aon: power-controller at 80088 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80088 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_aon";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_debug: power-controller at 80050 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_nub_sram: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "nub_sram";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_nub_fabric: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "nub_fabric";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_smc_cpu: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_cpu";
+		power-domains = <&ps_smc_fabric &ps_smc_aon>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
index f4a8b12437f0..fc4a80d0c787 100644
--- a/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
+++ b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
@@ -12,6 +12,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t8012.dtsi b/arch/arm64/boot/dts/apple/t8012.dtsi
index 45d24ca091b0..907ba127be79 100644
--- a/arch/arm64/boot/dts/apple/t8012.dtsi
+++ b/arch/arm64/boot/dts/apple/t8012.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a600000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,t8010-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -130,6 +141,14 @@ pinctrl_nub: pinctrl at 2111f0000 {
 				     <AIC_IRQ 166 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 211200000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x11200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2112b0000 {
 			compatible = "apple,t8010-wdt", "apple,wdt";
 			reg = <0x2 0x112b0000 0x0 0x4000>;
@@ -141,6 +160,7 @@ wdt: watchdog at 2112b0000 {
 		pinctrl_smc: pinctrl at 212024000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x12024000 0x0 0x1000>;
+			power-domains = <&ps_smc_cpu>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -174,3 +194,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8012-pmgr.dtsi"
-- 
2.47.1



From Jiaxin.Yu at mediatek.com  Sun Dec  1 09:15:45 2024
From: Jiaxin.Yu at mediatek.com (=?utf-8?B?SmlheGluIFl1ICjkv57lrrbpkasp?=)
Date: Sun, 1 Dec 2024 17:15:45 +0000
Subject: [PATCH v2 1/3] ASoC: hdmi-codec: Add event handler for hdmi TX
In-Reply-To: <Y5ipwqzHKTK8UdlC@sirena.org.uk>
References: <20221125094413.4940-1-jiaxin.yu@mediatek.com>
	 <20221125094413.4940-2-jiaxin.yu@mediatek.com>
	 <Y4Cysgk5Gic5ae9B@sirena.org.uk>
	 <18c82f6f723cd97a9d6b9a7ff16c6ed62fd005d6.camel@mediatek.com>
	 <Y4Y/vEWe3dw0FPQH@sirena.org.uk>
	 <cf9ea98a3263ffb8fc8b542888ad0ad680facfc7.camel@mediatek.com>
	 <Y4jHAJgmz/P58Q/C@sirena.org.uk>
	 <7023a2c7b471d6888d9079563a6c01f22599201f.camel@mediatek.com>
	 <Y43e+EsNCrCpZSIH@sirena.org.uk>
	 <dc50d0b21795acbcc44c77e5fd81e7cb92c65c67.camel@mediatek.com>
	 <Y5ipwqzHKTK8UdlC@sirena.org.uk>
Message-ID: <a699178dcef540fff5caae6291983a444886bff6.camel@mediatek.com>

On Tue, 2022-12-13 at 16:35 +0000, Mark Brown wrote:
> On Tue, Dec 13, 2022 at 02:23:32PM +0000, Jiaxin Yu (???) wrote:
> > On Mon, 2022-12-05 at 12:07 +0000, Mark Brown wrote:
> > > On Mon, Dec 05, 2022 at 09:34:17AM +0000, Jiaxin Yu (???) wrote:
> > > No, I mean that if you want to control the enable and disable of
> > > the
> > > output path you should implement a DAPM widget.
> > May I ask which driver file to add a new DAPM widget? Is it the
> > bridge
> > ic driver like it6505.c? Or is it linke the "SDB" added in this
> > patch?
> 
> I would expect this to follow a similar pattern to everything else
> with
> hdmi-codec.c and have the actual ASoC stuff in there with a callback
> exposed to the rest of the world.
> 
> > Yes, I should add a new set of events, such as:
> > enum {
> >     HDMI_CODEC_TRIGGER_EVENT_STOP,
> >     HDMI_CODEC_TRIGGER_EVENT_START,
> >     HDMI_CODEC_TRIGGER_EVENT_SUSPEND,
> >     HDMI_CODEC_TRIGGER_EVENT_RESUME,
> > }
> > Then provide handles for these events in the it6505 driver. Am I
> > right?
> 
> I'd expect more like on/off for a DAPM widget (the DAPM callbacks are
> pre/post on/off) but yes.

Dear mark,
I apologize for the delay in responding to this issue, as we have
recently encountered the same problem again. I would like to have your
guidance on this issue once more. Let me describe the problem we
encountered again.


                     ==> "hdmi-audio-codec"(it6505 plug-in)
DL1(FE) ==> I2S1(BE) 
                     ==> "rt1019p"(Speaker Codec)

I want to independently control the switches for the speaker and hdmi,
and realize that when HDMI is plugged in, I can switch to speaker
playback, and I can also switch back to hdmi playback too. Of course,
I2S1 is used for playback at this time. 

So I want to ask if I can do it by just adding
SOC_DAPM_PIN_SWITCH("Speakers") and SOC_DAPM_PIN_SWITCH("HDMI")?
Correspondingly, dapm widget and route path need to be added. That is
"SND_SOC_DAPM_SPK("Speakers", NULL)/ SND_SOC_DAPM_LINE("HDMI1", NULL)"
and "{"Speakers", NULL, "Speaker"}/ {"HDMI1", NULL, "TX"}".

If the above is not enough, what else should I modify? hdmi-codec.c or
it6505.c? Looking forward to getting you reply, Thank you.

Jiaxin.Yu





From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:09 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:09 +0100
Subject: [PATCH v4 09/18] dt-bindings: clock: imx8mn: add binding definitions for anatop
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-10-dario.binacchi@amarulasolutions.com>

Add the bindings definitions for the anatop node. The patch is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 include/dt-bindings/clock/imx8mn-clock.h | 67 ++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
index 04809edab33c..732ff87a16c2 100644
--- a/include/dt-bindings/clock/imx8mn-clock.h
+++ b/include/dt-bindings/clock/imx8mn-clock.h
@@ -267,4 +267,71 @@
 
 #define IMX8MN_CLK_END				235
 
+#define IMX8MN_ANATOP_CLK_DUMMY			0
+#define IMX8MN_ANATOP_CLK_32K			1
+#define IMX8MN_ANATOP_CLK_24M			2
+#define IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL	3
+#define IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL	4
+#define IMX8MN_ANATOP_VIDEO_PLL_REF_SEL		5
+#define IMX8MN_ANATOP_DRAM_PLL_REF_SEL		6
+#define IMX8MN_ANATOP_GPU_PLL_REF_SEL		7
+#define IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL	8
+#define IMX8MN_ANATOP_ARM_PLL_REF_SEL		9
+#define IMX8MN_ANATOP_SYS_PLL3_REF_SEL		10
+#define IMX8MN_ANATOP_AUDIO_PLL1		11
+#define IMX8MN_ANATOP_AUDIO_PLL2		12
+#define IMX8MN_ANATOP_VIDEO_PLL			13
+#define IMX8MN_ANATOP_DRAM_PLL			14
+#define IMX8MN_ANATOP_GPU_PLL			15
+#define IMX8MN_ANATOP_M7_ALT_PLL		16
+#define IMX8MN_ANATOP_ARM_PLL			17
+#define IMX8MN_ANATOP_SYS_PLL1			18
+#define IMX8MN_ANATOP_SYS_PLL2			19
+#define IMX8MN_ANATOP_SYS_PLL3			20
+#define IMX8MN_ANATOP_AUDIO_PLL1_BYPASS		21
+#define IMX8MN_ANATOP_AUDIO_PLL2_BYPASS		22
+#define IMX8MN_ANATOP_VIDEO_PLL_BYPASS		23
+#define IMX8MN_ANATOP_DRAM_PLL_BYPASS		24
+#define IMX8MN_ANATOP_GPU_PLL_BYPASS		25
+#define IMX8MN_ANATOP_M7_ALT_PLL_BYPASS		26
+#define IMX8MN_ANATOP_ARM_PLL_BYPASS		27
+#define IMX8MN_ANATOP_SYS_PLL3_BYPASS		28
+#define IMX8MN_ANATOP_AUDIO_PLL1_OUT		29
+#define IMX8MN_ANATOP_AUDIO_PLL2_OUT		30
+#define IMX8MN_ANATOP_VIDEO_PLL_OUT		31
+#define IMX8MN_ANATOP_DRAM_PLL_OUT		32
+#define IMX8MN_ANATOP_GPU_PLL_OUT		33
+#define IMX8MN_ANATOP_M7_ALT_PLL_OUT		34
+#define IMX8MN_ANATOP_ARM_PLL_OUT		35
+#define IMX8MN_ANATOP_SYS_PLL3_OUT		36
+#define IMX8MN_ANATOP_SYS_PLL1_OUT		37
+#define IMX8MN_ANATOP_SYS_PLL1_40M		38
+#define IMX8MN_ANATOP_SYS_PLL1_80M		39
+#define IMX8MN_ANATOP_SYS_PLL1_100M		40
+#define IMX8MN_ANATOP_SYS_PLL1_133M		41
+#define IMX8MN_ANATOP_SYS_PLL1_160M		42
+#define IMX8MN_ANATOP_SYS_PLL1_200M		43
+#define IMX8MN_ANATOP_SYS_PLL1_266M		44
+#define IMX8MN_ANATOP_SYS_PLL1_400M		45
+#define IMX8MN_ANATOP_SYS_PLL1_800M		46
+#define IMX8MN_ANATOP_SYS_PLL2_OUT		47
+#define IMX8MN_ANATOP_SYS_PLL2_50M		48
+#define IMX8MN_ANATOP_SYS_PLL2_100M		49
+#define IMX8MN_ANATOP_SYS_PLL2_125M		50
+#define IMX8MN_ANATOP_SYS_PLL2_166M		51
+#define IMX8MN_ANATOP_SYS_PLL2_200M		52
+#define IMX8MN_ANATOP_SYS_PLL2_250M		53
+#define IMX8MN_ANATOP_SYS_PLL2_333M		54
+#define IMX8MN_ANATOP_SYS_PLL2_500M		55
+#define IMX8MN_ANATOP_SYS_PLL2_1000M		56
+
+#define IMX8MN_ANATOP_CLK_CLKOUT1_SEL		57
+#define IMX8MN_ANATOP_CLK_CLKOUT1_DIV		58
+#define IMX8MN_ANATOP_CLK_CLKOUT1		59
+#define IMX8MN_ANATOP_CLK_CLKOUT2_SEL		60
+#define IMX8MN_ANATOP_CLK_CLKOUT2_DIV		61
+#define IMX8MN_ANATOP_CLK_CLKOUT2		62
+
+#define IMX8MN_ANATOP_CLK_END			63
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:10 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:10 +0100
Subject: [PATCH v4 10/18] dt-bindings: clock: imx8mp: add binding definitions for anatop
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-11-dario.binacchi@amarulasolutions.com>

Add the bindings definitions for the anatop node. The patch is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 include/dt-bindings/clock/imx8mp-clock.h | 70 ++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
index 0601df6c8d38..39e4ad470927 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -401,4 +401,74 @@
 
 #define IMX8MP_CLK_AUDIOMIX_END			59
 
+#define IMX8MP_ANATOP_CLK_DUMMY			0
+#define IMX8MP_ANATOP_CLK_24M			1
+#define IMX8MP_ANATOP_CLK_32K			2
+#define IMX8MP_ANATOP_AUDIO_PLL1_REF_SEL	3
+#define IMX8MP_ANATOP_AUDIO_PLL2_REF_SEL	4
+#define IMX8MP_ANATOP_VIDEO_PLL_REF_SEL		5
+#define IMX8MP_ANATOP_DRAM_PLL_REF_SEL		6
+#define IMX8MP_ANATOP_GPU_PLL_REF_SEL		7
+#define IMX8MP_ANATOP_VPU_PLL_REF_SEL		8
+#define IMX8MP_ANATOP_ARM_PLL_REF_SEL		9
+#define IMX8MP_ANATOP_SYS_PLL1_REF_SEL		10
+#define IMX8MP_ANATOP_SYS_PLL2_REF_SEL		11
+#define IMX8MP_ANATOP_SYS_PLL3_REF_SEL		12
+#define IMX8MP_ANATOP_AUDIO_PLL1		13
+#define IMX8MP_ANATOP_AUDIO_PLL2		14
+#define IMX8MP_ANATOP_VIDEO_PLL			15
+#define IMX8MP_ANATOP_DRAM_PLL			16
+#define IMX8MP_ANATOP_GPU_PLL			17
+#define IMX8MP_ANATOP_VPU_PLL			18
+#define IMX8MP_ANATOP_ARM_PLL			19
+#define IMX8MP_ANATOP_SYS_PLL1			20
+#define IMX8MP_ANATOP_SYS_PLL2			21
+#define IMX8MP_ANATOP_SYS_PLL3			22
+#define IMX8MP_ANATOP_AUDIO_PLL1_BYPASS		23
+#define IMX8MP_ANATOP_AUDIO_PLL2_BYPASS		24
+#define IMX8MP_ANATOP_VIDEO_PLL_BYPASS		25
+#define IMX8MP_ANATOP_DRAM_PLL_BYPASS		26
+#define IMX8MP_ANATOP_GPU_PLL_BYPASS		27
+#define IMX8MP_ANATOP_VPU_PLL_BYPASS		28
+#define IMX8MP_ANATOP_ARM_PLL_BYPASS		29
+#define IMX8MP_ANATOP_SYS_PLL1_BYPASS		30
+#define IMX8MP_ANATOP_SYS_PLL2_BYPASS		31
+#define IMX8MP_ANATOP_SYS_PLL3_BYPASS		32
+#define IMX8MP_ANATOP_AUDIO_PLL1_OUT		33
+#define IMX8MP_ANATOP_AUDIO_PLL2_OUT		34
+#define IMX8MP_ANATOP_VIDEO_PLL_OUT		35
+#define IMX8MP_ANATOP_DRAM_PLL_OUT		36
+#define IMX8MP_ANATOP_GPU_PLL_OUT		37
+#define IMX8MP_ANATOP_VPU_PLL_OUT		38
+#define IMX8MP_ANATOP_ARM_PLL_OUT		39
+#define IMX8MP_ANATOP_SYS_PLL3_OUT		40
+#define IMX8MP_ANATOP_SYS_PLL1_OUT		41
+#define IMX8MP_ANATOP_SYS_PLL1_40M		42
+#define IMX8MP_ANATOP_SYS_PLL1_80M		43
+#define IMX8MP_ANATOP_SYS_PLL1_100M		44
+#define IMX8MP_ANATOP_SYS_PLL1_133M		45
+#define IMX8MP_ANATOP_SYS_PLL1_160M		46
+#define IMX8MP_ANATOP_SYS_PLL1_200M		47
+#define IMX8MP_ANATOP_SYS_PLL1_266M		48
+#define IMX8MP_ANATOP_SYS_PLL1_400M		49
+#define IMX8MP_ANATOP_SYS_PLL1_800M		50
+#define IMX8MP_ANATOP_SYS_PLL2_OUT		51
+#define IMX8MP_ANATOP_SYS_PLL2_50M		52
+#define IMX8MP_ANATOP_SYS_PLL2_100M		53
+#define IMX8MP_ANATOP_SYS_PLL2_125M		54
+#define IMX8MP_ANATOP_SYS_PLL2_166M		55
+#define IMX8MP_ANATOP_SYS_PLL2_200M		56
+#define IMX8MP_ANATOP_SYS_PLL2_250M		57
+#define IMX8MP_ANATOP_SYS_PLL2_333M		58
+#define IMX8MP_ANATOP_SYS_PLL2_500M		59
+#define IMX8MP_ANATOP_SYS_PLL2_1000M		60
+#define IMX8MP_ANATOP_CLK_CLKOUT1_SEL		61
+#define IMX8MP_ANATOP_CLK_CLKOUT1_DIV		62
+#define IMX8MP_ANATOP_CLK_CLKOUT1		63
+#define IMX8MP_ANATOP_CLK_CLKOUT2_SEL		64
+#define IMX8MP_ANATOP_CLK_CLKOUT2_DIV		65
+#define IMX8MP_ANATOP_CLK_CLKOUT2		66
+
+#define IMX8MP_ANATOP_CLK_END			67
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:11 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:11 +0100
Subject: [PATCH v4 11/18] clk: imx: add hw API imx8m_anatop_get_clk_hw
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-12-dario.binacchi@amarulasolutions.com>

Get the hw of a clock registered by the anatop module. This function is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 drivers/clk/imx/clk.c | 26 ++++++++++++++++++++++++++
 drivers/clk/imx/clk.h |  6 ++++++
 2 files changed, 32 insertions(+)

diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
index df83bd939492..8a8473a77b7c 100644
--- a/drivers/clk/imx/clk.c
+++ b/drivers/clk/imx/clk.c
@@ -128,6 +128,32 @@ struct clk_hw *imx_get_clk_hw_by_name(struct device_node *np, const char *name)
 }
 EXPORT_SYMBOL_GPL(imx_get_clk_hw_by_name);
 
+#if defined(CONFIG_CLK_IMX8MM) || defined(CONFIG_CLK_IMX8MN) || \
+	defined(CONFIG_CLK_IMX8MP) || defined(CONFIG_CLK_IMX8MQ)
+struct clk_hw *imx8m_anatop_get_clk_hw(int id)
+{
+#if defined(CONFIG_CLK_IMX8MQ)
+	const char *compatible = "fsl,imx8mq-anatop";
+#else
+	const char *compatible = "fsl,imx8mm-anatop";
+#endif
+	struct device_node *np;
+	struct of_phandle_args args;
+	struct clk_hw *hw;
+
+	np = of_find_compatible_node(NULL, NULL, compatible);
+	args.np = np;
+	args.args_count = 1;
+	args.args[0] = id;
+	of_node_put(np);
+
+	hw = __clk_get_hw(of_clk_get_from_provider(&args));
+	pr_debug("%s: got clk: %s\n", __func__, clk_hw_get_name(hw));
+	return hw;
+}
+EXPORT_SYMBOL_GPL(imx8m_anatop_get_clk_hw);
+#endif
+
 /*
  * This fixups the register CCM_CSCMR1 write value.
  * The write/read/divider values of the aclk_podf field
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index aa5202f284f3..6b6af26f4f1e 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -487,4 +487,10 @@ struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible,
 			       u32 reg, const char **parent_names,
 			       u8 num_parents, const u32 *mux_table, u32 mask);
 
+
+#if defined(CONFIG_CLK_IMX8MM) || defined(CONFIG_CLK_IMX8MN) || \
+	defined(CONFIG_CLK_IMX8MP) || defined(CONFIG_CLK_IMX8MQ)
+struct clk_hw *imx8m_anatop_get_clk_hw(int id);
+#endif
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:12 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:12 +0100
Subject: [PATCH v4 12/18] clk: imx: add support for i.MX8MN anatop clock driver
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-13-dario.binacchi@amarulasolutions.com>

Support NXP i.MX8M anatop PLL module which generates PLLs to CCM root.
By doing so, we also simplify the CCM driver code. The changes are
backward compatible.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 drivers/clk/imx/Makefile            |   2 +-
 drivers/clk/imx/clk-imx8mn-anatop.c | 281 ++++++++++++++++++++++++++++
 drivers/clk/imx/clk-imx8mn.c        | 175 ++++++++---------
 3 files changed, 355 insertions(+), 103 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx8mn-anatop.c

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 03f2b2a1ab63..f0f1d01c68f8 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -26,7 +26,7 @@ mxc-clk-objs += clk-gpr-mux.o
 obj-$(CONFIG_MXC_CLK) += mxc-clk.o
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
-obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
+obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn-anatop.o clk-imx8mn.o
 obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-imx8mp-audiomix.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 
diff --git a/drivers/clk/imx/clk-imx8mn-anatop.c b/drivers/clk/imx/clk-imx8mn-anatop.c
new file mode 100644
index 000000000000..f02e4d5114a5
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mn-anatop.c
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * clk-imx8mn-anatop.c - NXP i.MX8MN anatop clock driver
+ *
+ * Copyright (c) 2022 Dario Binacchi <dario.binacchi at amarulasolutions.com>
+ */
+
+#include <dt-bindings/clock/imx8mn-clock.h>
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+
+#include "clk.h"
+
+static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
+static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", };
+static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
+					   "dummy", "dummy", "gpu_pll_out", "dummy",
+					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
+					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
+
+static struct clk_hw_onecell_data *clk_hw_data;
+static struct clk_hw **hws;
+
+static int imx8mn_anatop_clocks_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	void __iomem *base;
+	int ret;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base)) {
+		dev_err(dev, "failed to get base address\n");
+		return PTR_ERR(base);
+	}
+
+	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
+						    IMX8MN_ANATOP_CLK_END),
+				   GFP_KERNEL);
+	if (WARN_ON(!clk_hw_data))
+		return -ENOMEM;
+
+	clk_hw_data->num = IMX8MN_ANATOP_CLK_END;
+	hws = clk_hw_data->hws;
+
+	hws[IMX8MN_ANATOP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
+	hws[IMX8MN_ANATOP_CLK_32K] = imx_get_clk_hw_by_name(np, "osc_32k");
+	hws[IMX8MN_ANATOP_CLK_24M] = imx_get_clk_hw_by_name(np, "osc_24m");
+
+	hws[IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL] =
+		imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL] =
+		imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_VIDEO_PLL_REF_SEL] =
+		imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_DRAM_PLL_REF_SEL] =
+		imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_GPU_PLL_REF_SEL] =
+		imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL] =
+		imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_ARM_PLL_REF_SEL] =
+		imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_SYS_PLL3_REF_SEL] =
+		imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+	hws[IMX8MN_ANATOP_AUDIO_PLL1] =
+		imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel",
+				   base, &imx_1443x_pll);
+	hws[IMX8MN_ANATOP_AUDIO_PLL2] =
+		imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel",
+				   base + 0x14, &imx_1443x_pll);
+	hws[IMX8MN_ANATOP_VIDEO_PLL] =
+		imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel",
+				   base + 0x28, &imx_1443x_pll);
+	hws[IMX8MN_ANATOP_DRAM_PLL] =
+		imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50,
+				   &imx_1443x_dram_pll);
+	hws[IMX8MN_ANATOP_GPU_PLL] =
+		imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64,
+				   &imx_1416x_pll);
+	hws[IMX8MN_ANATOP_M7_ALT_PLL] =
+		imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel",
+				   base + 0x74, &imx_1416x_pll);
+	hws[IMX8MN_ANATOP_ARM_PLL] =
+		imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84,
+				   &imx_1416x_pll);
+	hws[IMX8MN_ANATOP_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
+	hws[IMX8MN_ANATOP_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
+	hws[IMX8MN_ANATOP_SYS_PLL3] =
+		imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114,
+				   &imx_1416x_pll);
+
+	/* PLL bypass out */
+	hws[IMX8MN_ANATOP_AUDIO_PLL1_BYPASS] =
+		imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1,
+				     audio_pll1_bypass_sels,
+				     ARRAY_SIZE(audio_pll1_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_AUDIO_PLL2_BYPASS] =
+		imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1,
+				     audio_pll2_bypass_sels,
+				     ARRAY_SIZE(audio_pll2_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_VIDEO_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1,
+				     video_pll_bypass_sels,
+				     ARRAY_SIZE(video_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_DRAM_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1,
+				     dram_pll_bypass_sels,
+				     ARRAY_SIZE(dram_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_GPU_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1,
+				     gpu_pll_bypass_sels,
+				     ARRAY_SIZE(gpu_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_M7_ALT_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1,
+				     m7_alt_pll_bypass_sels,
+				     ARRAY_SIZE(m7_alt_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_ARM_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1,
+				     arm_pll_bypass_sels,
+				     ARRAY_SIZE(arm_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_SYS_PLL3_BYPASS] =
+		imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1,
+				     sys_pll3_bypass_sels,
+				     ARRAY_SIZE(sys_pll3_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+
+	/* PLL out gate */
+	hws[IMX8MN_ANATOP_AUDIO_PLL1_OUT] =
+		imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass",
+				base, 13);
+	hws[IMX8MN_ANATOP_AUDIO_PLL2_OUT] =
+		imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass",
+				base + 0x14, 13);
+	hws[IMX8MN_ANATOP_VIDEO_PLL_OUT] =
+		imx_clk_hw_gate("video_pll_out", "video_pll_bypass",
+				base + 0x28, 13);
+	hws[IMX8MN_ANATOP_DRAM_PLL_OUT] =
+		imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass",
+				base + 0x50, 13);
+	hws[IMX8MN_ANATOP_GPU_PLL_OUT] =
+		imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass",
+				base + 0x64, 11);
+	hws[IMX8MN_ANATOP_M7_ALT_PLL_OUT] =
+		imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass",
+				base + 0x74, 11);
+	hws[IMX8MN_ANATOP_ARM_PLL_OUT] =
+		imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass",
+				base + 0x84, 11);
+	hws[IMX8MN_ANATOP_SYS_PLL3_OUT] =
+		imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass",
+				base + 0x114, 11);
+
+	/* SYS PLL1 fixed output */
+	hws[IMX8MN_ANATOP_SYS_PLL1_OUT] =
+		imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
+	hws[IMX8MN_ANATOP_SYS_PLL1_40M] =
+		imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
+	hws[IMX8MN_ANATOP_SYS_PLL1_80M] =
+		imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
+	hws[IMX8MN_ANATOP_SYS_PLL1_100M] =
+		imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
+	hws[IMX8MN_ANATOP_SYS_PLL1_133M] =
+		imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
+	hws[IMX8MN_ANATOP_SYS_PLL1_160M] =
+		imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
+	hws[IMX8MN_ANATOP_SYS_PLL1_200M] =
+		imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
+	hws[IMX8MN_ANATOP_SYS_PLL1_266M] =
+		imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
+	hws[IMX8MN_ANATOP_SYS_PLL1_400M] =
+		imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+	hws[IMX8MN_ANATOP_SYS_PLL1_800M] =
+		imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+
+	/* SYS PLL2 fixed output */
+	hws[IMX8MN_ANATOP_SYS_PLL2_OUT] =
+		imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
+	hws[IMX8MN_ANATOP_SYS_PLL2_50M] =
+		imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
+	hws[IMX8MN_ANATOP_SYS_PLL2_100M] =
+		imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
+	hws[IMX8MN_ANATOP_SYS_PLL2_125M] =
+		imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
+	hws[IMX8MN_ANATOP_SYS_PLL2_166M] =
+		imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
+	hws[IMX8MN_ANATOP_SYS_PLL2_200M] =
+		imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
+	hws[IMX8MN_ANATOP_SYS_PLL2_250M] =
+		imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
+	hws[IMX8MN_ANATOP_SYS_PLL2_333M] =
+		imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
+	hws[IMX8MN_ANATOP_SYS_PLL2_500M] =
+		imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+	hws[IMX8MN_ANATOP_SYS_PLL2_1000M] =
+		imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+
+	hws[IMX8MN_ANATOP_CLK_CLKOUT1_SEL] =
+		imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4,
+				clkout_sels, ARRAY_SIZE(clkout_sels));
+	hws[IMX8MN_ANATOP_CLK_CLKOUT1_DIV] =
+		imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128,
+				   0, 4);
+	hws[IMX8MN_ANATOP_CLK_CLKOUT1] =
+		imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8);
+	hws[IMX8MN_ANATOP_CLK_CLKOUT2_SEL]
+		= imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4,
+				  clkout_sels, ARRAY_SIZE(clkout_sels));
+	hws[IMX8MN_ANATOP_CLK_CLKOUT2_DIV] =
+		imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128,
+				   16, 4);
+	hws[IMX8MN_ANATOP_CLK_CLKOUT2] =
+		imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24);
+
+	imx_check_clk_hws(hws, IMX8MN_ANATOP_CLK_END);
+
+	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+	if (ret < 0) {
+		imx_unregister_hw_clocks(hws, IMX8MN_ANATOP_CLK_END);
+		return dev_err_probe(dev, ret,
+				     "failed to register anatop clock provider\n");
+	}
+
+	dev_info(dev, "NXP i.MX8MN anatop clock driver probed\n");
+	return 0;
+}
+
+static const struct of_device_id imx8mn_anatop_clk_of_match[] = {
+	{ .compatible = "fsl,imx8mn-anatop" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx8mn_anatop_clk_of_match);
+
+static struct platform_driver imx8mn_anatop_clk_driver = {
+	.probe = imx8mn_anatop_clocks_probe,
+	.driver = {
+		.name = "imx8mn-anatop",
+		/*
+		 * Disable bind attributes: clocks are not removed and
+		 * reloading the driver will crash or break devices.
+		 */
+		.suppress_bind_attrs = true,
+		.of_match_table = imx8mn_anatop_clk_of_match,
+	},
+};
+
+module_platform_driver(imx8mn_anatop_clk_driver);
+
+MODULE_AUTHOR("Dario Binacchi <dario.binacchi at amarulasolutions.com>");
+MODULE_DESCRIPTION("NXP i.MX8MN anatop clock driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index ab77e148e70c..588cebce6c9d 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -24,16 +24,6 @@ static u32 share_count_disp;
 static u32 share_count_pdm;
 static u32 share_count_nand;
 
-static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
-static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
-static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
-static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
-static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
-static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
-static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", };
-static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
-static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
-
 static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m",
 					       "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
 					       "audio_pll1_out", "sys_pll3_out", };
@@ -308,11 +298,6 @@ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sy
 						 "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out",
 						 "video_pll_out", "osc_32k", };
 
-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
-					   "dummy", "dummy", "gpu_pll_out", "dummy",
-					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
-					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
-
 static struct clk_hw_onecell_data *clk_hw_data;
 static struct clk_hw **hws;
 
@@ -323,6 +308,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	void __iomem *base;
 	int ret;
 
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (WARN_ON(IS_ERR(base)))
+		return PTR_ERR(base);
+
 	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
 					  IMX8MN_CLK_END), GFP_KERNEL);
 	if (WARN_ON(!clk_hw_data))
@@ -331,99 +320,84 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	clk_hw_data->num = IMX8MN_CLK_END;
 	hws = clk_hw_data->hws;
 
-	hws[IMX8MN_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
-	hws[IMX8MN_CLK_24M] = imx_get_clk_hw_by_name(np, "osc_24m");
-	hws[IMX8MN_CLK_32K] = imx_get_clk_hw_by_name(np, "osc_32k");
+	hws[IMX8MN_CLK_DUMMY] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_DUMMY);
+	hws[IMX8MN_CLK_24M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_24M);
+	hws[IMX8MN_CLK_32K] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_32K);
 	hws[IMX8MN_CLK_EXT1] = imx_get_clk_hw_by_name(np, "clk_ext1");
 	hws[IMX8MN_CLK_EXT2] = imx_get_clk_hw_by_name(np, "clk_ext2");
 	hws[IMX8MN_CLK_EXT3] = imx_get_clk_hw_by_name(np, "clk_ext3");
 	hws[IMX8MN_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
-	base = devm_of_iomap(dev, np, 0, NULL);
-	of_node_put(np);
-	if (WARN_ON(IS_ERR(base))) {
-		ret = PTR_ERR(base);
-		goto unregister_hws;
-	}
-
-	hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-
-	hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
-	hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
-	hws[IMX8MN_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll);
-	hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
-	hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
-	hws[IMX8MN_M7_ALT_PLL] = imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel", base + 0x74, &imx_1416x_pll);
-	hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
-	hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
-	hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
-	hws[IMX8MN_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
+	hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL);
+	hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL);
+	hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_REF_SEL);
+	hws[IMX8MN_DRAM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_REF_SEL);
+	hws[IMX8MN_GPU_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_REF_SEL);
+	hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL);
+	hws[IMX8MN_ARM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_REF_SEL);
+	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_REF_SEL);
+
+	hws[IMX8MN_AUDIO_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1);
+	hws[IMX8MN_AUDIO_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2);
+	hws[IMX8MN_VIDEO_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL);
+	hws[IMX8MN_DRAM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL);
+	hws[IMX8MN_GPU_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL);
+	hws[IMX8MN_M7_ALT_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL);
+	hws[IMX8MN_ARM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL);
+	hws[IMX8MN_SYS_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1);
+	hws[IMX8MN_SYS_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2);
+	hws[IMX8MN_SYS_PLL3] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3);
 
 	/* PLL bypass out */
-	hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1, m7_alt_pll_bypass_sels, ARRAY_SIZE(m7_alt_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_BYPASS);
+	hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_BYPASS);
+	hws[IMX8MN_VIDEO_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_BYPASS);
+	hws[IMX8MN_DRAM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_BYPASS);
+	hws[IMX8MN_GPU_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_BYPASS);
+	hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_BYPASS);
+	hws[IMX8MN_ARM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_BYPASS);
+	hws[IMX8MN_SYS_PLL3_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_BYPASS);
 
 	/* PLL out gate */
-	hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
-	hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
-	hws[IMX8MN_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13);
-	hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
-	hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
-	hws[IMX8MN_M7_ALT_PLL_OUT] = imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass", base + 0x74, 11);
-	hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
-	hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
+	hws[IMX8MN_AUDIO_PLL1_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_OUT);
+	hws[IMX8MN_AUDIO_PLL2_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_OUT);
+	hws[IMX8MN_VIDEO_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_OUT);
+	hws[IMX8MN_DRAM_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_OUT);
+	hws[IMX8MN_GPU_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_OUT);
+	hws[IMX8MN_M7_ALT_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_OUT);
+	hws[IMX8MN_ARM_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_OUT);
+	hws[IMX8MN_SYS_PLL3_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_OUT);
 
 	/* SYS PLL1 fixed output */
-	hws[IMX8MN_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
-	hws[IMX8MN_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
-	hws[IMX8MN_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
-	hws[IMX8MN_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
-	hws[IMX8MN_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
-	hws[IMX8MN_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
-	hws[IMX8MN_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
-	hws[IMX8MN_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
-	hws[IMX8MN_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
-	hws[IMX8MN_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+	hws[IMX8MN_SYS_PLL1_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_OUT);
+	hws[IMX8MN_SYS_PLL1_40M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_40M);
+	hws[IMX8MN_SYS_PLL1_80M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_80M);
+	hws[IMX8MN_SYS_PLL1_100M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_100M);
+	hws[IMX8MN_SYS_PLL1_133M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_133M);
+	hws[IMX8MN_SYS_PLL1_160M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_160M);
+	hws[IMX8MN_SYS_PLL1_200M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_200M);
+	hws[IMX8MN_SYS_PLL1_266M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_266M);
+	hws[IMX8MN_SYS_PLL1_400M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_400M);
+	hws[IMX8MN_SYS_PLL1_800M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_800M);
 
 	/* SYS PLL2 fixed output */
-	hws[IMX8MN_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
-	hws[IMX8MN_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
-	hws[IMX8MN_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
-	hws[IMX8MN_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
-	hws[IMX8MN_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
-	hws[IMX8MN_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
-	hws[IMX8MN_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
-	hws[IMX8MN_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
-	hws[IMX8MN_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
-	hws[IMX8MN_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
-
-	hws[IMX8MN_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
-	hws[IMX8MN_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128, 0, 4);
-	hws[IMX8MN_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8);
-	hws[IMX8MN_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
-	hws[IMX8MN_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128, 16, 4);
-	hws[IMX8MN_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24);
-
-	np = dev->of_node;
-	base = devm_platform_ioremap_resource(pdev, 0);
-	if (WARN_ON(IS_ERR(base))) {
-		ret = PTR_ERR(base);
-		goto unregister_hws;
-	}
+	hws[IMX8MN_SYS_PLL2_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_OUT);
+	hws[IMX8MN_SYS_PLL2_50M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_50M);
+	hws[IMX8MN_SYS_PLL2_100M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_100M);
+	hws[IMX8MN_SYS_PLL2_125M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_125M);
+	hws[IMX8MN_SYS_PLL2_166M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_166M);
+	hws[IMX8MN_SYS_PLL2_200M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_200M);
+	hws[IMX8MN_SYS_PLL2_250M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_250M);
+	hws[IMX8MN_SYS_PLL2_333M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_333M);
+	hws[IMX8MN_SYS_PLL2_500M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_500M);
+	hws[IMX8MN_SYS_PLL2_1000M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_1000M);
+
+	hws[IMX8MN_CLK_CLKOUT1_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1_SEL);
+	hws[IMX8MN_CLK_CLKOUT1_DIV] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1_DIV);
+	hws[IMX8MN_CLK_CLKOUT1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1);
+	hws[IMX8MN_CLK_CLKOUT2_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2_SEL);
+	hws[IMX8MN_CLK_CLKOUT2_DIV] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2_DIV);
+	hws[IMX8MN_CLK_CLKOUT2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2);
 
 	/* CORE */
 	hws[IMX8MN_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mn_a53_sels, base + 0x8000);
@@ -599,18 +573,15 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 
 	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
 	if (ret < 0) {
-		dev_err(dev, "failed to register hws for i.MX8MN\n");
-		goto unregister_hws;
+		imx_unregister_hw_clocks(hws, IMX8MN_CLK_END);
+		return dev_err_probe(dev, ret,
+				     "failed to register hws for i.MX8MN\n");
 	}
 
 	imx_register_uart_clocks();
 
+	dev_info(dev, "NXP i.MX8MN ccm clock driver probed\n");
 	return 0;
-
-unregister_hws:
-	imx_unregister_hw_clocks(hws, IMX8MN_CLK_END);
-
-	return ret;
 }
 
 static const struct of_device_id imx8mn_clk_of_match[] = {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:13 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:13 +0100
Subject: [PATCH v4 13/18] dt-bindings: clock: imx8m-clock: support spread spectrum clocking
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-14-dario.binacchi@amarulasolutions.com>

The patch adds the DT bindings for enabling and tuning spread spectrum
clocking generation.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Drop "fsl,ssc-clocks" property. The other added properties now refer
   to the clock list.
 - Updated minItems and maxItems of
   - clocks
   - clock-names
   - fsl,ssc-modfreq-hz
   - fsl,ssc-modrate-percent
   - fsl,ssc-modmethod
 - Updated the dts examples

 - Added in v3
 - The dt-bindings have been moved from fsl,imx8m-anatop.yaml to
   imx8m-clock.yaml. The anatop device (fsl,imx8m-anatop.yaml) is
   indeed more or less a syscon, so it represents a memory area
   accessible by ccm (imx8m-clock.yaml) to setup the PLLs.

 - Add "allOf:" and place it after "required:" block, like in the
   example schema.
 - Move the properties definition to the top-level.
 - Drop unit types as requested by the "make dt_binding_check" command.

---

(no changes since v1)

 .../bindings/clock/imx8m-clock.yaml           | 77 +++++++++++++++++--
 1 file changed, 71 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
index c643d4a81478..83036f6d2274 100644
--- a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
@@ -29,12 +29,12 @@ properties:
     maxItems: 2
 
   clocks:
-    minItems: 6
-    maxItems: 7
+    minItems: 7
+    maxItems: 10
 
   clock-names:
-    minItems: 6
-    maxItems: 7
+    minItems: 7
+    maxItems: 10
 
   '#clock-cells':
     const: 1
@@ -43,6 +43,34 @@ properties:
       ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8m-clock.h
       for the full list of i.MX8M clock IDs.
 
+  fsl,ssc-modfreq-hz:
+    description:
+      The values of modulation frequency (Hz unit) for each clock
+      supporting spread spectrum.
+    minItems: 7
+    maxItems: 10
+
+  fsl,ssc-modrate-percent:
+    description:
+      The percentage values of modulation rate for each clock
+      supporting spread spectrum.
+    minItems: 7
+    maxItems: 10
+
+  fsl,ssc-modmethod:
+    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+    description:
+      The modulation techniques for each clock supporting spread
+      spectrum.
+    minItems: 7
+    maxItems: 10
+    items:
+      enum:
+        - ""
+        - down-spread
+        - up-spread
+        - center-spread
+
 required:
   - compatible
   - reg
@@ -76,6 +104,10 @@ allOf:
             - const: clk_ext2
             - const: clk_ext3
             - const: clk_ext4
+        fsl,ssc-modfreq-hz: false
+        fsl,ssc-modrate-percent: false
+        fsl,ssc-modmethod: false
+
     else:
       properties:
         clocks:
@@ -86,6 +118,10 @@ allOf:
             - description: ext2 clock input
             - description: ext3 clock input
             - description: ext4 clock input
+            - description: audio1 PLL input
+            - description: audio2 PLL input
+            - description: dram PLL input
+            - description: video PLL input
 
         clock-names:
           items:
@@ -95,20 +131,49 @@ allOf:
             - const: clk_ext2
             - const: clk_ext3
             - const: clk_ext4
+            - const: audio_pll1
+            - const: audio_pll2
+            - const: dram_pll
+            - const: video_pll
 
 additionalProperties: false
 
 examples:
   # Clock Control Module node:
   - |
+    #include <dt-bindings/clock/imx8mm-clock.h>
+
     clock-controller at 30380000 {
         compatible = "fsl,imx8mm-ccm";
         reg = <0x30380000 0x10000>;
         #clock-cells = <1>;
         clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-                 <&clk_ext3>, <&clk_ext4>;
+                 <&clk_ext3>, <&clk_ext4>,
+                 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+                 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+                 <&anatop IMX8MM_ANATOP_DRAM_PLL>,
+                 <&anatop IMX8MM_ANATOP_VIDEO_PLL>;
         clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-                      "clk_ext3", "clk_ext4";
+                      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+                      "dram_pll", "video_pll";
+        fsl,ssc-modfreq-hz = <0>, <0>, <0>, <0>,
+                             <0>, <0>,
+                             <6818>,
+                             <0>,
+                             <0>,
+                             <2419>;
+        fsl,ssc-modrate-percent = <0>, <0>, <0>, <0>,
+                             <0>, <0>,
+                             <3>,
+                             <0>,
+                             <0>,
+                             <7>;
+        fsl,ssc-modmethod = "", "", "", "",
+                            "", "",
+                            "down-spread",
+                            "",
+                            "",
+                            "center-spread";
     };
 
   - |
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:14 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:14 +0100
Subject: [PATCH v4 14/18] arm64: dts: imx8mm: add PLLs to clock controller module (ccm)
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-15-dario.binacchi@amarulasolutions.com>

Add the PLLs generated by anatop to the clock list of the Clock
Controller Module (CCM) node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 597041a05073..0b35aecb6755 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -642,9 +642,14 @@ clk: clock-controller at 30380000 {
 					     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
 				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-					 <&clk_ext3>, <&clk_ext4>;
+					 <&clk_ext3>, <&clk_ext4>,
+					 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MM_ANATOP_DRAM_PLL>,
+					 <&anatop IMX8MM_ANATOP_VIDEO_PLL>;
 				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-					      "clk_ext3", "clk_ext4";
+					      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+					      "dram_pll", "video_pll";
 				assigned-clocks = <&clk IMX8MM_CLK_A53_SRC>,
 						<&clk IMX8MM_CLK_A53_CORE>,
 						<&clk IMX8MM_CLK_NOC>,
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:15 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:15 +0100
Subject: [PATCH v4 15/18] arm64: dts: imx8mn: add PLLs to clock controller module (ccm)
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-16-dario.binacchi@amarulasolutions.com>

Add the PLLs generated by anatop to the clock list of the Clock
Controller Module (CCM) node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index 49be492b5687..aaa179784717 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -643,9 +643,14 @@ clk: clock-controller at 30380000 {
 					     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
 				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-					 <&clk_ext3>, <&clk_ext4>;
+					 <&clk_ext3>, <&clk_ext4>,
+					 <&anatop IMX8MN_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MN_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MN_ANATOP_DRAM_PLL>,
+					 <&anatop IMX8MN_ANATOP_VIDEO_PLL>;
 				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-					      "clk_ext3", "clk_ext4";
+					      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+					      "dram_pll", "video_pll";
 				assigned-clocks = <&clk IMX8MN_CLK_A53_SRC>,
 						<&clk IMX8MN_CLK_A53_CORE>,
 						<&clk IMX8MN_CLK_NOC>,
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:16 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:16 +0100
Subject: [PATCH v4 16/18] arm64: dts: imx8mp: add PLLs to clock controller module (ccm)
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-17-dario.binacchi@amarulasolutions.com>

Add the PLLs generated by anatop to the clock list of the Clock
Controller Module (CCM) node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 0b928e173f29..861bd4f4dced 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -751,9 +751,14 @@ clk: clock-controller at 30380000 {
 					     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
 				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-					 <&clk_ext3>, <&clk_ext4>;
+					 <&clk_ext3>, <&clk_ext4>,
+					 <&anatop IMX8MP_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MP_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MP_ANATOP_DRAM_PLL>,
+					 <&anatop IMX8MP_ANATOP_VIDEO_PLL>;
 				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-					      "clk_ext3", "clk_ext4";
+					      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+					      "dram_pll", "video_pll";
 				assigned-clocks = <&clk IMX8MP_CLK_A53_SRC>,
 						  <&clk IMX8MP_CLK_A53_CORE>,
 						  <&clk IMX8MP_CLK_NOC>,
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:00 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:00 +0100
Subject: [PATCH v4 00/18] Support spread spectrum clocking for i.MX8N PLLs
Message-ID: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>

The series adds support for spread spectrum clocking for i.MX8MN
PLLs (audio, video and DRAM). It has been tested for the video PLL on
a board using i.MX8MN.
The patches added in version 4, such as the dt-bindings and the driver
for anatop, were inspired by the extensive email exchange from version 3:
https://lore.kernel.org/imx/20241106090549.3684963-1-dario.binacchi at amarulasolutions.com/

The series added spectrum spread support for the imx8mn platform only,
but in case it was merged, confirming that the directives and suggestions
made by the maintainers were correctly understood and implemented, I will
extend this support to the imx8mm and imx8mp platforms as well.

(no changes since v1)

Dario Binacchi (18):
  clk: imx8mm: rename video_pll1 to video_pll
  clk: imx8mp: rename video_pll1 to video_pll
  dt-bindings: clock: imx8m-anatop: define clocks/clock-names
  arm64: dts: imx8mm: add anatop clocks
  arm64: dts: imx8mn: add anatop clocks
  arm64: dts: imx8mp: add anatop clocks
  arm64: dts: imx8mq: add anatop clocks
  dt-bindings: clock: imx8mm: add binding definitions for anatop
  dt-bindings: clock: imx8mn: add binding definitions for anatop
  dt-bindings: clock: imx8mp: add binding definitions for anatop
  clk: imx: add hw API imx8m_anatop_get_clk_hw
  clk: imx: add support for i.MX8MN anatop clock driver
  dt-bindings: clock: imx8m-clock: support spread spectrum clocking
  arm64: dts: imx8mm: add PLLs to clock controller module (ccm)
  arm64: dts: imx8mn: add PLLs to clock controller module (ccm)
  arm64: dts: imx8mp: add PLLs to clock controller module (ccm)
  clk: imx: pll14xx: support spread spectrum clock generation
  clk: imx8mn: support spread spectrum clock generation

 .../bindings/clock/fsl,imx8m-anatop.yaml      |  53 +++-
 .../bindings/clock/imx8m-clock.yaml           |  77 ++++-
 arch/arm64/boot/dts/freescale/imx8mm.dtsi     |  11 +-
 arch/arm64/boot/dts/freescale/imx8mn.dtsi     |  11 +-
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     |  11 +-
 arch/arm64/boot/dts/freescale/imx8mq.dtsi     |   2 +
 drivers/clk/imx/Makefile                      |   2 +-
 drivers/clk/imx/clk-imx8mm.c                  | 102 +++----
 drivers/clk/imx/clk-imx8mn-anatop.c           | 281 ++++++++++++++++++
 drivers/clk/imx/clk-imx8mn.c                  | 188 ++++++------
 drivers/clk/imx/clk-imx8mp.c                  | 118 ++++----
 drivers/clk/imx/clk-pll14xx.c                 | 127 ++++++++
 drivers/clk/imx/clk.c                         |  26 ++
 drivers/clk/imx/clk.h                         |  22 ++
 include/dt-bindings/clock/imx8mm-clock.h      |  78 ++++-
 include/dt-bindings/clock/imx8mn-clock.h      |  67 +++++
 include/dt-bindings/clock/imx8mp-clock.h      |  79 ++++-
 17 files changed, 1022 insertions(+), 233 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx8mn-anatop.c

-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:01 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:01 +0100
Subject: [PATCH v4 01/18] clk: imx8mm: rename video_pll1 to video_pll
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-2-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's rename "video_pll1" to
"video_pll" to be consistent with the RM and avoid misunderstandings.

The IMX8MM_VIDEO_PLL1* constants have not been removed to ensure
backward compatibility of the patch.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 drivers/clk/imx/clk-imx8mm.c             | 102 +++++++++++------------
 include/dt-bindings/clock/imx8mm-clock.h |  12 ++-
 2 files changed, 59 insertions(+), 55 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index 342049b847b9..8a1fc7e17ba2 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -28,7 +28,7 @@ static u32 share_count_nand;
 static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
 static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
 static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
-static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char *video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
 static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
 static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
 static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
@@ -42,22 +42,22 @@ static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m
 static const char * const imx8mm_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
 
 static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m",
-				       "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+				       "sys_pll1_800m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", };
 
 static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
 					"sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", };
 
 static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
-					  "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					  "sys_pll2_1000m", "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
-					  "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					  "sys_pll2_1000m", "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m",
-					     "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",};
+					     "sys_pll2_1000m", "audio_pll1_out", "video_pll_out", "sys_pll1_100m",};
 
 static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
-					     "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+					     "sys_pll2_200m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", };
 
 static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
 					       "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
@@ -72,28 +72,28 @@ static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pl
 					     "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
 
 static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m",
-					      "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
+					      "audio_pll1_out", "video_pll_out", "clk_ext2", "clk_ext3", };
 
 static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
 					    "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
 
 static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
-					    "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					    "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
-					    "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					    "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m",
-					"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					"audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m",
-					    "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", };
+					    "sys_pll1_800m", "audio_pll1_out", "video_pll_out", };
 
 static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
-					"sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+					"sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll_out", };
 
 static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m",
-					      "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+					      "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll_out", };
 
 static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m",
 					     "sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", };
@@ -108,10 +108,10 @@ static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_8
 					   "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
 
 static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "dummy", "sys_pll1_800m", "sys_pll2_1000m",
-					      "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+					      "sys_pll1_160m", "video_pll_out", "sys_pll3_out", "audio_pll2_out", };
 
 static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "dummy", "sys_pll1_800m", "sys_pll2_1000m",
-						"sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+						"sys_pll1_160m", "video_pll_out", "sys_pll3_out", "audio_pll2_out", };
 
 static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
 					       "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
@@ -122,47 +122,47 @@ static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_p
 static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
 					      "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
 
-static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out", "audio_pll1_out",
 					     "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
-static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out", "audio_pll1_out",
 						"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
-static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
 
-static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
 
-static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
 
-static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
 
-static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
 
-static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
 
-static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					   "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
 
-static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					   "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
 
 static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
-					     "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
+					     "sys_pll1_160m", "audio_pll1_out", "video_pll_out", "clk_ext4", };
 
 static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
-					       "clk_ext3", "clk_ext4", "video_pll1_out", };
+					       "clk_ext3", "clk_ext4", "video_pll_out", };
 
 static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
-					     "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
+					     "sys_pll2_500m", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
-					 "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
+					 "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll_out", };
 
 static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m",
 					 "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
@@ -174,16 +174,16 @@ static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1
 					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
 
 static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
 					  "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
@@ -213,19 +213,19 @@ static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1
 					   "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
 
 static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
-					 "video_pll1_out", "sys_pll1_80m", "audio_pll1_out", "clk_ext1" };
+					 "video_pll_out", "sys_pll1_80m", "audio_pll1_out", "clk_ext1" };
 
 static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
 					 "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
@@ -234,31 +234,31 @@ static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_ou
 					  "sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", };
 
 static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
-					     "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					     "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m",
-					    "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+					    "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m",
-					    "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					    "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
 					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
 
 static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
-					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
-					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
 					     "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
 
 static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
-					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
-					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
 					     "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
@@ -286,9 +286,9 @@ static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }
 static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "dummy", "sys_pll1_200m",
 					  "audio_pll2_out", "sys_pll2_500m", "vpu_pll", "sys_pll1_80m", };
 static const char *imx8mm_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", "sys_pll2_166m",
-					  "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "osc_32k", };
+					  "sys_pll3_out", "audio_pll1_out", "video_pll_out", "osc_32k", };
 
-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					   "dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
 					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
 					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
@@ -327,7 +327,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MM_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
@@ -336,7 +336,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MM_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
 	hws[IMX8MM_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
-	hws[IMX8MM_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
+	hws[IMX8MM_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll);
 	hws[IMX8MM_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
 	hws[IMX8MM_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
 	hws[IMX8MM_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
@@ -348,7 +348,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 	/* PLL bypass out */
 	hws[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MM_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
@@ -358,7 +358,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 	/* PLL out gate */
 	hws[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
 	hws[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
-	hws[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+	hws[IMX8MM_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13);
 	hws[IMX8MM_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
 	hws[IMX8MM_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
 	hws[IMX8MM_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
index 1f768b2eeb1a..102d8a6cdb55 100644
--- a/include/dt-bindings/clock/imx8mm-clock.h
+++ b/include/dt-bindings/clock/imx8mm-clock.h
@@ -16,7 +16,8 @@
 #define IMX8MM_CLK_EXT4				7
 #define IMX8MM_AUDIO_PLL1_REF_SEL		8
 #define IMX8MM_AUDIO_PLL2_REF_SEL		9
-#define IMX8MM_VIDEO_PLL1_REF_SEL		10
+#define IMX8MM_VIDEO_PLL_REF_SEL		10
+#define IMX8MM_VIDEO_PLL1_REF_SEL		IMX8MM_VIDEO_PLL_REF_SEL
 #define IMX8MM_DRAM_PLL_REF_SEL			11
 #define IMX8MM_GPU_PLL_REF_SEL			12
 #define IMX8MM_VPU_PLL_REF_SEL			13
@@ -26,7 +27,8 @@
 #define IMX8MM_SYS_PLL3_REF_SEL			17
 #define IMX8MM_AUDIO_PLL1			18
 #define IMX8MM_AUDIO_PLL2			19
-#define IMX8MM_VIDEO_PLL1			20
+#define IMX8MM_VIDEO_PLL			20
+#define IMX8MM_VIDEO_PLL1			IMX8MM_VIDEO_PLL
 #define IMX8MM_DRAM_PLL				21
 #define IMX8MM_GPU_PLL				22
 #define IMX8MM_VPU_PLL				23
@@ -36,7 +38,8 @@
 #define IMX8MM_SYS_PLL3				27
 #define IMX8MM_AUDIO_PLL1_BYPASS		28
 #define IMX8MM_AUDIO_PLL2_BYPASS		29
-#define IMX8MM_VIDEO_PLL1_BYPASS		30
+#define IMX8MM_VIDEO_PLL_BYPASS			30
+#define IMX8MM_VIDEO_PLL1_BYPASS		IMX8MM_VIDEO_PLL_BYPASS
 #define IMX8MM_DRAM_PLL_BYPASS			31
 #define IMX8MM_GPU_PLL_BYPASS			32
 #define IMX8MM_VPU_PLL_BYPASS			33
@@ -46,7 +49,8 @@
 #define IMX8MM_SYS_PLL3_BYPASS			37
 #define IMX8MM_AUDIO_PLL1_OUT			38
 #define IMX8MM_AUDIO_PLL2_OUT			39
-#define IMX8MM_VIDEO_PLL1_OUT			40
+#define IMX8MM_VIDEO_PLL_OUT			40
+#define IMX8MM_VIDEO_PLL1_OUT			IMX8MM_VIDEO_PLL_OUT
 #define IMX8MM_DRAM_PLL_OUT			41
 #define IMX8MM_GPU_PLL_OUT			42
 #define IMX8MM_VPU_PLL_OUT			43
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:02 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:02 +0100
Subject: [PATCH v4 02/18] clk: imx8mp: rename video_pll1 to video_pll
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-3-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's rename "video_pll1" to
"video_pll" to be consistent with the RM and avoid misunderstandings.

The IMX8MP_VIDEO_PLL1* constants have not been removed to ensure
backward compatibility of the patch.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 drivers/clk/imx/clk-imx8mp.c             | 118 +++++++++++------------
 include/dt-bindings/clock/imx8mp-clock.h |   9 +-
 2 files changed, 65 insertions(+), 62 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 516dbd170c8a..e96460534e7d 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -23,7 +23,7 @@ static u32 share_count_audio;
 static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
 static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
 static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
-static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
 static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
 static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
 static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
@@ -40,27 +40,27 @@ static const char * const imx8mp_a53_core_sels[] = {"arm_a53_div", "arm_pll_out"
 
 static const char * const imx8mp_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m",
 					      "vpu_pll_out", "sys_pll1_800m", "audio_pll1_out",
-					      "video_pll1_out", "sys_pll3_out", };
+					      "video_pll_out", "sys_pll3_out", };
 
 static const char * const imx8mp_ml_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 					      "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-					      "video_pll1_out", "audio_pll2_out", };
+					      "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu3d_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						      "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						      "video_pll1_out", "audio_pll2_out", };
+						      "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu3d_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 							"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-							"video_pll1_out", "audio_pll2_out", };
+							"video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						 "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						 "video_pll1_out", "audio_pll2_out", };
+						 "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_audio_axi_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						     "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						     "video_pll1_out", "audio_pll2_out", };
+						     "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_hsio_axi_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
 						    "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
@@ -72,11 +72,11 @@ static const char * const imx8mp_media_isp_sels[] = {"osc_24m", "sys_pll2_1000m"
 
 static const char * const imx8mp_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m",
 						    "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
-						    "video_pll1_out", "sys_pll1_100m",};
+						    "video_pll_out", "sys_pll1_100m",};
 
 static const char * const imx8mp_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
 						    "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
-						    "video_pll1_out", "sys_pll3_out", };
+						    "video_pll_out", "sys_pll3_out", };
 
 static const char * const imx8mp_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
 						      "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
@@ -96,35 +96,35 @@ static const char * const imx8mp_media_apb_sels[] = {"osc_24m", "sys_pll2_125m",
 
 static const char * const imx8mp_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						   "video_pll1_out", "audio_pll2_out", };
+						   "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						   "video_pll1_out", "audio_pll2_out", };
+						   "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
 					       "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
-					       "video_pll1_out", "audio_pll2_out", };
+					       "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_noc_io_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
 						  "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
-						  "video_pll1_out", "audio_pll2_out", };
+						  "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_ml_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						  "video_pll1_out", "audio_pll2_out", };
+						  "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_ml_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						  "video_pll1_out", "audio_pll2_out", };
+						  "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m",
 					       "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
-					       "audio_pll1_out", "video_pll1_out", };
+					       "audio_pll1_out", "video_pll_out", };
 
 static const char * const imx8mp_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
 						     "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out",
-						     "audio_pll1_out", "video_pll1_out", };
+						     "audio_pll1_out", "video_pll_out", };
 
 static const char * const imx8mp_mipi_dsi_esc_rx_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
 							   "sys_pll1_800m", "sys_pll2_1000m",
@@ -159,56 +159,56 @@ static const char * const imx8mp_pcie_aux_sels[] = {"osc_24m", "sys_pll2_200m",
 						    "sys_pll1_160m", "sys_pll1_200m", };
 
 static const char * const imx8mp_i2c5_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c6_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext1", "clk_ext2", };
 
 static const char * const imx8mp_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext2", "clk_ext3", };
 
 static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
 
 static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext2", "clk_ext3", };
 
 static const char * const imx8mp_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
 
 static const char * const imx8mp_enet_qos_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
 						    "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
-						    "video_pll1_out", "clk_ext4", };
+						    "video_pll_out", "clk_ext4", };
 
 static const char * const imx8mp_enet_qos_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
 							  "clk_ext1", "clk_ext2", "clk_ext3",
-							  "clk_ext4", "video_pll1_out", };
+							  "clk_ext4", "video_pll_out", };
 
 static const char * const imx8mp_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
 						    "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
-						    "video_pll1_out", "clk_ext4", };
+						    "video_pll_out", "clk_ext4", };
 
 static const char * const imx8mp_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
 						      "clk_ext1", "clk_ext2", "clk_ext3",
-						      "clk_ext4", "video_pll1_out", };
+						      "clk_ext4", "video_pll_out", };
 
 static const char * const imx8mp_enet_phy_ref_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m",
 							"sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out",
-							"video_pll1_out", "audio_pll2_out", };
+							"video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
 						"sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
-						"sys_pll2_250m", "video_pll1_out", };
+						"sys_pll2_250m", "video_pll_out", };
 
 static const char * const imx8mp_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m",
 						"sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
@@ -223,19 +223,19 @@ static const char * const imx8mp_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "s
 						  "audio_pll2_out", "sys_pll1_100m", };
 
 static const char * const imx8mp_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
@@ -276,42 +276,42 @@ static const char * const imx8mp_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "s
 
 static const char * const imx8mp_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext1" };
 
 static const char * const imx8mp_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext2" };
 
 static const char * const imx8mp_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext3" };
 
 static const char * const imx8mp_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext1" };
 
 static const char * const imx8mp_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext2" };
 
 static const char * const imx8mp_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext3" };
 
 static const char * const imx8mp_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
@@ -328,19 +328,19 @@ static const char * const imx8mp_ipp_do_clko1_sels[] = {"osc_24m", "sys_pll1_800
 
 static const char * const imx8mp_ipp_do_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m",
 							"sys_pll1_166m", "sys_pll3_out", "audio_pll1_out",
-							"video_pll1_out", "osc_32k" };
+							"video_pll_out", "osc_32k" };
 
 static const char * const imx8mp_hdmi_fdcc_tst_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
 							 "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
-							 "audio_pll2_out", "video_pll1_out", };
+							 "audio_pll2_out", "video_pll_out", };
 
 static const char * const imx8mp_hdmi_24m_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						    "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						    "sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						    "audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_hdmi_ref_266m_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out",
 							 "sys_pll2_333m", "sys_pll1_266m", "sys_pll2_200m",
-							 "audio_pll1_out", "video_pll1_out", };
+							 "audio_pll1_out", "video_pll_out", };
 
 static const char * const imx8mp_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
 						  "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
@@ -349,26 +349,26 @@ static const char * const imx8mp_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "s
 static const char * const imx8mp_media_cam1_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
 							  "sys_pll1_800m", "sys_pll2_1000m",
 							  "sys_pll3_out", "audio_pll2_out",
-							  "video_pll1_out", };
+							  "video_pll_out", };
 
 static const char * const imx8mp_media_mipi_phy1_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
 							       "sys_pll1_800m", "sys_pll2_1000m",
 							       "clk_ext2", "audio_pll2_out",
-							       "video_pll1_out", };
+							       "video_pll_out", };
 
-static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
+static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out",
 							   "audio_pll1_out", "sys_pll1_800m",
 							   "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
 static const char * const imx8mp_media_cam2_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
 							  "sys_pll1_800m", "sys_pll2_1000m",
 							  "sys_pll3_out", "audio_pll2_out",
-							  "video_pll1_out", };
+							  "video_pll_out", };
 
 static const char * const imx8mp_media_ldb_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
 						     "sys_pll1_800m", "sys_pll2_1000m",
 						     "clk_ext2", "audio_pll2_out",
-						     "video_pll1_out", };
+						     "video_pll_out", };
 
 static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
 							"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
@@ -392,12 +392,12 @@ static const char * const imx8mp_vpu_vc8000e_sels[] = {"osc_24m", "vpu_pll_out",
 						       "sys_pll3_out", "audio_pll1_out", };
 
 static const char * const imx8mp_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
 
 static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
 
-static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
 						  "dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
 						  "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
 						  "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
@@ -440,7 +440,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", anatop_base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", anatop_base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MP_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MP_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", anatop_base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", anatop_base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", anatop_base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
@@ -451,7 +451,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", anatop_base, &imx_1443x_pll);
 	hws[IMX8MP_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", anatop_base + 0x14, &imx_1443x_pll);
-	hws[IMX8MP_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
+	hws[IMX8MP_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
 	hws[IMX8MP_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", anatop_base + 0x50, &imx_1443x_dram_pll);
 	hws[IMX8MP_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", anatop_base + 0x64, &imx_1416x_pll);
 	hws[IMX8MP_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", anatop_base + 0x74, &imx_1416x_pll);
@@ -462,7 +462,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MP_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", anatop_base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
@@ -473,7 +473,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
 	hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
-	hws[IMX8MP_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", anatop_base + 0x28, 13);
+	hws[IMX8MP_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", anatop_base + 0x28, 13);
 	hws[IMX8MP_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", anatop_base + 0x50, 13);
 	hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
 	hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
index 7da4243984b2..0601df6c8d38 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -16,7 +16,8 @@
 #define IMX8MP_CLK_EXT4				7
 #define IMX8MP_AUDIO_PLL1_REF_SEL		8
 #define IMX8MP_AUDIO_PLL2_REF_SEL		9
-#define IMX8MP_VIDEO_PLL1_REF_SEL		10
+#define IMX8MP_VIDEO_PLL_REF_SEL		10
+#define IMX8MP_VIDEO_PLL1_REF_SEL		IMX8MP_VIDEO_PLL_REF_SEL
 #define IMX8MP_DRAM_PLL_REF_SEL			11
 #define IMX8MP_GPU_PLL_REF_SEL			12
 #define IMX8MP_VPU_PLL_REF_SEL			13
@@ -26,7 +27,8 @@
 #define IMX8MP_SYS_PLL3_REF_SEL			17
 #define IMX8MP_AUDIO_PLL1			18
 #define IMX8MP_AUDIO_PLL2			19
-#define IMX8MP_VIDEO_PLL1			20
+#define IMX8MP_VIDEO_PLL			20
+#define IMX8MP_VIDEO_PLL1			IMX8MP_VIDEO_PLL
 #define IMX8MP_DRAM_PLL				21
 #define IMX8MP_GPU_PLL				22
 #define IMX8MP_VPU_PLL				23
@@ -46,7 +48,8 @@
 #define IMX8MP_SYS_PLL3_BYPASS			37
 #define IMX8MP_AUDIO_PLL1_OUT			38
 #define IMX8MP_AUDIO_PLL2_OUT			39
-#define IMX8MP_VIDEO_PLL1_OUT			40
+#define IMX8MP_VIDEO_PLL_OUT			40
+#define IMX8MP_VIDEO_PLL1_OUT			IMX8MP_VIDEO_PLL_OUT
 #define IMX8MP_DRAM_PLL_OUT			41
 #define IMX8MP_GPU_PLL_OUT			42
 #define IMX8MP_VPU_PLL_OUT			43
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:03 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:03 +0100
Subject: [PATCH v4 03/18] dt-bindings: clock: imx8m-anatop: define clocks/clock-names
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-4-dario.binacchi@amarulasolutions.com>

Define clocks and clock-names properties of the anatop device node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 .../bindings/clock/fsl,imx8m-anatop.yaml      | 53 ++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml b/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
index bbd22e95b319..f439b0a94ce2 100644
--- a/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
+++ b/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
@@ -30,22 +30,73 @@ properties:
   interrupts:
     maxItems: 1
 
+  clocks:
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    minItems: 2
+    maxItems: 3
+
   '#clock-cells':
     const: 1
 
 required:
   - compatible
   - reg
+  - clocks
+  - clock-names
   - '#clock-cells'
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx8mq-anatop
+    then:
+      properties:
+        clocks:
+          items:
+            - description: 32k osc
+            - description: 25m osc
+            - description: 27m osc
+        clock-names:
+          items:
+            - const: ckil
+            - const: osc_25m
+            - const: osc_27m
+    else:
+      properties:
+        clocks:
+          items:
+            - description: 32k osc
+            - description: 24m osc
+
+        clock-names:
+          items:
+            - const: osc_32k
+            - const: osc_24m
+
 additionalProperties: false
 
 examples:
   - |
-    anatop: clock-controller at 30360000 {
+    clock-controller at 30360000 {
         compatible = "fsl,imx8mn-anatop", "fsl,imx8mm-anatop";
         reg = <0x30360000 0x10000>;
         #clock-cells = <1>;
+        clocks = <&osc_32k>, <&osc_24m>;
+        clock-names = "osc_32k", "osc_24m";
+    };
+
+  - |
+    clock-controller at 30360000 {
+        compatible = "fsl,imx8mq-anatop";
+        reg = <0x30360000 0x10000>;
+        #clock-cells = <1>;
+        clocks = <&ckil>, <&osc_25m>, <&osc_27m>;
+        clock-names = "ckil", "osc_25m", "osc_27m";
     };
 
 ...
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:04 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:04 +0100
Subject: [PATCH v4 04/18] arm64: dts: imx8mm: add anatop clocks
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-5-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Add the bindings definitions for the anatop node. The patch is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 4de3bf22902b..597041a05073 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -600,6 +600,8 @@ anatop: clock-controller at 30360000 {
 				compatible = "fsl,imx8mm-anatop";
 				reg = <0x30360000 0x10000>;
 				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>;
+				clock-names = "osc_32k", "osc_24m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:05 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:05 +0100
Subject: [PATCH v4 05/18] arm64: dts: imx8mn: add anatop clocks
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-6-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index a5f9cfb46e5d..49be492b5687 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -606,6 +606,8 @@ anatop: clock-controller at 30360000 {
 				compatible = "fsl,imx8mn-anatop", "fsl,imx8mm-anatop";
 				reg = <0x30360000 0x10000>;
 				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>;
+				clock-names = "osc_32k", "osc_24m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:06 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:06 +0100
Subject: [PATCH v4 06/18] arm64: dts: imx8mp: add anatop clocks
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-7-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index e0d3b8cba221..0b928e173f29 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -709,6 +709,8 @@ anatop: clock-controller at 30360000 {
 				compatible = "fsl,imx8mp-anatop", "fsl,imx8mm-anatop";
 				reg = <0x30360000 0x10000>;
 				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>;
+				clock-names = "osc_32k", "osc_24m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:07 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:07 +0100
Subject: [PATCH v4 07/18] arm64: dts: imx8mq: add anatop clocks
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-8-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index d51de8d899b2..1d1424a136f0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -817,6 +817,8 @@ anatop: clock-controller at 30360000 {
 				reg = <0x30360000 0x10000>;
 				interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
+				clocks = <&ckil>, <&osc_25m>, <&osc_27m>;
+				clock-names = "ckil", "osc_25m", "osc_27m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:08 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:08 +0100
Subject: [PATCH v4 08/18] dt-bindings: clock: imx8mm: add binding definitions for anatop
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-9-dario.binacchi@amarulasolutions.com>

Add the bindings definitions for the anatop node. The patch is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

 - Added in v4

---

(no changes since v1)

 include/dt-bindings/clock/imx8mm-clock.h | 66 ++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
index 102d8a6cdb55..1962b0a1e732 100644
--- a/include/dt-bindings/clock/imx8mm-clock.h
+++ b/include/dt-bindings/clock/imx8mm-clock.h
@@ -287,4 +287,70 @@
 
 #define IMX8MM_CLK_END				258
 
+#define IMX8MM_ANATOP_CLK_DUMMY			0
+#define IMX8MM_ANATOP_CLK_32K			1
+#define IMX8MM_ANATOP_CLK_24M			2
+#define IMX8MM_ANATOP_AUDIO_PLL1_REF_SEL	3
+#define IMX8MM_ANATOP_AUDIO_PLL2_REF_SEL	4
+#define IMX8MM_ANATOP_VIDEO_PLL_REF_SEL		5
+#define IMX8MM_ANATOP_DRAM_PLL_REF_SEL		6
+#define IMX8MM_ANATOP_GPU_PLL_REF_SEL		7
+#define IMX8MM_ANATOP_VPU_PLL_REF_SEL		8
+#define IMX8MM_ANATOP_ARM_PLL_REF_SEL		9
+#define IMX8MM_ANATOP_SYS_PLL3_REF_SEL		10
+#define IMX8MM_ANATOP_AUDIO_PLL1		11
+#define IMX8MM_ANATOP_AUDIO_PLL2		12
+#define IMX8MM_ANATOP_VIDEO_PLL			13
+#define IMX8MM_ANATOP_DRAM_PLL			14
+#define IMX8MM_ANATOP_GPU_PLL			15
+#define IMX8MM_ANATOP_VPU_PLL			16
+#define IMX8MM_ANATOP_ARM_PLL			17
+#define IMX8MM_ANATOP_SYS_PLL1			18
+#define IMX8MM_ANATOP_SYS_PLL2			19
+#define IMX8MM_ANATOP_SYS_PLL3			20
+#define IMX8MM_ANATOP_AUDIO_PLL1_BYPASS		21
+#define IMX8MM_ANATOP_AUDIO_PLL2_BYPASS		22
+#define IMX8MM_ANATOP_VIDEO_PLL_BYPASS		23
+#define IMX8MM_ANATOP_DRAM_PLL_BYPASS		24
+#define IMX8MM_ANATOP_GPU_PLL_BYPASS		25
+#define IMX8MM_ANATOP_VPU_PLL_BYPASS		26
+#define IMX8MM_ANATOP_ARM_PLL_BYPASS		27
+#define IMX8MM_ANATOP_SYS_PLL3_BYPASS		28
+#define IMX8MM_ANATOP_AUDIO_PLL1_OUT		29
+#define IMX8MM_ANATOP_AUDIO_PLL2_OUT		30
+#define IMX8MM_ANATOP_VIDEO_PLL_OUT		31
+#define IMX8MM_ANATOP_DRAM_PLL_OUT		32
+#define IMX8MM_ANATOP_GPU_PLL_OUT		33
+#define IMX8MM_ANATOP_VPU_PLL_OUT		34
+#define IMX8MM_ANATOP_ARM_PLL_OUT		35
+#define IMX8MM_ANATOP_SYS_PLL3_OUT		36
+#define IMX8MM_ANATOP_SYS_PLL1_OUT		37
+#define IMX8MM_ANATOP_SYS_PLL1_40M		38
+#define IMX8MM_ANATOP_SYS_PLL1_80M		39
+#define IMX8MM_ANATOP_SYS_PLL1_100M		40
+#define IMX8MM_ANATOP_SYS_PLL1_133M		41
+#define IMX8MM_ANATOP_SYS_PLL1_160M		42
+#define IMX8MM_ANATOP_SYS_PLL1_200M		43
+#define IMX8MM_ANATOP_SYS_PLL1_266M		44
+#define IMX8MM_ANATOP_SYS_PLL1_400M		45
+#define IMX8MM_ANATOP_SYS_PLL1_800M		46
+#define IMX8MM_ANATOP_SYS_PLL2_OUT		47
+#define IMX8MM_ANATOP_SYS_PLL2_50M		48
+#define IMX8MM_ANATOP_SYS_PLL2_100M		49
+#define IMX8MM_ANATOP_SYS_PLL2_125M		50
+#define IMX8MM_ANATOP_SYS_PLL2_166M		51
+#define IMX8MM_ANATOP_SYS_PLL2_200M		52
+#define IMX8MM_ANATOP_SYS_PLL2_250M		53
+#define IMX8MM_ANATOP_SYS_PLL2_333M		54
+#define IMX8MM_ANATOP_SYS_PLL2_500M		55
+#define IMX8MM_ANATOP_SYS_PLL2_1000M		56
+#define IMX8MM_ANATOP_CLK_CLKOUT1_SEL		57
+#define IMX8MM_ANATOP_CLK_CLKOUT1_DIV		58
+#define IMX8MM_ANATOP_CLK_CLKOUT1		59
+#define IMX8MM_ANATOP_CLK_CLKOUT2_SEL		60
+#define IMX8MM_ANATOP_CLK_CLKOUT2_DIV		61
+#define IMX8MM_ANATOP_CLK_CLKOUT2		62
+
+#define IMX8MM_ANATOP_CLK_END			63
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:17 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:17 +0100
Subject: [PATCH v4 17/18] clk: imx: pll14xx: support spread spectrum clock generation
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-18-dario.binacchi@amarulasolutions.com>

Add support for spread spectrum clock (SSC) generation to the pll14xxx
driver.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
---

(no changes since v1)

 drivers/clk/imx/clk-pll14xx.c | 127 ++++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h         |  16 +++++
 2 files changed, 143 insertions(+)

diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index d63564dbb12c..b07c59fd659a 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -20,6 +20,8 @@
 #define GNRL_CTL	0x0
 #define DIV_CTL0	0x4
 #define DIV_CTL1	0x8
+#define SSCG_CTRL	0xc
+
 #define LOCK_STATUS	BIT(31)
 #define LOCK_SEL_MASK	BIT(29)
 #define CLKE_MASK	BIT(11)
@@ -31,6 +33,10 @@
 #define KDIV_MASK	GENMASK(15, 0)
 #define KDIV_MIN	SHRT_MIN
 #define KDIV_MAX	SHRT_MAX
+#define SSCG_ENABLE	BIT(31)
+#define MFREQ_CTL_MASK	GENMASK(19, 12)
+#define MRAT_CTL_MASK	GENMASK(9, 4)
+#define SEL_PF_MASK	GENMASK(1, 0)
 
 #define LOCK_TIMEOUT_US		10000
 
@@ -40,6 +46,8 @@ struct clk_pll14xx {
 	enum imx_pll14xx_type		type;
 	const struct imx_pll14xx_rate_table *rate_table;
 	int rate_count;
+	bool                            ssc_enable;
+	struct imx_pll14xx_ssc		ssc_conf;
 };
 
 #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
@@ -347,6 +355,27 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
 	return 0;
 }
 
+static void clk_pll1443x_enable_ssc(struct clk_hw *hw, unsigned long parent_rate,
+				    unsigned int pdiv, unsigned int mdiv)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+	struct imx_pll14xx_ssc *conf = &pll->ssc_conf;
+	u32 sscg_ctrl, mfr, mrr;
+
+	sscg_ctrl = readl_relaxed(pll->base + SSCG_CTRL);
+	sscg_ctrl &=
+		~(SSCG_ENABLE | MFREQ_CTL_MASK | MRAT_CTL_MASK | SEL_PF_MASK);
+
+	mfr = parent_rate / (conf->mod_freq * pdiv * (1 << 5));
+	mrr = (conf->mod_rate * mdiv * (1 << 6)) / (100 * mfr);
+
+	sscg_ctrl |= SSCG_ENABLE | FIELD_PREP(MFREQ_CTL_MASK, mfr) |
+		FIELD_PREP(MRAT_CTL_MASK, mrr) |
+		FIELD_PREP(SEL_PF_MASK, conf->mod_type);
+
+	writel_relaxed(sscg_ctrl, pll->base + SSCG_CTRL);
+}
+
 static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 				 unsigned long prate)
 {
@@ -368,6 +397,9 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 		writel_relaxed(FIELD_PREP(KDIV_MASK, rate.kdiv),
 			       pll->base + DIV_CTL1);
 
+		if (pll->ssc_enable)
+			clk_pll1443x_enable_ssc(hw, prate, rate.pdiv, rate.mdiv);
+
 		return 0;
 	}
 
@@ -408,6 +440,9 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 	gnrl_ctl &= ~BYPASS_MASK;
 	writel_relaxed(gnrl_ctl, pll->base + GNRL_CTL);
 
+	if (pll->ssc_enable)
+		clk_pll1443x_enable_ssc(hw, prate, rate.pdiv, rate.mdiv);
+
 	return 0;
 }
 
@@ -542,3 +577,95 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
 	return hw;
 }
 EXPORT_SYMBOL_GPL(imx_dev_clk_hw_pll14xx);
+
+void imx_clk_pll14xx_enable_ssc(struct clk_hw *hw, struct imx_pll14xx_ssc *conf)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+
+	pll->ssc_enable = true;
+	memcpy(&pll->ssc_conf, conf, sizeof(pll->ssc_conf));
+}
+EXPORT_SYMBOL_GPL(imx_clk_pll14xx_enable_ssc);
+
+static int clk_pll14xx_ssc_mod_type(const char *name,
+				    enum imx_pll14xx_ssc_mod_type *mod_type)
+{
+	int i;
+	struct {
+		const char *name;
+		enum imx_pll14xx_ssc_mod_type id;
+	} mod_types[] = {
+		{ .name = "down-spread", .id = IMX_PLL14XX_SSC_DOWN_SPREAD },
+		{ .name = "up-spread", .id = IMX_PLL14XX_SSC_UP_SPREAD },
+		{ .name = "center-spread", .id = IMX_PLL14XX_SSC_CENTER_SPREAD }
+	};
+
+	pr_info("%s, name: %s\n", __func__, name);
+	for (i = 0; i < ARRAY_SIZE(mod_types); i++) {
+		if (!strcmp(name, mod_types[i].name)) {
+			*mod_type = mod_types[i].id;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+int imx_clk_pll14xx_ssc_parse_dt(struct device_node *np, const char *pll_name,
+				 struct imx_pll14xx_ssc *conf)
+{
+	int i, ret, num_clks;
+	const char *s;
+
+	if (!conf)
+		return -EINVAL;
+
+	ret = of_property_count_strings(np, "clock-names");
+	if (ret < 0)
+		return ret;
+
+	num_clks = ret;
+	for (i = 0; i < num_clks; i++) {
+		ret = of_property_read_string_index(np, "clock-names", i, &s);
+		if (strcmp(pll_name, s))
+			continue;
+
+		ret = of_property_read_u32_index(np, "fsl,ssc-modfreq-hz", i,
+						 &conf->mod_freq);
+		if (ret)
+			return ret;
+
+		ret = of_property_read_u32_index(np, "fsl,ssc-modrate-percent", i,
+						 &conf->mod_rate);
+		if (ret) {
+			pr_err("missing fsl,ssc-modrate-percent property for %pOFn\n",
+			       np);
+			return ret;
+		}
+
+		ret = of_property_read_string_index(np, "fsl,ssc-modmethod", i, &s);
+		if (ret) {
+			pr_err("failed to get fsl,ssc-modmethod property for %pOFn\n",
+			       np);
+			return ret;
+		}
+
+		if (strlen(s) == 0)
+			return -ENODEV;
+
+		ret = clk_pll14xx_ssc_mod_type(s, &conf->mod_type);
+		if (ret) {
+			pr_err("wrong fsl,ssc-modmethod property for %pOFn\n", np);
+			return ret;
+
+		}
+
+		pr_debug("%s: mod_freq: %d, mod_rate: %d: mod_method: %s [%d]\n",
+			 __func__, conf->mod_freq, conf->mod_rate, s, conf->mod_type);
+
+		return 0;
+	}
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(imx_clk_pll14xx_ssc_parse_dt);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 6b6af26f4f1e..dad6e90c7dc0 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -69,6 +69,18 @@ struct imx_pll14xx_clk {
 	int flags;
 };
 
+enum imx_pll14xx_ssc_mod_type {
+	IMX_PLL14XX_SSC_DOWN_SPREAD,
+	IMX_PLL14XX_SSC_UP_SPREAD,
+	IMX_PLL14XX_SSC_CENTER_SPREAD,
+};
+
+struct imx_pll14xx_ssc {
+	unsigned int mod_freq;
+	unsigned int mod_rate;
+	enum imx_pll14xx_ssc_mod_type mod_type;
+};
+
 extern struct imx_pll14xx_clk imx_1416x_pll;
 extern struct imx_pll14xx_clk imx_1443x_pll;
 extern struct imx_pll14xx_clk imx_1443x_dram_pll;
@@ -493,4 +505,8 @@ struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible,
 struct clk_hw *imx8m_anatop_get_clk_hw(int id);
 #endif
 
+void imx_clk_pll14xx_enable_ssc(struct clk_hw *hw, struct imx_pll14xx_ssc *conf);
+int imx_clk_pll14xx_ssc_parse_dt(struct device_node *np, const char *pll_name,
+				 struct imx_pll14xx_ssc *conf);
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec  1 09:46:18 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun,  1 Dec 2024 18:46:18 +0100
Subject: [PATCH v4 18/18] clk: imx8mn: support spread spectrum clock generation
In-Reply-To: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241201174639.742000-19-dario.binacchi@amarulasolutions.com>

Add support for spread spectrum clock generation for the audio, video,
and DRAM PLLs.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v1)

 drivers/clk/imx/clk-imx8mn.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 588cebce6c9d..c61368e724f7 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -306,6 +306,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	void __iomem *base;
+	struct imx_pll14xx_ssc ssc_conf;
 	int ret;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
@@ -338,9 +339,21 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_REF_SEL);
 
 	hws[IMX8MN_AUDIO_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "audio_pll1", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_AUDIO_PLL1], &ssc_conf);
+
 	hws[IMX8MN_AUDIO_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "audio_pll2", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_AUDIO_PLL2], &ssc_conf);
+
 	hws[IMX8MN_VIDEO_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "video_pll", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_VIDEO_PLL], &ssc_conf);
+
 	hws[IMX8MN_DRAM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "dram_pll", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_DRAM_PLL], &ssc_conf);
+
 	hws[IMX8MN_GPU_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL);
 	hws[IMX8MN_M7_ALT_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL);
 	hws[IMX8MN_ARM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL);
-- 
2.43.0



From lkp at intel.com  Sun Dec  1 11:31:10 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 2 Dec 2024 03:31:10 +0800
Subject: [PATCH v4 02/18] clk: imx8mp: rename video_pll1 to video_pll
In-Reply-To: <20241201174639.742000-3-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-3-dario.binacchi@amarulasolutions.com>
Message-ID: <202412020311.N7CKTzed-lkp@intel.com>

Hi Dario,

kernel test robot noticed the following build errors:

[auto build test ERROR on abelvesa/clk/imx]
[also build test ERROR on shawnguo/for-next clk/clk-next linus/master v6.12 next-20241128]
[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/Dario-Binacchi/clk-imx8mm-rename-video_pll1-to-video_pll/20241202-015316
base:   https://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git clk/imx
patch link:    https://lore.kernel.org/r/20241201174639.742000-3-dario.binacchi%40amarulasolutions.com
patch subject: [PATCH v4 02/18] clk: imx8mp: rename video_pll1 to video_pll
config: arm-randconfig-002-20241202 (https://download.01.org/0day-ci/archive/20241202/202412020311.N7CKTzed-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241202/202412020311.N7CKTzed-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/202412020311.N7CKTzed-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/clk/imx/clk-imx8mp.c:465:6: error: use of undeclared identifier 'IMX8MP_VIDEO_PLL_BYPASS'
     465 |         hws[IMX8MP_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", anatop_base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
         |             ^
   1 error generated.


vim +/IMX8MP_VIDEO_PLL_BYPASS +465 drivers/clk/imx/clk-imx8mp.c

   407	
   408	static int imx8mp_clocks_probe(struct platform_device *pdev)
   409	{
   410		struct device *dev = &pdev->dev;
   411		struct device_node *np;
   412		void __iomem *anatop_base, *ccm_base;
   413		int err;
   414	
   415		np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop");
   416		anatop_base = devm_of_iomap(dev, np, 0, NULL);
   417		of_node_put(np);
   418		if (WARN_ON(IS_ERR(anatop_base)))
   419			return PTR_ERR(anatop_base);
   420	
   421		np = dev->of_node;
   422		ccm_base = devm_platform_ioremap_resource(pdev, 0);
   423		if (WARN_ON(IS_ERR(ccm_base)))
   424			return PTR_ERR(ccm_base);
   425	
   426		clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
   427		if (WARN_ON(!clk_hw_data))
   428			return -ENOMEM;
   429	
   430		clk_hw_data->num = IMX8MP_CLK_END;
   431		hws = clk_hw_data->hws;
   432	
   433		hws[IMX8MP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
   434		hws[IMX8MP_CLK_24M] = imx_get_clk_hw_by_name(np, "osc_24m");
   435		hws[IMX8MP_CLK_32K] = imx_get_clk_hw_by_name(np, "osc_32k");
   436		hws[IMX8MP_CLK_EXT1] = imx_get_clk_hw_by_name(np, "clk_ext1");
   437		hws[IMX8MP_CLK_EXT2] = imx_get_clk_hw_by_name(np, "clk_ext2");
   438		hws[IMX8MP_CLK_EXT3] = imx_get_clk_hw_by_name(np, "clk_ext3");
   439		hws[IMX8MP_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
   440	
   441		hws[IMX8MP_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", anatop_base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   442		hws[IMX8MP_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", anatop_base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   443		hws[IMX8MP_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   444		hws[IMX8MP_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", anatop_base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   445		hws[IMX8MP_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", anatop_base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   446		hws[IMX8MP_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", anatop_base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   447		hws[IMX8MP_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", anatop_base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   448		hws[IMX8MP_SYS_PLL1_REF_SEL] = imx_clk_hw_mux("sys_pll1_ref_sel", anatop_base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   449		hws[IMX8MP_SYS_PLL2_REF_SEL] = imx_clk_hw_mux("sys_pll2_ref_sel", anatop_base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   450		hws[IMX8MP_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", anatop_base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   451	
   452		hws[IMX8MP_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", anatop_base, &imx_1443x_pll);
   453		hws[IMX8MP_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", anatop_base + 0x14, &imx_1443x_pll);
   454		hws[IMX8MP_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
   455		hws[IMX8MP_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", anatop_base + 0x50, &imx_1443x_dram_pll);
   456		hws[IMX8MP_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", anatop_base + 0x64, &imx_1416x_pll);
   457		hws[IMX8MP_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", anatop_base + 0x74, &imx_1416x_pll);
   458		hws[IMX8MP_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", anatop_base + 0x84, &imx_1416x_pll);
   459		hws[IMX8MP_SYS_PLL1] = imx_clk_hw_pll14xx("sys_pll1", "sys_pll1_ref_sel", anatop_base + 0x94, &imx_1416x_pll);
   460		hws[IMX8MP_SYS_PLL2] = imx_clk_hw_pll14xx("sys_pll2", "sys_pll2_ref_sel", anatop_base + 0x104, &imx_1416x_pll);
   461		hws[IMX8MP_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", anatop_base + 0x114, &imx_1416x_pll);
   462	
   463		hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
   464		hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
 > 465		hws[IMX8MP_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", anatop_base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
   466		hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
   467		hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
   468		hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
   469		hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
   470		hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
   471		hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
   472		hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
   473	
   474		hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
   475		hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
   476		hws[IMX8MP_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", anatop_base + 0x28, 13);
   477		hws[IMX8MP_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", anatop_base + 0x50, 13);
   478		hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
   479		hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
   480		hws[IMX8MP_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", anatop_base + 0x84, 11);
   481		hws[IMX8MP_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", anatop_base + 0x114, 11);
   482	
   483		hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
   484	
   485		hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
   486		hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
   487		hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
   488		hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
   489		hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
   490		hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
   491		hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
   492		hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
   493		hws[IMX8MP_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
   494	
   495		hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
   496	
   497		hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
   498		hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
   499		hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
   500		hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
   501		hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
   502		hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
   503		hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
   504		hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
   505		hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
   506	
   507		hws[IMX8MP_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", anatop_base + 0x128, 4, 4,
   508							      imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels));
   509		hws[IMX8MP_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", anatop_base + 0x128, 0, 4);
   510		hws[IMX8MP_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", anatop_base + 0x128, 8);
   511		hws[IMX8MP_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", anatop_base + 0x128, 20, 4,
   512							      imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels));
   513		hws[IMX8MP_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", anatop_base + 0x128, 16, 4);
   514		hws[IMX8MP_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", anatop_base + 0x128, 24);
   515	
   516		hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000);
   517		hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV];
   518		hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV];
   519		hws[IMX8MP_CLK_M7_CORE] = imx8m_clk_hw_composite_core("m7_core", imx8mp_m7_sels, ccm_base + 0x8080);
   520		hws[IMX8MP_CLK_ML_CORE] = imx8m_clk_hw_composite_core("ml_core", imx8mp_ml_sels, ccm_base + 0x8100);
   521		hws[IMX8MP_CLK_GPU3D_CORE] = imx8m_clk_hw_composite_core("gpu3d_core", imx8mp_gpu3d_core_sels, ccm_base + 0x8180);
   522		hws[IMX8MP_CLK_GPU3D_SHADER_CORE] = imx8m_clk_hw_composite("gpu3d_shader_core", imx8mp_gpu3d_shader_sels, ccm_base + 0x8200);
   523		hws[IMX8MP_CLK_GPU2D_CORE] = imx8m_clk_hw_composite("gpu2d_core", imx8mp_gpu2d_sels, ccm_base + 0x8280);
   524		hws[IMX8MP_CLK_AUDIO_AXI] = imx8m_clk_hw_composite("audio_axi", imx8mp_audio_axi_sels, ccm_base + 0x8300);
   525		hws[IMX8MP_CLK_AUDIO_AXI_SRC] = hws[IMX8MP_CLK_AUDIO_AXI];
   526		hws[IMX8MP_CLK_HSIO_AXI] = imx8m_clk_hw_composite("hsio_axi", imx8mp_hsio_axi_sels, ccm_base + 0x8380);
   527		hws[IMX8MP_CLK_MEDIA_ISP] = imx8m_clk_hw_composite("media_isp", imx8mp_media_isp_sels, ccm_base + 0x8400);
   528	
   529		/* CORE SEL */
   530		hws[IMX8MP_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", ccm_base + 0x9880, 24, 1, imx8mp_a53_core_sels, ARRAY_SIZE(imx8mp_a53_core_sels));
   531	
   532		hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_bus_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800);
   533		hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
   534		hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900);
   535		hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
   536		hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite_bus("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
   537		hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite_bus("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
   538		hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite_bus("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
   539		hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite_bus("hdmi_axi", imx8mp_media_axi_sels, ccm_base + 0x8b80);
   540		hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
   541		hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
   542		hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_bus_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00);
   543		hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_bus_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80);
   544		hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite_bus("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
   545		hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite_bus("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
   546	
   547		hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
   548		hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
   549		hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
   550		hws[IMX8MP_CLK_MEDIA_DISP2_PIX] = imx8m_clk_hw_composite_bus_flags("media_disp2_pix", imx8mp_media_disp_pix_sels, ccm_base + 0x9300, CLK_SET_RATE_PARENT);
   551	
   552		hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
   553	
   554		hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
   555		hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
   556		hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100);
   557		hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
   558		hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);
   559		hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, ccm_base + 0xa280);
   560		hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", imx8mp_pcie_aux_sels, ccm_base + 0xa400);
   561		hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, ccm_base + 0xa480);
   562		hws[IMX8MP_CLK_I2C6] = imx8m_clk_hw_composite("i2c6", imx8mp_i2c6_sels, ccm_base + 0xa500);
   563		hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580);
   564		hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600);
   565		hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680);
   566		hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780);
   567		hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800);
   568		hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880);
   569		hws[IMX8MP_CLK_ENET_QOS_TIMER] = imx8m_clk_hw_composite("enet_qos_timer", imx8mp_enet_qos_timer_sels, ccm_base + 0xa900);
   570		hws[IMX8MP_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mp_enet_ref_sels, ccm_base + 0xa980);
   571		hws[IMX8MP_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mp_enet_timer_sels, ccm_base + 0xaa00);
   572		hws[IMX8MP_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy_ref", imx8mp_enet_phy_ref_sels, ccm_base + 0xaa80);
   573		hws[IMX8MP_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mp_nand_sels, ccm_base + 0xab00);
   574		hws[IMX8MP_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mp_qspi_sels, ccm_base + 0xab80);
   575		hws[IMX8MP_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mp_usdhc1_sels, ccm_base + 0xac00);
   576		hws[IMX8MP_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mp_usdhc2_sels, ccm_base + 0xac80);
   577		hws[IMX8MP_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mp_i2c1_sels, ccm_base + 0xad00);
   578		hws[IMX8MP_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mp_i2c2_sels, ccm_base + 0xad80);
   579		hws[IMX8MP_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mp_i2c3_sels, ccm_base + 0xae00);
   580		hws[IMX8MP_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mp_i2c4_sels, ccm_base + 0xae80);
   581	
   582		hws[IMX8MP_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mp_uart1_sels, ccm_base + 0xaf00);
   583		hws[IMX8MP_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mp_uart2_sels, ccm_base + 0xaf80);
   584		hws[IMX8MP_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mp_uart3_sels, ccm_base + 0xb000);
   585		hws[IMX8MP_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mp_uart4_sels, ccm_base + 0xb080);
   586		hws[IMX8MP_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mp_usb_core_ref_sels, ccm_base + 0xb100);
   587		hws[IMX8MP_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mp_usb_phy_ref_sels, ccm_base + 0xb180);
   588		hws[IMX8MP_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mp_gic_sels, ccm_base + 0xb200);
   589		hws[IMX8MP_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mp_ecspi1_sels, ccm_base + 0xb280);
   590		hws[IMX8MP_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mp_ecspi2_sels, ccm_base + 0xb300);
   591		hws[IMX8MP_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mp_pwm1_sels, ccm_base + 0xb380);
   592		hws[IMX8MP_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mp_pwm2_sels, ccm_base + 0xb400);
   593		hws[IMX8MP_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mp_pwm3_sels, ccm_base + 0xb480);
   594		hws[IMX8MP_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mp_pwm4_sels, ccm_base + 0xb500);
   595	
   596		hws[IMX8MP_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mp_gpt1_sels, ccm_base + 0xb580);
   597		hws[IMX8MP_CLK_GPT2] = imx8m_clk_hw_composite("gpt2", imx8mp_gpt2_sels, ccm_base + 0xb600);
   598		hws[IMX8MP_CLK_GPT3] = imx8m_clk_hw_composite("gpt3", imx8mp_gpt3_sels, ccm_base + 0xb680);
   599		hws[IMX8MP_CLK_GPT4] = imx8m_clk_hw_composite("gpt4", imx8mp_gpt4_sels, ccm_base + 0xb700);
   600		hws[IMX8MP_CLK_GPT5] = imx8m_clk_hw_composite("gpt5", imx8mp_gpt5_sels, ccm_base + 0xb780);
   601		hws[IMX8MP_CLK_GPT6] = imx8m_clk_hw_composite("gpt6", imx8mp_gpt6_sels, ccm_base + 0xb800);
   602		hws[IMX8MP_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mp_wdog_sels, ccm_base + 0xb900);
   603		hws[IMX8MP_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mp_wrclk_sels, ccm_base + 0xb980);
   604		hws[IMX8MP_CLK_IPP_DO_CLKO1] = imx8m_clk_hw_composite("ipp_do_clko1", imx8mp_ipp_do_clko1_sels, ccm_base + 0xba00);
   605		hws[IMX8MP_CLK_IPP_DO_CLKO2] = imx8m_clk_hw_composite("ipp_do_clko2", imx8mp_ipp_do_clko2_sels, ccm_base + 0xba80);
   606		hws[IMX8MP_CLK_HDMI_FDCC_TST] = imx8m_clk_hw_composite("hdmi_fdcc_tst", imx8mp_hdmi_fdcc_tst_sels, ccm_base + 0xbb00);
   607		hws[IMX8MP_CLK_HDMI_24M] = imx8m_clk_hw_composite("hdmi_24m", imx8mp_hdmi_24m_sels, ccm_base + 0xbb80);
   608		hws[IMX8MP_CLK_HDMI_REF_266M] = imx8m_clk_hw_composite("hdmi_ref_266m", imx8mp_hdmi_ref_266m_sels, ccm_base + 0xbc00);
   609		hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80);
   610		hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00);
   611		hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
   612		hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite_bus_flags("media_disp1_pix", imx8mp_media_disp_pix_sels, ccm_base + 0xbe00, CLK_SET_RATE_PARENT);
   613		hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
   614		hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00);
   615		hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80);
   616		hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = imx8m_clk_hw_composite("media_mipi_test_byte", imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100);
   617		hws[IMX8MP_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mp_ecspi3_sels, ccm_base + 0xc180);
   618		hws[IMX8MP_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mp_pdm_sels, ccm_base + 0xc200);
   619		hws[IMX8MP_CLK_VPU_VC8000E] = imx8m_clk_hw_composite("vpu_vc8000e", imx8mp_vpu_vc8000e_sels, ccm_base + 0xc280);
   620		hws[IMX8MP_CLK_SAI7] = imx8m_clk_hw_composite("sai7", imx8mp_sai7_sels, ccm_base + 0xc300);
   621	
   622		hws[IMX8MP_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
   623		hws[IMX8MP_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", ccm_base + 0x9800, 24, 1, imx8mp_dram_core_sels, ARRAY_SIZE(imx8mp_dram_core_sels), CLK_IS_CRITICAL);
   624	
   625		hws[IMX8MP_CLK_DRAM1_ROOT] = imx_clk_hw_gate4_flags("dram1_root_clk", "dram_core_clk", ccm_base + 0x4050, 0, CLK_IS_CRITICAL);
   626		hws[IMX8MP_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", ccm_base + 0x4070, 0);
   627		hws[IMX8MP_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", ccm_base + 0x4080, 0);
   628		hws[IMX8MP_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", ccm_base + 0x4090, 0);
   629		hws[IMX8MP_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", ccm_base + 0x40a0, 0);
   630		hws[IMX8MP_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", ccm_base + 0x40b0, 0);
   631		hws[IMX8MP_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", ccm_base + 0x40c0, 0);
   632		hws[IMX8MP_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", ccm_base + 0x40d0, 0);
   633		hws[IMX8MP_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", ccm_base + 0x40e0, 0);
   634		hws[IMX8MP_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", ccm_base + 0x40f0, 0);
   635		hws[IMX8MP_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", ccm_base + 0x4100, 0);
   636		hws[IMX8MP_CLK_GPT2_ROOT] = imx_clk_hw_gate4("gpt2_root_clk", "gpt2", ccm_base + 0x4110, 0);
   637		hws[IMX8MP_CLK_GPT3_ROOT] = imx_clk_hw_gate4("gpt3_root_clk", "gpt3", ccm_base + 0x4120, 0);
   638		hws[IMX8MP_CLK_GPT4_ROOT] = imx_clk_hw_gate4("gpt4_root_clk", "gpt4", ccm_base + 0x4130, 0);
   639		hws[IMX8MP_CLK_GPT5_ROOT] = imx_clk_hw_gate4("gpt5_root_clk", "gpt5", ccm_base + 0x4140, 0);
   640		hws[IMX8MP_CLK_GPT6_ROOT] = imx_clk_hw_gate4("gpt6_root_clk", "gpt6", ccm_base + 0x4150, 0);
   641		hws[IMX8MP_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", ccm_base + 0x4170, 0);
   642		hws[IMX8MP_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", ccm_base + 0x4180, 0);
   643		hws[IMX8MP_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", ccm_base + 0x4190, 0);
   644		hws[IMX8MP_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", ccm_base + 0x41a0, 0);
   645		hws[IMX8MP_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", ccm_base + 0x4210, 0);
   646		hws[IMX8MP_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", ccm_base + 0x4220, 0);
   647		hws[IMX8MP_CLK_PCIE_ROOT] = imx_clk_hw_gate4("pcie_root_clk", "pcie_aux", ccm_base + 0x4250, 0);
   648		hws[IMX8MP_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", ccm_base + 0x4280, 0);
   649		hws[IMX8MP_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", ccm_base + 0x4290, 0);
   650		hws[IMX8MP_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", ccm_base + 0x42a0, 0);
   651		hws[IMX8MP_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", ccm_base + 0x42b0, 0);
   652		hws[IMX8MP_CLK_QOS_ROOT] = imx_clk_hw_gate4("qos_root_clk", "ipg_root", ccm_base + 0x42c0, 0);
   653		hws[IMX8MP_CLK_QOS_ENET_ROOT] = imx_clk_hw_gate4("qos_enet_root_clk", "ipg_root", ccm_base + 0x42e0, 0);
   654		hws[IMX8MP_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", ccm_base + 0x42f0, 0);
   655		hws[IMX8MP_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", ccm_base + 0x4300, 0, &share_count_nand);
   656		hws[IMX8MP_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", ccm_base + 0x4300, 0, &share_count_nand);
   657		hws[IMX8MP_CLK_I2C5_ROOT] = imx_clk_hw_gate2("i2c5_root_clk", "i2c5", ccm_base + 0x4330, 0);
   658		hws[IMX8MP_CLK_I2C6_ROOT] = imx_clk_hw_gate2("i2c6_root_clk", "i2c6", ccm_base + 0x4340, 0);
   659		hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0);
   660		hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0);
   661		hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
   662		hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
   663		hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
   664		hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
   665		hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
   666		hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
   667		hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
   668		hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0);
   669		hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0);
   670		hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate2_shared2("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0, &share_count_usb);
   671		hws[IMX8MP_CLK_USB_SUSP] = imx_clk_hw_gate2_shared2("usb_suspend_clk", "osc_32k", ccm_base + 0x44d0, 0, &share_count_usb);
   672		hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0);
   673		hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0);
   674		hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);
   675		hws[IMX8MP_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", ccm_base + 0x4530, 0);
   676		hws[IMX8MP_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", ccm_base + 0x4540, 0);
   677		hws[IMX8MP_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", ccm_base + 0x4550, 0);
   678		hws[IMX8MP_CLK_VPU_G1_ROOT] = imx_clk_hw_gate4("vpu_g1_root_clk", "vpu_g1", ccm_base + 0x4560, 0);
   679		hws[IMX8MP_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", ccm_base + 0x4570, 0);
   680		hws[IMX8MP_CLK_VPU_VC8KE_ROOT] = imx_clk_hw_gate4("vpu_vc8ke_root_clk", "vpu_vc8000e", ccm_base + 0x4590, 0);
   681		hws[IMX8MP_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", ccm_base + 0x45a0, 0);
   682		hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_core", ccm_base + 0x45b0, 0);
   683		hws[IMX8MP_CLK_HSIO_ROOT] = imx_clk_hw_gate4("hsio_root_clk", "ipg_root", ccm_base + 0x45c0, 0);
   684		hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0, &share_count_media);
   685		hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0, &share_count_media);
   686		hws[IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam1_pix_root_clk", "media_cam1_pix", ccm_base + 0x45d0, 0, &share_count_media);
   687		hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media);
   688		hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media);
   689		hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media);
   690		hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT] = imx_clk_hw_gate2_shared2("media_mipi_phy1_ref_root", "media_mipi_phy1_ref", ccm_base + 0x45d0, 0, &share_count_media);
   691		hws[IMX8MP_CLK_MEDIA_LDB_ROOT] = imx_clk_hw_gate2_shared2("media_ldb_root_clk", "media_ldb", ccm_base + 0x45d0, 0, &share_count_media);
   692		hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp", ccm_base + 0x45d0, 0, &share_count_media);
   693	
   694		hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0);
   695		hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0);
   696		hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", "ipg_root", ccm_base + 0x4620, 0);
   697		hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", ccm_base + 0x4630, 0);
   698	
   699		hws[IMX8MP_CLK_AUDIO_AHB_ROOT] = imx_clk_hw_gate2_shared2("audio_ahb_root", "audio_ahb", ccm_base + 0x4650, 0, &share_count_audio);
   700		hws[IMX8MP_CLK_AUDIO_AXI_ROOT] = imx_clk_hw_gate2_shared2("audio_axi_root", "audio_axi", ccm_base + 0x4650, 0, &share_count_audio);
   701		hws[IMX8MP_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root", "sai1", ccm_base + 0x4650, 0, &share_count_audio);
   702		hws[IMX8MP_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root", "sai2", ccm_base + 0x4650, 0, &share_count_audio);
   703		hws[IMX8MP_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root", "sai3", ccm_base + 0x4650, 0, &share_count_audio);
   704		hws[IMX8MP_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root", "sai5", ccm_base + 0x4650, 0, &share_count_audio);
   705		hws[IMX8MP_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root", "sai6", ccm_base + 0x4650, 0, &share_count_audio);
   706		hws[IMX8MP_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root", "sai7", ccm_base + 0x4650, 0, &share_count_audio);
   707		hws[IMX8MP_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root", "pdm", ccm_base + 0x4650, 0, &share_count_audio);
   708	
   709		hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core",
   710						     hws[IMX8MP_CLK_A53_CORE]->clk,
   711						     hws[IMX8MP_CLK_A53_CORE]->clk,
   712						     hws[IMX8MP_ARM_PLL_OUT]->clk,
   713						     hws[IMX8MP_CLK_A53_DIV]->clk);
   714	
   715		imx_check_clk_hws(hws, IMX8MP_CLK_END);
   716	
   717		err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
   718		if (err < 0) {
   719			dev_err(dev, "failed to register hws for i.MX8MP\n");
   720			imx_unregister_hw_clocks(hws, IMX8MP_CLK_END);
   721			return err;
   722		}
   723	
   724		imx_register_uart_clocks();
   725	
   726		return 0;
   727	}
   728	

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


From rppt at kernel.org  Sun Dec  1 11:32:22 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Sun, 1 Dec 2024 21:32:22 +0200
Subject: [PATCH v2] arch_numa: Restore nid checks before registering a
 memblock with a node
In-Reply-To: <20241201092702.3792845-1-maz@kernel.org>
References: <20241201092702.3792845-1-maz@kernel.org>
Message-ID: <Z0y5xsGgtJrSkyBe@kernel.org>

Hi Marc,

On Sun, Dec 01, 2024 at 09:27:02AM +0000, Marc Zyngier wrote:
> Commit 767507654c22 ("arch_numa: switch over to numa_memblks")
> significantly cleaned up the NUMA registration code, but also
> dropped a significant check that was refusing to accept to
> configure a memblock with an invalid nid.

... 
 
> while previous kernel versions were able to recognise how brain-damaged
> the machine is, and only build a fake node.
> 
> Use the memblock_validate_numa_coverage() helper to restore some sanity
> and a "working" system.
> 
> Fixes: 767507654c22 ("arch_numa: switch over to numa_memblks")
> Suggested-by: Mike Rapoport <rppt at kernel.org>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Zi Yan <ziy at nvidia.com>
> Cc: Dan Williams <dan.j.williams at intel.com>
> Cc: David Hildenbrand <david at redhat.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: stable at vger.kernel.org
> ---
>  drivers/base/arch_numa.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
> index e187016764265..c63a72a1fed64 100644
> --- a/drivers/base/arch_numa.c
> +++ b/drivers/base/arch_numa.c
> @@ -208,6 +208,10 @@ static int __init numa_register_nodes(void)
>  {
>  	int nid;
>  
> +	/* Check the validity of the memblock/node mapping */
> +	if (!memblock_validate_numa_coverage(1))

I've changed this to memblock_validate_numa_coverage(0) and applied along
with my patch that changed memblock_validate_numa_coverage() to work with
0:

https://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git/log/?h=thunderx-fix

Can you please verify that it works on your "quality hardware"?

> +		return -EINVAL;
> +
>  	/* Finally register nodes. */
>  	for_each_node_mask(nid, numa_nodes_parsed) {
>  		unsigned long start_pfn, end_pfn;
> -- 
> 2.39.2

-- 
Sincerely yours,
Mike.


From maz at kernel.org  Sun Dec  1 11:49:44 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Dec 2024 19:49:44 +0000
Subject: [PATCH v2] arch_numa: Restore nid checks before registering a memblock with a node
In-Reply-To: <Z0y5xsGgtJrSkyBe@kernel.org>
References: <20241201092702.3792845-1-maz@kernel.org>
	<Z0y5xsGgtJrSkyBe@kernel.org>
Message-ID: <86zflftc87.wl-maz@kernel.org>

Hi Mike,

On Sun, 01 Dec 2024 19:32:22 +0000,
Mike Rapoport <rppt at kernel.org> wrote:
> 
> Hi Marc,
> 
> On Sun, Dec 01, 2024 at 09:27:02AM +0000, Marc Zyngier wrote:
> > Commit 767507654c22 ("arch_numa: switch over to numa_memblks")
> > significantly cleaned up the NUMA registration code, but also
> > dropped a significant check that was refusing to accept to
> > configure a memblock with an invalid nid.
> 
> ... 
>  
> > while previous kernel versions were able to recognise how brain-damaged
> > the machine is, and only build a fake node.
> > 
> > Use the memblock_validate_numa_coverage() helper to restore some sanity
> > and a "working" system.
> > 
> > Fixes: 767507654c22 ("arch_numa: switch over to numa_memblks")
> > Suggested-by: Mike Rapoport <rppt at kernel.org>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > Cc: Will Deacon <will at kernel.org>
> > Cc: Zi Yan <ziy at nvidia.com>
> > Cc: Dan Williams <dan.j.williams at intel.com>
> > Cc: David Hildenbrand <david at redhat.com>
> > Cc: Andrew Morton <akpm at linux-foundation.org>
> > Cc: stable at vger.kernel.org
> > ---
> >  drivers/base/arch_numa.c | 4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
> > index e187016764265..c63a72a1fed64 100644
> > --- a/drivers/base/arch_numa.c
> > +++ b/drivers/base/arch_numa.c
> > @@ -208,6 +208,10 @@ static int __init numa_register_nodes(void)
> >  {
> >  	int nid;
> >  
> > +	/* Check the validity of the memblock/node mapping */
> > +	if (!memblock_validate_numa_coverage(1))
> 
> I've changed this to memblock_validate_numa_coverage(0) and applied along
> with my patch that changed memblock_validate_numa_coverage() to work with
> 0:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git/log/?h=thunderx-fix
> 
> Can you please verify that it works on your "quality hardware"?

Commit 427c6179e159b in your tree still has memblock_validate_numa_coverage(1).
Forgot to push out the updated version?

Flipping this to 0 locally, I have verified that this still allows the
old thing to trudge along:

root at duodenum:~# uname -a
Linux duodenum 6.12.0-12115-g427c6179e159-dirty #3896 SMP PREEMPT Sun Dec  1 19:43:13 GMT 2024 aarch64

Thanks again,

	M.

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


From lkp at intel.com  Sun Dec  1 11:51:32 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 2 Dec 2024 03:51:32 +0800
Subject: [PATCH v4 12/18] clk: imx: add support for i.MX8MN anatop clock
 driver
In-Reply-To: <20241201174639.742000-13-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-13-dario.binacchi@amarulasolutions.com>
Message-ID: <202412020318.WUBdIsyd-lkp@intel.com>

Hi Dario,

kernel test robot noticed the following build errors:

[auto build test ERROR on abelvesa/clk/imx]
[also build test ERROR on shawnguo/for-next clk/clk-next linus/master v6.12 next-20241128]
[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/Dario-Binacchi/clk-imx8mm-rename-video_pll1-to-video_pll/20241202-015316
base:   https://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git clk/imx
patch link:    https://lore.kernel.org/r/20241201174639.742000-13-dario.binacchi%40amarulasolutions.com
patch subject: [PATCH v4 12/18] clk: imx: add support for i.MX8MN anatop clock driver
config: arc-randconfig-002-20241202 (https://download.01.org/0day-ci/archive/20241202/202412020318.WUBdIsyd-lkp at intel.com/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241202/202412020318.WUBdIsyd-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/202412020318.WUBdIsyd-lkp at intel.com/

All error/warnings (new ones prefixed by >>):

   drivers/clk/imx/clk-imx8mn.c: In function 'imx8mn_clocks_probe':
>> drivers/clk/imx/clk-imx8mn.c:323:33: error: implicit declaration of function 'imx8m_anatop_get_clk_hw' [-Werror=implicit-function-declaration]
     323 |         hws[IMX8MN_CLK_DUMMY] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_DUMMY);
         |                                 ^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/clk/imx/clk-imx8mn.c:323:31: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     323 |         hws[IMX8MN_CLK_DUMMY] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_DUMMY);
         |                               ^
   drivers/clk/imx/clk-imx8mn.c:324:29: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     324 |         hws[IMX8MN_CLK_24M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_24M);
         |                             ^
   drivers/clk/imx/clk-imx8mn.c:325:29: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     325 |         hws[IMX8MN_CLK_32K] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_32K);
         |                             ^
   drivers/clk/imx/clk-imx8mn.c:331:40: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     331 |         hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL);
         |                                        ^
   drivers/clk/imx/clk-imx8mn.c:332:40: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     332 |         hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL);
         |                                        ^
   drivers/clk/imx/clk-imx8mn.c:333:39: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     333 |         hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_REF_SEL);
         |                                       ^
   drivers/clk/imx/clk-imx8mn.c:334:38: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     334 |         hws[IMX8MN_DRAM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_REF_SEL);
         |                                      ^
   drivers/clk/imx/clk-imx8mn.c:335:37: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     335 |         hws[IMX8MN_GPU_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_REF_SEL);
         |                                     ^
   drivers/clk/imx/clk-imx8mn.c:336:40: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     336 |         hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL);
         |                                        ^
   drivers/clk/imx/clk-imx8mn.c:337:37: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     337 |         hws[IMX8MN_ARM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_REF_SEL);
         |                                     ^
   drivers/clk/imx/clk-imx8mn.c:338:38: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     338 |         hws[IMX8MN_SYS_PLL3_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_REF_SEL);
         |                                      ^
   drivers/clk/imx/clk-imx8mn.c:340:32: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     340 |         hws[IMX8MN_AUDIO_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1);
         |                                ^
   drivers/clk/imx/clk-imx8mn.c:341:32: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     341 |         hws[IMX8MN_AUDIO_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2);
         |                                ^
   drivers/clk/imx/clk-imx8mn.c:342:31: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     342 |         hws[IMX8MN_VIDEO_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL);
         |                               ^
   drivers/clk/imx/clk-imx8mn.c:343:30: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     343 |         hws[IMX8MN_DRAM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL);
         |                              ^
   drivers/clk/imx/clk-imx8mn.c:344:29: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     344 |         hws[IMX8MN_GPU_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL);
         |                             ^
   drivers/clk/imx/clk-imx8mn.c:345:32: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     345 |         hws[IMX8MN_M7_ALT_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL);
         |                                ^
   drivers/clk/imx/clk-imx8mn.c:346:29: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     346 |         hws[IMX8MN_ARM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL);
         |                             ^
   drivers/clk/imx/clk-imx8mn.c:347:30: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     347 |         hws[IMX8MN_SYS_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1);
         |                              ^
   drivers/clk/imx/clk-imx8mn.c:348:30: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     348 |         hws[IMX8MN_SYS_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2);
         |                              ^
   drivers/clk/imx/clk-imx8mn.c:349:30: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     349 |         hws[IMX8MN_SYS_PLL3] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3);
         |                              ^
   drivers/clk/imx/clk-imx8mn.c:352:39: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     352 |         hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_BYPASS);
         |                                       ^
   drivers/clk/imx/clk-imx8mn.c:353:39: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     353 |         hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_BYPASS);
         |                                       ^
   drivers/clk/imx/clk-imx8mn.c:354:38: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     354 |         hws[IMX8MN_VIDEO_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_BYPASS);
         |                                      ^
   drivers/clk/imx/clk-imx8mn.c:355:37: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     355 |         hws[IMX8MN_DRAM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_BYPASS);
         |                                     ^
   drivers/clk/imx/clk-imx8mn.c:356:36: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     356 |         hws[IMX8MN_GPU_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_BYPASS);
         |                                    ^
   drivers/clk/imx/clk-imx8mn.c:357:39: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     357 |         hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_BYPASS);
         |                                       ^
   drivers/clk/imx/clk-imx8mn.c:358:36: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     358 |         hws[IMX8MN_ARM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_BYPASS);
         |                                    ^
   drivers/clk/imx/clk-imx8mn.c:359:37: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     359 |         hws[IMX8MN_SYS_PLL3_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_BYPASS);
         |                                     ^
   drivers/clk/imx/clk-imx8mn.c:362:36: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     362 |         hws[IMX8MN_AUDIO_PLL1_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_OUT);
         |                                    ^
   drivers/clk/imx/clk-imx8mn.c:363:36: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     363 |         hws[IMX8MN_AUDIO_PLL2_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_OUT);
         |                                    ^
   drivers/clk/imx/clk-imx8mn.c:364:35: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     364 |         hws[IMX8MN_VIDEO_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_OUT);
         |                                   ^
   drivers/clk/imx/clk-imx8mn.c:365:34: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     365 |         hws[IMX8MN_DRAM_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_OUT);
         |                                  ^
   drivers/clk/imx/clk-imx8mn.c:366:33: warning: assignment to 'struct clk_hw *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     366 |         hws[IMX8MN_GPU_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_OUT);


vim +/imx8m_anatop_get_clk_hw +323 drivers/clk/imx/clk-imx8mn.c

   303	
   304	static int imx8mn_clocks_probe(struct platform_device *pdev)
   305	{
   306		struct device *dev = &pdev->dev;
   307		struct device_node *np = dev->of_node;
   308		void __iomem *base;
   309		int ret;
   310	
   311		base = devm_platform_ioremap_resource(pdev, 0);
   312		if (WARN_ON(IS_ERR(base)))
   313			return PTR_ERR(base);
   314	
   315		clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
   316						  IMX8MN_CLK_END), GFP_KERNEL);
   317		if (WARN_ON(!clk_hw_data))
   318			return -ENOMEM;
   319	
   320		clk_hw_data->num = IMX8MN_CLK_END;
   321		hws = clk_hw_data->hws;
   322	
 > 323		hws[IMX8MN_CLK_DUMMY] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_DUMMY);
   324		hws[IMX8MN_CLK_24M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_24M);
   325		hws[IMX8MN_CLK_32K] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_32K);
   326		hws[IMX8MN_CLK_EXT1] = imx_get_clk_hw_by_name(np, "clk_ext1");
   327		hws[IMX8MN_CLK_EXT2] = imx_get_clk_hw_by_name(np, "clk_ext2");
   328		hws[IMX8MN_CLK_EXT3] = imx_get_clk_hw_by_name(np, "clk_ext3");
   329		hws[IMX8MN_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
   330	
   331		hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL);
   332		hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL);
   333		hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_REF_SEL);
   334		hws[IMX8MN_DRAM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_REF_SEL);
   335		hws[IMX8MN_GPU_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_REF_SEL);
   336		hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL);
   337		hws[IMX8MN_ARM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_REF_SEL);
   338		hws[IMX8MN_SYS_PLL3_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_REF_SEL);
   339	
   340		hws[IMX8MN_AUDIO_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1);
   341		hws[IMX8MN_AUDIO_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2);
   342		hws[IMX8MN_VIDEO_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL);
   343		hws[IMX8MN_DRAM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL);
   344		hws[IMX8MN_GPU_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL);
   345		hws[IMX8MN_M7_ALT_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL);
   346		hws[IMX8MN_ARM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL);
   347		hws[IMX8MN_SYS_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1);
   348		hws[IMX8MN_SYS_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2);
   349		hws[IMX8MN_SYS_PLL3] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3);
   350	
   351		/* PLL bypass out */
   352		hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_BYPASS);
   353		hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_BYPASS);
   354		hws[IMX8MN_VIDEO_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_BYPASS);
   355		hws[IMX8MN_DRAM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_BYPASS);
   356		hws[IMX8MN_GPU_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_BYPASS);
   357		hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_BYPASS);
   358		hws[IMX8MN_ARM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_BYPASS);
   359		hws[IMX8MN_SYS_PLL3_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_BYPASS);
   360	
   361		/* PLL out gate */
   362		hws[IMX8MN_AUDIO_PLL1_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_OUT);
   363		hws[IMX8MN_AUDIO_PLL2_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_OUT);
   364		hws[IMX8MN_VIDEO_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_OUT);
   365		hws[IMX8MN_DRAM_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_OUT);
   366		hws[IMX8MN_GPU_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_OUT);
   367		hws[IMX8MN_M7_ALT_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_OUT);
   368		hws[IMX8MN_ARM_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_OUT);
   369		hws[IMX8MN_SYS_PLL3_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_OUT);
   370	
   371		/* SYS PLL1 fixed output */
   372		hws[IMX8MN_SYS_PLL1_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_OUT);
   373		hws[IMX8MN_SYS_PLL1_40M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_40M);
   374		hws[IMX8MN_SYS_PLL1_80M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_80M);
   375		hws[IMX8MN_SYS_PLL1_100M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_100M);
   376		hws[IMX8MN_SYS_PLL1_133M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_133M);
   377		hws[IMX8MN_SYS_PLL1_160M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_160M);
   378		hws[IMX8MN_SYS_PLL1_200M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_200M);
   379		hws[IMX8MN_SYS_PLL1_266M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_266M);
   380		hws[IMX8MN_SYS_PLL1_400M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_400M);
   381		hws[IMX8MN_SYS_PLL1_800M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_800M);
   382	
   383		/* SYS PLL2 fixed output */
   384		hws[IMX8MN_SYS_PLL2_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_OUT);
   385		hws[IMX8MN_SYS_PLL2_50M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_50M);
   386		hws[IMX8MN_SYS_PLL2_100M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_100M);
   387		hws[IMX8MN_SYS_PLL2_125M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_125M);
   388		hws[IMX8MN_SYS_PLL2_166M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_166M);
   389		hws[IMX8MN_SYS_PLL2_200M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_200M);
   390		hws[IMX8MN_SYS_PLL2_250M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_250M);
   391		hws[IMX8MN_SYS_PLL2_333M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_333M);
   392		hws[IMX8MN_SYS_PLL2_500M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_500M);
   393		hws[IMX8MN_SYS_PLL2_1000M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_1000M);
   394	
   395		hws[IMX8MN_CLK_CLKOUT1_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1_SEL);
   396		hws[IMX8MN_CLK_CLKOUT1_DIV] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1_DIV);
   397		hws[IMX8MN_CLK_CLKOUT1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1);
   398		hws[IMX8MN_CLK_CLKOUT2_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2_SEL);
   399		hws[IMX8MN_CLK_CLKOUT2_DIV] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2_DIV);
   400		hws[IMX8MN_CLK_CLKOUT2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2);
   401	
   402		/* CORE */
   403		hws[IMX8MN_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mn_a53_sels, base + 0x8000);
   404		hws[IMX8MN_CLK_A53_SRC] = hws[IMX8MN_CLK_A53_DIV];
   405		hws[IMX8MN_CLK_A53_CG] = hws[IMX8MN_CLK_A53_DIV];
   406	
   407		hws[IMX8MN_CLK_M7_CORE] = imx8m_clk_hw_composite_core("arm_m7_core", imx8mn_m7_sels, base + 0x8080);
   408	
   409		hws[IMX8MN_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mn_gpu_core_sels, base + 0x8180);
   410		hws[IMX8MN_CLK_GPU_SHADER] = imx8m_clk_hw_composite_core("gpu_shader", imx8mn_gpu_shader_sels, base + 0x8200);
   411	
   412		hws[IMX8MN_CLK_GPU_CORE_SRC] = hws[IMX8MN_CLK_GPU_CORE];
   413		hws[IMX8MN_CLK_GPU_CORE_CG] = hws[IMX8MN_CLK_GPU_CORE];
   414		hws[IMX8MN_CLK_GPU_CORE_DIV] = hws[IMX8MN_CLK_GPU_CORE];
   415		hws[IMX8MN_CLK_GPU_SHADER_SRC] = hws[IMX8MN_CLK_GPU_SHADER];
   416		hws[IMX8MN_CLK_GPU_SHADER_CG] = hws[IMX8MN_CLK_GPU_SHADER];
   417		hws[IMX8MN_CLK_GPU_SHADER_DIV] = hws[IMX8MN_CLK_GPU_SHADER];
   418	
   419		/* CORE SEL */
   420		hws[IMX8MN_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", base + 0x9880, 24, 1, imx8mn_a53_core_sels, ARRAY_SIZE(imx8mn_a53_core_sels));
   421	
   422		/* BUS */
   423		hws[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_hw_composite_bus_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
   424		hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
   425		hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_bus("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
   426		hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
   427		hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
   428		hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
   429		hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
   430		hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
   431		hws[IMX8MN_CLK_NOC] = imx8m_clk_hw_composite_bus_critical("noc", imx8mn_noc_sels, base + 0x8d00);
   432	
   433		hws[IMX8MN_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
   434		hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
   435		hws[IMX8MN_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
   436		hws[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
   437		hws[IMX8MN_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
   438	
   439		/*
   440		 * DRAM clocks are manipulated from TF-A outside clock framework.
   441		 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
   442		 * as div value should always be read from hardware
   443		 */
   444		hws[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
   445		hws[IMX8MN_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
   446	
   447		hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite_flags("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500, CLK_SET_RATE_PARENT);
   448		hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
   449		hws[IMX8MN_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mn_sai3_sels, base + 0xa680);
   450		hws[IMX8MN_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mn_sai5_sels, base + 0xa780);
   451		hws[IMX8MN_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mn_sai6_sels, base + 0xa800);
   452		hws[IMX8MN_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mn_spdif1_sels, base + 0xa880);
   453		hws[IMX8MN_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mn_enet_ref_sels, base + 0xa980);
   454		hws[IMX8MN_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mn_enet_timer_sels, base + 0xaa00);
   455		hws[IMX8MN_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mn_enet_phy_sels, base + 0xaa80);
   456		hws[IMX8MN_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mn_nand_sels, base + 0xab00);
   457		hws[IMX8MN_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mn_qspi_sels, base + 0xab80);
   458		hws[IMX8MN_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mn_usdhc1_sels, base + 0xac00);
   459		hws[IMX8MN_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mn_usdhc2_sels, base + 0xac80);
   460		hws[IMX8MN_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00);
   461		hws[IMX8MN_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80);
   462		hws[IMX8MN_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00);
   463		hws[IMX8MN_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80);
   464		hws[IMX8MN_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mn_uart1_sels, base + 0xaf00);
   465		hws[IMX8MN_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mn_uart2_sels, base + 0xaf80);
   466		hws[IMX8MN_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mn_uart3_sels, base + 0xb000);
   467		hws[IMX8MN_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mn_uart4_sels, base + 0xb080);
   468		hws[IMX8MN_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100);
   469		hws[IMX8MN_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180);
   470		hws[IMX8MN_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mn_gic_sels, base + 0xb200);
   471		hws[IMX8MN_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mn_ecspi1_sels, base + 0xb280);
   472		hws[IMX8MN_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mn_ecspi2_sels, base + 0xb300);
   473		hws[IMX8MN_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380);
   474		hws[IMX8MN_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400);
   475		hws[IMX8MN_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480);
   476		hws[IMX8MN_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500);
   477		hws[IMX8MN_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mn_gpt1_sels, base + 0xb580);
   478		hws[IMX8MN_CLK_GPT2] = imx8m_clk_hw_composite("gpt2", imx8mn_gpt2_sels, base + 0xb600);
   479		hws[IMX8MN_CLK_GPT3] = imx8m_clk_hw_composite("gpt3", imx8mn_gpt3_sels, base + 0xb680);
   480		hws[IMX8MN_CLK_GPT4] = imx8m_clk_hw_composite("gpt4", imx8mn_gpt4_sels, base + 0xb700);
   481		hws[IMX8MN_CLK_GPT5] = imx8m_clk_hw_composite("gpt5", imx8mn_gpt5_sels, base + 0xb780);
   482		hws[IMX8MN_CLK_GPT6] = imx8m_clk_hw_composite("gpt6", imx8mn_gpt6_sels, base + 0xb800);
   483		hws[IMX8MN_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mn_wdog_sels, base + 0xb900);
   484		hws[IMX8MN_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980);
   485		hws[IMX8MN_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mn_clko1_sels, base + 0xba00);
   486		hws[IMX8MN_CLK_CLKO2] = imx8m_clk_hw_composite("clko2", imx8mn_clko2_sels, base + 0xba80);
   487		hws[IMX8MN_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00);
   488		hws[IMX8MN_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80);
   489		hws[IMX8MN_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00);
   490		hws[IMX8MN_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80);
   491		hws[IMX8MN_CLK_CAMERA_PIXEL] = imx8m_clk_hw_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00);
   492		hws[IMX8MN_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mn_csi1_phy_sels, base + 0xbd80);
   493		hws[IMX8MN_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mn_csi2_phy_sels, base + 0xbf00);
   494		hws[IMX8MN_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mn_csi2_esc_sels, base + 0xbf80);
   495		hws[IMX8MN_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mn_ecspi3_sels, base + 0xc180);
   496		hws[IMX8MN_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mn_pdm_sels, base + 0xc200);
   497		hws[IMX8MN_CLK_SAI7] = imx8m_clk_hw_composite("sai7", imx8mn_sai7_sels, base + 0xc300);
   498	
   499		hws[IMX8MN_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
   500		hws[IMX8MN_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
   501		hws[IMX8MN_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
   502		hws[IMX8MN_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
   503		hws[IMX8MN_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
   504		hws[IMX8MN_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
   505		hws[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
   506		hws[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
   507		hws[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
   508		hws[IMX8MN_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
   509		hws[IMX8MN_CLK_GPT2_ROOT] = imx_clk_hw_gate4("gpt2_root_clk", "gpt2", base + 0x4110, 0);
   510		hws[IMX8MN_CLK_GPT3_ROOT] = imx_clk_hw_gate4("gpt3_root_clk", "gpt3", base + 0x4120, 0);
   511		hws[IMX8MN_CLK_GPT4_ROOT] = imx_clk_hw_gate4("gpt4_root_clk", "gpt4", base + 0x4130, 0);
   512		hws[IMX8MN_CLK_GPT5_ROOT] = imx_clk_hw_gate4("gpt5_root_clk", "gpt5", base + 0x4140, 0);
   513		hws[IMX8MN_CLK_GPT6_ROOT] = imx_clk_hw_gate4("gpt6_root_clk", "gpt6", base + 0x4150, 0);
   514		hws[IMX8MN_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
   515		hws[IMX8MN_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
   516		hws[IMX8MN_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
   517		hws[IMX8MN_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
   518		hws[IMX8MN_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
   519		hws[IMX8MN_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
   520		hws[IMX8MN_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
   521		hws[IMX8MN_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
   522		hws[IMX8MN_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
   523		hws[IMX8MN_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
   524		hws[IMX8MN_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
   525		hws[IMX8MN_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
   526		hws[IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
   527		hws[IMX8MN_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
   528		hws[IMX8MN_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
   529		hws[IMX8MN_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
   530		hws[IMX8MN_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
   531		hws[IMX8MN_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
   532		hws[IMX8MN_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
   533		hws[IMX8MN_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
   534		hws[IMX8MN_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
   535		hws[IMX8MN_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
   536		hws[IMX8MN_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
   537		hws[IMX8MN_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
   538		hws[IMX8MN_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
   539		hws[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
   540		hws[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_hw_gate4("gpu_core_root_clk", "gpu_core", base + 0x44f0, 0);
   541		hws[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
   542		hws[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
   543		hws[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
   544		hws[IMX8MN_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
   545		hws[IMX8MN_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
   546		hws[IMX8MN_CLK_GPU_BUS_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
   547		hws[IMX8MN_CLK_ASRC_ROOT] = imx_clk_hw_gate4("asrc_root_clk", "audio_ahb", base + 0x4580, 0);
   548		hws[IMX8MN_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
   549		hws[IMX8MN_CLK_PDM_IPG]  = imx_clk_hw_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
   550		hws[IMX8MN_CLK_DISP_AXI_ROOT]  = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
   551		hws[IMX8MN_CLK_DISP_APB_ROOT]  = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
   552		hws[IMX8MN_CLK_CAMERA_PIXEL_ROOT] = imx_clk_hw_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp);
   553		hws[IMX8MN_CLK_DISP_PIXEL_ROOT] = imx_clk_hw_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp);
   554		hws[IMX8MN_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
   555		hws[IMX8MN_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
   556		hws[IMX8MN_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
   557		hws[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
   558		hws[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
   559		hws[IMX8MN_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
   560		hws[IMX8MN_CLK_SAI7_IPG] = imx_clk_hw_gate2_shared2("sai7_ipg_clk", "ipg_audio_root", base + 0x4650, 0, &share_count_sai7);
   561	
   562		hws[IMX8MN_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc_24m", 1, 8);
   563	
   564		hws[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
   565	
   566		hws[IMX8MN_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core",
   567						   hws[IMX8MN_CLK_A53_CORE]->clk,
   568						   hws[IMX8MN_CLK_A53_CORE]->clk,
   569						   hws[IMX8MN_ARM_PLL_OUT]->clk,
   570						   hws[IMX8MN_CLK_A53_DIV]->clk);
   571	
   572		imx_check_clk_hws(hws, IMX8MN_CLK_END);
   573	
   574		ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
   575		if (ret < 0) {
   576			imx_unregister_hw_clocks(hws, IMX8MN_CLK_END);
   577			return dev_err_probe(dev, ret,
   578					     "failed to register hws for i.MX8MN\n");
   579		}
   580	
   581		imx_register_uart_clocks();
   582	
   583		dev_info(dev, "NXP i.MX8MN ccm clock driver probed\n");
   584		return 0;
   585	}
   586	

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


From rppt at kernel.org  Sun Dec  1 12:06:19 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Sun, 1 Dec 2024 22:06:19 +0200
Subject: [PATCH v2] arch_numa: Restore nid checks before registering a
 memblock with a node
In-Reply-To: <86zflftc87.wl-maz@kernel.org>
References: <20241201092702.3792845-1-maz@kernel.org>
 <Z0y5xsGgtJrSkyBe@kernel.org>
 <86zflftc87.wl-maz@kernel.org>
Message-ID: <Z0zBu1NhzRMfgIIt@kernel.org>

On Sun, Dec 01, 2024 at 07:49:44PM +0000, Marc Zyngier wrote:
> Hi Mike,
> 
> On Sun, 01 Dec 2024 19:32:22 +0000,
> Mike Rapoport <rppt at kernel.org> wrote:
> > 
> > Hi Marc,
> > 
> > On Sun, Dec 01, 2024 at 09:27:02AM +0000, Marc Zyngier wrote:
> > > Commit 767507654c22 ("arch_numa: switch over to numa_memblks")
> > > significantly cleaned up the NUMA registration code, but also
> > > dropped a significant check that was refusing to accept to
> > > configure a memblock with an invalid nid.
> > 
> > ... 
> >  
> > > while previous kernel versions were able to recognise how brain-damaged
> > > the machine is, and only build a fake node.
> > > 
> > > Use the memblock_validate_numa_coverage() helper to restore some sanity
> > > and a "working" system.
> > > 
> > > Fixes: 767507654c22 ("arch_numa: switch over to numa_memblks")
> > > Suggested-by: Mike Rapoport <rppt at kernel.org>
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > > Cc: Will Deacon <will at kernel.org>
> > > Cc: Zi Yan <ziy at nvidia.com>
> > > Cc: Dan Williams <dan.j.williams at intel.com>
> > > Cc: David Hildenbrand <david at redhat.com>
> > > Cc: Andrew Morton <akpm at linux-foundation.org>
> > > Cc: stable at vger.kernel.org
> > > ---
> > >  drivers/base/arch_numa.c | 4 ++++
> > >  1 file changed, 4 insertions(+)
> > > 
> > > diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
> > > index e187016764265..c63a72a1fed64 100644
> > > --- a/drivers/base/arch_numa.c
> > > +++ b/drivers/base/arch_numa.c
> > > @@ -208,6 +208,10 @@ static int __init numa_register_nodes(void)
> > >  {
> > >  	int nid;
> > >  
> > > +	/* Check the validity of the memblock/node mapping */
> > > +	if (!memblock_validate_numa_coverage(1))
> > 
> > I've changed this to memblock_validate_numa_coverage(0) and applied along
> > with my patch that changed memblock_validate_numa_coverage() to work with
> > 0:
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git/log/?h=thunderx-fix
> > 
> > Can you please verify that it works on your "quality hardware"?
> 
> Commit 427c6179e159b in your tree still has memblock_validate_numa_coverage(1).
> Forgot to push out the updated version?

Argh, indeed. 
 
> Flipping this to 0 locally, I have verified that this still allows the
> old thing to trudge along:
> 
> root at duodenum:~# uname -a
> Linux duodenum 6.12.0-12115-g427c6179e159-dirty #3896 SMP PREEMPT Sun Dec  1 19:43:13 GMT 2024 aarch64

Thanks for testing!
 
> Thanks again,
> 
> 	M.

-- 
Sincerely yours,
Mike.


From lkp at intel.com  Sun Dec  1 12:12:02 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 2 Dec 2024 04:12:02 +0800
Subject: [PATCH v4 02/18] clk: imx8mp: rename video_pll1 to video_pll
In-Reply-To: <20241201174639.742000-3-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-3-dario.binacchi@amarulasolutions.com>
Message-ID: <202412020312.z4UEdjd3-lkp@intel.com>

Hi Dario,

kernel test robot noticed the following build errors:

[auto build test ERROR on abelvesa/clk/imx]
[also build test ERROR on shawnguo/for-next clk/clk-next linus/master v6.12 next-20241128]
[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/Dario-Binacchi/clk-imx8mm-rename-video_pll1-to-video_pll/20241202-015316
base:   https://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git clk/imx
patch link:    https://lore.kernel.org/r/20241201174639.742000-3-dario.binacchi%40amarulasolutions.com
patch subject: [PATCH v4 02/18] clk: imx8mp: rename video_pll1 to video_pll
config: arm64-randconfig-002-20241202 (https://download.01.org/0day-ci/archive/20241202/202412020312.z4UEdjd3-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241202/202412020312.z4UEdjd3-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/202412020312.z4UEdjd3-lkp at intel.com/

All errors (new ones prefixed by >>):

   drivers/clk/imx/clk-imx8mp.c: In function 'imx8mp_clocks_probe':
>> drivers/clk/imx/clk-imx8mp.c:465:13: error: 'IMX8MP_VIDEO_PLL_BYPASS' undeclared (first use in this function); did you mean 'IMX8MP_VIDEO_PLL1_BYPASS'?
     465 |         hws[IMX8MP_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", anatop_base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
         |             ^~~~~~~~~~~~~~~~~~~~~~~
         |             IMX8MP_VIDEO_PLL1_BYPASS
   drivers/clk/imx/clk-imx8mp.c:465:13: note: each undeclared identifier is reported only once for each function it appears in


vim +465 drivers/clk/imx/clk-imx8mp.c

   407	
   408	static int imx8mp_clocks_probe(struct platform_device *pdev)
   409	{
   410		struct device *dev = &pdev->dev;
   411		struct device_node *np;
   412		void __iomem *anatop_base, *ccm_base;
   413		int err;
   414	
   415		np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop");
   416		anatop_base = devm_of_iomap(dev, np, 0, NULL);
   417		of_node_put(np);
   418		if (WARN_ON(IS_ERR(anatop_base)))
   419			return PTR_ERR(anatop_base);
   420	
   421		np = dev->of_node;
   422		ccm_base = devm_platform_ioremap_resource(pdev, 0);
   423		if (WARN_ON(IS_ERR(ccm_base)))
   424			return PTR_ERR(ccm_base);
   425	
   426		clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
   427		if (WARN_ON(!clk_hw_data))
   428			return -ENOMEM;
   429	
   430		clk_hw_data->num = IMX8MP_CLK_END;
   431		hws = clk_hw_data->hws;
   432	
   433		hws[IMX8MP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
   434		hws[IMX8MP_CLK_24M] = imx_get_clk_hw_by_name(np, "osc_24m");
   435		hws[IMX8MP_CLK_32K] = imx_get_clk_hw_by_name(np, "osc_32k");
   436		hws[IMX8MP_CLK_EXT1] = imx_get_clk_hw_by_name(np, "clk_ext1");
   437		hws[IMX8MP_CLK_EXT2] = imx_get_clk_hw_by_name(np, "clk_ext2");
   438		hws[IMX8MP_CLK_EXT3] = imx_get_clk_hw_by_name(np, "clk_ext3");
   439		hws[IMX8MP_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
   440	
   441		hws[IMX8MP_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", anatop_base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   442		hws[IMX8MP_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", anatop_base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   443		hws[IMX8MP_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   444		hws[IMX8MP_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", anatop_base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   445		hws[IMX8MP_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", anatop_base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   446		hws[IMX8MP_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", anatop_base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   447		hws[IMX8MP_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", anatop_base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   448		hws[IMX8MP_SYS_PLL1_REF_SEL] = imx_clk_hw_mux("sys_pll1_ref_sel", anatop_base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   449		hws[IMX8MP_SYS_PLL2_REF_SEL] = imx_clk_hw_mux("sys_pll2_ref_sel", anatop_base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   450		hws[IMX8MP_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", anatop_base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
   451	
   452		hws[IMX8MP_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", anatop_base, &imx_1443x_pll);
   453		hws[IMX8MP_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", anatop_base + 0x14, &imx_1443x_pll);
   454		hws[IMX8MP_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
   455		hws[IMX8MP_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", anatop_base + 0x50, &imx_1443x_dram_pll);
   456		hws[IMX8MP_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", anatop_base + 0x64, &imx_1416x_pll);
   457		hws[IMX8MP_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", anatop_base + 0x74, &imx_1416x_pll);
   458		hws[IMX8MP_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", anatop_base + 0x84, &imx_1416x_pll);
   459		hws[IMX8MP_SYS_PLL1] = imx_clk_hw_pll14xx("sys_pll1", "sys_pll1_ref_sel", anatop_base + 0x94, &imx_1416x_pll);
   460		hws[IMX8MP_SYS_PLL2] = imx_clk_hw_pll14xx("sys_pll2", "sys_pll2_ref_sel", anatop_base + 0x104, &imx_1416x_pll);
   461		hws[IMX8MP_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", anatop_base + 0x114, &imx_1416x_pll);
   462	
   463		hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
   464		hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
 > 465		hws[IMX8MP_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", anatop_base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
   466		hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
   467		hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
   468		hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
   469		hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
   470		hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
   471		hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
   472		hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
   473	
   474		hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
   475		hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
   476		hws[IMX8MP_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", anatop_base + 0x28, 13);
   477		hws[IMX8MP_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", anatop_base + 0x50, 13);
   478		hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
   479		hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
   480		hws[IMX8MP_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", anatop_base + 0x84, 11);
   481		hws[IMX8MP_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", anatop_base + 0x114, 11);
   482	
   483		hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
   484	
   485		hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
   486		hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
   487		hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
   488		hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
   489		hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
   490		hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
   491		hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
   492		hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
   493		hws[IMX8MP_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
   494	
   495		hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
   496	
   497		hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
   498		hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
   499		hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
   500		hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
   501		hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
   502		hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
   503		hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
   504		hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
   505		hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
   506	
   507		hws[IMX8MP_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", anatop_base + 0x128, 4, 4,
   508							      imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels));
   509		hws[IMX8MP_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", anatop_base + 0x128, 0, 4);
   510		hws[IMX8MP_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", anatop_base + 0x128, 8);
   511		hws[IMX8MP_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", anatop_base + 0x128, 20, 4,
   512							      imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels));
   513		hws[IMX8MP_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", anatop_base + 0x128, 16, 4);
   514		hws[IMX8MP_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", anatop_base + 0x128, 24);
   515	
   516		hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000);
   517		hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV];
   518		hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV];
   519		hws[IMX8MP_CLK_M7_CORE] = imx8m_clk_hw_composite_core("m7_core", imx8mp_m7_sels, ccm_base + 0x8080);
   520		hws[IMX8MP_CLK_ML_CORE] = imx8m_clk_hw_composite_core("ml_core", imx8mp_ml_sels, ccm_base + 0x8100);
   521		hws[IMX8MP_CLK_GPU3D_CORE] = imx8m_clk_hw_composite_core("gpu3d_core", imx8mp_gpu3d_core_sels, ccm_base + 0x8180);
   522		hws[IMX8MP_CLK_GPU3D_SHADER_CORE] = imx8m_clk_hw_composite("gpu3d_shader_core", imx8mp_gpu3d_shader_sels, ccm_base + 0x8200);
   523		hws[IMX8MP_CLK_GPU2D_CORE] = imx8m_clk_hw_composite("gpu2d_core", imx8mp_gpu2d_sels, ccm_base + 0x8280);
   524		hws[IMX8MP_CLK_AUDIO_AXI] = imx8m_clk_hw_composite("audio_axi", imx8mp_audio_axi_sels, ccm_base + 0x8300);
   525		hws[IMX8MP_CLK_AUDIO_AXI_SRC] = hws[IMX8MP_CLK_AUDIO_AXI];
   526		hws[IMX8MP_CLK_HSIO_AXI] = imx8m_clk_hw_composite("hsio_axi", imx8mp_hsio_axi_sels, ccm_base + 0x8380);
   527		hws[IMX8MP_CLK_MEDIA_ISP] = imx8m_clk_hw_composite("media_isp", imx8mp_media_isp_sels, ccm_base + 0x8400);
   528	
   529		/* CORE SEL */
   530		hws[IMX8MP_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", ccm_base + 0x9880, 24, 1, imx8mp_a53_core_sels, ARRAY_SIZE(imx8mp_a53_core_sels));
   531	
   532		hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_bus_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800);
   533		hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
   534		hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900);
   535		hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
   536		hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite_bus("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
   537		hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite_bus("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
   538		hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite_bus("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
   539		hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite_bus("hdmi_axi", imx8mp_media_axi_sels, ccm_base + 0x8b80);
   540		hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
   541		hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
   542		hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_bus_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00);
   543		hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_bus_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80);
   544		hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite_bus("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
   545		hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite_bus("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
   546	
   547		hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
   548		hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
   549		hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
   550		hws[IMX8MP_CLK_MEDIA_DISP2_PIX] = imx8m_clk_hw_composite_bus_flags("media_disp2_pix", imx8mp_media_disp_pix_sels, ccm_base + 0x9300, CLK_SET_RATE_PARENT);
   551	
   552		hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
   553	
   554		hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
   555		hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
   556		hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100);
   557		hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
   558		hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);
   559		hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, ccm_base + 0xa280);
   560		hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", imx8mp_pcie_aux_sels, ccm_base + 0xa400);
   561		hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, ccm_base + 0xa480);
   562		hws[IMX8MP_CLK_I2C6] = imx8m_clk_hw_composite("i2c6", imx8mp_i2c6_sels, ccm_base + 0xa500);
   563		hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580);
   564		hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600);
   565		hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680);
   566		hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780);
   567		hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800);
   568		hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880);
   569		hws[IMX8MP_CLK_ENET_QOS_TIMER] = imx8m_clk_hw_composite("enet_qos_timer", imx8mp_enet_qos_timer_sels, ccm_base + 0xa900);
   570		hws[IMX8MP_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mp_enet_ref_sels, ccm_base + 0xa980);
   571		hws[IMX8MP_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mp_enet_timer_sels, ccm_base + 0xaa00);
   572		hws[IMX8MP_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy_ref", imx8mp_enet_phy_ref_sels, ccm_base + 0xaa80);
   573		hws[IMX8MP_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mp_nand_sels, ccm_base + 0xab00);
   574		hws[IMX8MP_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mp_qspi_sels, ccm_base + 0xab80);
   575		hws[IMX8MP_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mp_usdhc1_sels, ccm_base + 0xac00);
   576		hws[IMX8MP_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mp_usdhc2_sels, ccm_base + 0xac80);
   577		hws[IMX8MP_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mp_i2c1_sels, ccm_base + 0xad00);
   578		hws[IMX8MP_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mp_i2c2_sels, ccm_base + 0xad80);
   579		hws[IMX8MP_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mp_i2c3_sels, ccm_base + 0xae00);
   580		hws[IMX8MP_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mp_i2c4_sels, ccm_base + 0xae80);
   581	
   582		hws[IMX8MP_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mp_uart1_sels, ccm_base + 0xaf00);
   583		hws[IMX8MP_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mp_uart2_sels, ccm_base + 0xaf80);
   584		hws[IMX8MP_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mp_uart3_sels, ccm_base + 0xb000);
   585		hws[IMX8MP_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mp_uart4_sels, ccm_base + 0xb080);
   586		hws[IMX8MP_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mp_usb_core_ref_sels, ccm_base + 0xb100);
   587		hws[IMX8MP_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mp_usb_phy_ref_sels, ccm_base + 0xb180);
   588		hws[IMX8MP_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mp_gic_sels, ccm_base + 0xb200);
   589		hws[IMX8MP_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mp_ecspi1_sels, ccm_base + 0xb280);
   590		hws[IMX8MP_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mp_ecspi2_sels, ccm_base + 0xb300);
   591		hws[IMX8MP_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mp_pwm1_sels, ccm_base + 0xb380);
   592		hws[IMX8MP_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mp_pwm2_sels, ccm_base + 0xb400);
   593		hws[IMX8MP_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mp_pwm3_sels, ccm_base + 0xb480);
   594		hws[IMX8MP_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mp_pwm4_sels, ccm_base + 0xb500);
   595	
   596		hws[IMX8MP_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mp_gpt1_sels, ccm_base + 0xb580);
   597		hws[IMX8MP_CLK_GPT2] = imx8m_clk_hw_composite("gpt2", imx8mp_gpt2_sels, ccm_base + 0xb600);
   598		hws[IMX8MP_CLK_GPT3] = imx8m_clk_hw_composite("gpt3", imx8mp_gpt3_sels, ccm_base + 0xb680);
   599		hws[IMX8MP_CLK_GPT4] = imx8m_clk_hw_composite("gpt4", imx8mp_gpt4_sels, ccm_base + 0xb700);
   600		hws[IMX8MP_CLK_GPT5] = imx8m_clk_hw_composite("gpt5", imx8mp_gpt5_sels, ccm_base + 0xb780);
   601		hws[IMX8MP_CLK_GPT6] = imx8m_clk_hw_composite("gpt6", imx8mp_gpt6_sels, ccm_base + 0xb800);
   602		hws[IMX8MP_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mp_wdog_sels, ccm_base + 0xb900);
   603		hws[IMX8MP_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mp_wrclk_sels, ccm_base + 0xb980);
   604		hws[IMX8MP_CLK_IPP_DO_CLKO1] = imx8m_clk_hw_composite("ipp_do_clko1", imx8mp_ipp_do_clko1_sels, ccm_base + 0xba00);
   605		hws[IMX8MP_CLK_IPP_DO_CLKO2] = imx8m_clk_hw_composite("ipp_do_clko2", imx8mp_ipp_do_clko2_sels, ccm_base + 0xba80);
   606		hws[IMX8MP_CLK_HDMI_FDCC_TST] = imx8m_clk_hw_composite("hdmi_fdcc_tst", imx8mp_hdmi_fdcc_tst_sels, ccm_base + 0xbb00);
   607		hws[IMX8MP_CLK_HDMI_24M] = imx8m_clk_hw_composite("hdmi_24m", imx8mp_hdmi_24m_sels, ccm_base + 0xbb80);
   608		hws[IMX8MP_CLK_HDMI_REF_266M] = imx8m_clk_hw_composite("hdmi_ref_266m", imx8mp_hdmi_ref_266m_sels, ccm_base + 0xbc00);
   609		hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80);
   610		hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00);
   611		hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
   612		hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite_bus_flags("media_disp1_pix", imx8mp_media_disp_pix_sels, ccm_base + 0xbe00, CLK_SET_RATE_PARENT);
   613		hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
   614		hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00);
   615		hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80);
   616		hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = imx8m_clk_hw_composite("media_mipi_test_byte", imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100);
   617		hws[IMX8MP_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mp_ecspi3_sels, ccm_base + 0xc180);
   618		hws[IMX8MP_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mp_pdm_sels, ccm_base + 0xc200);
   619		hws[IMX8MP_CLK_VPU_VC8000E] = imx8m_clk_hw_composite("vpu_vc8000e", imx8mp_vpu_vc8000e_sels, ccm_base + 0xc280);
   620		hws[IMX8MP_CLK_SAI7] = imx8m_clk_hw_composite("sai7", imx8mp_sai7_sels, ccm_base + 0xc300);
   621	
   622		hws[IMX8MP_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
   623		hws[IMX8MP_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", ccm_base + 0x9800, 24, 1, imx8mp_dram_core_sels, ARRAY_SIZE(imx8mp_dram_core_sels), CLK_IS_CRITICAL);
   624	
   625		hws[IMX8MP_CLK_DRAM1_ROOT] = imx_clk_hw_gate4_flags("dram1_root_clk", "dram_core_clk", ccm_base + 0x4050, 0, CLK_IS_CRITICAL);
   626		hws[IMX8MP_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", ccm_base + 0x4070, 0);
   627		hws[IMX8MP_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", ccm_base + 0x4080, 0);
   628		hws[IMX8MP_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", ccm_base + 0x4090, 0);
   629		hws[IMX8MP_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", ccm_base + 0x40a0, 0);
   630		hws[IMX8MP_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", ccm_base + 0x40b0, 0);
   631		hws[IMX8MP_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", ccm_base + 0x40c0, 0);
   632		hws[IMX8MP_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", ccm_base + 0x40d0, 0);
   633		hws[IMX8MP_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", ccm_base + 0x40e0, 0);
   634		hws[IMX8MP_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", ccm_base + 0x40f0, 0);
   635		hws[IMX8MP_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", ccm_base + 0x4100, 0);
   636		hws[IMX8MP_CLK_GPT2_ROOT] = imx_clk_hw_gate4("gpt2_root_clk", "gpt2", ccm_base + 0x4110, 0);
   637		hws[IMX8MP_CLK_GPT3_ROOT] = imx_clk_hw_gate4("gpt3_root_clk", "gpt3", ccm_base + 0x4120, 0);
   638		hws[IMX8MP_CLK_GPT4_ROOT] = imx_clk_hw_gate4("gpt4_root_clk", "gpt4", ccm_base + 0x4130, 0);
   639		hws[IMX8MP_CLK_GPT5_ROOT] = imx_clk_hw_gate4("gpt5_root_clk", "gpt5", ccm_base + 0x4140, 0);
   640		hws[IMX8MP_CLK_GPT6_ROOT] = imx_clk_hw_gate4("gpt6_root_clk", "gpt6", ccm_base + 0x4150, 0);
   641		hws[IMX8MP_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", ccm_base + 0x4170, 0);
   642		hws[IMX8MP_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", ccm_base + 0x4180, 0);
   643		hws[IMX8MP_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", ccm_base + 0x4190, 0);
   644		hws[IMX8MP_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", ccm_base + 0x41a0, 0);
   645		hws[IMX8MP_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", ccm_base + 0x4210, 0);
   646		hws[IMX8MP_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", ccm_base + 0x4220, 0);
   647		hws[IMX8MP_CLK_PCIE_ROOT] = imx_clk_hw_gate4("pcie_root_clk", "pcie_aux", ccm_base + 0x4250, 0);
   648		hws[IMX8MP_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", ccm_base + 0x4280, 0);
   649		hws[IMX8MP_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", ccm_base + 0x4290, 0);
   650		hws[IMX8MP_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", ccm_base + 0x42a0, 0);
   651		hws[IMX8MP_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", ccm_base + 0x42b0, 0);
   652		hws[IMX8MP_CLK_QOS_ROOT] = imx_clk_hw_gate4("qos_root_clk", "ipg_root", ccm_base + 0x42c0, 0);
   653		hws[IMX8MP_CLK_QOS_ENET_ROOT] = imx_clk_hw_gate4("qos_enet_root_clk", "ipg_root", ccm_base + 0x42e0, 0);
   654		hws[IMX8MP_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", ccm_base + 0x42f0, 0);
   655		hws[IMX8MP_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", ccm_base + 0x4300, 0, &share_count_nand);
   656		hws[IMX8MP_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", ccm_base + 0x4300, 0, &share_count_nand);
   657		hws[IMX8MP_CLK_I2C5_ROOT] = imx_clk_hw_gate2("i2c5_root_clk", "i2c5", ccm_base + 0x4330, 0);
   658		hws[IMX8MP_CLK_I2C6_ROOT] = imx_clk_hw_gate2("i2c6_root_clk", "i2c6", ccm_base + 0x4340, 0);
   659		hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0);
   660		hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0);
   661		hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
   662		hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
   663		hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
   664		hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
   665		hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
   666		hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
   667		hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
   668		hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0);
   669		hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0);
   670		hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate2_shared2("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0, &share_count_usb);
   671		hws[IMX8MP_CLK_USB_SUSP] = imx_clk_hw_gate2_shared2("usb_suspend_clk", "osc_32k", ccm_base + 0x44d0, 0, &share_count_usb);
   672		hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0);
   673		hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0);
   674		hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);
   675		hws[IMX8MP_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", ccm_base + 0x4530, 0);
   676		hws[IMX8MP_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", ccm_base + 0x4540, 0);
   677		hws[IMX8MP_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", ccm_base + 0x4550, 0);
   678		hws[IMX8MP_CLK_VPU_G1_ROOT] = imx_clk_hw_gate4("vpu_g1_root_clk", "vpu_g1", ccm_base + 0x4560, 0);
   679		hws[IMX8MP_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", ccm_base + 0x4570, 0);
   680		hws[IMX8MP_CLK_VPU_VC8KE_ROOT] = imx_clk_hw_gate4("vpu_vc8ke_root_clk", "vpu_vc8000e", ccm_base + 0x4590, 0);
   681		hws[IMX8MP_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", ccm_base + 0x45a0, 0);
   682		hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_core", ccm_base + 0x45b0, 0);
   683		hws[IMX8MP_CLK_HSIO_ROOT] = imx_clk_hw_gate4("hsio_root_clk", "ipg_root", ccm_base + 0x45c0, 0);
   684		hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0, &share_count_media);
   685		hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0, &share_count_media);
   686		hws[IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam1_pix_root_clk", "media_cam1_pix", ccm_base + 0x45d0, 0, &share_count_media);
   687		hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media);
   688		hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media);
   689		hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media);
   690		hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT] = imx_clk_hw_gate2_shared2("media_mipi_phy1_ref_root", "media_mipi_phy1_ref", ccm_base + 0x45d0, 0, &share_count_media);
   691		hws[IMX8MP_CLK_MEDIA_LDB_ROOT] = imx_clk_hw_gate2_shared2("media_ldb_root_clk", "media_ldb", ccm_base + 0x45d0, 0, &share_count_media);
   692		hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp", ccm_base + 0x45d0, 0, &share_count_media);
   693	
   694		hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0);
   695		hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0);
   696		hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", "ipg_root", ccm_base + 0x4620, 0);
   697		hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", ccm_base + 0x4630, 0);
   698	
   699		hws[IMX8MP_CLK_AUDIO_AHB_ROOT] = imx_clk_hw_gate2_shared2("audio_ahb_root", "audio_ahb", ccm_base + 0x4650, 0, &share_count_audio);
   700		hws[IMX8MP_CLK_AUDIO_AXI_ROOT] = imx_clk_hw_gate2_shared2("audio_axi_root", "audio_axi", ccm_base + 0x4650, 0, &share_count_audio);
   701		hws[IMX8MP_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root", "sai1", ccm_base + 0x4650, 0, &share_count_audio);
   702		hws[IMX8MP_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root", "sai2", ccm_base + 0x4650, 0, &share_count_audio);
   703		hws[IMX8MP_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root", "sai3", ccm_base + 0x4650, 0, &share_count_audio);
   704		hws[IMX8MP_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root", "sai5", ccm_base + 0x4650, 0, &share_count_audio);
   705		hws[IMX8MP_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root", "sai6", ccm_base + 0x4650, 0, &share_count_audio);
   706		hws[IMX8MP_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root", "sai7", ccm_base + 0x4650, 0, &share_count_audio);
   707		hws[IMX8MP_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root", "pdm", ccm_base + 0x4650, 0, &share_count_audio);
   708	
   709		hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core",
   710						     hws[IMX8MP_CLK_A53_CORE]->clk,
   711						     hws[IMX8MP_CLK_A53_CORE]->clk,
   712						     hws[IMX8MP_ARM_PLL_OUT]->clk,
   713						     hws[IMX8MP_CLK_A53_DIV]->clk);
   714	
   715		imx_check_clk_hws(hws, IMX8MP_CLK_END);
   716	
   717		err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
   718		if (err < 0) {
   719			dev_err(dev, "failed to register hws for i.MX8MP\n");
   720			imx_unregister_hw_clocks(hws, IMX8MP_CLK_END);
   721			return err;
   722		}
   723	
   724		imx_register_uart_clocks();
   725	
   726		return 0;
   727	}
   728	

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


From sebastian.reichel at collabora.com  Sun Dec  1 14:59:43 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Sun, 1 Dec 2024 23:59:43 +0100
Subject: [PATCH v1 04/10] phy: phy-rockchip-samsung-hdptx: Add support
 for eDP mode
In-Reply-To: <2886747.Y6S9NjorxK@diego>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <2131853.KlZ2vcFHjT@diego>
 <6e1f35c0-5ea8-414f-b3ea-4e7222c605ef@rock-chips.com>
 <2886747.Y6S9NjorxK@diego>
Message-ID: <h4giob7bcrh7qmtepti6huym2llw4ujfmeff76vrgpahb5zy6x@dz6zghsifww5>

Hi,

On Sat, Nov 30, 2024 at 09:25:12PM +0100, Heiko St?bner wrote:
> Am Freitag, 29. November 2024, 03:43:57 CET schrieb Damon Ding:
> > On 2024/11/27 19:04, Heiko St?bner wrote:
> > > Am Mittwoch, 27. November 2024, 12:00:10 CET schrieb Damon Ding:
> > >> On 2024/11/27 17:29, Heiko St?bner wrote:
> > >>> Am Mittwoch, 27. November 2024, 08:51:51 CET schrieb Damon Ding:
> > >>>> +static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode,
> > >>>> +				 int submode)
> > >>>> +{
> > >>>> +	return 0;
> > >>>> +}
> > >>>analogix_dp_phy_power_on
> > >>> I think it might make sense to go the same way as the DCPHY and also
> > >>> naneng combophy, to use #phy-cells = 1 to select the phy-mode via DT .
> > >>>
> > >>> See [0] for Sebastians initial suggestion regarding the DC-PHY.
> > >>> The naneng combophy already uses that scheme of mode-selection too.
> > >>>
> > >>> There is of course the issue of backwards-compatibility, but that can be
> > >>> worked around in the binding with something like:
> > >>>
> > >>>    '#phy-cells':
> > >>>       enum: [0, 1]
> > >>>       description: |
> > >>>         If #phy-cells is 0, PHY mode is set to PHY_TYPE_HDMI
> > >>>         If #phy-cells is 1 mode is set in the PHY cells. Supported modes are:
> > >>>           - PHY_TYPE_HDMI
> > >>>           - PHY_TYPE_DP
> > >>>         See include/dt-bindings/phy/phy.h for constants.
> > >>>
> > >>> PHY_TYPE_HDMI needs to be added to include/dt-bindings/phy/phy.h
> > >>> but PHY_TYPE_DP is already there.
> > >>>
> > >>> That way we would standardize on one form of accessing phy-types
> > >>> on rk3588 :-) .
> > >>>
> > >>> Also see the Mediatek CSI rx phy doing this too already [1]
> > >>>
> > >>>
> > >>> Heiko
> > >>>
> > >>> [0] https://lore.kernel.org/linux-rockchip/udad4qf3o7kt45nuz6gxsvsmprh4rnyfxfogopmih6ucznizih at 7oj2jrnlfonz/
> > >>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/phy/mediatek,mt8365-csi-rx.yaml
> > >>>
> > >>
> > >> It is really a nice way to separate HDMI and DP modes.
> > 
> > I apologize for reopening the discussion about the phy-types setting.
> 
> there is definitly no need to apologize. We're trying to find the best
> solution afterall :-) .
> 
> > With the .set_mode() of struct phy_ops, the HDMI and eDP dynamic 
> > switching can be achieved, which just depends on the right setting of
> > enum phy_mode in include/linux/phy/phy.h. So the previous way of 
> > configuring phy mode may be also good.
> 
> I think the deciding factor is, is there a use-case for needing to switch
> modes at runtime.
> 
> I do think the mode for the dc-phy and also the hdptx-phy is pretty much
> decided by the board design.
> 
> I.e. when you end up in a DP-connector (or eDP-panel) on your board you
> need DP mode, and when you end up in a hdmi-connector you need the
> HDMI phy mode.
> 
> So I think the phy-mode for the hdptx-phy is largely dictated by the static
> board definition (like devicetree), hence going with the dt-argument for
> the mode.
> 
> Like similar to the Naneng combophy, selecting its mode via argument
> because deciding if it ends up in a sata port is a board-design thing.
>
> Is there a use-case where you need to switch at runtime between
> HDMI and eDP? Like starting the phy in eDP mode but then needing
> to switch to HDMI mode, while the device is running?

I believe the eDP controller can only use the PHY in eDP mode and
the HDMI controller can only use it in HDMI mode. So in order to
support runtime switching, the following options are possible:

1. Enable both controllers, the PHY decides which one is really
   used, the other one is basically a non-functional dummy device
   until the PHY is reconfigured. This requires the set_mode()
   callback, since the HDMI and eDP drivers both expect their
   PHY to be enabled.

2. Properly enable / disable the used controller, so that only one
   controller is active at the same time. In this case the switching
   is handled one layer above and the PHY has nothing to do with it.
   The phy_enable call from each controller would just set it up in
   the right mode.

I guess option 1 is the hacked solution, which is easier to
implement as DRM's hotplug abilities are quite limited at the moment
as far as I know. I think the second solution looks much cleaner and
should be prefered for upstream. That solution does not require
calling set_mode() for runtime switching making this whole argument
void :)

FWIW I think the DT argument based mode setting and the runtime set_mode
are not necessarily mutual exclusive. In theory one could support both
and adding set_mode support later does not change any ABI as far as
I can see. Basically handle it like pin mux/configuration settings,
which are usually automatically handled by the device core based on
DT information, except for some drivers which have special needs.

> > And other phys may want to support dynamic switching too, like the 
> > Rockchip USBDP combo phy.
> 
> I guess USBDP is special in that in also does both modes dynamical
> depending on its use (like type-c with option DP altmode)

The USBDP PHY is indeed quite different from the PHYs in your list
above, but for a different reason: All the combined PHYs you listed
above only support one mode at the same time. E.g. you need to
decide between PCIe, SATA and USB3 mode for the Naneng combophy.

For the USBDP PHY the modes are not mutually exclusive. The USB
controller can request the USBDP PHY in USB mode at the same time
as the DP controller requests it in DP mode. Some additional
registers configure how the lanes are being muxed. A typcial setup
would be 2 lanes for USB3 and 2 lanes for DP.

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/20241201/1fa7dfce/attachment.sig>

From pbrobinson at gmail.com  Sun Dec  1 15:46:05 2024
From: pbrobinson at gmail.com (Peter Robinson)
Date: Sun,  1 Dec 2024 23:46:05 +0000
Subject: [PATCH] arm64: dts: rockchip: enable rng on all rk356x
In-Reply-To: <a>
References: <a>
Message-ID: <20241201234613.52322-1-pbrobinson@gmail.com>

The rk356x rng is available on both the rk3566 and rk3568
parts, the IP is all self contained within the SoCs so
it's enabled already by default on rk3568 so let's enable
it in the base rk356x.dtsi so it's enabled consistently
everywhere.

Signed-off-by: Peter Robinson <pbrobinson at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3568.dtsi      | 4 ----
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 1 -
 2 files changed, 5 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index ecaefe208e3e..9dc09db5034d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -397,10 +397,6 @@ power-domain at RK3568_PD_PIPE {
 	};
 };
 
-&rng {
-	status = "okay";
-};
-
 &usb_host0_xhci {
 	phys = <&usb2phy0_otg>, <&combphy0 PHY_TYPE_USB3>;
 	phy-names = "usb2-phy", "usb3-phy";
diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
index 62be06f3b863..2994cddb3464 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -1038,7 +1038,6 @@ rng: rng at fe388000 {
 		clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>;
 		clock-names = "core", "ahb";
 		resets = <&cru SRST_TRNG_NS>;
-		status = "disabled";
 	};
 
 	i2s0_8ch: i2s at fe400000 {
-- 
2.47.1



From wahrenst at gmx.net  Sun Dec  1 16:16:29 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon,  2 Dec 2024 01:16:29 +0100
Subject: [PATCH 1/3] usb: dwc2: Fix HCD resume
In-Reply-To: <20241202001631.75473-1-wahrenst@gmx.net>
References: <20241202001631.75473-1-wahrenst@gmx.net>
Message-ID: <20241202001631.75473-2-wahrenst@gmx.net>

The Raspberry Pi can suffer on interrupt storms on HCD resume. The dwc2
driver sometimes misses to enable HCD_FLAG_HW_ACCESSIBLE before re-enabling
the interrupts. This causes a situation where both handler ignore a incoming
port interrupt and force the upper layers to disable the dwc2 interrupt
line. This leaves the USB interface in a unusable state:

irq 66: nobody cared (try booting with the "irqpoll" option)
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W          6.10.0-rc3
Hardware name: BCM2835
Call trace:
unwind_backtrace from show_stack+0x10/0x14
show_stack from dump_stack_lvl+0x50/0x64
dump_stack_lvl from __report_bad_irq+0x38/0xc0
__report_bad_irq from note_interrupt+0x2ac/0x2f4
note_interrupt from handle_irq_event+0x88/0x8c
handle_irq_event from handle_level_irq+0xb4/0x1ac
handle_level_irq from generic_handle_domain_irq+0x24/0x34
generic_handle_domain_irq from bcm2836_chained_handle_irq+0x24/0x28
bcm2836_chained_handle_irq from generic_handle_domain_irq+0x24/0x34
generic_handle_domain_irq from generic_handle_arch_irq+0x34/0x44
generic_handle_arch_irq from __irq_svc+0x88/0xb0
Exception stack(0xc1b01f20 to 0xc1b01f68)
1f20: 0005c0d4 00000001 00000000 00000000 c1b09780 c1d6b32c c1b04e54 c1a5eae8
1f40: c1b04e90 00000000 00000000 00000000 c1d6a8a0 c1b01f70 c11d2da8 c11d4160
1f60: 60000013 ffffffff
__irq_svc from default_idle_call+0x1c/0xb0
default_idle_call from do_idle+0x21c/0x284
do_idle from cpu_startup_entry+0x28/0x2c
cpu_startup_entry from kernel_init+0x0/0x12c
handlers:
[<f539e0f4>] dwc2_handle_common_intr
[<75cd278b>] usb_hcd_irq
Disabling IRQ #66

So enable the HCD_FLAG_HW_ACCESSIBLE flag in case there is a port
connection.

Fixes: c74c26f6e398 ("usb: dwc2: Fix partial power down exiting by system resume")
Closes: https://lore.kernel.org/linux-usb/3fd0c2fb-4752-45b3-94eb-42352703e1fd at gmx.net/T/
Link: https://lore.kernel.org/all/5e8cbce0-3260-2971-484f-fc73a3b2bd28 at synopsys.com/
Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/usb/dwc2/hcd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index cb54390e7de4..26a320c1979a 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4431,6 +4431,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 	 * Power Down mode.
 	 */
 	if (hprt0 & HPRT0_CONNSTS) {
+		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 		hsotg->lx_state = DWC2_L0;
 		goto unlock;
 	}
--
2.34.1



From wahrenst at gmx.net  Sun Dec  1 16:16:28 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon,  2 Dec 2024 01:16:28 +0100
Subject: [PATCH 0/3] usb: dwc2: Fix HCD issues on Raspberry Pi
Message-ID: <20241202001631.75473-1-wahrenst@gmx.net>

This series address some serious HCD issues on the Raspberry Pi.

Stefan Wahren (3):
  usb: dwc2: Fix HCD resume
  usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature
  usb: dwc2: Fix HCD port connection race

 drivers/usb/dwc2/hcd.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

--
2.34.1



From wahrenst at gmx.net  Sun Dec  1 16:16:31 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon,  2 Dec 2024 01:16:31 +0100
Subject: [PATCH 3/3] usb: dwc2: Fix HCD port connection race
In-Reply-To: <20241202001631.75473-1-wahrenst@gmx.net>
References: <20241202001631.75473-1-wahrenst@gmx.net>
Message-ID: <20241202001631.75473-4-wahrenst@gmx.net>

On Raspberry Pis without onboard USB hub frequent device reconnects
can trigger a interrupt storm after DWC2 entered host clock gating.
This is caused by a race between _dwc2_hcd_suspend() and the port
interrupt, which sets port_connect_status. The issue occurs if
port_connect_status is still 1, but there is no connection anymore:

usb 1-1: USB disconnect, device number 25
dwc2 3f980000.usb: _dwc2_hcd_suspend: port_connect_status: 1
dwc2 3f980000.usb: Entering host clock gating.
Disabling IRQ #66
irq 66: nobody cared (try booting with the "irqpoll" option)
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.0-gc1bb81b13202-dirty #322
Hardware name: BCM2835
Call trace:
 unwind_backtrace from show_stack+0x10/0x14
 show_stack from dump_stack_lvl+0x50/0x64
 dump_stack_lvl from __report_bad_irq+0x38/0xc0
 __report_bad_irq from note_interrupt+0x2ac/0x2f4
 note_interrupt from handle_irq_event+0x88/0x8c
 handle_irq_event from handle_level_irq+0xb4/0x1ac
 handle_level_irq from generic_handle_domain_irq+0x24/0x34
 generic_handle_domain_irq from bcm2836_chained_handle_irq+0x24/0x28
 bcm2836_chained_handle_irq from generic_handle_domain_irq+0x24/0x34
 generic_handle_domain_irq from generic_handle_arch_irq+0x34/0x44
 generic_handle_arch_irq from __irq_svc+0x88/0xb0
 Exception stack(0xc1d01f20 to 0xc1d01f68)
 1f20: 0004ef3c 00000001 00000000 00000000 c1d09780 c1f6bb5c c1d04e54 c1c60ca8
 1f40: c1d04e94 00000000 00000000 c1d092a8 c1f6af20 c1d01f70 c1211b98 c1212f40
 1f60: 60000013 ffffffff
 __irq_svc from default_idle_call+0x1c/0xb0
 default_idle_call from do_idle+0x21c/0x284
 do_idle from cpu_startup_entry+0x28/0x2c
 cpu_startup_entry from kernel_init+0x0/0x12c
handlers:
 [<e3a25c00>] dwc2_handle_common_intr
 [<58bf98a3>] usb_hcd_irq
Disabling IRQ #66

So avoid this by reading the connection status directly.

Fixes: 113f86d0c302 ("usb: dwc2: Update partial power down entering by system suspend")
Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/usb/dwc2/hcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index fb4fbd8c43df..8c3941ecaaf5 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4345,7 +4345,7 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 	if (hsotg->bus_suspended)
 		goto skip_power_saving;

-	if (hsotg->flags.b.port_connect_status == 0)
+	if (!(dwc2_read_hprt0(hsotg) & HPRT0_CONNSTS))
 		goto skip_power_saving;

 	switch (hsotg->params.power_down) {
--
2.34.1



From wahrenst at gmx.net  Sun Dec  1 16:16:30 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon,  2 Dec 2024 01:16:30 +0100
Subject: [PATCH 2/3] usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature
In-Reply-To: <20241202001631.75473-1-wahrenst@gmx.net>
References: <20241202001631.75473-1-wahrenst@gmx.net>
Message-ID: <20241202001631.75473-3-wahrenst@gmx.net>

On Rasperry Pis without onboard USB hub the power cycle during
power connect init only disable the port but never enabled it again:

  usb usb1-port1: attempt power cycle

The port relevant part in dwc2_hcd_hub_control() is skipped in case
port_connect_status = 0 under the assumption the core is or will be soon
in device mode. But this assumption is wrong, because after ClearPortFeature
USB_PORT_FEAT_POWER the port_connect_status will also be 0 and
SetPortFeature (incl. USB_PORT_FEAT_POWER) will be a no-op.

Fix the behavior of dwc2_hcd_hub_control() by replacing the
port_connect_status check with dwc2_is_device_mode().

Link: https://github.com/raspberrypi/linux/issues/6247
Fixes: 7359d482eb4d ("staging: HCD files for the DWC2 driver")
Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/usb/dwc2/hcd.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 26a320c1979a..fb4fbd8c43df 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3546,11 +3546,9 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			port_status |= USB_PORT_STAT_C_OVERCURRENT << 16;
 		}

-		if (!hsotg->flags.b.port_connect_status) {
+		if (dwc2_is_device_mode(hsotg)) {
 			/*
-			 * The port is disconnected, which means the core is
-			 * either in device mode or it soon will be. Just
-			 * return 0's for the remainder of the port status
+			 * Just return 0's for the remainder of the port status
 			 * since the port register can't be read if the core
 			 * is in device mode.
 			 */
@@ -3620,13 +3618,11 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 		if (wvalue != USB_PORT_FEAT_TEST && (!windex || windex > 1))
 			goto error;

-		if (!hsotg->flags.b.port_connect_status) {
+		if (dwc2_is_device_mode(hsotg)) {
 			/*
-			 * The port is disconnected, which means the core is
-			 * either in device mode or it soon will be. Just
-			 * return without doing anything since the port
-			 * register can't be written if the core is in device
-			 * mode.
+			 * Just return 0's for the remainder of the port status
+			 * since the port register can't be read if the core
+			 * is in device mode.
 			 */
 			break;
 		}
--
2.34.1



From ebiggers at kernel.org  Sun Dec  1 17:08:29 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:29 -0800
Subject: [PATCH v4 04/19] crypto: crc32 - don't unnecessarily register arch algorithms
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-5-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Instead of registering the crc32-$arch and crc32c-$arch algorithms if
the arch-specific code was built, only register them when that code was
built *and* is not falling back to the base implementation at runtime.

This avoids confusing users like btrfs which checks the shash driver
name to determine whether it is crc32c-generic.

(It would also make sense to change btrfs to test the crc32_optimization
flags itself, so that it doesn't have to use the weird hack of parsing
the driver name.  This change still makes sense either way though.)

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 crypto/crc32_generic.c  | 8 ++++++--
 crypto/crc32c_generic.c | 8 ++++++--
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/crypto/crc32_generic.c b/crypto/crc32_generic.c
index cc064ea8240e..783a30b27398 100644
--- a/crypto/crc32_generic.c
+++ b/crypto/crc32_generic.c
@@ -155,19 +155,23 @@ static struct shash_alg algs[] = {{
 	.base.cra_ctxsize	= sizeof(u32),
 	.base.cra_module	= THIS_MODULE,
 	.base.cra_init		= crc32_cra_init,
 }};
 
+static int num_algs;
+
 static int __init crc32_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
+	num_algs = 1 + ((crc32_optimizations() & CRC32_LE_OPTIMIZATION) != 0);
+
+	return crypto_register_shashes(algs, num_algs);
 }
 
 static void __exit crc32_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
+	crypto_unregister_shashes(algs, num_algs);
 }
 
 subsys_initcall(crc32_mod_init);
 module_exit(crc32_mod_fini);
 
diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c
index 04b03d825cf4..985da981d6e2 100644
--- a/crypto/crc32c_generic.c
+++ b/crypto/crc32c_generic.c
@@ -195,19 +195,23 @@ static struct shash_alg algs[] = {{
 	.base.cra_ctxsize	= sizeof(struct chksum_ctx),
 	.base.cra_module	= THIS_MODULE,
 	.base.cra_init		= crc32c_cra_init,
 }};
 
+static int num_algs;
+
 static int __init crc32c_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
+	num_algs = 1 + ((crc32_optimizations() & CRC32C_OPTIMIZATION) != 0);
+
+	return crypto_register_shashes(algs, num_algs);
 }
 
 static void __exit crc32c_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
+	crypto_unregister_shashes(algs, num_algs);
 }
 
 subsys_initcall(crc32c_mod_init);
 module_exit(crc32c_mod_fini);
 
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:30 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:30 -0800
Subject: [PATCH v4 05/19] arm/crc32: expose CRC32 functions through lib
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-6-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the arm CRC32 assembly code into the lib directory and wire it up
to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/arm/crypto/crc32-ce-glue.c to
arch/arm/lib/crc32-glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm/Kconfig                              |   1 +
 arch/arm/configs/milbeaut_m10v_defconfig      |   1 -
 arch/arm/configs/multi_v7_defconfig           |   1 -
 arch/arm/crypto/Kconfig                       |  14 -
 arch/arm/crypto/Makefile                      |   2 -
 arch/arm/crypto/crc32-ce-glue.c               | 247 ------------------
 arch/arm/lib/Makefile                         |   3 +
 .../crc32-ce-core.S => lib/crc32-core.S}      |   5 +-
 arch/arm/lib/crc32-glue.c                     | 123 +++++++++
 9 files changed, 129 insertions(+), 268 deletions(-)
 delete mode 100644 arch/arm/crypto/crc32-ce-glue.c
 rename arch/arm/{crypto/crc32-ce-core.S => lib/crc32-core.S} (98%)
 create mode 100644 arch/arm/lib/crc32-glue.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 202397be76d8..f817ca317b02 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -5,10 +5,11 @@ 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_CPU_CACHE_ALIASING
 	select ARCH_HAS_CPU_FINALIZE_INIT if MMU
+	select ARCH_HAS_CRC32 if KERNEL_MODE_NEON
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL if MMU
 	select ARCH_HAS_DMA_ALLOC if MMU
 	select ARCH_HAS_DMA_OPS
 	select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
diff --git a/arch/arm/configs/milbeaut_m10v_defconfig b/arch/arm/configs/milbeaut_m10v_defconfig
index f5eeac9c65c3..acd16204f8d7 100644
--- a/arch/arm/configs/milbeaut_m10v_defconfig
+++ b/arch/arm/configs/milbeaut_m10v_defconfig
@@ -105,11 +105,10 @@ CONFIG_CRYPTO_SHA2_ARM_CE=m
 CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_AES_ARM_CE=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
-CONFIG_CRYPTO_CRC32_ARM_CE=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC_ITU_T=m
 CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=64
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 758276027dbc..9d4336261e45 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -1304,11 +1304,10 @@ CONFIG_CRYPTO_SHA2_ARM_CE=m
 CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_AES_ARM_CE=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
-CONFIG_CRYPTO_CRC32_ARM_CE=m
 CONFIG_CRYPTO_DEV_SUN4I_SS=m
 CONFIG_CRYPTO_DEV_FSL_CAAM=m
 CONFIG_CRYPTO_DEV_EXYNOS_RNG=m
 CONFIG_CRYPTO_DEV_S5P=m
 CONFIG_CRYPTO_DEV_ATMEL_AES=m
diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig
index 5ff49a5e9afc..ea0ebf336d0d 100644
--- a/arch/arm/crypto/Kconfig
+++ b/arch/arm/crypto/Kconfig
@@ -220,24 +220,10 @@ config CRYPTO_CHACHA20_NEON
 	  stream cipher algorithms
 
 	  Architecture: arm using:
 	  - NEON (Advanced SIMD) extensions
 
-config CRYPTO_CRC32_ARM_CE
-	tristate "CRC32C and CRC32"
-	depends on KERNEL_MODE_NEON
-	depends on CRC32
-	select CRYPTO_HASH
-	help
-	  CRC32c CRC algorithm with the iSCSI polynomial (RFC 3385 and RFC 3720)
-	  and CRC32 CRC algorithm (IEEE 802.3)
-
-	  Architecture: arm using:
-	  - CRC and/or PMULL instructions
-
-	  Drivers: crc32-arm-ce and crc32c-arm-ce
-
 config CRYPTO_CRCT10DIF_ARM_CE
 	tristate "CRCT10DIF"
 	depends on KERNEL_MODE_NEON
 	depends on CRC_T10DIF
 	select CRYPTO_HASH
diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
index 13e62c7c25dc..38ec5cc1e844 100644
--- a/arch/arm/crypto/Makefile
+++ b/arch/arm/crypto/Makefile
@@ -19,11 +19,10 @@ obj-$(CONFIG_CRYPTO_CURVE25519_NEON) += curve25519-neon.o
 obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o
 obj-$(CONFIG_CRYPTO_GHASH_ARM_CE) += ghash-arm-ce.o
 obj-$(CONFIG_CRYPTO_CRCT10DIF_ARM_CE) += crct10dif-arm-ce.o
-obj-$(CONFIG_CRYPTO_CRC32_ARM_CE) += crc32-arm-ce.o
 
 aes-arm-y	:= aes-cipher-core.o aes-cipher-glue.o
 aes-arm-bs-y	:= aes-neonbs-core.o aes-neonbs-glue.o
 sha1-arm-y	:= sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y	:= sha1-armv7-neon.o sha1_neon_glue.o
@@ -36,11 +35,10 @@ blake2b-neon-y  := blake2b-neon-core.o blake2b-neon-glue.o
 sha1-arm-ce-y	:= sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y	:= sha2-ce-core.o sha2-ce-glue.o
 aes-arm-ce-y	:= aes-ce-core.o aes-ce-glue.o
 ghash-arm-ce-y	:= ghash-ce-core.o ghash-ce-glue.o
 crct10dif-arm-ce-y	:= crct10dif-ce-core.o crct10dif-ce-glue.o
-crc32-arm-ce-y:= crc32-ce-core.o crc32-ce-glue.o
 chacha-neon-y := chacha-scalar-core.o chacha-glue.o
 chacha-neon-$(CONFIG_KERNEL_MODE_NEON) += chacha-neon-core.o
 poly1305-arm-y := poly1305-core.o poly1305-glue.o
 nhpoly1305-neon-y := nh-neon-core.o nhpoly1305-neon-glue.o
 curve25519-neon-y := curve25519-core.o curve25519-glue.o
diff --git a/arch/arm/crypto/crc32-ce-glue.c b/arch/arm/crypto/crc32-ce-glue.c
deleted file mode 100644
index 20b4dff13e3a..000000000000
--- a/arch/arm/crypto/crc32-ce-glue.c
+++ /dev/null
@@ -1,247 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions instructions
- *
- * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel at linaro.org>
- */
-
-#include <linux/cpufeature.h>
-#include <linux/crc32.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-
-#include <asm/hwcap.h>
-#include <asm/neon.h>
-#include <asm/simd.h>
-#include <linux/unaligned.h>
-
-#define PMULL_MIN_LEN		64L	/* minimum size of buffer
-					 * for crc32_pmull_le_16 */
-#define SCALE_F			16L	/* size of NEON register */
-
-asmlinkage u32 crc32_pmull_le(const u8 buf[], u32 len, u32 init_crc);
-asmlinkage u32 crc32_armv8_le(u32 init_crc, const u8 buf[], u32 len);
-
-asmlinkage u32 crc32c_pmull_le(const u8 buf[], u32 len, u32 init_crc);
-asmlinkage u32 crc32c_armv8_le(u32 init_crc, const u8 buf[], u32 len);
-
-static u32 (*fallback_crc32)(u32 init_crc, const u8 buf[], u32 len);
-static u32 (*fallback_crc32c)(u32 init_crc, const u8 buf[], u32 len);
-
-static int crc32_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = 0;
-	return 0;
-}
-
-static int crc32c_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = ~0;
-	return 0;
-}
-
-static int crc32_setkey(struct crypto_shash *hash, const u8 *key,
-			unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = le32_to_cpup((__le32 *)key);
-	return 0;
-}
-
-static int crc32_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crc = shash_desc_ctx(desc);
-
-	*crc = *mctx;
-	return 0;
-}
-
-static int crc32_update(struct shash_desc *desc, const u8 *data,
-			unsigned int length)
-{
-	u32 *crc = shash_desc_ctx(desc);
-
-	*crc = crc32_armv8_le(*crc, data, length);
-	return 0;
-}
-
-static int crc32c_update(struct shash_desc *desc, const u8 *data,
-			 unsigned int length)
-{
-	u32 *crc = shash_desc_ctx(desc);
-
-	*crc = crc32c_armv8_le(*crc, data, length);
-	return 0;
-}
-
-static int crc32_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crc = shash_desc_ctx(desc);
-
-	put_unaligned_le32(*crc, out);
-	return 0;
-}
-
-static int crc32c_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crc = shash_desc_ctx(desc);
-
-	put_unaligned_le32(~*crc, out);
-	return 0;
-}
-
-static int crc32_pmull_update(struct shash_desc *desc, const u8 *data,
-			      unsigned int length)
-{
-	u32 *crc = shash_desc_ctx(desc);
-	unsigned int l;
-
-	if (crypto_simd_usable()) {
-		if ((u32)data % SCALE_F) {
-			l = min_t(u32, length, SCALE_F - ((u32)data % SCALE_F));
-
-			*crc = fallback_crc32(*crc, data, l);
-
-			data += l;
-			length -= l;
-		}
-
-		if (length >= PMULL_MIN_LEN) {
-			l = round_down(length, SCALE_F);
-
-			kernel_neon_begin();
-			*crc = crc32_pmull_le(data, l, *crc);
-			kernel_neon_end();
-
-			data += l;
-			length -= l;
-		}
-	}
-
-	if (length > 0)
-		*crc = fallback_crc32(*crc, data, length);
-
-	return 0;
-}
-
-static int crc32c_pmull_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int length)
-{
-	u32 *crc = shash_desc_ctx(desc);
-	unsigned int l;
-
-	if (crypto_simd_usable()) {
-		if ((u32)data % SCALE_F) {
-			l = min_t(u32, length, SCALE_F - ((u32)data % SCALE_F));
-
-			*crc = fallback_crc32c(*crc, data, l);
-
-			data += l;
-			length -= l;
-		}
-
-		if (length >= PMULL_MIN_LEN) {
-			l = round_down(length, SCALE_F);
-
-			kernel_neon_begin();
-			*crc = crc32c_pmull_le(data, l, *crc);
-			kernel_neon_end();
-
-			data += l;
-			length -= l;
-		}
-	}
-
-	if (length > 0)
-		*crc = fallback_crc32c(*crc, data, length);
-
-	return 0;
-}
-
-static struct shash_alg crc32_pmull_algs[] = { {
-	.setkey			= crc32_setkey,
-	.init			= crc32_init,
-	.update			= crc32_update,
-	.final			= crc32_final,
-	.descsize		= sizeof(u32),
-	.digestsize		= sizeof(u32),
-
-	.base.cra_ctxsize	= sizeof(u32),
-	.base.cra_init		= crc32_cra_init,
-	.base.cra_name		= "crc32",
-	.base.cra_driver_name	= "crc32-arm-ce",
-	.base.cra_priority	= 200,
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_blocksize	= 1,
-	.base.cra_module	= THIS_MODULE,
-}, {
-	.setkey			= crc32_setkey,
-	.init			= crc32_init,
-	.update			= crc32c_update,
-	.final			= crc32c_final,
-	.descsize		= sizeof(u32),
-	.digestsize		= sizeof(u32),
-
-	.base.cra_ctxsize	= sizeof(u32),
-	.base.cra_init		= crc32c_cra_init,
-	.base.cra_name		= "crc32c",
-	.base.cra_driver_name	= "crc32c-arm-ce",
-	.base.cra_priority	= 200,
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_blocksize	= 1,
-	.base.cra_module	= THIS_MODULE,
-} };
-
-static int __init crc32_pmull_mod_init(void)
-{
-	if (elf_hwcap2 & HWCAP2_PMULL) {
-		crc32_pmull_algs[0].update = crc32_pmull_update;
-		crc32_pmull_algs[1].update = crc32c_pmull_update;
-
-		if (elf_hwcap2 & HWCAP2_CRC32) {
-			fallback_crc32 = crc32_armv8_le;
-			fallback_crc32c = crc32c_armv8_le;
-		} else {
-			fallback_crc32 = crc32_le;
-			fallback_crc32c = __crc32c_le;
-		}
-	} else if (!(elf_hwcap2 & HWCAP2_CRC32)) {
-		return -ENODEV;
-	}
-
-	return crypto_register_shashes(crc32_pmull_algs,
-				       ARRAY_SIZE(crc32_pmull_algs));
-}
-
-static void __exit crc32_pmull_mod_exit(void)
-{
-	crypto_unregister_shashes(crc32_pmull_algs,
-				  ARRAY_SIZE(crc32_pmull_algs));
-}
-
-static const struct cpu_feature __maybe_unused crc32_cpu_feature[] = {
-	{ cpu_feature(CRC32) }, { cpu_feature(PMULL) }, { }
-};
-MODULE_DEVICE_TABLE(cpu, crc32_cpu_feature);
-
-module_init(crc32_pmull_mod_init);
-module_exit(crc32_pmull_mod_exit);
-
-MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel at linaro.org>");
-MODULE_DESCRIPTION("Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS_CRYPTO("crc32");
-MODULE_ALIAS_CRYPTO("crc32c");
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 0ca5aae1bcc3..01cd4db2ed47 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -43,5 +43,8 @@ ifeq ($(CONFIG_KERNEL_MODE_NEON),y)
   CFLAGS_xor-neon.o		+= $(CC_FLAGS_FPU)
   obj-$(CONFIG_XOR_BLOCKS)	+= xor-neon.o
 endif
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
+
+obj-$(CONFIG_CRC32_ARCH) += crc32-arm.o
+crc32-arm-y := crc32-glue.o crc32-core.o
diff --git a/arch/arm/crypto/crc32-ce-core.S b/arch/arm/lib/crc32-core.S
similarity index 98%
rename from arch/arm/crypto/crc32-ce-core.S
rename to arch/arm/lib/crc32-core.S
index 88f9edf94e95..6f674f30c70b 100644
--- a/arch/arm/crypto/crc32-ce-core.S
+++ b/arch/arm/lib/crc32-core.S
@@ -46,11 +46,10 @@
  * Authors:   Gregory Prestas <Gregory_Prestas at us.xyratex.com>
  *	      Alexander Boyko <Alexander_Boyko at xyratex.com>
  */
 
 #include <linux/linkage.h>
-#include <linux/cfi_types.h>
 #include <asm/assembler.h>
 
 	.text
 	.align		6
 	.arch		armv8-a
@@ -295,13 +294,13 @@ ARM_BE8(rev16		r3, r3		)
 	bpl		.Laligned8\c
 	b		.Ltail\c
 	.endm
 
 	.align		5
-SYM_TYPED_FUNC_START(crc32_armv8_le)
+SYM_FUNC_START(crc32_armv8_le)
 	__crc32
 SYM_FUNC_END(crc32_armv8_le)
 
 	.align		5
-SYM_TYPED_FUNC_START(crc32c_armv8_le)
+SYM_FUNC_START(crc32c_armv8_le)
 	__crc32		c
 SYM_FUNC_END(crc32c_armv8_le)
diff --git a/arch/arm/lib/crc32-glue.c b/arch/arm/lib/crc32-glue.c
new file mode 100644
index 000000000000..2c30ba3d80e6
--- /dev/null
+++ b/arch/arm/lib/crc32-glue.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions instructions
+ *
+ * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel at linaro.org>
+ */
+
+#include <linux/cpufeature.h>
+#include <linux/crc32.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <crypto/internal/simd.h>
+
+#include <asm/hwcap.h>
+#include <asm/neon.h>
+#include <asm/simd.h>
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32);
+static DEFINE_STATIC_KEY_FALSE(have_pmull);
+
+#define PMULL_MIN_LEN	64	/* min size of buffer for pmull functions */
+
+asmlinkage u32 crc32_pmull_le(const u8 buf[], u32 len, u32 init_crc);
+asmlinkage u32 crc32_armv8_le(u32 init_crc, const u8 buf[], u32 len);
+
+asmlinkage u32 crc32c_pmull_le(const u8 buf[], u32 len, u32 init_crc);
+asmlinkage u32 crc32c_armv8_le(u32 init_crc, const u8 buf[], u32 len);
+
+static u32 crc32_le_scalar(u32 crc, const u8 *p, size_t len)
+{
+	if (static_branch_likely(&have_crc32))
+		return crc32_armv8_le(crc, p, len);
+	return crc32_le_base(crc, p, len);
+}
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (len >= PMULL_MIN_LEN + 15 &&
+	    static_branch_likely(&have_pmull) && crypto_simd_usable()) {
+		size_t n = -(uintptr_t)p & 15;
+
+		/* align p to 16-byte boundary */
+		if (n) {
+			crc = crc32_le_scalar(crc, p, n);
+			p += n;
+			len -= n;
+		}
+		n = round_down(len, 16);
+		kernel_neon_begin();
+		crc = crc32_pmull_le(p, n, crc);
+		kernel_neon_end();
+		p += n;
+		len -= n;
+	}
+	return crc32_le_scalar(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+static u32 crc32c_le_scalar(u32 crc, const u8 *p, size_t len)
+{
+	if (static_branch_likely(&have_crc32))
+		return crc32c_armv8_le(crc, p, len);
+	return crc32c_le_base(crc, p, len);
+}
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (len >= PMULL_MIN_LEN + 15 &&
+	    static_branch_likely(&have_pmull) && crypto_simd_usable()) {
+		size_t n = -(uintptr_t)p & 15;
+
+		/* align p to 16-byte boundary */
+		if (n) {
+			crc = crc32c_le_scalar(crc, p, n);
+			p += n;
+			len -= n;
+		}
+		n = round_down(len, 16);
+		kernel_neon_begin();
+		crc = crc32c_pmull_le(p, n, crc);
+		kernel_neon_end();
+		p += n;
+		len -= n;
+	}
+	return crc32c_le_scalar(crc, p, len);
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_arm_init(void)
+{
+	if (elf_hwcap2 & HWCAP2_CRC32)
+		static_branch_enable(&have_crc32);
+	if (elf_hwcap2 & HWCAP2_PMULL)
+		static_branch_enable(&have_pmull);
+	return 0;
+}
+arch_initcall(crc32_arm_init);
+
+static void __exit crc32_arm_exit(void)
+{
+}
+module_exit(crc32_arm_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (elf_hwcap2 & (HWCAP2_CRC32 | HWCAP2_PMULL))
+		return CRC32_LE_OPTIMIZATION | CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel at linaro.org>");
+MODULE_DESCRIPTION("Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions");
+MODULE_LICENSE("GPL v2");
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:27 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:27 -0800
Subject: [PATCH v4 02/19] lib/crc32: improve support for arch-specific overrides
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-3-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Currently the CRC32 library functions are defined as weak symbols, and
the arm64 and riscv architectures override them.

This method of arch-specific overrides has the limitation that it only
works when both the base and arch code is built-in.  Also, it makes the
arch-specific code be silently not used if it is accidentally built with
lib-y instead of obj-y; unfortunately the RISC-V code does this.

This commit reorganizes the code to have explicit *_arch() functions
that are called when they are enabled, similar to how some of the crypto
library code works (e.g. chacha_crypt() calls chacha_crypt_arch()).

Make the existing kconfig choice for the CRC32 implementation also
control whether the arch-optimized implementation (if one is available)
is enabled or not.  Make it enabled by default if CRC32 is also enabled.

The result is that arch-optimized CRC32 library functions will be
included automatically when appropriate, but it is now possible to
disable them.  They can also now be built as a loadable module if the
CRC32 library functions happen to be used only by loadable modules, in
which case the arch and base CRC32 modules will be automatically loaded
via direct symbol dependency when appropriate.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm64/Kconfig                        |  1 +
 arch/arm64/lib/Makefile                   |  3 +-
 arch/arm64/lib/crc32-glue.c               | 13 ++++-
 arch/riscv/Kconfig                        |  1 +
 arch/riscv/lib/Makefile                   |  3 +-
 arch/riscv/lib/{crc32.c => crc32-riscv.c} | 13 ++++-
 crypto/crc32_generic.c                    |  4 +-
 crypto/crc32c_generic.c                   |  4 +-
 include/linux/crc32.h                     | 35 +++++++++---
 lib/Kconfig                               | 70 +++++++++++++++++------
 lib/crc32.c                               | 22 +++----
 11 files changed, 118 insertions(+), 51 deletions(-)
 rename arch/riscv/lib/{crc32.c => crc32-riscv.c} (94%)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..71f6310c8240 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -19,10 +19,11 @@ config ARM64
 	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	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_CC_PLATFORM
+	select ARCH_HAS_CRC32
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DMA_OPS if XEN
 	select ARCH_HAS_DMA_PREP_COHERENT
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 8e882f479d98..5fbcf0d56665 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -11,11 +11,12 @@ CFLAGS_xor-neon.o		+= $(CC_FLAGS_FPU)
 CFLAGS_REMOVE_xor-neon.o	+= $(CC_FLAGS_NO_FPU)
 endif
 
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
 
-obj-$(CONFIG_CRC32) += crc32.o crc32-glue.o
+obj-$(CONFIG_CRC32_ARCH) += crc32-arm64.o
+crc32-arm64-y := crc32.o crc32-glue.o
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 
 obj-$(CONFIG_ARM64_MTE) += mte.o
 
diff --git a/arch/arm64/lib/crc32-glue.c b/arch/arm64/lib/crc32-glue.c
index ad015223d15d..d7f6e1cbf0d2 100644
--- a/arch/arm64/lib/crc32-glue.c
+++ b/arch/arm64/lib/crc32-glue.c
@@ -1,9 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
 #include <linux/crc32.h>
 #include <linux/linkage.h>
+#include <linux/module.h>
 
 #include <asm/alternative.h>
 #include <asm/cpufeature.h>
 #include <asm/neon.h>
 #include <asm/simd.h>
@@ -19,11 +20,11 @@ asmlinkage u32 crc32_be_arm64(u32 crc, unsigned char const *p, size_t len);
 
 asmlinkage u32 crc32_le_arm64_4way(u32 crc, unsigned char const *p, size_t len);
 asmlinkage u32 crc32c_le_arm64_4way(u32 crc, unsigned char const *p, size_t len);
 asmlinkage u32 crc32_be_arm64_4way(u32 crc, unsigned char const *p, size_t len);
 
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le_arch(u32 crc, const u8 *p, size_t len)
 {
 	if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
 		return crc32_le_base(crc, p, len);
 
 	if (len >= min_len && cpu_have_named_feature(PMULL) && crypto_simd_usable()) {
@@ -38,12 +39,13 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 			return crc;
 	}
 
 	return crc32_le_arm64(crc, p, len);
 }
+EXPORT_SYMBOL(crc32_le_arch);
 
-u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32c_le_arch(u32 crc, const u8 *p, size_t len)
 {
 	if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
 		return crc32c_le_base(crc, p, len);
 
 	if (len >= min_len && cpu_have_named_feature(PMULL) && crypto_simd_usable()) {
@@ -58,12 +60,13 @@ u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 			return crc;
 	}
 
 	return crc32c_le_arm64(crc, p, len);
 }
+EXPORT_SYMBOL(crc32c_le_arch);
 
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
 {
 	if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
 		return crc32_be_base(crc, p, len);
 
 	if (len >= min_len && cpu_have_named_feature(PMULL) && crypto_simd_usable()) {
@@ -78,5 +81,9 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 			return crc;
 	}
 
 	return crc32_be_arm64(crc, p, len);
 }
+EXPORT_SYMBOL(crc32_be_arch);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("arm64-optimized CRC32 functions");
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index d4a7ca0388c0..7d5718667e39 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -22,10 +22,11 @@ config RISCV
 	select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM_VMEMMAP
 	select ARCH_ENABLE_MEMORY_HOTREMOVE if MEMORY_HOTPLUG
 	select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
 	select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
 	select ARCH_HAS_BINFMT_FLAT
+	select ARCH_HAS_CRC32 if RISCV_ISA_ZBC
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL if MMU
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEBUG_WX
 	select ARCH_HAS_FAST_MULTIPLIER
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 8eec6b69a875..79368a895fee 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -13,10 +13,9 @@ ifeq ($(CONFIG_MMU), y)
 lib-$(CONFIG_RISCV_ISA_V)	+= uaccess_vector.o
 endif
 lib-$(CONFIG_MMU)	+= uaccess.o
 lib-$(CONFIG_64BIT)	+= tishift.o
 lib-$(CONFIG_RISCV_ISA_ZICBOZ)	+= clear_page.o
-lib-$(CONFIG_RISCV_ISA_ZBC)	+= crc32.o
-
+obj-$(CONFIG_CRC32_ARCH)	+= crc32-riscv.o
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 lib-$(CONFIG_RISCV_ISA_V)	+= xor.o
 lib-$(CONFIG_RISCV_ISA_V)	+= riscv_v_helpers.o
diff --git a/arch/riscv/lib/crc32.c b/arch/riscv/lib/crc32-riscv.c
similarity index 94%
rename from arch/riscv/lib/crc32.c
rename to arch/riscv/lib/crc32-riscv.c
index 333fb7af1192..a3ff7db2a1ce 100644
--- a/arch/riscv/lib/crc32.c
+++ b/arch/riscv/lib/crc32-riscv.c
@@ -12,10 +12,11 @@
 #include <linux/types.h>
 #include <linux/minmax.h>
 #include <linux/crc32poly.h>
 #include <linux/crc32.h>
 #include <linux/byteorder/generic.h>
+#include <linux/module.h>
 
 /*
  * Refer to https://www.corsix.org/content/barrett-reduction-polynomials for
  * better understanding of how this math works.
  *
@@ -215,21 +216,23 @@ static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p,
 
 legacy:
 	return crc_fb(crc, p, len);
 }
 
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le_arch(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, CRC32_POLY_LE, CRC32_POLY_QT_LE,
 				crc32_le_base);
 }
+EXPORT_SYMBOL(crc32_le_arch);
 
-u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32c_le_arch(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, CRC32C_POLY_LE,
 				CRC32C_POLY_QT_LE, crc32c_le_base);
 }
+EXPORT_SYMBOL(crc32c_le_arch);
 
 static inline u32 crc32_be_unaligned(u32 crc, unsigned char const *p,
 				     size_t len)
 {
 	size_t bits = len * 8;
@@ -251,11 +254,11 @@ static inline u32 crc32_be_unaligned(u32 crc, unsigned char const *p,
 	crc ^= crc_low;
 
 	return crc;
 }
 
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
 {
 	size_t offset, head_len, tail_len;
 	unsigned long const *p_ul;
 	unsigned long s;
 
@@ -290,5 +293,9 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 	return crc;
 
 legacy:
 	return crc32_be_base(crc, p, len);
 }
+EXPORT_SYMBOL(crc32_be_arch);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Accelerated CRC32 implementation with Zbc extension");
diff --git a/crypto/crc32_generic.c b/crypto/crc32_generic.c
index 6a55d206fab3..cc064ea8240e 100644
--- a/crypto/crc32_generic.c
+++ b/crypto/crc32_generic.c
@@ -158,16 +158,16 @@ static struct shash_alg algs[] = {{
 }};
 
 static int __init crc32_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + (&crc32_le != &crc32_le_base));
+	return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
 }
 
 static void __exit crc32_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + (&crc32_le != &crc32_le_base));
+	crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
 }
 
 subsys_initcall(crc32_mod_init);
 module_exit(crc32_mod_fini);
 
diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c
index 635599b255ec..04b03d825cf4 100644
--- a/crypto/crc32c_generic.c
+++ b/crypto/crc32c_generic.c
@@ -198,16 +198,16 @@ static struct shash_alg algs[] = {{
 }};
 
 static int __init crc32c_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + (&__crc32c_le != &crc32c_le_base));
+	return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
 }
 
 static void __exit crc32c_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + (&__crc32c_le != &crc32c_le_base));
+	crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
 }
 
 subsys_initcall(crc32c_mod_init);
 module_exit(crc32c_mod_fini);
 
diff --git a/include/linux/crc32.h b/include/linux/crc32.h
index 5b07fc9081c4..58c632533b08 100644
--- a/include/linux/crc32.h
+++ b/include/linux/crc32.h
@@ -6,14 +6,38 @@
 #define _LINUX_CRC32_H
 
 #include <linux/types.h>
 #include <linux/bitrev.h>
 
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len);
-u32 __pure crc32_le_base(u32 crc, unsigned char const *p, size_t len);
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len);
-u32 __pure crc32_be_base(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32_le_arch(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32_le_base(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32_be_base(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32c_le_arch(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32c_le_base(u32 crc, const u8 *p, size_t len);
+
+static inline u32 __pure crc32_le(u32 crc, const u8 *p, size_t len)
+{
+	if (IS_ENABLED(CONFIG_CRC32_ARCH))
+		return crc32_le_arch(crc, p, len);
+	return crc32_le_base(crc, p, len);
+}
+
+static inline u32 __pure crc32_be(u32 crc, const u8 *p, size_t len)
+{
+	if (IS_ENABLED(CONFIG_CRC32_ARCH))
+		return crc32_be_arch(crc, p, len);
+	return crc32_be_base(crc, p, len);
+}
+
+/* TODO: leading underscores should be dropped once callers have been updated */
+static inline u32 __pure __crc32c_le(u32 crc, const u8 *p, size_t len)
+{
+	if (IS_ENABLED(CONFIG_CRC32_ARCH))
+		return crc32c_le_arch(crc, p, len);
+	return crc32c_le_base(crc, p, len);
+}
 
 /**
  * crc32_le_combine - Combine two crc32 check values into one. For two
  * 		      sequences of bytes, seq1 and seq2 with lengths len1
  * 		      and len2, crc32_le() check values were calculated
@@ -36,13 +60,10 @@ u32 __attribute_const__ crc32_le_shift(u32 crc, size_t len);
 static inline u32 crc32_le_combine(u32 crc1, u32 crc2, size_t len2)
 {
 	return crc32_le_shift(crc1, len2) ^ crc2;
 }
 
-u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len);
-u32 __pure crc32c_le_base(u32 crc, unsigned char const *p, size_t len);
-
 /**
  * __crc32c_le_combine - Combine two crc32c check values into one. For two
  * 			 sequences of bytes, seq1 and seq2 with lengths len1
  * 			 and len2, __crc32c_le() check values were calculated
  * 			 for each, crc1 and crc2.
diff --git a/lib/Kconfig b/lib/Kconfig
index 5a318f753b2f..8858030bebae 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -188,10 +188,13 @@ config CRC32
 	  This option is provided for the case where no in-kernel-tree
 	  modules require CRC32/CRC32c functions, but a module built outside
 	  the kernel tree does. Such modules that use library CRC32/CRC32c
 	  functions require M here.
 
+config ARCH_HAS_CRC32
+	bool
+
 config CRC32_SELFTEST
 	tristate "CRC32 perform self test on init"
 	depends on CRC32
 	help
 	  This option enables the CRC32 library functions to perform a
@@ -200,54 +203,89 @@ config CRC32_SELFTEST
 	  and computes the total elapsed time and number of bytes processed.
 
 choice
 	prompt "CRC32 implementation"
 	depends on CRC32
-	default CRC32_SLICEBY8
+	default CRC32_IMPL_ARCH_PLUS_SLICEBY8 if ARCH_HAS_CRC32
+	default CRC32_IMPL_SLICEBY8 if !ARCH_HAS_CRC32
 	help
-	  This option allows a kernel builder to override the default choice
-	  of CRC32 algorithm.  Choose the default ("slice by 8") unless you
-	  know that you need one of the others.
+	  This option allows you to override the default choice of CRC32
+	  implementation.  Choose the default unless you know that you need one
+	  of the others.
 
-config CRC32_SLICEBY8
+config CRC32_IMPL_ARCH_PLUS_SLICEBY8
+	bool "Arch-optimized, with fallback to slice-by-8" if ARCH_HAS_CRC32
+	help
+	  Use architecture-optimized implementation of CRC32.  Fall back to
+	  slice-by-8 in cases where the arch-optimized implementation cannot be
+	  used, e.g. if the CPU lacks support for the needed instructions.
+
+	  This is the default when an arch-optimized implementation exists.
+
+config CRC32_IMPL_ARCH_PLUS_SLICEBY1
+	bool "Arch-optimized, with fallback to slice-by-1" if ARCH_HAS_CRC32
+	help
+	  Use architecture-optimized implementation of CRC32, but fall back to
+	  slice-by-1 instead of slice-by-8 in order to reduce the binary size.
+
+config CRC32_IMPL_SLICEBY8
 	bool "Slice by 8 bytes"
 	help
 	  Calculate checksum 8 bytes at a time with a clever slicing algorithm.
-	  This is the fastest algorithm, but comes with a 8KiB lookup table.
-	  Most modern processors have enough cache to hold this table without
-	  thrashing the cache.
-
-	  This is the default implementation choice.  Choose this one unless
-	  you have a good reason not to.
+	  This is much slower than the architecture-optimized implementation of
+	  CRC32 (if the selected arch has one), but it is portable and is the
+	  fastest implementation when no arch-optimized implementation is
+	  available.  It uses an 8KiB lookup table.  Most modern processors have
+	  enough cache to hold this table without thrashing the cache.
 
-config CRC32_SLICEBY4
+config CRC32_IMPL_SLICEBY4
 	bool "Slice by 4 bytes"
 	help
 	  Calculate checksum 4 bytes at a time with a clever slicing algorithm.
 	  This is a bit slower than slice by 8, but has a smaller 4KiB lookup
 	  table.
 
 	  Only choose this option if you know what you are doing.
 
-config CRC32_SARWATE
-	bool "Sarwate's Algorithm (one byte at a time)"
+config CRC32_IMPL_SLICEBY1
+	bool "Slice by 1 byte (Sarwate's algorithm)"
 	help
 	  Calculate checksum a byte at a time using Sarwate's algorithm.  This
-	  is not particularly fast, but has a small 256 byte lookup table.
+	  is not particularly fast, but has a small 1KiB lookup table.
 
 	  Only choose this option if you know what you are doing.
 
-config CRC32_BIT
+config CRC32_IMPL_BIT
 	bool "Classic Algorithm (one bit at a time)"
 	help
 	  Calculate checksum one bit at a time.  This is VERY slow, but has
 	  no lookup table.  This is provided as a debugging option.
 
 	  Only choose this option if you are debugging crc32.
 
 endchoice
 
+config CRC32_ARCH
+	tristate
+	default CRC32 if CRC32_IMPL_ARCH_PLUS_SLICEBY8 || CRC32_IMPL_ARCH_PLUS_SLICEBY1
+
+config CRC32_SLICEBY8
+	bool
+	default y if CRC32_IMPL_SLICEBY8 || CRC32_IMPL_ARCH_PLUS_SLICEBY8
+
+config CRC32_SLICEBY4
+	bool
+	default y if CRC32_IMPL_SLICEBY4
+
+config CRC32_SARWATE
+	bool
+	default y if CRC32_IMPL_SLICEBY1 || CRC32_IMPL_ARCH_PLUS_SLICEBY1
+
+config CRC32_BIT
+	bool
+	default y if CRC32_IMPL_BIT
+
 config CRC64
 	tristate "CRC64 functions"
 	help
 	  This option is provided for the case where no in-kernel-tree
 	  modules require CRC64 functions, but a module built outside
diff --git a/lib/crc32.c b/lib/crc32.c
index c67059b0082b..47151624332e 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -181,39 +181,31 @@ static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p,
 #endif
 	return crc;
 }
 
 #if CRC_LE_BITS == 1
-u32 __pure __weak crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, NULL, CRC32_POLY_LE);
 }
-u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32c_le_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, NULL, CRC32C_POLY_LE);
 }
 #else
-u32 __pure __weak crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, crc32table_le, CRC32_POLY_LE);
 }
-u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32c_le_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE);
 }
 #endif
-EXPORT_SYMBOL(crc32_le);
-EXPORT_SYMBOL(__crc32c_le);
-
-u32 __pure crc32_le_base(u32, unsigned char const *, size_t) __alias(crc32_le);
 EXPORT_SYMBOL(crc32_le_base);
-
-u32 __pure crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le);
 EXPORT_SYMBOL(crc32c_le_base);
 
-u32 __pure crc32_be_base(u32, unsigned char const *, size_t) __alias(crc32_be);
-
 /*
  * This multiplies the polynomials x and y modulo the given modulus.
  * This follows the "little-endian" CRC convention that the lsbit
  * represents the highest power of x, and the msbit represents x^0.
  */
@@ -333,16 +325,16 @@ static inline u32 __pure crc32_be_generic(u32 crc, unsigned char const *p,
 # endif
 	return crc;
 }
 
 #if CRC_BE_BITS == 1
-u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, NULL, CRC32_POLY_BE);
 }
 #else
-u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, crc32table_be, CRC32_POLY_BE);
 }
 #endif
-EXPORT_SYMBOL(crc32_be);
+EXPORT_SYMBOL(crc32_be_base);
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:31 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:31 -0800
Subject: [PATCH v4 06/19] loongarch/crc32: expose CRC32 functions through lib
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-7-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the loongarch CRC32 assembly code into the lib directory and wire
it up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/loongarch/crypto/crc32-loongarch.c to
arch/loongarch/lib/crc32-loongarch.c, view this commit with
'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: WangYuli <wangyuli at uniontech.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/loongarch/Kconfig                     |   1 +
 arch/loongarch/configs/loongson3_defconfig |   1 -
 arch/loongarch/crypto/Kconfig              |   9 -
 arch/loongarch/crypto/Makefile             |   2 -
 arch/loongarch/crypto/crc32-loongarch.c    | 300 ---------------------
 arch/loongarch/lib/Makefile                |   2 +
 arch/loongarch/lib/crc32-loongarch.c       | 135 ++++++++++
 7 files changed, 138 insertions(+), 312 deletions(-)
 delete mode 100644 arch/loongarch/crypto/crc32-loongarch.c
 create mode 100644 arch/loongarch/lib/crc32-loongarch.c

diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index dae3a9104ca6..1c4d13aa677e 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -13,10 +13,11 @@ config LOONGARCH
 	select ARCH_ENABLE_MEMORY_HOTPLUG
 	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
 	select ARCH_HAS_ACPI_TABLE_UPGRADE	if ACPI
 	select ARCH_HAS_CPU_FINALIZE_INIT
+	select ARCH_HAS_CRC32
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_FAST_MULTIPLIER
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_KCOV
diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig
index 4dffc90192f7..2052452e241a 100644
--- a/arch/loongarch/configs/loongson3_defconfig
+++ b/arch/loongarch/configs/loongson3_defconfig
@@ -1038,11 +1038,10 @@ CONFIG_CRYPTO_LZ4=m
 CONFIG_CRYPTO_LZ4HC=m
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_CRC32_LOONGARCH=m
 CONFIG_CRYPTO_DEV_VIRTIO=m
 CONFIG_DMA_CMA=y
 CONFIG_DMA_NUMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=0
 CONFIG_PRINTK_TIME=y
diff --git a/arch/loongarch/crypto/Kconfig b/arch/loongarch/crypto/Kconfig
index 200a6e8b43b1..a0270b3e5b30 100644
--- a/arch/loongarch/crypto/Kconfig
+++ b/arch/loongarch/crypto/Kconfig
@@ -1,14 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
 menu "Accelerated Cryptographic Algorithms for CPU (loongarch)"
 
-config CRYPTO_CRC32_LOONGARCH
-	tristate "CRC32c and CRC32"
-	select CRC32
-	select CRYPTO_HASH
-	help
-	  CRC32c and CRC32 CRC algorithms
-
-	  Architecture: LoongArch with CRC32 instructions
-
 endmenu
diff --git a/arch/loongarch/crypto/Makefile b/arch/loongarch/crypto/Makefile
index d22613d27ce9..ba83755dde2b 100644
--- a/arch/loongarch/crypto/Makefile
+++ b/arch/loongarch/crypto/Makefile
@@ -1,6 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 #
 # Makefile for LoongArch crypto files..
 #
-
-obj-$(CONFIG_CRYPTO_CRC32_LOONGARCH) += crc32-loongarch.o
diff --git a/arch/loongarch/crypto/crc32-loongarch.c b/arch/loongarch/crypto/crc32-loongarch.c
deleted file mode 100644
index b7d9782827f5..000000000000
--- a/arch/loongarch/crypto/crc32-loongarch.c
+++ /dev/null
@@ -1,300 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * crc32.c - CRC32 and CRC32C using LoongArch crc* instructions
- *
- * Module based on mips/crypto/crc32-mips.c
- *
- * Copyright (C) 2014 Linaro Ltd <yazen.ghannam at linaro.org>
- * Copyright (C) 2018 MIPS Tech, LLC
- * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
- */
-
-#include <linux/module.h>
-#include <crypto/internal/hash.h>
-
-#include <asm/cpu-features.h>
-#include <linux/unaligned.h>
-
-#define _CRC32(crc, value, size, type)			\
-do {							\
-	__asm__ __volatile__(				\
-		#type ".w." #size ".w" " %0, %1, %0\n\t"\
-		: "+r" (crc)				\
-		: "r" (value)				\
-		: "memory");				\
-} while (0)
-
-#define CRC32(crc, value, size)		_CRC32(crc, value, size, crc)
-#define CRC32C(crc, value, size)	_CRC32(crc, value, size, crcc)
-
-static u32 crc32_loongarch_hw(u32 crc_, const u8 *p, unsigned int len)
-{
-	u32 crc = crc_;
-
-	while (len >= sizeof(u64)) {
-		u64 value = get_unaligned_le64(p);
-
-		CRC32(crc, value, d);
-		p += sizeof(u64);
-		len -= sizeof(u64);
-	}
-
-	if (len & sizeof(u32)) {
-		u32 value = get_unaligned_le32(p);
-
-		CRC32(crc, value, w);
-		p += sizeof(u32);
-	}
-
-	if (len & sizeof(u16)) {
-		u16 value = get_unaligned_le16(p);
-
-		CRC32(crc, value, h);
-		p += sizeof(u16);
-	}
-
-	if (len & sizeof(u8)) {
-		u8 value = *p++;
-
-		CRC32(crc, value, b);
-	}
-
-	return crc;
-}
-
-static u32 crc32c_loongarch_hw(u32 crc_, const u8 *p, unsigned int len)
-{
-	u32 crc = crc_;
-
-	while (len >= sizeof(u64)) {
-		u64 value = get_unaligned_le64(p);
-
-		CRC32C(crc, value, d);
-		p += sizeof(u64);
-		len -= sizeof(u64);
-	}
-
-	if (len & sizeof(u32)) {
-		u32 value = get_unaligned_le32(p);
-
-		CRC32C(crc, value, w);
-		p += sizeof(u32);
-	}
-
-	if (len & sizeof(u16)) {
-		u16 value = get_unaligned_le16(p);
-
-		CRC32C(crc, value, h);
-		p += sizeof(u16);
-	}
-
-	if (len & sizeof(u8)) {
-		u8 value = *p++;
-
-		CRC32C(crc, value, b);
-	}
-
-	return crc;
-}
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-struct chksum_ctx {
-	u32 key;
-};
-
-struct chksum_desc_ctx {
-	u32 crc;
-};
-
-static int chksum_init(struct shash_desc *desc)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = mctx->key;
-
-	return 0;
-}
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set the seed.
- */
-static int chksum_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
-
-	if (keylen != sizeof(mctx->key))
-		return -EINVAL;
-
-	mctx->key = get_unaligned_le32(key);
-
-	return 0;
-}
-
-static int chksum_update(struct shash_desc *desc, const u8 *data, unsigned int length)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = crc32_loongarch_hw(ctx->crc, data, length);
-	return 0;
-}
-
-static int chksumc_update(struct shash_desc *desc, const u8 *data, unsigned int length)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = crc32c_loongarch_hw(ctx->crc, data, length);
-	return 0;
-}
-
-static int chksum_final(struct shash_desc *desc, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	put_unaligned_le32(ctx->crc, out);
-	return 0;
-}
-
-static int chksumc_final(struct shash_desc *desc, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	put_unaligned_le32(~ctx->crc, out);
-	return 0;
-}
-
-static int __chksum_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
-{
-	put_unaligned_le32(crc32_loongarch_hw(crc, data, len), out);
-	return 0;
-}
-
-static int __chksumc_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
-{
-	put_unaligned_le32(~crc32c_loongarch_hw(crc, data, len), out);
-	return 0;
-}
-
-static int chksum_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	return __chksum_finup(ctx->crc, data, len, out);
-}
-
-static int chksumc_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	return __chksumc_finup(ctx->crc, data, len, out);
-}
-
-static int chksum_digest(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-
-	return __chksum_finup(mctx->key, data, length, out);
-}
-
-static int chksumc_digest(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-
-	return __chksumc_finup(mctx->key, data, length, out);
-}
-
-static int chksum_cra_init(struct crypto_tfm *tfm)
-{
-	struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = 0;
-	return 0;
-}
-
-static int chksumc_cra_init(struct crypto_tfm *tfm)
-{
-	struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = ~0;
-	return 0;
-}
-
-static struct shash_alg crc32_alg = {
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.setkey			=	chksum_setkey,
-	.init			=	chksum_init,
-	.update			=	chksum_update,
-	.final			=	chksum_final,
-	.finup			=	chksum_finup,
-	.digest			=	chksum_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crc32",
-		.cra_driver_name	=	"crc32-loongarch",
-		.cra_priority		=	300,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(struct chksum_ctx),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	chksum_cra_init,
-	}
-};
-
-static struct shash_alg crc32c_alg = {
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.setkey			=	chksum_setkey,
-	.init			=	chksum_init,
-	.update			=	chksumc_update,
-	.final			=	chksumc_final,
-	.finup			=	chksumc_finup,
-	.digest			=	chksumc_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crc32c",
-		.cra_driver_name	=	"crc32c-loongarch",
-		.cra_priority		=	300,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(struct chksum_ctx),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	chksumc_cra_init,
-	}
-};
-
-static int __init crc32_mod_init(void)
-{
-	int err;
-
-	if (!cpu_has(CPU_FEATURE_CRC32))
-		return 0;
-
-	err = crypto_register_shash(&crc32_alg);
-	if (err)
-		return err;
-
-	err = crypto_register_shash(&crc32c_alg);
-	if (err)
-		return err;
-
-	return 0;
-}
-
-static void __exit crc32_mod_exit(void)
-{
-	if (!cpu_has(CPU_FEATURE_CRC32))
-		return;
-
-	crypto_unregister_shash(&crc32_alg);
-	crypto_unregister_shash(&crc32c_alg);
-}
-
-module_init(crc32_mod_init);
-module_exit(crc32_mod_exit);
-
-MODULE_AUTHOR("Min Zhou <zhoumin at loongson.cn>");
-MODULE_AUTHOR("Huacai Chen <chenhuacai at loongson.cn>");
-MODULE_DESCRIPTION("CRC32 and CRC32C using LoongArch crc* instructions");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
index ccea3bbd4353..fae77809048b 100644
--- a/arch/loongarch/lib/Makefile
+++ b/arch/loongarch/lib/Makefile
@@ -9,5 +9,7 @@ lib-y	+= delay.o memset.o memcpy.o memmove.o \
 obj-$(CONFIG_ARCH_SUPPORTS_INT128) += tishift.o
 
 obj-$(CONFIG_CPU_HAS_LSX) += xor_simd.o xor_simd_glue.o
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
+
+obj-$(CONFIG_CRC32_ARCH) += crc32-loongarch.o
diff --git a/arch/loongarch/lib/crc32-loongarch.c b/arch/loongarch/lib/crc32-loongarch.c
new file mode 100644
index 000000000000..8af8113ecd9d
--- /dev/null
+++ b/arch/loongarch/lib/crc32-loongarch.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CRC32 and CRC32C using LoongArch crc* instructions
+ *
+ * Module based on mips/crypto/crc32-mips.c
+ *
+ * Copyright (C) 2014 Linaro Ltd <yazen.ghannam at linaro.org>
+ * Copyright (C) 2018 MIPS Tech, LLC
+ * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
+ */
+
+#include <asm/cpu-features.h>
+#include <linux/crc32.h>
+#include <linux/module.h>
+#include <linux/unaligned.h>
+
+#define _CRC32(crc, value, size, type)			\
+do {							\
+	__asm__ __volatile__(				\
+		#type ".w." #size ".w" " %0, %1, %0\n\t"\
+		: "+r" (crc)				\
+		: "r" (value)				\
+		: "memory");				\
+} while (0)
+
+#define CRC32(crc, value, size)		_CRC32(crc, value, size, crc)
+#define CRC32C(crc, value, size)	_CRC32(crc, value, size, crcc)
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32);
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (!static_branch_likely(&have_crc32))
+		return crc32_le_base(crc, p, len);
+
+	while (len >= sizeof(u64)) {
+		u64 value = get_unaligned_le64(p);
+
+		CRC32(crc, value, d);
+		p += sizeof(u64);
+		len -= sizeof(u64);
+	}
+
+	if (len & sizeof(u32)) {
+		u32 value = get_unaligned_le32(p);
+
+		CRC32(crc, value, w);
+		p += sizeof(u32);
+	}
+
+	if (len & sizeof(u16)) {
+		u16 value = get_unaligned_le16(p);
+
+		CRC32(crc, value, h);
+		p += sizeof(u16);
+	}
+
+	if (len & sizeof(u8)) {
+		u8 value = *p++;
+
+		CRC32(crc, value, b);
+	}
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (!static_branch_likely(&have_crc32))
+		return crc32c_le_base(crc, p, len);
+
+	while (len >= sizeof(u64)) {
+		u64 value = get_unaligned_le64(p);
+
+		CRC32C(crc, value, d);
+		p += sizeof(u64);
+		len -= sizeof(u64);
+	}
+
+	if (len & sizeof(u32)) {
+		u32 value = get_unaligned_le32(p);
+
+		CRC32C(crc, value, w);
+		p += sizeof(u32);
+	}
+
+	if (len & sizeof(u16)) {
+		u16 value = get_unaligned_le16(p);
+
+		CRC32C(crc, value, h);
+		p += sizeof(u16);
+	}
+
+	if (len & sizeof(u8)) {
+		u8 value = *p++;
+
+		CRC32C(crc, value, b);
+	}
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_loongarch_init(void)
+{
+	if (cpu_has_crc32)
+		static_branch_enable(&have_crc32);
+	return 0;
+}
+arch_initcall(crc32_loongarch_init);
+
+static void __exit crc32_loongarch_exit(void)
+{
+}
+module_exit(crc32_loongarch_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_crc32))
+		return CRC32_LE_OPTIMIZATION | CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Min Zhou <zhoumin at loongson.cn>");
+MODULE_AUTHOR("Huacai Chen <chenhuacai at loongson.cn>");
+MODULE_DESCRIPTION("CRC32 and CRC32C using LoongArch crc* instructions");
+MODULE_LICENSE("GPL v2");
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:33 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:33 -0800
Subject: [PATCH v4 08/19] powerpc/crc32: expose CRC32 functions through lib
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-9-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the powerpc CRC32C assembly code into the lib directory and wire it
up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/powerpc/crypto/crc32c-vpmsum_glue.c to
arch/powerpc/lib/crc32-glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Michael Ellerman <mpe at ellerman.id.au> (powerpc)
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/powerpc/Kconfig                          |   1 +
 arch/powerpc/configs/powernv_defconfig        |   1 -
 arch/powerpc/configs/ppc64_defconfig          |   1 -
 arch/powerpc/crypto/Kconfig                   |  15 +-
 arch/powerpc/crypto/Makefile                  |   2 -
 arch/powerpc/crypto/crc32c-vpmsum_glue.c      | 173 ------------------
 arch/powerpc/crypto/crct10dif-vpmsum_asm.S    |   2 +-
 arch/powerpc/lib/Makefile                     |   3 +
 arch/powerpc/lib/crc32-glue.c                 |  92 ++++++++++
 .../{crypto => lib}/crc32-vpmsum_core.S       |   0
 .../{crypto => lib}/crc32c-vpmsum_asm.S       |   0
 11 files changed, 98 insertions(+), 192 deletions(-)
 delete mode 100644 arch/powerpc/crypto/crc32c-vpmsum_glue.c
 create mode 100644 arch/powerpc/lib/crc32-glue.c
 rename arch/powerpc/{crypto => lib}/crc32-vpmsum_core.S (100%)
 rename arch/powerpc/{crypto => lib}/crc32c-vpmsum_asm.S (100%)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a0ce777f9706..b5050a09a27f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -125,10 +125,11 @@ config PPC
 	select ARCH_DISABLE_KASAN_INLINE	if PPC_RADIX_MMU
 	select ARCH_DMA_DEFAULT_COHERENT	if !NOT_COHERENT_CACHE
 	select ARCH_ENABLE_MEMORY_HOTPLUG
 	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	select ARCH_HAS_COPY_MC			if PPC64
+	select ARCH_HAS_CRC32			if PPC64 && ALTIVEC
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEBUG_WX		if STRICT_KERNEL_RWX
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
index ee84ade7a033..4a7ddea05b4d 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -318,11 +318,10 @@ CONFIG_FTR_FIXUP_SELFTEST=y
 CONFIG_MSI_BITMAP_SELFTEST=y
 CONFIG_XMON=y
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_CRC32C_VPMSUM=m
 CONFIG_CRYPTO_CRCT10DIF_VPMSUM=m
 CONFIG_CRYPTO_MD5_PPC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA1_PPC=m
 CONFIG_CRYPTO_SHA256=y
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index f39c0d000c43..58e5f4488da4 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -387,11 +387,10 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_LZO=m
-CONFIG_CRYPTO_CRC32C_VPMSUM=m
 CONFIG_CRYPTO_CRCT10DIF_VPMSUM=m
 CONFIG_CRYPTO_VPMSUM_TESTER=m
 CONFIG_CRYPTO_MD5_PPC=m
 CONFIG_CRYPTO_SHA1_PPC=m
 CONFIG_CRYPTO_AES_GCM_P10=m
diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig
index 951a43726461..2d89e35b3cdd 100644
--- a/arch/powerpc/crypto/Kconfig
+++ b/arch/powerpc/crypto/Kconfig
@@ -11,23 +11,10 @@ config CRYPTO_CURVE25519_PPC64
 	  Curve25519 algorithm
 
 	  Architecture: PowerPC64
 	  - Little-endian
 
-config CRYPTO_CRC32C_VPMSUM
-	tristate "CRC32c"
-	depends on PPC64 && ALTIVEC
-	select CRYPTO_HASH
-	select CRC32
-	help
-	  CRC32c CRC algorithm with the iSCSI polynomial (RFC 3385 and RFC 3720)
-
-	  Architecture: powerpc64 using
-	  - AltiVec extensions
-
-	  Enable on POWER8 and newer processors for improved performance.
-
 config CRYPTO_CRCT10DIF_VPMSUM
 	tristate "CRC32T10DIF"
 	depends on PPC64 && ALTIVEC && CRC_T10DIF
 	select CRYPTO_HASH
 	help
@@ -38,11 +25,11 @@ config CRYPTO_CRCT10DIF_VPMSUM
 
 	  Enable on POWER8 and newer processors for improved performance.
 
 config CRYPTO_VPMSUM_TESTER
 	tristate "CRC32c and CRC32T10DIF hardware acceleration tester"
-	depends on CRYPTO_CRCT10DIF_VPMSUM && CRYPTO_CRC32C_VPMSUM
+	depends on CRYPTO_CRCT10DIF_VPMSUM && CRYPTO_CRC32C && CRC32_ARCH
 	help
 	  Stress test for CRC32c and CRCT10DIF algorithms implemented with
 	  powerpc64 AltiVec extensions (POWER8 vpmsum instructions).
 	  Unless you are testing these algorithms, you don't need this.
 
diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile
index 59808592f0a1..54486192273c 100644
--- a/arch/powerpc/crypto/Makefile
+++ b/arch/powerpc/crypto/Makefile
@@ -8,11 +8,10 @@
 obj-$(CONFIG_CRYPTO_AES_PPC_SPE) += aes-ppc-spe.o
 obj-$(CONFIG_CRYPTO_MD5_PPC) += md5-ppc.o
 obj-$(CONFIG_CRYPTO_SHA1_PPC) += sha1-powerpc.o
 obj-$(CONFIG_CRYPTO_SHA1_PPC_SPE) += sha1-ppc-spe.o
 obj-$(CONFIG_CRYPTO_SHA256_PPC_SPE) += sha256-ppc-spe.o
-obj-$(CONFIG_CRYPTO_CRC32C_VPMSUM) += crc32c-vpmsum.o
 obj-$(CONFIG_CRYPTO_CRCT10DIF_VPMSUM) += crct10dif-vpmsum.o
 obj-$(CONFIG_CRYPTO_VPMSUM_TESTER) += crc-vpmsum_test.o
 obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o
 obj-$(CONFIG_CRYPTO_CHACHA20_P10) += chacha-p10-crypto.o
 obj-$(CONFIG_CRYPTO_POLY1305_P10) += poly1305-p10-crypto.o
@@ -22,11 +21,10 @@ obj-$(CONFIG_CRYPTO_CURVE25519_PPC64) += curve25519-ppc64le.o
 aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o
 md5-ppc-y := md5-asm.o md5-glue.o
 sha1-powerpc-y := sha1-powerpc-asm.o sha1.o
 sha1-ppc-spe-y := sha1-spe-asm.o sha1-spe-glue.o
 sha256-ppc-spe-y := sha256-spe-asm.o sha256-spe-glue.o
-crc32c-vpmsum-y := crc32c-vpmsum_asm.o crc32c-vpmsum_glue.o
 crct10dif-vpmsum-y := crct10dif-vpmsum_asm.o crct10dif-vpmsum_glue.o
 aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-ppc.o
 chacha-p10-crypto-y := chacha-p10-glue.o chacha-p10le-8x.o
 poly1305-p10-crypto-y := poly1305-p10-glue.o poly1305-p10le_64.o
 vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o
diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c
deleted file mode 100644
index 63760b7dbb76..000000000000
--- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c
+++ /dev/null
@@ -1,173 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#include <linux/crc32.h>
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/cpufeature.h>
-#include <asm/simd.h>
-#include <asm/switch_to.h>
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-#define VMX_ALIGN		16
-#define VMX_ALIGN_MASK		(VMX_ALIGN-1)
-
-#define VECTOR_BREAKPOINT	512
-
-u32 __crc32c_vpmsum(u32 crc, unsigned char const *p, size_t len);
-
-static u32 crc32c_vpmsum(u32 crc, unsigned char const *p, size_t len)
-{
-	unsigned int prealign;
-	unsigned int tail;
-
-	if (len < (VECTOR_BREAKPOINT + VMX_ALIGN) || !crypto_simd_usable())
-		return __crc32c_le(crc, p, len);
-
-	if ((unsigned long)p & VMX_ALIGN_MASK) {
-		prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK);
-		crc = __crc32c_le(crc, p, prealign);
-		len -= prealign;
-		p += prealign;
-	}
-
-	if (len & ~VMX_ALIGN_MASK) {
-		preempt_disable();
-		pagefault_disable();
-		enable_kernel_altivec();
-		crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK);
-		disable_kernel_altivec();
-		pagefault_enable();
-		preempt_enable();
-	}
-
-	tail = len & VMX_ALIGN_MASK;
-	if (tail) {
-		p += len & ~VMX_ALIGN_MASK;
-		crc = __crc32c_le(crc, p, tail);
-	}
-
-	return crc;
-}
-
-static int crc32c_vpmsum_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = ~0;
-
-	return 0;
-}
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set
- * the seed.
- */
-static int crc32c_vpmsum_setkey(struct crypto_shash *hash, const u8 *key,
-			       unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = le32_to_cpup((__le32 *)key);
-	return 0;
-}
-
-static int crc32c_vpmsum_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = *mctx;
-
-	return 0;
-}
-
-static int crc32c_vpmsum_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = crc32c_vpmsum(*crcp, data, len);
-
-	return 0;
-}
-
-static int __crc32c_vpmsum_finup(u32 *crcp, const u8 *data, unsigned int len,
-				u8 *out)
-{
-	*(__le32 *)out = ~cpu_to_le32(crc32c_vpmsum(*crcp, data, len));
-
-	return 0;
-}
-
-static int crc32c_vpmsum_finup(struct shash_desc *desc, const u8 *data,
-			      unsigned int len, u8 *out)
-{
-	return __crc32c_vpmsum_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32c_vpmsum_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*(__le32 *)out = ~cpu_to_le32p(crcp);
-
-	return 0;
-}
-
-static int crc32c_vpmsum_digest(struct shash_desc *desc, const u8 *data,
-			       unsigned int len, u8 *out)
-{
-	return __crc32c_vpmsum_finup(crypto_shash_ctx(desc->tfm), data, len,
-				     out);
-}
-
-static struct shash_alg alg = {
-	.setkey		= crc32c_vpmsum_setkey,
-	.init		= crc32c_vpmsum_init,
-	.update		= crc32c_vpmsum_update,
-	.final		= crc32c_vpmsum_final,
-	.finup		= crc32c_vpmsum_finup,
-	.digest		= crc32c_vpmsum_digest,
-	.descsize	= sizeof(u32),
-	.digestsize	= CHKSUM_DIGEST_SIZE,
-	.base		= {
-		.cra_name		= "crc32c",
-		.cra_driver_name	= "crc32c-vpmsum",
-		.cra_priority		= 200,
-		.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		= CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		= sizeof(u32),
-		.cra_module		= THIS_MODULE,
-		.cra_init		= crc32c_vpmsum_cra_init,
-	}
-};
-
-static int __init crc32c_vpmsum_mod_init(void)
-{
-	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
-		return -ENODEV;
-
-	return crypto_register_shash(&alg);
-}
-
-static void __exit crc32c_vpmsum_mod_fini(void)
-{
-	crypto_unregister_shash(&alg);
-}
-
-module_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, crc32c_vpmsum_mod_init);
-module_exit(crc32c_vpmsum_mod_fini);
-
-MODULE_AUTHOR("Anton Blanchard <anton at samba.org>");
-MODULE_DESCRIPTION("CRC32C using vector polynomial multiply-sum instructions");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_CRYPTO("crc32c");
-MODULE_ALIAS_CRYPTO("crc32c-vpmsum");
diff --git a/arch/powerpc/crypto/crct10dif-vpmsum_asm.S b/arch/powerpc/crypto/crct10dif-vpmsum_asm.S
index f0b93a0fe168..0a52261bf859 100644
--- a/arch/powerpc/crypto/crct10dif-vpmsum_asm.S
+++ b/arch/powerpc/crypto/crct10dif-vpmsum_asm.S
@@ -840,6 +840,6 @@
 	.octa 0x000000000000000000000001f65a57f8	/* x^64 div p(x) */
 	/* Barrett constant n */
 	.octa 0x0000000000000000000000018bb70000
 
 #define CRC_FUNCTION_NAME __crct10dif_vpmsum
-#include "crc32-vpmsum_core.S"
+#include "../lib/crc32-vpmsum_core.S"
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index f14ecab674a3..da9381a1c95b 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -76,6 +76,9 @@ obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o
 obj-$(CONFIG_ALTIVEC)	+= xor_vmx.o xor_vmx_glue.o
 CFLAGS_xor_vmx.o += -mhard-float -maltivec $(call cc-option,-mabi=altivec)
 # Enable <altivec.h>
 CFLAGS_xor_vmx.o += -isystem $(shell $(CC) -print-file-name=include)
 
+obj-$(CONFIG_CRC32_ARCH) += crc32-powerpc.o
+crc32-powerpc-y := crc32-glue.o crc32c-vpmsum_asm.o
+
 obj-$(CONFIG_PPC64) += $(obj64-y)
diff --git a/arch/powerpc/lib/crc32-glue.c b/arch/powerpc/lib/crc32-glue.c
new file mode 100644
index 000000000000..79cc954f499f
--- /dev/null
+++ b/arch/powerpc/lib/crc32-glue.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/crc32.h>
+#include <crypto/internal/simd.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/cpufeature.h>
+#include <asm/simd.h>
+#include <asm/switch_to.h>
+
+#define VMX_ALIGN		16
+#define VMX_ALIGN_MASK		(VMX_ALIGN-1)
+
+#define VECTOR_BREAKPOINT	512
+
+static DEFINE_STATIC_KEY_FALSE(have_vec_crypto);
+
+u32 __crc32c_vpmsum(u32 crc, const u8 *p, size_t len);
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_le_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	unsigned int prealign;
+	unsigned int tail;
+
+	if (len < (VECTOR_BREAKPOINT + VMX_ALIGN) ||
+	    !static_branch_likely(&have_vec_crypto) || !crypto_simd_usable())
+		return crc32c_le_base(crc, p, len);
+
+	if ((unsigned long)p & VMX_ALIGN_MASK) {
+		prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK);
+		crc = crc32c_le_base(crc, p, prealign);
+		len -= prealign;
+		p += prealign;
+	}
+
+	if (len & ~VMX_ALIGN_MASK) {
+		preempt_disable();
+		pagefault_disable();
+		enable_kernel_altivec();
+		crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK);
+		disable_kernel_altivec();
+		pagefault_enable();
+		preempt_enable();
+	}
+
+	tail = len & VMX_ALIGN_MASK;
+	if (tail) {
+		p += len & ~VMX_ALIGN_MASK;
+		crc = crc32c_le_base(crc, p, tail);
+	}
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_powerpc_init(void)
+{
+	if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
+	    (cur_cpu_spec->cpu_user_features2 & PPC_FEATURE2_VEC_CRYPTO))
+		static_branch_enable(&have_vec_crypto);
+	return 0;
+}
+arch_initcall(crc32_powerpc_init);
+
+static void __exit crc32_powerpc_exit(void)
+{
+}
+module_exit(crc32_powerpc_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_vec_crypto))
+		return CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Anton Blanchard <anton at samba.org>");
+MODULE_DESCRIPTION("CRC32C using vector polynomial multiply-sum instructions");
+MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/crypto/crc32-vpmsum_core.S b/arch/powerpc/lib/crc32-vpmsum_core.S
similarity index 100%
rename from arch/powerpc/crypto/crc32-vpmsum_core.S
rename to arch/powerpc/lib/crc32-vpmsum_core.S
diff --git a/arch/powerpc/crypto/crc32c-vpmsum_asm.S b/arch/powerpc/lib/crc32c-vpmsum_asm.S
similarity index 100%
rename from arch/powerpc/crypto/crc32c-vpmsum_asm.S
rename to arch/powerpc/lib/crc32c-vpmsum_asm.S
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:32 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:32 -0800
Subject: [PATCH v4 07/19] mips/crc32: expose CRC32 functions through lib
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-8-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the mips CRC32 assembly code into the lib directory and wire it up
to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/mips/crypto/crc32-mips.c to
arch/mips/lib/crc32-mips.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/mips/Kconfig                     |   5 +-
 arch/mips/configs/eyeq5_defconfig     |   1 -
 arch/mips/configs/eyeq6_defconfig     |   1 -
 arch/mips/configs/generic/32r6.config |   2 -
 arch/mips/configs/generic/64r6.config |   1 -
 arch/mips/crypto/Kconfig              |   9 -
 arch/mips/crypto/Makefile             |   2 -
 arch/mips/crypto/crc32-mips.c         | 354 --------------------------
 arch/mips/lib/Makefile                |   2 +
 arch/mips/lib/crc32-mips.c            | 192 ++++++++++++++
 10 files changed, 195 insertions(+), 374 deletions(-)
 delete mode 100644 arch/mips/crypto/crc32-mips.c
 create mode 100644 arch/mips/lib/crc32-mips.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 467b10f4361a..a33f05e1ad6d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1993,15 +1993,15 @@ config CPU_MIPSR5
 	select MIPS_SPRAM
 
 config CPU_MIPSR6
 	bool
 	default y if CPU_MIPS32_R6 || CPU_MIPS64_R6
+	select ARCH_HAS_CRC32
 	select CPU_HAS_RIXI
 	select CPU_HAS_DIEI if !CPU_DIEI_BROKEN
 	select HAVE_ARCH_BITREVERSE
 	select MIPS_ASID_BITS_VARIABLE
-	select MIPS_CRC_SUPPORT
 	select MIPS_SPRAM
 
 config TARGET_ISA_REV
 	int
 	default 1 if CPU_MIPSR1
@@ -2473,13 +2473,10 @@ config MIPS_ASID_BITS
 	default 8
 
 config MIPS_ASID_BITS_VARIABLE
 	bool
 
-config MIPS_CRC_SUPPORT
-	bool
-
 # R4600 erratum.  Due to the lack of errata information the exact
 # technical details aren't known.  I've experimentally found that disabling
 # interrupts during indexed I-cache flushes seems to be sufficient to deal
 # with the issue.
 config WAR_R4600_V1_INDEX_ICACHEOP
diff --git a/arch/mips/configs/eyeq5_defconfig b/arch/mips/configs/eyeq5_defconfig
index ae9a09b16e40..ff7af5dc6d9d 100644
--- a/arch/mips/configs/eyeq5_defconfig
+++ b/arch/mips/configs/eyeq5_defconfig
@@ -97,11 +97,10 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_NFS_V4_1=y
 CONFIG_NFS_V4_2=y
 CONFIG_ROOT_NFS=y
-CONFIG_CRYPTO_CRC32_MIPS=y
 CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_RCU_TRACE is not set
 # CONFIG_FTRACE is not set
 CONFIG_CMDLINE_BOOL=y
diff --git a/arch/mips/configs/eyeq6_defconfig b/arch/mips/configs/eyeq6_defconfig
index 6597d5e88b33..0afbb45a78e8 100644
--- a/arch/mips/configs/eyeq6_defconfig
+++ b/arch/mips/configs/eyeq6_defconfig
@@ -100,11 +100,10 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_NFS_V4_1=y
 CONFIG_NFS_V4_2=y
 CONFIG_ROOT_NFS=y
-CONFIG_CRYPTO_CRC32_MIPS=y
 CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_RCU_TRACE is not set
 # CONFIG_FTRACE is not set
 CONFIG_CMDLINE_BOOL=y
diff --git a/arch/mips/configs/generic/32r6.config b/arch/mips/configs/generic/32r6.config
index 1a5d5ea4ab2b..ca606e71f4d0 100644
--- a/arch/mips/configs/generic/32r6.config
+++ b/arch/mips/configs/generic/32r6.config
@@ -1,4 +1,2 @@
 CONFIG_CPU_MIPS32_R6=y
 CONFIG_HIGHMEM=y
-
-CONFIG_CRYPTO_CRC32_MIPS=y
diff --git a/arch/mips/configs/generic/64r6.config b/arch/mips/configs/generic/64r6.config
index 63b4e95f303d..23a300914957 100644
--- a/arch/mips/configs/generic/64r6.config
+++ b/arch/mips/configs/generic/64r6.config
@@ -2,7 +2,6 @@ CONFIG_CPU_MIPS64_R6=y
 CONFIG_64BIT=y
 CONFIG_MIPS32_O32=y
 CONFIG_MIPS32_N32=y
 
 CONFIG_CPU_HAS_MSA=y
-CONFIG_CRYPTO_CRC32_MIPS=y
 CONFIG_VIRTUALIZATION=y
diff --git a/arch/mips/crypto/Kconfig b/arch/mips/crypto/Kconfig
index 9003a5c1e879..7decd40c4e20 100644
--- a/arch/mips/crypto/Kconfig
+++ b/arch/mips/crypto/Kconfig
@@ -1,18 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 
 menu "Accelerated Cryptographic Algorithms for CPU (mips)"
 
-config CRYPTO_CRC32_MIPS
-	tristate "CRC32c and CRC32"
-	depends on MIPS_CRC_SUPPORT
-	select CRYPTO_HASH
-	help
-	  CRC32c and CRC32 CRC algorithms
-
-	  Architecture: mips
-
 config CRYPTO_POLY1305_MIPS
 	tristate "Hash functions: Poly1305"
 	depends on MIPS
 	select CRYPTO_ARCH_HAVE_LIB_POLY1305
 	help
diff --git a/arch/mips/crypto/Makefile b/arch/mips/crypto/Makefile
index 5e4105cccf9f..fddc88281412 100644
--- a/arch/mips/crypto/Makefile
+++ b/arch/mips/crypto/Makefile
@@ -1,12 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
 #
 # Makefile for MIPS crypto files..
 #
 
-obj-$(CONFIG_CRYPTO_CRC32_MIPS) += crc32-mips.o
-
 obj-$(CONFIG_CRYPTO_CHACHA_MIPS) += chacha-mips.o
 chacha-mips-y := chacha-core.o chacha-glue.o
 AFLAGS_chacha-core.o += -O2 # needed to fill branch delay slots
 
 obj-$(CONFIG_CRYPTO_POLY1305_MIPS) += poly1305-mips.o
diff --git a/arch/mips/crypto/crc32-mips.c b/arch/mips/crypto/crc32-mips.c
deleted file mode 100644
index 90eacf00cfc3..000000000000
--- a/arch/mips/crypto/crc32-mips.c
+++ /dev/null
@@ -1,354 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * crc32-mips.c - CRC32 and CRC32C using optional MIPSr6 instructions
- *
- * Module based on arm64/crypto/crc32-arm.c
- *
- * Copyright (C) 2014 Linaro Ltd <yazen.ghannam at linaro.org>
- * Copyright (C) 2018 MIPS Tech, LLC
- */
-
-#include <linux/cpufeature.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <asm/mipsregs.h>
-#include <linux/unaligned.h>
-
-#include <crypto/internal/hash.h>
-
-enum crc_op_size {
-	b, h, w, d,
-};
-
-enum crc_type {
-	crc32,
-	crc32c,
-};
-
-#ifndef TOOLCHAIN_SUPPORTS_CRC
-#define _ASM_SET_CRC(OP, SZ, TYPE)					  \
-_ASM_MACRO_3R(OP, rt, rs, rt2,						  \
-	".ifnc	\\rt, \\rt2\n\t"					  \
-	".error	\"invalid operands \\\"" #OP " \\rt,\\rs,\\rt2\\\"\"\n\t" \
-	".endif\n\t"							  \
-	_ASM_INSN_IF_MIPS(0x7c00000f | (__rt << 16) | (__rs << 21) |	  \
-			  ((SZ) <<  6) | ((TYPE) << 8))			  \
-	_ASM_INSN32_IF_MM(0x00000030 | (__rs << 16) | (__rt << 21) |	  \
-			  ((SZ) << 14) | ((TYPE) << 3)))
-#define _ASM_UNSET_CRC(op, SZ, TYPE) ".purgem " #op "\n\t"
-#else /* !TOOLCHAIN_SUPPORTS_CRC */
-#define _ASM_SET_CRC(op, SZ, TYPE) ".set\tcrc\n\t"
-#define _ASM_UNSET_CRC(op, SZ, TYPE)
-#endif
-
-#define __CRC32(crc, value, op, SZ, TYPE)		\
-do {							\
-	__asm__ __volatile__(				\
-		".set	push\n\t"			\
-		_ASM_SET_CRC(op, SZ, TYPE)		\
-		#op "	%0, %1, %0\n\t"			\
-		_ASM_UNSET_CRC(op, SZ, TYPE)		\
-		".set	pop"				\
-		: "+r" (crc)				\
-		: "r" (value));				\
-} while (0)
-
-#define _CRC32_crc32b(crc, value)	__CRC32(crc, value, crc32b, 0, 0)
-#define _CRC32_crc32h(crc, value)	__CRC32(crc, value, crc32h, 1, 0)
-#define _CRC32_crc32w(crc, value)	__CRC32(crc, value, crc32w, 2, 0)
-#define _CRC32_crc32d(crc, value)	__CRC32(crc, value, crc32d, 3, 0)
-#define _CRC32_crc32cb(crc, value)	__CRC32(crc, value, crc32cb, 0, 1)
-#define _CRC32_crc32ch(crc, value)	__CRC32(crc, value, crc32ch, 1, 1)
-#define _CRC32_crc32cw(crc, value)	__CRC32(crc, value, crc32cw, 2, 1)
-#define _CRC32_crc32cd(crc, value)	__CRC32(crc, value, crc32cd, 3, 1)
-
-#define _CRC32(crc, value, size, op) \
-	_CRC32_##op##size(crc, value)
-
-#define CRC32(crc, value, size) \
-	_CRC32(crc, value, size, crc32)
-
-#define CRC32C(crc, value, size) \
-	_CRC32(crc, value, size, crc32c)
-
-static u32 crc32_mips_le_hw(u32 crc_, const u8 *p, unsigned int len)
-{
-	u32 crc = crc_;
-
-	if (IS_ENABLED(CONFIG_64BIT)) {
-		for (; len >= sizeof(u64); p += sizeof(u64), len -= sizeof(u64)) {
-			u64 value = get_unaligned_le64(p);
-
-			CRC32(crc, value, d);
-		}
-
-		if (len & sizeof(u32)) {
-			u32 value = get_unaligned_le32(p);
-
-			CRC32(crc, value, w);
-			p += sizeof(u32);
-		}
-	} else {
-		for (; len >= sizeof(u32); len -= sizeof(u32)) {
-			u32 value = get_unaligned_le32(p);
-
-			CRC32(crc, value, w);
-			p += sizeof(u32);
-		}
-	}
-
-	if (len & sizeof(u16)) {
-		u16 value = get_unaligned_le16(p);
-
-		CRC32(crc, value, h);
-		p += sizeof(u16);
-	}
-
-	if (len & sizeof(u8)) {
-		u8 value = *p++;
-
-		CRC32(crc, value, b);
-	}
-
-	return crc;
-}
-
-static u32 crc32c_mips_le_hw(u32 crc_, const u8 *p, unsigned int len)
-{
-	u32 crc = crc_;
-
-	if (IS_ENABLED(CONFIG_64BIT)) {
-		for (; len >= sizeof(u64); p += sizeof(u64), len -= sizeof(u64)) {
-			u64 value = get_unaligned_le64(p);
-
-			CRC32C(crc, value, d);
-		}
-
-		if (len & sizeof(u32)) {
-			u32 value = get_unaligned_le32(p);
-
-			CRC32C(crc, value, w);
-			p += sizeof(u32);
-		}
-	} else {
-		for (; len >= sizeof(u32); len -= sizeof(u32)) {
-			u32 value = get_unaligned_le32(p);
-
-			CRC32C(crc, value, w);
-			p += sizeof(u32);
-		}
-	}
-
-	if (len & sizeof(u16)) {
-		u16 value = get_unaligned_le16(p);
-
-		CRC32C(crc, value, h);
-		p += sizeof(u16);
-	}
-
-	if (len & sizeof(u8)) {
-		u8 value = *p++;
-
-		CRC32C(crc, value, b);
-	}
-	return crc;
-}
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-struct chksum_ctx {
-	u32 key;
-};
-
-struct chksum_desc_ctx {
-	u32 crc;
-};
-
-static int chksum_init(struct shash_desc *desc)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = mctx->key;
-
-	return 0;
-}
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set
- * the seed.
- */
-static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
-			 unsigned int keylen)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
-
-	if (keylen != sizeof(mctx->key))
-		return -EINVAL;
-	mctx->key = get_unaligned_le32(key);
-	return 0;
-}
-
-static int chksum_update(struct shash_desc *desc, const u8 *data,
-			 unsigned int length)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = crc32_mips_le_hw(ctx->crc, data, length);
-	return 0;
-}
-
-static int chksumc_update(struct shash_desc *desc, const u8 *data,
-			 unsigned int length)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = crc32c_mips_le_hw(ctx->crc, data, length);
-	return 0;
-}
-
-static int chksum_final(struct shash_desc *desc, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	put_unaligned_le32(ctx->crc, out);
-	return 0;
-}
-
-static int chksumc_final(struct shash_desc *desc, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	put_unaligned_le32(~ctx->crc, out);
-	return 0;
-}
-
-static int __chksum_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
-{
-	put_unaligned_le32(crc32_mips_le_hw(crc, data, len), out);
-	return 0;
-}
-
-static int __chksumc_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
-{
-	put_unaligned_le32(~crc32c_mips_le_hw(crc, data, len), out);
-	return 0;
-}
-
-static int chksum_finup(struct shash_desc *desc, const u8 *data,
-			unsigned int len, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	return __chksum_finup(ctx->crc, data, len, out);
-}
-
-static int chksumc_finup(struct shash_desc *desc, const u8 *data,
-			unsigned int len, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	return __chksumc_finup(ctx->crc, data, len, out);
-}
-
-static int chksum_digest(struct shash_desc *desc, const u8 *data,
-			 unsigned int length, u8 *out)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-
-	return __chksum_finup(mctx->key, data, length, out);
-}
-
-static int chksumc_digest(struct shash_desc *desc, const u8 *data,
-			 unsigned int length, u8 *out)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-
-	return __chksumc_finup(mctx->key, data, length, out);
-}
-
-static int chksum_cra_init(struct crypto_tfm *tfm)
-{
-	struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = ~0;
-	return 0;
-}
-
-static struct shash_alg crc32_alg = {
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.setkey			=	chksum_setkey,
-	.init			=	chksum_init,
-	.update			=	chksum_update,
-	.final			=	chksum_final,
-	.finup			=	chksum_finup,
-	.digest			=	chksum_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crc32",
-		.cra_driver_name	=	"crc32-mips-hw",
-		.cra_priority		=	300,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(struct chksum_ctx),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	chksum_cra_init,
-	}
-};
-
-static struct shash_alg crc32c_alg = {
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.setkey			=	chksum_setkey,
-	.init			=	chksum_init,
-	.update			=	chksumc_update,
-	.final			=	chksumc_final,
-	.finup			=	chksumc_finup,
-	.digest			=	chksumc_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crc32c",
-		.cra_driver_name	=	"crc32c-mips-hw",
-		.cra_priority		=	300,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(struct chksum_ctx),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	chksum_cra_init,
-	}
-};
-
-static int __init crc32_mod_init(void)
-{
-	int err;
-
-	err = crypto_register_shash(&crc32_alg);
-
-	if (err)
-		return err;
-
-	err = crypto_register_shash(&crc32c_alg);
-
-	if (err) {
-		crypto_unregister_shash(&crc32_alg);
-		return err;
-	}
-
-	return 0;
-}
-
-static void __exit crc32_mod_exit(void)
-{
-	crypto_unregister_shash(&crc32_alg);
-	crypto_unregister_shash(&crc32c_alg);
-}
-
-MODULE_AUTHOR("Marcin Nowakowski <marcin.nowakowski at mips.com");
-MODULE_DESCRIPTION("CRC32 and CRC32C using optional MIPS instructions");
-MODULE_LICENSE("GPL v2");
-
-module_cpu_feature_match(MIPS_CRC32, crc32_mod_init);
-module_exit(crc32_mod_exit);
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 5d5b993cbc2b..9c024e6d5e54 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -12,7 +12,9 @@ obj-$(CONFIG_PCI)	+= iomap-pci.o
 lib-$(CONFIG_GENERIC_CSUM)	:= $(filter-out csum_partial.o, $(lib-y))
 
 obj-$(CONFIG_CPU_GENERIC_DUMP_TLB) += dump_tlb.o
 obj-$(CONFIG_CPU_R3000)		+= r3k_dump_tlb.o
 
+obj-$(CONFIG_CRC32_ARCH)	+= crc32-mips.o
+
 # libgcc-style stuff needed in the kernel
 obj-y += bswapsi.o bswapdi.o multi3.o
diff --git a/arch/mips/lib/crc32-mips.c b/arch/mips/lib/crc32-mips.c
new file mode 100644
index 000000000000..083e5d693a16
--- /dev/null
+++ b/arch/mips/lib/crc32-mips.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * crc32-mips.c - CRC32 and CRC32C using optional MIPSr6 instructions
+ *
+ * Module based on arm64/crypto/crc32-arm.c
+ *
+ * Copyright (C) 2014 Linaro Ltd <yazen.ghannam at linaro.org>
+ * Copyright (C) 2018 MIPS Tech, LLC
+ */
+
+#include <linux/cpufeature.h>
+#include <linux/crc32.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/mipsregs.h>
+#include <linux/unaligned.h>
+
+enum crc_op_size {
+	b, h, w, d,
+};
+
+enum crc_type {
+	crc32,
+	crc32c,
+};
+
+#ifndef TOOLCHAIN_SUPPORTS_CRC
+#define _ASM_SET_CRC(OP, SZ, TYPE)					  \
+_ASM_MACRO_3R(OP, rt, rs, rt2,						  \
+	".ifnc	\\rt, \\rt2\n\t"					  \
+	".error	\"invalid operands \\\"" #OP " \\rt,\\rs,\\rt2\\\"\"\n\t" \
+	".endif\n\t"							  \
+	_ASM_INSN_IF_MIPS(0x7c00000f | (__rt << 16) | (__rs << 21) |	  \
+			  ((SZ) <<  6) | ((TYPE) << 8))			  \
+	_ASM_INSN32_IF_MM(0x00000030 | (__rs << 16) | (__rt << 21) |	  \
+			  ((SZ) << 14) | ((TYPE) << 3)))
+#define _ASM_UNSET_CRC(op, SZ, TYPE) ".purgem " #op "\n\t"
+#else /* !TOOLCHAIN_SUPPORTS_CRC */
+#define _ASM_SET_CRC(op, SZ, TYPE) ".set\tcrc\n\t"
+#define _ASM_UNSET_CRC(op, SZ, TYPE)
+#endif
+
+#define __CRC32(crc, value, op, SZ, TYPE)		\
+do {							\
+	__asm__ __volatile__(				\
+		".set	push\n\t"			\
+		_ASM_SET_CRC(op, SZ, TYPE)		\
+		#op "	%0, %1, %0\n\t"			\
+		_ASM_UNSET_CRC(op, SZ, TYPE)		\
+		".set	pop"				\
+		: "+r" (crc)				\
+		: "r" (value));				\
+} while (0)
+
+#define _CRC32_crc32b(crc, value)	__CRC32(crc, value, crc32b, 0, 0)
+#define _CRC32_crc32h(crc, value)	__CRC32(crc, value, crc32h, 1, 0)
+#define _CRC32_crc32w(crc, value)	__CRC32(crc, value, crc32w, 2, 0)
+#define _CRC32_crc32d(crc, value)	__CRC32(crc, value, crc32d, 3, 0)
+#define _CRC32_crc32cb(crc, value)	__CRC32(crc, value, crc32cb, 0, 1)
+#define _CRC32_crc32ch(crc, value)	__CRC32(crc, value, crc32ch, 1, 1)
+#define _CRC32_crc32cw(crc, value)	__CRC32(crc, value, crc32cw, 2, 1)
+#define _CRC32_crc32cd(crc, value)	__CRC32(crc, value, crc32cd, 3, 1)
+
+#define _CRC32(crc, value, size, op) \
+	_CRC32_##op##size(crc, value)
+
+#define CRC32(crc, value, size) \
+	_CRC32(crc, value, size, crc32)
+
+#define CRC32C(crc, value, size) \
+	_CRC32(crc, value, size, crc32c)
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32);
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (!static_branch_likely(&have_crc32))
+		return crc32_le_base(crc, p, len);
+
+	if (IS_ENABLED(CONFIG_64BIT)) {
+		for (; len >= sizeof(u64); p += sizeof(u64), len -= sizeof(u64)) {
+			u64 value = get_unaligned_le64(p);
+
+			CRC32(crc, value, d);
+		}
+
+		if (len & sizeof(u32)) {
+			u32 value = get_unaligned_le32(p);
+
+			CRC32(crc, value, w);
+			p += sizeof(u32);
+		}
+	} else {
+		for (; len >= sizeof(u32); len -= sizeof(u32)) {
+			u32 value = get_unaligned_le32(p);
+
+			CRC32(crc, value, w);
+			p += sizeof(u32);
+		}
+	}
+
+	if (len & sizeof(u16)) {
+		u16 value = get_unaligned_le16(p);
+
+		CRC32(crc, value, h);
+		p += sizeof(u16);
+	}
+
+	if (len & sizeof(u8)) {
+		u8 value = *p++;
+
+		CRC32(crc, value, b);
+	}
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (!static_branch_likely(&have_crc32))
+		return crc32c_le_base(crc, p, len);
+
+	if (IS_ENABLED(CONFIG_64BIT)) {
+		for (; len >= sizeof(u64); p += sizeof(u64), len -= sizeof(u64)) {
+			u64 value = get_unaligned_le64(p);
+
+			CRC32C(crc, value, d);
+		}
+
+		if (len & sizeof(u32)) {
+			u32 value = get_unaligned_le32(p);
+
+			CRC32C(crc, value, w);
+			p += sizeof(u32);
+		}
+	} else {
+		for (; len >= sizeof(u32); len -= sizeof(u32)) {
+			u32 value = get_unaligned_le32(p);
+
+			CRC32C(crc, value, w);
+			p += sizeof(u32);
+		}
+	}
+
+	if (len & sizeof(u16)) {
+		u16 value = get_unaligned_le16(p);
+
+		CRC32C(crc, value, h);
+		p += sizeof(u16);
+	}
+
+	if (len & sizeof(u8)) {
+		u8 value = *p++;
+
+		CRC32C(crc, value, b);
+	}
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_mips_init(void)
+{
+	if (cpu_have_feature(cpu_feature(MIPS_CRC32)))
+		static_branch_enable(&have_crc32);
+	return 0;
+}
+arch_initcall(crc32_mips_init);
+
+static void __exit crc32_mips_exit(void)
+{
+}
+module_exit(crc32_mips_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_crc32))
+		return CRC32_LE_OPTIMIZATION | CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Marcin Nowakowski <marcin.nowakowski at mips.com");
+MODULE_DESCRIPTION("CRC32 and CRC32C using optional MIPS instructions");
+MODULE_LICENSE("GPL v2");
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:34 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:34 -0800
Subject: [PATCH v4 09/19] s390/crc32: expose CRC32 functions through lib
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-10-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the s390 CRC32 assembly code into the lib directory and wire it up
to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/s390/crypto/crc32-vx.c to
arch/s390/lib/crc32-glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/s390/Kconfig                      |   1 +
 arch/s390/configs/debug_defconfig      |   1 -
 arch/s390/configs/defconfig            |   1 -
 arch/s390/crypto/Kconfig               |  12 -
 arch/s390/crypto/Makefile              |   2 -
 arch/s390/crypto/crc32-vx.c            | 306 -------------------------
 arch/s390/lib/Makefile                 |   3 +
 arch/s390/lib/crc32-glue.c             |  92 ++++++++
 arch/s390/{crypto => lib}/crc32-vx.h   |   0
 arch/s390/{crypto => lib}/crc32be-vx.c |   0
 arch/s390/{crypto => lib}/crc32le-vx.c |   0
 11 files changed, 96 insertions(+), 322 deletions(-)
 delete mode 100644 arch/s390/crypto/crc32-vx.c
 create mode 100644 arch/s390/lib/crc32-glue.c
 rename arch/s390/{crypto => lib}/crc32-vx.h (100%)
 rename arch/s390/{crypto => lib}/crc32be-vx.c (100%)
 rename arch/s390/{crypto => lib}/crc32le-vx.c (100%)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 0077969170e8..d272230cc885 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -70,10 +70,11 @@ config S390
 	select ARCH_BINFMT_ELF_STATE
 	select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
 	select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM
 	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
+	select ARCH_HAS_CRC32
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEBUG_WX
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index d8d227ab82de..f2a149b4fafd 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -793,11 +793,10 @@ CONFIG_CRYPTO_ZSTD=m
 CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_CRC32_S390=y
 CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_SHA1_S390=m
 CONFIG_CRYPTO_SHA256_S390=m
 CONFIG_CRYPTO_SHA3_256_S390=m
 CONFIG_CRYPTO_SHA3_512_S390=m
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index 6c2f2bb4fbf8..d521aabc31d7 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -780,11 +780,10 @@ CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_JITTERENTROPY_OSR=1
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_CRC32_S390=y
 CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_SHA1_S390=m
 CONFIG_CRYPTO_SHA256_S390=m
 CONFIG_CRYPTO_SHA3_256_S390=m
 CONFIG_CRYPTO_SHA3_512_S390=m
diff --git a/arch/s390/crypto/Kconfig b/arch/s390/crypto/Kconfig
index d3eb3a233693..b760232537f1 100644
--- a/arch/s390/crypto/Kconfig
+++ b/arch/s390/crypto/Kconfig
@@ -1,21 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 
 menu "Accelerated Cryptographic Algorithms for CPU (s390)"
 
-config CRYPTO_CRC32_S390
-	tristate "CRC32c and CRC32"
-	depends on S390
-	select CRYPTO_HASH
-	select CRC32
-	help
-	  CRC32c and CRC32 CRC algorithms
-
-	  Architecture: s390
-
-	  It is available with IBM z13 or later.
-
 config CRYPTO_SHA512_S390
 	tristate "Hash functions: SHA-384 and SHA-512"
 	depends on S390
 	select CRYPTO_HASH
 	help
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile
index a0cb96937c3d..14dafadbcbed 100644
--- a/arch/s390/crypto/Makefile
+++ b/arch/s390/crypto/Makefile
@@ -12,11 +12,9 @@ obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o
 obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
 obj-$(CONFIG_CRYPTO_PAES_S390) += paes_s390.o
 obj-$(CONFIG_CRYPTO_CHACHA_S390) += chacha_s390.o
 obj-$(CONFIG_S390_PRNG) += prng.o
 obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o
-obj-$(CONFIG_CRYPTO_CRC32_S390) += crc32-vx_s390.o
 obj-$(CONFIG_CRYPTO_HMAC_S390) += hmac_s390.o
 obj-y += arch_random.o
 
-crc32-vx_s390-y := crc32-vx.o crc32le-vx.o crc32be-vx.o
 chacha_s390-y := chacha-glue.o chacha-s390.o
diff --git a/arch/s390/crypto/crc32-vx.c b/arch/s390/crypto/crc32-vx.c
deleted file mode 100644
index 89a10337e6ea..000000000000
--- a/arch/s390/crypto/crc32-vx.c
+++ /dev/null
@@ -1,306 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Crypto-API module for CRC-32 algorithms implemented with the
- * z/Architecture Vector Extension Facility.
- *
- * Copyright IBM Corp. 2015
- * Author(s): Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
- */
-#define KMSG_COMPONENT	"crc32-vx"
-#define pr_fmt(fmt)	KMSG_COMPONENT ": " fmt
-
-#include <linux/module.h>
-#include <linux/cpufeature.h>
-#include <linux/crc32.h>
-#include <crypto/internal/hash.h>
-#include <asm/fpu.h>
-#include "crc32-vx.h"
-
-#define CRC32_BLOCK_SIZE	1
-#define CRC32_DIGEST_SIZE	4
-
-#define VX_MIN_LEN		64
-#define VX_ALIGNMENT		16L
-#define VX_ALIGN_MASK		(VX_ALIGNMENT - 1)
-
-struct crc_ctx {
-	u32 key;
-};
-
-struct crc_desc_ctx {
-	u32 crc;
-};
-
-/*
- * DEFINE_CRC32_VX() - Define a CRC-32 function using the vector extension
- *
- * Creates a function to perform a particular CRC-32 computation. Depending
- * on the message buffer, the hardware-accelerated or software implementation
- * is used.   Note that the message buffer is aligned to improve fetch
- * operations of VECTOR LOAD MULTIPLE instructions.
- *
- */
-#define DEFINE_CRC32_VX(___fname, ___crc32_vx, ___crc32_sw)		    \
-	static u32 __pure ___fname(u32 crc,				    \
-				unsigned char const *data, size_t datalen)  \
-	{								    \
-		unsigned long prealign, aligned, remaining;		    \
-		DECLARE_KERNEL_FPU_ONSTACK16(vxstate);			    \
-									    \
-		if (datalen < VX_MIN_LEN + VX_ALIGN_MASK)		    \
-			return ___crc32_sw(crc, data, datalen);		    \
-									    \
-		if ((unsigned long)data & VX_ALIGN_MASK) {		    \
-			prealign = VX_ALIGNMENT -			    \
-				  ((unsigned long)data & VX_ALIGN_MASK);    \
-			datalen -= prealign;				    \
-			crc = ___crc32_sw(crc, data, prealign);		    \
-			data = (void *)((unsigned long)data + prealign);    \
-		}							    \
-									    \
-		aligned = datalen & ~VX_ALIGN_MASK;			    \
-		remaining = datalen & VX_ALIGN_MASK;			    \
-									    \
-		kernel_fpu_begin(&vxstate, KERNEL_VXR_LOW);		    \
-		crc = ___crc32_vx(crc, data, aligned);			    \
-		kernel_fpu_end(&vxstate, KERNEL_VXR_LOW);		    \
-									    \
-		if (remaining)						    \
-			crc = ___crc32_sw(crc, data + aligned, remaining);  \
-									    \
-		return crc;						    \
-	}
-
-DEFINE_CRC32_VX(crc32_le_vx, crc32_le_vgfm_16, crc32_le)
-DEFINE_CRC32_VX(crc32_be_vx, crc32_be_vgfm_16, crc32_be)
-DEFINE_CRC32_VX(crc32c_le_vx, crc32c_le_vgfm_16, __crc32c_le)
-
-
-static int crc32_vx_cra_init_zero(struct crypto_tfm *tfm)
-{
-	struct crc_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = 0;
-	return 0;
-}
-
-static int crc32_vx_cra_init_invert(struct crypto_tfm *tfm)
-{
-	struct crc_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = ~0;
-	return 0;
-}
-
-static int crc32_vx_init(struct shash_desc *desc)
-{
-	struct crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
-	struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = mctx->key;
-	return 0;
-}
-
-static int crc32_vx_setkey(struct crypto_shash *tfm, const u8 *newkey,
-			   unsigned int newkeylen)
-{
-	struct crc_ctx *mctx = crypto_shash_ctx(tfm);
-
-	if (newkeylen != sizeof(mctx->key))
-		return -EINVAL;
-	mctx->key = le32_to_cpu(*(__le32 *)newkey);
-	return 0;
-}
-
-static int crc32be_vx_setkey(struct crypto_shash *tfm, const u8 *newkey,
-			     unsigned int newkeylen)
-{
-	struct crc_ctx *mctx = crypto_shash_ctx(tfm);
-
-	if (newkeylen != sizeof(mctx->key))
-		return -EINVAL;
-	mctx->key = be32_to_cpu(*(__be32 *)newkey);
-	return 0;
-}
-
-static int crc32le_vx_final(struct shash_desc *desc, u8 *out)
-{
-	struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	*(__le32 *)out = cpu_to_le32p(&ctx->crc);
-	return 0;
-}
-
-static int crc32be_vx_final(struct shash_desc *desc, u8 *out)
-{
-	struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	*(__be32 *)out = cpu_to_be32p(&ctx->crc);
-	return 0;
-}
-
-static int crc32c_vx_final(struct shash_desc *desc, u8 *out)
-{
-	struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	/*
-	 * Perform a final XOR with 0xFFFFFFFF to be in sync
-	 * with the generic crc32c shash implementation.
-	 */
-	*(__le32 *)out = ~cpu_to_le32p(&ctx->crc);
-	return 0;
-}
-
-static int __crc32le_vx_finup(u32 *crc, const u8 *data, unsigned int len,
-			      u8 *out)
-{
-	*(__le32 *)out = cpu_to_le32(crc32_le_vx(*crc, data, len));
-	return 0;
-}
-
-static int __crc32be_vx_finup(u32 *crc, const u8 *data, unsigned int len,
-			      u8 *out)
-{
-	*(__be32 *)out = cpu_to_be32(crc32_be_vx(*crc, data, len));
-	return 0;
-}
-
-static int __crc32c_vx_finup(u32 *crc, const u8 *data, unsigned int len,
-			     u8 *out)
-{
-	/*
-	 * Perform a final XOR with 0xFFFFFFFF to be in sync
-	 * with the generic crc32c shash implementation.
-	 */
-	*(__le32 *)out = ~cpu_to_le32(crc32c_le_vx(*crc, data, len));
-	return 0;
-}
-
-
-#define CRC32_VX_FINUP(alg, func)					      \
-	static int alg ## _vx_finup(struct shash_desc *desc, const u8 *data,  \
-				   unsigned int datalen, u8 *out)	      \
-	{								      \
-		return __ ## alg ## _vx_finup(shash_desc_ctx(desc),	      \
-					      data, datalen, out);	      \
-	}
-
-CRC32_VX_FINUP(crc32le, crc32_le_vx)
-CRC32_VX_FINUP(crc32be, crc32_be_vx)
-CRC32_VX_FINUP(crc32c, crc32c_le_vx)
-
-#define CRC32_VX_DIGEST(alg, func)					      \
-	static int alg ## _vx_digest(struct shash_desc *desc, const u8 *data, \
-				     unsigned int len, u8 *out)		      \
-	{								      \
-		return __ ## alg ## _vx_finup(crypto_shash_ctx(desc->tfm),    \
-					      data, len, out);		      \
-	}
-
-CRC32_VX_DIGEST(crc32le, crc32_le_vx)
-CRC32_VX_DIGEST(crc32be, crc32_be_vx)
-CRC32_VX_DIGEST(crc32c, crc32c_le_vx)
-
-#define CRC32_VX_UPDATE(alg, func)					      \
-	static int alg ## _vx_update(struct shash_desc *desc, const u8 *data, \
-				     unsigned int datalen)		      \
-	{								      \
-		struct crc_desc_ctx *ctx = shash_desc_ctx(desc);	      \
-		ctx->crc = func(ctx->crc, data, datalen);		      \
-		return 0;						      \
-	}
-
-CRC32_VX_UPDATE(crc32le, crc32_le_vx)
-CRC32_VX_UPDATE(crc32be, crc32_be_vx)
-CRC32_VX_UPDATE(crc32c, crc32c_le_vx)
-
-
-static struct shash_alg crc32_vx_algs[] = {
-	/* CRC-32 LE */
-	{
-		.init		=	crc32_vx_init,
-		.setkey		=	crc32_vx_setkey,
-		.update		=	crc32le_vx_update,
-		.final		=	crc32le_vx_final,
-		.finup		=	crc32le_vx_finup,
-		.digest		=	crc32le_vx_digest,
-		.descsize	=	sizeof(struct crc_desc_ctx),
-		.digestsize	=	CRC32_DIGEST_SIZE,
-		.base		=	{
-			.cra_name	 = "crc32",
-			.cra_driver_name = "crc32-vx",
-			.cra_priority	 = 200,
-			.cra_flags	 = CRYPTO_ALG_OPTIONAL_KEY,
-			.cra_blocksize	 = CRC32_BLOCK_SIZE,
-			.cra_ctxsize	 = sizeof(struct crc_ctx),
-			.cra_module	 = THIS_MODULE,
-			.cra_init	 = crc32_vx_cra_init_zero,
-		},
-	},
-	/* CRC-32 BE */
-	{
-		.init		=	crc32_vx_init,
-		.setkey		=	crc32be_vx_setkey,
-		.update		=	crc32be_vx_update,
-		.final		=	crc32be_vx_final,
-		.finup		=	crc32be_vx_finup,
-		.digest		=	crc32be_vx_digest,
-		.descsize	=	sizeof(struct crc_desc_ctx),
-		.digestsize	=	CRC32_DIGEST_SIZE,
-		.base		=	{
-			.cra_name	 = "crc32be",
-			.cra_driver_name = "crc32be-vx",
-			.cra_priority	 = 200,
-			.cra_flags	 = CRYPTO_ALG_OPTIONAL_KEY,
-			.cra_blocksize	 = CRC32_BLOCK_SIZE,
-			.cra_ctxsize	 = sizeof(struct crc_ctx),
-			.cra_module	 = THIS_MODULE,
-			.cra_init	 = crc32_vx_cra_init_zero,
-		},
-	},
-	/* CRC-32C LE */
-	{
-		.init		=	crc32_vx_init,
-		.setkey		=	crc32_vx_setkey,
-		.update		=	crc32c_vx_update,
-		.final		=	crc32c_vx_final,
-		.finup		=	crc32c_vx_finup,
-		.digest		=	crc32c_vx_digest,
-		.descsize	=	sizeof(struct crc_desc_ctx),
-		.digestsize	=	CRC32_DIGEST_SIZE,
-		.base		=	{
-			.cra_name	 = "crc32c",
-			.cra_driver_name = "crc32c-vx",
-			.cra_priority	 = 200,
-			.cra_flags	 = CRYPTO_ALG_OPTIONAL_KEY,
-			.cra_blocksize	 = CRC32_BLOCK_SIZE,
-			.cra_ctxsize	 = sizeof(struct crc_ctx),
-			.cra_module	 = THIS_MODULE,
-			.cra_init	 = crc32_vx_cra_init_invert,
-		},
-	},
-};
-
-
-static int __init crc_vx_mod_init(void)
-{
-	return crypto_register_shashes(crc32_vx_algs,
-				       ARRAY_SIZE(crc32_vx_algs));
-}
-
-static void __exit crc_vx_mod_exit(void)
-{
-	crypto_unregister_shashes(crc32_vx_algs, ARRAY_SIZE(crc32_vx_algs));
-}
-
-module_cpu_feature_match(S390_CPU_FEATURE_VXRS, crc_vx_mod_init);
-module_exit(crc_vx_mod_exit);
-
-MODULE_AUTHOR("Hendrik Brueckner <brueckner at linux.vnet.ibm.com>");
-MODULE_DESCRIPTION("CRC-32 algorithms using z/Architecture Vector Extension Facility");
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS_CRYPTO("crc32");
-MODULE_ALIAS_CRYPTO("crc32-vx");
-MODULE_ALIAS_CRYPTO("crc32c");
-MODULE_ALIAS_CRYPTO("crc32c-vx");
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index f43f897d3fc0..14bbfe50033c 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -22,5 +22,8 @@ obj-$(CONFIG_S390_MODULES_SANITY_TEST) += test_modules.o
 obj-$(CONFIG_S390_MODULES_SANITY_TEST_HELPERS) += test_modules_helpers.o
 
 lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 
 obj-$(CONFIG_EXPOLINE_EXTERN) += expoline.o
+
+obj-$(CONFIG_CRC32_ARCH) += crc32-s390.o
+crc32-s390-y := crc32-glue.o crc32le-vx.o crc32be-vx.o
diff --git a/arch/s390/lib/crc32-glue.c b/arch/s390/lib/crc32-glue.c
new file mode 100644
index 000000000000..137080e61f90
--- /dev/null
+++ b/arch/s390/lib/crc32-glue.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CRC-32 implemented with the z/Architecture Vector Extension Facility.
+ *
+ * Copyright IBM Corp. 2015
+ * Author(s): Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
+ */
+#define KMSG_COMPONENT	"crc32-vx"
+#define pr_fmt(fmt)	KMSG_COMPONENT ": " fmt
+
+#include <linux/module.h>
+#include <linux/cpufeature.h>
+#include <linux/crc32.h>
+#include <asm/fpu.h>
+#include "crc32-vx.h"
+
+#define VX_MIN_LEN		64
+#define VX_ALIGNMENT		16L
+#define VX_ALIGN_MASK		(VX_ALIGNMENT - 1)
+
+static DEFINE_STATIC_KEY_FALSE(have_vxrs);
+
+/*
+ * DEFINE_CRC32_VX() - Define a CRC-32 function using the vector extension
+ *
+ * Creates a function to perform a particular CRC-32 computation. Depending
+ * on the message buffer, the hardware-accelerated or software implementation
+ * is used.   Note that the message buffer is aligned to improve fetch
+ * operations of VECTOR LOAD MULTIPLE instructions.
+ */
+#define DEFINE_CRC32_VX(___fname, ___crc32_vx, ___crc32_sw)		    \
+	u32 ___fname(u32 crc, const u8 *data, size_t datalen)		    \
+	{								    \
+		unsigned long prealign, aligned, remaining;		    \
+		DECLARE_KERNEL_FPU_ONSTACK16(vxstate);			    \
+									    \
+		if (datalen < VX_MIN_LEN + VX_ALIGN_MASK ||		    \
+		    !static_branch_likely(&have_vxrs))			    \
+			return ___crc32_sw(crc, data, datalen);		    \
+									    \
+		if ((unsigned long)data & VX_ALIGN_MASK) {		    \
+			prealign = VX_ALIGNMENT -			    \
+				  ((unsigned long)data & VX_ALIGN_MASK);    \
+			datalen -= prealign;				    \
+			crc = ___crc32_sw(crc, data, prealign);		    \
+			data = (void *)((unsigned long)data + prealign);    \
+		}							    \
+									    \
+		aligned = datalen & ~VX_ALIGN_MASK;			    \
+		remaining = datalen & VX_ALIGN_MASK;			    \
+									    \
+		kernel_fpu_begin(&vxstate, KERNEL_VXR_LOW);		    \
+		crc = ___crc32_vx(crc, data, aligned);			    \
+		kernel_fpu_end(&vxstate, KERNEL_VXR_LOW);		    \
+									    \
+		if (remaining)						    \
+			crc = ___crc32_sw(crc, data + aligned, remaining);  \
+									    \
+		return crc;						    \
+	}								    \
+	EXPORT_SYMBOL(___fname);
+
+DEFINE_CRC32_VX(crc32_le_arch, crc32_le_vgfm_16, crc32_le_base)
+DEFINE_CRC32_VX(crc32_be_arch, crc32_be_vgfm_16, crc32_be_base)
+DEFINE_CRC32_VX(crc32c_le_arch, crc32c_le_vgfm_16, crc32c_le_base)
+
+static int __init crc32_s390_init(void)
+{
+	if (cpu_have_feature(S390_CPU_FEATURE_VXRS))
+		static_branch_enable(&have_vxrs);
+	return 0;
+}
+arch_initcall(crc32_s390_init);
+
+static void __exit crc32_s390_exit(void)
+{
+}
+module_exit(crc32_s390_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_vxrs))
+		return CRC32_LE_OPTIMIZATION |
+		       CRC32_BE_OPTIMIZATION |
+		       CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Hendrik Brueckner <brueckner at linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("CRC-32 algorithms using z/Architecture Vector Extension Facility");
+MODULE_LICENSE("GPL");
diff --git a/arch/s390/crypto/crc32-vx.h b/arch/s390/lib/crc32-vx.h
similarity index 100%
rename from arch/s390/crypto/crc32-vx.h
rename to arch/s390/lib/crc32-vx.h
diff --git a/arch/s390/crypto/crc32be-vx.c b/arch/s390/lib/crc32be-vx.c
similarity index 100%
rename from arch/s390/crypto/crc32be-vx.c
rename to arch/s390/lib/crc32be-vx.c
diff --git a/arch/s390/crypto/crc32le-vx.c b/arch/s390/lib/crc32le-vx.c
similarity index 100%
rename from arch/s390/crypto/crc32le-vx.c
rename to arch/s390/lib/crc32le-vx.c
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:35 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:35 -0800
Subject: [PATCH v4 10/19] sparc/crc32: expose CRC32 functions through lib
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-11-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the sparc CRC32C assembly code into the lib directory and wire it
up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/sparc/crypto/crc32c_glue.c to
arch/sparc/lib/crc32_glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/sparc/Kconfig                      |   1 +
 arch/sparc/crypto/Kconfig               |  10 --
 arch/sparc/crypto/Makefile              |   4 -
 arch/sparc/crypto/crc32c_glue.c         | 184 ------------------------
 arch/sparc/lib/Makefile                 |   2 +
 arch/sparc/lib/crc32_glue.c             |  93 ++++++++++++
 arch/sparc/{crypto => lib}/crc32c_asm.S |   2 +-
 7 files changed, 97 insertions(+), 199 deletions(-)
 delete mode 100644 arch/sparc/crypto/crc32c_glue.c
 create mode 100644 arch/sparc/lib/crc32_glue.c
 rename arch/sparc/{crypto => lib}/crc32c_asm.S (92%)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index dcfdb7f1dae9..0f88123925a4 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -108,10 +108,11 @@ config SPARC64
 	select ARCH_HAS_GIGANTIC_PAGE
 	select HAVE_SOFTIRQ_ON_OWN_STACK
 	select HAVE_SETUP_PER_CPU_AREA
 	select NEED_PER_CPU_EMBED_FIRST_CHUNK
 	select NEED_PER_CPU_PAGE_FIRST_CHUNK
+	select ARCH_HAS_CRC32
 
 config ARCH_PROC_KCORE_TEXT
 	def_bool y
 
 config CPU_BIG_ENDIAN
diff --git a/arch/sparc/crypto/Kconfig b/arch/sparc/crypto/Kconfig
index cfe5102b1c68..e858597de89d 100644
--- a/arch/sparc/crypto/Kconfig
+++ b/arch/sparc/crypto/Kconfig
@@ -14,20 +14,10 @@ config CRYPTO_DES_SPARC64
 	  Length-preserving ciphers: DES with ECB and CBC modes
 	  Length-preserving ciphers: Tripe DES EDE with ECB and CBC modes
 
 	  Architecture: sparc64
 
-config CRYPTO_CRC32C_SPARC64
-	tristate "CRC32c"
-	depends on SPARC64
-	select CRYPTO_HASH
-	select CRC32
-	help
-	  CRC32c CRC algorithm with the iSCSI polynomial (RFC 3385 and RFC 3720)
-
-	  Architecture: sparc64
-
 config CRYPTO_MD5_SPARC64
 	tristate "Digests: MD5"
 	depends on SPARC64
 	select CRYPTO_MD5
 	select CRYPTO_HASH
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile
index d257186c27d1..a2d7fca40cb4 100644
--- a/arch/sparc/crypto/Makefile
+++ b/arch/sparc/crypto/Makefile
@@ -10,17 +10,13 @@ obj-$(CONFIG_CRYPTO_MD5_SPARC64) += md5-sparc64.o
 
 obj-$(CONFIG_CRYPTO_AES_SPARC64) += aes-sparc64.o
 obj-$(CONFIG_CRYPTO_DES_SPARC64) += des-sparc64.o
 obj-$(CONFIG_CRYPTO_CAMELLIA_SPARC64) += camellia-sparc64.o
 
-obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o
-
 sha1-sparc64-y := sha1_asm.o sha1_glue.o
 sha256-sparc64-y := sha256_asm.o sha256_glue.o
 sha512-sparc64-y := sha512_asm.o sha512_glue.o
 md5-sparc64-y := md5_asm.o md5_glue.o
 
 aes-sparc64-y := aes_asm.o aes_glue.o
 des-sparc64-y := des_asm.o des_glue.o
 camellia-sparc64-y := camellia_asm.o camellia_glue.o
-
-crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o
diff --git a/arch/sparc/crypto/crc32c_glue.c b/arch/sparc/crypto/crc32c_glue.c
deleted file mode 100644
index 913b9a09e885..000000000000
--- a/arch/sparc/crypto/crc32c_glue.c
+++ /dev/null
@@ -1,184 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Glue code for CRC32C optimized for sparc64 crypto opcodes.
- *
- * This is based largely upon arch/x86/crypto/crc32c-intel.c
- *
- * Copyright (C) 2008 Intel Corporation
- * Authors: Austin Zhang <austin_zhang at linux.intel.com>
- *          Kent Liu <kent.liu at intel.com>
- */
-
-#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/crc32.h>
-
-#include <crypto/internal/hash.h>
-
-#include <asm/pstate.h>
-#include <asm/elf.h>
-#include <linux/unaligned.h>
-
-#include "opcodes.h"
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set
- * the seed.
- */
-static int crc32c_sparc64_setkey(struct crypto_shash *hash, const u8 *key,
-				 unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = get_unaligned_le32(key);
-	return 0;
-}
-
-static int crc32c_sparc64_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = *mctx;
-
-	return 0;
-}
-
-extern void crc32c_sparc64(u32 *crcp, const u64 *data, unsigned int len);
-
-static u32 crc32c_compute(u32 crc, const u8 *data, unsigned int len)
-{
-	unsigned int n = -(uintptr_t)data & 7;
-
-	if (n) {
-		/* Data isn't 8-byte aligned.  Align it. */
-		n = min(n, len);
-		crc = __crc32c_le(crc, data, n);
-		data += n;
-		len -= n;
-	}
-	n = len & ~7U;
-	if (n) {
-		crc32c_sparc64(&crc, (const u64 *)data, n);
-		data += n;
-		len -= n;
-	}
-	if (len)
-		crc = __crc32c_le(crc, data, len);
-	return crc;
-}
-
-static int crc32c_sparc64_update(struct shash_desc *desc, const u8 *data,
-				 unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = crc32c_compute(*crcp, data, len);
-	return 0;
-}
-
-static int __crc32c_sparc64_finup(const u32 *crcp, const u8 *data,
-				  unsigned int len, u8 *out)
-{
-	put_unaligned_le32(~crc32c_compute(*crcp, data, len), out);
-	return 0;
-}
-
-static int crc32c_sparc64_finup(struct shash_desc *desc, const u8 *data,
-				unsigned int len, u8 *out)
-{
-	return __crc32c_sparc64_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32c_sparc64_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	put_unaligned_le32(~*crcp, out);
-	return 0;
-}
-
-static int crc32c_sparc64_digest(struct shash_desc *desc, const u8 *data,
-				 unsigned int len, u8 *out)
-{
-	return __crc32c_sparc64_finup(crypto_shash_ctx(desc->tfm), data, len,
-				      out);
-}
-
-static int crc32c_sparc64_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = ~0;
-
-	return 0;
-}
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-static struct shash_alg alg = {
-	.setkey			=	crc32c_sparc64_setkey,
-	.init			=	crc32c_sparc64_init,
-	.update			=	crc32c_sparc64_update,
-	.final			=	crc32c_sparc64_final,
-	.finup			=	crc32c_sparc64_finup,
-	.digest			=	crc32c_sparc64_digest,
-	.descsize		=	sizeof(u32),
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.base			=	{
-		.cra_name		=	"crc32c",
-		.cra_driver_name	=	"crc32c-sparc64",
-		.cra_priority		=	SPARC_CR_OPCODE_PRIORITY,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(u32),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	crc32c_sparc64_cra_init,
-	}
-};
-
-static bool __init sparc64_has_crc32c_opcode(void)
-{
-	unsigned long cfr;
-
-	if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
-		return false;
-
-	__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
-	if (!(cfr & CFR_CRC32C))
-		return false;
-
-	return true;
-}
-
-static int __init crc32c_sparc64_mod_init(void)
-{
-	if (sparc64_has_crc32c_opcode()) {
-		pr_info("Using sparc64 crc32c opcode optimized CRC32C implementation\n");
-		return crypto_register_shash(&alg);
-	}
-	pr_info("sparc64 crc32c opcode not available.\n");
-	return -ENODEV;
-}
-
-static void __exit crc32c_sparc64_mod_fini(void)
-{
-	crypto_unregister_shash(&alg);
-}
-
-module_init(crc32c_sparc64_mod_init);
-module_exit(crc32c_sparc64_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated");
-
-MODULE_ALIAS_CRYPTO("crc32c");
-
-#include "crop_devid.c"
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index ee5091dd67ed..5724d0f356eb 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -51,5 +51,7 @@ lib-$(CONFIG_SPARC64) += copy_in_user.o memmove.o
 lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o
 
 obj-$(CONFIG_SPARC64) += iomap.o
 obj-$(CONFIG_SPARC32) += atomic32.o
 obj-$(CONFIG_SPARC64) += PeeCeeI.o
+obj-$(CONFIG_CRC32_ARCH) += crc32-sparc.o
+crc32-sparc-y := crc32_glue.o crc32c_asm.o
diff --git a/arch/sparc/lib/crc32_glue.c b/arch/sparc/lib/crc32_glue.c
new file mode 100644
index 000000000000..41076d2b1fd2
--- /dev/null
+++ b/arch/sparc/lib/crc32_glue.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Glue code for CRC32C optimized for sparc64 crypto opcodes.
+ *
+ * This is based largely upon arch/x86/crypto/crc32c-intel.c
+ *
+ * Copyright (C) 2008 Intel Corporation
+ * Authors: Austin Zhang <austin_zhang at linux.intel.com>
+ *          Kent Liu <kent.liu at intel.com>
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/crc32.h>
+#include <asm/pstate.h>
+#include <asm/elf.h>
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32c_opcode);
+
+u32 crc32_le_arch(u32 crc, const u8 *data, size_t len)
+{
+	return crc32_le_base(crc, data, len);
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+void crc32c_sparc64(u32 *crcp, const u64 *data, size_t len);
+
+u32 crc32c_le_arch(u32 crc, const u8 *data, size_t len)
+{
+	size_t n = -(uintptr_t)data & 7;
+
+	if (!static_branch_likely(&have_crc32c_opcode))
+		return crc32c_le_base(crc, data, len);
+
+	if (n) {
+		/* Data isn't 8-byte aligned.  Align it. */
+		n = min(n, len);
+		crc = crc32c_le_base(crc, data, n);
+		data += n;
+		len -= n;
+	}
+	n = len & ~7U;
+	if (n) {
+		crc32c_sparc64(&crc, (const u64 *)data, n);
+		data += n;
+		len -= n;
+	}
+	if (len)
+		crc = crc32c_le_base(crc, data, len);
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *data, size_t len)
+{
+	return crc32_be_base(crc, data, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_sparc_init(void)
+{
+	unsigned long cfr;
+
+	if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
+		return 0;
+
+	__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
+	if (!(cfr & CFR_CRC32C))
+		return 0;
+
+	static_branch_enable(&have_crc32c_opcode);
+	pr_info("Using sparc64 crc32c opcode optimized CRC32C implementation\n");
+	return 0;
+}
+arch_initcall(crc32_sparc_init);
+
+static void __exit crc32_sparc_exit(void)
+{
+}
+module_exit(crc32_sparc_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_crc32c_opcode))
+		return CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated");
diff --git a/arch/sparc/crypto/crc32c_asm.S b/arch/sparc/lib/crc32c_asm.S
similarity index 92%
rename from arch/sparc/crypto/crc32c_asm.S
rename to arch/sparc/lib/crc32c_asm.S
index b8659a479242..ee454fa6aed6 100644
--- a/arch/sparc/crypto/crc32c_asm.S
+++ b/arch/sparc/lib/crc32c_asm.S
@@ -1,11 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #include <linux/linkage.h>
 #include <asm/visasm.h>
 #include <asm/asi.h>
 
-#include "opcodes.h"
+#include "../crypto/opcodes.h"
 
 ENTRY(crc32c_sparc64)
 	/* %o0=crc32p, %o1=data_ptr, %o2=len */
 	VISEntryHalf
 	lda	[%o0] ASI_PL, %f1
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:36 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:36 -0800
Subject: [PATCH v4 11/19] x86/crc32: update prototype for crc_pcl()
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-12-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

- Change the len parameter from unsigned int to size_t, so that the
  library function which takes a size_t can safely use this code.

- Rename to crc32c_x86_3way() which is much clearer.

- Move the crc parameter to the front, as this is the usual convention.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/x86/crypto/crc32c-intel_glue.c       |  7 ++-
 arch/x86/crypto/crc32c-pcl-intel-asm_64.S | 63 ++++++++++++-----------
 2 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c
index 52c5d47ef5a1..603d159de400 100644
--- a/arch/x86/crypto/crc32c-intel_glue.c
+++ b/arch/x86/crypto/crc32c-intel_glue.c
@@ -39,12 +39,11 @@
  * size is >= 512 to account
  * for fpu state save/restore overhead.
  */
 #define CRC32C_PCL_BREAKEVEN	512
 
-asmlinkage unsigned int crc_pcl(const u8 *buffer, unsigned int len,
-				unsigned int crc_init);
+asmlinkage u32 crc32c_x86_3way(u32 crc, const u8 *buffer, size_t len);
 #endif /* CONFIG_X86_64 */
 
 static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length)
 {
 	while (length--) {
@@ -157,11 +156,11 @@ static int crc32c_pcl_intel_update(struct shash_desc *desc, const u8 *data,
 	 * use faster PCL version if datasize is large enough to
 	 * overcome kernel fpu state save/restore overhead
 	 */
 	if (len >= CRC32C_PCL_BREAKEVEN && crypto_simd_usable()) {
 		kernel_fpu_begin();
-		*crcp = crc_pcl(data, len, *crcp);
+		*crcp = crc32c_x86_3way(*crcp, data, len);
 		kernel_fpu_end();
 	} else
 		*crcp = crc32c_intel_le_hw(*crcp, data, len);
 	return 0;
 }
@@ -169,11 +168,11 @@ static int crc32c_pcl_intel_update(struct shash_desc *desc, const u8 *data,
 static int __crc32c_pcl_intel_finup(u32 *crcp, const u8 *data, unsigned int len,
 				u8 *out)
 {
 	if (len >= CRC32C_PCL_BREAKEVEN && crypto_simd_usable()) {
 		kernel_fpu_begin();
-		*(__le32 *)out = ~cpu_to_le32(crc_pcl(data, len, *crcp));
+		*(__le32 *)out = ~cpu_to_le32(crc32c_x86_3way(*crcp, data, len));
 		kernel_fpu_end();
 	} else
 		*(__le32 *)out =
 			~cpu_to_le32(crc32c_intel_le_hw(*crcp, data, len));
 	return 0;
diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
index 752812bc4991..9b8770503bbc 100644
--- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
@@ -50,19 +50,20 @@
 
 # Define threshold below which buffers are considered "small" and routed to
 # regular CRC code that does not interleave the CRC instructions.
 #define SMALL_SIZE 200
 
-# unsigned int crc_pcl(const u8 *buffer, unsigned int len, unsigned int crc_init);
+# u32 crc32c_x86_3way(u32 crc, const u8 *buffer, size_t len);
 
 .text
-SYM_FUNC_START(crc_pcl)
-#define    bufp		  %rdi
-#define    bufp_d	  %edi
-#define    len		  %esi
-#define    crc_init	  %edx
-#define    crc_init_q	  %rdx
+SYM_FUNC_START(crc32c_x86_3way)
+#define    crc0		  %edi
+#define    crc0_q	  %rdi
+#define    bufp		  %rsi
+#define    bufp_d	  %esi
+#define    len		  %rdx
+#define    len_dw	  %edx
 #define    n_misaligned	  %ecx /* overlaps chunk_bytes! */
 #define    n_misaligned_q %rcx
 #define    chunk_bytes	  %ecx /* overlaps n_misaligned! */
 #define    chunk_bytes_q  %rcx
 #define    crc1		  %r8
@@ -83,13 +84,13 @@ SYM_FUNC_START(crc_pcl)
 	# Process 1 <= n_misaligned <= 7 bytes individually in order to align
 	# the remaining data to an 8-byte boundary.
 .Ldo_align:
 	movq	(bufp), %rax
 	add	n_misaligned_q, bufp
-	sub	n_misaligned, len
+	sub	n_misaligned_q, len
 .Lalign_loop:
-	crc32b	%al, crc_init		# compute crc32 of 1-byte
+	crc32b	%al, crc0		# compute crc32 of 1-byte
 	shr	$8, %rax		# get next byte
 	dec	n_misaligned
 	jne     .Lalign_loop
 .Laligned:
 
@@ -100,11 +101,11 @@ SYM_FUNC_START(crc_pcl)
 	cmp	$128*24, len
 	jae     .Lfull_block
 
 .Lpartial_block:
 	# Compute floor(len / 24) to get num qwords to process from each lane.
-	imul	$2731, len, %eax	# 2731 = ceil(2^16 / 24)
+	imul	$2731, len_dw, %eax	# 2731 = ceil(2^16 / 24)
 	shr	$16, %eax
 	jmp	.Lcrc_3lanes
 
 .Lfull_block:
 	# Processing 128 qwords from each lane.
@@ -123,20 +124,20 @@ SYM_FUNC_START(crc_pcl)
 	jl	.Lcrc_3lanes_4x_done
 
 	# Unroll the loop by a factor of 4 to reduce the overhead of the loop
 	# bookkeeping instructions, which can compete with crc32q for the ALUs.
 .Lcrc_3lanes_4x_loop:
-	crc32q	(bufp), crc_init_q
+	crc32q	(bufp), crc0_q
 	crc32q	(bufp,chunk_bytes_q), crc1
 	crc32q	(bufp,chunk_bytes_q,2), crc2
-	crc32q	8(bufp), crc_init_q
+	crc32q	8(bufp), crc0_q
 	crc32q	8(bufp,chunk_bytes_q), crc1
 	crc32q	8(bufp,chunk_bytes_q,2), crc2
-	crc32q	16(bufp), crc_init_q
+	crc32q	16(bufp), crc0_q
 	crc32q	16(bufp,chunk_bytes_q), crc1
 	crc32q	16(bufp,chunk_bytes_q,2), crc2
-	crc32q	24(bufp), crc_init_q
+	crc32q	24(bufp), crc0_q
 	crc32q	24(bufp,chunk_bytes_q), crc1
 	crc32q	24(bufp,chunk_bytes_q,2), crc2
 	add	$32, bufp
 	sub	$4, %eax
 	jge	.Lcrc_3lanes_4x_loop
@@ -144,42 +145,42 @@ SYM_FUNC_START(crc_pcl)
 .Lcrc_3lanes_4x_done:
 	add	$4, %eax
 	jz	.Lcrc_3lanes_last_qword
 
 .Lcrc_3lanes_1x_loop:
-	crc32q	(bufp), crc_init_q
+	crc32q	(bufp), crc0_q
 	crc32q	(bufp,chunk_bytes_q), crc1
 	crc32q	(bufp,chunk_bytes_q,2), crc2
 	add	$8, bufp
 	dec	%eax
 	jnz	.Lcrc_3lanes_1x_loop
 
 .Lcrc_3lanes_last_qword:
-	crc32q	(bufp), crc_init_q
+	crc32q	(bufp), crc0_q
 	crc32q	(bufp,chunk_bytes_q), crc1
 # SKIP  crc32q	(bufp,chunk_bytes_q,2), crc2	; Don't do this one yet
 
 	################################################################
 	## 4) Combine three results:
 	################################################################
 
 	lea	(K_table-8)(%rip), %rax		# first entry is for idx 1
 	pmovzxdq (%rax,chunk_bytes_q), %xmm0	# 2 consts: K1:K2
 	lea	(chunk_bytes,chunk_bytes,2), %eax # chunk_bytes * 3
-	sub	%eax, len			# len -= chunk_bytes * 3
+	sub	%rax, len			# len -= chunk_bytes * 3
 
-	movq	crc_init_q, %xmm1		# CRC for block 1
+	movq	crc0_q, %xmm1			# CRC for block 1
 	pclmulqdq $0x00, %xmm0, %xmm1		# Multiply by K2
 
 	movq    crc1, %xmm2			# CRC for block 2
 	pclmulqdq $0x10, %xmm0, %xmm2		# Multiply by K1
 
 	pxor    %xmm2,%xmm1
 	movq    %xmm1, %rax
 	xor	(bufp,chunk_bytes_q,2), %rax
-	mov	crc2, crc_init_q
-	crc32	%rax, crc_init_q
+	mov	crc2, crc0_q
+	crc32	%rax, crc0_q
 	lea	8(bufp,chunk_bytes_q,2), bufp
 
 	################################################################
 	## 5) If more blocks remain, goto (2):
 	################################################################
@@ -191,38 +192,38 @@ SYM_FUNC_START(crc_pcl)
 
 	#######################################################################
 	## 6) Process any remainder without interleaving:
 	#######################################################################
 .Lsmall:
-	test	len, len
+	test	len_dw, len_dw
 	jz	.Ldone
-	mov	len, %eax
+	mov	len_dw, %eax
 	shr	$3, %eax
 	jz	.Ldo_dword
 .Ldo_qwords:
-	crc32q	(bufp), crc_init_q
+	crc32q	(bufp), crc0_q
 	add	$8, bufp
 	dec	%eax
 	jnz	.Ldo_qwords
 .Ldo_dword:
-	test	$4, len
+	test	$4, len_dw
 	jz	.Ldo_word
-	crc32l	(bufp), crc_init
+	crc32l	(bufp), crc0
 	add	$4, bufp
 .Ldo_word:
-	test	$2, len
+	test	$2, len_dw
 	jz	.Ldo_byte
-	crc32w	(bufp), crc_init
+	crc32w	(bufp), crc0
 	add	$2, bufp
 .Ldo_byte:
-	test	$1, len
+	test	$1, len_dw
 	jz	.Ldone
-	crc32b	(bufp), crc_init
+	crc32b	(bufp), crc0
 .Ldone:
-	mov	crc_init, %eax
+	mov	crc0, %eax
         RET
-SYM_FUNC_END(crc_pcl)
+SYM_FUNC_END(crc32c_x86_3way)
 
 .section	.rodata, "a", @progbits
 	################################################################
 	## PCLMULQDQ tables
 	## Table is 128 entries x 2 words (8 bytes) each
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:37 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:37 -0800
Subject: [PATCH v4 12/19] x86/crc32: update prototype for crc32_pclmul_le_16()
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-13-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

- Change the len parameter from unsigned int to size_t, so that the
  library function which takes a size_t can safely use this code.

- Move the crc parameter to the front, as this is the usual convention.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/x86/crypto/crc32-pclmul_asm.S  | 19 +++++++++----------
 arch/x86/crypto/crc32-pclmul_glue.c |  4 ++--
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/arch/x86/crypto/crc32-pclmul_asm.S b/arch/x86/crypto/crc32-pclmul_asm.S
index 5d31137e2c7d..f9637789cac1 100644
--- a/arch/x86/crypto/crc32-pclmul_asm.S
+++ b/arch/x86/crypto/crc32-pclmul_asm.S
@@ -56,30 +56,29 @@
 	.octa 0x00000001F701164100000001DB710641
 
 #define CONSTANT %xmm0
 
 #ifdef __x86_64__
-#define BUF     %rdi
-#define LEN     %rsi
-#define CRC     %edx
+#define CRC     %edi
+#define BUF     %rsi
+#define LEN     %rdx
 #else
-#define BUF     %eax
-#define LEN     %edx
-#define CRC     %ecx
+#define CRC     %eax
+#define BUF     %edx
+#define LEN     %ecx
 #endif
 
 
 
 .text
 /**
  *      Calculate crc32
- *      BUF - buffer (16 bytes aligned)
- *      LEN - sizeof buffer (16 bytes aligned), LEN should be grater than 63
  *      CRC - initial crc32
+ *      BUF - buffer (16 bytes aligned)
+ *      LEN - sizeof buffer (16 bytes aligned), LEN should be greater than 63
  *      return %eax crc32
- *      uint crc32_pclmul_le_16(unsigned char const *buffer,
- *	                     size_t len, uint crc32)
+ *      u32 crc32_pclmul_le_16(u32 crc, const u8 *buffer, size_t len);
  */
 
 SYM_FUNC_START(crc32_pclmul_le_16) /* buffer and buffer size are 16 bytes aligned */
 	movdqa  (BUF), %xmm1
 	movdqa  0x10(BUF), %xmm2
diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c
index 9f5e342b9845..9d14eac51c5b 100644
--- a/arch/x86/crypto/crc32-pclmul_glue.c
+++ b/arch/x86/crypto/crc32-pclmul_glue.c
@@ -44,11 +44,11 @@
 #define PCLMUL_MIN_LEN		64L     /* minimum size of buffer
 					 * for crc32_pclmul_le_16 */
 #define SCALE_F			16L	/* size of xmm register */
 #define SCALE_F_MASK		(SCALE_F - 1)
 
-u32 crc32_pclmul_le_16(unsigned char const *buffer, size_t len, u32 crc32);
+u32 crc32_pclmul_le_16(u32 crc, const u8 *buffer, size_t len);
 
 static u32 __attribute__((pure))
 	crc32_pclmul_le(u32 crc, unsigned char const *p, size_t len)
 {
 	unsigned int iquotient;
@@ -69,11 +69,11 @@ static u32 __attribute__((pure))
 	}
 	iquotient = len & (~SCALE_F_MASK);
 	iremainder = len & SCALE_F_MASK;
 
 	kernel_fpu_begin();
-	crc = crc32_pclmul_le_16(p, iquotient, crc);
+	crc = crc32_pclmul_le_16(crc, p, iquotient);
 	kernel_fpu_end();
 
 	if (iremainder)
 		crc = crc32_le(crc, p + iquotient, iremainder);
 
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:38 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:38 -0800
Subject: [PATCH v4 13/19] x86/crc32: expose CRC32 functions through lib
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-14-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the x86 CRC32 assembly code into the lib directory and wire it up
to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/x86/Kconfig                              |   1 +
 arch/x86/crypto/Kconfig                       |  22 --
 arch/x86/crypto/Makefile                      |   7 -
 arch/x86/crypto/crc32-pclmul_glue.c           | 202 --------------
 arch/x86/crypto/crc32c-intel_glue.c           | 249 ------------------
 arch/x86/lib/Makefile                         |   4 +
 arch/x86/lib/crc32-glue.c                     | 124 +++++++++
 .../crc32-pclmul_asm.S => lib/crc32-pclmul.S} |   0
 .../crc32c-3way.S}                            |   0
 drivers/target/iscsi/Kconfig                  |   1 -
 10 files changed, 129 insertions(+), 481 deletions(-)
 delete mode 100644 arch/x86/crypto/crc32-pclmul_glue.c
 delete mode 100644 arch/x86/crypto/crc32c-intel_glue.c
 create mode 100644 arch/x86/lib/crc32-glue.c
 rename arch/x86/{crypto/crc32-pclmul_asm.S => lib/crc32-pclmul.S} (100%)
 rename arch/x86/{crypto/crc32c-pcl-intel-asm_64.S => lib/crc32c-3way.S} (100%)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9d7bd0ae48c4..4f4fc67fbce7 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -74,10 +74,11 @@ config X86
 	select ARCH_HAS_ACPI_TABLE_UPGRADE	if ACPI
 	select ARCH_HAS_CACHE_LINE_SIZE
 	select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
 	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_CPU_PASID		if IOMMU_SVA
+	select ARCH_HAS_CRC32
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE	if !X86_PAE
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_DMA_OPS			if GART_IOMMU || XEN
diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
index 3d2e38ba5240..ba9a7e73cd08 100644
--- a/arch/x86/crypto/Kconfig
+++ b/arch/x86/crypto/Kconfig
@@ -490,32 +490,10 @@ config CRYPTO_GHASH_CLMUL_NI_INTEL
 	  GCM GHASH hash function (NIST SP800-38D)
 
 	  Architecture: x86_64 using:
 	  - CLMUL-NI (carry-less multiplication new instructions)
 
-config CRYPTO_CRC32C_INTEL
-	tristate "CRC32c (SSE4.2/PCLMULQDQ)"
-	depends on X86
-	select CRYPTO_HASH
-	help
-	  CRC32c CRC algorithm with the iSCSI polynomial (RFC 3385 and RFC 3720)
-
-	  Architecture: x86 (32-bit and 64-bit) using:
-	  - SSE4.2 (Streaming SIMD Extensions 4.2) CRC32 instruction
-	  - PCLMULQDQ (carry-less multiplication)
-
-config CRYPTO_CRC32_PCLMUL
-	tristate "CRC32 (PCLMULQDQ)"
-	depends on X86
-	select CRYPTO_HASH
-	select CRC32
-	help
-	  CRC32 CRC algorithm (IEEE 802.3)
-
-	  Architecture: x86 (32-bit and 64-bit) using:
-	  - PCLMULQDQ (carry-less multiplication)
-
 config CRYPTO_CRCT10DIF_PCLMUL
 	tristate "CRCT10DIF (PCLMULQDQ)"
 	depends on X86 && 64BIT && CRC_T10DIF
 	select CRYPTO_HASH
 	help
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 53b4a277809e..030b925ca4e2 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -73,17 +73,10 @@ obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
 ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o
 
 obj-$(CONFIG_CRYPTO_POLYVAL_CLMUL_NI) += polyval-clmulni.o
 polyval-clmulni-y := polyval-clmulni_asm.o polyval-clmulni_glue.o
 
-obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
-crc32c-intel-y := crc32c-intel_glue.o
-crc32c-intel-$(CONFIG_64BIT) += crc32c-pcl-intel-asm_64.o
-
-obj-$(CONFIG_CRYPTO_CRC32_PCLMUL) += crc32-pclmul.o
-crc32-pclmul-y := crc32-pclmul_asm.o crc32-pclmul_glue.o
-
 obj-$(CONFIG_CRYPTO_CRCT10DIF_PCLMUL) += crct10dif-pclmul.o
 crct10dif-pclmul-y := crct10dif-pcl-asm_64.o crct10dif-pclmul_glue.o
 
 obj-$(CONFIG_CRYPTO_POLY1305_X86_64) += poly1305-x86_64.o
 poly1305-x86_64-y := poly1305-x86_64-cryptogams.o poly1305_glue.o
diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c
deleted file mode 100644
index 9d14eac51c5b..000000000000
--- a/arch/x86/crypto/crc32-pclmul_glue.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please  visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
-/*
- * Copyright 2012 Xyratex Technology Limited
- *
- * Wrappers for kernel crypto shash api to pclmulqdq crc32 implementation.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/crc32.h>
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-
-#include <asm/cpufeatures.h>
-#include <asm/cpu_device_id.h>
-#include <asm/simd.h>
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-#define PCLMUL_MIN_LEN		64L     /* minimum size of buffer
-					 * for crc32_pclmul_le_16 */
-#define SCALE_F			16L	/* size of xmm register */
-#define SCALE_F_MASK		(SCALE_F - 1)
-
-u32 crc32_pclmul_le_16(u32 crc, const u8 *buffer, size_t len);
-
-static u32 __attribute__((pure))
-	crc32_pclmul_le(u32 crc, unsigned char const *p, size_t len)
-{
-	unsigned int iquotient;
-	unsigned int iremainder;
-	unsigned int prealign;
-
-	if (len < PCLMUL_MIN_LEN + SCALE_F_MASK || !crypto_simd_usable())
-		return crc32_le(crc, p, len);
-
-	if ((long)p & SCALE_F_MASK) {
-		/* align p to 16 byte */
-		prealign = SCALE_F - ((long)p & SCALE_F_MASK);
-
-		crc = crc32_le(crc, p, prealign);
-		len -= prealign;
-		p = (unsigned char *)(((unsigned long)p + SCALE_F_MASK) &
-				     ~SCALE_F_MASK);
-	}
-	iquotient = len & (~SCALE_F_MASK);
-	iremainder = len & SCALE_F_MASK;
-
-	kernel_fpu_begin();
-	crc = crc32_pclmul_le_16(crc, p, iquotient);
-	kernel_fpu_end();
-
-	if (iremainder)
-		crc = crc32_le(crc, p + iquotient, iremainder);
-
-	return crc;
-}
-
-static int crc32_pclmul_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = 0;
-
-	return 0;
-}
-
-static int crc32_pclmul_setkey(struct crypto_shash *hash, const u8 *key,
-			unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = le32_to_cpup((__le32 *)key);
-	return 0;
-}
-
-static int crc32_pclmul_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = *mctx;
-
-	return 0;
-}
-
-static int crc32_pclmul_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = crc32_pclmul_le(*crcp, data, len);
-	return 0;
-}
-
-/* No final XOR 0xFFFFFFFF, like crc32_le */
-static int __crc32_pclmul_finup(u32 *crcp, const u8 *data, unsigned int len,
-				u8 *out)
-{
-	*(__le32 *)out = cpu_to_le32(crc32_pclmul_le(*crcp, data, len));
-	return 0;
-}
-
-static int crc32_pclmul_finup(struct shash_desc *desc, const u8 *data,
-			      unsigned int len, u8 *out)
-{
-	return __crc32_pclmul_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32_pclmul_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*(__le32 *)out = cpu_to_le32p(crcp);
-	return 0;
-}
-
-static int crc32_pclmul_digest(struct shash_desc *desc, const u8 *data,
-			       unsigned int len, u8 *out)
-{
-	return __crc32_pclmul_finup(crypto_shash_ctx(desc->tfm), data, len,
-				    out);
-}
-
-static struct shash_alg alg = {
-	.setkey		= crc32_pclmul_setkey,
-	.init		= crc32_pclmul_init,
-	.update		= crc32_pclmul_update,
-	.final		= crc32_pclmul_final,
-	.finup		= crc32_pclmul_finup,
-	.digest		= crc32_pclmul_digest,
-	.descsize	= sizeof(u32),
-	.digestsize	= CHKSUM_DIGEST_SIZE,
-	.base		= {
-			.cra_name		= "crc32",
-			.cra_driver_name	= "crc32-pclmul",
-			.cra_priority		= 200,
-			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-			.cra_blocksize		= CHKSUM_BLOCK_SIZE,
-			.cra_ctxsize		= sizeof(u32),
-			.cra_module		= THIS_MODULE,
-			.cra_init		= crc32_pclmul_cra_init,
-	}
-};
-
-static const struct x86_cpu_id crc32pclmul_cpu_id[] = {
-	X86_MATCH_FEATURE(X86_FEATURE_PCLMULQDQ, NULL),
-	{}
-};
-MODULE_DEVICE_TABLE(x86cpu, crc32pclmul_cpu_id);
-
-
-static int __init crc32_pclmul_mod_init(void)
-{
-
-	if (!x86_match_cpu(crc32pclmul_cpu_id)) {
-		pr_info("PCLMULQDQ-NI instructions are not detected.\n");
-		return -ENODEV;
-	}
-	return crypto_register_shash(&alg);
-}
-
-static void __exit crc32_pclmul_mod_fini(void)
-{
-	crypto_unregister_shash(&alg);
-}
-
-module_init(crc32_pclmul_mod_init);
-module_exit(crc32_pclmul_mod_fini);
-
-MODULE_AUTHOR("Alexander Boyko <alexander_boyko at xyratex.com>");
-MODULE_DESCRIPTION("CRC32 algorithm (IEEE 802.3) accelerated with PCLMULQDQ");
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS_CRYPTO("crc32");
-MODULE_ALIAS_CRYPTO("crc32-pclmul");
diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c
deleted file mode 100644
index 603d159de400..000000000000
--- a/arch/x86/crypto/crc32c-intel_glue.c
+++ /dev/null
@@ -1,249 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Using hardware provided CRC32 instruction to accelerate the CRC32 disposal.
- * CRC32C polynomial:0x1EDC6F41(BE)/0x82F63B78(LE)
- * CRC32 is a new instruction in Intel SSE4.2, the reference can be found at:
- * http://www.intel.com/products/processor/manuals/
- * Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- * Volume 2A: Instruction Set Reference, A-M
- *
- * Copyright (C) 2008 Intel Corporation
- * Authors: Austin Zhang <austin_zhang at linux.intel.com>
- *          Kent Liu <kent.liu at intel.com>
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-
-#include <asm/cpufeatures.h>
-#include <asm/cpu_device_id.h>
-#include <asm/simd.h>
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-#define SCALE_F	sizeof(unsigned long)
-
-#ifdef CONFIG_X86_64
-#define CRC32_INST "crc32q %1, %q0"
-#else
-#define CRC32_INST "crc32l %1, %0"
-#endif
-
-#ifdef CONFIG_X86_64
-/*
- * use carryless multiply version of crc32c when buffer
- * size is >= 512 to account
- * for fpu state save/restore overhead.
- */
-#define CRC32C_PCL_BREAKEVEN	512
-
-asmlinkage u32 crc32c_x86_3way(u32 crc, const u8 *buffer, size_t len);
-#endif /* CONFIG_X86_64 */
-
-static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length)
-{
-	while (length--) {
-		asm("crc32b %1, %0"
-		    : "+r" (crc) : "rm" (*data));
-		data++;
-	}
-
-	return crc;
-}
-
-static u32 __pure crc32c_intel_le_hw(u32 crc, unsigned char const *p, size_t len)
-{
-	unsigned int iquotient = len / SCALE_F;
-	unsigned int iremainder = len % SCALE_F;
-	unsigned long *ptmp = (unsigned long *)p;
-
-	while (iquotient--) {
-		asm(CRC32_INST
-		    : "+r" (crc) : "rm" (*ptmp));
-		ptmp++;
-	}
-
-	if (iremainder)
-		crc = crc32c_intel_le_hw_byte(crc, (unsigned char *)ptmp,
-				 iremainder);
-
-	return crc;
-}
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set
- * the seed.
- */
-static int crc32c_intel_setkey(struct crypto_shash *hash, const u8 *key,
-			unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = le32_to_cpup((__le32 *)key);
-	return 0;
-}
-
-static int crc32c_intel_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = *mctx;
-
-	return 0;
-}
-
-static int crc32c_intel_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = crc32c_intel_le_hw(*crcp, data, len);
-	return 0;
-}
-
-static int __crc32c_intel_finup(u32 *crcp, const u8 *data, unsigned int len,
-				u8 *out)
-{
-	*(__le32 *)out = ~cpu_to_le32(crc32c_intel_le_hw(*crcp, data, len));
-	return 0;
-}
-
-static int crc32c_intel_finup(struct shash_desc *desc, const u8 *data,
-			      unsigned int len, u8 *out)
-{
-	return __crc32c_intel_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32c_intel_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*(__le32 *)out = ~cpu_to_le32p(crcp);
-	return 0;
-}
-
-static int crc32c_intel_digest(struct shash_desc *desc, const u8 *data,
-			       unsigned int len, u8 *out)
-{
-	return __crc32c_intel_finup(crypto_shash_ctx(desc->tfm), data, len,
-				    out);
-}
-
-static int crc32c_intel_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = ~0;
-
-	return 0;
-}
-
-#ifdef CONFIG_X86_64
-static int crc32c_pcl_intel_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	/*
-	 * use faster PCL version if datasize is large enough to
-	 * overcome kernel fpu state save/restore overhead
-	 */
-	if (len >= CRC32C_PCL_BREAKEVEN && crypto_simd_usable()) {
-		kernel_fpu_begin();
-		*crcp = crc32c_x86_3way(*crcp, data, len);
-		kernel_fpu_end();
-	} else
-		*crcp = crc32c_intel_le_hw(*crcp, data, len);
-	return 0;
-}
-
-static int __crc32c_pcl_intel_finup(u32 *crcp, const u8 *data, unsigned int len,
-				u8 *out)
-{
-	if (len >= CRC32C_PCL_BREAKEVEN && crypto_simd_usable()) {
-		kernel_fpu_begin();
-		*(__le32 *)out = ~cpu_to_le32(crc32c_x86_3way(*crcp, data, len));
-		kernel_fpu_end();
-	} else
-		*(__le32 *)out =
-			~cpu_to_le32(crc32c_intel_le_hw(*crcp, data, len));
-	return 0;
-}
-
-static int crc32c_pcl_intel_finup(struct shash_desc *desc, const u8 *data,
-			      unsigned int len, u8 *out)
-{
-	return __crc32c_pcl_intel_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32c_pcl_intel_digest(struct shash_desc *desc, const u8 *data,
-			       unsigned int len, u8 *out)
-{
-	return __crc32c_pcl_intel_finup(crypto_shash_ctx(desc->tfm), data, len,
-				    out);
-}
-#endif /* CONFIG_X86_64 */
-
-static struct shash_alg alg = {
-	.setkey			=	crc32c_intel_setkey,
-	.init			=	crc32c_intel_init,
-	.update			=	crc32c_intel_update,
-	.final			=	crc32c_intel_final,
-	.finup			=	crc32c_intel_finup,
-	.digest			=	crc32c_intel_digest,
-	.descsize		=	sizeof(u32),
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.base			=	{
-		.cra_name		=	"crc32c",
-		.cra_driver_name	=	"crc32c-intel",
-		.cra_priority		=	200,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(u32),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	crc32c_intel_cra_init,
-	}
-};
-
-static const struct x86_cpu_id crc32c_cpu_id[] = {
-	X86_MATCH_FEATURE(X86_FEATURE_XMM4_2, NULL),
-	{}
-};
-MODULE_DEVICE_TABLE(x86cpu, crc32c_cpu_id);
-
-static int __init crc32c_intel_mod_init(void)
-{
-	if (!x86_match_cpu(crc32c_cpu_id))
-		return -ENODEV;
-#ifdef CONFIG_X86_64
-	if (boot_cpu_has(X86_FEATURE_PCLMULQDQ)) {
-		alg.update = crc32c_pcl_intel_update;
-		alg.finup = crc32c_pcl_intel_finup;
-		alg.digest = crc32c_pcl_intel_digest;
-	}
-#endif
-	return crypto_register_shash(&alg);
-}
-
-static void __exit crc32c_intel_mod_fini(void)
-{
-	crypto_unregister_shash(&alg);
-}
-
-module_init(crc32c_intel_mod_init);
-module_exit(crc32c_intel_mod_fini);
-
-MODULE_AUTHOR("Austin Zhang <austin.zhang at intel.com>, Kent Liu <kent.liu at intel.com>");
-MODULE_DESCRIPTION("CRC32c (Castagnoli) optimization using Intel Hardware.");
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS_CRYPTO("crc32c");
-MODULE_ALIAS_CRYPTO("crc32c-intel");
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 98583a9dbab3..17510da06c9f 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -36,10 +36,14 @@ lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc.o copy_mc_64.o
 lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o
 lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
 lib-$(CONFIG_FUNCTION_ERROR_INJECTION)	+= error-inject.o
 lib-$(CONFIG_MITIGATION_RETPOLINE) += retpoline.o
 
+obj-$(CONFIG_CRC32_ARCH) += crc32-x86.o
+crc32-x86-y := crc32-glue.o crc32-pclmul.o
+crc32-x86-$(CONFIG_64BIT) += crc32c-3way.o
+
 obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o
 obj-y += iomem.o
 
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
diff --git a/arch/x86/lib/crc32-glue.c b/arch/x86/lib/crc32-glue.c
new file mode 100644
index 000000000000..2dd18a886ded
--- /dev/null
+++ b/arch/x86/lib/crc32-glue.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * x86-optimized CRC32 functions
+ *
+ * Copyright (C) 2008 Intel Corporation
+ * Copyright 2012 Xyratex Technology Limited
+ * Copyright 2024 Google LLC
+ */
+
+#include <asm/cpufeatures.h>
+#include <asm/simd.h>
+#include <crypto/internal/simd.h>
+#include <linux/crc32.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+/* minimum size of buffer for crc32_pclmul_le_16 */
+#define CRC32_PCLMUL_MIN_LEN	64
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32);
+static DEFINE_STATIC_KEY_FALSE(have_pclmulqdq);
+
+u32 crc32_pclmul_le_16(u32 crc, const u8 *buffer, size_t len);
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (len >= CRC32_PCLMUL_MIN_LEN + 15 &&
+	    static_branch_likely(&have_pclmulqdq) && crypto_simd_usable()) {
+		size_t n = -(uintptr_t)p & 15;
+
+		/* align p to 16-byte boundary */
+		if (n) {
+			crc = crc32_le_base(crc, p, n);
+			p += n;
+			len -= n;
+		}
+		n = round_down(len, 16);
+		kernel_fpu_begin();
+		crc = crc32_pclmul_le_16(crc, p, n);
+		kernel_fpu_end();
+		p += n;
+		len -= n;
+	}
+	if (len)
+		crc = crc32_le_base(crc, p, len);
+	return crc;
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+#ifdef CONFIG_X86_64
+#define CRC32_INST "crc32q %1, %q0"
+#else
+#define CRC32_INST "crc32l %1, %0"
+#endif
+
+/*
+ * Use carryless multiply version of crc32c when buffer size is >= 512 to
+ * account for FPU state save/restore overhead.
+ */
+#define CRC32C_PCLMUL_BREAKEVEN	512
+
+asmlinkage u32 crc32c_x86_3way(u32 crc, const u8 *buffer, size_t len);
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	size_t num_longs;
+
+	if (!static_branch_likely(&have_crc32))
+		return crc32c_le_base(crc, p, len);
+
+	if (IS_ENABLED(CONFIG_X86_64) && len >= CRC32C_PCLMUL_BREAKEVEN &&
+	    static_branch_likely(&have_pclmulqdq) && crypto_simd_usable()) {
+		kernel_fpu_begin();
+		crc = crc32c_x86_3way(crc, p, len);
+		kernel_fpu_end();
+		return crc;
+	}
+
+	for (num_longs = len / sizeof(unsigned long);
+	     num_longs != 0; num_longs--, p += sizeof(unsigned long))
+		asm(CRC32_INST : "+r" (crc) : "rm" (*(unsigned long *)p));
+
+	for (len %= sizeof(unsigned long); len; len--, p++)
+		asm("crc32b %1, %0" : "+r" (crc) : "rm" (*p));
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_x86_init(void)
+{
+	if (boot_cpu_has(X86_FEATURE_XMM4_2))
+		static_branch_enable(&have_crc32);
+	if (boot_cpu_has(X86_FEATURE_PCLMULQDQ))
+		static_branch_enable(&have_pclmulqdq);
+	return 0;
+}
+arch_initcall(crc32_x86_init);
+
+static void __exit crc32_x86_exit(void)
+{
+}
+module_exit(crc32_x86_exit);
+
+u32 crc32_optimizations(void)
+{
+	u32 optimizations = 0;
+
+	if (static_key_enabled(&have_crc32))
+		optimizations |= CRC32C_OPTIMIZATION;
+	if (static_key_enabled(&have_pclmulqdq))
+		optimizations |= CRC32_LE_OPTIMIZATION;
+	return optimizations;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_DESCRIPTION("x86-optimized CRC32 functions");
+MODULE_LICENSE("GPL");
diff --git a/arch/x86/crypto/crc32-pclmul_asm.S b/arch/x86/lib/crc32-pclmul.S
similarity index 100%
rename from arch/x86/crypto/crc32-pclmul_asm.S
rename to arch/x86/lib/crc32-pclmul.S
diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/lib/crc32c-3way.S
similarity index 100%
rename from arch/x86/crypto/crc32c-pcl-intel-asm_64.S
rename to arch/x86/lib/crc32c-3way.S
diff --git a/drivers/target/iscsi/Kconfig b/drivers/target/iscsi/Kconfig
index 922b207bc69d..1c0517a12571 100644
--- a/drivers/target/iscsi/Kconfig
+++ b/drivers/target/iscsi/Kconfig
@@ -2,11 +2,10 @@
 config ISCSI_TARGET
 	tristate "SCSI Target Mode Stack"
 	depends on INET
 	select CRYPTO
 	select CRYPTO_CRC32C
-	select CRYPTO_CRC32C_INTEL if X86
 	help
 	Say M to enable the SCSI target mode stack. A SCSI target mode stack
 	is software that makes local storage available over a storage network
 	to a SCSI initiator system. The supported storage network technologies
 	include iSCSI, Fibre Channel and the SCSI RDMA Protocol (SRP).
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:39 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:39 -0800
Subject: [PATCH v4 14/19] bcachefs: Explicitly select CRYPTO from BCACHEFS_FS
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-15-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Explicitly select CRYPTO from BCACHEFS_FS, so that this dependency of
CRYPTO_SHA256, CRYPTO_CHACHA20, and CRYPTO_POLY1305 (which are also
selected) is satisfied.  Currently this dependency is satisfied
indirectly via LIBCRC32C, but this is fragile and is planned to change
(https://lore.kernel.org/r/20241021002935.325878-13-ebiggers at kernel.org).

Acked-by: Kent Overstreet <kent.overstreet at linux.dev>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/bcachefs/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/bcachefs/Kconfig b/fs/bcachefs/Kconfig
index ab6c95b895b3..971ea505e7b0 100644
--- a/fs/bcachefs/Kconfig
+++ b/fs/bcachefs/Kconfig
@@ -13,10 +13,11 @@ config BCACHEFS_FS
 	select LZ4HC_DECOMPRESS
 	select ZLIB_DEFLATE
 	select ZLIB_INFLATE
 	select ZSTD_COMPRESS
 	select ZSTD_DECOMPRESS
+	select CRYPTO
 	select CRYPTO_SHA256
 	select CRYPTO_CHACHA20
 	select CRYPTO_POLY1305
 	select KEYS
 	select RAID6_PQ
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:41 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:41 -0800
Subject: [PATCH v4 16/19] ext4: switch to using the crc32c library
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-17-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the crc32c() library function directly takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32c().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Darrick J. Wong <djwong at kernel.org>
Acked-by: Theodore Ts'o <tytso at mit.edu>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/ext4/Kconfig |  3 +--
 fs/ext4/ext4.h  | 25 +++----------------------
 fs/ext4/super.c | 15 ---------------
 3 files changed, 4 insertions(+), 39 deletions(-)

diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index e20d59221fc0..c9ca41d91a6c 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -29,12 +29,11 @@ config EXT3_FS_SECURITY
 config EXT4_FS
 	tristate "The Extended 4 (ext4) filesystem"
 	select BUFFER_HEAD
 	select JBD2
 	select CRC16
-	select CRYPTO
-	select CRYPTO_CRC32C
+	select CRC32
 	select FS_IOMAP
 	select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
 	help
 	  This is the next generation of the ext3 filesystem.
 
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 74f2071189b2..4e7de7eaa374 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -31,11 +31,11 @@
 #include <linux/wait.h>
 #include <linux/sched/signal.h>
 #include <linux/blockgroup_lock.h>
 #include <linux/percpu_counter.h>
 #include <linux/ratelimit.h>
-#include <crypto/hash.h>
+#include <linux/crc32c.h>
 #include <linux/falloc.h>
 #include <linux/percpu-rwsem.h>
 #include <linux/fiemap.h>
 #ifdef __KERNEL__
 #include <linux/compat.h>
@@ -1660,13 +1660,10 @@ struct ext4_sb_info {
 	struct task_struct *s_mmp_tsk;
 
 	/* record the last minlen when FITRIM is called. */
 	unsigned long s_last_trim_minblks;
 
-	/* Reference to checksum algorithm driver via cryptoapi */
-	struct crypto_shash *s_chksum_driver;
-
 	/* Precomputed FS UUID checksum for seeding other checksums */
 	__u32 s_csum_seed;
 
 	/* Reclaim extents from extent status tree */
 	struct shrinker *s_es_shrinker;
@@ -2461,23 +2458,11 @@ static inline __le16 ext4_rec_len_to_disk(unsigned len, unsigned blocksize)
 #define DX_HASH_LAST 			DX_HASH_SIPHASH
 
 static inline u32 ext4_chksum(struct ext4_sb_info *sbi, u32 crc,
 			      const void *address, unsigned int length)
 {
-	struct {
-		struct shash_desc shash;
-		char ctx[4];
-	} desc;
-
-	BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver)!=sizeof(desc.ctx));
-
-	desc.shash.tfm = sbi->s_chksum_driver;
-	*(u32 *)desc.ctx = crc;
-
-	BUG_ON(crypto_shash_update(&desc.shash, address, length));
-
-	return *(u32 *)desc.ctx;
+	return crc32c(crc, address, length);
 }
 
 #ifdef __KERNEL__
 
 /* hash info structure used by the directory hash */
@@ -3274,15 +3259,11 @@ extern void ext4_group_desc_csum_set(struct super_block *sb, __u32 group,
 extern int ext4_register_li_request(struct super_block *sb,
 				    ext4_group_t first_not_zeroed);
 
 static inline int ext4_has_metadata_csum(struct super_block *sb)
 {
-	WARN_ON_ONCE(ext4_has_feature_metadata_csum(sb) &&
-		     !EXT4_SB(sb)->s_chksum_driver);
-
-	return ext4_has_feature_metadata_csum(sb) &&
-	       (EXT4_SB(sb)->s_chksum_driver != NULL);
+	return ext4_has_feature_metadata_csum(sb);
 }
 
 static inline int ext4_has_group_desc_csum(struct super_block *sb)
 {
 	return ext4_has_feature_gdt_csum(sb) || ext4_has_metadata_csum(sb);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 785809f33ff4..fdf4817a7dbc 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1378,12 +1378,10 @@ static void ext4_put_super(struct super_block *sb)
 	 * Now that we are completely done shutting down the
 	 * superblock, we need to actually destroy the kobject.
 	 */
 	kobject_put(&sbi->s_kobj);
 	wait_for_completion(&sbi->s_kobj_unregister);
-	if (sbi->s_chksum_driver)
-		crypto_free_shash(sbi->s_chksum_driver);
 	kfree(sbi->s_blockgroup_lock);
 	fs_put_dax(sbi->s_daxdev, NULL);
 	fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
 #if IS_ENABLED(CONFIG_UNICODE)
 	utf8_unload(sb->s_encoding);
@@ -4632,19 +4630,10 @@ static int ext4_init_metadata_csum(struct super_block *sb, struct ext4_super_blo
 		return -EINVAL;
 	}
 	ext4_setup_csum_trigger(sb, EXT4_JTR_ORPHAN_FILE,
 				ext4_orphan_file_block_trigger);
 
-	/* Load the checksum driver */
-	sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
-	if (IS_ERR(sbi->s_chksum_driver)) {
-		int ret = PTR_ERR(sbi->s_chksum_driver);
-		ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
-		sbi->s_chksum_driver = NULL;
-		return ret;
-	}
-
 	/* Check superblock checksum */
 	if (!ext4_superblock_csum_verify(sb, es)) {
 		ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
 			 "invalid superblock checksum.  Run e2fsck?");
 		return -EFSBADCRC;
@@ -5685,13 +5674,10 @@ failed_mount8: __maybe_unused
 	flush_work(&sbi->s_sb_upd_work);
 	ext4_stop_mmpd(sbi);
 	del_timer_sync(&sbi->s_err_report);
 	ext4_group_desc_free(sbi);
 failed_mount:
-	if (sbi->s_chksum_driver)
-		crypto_free_shash(sbi->s_chksum_driver);
-
 #if IS_ENABLED(CONFIG_UNICODE)
 	utf8_unload(sb->s_encoding);
 #endif
 
 #ifdef CONFIG_QUOTA
@@ -7492,8 +7478,7 @@ static void __exit ext4_exit_fs(void)
 }
 
 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
 MODULE_DESCRIPTION("Fourth Extended Filesystem");
 MODULE_LICENSE("GPL");
-MODULE_SOFTDEP("pre: crc32c");
 module_init(ext4_init_fs)
 module_exit(ext4_exit_fs)
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:43 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:43 -0800
Subject: [PATCH v4 18/19] f2fs: switch to using the crc32 library
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-19-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the crc32() library function takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Chao Yu <chao at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/f2fs/Kconfig |  3 +--
 fs/f2fs/f2fs.h  | 20 +-------------------
 fs/f2fs/super.c | 15 ---------------
 3 files changed, 2 insertions(+), 36 deletions(-)

diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
index 68a1e23e1557..5916a02fb46d 100644
--- a/fs/f2fs/Kconfig
+++ b/fs/f2fs/Kconfig
@@ -2,12 +2,11 @@
 config F2FS_FS
 	tristate "F2FS filesystem support"
 	depends on BLOCK
 	select BUFFER_HEAD
 	select NLS
-	select CRYPTO
-	select CRYPTO_CRC32
+	select CRC32
 	select F2FS_FS_XATTR if FS_ENCRYPTION
 	select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
 	select FS_IOMAP
 	select LZ4_COMPRESS if F2FS_FS_LZ4
 	select LZ4_DECOMPRESS if F2FS_FS_LZ4
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 6f2cbf4c5740..fd7e9cb6f893 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -22,11 +22,10 @@
 #include <linux/bio.h>
 #include <linux/blkdev.h>
 #include <linux/quotaops.h>
 #include <linux/part_stat.h>
 #include <linux/rw_hint.h>
-#include <crypto/hash.h>
 
 #include <linux/fscrypt.h>
 #include <linux/fsverity.h>
 
 struct pagevec;
@@ -1766,13 +1765,10 @@ struct f2fs_sb_info {
 
 	/* For write statistics */
 	u64 sectors_written_start;
 	u64 kbytes_written;
 
-	/* Reference to checksum algorithm driver via cryptoapi */
-	struct crypto_shash *s_chksum_driver;
-
 	/* Precomputed FS UUID checksum for seeding other checksums */
 	__u32 s_chksum_seed;
 
 	struct workqueue_struct *post_read_wq;	/* post read workqueue */
 
@@ -1946,25 +1942,11 @@ static inline unsigned int f2fs_time_to_wait(struct f2fs_sb_info *sbi,
  * Inline functions
  */
 static inline u32 __f2fs_crc32(struct f2fs_sb_info *sbi, u32 crc,
 			      const void *address, unsigned int length)
 {
-	struct {
-		struct shash_desc shash;
-		char ctx[4];
-	} desc;
-	int err;
-
-	BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver) != sizeof(desc.ctx));
-
-	desc.shash.tfm = sbi->s_chksum_driver;
-	*(u32 *)desc.ctx = crc;
-
-	err = crypto_shash_update(&desc.shash, address, length);
-	BUG_ON(err);
-
-	return *(u32 *)desc.ctx;
+	return crc32(crc, address, length);
 }
 
 static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address,
 			   unsigned int length)
 {
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index fc7d463dee15..19b67828ae32 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1692,12 +1692,10 @@ static void f2fs_put_super(struct super_block *sb)
 
 	f2fs_destroy_post_read_wq(sbi);
 
 	kvfree(sbi->ckpt);
 
-	if (sbi->s_chksum_driver)
-		crypto_free_shash(sbi->s_chksum_driver);
 	kfree(sbi->raw_super);
 
 	f2fs_destroy_page_array_cache(sbi);
 	f2fs_destroy_xattr_caches(sbi);
 #ifdef CONFIG_QUOTA
@@ -4464,19 +4462,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 		INIT_LIST_HEAD(&sbi->inode_list[i]);
 		spin_lock_init(&sbi->inode_lock[i]);
 	}
 	mutex_init(&sbi->flush_lock);
 
-	/* Load the checksum driver */
-	sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0);
-	if (IS_ERR(sbi->s_chksum_driver)) {
-		f2fs_err(sbi, "Cannot load crc32 driver.");
-		err = PTR_ERR(sbi->s_chksum_driver);
-		sbi->s_chksum_driver = NULL;
-		goto free_sbi;
-	}
-
 	/* set a block size */
 	if (unlikely(!sb_set_blocksize(sb, F2FS_BLKSIZE))) {
 		f2fs_err(sbi, "unable to set blocksize");
 		goto free_sbi;
 	}
@@ -4917,12 +4906,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 	fscrypt_free_dummy_policy(&F2FS_OPTION(sbi).dummy_enc_policy);
 	kvfree(options);
 free_sb_buf:
 	kfree(raw_super);
 free_sbi:
-	if (sbi->s_chksum_driver)
-		crypto_free_shash(sbi->s_chksum_driver);
 	kfree(sbi);
 	sb->s_fs_info = NULL;
 
 	/* give only one another chance */
 	if (retry_cnt > 0 && skip_recovery) {
@@ -5125,7 +5112,5 @@ module_init(init_f2fs_fs)
 module_exit(exit_f2fs_fs)
 
 MODULE_AUTHOR("Samsung Electronics's Praesto Team");
 MODULE_DESCRIPTION("Flash Friendly File System");
 MODULE_LICENSE("GPL");
-MODULE_SOFTDEP("pre: crc32");
-
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:44 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:44 -0800
Subject: [PATCH v4 19/19] scsi: target: iscsi: switch to using the crc32c library
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-20-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the crc32c() library function directly takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32c().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 drivers/target/iscsi/Kconfig              |   3 +-
 drivers/target/iscsi/iscsi_target.c       | 153 +++++++---------------
 drivers/target/iscsi/iscsi_target_login.c |  50 -------
 drivers/target/iscsi/iscsi_target_login.h |   1 -
 drivers/target/iscsi/iscsi_target_nego.c  |  21 +--
 include/target/iscsi/iscsi_target_core.h  |   3 -
 6 files changed, 49 insertions(+), 182 deletions(-)

diff --git a/drivers/target/iscsi/Kconfig b/drivers/target/iscsi/Kconfig
index 1c0517a12571..70d76f3dd693 100644
--- a/drivers/target/iscsi/Kconfig
+++ b/drivers/target/iscsi/Kconfig
@@ -1,11 +1,12 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config ISCSI_TARGET
 	tristate "SCSI Target Mode Stack"
 	depends on INET
+	select CRC32
 	select CRYPTO
-	select CRYPTO_CRC32C
+	select CRYPTO_HASH
 	help
 	Say M to enable the SCSI target mode stack. A SCSI target mode stack
 	is software that makes local storage available over a storage network
 	to a SCSI initiator system. The supported storage network technologies
 	include iSCSI, Fibre Channel and the SCSI RDMA Protocol (SRP).
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 6002283cbeba..091c1efccfb7 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -6,11 +6,11 @@
  *
  * Author: Nicholas A. Bellinger <nab at linux-iscsi.org>
  *
  ******************************************************************************/
 
-#include <crypto/hash.h>
+#include <linux/crc32c.h>
 #include <linux/string.h>
 #include <linux/kthread.h>
 #include <linux/completion.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
@@ -488,12 +488,12 @@ void iscsit_aborted_task(struct iscsit_conn *conn, struct iscsit_cmd *cmd)
 
 	__iscsit_free_cmd(cmd, true);
 }
 EXPORT_SYMBOL(iscsit_aborted_task);
 
-static void iscsit_do_crypto_hash_buf(struct ahash_request *, const void *,
-				      u32, u32, const void *, void *);
+static u32 iscsit_crc_buf(const void *buf, u32 payload_length,
+			  u32 padding, const void *pad_bytes);
 static void iscsit_tx_thread_wait_for_tcp(struct iscsit_conn *);
 
 static int
 iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 			  const void *data_buf, u32 data_buf_len)
@@ -508,13 +508,11 @@ iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 	iov[niov++].iov_len	= ISCSI_HDR_LEN;
 
 	if (conn->conn_ops->HeaderDigest) {
 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-		iscsit_do_crypto_hash_buf(conn->conn_tx_hash, hdr,
-					  ISCSI_HDR_LEN, 0, NULL,
-					  header_digest);
+		*header_digest = iscsit_crc_buf(hdr, ISCSI_HDR_LEN, 0, NULL);
 
 		iov[0].iov_len += ISCSI_CRC_LEN;
 		tx_size += ISCSI_CRC_LEN;
 		pr_debug("Attaching CRC32C HeaderDigest"
 			 " to opcode 0x%x 0x%08x\n",
@@ -535,15 +533,13 @@ iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 			pr_debug("Attaching %u additional"
 				 " padding bytes.\n", padding);
 		}
 
 		if (conn->conn_ops->DataDigest) {
-			iscsit_do_crypto_hash_buf(conn->conn_tx_hash,
-						  data_buf, data_buf_len,
-						  padding, &cmd->pad_bytes,
-						  &cmd->data_crc);
-
+			cmd->data_crc = iscsit_crc_buf(data_buf, data_buf_len,
+						       padding,
+						       &cmd->pad_bytes);
 			iov[niov].iov_base = &cmd->data_crc;
 			iov[niov++].iov_len = ISCSI_CRC_LEN;
 			tx_size += ISCSI_CRC_LEN;
 			pr_debug("Attached DataDigest for %u"
 				 " bytes opcode 0x%x, CRC 0x%08x\n",
@@ -564,12 +560,12 @@ iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 }
 
 static int iscsit_map_iovec(struct iscsit_cmd *cmd, struct kvec *iov, int nvec,
 			    u32 data_offset, u32 data_length);
 static void iscsit_unmap_iovec(struct iscsit_cmd *);
-static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsit_cmd *,
-				    u32, u32, u32, u8 *);
+static u32 iscsit_crc_sglist(const struct iscsit_cmd *cmd, u32 data_length,
+			     u32 padding, const u8 *pad_bytes);
 static int
 iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 		       const struct iscsi_datain *datain)
 {
 	struct kvec *iov;
@@ -582,14 +578,12 @@ iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 	tx_size += ISCSI_HDR_LEN;
 
 	if (conn->conn_ops->HeaderDigest) {
 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-		iscsit_do_crypto_hash_buf(conn->conn_tx_hash, cmd->pdu,
-					  ISCSI_HDR_LEN, 0, NULL,
-					  header_digest);
-
+		*header_digest = iscsit_crc_buf(cmd->pdu, ISCSI_HDR_LEN, 0,
+						NULL);
 		iov[0].iov_len += ISCSI_CRC_LEN;
 		tx_size += ISCSI_CRC_LEN;
 
 		pr_debug("Attaching CRC32 HeaderDigest for DataIN PDU 0x%08x\n",
 			 *header_digest);
@@ -612,16 +606,12 @@ iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 
 		pr_debug("Attaching %u padding bytes\n", cmd->padding);
 	}
 
 	if (conn->conn_ops->DataDigest) {
-		cmd->data_crc = iscsit_do_crypto_hash_sg(conn->conn_tx_hash,
-							 cmd, datain->offset,
-							 datain->length,
-							 cmd->padding,
-							 cmd->pad_bytes);
-
+		cmd->data_crc = iscsit_crc_sglist(cmd, datain->length,
+						  cmd->padding, cmd->pad_bytes);
 		iov[iov_count].iov_base	= &cmd->data_crc;
 		iov[iov_count++].iov_len = ISCSI_CRC_LEN;
 		tx_size += ISCSI_CRC_LEN;
 
 		pr_debug("Attached CRC32C DataDigest %d bytes, crc 0x%08x\n",
@@ -1402,81 +1392,49 @@ iscsit_handle_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 		return 0;
 
 	return iscsit_get_immediate_data(cmd, hdr, dump_payload);
 }
 
-static u32 iscsit_do_crypto_hash_sg(
-	struct ahash_request *hash,
-	struct iscsit_cmd *cmd,
-	u32 data_offset,
-	u32 data_length,
-	u32 padding,
-	u8 *pad_bytes)
+static u32 iscsit_crc_sglist(const struct iscsit_cmd *cmd, u32 data_length,
+			     u32 padding, const u8 *pad_bytes)
 {
-	u32 data_crc;
-	struct scatterlist *sg;
-	unsigned int page_off;
-
-	crypto_ahash_init(hash);
-
-	sg = cmd->first_data_sg;
-	page_off = cmd->first_data_sg_off;
-
-	if (data_length && page_off) {
-		struct scatterlist first_sg;
-		u32 len = min_t(u32, data_length, sg->length - page_off);
-
-		sg_init_table(&first_sg, 1);
-		sg_set_page(&first_sg, sg_page(sg), len, sg->offset + page_off);
-
-		ahash_request_set_crypt(hash, &first_sg, NULL, len);
-		crypto_ahash_update(hash);
-
-		data_length -= len;
-		sg = sg_next(sg);
-	}
+	struct scatterlist *sg = cmd->first_data_sg;
+	unsigned int page_off = cmd->first_data_sg_off;
+	u32 crc = ~0;
 
 	while (data_length) {
-		u32 cur_len = min_t(u32, data_length, sg->length);
+		u32 cur_len = min_t(u32, data_length, sg->length - page_off);
+		const void *virt;
 
-		ahash_request_set_crypt(hash, sg, NULL, cur_len);
-		crypto_ahash_update(hash);
+		virt = kmap_local_page(sg_page(sg)) + sg->offset + page_off;
+		crc = crc32c(crc, virt, cur_len);
+		kunmap_local(virt);
 
-		data_length -= cur_len;
 		/* iscsit_map_iovec has already checked for invalid sg pointers */
 		sg = sg_next(sg);
-	}
 
-	if (padding) {
-		struct scatterlist pad_sg;
-
-		sg_init_one(&pad_sg, pad_bytes, padding);
-		ahash_request_set_crypt(hash, &pad_sg, (u8 *)&data_crc,
-					padding);
-		crypto_ahash_finup(hash);
-	} else {
-		ahash_request_set_crypt(hash, NULL, (u8 *)&data_crc, 0);
-		crypto_ahash_final(hash);
+		page_off = 0;
+		data_length -= cur_len;
 	}
 
-	return data_crc;
+	if (padding)
+		crc = crc32c(crc, pad_bytes, padding);
+
+	return ~crc;
 }
 
-static void iscsit_do_crypto_hash_buf(struct ahash_request *hash,
-	const void *buf, u32 payload_length, u32 padding,
-	const void *pad_bytes, void *data_crc)
+static u32 iscsit_crc_buf(const void *buf, u32 payload_length,
+			  u32 padding, const void *pad_bytes)
 {
-	struct scatterlist sg[2];
+	u32 crc = ~0;
 
-	sg_init_table(sg, ARRAY_SIZE(sg));
-	sg_set_buf(sg, buf, payload_length);
-	if (padding)
-		sg_set_buf(sg + 1, pad_bytes, padding);
+	crc = crc32c(crc, buf, payload_length);
 
-	ahash_request_set_crypt(hash, sg, data_crc, payload_length + padding);
+	if (padding)
+		crc = crc32c(crc, pad_bytes, padding);
 
-	crypto_ahash_digest(hash);
+	return ~crc;
 }
 
 int
 __iscsit_check_dataout_hdr(struct iscsit_conn *conn, void *buf,
 			   struct iscsit_cmd *cmd, u32 payload_length,
@@ -1660,15 +1618,12 @@ iscsit_get_dataout(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 		return -1;
 
 	if (conn->conn_ops->DataDigest) {
 		u32 data_crc;
 
-		data_crc = iscsit_do_crypto_hash_sg(conn->conn_rx_hash, cmd,
-						    be32_to_cpu(hdr->offset),
-						    payload_length, padding,
-						    cmd->pad_bytes);
-
+		data_crc = iscsit_crc_sglist(cmd, payload_length, padding,
+					     cmd->pad_bytes);
 		if (checksum != data_crc) {
 			pr_err("ITT: 0x%08x, Offset: %u, Length: %u,"
 				" DataSN: 0x%08x, CRC32C DataDigest 0x%08x"
 				" does not match computed 0x%08x\n",
 				hdr->itt, hdr->offset, payload_length,
@@ -1923,14 +1878,12 @@ static int iscsit_handle_nop_out(struct iscsit_conn *conn, struct iscsit_cmd *cm
 			ret = -1;
 			goto out;
 		}
 
 		if (conn->conn_ops->DataDigest) {
-			iscsit_do_crypto_hash_buf(conn->conn_rx_hash, ping_data,
-						  payload_length, padding,
-						  cmd->pad_bytes, &data_crc);
-
+			data_crc = iscsit_crc_buf(ping_data, payload_length,
+						  padding, cmd->pad_bytes);
 			if (checksum != data_crc) {
 				pr_err("Ping data CRC32C DataDigest"
 				" 0x%08x does not match computed 0x%08x\n",
 					checksum, data_crc);
 				if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
@@ -2326,14 +2279,11 @@ iscsit_handle_text_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 		rx_got = rx_data(conn, &iov[0], niov, rx_size);
 		if (rx_got != rx_size)
 			goto reject;
 
 		if (conn->conn_ops->DataDigest) {
-			iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
-						  text_in, rx_size, 0, NULL,
-						  &data_crc);
-
+			data_crc = iscsit_crc_buf(text_in, rx_size, 0, NULL);
 			if (checksum != data_crc) {
 				pr_err("Text data CRC32C DataDigest"
 					" 0x%08x does not match computed"
 					" 0x%08x\n", checksum, data_crc);
 				if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
@@ -2686,14 +2636,12 @@ static int iscsit_handle_immediate_data(
 	}
 
 	if (conn->conn_ops->DataDigest) {
 		u32 data_crc;
 
-		data_crc = iscsit_do_crypto_hash_sg(conn->conn_rx_hash, cmd,
-						    cmd->write_data_done, length, padding,
-						    cmd->pad_bytes);
-
+		data_crc = iscsit_crc_sglist(cmd, length, padding,
+					     cmd->pad_bytes);
 		if (checksum != data_crc) {
 			pr_err("ImmediateData CRC32C DataDigest 0x%08x"
 				" does not match computed 0x%08x\n", checksum,
 				data_crc);
 
@@ -4114,14 +4062,12 @@ static void iscsit_get_rx_pdu(struct iscsit_conn *conn)
 			if (ret != ISCSI_CRC_LEN) {
 				iscsit_rx_thread_wait_for_tcp(conn);
 				break;
 			}
 
-			iscsit_do_crypto_hash_buf(conn->conn_rx_hash, buffer,
-						  ISCSI_HDR_LEN, 0, NULL,
-						  &checksum);
-
+			checksum = iscsit_crc_buf(buffer, ISCSI_HDR_LEN, 0,
+						  NULL);
 			if (digest != checksum) {
 				pr_err("HeaderDigest CRC32C failed,"
 					" received 0x%08x, computed 0x%08x\n",
 					digest, checksum);
 				/*
@@ -4404,19 +4350,10 @@ int iscsit_close_connection(
 	 * If any other processes are accessing this connection pointer we
 	 * must wait until they have completed.
 	 */
 	iscsit_check_conn_usage_count(conn);
 
-	ahash_request_free(conn->conn_tx_hash);
-	if (conn->conn_rx_hash) {
-		struct crypto_ahash *tfm;
-
-		tfm = crypto_ahash_reqtfm(conn->conn_rx_hash);
-		ahash_request_free(conn->conn_rx_hash);
-		crypto_free_ahash(tfm);
-	}
-
 	if (conn->sock)
 		sock_release(conn->sock);
 
 	if (conn->conn_transport->iscsit_free_conn)
 		conn->conn_transport->iscsit_free_conn(conn);
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 90b870f234f0..c2ac9a99ebbb 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -6,11 +6,10 @@
  *
  * Author: Nicholas A. Bellinger <nab at linux-iscsi.org>
  *
  ******************************************************************************/
 
-#include <crypto/hash.h>
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/kthread.h>
 #include <linux/sched/signal.h>
 #include <linux/idr.h>
@@ -69,50 +68,10 @@ static struct iscsi_login *iscsi_login_init_conn(struct iscsit_conn *conn)
 out_login:
 	kfree(login);
 	return NULL;
 }
 
-/*
- * Used by iscsi_target_nego.c:iscsi_target_locate_portal() to setup
- * per struct iscsit_conn libcrypto contexts for crc32c and crc32-intel
- */
-int iscsi_login_setup_crypto(struct iscsit_conn *conn)
-{
-	struct crypto_ahash *tfm;
-
-	/*
-	 * Setup slicing by CRC32C algorithm for RX and TX libcrypto contexts
-	 * which will default to crc32c_intel.ko for cpu_has_xmm4_2, or fallback
-	 * to software 1x8 byte slicing from crc32c.ko
-	 */
-	tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC);
-	if (IS_ERR(tfm)) {
-		pr_err("crypto_alloc_ahash() failed\n");
-		return -ENOMEM;
-	}
-
-	conn->conn_rx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
-	if (!conn->conn_rx_hash) {
-		pr_err("ahash_request_alloc() failed for conn_rx_hash\n");
-		crypto_free_ahash(tfm);
-		return -ENOMEM;
-	}
-	ahash_request_set_callback(conn->conn_rx_hash, 0, NULL, NULL);
-
-	conn->conn_tx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
-	if (!conn->conn_tx_hash) {
-		pr_err("ahash_request_alloc() failed for conn_tx_hash\n");
-		ahash_request_free(conn->conn_rx_hash);
-		conn->conn_rx_hash = NULL;
-		crypto_free_ahash(tfm);
-		return -ENOMEM;
-	}
-	ahash_request_set_callback(conn->conn_tx_hash, 0, NULL, NULL);
-
-	return 0;
-}
-
 static int iscsi_login_check_initiator_version(
 	struct iscsit_conn *conn,
 	u8 version_max,
 	u8 version_min)
 {
@@ -1163,19 +1122,10 @@ void iscsi_target_login_sess_out(struct iscsit_conn *conn,
 		} else
 			spin_unlock_bh(&conn->sess->conn_lock);
 		iscsit_dec_session_usage_count(conn->sess);
 	}
 
-	ahash_request_free(conn->conn_tx_hash);
-	if (conn->conn_rx_hash) {
-		struct crypto_ahash *tfm;
-
-		tfm = crypto_ahash_reqtfm(conn->conn_rx_hash);
-		ahash_request_free(conn->conn_rx_hash);
-		crypto_free_ahash(tfm);
-	}
-
 	if (conn->param_list) {
 		iscsi_release_param_list(conn->param_list);
 		conn->param_list = NULL;
 	}
 	iscsi_target_nego_release(conn);
diff --git a/drivers/target/iscsi/iscsi_target_login.h b/drivers/target/iscsi/iscsi_target_login.h
index e8760735486b..03c7d695d58f 100644
--- a/drivers/target/iscsi/iscsi_target_login.h
+++ b/drivers/target/iscsi/iscsi_target_login.h
@@ -7,11 +7,10 @@
 struct iscsit_conn;
 struct iscsi_login;
 struct iscsi_np;
 struct sockaddr_storage;
 
-extern int iscsi_login_setup_crypto(struct iscsit_conn *);
 extern int iscsi_check_for_session_reinstatement(struct iscsit_conn *);
 extern int iscsi_login_post_auth_non_zero_tsih(struct iscsit_conn *, u16, u32);
 extern int iscsit_setup_np(struct iscsi_np *,
 				struct sockaddr_storage *);
 extern int iscsi_target_setup_login_socket(struct iscsi_np *,
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index fa3fb5f4e6bc..16e3ded98c32 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -1192,18 +1192,11 @@ int iscsi_target_locate_portal(
 	if (!sessiontype) {
 		if (!login->leading_connection)
 			goto get_target;
 
 		sess->sess_ops->SessionType = 1;
-		/*
-		 * Setup crc32c modules from libcrypto
-		 */
-		if (iscsi_login_setup_crypto(conn) < 0) {
-			pr_err("iscsi_login_setup_crypto() failed\n");
-			ret = -1;
-			goto out;
-		}
+
 		/*
 		 * Serialize access across the discovery struct iscsi_portal_group to
 		 * process login attempt.
 		 */
 		conn->tpg = iscsit_global->discovery_tpg;
@@ -1256,21 +1249,11 @@ int iscsi_target_locate_portal(
 		ret = -1;
 		goto out;
 	}
 	conn->tpg_np = tpg_np;
 	pr_debug("Located Portal Group Object: %hu\n", conn->tpg->tpgt);
-	/*
-	 * Setup crc32c modules from libcrypto
-	 */
-	if (iscsi_login_setup_crypto(conn) < 0) {
-		pr_err("iscsi_login_setup_crypto() failed\n");
-		kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put);
-		iscsit_put_tiqn_for_login(tiqn);
-		conn->tpg = NULL;
-		ret = -1;
-		goto out;
-	}
+
 	/*
 	 * Serialize access across the struct iscsi_portal_group to
 	 * process login attempt.
 	 */
 	if (iscsit_access_np(np, conn->tpg) < 0) {
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h
index 60af7c63b34e..51ca80abacf7 100644
--- a/include/target/iscsi/iscsi_target_core.h
+++ b/include/target/iscsi/iscsi_target_core.h
@@ -574,13 +574,10 @@ struct iscsit_conn {
 	spinlock_t		nopin_timer_lock;
 	spinlock_t		response_queue_lock;
 	spinlock_t		state_lock;
 	spinlock_t		login_timer_lock;
 	spinlock_t		login_worker_lock;
-	/* libcrypto RX and TX contexts for crc32c */
-	struct ahash_request	*conn_rx_hash;
-	struct ahash_request	*conn_tx_hash;
 	/* Used for scheduling TX and RX connection kthreads */
 	cpumask_var_t		conn_cpumask;
 	cpumask_var_t		allowed_cpumask;
 	unsigned int		conn_rx_reset_cpumask:1;
 	unsigned int		conn_tx_reset_cpumask:1;
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:40 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:40 -0800
Subject: [PATCH v4 15/19] lib/crc32: make crc32c() go directly to lib
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-16-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the lower level __crc32c_le() library function is optimized for
each architecture, make crc32c() just call that instead of taking an
inefficient and error-prone detour through the shash API.

Note: a future cleanup should make crc32c_le() be the actual library
function instead of __crc32c_le().  That will require updating callers
of __crc32c_le() to use crc32c_le() instead, and updating callers of
crc32c_le() that expect a 'const void *' arg to expect 'const u8 *'
instead.  Similarly, a future cleanup should remove LIBCRC32C by making
everyone who is selecting it just select CRC32 directly instead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 include/linux/crc32c.h |  7 ++--
 lib/Kconfig            | 10 ++----
 lib/Makefile           |  1 -
 lib/libcrc32c.c        | 74 ------------------------------------------
 4 files changed, 8 insertions(+), 84 deletions(-)
 delete mode 100644 lib/libcrc32c.c

diff --git a/include/linux/crc32c.h b/include/linux/crc32c.h
index 357ae4611a45..47eb78003c26 100644
--- a/include/linux/crc32c.h
+++ b/include/linux/crc32c.h
@@ -1,12 +1,15 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _LINUX_CRC32C_H
 #define _LINUX_CRC32C_H
 
-#include <linux/types.h>
+#include <linux/crc32.h>
 
-extern u32 crc32c(u32 crc, const void *address, unsigned int length);
+static inline u32 crc32c(u32 crc, const void *address, unsigned int length)
+{
+	return __crc32c_le(crc, address, length);
+}
 
 /* This macro exists for backwards-compatibility. */
 #define crc32c_le crc32c
 
 #endif	/* _LINUX_CRC32C_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 8858030bebae..d0c2dc0dac32 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -308,18 +308,14 @@ config CRC7
 	  the kernel tree does. Such modules that use library CRC7
 	  functions require M here.
 
 config LIBCRC32C
 	tristate "CRC32c (Castagnoli, et al) Cyclic Redundancy-Check"
-	select CRYPTO
-	select CRYPTO_CRC32C
+	select CRC32
 	help
-	  This option is provided for the case where no in-kernel-tree
-	  modules require CRC32c functions, but a module built outside the
-	  kernel tree does. Such modules that use library CRC32c functions
-	  require M here.  See Castagnoli93.
-	  Module will be libcrc32c.
+	  This option just selects CRC32 and is provided for compatibility
+	  purposes until the users are updated to select CRC32 directly.
 
 config CRC8
 	tristate "CRC8 function"
 	help
 	  This option provides CRC8 function. Drivers may select this
diff --git a/lib/Makefile b/lib/Makefile
index a8155c972f02..6573163d24e4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -165,11 +165,10 @@ obj-$(CONFIG_CRC_ITU_T)	+= crc-itu-t.o
 obj-$(CONFIG_CRC32)	+= crc32.o
 obj-$(CONFIG_CRC64)     += crc64.o
 obj-$(CONFIG_CRC32_SELFTEST)	+= crc32test.o
 obj-$(CONFIG_CRC4)	+= crc4.o
 obj-$(CONFIG_CRC7)	+= crc7.o
-obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
 obj-$(CONFIG_CRC8)	+= crc8.o
 obj-$(CONFIG_CRC64_ROCKSOFT) += crc64-rocksoft.o
 obj-$(CONFIG_XXHASH)	+= xxhash.o
 obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
 
diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c
deleted file mode 100644
index 649e687413a0..000000000000
--- a/lib/libcrc32c.c
+++ /dev/null
@@ -1,74 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* 
- * CRC32C
- *@Article{castagnoli-crc,
- * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
- * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
- *                 and 32 Parity Bits}},
- * journal =      IEEE Transactions on Communication,
- * year =         {1993},
- * volume =       {41},
- * number =       {6},
- * pages =        {},
- * month =        {June},
- *}
- * Used by the iSCSI driver, possibly others, and derived from
- * the iscsi-crc.c module of the linux-iscsi driver at
- * http://linux-iscsi.sourceforge.net.
- *
- * Following the example of lib/crc32, this function is intended to be
- * flexible and useful for all users.  Modules that currently have their
- * own crc32c, but hopefully may be able to use this one are:
- *  net/sctp (please add all your doco to here if you change to
- *            use this one!)
- *  <endoflist>
- *
- * Copyright (c) 2004 Cisco Systems, Inc.
- */
-
-#include <crypto/hash.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/crc32c.h>
-
-static struct crypto_shash *tfm;
-
-u32 crc32c(u32 crc, const void *address, unsigned int length)
-{
-	SHASH_DESC_ON_STACK(shash, tfm);
-	u32 ret, *ctx = (u32 *)shash_desc_ctx(shash);
-	int err;
-
-	shash->tfm = tfm;
-	*ctx = crc;
-
-	err = crypto_shash_update(shash, address, length);
-	BUG_ON(err);
-
-	ret = *ctx;
-	barrier_data(ctx);
-	return ret;
-}
-
-EXPORT_SYMBOL(crc32c);
-
-static int __init libcrc32c_mod_init(void)
-{
-	tfm = crypto_alloc_shash("crc32c", 0, 0);
-	return PTR_ERR_OR_ZERO(tfm);
-}
-
-static void __exit libcrc32c_mod_fini(void)
-{
-	crypto_free_shash(tfm);
-}
-
-module_init(libcrc32c_mod_init);
-module_exit(libcrc32c_mod_fini);
-
-MODULE_AUTHOR("Clay Haapala <chaapala at cisco.com>");
-MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
-MODULE_LICENSE("GPL");
-MODULE_SOFTDEP("pre: crc32c");
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:42 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:42 -0800
Subject: [PATCH v4 17/19] jbd2: switch to using the crc32c library
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-18-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the crc32c() library function directly takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32c().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Darrick J. Wong <djwong at kernel.org>
Acked-by: Theodore Ts'o <tytso at mit.edu>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/jbd2/Kconfig      |  2 --
 fs/jbd2/journal.c    | 30 +++---------------------------
 include/linux/jbd2.h | 33 +++------------------------------
 3 files changed, 6 insertions(+), 59 deletions(-)

diff --git a/fs/jbd2/Kconfig b/fs/jbd2/Kconfig
index 4ad2c67f93f1..9c19e1512101 100644
--- a/fs/jbd2/Kconfig
+++ b/fs/jbd2/Kconfig
@@ -1,11 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config JBD2
 	tristate
 	select CRC32
-	select CRYPTO
-	select CRYPTO_CRC32C
 	help
 	  This is a generic journaling layer for block devices that support
 	  both 32-bit and 64-bit block numbers.  It is currently used by
 	  the ext4 and OCFS2 filesystems, but it could also be used to add
 	  journal support to other file systems or block devices such
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 7e49d912b091..d8084b31b361 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1367,24 +1367,16 @@ static int journal_check_superblock(journal_t *journal)
 		printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2/3 "
 		       "at the same time!\n");
 		return err;
 	}
 
-	/* Load the checksum driver */
 	if (jbd2_journal_has_csum_v2or3_feature(journal)) {
 		if (sb->s_checksum_type != JBD2_CRC32C_CHKSUM) {
 			printk(KERN_ERR "JBD2: Unknown checksum type\n");
 			return err;
 		}
 
-		journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
-		if (IS_ERR(journal->j_chksum_driver)) {
-			printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
-			err = PTR_ERR(journal->j_chksum_driver);
-			journal->j_chksum_driver = NULL;
-			return err;
-		}
 		/* Check superblock checksum */
 		if (sb->s_checksum != jbd2_superblock_csum(journal, sb)) {
 			printk(KERN_ERR "JBD2: journal checksum error\n");
 			err = -EFSBADCRC;
 			return err;
@@ -1606,12 +1598,10 @@ static journal_t *journal_init_common(struct block_device *bdev,
 
 	return journal;
 
 err_cleanup:
 	percpu_counter_destroy(&journal->j_checkpoint_jh_count);
-	if (journal->j_chksum_driver)
-		crypto_free_shash(journal->j_chksum_driver);
 	kfree(journal->j_wbuf);
 	jbd2_journal_destroy_revoke(journal);
 	journal_fail_superblock(journal);
 	kfree(journal);
 	return ERR_PTR(err);
@@ -2189,12 +2179,10 @@ int jbd2_journal_destroy(journal_t *journal)
 	if (journal->j_proc_entry)
 		jbd2_stats_proc_exit(journal);
 	iput(journal->j_inode);
 	if (journal->j_revoke)
 		jbd2_journal_destroy_revoke(journal);
-	if (journal->j_chksum_driver)
-		crypto_free_shash(journal->j_chksum_driver);
 	kfree(journal->j_fc_wbuf);
 	kfree(journal->j_wbuf);
 	kfree(journal);
 
 	return err;
@@ -2335,31 +2323,19 @@ int jbd2_journal_set_features(journal_t *journal, unsigned long compat,
 			pr_err("JBD2: Cannot enable fast commits.\n");
 			return 0;
 		}
 	}
 
-	/* Load the checksum driver if necessary */
-	if ((journal->j_chksum_driver == NULL) &&
-	    INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
-		journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
-		if (IS_ERR(journal->j_chksum_driver)) {
-			printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
-			journal->j_chksum_driver = NULL;
-			return 0;
-		}
-		/* Precompute checksum seed for all metadata */
-		journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid,
-						   sizeof(sb->s_uuid));
-	}
-
 	lock_buffer(journal->j_sb_buffer);
 
-	/* If enabling v3 checksums, update superblock */
+	/* If enabling v3 checksums, update superblock and precompute seed */
 	if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
 		sb->s_checksum_type = JBD2_CRC32C_CHKSUM;
 		sb->s_feature_compat &=
 			~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
+		journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid,
+						   sizeof(sb->s_uuid));
 	}
 
 	/* If enabling v1 checksums, downgrade superblock */
 	if (COMPAT_FEATURE_ON(JBD2_FEATURE_COMPAT_CHECKSUM))
 		sb->s_feature_incompat &=
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 50f7ea8714bf..561025b4f3d9 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -26,11 +26,11 @@
 #include <linux/mutex.h>
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <linux/bit_spinlock.h>
 #include <linux/blkdev.h>
-#include <crypto/hash.h>
+#include <linux/crc32c.h>
 #endif
 
 #define journal_oom_retry 1
 
 /*
@@ -1239,17 +1239,10 @@ struct journal_s
 	 * An opaque pointer to fs-private information.  ext3 puts its
 	 * superblock pointer here.
 	 */
 	void *j_private;
 
-	/**
-	 * @j_chksum_driver:
-	 *
-	 * Reference to checksum algorithm driver via cryptoapi.
-	 */
-	struct crypto_shash *j_chksum_driver;
-
 	/**
 	 * @j_csum_seed:
 	 *
 	 * Precomputed journal UUID checksum for seeding other checksums.
 	 */
@@ -1748,14 +1741,11 @@ static inline bool jbd2_journal_has_csum_v2or3_feature(journal_t *j)
 	return jbd2_has_feature_csum2(j) || jbd2_has_feature_csum3(j);
 }
 
 static inline int jbd2_journal_has_csum_v2or3(journal_t *journal)
 {
-	WARN_ON_ONCE(jbd2_journal_has_csum_v2or3_feature(journal) &&
-		     journal->j_chksum_driver == NULL);
-
-	return journal->j_chksum_driver != NULL;
+	return jbd2_journal_has_csum_v2or3_feature(journal);
 }
 
 static inline int jbd2_journal_get_num_fc_blks(journal_superblock_t *jsb)
 {
 	int num_fc_blocks = be32_to_cpu(jsb->s_num_fc_blks);
@@ -1788,31 +1778,14 @@ static inline unsigned long jbd2_log_space_left(journal_t *journal)
 #define BJ_Forget	2	/* Buffer superseded by this transaction */
 #define BJ_Shadow	3	/* Buffer contents being shadowed to the log */
 #define BJ_Reserved	4	/* Buffer is reserved for access by journal */
 #define BJ_Types	5
 
-/* JBD uses a CRC32 checksum */
-#define JBD_MAX_CHECKSUM_SIZE 4
-
 static inline u32 jbd2_chksum(journal_t *journal, u32 crc,
 			      const void *address, unsigned int length)
 {
-	DEFINE_RAW_FLEX(struct shash_desc, desc, __ctx,
-		DIV_ROUND_UP(JBD_MAX_CHECKSUM_SIZE,
-			     sizeof(*((struct shash_desc *)0)->__ctx)));
-	int err;
-
-	BUG_ON(crypto_shash_descsize(journal->j_chksum_driver) >
-		JBD_MAX_CHECKSUM_SIZE);
-
-	desc->tfm = journal->j_chksum_driver;
-	*(u32 *)desc->__ctx = crc;
-
-	err = crypto_shash_update(desc, address, length);
-	BUG_ON(err);
-
-	return *(u32 *)desc->__ctx;
+	return crc32c(crc, address, length);
 }
 
 /* Return most recent uncommitted transaction */
 static inline tid_t  jbd2_get_latest_transaction(journal_t *journal)
 {
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:44 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:44 -0800
Subject: [PATCH v2 00/12] Wire up CRC-T10DIF library functions to arch-optimized code
Message-ID: <20241202012056.209768-1-ebiggers@kernel.org>

This patchset is also available in git via:

    git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git crc-t10dif-lib-v2

This patchset updates the kernel's CRC-T10DIF library functions to be
directly optimized for x86, arm, arm64, and powerpc without taking an
unnecessary and inefficient detour through the crypto API.  It follows
the same approach that I'm taking for CRC32 in the patchset
https://lore.kernel.org/lkml/20241202010844.144356-1-ebiggers at kernel.org/

This patchset also adds a CRC KUnit test suite that covers multiple CRC
variants, and deletes some older ad-hoc tests that are obsoleted by it.

This patchset applies to v6.13-rc1 plus my CRC32 patchset.  It can be
retrieved from git using above command.  This is targeting 6.14.

Changed in v2:
  - Rebased onto v6.13-rc1.
  - Tweaked crc_t10dif_arch() for arm32 and arm64 to not call
    crypto_simd_usable() more times than is necessary.
  - Added patch removing redundant crc16_kunit.c which got added in v6.13-rc1.
  - Made some small tweaks to crc_kunit.c.
  - Listed Ard as a reviewer in the MAINTAINERS entry.
  - Dropped scripts/crc from MAINTAINERS entry, as it hasn't been added yet.
  - Clarified a commit message.
  - Added Reviewed-by and Acked-by's.

Eric Biggers (12):
  lib/crc-t10dif: stop wrapping the crypto API
  lib/crc-t10dif: add support for arch overrides
  crypto: crct10dif - expose arch-optimized lib function
  x86/crc-t10dif: expose CRC-T10DIF function through lib
  arm/crc-t10dif: expose CRC-T10DIF function through lib
  arm64/crc-t10dif: expose CRC-T10DIF function through lib
  powerpc/crc-t10dif: expose CRC-T10DIF function through lib
  lib/crc_kunit.c: add KUnit test suite for CRC library functions
  lib/crc16_kunit: delete obsolete crc16_kunit.c
  lib/crc32test: delete obsolete crc32test.c
  powerpc/crc: delete obsolete crc-vpmsum_test.c
  MAINTAINERS: add entry for CRC library

 MAINTAINERS                                   |  11 +
 arch/arm/Kconfig                              |   1 +
 arch/arm/crypto/Kconfig                       |  11 -
 arch/arm/crypto/Makefile                      |   2 -
 arch/arm/crypto/crct10dif-ce-glue.c           | 124 ---
 arch/arm/lib/Makefile                         |   3 +
 .../crc-t10dif-core.S}                        |   0
 arch/arm/lib/crc-t10dif-glue.c                |  80 ++
 arch/arm64/Kconfig                            |   1 +
 arch/arm64/configs/defconfig                  |   1 -
 arch/arm64/crypto/Kconfig                     |  10 -
 arch/arm64/crypto/Makefile                    |   3 -
 arch/arm64/crypto/crct10dif-ce-glue.c         | 132 ---
 arch/arm64/lib/Makefile                       |   3 +
 .../crc-t10dif-core.S}                        |   0
 arch/arm64/lib/crc-t10dif-glue.c              |  81 ++
 arch/m68k/configs/amiga_defconfig             |   1 -
 arch/m68k/configs/apollo_defconfig            |   1 -
 arch/m68k/configs/atari_defconfig             |   1 -
 arch/m68k/configs/bvme6000_defconfig          |   1 -
 arch/m68k/configs/hp300_defconfig             |   1 -
 arch/m68k/configs/mac_defconfig               |   1 -
 arch/m68k/configs/multi_defconfig             |   1 -
 arch/m68k/configs/mvme147_defconfig           |   1 -
 arch/m68k/configs/mvme16x_defconfig           |   1 -
 arch/m68k/configs/q40_defconfig               |   1 -
 arch/m68k/configs/sun3_defconfig              |   1 -
 arch/m68k/configs/sun3x_defconfig             |   1 -
 arch/powerpc/Kconfig                          |   1 +
 arch/powerpc/configs/powernv_defconfig        |   1 -
 arch/powerpc/configs/ppc64_defconfig          |   2 -
 arch/powerpc/crypto/Kconfig                   |  20 -
 arch/powerpc/crypto/Makefile                  |   3 -
 arch/powerpc/crypto/crc-vpmsum_test.c         | 133 ---
 arch/powerpc/lib/Makefile                     |   3 +
 .../crc-t10dif-glue.c}                        |  69 +-
 .../{crypto => lib}/crct10dif-vpmsum_asm.S    |   2 +-
 arch/s390/configs/debug_defconfig             |   1 -
 arch/x86/Kconfig                              |   1 +
 arch/x86/crypto/Kconfig                       |  10 -
 arch/x86/crypto/Makefile                      |   3 -
 arch/x86/crypto/crct10dif-pclmul_glue.c       | 143 ---
 arch/x86/lib/Makefile                         |   3 +
 arch/x86/lib/crc-t10dif-glue.c                |  51 ++
 .../{crypto => lib}/crct10dif-pcl-asm_64.S    |   0
 crypto/Kconfig                                |   1 +
 crypto/Makefile                               |   3 +-
 crypto/crct10dif_common.c                     |  82 --
 crypto/crct10dif_generic.c                    |  82 +-
 include/linux/crc-t10dif.h                    |  28 +-
 lib/Kconfig                                   |  43 +-
 lib/Kconfig.debug                             |  29 +-
 lib/Makefile                                  |   3 +-
 lib/crc-t10dif.c                              | 156 +---
 lib/crc16_kunit.c                             | 155 ----
 lib/crc32test.c                               | 852 ------------------
 lib/crc_kunit.c                               | 435 +++++++++
 .../testing/selftests/arm64/fp/kernel-test.c  |   3 +-
 58 files changed, 880 insertions(+), 1913 deletions(-)
 delete mode 100644 arch/arm/crypto/crct10dif-ce-glue.c
 rename arch/arm/{crypto/crct10dif-ce-core.S => lib/crc-t10dif-core.S} (100%)
 create mode 100644 arch/arm/lib/crc-t10dif-glue.c
 delete mode 100644 arch/arm64/crypto/crct10dif-ce-glue.c
 rename arch/arm64/{crypto/crct10dif-ce-core.S => lib/crc-t10dif-core.S} (100%)
 create mode 100644 arch/arm64/lib/crc-t10dif-glue.c
 delete mode 100644 arch/powerpc/crypto/crc-vpmsum_test.c
 rename arch/powerpc/{crypto/crct10dif-vpmsum_glue.c => lib/crc-t10dif-glue.c} (50%)
 rename arch/powerpc/{crypto => lib}/crct10dif-vpmsum_asm.S (99%)
 delete mode 100644 arch/x86/crypto/crct10dif-pclmul_glue.c
 create mode 100644 arch/x86/lib/crc-t10dif-glue.c
 rename arch/x86/{crypto => lib}/crct10dif-pcl-asm_64.S (100%)
 delete mode 100644 crypto/crct10dif_common.c
 delete mode 100644 lib/crc16_kunit.c
 delete mode 100644 lib/crc32test.c
 create mode 100644 lib/crc_kunit.c


base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
prerequisite-patch-id: f8b995a05288ddc7f06f93d5eb7ffc71f53232d4
prerequisite-patch-id: cda9f22081116d690534a921473af93d06ab7539
prerequisite-patch-id: 12e0b107ed65a4d61fe3c9aa29451b082276f84f
prerequisite-patch-id: 292ec37c4a28e33cce4c13ad75a3ad2104799352
prerequisite-patch-id: b1cf6138d2a225dcda1adedc89d20d36a54bb309
prerequisite-patch-id: 1a7519c0d1fc64926480c8be838a98b5095534ec
prerequisite-patch-id: 0f22f1d50b6c17c93825e4a0651d51f4de9efe47
prerequisite-patch-id: 285ac22e7e2bad4920c3872992aa45e7f04d3702
prerequisite-patch-id: 9b085b26ff8fe55cf7cd343e9123e742f82a1fbb
prerequisite-patch-id: a4e94f9bb7c2c1d4d5486877b660ca6d606a46ef
prerequisite-patch-id: 5d541cd572220aa5c1885a639693fc78210c6112
prerequisite-patch-id: 95195b4e2e9d9e0e7b1cafa37d0cf2b3373f007f
prerequisite-patch-id: da2e5649997b6265ef0e6ad90b8be6a7a1509705
prerequisite-patch-id: e4b967a2d11e31bb8ee1402313bc0c70b34af26b
prerequisite-patch-id: d535ea87c7ac3b194abc358567b97b5fd524c144
prerequisite-patch-id: 1b919d5298106e9014f09f6e9ca5c75cbb157399
prerequisite-patch-id: 19f12966c5081d27bc64bced052814b15f16b087
prerequisite-patch-id: a4251f6e980b8ac54aeb6cfb09f0ffe92396331d
prerequisite-patch-id: 6fad2aeaf54145934d2dfd52bed0464b18445fb5
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:45 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:45 -0800
Subject: [PATCH v2 01/12] lib/crc-t10dif: stop wrapping the crypto API
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-2-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

In preparation for making the CRC-T10DIF library directly optimized for
each architecture, like what has been done for CRC32, get rid of the
weird layering where crc_t10dif_update() calls into the crypto API.
Instead, move crc_t10dif_generic() into the crc-t10dif library module,
and make crc_t10dif_update() just call crc_t10dif_generic().
Acceleration will be reintroduced via crc_t10dif_arch() in the following
patches.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 crypto/Kconfig             |   1 +
 crypto/Makefile            |   2 +-
 crypto/crct10dif_common.c  |  82 -------------------
 include/linux/crc-t10dif.h |  16 ++--
 lib/Kconfig                |   2 -
 lib/crc-t10dif.c           | 156 +++++++++++--------------------------
 6 files changed, 58 insertions(+), 201 deletions(-)
 delete mode 100644 crypto/crct10dif_common.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6b0bfbccac08..b459e8a23acc 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1100,10 +1100,11 @@ config CRYPTO_CRC32
 	  Used by RoCEv2 and f2fs.
 
 config CRYPTO_CRCT10DIF
 	tristate "CRCT10DIF"
 	select CRYPTO_HASH
+	select CRC_T10DIF
 	help
 	  CRC16 CRC algorithm used for the T10 (SCSI) Data Integrity Field (DIF)
 
 	  CRC algorithm used by the SCSI Block Commands standard.
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 77abca715445..0537df1719d3 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -155,11 +155,11 @@ obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
 obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
 obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o
 obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o
 CFLAGS_crc32c_generic.o += -DARCH=$(ARCH)
 CFLAGS_crc32_generic.o += -DARCH=$(ARCH)
-obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o
+obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_generic.o
 obj-$(CONFIG_CRYPTO_CRC64_ROCKSOFT) += crc64_rocksoft_generic.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
 obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o
 obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
 obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o
diff --git a/crypto/crct10dif_common.c b/crypto/crct10dif_common.c
deleted file mode 100644
index b2fab366f518..000000000000
--- a/crypto/crct10dif_common.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Cryptographic API.
- *
- * T10 Data Integrity Field CRC16 Crypto Transform
- *
- * Copyright (c) 2007 Oracle Corporation.  All rights reserved.
- * Written by Martin K. Petersen <martin.petersen at oracle.com>
- * Copyright (C) 2013 Intel Corporation
- * Author: Tim Chen <tim.c.chen at linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-#include <linux/crc-t10dif.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-/* Table generated using the following polynomium:
- * x^16 + x^15 + x^11 + x^9 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
- * gt: 0x8bb7
- */
-static const __u16 t10_dif_crc_table[256] = {
-	0x0000, 0x8BB7, 0x9CD9, 0x176E, 0xB205, 0x39B2, 0x2EDC, 0xA56B,
-	0xEFBD, 0x640A, 0x7364, 0xF8D3, 0x5DB8, 0xD60F, 0xC161, 0x4AD6,
-	0x54CD, 0xDF7A, 0xC814, 0x43A3, 0xE6C8, 0x6D7F, 0x7A11, 0xF1A6,
-	0xBB70, 0x30C7, 0x27A9, 0xAC1E, 0x0975, 0x82C2, 0x95AC, 0x1E1B,
-	0xA99A, 0x222D, 0x3543, 0xBEF4, 0x1B9F, 0x9028, 0x8746, 0x0CF1,
-	0x4627, 0xCD90, 0xDAFE, 0x5149, 0xF422, 0x7F95, 0x68FB, 0xE34C,
-	0xFD57, 0x76E0, 0x618E, 0xEA39, 0x4F52, 0xC4E5, 0xD38B, 0x583C,
-	0x12EA, 0x995D, 0x8E33, 0x0584, 0xA0EF, 0x2B58, 0x3C36, 0xB781,
-	0xD883, 0x5334, 0x445A, 0xCFED, 0x6A86, 0xE131, 0xF65F, 0x7DE8,
-	0x373E, 0xBC89, 0xABE7, 0x2050, 0x853B, 0x0E8C, 0x19E2, 0x9255,
-	0x8C4E, 0x07F9, 0x1097, 0x9B20, 0x3E4B, 0xB5FC, 0xA292, 0x2925,
-	0x63F3, 0xE844, 0xFF2A, 0x749D, 0xD1F6, 0x5A41, 0x4D2F, 0xC698,
-	0x7119, 0xFAAE, 0xEDC0, 0x6677, 0xC31C, 0x48AB, 0x5FC5, 0xD472,
-	0x9EA4, 0x1513, 0x027D, 0x89CA, 0x2CA1, 0xA716, 0xB078, 0x3BCF,
-	0x25D4, 0xAE63, 0xB90D, 0x32BA, 0x97D1, 0x1C66, 0x0B08, 0x80BF,
-	0xCA69, 0x41DE, 0x56B0, 0xDD07, 0x786C, 0xF3DB, 0xE4B5, 0x6F02,
-	0x3AB1, 0xB106, 0xA668, 0x2DDF, 0x88B4, 0x0303, 0x146D, 0x9FDA,
-	0xD50C, 0x5EBB, 0x49D5, 0xC262, 0x6709, 0xECBE, 0xFBD0, 0x7067,
-	0x6E7C, 0xE5CB, 0xF2A5, 0x7912, 0xDC79, 0x57CE, 0x40A0, 0xCB17,
-	0x81C1, 0x0A76, 0x1D18, 0x96AF, 0x33C4, 0xB873, 0xAF1D, 0x24AA,
-	0x932B, 0x189C, 0x0FF2, 0x8445, 0x212E, 0xAA99, 0xBDF7, 0x3640,
-	0x7C96, 0xF721, 0xE04F, 0x6BF8, 0xCE93, 0x4524, 0x524A, 0xD9FD,
-	0xC7E6, 0x4C51, 0x5B3F, 0xD088, 0x75E3, 0xFE54, 0xE93A, 0x628D,
-	0x285B, 0xA3EC, 0xB482, 0x3F35, 0x9A5E, 0x11E9, 0x0687, 0x8D30,
-	0xE232, 0x6985, 0x7EEB, 0xF55C, 0x5037, 0xDB80, 0xCCEE, 0x4759,
-	0x0D8F, 0x8638, 0x9156, 0x1AE1, 0xBF8A, 0x343D, 0x2353, 0xA8E4,
-	0xB6FF, 0x3D48, 0x2A26, 0xA191, 0x04FA, 0x8F4D, 0x9823, 0x1394,
-	0x5942, 0xD2F5, 0xC59B, 0x4E2C, 0xEB47, 0x60F0, 0x779E, 0xFC29,
-	0x4BA8, 0xC01F, 0xD771, 0x5CC6, 0xF9AD, 0x721A, 0x6574, 0xEEC3,
-	0xA415, 0x2FA2, 0x38CC, 0xB37B, 0x1610, 0x9DA7, 0x8AC9, 0x017E,
-	0x1F65, 0x94D2, 0x83BC, 0x080B, 0xAD60, 0x26D7, 0x31B9, 0xBA0E,
-	0xF0D8, 0x7B6F, 0x6C01, 0xE7B6, 0x42DD, 0xC96A, 0xDE04, 0x55B3
-};
-
-__u16 crc_t10dif_generic(__u16 crc, const unsigned char *buffer, size_t len)
-{
-	unsigned int i;
-
-	for (i = 0 ; i < len ; i++)
-		crc = (crc << 8) ^ t10_dif_crc_table[((crc >> 8) ^ buffer[i]) & 0xff];
-
-	return crc;
-}
-EXPORT_SYMBOL(crc_t10dif_generic);
-
-MODULE_DESCRIPTION("T10 DIF CRC calculation common code");
-MODULE_LICENSE("GPL");
diff --git a/include/linux/crc-t10dif.h b/include/linux/crc-t10dif.h
index 6bb0c0bf357b..206ba2305483 100644
--- a/include/linux/crc-t10dif.h
+++ b/include/linux/crc-t10dif.h
@@ -4,13 +4,19 @@
 
 #include <linux/types.h>
 
 #define CRC_T10DIF_DIGEST_SIZE 2
 #define CRC_T10DIF_BLOCK_SIZE 1
-#define CRC_T10DIF_STRING "crct10dif"
 
-extern __u16 crc_t10dif_generic(__u16 crc, const unsigned char *buffer,
-				size_t len);
-extern __u16 crc_t10dif(unsigned char const *, size_t);
-extern __u16 crc_t10dif_update(__u16 crc, unsigned char const *, size_t);
+u16 crc_t10dif_generic(u16 crc, const u8 *p, size_t len);
+
+static inline u16 crc_t10dif_update(u16 crc, const u8 *p, size_t len)
+{
+	return crc_t10dif_generic(crc, p, len);
+}
+
+static inline u16 crc_t10dif(const u8 *p, size_t len)
+{
+	return crc_t10dif_update(0, p, len);
+}
 
 #endif
diff --git a/lib/Kconfig b/lib/Kconfig
index d0c2dc0dac32..be59f7cdf448 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -154,12 +154,10 @@ config CRC16
 	  the kernel tree does. Such modules that use library CRC16
 	  functions require M here.
 
 config CRC_T10DIF
 	tristate "CRC calculation for the T10 Data Integrity Field"
-	select CRYPTO
-	select CRYPTO_CRCT10DIF
 	help
 	  This option is only needed if a module that's not in the
 	  kernel tree needs to calculate CRC checks for use with the
 	  SCSI data integrity subsystem.
 
diff --git a/lib/crc-t10dif.c b/lib/crc-t10dif.c
index 1ed2ed487097..311c2ab829f1 100644
--- a/lib/crc-t10dif.c
+++ b/lib/crc-t10dif.c
@@ -7,125 +7,59 @@
  */
 
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/crc-t10dif.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <crypto/hash.h>
-#include <crypto/algapi.h>
-#include <linux/static_key.h>
-#include <linux/notifier.h>
 
-static struct crypto_shash __rcu *crct10dif_tfm;
-static DEFINE_STATIC_KEY_TRUE(crct10dif_fallback);
-static DEFINE_MUTEX(crc_t10dif_mutex);
-static struct work_struct crct10dif_rehash_work;
-
-static int crc_t10dif_notify(struct notifier_block *self, unsigned long val, void *data)
-{
-	struct crypto_alg *alg = data;
-
-	if (val != CRYPTO_MSG_ALG_LOADED ||
-	    strcmp(alg->cra_name, CRC_T10DIF_STRING))
-		return NOTIFY_DONE;
-
-	schedule_work(&crct10dif_rehash_work);
-	return NOTIFY_OK;
-}
-
-static void crc_t10dif_rehash(struct work_struct *work)
-{
-	struct crypto_shash *new, *old;
-
-	mutex_lock(&crc_t10dif_mutex);
-	old = rcu_dereference_protected(crct10dif_tfm,
-					lockdep_is_held(&crc_t10dif_mutex));
-	new = crypto_alloc_shash(CRC_T10DIF_STRING, 0, 0);
-	if (IS_ERR(new)) {
-		mutex_unlock(&crc_t10dif_mutex);
-		return;
-	}
-	rcu_assign_pointer(crct10dif_tfm, new);
-	mutex_unlock(&crc_t10dif_mutex);
-
-	if (old) {
-		synchronize_rcu();
-		crypto_free_shash(old);
-	} else {
-		static_branch_disable(&crct10dif_fallback);
-	}
-}
-
-static struct notifier_block crc_t10dif_nb = {
-	.notifier_call = crc_t10dif_notify,
+/*
+ * Table generated using the following polynomial:
+ * x^16 + x^15 + x^11 + x^9 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
+ * gt: 0x8bb7
+ */
+static const u16 t10_dif_crc_table[256] = {
+	0x0000, 0x8BB7, 0x9CD9, 0x176E, 0xB205, 0x39B2, 0x2EDC, 0xA56B,
+	0xEFBD, 0x640A, 0x7364, 0xF8D3, 0x5DB8, 0xD60F, 0xC161, 0x4AD6,
+	0x54CD, 0xDF7A, 0xC814, 0x43A3, 0xE6C8, 0x6D7F, 0x7A11, 0xF1A6,
+	0xBB70, 0x30C7, 0x27A9, 0xAC1E, 0x0975, 0x82C2, 0x95AC, 0x1E1B,
+	0xA99A, 0x222D, 0x3543, 0xBEF4, 0x1B9F, 0x9028, 0x8746, 0x0CF1,
+	0x4627, 0xCD90, 0xDAFE, 0x5149, 0xF422, 0x7F95, 0x68FB, 0xE34C,
+	0xFD57, 0x76E0, 0x618E, 0xEA39, 0x4F52, 0xC4E5, 0xD38B, 0x583C,
+	0x12EA, 0x995D, 0x8E33, 0x0584, 0xA0EF, 0x2B58, 0x3C36, 0xB781,
+	0xD883, 0x5334, 0x445A, 0xCFED, 0x6A86, 0xE131, 0xF65F, 0x7DE8,
+	0x373E, 0xBC89, 0xABE7, 0x2050, 0x853B, 0x0E8C, 0x19E2, 0x9255,
+	0x8C4E, 0x07F9, 0x1097, 0x9B20, 0x3E4B, 0xB5FC, 0xA292, 0x2925,
+	0x63F3, 0xE844, 0xFF2A, 0x749D, 0xD1F6, 0x5A41, 0x4D2F, 0xC698,
+	0x7119, 0xFAAE, 0xEDC0, 0x6677, 0xC31C, 0x48AB, 0x5FC5, 0xD472,
+	0x9EA4, 0x1513, 0x027D, 0x89CA, 0x2CA1, 0xA716, 0xB078, 0x3BCF,
+	0x25D4, 0xAE63, 0xB90D, 0x32BA, 0x97D1, 0x1C66, 0x0B08, 0x80BF,
+	0xCA69, 0x41DE, 0x56B0, 0xDD07, 0x786C, 0xF3DB, 0xE4B5, 0x6F02,
+	0x3AB1, 0xB106, 0xA668, 0x2DDF, 0x88B4, 0x0303, 0x146D, 0x9FDA,
+	0xD50C, 0x5EBB, 0x49D5, 0xC262, 0x6709, 0xECBE, 0xFBD0, 0x7067,
+	0x6E7C, 0xE5CB, 0xF2A5, 0x7912, 0xDC79, 0x57CE, 0x40A0, 0xCB17,
+	0x81C1, 0x0A76, 0x1D18, 0x96AF, 0x33C4, 0xB873, 0xAF1D, 0x24AA,
+	0x932B, 0x189C, 0x0FF2, 0x8445, 0x212E, 0xAA99, 0xBDF7, 0x3640,
+	0x7C96, 0xF721, 0xE04F, 0x6BF8, 0xCE93, 0x4524, 0x524A, 0xD9FD,
+	0xC7E6, 0x4C51, 0x5B3F, 0xD088, 0x75E3, 0xFE54, 0xE93A, 0x628D,
+	0x285B, 0xA3EC, 0xB482, 0x3F35, 0x9A5E, 0x11E9, 0x0687, 0x8D30,
+	0xE232, 0x6985, 0x7EEB, 0xF55C, 0x5037, 0xDB80, 0xCCEE, 0x4759,
+	0x0D8F, 0x8638, 0x9156, 0x1AE1, 0xBF8A, 0x343D, 0x2353, 0xA8E4,
+	0xB6FF, 0x3D48, 0x2A26, 0xA191, 0x04FA, 0x8F4D, 0x9823, 0x1394,
+	0x5942, 0xD2F5, 0xC59B, 0x4E2C, 0xEB47, 0x60F0, 0x779E, 0xFC29,
+	0x4BA8, 0xC01F, 0xD771, 0x5CC6, 0xF9AD, 0x721A, 0x6574, 0xEEC3,
+	0xA415, 0x2FA2, 0x38CC, 0xB37B, 0x1610, 0x9DA7, 0x8AC9, 0x017E,
+	0x1F65, 0x94D2, 0x83BC, 0x080B, 0xAD60, 0x26D7, 0x31B9, 0xBA0E,
+	0xF0D8, 0x7B6F, 0x6C01, 0xE7B6, 0x42DD, 0xC96A, 0xDE04, 0x55B3
 };
 
-__u16 crc_t10dif_update(__u16 crc, const unsigned char *buffer, size_t len)
-{
-	struct {
-		struct shash_desc shash;
-		__u16 crc;
-	} desc;
-	int err;
-
-	if (static_branch_unlikely(&crct10dif_fallback))
-		return crc_t10dif_generic(crc, buffer, len);
-
-	rcu_read_lock();
-	desc.shash.tfm = rcu_dereference(crct10dif_tfm);
-	desc.crc = crc;
-	err = crypto_shash_update(&desc.shash, buffer, len);
-	rcu_read_unlock();
-
-	BUG_ON(err);
-
-	return desc.crc;
-}
-EXPORT_SYMBOL(crc_t10dif_update);
-
-__u16 crc_t10dif(const unsigned char *buffer, size_t len)
-{
-	return crc_t10dif_update(0, buffer, len);
-}
-EXPORT_SYMBOL(crc_t10dif);
-
-static int __init crc_t10dif_mod_init(void)
-{
-	INIT_WORK(&crct10dif_rehash_work, crc_t10dif_rehash);
-	crypto_register_notifier(&crc_t10dif_nb);
-	crc_t10dif_rehash(&crct10dif_rehash_work);
-	return 0;
-}
-
-static void __exit crc_t10dif_mod_fini(void)
-{
-	crypto_unregister_notifier(&crc_t10dif_nb);
-	cancel_work_sync(&crct10dif_rehash_work);
-	crypto_free_shash(rcu_dereference_protected(crct10dif_tfm, 1));
-}
-
-module_init(crc_t10dif_mod_init);
-module_exit(crc_t10dif_mod_fini);
-
-static int crc_t10dif_transform_show(char *buffer, const struct kernel_param *kp)
+u16 crc_t10dif_generic(u16 crc, const u8 *p, size_t len)
 {
-	struct crypto_shash *tfm;
-	int len;
+	size_t i;
 
-	if (static_branch_unlikely(&crct10dif_fallback))
-		return sprintf(buffer, "fallback\n");
+	for (i = 0; i < len; i++)
+		crc = (crc << 8) ^ t10_dif_crc_table[(crc >> 8) ^ p[i]];
 
-	rcu_read_lock();
-	tfm = rcu_dereference(crct10dif_tfm);
-	len = snprintf(buffer, PAGE_SIZE, "%s\n",
-		       crypto_shash_driver_name(tfm));
-	rcu_read_unlock();
-
-	return len;
+	return crc;
 }
+EXPORT_SYMBOL(crc_t10dif_generic);
 
-module_param_call(transform, NULL, crc_t10dif_transform_show, NULL, 0444);
-
-MODULE_DESCRIPTION("T10 DIF CRC calculation (library API)");
+MODULE_DESCRIPTION("T10 DIF CRC calculation");
 MODULE_LICENSE("GPL");
-MODULE_SOFTDEP("pre: crct10dif");
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:46 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:46 -0800
Subject: [PATCH v2 02/12] lib/crc-t10dif: add support for arch overrides
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-3-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Following what was done for CRC32, add support for architecture-specific
override of the CRC-T10DIF library.  This will allow the CRC-T10DIF
library functions to access architecture-optimized code directly.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 include/linux/crc-t10dif.h | 12 ++++++++++++
 lib/Kconfig                | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/include/linux/crc-t10dif.h b/include/linux/crc-t10dif.h
index 206ba2305483..16787c1cee21 100644
--- a/include/linux/crc-t10dif.h
+++ b/include/linux/crc-t10dif.h
@@ -5,18 +5,30 @@
 #include <linux/types.h>
 
 #define CRC_T10DIF_DIGEST_SIZE 2
 #define CRC_T10DIF_BLOCK_SIZE 1
 
+u16 crc_t10dif_arch(u16 crc, const u8 *p, size_t len);
 u16 crc_t10dif_generic(u16 crc, const u8 *p, size_t len);
 
 static inline u16 crc_t10dif_update(u16 crc, const u8 *p, size_t len)
 {
+	if (IS_ENABLED(CONFIG_CRC_T10DIF_ARCH))
+		return crc_t10dif_arch(crc, p, len);
 	return crc_t10dif_generic(crc, p, len);
 }
 
 static inline u16 crc_t10dif(const u8 *p, size_t len)
 {
 	return crc_t10dif_update(0, p, len);
 }
 
+#if IS_ENABLED(CONFIG_CRC_T10DIF_ARCH)
+bool crc_t10dif_is_optimized(void);
+#else
+static inline bool crc_t10dif_is_optimized(void)
+{
+	return false;
+}
+#endif
+
 #endif
diff --git a/lib/Kconfig b/lib/Kconfig
index be59f7cdf448..e52a38d8d783 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -159,10 +159,42 @@ config CRC_T10DIF
 	help
 	  This option is only needed if a module that's not in the
 	  kernel tree needs to calculate CRC checks for use with the
 	  SCSI data integrity subsystem.
 
+config ARCH_HAS_CRC_T10DIF
+	bool
+
+choice
+	prompt "CRC-T10DIF implementation"
+	depends on CRC_T10DIF
+	default CRC_T10DIF_IMPL_ARCH if ARCH_HAS_CRC_T10DIF
+	default CRC_T10DIF_IMPL_GENERIC if !ARCH_HAS_CRC_T10DIF
+	help
+	  This option allows you to override the default choice of CRC-T10DIF
+	  implementation.
+
+config CRC_T10DIF_IMPL_ARCH
+	bool "Architecture-optimized" if ARCH_HAS_CRC_T10DIF
+	help
+	  Use the optimized implementation of CRC-T10DIF for the selected
+	  architecture.  It is recommended to keep this enabled, as it can
+	  greatly improve CRC-T10DIF performance.
+
+config CRC_T10DIF_IMPL_GENERIC
+	bool "Generic implementation"
+	help
+	  Use the generic table-based implementation of CRC-T10DIF.  Selecting
+	  this will reduce code size slightly but can greatly reduce CRC-T10DIF
+	  performance.
+
+endchoice
+
+config CRC_T10DIF_ARCH
+	tristate
+	default CRC_T10DIF if CRC_T10DIF_IMPL_ARCH
+
 config CRC64_ROCKSOFT
 	tristate "CRC calculation for the Rocksoft model CRC64"
 	select CRC64
 	select CRYPTO
 	select CRYPTO_CRC64_ROCKSOFT
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:49 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:49 -0800
Subject: [PATCH v2 05/12] arm/crc-t10dif: expose CRC-T10DIF function through lib
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-6-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the arm CRC-T10DIF assembly code into the lib directory and wire it
up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/arm/crypto/crct10dif-ce-glue.c to
arch/arm/lib/crc-t10dif-glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm/Kconfig                              |   1 +
 arch/arm/crypto/Kconfig                       |  11 --
 arch/arm/crypto/Makefile                      |   2 -
 arch/arm/crypto/crct10dif-ce-glue.c           | 124 ------------------
 arch/arm/lib/Makefile                         |   3 +
 .../crc-t10dif-core.S}                        |   0
 arch/arm/lib/crc-t10dif-glue.c                |  80 +++++++++++
 7 files changed, 84 insertions(+), 137 deletions(-)
 delete mode 100644 arch/arm/crypto/crct10dif-ce-glue.c
 rename arch/arm/{crypto/crct10dif-ce-core.S => lib/crc-t10dif-core.S} (100%)
 create mode 100644 arch/arm/lib/crc-t10dif-glue.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f817ca317b02..3ad4c3c97918 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -6,10 +6,11 @@ config ARM
 	select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
 	select ARCH_HAS_BINFMT_FLAT
 	select ARCH_HAS_CPU_CACHE_ALIASING
 	select ARCH_HAS_CPU_FINALIZE_INIT if MMU
 	select ARCH_HAS_CRC32 if KERNEL_MODE_NEON
+	select ARCH_HAS_CRC_T10DIF if KERNEL_MODE_NEON
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL if MMU
 	select ARCH_HAS_DMA_ALLOC if MMU
 	select ARCH_HAS_DMA_OPS
 	select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig
index ea0ebf336d0d..32650c8431d9 100644
--- a/arch/arm/crypto/Kconfig
+++ b/arch/arm/crypto/Kconfig
@@ -220,18 +220,7 @@ config CRYPTO_CHACHA20_NEON
 	  stream cipher algorithms
 
 	  Architecture: arm using:
 	  - NEON (Advanced SIMD) extensions
 
-config CRYPTO_CRCT10DIF_ARM_CE
-	tristate "CRCT10DIF"
-	depends on KERNEL_MODE_NEON
-	depends on CRC_T10DIF
-	select CRYPTO_HASH
-	help
-	  CRC16 CRC algorithm used for the T10 (SCSI) Data Integrity Field (DIF)
-
-	  Architecture: arm using:
-	  - PMULL (Polynomial Multiply Long) instructions
-
 endmenu
 
diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
index 38ec5cc1e844..3d0e23ff9e74 100644
--- a/arch/arm/crypto/Makefile
+++ b/arch/arm/crypto/Makefile
@@ -18,11 +18,10 @@ obj-$(CONFIG_CRYPTO_CURVE25519_NEON) += curve25519-neon.o
 
 obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o
 obj-$(CONFIG_CRYPTO_GHASH_ARM_CE) += ghash-arm-ce.o
-obj-$(CONFIG_CRYPTO_CRCT10DIF_ARM_CE) += crct10dif-arm-ce.o
 
 aes-arm-y	:= aes-cipher-core.o aes-cipher-glue.o
 aes-arm-bs-y	:= aes-neonbs-core.o aes-neonbs-glue.o
 sha1-arm-y	:= sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y	:= sha1-armv7-neon.o sha1_neon_glue.o
@@ -34,11 +33,10 @@ libblake2s-arm-y:= blake2s-core.o blake2s-glue.o
 blake2b-neon-y  := blake2b-neon-core.o blake2b-neon-glue.o
 sha1-arm-ce-y	:= sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y	:= sha2-ce-core.o sha2-ce-glue.o
 aes-arm-ce-y	:= aes-ce-core.o aes-ce-glue.o
 ghash-arm-ce-y	:= ghash-ce-core.o ghash-ce-glue.o
-crct10dif-arm-ce-y	:= crct10dif-ce-core.o crct10dif-ce-glue.o
 chacha-neon-y := chacha-scalar-core.o chacha-glue.o
 chacha-neon-$(CONFIG_KERNEL_MODE_NEON) += chacha-neon-core.o
 poly1305-arm-y := poly1305-core.o poly1305-glue.o
 nhpoly1305-neon-y := nh-neon-core.o nhpoly1305-neon-glue.o
 curve25519-neon-y := curve25519-core.o curve25519-glue.o
diff --git a/arch/arm/crypto/crct10dif-ce-glue.c b/arch/arm/crypto/crct10dif-ce-glue.c
deleted file mode 100644
index a8b74523729e..000000000000
--- a/arch/arm/crypto/crct10dif-ce-glue.c
+++ /dev/null
@@ -1,124 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions instructions
- *
- * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel at linaro.org>
- */
-
-#include <linux/crc-t10dif.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-
-#include <asm/neon.h>
-#include <asm/simd.h>
-
-#define CRC_T10DIF_PMULL_CHUNK_SIZE	16U
-
-asmlinkage u16 crc_t10dif_pmull64(u16 init_crc, const u8 *buf, size_t len);
-asmlinkage void crc_t10dif_pmull8(u16 init_crc, const u8 *buf, size_t len,
-				  u8 out[16]);
-
-static int crct10dif_init(struct shash_desc *desc)
-{
-	u16 *crc = shash_desc_ctx(desc);
-
-	*crc = 0;
-	return 0;
-}
-
-static int crct10dif_update_ce(struct shash_desc *desc, const u8 *data,
-			       unsigned int length)
-{
-	u16 *crc = shash_desc_ctx(desc);
-
-	if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE && crypto_simd_usable()) {
-		kernel_neon_begin();
-		*crc = crc_t10dif_pmull64(*crc, data, length);
-		kernel_neon_end();
-	} else {
-		*crc = crc_t10dif_generic(*crc, data, length);
-	}
-
-	return 0;
-}
-
-static int crct10dif_update_neon(struct shash_desc *desc, const u8 *data,
-			         unsigned int length)
-{
-	u16 *crcp = shash_desc_ctx(desc);
-	u8 buf[16] __aligned(16);
-	u16 crc = *crcp;
-
-	if (length > CRC_T10DIF_PMULL_CHUNK_SIZE && crypto_simd_usable()) {
-		kernel_neon_begin();
-		crc_t10dif_pmull8(crc, data, length, buf);
-		kernel_neon_end();
-
-		crc = 0;
-		data = buf;
-		length = sizeof(buf);
-	}
-
-	*crcp = crc_t10dif_generic(crc, data, length);
-	return 0;
-}
-
-static int crct10dif_final(struct shash_desc *desc, u8 *out)
-{
-	u16 *crc = shash_desc_ctx(desc);
-
-	*(u16 *)out = *crc;
-	return 0;
-}
-
-static struct shash_alg algs[] = {{
-	.digestsize		= CRC_T10DIF_DIGEST_SIZE,
-	.init			= crct10dif_init,
-	.update			= crct10dif_update_neon,
-	.final			= crct10dif_final,
-	.descsize		= CRC_T10DIF_DIGEST_SIZE,
-
-	.base.cra_name		= "crct10dif",
-	.base.cra_driver_name	= "crct10dif-arm-neon",
-	.base.cra_priority	= 150,
-	.base.cra_blocksize	= CRC_T10DIF_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-}, {
-	.digestsize		= CRC_T10DIF_DIGEST_SIZE,
-	.init			= crct10dif_init,
-	.update			= crct10dif_update_ce,
-	.final			= crct10dif_final,
-	.descsize		= CRC_T10DIF_DIGEST_SIZE,
-
-	.base.cra_name		= "crct10dif",
-	.base.cra_driver_name	= "crct10dif-arm-ce",
-	.base.cra_priority	= 200,
-	.base.cra_blocksize	= CRC_T10DIF_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-}};
-
-static int __init crc_t10dif_mod_init(void)
-{
-	if (!(elf_hwcap & HWCAP_NEON))
-		return -ENODEV;
-
-	return crypto_register_shashes(algs, 1 + !!(elf_hwcap2 & HWCAP2_PMULL));
-}
-
-static void __exit crc_t10dif_mod_exit(void)
-{
-	crypto_unregister_shashes(algs, 1 + !!(elf_hwcap2 & HWCAP2_PMULL));
-}
-
-module_init(crc_t10dif_mod_init);
-module_exit(crc_t10dif_mod_exit);
-
-MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel at linaro.org>");
-MODULE_DESCRIPTION("Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS_CRYPTO("crct10dif");
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 01cd4db2ed47..007874320937 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -46,5 +46,8 @@ endif
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 
 obj-$(CONFIG_CRC32_ARCH) += crc32-arm.o
 crc32-arm-y := crc32-glue.o crc32-core.o
+
+obj-$(CONFIG_CRC_T10DIF_ARCH) += crc-t10dif-arm.o
+crc-t10dif-arm-y := crc-t10dif-glue.o crc-t10dif-core.o
diff --git a/arch/arm/crypto/crct10dif-ce-core.S b/arch/arm/lib/crc-t10dif-core.S
similarity index 100%
rename from arch/arm/crypto/crct10dif-ce-core.S
rename to arch/arm/lib/crc-t10dif-core.S
diff --git a/arch/arm/lib/crc-t10dif-glue.c b/arch/arm/lib/crc-t10dif-glue.c
new file mode 100644
index 000000000000..d24dee62670e
--- /dev/null
+++ b/arch/arm/lib/crc-t10dif-glue.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions instructions
+ *
+ * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel at linaro.org>
+ */
+
+#include <linux/crc-t10dif.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <crypto/internal/simd.h>
+
+#include <asm/neon.h>
+#include <asm/simd.h>
+
+static DEFINE_STATIC_KEY_FALSE(have_neon);
+static DEFINE_STATIC_KEY_FALSE(have_pmull);
+
+#define CRC_T10DIF_PMULL_CHUNK_SIZE	16U
+
+asmlinkage u16 crc_t10dif_pmull64(u16 init_crc, const u8 *buf, size_t len);
+asmlinkage void crc_t10dif_pmull8(u16 init_crc, const u8 *buf, size_t len,
+				  u8 out[16]);
+
+u16 crc_t10dif_arch(u16 crc, const u8 *data, size_t length)
+{
+	if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE) {
+		if (static_branch_likely(&have_pmull)) {
+			if (crypto_simd_usable()) {
+				kernel_neon_begin();
+				crc = crc_t10dif_pmull64(crc, data, length);
+				kernel_neon_end();
+				return crc;
+			}
+		} else if (length > CRC_T10DIF_PMULL_CHUNK_SIZE &&
+			   static_branch_likely(&have_neon) &&
+			   crypto_simd_usable()) {
+			u8 buf[16] __aligned(16);
+
+			kernel_neon_begin();
+			crc_t10dif_pmull8(crc, data, length, buf);
+			kernel_neon_end();
+
+			crc = 0;
+			data = buf;
+			length = sizeof(buf);
+		}
+	}
+	return crc_t10dif_generic(crc, data, length);
+}
+EXPORT_SYMBOL(crc_t10dif_arch);
+
+static int __init crc_t10dif_arm_init(void)
+{
+	if (elf_hwcap & HWCAP_NEON) {
+		static_branch_enable(&have_neon);
+		if (elf_hwcap2 & HWCAP2_PMULL)
+			static_branch_enable(&have_pmull);
+	}
+	return 0;
+}
+arch_initcall(crc_t10dif_arm_init);
+
+static void __exit crc_t10dif_arm_exit(void)
+{
+}
+module_exit(crc_t10dif_arm_exit);
+
+bool crc_t10dif_is_optimized(void)
+{
+	return static_key_enabled(&have_neon);
+}
+EXPORT_SYMBOL(crc_t10dif_is_optimized);
+
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel at linaro.org>");
+MODULE_DESCRIPTION("Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions");
+MODULE_LICENSE("GPL v2");
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:50 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:50 -0800
Subject: [PATCH v2 06/12] arm64/crc-t10dif: expose CRC-T10DIF function through lib
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-7-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the arm64 CRC-T10DIF assembly code into the lib directory and wire
it up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/arm64/crypto/crct10dif-ce-glue.c to
arch/arm64/lib/crc-t10dif-glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm64/Kconfig                            |   1 +
 arch/arm64/configs/defconfig                  |   1 -
 arch/arm64/crypto/Kconfig                     |  10 --
 arch/arm64/crypto/Makefile                    |   3 -
 arch/arm64/crypto/crct10dif-ce-glue.c         | 132 ------------------
 arch/arm64/lib/Makefile                       |   3 +
 .../crc-t10dif-core.S}                        |   0
 arch/arm64/lib/crc-t10dif-glue.c              |  81 +++++++++++
 .../testing/selftests/arm64/fp/kernel-test.c  |   3 +-
 9 files changed, 86 insertions(+), 148 deletions(-)
 delete mode 100644 arch/arm64/crypto/crct10dif-ce-glue.c
 rename arch/arm64/{crypto/crct10dif-ce-core.S => lib/crc-t10dif-core.S} (100%)
 create mode 100644 arch/arm64/lib/crc-t10dif-glue.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 71f6310c8240..cbfd357f94a6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -20,10 +20,11 @@ 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_CC_PLATFORM
 	select ARCH_HAS_CRC32
+	select ARCH_HAS_CRC_T10DIF if KERNEL_MODE_NEON
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DMA_OPS if XEN
 	select ARCH_HAS_DMA_PREP_COHERENT
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..9c0d6b93a3c2 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1696,11 +1696,10 @@ CONFIG_CRYPTO_SHA512_ARM64_CE=m
 CONFIG_CRYPTO_SHA3_ARM64=m
 CONFIG_CRYPTO_SM3_ARM64_CE=m
 CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
 CONFIG_CRYPTO_AES_ARM64_BS=m
 CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
-CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m
 CONFIG_CRYPTO_DEV_SUN8I_CE=m
 CONFIG_CRYPTO_DEV_FSL_CAAM=m
 CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=m
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCOM_RNG=m
diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index e7d9bd8e4709..5636ab83f22a 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -310,17 +310,7 @@ config CRYPTO_SM4_ARM64_CE_GCM
 	  Architecture: arm64 using:
 	  - ARMv8 Crypto Extensions
 	  - PMULL (Polynomial Multiply Long) instructions
 	  - NEON (Advanced SIMD) extensions
 
-config CRYPTO_CRCT10DIF_ARM64_CE
-	tristate "CRCT10DIF (PMULL)"
-	depends on KERNEL_MODE_NEON && CRC_T10DIF
-	select CRYPTO_HASH
-	help
-	  CRC16 CRC algorithm used for the T10 (SCSI) Data Integrity Field (DIF)
-
-	  Architecture: arm64 using
-	  - PMULL (Polynomial Multiply Long) instructions
-
 endmenu
 
diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile
index fbe64dce66e0..e7139c4768ce 100644
--- a/arch/arm64/crypto/Makefile
+++ b/arch/arm64/crypto/Makefile
@@ -42,13 +42,10 @@ obj-$(CONFIG_CRYPTO_GHASH_ARM64_CE) += ghash-ce.o
 ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o
 
 obj-$(CONFIG_CRYPTO_POLYVAL_ARM64_CE) += polyval-ce.o
 polyval-ce-y := polyval-ce-glue.o polyval-ce-core.o
 
-obj-$(CONFIG_CRYPTO_CRCT10DIF_ARM64_CE) += crct10dif-ce.o
-crct10dif-ce-y := crct10dif-ce-core.o crct10dif-ce-glue.o
-
 obj-$(CONFIG_CRYPTO_AES_ARM64_CE) += aes-ce-cipher.o
 aes-ce-cipher-y := aes-ce-core.o aes-ce-glue.o
 
 obj-$(CONFIG_CRYPTO_AES_ARM64_CE_CCM) += aes-ce-ccm.o
 aes-ce-ccm-y := aes-ce-ccm-glue.o aes-ce-ccm-core.o
diff --git a/arch/arm64/crypto/crct10dif-ce-glue.c b/arch/arm64/crypto/crct10dif-ce-glue.c
deleted file mode 100644
index 08bcbd884395..000000000000
--- a/arch/arm64/crypto/crct10dif-ce-glue.c
+++ /dev/null
@@ -1,132 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Accelerated CRC-T10DIF using arm64 NEON and Crypto Extensions instructions
- *
- * Copyright (C) 2016 - 2017 Linaro Ltd <ard.biesheuvel at linaro.org>
- */
-
-#include <linux/cpufeature.h>
-#include <linux/crc-t10dif.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-
-#include <asm/neon.h>
-#include <asm/simd.h>
-
-#define CRC_T10DIF_PMULL_CHUNK_SIZE	16U
-
-asmlinkage void crc_t10dif_pmull_p8(u16 init_crc, const u8 *buf, size_t len,
-				    u8 out[16]);
-asmlinkage u16 crc_t10dif_pmull_p64(u16 init_crc, const u8 *buf, size_t len);
-
-static int crct10dif_init(struct shash_desc *desc)
-{
-	u16 *crc = shash_desc_ctx(desc);
-
-	*crc = 0;
-	return 0;
-}
-
-static int crct10dif_update_pmull_p8(struct shash_desc *desc, const u8 *data,
-			    unsigned int length)
-{
-	u16 *crcp = shash_desc_ctx(desc);
-	u16 crc = *crcp;
-	u8 buf[16];
-
-	if (length > CRC_T10DIF_PMULL_CHUNK_SIZE && crypto_simd_usable()) {
-		kernel_neon_begin();
-		crc_t10dif_pmull_p8(crc, data, length, buf);
-		kernel_neon_end();
-
-		crc = 0;
-		data = buf;
-		length = sizeof(buf);
-	}
-
-	*crcp = crc_t10dif_generic(crc, data, length);
-	return 0;
-}
-
-static int crct10dif_update_pmull_p64(struct shash_desc *desc, const u8 *data,
-			    unsigned int length)
-{
-	u16 *crc = shash_desc_ctx(desc);
-
-	if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE && crypto_simd_usable()) {
-		kernel_neon_begin();
-		*crc = crc_t10dif_pmull_p64(*crc, data, length);
-		kernel_neon_end();
-	} else {
-		*crc = crc_t10dif_generic(*crc, data, length);
-	}
-
-	return 0;
-}
-
-static int crct10dif_final(struct shash_desc *desc, u8 *out)
-{
-	u16 *crc = shash_desc_ctx(desc);
-
-	*(u16 *)out = *crc;
-	return 0;
-}
-
-static struct shash_alg crc_t10dif_alg[] = {{
-	.digestsize		= CRC_T10DIF_DIGEST_SIZE,
-	.init			= crct10dif_init,
-	.update			= crct10dif_update_pmull_p8,
-	.final			= crct10dif_final,
-	.descsize		= CRC_T10DIF_DIGEST_SIZE,
-
-	.base.cra_name		= "crct10dif",
-	.base.cra_driver_name	= "crct10dif-arm64-neon",
-	.base.cra_priority	= 150,
-	.base.cra_blocksize	= CRC_T10DIF_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-}, {
-	.digestsize		= CRC_T10DIF_DIGEST_SIZE,
-	.init			= crct10dif_init,
-	.update			= crct10dif_update_pmull_p64,
-	.final			= crct10dif_final,
-	.descsize		= CRC_T10DIF_DIGEST_SIZE,
-
-	.base.cra_name		= "crct10dif",
-	.base.cra_driver_name	= "crct10dif-arm64-ce",
-	.base.cra_priority	= 200,
-	.base.cra_blocksize	= CRC_T10DIF_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-}};
-
-static int __init crc_t10dif_mod_init(void)
-{
-	if (cpu_have_named_feature(PMULL))
-		return crypto_register_shashes(crc_t10dif_alg,
-					       ARRAY_SIZE(crc_t10dif_alg));
-	else
-		/* only register the first array element */
-		return crypto_register_shash(crc_t10dif_alg);
-}
-
-static void __exit crc_t10dif_mod_exit(void)
-{
-	if (cpu_have_named_feature(PMULL))
-		crypto_unregister_shashes(crc_t10dif_alg,
-					  ARRAY_SIZE(crc_t10dif_alg));
-	else
-		crypto_unregister_shash(crc_t10dif_alg);
-}
-
-module_cpu_feature_match(ASIMD, crc_t10dif_mod_init);
-module_exit(crc_t10dif_mod_exit);
-
-MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel at linaro.org>");
-MODULE_DESCRIPTION("CRC-T10DIF using arm64 NEON and Crypto Extensions");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS_CRYPTO("crct10dif");
-MODULE_ALIAS_CRYPTO("crct10dif-arm64-ce");
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 5fbcf0d56665..4d49dff721a8 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -14,10 +14,13 @@ endif
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
 
 obj-$(CONFIG_CRC32_ARCH) += crc32-arm64.o
 crc32-arm64-y := crc32.o crc32-glue.o
 
+obj-$(CONFIG_CRC_T10DIF_ARCH) += crc-t10dif-arm64.o
+crc-t10dif-arm64-y := crc-t10dif-glue.o crc-t10dif-core.o
+
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 
 obj-$(CONFIG_ARM64_MTE) += mte.o
 
 obj-$(CONFIG_KASAN_SW_TAGS) += kasan_sw_tags.o
diff --git a/arch/arm64/crypto/crct10dif-ce-core.S b/arch/arm64/lib/crc-t10dif-core.S
similarity index 100%
rename from arch/arm64/crypto/crct10dif-ce-core.S
rename to arch/arm64/lib/crc-t10dif-core.S
diff --git a/arch/arm64/lib/crc-t10dif-glue.c b/arch/arm64/lib/crc-t10dif-glue.c
new file mode 100644
index 000000000000..dab7e3796232
--- /dev/null
+++ b/arch/arm64/lib/crc-t10dif-glue.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated CRC-T10DIF using arm64 NEON and Crypto Extensions instructions
+ *
+ * Copyright (C) 2016 - 2017 Linaro Ltd <ard.biesheuvel at linaro.org>
+ */
+
+#include <linux/cpufeature.h>
+#include <linux/crc-t10dif.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <crypto/internal/simd.h>
+
+#include <asm/neon.h>
+#include <asm/simd.h>
+
+static DEFINE_STATIC_KEY_FALSE(have_asimd);
+static DEFINE_STATIC_KEY_FALSE(have_pmull);
+
+#define CRC_T10DIF_PMULL_CHUNK_SIZE	16U
+
+asmlinkage void crc_t10dif_pmull_p8(u16 init_crc, const u8 *buf, size_t len,
+				    u8 out[16]);
+asmlinkage u16 crc_t10dif_pmull_p64(u16 init_crc, const u8 *buf, size_t len);
+
+u16 crc_t10dif_arch(u16 crc, const u8 *data, size_t length)
+{
+	if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE) {
+		if (static_branch_likely(&have_pmull)) {
+			if (crypto_simd_usable()) {
+				kernel_neon_begin();
+				crc = crc_t10dif_pmull_p64(crc, data, length);
+				kernel_neon_end();
+				return crc;
+			}
+		} else if (length > CRC_T10DIF_PMULL_CHUNK_SIZE &&
+			   static_branch_likely(&have_asimd) &&
+			   crypto_simd_usable()) {
+			u8 buf[16];
+
+			kernel_neon_begin();
+			crc_t10dif_pmull_p8(crc, data, length, buf);
+			kernel_neon_end();
+
+			crc = 0;
+			data = buf;
+			length = sizeof(buf);
+		}
+	}
+	return crc_t10dif_generic(crc, data, length);
+}
+EXPORT_SYMBOL(crc_t10dif_arch);
+
+static int __init crc_t10dif_arm64_init(void)
+{
+	if (cpu_have_named_feature(ASIMD)) {
+		static_branch_enable(&have_asimd);
+		if (cpu_have_named_feature(PMULL))
+			static_branch_enable(&have_pmull);
+	}
+	return 0;
+}
+arch_initcall(crc_t10dif_arm64_init);
+
+static void __exit crc_t10dif_arm64_exit(void)
+{
+}
+module_exit(crc_t10dif_arm64_exit);
+
+bool crc_t10dif_is_optimized(void)
+{
+	return static_key_enabled(&have_asimd);
+}
+EXPORT_SYMBOL(crc_t10dif_is_optimized);
+
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel at linaro.org>");
+MODULE_DESCRIPTION("CRC-T10DIF using arm64 NEON and Crypto Extensions");
+MODULE_LICENSE("GPL v2");
diff --git a/tools/testing/selftests/arm64/fp/kernel-test.c b/tools/testing/selftests/arm64/fp/kernel-test.c
index 859345379044..348e8bef62c7 100644
--- a/tools/testing/selftests/arm64/fp/kernel-test.c
+++ b/tools/testing/selftests/arm64/fp/kernel-test.c
@@ -44,12 +44,11 @@ static void handle_kick_signal(int sig, siginfo_t *info, void *context)
 {
 	sigs++;
 }
 
 static char *drivers[] = {
-	"crct10dif-arm64-ce",
-	/* "crct10dif-arm64-neon", - Same priority as generic */
+	"crct10dif-arm64",
 	"sha1-ce",
 	"sha224-arm64",
 	"sha224-arm64-neon",
 	"sha224-ce",
 	"sha256-arm64",
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:51 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:51 -0800
Subject: [PATCH v2 07/12] powerpc/crc-t10dif: expose CRC-T10DIF function through lib
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-8-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the powerpc CRC-T10DIF assembly code into the lib directory and
wire it up to the library interface.  This allows it to be used without
going through the crypto API.  It remains usable via the crypto API too
via the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/powerpc/crypto/crct10dif-vpmsum_glue.c
to arch/powerpc/lib/crc-t10dif-glue.c, view this commit with
'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/powerpc/Kconfig                          |  1 +
 arch/powerpc/configs/powernv_defconfig        |  1 -
 arch/powerpc/configs/ppc64_defconfig          |  1 -
 arch/powerpc/crypto/Kconfig                   | 15 +---
 arch/powerpc/crypto/Makefile                  |  2 -
 arch/powerpc/lib/Makefile                     |  3 +
 .../crc-t10dif-glue.c}                        | 69 +++++--------------
 .../{crypto => lib}/crct10dif-vpmsum_asm.S    |  2 +-
 8 files changed, 23 insertions(+), 71 deletions(-)
 rename arch/powerpc/{crypto/crct10dif-vpmsum_glue.c => lib/crc-t10dif-glue.c} (50%)
 rename arch/powerpc/{crypto => lib}/crct10dif-vpmsum_asm.S (99%)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b5050a09a27f..da0ac6697ac5 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -126,10 +126,11 @@ config PPC
 	select ARCH_DMA_DEFAULT_COHERENT	if !NOT_COHERENT_CACHE
 	select ARCH_ENABLE_MEMORY_HOTPLUG
 	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	select ARCH_HAS_COPY_MC			if PPC64
 	select ARCH_HAS_CRC32			if PPC64 && ALTIVEC
+	select ARCH_HAS_CRC_T10DIF		if PPC64 && ALTIVEC
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEBUG_WX		if STRICT_KERNEL_RWX
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
index 4a7ddea05b4d..6b6d7467fecf 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -318,11 +318,10 @@ CONFIG_FTR_FIXUP_SELFTEST=y
 CONFIG_MSI_BITMAP_SELFTEST=y
 CONFIG_XMON=y
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_CRCT10DIF_VPMSUM=m
 CONFIG_CRYPTO_MD5_PPC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA1_PPC=m
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_WP512=m
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 58e5f4488da4..15101f5c3238 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -387,11 +387,10 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_LZO=m
-CONFIG_CRYPTO_CRCT10DIF_VPMSUM=m
 CONFIG_CRYPTO_VPMSUM_TESTER=m
 CONFIG_CRYPTO_MD5_PPC=m
 CONFIG_CRYPTO_SHA1_PPC=m
 CONFIG_CRYPTO_AES_GCM_P10=m
 CONFIG_CRYPTO_DEV_NX=y
diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig
index 2d89e35b3cdd..45376f1a43bd 100644
--- a/arch/powerpc/crypto/Kconfig
+++ b/arch/powerpc/crypto/Kconfig
@@ -11,25 +11,14 @@ config CRYPTO_CURVE25519_PPC64
 	  Curve25519 algorithm
 
 	  Architecture: PowerPC64
 	  - Little-endian
 
-config CRYPTO_CRCT10DIF_VPMSUM
-	tristate "CRC32T10DIF"
-	depends on PPC64 && ALTIVEC && CRC_T10DIF
-	select CRYPTO_HASH
-	help
-	  CRC16 CRC algorithm used for the T10 (SCSI) Data Integrity Field (DIF)
-
-	  Architecture: powerpc64 using
-	  - AltiVec extensions
-
-	  Enable on POWER8 and newer processors for improved performance.
-
 config CRYPTO_VPMSUM_TESTER
 	tristate "CRC32c and CRC32T10DIF hardware acceleration tester"
-	depends on CRYPTO_CRCT10DIF_VPMSUM && CRYPTO_CRC32C && CRC32_ARCH
+	depends on CRYPTO_CRC32C && CRC32_ARCH
+	depends on CRYPTO_CRCT10DIF && CRC_T10DIF_ARCH
 	help
 	  Stress test for CRC32c and CRCT10DIF algorithms implemented with
 	  powerpc64 AltiVec extensions (POWER8 vpmsum instructions).
 	  Unless you are testing these algorithms, you don't need this.
 
diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile
index 54486192273c..d2238ac7e52c 100644
--- a/arch/powerpc/crypto/Makefile
+++ b/arch/powerpc/crypto/Makefile
@@ -8,11 +8,10 @@
 obj-$(CONFIG_CRYPTO_AES_PPC_SPE) += aes-ppc-spe.o
 obj-$(CONFIG_CRYPTO_MD5_PPC) += md5-ppc.o
 obj-$(CONFIG_CRYPTO_SHA1_PPC) += sha1-powerpc.o
 obj-$(CONFIG_CRYPTO_SHA1_PPC_SPE) += sha1-ppc-spe.o
 obj-$(CONFIG_CRYPTO_SHA256_PPC_SPE) += sha256-ppc-spe.o
-obj-$(CONFIG_CRYPTO_CRCT10DIF_VPMSUM) += crct10dif-vpmsum.o
 obj-$(CONFIG_CRYPTO_VPMSUM_TESTER) += crc-vpmsum_test.o
 obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o
 obj-$(CONFIG_CRYPTO_CHACHA20_P10) += chacha-p10-crypto.o
 obj-$(CONFIG_CRYPTO_POLY1305_P10) += poly1305-p10-crypto.o
 obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o
@@ -21,11 +20,10 @@ obj-$(CONFIG_CRYPTO_CURVE25519_PPC64) += curve25519-ppc64le.o
 aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o
 md5-ppc-y := md5-asm.o md5-glue.o
 sha1-powerpc-y := sha1-powerpc-asm.o sha1.o
 sha1-ppc-spe-y := sha1-spe-asm.o sha1-spe-glue.o
 sha256-ppc-spe-y := sha256-spe-asm.o sha256-spe-glue.o
-crct10dif-vpmsum-y := crct10dif-vpmsum_asm.o crct10dif-vpmsum_glue.o
 aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-ppc.o
 chacha-p10-crypto-y := chacha-p10-glue.o chacha-p10le-8x.o
 poly1305-p10-crypto-y := poly1305-p10-glue.o poly1305-p10le_64.o
 vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o
 curve25519-ppc64le-y := curve25519-ppc64le-core.o curve25519-ppc64le_asm.o
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index da9381a1c95b..dd8a4b52a0cc 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -79,6 +79,9 @@ CFLAGS_xor_vmx.o += -mhard-float -maltivec $(call cc-option,-mabi=altivec)
 CFLAGS_xor_vmx.o += -isystem $(shell $(CC) -print-file-name=include)
 
 obj-$(CONFIG_CRC32_ARCH) += crc32-powerpc.o
 crc32-powerpc-y := crc32-glue.o crc32c-vpmsum_asm.o
 
+obj-$(CONFIG_CRC_T10DIF_ARCH) += crc-t10dif-powerpc.o
+crc-t10dif-powerpc-y := crc-t10dif-glue.o crct10dif-vpmsum_asm.o
+
 obj-$(CONFIG_PPC64) += $(obj64-y)
diff --git a/arch/powerpc/crypto/crct10dif-vpmsum_glue.c b/arch/powerpc/lib/crc-t10dif-glue.c
similarity index 50%
rename from arch/powerpc/crypto/crct10dif-vpmsum_glue.c
rename to arch/powerpc/lib/crc-t10dif-glue.c
index 1dc8b6915178..730850dbc51d 100644
--- a/arch/powerpc/crypto/crct10dif-vpmsum_glue.c
+++ b/arch/powerpc/lib/crc-t10dif-glue.c
@@ -5,11 +5,10 @@
  * Copyright 2017, Daniel Axtens, IBM Corporation.
  * [based on crc32c-vpmsum_glue.c]
  */
 
 #include <linux/crc-t10dif.h>
-#include <crypto/internal/hash.h>
 #include <crypto/internal/simd.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
@@ -20,19 +19,22 @@
 #define VMX_ALIGN		16
 #define VMX_ALIGN_MASK		(VMX_ALIGN-1)
 
 #define VECTOR_BREAKPOINT	64
 
+static DEFINE_STATIC_KEY_FALSE(have_vec_crypto);
+
 u32 __crct10dif_vpmsum(u32 crc, unsigned char const *p, size_t len);
 
-static u16 crct10dif_vpmsum(u16 crci, unsigned char const *p, size_t len)
+u16 crc_t10dif_arch(u16 crci, const u8 *p, size_t len)
 {
 	unsigned int prealign;
 	unsigned int tail;
 	u32 crc = crci;
 
-	if (len < (VECTOR_BREAKPOINT + VMX_ALIGN) || !crypto_simd_usable())
+	if (len < (VECTOR_BREAKPOINT + VMX_ALIGN) ||
+	    !static_branch_likely(&have_vec_crypto) || !crypto_simd_usable())
 		return crc_t10dif_generic(crc, p, len);
 
 	if ((unsigned long)p & VMX_ALIGN_MASK) {
 		prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK);
 		crc = crc_t10dif_generic(crc, p, prealign);
@@ -58,69 +60,30 @@ static u16 crct10dif_vpmsum(u16 crci, unsigned char const *p, size_t len)
 		crc = crc_t10dif_generic(crc, p, tail);
 	}
 
 	return crc & 0xffff;
 }
+EXPORT_SYMBOL(crc_t10dif_arch);
 
-static int crct10dif_vpmsum_init(struct shash_desc *desc)
-{
-	u16 *crc = shash_desc_ctx(desc);
-
-	*crc = 0;
-	return 0;
-}
-
-static int crct10dif_vpmsum_update(struct shash_desc *desc, const u8 *data,
-			    unsigned int length)
-{
-	u16 *crc = shash_desc_ctx(desc);
-
-	*crc = crct10dif_vpmsum(*crc, data, length);
-
-	return 0;
-}
-
-
-static int crct10dif_vpmsum_final(struct shash_desc *desc, u8 *out)
+static int __init crc_t10dif_powerpc_init(void)
 {
-	u16 *crcp = shash_desc_ctx(desc);
-
-	*(u16 *)out = *crcp;
+	if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
+	    (cur_cpu_spec->cpu_user_features2 & PPC_FEATURE2_VEC_CRYPTO))
+		static_branch_enable(&have_vec_crypto);
 	return 0;
 }
+arch_initcall(crc_t10dif_powerpc_init);
 
-static struct shash_alg alg = {
-	.init		= crct10dif_vpmsum_init,
-	.update		= crct10dif_vpmsum_update,
-	.final		= crct10dif_vpmsum_final,
-	.descsize	= CRC_T10DIF_DIGEST_SIZE,
-	.digestsize	= CRC_T10DIF_DIGEST_SIZE,
-	.base		= {
-		.cra_name		= "crct10dif",
-		.cra_driver_name	= "crct10dif-vpmsum",
-		.cra_priority		= 200,
-		.cra_blocksize		= CRC_T10DIF_BLOCK_SIZE,
-		.cra_module		= THIS_MODULE,
-	}
-};
-
-static int __init crct10dif_vpmsum_mod_init(void)
+static void __exit crc_t10dif_powerpc_exit(void)
 {
-	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
-		return -ENODEV;
-
-	return crypto_register_shash(&alg);
 }
+module_exit(crc_t10dif_powerpc_exit);
 
-static void __exit crct10dif_vpmsum_mod_fini(void)
+bool crc_t10dif_is_optimized(void)
 {
-	crypto_unregister_shash(&alg);
+	return static_key_enabled(&have_vec_crypto);
 }
-
-module_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, crct10dif_vpmsum_mod_init);
-module_exit(crct10dif_vpmsum_mod_fini);
+EXPORT_SYMBOL(crc_t10dif_is_optimized);
 
 MODULE_AUTHOR("Daniel Axtens <dja at axtens.net>");
 MODULE_DESCRIPTION("CRCT10DIF using vector polynomial multiply-sum instructions");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS_CRYPTO("crct10dif");
-MODULE_ALIAS_CRYPTO("crct10dif-vpmsum");
diff --git a/arch/powerpc/crypto/crct10dif-vpmsum_asm.S b/arch/powerpc/lib/crct10dif-vpmsum_asm.S
similarity index 99%
rename from arch/powerpc/crypto/crct10dif-vpmsum_asm.S
rename to arch/powerpc/lib/crct10dif-vpmsum_asm.S
index 0a52261bf859..f0b93a0fe168 100644
--- a/arch/powerpc/crypto/crct10dif-vpmsum_asm.S
+++ b/arch/powerpc/lib/crct10dif-vpmsum_asm.S
@@ -840,6 +840,6 @@
 	.octa 0x000000000000000000000001f65a57f8	/* x^64 div p(x) */
 	/* Barrett constant n */
 	.octa 0x0000000000000000000000018bb70000
 
 #define CRC_FUNCTION_NAME __crct10dif_vpmsum
-#include "../lib/crc32-vpmsum_core.S"
+#include "crc32-vpmsum_core.S"
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:53 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:53 -0800
Subject: [PATCH v2 09/12] lib/crc16_kunit: delete obsolete crc16_kunit.c
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-10-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

This new test showed up in v6.13-rc1.  Delete it since it is being
superseded by crc_kunit.c, which is more comprehensive (tests multiple
CRC variants without duplicating code, includes a benchmark, etc.).

Cc: Vinicius Peixoto <vpeixoto at lkcamp.dev>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 lib/Kconfig.debug |   9 ---
 lib/Makefile      |   1 -
 lib/crc16_kunit.c | 155 ----------------------------------------------
 3 files changed, 165 deletions(-)
 delete mode 100644 lib/crc16_kunit.c

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index d9b89dd3f6a0..688dace36f36 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2876,19 +2876,10 @@ config USERCOPY_KUNIT_TEST
 	help
 	  This builds the "usercopy_kunit" module that runs sanity checks
 	  on the copy_to/from_user infrastructure, making sure basic
 	  user/kernel boundary testing is working.
 
-config CRC16_KUNIT_TEST
-	tristate "KUnit tests for CRC16"
-	depends on KUNIT
-	default KUNIT_ALL_TESTS
-	select CRC16
-	help
-	  Enable this option to run unit tests for the kernel's CRC16
-	  implementation (<linux/crc16.h>).
-
 config TEST_UDELAY
 	tristate "udelay test driver"
 	help
 	  This builds the "udelay_test" module that helps to make sure
 	  that udelay() is working properly.
diff --git a/lib/Makefile b/lib/Makefile
index ccd803d03e58..34f4d61e3cf7 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -392,11 +392,10 @@ CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-truncation)
 CFLAGS_fortify_kunit.o += $(DISABLE_STRUCTLEAK_PLUGIN)
 obj-$(CONFIG_FORTIFY_KUNIT_TEST) += fortify_kunit.o
 obj-$(CONFIG_CRC_KUNIT_TEST) += crc_kunit.o
 obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o
 obj-$(CONFIG_USERCOPY_KUNIT_TEST) += usercopy_kunit.o
-obj-$(CONFIG_CRC16_KUNIT_TEST) += crc16_kunit.o
 
 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
 
 obj-$(CONFIG_FIRMWARE_TABLE) += fw_table.o
 
diff --git a/lib/crc16_kunit.c b/lib/crc16_kunit.c
deleted file mode 100644
index 0918c98a96d2..000000000000
--- a/lib/crc16_kunit.c
+++ /dev/null
@@ -1,155 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * KUnits tests for CRC16.
- *
- * Copyright (C) 2024, LKCAMP
- * Author: Vinicius Peixoto <vpeixoto at lkcamp.dev>
- * Author: Fabricio Gasperin <fgasperin at lkcamp.dev>
- * Author: Enzo Bertoloti <ebertoloti at lkcamp.dev>
- */
-#include <kunit/test.h>
-#include <linux/crc16.h>
-#include <linux/prandom.h>
-
-#define CRC16_KUNIT_DATA_SIZE 4096
-#define CRC16_KUNIT_TEST_SIZE 100
-#define CRC16_KUNIT_SEED 0x12345678
-
-/**
- * struct crc16_test - CRC16 test data
- * @crc: initial input value to CRC16
- * @start: Start index within the data buffer
- * @length: Length of the data
- */
-static struct crc16_test {
-	u16 crc;
-	u16 start;
-	u16 length;
-} tests[CRC16_KUNIT_TEST_SIZE];
-
-u8 data[CRC16_KUNIT_DATA_SIZE];
-
-
-/* Naive implementation of CRC16 for validation purposes */
-static inline u16 _crc16_naive_byte(u16 crc, u8 data)
-{
-	u8 i = 0;
-
-	crc ^= (u16) data;
-	for (i = 0; i < 8; i++) {
-		if (crc & 0x01)
-			crc = (crc >> 1) ^ 0xa001;
-		else
-			crc = crc >> 1;
-	}
-
-	return crc;
-}
-
-
-static inline u16 _crc16_naive(u16 crc, u8 *buffer, size_t len)
-{
-	while (len--)
-		crc = _crc16_naive_byte(crc, *buffer++);
-	return crc;
-}
-
-
-/* Small helper for generating pseudorandom 16-bit data */
-static inline u16 _rand16(void)
-{
-	static u32 rand = CRC16_KUNIT_SEED;
-
-	rand = next_pseudo_random32(rand);
-	return rand & 0xFFFF;
-}
-
-
-static int crc16_init_test_data(struct kunit_suite *suite)
-{
-	size_t i;
-
-	/* Fill the data buffer with random bytes */
-	for (i = 0; i < CRC16_KUNIT_DATA_SIZE; i++)
-		data[i] = _rand16() & 0xFF;
-
-	/* Generate random test data while ensuring the random
-	 * start + length values won't overflow the 4096-byte
-	 * buffer (0x7FF * 2 = 0xFFE < 0x1000)
-	 */
-	for (size_t i = 0; i < CRC16_KUNIT_TEST_SIZE; i++) {
-		tests[i].crc = _rand16();
-		tests[i].start = _rand16() & 0x7FF;
-		tests[i].length = _rand16() & 0x7FF;
-	}
-
-	return 0;
-}
-
-static void crc16_test_empty(struct kunit *test)
-{
-	u16 crc;
-
-	/* The result for empty data should be the same as the
-	 * initial crc
-	 */
-	crc = crc16(0x00, data, 0);
-	KUNIT_EXPECT_EQ(test, crc, 0);
-	crc = crc16(0xFF, data, 0);
-	KUNIT_EXPECT_EQ(test, crc, 0xFF);
-}
-
-static void crc16_test_correctness(struct kunit *test)
-{
-	size_t i;
-	u16 crc, crc_naive;
-
-	for (i = 0; i < CRC16_KUNIT_TEST_SIZE; i++) {
-		/* Compare results with the naive crc16 implementation */
-		crc = crc16(tests[i].crc, data + tests[i].start,
-			    tests[i].length);
-		crc_naive = _crc16_naive(tests[i].crc, data + tests[i].start,
-					 tests[i].length);
-		KUNIT_EXPECT_EQ(test, crc, crc_naive);
-	}
-}
-
-
-static void crc16_test_combine(struct kunit *test)
-{
-	size_t i, j;
-	u16 crc, crc_naive;
-
-	/* Make sure that combining two consecutive crc16 calculations
-	 * yields the same result as calculating the crc16 for the whole thing
-	 */
-	for (i = 0; i < CRC16_KUNIT_TEST_SIZE; i++) {
-		crc_naive = crc16(tests[i].crc, data + tests[i].start, tests[i].length);
-		for (j = 0; j < tests[i].length; j++) {
-			crc = crc16(tests[i].crc, data + tests[i].start, j);
-			crc = crc16(crc, data + tests[i].start + j, tests[i].length - j);
-			KUNIT_EXPECT_EQ(test, crc, crc_naive);
-		}
-	}
-}
-
-
-static struct kunit_case crc16_test_cases[] = {
-	KUNIT_CASE(crc16_test_empty),
-	KUNIT_CASE(crc16_test_combine),
-	KUNIT_CASE(crc16_test_correctness),
-	{},
-};
-
-static struct kunit_suite crc16_test_suite = {
-	.name = "crc16",
-	.test_cases = crc16_test_cases,
-	.suite_init = crc16_init_test_data,
-};
-kunit_test_suite(crc16_test_suite);
-
-MODULE_AUTHOR("Fabricio Gasperin <fgasperin at lkcamp.dev>");
-MODULE_AUTHOR("Vinicius Peixoto <vpeixoto at lkcamp.dev>");
-MODULE_AUTHOR("Enzo Bertoloti <ebertoloti at lkcamp.dev>");
-MODULE_DESCRIPTION("Unit tests for crc16");
-MODULE_LICENSE("GPL");
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:55 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:55 -0800
Subject: [PATCH v2 11/12] powerpc/crc: delete obsolete crc-vpmsum_test.c
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-12-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Delete crc-vpmsum_test.c, since its functionality is now covered by the
new crc_kunit.c as well as the crypto subsystem's fuzz tests.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Cc: Vinicius Peixoto <vpeixoto at lkcamp.dev>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/powerpc/configs/ppc64_defconfig  |   1 -
 arch/powerpc/crypto/Kconfig           |   9 --
 arch/powerpc/crypto/Makefile          |   1 -
 arch/powerpc/crypto/crc-vpmsum_test.c | 133 --------------------------
 4 files changed, 144 deletions(-)
 delete mode 100644 arch/powerpc/crypto/crc-vpmsum_test.c

diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 15101f5c3238..465eb96c755e 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -387,11 +387,10 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_LZO=m
-CONFIG_CRYPTO_VPMSUM_TESTER=m
 CONFIG_CRYPTO_MD5_PPC=m
 CONFIG_CRYPTO_SHA1_PPC=m
 CONFIG_CRYPTO_AES_GCM_P10=m
 CONFIG_CRYPTO_DEV_NX=y
 CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig
index 45376f1a43bd..5b315e9756b3 100644
--- a/arch/powerpc/crypto/Kconfig
+++ b/arch/powerpc/crypto/Kconfig
@@ -11,19 +11,10 @@ config CRYPTO_CURVE25519_PPC64
 	  Curve25519 algorithm
 
 	  Architecture: PowerPC64
 	  - Little-endian
 
-config CRYPTO_VPMSUM_TESTER
-	tristate "CRC32c and CRC32T10DIF hardware acceleration tester"
-	depends on CRYPTO_CRC32C && CRC32_ARCH
-	depends on CRYPTO_CRCT10DIF && CRC_T10DIF_ARCH
-	help
-	  Stress test for CRC32c and CRCT10DIF algorithms implemented with
-	  powerpc64 AltiVec extensions (POWER8 vpmsum instructions).
-	  Unless you are testing these algorithms, you don't need this.
-
 config CRYPTO_MD5_PPC
 	tristate "Digests: MD5"
 	depends on PPC
 	select CRYPTO_HASH
 	help
diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile
index d2238ac7e52c..9b38f4a7bc15 100644
--- a/arch/powerpc/crypto/Makefile
+++ b/arch/powerpc/crypto/Makefile
@@ -8,11 +8,10 @@
 obj-$(CONFIG_CRYPTO_AES_PPC_SPE) += aes-ppc-spe.o
 obj-$(CONFIG_CRYPTO_MD5_PPC) += md5-ppc.o
 obj-$(CONFIG_CRYPTO_SHA1_PPC) += sha1-powerpc.o
 obj-$(CONFIG_CRYPTO_SHA1_PPC_SPE) += sha1-ppc-spe.o
 obj-$(CONFIG_CRYPTO_SHA256_PPC_SPE) += sha256-ppc-spe.o
-obj-$(CONFIG_CRYPTO_VPMSUM_TESTER) += crc-vpmsum_test.o
 obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o
 obj-$(CONFIG_CRYPTO_CHACHA20_P10) += chacha-p10-crypto.o
 obj-$(CONFIG_CRYPTO_POLY1305_P10) += poly1305-p10-crypto.o
 obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o
 obj-$(CONFIG_CRYPTO_CURVE25519_PPC64) += curve25519-ppc64le.o
diff --git a/arch/powerpc/crypto/crc-vpmsum_test.c b/arch/powerpc/crypto/crc-vpmsum_test.c
deleted file mode 100644
index c61a874a3a5c..000000000000
--- a/arch/powerpc/crypto/crc-vpmsum_test.c
+++ /dev/null
@@ -1,133 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * CRC vpmsum tester
- * Copyright 2017 Daniel Axtens, IBM Corporation.
- */
-
-#include <linux/crc-t10dif.h>
-#include <linux/crc32.h>
-#include <crypto/internal/hash.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/random.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/cpufeature.h>
-#include <asm/switch_to.h>
-
-static unsigned long iterations = 10000;
-
-#define MAX_CRC_LENGTH 65535
-
-
-static int __init crc_test_init(void)
-{
-	u16 crc16 = 0, verify16 = 0;
-	__le32 verify32le = 0;
-	unsigned char *data;
-	u32 verify32 = 0;
-	unsigned long i;
-	__le32 crc32;
-	int ret;
-
-	struct crypto_shash *crct10dif_tfm;
-	struct crypto_shash *crc32c_tfm;
-
-	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
-		return -ENODEV;
-
-	data = kmalloc(MAX_CRC_LENGTH, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	crct10dif_tfm = crypto_alloc_shash("crct10dif", 0, 0);
-
-	if (IS_ERR(crct10dif_tfm)) {
-		pr_err("Error allocating crc-t10dif\n");
-		goto free_buf;
-	}
-
-	crc32c_tfm = crypto_alloc_shash("crc32c", 0, 0);
-
-	if (IS_ERR(crc32c_tfm)) {
-		pr_err("Error allocating crc32c\n");
-		goto free_16;
-	}
-
-	do {
-		SHASH_DESC_ON_STACK(crct10dif_shash, crct10dif_tfm);
-		SHASH_DESC_ON_STACK(crc32c_shash, crc32c_tfm);
-
-		crct10dif_shash->tfm = crct10dif_tfm;
-		ret = crypto_shash_init(crct10dif_shash);
-
-		if (ret) {
-			pr_err("Error initing crc-t10dif\n");
-			goto free_32;
-		}
-
-
-		crc32c_shash->tfm = crc32c_tfm;
-		ret = crypto_shash_init(crc32c_shash);
-
-		if (ret) {
-			pr_err("Error initing crc32c\n");
-			goto free_32;
-		}
-
-		pr_info("crc-vpmsum_test begins, %lu iterations\n", iterations);
-		for (i=0; i<iterations; i++) {
-			size_t offset = get_random_u32_below(16);
-			size_t len = get_random_u32_below(MAX_CRC_LENGTH);
-
-			if (len <= offset)
-				continue;
-			get_random_bytes(data, len);
-			len -= offset;
-
-			crypto_shash_update(crct10dif_shash, data+offset, len);
-			crypto_shash_final(crct10dif_shash, (u8 *)(&crc16));
-			verify16 = crc_t10dif_generic(verify16, data+offset, len);
-
-
-			if (crc16 != verify16) {
-				pr_err("FAILURE in CRC16: got 0x%04x expected 0x%04x (len %lu)\n",
-				       crc16, verify16, len);
-				break;
-			}
-
-			crypto_shash_update(crc32c_shash, data+offset, len);
-			crypto_shash_final(crc32c_shash, (u8 *)(&crc32));
-			verify32 = le32_to_cpu(verify32le);
-		        verify32le = ~cpu_to_le32(__crc32c_le(~verify32, data+offset, len));
-			if (crc32 != verify32le) {
-				pr_err("FAILURE in CRC32: got 0x%08x expected 0x%08x (len %lu)\n",
-				       crc32, verify32, len);
-				break;
-			}
-		cond_resched();
-		}
-		pr_info("crc-vpmsum_test done, completed %lu iterations\n", i);
-	} while (0);
-
-free_32:
-	crypto_free_shash(crc32c_tfm);
-
-free_16:
-	crypto_free_shash(crct10dif_tfm);
-
-free_buf:
-	kfree(data);
-
-	return 0;
-}
-
-static void __exit crc_test_exit(void) {}
-
-module_init(crc_test_init);
-module_exit(crc_test_exit);
-module_param(iterations, long, 0400);
-
-MODULE_AUTHOR("Daniel Axtens <dja at axtens.net>");
-MODULE_DESCRIPTION("Vector polynomial multiply-sum CRC tester");
-MODULE_LICENSE("GPL");
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:56 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:56 -0800
Subject: [PATCH v2 12/12] MAINTAINERS: add entry for CRC library
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-13-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

I am volunteering to maintain the kernel's CRC library code.

Ard has volunteered to be a reviewer.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 MAINTAINERS | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..b7eb0c0a9c1c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6054,10 +6054,21 @@ CRAMFS FILESYSTEM
 M:	Nicolas Pitre <nico at fluxnic.net>
 S:	Maintained
 F:	Documentation/filesystems/cramfs.rst
 F:	fs/cramfs/
 
+CRC LIBRARY
+M:	Eric Biggers <ebiggers at kernel.org>
+R:	Ard Biesheuvel <ardb at kernel.org>
+L:	linux-crypto at vger.kernel.org
+S:	Maintained
+T:	git https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git crc-next
+F:	Documentation/staging/crc*
+F:	arch/*/lib/crc*
+F:	include/linux/crc*
+F:	lib/crc*
+
 CREATIVE SB0540
 M:	Bastien Nocera <hadess at hadess.net>
 L:	linux-input at vger.kernel.org
 S:	Maintained
 F:	drivers/hid/hid-creative-sb0540.c
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:54 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:54 -0800
Subject: [PATCH v2 10/12] lib/crc32test: delete obsolete crc32test.c
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-11-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Delete crc32test.c, since it has been superseded by crc_kunit.c.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Cc: Vinicius Peixoto <vpeixoto at lkcamp.dev>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/m68k/configs/amiga_defconfig    |   1 -
 arch/m68k/configs/apollo_defconfig   |   1 -
 arch/m68k/configs/atari_defconfig    |   1 -
 arch/m68k/configs/bvme6000_defconfig |   1 -
 arch/m68k/configs/hp300_defconfig    |   1 -
 arch/m68k/configs/mac_defconfig      |   1 -
 arch/m68k/configs/multi_defconfig    |   1 -
 arch/m68k/configs/mvme147_defconfig  |   1 -
 arch/m68k/configs/mvme16x_defconfig  |   1 -
 arch/m68k/configs/q40_defconfig      |   1 -
 arch/m68k/configs/sun3_defconfig     |   1 -
 arch/m68k/configs/sun3x_defconfig    |   1 -
 arch/s390/configs/debug_defconfig    |   1 -
 lib/Kconfig                          |   9 -
 lib/Makefile                         |   1 -
 lib/crc32test.c                      | 852 ---------------------------
 16 files changed, 875 deletions(-)
 delete mode 100644 lib/crc32test.c

diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index c705247e7b5b..e5acb7b52550 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -604,11 +604,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index 6d62b9187a58..89fc22636bb5 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -561,11 +561,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index c3c644df852d..9dfba6488b72 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -581,11 +581,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index 20261f819691..5250447e249b 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -553,11 +553,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index ce4fe93a0f70..0f99307f9caf 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -563,11 +563,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 040ae75f47c3..36e5f493654a 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -580,11 +580,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index 20d877cb4e30..382b0e2e20dc 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -667,11 +667,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 5e1c8d0d3da5..d91ec0cc23c8 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -553,11 +553,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index 5d1409e6a137..4cde4ee78a85 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -554,11 +554,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index e4c30e2b9bbb..d49c01e591e1 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -570,11 +570,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index 980843a9ea1e..468f2545b93e 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -551,11 +551,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index 38681cc6b598..ea38b1f2453d 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -551,11 +551,10 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_PRIME_NUMBERS=m
-CONFIG_CRC32_SELFTEST=m
 CONFIG_XZ_DEC_TEST=m
 CONFIG_GLOB_SELFTEST=m
 # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_TEST_LOCKUP=m
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index f2a149b4fafd..931c0a974ed8 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -815,11 +815,10 @@ CONFIG_CRYPTO_PAES_S390=m
 CONFIG_CRYPTO_DEV_VIRTIO=m
 CONFIG_SYSTEM_BLACKLIST_KEYRING=y
 CONFIG_CORDIC=m
 CONFIG_CRYPTO_LIB_CURVE25519=m
 CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
-CONFIG_CRC32_SELFTEST=y
 CONFIG_CRC4=m
 CONFIG_CRC7=m
 CONFIG_CRC8=m
 CONFIG_RANDOM32_SELFTEST=y
 CONFIG_XZ_DEC_MICROLZMA=y
diff --git a/lib/Kconfig b/lib/Kconfig
index e52a38d8d783..a78d22c6507f 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -221,19 +221,10 @@ config CRC32
 	  functions require M here.
 
 config ARCH_HAS_CRC32
 	bool
 
-config CRC32_SELFTEST
-	tristate "CRC32 perform self test on init"
-	depends on CRC32
-	help
-	  This option enables the CRC32 library functions to perform a
-	  self test on initialization. The self test computes crc32_le
-	  and crc32_be over byte strings with random alignment and length
-	  and computes the total elapsed time and number of bytes processed.
-
 choice
 	prompt "CRC32 implementation"
 	depends on CRC32
 	default CRC32_IMPL_ARCH_PLUS_SLICEBY8 if ARCH_HAS_CRC32
 	default CRC32_IMPL_SLICEBY8 if !ARCH_HAS_CRC32
diff --git a/lib/Makefile b/lib/Makefile
index 34f4d61e3cf7..d5cfc7afbbb8 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -162,11 +162,10 @@ obj-$(CONFIG_CRC_CCITT)	+= crc-ccitt.o
 obj-$(CONFIG_CRC16)	+= crc16.o
 obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o
 obj-$(CONFIG_CRC_ITU_T)	+= crc-itu-t.o
 obj-$(CONFIG_CRC32)	+= crc32.o
 obj-$(CONFIG_CRC64)     += crc64.o
-obj-$(CONFIG_CRC32_SELFTEST)	+= crc32test.o
 obj-$(CONFIG_CRC4)	+= crc4.o
 obj-$(CONFIG_CRC7)	+= crc7.o
 obj-$(CONFIG_CRC8)	+= crc8.o
 obj-$(CONFIG_CRC64_ROCKSOFT) += crc64-rocksoft.o
 obj-$(CONFIG_XXHASH)	+= xxhash.o
diff --git a/lib/crc32test.c b/lib/crc32test.c
deleted file mode 100644
index 9b4af79412c4..000000000000
--- a/lib/crc32test.c
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
- * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin
- * cleaned up code to current version of sparse and added the slicing-by-8
- * algorithm to the closely similar existing slicing-by-4 algorithm.
- *
- * Oct 15, 2000 Matt Domsch <Matt_Domsch at dell.com>
- * Nicer crc32 functions/docs submitted by linux at horizon.com.  Thanks!
- * Code was from the public domain, copyright abandoned.  Code was
- * subsequently included in the kernel, thus was re-licensed under the
- * GNU GPL v2.
- *
- * Oct 12, 2000 Matt Domsch <Matt_Domsch at dell.com>
- * Same crc32 function was used in 5 other places in the kernel.
- * I made one version, and deleted the others.
- * There are various incantations of crc32().  Some use a seed of 0 or ~0.
- * Some xor at the end with ~0.  The generic crc32() function takes
- * seed as an argument, and doesn't xor at the end.  Then individual
- * users can do whatever they need.
- *   drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
- *   fs/jffs2 uses seed 0, doesn't xor with ~0.
- *   fs/partitions/efi.c uses seed ~0, xor's with ~0.
- *
- * This source code is licensed under the GNU General Public License,
- * Version 2.  See the file COPYING for more details.
- */
-
-#include <linux/crc32.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-
-#include "crc32defs.h"
-
-/* 4096 random bytes */
-static u8 const __aligned(8) test_buf[] __initconst =
-{
-	0x5b, 0x85, 0x21, 0xcb, 0x09, 0x68, 0x7d, 0x30,
-	0xc7, 0x69, 0xd7, 0x30, 0x92, 0xde, 0x59, 0xe4,
-	0xc9, 0x6e, 0x8b, 0xdb, 0x98, 0x6b, 0xaa, 0x60,
-	0xa8, 0xb5, 0xbc, 0x6c, 0xa9, 0xb1, 0x5b, 0x2c,
-	0xea, 0xb4, 0x92, 0x6a, 0x3f, 0x79, 0x91, 0xe4,
-	0xe9, 0x70, 0x51, 0x8c, 0x7f, 0x95, 0x6f, 0x1a,
-	0x56, 0xa1, 0x5c, 0x27, 0x03, 0x67, 0x9f, 0x3a,
-	0xe2, 0x31, 0x11, 0x29, 0x6b, 0x98, 0xfc, 0xc4,
-	0x53, 0x24, 0xc5, 0x8b, 0xce, 0x47, 0xb2, 0xb9,
-	0x32, 0xcb, 0xc1, 0xd0, 0x03, 0x57, 0x4e, 0xd4,
-	0xe9, 0x3c, 0xa1, 0x63, 0xcf, 0x12, 0x0e, 0xca,
-	0xe1, 0x13, 0xd1, 0x93, 0xa6, 0x88, 0x5c, 0x61,
-	0x5b, 0xbb, 0xf0, 0x19, 0x46, 0xb4, 0xcf, 0x9e,
-	0xb6, 0x6b, 0x4c, 0x3a, 0xcf, 0x60, 0xf9, 0x7a,
-	0x8d, 0x07, 0x63, 0xdb, 0x40, 0xe9, 0x0b, 0x6f,
-	0xad, 0x97, 0xf1, 0xed, 0xd0, 0x1e, 0x26, 0xfd,
-	0xbf, 0xb7, 0xc8, 0x04, 0x94, 0xf8, 0x8b, 0x8c,
-	0xf1, 0xab, 0x7a, 0xd4, 0xdd, 0xf3, 0xe8, 0x88,
-	0xc3, 0xed, 0x17, 0x8a, 0x9b, 0x40, 0x0d, 0x53,
-	0x62, 0x12, 0x03, 0x5f, 0x1b, 0x35, 0x32, 0x1f,
-	0xb4, 0x7b, 0x93, 0x78, 0x0d, 0xdb, 0xce, 0xa4,
-	0xc0, 0x47, 0xd5, 0xbf, 0x68, 0xe8, 0x5d, 0x74,
-	0x8f, 0x8e, 0x75, 0x1c, 0xb2, 0x4f, 0x9a, 0x60,
-	0xd1, 0xbe, 0x10, 0xf4, 0x5c, 0xa1, 0x53, 0x09,
-	0xa5, 0xe0, 0x09, 0x54, 0x85, 0x5c, 0xdc, 0x07,
-	0xe7, 0x21, 0x69, 0x7b, 0x8a, 0xfd, 0x90, 0xf1,
-	0x22, 0xd0, 0xb4, 0x36, 0x28, 0xe6, 0xb8, 0x0f,
-	0x39, 0xde, 0xc8, 0xf3, 0x86, 0x60, 0x34, 0xd2,
-	0x5e, 0xdf, 0xfd, 0xcf, 0x0f, 0xa9, 0x65, 0xf0,
-	0xd5, 0x4d, 0x96, 0x40, 0xe3, 0xdf, 0x3f, 0x95,
-	0x5a, 0x39, 0x19, 0x93, 0xf4, 0x75, 0xce, 0x22,
-	0x00, 0x1c, 0x93, 0xe2, 0x03, 0x66, 0xf4, 0x93,
-	0x73, 0x86, 0x81, 0x8e, 0x29, 0x44, 0x48, 0x86,
-	0x61, 0x7c, 0x48, 0xa3, 0x43, 0xd2, 0x9c, 0x8d,
-	0xd4, 0x95, 0xdd, 0xe1, 0x22, 0x89, 0x3a, 0x40,
-	0x4c, 0x1b, 0x8a, 0x04, 0xa8, 0x09, 0x69, 0x8b,
-	0xea, 0xc6, 0x55, 0x8e, 0x57, 0xe6, 0x64, 0x35,
-	0xf0, 0xc7, 0x16, 0x9f, 0x5d, 0x5e, 0x86, 0x40,
-	0x46, 0xbb, 0xe5, 0x45, 0x88, 0xfe, 0xc9, 0x63,
-	0x15, 0xfb, 0xf5, 0xbd, 0x71, 0x61, 0xeb, 0x7b,
-	0x78, 0x70, 0x07, 0x31, 0x03, 0x9f, 0xb2, 0xc8,
-	0xa7, 0xab, 0x47, 0xfd, 0xdf, 0xa0, 0x78, 0x72,
-	0xa4, 0x2a, 0xe4, 0xb6, 0xba, 0xc0, 0x1e, 0x86,
-	0x71, 0xe6, 0x3d, 0x18, 0x37, 0x70, 0xe6, 0xff,
-	0xe0, 0xbc, 0x0b, 0x22, 0xa0, 0x1f, 0xd3, 0xed,
-	0xa2, 0x55, 0x39, 0xab, 0xa8, 0x13, 0x73, 0x7c,
-	0x3f, 0xb2, 0xd6, 0x19, 0xac, 0xff, 0x99, 0xed,
-	0xe8, 0xe6, 0xa6, 0x22, 0xe3, 0x9c, 0xf1, 0x30,
-	0xdc, 0x01, 0x0a, 0x56, 0xfa, 0xe4, 0xc9, 0x99,
-	0xdd, 0xa8, 0xd8, 0xda, 0x35, 0x51, 0x73, 0xb4,
-	0x40, 0x86, 0x85, 0xdb, 0x5c, 0xd5, 0x85, 0x80,
-	0x14, 0x9c, 0xfd, 0x98, 0xa9, 0x82, 0xc5, 0x37,
-	0xff, 0x32, 0x5d, 0xd0, 0x0b, 0xfa, 0xdc, 0x04,
-	0x5e, 0x09, 0xd2, 0xca, 0x17, 0x4b, 0x1a, 0x8e,
-	0x15, 0xe1, 0xcc, 0x4e, 0x52, 0x88, 0x35, 0xbd,
-	0x48, 0xfe, 0x15, 0xa0, 0x91, 0xfd, 0x7e, 0x6c,
-	0x0e, 0x5d, 0x79, 0x1b, 0x81, 0x79, 0xd2, 0x09,
-	0x34, 0x70, 0x3d, 0x81, 0xec, 0xf6, 0x24, 0xbb,
-	0xfb, 0xf1, 0x7b, 0xdf, 0x54, 0xea, 0x80, 0x9b,
-	0xc7, 0x99, 0x9e, 0xbd, 0x16, 0x78, 0x12, 0x53,
-	0x5e, 0x01, 0xa7, 0x4e, 0xbd, 0x67, 0xe1, 0x9b,
-	0x4c, 0x0e, 0x61, 0x45, 0x97, 0xd2, 0xf0, 0x0f,
-	0xfe, 0x15, 0x08, 0xb7, 0x11, 0x4c, 0xe7, 0xff,
-	0x81, 0x53, 0xff, 0x91, 0x25, 0x38, 0x7e, 0x40,
-	0x94, 0xe5, 0xe0, 0xad, 0xe6, 0xd9, 0x79, 0xb6,
-	0x92, 0xc9, 0xfc, 0xde, 0xc3, 0x1a, 0x23, 0xbb,
-	0xdd, 0xc8, 0x51, 0x0c, 0x3a, 0x72, 0xfa, 0x73,
-	0x6f, 0xb7, 0xee, 0x61, 0x39, 0x03, 0x01, 0x3f,
-	0x7f, 0x94, 0x2e, 0x2e, 0xba, 0x3a, 0xbb, 0xb4,
-	0xfa, 0x6a, 0x17, 0xfe, 0xea, 0xef, 0x5e, 0x66,
-	0x97, 0x3f, 0x32, 0x3d, 0xd7, 0x3e, 0xb1, 0xf1,
-	0x6c, 0x14, 0x4c, 0xfd, 0x37, 0xd3, 0x38, 0x80,
-	0xfb, 0xde, 0xa6, 0x24, 0x1e, 0xc8, 0xca, 0x7f,
-	0x3a, 0x93, 0xd8, 0x8b, 0x18, 0x13, 0xb2, 0xe5,
-	0xe4, 0x93, 0x05, 0x53, 0x4f, 0x84, 0x66, 0xa7,
-	0x58, 0x5c, 0x7b, 0x86, 0x52, 0x6d, 0x0d, 0xce,
-	0xa4, 0x30, 0x7d, 0xb6, 0x18, 0x9f, 0xeb, 0xff,
-	0x22, 0xbb, 0x72, 0x29, 0xb9, 0x44, 0x0b, 0x48,
-	0x1e, 0x84, 0x71, 0x81, 0xe3, 0x6d, 0x73, 0x26,
-	0x92, 0xb4, 0x4d, 0x2a, 0x29, 0xb8, 0x1f, 0x72,
-	0xed, 0xd0, 0xe1, 0x64, 0x77, 0xea, 0x8e, 0x88,
-	0x0f, 0xef, 0x3f, 0xb1, 0x3b, 0xad, 0xf9, 0xc9,
-	0x8b, 0xd0, 0xac, 0xc6, 0xcc, 0xa9, 0x40, 0xcc,
-	0x76, 0xf6, 0x3b, 0x53, 0xb5, 0x88, 0xcb, 0xc8,
-	0x37, 0xf1, 0xa2, 0xba, 0x23, 0x15, 0x99, 0x09,
-	0xcc, 0xe7, 0x7a, 0x3b, 0x37, 0xf7, 0x58, 0xc8,
-	0x46, 0x8c, 0x2b, 0x2f, 0x4e, 0x0e, 0xa6, 0x5c,
-	0xea, 0x85, 0x55, 0xba, 0x02, 0x0e, 0x0e, 0x48,
-	0xbc, 0xe1, 0xb1, 0x01, 0x35, 0x79, 0x13, 0x3d,
-	0x1b, 0xc0, 0x53, 0x68, 0x11, 0xe7, 0x95, 0x0f,
-	0x9d, 0x3f, 0x4c, 0x47, 0x7b, 0x4d, 0x1c, 0xae,
-	0x50, 0x9b, 0xcb, 0xdd, 0x05, 0x8d, 0x9a, 0x97,
-	0xfd, 0x8c, 0xef, 0x0c, 0x1d, 0x67, 0x73, 0xa8,
-	0x28, 0x36, 0xd5, 0xb6, 0x92, 0x33, 0x40, 0x75,
-	0x0b, 0x51, 0xc3, 0x64, 0xba, 0x1d, 0xc2, 0xcc,
-	0xee, 0x7d, 0x54, 0x0f, 0x27, 0x69, 0xa7, 0x27,
-	0x63, 0x30, 0x29, 0xd9, 0xc8, 0x84, 0xd8, 0xdf,
-	0x9f, 0x68, 0x8d, 0x04, 0xca, 0xa6, 0xc5, 0xc7,
-	0x7a, 0x5c, 0xc8, 0xd1, 0xcb, 0x4a, 0xec, 0xd0,
-	0xd8, 0x20, 0x69, 0xc5, 0x17, 0xcd, 0x78, 0xc8,
-	0x75, 0x23, 0x30, 0x69, 0xc9, 0xd4, 0xea, 0x5c,
-	0x4f, 0x6b, 0x86, 0x3f, 0x8b, 0xfe, 0xee, 0x44,
-	0xc9, 0x7c, 0xb7, 0xdd, 0x3e, 0xe5, 0xec, 0x54,
-	0x03, 0x3e, 0xaa, 0x82, 0xc6, 0xdf, 0xb2, 0x38,
-	0x0e, 0x5d, 0xb3, 0x88, 0xd9, 0xd3, 0x69, 0x5f,
-	0x8f, 0x70, 0x8a, 0x7e, 0x11, 0xd9, 0x1e, 0x7b,
-	0x38, 0xf1, 0x42, 0x1a, 0xc0, 0x35, 0xf5, 0xc7,
-	0x36, 0x85, 0xf5, 0xf7, 0xb8, 0x7e, 0xc7, 0xef,
-	0x18, 0xf1, 0x63, 0xd6, 0x7a, 0xc6, 0xc9, 0x0e,
-	0x4d, 0x69, 0x4f, 0x84, 0xef, 0x26, 0x41, 0x0c,
-	0xec, 0xc7, 0xe0, 0x7e, 0x3c, 0x67, 0x01, 0x4c,
-	0x62, 0x1a, 0x20, 0x6f, 0xee, 0x47, 0x4d, 0xc0,
-	0x99, 0x13, 0x8d, 0x91, 0x4a, 0x26, 0xd4, 0x37,
-	0x28, 0x90, 0x58, 0x75, 0x66, 0x2b, 0x0a, 0xdf,
-	0xda, 0xee, 0x92, 0x25, 0x90, 0x62, 0x39, 0x9e,
-	0x44, 0x98, 0xad, 0xc1, 0x88, 0xed, 0xe4, 0xb4,
-	0xaf, 0xf5, 0x8c, 0x9b, 0x48, 0x4d, 0x56, 0x60,
-	0x97, 0x0f, 0x61, 0x59, 0x9e, 0xa6, 0x27, 0xfe,
-	0xc1, 0x91, 0x15, 0x38, 0xb8, 0x0f, 0xae, 0x61,
-	0x7d, 0x26, 0x13, 0x5a, 0x73, 0xff, 0x1c, 0xa3,
-	0x61, 0x04, 0x58, 0x48, 0x55, 0x44, 0x11, 0xfe,
-	0x15, 0xca, 0xc3, 0xbd, 0xca, 0xc5, 0xb4, 0x40,
-	0x5d, 0x1b, 0x7f, 0x39, 0xb5, 0x9c, 0x35, 0xec,
-	0x61, 0x15, 0x32, 0x32, 0xb8, 0x4e, 0x40, 0x9f,
-	0x17, 0x1f, 0x0a, 0x4d, 0xa9, 0x91, 0xef, 0xb7,
-	0xb0, 0xeb, 0xc2, 0x83, 0x9a, 0x6c, 0xd2, 0x79,
-	0x43, 0x78, 0x5e, 0x2f, 0xe5, 0xdd, 0x1a, 0x3c,
-	0x45, 0xab, 0x29, 0x40, 0x3a, 0x37, 0x5b, 0x6f,
-	0xd7, 0xfc, 0x48, 0x64, 0x3c, 0x49, 0xfb, 0x21,
-	0xbe, 0xc3, 0xff, 0x07, 0xfb, 0x17, 0xe9, 0xc9,
-	0x0c, 0x4c, 0x5c, 0x15, 0x9e, 0x8e, 0x22, 0x30,
-	0x0a, 0xde, 0x48, 0x7f, 0xdb, 0x0d, 0xd1, 0x2b,
-	0x87, 0x38, 0x9e, 0xcc, 0x5a, 0x01, 0x16, 0xee,
-	0x75, 0x49, 0x0d, 0x30, 0x01, 0x34, 0x6a, 0xb6,
-	0x9a, 0x5a, 0x2a, 0xec, 0xbb, 0x48, 0xac, 0xd3,
-	0x77, 0x83, 0xd8, 0x08, 0x86, 0x4f, 0x48, 0x09,
-	0x29, 0x41, 0x79, 0xa1, 0x03, 0x12, 0xc4, 0xcd,
-	0x90, 0x55, 0x47, 0x66, 0x74, 0x9a, 0xcc, 0x4f,
-	0x35, 0x8c, 0xd6, 0x98, 0xef, 0xeb, 0x45, 0xb9,
-	0x9a, 0x26, 0x2f, 0x39, 0xa5, 0x70, 0x6d, 0xfc,
-	0xb4, 0x51, 0xee, 0xf4, 0x9c, 0xe7, 0x38, 0x59,
-	0xad, 0xf4, 0xbc, 0x46, 0xff, 0x46, 0x8e, 0x60,
-	0x9c, 0xa3, 0x60, 0x1d, 0xf8, 0x26, 0x72, 0xf5,
-	0x72, 0x9d, 0x68, 0x80, 0x04, 0xf6, 0x0b, 0xa1,
-	0x0a, 0xd5, 0xa7, 0x82, 0x3a, 0x3e, 0x47, 0xa8,
-	0x5a, 0xde, 0x59, 0x4f, 0x7b, 0x07, 0xb3, 0xe9,
-	0x24, 0x19, 0x3d, 0x34, 0x05, 0xec, 0xf1, 0xab,
-	0x6e, 0x64, 0x8f, 0xd3, 0xe6, 0x41, 0x86, 0x80,
-	0x70, 0xe3, 0x8d, 0x60, 0x9c, 0x34, 0x25, 0x01,
-	0x07, 0x4d, 0x19, 0x41, 0x4e, 0x3d, 0x5c, 0x7e,
-	0xa8, 0xf5, 0xcc, 0xd5, 0x7b, 0xe2, 0x7d, 0x3d,
-	0x49, 0x86, 0x7d, 0x07, 0xb7, 0x10, 0xe3, 0x35,
-	0xb8, 0x84, 0x6d, 0x76, 0xab, 0x17, 0xc6, 0x38,
-	0xb4, 0xd3, 0x28, 0x57, 0xad, 0xd3, 0x88, 0x5a,
-	0xda, 0xea, 0xc8, 0x94, 0xcc, 0x37, 0x19, 0xac,
-	0x9c, 0x9f, 0x4b, 0x00, 0x15, 0xc0, 0xc8, 0xca,
-	0x1f, 0x15, 0xaa, 0xe0, 0xdb, 0xf9, 0x2f, 0x57,
-	0x1b, 0x24, 0xc7, 0x6f, 0x76, 0x29, 0xfb, 0xed,
-	0x25, 0x0d, 0xc0, 0xfe, 0xbd, 0x5a, 0xbf, 0x20,
-	0x08, 0x51, 0x05, 0xec, 0x71, 0xa3, 0xbf, 0xef,
-	0x5e, 0x99, 0x75, 0xdb, 0x3c, 0x5f, 0x9a, 0x8c,
-	0xbb, 0x19, 0x5c, 0x0e, 0x93, 0x19, 0xf8, 0x6a,
-	0xbc, 0xf2, 0x12, 0x54, 0x2f, 0xcb, 0x28, 0x64,
-	0x88, 0xb3, 0x92, 0x0d, 0x96, 0xd1, 0xa6, 0xe4,
-	0x1f, 0xf1, 0x4d, 0xa4, 0xab, 0x1c, 0xee, 0x54,
-	0xf2, 0xad, 0x29, 0x6d, 0x32, 0x37, 0xb2, 0x16,
-	0x77, 0x5c, 0xdc, 0x2e, 0x54, 0xec, 0x75, 0x26,
-	0xc6, 0x36, 0xd9, 0x17, 0x2c, 0xf1, 0x7a, 0xdc,
-	0x4b, 0xf1, 0xe2, 0xd9, 0x95, 0xba, 0xac, 0x87,
-	0xc1, 0xf3, 0x8e, 0x58, 0x08, 0xd8, 0x87, 0x60,
-	0xc9, 0xee, 0x6a, 0xde, 0xa4, 0xd2, 0xfc, 0x0d,
-	0xe5, 0x36, 0xc4, 0x5c, 0x52, 0xb3, 0x07, 0x54,
-	0x65, 0x24, 0xc1, 0xb1, 0xd1, 0xb1, 0x53, 0x13,
-	0x31, 0x79, 0x7f, 0x05, 0x76, 0xeb, 0x37, 0x59,
-	0x15, 0x2b, 0xd1, 0x3f, 0xac, 0x08, 0x97, 0xeb,
-	0x91, 0x98, 0xdf, 0x6c, 0x09, 0x0d, 0x04, 0x9f,
-	0xdc, 0x3b, 0x0e, 0x60, 0x68, 0x47, 0x23, 0x15,
-	0x16, 0xc6, 0x0b, 0x35, 0xf8, 0x77, 0xa2, 0x78,
-	0x50, 0xd4, 0x64, 0x22, 0x33, 0xff, 0xfb, 0x93,
-	0x71, 0x46, 0x50, 0x39, 0x1b, 0x9c, 0xea, 0x4e,
-	0x8d, 0x0c, 0x37, 0xe5, 0x5c, 0x51, 0x3a, 0x31,
-	0xb2, 0x85, 0x84, 0x3f, 0x41, 0xee, 0xa2, 0xc1,
-	0xc6, 0x13, 0x3b, 0x54, 0x28, 0xd2, 0x18, 0x37,
-	0xcc, 0x46, 0x9f, 0x6a, 0x91, 0x3d, 0x5a, 0x15,
-	0x3c, 0x89, 0xa3, 0x61, 0x06, 0x7d, 0x2e, 0x78,
-	0xbe, 0x7d, 0x40, 0xba, 0x2f, 0x95, 0xb1, 0x2f,
-	0x87, 0x3b, 0x8a, 0xbe, 0x6a, 0xf4, 0xc2, 0x31,
-	0x74, 0xee, 0x91, 0xe0, 0x23, 0xaa, 0x5d, 0x7f,
-	0xdd, 0xf0, 0x44, 0x8c, 0x0b, 0x59, 0x2b, 0xfc,
-	0x48, 0x3a, 0xdf, 0x07, 0x05, 0x38, 0x6c, 0xc9,
-	0xeb, 0x18, 0x24, 0x68, 0x8d, 0x58, 0x98, 0xd3,
-	0x31, 0xa3, 0xe4, 0x70, 0x59, 0xb1, 0x21, 0xbe,
-	0x7e, 0x65, 0x7d, 0xb8, 0x04, 0xab, 0xf6, 0xe4,
-	0xd7, 0xda, 0xec, 0x09, 0x8f, 0xda, 0x6d, 0x24,
-	0x07, 0xcc, 0x29, 0x17, 0x05, 0x78, 0x1a, 0xc1,
-	0xb1, 0xce, 0xfc, 0xaa, 0x2d, 0xe7, 0xcc, 0x85,
-	0x84, 0x84, 0x03, 0x2a, 0x0c, 0x3f, 0xa9, 0xf8,
-	0xfd, 0x84, 0x53, 0x59, 0x5c, 0xf0, 0xd4, 0x09,
-	0xf0, 0xd2, 0x6c, 0x32, 0x03, 0xb0, 0xa0, 0x8c,
-	0x52, 0xeb, 0x23, 0x91, 0x88, 0x43, 0x13, 0x46,
-	0xf6, 0x1e, 0xb4, 0x1b, 0xf5, 0x8e, 0x3a, 0xb5,
-	0x3d, 0x00, 0xf6, 0xe5, 0x08, 0x3d, 0x5f, 0x39,
-	0xd3, 0x21, 0x69, 0xbc, 0x03, 0x22, 0x3a, 0xd2,
-	0x5c, 0x84, 0xf8, 0x15, 0xc4, 0x80, 0x0b, 0xbc,
-	0x29, 0x3c, 0xf3, 0x95, 0x98, 0xcd, 0x8f, 0x35,
-	0xbc, 0xa5, 0x3e, 0xfc, 0xd4, 0x13, 0x9e, 0xde,
-	0x4f, 0xce, 0x71, 0x9d, 0x09, 0xad, 0xf2, 0x80,
-	0x6b, 0x65, 0x7f, 0x03, 0x00, 0x14, 0x7c, 0x15,
-	0x85, 0x40, 0x6d, 0x70, 0xea, 0xdc, 0xb3, 0x63,
-	0x35, 0x4f, 0x4d, 0xe0, 0xd9, 0xd5, 0x3c, 0x58,
-	0x56, 0x23, 0x80, 0xe2, 0x36, 0xdd, 0x75, 0x1d,
-	0x94, 0x11, 0x41, 0x8e, 0xe0, 0x81, 0x8e, 0xcf,
-	0xe0, 0xe5, 0xf6, 0xde, 0xd1, 0xe7, 0x04, 0x12,
-	0x79, 0x92, 0x2b, 0x71, 0x2a, 0x79, 0x8b, 0x7c,
-	0x44, 0x79, 0x16, 0x30, 0x4e, 0xf4, 0xf6, 0x9b,
-	0xb7, 0x40, 0xa3, 0x5a, 0xa7, 0x69, 0x3e, 0xc1,
-	0x3a, 0x04, 0xd0, 0x88, 0xa0, 0x3b, 0xdd, 0xc6,
-	0x9e, 0x7e, 0x1e, 0x1e, 0x8f, 0x44, 0xf7, 0x73,
-	0x67, 0x1e, 0x1a, 0x78, 0xfa, 0x62, 0xf4, 0xa9,
-	0xa8, 0xc6, 0x5b, 0xb8, 0xfa, 0x06, 0x7d, 0x5e,
-	0x38, 0x1c, 0x9a, 0x39, 0xe9, 0x39, 0x98, 0x22,
-	0x0b, 0xa7, 0xac, 0x0b, 0xf3, 0xbc, 0xf1, 0xeb,
-	0x8c, 0x81, 0xe3, 0x48, 0x8a, 0xed, 0x42, 0xc2,
-	0x38, 0xcf, 0x3e, 0xda, 0xd2, 0x89, 0x8d, 0x9c,
-	0x53, 0xb5, 0x2f, 0x41, 0x01, 0x26, 0x84, 0x9c,
-	0xa3, 0x56, 0xf6, 0x49, 0xc7, 0xd4, 0x9f, 0x93,
-	0x1b, 0x96, 0x49, 0x5e, 0xad, 0xb3, 0x84, 0x1f,
-	0x3c, 0xa4, 0xe0, 0x9b, 0xd1, 0x90, 0xbc, 0x38,
-	0x6c, 0xdd, 0x95, 0x4d, 0x9d, 0xb1, 0x71, 0x57,
-	0x2d, 0x34, 0xe8, 0xb8, 0x42, 0xc7, 0x99, 0x03,
-	0xc7, 0x07, 0x30, 0x65, 0x91, 0x55, 0xd5, 0x90,
-	0x70, 0x97, 0x37, 0x68, 0xd4, 0x11, 0xf9, 0xe8,
-	0xce, 0xec, 0xdc, 0x34, 0xd5, 0xd3, 0xb7, 0xc4,
-	0xb8, 0x97, 0x05, 0x92, 0xad, 0xf8, 0xe2, 0x36,
-	0x64, 0x41, 0xc9, 0xc5, 0x41, 0x77, 0x52, 0xd7,
-	0x2c, 0xa5, 0x24, 0x2f, 0xd9, 0x34, 0x0b, 0x47,
-	0x35, 0xa7, 0x28, 0x8b, 0xc5, 0xcd, 0xe9, 0x46,
-	0xac, 0x39, 0x94, 0x3c, 0x10, 0xc6, 0x29, 0x73,
-	0x0e, 0x0e, 0x5d, 0xe0, 0x71, 0x03, 0x8a, 0x72,
-	0x0e, 0x26, 0xb0, 0x7d, 0x84, 0xed, 0x95, 0x23,
-	0x49, 0x5a, 0x45, 0x83, 0x45, 0x60, 0x11, 0x4a,
-	0x46, 0x31, 0xd4, 0xd8, 0x16, 0x54, 0x98, 0x58,
-	0xed, 0x6d, 0xcc, 0x5d, 0xd6, 0x50, 0x61, 0x9f,
-	0x9d, 0xc5, 0x3e, 0x9d, 0x32, 0x47, 0xde, 0x96,
-	0xe1, 0x5d, 0xd8, 0xf8, 0xb4, 0x69, 0x6f, 0xb9,
-	0x15, 0x90, 0x57, 0x7a, 0xf6, 0xad, 0xb0, 0x5b,
-	0xf5, 0xa6, 0x36, 0x94, 0xfd, 0x84, 0xce, 0x1c,
-	0x0f, 0x4b, 0xd0, 0xc2, 0x5b, 0x6b, 0x56, 0xef,
-	0x73, 0x93, 0x0b, 0xc3, 0xee, 0xd9, 0xcf, 0xd3,
-	0xa4, 0x22, 0x58, 0xcd, 0x50, 0x6e, 0x65, 0xf4,
-	0xe9, 0xb7, 0x71, 0xaf, 0x4b, 0xb3, 0xb6, 0x2f,
-	0x0f, 0x0e, 0x3b, 0xc9, 0x85, 0x14, 0xf5, 0x17,
-	0xe8, 0x7a, 0x3a, 0xbf, 0x5f, 0x5e, 0xf8, 0x18,
-	0x48, 0xa6, 0x72, 0xab, 0x06, 0x95, 0xe9, 0xc8,
-	0xa7, 0xf4, 0x32, 0x44, 0x04, 0x0c, 0x84, 0x98,
-	0x73, 0xe3, 0x89, 0x8d, 0x5f, 0x7e, 0x4a, 0x42,
-	0x8f, 0xc5, 0x28, 0xb1, 0x82, 0xef, 0x1c, 0x97,
-	0x31, 0x3b, 0x4d, 0xe0, 0x0e, 0x10, 0x10, 0x97,
-	0x93, 0x49, 0x78, 0x2f, 0x0d, 0x86, 0x8b, 0xa1,
-	0x53, 0xa9, 0x81, 0x20, 0x79, 0xe7, 0x07, 0x77,
-	0xb6, 0xac, 0x5e, 0xd2, 0x05, 0xcd, 0xe9, 0xdb,
-	0x8a, 0x94, 0x82, 0x8a, 0x23, 0xb9, 0x3d, 0x1c,
-	0xa9, 0x7d, 0x72, 0x4a, 0xed, 0x33, 0xa3, 0xdb,
-	0x21, 0xa7, 0x86, 0x33, 0x45, 0xa5, 0xaa, 0x56,
-	0x45, 0xb5, 0x83, 0x29, 0x40, 0x47, 0x79, 0x04,
-	0x6e, 0xb9, 0x95, 0xd0, 0x81, 0x77, 0x2d, 0x48,
-	0x1e, 0xfe, 0xc3, 0xc2, 0x1e, 0xe5, 0xf2, 0xbe,
-	0xfd, 0x3b, 0x94, 0x9f, 0xc4, 0xc4, 0x26, 0x9d,
-	0xe4, 0x66, 0x1e, 0x19, 0xee, 0x6c, 0x79, 0x97,
-	0x11, 0x31, 0x4b, 0x0d, 0x01, 0xcb, 0xde, 0xa8,
-	0xf6, 0x6d, 0x7c, 0x39, 0x46, 0x4e, 0x7e, 0x3f,
-	0x94, 0x17, 0xdf, 0xa1, 0x7d, 0xd9, 0x1c, 0x8e,
-	0xbc, 0x7d, 0x33, 0x7d, 0xe3, 0x12, 0x40, 0xca,
-	0xab, 0x37, 0x11, 0x46, 0xd4, 0xae, 0xef, 0x44,
-	0xa2, 0xb3, 0x6a, 0x66, 0x0e, 0x0c, 0x90, 0x7f,
-	0xdf, 0x5c, 0x66, 0x5f, 0xf2, 0x94, 0x9f, 0xa6,
-	0x73, 0x4f, 0xeb, 0x0d, 0xad, 0xbf, 0xc0, 0x63,
-	0x5c, 0xdc, 0x46, 0x51, 0xe8, 0x8e, 0x90, 0x19,
-	0xa8, 0xa4, 0x3c, 0x91, 0x79, 0xfa, 0x7e, 0x58,
-	0x85, 0x13, 0x55, 0xc5, 0x19, 0x82, 0x37, 0x1b,
-	0x0a, 0x02, 0x1f, 0x99, 0x6b, 0x18, 0xf1, 0x28,
-	0x08, 0xa2, 0x73, 0xb8, 0x0f, 0x2e, 0xcd, 0xbf,
-	0xf3, 0x86, 0x7f, 0xea, 0xef, 0xd0, 0xbb, 0xa6,
-	0x21, 0xdf, 0x49, 0x73, 0x51, 0xcc, 0x36, 0xd3,
-	0x3e, 0xa0, 0xf8, 0x44, 0xdf, 0xd3, 0xa6, 0xbe,
-	0x8a, 0xd4, 0x57, 0xdd, 0x72, 0x94, 0x61, 0x0f,
-	0x82, 0xd1, 0x07, 0xb8, 0x7c, 0x18, 0x83, 0xdf,
-	0x3a, 0xe5, 0x50, 0x6a, 0x82, 0x20, 0xac, 0xa9,
-	0xa8, 0xff, 0xd9, 0xf3, 0x77, 0x33, 0x5a, 0x9e,
-	0x7f, 0x6d, 0xfe, 0x5d, 0x33, 0x41, 0x42, 0xe7,
-	0x6c, 0x19, 0xe0, 0x44, 0x8a, 0x15, 0xf6, 0x70,
-	0x98, 0xb7, 0x68, 0x4d, 0xfa, 0x97, 0x39, 0xb0,
-	0x8e, 0xe8, 0x84, 0x8b, 0x75, 0x30, 0xb7, 0x7d,
-	0x92, 0x69, 0x20, 0x9c, 0x81, 0xfb, 0x4b, 0xf4,
-	0x01, 0x50, 0xeb, 0xce, 0x0c, 0x1c, 0x6c, 0xb5,
-	0x4a, 0xd7, 0x27, 0x0c, 0xce, 0xbb, 0xe5, 0x85,
-	0xf0, 0xb6, 0xee, 0xd5, 0x70, 0xdd, 0x3b, 0xfc,
-	0xd4, 0x99, 0xf1, 0x33, 0xdd, 0x8b, 0xc4, 0x2f,
-	0xae, 0xab, 0x74, 0x96, 0x32, 0xc7, 0x4c, 0x56,
-	0x3c, 0x89, 0x0f, 0x96, 0x0b, 0x42, 0xc0, 0xcb,
-	0xee, 0x0f, 0x0b, 0x8c, 0xfb, 0x7e, 0x47, 0x7b,
-	0x64, 0x48, 0xfd, 0xb2, 0x00, 0x80, 0x89, 0xa5,
-	0x13, 0x55, 0x62, 0xfc, 0x8f, 0xe2, 0x42, 0x03,
-	0xb7, 0x4e, 0x2a, 0x79, 0xb4, 0x82, 0xea, 0x23,
-	0x49, 0xda, 0xaf, 0x52, 0x63, 0x1e, 0x60, 0x03,
-	0x89, 0x06, 0x44, 0x46, 0x08, 0xc3, 0xc4, 0x87,
-	0x70, 0x2e, 0xda, 0x94, 0xad, 0x6b, 0xe0, 0xe4,
-	0xd1, 0x8a, 0x06, 0xc2, 0xa8, 0xc0, 0xa7, 0x43,
-	0x3c, 0x47, 0x52, 0x0e, 0xc3, 0x77, 0x81, 0x11,
-	0x67, 0x0e, 0xa0, 0x70, 0x04, 0x47, 0x29, 0x40,
-	0x86, 0x0d, 0x34, 0x56, 0xa7, 0xc9, 0x35, 0x59,
-	0x68, 0xdc, 0x93, 0x81, 0x70, 0xee, 0x86, 0xd9,
-	0x80, 0x06, 0x40, 0x4f, 0x1a, 0x0d, 0x40, 0x30,
-	0x0b, 0xcb, 0x96, 0x47, 0xc1, 0xb7, 0x52, 0xfd,
-	0x56, 0xe0, 0x72, 0x4b, 0xfb, 0xbd, 0x92, 0x45,
-	0x61, 0x71, 0xc2, 0x33, 0x11, 0xbf, 0x52, 0x83,
-	0x79, 0x26, 0xe0, 0x49, 0x6b, 0xb7, 0x05, 0x8b,
-	0xe8, 0x0e, 0x87, 0x31, 0xd7, 0x9d, 0x8a, 0xf5,
-	0xc0, 0x5f, 0x2e, 0x58, 0x4a, 0xdb, 0x11, 0xb3,
-	0x6c, 0x30, 0x2a, 0x46, 0x19, 0xe3, 0x27, 0x84,
-	0x1f, 0x63, 0x6e, 0xf6, 0x57, 0xc7, 0xc9, 0xd8,
-	0x5e, 0xba, 0xb3, 0x87, 0xd5, 0x83, 0x26, 0x34,
-	0x21, 0x9e, 0x65, 0xde, 0x42, 0xd3, 0xbe, 0x7b,
-	0xbc, 0x91, 0x71, 0x44, 0x4d, 0x99, 0x3b, 0x31,
-	0xe5, 0x3f, 0x11, 0x4e, 0x7f, 0x13, 0x51, 0x3b,
-	0xae, 0x79, 0xc9, 0xd3, 0x81, 0x8e, 0x25, 0x40,
-	0x10, 0xfc, 0x07, 0x1e, 0xf9, 0x7b, 0x9a, 0x4b,
-	0x6c, 0xe3, 0xb3, 0xad, 0x1a, 0x0a, 0xdd, 0x9e,
-	0x59, 0x0c, 0xa2, 0xcd, 0xae, 0x48, 0x4a, 0x38,
-	0x5b, 0x47, 0x41, 0x94, 0x65, 0x6b, 0xbb, 0xeb,
-	0x5b, 0xe3, 0xaf, 0x07, 0x5b, 0xd4, 0x4a, 0xa2,
-	0xc9, 0x5d, 0x2f, 0x64, 0x03, 0xd7, 0x3a, 0x2c,
-	0x6e, 0xce, 0x76, 0x95, 0xb4, 0xb3, 0xc0, 0xf1,
-	0xe2, 0x45, 0x73, 0x7a, 0x5c, 0xab, 0xc1, 0xfc,
-	0x02, 0x8d, 0x81, 0x29, 0xb3, 0xac, 0x07, 0xec,
-	0x40, 0x7d, 0x45, 0xd9, 0x7a, 0x59, 0xee, 0x34,
-	0xf0, 0xe9, 0xd5, 0x7b, 0x96, 0xb1, 0x3d, 0x95,
-	0xcc, 0x86, 0xb5, 0xb6, 0x04, 0x2d, 0xb5, 0x92,
-	0x7e, 0x76, 0xf4, 0x06, 0xa9, 0xa3, 0x12, 0x0f,
-	0xb1, 0xaf, 0x26, 0xba, 0x7c, 0xfc, 0x7e, 0x1c,
-	0xbc, 0x2c, 0x49, 0x97, 0x53, 0x60, 0x13, 0x0b,
-	0xa6, 0x61, 0x83, 0x89, 0x42, 0xd4, 0x17, 0x0c,
-	0x6c, 0x26, 0x52, 0xc3, 0xb3, 0xd4, 0x67, 0xf5,
-	0xe3, 0x04, 0xb7, 0xf4, 0xcb, 0x80, 0xb8, 0xcb,
-	0x77, 0x56, 0x3e, 0xaa, 0x57, 0x54, 0xee, 0xb4,
-	0x2c, 0x67, 0xcf, 0xf2, 0xdc, 0xbe, 0x55, 0xf9,
-	0x43, 0x1f, 0x6e, 0x22, 0x97, 0x67, 0x7f, 0xc4,
-	0xef, 0xb1, 0x26, 0x31, 0x1e, 0x27, 0xdf, 0x41,
-	0x80, 0x47, 0x6c, 0xe2, 0xfa, 0xa9, 0x8c, 0x2a,
-	0xf6, 0xf2, 0xab, 0xf0, 0x15, 0xda, 0x6c, 0xc8,
-	0xfe, 0xb5, 0x23, 0xde, 0xa9, 0x05, 0x3f, 0x06,
-	0x54, 0x4c, 0xcd, 0xe1, 0xab, 0xfc, 0x0e, 0x62,
-	0x33, 0x31, 0x73, 0x2c, 0x76, 0xcb, 0xb4, 0x47,
-	0x1e, 0x20, 0xad, 0xd8, 0xf2, 0x31, 0xdd, 0xc4,
-	0x8b, 0x0c, 0x77, 0xbe, 0xe1, 0x8b, 0x26, 0x00,
-	0x02, 0x58, 0xd6, 0x8d, 0xef, 0xad, 0x74, 0x67,
-	0xab, 0x3f, 0xef, 0xcb, 0x6f, 0xb0, 0xcc, 0x81,
-	0x44, 0x4c, 0xaf, 0xe9, 0x49, 0x4f, 0xdb, 0xa0,
-	0x25, 0xa4, 0xf0, 0x89, 0xf1, 0xbe, 0xd8, 0x10,
-	0xff, 0xb1, 0x3b, 0x4b, 0xfa, 0x98, 0xf5, 0x79,
-	0x6d, 0x1e, 0x69, 0x4d, 0x57, 0xb1, 0xc8, 0x19,
-	0x1b, 0xbd, 0x1e, 0x8c, 0x84, 0xb7, 0x7b, 0xe8,
-	0xd2, 0x2d, 0x09, 0x41, 0x41, 0x37, 0x3d, 0xb1,
-	0x6f, 0x26, 0x5d, 0x71, 0x16, 0x3d, 0xb7, 0x83,
-	0x27, 0x2c, 0xa7, 0xb6, 0x50, 0xbd, 0x91, 0x86,
-	0xab, 0x24, 0xa1, 0x38, 0xfd, 0xea, 0x71, 0x55,
-	0x7e, 0x9a, 0x07, 0x77, 0x4b, 0xfa, 0x61, 0x66,
-	0x20, 0x1e, 0x28, 0x95, 0x18, 0x1b, 0xa4, 0xa0,
-	0xfd, 0xc0, 0x89, 0x72, 0x43, 0xd9, 0x3b, 0x49,
-	0x5a, 0x3f, 0x9d, 0xbf, 0xdb, 0xb4, 0x46, 0xea,
-	0x42, 0x01, 0x77, 0x23, 0x68, 0x95, 0xb6, 0x24,
-	0xb3, 0xa8, 0x6c, 0x28, 0x3b, 0x11, 0x40, 0x7e,
-	0x18, 0x65, 0x6d, 0xd8, 0x24, 0x42, 0x7d, 0x88,
-	0xc0, 0x52, 0xd9, 0x05, 0xe4, 0x95, 0x90, 0x87,
-	0x8c, 0xf4, 0xd0, 0x6b, 0xb9, 0x83, 0x99, 0x34,
-	0x6d, 0xfe, 0x54, 0x40, 0x94, 0x52, 0x21, 0x4f,
-	0x14, 0x25, 0xc5, 0xd6, 0x5e, 0x95, 0xdc, 0x0a,
-	0x2b, 0x89, 0x20, 0x11, 0x84, 0x48, 0xd6, 0x3a,
-	0xcd, 0x5c, 0x24, 0xad, 0x62, 0xe3, 0xb1, 0x93,
-	0x25, 0x8d, 0xcd, 0x7e, 0xfc, 0x27, 0xa3, 0x37,
-	0xfd, 0x84, 0xfc, 0x1b, 0xb2, 0xf1, 0x27, 0x38,
-	0x5a, 0xb7, 0xfc, 0xf2, 0xfa, 0x95, 0x66, 0xd4,
-	0xfb, 0xba, 0xa7, 0xd7, 0xa3, 0x72, 0x69, 0x48,
-	0x48, 0x8c, 0xeb, 0x28, 0x89, 0xfe, 0x33, 0x65,
-	0x5a, 0x36, 0x01, 0x7e, 0x06, 0x79, 0x0a, 0x09,
-	0x3b, 0x74, 0x11, 0x9a, 0x6e, 0xbf, 0xd4, 0x9e,
-	0x58, 0x90, 0x49, 0x4f, 0x4d, 0x08, 0xd4, 0xe5,
-	0x4a, 0x09, 0x21, 0xef, 0x8b, 0xb8, 0x74, 0x3b,
-	0x91, 0xdd, 0x36, 0x85, 0x60, 0x2d, 0xfa, 0xd4,
-	0x45, 0x7b, 0x45, 0x53, 0xf5, 0x47, 0x87, 0x7e,
-	0xa6, 0x37, 0xc8, 0x78, 0x7a, 0x68, 0x9d, 0x8d,
-	0x65, 0x2c, 0x0e, 0x91, 0x5c, 0xa2, 0x60, 0xf0,
-	0x8e, 0x3f, 0xe9, 0x1a, 0xcd, 0xaa, 0xe7, 0xd5,
-	0x77, 0x18, 0xaf, 0xc9, 0xbc, 0x18, 0xea, 0x48,
-	0x1b, 0xfb, 0x22, 0x48, 0x70, 0x16, 0x29, 0x9e,
-	0x5b, 0xc1, 0x2c, 0x66, 0x23, 0xbc, 0xf0, 0x1f,
-	0xef, 0xaf, 0xe4, 0xd6, 0x04, 0x19, 0x82, 0x7a,
-	0x0b, 0xba, 0x4b, 0x46, 0xb1, 0x6a, 0x85, 0x5d,
-	0xb4, 0x73, 0xd6, 0x21, 0xa1, 0x71, 0x60, 0x14,
-	0xee, 0x0a, 0x77, 0xc4, 0x66, 0x2e, 0xf9, 0x69,
-	0x30, 0xaf, 0x41, 0x0b, 0xc8, 0x83, 0x3c, 0x53,
-	0x99, 0x19, 0x27, 0x46, 0xf7, 0x41, 0x6e, 0x56,
-	0xdc, 0x94, 0x28, 0x67, 0x4e, 0xb7, 0x25, 0x48,
-	0x8a, 0xc2, 0xe0, 0x60, 0x96, 0xcc, 0x18, 0xf4,
-	0x84, 0xdd, 0xa7, 0x5e, 0x3e, 0x05, 0x0b, 0x26,
-	0x26, 0xb2, 0x5c, 0x1f, 0x57, 0x1a, 0x04, 0x7e,
-	0x6a, 0xe3, 0x2f, 0xb4, 0x35, 0xb6, 0x38, 0x40,
-	0x40, 0xcd, 0x6f, 0x87, 0x2e, 0xef, 0xa3, 0xd7,
-	0xa9, 0xc2, 0xe8, 0x0d, 0x27, 0xdf, 0x44, 0x62,
-	0x99, 0xa0, 0xfc, 0xcf, 0x81, 0x78, 0xcb, 0xfe,
-	0xe5, 0xa0, 0x03, 0x4e, 0x6c, 0xd7, 0xf4, 0xaf,
-	0x7a, 0xbb, 0x61, 0x82, 0xfe, 0x71, 0x89, 0xb2,
-	0x22, 0x7c, 0x8e, 0x83, 0x04, 0xce, 0xf6, 0x5d,
-	0x84, 0x8f, 0x95, 0x6a, 0x7f, 0xad, 0xfd, 0x32,
-	0x9c, 0x5e, 0xe4, 0x9c, 0x89, 0x60, 0x54, 0xaa,
-	0x96, 0x72, 0xd2, 0xd7, 0x36, 0x85, 0xa9, 0x45,
-	0xd2, 0x2a, 0xa1, 0x81, 0x49, 0x6f, 0x7e, 0x04,
-	0xfa, 0xe2, 0xfe, 0x90, 0x26, 0x77, 0x5a, 0x33,
-	0xb8, 0x04, 0x9a, 0x7a, 0xe6, 0x4c, 0x4f, 0xad,
-	0x72, 0x96, 0x08, 0x28, 0x58, 0x13, 0xf8, 0xc4,
-	0x1c, 0xf0, 0xc3, 0x45, 0x95, 0x49, 0x20, 0x8c,
-	0x9f, 0x39, 0x70, 0xe1, 0x77, 0xfe, 0xd5, 0x4b,
-	0xaf, 0x86, 0xda, 0xef, 0x22, 0x06, 0x83, 0x36,
-	0x29, 0x12, 0x11, 0x40, 0xbc, 0x3b, 0x86, 0xaa,
-	0xaa, 0x65, 0x60, 0xc3, 0x80, 0xca, 0xed, 0xa9,
-	0xf3, 0xb0, 0x79, 0x96, 0xa2, 0x55, 0x27, 0x28,
-	0x55, 0x73, 0x26, 0xa5, 0x50, 0xea, 0x92, 0x4b,
-	0x3c, 0x5c, 0x82, 0x33, 0xf0, 0x01, 0x3f, 0x03,
-	0xc1, 0x08, 0x05, 0xbf, 0x98, 0xf4, 0x9b, 0x6d,
-	0xa5, 0xa8, 0xb4, 0x82, 0x0c, 0x06, 0xfa, 0xff,
-	0x2d, 0x08, 0xf3, 0x05, 0x4f, 0x57, 0x2a, 0x39,
-	0xd4, 0x83, 0x0d, 0x75, 0x51, 0xd8, 0x5b, 0x1b,
-	0xd3, 0x51, 0x5a, 0x32, 0x2a, 0x9b, 0x32, 0xb2,
-	0xf2, 0xa4, 0x96, 0x12, 0xf2, 0xae, 0x40, 0x34,
-	0x67, 0xa8, 0xf5, 0x44, 0xd5, 0x35, 0x53, 0xfe,
-	0xa3, 0x60, 0x96, 0x63, 0x0f, 0x1f, 0x6e, 0xb0,
-	0x5a, 0x42, 0xa6, 0xfc, 0x51, 0x0b, 0x60, 0x27,
-	0xbc, 0x06, 0x71, 0xed, 0x65, 0x5b, 0x23, 0x86,
-	0x4a, 0x07, 0x3b, 0x22, 0x07, 0x46, 0xe6, 0x90,
-	0x3e, 0xf3, 0x25, 0x50, 0x1b, 0x4c, 0x7f, 0x03,
-	0x08, 0xa8, 0x36, 0x6b, 0x87, 0xe5, 0xe3, 0xdb,
-	0x9a, 0x38, 0x83, 0xff, 0x9f, 0x1a, 0x9f, 0x57,
-	0xa4, 0x2a, 0xf6, 0x37, 0xbc, 0x1a, 0xff, 0xc9,
-	0x1e, 0x35, 0x0c, 0xc3, 0x7c, 0xa3, 0xb2, 0xe5,
-	0xd2, 0xc6, 0xb4, 0x57, 0x47, 0xe4, 0x32, 0x16,
-	0x6d, 0xa9, 0xae, 0x64, 0xe6, 0x2d, 0x8d, 0xc5,
-	0x8d, 0x50, 0x8e, 0xe8, 0x1a, 0x22, 0x34, 0x2a,
-	0xd9, 0xeb, 0x51, 0x90, 0x4a, 0xb1, 0x41, 0x7d,
-	0x64, 0xf9, 0xb9, 0x0d, 0xf6, 0x23, 0x33, 0xb0,
-	0x33, 0xf4, 0xf7, 0x3f, 0x27, 0x84, 0xc6, 0x0f,
-	0x54, 0xa5, 0xc0, 0x2e, 0xec, 0x0b, 0x3a, 0x48,
-	0x6e, 0x80, 0x35, 0x81, 0x43, 0x9b, 0x90, 0xb1,
-	0xd0, 0x2b, 0xea, 0x21, 0xdc, 0xda, 0x5b, 0x09,
-	0xf4, 0xcc, 0x10, 0xb4, 0xc7, 0xfe, 0x79, 0x51,
-	0xc3, 0xc5, 0xac, 0x88, 0x74, 0x84, 0x0b, 0x4b,
-	0xca, 0x79, 0x16, 0x29, 0xfb, 0x69, 0x54, 0xdf,
-	0x41, 0x7e, 0xe9, 0xc7, 0x8e, 0xea, 0xa5, 0xfe,
-	0xfc, 0x76, 0x0e, 0x90, 0xc4, 0x92, 0x38, 0xad,
-	0x7b, 0x48, 0xe6, 0x6e, 0xf7, 0x21, 0xfd, 0x4e,
-	0x93, 0x0a, 0x7b, 0x41, 0x83, 0x68, 0xfb, 0x57,
-	0x51, 0x76, 0x34, 0xa9, 0x6c, 0x00, 0xaa, 0x4f,
-	0x66, 0x65, 0x98, 0x4a, 0x4f, 0xa3, 0xa0, 0xef,
-	0x69, 0x3f, 0xe3, 0x1c, 0x92, 0x8c, 0xfd, 0xd8,
-	0xe8, 0xde, 0x7c, 0x7f, 0x3e, 0x84, 0x8e, 0x69,
-	0x3c, 0xf1, 0xf2, 0x05, 0x46, 0xdc, 0x2f, 0x9d,
-	0x5e, 0x6e, 0x4c, 0xfb, 0xb5, 0x99, 0x2a, 0x59,
-	0x63, 0xc1, 0x34, 0xbc, 0x57, 0xc0, 0x0d, 0xb9,
-	0x61, 0x25, 0xf3, 0x33, 0x23, 0x51, 0xb6, 0x0d,
-	0x07, 0xa6, 0xab, 0x94, 0x4a, 0xb7, 0x2a, 0xea,
-	0xee, 0xac, 0xa3, 0xc3, 0x04, 0x8b, 0x0e, 0x56,
-	0xfe, 0x44, 0xa7, 0x39, 0xe2, 0xed, 0xed, 0xb4,
-	0x22, 0x2b, 0xac, 0x12, 0x32, 0x28, 0x91, 0xd8,
-	0xa5, 0xab, 0xff, 0x5f, 0xe0, 0x4b, 0xda, 0x78,
-	0x17, 0xda, 0xf1, 0x01, 0x5b, 0xcd, 0xe2, 0x5f,
-	0x50, 0x45, 0x73, 0x2b, 0xe4, 0x76, 0x77, 0xf4,
-	0x64, 0x1d, 0x43, 0xfb, 0x84, 0x7a, 0xea, 0x91,
-	0xae, 0xf9, 0x9e, 0xb7, 0xb4, 0xb0, 0x91, 0x5f,
-	0x16, 0x35, 0x9a, 0x11, 0xb8, 0xc7, 0xc1, 0x8c,
-	0xc6, 0x10, 0x8d, 0x2f, 0x63, 0x4a, 0xa7, 0x57,
-	0x3a, 0x51, 0xd6, 0x32, 0x2d, 0x64, 0x72, 0xd4,
-	0x66, 0xdc, 0x10, 0xa6, 0x67, 0xd6, 0x04, 0x23,
-	0x9d, 0x0a, 0x11, 0x77, 0xdd, 0x37, 0x94, 0x17,
-	0x3c, 0xbf, 0x8b, 0x65, 0xb0, 0x2e, 0x5e, 0x66,
-	0x47, 0x64, 0xac, 0xdd, 0xf0, 0x84, 0xfd, 0x39,
-	0xfa, 0x15, 0x5d, 0xef, 0xae, 0xca, 0xc1, 0x36,
-	0xa7, 0x5c, 0xbf, 0xc7, 0x08, 0xc2, 0x66, 0x00,
-	0x74, 0x74, 0x4e, 0x27, 0x3f, 0x55, 0x8a, 0xb7,
-	0x38, 0x66, 0x83, 0x6d, 0xcf, 0x99, 0x9e, 0x60,
-	0x8f, 0xdd, 0x2e, 0x62, 0x22, 0x0e, 0xef, 0x0c,
-	0x98, 0xa7, 0x85, 0x74, 0x3b, 0x9d, 0xec, 0x9e,
-	0xa9, 0x19, 0x72, 0xa5, 0x7f, 0x2c, 0x39, 0xb7,
-	0x7d, 0xb7, 0xf1, 0x12, 0x65, 0x27, 0x4b, 0x5a,
-	0xde, 0x17, 0xfe, 0xad, 0x44, 0xf3, 0x20, 0x4d,
-	0xfd, 0xe4, 0x1f, 0xb5, 0x81, 0xb0, 0x36, 0x37,
-	0x08, 0x6f, 0xc3, 0x0c, 0xe9, 0x85, 0x98, 0x82,
-	0xa9, 0x62, 0x0c, 0xc4, 0x97, 0xc0, 0x50, 0xc8,
-	0xa7, 0x3c, 0x50, 0x9f, 0x43, 0xb9, 0xcd, 0x5e,
-	0x4d, 0xfa, 0x1c, 0x4b, 0x0b, 0xa9, 0x98, 0x85,
-	0x38, 0x92, 0xac, 0x8d, 0xe4, 0xad, 0x9b, 0x98,
-	0xab, 0xd9, 0x38, 0xac, 0x62, 0x52, 0xa3, 0x22,
-	0x63, 0x0f, 0xbf, 0x95, 0x48, 0xdf, 0x69, 0xe7,
-	0x8b, 0x33, 0xd5, 0xb2, 0xbd, 0x05, 0x49, 0x49,
-	0x9d, 0x57, 0x73, 0x19, 0x33, 0xae, 0xfa, 0x33,
-	0xf1, 0x19, 0xa8, 0x80, 0xce, 0x04, 0x9f, 0xbc,
-	0x1d, 0x65, 0x82, 0x1b, 0xe5, 0x3a, 0x51, 0xc8,
-	0x1c, 0x21, 0xe3, 0x5d, 0xf3, 0x7d, 0x9b, 0x2f,
-	0x2c, 0x1d, 0x4a, 0x7f, 0x9b, 0x68, 0x35, 0xa3,
-	0xb2, 0x50, 0xf7, 0x62, 0x79, 0xcd, 0xf4, 0x98,
-	0x4f, 0xe5, 0x63, 0x7c, 0x3e, 0x45, 0x31, 0x8c,
-	0x16, 0xa0, 0x12, 0xc8, 0x58, 0xce, 0x39, 0xa6,
-	0xbc, 0x54, 0xdb, 0xc5, 0xe0, 0xd5, 0xba, 0xbc,
-	0xb9, 0x04, 0xf4, 0x8d, 0xe8, 0x2f, 0x15, 0x9d,
-};
-
-/* 100 test cases */
-static struct crc_test {
-	u32 crc;	/* random starting crc */
-	u32 start;	/* random 6 bit offset in buf */
-	u32 length;	/* random 11 bit length of test */
-	u32 crc_le;	/* expected crc32_le result */
-	u32 crc_be;	/* expected crc32_be result */
-	u32 crc32c_le;	/* expected crc32c_le result */
-} const test[] __initconst =
-{
-	{0x674bf11d, 0x00000038, 0x00000542, 0x0af6d466, 0xd8b6e4c1, 0xf6e93d6c},
-	{0x35c672c6, 0x0000003a, 0x000001aa, 0xc6d3dfba, 0x28aaf3ad, 0x0fe92aca},
-	{0x496da28e, 0x00000039, 0x000005af, 0xd933660f, 0x5d57e81f, 0x52e1ebb8},
-	{0x09a9b90e, 0x00000027, 0x000001f8, 0xb45fe007, 0xf45fca9a, 0x0798af9a},
-	{0xdc97e5a9, 0x00000025, 0x000003b6, 0xf81a3562, 0xe0126ba2, 0x18eb3152},
-	{0x47c58900, 0x0000000a, 0x000000b9, 0x8e58eccf, 0xf3afc793, 0xd00d08c7},
-	{0x292561e8, 0x0000000c, 0x00000403, 0xa2ba8aaf, 0x0b797aed, 0x8ba966bc},
-	{0x415037f6, 0x00000003, 0x00000676, 0xa17d52e8, 0x7f0fdf35, 0x11d694a2},
-	{0x3466e707, 0x00000026, 0x00000042, 0x258319be, 0x75c484a2, 0x6ab3208d},
-	{0xafd1281b, 0x00000023, 0x000002ee, 0x4428eaf8, 0x06c7ad10, 0xba4603c5},
-	{0xd3857b18, 0x00000028, 0x000004a2, 0x5c430821, 0xb062b7cb, 0xe6071c6f},
-	{0x1d825a8f, 0x0000002b, 0x0000050b, 0xd2c45f0c, 0xd68634e0, 0x179ec30a},
-	{0x5033e3bc, 0x0000000b, 0x00000078, 0xa3ea4113, 0xac6d31fb, 0x0903beb8},
-	{0x94f1fb5e, 0x0000000f, 0x000003a2, 0xfbfc50b1, 0x3cfe50ed, 0x6a7cb4fa},
-	{0xc9a0fe14, 0x00000009, 0x00000473, 0x5fb61894, 0x87070591, 0xdb535801},
-	{0x88a034b1, 0x0000001c, 0x000005ad, 0xc1b16053, 0x46f95c67, 0x92bed597},
-	{0xf0f72239, 0x00000020, 0x0000026d, 0xa6fa58f3, 0xf8c2c1dd, 0x192a3f1b},
-	{0xcc20a5e3, 0x0000003b, 0x0000067a, 0x7740185a, 0x308b979a, 0xccbaec1a},
-	{0xce589c95, 0x0000002b, 0x00000641, 0xd055e987, 0x40aae25b, 0x7eabae4d},
-	{0x78edc885, 0x00000035, 0x000005be, 0xa39cb14b, 0x035b0d1f, 0x28c72982},
-	{0x9d40a377, 0x0000003b, 0x00000038, 0x1f47ccd2, 0x197fbc9d, 0xc3cd4d18},
-	{0x703d0e01, 0x0000003c, 0x000006f1, 0x88735e7c, 0xfed57c5a, 0xbca8f0e7},
-	{0x776bf505, 0x0000000f, 0x000005b2, 0x5cc4fc01, 0xf32efb97, 0x713f60b3},
-	{0x4a3e7854, 0x00000027, 0x000004b8, 0x8d923c82, 0x0cbfb4a2, 0xebd08fd5},
-	{0x209172dd, 0x0000003b, 0x00000356, 0xb89e9c2b, 0xd7868138, 0x64406c59},
-	{0x3ba4cc5b, 0x0000002f, 0x00000203, 0xe51601a9, 0x5b2a1032, 0x7421890e},
-	{0xfc62f297, 0x00000000, 0x00000079, 0x71a8e1a2, 0x5d88685f, 0xe9347603},
-	{0x64280b8b, 0x00000016, 0x000007ab, 0x0fa7a30c, 0xda3a455f, 0x1bef9060},
-	{0x97dd724b, 0x00000033, 0x000007ad, 0x5788b2f4, 0xd7326d32, 0x34720072},
-	{0x61394b52, 0x00000035, 0x00000571, 0xc66525f1, 0xcabe7fef, 0x48310f59},
-	{0x29b4faff, 0x00000024, 0x0000006e, 0xca13751e, 0x993648e0, 0x783a4213},
-	{0x29bfb1dc, 0x0000000b, 0x00000244, 0x436c43f7, 0x429f7a59, 0x9e8efd41},
-	{0x86ae934b, 0x00000035, 0x00000104, 0x0760ec93, 0x9cf7d0f4, 0xfc3d34a5},
-	{0xc4c1024e, 0x0000002e, 0x000006b1, 0x6516a3ec, 0x19321f9c, 0x17a52ae2},
-	{0x3287a80a, 0x00000026, 0x00000496, 0x0b257eb1, 0x754ebd51, 0x886d935a},
-	{0xa4db423e, 0x00000023, 0x0000045d, 0x9b3a66dc, 0x873e9f11, 0xeaaeaeb2},
-	{0x7a1078df, 0x00000015, 0x0000014a, 0x8c2484c5, 0x6a628659, 0x8e900a4b},
-	{0x6048bd5b, 0x00000006, 0x0000006a, 0x897e3559, 0xac9961af, 0xd74662b1},
-	{0xd8f9ea20, 0x0000003d, 0x00000277, 0x60eb905b, 0xed2aaf99, 0xd26752ba},
-	{0xea5ec3b4, 0x0000002a, 0x000004fe, 0x869965dc, 0x6c1f833b, 0x8b1fcd62},
-	{0x2dfb005d, 0x00000016, 0x00000345, 0x6a3b117e, 0xf05e8521, 0xf54342fe},
-	{0x5a214ade, 0x00000020, 0x000005b6, 0x467f70be, 0xcb22ccd3, 0x5b95b988},
-	{0xf0ab9cca, 0x00000032, 0x00000515, 0xed223df3, 0x7f3ef01d, 0x2e1176be},
-	{0x91b444f9, 0x0000002e, 0x000007f8, 0x84e9a983, 0x5676756f, 0x66120546},
-	{0x1b5d2ddb, 0x0000002e, 0x0000012c, 0xba638c4c, 0x3f42047b, 0xf256a5cc},
-	{0xd824d1bb, 0x0000003a, 0x000007b5, 0x6288653b, 0x3a3ebea0, 0x4af1dd69},
-	{0x0470180c, 0x00000034, 0x000001f0, 0x9d5b80d6, 0x3de08195, 0x56f0a04a},
-	{0xffaa3a3f, 0x00000036, 0x00000299, 0xf3a82ab8, 0x53e0c13d, 0x74f6b6b2},
-	{0x6406cfeb, 0x00000023, 0x00000600, 0xa920b8e8, 0xe4e2acf4, 0x085951fd},
-	{0xb24aaa38, 0x0000003e, 0x000004a1, 0x657cc328, 0x5077b2c3, 0xc65387eb},
-	{0x58b2ab7c, 0x00000039, 0x000002b4, 0x3a17ee7e, 0x9dcb3643, 0x1ca9257b},
-	{0x3db85970, 0x00000006, 0x000002b6, 0x95268b59, 0xb9812c10, 0xfd196d76},
-	{0x857830c5, 0x00000003, 0x00000590, 0x4ef439d5, 0xf042161d, 0x5ef88339},
-	{0xe1fcd978, 0x0000003e, 0x000007d8, 0xae8d8699, 0xce0a1ef5, 0x2c3714d9},
-	{0xb982a768, 0x00000016, 0x000006e0, 0x62fad3df, 0x5f8a067b, 0x58576548},
-	{0x1d581ce8, 0x0000001e, 0x0000058b, 0xf0f5da53, 0x26e39eee, 0xfd7c57de},
-	{0x2456719b, 0x00000025, 0x00000503, 0x4296ac64, 0xd50e4c14, 0xd5fedd59},
-	{0xfae6d8f2, 0x00000000, 0x0000055d, 0x057fdf2e, 0x2a31391a, 0x1cc3b17b},
-	{0xcba828e3, 0x00000039, 0x000002ce, 0xe3f22351, 0x8f00877b, 0x270eed73},
-	{0x13d25952, 0x0000000a, 0x0000072d, 0x76d4b4cc, 0x5eb67ec3, 0x91ecbb11},
-	{0x0342be3f, 0x00000015, 0x00000599, 0xec75d9f1, 0x9d4d2826, 0x05ed8d0c},
-	{0xeaa344e0, 0x00000014, 0x000004d8, 0x72a4c981, 0x2064ea06, 0x0b09ad5b},
-	{0xbbb52021, 0x0000003b, 0x00000272, 0x04af99fc, 0xaf042d35, 0xf8d511fb},
-	{0xb66384dc, 0x0000001d, 0x000007fc, 0xd7629116, 0x782bd801, 0x5ad832cc},
-	{0x616c01b6, 0x00000022, 0x000002c8, 0x5b1dab30, 0x783ce7d2, 0x1214d196},
-	{0xce2bdaad, 0x00000016, 0x0000062a, 0x932535c8, 0x3f02926d, 0x5747218a},
-	{0x00fe84d7, 0x00000005, 0x00000205, 0x850e50aa, 0x753d649c, 0xde8f14de},
-	{0xbebdcb4c, 0x00000006, 0x0000055d, 0xbeaa37a2, 0x2d8c9eba, 0x3563b7b9},
-	{0xd8b1a02a, 0x00000010, 0x00000387, 0x5017d2fc, 0x503541a5, 0x071475d0},
-	{0x3b96cad2, 0x00000036, 0x00000347, 0x1d2372ae, 0x926cd90b, 0x54c79d60},
-	{0xc94c1ed7, 0x00000005, 0x0000038b, 0x9e9fdb22, 0x144a9178, 0x4c53eee6},
-	{0x1aad454e, 0x00000025, 0x000002b2, 0xc3f6315c, 0x5c7a35b3, 0x10137a3c},
-	{0xa4fec9a6, 0x00000000, 0x000006d6, 0x90be5080, 0xa4107605, 0xaa9d6c73},
-	{0x1bbe71e2, 0x0000001f, 0x000002fd, 0x4e504c3b, 0x284ccaf1, 0xb63d23e7},
-	{0x4201c7e4, 0x00000002, 0x000002b7, 0x7822e3f9, 0x0cc912a9, 0x7f53e9cf},
-	{0x23fddc96, 0x00000003, 0x00000627, 0x8a385125, 0x07767e78, 0x13c1cd83},
-	{0xd82ba25c, 0x00000016, 0x0000063e, 0x98e4148a, 0x283330c9, 0x49ff5867},
-	{0x786f2032, 0x0000002d, 0x0000060f, 0xf201600a, 0xf561bfcd, 0x8467f211},
-	{0xfebe4e1f, 0x0000002a, 0x000004f2, 0x95e51961, 0xfd80dcab, 0x3f9683b2},
-	{0x1a6e0a39, 0x00000008, 0x00000672, 0x8af6c2a5, 0x78dd84cb, 0x76a3f874},
-	{0x56000ab8, 0x0000000e, 0x000000e5, 0x36bacb8f, 0x22ee1f77, 0x863b702f},
-	{0x4717fe0c, 0x00000000, 0x000006ec, 0x8439f342, 0x5c8e03da, 0xdc6c58ff},
-	{0xd5d5d68e, 0x0000003c, 0x000003a3, 0x46fff083, 0x177d1b39, 0x0622cc95},
-	{0xc25dd6c6, 0x00000024, 0x000006c0, 0x5ceb8eb4, 0x892b0d16, 0xe85605cd},
-	{0xe9b11300, 0x00000023, 0x00000683, 0x07a5d59a, 0x6c6a3208, 0x31da5f06},
-	{0x95cd285e, 0x00000001, 0x00000047, 0x7b3a4368, 0x0202c07e, 0xa1f2e784},
-	{0xd9245a25, 0x0000001e, 0x000003a6, 0xd33c1841, 0x1936c0d5, 0xb07cc616},
-	{0x103279db, 0x00000006, 0x0000039b, 0xca09b8a0, 0x77d62892, 0xbf943b6c},
-	{0x1cba3172, 0x00000027, 0x000001c8, 0xcb377194, 0xebe682db, 0x2c01af1c},
-	{0x8f613739, 0x0000000c, 0x000001df, 0xb4b0bc87, 0x7710bd43, 0x0fe5f56d},
-	{0x1c6aa90d, 0x0000001b, 0x0000053c, 0x70559245, 0xda7894ac, 0xf8943b2d},
-	{0xaabe5b93, 0x0000003d, 0x00000715, 0xcdbf42fa, 0x0c3b99e7, 0xe4d89272},
-	{0xf15dd038, 0x00000006, 0x000006db, 0x6e104aea, 0x8d5967f2, 0x7c2f6bbb},
-	{0x584dd49c, 0x00000020, 0x000007bc, 0x36b6cfd6, 0xad4e23b2, 0xabbf388b},
-	{0x5d8c9506, 0x00000020, 0x00000470, 0x4c62378e, 0x31d92640, 0x1dca1f4e},
-	{0xb80d17b0, 0x00000032, 0x00000346, 0x22a5bb88, 0x9a7ec89f, 0x5c170e23},
-	{0xdaf0592e, 0x00000023, 0x000007b0, 0x3cab3f99, 0x9b1fdd99, 0xc0e9d672},
-	{0x4793cc85, 0x0000000d, 0x00000706, 0xe82e04f6, 0xed3db6b7, 0xc18bdc86},
-	{0x82ebf64e, 0x00000009, 0x000007c3, 0x69d590a9, 0x9efa8499, 0xa874fcdd},
-	{0xb18a0319, 0x00000026, 0x000007db, 0x1cf98dcc, 0x8fa9ad6a, 0x9dc0bb48},
-};
-
-#include <linux/time.h>
-
-static int __init crc32c_test(void)
-{
-	int i;
-	int errors = 0;
-	int bytes = 0;
-	u64 nsec;
-	unsigned long flags;
-
-	/* keep static to prevent cache warming code from
-	 * getting eliminated by the compiler */
-	static u32 crc;
-
-	/* pre-warm the cache */
-	for (i = 0; i < 100; i++) {
-		bytes += test[i].length;
-
-		crc ^= __crc32c_le(test[i].crc, test_buf +
-		    test[i].start, test[i].length);
-	}
-
-	/* reduce OS noise */
-	local_irq_save(flags);
-
-	nsec = ktime_get_ns();
-	for (i = 0; i < 100; i++) {
-		if (test[i].crc32c_le != __crc32c_le(test[i].crc, test_buf +
-		    test[i].start, test[i].length))
-			errors++;
-	}
-	nsec = ktime_get_ns() - nsec;
-
-	local_irq_restore(flags);
-
-	pr_info("crc32c: CRC_LE_BITS = %d\n", CRC_LE_BITS);
-
-	if (errors)
-		pr_warn("crc32c: %d self tests failed\n", errors);
-	else {
-		pr_info("crc32c: self tests passed, processed %d bytes in %lld nsec\n",
-			bytes, nsec);
-	}
-
-	return 0;
-}
-
-static int __init crc32c_combine_test(void)
-{
-	int i, j;
-	int errors = 0, runs = 0;
-
-	for (i = 0; i < 10; i++) {
-		u32 crc_full;
-
-		crc_full = __crc32c_le(test[i].crc, test_buf + test[i].start,
-				       test[i].length);
-		for (j = 0; j <= test[i].length; ++j) {
-			u32 crc1, crc2;
-			u32 len1 = j, len2 = test[i].length - j;
-
-			crc1 = __crc32c_le(test[i].crc, test_buf +
-					   test[i].start, len1);
-			crc2 = __crc32c_le(0, test_buf + test[i].start +
-					   len1, len2);
-
-			if (!(crc_full == __crc32c_le_combine(crc1, crc2, len2) &&
-			      crc_full == test[i].crc32c_le))
-				errors++;
-			runs++;
-			cond_resched();
-		}
-	}
-
-	if (errors)
-		pr_warn("crc32c_combine: %d/%d self tests failed\n", errors, runs);
-	else
-		pr_info("crc32c_combine: %d self tests passed\n", runs);
-
-	return 0;
-}
-
-static int __init crc32_test(void)
-{
-	int i;
-	int errors = 0;
-	int bytes = 0;
-	u64 nsec;
-	unsigned long flags;
-
-	/* keep static to prevent cache warming code from
-	 * getting eliminated by the compiler */
-	static u32 crc;
-
-	/* pre-warm the cache */
-	for (i = 0; i < 100; i++) {
-		bytes += 2*test[i].length;
-
-		crc ^= crc32_le(test[i].crc, test_buf +
-		    test[i].start, test[i].length);
-
-		crc ^= crc32_be(test[i].crc, test_buf +
-		    test[i].start, test[i].length);
-	}
-
-	/* reduce OS noise */
-	local_irq_save(flags);
-
-	nsec = ktime_get_ns();
-	for (i = 0; i < 100; i++) {
-		if (test[i].crc_le != crc32_le(test[i].crc, test_buf +
-		    test[i].start, test[i].length))
-			errors++;
-
-		if (test[i].crc_be != crc32_be(test[i].crc, test_buf +
-		    test[i].start, test[i].length))
-			errors++;
-	}
-	nsec = ktime_get_ns() - nsec;
-
-	local_irq_restore(flags);
-
-	pr_info("crc32: CRC_LE_BITS = %d, CRC_BE BITS = %d\n",
-		 CRC_LE_BITS, CRC_BE_BITS);
-
-	if (errors)
-		pr_warn("crc32: %d self tests failed\n", errors);
-	else {
-		pr_info("crc32: self tests passed, processed %d bytes in %lld nsec\n",
-			bytes, nsec);
-	}
-
-	return 0;
-}
-
-static int __init crc32_combine_test(void)
-{
-	int i, j;
-	int errors = 0, runs = 0;
-
-	for (i = 0; i < 10; i++) {
-		u32 crc_full;
-
-		crc_full = crc32_le(test[i].crc, test_buf + test[i].start,
-				    test[i].length);
-		for (j = 0; j <= test[i].length; ++j) {
-			u32 crc1, crc2;
-			u32 len1 = j, len2 = test[i].length - j;
-
-			crc1 = crc32_le(test[i].crc, test_buf +
-					test[i].start, len1);
-			crc2 = crc32_le(0, test_buf + test[i].start +
-					len1, len2);
-
-			if (!(crc_full == crc32_le_combine(crc1, crc2, len2) &&
-			      crc_full == test[i].crc_le))
-				errors++;
-			runs++;
-			cond_resched();
-		}
-	}
-
-	if (errors)
-		pr_warn("crc32_combine: %d/%d self tests failed\n", errors, runs);
-	else
-		pr_info("crc32_combine: %d self tests passed\n", runs);
-
-	return 0;
-}
-
-static int __init crc32test_init(void)
-{
-	crc32_test();
-	crc32c_test();
-
-	crc32_combine_test();
-	crc32c_combine_test();
-
-	return 0;
-}
-
-static void __exit crc32_exit(void)
-{
-}
-
-module_init(crc32test_init);
-module_exit(crc32_exit);
-
-MODULE_AUTHOR("Matt Domsch <Matt_Domsch at dell.com>");
-MODULE_DESCRIPTION("CRC32 selftest");
-MODULE_LICENSE("GPL");
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:47 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:47 -0800
Subject: [PATCH v2 03/12] crypto: crct10dif - expose arch-optimized lib function
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-4-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that crc_t10dif_update() may be directly optimized for each
architecture, make the shash driver for crct10dif register a
crct10dif-$arch algorithm that uses it, instead of only
crct10dif-generic which uses crc_t10dif_generic().

The result is that architecture-optimized crct10dif will remain
available through the shash API once the architectures implement
crc_t10dif_arch() instead of the shash API.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 crypto/Makefile            |  1 +
 crypto/crct10dif_generic.c | 82 +++++++++++++++++++++++++++++---------
 2 files changed, 65 insertions(+), 18 deletions(-)

diff --git a/crypto/Makefile b/crypto/Makefile
index 0537df1719d3..ffd94c7f2643 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -156,10 +156,11 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
 obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o
 obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o
 CFLAGS_crc32c_generic.o += -DARCH=$(ARCH)
 CFLAGS_crc32_generic.o += -DARCH=$(ARCH)
 obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_generic.o
+CFLAGS_crct10dif_generic.o += -DARCH=$(ARCH)
 obj-$(CONFIG_CRYPTO_CRC64_ROCKSOFT) += crc64_rocksoft_generic.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
 obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o
 obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
 obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o
diff --git a/crypto/crct10dif_generic.c b/crypto/crct10dif_generic.c
index e843982073bb..259cb01932cb 100644
--- a/crypto/crct10dif_generic.c
+++ b/crypto/crct10dif_generic.c
@@ -55,10 +55,19 @@ static int chksum_update(struct shash_desc *desc, const u8 *data,
 
 	ctx->crc = crc_t10dif_generic(ctx->crc, data, length);
 	return 0;
 }
 
+static int chksum_update_arch(struct shash_desc *desc, const u8 *data,
+			      unsigned int length)
+{
+	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
+	ctx->crc = crc_t10dif_update(ctx->crc, data, length);
+	return 0;
+}
+
 static int chksum_final(struct shash_desc *desc, u8 *out)
 {
 	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
 	*(__u16 *)out = ctx->crc;
@@ -69,49 +78,86 @@ static int __chksum_finup(__u16 crc, const u8 *data, unsigned int len, u8 *out)
 {
 	*(__u16 *)out = crc_t10dif_generic(crc, data, len);
 	return 0;
 }
 
+static int __chksum_finup_arch(__u16 crc, const u8 *data, unsigned int len,
+			       u8 *out)
+{
+	*(__u16 *)out = crc_t10dif_update(crc, data, len);
+	return 0;
+}
+
 static int chksum_finup(struct shash_desc *desc, const u8 *data,
 			unsigned int len, u8 *out)
 {
 	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
 	return __chksum_finup(ctx->crc, data, len, out);
 }
 
+static int chksum_finup_arch(struct shash_desc *desc, const u8 *data,
+			     unsigned int len, u8 *out)
+{
+	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
+	return __chksum_finup_arch(ctx->crc, data, len, out);
+}
+
 static int chksum_digest(struct shash_desc *desc, const u8 *data,
 			 unsigned int length, u8 *out)
 {
 	return __chksum_finup(0, data, length, out);
 }
 
-static struct shash_alg alg = {
-	.digestsize		=	CRC_T10DIF_DIGEST_SIZE,
-	.init		=	chksum_init,
-	.update		=	chksum_update,
-	.final		=	chksum_final,
-	.finup		=	chksum_finup,
-	.digest		=	chksum_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crct10dif",
-		.cra_driver_name	=	"crct10dif-generic",
-		.cra_priority		=	100,
-		.cra_blocksize		=	CRC_T10DIF_BLOCK_SIZE,
-		.cra_module		=	THIS_MODULE,
-	}
-};
+static int chksum_digest_arch(struct shash_desc *desc, const u8 *data,
+			      unsigned int length, u8 *out)
+{
+	return __chksum_finup_arch(0, data, length, out);
+}
+
+static struct shash_alg algs[] = {{
+	.digestsize		= CRC_T10DIF_DIGEST_SIZE,
+	.init			= chksum_init,
+	.update			= chksum_update,
+	.final			= chksum_final,
+	.finup			= chksum_finup,
+	.digest			= chksum_digest,
+	.descsize		= sizeof(struct chksum_desc_ctx),
+	.base.cra_name		= "crct10dif",
+	.base.cra_driver_name	= "crct10dif-generic",
+	.base.cra_priority	= 100,
+	.base.cra_blocksize	= CRC_T10DIF_BLOCK_SIZE,
+	.base.cra_module	= THIS_MODULE,
+}, {
+	.digestsize		= CRC_T10DIF_DIGEST_SIZE,
+	.init			= chksum_init,
+	.update			= chksum_update_arch,
+	.final			= chksum_final,
+	.finup			= chksum_finup_arch,
+	.digest			= chksum_digest_arch,
+	.descsize		= sizeof(struct chksum_desc_ctx),
+	.base.cra_name		= "crct10dif",
+	.base.cra_driver_name	= "crct10dif-" __stringify(ARCH),
+	.base.cra_priority	= 150,
+	.base.cra_blocksize	= CRC_T10DIF_BLOCK_SIZE,
+	.base.cra_module	= THIS_MODULE,
+}};
+
+static int num_algs;
 
 static int __init crct10dif_mod_init(void)
 {
-	return crypto_register_shash(&alg);
+	/* register the arch flavor only if it differs from the generic one */
+	num_algs = 1 + crc_t10dif_is_optimized();
+
+	return crypto_register_shashes(algs, num_algs);
 }
 
 static void __exit crct10dif_mod_fini(void)
 {
-	crypto_unregister_shash(&alg);
+	crypto_unregister_shashes(algs, num_algs);
 }
 
 subsys_initcall(crct10dif_mod_init);
 module_exit(crct10dif_mod_fini);
 
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:48 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:48 -0800
Subject: [PATCH v2 04/12] x86/crc-t10dif: expose CRC-T10DIF function through lib
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-5-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the x86 CRC-T10DIF assembly code into the lib directory and wire it
up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/x86/Kconfig                              |   1 +
 arch/x86/crypto/Kconfig                       |  10 --
 arch/x86/crypto/Makefile                      |   3 -
 arch/x86/crypto/crct10dif-pclmul_glue.c       | 143 ------------------
 arch/x86/lib/Makefile                         |   3 +
 arch/x86/lib/crc-t10dif-glue.c                |  51 +++++++
 .../{crypto => lib}/crct10dif-pcl-asm_64.S    |   0
 7 files changed, 55 insertions(+), 156 deletions(-)
 delete mode 100644 arch/x86/crypto/crct10dif-pclmul_glue.c
 create mode 100644 arch/x86/lib/crc-t10dif-glue.c
 rename arch/x86/{crypto => lib}/crct10dif-pcl-asm_64.S (100%)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 4f4fc67fbce7..65f8478fe7a9 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -75,10 +75,11 @@ config X86
 	select ARCH_HAS_CACHE_LINE_SIZE
 	select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
 	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_CPU_PASID		if IOMMU_SVA
 	select ARCH_HAS_CRC32
+	select ARCH_HAS_CRC_T10DIF		if X86_64
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE	if !X86_PAE
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_DMA_OPS			if GART_IOMMU || XEN
diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
index ba9a7e73cd08..4757bf922075 100644
--- a/arch/x86/crypto/Kconfig
+++ b/arch/x86/crypto/Kconfig
@@ -490,16 +490,6 @@ config CRYPTO_GHASH_CLMUL_NI_INTEL
 	  GCM GHASH hash function (NIST SP800-38D)
 
 	  Architecture: x86_64 using:
 	  - CLMUL-NI (carry-less multiplication new instructions)
 
-config CRYPTO_CRCT10DIF_PCLMUL
-	tristate "CRCT10DIF (PCLMULQDQ)"
-	depends on X86 && 64BIT && CRC_T10DIF
-	select CRYPTO_HASH
-	help
-	  CRC16 CRC algorithm used for the T10 (SCSI) Data Integrity Field (DIF)
-
-	  Architecture: x86_64 using:
-	  - PCLMULQDQ (carry-less multiplication)
-
 endmenu
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 030b925ca4e2..07b00bfca64b 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -73,13 +73,10 @@ obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
 ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o
 
 obj-$(CONFIG_CRYPTO_POLYVAL_CLMUL_NI) += polyval-clmulni.o
 polyval-clmulni-y := polyval-clmulni_asm.o polyval-clmulni_glue.o
 
-obj-$(CONFIG_CRYPTO_CRCT10DIF_PCLMUL) += crct10dif-pclmul.o
-crct10dif-pclmul-y := crct10dif-pcl-asm_64.o crct10dif-pclmul_glue.o
-
 obj-$(CONFIG_CRYPTO_POLY1305_X86_64) += poly1305-x86_64.o
 poly1305-x86_64-y := poly1305-x86_64-cryptogams.o poly1305_glue.o
 targets += poly1305-x86_64-cryptogams.S
 
 obj-$(CONFIG_CRYPTO_NHPOLY1305_SSE2) += nhpoly1305-sse2.o
diff --git a/arch/x86/crypto/crct10dif-pclmul_glue.c b/arch/x86/crypto/crct10dif-pclmul_glue.c
deleted file mode 100644
index 71291d5af9f4..000000000000
--- a/arch/x86/crypto/crct10dif-pclmul_glue.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Cryptographic API.
- *
- * T10 Data Integrity Field CRC16 Crypto Transform using PCLMULQDQ Instructions
- *
- * Copyright (C) 2013 Intel Corporation
- * Author: Tim Chen <tim.c.chen at linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/crc-t10dif.h>
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <asm/cpufeatures.h>
-#include <asm/cpu_device_id.h>
-#include <asm/simd.h>
-
-asmlinkage u16 crc_t10dif_pcl(u16 init_crc, const u8 *buf, size_t len);
-
-struct chksum_desc_ctx {
-	__u16 crc;
-};
-
-static int chksum_init(struct shash_desc *desc)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = 0;
-
-	return 0;
-}
-
-static int chksum_update(struct shash_desc *desc, const u8 *data,
-			 unsigned int length)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	if (length >= 16 && crypto_simd_usable()) {
-		kernel_fpu_begin();
-		ctx->crc = crc_t10dif_pcl(ctx->crc, data, length);
-		kernel_fpu_end();
-	} else
-		ctx->crc = crc_t10dif_generic(ctx->crc, data, length);
-	return 0;
-}
-
-static int chksum_final(struct shash_desc *desc, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	*(__u16 *)out = ctx->crc;
-	return 0;
-}
-
-static int __chksum_finup(__u16 crc, const u8 *data, unsigned int len, u8 *out)
-{
-	if (len >= 16 && crypto_simd_usable()) {
-		kernel_fpu_begin();
-		*(__u16 *)out = crc_t10dif_pcl(crc, data, len);
-		kernel_fpu_end();
-	} else
-		*(__u16 *)out = crc_t10dif_generic(crc, data, len);
-	return 0;
-}
-
-static int chksum_finup(struct shash_desc *desc, const u8 *data,
-			unsigned int len, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	return __chksum_finup(ctx->crc, data, len, out);
-}
-
-static int chksum_digest(struct shash_desc *desc, const u8 *data,
-			 unsigned int length, u8 *out)
-{
-	return __chksum_finup(0, data, length, out);
-}
-
-static struct shash_alg alg = {
-	.digestsize		=	CRC_T10DIF_DIGEST_SIZE,
-	.init		=	chksum_init,
-	.update		=	chksum_update,
-	.final		=	chksum_final,
-	.finup		=	chksum_finup,
-	.digest		=	chksum_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crct10dif",
-		.cra_driver_name	=	"crct10dif-pclmul",
-		.cra_priority		=	200,
-		.cra_blocksize		=	CRC_T10DIF_BLOCK_SIZE,
-		.cra_module		=	THIS_MODULE,
-	}
-};
-
-static const struct x86_cpu_id crct10dif_cpu_id[] = {
-	X86_MATCH_FEATURE(X86_FEATURE_PCLMULQDQ, NULL),
-	{}
-};
-MODULE_DEVICE_TABLE(x86cpu, crct10dif_cpu_id);
-
-static int __init crct10dif_intel_mod_init(void)
-{
-	if (!x86_match_cpu(crct10dif_cpu_id))
-		return -ENODEV;
-
-	return crypto_register_shash(&alg);
-}
-
-static void __exit crct10dif_intel_mod_fini(void)
-{
-	crypto_unregister_shash(&alg);
-}
-
-module_init(crct10dif_intel_mod_init);
-module_exit(crct10dif_intel_mod_fini);
-
-MODULE_AUTHOR("Tim Chen <tim.c.chen at linux.intel.com>");
-MODULE_DESCRIPTION("T10 DIF CRC calculation accelerated with PCLMULQDQ.");
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS_CRYPTO("crct10dif");
-MODULE_ALIAS_CRYPTO("crct10dif-pclmul");
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 17510da06c9f..8a59c61624c2 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -40,10 +40,13 @@ lib-$(CONFIG_MITIGATION_RETPOLINE) += retpoline.o
 
 obj-$(CONFIG_CRC32_ARCH) += crc32-x86.o
 crc32-x86-y := crc32-glue.o crc32-pclmul.o
 crc32-x86-$(CONFIG_64BIT) += crc32c-3way.o
 
+obj-$(CONFIG_CRC_T10DIF_ARCH) += crc-t10dif-x86.o
+crc-t10dif-x86-y := crc-t10dif-glue.o crct10dif-pcl-asm_64.o
+
 obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o
 obj-y += iomem.o
 
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
diff --git a/arch/x86/lib/crc-t10dif-glue.c b/arch/x86/lib/crc-t10dif-glue.c
new file mode 100644
index 000000000000..13f07ddc9122
--- /dev/null
+++ b/arch/x86/lib/crc-t10dif-glue.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * CRC-T10DIF using PCLMULQDQ instructions
+ *
+ * Copyright 2024 Google LLC
+ */
+
+#include <asm/cpufeatures.h>
+#include <asm/simd.h>
+#include <crypto/internal/simd.h>
+#include <linux/crc-t10dif.h>
+#include <linux/module.h>
+
+static DEFINE_STATIC_KEY_FALSE(have_pclmulqdq);
+
+asmlinkage u16 crc_t10dif_pcl(u16 init_crc, const u8 *buf, size_t len);
+
+u16 crc_t10dif_arch(u16 crc, const u8 *p, size_t len)
+{
+	if (len >= 16 &&
+	    static_key_enabled(&have_pclmulqdq) && crypto_simd_usable()) {
+		kernel_fpu_begin();
+		crc = crc_t10dif_pcl(crc, p, len);
+		kernel_fpu_end();
+		return crc;
+	}
+	return crc_t10dif_generic(crc, p, len);
+}
+EXPORT_SYMBOL(crc_t10dif_arch);
+
+static int __init crc_t10dif_x86_init(void)
+{
+	if (boot_cpu_has(X86_FEATURE_PCLMULQDQ))
+		static_branch_enable(&have_pclmulqdq);
+	return 0;
+}
+arch_initcall(crc_t10dif_x86_init);
+
+static void __exit crc_t10dif_x86_exit(void)
+{
+}
+module_exit(crc_t10dif_x86_exit);
+
+bool crc_t10dif_is_optimized(void)
+{
+	return static_key_enabled(&have_pclmulqdq);
+}
+EXPORT_SYMBOL(crc_t10dif_is_optimized);
+
+MODULE_DESCRIPTION("CRC-T10DIF using PCLMULQDQ instructions");
+MODULE_LICENSE("GPL");
diff --git a/arch/x86/crypto/crct10dif-pcl-asm_64.S b/arch/x86/lib/crct10dif-pcl-asm_64.S
similarity index 100%
rename from arch/x86/crypto/crct10dif-pcl-asm_64.S
rename to arch/x86/lib/crct10dif-pcl-asm_64.S
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:26 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:26 -0800
Subject: [PATCH v4 01/19] lib/crc32: drop leading underscores from __crc32c_le_base
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-2-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Remove the leading underscores from __crc32c_le_base().

This is in preparation for adding crc32c_le_arch() and eventually
renaming __crc32c_le() to crc32c_le().

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm64/lib/crc32-glue.c | 2 +-
 arch/riscv/lib/crc32.c      | 2 +-
 crypto/crc32c_generic.c     | 8 ++++----
 include/linux/crc32.h       | 2 +-
 lib/crc32.c                 | 4 ++--
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/lib/crc32-glue.c b/arch/arm64/lib/crc32-glue.c
index 295ae3e6b997..ad015223d15d 100644
--- a/arch/arm64/lib/crc32-glue.c
+++ b/arch/arm64/lib/crc32-glue.c
@@ -42,11 +42,11 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 }
 
 u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 {
 	if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
-		return __crc32c_le_base(crc, p, len);
+		return crc32c_le_base(crc, p, len);
 
 	if (len >= min_len && cpu_have_named_feature(PMULL) && crypto_simd_usable()) {
 		kernel_neon_begin();
 		crc = crc32c_le_arm64_4way(crc, p, len);
 		kernel_neon_end();
diff --git a/arch/riscv/lib/crc32.c b/arch/riscv/lib/crc32.c
index d7dc599af3ef..333fb7af1192 100644
--- a/arch/riscv/lib/crc32.c
+++ b/arch/riscv/lib/crc32.c
@@ -224,11 +224,11 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 }
 
 u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, CRC32C_POLY_LE,
-				CRC32C_POLY_QT_LE, __crc32c_le_base);
+				CRC32C_POLY_QT_LE, crc32c_le_base);
 }
 
 static inline u32 crc32_be_unaligned(u32 crc, unsigned char const *p,
 				     size_t len)
 {
diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c
index 7c2357c30fdf..635599b255ec 100644
--- a/crypto/crc32c_generic.c
+++ b/crypto/crc32c_generic.c
@@ -83,11 +83,11 @@ static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
 static int chksum_update(struct shash_desc *desc, const u8 *data,
 			 unsigned int length)
 {
 	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
-	ctx->crc = __crc32c_le_base(ctx->crc, data, length);
+	ctx->crc = crc32c_le_base(ctx->crc, data, length);
 	return 0;
 }
 
 static int chksum_update_arch(struct shash_desc *desc, const u8 *data,
 			      unsigned int length)
@@ -106,11 +106,11 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
 	return 0;
 }
 
 static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
 {
-	put_unaligned_le32(~__crc32c_le_base(*crcp, data, len), out);
+	put_unaligned_le32(~crc32c_le_base(*crcp, data, len), out);
 	return 0;
 }
 
 static int __chksum_finup_arch(u32 *crcp, const u8 *data, unsigned int len,
 			       u8 *out)
@@ -198,16 +198,16 @@ static struct shash_alg algs[] = {{
 }};
 
 static int __init crc32c_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + (&__crc32c_le != &__crc32c_le_base));
+	return crypto_register_shashes(algs, 1 + (&__crc32c_le != &crc32c_le_base));
 }
 
 static void __exit crc32c_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + (&__crc32c_le != &__crc32c_le_base));
+	crypto_unregister_shashes(algs, 1 + (&__crc32c_le != &crc32c_le_base));
 }
 
 subsys_initcall(crc32c_mod_init);
 module_exit(crc32c_mod_fini);
 
diff --git a/include/linux/crc32.h b/include/linux/crc32.h
index 87f788c0d607..5b07fc9081c4 100644
--- a/include/linux/crc32.h
+++ b/include/linux/crc32.h
@@ -37,11 +37,11 @@ static inline u32 crc32_le_combine(u32 crc1, u32 crc2, size_t len2)
 {
 	return crc32_le_shift(crc1, len2) ^ crc2;
 }
 
 u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len);
-u32 __pure __crc32c_le_base(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32c_le_base(u32 crc, unsigned char const *p, size_t len);
 
 /**
  * __crc32c_le_combine - Combine two crc32c check values into one. For two
  * 			 sequences of bytes, seq1 and seq2 with lengths len1
  * 			 and len2, __crc32c_le() check values were calculated
diff --git a/lib/crc32.c b/lib/crc32.c
index ff587fee3893..c67059b0082b 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -205,12 +205,12 @@ EXPORT_SYMBOL(crc32_le);
 EXPORT_SYMBOL(__crc32c_le);
 
 u32 __pure crc32_le_base(u32, unsigned char const *, size_t) __alias(crc32_le);
 EXPORT_SYMBOL(crc32_le_base);
 
-u32 __pure __crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le);
-EXPORT_SYMBOL(__crc32c_le_base);
+u32 __pure crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le);
+EXPORT_SYMBOL(crc32c_le_base);
 
 u32 __pure crc32_be_base(u32, unsigned char const *, size_t) __alias(crc32_be);
 
 /*
  * This multiplies the polynomials x and y modulo the given modulus.
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:25 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:25 -0800
Subject: [PATCH v4 00/19] Wire up CRC32 library functions to arch-optimized code
Message-ID: <20241202010844.144356-1-ebiggers@kernel.org>

This patchset applies to v6.13-rc1 and is also available in git via:

    git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git crc32-lib-v4

CRC32 is a family of common non-cryptographic integrity check algorithms
that are fairly fast with a portable C implementation and become far
faster still with the CRC32 or carryless multiplication instructions
that most CPUs have.  9 architectures already have optimized code for at
least some CRC32 variants; however, except for arm64 this optimized code
was only accessible through the crypto API, not the library functions.

This patchset fixes that so that the CRC32 library functions use the
optimized code.  This allows users to just use the library instead of
the crypto API.  This is much simpler and also improves performance due
to eliminating the crypto API overhead including an indirect call.  Some
examples of updating users are included at the end of the patchset.

Note: crc32c() was a weird case.  It was a library function layered on
top of the crypto API, which in turn is layered on top of the real
library functions.  So while it was easy to use, it was still subject to
the crypto API overhead.  This patchset provides CRC32C acceleration in
the real library functions directly.

The updated CRC32 library design is:

- Each arch's CRC32 code (all variants) is in arch/$ARCH/lib/crc32*.
  This adopts what arm64 and riscv already did.  Note, the crypto
  directory is not used because CRC32 is not a cryptographic algorithm.

- Weak symbols are no longer used.  Instead there are crc32*_base() and
  crc32*_arch(), and the appropriate ones are called based on the
  kconfig.  This is similar to how the ChaCha20 library code works.

- Each arch's CRC32 library code is enabled by default when CRC32 is
  enabled, but it can now be disabled, controlled by the choice that
  previously controlled the base implementation only.  It can also now
  be built as a module if CRC32 is a module too, in which case it will
  be automatically loaded via direct symbol dependency when appropriate.

- Instead of lots of pointless glue code that wires up each CRC32
  variant to the crypto API for each architecture, we now just rely on
  the existing shash algorithms that use the library functions.

- As before, the library functions don't provide access to off-CPU
  crypto accelerators.  But these appear to have very little, if any,
  real-world relevance for CRC32 which is very fast on CPUs.

A separate patchset applies a similar cleanup to CRC-T10DIF.

Changed in v4:
  - Rebased onto v6.13-rc1.
  - Removed no-longer-needed CFI stubs from arch/arm/lib/crc32-core.S.
  - Removed no-longer-needed definition of JBD_MAX_CHECKSUM_SIZE from jbd2.h.
  - Removed no-longer-needed inclusion of <crypto/hash.h> from f2fs.h.
  - Merged 'if' statements with the same condition in jbd2_journal_set_features.
  - Added bcachefs dependency patch, as it wasn't merged in 6.13 as expected.
  - Reordered CPU feature checks to before crypto_simd_usable(), so that
    crypto_simd_usable() doesn't get called unnecessarily.
  - For loongarch, use cpu_has_crc32() instead of cpu_has(CPU_FEATURE_CRC32),
    for consistency with the rest of the loongarch code.
  - Correctly set the new dependencies of CRYPTO_VPMSUM_TESTER.
  - Added Reviewed-by's and Acked-by's.

Changed in v3:
  - Replaced crc32_optimizations global variable with
    crc32_optimizations() function.
  - Make ISCSI_TARGET keep selecting CRYPTO_HASH, since
    iscsi_target_auth.c still uses the shash API for other algorithms.

Changed in v2:
  - Added a way to determine if the arch-optimized code is actually
    being used at runtime, and used this to register the appropriate
    shash algorithms with crypto API.
  - Added a patch that converts iSCSI to use the library.
  - Listed a bcachefs patch as a dependency.
  - Added Ard's Reviewed-by.

Eric Biggers (19):
  lib/crc32: drop leading underscores from __crc32c_le_base
  lib/crc32: improve support for arch-specific overrides
  lib/crc32: expose whether the lib is really optimized at runtime
  crypto: crc32 - don't unnecessarily register arch algorithms
  arm/crc32: expose CRC32 functions through lib
  loongarch/crc32: expose CRC32 functions through lib
  mips/crc32: expose CRC32 functions through lib
  powerpc/crc32: expose CRC32 functions through lib
  s390/crc32: expose CRC32 functions through lib
  sparc/crc32: expose CRC32 functions through lib
  x86/crc32: update prototype for crc_pcl()
  x86/crc32: update prototype for crc32_pclmul_le_16()
  x86/crc32: expose CRC32 functions through lib
  bcachefs: Explicitly select CRYPTO from BCACHEFS_FS
  lib/crc32: make crc32c() go directly to lib
  ext4: switch to using the crc32c library
  jbd2: switch to using the crc32c library
  f2fs: switch to using the crc32 library
  scsi: target: iscsi: switch to using the crc32c library

 arch/arm/Kconfig                              |   1 +
 arch/arm/configs/milbeaut_m10v_defconfig      |   1 -
 arch/arm/configs/multi_v7_defconfig           |   1 -
 arch/arm/crypto/Kconfig                       |  14 -
 arch/arm/crypto/Makefile                      |   2 -
 arch/arm/crypto/crc32-ce-glue.c               | 247 ------------
 arch/arm/lib/Makefile                         |   3 +
 .../crc32-ce-core.S => lib/crc32-core.S}      |   5 +-
 arch/arm/lib/crc32-glue.c                     | 123 ++++++
 arch/arm64/Kconfig                            |   1 +
 arch/arm64/lib/Makefile                       |   3 +-
 arch/arm64/lib/crc32-glue.c                   |  25 +-
 arch/loongarch/Kconfig                        |   1 +
 arch/loongarch/configs/loongson3_defconfig    |   1 -
 arch/loongarch/crypto/Kconfig                 |   9 -
 arch/loongarch/crypto/Makefile                |   2 -
 arch/loongarch/crypto/crc32-loongarch.c       | 300 ---------------
 arch/loongarch/lib/Makefile                   |   2 +
 arch/loongarch/lib/crc32-loongarch.c          | 135 +++++++
 arch/mips/Kconfig                             |   5 +-
 arch/mips/configs/eyeq5_defconfig             |   1 -
 arch/mips/configs/eyeq6_defconfig             |   1 -
 arch/mips/configs/generic/32r6.config         |   2 -
 arch/mips/configs/generic/64r6.config         |   1 -
 arch/mips/crypto/Kconfig                      |   9 -
 arch/mips/crypto/Makefile                     |   2 -
 arch/mips/crypto/crc32-mips.c                 | 354 ------------------
 arch/mips/lib/Makefile                        |   2 +
 arch/mips/lib/crc32-mips.c                    | 192 ++++++++++
 arch/powerpc/Kconfig                          |   1 +
 arch/powerpc/configs/powernv_defconfig        |   1 -
 arch/powerpc/configs/ppc64_defconfig          |   1 -
 arch/powerpc/crypto/Kconfig                   |  15 +-
 arch/powerpc/crypto/Makefile                  |   2 -
 arch/powerpc/crypto/crc32c-vpmsum_glue.c      | 173 ---------
 arch/powerpc/crypto/crct10dif-vpmsum_asm.S    |   2 +-
 arch/powerpc/lib/Makefile                     |   3 +
 arch/powerpc/lib/crc32-glue.c                 |  92 +++++
 .../{crypto => lib}/crc32-vpmsum_core.S       |   0
 .../{crypto => lib}/crc32c-vpmsum_asm.S       |   0
 arch/riscv/Kconfig                            |   1 +
 arch/riscv/lib/Makefile                       |   3 +-
 arch/riscv/lib/{crc32.c => crc32-riscv.c}     |  25 +-
 arch/s390/Kconfig                             |   1 +
 arch/s390/configs/debug_defconfig             |   1 -
 arch/s390/configs/defconfig                   |   1 -
 arch/s390/crypto/Kconfig                      |  12 -
 arch/s390/crypto/Makefile                     |   2 -
 arch/s390/crypto/crc32-vx.c                   | 306 ---------------
 arch/s390/lib/Makefile                        |   3 +
 arch/s390/lib/crc32-glue.c                    |  92 +++++
 arch/s390/{crypto => lib}/crc32-vx.h          |   0
 arch/s390/{crypto => lib}/crc32be-vx.c        |   0
 arch/s390/{crypto => lib}/crc32le-vx.c        |   0
 arch/sparc/Kconfig                            |   1 +
 arch/sparc/crypto/Kconfig                     |  10 -
 arch/sparc/crypto/Makefile                    |   4 -
 arch/sparc/crypto/crc32c_glue.c               | 184 ---------
 arch/sparc/lib/Makefile                       |   2 +
 arch/sparc/lib/crc32_glue.c                   |  93 +++++
 arch/sparc/{crypto => lib}/crc32c_asm.S       |   2 +-
 arch/x86/Kconfig                              |   1 +
 arch/x86/crypto/Kconfig                       |  22 --
 arch/x86/crypto/Makefile                      |   7 -
 arch/x86/crypto/crc32-pclmul_glue.c           | 202 ----------
 arch/x86/crypto/crc32c-intel_glue.c           | 250 -------------
 arch/x86/lib/Makefile                         |   4 +
 arch/x86/lib/crc32-glue.c                     | 124 ++++++
 .../crc32-pclmul_asm.S => lib/crc32-pclmul.S} |  19 +-
 .../crc32c-3way.S}                            |  63 ++--
 crypto/crc32_generic.c                        |   8 +-
 crypto/crc32c_generic.c                       |  12 +-
 drivers/target/iscsi/Kconfig                  |   4 +-
 drivers/target/iscsi/iscsi_target.c           | 153 +++-----
 drivers/target/iscsi/iscsi_target_login.c     |  50 ---
 drivers/target/iscsi/iscsi_target_login.h     |   1 -
 drivers/target/iscsi/iscsi_target_nego.c      |  21 +-
 fs/bcachefs/Kconfig                           |   1 +
 fs/ext4/Kconfig                               |   3 +-
 fs/ext4/ext4.h                                |  25 +-
 fs/ext4/super.c                               |  15 -
 fs/f2fs/Kconfig                               |   3 +-
 fs/f2fs/f2fs.h                                |  20 +-
 fs/f2fs/super.c                               |  15 -
 fs/jbd2/Kconfig                               |   2 -
 fs/jbd2/journal.c                             |  30 +-
 include/linux/crc32.h                         |  50 ++-
 include/linux/crc32c.h                        |   7 +-
 include/linux/jbd2.h                          |  33 +-
 include/target/iscsi/iscsi_target_core.h      |   3 -
 lib/Kconfig                                   |  80 ++--
 lib/Makefile                                  |   1 -
 lib/crc32.c                                   |  24 +-
 lib/libcrc32c.c                               |  74 ----
 94 files changed, 1159 insertions(+), 2646 deletions(-)
 delete mode 100644 arch/arm/crypto/crc32-ce-glue.c
 rename arch/arm/{crypto/crc32-ce-core.S => lib/crc32-core.S} (98%)
 create mode 100644 arch/arm/lib/crc32-glue.c
 delete mode 100644 arch/loongarch/crypto/crc32-loongarch.c
 create mode 100644 arch/loongarch/lib/crc32-loongarch.c
 delete mode 100644 arch/mips/crypto/crc32-mips.c
 create mode 100644 arch/mips/lib/crc32-mips.c
 delete mode 100644 arch/powerpc/crypto/crc32c-vpmsum_glue.c
 create mode 100644 arch/powerpc/lib/crc32-glue.c
 rename arch/powerpc/{crypto => lib}/crc32-vpmsum_core.S (100%)
 rename arch/powerpc/{crypto => lib}/crc32c-vpmsum_asm.S (100%)
 rename arch/riscv/lib/{crc32.c => crc32-riscv.c} (91%)
 delete mode 100644 arch/s390/crypto/crc32-vx.c
 create mode 100644 arch/s390/lib/crc32-glue.c
 rename arch/s390/{crypto => lib}/crc32-vx.h (100%)
 rename arch/s390/{crypto => lib}/crc32be-vx.c (100%)
 rename arch/s390/{crypto => lib}/crc32le-vx.c (100%)
 delete mode 100644 arch/sparc/crypto/crc32c_glue.c
 create mode 100644 arch/sparc/lib/crc32_glue.c
 rename arch/sparc/{crypto => lib}/crc32c_asm.S (92%)
 delete mode 100644 arch/x86/crypto/crc32-pclmul_glue.c
 delete mode 100644 arch/x86/crypto/crc32c-intel_glue.c
 create mode 100644 arch/x86/lib/crc32-glue.c
 rename arch/x86/{crypto/crc32-pclmul_asm.S => lib/crc32-pclmul.S} (95%)
 rename arch/x86/{crypto/crc32c-pcl-intel-asm_64.S => lib/crc32c-3way.S} (92%)
 delete mode 100644 lib/libcrc32c.c


base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:08:28 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:08:28 -0800
Subject: [PATCH v4 03/19] lib/crc32: expose whether the lib is really optimized at runtime
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241202010844.144356-4-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Make the CRC32 library export a function crc32_optimizations() which
returns flags that indicate which CRC32 functions are actually executing
optimized code at runtime.

This will be used to determine whether the crc32[c]-$arch shash
algorithms should be registered in the crypto API.  btrfs could also
start using these flags instead of the hack that it currently uses where
it parses the crypto_shash_driver_name.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm64/lib/crc32-glue.c  | 10 ++++++++++
 arch/riscv/lib/crc32-riscv.c | 10 ++++++++++
 include/linux/crc32.h        | 15 +++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/arch/arm64/lib/crc32-glue.c b/arch/arm64/lib/crc32-glue.c
index d7f6e1cbf0d2..15c4c9db573e 100644
--- a/arch/arm64/lib/crc32-glue.c
+++ b/arch/arm64/lib/crc32-glue.c
@@ -83,7 +83,17 @@ u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
 
 	return crc32_be_arm64(crc, p, len);
 }
 EXPORT_SYMBOL(crc32_be_arch);
 
+u32 crc32_optimizations(void)
+{
+	if (alternative_has_cap_likely(ARM64_HAS_CRC32))
+		return CRC32_LE_OPTIMIZATION |
+		       CRC32_BE_OPTIMIZATION |
+		       CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("arm64-optimized CRC32 functions");
diff --git a/arch/riscv/lib/crc32-riscv.c b/arch/riscv/lib/crc32-riscv.c
index a3ff7db2a1ce..53d56ab422c7 100644
--- a/arch/riscv/lib/crc32-riscv.c
+++ b/arch/riscv/lib/crc32-riscv.c
@@ -295,7 +295,17 @@ u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
 legacy:
 	return crc32_be_base(crc, p, len);
 }
 EXPORT_SYMBOL(crc32_be_arch);
 
+u32 crc32_optimizations(void)
+{
+	if (riscv_has_extension_likely(RISCV_ISA_EXT_ZBC))
+		return CRC32_LE_OPTIMIZATION |
+		       CRC32_BE_OPTIMIZATION |
+		       CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Accelerated CRC32 implementation with Zbc extension");
diff --git a/include/linux/crc32.h b/include/linux/crc32.h
index 58c632533b08..e9bd40056687 100644
--- a/include/linux/crc32.h
+++ b/include/linux/crc32.h
@@ -35,10 +35,25 @@ static inline u32 __pure __crc32c_le(u32 crc, const u8 *p, size_t len)
 	if (IS_ENABLED(CONFIG_CRC32_ARCH))
 		return crc32c_le_arch(crc, p, len);
 	return crc32c_le_base(crc, p, len);
 }
 
+/*
+ * crc32_optimizations() returns flags that indicate which CRC32 library
+ * functions are using architecture-specific optimizations.  Unlike
+ * IS_ENABLED(CONFIG_CRC32_ARCH) it takes into account the different CRC32
+ * variants and also whether any needed CPU features are available at runtime.
+ */
+#define CRC32_LE_OPTIMIZATION	BIT(0) /* crc32_le() is optimized */
+#define CRC32_BE_OPTIMIZATION	BIT(1) /* crc32_be() is optimized */
+#define CRC32C_OPTIMIZATION	BIT(2) /* __crc32c_le() is optimized */
+#if IS_ENABLED(CONFIG_CRC32_ARCH)
+u32 crc32_optimizations(void);
+#else
+static inline u32 crc32_optimizations(void) { return 0; }
+#endif
+
 /**
  * crc32_le_combine - Combine two crc32 check values into one. For two
  * 		      sequences of bytes, seq1 and seq2 with lengths len1
  * 		      and len2, crc32_le() check values were calculated
  * 		      for each, crc1 and crc2.
-- 
2.47.1



From ebiggers at kernel.org  Sun Dec  1 17:20:52 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  1 Dec 2024 17:20:52 -0800
Subject: [PATCH v2 08/12] lib/crc_kunit.c: add KUnit test suite for CRC library functions
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241202012056.209768-9-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Add a KUnit test suite for the crc16, crc_t10dif, crc32_le, crc32_be,
crc32c, and crc64_be library functions.  It avoids code duplication by
sharing most logic among all CRC variants.  The test suite includes:

- Differential fuzz test of each CRC function against a simple
  bit-at-a-time reference implementation.
- Test for CRC combination, when implemented by a CRC variant.
- Optional benchmark of each CRC function with various data lengths.

This is intended as a replacement for crc32test and crc16_kunit, as well
as a new test for CRC variants which didn't previously have a test.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
Cc: Vinicius Peixoto <vpeixoto at lkcamp.dev>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 lib/Kconfig.debug |  20 +++
 lib/Makefile      |   1 +
 lib/crc_kunit.c   | 435 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 456 insertions(+)
 create mode 100644 lib/crc_kunit.c

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index f3d723705879..d9b89dd3f6a0 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2836,10 +2836,30 @@ config HW_BREAKPOINT_KUNIT_TEST
 	help
 	  Tests for hw_breakpoint constraints accounting.
 
 	  If unsure, say N.
 
+config CRC_KUNIT_TEST
+	tristate "KUnit tests for CRC functions" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	select CRC16
+	select CRC_T10DIF
+	select CRC32
+	select CRC64
+	help
+	  Unit tests for the CRC library functions.
+
+	  This is intended to help people writing architecture-specific
+	  optimized versions.  If unsure, say N.
+
+config CRC_BENCHMARK
+	bool "Benchmark for the CRC functions"
+	depends on CRC_KUNIT_TEST
+	help
+	  Include benchmarks in the KUnit test suite for the CRC functions.
+
 config SIPHASH_KUNIT_TEST
 	tristate "Perform selftest on siphash functions" if !KUNIT_ALL_TESTS
 	depends on KUNIT
 	default KUNIT_ALL_TESTS
 	help
diff --git a/lib/Makefile b/lib/Makefile
index 6573163d24e4..ccd803d03e58 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -389,10 +389,11 @@ obj-$(CONFIG_STACKINIT_KUNIT_TEST) += stackinit_kunit.o
 CFLAGS_fortify_kunit.o += $(call cc-disable-warning, unsequenced)
 CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-overread)
 CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-truncation)
 CFLAGS_fortify_kunit.o += $(DISABLE_STRUCTLEAK_PLUGIN)
 obj-$(CONFIG_FORTIFY_KUNIT_TEST) += fortify_kunit.o
+obj-$(CONFIG_CRC_KUNIT_TEST) += crc_kunit.o
 obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o
 obj-$(CONFIG_USERCOPY_KUNIT_TEST) += usercopy_kunit.o
 obj-$(CONFIG_CRC16_KUNIT_TEST) += crc16_kunit.o
 
 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
diff --git a/lib/crc_kunit.c b/lib/crc_kunit.c
new file mode 100644
index 000000000000..6a61d4b5fd45
--- /dev/null
+++ b/lib/crc_kunit.c
@@ -0,0 +1,435 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Unit tests and benchmarks for the CRC library functions
+ *
+ * Copyright 2024 Google LLC
+ *
+ * Author: Eric Biggers <ebiggers at google.com>
+ */
+#include <kunit/test.h>
+#include <linux/crc16.h>
+#include <linux/crc-t10dif.h>
+#include <linux/crc32.h>
+#include <linux/crc32c.h>
+#include <linux/crc64.h>
+#include <linux/prandom.h>
+#include <linux/vmalloc.h>
+
+#define CRC_KUNIT_SEED			42
+#define CRC_KUNIT_MAX_LEN		16384
+#define CRC_KUNIT_NUM_TEST_ITERS	1000
+
+static struct rnd_state rng;
+static u8 *test_buffer;
+static size_t test_buflen;
+
+/**
+ * struct crc_variant - describes a CRC variant
+ * @bits: Number of bits in the CRC, 1 <= @bits <= 64.
+ * @le: true if it's a "little endian" CRC (reversed mapping between bits and
+ *	polynomial coefficients in each byte), false if it's a "big endian" CRC
+ *	(natural mapping between bits and polynomial coefficients in each byte)
+ * @poly: The generator polynomial with the highest-order term omitted.
+ *	  Bit-reversed if @le is true.
+ * @func: The function to compute a CRC.  The type signature uses u64 so that it
+ *	  can fit any CRC up to CRC-64.
+ * @combine_func: Optional function to combine two CRCs.
+ */
+struct crc_variant {
+	int bits;
+	bool le;
+	u64 poly;
+	u64 (*func)(u64 crc, const u8 *p, size_t len);
+	u64 (*combine_func)(u64 crc1, u64 crc2, size_t len2);
+};
+
+static u32 rand32(void)
+{
+	return prandom_u32_state(&rng);
+}
+
+static u64 rand64(void)
+{
+	u32 n = rand32();
+
+	return ((u64)n << 32) | rand32();
+}
+
+static u64 crc_mask(const struct crc_variant *v)
+{
+	return (u64)-1 >> (64 - v->bits);
+}
+
+/* Reference implementation of any CRC variant */
+static u64 crc_ref(const struct crc_variant *v,
+		   u64 crc, const u8 *p, size_t len)
+{
+	size_t i, j;
+
+	for (i = 0; i < len; i++) {
+		for (j = 0; j < 8; j++) {
+			if (v->le) {
+				crc ^= (p[i] >> j) & 1;
+				crc = (crc >> 1) ^ ((crc & 1) ? v->poly : 0);
+			} else {
+				crc ^= (u64)((p[i] >> (7 - j)) & 1) <<
+				       (v->bits - 1);
+				if (crc & (1ULL << (v->bits - 1)))
+					crc = ((crc << 1) ^ v->poly) &
+					      crc_mask(v);
+				else
+					crc <<= 1;
+			}
+		}
+	}
+	return crc;
+}
+
+static int crc_suite_init(struct kunit_suite *suite)
+{
+	/*
+	 * Allocate the test buffer using vmalloc() with a page-aligned length
+	 * so that it is immediately followed by a guard page.  This allows
+	 * buffer overreads to be detected, even in assembly code.
+	 */
+	test_buflen = round_up(CRC_KUNIT_MAX_LEN, PAGE_SIZE);
+	test_buffer = vmalloc(test_buflen);
+	if (!test_buffer)
+		return -ENOMEM;
+
+	prandom_seed_state(&rng, CRC_KUNIT_SEED);
+	prandom_bytes_state(&rng, test_buffer, test_buflen);
+	return 0;
+}
+
+static void crc_suite_exit(struct kunit_suite *suite)
+{
+	vfree(test_buffer);
+	test_buffer = NULL;
+}
+
+/* Generate a random initial CRC. */
+static u64 generate_random_initial_crc(const struct crc_variant *v)
+{
+	switch (rand32() % 4) {
+	case 0:
+		return 0;
+	case 1:
+		return crc_mask(v); /* All 1 bits */
+	default:
+		return rand64() & crc_mask(v);
+	}
+}
+
+/* Generate a random length, preferring small lengths. */
+static size_t generate_random_length(size_t max_length)
+{
+	size_t len;
+
+	switch (rand32() % 3) {
+	case 0:
+		len = rand32() % 128;
+		break;
+	case 1:
+		len = rand32() % 3072;
+		break;
+	default:
+		len = rand32();
+		break;
+	}
+	return len % (max_length + 1);
+}
+
+/* Test that v->func gives the same CRCs as a reference implementation. */
+static void crc_main_test(struct kunit *test, const struct crc_variant *v)
+{
+	size_t i;
+
+	for (i = 0; i < CRC_KUNIT_NUM_TEST_ITERS; i++) {
+		u64 init_crc, expected_crc, actual_crc;
+		size_t len, offset;
+		bool nosimd;
+
+		init_crc = generate_random_initial_crc(v);
+		len = generate_random_length(CRC_KUNIT_MAX_LEN);
+
+		/* Generate a random offset. */
+		if (rand32() % 2 == 0) {
+			/* Use a random alignment mod 64 */
+			offset = rand32() % 64;
+			offset = min(offset, CRC_KUNIT_MAX_LEN - len);
+		} else {
+			/* Go up to the guard page, to catch buffer overreads */
+			offset = test_buflen - len;
+		}
+
+		if (rand32() % 8 == 0)
+			/* Refresh the data occasionally. */
+			prandom_bytes_state(&rng, &test_buffer[offset], len);
+
+		nosimd = rand32() % 8 == 0;
+
+		/*
+		 * Compute the CRC, and verify that it equals the CRC computed
+		 * by a simple bit-at-a-time reference implementation.
+		 */
+		expected_crc = crc_ref(v, init_crc, &test_buffer[offset], len);
+		if (nosimd)
+			local_irq_disable();
+		actual_crc = v->func(init_crc, &test_buffer[offset], len);
+		if (nosimd)
+			local_irq_enable();
+		KUNIT_EXPECT_EQ_MSG(test, expected_crc, actual_crc,
+				    "Wrong result with len=%zu offset=%zu nosimd=%d",
+				    len, offset, nosimd);
+	}
+}
+
+/* Test that CRC(concat(A, B)) == combine_CRCs(CRC(A), CRC(B), len(B)). */
+static void crc_combine_test(struct kunit *test, const struct crc_variant *v)
+{
+	int i;
+
+	for (i = 0; i < 100; i++) {
+		u64 init_crc = generate_random_initial_crc(v);
+		size_t len1 = generate_random_length(CRC_KUNIT_MAX_LEN);
+		size_t len2 = generate_random_length(CRC_KUNIT_MAX_LEN - len1);
+		u64 crc1, crc2, expected_crc, actual_crc;
+
+		prandom_bytes_state(&rng, test_buffer, len1 + len2);
+		crc1 = v->func(init_crc, test_buffer, len1);
+		crc2 = v->func(0, &test_buffer[len1], len2);
+		expected_crc = v->func(init_crc, test_buffer, len1 + len2);
+		actual_crc = v->combine_func(crc1, crc2, len2);
+		KUNIT_EXPECT_EQ_MSG(test, expected_crc, actual_crc,
+				    "CRC combination gave wrong result with len1=%zu len2=%zu\n",
+				    len1, len2);
+	}
+}
+
+static void crc_test(struct kunit *test, const struct crc_variant *v)
+{
+	crc_main_test(test, v);
+	if (v->combine_func)
+		crc_combine_test(test, v);
+}
+
+static __always_inline void
+crc_benchmark(struct kunit *test,
+	      u64 (*crc_func)(u64 crc, const u8 *p, size_t len))
+{
+	static const size_t lens_to_test[] = {
+		1, 16, 64, 127, 128, 200, 256, 511, 512, 1024, 3173, 4096, 16384,
+	};
+	size_t len, i, j, num_iters;
+	/*
+	 * Some of the CRC library functions are marked as __pure, so use
+	 * volatile to ensure that all calls are really made as intended.
+	 */
+	volatile u64 crc = 0;
+	u64 t;
+
+	if (!IS_ENABLED(CONFIG_CRC_BENCHMARK))
+		kunit_skip(test, "not enabled");
+
+	/* warm-up */
+	for (i = 0; i < 10000000; i += CRC_KUNIT_MAX_LEN)
+		crc = crc_func(crc, test_buffer, CRC_KUNIT_MAX_LEN);
+
+	for (i = 0; i < ARRAY_SIZE(lens_to_test); i++) {
+		len = lens_to_test[i];
+		KUNIT_ASSERT_LE(test, len, CRC_KUNIT_MAX_LEN);
+		num_iters = 10000000 / (len + 128);
+		preempt_disable();
+		t = ktime_get_ns();
+		for (j = 0; j < num_iters; j++)
+			crc = crc_func(crc, test_buffer, len);
+		t = ktime_get_ns() - t;
+		preempt_enable();
+		kunit_info(test, "len=%zu: %llu MB/s\n",
+			   len, div64_u64((u64)len * num_iters * 1000, t));
+	}
+}
+
+/* crc16 */
+
+static u64 crc16_wrapper(u64 crc, const u8 *p, size_t len)
+{
+	return crc16(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc16 = {
+	.bits = 16,
+	.le = true,
+	.poly = 0xa001,
+	.func = crc16_wrapper,
+};
+
+static void crc16_test(struct kunit *test)
+{
+	crc_test(test, &crc_variant_crc16);
+}
+
+static void crc16_benchmark(struct kunit *test)
+{
+	crc_benchmark(test, crc16_wrapper);
+}
+
+/* crc_t10dif */
+
+static u64 crc_t10dif_wrapper(u64 crc, const u8 *p, size_t len)
+{
+	return crc_t10dif_update(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc_t10dif = {
+	.bits = 16,
+	.le = false,
+	.poly = 0x8bb7,
+	.func = crc_t10dif_wrapper,
+};
+
+static void crc_t10dif_test(struct kunit *test)
+{
+	crc_test(test, &crc_variant_crc_t10dif);
+}
+
+static void crc_t10dif_benchmark(struct kunit *test)
+{
+	crc_benchmark(test, crc_t10dif_wrapper);
+}
+
+/* crc32_le */
+
+static u64 crc32_le_wrapper(u64 crc, const u8 *p, size_t len)
+{
+	return crc32_le(crc, p, len);
+}
+
+static u64 crc32_le_combine_wrapper(u64 crc1, u64 crc2, size_t len2)
+{
+	return crc32_le_combine(crc1, crc2, len2);
+}
+
+static const struct crc_variant crc_variant_crc32_le = {
+	.bits = 32,
+	.le = true,
+	.poly = 0xedb88320,
+	.func = crc32_le_wrapper,
+	.combine_func = crc32_le_combine_wrapper,
+};
+
+static void crc32_le_test(struct kunit *test)
+{
+	crc_test(test, &crc_variant_crc32_le);
+}
+
+static void crc32_le_benchmark(struct kunit *test)
+{
+	crc_benchmark(test, crc32_le_wrapper);
+}
+
+/* crc32_be */
+
+static u64 crc32_be_wrapper(u64 crc, const u8 *p, size_t len)
+{
+	return crc32_be(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc32_be = {
+	.bits = 32,
+	.le = false,
+	.poly = 0x04c11db7,
+	.func = crc32_be_wrapper,
+};
+
+static void crc32_be_test(struct kunit *test)
+{
+	crc_test(test, &crc_variant_crc32_be);
+}
+
+static void crc32_be_benchmark(struct kunit *test)
+{
+	crc_benchmark(test, crc32_be_wrapper);
+}
+
+/* crc32c */
+
+static u64 crc32c_wrapper(u64 crc, const u8 *p, size_t len)
+{
+	return crc32c(crc, p, len);
+}
+
+static u64 crc32c_combine_wrapper(u64 crc1, u64 crc2, size_t len2)
+{
+	return __crc32c_le_combine(crc1, crc2, len2);
+}
+
+static const struct crc_variant crc_variant_crc32c = {
+	.bits = 32,
+	.le = true,
+	.poly = 0x82f63b78,
+	.func = crc32c_wrapper,
+	.combine_func = crc32c_combine_wrapper,
+};
+
+static void crc32c_test(struct kunit *test)
+{
+	crc_test(test, &crc_variant_crc32c);
+}
+
+static void crc32c_benchmark(struct kunit *test)
+{
+	crc_benchmark(test, crc32c_wrapper);
+}
+
+/* crc64_be */
+
+static u64 crc64_be_wrapper(u64 crc, const u8 *p, size_t len)
+{
+	return crc64_be(crc, p, len);
+}
+
+static const struct crc_variant crc_variant_crc64_be = {
+	.bits = 64,
+	.le = false,
+	.poly = 0x42f0e1eba9ea3693,
+	.func = crc64_be_wrapper,
+};
+
+static void crc64_be_test(struct kunit *test)
+{
+	crc_test(test, &crc_variant_crc64_be);
+}
+
+static void crc64_be_benchmark(struct kunit *test)
+{
+	crc_benchmark(test, crc64_be_wrapper);
+}
+
+static struct kunit_case crc_test_cases[] = {
+	KUNIT_CASE(crc16_test),
+	KUNIT_CASE(crc16_benchmark),
+	KUNIT_CASE(crc_t10dif_test),
+	KUNIT_CASE(crc_t10dif_benchmark),
+	KUNIT_CASE(crc32_le_test),
+	KUNIT_CASE(crc32_le_benchmark),
+	KUNIT_CASE(crc32_be_test),
+	KUNIT_CASE(crc32_be_benchmark),
+	KUNIT_CASE(crc32c_test),
+	KUNIT_CASE(crc32c_benchmark),
+	KUNIT_CASE(crc64_be_test),
+	KUNIT_CASE(crc64_be_benchmark),
+	{},
+};
+
+static struct kunit_suite crc_test_suite = {
+	.name = "crc",
+	.test_cases = crc_test_cases,
+	.suite_init = crc_suite_init,
+	.suite_exit = crc_suite_exit,
+};
+kunit_test_suite(crc_test_suite);
+
+MODULE_DESCRIPTION("Unit tests and benchmarks for the CRC library functions");
+MODULE_LICENSE("GPL");
-- 
2.47.1



From damon.ding at rock-chips.com  Sun Dec  1 18:03:42 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 2 Dec 2024 10:03:42 +0800
Subject: [PATCH v1 02/10] dt-bindings: display: rockchip: analogix-dp: Add
 support for RK3588
In-Reply-To: <5d4bebf5-7954-4739-9cd4-93d78d337738@kernel.org>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <20241127075157.856029-3-damon.ding@rock-chips.com>
 <5d4bebf5-7954-4739-9cd4-93d78d337738@kernel.org>
Message-ID: <79421ac4-ffb5-4763-8ba7-cb7bd25c1c80@rock-chips.com>

Hi Krzysztof,

On 2024/11/27 18:23, Krzysztof Kozlowski wrote:
> On 27/11/2024 08:51, Damon Ding wrote:
>> Add the compatible "rockchip,rk3588-edp".
> 
> This we see from the diff. Say something about hardware and why it is
> not compatible with existing variants.

In response to your kind suggestion, I will add more details in next 
version, specifically:

Compared with RK3288/RK3399, the HBR2 link rate support is the main
improvement of RK3588 eDP TX controller, and there are also two
independent eDP display interfaces on RK3588 Soc.

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

Best regards,
Damon



From zengheng4 at huawei.com  Sun Dec  1 18:12:49 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Mon, 2 Dec 2024 10:12:49 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v2 0/6] arm_mpam:
 Introduce the Narrow-PARTID feature for MPAM driver
In-Reply-To: <Z0SaMZ00MZ6288v8@e133380.arm.com>
References: <20241119135104.595630-1-zengheng4@huawei.com>
 <Zzyvbx9uubrLNv1C@e133380.arm.com>
 <c5c5de75-151b-e6bd-952e-606326b46e9a@huawei.com>
 <Z0SaMZ00MZ6288v8@e133380.arm.com>
Message-ID: <79fd4520-f974-76f7-f538-0c72dc8acd40@huawei.com>



On 2024/11/25 23:39, Dave Martin wrote:

>> The advantages of doing this are:
>>
>>  ? 1. There is no need to modify or disrupt the existing resctrl layer
>>
>>  ?? interface, ensuring that each control group has same resource
>>
>>  ?? control functionality;
> 
> I don't think this is guaranteed.
> 
> If there is some MSC that does not have PARTID Narrowing support, and
> this MSC has a memory bandwidth control that the MPAM driver exposes
> through resctrl, then there is no way to configure that MSC that
> exhibits the behaviour that the resctrl user expects.
> 
> For a concrete example:
> 
> Suppose that n=8, and the user asks for P1 to be given 30% of system
> memory bandwidth.
> 
> On the affected MSC, P1 maps to eight PARTIDs, each with its own memory
> bandwidth regulation.
> 
> If the work that happens to be in M1_1 dominates P1's bandwith
> requirment, then PARTID_1_1 needs to be given 30% of total memory bandwidth.
> 
> If the work in P1 is evenly spread across M1_1, M1_2 ... M1_m, then
> they would each need to be given 30% / 8 = 3.75% of total memory
> bandwidth so that the total allocated bandwidth is 30%.
> 
> But we don't know how memory bandwidth consumption is distributed among
> M1_1, M2_2 etc., so there is no way to program the memory bandiwdth
> regulation on that MSC that guarantees the expected result of P1
> receiving 30% of the total available bandwidth.
> 
> 
> This means that on some hardware, a choice needs to be made: should the
> MPAM driver hide from resctrl any controls that have this problem, or
> should it disable the use of PARTID Narrowing for providing additional
> monitoring groups.
> 
> My concern is that the correct choice is likely to be use-case-
> dependent.
> 
> Do you have a view on this?

I understand your meaning and concerns, and this is indeed a problem.

 From a software perspective, I think the use cases should be limited. 
For scenarios where mata does not support narrow-partid, I tend to favor
disabling the narrow-partid feature in the driver for such scenarios.

 From a hardware perspective, MSCs, such as L2/L3, are designed with area
considerations in mind and choose to implement the narrow-partid feature.

MATA, on the other hand, is located on a different die and does not have 
similar concerns, often not considering the implementation of the 
narrow-partid feature, which makes this a rather thorny issue.

>>  ? 2. MSCs that support narrow-partid (including intPARTID and reqPARTID)
>>
>>  ?? and MSCs that do not support (only including PARTID) can share the
>>
>>  ?? same PARTID space;
> 
> This seems like it may be problematic on some hardware, as I tried to
> explain above for point 1.
> 
> Note though, if the non-Narrowing MSCs only have bitmap-type controls,
> then sharing the PARTID space is harmless.  This comes about because
> because these controls explicitly allow contention: cache way 0 for
> example is contended between all the work that is allowed by MPAM to
> use this cache way.  Breaking up the work arbitrarily under different
> PARTIDs makes no difference in this case: the amount of work allocated
> to that cache way, and the amount of contention is still the same.
> 

Completely agree. MSCs without the narrow-partid feature, if they only 
have bitmap-type controls, can be compatible with the shared PARTID 
space scheme.

>>
>>  ? 3. On the premise of ensuring the (1) point, the number of control
>>
>>  ?? groups can be maximized, because users can always choose to make a
>>
>>  ?? control group act as a sub-monitoring group under another control
>>
>>  ?? group;
> 
> What do you mean by "control group" here?
> 
> resctrl's group hierarchy is strict: work is distributed across one or
> more control groups at the top level, and the work in each control
> group is further distributed across one or more monitoring groups
> within that control group.
> 
> There is no way to repurpose a resctrl control group is a monitoring
> group under some other control group.
> 
> Or were you referring to something else here?
> 

Apologies for my miscommunication.

What I meant to say is to use the extra PARTIDs of MSC (which do not support
the narrow-partid feature) as an expansion for number of sub-monitoring 
groups.

>>> 2) The resctrl core code uses CLOSIDs and RMIDs to identify control
>>> groups and monitoring groups.  If a particular driver wants to
>>> translate these into other values (reqPARTID, intPARTID, PMG) then it
>>> can do so, but this mapping logic should be encapsulated in the driver.
>>> This should be better for maintainability, since the details of the
>>> remapping will be arch-specific -- and in general not all arches are
>>> going to require it.  With this in mind, I think that changes in the
>>> resctrl core code would be minimal (perhaps no changes at all).
> 
>>  ? Yes, maintaining the interface of the resctrl core code unchanged is,
>> in essence, the (first) important constraint of the current MPAM code.
>> We try the best to keep all resctrl interfaces and ensure the existing
>> functionality of x86 RDT.
>>
>>  ? The only thing that falls short of being ideal (forgive me), is that
>> it introduces the sole new function resctrl_arch_alloc_rmid() into the
>> resctrl code (resctrl_arch_free_rmid() will be optimized away in the next
>> version, and there are no other new functions any more).
>>
>>  ? The resctrl_arch_alloc_rmid() is the result of several restructuring
>> iterations and it is one of the most critical points in the patch series.
> 
> I was concerned about the changes in patch 6 for example, where the new
> function task_belongs_to_ctrl_group() now has to look at more
> information that just rdtgroup->closid, in order to determine which
> control group a task belongs to.  This is precisely what
> resctrl_arch_match_closid() is supposed to do, using just the closid.
> 
> This suggests that the meaning of "closid" in the core code has been
> changed: if closid is the control group identifier, then each control
> group should have exactly one closid value.
> 
> 
> For comparison, you may want to take a look at the top 3 commits of
> this experimental branch:
> 
> https://git.gitlab.arm.com/linux-arm/linux-dm/-/commits/mpam/partid-pmg-remap/v0.2/head/?ref_type=heads
> 
> which attempts to do all the mapping within the MPAM driver instead.
> Note, the approach is a bit over-complicated and I decided that a
> simpler approach is needed.  But it may help to illustrate what I mean
> about keeping all the remapping out of the resctrl core code.
> 
> 

I understand your suggestion. I will consider refactoring the mapping 
relationships between closid/rmid and partid/reqpartid/intpartid/pmg.

In fact, I prepared a simplified version of v2 as v3. But in light of 
your suggestions, I decide to reconstruct the solution. At present, I'm 
not sure if I can completely isolated the mapping within the MPAM driver 
layer only. If my reconstructed version goes smoothly, I will reply ASAP.

>>> 4) If the mapping between reqPARTIDs and (CLOSID,RMID) pairs is static,
>>> is it necessary to track which reqPARTIDs are in use?  Would it be
>>> simpler to treat all n reqPARTIDs as permanently assigned to the
>>> corresponding CLOSID?
>>>
>>> If reqPARTID usage is not tracked, then every control change on MSCs
>>> that do not support PARTID Narrowing would need to be replicated across
>>> all reqPARTIDs corresponding to the affected resctrl control partition.
>>> But control changes are a relatively rare event, so this approach feels
>>> acceptable as a way of keeping the driver complexity down.  It partly
>>> depends on how large the "n" parameter can become.
>>  ? Yes, totally agree. I will try to remove the reqPARTID bitmap and
>> the resctrl_arch_free_rmid(). As mentioned, this will simplify the code
>> logic and reduce changes to the resctrl layer code.
>>
>>  ? Initially, to reduce the number of IPI interrupt, keep this resource
>> tracking until now, and I will prioritize optimization for the next
>> version.
>>  ?(In fact, the initial version of the patch set was dynamically allocated,
>> and during the code restructuring process, it was inevitable to retain
>> some of the original ideas.)
>>
>> Best regards,
>> Zeng Heng
>>
> 
> OK; fair enough.
> 
> This kind of feature could always be re-added later on if it proves to
> be important for performance in real use-cases, but it is probably best
> to keep things as simple as possible initially.
> 

Many thanks as always for your prompt reply and insightful suggestions.

Best Regards,
Zeng Heng



From a0987203069 at gmail.com  Sun Dec  1 18:36:41 2024
From: a0987203069 at gmail.com (Joey Lu)
Date: Mon,  2 Dec 2024 10:36:41 +0800
Subject: [PATCH v4 1/3] dt-bindings: net: nuvoton: Add schema for Nuvoton MA35 family GMAC
In-Reply-To: <20241202023643.75010-1-a0987203069@gmail.com>
References: <20241202023643.75010-1-a0987203069@gmail.com>
Message-ID: <20241202023643.75010-2-a0987203069@gmail.com>

Create initial schema for Nuvoton MA35 family Gigabit MAC.

Signed-off-by: Joey Lu <a0987203069 at gmail.com>
---
 .../bindings/net/nuvoton,ma35d1-dwmac.yaml    | 134 ++++++++++++++++++
 .../devicetree/bindings/net/snps,dwmac.yaml   |   1 +
 2 files changed, 135 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml

diff --git a/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml b/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
new file mode 100644
index 000000000000..e44abaf4da3e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/nuvoton,ma35d1-dwmac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton DWMAC glue layer controller
+
+maintainers:
+  - Joey Lu <yclu4 at nuvoton.com>
+
+description:
+  Nuvoton 10/100/1000Mbps Gigabit Ethernet MAC Controller is based on
+  Synopsys DesignWare MAC (version 3.73a).
+
+allOf:
+  - $ref: snps,dwmac.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - nuvoton,ma35d1-dwmac
+
+  reg:
+    maxItems: 1
+    description:
+      Register range should be one of the GMAC interface.
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: MAC clock
+      - description: PTP clock
+
+  clock-names:
+    items:
+      - const: stmmaceth
+      - const: ptp_ref
+
+  nuvoton,sys:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle to access syscon registers.
+          - description: GMAC interface ID.
+            enum:
+              - 0
+              - 1
+    description:
+      A phandle to the syscon with one argument that configures system registers
+      for MA35D1's two GMACs. The argument specifies the GMAC interface ID.
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    items:
+      - const: stmmaceth
+
+  phy-mode:
+    enum:
+      - rmii
+      - rgmii
+      - rgmii-id
+      - rgmii-txid
+      - rgmii-rxid
+
+  tx-internal-delay-ps:
+    default: 0
+    minimum: 0
+    maximum: 2000
+    description:
+      RGMII TX path delay used only when PHY operates in RGMII mode with
+      internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds.
+      Allowed values are from 0 to 2000.
+
+  rx-internal-delay-ps:
+    default: 0
+    minimum: 0
+    maximum: 2000
+    description:
+      RGMII RX path delay used only when PHY operates in RGMII mode with
+      internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds.
+      Allowed values are from 0 to 2000.
+
+  mdio:
+    $ref: /schemas/net/mdio.yaml#
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - clocks
+  - clock-names
+  - nuvoton,sys
+  - resets
+  - reset-names
+  - phy-mode
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+    #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
+    ethernet at 40120000 {
+        compatible = "nuvoton,ma35d1-dwmac";
+        reg = <0x40120000 0x10000>;
+        interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "macirq";
+        clocks = <&clk EMAC0_GATE>, <&clk EPLL_DIV8>;
+        clock-names = "stmmaceth", "ptp_ref";
+
+        nuvoton,sys = <&sys 0>;
+        resets = <&sys MA35D1_RESET_GMAC0>;
+        reset-names = "stmmaceth";
+
+        phy-mode = "rgmii-id";
+        phy-handle = <&eth_phy0>;
+        mdio {
+            compatible = "snps,dwmac-mdio";
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            ethernet-phy at 0 {
+                reg = <0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index eb1f3ae41ab9..4bf59ab910cc 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -67,6 +67,7 @@ properties:
         - ingenic,x2000-mac
         - loongson,ls2k-dwmac
         - loongson,ls7a-dwmac
+        - nuvoton,ma35d1-dwmac
         - qcom,qcs404-ethqos
         - qcom,sa8775p-ethqos
         - qcom,sc8280xp-ethqos
-- 
2.34.1



From a0987203069 at gmail.com  Sun Dec  1 18:36:42 2024
From: a0987203069 at gmail.com (Joey Lu)
Date: Mon,  2 Dec 2024 10:36:42 +0800
Subject: [PATCH v4 2/3] arm64: dts: nuvoton: Add Ethernet nodes
In-Reply-To: <20241202023643.75010-1-a0987203069@gmail.com>
References: <20241202023643.75010-1-a0987203069@gmail.com>
Message-ID: <20241202023643.75010-3-a0987203069@gmail.com>

Add GMAC nodes for our MA35D1 development boards:
two RGMII interfaces for SOM board, and one RGMII and one RMII
interface for IoT board.

Signed-off-by: Joey Lu <a0987203069 at gmail.com>
---
 .../boot/dts/nuvoton/ma35d1-iot-512m.dts      | 12 +++++
 .../boot/dts/nuvoton/ma35d1-som-256m.dts      | 10 ++++
 arch/arm64/boot/dts/nuvoton/ma35d1.dtsi       | 54 +++++++++++++++++++
 3 files changed, 76 insertions(+)

diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts b/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
index 9482bec1aa57..5cc712ae92d8 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
@@ -18,6 +18,8 @@ aliases {
 		serial12 = &uart12;
 		serial13 = &uart13;
 		serial14 = &uart14;
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
 	};
 
 	chosen {
@@ -126,3 +128,13 @@ &uart14 {
 	pinctrl-0 = <&pinctrl_uart14>;
 	status = "okay";
 };
+
+&gmac0 {
+	phy-mode = "rgmii-id";
+	status = "okay";
+};
+
+&gmac1 {
+	phy-mode = "rmii";
+	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 f6f20a17e501..1d9ac350a1f1 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
@@ -18,6 +18,8 @@ aliases {
 		serial12 = &uart12;
 		serial14 = &uart14;
 		serial16 = &uart16;
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
 	};
 
 	chosen {
@@ -129,3 +131,11 @@ &uart16 {
 	pinctrl-0 = <&pinctrl_uart16>;
 	status = "okay";
 };
+
+&gmac0 {
+	status = "okay";
+};
+
+&gmac1 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
index e51b98f5bdce..89712e262ee6 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
@@ -379,5 +379,59 @@ uart16: serial at 40880000 {
 			clocks = <&clk UART16_GATE>;
 			status = "disabled";
 		};
+
+		gmac0: ethernet at 40120000 {
+			compatible = "nuvoton,ma35d1-dwmac";
+			reg = <0x0 0x40120000 0x0 0x10000>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+			clocks = <&clk EMAC0_GATE>, <&clk EPLL_DIV8>;
+			clock-names = "stmmaceth", "ptp_ref";
+
+			nuvoton,sys = <&sys 0>;
+			resets = <&sys MA35D1_RESET_GMAC0>;
+			reset-names = "stmmaceth";
+
+			phy-mode = "rgmii-id";
+			phy-handle = <&eth_phy0>;
+			status = "disabled";
+
+			mdio0: mdio {
+				compatible = "snps,dwmac-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				eth_phy0: ethernet-phy at 0 {
+					reg = <0>;
+				};
+			};
+		};
+
+		gmac1: ethernet at 40130000 {
+			compatible = "nuvoton,ma35d1-dwmac";
+			reg = <0x0 0x40130000 0x0 0x10000>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+			clocks = <&clk EMAC1_GATE>, <&clk EPLL_DIV8>;
+			clock-names = "stmmaceth", "ptp_ref";
+
+			nuvoton,sys = <&sys 1>;
+			resets = <&sys MA35D1_RESET_GMAC1>;
+			reset-names = "stmmaceth";
+
+			phy-mode = "rgmii-id";
+			phy-handle = <&eth_phy1>;
+			status = "disabled";
+
+			mdio1: mdio {
+				compatible = "snps,dwmac-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				eth_phy1: ethernet-phy at 1 {
+					reg = <1>;
+				};
+			};
+		};
 	};
 };
-- 
2.34.1



From a0987203069 at gmail.com  Sun Dec  1 18:36:40 2024
From: a0987203069 at gmail.com (Joey Lu)
Date: Mon,  2 Dec 2024 10:36:40 +0800
Subject: [PATCH v4 0/3] Add support for Nuvoton MA35D1 GMAC
Message-ID: <20241202023643.75010-1-a0987203069@gmail.com>

This patch series is submitted to add GMAC support for Nuvoton MA35D1
SoC platform. This work involves implementing a GMAC driver glue layer
based on Synopsys DWMAC driver framework to leverage MA35D1's dual GMAC
interface capabilities.

Overview:
  1. Added a GMAC driver glue layer for MA35D1 SoC, providing support for
  the platform's two GMAC interfaces.
  2. Added device tree settings, with specific configurations for our
  development boards:
    a. SOM board: Configured for two RGMII interfaces.
    b. IoT board: Configured with one RGMII and one RMII interface.
  3. Added dt-bindings for the GMAC interfaces.

v4:
  - Update nuvoton,ma35d1-dwmac.yaml
    - Remove unnecessary property 'select'.
    - Remove unnecessary compatible entries and fix items.
    - Specify number of entries for 'reg'.
    - Remove already defined property 'phy-handle'.
    - Update example.
    - Modify the property internal path delay to match the driver.
  - Update dtsi
    - Move 'status' to be the last property.
  - Update dwmac-nuvoton driver
    - Use .remove instead of .remove_new.
    - Use dev_err_probe instead.

v3:
  - Update nuvoton,ma35d1-dwmac.yaml
    - Fix for dt_binding_check warnings/errors.
    - Add compatible in snps,dwmac.yaml.
  - Update dtsi
    - Update dtsi to follow examples in yaml.
  - Update dwmac-nuvoton driver
    - Fix for auto build test warnings.
    - Invalid path delay arguments will be returned.

v2:
  - Update nuvoton,ma35d1-dwmac.yaml
    - Rename file to align with the compatible property.
    - Add an argument to syscon to replace mac-id,
      with corresponding descriptions.
    - Use tx-internal-delay-ps and rx-internal-delay-ps properties for
      configurable path delay with corresponding descriptions,
      allowing selection between GMAC internal and PHY.
    - Add all supported phy-mode options.
    - Remove unused properties.
  - Update dtsi
    - Modify syscon configuration to include an argument for
      GMAC interface selection.
  - Update dwmac-nuvoton driver
    - Remove redundant device information print statements.
    - Remove non-global parameters.
    - Retrieve GMAC interface selection from the syscon argument.
    - Parse Tx and Rx path delays by correct properties.
    - Update configurations to support Wake-on-LAN.

Joey Lu (3):
  dt-bindings: net: nuvoton: Add schema for Nuvoton MA35 family GMAC
  arm64: dts: nuvoton: Add Ethernet nodes
  net: stmmac: dwmac-nuvoton: Add dwmac glue for Nuvoton MA35 family

 .../bindings/net/nuvoton,ma35d1-dwmac.yaml    | 134 +++++++++++++
 .../devicetree/bindings/net/snps,dwmac.yaml   |   1 +
 .../boot/dts/nuvoton/ma35d1-iot-512m.dts      |  12 ++
 .../boot/dts/nuvoton/ma35d1-som-256m.dts      |  10 +
 arch/arm64/boot/dts/nuvoton/ma35d1.dtsi       |  54 ++++++
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../ethernet/stmicro/stmmac/dwmac-nuvoton.c   | 179 ++++++++++++++++++
 8 files changed, 402 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c

-- 
2.34.1



From a0987203069 at gmail.com  Sun Dec  1 18:36:43 2024
From: a0987203069 at gmail.com (Joey Lu)
Date: Mon,  2 Dec 2024 10:36:43 +0800
Subject: [PATCH v4 3/3] net: stmmac: dwmac-nuvoton: Add dwmac glue for Nuvoton MA35 family
In-Reply-To: <20241202023643.75010-1-a0987203069@gmail.com>
References: <20241202023643.75010-1-a0987203069@gmail.com>
Message-ID: <20241202023643.75010-4-a0987203069@gmail.com>

Add support for Gigabit Ethernet on Nuvoton MA35 series using dwmac driver.

Signed-off-by: Joey Lu <a0987203069 at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../ethernet/stmicro/stmmac/dwmac-nuvoton.c   | 179 ++++++++++++++++++
 3 files changed, 191 insertions(+)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 6658536a4e17..c8cbc0ec1311 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -121,6 +121,17 @@ config DWMAC_MESON
 	  the stmmac device driver. This driver is used for Meson6,
 	  Meson8, Meson8b and GXBB SoCs.
 
+config DWMAC_NUVOTON
+	tristate "Nuvoton MA35 dwmac support"
+	default ARCH_MA35
+	depends on OF && (ARCH_MA35 || COMPILE_TEST)
+	select MFD_SYSCON
+	help
+	  Support for Ethernet controller on Nuvoton MA35 series SoC.
+
+	  This selects the Nuvoton MA35 series SoC glue layer support
+	  for the stmmac device driver.
+
 config DWMAC_QCOM_ETHQOS
 	tristate "Qualcomm ETHQOS support"
 	default ARCH_QCOM
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 2389fd261344..9812b824459f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_DWMAC_IPQ806X)	+= dwmac-ipq806x.o
 obj-$(CONFIG_DWMAC_LPC18XX)	+= dwmac-lpc18xx.o
 obj-$(CONFIG_DWMAC_MEDIATEK)	+= dwmac-mediatek.o
 obj-$(CONFIG_DWMAC_MESON)	+= dwmac-meson.o dwmac-meson8b.o
+obj-$(CONFIG_DWMAC_NUVOTON)	+= dwmac-nuvoton.o
 obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-ethqos.o
 obj-$(CONFIG_DWMAC_ROCKCHIP)	+= dwmac-rk.o
 obj-$(CONFIG_DWMAC_RZN1)	+= dwmac-rzn1.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c
new file mode 100644
index 000000000000..eed852cb13ab
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Nuvoton DWMAC specific glue layer
+ *
+ * Copyright (C) 2024 Nuvoton Technology Corp.
+ *
+ * Author: Joey Lu <yclu4 at nuvoton.com>
+ */
+
+#include <linux/mfd/syscon.h>
+#include <linux/of_device.h>
+#include <linux/of_net.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/stmmac.h>
+
+#include "stmmac.h"
+#include "stmmac_platform.h"
+
+#define REG_SYS_GMAC0MISCR  0x108
+#define REG_SYS_GMAC1MISCR  0x10C
+
+#define MISCR_RMII          BIT(0)
+
+/* 2000ps is mapped to 0 ~ 0xF */
+#define PATH_DELAY_DEC      134
+#define TX_DELAY_OFFSET     16
+#define TX_DELAY_MASK       GENMASK(19, 16)
+#define RX_DELAY_OFFSET     20
+#define RX_DELAY_MASK       GENMASK(23, 20)
+
+struct nvt_priv_data {
+	struct platform_device *pdev;
+	struct regmap *regmap;
+};
+
+static struct nvt_priv_data *
+nuvoton_gmac_setup(struct platform_device *pdev, struct plat_stmmacenet_data *plat)
+{
+	struct device *dev = &pdev->dev;
+	struct nvt_priv_data *bsp_priv;
+	phy_interface_t phy_mode;
+	u32 tx_delay, rx_delay;
+	u32 macid, arg, reg;
+
+	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
+	if (!bsp_priv)
+		return ERR_PTR(-ENOMEM);
+
+	bsp_priv->regmap =
+		syscon_regmap_lookup_by_phandle_args(dev->of_node, "nuvoton,sys", 1, &macid);
+	if (IS_ERR(bsp_priv->regmap)) {
+		dev_err_probe(dev, PTR_ERR(bsp_priv->regmap), "Failed to get sys register\n");
+		return ERR_PTR(-ENODEV);
+	}
+	if (macid > 1) {
+		dev_err_probe(dev, -EINVAL, "Invalid sys arguments\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dev->of_node, "tx-internal-delay-ps", &arg)) {
+		tx_delay = 0; /* Default value is 0 */
+	} else {
+		if (arg <= 2000) {
+			tx_delay = (arg == 2000) ? 0xF : (arg / PATH_DELAY_DEC);
+			dev_dbg(dev, "Set Tx path delay to 0x%x\n", tx_delay);
+		} else {
+			dev_err(dev, "Invalid Tx path delay argument.\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
+	if (of_property_read_u32(dev->of_node, "rx-internal-delay-ps", &arg)) {
+		rx_delay = 0; /* Default value is 0 */
+	} else {
+		if (arg <= 2000) {
+			rx_delay = (arg == 2000) ? 0xF : (arg / PATH_DELAY_DEC);
+			dev_dbg(dev, "Set Rx path delay to 0x%x\n", rx_delay);
+		} else {
+			dev_err(dev, "Invalid Rx path delay argument.\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
+	regmap_read(bsp_priv->regmap,
+		    macid == 0 ? REG_SYS_GMAC0MISCR : REG_SYS_GMAC1MISCR, &reg);
+	reg &= ~(TX_DELAY_MASK | RX_DELAY_MASK);
+
+	if (of_get_phy_mode(pdev->dev.of_node, &phy_mode)) {
+		dev_err(dev, "missing phy mode property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	switch (phy_mode) {
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		reg &= ~MISCR_RMII;
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		reg |= MISCR_RMII;
+		break;
+	default:
+		dev_err(dev, "Unsupported phy-mode (%d)\n", phy_mode);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (!(reg & MISCR_RMII)) {
+		reg |= tx_delay << TX_DELAY_OFFSET;
+		reg |= rx_delay << RX_DELAY_OFFSET;
+	}
+
+	regmap_write(bsp_priv->regmap,
+		     macid == 0 ? REG_SYS_GMAC0MISCR : REG_SYS_GMAC1MISCR, reg);
+
+	bsp_priv->pdev = pdev;
+
+	return bsp_priv;
+}
+
+static int nuvoton_gmac_probe(struct platform_device *pdev)
+{
+	struct plat_stmmacenet_data *plat_dat;
+	struct stmmac_resources stmmac_res;
+	int ret;
+
+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
+	if (ret)
+		return ret;
+
+	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	if (IS_ERR(plat_dat))
+		return PTR_ERR(plat_dat);
+
+	/* Nuvoton DWMAC configs */
+	plat_dat->has_gmac = 1;
+	plat_dat->tx_fifo_size = 2048;
+	plat_dat->rx_fifo_size = 4096;
+	plat_dat->multicast_filter_bins = 0;
+	plat_dat->unicast_filter_entries = 8;
+	plat_dat->flags &= ~STMMAC_FLAG_USE_PHY_WOL;
+
+	plat_dat->bsp_priv = nuvoton_gmac_setup(pdev, plat_dat);
+	if (IS_ERR(plat_dat->bsp_priv)) {
+		ret = PTR_ERR(plat_dat->bsp_priv);
+		return ret;
+	}
+
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		return ret;
+
+	/* We support WoL by magic packet, override pmt to make it work! */
+	plat_dat->pmt = 1;
+	device_set_wakeup_capable(&pdev->dev, 1);
+
+	return 0;
+}
+
+static const struct of_device_id nuvoton_dwmac_match[] = {
+	{ .compatible = "nuvoton,ma35d1-dwmac"},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, nuvoton_dwmac_match);
+
+static struct platform_driver nuvoton_dwmac_driver = {
+	.probe  = nuvoton_gmac_probe,
+	.remove = stmmac_pltfr_remove,
+	.driver = {
+		.name           = "nuvoton-dwmac",
+		.pm		= &stmmac_pltfr_pm_ops,
+		.of_match_table = nuvoton_dwmac_match,
+	},
+};
+module_platform_driver(nuvoton_dwmac_driver);
+
+MODULE_AUTHOR("Joey Lu <yclu4 at nuvoton.com>");
+MODULE_DESCRIPTION("Nuvoton DWMAC specific glue layer");
+MODULE_LICENSE("GPL v2");
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:16:05 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 2 Dec 2024 10:16:05 +0800
Subject: [PATCH v4 09/19] drm/imx: Add i.MX8qxp Display Controller display
 engine
In-Reply-To: <gyt3z6jisr4cea4wwk32hgzbatbczibppgrv6copcl4qo2chlx@w5kcqulhoe2p>
References: <20241125093316.2357162-1-victor.liu@nxp.com>
 <20241125093316.2357162-10-victor.liu@nxp.com>
 <gyt3z6jisr4cea4wwk32hgzbatbczibppgrv6copcl4qo2chlx@w5kcqulhoe2p>
Message-ID: <73540c67-4d4e-4deb-b5c1-2caac50edf2d@nxp.com>

On 12/01/2024, Uwe Kleine-K?nig wrote:
> Hello,

Hello,

> 
> On Mon, Nov 25, 2024 at 05:33:06PM +0800, Liu Ying wrote:
>> +struct platform_driver dc_de_driver = {
>> +	.probe = dc_de_probe,
>> +	.remove_new = dc_de_remove,
> 
> Please use .remove here. Also in a few other patches of this series.

Will use .remove in next version.  Thanks.

> 
> Best regards
> Uwe
> 
>> +	.driver = {
>> +		.name = "imx8-dc-display-engine",
>> +		.suppress_bind_attrs = true,
>> +		.of_match_table = dc_de_dt_ids,
>> +		.pm = pm_sleep_ptr(&dc_de_pm_ops),
>> +	},
>> +};

-- 
Regards,
Liu Ying



From ck.hu at mediatek.com  Sun Dec  1 18:52:09 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 2 Dec 2024 02:52:09 +0000
Subject: [PATCH v1 6/7] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241120124512.134278-7-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-7-angelogioacchino.delregno@collabora.com>
Message-ID: <0fe707761a3a5a432a191f5afb07df7831e03c22.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +int mtk_hdmi_common_probe(struct platform_device *pdev, struct mtk_hdmi *hdmi)
> +{
> +       const struct mtk_hdmi_ver_conf *ver_conf;
> +       struct device *dev = &pdev->dev;
> +       int ret;
> +
> +       hdmi->dev = dev;
> +       hdmi->conf = of_device_get_match_data(dev);
> +       ver_conf = hdmi->conf->ver_conf;
> +
> +       hdmi->clk = devm_kcalloc(dev, ver_conf->num_clocks, sizeof(*hdmi->clk), GFP_KERNEL);
> +       if (!hdmi->clk)
> +               return -ENOMEM;
> +
> +       hdmi->phy = devm_phy_get(dev, "hdmi");
> +       if (IS_ERR(hdmi->phy))
> +               return dev_err_probe(dev, PTR_ERR(hdmi->phy), "Failed to get HDMI PHY\n");
> +
> +       ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, ver_conf->mtk_hdmi_clock_names,
> +                                     ver_conf->num_clocks);
> +       if (ret)
> +               return ret;
> +
> +       platform_set_drvdata(pdev, hdmi);
> +
> +       ret = mtk_hdmi_register_audio_driver(dev);
> +       if (ret)
> +               return dev_err_probe(dev, ret, "Cannot register HDMI Audio driver\n");

You change the error message here. If this is necessary, separate this to a refinement patch.

> +
> +       hdmi->bridge.funcs = ver_conf->bridge_funcs;
> +       hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
> +       hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
> +       hdmi->bridge.of_node = pdev->dev.of_node;
> +       hdmi->bridge.ddc = hdmi->ddc_adpt;
> +
> +       ret = devm_drm_bridge_add(dev, &hdmi->bridge);

You change drm_bridge_add() to devm_drm_bridge_add(). If this is necessary, separate this to a refinement patch.

Regards,
CK

> +       if (ret)
> +               return dev_err_probe(dev, ret, "Failed to add bridge\n");
> +
> +       return 0;
> +}
> +

From victor.liu at nxp.com  Sun Dec  1 18:56:24 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:24 +0800
Subject: [PATCH v5 08/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-9-victor.liu@nxp.com>

i.MX8qxp Display Controller(DC) is comprised of three main components that
include a blit engine for 2D graphics accelerations, display controller for
display output processing, as well as a command sequencer.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* Document aliases.  Drop Rob's previous R-b tag. (Maxime)

v4:
* Collect Rob's R-b tag.

v3:
* No change.

v2:
* Drop fsl,dc-*-id DT properties from example. (Krzysztof)
* Use generic pmu pattern property. (Krzysztof)

 .../bindings/display/imx/fsl,imx8qxp-dc.yaml  | 240 ++++++++++++++++++
 1 file changed, 240 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
new file mode 100644
index 000000000000..10cc83a7420f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
@@ -0,0 +1,240 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller
+
+description: |
+  The Freescale i.MX8qxp Display Controller(DC) is comprised of three main
+  components that include a blit engine for 2D graphics accelerations, display
+  controller for display output processing, as well as a command sequencer.
+
+                                  Display buffers              Source buffers
+                                 (AXI read master)            (AXI read master)
+                                  | .......... |                  | | |
+      +---------------------------+------------+------------------+-+-+------+
+      | Display Controller (DC)   | .......... |                  | | |      |
+      |                           |            |                  | | |      |
+      |   @@@@@@@@@@@  +----------+------------+------------+     | | |      |
+  A   |  | Command   | |          V            V            |     | | |      |
+  X <-+->| Sequencer | |    @@@@@@@@@@@@@@@@@@@@@@@@@@@@    |     V V V      |
+  I   |  | (AXI CLK) | |   |                            |   |   @@@@@@@@@@   |
+      |   @@@@@@@@@@@  |   |       Pixel Engine         |   |  |          |  |
+      |       |        |   |         (AXI CLK)          |   |  |          |  |
+      |       V        |    @@@@@@@@@@@@@@@@@@@@@@@@@@@@    |  |          |  |
+  A   |   ***********  |       |   |            |   |       |  |   Blit   |  |
+  H <-+->| Configure | |       V   V            V   V       |  |  Engine  |  |
+  B   |  | (CFG CLK) | |    00000000000      11111111111    |  | (AXI CLK)|  |
+      |   ***********  |   |  Display  |    |  Display  |   |  |          |  |
+      |                |   |  Engine   |    |  Engine   |   |  |          |  |
+      |                |   | (Disp CLK)|    | (Disp CLK)|   |  |          |  |
+      |   @@@@@@@@@@@  |    00000000000      11111111111    |   @@@@@@@@@@   |
+  I   |  |  Common   | |         |                |         |       |        |
+  R <-+--|  Control  | |         |    Display     |         |       |        |
+  Q   |  | (AXI CLK) | |         |   Controller   |         |       |        |
+      |   @@@@@@@@@@@  +------------------------------------+       |        |
+      |                          |                |       ^         |        |
+      +--------------------------+----------------+-------+---------+--------+
+              ^                  |                |       |         |
+              |                  V                V       |         V
+       Clocks & Resets        Display          Display  Panic   Destination
+                              Output0          Output1 Control    buffer
+                                                              (AXI write master)
+
+  Each Display Controller device should have an alias in the aliases node, in
+  the form of dc<x>, where <x> is an integer specifying the Display Controller
+  instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: axi
+      - const: cfg
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^command-sequencer@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-command-sequencer
+
+  "^display-engine@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-display-engine
+
+  "^interrupt-controller@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-intc
+
+  "^pixel-engine@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-pixel-engine
+
+  "^pmu@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-axi-performance-counter
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - power-domains
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    display-controller at 56180000 {
+        compatible = "fsl,imx8qxp-dc";
+        reg = <0x56180000 0x40000>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_4>;
+        power-domains = <&pd IMX_SC_R_DC_0>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        interrupt-controller at 56180040 {
+            compatible = "fsl,imx8qxp-dc-intc";
+            reg = <0x56180040 0x60>;
+            clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+            interrupt-controller;
+            interrupt-parent = <&dc0_irqsteer>;
+            #interrupt-cells = <1>;
+            interrupts = <448>, <449>, <450>,  <64>,
+                          <65>,  <66>,  <67>,  <68>,
+                          <69>,  <70>, <193>, <194>,
+                         <195>, <196>, <197>,  <72>,
+                          <73>,  <74>,  <75>,  <76>,
+                          <77>,  <78>,  <79>,  <80>,
+                          <81>, <199>, <200>, <201>,
+                         <202>, <203>, <204>, <205>,
+                         <206>, <207>, <208>,   <5>,
+                           <0>,   <1>,   <2>,   <3>,
+                           <4>,  <82>,  <83>,  <84>,
+                          <85>, <209>, <210>, <211>,
+                         <212>;
+            interrupt-names = "store9_shdload",
+                              "store9_framecomplete",
+                              "store9_seqcomplete",
+                              "extdst0_shdload",
+                              "extdst0_framecomplete",
+                              "extdst0_seqcomplete",
+                              "extdst4_shdload",
+                              "extdst4_framecomplete",
+                              "extdst4_seqcomplete",
+                              "extdst1_shdload",
+                              "extdst1_framecomplete",
+                              "extdst1_seqcomplete",
+                              "extdst5_shdload",
+                              "extdst5_framecomplete",
+                              "extdst5_seqcomplete",
+                              "disengcfg_shdload0",
+                              "disengcfg_framecomplete0",
+                              "disengcfg_seqcomplete0",
+                              "framegen0_int0",
+                              "framegen0_int1",
+                              "framegen0_int2",
+                              "framegen0_int3",
+                              "sig0_shdload",
+                              "sig0_valid",
+                              "sig0_error",
+                              "disengcfg_shdload1",
+                              "disengcfg_framecomplete1",
+                              "disengcfg_seqcomplete1",
+                              "framegen1_int0",
+                              "framegen1_int1",
+                              "framegen1_int2",
+                              "framegen1_int3",
+                              "sig1_shdload",
+                              "sig1_valid",
+                              "sig1_error",
+                              "reserved",
+                              "cmdseq_error",
+                              "comctrl_sw0",
+                              "comctrl_sw1",
+                              "comctrl_sw2",
+                              "comctrl_sw3",
+                              "framegen0_primsync_on",
+                              "framegen0_primsync_off",
+                              "framegen0_secsync_on",
+                              "framegen0_secsync_off",
+                              "framegen1_primsync_on",
+                              "framegen1_primsync_off",
+                              "framegen1_secsync_on",
+                              "framegen1_secsync_off";
+        };
+
+        pixel-engine at 56180800 {
+            compatible = "fsl,imx8qxp-dc-pixel-engine";
+            reg = <0x56180800 0xac00>;
+            clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges;
+        };
+
+        display-engine at 5618b400 {
+            compatible = "fsl,imx8qxp-dc-display-engine";
+            reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
+            reg-names = "top", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <15>, <16>, <17>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+            power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges;
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:25 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:25 +0800
Subject: [PATCH v5 09/19] drm/imx: Add i.MX8qxp Display Controller display engine
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-10-victor.liu@nxp.com>

i.MX8qxp Display Controller display engine consists of all processing
units that operate in a display clock domain.  Add minimal feature
support with FrameGen and TCon so that the engine can output display
timings.  The FrameGen driver, TCon driver and display engine driver
are components to be aggregated by a master registered in the upcoming
DRM driver.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* Replace .remove_new with .remove in dc-{de,fg,tc}.c. (Uwe)
* Select REGMAP and REGMAP_MMIO Kconfig options.
* Fix commit message to state that display engine driver is a component driver
  instead of a master/aggregate driver.

v4:
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Inline some small functions. (Dmitry)
* Move dc_fg_displaymode() and dc_fg_panic_displaymode() function calls from
  KMS routine to initialization stage. (Dmitry)
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
* Drop unnecessary private struct dc_*_priv.
* Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
  interfaces to bind/unbind the drivers.

v3:
* No change.

v2:
* Use OF alias id to get instance id.
* Add dev member to struct dc_tc.

 drivers/gpu/drm/imx/Kconfig     |   1 +
 drivers/gpu/drm/imx/Makefile    |   1 +
 drivers/gpu/drm/imx/dc/Kconfig  |   7 +
 drivers/gpu/drm/imx/dc/Makefile |   5 +
 drivers/gpu/drm/imx/dc/dc-de.c  | 153 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-de.h  |  57 +++++
 drivers/gpu/drm/imx/dc/dc-drv.c |  32 +++
 drivers/gpu/drm/imx/dc/dc-drv.h |  24 ++
 drivers/gpu/drm/imx/dc/dc-fg.c  | 374 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-tc.c  | 138 ++++++++++++
 10 files changed, 792 insertions(+)
 create mode 100644 drivers/gpu/drm/imx/dc/Kconfig
 create mode 100644 drivers/gpu/drm/imx/dc/Makefile
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fg.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-tc.c

diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
index 03535a15dd8f..3e8c6edbc17c 100644
--- a/drivers/gpu/drm/imx/Kconfig
+++ b/drivers/gpu/drm/imx/Kconfig
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
+source "drivers/gpu/drm/imx/dc/Kconfig"
 source "drivers/gpu/drm/imx/dcss/Kconfig"
 source "drivers/gpu/drm/imx/ipuv3/Kconfig"
 source "drivers/gpu/drm/imx/lcdc/Kconfig"
diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index 86f38e7c7422..c7b317640d71 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
+obj-$(CONFIG_DRM_IMX8_DC) += dc/
 obj-$(CONFIG_DRM_IMX_DCSS) += dcss/
 obj-$(CONFIG_DRM_IMX) += ipuv3/
 obj-$(CONFIG_DRM_IMX_LCDC) += lcdc/
diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
new file mode 100644
index 000000000000..e1ef76d82830
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -0,0 +1,7 @@
+config DRM_IMX8_DC
+	tristate "Freescale i.MX8 Display Controller Graphics"
+	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
+	select REGMAP
+	select REGMAP_MMIO
+	help
+	  enable Freescale i.MX8 Display Controller(DC) graphics support
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
new file mode 100644
index 000000000000..56de82d53d4d
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+imx8-dc-drm-objs := dc-de.o dc-drv.o dc-fg.o dc-tc.o
+
+obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-de.c b/drivers/gpu/drm/imx/dc/dc-de.c
new file mode 100644
index 000000000000..24cd37c1e4a8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-de.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+
+#define POLARITYCTRL		0xc
+#define  POLEN_HIGH		BIT(2)
+
+static const struct regmap_range dc_de_regmap_ranges[] = {
+	regmap_reg_range(POLARITYCTRL, POLARITYCTRL),
+};
+
+static const struct regmap_access_table dc_de_regmap_access_table = {
+	.yes_ranges = dc_de_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_de_regmap_ranges),
+};
+
+static const struct regmap_config dc_de_top_regmap_config = {
+	.name = "display-engine-top",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_de_regmap_access_table,
+	.rd_table = &dc_de_regmap_access_table,
+};
+
+static inline void dc_dec_init(struct dc_de *de)
+{
+	regmap_write_bits(de->reg_top, POLARITYCTRL, POLARITYCTRL, POLEN_HIGH);
+}
+
+static int dc_de_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	void __iomem *base_top;
+	struct dc_de *de;
+	int ret;
+
+	de = devm_kzalloc(dev, sizeof(*de), GFP_KERNEL);
+	if (!de)
+		return -ENOMEM;
+
+	base_top = devm_platform_ioremap_resource_byname(pdev, "top");
+	if (IS_ERR(base_top))
+		return PTR_ERR(base_top);
+
+	de->reg_top = devm_regmap_init_mmio(dev, base_top,
+					    &dc_de_top_regmap_config);
+	if (IS_ERR(de->reg_top))
+		return PTR_ERR(de->reg_top);
+
+	de->irq_shdld = platform_get_irq_byname(pdev, "shdload");
+	if (de->irq_shdld < 0)
+		return de->irq_shdld;
+
+	de->irq_framecomplete = platform_get_irq_byname(pdev, "framecomplete");
+	if (de->irq_framecomplete < 0)
+		return de->irq_framecomplete;
+
+	de->irq_seqcomplete = platform_get_irq_byname(pdev, "seqcomplete");
+	if (de->irq_seqcomplete < 0)
+		return de->irq_seqcomplete;
+
+	de->id = of_alias_get_id(dev->of_node, "dc0-display-engine");
+	if (de->id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", de->id);
+		return de->id;
+	}
+
+	de->dev = dev;
+
+	dev_set_drvdata(dev, de);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	dc_drm->de[de->id] = de;
+
+	return 0;
+}
+
+static const struct component_ops dc_de_ops = {
+	.bind = dc_de_bind,
+};
+
+static int dc_de_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = component_add(&pdev->dev, &dc_de_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_de_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_de_ops);
+}
+
+static int dc_de_runtime_resume(struct device *dev)
+{
+	struct dc_de *de = dev_get_drvdata(dev);
+
+	dc_dec_init(de);
+	dc_fg_init(de->fg);
+	dc_tc_init(de->tc);
+
+	return 0;
+}
+
+static const struct dev_pm_ops dc_de_pm_ops = {
+	RUNTIME_PM_OPS(NULL, dc_de_runtime_resume, NULL)
+};
+
+static const struct of_device_id dc_de_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-display-engine", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_de_dt_ids);
+
+struct platform_driver dc_de_driver = {
+	.probe = dc_de_probe,
+	.remove = dc_de_remove,
+	.driver = {
+		.name = "imx8-dc-display-engine",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_de_dt_ids,
+		.pm = pm_sleep_ptr(&dc_de_pm_ops),
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
new file mode 100644
index 000000000000..17a44362118e
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_DISPLAY_ENGINE_H__
+#define __DC_DISPLAY_ENGINE_H__
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <drm/drm_modes.h>
+
+#define DC_DISPLAYS	2
+
+struct dc_fg {
+	struct device *dev;
+	struct regmap *reg;
+	struct clk *clk_disp;
+};
+
+struct dc_tc {
+	struct device *dev;
+	struct regmap *reg;
+};
+
+struct dc_de {
+	struct device *dev;
+	struct regmap *reg_top;
+	struct dc_fg *fg;
+	struct dc_tc *tc;
+	int irq_shdld;
+	int irq_framecomplete;
+	int irq_seqcomplete;
+	int id;
+};
+
+/* Frame Generator Unit */
+void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m);
+void dc_fg_enable(struct dc_fg *fg);
+void dc_fg_disable(struct dc_fg *fg);
+void dc_fg_shdtokgen(struct dc_fg *fg);
+u32 dc_fg_get_frame_index(struct dc_fg *fg);
+u32 dc_fg_get_line_index(struct dc_fg *fg);
+bool dc_fg_wait_for_frame_index_moving(struct dc_fg *fg);
+bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg);
+void dc_fg_secondary_clear_channel_status(struct dc_fg *fg);
+int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg);
+void dc_fg_enable_clock(struct dc_fg *fg);
+void dc_fg_disable_clock(struct dc_fg *fg);
+enum drm_mode_status dc_fg_check_clock(struct dc_fg *fg, int clk_khz);
+void dc_fg_init(struct dc_fg *fg);
+
+/* Timing Controller Unit */
+void dc_tc_init(struct dc_tc *tc);
+
+#endif /* __DC_DISPLAY_ENGINE_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
new file mode 100644
index 000000000000..e5910a82dd4d
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "dc-drv.h"
+
+static struct platform_driver * const dc_drivers[] = {
+	&dc_de_driver,
+	&dc_fg_driver,
+	&dc_tc_driver,
+};
+
+static int __init dc_drm_init(void)
+{
+	return platform_register_drivers(dc_drivers, ARRAY_SIZE(dc_drivers));
+}
+
+static void __exit dc_drm_exit(void)
+{
+	platform_unregister_drivers(dc_drivers, ARRAY_SIZE(dc_drivers));
+}
+
+module_init(dc_drm_init);
+module_exit(dc_drm_exit);
+
+MODULE_DESCRIPTION("i.MX8 Display Controller DRM Driver");
+MODULE_AUTHOR("Liu Ying <victor.liu at nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
new file mode 100644
index 000000000000..e1290d9a0a99
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_DRV_H__
+#define __DC_DRV_H__
+
+#include <linux/platform_device.h>
+
+#include <drm/drm_device.h>
+
+#include "dc-de.h"
+
+struct dc_drm_device {
+	struct drm_device base;
+	struct dc_de *de[DC_DISPLAYS];
+};
+
+extern struct platform_driver dc_de_driver;
+extern struct platform_driver dc_fg_driver;
+extern struct platform_driver dc_tc_driver;
+
+#endif /* __DC_DRV_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
new file mode 100644
index 000000000000..bb51fe6faee0
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fg.c
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/device.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/regmap.h>
+#include <linux/units.h>
+
+#include <drm/drm_modes.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+
+#define FGSTCTRL		0x8
+#define  FGSYNCMODE_MASK	GENMASK(2, 1)
+#define  FGSYNCMODE(x)		FIELD_PREP(FGSYNCMODE_MASK, (x))
+#define  SHDEN			BIT(0)
+
+#define HTCFG1			0xc
+#define  HTOTAL(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  HACT(x)		FIELD_PREP(GENMASK(13, 0), (x))
+
+#define HTCFG2			0x10
+#define  HSEN			BIT(31)
+#define  HSBP(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  HSYNC(x)		FIELD_PREP(GENMASK(13, 0), ((x) - 1))
+
+#define VTCFG1			0x14
+#define  VTOTAL(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  VACT(x)		FIELD_PREP(GENMASK(13, 0), (x))
+
+#define VTCFG2			0x18
+#define  VSEN			BIT(31)
+#define  VSBP(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  VSYNC(x)		FIELD_PREP(GENMASK(13, 0), ((x) - 1))
+
+#define PKICKCONFIG		0x2c
+#define SKICKCONFIG		0x30
+#define  EN			BIT(31)
+#define  ROW(x)			FIELD_PREP(GENMASK(29, 16), (x))
+#define  COL(x)			FIELD_PREP(GENMASK(13, 0), (x))
+
+#define PACFG			0x54
+#define SACFG			0x58
+#define  STARTY(x)		FIELD_PREP(GENMASK(29, 16), ((x) + 1))
+#define  STARTX(x)		FIELD_PREP(GENMASK(13, 0), ((x) + 1))
+
+#define FGINCTRL		0x5c
+#define FGINCTRLPANIC		0x60
+#define  FGDM_MASK		GENMASK(2, 0)
+#define  ENPRIMALPHA		BIT(3)
+#define  ENSECALPHA		BIT(4)
+
+#define FGCCR			0x64
+#define  CCGREEN(x)		FIELD_PREP(GENMASK(19, 10), (x))
+
+#define FGENABLE		0x68
+#define  FGEN			BIT(0)
+
+#define FGSLR			0x6c
+#define  SHDTOKGEN		BIT(0)
+
+#define FGTIMESTAMP		0x74
+#define  FRAMEINDEX(x)		FIELD_GET(GENMASK(31, 14), (x))
+#define  LINEINDEX(x)		FIELD_GET(GENMASK(13, 0), (x))
+
+#define FGCHSTAT		0x78
+#define  SECSYNCSTAT		BIT(24)
+#define  SFIFOEMPTY		BIT(16)
+
+#define FGCHSTATCLR		0x7c
+#define  CLRSECSTAT		BIT(16)
+
+enum dc_fg_syncmode {
+	FG_SYNCMODE_OFF,	/* No side-by-side synchronization. */
+};
+
+enum dc_fg_dm {
+	FG_DM_CONSTCOL = 0x1,	/* Constant Color Background is shown. */
+	FG_DM_SEC_ON_TOP = 0x5,	/* Both inputs overlaid with secondary on top. */
+};
+
+static const struct regmap_range dc_fg_regmap_wr_ranges[] = {
+	regmap_reg_range(FGSTCTRL, VTCFG2),
+	regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
+	regmap_reg_range(PACFG, FGSLR),
+	regmap_reg_range(FGCHSTATCLR, FGCHSTATCLR),
+};
+
+static const struct regmap_range dc_fg_regmap_rd_ranges[] = {
+	regmap_reg_range(FGSTCTRL, VTCFG2),
+	regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
+	regmap_reg_range(PACFG, FGSLR),
+	regmap_reg_range(FGTIMESTAMP, FGCHSTATCLR),
+};
+
+static const struct regmap_access_table dc_fg_regmap_wr_table = {
+	.yes_ranges = dc_fg_regmap_wr_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_wr_ranges),
+};
+
+static const struct regmap_access_table dc_fg_regmap_rd_table = {
+	.yes_ranges = dc_fg_regmap_rd_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_rd_ranges),
+};
+
+static const struct regmap_config dc_fg_regmap_config = {
+	.name = "framegen",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fg_regmap_wr_table,
+	.rd_table = &dc_fg_regmap_rd_table,
+};
+
+static inline void dc_fg_enable_shden(struct dc_fg *fg)
+{
+	regmap_write_bits(fg->reg, FGSTCTRL, SHDEN, SHDEN);
+}
+
+static inline void dc_fg_syncmode(struct dc_fg *fg, enum dc_fg_syncmode mode)
+{
+	regmap_write_bits(fg->reg, FGSTCTRL, FGSYNCMODE_MASK, FGSYNCMODE(mode));
+}
+
+void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
+{
+	u32 hact, htotal, hsync, hsbp;
+	u32 vact, vtotal, vsync, vsbp;
+	u32 kick_row, kick_col;
+	int ret;
+
+	hact = m->crtc_hdisplay;
+	htotal = m->crtc_htotal;
+	hsync = m->crtc_hsync_end - m->crtc_hsync_start;
+	hsbp = m->crtc_htotal - m->crtc_hsync_start;
+
+	vact = m->crtc_vdisplay;
+	vtotal = m->crtc_vtotal;
+	vsync = m->crtc_vsync_end - m->crtc_vsync_start;
+	vsbp = m->crtc_vtotal - m->crtc_vsync_start;
+
+	/* video mode */
+	regmap_write(fg->reg, HTCFG1, HACT(hact)   | HTOTAL(htotal));
+	regmap_write(fg->reg, HTCFG2, HSYNC(hsync) | HSBP(hsbp) | HSEN);
+	regmap_write(fg->reg, VTCFG1, VACT(vact)   | VTOTAL(vtotal));
+	regmap_write(fg->reg, VTCFG2, VSYNC(vsync) | VSBP(vsbp) | VSEN);
+
+	kick_col = hact + 1;
+	kick_row = vact;
+
+	/* pkickconfig */
+	regmap_write(fg->reg, PKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
+
+	/* skikconfig */
+	regmap_write(fg->reg, SKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
+
+	/* primary and secondary area position configuration */
+	regmap_write(fg->reg, PACFG, STARTX(0) | STARTY(0));
+	regmap_write(fg->reg, SACFG, STARTX(0) | STARTY(0));
+
+	/* alpha */
+	regmap_write_bits(fg->reg, FGINCTRL,      ENPRIMALPHA | ENSECALPHA, 0);
+	regmap_write_bits(fg->reg, FGINCTRLPANIC, ENPRIMALPHA | ENSECALPHA, 0);
+
+	/* constant color is green(used in panic mode)  */
+	regmap_write(fg->reg, FGCCR, CCGREEN(0x3ff));
+
+	ret = clk_set_rate(fg->clk_disp, m->clock * HZ_PER_KHZ);
+	if (ret < 0)
+		dev_err(fg->dev, "failed to set display clock rate: %d\n", ret);
+}
+
+static inline void dc_fg_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
+{
+	regmap_write_bits(fg->reg, FGINCTRL, FGDM_MASK, mode);
+}
+
+static inline void dc_fg_panic_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
+{
+	regmap_write_bits(fg->reg, FGINCTRLPANIC, FGDM_MASK, mode);
+}
+
+void dc_fg_enable(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGENABLE, FGEN);
+}
+
+void dc_fg_disable(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGENABLE, 0);
+}
+
+void dc_fg_shdtokgen(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGSLR, SHDTOKGEN);
+}
+
+u32 dc_fg_get_frame_index(struct dc_fg *fg)
+{
+	u32 val;
+
+	regmap_read(fg->reg, FGTIMESTAMP, &val);
+
+	return FRAMEINDEX(val);
+}
+
+u32 dc_fg_get_line_index(struct dc_fg *fg)
+{
+	u32 val;
+
+	regmap_read(fg->reg, FGTIMESTAMP, &val);
+
+	return LINEINDEX(val);
+}
+
+bool dc_fg_wait_for_frame_index_moving(struct dc_fg *fg)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(100);
+	u32 frame_index, last_frame_index;
+
+	frame_index = dc_fg_get_frame_index(fg);
+	do {
+		last_frame_index = frame_index;
+		frame_index = dc_fg_get_frame_index(fg);
+	} while (last_frame_index == frame_index &&
+		 time_before(jiffies, timeout));
+
+	return last_frame_index != frame_index;
+}
+
+bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg)
+{
+	u32 val;
+
+	regmap_read(fg->reg, FGCHSTAT, &val);
+
+	return !!(val & SFIFOEMPTY);
+}
+
+void dc_fg_secondary_clear_channel_status(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGCHSTATCLR, CLRSECSTAT);
+}
+
+int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg)
+{
+	unsigned int val;
+
+	return regmap_read_poll_timeout(fg->reg, FGCHSTAT, val,
+					val & SECSYNCSTAT, 5, 100000);
+}
+
+void dc_fg_enable_clock(struct dc_fg *fg)
+{
+	int ret;
+
+	ret = clk_prepare_enable(fg->clk_disp);
+	if (ret)
+		dev_err(fg->dev, "failed to enable display clock: %d\n", ret);
+}
+
+void dc_fg_disable_clock(struct dc_fg *fg)
+{
+	clk_disable_unprepare(fg->clk_disp);
+}
+
+enum drm_mode_status dc_fg_check_clock(struct dc_fg *fg, int clk_khz)
+{
+	unsigned long rounded_rate;
+
+	rounded_rate = clk_round_rate(fg->clk_disp, clk_khz * HZ_PER_KHZ);
+
+	if (rounded_rate != clk_khz * HZ_PER_KHZ)
+		return MODE_NOCLOCK;
+
+	return MODE_OK;
+}
+
+void dc_fg_init(struct dc_fg *fg)
+{
+	dc_fg_enable_shden(fg);
+	dc_fg_syncmode(fg, FG_SYNCMODE_OFF);
+	dc_fg_displaymode(fg, FG_DM_SEC_ON_TOP);
+	dc_fg_panic_displaymode(fg, FG_DM_CONSTCOL);
+}
+
+static int dc_fg_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	void __iomem *base;
+	struct dc_fg *fg;
+	struct dc_de *de;
+	int id;
+
+	fg = devm_kzalloc(dev, sizeof(*fg), GFP_KERNEL);
+	if (!fg)
+		return -ENOMEM;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	fg->reg = devm_regmap_init_mmio(dev, base, &dc_fg_regmap_config);
+	if (IS_ERR(fg->reg))
+		return PTR_ERR(fg->reg);
+
+	fg->clk_disp = devm_clk_get(dev, NULL);
+	if (IS_ERR(fg->clk_disp))
+		return dev_err_probe(dev, PTR_ERR(fg->clk_disp),
+				     "failed to get display clock\n");
+
+	id = of_alias_get_id(dev->of_node, "dc0-framegen");
+	if (id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", id);
+		return id;
+	}
+
+	fg->dev = dev;
+
+	de = dc_drm->de[id];
+	de->fg = fg;
+
+	return 0;
+}
+
+static const struct component_ops dc_fg_ops = {
+	.bind = dc_fg_bind,
+};
+
+static int dc_fg_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_fg_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_fg_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_fg_ops);
+}
+
+static const struct of_device_id dc_fg_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-framegen", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_fg_dt_ids);
+
+struct platform_driver dc_fg_driver = {
+	.probe = dc_fg_probe,
+	.remove = dc_fg_remove,
+	.driver = {
+		.name = "imx8-dc-framegen",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_fg_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-tc.c b/drivers/gpu/drm/imx/dc/dc-tc.c
new file mode 100644
index 000000000000..66e0efbc90ab
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-tc.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "dc-drv.h"
+#include "dc-de.h"
+
+#define TCON_CTRL	0x410
+#define  CTRL_RST_VAL	0x01401408
+
+/* red: MAPBIT 29-20, green: MAPBIT 19-10, blue: MAPBIT 9-0 */
+#define MAPBIT3_0	0x418
+#define MAPBIT7_4	0x41c
+#define MAPBIT11_8	0x420
+#define MAPBIT15_12	0x424
+#define MAPBIT19_16	0x428
+#define MAPBIT23_20	0x42c
+#define MAPBIT27_24	0x430
+#define MAPBIT31_28	0x434
+
+static const struct regmap_range dc_tc_regmap_ranges[] = {
+	regmap_reg_range(TCON_CTRL, TCON_CTRL),
+	regmap_reg_range(MAPBIT3_0, MAPBIT31_28),
+};
+
+static const struct regmap_access_table dc_tc_regmap_access_table = {
+	.yes_ranges = dc_tc_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_tc_regmap_ranges),
+};
+
+static const struct regmap_config dc_tc_regmap_config = {
+	.name = "tcon",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_tc_regmap_access_table,
+	.rd_table = &dc_tc_regmap_access_table,
+};
+
+/*
+ * The pixels reach TCON are always in 30-bit BGR format.
+ * The first bridge always receives pixels in 30-bit RGB format.
+ * So, map the format to MEDIA_BUS_FMT_RGB101010_1X30.
+ */
+static const u32 dc_tc_mapbit[] = {
+	0x17161514, 0x1b1a1918, 0x0b0a1d1c, 0x0f0e0d0c,
+	0x13121110, 0x03020100, 0x07060504, 0x00000908,
+};
+
+void dc_tc_init(struct dc_tc *tc)
+{
+	/* reset TCON_CTRL to POR default so that TCON works in bypass mode */
+	regmap_write(tc->reg, TCON_CTRL, CTRL_RST_VAL);
+
+	/* set format */
+	regmap_bulk_write(tc->reg, MAPBIT3_0, dc_tc_mapbit,
+			  ARRAY_SIZE(dc_tc_mapbit));
+}
+
+static int dc_tc_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	void __iomem *base;
+	struct dc_tc *tc;
+	struct dc_de *de;
+	int id;
+
+	tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL);
+	if (!tc)
+		return -ENOMEM;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	tc->reg = devm_regmap_init_mmio(dev, base, &dc_tc_regmap_config);
+	if (IS_ERR(tc->reg))
+		return PTR_ERR(tc->reg);
+
+	id = of_alias_get_id(dev->of_node, "dc0-tcon");
+	if (id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", id);
+		return id;
+	}
+
+	de = dc_drm->de[id];
+	de->tc = tc;
+	de->tc->dev = dev;
+
+	return 0;
+}
+
+static const struct component_ops dc_tc_ops = {
+	.bind = dc_tc_bind,
+};
+
+static int dc_tc_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_tc_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_tc_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_tc_ops);
+}
+
+static const struct of_device_id dc_tc_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-tcon", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_tc_dt_ids);
+
+struct platform_driver dc_tc_driver = {
+	.probe = dc_tc_probe,
+	.remove = dc_tc_remove,
+	.driver = {
+		.name = "imx8-dc-tcon",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_tc_dt_ids,
+	},
+};
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:27 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:27 +0800
Subject: [PATCH v5 11/19] drm/imx: Add i.MX8qxp Display Controller interrupt controller
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-12-victor.liu@nxp.com>

i.MX8qxp Display Controller has a built-in interrupt controller to support
Enable/Status/Preset/Clear interrupt bit.  Add driver for it.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* Replace .remove_new with .remove in dc-ic.c. (Uwe)

v4:
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_ic_data data strutures.
* Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
  interfaces to bind/unbind the driver.
* Take DC interrupt controller driver as a standalone driver instead of a
  component driver.
* Replace drmm_kcalloc() with devm_kcalloc() to allocate an array for
  struct dc_ic_entry.
* Call platform_get_irq() from DC interrupt controller driver to make sure
  parent interrupt controller driver is probed first.

v3:
* No change.

v2:
* No change.

 drivers/gpu/drm/imx/dc/Kconfig  |   1 +
 drivers/gpu/drm/imx/dc/Makefile |   2 +-
 drivers/gpu/drm/imx/dc/dc-drv.c |   1 +
 drivers/gpu/drm/imx/dc/dc-drv.h |   1 +
 drivers/gpu/drm/imx/dc/dc-ic.c  | 279 ++++++++++++++++++++++++++++++++
 5 files changed, 283 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ic.c

diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
index e1ef76d82830..1fc84c7475de 100644
--- a/drivers/gpu/drm/imx/dc/Kconfig
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -1,6 +1,7 @@
 config DRM_IMX8_DC
 	tristate "Freescale i.MX8 Display Controller Graphics"
 	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
+	select GENERIC_IRQ_CHIP
 	select REGMAP
 	select REGMAP_MMIO
 	help
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index 2942ae6fd5bd..1ce3e8a8db22 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
 imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
-		    dc-fw.o dc-lb.o dc-pe.o dc-tc.o
+		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
 
 obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index 7c64acc863ad..fd68861f770a 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -15,6 +15,7 @@ static struct platform_driver * const dc_drivers[] = {
 	&dc_fg_driver,
 	&dc_fl_driver,
 	&dc_fw_driver,
+	&dc_ic_driver,
 	&dc_lb_driver,
 	&dc_pe_driver,
 	&dc_tc_driver,
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index c687a36b8153..3b11f4862c6c 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -25,6 +25,7 @@ extern struct platform_driver dc_de_driver;
 extern struct platform_driver dc_fg_driver;
 extern struct platform_driver dc_fl_driver;
 extern struct platform_driver dc_fw_driver;
+extern struct platform_driver dc_ic_driver;
 extern struct platform_driver dc_lb_driver;
 extern struct platform_driver dc_pe_driver;
 extern struct platform_driver dc_tc_driver;
diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
new file mode 100644
index 000000000000..f022f0374772
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-ic.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#define USERINTERRUPTMASK(n)	(0x8 + 4 * (n))
+#define INTERRUPTENABLE(n)	(0x10 + 4 * (n))
+#define INTERRUPTPRESET(n)	(0x18 + 4 * (n))
+#define INTERRUPTCLEAR(n)	(0x20 + 4 * (n))
+#define INTERRUPTSTATUS(n)	(0x28 + 4 * (n))
+#define USERINTERRUPTENABLE(n)	(0x40 + 4 * (n))
+#define USERINTERRUPTPRESET(n)	(0x48 + 4 * (n))
+#define USERINTERRUPTCLEAR(n)	(0x50 + 4 * (n))
+#define USERINTERRUPTSTATUS(n)	(0x58 + 4 * (n))
+
+#define IRQ_COUNT	49
+#define IRQ_RESERVED	35
+#define REG_NUM		2
+
+struct dc_ic_data {
+	struct regmap		*regs;
+	struct clk		*clk_axi;
+	int			irq[IRQ_COUNT];
+	struct irq_domain	*domain;
+};
+
+struct dc_ic_entry {
+	struct dc_ic_data *data;
+	int irq;
+};
+
+static const struct regmap_range dc_ic_regmap_write_ranges[] = {
+	regmap_reg_range(USERINTERRUPTMASK(0), INTERRUPTCLEAR(1)),
+	regmap_reg_range(USERINTERRUPTENABLE(0), USERINTERRUPTCLEAR(1)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_write_table = {
+	.yes_ranges = dc_ic_regmap_write_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_write_ranges),
+};
+
+static const struct regmap_range dc_ic_regmap_read_ranges[] = {
+	regmap_reg_range(USERINTERRUPTMASK(0), USERINTERRUPTSTATUS(1)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_read_table = {
+	.yes_ranges = dc_ic_regmap_read_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_read_ranges),
+};
+
+static const struct regmap_range dc_ic_regmap_volatile_ranges[] = {
+	regmap_reg_range(INTERRUPTPRESET(0), INTERRUPTCLEAR(1)),
+	regmap_reg_range(USERINTERRUPTPRESET(0), USERINTERRUPTCLEAR(1)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_volatile_table = {
+	.yes_ranges = dc_ic_regmap_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_volatile_ranges),
+};
+
+static const struct regmap_config dc_ic_regmap_config = {
+	.name = "interrupt-controller",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_ic_regmap_write_table,
+	.rd_table = &dc_ic_regmap_read_table,
+	.volatile_table = &dc_ic_regmap_volatile_table,
+};
+
+static void dc_ic_irq_handler(struct irq_desc *desc)
+{
+	struct dc_ic_entry *entry = irq_desc_get_handler_data(desc);
+	struct dc_ic_data *data = entry->data;
+	unsigned int status, enable;
+	unsigned int virq;
+
+	chained_irq_enter(irq_desc_get_chip(desc), desc);
+
+	regmap_read(data->regs, USERINTERRUPTSTATUS(entry->irq / 32), &status);
+	regmap_read(data->regs, USERINTERRUPTENABLE(entry->irq / 32), &enable);
+
+	status &= enable;
+
+	if (status & BIT(entry->irq % 32)) {
+		virq = irq_linear_revmap(data->domain, entry->irq);
+		if (virq)
+			generic_handle_irq(virq);
+	}
+
+	chained_irq_exit(irq_desc_get_chip(desc), desc);
+}
+
+static const unsigned long unused_irq[REG_NUM] = {0x00000000, 0xfffe0008};
+
+static int dc_ic_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct irq_chip_generic *gc;
+	struct dc_ic_entry *entry;
+	struct irq_chip_type *ct;
+	struct dc_ic_data *data;
+	void __iomem *base;
+	int i, ret;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	entry = devm_kcalloc(dev, IRQ_COUNT, sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base)) {
+		dev_err(dev, "failed to initialize reg\n");
+		return PTR_ERR(base);
+	}
+
+	data->regs = devm_regmap_init_mmio(dev, base, &dc_ic_regmap_config);
+	if (IS_ERR(data->regs))
+		return PTR_ERR(data->regs);
+
+	data->clk_axi = devm_clk_get(dev, NULL);
+	if (IS_ERR(data->clk_axi))
+		return dev_err_probe(dev, PTR_ERR(data->clk_axi),
+				     "failed to get AXI clock\n");
+
+	for (i = 0; i < IRQ_COUNT; i++) {
+		/* skip the reserved IRQ */
+		if (i == IRQ_RESERVED)
+			continue;
+
+		ret = platform_get_irq(pdev, i);
+		if (ret < 0)
+			return ret;
+	}
+
+	dev_set_drvdata(dev, data);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0) {
+		dev_err(dev, "failed to get runtime PM sync: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < REG_NUM; i++) {
+		/* mask and clear all interrupts */
+		regmap_write(data->regs, USERINTERRUPTENABLE(i), 0x0);
+		regmap_write(data->regs, INTERRUPTENABLE(i), 0x0);
+		regmap_write(data->regs, USERINTERRUPTCLEAR(i), 0xffffffff);
+		regmap_write(data->regs, INTERRUPTCLEAR(i), 0xffffffff);
+
+		/* set all interrupts to user mode */
+		regmap_write(data->regs, USERINTERRUPTMASK(i), 0xffffffff);
+	}
+
+	data->domain = irq_domain_add_linear(dev->of_node, IRQ_COUNT,
+					     &irq_generic_chip_ops, data);
+	if (!data->domain) {
+		dev_err(dev, "failed to create IRQ domain\n");
+		pm_runtime_put(dev);
+		return -ENOMEM;
+	}
+	irq_domain_set_pm_device(data->domain, dev);
+
+	ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, "DC",
+					     handle_level_irq, 0, 0, 0);
+	if (ret) {
+		dev_err(dev, "failed to alloc generic IRQ chips: %d\n", ret);
+		irq_domain_remove(data->domain);
+		pm_runtime_put(dev);
+		return ret;
+	}
+
+	for (i = 0; i < IRQ_COUNT; i += 32) {
+		gc = irq_get_domain_generic_chip(data->domain, i);
+		gc->reg_base = base;
+		gc->unused = unused_irq[i / 32];
+		ct = gc->chip_types;
+		ct->chip.irq_ack = irq_gc_ack_set_bit;
+		ct->chip.irq_mask = irq_gc_mask_clr_bit;
+		ct->chip.irq_unmask = irq_gc_mask_set_bit;
+		ct->regs.ack = USERINTERRUPTCLEAR(i / 32);
+		ct->regs.mask = USERINTERRUPTENABLE(i / 32);
+	}
+
+	for (i = 0; i < IRQ_COUNT; i++) {
+		/* skip the reserved IRQ */
+		if (i == IRQ_RESERVED)
+			continue;
+
+		data->irq[i] = irq_of_parse_and_map(dev->of_node, i);
+
+		entry[i].data = data;
+		entry[i].irq = i;
+
+		irq_set_chained_handler_and_data(data->irq[i],
+						 dc_ic_irq_handler, &entry[i]);
+	}
+
+	return 0;
+}
+
+static void dc_ic_remove(struct platform_device *pdev)
+{
+	struct dc_ic_data *data = dev_get_drvdata(&pdev->dev);
+	int i;
+
+	for (i = 0; i < IRQ_COUNT; i++) {
+		if (i == IRQ_RESERVED)
+			continue;
+
+		irq_set_chained_handler_and_data(data->irq[i], NULL, NULL);
+	}
+
+	irq_domain_remove(data->domain);
+
+	pm_runtime_put_sync(&pdev->dev);
+}
+
+static int dc_ic_runtime_suspend(struct device *dev)
+{
+	struct dc_ic_data *data = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(data->clk_axi);
+
+	return 0;
+}
+
+static int dc_ic_runtime_resume(struct device *dev)
+{
+	struct dc_ic_data *data = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(data->clk_axi);
+	if (ret)
+		dev_err(dev, "failed to enable AXI clock: %d\n", ret);
+
+	return ret;
+}
+
+static const struct dev_pm_ops dc_ic_pm_ops = {
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				      pm_runtime_force_resume)
+	RUNTIME_PM_OPS(dc_ic_runtime_suspend, dc_ic_runtime_resume, NULL)
+};
+
+static const struct of_device_id dc_ic_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-intc", },
+	{ /* sentinel */ }
+};
+
+struct platform_driver dc_ic_driver = {
+	.probe = dc_ic_probe,
+	.remove = dc_ic_remove,
+	.driver = {
+		.name = "imx8-dc-intc",
+		.suppress_bind_attrs = true,
+		.of_match_table	= dc_ic_dt_ids,
+		.pm = pm_sleep_ptr(&dc_ic_pm_ops),
+	},
+};
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:30 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:30 +0800
Subject: [DO NOT MERGE PATCH v5 14/19] dt-bindings: phy: mixel, mipi-dsi-phy: Allow assigned-clock* properties
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-15-victor.liu@nxp.com>

assigned-clock* properties can be used by default now, so allow them.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch as needed by MIPI/LVDS subsystems device tree.

 .../devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml          | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
index 3c28ec50f097..286a4fcc977d 100644
--- a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
@@ -72,11 +72,6 @@ allOf:
           contains:
             const: fsl,imx8qxp-mipi-dphy
     then:
-      properties:
-        assigned-clocks: false
-        assigned-clock-parents: false
-        assigned-clock-rates: false
-
       required:
         - fsl,syscon
 
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:31 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:31 +0800
Subject: [DO NOT MERGE PATCH v5 15/19] dt-bindings: firmware: imx: Add SCU controlled display pixel link nodes
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-16-victor.liu@nxp.com>

Document SCU controlled display pixel link child nodes.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch as needed by display controller subsystem device tree.

 .../devicetree/bindings/firmware/fsl,scu.yaml | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
index 557e524786c2..1a920f013ad2 100644
--- a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
+++ b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
@@ -30,6 +30,26 @@ properties:
       Clock controller node that provides the clocks controlled by the SCU
     $ref: /schemas/clock/fsl,scu-clk.yaml
 
+  dc0-pixel-link0:
+    description:
+      Display pixel link0 in display controller subsystem0 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
+  dc0-pixel-link1:
+    description:
+      Display pixel link1 in display controller subsystem0 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
+  dc1-pixel-link0:
+    description:
+      Display pixel link0 in display controller subsystem1 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
+  dc1-pixel-link1:
+    description:
+      Display pixel link1 in display controller subsystem1 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
   gpio:
     description:
       Control the GPIO PINs on SCU domain over the firmware APIs
-- 
2.34.1



From xueshuai at linux.alibaba.com  Sun Dec  1 19:05:25 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Mon,  2 Dec 2024 11:05:25 +0800
Subject: [PATCH v17 1/3] ACPI: APEI: send SIGBUS to current task if synchronous memory error not recovered
In-Reply-To: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
Message-ID: <20241202030527.20586-2-xueshuai@linux.alibaba.com>

Synchronous error was detected as a result of user-space process accessing
a 2-bit uncorrected error. The CPU will take a synchronous error exception
such as Synchronous External Abort (SEA) on Arm64. The kernel will queue a
memory_failure() work which poisons the related page, unmaps the page, and
then sends a SIGBUS to the process, so that a system wide panic can be
avoided.

However, no memory_failure() work will be queued when abnormal synchronous
errors occur. These errors can include situations such as invalid PA,
unexpected severity, no memory failure config support, invalid GUID
section, etc. In such case, the user-space process will trigger SEA again.
This loop can potentially exceed the platform firmware threshold or even
trigger a kernel hard lockup, leading to a system reboot.

Fix it by performing a force kill if no memory_failure() work is queued
for synchronous errors.

Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Reviewed-by: Yazen Ghannam <yazen.ghannam at amd.com>
---
 drivers/acpi/apei/ghes.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index a2491905f165..106486bdfefc 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -801,6 +801,17 @@ static bool ghes_do_proc(struct ghes *ghes,
 		}
 	}
 
+	/*
+	 * If no memory failure work is queued for abnormal synchronous
+	 * errors, do a force kill.
+	 */
+	if (sync && !queued) {
+		dev_err(ghes->dev,
+			HW_ERR GHES_PFX "%s:%d: synchronous unrecoverable error (SIGBUS)\n",
+			current->comm, task_pid_nr(current));
+		force_sig(SIGBUS);
+	}
+
 	return queued;
 }
 
-- 
2.39.3



From xueshuai at linux.alibaba.com  Sun Dec  1 19:05:24 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Mon,  2 Dec 2024 11:05:24 +0800
Subject: [PATCH v17 0/3] ACPI: APEI: handle synchronous errors in task work
Message-ID: <20241202030527.20586-1-xueshuai@linux.alibaba.com>

changes singce v16:
- add reviewed-by tag for patch 1 and patch 2 from Yazen
- rewrite warning message for force kill (per Yazen)
- warn with dev_err in ghes (per Jarkko)
- add return value -ENXIO in memory_failure comments  (per Yazen)
- Link: https://lore.kernel.org/lkml/20241104015430.98599-1-xueshuai at linux.alibaba.com/

changes singce v15:
- add HW_ERR and GHES_PFX prefix per Yazen 

changes since v14:
- add reviewed-by tags from Jarkko and Jonathan
- remove local variable and use twcb->pfn

changes since v13:
- add reviewed-by tag from Jarkko
- rename task_work to ghes_task_work (per Jarkko)

changes since v12:
- tweak error message for force kill (per Jarkko)
- fix comments style (per Jarkko)
- fix commit log typo (per Jarko)

changes since v11:
- rebase to Linux 6.11-rc6
- fix grammer and typo in commit log (per Borislav)
- remove `sync_` perfix of `sync_task_work`  (per Borislav)
- comments flags and description of `task_work`  (per Borislav)

changes since v10:
- rebase to v6.8-rc2

changes since v9:
- split patch 2 to address exactly one issue in one patch (per Borislav)
- rewrite commit log according to template (per Borislav)
- pickup reviewed-by tag of patch 1 from James Morse
- alloc and free twcb through gen_pool_{alloc, free) (Per James)
- rewrite cover letter

changes since v8:
- remove the bug fix tag of patch 2 (per Jarkko Sakkinen)
- remove the declaration of memory_failure_queue_kick (per Naoya Horiguchi)
- rewrite the return value comments of memory_failure (per Naoya Horiguchi)

changes since v7:
- rebase to Linux v6.6-rc2 (no code changed)
- rewritten the cover letter to explain the motivation of this patchset

changes since v6:
- add more explicty error message suggested by Xiaofei
- pick up reviewed-by tag from Xiaofei
- pick up internal reviewed-by tag from Baolin

changes since v5 by addressing comments from Kefeng:
- document return value of memory_failure()
- drop redundant comments in call site of memory_failure() 
- make ghes_do_proc void and handle abnormal case within it
- pick up reviewed-by tag from Kefeng Wang 

changes since v4 by addressing comments from Xiaofei:
- do a force kill only for abnormal sync errors

changes since v3 by addressing comments from Xiaofei:
- do a force kill for abnormal memory failure error such as invalid PA,
unexpected severity, OOM, etc
- pcik up tested-by tag from Ma Wupeng

changes since v2 by addressing comments from Naoya:
- rename mce_task_work to sync_task_work
- drop ACPI_HEST_NOTIFY_MCE case in is_hest_sync_notify()
- add steps to reproduce this problem in cover letter

changes since v1:
- synchronous events by notify type
- Link: https://lore.kernel.org/lkml/20221206153354.92394-3-xueshuai at linux.alibaba.com/

## Cover Letter

There are two major types of uncorrected recoverable (UCR) errors :

- Synchronous error: The error is detected and raised at the point of the
  consumption in the execution flow, e.g. when a CPU tries to access
  a poisoned cache line. The CPU will take a synchronous error exception
  such as Synchronous External Abort (SEA) on Arm64 and Machine Check
  Exception (MCE) on X86. OS requires to take action (for example, offline
  failure page/kill failure thread) to recover this uncorrectable error.

- Asynchronous error: The error is detected out of processor execution
  context, e.g. when an error is detected by a background scrubber. Some data
  in the memory are corrupted. But the data have not been consumed. OS is
  optional to take action to recover this uncorrectable error.

Currently, both synchronous and asynchronous error use
memory_failure_queue() to schedule memory_failure() exectute in kworker
context. As a result, when a user-space process is accessing a poisoned
data, a data abort is taken and the memory_failure() is executed in the
kworker context:

  - will send wrong si_code by SIGBUS signal in early_kill mode, and
  - can not kill the user-space in some cases resulting a synchronous
    error infinite loop

Issue 1: send wrong si_code in early_kill mode

Since commit a70297d22132 ("ACPI: APEI: set memory failure flags as
MF_ACTION_REQUIRED on synchronous events")', the flag MF_ACTION_REQUIRED
could be used to determine whether a synchronous exception occurs on
ARM64 platform.  When a synchronous exception is detected, the kernel is
expected to terminate the current process which has accessed poisoned
page. This is done by sending a SIGBUS signal with an error code
BUS_MCEERR_AR, indicating an action-required machine check error on
read.

However, when kill_proc() is called to terminate the processes who have
the poisoned page mapped, it sends the incorrect SIGBUS error code
BUS_MCEERR_AO because the context in which it operates is not the one
where the error was triggered.

To reproduce this problem:

  # STEP1: enable early kill mode
  #sysctl -w vm.memory_failure_early_kill=1
  vm.memory_failure_early_kill = 1

  # STEP2: inject an UCE error and consume it to trigger a synchronous error
  #einj_mem_uc single
  0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
  injecting ...
  triggering ...
  signal 7 code 5 addr 0xffffb0d75000
  page not present
  Test passed

The si_code (code 5) from einj_mem_uc indicates that it is BUS_MCEERR_AO
error and it is not fact.

To fix it, queue memory_failure() as a task_work so that it runs in
the context of the process that is actually consuming the poisoned data.

After this patch set:

  # STEP1: enable early kill mode
  #sysctl -w vm.memory_failure_early_kill=1
  vm.memory_failure_early_kill = 1

  # STEP2: inject an UCE error and consume it to trigger a synchronous error
  #einj_mem_uc single
  0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
  injecting ...
  triggering ...
  signal 7 code 4 addr 0xffffb0d75000
  page not present
  Test passed

The si_code (code 4) from einj_mem_uc indicates that it is BUS_MCEERR_AR
error as we expected.

Issue 2: a synchronous error infinite loop due to memory_failure() failed

If a user-space process, e.g. devmem, a poisoned page which has been set
HWPosion flag, kill_accessing_process() is called to send SIGBUS to the
current processs with error info. Because the memory_failure() is
executed in the kworker contex, it will just do nothing but return
EFAULT. So, devmem will access the posioned page and trigger an
excepction again, resulting in a synchronous error infinite loop. Such
loop may cause platform firmware to exceed some threshold and reboot
when Linux could have recovered from this error.

To reproduce this problem:

  # STEP 1: inject an UCE error, and kernel will set HWPosion flag for related page
  #einj_mem_uc single
  0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
  injecting ...
  triggering ...
  signal 7 code 4 addr 0xffffb0d75000
  page not present
  Test passed

  # STEP 2: access the same page and it will trigger a synchronous error infinite loop
  devmem 0x4092d55b400

To fix it, if memory_failure() failed, perform a force kill to current process.

Issue 3: a synchronous error infinite loop due to no memory_failure() queued

No memory_failure() work is queued unless all bellow preconditions check passed:

- `if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))` in ghes_handle_memory_failure()
- `if (flags == -1)` in ghes_handle_memory_failure()
- `if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))` in ghes_do_memory_failure()
- `if (!pfn_valid(pfn) && !arch_is_platform_page(physical_addr)) ` in ghes_do_memory_failure()

If the preconditions are not passed, the user-space process will trigger SEA again.
This loop can potentially exceed the platform firmware threshold or even
trigger a kernel hard lockup, leading to a system reboot.

To fix it, if no memory_failure() queued, perform a force kill to current process.

And the the memory errors triggered in kernel-mode[5], also relies on this
patchset to kill the failure thread.

Lv Ying and XiuQi from Huawei also proposed to address similar problem[2][4].
Acknowledge to discussion with them.

[1] Add ARMv8 RAS virtualization support in QEMU https://patchew.org/QEMU/20200512030609.19593-1-gengdongjiu at huawei.com/
[2] https://lore.kernel.org/lkml/20221205115111.131568-3-lvying6 at huawei.com/
[3] https://lkml.kernel.org/r/20220914064935.7851-1-xueshuai at linux.alibaba.com
[4] https://lore.kernel.org/lkml/20221209095407.383211-1-lvying6 at huawei.com/
[5] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20240528085915.1955987-1-tongtiangen at huawei.com/

Shuai Xue (3):
  ACPI: APEI: send SIGBUS to current task if synchronous memory error
    not recovered
  mm: memory-failure: move return value documentation to function
    declaration
  ACPI: APEI: handle synchronous exceptions in task work

 arch/x86/kernel/cpu/mce/core.c |  7 ---
 drivers/acpi/apei/ghes.c       | 86 +++++++++++++++++++++-------------
 include/acpi/ghes.h            |  3 --
 include/linux/mm.h             |  1 -
 mm/memory-failure.c            | 23 +++------
 5 files changed, 61 insertions(+), 59 deletions(-)

-- 
2.39.3



From xueshuai at linux.alibaba.com  Sun Dec  1 19:05:26 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Mon,  2 Dec 2024 11:05:26 +0800
Subject: [PATCH v17 2/3] mm: memory-failure: move return value documentation to function declaration
In-Reply-To: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
Message-ID: <20241202030527.20586-3-xueshuai@linux.alibaba.com>

Part of return value comments for memory_failure() were originally
documented at the call site. Move those comments to the function
declaration to improve code readability and to provide developers with
immediate access to function usage and return information.

Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Reviewed-by: Yazen Ghannam <yazen.ghannam at amd.com>
---
 arch/x86/kernel/cpu/mce/core.c |  7 -------
 mm/memory-failure.c            | 10 +++++++---
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 7fb5556a0b53..d1dd7f892514 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -1398,13 +1398,6 @@ static void kill_me_maybe(struct callback_head *cb)
 		return;
 	}
 
-	/*
-	 * -EHWPOISON from memory_failure() means that it already sent SIGBUS
-	 * to the current process with the proper error info,
-	 * -EOPNOTSUPP means hwpoison_filter() filtered the error event,
-	 *
-	 * In both cases, no further processing is required.
-	 */
 	if (ret == -EHWPOISON || ret == -EOPNOTSUPP)
 		return;
 
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index a7b8ccd29b6f..14c316d7d38d 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -2211,9 +2211,13 @@ static void kill_procs_now(struct page *p, unsigned long pfn, int flags,
  * Must run in process context (e.g. a work queue) with interrupts
  * enabled and no spinlocks held.
  *
- * Return: 0 for successfully handled the memory error,
- *         -EOPNOTSUPP for hwpoison_filter() filtered the error event,
- *         < 0(except -EOPNOTSUPP) on failure.
+ * Return:
+ *   0             - success,
+ *   -ENXIO        - memory not managed by the kernel
+ *   -EOPNOTSUPP   - hwpoison_filter() filtered the error event,
+ *   -EHWPOISON    - the page was already poisoned, potentially
+ *                   kill process,
+ *   other negative values - failure.
  */
 int memory_failure(unsigned long pfn, int flags)
 {
-- 
2.39.3



From xueshuai at linux.alibaba.com  Sun Dec  1 19:05:27 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Mon,  2 Dec 2024 11:05:27 +0800
Subject: [PATCH v17 3/3] ACPI: APEI: handle synchronous exceptions in task work
In-Reply-To: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
Message-ID: <20241202030527.20586-4-xueshuai@linux.alibaba.com>

The memory uncorrected error could be signaled by asynchronous interrupt
(specifically, SPI in arm64 platform), e.g. when an error is detected by
a background scrubber, or signaled by synchronous exception
(specifically, data abort exception in arm64 platform), e.g. when a CPU
tries to access a poisoned cache line. Currently, both synchronous and
asynchronous error use memory_failure_queue() to schedule
memory_failure() to exectute in a kworker context.

As a result, when a user-space process is accessing a poisoned data, a
data abort is taken and the memory_failure() is executed in the kworker
context, memory_failure():

  - will send wrong si_code by SIGBUS signal in early_kill mode, and
  - can not kill the user-space in some cases resulting a synchronous
    error infinite loop

Issue 1: send wrong si_code in early_kill mode

Since commit a70297d22132 ("ACPI: APEI: set memory failure flags as
MF_ACTION_REQUIRED on synchronous events")', the flag MF_ACTION_REQUIRED
could be used to determine whether a synchronous exception occurs on
ARM64 platform.  When a synchronous exception is detected, the kernel is
expected to terminate the current process which has accessed poisoned
page. This is done by sending a SIGBUS signal with an error code
BUS_MCEERR_AR, indicating an action-required machine check error on
read.

However, when kill_proc() is called to terminate the processes who have
the poisoned page mapped, it sends the incorrect SIGBUS error code
BUS_MCEERR_AO because the context in which it operates is not the one
where the error was triggered.

To reproduce this problem:

  #sysctl -w vm.memory_failure_early_kill=1
  vm.memory_failure_early_kill = 1

  # STEP2: inject an UCE error and consume it to trigger a synchronous error
  #einj_mem_uc single
  0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
  injecting ...
  triggering ...
  signal 7 code 5 addr 0xffffb0d75000
  page not present
  Test passed

The si_code (code 5) from einj_mem_uc indicates that it is BUS_MCEERR_AO
error and it is not the fact.

After this patch:

  # STEP1: enable early kill mode
  #sysctl -w vm.memory_failure_early_kill=1
  vm.memory_failure_early_kill = 1
  # STEP2: inject an UCE error and consume it to trigger a synchronous error
  #einj_mem_uc single
  0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
  injecting ...
  triggering ...
  signal 7 code 4 addr 0xffffb0d75000
  page not present
  Test passed

The si_code (code 4) from einj_mem_uc indicates that it is a BUS_MCEERR_AR
error as we expected.

Issue 2: a synchronous error infinite loop

If a user-space process, e.g. devmem, accesses a poisoned page for which
the HWPoison flag is set, kill_accessing_process() is called to send
SIGBUS to current processs with error info. Because the memory_failure()
is executed in the kworker context, it will just do nothing but return
EFAULT. So, devmem will access the posioned page and trigger an
exception again, resulting in a synchronous error infinite loop. Such
exception loop may cause platform firmware to exceed some threshold and
reboot when Linux could have recovered from this error.

To reproduce this problem:

  # STEP 1: inject an UCE error, and kernel will set HWPosion flag for related page
  #einj_mem_uc single
  0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
  injecting ...
  triggering ...
  signal 7 code 4 addr 0xffffb0d75000
  page not present
  Test passed

  # STEP 2: access the same page and it will trigger a synchronous error infinite loop
  devmem 0x4092d55b400

To fix above two issues, queue memory_failure() as a task_work so that
it runs in the context of the process that is actually consuming the
poisoned data.

Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
Tested-by: Ma Wupeng <mawupeng1 at huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>
Reviewed-by: Xiaofei Tan <tanxiaofei at huawei.com>
Reviewed-by: Baolin Wang <baolin.wang at linux.alibaba.com>
Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
---
 drivers/acpi/apei/ghes.c | 77 +++++++++++++++++++++++-----------------
 include/acpi/ghes.h      |  3 --
 include/linux/mm.h       |  1 -
 mm/memory-failure.c      | 13 -------
 4 files changed, 44 insertions(+), 50 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 106486bdfefc..70f2ee3ad1a8 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -467,28 +467,41 @@ static void ghes_clear_estatus(struct ghes *ghes,
 }
 
 /*
- * Called as task_work before returning to user-space.
- * Ensure any queued work has been done before we return to the context that
- * triggered the notification.
+ * struct ghes_task_work - for synchronous RAS event
+ *
+ * @twork:                callback_head for task work
+ * @pfn:                  page frame number of corrupted page
+ * @flags:                work control flags
+ *
+ * Structure to pass task work to be handled before
+ * returning to user-space via task_work_add().
  */
-static void ghes_kick_task_work(struct callback_head *head)
+struct ghes_task_work {
+	struct callback_head twork;
+	u64 pfn;
+	int flags;
+};
+
+static void memory_failure_cb(struct callback_head *twork)
 {
-	struct acpi_hest_generic_status *estatus;
-	struct ghes_estatus_node *estatus_node;
-	u32 node_len;
+	struct ghes_task_work *twcb = container_of(twork, struct ghes_task_work, twork);
+	int ret;
 
-	estatus_node = container_of(head, struct ghes_estatus_node, task_work);
-	if (IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
-		memory_failure_queue_kick(estatus_node->task_work_cpu);
+	ret = memory_failure(twcb->pfn, twcb->flags);
+	gen_pool_free(ghes_estatus_pool, (unsigned long)twcb, sizeof(*twcb));
 
-	estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
-	node_len = GHES_ESTATUS_NODE_LEN(cper_estatus_len(estatus));
-	gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len);
+	if (!ret || ret == -EHWPOISON || ret == -EOPNOTSUPP)
+		return;
+
+	pr_err("%#llx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",
+			twcb->pfn, current->comm, task_pid_nr(current));
+	force_sig(SIGBUS);
 }
 
 static bool ghes_do_memory_failure(u64 physical_addr, int flags)
 {
 	unsigned long pfn;
+	struct ghes_task_work *twcb;
 
 	if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
 		return false;
@@ -501,6 +514,18 @@ static bool ghes_do_memory_failure(u64 physical_addr, int flags)
 		return false;
 	}
 
+	if (flags == MF_ACTION_REQUIRED && current->mm) {
+		twcb = (void *)gen_pool_alloc(ghes_estatus_pool, sizeof(*twcb));
+		if (!twcb)
+			return false;
+
+		twcb->pfn = pfn;
+		twcb->flags = flags;
+		init_task_work(&twcb->twork, memory_failure_cb);
+		task_work_add(current, &twcb->twork, TWA_RESUME);
+		return true;
+	}
+
 	memory_failure_queue(pfn, flags);
 	return true;
 }
@@ -745,7 +770,7 @@ int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd)
 }
 EXPORT_SYMBOL_NS_GPL(cxl_cper_kfifo_get, CXL);
 
-static bool ghes_do_proc(struct ghes *ghes,
+static void ghes_do_proc(struct ghes *ghes,
 			 const struct acpi_hest_generic_status *estatus)
 {
 	int sev, sec_sev;
@@ -811,8 +836,6 @@ static bool ghes_do_proc(struct ghes *ghes,
 			current->comm, task_pid_nr(current));
 		force_sig(SIGBUS);
 	}
-
-	return queued;
 }
 
 static void __ghes_print_estatus(const char *pfx,
@@ -1114,9 +1137,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
 	struct ghes_estatus_node *estatus_node;
 	struct acpi_hest_generic *generic;
 	struct acpi_hest_generic_status *estatus;
-	bool task_work_pending;
 	u32 len, node_len;
-	int ret;
 
 	llnode = llist_del_all(&ghes_estatus_llist);
 	/*
@@ -1131,25 +1152,16 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
 		estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
 		len = cper_estatus_len(estatus);
 		node_len = GHES_ESTATUS_NODE_LEN(len);
-		task_work_pending = ghes_do_proc(estatus_node->ghes, estatus);
+
+		ghes_do_proc(estatus_node->ghes, estatus);
+
 		if (!ghes_estatus_cached(estatus)) {
 			generic = estatus_node->generic;
 			if (ghes_print_estatus(NULL, generic, estatus))
 				ghes_estatus_cache_add(generic, estatus);
 		}
-
-		if (task_work_pending && current->mm) {
-			estatus_node->task_work.func = ghes_kick_task_work;
-			estatus_node->task_work_cpu = smp_processor_id();
-			ret = task_work_add(current, &estatus_node->task_work,
-					    TWA_RESUME);
-			if (ret)
-				estatus_node->task_work.func = NULL;
-		}
-
-		if (!estatus_node->task_work.func)
-			gen_pool_free(ghes_estatus_pool,
-				      (unsigned long)estatus_node, node_len);
+		gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node,
+			      node_len);
 
 		llnode = next;
 	}
@@ -1210,7 +1222,6 @@ static int ghes_in_nmi_queue_one_entry(struct ghes *ghes,
 
 	estatus_node->ghes = ghes;
 	estatus_node->generic = ghes->generic;
-	estatus_node->task_work.func = NULL;
 	estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
 
 	if (__ghes_read_estatus(estatus, buf_paddr, fixmap_idx, len)) {
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index be1dd4c1a917..ebd21b05fe6e 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -35,9 +35,6 @@ struct ghes_estatus_node {
 	struct llist_node llnode;
 	struct acpi_hest_generic *generic;
 	struct ghes *ghes;
-
-	int task_work_cpu;
-	struct callback_head task_work;
 };
 
 struct ghes_estatus_cache {
diff --git a/include/linux/mm.h b/include/linux/mm.h
index c39c4945946c..aa4246c7c23e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3936,7 +3936,6 @@ enum mf_flags {
 int mf_dax_kill_procs(struct address_space *mapping, pgoff_t index,
 		      unsigned long count, int mf_flags);
 extern int memory_failure(unsigned long pfn, int flags);
-extern void memory_failure_queue_kick(int cpu);
 extern int unpoison_memory(unsigned long pfn);
 extern atomic_long_t num_poisoned_pages __read_mostly;
 extern int soft_offline_page(unsigned long pfn, int flags);
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 14c316d7d38d..e0adb665d07b 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -2499,19 +2499,6 @@ static void memory_failure_work_func(struct work_struct *work)
 	}
 }
 
-/*
- * Process memory_failure work queued on the specified CPU.
- * Used to avoid return-to-userspace racing with the memory_failure workqueue.
- */
-void memory_failure_queue_kick(int cpu)
-{
-	struct memory_failure_cpu *mf_cpu;
-
-	mf_cpu = &per_cpu(memory_failure_cpu, cpu);
-	cancel_work_sync(&mf_cpu->work);
-	memory_failure_work_func(&mf_cpu->work);
-}
-
 static int __init memory_failure_init(void)
 {
 	struct memory_failure_cpu *mf_cpu;
-- 
2.39.3



From xu.yang_2 at nxp.com  Sun Dec  1 18:47:52 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Mon, 2 Dec 2024 10:47:52 +0800
Subject: [PATCH v10 1/3] phy: fsl-imx8mq-usb: add tca function driver for
 imx95
In-Reply-To: <2ae369bc-9cf3-49d8-92dc-ad19ddb48efe@marvell.com>
References: <20241115093312.3407815-1-xu.yang_2@nxp.com>
 <2ae369bc-9cf3-49d8-92dc-ad19ddb48efe@marvell.com>
Message-ID: <20241202024752.bmvjn3lzz2wjkfvp@hippo>

Hi Amit,

On Fri, Nov 29, 2024 at 11:04:33PM +0530, Amit Singh Tomar wrote:
> Hi,
> 
> > The i.MX95 USB3 phy has a Type-C Assist block (TCA). This block consists
> > two functional blocks (XBar assist and VBus assist) and one system
> > access interface using APB.
> > 
> > The primary functionality of XBar assist is:
> >    - switching lane for flip
> >    - moving unused lanes into lower power states.
> > 
> > This info can be get from:
> > i.MX95 RM Chapter 163.3.8 Type-C assist (TCA) block.
> > 
> > This will add support for TCA block to achieve lane switching and tca
> > lower power functionality.
> > 
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > Reviewed-by: Jun Li <jun.li at nxp.com>
> > 
> > ---
> > Changes in v2:
> >    - return the value of imx95_usb_phy_get_tca()
> > Changes in v3:
> >    - no changes
> > Changes in v4:
> >    - remove compatible check for imx95
> >    - check whether tca register region exist or not, yes means has tca,
> >      otherwise skip tca setup
> > Changes in v5:
> >    - no changes
> > Changes in v6:
> >    - no changes
> > Changes in v7:
> >    - fix sparse warnings in imx95_usb_phy_get_tca()
> > Changes in v8:
> >    - #define TCA_INFO 0xFC -> 0xfc
> > Changes in v9:
> >    - no changes
> > Changes in v10:
> >    - no changes
> > ---
> >    drivers/phy/freescale/Kconfig              |   1 +
> >    drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 243 +++++++++++++++++++++
> >    2 files changed, 244 insertions(+)
> > 
> > diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> > index dcd9acff6d01..81f53564ee15 100644
> > --- a/drivers/phy/freescale/Kconfig
> > +++ b/drivers/phy/freescale/Kconfig
> > @@ -5,6 +5,7 @@ if (ARCH_MXC && ARM64) || COMPILE_TEST
> >    config PHY_FSL_IMX8MQ_USB
> >    	tristate "Freescale i.MX8M USB3 PHY"
> >    	depends on OF && HAS_IOMEM
> > +	depends on TYPEC || TYPEC=n
> >    	select GENERIC_PHY
> >    	default ARCH_MXC && ARM64
> > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > index adc6394626ce..f2b2da8cedc3 100644
> > --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
> > @@ -10,6 +10,7 @@
> >    #include <linux/phy/phy.h>
> >    #include <linux/platform_device.h>
> >    #include <linux/regulator/consumer.h>
> > +#include <linux/usb/typec_mux.h>
> >    #define PHY_CTRL0			0x0
> >    #define PHY_CTRL0_REF_SSP_EN		BIT(2)
> > @@ -50,11 +51,66 @@
> >    #define PHY_TUNE_DEFAULT		0xffffffff
> > +#define TCA_CLK_RST			0x00
> > +#define TCA_CLK_RST_SW			BIT(9)
> > +#define TCA_CLK_RST_REF_CLK_EN		BIT(1)
> > +#define TCA_CLK_RST_SUSPEND_CLK_EN	BIT(0)
> > +
> > +#define TCA_INTR_EN			0x04
> > +#define TCA_INTR_STS			0x08
> > +
> > +#define TCA_GCFG			0x10
> > +#define TCA_GCFG_ROLE_HSTDEV		BIT(4)
> > +#define TCA_GCFG_OP_MODE		GENMASK(1, 0)
> > +#define TCA_GCFG_OP_MODE_SYSMODE	0
> > +#define TCA_GCFG_OP_MODE_SYNCMODE	1
> > +
> > +#define TCA_TCPC			0x14
> > +#define TCA_TCPC_VALID			BIT(4)
> > +#define TCA_TCPC_LOW_POWER_EN		BIT(3)
> > +#define TCA_TCPC_ORIENTATION_NORMAL	BIT(2)
> > +#define TCA_TCPC_MUX_CONTRL		GENMASK(1, 0)
> > +#define TCA_TCPC_MUX_CONTRL_NO_CONN	0
> > +#define TCA_TCPC_MUX_CONTRL_USB_CONN	1
> > +
> > +#define TCA_SYSMODE_CFG			0x18
> > +#define TCA_SYSMODE_TCPC_DISABLE	BIT(3)
> > +#define TCA_SYSMODE_TCPC_FLIP		BIT(2)
> > +
> > +#define TCA_CTRLSYNCMODE_CFG0		0x20
> > +#define TCA_CTRLSYNCMODE_CFG1           0x20
> > +
> > +#define TCA_PSTATE			0x30
> > +#define TCA_PSTATE_CM_STS		BIT(4)
> > +#define TCA_PSTATE_TX_STS		BIT(3)
> > +#define TCA_PSTATE_RX_PLL_STS		BIT(2)
> > +#define TCA_PSTATE_PIPE0_POWER_DOWN	GENMASK(1, 0)
> > +
> > +#define TCA_GEN_STATUS			0x34
> > +#define TCA_GEN_DEV_POR			BIT(12)
> > +#define TCA_GEN_REF_CLK_SEL		BIT(8)
> > +#define TCA_GEN_TYPEC_FLIP_INVERT	BIT(4)
> > +#define TCA_GEN_PHY_TYPEC_DISABLE	BIT(3)
> > +#define TCA_GEN_PHY_TYPEC_FLIP		BIT(2)
> > +
> > +#define TCA_VBUS_CTRL			0x40
> > +#define TCA_VBUS_STATUS			0x44
> > +
> > +#define TCA_INFO			0xfc
> > +
> > +struct tca_blk {
> > +	struct typec_switch_dev *sw;
> > +	void __iomem *base;
> > +	struct mutex mutex;
> > +	enum typec_orientation orientation;
> > +};
> > +
> >    struct imx8mq_usb_phy {
> >    	struct phy *phy;
> >    	struct clk *clk;
> >    	void __iomem *base;
> >    	struct regulator *vbus;
> > +	struct tca_blk *tca;
> >    	u32 pcs_tx_swing_full;
> >    	u32 pcs_tx_deemph_3p5db;
> >    	u32 tx_vref_tune;
> > @@ -64,6 +120,175 @@ struct imx8mq_usb_phy {
> >    	u32 comp_dis_tune;
> >    };
> > +
> > +static void tca_blk_orientation_set(struct tca_blk *tca,
> > +				enum typec_orientation orientation);
> > +
> > +#ifdef CONFIG_TYPEC
> > +
> > +static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
> > +				enum typec_orientation orientation)
> > +{
> > +	struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
> > +	struct tca_blk *tca = imx_phy->tca;
> > +	int ret;
> > +
> > +	if (tca->orientation == orientation)
> > +		return 0;
> > +
> > +	ret = clk_prepare_enable(imx_phy->clk);
> > +	if (ret)
> > +		return ret;
> > +
> > +	tca_blk_orientation_set(tca, orientation);
> > +	clk_disable_unprepare(imx_phy->clk);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
> > +					struct imx8mq_usb_phy *imx_phy)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct typec_switch_dev *sw;
> > +	struct typec_switch_desc sw_desc = { };
> > +
> > +	sw_desc.drvdata = imx_phy;
> > +	sw_desc.fwnode = dev->fwnode;
> > +	sw_desc.set = tca_blk_typec_switch_set;
> > +	sw_desc.name = NULL;
> > +
> > +	sw = typec_switch_register(dev, &sw_desc);
> > +	if (IS_ERR(sw)) {
> > +		dev_err(dev, "Error register tca orientation switch: %ld",
> > +				PTR_ERR(sw));
> > +		return NULL;
> > +	}
> > +
> > +	return sw;
> > +}
> > +
> > +static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
> > +{
> > +	typec_switch_unregister(sw);
> > +}
> > +
> > +#else
> > +
> > +static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
> > +			struct imx8mq_usb_phy *imx_phy)
> > +{
> > +	return NULL;
> > +}
> > +
> > +static void tca_blk_put_typec_switch(struct typec_switch_dev *sw) {}
> > +
> > +#endif /* CONFIG_TYPEC */
> > +
> > +static void tca_blk_orientation_set(struct tca_blk *tca,
> > +				enum typec_orientation orientation)
> > +{
> > +	u32 val;
> > +
> > +	mutex_lock(&tca->mutex);
> > +
> > +	if (orientation == TYPEC_ORIENTATION_NONE) {
> > +		/*
> > +		 * use Controller Synced Mode for TCA low power enable and
> > +		 * put PHY to USB safe state.
> > +		 */
> > +		val = readl(tca->base + TCA_GCFG);
> > +		val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYNCMODE);
> > +		writel(val, tca->base + TCA_GCFG);
> If the register is intended to be completely overwritten, the readl is
> unnecessary. Otherwise, ensure a proper read-modify-write sequence.

Yes, the readl can be removed. I will improve it in next version.
Thanks for your comments.

Thanks,
Xu Yang

> > +
> > +		val = readl(tca->base + TCA_TCPC);
> > +		val = TCA_TCPC_VALID | TCA_TCPC_LOW_POWER_EN;
> > +		writel(val, tca->base + TCA_TCPC);
> > +
> > +		goto out;
> > +	}
> > +
> > +	/* use System Configuration Mode for TCA mux control. */
> > +	val = readl(tca->base + TCA_GCFG);
> > +	val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYSMODE);
> > +	writel(val, tca->base + TCA_GCFG);
> > +
> > +	/* Disable TCA module */
> > +	val = readl(tca->base + TCA_SYSMODE_CFG);
> > +	val |= TCA_SYSMODE_TCPC_DISABLE;
> > +	writel(val, tca->base + TCA_SYSMODE_CFG);
> > +
> > +	if (orientation == TYPEC_ORIENTATION_REVERSE)
> > +		val |= TCA_SYSMODE_TCPC_FLIP;
> > +	else if (orientation == TYPEC_ORIENTATION_NORMAL)
> > +		val &= ~TCA_SYSMODE_TCPC_FLIP;
> > +
> > +	writel(val, tca->base + TCA_SYSMODE_CFG);
> > +
> > +	/* Enable TCA module */
> > +	val &= ~TCA_SYSMODE_TCPC_DISABLE;
> > +	writel(val, tca->base + TCA_SYSMODE_CFG);
> > +
> > +out:
> > +	tca->orientation = orientation;
> > +	mutex_unlock(&tca->mutex);
> > +}
> > +
> > +static void tca_blk_init(struct tca_blk *tca)
> > +{
> > +	u32 val;
> > +
> > +	/* reset XBar block */
> > +	val = readl(tca->base + TCA_CLK_RST);
> > +	val &= ~TCA_CLK_RST_SW;
> > +	writel(val, tca->base + TCA_CLK_RST);
> > +
> > +	udelay(100);
> > +
> > +	/* clear reset */
> > +	val |= TCA_CLK_RST_SW;
> > +	writel(val, tca->base + TCA_CLK_RST);
> > +
> > +	tca_blk_orientation_set(tca, tca->orientation);
> > +}
> > +
> > +static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
> > +				struct imx8mq_usb_phy *imx_phy)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct resource *res;
> > +	struct tca_blk *tca;
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +	if (!res)
> > +		return NULL;
> > +
> > +	tca = devm_kzalloc(dev, sizeof(*tca), GFP_KERNEL);
> > +	if (!tca)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	tca->base = devm_ioremap_resource(&pdev->dev, res);
> > +	if (IS_ERR(tca->base))
> > +		return ERR_CAST(tca->base);
> > +
> > +	mutex_init(&tca->mutex);
> > +
> > +	tca->orientation = TYPEC_ORIENTATION_NORMAL;
> > +	tca->sw = tca_blk_get_typec_switch(pdev, imx_phy);
> > +
> > +	return tca;
> > +}
> > +
> > +static void imx95_usb_phy_put_tca(struct imx8mq_usb_phy *imx_phy)
> > +{
> > +	struct tca_blk *tca = imx_phy->tca;
> > +
> > +	if (!tca)
> > +		return;
> > +
> > +	tca_blk_put_typec_switch(tca->sw);
> > +}
> > +
> >    static u32 phy_tx_vref_tune_from_property(u32 percent)
> >    {
> >    	percent = clamp(percent, 94U, 124U);
> > @@ -315,6 +540,9 @@ static int imx8mp_usb_phy_init(struct phy *phy)
> >    	imx8m_phy_tune(imx_phy);
> > +	if (imx_phy->tca)
> > +		tca_blk_init(imx_phy->tca);
> > +
> >    	return 0;
> >    }
> > @@ -359,6 +587,8 @@ static const struct of_device_id imx8mq_usb_phy_of_match[] = {
> >    	 .data = &imx8mq_usb_phy_ops,},
> >    	{.compatible = "fsl,imx8mp-usb-phy",
> >    	 .data = &imx8mp_usb_phy_ops,},
> > +	{.compatible = "fsl,imx95-usb-phy",
> > +	 .data = &imx8mp_usb_phy_ops,},
> >    	{ }
> >    };
> >    MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
> > @@ -398,6 +628,11 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
> >    	phy_set_drvdata(imx_phy->phy, imx_phy);
> > +	imx_phy->tca = imx95_usb_phy_get_tca(pdev, imx_phy);
> > +	if (IS_ERR(imx_phy->tca))
> > +		return dev_err_probe(dev, PTR_ERR(imx_phy->tca),
> > +					"failed to get tca\n");
> > +
> >    	imx8m_get_phy_tuning_data(imx_phy);
> >    	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > @@ -405,8 +640,16 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
> >    	return PTR_ERR_OR_ZERO(phy_provider);
> >    }
> > +static void imx8mq_usb_phy_remove(struct platform_device *pdev)
> > +{
> > +	struct imx8mq_usb_phy *imx_phy = platform_get_drvdata(pdev);
> > +
> > +	imx95_usb_phy_put_tca(imx_phy);
> > +}
> > +
> >    static struct platform_driver imx8mq_usb_phy_driver = {
> >    	.probe	= imx8mq_usb_phy_probe,
> > +	.remove = imx8mq_usb_phy_remove,
> >    	.driver = {
> >    		.name	= "imx8mq-usb-phy",
> >    		.of_match_table	= imx8mq_usb_phy_of_match,
> > -- 
> > 2.34.1
> > 
> > 
> 


From victor.liu at nxp.com  Sun Dec  1 18:56:22 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:22 +0800
Subject: [PATCH v5 06/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller command sequencer
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-7-victor.liu@nxp.com>

i.MX8qxp Display Controller contains a command sequencer is designed to
autonomously process command lists.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* No change.

v4:
* Replace "fsl,iram" property with standard "sram" property. (Rob)

v3:
* New patch. (Rob)

 .../imx/fsl,imx8qxp-dc-command-sequencer.yaml | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml
new file mode 100644
index 000000000000..27118f4c0d28
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Command Sequencer
+
+description: |
+  The Command Sequencer is designed to autonomously process command lists.
+  By that it can load setups into the DC configuration and synchronize to
+  hardware events.  This releases a system's CPU from workload, because it
+  does not need to wait for certain events.  Also it simplifies SW architecture,
+  because no interrupt handlers are required.  Setups are read via AXI bus,
+  while write access to configuration registers occurs directly via an internal
+  bus.  This saves bandwidth for the AXI interconnect and improves the system
+  architecture in terms of safety aspects.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-command-sequencer
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 5
+
+  interrupt-names:
+    items:
+      - const: error
+      - const: sw0
+      - const: sw1
+      - const: sw2
+      - const: sw3
+
+  sram:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle pointing to the mmio-sram device node
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    command-sequencer at 56180400 {
+        compatible = "fsl,imx8qxp-dc-command-sequencer";
+        reg = <0x56180400 0x1a4>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <36>, <37>, <38>, <39>, <40>;
+        interrupt-names = "error", "sw0", "sw1", "sw2", "sw3";
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:16 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:16 +0800
Subject: [PATCH v5 00/19] Add Freescale i.MX8qxp Display Controller support
Message-ID: <20241202025635.1274467-1-victor.liu@nxp.com>

Hi,

This patch series aims to add Freescale i.MX8qxp Display Controller support.

The controller is comprised of three main components that include a blit
engine for 2D graphics accelerations, display controller for display output
processing, as well as a command sequencer.

Previous patch series attempts to do that can be found at:
https://patchwork.freedesktop.org/series/84524/

This series addresses Maxime's comments on the previous one:
a. Split the display controller into multiple internal devices.
   1) List display engine, pixel engine, interrupt controller and more as the
      controller's child devices.
   2) List display engine and pixel engine's processing units as their child
      devices.

b. Add minimal feature support.
   Only support two display pipelines with primary planes with XR24 fb,
   backed by two fetchunits.  No fetchunit dynamic allocation logic(to be done
   when necessary).

c. Use drm_dev_{enter, exit}().

Since this series changes a lot comparing to the previous one, I choose to
send it with a new patch series, not a new version.

To follow up i.MX8qxp TRM, I changed the controller name to "Display Controller"
instead of the previous "DPU".  "DPU" is only mentioned in the SoC block
diagram and represents the whole display subsystem which includes the display
controller and prefech engines, etc.

With an additional patch[1] for simple-pm-bus.c, this series facilitates
testing a LVDS panel on i.MX8qxp MEK.

Please do NOT merge patch 14-19.  They are only used to facilitate testing
the LVDS panel.

[1] https://lkml.org/lkml/2023/1/25/120

v5:
* Document display controller device's and some display controller internal
  devices' aliases in DT bindings. Hence, drop collected R-b tags from some
  patches for DT bindings. (Maxime)
* Replace .remove_new with .remove in all drivers. (Uwe)
* Select REGMAP and REGMAP_MMIO options in patch 9.
* Fix patch 9 & 10's commit message to state that display engine driver and
  pixel engine driver are component drivers instead of master/aggregate drivers.

v4:
* Collect Rob's R-b tags on DT binding patches(patch 1-5).
* Replace "fsl,iram" property with standard "sram" property in
  fsl,imx8qxp-dc-command-sequencer.yaml in patch 6. (Rob)
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Inline some small functions. (Dmitry)
* Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
  function calls from KMS routine to initialization stage. (Dmitry)
* Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
  appropriate .h header files or .c source files. (Dmitry)
* Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
* Drop dc_drm->pe_rpm_count. (Dmitry)
* Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
* Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
  Instead, put it in struct dc_crtc.  (Dmitry)
* Call devm_request_irq() to request IRQs, instead of using drmm action.
  (Dmitry)
* Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
* Select DRM_CLIENT_SELECTION due to rebase.
* Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
* Drop unnecessary private struct dc_*_priv from DC internal device drivers.
* Set suppress_bind_attrs driver flag to true in DC internal device drivers
  to avoid unnecessary sys interfaces to bind/unbind the drivers.
* Make some fetch unit operations be aware of fractional fetch unit index(0-7).
* Take DC interrupt controller driver as a standalone driver instead of a
  component driver.
* Replace drmm_kcalloc() with devm_kcalloc() to allocate an array for
  struct dc_ic_entry.
* Call platform_get_irq() from DC interrupt controller driver to make sure
  parent interrupt controller driver is probed first.
* Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
* Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
  rebase.
* Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
  register dc_drm_component_unbind_all() action.
* Request interrupts in dc_crtc_post_init() after encoder initialization to
  make sure next bridge is found first.
* Trivial tweaks.

v3:
* Collect Rob's R-b tag on the patch for adding fsl,imx8qxp-dc-intc.yaml.
* Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
  fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
  into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
* Document all processing units, command sequencer, axi performance counter
  and blit engine. (Rob)

v2:
* Drop fsl,dc-*-id DT properties from fsl,imx8qxp-dc*.yaml. (Krzysztof)
* Move port property from fsl,imx8qxp-dc-display-engine.yaml to
  fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
* Drop unneeded "|" from fsl,imx8qxp-dc-intc.yaml. (Krzysztof)
* Use generic pmu pattern property in fsl,imx8qxp-dc.yaml. (Krzysztof)
* Fix register range size in fsl,imx8qxp-dc*.yaml.
* Use OF alias id to get instance id from display driver.
* Find next bridge from TCon's port from display driver.
* Drop drm/drm_module.h include from dc-drv.c.
* Improve file list in MAINTAINERS. (Frank)
* Add entire i.MX8qxp display controller device tree for review. (Krzysztof)
* Add MIPI/LVDS subsystems device tree and a DT overlay for imx8qxp
  MEK to test a LVDS panel as an example. (Francesco)

Liu Ying (19):
  dt-bindings: display: imx: Add i.MX8qxp Display Controller processing
    units
  dt-bindings: display: imx: Add i.MX8qxp Display Controller blit engine
  dt-bindings: display: imx: Add i.MX8qxp Display Controller display
    engine
  dt-bindings: display: imx: Add i.MX8qxp Display Controller pixel
    engine
  dt-bindings: display: imx: Add i.MX8qxp Display Controller AXI
    performance counter
  dt-bindings: display: imx: Add i.MX8qxp Display Controller command
    sequencer
  dt-bindings: interrupt-controller: Add i.MX8qxp Display Controller
    interrupt controller
  dt-bindings: display: imx: Add i.MX8qxp Display Controller
  drm/imx: Add i.MX8qxp Display Controller display engine
  drm/imx: Add i.MX8qxp Display Controller pixel engine
  drm/imx: Add i.MX8qxp Display Controller interrupt controller
  drm/imx: Add i.MX8qxp Display Controller KMS
  MAINTAINERS: Add maintainer for i.MX8qxp Display Controller
  dt-bindings: phy: mixel, mipi-dsi-phy: Allow assigned-clock*
    properties
  dt-bindings: firmware: imx: Add SCU controlled display pixel link
    nodes
  arm64: dts: imx8qxp: Add display controller subsystem
  arm64: dts: imx8qxp: Add MIPI-LVDS combo subsystems
  arm64: dts: imx8qxp-mek: Enable display controller
  arm64: dts: imx8qxp-mek: Add MX8-DLVDS-LCD1 display module support

 ...sl,imx8qxp-dc-axi-performance-counter.yaml |  57 ++
 .../imx/fsl,imx8qxp-dc-blit-engine.yaml       | 204 +++++++
 .../display/imx/fsl,imx8qxp-dc-blitblend.yaml |  46 ++
 .../display/imx/fsl,imx8qxp-dc-clut.yaml      |  49 ++
 .../imx/fsl,imx8qxp-dc-command-sequencer.yaml |  67 +++
 .../imx/fsl,imx8qxp-dc-constframe.yaml        |  49 ++
 .../imx/fsl,imx8qxp-dc-display-engine.yaml    | 157 +++++
 .../display/imx/fsl,imx8qxp-dc-dither.yaml    |  49 ++
 .../display/imx/fsl,imx8qxp-dc-extdst.yaml    |  77 +++
 .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 +++++
 .../display/imx/fsl,imx8qxp-dc-filter.yaml    |  47 ++
 .../display/imx/fsl,imx8qxp-dc-framegen.yaml  |  68 +++
 .../display/imx/fsl,imx8qxp-dc-gammacor.yaml  |  38 ++
 .../imx/fsl,imx8qxp-dc-layerblend.yaml        |  45 ++
 .../display/imx/fsl,imx8qxp-dc-matrix.yaml    |  48 ++
 .../imx/fsl,imx8qxp-dc-pixel-engine.yaml      | 250 ++++++++
 .../display/imx/fsl,imx8qxp-dc-rop.yaml       |  48 ++
 .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++
 .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  89 +++
 .../display/imx/fsl,imx8qxp-dc-signature.yaml |  58 ++
 .../display/imx/fsl,imx8qxp-dc-store.yaml     | 100 ++++
 .../display/imx/fsl,imx8qxp-dc-tcon.yaml      |  50 ++
 .../bindings/display/imx/fsl,imx8qxp-dc.yaml  | 240 ++++++++
 .../devicetree/bindings/firmware/fsl,scu.yaml |  20 +
 .../fsl,imx8qxp-dc-intc.yaml                  | 318 ++++++++++
 .../bindings/phy/mixel,mipi-dsi-phy.yaml      |   5 -
 MAINTAINERS                                   |   8 +
 arch/arm64/boot/dts/freescale/Makefile        |   4 +
 .../arm64/boot/dts/freescale/imx8-ss-dc0.dtsi | 408 +++++++++++++
 .../imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso | 183 ++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |  34 ++
 .../boot/dts/freescale/imx8qxp-ss-dc.dtsi     | 240 ++++++++
 .../dts/freescale/imx8qxp-ss-mipi-lvds.dtsi   | 437 ++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |  28 +-
 drivers/gpu/drm/imx/Kconfig                   |   1 +
 drivers/gpu/drm/imx/Makefile                  |   1 +
 drivers/gpu/drm/imx/dc/Kconfig                |  13 +
 drivers/gpu/drm/imx/dc/Makefile               |   7 +
 drivers/gpu/drm/imx/dc/dc-cf.c                | 162 +++++
 drivers/gpu/drm/imx/dc/dc-crtc.c              | 558 ++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-de.c                | 153 +++++
 drivers/gpu/drm/imx/dc/dc-de.h                |  60 ++
 drivers/gpu/drm/imx/dc/dc-drv.c               | 283 +++++++++
 drivers/gpu/drm/imx/dc/dc-drv.h               |  52 ++
 drivers/gpu/drm/imx/dc/dc-ed.c                | 270 +++++++++
 drivers/gpu/drm/imx/dc/dc-fg.c                | 374 ++++++++++++
 drivers/gpu/drm/imx/dc/dc-fl.c                | 180 ++++++
 drivers/gpu/drm/imx/dc/dc-fu.c                | 268 +++++++++
 drivers/gpu/drm/imx/dc/dc-fu.h                | 129 ++++
 drivers/gpu/drm/imx/dc/dc-fw.c                | 219 +++++++
 drivers/gpu/drm/imx/dc/dc-ic.c                | 279 +++++++++
 drivers/gpu/drm/imx/dc/dc-kms.c               | 143 +++++
 drivers/gpu/drm/imx/dc/dc-kms.h               |  58 ++
 drivers/gpu/drm/imx/dc/dc-lb.c                | 319 ++++++++++
 drivers/gpu/drm/imx/dc/dc-pe.c                | 133 +++++
 drivers/gpu/drm/imx/dc/dc-pe.h                | 100 ++++
 drivers/gpu/drm/imx/dc/dc-plane.c             | 241 ++++++++
 drivers/gpu/drm/imx/dc/dc-tc.c                | 138 +++++
 58 files changed, 7837 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi
 create mode 100644 drivers/gpu/drm/imx/dc/Kconfig
 create mode 100644 drivers/gpu/drm/imx/dc/Makefile
 create mode 100644 drivers/gpu/drm/imx/dc/dc-cf.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ed.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fg.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fl.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fw.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ic.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-lb.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-tc.c

-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:21 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:21 +0800
Subject: [PATCH v5 05/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller AXI performance counter
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-6-victor.liu@nxp.com>

i.MX8qxp Display Controller contains a AXI performance counter which allows
measurement of average bandwidth and latency during operation.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v5:
* No change.

v4:
* Collect Rob's R-b tag.

v3:
* New patch. (Rob)

 ...sl,imx8qxp-dc-axi-performance-counter.yaml | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml
new file mode 100644
index 000000000000..1d6501afc7f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller AXI Performance Counter
+
+description: |
+  Performance counters are provided to allow measurement of average bandwidth
+  and latency during operation. The following features are supported:
+
+  * Manual and timer controlled measurement mode.
+
+  * Measurement counters:
+    - GLOBAL_COUNTER for overall measurement time
+    - BUSY_COUNTER for number of data bus busy cycles
+    - DATA_COUNTER for number of data transfer cycles
+    - TRANSFER_COUNTER for number of transfers
+    - ADDRBUSY_COUNTER for number of address bus busy cycles
+    - LATENCY_COUNTER for average latency
+
+  * Counter overflow detection.
+
+  * Outstanding Transfer Counters (OTC) which are used for latency measurement
+    have to run immediately after reset, but can be disabled by software when
+    there is no need for latency measurement.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-axi-performance-counter
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    pmu at 5618f000 {
+        compatible = "fsl,imx8qxp-dc-axi-performance-counter";
+        reg = <0x5618f000 0x90>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+    };
-- 
2.34.1



From ryan_chen at aspeedtech.com  Sun Dec  1 19:12:01 2024
From: ryan_chen at aspeedtech.com (Ryan Chen)
Date: Mon, 2 Dec 2024 03:12:01 +0000
Subject: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
In-Reply-To: <a68516df98c8b8fb80f094e6e55fcb8d.sboyd@kernel.org>
References: <20241028053018.2579200-1-ryan_chen@aspeedtech.com>
 <20241028053018.2579200-4-ryan_chen@aspeedtech.com>
 <287924eed186e3b6b52cd13bcf939ab6.sboyd@kernel.org>
 <SI6PR06MB7535F5D22E3FCCF5C610B307F2552@SI6PR06MB7535.apcprd06.prod.outlook.com>
 <a68516df98c8b8fb80f094e6e55fcb8d.sboyd@kernel.org>
Message-ID: <OS8PR06MB75419637D55A022300E00850F2352@OS8PR06MB7541.apcprd06.prod.outlook.com>

> > > Subject: Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> > >
> > > Quoting Ryan Chen (2024-10-27 22:30:18)
> > > > diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c
> > > > new file mode 100644 index 000000000000..db9ee5031b7c
> > > > --- /dev/null
> > > > +++ b/drivers/clk/clk-ast2700.c
> > > > @@ -0,0 +1,1513 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> [...]
> > > > +struct ast2700_clk_info {
> > > > +       const char *name;
> > > > +       const char * const *parent_names;
> > >
> > > Please don't use strings for parent names.
> > Sorry, do you mean use clk_parent_data struct for parent?
> >         +const struct clk_parent_data   parent;         /* For gate */
> >         +const struct clk_parent_data   *parents;               /*
> For mux */
> 
> Yes.
And I find a better way for parent_data. The following is my modification. 
And parent_data will be union data structure. Like following.
Is this good direction? 

#define DIVIDER_CLK(_id, _name, _parent, _reg, _shift, _width, _div_table) \
	[_id] = { \
		.type = CLK_DIVIDER, \
		.name = _name, \
		.data = { \
			.div = { \
				.parent = _parent, \
				.reg = _reg, \
				.bit_shift = _shift, \
				.bit_width = _width, \
				.div_table = _div_table, \
			}, \
		}, \
	}
struct ast2700_clk_info {
	const char *name;
	u8 clk_idx;
	u32 reg;
	u32 type;
	union {
		struct ast2700_clk_fixed_factor_data factor;
		struct ast2700_clk_fixed_rate_data rate;
		struct ast2700_clk_gate_data gate;
		struct ast2700_clk_div_data div;
		struct ast2700_clk_pll_data pll;
		struct ast2700_clk_mux_data mux;
	} data;
};

struct ast2700_clk_div_data {
	const struct clk_div_table *div_table;
	const struct clk_parent_data *parent;
	u8 bit_shift;
	u8 bit_width;
	u32 reg;
};

static const struct ast2700_clk_info ast2700_scu0_clk_info[] __initconst = {
...........................
	DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,
		    SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table),
......................
> 
> >
> > >
> > > > +       const struct clk_div_table *div_table;
> > > > +       unsigned long fixed_rate;
> > > > +       unsigned int mult;
> > > > +       unsigned int div;
> > > > +       u32 reg;
> > > > +       u32 flags;
> > > > +       u32 type;
> > > > +       u8 clk_idx;
> > > > +       u8 bit_shift;
> > > > +       u8 bit_width;
> > > > +       u8 num_parents;
> > > > +};
> > > > +
> > > [...]
> > > > +
> > > > +static const struct clk_div_table ast2700_clk_div_table2[] = {
> > > > +       { 0x0, 2 },
> > > > +       { 0x1, 4 },
> > > > +       { 0x2, 6 },
> > > > +       { 0x3, 8 },
> > > > +       { 0x4, 10 },
> > > > +       { 0x5, 12 },
> > > > +       { 0x6, 14 },
> > > > +       { 0x7, 16 },
> > >
> > > Isn't this the default divider setting for struct clk_divider?
> > Sorry, I don't catch your point.
> > the SoC do have default divider setting. But it can be modified.
> > And also have different divider table setting.
> 
> I mean that this is the way that struct clk_divider works already. So you don't
> need to make the clk_div_table array for what is supported in code.

Sorry, I understand your point. But I trace the code didn't get any clue. "clk_divider work already".
finally function call will be __clk_hw_register_divider
https://github.com/torvalds/linux/blob/master/drivers/clk/clk-divider.c#L589
It still need table point need to address. Can you give me more direction or example?


> 
> > >
> > > > +       { 0 }
> > > > +};
> > > > +
> > > > +static const struct clk_div_table ast2700_clk_uart_div_table[] = {
> > > > +       { 0x0, 1 },
> > > > +       { 0x1, 13 },
> > > > +       { 0 }
> > > [...]
> > > > +               .bit_shift = 23,
> > > > +               .bit_width = 3,
> > > > +               .div_table = ast2700_clk_div_table2,
> > > > +       },
> > > > +       [SCU0_CLK_GATE_MCLK] = {
> > > > +               .type = CLK_GATE_ASPEED,
> > > > +               .name = "mclk-gate",
> > > > +               .parent_names = (const char *[]){ "soc0-mpll", },
> > > > +               .reg = SCU0_CLK_STOP,
> > > > +               .clk_idx = 0,
> > > > +               .flags = CLK_IS_CRITICAL,
> > > > +       },
> > > > +       [SCU0_CLK_GATE_ECLK] = {
> > > > +               .type = CLK_GATE_ASPEED,
> > > > +               .name = "eclk-gate",
> > > > +               .parent_names = (const char *[]){  },
> > > > +               .reg = SCU0_CLK_STOP,
> > > > +               .clk_idx = 1,
> > > > +       },
> > > > +       [SCU0_CLK_GATE_2DCLK] = {
> > > > +               .type = CLK_GATE_ASPEED,
> > > > +               .name = "gclk-gate",
> > > > +               .parent_names = (const char *[]){  },
> > >
> > > This has no parent? Why is parent_names set to an empty array?
> > Due to I use clk->parent_names[0] for clk_hw_register_gate, const char
> *name parameter input.
> > If null, that will cause panic for NULL point.
> 
> But the parent is NULL? How many parents does this clk have?

I will remove this in array.
I will do parent_names = parent ? &parent->name : NULL; to check null.
> 
> > >
> > > > +       if (!clk_data)
> > > > +               return devm_of_platform_populate(dev);
> > >
> > > What is being populated? Isn't there always clk_data?
> > Yes, it is always clk_data, I will modify to be following, is it ok?
> > If(!clk_data)
> >         Return -ENODEV;
> >
> 
> Sure.
> 
> > >
> > > Please don't use strings for parent_names. Use clk_hw pointers or DT
> indices.
> > Use clk_pareent_data is it ok ?
> 
> Yes.

From victor.liu at nxp.com  Sun Dec  1 18:56:29 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:29 +0800
Subject: [PATCH v5 13/19] MAINTAINERS: Add maintainer for i.MX8qxp Display Controller
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-14-victor.liu@nxp.com>

Add myself as the maintainer of i.MX8qxp Display Controller.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* Improve file list. (Frank)

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1240e75ecf4b..f3f9655b2f00 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7675,6 +7675,14 @@ F:	Documentation/devicetree/bindings/display/imx/
 F:	drivers/gpu/drm/imx/ipuv3/
 F:	drivers/gpu/ipu-v3/
 
+DRM DRIVERS FOR FREESCALE IMX8 DISPLAY CONTROLLER
+M:	Liu Ying <victor.liu at nxp.com>
+L:	dri-devel at lists.freedesktop.org
+S:	Maintained
+T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
+F:	Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc*.yaml
+F:	drivers/gpu/drm/imx/dc/
+
 DRM DRIVERS FOR FREESCALE IMX BRIDGE
 M:	Liu Ying <victor.liu at nxp.com>
 L:	dri-devel at lists.freedesktop.org
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:20 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:20 +0800
Subject: [PATCH v5 04/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller pixel engine
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-5-victor.liu@nxp.com>

i.MX8qxp Display Controller pixel engine consists of all processing units
that operate in the AXI bus clock domain.  Command sequencer and interrupt
controller of the Display Controller work with AXI bus clock, but they are
not in pixel engine.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v5:
* No change.

v4:
* Collect Rob's R-b tag.

v3:
* No change.

v2:
* Drop fsl,dc-*-id DT properties from example. (Krzysztof)
* Fix register range sizes in example.

 .../imx/fsl,imx8qxp-dc-pixel-engine.yaml      | 250 ++++++++++++++++++
 1 file changed, 250 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
new file mode 100644
index 000000000000..633443a6cc38
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
@@ -0,0 +1,250 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Pixel Engine
+
+description:
+  All Processing Units that operate in the AXI bus clock domain. Pixel
+  pipelines have the ability to stall when a destination is busy. Implements
+  all communication to memory resources and most of the image processing
+  functions. Interconnection of Processing Units is re-configurable.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-pixel-engine
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^blit-engine@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-blit-engine
+
+  "^constframe@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-constframe
+
+  "^extdst@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-extdst
+
+  "^fetchdecode@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchdecode
+
+  "^fetcheco@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetcheco
+
+  "^fetchlayer@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchlayer
+
+  "^fetchwarp@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchwarp
+
+  "^hscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-hscaler
+
+  "^layerblend@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-layerblend
+
+  "^matrix@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-matrix
+
+  "^safety@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-safety
+
+  "^vscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-vscaler
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    pixel-engine at 56180800 {
+        compatible = "fsl,imx8qxp-dc-pixel-engine";
+        reg = <0x56180800 0xac00>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        constframe at 56180960 {
+            compatible = "fsl,imx8qxp-dc-constframe";
+            reg = <0x56180960 0xc>, <0x56184400 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 56180980 {
+            compatible = "fsl,imx8qxp-dc-extdst";
+            reg = <0x56180980 0x1c>, <0x56184800 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <3>, <4>, <5>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        constframe at 561809a0 {
+            compatible = "fsl,imx8qxp-dc-constframe";
+            reg = <0x561809a0 0xc>, <0x56184c00 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 561809c0 {
+            compatible = "fsl,imx8qxp-dc-extdst";
+            reg = <0x561809c0 0x1c>, <0x56185000 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <6>, <7>, <8>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        constframe at 561809e0 {
+            compatible = "fsl,imx8qxp-dc-constframe";
+            reg = <0x561809e0 0xc>, <0x56185400 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 56180a00 {
+            compatible = "fsl,imx8qxp-dc-extdst";
+            reg = <0x56180a00 0x1c>, <0x56185800 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <9>, <10>, <11>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        constframe at 56180a20 {
+            compatible = "fsl,imx8qxp-dc-constframe";
+            reg = <0x56180a20 0xc>, <0x56185c00 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 56180a40 {
+            compatible = "fsl,imx8qxp-dc-extdst";
+            reg = <0x56180a40 0x1c>, <0x56186000 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <12>, <13>, <14>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        fetchwarp at 56180a60 {
+            compatible = "fsl,imx8qxp-dc-fetchwarp";
+            reg = <0x56180a60 0x10>, <0x56186400 0x190>;
+            reg-names = "pec", "cfg";
+        };
+
+        fetchlayer at 56180ac0 {
+            compatible = "fsl,imx8qxp-dc-fetchlayer";
+            reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180ba0 {
+            compatible = "fsl,imx8qxp-dc-layerblend";
+            reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180bc0 {
+            compatible = "fsl,imx8qxp-dc-layerblend";
+            reg = <0x56180bc0 0x10>, <0x5618a800 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180be0 {
+            compatible = "fsl,imx8qxp-dc-layerblend";
+            reg = <0x56180be0 0x10>, <0x5618ac00 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180c00 {
+            compatible = "fsl,imx8qxp-dc-layerblend";
+            reg = <0x56180c00 0x10>, <0x5618b000 0x20>;
+            reg-names = "pec", "cfg";
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:19 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:19 +0800
Subject: [PATCH v5 03/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller display engine
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-4-victor.liu@nxp.com>

i.MX8qxp Display Controller display engine consists of all processing units
that operate in a display clock domain.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* Document aliases.  Drop Rob's previous R-b tag. (Maxime)

v4:
* Collect Rob's R-b tag.

v3:
* No change.

v2:
* Drop fsl,dc-*-id DT properties. (Krzysztof)
* Drop port property. (Krzysztof)
* Fix register range sizes in example.

 .../imx/fsl,imx8qxp-dc-display-engine.yaml    | 157 ++++++++++++++++++
 1 file changed, 157 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml
new file mode 100644
index 000000000000..b5da0bf3a1f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml
@@ -0,0 +1,157 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-display-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Display Engine
+
+description: |
+  All Processing Units that operate in a display clock domain. Pixel pipeline
+  is driven by a video timing and cannot be stalled. Implements all display
+  specific processing.
+
+  Each Display Engine device should have an alias in the aliases node, in the
+  form of dc<x>-display-engine<y>, where <x> is an integer specifying the
+  Display Controller instance and <y> is an integer specifying the Display
+  Engine device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-display-engine
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: top
+      - const: cfg
+
+  resets:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: framecomplete
+      - const: seqcomplete
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^dither@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-dither
+
+  "^framegen@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-framegen
+
+  "^gammacor@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-gammacor
+
+  "^matrix@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-matrix
+
+  "^signature@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-signature
+
+  "^tcon@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-tcon
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+  - power-domains
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    display-engine at 5618b400 {
+        compatible = "fsl,imx8qxp-dc-display-engine";
+        reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
+        reg-names = "top", "cfg";
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <15>, <16>, <17>;
+        interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        framegen at 5618b800 {
+            compatible = "fsl,imx8qxp-dc-framegen";
+            reg = <0x5618b800 0x98>;
+            clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <18>, <19>, <20>, <21>, <41>, <42>, <43>, <44>;
+            interrupt-names = "int0", "int1", "int2", "int3",
+                              "primsync_on", "primsync_off",
+                              "secsync_on", "secsync_off";
+        };
+
+        tcon at 5618c800 {
+            compatible = "fsl,imx8qxp-dc-tcon";
+            reg = <0x5618c800 0x588>;
+
+            port {
+                dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
+                    remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
+                };
+            };
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:17 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:17 +0800
Subject: [PATCH v5 01/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller processing units
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-2-victor.liu@nxp.com>

Freescale i.MX8qxp Display Controller is implemented as construction set of
building blocks with unified concept and standardized interfaces.  Document
all existing processing units.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* Document aliases for processing units which have multiple instances in
  the Display Controller.  Drop Rob's previous R-b tag. (Maxime)

v4:
* Collect Rob's R-b tag.

v3:
* Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
  fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
  into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
* Document all processing units. (Rob)

v2:
* Drop fsl,dc-*-id DT properties. (Krzysztof)
* Add port property to fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
* Fix register range sizes in examples.

 .../display/imx/fsl,imx8qxp-dc-blitblend.yaml |  46 ++++++
 .../display/imx/fsl,imx8qxp-dc-clut.yaml      |  49 ++++++
 .../imx/fsl,imx8qxp-dc-constframe.yaml        |  49 ++++++
 .../display/imx/fsl,imx8qxp-dc-dither.yaml    |  49 ++++++
 .../display/imx/fsl,imx8qxp-dc-extdst.yaml    |  77 +++++++++
 .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 ++++++++++++++++++
 .../display/imx/fsl,imx8qxp-dc-filter.yaml    |  47 ++++++
 .../display/imx/fsl,imx8qxp-dc-framegen.yaml  |  68 ++++++++
 .../display/imx/fsl,imx8qxp-dc-gammacor.yaml  |  38 +++++
 .../imx/fsl,imx8qxp-dc-layerblend.yaml        |  45 ++++++
 .../display/imx/fsl,imx8qxp-dc-matrix.yaml    |  48 ++++++
 .../display/imx/fsl,imx8qxp-dc-rop.yaml       |  48 ++++++
 .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++++
 .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  89 +++++++++++
 .../display/imx/fsl,imx8qxp-dc-signature.yaml |  58 +++++++
 .../display/imx/fsl,imx8qxp-dc-store.yaml     | 100 ++++++++++++
 .../display/imx/fsl,imx8qxp-dc-tcon.yaml      |  50 ++++++
 17 files changed, 1042 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
new file mode 100644
index 000000000000..7f800e72c3f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blitblend.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Blit Blend Unit
+
+description: |
+  Combines two input frames to a single output frame, all frames having the
+  same dimension.
+
+  Each Blit Blend Unit device should have an alias in the aliases node, in the
+  form of dc<x>-blitblend<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Blit Blend Unit
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-blitblend
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    blitblend at 56180920 {
+        compatible = "fsl,imx8qxp-dc-blitblend";
+        reg = <0x56180920 0x10>, <0x56183c00 0x3c>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
new file mode 100644
index 000000000000..351692d8942e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-clut.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Color Lookup Table
+
+description: |
+  The unit implements 3 look-up tables with 256 x 10 bit entries each. These
+  can be used for different kinds of applications. From 10-bit input values
+  only upper 8 bits are used.
+
+  The unit supports color lookup, index lookup, dithering and alpha masking.
+
+  Each Color Lookup Table device should have an alias in the aliases node, in
+  the form of dc<x>-clut<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Color Lookup Table
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-clut
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    clut at 56180880 {
+        compatible = "fsl,imx8qxp-dc-clut";
+        reg = <0x56180880 0x10>, <0x56182400 0x404>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
new file mode 100644
index 000000000000..cae19bc05d6e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-constframe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Constant Frame
+
+description: |
+  The Constant Frame unit is used instead of a Fetch unit where generation of
+  constant color frames only is sufficient. This is the case for the background
+  planes of content and safety streams in a Display Controller.
+
+  The color can be setup to any RGBA value.
+
+  Each Constant Frame device should have an alias in the aliases node, in the
+  form of dc<x>-constframe<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Constant Frame device
+  instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-constframe
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    constframe at 56180960 {
+        compatible = "fsl,imx8qxp-dc-constframe";
+        reg = <0x56180960 0xc>, <0x56184400 0x20>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
new file mode 100644
index 000000000000..cb0b4a05cfdc
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-dither.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Dither Unit
+
+description: |
+  The unit can increase the physical color resolution of a display from 5, 6, 7
+  or 8 bits per RGB channel to a virtual resolution of 10 bits. The physical
+  resolution can be set individually for each channel.
+
+  The resolution is increased by mixing the two physical colors that are nearest
+  to the virtual color code in a variable ratio either by time (temporal
+  dithering) or by position (spatial dithering).
+
+  An optimized algorithm for temporal dithering minimizes noise artifacts on the
+  output image.
+
+  The dither operation can be individually enabled or disabled for each pixel
+  using the alpha input bit.
+
+  Each Dither Unit device should have an alias in the aliases node, in the form
+  of dc<x>-dither<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the Dither Unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-dither
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    dither at 5618c400 {
+        compatible = "fsl,imx8qxp-dc-dither";
+        reg = <0x5618c400 0x14>;
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
new file mode 100644
index 000000000000..b382af1de1c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-extdst.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller External Destination Interface
+
+description: |
+  The External Destination unit is the interface between the internal pixel
+  processing pipeline of the Pixel Engine, which is 30-bit RGB plus 8-bit Alpha,
+  and a Display Engine.
+
+  It comprises the following built-in Gamma apply function.
+
+  +------X-----------------------+
+  |      |          ExtDst Unit  |
+  |      V                       |
+  |  +-------+                   |
+  |  | Gamma |                   |
+  |  +-------+                   |
+  |      |                       |
+  |      V                       +
+  +------X-----------------------+
+
+  The output format is 24-bit RGB plus 1-bit Alpha. Conversion from 10 to 8
+  bits is done by LSBit truncation.  Alpha output bit is 1 for input 255, 0
+  otherwise.
+
+  Each External Destination unit device should have an alias in the aliases
+  node, in the form of dc<x>-blitblend<y>, where <x> is an integer specifying
+  the Display Controller instance and <y> is an integer specifying the External
+  Destination unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-extdst
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: framecomplete
+      - const: seqcomplete
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    extdst at 56180980 {
+        compatible = "fsl,imx8qxp-dc-extdst";
+        reg = <0x56180980 0x1c>, <0x56184800 0x28>;
+        reg-names = "pec", "cfg";
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <3>, <4>, <5>;
+        interrupt-names = "shdload", "framecomplete", "seqcomplete";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
new file mode 100644
index 000000000000..2141e692bc02
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-fetchunit.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Fetch Unit
+
+description: |
+  The Fetch Unit is the interface between the AXI bus for source buffer access
+  and the internal pixel processing pipeline, which is 30-bit RGB plus 8-bit
+  Alpha.
+
+  It is used to generate foreground planes in Display Controllers and source
+  planes in Blit Engines, and comprises the following built-in functions to
+  convert a wide range of frame buffer types.
+
+  +---------X-----------------------------------------+
+  |         |                           Fetch Unit    |
+  |         V                                         |
+  |    +---------+                                    |
+  |    |         |                                    |
+  |    | Decode  | Decompression [Decode]             |
+  |    |         |                                    |
+  |    +---------+                                    |
+  |         |                                         |
+  |         V                                         |
+  |    +---------+                                    |
+  |    | Clip &  | Clip Window [All]                  |
+  |    | Overlay | Plane composition [Layer, Warp]    |
+  |    |         |                                    |
+  |    +---------+                                    |
+  |         |                                         |
+  |         V                                         |
+  |    +---------+                                    |
+  |    | Re-     | Flip/Rotate/Repl./Drop [All]       |
+  X--> | sample  | Perspective/Affine warping [Persp] |
+  | |  |         | Arbitrary warping [Warp, Persp]    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         |                                    |
+  | |  | Palette | Color Palette [Layer, Decode]      |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  | Extract | Raw to RGBA/YUV [All]              |
+  | |  | &       | Bit width expansion [All]          |
+  | |  | Expand  |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | Planar to packed                   |
+  | |->| Combine | [Decode, Warp, Persp]              |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | YUV422 to YUV444                   |
+  | |  | Chroma  | [Decode, Persp]                    |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | YUV to RGB                         |
+  | |  | Color   | [Warp, Persp, Decode, Layer]       |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | Gamma removal                      |
+  | |  | Gamma   | [Warp, Persp, Decode, Layer]       |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | Alpla multiply, RGB pre-multiply   |
+  |  ->| Multiply| [Warp, Persp, Decode, Layer]       |
+  |    |         |                                    |
+  |     ---------                                     |
+  |         |                                         |
+  |         V                                         |
+  |    +---------+                                    |
+  |    |         | Bilinear filter                    |
+  |    | Filter  | [Warp, Persp]                      |
+  |    |         |                                    |
+  |    +---------+                                    |
+  |         |                                         |
+  |         V                                         |
+  +---------X-----------------------------------------+
+
+  Note that different derivatives of the Fetch Unit exist. Each implements a
+  specific subset only of the pipeline stages shown above. Restrictions for the
+  units are specified in [square brackets].
+
+  Each Fetch Unit device should have an alias in the aliases node, in the form
+  of dc<x>-fetch<y><z>, where <x> is an integer specifying the Display
+  Controller instance, <y> specifies different derivative names(decode, eco,
+  layer and warp) and <z> is an integer specifying the Fetch Unit device
+  instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-fetchdecode
+      - fsl,imx8qxp-dc-fetcheco
+      - fsl,imx8qxp-dc-fetchlayer
+      - fsl,imx8qxp-dc-fetchwarp
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  fsl,prg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Optional Prefetch Resolve Gasket associated with the Fetch Unit.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    fetchlayer at 56180ac0 {
+        compatible = "fsl,imx8qxp-dc-fetchlayer";
+        reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
new file mode 100644
index 000000000000..e1bdcdd893b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-filter.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Filter Unit
+
+description: |
+  5x5 FIR filter with 25 programmable coefficients.
+
+  Typical applications are image blurring, sharpening or support for edge
+  detection algorithms.
+
+  Each Filter Unit device should have an alias in the aliases node, in the form
+  of dc<x>-filter<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the Filter Unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-filter
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    filter at 56180900 {
+        compatible = "fsl,imx8qxp-dc-filter";
+        reg = <0x56180900 0x10>, <0x56183800 0x30>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
new file mode 100644
index 000000000000..d784f6e59312
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-framegen.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Frame Generator
+
+description: |
+  The Frame Generator (FrameGen) module generates a programmable video timing
+  and optionally allows to synchronize the generated video timing to external
+  synchronization signals.
+
+  Each FrameGen device should have an alias in the aliases node, in the form of
+  dc<x>-framegen<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the FrameGen device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-framegen
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 8
+
+  interrupt-names:
+    items:
+      - const: int0
+      - const: int1
+      - const: int2
+      - const: int3
+      - const: primsync_on
+      - const: primsync_off
+      - const: secsync_on
+      - const: secsync_off
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    framegen at 5618b800 {
+        compatible = "fsl,imx8qxp-dc-framegen";
+        reg = <0x5618b800 0x98>;
+        clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <18>, <19>, <20>, <21>, <41>, <42>, <43>, <44>;
+        interrupt-names = "int0", "int1", "int2", "int3",
+                          "primsync_on", "primsync_off",
+                          "secsync_on", "secsync_off";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
new file mode 100644
index 000000000000..895501566210
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-gammacor.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Gamma Correction Unit
+
+description: |
+  The unit supports non-linear color transformation.
+
+  Each Gamma Correction Unit device should have an alias in the aliases node,
+  in the form of dc<x>-gammacor<y>, where <x> is an integer specifying the
+  Display Controller instance and <y> is an integer specifying the Gamma
+  Correction Unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-gammacor
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    gammacor at 5618c000 {
+        compatible = "fsl,imx8qxp-dc-gammacor";
+        reg = <0x5618c000 0x20>;
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
new file mode 100644
index 000000000000..50c0c1dacb41
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-layerblend.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Layer Blend Unit
+
+description: |
+  Combines two input frames to a single output frame.
+
+  Each Layer Blend Unit device should have an alias in the aliases node, in the
+  form of dc<x>-layerblend<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Layer Blend Unit
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-layerblend
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    layerblend at 56180ba0 {
+        compatible = "fsl,imx8qxp-dc-layerblend";
+        reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
new file mode 100644
index 000000000000..8778526e1eb8
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-matrix.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Color Matrix
+
+description: |
+  The unit supports linear color transformation, alpha pre-multiply and
+  alpha masking.
+
+  Each Color Matrix device should have an alias in the aliases node, in the form
+  of dc<x>-matrix<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the Color Matrix device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-matrix
+
+  reg:
+    minItems: 1
+    maxItems: 2
+
+  reg-names:
+    oneOf:
+      - const: cfg      # matrix in display engine
+      - items:          # matrix in pixel engine
+          - const: pec
+          - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    matrix at 5618bc00 {
+        compatible = "fsl,imx8qxp-dc-matrix";
+        reg = <0x5618bc00 0x3c>;
+        reg-names = "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
new file mode 100644
index 000000000000..a724cf960250
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-rop.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Raster Operation Unit
+
+description: |
+  The unit can combine up to three input frames to a single output frame, all
+  having the same dimension.
+
+  The unit supports logic operations, arithmetic operations and packing.
+
+  Each Raster Operation Unit device should have an alias in the aliases node,
+  in the form of dc<x>-rop<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Raster Operation Unit
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-rop
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    rop at 56180860 {
+        compatible = "fsl,imx8qxp-dc-rop";
+        reg = <0x56180860 0x10>, <0x56182000 0x20>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
new file mode 100644
index 000000000000..66c12948ab09
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-safety.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Safety Unit
+
+description:
+  The unit allows corresponding processing units to be configured in a path
+  leading to multiple endpoints.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-safety
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    safety at 56180800 {
+        compatible = "fsl,imx8qxp-dc-safety";
+        reg = <0x56180800 0x1c>;
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
new file mode 100644
index 000000000000..a1d6673f2a05
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Scaling Engine
+
+description: |
+  The unit can change the dimension of the input frame by nearest or linear
+  re-sampling with 1/32 sub pixel precision.
+
+  Internally it consist of two independent blocks for horizontal and vertical
+  scaling. The sequence of both operations is arbitrary.
+
+  Any frame dimensions between 1 and 16384 pixels in width and height are
+  supported, except that the vertical scaler has a frame width maximum
+  depending of the system's functional limitations.
+
+  In general all scale factors are supported inside the supported frame
+  dimensions. In range of scale factors 1/16..16 the filtered output colors
+  are LSBit precise (e.g. DC ripple free).
+
+                       +-----------+
+                       |   Line    |
+                       |  Buffer   |
+                       +-----------+
+                             ^
+                             |
+                             V
+                 |\    +-----------+
+           ------+ |   |           |
+          |      | +-->| Vertical  |----
+          |  ----+ |   |  Scaler   |    |
+          | |    |/    +-----------+    |
+          | |                           |
+          | |                           |
+          | |                           |     |\
+          |  ------------- -------------+-----+ |
+  Input --+               X                   | +--> Output
+          |  ------------- -------------+-----+ |
+          | |                           |     |/
+          | |                           |
+          | |    |\    +-----------+    |
+          |  ----+ |   |           |    |
+          |      | +-->| Horizontal|----
+           ------+ |   |  Scaler   |
+                 |/    +-----------+
+
+  The unit supports downscaling, upscaling, sub pixel translation and bob
+  de-interlacing.
+
+  Each Scaling Engine device should have an alias in the aliases node, in the
+  form of dc<x>-<y>scaler<z>, where <x> is an integer specifying the Display
+  Controller instance, <y> specifies scaling type(either "h" for horizontal
+  scaler or "v" for vertical scaler) and <z> is an integer specifying the
+  Scaling Engine device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-hscaler
+      - fsl,imx8qxp-dc-vscaler
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    hscaler at 561808c0 {
+        compatible = "fsl,imx8qxp-dc-hscaler";
+        reg = <0x561808c0 0x10>, <0x56183000 0x18>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
new file mode 100644
index 000000000000..5403e3359fcb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-signature.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Signature Unit
+
+description: |
+  In order to control the correctness of display output, signature values can
+  be computed for each frame and compared against reference values. In case of
+  a mismatch (signature violation) a HW event can be triggered, for example a
+  SW interrupt.
+
+  This unit supports signature computation, reference check, evaluation windows,
+  alpha masking and panic modes.
+
+  Each Signature Unit device should have an alias in the aliases node, in the
+  form of dc<x>-signature<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Signature Unit device
+  instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-signature
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: valid
+      - const: error
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    signature at 5618d000 {
+        compatible = "fsl,imx8qxp-dc-signature";
+        reg = <0x5618d000 0x140>;
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <22>, <23>, <24>;
+        interrupt-names = "shdload", "valid", "error";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
new file mode 100644
index 000000000000..38d86e3dd6b1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-store.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Store Unit
+
+description: |
+  The Store unit is the interface between the internal pixel processing
+  pipeline, which is 30-bit RGB plus 8-bit Alpha, and the AXI bus for
+  destination buffer access. It is used for the destination of Blit Engines.
+  It comprises a set of built-in functions to generate a wide range of buffer
+  formats. Note, that these are exactly inverse to corresponding functions in
+  the Fetch Unit.
+
+  +------X-------------------------+
+  |      |              Store Unit |
+  |      V                         |
+  |  +-------+                     |
+  |  | Gamma | Gamma apply         |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Color | RGB to YUV          |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Chroma| YUV444 to 422       |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Reduce| Bit width reduction |
+  |  |       | dithering           |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Pack  | RGBA/YUV to RAW     |
+  |  | Encode| or Compression      |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  +------X-------------------------+
+
+  Each Store Unit device should have an alias in the aliases node, in the form
+  of dc<x>-store<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the Store Unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-store
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: framecomplete
+      - const: seqcomplete
+
+  fsl,lts:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Optional Linear Tile Store associated with the Store Unit.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    store at 56180940 {
+        compatible = "fsl,imx8qxp-dc-store";
+        reg = <0x56180940 0x1c>, <0x56184000 0x5c>;
+        reg-names = "pec", "cfg";
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <0>, <1>, <2>;
+        interrupt-names = "shdload", "framecomplete", "seqcomplete";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
new file mode 100644
index 000000000000..87f02d92d55e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-tcon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Timing Controller
+
+description: |
+  The TCon can generate a wide range of customized synchronization signals and
+  does the mapping of the color bits to the output.
+
+  Each Timing Controller device should have an alias in the aliases node, in the
+  form of dc<x>-tcon<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Timing Controller
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-tcon
+
+  reg:
+    maxItems: 1
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description: video output
+
+required:
+  - compatible
+  - reg
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    tcon at 5618c800 {
+        compatible = "fsl,imx8qxp-dc-tcon";
+        reg = <0x5618c800 0x588>;
+
+        port {
+            dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
+                remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
+            };
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:28 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:28 +0800
Subject: [PATCH v5 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-13-victor.liu@nxp.com>

i.MX8qxp Display Controller(DC) is comprised of three main components that
include a blit engine for 2D graphics accelerations, display controller for
display output processing, as well as a command sequencer.  Add kernel
mode setting support for the display controller part with two CRTCs and
two primary planes(backed by FetchLayer and FetchWarp respectively).  The
registers of the display controller are accessed without command sequencer
involved, instead just by using CPU.  The command sequencer is supposed to
be used by the blit engine.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* Replace .remove_new with .remove in dc-drv.c. (Uwe)

v4:
* Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
  function calls from KMS routine to initialization stage. (Dmitry)
* Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
  appropriate .h header files or .c source files. (Dmitry)
* Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
* Drop dc_drm->pe_rpm_count. (Dmitry)
* Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
* Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
  Instead, put it in struct dc_crtc.  (Dmitry)
* Call devm_request_irq() to request IRQs, instead of using drmm action.
  (Dmitry)
* Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
* Select DRM_CLIENT_SELECTION due to rebase.
* Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
* Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
* Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
  rebase.
* Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
  register dc_drm_component_unbind_all() action.
* Request interrupts in dc_crtc_post_init() after encoder initialization to
  make sure next bridge is found first.

v3:
* No change.

v2:
* Find next bridge from TCon's port.
* Drop drm/drm_module.h include from dc-drv.c.

 drivers/gpu/drm/imx/dc/Kconfig    |   5 +
 drivers/gpu/drm/imx/dc/Makefile   |   5 +-
 drivers/gpu/drm/imx/dc/dc-crtc.c  | 558 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
 drivers/gpu/drm/imx/dc/dc-drv.c   | 244 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-drv.h   |  19 +
 drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
 drivers/gpu/drm/imx/dc/dc-kms.h   |  58 ++++
 drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
 9 files changed, 1274 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c

diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
index 1fc84c7475de..415993207f2e 100644
--- a/drivers/gpu/drm/imx/dc/Kconfig
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -1,6 +1,11 @@
 config DRM_IMX8_DC
 	tristate "Freescale i.MX8 Display Controller Graphics"
 	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
+	select DRM_CLIENT_SELECTION
+	select DRM_GEM_DMA_HELPER
+	select DRM_KMS_HELPER
+	select DRM_DISPLAY_HELPER
+	select DRM_BRIDGE_CONNECTOR
 	select GENERIC_IRQ_CHIP
 	select REGMAP
 	select REGMAP_MMIO
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index 1ce3e8a8db22..b9d33c074984 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
-imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
-		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
+imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
+		    dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
+		    dc-plane.o dc-tc.o
 
 obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
new file mode 100644
index 000000000000..fd6daa1807d8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/completion.h>
+#include <linux/container_of.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/pm_runtime.h>
+#include <linux/spinlock.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_device.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_print.h>
+#include <drm/drm_vblank.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+#include "dc-kms.h"
+#include "dc-pe.h"
+
+#define dc_crtc_dbg(crtc, fmt, ...)					\
+do {									\
+	typeof(crtc) _crtc = (crtc);					\
+	drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
+		    _crtc->base.id, _crtc->name, ##__VA_ARGS__);	\
+} while (0)
+
+#define dc_crtc_err(crtc, fmt, ...)					\
+do {									\
+	typeof(crtc) _crtc = (crtc);					\
+	drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
+		_crtc->base.id, _crtc->name, ##__VA_ARGS__);		\
+} while (0)
+
+#define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c)				\
+do {									\
+	unsigned long ret;						\
+	ret = wait_for_completion_timeout(&dc_crtc->c, HZ);		\
+	if (ret == 0)							\
+		dc_crtc_err(crtc, "%s: wait for " #c " timeout\n",	\
+							__func__);	\
+} while (0)
+
+#define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg)					\
+do {									\
+	typeof(fg) _fg = (fg);						\
+	if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) {		\
+		dc_fg_secondary_clear_channel_status(_fg);		\
+		dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n",		\
+							__func__);	\
+	}								\
+} while (0)
+
+#define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg)			\
+do {									\
+	if (dc_fg_wait_for_secondary_syncup(fg))			\
+		dc_crtc_err(crtc,					\
+			"%s: FrameGen secondary channel isn't syncup\n",\
+							__func__);	\
+} while (0)
+
+static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct dc_crtc, base);
+}
+
+static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	return dc_fg_get_frame_index(dc_crtc->fg);
+}
+
+static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	enable_irq(dc_crtc->irq_dec_framecomplete);
+
+	return 0;
+}
+
+static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	disable_irq_nosync(dc_crtc->irq_dec_framecomplete);
+}
+
+static irqreturn_t
+dc_crtc_dec_framecomplete_irq_handler(int irq, void *dev_id)
+{
+	struct dc_crtc *dc_crtc = dev_id;
+	struct drm_crtc *crtc = &dc_crtc->base;
+	unsigned long flags;
+
+	drm_crtc_handle_vblank(crtc);
+
+	spin_lock_irqsave(&crtc->dev->event_lock, flags);
+	if (dc_crtc->event) {
+		drm_crtc_send_vblank_event(crtc, dc_crtc->event);
+		dc_crtc->event = NULL;
+		drm_crtc_vblank_put(crtc);
+	}
+	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dc_crtc_common_irq_handler(int irq, void *dev_id)
+{
+	struct dc_crtc *dc_crtc = dev_id;
+
+	if (irq == dc_crtc->irq_dec_seqcomplete)
+		complete(&dc_crtc->dec_seqcomplete_done);
+	else if (irq == dc_crtc->irq_dec_shdld)
+		complete(&dc_crtc->dec_shdld_done);
+	else if (irq == dc_crtc->irq_ed_cont_shdld)
+		complete(&dc_crtc->ed_cont_shdld_done);
+	else if (irq == dc_crtc->irq_ed_safe_shdld)
+		complete(&dc_crtc->ed_safe_shdld_done);
+
+	return IRQ_HANDLED;
+}
+
+static const struct drm_crtc_funcs dc_crtc_funcs = {
+	.reset			= drm_atomic_helper_crtc_reset,
+	.destroy		= drm_crtc_cleanup,
+	.set_config		= drm_atomic_helper_set_config,
+	.page_flip		= drm_atomic_helper_page_flip,
+	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
+	.get_vblank_counter	= dc_crtc_get_vblank_counter,
+	.enable_vblank		= dc_crtc_enable_vblank,
+	.disable_vblank		= dc_crtc_disable_vblank,
+	.get_vblank_timestamp	= drm_crtc_vblank_helper_get_vblank_timestamp,
+};
+
+static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
+{
+	struct drm_crtc *crtc = crtc_state->crtc;
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	spin_lock_irq(&crtc->dev->event_lock);
+	if (crtc_state->event) {
+		WARN_ON(drm_crtc_vblank_get(crtc));
+		WARN_ON(dc_crtc->event);
+		dc_crtc->event = crtc_state->event;
+		crtc_state->event = NULL;
+	}
+	spin_unlock_irq(&crtc->dev->event_lock);
+}
+
+static enum drm_mode_status
+dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
+{
+	return dc_fg_check_clock(dc_crtc->fg, clk_khz);
+}
+
+static enum drm_mode_status
+dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	enum drm_mode_status status;
+
+	status = dc_crtc_check_clock(dc_crtc, mode->clock);
+	if (status != MODE_OK)
+		return status;
+
+	if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static int
+dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	enum drm_mode_status status;
+
+	status = dc_crtc_check_clock(dc_crtc, adj->clock);
+	if (status != MODE_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void
+dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int idx, ret;
+
+	if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
+	    !new_crtc_state->active)
+		return;
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		return;
+
+	/* request pixel engine power-on when CRTC starts to be active */
+	ret = pm_runtime_resume_and_get(dc_crtc->pe->dev);
+	if (ret)
+		dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
+			    ret);
+
+	drm_dev_exit(idx);
+}
+
+static void
+dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *old_crtc_state =
+				drm_atomic_get_old_crtc_state(state, crtc);
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int idx;
+
+	if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
+	    (!old_crtc_state->active && !new_crtc_state->active))
+		return;
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		goto out;
+
+	enable_irq(dc_crtc->irq_ed_cont_shdld);
+
+	/* flush plane update out to display */
+	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
+
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
+
+	disable_irq(dc_crtc->irq_ed_cont_shdld);
+
+	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
+
+	drm_dev_exit(idx);
+
+out:
+	dc_crtc_queue_state_event(new_crtc_state);
+}
+
+static void
+dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	enum dc_link_id cf_link;
+	int idx, ret;
+
+	dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
+
+	drm_crtc_vblank_on(crtc);
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		goto out;
+
+	/* request display engine power-on when CRTC is enabled */
+	ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
+	if (ret < 0)
+		dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
+			    ret);
+
+	enable_irq(dc_crtc->irq_dec_shdld);
+	enable_irq(dc_crtc->irq_ed_cont_shdld);
+	enable_irq(dc_crtc->irq_ed_safe_shdld);
+
+	dc_fg_cfg_videomode(dc_crtc->fg, adj);
+
+	dc_cf_framedimensions(dc_crtc->cf_cont,
+			      adj->crtc_hdisplay, adj->crtc_vdisplay);
+	dc_cf_framedimensions(dc_crtc->cf_safe,
+			      adj->crtc_hdisplay, adj->crtc_vdisplay);
+
+	/* constframe in safety stream shows blue frame */
+	dc_cf_constantcolor_blue(dc_crtc->cf_safe);
+	cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
+	dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
+
+	/* show CRTC background if no plane is enabled */
+	if (new_crtc_state->plane_mask == 0) {
+		/* constframe in content stream shows black frame */
+		dc_cf_constantcolor_black(dc_crtc->cf_cont);
+
+		cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
+		dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
+	}
+
+	dc_fg_enable_clock(dc_crtc->fg);
+	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
+	dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
+	dc_fg_shdtokgen(dc_crtc->fg);
+	dc_fg_enable(dc_crtc->fg);
+
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdld_done);
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdld_done);
+
+	disable_irq(dc_crtc->irq_ed_safe_shdld);
+	disable_irq(dc_crtc->irq_ed_cont_shdld);
+	disable_irq(dc_crtc->irq_dec_shdld);
+
+	DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
+
+	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
+
+	drm_dev_exit(idx);
+
+out:
+	dc_crtc_queue_state_event(new_crtc_state);
+}
+
+static void
+dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int idx, ret;
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		goto out;
+
+	enable_irq(dc_crtc->irq_dec_seqcomplete);
+	dc_fg_disable(dc_crtc->fg);
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
+	disable_irq(dc_crtc->irq_dec_seqcomplete);
+
+	dc_fg_disable_clock(dc_crtc->fg);
+
+	/* request pixel engine power-off as plane is off too */
+	ret = pm_runtime_put(dc_crtc->pe->dev);
+	if (ret)
+		dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
+			    ret);
+
+	/* request display engine power-off when CRTC is disabled */
+	ret = pm_runtime_put(dc_crtc->de->dev);
+	if (ret < 0)
+		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
+			    ret);
+
+	drm_dev_exit(idx);
+
+out:
+	drm_crtc_vblank_off(crtc);
+
+	spin_lock_irq(&crtc->dev->event_lock);
+	if (new_crtc_state->event && !new_crtc_state->active) {
+		drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
+		new_crtc_state->event = NULL;
+	}
+	spin_unlock_irq(&crtc->dev->event_lock);
+}
+
+void dc_crtc_disable_at_unbind(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int ret;
+
+	if (!dc_fg_wait_for_frame_index_moving(dc_crtc->fg))
+		return;
+
+	dc_fg_disable_clock(dc_crtc->fg);
+
+	if (pm_runtime_active(dc_crtc->pe->dev)) {
+		ret = pm_runtime_put_sync(dc_crtc->pe->dev);
+		if (ret)
+			dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
+				    ret);
+	}
+
+	ret = pm_runtime_put_sync(dc_crtc->de->dev);
+	if (ret < 0)
+		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
+			    ret);
+}
+
+static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
+					 bool in_vblank_irq,
+					 int *vpos, int *hpos,
+					 ktime_t *stime, ktime_t *etime,
+					 const struct drm_display_mode *mode)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int vdisplay = mode->crtc_vdisplay;
+	int vtotal = mode->crtc_vtotal;
+	bool reliable;
+	int line;
+	int idx;
+
+	if (stime)
+		*stime = ktime_get();
+
+	if (!drm_dev_enter(crtc->dev, &idx)) {
+		reliable = false;
+		*vpos = 0;
+		*hpos = 0;
+		goto out;
+	}
+
+	/* line index starts with 0 for the first active output line */
+	line = dc_fg_get_line_index(dc_crtc->fg);
+
+	if (line < vdisplay)
+		/* active scanout area - positive */
+		*vpos = line + 1;
+	else
+		/* inside vblank - negative */
+		*vpos = line - (vtotal - 1);
+
+	*hpos = 0;
+
+	reliable = true;
+
+	drm_dev_exit(idx);
+out:
+	if (etime)
+		*etime = ktime_get();
+
+	return reliable;
+}
+
+static const struct drm_crtc_helper_funcs dc_helper_funcs = {
+	.mode_valid		= dc_crtc_mode_valid,
+	.atomic_check		= dc_crtc_atomic_check,
+	.atomic_begin		= dc_crtc_atomic_begin,
+	.atomic_flush		= dc_crtc_atomic_flush,
+	.atomic_enable		= dc_crtc_atomic_enable,
+	.atomic_disable		= dc_crtc_atomic_disable,
+	.get_scanout_position	= dc_crtc_get_scanout_position,
+};
+
+static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
+{
+	struct {
+		struct device *dev;
+		unsigned int irq;
+		irqreturn_t (*irq_handler)(int irq, void *dev_id);
+	} irqs[DC_CRTC_IRQS] = {
+		{
+			dc_crtc->de->dev,
+			dc_crtc->irq_dec_framecomplete,
+			dc_crtc_dec_framecomplete_irq_handler,
+		}, {
+			dc_crtc->de->dev,
+			dc_crtc->irq_dec_seqcomplete,
+			dc_crtc_common_irq_handler,
+		}, {
+			dc_crtc->de->dev,
+			dc_crtc->irq_dec_shdld,
+			dc_crtc_common_irq_handler,
+		}, {
+			dc_crtc->ed_cont->dev,
+			dc_crtc->irq_ed_cont_shdld,
+			dc_crtc_common_irq_handler,
+		}, {
+			dc_crtc->ed_safe->dev,
+			dc_crtc->irq_ed_safe_shdld,
+			dc_crtc_common_irq_handler,
+		},
+	};
+	int i, ret;
+
+	for (i = 0; i < DC_CRTC_IRQS; i++) {
+		struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
+
+		ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
+				       irqs[i].irq_handler, IRQF_NO_AUTOEN,
+				       dev_name(irqs[i].dev), dc_crtc);
+		if (ret) {
+			dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
+				irqs[i].irq, ret);
+			return ret;
+		}
+
+		irq->dc_crtc = dc_crtc;
+		irq->irq = irqs[i].irq;
+	}
+
+	return 0;
+}
+
+int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
+{
+	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
+	struct drm_device *drm = &dc_drm->base;
+	struct dc_de *de = dc_drm->de[crtc_index];
+	struct dc_pe *pe = dc_drm->pe;
+	struct dc_plane *dc_primary;
+	int ret;
+
+	dc_crtc->de = de;
+	dc_crtc->pe = pe;
+
+	init_completion(&dc_crtc->dec_seqcomplete_done);
+	init_completion(&dc_crtc->dec_shdld_done);
+	init_completion(&dc_crtc->ed_cont_shdld_done);
+	init_completion(&dc_crtc->ed_safe_shdld_done);
+
+	dc_crtc->cf_cont = pe->cf_cont[crtc_index];
+	dc_crtc->cf_safe = pe->cf_safe[crtc_index];
+	dc_crtc->ed_cont = pe->ed_cont[crtc_index];
+	dc_crtc->ed_safe = pe->ed_safe[crtc_index];
+	dc_crtc->fg = de->fg;
+
+	dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
+	dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
+	dc_crtc->irq_dec_shdld = de->irq_shdld;
+	dc_crtc->irq_ed_safe_shdld = dc_crtc->ed_safe->irq_shdld;
+	dc_crtc->irq_ed_cont_shdld = dc_crtc->ed_cont->irq_shdld;
+
+	dc_primary = &dc_drm->dc_primary[crtc_index];
+	ret = dc_plane_init(dc_drm, dc_primary);
+	if (ret) {
+		dev_err(drm->dev,
+			"failed to init primary plane for display engine%u: %d\n",
+			de->id, ret);
+		return ret;
+	}
+
+	drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
+
+	ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
+					NULL, &dc_crtc_funcs, NULL);
+	if (ret)
+		dev_err(drm->dev,
+			"failed to add CRTC for display engine%u: %d\n",
+			de->id, ret);
+
+	return ret;
+}
+
+int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
+{
+	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
+	struct drm_device *drm = &dc_drm->base;
+
+	return dc_crtc_request_irqs(drm, dc_crtc);
+}
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
index 17a44362118e..8a7b6c03a222 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.h
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -13,6 +13,9 @@
 
 #define DC_DISPLAYS	2
 
+#define DC_FRAMEGEN_MAX_FRAME_INDEX	0x3ffff
+#define DC_FRAMEGEN_MAX_CLOCK_KHZ	300000
+
 struct dc_fg {
 	struct device *dev;
 	struct regmap *reg;
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index fd68861f770a..1e4b8afa3eec 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -3,11 +3,254 @@
  * Copyright 2024 NXP
  */
 
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
 
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_client_setup.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fbdev_dma.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_modeset_helper.h>
+#include <drm/drm_of.h>
+
+#include "dc-de.h"
 #include "dc-drv.h"
 
+struct dc_priv {
+	struct drm_device *drm;
+	struct clk *clk_cfg;
+};
+
+DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
+
+static struct drm_driver dc_drm_driver = {
+	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
+	DRM_GEM_DMA_DRIVER_OPS,
+	DRM_FBDEV_DMA_DRIVER_OPS,
+	.fops = &dc_drm_driver_fops,
+	.name = "imx8-dc",
+	.desc = "i.MX8 DC DRM graphics",
+	.date = "20240530",
+	.major = 1,
+	.minor = 0,
+	.patchlevel = 0,
+};
+
+static void
+dc_add_components(struct device *dev, struct component_match **matchptr)
+{
+	struct device_node *child, *grandchild;
+
+	for_each_available_child_of_node(dev->of_node, child) {
+		/* The interrupt controller is not a component. */
+		if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
+			continue;
+
+		drm_of_component_match_add(dev, matchptr, component_compare_of,
+					   child);
+
+		for_each_available_child_of_node(child, grandchild)
+			drm_of_component_match_add(dev, matchptr,
+						   component_compare_of,
+						   grandchild);
+	}
+}
+
+static void dc_drm_component_unbind_all(void *ptr)
+{
+	struct dc_drm_device *dc_drm = ptr;
+	struct drm_device *drm = &dc_drm->base;
+
+	component_unbind_all(drm->dev, dc_drm);
+}
+
+static int dc_drm_bind(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+	struct dc_drm_device *dc_drm;
+	struct drm_device *drm;
+	int ret;
+
+	dc_drm = devm_drm_dev_alloc(dev, &dc_drm_driver, struct dc_drm_device,
+				    base);
+	if (IS_ERR(dc_drm))
+		return PTR_ERR(dc_drm);
+
+	drm = &dc_drm->base;
+
+	ret = component_bind_all(dev, dc_drm);
+	if (ret)
+		return ret;
+
+	ret = devm_add_action_or_reset(dev, dc_drm_component_unbind_all,
+				       dc_drm);
+	if (ret)
+		return ret;
+
+	ret = dc_kms_init(dc_drm);
+	if (ret)
+		return ret;
+
+	ret = drm_dev_register(drm, 0);
+	if (ret) {
+		dev_err(dev, "failed to register drm device: %d\n", ret);
+		goto err;
+	}
+
+	drm_client_setup_with_fourcc(drm, DRM_FORMAT_XRGB8888);
+
+	priv->drm = drm;
+
+	return 0;
+
+err:
+	dc_kms_uninit(dc_drm);
+
+	return ret;
+}
+
+static void dc_drm_unbind(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+	struct dc_drm_device *dc_drm = to_dc_drm_device(priv->drm);
+	struct drm_device *drm = &dc_drm->base;
+	struct drm_crtc *crtc;
+
+	priv->drm = NULL;
+	drm_dev_unplug(drm);
+	dc_kms_uninit(dc_drm);
+	drm_atomic_helper_shutdown(drm);
+
+	drm_for_each_crtc(crtc, drm)
+		dc_crtc_disable_at_unbind(crtc);
+}
+
+static const struct component_master_ops dc_drm_ops = {
+	.bind = dc_drm_bind,
+	.unbind = dc_drm_unbind,
+};
+
+static int dc_probe(struct platform_device *pdev)
+{
+	struct component_match *match = NULL;
+	struct dc_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->clk_cfg))
+		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
+				     "failed to get cfg clock\n");
+
+	dev_set_drvdata(&pdev->dev, priv);
+
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret)
+		return ret;
+
+	dc_add_components(&pdev->dev, &match);
+
+	ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component master\n");
+
+	return 0;
+}
+
+static void dc_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &dc_drm_ops);
+}
+
+static int dc_runtime_suspend(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(priv->clk_cfg);
+
+	return 0;
+}
+
+static int dc_runtime_resume(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(priv->clk_cfg);
+	if (ret)
+		dev_err(dev, "failed to enable cfg clock: %d\n", ret);
+
+	return ret;
+}
+
+static int dc_suspend(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+
+	return drm_mode_config_helper_suspend(priv->drm);
+}
+
+static int dc_resume(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+
+	return drm_mode_config_helper_resume(priv->drm);
+}
+
+static void dc_shutdown(struct platform_device *pdev)
+{
+	struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
+
+	drm_atomic_helper_shutdown(priv->drm);
+}
+
+static const struct dev_pm_ops dc_pm_ops = {
+	RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
+	SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
+};
+
+static const struct of_device_id dc_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_dt_ids);
+
+static struct platform_driver dc_driver = {
+	.probe = dc_probe,
+	.remove = dc_remove,
+	.shutdown = dc_shutdown,
+	.driver = {
+		.name = "imx8-dc",
+		.of_match_table	= dc_dt_ids,
+		.pm = pm_sleep_ptr(&dc_pm_ops),
+	},
+};
+
 static struct platform_driver * const dc_drivers[] = {
 	&dc_cf_driver,
 	&dc_de_driver,
@@ -19,6 +262,7 @@ static struct platform_driver * const dc_drivers[] = {
 	&dc_lb_driver,
 	&dc_pe_driver,
 	&dc_tc_driver,
+	&dc_driver,
 };
 
 static int __init dc_drm_init(void)
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index 3b11f4862c6c..39a771a13933 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -6,19 +6,38 @@
 #ifndef __DC_DRV_H__
 #define __DC_DRV_H__
 
+#include <linux/container_of.h>
 #include <linux/platform_device.h>
 
 #include <drm/drm_device.h>
+#include <drm/drm_encoder.h>
 
 #include "dc-de.h"
+#include "dc-kms.h"
 #include "dc-pe.h"
 
 struct dc_drm_device {
 	struct drm_device base;
+	struct dc_crtc dc_crtc[DC_DISPLAYS];
+	struct dc_plane dc_primary[DC_DISPLAYS];
+	struct drm_encoder encoder[DC_DISPLAYS];
 	struct dc_de *de[DC_DISPLAYS];
 	struct dc_pe *pe;
 };
 
+static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
+{
+	return container_of(drm, struct dc_drm_device, base);
+}
+
+int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
+int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
+
+int dc_kms_init(struct dc_drm_device *dc_drm);
+void dc_kms_uninit(struct dc_drm_device *dc_drm);
+
+int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
+
 extern struct platform_driver dc_cf_driver;
 extern struct platform_driver dc_ed_driver;
 extern struct platform_driver dc_de_driver;
diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
new file mode 100644
index 000000000000..2b18aa37a4a8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-kms.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/of.h>
+#include <linux/of_graph.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_device.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_mode_config.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_vblank.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+#include "dc-kms.h"
+
+static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
+	.fb_create = drm_gem_fb_create,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
+};
+
+static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
+					int crtc_index)
+{
+	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
+	struct drm_device *drm = &dc_drm->base;
+	struct drm_crtc *crtc = &dc_crtc->base;
+	struct drm_connector *connector;
+	struct device *dev = drm->dev;
+	struct drm_encoder *encoder;
+	struct drm_bridge *bridge;
+	int ret;
+
+	bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
+					0, 0);
+	if (IS_ERR(bridge)) {
+		ret = PTR_ERR(bridge);
+		if (ret == -ENODEV)
+			return 0;
+
+		return dev_err_probe(dev, ret,
+				     "failed to find bridge for CRTC%u\n",
+				     crtc->index);
+	}
+
+	encoder = &dc_drm->encoder[crtc_index];
+	ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
+	if (ret) {
+		dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
+			crtc->index, ret);
+		return ret;
+	}
+
+	encoder->possible_crtcs = drm_crtc_mask(crtc);
+
+	ret = drm_bridge_attach(encoder, bridge, NULL,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret) {
+		dev_err(dev,
+			"failed to attach bridge to encoder for CRTC%u: %d\n",
+			crtc->index, ret);
+		return ret;
+	}
+
+	connector = drm_bridge_connector_init(drm, encoder);
+	if (IS_ERR(connector)) {
+		ret = PTR_ERR(connector);
+		dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
+			crtc->index, ret);
+		return ret;
+	}
+
+	ret = drm_connector_attach_encoder(connector, encoder);
+	if (ret)
+		dev_err(dev,
+			"failed to attach encoder to connector for CRTC%u: %d\n",
+			crtc->index, ret);
+
+	return ret;
+}
+
+int dc_kms_init(struct dc_drm_device *dc_drm)
+{
+	struct drm_device *drm = &dc_drm->base;
+	int ret, i;
+
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
+
+	drm->mode_config.min_width = 60;
+	drm->mode_config.min_height = 60;
+	drm->mode_config.max_width = 8192;
+	drm->mode_config.max_height = 8192;
+	drm->mode_config.funcs = &dc_drm_mode_config_funcs;
+
+	drm->vblank_disable_immediate = true;
+	drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
+
+	for (i = 0; i < DC_DISPLAYS; i++) {
+		ret = dc_crtc_init(dc_drm, i);
+		if (ret)
+			return ret;
+
+		ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < DC_DISPLAYS; i++) {
+		ret = dc_crtc_post_init(dc_drm, i);
+		if (ret)
+			return ret;
+	}
+
+	ret = drm_vblank_init(drm, DC_DISPLAYS);
+	if (ret) {
+		dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
+		return ret;
+	}
+
+	drm_mode_config_reset(drm);
+
+	drm_kms_helper_poll_init(drm);
+
+	return 0;
+}
+
+void dc_kms_uninit(struct dc_drm_device *dc_drm)
+{
+	drm_kms_helper_poll_fini(&dc_drm->base);
+}
diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
new file mode 100644
index 000000000000..57f6e0c15f57
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-kms.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_KMS_H__
+#define __DC_KMS_H__
+
+#include <linux/completion.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_vblank.h>
+
+#include "dc-de.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+#define DC_CRTC_IRQS	5
+
+struct dc_crtc_irq {
+	struct dc_crtc *dc_crtc;
+	unsigned int irq;
+};
+
+struct dc_crtc {
+	struct drm_crtc base;
+	struct dc_de *de;
+	struct dc_pe *pe;
+	struct dc_cf *cf_cont;
+	struct dc_cf *cf_safe;
+	struct dc_ed *ed_cont;
+	struct dc_ed *ed_safe;
+	struct dc_fg *fg;
+	unsigned int irq_dec_framecomplete;
+	unsigned int irq_dec_seqcomplete;
+	unsigned int irq_dec_shdld;
+	unsigned int irq_ed_cont_shdld;
+	unsigned int irq_ed_safe_shdld;
+	struct completion dec_seqcomplete_done;
+	struct completion dec_shdld_done;
+	struct completion ed_safe_shdld_done;
+	struct completion ed_cont_shdld_done;
+	struct drm_pending_vblank_event *event;
+	struct dc_crtc_irq irqs[DC_CRTC_IRQS];
+};
+
+struct dc_plane {
+	struct drm_plane base;
+	struct dc_fu *fu;
+	struct dc_cf *cf;
+	struct dc_lb *lb;
+	struct dc_ed *ed;
+};
+
+void dc_crtc_disable_at_unbind(struct drm_crtc *crtc);
+
+#endif /* __DC_KMS_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
new file mode 100644
index 000000000000..78d0d2cd3451
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-plane.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/container_of.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fb_dma_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_print.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-kms.h"
+
+#define DC_PLANE_MAX_PITCH	0x10000
+#define DC_PLANE_MAX_PIX_CNT	8192
+
+#define dc_plane_dbg(plane, fmt, ...)					\
+do {									\
+	typeof(plane) _plane = (plane);					\
+	drm_dbg_kms(_plane->dev, "[PLANE:%d:%s] " fmt,			\
+		    _plane->base.id, _plane->name, ##__VA_ARGS__);	\
+} while (0)
+
+static const uint32_t dc_plane_formats[] = {
+	DRM_FORMAT_XRGB8888,
+};
+
+static const struct drm_plane_funcs dc_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,
+};
+
+static inline struct dc_plane *to_dc_plane(struct drm_plane *plane)
+{
+	return container_of(plane, struct dc_plane, base);
+}
+
+static int dc_plane_check_no_off_screen(struct drm_plane_state *state,
+					struct drm_crtc_state *crtc_state)
+{
+	if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
+	    state->dst.x2 > crtc_state->adjusted_mode.hdisplay ||
+	    state->dst.y2 > crtc_state->adjusted_mode.vdisplay) {
+		dc_plane_dbg(state->plane, "no off screen\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dc_plane_check_max_source_resolution(struct drm_plane_state *state)
+{
+	int src_h = drm_rect_height(&state->src) >> 16;
+	int src_w = drm_rect_width(&state->src) >> 16;
+
+	if (src_w > DC_PLANE_MAX_PIX_CNT || src_h > DC_PLANE_MAX_PIX_CNT) {
+		dc_plane_dbg(state->plane, "invalid source resolution\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dc_plane_check_fb(struct drm_plane_state *state)
+{
+	struct drm_framebuffer *fb = state->fb;
+	dma_addr_t baseaddr = drm_fb_dma_get_gem_addr(fb, state, 0);
+
+	/* base address alignment */
+	if (baseaddr & 0x3) {
+		dc_plane_dbg(state->plane, "fb bad baddr alignment\n");
+		return -EINVAL;
+	}
+
+	/* pitches[0] range */
+	if (fb->pitches[0] > DC_PLANE_MAX_PITCH) {
+		dc_plane_dbg(state->plane, "fb pitches[0] is out of range\n");
+		return -EINVAL;
+	}
+
+	/* pitches[0] alignment */
+	if (fb->pitches[0] & 0x3) {
+		dc_plane_dbg(state->plane, "fb bad pitches[0] alignment\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+dc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
+{
+	struct drm_plane_state *plane_state =
+				drm_atomic_get_new_plane_state(state, plane);
+	struct drm_crtc_state *crtc_state;
+	int ret;
+
+	/* ok to disable */
+	if (!plane_state->fb)
+		return 0;
+
+	if (!plane_state->crtc) {
+		dc_plane_dbg(plane, "no CRTC in plane state\n");
+		return -EINVAL;
+	}
+
+	crtc_state =
+		drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return -EINVAL;
+
+	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
+						  DRM_PLANE_NO_SCALING,
+						  DRM_PLANE_NO_SCALING,
+						  true, false);
+	if (ret) {
+		dc_plane_dbg(plane, "failed to check plane state: %d\n", ret);
+		return ret;
+	}
+
+	ret = dc_plane_check_no_off_screen(plane_state, crtc_state);
+	if (ret)
+		return ret;
+
+	ret = dc_plane_check_max_source_resolution(plane_state);
+	if (ret)
+		return ret;
+
+	return dc_plane_check_fb(plane_state);
+}
+
+static void
+dc_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_state =
+				drm_atomic_get_new_plane_state(state, plane);
+	struct dc_plane *dplane = to_dc_plane(plane);
+	struct drm_framebuffer *fb = new_state->fb;
+	const struct dc_fu_ops *fu_ops;
+	struct dc_lb *lb = dplane->lb;
+	struct dc_fu *fu = dplane->fu;
+	dma_addr_t baseaddr;
+	int src_w, src_h;
+	int idx;
+
+	if (!drm_dev_enter(plane->dev, &idx))
+		return;
+
+	src_w = drm_rect_width(&new_state->src) >> 16;
+	src_h = drm_rect_height(&new_state->src) >> 16;
+
+	baseaddr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
+
+	fu_ops = dc_fu_get_ops(dplane->fu);
+
+	fu_ops->set_layerblend(fu, lb);
+	fu_ops->set_burstlength(fu, baseaddr);
+	fu_ops->set_src_stride(fu, DC_FETCHUNIT_FRAC0, fb->pitches[0]);
+	fu_ops->set_src_buf_dimensions(fu, DC_FETCHUNIT_FRAC0, src_w, src_h);
+	fu_ops->set_fmt(fu, DC_FETCHUNIT_FRAC0, fb->format);
+	fu_ops->set_framedimensions(fu, src_w, src_h);
+	fu_ops->set_baseaddress(fu, DC_FETCHUNIT_FRAC0, baseaddr);
+	fu_ops->enable_src_buf(fu, DC_FETCHUNIT_FRAC0);
+
+	dc_plane_dbg(plane, "uses %s\n", fu_ops->get_name(fu));
+
+	dc_lb_pec_dynamic_prim_sel(lb, dc_cf_get_link_id(dplane->cf));
+	dc_lb_pec_dynamic_sec_sel(lb, fu_ops->get_link_id(fu));
+	dc_lb_mode(lb, LB_BLEND);
+	dc_lb_position(lb, new_state->dst.x1, new_state->dst.y1);
+	dc_lb_pec_clken(lb, CLKEN_AUTOMATIC);
+
+	dc_plane_dbg(plane, "uses LayerBlend%u\n", dc_lb_get_id(lb));
+
+	/* set ExtDst's source to LayerBlend */
+	dc_ed_pec_src_sel(dplane->ed, dc_lb_get_link_id(lb));
+
+	drm_dev_exit(idx);
+}
+
+static void dc_plane_atomic_disable(struct drm_plane *plane,
+				    struct drm_atomic_state *state)
+{
+	struct dc_plane *dplane = to_dc_plane(plane);
+	const struct dc_fu_ops *fu_ops;
+	int idx;
+
+	if (!drm_dev_enter(plane->dev, &idx))
+		return;
+
+	/* disable fetchunit in shadow */
+	fu_ops = dc_fu_get_ops(dplane->fu);
+	fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
+
+	/* set ExtDst's source to ConstFrame */
+	dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
+
+	drm_dev_exit(idx);
+}
+
+static const struct drm_plane_helper_funcs dc_plane_helper_funcs = {
+	.atomic_check = dc_plane_atomic_check,
+	.atomic_update = dc_plane_atomic_update,
+	.atomic_disable = dc_plane_atomic_disable,
+};
+
+int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
+{
+	struct drm_plane *plane = &dc_plane->base;
+	int ret;
+
+	ret = drm_universal_plane_init(&dc_drm->base, plane, 0, &dc_plane_funcs,
+				       dc_plane_formats,
+				       ARRAY_SIZE(dc_plane_formats),
+				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
+	if (ret)
+		return ret;
+
+	drm_plane_helper_add(plane, &dc_plane_helper_funcs);
+
+	dc_plane->fu = dc_drm->pe->fu_disp[plane->index];
+	dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
+	dc_plane->lb = dc_drm->pe->lb[plane->index];
+	dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
+
+	return 0;
+}
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:26 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:26 +0800
Subject: [PATCH v5 10/19] drm/imx: Add i.MX8qxp Display Controller pixel engine
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-11-victor.liu@nxp.com>

i.MX8qxp Display Controller pixel engine consists of all processing
units that operate in the AXI bus clock domain.  Add drivers for
ConstFrame, ExtDst, FetchLayer, FetchWarp and LayerBlend units, as
well as a pixel engine driver, so that two displays with primary
planes can be supported.  The pixel engine driver and those unit
drivers are components to be aggregated by a master registered in
the upcoming DRM driver.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* Replace .remove_new with .remove in dc-{cf,de,fl,fw,lb,pe}.c. (Uwe)
* Fix commit message to state that pixel engine driver is a component driver
  instead of a master/aggregate driver.

v4:
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Inline some small functions. (Dmitry)
* Move dc_lb_blendcontrol() function call from KMS routine to initialization
  stage. (Dmitry)
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
* Drop unnecessary private struct dc_*_priv.
* Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
  interfaces to bind/unbind the drivers.
* Make some fetch unit operations be aware of fractional fetch unit index(0-7).

v3:
* No change.

v2:
* Use OF alias id to get instance id.

 drivers/gpu/drm/imx/dc/Makefile |   3 +-
 drivers/gpu/drm/imx/dc/dc-cf.c  | 162 ++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-drv.c |   6 +
 drivers/gpu/drm/imx/dc/dc-drv.h |   8 +
 drivers/gpu/drm/imx/dc/dc-ed.c  | 270 +++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-fl.c  | 180 ++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-fu.c  | 268 +++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-fu.h  | 129 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-fw.c  | 219 ++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-lb.c  | 319 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-pe.c  | 133 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-pe.h  | 100 ++++++++++
 12 files changed, 1796 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/imx/dc/dc-cf.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ed.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fl.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fw.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-lb.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.h

diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index 56de82d53d4d..2942ae6fd5bd 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-imx8-dc-drm-objs := dc-de.o dc-drv.o dc-fg.o dc-tc.o
+imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
+		    dc-fw.o dc-lb.o dc-pe.o dc-tc.o
 
 obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
new file mode 100644
index 000000000000..266344054ac6
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-cf.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define STATICCONTROL		0x8
+
+#define FRAMEDIMENSIONS		0xc
+#define  HEIGHT(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  WIDTH(x)		FIELD_PREP(GENMASK(13, 0), ((x) - 1))
+
+#define CONSTANTCOLOR		0x10
+#define  BLUE(x)		FIELD_PREP(GENMASK(15, 8), (x))
+
+static const struct regmap_range dc_cf_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, CONSTANTCOLOR),
+};
+
+static const struct regmap_access_table dc_cf_regmap_access_table = {
+	.yes_ranges = dc_cf_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_cf_regmap_ranges),
+};
+
+static const struct regmap_config dc_cf_cfg_regmap_config = {
+	.name = "constframe-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_cf_regmap_access_table,
+	.rd_table = &dc_cf_regmap_access_table,
+};
+
+static inline void dc_cf_enable_shden(struct dc_cf *cf)
+{
+	regmap_write(cf->reg_cfg, STATICCONTROL, SHDEN);
+}
+
+enum dc_link_id dc_cf_get_link_id(struct dc_cf *cf)
+{
+	return cf->link;
+}
+
+void dc_cf_framedimensions(struct dc_cf *cf, unsigned int w,
+			   unsigned int h)
+{
+	regmap_write(cf->reg_cfg, FRAMEDIMENSIONS, WIDTH(w) | HEIGHT(h));
+}
+
+void dc_cf_constantcolor_black(struct dc_cf *cf)
+{
+	regmap_write(cf->reg_cfg, CONSTANTCOLOR, 0);
+}
+
+void dc_cf_constantcolor_blue(struct dc_cf *cf)
+{
+	regmap_write(cf->reg_cfg, CONSTANTCOLOR, BLUE(0xff));
+}
+
+void dc_cf_init(struct dc_cf *cf)
+{
+	dc_cf_enable_shden(cf);
+}
+
+static int dc_cf_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_cfg;
+	struct dc_cf *cf;
+	int id;
+
+	cf = devm_kzalloc(dev, sizeof(*cf), GFP_KERNEL);
+	if (!cf)
+		return -ENOMEM;
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	cf->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_cf_cfg_regmap_config);
+	if (IS_ERR(cf->reg_cfg))
+		return PTR_ERR(cf->reg_cfg);
+
+	id = of_alias_get_id(dev->of_node, "dc0-constframe");
+	if (id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", id);
+		return id;
+	}
+
+	switch (id) {
+	case 0:
+		pe->cf_cont[0] = cf;
+		cf->link = LINK_ID_CONSTFRAME0;
+		break;
+	case 1:
+		pe->cf_cont[1] = cf;
+		cf->link = LINK_ID_CONSTFRAME1;
+		break;
+	case 4:
+		pe->cf_safe[0] = cf;
+		cf->link = LINK_ID_CONSTFRAME4;
+		break;
+	case 5:
+		pe->cf_safe[1] = cf;
+		cf->link = LINK_ID_CONSTFRAME5;
+		break;
+	}
+
+	return 0;
+}
+
+static const struct component_ops dc_cf_ops = {
+	.bind = dc_cf_bind,
+};
+
+static int dc_cf_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_cf_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_cf_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_cf_ops);
+}
+
+static const struct of_device_id dc_cf_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-constframe", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_cf_dt_ids);
+
+struct platform_driver dc_cf_driver = {
+	.probe = dc_cf_probe,
+	.remove = dc_cf_remove,
+	.driver = {
+		.name = "imx8-dc-constframe",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_cf_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index e5910a82dd4d..7c64acc863ad 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -9,8 +9,14 @@
 #include "dc-drv.h"
 
 static struct platform_driver * const dc_drivers[] = {
+	&dc_cf_driver,
 	&dc_de_driver,
+	&dc_ed_driver,
 	&dc_fg_driver,
+	&dc_fl_driver,
+	&dc_fw_driver,
+	&dc_lb_driver,
+	&dc_pe_driver,
 	&dc_tc_driver,
 };
 
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index e1290d9a0a99..c687a36b8153 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -11,14 +11,22 @@
 #include <drm/drm_device.h>
 
 #include "dc-de.h"
+#include "dc-pe.h"
 
 struct dc_drm_device {
 	struct drm_device base;
 	struct dc_de *de[DC_DISPLAYS];
+	struct dc_pe *pe;
 };
 
+extern struct platform_driver dc_cf_driver;
+extern struct platform_driver dc_ed_driver;
 extern struct platform_driver dc_de_driver;
 extern struct platform_driver dc_fg_driver;
+extern struct platform_driver dc_fl_driver;
+extern struct platform_driver dc_fw_driver;
+extern struct platform_driver dc_lb_driver;
+extern struct platform_driver dc_pe_driver;
 extern struct platform_driver dc_tc_driver;
 
 #endif /* __DC_DRV_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
new file mode 100644
index 000000000000..283777ca7be2
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-ed.c
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_STATIC	0x8
+#define  POWERDOWN		BIT(4)
+#define  SYNC_MODE		BIT(8)
+#define  SINGLE			0
+#define  DIV_MASK		GENMASK(23, 16)
+#define  DIV(x)			FIELD_PREP(DIV_MASK, (x))
+#define  DIV_RESET		0x80
+
+#define PIXENGCFG_DYNAMIC	0xc
+
+#define PIXENGCFG_TRIGGER	0x14
+#define  SYNC_TRIGGER		BIT(0)
+
+#define STATICCONTROL		0x8
+#define  KICK_MODE		BIT(8)
+#define  EXTERNAL		BIT(8)
+#define  PERFCOUNTMODE		BIT(12)
+
+#define CONTROL			0xc
+#define  GAMMAAPPLYENABLE	BIT(0)
+
+static const struct regmap_range dc_ed_pec_regmap_access_ranges[] = {
+	regmap_reg_range(PIXENGCFG_STATIC, PIXENGCFG_STATIC),
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+	regmap_reg_range(PIXENGCFG_TRIGGER, PIXENGCFG_TRIGGER),
+};
+
+static const struct regmap_access_table dc_ed_pec_regmap_access_table = {
+	.yes_ranges = dc_ed_pec_regmap_access_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_pec_regmap_access_ranges),
+};
+
+static const struct regmap_range dc_ed_pec_regmap_volatile_ranges[] = {
+	regmap_reg_range(PIXENGCFG_TRIGGER, PIXENGCFG_TRIGGER),
+};
+
+static const struct regmap_access_table dc_ed_pec_regmap_volatile_table = {
+	.yes_ranges = dc_ed_pec_regmap_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_pec_regmap_volatile_ranges),
+};
+
+static const struct regmap_config dc_ed_pec_regmap_config = {
+	.name = "extdst-pec",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_ed_pec_regmap_access_table,
+	.rd_table = &dc_ed_pec_regmap_access_table,
+	.volatile_table = &dc_ed_pec_regmap_volatile_table,
+};
+
+static const struct regmap_range dc_ed_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, STATICCONTROL),
+	regmap_reg_range(CONTROL, CONTROL),
+};
+
+static const struct regmap_access_table dc_ed_regmap_access_table = {
+	.yes_ranges = dc_ed_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_regmap_ranges),
+};
+
+static const struct regmap_config dc_ed_cfg_regmap_config = {
+	.name = "extdst-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_ed_regmap_access_table,
+	.rd_table = &dc_ed_regmap_access_table,
+};
+
+static const enum dc_link_id src_sels[] = {
+	LINK_ID_NONE,
+	LINK_ID_CONSTFRAME0,
+	LINK_ID_CONSTFRAME1,
+	LINK_ID_CONSTFRAME4,
+	LINK_ID_CONSTFRAME5,
+	LINK_ID_LAYERBLEND3,
+	LINK_ID_LAYERBLEND2,
+	LINK_ID_LAYERBLEND1,
+	LINK_ID_LAYERBLEND0,
+};
+
+static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SHDEN, SHDEN);
+}
+
+static inline void dc_ed_pec_poweron(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, POWERDOWN, 0);
+}
+
+static inline void dc_ed_pec_sync_mode_single(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SYNC_MODE, SINGLE);
+}
+
+static inline void dc_ed_pec_div_reset(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, DIV_MASK,
+			  DIV(DIV_RESET));
+}
+
+void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(src_sels); i++) {
+		if (src_sels[i] == src) {
+			regmap_write(ed->reg_pec, PIXENGCFG_DYNAMIC, src);
+			return;
+		}
+	}
+}
+
+void dc_ed_pec_sync_trigger(struct dc_ed *ed)
+{
+	regmap_write(ed->reg_pec, PIXENGCFG_TRIGGER, SYNC_TRIGGER);
+}
+
+static inline void dc_ed_enable_shden(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_ed_kick_mode_external(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, STATICCONTROL, KICK_MODE, EXTERNAL);
+}
+
+static inline void dc_ed_disable_perfcountmode(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, STATICCONTROL, PERFCOUNTMODE, 0);
+}
+
+static inline void dc_ed_disable_gamma_apply(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, CONTROL, GAMMAAPPLYENABLE, 0);
+}
+
+void dc_ed_init(struct dc_ed *ed)
+{
+	dc_ed_pec_src_sel(ed, LINK_ID_NONE);
+	dc_ed_pec_enable_shden(ed);
+	dc_ed_pec_poweron(ed);
+	dc_ed_pec_sync_mode_single(ed);
+	dc_ed_pec_div_reset(ed);
+	dc_ed_enable_shden(ed);
+	dc_ed_disable_perfcountmode(ed);
+	dc_ed_kick_mode_external(ed);
+	dc_ed_disable_gamma_apply(ed);
+}
+
+static int dc_ed_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_pec;
+	void __iomem *base_cfg;
+	struct dc_ed *ed;
+	int id;
+
+	ed = devm_kzalloc(dev, sizeof(*ed), GFP_KERNEL);
+	if (!ed)
+		return -ENOMEM;
+
+	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
+	if (IS_ERR(base_pec))
+		return PTR_ERR(base_pec);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	ed->reg_pec = devm_regmap_init_mmio(dev, base_pec,
+					    &dc_ed_pec_regmap_config);
+	if (IS_ERR(ed->reg_pec))
+		return PTR_ERR(ed->reg_pec);
+
+	ed->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_ed_cfg_regmap_config);
+	if (IS_ERR(ed->reg_cfg))
+		return PTR_ERR(ed->reg_cfg);
+
+	ed->irq_shdld = platform_get_irq_byname(pdev, "shdload");
+	if (ed->irq_shdld < 0)
+		return ed->irq_shdld;
+
+	id = of_alias_get_id(dev->of_node, "dc0-extdst");
+	if (id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", id);
+		return id;
+	}
+
+	ed->dev = dev;
+
+	switch (id) {
+	case 0:
+		pe->ed_cont[0] = ed;
+		break;
+	case 1:
+		pe->ed_cont[1] = ed;
+		break;
+	case 4:
+		pe->ed_safe[0] = ed;
+		break;
+	case 5:
+		pe->ed_safe[1] = ed;
+		break;
+	}
+
+	return 0;
+}
+
+static const struct component_ops dc_ed_ops = {
+	.bind = dc_ed_bind,
+};
+
+static int dc_ed_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_ed_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_ed_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_ed_ops);
+}
+
+static const struct of_device_id dc_ed_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-extdst", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_ed_dt_ids);
+
+struct platform_driver dc_ed_driver = {
+	.probe = dc_ed_probe,
+	.remove = dc_ed_remove,
+	.driver = {
+		.name = "imx8-dc-extdst",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_ed_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
new file mode 100644
index 000000000000..7797ea59278a
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fl.c
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+#define BASEADDRESS(x)			(0x10 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERATTRIBUTES(x)	(0x14 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERDIMENSION(x)	(0x18 + FRAC_OFFSET * (x))
+#define COLORCOMPONENTBITS(x)		(0x1c + FRAC_OFFSET * (x))
+#define COLORCOMPONENTSHIFT(x)		(0x20 + FRAC_OFFSET * (x))
+#define LAYEROFFSET(x)			(0x24 + FRAC_OFFSET * (x))
+#define CLIPWINDOWOFFSET(x)		(0x28 + FRAC_OFFSET * (x))
+#define CLIPWINDOWDIMENSIONS(x)		(0x2c + FRAC_OFFSET * (x))
+#define CONSTANTCOLOR(x)		(0x30 + FRAC_OFFSET * (x))
+#define LAYERPROPERTY(x)		(0x34 + FRAC_OFFSET * (x))
+#define FRAMEDIMENSIONS			0x150
+
+struct dc_fl {
+	struct dc_fu fu;
+	int id;
+};
+
+static const struct regmap_range dc_fl_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS),
+};
+
+static const struct regmap_access_table dc_fl_regmap_access_table = {
+	.yes_ranges = dc_fl_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fl_regmap_ranges),
+};
+
+static const struct regmap_config dc_fl_cfg_regmap_config = {
+	.name = "fetchlayer-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fl_regmap_access_table,
+	.rd_table = &dc_fl_regmap_access_table,
+};
+
+static void dc_fl_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
+			  const struct drm_format_info *format)
+{
+	u32 bits = 0, shifts = 0;
+
+	dc_fu_set_src_bpp(fu, frac, format->cpp[0] * 8);
+
+	regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
+			  YUVCONVERSIONMODE_MASK,
+			  YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
+
+	dc_fu_get_pixel_format_bits(fu, format->format, &bits);
+	dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
+
+	regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
+	regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
+}
+
+static void dc_fl_set_framedimensions(struct dc_fu *fu, int w, int h)
+{
+	regmap_write(fu->reg_cfg, FRAMEDIMENSIONS,
+		     FRAMEWIDTH(w) | FRAMEHEIGHT(h));
+}
+
+static void dc_fl_init(struct dc_fu *fu)
+{
+	dc_fu_common_hw_init(fu);
+	dc_fu_shdldreq_sticky(fu, 0xff);
+}
+
+static void dc_fl_set_ops(struct dc_fu *fu)
+{
+	memcpy(&fu->ops, &dc_fu_common_ops, sizeof(dc_fu_common_ops));
+	fu->ops.init = dc_fl_init;
+	fu->ops.set_fmt = dc_fl_set_fmt;
+	fu->ops.set_framedimensions = dc_fl_set_framedimensions;
+}
+
+static int dc_fl_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_cfg;
+	struct dc_fl *fl;
+	struct dc_fu *fu;
+	int i;
+
+	fl = devm_kzalloc(dev, sizeof(*fl), GFP_KERNEL);
+	if (!fl)
+		return -ENOMEM;
+
+	fu = &fl->fu;
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_fl_cfg_regmap_config);
+	if (IS_ERR(fu->reg_cfg))
+		return PTR_ERR(fu->reg_cfg);
+
+	fl->id = of_alias_get_id(dev->of_node, "dc0-fetchlayer");
+	if (fl->id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", fl->id);
+		return fl->id;
+	}
+
+	fu->link_id = LINK_ID_FETCHLAYER0;
+	fu->id = DC_FETCHUNIT_FL0;
+	for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
+		fu->reg_baseaddr[i]		  = BASEADDRESS(i);
+		fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
+		fu->reg_sourcebufferdimension[i]  = SOURCEBUFFERDIMENSION(i);
+		fu->reg_layeroffset[i]		  = LAYEROFFSET(i);
+		fu->reg_clipwindowoffset[i]	  = CLIPWINDOWOFFSET(i);
+		fu->reg_clipwindowdimensions[i]	  = CLIPWINDOWDIMENSIONS(i);
+		fu->reg_constantcolor[i]	  = CONSTANTCOLOR(i);
+		fu->reg_layerproperty[i]	  = LAYERPROPERTY(i);
+	}
+	snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
+
+	dc_fl_set_ops(fu);
+
+	pe->fu_disp[fu->id] = fu;
+
+	return 0;
+}
+
+static const struct component_ops dc_fl_ops = {
+	.bind = dc_fl_bind,
+};
+
+static int dc_fl_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_fl_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_fl_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_fl_ops);
+}
+
+static const struct of_device_id dc_fl_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-fetchlayer", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_fl_dt_ids);
+
+struct platform_driver dc_fl_driver = {
+	.probe = dc_fl_probe,
+	.remove = dc_fl_remove,
+	.driver = {
+		.name = "imx8-dc-fetchlayer",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_fl_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.c b/drivers/gpu/drm/imx/dc/dc-fu.c
new file mode 100644
index 000000000000..dda8e6c52be8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fu.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/math.h>
+
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+/* STATICCONTROL */
+#define SHDLDREQSTICKY_MASK		GENMASK(31, 24)
+#define SHDLDREQSTICKY(x)		FIELD_PREP(SHDLDREQSTICKY_MASK, (x))
+#define BASEADDRESSAUTOUPDATE_MASK	GENMASK(23, 16)
+#define BASEADDRESSAUTOUPDATE(x)	FIELD_PREP(BASEADDRESSAUTOUPDATE_MASK, (x))
+
+/* BURSTBUFFERMANAGEMENT */
+#define SETBURSTLENGTH_MASK		GENMASK(12, 8)
+#define SETBURSTLENGTH(x)		FIELD_PREP(SETBURSTLENGTH_MASK, (x))
+#define SETNUMBUFFERS_MASK		GENMASK(7, 0)
+#define SETNUMBUFFERS(x)		FIELD_PREP(SETNUMBUFFERS_MASK, (x))
+#define LINEMODE_MASK			BIT(31)
+
+/* SOURCEBUFFERATTRIBUTES */
+#define BITSPERPIXEL_MASK		GENMASK(21, 16)
+#define BITSPERPIXEL(x)			FIELD_PREP(BITSPERPIXEL_MASK, (x))
+#define STRIDE_MASK			GENMASK(15, 0)
+#define STRIDE(x)			FIELD_PREP(STRIDE_MASK, (x) - 1)
+
+/* SOURCEBUFFERDIMENSION */
+#define LINEWIDTH(x)			FIELD_PREP(GENMASK(13, 0), (x))
+#define LINECOUNT(x)			FIELD_PREP(GENMASK(29, 16), (x))
+
+/* LAYEROFFSET */
+#define LAYERXOFFSET(x)			FIELD_PREP(GENMASK(14, 0), (x))
+#define LAYERYOFFSET(x)			FIELD_PREP(GENMASK(30, 16), (x))
+
+/* CLIPWINDOWOFFSET */
+#define CLIPWINDOWXOFFSET(x)		FIELD_PREP(GENMASK(14, 0), (x))
+#define CLIPWINDOWYOFFSET(x)		FIELD_PREP(GENMASK(30, 16), (x))
+
+/* CLIPWINDOWDIMENSIONS */
+#define CLIPWINDOWWIDTH(x)		FIELD_PREP(GENMASK(13, 0), (x) - 1)
+#define CLIPWINDOWHEIGHT(x)		FIELD_PREP(GENMASK(29, 16), (x) - 1)
+
+static const enum dc_fu_frac dc_fetchunit_all_fracs[] = {
+	DC_FETCHUNIT_FRAC0, DC_FETCHUNIT_FRAC1,
+	DC_FETCHUNIT_FRAC2, DC_FETCHUNIT_FRAC3,
+	DC_FETCHUNIT_FRAC4, DC_FETCHUNIT_FRAC5,
+	DC_FETCHUNIT_FRAC6, DC_FETCHUNIT_FRAC7
+};
+
+enum dc_linemode {
+	/*
+	 * Mandatory setting for operation in the Display Controller.
+	 * Works also for Blit Engine with marginal performance impact.
+	 */
+	LINEMODE_DISPLAY = 0,
+};
+
+struct dc_fu_pixel_format {
+	u32 pixel_format;
+	u32 bits;
+	u32 shifts;
+};
+
+static const struct dc_fu_pixel_format pixel_formats[] = {
+	{
+		DRM_FORMAT_XRGB8888,
+		R_BITS(8)   | G_BITS(8)   | B_BITS(8)   | A_BITS(0),
+		R_SHIFT(16) | G_SHIFT(8)  | B_SHIFT(0)  | A_SHIFT(0),
+	},
+};
+
+void dc_fu_get_pixel_format_bits(struct dc_fu *fu, u32 format, u32 *bits)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+		if (pixel_formats[i].pixel_format == format) {
+			*bits = pixel_formats[i].bits;
+			return;
+		}
+	}
+}
+
+void
+dc_fu_get_pixel_format_shifts(struct dc_fu *fu, u32 format, u32 *shifts)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+		if (pixel_formats[i].pixel_format == format) {
+			*shifts = pixel_formats[i].shifts;
+			return;
+		}
+	}
+}
+
+static inline void dc_fu_enable_shden(struct dc_fu *fu)
+{
+	regmap_write_bits(fu->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_fu_baddr_autoupdate(struct dc_fu *fu, u8 layer_mask)
+{
+	regmap_write_bits(fu->reg_cfg, STATICCONTROL,
+			  BASEADDRESSAUTOUPDATE_MASK,
+			  BASEADDRESSAUTOUPDATE(layer_mask));
+}
+
+void dc_fu_shdldreq_sticky(struct dc_fu *fu, u8 layer_mask)
+{
+	regmap_write_bits(fu->reg_cfg, STATICCONTROL, SHDLDREQSTICKY_MASK,
+			  SHDLDREQSTICKY(layer_mask));
+}
+
+static inline void dc_fu_set_linemode(struct dc_fu *fu, enum dc_linemode mode)
+{
+	regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT, LINEMODE_MASK,
+			  mode);
+}
+
+static inline void dc_fu_set_numbuffers(struct dc_fu *fu, unsigned int num)
+{
+	regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
+			  SETNUMBUFFERS_MASK, SETNUMBUFFERS(num));
+}
+
+static void dc_fu_set_burstlength(struct dc_fu *fu, dma_addr_t baddr)
+{
+	unsigned int burst_size, burst_length;
+
+	burst_size = 1 << __ffs(baddr);
+	burst_size = round_up(burst_size, 8);
+	burst_size = min(burst_size, 128U);
+	burst_length = burst_size / 8;
+
+	regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
+			  SETBURSTLENGTH_MASK, SETBURSTLENGTH(burst_length));
+}
+
+static void dc_fu_set_baseaddress(struct dc_fu *fu, enum dc_fu_frac frac,
+				  dma_addr_t baddr)
+{
+	regmap_write(fu->reg_cfg, fu->reg_baseaddr[frac], baddr);
+}
+
+void dc_fu_set_src_bpp(struct dc_fu *fu, enum dc_fu_frac frac, unsigned int bpp)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_sourcebufferattributes[frac],
+			  BITSPERPIXEL_MASK, BITSPERPIXEL(bpp));
+}
+
+static void dc_fu_set_src_stride(struct dc_fu *fu, enum dc_fu_frac frac,
+				 unsigned int stride)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_sourcebufferattributes[frac],
+			  STRIDE_MASK, STRIDE(stride));
+}
+
+static void dc_fu_set_src_buf_dimensions(struct dc_fu *fu, enum dc_fu_frac frac,
+					 int w, int h)
+{
+	regmap_write(fu->reg_cfg, fu->reg_sourcebufferdimension[frac],
+		     LINEWIDTH(w) | LINECOUNT(h));
+}
+
+static inline void dc_fu_layeroffset(struct dc_fu *fu, enum dc_fu_frac frac,
+				     unsigned int x, unsigned int y)
+{
+	regmap_write(fu->reg_cfg, fu->reg_layeroffset[frac],
+		     LAYERXOFFSET(x) | LAYERYOFFSET(y));
+}
+
+static inline void dc_fu_clipoffset(struct dc_fu *fu, enum dc_fu_frac frac,
+				    unsigned int x, unsigned int y)
+{
+	regmap_write(fu->reg_cfg, fu->reg_clipwindowoffset[frac],
+		     CLIPWINDOWXOFFSET(x) | CLIPWINDOWYOFFSET(y));
+}
+
+static inline void dc_fu_clipdimensions(struct dc_fu *fu, enum dc_fu_frac frac,
+					unsigned int w, unsigned int h)
+{
+	regmap_write(fu->reg_cfg, fu->reg_clipwindowdimensions[frac],
+		     CLIPWINDOWWIDTH(w) | CLIPWINDOWHEIGHT(h));
+}
+
+static inline void
+dc_fu_set_pixel_blend_mode(struct dc_fu *fu, enum dc_fu_frac frac)
+{
+	regmap_write(fu->reg_cfg, fu->reg_layerproperty[frac], 0);
+	regmap_write(fu->reg_cfg, fu->reg_constantcolor[frac], 0);
+}
+
+static void dc_fu_enable_src_buf(struct dc_fu *fu, enum dc_fu_frac frac)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
+			  SOURCEBUFFERENABLE, SOURCEBUFFERENABLE);
+}
+
+static void dc_fu_disable_src_buf(struct dc_fu *fu, enum dc_fu_frac frac)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
+			  SOURCEBUFFERENABLE, 0);
+
+	if (fu->lb) {
+		dc_lb_pec_clken(fu->lb, CLKEN_DISABLE);
+		dc_lb_mode(fu->lb, LB_NEUTRAL);
+	}
+}
+
+static void dc_fu_set_layerblend(struct dc_fu *fu, struct dc_lb *lb)
+{
+	fu->lb = lb;
+}
+
+static enum dc_link_id dc_fu_get_link_id(struct dc_fu *fu)
+{
+	return fu->link_id;
+}
+
+static const char *dc_fu_get_name(struct dc_fu *fu)
+{
+	return fu->name;
+}
+
+const struct dc_fu_ops dc_fu_common_ops = {
+	.set_burstlength	= dc_fu_set_burstlength,
+	.set_baseaddress	= dc_fu_set_baseaddress,
+	.set_src_stride		= dc_fu_set_src_stride,
+	.set_src_buf_dimensions = dc_fu_set_src_buf_dimensions,
+	.enable_src_buf		= dc_fu_enable_src_buf,
+	.disable_src_buf	= dc_fu_disable_src_buf,
+	.set_layerblend		= dc_fu_set_layerblend,
+	.get_link_id		= dc_fu_get_link_id,
+	.get_name		= dc_fu_get_name,
+};
+
+const struct dc_fu_ops *dc_fu_get_ops(struct dc_fu *fu)
+{
+	return &fu->ops;
+}
+
+void dc_fu_common_hw_init(struct dc_fu *fu)
+{
+	enum dc_fu_frac frac;
+	int i;
+
+	dc_fu_baddr_autoupdate(fu, 0x0);
+	dc_fu_enable_shden(fu);
+	dc_fu_set_linemode(fu, LINEMODE_DISPLAY);
+	dc_fu_set_numbuffers(fu, 16);
+
+	for (i = 0; i < ARRAY_SIZE(dc_fetchunit_all_fracs); i++) {
+		frac = dc_fetchunit_all_fracs[i];
+
+		dc_fu_layeroffset(fu, frac, 0, 0);
+		dc_fu_clipoffset(fu, frac, 0, 0);
+		dc_fu_clipdimensions(fu, frac, 1, 1);
+		dc_fu_disable_src_buf(fu, frac);
+		dc_fu_set_pixel_blend_mode(fu, frac);
+	}
+}
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.h b/drivers/gpu/drm/imx/dc/dc-fu.h
new file mode 100644
index 000000000000..d5e20b132005
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fu.h
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_FETCHUNIT_H__
+#define __DC_FETCHUNIT_H__
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "dc-pe.h"
+
+#define FRAC_OFFSET			0x28
+
+#define STATICCONTROL			0x8
+#define BURSTBUFFERMANAGEMENT		0xc
+
+/* COLORCOMPONENTBITS */
+#define R_BITS(x)			FIELD_PREP_CONST(GENMASK(27, 24), (x))
+#define G_BITS(x)			FIELD_PREP_CONST(GENMASK(19, 16), (x))
+#define B_BITS(x)			FIELD_PREP_CONST(GENMASK(11, 8), (x))
+#define A_BITS(x)			FIELD_PREP_CONST(GENMASK(3, 0), (x))
+
+/* COLORCOMPONENTSHIFT */
+#define R_SHIFT(x)			FIELD_PREP_CONST(GENMASK(28, 24), (x))
+#define G_SHIFT(x)			FIELD_PREP_CONST(GENMASK(20, 16), (x))
+#define B_SHIFT(x)			FIELD_PREP_CONST(GENMASK(12, 8), (x))
+#define A_SHIFT(x)			FIELD_PREP_CONST(GENMASK(4, 0), (x))
+
+/* LAYERPROPERTY */
+#define YUVCONVERSIONMODE_MASK		GENMASK(18, 17)
+#define YUVCONVERSIONMODE(x)		FIELD_PREP(YUVCONVERSIONMODE_MASK, (x))
+#define SOURCEBUFFERENABLE		BIT(31)
+
+/* FRAMEDIMENSIONS */
+#define FRAMEWIDTH(x)			FIELD_PREP(GENMASK(13, 0), (x))
+#define FRAMEHEIGHT(x)			FIELD_PREP(GENMASK(29, 16), (x))
+
+/* CONTROL */
+#define INPUTSELECT_MASK		GENMASK(4, 3)
+#define INPUTSELECT(x)			FIELD_PREP(INPUTSELECT_MASK, (x))
+#define RASTERMODE_MASK			GENMASK(2, 0)
+#define RASTERMODE(x)			FIELD_PREP(RASTERMODE_MASK, (x))
+
+enum dc_yuvconversionmode {
+	YUVCONVERSIONMODE_OFF,
+};
+
+enum dc_inputselect {
+	INPUTSELECT_INACTIVE,
+};
+
+enum dc_rastermode {
+	RASTERMODE_NORMAL,
+};
+
+enum {
+	DC_FETCHUNIT_FL0,
+	DC_FETCHUNIT_FW2,
+};
+
+enum dc_fu_frac {
+	DC_FETCHUNIT_FRAC0,
+	DC_FETCHUNIT_FRAC1,
+	DC_FETCHUNIT_FRAC2,
+	DC_FETCHUNIT_FRAC3,
+	DC_FETCHUNIT_FRAC4,
+	DC_FETCHUNIT_FRAC5,
+	DC_FETCHUNIT_FRAC6,
+	DC_FETCHUNIT_FRAC7,
+	DC_FETCHUNIT_FRAC_NUM,
+};
+
+struct dc_fu;
+struct dc_lb;
+
+struct dc_fu_ops {
+	void (*init)(struct dc_fu *fu);
+	void (*set_burstlength)(struct dc_fu *fu, dma_addr_t baddr);
+	void (*set_baseaddress)(struct dc_fu *fu, enum dc_fu_frac frac,
+				dma_addr_t baddr);
+	void (*set_src_stride)(struct dc_fu *fu, enum dc_fu_frac frac,
+			       unsigned int stride);
+	void (*set_src_buf_dimensions)(struct dc_fu *fu, enum dc_fu_frac frac,
+				       int w, int h);
+	void (*set_fmt)(struct dc_fu *fu, enum dc_fu_frac frac,
+			const struct drm_format_info *format);
+	void (*enable_src_buf)(struct dc_fu *fu, enum dc_fu_frac frac);
+	void (*disable_src_buf)(struct dc_fu *fu, enum dc_fu_frac frac);
+	void (*set_framedimensions)(struct dc_fu *fu, int w, int h);
+	void (*set_layerblend)(struct dc_fu *fu, struct dc_lb *lb);
+	enum dc_link_id (*get_link_id)(struct dc_fu *fu);
+	const char *(*get_name)(struct dc_fu *fu);
+};
+
+struct dc_fu {
+	struct regmap *reg_pec;
+	struct regmap *reg_cfg;
+	char name[13];
+	u32 reg_baseaddr[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_sourcebufferattributes[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_sourcebufferdimension[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_layeroffset[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_clipwindowoffset[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_clipwindowdimensions[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_constantcolor[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_layerproperty[DC_FETCHUNIT_FRAC_NUM];
+	unsigned int id;
+	enum dc_link_id link_id;
+	struct dc_fu_ops ops;
+	struct dc_lb *lb;
+};
+
+extern const struct dc_fu_ops dc_fu_common_ops;
+
+void dc_fu_get_pixel_format_bits(struct dc_fu *fu, u32 format, u32 *bits);
+void dc_fu_get_pixel_format_shifts(struct dc_fu *fu, u32 format, u32 *shifts);
+void dc_fu_shdldreq_sticky(struct dc_fu *fu, u8 layer_mask);
+void dc_fu_set_src_bpp(struct dc_fu *fu, enum dc_fu_frac frac, unsigned int bpp);
+void dc_fu_common_hw_init(struct dc_fu *fu);
+
+const struct dc_fu_ops *dc_fu_get_ops(struct dc_fu *fu);
+
+#endif /* __DC_FETCHUNIT_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-fw.c b/drivers/gpu/drm/imx/dc/dc-fw.c
new file mode 100644
index 000000000000..212302b026c0
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fw.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_DYNAMIC		0x8
+
+#define BASEADDRESS(x)			(0x10 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERATTRIBUTES(x)	(0x14 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERDIMENSION(x)	(0x18 + FRAC_OFFSET * (x))
+#define COLORCOMPONENTBITS(x)		(0x1c + FRAC_OFFSET * (x))
+#define COLORCOMPONENTSHIFT(x)		(0x20 + FRAC_OFFSET * (x))
+#define LAYEROFFSET(x)			(0x24 + FRAC_OFFSET * (x))
+#define CLIPWINDOWOFFSET(x)		(0x28 + FRAC_OFFSET * (x))
+#define CLIPWINDOWDIMENSIONS(x)		(0x2c + FRAC_OFFSET * (x))
+#define CONSTANTCOLOR(x)		(0x30 + FRAC_OFFSET * (x))
+#define LAYERPROPERTY(x)		(0x34 + FRAC_OFFSET * (x))
+#define FRAMEDIMENSIONS			0x150
+#define CONTROL				0x170
+
+struct dc_fw {
+	struct dc_fu fu;
+	int id;
+};
+
+static const struct regmap_range dc_fw_pec_regmap_access_ranges[] = {
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+};
+
+static const struct regmap_access_table dc_fw_pec_regmap_access_table = {
+	.yes_ranges = dc_fw_pec_regmap_access_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fw_pec_regmap_access_ranges),
+};
+
+static const struct regmap_config dc_fw_pec_regmap_config = {
+	.name = "fetchwarp-pec",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fw_pec_regmap_access_table,
+	.rd_table = &dc_fw_pec_regmap_access_table,
+};
+
+static const struct regmap_range dc_fw_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS),
+	regmap_reg_range(CONTROL, CONTROL),
+};
+
+static const struct regmap_access_table dc_fw_regmap_access_table = {
+	.yes_ranges = dc_fw_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fw_regmap_ranges),
+};
+
+static const struct regmap_config dc_fw_cfg_regmap_config = {
+	.name = "fetchwarp-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fw_regmap_access_table,
+	.rd_table = &dc_fw_regmap_access_table,
+};
+
+static void dc_fw_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
+			  const struct drm_format_info *format)
+{
+	u32 bits = 0, shifts = 0;
+
+	dc_fu_set_src_bpp(fu, frac, format->cpp[0] * 8);
+
+	regmap_write_bits(fu->reg_cfg, CONTROL, INPUTSELECT_MASK,
+			  INPUTSELECT(INPUTSELECT_INACTIVE));
+	regmap_write_bits(fu->reg_cfg, CONTROL, RASTERMODE_MASK,
+			  RASTERMODE(RASTERMODE_NORMAL));
+
+	regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
+			  YUVCONVERSIONMODE_MASK,
+			  YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
+
+	dc_fu_get_pixel_format_bits(fu, format->format, &bits);
+	dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
+
+	regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
+	regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
+}
+
+static void dc_fw_set_framedimensions(struct dc_fu *fu, int w, int h)
+{
+	regmap_write(fu->reg_cfg, FRAMEDIMENSIONS,
+		     FRAMEWIDTH(w) | FRAMEHEIGHT(h));
+}
+
+static void dc_fw_init(struct dc_fu *fu)
+{
+	regmap_write(fu->reg_pec, PIXENGCFG_DYNAMIC, LINK_ID_NONE);
+	dc_fu_common_hw_init(fu);
+	dc_fu_shdldreq_sticky(fu, 0xff);
+}
+
+static void dc_fw_set_ops(struct dc_fu *fu)
+{
+	memcpy(&fu->ops, &dc_fu_common_ops, sizeof(dc_fu_common_ops));
+	fu->ops.init = dc_fw_init;
+	fu->ops.set_fmt	= dc_fw_set_fmt;
+	fu->ops.set_framedimensions = dc_fw_set_framedimensions;
+}
+
+static int dc_fw_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_pec;
+	void __iomem *base_cfg;
+	struct dc_fw *fw;
+	struct dc_fu *fu;
+	int i;
+
+	fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
+	if (!fw)
+		return -ENOMEM;
+
+	fu = &fw->fu;
+
+	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
+	if (IS_ERR(base_pec))
+		return PTR_ERR(base_pec);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	fu->reg_pec = devm_regmap_init_mmio(dev, base_pec,
+					    &dc_fw_pec_regmap_config);
+	if (IS_ERR(fu->reg_pec))
+		return PTR_ERR(fu->reg_pec);
+
+	fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_fw_cfg_regmap_config);
+	if (IS_ERR(fu->reg_cfg))
+		return PTR_ERR(fu->reg_cfg);
+
+	fw->id = of_alias_get_id(dev->of_node, "dc0-fetchwarp");
+	if (fw->id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", fw->id);
+		return fw->id;
+	}
+
+	fu->link_id = LINK_ID_FETCHWARP2;
+	fu->id = DC_FETCHUNIT_FW2;
+	for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
+		fu->reg_baseaddr[i]		  = BASEADDRESS(i);
+		fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
+		fu->reg_sourcebufferdimension[i]  = SOURCEBUFFERDIMENSION(i);
+		fu->reg_layeroffset[i]		  = LAYEROFFSET(i);
+		fu->reg_clipwindowoffset[i]	  = CLIPWINDOWOFFSET(i);
+		fu->reg_clipwindowdimensions[i]	  = CLIPWINDOWDIMENSIONS(i);
+		fu->reg_constantcolor[i]	  = CONSTANTCOLOR(i);
+		fu->reg_layerproperty[i]	  = LAYERPROPERTY(i);
+	}
+	snprintf(fu->name, sizeof(fu->name), "FetchWarp%u", fw->id);
+
+	dc_fw_set_ops(fu);
+
+	pe->fu_disp[fu->id] = fu;
+
+	return 0;
+}
+
+static const struct component_ops dc_fw_ops = {
+	.bind = dc_fw_bind,
+};
+
+static int dc_fw_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_fw_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_fw_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_fw_ops);
+}
+
+static const struct of_device_id dc_fw_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-fetchwarp", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_fw_dt_ids);
+
+struct platform_driver dc_fw_driver = {
+	.probe = dc_fw_probe,
+	.remove = dc_fw_remove,
+	.driver = {
+		.name = "imx8-dc-fetchwarp",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_fw_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
new file mode 100644
index 000000000000..af35d377126b
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-lb.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_blend.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_DYNAMIC			0x8
+#define  PIXENGCFG_DYNAMIC_PRIM_SEL_MASK	GENMASK(5, 0)
+#define  PIXENGCFG_DYNAMIC_PRIM_SEL(x)		\
+		FIELD_PREP(PIXENGCFG_DYNAMIC_PRIM_SEL_MASK, (x))
+#define  PIXENGCFG_DYNAMIC_SEC_SEL_MASK		GENMASK(13, 8)
+#define  PIXENGCFG_DYNAMIC_SEC_SEL(x)		\
+		FIELD_PREP(PIXENGCFG_DYNAMIC_SEC_SEL_MASK, (x))
+
+#define STATICCONTROL				0x8
+#define  SHDTOKSEL_MASK				GENMASK(4, 3)
+#define  SHDTOKSEL(x)				FIELD_PREP(SHDTOKSEL_MASK, (x))
+#define  SHDLDSEL_MASK				GENMASK(2, 1)
+#define  SHDLDSEL(x)				FIELD_PREP(SHDLDSEL_MASK, (x))
+
+#define CONTROL					0xc
+#define  CTRL_MODE_MASK				BIT(0)
+#define  CTRL_MODE(x)				FIELD_PREP(CTRL_MODE_MASK, (x))
+
+#define BLENDCONTROL				0x10
+#define  ALPHA_MASK				GENMASK(23, 16)
+#define  ALPHA(x)				FIELD_PREP(ALPHA_MASK, (x))
+#define  PRIM_C_BLD_FUNC_MASK			GENMASK(2, 0)
+#define  PRIM_C_BLD_FUNC(x)			\
+		FIELD_PREP(PRIM_C_BLD_FUNC_MASK, (x))
+#define  SEC_C_BLD_FUNC_MASK			GENMASK(6, 4)
+#define  SEC_C_BLD_FUNC(x)			\
+		FIELD_PREP(SEC_C_BLD_FUNC_MASK, (x))
+#define  PRIM_A_BLD_FUNC_MASK			GENMASK(10, 8)
+#define  PRIM_A_BLD_FUNC(x)			\
+		FIELD_PREP(PRIM_A_BLD_FUNC_MASK, (x))
+#define  SEC_A_BLD_FUNC_MASK			GENMASK(14, 12)
+#define  SEC_A_BLD_FUNC(x)			\
+		FIELD_PREP(SEC_A_BLD_FUNC_MASK, (x))
+
+#define POSITION				0x14
+#define  XPOS_MASK				GENMASK(15, 0)
+#define  XPOS(x)				FIELD_PREP(XPOS_MASK, (x))
+#define  YPOS_MASK				GENMASK(31, 16)
+#define  YPOS(x)				FIELD_PREP(YPOS_MASK, (x))
+
+enum dc_lb_blend_func {
+	DC_LAYERBLEND_BLEND_ZERO,
+	DC_LAYERBLEND_BLEND_ONE,
+	DC_LAYERBLEND_BLEND_PRIM_ALPHA,
+	DC_LAYERBLEND_BLEND_ONE_MINUS_PRIM_ALPHA,
+	DC_LAYERBLEND_BLEND_SEC_ALPHA,
+	DC_LAYERBLEND_BLEND_ONE_MINUS_SEC_ALPHA,
+	DC_LAYERBLEND_BLEND_CONST_ALPHA,
+	DC_LAYERBLEND_BLEND_ONE_MINUS_CONST_ALPHA,
+};
+
+enum dc_lb_shadow_sel {
+	BOTH = 0x2,
+};
+
+static const struct regmap_range dc_lb_pec_regmap_access_ranges[] = {
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+};
+
+static const struct regmap_access_table dc_lb_pec_regmap_access_table = {
+	.yes_ranges = dc_lb_pec_regmap_access_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_lb_pec_regmap_access_ranges),
+};
+
+static const struct regmap_config dc_lb_pec_regmap_config = {
+	.name = "layerblend-pec",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_lb_pec_regmap_access_table,
+	.rd_table = &dc_lb_pec_regmap_access_table,
+};
+
+static const struct regmap_range dc_lb_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, POSITION),
+};
+
+static const struct regmap_access_table dc_lb_regmap_access_table = {
+	.yes_ranges = dc_lb_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_lb_regmap_ranges),
+};
+
+static const struct regmap_config dc_lb_cfg_regmap_config = {
+	.name = "layerblend-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_lb_regmap_access_table,
+	.rd_table = &dc_lb_regmap_access_table,
+};
+
+static const enum dc_link_id lb_links[] = {
+	LINK_ID_LAYERBLEND0,
+	LINK_ID_LAYERBLEND1,
+	LINK_ID_LAYERBLEND2,
+	LINK_ID_LAYERBLEND3,
+};
+
+static const enum dc_link_id prim_sels[] = {
+	/* common options */
+	LINK_ID_NONE,
+	LINK_ID_CONSTFRAME0,
+	LINK_ID_CONSTFRAME1,
+	LINK_ID_CONSTFRAME4,
+	LINK_ID_CONSTFRAME5,
+	/*
+	 * special options:
+	 * layerblend(n) has n special options,
+	 * from layerblend0 to layerblend(n - 1), e.g.,
+	 * layerblend3 has 3 special options -
+	 * layerblend0/1/2.
+	 */
+	LINK_ID_LAYERBLEND0,
+	LINK_ID_LAYERBLEND1,
+	LINK_ID_LAYERBLEND2,
+	LINK_ID_LAYERBLEND3,
+};
+
+static const enum dc_link_id sec_sels[] = {
+	LINK_ID_NONE,
+	LINK_ID_FETCHWARP2,
+	LINK_ID_FETCHLAYER0,
+};
+
+enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
+{
+	return lb->link;
+}
+
+void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim)
+{
+	int fixed_sels_num = ARRAY_SIZE(prim_sels) - 4;
+	int i;
+
+	for (i = 0; i < fixed_sels_num + lb->id; i++) {
+		if (prim_sels[i] == prim) {
+			regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
+					  PIXENGCFG_DYNAMIC_PRIM_SEL_MASK,
+					  PIXENGCFG_DYNAMIC_PRIM_SEL(prim));
+			return;
+		}
+	}
+}
+
+void dc_lb_pec_dynamic_sec_sel(struct dc_lb *lb, enum dc_link_id sec)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sec_sels); i++) {
+		if (sec_sels[i] == sec) {
+			regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
+					  PIXENGCFG_DYNAMIC_SEC_SEL_MASK,
+					  PIXENGCFG_DYNAMIC_SEC_SEL(sec));
+			return;
+		}
+	}
+}
+
+void dc_lb_pec_clken(struct dc_lb *lb, enum dc_pec_clken clken)
+{
+	regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC, CLKEN_MASK,
+			  CLKEN(clken));
+}
+
+static inline void dc_lb_enable_shden(struct dc_lb *lb)
+{
+	regmap_write_bits(lb->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_lb_shdtoksel(struct dc_lb *lb, enum dc_lb_shadow_sel sel)
+{
+	regmap_write_bits(lb->reg_cfg, STATICCONTROL, SHDTOKSEL_MASK,
+			  SHDTOKSEL(sel));
+}
+
+static inline void dc_lb_shdldsel(struct dc_lb *lb, enum dc_lb_shadow_sel sel)
+{
+	regmap_write_bits(lb->reg_cfg, STATICCONTROL, SHDLDSEL_MASK,
+			  SHDLDSEL(sel));
+}
+
+void dc_lb_mode(struct dc_lb *lb, enum dc_lb_mode mode)
+{
+	regmap_write_bits(lb->reg_cfg, CONTROL, CTRL_MODE_MASK, mode);
+}
+
+static inline void dc_lb_blendcontrol(struct dc_lb *lb)
+{
+	u32 val = PRIM_A_BLD_FUNC(DC_LAYERBLEND_BLEND_ZERO) |
+		  SEC_A_BLD_FUNC(DC_LAYERBLEND_BLEND_ZERO) |
+		  PRIM_C_BLD_FUNC(DC_LAYERBLEND_BLEND_ZERO) |
+		  SEC_C_BLD_FUNC(DC_LAYERBLEND_BLEND_CONST_ALPHA) |
+		  ALPHA(DRM_BLEND_ALPHA_OPAQUE >> 8);
+
+	regmap_write(lb->reg_cfg, BLENDCONTROL, val);
+}
+
+void dc_lb_position(struct dc_lb *lb, int x, int y)
+{
+	regmap_write(lb->reg_cfg, POSITION, XPOS(x) | YPOS(y));
+}
+
+unsigned int dc_lb_get_id(struct dc_lb *lb)
+{
+	return lb->id;
+}
+
+void dc_lb_init(struct dc_lb *lb)
+{
+	dc_lb_pec_dynamic_prim_sel(lb, LINK_ID_NONE);
+	dc_lb_pec_dynamic_sec_sel(lb, LINK_ID_NONE);
+	dc_lb_pec_clken(lb, CLKEN_DISABLE);
+	dc_lb_shdldsel(lb, BOTH);
+	dc_lb_shdtoksel(lb, BOTH);
+	dc_lb_blendcontrol(lb);
+	dc_lb_enable_shden(lb);
+}
+
+static int dc_lb_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_pec;
+	void __iomem *base_cfg;
+	struct dc_lb *lb;
+
+	lb = devm_kzalloc(dev, sizeof(*lb), GFP_KERNEL);
+	if (!lb)
+		return -ENOMEM;
+
+	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
+	if (IS_ERR(base_pec))
+		return PTR_ERR(base_pec);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	lb->reg_pec = devm_regmap_init_mmio(dev, base_pec,
+					    &dc_lb_pec_regmap_config);
+	if (IS_ERR(lb->reg_pec))
+		return PTR_ERR(lb->reg_pec);
+
+	lb->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_lb_cfg_regmap_config);
+	if (IS_ERR(lb->reg_cfg))
+		return PTR_ERR(lb->reg_cfg);
+
+	lb->id = of_alias_get_id(dev->of_node, "dc0-layerblend");
+	if (lb->id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", lb->id);
+		return lb->id;
+	}
+
+	lb->link = lb_links[lb->id];
+
+	pe->lb[lb->id] = lb;
+
+	return 0;
+}
+
+static const struct component_ops dc_lb_ops = {
+	.bind = dc_lb_bind,
+};
+
+static int dc_lb_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_lb_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_lb_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_lb_ops);
+}
+
+static const struct of_device_id dc_lb_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-layerblend", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_lb_dt_ids);
+
+struct platform_driver dc_lb_driver = {
+	.probe = dc_lb_probe,
+	.remove = dc_lb_remove,
+	.driver = {
+		.name = "imx8-dc-layerblend",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_lb_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.c b/drivers/gpu/drm/imx/dc/dc-pe.c
new file mode 100644
index 000000000000..459fc3823953
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-pe.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+static int dc_pe_bind(struct device *dev, struct device *master, void *data)
+{
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe;
+	int ret;
+
+	pe = devm_kzalloc(dev, sizeof(*pe), GFP_KERNEL);
+	if (!pe)
+		return -ENOMEM;
+
+	pe->clk_axi = devm_clk_get(dev, NULL);
+	if (IS_ERR(pe->clk_axi))
+		return dev_err_probe(dev, PTR_ERR(pe->clk_axi),
+				     "failed to get AXI clock\n");
+
+	pe->dev = dev;
+
+	dev_set_drvdata(dev, pe);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	dc_drm->pe = pe;
+
+	return 0;
+}
+
+static const struct component_ops dc_pe_ops = {
+	.bind = dc_pe_bind,
+};
+
+static int dc_pe_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = component_add(&pdev->dev, &dc_pe_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_pe_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_pe_ops);
+}
+
+static int dc_pe_runtime_suspend(struct device *dev)
+{
+	struct dc_pe *pe = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(pe->clk_axi);
+
+	return 0;
+}
+
+static int dc_pe_runtime_resume(struct device *dev)
+{
+	struct dc_pe *pe = dev_get_drvdata(dev);
+	int i, ret;
+
+	ret = clk_prepare_enable(pe->clk_axi);
+	if (ret) {
+		dev_err(dev, "failed to enable AXI clock: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pe->cf_safe); i++)
+		dc_cf_init(pe->cf_safe[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->cf_cont); i++)
+		dc_cf_init(pe->cf_cont[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->ed_safe); i++)
+		dc_ed_init(pe->ed_safe[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->ed_cont); i++)
+		dc_ed_init(pe->ed_cont[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->fu_disp); i++)
+		pe->fu_disp[i]->ops.init(pe->fu_disp[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->lb); i++)
+		dc_lb_init(pe->lb[i]);
+
+	return 0;
+}
+
+static const struct dev_pm_ops dc_pe_pm_ops = {
+	RUNTIME_PM_OPS(dc_pe_runtime_suspend, dc_pe_runtime_resume, NULL)
+};
+
+static const struct of_device_id dc_pe_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-pixel-engine", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_pe_dt_ids);
+
+struct platform_driver dc_pe_driver = {
+	.probe = dc_pe_probe,
+	.remove = dc_pe_remove,
+	.driver = {
+		.name = "imx8-dc-pixel-engine",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_pe_dt_ids,
+		.pm = pm_sleep_ptr(&dc_pe_pm_ops),
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
new file mode 100644
index 000000000000..d0c1080e58d8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-pe.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_PIXEL_ENGINE_H__
+#define __DC_PIXEL_ENGINE_H__
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+#include "dc-de.h"
+
+#define SHDEN			BIT(0)
+
+#define CLKEN_MASK_SHIFT	24
+#define CLKEN_MASK		(0x3 << CLKEN_MASK_SHIFT)
+#define CLKEN(n)		((n) << CLKEN_MASK_SHIFT)
+
+#define DC_DISP_FETCHUNIT_CNT	2
+#define DC_LAYERBLEND_CNT	4
+
+enum dc_link_id {
+	LINK_ID_NONE		= 0x00,
+	LINK_ID_CONSTFRAME0	= 0x0c,
+	LINK_ID_CONSTFRAME4	= 0x0e,
+	LINK_ID_CONSTFRAME1	= 0x10,
+	LINK_ID_CONSTFRAME5	= 0x12,
+	LINK_ID_FETCHWARP2	= 0x14,
+	LINK_ID_FETCHLAYER0	= 0x1a,
+	LINK_ID_LAYERBLEND0	= 0x21,
+	LINK_ID_LAYERBLEND1	= 0x22,
+	LINK_ID_LAYERBLEND2	= 0x23,
+	LINK_ID_LAYERBLEND3	= 0x24,
+};
+
+enum dc_lb_mode {
+	LB_NEUTRAL,	/* Output is same as primary input. */
+	LB_BLEND,
+};
+
+enum dc_pec_clken {
+	CLKEN_DISABLE,
+	CLKEN_AUTOMATIC,
+};
+
+struct dc_cf {
+	struct regmap *reg_cfg;
+	enum dc_link_id link;
+};
+
+struct dc_ed {
+	struct device *dev;
+	struct regmap *reg_pec;
+	struct regmap *reg_cfg;
+	int irq_shdld;
+};
+
+struct dc_lb {
+	struct regmap *reg_pec;
+	struct regmap *reg_cfg;
+	int id;
+	enum dc_link_id link;
+};
+
+struct dc_pe {
+	struct device *dev;
+	struct clk *clk_axi;
+	struct dc_cf *cf_safe[DC_DISPLAYS];
+	struct dc_cf *cf_cont[DC_DISPLAYS];
+	struct dc_ed *ed_safe[DC_DISPLAYS];
+	struct dc_ed *ed_cont[DC_DISPLAYS];
+	struct dc_fu *fu_disp[DC_DISP_FETCHUNIT_CNT];
+	struct dc_lb *lb[DC_LAYERBLEND_CNT];
+};
+
+/* Constant Frame Unit */
+enum dc_link_id dc_cf_get_link_id(struct dc_cf *cf);
+void dc_cf_framedimensions(struct dc_cf *cf, unsigned int w, unsigned int h);
+void dc_cf_constantcolor_black(struct dc_cf *cf);
+void dc_cf_constantcolor_blue(struct dc_cf *cf);
+void dc_cf_init(struct dc_cf *cf);
+
+/* External Destination Unit */
+void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src);
+void dc_ed_pec_sync_trigger(struct dc_ed *ed);
+void dc_ed_init(struct dc_ed *ed);
+
+/* Layer Blend Unit */
+enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb);
+void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim);
+void dc_lb_pec_dynamic_sec_sel(struct dc_lb *lb, enum dc_link_id sec);
+void dc_lb_pec_clken(struct dc_lb *lb, enum dc_pec_clken clken);
+void dc_lb_mode(struct dc_lb *lb, enum dc_lb_mode mode);
+void dc_lb_position(struct dc_lb *lb, int x, int y);
+unsigned int dc_lb_get_id(struct dc_lb *lb);
+void dc_lb_init(struct dc_lb *lb);
+
+#endif /* __DC_PIXEL_ENGINE_H__ */
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:34 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:34 +0800
Subject: [DO NOT MERGE PATCH v5 18/19] arm64: dts: imx8qxp-mek: Enable display controller
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-19-victor.liu@nxp.com>

Enable display controller for i.MX8qxp MEK.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Francesco)

 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index be79c793213a..c7b4015c7bf7 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -234,6 +234,10 @@ &asrc0 {
 	status = "okay";
 };
 
+&dc0 {
+	status = "okay";
+};
+
 &dsp {
 	memory-region = <&dsp_vdev0buffer>, <&dsp_vdev0vring0>,
 			<&dsp_vdev0vring1>, <&dsp_reserved>;
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:35 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:35 +0800
Subject: [DO NOT MERGE PATCH v5 19/19] arm64: dts: imx8qxp-mek: Add MX8-DLVDS-LCD1 display module support
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-20-victor.liu@nxp.com>

MX8-DLVDS-LCD1 display module integrates a KOE TX26D202VM0BWA LCD panel
and a touch IC.  Add an overlay to support the LCD panel on i.MX8qxp
MEK.  mipi_lvds_0_ldb channel0 and mipi_lvds_1_ldb channel1 send odd
and even pixels to the panel respectively.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Francesco)

 arch/arm64/boot/dts/freescale/Makefile        |   4 +
 .../imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso | 183 ++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |  30 +++
 3 files changed, 217 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 42e6482a31cb..a22476e81cc7 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -254,6 +254,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-eval-v3.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-iris.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-iris-v2.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb
+
+imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd-dtbs += imx8qxp-mek.dtb imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtb
+
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-tqma8xqp-mba8xx.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8ulp-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx93-9x9-qsb.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso b/arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso
new file mode 100644
index 000000000000..7ddd90e68754
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+
+&{/} {
+	panel-lvds0 {
+		compatible = "koe,tx26d202vm0bwa";
+		backlight = <&backlight_lvds1>;
+		power-supply = <&reg_vcc_per_3v3>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+
+				panel_lvds0_in: endpoint {
+					remote-endpoint = <&lvds0_out>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+
+				panel_lvds1_in: endpoint {
+					remote-endpoint = <&lvds1_out>;
+				};
+			};
+		};
+	};
+};
+
+&backlight_lvds1 {
+	status = "okay";
+};
+
+&dc0_framegen0 {
+	assigned-clocks = <&clk IMX_SC_R_DC_0_PLL_0 IMX_SC_PM_CLK_PLL>,
+			  <&clk IMX_SC_R_DC_0 IMX_SC_PM_CLK_MISC0>;
+	assigned-clock-parents = <0>,
+				 <&clk IMX_SC_R_DC_0_PLL_0 IMX_SC_PM_CLK_PLL>;
+	assigned-clock-rates = <940320000>;
+};
+
+&dc0_pixel_link0 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 1 {
+			reg = <1>;
+
+			status = "okay";
+		};
+	};
+};
+
+&dc0_pc {
+	status = "okay";
+
+	channel at 0 {
+		status = "okay";
+	};
+};
+
+&mipi_lvds_0_ldb {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	fsl,companion-ldb = <&mipi_lvds_1_ldb>;
+	status = "okay";
+
+	channel at 0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+		status = "okay";
+
+		port at 1 {
+			reg = <1>;
+
+			lvds0_out: endpoint {
+				remote-endpoint = <&panel_lvds0_in>;
+			};
+		};
+	};
+};
+
+&mipi_lvds_0_phy {
+	status = "okay";
+};
+
+&mipi_lvds_0_pxl2dpi {
+	fsl,companion-pxl2dpi = <&mipi_lvds_1_pxl2dpi>;
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+
+			mipi_lvds_0_pxl2dpi_dc0_pixel_link0: endpoint at 0 {
+				status = "okay";
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0: endpoint at 0 {
+				status = "okay";
+			};
+		};
+	};
+};
+
+&mipi_lvds_1_ldb {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	channel at 1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <1>;
+		status = "okay";
+
+		port at 1 {
+			reg = <1>;
+
+			lvds1_out: endpoint {
+				remote-endpoint = <&panel_lvds1_in>;
+			};
+		};
+	};
+};
+
+&mipi_lvds_1_phy {
+	status = "okay";
+};
+
+&mipi_lvds_1_pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_mipi_lvds1>;
+	status = "okay";
+};
+
+&mipi_lvds_1_pxl2dpi {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+
+			mipi_lvds_1_pxl2dpi_dc0_pixel_link0: endpoint at 1 {
+				status = "okay";
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch1: endpoint at 1 {
+				status = "okay";
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index c7b4015c7bf7..cb999be00c22 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -21,6 +21,16 @@ chosen {
 		stdout-path = &lpuart0;
 	};
 
+	backlight_lvds1: backlight-lvds1 {
+		compatible = "pwm-backlight";
+		pwms = <&mipi_lvds_1_pwm 0 100000 0>;
+		brightness-levels = <0 100>;
+		num-interpolated-steps = <100>;
+		default-brightness-level = <100>;
+		power-supply = <&reg_vcc_12v0>;
+		status = "disabled";
+	};
+
 	imx8x_cm4: imx8x-cm4 {
 		compatible = "fsl,imx8qxp-cm4";
 		mbox-names = "tx", "rx", "rxdb";
@@ -58,6 +68,20 @@ dsp_vdev0buffer: memory at 94300000 {
 		};
 	};
 
+	reg_vcc_12v0: regulator-vcc-12v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_12V0";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	reg_vcc_per_3v3: regulator-vcc-per-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_PER_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
 	reg_usdhc2_vmmc: usdhc2-vmmc {
 		compatible = "regulator-fixed";
 		regulator-name = "SD1_SPWR";
@@ -785,6 +809,12 @@ IMX8QXP_FLEXCAN2_RX_ADMA_UART3_RX       0x06000020
 		>;
 	};
 
+	pinctrl_pwm_mipi_lvds1: mipilvds1pwmgrp {
+		fsl,pins = <
+			IMX8QXP_MIPI_DSI1_GPIO0_00_MIPI_DSI1_PWM0_OUT		0x00000020
+		>;
+	};
+
 	pinctrl_pcieb: pcieagrp {
 		fsl,pins = <
 			IMX8QXP_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00		0x06000021
-- 
2.34.1



From luoxueqin at kylinos.cn  Sun Dec  1 19:19:15 2024
From: luoxueqin at kylinos.cn (xueqin Luo)
Date: Mon,  2 Dec 2024 11:19:15 +0800
Subject: [PATCH -next 0/2] *** fix overflows seen when writing limit attributes ***
Message-ID: <20241202031917.23741-1-luoxueqin@kylinos.cn>

DIV_ROUND_CLOSEST() after kstrtoul() results in an overflow if a large
number such as 18446744073709551615 is provided by the user.
Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
This commit was inspired by commit: 57ee12b6c514.

xueqin Luo (2):
  wifi: mt76: mt7996: fix overflows seen when writing limit attributes
  mt76: mt7915: fix overflows seen when writing limit attributes

 drivers/net/wireless/mediatek/mt76/mt7915/init.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt7996/init.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

-- 
2.34.1



From luoxueqin at kylinos.cn  Sun Dec  1 19:19:16 2024
From: luoxueqin at kylinos.cn (xueqin Luo)
Date: Mon,  2 Dec 2024 11:19:16 +0800
Subject: [PATCH -next 1/2] wifi: mt76: mt7996: fix overflows seen when writing limit attributes
In-Reply-To: <20241202031917.23741-1-luoxueqin@kylinos.cn>
References: <20241202031917.23741-1-luoxueqin@kylinos.cn>
Message-ID: <20241202031917.23741-2-luoxueqin@kylinos.cn>

DIV_ROUND_CLOSEST() after kstrtoul() results in an overflow if a large
number such as 18446744073709551615 is provided by the user.
Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
This commit was inspired by commit: 57ee12b6c514.

Fixes: 6879b2e94172 ("wifi: mt76: mt7996: add thermal sensor device support")
Signed-off-by: xueqin Luo <luoxueqin at kylinos.cn>
---
 drivers/net/wireless/mediatek/mt76/mt7996/init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
index 5e96973226bb..3a175222f8ba 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
@@ -85,7 +85,7 @@ static ssize_t mt7996_thermal_temp_store(struct device *dev,
 		return ret;
 
 	mutex_lock(&phy->dev->mt76.mutex);
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 40, 130);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, 40 * 1000, 130 * 1000), 1000);
 
 	/* add a safety margin ~10 */
 	if ((i - 1 == MT7996_CRIT_TEMP_IDX &&
-- 
2.34.1



From xiazhengqiao at huaqin.corp-partner.google.com  Sun Dec  1 19:20:32 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Mon,  2 Dec 2024 11:20:32 +0800
Subject: [PATCH v4 1/4] dt-bindings: arm: mediatek: Add MT8186 Chinchou Chromebook
In-Reply-To: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <20241202032035.29045-2-xiazhengqiao@huaqin.corp-partner.google.com>

Add an entry for the MT8186 based Chinchou Chromebook, also known as the
ASUS Chromebook CZ12 Flip (CZ1204F) and CZ12(CZ1204C).

Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../devicetree/bindings/arm/mediatek.yaml     | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 1d4bb50fcd8d..3efab59b8a73 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -239,6 +239,34 @@ properties:
           - enum:
               - mediatek,mt8183-pumpkin
           - const: mediatek,mt8183
+      - description: Google Chinchou (Asus Chromebook CZ1104CM2A/CZ1204CM2A)
+        items:
+          - const: google,chinchou-sku0
+          - const: google,chinchou-sku2
+          - const: google,chinchou-sku4
+          - const: google,chinchou-sku5
+          - const: google,chinchou
+          - const: mediatek,mt8186
+      - description: Google Chinchou (Asus Chromebook CZ1104FM2A/CZ1204FM2A/CZ1104CM2A/CZ1204CM2A)
+        items:
+          - const: google,chinchou-sku1
+          - const: google,chinchou-sku17
+          - const: google,chinchou-sku3
+          - const: google,chinchou-sku6
+          - const: google,chinchou-sku7
+          - const: google,chinchou-sku20
+          - const: google,chinchou-sku22
+          - const: google,chinchou-sku23
+          - const: google,chinchou
+          - const: mediatek,mt8186
+      - description: Google Chinchou360 (Asus Chromebook CZ1104FM2A/CZ1204FM2A Flip)
+        items:
+          - const: google,chinchou-sku16
+          - const: google,chinchou-sku18
+          - const: google,chinchou-sku19
+          - const: google,chinchou-sku21
+          - const: google,chinchou
+          - const: mediatek,mt8186
       - description: Google Magneton (Lenovo IdeaPad Slim 3 Chromebook (14M868))
         items:
           - const: google,steelix-sku393219
-- 
2.17.1



From xiazhengqiao at huaqin.corp-partner.google.com  Sun Dec  1 19:20:33 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Mon,  2 Dec 2024 11:20:33 +0800
Subject: [PATCH v4 2/4] arm64: dts: mediatek: Add MT8186 Chinchou Chromebooks
In-Reply-To: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <20241202032035.29045-3-xiazhengqiao@huaqin.corp-partner.google.com>

MT8186 chinchou, known as ASUS Chromebook CZ12 Flip (CZ1204F)
and CZ12(CZ1204C), is a MT8186 based laptop.
It is based on the "corsola" design.It includes chinchou and chinchou360,
including LTE, stylus, touchscreen combinations.

Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
---
 arch/arm64/boot/dts/mediatek/Makefile         |   3 +
 .../mediatek/mt8186-corsola-chinchou-sku0.dts |  18 +
 .../mediatek/mt8186-corsola-chinchou-sku1.dts |  35 ++
 .../mt8186-corsola-chinchou-sku16.dts         |  29 ++
 .../dts/mediatek/mt8186-corsola-chinchou.dtsi | 321 ++++++++++++++++++
 5 files changed, 406 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 8fd7b2bb7a15..0db7770e8907 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -55,6 +55,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
new file mode 100644
index 000000000000..5d012bc4ff0d
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-chinchou.dtsi"
+
+/ {
+	model = "Google chinchou CZ1104CM2A/CZ1204CM2A";
+	compatible = "google,chinchou-sku0", "google,chinchou-sku2",
+			"google,chinchou-sku4", "google,chinchou-sku5",
+			"google,chinchou", "mediatek,mt8186";
+};
+
+&gpio_keys {
+	status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
new file mode 100644
index 000000000000..c18f473f6a0f
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-chinchou.dtsi"
+
+/ {
+	model = "Google chinchou CZ1104FM2A/CZ1204FM2A/CZ1104CM2A/CZ1204CM2A";
+	compatible = "google,chinchou-sku1", "google,chinchou-sku17",
+			"google,chinchou-sku3", "google,chinchou-sku6",
+			"google,chinchou-sku7", "google,chinchou-sku20",
+			"google,chinchou-sku22", "google,chinchou-sku23",
+			"google,chinchou", "mediatek,mt8186";
+};
+
+&gpio_keys {
+	status = "disabled";
+};
+
+&i2c1 {
+	i2c-scl-internal-delay-ns = <10000>;
+
+	touchscreen: touchscreen at 41 {
+		compatible = "ilitek,ili2901";
+		reg = <0x41>;
+		interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&touchscreen_pins>;
+		reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>;
+		vccio-supply = <&pp1800_tchscr_report_disable>;
+		vcc33-supply = <&pp3300_z2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts
new file mode 100644
index 000000000000..eb377de1fcde
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-chinchou.dtsi"
+
+/ {
+	model = "Google chinchou CZ1104FM2A/CZ1204FM2A";
+	compatible = "google,chinchou-sku16", "google,chinchou-sku18",
+			"google,chinchou-sku19", "google,chinchou-sku21",
+			"google,chinchou", "mediatek,mt8186";
+};
+
+&i2c1 {
+	i2c-scl-internal-delay-ns = <10000>;
+
+	touchscreen: touchscreen at 41 {
+		compatible = "ilitek,ili2901";
+		reg = <0x41>;
+		interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&touchscreen_pins>;
+		reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>;
+		vccio-supply = <&pp1800_tchscr_report_disable>;
+		vcc33-supply = <&pp3300_z2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi
new file mode 100644
index 000000000000..c3835c7c4444
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi
@@ -0,0 +1,321 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola.dtsi"
+
+/ {
+	/delete-node/ speaker-codec;
+
+	pp1000_edpbrdg: regulator-pp1000-edpbrdg {
+		compatible = "regulator-fixed";
+		regulator-name = "pp1000_edpbrdg";
+		pinctrl-names = "default";
+		pinctrl-0 = <&en_pp1000_edpbrdg>;
+		enable-active-high;
+		regulator-boot-on;
+		gpio = <&pio 29 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&pp3300_z2>;
+	};
+
+	pp1800_edpbrdg_dx: regulator-pp1800-edpbrdg-dx {
+		compatible = "regulator-fixed";
+		regulator-name = "pp1800_edpbrdg_dx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&en_pp1800_edpbrdg>;
+		enable-active-high;
+		regulator-boot-on;
+		gpio = <&pio 30 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&mt6366_vio18_reg>;
+	};
+
+	pp3300_edp_dx: regulator-pp3300-edp-dx {
+		compatible = "regulator-fixed";
+		regulator-name = "pp3300_edp_dx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&en_pp3300_edpbrdg>;
+		enable-active-high;
+		regulator-boot-on;
+		gpio = <&pio 31 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&pp3300_z2>;
+	};
+
+	pp1800_tchscr_report_disable: regulator-pp1800-tchscr-report-disable {
+		compatible = "regulator-fixed";
+		regulator-name = "pp1800_tchscr_report_disable";
+		pinctrl-names = "default";
+		regulator-boot-on;
+		pinctrl-0 = <&touch_pin_report>;
+		gpio = <&pio 37 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&dsi_out {
+	remote-endpoint = <&anx7625_in>;
+};
+
+&i2c0 {
+	clock-frequency = <400000>;
+
+	anx_bridge: anx7625 at 58 {
+		compatible = "analogix,anx7625";
+		reg = <0x58>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&anx7625_pins>;
+		enable-gpios = <&pio 96 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&pio 98 GPIO_ACTIVE_HIGH>;
+		vdd10-supply = <&pp1000_edpbrdg>;
+		vdd18-supply = <&pp1800_edpbrdg_dx>;
+		vdd33-supply = <&pp3300_edp_dx>;
+		analogix,lane0-swing = /bits/ 8 <0x70 0x30>;
+		analogix,lane1-swing = /bits/ 8 <0x70 0x30>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				anx7625_in: endpoint {
+					remote-endpoint = <&dsi_out>;
+					data-lanes = <0 1 2 3>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				anx7625_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+		};
+
+		aux-bus {
+			panel: panel {
+				compatible = "edp-panel";
+				power-supply = <&pp3300_disp_x>;
+				backlight = <&backlight_lcd0>;
+
+				port {
+					panel_in: endpoint {
+						remote-endpoint = <&anx7625_out>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&i2c2 {
+	/delete-node/ trackpad at 15;
+
+	touchpad at 15 {
+		compatible = "hid-over-i2c";
+		reg = <0x15>;
+		interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>;
+		post-power-on-delay-ms = <10>;
+		hid-descr-addr = <0x0001>;
+		vdd-supply = <&pp3300_s3>;
+		wakeup-source;
+	};
+};
+
+&i2c5 {
+	clock-frequency = <400000>;
+	/delete-node/ codec at 1a;
+
+	rt5650: rt5650 at 1a {
+		compatible = "realtek,rt5650";
+		reg = <0x1a>;
+		avdd-supply = <&mt6366_vio18_reg>;
+		cpvdd-supply = <&mt6366_vio18_reg>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&speaker_codec_pins_default>;
+		cbj-sleeve-gpios = <&pio 150 GPIO_ACTIVE_HIGH>;
+		interrupt-parent = <&pio>;
+		interrupts = <17 IRQ_TYPE_EDGE_BOTH>;
+		#sound-dai-cells = <0>;
+		realtek,dmic1-data-pin = <2>;
+		realtek,jd-mode = <2>;
+	};
+};
+
+&i2c_tunnel {
+	/delete-node/ sbs-battery at b;
+
+	battery: sbs-battery at f {
+		compatible = "sbs,sbs-battery";
+		reg = <0xf>;
+		sbs,i2c-retry-count = <2>;
+		sbs,poll-retry-count = <1>;
+	};
+};
+
+&keyboard_controller {
+	keypad,num-columns = <15>;
+
+	function-row-physmap = <
+		MATRIX_KEY(0x00, 0x02, 0)        /* T1 */
+		MATRIX_KEY(0x03, 0x02, 0)        /* T2 */
+		MATRIX_KEY(0x02, 0x02, 0)        /* T3 */
+		MATRIX_KEY(0x01, 0x02, 0)        /* T4 */
+		MATRIX_KEY(0x03, 0x04, 0)        /* T5 */
+		MATRIX_KEY(0x02, 0x04, 0)        /* T6 */
+		MATRIX_KEY(0x01, 0x04, 0)        /* T7 */
+		MATRIX_KEY(0x02, 0x09, 0)        /* T8 */
+		MATRIX_KEY(0x01, 0x09, 0)        /* T9 */
+		MATRIX_KEY(0x00, 0x04, 0)        /* T10 */
+		MATRIX_KEY(0x00, 0x01, 0)        /* T11 */
+		MATRIX_KEY(0x01, 0x05, 0)        /* T12 */
+	>;
+
+	linux,keymap = <
+		CROS_STD_MAIN_KEYMAP
+		MATRIX_KEY(0x00, 0x02, KEY_BACK)           /* T1 */
+		MATRIX_KEY(0x03, 0x02, KEY_REFRESH)        /* T2 */
+		MATRIX_KEY(0x02, 0x02, KEY_ZOOM)           /* T3 */
+		MATRIX_KEY(0x01, 0x02, KEY_SCALE)          /* T4 */
+		MATRIX_KEY(0x03, 0x04, KEY_SYSRQ)          /* T5 */
+		MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN) /* T6 */
+		MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP)   /* T7 */
+		MATRIX_KEY(0x02, 0x09, KEY_MUTE)           /* T8 */
+		MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN)	   /* T9 */
+		MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP)	   /* T10 */
+		MATRIX_KEY(0x00, 0x01, KEY_MICMUTE)        /* T11 */
+		MATRIX_KEY(0x01, 0x05, KEY_CONTROLPANEL)   /* T12 */
+		MATRIX_KEY(0x03, 0x05, KEY_PREVIOUSSONG)   /* T13 */
+		MATRIX_KEY(0x00, 0x09, KEY_PLAYPAUSE)	   /* T14 */
+		MATRIX_KEY(0x00, 0x0b, KEY_NEXTSONG)	   /* T15 */
+		MATRIX_KEY(0x03, 0x00, KEY_LEFTMETA)	   /* Search*/
+		MATRIX_KEY(0x01, 0x0e, KEY_LEFTCTRL)	   /* Left Control*/
+		MATRIX_KEY(0x06, 0x0d, KEY_LEFTALT)        /* Left ALT*/
+		MATRIX_KEY(0x03, 0x0e, KEY_RIGHTCTRL)      /* Right Control*/
+		MATRIX_KEY(0x06, 0x0a, KEY_BACKSLASH)      /* BACKSLASH*/
+	>;
+};
+
+&mmc1_pins_default {
+	pins-clk {
+		drive-strength = <MTK_DRIVE_8mA>;
+	};
+
+	pins-cmd-dat {
+		drive-strength = <MTK_DRIVE_8mA>;
+	};
+};
+
+&mmc1_pins_uhs {
+	pins-clk {
+		drive-strength = <MTK_DRIVE_8mA>;
+	};
+
+	pins-cmd-dat {
+		drive-strength = <MTK_DRIVE_8mA>;
+	};
+};
+
+&pen_insert {
+	wakeup-event-action = <EV_ACT_ANY>;
+};
+
+&pio {
+	anx7625_pins: anx7625-pins {
+		pins-int {
+			pinmux = <PINMUX_GPIO9__FUNC_GPIO9>;
+			input-enable;
+			bias-disable;
+		};
+
+		pins-reset {
+			pinmux = <PINMUX_GPIO98__FUNC_GPIO98>;
+			output-low;
+		};
+
+		pins-power-en {
+			pinmux = <PINMUX_GPIO96__FUNC_GPIO96>;
+			output-low;
+		};
+	};
+
+	en_pp1000_edpbrdg: pp1000-edpbrdg-en-pins {
+		pins-vreg-en {
+			pinmux = <PINMUX_GPIO29__FUNC_GPIO29>;
+			output-low;
+		};
+	};
+
+	en_pp1800_edpbrdg: pp1800-edpbrdg-en-pins {
+		pins-vreg-en {
+			pinmux = <PINMUX_GPIO30__FUNC_GPIO30>;
+			output-low;
+		};
+	};
+
+	en_pp3300_edpbrdg: pp3300-edpbrdg-en-pins {
+		pins-vreg-en {
+			pinmux = <PINMUX_GPIO31__FUNC_GPIO31>;
+			output-low;
+		};
+	};
+
+	touch_pin_report: pin-report-pins {
+		pins-touch-en {
+			pinmux = <PINMUX_GPIO37__FUNC_GPIO37>;
+			output-low;
+		};
+	};
+};
+
+&sound {
+	compatible = "mediatek,mt8186-mt6366-rt5650-sound";
+	model = "mt8186_rt5650";
+	mediatek,adsp = <&adsp>;
+
+	audio-routing =
+		"Headphone", "HPOL",
+		"Headphone", "HPOR",
+		"IN1P", "Headset Mic",
+		"IN1N", "Headset Mic",
+		"Speakers", "SPOL",
+		"Speakers", "SPOR",
+		"HDMI1", "TX";
+
+	hs-playback-dai-link {
+		codec {
+			sound-dai = <&rt5650>;
+		};
+	};
+
+	hs-capture-dai-link {
+		codec {
+			sound-dai = <&rt5650>;
+		};
+	};
+
+	spk-share-dai-link {
+	};
+
+	spk-hdmi-playback-dai-link {
+		codec {
+			sound-dai = <&it6505dptx>;
+		};
+	};
+};
+
+&touchscreen_pins {
+	/delete-node/ pins-report-sw;
+};
+
+&wifi_enable_pin {
+	pins-wifi-enable {
+		pinmux = <PINMUX_GPIO51__FUNC_GPIO51>;
+	};
+};
+
+&wifi_pwrseq {
+	reset-gpios = <&pio 51 GPIO_ACTIVE_LOW>;
+};
-- 
2.17.1



From xiazhengqiao at huaqin.corp-partner.google.com  Sun Dec  1 19:20:34 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Mon,  2 Dec 2024 11:20:34 +0800
Subject: [PATCH v4 3/4] arm64: dts: mediatek: Add exton node for DP bridge
In-Reply-To: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <20241202032035.29045-4-xiazhengqiao@huaqin.corp-partner.google.com>

Add exton node for DP bridge to make the display work properly.

Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
---
 arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
index cfcc7909dfe6..e324e3fd347e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
@@ -424,6 +424,7 @@
 		ovdd-supply = <&mt6366_vsim2_reg>;
 		pwr18-supply = <&pp1800_dpbrdg_dx>;
 		reset-gpios = <&pio 177 GPIO_ACTIVE_LOW>;
+		extcon = <&usbc_extcon>;
 
 		ports {
 			#address-cells = <1>;
@@ -1656,6 +1657,11 @@
 				try-power-role = "source";
 			};
 		};
+
+		usbc_extcon: extcon0 {
+			compatible = "google,extcon-usbc-cros-ec";
+			google,usb-port-id = <0>;
+		};
 	};
 };
 
-- 
2.17.1



From xiazhengqiao at huaqin.corp-partner.google.com  Sun Dec  1 19:20:35 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Mon,  2 Dec 2024 11:20:35 +0800
Subject: [PATCH v4 4/4] arm64: dts: mediatek: Modify audio codec name for pmic
In-Reply-To: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <20241202032035.29045-5-xiazhengqiao@huaqin.corp-partner.google.com>

change `codec` in pmic (in mt8186-corsola.dtsi) to `audio-codec`

Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
---
 arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
index e324e3fd347e..cebb134331fb 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
@@ -1276,7 +1276,7 @@
 		interrupts-extended = <&pio 201 IRQ_TYPE_LEVEL_HIGH>;
 		#interrupt-cells = <2>;
 
-		mt6366codec: codec {
+		mt6366codec: audio-codec {
 			compatible = "mediatek,mt6366-sound", "mediatek,mt6358-sound";
 			Avdd-supply = <&mt6366_vaud28_reg>;
 			mediatek,dmic-mode = <1>; /* one-wire */
-- 
2.17.1



From damon.ding at rock-chips.com  Sun Dec  1 19:28:13 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 2 Dec 2024 11:28:13 +0800
Subject: [PATCH v1 04/10] phy: phy-rockchip-samsung-hdptx: Add support for
 eDP mode
In-Reply-To: <h4giob7bcrh7qmtepti6huym2llw4ujfmeff76vrgpahb5zy6x@dz6zghsifww5>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <2131853.KlZ2vcFHjT@diego>
 <6e1f35c0-5ea8-414f-b3ea-4e7222c605ef@rock-chips.com>
 <2886747.Y6S9NjorxK@diego>
 <h4giob7bcrh7qmtepti6huym2llw4ujfmeff76vrgpahb5zy6x@dz6zghsifww5>
Message-ID: <2342f342-672c-447e-90d8-674b748af6a4@rock-chips.com>

Hi,

On 2024/12/2 6:59, Sebastian Reichel wrote:
> Hi,
> 
> On Sat, Nov 30, 2024 at 09:25:12PM +0100, Heiko St?bner wrote:
>> Am Freitag, 29. November 2024, 03:43:57 CET schrieb Damon Ding:
>>> On 2024/11/27 19:04, Heiko St?bner wrote:
>>>> Am Mittwoch, 27. November 2024, 12:00:10 CET schrieb Damon Ding:
>>>>> On 2024/11/27 17:29, Heiko St?bner wrote:
>>>>>> Am Mittwoch, 27. November 2024, 08:51:51 CET schrieb Damon Ding:
>>>>>>> +static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode,
>>>>>>> +				 int submode)
>>>>>>> +{
>>>>>>> +	return 0;
>>>>>>> +}
>>>>>> analogix_dp_phy_power_on
>>>>>> I think it might make sense to go the same way as the DCPHY and also
>>>>>> naneng combophy, to use #phy-cells = 1 to select the phy-mode via DT .
>>>>>>
>>>>>> See [0] for Sebastians initial suggestion regarding the DC-PHY.
>>>>>> The naneng combophy already uses that scheme of mode-selection too.
>>>>>>
>>>>>> There is of course the issue of backwards-compatibility, but that can be
>>>>>> worked around in the binding with something like:
>>>>>>
>>>>>>     '#phy-cells':
>>>>>>        enum: [0, 1]
>>>>>>        description: |
>>>>>>          If #phy-cells is 0, PHY mode is set to PHY_TYPE_HDMI
>>>>>>          If #phy-cells is 1 mode is set in the PHY cells. Supported modes are:
>>>>>>            - PHY_TYPE_HDMI
>>>>>>            - PHY_TYPE_DP
>>>>>>          See include/dt-bindings/phy/phy.h for constants.
>>>>>>
>>>>>> PHY_TYPE_HDMI needs to be added to include/dt-bindings/phy/phy.h
>>>>>> but PHY_TYPE_DP is already there.
>>>>>>
>>>>>> That way we would standardize on one form of accessing phy-types
>>>>>> on rk3588 :-) .
>>>>>>
>>>>>> Also see the Mediatek CSI rx phy doing this too already [1]
>>>>>>
>>>>>>
>>>>>> Heiko
>>>>>>
>>>>>> [0] https://lore.kernel.org/linux-rockchip/udad4qf3o7kt45nuz6gxsvsmprh4rnyfxfogopmih6ucznizih at 7oj2jrnlfonz/
>>>>>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/phy/mediatek,mt8365-csi-rx.yaml
>>>>>>
>>>>>
>>>>> It is really a nice way to separate HDMI and DP modes.
>>>
>>> I apologize for reopening the discussion about the phy-types setting.
>>
>> there is definitly no need to apologize. We're trying to find the best
>> solution afterall :-) .
>>
>>> With the .set_mode() of struct phy_ops, the HDMI and eDP dynamic
>>> switching can be achieved, which just depends on the right setting of
>>> enum phy_mode in include/linux/phy/phy.h. So the previous way of
>>> configuring phy mode may be also good.
>>
>> I think the deciding factor is, is there a use-case for needing to switch
>> modes at runtime.
>>
>> I do think the mode for the dc-phy and also the hdptx-phy is pretty much
>> decided by the board design.
>>
>> I.e. when you end up in a DP-connector (or eDP-panel) on your board you
>> need DP mode, and when you end up in a hdmi-connector you need the
>> HDMI phy mode.
>>
>> So I think the phy-mode for the hdptx-phy is largely dictated by the static
>> board definition (like devicetree), hence going with the dt-argument for
>> the mode.
>>
>> Like similar to the Naneng combophy, selecting its mode via argument
>> because deciding if it ends up in a sata port is a board-design thing.
>>
>> Is there a use-case where you need to switch at runtime between
>> HDMI and eDP? Like starting the phy in eDP mode but then needing
>> to switch to HDMI mode, while the device is running?

Indeed, we have the board as you described, on which the DP-connector 
and HDMI-connector both have been configured.

And the dynamic switching is more useful for RK3576, which has the same 
eDP/HDMI design as RK3588 but only one eDP controller/HDMI 
controller/HDPTX phy. We can only enable both of eDP/HDMI by this way.

> 
> I believe the eDP controller can only use the PHY in eDP mode and
> the HDMI controller can only use it in HDMI mode. So in order to
> support runtime switching, the following options are possible:
> 
> 1. Enable both controllers, the PHY decides which one is really
>     used, the other one is basically a non-functional dummy device
>     until the PHY is reconfigured. This requires the set_mode()
>     callback, since the HDMI and eDP drivers both expect their
>     PHY to be enabled.
> 
> 2. Properly enable / disable the used controller, so that only one
>     controller is active at the same time. In this case the switching
>     is handled one layer above and the PHY has nothing to do with it.
>     The phy_enable call from each controller would just set it up in
>     the right mode.
> 
> I guess option 1 is the hacked solution, which is easier to
> implement as DRM's hotplug abilities are quite limited at the moment
> as far as I know. I think the second solution looks much cleaner and
> should be prefered for upstream. That solution does not require
> calling set_mode() for runtime switching making this whole argument
> void :)
> 

Your friendly and detailed analysis has brought me some valuable 
insights. :)

The option 2 is really a better way to support the dynamic switching, 
and we still need the .set_mode() to select the configurations for 
either eDP or HDMI in HDPTX phy at the controller level. Would you mind
elaborating on the useful way to choose the phy mode for the second 
solution?

> FWIW I think the DT argument based mode setting and the runtime set_mode
> are not necessarily mutual exclusive. In theory one could support both
> and adding set_mode support later does not change any ABI as far as
> I can see. Basically handle it like pin mux/configuration settings,
> which are usually automatically handled by the device core based on
> DT information, except for some drivers which have special needs.
> 

>>> And other phys may want to support dynamic switching too, like the
>>> Rockchip USBDP combo phy.
>>
>> I guess USBDP is special in that in also does both modes dynamical
>> depending on its use (like type-c with option DP altmode)
> 
> The USBDP PHY is indeed quite different from the PHYs in your list
> above, but for a different reason: All the combined PHYs you listed
> above only support one mode at the same time. E.g. you need to
> decide between PCIe, SATA and USB3 mode for the Naneng combophy.
> 
> For the USBDP PHY the modes are not mutually exclusive. The USB
> controller can request the USBDP PHY in USB mode at the same time
> as the DP controller requests it in DP mode. Some additional
> registers configure how the lanes are being muxed. A typcial setup
> would be 2 lanes for USB3 and 2 lanes for DP.
> 
> Greetings,
> 
> -- Sebastian

Best regards,
Damon



From victor.liu at nxp.com  Sun Dec  1 18:56:23 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:23 +0800
Subject: [PATCH v5 07/19] dt-bindings: interrupt-controller: Add i.MX8qxp Display Controller interrupt controller
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-8-victor.liu@nxp.com>

i.MX8qxp Display Controller has a built-in interrupt controller to support
Enable/Status/Preset/Clear interrupt bit.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v5:
* No change.

v4:
* No change.

v3:
* Collect Rob's R-b tag.

v2:
* Drop unneeded "|". (Krzysztof)

 .../fsl,imx8qxp-dc-intc.yaml                  | 318 ++++++++++++++++++
 1 file changed, 318 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml
new file mode 100644
index 000000000000..6985ee644a25
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml
@@ -0,0 +1,318 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/fsl,imx8qxp-dc-intc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller interrupt controller
+
+description: |
+  The Display Controller has a built-in interrupt controller with the following
+  features for all relevant HW events:
+
+  * Enable bit (mask)
+  * Status bit (set by an HW event)
+  * Preset bit (can be used by SW to set status)
+  * Clear bit (used by SW to reset the status)
+
+  Each interrupt can be connected as IRQ (maskable) and/or NMI (non-maskable).
+  Alternatively the un-masked trigger signals for all HW events are provided,
+  allowing it to use a global interrupt controller instead.
+
+  Each interrupt can be protected against SW running in user mode. In that case,
+  only privileged AHB access can control the interrupt status.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-intc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 1
+
+  interrupts:
+    items:
+      - description: store9 shadow load interrupt(blit engine)
+      - description: store9 frame complete interrupt(blit engine)
+      - description: store9 sequence complete interrupt(blit engine)
+      - description:
+          extdst0 shadow load interrupt
+          (display controller, content stream 0)
+      - description:
+          extdst0 frame complete interrupt
+          (display controller, content stream 0)
+      - description:
+          extdst0 sequence complete interrupt
+          (display controller, content stream 0)
+      - description:
+          extdst4 shadow load interrupt
+          (display controller, safety stream 0)
+      - description:
+          extdst4 frame complete interrupt
+          (display controller, safety stream 0)
+      - description:
+          extdst4 sequence complete interrupt
+          (display controller, safety stream 0)
+      - description:
+          extdst1 shadow load interrupt
+          (display controller, content stream 1)
+      - description:
+          extdst1 frame complete interrupt
+          (display controller, content stream 1)
+      - description:
+          extdst1 sequence complete interrupt
+          (display controller, content stream 1)
+      - description:
+          extdst5 shadow load interrupt
+          (display controller, safety stream 1)
+      - description:
+          extdst5 frame complete interrupt
+          (display controller, safety stream 1)
+      - description:
+          extdst5 sequence complete interrupt
+          (display controller, safety stream 1)
+      - description:
+          disengcfg0 shadow load interrupt
+          (display controller, display stream 0)
+      - description:
+          disengcfg0 frame complete interrupt
+          (display controller, display stream 0)
+      - description:
+          disengcfg0 sequence complete interrupt
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt0
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt1
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt2
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt3
+          (display controller, display stream 0)
+      - description:
+          signature0 shadow load interrupt
+          (display controller, display stream 0)
+      - description:
+          signature0 measurement valid interrupt
+          (display controller, display stream 0)
+      - description:
+          signature0 error condition interrupt
+          (display controller, display stream 0)
+      - description:
+          disengcfg1 shadow load interrupt
+          (display controller, display stream 1)
+      - description:
+          disengcfg1 frame complete interrupt
+          (display controller, display stream 1)
+      - description:
+          disengcfg1 sequence complete interrupt
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt0
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt1
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt2
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt3
+          (display controller, display stream 1)
+      - description:
+          signature1 shadow load interrupt
+          (display controller, display stream 1)
+      - description:
+          signature1 measurement valid interrupt
+          (display controller, display stream 1)
+      - description:
+          signature1 error condition interrupt
+          (display controller, display stream 1)
+      - description: reserved
+      - description:
+          command sequencer error condition interrupt(command sequencer)
+      - description:
+          common control software interrupt0(common control)
+      - description:
+          common control software interrupt1(common control)
+      - description:
+          common control software interrupt2(common control)
+      - description:
+          common control software interrupt3(common control)
+      - description:
+          framegen0 synchronization status activated interrupt
+          (display controller, safety stream 0)
+      - description:
+          framegen0 synchronization status deactivated interrupt
+          (display controller, safety stream 0)
+      - description:
+          framegen0 synchronization status activated interrupt
+          (display controller, content stream 0)
+      - description:
+          framegen0 synchronization status deactivated interrupt
+          (display controller, content stream 0)
+      - description:
+          framegen1 synchronization status activated interrupt
+          (display controller, safety stream 1)
+      - description:
+          framegen1 synchronization status deactivated interrupt
+          (display controller, safety stream 1)
+      - description:
+          framegen1 synchronization status activated interrupt
+          (display controller, content stream 1)
+      - description:
+          framegen1 synchronization status deactivated interrupt
+          (display controller, content stream 1)
+    minItems: 49
+
+  interrupt-names:
+    items:
+      - const: store9_shdload
+      - const: store9_framecomplete
+      - const: store9_seqcomplete
+      - const: extdst0_shdload
+      - const: extdst0_framecomplete
+      - const: extdst0_seqcomplete
+      - const: extdst4_shdload
+      - const: extdst4_framecomplete
+      - const: extdst4_seqcomplete
+      - const: extdst1_shdload
+      - const: extdst1_framecomplete
+      - const: extdst1_seqcomplete
+      - const: extdst5_shdload
+      - const: extdst5_framecomplete
+      - const: extdst5_seqcomplete
+      - const: disengcfg_shdload0
+      - const: disengcfg_framecomplete0
+      - const: disengcfg_seqcomplete0
+      - const: framegen0_int0
+      - const: framegen0_int1
+      - const: framegen0_int2
+      - const: framegen0_int3
+      - const: sig0_shdload
+      - const: sig0_valid
+      - const: sig0_error
+      - const: disengcfg_shdload1
+      - const: disengcfg_framecomplete1
+      - const: disengcfg_seqcomplete1
+      - const: framegen1_int0
+      - const: framegen1_int1
+      - const: framegen1_int2
+      - const: framegen1_int3
+      - const: sig1_shdload
+      - const: sig1_valid
+      - const: sig1_error
+      - const: reserved
+      - const: cmdseq_error
+      - const: comctrl_sw0
+      - const: comctrl_sw1
+      - const: comctrl_sw2
+      - const: comctrl_sw3
+      - const: framegen0_primsync_on
+      - const: framegen0_primsync_off
+      - const: framegen0_secsync_on
+      - const: framegen0_secsync_off
+      - const: framegen1_primsync_on
+      - const: framegen1_primsync_off
+      - const: framegen1_secsync_on
+      - const: framegen1_secsync_off
+    minItems: 49
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupt-controller
+  - "#interrupt-cells"
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    interrupt-controller at 56180040 {
+        compatible = "fsl,imx8qxp-dc-intc";
+        reg = <0x56180040 0x60>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+        interrupt-controller;
+        interrupt-parent = <&dc0_irqsteer>;
+        #interrupt-cells = <1>;
+        interrupts = <448>, <449>, <450>,  <64>,
+                      <65>,  <66>,  <67>,  <68>,
+                      <69>,  <70>, <193>, <194>,
+                     <195>, <196>, <197>,  <72>,
+                      <73>,  <74>,  <75>,  <76>,
+                      <77>,  <78>,  <79>,  <80>,
+                      <81>, <199>, <200>, <201>,
+                     <202>, <203>, <204>, <205>,
+                     <206>, <207>, <208>,   <5>,
+                       <0>,   <1>,   <2>,   <3>,
+                       <4>,  <82>,  <83>,  <84>,
+                      <85>, <209>, <210>, <211>,
+                     <212>;
+        interrupt-names = "store9_shdload",
+                          "store9_framecomplete",
+                          "store9_seqcomplete",
+                          "extdst0_shdload",
+                          "extdst0_framecomplete",
+                          "extdst0_seqcomplete",
+                          "extdst4_shdload",
+                          "extdst4_framecomplete",
+                          "extdst4_seqcomplete",
+                          "extdst1_shdload",
+                          "extdst1_framecomplete",
+                          "extdst1_seqcomplete",
+                          "extdst5_shdload",
+                          "extdst5_framecomplete",
+                          "extdst5_seqcomplete",
+                          "disengcfg_shdload0",
+                          "disengcfg_framecomplete0",
+                          "disengcfg_seqcomplete0",
+                          "framegen0_int0",
+                          "framegen0_int1",
+                          "framegen0_int2",
+                          "framegen0_int3",
+                          "sig0_shdload",
+                          "sig0_valid",
+                          "sig0_error",
+                          "disengcfg_shdload1",
+                          "disengcfg_framecomplete1",
+                          "disengcfg_seqcomplete1",
+                          "framegen1_int0",
+                          "framegen1_int1",
+                          "framegen1_int2",
+                          "framegen1_int3",
+                          "sig1_shdload",
+                          "sig1_valid",
+                          "sig1_error",
+                          "reserved",
+                          "cmdseq_error",
+                          "comctrl_sw0",
+                          "comctrl_sw1",
+                          "comctrl_sw2",
+                          "comctrl_sw3",
+                          "framegen0_primsync_on",
+                          "framegen0_primsync_off",
+                          "framegen0_secsync_on",
+                          "framegen0_secsync_off",
+                          "framegen1_primsync_on",
+                          "framegen1_primsync_off",
+                          "framegen1_secsync_on",
+                          "framegen1_secsync_off";
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:18 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:18 +0800
Subject: [PATCH v5 02/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller blit engine
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-3-victor.liu@nxp.com>

i.MX8qxp Display Controller contains a blit engine for raster graphics.
It may read up to 3 source images from memory and computes one destination
image from it, which is written back to memory.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v5:
* No change.

v4:
* Collect Rob's R-b tag.

v3:
* New patch. (Rob)

 .../imx/fsl,imx8qxp-dc-blit-engine.yaml       | 204 ++++++++++++++++++
 1 file changed, 204 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml
new file mode 100644
index 000000000000..45db6da39e20
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml
@@ -0,0 +1,204 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blit-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Blit Engine
+
+description: |
+  A blit operation (block based image transfer) reads up to 3 source images
+  from memory and computes one destination image from it, which is written
+  back to memory. The following basic operations are supported:
+
+  * Buffer Fill
+    Fills a buffer with constant color
+
+  * Buffer Copy
+    Copies one source to a destination buffer.
+
+  * Image Blend
+    Combines two source images by a blending equation and writes result to
+    destination (which can be one of the sources).
+
+  * Image Rop2/3
+    Combines up to three source images by a logical equation (raster operation)
+    and writes result to destination (which can be one of the sources).
+
+  * Image Flip
+    Mirrors the source image in horizontal and/or vertical direction.
+
+  * Format Convert
+    Convert between the supported color and buffer formats.
+
+  * Color Transform
+    Modify colors by linear or non-linear transformations.
+
+  * Image Scale
+    Changes size of the source image.
+
+  * Image Rotate
+    Rotates the source image by any angle.
+
+  * Image Filter
+    Performs an FIR filter operation on the source image.
+
+  * Image Warp
+    Performs a re-sampling of the source image with any pattern. The sample
+    point positions are read from a compressed coordinate buffer.
+
+  * Buffer Pack
+    Writes an image with color components stored in up to three different
+    buffers (planar formats) into a single buffer (packed format).
+
+  * Chroma Resample
+    Converts between different YUV formats that differ in chroma sampling rate
+    (4:4:4, 4:2:2, 4:2:0).
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-blit-engine
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^blitblend@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-blitblend
+
+  "^clut@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-clut
+
+  "^fetchdecode@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchdecode
+
+  "^fetcheco@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetcheco
+
+  "^fetchwarp@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchwarp
+
+  "^filter@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-filter
+
+  "^hscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-hscaler
+
+  "^matrix@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-matrix
+
+  "^rop@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-rop
+
+  "^store@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-store
+
+  "^vscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-vscaler
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    blit-engine at 56180820 {
+        compatible = "fsl,imx8qxp-dc-blit-engine";
+        reg = <0x56180820 0x13c>, <0x56181000 0x3400>;
+        reg-names = "pec", "cfg";
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        fetchdecode at 56180820 {
+            compatible = "fsl,imx8qxp-dc-fetchdecode";
+            reg = <0x56180820 0x10>, <0x56181000 0x404>;
+            reg-names = "pec", "cfg";
+        };
+
+        store at 56180940 {
+            compatible = "fsl,imx8qxp-dc-store";
+            reg = <0x56180940 0x1c>, <0x56184000 0x5c>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <0>, <1>, <2>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  1 18:56:32 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:32 +0800
Subject: [DO NOT MERGE PATCH v5 16/19] arm64: dts: imx8qxp: Add display controller subsystem
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-17-victor.liu@nxp.com>

Add display controller subsystem in i.MX8qxp SoC.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Krzysztof)

 .../arm64/boot/dts/freescale/imx8-ss-dc0.dtsi | 408 ++++++++++++++++++
 .../boot/dts/freescale/imx8qxp-ss-dc.dtsi     | 236 ++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |  25 +-
 3 files changed, 668 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
new file mode 100644
index 000000000000..0db345204b89
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+dc0_axi_ext_clk: clock-dc0-axi-ext {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <800000000>;
+	clock-output-names = "dc0_axi_ext_clk";
+};
+
+dc0_axi_int_clk: clock-dc0-axi-int {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <400000000>;
+	clock-output-names = "dc0_axi_int_clk";
+};
+
+dc0_cfg_clk: clock-dc0-cfg {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <100000000>;
+	clock-output-names = "dc0_cfg_clk";
+};
+
+dc0_subsys: bus at 56000000 {
+	compatible = "simple-bus";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0x56000000 0x0 0x56000000 0x1000000>;
+
+	dc0_irqsteer: interrupt-controller at 56000000 {
+		compatible = "fsl,imx-irqsteer";
+		reg = <0x56000000 0x1000>;
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		#interrupt-cells = <1>;
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&dc0_lis_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+		fsl,channel = <0>;
+		fsl,num-irqs = <512>;
+	};
+
+	dc0_disp_lpcg: clock-controller at 56010000 {
+		reg = <0x56010000 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_DC_0 IMX_SC_PM_CLK_MISC0>,
+			 <&clk IMX_SC_R_DC_0 IMX_SC_PM_CLK_MISC1>;
+		clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>;
+		clock-output-names = "dc0_disp0_lpcg_clk", "dc0_disp1_lpcg_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_lis_lpcg: clock-controller at 56010004 {
+		reg = <0x56010004 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "dc0_lis_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_disp_ctrl_link_mst0_lpcg: clock-controller at 56010008 {
+		reg = <0x56010008 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "dc0_disp_ctrl_link_mst0_lpcg_msi_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_pixel_combiner_lpcg: clock-controller at 56010010 {
+		reg = <0x56010010 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "dc0_pixel_combiner_lpcg_apb_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_lpcg: clock-controller at 56010014 {
+		reg = <0x56010014 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>, <&dc0_axi_int_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_5>;
+		clock-output-names = "dc0_lpcg_cfg_clk",
+				     "dc0_lpcg_axi_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_pc: pixel-combiner at 56020000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x56020000 0x10000>;
+		clocks = <&dc0_pixel_combiner_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "apb";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+		status = "disabled";
+
+		channel at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			status = "disabled";
+
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_combiner_ch0_dc0_disp0: endpoint {
+					remote-endpoint = <&dc0_disp0_dc0_pixel_combiner_ch0>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				dc0_pixel_combiner_ch0_dc0_pixel_link0: endpoint {
+					remote-endpoint = <&dc0_pixel_link0_dc0_pixel_combiner_ch0>;
+				};
+			};
+		};
+
+		channel at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			status = "disabled";
+
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_combiner_ch1_dc0_disp1: endpoint {
+					remote-endpoint = <&dc0_disp1_dc0_pixel_combiner_ch1>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				dc0_pixel_combiner_ch1_dc0_pixel_link1: endpoint {
+					remote-endpoint = <&dc0_pixel_link1_dc0_pixel_combiner_ch1>;
+				};
+			};
+		};
+	};
+
+	dc0: display-controller at 56180000 {
+		reg = <0x56180000 0x40000>;
+		clocks = <&dc0_lpcg IMX_LPCG_CLK_4>;
+		power-domains = <&pd IMX_SC_R_DC_0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		status = "disabled";
+
+		dc0_intc: interrupt-controller at 56180040 {
+			reg = <0x56180040 0x60>;
+			clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+			interrupt-controller;
+			interrupt-parent = <&dc0_irqsteer>;
+			#interrupt-cells = <1>;
+			interrupts = <448>, <449>, <450>,  <64>,
+				      <65>,  <66>,  <67>,  <68>,
+				      <69>,  <70>, <193>, <194>,
+				     <195>, <196>, <197>,  <72>,
+				      <73>,  <74>,  <75>,  <76>,
+				      <77>,  <78>,  <79>,  <80>,
+				      <81>, <199>, <200>, <201>,
+				     <202>, <203>, <204>, <205>,
+				     <206>, <207>, <208>,   <5>,
+				       <0>,   <1>,   <2>,   <3>,
+				       <4>,  <82>,  <83>,  <84>,
+				      <85>, <209>, <210>, <211>,
+				     <212>;
+			interrupt-names = "store9_shdload",
+					  "store9_framecomplete",
+					  "store9_seqcomplete",
+					  "extdst0_shdload",
+					  "extdst0_framecomplete",
+					  "extdst0_seqcomplete",
+					  "extdst4_shdload",
+					  "extdst4_framecomplete",
+					  "extdst4_seqcomplete",
+					  "extdst1_shdload",
+					  "extdst1_framecomplete",
+					  "extdst1_seqcomplete",
+					  "extdst5_shdload",
+					  "extdst5_framecomplete",
+					  "extdst5_seqcomplete",
+					  "disengcfg_shdload0",
+					  "disengcfg_framecomplete0",
+					  "disengcfg_seqcomplete0",
+					  "framegen0_int0",
+					  "framegen0_int1",
+					  "framegen0_int2",
+					  "framegen0_int3",
+					  "sig0_shdload",
+					  "sig0_valid",
+					  "sig0_error",
+					  "disengcfg_shdload1",
+					  "disengcfg_framecomplete1",
+					  "disengcfg_seqcomplete1",
+					  "framegen1_int0",
+					  "framegen1_int1",
+					  "framegen1_int2",
+					  "framegen1_int3",
+					  "sig1_shdload",
+					  "sig1_valid",
+					  "sig1_error",
+					  "reserved",
+					  "cmdseq_error",
+					  "comctrl_sw0",
+					  "comctrl_sw1",
+					  "comctrl_sw2",
+					  "comctrl_sw3",
+					  "framegen0_primsync_on",
+					  "framegen0_primsync_off",
+					  "framegen0_secsync_on",
+					  "framegen0_secsync_off",
+					  "framegen1_primsync_on",
+					  "framegen1_primsync_off",
+					  "framegen1_secsync_on",
+					  "framegen1_secsync_off";
+		};
+
+		dc0_pixel_engine: pixel-engine at 56180800 {
+			reg = <0x56180800 0xac00>;
+			clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			dc0_constframe0: constframe at 56180960 {
+				reg = <0x56180960 0xc>, <0x56184400 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst0: extdst at 56180980 {
+				reg = <0x56180980 0x1c>, <0x56184800 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <3>, <4>, <5>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_constframe4: constframe at 561809a0 {
+				reg = <0x561809a0 0xc>, <0x56184c00 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst4: extdst at 561809c0 {
+				reg = <0x561809c0 0x1c>, <0x56185000 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <6>, <7>, <8>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_constframe1: constframe at 561809e0 {
+				reg = <0x561809e0 0xc>, <0x56185400 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst1: extdst at 56180a00 {
+				reg = <0x56180a00 0x1c>, <0x56185800 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <9>, <10>, <11>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_constframe5: constframe at 56180a20 {
+				reg = <0x56180a20 0xc>, <0x56185c00 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst5: extdst at 56180a40 {
+				reg = <0x56180a40 0x1c>, <0x56186000 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <12>, <13>, <14>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_fetchwarp2: fetchwarp at 56180a60 {
+				reg = <0x56180a60 0x10>, <0x56186400 0x190>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_fetchlayer0: fetchlayer at 56180ac0 {
+				reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend0: layerblend at 56180ba0 {
+				reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend1: layerblend at 56180bc0 {
+				reg = <0x56180bc0 0x10>, <0x5618a800 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend2: layerblend at 56180be0 {
+				reg = <0x56180be0 0x10>, <0x5618ac00 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend3: layerblend at 56180c00 {
+				reg = <0x56180c00 0x10>, <0x5618b000 0x20>;
+				reg-names = "pec", "cfg";
+			};
+		};
+
+		dc0_display_engine0: display-engine at 5618b400 {
+			reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
+			reg-names = "top", "cfg";
+			interrupt-parent = <&dc0_intc>;
+			interrupts = <15>, <16>, <17>;
+			interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			dc0_framegen0: framegen at 5618b800 {
+				reg = <0x5618b800 0x98>;
+				clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <18>, <19>, <20>, <21>,
+					     <41>, <42>, <43>, <44>;
+				interrupt-names = "int0", "int1", "int2", "int3",
+						  "primsync_on", "primsync_off",
+						  "secsync_on", "secsync_off";
+			};
+
+			dc0_tcon0: tcon at 5618c800 {
+				reg = <0x5618c800 0x588>;
+
+				port {
+					dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
+						remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
+					};
+				};
+			};
+		};
+
+		dc0_display_engine1: display-engine at 5618b420 {
+			reg = <0x5618b420 0x14>, <0x5618d400 0x1c00>;
+			reg-names = "top", "cfg";
+			interrupt-parent = <&dc0_intc>;
+			interrupts = <25>, <26>, <27>;
+			interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			power-domains = <&pd IMX_SC_R_DC_0_PLL_1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			dc0_framegen1: framegen at 5618d400 {
+				reg = <0x5618d400 0x98>;
+				clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_1>;
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <28>, <29>, <30>, <31>,
+					     <45>, <46>, <47>, <48>;
+				interrupt-names = "int0", "int1", "int2", "int3",
+						  "primsync_on", "primsync_off",
+						  "secsync_on", "secsync_off";
+			};
+
+			dc0_tcon1: tcon at 5618e400 {
+				reg = <0x5618e400 0x588>;
+
+				port {
+					dc0_disp1_dc0_pixel_combiner_ch1: endpoint {
+						remote-endpoint = <&dc0_pixel_combiner_ch1_dc0_disp1>;
+					};
+				};
+			};
+		};
+	};
+
+	dc0_pl_msi_bus: bus at 56200000 {
+		reg = <0x56200000 0x100000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&dc0_irqsteer>;
+		interrupts = <320>;
+		ranges;
+		clocks = <&dc0_disp_ctrl_link_mst0_lpcg IMX_LPCG_CLK_4>,
+			 <&dc0_disp_ctrl_link_mst0_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "msi", "ahb";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
new file mode 100644
index 000000000000..299720d8c99e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+&dc0 {
+	compatible = "fsl,imx8qxp-dc";
+};
+
+&dc0_constframe0 {
+	compatible = "fsl,imx8qxp-dc-constframe";
+};
+
+&dc0_constframe1 {
+	compatible = "fsl,imx8qxp-dc-constframe";
+};
+
+&dc0_constframe4 {
+	compatible = "fsl,imx8qxp-dc-constframe";
+};
+
+&dc0_constframe5 {
+	compatible = "fsl,imx8qxp-dc-constframe";
+};
+
+&dc0_disp_ctrl_link_mst0_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_disp_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_display_engine0 {
+	compatible = "fsl,imx8qxp-dc-display-engine";
+};
+
+&dc0_display_engine1 {
+	compatible = "fsl,imx8qxp-dc-display-engine";
+};
+
+&dc0_extdst0 {
+	compatible = "fsl,imx8qxp-dc-extdst";
+};
+
+&dc0_extdst1 {
+	compatible = "fsl,imx8qxp-dc-extdst";
+};
+
+&dc0_extdst4 {
+	compatible = "fsl,imx8qxp-dc-extdst";
+};
+
+&dc0_extdst5 {
+	compatible = "fsl,imx8qxp-dc-extdst";
+};
+
+&dc0_fetchlayer0 {
+	compatible = "fsl,imx8qxp-dc-fetchlayer";
+};
+
+&dc0_fetchwarp2 {
+	compatible = "fsl,imx8qxp-dc-fetchwarp";
+};
+
+&dc0_framegen0 {
+	compatible = "fsl,imx8qxp-dc-framegen";
+};
+
+&dc0_framegen1 {
+	compatible = "fsl,imx8qxp-dc-framegen";
+};
+
+&dc0_intc {
+	compatible = "fsl,imx8qxp-dc-intc";
+};
+
+&dc0_layerblend0 {
+	compatible = "fsl,imx8qxp-dc-layerblend";
+};
+
+&dc0_layerblend1 {
+	compatible = "fsl,imx8qxp-dc-layerblend";
+};
+
+&dc0_layerblend2 {
+	compatible = "fsl,imx8qxp-dc-layerblend";
+};
+
+&dc0_layerblend3 {
+	compatible = "fsl,imx8qxp-dc-layerblend";
+};
+
+&dc0_lis_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_pc {
+	compatible = "fsl,imx8qxp-pixel-combiner";
+};
+
+&dc0_pixel_combiner_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_pixel_engine {
+	compatible = "fsl,imx8qxp-dc-pixel-engine";
+};
+
+&dc0_pl_msi_bus {
+	compatible = "fsl,imx8qxp-display-pixel-link-msi-bus", "simple-pm-bus";
+};
+
+&dc0_tcon0 {
+	compatible = "fsl,imx8qxp-dc-tcon";
+};
+
+&dc0_tcon1 {
+	compatible = "fsl,imx8qxp-dc-tcon";
+};
+
+&scu {
+	dc0_pixel_link0: dc0-pixel-link0 {
+		compatible = "fsl,imx8qxp-dc-pixel-link";
+		fsl,dc-id = /bits/ 8 <0>;
+		fsl,dc-stream-id = /bits/ 8 <0>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* from dc0 pixel combiner channel0 */
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_link0_dc0_pixel_combiner_ch0: endpoint {
+					remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_pixel_link0>;
+				};
+			};
+
+			/* to PXL2DPIs in MIPI/LVDS combo subsystems */
+			port at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				status = "disabled";
+
+				dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint at 0 {
+					reg = <0>;
+				};
+
+				dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint at 1 {
+					reg = <1>;
+				};
+			};
+
+			/* unused */
+			port at 2 {
+				reg = <2>;
+				status = "disabled";
+			};
+
+			/* unused */
+			port at 3 {
+				reg = <3>;
+				status = "disabled";
+			};
+
+			/* to imaging subsystem */
+			port at 4 {
+				reg = <4>;
+				status = "disabled";
+			};
+		};
+	};
+
+	dc0_pixel_link1: dc0-pixel-link1 {
+		compatible = "fsl,imx8qxp-dc-pixel-link";
+		fsl,dc-id = /bits/ 8 <0>;
+		fsl,dc-stream-id = /bits/ 8 <1>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* from dc0 pixel combiner channel1 */
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_link1_dc0_pixel_combiner_ch1: endpoint {
+					remote-endpoint = <&dc0_pixel_combiner_ch1_dc0_pixel_link1>;
+				};
+			};
+
+			/* to PXL2DPIs in MIPI/LVDS combo subsystems */
+			port at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				status = "disabled";
+
+				dc0_pixel_link1_mipi_lvds_1_pxl2dpi: endpoint at 0 {
+					reg = <0>;
+				};
+
+				dc0_pixel_link1_mipi_lvds_0_pxl2dpi: endpoint at 1 {
+					reg = <1>;
+				};
+			};
+
+			/* to parallel display interface in ADMA subsystem */
+			port at 2 {
+				reg = <2>;
+				status = "disabled";
+			};
+
+			/* unused */
+			port at 3 {
+				reg = <3>;
+				status = "disabled";
+			};
+
+			/* unused */
+			port at 4 {
+				reg = <4>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 05138326f0a5..35cc82cbbcd1 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -20,6 +20,27 @@ / {
 	#size-cells = <2>;
 
 	aliases {
+		dc0 = &dc0;
+		dc0-constframe0 = &dc0_constframe0;
+		dc0-constframe1 = &dc0_constframe1;
+		dc0-constframe4 = &dc0_constframe4;
+		dc0-constframe5 = &dc0_constframe5;
+		dc0-display-engine0 = &dc0_display_engine0;
+		dc0-display-engine1 = &dc0_display_engine1;
+		dc0-extdst0 = &dc0_extdst0;
+		dc0-extdst1 = &dc0_extdst1;
+		dc0-extdst4 = &dc0_extdst4;
+		dc0-extdst5 = &dc0_extdst5;
+		dc0-fetchlayer0 = &dc0_fetchlayer0;
+		dc0-fetchwarp2 = &dc0_fetchwarp2;
+		dc0-framegen0 = &dc0_framegen0;
+		dc0-framegen1 = &dc0_framegen1;
+		dc0-layerblend0 = &dc0_layerblend0;
+		dc0-layerblend1 = &dc0_layerblend1;
+		dc0-layerblend2 = &dc0_layerblend2;
+		dc0-layerblend3 = &dc0_layerblend3;
+		dc0-tcon0 = &dc0_tcon0;
+		dc0-tcon1 = &dc0_tcon1;
 		ethernet0 = &fec1;
 		ethernet1 = &fec2;
 		gpio0 = &lsio_gpio0;
@@ -206,7 +227,7 @@ psci {
 		method = "smc";
 	};
 
-	system-controller {
+	scu: system-controller {
 		compatible = "fsl,imx-scu";
 		mbox-names = "tx0",
 			     "rx0",
@@ -323,6 +344,7 @@ map0 {
 	#include "imx8-ss-vpu.dtsi"
 	#include "imx8-ss-cm40.dtsi"
 	#include "imx8-ss-gpu0.dtsi"
+	#include "imx8-ss-dc0.dtsi"
 	#include "imx8-ss-adma.dtsi"
 	#include "imx8-ss-conn.dtsi"
 	#include "imx8-ss-ddr.dtsi"
@@ -332,6 +354,7 @@ map0 {
 
 #include "imx8qxp-ss-img.dtsi"
 #include "imx8qxp-ss-vpu.dtsi"
+#include "imx8qxp-ss-dc.dtsi"
 #include "imx8qxp-ss-adma.dtsi"
 #include "imx8qxp-ss-conn.dtsi"
 #include "imx8qxp-ss-lsio.dtsi"
-- 
2.34.1



From luoxueqin at kylinos.cn  Sun Dec  1 19:19:17 2024
From: luoxueqin at kylinos.cn (xueqin Luo)
Date: Mon,  2 Dec 2024 11:19:17 +0800
Subject: [PATCH -next 2/2] mt76: mt7915: fix overflows seen when writing limit attributes
In-Reply-To: <20241202031917.23741-1-luoxueqin@kylinos.cn>
References: <20241202031917.23741-1-luoxueqin@kylinos.cn>
Message-ID: <20241202031917.23741-3-luoxueqin@kylinos.cn>

DIV_ROUND_CLOSEST() after kstrtoul() results in an overflow if a large
number such as 18446744073709551615 is provided by the user.
Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
This commit was inspired by commit: 57ee12b6c514.

Fixes: 02ee68b95d81 ("mt76: mt7915: add control knobs for thermal throttling")
Signed-off-by: xueqin Luo <luoxueqin at kylinos.cn>
---
 drivers/net/wireless/mediatek/mt76/mt7915/init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 6bef96e3d2a3..77d82ccd7307 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -82,7 +82,7 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev,
 		return ret;
 
 	mutex_lock(&phy->dev->mt76.mutex);
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 60, 130);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, 60 * 1000, 130 * 1000), 1000);
 
 	if ((i - 1 == MT7915_CRIT_TEMP_IDX &&
 	     val > phy->throttle_temp[MT7915_MAX_TEMP_IDX]) ||
-- 
2.34.1



From xiazhengqiao at huaqin.corp-partner.google.com  Sun Dec  1 19:20:31 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Mon,  2 Dec 2024 11:20:31 +0800
Subject: [PATCH v4 0/4] arm64: dts: mediatek: Add MT8186 Chinchou
Message-ID: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>

This is v4 of the MT8186 Chromebook device tree series to support
MT8186 chinchou platform. It is based on the "corsola" design.
It includes chinchou and chinchou360, including LTE, stylus,
touchscreen combinations.

Changes in v4:
- modify 'rt1019p_pins_default' to 'speaker_codec_pins_default'
- Move usbc_extcon out of typec
- Link to v3: https://patchwork.kernel.org/project/linux-arm-kernel/cover/20241021072626.15102-1-xiazhengqiao at huaqin.corp-partner.google.com/

Changes in v3:
- Add a patch to change codec in pmic (in mt8186-corsola.dtsi) to audio-codec
- Link to v2: https://lore.kernel.org/all/20241018091135.17075-1-xiazhengqiao at huaqin.corp-partner.google.com/

Changes in v2:
- Modify location of "const: google,chinchou-sku17" in mediatek.yaml
- rename "pin-report" to "pin-report-pins"
- add "vcc33-supply" and "vcc33-supply" 
- rename "cbj-sleeve-gpio" to "cbj-sleeve-gpios"
- modify subnode of sound 
- Link to v1: https://lore.kernel.org/all/172900161180.733089.8963543745385219831.robh at kernel.org/

Zhengqiao Xia (4):
  dt-bindings: arm: mediatek: Add MT8186 Chinchou Chromebook
  arm64: dts: mediatek: Add MT8186 Chinchou Chromebooks
  arm64: dts: mediatek: Add exton node for DP bridge
  arm64: dts: mediatek: Modify audio codec name for pmic

 .../devicetree/bindings/arm/mediatek.yaml     |  28 ++
 arch/arm64/boot/dts/mediatek/Makefile         |   3 +
 .../mediatek/mt8186-corsola-chinchou-sku0.dts |  18 +
 .../mediatek/mt8186-corsola-chinchou-sku1.dts |  35 ++
 .../mt8186-corsola-chinchou-sku16.dts         |  29 ++
 .../dts/mediatek/mt8186-corsola-chinchou.dtsi | 321 ++++++++++++++++++
 .../boot/dts/mediatek/mt8186-corsola.dtsi     |   8 +-
 7 files changed, 441 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi

-- 
2.17.1



From victor.liu at nxp.com  Sun Dec  1 18:56:33 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  2 Dec 2024 10:56:33 +0800
Subject: [DO NOT MERGE PATCH v5 17/19] arm64: dts: imx8qxp: Add MIPI-LVDS combo subsystems
In-Reply-To: <20241202025635.1274467-1-victor.liu@nxp.com>
References: <20241202025635.1274467-1-victor.liu@nxp.com>
Message-ID: <20241202025635.1274467-18-victor.liu@nxp.com>

The MIPI-LVDS combo subsystems are peripherals of pixel link MSI
bus in i.MX8qxp display controller subsystem.  Add the MIPI-LVDS
combo subsystems.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Francesco)

 .../boot/dts/freescale/imx8qxp-ss-dc.dtsi     |   4 +
 .../dts/freescale/imx8qxp-ss-mipi-lvds.dtsi   | 437 ++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   3 +
 3 files changed, 444 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
index 299720d8c99e..94c46a20597c 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
@@ -152,10 +152,12 @@ port at 1 {
 
 				dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint at 0 {
 					reg = <0>;
+					remote-endpoint = <&mipi_lvds_0_pxl2dpi_dc0_pixel_link0>;
 				};
 
 				dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint at 1 {
 					reg = <1>;
+					remote-endpoint = <&mipi_lvds_1_pxl2dpi_dc0_pixel_link0>;
 				};
 			};
 
@@ -207,10 +209,12 @@ port at 1 {
 
 				dc0_pixel_link1_mipi_lvds_1_pxl2dpi: endpoint at 0 {
 					reg = <0>;
+					remote-endpoint = <&mipi_lvds_1_pxl2dpi_dc0_pixel_link1>;
 				};
 
 				dc0_pixel_link1_mipi_lvds_0_pxl2dpi: endpoint at 1 {
 					reg = <1>;
+					remote-endpoint = <&mipi_lvds_0_pxl2dpi_dc0_pixel_link1>;
 				};
 			};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi
new file mode 100644
index 000000000000..fa7e7c33518e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi
@@ -0,0 +1,437 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/firmware/imx/rsrc.h>
+
+/ {
+	mipi_lvds_0_ipg_clk: clock-mipi-lvds0-ipg {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <120000000>;
+		clock-output-names = "mipi_lvds_0_ipg_clk";
+	};
+
+	mipi_lvds_1_ipg_clk: clock-mipi-lvds1-ipg {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <120000000>;
+		clock-output-names = "mipi_lvds_1_ipg_clk";
+	};
+};
+
+&dc0_pl_msi_bus {
+	mipi_lvds_0_irqsteer: interrupt-controller at 56220000 {
+		compatible = "fsl,imx-irqsteer";
+		reg = <0x56220000 0x1000>;
+		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		#interrupt-cells = <1>;
+		clocks = <&mipi_lvds_0_lis_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+		fsl,channel = <0>;
+		fsl,num-irqs = <32>;
+	};
+
+	mipi_lvds_0_csr: syscon at 56221000 {
+		compatible = "fsl,imx8qxp-mipi-lvds-csr", "syscon", "simple-mfd";
+		reg = <0x56221000 0x1000>;
+		clocks = <&mipi_lvds_0_di_mipi_lvds_regs_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+
+		mipi_lvds_0_pxl2dpi: pxl2dpi {
+			compatible = "fsl,imx8qxp-pxl2dpi";
+			fsl,sc-resource = <IMX_SC_R_MIPI_0>;
+			power-domains = <&pd IMX_SC_R_MIPI_0>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					mipi_lvds_0_pxl2dpi_dc0_pixel_link0: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&dc0_pixel_link0_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_0_pxl2dpi_dc0_pixel_link1: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&dc0_pixel_link1_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+
+				port at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+			};
+		};
+
+		mipi_lvds_0_ldb: ldb {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,imx8qxp-ldb";
+			clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>,
+				 <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+			clock-names = "pixel", "bypass";
+			assigned-clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>;
+			assigned-clock-parents = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+			power-domains = <&pd IMX_SC_R_LVDS_0>;
+			status = "disabled";
+
+			channel at 0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				phys = <&mipi_lvds_0_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0>;
+					};
+				};
+			};
+
+			channel at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				phys = <&mipi_lvds_0_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1>;
+					};
+				};
+			};
+		};
+	};
+
+	mipi_lvds_0_lis_lpcg: clock-controller at 56223000 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56223000 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_0_lis_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0>;
+	};
+
+	mipi_lvds_0_di_mipi_lvds_regs_lpcg: clock-controller at 56223004 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56223004 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_0_di_mipi_lvds_regs_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0>;
+	};
+
+	mipi_lvds_0_pwm_lpcg: clock-controller at 5622300c {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x5622300c 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_0_PWM_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_0_ipg_clk>,
+			 <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>,
+				<IMX_LPCG_CLK_1>;
+		clock-output-names = "mipi_lvds_0_pwm_lpcg_clk",
+				     "mipi_lvds_0_pwm_lpcg_ipg_clk",
+				     "mipi_lvds_0_pwm_lpcg_32k_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0_PWM_0>;
+	};
+
+	mipi_lvds_0_i2c0_lpcg: clock-controller at 56223010 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56223010 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_0_I2C_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_0_i2c0_lpcg_clk",
+				     "mipi_lvds_0_i2c0_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0_I2C_0>;
+	};
+
+	mipi_lvds_0_pwm: pwm at 56224000 {
+		compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
+		reg = <0x56224000 0x1000>;
+		interrupt-parent = <&mipi_lvds_0_irqsteer>;
+		interrupts = <12>;
+		clocks = <&mipi_lvds_0_pwm_lpcg IMX_LPCG_CLK_4>,
+			 <&mipi_lvds_0_pwm_lpcg IMX_LPCG_CLK_0>;
+		clock-names = "ipg", "per";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_0_PWM_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		#pwm-cells = <3>;
+		power-domains = <&pd IMX_SC_R_MIPI_0_PWM_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_0_i2c0: i2c at 56226000 {
+		compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x56226000 0x1000>;
+		interrupt-parent = <&mipi_lvds_0_irqsteer>;
+		interrupts = <8>;
+		clocks = <&mipi_lvds_0_i2c0_lpcg IMX_LPCG_CLK_0>,
+			 <&mipi_lvds_0_i2c0_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_0_I2C_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd IMX_SC_R_MIPI_0_I2C_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_0_phy: phy at 56228300 {
+		compatible = "fsl,imx8qxp-mipi-dphy";
+		reg = <0x56228300 0x100>;
+		clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_PHY>;
+		clock-names = "phy_ref";
+		assigned-clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_PHY>;
+		assigned-clock-parents = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+		#phy-cells = <0>;
+		fsl,syscon = <&mipi_lvds_0_csr>;
+		power-domains = <&pd IMX_SC_R_MIPI_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_1_irqsteer: interrupt-controller at 56240000 {
+		compatible = "fsl,imx-irqsteer";
+		reg = <0x56240000 0x1000>;
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		#interrupt-cells = <1>;
+		clocks = <&mipi_lvds_1_lis_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+		fsl,channel = <0>;
+		fsl,num-irqs = <32>;
+	};
+
+	mipi_lvds_1_csr: syscon at 56241000 {
+		compatible = "fsl,imx8qxp-mipi-lvds-csr", "syscon", "simple-mfd";
+		reg = <0x56241000 0x1000>;
+		clocks = <&mipi_lvds_1_di_mipi_lvds_regs_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+
+		mipi_lvds_1_pxl2dpi: pxl2dpi {
+			compatible = "fsl,imx8qxp-pxl2dpi";
+			fsl,sc-resource = <IMX_SC_R_MIPI_1>;
+			power-domains = <&pd IMX_SC_R_MIPI_1>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					mipi_lvds_1_pxl2dpi_dc0_pixel_link1: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&dc0_pixel_link1_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_1_pxl2dpi_dc0_pixel_link0: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&dc0_pixel_link0_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+
+				port at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch0: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&mipi_lvds_1_ldb_ch0_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch1: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&mipi_lvds_1_ldb_ch1_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+			};
+		};
+
+		mipi_lvds_1_ldb: ldb {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,imx8qxp-ldb";
+			clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_MISC2>,
+				 <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_BYPASS>;
+			clock-names = "pixel", "bypass";
+			assigned-clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_MISC2>;
+			assigned-clock-parents = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_BYPASS>;
+			power-domains = <&pd IMX_SC_R_LVDS_1>;
+			status = "disabled";
+
+			channel at 0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				phys = <&mipi_lvds_1_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_1_ldb_ch0_mipi_lvds_1_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch0>;
+					};
+				};
+			};
+
+			channel at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				phys = <&mipi_lvds_1_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_1_ldb_ch1_mipi_lvds_1_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch1>;
+					};
+				};
+			};
+		};
+	};
+
+	mipi_lvds_1_lis_lpcg: clock-controller at 56243000 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56243000 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_1_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_1_lis_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_1>;
+	};
+
+	mipi_lvds_1_di_mipi_lvds_regs_lpcg: clock-controller at 56243004 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56243004 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_1_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_1_di_mipi_lvds_regs_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_1>;
+	};
+
+	mipi_lvds_1_pwm_lpcg: clock-controller at 5624300c {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x5624300c 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_1_PWM_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_1_ipg_clk>,
+			 <&mipi_lvds_1_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>,
+				<IMX_LPCG_CLK_1>;
+		clock-output-names = "mipi_lvds_1_pwm_lpcg_clk",
+				     "mipi_lvds_1_pwm_lpcg_ipg_clk",
+				     "mipi_lvds_1_pwm_lpcg_32k_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_1_PWM_0>;
+	};
+
+	mipi_lvds_1_i2c0_lpcg: clock-controller at 56243010 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56243010 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_1_I2C_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_1_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_1_i2c0_lpcg_clk",
+				     "mipi_lvds_1_i2c0_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_1_I2C_0>;
+	};
+
+	mipi_lvds_1_pwm: pwm at 56244000 {
+		compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
+		reg = <0x56244000 0x1000>;
+		interrupt-parent = <&mipi_lvds_1_irqsteer>;
+		interrupts = <12>;
+		clocks = <&mipi_lvds_1_pwm_lpcg IMX_LPCG_CLK_4>,
+			 <&mipi_lvds_1_pwm_lpcg IMX_LPCG_CLK_0>;
+		clock-names = "ipg", "per";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_1_PWM_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		#pwm-cells = <3>;
+		power-domains = <&pd IMX_SC_R_MIPI_1_PWM_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_1_i2c0: i2c at 56246000 {
+		compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x56246000 0x1000>;
+		interrupt-parent = <&mipi_lvds_1_irqsteer>;
+		interrupts = <8>;
+		clocks = <&mipi_lvds_1_i2c0_lpcg IMX_LPCG_CLK_0>,
+			 <&mipi_lvds_1_i2c0_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_1_I2C_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd IMX_SC_R_MIPI_1_I2C_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_1_phy: phy at 56248300 {
+		compatible = "fsl,imx8qxp-mipi-dphy";
+		reg = <0x56248300 0x100>;
+		clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_PHY>;
+		clock-names = "phy_ref";
+		assigned-clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_PHY>;
+		assigned-clock-parents = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_BYPASS>;
+		#phy-cells = <0>;
+		fsl,syscon = <&mipi_lvds_1_csr>;
+		power-domains = <&pd IMX_SC_R_MIPI_1>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 35cc82cbbcd1..25adc1090dec 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -55,6 +55,8 @@ aliases {
 		i2c1 = &i2c1;
 		i2c2 = &i2c2;
 		i2c3 = &i2c3;
+		mipi-dphy0 = &mipi_lvds_0_phy;
+		mipi-dphy1 = &mipi_lvds_1_phy;
 		mmc0 = &usdhc1;
 		mmc1 = &usdhc2;
 		mmc2 = &usdhc3;
@@ -355,6 +357,7 @@ map0 {
 #include "imx8qxp-ss-img.dtsi"
 #include "imx8qxp-ss-vpu.dtsi"
 #include "imx8qxp-ss-dc.dtsi"
+#include "imx8qxp-ss-mipi-lvds.dtsi"
 #include "imx8qxp-ss-adma.dtsi"
 #include "imx8qxp-ss-conn.dtsi"
 #include "imx8qxp-ss-lsio.dtsi"
-- 
2.34.1



From dsimic at manjaro.org  Sun Dec  1 19:55:03 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 02 Dec 2024 04:55:03 +0100
Subject: [PATCH] arm64: dts: rockchip: enable rng on all rk356x
In-Reply-To: <20241201234613.52322-1-pbrobinson@gmail.com>
References: <a> <20241201234613.52322-1-pbrobinson@gmail.com>
Message-ID: <302bdae2f4defeefe88ea4018a0be11f@manjaro.org>

Hello Peter,

On 2024-12-02 00:46, Peter Robinson wrote:
> The rk356x rng is available on both the rk3566 and rk3568
> parts, the IP is all self contained within the SoCs so
> it's enabled already by default on rk3568 so let's enable
> it in the base rk356x.dtsi so it's enabled consistently
> everywhere.

Please, go through the mailing list threads [1][2] that have led us
to the current state.  To sum it up, it isn't about what's supported
in the two RK356x SoC variants, but about the RK3566's HWRNG being
disabled because the testing showed that it produces unacceptably
low quality of random data, for some yet unknown reason.

[1] 
https://lore.kernel.org/linux-rockchip/cover.1720969799.git.daniel at makrotopia.org/T/#u
[2] 
https://lore.kernel.org/linux-rockchip/cover.1722355365.git.daniel at makrotopia.org/T/#u

> Signed-off-by: Peter Robinson <pbrobinson at gmail.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3568.dtsi      | 4 ----
>  arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 1 -
>  2 files changed, 5 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> index ecaefe208e3e..9dc09db5034d 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> @@ -397,10 +397,6 @@ power-domain at RK3568_PD_PIPE {
>  	};
>  };
> 
> -&rng {
> -	status = "okay";
> -};
> -
>  &usb_host0_xhci {
>  	phys = <&usb2phy0_otg>, <&combphy0 PHY_TYPE_USB3>;
>  	phy-names = "usb2-phy", "usb3-phy";
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> index 62be06f3b863..2994cddb3464 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> @@ -1038,7 +1038,6 @@ rng: rng at fe388000 {
>  		clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>;
>  		clock-names = "core", "ahb";
>  		resets = <&cru SRST_TRNG_NS>;
> -		status = "disabled";
>  	};
> 
>  	i2s0_8ch: i2s at fe400000 {


From wenst at chromium.org  Sun Dec  1 20:24:36 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 2 Dec 2024 12:24:36 +0800
Subject: [PATCH v2 0/8] MT8188 DT and binding fixes
In-Reply-To: <20241001113052.3124869-1-fshao@chromium.org>
References: <20241001113052.3124869-1-fshao@chromium.org>
Message-ID: <CAGXv+5E4=dKkUo73x5vCMHawcr9AUd71LyLmDbdyOdJZv0ZBaQ@mail.gmail.com>

Hi,

On Tue, Oct 1, 2024 at 7:31?PM Fei Shao <fshao at chromium.org> wrote:
>
> Hi,
>
> This series is split from a previous series[*] to focus on few fixes and
> improvements around MediaTek MT8188 device tree and associated bindings,
> and addressed comments and carried tags from the previous series.
>
> [*]: https://lore.kernel.org/all/20240909111535.528624-1-fshao at chromium.org/
> [v1]: https://lore.kernel.org/all/20240925110044.3678055-1-fshao at chromium.org/
>
> Regards,
> Fei
>
> Changes in v2:
> - new patch to MediaTek jpeg and vcodec bindings
> - new patch to move MT8188 SPI NOR cell properties
> - revise commit message of vdec power domain changes
>
> Fei Shao (8):

>   dt-bindings: power: mediatek: Add another nested power-domain layer

This one ^

>   dt-bindings: PCI: mediatek-gen3: Allow exact number of clocks only

>   dt-bindings: media: mediatek,jpeg: Relax IOMMU max item count
>   dt-bindings: media: mediatek,vcodec: Revise description

and these two ^ have not been picked up, and now v6.13-rc1 has DT
validation errors for MT8188:

/ssd1/wenst/linux/mtk/arch/arm64/boot/dts/mediatek/mt8188-evb.dtb:
syscon at 10006000:
power-controller:power-domain at 15:power-domain at 16:power-domain at 29:power-domain at 30:
Unevaluated properties are not allowed ('power-domain at 31',
'power-domain at 32' were unexpected)
    from schema $id:
http://devicetree.org/schemas/mfd/mediatek,mt8195-scpsys.yaml#
/ssd1/wenst/linux/mtk/arch/arm64/boot/dts/mediatek/mt8188-evb.dtb:
power-controller:
power-domain at 15:power-domain at 16:power-domain at 29:power-domain at 30:
Unevaluated properties are not allowed ('power-domain at 31',
'power-domain at 32' were unexpected)
    from schema $id:
http://devicetree.org/schemas/power/mediatek,power-controller.yaml#

/ssd1/wenst/linux/mtk/arch/arm64/boot/dts/mediatek/mt8188-evb.dtb:
jpeg-decoder at 1a040000: iommus: [[101, 685], [101, 686], [101, 690],
[101, 691], [101, 692], [101, 693]] is too long
    from schema $id:
http://devicetree.org/schemas/media/mediatek-jpeg-decoder.yaml#


Is there any way we can get them into v6.13 as well?

ChenYu

>   arm64: dts: mediatek: mt8188: Add missing dma-ranges to soc node
>   arm64: dts: mediatek: mt8188: Update vppsys node names to syscon
>   arm64: dts: mediatek: mt8188: Move vdec1 power domain under vdec0
>   arm64: dts: mediatek: mt8188: Move SPI NOR *-cells properties
>
>  .../media/mediatek,vcodec-subdev-decoder.yaml | 100 +++++++++++-------
>  .../bindings/media/mediatek-jpeg-decoder.yaml |   3 +-
>  .../bindings/media/mediatek-jpeg-encoder.yaml |   2 +-
>  .../bindings/pci/mediatek-pcie-gen3.yaml      |   5 +-
>  .../power/mediatek,power-controller.yaml      |   4 +
>  arch/arm64/boot/dts/mediatek/mt8188-evb.dts   |   2 -
>  arch/arm64/boot/dts/mediatek/mt8188.dtsi      |  33 +++---
>  7 files changed, 88 insertions(+), 61 deletions(-)
>
> --
> 2.46.1.824.gd892dcdcdd-goog
>
>


From andersson at kernel.org  Sun Dec  1 20:25:05 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sun, 1 Dec 2024 22:25:05 -0600
Subject: [PATCH v3 00/11] Add support for videocc, camcc, dispcc and
 gpucc on Qualcomm QCS615 platform
In-Reply-To: <20241108-qcs615-mm-clockcontroller-v3-0-7d3b2d235fdf@quicinc.com>
References: <20241108-qcs615-mm-clockcontroller-v3-0-7d3b2d235fdf@quicinc.com>
Message-ID: <a4f6ojknv3hats4rwmdg5mw2rxhx7kq4u6axybdawak54crn5s@xnjbl7zno42s>

On Fri, Nov 08, 2024 at 09:39:17AM +0530, Taniya Das wrote:
> Add support for multimedia clock controllers on Qualcomm QCS615 platform.
> Update the defconfig to enable these clock controllers.
> 
> Global clock controller support
> https://lore.kernel.org/all/20241022-qcs615-clock-driver-v4-0-3d716ad0d987 at quicinc.com/
> 
> Signed-off-by: Taniya Das <quic_tdas at quicinc.com>

Dropping this series from my queue, due to lack of response from author.

Taniya, please answer questions/feedback from Dmitry, Vladimir and
Bryan, and repose as necessary.

Thanks,
Bjorn

> ---
> Changes in v3:
> - update PLL configs to use BIT and GENMASK for vco_val and vco_mask for all CCs [Bryan O'Donoghue]
> - Link to v2: https://lore.kernel.org/r/20241101-qcs615-mm-clockcontroller-v2-0-d1a4870a4aed at quicinc.com
> 
> Changes in v2:
> - cleanups in clk_alpha_pll_slew_update and clk_alpha_pll_slew_enable functions [Christophe]
> - update PLL configs for "vco_val = 0x0" shift(20)  [Bryan O'Donoghue]
> - update PLL configs to use lower case for L value  [Dmitry]
> - Link parents for IFE/IPE/BPS GDSCs as Titan Top GDSC [Bryan O'Donoghue, Dmitry]
> - Remove DT_BI_TCXO_AO from camcc-qcs615           [Dmitry]
> - Remove HW_CTRL_TRIGGER from camcc-qcs615         [Bryan O'Donoghue]
> - Update platform name for default configuration   [Dmitry]
> - Link to v1: https://lore.kernel.org/r/20241019-qcs615-mm-clockcontroller-v1-0-4cfb96d779ae at quicinc.com
> 
> ---
> Taniya Das (11):
>       clk: qcom: Update the support for alpha mode configuration
>       clk: qcom: clk-alpha-pll: Add support for dynamic update for slewing PLLs
>       dt-bindings: clock: Add Qualcomm QCS615 Camera clock controller
>       clk: qcom: camcc-qcs615: Add QCS615 camera clock controller driver
>       dt-bindings: clock: Add Qualcomm QCS615 Display clock controller
>       clk: qcom: dispcc-qcs615: Add QCS615 display clock controller driver
>       dt-bindings: clock: Add Qualcomm QCS615 Graphics clock controller
>       clk: qcom: gpucc-qcs615: Add QCS615 graphics clock controller driver
>       dt-bindings: clock: Add Qualcomm QCS615 Video clock controller
>       clk: qcom: videocc-qcs615: Add QCS615 video clock controller driver
>       arm64: defconfig: Enable QCS615 clock controllers
> 
>  .../bindings/clock/qcom,qcs615-camcc.yaml          |   60 +
>  .../bindings/clock/qcom,qcs615-dispcc.yaml         |   73 +
>  .../bindings/clock/qcom,qcs615-gpucc.yaml          |   66 +
>  .../bindings/clock/qcom,qcs615-videocc.yaml        |   64 +
>  arch/arm64/configs/defconfig                       |    4 +
>  drivers/clk/qcom/Kconfig                           |   35 +
>  drivers/clk/qcom/Makefile                          |    4 +
>  drivers/clk/qcom/camcc-qcs615.c                    | 1591 ++++++++++++++++++++
>  drivers/clk/qcom/clk-alpha-pll.c                   |  172 +++
>  drivers/clk/qcom/clk-alpha-pll.h                   |    1 +
>  drivers/clk/qcom/dispcc-qcs615.c                   |  786 ++++++++++
>  drivers/clk/qcom/gpucc-qcs615.c                    |  525 +++++++
>  drivers/clk/qcom/videocc-qcs615.c                  |  332 ++++
>  include/dt-bindings/clock/qcom,qcs615-camcc.h      |  110 ++
>  include/dt-bindings/clock/qcom,qcs615-dispcc.h     |   52 +
>  include/dt-bindings/clock/qcom,qcs615-gpucc.h      |   39 +
>  include/dt-bindings/clock/qcom,qcs615-videocc.h    |   30 +
>  17 files changed, 3944 insertions(+)
> ---
> base-commit: 15e7d45e786a62a211dd0098fee7c57f84f8c681
> change-id: 20241016-qcs615-mm-clockcontroller-cff9aea7a006
> 
> Best regards,
> -- 
> Taniya Das <quic_tdas at quicinc.com>
> 


From anshuman.khandual at arm.com  Sun Dec  1 20:35:53 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon,  2 Dec 2024 10:05:53 +0530
Subject: [PATCH] arm64/mm: Drop INIT_MM_CONTEXT()
Message-ID: <20241202043553.29592-1-anshuman.khandual@arm.com>

Platform override for INIT_MM_CONTEXT() is redundant because swapper_pg_dir
always gets assigned as the pgd during init_mm initialization. So just drop
this override on arm64.

Originally this override was added via the 'commit 2b5548b68199 ("arm64/mm:
Separate boot-time page tables from swapper_pg_dir")' because non standard
init_pg_dir was assigned as the pgd. Subsequently it was changed as default
swapper_pg_dir by the 'commit ba5b0333a847 ("arm64: mm: omit redundant
remap of kernel image")', which might have also just dropped this override.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Ryan Roberts <ryan.roberts at arm.com>
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 patch applies on v6.13-rc1

 arch/arm64/include/asm/mmu.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 2ec96d91acc6..662471cfc536 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -109,8 +109,5 @@ static inline bool kaslr_requires_kpti(void)
 	return true;
 }
 
-#define INIT_MM_CONTEXT(name)	\
-	.pgd = swapper_pg_dir,
-
 #endif	/* !__ASSEMBLY__ */
 #endif
-- 
2.30.2



From masterr3c0rd at epochal.quest  Sun Dec  1 20:43:25 2024
From: masterr3c0rd at epochal.quest (Cody Eksal)
Date: Mon, 02 Dec 2024 00:43:25 -0400
Subject: [PATCH 0/2] sunxi: Add A100 syscon nodes
Message-ID: <20241202-a100-syscon-v1-0-86c6524f24d7@epochal.quest>

Hello again! Happy December!

Here are some very small patches to add syscon nodes to the A100's
device tree. These had not been added yet, as they hadn't been needed up
to this point. However, Parthiban and I have been working on patch
series in parallel that require either the syscon or the SRAM nodes it
is responsible for; specifically my patches add support for the A100's
ethernet controller, while Parthiban has been working hard on bringing
up the Display Engine.

Thanks as always!
- Cody

Signed-off-by: Cody Eksal <masterr3c0rd at epochal.quest>
---
Cody Eksal (2):
      dt-bindings: sram: sunxi-sram: Add A100 compatible
      arm64: dts: allwinner: a100: Add syscon nodes

 .../sram/allwinner,sun4i-a10-system-control.yaml   |  4 ++-
 arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi     | 31 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)
---
base-commit: e70140ba0d2b1a30467d4af6bcfe761327b9ec95
change-id: 20241126-a100-syscon-7316bea62e42

Best regards,
-- 
Cody Eksal <masterr3c0rd at epochal.quest>



From masterr3c0rd at epochal.quest  Sun Dec  1 20:43:27 2024
From: masterr3c0rd at epochal.quest (Cody Eksal)
Date: Mon, 02 Dec 2024 00:43:27 -0400
Subject: [PATCH 2/2] arm64: dts: allwinner: a100: Add syscon nodes
In-Reply-To: <20241202-a100-syscon-v1-0-86c6524f24d7@epochal.quest>
References: <20241202-a100-syscon-v1-0-86c6524f24d7@epochal.quest>
Message-ID: <20241202-a100-syscon-v1-2-86c6524f24d7@epochal.quest>

The Allwinner A100 has a system configuration block, denoted as SYS_CFG
in the user manual's memory map. It is undocumented in the manual, but
a glance at the vendor tree shows this block is similar to its
predecessors in the A64 and H6. The A100 also has 3 SRAM blocks: A1, A2,
and C. Add all of these to the SoC's device tree.

Signed-off-by: Cody Eksal <masterr3c0rd at epochal.quest>
---
 arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 31 ++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
index 29ac7716c7a5284ccf8af675db9c7d016785f0ff..31540a7ca1f01c6c2e69e329054aca16ffd112c4 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
@@ -101,6 +101,37 @@ soc {
 		#size-cells = <1>;
 		ranges = <0 0 0 0x3fffffff>;
 
+		syscon: syscon at 3000000 {
+			compatible = "allwinner,sun50i-a100-system-control",
+				     "allwinner,sun50i-a64-system-control";
+			reg = <0x03000000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			sram_a1: sram at 20000 {
+				compatible = "mmio-sram";
+				reg = <0x00020000 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x00020000 0x4000>;
+			};
+			sram_c: sram at 24000 {
+				compatible = "mmio-sram";
+				reg = <0x024000 0x21000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x024000 0x21000>;
+			};
+			sram_a2: sram at 100000 {
+				compatible = "mmio-sram";
+				reg = <0x0100000 0x14000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x0100000 0x14000>;
+			};
+		};
+
 		ccu: clock at 3001000 {
 			compatible = "allwinner,sun50i-a100-ccu";
 			reg = <0x03001000 0x1000>;

-- 
2.47.1



From masterr3c0rd at epochal.quest  Sun Dec  1 20:43:26 2024
From: masterr3c0rd at epochal.quest (Cody Eksal)
Date: Mon, 02 Dec 2024 00:43:26 -0400
Subject: [PATCH 1/2] dt-bindings: sram: sunxi-sram: Add A100 compatible
In-Reply-To: <20241202-a100-syscon-v1-0-86c6524f24d7@epochal.quest>
References: <20241202-a100-syscon-v1-0-86c6524f24d7@epochal.quest>
Message-ID: <20241202-a100-syscon-v1-1-86c6524f24d7@epochal.quest>

The Allwinner A100 has a system configuration block similar to that of
the A64 and H6. Add a compatible for it.

Signed-off-by: Cody Eksal <masterr3c0rd at epochal.quest>
---
 .../devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml b/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml
index d9322704f3588e036280d08deaf59972f1dfeb7f..a7236f7db4ec34d44c4e2268f76281ef8ed83189 100644
--- a/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml
+++ b/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml
@@ -47,7 +47,9 @@ properties:
           - const: allwinner,sun8i-v3s-system-control
           - const: allwinner,sun8i-h3-system-control
       - items:
-          - const: allwinner,sun50i-h6-system-control
+          - enum:
+              - allwinner,sun50i-a100-system-control
+              - allwinner,sun50i-h6-system-control
           - const: allwinner,sun50i-a64-system-control
 
   reg:

-- 
2.47.1



From ankita at nvidia.com  Sun Dec  1 20:51:02 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Mon, 2 Dec 2024 04:51:02 +0000
Subject: [PATCH v2 0/1] KVM: arm64: Map GPU memory with no struct pages
In-Reply-To: <07252361-8886-4284-bdba-55c3fe728831@redhat.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <07252361-8886-4284-bdba-55c3fe728831@redhat.com>
Message-ID: <SA1PR12MB7199EA7300F9F1C5D3505C0EB0352@SA1PR12MB7199.namprd12.prod.outlook.com>

Thanks Don.

> My email client says this patch: [PATCH v2 1/1] KVM: arm64: Allow cacheable stage 2 mapping using VMA flags
> ?? is part of a thread for this titled patchPATCH.? Is it?

Those are supposed to be 2 different patches (0/1 being the cover letter, 1/1 the primary patch).

> So, could you clean these two up into (a) a series, or (b) single, separate PATCH's?

Yeah, I'll send it as a patch with a cover letter in a series when I send the next version.




From parthiban at linumiz.com  Sun Dec  1 20:51:26 2024
From: parthiban at linumiz.com (Parthiban)
Date: Mon, 2 Dec 2024 10:21:26 +0530
Subject: [PATCH 2/2] arm64: dts: allwinner: a100: Add syscon nodes
In-Reply-To: <20241202-a100-syscon-v1-2-86c6524f24d7@epochal.quest>
References: <20241202-a100-syscon-v1-0-86c6524f24d7@epochal.quest>
 <20241202-a100-syscon-v1-2-86c6524f24d7@epochal.quest>
Message-ID: <d394f125-f301-4cc6-a477-36d1267b614a@linumiz.com>

On 12/2/24 10:13 AM, Cody Eksal wrote:
> The Allwinner A100 has a system configuration block, denoted as SYS_CFG
> in the user manual's memory map. It is undocumented in the manual, but
> a glance at the vendor tree shows this block is similar to its
> predecessors in the A64 and H6. The A100 also has 3 SRAM blocks: A1, A2,
> and C. Add all of these to the SoC's device tree.
> 
> Signed-off-by: Cody Eksal <masterr3c0rd at epochal.quest>
Reviewed-by: Parthiban Nallathambi <parthiban at linumiz.com>

Thanks,
Parthiban
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 31 ++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
> index 29ac7716c7a5284ccf8af675db9c7d016785f0ff..31540a7ca1f01c6c2e69e329054aca16ffd112c4 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
> @@ -101,6 +101,37 @@ soc {
>  		#size-cells = <1>;
>  		ranges = <0 0 0 0x3fffffff>;
>  
> +		syscon: syscon at 3000000 {
> +			compatible = "allwinner,sun50i-a100-system-control",
> +				     "allwinner,sun50i-a64-system-control";
> +			reg = <0x03000000 0x1000>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges;
> +
> +			sram_a1: sram at 20000 {
> +				compatible = "mmio-sram";
> +				reg = <0x00020000 0x4000>;
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +				ranges = <0 0x00020000 0x4000>;
> +			};
> +			sram_c: sram at 24000 {
> +				compatible = "mmio-sram";
> +				reg = <0x024000 0x21000>;
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +				ranges = <0 0x024000 0x21000>;
> +			};
> +			sram_a2: sram at 100000 {
> +				compatible = "mmio-sram";
> +				reg = <0x0100000 0x14000>;
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +				ranges = <0 0x0100000 0x14000>;
> +			};
> +		};
> +
>  		ccu: clock at 3001000 {
>  			compatible = "allwinner,sun50i-a100-ccu";
>  			reg = <0x03001000 0x1000>;
> 



From wenst at chromium.org  Sun Dec  1 20:57:55 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon,  2 Dec 2024 12:57:55 +0800
Subject: [PATCH] dt-bindings: soc: fsl: cpm_qe: Limit matching to nodes with "fsl,qe"
Message-ID: <20241202045757.39244-1-wenst@chromium.org>

Otherwise the binding matches against random nodes with "simple-bus"
giving out all kinds of invalid warnings:

    $ make CHECK_DTBS=y mediatek/mt8188-evb.dtb
      SYNC    include/config/auto.conf.cmd
      UPD     include/config/kernel.release
      SCHEMA  Documentation/devicetree/bindings/processed-schema.json
      DTC [C] arch/arm64/boot/dts/mediatek/mt8188-evb.dtb
    arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: compatible:0: 'fsl,qe' was expected
	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
    arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: compatible: ['simple-bus'] is too short
	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
    arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:compatible:0: 'fsl,qe-ic' was expected
	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
    arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:reg: [[0, 201326592, 0, 262144], [0, 201588736, 0, 2097152]] is too long
	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
    arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:#interrupt-cells:0:0: 1 was expected
	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
    arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000: '#redistributor-regions', 'ppi-partitions' do not match any of the regexes: 'pinctrl-[0-9]+'
	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
    arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: 'reg' is a required property
	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
    arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: 'bus-frequency' is a required property
	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#

Fixes: ecbfc6ff94a2 ("dt-bindings: soc: fsl: cpm_qe: convert to yaml format")
Cc: Frank Li <Frank.Li at nxp.com>
Cc: <stable at vger.kernel.org> # v6.11+
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 .../devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml        | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
index 89cdf5e1d0a8..9e07a2c4d05b 100644
--- a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
+++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
@@ -21,6 +21,14 @@ description: |
   The description below applies to the qe of MPC8360 and
   more nodes and properties would be extended in the future.
 
+select:
+  properties:
+    compatible:
+      contains:
+        const: fsl,qe
+  required:
+    - compatible
+
 properties:
   compatible:
     items:
-- 
2.47.0.338.g60cca15819-goog



From vt at altlinux.org  Sun Dec  1 20:58:30 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Mon, 2 Dec 2024 07:58:30 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
Message-ID: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>

Hi,

v6.13-rc1 exhibits a boot failure on aarch64 under KVM. (QEMU 9.1.1, CPU
Kunpeng-920). Boot log:

+ time qemu-system-aarch64 -M accel=kvm:tcg -smp cores=8 -m 4096 -serial mon:stdio -nodefaults -nographic -no-reboot -fsdev local,id=root,path=/,security_model=none,multidevs=remap -device virtio-9p-pci,fsdev=root,mount_tag=virtio-9p:/ -device virtio-rng-pci -kernel /usr/src/tmp/kernel-image-6.13-buildroot/boot/vmlinuz-6.13.0-6.13-alt0.rc1 -initrd /usr/src/tmp/initramfs-6.13.0-6.13-alt0.rc1.img -sandbox on,spawn=deny -M virt,gic-version=3 -cpu max -append 'console=ttyAMA0 mitigations=off nokaslr  panic=-1 SCRIPT=/usr/src/tmp/vm.SchsIm2FjB earlycon earlyprintk=serial ignore_loglevel debug rddebug'
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x481fd010]
[    0.000000] Linux version 6.13.0-6.13-alt0.rc1 (builder at localhost.localdomain) (gcc-14 (GCC) 14.2.1 20241028 (ALT Sisyphus 14.2.1-alt1), GNU ld (GNU Binutils) 2.43.1.20241025) #1 SMP PREEMPT_DYNAMIC Mon Dec  2 03:33:29 UTC 2024
[    0.000000] KASLR disabled on command line
[    0.000000] random: crng init done
[    0.000000] Machine model: linux,dummy-virt
[    0.000000] printk: debug: ignoring loglevel setting.
[    0.000000] efi: UEFI not found.
[    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '')
[    0.000000] printk: legacy bootconsole [pl11] enabled
[    0.000000] OF: reserved mem: Reserved memory: No reserved-memory node in the DT
[    0.000000] NUMA: Faking a node at [mem 0x0000000040000000-0x000000013fffffff]
[    0.000000] NODE_DATA(0) allocated [mem 0x13f7f3540-0x13f7f947f]
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000040000000-0x00000000ffffffff]
[    0.000000]   DMA32    empty
[    0.000000]   Normal   [mem 0x0000000100000000-0x000000013fffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000040000000-0x000000013fffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000013fffffff]
[    0.000000] cma: Reserved 256 MiB at 0x00000000f0000000 on node -1
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: Trusted OS migration not required
[    0.000000] psci: SMC Calling Convention v1.1
[    0.000000] smccc: KVM: hypervisor services detected (0x00000000 0x00000000 0x00000000 0x00000003)
[    0.000000] percpu: Embedded 34 pages/cpu s100632 r8192 d30440 u139264
[    0.000000] pcpu-alloc: s100632 r8192 d30440 u139264 alloc=34*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7
[    0.000000] Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.13.0-6.13-alt0.rc1 #1
[    0.000000] Hardware name: linux,dummy-virt (DT)
[    0.000000] pstate: 004000c5 (nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[    0.000000] pc : __cpuinfo_store_cpu+0xe8/0x240
[    0.000000] lr : cpuinfo_store_boot_cpu+0x34/0x88
[    0.000000] sp : ffff800082013df0
[    0.000000] x29: ffff800082013df0 x28: 000000000000008e x27: ffff800081e38128
[    0.000000] x26: ffff800081702190 x25: ffff80008201f040 x24: ffff0000ff7d1d00
[    0.000000] x23: ffff80008201ec00 x22: ffff800081e39100 x21: ffff8000816f9750
[    0.000000] x20: ffff800081f55280 x19: ffff0000ff6be2e0 x18: 0000000000000000
[    0.000000] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
[    0.000000] x14: 000000000000002f x13: 000000013f7f9490 x12: 0000008000000000
[    0.000000] x11: 0000000000000000 x10: 00000000007f8000 x9 : 000000013f808000
[    0.000000] x8 : 0000000000000000 x7 : 0000000000000000 x6 : 000000013f7f94c0
[    0.000000] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 1100010011111111
[    0.000000] x2 : 0000000000000001 x1 : 0000000084448004 x0 : ffff0000ff6be2e0
[    0.000000] Call trace:
[    0.000000]  __cpuinfo_store_cpu+0xe8/0x240 (P)
[    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88 (L)
[    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88
[    0.000000]  smp_prepare_boot_cpu+0x30/0x58
[    0.000000]  start_kernel+0x514/0x9d0
[    0.000000]  __primary_switched+0x88/0x98
[    0.000000] Code: f100085f 54000600 f2580c7f 54000060 (d538a482)
[    0.000000] ---[ end trace 0000000000000000 ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.000000] Rebooting in 600 seconds..

Thanks,



From itaru.kitayama at linux.dev  Sun Dec  1 21:10:56 2024
From: itaru.kitayama at linux.dev (Itaru Kitayama)
Date: Mon, 2 Dec 2024 14:10:56 +0900
Subject: [PATCH v5 00/43] arm64: Support for Arm CCA in KVM
In-Reply-To: <20241004152804.72508-1-steven.price@arm.com>
References: <20241004152804.72508-1-steven.price@arm.com>
Message-ID: <Z01BYOgsLXV5yULk@vm3>

On Fri, Oct 04, 2024 at 04:27:21PM +0100, Steven Price wrote:
> This series adds support for running protected VMs using KVM under the
> Arm Confidential Compute Architecture (CCA).
> 
> The related guest support was posted[1] earlier. As with the guest this
> series moves to the "v1.0-rel0" version of the specification[2].
> 
> Almost all changes since v4[3] are either due to rebasing or minor
> changes to improve the code following review comments. There are two bug
> fixes:
> 
>  * Setting the GPRS on entry after an exit where the host is allowed to
>    change registers is now done in kvm_rec_enter(). This fixes a bug
>    where register updates done by user space were being ignored.
> 
>  * Drop the PTE_SHARED bit for unprotected page table entries - this bit
>    isn't controlled by the host and the RMM now enforces the bit is
>    zero.
> 
> Major limitations:
> 
>  * Only supports 4k host PAGE_SIZE (if PAGE_SIZE != 4k then the realm
>    extensions are disabled).
> 
>  * No support for huge pages when mapping the guest's pages. There is
>    some 'dead' code left over from before guest_mem was supported. This
>    is partly a current limitation of guest_memfd.
> 
> The ABI to the RMM (the RMI) is based on RMM v1.0-rel0 specification[2].
> 
> This series is based on v6.12-rc1. It is also available as a git
> repository:
> 
> https://gitlab.arm.com/linux-arm/linux-cca cca-host/v5
> 
> Work in progress changes for kvmtool are available from the git
> repository below:
> 
> https://gitlab.arm.com/linux-arm/kvmtool-cca cca/v3
> 
> [1] https://lore.kernel.org/r/20241004144307.66199-1-steven.price%40arm.com
> [2] https://developer.arm.com/documentation/den0137/1-0rel0/
> [3] https://lore.kernel.org/r/20240821153844.60084-1-steven.price%40arm.com
> 
> Jean-Philippe Brucker (7):
>   arm64: RME: Propagate number of breakpoints and watchpoints to
>     userspace
>   arm64: RME: Set breakpoint parameters through SET_ONE_REG
>   arm64: RME: Initialize PMCR.N with number counter supported by RMM
>   arm64: RME: Propagate max SVE vector length from RMM
>   arm64: RME: Configure max SVE vector length for a Realm
>   arm64: RME: Provide register list for unfinalized RME RECs
>   arm64: RME: Provide accurate register list
> 
> Joey Gouly (2):
>   arm64: rme: allow userspace to inject aborts
>   arm64: rme: support RSI_HOST_CALL
> 
> Sean Christopherson (1):
>   KVM: Prepare for handling only shared mappings in mmu_notifier events
> 
> Steven Price (29):
>   arm64: RME: Handle Granule Protection Faults (GPFs)
>   arm64: RME: Add SMC definitions for calling the RMM
>   arm64: RME: Add wrappers for RMI calls
>   arm64: RME: Check for RME support at KVM init
>   arm64: RME: Define the user ABI
>   arm64: RME: ioctls to create and configure realms
>   arm64: kvm: Allow passing machine type in KVM creation
>   arm64: RME: Keep a spare page delegated to the RMM
>   arm64: RME: RTT tear down
>   arm64: RME: Allocate/free RECs to match vCPUs
>   arm64: RME: Support for the VGIC in realms
>   KVM: arm64: Support timers in realm RECs
>   arm64: RME: Allow VMM to set RIPAS
>   arm64: RME: Handle realm enter/exit
>   KVM: arm64: Handle realm MMIO emulation
>   arm64: RME: Allow populating initial contents
>   arm64: RME: Runtime faulting of memory
>   KVM: arm64: Handle realm VCPU load
>   KVM: arm64: Validate register access for a Realm VM
>   KVM: arm64: Handle Realm PSCI requests
>   KVM: arm64: WARN on injected undef exceptions
>   arm64: Don't expose stolen time for realm guests
>   arm64: RME: Always use 4k pages for realms
>   arm64: rme: Prevent Device mappings for Realms
>   arm_pmu: Provide a mechanism for disabling the physical IRQ
>   arm64: rme: Enable PMU support with a realm guest
>   kvm: rme: Hide KVM_CAP_READONLY_MEM for realm guests
>   arm64: kvm: Expose support for private memory
>   KVM: arm64: Allow activating realms
> 
> Suzuki K Poulose (4):
>   kvm: arm64: pgtable: Track the number of pages in the entry level
>   kvm: arm64: Include kvm_emulate.h in kvm/arm_psci.h
>   kvm: arm64: Expose debug HW register numbers for Realm
>   arm64: rme: Allow checking SVE on VM instance

On FVP, the v5+v7 kernel is unable to execute virt-manager:

Starting install...
Allocating 'test9.qcow2'                                    |    0 B  00:00 ...
Removing disk 'test9.qcow2'                                 |    0 B  00:00
ERROR    internal error: process exited while connecting to monitor: 2024-12-04T18:56:11.646168Z qemu-system-aarch64: -accel kvm: ioctl(KVM_CREATE_VM) failed: Invalid argument
2024-12-04T18:56:11.646520Z qemu-system-aarch64: -accel kvm: failed to initialize kvm: Invalid argument
Domain installation does not appear to have been successful.

Below is my virt-manager options:

virt-install --machine=virt --arch=aarch64 --name=test9 --memory=2048 --vcpu=1 --nographic --check all=off --features acpi=off --virt-type kvm --boot kernel=Image-cca,initrd=rootfs.cpio,kernel_args='earlycon console=ttyAMA0 rdinit=/sbin/init rw root=/dev/vda acpi=off' --qemu-commandline='-M virt,confidential-guest-support=rme0,gic-version=3 -cpu host -object rme-guest,id=rme0 -nodefaults' --disk size=4 --import --osinfo detect=on,require=off

Userland is Ubuntu 24.10, the VMM is Linaro's cca/2024-11-20:

https://git.codelinaro.org/linaro/dcap/qemu/-/tree/cca/2024-11-20?ref_type=heads

virt-install doesn't complain if I try to bring up a normal VM.

Thanks,
Itaru. 

> 
>  Documentation/virt/kvm/api.rst       |    3 +
>  arch/arm64/include/asm/kvm_emulate.h |   34 +
>  arch/arm64/include/asm/kvm_host.h    |   16 +-
>  arch/arm64/include/asm/kvm_pgtable.h |    2 +
>  arch/arm64/include/asm/kvm_rme.h     |  155 +++
>  arch/arm64/include/asm/rmi_cmds.h    |  510 ++++++++
>  arch/arm64/include/asm/rmi_smc.h     |  255 ++++
>  arch/arm64/include/asm/virt.h        |    1 +
>  arch/arm64/include/uapi/asm/kvm.h    |   49 +
>  arch/arm64/kvm/Kconfig               |    1 +
>  arch/arm64/kvm/Makefile              |    3 +-
>  arch/arm64/kvm/arch_timer.c          |   45 +-
>  arch/arm64/kvm/arm.c                 |  166 ++-
>  arch/arm64/kvm/guest.c               |   99 +-
>  arch/arm64/kvm/hyp/pgtable.c         |    5 +-
>  arch/arm64/kvm/hypercalls.c          |    4 +-
>  arch/arm64/kvm/inject_fault.c        |    2 +
>  arch/arm64/kvm/mmio.c                |   10 +-
>  arch/arm64/kvm/mmu.c                 |  185 ++-
>  arch/arm64/kvm/pmu-emul.c            |    7 +-
>  arch/arm64/kvm/psci.c                |   29 +
>  arch/arm64/kvm/reset.c               |   23 +-
>  arch/arm64/kvm/rme-exit.c            |  207 ++++
>  arch/arm64/kvm/rme.c                 | 1628 ++++++++++++++++++++++++++
>  arch/arm64/kvm/sys_regs.c            |   83 +-
>  arch/arm64/kvm/vgic/vgic-v3.c        |    8 +-
>  arch/arm64/kvm/vgic/vgic.c           |   41 +-
>  arch/arm64/mm/fault.c                |   31 +-
>  drivers/perf/arm_pmu.c               |   15 +
>  include/kvm/arm_arch_timer.h         |    2 +
>  include/kvm/arm_pmu.h                |    4 +
>  include/kvm/arm_psci.h               |    2 +
>  include/linux/kvm_host.h             |    2 +
>  include/linux/perf/arm_pmu.h         |    5 +
>  include/uapi/linux/kvm.h             |   31 +-
>  virt/kvm/kvm_main.c                  |    7 +
>  36 files changed, 3569 insertions(+), 101 deletions(-)
>  create mode 100644 arch/arm64/include/asm/kvm_rme.h
>  create mode 100644 arch/arm64/include/asm/rmi_cmds.h
>  create mode 100644 arch/arm64/include/asm/rmi_smc.h
>  create mode 100644 arch/arm64/kvm/rme-exit.c
>  create mode 100644 arch/arm64/kvm/rme.c
> 
> -- 
> 2.34.1
> 


From ck.hu at mediatek.com  Sun Dec  1 21:18:37 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 2 Dec 2024 05:18:37 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
Message-ID: <5401e3a681e4dc92625566b87c1bf3c9e8cc0443.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static const struct drm_bridge_funcs mtk_v2_hdmi_bridge_funcs = {
> +       .attach = mtk_hdmi_v2_bridge_attach,
> +       .detach = mtk_hdmi_v2_bridge_detach,
> +       .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,
> +       .mode_fixup = mtk_hdmi_bridge_mode_fixup,
> +       .atomic_disable = mtk_hdmi_v2_bridge_disable,
> +       .atomic_post_disable = mtk_hdmi_v2_bridge_post_disable,
> +       .mode_set = mtk_hdmi_bridge_mode_set,
> +       .atomic_pre_enable = mtk_hdmi_v2_bridge_pre_enable,
> +       .atomic_enable = mtk_hdmi_v2_bridge_enable,
> +       .edid_read = mtk_hdmi_v2_bridge_edid_read,
> +       .detect = mtk_hdmi_v2_bridge_detect,
> +       .debugfs_init = mtk_hdmi_v2_debugfs_init,

v1 has mode_valid callback function, so implement it in v2.

Regards,
CK

> +};
> +

> 

From wenst at chromium.org  Sun Dec  1 22:28:25 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon,  2 Dec 2024 14:28:25 +0800
Subject: [PATCH] remoteproc: mtk_scp: Only populate devices SCP cores
Message-ID: <20241202062826.66619-1-wenst@chromium.org>

When multi-core SCP support was added, the driver was made to populate
platform devices for all the sub-nodes. This ended up adding platform
devices for the rpmsg sub-nodes as well, which never actually get used,
since rpmsg devices are registered through the rpmsg interface.

Limit of_platform_populate() to just populating the SCP cores with a
compatible string match list.

Fixes: 1fdbf0cdde98 ("remoteproc: mediatek: Probe SCP cluster on multi-core SCP")
Cc: Tinghan Shen <tinghan.shen at mediatek.com>
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/remoteproc/mtk_scp.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 0f4a7065d0bd..8206a1766481 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -1326,6 +1326,11 @@ static int scp_cluster_init(struct platform_device *pdev, struct mtk_scp_of_clus
 	return ret;
 }
 
+static const struct of_device_id scp_core_match[] = {
+	{ .compatible = "mediatek,scp-core" },
+	{}
+};
+
 static int scp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1357,13 +1362,15 @@ static int scp_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&scp_cluster->mtk_scp_list);
 	mutex_init(&scp_cluster->cluster_lock);
 
-	ret = devm_of_platform_populate(dev);
+	ret = of_platform_populate(dev_of_node(dev), scp_core_match, NULL, dev);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to populate platform devices\n");
 
 	ret = scp_cluster_init(pdev, scp_cluster);
-	if (ret)
+	if (ret) {
+		of_platform_depopulate(dev);
 		return ret;
+	}
 
 	return 0;
 }
@@ -1379,6 +1386,7 @@ static void scp_remove(struct platform_device *pdev)
 		rproc_del(scp->rproc);
 		scp_free(scp);
 	}
+	of_platform_depopulate(&pdev->dev);
 	mutex_destroy(&scp_cluster->cluster_lock);
 }
 
-- 
2.47.0.338.g60cca15819-goog



From anshuman.khandual at arm.com  Sun Dec  1 22:44:07 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon,  2 Dec 2024 12:14:07 +0530
Subject: [PATCH] arm64/mm: Ensure adequate HUGE_MAX_HSTATE
Message-ID: <20241202064407.53807-1-anshuman.khandual@arm.com>

This asserts that HUGE_MAX_HSTATE is sufficient enough preventing potential
hugetlb_max_hstate runtime overflow in hugetlb_add_hstate() thus triggering
a BUG_ON() there after.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Ryan Roberts <ryan.roberts at arm.com>
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 patch applies on v6.13-rc1

 arch/arm64/mm/hugetlbpage.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 3215adf48a1b..98a2a0e64e25 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -519,6 +519,18 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
 
 static int __init hugetlbpage_init(void)
 {
+	/*
+	 * HugeTLB pages are supported on maximum four page table
+	 * levels (PUD, CONT PMD, PMD, CONT PTE) for a given base
+	 * page size, corresponding to hugetlb_add_hstate() calls
+	 * here.
+	 *
+	 * HUGE_MAX_HSTATE should at least match maximum supported
+	 * HugeTLB page sizes on the platform. Any new addition to
+	 * supported HugeTLB page sizes will also require changing
+	 * HUGE_MAX_HSTATE as well.
+	 */
+	BUILD_BUG_ON(HUGE_MAX_HSTATE < 4);
 	if (pud_sect_supported())
 		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
 
-- 
2.30.2



From wenst at chromium.org  Sun Dec  1 22:55:11 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 2 Dec 2024 14:55:11 +0800
Subject: [PATCH] remoteproc: mtk_scp: Only populate devices SCP cores
In-Reply-To: <20241202062826.66619-1-wenst@chromium.org>
References: <20241202062826.66619-1-wenst@chromium.org>
Message-ID: <CAGXv+5EYkG=Y1vWDO6DWnUhd0WRuctYn_3w2YkvJoR_7JhsCpQ@mail.gmail.com>

On Mon, Dec 2, 2024 at 2:28?PM Chen-Yu Tsai <wenst at chromium.org> wrote:
>

Oops. The subject should read "Only populate devices for SCP cores".

I'll let this one sit for a couple days before sending a new version.

ChenYu

> When multi-core SCP support was added, the driver was made to populate
> platform devices for all the sub-nodes. This ended up adding platform
> devices for the rpmsg sub-nodes as well, which never actually get used,
> since rpmsg devices are registered through the rpmsg interface.
>
> Limit of_platform_populate() to just populating the SCP cores with a
> compatible string match list.
>
> Fixes: 1fdbf0cdde98 ("remoteproc: mediatek: Probe SCP cluster on multi-core SCP")
> Cc: Tinghan Shen <tinghan.shen at mediatek.com>
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/remoteproc/mtk_scp.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> index 0f4a7065d0bd..8206a1766481 100644
> --- a/drivers/remoteproc/mtk_scp.c
> +++ b/drivers/remoteproc/mtk_scp.c
> @@ -1326,6 +1326,11 @@ static int scp_cluster_init(struct platform_device *pdev, struct mtk_scp_of_clus
>         return ret;
>  }
>
> +static const struct of_device_id scp_core_match[] = {
> +       { .compatible = "mediatek,scp-core" },
> +       {}
> +};
> +
>  static int scp_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> @@ -1357,13 +1362,15 @@ static int scp_probe(struct platform_device *pdev)
>         INIT_LIST_HEAD(&scp_cluster->mtk_scp_list);
>         mutex_init(&scp_cluster->cluster_lock);
>
> -       ret = devm_of_platform_populate(dev);
> +       ret = of_platform_populate(dev_of_node(dev), scp_core_match, NULL, dev);
>         if (ret)
>                 return dev_err_probe(dev, ret, "Failed to populate platform devices\n");
>
>         ret = scp_cluster_init(pdev, scp_cluster);
> -       if (ret)
> +       if (ret) {
> +               of_platform_depopulate(dev);
>                 return ret;
> +       }
>
>         return 0;
>  }
> @@ -1379,6 +1386,7 @@ static void scp_remove(struct platform_device *pdev)
>                 rproc_del(scp->rproc);
>                 scp_free(scp);
>         }
> +       of_platform_depopulate(&pdev->dev);
>         mutex_destroy(&scp_cluster->cluster_lock);
>  }
>
> --
> 2.47.0.338.g60cca15819-goog
>


From andrej.picej at norik.com  Sun Dec  1 23:20:52 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:52 +0100
Subject: [PATCH v2 15/15] arm64: dts: imx8mm-phycore-som: Add overlay to disable SPI NOR flash
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-16-andrej.picej@norik.com>

From: Teresa Remmet <t.remmet at phytec.de>

There are SoM variants with no SPI NOR flash populated. Add overlay to be
able to support this.

Signed-off-by: Teresa Remmet <t.remmet at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change.
---
 arch/arm64/boot/dts/freescale/Makefile           |  2 ++
 .../freescale/imx8mm-phycore-no-spiflash.dtso    | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phycore-no-spiflash.dtso

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index da6ddce6b7c7..6dcefd58996d 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -126,11 +126,13 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb
 imx8mm-phyboard-polis-peb-av-10-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-av-10.dtbo
 imx8mm-phyboard-polis-peb-eval-01-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-eval-01.dtbo
 imx8mm-phycore-no-eth-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phycore-no-eth.dtbo
+imx8mm-phycore-no-spiflash-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phycore-no-spiflash.dtbo
 imx8mm-phycore-rpmsg-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phycore-rpmsg.dtbo
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-av-10.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-eval-01.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phycore-no-eth.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-phycore-no-spiflash.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phycore-rpmsg.dtb
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phygate-tauri-l.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-no-spiflash.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phycore-no-spiflash.dtso
new file mode 100644
index 000000000000..71918a3241d5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-no-spiflash.dtso
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Teresa Remmet <t.remmet at phytec.de>
+ */
+
+/dts-v1/;
+/plugin/;
+
+&flexspi {
+	status = "disabled";
+};
+
+&som_flash {
+	status = "disabled";
+};
-- 
2.34.1



From ck.hu at mediatek.com  Sun Dec  1 23:27:58 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 2 Dec 2024 07:27:58 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
Message-ID: <559ac08df6614e47c3e8d9d8160b35c9e683c503.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static int mtk_hdmi_v2_enable(struct mtk_hdmi *hdmi)
> +{
> +       int ret;
> +
> +       ret = pm_runtime_resume_and_get(hdmi->dev);

Why turn on power when attach?
Should hot-plug detection be always on so power on when attach?
If so, maybe we need to use CEC to detect hot-plug because CEC has lower power and HDMI power would not be always on.
As you describe previously, CEC just need some hack to support both HDMI Tx and HDMI Rx.
So there is a software solution to use CEC to detect hot-plug in a lower power mode.
And v1 use CEC to detect hot-plug, so it's worth to make v1 and v2 has the same behavior.

Regards,
CK


> +       if (ret) {
> +               dev_err(hdmi->dev, "Cannot resume HDMI\n");
> +               return ret;
> +       }
> +
> +       mtk_hdmi_v2_clk_enable(hdmi);
> +       mtk_hdmi_hw_reset(hdmi);
> +       mtk_hdmi_set_sw_hpd(hdmi, true);
> +
> +       return 0;
> +}
> +

> 

From krzk at kernel.org  Sun Dec  1 23:32:02 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 08:32:02 +0100
Subject: [PATCH v4 01/18] clk: imx8mm: rename video_pll1 to video_pll
In-Reply-To: <20241201174639.742000-2-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
 <20241201174639.742000-2-dario.binacchi@amarulasolutions.com>
Message-ID: <hdpndzf6jpywogsdcgl7wwmqzgbcvhportoieieohfmp7dwmyq@l6eujnohfe3s>

On Sun, Dec 01, 2024 at 06:46:01PM +0100, Dario Binacchi wrote:
> Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
> name used in the RM is video_pll. So, let's rename "video_pll1" to
> "video_pll" to be consistent with the RM and avoid misunderstandings.
> 
> The IMX8MM_VIDEO_PLL1* constants have not been removed to ensure
> backward compatibility of the patch.
> 
> No functional changes intended.
> 
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> 
>  - Added in v4

Wrongly placed changelog.

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

Bindings are separate from drivers. Always.

Best regards,
Krzysztof



From quic_tdas at quicinc.com  Sun Dec  1 23:31:43 2024
From: quic_tdas at quicinc.com (Taniya Das)
Date: Mon, 2 Dec 2024 13:01:43 +0530
Subject: [PATCH v3 03/11] dt-bindings: clock: Add Qualcomm QCS615 Camera
 clock controller
In-Reply-To: <a6926e47-0344-4996-b330-cfcf3e7b5f31@linaro.org>
References: <20241108-qcs615-mm-clockcontroller-v3-0-7d3b2d235fdf@quicinc.com>
 <20241108-qcs615-mm-clockcontroller-v3-3-7d3b2d235fdf@quicinc.com>
 <a6926e47-0344-4996-b330-cfcf3e7b5f31@linaro.org>
Message-ID: <77a134d6-9226-4c49-9c4b-9986e5296805@quicinc.com>



On 11/8/2024 5:58 PM, Vladimir Zapolskiy wrote:
>> +additionalProperties: false
>> +
>> +examples:
>> +? - |
>> +??? #include <dt-bindings/clock/qcom,rpmh.h>
>> +??? clock-controller at ad00000 {
>> +????? compatible = "qcom,qcs615-camcc";
>> +????? reg = <0xad00000 0x10000>;
>> +????? clocks = <&rpmhcc RPMH_CXO_CLK>;
>> +
>> +????? #clock-cells = <1>;
>> +????? #reset-cells = <1>;
>> +????? #power-domain-cells = <1>;
>> +??? };
>> +...
> 
> would you find it possible to merge this binding into the existing one
> qcom,sdm845-camcc.yaml?
> 
> Those two are very similar, sdm845-camcc requires clock-names though.

Clock-names were mandatory during SDM845, so I moved to add the new 
bindings. Please let me know if you still think I should merge it.

-- 
Thanks & Regards,
Taniya Das.


From quic_tdas at quicinc.com  Sun Dec  1 23:32:17 2024
From: quic_tdas at quicinc.com (Taniya Das)
Date: Mon, 2 Dec 2024 13:02:17 +0530
Subject: [PATCH v3 03/11] dt-bindings: clock: Add Qualcomm QCS615 Camera
 clock controller
In-Reply-To: <be4blr2wvnc7b4iubexxnzqevjpgnfhdt7azcuwdtqgp6xbdvh@c3txmpuo5lot>
References: <20241108-qcs615-mm-clockcontroller-v3-0-7d3b2d235fdf@quicinc.com>
 <20241108-qcs615-mm-clockcontroller-v3-3-7d3b2d235fdf@quicinc.com>
 <be4blr2wvnc7b4iubexxnzqevjpgnfhdt7azcuwdtqgp6xbdvh@c3txmpuo5lot>
Message-ID: <105428de-81a0-4da3-94ce-7b9310a29e17@quicinc.com>



On 11/8/2024 10:52 PM, Dmitry Baryshkov wrote:
>> +  clocks:
>> +    items:
>> +      - description: Board XO source
>> +
>> +  '#clock-cells':
>> +    const: 1
>> +
>> +  '#reset-cells':
>> +    const: 1
>> +
>> +  '#power-domain-cells':
>> +    const: 1
> Please use qcom,gcc.yaml instead of copying the same set of properties
> over and over.

Sure, will take care in the next patch.

-- 
Thanks & Regards,
Taniya Das.


From krzk at kernel.org  Sun Dec  1 23:33:02 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 08:33:02 +0100
Subject: [PATCH v4 02/18] clk: imx8mp: rename video_pll1 to video_pll
In-Reply-To: <20241201174639.742000-3-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
 <20241201174639.742000-3-dario.binacchi@amarulasolutions.com>
Message-ID: <h5eswwlw3rpuc46ote3bhexetlf35i72btwlq2xsqt7p4rg2jx@eugvszlgpuvc>

On Sun, Dec 01, 2024 at 06:46:02PM +0100, Dario Binacchi wrote:
> Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
> name used in the RM is video_pll. So, let's rename "video_pll1" to
> "video_pll" to be consistent with the RM and avoid misunderstandings.
> 
> The IMX8MP_VIDEO_PLL1* constants have not been removed to ensure
> backward compatibility of the patch.
> 
> No functional changes intended.
> 
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> 
>  - Added in v4
> 
> ---
> 
> (no changes since v1)


Same problems.

Best regards,
Krzysztof



From krzk at kernel.org  Sun Dec  1 23:33:41 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 08:33:41 +0100
Subject: [PATCH v4 08/18] dt-bindings: clock: imx8mm: add binding
 definitions for anatop
In-Reply-To: <20241201174639.742000-9-dario.binacchi@amarulasolutions.com>
References: <20241201174639.742000-1-dario.binacchi@amarulasolutions.com>
 <20241201174639.742000-9-dario.binacchi@amarulasolutions.com>
Message-ID: <2t7eok4xmjxywt4dzjviz4brvohk2y7gceu2srioocgpekpu23@grgdf24djo4o>

On Sun, Dec 01, 2024 at 06:46:08PM +0100, Dario Binacchi wrote:
> Add the bindings definitions for the anatop node. The patch is
> preparatory for future developments.
> 
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> 
>  - Added in v4
> 
> ---
> 
> (no changes since v1)

My comments apply everywhere, I'll mark everything as changes requested.

Best regards,
Krzysztof



From quic_tdas at quicinc.com  Sun Dec  1 23:35:54 2024
From: quic_tdas at quicinc.com (Taniya Das)
Date: Mon, 2 Dec 2024 13:05:54 +0530
Subject: [PATCH v3 05/11] dt-bindings: clock: Add Qualcomm QCS615 Display
 clock controller
In-Reply-To: <s5rie2osuh2ngkwd2jinly7ulogqqeqois724h3e54a7rqrn2w@wn3yypxi7wca>
References: <20241108-qcs615-mm-clockcontroller-v3-0-7d3b2d235fdf@quicinc.com>
 <20241108-qcs615-mm-clockcontroller-v3-5-7d3b2d235fdf@quicinc.com>
 <173104478441.565041.9851772057058427001.robh@kernel.org>
 <s5rie2osuh2ngkwd2jinly7ulogqqeqois724h3e54a7rqrn2w@wn3yypxi7wca>
Message-ID: <74e5b8b5-ee09-4fb5-9643-14ea11c445e5@quicinc.com>



On 11/8/2024 5:09 PM, Krzysztof Kozlowski wrote:
>> dtschema/dtc warnings/errors:
>> Documentation/devicetree/bindings/clock/qcom,qcs615-dispcc.example.dts:19:18: fatal error: dt-bindings/clock/qcom,qcs615-gcc.h: No such file or directory
>>     19 |         #include <dt-bindings/clock/qcom,qcs615-gcc.h>
>>        |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> compilation terminated.
>> make[2]: *** [scripts/Makefile.dtbs:129: Documentation/devicetree/bindings/clock/qcom,qcs615-dispcc.example.dtb] Error 1
>> make[2]: *** Waiting for unfinished jobs....
>> make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1442: dt_binding_check] Error 2
>> make: *** [Makefile:224: __sub-make] Error 2
>>
>> doc reference errors (make refcheckdocs):
>>
>> Seehttps://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241108-qcs615-mm-clockcontroller-v3-5-7d3b2d235fdf at quicinc.com
>>
>> The base for the series is generally the latest rc1. A different dependency
>> should be noted in*this*  patch.
> I see this patchset being sent again without changes and receiving same
> errors again, so maybe you expect different results, like some review? I
> don't know, but just in case that's the case please carefully read
> message you got.
> 
> If lack of review is expected, then of course no problem here.

The base patch dependency(GCC) clock controller was mentioned in the 
cover letter:
https://lore.kernel.org/all/20241022-qcs615-clock-driver-v4-0-3d716ad0d987 at quicinc.com/

Thanks, I will keep a note to notify reviewers explicitly mentioning the 
dependency.



-- 
Thanks & Regards,
Taniya Das.


From andrej.picej at norik.com  Sun Dec  1 23:20:40 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:40 +0100
Subject: [PATCH v2 03/15] arm64: dts: imx8mm-phycore-som: Remove magic-packet property
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-4-andrej.picej@norik.com>

From: Teresa Remmet <t.remmet at phytec.de>

Remove device tree property "fsl,magic-packet" as WoL is not working
on the SoM and so not required. This also saves a significant amount of
power during suspend as the ethernet phy is not powered down otherwise.

Signed-off-by: Teresa Remmet <t.remmet at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change
---
 arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
index 7761acc5c510..8de5a46512b0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
@@ -69,7 +69,6 @@ opp-750000000 {
 
 /* Ethernet */
 &fec1 {
-	fsl,magic-packet;
 	phy-mode = "rgmii-id";
 	phy-handle = <&ethphy0>;
 	pinctrl-names = "default";
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:37 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:37 +0100
Subject: [PATCH v2 00/15] Update PHYTEC's i.MX8MM DTSs
Message-ID: <20241202072052.2195283-1-andrej.picej@norik.com>

Hi all,

these patches aim to get PHYTEC downstream kernel device-tree changes
into the mainline for the phyCORE-i.MX8MM SoM and boards (phyBOARD-Polis
and phyGATE-Tauri-L).

Changes mainly fix suspending/resuming with different wakeup-sources and
add missing regulators. Last 4 patches add additional overlays. Some are
meant to be used with PHYTEC's "option tree" to add/disable optional SoM
components (idea behind it is outlined in [1]).

[1] https://lore.kernel.org/all/4e7dd467-20be-43ce-936d-200ede6d511b at phytec.de/

v1 at: https://lore.kernel.org/all/20241125081814.397352-1-andrej.picej at norik.com/
v2 changes in corresponding patches.

Best regards,
Andrej

Andrej Picej (3):
  arm64: dts: imx8mm-phycore-som: Fix bluetooth wakeup source
  arm64: dts: imx8mm-phyboard-polis: Set RTC as wakeup-source
  arm64: dts: imx8mm-phygate-tauri-l: Set RTC as wakeup-source

Dominik Haller (1):
  arm64: dts: imx8mm-phycore-som: Add overlay for rproc

Janine Hagemann (1):
  arm64: dts: imx8mm-phyboard-polis: Add overlay for PEB-EVAL-01

Teresa Remmet (5):
  arm64: dts: imx8mm-phycore-som: Keep LDO3 on in suspend
  arm64: dts: imx8mm-phycore-som: Remove magic-packet property
  arm64: dts: imx8mm-phyboard-polis: Add support for PEB-AV-10
  arm64: dts: imx8mm-phycore-som: Add no-eth phy overlay
  arm64: dts: imx8mm-phycore-som: Add overlay to disable SPI NOR flash

Yannic Moog (3):
  arm64: dts: imx8mm-phycore-som: add descriptions to nodes
  arm64: dts: imx8mm-phyboard-polis: add RTC description
  arm64: dts: imx8mm: move bulk of rtc properties to carrierboards

Yashwanth Varakala (2):
  arm64: dts: imx8mm-phycore-som: Assign regulator for dsi to lvds
    bridge
  arm64: dts: imx8mm-phyboard-polis: Assign missing regulator for
    bluetooth

 arch/arm64/boot/dts/freescale/Makefile        |  13 +
 .../imx8mm-phyboard-polis-peb-av-10.dtso      | 237 ++++++++++++++++++
 .../imx8mm-phyboard-polis-peb-eval-01.dtso    |  72 ++++++
 .../freescale/imx8mm-phyboard-polis-rdk.dts   |  17 +-
 .../dts/freescale/imx8mm-phycore-no-eth.dtso  |  12 +
 .../freescale/imx8mm-phycore-no-spiflash.dtso |  16 ++
 .../dts/freescale/imx8mm-phycore-rpmsg.dtso   |  55 ++++
 .../dts/freescale/imx8mm-phycore-som.dtsi     |  22 +-
 .../dts/freescale/imx8mm-phygate-tauri-l.dts  |  11 +
 9 files changed, 439 insertions(+), 16 deletions(-)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-eval-01.dtso
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phycore-no-eth.dtso
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phycore-no-spiflash.dtso
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phycore-rpmsg.dtso

-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:38 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:38 +0100
Subject: [PATCH v2 01/15] arm64: dts: imx8mm-phycore-som: Keep LDO3 on in suspend
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-2-andrej.picej@norik.com>

From: Teresa Remmet <t.remmet at phytec.de>

LDO3 is also used as switch for enabling VDD_3V3_S and need to
be kept on during suspend. Disabling this can lead to an unwanted
reset during resume.

Set LDO3 to 2,5V as the voltage should be fix.

Signed-off-by: Teresa Remmet <t.remmet at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change
---
 arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
index 6069678244f3..7761acc5c510 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
@@ -161,11 +161,13 @@ reg_vcc_enet: ldo3 {
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-max-microvolt = <2500000>;
-				regulator-min-microvolt = <1500000>;
+				regulator-min-microvolt = <2500000>;
 				regulator-name = "VCC_ENET_2V5 (LDO3)";
 
 				regulator-state-mem {
-					regulator-off-in-suspend;
+					regulator-on-in-suspend;
+					regulator-suspend-max-microvolt = <2500000>;
+					regulator-suspend-min-microvolt = <2500000>;
 				};
 			};
 
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:39 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:39 +0100
Subject: [PATCH v2 02/15] arm64: dts: imx8mm-phycore-som: Fix bluetooth wakeup source
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-3-andrej.picej@norik.com>

Not using pull-up on the host wake-up line triggers the wake up
immediately after device enters suspend. Fix this by enabling internal
pull-up and setting interrupt triggering on the falling edge.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
Reviewed-by: Teresa Remmet <t.remmet at phytec.de>
---
Changes in v2:
 - added Teresa's Reviewed-by tag.
---
 arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
index 5eacbd9611ee..31d5c57d3c24 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
@@ -255,7 +255,7 @@ bluetooth {
 		device-wakeup-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
 		interrupt-names = "host-wakeup";
 		interrupt-parent = <&gpio2>;
-		interrupts = <9 IRQ_TYPE_EDGE_BOTH>;
+		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
 		max-speed = <2000000>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_bt>;
@@ -332,7 +332,7 @@ pinctrl_bt: btgrp {
 		fsl,pins = <
 			MX8MM_IOMUXC_SD1_DATA4_GPIO2_IO6	0x00
 			MX8MM_IOMUXC_SD1_DATA6_GPIO2_IO8	0x00
-			MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9	0x00
+			MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9	0x140
 		>;
 	};
 
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:41 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:41 +0100
Subject: [PATCH v2 04/15] arm64: dts: imx8mm-phycore-som: Assign regulator for dsi to lvds bridge
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-5-andrej.picej@norik.com>

From: Yashwanth Varakala <y.varakala at phytec.de>

Add a missing voltage regulator of 1.8v to the sn65dsi83
(dsi_lvds bridge) node. Due to the absence of this regulator, a fallback
dummy regulator is used and that triggers a warning message from the
kernel. Assigning the appropriate regulator avoids the warning.

Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change
---
 arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
index 8de5a46512b0..7e859c65317a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
@@ -286,6 +286,7 @@ sn65dsi83: bridge at 2d {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_sn65dsi83>;
 		reg = <0x2d>;
+		vcc-supply = <&reg_vdd_1v8>;
 		status = "disabled";
 	};
 
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:42 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:42 +0100
Subject: [PATCH v2 05/15] arm64: dts: imx8mm-phycore-som: add descriptions to nodes
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-6-andrej.picej@norik.com>

From: Yannic Moog <y.moog at phytec.de>

Add missing EEPROM and RTC descriptions. Also use eMMC with
lower-case "e".

Signed-off-by: Yannic Moog <y.moog at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change
---
 arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
index 7e859c65317a..cced82226c6d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
@@ -290,6 +290,7 @@ sn65dsi83: bridge at 2d {
 		status = "disabled";
 	};
 
+	/* EEPROM */
 	eeprom at 51 {
 		compatible = "atmel,24c32";
 		pagesize = <32>;
@@ -297,6 +298,7 @@ eeprom at 51 {
 		vcc-supply = <&reg_vdd_3v3_s>;
 	};
 
+	/* RTC */
 	rv3028: rtc at 52 {
 		compatible = "microcrystal,rv3028";
 		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
@@ -307,7 +309,7 @@ rv3028: rtc at 52 {
 	};
 };
 
-/* EMMC */
+/* eMMC */
 &usdhc3 {
 	assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>;
 	assigned-clock-rates = <400000000>;
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:43 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:43 +0100
Subject: [PATCH v2 06/15] arm64: dts: imx8mm-phyboard-polis: add RTC description
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-7-andrej.picej@norik.com>

From: Yannic Moog <y.moog at phytec.de>

Add RTC description.

Signed-off-by: Yannic Moog <y.moog at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change
---
 arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
index 31d5c57d3c24..6c95257119d6 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
@@ -219,6 +219,7 @@ &pcie_phy {
 	status = "okay";
 };
 
+/* RTC */
 &rv3028 {
 	aux-voltage-chargeable = <1>;
 	trickle-resistor-ohms = <3000>;
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:44 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:44 +0100
Subject: [PATCH v2 07/15] arm64: dts: imx8mm-phyboard-polis: Set RTC as wakeup-source
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-8-andrej.picej@norik.com>

RV-3028 RTC can be used to wakeup the system on phyBOARD-Polis-i.MX8MM,
mark the device as wakeup source.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
Reviewed-by: Teresa Remmet <t.remmet at phytec.de>
---
Changes in v2:
 - added Teresa's Reviewed-by tag.
---
 arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
index 6c95257119d6..7aaf705c7e47 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
@@ -223,6 +223,7 @@ &pcie_phy {
 &rv3028 {
 	aux-voltage-chargeable = <1>;
 	trickle-resistor-ohms = <3000>;
+	wakeup-source;
 };
 
 &snvs_pwrkey {
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:45 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:45 +0100
Subject: [PATCH v2 08/15] arm64: dts: imx8mm-phygate-tauri-l: Set RTC as wakeup-source
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-9-andrej.picej@norik.com>

RV-3028 RTC can be used to wakeup the system on phyGATE-Tauri-L-i.MX8MM,
mark the device as wakeup source.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
Reviewed-by: Teresa Remmet <t.remmet at phytec.de>
---
Changes in v2:
 - added Teresa's Reviewed-by tag.
---
 arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
index c3835b2d860a..c9bf4ac254bb 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
@@ -217,6 +217,7 @@ &pwm4 {
 &rv3028 {
 	aux-voltage-chargeable = <1>;
 	trickle-resistor-ohms = <3000>;
+	wakeup-source;
 };
 
 &uart1 {
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:46 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:46 +0100
Subject: [PATCH v2 09/15] arm64: dts: imx8mm: move bulk of rtc properties to carrierboards
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-10-andrej.picej@norik.com>

From: Yannic Moog <y.moog at phytec.de>

Move properties from SoM's dtsi to carrierboard's dts as they are
actually defined by the carrier board design.

Signed-off-by: Yannic Moog <y.moog at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - also moved pinctrl settings to the carrier boards dts.
---
 .../boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts   | 10 ++++++++++
 arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi  | 10 ----------
 .../boot/dts/freescale/imx8mm-phygate-tauri-l.dts      | 10 ++++++++++
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
index 7aaf705c7e47..17e5dd40b5d7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
@@ -221,6 +221,10 @@ &pcie_phy {
 
 /* RTC */
 &rv3028 {
+	interrupt-parent = <&gpio1>;
+	interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+	pinctrl-0 = <&pinctrl_rtc>;
+	pinctrl-names = "default";
 	aux-voltage-chargeable = <1>;
 	trickle-resistor-ohms = <3000>;
 	wakeup-source;
@@ -410,6 +414,12 @@ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19	0x40
 		>;
 	};
 
+	pinctrl_rtc: rtcgrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x1c0
+		>;
+	};
+
 	pinctrl_tpm: tpmgrp {
 		fsl,pins = <
 			MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11      0x140
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
index cced82226c6d..672baba4c8d0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi
@@ -301,10 +301,6 @@ eeprom at 51 {
 	/* RTC */
 	rv3028: rtc at 52 {
 		compatible = "microcrystal,rv3028";
-		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
-		interrupt-parent = <&gpio1>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_rtc>;
 		reg = <0x52>;
 	};
 };
@@ -377,12 +373,6 @@ MX8MM_IOMUXC_I2C1_SCL_GPIO5_IO14		0x1e0
 		>;
 	};
 
-	pinctrl_rtc: rtcgrp {
-		fsl,pins = <
-			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x1c0
-		>;
-	};
-
 	pinctrl_sn65dsi83: sn65dsi83grp {
 		fsl,pins = <
 			MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x0
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
index c9bf4ac254bb..755cf9cacd22 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phygate-tauri-l.dts
@@ -215,6 +215,10 @@ &pwm4 {
 
 /* RTC */
 &rv3028 {
+	interrupt-parent = <&gpio1>;
+	interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+	pinctrl-0 = <&pinctrl_rtc>;
+	pinctrl-names = "default";
 	aux-voltage-chargeable = <1>;
 	trickle-resistor-ohms = <3000>;
 	wakeup-source;
@@ -395,6 +399,12 @@ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19     0x40
 		>;
 	};
 
+	pinctrl_rtc: rtcgrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x1c0
+		>;
+	};
+
 	pinctrl_tempsense: tempsensegrp {
 		fsl,pins = <
 			MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31	0x00
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:47 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:47 +0100
Subject: [PATCH v2 10/15] arm64: dts: imx8mm-phyboard-polis: Assign missing regulator for bluetooth
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-11-andrej.picej@norik.com>

From: Yashwanth Varakala <y.varakala at phytec.de>

Assign the missing regulator to the bluetooth node. Absence of
this regulator triggers the warning message from kernel as driver
uses a fallback dummy regulator when there is no regulator assigned.

Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change.
---
 arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
index 17e5dd40b5d7..be470cfb03d7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts
@@ -266,6 +266,7 @@ bluetooth {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_bt>;
 		shutdown-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
+		vbat-supply = <&reg_vcc_3v3>;
 		vddio-supply = <&reg_vcc_3v3>;
 	};
 };
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:49 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:49 +0100
Subject: [PATCH v2 12/15] arm64: dts: imx8mm-phyboard-polis: Add overlay for PEB-EVAL-01
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-13-andrej.picej@norik.com>

From: Janine Hagemann <j.hagemann at phytec.de>

Add support for the PEB-EVAL-01 expansion board for
phyBOARD-Polis-i.MX8MM.

Signed-off-by: Janine Hagemann <j.hagemann at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change.
---
 arch/arm64/boot/dts/freescale/Makefile        |  2 +
 .../imx8mm-phyboard-polis-peb-eval-01.dtso    | 72 +++++++++++++++++++
 2 files changed, 74 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-eval-01.dtso

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index b411d76c3d1d..99be36a04db9 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -124,8 +124,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-phg.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb
 
 imx8mm-phyboard-polis-peb-av-10-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-av-10.dtbo
+imx8mm-phyboard-polis-peb-eval-01-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-eval-01.dtbo
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-av-10.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-eval-01.dtb
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phygate-tauri-l.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-prt8mm.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-eval-01.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-eval-01.dtso
new file mode 100644
index 000000000000..2ca4ae6e2bf2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-eval-01.dtso
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Janine Hagemann <j.hagemann at phytec.de>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include "imx8mm-pinfunc.h"
+
+&{/} {
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		button-0 {
+			label = "home";
+			linux,code = <KEY_HOME>;
+			gpios = <&gpio4 17 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+
+		button-1 {
+			label = "menu";
+			linux,code = <KEY_MENU>;
+			gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+	};
+
+	user-leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_user_leds>;
+
+		user-led1 {
+			gpios = <&gpio4 14 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		user-led2 {
+			gpios = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		user-led3 {
+			gpios = <&gpio5 28 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl_gpio_keys: gpio_keysgrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17	0x16
+			MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29	0x16
+		>;
+	};
+
+	pinctrl_user_leds: user_ledsgrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15	0x16
+			MX8MM_IOMUXC_UART4_RXD_GPIO5_IO28	0x16
+			MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14	0x16
+		>;
+	};
+};
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:50 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:50 +0100
Subject: [PATCH v2 13/15] arm64: dts: imx8mm-phycore-som: Add overlay for rproc
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-14-andrej.picej@norik.com>

From: Dominik Haller <d.haller at phytec.de>

Adds a devicetree overlay containing reserved memory regions used
for intercore communication between A53 and M4 cores.

Signed-off-by: Dominik Haller <d.haller at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change.
---
 arch/arm64/boot/dts/freescale/Makefile        |  2 +
 .../dts/freescale/imx8mm-phycore-rpmsg.dtso   | 55 +++++++++++++++++++
 2 files changed, 57 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phycore-rpmsg.dtso

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 99be36a04db9..5bc083a7b778 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -125,9 +125,11 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb
 
 imx8mm-phyboard-polis-peb-av-10-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-av-10.dtbo
 imx8mm-phyboard-polis-peb-eval-01-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-eval-01.dtbo
+imx8mm-phycore-rpmsg-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phycore-rpmsg.dtbo
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-av-10.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-eval-01.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-phycore-rpmsg.dtb
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phygate-tauri-l.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-prt8mm.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-rpmsg.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phycore-rpmsg.dtso
new file mode 100644
index 000000000000..0c61946f0cf8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-rpmsg.dtso
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Dominik Haller <d.haller at phytec.de>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/imx8mm-clock.h>
+
+&{/} {
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		m4_reserved: m4 at 80000000 {
+			reg = <0 0x80000000 0 0x1000000>;
+			no-map;
+		};
+
+		vdev0vring0: vdev0vring0 at b8000000 {
+			reg = <0 0xb8000000 0 0x8000>;
+			no-map;
+		};
+
+		vdev0vring1: vdev0vring1 at b8008000 {
+			reg = <0 0xb8008000 0 0x8000>;
+			no-map;
+		};
+
+		rsc_table: rsc_table at b80ff000 {
+			reg = <0 0xb80ff000 0 0x1000>;
+			no-map;
+		};
+
+		vdevbuffer: vdevbuffer at b8400000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0xb8400000 0 0x100000>;
+			no-map;
+		};
+	};
+
+	core-m4 {
+		compatible = "fsl,imx8mm-cm4";
+		clocks = <&clk IMX8MM_CLK_M4_DIV>;
+		mboxes = <&mu 0 1
+			&mu 1 1
+			&mu 3 1>;
+		mbox-names = "tx", "rx", "rxdb";
+		memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>;
+		syscon = <&src>;
+	};
+};
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:48 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:48 +0100
Subject: [PATCH v2 11/15] arm64: dts: imx8mm-phyboard-polis: Add support for PEB-AV-10
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-12-andrej.picej@norik.com>

From: Teresa Remmet <t.remmet at phytec.de>

PEB-AV-10 is an Audio/Video extension module which extends
phyBOARD-Polis i.MX8MM.
With MIPI DSI to LVDS bridge already populated on SoM the PEB-AV-10 adds
support for:
- connecting 10" display,
- audio with TLV320AIC and
- EEPROM.

Signed-off-by: Teresa Remmet <t.remmet at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change.
---
 arch/arm64/boot/dts/freescale/Makefile        |   5 +
 .../imx8mm-phyboard-polis-peb-av-10.dtso      | 237 ++++++++++++++++++
 2 files changed, 242 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 9d3df8b218a2..b411d76c3d1d 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -122,6 +122,11 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-mx8menlo.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phg.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb
+
+imx8mm-phyboard-polis-peb-av-10-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-av-10.dtbo
+
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-av-10.dtb
+
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phygate-tauri-l.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-prt8mm.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-tqma8mqml-mba8mx.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
new file mode 100644
index 000000000000..a9de42cf14be
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Teresa Remmet <t.remmet at phytec.de>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/imx8mm-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "imx8mm-pinfunc.h"
+
+&{/} {
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_lcd>;
+		default-brightness-level = <6>;
+		pwms = <&pwm4 0 50000 0>;
+		power-supply = <&reg_vdd_3v3_s>;
+		enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+		brightness-levels= <0 4 8 16 32 64 128 255>;
+	};
+
+	panel {
+		compatible = "edt,etml1010g3dra";
+		backlight = <&backlight>;
+		power-supply = <&reg_vcc_3v3>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&bridge_out>;
+			};
+		};
+	};
+
+	reg_sound_1v8: regulator-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_1V8_Audio";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	reg_sound_3v3: regulator-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_3V3_Analog";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	sound-peb-av-10 {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "snd-peb-av-10";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink_master>;
+		simple-audio-card,frame-master = <&dailink_master>;
+		simple-audio-card,mclk-fs = <32>;
+		simple-audio-card,widgets =
+			"Line", "Line In",
+			"Speaker", "Speaker",
+			"Microphone", "Microphone Jack",
+			"Headphone", "Headphone Jack";
+		simple-audio-card,routing =
+			"Speaker", "SPOP",
+			"Speaker", "SPOM",
+			"Headphone Jack", "HPLOUT",
+			"Headphone Jack", "HPROUT",
+			"LINE1L", "Line In",
+			"LINE1R", "Line In",
+			"MIC3R", "Microphone Jack",
+			"Microphone Jack", "Mic Bias";
+
+		simple-audio-card,cpu {
+			sound-dai = <&sai5>;
+		};
+
+		dailink_master: simple-audio-card,codec {
+			sound-dai = <&codec>;
+			clocks = <&clk IMX8MM_CLK_SAI5>;
+		};
+	};
+};
+
+&i2c3 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	pinctrl-1 = <&pinctrl_i2c3_gpio>;
+	sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	codec: codec at 18 {
+		compatible = "ti,tlv320aic3007";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_tlv320>;
+		#sound-dai-cells = <0>;
+		reg = <0x18>;
+		reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+		ai3x-gpio-func = <0xd 0x0>;
+		ai3x-micbias-vg = <2>;
+		AVDD-supply = <&reg_sound_3v3>;
+		IOVDD-supply = <&reg_sound_3v3>;
+		DRVDD-supply = <&reg_sound_3v3>;
+		DVDD-supply = <&reg_sound_1v8>;
+	};
+
+	eeprom at 57 {
+		compatible = "atmel,24c32";
+		pagesize = <32>;
+		reg = <0x57>;
+		vcc-supply = <&reg_vdd_3v3_s>;
+	};
+
+	eeprom at 5f {
+		compatible = "atmel,24c32";
+		pagesize = <32>;
+		reg = <0x5f>;
+		size = <32>;
+		vcc-supply = <&reg_vdd_3v3_s>;
+	};
+};
+
+&lcdif {
+	status = "okay";
+};
+
+&mipi_dsi {
+	samsung,esc-clock-frequency = <10000000>;
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port at 1 {
+			reg = <1>;
+			dsi_out: endpoint {
+				remote-endpoint = <&bridge_in>;
+			};
+		};
+	};
+};
+
+&pwm4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm4>;
+	status = "okay";
+};
+
+&sai5 {
+	assigned-clocks = <&clk IMX8MM_CLK_SAI5>;
+	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>;
+	assigned-clock-rates = <11289600>;
+	clocks = <&clk IMX8MM_CLK_SAI5_IPG>, <&clk IMX8MM_CLK_DUMMY>,
+		<&clk IMX8MM_CLK_SAI5_ROOT>, <&clk IMX8MM_CLK_DUMMY>,
+		<&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_AUDIO_PLL1_OUT>,
+		<&clk IMX8MM_AUDIO_PLL2_OUT>;
+	clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k",
+			"pll11k";
+	fsl,sai-mclk-direction-output;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai5>;
+	#sound-dai-cells = <0>;
+	status = "okay";
+};
+
+&sn65dsi83 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+			bridge_in: endpoint {
+				remote-endpoint = <&dsi_out>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+
+		port at 2 {
+			reg = <2>;
+			bridge_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+	};
+};
+
+&iomuxc {
+
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL          0x400001c2
+			MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA          0x400001c2
+		>;
+	};
+
+	pinctrl_i2c3_gpio: i2c3gpiogrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18        0x1e2
+			MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19        0x1e2
+		>;
+	};
+	pinctrl_lcd: lcd0grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1		0x12
+		>;
+	};
+
+	pinctrl_pwm4: pwm4grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SAI3_MCLK_PWM4_OUT		0x12
+		>;
+	};
+
+	pinctrl_sai5: sai5grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK        0xd6
+			MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0    0xd6
+			MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC     0xd6
+			MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK     0xd6
+			MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0    0xd6
+		>;
+	};
+
+	pinctrl_tlv320: tlv320grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28       0x16
+			MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20        0x16
+		>;
+	};
+};
-- 
2.34.1



From andrej.picej at norik.com  Sun Dec  1 23:20:51 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon,  2 Dec 2024 08:20:51 +0100
Subject: [PATCH v2 14/15] arm64: dts: imx8mm-phycore-som: Add no-eth phy overlay
In-Reply-To: <20241202072052.2195283-1-andrej.picej@norik.com>
References: <20241202072052.2195283-1-andrej.picej@norik.com>
Message-ID: <20241202072052.2195283-15-andrej.picej@norik.com>

From: Teresa Remmet <t.remmet at phytec.de>

There are SoM variants with no eth phy populated. Add overlay to be
able to support this.

Signed-off-by: Teresa Remmet <t.remmet at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
 - no change.
---
 arch/arm64/boot/dts/freescale/Makefile               |  2 ++
 .../boot/dts/freescale/imx8mm-phycore-no-eth.dtso    | 12 ++++++++++++
 2 files changed, 14 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-phycore-no-eth.dtso

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 5bc083a7b778..da6ddce6b7c7 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -125,10 +125,12 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb
 
 imx8mm-phyboard-polis-peb-av-10-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-av-10.dtbo
 imx8mm-phyboard-polis-peb-eval-01-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phyboard-polis-peb-eval-01.dtbo
+imx8mm-phycore-no-eth-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phycore-no-eth.dtbo
 imx8mm-phycore-rpmsg-dtbs += imx8mm-phyboard-polis-rdk.dtb imx8mm-phycore-rpmsg.dtbo
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-av-10.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-peb-eval-01.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-phycore-no-eth.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phycore-rpmsg.dtb
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-phygate-tauri-l.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-no-eth.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phycore-no-eth.dtso
new file mode 100644
index 000000000000..dd66ccfbb4d7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-no-eth.dtso
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Teresa Remmet <t.remmet at phytec.de>
+ */
+
+/dts-v1/;
+/plugin/;
+
+&ethphy0 {
+	status = "disabled";
+};
-- 
2.34.1



From quic_tdas at quicinc.com  Sun Dec  1 23:36:58 2024
From: quic_tdas at quicinc.com (Taniya Das)
Date: Mon, 2 Dec 2024 13:06:58 +0530
Subject: [PATCH v3 10/11] clk: qcom: videocc-qcs615: Add QCS615 video
 clock controller driver
In-Reply-To: <d4afdd01-3147-4cfc-820a-f6004637e6bf@linaro.org>
References: <20241108-qcs615-mm-clockcontroller-v3-0-7d3b2d235fdf@quicinc.com>
 <20241108-qcs615-mm-clockcontroller-v3-10-7d3b2d235fdf@quicinc.com>
 <d4afdd01-3147-4cfc-820a-f6004637e6bf@linaro.org>
Message-ID: <8d08c539-6abf-4def-890f-e54176f26efc@quicinc.com>



On 11/9/2024 10:52 PM, Bryan O'Donoghue wrote:
> On 08/11/2024 04:09, Taniya Das wrote:
>> +static struct gdsc vcodec0_gdsc = {
>> +??? .gdscr = 0x874,
>> +??? .en_rest_wait_val = 0x2,
>> +??? .en_few_wait_val = 0x2,
>> +??? .clk_dis_wait_val = 0x6,
>> +??? .pd = {
>> +??????? .name = "vcodec0_gdsc",
>> +??? },
>> +??? .pwrsts = PWRSTS_OFF_ON,
>> +??? .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR,
>> +};
>> +
>> +static struct gdsc venus_gdsc = {
>> +??? .gdscr = 0x814,
>> +??? .en_rest_wait_val = 0x2,
>> +??? .en_few_wait_val = 0x2,
>> +??? .clk_dis_wait_val = 0x6,
>> +??? .pd = {
>> +??????? .name = "venus_gdsc",
>> +??? },
>> +??? .pwrsts = PWRSTS_OFF_ON,
>> +??? .flags = POLL_CFG_GDSCR,
>> +};
>> +
> 
> This looks good to me, except; could you please check if venus gdsc 
> should be the parent of vcodec0.

For the video gdscs we generally do not explicitly need to mention the 
parent GDSC.

-- 
Thanks & Regards,
Taniya Das.


From quic_tdas at quicinc.com  Sun Dec  1 23:39:12 2024
From: quic_tdas at quicinc.com (Taniya Das)
Date: Mon, 2 Dec 2024 13:09:12 +0530
Subject: [PATCH v3 00/11] Add support for videocc, camcc, dispcc and gpucc
 on Qualcomm QCS615 platform
In-Reply-To: <a4f6ojknv3hats4rwmdg5mw2rxhx7kq4u6axybdawak54crn5s@xnjbl7zno42s>
References: <20241108-qcs615-mm-clockcontroller-v3-0-7d3b2d235fdf@quicinc.com>
 <a4f6ojknv3hats4rwmdg5mw2rxhx7kq4u6axybdawak54crn5s@xnjbl7zno42s>
Message-ID: <bfabfba2-6688-4461-83d6-b6f4c86b08ab@quicinc.com>



On 12/2/2024 9:55 AM, Bjorn Andersson wrote:
> On Fri, Nov 08, 2024 at 09:39:17AM +0530, Taniya Das wrote:
>> Add support for multimedia clock controllers on Qualcomm QCS615 platform.
>> Update the defconfig to enable these clock controllers.
>>
>> Global clock controller support
>> https://lore.kernel.org/all/20241022-qcs615-clock-driver-v4-0-3d716ad0d987 at quicinc.com/
>>
>> Signed-off-by: Taniya Das<quic_tdas at quicinc.com>
> Dropping this series from my queue, due to lack of response from author.
> 
> Taniya, please answer questions/feedback from Dmitry, Vladimir and
> Bryan, and repose as necessary.

Sure, Bjorn, I had a dependency on the GCC patch.
 
https://lore.kernel.org/all/20241022-qcs615-clock-driver-v4-0-3d716ad0d987 at quicinc.com/

I will fix the comments once the Global clock controller patch is picked.

-- 
Thanks & Regards,
Taniya Das.


From pengfei.li_1 at nxp.com  Sun Dec  1 23:24:44 2024
From: pengfei.li_1 at nxp.com (Pengfei Li)
Date: Mon, 2 Dec 2024 15:24:44 +0800
Subject: [PATCH v3 0/4] Add i.MX91 platform support
In-Reply-To: <20241120094945.3032663-1-pengfei.li_1@nxp.com>
References: <20241120094945.3032663-1-pengfei.li_1@nxp.com>
Message-ID: <Z01gfuVIIhl0rYwI@pengfei-OptiPlex-Tower-Plus-7010>

On Wed, Nov 20, 2024 at 05:49:41PM +0800, Pengfei Li wrote:
> The design of the i.MX91 platform is very similar to i.MX93.
> The mainly difference between i.MX91 and i.MX93 is as follows:
> - i.MX91 removed some clocks and modified the names of some clocks.
> - i.MX91 only has one A core
> - i.MX91 has different pinmux
> 
> Therefore, i.MX91 can reuse i.MX93 dtsi.
> 
> ---
> Change for v3:
> - Add Conor's ack on patch #1
> - format imx91-11x11-evk.dts with the dt-format tool
> - add lpi2c1 node
> - link to v2: https://lore.kernel.org/all/20241118051541.2621360-1-pengfei.li_1 at nxp.com/
> 
> Pengfei Li (4):
>   dt-bindings: arm: fsl: Add i.MX91 11x11 evk board
>   arm64: dts: freescale: Add i.MX91 dtsi support
>   arm64: dts: freescale: Add i.MX91 11x11 EVK basic support
>   arm64: defconfig: enable i.MX91 pinctrl
> 
>  .../devicetree/bindings/arm/fsl.yaml          |   6 +
>  arch/arm64/boot/dts/freescale/Makefile        |   1 +
>  .../boot/dts/freescale/imx91-11x11-evk.dts    | 875 ++++++++++++++++++
>  arch/arm64/boot/dts/freescale/imx91-pinfunc.h | 770 +++++++++++++++
>  arch/arm64/boot/dts/freescale/imx91.dtsi      |  70 ++
>  arch/arm64/configs/defconfig                  |   1 +
>  6 files changed, 1723 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/imx91-pinfunc.h
>  create mode 100644 arch/arm64/boot/dts/freescale/imx91.dtsi
> 
> -- 
> 2.34.1
> 
> 

Hi Rob Herring,

I haven't received any comments from others about this version of the patch set, is this patch set applicable?

BR,
Pengfei Li



From krzk at kernel.org  Sun Dec  1 23:56:07 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 08:56:07 +0100
Subject: [PATCH] media: dt-bindings: sony,imx415: add required
 clock-names property
In-Reply-To: <20241130141716.1007115-1-matthias.fend@emfend.at>
References: <20241130141716.1007115-1-matthias.fend@emfend.at>
Message-ID: <bh3obpt6bcklejdvrk4r6ienraz5zmhrdyotijhvlwexussqgj@hicmx34vi27w>

On Sat, Nov 30, 2024 at 03:17:15PM +0100, Matthias Fend wrote:
> The imx415 driver expects a clock with the name "inck".
> Document this in the bindings.

No, fix the driver instead of bypassing review. It was decided to drop
it during review, so you cannot reintroduce it 2 years later claiming
that's now ABI. Of course original submission was buggy and never
tested, but that does not allow review bypass.

Best regards,
Krzysztof



From eauger at redhat.com  Mon Dec  2 00:03:26 2024
From: eauger at redhat.com (Eric Auger)
Date: Mon, 2 Dec 2024 09:03:26 +0100
Subject: [PATCH] KVM: arm64: Make the exposed feature bits in AA64DFR0_EL1
 writable from userspace
In-Reply-To: <865xo3vbjq.wl-maz@kernel.org>
References: <20240813142835.77180-1-shameerali.kolothum.thodi@huawei.com>
 <86v804z3lk.wl-maz@kernel.org> <b2dad37ac5464384abe4edf76cb6b546@huawei.com>
 <4d3a7dde-e085-fa70-8859-ba153c93b615@redhat.com>
 <87zfllssji.wl-maz@kernel.org>
 <c879fda9-db5a-4743-805d-03c0acba8060@redhat.com>
 <865xo3vbjq.wl-maz@kernel.org>
Message-ID: <e35612b4-e25b-4846-8fd2-56c2473c140d@redhat.com>

Hi Marc,

On 12/1/24 13:21, Marc Zyngier wrote:
> Hey Eric,
> 
> On Thu, 28 Nov 2024 09:31:08 +0000,
> Eric Auger <eauger at redhat.com> wrote:
>>
>> Hi Marc,
>>
>> On 11/26/24 20:29, Marc Zyngier wrote:
>>> Finally, who is going to ensure this keeps working in the foreseeable
>>> future? Because while this is nice, that's not what gets deployed in
>>> production, as it leads to unpredictable performances. My take is that
>>> this thing will eventually bitrot and die.
>> In the context of our works to define qemu vcpu models for ARM
>> (https://lore.kernel.org/all/20241025101959.601048-1-eric.auger at redhat.com/)
>> , our current approach is to try migrating between modern HW we have
>> access to. The case above is migration between AmpereOne and Grace which
>> both should be prevalent systems. Do you think this does not make sense
>> at all to try migrating between those, alhough this may be challenging?
> 
> I don't mind the challenge. But I'm worried this is something that
> looks like a reasonable idea that doesn't get any traction in
> practice.
> 
> And the example you mention is pretty striking: who in their right
> mind would migrate between these two systems? If you deploy a Grace
> system, that's because you are making use of the GPU, and your VM is
> likely to require it. Conversely, if you run on an Ampere system, you
> don't want to use a valuable (read: bloody expensive) slot on a Grace
> machine.

Yes I acknowledge it is a total valid point from a use case and cost
point of view. I was expecting maybe some interest migrating between
AmpereOne and Grace-Grace for farm enhancement but most probably it is
marginal.

Definition of [qemu] named vcpu models looks pretty uneasy then because
we don't have much relevant and accessible HW to test with, taking into
account such non technical considerations. Besides migration within a
CPU family I don't see much.
> 
>> Other cases we have looked at are migration within Ampere Altra Max
>> system family (which should be hopefully fine now with have CTR_EL0
>> works from Sebastian upstream), mig between Graviton hosts. Wrt Ampere
>> Altra Max to AmpereOne, Oliver pointed out the cntfrq issue which is
>> blocking.
>>
>> Do you think we should restrict our studies to systems which are
>> "closer" to each other in terms of ARM spec rev. We throught that
>> migration bewteen AmpereOne And Grace would be an interesting POC and
>> not totally irrelevant in terms of industry.
> 
> These two implementations may be close in terms of CPU features. But
> as systems, they are massively different, and I very much doubt they
> have the same deployment story. If they have one at all.
OK thank you for sharing your point of view.
> 
> The Graviton story may have more traction, but these folks have their
> own way of doing things, and in my experience do not give upstream
> much consideration.
OK thanks
> 
> To sum it up, I'm not opposed to this work. But if we are going to
> carry this sort of complex emulation, I want someone to step up and
> promise that they will test it for the next 10 years, at the very
> least. Because I'm very unlikely to ever have access to any of these
> machines, let alone both, and I don't see people using it in practice.
understood!

Thanks

Eric
> 
> Thanks,
> 
> 	M.
> 



From claudiu.beznea at tuxon.dev  Mon Dec  2 00:05:11 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Mon, 2 Dec 2024 10:05:11 +0200
Subject: [PATCH] ARM: at91: pm: change BU Power Switch to automatic mode
In-Reply-To: <20241125165648.509162-1-nicolas.ferre@microchip.com>
References: <20241125165648.509162-1-nicolas.ferre@microchip.com>
Message-ID: <34a5b77b-e732-4393-a469-d9c719afa879@tuxon.dev>

Hi, Nicolas,

On 25.11.2024 18:56, nicolas.ferre at microchip.com wrote:
> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> Change how the Backup Unit Power is configured and force the
> automatic/hardware mode.
> This change eliminates the need for software management of the power
> switch, ensuring it transitions to the backup power source before
> entering low power modes.
> 
> This is done in the only locaton where this swich was configured. It's

s/locaton/location

> usually done in the bootloader.
> 
> Previously, the loss of the VDDANA (or VDDIN33) power source was not
> automatically compensated by an alternative power source. This resulted
> in the loss of Backup Unit content, including Backup Self-refresh low
> power mode information, OTP emulation configuration, and boot
> configuration, for instance.

Should we add a fixes for this?

> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
> ---
>  arch/arm/mach-at91/pm.c | 31 ++++++++++++++++++++-----------
>  1 file changed, 20 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
> index b9b995f8a36e..05a1547642b6 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -598,7 +598,21 @@ static int at91_suspend_finish(unsigned long val)
>  	return 0;
>  }
>  
> -static void at91_pm_switch_ba_to_vbat(void)
> +/**
> + * at91_pm_switch_ba_to_auto() - Configure Backup Unit Power Switch
> + * to automatic/hardware mode.
> + *
> + * The Backup Unit Power Switch can be managed either by software or hardware.
> + * Enabling hardware mode allows the automatic transition of power between
> + * VDDANA (or VDDIN33) and VDDBU (or VBAT, respectively), based on the
> + * availability of these power sources.
> + *
> + * If the Backup Unit Power Switch is already in automatic mode, no action is
> + * required. If it is in software-controlled mode, it is switched to automatic
> + * mode to enhance safety and eliminate the need for toggling between power
> + * sources.
> + */
> +static void at91_pm_switch_ba_to_auto(void)
>  {
>  	unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu);
>  	unsigned int val;
> @@ -609,24 +623,19 @@ static void at91_pm_switch_ba_to_vbat(void)
>  
>  	val = readl(soc_pm.data.sfrbu + offset);
>  
> -	/* Already on VBAT. */
> -	if (!(val & soc_pm.sfrbu_regs.pswbu.state))
> +	/* Already on auto/hardware. */
> +	if (!(val & soc_pm.sfrbu_regs.pswbu.ctrl))
>  		return;
>  
> -	val &= ~soc_pm.sfrbu_regs.pswbu.softsw;

It seems that softsw and state members of at91_pm_sfrbu_regs.pswbu along
with their initialization could be dropped. What do you think?

I can do it while applying, if any.

Thank you,
Claudiu


> -	val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl;
> +	val &= ~soc_pm.sfrbu_regs.pswbu.ctrl;
> +	val |= soc_pm.sfrbu_regs.pswbu.key;
>  	writel(val, soc_pm.data.sfrbu + offset);
> -
> -	/* Wait for update. */
> -	val = readl(soc_pm.data.sfrbu + offset);
> -	while (val & soc_pm.sfrbu_regs.pswbu.state)
> -		val = readl(soc_pm.data.sfrbu + offset);
>  }
>  
>  static void at91_pm_suspend(suspend_state_t state)
>  {
>  	if (soc_pm.data.mode == AT91_PM_BACKUP) {
> -		at91_pm_switch_ba_to_vbat();
> +		at91_pm_switch_ba_to_auto();
>  
>  		cpu_suspend(0, at91_suspend_finish);
>  


From claudiu.beznea at tuxon.dev  Mon Dec  2 00:08:25 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Mon, 2 Dec 2024 10:08:25 +0200
Subject: [PATCH 1/2] ARM: dts: microchip: sam9x7: Move i2c address/size to
 dtsi
In-Reply-To: <20241122080523.3941-2-mihai.sain@microchip.com>
References: <20241122080523.3941-1-mihai.sain@microchip.com>
 <20241122080523.3941-2-mihai.sain@microchip.com>
Message-ID: <db8187d8-5ec6-4aaa-bd61-21cd3a806c66@tuxon.dev>

Hi, Mihai,

On 22.11.2024 10:05, Mihai Sain wrote:
> Since these properties are common for all i2c subnodes,
> move them to SoC dtsi from board dts.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

> ---
>  .../dts/microchip/at91-sam9x75_curiosity.dts  |  2 --
>  arch/arm/boot/dts/microchip/sam9x7.dtsi       | 26 +++++++++++++++++++
>  2 files changed, 26 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts
> index 87b6ea97590b..d453800f8e35 100644
> --- a/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts
> +++ b/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts
> @@ -88,8 +88,6 @@ &flx6 {
>  };
>  
>  &i2c6 {
> -	#address-cells = <1>;
> -	#size-cells = <0>;
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_flx6_default>;
>  	i2c-analog-filter;
> diff --git a/arch/arm/boot/dts/microchip/sam9x7.dtsi b/arch/arm/boot/dts/microchip/sam9x7.dtsi
> index beb1f34b38d3..aedba0a8318f 100644
> --- a/arch/arm/boot/dts/microchip/sam9x7.dtsi
> +++ b/arch/arm/boot/dts/microchip/sam9x7.dtsi
> @@ -151,6 +151,8 @@ i2c4: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <13 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 13>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -220,6 +222,8 @@ i2c5: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <14 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 14>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -312,6 +316,8 @@ i2c11: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <32 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 32>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -362,6 +368,8 @@ i2c12: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <33 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 33>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -533,6 +541,8 @@ i2c6: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <9 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 9>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -583,6 +593,8 @@ i2c7: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <10 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 10>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -633,6 +645,8 @@ i2c8: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <11 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 11>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -702,6 +716,8 @@ i2c0: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <5 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 5>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -771,6 +787,8 @@ i2c1: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <6 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 6>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -840,6 +858,8 @@ i2c2: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <7 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 7>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -909,6 +929,8 @@ i2c3: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <8 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 8>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -984,6 +1006,8 @@ i2c9: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <15 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 15>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |
> @@ -1034,6 +1058,8 @@ i2c10: i2c at 600 {
>  				compatible = "microchip,sam9x7-i2c", "microchip,sam9x60-i2c";
>  				reg = <0x600 0x200>;
>  				interrupts = <16 IRQ_TYPE_LEVEL_HIGH 7>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
>  				clocks = <&pmc PMC_TYPE_PERIPHERAL 16>;
>  				dmas = <&dma0
>  					(AT91_XDMAC_DT_MEM_IF(0) |


From claudiu.beznea at tuxon.dev  Mon Dec  2 00:14:25 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Mon, 2 Dec 2024 10:14:25 +0200
Subject: [PATCH 2/2] ARM: dts: microchip: sam9x75_curiosity: Add power
 monitor support
In-Reply-To: <20241122080523.3941-3-mihai.sain@microchip.com>
References: <20241122080523.3941-1-mihai.sain@microchip.com>
 <20241122080523.3941-3-mihai.sain@microchip.com>
Message-ID: <2d8dd1c8-fd4b-4dc1-ba62-312ac86335a6@tuxon.dev>

Hi, Mihai,

On 22.11.2024 10:05, Mihai Sain wrote:
> Add PAC1934 support in order to monitor the board power consumption.
> Device is connected on flexcom7 in twi mode.
> 
> [root at SAM9X75 ~]$ awk -f pac1934.awk
> VDD3V3 current:   10.675 mA, voltage: 3295.41 mV
> VDDOUT4 current:  5.7625 mA, voltage: 1196.78 mV
> VDDCORE current: 115.442 mA, voltage: 1243.65 mV
> VDDIODDR current: 29.585 mA, voltage: 1345.21 mV
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  .../dts/microchip/at91-sam9x75_curiosity.dts  | 52 +++++++++++++++++++
>  1 file changed, 52 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts
> index d453800f8e35..76d7a756e08c 100644
> --- a/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts
> +++ b/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts
> @@ -198,6 +198,52 @@ regulator-state-standby {
>  	};
>  };
>  
> +&flx7 {
> +	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
> +	status = "okay";
> +};
> +
> +&i2c7 {
> +	dmas = <0>, <0>;
> +	i2c-analog-filter;
> +	i2c-digital-filter;
> +	i2c-digital-filter-width-ns = <35>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_flx7_default>;
> +	status = "okay";
> +
> +	power-monitor at 10 {
> +		compatible = "microchip,pac1934";
> +		reg = <0x10>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		channel at 1 {
> +			reg = <0x1>;
> +			shunt-resistor-micro-ohms = <10000>;
> +			label = "VDD3V3";
> +		};
> +
> +		channel at 2 {
> +			reg = <0x2>;
> +			shunt-resistor-micro-ohms = <10000>;
> +			label = "VDDOUT4";

On the schematics at [1] this seems to be named DCDC4. Is there a mistake
on [1] or this patch needs adjustments? If so, I can do it while applying.

Thank you,
Claudiu

[1]
https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/UserGuides/SAM9X75-Curiosity-User-Guide-DS60001859.pdf

> +		};
> +
> +		channel at 3 {
> +			reg = <0x3>;
> +			shunt-resistor-micro-ohms = <10000>;
> +			label = "VDDCORE";
> +		};
> +
> +		channel at 4 {
> +			reg = <0x4>;
> +			shunt-resistor-micro-ohms = <10000>;
> +			label = "VDDIODDR";
> +		};
> +	};
> +};
> +
>  &i2s {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_i2s_default>;
> @@ -231,6 +277,12 @@ pinctrl_flx6_default: flx6-default {
>  				<AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
>  				<AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
>  		};
> +
> +		pinctrl_flx7_default: flx7-default {
> +			atmel,pins =
> +				<AT91_PIOC 0 AT91_PERIPH_C AT91_PINCTRL_PULL_UP>,
> +				<AT91_PIOC 1 AT91_PERIPH_C AT91_PINCTRL_PULL_UP>;
> +		};
>  	};
>  
>  	gpio-keys {


From michael.riesch at wolfvision.net  Mon Dec  2 00:18:56 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Mon, 2 Dec 2024 09:18:56 +0100
Subject: [PATCH] media: dt-bindings: sony,imx415: add required clock-names
 property
In-Reply-To: <bh3obpt6bcklejdvrk4r6ienraz5zmhrdyotijhvlwexussqgj@hicmx34vi27w>
References: <20241130141716.1007115-1-matthias.fend@emfend.at>
 <bh3obpt6bcklejdvrk4r6ienraz5zmhrdyotijhvlwexussqgj@hicmx34vi27w>
Message-ID: <f088a247-8049-49a7-bab3-5b517cb0c531@wolfvision.net>

Hi Matthias, Krzysztof,

On 12/2/24 08:56, Krzysztof Kozlowski wrote:
> On Sat, Nov 30, 2024 at 03:17:15PM +0100, Matthias Fend wrote:
>> The imx415 driver expects a clock with the name "inck".
>> Document this in the bindings.
> 
> No, fix the driver instead of bypassing review. It was decided to drop
> it during review, so you cannot reintroduce it 2 years later claiming
> that's now ABI. Of course original submission was buggy and never
> tested, but that does not allow review bypass.

Just to make sure I am on the same page here: Between v2 and v3 of the
IMX415 submission the clock-names property was dropped. At that point,
we should have changed the acquisition of the clock from
    sensor->clk = devm_clk_get(sensor->dev, "inck");
to
    sensor->clk = devm_clk_get(sensor->dev, NULL);

Is that correct/the proper fix?

> 
> Best regards,
> Krzysztof
> 

Best regards,
Michael


From geert at linux-m68k.org  Mon Dec  2 00:33:18 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 2 Dec 2024 09:33:18 +0100
Subject: [PATCH v2 10/12] lib/crc32test: delete obsolete crc32test.c
In-Reply-To: <20241202012056.209768-11-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org> <20241202012056.209768-11-ebiggers@kernel.org>
Message-ID: <CAMuHMdV5rQggS9YHMJfU0gdhg6oFENTnPKp9Tbp3sJKgQdnMTA@mail.gmail.com>

On Mon, Dec 2, 2024 at 2:24?AM Eric Biggers <ebiggers at kernel.org> wrote:
> From: Eric Biggers <ebiggers at google.com>
>
> Delete crc32test.c, since it has been superseded by crc_kunit.c.
>
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>
> Cc: Vinicius Peixoto <vpeixoto at lkcamp.dev>
> Signed-off-by: Eric Biggers <ebiggers at google.com>
> ---
>  arch/m68k/configs/amiga_defconfig    |   1 -
>  arch/m68k/configs/apollo_defconfig   |   1 -
>  arch/m68k/configs/atari_defconfig    |   1 -
>  arch/m68k/configs/bvme6000_defconfig |   1 -
>  arch/m68k/configs/hp300_defconfig    |   1 -
>  arch/m68k/configs/mac_defconfig      |   1 -
>  arch/m68k/configs/multi_defconfig    |   1 -
>  arch/m68k/configs/mvme147_defconfig  |   1 -
>  arch/m68k/configs/mvme16x_defconfig  |   1 -
>  arch/m68k/configs/q40_defconfig      |   1 -
>  arch/m68k/configs/sun3_defconfig     |   1 -
>  arch/m68k/configs/sun3x_defconfig    |   1 -

Acked-by: Geert Uytterhoeven <geert at linux-m68k.org> # m68k

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 anshuman.khandual at arm.com  Mon Dec  2 00:38:50 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon,  2 Dec 2024 14:08:50 +0530
Subject: [PATCH] arm64/mm: Replace open encodings with PXD_TABLE_BIT
Message-ID: <20241202083850.73207-1-anshuman.khandual@arm.com>

[pgd|p4d]_bad() helpers have open encodings for their respective table bits
which can be replaced with corresponding macros. This makes things clearer,
thus improving their readability as well.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Ryan Roberts <ryan.roberts at arm.com>
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 patch applies on v6.13-rc1

 arch/arm64/include/asm/pgtable.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6986345b537a..e20b80229910 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -896,7 +896,7 @@ static inline bool mm_pud_folded(const struct mm_struct *mm)
 	pr_err("%s:%d: bad pud %016llx.\n", __FILE__, __LINE__, pud_val(e))
 
 #define p4d_none(p4d)		(pgtable_l4_enabled() && !p4d_val(p4d))
-#define p4d_bad(p4d)		(pgtable_l4_enabled() && !(p4d_val(p4d) & 2))
+#define p4d_bad(p4d)		(pgtable_l4_enabled() && !(p4d_val(p4d) & P4D_TABLE_BIT))
 #define p4d_present(p4d)	(!p4d_none(p4d))
 
 static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
@@ -1023,7 +1023,7 @@ static inline bool mm_p4d_folded(const struct mm_struct *mm)
 	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_bad(pgd)		(pgtable_l5_enabled() && !(pgd_val(pgd) & PGD_TABLE_BIT))
 #define pgd_present(pgd)	(!pgd_none(pgd))
 
 static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
-- 
2.30.2



From krzk at kernel.org  Mon Dec  2 00:43:07 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 09:43:07 +0100
Subject: [PATCH 1/3] dt-bindings: arm: apple: Add T2 devices
In-Reply-To: <20241201161942.36027-2-towinchenmi@gmail.com>
References: <20241201161942.36027-1-towinchenmi@gmail.com>
 <20241201161942.36027-2-towinchenmi@gmail.com>
Message-ID: <5ap2q5ok2jsqvft3puha6n4wmdc6tjtr5r52qdvblpiqz6t5ak@oas4a3vdikox>

On Mon, Dec 02, 2024 at 12:18:41AM +0800, Nick Chan wrote:
> This adds the following apple,t8012 based platforms:


"Add"
Please do not use "This commit/patch/change", but imperative mood. See
longer explanation here:
https://elixir.bootlin.com/linux/v5.17.1/source/Documentation/process/submitting-patches.rst#L95


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

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec  2 00:43:44 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 09:43:44 +0100
Subject: [PATCH 1/2] dt-bindings: sram: sunxi-sram: Add A100 compatible
In-Reply-To: <20241202-a100-syscon-v1-1-86c6524f24d7@epochal.quest>
References: <20241202-a100-syscon-v1-0-86c6524f24d7@epochal.quest>
 <20241202-a100-syscon-v1-1-86c6524f24d7@epochal.quest>
Message-ID: <xos2khgdmnt6iinglnuuat6ak7bxzrufw775stmoy72igul7b7@5oqu374t2764>

On Mon, Dec 02, 2024 at 12:43:26AM -0400, Cody Eksal wrote:
> The Allwinner A100 has a system configuration block similar to that of
> the A64 and H6. Add a compatible for it.
> 
> Signed-off-by: Cody Eksal <masterr3c0rd at epochal.quest>
> ---

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

Best regards,
Krzysztof



From wiagn233 at outlook.com  Mon Dec  2 00:49:22 2024
From: wiagn233 at outlook.com (Qu Shengyu)
Date: Mon, 2 Dec 2024 08:49:22 +0000
Subject: [PATCH v6] wifi: mt76: mt7915: add wds support when wed is
 enabled
In-Reply-To: <TYCPR01MB843742DF3BB41BAC3B97C3C998982@TYCPR01MB8437.jpnprd01.prod.outlook.com>
References: <TY3P286MB26111E4DB0841A176DF8E44E98BE2@TY3P286MB2611.JPNP286.PROD.OUTLOOK.COM>
 <49a385d0-9ffc-468f-b7de-83abfa1e18f0@nbd.name>
 <TYCPR01MB843742DF3BB41BAC3B97C3C998982@TYCPR01MB8437.jpnprd01.prod.outlook.com>
Message-ID: <TYCPR01MB8437833F5213A2AEBF808FE098352@TYCPR01MB8437.jpnprd01.prod.outlook.com>

Hello Felix,

Sorry to bother but any updates on this? I remember that you?ve agreed to take over this patch on IRC.

Best regards,
Shengyu

> ? 2024?9?9??00:27?Shengyu Qu <wiagn233 at outlook.com> ???
> 
> ?
>> 
>>> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>>> index 049223df9beb1..dc4d87e004a0f 100644
>>> --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>>> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>>> @@ -745,8 +745,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
>>>       bool ext_phy = mvif->phy != &dev->phy;
>>>       int ret, idx;
>>>       u32 addr;
>>> +    u8 flags = MT76_WED_DEFAULT;
>>> -    idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
>>> +    if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
>>> +        !is_mt7915(&dev->mt76)) {
>>> +        flags = test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ?
>>> +               MT76_WED_WDS_ACTIVE : MT76_WED_ACTIVE;
>>> +    }
>>> +
>>> +    idx = __mt76_wcid_alloc(mdev->wcid_mask, MT7915_WTBL_STA, flags);
>>>       if (idx < 0)
>>>           return -ENOSPC;
>> I'd prefer to replace the mt76_wcid_alloc flags argument with an explicit start offset argument.
> 
> Hi Felix,
> 
> I'm not really familiar with mt76 code, just a enthusiast that wants to
> make WDS+WED working. So I'm not sure how to do this correctly... Maybe
> it's better for you to take over this patch, sorry.
> 
>>> @@ -1201,12 +1208,27 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
>>>   {
>>>       struct mt7915_dev *dev = mt7915_hw_dev(hw);
>>>       struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
>>> +    int min = MT76_WED_WDS_MIN, max = MT76_WED_WDS_MAX;
>>>       if (enabled)
>>>           set_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
>>>       else
>>>           clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
>>> +    if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
>>> +        !is_mt7915(&dev->mt76) &&
>>> +        (msta->wcid.idx < min || msta->wcid.idx > max - 1)) {
>>> +        struct ieee80211_sta *pre_sta;
>>> +
>>> +        pre_sta = kzalloc(sizeof(*sta) + sizeof(*msta), GFP_KERNEL);
>>> +        mt76_sta_pre_rcu_remove(hw, vif, sta);
>>> +        memmove(pre_sta, sta, sizeof(*sta) + sizeof(*msta));
>>> +        mt7915_sta_add(hw, vif, sta);
>>> +        synchronize_rcu();
>>> +        mt7915_sta_remove(hw, vif, pre_sta);
>>> +        kfree(pre_sta);
>>> +    }
>>> +
>>>       mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
>>>   }
>>> 
>> In order to update the code based on my latest changes and to fix potential race conditions on tx/rx packets during the transition, please change to this order:
>> 1. copy the sta
>> 2. allocate a new wcid
>> 3. change the wcid index in the copied sta to the newly allocated wcid
>> 4. call mcu functions on the duplicate sta for creating the new sta entry.
>> 5. use rcu_assign_pointer to point dev->wcid[new_idx] at &msta->wcid
>> 6. swap wcid index between real sta and duplicated sta
>> 7. rcu_assign_pointer(dev->wcid[orig_idx], NULL)
>> 8. synchronize_rcu()
>> 9. call mcu functions to delete the duplicate sta's entry (points to old wcid after the swap)
>> 10. free the duplicated sta
> 
> Now, the mt7915_sta_set_4addr function looks like this(__mt76_wcid_alloc
> not modified), do you think it's acceptable?
> 
> static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
>                 struct ieee80211_vif *vif,
>                 struct ieee80211_sta *sta,
>                 bool enabled)
> {
>    struct mt7915_dev *dev = mt7915_hw_dev(hw);
>    struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
>    int min = MT76_WED_WDS_MIN, max = MT76_WED_WDS_MAX;
>    struct ieee80211_sta *pre_sta;
>    u8 flags = MT76_WED_DEFAULT;
>    int temp_idx;
> 
>    if (enabled)
>        set_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
>    else
>        clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
> 
>    if (!msta->wcid.sta)
>        return;
> 
>    if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
>        !is_mt7915(&dev->mt76) &&
>        (msta->wcid.idx < min || msta->wcid.idx > max - 1)) {
>        pre_sta = kzalloc(sizeof(*sta) + sizeof(*msta), GFP_KERNEL);
>        memmove(pre_sta, sta, sizeof(*sta) + sizeof(*msta));
>        if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
>            !is_mt7915(&dev->mt76)) {
>            flags = test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ?
>                MT76_WED_WDS_ACTIVE : MT76_WED_ACTIVE;
>        }
> 
>        temp_idx = __mt76_wcid_alloc(mdev->wcid_mask, MT7915_WTBL_STA, flags);
>        ((struct mt7915_sta *)pre_sta->drv_priv)->wcid.idx = temp_idx;
>        mt7915_sta_add(hw, vif, pre_sta);
>        rcu_assign_pointer(dev->mt76.wcid[temp_idx], &msta->wcid);
>        temp_idx = msta->wcid.idx;
>        msta->wcid.idx = ((struct mt7915_sta *)pre_sta->drv_priv)->wcid.idx;
>        ((struct mt7915_sta *)pre_sta->drv_priv)->wcid.idx = temp_idx;
>        rcu_assign_pointer(dev->mt76.wcid[temp_idx], NULL);
>        synchronize_rcu();
>        mt7915_sta_remove(hw, vif, pre_sta);
>        kfree(pre_sta);
>    }
> 
>    mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
> }
> 
> Best regards,
> Shengyu
> 
>> This should allow mgmt tx/rx to work while the sta is being migrated to the new wcid entry.
>> - Felix
> <OpenPGP_0xE3520CC91929C8E7.asc>

From steven.price at arm.com  Mon Dec  2 00:54:11 2024
From: steven.price at arm.com (Steven Price)
Date: Mon, 2 Dec 2024 08:54:11 +0000
Subject: [PATCH v5 00/43] arm64: Support for Arm CCA in KVM
In-Reply-To: <Z01BYOgsLXV5yULk@vm3>
References: <20241004152804.72508-1-steven.price@arm.com>
 <Z01BYOgsLXV5yULk@vm3>
Message-ID: <01205247-ffcd-439f-b00f-d8e70720d049@arm.com>

Hi Itaru,

On 02/12/2024 05:10, Itaru Kitayama wrote:
> On Fri, Oct 04, 2024 at 04:27:21PM +0100, Steven Price wrote:
>> This series adds support for running protected VMs using KVM under the
>> Arm Confidential Compute Architecture (CCA).
...
> 
> On FVP, the v5+v7 kernel is unable to execute virt-manager:
> 
> Starting install...
> Allocating 'test9.qcow2'                                    |    0 B  00:00 ...
> Removing disk 'test9.qcow2'                                 |    0 B  00:00
> ERROR    internal error: process exited while connecting to monitor: 2024-12-04T18:56:11.646168Z qemu-system-aarch64: -accel kvm: ioctl(KVM_CREATE_VM) failed: Invalid argument
> 2024-12-04T18:56:11.646520Z qemu-system-aarch64: -accel kvm: failed to initialize kvm: Invalid argument
> Domain installation does not appear to have been successful.

Can you check that the kernel has detected the RMM being available, you
should have a message like below when the host kernel is booting:

kvm [1]: RMI ABI version 1.0

My guess is that you've got mismatched versions of the RMM and TF-A. The
interface between those two components isn't stable and there were
breaking changes fairly recently. And obviously if the RMM hasn't
initialised successfully then confidential VMs won't be available.

> Below is my virt-manager options:
> 
> virt-install --machine=virt --arch=aarch64 --name=test9 --memory=2048 --vcpu=1 --nographic --check all=off --features acpi=off --virt-type kvm --boot kernel=Image-cca,initrd=rootfs.cpio,kernel_args='earlycon console=ttyAMA0 rdinit=/sbin/init rw root=/dev/vda acpi=off' --qemu-commandline='-M virt,confidential-guest-support=rme0,gic-version=3 -cpu host -object rme-guest,id=rme0 -nodefaults' --disk size=4 --import --osinfo detect=on,require=off
> 
> Userland is Ubuntu 24.10, the VMM is Linaro's cca/2024-11-20:
> 
> https://git.codelinaro.org/linaro/dcap/qemu/-/tree/cca/2024-11-20?ref_type=heads

I don't think this is the latest QEMU tree, Jean-Philippe posted an
update last week:

https://lore.kernel.org/qemu-devel/20241125195626.856992-2-jean-philippe at linaro.org/

I'm not sure if there were any important updates there, but there are
detailed instructions that might help.

Regards,
Steve



From ot_chhao.chang at mediatek.com  Mon Dec  2 00:50:19 2024
From: ot_chhao.chang at mediatek.com (chang hao)
Date: Mon, 2 Dec 2024 16:50:19 +0800
Subject: [PATCH] pinctrl: mediatek: add eint new design for mt8196
Message-ID: <20241202085024.25375-1-ot_chhao.chang@mediatek.com>

From: Chhao Chang <ot_chhao.chang at mediatek.com>

Change 1: change EINT from 1 address to 5 addresses,
Eint number is stored on each base.
Change 2: Compatible with 1 address design

Signed-off-by: Chhao Chang <ot_chhao.chang at mediatek.com>
---
 drivers/pinctrl/mediatek/mtk-eint.c           | 976 ++++++++++++++----
 drivers/pinctrl/mediatek/mtk-eint.h           |  87 +-
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  |  50 +-
 3 files changed, 877 insertions(+), 236 deletions(-)

diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
index 27f0a54e12bf..2d13e36017ae 100644
--- a/drivers/pinctrl/mediatek/mtk-eint.c
+++ b/drivers/pinctrl/mediatek/mtk-eint.c
@@ -1,21 +1,24 @@
 // SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2014-2018 MediaTek Inc.
-
+// Copyright (c) 2014-2024 MediaTek Inc.
 /*
  * Library for MediaTek External Interrupt Support
  *
  * Author: Maoguang Meng <maoguang.meng at mediatek.com>
- *	   Sean Wang <sean.wang at mediatek.com>
- *
+ * Sean Wang <sean.wang at mediatek.com>
+ * Chhao Chang <ot_chhao.chang at mediatek.com>
  */
 
+#include <linux/atomic.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
 #include <linux/io.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
 
@@ -23,10 +26,14 @@
 
 #define MTK_EINT_EDGE_SENSITIVE           0
 #define MTK_EINT_LEVEL_SENSITIVE          1
-#define MTK_EINT_DBNC_SET_DBNC_BITS	  4
-#define MTK_EINT_DBNC_MAX		  16
-#define MTK_EINT_DBNC_RST_BIT		  (0x1 << 1)
-#define MTK_EINT_DBNC_SET_EN		  (0x1 << 0)
+#define MTK_EINT_DBNC_SET_DBNC_BITS       4
+#define MTK_EINT_DBNC_MAX                 16
+#define MTK_EINT_DBNC_RST_BIT             (0x1 << 1)
+#define MTK_EINT_DBNC_SET_EN              (0x1 << 0)
+
+#define MTK_EINT_NO_OFFSET                0
+
+static struct mtk_eint *global_eintc;
 
 static const struct mtk_eint_regs mtk_generic_eint_regs = {
 	.stat      = 0x000,
@@ -47,6 +54,10 @@ static const struct mtk_eint_regs mtk_generic_eint_regs = {
 	.dbnc_ctrl = 0x500,
 	.dbnc_set  = 0x600,
 	.dbnc_clr  = 0x700,
+	.event     = 0x800,
+	.event_set = 0x840,
+	.event_clr = 0x880,
+	.raw_stat  = 0xa00,
 };
 
 const unsigned int debounce_time_mt2701[] = {
@@ -64,60 +75,122 @@ const unsigned int debounce_time_mt6795[] = {
 };
 EXPORT_SYMBOL_GPL(debounce_time_mt6795);
 
+/*
+ * Return the iomem of specific register offset and decode the coordinate
+ * (instance, index) from global eint number.
+ * If return NULL, then it must be either out-of-range or do-not-support.
+ */
 static void __iomem *mtk_eint_get_offset(struct mtk_eint *eint,
 					 unsigned int eint_num,
-					 unsigned int offset)
+					 unsigned int offset,
+					 unsigned int *instance,
+					 unsigned int *index)
 {
-	unsigned int eint_base = 0;
 	void __iomem *reg;
 
-	if (eint_num >= eint->hw->ap_num)
-		eint_base = eint->hw->ap_num;
+	if (eint_num >= eint->total_pin_number ||
+	    !eint->pins[eint_num].enabled) {
+		WARN_ON(1);
+		return NULL;
+	}
 
-	reg = eint->base + offset + ((eint_num - eint_base) / 32) * 4;
+	*instance = eint->pins[eint_num].instance;
+	*index = eint->pins[eint_num].index;
+	reg = eint->instances[*instance].base + offset + (*index / 32 * 4);
 
 	return reg;
 }
 
+/*
+ * Generate helper function to access property register of a dedicate pin.
+ */
+#define DEFINE_EINT_GET_FUNCTION(_NAME, _OFFSET) \
+static unsigned int mtk_eint_get_##_NAME(struct mtk_eint *eint, \
+				   unsigned int eint_num) \
+{ \
+	unsigned int instance, index; \
+	void __iomem *reg = mtk_eint_get_offset(eint, eint_num, \
+						_OFFSET, \
+						&instance, &index); \
+	unsigned int bit = BIT(index & 0x1f);\
+\
+	if (!reg) { \
+		dev_err(eint->dev, "%s invalid eint_num %d\n", \
+			__func__, eint_num); \
+		return 0;\
+	} \
+\
+	return !!(readl(reg) & bit); \
+}
+
+DEFINE_EINT_GET_FUNCTION(stat, eint->comp->regs->stat);
+DEFINE_EINT_GET_FUNCTION(mask, eint->comp->regs->mask);
+DEFINE_EINT_GET_FUNCTION(sens, eint->comp->regs->sens);
+DEFINE_EINT_GET_FUNCTION(pol, eint->comp->regs->pol);
+DEFINE_EINT_GET_FUNCTION(soft, eint->comp->regs->soft);
+DEFINE_EINT_GET_FUNCTION(raw_stat, eint->comp->regs->raw_stat);
+
 static unsigned int mtk_eint_can_en_debounce(struct mtk_eint *eint,
 					     unsigned int eint_num)
 {
 	unsigned int sens;
-	unsigned int bit = BIT(eint_num % 32);
+	unsigned int instance, index;
 	void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
-						eint->regs->sens);
+						eint->comp->regs->sens,
+						&instance, &index);
+	unsigned int bit = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return 0;
+	}
 
 	if (readl(reg) & bit)
 		sens = MTK_EINT_LEVEL_SENSITIVE;
 	else
 		sens = MTK_EINT_EDGE_SENSITIVE;
 
-	if (eint_num < eint->hw->db_cnt && sens != MTK_EINT_EDGE_SENSITIVE)
+	if (eint->pins[eint_num].debounce &&
+	    sens != MTK_EINT_EDGE_SENSITIVE)
 		return 1;
 	else
 		return 0;
 }
 
-static int mtk_eint_flip_edge(struct mtk_eint *eint, int hwirq)
+static int mtk_eint_flip_edge(struct mtk_eint *eint, int eint_num)
 {
 	int start_level, curr_level;
 	unsigned int reg_offset;
-	u32 mask = BIT(hwirq & 0x1f);
-	u32 port = (hwirq >> 5) & eint->hw->port_mask;
-	void __iomem *reg = eint->base + (port << 2);
+	unsigned int instance, index, mask, port;
+	void __iomem *reg;
 
-	curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl, hwirq);
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return 0;
+	}
+
+	mask = BIT(index & 0x1f);
+	port = index >> 5;
+	reg = eint->instances[instance].base + port * 4;
+
+	curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl, eint_num);
 
 	do {
 		start_level = curr_level;
 		if (start_level)
-			reg_offset = eint->regs->pol_clr;
+			reg_offset = eint->comp->regs->pol_clr;
 		else
-			reg_offset = eint->regs->pol_set;
+			reg_offset = eint->comp->regs->pol_set;
+
 		writel(mask, reg + reg_offset);
 
 		curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl,
-							      hwirq);
+							      eint_num);
 	} while (start_level != curr_level);
 
 	return start_level;
@@ -126,11 +199,19 @@ static int mtk_eint_flip_edge(struct mtk_eint *eint, int hwirq)
 static void mtk_eint_mask(struct irq_data *d)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	u32 mask = BIT(d->hwirq & 0x1f);
+	unsigned int instance, index;
 	void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
-						eint->regs->mask_set);
+						eint->comp->regs->mask_set,
+						&instance, &index);
+	u32 mask = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, d->hwirq);
+		return;
+	}
 
-	eint->cur_mask[d->hwirq >> 5] &= ~mask;
+	eint->instances[instance].cur_mask[index >> 5] &= ~mask;
 
 	writel(mask, reg);
 }
@@ -138,43 +219,123 @@ static void mtk_eint_mask(struct irq_data *d)
 static void mtk_eint_unmask(struct irq_data *d)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	u32 mask = BIT(d->hwirq & 0x1f);
+	unsigned int instance, index;
 	void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
-						eint->regs->mask_clr);
+						eint->comp->regs->mask_clr,
+						&instance, &index);
+	u32 mask = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, d->hwirq);
+		return;
+	}
 
-	eint->cur_mask[d->hwirq >> 5] |= mask;
+	eint->instances[instance].cur_mask[index >> 5] |= mask;
 
 	writel(mask, reg);
 
-	if (eint->dual_edge[d->hwirq])
+	if (eint->pins[d->hwirq].dual_edge)
 		mtk_eint_flip_edge(eint, d->hwirq);
 }
 
-static unsigned int mtk_eint_get_mask(struct mtk_eint *eint,
-				      unsigned int eint_num)
+/*
+ * We need to do extra effort to clear edge-triggered EINT
+ * which located in eint_c due to hw design limitation.
+ */
+void mt6983_eint_ack(struct irq_data *d)
 {
-	unsigned int bit = BIT(eint_num % 32);
-	void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
-						eint->regs->mask);
+	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+	unsigned int instance, index;
+	void __iomem *sens_reg;
+	void __iomem *ack_reg = mtk_eint_get_offset(eint, d->hwirq,
+						eint->comp->regs->sens,
+						&instance, &index);
+	unsigned int bit = BIT(index & 0x1f);
+
+	if (!ack_reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, d->hwirq);
+		return;
+	}
 
-	return !!(readl(reg) & bit);
+	if (instance == 4) {
+		sens_reg = mtk_eint_get_offset(eint, d->hwirq,
+					       eint->comp->regs->sens_clr,
+					       &instance, &index);
+		writel(bit, sens_reg);
+		sens_reg = mtk_eint_get_offset(eint, d->hwirq,
+					       eint->comp->regs->sens_set,
+					       &instance, &index);
+		writel(bit, sens_reg);
+	} else {
+		writel(bit, ack_reg);
+	}
 }
 
 static void mtk_eint_ack(struct irq_data *d)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	u32 mask = BIT(d->hwirq & 0x1f);
-	void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
-						eint->regs->ack);
+	unsigned int instance, index;
+	void __iomem *reg;
+	unsigned int bit;
 
-	writel(mask, reg);
+	if (eint->comp->ops.ack) {
+		eint->comp->ops.ack(d);
+	} else {
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->ack,
+					  &instance, &index);
+		bit = BIT(index & 0x1f);
+		if (!reg) {
+			dev_err(eint->dev, "%s invalid eint_num %lu\n",
+				__func__, d->hwirq);
+			return;
+		}
+
+		writel(bit, reg);
+	}
+}
+
+static void mtk_eint_soft_set(struct mtk_eint *eint, unsigned int eint_num)
+{
+	unsigned int instance, index;
+	void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
+						eint->comp->regs->soft_set,
+						&instance, &index);
+	unsigned int bit = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return;
+	}
+
+	writel(bit, reg);
+}
+
+static void mtk_eint_soft_clr(struct mtk_eint *eint, unsigned int eint_num)
+{
+	unsigned int instance, index;
+	void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
+						eint->comp->regs->soft_clr,
+						&instance, &index);
+	unsigned int bit = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return;
+	}
+
+	writel(bit, reg);
 }
 
 static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	bool masked;
-	u32 mask = BIT(d->hwirq & 0x1f);
+	u32 mask;
+	unsigned int instance, index;
 	void __iomem *reg;
 
 	if (((type & IRQ_TYPE_EDGE_BOTH) && (type & IRQ_TYPE_LEVEL_MASK)) ||
@@ -186,36 +347,42 @@ static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
 	}
 
 	if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
-		eint->dual_edge[d->hwirq] = 1;
+		eint->pins[d->hwirq].dual_edge = 1;
 	else
-		eint->dual_edge[d->hwirq] = 0;
+		eint->pins[d->hwirq].dual_edge = 0;
 
-	if (!mtk_eint_get_mask(eint, d->hwirq)) {
-		mtk_eint_mask(d);
-		masked = false;
-	} else {
-		masked = true;
-	}
+	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->pol_clr,
+					  &instance, &index);
+	else
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->pol_set,
+					  &instance, &index);
 
-	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) {
-		reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_clr);
-		writel(mask, reg);
-	} else {
-		reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_set);
-		writel(mask, reg);
-	}
+	mask = BIT(index & 0x1f);
+	writel(mask, reg);
 
-	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
-		reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_clr);
-		writel(mask, reg);
-	} else {
-		reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_set);
-		writel(mask, reg);
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->sens_clr,
+					  &instance, &index);
+	else
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->sens_set,
+					  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, d->hwirq);
+		return 0;
 	}
 
-	mtk_eint_ack(d);
-	if (!masked)
-		mtk_eint_unmask(d);
+	mask = BIT(index & 0x1f);
+	writel(mask, reg);
+
+	if (eint->pins[d->hwirq].dual_edge)
+		mtk_eint_flip_edge(eint, d->hwirq);
 
 	return 0;
 }
@@ -223,30 +390,28 @@ static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
 static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	int shift = d->hwirq & 0x1f;
-	int reg = d->hwirq >> 5;
+	unsigned int instance, index, shift, port;
+	void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
+						MTK_EINT_NO_OFFSET,
+						&instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, d->hwirq);
+		return 0;
+	}
+
+	shift = index & 0x1f;
+	port = index >> 5;
 
 	if (on)
-		eint->wake_mask[reg] |= BIT(shift);
+		eint->instances[instance].wake_mask[port] |= BIT(shift);
 	else
-		eint->wake_mask[reg] &= ~BIT(shift);
+		eint->instances[instance].wake_mask[port] &= ~BIT(shift);
 
 	return 0;
 }
 
-static void mtk_eint_chip_write_mask(const struct mtk_eint *eint,
-				     void __iomem *base, u32 *buf)
-{
-	int port;
-	void __iomem *reg;
-
-	for (port = 0; port < eint->hw->ports; port++) {
-		reg = base + (port << 2);
-		writel_relaxed(~buf[port], reg + eint->regs->mask_set);
-		writel_relaxed(buf[port], reg + eint->regs->mask_clr);
-	}
-}
-
 static int mtk_eint_irq_request_resources(struct irq_data *d)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
@@ -258,23 +423,25 @@ static int mtk_eint_irq_request_resources(struct irq_data *d)
 					   &gpio_n, &gpio_c);
 	if (err < 0) {
 		dev_err(eint->dev, "Can not find pin\n");
-		return err;
+		goto err_out;
 	}
 
 	err = gpiochip_lock_as_irq(gpio_c, gpio_n);
 	if (err < 0) {
 		dev_err(eint->dev, "unable to lock HW IRQ %lu for IRQ\n",
 			irqd_to_hwirq(d));
-		return err;
+		goto err_out;
 	}
 
 	err = eint->gpio_xlate->set_gpio_as_eint(eint->pctl, d->hwirq);
 	if (err < 0) {
 		dev_err(eint->dev, "Can not eint mode\n");
-		return err;
+		goto err_out;
 	}
 
 	return 0;
+err_out:
+	return err;
 }
 
 static void mtk_eint_irq_release_resources(struct irq_data *d)
@@ -290,7 +457,7 @@ static void mtk_eint_irq_release_resources(struct irq_data *d)
 }
 
 static struct irq_chip mtk_eint_irq_chip = {
-	.name = "mt-eint",
+	.name = "mtk-eint",
 	.irq_disable = mtk_eint_mask,
 	.irq_mask = mtk_eint_mask,
 	.irq_unmask = mtk_eint_unmask,
@@ -301,35 +468,53 @@ static struct irq_chip mtk_eint_irq_chip = {
 	.irq_release_resources = mtk_eint_irq_release_resources,
 };
 
+/*
+ * Configure all EINT pins as domain 0, which only belongs to AP.
+ */
 static unsigned int mtk_eint_hw_init(struct mtk_eint *eint)
 {
-	void __iomem *dom_en = eint->base + eint->regs->dom_en;
-	void __iomem *mask_set = eint->base + eint->regs->mask_set;
-	unsigned int i;
-
-	for (i = 0; i < eint->hw->ap_num; i += 32) {
-		writel(0xffffffff, dom_en);
-		writel(0xffffffff, mask_set);
-		dom_en += 4;
-		mask_set += 4;
+	void __iomem *dom, *eevt;
+	unsigned int i, j;
+
+	for (i = 0; i < eint->instance_number; i++) {
+		dom = eint->instances[i].base + eint->comp->regs->dom_en;
+		eevt = eint->instances[i].base + eint->comp->regs->event_clr;
+		for (j = 0; j < eint->instances[i].number; j += 32) {
+			writel(0xffffffff, dom);
+			writel(0xffffffff, eevt);
+			dom += 4;
+			eevt += 4;
+		}
 	}
 
 	return 0;
 }
 
 static inline void
-mtk_eint_debounce_process(struct mtk_eint *eint, int index)
+mtk_eint_debounce_process(struct mtk_eint *eint, int eint_num)
 {
 	unsigned int rst, ctrl_offset;
 	unsigned int bit, dbnc;
+	unsigned int instance, index;
+	void __iomem *reg;
 
-	ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_ctrl;
-	dbnc = readl(eint->base + ctrl_offset);
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return;
+	}
+
+	ctrl_offset = (index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
+	dbnc = readl(eint->instances[instance].base + ctrl_offset);
 	bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
+
 	if ((bit & dbnc) > 0) {
-		ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_set;
+		ctrl_offset = (index / 4) * 4 + eint->comp->regs->dbnc_set;
 		rst = MTK_EINT_DBNC_RST_BIT << ((index % 4) * 8);
-		writel(rst, eint->base + ctrl_offset);
+		writel(rst, eint->instances[instance].base + ctrl_offset);
 	}
 }
 
@@ -337,65 +522,66 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct mtk_eint *eint = irq_desc_get_handler_data(desc);
-	unsigned int status, eint_num;
-	int offset, mask_offset, index;
-	void __iomem *reg =  mtk_eint_get_offset(eint, 0, eint->regs->stat);
-	int dual_edge, start_level, curr_level;
+	unsigned int status, i, j;
+	int shift, port, eint_num, virq;
+	unsigned int dual_edge, start_level, curr_level;
+	struct mtk_eint_instance eint_instance;
+	void __iomem *addr;
 
 	chained_irq_enter(chip, desc);
-	for (eint_num = 0; eint_num < eint->hw->ap_num; eint_num += 32,
-	     reg += 4) {
-		status = readl(reg);
-		while (status) {
-			offset = __ffs(status);
-			mask_offset = eint_num >> 5;
-			index = eint_num + offset;
-			status &= ~BIT(offset);
-
-			/*
-			 * If we get an interrupt on pin that was only required
-			 * for wake (but no real interrupt requested), mask the
-			 * interrupt (as would mtk_eint_resume do anyway later
-			 * in the resume sequence).
-			 */
-			if (eint->wake_mask[mask_offset] & BIT(offset) &&
-			    !(eint->cur_mask[mask_offset] & BIT(offset))) {
-				writel_relaxed(BIT(offset), reg -
-					eint->regs->stat +
-					eint->regs->mask_set);
-			}
 
-			dual_edge = eint->dual_edge[index];
-			if (dual_edge) {
-				/*
-				 * Clear soft-irq in case we raised it last
-				 * time.
-				 */
-				writel(BIT(offset), reg - eint->regs->stat +
-				       eint->regs->soft_clr);
+	for (i = 0; i < eint->instance_number; i++) {
+		eint_instance = eint->instances[i];
 
-				start_level =
-				eint->gpio_xlate->get_gpio_state(eint->pctl,
-								 index);
-			}
+		/* Iterate all pins by port */
+		for (j = 0; j < eint_instance.number; j += 32) {
+			port = j >> 5;
+			status = readl(eint_instance.base + port * 4 +
+				       eint->comp->regs->stat);
+			while (status) {
+				shift = __ffs(status);
+				status &= ~BIT(shift);
 
-			generic_handle_domain_irq(eint->domain, index);
-
-			if (dual_edge) {
-				curr_level = mtk_eint_flip_edge(eint, index);
+				eint_num = eint->instances[i].pin_list[shift + j];
+				virq = irq_find_mapping(eint->domain, eint_num);
 
 				/*
-				 * If level changed, we might lost one edge
-				 * interrupt, raised it through soft-irq.
+				 * If we get an interrupt on pin that was only required
+				 * for wake (but no real interrupt requested), mask the
+				 * interrupt (as would mtk_eint_resume do anyway later
+				 * in the resume sequence).
 				 */
-				if (start_level != curr_level)
-					writel(BIT(offset), reg -
-					       eint->regs->stat +
-					       eint->regs->soft_set);
+				if (eint->instances[i].wake_mask[port] & BIT(shift) &&
+				    !(eint->instances[i].cur_mask[port] & BIT(shift))) {
+					addr = eint_instance.base + port * 4 +
+						eint->comp->regs->mask_set;
+					writel_relaxed(BIT(shift), addr);
+				}
+
+				dual_edge = eint->pins[eint_num].dual_edge;
+				if (dual_edge)
+					start_level =
+					eint->gpio_xlate->get_gpio_state(eint->pctl,
+									 eint_num);
+
+				generic_handle_irq(virq);
+
+				if (dual_edge) {
+					curr_level = mtk_eint_flip_edge(eint, eint_num);
+
+					/*
+					 * If level changed, we might lost one edge
+					 * interrupt, raised it through soft-irq.
+					 */
+					if (start_level != curr_level)
+						mtk_eint_soft_set(eint, eint_num);
+
+					mtk_eint_soft_clr(eint, eint_num);
+				}
+
+				if (eint->pins[eint_num].debounce)
+					mtk_eint_debounce_process(eint, eint_num);
 			}
-
-			if (index < eint->hw->db_cnt)
-				mtk_eint_debounce_process(eint, index);
 		}
 	}
 	chained_irq_exit(chip, desc);
@@ -403,7 +589,20 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
 
 int mtk_eint_do_suspend(struct mtk_eint *eint)
 {
-	mtk_eint_chip_write_mask(eint, eint->base, eint->wake_mask);
+	unsigned int i, j, port;
+
+	for (i = 0; i < eint->instance_number; i++) {
+		struct mtk_eint_instance inst = eint->instances[i];
+
+		for (j = 0; j < inst.number; j += 32) {
+			port = j >> 5;
+			writel_relaxed(~inst.wake_mask[port],
+				       inst.base + port * 4 + eint->comp->regs->mask_set);
+			writel_relaxed(inst.wake_mask[port],
+				       inst.base + port * 4 + eint->comp->regs->mask_clr);
+		}
+	}
+	dsb(sy);
 
 	return 0;
 }
@@ -411,7 +610,20 @@ EXPORT_SYMBOL_GPL(mtk_eint_do_suspend);
 
 int mtk_eint_do_resume(struct mtk_eint *eint)
 {
-	mtk_eint_chip_write_mask(eint, eint->base, eint->cur_mask);
+	unsigned int i, j, port;
+
+	for (i = 0; i < eint->instance_number; i++) {
+		struct mtk_eint_instance inst = eint->instances[i];
+
+		for (j = 0; j < inst.number; j += 32) {
+			port = j >> 5;
+			writel_relaxed(~inst.cur_mask[port],
+				       inst.base + port * 4 + eint->comp->regs->mask_set);
+			writel_relaxed(inst.cur_mask[port],
+				       inst.base + port * 4 + eint->comp->regs->mask_clr);
+		}
+	}
+	dsb(sy);
 
 	return 0;
 }
@@ -423,24 +635,42 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
 	int virq, eint_offset;
 	unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask,
 		     dbnc;
+	static const unsigned int debounce_time[] = { 156, 313, 625, 1250,
+		20000, 40000, 80000, 160000, 320000, 640000 };
 	struct irq_data *d;
+	unsigned int instance, index;
+	void __iomem *reg;
 
-	if (!eint->hw->db_time)
-		return -EOPNOTSUPP;
+	/*
+	 * Due to different number of bit field, we only decode
+	 * the coordinate here, instead of get the VA.
+	 */
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, eint_num);
+		return 0;
+	}
 
 	virq = irq_find_mapping(eint->domain, eint_num);
-	eint_offset = (eint_num % 4) * 8;
+	eint_offset = (index % 4) * 8;
 	d = irq_get_irq_data(virq);
 
-	set_offset = (eint_num / 4) * 4 + eint->regs->dbnc_set;
-	clr_offset = (eint_num / 4) * 4 + eint->regs->dbnc_clr;
+	reg = eint->instances[instance].base;
+	set_offset = (index / 4) * 4 + eint->comp->regs->dbnc_set;
+	clr_offset = (index / 4) * 4 + eint->comp->regs->dbnc_clr;
 
 	if (!mtk_eint_can_en_debounce(eint, eint_num))
 		return -EINVAL;
 
-	dbnc = eint->num_db_time;
-	for (i = 0; i < eint->num_db_time; i++) {
-		if (debounce <= eint->hw->db_time[i]) {
+	/*
+	 * Check eint number to avoid access out-of-range
+	 */
+	dbnc = ARRAY_SIZE(debounce_time) - 1;
+	for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
+		if (debounce <= debounce_time[i]) {
 			dbnc = i;
 			break;
 		}
@@ -454,18 +684,16 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
 	}
 
 	clr_bit = 0xff << eint_offset;
-	writel(clr_bit, eint->base + clr_offset);
+	writel(clr_bit, reg + clr_offset);
 
-	bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS) | MTK_EINT_DBNC_SET_EN) <<
-		eint_offset;
+	bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS)
+		| MTK_EINT_DBNC_SET_EN) << eint_offset;
 	rst = MTK_EINT_DBNC_RST_BIT << eint_offset;
-	writel(rst | bit, eint->base + set_offset);
+	writel(rst | bit, reg + set_offset);
+
+	/* Delay should be (8T @ 32k) from dbc rst to work correctly. */
+	udelay(250);
 
-	/*
-	 * Delay a while (more than 2T) to wait for hw debounce counter reset
-	 * work correctly.
-	 */
-	udelay(1);
 	if (unmask == 1)
 		mtk_eint_unmask(d);
 
@@ -473,6 +701,53 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
 }
 EXPORT_SYMBOL_GPL(mtk_eint_set_debounce);
 
+unsigned int mtk_eint_get_debounce_en(struct mtk_eint *eint,
+				      unsigned int eint_num)
+{
+	unsigned int instance, index, bit;
+	void __iomem *reg;
+
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return 0;
+	}
+
+	reg = eint->instances[instance].base +
+		(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
+
+	bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
+
+	return (readl(reg) & bit) ? 1 : 0;
+}
+
+unsigned int mtk_eint_get_debounce_value(struct mtk_eint *eint,
+					 unsigned int eint_num)
+{
+	unsigned int instance, index, mask, offset;
+	void __iomem *reg;
+
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return 0;
+	}
+
+	reg = eint->instances[instance].base +
+		(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
+
+	offset = MTK_EINT_DBNC_SET_DBNC_BITS + ((index % 4) * 8);
+	mask = 0xf << offset;
+
+	return ((readl(reg) & mask) >> offset);
+}
+
 int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
 {
 	int irq;
@@ -485,44 +760,348 @@ int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
 }
 EXPORT_SYMBOL_GPL(mtk_eint_find_irq);
 
+/*
+ * Dump the properties/states of the specific EINT pin.
+ * @eint_num: the global EINT number.
+ * @buf: the pointer of a string buffer.
+ * @buf_size: the size of the buffer.
+ *
+ * If the return value < 0, it means that the @eint_num is invalid;
+ * Otherwise, return 0;
+ */
+int dump_eint_pin_status(unsigned int eint_num, char *buf, unsigned int buf_size)
+{
+	unsigned int len = 0, enabled, stat, raw_stat, soft, mask, sens, pol,
+		     deb_en, deb_val;
+
+	if (eint_num < 0 || eint_num >= global_eintc->total_pin_number)
+		return -ENODEV;
+
+	enabled = global_eintc->pins[eint_num].enabled;
+	stat = mtk_eint_get_stat(global_eintc, eint_num);
+	raw_stat = mtk_eint_get_raw_stat(global_eintc, eint_num);
+	soft = mtk_eint_get_soft(global_eintc, eint_num);
+	mask = mtk_eint_get_mask(global_eintc, eint_num);
+	sens = mtk_eint_get_sens(global_eintc, eint_num);
+	pol = mtk_eint_get_pol(global_eintc, eint_num);
+
+	len += snprintf(buf + len, buf_size - len,
+			"%s=%u(%s)\n%s=%s_%s\n%s=%u\n%s=%u\n%s=%u\n%s=%u\n",
+			"Pin", eint_num, enabled ? "enabled" : "disabled",
+			"Type", (sens == 1) ? "level" : "edge",
+			(pol == 1) ? "high" : "low",
+			"Pending", stat,
+			"Raw", raw_stat,
+			"Soft", soft,
+			"Mask", mask);
+
+	if (mtk_eint_can_en_debounce(global_eintc, eint_num)) {
+		deb_en	= mtk_eint_get_debounce_en(global_eintc, eint_num);
+		deb_val = mtk_eint_get_debounce_value(global_eintc, eint_num);
+
+		len += snprintf(buf + len, buf_size - len,
+				"Support debounce, %s=%u, %s=%u\n",
+				"enable", deb_en,
+				"setting", deb_val);
+	} else {
+		len += snprintf(buf + len, buf_size - len,
+				"Not support debounce\n");
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dump_eint_pin_status);
+
+static ssize_t eintc_status_show(struct device_driver *driver, char *buf)
+{
+	struct mtk_eint *eint = global_eintc;
+	unsigned int i, j, len = 0,
+		     instance_num = eint->instance_number;
+
+	len += snprintf(buf + len, PAGE_SIZE - len, "=====EINTC Dump=====\n");
+
+	for (i = 0; i < instance_num; i++) {
+		struct mtk_eint_instance inst = eint->instances[i];
+
+		len += snprintf(buf + len, PAGE_SIZE - len,
+				"Instance %d name=%s with %u pins\n",
+				i, inst.name, inst.number);
+
+		for (j = 0; j < inst.number; j++)
+			len += snprintf(buf + len, PAGE_SIZE - len,
+					"%d ", inst.pin_list[j]);
+
+		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+	}
+
+	return strlen(buf);
+}
+
+static DRIVER_ATTR_RO(eintc_status);
+
+static ssize_t eint_pin_status_show(struct device_driver *driver, char *buf)
+{
+	struct mtk_eint *eint = global_eintc;
+	unsigned int len = 0;
+
+	len += snprintf(buf + len, PAGE_SIZE - len,
+			"=====EINT Pin Dump=====\n");
+
+	dump_eint_pin_status(eint->dump_target_eint,
+			     buf + len, PAGE_SIZE - len);
+
+	return strlen(buf);
+}
+
+static ssize_t eint_pin_status_store(struct device_driver *driver,
+				     const char *buf, size_t count)
+{
+	int eint_num, ret;
+
+	ret = kstrtouint(buf, 10, &eint_num);
+
+	if (ret || eint_num >= global_eintc->total_pin_number) {
+		dev_err(global_eintc->dev,
+			"%s invalid input: %s.\n", __func__, buf);
+		goto err_out;
+	}
+
+	global_eintc->dump_target_eint = (unsigned int)eint_num;
+
+err_out:
+	return count;
+}
+
+static DRIVER_ATTR_RW(eint_pin_status);
+
+static const struct mtk_eint_compatible default_compat = {
+	.regs = &mtk_generic_eint_regs,
+};
+
 int mtk_eint_do_init(struct mtk_eint *eint)
 {
-	int i;
+	int i, virq;
+	unsigned int ret, size, inst = 0;
 
-	/* If clients don't assign a specific regs, let's use generic one */
-	if (!eint->regs)
-		eint->regs = &mtk_generic_eint_regs;
+	eint->instance_number = 1;
+	eint->total_pin_number = eint->hw->ap_num;
 
-	eint->wake_mask = devm_kcalloc(eint->dev, eint->hw->ports,
-				       sizeof(*eint->wake_mask), GFP_KERNEL);
-	if (!eint->wake_mask)
-		return -ENOMEM;
+	dev_info(eint->dev, "%s read ap_num: %u\n", __func__, eint->hw->ap_num);
 
-	eint->cur_mask = devm_kcalloc(eint->dev, eint->hw->ports,
-				      sizeof(*eint->cur_mask), GFP_KERNEL);
-	if (!eint->cur_mask)
+	size = eint->instance_number * sizeof(struct mtk_eint_instance);
+	eint->instances = devm_kzalloc(eint->dev, size, GFP_KERNEL);
+	if (!eint->instances)
 		return -ENOMEM;
 
-	eint->dual_edge = devm_kcalloc(eint->dev, eint->hw->ap_num,
-				       sizeof(int), GFP_KERNEL);
-	if (!eint->dual_edge)
+	size = eint->total_pin_number * sizeof(struct mtk_eint_pin);
+	eint->pins = devm_kzalloc(eint->dev, size, GFP_KERNEL);
+	if (!eint->pins)
 		return -ENOMEM;
 
+	for (i = 0; i < eint->total_pin_number; i++) {
+		eint->pins[i].enabled = true;
+		eint->pins[i].instance = inst;
+		eint->pins[i].index = i;
+		eint->pins[i].debounce =  (i < eint->hw->db_cnt) ? 1 : 0;
+
+		eint->instances[inst].pin_list[i] = i;
+		eint->instances[inst].number++;
+	}
+
+	for (i = 0; i < eint->instance_number; i++) {
+		size = (eint->instances[i].number / 32 + 1) * sizeof(unsigned int);
+		eint->instances[i].wake_mask =
+			devm_kzalloc(eint->dev, size, GFP_KERNEL);
+		eint->instances[i].cur_mask =
+			devm_kzalloc(eint->dev, size, GFP_KERNEL);
+
+		if (!eint->instances[i].wake_mask ||
+		    !eint->instances[i].cur_mask)
+			return -ENOMEM;
+	}
+
+	eint->comp = &default_compat;
+
 	eint->domain = irq_domain_add_linear(eint->dev->of_node,
-					     eint->hw->ap_num,
+					     eint->total_pin_number,
 					     &irq_domain_simple_ops, NULL);
 	if (!eint->domain)
 		return -ENOMEM;
 
-	if (eint->hw->db_time) {
-		for (i = 0; i < MTK_EINT_DBNC_MAX; i++)
-			if (eint->hw->db_time[i] == 0)
-				break;
-		eint->num_db_time = i;
+	eint->instances[inst].base = eint->base;
+
+	mtk_eint_hw_init(eint);
+
+	for (i = 0; i < eint->total_pin_number; i++) {
+		virq = irq_create_mapping(eint->domain, i);
+
+		irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
+					 handle_level_irq);
+		irq_set_chip_data(virq, eint);
+	}
+
+	irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler,
+					 eint);
+
+	ret = driver_create_file(eint->dev->driver,
+				 &driver_attr_eintc_status);
+
+	ret |= driver_create_file(eint->dev->driver,
+				  &driver_attr_eint_pin_status);
+
+	if (ret)
+		dev_err(eint->dev, "%s create sysfs files failed.\n", __func__);
+
+	global_eintc = eint;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mtk_eint_do_init);
+
+int mtk_eint_do_init_v2(struct mtk_eint *eint)
+{
+	int i, matrix_number = 0;
+	struct device_node *node;
+	unsigned int ret, size, offset;
+	unsigned int id, inst, idx, support_deb;
+
+	const phandle *ph;
+
+#if defined(MTK_EINT_DEBUG)
+	struct mtk_eint_pin pin;
+#endif
+
+	ph = of_get_property(eint->dev->of_node, "mediatek,eint", NULL);
+	if (!ph) {
+		dev_err(eint->dev, "Cannot find EINT phandle in PIO node.\n");
+		return -ENODEV;
+	}
+
+	node = of_find_node_by_phandle(be32_to_cpup(ph));
+	if (!node) {
+		dev_err(eint->dev, "Cannot find EINT node by phandle.\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(node, "mediatek,total-pin-number",
+				   &eint->total_pin_number);
+	if (ret) {
+		dev_err(eint->dev, "%s Get total pin Fail.\n", __func__);
+		return -EINVAL;
+	}
+
+	dev_info(eint->dev, "%s eint total pins:%u.\n",
+		 __func__, eint->total_pin_number);
+
+	ret = of_property_read_u32(node, "mediatek,instance-num",
+				   &eint->instance_number);
+	if (ret)
+		eint->instance_number = 1;
+
+	size = eint->instance_number * sizeof(struct mtk_eint_instance);
+	eint->instances = devm_kzalloc(eint->dev, size, GFP_KERNEL);
+	if (!eint->instances)
+		return -ENOMEM;
+
+	size = eint->total_pin_number * sizeof(struct mtk_eint_pin);
+	eint->pins = devm_kzalloc(eint->dev, size, GFP_KERNEL);
+	if (!eint->pins)
+		return -ENOMEM;
+
+	for (i = 0; i < eint->instance_number; i++) {
+		ret = of_property_read_string_index(node, "reg-name", i,
+						    &(eint->instances[i].name));
+		if (ret) {
+			dev_info(eint->dev,
+				 "%s cannot read the name of instance %d.\n",
+				 __func__, i);
+		}
+
+		eint->instances[i].base = of_iomap(node, i);
+		if (!eint->instances[i].base)
+			return -ENOMEM;
+	}
+
+	matrix_number = of_property_count_u32_elems(node, "mediatek,pins") / 4;
+	if (matrix_number < 0) {
+		matrix_number = eint->total_pin_number;
+		dev_info(eint->dev, "%s eint in legacy mode, matrix number is %u.\n",
+			 __func__, matrix_number);
+	} else {
+		dev_info(eint->dev, "%s eint in new mode, matrix number is %u.\n",
+			 __func__, matrix_number);
+	}
+
+	for (i = 0; i < matrix_number ; i++) {
+		offset = i * 4;
+
+		ret = of_property_read_u32_index(node, "mediatek,pins",
+						 offset, &id);
+		ret |= of_property_read_u32_index(node, "mediatek,pins",
+						  offset + 1, &inst);
+		ret |= of_property_read_u32_index(node, "mediatek,pins",
+						  offset + 2, &idx);
+		ret |= of_property_read_u32_index(node, "mediatek,pins",
+						  offset + 3, &support_deb);
+
+		/* Legacy chip which no need to give coordinate list */
+		if (ret) {
+			id = i;
+			inst = 0;
+			idx = i;
+			support_deb = (i < MTK_EINT_DBNC_MAX) ? 1 : 0;
+		}
+
+		eint->pins[id].enabled = true;
+		eint->pins[id].instance = inst;
+		eint->pins[id].index = idx;
+		eint->pins[id].debounce = support_deb;
+
+		eint->instances[inst].pin_list[idx] = id;
+		eint->instances[inst].number++;
+
+#if defined(MTK_EINT_DEBUG)
+		pin = eint->pins[id];
+		dev_info(eint->dev,
+			 "EINT%u in (%u-%u, %u), deb = %u. %u",
+			 id,
+			 pin.instance,
+			 eint->instances[inst].number,
+			 pin.index,
+			 pin.debounce,
+			 eint->instances[pin.instance].pin_list[pin.index]);
+#endif
+	}
+
+	for (i = 0; i < eint->instance_number; i++) {
+		size = (eint->instances[i].number / 32 + 1) * sizeof(unsigned int);
+		eint->instances[i].wake_mask =
+			devm_kzalloc(eint->dev, size, GFP_KERNEL);
+		eint->instances[i].cur_mask =
+			devm_kzalloc(eint->dev, size, GFP_KERNEL);
+
+		if (!eint->instances[i].wake_mask ||
+		    !eint->instances[i].cur_mask)
+			return -ENOMEM;
 	}
 
+	eint->comp = &default_compat;
+
+	eint->irq = irq_of_parse_and_map(node, 0);
+	if (!eint->irq) {
+		dev_err(eint->dev,
+			"%s IRQ parse fail.\n", __func__);
+		return -EINVAL;
+	}
+
+	eint->domain = irq_domain_add_linear(eint->dev->of_node,
+					     eint->total_pin_number,
+					     &irq_domain_simple_ops, NULL);
+	if (!eint->domain)
+		return -ENOMEM;
+
 	mtk_eint_hw_init(eint);
-	for (i = 0; i < eint->hw->ap_num; i++) {
+	for (i = 0; i < eint->total_pin_number; i++) {
 		int virq = irq_create_mapping(eint->domain, i);
 
 		irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
@@ -533,9 +1112,20 @@ int mtk_eint_do_init(struct mtk_eint *eint)
 	irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler,
 					 eint);
 
+	ret = driver_create_file(eint->dev->driver,
+				 &driver_attr_eintc_status);
+
+	ret |= driver_create_file(eint->dev->driver,
+				  &driver_attr_eint_pin_status);
+
+	if (ret)
+		dev_err(eint->dev, "%s create sysfs files failed.\n", __func__);
+
+	global_eintc = eint;
+
 	return 0;
 }
-EXPORT_SYMBOL_GPL(mtk_eint_do_init);
+EXPORT_SYMBOL_GPL(mtk_eint_do_init_v2);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("MediaTek EINT Driver");
diff --git a/drivers/pinctrl/mediatek/mtk-eint.h b/drivers/pinctrl/mediatek/mtk-eint.h
index 6139b16cd225..30be50308b44 100644
--- a/drivers/pinctrl/mediatek/mtk-eint.h
+++ b/drivers/pinctrl/mediatek/mtk-eint.h
@@ -1,16 +1,19 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (C) 2014-2018 MediaTek Inc.
+ * Copyright (C) 2014-2024 MediaTek Inc.
  *
  * Author: Maoguang Meng <maoguang.meng at mediatek.com>
- *	   Sean Wang <sean.wang at mediatek.com>
- *
+ * Sean Wang <sean.wang at mediatek.com>
+ * Chhao Chang <ot_chhao.chang at mediatek.com>
  */
 #ifndef __MTK_EINT_H
 #define __MTK_EINT_H
 
 #include <linux/irqdomain.h>
 
+#define MAX_PIN 256
+//#define MTK_EINT_DEBUG
+
 struct mtk_eint_regs {
 	unsigned int	stat;
 	unsigned int	ack;
@@ -30,19 +33,37 @@ struct mtk_eint_regs {
 	unsigned int	dbnc_ctrl;
 	unsigned int	dbnc_set;
 	unsigned int	dbnc_clr;
+	unsigned int	event;
+	unsigned int	event_set;
+	unsigned int	event_clr;
+	unsigned int	raw_stat;
 };
 
-struct mtk_eint_hw {
-	u8		port_mask;
-	u8		ports;
-	unsigned int	ap_num;
-	unsigned int	db_cnt;
-	const unsigned int *db_time;
+struct mtk_eint_ops {
+	void (*ack)(struct irq_data *d);
 };
 
-extern const unsigned int debounce_time_mt2701[];
-extern const unsigned int debounce_time_mt6765[];
-extern const unsigned int debounce_time_mt6795[];
+struct mtk_eint_compatible {
+	struct mtk_eint_ops ops;
+	const struct mtk_eint_regs *regs;
+};
+
+struct mtk_eint_pin {
+	bool enabled;
+	u8 instance;
+	u8 index;
+	bool debounce;
+	bool dual_edge;
+};
+
+struct mtk_eint_instance {
+	const char *name;
+	void __iomem *base;
+	unsigned int number;
+	u16 pin_list[MAX_PIN];
+	unsigned int *wake_mask;
+	unsigned int *cur_mask;
+};
 
 struct mtk_eint;
 
@@ -54,33 +75,49 @@ struct mtk_eint_xt {
 	int (*set_gpio_as_eint)(void *data, unsigned long eint_n);
 };
 
+struct mtk_eint_hw {
+	u8              port_mask;
+	u8              ports;
+	unsigned int    ap_num;
+	unsigned int    db_cnt;
+	const unsigned int *db_time;
+};
+
+extern const unsigned int debounce_time_mt2701[];
+extern const unsigned int debounce_time_mt6765[];
+extern const unsigned int debounce_time_mt6795[];
+
 struct mtk_eint {
 	struct device *dev;
 	void __iomem *base;
 	struct irq_domain *domain;
 	int irq;
 
-	int *dual_edge;
-	u32 *wake_mask;
-	u32 *cur_mask;
-
-	/* Used to fit into various EINT device */
+	/* An array to record the coordinate, index by global EINT ID */
+	struct mtk_eint_pin *pins;
+	/* An array to record the global EINT ID, index by coordinate */
+	struct mtk_eint_instance *instances;
+	unsigned int total_pin_number;
+	unsigned int instance_number;
+	unsigned int dump_target_eint;
+	const struct mtk_eint_compatible *comp;
 	const struct mtk_eint_hw *hw;
 	const struct mtk_eint_regs *regs;
-	u16 num_db_time;
 
 	/* Used to fit into various pinctrl device */
 	void *pctl;
 	const struct mtk_eint_xt *gpio_xlate;
 };
 
-#if IS_ENABLED(CONFIG_EINT_MTK)
+#if (IS_ENABLED(CONFIG_EINT_MTK) || IS_ENABLED(CONFIG_DEVICE_MODULES_EINT_MTK))
 int mtk_eint_do_init(struct mtk_eint *eint);
+int mtk_eint_do_init_v2(struct mtk_eint *eint);
 int mtk_eint_do_suspend(struct mtk_eint *eint);
 int mtk_eint_do_resume(struct mtk_eint *eint);
 int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n,
 			  unsigned int debounce);
 int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n);
+int dump_eint_pin_status(unsigned int eint_num, char *buf, unsigned int buf_size);
 
 #else
 static inline int mtk_eint_do_init(struct mtk_eint *eint)
@@ -88,6 +125,11 @@ static inline int mtk_eint_do_init(struct mtk_eint *eint)
 	return -EOPNOTSUPP;
 }
 
+static inline int mtk_eint_do_init_v2(struct mtk_eint *eint)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int mtk_eint_do_suspend(struct mtk_eint *eint)
 {
 	return -EOPNOTSUPP;
@@ -108,5 +150,10 @@ static inline int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
 {
 	return -EOPNOTSUPP;
 }
+
+static inline int dump_eint_pin_status(unsigned int eint_num)
+{
+	return -EOPNOTSUPP;
+}
 #endif
 #endif /* __MTK_EINT_H */
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 54301fbba524..59d5ca2405f3 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -375,33 +375,37 @@ int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
 	if (!of_property_read_bool(np, "interrupt-controller"))
 		return -ENODEV;
 
-	hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
-	if (!hw->eint)
-		return -ENOMEM;
-
-	hw->eint->base = devm_platform_ioremap_resource_byname(pdev, "eint");
-	if (IS_ERR(hw->eint->base)) {
-		ret = PTR_ERR(hw->eint->base);
-		goto err_free_eint;
-	}
+	if (hw->soc->eint_hw) {
+		hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
+		if (!hw->eint)
+			return -ENOMEM;
+
+		hw->eint->base = devm_platform_ioremap_resource_byname(pdev, "eint");
+		if (IS_ERR(hw->eint->base)) {
+			ret = PTR_ERR(hw->eint->base);
+			goto err_free_eint;
+		}
 
-	hw->eint->irq = irq_of_parse_and_map(np, 0);
-	if (!hw->eint->irq) {
-		ret = -EINVAL;
-		goto err_free_eint;
-	}
+		hw->eint->irq = irq_of_parse_and_map(np, 0);
+		if (!hw->eint->irq) {
+			ret = -EINVAL;
+			goto err_free_eint;
+		}
 
-	if (!hw->soc->eint_hw) {
-		ret = -ENODEV;
-		goto err_free_eint;
-	}
+		hw->eint->dev = &pdev->dev;
+		hw->eint->hw = hw->soc->eint_hw;
+		hw->eint->pctl = hw;
+		hw->eint->gpio_xlate = &mtk_eint_xt;
+
+		return mtk_eint_do_init(hw->eint);
 
-	hw->eint->dev = &pdev->dev;
-	hw->eint->hw = hw->soc->eint_hw;
-	hw->eint->pctl = hw;
-	hw->eint->gpio_xlate = &mtk_eint_xt;
+	} else {
+		hw->eint->dev = &pdev->dev;
+		hw->eint->pctl = hw;
+		hw->eint->gpio_xlate = &mtk_eint_xt;
 
-	return mtk_eint_do_init(hw->eint);
+		return mtk_eint_do_init_v2(hw->eint);
+	}
 
 err_free_eint:
 	devm_kfree(hw->dev, hw->eint);
-- 
2.34.1



From lkp at intel.com  Mon Dec  2 00:54:11 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 2 Dec 2024 16:54:11 +0800
Subject: [PATCH v5 10/19] drm/imx: Add i.MX8qxp Display Controller pixel
 engine
In-Reply-To: <20241202025635.1274467-11-victor.liu@nxp.com>
References: <20241202025635.1274467-11-victor.liu@nxp.com>
Message-ID: <202412021617.HmlPGJLh-lkp@intel.com>

Hi Liu,

kernel test robot noticed the following build warnings:

[auto build test WARNING on shawnguo/for-next]
[also build test WARNING on linus/master v6.13-rc1 next-20241128]
[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/Liu-Ying/dt-bindings-display-imx-Add-i-MX8qxp-Display-Controller-processing-units/20241202-110331
base:   https://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git for-next
patch link:    https://lore.kernel.org/r/20241202025635.1274467-11-victor.liu%40nxp.com
patch subject: [PATCH v5 10/19] drm/imx: Add i.MX8qxp Display Controller pixel engine
config: alpha-allyesconfig (https://download.01.org/0day-ci/archive/20241202/202412021617.HmlPGJLh-lkp at intel.com/config)
compiler: alpha-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241202/202412021617.HmlPGJLh-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/202412021617.HmlPGJLh-lkp at intel.com/

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/imx/dc/dc-fl.c: In function 'dc_fl_bind':
>> drivers/gpu/drm/imx/dc/dc-fl.c:136:57: warning: '%d' directive output may be truncated writing between 1 and 10 bytes into a region of size 3 [-Wformat-truncation=]
     136 |         snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
         |                                                         ^~
   drivers/gpu/drm/imx/dc/dc-fl.c:136:46: note: directive argument in the range [0, 2147483647]
     136 |         snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
         |                                              ^~~~~~~~~~~~~~
   drivers/gpu/drm/imx/dc/dc-fl.c:136:9: note: 'snprintf' output between 12 and 21 bytes into a destination of size 13
     136 |         snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
   drivers/gpu/drm/imx/dc/dc-fw.c: In function 'dc_fw_bind':
>> drivers/gpu/drm/imx/dc/dc-fw.c:175:56: warning: '%u' directive output may be truncated writing between 1 and 10 bytes into a region of size 4 [-Wformat-truncation=]
     175 |         snprintf(fu->name, sizeof(fu->name), "FetchWarp%u", fw->id);
         |                                                        ^~
   drivers/gpu/drm/imx/dc/dc-fw.c:175:46: note: directive argument in the range [0, 2147483647]
     175 |         snprintf(fu->name, sizeof(fu->name), "FetchWarp%u", fw->id);
         |                                              ^~~~~~~~~~~~~
   drivers/gpu/drm/imx/dc/dc-fw.c:175:9: note: 'snprintf' output between 11 and 20 bytes into a destination of size 13
     175 |         snprintf(fu->name, sizeof(fu->name), "FetchWarp%u", fw->id);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +136 drivers/gpu/drm/imx/dc/dc-fl.c

    92	
    93	static int dc_fl_bind(struct device *dev, struct device *master, void *data)
    94	{
    95		struct platform_device *pdev = to_platform_device(dev);
    96		struct dc_drm_device *dc_drm = data;
    97		struct dc_pe *pe = dc_drm->pe;
    98		void __iomem *base_cfg;
    99		struct dc_fl *fl;
   100		struct dc_fu *fu;
   101		int i;
   102	
   103		fl = devm_kzalloc(dev, sizeof(*fl), GFP_KERNEL);
   104		if (!fl)
   105			return -ENOMEM;
   106	
   107		fu = &fl->fu;
   108	
   109		base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
   110		if (IS_ERR(base_cfg))
   111			return PTR_ERR(base_cfg);
   112	
   113		fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
   114						    &dc_fl_cfg_regmap_config);
   115		if (IS_ERR(fu->reg_cfg))
   116			return PTR_ERR(fu->reg_cfg);
   117	
   118		fl->id = of_alias_get_id(dev->of_node, "dc0-fetchlayer");
   119		if (fl->id < 0) {
   120			dev_err(dev, "failed to get alias id: %d\n", fl->id);
   121			return fl->id;
   122		}
   123	
   124		fu->link_id = LINK_ID_FETCHLAYER0;
   125		fu->id = DC_FETCHUNIT_FL0;
   126		for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
   127			fu->reg_baseaddr[i]		  = BASEADDRESS(i);
   128			fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
   129			fu->reg_sourcebufferdimension[i]  = SOURCEBUFFERDIMENSION(i);
   130			fu->reg_layeroffset[i]		  = LAYEROFFSET(i);
   131			fu->reg_clipwindowoffset[i]	  = CLIPWINDOWOFFSET(i);
   132			fu->reg_clipwindowdimensions[i]	  = CLIPWINDOWDIMENSIONS(i);
   133			fu->reg_constantcolor[i]	  = CONSTANTCOLOR(i);
   134			fu->reg_layerproperty[i]	  = LAYERPROPERTY(i);
   135		}
 > 136		snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
   137	
   138		dc_fl_set_ops(fu);
   139	
   140		pe->fu_disp[fu->id] = fu;
   141	
   142		return 0;
   143	}
   144	

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


From urszula.kurach at finteras.pl  Mon Dec  2 00:55:23 2024
From: urszula.kurach at finteras.pl (Urszula Kurach)
Date: Mon,  2 Dec 2024 08:55:23 GMT
Subject: =?UTF-8?Q?Pakiety_telemedyczne_dla_pracownik=C3=B3w?=
Message-ID: <20241202084500-0.1.57.6qv3.0.jo69viwdf7@finteras.pl>

Szanowni Pa?stwo,

chcia?abym zapyta?, czy byliby Pa?stwo zainteresowani dost?pem do nielimitowanej opieki telemedycznej pediatry, ortopedy, neurologa oraz lekarzy wielu innych specjalizacji?

Oferujemy 3 r??ne pakiety, kt?re zapewniaj? dost?p do us?ug dopasowanych do potrzeb Pa?stwa firmy. Pakiet podstawowy daje mo?liwo?? korzystania z konsultacji internisty nawet w weekendy i ?wi?ta, natomiast pakiet pe?ny obejmuje dost?p do lekarzy 42 specjalizacji, a tak?e atrakcyjne rabaty na badania laboratoryjne i diagnostyk? obrazow?.

Dzi?ki takim rozwi?zaniom, Pa?stwa pracownicy zyskaj? warto?ciowy benefit pozap?acowy, a firma zyska zmotywowany zesp??, mniej absencji chorobowych i dodatkowe oszcz?dno?ci.

Czy mog? przedstawi? wi?cej szczeg???w na temat dost?pnych pakiet?w?


Pozdrawiam
Urszula Kurach


From krzk at kernel.org  Mon Dec  2 00:53:04 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 09:53:04 +0100
Subject: [PATCH v3 3/4] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S20 5G (x1s)
In-Reply-To: <9f48459e-f381-446a-86bf-c8d1bb8858bc@gmail.com>
References: <20241030232308.72210-1-umer.uddin@mentallysanemainliners.org>
 <20241030232308.72210-4-umer.uddin@mentallysanemainliners.org>
 <9f48459e-f381-446a-86bf-c8d1bb8858bc@gmail.com>
Message-ID: <88f6ab28-1b3f-4144-91c8-0131ee008838@kernel.org>

On 14/11/2024 10:09, Ivaylo Ivanov wrote:
>> +
>> +/ {
>> +	#address-cells = <2>;
>> +	#size-cells = <2>;
>> +
>> +	model = "Samsung Galaxy S20 5G";
>> +	compatible = "samsung,x1s", "samsung,exynos990";
>> +
>> +	memory at 80000000 {
>> +		device_type = "memory";
>> +		reg = <0x0 0x80000000 0x0 0x3ab00000>,
>> +		      /* Memory hole */
>> +		      <0x0 0xc1200000 0x0 0x1ee00000>,
>> +		      /* Memory hole */
>> +		      <0x0 0xe1900000 0x0 0x1e700000>,
>> +		      /* Memory hole */
> 
> The space from 0x100000000 to 0x880000000 isn't a hole in the memory
> though, is it? 0x880000000 is in the 64 bit address space.
> 
> Best regards, Ivo.
Umer,

I wanted to apply the series, but for two weeks you ignored this
feedback/comment, so I am dropping the patchset from my queue.

Be sure you respond to reviewers in timely manner (and if you give
yourself more than two weeks to respond it also means other have more
than two weeks...).

Best regards,
Krzysztof


From krzysztof.kozlowski at linaro.org  Mon Dec  2 00:53:46 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 02 Dec 2024 09:53:46 +0100
Subject: (subset) [PATCH v2 4/5] arm64: dts: exynos8895: Add serial_0/1
 nodes
In-Reply-To: <20241023091734.538682-5-ivo.ivanov.ivanov1@gmail.com>
References: <20241023091734.538682-1-ivo.ivanov.ivanov1@gmail.com>
 <20241023091734.538682-5-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <173312962604.23906.10353059101648062689.b4-ty@linaro.org>


On Wed, 23 Oct 2024 12:17:33 +0300, Ivaylo Ivanov wrote:
> Add nodes for serial_0 (UART_DBG) and serial_1 (UART_BT), which
> allows using them.
> 
> 

Applied, thanks!

[4/5] arm64: dts: exynos8895: Add serial_0/1 nodes
      https://git.kernel.org/krzk/linux/c/aa33006c53c9c56ecbcbbb9b5415e27000eb86d4

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



From krzk at kernel.org  Mon Dec  2 00:56:37 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 09:56:37 +0100
Subject: [PATCH v2 2/2] arm64: dts: Add initial support for Samsung Galaxy
 S20 FE (r8s)
In-Reply-To: <746e218b-a00c-49ac-a998-511696bc9525@gmail.com>
References: <20241112193149.1262-1-wachiturroxd150@gmail.com>
 <20241112193149.1262-3-wachiturroxd150@gmail.com>
 <746e218b-a00c-49ac-a998-511696bc9525@gmail.com>
Message-ID: <f8780a3a-793a-4067-8108-18a293eb1fd0@kernel.org>

On 14/11/2024 09:26, Ivaylo Ivanov wrote:
> 
> 
> 
> On 11/12/24 21:31, Denzeel Oliva wrote:
>> Add initial support for the Samsung Galaxy S20 FE (r8s/SM-G780F) device.
>> Its launch was in 2020 and also based on the Exynos 990 SoC.
>> It is only configured with 6GB of RAM, although storage options may differ.
> 
> As far as I can tell, there are models with more than 6gb's of ram.
> How would the memory node differ for them?
> 
Denzeel,

This comment was not addressed.

Be sure you respond to reviewers in timely manner (and if you give
yourself more than two weeks to respond it also means other have more
than two weeks...).

Nevertheless, this is not really stopping from merging this device.  New
variants can be always later added with different memory map.

Best regards,
Krzysztof


From jakobunt at gmail.com  Mon Dec  2 01:04:07 2024
From: jakobunt at gmail.com (Jakob Unterwurzacher)
Date: Mon,  2 Dec 2024 10:04:07 +0100
Subject: [PATCH] arm64: dts: rockchip: increase gmac rx_delay to 0x11 on rk3399-puma
Message-ID: <20241202090408.201662-1-jakob.unterwurzacher@cherry.de>

During mass manufacturing, we noticed the mmc_rx_crc_error counter,
as reported by "ethtool -S eth0 | grep mmc_rx_crc_error" to increase
above zero during nuttcp speedtests.

Cycling through the rx_delay range on two boards shows that is a large
"good" region from 0x11 to 0x35 (see below for details).

This commit increases rx_delay to 0x11, which is the smallest
possible change that fixes the issue we are seeing on the KSZ9031 PHY.
This also matches what most other rk3399 boards do.

Tests for Puma PCBA S/N TT0069903:

	rx_delay mmc_rx_crc_error
	-------- ----------------
	0x09 (dhcp broken)
	0x10 897
	0x11 0
	0x20 0
	0x30 0
	0x35 0
	0x3a 745
	0x3b 11375
	0x3c 36680
	0x40 (dhcp broken)
	0x7f (dhcp broken)

Tests for Puma PCBA S/N TT0157733:

	rx_delay mmc_rx_crc_error
	-------- ----------------
	0x10 59
	0x11 0
	0x35 0

Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at cherry.de>
---
 arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
index 9efcdce0f593..13d0c511046b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
@@ -181,7 +181,7 @@ &gmac {
 	snps,reset-active-low;
 	snps,reset-delays-us = <0 10000 50000>;
 	tx_delay = <0x10>;
-	rx_delay = <0x10>;
+	rx_delay = <0x11>;
 	status = "okay";
 };
 
-- 
2.39.5



From dan.carpenter at linaro.org  Mon Dec  2 01:07:22 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Mon, 2 Dec 2024 12:07:22 +0300
Subject: [PATCH v2] PCI: rockchip-ep: Fix error code in
 rockchip_pcie_ep_init_ob_mem()
Message-ID: <Z014ylYz_xrrgI4W@stanley.mountain>

Return -ENOMEM if pci_epc_mem_alloc_addr() fails.  Don't return success.

Fixes: 945648019466 ("PCI: rockchip-ep: Refactor rockchip_pcie_ep_probe() memory allocations")
Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>
Reviewed-by: Damien Le Moal <dlemoal at kernel.org>
---
v2: Update the git hash for the Fixes tag because the tree was rebased I guess.

 drivers/pci/controller/pcie-rockchip-ep.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
index 1064b7b06cef..34162ca14093 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -784,6 +784,7 @@ static int rockchip_pcie_ep_init_ob_mem(struct rockchip_pcie_ep *ep)
 						  SZ_1M);
 	if (!ep->irq_cpu_addr) {
 		dev_err(dev, "failed to reserve memory space for MSI\n");
+		err = -ENOMEM;
 		goto err_epc_mem_exit;
 	}
 
-- 
2.45.2



From maz at kernel.org  Mon Dec  2 01:11:37 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Dec 2024 09:11:37 +0000
Subject: [PATCH] KVM: arm64: Make the exposed feature bits in AA64DFR0_EL1 writable from userspace
In-Reply-To: <e35612b4-e25b-4846-8fd2-56c2473c140d@redhat.com>
References: <20240813142835.77180-1-shameerali.kolothum.thodi@huawei.com>
	<86v804z3lk.wl-maz@kernel.org>
	<b2dad37ac5464384abe4edf76cb6b546@huawei.com>
	<4d3a7dde-e085-fa70-8859-ba153c93b615@redhat.com>
	<87zfllssji.wl-maz@kernel.org>
	<c879fda9-db5a-4743-805d-03c0acba8060@redhat.com>
	<865xo3vbjq.wl-maz@kernel.org>
	<e35612b4-e25b-4846-8fd2-56c2473c140d@redhat.com>
Message-ID: <86y10ytpo6.wl-maz@kernel.org>

On Mon, 02 Dec 2024 08:03:26 +0000,
Eric Auger <eauger at redhat.com> wrote:
> 
> Hi Marc,
> 
> On 12/1/24 13:21, Marc Zyngier wrote:
> > Hey Eric,
> > 
> > On Thu, 28 Nov 2024 09:31:08 +0000,
> > Eric Auger <eauger at redhat.com> wrote:
> >>
> >> Hi Marc,
> >>
> >> On 11/26/24 20:29, Marc Zyngier wrote:
> >>> Finally, who is going to ensure this keeps working in the foreseeable
> >>> future? Because while this is nice, that's not what gets deployed in
> >>> production, as it leads to unpredictable performances. My take is that
> >>> this thing will eventually bitrot and die.
> >> In the context of our works to define qemu vcpu models for ARM
> >> (https://lore.kernel.org/all/20241025101959.601048-1-eric.auger at redhat.com/)
> >> , our current approach is to try migrating between modern HW we have
> >> access to. The case above is migration between AmpereOne and Grace which
> >> both should be prevalent systems. Do you think this does not make sense
> >> at all to try migrating between those, alhough this may be challenging?
> > 
> > I don't mind the challenge. But I'm worried this is something that
> > looks like a reasonable idea that doesn't get any traction in
> > practice.
> > 
> > And the example you mention is pretty striking: who in their right
> > mind would migrate between these two systems? If you deploy a Grace
> > system, that's because you are making use of the GPU, and your VM is
> > likely to require it. Conversely, if you run on an Ampere system, you
> > don't want to use a valuable (read: bloody expensive) slot on a Grace
> > machine.
> 
> Yes I acknowledge it is a total valid point from a use case and cost
> point of view. I was expecting maybe some interest migrating between
> AmpereOne and Grace-Grace for farm enhancement but most probably it is
> marginal.

That's my understanding as well. Cloud vendors tend to have
homogeneous systems, and those who don't are realising that they shot
themselves in the foot (and in that case, the debug infrastructure is
the least of their worries).

> Definition of [qemu] named vcpu models looks pretty uneasy then because
> we don't have much relevant and accessible HW to test with, taking into
> account such non technical considerations. Besides migration within a
> CPU family I don't see much.

That's basically my point.

Another thing to consider is that there is an effort on the SBSA
front to standardise which breakpoint numbers are context-aware, which
would side-step the need for emulation in the long run (once the
current crop of HW is gone and forgotten, which should be in the next
3 months or so ;-).

But if there was a *credible* user coming out and saying that they
depended on this sort of feature to be supported now and forever, then
I'd be more supportive.

Thanks,

	M.

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


From tabba at google.com  Mon Dec  2 01:16:48 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Dec 2024 09:16:48 +0000
Subject: [PATCH v3 15/15] KVM: arm64: Renumber remaining vcpu guest
 configuration flags
In-Reply-To: <8634j7v9rm.wl-maz@kernel.org>
References: <20241128123515.1709777-1-tabba@google.com> <20241128123515.1709777-16-tabba@google.com>
 <8634j7v9rm.wl-maz@kernel.org>
Message-ID: <CA+EHjTxnYi7_kStfQtExuQTyBEZict5ekmfn_vg100tHFv_VJQ@mail.gmail.com>

On Sun, 1 Dec 2024 at 13:00, Marc Zyngier <maz at kernel.org> wrote:
>
> On Thu, 28 Nov 2024 12:35:15 +0000,
> Fuad Tabba <tabba at google.com> wrote:
> >
> > With the vcpu's SVE and PtrAuth configuration flags removed,
> > there are gaps in the numbering of the cflag bits. Renumber
> > VCPU_INITIALIZED to bit 0 to remove the gaps.
> >
> > No functional change intended.
> >
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_host.h | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index c5c80c789ad0..2e4afec09728 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -864,10 +864,10 @@ struct kvm_vcpu_arch {
> >  #define vcpu_set_flag(v, ...)        __vcpu_set_flag((v), __VA_ARGS__)
> >  #define vcpu_clear_flag(v, ...)      __vcpu_clear_flag((v), __VA_ARGS__)
> >
> > +/* KVM_ARM_VCPU_INIT completed */
> > +#define VCPU_INITIALIZED     __vcpu_single_flag(cflags, BIT(0))
> >  /* SVE config completed */
> >  #define VCPU_SVE_FINALIZED   __vcpu_single_flag(cflags, BIT(1))
> > -/* KVM_ARM_VCPU_INIT completed */
> > -#define VCPU_INITIALIZED     __vcpu_single_flag(cflags, BIT(3))
> >
> >  /* Exception pending */
> >  #define PENDING_EXCEPTION    __vcpu_single_flag(iflags, BIT(0))
>
> Please fold this with the relevant patches, even if that makes two
> consecutive renumbering patches.

Will do.

Thanks!
/fuad

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


From yangyicong at huawei.com  Mon Dec  2 01:24:18 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 17:24:18 +0800
Subject: [PATCH 3/4] coresight: tmc-etr: Fix race condition between sysfs and perf mode
In-Reply-To: <20241202092419.11777-1-yangyicong@huawei.com>
References: <20241202092419.11777-1-yangyicong@huawei.com>
Message-ID: <20241202092419.11777-4-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

When trying to run perf and sysfs mode simultaneously, the WARN_ON()
in tmc_etr_enable_hw() is triggered sometimes:

 WARNING: CPU: 42 PID: 3911571 at drivers/hwtracing/coresight/coresight-tmc-etr.c:1060 tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc]
 [..snip..]
 Call trace:
  tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc] (P)
  tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc] (L)
  tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc]
  coresight_enable_path+0x1c8/0x218 [coresight]
  coresight_enable_sysfs+0xa4/0x228 [coresight]
  enable_source_store+0x58/0xa8 [coresight]
  dev_attr_store+0x20/0x40
  sysfs_kf_write+0x4c/0x68
  kernfs_fop_write_iter+0x120/0x1b8
  vfs_write+0x2c8/0x388
  ksys_write+0x74/0x108
  __arm64_sys_write+0x24/0x38
  el0_svc_common.constprop.0+0x64/0x148
  do_el0_svc+0x24/0x38
  el0_svc+0x3c/0x130
  el0t_64_sync_handler+0xc8/0xd0
  el0t_64_sync+0x1ac/0x1b0
 ---[ end trace 0000000000000000 ]---

Since the enablement of sysfs mode is separeted into two critical regions,
one for sysfs buffer allocation and another for hardware enablement, it's
possible to race with the perf mode. Fix this by double check whether
the perf mode's been used before enabling the hardware in sysfs mode.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 .../hwtracing/coresight/coresight-tmc-etr.c   | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index ad83714ca4dc..d382d95da5ff 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1230,6 +1230,36 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 
+	/*
+	 * Since the sysfs buffer allocation and the hardware enablement is not
+	 * in the same critical region, it's possible to race with the perf
+	 * mode:
+	 *   [sysfs mode]                   [perf mode]
+	 *   tmc_etr_get_sysfs_buffer()
+	 *     spin_lock(&drvdata->spinlock)
+	 *     [sysfs buffer allocation]
+	 *     spin_unlock(&drvdata->spinlock)
+	 *                                  spin_lock(&drvdata->spinlock)
+	 *                                  tmc_etr_enable_hw()
+	 *                                    drvdata->etr_buf = etr_perf->etr_buf
+	 *                                  spin_unlock(&drvdata->spinlock)
+	 *   spin_lock(&drvdata->spinlock)
+	 *   tmc_etr_enable_hw()
+	 *     WARN_ON(drvdata->etr_buf) // WARN sicne etr_buf initialized at
+	 *                                  the perf side
+	 *   spin_unlock(&drvdata->spinlock)
+	 *
+	 * So check here before continue.
+	 */
+	if (coresight_get_mode(csdev) == CS_MODE_PERF) {
+		drvdata->sysfs_buf = NULL;
+		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+		/* Free allocated memory out side of the spinlock */
+		tmc_etr_free_sysfs_buf(sysfs_buf);
+		return -EBUSY;
+	}
+
 	/*
 	 * In sysFS mode we can have multiple writers per sink.  Since this
 	 * sink is already enabled no memory is needed and the HW need not be
-- 
2.24.0



From yangyicong at huawei.com  Mon Dec  2 01:24:17 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 17:24:17 +0800
Subject: [PATCH 2/4] coresight: tmc: Add missing doc of tmc_drvdata::reading
In-Reply-To: <20241202092419.11777-1-yangyicong@huawei.com>
References: <20241202092419.11777-1-yangyicong@huawei.com>
Message-ID: <20241202092419.11777-3-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

tmc_drvdata::reading is used to indicate whether a reading process
is performed through /dev/xyz.tmc. Document it.

Reviewed-by: James Clark <james.clark at linaro.org>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/hwtracing/coresight/coresight-tmc.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 2671926be62a..fdf7955e7350 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -174,6 +174,7 @@ struct etr_buf {
  * @pid:	Process ID of the process that owns the session that is using
  *		this component. For example this would be the pid of the Perf
  *		process.
+ * @reading:	buffer's in the reading through "/dev/xyz.tmc" entry
  * @buf:	Snapshot of the trace data for ETF/ETB.
  * @etr_buf:	details of buffer used in TMC-ETR
  * @len:	size of the available trace for ETF/ETB.
-- 
2.24.0



From yangyicong at huawei.com  Mon Dec  2 01:24:15 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 17:24:15 +0800
Subject: [PATCH 0/4] Coresight TMC-ETR some bugfixes and cleanups
Message-ID: <20241202092419.11777-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Fix two race issues found by using TMC-ETR. Two cleanups found when
debugging the issues. Patch 1/4 is suggested by Suzuki in [1] and
tested to solve the original issue.

[1] https://lore.kernel.org/linux-arm-kernel/20241114081653.24328-1-yangyicong at huawei.com/

Suzuki K Poulose (1):
  coresight: tmc: Don't reallocate the sysfs_buffer if it's in use

Yicong Yang (3):
  coresight: tmc: Add missing doc of tmc_drvdata::reading
  coresight: tmc-etr: Fix race condition between sysfs and perf mode
  coresight: tmc-etr: Decouple the perf buffer allocation from sysfs
    mode

 .../hwtracing/coresight/coresight-tmc-etr.c   | 65 +++++++++++++------
 drivers/hwtracing/coresight/coresight-tmc.h   |  1 +
 2 files changed, 45 insertions(+), 21 deletions(-)

-- 
2.24.0



From yangyicong at huawei.com  Mon Dec  2 01:24:16 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 17:24:16 +0800
Subject: [PATCH 1/4] coresight: tmc: Don't reallocate the sysfs_buffer if it's in use
In-Reply-To: <20241202092419.11777-1-yangyicong@huawei.com>
References: <20241202092419.11777-1-yangyicong@huawei.com>
Message-ID: <20241202092419.11777-2-yangyicong@huawei.com>

From: Suzuki K Poulose <suzuki.poulose at arm.com>

Enable the trace in below steps will crash the kernel by NULL pointer
dereferencing:
echo 1 > /sys/bus/coresight/devices/tmc_etr0/enable_sink
echo 1 > /sys/bus/coresight/devices/etm0/enable_source
echo 0x400000 > /sys/bus/coresight/devices/tmc_etr0/buffer_size
echo 1 > /sys/bus/coresight/devices/etm2/enable_source
dd if=/dev/tmc_etr0 of=test_etm_sysfs_etr_030.data

The call trace will be like:
 WARNING: CPU: 39 PID: 8586 at drivers/hwtracing/coresight/coresight-tmc-etr.c:1123 __tmc_etr_disable_hw+0x108/0x140 [coresight_tmc]
 [...]
 Call trace:
  __tmc_etr_disable_hw+0x108/0x140 [coresight_tmc]
  tmc_read_prepare_etr+0xc0/0xd0 [coresight_tmc]
  tmc_open+0x60/0xa0 [coresight_tmc]
  misc_open+0x11c/0x170
  chrdev_open+0xcc/0x2b0
  do_dentry_open+0x140/0x4e0
  vfs_open+0x34/0xf8
  path_openat+0x2b0/0xf58
  do_filp_open+0x8c/0x148
  do_sys_openat2+0xb8/0xe8
  __arm64_sys_openat+0x70/0xc0
  el0_svc_common.constprop.0+0x64/0x148
  do_el0_svc+0x24/0x38
  el0_svc+0x40/0x140
  el0t_64_sync_handler+0xc0/0xc8
  el0t_64_sync+0x1a4/0x1a8
 ---[ end trace 0000000000000000 ]---
 Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
 [...]
 Call trace:
  tmc_etr_get_sysfs_trace+0x10/0x80 [coresight_tmc]
  vfs_read+0xcc/0x310
  ksys_read+0x74/0x108
  __arm64_sys_read+0x24/0x38
  el0_svc_common.constprop.0+0x64/0x148
  do_el0_svc+0x24/0x38
  el0_svc+0x40/0x140

Due to the buffer size changed, the buffer will be reallocated in
tmc_etr_get_sysfs_buffer() when the second source enabled. At trace
end tmc_etr_sync_sysfs_buf() will reset the drvdata->sysfs_buf and
trigger the later NULL pointer dereference when reading out the
data. Fix this by checking whether the buffer's in use before
reallocate a now one in tmc_etr_get_sysfs_buffer().

Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/hwtracing/coresight/coresight-tmc-etr.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..ad83714ca4dc 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1178,7 +1178,11 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 	 */
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 	sysfs_buf = READ_ONCE(drvdata->sysfs_buf);
-	if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) {
+
+	/* Don't reallocate the buffer if it's already in use */
+	if (!sysfs_buf ||
+	    ((sysfs_buf->size != drvdata->size) &&
+	     coresight_get_mode(csdev) != CS_MODE_SYSFS)) {
 		spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 		/* Allocate memory with the locks released */
-- 
2.24.0



From yangyicong at huawei.com  Mon Dec  2 01:24:19 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 17:24:19 +0800
Subject: [PATCH 4/4] coresight: tmc-etr: Decouple the perf buffer allocation from sysfs mode
In-Reply-To: <20241202092419.11777-1-yangyicong@huawei.com>
References: <20241202092419.11777-1-yangyicong@huawei.com>
Message-ID: <20241202092419.11777-5-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Currently the perf buffer allocation follows the below logic:
- if the required AUX buffer size if larger, allocate the buffer with
  the required size
- otherwise allocate the size reference to the sysfs buffer size

This is not useful as we only collect to one AUX data, so just try to
allocate the buffer match the AUX buffer size.

Suggested-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Link: https://lore.kernel.org/linux-arm-kernel/df8967cd-2157-46a2-97d9-a1aea883cf63 at arm.com/
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 .../hwtracing/coresight/coresight-tmc-etr.c   | 29 ++++++-------------
 1 file changed, 9 insertions(+), 20 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index d382d95da5ff..d8b005d0bf05 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1307,9 +1307,7 @@ EXPORT_SYMBOL_GPL(tmc_etr_get_buffer);
 
 /*
  * alloc_etr_buf: Allocate ETR buffer for use by perf.
- * The size of the hardware buffer is dependent on the size configured
- * via sysfs and the perf ring buffer size. We prefer to allocate the
- * largest possible size, scaling down the size by half until it
+ * Allocate the largest possible size, scaling down the size by half until it
  * reaches a minimum limit (1M), beyond which we give up.
  */
 static struct etr_buf *
@@ -1321,33 +1319,24 @@ alloc_etr_buf(struct tmc_drvdata *drvdata, struct perf_event *event,
 	unsigned long size;
 
 	node = (event->cpu == -1) ? NUMA_NO_NODE : cpu_to_node(event->cpu);
-	/*
-	 * Try to match the perf ring buffer size if it is larger
-	 * than the size requested via sysfs.
-	 */
-	if ((nr_pages << PAGE_SHIFT) > drvdata->size) {
-		etr_buf = tmc_alloc_etr_buf(drvdata, ((ssize_t)nr_pages << PAGE_SHIFT),
-					    0, node, NULL);
-		if (!IS_ERR(etr_buf))
-			goto done;
-	}
+
+	/* Use the minimum limit if the required size is smaller */
+	size = (unsigned long)nr_pages << PAGE_SHIFT;
+	if (size < TMC_ETR_PERF_MIN_BUF_SIZE)
+		size = TMC_ETR_PERF_MIN_BUF_SIZE;
 
 	/*
-	 * Else switch to configured size for this ETR
-	 * and scale down until we hit the minimum limit.
+	 * Try to allocate the required size for this ETR, if failed scale
+	 * down until we hit the minimum limit.
 	 */
-	size = drvdata->size;
 	do {
 		etr_buf = tmc_alloc_etr_buf(drvdata, size, 0, node, NULL);
 		if (!IS_ERR(etr_buf))
-			goto done;
+			return etr_buf;
 		size /= 2;
 	} while (size >= TMC_ETR_PERF_MIN_BUF_SIZE);
 
 	return ERR_PTR(-ENOMEM);
-
-done:
-	return etr_buf;
 }
 
 static struct etr_buf *
-- 
2.24.0



From manivannan.sadhasivam at linaro.org  Mon Dec  2 01:29:02 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Mon, 2 Dec 2024 14:59:02 +0530
Subject: [PATCH] PCI: check bridge->bus in pci_host_common_remove
In-Reply-To: <20241127195650.GA4132105-robh@kernel.org>
References: <20241028084644.3778081-1-peng.fan@oss.nxp.com>
 <20241115062005.6ifvr6ens2qnrrrf@thinkpad>
 <PAXPR04MB8459D1507CA69498D8C38E0488242@PAXPR04MB8459.eurprd04.prod.outlook.com>
 <20241115144720.ovsyq2ani47norby@thinkpad>
 <20241127195650.GA4132105-robh@kernel.org>
Message-ID: <20241202092902.rp6xb3f64llpabbi@thinkpad>

On Wed, Nov 27, 2024 at 01:56:50PM -0600, Rob Herring wrote:
> On Fri, Nov 15, 2024 at 08:17:20PM +0530, Manivannan Sadhasivam wrote:
> > On Fri, Nov 15, 2024 at 10:14:10AM +0000, Peng Fan wrote:
> > > Hi Manivannan,
> > > 
> > > > Subject: Re: [PATCH] PCI: check bridge->bus in
> > > > pci_host_common_remove
> > > > 
> > > > On Mon, Oct 28, 2024 at 04:46:43PM +0800, Peng Fan (OSS) wrote:
> > > > > From: Peng Fan <peng.fan at nxp.com>
> > > > >
> > > > > When PCI node was created using an overlay and the overlay is
> > > > > reverted/destroyed, the "linux,pci-domain" property no longer exists,
> > > > > so of_get_pci_domain_nr will return failure. Then
> > > > > of_pci_bus_release_domain_nr will actually use the dynamic IDA,
> > > > even
> > > > > if the IDA was allocated in static IDA. So the flow is as below:
> > > > > A: of_changeset_revert
> > > > >     pci_host_common_remove
> > > > >      pci_bus_release_domain_nr
> > > > >        of_pci_bus_release_domain_nr
> > > > >          of_get_pci_domain_nr      # fails because overlay is gone
> > > > >          ida_free(&pci_domain_nr_dynamic_ida)
> > > > >
> > > > > With driver calls pci_host_common_remove explicity, the flow
> > > > becomes:
> > > > > B pci_host_common_remove
> > > > >    pci_bus_release_domain_nr
> > > > >     of_pci_bus_release_domain_nr
> > > > >      of_get_pci_domain_nr      # succeeds in this order
> > > > >       ida_free(&pci_domain_nr_static_ida)
> > > > > A of_changeset_revert
> > > > >    pci_host_common_remove
> > > > >
> > > > > With updated flow, the pci_host_common_remove will be called
> > > > twice, so
> > > > > need to check 'bridge->bus' to avoid accessing invalid pointer.
> > > > >
> > > > > Fixes: c14f7ccc9f5d ("PCI: Assign PCI domain IDs by ida_alloc()")
> > > > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > > 
> > > > I went through the previous discussion [1] and I couldn't see an
> > > > agreement on the point raised by Bjorn on 'removing the host bridge
> > > > before the overlay'.
> > > 
> > > This patch is an agreement to Bjorn's idea. 
> > > 
> > > I have added pci_host_common_remove to remove host bridge
> > > before removing overlay as I wrote in commit log.
> > > 
> > > But of_changeset_revert will still runs into pci_host_
> > > common_remove to remove the host bridge again. Per
> > > my view, the design of of_changeset_revert to remove
> > > the device tree node will trigger device remove, so even
> > > pci_host_common_remove was explicitly used before
> > > of_changeset_revert. The following call to of_changeset_revert
> > > will still call pci_host_common_remove.
> > > 
> > > So I did this patch to add a check of 'bus' to avoid remove again.
> > > 
> > 
> > Ok. I think there was a misunderstanding. Bjorn's example driver,
> > 'i2c-demux-pinctrl' applies the changeset, then adds the i2c adapter for its
> > own. And in remove(), it does the reverse.
> > 
> > But in your case, the issue is with the host bridge driver that gets probed
> > because of the changeset. While with 'i2c-demux-pinctrl' driver, it only
> > applies the changeset. So we cannot compare both drivers. I believe in your
> > case, 'i2c-demux-pinctrl' becomes 'jailhouse', isn't it?
> > 
> > So in your case, changeset is applied by jailhouse and that causes the
> > platform device to be created for the host bridge and then the host bridge
> > driver gets probed. So during destroy(), you call of_changeset_revert() that
> > removes the platform device and during that process it removes the host bridge
> > driver. The issue happens because during host bridge remove, it calls
> > pci_remove_root_bus() and that tries to remove the domain_nr using
> > pci_bus_release_domain_nr().
> >
> > But pci_bus_release_domain_nr() uses DT node to check whether to free the
> > domain_nr from static IDA or dynamic IDA. And because there is no DT node exist
> > at this time (it was already removed by of_changeset_revert()), it forces
> > pci_bus_release_domain_nr() to use dynamic IDA even though the IDA was initially
> > allocated from static IDA.
> 
> Putting linux,pci-domain in an overlay is the same problem as aliases in 
> overlays[1]. It's not going to work well.
> 
> IMO, you can have overlays, or you can have static domains. You can't 
> have both.
> 

Okay. 

> > I think a neat way to solve this issue would be by removing the OF node only
> > after removing all platform devices/drivers associated with that node. But I
> > honestly do not know whether that is possible or not. Otherwise, any other
> > driver that relies on the OF node in its remove() callback, could suffer from
> > the same issue. And whatever fix we may come up with in PCI core, it will be a
> > band-aid only.
> > 
> > I'd like to check with Rob first about his opinion.
> 
> If the struct device has an of_node set, there should be a reference 
> count on that node. But I think that only prevents the node from being 
> freed. It does not prevent the overlay from being detached. This is one 
> of many of the issues with overlays Frank painstakingly documented[2].
> 

Ah, I do remember this page as Frank ended up creating it based on my
continuous nudge to add CONFIG_FS interface for applying overlays.

So why are we applying overlays in kernel now?

> Perhaps it is just a matter of iterating thru all the nodes in an 
> overlay, getting their driver/device, and forcing them to unbind. 
> Though that has to be done per bus type.
> 

Sounds like the correct approach.

- Mani

-- 
????????? ????????


From granquet at baylibre.com  Mon Dec  2 01:38:07 2024
From: granquet at baylibre.com (Guillaume Ranquet)
Date: Mon, 2 Dec 2024 03:38:07 -0600
Subject: [PATCH v2 1/1] drm/mediatek: Add return value check when reading DPCD
In-Reply-To: <20241128030940.25657-1-liankun.yang@mediatek.com>
References: <20241128030940.25657-1-liankun.yang@mediatek.com>
Message-ID: <CABnWg9tDMkKkFbQpL8YphOBu3_2zr_q4YASnO-UYMrdM22wCuQ@mail.gmail.com>

On Thu, 28 Nov 2024 04:08, Liankun Yang <liankun.yang at mediatek.com> wrote:
>Returns the number of bytes transferred (1) on success.
>Check the return value to confirm that AUX communication is successful.
>
>Fixes: d9e6ea02fc3f ("drm/mediatek: dp: Add MT8195 External DisplayPort support")
>
>Signed-off-by: Liankun Yang <liankun.yang at mediatek.com>
>---
>Changes in V2:
>- Modify Fixes in Commit Message.
>Per suggestion from the previous thread:
>https://patchwork.kernel.org/project/linux-mediatek/patch/20240930092000.5385-1-liankun.yang at mediatek.com/
>---
> drivers/gpu/drm/mediatek/mtk_dp.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
>index 1cc916b16471..9dc68ec2ff43 100644
>--- a/drivers/gpu/drm/mediatek/mtk_dp.c
>+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
>@@ -2101,6 +2101,7 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
> 	enum drm_connector_status ret = connector_status_disconnected;
> 	bool enabled = mtk_dp->enabled;
> 	u8 sink_count = 0;
>+	size_t value;
>
> 	if (!mtk_dp->train_info.cable_plugged_in)
> 		return ret;
>@@ -2115,7 +2116,12 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
> 	 * function, we just need to check the HPD connection to check
> 	 * whether we connect to a sink device.
> 	 */
>-	drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
>+	value = drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
>+	if (value < 0) {
>+		drm_err(mtk_dp->drm_dev, "Failed to read DP Sink Count: %zd\n", value);
>+		return ret;
>+	}
>+
> 	if (DP_GET_SINK_COUNT(sink_count))
> 		ret = connector_status_connected;

Hi Liankun,

thx for your fix.
I think your patch could be improved by using the drm_dp_helper
function drm_dp_read_sink_count() ?

Thx,
Guillaume.

>
>--
>2.45.2


From victor.liu at nxp.com  Mon Dec  2 01:41:49 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 2 Dec 2024 17:41:49 +0800
Subject: [PATCH v5 10/19] drm/imx: Add i.MX8qxp Display Controller pixel
 engine
In-Reply-To: <202412021617.HmlPGJLh-lkp@intel.com>
References: <20241202025635.1274467-11-victor.liu@nxp.com>
 <202412021617.HmlPGJLh-lkp@intel.com>
Message-ID: <bc08993d-3672-452a-a29e-3a85199a0dcb@nxp.com>

On 12/02/2024, kernel test robot wrote:
> Hi Liu,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on shawnguo/for-next]
> [also build test WARNING on linus/master v6.13-rc1 next-20241128]
> [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/Liu-Ying/dt-bindings-display-imx-Add-i-MX8qxp-Display-Controller-processing-units/20241202-110331
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git for-next
> patch link:    https://lore.kernel.org/r/20241202025635.1274467-11-victor.liu%40nxp.com
> patch subject: [PATCH v5 10/19] drm/imx: Add i.MX8qxp Display Controller pixel engine
> config: alpha-allyesconfig (https://download.01.org/0day-ci/archive/20241202/202412021617.HmlPGJLh-lkp at intel.com/config)
> compiler: alpha-linux-gcc (GCC) 14.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241202/202412021617.HmlPGJLh-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/202412021617.HmlPGJLh-lkp at intel.com/
> 
> All warnings (new ones prefixed by >>):
> 
>    drivers/gpu/drm/imx/dc/dc-fl.c: In function 'dc_fl_bind':
>>> drivers/gpu/drm/imx/dc/dc-fl.c:136:57: warning: '%d' directive output may be truncated writing between 1 and 10 bytes into a region of size 3 [-Wformat-truncation=]
>      136 |         snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
>          |                                                         ^~
>    drivers/gpu/drm/imx/dc/dc-fl.c:136:46: note: directive argument in the range [0, 2147483647]
>      136 |         snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
>          |                                              ^~~~~~~~~~~~~~
>    drivers/gpu/drm/imx/dc/dc-fl.c:136:9: note: 'snprintf' output between 12 and 21 bytes into a destination of size 13

Will expand sizeof(fu->name) from 13 to 21.
Thanks for the report.

>      136 |         snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
>          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --
>    drivers/gpu/drm/imx/dc/dc-fw.c: In function 'dc_fw_bind':
>>> drivers/gpu/drm/imx/dc/dc-fw.c:175:56: warning: '%u' directive output may be truncated writing between 1 and 10 bytes into a region of size 4 [-Wformat-truncation=]
>      175 |         snprintf(fu->name, sizeof(fu->name), "FetchWarp%u", fw->id);
>          |                                                        ^~
>    drivers/gpu/drm/imx/dc/dc-fw.c:175:46: note: directive argument in the range [0, 2147483647]
>      175 |         snprintf(fu->name, sizeof(fu->name), "FetchWarp%u", fw->id);
>          |                                              ^~~~~~~~~~~~~
>    drivers/gpu/drm/imx/dc/dc-fw.c:175:9: note: 'snprintf' output between 11 and 20 bytes into a destination of size 13
>      175 |         snprintf(fu->name, sizeof(fu->name), "FetchWarp%u", fw->id);
>          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> 
> vim +136 drivers/gpu/drm/imx/dc/dc-fl.c
> 
>     92	
>     93	static int dc_fl_bind(struct device *dev, struct device *master, void *data)
>     94	{
>     95		struct platform_device *pdev = to_platform_device(dev);
>     96		struct dc_drm_device *dc_drm = data;
>     97		struct dc_pe *pe = dc_drm->pe;
>     98		void __iomem *base_cfg;
>     99		struct dc_fl *fl;
>    100		struct dc_fu *fu;
>    101		int i;
>    102	
>    103		fl = devm_kzalloc(dev, sizeof(*fl), GFP_KERNEL);
>    104		if (!fl)
>    105			return -ENOMEM;
>    106	
>    107		fu = &fl->fu;
>    108	
>    109		base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
>    110		if (IS_ERR(base_cfg))
>    111			return PTR_ERR(base_cfg);
>    112	
>    113		fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
>    114						    &dc_fl_cfg_regmap_config);
>    115		if (IS_ERR(fu->reg_cfg))
>    116			return PTR_ERR(fu->reg_cfg);
>    117	
>    118		fl->id = of_alias_get_id(dev->of_node, "dc0-fetchlayer");
>    119		if (fl->id < 0) {
>    120			dev_err(dev, "failed to get alias id: %d\n", fl->id);
>    121			return fl->id;
>    122		}
>    123	
>    124		fu->link_id = LINK_ID_FETCHLAYER0;
>    125		fu->id = DC_FETCHUNIT_FL0;
>    126		for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
>    127			fu->reg_baseaddr[i]		  = BASEADDRESS(i);
>    128			fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
>    129			fu->reg_sourcebufferdimension[i]  = SOURCEBUFFERDIMENSION(i);
>    130			fu->reg_layeroffset[i]		  = LAYEROFFSET(i);
>    131			fu->reg_clipwindowoffset[i]	  = CLIPWINDOWOFFSET(i);
>    132			fu->reg_clipwindowdimensions[i]	  = CLIPWINDOWDIMENSIONS(i);
>    133			fu->reg_constantcolor[i]	  = CONSTANTCOLOR(i);
>    134			fu->reg_layerproperty[i]	  = LAYERPROPERTY(i);
>    135		}
>  > 136		snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
>    137	
>    138		dc_fl_set_ops(fu);
>    139	
>    140		pe->fu_disp[fu->id] = fu;
>    141	
>    142		return 0;
>    143	}
>    144	
> 

-- 
Regards,
Liu Ying



From suzuki.poulose at arm.com  Mon Dec  2 01:46:55 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 2 Dec 2024 09:46:55 +0000
Subject: [PATCH 3/4] coresight: tmc-etr: Fix race condition between sysfs
 and perf mode
In-Reply-To: <20241202092419.11777-4-yangyicong@huawei.com>
References: <20241202092419.11777-1-yangyicong@huawei.com>
 <20241202092419.11777-4-yangyicong@huawei.com>
Message-ID: <62f5d1c5-05bd-41b6-8703-baacec3e2619@arm.com>

Hi Yicong

On 02/12/2024 09:24, Yicong Yang wrote:
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> When trying to run perf and sysfs mode simultaneously, the WARN_ON()
> in tmc_etr_enable_hw() is triggered sometimes:
> 
>   WARNING: CPU: 42 PID: 3911571 at drivers/hwtracing/coresight/coresight-tmc-etr.c:1060 tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc]
>   [..snip..]
>   Call trace:
>    tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc] (P)
>    tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc] (L)
>    tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc]
>    coresight_enable_path+0x1c8/0x218 [coresight]
>    coresight_enable_sysfs+0xa4/0x228 [coresight]
>    enable_source_store+0x58/0xa8 [coresight]
>    dev_attr_store+0x20/0x40
>    sysfs_kf_write+0x4c/0x68
>    kernfs_fop_write_iter+0x120/0x1b8
>    vfs_write+0x2c8/0x388
>    ksys_write+0x74/0x108
>    __arm64_sys_write+0x24/0x38
>    el0_svc_common.constprop.0+0x64/0x148
>    do_el0_svc+0x24/0x38
>    el0_svc+0x3c/0x130
>    el0t_64_sync_handler+0xc8/0xd0
>    el0t_64_sync+0x1ac/0x1b0
>   ---[ end trace 0000000000000000 ]---
> 
> Since the enablement of sysfs mode is separeted into two critical regions,
> one for sysfs buffer allocation and another for hardware enablement, it's
> possible to race with the perf mode. Fix this by double check whether
> the perf mode's been used before enabling the hardware in sysfs mode.

Thanks for the fix. Some minor comments below.

It needs a Fixes tag.

> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>   .../hwtracing/coresight/coresight-tmc-etr.c   | 30 +++++++++++++++++++
>   1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index ad83714ca4dc..d382d95da5ff 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -1230,6 +1230,36 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
>   
>   	spin_lock_irqsave(&drvdata->spinlock, flags);
>   
> +	/*
> +	 * Since the sysfs buffer allocation and the hardware enablement is not
> +	 * in the same critical region, it's possible to race with the perf
> +	 * mode:
> +	 *   [sysfs mode]                   [perf mode]
> +	 *   tmc_etr_get_sysfs_buffer()
> +	 *     spin_lock(&drvdata->spinlock)
> +	 *     [sysfs buffer allocation]
> +	 *     spin_unlock(&drvdata->spinlock)
> +	 *                                  spin_lock(&drvdata->spinlock)
> +	 *                                  tmc_etr_enable_hw()
> +	 *                                    drvdata->etr_buf = etr_perf->etr_buf
> +	 *                                  spin_unlock(&drvdata->spinlock)
> +	 *   spin_lock(&drvdata->spinlock)
> +	 *   tmc_etr_enable_hw()
> +	 *     WARN_ON(drvdata->etr_buf) // WARN sicne etr_buf initialized at
> +	 *                                  the perf side
> +	 *   spin_unlock(&drvdata->spinlock)
> +	 *
> +	 * So check here before continue.
> +	 */
> +	if (coresight_get_mode(csdev) == CS_MODE_PERF) {
> +		drvdata->sysfs_buf = NULL;
> +		spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +
> +		/* Free allocated memory out side of the spinlock */
> +		tmc_etr_free_sysfs_buf(sysfs_buf);
> +		return -EBUSY;
> +	}

With this in place, I think we should remove the check for CS_MODE_PERF 
in get_etr_sysfs_buf() to avoid confusion (which I believe opened up 
this race)

Suzuki



> +
>   	/*
>   	 * In sysFS mode we can have multiple writers per sink.  Since this
>   	 * sink is already enabled no memory is needed and the HW need not be



From quentin.schulz at cherry.de  Mon Dec  2 01:52:06 2024
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Mon, 2 Dec 2024 10:52:06 +0100
Subject: [PATCH] arm64: dts: rockchip: increase gmac rx_delay to 0x11 on
 rk3399-puma
In-Reply-To: <20241202090408.201662-1-jakob.unterwurzacher@cherry.de>
References: <20241202090408.201662-1-jakob.unterwurzacher@cherry.de>
Message-ID: <63b3be80-cb6c-49e5-858f-70fd826140c5@cherry.de>

Hi Jakob,

On 12/2/24 10:04 AM, Jakob Unterwurzacher wrote:
> During mass manufacturing, we noticed the mmc_rx_crc_error counter,
> as reported by "ethtool -S eth0 | grep mmc_rx_crc_error" to increase
> above zero during nuttcp speedtests.
> 
> Cycling through the rx_delay range on two boards shows that is a large
> "good" region from 0x11 to 0x35 (see below for details).
> 

Is this missing a "there" after that? "that there is a large good region"?

> This commit increases rx_delay to 0x11, which is the smallest
> possible change that fixes the issue we are seeing on the KSZ9031 PHY.
> This also matches what most other rk3399 boards do.
> 
> Tests for Puma PCBA S/N TT0069903:
> 
> 	rx_delay mmc_rx_crc_error
> 	-------- ----------------
> 	0x09 (dhcp broken)
> 	0x10 897
> 	0x11 0
> 	0x20 0
> 	0x30 0
> 	0x35 0
> 	0x3a 745
> 	0x3b 11375
> 	0x3c 36680
> 	0x40 (dhcp broken)
> 	0x7f (dhcp broken)
> 
> Tests for Puma PCBA S/N TT0157733:
> 
> 	rx_delay mmc_rx_crc_error
> 	-------- ----------------
> 	0x10 59
> 	0x11 0
> 	0x35 0
> 
> Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at cherry.de>

This would be a candidate for backporting I believe.

Therefore, a

Cc: <stable at vger.kernel.org>

here would have been nice (in the commit log), c.f. 
https://www.kernel.org/doc/html/latest/process/submitting-patches.html#select-the-recipients-for-your-patch

> ---
>   arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> index 9efcdce0f593..13d0c511046b 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> @@ -181,7 +181,7 @@ &gmac {
>   	snps,reset-active-low;
>   	snps,reset-delays-us = <0 10000 50000>;
>   	tx_delay = <0x10>;
> -	rx_delay = <0x10>;
> +	rx_delay = <0x11>;

While at it, we could reorder this alphabetically and move rx_delay 
between pinctrl-0 and snps,reset-gpio? c.f. 
https://www.kernel.org/doc/html/latest/devicetree/bindings/dts-coding-style.html#order-of-properties-in-device-node 
rx_delay and tx_delay seem to be vendor-specific but without the vendor 
prefix, but so is snps,reset-gpio so that should be fine to reorder this 
way.

Considering we have an option for KSZ9031 on RK3588 Jaguar and RK3588 
Tiger and the "same" MAC IP is used and that we use the same TXD and RXD 
delay than on RK3399 Puma right now, I guess we would want to check 
those don't need a change as well? (funnily enough, all RK3588-based 
boards in 6.12 actually have 0x00 for rx_delay and 0x43/0x44 for 
tx_delay, except ours which are at 0x10). Not a blocker for this patch 
though, so:

Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>

Thanks!
Quentin


From quic_liuxin at quicinc.com  Mon Dec  2 01:54:44 2024
From: quic_liuxin at quicinc.com (Xin Liu)
Date: Mon, 2 Dec 2024 17:54:44 +0800
Subject: [PATCH v3 3/4] arm64: dts: qcom: add QCS8300 platform
In-Reply-To: <2a2a780d-5e3e-4582-b75d-211732a9b727@oss.qualcomm.com>
References: <20241128-qcs8300_initial_dtsi-v3-0-26aa8a164914@quicinc.com>
 <20241128-qcs8300_initial_dtsi-v3-3-26aa8a164914@quicinc.com>
 <2a2a780d-5e3e-4582-b75d-211732a9b727@oss.qualcomm.com>
Message-ID: <4c39e6f8-22d2-4568-9116-01294f85a283@quicinc.com>



? 2024/11/29 4:14, Konrad Dybcio ??:
> On 28.11.2024 9:44 AM, Jingyi Wang wrote:
>> Add initial DTSI for QCS8300 SoC.
>>
>> Features added in this revision:
>> - CPUs with PSCI idle states
>> - Interrupt-controller with PDC wakeup support
>> - Timers, TCSR Clock Controllers
>> - Reserved Shared memory
>> - GCC and RPMHCC
>> - TLMM
>> - Interconnect
>> - QuP with uart
>> - SMMU
>> - QFPROM
>> - Rpmhpd power controller
>> - UFS
>> - Inter-Processor Communication Controller
>> - SRAM
>> - Remoteprocs including ADSP,CDSP and GPDSP
>> - BWMONs
>>
>> Written with help from Zhenhua Huang(added the smmu node), Xin Liu(added
>> ufs, adsp and gpdsp nodes), Tingguo Cheng(added the rpmhpd node), Kyle
>> Deng(added the aoss_qmp node), Raviteja Laggyshetty(added interconnect
>> nodes) and Cong Zhang(added the INTID of EL2 non-secure physical timer).
>>
>> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
>> ---
> 
> [...]
> 
>> +		cpu-map {
>> +			cluster0 {
>> +				core0 {
>> +					cpu = <&cpu0>;
>> +				};
>> +
>> +				core1 {
>> +					cpu = <&cpu1>;
>> +				};
>> +
>> +				core2 {
>> +					cpu = <&cpu2>;
>> +				};
>> +
>> +				core3 {
>> +					cpu = <&cpu3>;
>> +				};
>> +
>> +				core4 {
>> +					cpu = <&cpu4>;
>> +				};
> 
> The MPIDR_EL1 register value (CPU node reg) suggests they are not
> part of the same cluster (as you confirmed in the psci idle domains
> description)
> 
> [...]
> 
>> +
>> +		ufs_mem_hc: ufs at 1d84000 {
>> +			compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
>> +			reg = <0x0 0x01d84000 0x0 0x3000>;
>> +			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
>> +			phys = <&ufs_mem_phy>;
>> +			phy-names = "ufsphy";
>> +			lanes-per-direction = <2>;
>> +			#reset-cells = <1>;
>> +			resets = <&gcc GCC_UFS_PHY_BCR>;
>> +			reset-names = "rst";
>> +
>> +			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
>> +			required-opps = <&rpmhpd_opp_nom>;
>> +
>> +			iommus = <&apps_smmu 0x100 0x0>;
>> +			dma-coherent;
>> +
>> +			interconnects = <&aggre1_noc MASTER_UFS_MEM 0
> 
> QCOM_ICC_TAG_ALWAYS, file-wide
> 
> [...]
> 
>> +		ufs_mem_phy: phy at 1d87000 {
>> +			compatible = "qcom,qcs8300-qmp-ufs-phy", "qcom,sa8775p-qmp-ufs-phy";
>> +			reg = <0x0 0x01d87000 0x0 0xe10>;
>> +			/*
>> +			 * Yes, GCC_EDP_REF_CLKREF_EN is correct in qref. It
>> +			 * enables the CXO clock to eDP *and* UFS PHY.
>> +			 */
>> +			clocks = <&rpmhcc RPMH_CXO_CLK>,
>> +				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
>> +				 <&gcc GCC_EDP_REF_CLKREF_EN>;
> 
> Are you sure about this, or is this just copypasted from sa8775p?
Thank you for your comments. I confirm with the colleague responsible 
for this area, and configuring the clock this way is correct.
> 
> [...]
> 
>> +
>> +		intc: interrupt-controller at 17a00000 {
>> +			compatible = "arm,gic-v3";
>> +			reg = <0x0 0x17a00000 0x0 0x10000>,     /* GICD */
>> +			      <0x0 0x17a60000 0x0 0x100000>;    /* GICR * 8 */
> 
> Drop these comments
> 
>> +			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
>> +			#interrupt-cells = <3>;
>> +			interrupt-controller;
>> +			#redistributor-regions = <1>;
>> +			redistributor-stride = <0x0 0x20000>;
>> +		};
>> +
>> +		memtimer: timer at 17c20000 {
> 
> Unused label
> 
> [...]
> 
>> +	arch_timer: timer {
> 
> Ditto
> 
> Konrad



From mark.rutland at arm.com  Mon Dec  2 01:55:56 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 2 Dec 2024 09:55:56 +0000
Subject: [boot-wrapper v5] aarch64: Start Xen on Armv8-R at EL2
In-Reply-To: <D246D077-897A-43AF-9B7F-38990A1800B2@arm.com>
References: <20241127102300.2822848-1-luca.fancellu@arm.com>
 <Z0hOCh16ThvfN-Jr@J2N7QTR9R3>
 <D246D077-897A-43AF-9B7F-38990A1800B2@arm.com>
Message-ID: <Z02ELNY-6PA3wcK7@J2N7QTR9R3>

On Thu, Nov 28, 2024 at 11:06:14AM +0000, Luca Fancellu wrote:
> > On 28 Nov 2024, at 11:03, Mark Rutland <mark.rutland at arm.com> wrote:
> > On Wed, Nov 27, 2024 at 10:23:00AM +0000, Luca Fancellu wrote:
> >> When bootwrapper is compiled with Xen support and it is started
> >> at EL2 on Armv8-R AArch64, keep the current EL and jump to the
> >> Xen image using the SPSR_KERNEL as spsr_el2 value.
> >>
> >> The only available boot method on Armv8-R AArch64 when starting
> >> Xen is spin table at the moment, reflect this in the build
> >> configuration.
> >>
> >> Signed-off-by: Luca Fancellu <luca.fancellu at arm.com>

> >> +# Don't allow PSCI + Xen + aarch64-r
> >> +AS_IF([test "x$USE_PSCI" = "xyes" -a "x$USE_ARCH" = "xaarch64-r" -a "x$X_IMAGE" != "x"],
> >> + [AC_MSG_ERROR([With aarch64-r and Xen, PSCI must be disabled.])]
> >> +)
> >
> > I'll delete the comment and change the message here to:
> >
> > With an AArch64-R Xen, boot method must be spin-table.
> >
> > ... since that's consistent with the other message above:
> >
> > With an AArch32 kernel, boot method must be PSCI.
> >
> > ... and it's slightly nicer to tell the user what will work rather than
> > what won't work.
> >
> > Otherwise this looks fine to me, and I will apply this shortly (with
> > those changes) if no-one objects.
> 
> Sounds good to me! Thanks!

Thanks; applied (with those fixups).

Mark.


From heiko at sntech.de  Mon Dec  2 01:56:55 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 02 Dec 2024 10:56:55 +0100
Subject: [PATCH] arm64: dts: rockchip: increase gmac rx_delay to 0x11 on
 rk3399-puma
In-Reply-To: <63b3be80-cb6c-49e5-858f-70fd826140c5@cherry.de>
References: <20241202090408.201662-1-jakob.unterwurzacher@cherry.de>
 <63b3be80-cb6c-49e5-858f-70fd826140c5@cherry.de>
Message-ID: <2578458.4XsnlVU6TS@diego>

Am Montag, 2. Dezember 2024, 10:52:06 CET schrieb Quentin Schulz:
> Hi Jakob,
> 
> On 12/2/24 10:04 AM, Jakob Unterwurzacher wrote:
> > During mass manufacturing, we noticed the mmc_rx_crc_error counter,
> > as reported by "ethtool -S eth0 | grep mmc_rx_crc_error" to increase
> > above zero during nuttcp speedtests.
> > 
> > Cycling through the rx_delay range on two boards shows that is a large
> > "good" region from 0x11 to 0x35 (see below for details).
> > 
> 
> Is this missing a "there" after that? "that there is a large good region"?
> 
> > This commit increases rx_delay to 0x11, which is the smallest
> > possible change that fixes the issue we are seeing on the KSZ9031 PHY.
> > This also matches what most other rk3399 boards do.
> > 
> > Tests for Puma PCBA S/N TT0069903:
> > 
> > 	rx_delay mmc_rx_crc_error
> > 	-------- ----------------
> > 	0x09 (dhcp broken)
> > 	0x10 897
> > 	0x11 0
> > 	0x20 0
> > 	0x30 0
> > 	0x35 0
> > 	0x3a 745
> > 	0x3b 11375
> > 	0x3c 36680
> > 	0x40 (dhcp broken)
> > 	0x7f (dhcp broken)
> > 
> > Tests for Puma PCBA S/N TT0157733:
> > 
> > 	rx_delay mmc_rx_crc_error
> > 	-------- ----------------
> > 	0x10 59
> > 	0x11 0
> > 	0x35 0
> > 
> > Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at cherry.de>
> 
> This would be a candidate for backporting I believe.
> 
> Therefore, a

also please include a

Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")

> Cc: <stable at vger.kernel.org>
> 
> here would have been nice (in the commit log), c.f. 
> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#select-the-recipients-for-your-patch
> 
> > ---
> >   arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> > index 9efcdce0f593..13d0c511046b 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> > @@ -181,7 +181,7 @@ &gmac {
> >   	snps,reset-active-low;
> >   	snps,reset-delays-us = <0 10000 50000>;
> >   	tx_delay = <0x10>;
> > -	rx_delay = <0x10>;
> > +	rx_delay = <0x11>;
> 
> While at it, we could reorder this alphabetically and move rx_delay 

I would disagree. This is a "fix", so should ideally only do the minimal
changes to make life of the stable people easier.

Doing this one-line change is way easier to understand than stuff also
moving around.

Heiko

> between pinctrl-0 and snps,reset-gpio? c.f. 
> https://www.kernel.org/doc/html/latest/devicetree/bindings/dts-coding-style.html#order-of-properties-in-device-node 
> rx_delay and tx_delay seem to be vendor-specific but without the vendor 
> prefix, but so is snps,reset-gpio so that should be fine to reorder this 
> way.
> 
> Considering we have an option for KSZ9031 on RK3588 Jaguar and RK3588 
> Tiger and the "same" MAC IP is used and that we use the same TXD and RXD 
> delay than on RK3399 Puma right now, I guess we would want to check 
> those don't need a change as well? (funnily enough, all RK3588-based 
> boards in 6.12 actually have 0x00 for rx_delay and 0x43/0x44 for 
> tx_delay, except ours which are at 0x10). Not a blocker for this patch 
> though, so:
> 
> Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>
> 
> Thanks!
> Quentin
> 






From quic_jingyw at quicinc.com  Mon Dec  2 02:00:25 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Mon, 2 Dec 2024 18:00:25 +0800
Subject: [PATCH v3 3/4] arm64: dts: qcom: add QCS8300 platform
In-Reply-To: <2a2a780d-5e3e-4582-b75d-211732a9b727@oss.qualcomm.com>
References: <20241128-qcs8300_initial_dtsi-v3-0-26aa8a164914@quicinc.com>
 <20241128-qcs8300_initial_dtsi-v3-3-26aa8a164914@quicinc.com>
 <2a2a780d-5e3e-4582-b75d-211732a9b727@oss.qualcomm.com>
Message-ID: <80b1a205-422f-4e6d-97e9-69ee335a31f8@quicinc.com>



On 11/29/2024 4:14 AM, Konrad Dybcio wrote:
> On 28.11.2024 9:44 AM, Jingyi Wang wrote:
>> Add initial DTSI for QCS8300 SoC.
>>
>> Features added in this revision:
>> - CPUs with PSCI idle states
>> - Interrupt-controller with PDC wakeup support
>> - Timers, TCSR Clock Controllers
>> - Reserved Shared memory
>> - GCC and RPMHCC
>> - TLMM
>> - Interconnect
>> - QuP with uart
>> - SMMU
>> - QFPROM
>> - Rpmhpd power controller
>> - UFS
>> - Inter-Processor Communication Controller
>> - SRAM
>> - Remoteprocs including ADSP,CDSP and GPDSP
>> - BWMONs
>>
>> Written with help from Zhenhua Huang(added the smmu node), Xin Liu(added
>> ufs, adsp and gpdsp nodes), Tingguo Cheng(added the rpmhpd node), Kyle
>> Deng(added the aoss_qmp node), Raviteja Laggyshetty(added interconnect
>> nodes) and Cong Zhang(added the INTID of EL2 non-secure physical timer).
>>
>> Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
>> ---
> 
> [...]
> 
>> +		cpu-map {
>> +			cluster0 {
>> +				core0 {
>> +					cpu = <&cpu0>;
>> +				};
>> +
>> +				core1 {
>> +					cpu = <&cpu1>;
>> +				};
>> +
>> +				core2 {
>> +					cpu = <&cpu2>;
>> +				};
>> +
>> +				core3 {
>> +					cpu = <&cpu3>;
>> +				};
>> +
>> +				core4 {
>> +					cpu = <&cpu4>;
>> +				};
> 
> The MPIDR_EL1 register value (CPU node reg) suggests they are not
> part of the same cluster (as you confirmed in the psci idle domains
> description)
> 
will separate into 2 clusters.
> [...]
> 
>> +
>> +		ufs_mem_hc: ufs at 1d84000 {
>> +			compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
>> +			reg = <0x0 0x01d84000 0x0 0x3000>;
>> +			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
>> +			phys = <&ufs_mem_phy>;
>> +			phy-names = "ufsphy";
>> +			lanes-per-direction = <2>;
>> +			#reset-cells = <1>;
>> +			resets = <&gcc GCC_UFS_PHY_BCR>;
>> +			reset-names = "rst";
>> +
>> +			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
>> +			required-opps = <&rpmhpd_opp_nom>;
>> +
>> +			iommus = <&apps_smmu 0x100 0x0>;
>> +			dma-coherent;
>> +
>> +			interconnects = <&aggre1_noc MASTER_UFS_MEM 0
> 
> QCOM_ICC_TAG_ALWAYS, file-wide
> 
well noted.
> [...]
> 
>> +		ufs_mem_phy: phy at 1d87000 {
>> +			compatible = "qcom,qcs8300-qmp-ufs-phy", "qcom,sa8775p-qmp-ufs-phy";
>> +			reg = <0x0 0x01d87000 0x0 0xe10>;
>> +			/*
>> +			 * Yes, GCC_EDP_REF_CLKREF_EN is correct in qref. It
>> +			 * enables the CXO clock to eDP *and* UFS PHY.
>> +			 */
>> +			clocks = <&rpmhcc RPMH_CXO_CLK>,
>> +				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
>> +				 <&gcc GCC_EDP_REF_CLKREF_EN>;
> 
> Are you sure about this, or is this just copypasted from sa8775p?
> 
> [...]
> 
>> +
>> +		intc: interrupt-controller at 17a00000 {
>> +			compatible = "arm,gic-v3";
>> +			reg = <0x0 0x17a00000 0x0 0x10000>,     /* GICD */
>> +			      <0x0 0x17a60000 0x0 0x100000>;    /* GICR * 8 */
> 
> Drop these comments
> 
well noted.
>> +			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
>> +			#interrupt-cells = <3>;
>> +			interrupt-controller;
>> +			#redistributor-regions = <1>;
>> +			redistributor-stride = <0x0 0x20000>;
>> +		};
>> +
>> +		memtimer: timer at 17c20000 {
> 
> Unused label
> 
well noted.
> [...]
> 
>> +	arch_timer: timer {
> 
> Ditto
> 
well noted.
> Konrad

Thanks,
Jingyi


From ardb at kernel.org  Mon Dec  2 02:01:18 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 2 Dec 2024 11:01:18 +0100
Subject: [PATCH] arm64/mm: Drop INIT_MM_CONTEXT()
In-Reply-To: <20241202043553.29592-1-anshuman.khandual@arm.com>
References: <20241202043553.29592-1-anshuman.khandual@arm.com>
Message-ID: <CAMj1kXGPcMYsJV9w_fBXEyxUJFGZhSpn2etWie9wKA_HS3kF_g@mail.gmail.com>

On Mon, 2 Dec 2024 at 05:36, Anshuman Khandual
<anshuman.khandual at arm.com> wrote:
>
> Platform override for INIT_MM_CONTEXT() is redundant because swapper_pg_dir
> always gets assigned as the pgd during init_mm initialization. So just drop
> this override on arm64.
>
> Originally this override was added via the 'commit 2b5548b68199 ("arm64/mm:
> Separate boot-time page tables from swapper_pg_dir")' because non standard
> init_pg_dir was assigned as the pgd. Subsequently it was changed as default
> swapper_pg_dir by the 'commit ba5b0333a847 ("arm64: mm: omit redundant
> remap of kernel image")', which might have also just dropped this override.
>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Ryan Roberts <ryan.roberts at arm.com>
> 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>

Acked-by: Ard Biesheuvel <ardb at kernel.org>

> ---
> This patch applies on v6.13-rc1
>
>  arch/arm64/include/asm/mmu.h | 3 ---
>  1 file changed, 3 deletions(-)
>
> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
> index 2ec96d91acc6..662471cfc536 100644
> --- a/arch/arm64/include/asm/mmu.h
> +++ b/arch/arm64/include/asm/mmu.h
> @@ -109,8 +109,5 @@ static inline bool kaslr_requires_kpti(void)
>         return true;
>  }
>
> -#define INIT_MM_CONTEXT(name)  \
> -       .pgd = swapper_pg_dir,
> -
>  #endif /* !__ASSEMBLY__ */
>  #endif
> --
> 2.30.2
>


From m-malladi at ti.com  Mon Dec  2 02:07:06 2024
From: m-malladi at ti.com (Malladi, Meghana)
Date: Mon, 2 Dec 2024 15:37:06 +0530
Subject: [PATCH net v2 1/2] net: ti: icssg-prueth: Fix firmware load
 sequence.
In-Reply-To: <a4071a1c-8c27-4464-9054-df9b3e317eab@kernel.org>
References: <20241128122931.2494446-1-m-malladi@ti.com>
 <20241128122931.2494446-2-m-malladi@ti.com>
 <a4071a1c-8c27-4464-9054-df9b3e317eab@kernel.org>
Message-ID: <9e06da02-52d1-48b3-84d2-d67789e42077@ti.com>



On 11/29/2024 6:26 PM, Roger Quadros wrote:
> Hi,
> 
> On 28/11/2024 14:29, Meghana Malladi wrote:
>> From: MD Danish Anwar <danishanwar at ti.com>
>>
>> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
>> and SLICE1. Currently whenever any ICSSG interface comes up we load the
>> respective firmwares to PRU cores and whenever interface goes down, we
>> stop the resective cores. Due to this, when SLICE0 goes down while
>> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
>> stopped. This results in clock jump for SLICE1 interface as the timesync
>> related operations are no longer running.
>>
>> As there are interdependencies between SLICE0 and SLICE1 firmwares,
>> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
>> ICSSG interface is up.
>>
>> Use emacs_initialized as reference count to load the firmwares for the
>> first and last interface up/down. Moving init_emac_mode and fw_offload_mode
>> API outside of icssg_config to icssg_common_start API as they need
>> to be called only once per firmware boot.
>>
>> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
>> ---
>>
>> Hi all,
>>
>> This patch is based on net-next tagged next-2024110.
>> v1:https://lore.kernel.org/all/20241106074040.3361730-2-m-malladi at ti.com
>>
>> Changes since v1 (v2-v1):
>> - Moving the NULL check inside the function as suggested by
>> Simon Horman <horms at kernel.org>
>> - Introduce prueth_emac_common_start() and prueth_emac_common_stop()
>> and move common code there as suggested by Roger Quadros <rogerq at kernel.org>
>> - Moving init_emac_mode and fw_offload_mode API outside of icssg_config
>> to icssg_common_start API as they need to be called only once per
>> firmware boot
>>
>>   drivers/net/ethernet/ti/icssg/icssg_config.c |  45 ++++--
>>   drivers/net/ethernet/ti/icssg/icssg_config.h |   1 +
>>   drivers/net/ethernet/ti/icssg/icssg_prueth.c | 150 ++++++++++++-------
>>   drivers/net/ethernet/ti/icssg/icssg_prueth.h |   3 +
>>   4 files changed, 133 insertions(+), 66 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
>> index 5d2491c2943a..342150756cf7 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_config.c
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
>> @@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>>   	return 0;
>>   }
>>   
>> -static void icssg_init_emac_mode(struct prueth *prueth)
>> +void icssg_init_emac_mode(struct prueth *prueth)
>>   {
>>   	/* When the device is configured as a bridge and it is being brought
>>   	 * back to the emac mode, the host mac address has to be set as 0.
>> @@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>>   	int i;
>>   	u8 mac[ETH_ALEN] = { 0 };
>>   
>> -	if (prueth->emacs_initialized)
>> -		return;
>> -
>>   	/* Set VLAN TABLE address base */
>>   	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>>   			   addr <<  SMEM_VLAN_OFFSET);
>> @@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>>   	/* Clear host MAC address */
>>   	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
>>   }
>> +EXPORT_SYMBOL_GPL(icssg_init_emac_mode);
>>   
>> -static void icssg_init_fw_offload_mode(struct prueth *prueth)
>> +void icssg_init_fw_offload_mode(struct prueth *prueth)
>>   {
>>   	u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET;
>>   	int i;
>>   
>> -	if (prueth->emacs_initialized)
>> -		return;
>> -
>>   	/* Set VLAN TABLE address base */
>>   	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>>   			   addr <<  SMEM_VLAN_OFFSET);
>> @@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth)
>>   		icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr);
>>   	icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST);
>>   }
>> +EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode);
>>   
>>   int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>>   {
>> @@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>>   	struct icssg_flow_cfg __iomem *flow_cfg;
>>   	int ret;
>>   
>> -	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>> -		icssg_init_fw_offload_mode(prueth);
>> -	else
>> -		icssg_init_emac_mode(prueth);
>> -
>>   	memset_io(config, 0, TAS_GATE_MASK_LIST0);
>>   	icssg_miig_queues_init(prueth, slice);
>>   
>> @@ -786,3 +777,31 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port)
>>   		writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET);
>>   }
>>   EXPORT_SYMBOL_GPL(icssg_set_pvid);
>> +
>> +int emac_fdb_flow_id_updated(struct prueth_emac *emac)
>> +{
>> +	struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
>> +	int slice = prueth_emac_slice(emac);
>> +	struct mgmt_cmd fdb_cmd = { 0 };
>> +	int ret = 0;
>> +
>> +	fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
>> +	fdb_cmd.type   = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
>> +	fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq);
>> +	fdb_cmd.param  = 0;
>> +
>> +	fdb_cmd.param |= (slice << 4);
>> +	fdb_cmd.cmd_args[0] = 0;
>> +
>> +	ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp);
>> +
>> +	if (ret)
>> +		return ret;
>> +
>> +	WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum);
>> +	if (fdb_cmd_rsp.status == 1)
>> +		return 0;
>> +
>> +	return -EINVAL;
>> +}
>> +EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated);
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
>> index 92c2deaa3068..c884e9fa099e 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_config.h
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
>> @@ -55,6 +55,7 @@ struct icssg_rxq_ctx {
>>   #define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
>>   #define ICSSG_FW_MGMT_CMD_TYPE		0x04
>>   #define ICSSG_FW_MGMT_PKT		0x80000000
>> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW	0x05
>>   
>>   struct icssg_r30_cmd {
>>   	u32 cmd[4];
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> index c568c84a032b..3a495b5d010c 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> @@ -164,11 +164,11 @@ static struct icssg_firmwares icssg_emac_firmwares[] = {
>>   	}
>>   };
>>   
>> -static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>> +static int prueth_emac_start(struct prueth *prueth, int slice)
>>   {
>>   	struct icssg_firmwares *firmwares;
>>   	struct device *dev = prueth->dev;
>> -	int slice, ret;
>> +	int ret;
>>   
>>   	if (prueth->is_switch_mode)
>>   		firmwares = icssg_switch_firmwares;
>> @@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>   	else
>>   		firmwares = icssg_emac_firmwares;
>>   
>> -	slice = prueth_emac_slice(emac);
>> -	if (slice < 0) {
>> -		netdev_err(emac->ndev, "invalid port\n");
>> -		return -EINVAL;
>> -	}
>> -
>> -	ret = icssg_config(prueth, emac, slice);
>> -	if (ret)
>> -		return ret;
>> -
>>   	ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
>>   	ret = rproc_boot(prueth->pru[slice]);
>>   	if (ret) {
>> @@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>   		goto halt_rtu;
>>   	}
>>   
>> -	emac->fw_running = 1;
>>   	return 0;
>>   
>>   halt_rtu:
>> @@ -220,6 +209,77 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>   	return ret;
>>   }
>>   
>> +static int prueth_emac_common_start(struct prueth *prueth)
>> +{
>> +	struct prueth_emac *emac;
>> +	int slice, ret;
>> +
>> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>> +		return -EINVAL;
>> +
>> +	/* clear SMEM and MSMC settings for all slices */
>> +	memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
>> +	memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
>> +
>> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
>> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
>> +
>> +	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>> +		icssg_init_fw_offload_mode(prueth);
>> +	else
>> +		icssg_init_emac_mode(prueth);
>> +
>> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>> +		emac = prueth->emac[slice];
>> +		if (emac) {
>> +			ret = icssg_config(prueth, emac, slice);
>> +			if (ret)
>> +				return ret;
>> +		}
>> +		ret = prueth_emac_start(prueth, slice);
> 
> if (ret)
> 	return ret;
> 
>> +		if (!ret && emac)
> 
> Then no need to check for !ret
> 

To set emac->fw_running to 1, we need to ensure all the firmwares 
started without any failures, hence checking for !ret from 
prueth_emac_start and non-NULL emac before setting emac->fw_running to 1.

>> +			emac->fw_running = 1;
>> +	}
>> +
>> +	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>> +	       prueth->emac[ICSS_SLICE1];
>> +	ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>> +			    emac, IEP_DEFAULT_CYCLE_TIME_NS);
>> +	if (ret) {
>> +		dev_err(prueth->dev, "Failed to initialize IEP module\n");
>> +		return ret;
>> +	}
> 
> If we return error anywhere in this function will the caller take
> care of cleaning up?
> i.e. icssg_class_disable(), stopping any started cores, icss_iep_exit?
> 

No, caller of this function doesn't take care of the cleaning. What do 
you think about adding appropriate labels inside
prueth_emac_common_start() to handle error cases instead of letting the 
caller handle them ?

> You can't rely on prueth_emac_common_stop() as all cores might not
> have started and iep_init may not have been called.
> But you can if you check and call only if required.
> e.g. fw_running flag can be used to track if cores were started.
> 

Yes agreed. I will add this change and call prueth_emac_common_stop() in 
case of failure.

>> +
> 
> Shouldn't we be setting emacs->initialized here and get rid of doing that
> in emac_ndo_open()?
> 
> then you can track it to call icss_iep_exit().
> 

No. I have tried that, but emacs->initialized is needed by the caller to 
call prueth_emac_common_start() and prueth_emac_common_stop() only once. 
Moving this inside will cause above two functions to never get called.
Also we should have a good placeholder for emacs->initialized++/--, 
which is inside ndo_open() and ndo_stop().

>> +	return 0;
>> +}
>> +
>> +static int prueth_emac_common_stop(struct prueth *prueth)
>> +{
>> +	struct prueth_emac *emac;
>> +	int slice;
>> +
>> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>> +		return -EINVAL;
>> +
>> +	icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
>> +	icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
>> +
>> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>> +		emac = prueth->emac[slice];
>> +		rproc_shutdown(prueth->txpru[slice]);
>> +		rproc_shutdown(prueth->rtu[slice]);
>> +		rproc_shutdown(prueth->pru[slice]);
>> +		if (emac)
>> +			emac->fw_running = 0;
>> +	}
>> +
>> +	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>> +	       prueth->emac[ICSS_SLICE1];
>> +	icss_iep_exit(emac->iep);
>> +
> 
> emacs->initialized = 0;
> 

This is already handled inside ndo_stop().

>> +	return 0;
>> +}
>> +
>>   /* called back by PHY layer if there is change in link state of hw port*/
>>   static void emac_adjust_link(struct net_device *ndev)
>>   {
>> @@ -543,23 +603,17 @@ 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;
>> +	struct icssg_flow_cfg __iomem *flow_cfg;
>>   	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, false);
> 
> This is changing existing behaviour.
> If network device is stopped and started we expect all classifiers to be set to defaults?
> 

This is an expected change. When the firmwares are loaded the firmware 
sets the correct classifier values for that slice. Since we are loading 
firmwares for both the slices at once, we need to set the classifiers to 
default before firmware load to avoid overwriting these values after the 
firmware load.

>>   	icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
>>   
>>   	/* Notify the stack of the actual queue counts. */
>> @@ -597,18 +651,23 @@ static int emac_ndo_open(struct net_device *ndev)
>>   		goto cleanup_napi;
>>   	}
>>   
>> -	/* reset and start PRU firmware */
>> -	ret = prueth_emac_start(prueth, emac);
>> -	if (ret)
>> -		goto free_rx_irq;
>> +	if (!prueth->emacs_initialized) {
>> +		ret = prueth_emac_common_start(prueth);
>> +		if (ret)
>> +			goto free_rx_irq;
> 
> goto stop;
> 
> so you can use pruet_emac_common_stop() to do the necessary cleanup.
> 

Yeah ok.

>> +	}
>>   
>> -	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>> +	flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
>> +	writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
>> +	ret = emac_fdb_flow_id_updated(emac);
>>   
>> -	if (!prueth->emacs_initialized) {
>> -		ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>> -				    emac, IEP_DEFAULT_CYCLE_TIME_NS);
>> +	if (ret) {
>> +		netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
>> +		goto stop;
>>   	}
>>   
>> +	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>> +
>>   	ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
>>   				   IRQF_ONESHOT, dev_name(dev), emac);
>>   	if (ret)
>> @@ -653,7 +712,7 @@ static int emac_ndo_open(struct net_device *ndev)
>>   free_tx_ts_irq:
>>   	free_irq(emac->tx_ts_irq, emac);
>>   stop:
>> -	prueth_emac_stop(emac);
>> +	prueth_emac_common_stop(prueth);
>>   free_rx_irq:
>>   	free_irq(emac->rx_chns.irq[rx_flow], emac);
>>   cleanup_napi:
>> @@ -689,8 +748,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>>   	if (ndev->phydev)
>>   		phy_stop(ndev->phydev);
>>   
>> -	icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
>> -
>>   	if (emac->prueth->is_hsr_offload_mode)
>>   		__dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
>>   	else
>> @@ -729,10 +786,8 @@ static int emac_ndo_stop(struct net_device *ndev)
>>   	cancel_delayed_work_sync(&emac->stats_work);
>>   
>>   	if (prueth->emacs_initialized == 1)
>> -		icss_iep_exit(emac->iep);
>> -
>> -	/* stop PRUs */
>> -	prueth_emac_stop(emac);
>> +		/* stop PRUs */
>> +		prueth_emac_common_stop(prueth);
> 
> You don't need this anymore as we will rely on stop: label to call
> prueth_emac_common_stop();
> 

But this is inside emac_ndo_stop(), why do we need label here?

>>   
>>   	free_irq(emac->tx_ts_irq, emac);
>>   
>> @@ -1069,16 +1124,10 @@ static void prueth_emac_restart(struct prueth *prueth)
>>   	icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
>>   
>>   	/* Stop both pru cores for both PRUeth ports*/
>> -	prueth_emac_stop(emac0);
>> -	prueth->emacs_initialized--;
>> -	prueth_emac_stop(emac1);
>> -	prueth->emacs_initialized--;
>> +	prueth_emac_common_stop(prueth);
>>   
>>   	/* Start both pru cores for both PRUeth ports */
>> -	prueth_emac_start(prueth, emac0);
>> -	prueth->emacs_initialized++;
>> -	prueth_emac_start(prueth, emac1);
>> -	prueth->emacs_initialized++;
>> +	prueth_emac_common_start(prueth);
>>   
>>   	/* Enable forwarding for both PRUeth ports */
>>   	icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
>> @@ -1413,13 +1462,10 @@ static int prueth_probe(struct platform_device *pdev)
>>   		prueth->pa_stats = NULL;
>>   	}
>>   
>> -	if (eth0_node) {
>> +	if (eth0_node || eth1_node) {
>>   		ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
>>   		if (ret)
>>   			goto put_cores;
>> -	}
>> -
>> -	if (eth1_node) {
>>   		ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
>>   		if (ret)
>>   			goto put_cores;
>> @@ -1618,14 +1664,12 @@ static int prueth_probe(struct platform_device *pdev)
>>   	pruss_put(prueth->pruss);
>>   
>>   put_cores:
>> -	if (eth1_node) {
>> -		prueth_put_cores(prueth, ICSS_SLICE1);
>> -		of_node_put(eth1_node);
>> -	}
>> -
>> -	if (eth0_node) {
>> +	if (eth0_node || eth1_node) {
>>   		prueth_put_cores(prueth, ICSS_SLICE0);
>>   		of_node_put(eth0_node);
>> +
>> +		prueth_put_cores(prueth, ICSS_SLICE1);
>> +		of_node_put(eth1_node);
>>   	}
>>   
>>   	return ret;
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> index f5c1d473e9f9..9fc72614d990 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> @@ -361,6 +361,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
>>   			 enum icssg_port_state_cmd state);
>>   void icssg_config_set_speed(struct prueth_emac *emac);
>>   void icssg_config_half_duplex(struct prueth_emac *emac);
>> +void icssg_init_emac_mode(struct prueth *prueth);
>> +void icssg_init_fw_offload_mode(struct prueth *prueth);
>>   
>>   /* Buffer queue helpers */
>>   int icssg_queue_pop(struct prueth *prueth, u8 queue);
>> @@ -377,6 +379,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
>>   		       u8 untag_mask, bool add);
>>   u16 icssg_get_pvid(struct prueth_emac *emac);
>>   void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
>> +int emac_fdb_flow_id_updated(struct prueth_emac *emac);
>>   #define prueth_napi_to_tx_chn(pnapi) \
>>   	container_of(pnapi, struct prueth_tx_chn, napi_tx)
>>   
> 



From romain.naour at smile.fr  Mon Dec  2 02:11:40 2024
From: romain.naour at smile.fr (Romain Naour)
Date: Mon,  2 Dec 2024 11:11:40 +0100
Subject: [PATCHv2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable ACSPCIE output for PCIe1
Message-ID: <20241202101140.48778-1-romain.naour@smile.fr>

From: Romain Naour <romain.naour at skf.com>

Unlike the SK-TDA4VM (k3-j721e-sk) board, there is no clock generator
(CDCI6214RGET) on the BeagleBone AI-64 (k3-j721e-beagleboneai64) to
provide PCIe refclk signal to PCIe Endponts. So the ACSPCIE module must
provide refclk through PCIe_REFCLK pins.

Use the new "ti,syscon-acspcie-proxy-ctrl" property to enable ACSPCIE
module's PAD IO Buffers.

Reuse the compatible "ti,j784s4-acspcie-proxy-ctrl" since the ACSPCIE
buffer and its functionality is the same across all K3 SoCs.

Cc: Siddharth Vadapalli <s-vadapalli at ti.com>
Signed-off-by: Romain Naour <romain.naour at skf.com>
---
With this patch, we can remove "HACK: Sierra: Drive clock out" patch
applied on vendor kernel for BeagleBone AI-64:
https://openbeagle.org/beagleboard/linux/-/commit/ad65d7ef675966cdbc5d75f2bd545fad1914ba9b

v2:
 - use generic style comments
 - use "syscon" as generic node name for "acspcie0_proxy_ctrl" node
 - Keep the compatible "ti,j784s4-acspcie-proxy-ctrl" since the
   ACSPCIE buffer and its functionality is the same across all K3 SoCs.
   (Siddharth Vadapalli)

   "The compatible "ti,j784s4-acspcie-pcie-ctrl" should be reused for
   J721E and all other K3 SoCs.
   For example, see:
   https://lore.kernel.org/r/20240402105708.4114146-1-s-vadapalli at ti.com/
   which introduced "ti,am62p-cpsw-mac-efuse" compatible.

   The same compatible is reused across all K3 SoCs:
   https://lore.kernel.org/r/20240628151518.40100-1-afd at ti.com/ "
---
 arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts |  5 +++++
 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi          | 10 ++++++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
index fb899c99753e..741ad2ba6fdb 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
@@ -859,6 +859,11 @@ &pcie1_rc {
 	num-lanes = <2>;
 	max-link-speed = <3>;
 	reset-gpios = <&main_gpio0 22 GPIO_ACTIVE_HIGH>;
+	/*
+	 * There is no on-board or external reference clock generators,
+	 * use refclk from the ACSPCIE module's PAD IO Buffers.
+	 */
+	ti,syscon-acspcie-proxy-ctrl = <&acspcie0_proxy_ctrl 0x3>;
 };
 
 &ufs_wrapper {
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index af3d730154ac..b9bb59ce4ed2 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -5,6 +5,7 @@
  * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
  */
 #include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-cadence.h>
 #include <dt-bindings/phy/phy-ti.h>
 #include <dt-bindings/mux/mux.h>
 
@@ -82,6 +83,11 @@ ehrpwm_tbclk: clock-controller at 4140 {
 			reg = <0x4140 0x18>;
 			#clock-cells = <1>;
 		};
+
+		acspcie0_proxy_ctrl: syscon at 18090 {
+			compatible = "ti,j784s4-acspcie-proxy-ctrl", "syscon";
+			reg = <0x18090 0x4>;
+		};
 	};
 
 	main_ehrpwm0: pwm at 3000000 {
@@ -979,8 +985,8 @@ pcie1_rc: pcie at 2910000 {
 		max-link-speed = <3>;
 		num-lanes = <2>;
 		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 240 1>;
-		clock-names = "fck";
+		clocks = <&k3_clks 240 1>, <&serdes1 CDNS_SIERRA_DERIVED_REFCLK>;
+		clock-names = "fck", "pcie_refclk";
 		#address-cells = <3>;
 		#size-cells = <2>;
 		bus-range = <0x0 0xff>;
-- 
2.45.0



From krzk at kernel.org  Mon Dec  2 02:14:46 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 11:14:46 +0100
Subject: [PATCHv2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable ACSPCIE
 output for PCIe1
In-Reply-To: <20241202101140.48778-1-romain.naour@smile.fr>
References: <20241202101140.48778-1-romain.naour@smile.fr>
Message-ID: <dabbad2b-f8a6-4ed7-86da-ec696cf67461@kernel.org>

On 02/12/2024 11:11, Romain Naour wrote:
> From: Romain Naour <romain.naour at skf.com>
> 
> Unlike the SK-TDA4VM (k3-j721e-sk) board, there is no clock generator
> (CDCI6214RGET) on the BeagleBone AI-64 (k3-j721e-beagleboneai64) to
> provide PCIe refclk signal to PCIe Endponts. So the ACSPCIE module must
> provide refclk through PCIe_REFCLK pins.
> 
> Use the new "ti,syscon-acspcie-proxy-ctrl" property to enable ACSPCIE
> module's PAD IO Buffers.
> 
> Reuse the compatible "ti,j784s4-acspcie-proxy-ctrl" since the ACSPCIE
> buffer and its functionality is the same across all K3 SoCs.
> 
> Cc: Siddharth Vadapalli <s-vadapalli at ti.com>
> Signed-off-by: Romain Naour <romain.naour at skf.com>
> ---
> With this patch, we can remove "HACK: Sierra: Drive clock out" patch
> applied on vendor kernel for BeagleBone AI-64:
> https://openbeagle.org/beagleboard/linux/-/commit/ad65d7ef675966cdbc5d75f2bd545fad1914ba9b
> 
> v2:
>  - use generic style comments
>  - use "syscon" as generic node name for "acspcie0_proxy_ctrl" node
>  - Keep the compatible "ti,j784s4-acspcie-proxy-ctrl" since the
>    ACSPCIE buffer and its functionality is the same across all K3 SoCs.
>    (Siddharth Vadapalli)
> 
>    "The compatible "ti,j784s4-acspcie-pcie-ctrl" should be reused for
>    J721E and all other K3 SoCs.

No, it shouldn't and you got comment on this. You always need specific
compatible, see writing bindings doc.

Best regards,
Krzysztof


From mripard at kernel.org  Mon Dec  2 02:19:41 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 02 Dec 2024 10:19:41 +0000
Subject: [PATCH 00/10] drm/connector: add eld_mutex to protect
 connector->eld
In-Reply-To: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
References: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
Message-ID: <77545786331df8bfaf5fdcb309437358@kernel.org>

On Sun, 1 Dec 2024 01:55:17 +0200, Dmitry Baryshkov wrote:
> The connector->eld is accessed by the .get_eld() callback. This access
> can collide with the drm_edid_to_eld() updating the data at the same
> time. Add drm_connector.eld_mutex to protect the data from concurrenct
> access.
> 
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From jani.nikula at linux.intel.com  Mon Dec  2 02:23:29 2024
From: jani.nikula at linux.intel.com (Jani Nikula)
Date: Mon, 02 Dec 2024 12:23:29 +0200
Subject: [PATCH 01/10] drm/connector: add mutex to protect ELD from
 concurrent access
In-Reply-To: <20241201-drm-connector-eld-mutex-v1-1-ba56a6545c03@linaro.org>
References: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
 <20241201-drm-connector-eld-mutex-v1-1-ba56a6545c03@linaro.org>
Message-ID: <87r06q5qou.fsf@intel.com>

On Sun, 01 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> The connector->eld is accessed by the .get_eld() callback. This access
> can collide with the drm_edid_to_eld() updating the data at the same
> time. Add drm_connector.eld_mutex to protect the data from concurrenct
> access. Individual drivers are not updated (to reduce possible issues
> while applying the patch), maintainers are to find a best suitable way
> to lock that mutex while accessing the ELD data.

Missed clear_eld().

BR,
Jani.

>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/drm_connector.c | 1 +
>  drivers/gpu/drm/drm_edid.c      | 4 ++++
>  include/drm/drm_connector.h     | 5 ++++-
>  3 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index fc35f47e2849ed6786d6223ac9c69e1c359fc648..bbdaaf7022b62d84594a29f1b60144920903a99a 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -277,6 +277,7 @@ static int __drm_connector_init(struct drm_device *dev,
>  	INIT_LIST_HEAD(&connector->probed_modes);
>  	INIT_LIST_HEAD(&connector->modes);
>  	mutex_init(&connector->mutex);
> +	mutex_init(&connector->eld_mutex);
>  	mutex_init(&connector->edid_override_mutex);
>  	mutex_init(&connector->hdmi.infoframes.lock);
>  	connector->edid_blob_ptr = NULL;
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 855beafb76ffbecf5c08d58e2f54bfb76f30b930..f0ca77bd42fd518d505d0db78557e0c8d83efb29 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -5657,6 +5657,8 @@ static void drm_edid_to_eld(struct drm_connector *connector,
>  	if (!drm_edid)
>  		return;
>  
> +	mutex_lock(&connector->eld_mutex);
> +
>  	mnl = get_monitor_name(drm_edid, &eld[DRM_ELD_MONITOR_NAME_STRING]);
>  	drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD monitor %s\n",
>  		    connector->base.id, connector->name,
> @@ -5717,6 +5719,8 @@ static void drm_edid_to_eld(struct drm_connector *connector,
>  	drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD size %d, SAD count %d\n",
>  		    connector->base.id, connector->name,
>  		    drm_eld_size(eld), total_sad_count);
> +
> +	mutex_unlock(&connector->eld_mutex);
>  }
>  
>  static int _drm_edid_to_sad(const struct drm_edid *drm_edid,
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index e3fa43291f449d70f3b92a00985336c4f2237bc6..1e2b25e204cb523d61d30f5409faa059bf2b86eb 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -2001,8 +2001,11 @@ struct drm_connector {
>  	struct drm_encoder *encoder;
>  
>  #define MAX_ELD_BYTES	128
> -	/** @eld: EDID-like data, if present */
> +	/** @eld: EDID-like data, if present, protected by @eld_mutex */
>  	uint8_t eld[MAX_ELD_BYTES];
> +	/** @eld_mutex: protection for concurrenct access to @eld */
> +	struct mutex eld_mutex;
> +
>  	/** @latency_present: AV delay info from ELD, if found */
>  	bool latency_present[2];
>  	/**

-- 
Jani Nikula, Intel


From yassine.ouaissa at allegrodvt.com  Mon Dec  2 02:26:38 2024
From: yassine.ouaissa at allegrodvt.com (Yassine Ouaissa)
Date: Mon,  2 Dec 2024 11:26:38 +0100
Subject: [PATCH] media: allegro-dvt: Moving the current driver to subdirectory
Message-ID: <20241202102654.40472-1-yassine.ouaissa@allegrodvt.com>

In preparation for the upcoming driver update, we need to realocate the
current driver that is not maintained by us ( allegro-dvt ).
This will help ensure a clean transition and avoid any potential
conflicts with the new driver.

This patch is crucial for keeping our directory organized and
facilitating a smooth integration of the new driver

Signed-off-by: Yassine Ouaissa <yassine.ouaissa at allegrodvt.com>
---
 MAINTAINERS                                               | 2 +-
 drivers/media/platform/allegro-dvt/Kconfig                | 4 ++--
 drivers/media/platform/allegro-dvt/Makefile               | 8 ++------
 drivers/media/platform/allegro-dvt/zynqmp/Makefile        | 6 ++++++
 .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c    | 0
 .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h    | 0
 .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c    | 0
 .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h    | 0
 .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c    | 0
 .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h    | 0
 .../{allegro-core.c => zynqmp/zynqmp-allegro-core.c}      | 2 +-
 .../{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c}      | 2 +-
 .../{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h}      | 0
 13 files changed, 13 insertions(+), 11 deletions(-)
 create mode 100644 drivers/media/platform/allegro-dvt/zynqmp/Makefile
 rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c (100%)
 rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h (100%)
 rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c (100%)
 rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h (100%)
 rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c (100%)
 rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h (100%)
 rename drivers/media/platform/allegro-dvt/{allegro-core.c => zynqmp/zynqmp-allegro-core.c} (99%)
 rename drivers/media/platform/allegro-dvt/{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c} (99%)
 rename drivers/media/platform/allegro-dvt/{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h} (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7292e4a1ddb8..d79efe6f8992 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -795,7 +795,7 @@ R:	Pengutronix Kernel Team <kernel at pengutronix.de>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/allegro,al5e.yaml
-F:	drivers/media/platform/allegro-dvt/
+F:	drivers/media/platform/allegro-dvt/zynqmp
 
 ALLIED VISION ALVIUM CAMERA DRIVER
 M:	Tommaso Merciai <tomm.merciai at gmail.com>
diff --git a/drivers/media/platform/allegro-dvt/Kconfig b/drivers/media/platform/allegro-dvt/Kconfig
index 2182e1277568..9bc7e99788b8 100644
--- a/drivers/media/platform/allegro-dvt/Kconfig
+++ b/drivers/media/platform/allegro-dvt/Kconfig
@@ -2,8 +2,8 @@
 
 comment "Allegro DVT media platform drivers"
 
-config VIDEO_ALLEGRO_DVT
-	tristate "Allegro DVT Video IP Core"
+config VIDEO_ZYNQMP_ALLEGRO_DVT
+	tristate "Allegro DVT Video IP Core for ZynqMP"
 	depends on V4L_MEM2MEM_DRIVERS
 	depends on VIDEO_DEV
 	depends on ARCH_ZYNQMP || COMPILE_TEST
diff --git a/drivers/media/platform/allegro-dvt/Makefile b/drivers/media/platform/allegro-dvt/Makefile
index 66108a303774..04727c5f7ef4 100644
--- a/drivers/media/platform/allegro-dvt/Makefile
+++ b/drivers/media/platform/allegro-dvt/Makefile
@@ -1,6 +1,2 @@
-# SPDX-License-Identifier: GPL-2.0
-
-allegro-objs := allegro-core.o allegro-mail.o
-allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
-
-obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y += zynqmp/
diff --git a/drivers/media/platform/allegro-dvt/zynqmp/Makefile b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
new file mode 100644
index 000000000000..a8ddb9cf93a8
--- /dev/null
+++ b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+zynqmp-allegro-objs := zynqmp-allegro-core.o zynqmp-allegro-mail.o
+zynqmp-allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
+
+obj-$(CONFIG_VIDEO_ZYNQMP_ALLEGRO_DVT) += zynqmp-allegro.o
diff --git a/drivers/media/platform/allegro-dvt/nal-h264.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
similarity index 100%
rename from drivers/media/platform/allegro-dvt/nal-h264.c
rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
diff --git a/drivers/media/platform/allegro-dvt/nal-h264.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
similarity index 100%
rename from drivers/media/platform/allegro-dvt/nal-h264.h
rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
similarity index 100%
rename from drivers/media/platform/allegro-dvt/nal-hevc.c
rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
similarity index 100%
rename from drivers/media/platform/allegro-dvt/nal-hevc.h
rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
similarity index 100%
rename from drivers/media/platform/allegro-dvt/nal-rbsp.c
rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
similarity index 100%
rename from drivers/media/platform/allegro-dvt/nal-rbsp.h
rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
similarity index 99%
rename from drivers/media/platform/allegro-dvt/allegro-core.c
rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
index e491399afcc9..8895d7755987 100644
--- a/drivers/media/platform/allegro-dvt/allegro-core.c
+++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
@@ -31,7 +31,7 @@
 #include <media/videobuf2-dma-contig.h>
 #include <media/videobuf2-v4l2.h>
 
-#include "allegro-mail.h"
+#include "zynqmp-allegro-mail.h"
 #include "nal-h264.h"
 #include "nal-hevc.h"
 
diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
similarity index 99%
rename from drivers/media/platform/allegro-dvt/allegro-mail.c
rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
index aadc947a77ae..88a98f9e5d00 100644
--- a/drivers/media/platform/allegro-dvt/allegro-mail.c
+++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
@@ -12,7 +12,7 @@
 #include <linux/string.h>
 #include <linux/videodev2.h>
 
-#include "allegro-mail.h"
+#include "zynqmp-allegro-mail.h"
 
 const char *msg_type_name(enum mcu_msg_type type)
 {
diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.h b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
similarity index 100%
rename from drivers/media/platform/allegro-dvt/allegro-mail.h
rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
-- 
2.30.2



From jean-philippe at linaro.org  Mon Dec  2 02:26:32 2024
From: jean-philippe at linaro.org (Jean-Philippe Brucker)
Date: Mon, 2 Dec 2024 10:26:32 +0000
Subject: [PATCH v5 00/43] arm64: Support for Arm CCA in KVM
In-Reply-To: <01205247-ffcd-439f-b00f-d8e70720d049@arm.com>
References: <20241004152804.72508-1-steven.price@arm.com>
 <Z01BYOgsLXV5yULk@vm3>
 <01205247-ffcd-439f-b00f-d8e70720d049@arm.com>
Message-ID: <20241202102632.GB1704077@myrica>

On Mon, Dec 02, 2024 at 08:54:11AM +0000, Steven Price wrote:
> Hi Itaru,
> 
> On 02/12/2024 05:10, Itaru Kitayama wrote:
> > On Fri, Oct 04, 2024 at 04:27:21PM +0100, Steven Price wrote:
> >> This series adds support for running protected VMs using KVM under the
> >> Arm Confidential Compute Architecture (CCA).
> ...
> > 
> > On FVP, the v5+v7 kernel is unable to execute virt-manager:
> > 
> > Starting install...
> > Allocating 'test9.qcow2'                                    |    0 B  00:00 ...
> > Removing disk 'test9.qcow2'                                 |    0 B  00:00
> > ERROR    internal error: process exited while connecting to monitor: 2024-12-04T18:56:11.646168Z qemu-system-aarch64: -accel kvm: ioctl(KVM_CREATE_VM) failed: Invalid argument
> > 2024-12-04T18:56:11.646520Z qemu-system-aarch64: -accel kvm: failed to initialize kvm: Invalid argument
> > Domain installation does not appear to have been successful.
> 
> Can you check that the kernel has detected the RMM being available, you
> should have a message like below when the host kernel is booting:
> 
> kvm [1]: RMI ABI version 1.0
> 
> My guess is that you've got mismatched versions of the RMM and TF-A. The
> interface between those two components isn't stable and there were
> breaking changes fairly recently. And obviously if the RMM hasn't
> initialised successfully then confidential VMs won't be available.
> 
> > Below is my virt-manager options:
> > 
> > virt-install --machine=virt --arch=aarch64 --name=test9 --memory=2048 --vcpu=1 --nographic --check all=off --features acpi=off --virt-type kvm --boot kernel=Image-cca,initrd=rootfs.cpio,kernel_args='earlycon console=ttyAMA0 rdinit=/sbin/init rw root=/dev/vda acpi=off' --qemu-commandline='-M virt,confidential-guest-support=rme0,gic-version=3 -cpu host -object rme-guest,id=rme0 -nodefaults' --disk size=4 --import --osinfo detect=on,require=off
> > 
> > Userland is Ubuntu 24.10, the VMM is Linaro's cca/2024-11-20:
> > 
> > https://git.codelinaro.org/linaro/dcap/qemu/-/tree/cca/2024-11-20?ref_type=heads

Indeed, QEMU branch 2024-11-20 has to be used with an older version of the
KVM patch and older RMM. For KVM v5+v7 you need the most recent QEMU
branch, confusingly called cca/v3 (because it's the third patch series).

Thanks,
Jean

> 
> I don't think this is the latest QEMU tree, Jean-Philippe posted an
> update last week:
> 
> https://lore.kernel.org/qemu-devel/20241125195626.856992-2-jean-philippe at linaro.org/
> 
> I'm not sure if there were any important updates there, but there are
> detailed instructions that might help.
> 
> Regards,
> Steve
> 


From jakobunt at gmail.com  Mon Dec  2 02:25:44 2024
From: jakobunt at gmail.com (Jakob Unterwurzacher)
Date: Mon,  2 Dec 2024 11:25:44 +0100
Subject: [PATCH v2] arm64: dts: rockchip: increase gmac rx_delay to 0x11 on rk3399-puma
Message-ID: <20241202102543.204154-1-jakob.unterwurzacher@cherry.de>

During mass manufacturing, we noticed the mmc_rx_crc_error counter,
as reported by "ethtool -S eth0 | grep mmc_rx_crc_error" to increase
above zero during nuttcp speedtests.

Cycling through the rx_delay range on two boards shows that there is a
large "good" region from 0x11 to 0x35 (see below for details).

This commit increases rx_delay to 0x11, which is the smallest
possible change that fixes the issue we are seeing on the KSZ9031 PHY.
This also matches what most other rk3399 boards do.

Tests for Puma PCBA S/N TT0069903:

	rx_delay mmc_rx_crc_error
	-------- ----------------
	0x09 (dhcp broken)
	0x10 897
	0x11 0
	0x20 0
	0x30 0
	0x35 0
	0x3a 745
	0x3b 11375
	0x3c 36680
	0x40 (dhcp broken)
	0x7f (dhcp broken)

Tests for Puma PCBA S/N TT0157733:

	rx_delay mmc_rx_crc_error
	-------- ----------------
	0x10 59
	0x11 0
	0x35 0

Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")
Cc: <stable at vger.kernel.org>
Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>
Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at cherry.de>
---
v2: cc stable, add "Fixes:", add omitted "there" to commit msg,
    add Reviewed-by.

 arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
index 9efcdce0f593..13d0c511046b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
@@ -181,7 +181,7 @@ &gmac {
 	snps,reset-active-low;
 	snps,reset-delays-us = <0 10000 50000>;
 	tx_delay = <0x10>;
-	rx_delay = <0x10>;
+	rx_delay = <0x11>;
 	status = "okay";
 };
 
-- 
2.39.5



From krzk at kernel.org  Mon Dec  2 02:31:27 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 11:31:27 +0100
Subject: [PATCH] media: dt-bindings: sony,imx415: add required clock-names
 property
In-Reply-To: <f088a247-8049-49a7-bab3-5b517cb0c531@wolfvision.net>
References: <20241130141716.1007115-1-matthias.fend@emfend.at>
 <bh3obpt6bcklejdvrk4r6ienraz5zmhrdyotijhvlwexussqgj@hicmx34vi27w>
 <f088a247-8049-49a7-bab3-5b517cb0c531@wolfvision.net>
Message-ID: <ab06e590-f113-459d-80b6-28136a79e10d@kernel.org>

On 02/12/2024 09:18, Michael Riesch wrote:
> Hi Matthias, Krzysztof,
> 
> On 12/2/24 08:56, Krzysztof Kozlowski wrote:
>> On Sat, Nov 30, 2024 at 03:17:15PM +0100, Matthias Fend wrote:
>>> The imx415 driver expects a clock with the name "inck".
>>> Document this in the bindings.
>>
>> No, fix the driver instead of bypassing review. It was decided to drop
>> it during review, so you cannot reintroduce it 2 years later claiming
>> that's now ABI. Of course original submission was buggy and never
>> tested, but that does not allow review bypass.
> 
> Just to make sure I am on the same page here: Between v2 and v3 of the
> IMX415 submission the clock-names property was dropped. At that point,
> we should have changed the acquisition of the clock from
>     sensor->clk = devm_clk_get(sensor->dev, "inck");
> to
>     sensor->clk = devm_clk_get(sensor->dev, NULL);
> 
> Is that correct/the proper fix?

Yes, because driver could simply not work. It was never tested, after
the change.

Best regards,
Krzysztof


From mripard at kernel.org  Mon Dec  2 02:32:21 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 2 Dec 2024 11:32:21 +0100
Subject: [PATCH v2 1/3] drm/modes: introduce drm_mode_validate_mode()
 helper function
In-Reply-To: <tzcjzgp7xalhhezcv5hfa7cjscxg44phqcw2ap54lesly4gk6o@6dtco2d3jahj>
References: <20241125-dsi-relax-v2-0-9113419f4a40@geanix.com>
 <20241125-dsi-relax-v2-1-9113419f4a40@geanix.com>
 <20241125-gleaming-anteater-of-perfection-42bd2b@houat>
 <bfuj6w6hsbfpdw24th6dl3ugvj45op6jb45gx5ab5pulud7hiz@o2zbn45z3lt4>
 <tzcjzgp7xalhhezcv5hfa7cjscxg44phqcw2ap54lesly4gk6o@6dtco2d3jahj>
Message-ID: <20241202-nickel-rottweiler-of-hail-c9ec8b@houat>

On Tue, Nov 26, 2024 at 02:30:53PM +0100, Sean Nyekjaer wrote:
> Hi Maxime,
> 
> On Tue, Nov 26, 2024 at 08:36:01AM +0100, Sean Nyekjaer wrote:
> > Hi Maxime,
> > 
> 
> [...]
> 
> > > 
> > > We probably need some kunit tests here too.
> > 
> > Good idea, will be my first :)
> > 
> 
> Would something like this work?
> 
> diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
> index 294773342e71..26e4ff02df85 100644
> --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
> @@ -1364,6 +1364,7 @@ static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test
>  	struct drm_connector_state *conn_state;
>  	struct drm_display_info *info;
>  	struct drm_display_mode *preferred;
> +	enum drm_mode_status mode_status;
>  	unsigned long long rate;
>  	struct drm_connector *conn;
>  	struct drm_device *drm;
> @@ -1408,6 +1409,9 @@ static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test
>  	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
>  	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
>  
> +	mode_status = drm_mode_check_pixel_clock(preferred, rate);
> +	KUNIT_ASSERT_EQ(test, mode_status, MODE_OK);
> +

Not really. You need to test that function, and ideally only that
function, with a bunch of random inputs, including the error conditions.

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

From marcin.juszkiewicz at linaro.org  Mon Dec  2 02:40:01 2024
From: marcin.juszkiewicz at linaro.org (Marcin Juszkiewicz)
Date: Mon, 2 Dec 2024 11:40:01 +0100
Subject: [PATCH] arm64: dts: rockchip: enable rng on all rk356x
In-Reply-To: <302bdae2f4defeefe88ea4018a0be11f@manjaro.org>
References: <a> <20241201234613.52322-1-pbrobinson@gmail.com>
 <302bdae2f4defeefe88ea4018a0be11f@manjaro.org>
Message-ID: <b50376c7-c5d5-41ae-95ea-e2d68c1cc809@linaro.org>

W dniu 2.12.2024 o 04:55, Dragan Simic pisze:
 > On 2024-12-02 00:46, Peter Robinson wrote:
 >> The rk356x rng is available on both the rk3566 and rk3568
 >> parts, the IP is all self contained within the SoCs so
 >> it's enabled already by default on rk3568 so let's enable
 >> it in the base rk356x.dtsi so it's enabled consistently
 >> everywhere.
 >
 > Please, go through the mailing list threads [1][2] that have led us
 > to the current state.  To sum it up, it isn't about what's supported
 > in the two RK356x SoC variants, but about the RK3566's HWRNG being
 > disabled because the testing showed that it produces unacceptably
 > low quality of random data, for some yet unknown reason.

So maybe there should be a comment in rockchip/rk3568.dtsi so we would 
not get back to it again.


From itaru.kitayama at linux.dev  Mon Dec  2 02:42:35 2024
From: itaru.kitayama at linux.dev (Itaru Kitayama)
Date: Mon, 2 Dec 2024 19:42:35 +0900
Subject: [PATCH v5 00/43] arm64: Support for Arm CCA in KVM
In-Reply-To: <20241202102632.GB1704077@myrica>
References: <20241004152804.72508-1-steven.price@arm.com>
 <Z01BYOgsLXV5yULk@vm3> <01205247-ffcd-439f-b00f-d8e70720d049@arm.com>
 <20241202102632.GB1704077@myrica>
Message-ID: <4313C668-D48C-4443-917E-67A112BE1C37@linux.dev>

Hi Jean, Steven,

> On Dec 2, 2024, at 19:26, Jean-Philippe Brucker <jean-philippe at linaro.org> wrote:
> 
> On Mon, Dec 02, 2024 at 08:54:11AM +0000, Steven Price wrote:
>> Hi Itaru,
>> 
>> On 02/12/2024 05:10, Itaru Kitayama wrote:
>>> On Fri, Oct 04, 2024 at 04:27:21PM +0100, Steven Price wrote:
>>>> This series adds support for running protected VMs using KVM under the
>>>> Arm Confidential Compute Architecture (CCA).
>> ...
>>> 
>>> On FVP, the v5+v7 kernel is unable to execute virt-manager:
>>> 
>>> Starting install...
>>> Allocating 'test9.qcow2'                                    |    0 B  00:00 ...
>>> Removing disk 'test9.qcow2'                                 |    0 B  00:00
>>> ERROR    internal error: process exited while connecting to monitor: 2024-12-04T18:56:11.646168Z qemu-system-aarch64: -accel kvm: ioctl(KVM_CREATE_VM) failed: Invalid argument
>>> 2024-12-04T18:56:11.646520Z qemu-system-aarch64: -accel kvm: failed to initialize kvm: Invalid argument
>>> Domain installation does not appear to have been successful.
>> 
>> Can you check that the kernel has detected the RMM being available, you
>> should have a message like below when the host kernel is booting:
>> 
>> kvm [1]: RMI ABI version 1.0
>> 
>> My guess is that you've got mismatched versions of the RMM and TF-A. The
>> interface between those two components isn't stable and there were
>> breaking changes fairly recently. And obviously if the RMM hasn't
>> initialised successfully then confidential VMs won't be available.
>> 
>>> Below is my virt-manager options:
>>> 
>>> virt-install --machine=virt --arch=aarch64 --name=test9 --memory=2048 --vcpu=1 --nographic --check all=off --features acpi=off --virt-type kvm --boot kernel=Image-cca,initrd=rootfs.cpio,kernel_args='earlycon console=ttyAMA0 rdinit=/sbin/init rw root=/dev/vda acpi=off' --qemu-commandline='-M virt,confidential-guest-support=rme0,gic-version=3 -cpu host -object rme-guest,id=rme0 -nodefaults' --disk size=4 --import --osinfo detect=on,require=off
>>> 
>>> Userland is Ubuntu 24.10, the VMM is Linaro's cca/2024-11-20:
>>> 
>>> https://git.codelinaro.org/linaro/dcap/qemu/-/tree/cca/2024-11-20?ref_type=heads
> 
> Indeed, QEMU branch 2024-11-20 has to be used with an older version of the
> KVM patch and older RMM. For KVM v5+v7 you need the most recent QEMU
> branch, confusingly called cca/v3 (because it's the third patch series).
> 
> Thanks,
> Jean

I wasn?t applying with the updated Shrinkwrap?s overlay file when building TF-RMM.
With the correct VMM as you guys mentioned (cca/v3) I was able to start the installation via
the virt-install interacting with the Ubuntu 24.10?s monolitihc libvirtd.

Thanks,
Itaru.

> 
>> 
>> I don't think this is the latest QEMU tree, Jean-Philippe posted an
>> update last week:
>> 
>> https://lore.kernel.org/qemu-devel/20241125195626.856992-2-jean-philippe at linaro.org/
>> 
>> I'm not sure if there were any important updates there, but there are
>> detailed instructions that might help.
>> 
>> Regards,
>> Steve




From amergnat at baylibre.com  Mon Dec  2 02:50:19 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Mon, 2 Dec 2024 11:50:19 +0100
Subject: [PATCH] drm/mediatek: Initialize pointer in mtk_drm_of_ddp_path_build_one()
In-Reply-To: <20241112105030.93337-1-angelogioacchino.delregno@collabora.com>
References: <20241112105030.93337-1-angelogioacchino.delregno@collabora.com>
Message-ID: <CAFGrd9qe5Q60zBEXyCokcLtFQVk+qa9yajO4_gHZR381i9cVOA@mail.gmail.com>

On Tue, Nov 12, 2024 at 11:50?AM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> The struct device_node *next pointer is not initialized, and it is
> used in an error path in which it may have never been modified by
> function mtk_drm_of_get_ddp_ep_cid().
>
> Since the error path is relying on that pointer being NULL for the
> OVL Adaptor and/or invalid component check and since said pointer
> is being used in prints for %pOF, in the case that it points to a
> bogus address, the print may cause a KP.
>
> To resolve that, initialize the *next pointer to NULL before usage.
>

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>


From yangyicong at huawei.com  Mon Dec  2 02:54:33 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 18:54:33 +0800
Subject: [PATCH 3/4] coresight: tmc-etr: Fix race condition between sysfs
 and perf mode
In-Reply-To: <62f5d1c5-05bd-41b6-8703-baacec3e2619@arm.com>
References: <20241202092419.11777-1-yangyicong@huawei.com>
 <20241202092419.11777-4-yangyicong@huawei.com>
 <62f5d1c5-05bd-41b6-8703-baacec3e2619@arm.com>
Message-ID: <b88ca1ef-469d-1c04-03f6-d51518b77bc2@huawei.com>

On 2024/12/2 17:46, Suzuki K Poulose wrote:
> Hi Yicong
> 
> On 02/12/2024 09:24, Yicong Yang wrote:
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> When trying to run perf and sysfs mode simultaneously, the WARN_ON()
>> in tmc_etr_enable_hw() is triggered sometimes:
>>
>> ? WARNING: CPU: 42 PID: 3911571 at drivers/hwtracing/coresight/coresight-tmc-etr.c:1060 tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc]
>> ? [..snip..]
>> ? Call trace:
>> ?? tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc] (P)
>> ?? tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc] (L)
>> ?? tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc]
>> ?? coresight_enable_path+0x1c8/0x218 [coresight]
>> ?? coresight_enable_sysfs+0xa4/0x228 [coresight]
>> ?? enable_source_store+0x58/0xa8 [coresight]
>> ?? dev_attr_store+0x20/0x40
>> ?? sysfs_kf_write+0x4c/0x68
>> ?? kernfs_fop_write_iter+0x120/0x1b8
>> ?? vfs_write+0x2c8/0x388
>> ?? ksys_write+0x74/0x108
>> ?? __arm64_sys_write+0x24/0x38
>> ?? el0_svc_common.constprop.0+0x64/0x148
>> ?? do_el0_svc+0x24/0x38
>> ?? el0_svc+0x3c/0x130
>> ?? el0t_64_sync_handler+0xc8/0xd0
>> ?? el0t_64_sync+0x1ac/0x1b0
>> ? ---[ end trace 0000000000000000 ]---
>>
>> Since the enablement of sysfs mode is separeted into two critical regions,
>> one for sysfs buffer allocation and another for hardware enablement, it's
>> possible to race with the perf mode. Fix this by double check whether
>> the perf mode's been used before enabling the hardware in sysfs mode.
> 
> Thanks for the fix. Some minor comments below.
> 
> It needs a Fixes tag.
> 
>>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> ---
>> ? .../hwtracing/coresight/coresight-tmc-etr.c?? | 30 +++++++++++++++++++
>> ? 1 file changed, 30 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> index ad83714ca4dc..d382d95da5ff 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> @@ -1230,6 +1230,36 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
>> ? ????? spin_lock_irqsave(&drvdata->spinlock, flags);
>> ? +??? /*
>> +???? * Since the sysfs buffer allocation and the hardware enablement is not
>> +???? * in the same critical region, it's possible to race with the perf
>> +???? * mode:
>> +???? *?? [sysfs mode]?????????????????? [perf mode]
>> +???? *?? tmc_etr_get_sysfs_buffer()
>> +???? *???? spin_lock(&drvdata->spinlock)
>> +???? *???? [sysfs buffer allocation]
>> +???? *???? spin_unlock(&drvdata->spinlock)
>> +???? *????????????????????????????????? spin_lock(&drvdata->spinlock)
>> +???? *????????????????????????????????? tmc_etr_enable_hw()
>> +???? *??????????????????????????????????? drvdata->etr_buf = etr_perf->etr_buf
>> +???? *????????????????????????????????? spin_unlock(&drvdata->spinlock)
>> +???? *?? spin_lock(&drvdata->spinlock)
>> +???? *?? tmc_etr_enable_hw()
>> +???? *???? WARN_ON(drvdata->etr_buf) // WARN sicne etr_buf initialized at
>> +???? *????????????????????????????????? the perf side
>> +???? *?? spin_unlock(&drvdata->spinlock)
>> +???? *
>> +???? * So check here before continue.
>> +???? */
>> +??? if (coresight_get_mode(csdev) == CS_MODE_PERF) {
>> +??????? drvdata->sysfs_buf = NULL;
>> +??????? spin_unlock_irqrestore(&drvdata->spinlock, flags);
>> +
>> +??????? /* Free allocated memory out side of the spinlock */
>> +??????? tmc_etr_free_sysfs_buf(sysfs_buf);
>> +??????? return -EBUSY;
>> +??? }
> 
> With this in place, I think we should remove the check for CS_MODE_PERF in get_etr_sysfs_buf() to avoid confusion (which I believe opened up this race)
> 

ok, considering that maybe we can optimize it a bit more in the tmc_etr_get_sysfs_buffer().
Check whether the perf mode's already running before we actually allocate the buffer.
Then we can save the time of allocating/freeing the sysfs buffer if race with the perf mode.

Thanks.



From m.tretter at pengutronix.de  Mon Dec  2 02:55:40 2024
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Mon, 2 Dec 2024 11:55:40 +0100
Subject: [PATCH] media: allegro-dvt: Moving the current driver to
 subdirectory
In-Reply-To: <20241202102654.40472-1-yassine.ouaissa@allegrodvt.com>
References: <20241202102654.40472-1-yassine.ouaissa@allegrodvt.com>
Message-ID: <Z02SLI05JhNDtXFn@pengutronix.de>

Hi Yassine,

On Mon, 02 Dec 2024 11:26:38 +0100, Yassine Ouaissa wrote:
> In preparation for the upcoming driver update, we need to realocate the
> current driver that is not maintained by us ( allegro-dvt ).
> This will help ensure a clean transition and avoid any potential
> conflicts with the new driver.

What kind of conflicts do you encounter or expect? It's kind of
surprising that your driver would conflict with anything in the existing
driver.

> 
> This patch is crucial for keeping our directory organized and
> facilitating a smooth integration of the new driver

I'd like to see how you plan to integrate your driver, what it looks
like and what conflicts with the existing driver actually occur. Without
that information I don't see the point in moving the driver to a
sub-directory.

Michael

> 
> Signed-off-by: Yassine Ouaissa <yassine.ouaissa at allegrodvt.com>
> ---
>  MAINTAINERS                                               | 2 +-
>  drivers/media/platform/allegro-dvt/Kconfig                | 4 ++--
>  drivers/media/platform/allegro-dvt/Makefile               | 8 ++------
>  drivers/media/platform/allegro-dvt/zynqmp/Makefile        | 6 ++++++
>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c    | 0
>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h    | 0
>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c    | 0
>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h    | 0
>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c    | 0
>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h    | 0
>  .../{allegro-core.c => zynqmp/zynqmp-allegro-core.c}      | 2 +-
>  .../{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c}      | 2 +-
>  .../{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h}      | 0
>  13 files changed, 13 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/media/platform/allegro-dvt/zynqmp/Makefile
>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c (100%)
>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h (100%)
>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c (100%)
>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h (100%)
>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c (100%)
>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h (100%)
>  rename drivers/media/platform/allegro-dvt/{allegro-core.c => zynqmp/zynqmp-allegro-core.c} (99%)
>  rename drivers/media/platform/allegro-dvt/{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c} (99%)
>  rename drivers/media/platform/allegro-dvt/{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h} (100%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7292e4a1ddb8..d79efe6f8992 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -795,7 +795,7 @@ R:	Pengutronix Kernel Team <kernel at pengutronix.de>
>  L:	linux-media at vger.kernel.org
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/media/allegro,al5e.yaml
> -F:	drivers/media/platform/allegro-dvt/
> +F:	drivers/media/platform/allegro-dvt/zynqmp
>  
>  ALLIED VISION ALVIUM CAMERA DRIVER
>  M:	Tommaso Merciai <tomm.merciai at gmail.com>
> diff --git a/drivers/media/platform/allegro-dvt/Kconfig b/drivers/media/platform/allegro-dvt/Kconfig
> index 2182e1277568..9bc7e99788b8 100644
> --- a/drivers/media/platform/allegro-dvt/Kconfig
> +++ b/drivers/media/platform/allegro-dvt/Kconfig
> @@ -2,8 +2,8 @@
>  
>  comment "Allegro DVT media platform drivers"
>  
> -config VIDEO_ALLEGRO_DVT
> -	tristate "Allegro DVT Video IP Core"
> +config VIDEO_ZYNQMP_ALLEGRO_DVT
> +	tristate "Allegro DVT Video IP Core for ZynqMP"
>  	depends on V4L_MEM2MEM_DRIVERS
>  	depends on VIDEO_DEV
>  	depends on ARCH_ZYNQMP || COMPILE_TEST
> diff --git a/drivers/media/platform/allegro-dvt/Makefile b/drivers/media/platform/allegro-dvt/Makefile
> index 66108a303774..04727c5f7ef4 100644
> --- a/drivers/media/platform/allegro-dvt/Makefile
> +++ b/drivers/media/platform/allegro-dvt/Makefile
> @@ -1,6 +1,2 @@
> -# SPDX-License-Identifier: GPL-2.0
> -
> -allegro-objs := allegro-core.o allegro-mail.o
> -allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
> -
> -obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o
> +# SPDX-License-Identifier: GPL-2.0-only
> +obj-y += zynqmp/
> diff --git a/drivers/media/platform/allegro-dvt/zynqmp/Makefile b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
> new file mode 100644
> index 000000000000..a8ddb9cf93a8
> --- /dev/null
> +++ b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +zynqmp-allegro-objs := zynqmp-allegro-core.o zynqmp-allegro-mail.o
> +zynqmp-allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
> +
> +obj-$(CONFIG_VIDEO_ZYNQMP_ALLEGRO_DVT) += zynqmp-allegro.o
> diff --git a/drivers/media/platform/allegro-dvt/nal-h264.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
> similarity index 100%
> rename from drivers/media/platform/allegro-dvt/nal-h264.c
> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
> diff --git a/drivers/media/platform/allegro-dvt/nal-h264.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
> similarity index 100%
> rename from drivers/media/platform/allegro-dvt/nal-h264.h
> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
> diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
> similarity index 100%
> rename from drivers/media/platform/allegro-dvt/nal-hevc.c
> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
> diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
> similarity index 100%
> rename from drivers/media/platform/allegro-dvt/nal-hevc.h
> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
> diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
> similarity index 100%
> rename from drivers/media/platform/allegro-dvt/nal-rbsp.c
> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
> diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
> similarity index 100%
> rename from drivers/media/platform/allegro-dvt/nal-rbsp.h
> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
> diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> similarity index 99%
> rename from drivers/media/platform/allegro-dvt/allegro-core.c
> rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> index e491399afcc9..8895d7755987 100644
> --- a/drivers/media/platform/allegro-dvt/allegro-core.c
> +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> @@ -31,7 +31,7 @@
>  #include <media/videobuf2-dma-contig.h>
>  #include <media/videobuf2-v4l2.h>
>  
> -#include "allegro-mail.h"
> +#include "zynqmp-allegro-mail.h"
>  #include "nal-h264.h"
>  #include "nal-hevc.h"
>  
> diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> similarity index 99%
> rename from drivers/media/platform/allegro-dvt/allegro-mail.c
> rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> index aadc947a77ae..88a98f9e5d00 100644
> --- a/drivers/media/platform/allegro-dvt/allegro-mail.c
> +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> @@ -12,7 +12,7 @@
>  #include <linux/string.h>
>  #include <linux/videodev2.h>
>  
> -#include "allegro-mail.h"
> +#include "zynqmp-allegro-mail.h"
>  
>  const char *msg_type_name(enum mcu_msg_type type)
>  {
> diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.h b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
> similarity index 100%
> rename from drivers/media/platform/allegro-dvt/allegro-mail.h
> rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
> -- 
> 2.30.2
> 
> 

-- 
Pengutronix e.K.                           | Michael Tretter             |
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 s-vadapalli at ti.com  Mon Dec  2 02:58:46 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Mon, 2 Dec 2024 16:28:46 +0530
Subject: [PATCHv2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable
 ACSPCIE output for PCIe1
In-Reply-To: <dabbad2b-f8a6-4ed7-86da-ec696cf67461@kernel.org>
References: <20241202101140.48778-1-romain.naour@smile.fr>
 <dabbad2b-f8a6-4ed7-86da-ec696cf67461@kernel.org>
Message-ID: <k7udgqugqseweckb7hjniz3aops4kn35ttju2ju7f2pcbmndrg@dau5nr4leish>

On Mon, Dec 02, 2024 at 11:14:46AM +0100, Krzysztof Kozlowski wrote:

Hello Krzysztof,

> On 02/12/2024 11:11, Romain Naour wrote:
> > From: Romain Naour <romain.naour at skf.com>
> > 
> > Unlike the SK-TDA4VM (k3-j721e-sk) board, there is no clock generator
> > (CDCI6214RGET) on the BeagleBone AI-64 (k3-j721e-beagleboneai64) to
> > provide PCIe refclk signal to PCIe Endponts. So the ACSPCIE module must
> > provide refclk through PCIe_REFCLK pins.
> > 
> > Use the new "ti,syscon-acspcie-proxy-ctrl" property to enable ACSPCIE
> > module's PAD IO Buffers.
> > 
> > Reuse the compatible "ti,j784s4-acspcie-proxy-ctrl" since the ACSPCIE
> > buffer and its functionality is the same across all K3 SoCs.
> > 
> > Cc: Siddharth Vadapalli <s-vadapalli at ti.com>
> > Signed-off-by: Romain Naour <romain.naour at skf.com>
> > ---
> > With this patch, we can remove "HACK: Sierra: Drive clock out" patch
> > applied on vendor kernel for BeagleBone AI-64:
> > https://openbeagle.org/beagleboard/linux/-/commit/ad65d7ef675966cdbc5d75f2bd545fad1914ba9b
> > 
> > v2:
> >  - use generic style comments
> >  - use "syscon" as generic node name for "acspcie0_proxy_ctrl" node
> >  - Keep the compatible "ti,j784s4-acspcie-proxy-ctrl" since the
> >    ACSPCIE buffer and its functionality is the same across all K3 SoCs.
> >    (Siddharth Vadapalli)
> > 
> >    "The compatible "ti,j784s4-acspcie-pcie-ctrl" should be reused for
> >    J721E and all other K3 SoCs.
> 
> No, it shouldn't and you got comment on this. You always need specific
> compatible, see writing bindings doc.

Could you please clarify in which cases reusing the compatible is
permissible? The list of compatibles at:
https://github.com/torvalds/linux/blob/v6.12/Documentation/devicetree/bindings/mfd/syscon.yaml#L112
namely,
          - ti,am62-opp-efuse-table
          - ti,am62-usb-phy-ctrl
          - ti,am625-dss-oldi-io-ctrl
          - ti,am62p-cpsw-mac-efuse
          - ti,am654-dss-oldi-io-ctrl
          - ti,j784s4-pcie-ctrl
have all been reused for different TI SoCs since they all correspond to the
device functionality enabled via the CTRL_MMR System Controller registers.
The compatible "ti,j784s4-acspcie-pcie-ctrl" has also been added to the
list:
https://github.com/torvalds/linux/blob/v6.12/Documentation/devicetree/bindings/mfd/syscon.yaml#L117
with the intent of reusing it the same way that other compatibles have
been reused.

Regards,
Siddharth.


From linux at fw-web.de  Mon Dec  2 03:00:34 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 12:00:34 +0100
Subject: [PATCH v5 0/5] Add pinctrl support for mt7988
Message-ID: <20241202110045.22084-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This series adds pinctrl driver, dt-bindings and dts node for pinctrl
on mediatek mt7988 SoC.

changes in v5:
- rebased to 6.13-rc1
- moved dt nodes with mutliple options to BPI-R4 board
- changes suggested by angelo in v4
- changed example in binding and dt node to not using const MTK_DRIVE_8mA

changes in v4:
- fixed fixed string binding error

changes in v3:
- rebase on rafals dts patches
- update binding to have mux subnode as fixed string and conf with optional suffix

changes in v2:
  binding:
  - drop gpio-cells description
  - move ref in mux subnode up
  - order uart-functions alphanumeric and fix typo
  dts:
  - fix indentation of reg-values

Daniel Golle (2):
  pinctrl: mediatek: add support for MTK_PULL_PD_TYPE
  pinctrl: mediatek: add MT7988 pinctrl driver

Frank Wunderlich (3):
  dt-bindings: pinctrl: add binding for MT7988 SoC
  arm64: dts: mediatek: mt7988: add pinctrl support
  arm64: dts: mediatek: mt7988: add pinctrl subnodes for bpi-r4

 .../pinctrl/mediatek,mt7988-pinctrl.yaml      |  578 ++++++
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  |  189 ++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi     |   54 +
 drivers/pinctrl/mediatek/Kconfig              |    7 +
 drivers/pinctrl/mediatek/Makefile             |    1 +
 drivers/pinctrl/mediatek/pinctrl-mt7988.c     | 1556 +++++++++++++++++
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  |   73 +-
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |    1 +
 8 files changed, 2448 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c

-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 03:00:38 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 12:00:38 +0100
Subject: [PATCH v5 4/5] arm64: dts: mediatek: mt7988: add pinctrl support
In-Reply-To: <20241202110045.22084-1-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
Message-ID: <20241202110045.22084-5-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add mt7988a pinctrl node.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
v5:
- drop pins with second function

v2:
- fix wrong alignment of reg values
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 54 +++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index c9649b815276..46969577c87a 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -3,6 +3,7 @@
 #include <dt-bindings/clock/mediatek,mt7988-clk.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
 
 / {
 	compatible = "mediatek,mt7988a";
@@ -105,6 +106,59 @@ clock-controller at 1001e000 {
 			#clock-cells = <1>;
 		};
 
+		pio: pinctrl at 1001f000 {
+			compatible = "mediatek,mt7988-pinctrl";
+			reg = <0 0x1001f000 0 0x1000>,
+			      <0 0x11c10000 0 0x1000>,
+			      <0 0x11d00000 0 0x1000>,
+			      <0 0x11d20000 0 0x1000>,
+			      <0 0x11e00000 0 0x1000>,
+			      <0 0x11f00000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "gpio", "iocfg_tr",
+				    "iocfg_br", "iocfg_rb",
+				    "iocfg_lb", "iocfg_tl", "eint";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pio 0 0 84>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&gic>;
+			#interrupt-cells = <2>;
+
+			pcie0_pins: pcie0-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
+						 "pcie_wake_n0_0";
+				};
+			};
+
+			pcie1_pins: pcie1-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
+						 "pcie_wake_n1_0";
+				};
+			};
+
+			pcie2_pins: pcie2-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
+						 "pcie_wake_n2_0";
+				};
+			};
+
+			pcie3_pins: pcie3-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
+						 "pcie_wake_n3_0";
+				};
+			};
+		};
+
 		pwm at 10048000 {
 			compatible = "mediatek,mt7988-pwm";
 			reg = <0 0x10048000 0 0x1000>;
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 03:00:39 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 12:00:39 +0100
Subject: [PATCH v5 5/5] arm64: dts: mediatek: mt7988: add pinctrl subnodes for bpi-r4
In-Reply-To: <20241202110045.22084-1-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
Message-ID: <20241202110045.22084-6-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add board specidic pinctrl configurations on Bananapi R4.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 189 ++++++++++++++++++
 1 file changed, 189 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index efc4ad0b08b8..aa2dabc041fd 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -9,3 +9,192 @@ / {
 	model = "Banana Pi BPI-R4";
 	chassis-type = "embedded";
 };
+
+&pio {
+	mdio0_pins: mdio0-pins {
+		mux {
+			function = "eth";
+			groups = "mdc_mdio0";
+		};
+
+		conf {
+			pins = "SMI_0_MDC", "SMI_0_MDIO";
+			drive-strength = <8>;
+		};
+	};
+
+	i2c0_pins: i2c0-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c0_1";
+		};
+	};
+
+	i2c1_pins: i2c1-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_0";
+		};
+	};
+
+	i2c1_sfp_pins: i2c1-sfp-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_sfp";
+		};
+	};
+
+	i2c2_0_pins: i2c2-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c2_0";
+		};
+	};
+
+	i2c2_1_pins: i2c2-g1-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c2_1";
+		};
+	};
+
+	gbe0_led0_pins: gbe0-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe0_led0";
+		};
+	};
+
+	gbe1_led0_pins: gbe1-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe1_led0";
+		};
+	};
+
+	gbe2_led0_pins: gbe2-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe2_led0";
+		};
+	};
+
+	gbe3_led0_pins: gbe3-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe3_led0";
+		};
+	};
+
+	gbe0_led1_pins: gbe0-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe0_led1";
+		};
+	};
+
+	gbe1_led1_pins: gbe1-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe1_led1";
+		};
+	};
+
+	gbe2_led1_pins: gbe2-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe2_led1";
+		};
+	};
+
+	gbe3_led1_pins: gbe3-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe3_led1";
+		};
+	};
+
+	i2p5gbe_led0_pins: 2p5gbe-led0-pins {
+		mux {
+			function = "led";
+			groups = "2p5gbe_led0";
+		};
+	};
+
+	i2p5gbe_led1_pins: 2p5gbe-led1-pins {
+		mux {
+			function = "led";
+			groups = "2p5gbe_led1";
+		};
+	};
+
+	mmc0_pins_emmc_45: mmc0-emmc-45-pins {
+		mux {
+			function = "flash";
+			groups = "emmc_45";
+		};
+	};
+
+	mmc0_pins_emmc_51: mmc0-emmc-51-pins {
+		mux {
+			function = "flash";
+			groups = "emmc_51";
+		};
+	};
+
+	mmc0_pins_sdcard: mmc0-sdcard-pins {
+		mux {
+			function = "flash";
+			groups = "sdcard";
+		};
+	};
+
+	uart0_pins: uart0-pins {
+		mux {
+			function = "uart";
+			groups =  "uart0";
+		};
+	};
+
+	snfi_pins: snfi-pins {
+		mux {
+			function = "flash";
+			groups = "snfi";
+		};
+	};
+
+	spi0_pins: spi0-pins {
+		mux {
+			function = "spi";
+			groups = "spi0";
+		};
+	};
+
+	spi0_flash_pins: spi0-flash-pins {
+		mux {
+			function = "spi";
+			groups = "spi0", "spi0_wp_hold";
+		};
+	};
+
+	spi1_pins: spi1-pins {
+		mux {
+			function = "spi";
+			groups = "spi1";
+		};
+	};
+
+	spi2_pins: spi2-pins {
+		mux {
+			function = "spi";
+			groups = "spi2";
+		};
+	};
+
+	spi2_flash_pins: spi2-flash-pins {
+		mux {
+			function = "spi";
+			groups = "spi2", "spi2_wp_hold";
+		};
+	};
+};
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 03:00:35 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 12:00:35 +0100
Subject: [PATCH v5 1/5] pinctrl: mediatek: add support for MTK_PULL_PD_TYPE
In-Reply-To: <20241202110045.22084-1-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
Message-ID: <20241202110045.22084-2-linux@fw-web.de>

From: Daniel Golle <daniel at makrotopia.org>

The MediaTek MT7988 SoC got some pins which only got configurable
pull-down but unlike previous designs there is no pull-up option.
Add new type MTK_PULL_PD_TYPE to support configuring such pins.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
v5:
- add changes suggested by angelo (pd_only), long version, tested with emmc
---
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  | 73 ++++++++++++++++---
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |  1 +
 2 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 54301fbba524..7b704cc55c9f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1);
  */
 static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
 				const struct mtk_pin_desc *desc,
-				u32 pullup, u32 arg)
+				u32 pullup, u32 arg, bool pd_only)
 {
 	int err, pu, pd;
 
@@ -587,18 +587,34 @@ static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
 		pu = 0;
 		pd = 1;
 	} else {
-		err = -EINVAL;
-		goto out;
+		return -EINVAL;
 	}
 
-	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
-	if (err)
-		goto out;
+	if (!pd_only) {
+		err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
+		if (err)
+			return err;
+	}
 
-	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+}
+
+static int mtk_pinconf_bias_set_pd(struct mtk_pinctrl *hw,
+				const struct mtk_pin_desc *desc,
+				u32 pullup, u32 arg)
+{
+	int err, pd;
+
+	if (arg != MTK_DISABLE && arg != MTK_ENABLE)
+		return -EINVAL;
+
+	if (arg == MTK_DISABLE || pullup)
+		pd = 0;
+	else if (!pullup)
+		pd = 1;
+
+	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
 
-out:
-	return err;
 }
 
 static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
@@ -737,7 +753,7 @@ static int mtk_pinconf_bias_set_pu_pd_rsel(struct mtk_pinctrl *hw,
 			return err;
 	}
 
-	return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable);
+	return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable, false);
 }
 
 int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
@@ -758,8 +774,14 @@ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
 			return 0;
 	}
 
+	if (try_all_type & MTK_PULL_PD_TYPE) {
+		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, true);
+		if (!err)
+			return err;
+	}
+
 	if (try_all_type & MTK_PULL_PU_PD_TYPE) {
-		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, false);
 		if (!err)
 			return 0;
 	}
@@ -878,6 +900,29 @@ static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
 	return err;
 }
 
+static int mtk_pinconf_bias_get_pd(struct mtk_pinctrl *hw,
+				const struct mtk_pin_desc *desc,
+				u32 *pullup, u32 *enable)
+{
+	int err, pd;
+
+	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
+	if (err)
+		goto out;
+
+	if (pd == 0) {
+		*pullup = 0;
+		*enable = MTK_DISABLE;
+	} else if (pd == 1) {
+		*pullup = 0;
+		*enable = MTK_ENABLE;
+	} else
+		err = -EINVAL;
+
+out:
+	return err;
+}
+
 static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
 				const struct mtk_pin_desc *desc,
 				u32 *pullup, u32 *enable)
@@ -947,6 +992,12 @@ int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
 			return 0;
 	}
 
+	if (try_all_type & MTK_PULL_PD_TYPE) {
+		err = mtk_pinconf_bias_get_pd(hw, desc, pullup, enable);
+		if (!err)
+			return err;
+	}
+
 	if (try_all_type & MTK_PULL_PU_PD_TYPE) {
 		err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
 		if (!err)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 23688ca6d04e..9c271dc2b521 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -24,6 +24,7 @@
  * turned on/off itself. But it can't be selected pull up/down
  */
 #define MTK_PULL_RSEL_TYPE		BIT(3)
+#define MTK_PULL_PD_TYPE        BIT(4)
 /* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by
  * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE.
  */
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 03:00:36 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 12:00:36 +0100
Subject: [PATCH v5 2/5] pinctrl: mediatek: add MT7988 pinctrl driver
In-Reply-To: <20241202110045.22084-1-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
Message-ID: <20241202110045.22084-3-linux@fw-web.de>

From: Daniel Golle <daniel at makrotopia.org>

Add pinctrl driver for the MediaTek MT7988 SoC.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
[correctly initialise for the function_desc structure]
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

---
v5:
- changes requested by angelo
  - lowercase mt7988_pinctrl_reg_page
  - compatible match in one line
  - HW debounce is only available for pins 0 to 15 and does not support
    pins with numbers 16 or higher.
- add additional PWM pingroups
---
 drivers/pinctrl/mediatek/Kconfig          |    7 +
 drivers/pinctrl/mediatek/Makefile         |    1 +
 drivers/pinctrl/mediatek/pinctrl-mt7988.c | 1556 +++++++++++++++++++++
 3 files changed, 1564 insertions(+)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c

diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index a417a031659c..58f32818a0e6 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -202,6 +202,13 @@ config PINCTRL_MT7986
 	default ARM64 && ARCH_MEDIATEK
 	select PINCTRL_MTK_MOORE
 
+config PINCTRL_MT7988
+	bool "Mediatek MT7988 pin control"
+	depends on OF
+	depends on ARM64 || COMPILE_TEST
+	default ARM64 && ARCH_MEDIATEK
+	select PINCTRL_MTK_MOORE
+
 config PINCTRL_MT8167
 	bool "MediaTek MT8167 pin control"
 	depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 1405d434218e..721ae83476d0 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_PINCTRL_MT7623)		+= pinctrl-mt7623.o
 obj-$(CONFIG_PINCTRL_MT7629)		+= pinctrl-mt7629.o
 obj-$(CONFIG_PINCTRL_MT7981)		+= pinctrl-mt7981.o
 obj-$(CONFIG_PINCTRL_MT7986)		+= pinctrl-mt7986.o
+obj-$(CONFIG_PINCTRL_MT7988)		+= pinctrl-mt7988.o
 obj-$(CONFIG_PINCTRL_MT8167)		+= pinctrl-mt8167.o
 obj-$(CONFIG_PINCTRL_MT8173)		+= pinctrl-mt8173.o
 obj-$(CONFIG_PINCTRL_MT8183)		+= pinctrl-mt8183.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7988.c b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
new file mode 100644
index 000000000000..9d59ac2d2e4f
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
@@ -0,0 +1,1556 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7988 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2020 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ */
+
+#include "pinctrl-moore.h"
+
+enum mt7988_pinctrl_reg_page {
+	GPIO_BASE,
+	IOCFG_TR_BASE,
+	IOCFG_BR_BASE,
+	IOCFG_RB_BASE,
+	IOCFG_LB_BASE,
+	IOCFG_TL_BASE,
+};
+
+#define MT7988_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+		       _x_bits)                                                \
+	PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+		       _x_bits, 32, 0)
+
+#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,    \
+			_x_bits)                                               \
+	PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+		       _x_bits, 32, 1)
+
+static const struct mtk_pin_field_calc mt7988_pin_mode_range[] = {
+	PIN_FIELD(0, 83, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_dir_range[] = {
+	PIN_FIELD(0, 83, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_di_range[] = {
+	PIN_FIELD(0, 83, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_do_range[] = {
+	PIN_FIELD(0, 83, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_ies_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x30, 0x10, 13, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x30, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0x30, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x40, 0x10, 21, 1),
+	PIN_FIELD_BASE(13, 13, 1, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0x40, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(15, 15, 5, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(16, 16, 5, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(17, 17, 5, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(18, 18, 5, 0x30, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x30, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x50, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x50, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x50, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x50, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x50, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x50, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x50, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x50, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x50, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x50, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x50, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x50, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x50, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x50, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x50, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x50, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x50, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x50, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x50, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x40, 0x10, 13, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(63, 63, 1, 0x40, 0x10, 20, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x40, 0x10, 11, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x40, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(71, 71, 5, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(72, 72, 5, 0x30, 0x10, 6, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(75, 75, 4, 0x30, 0x10, 11, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0x30, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x40, 0x10, 18, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x40, 0x10, 19, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x40, 0x10, 17, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_smt_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0xc0, 0x10, 13, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0xc0, 0x10, 14, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0xc0, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0xc0, 0x10, 12, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0xc0, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0xc0, 0x10, 9, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0xc0, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(7, 7, 4, 0xb0, 0x10, 8, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0xb0, 0x10, 6, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0xb0, 0x10, 5, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0xb0, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0xe0, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0xe0, 0x10, 21, 1),
+	PIN_FIELD_BASE(13, 13, 1, 0xe0, 0x10, 1, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0xe0, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(15, 15, 5, 0xc0, 0x10, 7, 1),
+	PIN_FIELD_BASE(16, 16, 5, 0xc0, 0x10, 8, 1),
+	PIN_FIELD_BASE(17, 17, 5, 0xc0, 0x10, 3, 1),
+	PIN_FIELD_BASE(18, 18, 5, 0xc0, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0xb0, 0x10, 7, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0xb0, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x140, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x140, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x140, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x140, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x140, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x140, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x140, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x140, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x140, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x140, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x140, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x140, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0x150, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x140, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x140, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x140, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x150, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x140, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x140, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x140, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x140, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x140, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x140, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x140, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x140, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x140, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x140, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x140, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x140, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x140, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x140, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x140, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x140, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x140, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0xe0, 0x10, 14, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0xe0, 0x10, 15, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0xe0, 0x10, 13, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0xe0, 0x10, 4, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0xe0, 0x10, 5, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0xe0, 0x10, 6, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0xe0, 0x10, 3, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0xe0, 0x10, 7, 1),
+	PIN_FIELD_BASE(63, 63, 1, 0xe0, 0x10, 20, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0xe0, 0x10, 8, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0xe0, 0x10, 9, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0xe0, 0x10, 10, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0xe0, 0x10, 11, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0xe0, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0xc0, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0xc0, 0x10, 2, 1),
+	PIN_FIELD_BASE(71, 71, 5, 0xc0, 0x10, 5, 1),
+	PIN_FIELD_BASE(72, 72, 5, 0xc0, 0x10, 6, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0xb0, 0x10, 10, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0xb0, 0x10, 1, 1),
+	PIN_FIELD_BASE(75, 75, 4, 0xb0, 0x10, 11, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0xb0, 0x10, 9, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0xb0, 0x10, 2, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0xb0, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0xb0, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0xe0, 0x10, 18, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0xe0, 0x10, 19, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0xe0, 0x10, 16, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0xe0, 0x10, 17, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_pu_range[] = {
+	PIN_FIELD_BASE(7, 7, 4, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x60, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0x60, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(13, 13, 1, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(63, 63, 1, 0x70, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(75, 75, 4, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0x60, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_pd_range[] = {
+	PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0x40, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(13, 13, 1, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0x50, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(15, 15, 5, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(16, 16, 5, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(17, 17, 5, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(18, 18, 5, 0x40, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(63, 63, 1, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(71, 71, 5, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(72, 72, 5, 0x40, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(75, 75, 4, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0x40, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_drv_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(1, 1, 5, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(3, 3, 5, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(4, 4, 5, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(5, 5, 5, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(6, 6, 5, 0x00, 0x10, 12, 3),
+
+	PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 28, 3),
+	PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(10, 10, 4, 0x00, 0x10, 9, 3),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(12, 12, 1, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(13, 13, 1, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(14, 14, 1, 0x00, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(20, 20, 4, 0x00, 0x10, 12, 3),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x10, 0x10, 21, 3),
+	PIN_FIELD_BASE(22, 22, 3, 0x20, 0x10, 9, 3),
+	PIN_FIELD_BASE(23, 23, 3, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(24, 24, 3, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(25, 25, 3, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(26, 26, 3, 0x20, 0x10, 6, 3),
+	PIN_FIELD_BASE(27, 27, 3, 0x10, 0x10, 24, 3),
+	PIN_FIELD_BASE(28, 28, 3, 0x20, 0x10, 15, 3),
+	PIN_FIELD_BASE(29, 29, 3, 0x20, 0x10, 18, 3),
+	PIN_FIELD_BASE(30, 30, 3, 0x20, 0x10, 21, 3),
+	PIN_FIELD_BASE(31, 31, 3, 0x20, 0x10, 12, 3),
+	PIN_FIELD_BASE(32, 32, 3, 0x20, 0x10, 24, 3),
+	PIN_FIELD_BASE(33, 33, 3, 0x30, 0x10, 6, 3),
+	PIN_FIELD_BASE(34, 34, 3, 0x30, 0x10, 3, 3),
+	PIN_FIELD_BASE(35, 35, 3, 0x20, 0x10, 27, 3),
+	PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 0, 3),
+	PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 9, 3),
+	PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(40, 40, 3, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(41, 41, 3, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(42, 42, 3, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(43, 43, 3, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(44, 44, 3, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(45, 45, 3, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(46, 46, 3, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(47, 47, 3, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(48, 48, 3, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(49, 49, 3, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(50, 50, 3, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(51, 51, 3, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(52, 52, 3, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(53, 53, 3, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(54, 54, 3, 0x10, 0x10, 18, 3),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(56, 56, 1, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(57, 57, 1, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(58, 58, 1, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(59, 59, 1, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(60, 60, 1, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(61, 61, 1, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(62, 62, 1, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(63, 63, 1, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(64, 64, 1, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(65, 65, 1, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(66, 66, 1, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(67, 67, 1, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(68, 68, 1, 0x10, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(70, 70, 5, 0x00, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(74, 74, 4, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(75, 75, 4, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(76, 76, 4, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(77, 77, 4, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(78, 78, 4, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(79, 79, 4, 0x10, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x10, 0x10, 24, 3),
+	PIN_FIELD_BASE(81, 81, 1, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(82, 82, 1, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(83, 83, 1, 0x10, 0x10, 21, 3),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_pupd_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x50, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x60, 0x10, 18, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x50, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x70, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x70, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x70, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x70, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x70, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x70, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x70, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x70, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x70, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x70, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x70, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x70, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x70, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x70, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x70, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x70, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x70, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x70, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x70, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x70, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x70, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x70, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x70, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x70, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x70, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x70, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x70, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x60, 0x10, 12, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x60, 0x10, 13, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x60, 0x10, 11, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x60, 0x10, 4, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x60, 0x10, 9, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x60, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x50, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x50, 0x10, 0, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x60, 0x10, 16, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x60, 0x10, 17, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x60, 0x10, 14, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x60, 0x10, 15, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_r0_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x60, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x80, 0x10, 18, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x70, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x90, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x90, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x90, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x90, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x90, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x90, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x90, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x90, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x90, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x90, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x90, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x90, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0xa0, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x90, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x90, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x90, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0xa0, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x90, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x90, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x90, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x90, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x90, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x90, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x90, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x90, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x80, 0x10, 12, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x80, 0x10, 13, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x80, 0x10, 11, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x80, 0x10, 3, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x80, 0x10, 4, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x80, 0x10, 5, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x80, 0x10, 6, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x80, 0x10, 7, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x80, 0x10, 8, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x80, 0x10, 9, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x80, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x60, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x70, 0x10, 0, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x80, 0x10, 16, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x80, 0x10, 17, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x80, 0x10, 14, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x80, 0x10, 15, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_r1_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x70, 0x10, 7, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x70, 0x10, 5, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x70, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x70, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x90, 0x10, 18, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x80, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0xb0, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0xb0, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0xb0, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0xb0, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0xb0, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0xb0, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0xb0, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0xb0, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0xb0, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0xb0, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0xb0, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0xb0, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0xc0, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0xb0, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0xb0, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0xb0, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0xc0, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0xb0, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0xb0, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0xb0, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0xb0, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0xb0, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0xb0, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0xb0, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0xb0, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0xb0, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0xb0, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0xb0, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0xb0, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0xb0, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0xb0, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0xb0, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0xb0, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0xb0, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x90, 0x10, 12, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x90, 0x10, 13, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x90, 0x10, 11, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x90, 0x10, 6, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x90, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x70, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x80, 0x10, 3, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x80, 0x10, 0, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x90, 0x10, 16, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x90, 0x10, 17, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x90, 0x10, 14, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x90, 0x10, 15, 1),
+};
+
+static const unsigned int mt7988_pull_type[] = {
+	MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PU_PD_TYPE,    /*7*/
+	MTK_PULL_PU_PD_TYPE,    /*8*/ MTK_PULL_PU_PD_TYPE,    /*9*/
+	MTK_PULL_PU_PD_TYPE,    /*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PU_PD_TYPE,    /*13*/
+	MTK_PULL_PU_PD_TYPE,    /*14*/ MTK_PULL_PD_TYPE,       /*15*/
+	MTK_PULL_PD_TYPE,       /*16*/ MTK_PULL_PD_TYPE,       /*17*/
+	MTK_PULL_PD_TYPE,       /*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PU_PD_TYPE,    /*63*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PUPD_R1R0_TYPE,/*69*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*70*/ MTK_PULL_PD_TYPE,       /*71*/
+	MTK_PULL_PD_TYPE,       /*72*/ MTK_PULL_PUPD_R1R0_TYPE,/*73*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,    /*75*/
+	MTK_PULL_PU_PD_TYPE,    /*76*/ MTK_PULL_PU_PD_TYPE,    /*77*/
+	MTK_PULL_PU_PD_TYPE,    /*78*/ MTK_PULL_PU_PD_TYPE,    /*79*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*80*/ MTK_PULL_PUPD_R1R0_TYPE,/*81*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*82*/ MTK_PULL_PUPD_R1R0_TYPE,/*83*/
+};
+
+static const struct mtk_pin_reg_calc mt7988_reg_cals[] = {
+	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7988_pin_mode_range),
+	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7988_pin_dir_range),
+	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7988_pin_di_range),
+	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7988_pin_do_range),
+	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7988_pin_smt_range),
+	[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7988_pin_ies_range),
+	[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7988_pin_pu_range),
+	[PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7988_pin_pd_range),
+	[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7988_pin_drv_range),
+	[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7988_pin_pupd_range),
+	[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7988_pin_r0_range),
+	[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7988_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7988_pins[] = {
+	MT7988_PIN(0, "UART2_RXD"),
+	MT7988_PIN(1, "UART2_TXD"),
+	MT7988_PIN(2, "UART2_CTS"),
+	MT7988_PIN(3, "UART2_RTS"),
+	MT7988_PIN(4, "GPIO_A"),
+	MT7988_PIN(5, "SMI_0_MDC"),
+	MT7988_PIN(6, "SMI_0_MDIO"),
+	MT7988_PIN(7, "PCIE30_2L_0_WAKE_N"),
+	MT7988_PIN(8, "PCIE30_2L_0_CLKREQ_N"),
+	MT7988_PIN(9, "PCIE30_1L_1_WAKE_N"),
+	MT7988_PIN(10, "PCIE30_1L_1_CLKREQ_N"),
+	MT7988_PIN(11, "GPIO_P"),
+	MT7988_PIN(12, "WATCHDOG"),
+	MT7988_PIN(13, "GPIO_RESET"),
+	MT7988_PIN(14, "GPIO_WPS"),
+	MT7988_PIN(15, "PMIC_I2C_SCL"),
+	MT7988_PIN(16, "PMIC_I2C_SDA"),
+	MT7988_PIN(17, "I2C_1_SCL"),
+	MT7988_PIN(18, "I2C_1_SDA"),
+	MT7988_PIN(19, "PCIE30_2L_0_PRESET_N"),
+	MT7988_PIN(20, "PCIE30_1L_1_PRESET_N"),
+	MT7988_PIN(21, "PWMD1"),
+	MT7988_PIN(22, "SPI0_WP"),
+	MT7988_PIN(23, "SPI0_HOLD"),
+	MT7988_PIN(24, "SPI0_CSB"),
+	MT7988_PIN(25, "SPI0_MISO"),
+	MT7988_PIN(26, "SPI0_MOSI"),
+	MT7988_PIN(27, "SPI0_CLK"),
+	MT7988_PIN(28, "SPI1_CSB"),
+	MT7988_PIN(29, "SPI1_MISO"),
+	MT7988_PIN(30, "SPI1_MOSI"),
+	MT7988_PIN(31, "SPI1_CLK"),
+	MT7988_PIN(32, "SPI2_CLK"),
+	MT7988_PIN(33, "SPI2_MOSI"),
+	MT7988_PIN(34, "SPI2_MISO"),
+	MT7988_PIN(35, "SPI2_CSB"),
+	MT7988_PIN(36, "SPI2_HOLD"),
+	MT7988_PIN(37, "SPI2_WP"),
+	MT7988_PIN(38, "EMMC_RSTB"),
+	MT7988_PIN(39, "EMMC_DSL"),
+	MT7988_PIN(40, "EMMC_CK"),
+	MT7988_PIN(41, "EMMC_CMD"),
+	MT7988_PIN(42, "EMMC_DATA_7"),
+	MT7988_PIN(43, "EMMC_DATA_6"),
+	MT7988_PIN(44, "EMMC_DATA_5"),
+	MT7988_PIN(45, "EMMC_DATA_4"),
+	MT7988_PIN(46, "EMMC_DATA_3"),
+	MT7988_PIN(47, "EMMC_DATA_2"),
+	MT7988_PIN(48, "EMMC_DATA_1"),
+	MT7988_PIN(49, "EMMC_DATA_0"),
+	MT7988_PIN(50, "PCM_FS_I2S_LRCK"),
+	MT7988_PIN(51, "PCM_CLK_I2S_BCLK"),
+	MT7988_PIN(52, "PCM_DRX_I2S_DIN"),
+	MT7988_PIN(53, "PCM_DTX_I2S_DOUT"),
+	MT7988_PIN(54, "PCM_MCK_I2S_MCLK"),
+	MT7988_PIN(55, "UART0_RXD"),
+	MT7988_PIN(56, "UART0_TXD"),
+	MT7988_PIN(57, "PWMD0"),
+	MT7988_PIN(58, "JTAG_JTDI"),
+	MT7988_PIN(59, "JTAG_JTDO"),
+	MT7988_PIN(60, "JTAG_JTMS"),
+	MT7988_PIN(61, "JTAG_JTCLK"),
+	MT7988_PIN(62, "JTAG_JTRST_N"),
+	MT7988_PIN(63, "USB_DRV_VBUS_P1"),
+	MT7988_PIN(64, "LED_A"),
+	MT7988_PIN(65, "LED_B"),
+	MT7988_PIN(66, "LED_C"),
+	MT7988_PIN(67, "LED_D"),
+	MT7988_PIN(68, "LED_E"),
+	MT7988_PIN(69, "GPIO_B"),
+	MT7988_PIN(70, "GPIO_C"),
+	MT7988_PIN(71, "I2C_2_SCL"),
+	MT7988_PIN(72, "I2C_2_SDA"),
+	MT7988_PIN(73, "PCIE30_2L_1_PRESET_N"),
+	MT7988_PIN(74, "PCIE30_1L_0_PRESET_N"),
+	MT7988_PIN(75, "PCIE30_2L_1_WAKE_N"),
+	MT7988_PIN(76, "PCIE30_2L_1_CLKREQ_N"),
+	MT7988_PIN(77, "PCIE30_1L_0_WAKE_N"),
+	MT7988_PIN(78, "PCIE30_1L_0_CLKREQ_N"),
+	MT7988_PIN(79, "USB_DRV_VBUS_P0"),
+	MT7988_PIN(80, "UART1_RXD"),
+	MT7988_PIN(81, "UART1_TXD"),
+	MT7988_PIN(82, "UART1_CTS"),
+	MT7988_PIN(83, "UART1_RTS"),
+};
+
+/* jtag */
+static int mt7988_tops_jtag0_0_pins[] = { 0, 1, 2, 3, 4 };
+static int mt7988_tops_jtag0_0_funcs[] = { 2, 2, 2, 2, 2 };
+
+static int mt7988_wo0_jtag_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_wo0_jtag_funcs[] = { 3, 3, 3, 3, 3 };
+
+static int mt7988_wo1_jtag_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_wo1_jtag_funcs[] = { 4, 4, 4, 4, 4 };
+
+static int mt7988_wo2_jtag_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_wo2_jtag_funcs[] = { 5, 5, 5, 5, 5 };
+
+static int mt7988_jtag_pins[] = { 58, 59, 60, 61, 62 };
+static int mt7988_jtag_funcs[] = { 1, 1, 1, 1, 1 };
+
+static int mt7988_tops_jtag0_1_pins[] = { 58, 59, 60, 61, 62 };
+static int mt7988_tops_jtag0_1_funcs[] = { 4, 4, 4, 4, 4 };
+
+/* int_usxgmii */
+static int mt7988_int_usxgmii_pins[] = { 2, 3 };
+static int mt7988_int_usxgmii_funcs[] = { 3, 3 };
+
+/* pwm */
+static int mt7988_pwm0_pins[] = { 57 };
+static int mt7988_pwm0_funcs[] = { 1 };
+
+static int mt7988_pwm1_pins[] = { 21 };
+static int mt7988_pwm1_funcs[] = { 1 };
+
+static int mt7988_pwm2_pins[] = { 80 };
+static int mt7988_pwm2_funcs[] = { 2 };
+
+static int mt7988_pwm2_0_pins[] = { 58 };
+static int mt7988_pwm2_0_funcs[] = { 5 };
+
+static int mt7988_pwm3_pins[] = { 81 };
+static int mt7988_pwm3_funcs[] = { 2 };
+
+static int mt7988_pwm3_0_pins[] = { 59 };
+static int mt7988_pwm3_0_funcs[] = { 5 };
+
+static int mt7988_pwm4_pins[] = { 82 };
+static int mt7988_pwm4_funcs[] = { 2 };
+
+static int mt7988_pwm4_0_pins[] = { 60 };
+static int mt7988_pwm4_0_funcs[] = { 5 };
+
+static int mt7988_pwm5_pins[] = { 83 };
+static int mt7988_pwm5_funcs[] = { 2 };
+
+static int mt7988_pwm5_0_pins[] = { 61 };
+static int mt7988_pwm5_0_funcs[] = { 5 };
+
+static int mt7988_pwm6_pins[] = { 69 };
+static int mt7988_pwm6_funcs[] = { 3 };
+
+static int mt7988_pwm6_0_pins[] = { 62 };
+static int mt7988_pwm6_0_funcs[] = { 5 };
+
+static int mt7988_pwm7_pins[] = { 70 };
+static int mt7988_pwm7_funcs[] = { 3 };
+
+static int mt7988_pwm7_0_pins[] = { 4 };
+static int mt7988_pwm7_0_funcs[] = { 3 };
+
+/* dfd */
+static int mt7988_dfd_pins[] = { 0, 1, 2, 3, 4 };
+static int mt7988_dfd_funcs[] = { 4, 4, 4, 4, 4 };
+
+/* i2c */
+static int mt7988_xfi_phy0_i2c0_pins[] = { 0, 1 };
+static int mt7988_xfi_phy0_i2c0_funcs[] = { 5, 5 };
+
+static int mt7988_xfi_phy1_i2c0_pins[] = { 0, 1 };
+static int mt7988_xfi_phy1_i2c0_funcs[] = { 6, 6 };
+
+static int mt7988_xfi_phy_pll_i2c0_pins[] = { 3, 4 };
+static int mt7988_xfi_phy_pll_i2c0_funcs[] = { 5, 5 };
+
+static int mt7988_xfi_phy_pll_i2c1_pins[] = { 3, 4 };
+static int mt7988_xfi_phy_pll_i2c1_funcs[] = { 6, 6 };
+
+static int mt7988_i2c0_0_pins[] = { 5, 6 };
+static int mt7988_i2c0_0_funcs[] = { 2, 2 };
+
+static int mt7988_i2c1_sfp_pins[] = { 5, 6 };
+static int mt7988_i2c1_sfp_funcs[] = { 4, 4 };
+
+static int mt7988_xfi_pextp_phy0_i2c_pins[] = { 5, 6 };
+static int mt7988_xfi_pextp_phy0_i2c_funcs[] = { 5, 5 };
+
+static int mt7988_xfi_pextp_phy1_i2c_pins[] = { 5, 6 };
+static int mt7988_xfi_pextp_phy1_i2c_funcs[] = { 6, 6 };
+
+static int mt7988_i2c0_1_pins[] = { 15, 16 };
+static int mt7988_i2c0_1_funcs[] = { 1, 1 };
+
+static int mt7988_u30_phy_i2c0_pins[] = { 15, 16 };
+static int mt7988_u30_phy_i2c0_funcs[] = { 2, 2 };
+
+static int mt7988_u32_phy_i2c0_pins[] = { 15, 16 };
+static int mt7988_u32_phy_i2c0_funcs[] = { 3, 3 };
+
+static int mt7988_xfi_phy0_i2c1_pins[] = { 15, 16 };
+static int mt7988_xfi_phy0_i2c1_funcs[] = { 5, 5 };
+
+static int mt7988_xfi_phy1_i2c1_pins[] = { 15, 16 };
+static int mt7988_xfi_phy1_i2c1_funcs[] = { 6, 6 };
+
+static int mt7988_xfi_phy_pll_i2c2_pins[] = { 15, 16 };
+static int mt7988_xfi_phy_pll_i2c2_funcs[] = { 7, 7 };
+
+static int mt7988_i2c1_0_pins[] = { 17, 18 };
+static int mt7988_i2c1_0_funcs[] = { 1, 1 };
+
+static int mt7988_u30_phy_i2c1_pins[] = { 17, 18 };
+static int mt7988_u30_phy_i2c1_funcs[] = { 2, 2 };
+
+static int mt7988_u32_phy_i2c1_pins[] = { 17, 18 };
+static int mt7988_u32_phy_i2c1_funcs[] = { 3, 3 };
+
+static int mt7988_xfi_phy_pll_i2c3_pins[] = { 17, 18 };
+static int mt7988_xfi_phy_pll_i2c3_funcs[] = { 4, 4 };
+
+static int mt7988_sgmii0_i2c_pins[] = { 17, 18 };
+static int mt7988_sgmii0_i2c_funcs[] = { 5, 5 };
+
+static int mt7988_sgmii1_i2c_pins[] = { 17, 18 };
+static int mt7988_sgmii1_i2c_funcs[] = { 6, 6 };
+
+static int mt7988_i2c1_2_pins[] = { 69, 70 };
+static int mt7988_i2c1_2_funcs[] = { 2, 2 };
+
+static int mt7988_i2c2_0_pins[] = { 69, 70 };
+static int mt7988_i2c2_0_funcs[] = { 4, 4 };
+
+static int mt7988_i2c2_1_pins[] = { 71, 72 };
+static int mt7988_i2c2_1_funcs[] = { 1, 1 };
+
+/* eth */
+static int mt7988_mdc_mdio0_pins[] = { 5, 6 };
+static int mt7988_mdc_mdio0_funcs[] = { 1, 1 };
+
+static int mt7988_2p5g_ext_mdio_pins[] = { 28, 29 };
+static int mt7988_2p5g_ext_mdio_funcs[] = { 6, 6 };
+
+static int mt7988_gbe_ext_mdio_pins[] = { 30, 31 };
+static int mt7988_gbe_ext_mdio_funcs[] = { 6, 6 };
+
+static int mt7988_mdc_mdio1_pins[] = { 69, 70 };
+static int mt7988_mdc_mdio1_funcs[] = { 1, 1 };
+
+/* pcie */
+static int mt7988_pcie_wake_n0_0_pins[] = { 7 };
+static int mt7988_pcie_wake_n0_0_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n0_0_pins[] = { 8 };
+static int mt7988_pcie_clk_req_n0_0_funcs[] = { 1 };
+
+static int mt7988_pcie_wake_n3_0_pins[] = { 9 };
+static int mt7988_pcie_wake_n3_0_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n3_pins[] = { 10 };
+static int mt7988_pcie_clk_req_n3_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n0_1_pins[] = { 10 };
+static int mt7988_pcie_clk_req_n0_1_funcs[] = { 2 };
+
+static int mt7988_pcie_p0_phy_i2c_pins[] = { 7, 8 };
+static int mt7988_pcie_p0_phy_i2c_funcs[] = { 3, 3 };
+
+static int mt7988_pcie_p1_phy_i2c_pins[] = { 7, 8 };
+static int mt7988_pcie_p1_phy_i2c_funcs[] = { 4, 4 };
+
+static int mt7988_pcie_p3_phy_i2c_pins[] = { 9, 10 };
+static int mt7988_pcie_p3_phy_i2c_funcs[] = { 4, 4 };
+
+static int mt7988_pcie_p2_phy_i2c_pins[] = { 7, 8 };
+static int mt7988_pcie_p2_phy_i2c_funcs[] = { 5, 5 };
+
+static int mt7988_ckm_phy_i2c_pins[] = { 9, 10 };
+static int mt7988_ckm_phy_i2c_funcs[] = { 5, 5 };
+
+static int mt7988_pcie_wake_n0_1_pins[] = { 13 };
+static int mt7988_pcie_wake_n0_1_funcs[] = { 2 };
+
+static int mt7988_pcie_wake_n3_1_pins[] = { 14 };
+static int mt7988_pcie_wake_n3_1_funcs[] = { 2 };
+
+static int mt7988_pcie_2l_0_pereset_pins[] = { 19 };
+static int mt7988_pcie_2l_0_pereset_funcs[] = { 1 };
+
+static int mt7988_pcie_1l_1_pereset_pins[] = { 20 };
+static int mt7988_pcie_1l_1_pereset_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n2_1_pins[] = { 63 };
+static int mt7988_pcie_clk_req_n2_1_funcs[] = { 2 };
+
+static int mt7988_pcie_2l_1_pereset_pins[] = { 73 };
+static int mt7988_pcie_2l_1_pereset_funcs[] = { 1 };
+
+static int mt7988_pcie_1l_0_pereset_pins[] = { 74 };
+static int mt7988_pcie_1l_0_pereset_funcs[] = { 1 };
+
+static int mt7988_pcie_wake_n1_0_pins[] = { 75 };
+static int mt7988_pcie_wake_n1_0_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n1_pins[] = { 76 };
+static int mt7988_pcie_clk_req_n1_funcs[] = { 1 };
+
+static int mt7988_pcie_wake_n2_0_pins[] = { 77 };
+static int mt7988_pcie_wake_n2_0_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n2_0_pins[] = { 78 };
+static int mt7988_pcie_clk_req_n2_0_funcs[] = { 1 };
+
+static int mt7988_pcie_wake_n2_1_pins[] = { 79 };
+static int mt7988_pcie_wake_n2_1_funcs[] = { 2 };
+
+/* pmic */
+static int mt7988_pmic_pins[] = { 11 };
+static int mt7988_pmic_funcs[] = { 1 };
+
+/* watchdog */
+static int mt7988_watchdog_pins[] = { 12 };
+static int mt7988_watchdog_funcs[] = { 1 };
+
+/* spi */
+static int mt7988_spi0_wp_hold_pins[] = { 22, 23 };
+static int mt7988_spi0_wp_hold_funcs[] = { 1, 1 };
+
+static int mt7988_spi0_pins[] = { 24, 25, 26, 27 };
+static int mt7988_spi0_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_spi1_pins[] = { 28, 29, 30, 31 };
+static int mt7988_spi1_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_spi2_pins[] = { 32, 33, 34, 35 };
+static int mt7988_spi2_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_spi2_wp_hold_pins[] = { 36, 37 };
+static int mt7988_spi2_wp_hold_funcs[] = { 1, 1 };
+
+/* flash */
+static int mt7988_snfi_pins[] = { 22, 23, 24, 25, 26, 27 };
+static int mt7988_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
+
+static int mt7988_emmc_45_pins[] = {
+	21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
+};
+static int mt7988_emmc_45_funcs[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
+
+static int mt7988_sdcard_pins[] = { 32, 33, 34, 35, 36, 37 };
+static int mt7988_sdcard_funcs[] = { 5, 5, 5, 5, 5, 5 };
+
+static int mt7988_emmc_51_pins[] = { 38, 39, 40, 41, 42, 43,
+				     44, 45, 46, 47, 48, 49 };
+static int mt7988_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+
+/* uart */
+static int mt7988_uart2_pins[] = { 0, 1, 2, 3 };
+static int mt7988_uart2_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_tops_uart0_0_pins[] = { 22, 23 };
+static int mt7988_tops_uart0_0_funcs[] = { 3, 3 };
+
+static int mt7988_uart2_0_pins[] = { 28, 29, 30, 31 };
+static int mt7988_uart2_0_funcs[] = { 2, 2, 2, 2 };
+
+static int mt7988_uart1_0_pins[] = { 32, 33, 34, 35 };
+static int mt7988_uart1_0_funcs[] = { 2, 2, 2, 2 };
+
+static int mt7988_uart2_1_pins[] = { 32, 33, 34, 35 };
+static int mt7988_uart2_1_funcs[] = { 3, 3, 3, 3 };
+
+static int mt7988_net_wo0_uart_txd_0_pins[] = { 28 };
+static int mt7988_net_wo0_uart_txd_0_funcs[] = { 3 };
+
+static int mt7988_net_wo1_uart_txd_0_pins[] = { 29 };
+static int mt7988_net_wo1_uart_txd_0_funcs[] = { 3 };
+
+static int mt7988_net_wo2_uart_txd_0_pins[] = { 30 };
+static int mt7988_net_wo2_uart_txd_0_funcs[] = { 3 };
+
+static int mt7988_tops_uart1_0_pins[] = { 28, 29 };
+static int mt7988_tops_uart1_0_funcs[] = { 4, 4 };
+
+static int mt7988_tops_uart0_1_pins[] = { 30, 31 };
+static int mt7988_tops_uart0_1_funcs[] = { 4, 4 };
+
+static int mt7988_tops_uart1_1_pins[] = { 36, 37 };
+static int mt7988_tops_uart1_1_funcs[] = { 3, 3 };
+
+static int mt7988_uart0_pins[] = { 55, 56 };
+static int mt7988_uart0_funcs[] = { 1, 1 };
+
+static int mt7988_tops_uart0_2_pins[] = { 55, 56 };
+static int mt7988_tops_uart0_2_funcs[] = { 2, 2 };
+
+static int mt7988_uart2_2_pins[] = { 50, 51, 52, 53 };
+static int mt7988_uart2_2_funcs[] = { 2, 2, 2, 2 };
+
+static int mt7988_uart1_1_pins[] = { 58, 59, 60, 61 };
+static int mt7988_uart1_1_funcs[] = { 2, 2, 2, 2 };
+
+static int mt7988_uart2_3_pins[] = { 58, 59, 60, 61 };
+static int mt7988_uart2_3_funcs[] = { 3, 3, 3, 3 };
+
+static int mt7988_uart1_2_pins[] = { 80, 81, 82, 83 };
+static int mt7988_uart1_2_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_uart1_2_lite_pins[] = { 80, 81 };
+static int mt7988_uart1_2_lite_funcs[] = { 1, 1 };
+
+static int mt7988_tops_uart1_2_pins[] = { 80, 81 };
+static int mt7988_tops_uart1_2_funcs[] = { 4, 4, };
+
+static int mt7988_net_wo0_uart_txd_1_pins[] = { 80 };
+static int mt7988_net_wo0_uart_txd_1_funcs[] = { 3 };
+
+static int mt7988_net_wo1_uart_txd_1_pins[] = { 81 };
+static int mt7988_net_wo1_uart_txd_1_funcs[] = { 3 };
+
+static int mt7988_net_wo2_uart_txd_1_pins[] = { 82 };
+static int mt7988_net_wo2_uart_txd_1_funcs[] = { 3 };
+
+/* udi */
+static int mt7988_udi_pins[] = { 32, 33, 34, 35, 36 };
+static int mt7988_udi_funcs[] = { 4, 4, 4, 4, 4 };
+
+/* i2s */
+static int mt7988_i2s_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_i2s_funcs[] = { 1, 1, 1, 1, 1 };
+
+/* pcm */
+static int mt7988_pcm_pins[] = { 50, 51, 52, 53 };
+static int mt7988_pcm_funcs[] = { 1, 1, 1, 1 };
+
+/* led */
+static int mt7988_gbe0_led1_pins[] = { 58 };
+static int mt7988_gbe0_led1_funcs[] = { 6 };
+static int mt7988_gbe1_led1_pins[] = { 59 };
+static int mt7988_gbe1_led1_funcs[] = { 6 };
+static int mt7988_gbe2_led1_pins[] = { 60 };
+static int mt7988_gbe2_led1_funcs[] = { 6 };
+static int mt7988_gbe3_led1_pins[] = { 61 };
+static int mt7988_gbe3_led1_funcs[] = { 6 };
+
+static int mt7988_2p5gbe_led1_pins[] = { 62 };
+static int mt7988_2p5gbe_led1_funcs[] = { 6 };
+
+static int mt7988_gbe0_led0_pins[] = { 64 };
+static int mt7988_gbe0_led0_funcs[] = { 1 };
+static int mt7988_gbe1_led0_pins[] = { 65 };
+static int mt7988_gbe1_led0_funcs[] = { 1 };
+static int mt7988_gbe2_led0_pins[] = { 66 };
+static int mt7988_gbe2_led0_funcs[] = { 1 };
+static int mt7988_gbe3_led0_pins[] = { 67 };
+static int mt7988_gbe3_led0_funcs[] = { 1 };
+
+static int mt7988_2p5gbe_led0_pins[] = { 68 };
+static int mt7988_2p5gbe_led0_funcs[] = { 1 };
+
+/* usb */
+static int mt7988_drv_vbus_p1_pins[] = { 63 };
+static int mt7988_drv_vbus_p1_funcs[] = { 1 };
+
+static int mt7988_drv_vbus_pins[] = { 79 };
+static int mt7988_drv_vbus_funcs[] = { 1 };
+
+static const struct group_desc mt7988_groups[] = {
+	/*  @GPIO(0,1,2,3): uart2 */
+	PINCTRL_PIN_GROUP("uart2", mt7988_uart2),
+	/*  @GPIO(0,1,2,3,4): tops_jtag0_0 */
+	PINCTRL_PIN_GROUP("tops_jtag0_0", mt7988_tops_jtag0_0),
+	/*  @GPIO(2,3): int_usxgmii */
+	PINCTRL_PIN_GROUP("int_usxgmii", mt7988_int_usxgmii),
+	/*  @GPIO(0,1,2,3,4): dfd */
+	PINCTRL_PIN_GROUP("dfd", mt7988_dfd),
+	/*  @GPIO(0,1): xfi_phy0_i2c0 */
+	PINCTRL_PIN_GROUP("xfi_phy0_i2c0", mt7988_xfi_phy0_i2c0),
+	/*  @GPIO(0,1): xfi_phy1_i2c0 */
+	PINCTRL_PIN_GROUP("xfi_phy1_i2c0", mt7988_xfi_phy1_i2c0),
+	/*  @GPIO(3,4): xfi_phy_pll_i2c0 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c0", mt7988_xfi_phy_pll_i2c0),
+	/*  @GPIO(3,4): xfi_phy_pll_i2c1 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c1", mt7988_xfi_phy_pll_i2c1),
+	/*  @GPIO(4): pwm7 */
+	PINCTRL_PIN_GROUP("pwm7_0", mt7988_pwm7_0),
+	/*  @GPIO(5,6) i2c0_0 */
+	PINCTRL_PIN_GROUP("i2c0_0", mt7988_i2c0_0),
+	/*  @GPIO(5,6) i2c1_sfp */
+	PINCTRL_PIN_GROUP("i2c1_sfp", mt7988_i2c1_sfp),
+	/*  @GPIO(5,6) xfi_pextp_phy0_i2c */
+	PINCTRL_PIN_GROUP("xfi_pextp_phy0_i2c", mt7988_xfi_pextp_phy0_i2c),
+	/*  @GPIO(5,6) xfi_pextp_phy1_i2c */
+	PINCTRL_PIN_GROUP("xfi_pextp_phy1_i2c", mt7988_xfi_pextp_phy1_i2c),
+	/*  @GPIO(5,6) mdc_mdio0 */
+	PINCTRL_PIN_GROUP("mdc_mdio0", mt7988_mdc_mdio0),
+	/*  @GPIO(7): pcie_wake_n0_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n0_0", mt7988_pcie_wake_n0_0),
+	/*  @GPIO(8): pcie_clk_req_n0_0 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n0_0", mt7988_pcie_clk_req_n0_0),
+	/*  @GPIO(9): pcie_wake_n3_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n3_0", mt7988_pcie_wake_n3_0),
+	/*  @GPIO(10): pcie_clk_req_n3 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n3", mt7988_pcie_clk_req_n3),
+	/*  @GPIO(10): pcie_clk_req_n0_1 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n0_1", mt7988_pcie_clk_req_n0_1),
+	/*  @GPIO(7,8) pcie_p0_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p0_phy_i2c", mt7988_pcie_p0_phy_i2c),
+	/*  @GPIO(7,8) pcie_p1_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p1_phy_i2c", mt7988_pcie_p1_phy_i2c),
+	/*  @GPIO(7,8) pcie_p2_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p2_phy_i2c", mt7988_pcie_p2_phy_i2c),
+	/*  @GPIO(9,10) pcie_p3_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p3_phy_i2c", mt7988_pcie_p3_phy_i2c),
+	/*  @GPIO(9,10) ckm_phy_i2c */
+	PINCTRL_PIN_GROUP("ckm_phy_i2c", mt7988_ckm_phy_i2c),
+	/*  @GPIO(11): pmic */
+	PINCTRL_PIN_GROUP("pcie_pmic", mt7988_pmic),
+	/*  @GPIO(12): watchdog */
+	PINCTRL_PIN_GROUP("watchdog", mt7988_watchdog),
+	/*  @GPIO(13): pcie_wake_n0_1 */
+	PINCTRL_PIN_GROUP("pcie_wake_n0_1", mt7988_pcie_wake_n0_1),
+	/*  @GPIO(14): pcie_wake_n3_1 */
+	PINCTRL_PIN_GROUP("pcie_wake_n3_1", mt7988_pcie_wake_n3_1),
+	/*  @GPIO(15,16) i2c0_1 */
+	PINCTRL_PIN_GROUP("i2c0_1", mt7988_i2c0_1),
+	/*  @GPIO(15,16) u30_phy_i2c0 */
+	PINCTRL_PIN_GROUP("u30_phy_i2c0", mt7988_u30_phy_i2c0),
+	/*  @GPIO(15,16) u32_phy_i2c0 */
+	PINCTRL_PIN_GROUP("u32_phy_i2c0", mt7988_u32_phy_i2c0),
+	/*  @GPIO(15,16) xfi_phy0_i2c1 */
+	PINCTRL_PIN_GROUP("xfi_phy0_i2c1", mt7988_xfi_phy0_i2c1),
+	/*  @GPIO(15,16) xfi_phy1_i2c1 */
+	PINCTRL_PIN_GROUP("xfi_phy1_i2c1", mt7988_xfi_phy1_i2c1),
+	/*  @GPIO(15,16) xfi_phy_pll_i2c2 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c2", mt7988_xfi_phy_pll_i2c2),
+	/*  @GPIO(17,18) i2c1_0 */
+	PINCTRL_PIN_GROUP("i2c1_0", mt7988_i2c1_0),
+	/*  @GPIO(17,18) u30_phy_i2c1 */
+	PINCTRL_PIN_GROUP("u30_phy_i2c1", mt7988_u30_phy_i2c1),
+	/*  @GPIO(17,18) u32_phy_i2c1 */
+	PINCTRL_PIN_GROUP("u32_phy_i2c1", mt7988_u32_phy_i2c1),
+	/*  @GPIO(17,18) xfi_phy_pll_i2c3 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c3", mt7988_xfi_phy_pll_i2c3),
+	/*  @GPIO(17,18) sgmii0_i2c */
+	PINCTRL_PIN_GROUP("sgmii0_i2c", mt7988_sgmii0_i2c),
+	/*  @GPIO(17,18) sgmii1_i2c */
+	PINCTRL_PIN_GROUP("sgmii1_i2c", mt7988_sgmii1_i2c),
+	/*  @GPIO(19): pcie_2l_0_pereset */
+	PINCTRL_PIN_GROUP("pcie_2l_0_pereset", mt7988_pcie_2l_0_pereset),
+	/*  @GPIO(20): pcie_1l_1_pereset */
+	PINCTRL_PIN_GROUP("pcie_1l_1_pereset", mt7988_pcie_1l_1_pereset),
+	/*  @GPIO(21): pwm1 */
+	PINCTRL_PIN_GROUP("pwm1", mt7988_pwm1),
+	/*  @GPIO(22,23) spi0_wp_hold */
+	PINCTRL_PIN_GROUP("spi0_wp_hold", mt7988_spi0_wp_hold),
+	/*  @GPIO(24,25,26,27) spi0 */
+	PINCTRL_PIN_GROUP("spi0", mt7988_spi0),
+	/*  @GPIO(28,29,30,31) spi1 */
+	PINCTRL_PIN_GROUP("spi1", mt7988_spi1),
+	/*  @GPIO(32,33,34,35) spi2 */
+	PINCTRL_PIN_GROUP("spi2", mt7988_spi2),
+	/*  @GPIO(36,37) spi2_wp_hold */
+	PINCTRL_PIN_GROUP("spi2_wp_hold", mt7988_spi2_wp_hold),
+	/*  @GPIO(22,23,24,25,26,27) snfi */
+	PINCTRL_PIN_GROUP("snfi", mt7988_snfi),
+	/*  @GPIO(22,23) tops_uart0_0 */
+	PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart0_0),
+	/*  @GPIO(28,29,30,31) uart2_0 */
+	PINCTRL_PIN_GROUP("uart2_0", mt7988_uart2_0),
+	/*  @GPIO(32,33,34,35) uart1_0 */
+	PINCTRL_PIN_GROUP("uart1_0", mt7988_uart1_0),
+	/*  @GPIO(32,33,34,35) uart2_1 */
+	PINCTRL_PIN_GROUP("uart2_1", mt7988_uart2_1),
+	/*  @GPIO(28) net_wo0_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
+	/*  @GPIO(29) net_wo1_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
+	/*  @GPIO(30) net_wo2_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
+	/*  @GPIO(28,29) tops_uart1_0 */
+	PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart1_0),
+	/*  @GPIO(30,31) tops_uart0_1 */
+	PINCTRL_PIN_GROUP("tops_uart0_1", mt7988_tops_uart0_1),
+	/*  @GPIO(36,37) tops_uart1_1 */
+	PINCTRL_PIN_GROUP("tops_uart1_1", mt7988_tops_uart1_1),
+	/*  @GPIO(32,33,34,35,36) udi */
+	PINCTRL_PIN_GROUP("udi", mt7988_udi),
+	/*  @GPIO(21,28,29,30,31,32,33,34,35,36,37) emmc_45 */
+	PINCTRL_PIN_GROUP("emmc_45", mt7988_emmc_45),
+	/*  @GPIO(32,33,34,35,36,37) sdcard */
+	PINCTRL_PIN_GROUP("sdcard", mt7988_sdcard),
+	/*  @GPIO(38,39,40,41,42,43,44,45,46,47,48,49) emmc_51 */
+	PINCTRL_PIN_GROUP("emmc_51", mt7988_emmc_51),
+	/*  @GPIO(28,29) 2p5g_ext_mdio */
+	PINCTRL_PIN_GROUP("2p5g_ext_mdio", mt7988_2p5g_ext_mdio),
+	/*  @GPIO(30,31) gbe_ext_mdio */
+	PINCTRL_PIN_GROUP("gbe_ext_mdio", mt7988_gbe_ext_mdio),
+	/*  @GPIO(50,51,52,53,54) i2s */
+	PINCTRL_PIN_GROUP("i2s", mt7988_i2s),
+	/*  @GPIO(50,51,52,53) pcm */
+	PINCTRL_PIN_GROUP("pcm", mt7988_pcm),
+	/*  @GPIO(55,56) uart0 */
+	PINCTRL_PIN_GROUP("uart0", mt7988_uart0),
+	/*  @GPIO(55,56) tops_uart0_2 */
+	PINCTRL_PIN_GROUP("tops_uart0_2", mt7988_tops_uart0_2),
+	/*  @GPIO(50,51,52,53) uart2_2 */
+	PINCTRL_PIN_GROUP("uart2_2", mt7988_uart2_2),
+	/*  @GPIO(50,51,52,53,54) wo0_jtag */
+	PINCTRL_PIN_GROUP("wo0_jtag", mt7988_wo0_jtag),
+	/*  @GPIO(50,51,52,53,54) wo1-wo1_jtag */
+	PINCTRL_PIN_GROUP("wo1_jtag", mt7988_wo1_jtag),
+	/*  @GPIO(50,51,52,53,54) wo2_jtag */
+	PINCTRL_PIN_GROUP("wo2_jtag", mt7988_wo2_jtag),
+	/*  @GPIO(57) pwm0 */
+	PINCTRL_PIN_GROUP("pwm0", mt7988_pwm0),
+	/*  @GPIO(58) pwm2_0 */
+	PINCTRL_PIN_GROUP("pwm2_0", mt7988_pwm2_0),
+	/*  @GPIO(59) pwm3_0 */
+	PINCTRL_PIN_GROUP("pwm3_0", mt7988_pwm3_0),
+	/*  @GPIO(60) pwm4_0 */
+	PINCTRL_PIN_GROUP("pwm4_0", mt7988_pwm4_0),
+	/*  @GPIO(61) pwm5_0 */
+	PINCTRL_PIN_GROUP("pwm5_0", mt7988_pwm5_0),
+	/*  @GPIO(58,59,60,61,62) jtag */
+	PINCTRL_PIN_GROUP("jtag", mt7988_jtag),
+	/*  @GPIO(58,59,60,61,62) tops_jtag0_1 */
+	PINCTRL_PIN_GROUP("tops_jtag0_1", mt7988_tops_jtag0_1),
+	/*  @GPIO(58,59,60,61) uart2_3 */
+	PINCTRL_PIN_GROUP("uart2_3", mt7988_uart2_3),
+	/*  @GPIO(58,59,60,61) uart1_1 */
+	PINCTRL_PIN_GROUP("uart1_1", mt7988_uart1_1),
+	/*  @GPIO(58,59,60,61) gbe_led1 */
+	PINCTRL_PIN_GROUP("gbe0_led1", mt7988_gbe0_led1),
+	PINCTRL_PIN_GROUP("gbe1_led1", mt7988_gbe1_led1),
+	PINCTRL_PIN_GROUP("gbe2_led1", mt7988_gbe2_led1),
+	PINCTRL_PIN_GROUP("gbe3_led1", mt7988_gbe3_led1),
+	/*  @GPIO(62) pwm6_0 */
+	PINCTRL_PIN_GROUP("pwm6_0", mt7988_pwm6_0),
+	/*  @GPIO(62) 2p5gbe_led1 */
+	PINCTRL_PIN_GROUP("2p5gbe_led1", mt7988_2p5gbe_led1),
+	/*  @GPIO(64,65,66,67) gbe_led0 */
+	PINCTRL_PIN_GROUP("gbe0_led0", mt7988_gbe0_led0),
+	PINCTRL_PIN_GROUP("gbe1_led0", mt7988_gbe1_led0),
+	PINCTRL_PIN_GROUP("gbe2_led0", mt7988_gbe2_led0),
+	PINCTRL_PIN_GROUP("gbe3_led0", mt7988_gbe3_led0),
+	/*  @GPIO(68) 2p5gbe_led0 */
+	PINCTRL_PIN_GROUP("2p5gbe_led0", mt7988_2p5gbe_led0),
+	/*  @GPIO(63) drv_vbus_p1 */
+	PINCTRL_PIN_GROUP("drv_vbus_p1", mt7988_drv_vbus_p1),
+	/*  @GPIO(63) pcie_clk_req_n2_1 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n2_1", mt7988_pcie_clk_req_n2_1),
+	/*  @GPIO(69, 70) mdc_mdio1 */
+	PINCTRL_PIN_GROUP("mdc_mdio1", mt7988_mdc_mdio1),
+	/*  @GPIO(69, 70) i2c1_2 */
+	PINCTRL_PIN_GROUP("i2c1_2", mt7988_i2c1_2),
+	/*  @GPIO(69) pwm6 */
+	PINCTRL_PIN_GROUP("pwm6", mt7988_pwm6),
+	/*  @GPIO(70) pwm7 */
+	PINCTRL_PIN_GROUP("pwm7", mt7988_pwm7),
+	/*  @GPIO(69,70) i2c2_0 */
+	PINCTRL_PIN_GROUP("i2c2_0", mt7988_i2c2_0),
+	/*  @GPIO(71,72) i2c2_1 */
+	PINCTRL_PIN_GROUP("i2c2_1", mt7988_i2c2_1),
+	/*  @GPIO(73) pcie_2l_1_pereset */
+	PINCTRL_PIN_GROUP("pcie_2l_1_pereset", mt7988_pcie_2l_1_pereset),
+	/*  @GPIO(74) pcie_1l_0_pereset */
+	PINCTRL_PIN_GROUP("pcie_1l_0_pereset", mt7988_pcie_1l_0_pereset),
+	/*  @GPIO(75) pcie_wake_n1_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n1_0", mt7988_pcie_wake_n1_0),
+	/*  @GPIO(76) pcie_clk_req_n1 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n1", mt7988_pcie_clk_req_n1),
+	/*  @GPIO(77) pcie_wake_n2_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n2_0", mt7988_pcie_wake_n2_0),
+	/*  @GPIO(78) pcie_clk_req_n2_0 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n2_0", mt7988_pcie_clk_req_n2_0),
+	/*  @GPIO(79) drv_vbus */
+	PINCTRL_PIN_GROUP("drv_vbus", mt7988_drv_vbus),
+	/*  @GPIO(79) pcie_wake_n2_1 */
+	PINCTRL_PIN_GROUP("pcie_wake_n2_1", mt7988_pcie_wake_n2_1),
+	/*  @GPIO(80,81,82,83) uart1_2 */
+	PINCTRL_PIN_GROUP("uart1_2", mt7988_uart1_2),
+	/*  @GPIO(80,81) uart1_2_lite */
+	PINCTRL_PIN_GROUP("uart1_2_lite", mt7988_uart1_2_lite),
+	/*  @GPIO(80) pwm2 */
+	PINCTRL_PIN_GROUP("pwm2", mt7988_pwm2),
+	/*  @GPIO(81) pwm3 */
+	PINCTRL_PIN_GROUP("pwm3", mt7988_pwm3),
+	/*  @GPIO(82) pwm4 */
+	PINCTRL_PIN_GROUP("pwm4", mt7988_pwm4),
+	/*  @GPIO(83) pwm5 */
+	PINCTRL_PIN_GROUP("pwm5", mt7988_pwm5),
+	/*  @GPIO(80) net_wo0_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
+	/*  @GPIO(81) net_wo1_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
+	/*  @GPIO(82) net_wo2_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
+	/*  @GPIO(80,81) tops_uart1_2 */
+	PINCTRL_PIN_GROUP("tops_uart1_2", mt7988_tops_uart1_2),
+	/*  @GPIO(80) net_wo0_uart_txd_1 */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7988_net_wo0_uart_txd_1),
+	/*  @GPIO(81) net_wo1_uart_txd_1 */
+	PINCTRL_PIN_GROUP("net_wo1_uart_txd_1", mt7988_net_wo1_uart_txd_1),
+	/*  @GPIO(82) net_wo2_uart_txd_1 */
+	PINCTRL_PIN_GROUP("net_wo2_uart_txd_1", mt7988_net_wo2_uart_txd_1),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+static const char * const mt7988_jtag_groups[] = {
+	"tops_jtag0_0", "wo0_jtag", "wo1_jtag",
+	"wo2_jtag",	"jtag",	    "tops_jtag0_1",
+};
+static const char * const mt7988_int_usxgmii_groups[] = {
+	"int_usxgmii",
+};
+static const char * const mt7988_pwm_groups[] = {
+	"pwm0", "pwm1", "pwm2", "pwm2_0", "pwm3", "pwm3_0", "pwm4", "pwm4_0",
+	"pwm5", "pwm5_0", "pwm6", "pwm6_0", "pwm7", "pwm7_0",
+
+};
+static const char * const mt7988_dfd_groups[] = {
+	"dfd",
+};
+static const char * const mt7988_i2c_groups[] = {
+	"xfi_phy0_i2c0",
+	"xfi_phy1_i2c0",
+	"xfi_phy_pll_i2c0",
+	"xfi_phy_pll_i2c1",
+	"i2c0_0",
+	"i2c1_sfp",
+	"xfi_pextp_phy0_i2c",
+	"xfi_pextp_phy1_i2c",
+	"i2c0_1",
+	"u30_phy_i2c0",
+	"u32_phy_i2c0",
+	"xfi_phy0_i2c1",
+	"xfi_phy1_i2c1",
+	"xfi_phy_pll_i2c2",
+	"i2c1_0",
+	"u30_phy_i2c1",
+	"u32_phy_i2c1",
+	"xfi_phy_pll_i2c3",
+	"sgmii0_i2c",
+	"sgmii1_i2c",
+	"i2c1_2",
+	"i2c2_0",
+	"i2c2_1",
+};
+static const char * const mt7988_ethernet_groups[] = {
+	"mdc_mdio0",
+	"2p5g_ext_mdio",
+	"gbe_ext_mdio",
+	"mdc_mdio1",
+};
+static const char * const mt7988_pcie_groups[] = {
+	"pcie_wake_n0_0",    "pcie_clk_req_n0_0", "pcie_wake_n3_0",
+	"pcie_clk_req_n3",   "pcie_p0_phy_i2c",	  "pcie_p1_phy_i2c",
+	"pcie_p3_phy_i2c",   "pcie_p2_phy_i2c",	  "ckm_phy_i2c",
+	"pcie_wake_n0_1",    "pcie_wake_n3_1",	  "pcie_2l_0_pereset",
+	"pcie_1l_1_pereset", "pcie_clk_req_n2_1", "pcie_2l_1_pereset",
+	"pcie_1l_0_pereset", "pcie_wake_n1_0",	  "pcie_clk_req_n1",
+	"pcie_wake_n2_0",    "pcie_clk_req_n2_0", "pcie_wake_n2_1",
+	"pcie_clk_req_n0_1"
+};
+static const char * const mt7988_pmic_groups[] = {
+	"pmic",
+};
+static const char * const mt7988_wdt_groups[] = {
+	"watchdog",
+};
+static const char * const mt7988_spi_groups[] = {
+	"spi0", "spi0_wp_hold", "spi1", "spi2", "spi2_wp_hold",
+};
+static const char * const mt7988_flash_groups[] = { "emmc_45", "sdcard", "snfi",
+						    "emmc_51" };
+static const char * const mt7988_uart_groups[] = {
+	"uart2",
+	"tops_uart0_0",
+	"uart2_0",
+	"uart1_0",
+	"uart2_1",
+	"net_wo0_uart_txd_0",
+	"net_wo1_uart_txd_0",
+	"net_wo2_uart_txd_0",
+	"tops_uart1_0",
+	"ops_uart0_1",
+	"ops_uart1_1",
+	"uart0",
+	"tops_uart0_2",
+	"uart1_1",
+	"uart2_3",
+	"uart1_2",
+	"uart1_2_lite",
+	"tops_uart1_2",
+	"net_wo0_uart_txd_1",
+	"net_wo1_uart_txd_1",
+	"net_wo2_uart_txd_1",
+};
+static const char * const mt7988_udi_groups[] = {
+	"udi",
+};
+static const char * const mt7988_audio_groups[] = {
+	"i2s", "pcm",
+};
+static const char * const mt7988_led_groups[] = {
+	"gbe0_led1", "gbe1_led1", "gbe2_led1", "gbe3_led1", "2p5gbe_led1",
+	"gbe0_led0", "gbe1_led0", "gbe2_led0", "gbe3_led0", "2p5gbe_led0",
+	"wf5g_led0",   "wf5g_led1",
+};
+static const char * const mt7988_usb_groups[] = {
+	"drv_vbus",
+	"drv_vbus_p1",
+};
+
+static const struct function_desc mt7988_functions[] = {
+	{ { "audio", mt7988_audio_groups, ARRAY_SIZE(mt7988_audio_groups) },
+	  NULL },
+	{ { "jtag", mt7988_jtag_groups, ARRAY_SIZE(mt7988_jtag_groups) },
+	  NULL },
+	{ { "int_usxgmii", mt7988_int_usxgmii_groups,
+	    ARRAY_SIZE(mt7988_int_usxgmii_groups) },
+	  NULL },
+	{ { "pwm", mt7988_pwm_groups, ARRAY_SIZE(mt7988_pwm_groups) }, NULL },
+	{ { "dfd", mt7988_dfd_groups, ARRAY_SIZE(mt7988_dfd_groups) }, NULL },
+	{ { "i2c", mt7988_i2c_groups, ARRAY_SIZE(mt7988_i2c_groups) }, NULL },
+	{ { "eth", mt7988_ethernet_groups, ARRAY_SIZE(mt7988_ethernet_groups) },
+	  NULL },
+	{ { "pcie", mt7988_pcie_groups, ARRAY_SIZE(mt7988_pcie_groups) },
+	  NULL },
+	{ { "pmic", mt7988_pmic_groups, ARRAY_SIZE(mt7988_pmic_groups) },
+	  NULL },
+	{ { "watchdog", mt7988_wdt_groups, ARRAY_SIZE(mt7988_wdt_groups) },
+	  NULL },
+	{ { "spi", mt7988_spi_groups, ARRAY_SIZE(mt7988_spi_groups) }, NULL },
+	{ { "flash", mt7988_flash_groups, ARRAY_SIZE(mt7988_flash_groups) },
+	  NULL },
+	{ { "uart", mt7988_uart_groups, ARRAY_SIZE(mt7988_uart_groups) },
+	  NULL },
+	{ { "udi", mt7988_udi_groups, ARRAY_SIZE(mt7988_udi_groups) }, NULL },
+	{ { "usb", mt7988_usb_groups, ARRAY_SIZE(mt7988_usb_groups) }, NULL },
+	{ { "led", mt7988_led_groups, ARRAY_SIZE(mt7988_led_groups) }, NULL },
+};
+
+static const struct mtk_eint_hw mt7988_eint_hw = {
+	.port_mask = 7,
+	.ports = 7,
+	.ap_num = ARRAY_SIZE(mt7988_pins),
+	.db_cnt = 16,
+};
+
+static const char * const mt7988_pinctrl_register_base_names[] = {
+	"gpio",	 "iocfg_tr", "iocfg_br",
+	"iocfg_rb", "iocfg_lb", "iocfg_tl",
+};
+
+static struct mtk_pin_soc mt7988_data = {
+	.reg_cal = mt7988_reg_cals,
+	.pins = mt7988_pins,
+	.npins = ARRAY_SIZE(mt7988_pins),
+	.grps = mt7988_groups,
+	.ngrps = ARRAY_SIZE(mt7988_groups),
+	.funcs = mt7988_functions,
+	.nfuncs = ARRAY_SIZE(mt7988_functions),
+	.eint_hw = &mt7988_eint_hw,
+	.gpio_m = 0,
+	.ies_present = false,
+	.base_names = mt7988_pinctrl_register_base_names,
+	.nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
+	.bias_disable_set = mtk_pinconf_bias_disable_set,
+	.bias_disable_get = mtk_pinconf_bias_disable_get,
+	.bias_set = mtk_pinconf_bias_set,
+	.bias_get = mtk_pinconf_bias_get,
+	.pull_type = mt7988_pull_type,
+	.bias_set_combo = mtk_pinconf_bias_set_combo,
+	.bias_get_combo = mtk_pinconf_bias_get_combo,
+	.drive_set = mtk_pinconf_drive_set_rev1,
+	.drive_get = mtk_pinconf_drive_get_rev1,
+	.adv_pull_get = mtk_pinconf_adv_pull_get,
+	.adv_pull_set = mtk_pinconf_adv_pull_set,
+};
+
+static const struct of_device_id mt7988_pinctrl_of_match[] = {
+	{ .compatible = "mediatek,mt7988-pinctrl" },
+	{}
+};
+
+static int mt7988_pinctrl_probe(struct platform_device *pdev)
+{
+	return mtk_moore_pinctrl_probe(pdev, &mt7988_data);
+}
+
+static struct platform_driver mt7988_pinctrl_driver = {
+	.driver = {
+		.name = "mt7988-pinctrl",
+		.of_match_table = mt7988_pinctrl_of_match,
+	},
+	.probe = mt7988_pinctrl_probe,
+};
+
+static int __init mt7988_pinctrl_init(void)
+{
+	return platform_driver_register(&mt7988_pinctrl_driver);
+}
+arch_initcall(mt7988_pinctrl_init);
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 03:00:37 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 12:00:37 +0100
Subject: [PATCH v5 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241202110045.22084-1-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
Message-ID: <20241202110045.22084-4-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This adds bindings for MT7988 pinctrl driver.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
changes in v5 (so not adding RB from Rob given in v4):
- do not use MTK_DRIVE_8mA in example
- add _0 functions for pwm

changes in v4:
- dt-binding: pinctrl: fix dt_binding_check fixed-string error

'^mux$' should not be valid under {'pattern': '^\\^[a-zA-Z0-9,\\-._#@]+\\$$'}
	hint: Fixed strings belong in 'properties', not 'patternProperties'

changes in v3:
- limit conf subnode name with optional suffix like mmc on mt7986
- match mux subnode without wildcards

changes in v2:
- drop gpio-cells description
- move ref in mux subnode up
- order uart-functions alphanumeric and fix typo
---
 .../pinctrl/mediatek,mt7988-pinctrl.yaml      | 578 ++++++++++++++++++
 1 file changed, 578 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
new file mode 100644
index 000000000000..dd5584557135
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
@@ -0,0 +1,578 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7988-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT7988 Pin Controller
+
+maintainers:
+  - Sean Wang <sean.wang at kernel.org>
+
+description:
+  The MediaTek's MT7988 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7988-pinctrl
+
+  reg:
+    minItems: 7
+    maxItems: 7
+
+  reg-names:
+    items:
+      - const: gpio
+      - const: iocfg_tr
+      - const: iocfg_br
+      - const: iocfg_rb
+      - const: iocfg_lb
+      - const: iocfg_tl
+      - const: eint
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-ranges:
+    minItems: 1
+    maxItems: 5
+    description:
+      GPIO valid number range.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - gpio-controller
+  - "#gpio-cells"
+
+patternProperties:
+  '-pins$':
+    type: object
+    additionalProperties: false
+
+    properties:
+      'mux':
+        type: object
+        additionalProperties: false
+        $ref: /schemas/pinctrl/pinmux-node.yaml
+        description: |
+          pinmux configuration nodes.
+
+          The following table shows the effective values of "group", "function"
+          properties and chip pinout pins
+
+          groups               function           pins (in pin#)
+          ---------------------------------------------------------------------
+          "tops_jtag0_0"       "jtag"             0, 1, 2, 3, 4
+          "wo0_jtag"           "jtag"             50, 51, 52, 53, 54
+          "wo1_jtag"           "jtag"             50, 51, 52, 53, 54
+          "wo2_jtag"           "jtag"             50, 51, 52, 53, 54
+          "jtag"               "jtag"             58, 59, 60, 61, 62
+          "tops_jtag0_1"       "jtag"             58, 59, 60, 61, 62
+          "int_usxgmii"        "int_usxgmii"      2, 3
+          "pwm0"               "pwm"              57
+          "pwm1"               "pwm"              21
+          "pwm2"               "pwm"              80
+          "pwm2_0"             "pwm"              58
+          "pwm3"               "pwm"              81
+          "pwm3_0"             "pwm"              59
+          "pwm4"               "pwm"              82
+          "pwm4_0"             "pwm"              60
+          "pwm5"               "pwm"              83
+          "pwm5_0"             "pwm"              61
+          "pwm6"               "pwm"              69
+          "pwm6_0"             "pwm"              62
+          "pwm7"               "pwm"              70
+          "pwm7_0"             "pwm"              4
+          "dfd"                "dfd"              0, 1, 2, 3, 4
+          "xfi_phy0_i2c0"      "i2c"              0, 1
+          "xfi_phy1_i2c0"      "i2c"              0, 1
+          "xfi_phy_pll_i2c0"   "i2c"              3, 4
+          "xfi_phy_pll_i2c1"   "i2c"              3, 4
+          "i2c0_0"             "i2c"              5, 6
+          "i2c1_sfp"           "i2c"              5, 6
+          "xfi_pextp_phy0_i2c" "i2c"              5, 6
+          "xfi_pextp_phy1_i2c" "i2c"              5, 6
+          "i2c0_1"             "i2c"              15, 16
+          "u30_phy_i2c0"       "i2c"              15, 16
+          "u32_phy_i2c0"       "i2c"              15, 16
+          "xfi_phy0_i2c1"      "i2c"              15, 16
+          "xfi_phy1_i2c1"      "i2c"              15, 16
+          "xfi_phy_pll_i2c2"   "i2c"              15, 16
+          "i2c1_0"             "i2c"              17, 18
+          "u30_phy_i2c1"       "i2c"              17, 18
+          "u32_phy_i2c1"       "i2c"              17, 18
+          "xfi_phy_pll_i2c3"   "i2c"              17, 18
+          "sgmii0_i2c"         "i2c"              17, 18
+          "sgmii1_i2c"         "i2c"              17, 18
+          "i2c1_2"             "i2c"              69, 70
+          "i2c2_0"             "i2c"              69, 70
+          "i2c2_1"             "i2c"              71, 72
+          "mdc_mdio0"          "eth"              5, 6
+          "2p5g_ext_mdio"      "eth"              28, 29
+          "gbe_ext_mdio"       "eth"              30, 31
+          "mdc_mdio1"          "eth"              69, 70
+          "pcie_wake_n0_0"     "pcie"             7
+          "pcie_clk_req_n0_0"  "pcie"             8
+          "pcie_wake_n3_0"     "pcie"             9
+          "pcie_clk_req_n3"    "pcie"             10
+          "pcie_clk_req_n0_1"  "pcie"             10
+          "pcie_p0_phy_i2c"    "pcie"             7, 8
+          "pcie_p1_phy_i2c"    "pcie"             7, 8
+          "pcie_p3_phy_i2c"    "pcie"             9, 10
+          "pcie_p2_phy_i2c"    "pcie"             7, 8
+          "ckm_phy_i2c"        "pcie"             9, 10
+          "pcie_wake_n0_1"     "pcie"             13
+          "pcie_wake_n3_1"     "pcie"             14
+          "pcie_2l_0_pereset"  "pcie"             19
+          "pcie_1l_1_pereset"  "pcie"             20
+          "pcie_clk_req_n2_1"  "pcie"             63
+          "pcie_2l_1_pereset"  "pcie"             73
+          "pcie_1l_0_pereset"  "pcie"             74
+          "pcie_wake_n1_0"     "pcie"             75
+          "pcie_clk_req_n1"    "pcie"             76
+          "pcie_wake_n2_0"     "pcie"             77
+          "pcie_clk_req_n2_0"  "pcie"             78
+          "pcie_wake_n2_1"     "pcie"             79
+          "pmic"               "pmic"             11
+          "watchdog"           "watchdog"         12
+          "spi0_wp_hold"       "spi"              22, 23
+          "spi0"               "spi"              24, 25, 26, 27
+          "spi1"               "spi"              28, 29, 30, 31
+          "spi2"               "spi"              32, 33, 34, 35
+          "spi2_wp_hold"       "spi"              36, 37
+          "snfi"               "flash"            22, 23, 24, 25, 26, 27
+          "emmc_45"            "flash"            21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
+          "sdcard"             "flash"            32, 33, 34, 35, 36, 37
+          "emmc_51"            "flash"            38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49
+          "uart2"              "uart"             0, 1, 2, 3
+          "tops_uart0_0"       "uart"             22, 23
+          "uart2_0"            "uart"             28, 29, 30, 31
+          "uart1_0"            "uart"             32, 33, 34, 35
+          "uart2_1"            "uart"             32, 33, 34, 35
+          "net_wo0_uart_txd_0" "uart"             28
+          "net_wo1_uart_txd_0" "uart"             29
+          "net_wo2_uart_txd_0" "uart"             30
+          "tops_uart1_0"       "uart"             28, 29
+          "tops_uart0_1"       "uart"             30, 31
+          "tops_uart1_1"       "uart"             36, 37
+          "uart0"              "uart"             55, 56
+          "tops_uart0_2"       "uart"             55, 56
+          "uart2_2"            "uart"             50, 51, 52, 53
+          "uart1_1"            "uart"             58, 59, 60, 61
+          "uart2_3"            "uart"             58, 59, 60, 61
+          "uart1_2"            "uart"             80, 81, 82, 83
+          "uart1_2_lite"       "uart"             80, 81
+          "tops_uart1_2"       "uart"             80, 81
+          "net_wo0_uart_txd_1" "uart"             80
+          "net_wo1_uart_txd_1" "uart"             81
+          "net_wo2_uart_txd_1" "uart"             82
+          "udi"                "udi"              32, 33, 34, 35, 36
+          "i2s"                "audio"            50, 51, 52, 53, 54
+          "pcm"                "audio"            50, 51, 52, 53
+          "gbe0_led1"          "led"              58
+          "gbe1_led1"          "led"              59
+          "gbe2_led1"          "led"              60
+          "gbe3_led1"          "led"              61
+          "2p5gbe_led1"        "led"              62
+          "gbe0_led0"          "led"              64
+          "gbe1_led0"          "led"              65
+          "gbe2_led0"          "led"              66
+          "gbe3_led0"          "led"              67
+          "2p5gbe_led0"        "led"              68
+          "drv_vbus_p1"        "usb"              63
+          "drv_vbus"           "usb"              79
+
+        properties:
+          function:
+            description:
+              A string containing the name of the function to mux to the group.
+            enum: [audio, dfd, eth, flash, i2c, int_usxgmii, jtag, led, pcie, pmic, pwm, spi,
+                   uart, udi, usb, watchdog]
+          groups:
+            description:
+              An array of strings. Each string contains the name of a group.
+        required:
+          - function
+          - groups
+
+        allOf:
+          - if:
+              properties:
+                function:
+                  const: audio
+            then:
+              properties:
+                groups:
+                  enum: [i2s, pcm]
+          - if:
+              properties:
+                function:
+                  const: jtag
+            then:
+              properties:
+                groups:
+                  enum: [jtag, tops_jtag0_0, tops_jtag0_1, wo0_jtag, wo1_jtag, wo2_jtag]
+          - if:
+              properties:
+                function:
+                  const: int_usxgmii
+            then:
+              properties:
+                groups:
+                  enum: [int_usxgmii]
+          - if:
+              properties:
+                function:
+                  const: dfd
+            then:
+              properties:
+                groups:
+                  enum: [dfd]
+          - if:
+              properties:
+                function:
+                  const: flash
+            then:
+              properties:
+                groups:
+                  enum: [emmc_45, emmc_51, sdcard, snfi]
+          - if:
+              properties:
+                function:
+                  const: eth
+            then:
+              properties:
+                groups:
+                  enum: [2p5g_ext_mdio, gbe_ext_mdio, mdc_mdio0, mdc_mdio1]
+          - if:
+              properties:
+                function:
+                  const: i2c
+            then:
+              properties:
+                groups:
+                  enum: [xfi_phy0_i2c0, xfi_phy1_i2c0, xfi_phy_pll_i2c0,
+                         xfi_phy_pll_i2c1, i2c0_0, i2c1_sfp, xfi_pextp_phy0_i2c,
+                         xfi_pextp_phy1_i2c, i2c0_1, u30_phy_i2c0, u32_phy_i2c0,
+                         xfi_phy0_i2c1, xfi_phy1_i2c1, xfi_phy_pll_i2c2, i2c1_0,
+                         u30_phy_i2c1, u32_phy_i2c1, xfi_phy_pll_i2c3, sgmii0_i2c,
+                         sgmii1_i2c, i2c1_2, i2c2_0, i2c2_1]
+          - if:
+              properties:
+                function:
+                  const: led
+            then:
+              properties:
+                groups:
+                  enum: [2p5gbe_led0, 2p5gbe_led1, gbe0_led0, gbe0_led1, gbe1_led0, gbe1_led1,
+                         gbe2_led0, gbe2_led1, gbe3_led0, gbe3_led1, wf5g_led0, wf5g_led1]
+          - if:
+              properties:
+                function:
+                  const: pcie
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [pcie_wake_n0_0, pcie_clk_req_n0_0, pcie_wake_n3_0,
+                           pcie_clk_req_n3, pcie_p0_phy_i2c, pcie_p1_phy_i2c,
+                           pcie_p3_phy_i2c, pcie_p2_phy_i2c, ckm_phy_i2c,
+                           pcie_wake_n0_1, pcie_wake_n3_1, pcie_2l_0_pereset,
+                           pcie_1l_1_pereset, pcie_clk_req_n2_1, pcie_2l_1_pereset,
+                           pcie_1l_0_pereset, pcie_wake_n1_0, pcie_clk_req_n1,
+                           pcie_wake_n2_0, pcie_clk_req_n2_0, pcie_wake_n2_1,
+                           pcie_clk_req_n0_1]
+                  maxItems: 3
+          - if:
+              properties:
+                function:
+                  const: pmic
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [pmic]
+                  maxItems: 1
+          - if:
+              properties:
+                function:
+                  const: pwm
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [pwm0, pwm1, pwm2, pwm2_0, pwm3, pwm3_0, pwm4, pwm4_0, pwm5, pwm5_0,
+                           pwm6, pwm6_0, pwm7, pwm7_0]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: spi
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [spi0, spi0_wp_hold, spi1, spi2, spi2_wp_hold]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: uart
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [net_wo0_uart_txd_0, net_wo0_uart_txd_1, net_wo1_uart_txd_0,
+                           net_wo1_uart_txd_1, net_wo2_uart_txd_0, net_wo2_uart_txd_1,
+                           tops_uart0_0, tops_uart0_1, tops_uart0_2, tops_uart1_0,
+                           tops_uart1_1, tops_uart1_2, uart0, uart1_0, uart1_1, uart1_2,
+                           uart1_2_lite, uart2, uart2_0, uart2_1, uart2_3]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: watchdog
+            then:
+              properties:
+                groups:
+                  enum: [watchdog]
+          - if:
+              properties:
+                function:
+                  const: udi
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [udi]
+                  maxItems: 1
+          - if:
+              properties:
+                function:
+                  const: usb
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [drv_vbus, drv_vbus_p1]
+                  maxItems: 1
+
+    patternProperties:
+      '^conf(-[-a-z]*)?$':
+        type: object
+        additionalProperties: false
+        description:
+          pinconf configuration nodes.
+        $ref: /schemas/pinctrl/pincfg-node.yaml
+
+        properties:
+          pins:
+            description:
+              An array of strings. Each string contains the name of a pin.
+            items:
+              enum: [UART2_RXD, UART2_TXD, UART2_CTS, UART2_RTS, GPIO_A, SMI_0_MDC,
+                     SMI_0_MDIO, PCIE30_2L_0_WAKE_N, PCIE30_2L_0_CLKREQ_N,
+                     PCIE30_1L_1_WAKE_N, PCIE30_1L_1_CLKREQ_N, GPIO_P, WATCHDOG,
+                     GPIO_RESET, GPIO_WPS, PMIC_I2C_SCL, PMIC_I2C_SDA, I2C_1_SCL,
+                     I2C_1_SDA, PCIE30_2L_0_PRESET_N, PCIE30_1L_1_PRESET_N, PWMD1,
+                     SPI0_WP, SPI0_HOLD, SPI0_CSB, SPI0_MISO, SPI0_MOSI, SPI0_CLK,
+                     SPI1_CSB, SPI1_MISO, SPI1_MOSI, SPI1_CLK, SPI2_CLK, SPI2_MOSI,
+                     SPI2_MISO, SPI2_CSB, SPI2_HOLD, SPI2_WP, EMMC_RSTB, EMMC_DSL,
+                     EMMC_CK, EMMC_CMD, EMMC_DATA_7, EMMC_DATA_6, EMMC_DATA_5,
+                     EMMC_DATA_4, EMMC_DATA_3, EMMC_DATA_2, EMMC_DATA_1,
+                     EMMC_DATA_0, PCM_FS_I2S_LRCK, PCM_CLK_I2S_BCLK,
+                     PCM_DRX_I2S_DIN, PCM_DTX_I2S_DOUT, PCM_MCK_I2S_MCLK,
+                     UART0_RXD, UART0_TXD, PWMD0, JTAG_JTDI, JTAG_JTDO, JTAG_JTMS,
+                     JTAG_JTCLK, JTAG_JTRST_N, USB_DRV_VBUS_P1, LED_A, LED_B, LED_C,
+                     LED_D, LED_E, GPIO_B, GPIO_C, I2C_2_SCL, I2C_2_SDA,
+                     PCIE30_2L_1_PRESET_N, PCIE30_1L_0_PRESET_N,
+                     PCIE30_2L_1_WAKE_N, PCIE30_2L_1_CLKREQ_N,
+                     PCIE30_1L_0_WAKE_N, PCIE30_1L_0_CLKREQ_N, USB_DRV_VBUS_P0,
+                     UART1_RXD, UART1_TXD, UART1_CTS, UART1_RTS]
+            maxItems: 84
+
+          bias-disable: true
+
+          bias-pull-up:
+            oneOf:
+              - type: boolean
+                description: normal pull up.
+              - enum: [100, 101, 102, 103]
+                description:
+                  PUPD/R1/R0 pull down type. See MTK_PUPD_SET_R1R0 defines in
+                  dt-bindings/pinctrl/mt65xx.h.
+
+          bias-pull-down:
+            oneOf:
+              - type: boolean
+                description: normal pull down.
+              - enum: [100, 101, 102, 103]
+                description:
+                  PUPD/R1/R0 pull down type. See MTK_PUPD_SET_R1R0 defines in
+                  dt-bindings/pinctrl/mt65xx.h.
+
+          input-enable: true
+
+          input-disable: true
+
+          output-enable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            enum: [2, 4, 6, 8, 10, 12, 14, 16]
+
+          mediatek,pull-up-adv:
+            description: |
+              Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
+              Pull up settings for 2 pull resistors, R0 and R1. Valid arguments
+              are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,pull-down-adv:
+            description: |
+              Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
+              Pull down settings for 2 pull resistors, R0 and R1. Valid arguments
+              are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+        required:
+          - pins
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/mt65xx.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      pio: pinctrl at 1001f000 {
+        compatible = "mediatek,mt7988-pinctrl";
+        reg = <0 0x1001f000 0 0x1000>,
+        <0 0x11c10000 0 0x1000>,
+        <0 0x11d00000 0 0x1000>,
+        <0 0x11d20000 0 0x1000>,
+        <0 0x11e00000 0 0x1000>,
+        <0 0x11f00000 0 0x1000>,
+        <0 0x1000b000 0 0x1000>;
+        reg-names = "gpio", "iocfg_tr",
+          "iocfg_br", "iocfg_rb",
+          "iocfg_lb", "iocfg_tl", "eint";
+        gpio-controller;
+        #gpio-cells = <2>;
+        gpio-ranges = <&pio 0 0 84>;
+        interrupt-controller;
+        interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-parent = <&gic>;
+        #interrupt-cells = <2>;
+
+        i2c0_pins: i2c0-g0-pins {
+          mux {
+            function = "i2c";
+            groups = "i2c0_1";
+          };
+        };
+
+        mdio0_pins: mdio0-pins {
+          mux {
+            function = "eth";
+            groups = "mdc_mdio0";
+          };
+
+          conf {
+            pins = "SMI_0_MDC", "SMI_0_MDIO";
+            drive-strength = <8>;
+          };
+        };
+
+        mmc0_pins_emmc_51: mmc0-emmc-51-pins {
+          mux {
+            function = "flash";
+            groups = "emmc_51";
+          };
+        };
+
+        mmc0_pins_sdcard: mmc0-sdcard-pins {
+          mux {
+            function = "flash";
+            groups = "sdcard";
+          };
+        };
+
+        pcie0_pins: pcie0-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
+                     "pcie_wake_n0_0";
+          };
+        };
+
+        pcie1_pins: pcie1-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
+                     "pcie_wake_n1_0";
+          };
+        };
+
+        pcie2_pins: pcie2-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
+                     "pcie_wake_n2_0";
+          };
+        };
+
+        pcie3_pins: pcie3-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
+                     "pcie_wake_n3_0";
+          };
+        };
+
+        uart0_pins: uart0-pins {
+          mux {
+            function = "uart";
+            groups =  "uart0";
+          };
+        };
+      };
+    };
-- 
2.43.0



From dmitry.baryshkov at linaro.org  Mon Dec  2 03:03:07 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 2 Dec 2024 13:03:07 +0200
Subject: [PATCH 00/10] drm/connector: add eld_mutex to protect
 connector->eld
In-Reply-To: <77545786331df8bfaf5fdcb309437358@kernel.org>
References: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
 <77545786331df8bfaf5fdcb309437358@kernel.org>
Message-ID: <ohbtatnn33jj6y3q4milf4txi4n7yirnny2eefdjddlkn2dnhp@eqjedetct4q3>

On Mon, Dec 02, 2024 at 10:19:41AM +0000, Maxime Ripard wrote:
> On Sun, 1 Dec 2024 01:55:17 +0200, Dmitry Baryshkov wrote:
> > The connector->eld is accessed by the .get_eld() callback. This access
> > can collide with the drm_edid_to_eld() updating the data at the same
> > time. Add drm_connector.eld_mutex to protect the data from concurrenct
> > access.
> > 
> > 
> > [ ... ]
> 
> Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!

I'm going to post v2 to fix Jani's comment, but what should be the merge
strategy? Merge patches 1-3, 5, 9-10 through drm-misc and the rest (AMD,
i915, MSM, radeon) through the driver trees?

-- 
With best wishes
Dmitry


From mripard at kernel.org  Mon Dec  2 03:03:40 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 2 Dec 2024 12:03:40 +0100
Subject: [PATCH] pinctrl: sunxi: Use minimal debouncing period as default
In-Reply-To: <Z0rqILFESdje9qUn@collins>
References: <20241119140805.3345412-1-paulk@sys-base.io>
 <20241119-prudent-jasmine-lizard-195cef@houat>
 <ZzyoIABRArkGoZBn@collins>
 <20241119-vivacious-optimistic-squirrel-a2f3c5@houat>
 <ZzzdT0wr0u1ApVgV@collins>
 <20241120-wild-stimulating-prawn-ffefb7@houat>
 <Zz20dquzl5_2_3TQ@collins>
 <20241129-amazing-whale-of-proficiency-ee6fd2@houat>
 <Z0rqILFESdje9qUn@collins>
Message-ID: <20241202-magnetic-curious-bear-1cc48e@houat>

On Sat, Nov 30, 2024 at 11:34:08AM +0100, Paul Kocialkowski wrote:
> Hi Maxime,
> 
> Le Fri 29 Nov 24, 16:37, Maxime Ripard a ?crit :
> > On Wed, Nov 20, 2024 at 11:05:42AM +0100, Paul Kocialkowski wrote:
> > > Le Wed 20 Nov 24, 09:01, Maxime Ripard a ?crit :
> > > > > > If anything, the status quo doesn't impose anything, it just rolls with
> > > > > > the hardware default. Yours would impose one though.
> > > > > 
> > > > > The result is that it puts a strong limitation and breaks many use cases by
> > > > > default. I don't think we have to accept whatever register default was chosen
> > > > > by hardware engineers as the most sensible default choice and pretend that this
> > > > > is not a policy decision.
> > > > 
> > > > You're making it much worse than it is. It doesn't "break many use
> > > > cases" it broke one, by default, with a supported way to unbreak it, in
> > > > 12 years.
> > > 
> > > I think this is exaggerated. Like I mentioned previously there are *many*
> > > situations that are not covered by the default.
> > 
> > Note that this statement would be true for any default. The current, the
> > one you suggest, or any other really. The fact that we have a way to
> > override it is an acknowledgement that it's not a one size fits all
> > situation.
> 
> Again the debate is about which option has the best advantages over
> disadvantages. I'm not saying the default I suggest has no issues, but
> rather that the benefits very clearly outweight the issues. Hence the many
> situations that would be supported with the shortest debouncing period (both
> short and frequent interrupts) versus the few broken-hardware use-cases
> (related to interrupt storms) support with the largest period.
> 
> > > The fact that I'm the first person to bring it up in 12 years doesn't
> > > change that.
> > 
> > Sure. It does however hint that it seems like it's a sane enough
> > default.
> 
> Or maybe people didn't realize this mechanism existed, failed to understand
> why their device didn't work with Allwinner platforms and just moved on to
> use something else. Indeed it's all very subjective interpretation.
> 
> > > Sofar the downside you brought up boils down to: badly-designed
> > > hardware may have relied on this mechanism to avoid interrupt storms
> > > that could prevent the system from booting.
> > 
> > It's not about good or bad design. Buttons bounce, HPD signals bounce,
> > it's just the world we live in.
> 
> Well I'm an electrical engineer and the first thing we were told about
> buttons and connectors is to include hardware debouncing. The second thing
> is that it can be done in software (which again is done in a number of drivers)
> by just disabling the interrupt for a while if it happens too often.
> 
> So I'm quite affirmative that taking none of these into account is constitutive
> of a broken hardware design. No electrical engineer is told that they shouldn't
> care about this because the SoC will filter interrupts for them.

The SoC provides the hardware debouncing. There's no reason not to use
it, or to choose something redundant. Some might, but it's also
perfectly valid to just rely on the SoC there.

> Of course it's fine to use this mechanism when it exists, but it's not a
> reasonable expectation to just assume it will always be there. This is why
> I think it's not a legitimate reason to make it a default.

Nobody ever designed a board without considering the SoC features but
rather by adhering to a dogma. The SoC features, components chosen and
their price, etc. all play a role.

> > But let me rephrase if my main objection wasn't clear enough: you want
> > to introduce an ABI breaking change. With the possibility of breaking
> > devices that have worked fine so far. That's not ok.
> 
> I believe it is highly questionable that this constitutes ABI breakage.
> To me there was no defined behavior in the first place, since the debouncing
> configuration is inherited either from the reset value or the boot stage.
> There is also no formal indication of what the default is, anywhere.

Depending on the interpretation, it either means that you change the
default, or add a default, to a device-tree property. That constitutes
an ABI breakage on its own right. And then we can introduce regressions
for boards, which is another breakage.

> Changing the default configuration of hardware is commonplace. One might
> for example introduce a reset to a driver to get a clean state because it
> happened that some boot software would mess it up and it went unnoticed for
> a while. Would you also call that ABI breakage?

No, because it doesn't require a change in the default state Linux
expects when it boots, or changing anything in the device tree. It's a
self-contained change, and thus there's no interface to break.

> I think there's a number of situations where it's much more sensible to change
> a default state to avoid very visible and practical issues. And it does happen.
> 
> Also my understanding of the "ABI breakage" rule in the kernel is that no
> userspace program should stop working when it was implemented to (correctly)
> follow some kernel-related ABI. It doesn't mean that we cannot change any
> default state

If applications rely on that default one way or another, it's absolutely
what it means. The only criteria is whether this will create a
regression for any application.

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

From krzk at kernel.org  Mon Dec  2 03:07:17 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 12:07:17 +0100
Subject: [PATCHv2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable ACSPCIE
 output for PCIe1
In-Reply-To: <k7udgqugqseweckb7hjniz3aops4kn35ttju2ju7f2pcbmndrg@dau5nr4leish>
References: <20241202101140.48778-1-romain.naour@smile.fr>
 <dabbad2b-f8a6-4ed7-86da-ec696cf67461@kernel.org>
 <k7udgqugqseweckb7hjniz3aops4kn35ttju2ju7f2pcbmndrg@dau5nr4leish>
Message-ID: <abeb632b-9efc-48e5-a28a-a9d7c02e0a6e@kernel.org>

On 02/12/2024 11:58, Siddharth Vadapalli wrote:
> On Mon, Dec 02, 2024 at 11:14:46AM +0100, Krzysztof Kozlowski wrote:
> 
> Hello Krzysztof,
> 
>> On 02/12/2024 11:11, Romain Naour wrote:
>>> From: Romain Naour <romain.naour at skf.com>
>>>
>>> Unlike the SK-TDA4VM (k3-j721e-sk) board, there is no clock generator
>>> (CDCI6214RGET) on the BeagleBone AI-64 (k3-j721e-beagleboneai64) to
>>> provide PCIe refclk signal to PCIe Endponts. So the ACSPCIE module must
>>> provide refclk through PCIe_REFCLK pins.
>>>
>>> Use the new "ti,syscon-acspcie-proxy-ctrl" property to enable ACSPCIE
>>> module's PAD IO Buffers.
>>>
>>> Reuse the compatible "ti,j784s4-acspcie-proxy-ctrl" since the ACSPCIE
>>> buffer and its functionality is the same across all K3 SoCs.
>>>
>>> Cc: Siddharth Vadapalli <s-vadapalli at ti.com>
>>> Signed-off-by: Romain Naour <romain.naour at skf.com>
>>> ---
>>> With this patch, we can remove "HACK: Sierra: Drive clock out" patch
>>> applied on vendor kernel for BeagleBone AI-64:
>>> https://openbeagle.org/beagleboard/linux/-/commit/ad65d7ef675966cdbc5d75f2bd545fad1914ba9b
>>>
>>> v2:
>>>  - use generic style comments
>>>  - use "syscon" as generic node name for "acspcie0_proxy_ctrl" node
>>>  - Keep the compatible "ti,j784s4-acspcie-proxy-ctrl" since the
>>>    ACSPCIE buffer and its functionality is the same across all K3 SoCs.
>>>    (Siddharth Vadapalli)
>>>
>>>    "The compatible "ti,j784s4-acspcie-pcie-ctrl" should be reused for
>>>    J721E and all other K3 SoCs.
>>
>> No, it shouldn't and you got comment on this. You always need specific
>> compatible, see writing bindings doc.
> 
> Could you please clarify in which cases reusing the compatible is
> permissible? The list of compatibles at:

Never? You always need specific compatible. Did you read the writing
bindings document?

> https://github.com/torvalds/linux/blob/v6.12/Documentation/devicetree/bindings/mfd/syscon.yaml#L112
> namely,
>           - ti,am62-opp-efuse-table
>           - ti,am62-usb-phy-ctrl
>           - ti,am625-dss-oldi-io-ctrl
>           - ti,am62p-cpsw-mac-efuse
>           - ti,am654-dss-oldi-io-ctrl
>           - ti,j784s4-pcie-ctrl
> have all been reused for different TI SoCs since they all correspond to the
> device functionality enabled via the CTRL_MMR System Controller registers.

If you find a bug, does it mean you can send new patch introducing the
same bug?

> The compatible "ti,j784s4-acspcie-pcie-ctrl" has also been added to the
> list:
> https://github.com/torvalds/linux/blob/v6.12/Documentation/devicetree/bindings/mfd/syscon.yaml#L117
> with the intent of reusing it the same way that other compatibles have
> been reused.

And?

Best regards,
Krzysztof


From s-vadapalli at ti.com  Mon Dec  2 03:17:31 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Mon, 2 Dec 2024 16:47:31 +0530
Subject: [PATCHv2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable
 ACSPCIE output for PCIe1
In-Reply-To: <abeb632b-9efc-48e5-a28a-a9d7c02e0a6e@kernel.org>
References: <20241202101140.48778-1-romain.naour@smile.fr>
 <dabbad2b-f8a6-4ed7-86da-ec696cf67461@kernel.org>
 <k7udgqugqseweckb7hjniz3aops4kn35ttju2ju7f2pcbmndrg@dau5nr4leish>
 <abeb632b-9efc-48e5-a28a-a9d7c02e0a6e@kernel.org>
Message-ID: <7yyz4gnb7jjunbfin4sph7ntvcytjxdh23b3m2lsv24csqccbr@xitdhoq2x7iq>

On Mon, Dec 02, 2024 at 12:07:17PM +0100, Krzysztof Kozlowski wrote:
> On 02/12/2024 11:58, Siddharth Vadapalli wrote:
> > On Mon, Dec 02, 2024 at 11:14:46AM +0100, Krzysztof Kozlowski wrote:
> > 
> > Hello Krzysztof,
> > 
> >> On 02/12/2024 11:11, Romain Naour wrote:
> >>> From: Romain Naour <romain.naour at skf.com>
> >>>
> >>> Unlike the SK-TDA4VM (k3-j721e-sk) board, there is no clock generator
> >>> (CDCI6214RGET) on the BeagleBone AI-64 (k3-j721e-beagleboneai64) to
> >>> provide PCIe refclk signal to PCIe Endponts. So the ACSPCIE module must
> >>> provide refclk through PCIe_REFCLK pins.
> >>>
> >>> Use the new "ti,syscon-acspcie-proxy-ctrl" property to enable ACSPCIE
> >>> module's PAD IO Buffers.
> >>>
> >>> Reuse the compatible "ti,j784s4-acspcie-proxy-ctrl" since the ACSPCIE
> >>> buffer and its functionality is the same across all K3 SoCs.
> >>>
> >>> Cc: Siddharth Vadapalli <s-vadapalli at ti.com>
> >>> Signed-off-by: Romain Naour <romain.naour at skf.com>
> >>> ---
> >>> With this patch, we can remove "HACK: Sierra: Drive clock out" patch
> >>> applied on vendor kernel for BeagleBone AI-64:
> >>> https://openbeagle.org/beagleboard/linux/-/commit/ad65d7ef675966cdbc5d75f2bd545fad1914ba9b
> >>>
> >>> v2:
> >>>  - use generic style comments
> >>>  - use "syscon" as generic node name for "acspcie0_proxy_ctrl" node
> >>>  - Keep the compatible "ti,j784s4-acspcie-proxy-ctrl" since the
> >>>    ACSPCIE buffer and its functionality is the same across all K3 SoCs.
> >>>    (Siddharth Vadapalli)
> >>>
> >>>    "The compatible "ti,j784s4-acspcie-pcie-ctrl" should be reused for
> >>>    J721E and all other K3 SoCs.
> >>
> >> No, it shouldn't and you got comment on this. You always need specific
> >> compatible, see writing bindings doc.
> > 
> > Could you please clarify in which cases reusing the compatible is
> > permissible? The list of compatibles at:
> 
> Never? You always need specific compatible. Did you read the writing
> bindings document?
> 
> > https://github.com/torvalds/linux/blob/v6.12/Documentation/devicetree/bindings/mfd/syscon.yaml#L112
> > namely,
> >           - ti,am62-opp-efuse-table
> >           - ti,am62-usb-phy-ctrl
> >           - ti,am625-dss-oldi-io-ctrl
> >           - ti,am62p-cpsw-mac-efuse
> >           - ti,am654-dss-oldi-io-ctrl
> >           - ti,j784s4-pcie-ctrl
> > have all been reused for different TI SoCs since they all correspond to the
> > device functionality enabled via the CTRL_MMR System Controller registers.
> 
> If you find a bug, does it mean you can send new patch introducing the
> same bug?

Thank you for clarifying. Since the above compatibles have been reused,
they served as an example and appeared as the norm. But as you said, the
reference should be the bindings document and not the patches that got
through and ended up in the bindings. I will make sure that I add new
compatibles for each SoC going forward, despite what the existing
implementation suggests.

Regards,
Siddharth.


From andrea.porta at suse.com  Mon Dec  2 03:19:26 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:26 +0100
Subject: [PATCH v5 02/10] dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <42e09506979d878547d1140d7f6bf68ace76549b.1733136811.git.andrea.porta@suse.com>

Add device tree bindings for the gpio/pin/mux controller that is part of
the RP1 multi function device, and relative entries in MAINTAINERS file.

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../pinctrl/raspberrypi,rp1-gpio.yaml         | 198 ++++++++++++++++++
 MAINTAINERS                                   |   2 +
 2 files changed, 200 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
new file mode 100644
index 000000000000..9528f8675b3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/raspberrypi,rp1-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RaspberryPi RP1 GPIO/Pinconf/Pinmux Controller submodule
+
+maintainers:
+  - Andrea della Porta <andrea.porta at suse.com>
+
+description:
+  The RP1 chipset is a Multi Function Device containing, among other
+  sub-peripherals, a gpio/pinconf/mux controller whose 54 pins are grouped
+  into 3 banks.
+  It works also as an interrupt controller for those gpios.
+
+properties:
+  compatible:
+    const: raspberrypi,rp1-gpio
+
+  reg:
+    maxItems: 3
+    description: One reg specifier for each one of the 3 pin banks.
+
+  '#gpio-cells':
+    description: The first cell is the pin number and the second cell is used
+      to specify the flags (see include/dt-bindings/gpio/gpio.h).
+    const: 2
+
+  gpio-controller: true
+
+  gpio-ranges:
+    maxItems: 1
+
+  gpio-line-names:
+    maxItems: 54
+
+  interrupts:
+    maxItems: 3
+    description: One interrupt specifier for each one of the 3 pin banks.
+
+  '#interrupt-cells':
+    description:
+      Specifies the Bank number [0, 1, 2] and Flags as defined in
+      include/dt-bindings/interrupt-controller/irq.h.
+    const: 2
+
+  interrupt-controller: true
+
+patternProperties:
+  '-state$':
+    oneOf:
+      - $ref: '#/$defs/raspberrypi-rp1-state'
+      - patternProperties:
+          '-pins$':
+            $ref: '#/$defs/raspberrypi-rp1-state'
+        additionalProperties: false
+
+$defs:
+  raspberrypi-rp1-state:
+    allOf:
+      - $ref: pincfg-node.yaml#
+      - $ref: pinmux-node.yaml#
+
+    description:
+      Pin controller client devices use pin configuration subnodes (children
+      and grandchildren) for desired pin configuration.
+      Client device subnodes use below standard properties.
+
+    properties:
+      pins:
+        description:
+          List of gpio pins affected by the properties specified in this
+          subnode.
+        items:
+          pattern: '^gpio([0-9]|[1-4][0-9]|5[0-3])$'
+
+      function:
+        enum: [ alt0, alt1, alt2, alt3, alt4, gpio, alt6, alt7, alt8, none,
+                aaud, dcd0, dpi, dsi0_te_ext, dsi1_te_ext, dsr0, dtr0, gpclk0,
+                gpclk1, gpclk2, gpclk3, gpclk4, gpclk5, i2c0, i2c1, i2c2, i2c3,
+                i2c4, i2c5, i2c6, i2s0, i2s1, i2s2, ir, mic, pcie_clkreq_n,
+                pio, proc_rio, pwm0, pwm1, ri0, sd0, sd1, spi0, spi1, spi2,
+                spi3, spi4, spi5, spi6, spi7, spi8, uart0, uart1, uart2, uart3,
+                uart4, uart5, vbus0, vbus1, vbus2, vbus3 ]
+
+        description:
+          Specify the alternative function to be configured for the specified
+          pins.
+
+      bias-disable: true
+      bias-pull-down: true
+      bias-pull-up: true
+      input-enable: true
+      input-schmitt-enable: true
+      output-enable: true
+      output-high: true
+      output-low: true
+      slew-rate:
+        description: 0 is slow slew rate, 1 is fast slew rate
+        enum: [ 0, 1 ]
+      drive-strength:
+        enum: [ 2, 4, 8, 12 ]
+
+    additionalProperties: false
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+required:
+  - reg
+  - compatible
+  - '#gpio-cells'
+  - gpio-controller
+  - interrupts
+  - '#interrupt-cells'
+  - interrupt-controller
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    rp1 {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        rp1_gpio: pinctrl at c0400d0000 {
+            reg = <0xc0 0x400d0000  0x0 0xc000>,
+                  <0xc0 0x400e0000  0x0 0xc000>,
+                  <0xc0 0x400f0000  0x0 0xc000>;
+            compatible = "raspberrypi,rp1-gpio";
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+            interrupts = <0 IRQ_TYPE_LEVEL_HIGH>,
+                         <1 IRQ_TYPE_LEVEL_HIGH>,
+                         <2 IRQ_TYPE_LEVEL_HIGH>;
+            gpio-line-names =
+                   "ID_SDA", // GPIO0
+                   "ID_SCL", // GPIO1
+                   "GPIO2", "GPIO3", "GPIO4", "GPIO5", "GPIO6",
+                   "GPIO7", "GPIO8", "GPIO9", "GPIO10", "GPIO11",
+                   "GPIO12", "GPIO13", "GPIO14", "GPIO15", "GPIO16",
+                   "GPIO17", "GPIO18", "GPIO19", "GPIO20", "GPIO21",
+                   "GPIO22", "GPIO23", "GPIO24", "GPIO25", "GPIO26",
+                   "GPIO27",
+                   "PCIE_RP1_WAKE", // GPIO28
+                   "FAN_TACH", // GPIO29
+                   "HOST_SDA", // GPIO30
+                   "HOST_SCL", // GPIO31
+                   "ETH_RST_N", // GPIO32
+                   "", // GPIO33
+                   "CD0_IO0_MICCLK", // GPIO34
+                   "CD0_IO0_MICDAT0", // GPIO35
+                   "RP1_PCIE_CLKREQ_N", // GPIO36
+                   "", // GPIO37
+                   "CD0_SDA", // GPIO38
+                   "CD0_SCL", // GPIO39
+                   "CD1_SDA", // GPIO40
+                   "CD1_SCL", // GPIO41
+                   "USB_VBUS_EN", // GPIO42
+                   "USB_OC_N", // GPIO43
+                   "RP1_STAT_LED", // GPIO44
+                   "FAN_PWM", // GPIO45
+                   "CD1_IO0_MICCLK", // GPIO46
+                   "2712_WAKE", // GPIO47
+                   "CD1_IO1_MICDAT1", // GPIO48
+                   "EN_MAX_USB_CUR", // GPIO49
+                   "", // GPIO50
+                   "", // GPIO51
+                   "", // GPIO52
+                   ""; // GPIO53
+
+            rp1-i2s0-default-state {
+                function = "i2s0";
+                pins = "gpio18", "gpio19", "gpio20", "gpio21";
+                bias-disable;
+            };
+
+            rp1-uart0-default-state {
+                txd-pins {
+                    function = "uart0";
+                    pins = "gpio14";
+                    bias-disable;
+                };
+
+                rxd-pins {
+                    function = "uart0";
+                    pins = "gpio15";
+                    bias-pull-up;
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 8ced4ed32c00..a547e863807c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19578,7 +19578,9 @@ RASPBERRY PI RP1 PCI DRIVER
 M:	Andrea della Porta <andrea.porta at suse.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
+F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 F:	include/dt-bindings/clock/rp1.h
+F:	include/dt-bindings/misc/rp1.h
 
 RC-CORE / LIRC FRAMEWORK
 M:	Sean Young <sean at mess.org>
-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:25 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:25 +0100
Subject: [PATCH v5 01/10] dt-bindings: clock: Add RaspberryPi RP1 clock bindings
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <ae94e78443099cb6c48528ac8b18daaaae41419a.1733136811.git.andrea.porta@suse.com>

Add device tree bindings for the clock generator found in RP1 multi
function device, and relative entries in MAINTAINERS file.

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../clock/raspberrypi,rp1-clocks.yaml         | 58 ++++++++++++++++++
 MAINTAINERS                                   |  6 ++
 .../clock/raspberrypi,rp1-clocks.h            | 61 +++++++++++++++++++
 3 files changed, 125 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
 create mode 100644 include/dt-bindings/clock/raspberrypi,rp1-clocks.h

diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
new file mode 100644
index 000000000000..b2670cf7403a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/raspberrypi,rp1-clocks.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RaspberryPi RP1 clock generator
+
+maintainers:
+  - Andrea della Porta <andrea.porta at suse.com>
+
+description: |
+  The RP1 contains a clock generator designed as three PLLs (CORE, AUDIO,
+  VIDEO), and each PLL output can be programmed though dividers to generate
+  the clocks to drive the sub-peripherals embedded inside the chipset.
+
+  Link to datasheet:
+  https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
+
+properties:
+  compatible:
+    const: raspberrypi,rp1-clocks
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+    description:
+      The available clocks are defined in
+      include/dt-bindings/clock/raspberrypi,rp1-clocks.h.
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/raspberrypi,rp1-clocks.h>
+
+    rp1 {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clocks at c040018000 {
+            compatible = "raspberrypi,rp1-clocks";
+            reg = <0xc0 0x40018000 0x0 0x10038>;
+            #clock-cells = <1>;
+            clocks = <&clk_rp1_xosc>;
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..8ced4ed32c00 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19574,6 +19574,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/raspberrypi,rp1-cfe.yaml
 F:	drivers/media/platform/raspberrypi/rp1-cfe/
 
+RASPBERRY PI RP1 PCI DRIVER
+M:	Andrea della Porta <andrea.porta at suse.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
+F:	include/dt-bindings/clock/rp1.h
+
 RC-CORE / LIRC FRAMEWORK
 M:	Sean Young <sean at mess.org>
 L:	linux-media at vger.kernel.org
diff --git a/include/dt-bindings/clock/raspberrypi,rp1-clocks.h b/include/dt-bindings/clock/raspberrypi,rp1-clocks.h
new file mode 100644
index 000000000000..248efb895f35
--- /dev/null
+++ b/include/dt-bindings/clock/raspberrypi,rp1-clocks.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2021 Raspberry Pi Ltd.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_RASPBERRYPI_RP1
+#define __DT_BINDINGS_CLOCK_RASPBERRYPI_RP1
+
+#define RP1_PLL_SYS_CORE		0
+#define RP1_PLL_AUDIO_CORE		1
+#define RP1_PLL_VIDEO_CORE		2
+
+#define RP1_PLL_SYS			3
+#define RP1_PLL_AUDIO			4
+#define RP1_PLL_VIDEO			5
+
+#define RP1_PLL_SYS_PRI_PH		6
+#define RP1_PLL_SYS_SEC_PH		7
+#define RP1_PLL_AUDIO_PRI_PH		8
+
+#define RP1_PLL_SYS_SEC			9
+#define RP1_PLL_AUDIO_SEC		10
+#define RP1_PLL_VIDEO_SEC		11
+
+#define RP1_CLK_SYS			12
+#define RP1_CLK_SLOW_SYS		13
+#define RP1_CLK_DMA			14
+#define RP1_CLK_UART			15
+#define RP1_CLK_ETH			16
+#define RP1_CLK_PWM0			17
+#define RP1_CLK_PWM1			18
+#define RP1_CLK_AUDIO_IN		19
+#define RP1_CLK_AUDIO_OUT		20
+#define RP1_CLK_I2S			21
+#define RP1_CLK_MIPI0_CFG		22
+#define RP1_CLK_MIPI1_CFG		23
+#define RP1_CLK_PCIE_AUX		24
+#define RP1_CLK_USBH0_MICROFRAME	25
+#define RP1_CLK_USBH1_MICROFRAME	26
+#define RP1_CLK_USBH0_SUSPEND		27
+#define RP1_CLK_USBH1_SUSPEND		28
+#define RP1_CLK_ETH_TSU			29
+#define RP1_CLK_ADC			30
+#define RP1_CLK_SDIO_TIMER		31
+#define RP1_CLK_SDIO_ALT_SRC		32
+#define RP1_CLK_GP0			33
+#define RP1_CLK_GP1			34
+#define RP1_CLK_GP2			35
+#define RP1_CLK_GP3			36
+#define RP1_CLK_GP4			37
+#define RP1_CLK_GP5			38
+#define RP1_CLK_VEC			39
+#define RP1_CLK_DPI			40
+#define RP1_CLK_MIPI0_DPI		41
+#define RP1_CLK_MIPI1_DPI		42
+
+/* Extra PLL output channels - RP1B0 only */
+#define RP1_PLL_VIDEO_PRI_PH		43
+#define RP1_PLL_AUDIO_TERN		44
+
+#endif
-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:24 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:24 +0100
Subject: [PATCH v5 00/10] Add support for RaspberryPi RP1 PCI device using a DT overlay
Message-ID: <cover.1733136811.git.andrea.porta@suse.com>

RP1 is an MFD chipset that acts as a south-bridge PCIe endpoint sporting
a pletora of subdevices (i.e.  Ethernet, USB host controller, I2C, PWM,
etc.) whose registers are all reachable starting from an offset from the
BAR address.  The main point here is that while the RP1 as an endpoint
itself is discoverable via usual PCI enumeraiton, the devices it contains
are not discoverable and must be declared e.g. via the devicetree.

This patchset is an attempt to provide a minimum infrastructure to allow
the RP1 chipset to be discovered and perpherals it contains to be added
from a devictree overlay loaded during RP1 PCI endpoint enumeration.
Followup patches should add support for the several peripherals contained
in RP1.

This work is based upon dowstream drivers code and the proposal from RH
et al. (see [1] and [2]). A similar approach is also pursued in [3].

The patches are ordered as follows:

-PATCHES 1 to 4: add binding schemas for clock, gpio and RP1 peripherals.
 They are needed to support the other peripherals, e.g. the ethernet mac
 depends on a clock generated by RP1 and the phy is reset though the
 on-board gpio controller.

-PATCH 5 and 6: add clock and gpio device drivers.

-PATCH 7: the devicetree overlay describing the RP1 chipset. Please
 note that this patch should be taken by the same maintainer that will
 also take patch 11, since txeieh dtso is compiled in as binary blob and is
 closely coupled to the driver.

-PATCH 8: this is the main patch to support RP1 chipset and peripherals
 enabling through dtb overlay. The dtso since is intimately coupled with
 the driver and will be linked in as binary blob in the driver obj.
 The real dtso is in devicetree folder while the dtso in driver folder is
 just a placeholder to include the real dtso.
 In this way it is possible to check the dtso against dt-bindings.
 The reason why drivers/misc has been selected as containing folder
 for this driver can be seen in [6], [7] and [8].

-PATCH 9: add the external clock node (used by RP1) to the main dts.

-PATCH 10: add the relevant kernel CONFIG_ options to defconfig.

This patchset is also a first attempt to be more agnostic wrt hardware
description standards such as OF devicetree and ACPI, where 'agnostic'
means "using DT in coexistence with ACPI", as been already promoted
by e.g. AL (see [4]). Although there's currently no evidence it will also
run out of the box on purely ACPI system, it is a first step towards
that direction.

Please note that albeit this patchset has no prerequisites in order to
be applied cleanly, it still depends on Stanimir's WIP patchset for BCM2712
PCIe controller (see [5]) in order to work at runtime.

Many thanks,
Andrea della Porta

Links:
- [1]: https://lpc.events/event/17/contributions/1421/attachments/1337/2680/LPC2023%20Non-discoverable%20devices%20in%20PCI.pdf
- [2]: https://lore.kernel.org/lkml/20230419231155.GA899497-robh at kernel.org/t/
- [3]: https://lore.kernel.org/all/20240808154658.247873-1-herve.codina at bootlin.com/#t
- [4]: https://lore.kernel.org/all/73e05c77-6d53-4aae-95ac-415456ff0ae4 at lunn.ch/
- [5]: https://lore.kernel.org/all/20240626104544.14233-1-svarbanov at suse.de/
- [6]: https://lore.kernel.org/all/20240612140208.GC1504919 at google.com/
- [7]: https://lore.kernel.org/all/83f7fa09-d0e6-4f36-a27d-cee08979be2a at app.fastmail.com/
- [8]: https://lore.kernel.org/all/2024081356-mutable-everyday-6f9d at gregkh/


CHANGES IN V5:

PATCH RELATED -------------------------------------------------

- patch 1 and 2: added: 'Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>'

- patch 6 and 10: added 'Reviewed-by: Stefan Wahren <wahrenst at gmx.net>'

- rebased on v6.13-rc1


KCONFIG -----------------------------------------

- drivers/misc/rp1/Kconfig: leading spaces converted to tab


RP1 MISC DRIVER -----------------------------------

- added a comment to describe ovcs_id field from struct rp1_dev

- added braces around a single line if statement followed by a braced
  else condition

- removed a double space character


GPIO/PINCTRL --------------------------------------

- moved a multiplication (*) sign to the line it belongs to (code style
  fixup)


DTS -----------------------------------------

- Moved clk_rp1_xosc from SoC DTS to board DTS


BINDINGS ------------------------------------

- pci1de4,1.yaml: adjusted ranges and reg properties in the example
  to better reflect the address from RP1 documentation. These refelcts
  the same convention used in the dtso

- raspberrypi,rp1-gpio.yaml: fixed 'pins' pattern to go at most up to 53

- raspberrypi,rp1-gpio.yaml: using single quotes consistently over double
  quotes

- raspberrypi,rp1-gpio.yaml: added some pin config option supported by the
  hw/driver but missing in the schema


Andrea della Porta (10):
  dt-bindings: clock: Add RaspberryPi RP1 clock bindings
  dt-bindings: pinctrl: Add RaspberryPi RP1 gpio/pinctrl/pinmux bindings
  dt-bindings: pci: Add common schema for devices accessible through PCI
    BARs
  dt-bindings: misc: Add device specific bindings for RaspberryPi RP1
  clk: rp1: Add support for clocks provided by RP1
  pinctrl: rp1: Implement RaspberryPi RP1 gpio support
  arm64: dts: rp1: Add support for RaspberryPi's RP1 device
  misc: rp1: RaspberryPi RP1 misc driver
  arm64: dts: bcm2712: Add external clock for RP1 chipset on Rpi5
  arm64: defconfig: Enable RP1 misc/clock/gpio drivers

 .../clock/raspberrypi,rp1-clocks.yaml         |   58 +
 .../devicetree/bindings/misc/pci1de4,1.yaml   |   73 +
 .../devicetree/bindings/pci/pci-ep-bus.yaml   |   58 +
 .../pinctrl/raspberrypi,rp1-gpio.yaml         |  198 +++
 MAINTAINERS                                   |   14 +
 .../boot/dts/broadcom/bcm2712-rpi-5-b.dts     |    7 +
 arch/arm64/boot/dts/broadcom/rp1.dtso         |   58 +
 arch/arm64/configs/defconfig                  |    3 +
 drivers/clk/Kconfig                           |    9 +
 drivers/clk/Makefile                          |    1 +
 drivers/clk/clk-rp1.c                         | 1527 +++++++++++++++++
 drivers/misc/Kconfig                          |    1 +
 drivers/misc/Makefile                         |    1 +
 drivers/misc/rp1/Kconfig                      |   21 +
 drivers/misc/rp1/Makefile                     |    3 +
 drivers/misc/rp1/rp1-pci.dtso                 |    8 +
 drivers/misc/rp1/rp1_pci.c                    |  366 ++++
 drivers/misc/rp1/rp1_pci.h                    |   14 +
 drivers/pci/quirks.c                          |    1 +
 drivers/pinctrl/Kconfig                       |   11 +
 drivers/pinctrl/Makefile                      |    1 +
 drivers/pinctrl/pinctrl-rp1.c                 |  789 +++++++++
 .../clock/raspberrypi,rp1-clocks.h            |   61 +
 include/linux/pci_ids.h                       |    3 +
 24 files changed, 3286 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
 create mode 100644 Documentation/devicetree/bindings/misc/pci1de4,1.yaml
 create mode 100644 Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso
 create mode 100644 drivers/clk/clk-rp1.c
 create mode 100644 drivers/misc/rp1/Kconfig
 create mode 100644 drivers/misc/rp1/Makefile
 create mode 100644 drivers/misc/rp1/rp1-pci.dtso
 create mode 100644 drivers/misc/rp1/rp1_pci.c
 create mode 100644 drivers/misc/rp1/rp1_pci.h
 create mode 100644 drivers/pinctrl/pinctrl-rp1.c
 create mode 100644 include/dt-bindings/clock/raspberrypi,rp1-clocks.h

-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:28 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:28 +0100
Subject: [PATCH v5 04/10] dt-bindings: misc: Add device specific bindings for RaspberryPi RP1
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <99c23bd584d7b1b998d2cafb7807e0650db73f20.1733136811.git.andrea.porta@suse.com>

The RP1 is a MFD that exposes its peripherals through PCI BARs. This
schema is intended as minimal support for the clock generator and
gpio controller peripherals which are accessible through BAR1.

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 .../devicetree/bindings/misc/pci1de4,1.yaml   | 73 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 74 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/pci1de4,1.yaml

diff --git a/Documentation/devicetree/bindings/misc/pci1de4,1.yaml b/Documentation/devicetree/bindings/misc/pci1de4,1.yaml
new file mode 100644
index 000000000000..5171a949eda5
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/pci1de4,1.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/misc/pci1de4,1.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RaspberryPi RP1 MFD PCI device
+
+maintainers:
+  - Andrea della Porta <andrea.porta at suse.com>
+
+description:
+  The RaspberryPi RP1 is a PCI multi function device containing
+  peripherals ranging from Ethernet to USB controller, I2C, SPI
+  and others.
+  The peripherals are accessed by addressing the PCI BAR1 region.
+
+allOf:
+  - $ref: /schemas/pci/pci-ep-bus.yaml
+
+properties:
+  compatible:
+    additionalItems: true
+    maxItems: 3
+    items:
+      - const: pci1de4,1
+
+  '#interrupt-cells':
+    const: 2
+    description:
+      Specifies respectively the interrupt number and flags as defined
+      in include/dt-bindings/interrupt-controller/irq.h.
+
+  interrupt-controller: true
+
+unevaluatedProperties: false
+
+required:
+  - compatible
+  - '#interrupt-cells'
+  - interrupt-controller
+  - pci-ep-bus at 1
+
+examples:
+  - |
+    pci {
+        #address-cells = <3>;
+        #size-cells = <2>;
+
+        rp1 at 0,0 {
+            compatible = "pci1de4,1";
+            ranges = <0x01 0x00 0x00000000  0x82010000 0x00 0x00  0x00 0x400000>;
+            #address-cells = <3>;
+            #size-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+
+            pci_ep_bus: pci-ep-bus at 1 {
+                compatible = "simple-bus";
+                ranges = <0x00 0x40000000  0x01 0x00 0x00000000  0x00 0x00400000>;
+                dma-ranges = <0x10 0x00000000  0x43000000 0x10 0x00000000  0x10 0x00000000>;
+                #address-cells = <2>;
+                #size-cells = <2>;
+
+                rp1_clocks: clocks at 40018000 {
+                    compatible = "raspberrypi,rp1-clocks";
+                    reg = <0x00 0x40018000 0x0 0x10038>;
+                    #clock-cells = <1>;
+                    clocks = <&clk_rp1_xosc>;
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index ceed86755da4..4bc77e3fa80d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19578,6 +19578,7 @@ RASPBERRY PI RP1 PCI DRIVER
 M:	Andrea della Porta <andrea.porta at suse.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
+F:	Documentation/devicetree/bindings/misc/pci1de4,1.yaml
 F:	Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
 F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 F:	include/dt-bindings/clock/rp1.h
-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:27 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:27 +0100
Subject: [PATCH v5 03/10] dt-bindings: pci: Add common schema for devices accessible through PCI BARs
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <92fe1c6eb3ae1e7e7c151423568be2d13f19b55a.1733136811.git.andrea.porta@suse.com>

Common YAML schema for devices that exports internal peripherals through
PCI BARs. The BARs are exposed as simple-buses through which the
peripherals can be accessed.

This is not intended to be used as a standalone binding, but should be
included by device specific bindings.

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 .../devicetree/bindings/pci/pci-ep-bus.yaml   | 58 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/pci-ep-bus.yaml

diff --git a/Documentation/devicetree/bindings/pci/pci-ep-bus.yaml b/Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
new file mode 100644
index 000000000000..33479a5b40c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/pci-ep-bus.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Common Properties for PCI MFD EP with Peripherals Addressable from BARs
+
+maintainers:
+  - Andrea della Porta  <andrea.porta at suse.com>
+
+description:
+  Define a generic node representing a PCI endpoint which contains several sub-
+  peripherals. The peripherals can be accessed through one or more BARs.
+  This common schema is intended to be referenced from device tree bindings, and
+  does not represent a device tree binding by itself.
+
+properties:
+  '#address-cells':
+    const: 3
+
+  '#size-cells':
+    const: 2
+
+  ranges:
+    minItems: 1
+    maxItems: 6
+    items:
+      maxItems: 8
+      additionalItems: true
+      items:
+        - maximum: 5  # The BAR number
+        - const: 0
+        - const: 0
+
+patternProperties:
+  '^pci-ep-bus@[0-5]$':
+    type: object
+    description:
+      One node for each BAR used by peripherals contained in the PCI endpoint.
+      Each node represent a bus on which peripherals are connected.
+      This allows for some segmentation, e.g. one peripheral is accessible
+      through BAR0 and another through BAR1, and you don't want the two
+      peripherals to be able to act on the other BAR. Alternatively, when
+      different peripherals need to share BARs, you can define only one node
+      and use 'ranges' property to map all the used BARs.
+
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: simple-bus
+
+    required:
+      - compatible
+
+additionalProperties: true
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index a547e863807c..ceed86755da4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19578,6 +19578,7 @@ RASPBERRY PI RP1 PCI DRIVER
 M:	Andrea della Porta <andrea.porta at suse.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
+F:	Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
 F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 F:	include/dt-bindings/clock/rp1.h
 F:	include/dt-bindings/misc/rp1.h
-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:29 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:29 +0100
Subject: [PATCH v5 05/10] clk: rp1: Add support for clocks provided by RP1
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <48d32b3d58fc377987ca062904437805075f072d.1733136811.git.andrea.porta@suse.com>

RaspberryPi RP1 is an MFD providing, among other peripherals, several
clock generators and PLLs that drives the sub-peripherals.
Add the driver to support the clock providers.

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 MAINTAINERS           |    1 +
 drivers/clk/Kconfig   |    9 +
 drivers/clk/Makefile  |    1 +
 drivers/clk/clk-rp1.c | 1527 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1538 insertions(+)
 create mode 100644 drivers/clk/clk-rp1.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4bc77e3fa80d..9ad37eb45a51 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19581,6 +19581,7 @@ F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
 F:	Documentation/devicetree/bindings/misc/pci1de4,1.yaml
 F:	Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
 F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
+F:	drivers/clk/clk-rp1.c
 F:	include/dt-bindings/clock/rp1.h
 F:	include/dt-bindings/misc/rp1.h
 
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 713573b6c86c..cff90de71409 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -88,6 +88,15 @@ config COMMON_CLK_RK808
 	  These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each.
 	  Clkout1 is always on, Clkout2 can off by control register.
 
+config COMMON_CLK_RP1
+	tristate "Raspberry Pi RP1-based clock support"
+	depends on MISC_RP1 || COMPILE_TEST
+	default MISC_RP1
+	help
+	  Enable common clock framework support for Raspberry Pi RP1.
+	  This multi-function device has 3 main PLLs and several clock
+	  generators to drive the internal sub-peripherals.
+
 config COMMON_CLK_HI655X
 	tristate "Clock driver for Hi655x" if EXPERT
 	depends on (MFD_HI655X_PMIC || COMPILE_TEST)
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index bf4bd45adc3a..ff3993ed7e09 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -84,6 +84,7 @@ obj-$(CONFIG_CLK_LS1028A_PLLDIG)	+= clk-plldig.o
 obj-$(CONFIG_COMMON_CLK_PWM)		+= clk-pwm.o
 obj-$(CONFIG_CLK_QORIQ)			+= clk-qoriq.o
 obj-$(CONFIG_COMMON_CLK_RK808)		+= clk-rk808.o
+obj-$(CONFIG_COMMON_CLK_RP1)            += clk-rp1.o
 obj-$(CONFIG_COMMON_CLK_HI655X)		+= clk-hi655x.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)	+= clk-s2mps11.o
 obj-$(CONFIG_COMMON_CLK_SCMI)           += clk-scmi.o
diff --git a/drivers/clk/clk-rp1.c b/drivers/clk/clk-rp1.c
new file mode 100644
index 000000000000..d3789f5f835e
--- /dev/null
+++ b/drivers/clk/clk-rp1.c
@@ -0,0 +1,1527 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Raspberry Pi Ltd.
+ *
+ * Clock driver for RP1 PCIe multifunction chip.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/units.h>
+
+#include <dt-bindings/clock/raspberrypi,rp1-clocks.h>
+
+#define PLL_SYS_OFFSET			0x08000
+#define PLL_SYS_CS			(PLL_SYS_OFFSET + 0x00)
+#define PLL_SYS_PWR			(PLL_SYS_OFFSET + 0x04)
+#define PLL_SYS_FBDIV_INT		(PLL_SYS_OFFSET + 0x08)
+#define PLL_SYS_FBDIV_FRAC		(PLL_SYS_OFFSET + 0x0c)
+#define PLL_SYS_PRIM			(PLL_SYS_OFFSET + 0x10)
+#define PLL_SYS_SEC			(PLL_SYS_OFFSET + 0x14)
+
+#define PLL_AUDIO_OFFSET		0x0c000
+#define PLL_AUDIO_CS			(PLL_AUDIO_OFFSET + 0x00)
+#define PLL_AUDIO_PWR			(PLL_AUDIO_OFFSET + 0x04)
+#define PLL_AUDIO_FBDIV_INT		(PLL_AUDIO_OFFSET + 0x08)
+#define PLL_AUDIO_FBDIV_FRAC		(PLL_AUDIO_OFFSET + 0x0c)
+#define PLL_AUDIO_PRIM			(PLL_AUDIO_OFFSET + 0x10)
+#define PLL_AUDIO_SEC			(PLL_AUDIO_OFFSET + 0x14)
+#define PLL_AUDIO_TERN			(PLL_AUDIO_OFFSET + 0x18)
+
+#define PLL_VIDEO_OFFSET		0x10000
+#define PLL_VIDEO_CS			(PLL_VIDEO_OFFSET + 0x00)
+#define PLL_VIDEO_PWR			(PLL_VIDEO_OFFSET + 0x04)
+#define PLL_VIDEO_FBDIV_INT		(PLL_VIDEO_OFFSET + 0x08)
+#define PLL_VIDEO_FBDIV_FRAC		(PLL_VIDEO_OFFSET + 0x0c)
+#define PLL_VIDEO_PRIM			(PLL_VIDEO_OFFSET + 0x10)
+#define PLL_VIDEO_SEC			(PLL_VIDEO_OFFSET + 0x14)
+
+#define GPCLK_OE_CTRL			0x00000
+
+#define CLK_SYS_OFFSET			0x00014
+#define CLK_SYS_CTRL			(CLK_SYS_OFFSET + 0x00)
+#define CLK_SYS_DIV_INT			(CLK_SYS_OFFSET + 0x04)
+#define CLK_SYS_SEL			(CLK_SYS_OFFSET + 0x0c)
+
+#define CLK_SLOW_OFFSET			0x00024
+#define CLK_SLOW_SYS_CTRL		(CLK_SLOW_OFFSET + 0x00)
+#define CLK_SLOW_SYS_DIV_INT		(CLK_SLOW_OFFSET + 0x04)
+#define CLK_SLOW_SYS_SEL		(CLK_SLOW_OFFSET + 0x0c)
+
+#define CLK_DMA_OFFSET			0x00044
+#define CLK_DMA_CTRL			(CLK_DMA_OFFSET + 0x00)
+#define CLK_DMA_DIV_INT			(CLK_DMA_OFFSET + 0x04)
+#define CLK_DMA_SEL			(CLK_DMA_OFFSET + 0x0c)
+
+#define CLK_UART_OFFSET			0x00054
+#define CLK_UART_CTRL			(CLK_UART_OFFSET + 0x00)
+#define CLK_UART_DIV_INT		(CLK_UART_OFFSET + 0x04)
+#define CLK_UART_SEL			(CLK_UART_OFFSET + 0x0c)
+
+#define CLK_ETH_OFFSET			0x00064
+#define CLK_ETH_CTRL			(CLK_ETH_OFFSET + 0x00)
+#define CLK_ETH_DIV_INT			(CLK_ETH_OFFSET + 0x04)
+#define CLK_ETH_SEL			(CLK_ETH_OFFSET + 0x0c)
+
+#define CLK_PWM0_OFFSET			0x00074
+#define CLK_PWM0_CTRL			(CLK_PWM0_OFFSET + 0x00)
+#define CLK_PWM0_DIV_INT		(CLK_PWM0_OFFSET + 0x04)
+#define CLK_PWM0_DIV_FRAC		(CLK_PWM0_OFFSET + 0x08)
+#define CLK_PWM0_SEL			(CLK_PWM0_OFFSET + 0x0c)
+
+#define CLK_PWM1_OFFSET			0x00084
+#define CLK_PWM1_CTRL			(CLK_PWM1_OFFSET + 0x00)
+#define CLK_PWM1_DIV_INT		(CLK_PWM1_OFFSET + 0x04)
+#define CLK_PWM1_DIV_FRAC		(CLK_PWM1_OFFSET + 0x08)
+#define CLK_PWM1_SEL			(CLK_PWM1_OFFSET + 0x0c)
+
+#define CLK_AUDIO_IN_OFFSET		0x00094
+#define CLK_AUDIO_IN_CTRL		(CLK_AUDIO_IN_OFFSET + 0x00)
+#define CLK_AUDIO_IN_DIV_INT		(CLK_AUDIO_IN_OFFSET + 0x04)
+#define CLK_AUDIO_IN_SEL		(CLK_AUDIO_IN_OFFSET + 0x0c)
+
+#define CLK_AUDIO_OUT_OFFSET		0x000a4
+#define CLK_AUDIO_OUT_CTRL		(CLK_AUDIO_OUT_OFFSET + 0x00)
+#define CLK_AUDIO_OUT_DIV_INT		(CLK_AUDIO_OUT_OFFSET + 0x04)
+#define CLK_AUDIO_OUT_SEL		(CLK_AUDIO_OUT_OFFSET + 0x0c)
+
+#define CLK_I2S_OFFSET			0x000b4
+#define CLK_I2S_CTRL			(CLK_I2S_OFFSET + 0x00)
+#define CLK_I2S_DIV_INT			(CLK_I2S_OFFSET + 0x04)
+#define CLK_I2S_SEL			(CLK_I2S_OFFSET + 0x0c)
+
+#define CLK_MIPI0_CFG_OFFSET		0x000c4
+#define CLK_MIPI0_CFG_CTRL		(CLK_MIPI0_CFG_OFFSET + 0x00)
+#define CLK_MIPI0_CFG_DIV_INT		(CLK_MIPI0_CFG_OFFSET + 0x04)
+#define CLK_MIPI0_CFG_SEL		(CLK_MIPI0_CFG_OFFSET + 0x0c)
+
+#define CLK_MIPI1_CFG_OFFSET		0x000d4
+#define CLK_MIPI1_CFG_CTRL		(CLK_MIPI1_CFG_OFFSET + 0x00)
+#define CLK_MIPI1_CFG_DIV_INT		(CLK_MIPI1_CFG_OFFSET + 0x04)
+#define CLK_MIPI1_CFG_SEL		(CLK_MIPI1_CFG_OFFSET + 0x0c)
+
+#define CLK_PCIE_AUX_OFFSET		0x000e4
+#define CLK_PCIE_AUX_CTRL		(CLK_PCIE_AUX_OFFSET + 0x00)
+#define CLK_PCIE_AUX_DIV_INT		(CLK_PCIE_AUX_OFFSET + 0x04)
+#define CLK_PCIE_AUX_SEL		(CLK_PCIE_AUX_OFFSET + 0x0c)
+
+#define CLK_USBH0_MICROFRAME_OFFSET	0x000f4
+#define CLK_USBH0_MICROFRAME_CTRL	(CLK_USBH0_MICROFRAME_OFFSET + 0x00)
+#define CLK_USBH0_MICROFRAME_DIV_INT	(CLK_USBH0_MICROFRAME_OFFSET + 0x04)
+#define CLK_USBH0_MICROFRAME_SEL	(CLK_USBH0_MICROFRAME_OFFSET + 0x0c)
+
+#define CLK_USBH1_MICROFRAME_OFFSET	0x00104
+#define CLK_USBH1_MICROFRAME_CTRL	(CLK_USBH1_MICROFRAME_OFFSET + 0x00)
+#define CLK_USBH1_MICROFRAME_DIV_INT	(CLK_USBH1_MICROFRAME_OFFSET + 0x04)
+#define CLK_USBH1_MICROFRAME_SEL	(CLK_USBH1_MICROFRAME_OFFSET + 0x0c)
+
+#define CLK_USBH0_SUSPEND_OFFSET	0x00114
+#define CLK_USBH0_SUSPEND_CTRL		(CLK_USBH0_SUSPEND_OFFSET + 0x00)
+#define CLK_USBH0_SUSPEND_DIV_INT	(CLK_USBH0_SUSPEND_OFFSET + 0x04)
+#define CLK_USBH0_SUSPEND_SEL		(CLK_USBH0_SUSPEND_OFFSET + 0x0c)
+
+#define CLK_USBH1_SUSPEND_OFFSET	0x00124
+#define CLK_USBH1_SUSPEND_CTRL		(CLK_USBH1_SUSPEND_OFFSET + 0x00)
+#define CLK_USBH1_SUSPEND_DIV_INT	(CLK_USBH1_SUSPEND_OFFSET + 0x04)
+#define CLK_USBH1_SUSPEND_SEL		(CLK_USBH1_SUSPEND_OFFSET + 0x0c)
+
+#define CLK_ETH_TSU_OFFSET		0x00134
+#define CLK_ETH_TSU_CTRL		(CLK_ETH_TSU_OFFSET + 0x00)
+#define CLK_ETH_TSU_DIV_INT		(CLK_ETH_TSU_OFFSET + 0x04)
+#define CLK_ETH_TSU_SEL			(CLK_ETH_TSU_OFFSET + 0x0c)
+
+#define CLK_ADC_OFFSET			0x00144
+#define CLK_ADC_CTRL			(CLK_ADC_OFFSET + 0x00)
+#define CLK_ADC_DIV_INT			(CLK_ADC_OFFSET + 0x04)
+#define CLK_ADC_SEL			(CLK_ADC_OFFSET + 0x0c)
+
+#define CLK_SDIO_TIMER_OFFSET		0x00154
+#define CLK_SDIO_TIMER_CTRL		(CLK_SDIO_TIMER_OFFSET + 0x00)
+#define CLK_SDIO_TIMER_DIV_INT		(CLK_SDIO_TIMER_OFFSET + 0x04)
+#define CLK_SDIO_TIMER_SEL		(CLK_SDIO_TIMER_OFFSET + 0x0c)
+
+#define CLK_SDIO_ALT_SRC_OFFSET		0x00164
+#define CLK_SDIO_ALT_SRC_CTRL		(CLK_SDIO_ALT_SRC_OFFSET + 0x00)
+#define CLK_SDIO_ALT_SRC_DIV_INT	(CLK_SDIO_ALT_SRC_OFFSET + 0x04)
+#define CLK_SDIO_ALT_SRC_SEL		(CLK_SDIO_ALT_SRC_OFFSET + 0x0c)
+
+#define CLK_GP0_OFFSET			0x00174
+#define CLK_GP0_CTRL			(CLK_GP0_OFFSET + 0x00)
+#define CLK_GP0_DIV_INT			(CLK_GP0_OFFSET + 0x04)
+#define CLK_GP0_DIV_FRAC		(CLK_GP0_OFFSET + 0x08)
+#define CLK_GP0_SEL			(CLK_GP0_OFFSET + 0x0c)
+
+#define CLK_GP1_OFFSET			0x00184
+#define CLK_GP1_CTRL			(CLK_GP1_OFFSET + 0x00)
+#define CLK_GP1_DIV_INT			(CLK_GP1_OFFSET + 0x04)
+#define CLK_GP1_DIV_FRAC		(CLK_GP1_OFFSET + 0x08)
+#define CLK_GP1_SEL			(CLK_GP1_OFFSET + 0x0c)
+
+#define CLK_GP2_OFFSET			0x00194
+#define CLK_GP2_CTRL			(CLK_GP2_OFFSET + 0x00)
+#define CLK_GP2_DIV_INT			(CLK_GP2_OFFSET + 0x04)
+#define CLK_GP2_DIV_FRAC		(CLK_GP2_OFFSET + 0x08)
+#define CLK_GP2_SEL			(CLK_GP2_OFFSET + 0x0c)
+
+#define CLK_GP3_OFFSET			0x001a4
+#define CLK_GP3_CTRL			(CLK_GP3_OFFSET + 0x00)
+#define CLK_GP3_DIV_INT			(CLK_GP3_OFFSET + 0x04)
+#define CLK_GP3_DIV_FRAC		(CLK_GP3_OFFSET + 0x08)
+#define CLK_GP3_SEL			(CLK_GP3_OFFSET + 0x0c)
+
+#define CLK_GP4_OFFSET			0x001b4
+#define CLK_GP4_CTRL			(CLK_GP4_OFFSET + 0x00)
+#define CLK_GP4_DIV_INT			(CLK_GP4_OFFSET + 0x04)
+#define CLK_GP4_DIV_FRAC		(CLK_GP4_OFFSET + 0x08)
+#define CLK_GP4_SEL			(CLK_GP4_OFFSET + 0x0c)
+
+#define CLK_GP5_OFFSET			0x001c4
+#define CLK_GP5_CTRL			(CLK_GP5_OFFSET + 0x00)
+#define CLK_GP5_DIV_INT			(CLK_GP5_OFFSET + 0x04)
+#define CLK_GP5_DIV_FRAC		(CLK_GP5_OFFSET + 0x08)
+#define CLK_GP5_SEL			(CLK_GP5_OFFSET + 0x0c)
+
+#define CLK_SYS_RESUS_CTRL		0x0020c
+
+#define CLK_SLOW_SYS_RESUS_CTRL		0x00214
+
+#define FC0_OFFSET			0x0021c
+#define FC0_REF_KHZ			(FC0_OFFSET + 0x00)
+#define FC0_MIN_KHZ			(FC0_OFFSET + 0x04)
+#define FC0_MAX_KHZ			(FC0_OFFSET + 0x08)
+#define FC0_DELAY			(FC0_OFFSET + 0x0c)
+#define FC0_INTERVAL			(FC0_OFFSET + 0x10)
+#define FC0_SRC				(FC0_OFFSET + 0x14)
+#define FC0_STATUS			(FC0_OFFSET + 0x18)
+#define FC0_RESULT			(FC0_OFFSET + 0x1c)
+#define FC_SIZE				0x20
+#define FC_COUNT			8
+#define FC_NUM(idx, off)		((idx) * 32 + (off))
+
+#define AUX_SEL				1
+
+#define VIDEO_CLOCKS_OFFSET		0x4000
+#define VIDEO_CLK_VEC_CTRL		(VIDEO_CLOCKS_OFFSET + 0x0000)
+#define VIDEO_CLK_VEC_DIV_INT		(VIDEO_CLOCKS_OFFSET + 0x0004)
+#define VIDEO_CLK_VEC_SEL		(VIDEO_CLOCKS_OFFSET + 0x000c)
+#define VIDEO_CLK_DPI_CTRL		(VIDEO_CLOCKS_OFFSET + 0x0010)
+#define VIDEO_CLK_DPI_DIV_INT		(VIDEO_CLOCKS_OFFSET + 0x0014)
+#define VIDEO_CLK_DPI_SEL		(VIDEO_CLOCKS_OFFSET + 0x001c)
+#define VIDEO_CLK_MIPI0_DPI_CTRL	(VIDEO_CLOCKS_OFFSET + 0x0020)
+#define VIDEO_CLK_MIPI0_DPI_DIV_INT	(VIDEO_CLOCKS_OFFSET + 0x0024)
+#define VIDEO_CLK_MIPI0_DPI_DIV_FRAC	(VIDEO_CLOCKS_OFFSET + 0x0028)
+#define VIDEO_CLK_MIPI0_DPI_SEL		(VIDEO_CLOCKS_OFFSET + 0x002c)
+#define VIDEO_CLK_MIPI1_DPI_CTRL	(VIDEO_CLOCKS_OFFSET + 0x0030)
+#define VIDEO_CLK_MIPI1_DPI_DIV_INT	(VIDEO_CLOCKS_OFFSET + 0x0034)
+#define VIDEO_CLK_MIPI1_DPI_DIV_FRAC	(VIDEO_CLOCKS_OFFSET + 0x0038)
+#define VIDEO_CLK_MIPI1_DPI_SEL		(VIDEO_CLOCKS_OFFSET + 0x003c)
+
+#define DIV_INT_8BIT_MAX		GENMASK(7, 0)	/* max divide for most clocks */
+#define DIV_INT_16BIT_MAX		GENMASK(15, 0)	/* max divide for GPx, PWM */
+#define DIV_INT_24BIT_MAX               GENMASK(23, 0)	/* max divide for CLK_SYS */
+
+#define FC0_STATUS_DONE			BIT(4)
+#define FC0_STATUS_RUNNING		BIT(8)
+#define FC0_RESULT_FRAC_SHIFT		5
+
+#define PLL_PRIM_DIV1_SHIFT		16
+#define PLL_PRIM_DIV1_WIDTH		3
+#define PLL_PRIM_DIV1_MASK		GENMASK(PLL_PRIM_DIV1_SHIFT + \
+						PLL_PRIM_DIV1_WIDTH - 1, \
+						PLL_PRIM_DIV1_SHIFT)
+#define PLL_PRIM_DIV2_SHIFT		12
+#define PLL_PRIM_DIV2_WIDTH		3
+#define PLL_PRIM_DIV2_MASK		GENMASK(PLL_PRIM_DIV2_SHIFT + \
+						PLL_PRIM_DIV2_WIDTH - 1, \
+						PLL_PRIM_DIV2_SHIFT)
+
+#define PLL_SEC_DIV_SHIFT		8
+#define PLL_SEC_DIV_WIDTH		5
+#define PLL_SEC_DIV_MASK		GENMASK(PLL_SEC_DIV_SHIFT + \
+						PLL_SEC_DIV_WIDTH - 1, \
+						PLL_SEC_DIV_SHIFT)
+
+#define PLL_CS_LOCK			BIT(31)
+#define PLL_CS_REFDIV_SHIFT		0
+
+#define PLL_PWR_PD			BIT(0)
+#define PLL_PWR_DACPD			BIT(1)
+#define PLL_PWR_DSMPD			BIT(2)
+#define PLL_PWR_POSTDIVPD		BIT(3)
+#define PLL_PWR_4PHASEPD		BIT(4)
+#define PLL_PWR_VCOPD			BIT(5)
+#define PLL_PWR_MASK			GENMASK(5, 0)
+
+#define PLL_SEC_RST			BIT(16)
+#define PLL_SEC_IMPL			BIT(31)
+
+/* PLL phase output for both PRI and SEC */
+#define PLL_PH_EN			BIT(4)
+#define PLL_PH_PHASE_SHIFT		0
+
+#define RP1_PLL_PHASE_0			0
+#define RP1_PLL_PHASE_90		1
+#define RP1_PLL_PHASE_180		2
+#define RP1_PLL_PHASE_270		3
+
+/* Clock fields for all clocks */
+#define CLK_CTRL_ENABLE			BIT(11)
+#define CLK_CTRL_AUXSRC_SHIFT		5
+#define CLK_CTRL_AUXSRC_WIDTH		5
+#define CLK_CTRL_AUXSRC_MASK		GENMASK(CLK_CTRL_AUXSRC_SHIFT + \
+						CLK_CTRL_AUXSRC_WIDTH - 1, \
+						CLK_CTRL_AUXSRC_SHIFT)
+#define CLK_CTRL_SRC_SHIFT		0
+#define CLK_DIV_FRAC_BITS		16
+
+#define LOCK_TIMEOUT_US			100000
+#define LOCK_POLL_DELAY_US		5
+
+#define MAX_CLK_PARENTS			16
+
+/*
+ * Secondary PLL channel output divider table.
+ * Divider values range from 8 to 19.
+ * Invalid values default to 19
+ */
+static const struct clk_div_table pll_sec_div_table[] = {
+	{ 0x00, 19 },
+	{ 0x01, 19 },
+	{ 0x02, 19 },
+	{ 0x03, 19 },
+	{ 0x04, 19 },
+	{ 0x05, 19 },
+	{ 0x06, 19 },
+	{ 0x07, 19 },
+	{ 0x08,  8 },
+	{ 0x09,  9 },
+	{ 0x0a, 10 },
+	{ 0x0b, 11 },
+	{ 0x0c, 12 },
+	{ 0x0d, 13 },
+	{ 0x0e, 14 },
+	{ 0x0f, 15 },
+	{ 0x10, 16 },
+	{ 0x11, 17 },
+	{ 0x12, 18 },
+	{ 0x13, 19 },
+	{ 0x14, 19 },
+	{ 0x15, 19 },
+	{ 0x16, 19 },
+	{ 0x17, 19 },
+	{ 0x18, 19 },
+	{ 0x19, 19 },
+	{ 0x1a, 19 },
+	{ 0x1b, 19 },
+	{ 0x1c, 19 },
+	{ 0x1d, 19 },
+	{ 0x1e, 19 },
+	{ 0x1f, 19 },
+	{ 0 }
+};
+
+struct rp1_clockman {
+	struct device *dev;
+	void __iomem *regs;
+	struct regmap *regmap;
+	spinlock_t regs_lock; /* spinlock for all clocks */
+
+	/* Must be last */
+	struct clk_hw_onecell_data onecell;
+};
+
+struct rp1_pll_core_data {
+	u32 cs_reg;
+	u32 pwr_reg;
+	u32 fbdiv_int_reg;
+	u32 fbdiv_frac_reg;
+	u32 fc0_src;
+};
+
+struct rp1_pll_data {
+	u32 ctrl_reg;
+	u32 fc0_src;
+};
+
+struct rp1_pll_ph_data {
+	unsigned int phase;
+	unsigned int fixed_divider;
+	u32 ph_reg;
+	u32 fc0_src;
+};
+
+struct rp1_pll_divider_data {
+	u32 sec_reg;
+	u32 fc0_src;
+};
+
+struct rp1_clock_data {
+	int num_std_parents;
+	int num_aux_parents;
+	u32 oe_mask;
+	u32 clk_src_mask;
+	u32 ctrl_reg;
+	u32 div_int_reg;
+	u32 div_frac_reg;
+	u32 sel_reg;
+	u32 div_int_max;
+	unsigned long max_freq;
+	u32 fc0_src;
+};
+
+struct rp1_clk_desc {
+	struct clk_hw *(*clk_register)(struct rp1_clockman *clockman,
+				       struct rp1_clk_desc *desc);
+	const void *data;
+	struct clk_hw hw;
+	struct rp1_clockman *clockman;
+	unsigned long cached_rate;
+	struct clk_divider div;
+};
+
+static inline
+void clockman_write(struct rp1_clockman *clockman, u32 reg, u32 val)
+{
+	regmap_write(clockman->regmap, reg, val);
+}
+
+static inline u32 clockman_read(struct rp1_clockman *clockman, u32 reg)
+{
+	u32 val;
+
+	regmap_read(clockman->regmap, reg, &val);
+
+	return val;
+}
+
+static int rp1_pll_core_is_on(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *pll_core = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+
+	u32 pwr = clockman_read(clockman, data->pwr_reg);
+
+	return (pwr & PLL_PWR_PD) || (pwr & PLL_PWR_POSTDIVPD);
+}
+
+static int rp1_pll_core_on(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *pll_core = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+
+	u32 fbdiv_frac, val;
+	int ret;
+
+	spin_lock(&clockman->regs_lock);
+
+	if (!(clockman_read(clockman, data->cs_reg) & PLL_CS_LOCK)) {
+		/* Reset to a known state. */
+		clockman_write(clockman, data->pwr_reg, PLL_PWR_MASK);
+		clockman_write(clockman, data->fbdiv_int_reg, 20);
+		clockman_write(clockman, data->fbdiv_frac_reg, 0);
+		clockman_write(clockman, data->cs_reg, 1 << PLL_CS_REFDIV_SHIFT);
+	}
+
+	/* Come out of reset. */
+	fbdiv_frac = clockman_read(clockman, data->fbdiv_frac_reg);
+	clockman_write(clockman, data->pwr_reg, fbdiv_frac ? 0 : PLL_PWR_DSMPD);
+	spin_unlock(&clockman->regs_lock);
+
+	/* Wait for the PLL to lock. */
+	ret = regmap_read_poll_timeout(clockman->regmap, data->cs_reg, val,
+				       val & PLL_CS_LOCK,
+				       LOCK_POLL_DELAY_US, LOCK_TIMEOUT_US);
+	if (ret)
+		dev_err(clockman->dev, "%s: can't lock PLL\n",
+			clk_hw_get_name(hw));
+
+	return ret;
+}
+
+static void rp1_pll_core_off(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *pll_core = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->pwr_reg, 0);
+	spin_unlock(&clockman->regs_lock);
+}
+
+static inline unsigned long get_pll_core_divider(struct clk_hw *hw,
+						 unsigned long rate,
+						 unsigned long parent_rate,
+						 u32 *div_int, u32 *div_frac)
+{
+	u32 fbdiv_int, fbdiv_frac;
+	unsigned long calc_rate;
+	u64 shifted_fbdiv_int;
+	u64 div_fp64; /* 32.32 fixed point fraction. */
+
+	/* Factor of reference clock to VCO frequency. */
+	div_fp64 = (u64)(rate) << 32;
+	div_fp64 = DIV_ROUND_CLOSEST_ULL(div_fp64, parent_rate);
+
+	/* Round the fractional component at 24 bits. */
+	div_fp64 += 1 << (32 - 24 - 1);
+
+	fbdiv_int = div_fp64 >> 32;
+	fbdiv_frac = (div_fp64 >> (32 - 24)) & 0xffffff;
+
+	shifted_fbdiv_int = (u64)fbdiv_int << 24;
+	calc_rate = (u64)parent_rate * (shifted_fbdiv_int + fbdiv_frac);
+	calc_rate += BIT(23);
+	calc_rate >>= 24;
+
+	*div_int = fbdiv_int;
+	*div_frac = fbdiv_frac;
+
+	return calc_rate;
+}
+
+static int rp1_pll_core_set_rate(struct clk_hw *hw,
+				 unsigned long rate, unsigned long parent_rate)
+{
+	struct rp1_clk_desc *pll_core = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+
+	unsigned long calc_rate;
+	u32 fbdiv_int, fbdiv_frac;
+
+	/* Disable dividers to start with. */
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->fbdiv_int_reg, 0);
+	clockman_write(clockman, data->fbdiv_frac_reg, 0);
+	spin_unlock(&clockman->regs_lock);
+
+	calc_rate = get_pll_core_divider(hw, rate, parent_rate,
+					 &fbdiv_int, &fbdiv_frac);
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->pwr_reg, fbdiv_frac ? 0 : PLL_PWR_DSMPD);
+	clockman_write(clockman, data->fbdiv_int_reg, fbdiv_int);
+	clockman_write(clockman, data->fbdiv_frac_reg, fbdiv_frac);
+	spin_unlock(&clockman->regs_lock);
+
+	/* Check that reference frequency is no greater than VCO / 16. */
+	if (WARN_ON_ONCE(parent_rate > (rate / 16)))
+		return -ERANGE;
+
+	pll_core->cached_rate = calc_rate;
+
+	spin_lock(&clockman->regs_lock);
+	/* Don't need to divide ref unless parent_rate > (output freq / 16) */
+	clockman_write(clockman, data->cs_reg,
+		       clockman_read(clockman, data->cs_reg) |
+				     (1 << PLL_CS_REFDIV_SHIFT));
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static unsigned long rp1_pll_core_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	struct rp1_clk_desc *pll_core = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll_core->clockman;
+	const struct rp1_pll_core_data *data = pll_core->data;
+
+	u32 fbdiv_int, fbdiv_frac;
+	unsigned long calc_rate;
+	u64 shifted_fbdiv_int;
+
+	fbdiv_int = clockman_read(clockman, data->fbdiv_int_reg);
+	fbdiv_frac = clockman_read(clockman, data->fbdiv_frac_reg);
+
+	shifted_fbdiv_int = (u64)fbdiv_int << 24;
+	calc_rate = (u64)parent_rate * (shifted_fbdiv_int + fbdiv_frac);
+	calc_rate += BIT(23);
+	calc_rate >>= 24;
+
+	return calc_rate;
+}
+
+static long rp1_pll_core_round_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *parent_rate)
+{
+	u32 fbdiv_int, fbdiv_frac;
+
+	return get_pll_core_divider(hw, rate, *parent_rate,
+				    &fbdiv_int, &fbdiv_frac);
+}
+
+static void get_pll_prim_dividers(unsigned long rate, unsigned long parent_rate,
+				  u32 *divider1, u32 *divider2)
+{
+	unsigned int div1, div2;
+	unsigned int best_div1 = 7, best_div2 = 7;
+	unsigned long best_rate_diff =
+		abs_diff(DIV_ROUND_CLOSEST(parent_rate, best_div1 * best_div2), rate);
+	unsigned long rate_diff, calc_rate;
+
+	for (div1 = 1; div1 <= 7; div1++) {
+		for (div2 = 1; div2 <= div1; div2++) {
+			calc_rate = DIV_ROUND_CLOSEST(parent_rate, div1 * div2);
+			rate_diff = abs_diff(calc_rate, rate);
+
+			if (calc_rate == rate) {
+				best_div1 = div1;
+				best_div2 = div2;
+				goto done;
+			} else if (rate_diff < best_rate_diff) {
+				best_div1 = div1;
+				best_div2 = div2;
+				best_rate_diff = rate_diff;
+			}
+		}
+	}
+
+done:
+	*divider1 = best_div1;
+	*divider2 = best_div2;
+}
+
+static int rp1_pll_set_rate(struct clk_hw *hw,
+			    unsigned long rate, unsigned long parent_rate)
+{
+	struct rp1_clk_desc *pll = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll->clockman;
+	const struct rp1_pll_data *data = pll->data;
+
+	u32 prim, prim_div1, prim_div2;
+
+	get_pll_prim_dividers(rate, parent_rate, &prim_div1, &prim_div2);
+
+	spin_lock(&clockman->regs_lock);
+	prim = clockman_read(clockman, data->ctrl_reg);
+	prim &= ~PLL_PRIM_DIV1_MASK;
+	prim |= FIELD_PREP(PLL_PRIM_DIV1_MASK, prim_div1);
+	prim &= ~PLL_PRIM_DIV2_MASK;
+	prim |= FIELD_PREP(PLL_PRIM_DIV2_MASK, prim_div2);
+	clockman_write(clockman, data->ctrl_reg, prim);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static unsigned long rp1_pll_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct rp1_clk_desc *pll = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll->clockman;
+	const struct rp1_pll_data *data = pll->data;
+	u32 prim, prim_div1, prim_div2;
+
+	prim = clockman_read(clockman, data->ctrl_reg);
+	prim_div1 = (prim & PLL_PRIM_DIV1_MASK) >> PLL_PRIM_DIV1_SHIFT;
+	prim_div2 = (prim & PLL_PRIM_DIV2_MASK) >> PLL_PRIM_DIV2_SHIFT;
+
+	if (!prim_div1 || !prim_div2) {
+		dev_err(clockman->dev, "%s: (%s) zero divider value\n",
+			__func__, clk_hw_get_name(hw));
+		return 0;
+	}
+
+	return DIV_ROUND_CLOSEST(parent_rate, prim_div1 * prim_div2);
+}
+
+static long rp1_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *parent_rate)
+{
+	u32 div1, div2;
+
+	get_pll_prim_dividers(rate, *parent_rate, &div1, &div2);
+
+	return DIV_ROUND_CLOSEST(*parent_rate, div1 * div2);
+}
+
+static int rp1_pll_ph_is_on(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll_ph->clockman;
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+
+	return !!(clockman_read(clockman, data->ph_reg) & PLL_PH_EN);
+}
+
+static int rp1_pll_ph_on(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll_ph->clockman;
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+	u32 ph_reg;
+
+	/* TODO: ensure pri/sec is enabled! */
+	spin_lock(&clockman->regs_lock);
+	ph_reg = clockman_read(clockman, data->ph_reg);
+	ph_reg |= data->phase << PLL_PH_PHASE_SHIFT;
+	ph_reg |= PLL_PH_EN;
+	clockman_write(clockman, data->ph_reg, ph_reg);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static void rp1_pll_ph_off(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = pll_ph->clockman;
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->ph_reg,
+		       clockman_read(clockman, data->ph_reg) & ~PLL_PH_EN);
+	spin_unlock(&clockman->regs_lock);
+}
+
+static unsigned long rp1_pll_ph_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+
+	return parent_rate / data->fixed_divider;
+}
+
+static long rp1_pll_ph_round_rate(struct clk_hw *hw, unsigned long rate,
+				  unsigned long *parent_rate)
+{
+	struct rp1_clk_desc *pll_ph = container_of(hw, struct rp1_clk_desc, hw);
+	const struct rp1_pll_ph_data *data = pll_ph->data;
+
+	return *parent_rate / data->fixed_divider;
+}
+
+static int rp1_pll_divider_is_on(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *divider = container_of(hw, struct rp1_clk_desc, div.hw);
+	struct rp1_clockman *clockman = divider->clockman;
+	const struct rp1_pll_data *data = divider->data;
+
+	return !(clockman_read(clockman, data->ctrl_reg) & PLL_SEC_RST);
+}
+
+static int rp1_pll_divider_on(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *divider = container_of(hw, struct rp1_clk_desc, div.hw);
+	struct rp1_clockman *clockman = divider->clockman;
+	const struct rp1_pll_data *data = divider->data;
+
+	spin_lock(&clockman->regs_lock);
+	/* Check the implementation bit is set! */
+	WARN_ON(!(clockman_read(clockman, data->ctrl_reg) & PLL_SEC_IMPL));
+	clockman_write(clockman, data->ctrl_reg,
+		       clockman_read(clockman, data->ctrl_reg) & ~PLL_SEC_RST);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static void rp1_pll_divider_off(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *divider = container_of(hw, struct rp1_clk_desc, div.hw);
+	struct rp1_clockman *clockman = divider->clockman;
+	const struct rp1_pll_data *data = divider->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->ctrl_reg,
+		       clockman_read(clockman, data->ctrl_reg) | PLL_SEC_RST);
+	spin_unlock(&clockman->regs_lock);
+}
+
+static int rp1_pll_divider_set_rate(struct clk_hw *hw,
+				    unsigned long rate,
+				    unsigned long parent_rate)
+{
+	struct rp1_clk_desc *divider = container_of(hw, struct rp1_clk_desc, div.hw);
+	struct rp1_clockman *clockman = divider->clockman;
+	const struct rp1_pll_data *data = divider->data;
+	u32 div, sec;
+
+	div = DIV_ROUND_UP_ULL(parent_rate, rate);
+	div = clamp(div, 8u, 19u);
+
+	spin_lock(&clockman->regs_lock);
+	sec = clockman_read(clockman, data->ctrl_reg);
+	sec &= ~PLL_SEC_DIV_MASK;
+	sec |= FIELD_PREP(PLL_SEC_DIV_MASK, div);
+
+	/* Must keep the divider in reset to change the value. */
+	sec |= PLL_SEC_RST;
+	clockman_write(clockman, data->ctrl_reg, sec);
+
+	/* TODO: must sleep 10 pll vco cycles */
+	sec &= ~PLL_SEC_RST;
+	clockman_write(clockman, data->ctrl_reg, sec);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static unsigned long rp1_pll_divider_recalc_rate(struct clk_hw *hw,
+						 unsigned long parent_rate)
+{
+	return clk_divider_ops.recalc_rate(hw, parent_rate);
+}
+
+static long rp1_pll_divider_round_rate(struct clk_hw *hw,
+				       unsigned long rate,
+				       unsigned long *parent_rate)
+{
+	return clk_divider_ops.round_rate(hw, rate, parent_rate);
+}
+
+static int rp1_clock_is_on(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+
+	return !!(clockman_read(clockman, data->ctrl_reg) & CLK_CTRL_ENABLE);
+}
+
+static unsigned long rp1_clock_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+	u64 calc_rate;
+	u64 div;
+
+	u32 frac;
+
+	div = clockman_read(clockman, data->div_int_reg);
+	frac = (data->div_frac_reg != 0) ?
+		clockman_read(clockman, data->div_frac_reg) : 0;
+
+	/* If the integer portion of the divider is 0, treat it as 2^16 */
+	if (!div)
+		div = 1 << 16;
+
+	div = (div << CLK_DIV_FRAC_BITS) | (frac >> (32 - CLK_DIV_FRAC_BITS));
+
+	calc_rate = (u64)parent_rate << CLK_DIV_FRAC_BITS;
+	calc_rate = div64_u64(calc_rate, div);
+
+	return calc_rate;
+}
+
+static int rp1_clock_on(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->ctrl_reg,
+		       clockman_read(clockman, data->ctrl_reg) | CLK_CTRL_ENABLE);
+	/* If this is a GPCLK, turn on the output-enable */
+	if (data->oe_mask)
+		clockman_write(clockman, GPCLK_OE_CTRL,
+			       clockman_read(clockman, GPCLK_OE_CTRL) | data->oe_mask);
+	spin_unlock(&clockman->regs_lock);
+
+	return 0;
+}
+
+static void rp1_clock_off(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+
+	spin_lock(&clockman->regs_lock);
+	clockman_write(clockman, data->ctrl_reg,
+		       clockman_read(clockman, data->ctrl_reg) & ~CLK_CTRL_ENABLE);
+	/* If this is a GPCLK, turn off the output-enable */
+	if (data->oe_mask)
+		clockman_write(clockman, GPCLK_OE_CTRL,
+			       clockman_read(clockman, GPCLK_OE_CTRL) & ~data->oe_mask);
+	spin_unlock(&clockman->regs_lock);
+}
+
+static u32 rp1_clock_choose_div(unsigned long rate, unsigned long parent_rate,
+				const struct rp1_clock_data *data)
+{
+	u64 div;
+
+	/*
+	 * Due to earlier rounding, calculated parent_rate may differ from
+	 * expected value. Don't fail on a small discrepancy near unity divide.
+	 */
+	if (!rate || rate > parent_rate + (parent_rate >> CLK_DIV_FRAC_BITS))
+		return 0;
+
+	/*
+	 * Always express div in fixed-point format for fractional division;
+	 * If no fractional divider is present, the fraction part will be zero.
+	 */
+	if (data->div_frac_reg) {
+		div = (u64)parent_rate << CLK_DIV_FRAC_BITS;
+		div = DIV_ROUND_CLOSEST_ULL(div, rate);
+	} else {
+		div = DIV_ROUND_CLOSEST_ULL(parent_rate, rate);
+		div <<= CLK_DIV_FRAC_BITS;
+	}
+
+	div = clamp(div,
+		    1ull << CLK_DIV_FRAC_BITS,
+		    (u64)data->div_int_max << CLK_DIV_FRAC_BITS);
+
+	return div;
+}
+
+static u8 rp1_clock_get_parent(struct clk_hw *hw)
+{
+	struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+	u32 sel, ctrl;
+	u8 parent;
+
+	/* Sel is one-hot, so find the first bit set */
+	sel = clockman_read(clockman, data->sel_reg);
+	parent = ffs(sel) - 1;
+
+	/* sel == 0 implies the parent clock is not enabled yet. */
+	if (!sel) {
+		/* Read the clock src from the CTRL register instead */
+		ctrl = clockman_read(clockman, data->ctrl_reg);
+		parent = (ctrl & data->clk_src_mask) >> CLK_CTRL_SRC_SHIFT;
+	}
+
+	if (parent >= data->num_std_parents)
+		parent = AUX_SEL;
+
+	if (parent == AUX_SEL) {
+		/*
+		 * Clock parent is an auxiliary source, so get the parent from
+		 * the AUXSRC register field.
+		 */
+		ctrl = clockman_read(clockman, data->ctrl_reg);
+		parent = (ctrl & CLK_CTRL_AUXSRC_MASK) >> CLK_CTRL_AUXSRC_SHIFT;
+		parent += data->num_std_parents;
+	}
+
+	return parent;
+}
+
+static int rp1_clock_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+	u32 ctrl, sel;
+
+	spin_lock(&clockman->regs_lock);
+	ctrl = clockman_read(clockman, data->ctrl_reg);
+
+	if (index >= data->num_std_parents) {
+		/* This is an aux source request */
+		if (index >= data->num_std_parents + data->num_aux_parents) {
+			spin_unlock(&clockman->regs_lock);
+			return -EINVAL;
+		}
+
+		/* Select parent from aux list */
+		ctrl &= ~CLK_CTRL_AUXSRC_MASK;
+		ctrl |= FIELD_PREP(CLK_CTRL_AUXSRC_MASK, index - data->num_std_parents);
+		/* Set src to aux list */
+		ctrl &= ~data->clk_src_mask;
+		ctrl |= (AUX_SEL << CLK_CTRL_SRC_SHIFT) & data->clk_src_mask;
+	} else {
+		ctrl &= ~data->clk_src_mask;
+		ctrl |= (index << CLK_CTRL_SRC_SHIFT) & data->clk_src_mask;
+	}
+
+	clockman_write(clockman, data->ctrl_reg, ctrl);
+	spin_unlock(&clockman->regs_lock);
+
+	sel = rp1_clock_get_parent(hw);
+	WARN(sel != index, "(%s): Parent index req %u returned back %u\n",
+	     clk_hw_get_name(hw), index, sel);
+
+	return 0;
+}
+
+static int rp1_clock_set_rate_and_parent(struct clk_hw *hw,
+					 unsigned long rate,
+					 unsigned long parent_rate,
+					 u8 parent)
+{
+	struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+	struct rp1_clockman *clockman = clock->clockman;
+	const struct rp1_clock_data *data = clock->data;
+	u32 div = rp1_clock_choose_div(rate, parent_rate, data);
+
+	WARN(rate > 4000000000ll, "rate is -ve (%d)\n", (int)rate);
+
+	if (WARN(!div,
+		 "clk divider calculated as 0! (%s, rate %ld, parent rate %ld)\n",
+		 clk_hw_get_name(hw), rate, parent_rate))
+		div = 1 << CLK_DIV_FRAC_BITS;
+
+	spin_lock(&clockman->regs_lock);
+
+	clockman_write(clockman, data->div_int_reg, div >> CLK_DIV_FRAC_BITS);
+	if (data->div_frac_reg)
+		clockman_write(clockman, data->div_frac_reg, div << (32 - CLK_DIV_FRAC_BITS));
+
+	spin_unlock(&clockman->regs_lock);
+
+	if (parent != 0xff)
+		rp1_clock_set_parent(hw, parent);
+
+	return 0;
+}
+
+static int rp1_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long parent_rate)
+{
+	return rp1_clock_set_rate_and_parent(hw, rate, parent_rate, 0xff);
+}
+
+static void rp1_clock_choose_div_and_prate(struct clk_hw *hw,
+					   int parent_idx,
+					   unsigned long rate,
+					   unsigned long *prate,
+					   unsigned long *calc_rate)
+{
+	struct rp1_clk_desc *clock = container_of(hw, struct rp1_clk_desc, hw);
+	const struct rp1_clock_data *data = clock->data;
+	struct clk_hw *parent;
+	u32 div;
+	u64 tmp;
+
+	parent = clk_hw_get_parent_by_index(hw, parent_idx);
+
+	*prate = clk_hw_get_rate(parent);
+	div = rp1_clock_choose_div(rate, *prate, data);
+
+	if (!div) {
+		*calc_rate = 0;
+		return;
+	}
+
+	/* Recalculate to account for rounding errors */
+	tmp = (u64)*prate << CLK_DIV_FRAC_BITS;
+	tmp = div_u64(tmp, div);
+
+	/*
+	 * Prevent overclocks - if all parent choices result in
+	 * a downstream clock in excess of the maximum, then the
+	 * call to set the clock will fail.
+	 */
+	if (tmp > data->max_freq)
+		*calc_rate = 0;
+	else
+		*calc_rate = tmp;
+}
+
+static int rp1_clock_determine_rate(struct clk_hw *hw,
+				    struct clk_rate_request *req)
+{
+	struct clk_hw *parent, *best_parent = NULL;
+	unsigned long best_rate = 0;
+	unsigned long best_prate = 0;
+	unsigned long best_rate_diff = ULONG_MAX;
+	unsigned long prate, calc_rate;
+	size_t i;
+
+	/*
+	 * If the NO_REPARENT flag is set, try to use existing parent.
+	 */
+	if ((clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT)) {
+		i = rp1_clock_get_parent(hw);
+		parent = clk_hw_get_parent_by_index(hw, i);
+		if (parent) {
+			rp1_clock_choose_div_and_prate(hw, i, req->rate, &prate,
+						       &calc_rate);
+			if (calc_rate > 0) {
+				req->best_parent_hw = parent;
+				req->best_parent_rate = prate;
+				req->rate = calc_rate;
+				return 0;
+			}
+		}
+	}
+
+	/*
+	 * Select parent clock that results in the closest rate (lower or
+	 * higher)
+	 */
+	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
+		parent = clk_hw_get_parent_by_index(hw, i);
+		if (!parent)
+			continue;
+
+		rp1_clock_choose_div_and_prate(hw, i, req->rate, &prate,
+					       &calc_rate);
+
+		if (abs_diff(calc_rate, req->rate) < best_rate_diff) {
+			best_parent = parent;
+			best_prate = prate;
+			best_rate = calc_rate;
+			best_rate_diff = abs_diff(calc_rate, req->rate);
+
+			if (best_rate_diff == 0)
+				break;
+		}
+	}
+
+	if (best_rate == 0)
+		return -EINVAL;
+
+	req->best_parent_hw = best_parent;
+	req->best_parent_rate = best_prate;
+	req->rate = best_rate;
+
+	return 0;
+}
+
+static const struct clk_ops rp1_pll_core_ops = {
+	.is_prepared = rp1_pll_core_is_on,
+	.prepare = rp1_pll_core_on,
+	.unprepare = rp1_pll_core_off,
+	.set_rate = rp1_pll_core_set_rate,
+	.recalc_rate = rp1_pll_core_recalc_rate,
+	.round_rate = rp1_pll_core_round_rate,
+};
+
+static const struct clk_ops rp1_pll_ops = {
+	.set_rate = rp1_pll_set_rate,
+	.recalc_rate = rp1_pll_recalc_rate,
+	.round_rate = rp1_pll_round_rate,
+};
+
+static const struct clk_ops rp1_pll_ph_ops = {
+	.is_prepared = rp1_pll_ph_is_on,
+	.prepare = rp1_pll_ph_on,
+	.unprepare = rp1_pll_ph_off,
+	.recalc_rate = rp1_pll_ph_recalc_rate,
+	.round_rate = rp1_pll_ph_round_rate,
+};
+
+static const struct clk_ops rp1_pll_divider_ops = {
+	.is_prepared = rp1_pll_divider_is_on,
+	.prepare = rp1_pll_divider_on,
+	.unprepare = rp1_pll_divider_off,
+	.set_rate = rp1_pll_divider_set_rate,
+	.recalc_rate = rp1_pll_divider_recalc_rate,
+	.round_rate = rp1_pll_divider_round_rate,
+};
+
+static const struct clk_ops rp1_clk_ops = {
+	.is_prepared = rp1_clock_is_on,
+	.prepare = rp1_clock_on,
+	.unprepare = rp1_clock_off,
+	.recalc_rate = rp1_clock_recalc_rate,
+	.get_parent = rp1_clock_get_parent,
+	.set_parent = rp1_clock_set_parent,
+	.set_rate_and_parent = rp1_clock_set_rate_and_parent,
+	.set_rate = rp1_clock_set_rate,
+	.determine_rate = rp1_clock_determine_rate,
+};
+
+static struct clk_hw *rp1_register_pll(struct rp1_clockman *clockman,
+				       struct rp1_clk_desc *desc)
+{
+	int ret;
+
+	desc->clockman = clockman;
+
+	ret = devm_clk_hw_register(clockman->dev, &desc->hw);
+
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &desc->hw;
+}
+
+static struct clk_hw *rp1_register_pll_divider(struct rp1_clockman *clockman,
+					       struct rp1_clk_desc *desc)
+{
+	const struct rp1_pll_data *divider_data = desc->data;
+	int ret;
+
+	desc->div.reg = clockman->regs + divider_data->ctrl_reg;
+	desc->div.shift = PLL_SEC_DIV_SHIFT;
+	desc->div.width = PLL_SEC_DIV_WIDTH;
+	desc->div.flags = CLK_DIVIDER_ROUND_CLOSEST;
+	desc->div.lock = &clockman->regs_lock;
+	desc->div.hw.init = desc->hw.init;
+	desc->div.table = pll_sec_div_table;
+
+	desc->clockman = clockman;
+
+	ret = devm_clk_hw_register(clockman->dev, &desc->div.hw);
+
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &desc->div.hw;
+}
+
+static struct clk_hw *rp1_register_clock(struct rp1_clockman *clockman,
+					 struct rp1_clk_desc *desc)
+{
+	const struct rp1_clock_data *clock_data = desc->data;
+	int ret;
+
+	if (WARN_ON_ONCE(MAX_CLK_PARENTS <
+	       clock_data->num_std_parents + clock_data->num_aux_parents))
+		return NULL;
+
+	/* There must be a gap for the AUX selector */
+	if (WARN_ON_ONCE(clock_data->num_std_parents > AUX_SEL &&
+			 desc->hw.init->parent_data[AUX_SEL].index != -1))
+		return NULL;
+
+	desc->clockman = clockman;
+
+	ret = devm_clk_hw_register(clockman->dev, &desc->hw);
+
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &desc->hw;
+}
+
+/* Assignment helper macros for different clock types. */
+#define _REGISTER(f, ...)	{ .clk_register = f, __VA_ARGS__ }
+
+#define CLK_DATA(type, ...)	.data = &(struct type) { __VA_ARGS__ }
+
+#define REGISTER_PLL(...)	_REGISTER(&rp1_register_pll,		\
+					  __VA_ARGS__)
+
+#define REGISTER_PLL_DIV(...)	_REGISTER(&rp1_register_pll_divider,	\
+					  __VA_ARGS__)
+
+#define REGISTER_CLK(...)	_REGISTER(&rp1_register_clock,		\
+					  __VA_ARGS__)
+
+static struct rp1_clk_desc pll_sys_core_desc = REGISTER_PLL(
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(
+		"pll_sys_core",
+		(const struct clk_parent_data[]) { { .index = 0 } },
+		&rp1_pll_core_ops,
+		CLK_IS_CRITICAL
+	),
+	CLK_DATA(rp1_pll_core_data,
+		 .cs_reg = PLL_SYS_CS,
+		 .pwr_reg = PLL_SYS_PWR,
+		 .fbdiv_int_reg = PLL_SYS_FBDIV_INT,
+		 .fbdiv_frac_reg = PLL_SYS_FBDIV_FRAC,
+	)
+);
+
+static struct rp1_clk_desc pll_audio_core_desc = REGISTER_PLL(
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(
+		"pll_audio_core",
+		(const struct clk_parent_data[]) { { .index = 0 } },
+		&rp1_pll_core_ops,
+		CLK_IS_CRITICAL
+	),
+	CLK_DATA(rp1_pll_core_data,
+		 .cs_reg = PLL_AUDIO_CS,
+		 .pwr_reg = PLL_AUDIO_PWR,
+		 .fbdiv_int_reg = PLL_AUDIO_FBDIV_INT,
+		 .fbdiv_frac_reg = PLL_AUDIO_FBDIV_FRAC,
+	)
+);
+
+static struct rp1_clk_desc pll_video_core_desc = REGISTER_PLL(
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(
+		"pll_video_core",
+		(const struct clk_parent_data[]) { { .index = 0 } },
+		&rp1_pll_core_ops,
+		CLK_IS_CRITICAL
+	),
+	CLK_DATA(rp1_pll_core_data,
+		 .cs_reg = PLL_VIDEO_CS,
+		 .pwr_reg = PLL_VIDEO_PWR,
+		 .fbdiv_int_reg = PLL_VIDEO_FBDIV_INT,
+		 .fbdiv_frac_reg = PLL_VIDEO_FBDIV_FRAC,
+	)
+);
+
+static struct rp1_clk_desc pll_sys_desc = REGISTER_PLL(
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(
+		"pll_sys",
+		(const struct clk_parent_data[]) {
+			{ .hw = &pll_sys_core_desc.hw }
+		},
+		&rp1_pll_ops,
+		0
+	),
+	CLK_DATA(rp1_pll_data,
+		 .ctrl_reg = PLL_SYS_PRIM,
+		 .fc0_src = FC_NUM(0, 2),
+	)
+);
+
+static struct rp1_clk_desc pll_sys_sec_desc = REGISTER_PLL_DIV(
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(
+		"pll_sys_sec",
+		(const struct clk_parent_data[]) {
+			{ .hw = &pll_sys_core_desc.hw }
+		},
+		&rp1_pll_divider_ops,
+		0
+	),
+	CLK_DATA(rp1_pll_data,
+		 .ctrl_reg = PLL_SYS_SEC,
+		 .fc0_src = FC_NUM(2, 2),
+	)
+);
+
+static struct rp1_clk_desc clk_eth_tsu_desc = REGISTER_CLK(
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(
+		"clk_eth_tsu",
+		(const struct clk_parent_data[]) { { .index = 0 } },
+		&rp1_clk_ops,
+		0
+	),
+	CLK_DATA(rp1_clock_data,
+		 .num_std_parents = 0,
+		 .num_aux_parents = 1,
+		 .ctrl_reg = CLK_ETH_TSU_CTRL,
+		 .div_int_reg = CLK_ETH_TSU_DIV_INT,
+		 .sel_reg = CLK_ETH_TSU_SEL,
+		 .div_int_max = DIV_INT_8BIT_MAX,
+		 .max_freq = 50 * HZ_PER_MHZ,
+		 .fc0_src = FC_NUM(5, 7),
+	)
+);
+
+static const struct clk_parent_data clk_eth_parents[] = {
+	{ .hw = &pll_sys_sec_desc.div.hw },
+	{ .hw = &pll_sys_desc.hw },
+};
+
+static struct rp1_clk_desc clk_eth_desc = REGISTER_CLK(
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(
+		"clk_eth",
+		clk_eth_parents,
+		&rp1_clk_ops,
+		0
+	),
+	CLK_DATA(rp1_clock_data,
+		 .num_std_parents = 0,
+		 .num_aux_parents = 2,
+		 .ctrl_reg = CLK_ETH_CTRL,
+		 .div_int_reg = CLK_ETH_DIV_INT,
+		 .sel_reg = CLK_ETH_SEL,
+		 .div_int_max = DIV_INT_8BIT_MAX,
+		 .max_freq = 125 * HZ_PER_MHZ,
+		 .fc0_src = FC_NUM(4, 6),
+	)
+);
+
+static const struct clk_parent_data clk_sys_parents[] = {
+	{ .index = 0 },
+	{ .index = -1 },
+	{ .hw = &pll_sys_desc.hw },
+};
+
+static struct rp1_clk_desc clk_sys_desc = REGISTER_CLK(
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(
+		"clk_sys",
+		clk_sys_parents,
+		&rp1_clk_ops,
+		CLK_IS_CRITICAL
+	),
+	CLK_DATA(rp1_clock_data,
+		 .num_std_parents = 3,
+		 .num_aux_parents = 0,
+		 .ctrl_reg = CLK_SYS_CTRL,
+		 .div_int_reg = CLK_SYS_DIV_INT,
+		 .sel_reg = CLK_SYS_SEL,
+		 .div_int_max = DIV_INT_24BIT_MAX,
+		 .max_freq = 200 * HZ_PER_MHZ,
+		 .fc0_src = FC_NUM(0, 4),
+		 .clk_src_mask = 0x3,
+	)
+);
+
+static struct rp1_clk_desc pll_sys_pri_ph_desc = REGISTER_PLL(
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(
+		"pll_sys_pri_ph",
+		(const struct clk_parent_data[]) {
+			{ .hw = &pll_sys_desc.hw }
+		},
+		&rp1_pll_ph_ops,
+		0
+	),
+	CLK_DATA(rp1_pll_ph_data,
+		 .ph_reg = PLL_SYS_PRIM,
+		 .fixed_divider = 2,
+		 .phase = RP1_PLL_PHASE_0,
+		 .fc0_src = FC_NUM(1, 2),
+	)
+);
+
+static struct rp1_clk_desc *const clk_desc_array[] = {
+	[RP1_PLL_SYS_CORE] = &pll_sys_core_desc,
+	[RP1_PLL_AUDIO_CORE] = &pll_audio_core_desc,
+	[RP1_PLL_VIDEO_CORE] = &pll_video_core_desc,
+	[RP1_PLL_SYS] = &pll_sys_desc,
+	[RP1_CLK_ETH_TSU] = &clk_eth_tsu_desc,
+	[RP1_CLK_ETH] = &clk_eth_desc,
+	[RP1_CLK_SYS] = &clk_sys_desc,
+	[RP1_PLL_SYS_PRI_PH] = &pll_sys_pri_ph_desc,
+	[RP1_PLL_SYS_SEC] = &pll_sys_sec_desc,
+};
+
+static const struct regmap_range rp1_reg_ranges[] = {
+	regmap_reg_range(PLL_SYS_CS, PLL_SYS_SEC),
+	regmap_reg_range(PLL_AUDIO_CS, PLL_AUDIO_TERN),
+	regmap_reg_range(PLL_VIDEO_CS, PLL_VIDEO_SEC),
+	regmap_reg_range(GPCLK_OE_CTRL, GPCLK_OE_CTRL),
+	regmap_reg_range(CLK_SYS_CTRL, CLK_SYS_DIV_INT),
+	regmap_reg_range(CLK_SYS_SEL, CLK_SYS_SEL),
+	regmap_reg_range(CLK_SLOW_SYS_CTRL, CLK_SLOW_SYS_DIV_INT),
+	regmap_reg_range(CLK_SLOW_SYS_SEL, CLK_SLOW_SYS_SEL),
+	regmap_reg_range(CLK_DMA_CTRL, CLK_DMA_DIV_INT),
+	regmap_reg_range(CLK_DMA_SEL, CLK_DMA_SEL),
+	regmap_reg_range(CLK_UART_CTRL, CLK_UART_DIV_INT),
+	regmap_reg_range(CLK_UART_SEL, CLK_UART_SEL),
+	regmap_reg_range(CLK_ETH_CTRL, CLK_ETH_DIV_INT),
+	regmap_reg_range(CLK_ETH_SEL, CLK_ETH_SEL),
+	regmap_reg_range(CLK_PWM0_CTRL, CLK_PWM0_SEL),
+	regmap_reg_range(CLK_PWM1_CTRL, CLK_PWM1_SEL),
+	regmap_reg_range(CLK_AUDIO_IN_CTRL, CLK_AUDIO_IN_DIV_INT),
+	regmap_reg_range(CLK_AUDIO_IN_SEL, CLK_AUDIO_IN_SEL),
+	regmap_reg_range(CLK_AUDIO_OUT_CTRL, CLK_AUDIO_OUT_DIV_INT),
+	regmap_reg_range(CLK_AUDIO_OUT_SEL, CLK_AUDIO_OUT_SEL),
+	regmap_reg_range(CLK_I2S_CTRL, CLK_I2S_DIV_INT),
+	regmap_reg_range(CLK_I2S_SEL, CLK_I2S_SEL),
+	regmap_reg_range(CLK_MIPI0_CFG_CTRL, CLK_MIPI0_CFG_DIV_INT),
+	regmap_reg_range(CLK_MIPI0_CFG_SEL, CLK_MIPI0_CFG_SEL),
+	regmap_reg_range(CLK_MIPI1_CFG_CTRL, CLK_MIPI1_CFG_DIV_INT),
+	regmap_reg_range(CLK_MIPI1_CFG_SEL, CLK_MIPI1_CFG_SEL),
+	regmap_reg_range(CLK_PCIE_AUX_CTRL, CLK_PCIE_AUX_DIV_INT),
+	regmap_reg_range(CLK_PCIE_AUX_SEL, CLK_PCIE_AUX_SEL),
+	regmap_reg_range(CLK_USBH0_MICROFRAME_CTRL, CLK_USBH0_MICROFRAME_DIV_INT),
+	regmap_reg_range(CLK_USBH0_MICROFRAME_SEL, CLK_USBH0_MICROFRAME_SEL),
+	regmap_reg_range(CLK_USBH1_MICROFRAME_CTRL, CLK_USBH1_MICROFRAME_DIV_INT),
+	regmap_reg_range(CLK_USBH1_MICROFRAME_SEL, CLK_USBH1_MICROFRAME_SEL),
+	regmap_reg_range(CLK_USBH0_SUSPEND_CTRL, CLK_USBH0_SUSPEND_DIV_INT),
+	regmap_reg_range(CLK_USBH0_SUSPEND_SEL, CLK_USBH0_SUSPEND_SEL),
+	regmap_reg_range(CLK_USBH1_SUSPEND_CTRL, CLK_USBH1_SUSPEND_DIV_INT),
+	regmap_reg_range(CLK_USBH1_SUSPEND_SEL, CLK_USBH1_SUSPEND_SEL),
+	regmap_reg_range(CLK_ETH_TSU_CTRL, CLK_ETH_TSU_DIV_INT),
+	regmap_reg_range(CLK_ETH_TSU_SEL, CLK_ETH_TSU_SEL),
+	regmap_reg_range(CLK_ADC_CTRL, CLK_ADC_DIV_INT),
+	regmap_reg_range(CLK_ADC_SEL, CLK_ADC_SEL),
+	regmap_reg_range(CLK_SDIO_TIMER_CTRL, CLK_SDIO_TIMER_DIV_INT),
+	regmap_reg_range(CLK_SDIO_TIMER_SEL, CLK_SDIO_TIMER_SEL),
+	regmap_reg_range(CLK_SDIO_ALT_SRC_CTRL, CLK_SDIO_ALT_SRC_DIV_INT),
+	regmap_reg_range(CLK_SDIO_ALT_SRC_SEL, CLK_SDIO_ALT_SRC_SEL),
+	regmap_reg_range(CLK_GP0_CTRL, CLK_GP0_SEL),
+	regmap_reg_range(CLK_GP1_CTRL, CLK_GP1_SEL),
+	regmap_reg_range(CLK_GP2_CTRL, CLK_GP2_SEL),
+	regmap_reg_range(CLK_GP3_CTRL, CLK_GP3_SEL),
+	regmap_reg_range(CLK_GP4_CTRL, CLK_GP4_SEL),
+	regmap_reg_range(CLK_GP5_CTRL, CLK_GP5_SEL),
+	regmap_reg_range(CLK_SYS_RESUS_CTRL, CLK_SYS_RESUS_CTRL),
+	regmap_reg_range(CLK_SLOW_SYS_RESUS_CTRL, CLK_SLOW_SYS_RESUS_CTRL),
+	regmap_reg_range(FC0_REF_KHZ, FC0_RESULT),
+	regmap_reg_range(VIDEO_CLK_VEC_CTRL, VIDEO_CLK_VEC_DIV_INT),
+	regmap_reg_range(VIDEO_CLK_VEC_SEL, VIDEO_CLK_DPI_DIV_INT),
+	regmap_reg_range(VIDEO_CLK_DPI_SEL, VIDEO_CLK_MIPI1_DPI_SEL),
+};
+
+static const struct regmap_access_table rp1_reg_table = {
+	.yes_ranges = rp1_reg_ranges,
+	.n_yes_ranges = ARRAY_SIZE(rp1_reg_ranges),
+};
+
+static const struct regmap_config rp1_clk_regmap_cfg = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = PLL_VIDEO_SEC,
+	.name = "rp1-clk",
+	.rd_table = &rp1_reg_table,
+};
+
+static int rp1_clk_probe(struct platform_device *pdev)
+{
+	const size_t asize = ARRAY_SIZE(clk_desc_array);
+	struct rp1_clk_desc *desc;
+	struct device *dev = &pdev->dev;
+	struct rp1_clockman *clockman;
+	struct clk_hw **hws;
+	unsigned int i;
+
+	clockman = devm_kzalloc(dev, struct_size(clockman, onecell.hws, asize),
+				GFP_KERNEL);
+	if (!clockman)
+		return -ENOMEM;
+
+	spin_lock_init(&clockman->regs_lock);
+	clockman->dev = dev;
+
+	clockman->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(clockman->regs))
+		return PTR_ERR(clockman->regs);
+
+	clockman->regmap = devm_regmap_init_mmio(dev, clockman->regs,
+						 &rp1_clk_regmap_cfg);
+	if (IS_ERR(clockman->regmap)) {
+		dev_err_probe(dev, PTR_ERR(clockman->regmap),
+			      "could not init clock regmap\n");
+		return PTR_ERR(clockman->regmap);
+	}
+
+	clockman->onecell.num = asize;
+	hws = clockman->onecell.hws;
+
+	for (i = 0; i < asize; i++) {
+		desc = clk_desc_array[i];
+		if (desc && desc->clk_register && desc->data) {
+			hws[i] = desc->clk_register(clockman, desc);
+			if (IS_ERR_OR_NULL(hws[i]))
+				dev_err_probe(dev, PTR_ERR(hws[i]),
+					      "Unable to register clock: %s\n",
+					      clk_hw_get_name(hws[i]));
+		}
+	}
+
+	platform_set_drvdata(pdev, clockman);
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &clockman->onecell);
+}
+
+static const struct of_device_id rp1_clk_of_match[] = {
+	{ .compatible = "raspberrypi,rp1-clocks" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, rp1_clk_of_match);
+
+static struct platform_driver rp1_clk_driver = {
+	.driver = {
+		.name = "rp1-clk",
+		.of_match_table = rp1_clk_of_match,
+	},
+	.probe = rp1_clk_probe,
+};
+
+module_platform_driver(rp1_clk_driver);
+
+MODULE_AUTHOR("Naushir Patuck <naush at raspberrypi.com>");
+MODULE_AUTHOR("Andrea della Porta <andrea.porta at suse.com>");
+MODULE_DESCRIPTION("RP1 clock driver");
+MODULE_LICENSE("GPL");
-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:31 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:31 +0100
Subject: [PATCH v5 07/10] arm64: dts: rp1: Add support for RaspberryPi's RP1 device
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <dab4c549cc243e80022c64ca522729f3408a7077.1733136811.git.andrea.porta@suse.com>

RaspberryPi RP1 is a multi function PCI endpoint device that
exposes several subperipherals via PCI BAR.
Add a dtb overlay that will be compiled into a binary blob
and linked in the RP1 driver.
This overlay offers just minimal support to represent the
RP1 device itself, the sub-peripherals will be added by
future patches.

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
NOTE: this patch should be taken by the same maintainer that will take
"[PATCH v4 08/10] misc: rp1: RaspberryPi RP1 misc driver", since they
are closely related in terms of compiling.

 MAINTAINERS                           |  1 +
 arch/arm64/boot/dts/broadcom/rp1.dtso | 58 +++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 arch/arm64/boot/dts/broadcom/rp1.dtso

diff --git a/MAINTAINERS b/MAINTAINERS
index 9b8e87b8d6de..fbdd8594aa7e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19577,6 +19577,7 @@ F:	drivers/media/platform/raspberrypi/rp1-cfe/
 RASPBERRY PI RP1 PCI DRIVER
 M:	Andrea della Porta <andrea.porta at suse.com>
 S:	Maintained
+F:	arch/arm64/boot/dts/broadcom/rp1.dtso
 F:	Documentation/devicetree/bindings/clock/raspberrypi,rp1-clocks.yaml
 F:	Documentation/devicetree/bindings/misc/pci1de4,1.yaml
 F:	Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
diff --git a/arch/arm64/boot/dts/broadcom/rp1.dtso b/arch/arm64/boot/dts/broadcom/rp1.dtso
new file mode 100644
index 000000000000..cdff061e2750
--- /dev/null
+++ b/arch/arm64/boot/dts/broadcom/rp1.dtso
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/raspberrypi,rp1-clocks.h>
+
+/dts-v1/;
+/plugin/;
+
+/ {
+	fragment at 0 {
+		target-path="";
+		__overlay__ {
+			compatible = "pci1de4,1";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			pci_ep_bus: pci-ep-bus at 1 {
+				compatible = "simple-bus";
+				ranges = <0x00 0x40000000  0x01 0x00 0x00000000  0x00 0x00400000>;
+				dma-ranges = <0x10 0x00000000  0x43000000 0x10 0x00000000  0x10 0x00000000>;
+				#address-cells = <2>;
+				#size-cells = <2>;
+
+				rp1_clocks: clocks at 40018000 {
+					compatible = "raspberrypi,rp1-clocks";
+					reg = <0x00 0x40018000 0x0 0x10038>;
+					#clock-cells = <1>;
+					clocks = <&clk_rp1_xosc>;
+					assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
+							  <&rp1_clocks RP1_PLL_SYS>,
+							  <&rp1_clocks RP1_PLL_SYS_SEC>,
+							  <&rp1_clocks RP1_CLK_SYS>;
+					assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
+							       <200000000>,  // RP1_PLL_SYS
+							       <125000000>,  // RP1_PLL_SYS_SEC
+							       <200000000>;  // RP1_CLK_SYS
+				};
+
+				rp1_gpio: pinctrl at 400d0000 {
+					compatible = "raspberrypi,rp1-gpio";
+					reg = <0x00 0x400d0000  0x0 0xc000>,
+					      <0x00 0x400e0000  0x0 0xc000>,
+					      <0x00 0x400f0000  0x0 0xc000>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+					interrupts = <0 IRQ_TYPE_LEVEL_HIGH>,
+						     <1 IRQ_TYPE_LEVEL_HIGH>,
+						     <2 IRQ_TYPE_LEVEL_HIGH>;
+				};
+			};
+		};
+	};
+};
-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:30 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:30 +0100
Subject: [PATCH v5 06/10] pinctrl: rp1: Implement RaspberryPi RP1 gpio support
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <382d56db9ab749a99f142fc65eeacdbd6c44be93.1733136811.git.andrea.porta@suse.com>

The RP1 is an MFD supporting a gpio controller and /pinmux/pinctrl.
Add minimum support for the gpio only portion. The driver is in
pinctrl folder since upcoming patches will add the pinmux/pinctrl
support where the gpio part can be seen as an addition.

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Stefan Wahren <wahrenst at gmx.net>
---
 MAINTAINERS                   |   1 +
 drivers/pinctrl/Kconfig       |  11 +
 drivers/pinctrl/Makefile      |   1 +
 drivers/pinctrl/pinctrl-rp1.c | 789 ++++++++++++++++++++++++++++++++++
 4 files changed, 802 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-rp1.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ad37eb45a51..9b8e87b8d6de 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19582,6 +19582,7 @@ F:	Documentation/devicetree/bindings/misc/pci1de4,1.yaml
 F:	Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
 F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 F:	drivers/clk/clk-rp1.c
+F:	drivers/pinctrl/pinctrl-rp1.c
 F:	include/dt-bindings/clock/rp1.h
 F:	include/dt-bindings/misc/rp1.h
 
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 95a8e2b9a614..53b265cabc26 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -612,6 +612,17 @@ config PINCTRL_MLXBF3
 	  each pin. This driver can also be built as a module called
 	  pinctrl-mlxbf3.
 
+config PINCTRL_RP1
+	tristate "Pinctrl driver for RP1"
+	depends on MISC_RP1
+	default MISC_RP1
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	help
+	  Enable the gpio and pinctrl/mux driver for RaspberryPi RP1
+	  multi function device.
+
 source "drivers/pinctrl/actions/Kconfig"
 source "drivers/pinctrl/aspeed/Kconfig"
 source "drivers/pinctrl/bcm/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index fba1c56624c0..6fb77de58545 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -48,6 +48,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_RP1)       += pinctrl-rp1.o
 obj-$(CONFIG_PINCTRL_SCMI)	+= pinctrl-scmi.o
 obj-$(CONFIG_PINCTRL_SINGLE)	+= pinctrl-single.o
 obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c
new file mode 100644
index 000000000000..0d081f75d2ec
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-rp1.c
@@ -0,0 +1,789 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Raspberry Pi RP1 GPIO unit
+ *
+ * Copyright (C) 2023 Raspberry Pi Ltd.
+ *
+ * This driver is inspired by:
+ * pinctrl-bcm2835.c, please see original file for copyright information
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define MODULE_NAME "pinctrl-rp1"
+#define RP1_NUM_GPIOS	54
+#define RP1_NUM_BANKS	3
+
+#define RP1_INT_EDGE_FALLING		BIT(0)
+#define RP1_INT_EDGE_RISING		BIT(1)
+#define RP1_INT_LEVEL_LOW		BIT(2)
+#define RP1_INT_LEVEL_HIGH		BIT(3)
+#define RP1_INT_MASK			GENMASK(3, 0)
+#define RP1_INT_EDGE_BOTH		(RP1_INT_EDGE_FALLING |	\
+					 RP1_INT_EDGE_RISING)
+
+#define RP1_FSEL_COUNT			9
+
+#define RP1_FSEL_ALT0			0x00
+#define RP1_FSEL_GPIO			0x05
+#define RP1_FSEL_NONE			0x09
+#define RP1_FSEL_NONE_HW		0x1f
+
+#define RP1_PAD_DRIVE_2MA		0x0
+#define RP1_PAD_DRIVE_4MA		0x1
+#define RP1_PAD_DRIVE_8MA		0x2
+#define RP1_PAD_DRIVE_12MA		0x3
+
+enum {
+	RP1_PUD_OFF			= 0,
+	RP1_PUD_DOWN			= 1,
+	RP1_PUD_UP			= 2,
+};
+
+enum {
+	RP1_DIR_OUTPUT			= 0,
+	RP1_DIR_INPUT			= 1,
+};
+
+enum {
+	RP1_OUTOVER_PERI		= 0,
+	RP1_OUTOVER_INVPERI		= 1,
+	RP1_OUTOVER_LOW			= 2,
+	RP1_OUTOVER_HIGH		= 3,
+};
+
+enum {
+	RP1_OEOVER_PERI			= 0,
+	RP1_OEOVER_INVPERI		= 1,
+	RP1_OEOVER_DISABLE		= 2,
+	RP1_OEOVER_ENABLE		= 3,
+};
+
+enum {
+	RP1_INOVER_PERI			= 0,
+	RP1_INOVER_INVPERI		= 1,
+	RP1_INOVER_LOW			= 2,
+	RP1_INOVER_HIGH			= 3,
+};
+
+enum {
+	RP1_GPIO_CTRL_IRQRESET_SET		= 0,
+	RP1_GPIO_CTRL_INT_CLR			= 1,
+	RP1_GPIO_CTRL_INT_SET			= 2,
+	RP1_GPIO_CTRL_OEOVER			= 3,
+	RP1_GPIO_CTRL_FUNCSEL			= 4,
+	RP1_GPIO_CTRL_OUTOVER			= 5,
+	RP1_GPIO_CTRL				= 6,
+};
+
+enum {
+	RP1_INTE_SET			= 0,
+	RP1_INTE_CLR			= 1,
+};
+
+enum {
+	RP1_RIO_OUT_SET			= 0,
+	RP1_RIO_OUT_CLR			= 1,
+	RP1_RIO_OE			= 2,
+	RP1_RIO_OE_SET			= 3,
+	RP1_RIO_OE_CLR			= 4,
+	RP1_RIO_IN			= 5,
+};
+
+enum {
+	RP1_PAD_SLEWFAST		= 0,
+	RP1_PAD_SCHMITT			= 1,
+	RP1_PAD_PULL			= 2,
+	RP1_PAD_DRIVE			= 3,
+	RP1_PAD_IN_ENABLE		= 4,
+	RP1_PAD_OUT_DISABLE		= 5,
+};
+
+static const struct reg_field rp1_gpio_fields[] = {
+	[RP1_GPIO_CTRL_IRQRESET_SET]	= REG_FIELD(0x2004, 28, 28),
+	[RP1_GPIO_CTRL_INT_CLR]		= REG_FIELD(0x3004, 20, 23),
+	[RP1_GPIO_CTRL_INT_SET]		= REG_FIELD(0x2004, 20, 23),
+	[RP1_GPIO_CTRL_OEOVER]		= REG_FIELD(0x0004, 14, 15),
+	[RP1_GPIO_CTRL_FUNCSEL]		= REG_FIELD(0x0004, 0, 4),
+	[RP1_GPIO_CTRL_OUTOVER]		= REG_FIELD(0x0004, 12, 13),
+	[RP1_GPIO_CTRL]			= REG_FIELD(0x0004, 0, 31),
+};
+
+static const struct reg_field rp1_inte_fields[] = {
+	[RP1_INTE_SET]			= REG_FIELD(0x2000, 0, 0),
+	[RP1_INTE_CLR]			= REG_FIELD(0x3000, 0, 0),
+};
+
+static const struct reg_field rp1_rio_fields[] = {
+	[RP1_RIO_OUT_SET]		= REG_FIELD(0x2000, 0, 0),
+	[RP1_RIO_OUT_CLR]		= REG_FIELD(0x3000, 0, 0),
+	[RP1_RIO_OE]			= REG_FIELD(0x0004, 0, 0),
+	[RP1_RIO_OE_SET]		= REG_FIELD(0x2004, 0, 0),
+	[RP1_RIO_OE_CLR]		= REG_FIELD(0x3004, 0, 0),
+	[RP1_RIO_IN]			= REG_FIELD(0x0008, 0, 0),
+};
+
+static const struct reg_field rp1_pad_fields[] = {
+	[RP1_PAD_SLEWFAST]		= REG_FIELD(0, 0, 0),
+	[RP1_PAD_SCHMITT]		= REG_FIELD(0, 1, 1),
+	[RP1_PAD_PULL]			= REG_FIELD(0, 2, 3),
+	[RP1_PAD_DRIVE]			= REG_FIELD(0, 4, 5),
+	[RP1_PAD_IN_ENABLE]		= REG_FIELD(0, 6, 6),
+	[RP1_PAD_OUT_DISABLE]		= REG_FIELD(0, 7, 7),
+};
+
+struct rp1_iobank_desc {
+	int min_gpio;
+	int num_gpios;
+	int gpio_offset;
+	int inte_offset;
+	int ints_offset;
+	int rio_offset;
+	int pads_offset;
+};
+
+struct rp1_pin_info {
+	u8 num;
+	u8 bank;
+	u8 offset;
+	u8 fsel;
+	u8 irq_type;
+
+	struct regmap_field *gpio[ARRAY_SIZE(rp1_gpio_fields)];
+	struct regmap_field *rio[ARRAY_SIZE(rp1_rio_fields)];
+	struct regmap_field *inte[ARRAY_SIZE(rp1_inte_fields)];
+	struct regmap_field *pad[ARRAY_SIZE(rp1_pad_fields)];
+};
+
+struct rp1_pinctrl {
+	struct device *dev;
+	void __iomem *gpio_base;
+	void __iomem *rio_base;
+	void __iomem *pads_base;
+	int irq[RP1_NUM_BANKS];
+	struct rp1_pin_info pins[RP1_NUM_GPIOS];
+
+	struct pinctrl_dev *pctl_dev;
+	struct gpio_chip gpio_chip;
+	struct pinctrl_gpio_range gpio_range;
+
+	raw_spinlock_t irq_lock[RP1_NUM_BANKS];
+};
+
+static const struct rp1_iobank_desc rp1_iobanks[RP1_NUM_BANKS] = {
+	/*         gpio   inte    ints     rio    pads */
+	{  0, 28, 0x0000, 0x011c, 0x0124, 0x0000, 0x0004 },
+	{ 28,  6, 0x4000, 0x411c, 0x4124, 0x4000, 0x4004 },
+	{ 34, 20, 0x8000, 0x811c, 0x8124, 0x8000, 0x8004 },
+};
+
+static int rp1_pinconf_set(struct rp1_pin_info *pin,
+			   unsigned int offset, unsigned long *configs,
+			   unsigned int num_configs);
+
+static struct rp1_pin_info *rp1_get_pin(struct gpio_chip *chip,
+					unsigned int offset)
+{
+	struct rp1_pinctrl *pc = gpiochip_get_data(chip);
+
+	if (pc && offset < RP1_NUM_GPIOS)
+		return &pc->pins[offset];
+	return NULL;
+}
+
+static void rp1_input_enable(struct rp1_pin_info *pin, int value)
+{
+	regmap_field_write(pin->pad[RP1_PAD_IN_ENABLE], !!value);
+}
+
+static void rp1_output_enable(struct rp1_pin_info *pin, int value)
+{
+	regmap_field_write(pin->pad[RP1_PAD_OUT_DISABLE], !value);
+}
+
+static u32 rp1_get_fsel(struct rp1_pin_info *pin)
+{
+	u32 oeover, fsel;
+
+	regmap_field_read(pin->gpio[RP1_GPIO_CTRL_OEOVER], &oeover);
+	regmap_field_read(pin->gpio[RP1_GPIO_CTRL_FUNCSEL], &fsel);
+
+	if (oeover != RP1_OEOVER_PERI || fsel >= RP1_FSEL_COUNT)
+		fsel = RP1_FSEL_NONE;
+
+	return fsel;
+}
+
+static void rp1_set_fsel(struct rp1_pin_info *pin, u32 fsel)
+{
+	if (fsel >= RP1_FSEL_COUNT)
+		fsel = RP1_FSEL_NONE_HW;
+
+	rp1_input_enable(pin, 1);
+	rp1_output_enable(pin, 1);
+
+	if (fsel == RP1_FSEL_NONE) {
+		regmap_field_write(pin->gpio[RP1_GPIO_CTRL_OEOVER], RP1_OEOVER_DISABLE);
+	} else {
+		regmap_field_write(pin->gpio[RP1_GPIO_CTRL_OUTOVER], RP1_OUTOVER_PERI);
+		regmap_field_write(pin->gpio[RP1_GPIO_CTRL_OEOVER], RP1_OEOVER_PERI);
+	}
+
+	regmap_field_write(pin->gpio[RP1_GPIO_CTRL_FUNCSEL], fsel);
+}
+
+static int rp1_get_dir(struct rp1_pin_info *pin)
+{
+	unsigned int val;
+
+	regmap_field_read(pin->rio[RP1_RIO_OE], &val);
+
+	return !val ? RP1_DIR_INPUT : RP1_DIR_OUTPUT;
+}
+
+static void rp1_set_dir(struct rp1_pin_info *pin, bool is_input)
+{
+	int reg = is_input ? RP1_RIO_OE_CLR : RP1_RIO_OE_SET;
+
+	regmap_field_write(pin->rio[reg], 1);
+}
+
+static int rp1_get_value(struct rp1_pin_info *pin)
+{
+	unsigned int val;
+
+	regmap_field_read(pin->rio[RP1_RIO_IN], &val);
+
+	return !!val;
+}
+
+static void rp1_set_value(struct rp1_pin_info *pin, int value)
+{
+	/* Assume the pin is already an output */
+	int reg = value ? RP1_RIO_OUT_SET : RP1_RIO_OUT_CLR;
+
+	regmap_field_write(pin->rio[reg], 1);
+}
+
+static int rp1_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+	int ret;
+
+	if (!pin)
+		return -EINVAL;
+
+	ret = rp1_get_value(pin);
+
+	return ret;
+}
+
+static void rp1_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+
+	if (pin)
+		rp1_set_value(pin, value);
+}
+
+static int rp1_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+	u32 fsel;
+
+	if (!pin)
+		return -EINVAL;
+
+	fsel = rp1_get_fsel(pin);
+	if (fsel != RP1_FSEL_GPIO)
+		return -EINVAL;
+
+	return (rp1_get_dir(pin) == RP1_DIR_OUTPUT) ?
+		GPIO_LINE_DIRECTION_OUT :
+		GPIO_LINE_DIRECTION_IN;
+}
+
+static int rp1_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+
+	if (!pin)
+		return -EINVAL;
+	rp1_set_dir(pin, RP1_DIR_INPUT);
+	rp1_set_fsel(pin, RP1_FSEL_GPIO);
+
+	return 0;
+}
+
+static int rp1_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
+				     int value)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+
+	if (!pin)
+		return -EINVAL;
+	rp1_set_value(pin, value);
+	rp1_set_dir(pin, RP1_DIR_OUTPUT);
+	rp1_set_fsel(pin, RP1_FSEL_GPIO);
+
+	return 0;
+}
+
+static int rp1_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+			       unsigned long config)
+{
+	struct rp1_pin_info *pin = rp1_get_pin(chip, offset);
+	unsigned long configs[] = { config };
+
+	return rp1_pinconf_set(pin, offset, configs,
+			       ARRAY_SIZE(configs));
+}
+
+static const struct gpio_chip rp1_gpio_chip = {
+	.label = MODULE_NAME,
+	.owner = THIS_MODULE,
+	.request = gpiochip_generic_request,
+	.free = gpiochip_generic_free,
+	.direction_input = rp1_gpio_direction_input,
+	.direction_output = rp1_gpio_direction_output,
+	.get_direction = rp1_gpio_get_direction,
+	.get = rp1_gpio_get,
+	.set = rp1_gpio_set,
+	.base = -1,
+	.set_config = rp1_gpio_set_config,
+	.ngpio = RP1_NUM_GPIOS,
+	.can_sleep = false,
+};
+
+static void rp1_gpio_irq_handler(struct irq_desc *desc)
+{
+	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+	struct irq_chip *host_chip = irq_desc_get_chip(desc);
+	struct rp1_pinctrl *pc = gpiochip_get_data(chip);
+	const struct rp1_iobank_desc *bank;
+	int irq = irq_desc_get_irq(desc);
+	unsigned long ints;
+	int bit_pos;
+
+	if (pc->irq[0] == irq)
+		bank = &rp1_iobanks[0];
+	else if (pc->irq[1] == irq)
+		bank = &rp1_iobanks[1];
+	else
+		bank = &rp1_iobanks[2];
+
+	chained_irq_enter(host_chip, desc);
+
+	ints = readl(pc->gpio_base + bank->ints_offset);
+	for_each_set_bit(bit_pos, &ints, 32) {
+		struct rp1_pin_info *pin = rp1_get_pin(chip, bit_pos);
+
+		regmap_field_write(pin->gpio[RP1_GPIO_CTRL_IRQRESET_SET], 1);
+		generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irq.domain,
+						     bank->gpio_offset + bit_pos));
+	}
+
+	chained_irq_exit(host_chip, desc);
+}
+
+static void rp1_gpio_irq_config(struct rp1_pin_info *pin, bool enable)
+{
+	int reg = enable ? RP1_INTE_SET : RP1_INTE_CLR;
+
+	regmap_field_write(pin->inte[reg], 1);
+	if (!enable)
+		/* Clear any latched events */
+		regmap_field_write(pin->gpio[RP1_GPIO_CTRL_IRQRESET_SET], 1);
+}
+
+static void rp1_gpio_irq_enable(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	unsigned int gpio = irqd_to_hwirq(data);
+	struct rp1_pin_info *pin = rp1_get_pin(chip, gpio);
+
+	rp1_gpio_irq_config(pin, true);
+}
+
+static void rp1_gpio_irq_disable(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	unsigned int gpio = irqd_to_hwirq(data);
+	struct rp1_pin_info *pin = rp1_get_pin(chip, gpio);
+
+	rp1_gpio_irq_config(pin, false);
+}
+
+static int rp1_irq_set_type(struct rp1_pin_info *pin, unsigned int type)
+{
+	u32 irq_flags;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		irq_flags = 0;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		irq_flags = RP1_INT_EDGE_RISING;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		irq_flags = RP1_INT_EDGE_FALLING;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		irq_flags = RP1_INT_EDGE_RISING | RP1_INT_EDGE_FALLING;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		irq_flags = RP1_INT_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		irq_flags = RP1_INT_LEVEL_LOW;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* Clear them all */
+	regmap_field_write(pin->gpio[RP1_GPIO_CTRL_INT_CLR], RP1_INT_MASK);
+
+	/* Set those that are needed */
+	regmap_field_write(pin->gpio[RP1_GPIO_CTRL_INT_SET], irq_flags);
+	pin->irq_type = type;
+
+	return 0;
+}
+
+static int rp1_gpio_irq_set_type(struct irq_data *data, unsigned int type)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	unsigned int gpio = irqd_to_hwirq(data);
+	struct rp1_pin_info *pin = rp1_get_pin(chip, gpio);
+	struct rp1_pinctrl *pc = gpiochip_get_data(chip);
+	int bank = pin->bank;
+	unsigned long flags;
+	int ret;
+
+	raw_spin_lock_irqsave(&pc->irq_lock[bank], flags);
+
+	ret = rp1_irq_set_type(pin, type);
+	if (!ret) {
+		if (type & IRQ_TYPE_EDGE_BOTH)
+			irq_set_handler_locked(data, handle_edge_irq);
+		else
+			irq_set_handler_locked(data, handle_level_irq);
+	}
+
+	raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags);
+
+	return ret;
+}
+
+static void rp1_gpio_irq_ack(struct irq_data *data)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	unsigned int gpio = irqd_to_hwirq(data);
+	struct rp1_pin_info *pin = rp1_get_pin(chip, gpio);
+
+	/* Clear any latched events */
+	regmap_field_write(pin->gpio[RP1_GPIO_CTRL_IRQRESET_SET], 1);
+}
+
+static struct irq_chip rp1_gpio_irq_chip = {
+	.name = MODULE_NAME,
+	.irq_enable = rp1_gpio_irq_enable,
+	.irq_disable = rp1_gpio_irq_disable,
+	.irq_set_type = rp1_gpio_irq_set_type,
+	.irq_ack = rp1_gpio_irq_ack,
+	.irq_mask = rp1_gpio_irq_disable,
+	.irq_unmask = rp1_gpio_irq_enable,
+	.flags = IRQCHIP_IMMUTABLE,
+};
+
+static void rp1_pull_config_set(struct rp1_pin_info *pin, unsigned int arg)
+{
+	regmap_field_write(pin->pad[RP1_PAD_PULL], arg & 0x3);
+}
+
+static int rp1_pinconf_set(struct rp1_pin_info *pin, unsigned int offset,
+			   unsigned long *configs, unsigned int num_configs)
+{
+	u32 param, arg;
+	int i;
+
+	if (!pin)
+		return -EINVAL;
+
+	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:
+			rp1_pull_config_set(pin, RP1_PUD_OFF);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			rp1_pull_config_set(pin, RP1_PUD_DOWN);
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_UP:
+			rp1_pull_config_set(pin, RP1_PUD_UP);
+			break;
+
+		case PIN_CONFIG_INPUT_ENABLE:
+			rp1_input_enable(pin, arg);
+			break;
+
+		case PIN_CONFIG_OUTPUT_ENABLE:
+			rp1_output_enable(pin, arg);
+			break;
+
+		case PIN_CONFIG_OUTPUT:
+			rp1_set_value(pin, arg);
+			rp1_set_dir(pin, RP1_DIR_OUTPUT);
+			rp1_set_fsel(pin, RP1_FSEL_GPIO);
+			break;
+
+		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+			regmap_field_write(pin->pad[RP1_PAD_SCHMITT], !!arg);
+			break;
+
+		case PIN_CONFIG_SLEW_RATE:
+			regmap_field_write(pin->pad[RP1_PAD_SLEWFAST], !!arg);
+			break;
+
+		case PIN_CONFIG_DRIVE_STRENGTH:
+			switch (arg) {
+			case 2:
+				arg = RP1_PAD_DRIVE_2MA;
+				break;
+			case 4:
+				arg = RP1_PAD_DRIVE_4MA;
+				break;
+			case 8:
+				arg = RP1_PAD_DRIVE_8MA;
+				break;
+			case 12:
+				arg = RP1_PAD_DRIVE_12MA;
+				break;
+			default:
+				return -ENOTSUPP;
+			}
+			regmap_field_write(pin->pad[RP1_PAD_DRIVE], arg);
+			break;
+
+		default:
+			return -ENOTSUPP;
+
+		} /* switch param type */
+	} /* for each config */
+
+	return 0;
+}
+
+static const struct of_device_id rp1_pinctrl_match[] = {
+	{ .compatible = "raspberrypi,rp1-gpio" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rp1_pinctrl_match);
+
+static struct rp1_pinctrl rp1_pinctrl_data = {};
+
+static const struct regmap_config rp1_pinctrl_regmap_cfg = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.fast_io = true,
+	.name = "rp1-pinctrl",
+};
+
+static int rp1_gen_regfield(struct device *dev,
+			    const struct reg_field *array,
+			    size_t array_size,
+			    int reg_off,
+			    int pin_off,
+			    bool additive_offset,
+			    struct regmap *regmap,
+			    struct regmap_field *out[])
+{
+	struct reg_field regfield;
+	int k;
+
+	for (k = 0; k < array_size; k++) {
+		regfield = array[k];
+		regfield.reg = (additive_offset ? regfield.reg : 0) + reg_off;
+		if (pin_off >= 0) {
+			regfield.lsb = pin_off;
+			regfield.msb = regfield.lsb;
+		}
+		out[k] = devm_regmap_field_alloc(dev, regmap, regfield);
+
+		if (IS_ERR(out[k]))
+			return PTR_ERR(out[k]);
+	}
+
+	return 0;
+}
+
+static int rp1_pinctrl_probe(struct platform_device *pdev)
+{
+	struct regmap *gpio_regmap, *rio_regmap, *pads_regmap;
+	struct rp1_pinctrl *pc = &rp1_pinctrl_data;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct gpio_irq_chip *girq;
+	int err, i;
+
+	pc->dev = dev;
+	pc->gpio_chip = rp1_gpio_chip;
+	pc->gpio_chip.parent = dev;
+
+	pc->gpio_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(pc->gpio_base))
+		return dev_err_probe(dev, PTR_ERR(pc->gpio_base), "could not get GPIO IO memory\n");
+
+	pc->rio_base = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(pc->rio_base))
+		return dev_err_probe(dev, PTR_ERR(pc->rio_base), "could not get RIO IO memory\n");
+
+	pc->pads_base = devm_platform_ioremap_resource(pdev, 2);
+	if (IS_ERR(pc->pads_base))
+		return dev_err_probe(dev, PTR_ERR(pc->pads_base), "could not get PADS IO memory\n");
+
+	gpio_regmap = devm_regmap_init_mmio(dev, pc->gpio_base,
+					    &rp1_pinctrl_regmap_cfg);
+	if (IS_ERR(gpio_regmap))
+		return dev_err_probe(dev, PTR_ERR(gpio_regmap), "could not init GPIO regmap\n");
+
+	rio_regmap = devm_regmap_init_mmio(dev, pc->rio_base,
+					   &rp1_pinctrl_regmap_cfg);
+	if (IS_ERR(rio_regmap))
+		return dev_err_probe(dev, PTR_ERR(rio_regmap), "could not init RIO regmap\n");
+
+	pads_regmap = devm_regmap_init_mmio(dev, pc->pads_base,
+					    &rp1_pinctrl_regmap_cfg);
+	if (IS_ERR(pads_regmap))
+		return dev_err_probe(dev, PTR_ERR(pads_regmap), "could not init PADS regmap\n");
+
+	for (i = 0; i < RP1_NUM_BANKS; i++) {
+		const struct rp1_iobank_desc *bank = &rp1_iobanks[i];
+		int j;
+
+		for (j = 0; j < bank->num_gpios; j++) {
+			struct rp1_pin_info *pin =
+				&pc->pins[bank->min_gpio + j];
+			int reg_off;
+
+			pin->num = bank->min_gpio + j;
+			pin->bank = i;
+			pin->offset = j;
+
+			reg_off = bank->gpio_offset + pin->offset *
+				  sizeof(u32) * 2;
+			err = rp1_gen_regfield(dev,
+					       rp1_gpio_fields,
+					       ARRAY_SIZE(rp1_gpio_fields),
+					       reg_off,
+					       -1,
+					       true,
+					       gpio_regmap,
+					       pin->gpio);
+
+			if (err)
+				return dev_err_probe(dev, err,
+						     "Unable to allocate regmap for gpio\n");
+
+			reg_off = bank->inte_offset;
+			err = rp1_gen_regfield(dev,
+					       rp1_inte_fields,
+					       ARRAY_SIZE(rp1_inte_fields),
+					       reg_off,
+					       pin->offset,
+					       true,
+					       gpio_regmap,
+					       pin->inte);
+
+			if (err)
+				return dev_err_probe(dev, err,
+						     "Unable to allocate regmap for inte\n");
+
+			reg_off = bank->rio_offset;
+			err = rp1_gen_regfield(dev,
+					       rp1_rio_fields,
+					       ARRAY_SIZE(rp1_rio_fields),
+					       reg_off,
+					       pin->offset,
+					       true,
+					       rio_regmap,
+					       pin->rio);
+
+			if (err)
+				return dev_err_probe(dev, err,
+						     "Unable to allocate regmap for rio\n");
+
+			reg_off = bank->pads_offset + pin->offset * sizeof(u32);
+			err = rp1_gen_regfield(dev,
+					       rp1_pad_fields,
+					       ARRAY_SIZE(rp1_pad_fields),
+					       reg_off,
+					       -1,
+					       false,
+					       pads_regmap,
+					       pin->pad);
+
+			if (err)
+				return dev_err_probe(dev, err,
+						     "Unable to allocate regmap for pad\n");
+		}
+
+		raw_spin_lock_init(&pc->irq_lock[i]);
+	}
+
+	girq = &pc->gpio_chip.irq;
+	girq->chip = &rp1_gpio_irq_chip;
+	girq->parent_handler = rp1_gpio_irq_handler;
+	girq->num_parents = RP1_NUM_BANKS;
+	girq->parents = pc->irq;
+	girq->default_type = IRQ_TYPE_NONE;
+	girq->handler = handle_level_irq;
+
+	/*
+	 * Use the same handler for all groups: this is necessary
+	 * since we use one gpiochip to cover all lines - the
+	 * irq handler then needs to figure out which group and
+	 * bank that was firing the IRQ and look up the per-group
+	 * and bank data.
+	 */
+	for (i = 0; i < RP1_NUM_BANKS; i++) {
+		pc->irq[i] = irq_of_parse_and_map(np, i);
+		if (!pc->irq[i]) {
+			girq->num_parents = i;
+			break;
+		}
+	}
+
+	platform_set_drvdata(pdev, pc);
+
+	err = devm_gpiochip_add_data(dev, &pc->gpio_chip, pc);
+	if (err)
+		return dev_err_probe(dev, err, "could not add GPIO chip\n");
+
+	return 0;
+}
+
+static struct platform_driver rp1_pinctrl_driver = {
+	.probe = rp1_pinctrl_probe,
+	.driver = {
+		.name = MODULE_NAME,
+		.of_match_table = rp1_pinctrl_match,
+		.suppress_bind_attrs = true,
+	},
+};
+module_platform_driver(rp1_pinctrl_driver);
+
+MODULE_AUTHOR("Phil Elwell <phil at raspberrypi.com>");
+MODULE_AUTHOR("Andrea della Porta <andrea.porta at suse.com>");
+MODULE_DESCRIPTION("RP1 pinctrl/gpio driver");
+MODULE_LICENSE("GPL");
-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:32 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:32 +0100
Subject: [PATCH v5 08/10] misc: rp1: RaspberryPi RP1 misc driver
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <28fe72eec1c08781770cee65032bb10a6d5994a9.1733136811.git.andrea.porta@suse.com>

The RaspberryPi RP1 is a PCI multi function device containing
peripherals ranging from Ethernet to USB controller, I2C, SPI
and others.

Implement a bare minimum driver to operate the RP1, leveraging
actual OF based driver implementations for the on-board peripherals
by loading a devicetree overlay during driver probe.

The peripherals are accessed by mapping MMIO registers starting
from PCI BAR1 region.

With the overlay approach we can achieve more generic and agnostic
approach to managing this chipset, being that it is a PCI endpoint
and could possibly be reused in other hw implementations. The
presented approach is also used by Bootlin's Microchip LAN966x
patchset (see link) as well, for a similar chipset.

Since the gpio line names should be provided by the user, there
is an interface through configfs that allows the userspace to
load a DT overlay that will provide gpio-line-names property.
The interface can be invoked like this:

cat rpi-rp1-gpios-5-b.dtbo > /sys/kernel/config/rp1-cfg/gpio_set_names

and is designed to be similar to what users are already used to
from distro with downstream kernel.

For reasons why this driver is contained in drivers/misc, please
check the links.

This driver is heavily based on downstream code from RaspberryPi
Foundation, and the original author is Phil Elwell.

Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
Link: https://lore.kernel.org/all/20240612140208.GC1504919 at google.com/
Link: https://lore.kernel.org/all/83f7fa09-d0e6-4f36-a27d-cee08979be2a at app.fastmail.com/
Link: https://lore.kernel.org/all/2024081356-mutable-everyday-6f9d at gregkh/
Link: https://lore.kernel.org/all/20240808154658.247873-1-herve.codina at bootlin.com/

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 MAINTAINERS                   |   1 +
 drivers/misc/Kconfig          |   1 +
 drivers/misc/Makefile         |   1 +
 drivers/misc/rp1/Kconfig      |  21 ++
 drivers/misc/rp1/Makefile     |   3 +
 drivers/misc/rp1/rp1-pci.dtso |   8 +
 drivers/misc/rp1/rp1_pci.c    | 366 ++++++++++++++++++++++++++++++++++
 drivers/misc/rp1/rp1_pci.h    |  14 ++
 drivers/pci/quirks.c          |   1 +
 include/linux/pci_ids.h       |   3 +
 10 files changed, 419 insertions(+)
 create mode 100644 drivers/misc/rp1/Kconfig
 create mode 100644 drivers/misc/rp1/Makefile
 create mode 100644 drivers/misc/rp1/rp1-pci.dtso
 create mode 100644 drivers/misc/rp1/rp1_pci.c
 create mode 100644 drivers/misc/rp1/rp1_pci.h

diff --git a/MAINTAINERS b/MAINTAINERS
index fbdd8594aa7e..d67ba6d10aa8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19583,6 +19583,7 @@ F:	Documentation/devicetree/bindings/misc/pci1de4,1.yaml
 F:	Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
 F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
 F:	drivers/clk/clk-rp1.c
+F:	drivers/misc/rp1/
 F:	drivers/pinctrl/pinctrl-rp1.c
 F:	include/dt-bindings/clock/rp1.h
 F:	include/dt-bindings/misc/rp1.h
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 09cbe3f0ab1e..ffa4d8315c35 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -651,4 +651,5 @@ source "drivers/misc/uacce/Kconfig"
 source "drivers/misc/pvpanic/Kconfig"
 source "drivers/misc/mchp_pci1xxxx/Kconfig"
 source "drivers/misc/keba/Kconfig"
+source "drivers/misc/rp1/Kconfig"
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 40bf953185c7..3b6b07a23aac 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -74,3 +74,4 @@ lan966x-pci-objs		:= lan966x_pci.o
 lan966x-pci-objs		+= lan966x_pci.dtbo.o
 obj-$(CONFIG_MCHP_LAN966X_PCI)	+= lan966x-pci.o
 obj-y				+= keba/
+obj-$(CONFIG_MISC_RP1)		+= rp1/
diff --git a/drivers/misc/rp1/Kconfig b/drivers/misc/rp1/Kconfig
new file mode 100644
index 000000000000..15c443e13389
--- /dev/null
+++ b/drivers/misc/rp1/Kconfig
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# RaspberryPi RP1 misc device
+#
+
+config MISC_RP1
+	tristate "RaspberryPi RP1 PCIe support"
+	depends on OF_IRQ && PCI_MSI && PCI_QUIRKS
+	select OF_OVERLAY
+	select PCI_DYNAMIC_OF_NODES
+	help
+	  Support the RP1 peripheral chip found on Raspberry Pi 5 board.
+
+	  This device supports several sub-devices including e.g. Ethernet
+	  controller, USB controller, I2C, SPI and UART.
+
+	  The driver is responsible for enabling the DT node once the PCIe
+	  endpoint has been configured, and handling interrupts.
+
+	  This driver uses an overlay to load other drivers to support for
+	  RP1 internal sub-devices.
diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
new file mode 100644
index 000000000000..508b4cb05627
--- /dev/null
+++ b/drivers/misc/rp1/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
+rp1-pci-objs			:= rp1_pci.o rp1-pci.dtbo.o
diff --git a/drivers/misc/rp1/rp1-pci.dtso b/drivers/misc/rp1/rp1-pci.dtso
new file mode 100644
index 000000000000..0bf2f4bb18e6
--- /dev/null
+++ b/drivers/misc/rp1/rp1-pci.dtso
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/* the dts overlay is included from the dts directory so
+ * it can be possible to check it with CHECK_DTBS while
+ * also compile it from the driver source directory.
+ */
+
+#include "arm64/broadcom/rp1.dtso"
diff --git a/drivers/misc/rp1/rp1_pci.c b/drivers/misc/rp1/rp1_pci.c
new file mode 100644
index 000000000000..0dd345341c6f
--- /dev/null
+++ b/drivers/misc/rp1/rp1_pci.c
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018-24 Raspberry Pi Ltd.
+ * All rights reserved.
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_platform.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+#include "rp1_pci.h"
+
+#define RP1_DRIVER_NAME		"rp1"
+
+#define RP1_HW_IRQ_MASK		GENMASK(5, 0)
+
+#define REG_SET			0x800
+#define REG_CLR			0xc00
+
+/* MSI-X CFG registers start at 0x8 */
+#define MSIX_CFG(x) (0x8 + (4 * (x)))
+
+#define MSIX_CFG_IACK_EN        BIT(3)
+#define MSIX_CFG_IACK           BIT(2)
+#define MSIX_CFG_ENABLE         BIT(0)
+
+/* Address map */
+#define RP1_PCIE_APBS_BASE	0x108000
+
+/* Interrupts */
+#define RP1_INT_IO_BANK0	0
+#define RP1_INT_IO_BANK1	1
+#define RP1_INT_IO_BANK2	2
+#define RP1_INT_AUDIO_IN	3
+#define RP1_INT_AUDIO_OUT	4
+#define RP1_INT_PWM0		5
+#define RP1_INT_ETH		6
+#define RP1_INT_I2C0		7
+#define RP1_INT_I2C1		8
+#define RP1_INT_I2C2		9
+#define RP1_INT_I2C3		10
+#define RP1_INT_I2C4		11
+#define RP1_INT_I2C5		12
+#define RP1_INT_I2C6		13
+#define RP1_INT_I2S0		14
+#define RP1_INT_I2S1		15
+#define RP1_INT_I2S2		16
+#define RP1_INT_SDIO0		17
+#define RP1_INT_SDIO1		18
+#define RP1_INT_SPI0		19
+#define RP1_INT_SPI1		20
+#define RP1_INT_SPI2		21
+#define RP1_INT_SPI3		22
+#define RP1_INT_SPI4		23
+#define RP1_INT_SPI5		24
+#define RP1_INT_UART0		25
+#define RP1_INT_TIMER_0		26
+#define RP1_INT_TIMER_1		27
+#define RP1_INT_TIMER_2		28
+#define RP1_INT_TIMER_3		29
+#define RP1_INT_USBHOST0	30
+#define RP1_INT_USBHOST0_0	31
+#define RP1_INT_USBHOST0_1	32
+#define RP1_INT_USBHOST0_2	33
+#define RP1_INT_USBHOST0_3	34
+#define RP1_INT_USBHOST1	35
+#define RP1_INT_USBHOST1_0	36
+#define RP1_INT_USBHOST1_1	37
+#define RP1_INT_USBHOST1_2	38
+#define RP1_INT_USBHOST1_3	39
+#define RP1_INT_DMA		40
+#define RP1_INT_PWM1		41
+#define RP1_INT_UART1		42
+#define RP1_INT_UART2		43
+#define RP1_INT_UART3		44
+#define RP1_INT_UART4		45
+#define RP1_INT_UART5		46
+#define RP1_INT_MIPI0		47
+#define RP1_INT_MIPI1		48
+#define RP1_INT_VIDEO_OUT	49
+#define RP1_INT_PIO_0		50
+#define RP1_INT_PIO_1		51
+#define RP1_INT_ADC_FIFO	52
+#define RP1_INT_PCIE_OUT	53
+#define RP1_INT_SPI6		54
+#define RP1_INT_SPI7		55
+#define RP1_INT_SPI8		56
+#define RP1_INT_SYSCFG		58
+#define RP1_INT_CLOCKS_DEFAULT	59
+#define RP1_INT_VBUSCTRL	60
+#define RP1_INT_PROC_MISC	57
+#define RP1_INT_END		61
+
+struct rp1_dev {
+	struct pci_dev *pdev;
+	struct irq_domain *domain;
+	struct irq_data *pcie_irqds[64];
+	void __iomem *bar1;
+	int ovcs_id;	/* overlay changeset id */
+	bool level_triggered_irq[RP1_INT_END];
+};
+
+static void msix_cfg_set(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
+{
+	iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_SET + MSIX_CFG(hwirq));
+}
+
+static void msix_cfg_clr(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
+{
+	iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_CLR + MSIX_CFG(hwirq));
+}
+
+static void rp1_mask_irq(struct irq_data *irqd)
+{
+	struct rp1_dev *rp1 = irqd->domain->host_data;
+	struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
+
+	pci_msi_mask_irq(pcie_irqd);
+}
+
+static void rp1_unmask_irq(struct irq_data *irqd)
+{
+	struct rp1_dev *rp1 = irqd->domain->host_data;
+	struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
+
+	pci_msi_unmask_irq(pcie_irqd);
+}
+
+static int rp1_irq_set_type(struct irq_data *irqd, unsigned int type)
+{
+	struct rp1_dev *rp1 = irqd->domain->host_data;
+	unsigned int hwirq = (unsigned int)irqd->hwirq;
+
+	switch (type) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		dev_dbg(&rp1->pdev->dev, "MSIX IACK EN for irq %d\n", hwirq);
+		msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK_EN);
+		rp1->level_triggered_irq[hwirq] = true;
+	break;
+	case IRQ_TYPE_EDGE_RISING:
+		msix_cfg_clr(rp1, hwirq, MSIX_CFG_IACK_EN);
+		rp1->level_triggered_irq[hwirq] = false;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct irq_chip rp1_irq_chip = {
+	.name		= "rp1_irq_chip",
+	.irq_mask	= rp1_mask_irq,
+	.irq_unmask	= rp1_unmask_irq,
+	.irq_set_type	= rp1_irq_set_type,
+};
+
+static void rp1_chained_handle_irq(struct irq_desc *desc)
+{
+	unsigned int hwirq = desc->irq_data.hwirq & RP1_HW_IRQ_MASK;
+	struct rp1_dev *rp1 = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	unsigned int virq;
+
+	chained_irq_enter(chip, desc);
+
+	virq = irq_find_mapping(rp1->domain, hwirq);
+	generic_handle_irq(virq);
+	if (rp1->level_triggered_irq[hwirq])
+		msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK);
+
+	chained_irq_exit(chip, desc);
+}
+
+static int rp1_irq_xlate(struct irq_domain *d, struct device_node *node,
+			 const u32 *intspec, unsigned int intsize,
+			 unsigned long *out_hwirq, unsigned int *out_type)
+{
+	struct rp1_dev *rp1 = d->host_data;
+	struct irq_data *pcie_irqd;
+	unsigned long hwirq;
+	int pcie_irq;
+	int ret;
+
+	ret = irq_domain_xlate_twocell(d, node, intspec, intsize,
+				       &hwirq, out_type);
+	if (ret)
+		return ret;
+
+	pcie_irq = pci_irq_vector(rp1->pdev, hwirq);
+	pcie_irqd = irq_get_irq_data(pcie_irq);
+	rp1->pcie_irqds[hwirq] = pcie_irqd;
+	*out_hwirq = hwirq;
+
+	return 0;
+}
+
+static int rp1_irq_activate(struct irq_domain *d, struct irq_data *irqd,
+			    bool reserve)
+{
+	struct rp1_dev *rp1 = d->host_data;
+
+	msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
+
+	return 0;
+}
+
+static void rp1_irq_deactivate(struct irq_domain *d, struct irq_data *irqd)
+{
+	struct rp1_dev *rp1 = d->host_data;
+
+	msix_cfg_clr(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
+}
+
+static const struct irq_domain_ops rp1_domain_ops = {
+	.xlate      = rp1_irq_xlate,
+	.activate   = rp1_irq_activate,
+	.deactivate = rp1_irq_deactivate,
+};
+
+static void rp1_unregister_interrupts(struct pci_dev *pdev)
+{
+	struct rp1_dev *rp1 = pci_get_drvdata(pdev);
+	int irq, i;
+
+	if (rp1->domain) {
+		for (i = 0; i < RP1_INT_END; i++) {
+			irq = irq_find_mapping(rp1->domain, i);
+			irq_dispose_mapping(irq);
+		}
+
+		irq_domain_remove(rp1->domain);
+	}
+
+	pci_free_irq_vectors(pdev);
+}
+
+static int rp1_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	u32 dtbo_size = __dtbo_rp1_pci_end - __dtbo_rp1_pci_begin;
+	void *dtbo_start = __dtbo_rp1_pci_begin;
+	struct device *dev = &pdev->dev;
+	struct device_node *rp1_node;
+	struct rp1_dev *rp1;
+	int err = 0;
+	int i;
+
+	rp1_node = dev_of_node(dev);
+	if (!rp1_node) {
+		dev_err(dev, "Missing of_node for device\n");
+		return -EINVAL;
+	}
+
+	rp1 = devm_kzalloc(&pdev->dev, sizeof(*rp1), GFP_KERNEL);
+	if (!rp1)
+		return -ENOMEM;
+
+	rp1->pdev = pdev;
+
+	if (pci_resource_len(pdev, 1) <= 0x10000) {
+		dev_err(&pdev->dev,
+			"Not initialised - is the firmware running?\n");
+		return -EINVAL;
+	}
+
+	err = pcim_enable_device(pdev);
+	if (err < 0)
+		return dev_err_probe(&pdev->dev, err,
+				     "Enabling PCI device has failed");
+
+	rp1->bar1 = pcim_iomap(pdev, 1, 0);
+	if (!rp1->bar1) {
+		dev_err(&pdev->dev, "Cannot map PCI BAR\n");
+		return -EIO;
+	}
+
+	pci_set_master(pdev);
+
+	err = pci_alloc_irq_vectors(pdev, RP1_INT_END, RP1_INT_END,
+				    PCI_IRQ_MSIX);
+	if (err < 0) {
+		return dev_err_probe(&pdev->dev, err,
+				     "pci_alloc_irq_vectors failed");
+	} else if (err != RP1_INT_END) {
+		dev_err(&pdev->dev, "Cannot allocate enough interrupts\n");
+		return -EINVAL;
+	}
+
+	pci_set_drvdata(pdev, rp1);
+	rp1->domain = irq_domain_add_linear(rp1_node, RP1_INT_END,
+					    &rp1_domain_ops, rp1);
+	if (!rp1->domain) {
+		dev_err(&pdev->dev, "Error creating IRQ domain\n");
+		err = -ENOMEM;
+		goto err_unregister_interrupts;
+	}
+
+	for (i = 0; i < RP1_INT_END; i++) {
+		unsigned int irq = irq_create_mapping(rp1->domain, i);
+
+		if (!irq) {
+			dev_err(&pdev->dev, "failed to create irq mapping\n");
+			err = -EINVAL;
+			goto err_unregister_interrupts;
+		}
+
+		irq_set_chip_and_handler(irq, &rp1_irq_chip, handle_level_irq);
+		irq_set_probe(irq);
+		irq_set_chained_handler_and_data(pci_irq_vector(pdev, i),
+						 rp1_chained_handle_irq, rp1);
+	}
+
+	err = of_overlay_fdt_apply(dtbo_start, dtbo_size, &rp1->ovcs_id, rp1_node);
+	if (err)
+		goto err_unregister_interrupts;
+
+	err = of_platform_default_populate(rp1_node, NULL, dev);
+	if (err)
+		goto err_unload_overlay;
+
+	return 0;
+
+err_unload_overlay:
+	of_overlay_remove(&rp1->ovcs_id);
+err_unregister_interrupts:
+	rp1_unregister_interrupts(pdev);
+
+	return err;
+}
+
+static void rp1_remove(struct pci_dev *pdev)
+{
+	struct rp1_dev *rp1 = pci_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	of_platform_depopulate(dev);
+	of_overlay_remove(&rp1->ovcs_id);
+	rp1_unregister_interrupts(pdev);
+}
+
+static const struct pci_device_id dev_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RPI_RP1_C0), },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, dev_id_table);
+
+static struct pci_driver rp1_driver = {
+	.name		= RP1_DRIVER_NAME,
+	.id_table	= dev_id_table,
+	.probe		= rp1_probe,
+	.remove		= rp1_remove,
+};
+
+module_pci_driver(rp1_driver);
+
+MODULE_AUTHOR("Phil Elwell <phil at raspberrypi.com>");
+MODULE_AUTHOR("Andrea della Porta <andrea.porta at suse.com>");
+MODULE_DESCRIPTION("RP1 wrapper");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/rp1/rp1_pci.h b/drivers/misc/rp1/rp1_pci.h
new file mode 100644
index 000000000000..7982f13bad9b
--- /dev/null
+++ b/drivers/misc/rp1/rp1_pci.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Copyright (c) 2018-24 Raspberry Pi Ltd.
+ * All rights reserved.
+ */
+
+#ifndef _RP1_EXTERN_H_
+#define _RP1_EXTERN_H_
+
+extern char __dtbo_rp1_pci_begin[];
+extern char __dtbo_rp1_pci_end[];
+
+#endif
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 76f4df75b08a..e9a0fb707a4a 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -6269,6 +6269,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5020, of_pci_make_dev_node);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5021, of_pci_make_dev_node);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT, 0x0005, of_pci_make_dev_node);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, 0x9660, of_pci_make_dev_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RPI_RP1_C0, of_pci_make_dev_node);
 
 /*
  * Devices known to require a longer delay before first config space access
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index d2402bf4aea2..9232b131a41e 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2615,6 +2615,9 @@
 #define PCI_VENDOR_ID_TEKRAM		0x1de1
 #define PCI_DEVICE_ID_TEKRAM_DC290	0xdc29
 
+#define PCI_VENDOR_ID_RPI		0x1de4
+#define PCI_DEVICE_ID_RPI_RP1_C0	0x0001
+
 #define PCI_VENDOR_ID_ALIBABA		0x1ded
 
 #define PCI_VENDOR_ID_CXL		0x1e98
-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:33 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:33 +0100
Subject: [PATCH v5 09/10] arm64: dts: bcm2712: Add external clock for RP1 chipset on Rpi5
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <8b4dda91fae156a7f28f2807cd6d64ac2ec07dd7.1733136811.git.andrea.porta@suse.com>

The RP1 found on Raspberry Pi 5 board needs an external crystal at 50MHz.
Add clk_rp1_xosc node to provide that.

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
index 2bdbb6780242..ae3c0c153cea 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
@@ -16,6 +16,13 @@ chosen: chosen {
 		stdout-path = "serial10:115200n8";
 	};
 
+	clk_rp1_xosc: clock-50000000 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-output-names = "rp1-xosc";
+		clock-frequency = <50000000>;
+	};
+
 	/* Will be filled by the bootloader */
 	memory at 0 {
 		device_type = "memory";
-- 
2.35.3



From andrea.porta at suse.com  Mon Dec  2 03:19:34 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  2 Dec 2024 12:19:34 +0100
Subject: [PATCH v5 10/10] arm64: defconfig: Enable RP1 misc/clock/gpio drivers
In-Reply-To: <cover.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
Message-ID: <2dc27b08d82e5257a831026c963ac148d11cb6e8.1733136811.git.andrea.porta@suse.com>

Select the RP1 drivers needed to operate the PCI endpoint containing
several peripherals such as Ethernet and USB Controller. This chip is
present on RaspberryPi 5.

Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
Reviewed-by: Stefan Wahren <wahrenst at gmx.net>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..91b39026dc56 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -609,6 +609,7 @@ CONFIG_PINCTRL_QCM2290=y
 CONFIG_PINCTRL_QCS404=y
 CONFIG_PINCTRL_QDF2XXX=y
 CONFIG_PINCTRL_QDU1000=y
+CONFIG_PINCTRL_RP1=m
 CONFIG_PINCTRL_SA8775P=y
 CONFIG_PINCTRL_SC7180=y
 CONFIG_PINCTRL_SC7280=y
@@ -690,6 +691,7 @@ CONFIG_SENSORS_RASPBERRYPI_HWMON=m
 CONFIG_SENSORS_SL28CPLD=m
 CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_INA3221=m
+CONFIG_MISC_RP1=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
 CONFIG_DEVFREQ_THERMAL=y
@@ -1272,6 +1274,7 @@ CONFIG_COMMON_CLK_CS2000_CP=y
 CONFIG_COMMON_CLK_FSL_SAI=y
 CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_COMMON_CLK_PWM=y
+CONFIG_COMMON_CLK_RP1=m
 CONFIG_COMMON_CLK_RS9_PCIE=y
 CONFIG_COMMON_CLK_VC3=y
 CONFIG_COMMON_CLK_VC5=y
-- 
2.35.3



From s.hauer at pengutronix.de  Mon Dec  2 03:22:28 2024
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 02 Dec 2024 12:22:28 +0100
Subject: [PATCH v2 0/4] nvmem: imx-ocotp-ele: fix reading from ELE OCOTP
Message-ID: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>

Commits b2ab0edaf484 ("arm64: dts: imx93: add nvmem property for fec1")
and 0d4fbaffbdca ("arm64: dts: imx93: add nvmem property for eqos")
introduced NVMEM cell bindings for reading MAC addresses from the ELE
OCOTP. This doesn't work as expected due to bugs in the driver:

- imx_ocotp_reg_read() interprets the incoming offset as 32bit word
  offset, but it really is in bytes which means the driver reads bogus
  values whenever the offset is non zero
- imx_ocotp_reg_read() reads wrong results when the offset is not 32bit
  word aligned
- MAC addresses are stored in reverse byte order in the ELE OCOTP, we
  have to swap the order before passing them to the upper layer

This likely went through unnoticed because the bootloader normally adds
the MAC addresses to the ethernet nodes and in this case they are
preferred over the NVMEM addresses.

This series fixes these issues.

Sascha

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
Changes in v2:
- Add Fixes: and Cc: stable tag as requested by Fabio
- Link to v1: https://lore.kernel.org/r/20241023-imx-ele-ocotp-fixes-v1-0-4adc00ce288f at pengutronix.de

---
Sascha Hauer (4):
      nvmem: imx-ocotp-ele: simplify read beyond device check
      nvmem: imx-ocotp-ele: fix reading from non zero offset
      nvmem: imx-ocotp-ele: fix MAC address byte order
      nvmem: imx-ocotp-ele: set word length to 1

 drivers/nvmem/imx-ocotp-ele.c | 38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241023-imx-ele-ocotp-fixes-f7b216171e1e

Best regards,
-- 
Sascha Hauer <s.hauer at pengutronix.de>



From s.hauer at pengutronix.de  Mon Dec  2 03:22:30 2024
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 02 Dec 2024 12:22:30 +0100
Subject: [PATCH v2 2/4] nvmem: imx-ocotp-ele: fix reading from non zero
 offset
In-Reply-To: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
References: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
Message-ID: <20241202-imx-ele-ocotp-fixes-v2-2-3c021a97eb5d@pengutronix.de>

In imx_ocotp_reg_read() the offset comes in as bytes and not as words.
This means we have to divide offset by 4 to get to the correct word
offset.

Also the incoming offset might not be word aligned. In order to read
from the OCOTP the driver aligns down the previous word boundary and
reads from there. This means we have to skip this alignment offset from
the temporary buffer when copying the data to the output buffer.

Fixes: 22e9e6fcfb504 ("nvmem: imx: support i.MX93 OCOTP")
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Cc: stable <stable at kernel.org>
---
 drivers/nvmem/imx-ocotp-ele.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index 2e186b7d3b040..b2d21a5f77bc1 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -71,12 +71,14 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 	u32 *buf;
 	void *p;
 	int i;
+	u8 skipbytes;
 
 	if (offset + bytes > priv->data->size)
 		bytes = priv->data->size - offset;
 
-	index = offset;
-	num_bytes = round_up(bytes, 4);
+	index = offset >> 2;
+	skipbytes = offset - (index << 2);
+	num_bytes = round_up(bytes + skipbytes, 4);
 	count = num_bytes >> 2;
 
 	p = kzalloc(num_bytes, GFP_KERNEL);
@@ -100,7 +102,7 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 			*buf++ = readl_relaxed(reg + (i << 2));
 	}
 
-	memcpy(val, (u8 *)p, bytes);
+	memcpy(val, ((u8 *)p) + skipbytes, bytes);
 
 	mutex_unlock(&priv->lock);
 

-- 
2.39.5



From s.hauer at pengutronix.de  Mon Dec  2 03:22:32 2024
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 02 Dec 2024 12:22:32 +0100
Subject: [PATCH v2 4/4] nvmem: imx-ocotp-ele: set word length to 1
In-Reply-To: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
References: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
Message-ID: <20241202-imx-ele-ocotp-fixes-v2-4-3c021a97eb5d@pengutronix.de>

The ELE hardware internally has a word length of 4. However, among other
things we store MAC addresses in the ELE OCOTP. With a length of 6 bytes
these are naturally unaligned to the word length. Therefore we must
support unaligned reads in reg_read() and indeed it works properly when
reg_read() is called via nvmem_reg_read(). Setting the word size to 4
has the only visible effect that doing unaligned reads from userspace
via bin_attr_nvmem_read() do not work because they are rejected by that
function.

Given that we have to abstract from word accesses to byte accesses in
the driver, set the word size to 1. This allows bytewise accesses from
userspace to be able to test what the driver has to support anyway.

Fixes: 22e9e6fcfb504 ("nvmem: imx: support i.MX93 OCOTP")
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Cc: stable <stable at kernel.org>
---
 drivers/nvmem/imx-ocotp-ele.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index 422a6d53b10ef..ca6dd71d8a2e2 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -153,7 +153,7 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	priv->config.owner = THIS_MODULE;
 	priv->config.size = priv->data->size;
 	priv->config.reg_read = priv->data->reg_read;
-	priv->config.word_size = 4;
+	priv->config.word_size = 1;
 	priv->config.stride = 1;
 	priv->config.priv = priv;
 	priv->config.read_only = true;

-- 
2.39.5



From lpieralisi at kernel.org  Mon Dec  2 03:25:18 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Mon,  2 Dec 2024 12:25:18 +0100
Subject: [PATCH] irqchip/gic-v3: Fix irq_complete_ack() comment
Message-ID: <20241202112518.51178-1-lpieralisi@kernel.org>

When the GIC is in EOImode == 1 in irq_complete_ack() we
execute a priority drop not a deactivation.

Fix the function comment to clarify the behaviour.

Signed-off-by: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-gic-v3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 8b6159f4cdaf..34db379d066a 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -817,7 +817,7 @@ static void gic_deactivate_unhandled(u32 irqnr)
  *     register state is not stale, as these may have been indirectly written
  *     *after* exception entry.
  *
- * (2) Deactivate the interrupt when EOI mode 1 is in use.
+ * (2) Execute an interrupt priority drop when EOI mode 1 is in use.
  */
 static inline void gic_complete_ack(u32 irqnr)
 {
-- 
2.47.0



From suzuki.poulose at arm.com  Mon Dec  2 03:31:41 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 2 Dec 2024 11:31:41 +0000
Subject: [PATCH 3/4] coresight: tmc-etr: Fix race condition between sysfs
 and perf mode
In-Reply-To: <ca63ed33-f9ab-484a-b846-9e00a8d1d1ca@linaro.org>
References: <20241202092419.11777-1-yangyicong@huawei.com>
 <20241202092419.11777-4-yangyicong@huawei.com>
 <62f5d1c5-05bd-41b6-8703-baacec3e2619@arm.com>
 <ca63ed33-f9ab-484a-b846-9e00a8d1d1ca@linaro.org>
Message-ID: <d17a8c73-1f5c-48c6-9079-e191eeb0928e@arm.com>

On 02/12/2024 11:19, James Clark wrote:
> 
> 
> On 02/12/2024 9:46 am, Suzuki K Poulose wrote:
>> Hi Yicong
>>
>> On 02/12/2024 09:24, Yicong Yang wrote:
>>> From: Yicong Yang <yangyicong at hisilicon.com>
>>>
>>> When trying to run perf and sysfs mode simultaneously, the WARN_ON()
>>> in tmc_etr_enable_hw() is triggered sometimes:
>>>
>>> ? WARNING: CPU: 42 PID: 3911571 at drivers/hwtracing/coresight/ 
>>> coresight-tmc-etr.c:1060 tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc]
>>> ? [..snip..]
>>> ? Call trace:
>>> ?? tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc] (P)
>>> ?? tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc] (L)
>>> ?? tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc]
>>> ?? coresight_enable_path+0x1c8/0x218 [coresight]
>>> ?? coresight_enable_sysfs+0xa4/0x228 [coresight]
>>> ?? enable_source_store+0x58/0xa8 [coresight]
>>> ?? dev_attr_store+0x20/0x40
>>> ?? sysfs_kf_write+0x4c/0x68
>>> ?? kernfs_fop_write_iter+0x120/0x1b8
>>> ?? vfs_write+0x2c8/0x388
>>> ?? ksys_write+0x74/0x108
>>> ?? __arm64_sys_write+0x24/0x38
>>> ?? el0_svc_common.constprop.0+0x64/0x148
>>> ?? do_el0_svc+0x24/0x38
>>> ?? el0_svc+0x3c/0x130
>>> ?? el0t_64_sync_handler+0xc8/0xd0
>>> ?? el0t_64_sync+0x1ac/0x1b0
>>> ? ---[ end trace 0000000000000000 ]---
>>>
>>> Since the enablement of sysfs mode is separeted into two critical 
>>> regions,
>>> one for sysfs buffer allocation and another for hardware enablement, 
>>> it's
>>> possible to race with the perf mode. Fix this by double check whether
>>> the perf mode's been used before enabling the hardware in sysfs mode.
>>
>> Thanks for the fix. Some minor comments below.
>>
>> It needs a Fixes tag.
>>
>>>
>>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>>> ---
>>> ? .../hwtracing/coresight/coresight-tmc-etr.c?? | 30 +++++++++++++++++++
>>> ? 1 file changed, 30 insertions(+)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/ 
>>> drivers/hwtracing/coresight/coresight-tmc-etr.c
>>> index ad83714ca4dc..d382d95da5ff 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
>>> @@ -1230,6 +1230,36 @@ static int tmc_enable_etr_sink_sysfs(struct 
>>> coresight_device *csdev)
>>> ????? spin_lock_irqsave(&drvdata->spinlock, flags);
>>> +??? /*
>>> +???? * Since the sysfs buffer allocation and the hardware enablement 
>>> is not
>>> +???? * in the same critical region, it's possible to race with the perf
>>> +???? * mode:
>>> +???? *?? [sysfs mode]?????????????????? [perf mode]
>>> +???? *?? tmc_etr_get_sysfs_buffer()
>>> +???? *???? spin_lock(&drvdata->spinlock)
>>> +???? *???? [sysfs buffer allocation]
>>> +???? *???? spin_unlock(&drvdata->spinlock)
>>> +???? *????????????????????????????????? spin_lock(&drvdata->spinlock)
>>> +???? *????????????????????????????????? tmc_etr_enable_hw()
>>> +???? *??????????????????????????????????? drvdata->etr_buf = 
>>> etr_perf->etr_buf
>>> +???? *????????????????????????????????? spin_unlock(&drvdata->spinlock)
>>> +???? *?? spin_lock(&drvdata->spinlock)
>>> +???? *?? tmc_etr_enable_hw()
>>> +???? *???? WARN_ON(drvdata->etr_buf) // WARN sicne etr_buf 
>>> initialized at
>>> +???? *????????????????????????????????? the perf side
>>> +???? *?? spin_unlock(&drvdata->spinlock)
>>> +???? *
>>> +???? * So check here before continue.
>>> +???? */
>>> +??? if (coresight_get_mode(csdev) == CS_MODE_PERF) {
>>> +??????? drvdata->sysfs_buf = NULL;
>>> +??????? spin_unlock_irqrestore(&drvdata->spinlock, flags);
>>> +
>>> +??????? /* Free allocated memory out side of the spinlock */
>>> +??????? tmc_etr_free_sysfs_buf(sysfs_buf);
>>> +??????? return -EBUSY;
>>> +??? }
>>
>> With this in place, I think we should remove the check for 
>> CS_MODE_PERF in get_etr_sysfs_buf() to avoid confusion (which I 
>> believe opened up this race)
>>
>> Suzuki
>>
> 
> Is it not simpler to set the mode to SYSFS before allocating the buffer 
> in the first place? Then we don't need to free if it races and can't get 
> into the intermediate state where it's a half initialized sysfs mode. 
> The lock doesn't need to be held the whole time, just when setting the 
> mode.
> 
> Or maybe to make it more consistent with etm4_enable() use 
> coresight_take_mode() outside of the lock.
> 
> And then also clean up the perf mode check in get_etr_sysfs_buf().
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/ 
> hwtracing/coresight/coresight-tmc-etr.c
> index a48bb85d0e7f..29c07832127b 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -1219,13 +1219,17 @@ static int tmc_enable_etr_sink_sysfs(struct 
> coresight_device *csdev)
>  ??????? int ret = 0;
>  ??????? unsigned long flags;
>  ??????? struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> -?????? struct etr_buf *sysfs_buf = tmc_etr_get_sysfs_buffer(csdev);
> +?????? struct etr_buf *sysfs_buf;
> 
> +?????? spin_lock_irqsave(&drvdata->spinlock, flags);
> +
> +?????? if (coresight_get_mode(csdev) == CS_MODE_PERF)
> +?????????????? return -EBUSY;
> +
> +?????? sysfs_buf = tmc_etr_get_sysfs_buffer(csdev);

^^ This would try to loack the spinlock again. Or we should explicitly 
assert that the spinlock is held in the tmc_etr_get_sysfs_buffer() and 
release it and then allocate the buffer. Which again opens up a race
for a PERF session to take it over ?

Suzuki


>  ??????? if (IS_ERR(sysfs_buf))
>  ??????????????? return PTR_ERR(sysfs_buf);
> 
> -?????? spin_lock_irqsave(&drvdata->spinlock, flags);
> -
>  ??????? /*
>  ???????? * In sysFS mode we can have multiple writers per sink.? Since 
> this
>  ???????? * sink is already enabled no memory is needed and the HW need 
> not be
> 
> 



From angelogioacchino.delregno at collabora.com  Mon Dec  2 03:33:08 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 2 Dec 2024 12:33:08 +0100
Subject: [PATCH] devfreq: Switch back to struct platform_driver::remove()
In-Reply-To: <20241130135813.895628-2-u.kleine-koenig@baylibre.com>
References: <20241130135813.895628-2-u.kleine-koenig@baylibre.com>
Message-ID: <000cf951-1afc-4bcf-9f72-c484dcfa1b2d@collabora.com>

Il 30/11/24 14:58, Uwe Kleine-K?nig ha scritto:
> After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
> return void") .remove() is (again) the right callback to implement for
> platform drivers.
> 
> Convert all platform drivers below drivers/devfreq to use .remove(),
> with the eventual goal to drop struct platform_driver::remove_new(). As
> .remove() and .remove_new() have the same prototypes, conversion is done
> by just changing the structure member name in the driver initializer.
> 
> While touching these drivers, make the alignment of the touched
> initializers consistent.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>

For MediaTek

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From ryan.roberts at arm.com  Mon Dec  2 03:38:34 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 2 Dec 2024 11:38:34 +0000
Subject: [PATCH] arm64/mm: Drop INIT_MM_CONTEXT()
In-Reply-To: <20241202043553.29592-1-anshuman.khandual@arm.com>
References: <20241202043553.29592-1-anshuman.khandual@arm.com>
Message-ID: <3050a0b3-95f6-48aa-8850-e921bd848f85@arm.com>

On 02/12/2024 04:35, Anshuman Khandual wrote:
> Platform override for INIT_MM_CONTEXT() is redundant because swapper_pg_dir
> always gets assigned as the pgd during init_mm initialization. So just drop
> this override on arm64.
> 
> Originally this override was added via the 'commit 2b5548b68199 ("arm64/mm:
> Separate boot-time page tables from swapper_pg_dir")' because non standard
> init_pg_dir was assigned as the pgd. Subsequently it was changed as default
> swapper_pg_dir by the 'commit ba5b0333a847 ("arm64: mm: omit redundant
> remap of kernel image")', which might have also just dropped this override.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Ryan Roberts <ryan.roberts at arm.com>
> 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>

Reviewed-by: Ryan Roberts <ryan.roberts at arm.com>

> ---
> This patch applies on v6.13-rc1
> 
>  arch/arm64/include/asm/mmu.h | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
> index 2ec96d91acc6..662471cfc536 100644
> --- a/arch/arm64/include/asm/mmu.h
> +++ b/arch/arm64/include/asm/mmu.h
> @@ -109,8 +109,5 @@ static inline bool kaslr_requires_kpti(void)
>  	return true;
>  }
>  
> -#define INIT_MM_CONTEXT(name)	\
> -	.pgd = swapper_pg_dir,
> -
>  #endif	/* !__ASSEMBLY__ */
>  #endif



From suzuki.poulose at arm.com  Mon Dec  2 03:38:54 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 2 Dec 2024 11:38:54 +0000
Subject: [PATCH 3/4] coresight: tmc-etr: Fix race condition between sysfs
 and perf mode
In-Reply-To: <d17a8c73-1f5c-48c6-9079-e191eeb0928e@arm.com>
References: <20241202092419.11777-1-yangyicong@huawei.com>
 <20241202092419.11777-4-yangyicong@huawei.com>
 <62f5d1c5-05bd-41b6-8703-baacec3e2619@arm.com>
 <ca63ed33-f9ab-484a-b846-9e00a8d1d1ca@linaro.org>
 <d17a8c73-1f5c-48c6-9079-e191eeb0928e@arm.com>
Message-ID: <edeb40e5-133e-484f-8f07-d391cfeebf7b@arm.com>

On 02/12/2024 11:31, Suzuki K Poulose wrote:
> On 02/12/2024 11:19, James Clark wrote:
>>
>>
>> On 02/12/2024 9:46 am, Suzuki K Poulose wrote:
>>> Hi Yicong
>>>
>>> On 02/12/2024 09:24, Yicong Yang wrote:
>>>> From: Yicong Yang <yangyicong at hisilicon.com>
>>>>
>>>> When trying to run perf and sysfs mode simultaneously, the WARN_ON()
>>>> in tmc_etr_enable_hw() is triggered sometimes:
>>>>
>>>> ? WARNING: CPU: 42 PID: 3911571 at drivers/hwtracing/coresight/ 
>>>> coresight-tmc-etr.c:1060 tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc]
>>>> ? [..snip..]
>>>> ? Call trace:
>>>> ?? tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc] (P)
>>>> ?? tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc] (L)
>>>> ?? tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc]
>>>> ?? coresight_enable_path+0x1c8/0x218 [coresight]
>>>> ?? coresight_enable_sysfs+0xa4/0x228 [coresight]
>>>> ?? enable_source_store+0x58/0xa8 [coresight]
>>>> ?? dev_attr_store+0x20/0x40
>>>> ?? sysfs_kf_write+0x4c/0x68
>>>> ?? kernfs_fop_write_iter+0x120/0x1b8
>>>> ?? vfs_write+0x2c8/0x388
>>>> ?? ksys_write+0x74/0x108
>>>> ?? __arm64_sys_write+0x24/0x38
>>>> ?? el0_svc_common.constprop.0+0x64/0x148
>>>> ?? do_el0_svc+0x24/0x38
>>>> ?? el0_svc+0x3c/0x130
>>>> ?? el0t_64_sync_handler+0xc8/0xd0
>>>> ?? el0t_64_sync+0x1ac/0x1b0
>>>> ? ---[ end trace 0000000000000000 ]---
>>>>
>>>> Since the enablement of sysfs mode is separeted into two critical 
>>>> regions,
>>>> one for sysfs buffer allocation and another for hardware enablement, 
>>>> it's
>>>> possible to race with the perf mode. Fix this by double check whether
>>>> the perf mode's been used before enabling the hardware in sysfs mode.
>>>
>>> Thanks for the fix. Some minor comments below.
>>>
>>> It needs a Fixes tag.
>>>
>>>>
>>>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>>>> ---
>>>> ? .../hwtracing/coresight/coresight-tmc-etr.c?? | 30 +++++++++++++++ 
>>>> ++++
>>>> ? 1 file changed, 30 insertions(+)
>>>>
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/ 
>>>> drivers/hwtracing/coresight/coresight-tmc-etr.c
>>>> index ad83714ca4dc..d382d95da5ff 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
>>>> @@ -1230,6 +1230,36 @@ static int tmc_enable_etr_sink_sysfs(struct 
>>>> coresight_device *csdev)
>>>> ????? spin_lock_irqsave(&drvdata->spinlock, flags);
>>>> +??? /*
>>>> +???? * Since the sysfs buffer allocation and the hardware 
>>>> enablement is not
>>>> +???? * in the same critical region, it's possible to race with the 
>>>> perf
>>>> +???? * mode:
>>>> +???? *?? [sysfs mode]?????????????????? [perf mode]
>>>> +???? *?? tmc_etr_get_sysfs_buffer()
>>>> +???? *???? spin_lock(&drvdata->spinlock)
>>>> +???? *???? [sysfs buffer allocation]
>>>> +???? *???? spin_unlock(&drvdata->spinlock)
>>>> +???? *????????????????????????????????? spin_lock(&drvdata->spinlock)
>>>> +???? *????????????????????????????????? tmc_etr_enable_hw()
>>>> +???? *??????????????????????????????????? drvdata->etr_buf = 
>>>> etr_perf->etr_buf
>>>> +???? *????????????????????????????????? spin_unlock(&drvdata- 
>>>> >spinlock)
>>>> +???? *?? spin_lock(&drvdata->spinlock)
>>>> +???? *?? tmc_etr_enable_hw()
>>>> +???? *???? WARN_ON(drvdata->etr_buf) // WARN sicne etr_buf 
>>>> initialized at
>>>> +???? *????????????????????????????????? the perf side
>>>> +???? *?? spin_unlock(&drvdata->spinlock)
>>>> +???? *
>>>> +???? * So check here before continue.
>>>> +???? */
>>>> +??? if (coresight_get_mode(csdev) == CS_MODE_PERF) {
>>>> +??????? drvdata->sysfs_buf = NULL;
>>>> +??????? spin_unlock_irqrestore(&drvdata->spinlock, flags);
>>>> +
>>>> +??????? /* Free allocated memory out side of the spinlock */
>>>> +??????? tmc_etr_free_sysfs_buf(sysfs_buf);
>>>> +??????? return -EBUSY;
>>>> +??? }
>>>
>>> With this in place, I think we should remove the check for 
>>> CS_MODE_PERF in get_etr_sysfs_buf() to avoid confusion (which I 
>>> believe opened up this race)
>>>
>>> Suzuki
>>>
>>
>> Is it not simpler to set the mode to SYSFS before allocating the 
>> buffer in the first place? Then we don't need to free if it races and 
>> can't get into the intermediate state where it's a half initialized 
>> sysfs mode. The lock doesn't need to be held the whole time, just when 
>> setting the mode.
>>
>> Or maybe to make it more consistent with etm4_enable() use 
>> coresight_take_mode() outside of the lock.
>>
>> And then also clean up the perf mode check in get_etr_sysfs_buf().
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/ 
>> drivers/ hwtracing/coresight/coresight-tmc-etr.c
>> index a48bb85d0e7f..29c07832127b 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> @@ -1219,13 +1219,17 @@ static int tmc_enable_etr_sink_sysfs(struct 
>> coresight_device *csdev)
>> ???????? int ret = 0;
>> ???????? unsigned long flags;
>> ???????? struct tmc_drvdata *drvdata = dev_get_drvdata(csdev- 
>> >dev.parent);
>> -?????? struct etr_buf *sysfs_buf = tmc_etr_get_sysfs_buffer(csdev);
>> +?????? struct etr_buf *sysfs_buf;
>>
>> +?????? spin_lock_irqsave(&drvdata->spinlock, flags);
>> +
>> +?????? if (coresight_get_mode(csdev) == CS_MODE_PERF)
>> +?????????????? return -EBUSY;
>> +
>> +?????? sysfs_buf = tmc_etr_get_sysfs_buffer(csdev);
> 
> ^^ This would try to loack the spinlock again. Or we should explicitly 
> assert that the spinlock is held in the tmc_etr_get_sysfs_buffer() and 
> release it and then allocate the buffer. Which again opens up a race
> for a PERF session to take it over ?

Ah, no, the mode will prevent PERF mode taking over.

Suzuki

> 
> Suzuki
> 
> 
>> ???????? if (IS_ERR(sysfs_buf))
>> ???????????????? return PTR_ERR(sysfs_buf);
>>
>> -?????? spin_lock_irqsave(&drvdata->spinlock, flags);
>> -
>> ???????? /*
>> ????????? * In sysFS mode we can have multiple writers per sink.  
>> Since this
>> ????????? * sink is already enabled no memory is needed and the HW 
>> need not be
>>
>>
> 



From james.clark at linaro.org  Mon Dec  2 03:19:15 2024
From: james.clark at linaro.org (James Clark)
Date: Mon, 2 Dec 2024 11:19:15 +0000
Subject: [PATCH 3/4] coresight: tmc-etr: Fix race condition between sysfs
 and perf mode
In-Reply-To: <62f5d1c5-05bd-41b6-8703-baacec3e2619@arm.com>
References: <20241202092419.11777-1-yangyicong@huawei.com>
 <20241202092419.11777-4-yangyicong@huawei.com>
 <62f5d1c5-05bd-41b6-8703-baacec3e2619@arm.com>
Message-ID: <ca63ed33-f9ab-484a-b846-9e00a8d1d1ca@linaro.org>



On 02/12/2024 9:46 am, Suzuki K Poulose wrote:
> Hi Yicong
> 
> On 02/12/2024 09:24, Yicong Yang wrote:
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> When trying to run perf and sysfs mode simultaneously, the WARN_ON()
>> in tmc_etr_enable_hw() is triggered sometimes:
>>
>> ? WARNING: CPU: 42 PID: 3911571 at drivers/hwtracing/coresight/ 
>> coresight-tmc-etr.c:1060 tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc]
>> ? [..snip..]
>> ? Call trace:
>> ?? tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc] (P)
>> ?? tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc] (L)
>> ?? tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc]
>> ?? coresight_enable_path+0x1c8/0x218 [coresight]
>> ?? coresight_enable_sysfs+0xa4/0x228 [coresight]
>> ?? enable_source_store+0x58/0xa8 [coresight]
>> ?? dev_attr_store+0x20/0x40
>> ?? sysfs_kf_write+0x4c/0x68
>> ?? kernfs_fop_write_iter+0x120/0x1b8
>> ?? vfs_write+0x2c8/0x388
>> ?? ksys_write+0x74/0x108
>> ?? __arm64_sys_write+0x24/0x38
>> ?? el0_svc_common.constprop.0+0x64/0x148
>> ?? do_el0_svc+0x24/0x38
>> ?? el0_svc+0x3c/0x130
>> ?? el0t_64_sync_handler+0xc8/0xd0
>> ?? el0t_64_sync+0x1ac/0x1b0
>> ? ---[ end trace 0000000000000000 ]---
>>
>> Since the enablement of sysfs mode is separeted into two critical 
>> regions,
>> one for sysfs buffer allocation and another for hardware enablement, it's
>> possible to race with the perf mode. Fix this by double check whether
>> the perf mode's been used before enabling the hardware in sysfs mode.
> 
> Thanks for the fix. Some minor comments below.
> 
> It needs a Fixes tag.
> 
>>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> ---
>> ? .../hwtracing/coresight/coresight-tmc-etr.c?? | 30 +++++++++++++++++++
>> ? 1 file changed, 30 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/ 
>> drivers/hwtracing/coresight/coresight-tmc-etr.c
>> index ad83714ca4dc..d382d95da5ff 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> @@ -1230,6 +1230,36 @@ static int tmc_enable_etr_sink_sysfs(struct 
>> coresight_device *csdev)
>> ????? spin_lock_irqsave(&drvdata->spinlock, flags);
>> +??? /*
>> +???? * Since the sysfs buffer allocation and the hardware enablement 
>> is not
>> +???? * in the same critical region, it's possible to race with the perf
>> +???? * mode:
>> +???? *?? [sysfs mode]?????????????????? [perf mode]
>> +???? *?? tmc_etr_get_sysfs_buffer()
>> +???? *???? spin_lock(&drvdata->spinlock)
>> +???? *???? [sysfs buffer allocation]
>> +???? *???? spin_unlock(&drvdata->spinlock)
>> +???? *????????????????????????????????? spin_lock(&drvdata->spinlock)
>> +???? *????????????????????????????????? tmc_etr_enable_hw()
>> +???? *??????????????????????????????????? drvdata->etr_buf = 
>> etr_perf->etr_buf
>> +???? *????????????????????????????????? spin_unlock(&drvdata->spinlock)
>> +???? *?? spin_lock(&drvdata->spinlock)
>> +???? *?? tmc_etr_enable_hw()
>> +???? *???? WARN_ON(drvdata->etr_buf) // WARN sicne etr_buf 
>> initialized at
>> +???? *????????????????????????????????? the perf side
>> +???? *?? spin_unlock(&drvdata->spinlock)
>> +???? *
>> +???? * So check here before continue.
>> +???? */
>> +??? if (coresight_get_mode(csdev) == CS_MODE_PERF) {
>> +??????? drvdata->sysfs_buf = NULL;
>> +??????? spin_unlock_irqrestore(&drvdata->spinlock, flags);
>> +
>> +??????? /* Free allocated memory out side of the spinlock */
>> +??????? tmc_etr_free_sysfs_buf(sysfs_buf);
>> +??????? return -EBUSY;
>> +??? }
> 
> With this in place, I think we should remove the check for CS_MODE_PERF 
> in get_etr_sysfs_buf() to avoid confusion (which I believe opened up 
> this race)
> 
> Suzuki
> 

Is it not simpler to set the mode to SYSFS before allocating the buffer 
in the first place? Then we don't need to free if it races and can't get 
into the intermediate state where it's a half initialized sysfs mode. 
The lock doesn't need to be held the whole time, just when setting the mode.

Or maybe to make it more consistent with etm4_enable() use 
coresight_take_mode() outside of the lock.

And then also clean up the perf mode check in get_etr_sysfs_buf().

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c 
b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..29c07832127b 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1219,13 +1219,17 @@ static int tmc_enable_etr_sink_sysfs(struct 
coresight_device *csdev)
         int ret = 0;
         unsigned long flags;
         struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-       struct etr_buf *sysfs_buf = tmc_etr_get_sysfs_buffer(csdev);
+       struct etr_buf *sysfs_buf;

+       spin_lock_irqsave(&drvdata->spinlock, flags);
+
+       if (coresight_get_mode(csdev) == CS_MODE_PERF)
+               return -EBUSY;
+
+       sysfs_buf = tmc_etr_get_sysfs_buffer(csdev);
         if (IS_ERR(sysfs_buf))
                 return PTR_ERR(sysfs_buf);

-       spin_lock_irqsave(&drvdata->spinlock, flags);
-
         /*
          * In sysFS mode we can have multiple writers per sink.  Since this
          * sink is already enabled no memory is needed and the HW need 
not be




From frank-w at public-files.de  Mon Dec  2 03:19:31 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Mon, 2 Dec 2024 12:19:31 +0100
Subject: Aw: Re: [PATCH v1 1/3] arm64: dts: marvell: Fix anyOf conditional
 failed
In-Reply-To: <20241111203611.GB1887580-robh@kernel.org>
References: <20241109094623.37518-1-linux@fw-web.de>
 <20241109094623.37518-2-linux@fw-web.de>
 <20241111203611.GB1887580-robh@kernel.org>
Message-ID: <trinity-796b046d-1857-413e-bb82-78e700d6b5ac-1733138371404@msvc-mesg-gmx005>

Hi,

just a gentle ping to have it finally merged

regards Frank


From s.hauer at pengutronix.de  Mon Dec  2 03:22:29 2024
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 02 Dec 2024 12:22:29 +0100
Subject: [PATCH v2 1/4] nvmem: imx-ocotp-ele: simplify read beyond device
 check
In-Reply-To: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
References: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
Message-ID: <20241202-imx-ele-ocotp-fixes-v2-1-3c021a97eb5d@pengutronix.de>

Do the read beyond device check on function entry in bytes instead of
32bit words which is easier to follow.

Fixes: 22e9e6fcfb504 ("nvmem: imx: support i.MX93 OCOTP")
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Cc: stable <stable at kernel.org>
---
 drivers/nvmem/imx-ocotp-ele.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index 1ba4944976987..2e186b7d3b040 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -72,13 +72,13 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 	void *p;
 	int i;
 
+	if (offset + bytes > priv->data->size)
+		bytes = priv->data->size - offset;
+
 	index = offset;
 	num_bytes = round_up(bytes, 4);
 	count = num_bytes >> 2;
 
-	if (count > ((priv->data->size >> 2) - index))
-		count = (priv->data->size >> 2) - index;
-
 	p = kzalloc(num_bytes, GFP_KERNEL);
 	if (!p)
 		return -ENOMEM;

-- 
2.39.5



From s.hauer at pengutronix.de  Mon Dec  2 03:22:31 2024
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 02 Dec 2024 12:22:31 +0100
Subject: [PATCH v2 3/4] nvmem: imx-ocotp-ele: fix MAC address byte order
In-Reply-To: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
References: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
Message-ID: <20241202-imx-ele-ocotp-fixes-v2-3-3c021a97eb5d@pengutronix.de>

According to the i.MX93 Fusemap the two MAC addresses are stored in
words 315 to 317 like this:

315	MAC1_ADDR_31_0[31:0]
316	MAC1_ADDR_47_32[47:32]
	MAC2_ADDR_15_0[15:0]
317	MAC2_ADDR_47_16[31:0]

This means the MAC addresses are stored in reverse byte order. We have
to swap the bytes before passing them to the upper layers. The storage
format is consistent to the one used on i.MX6 using imx-ocotp driver
which does the same byte swapping as introduced here.

With this patch the MAC address on my i.MX93 TQ board correctly reads as
00:d0:93:6b:27:b8 instead of b8:27:6b:93:d0:00.

Fixes: 22e9e6fcfb504 ("nvmem: imx: support i.MX93 OCOTP")
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Cc: stable <stable at kernel.org>
---
 drivers/nvmem/imx-ocotp-ele.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index b2d21a5f77bc1..422a6d53b10ef 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -111,6 +111,26 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 	return 0;
 };
 
+static int imx_ocotp_cell_pp(void *context, const char *id, int index,
+			     unsigned int offset, void *data, size_t bytes)
+{
+	u8 *buf = data;
+	int i;
+
+	/* Deal with some post processing of nvmem cell data */
+	if (id && !strcmp(id, "mac-address"))
+		for (i = 0; i < bytes / 2; i++)
+			swap(buf[i], buf[bytes - i - 1]);
+
+	return 0;
+}
+
+static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
+					 struct nvmem_cell_info *cell)
+{
+	cell->read_post_process = imx_ocotp_cell_pp;
+}
+
 static int imx_ele_ocotp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -137,6 +157,8 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	priv->config.stride = 1;
 	priv->config.priv = priv;
 	priv->config.read_only = true;
+	priv->config.add_legacy_fixed_of_cells = true;
+	priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
 	mutex_init(&priv->lock);
 
 	nvmem = devm_nvmem_register(dev, &priv->config);

-- 
2.39.5



From ryan.roberts at arm.com  Mon Dec  2 03:42:05 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 2 Dec 2024 11:42:05 +0000
Subject: [PATCH] arm64/mm: Replace open encodings with PXD_TABLE_BIT
In-Reply-To: <20241202083850.73207-1-anshuman.khandual@arm.com>
References: <20241202083850.73207-1-anshuman.khandual@arm.com>
Message-ID: <85b1bf12-54cc-4d17-9aa1-ab496cb04d36@arm.com>

On 02/12/2024 08:38, Anshuman Khandual wrote:
> [pgd|p4d]_bad() helpers have open encodings for their respective table bits
> which can be replaced with corresponding macros. This makes things clearer,
> thus improving their readability as well.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Ryan Roberts <ryan.roberts at arm.com>
> 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>

Reviewed-by: Ryan Roberts <ryan.roberts at arm.com>

> ---
> This patch applies on v6.13-rc1
> 
>  arch/arm64/include/asm/pgtable.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 6986345b537a..e20b80229910 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -896,7 +896,7 @@ static inline bool mm_pud_folded(const struct mm_struct *mm)
>  	pr_err("%s:%d: bad pud %016llx.\n", __FILE__, __LINE__, pud_val(e))
>  
>  #define p4d_none(p4d)		(pgtable_l4_enabled() && !p4d_val(p4d))
> -#define p4d_bad(p4d)		(pgtable_l4_enabled() && !(p4d_val(p4d) & 2))
> +#define p4d_bad(p4d)		(pgtable_l4_enabled() && !(p4d_val(p4d) & P4D_TABLE_BIT))
>  #define p4d_present(p4d)	(!p4d_none(p4d))
>  
>  static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
> @@ -1023,7 +1023,7 @@ static inline bool mm_p4d_folded(const struct mm_struct *mm)
>  	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_bad(pgd)		(pgtable_l5_enabled() && !(pgd_val(pgd) & PGD_TABLE_BIT))
>  #define pgd_present(pgd)	(!pgd_none(pgd))
>  
>  static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)



From wahrenst at gmx.net  Mon Dec  2 03:46:27 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon,  2 Dec 2024 12:46:27 +0100
Subject: [PATCH V6] dmaengine: bcm2835-dma: add suspend/resume pm support
Message-ID: <20241202114627.33401-1-wahrenst@gmx.net>

bcm2835-dma provides the service to others, so it should
suspend late and resume early.

Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/dma/bcm2835-dma.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

 Changes in V6:
 - split out of series because there is no dependency

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 7ba52dee40a9..cf8a01a5b884 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -875,6 +875,35 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
 	return chan;
 }

+static int bcm2835_dma_suspend_late(struct device *dev)
+{
+	struct bcm2835_dmadev *od = dev_get_drvdata(dev);
+	struct bcm2835_chan *c, *next;
+
+	list_for_each_entry_safe(c, next, &od->ddev.channels,
+				 vc.chan.device_node) {
+		void __iomem *chan_base = c->chan_base;
+
+		if (readl(chan_base + BCM2835_DMA_ADDR)) {
+			dev_warn(dev, "Suspend is prevented by chan %d\n",
+				 c->ch);
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static int bcm2835_dma_resume_early(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops bcm2835_dma_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late,
+				     bcm2835_dma_resume_early)
+};
+
 static int bcm2835_dma_probe(struct platform_device *pdev)
 {
 	struct bcm2835_dmadev *od;
@@ -1033,6 +1062,7 @@ static struct platform_driver bcm2835_dma_driver = {
 	.driver = {
 		.name = "bcm2835-dma",
 		.of_match_table = of_match_ptr(bcm2835_dma_of_match),
+		.pm = pm_ptr(&bcm2835_dma_pm_ops),
 	},
 };

--
2.34.1



From dmitry.baryshkov at linaro.org  Mon Dec  2 03:52:57 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 2 Dec 2024 13:52:57 +0200
Subject: [PATCH v3 05/11] dt-bindings: clock: Add Qualcomm QCS615 Display
 clock controller
In-Reply-To: <74e5b8b5-ee09-4fb5-9643-14ea11c445e5@quicinc.com>
References: <20241108-qcs615-mm-clockcontroller-v3-0-7d3b2d235fdf@quicinc.com>
 <20241108-qcs615-mm-clockcontroller-v3-5-7d3b2d235fdf@quicinc.com>
 <173104478441.565041.9851772057058427001.robh@kernel.org>
 <s5rie2osuh2ngkwd2jinly7ulogqqeqois724h3e54a7rqrn2w@wn3yypxi7wca>
 <74e5b8b5-ee09-4fb5-9643-14ea11c445e5@quicinc.com>
Message-ID: <afbxakprrm62hnlirqr3244wuf4zzlureejlce76av5xyqsuyy@gadkbshd3dam>

On Mon, Dec 02, 2024 at 01:05:54PM +0530, Taniya Das wrote:
> 
> 
> On 11/8/2024 5:09 PM, Krzysztof Kozlowski wrote:
> > > dtschema/dtc warnings/errors:
> > > Documentation/devicetree/bindings/clock/qcom,qcs615-dispcc.example.dts:19:18: fatal error: dt-bindings/clock/qcom,qcs615-gcc.h: No such file or directory
> > >     19 |         #include <dt-bindings/clock/qcom,qcs615-gcc.h>
> > >        |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > compilation terminated.
> > > make[2]: *** [scripts/Makefile.dtbs:129: Documentation/devicetree/bindings/clock/qcom,qcs615-dispcc.example.dtb] Error 1
> > > make[2]: *** Waiting for unfinished jobs....
> > > make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1442: dt_binding_check] Error 2
> > > make: *** [Makefile:224: __sub-make] Error 2
> > > 
> > > doc reference errors (make refcheckdocs):
> > > 
> > > Seehttps://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241108-qcs615-mm-clockcontroller-v3-5-7d3b2d235fdf at quicinc.com
> > > 
> > > The base for the series is generally the latest rc1. A different dependency
> > > should be noted in*this*  patch.
> > I see this patchset being sent again without changes and receiving same
> > errors again, so maybe you expect different results, like some review? I
> > don't know, but just in case that's the case please carefully read
> > message you got.
> > 
> > If lack of review is expected, then of course no problem here.
> 
> The base patch dependency(GCC) clock controller was mentioned in the cover
> letter:
> https://lore.kernel.org/all/20241022-qcs615-clock-driver-v4-0-3d716ad0d987 at quicinc.com/
> 
> Thanks, I will keep a note to notify reviewers explicitly mentioning the
> dependency.

This is usually being solved by:
- specifying correct base id and prerequisites in b4 prep --edit-deps,
- using ephemeral DT nodes in the bindings examples.

I think either of the options could have worked here. I don't know if
the bot picks up prerequisites from the cover letter, but even if it
doesn't, the issue is on its side, not on yours. However we still see
the same issue on and on. Could you please update the internal
guidelines on writing DT bindings so that the issue of (not) using
bindings of (other) clock controllers gets handled there?

-- 
With best wishes
Dmitry


From lkp at intel.com  Mon Dec  2 03:50:11 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 2 Dec 2024 19:50:11 +0800
Subject: [PATCH] pinctrl: mediatek: add eint new design for mt8196
In-Reply-To: <20241202085024.25375-1-ot_chhao.chang@mediatek.com>
References: <20241202085024.25375-1-ot_chhao.chang@mediatek.com>
Message-ID: <202412021959.txWIlGI0-lkp@intel.com>

Hi chang,

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 linus/master v6.13-rc1 next-20241128]
[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/chang-hao/pinctrl-mediatek-add-eint-new-design-for-mt8196/20241202-165544
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
patch link:    https://lore.kernel.org/r/20241202085024.25375-1-ot_chhao.chang%40mediatek.com
patch subject: [PATCH] pinctrl: mediatek: add eint new design for mt8196
config: x86_64-buildonly-randconfig-004-20241202 (https://download.01.org/0day-ci/archive/20241202/202412021959.txWIlGI0-lkp at intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241202/202412021959.txWIlGI0-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/202412021959.txWIlGI0-lkp at intel.com/

All error/warnings (new ones prefixed by >>):

>> drivers/pinctrl/mediatek/mtk-eint.c:246:6: warning: no previous prototype for function 'mt6983_eint_ack' [-Wmissing-prototypes]
     246 | void mt6983_eint_ack(struct irq_data *d)
         |      ^
   drivers/pinctrl/mediatek/mtk-eint.c:246:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
     246 | void mt6983_eint_ack(struct irq_data *d)
         | ^
         | static 
>> drivers/pinctrl/mediatek/mtk-eint.c:605:2: error: call to undeclared function 'dsb'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     605 |         dsb(sy);
         |         ^
>> drivers/pinctrl/mediatek/mtk-eint.c:605:6: error: use of undeclared identifier 'sy'
     605 |         dsb(sy);
         |             ^
   drivers/pinctrl/mediatek/mtk-eint.c:626:2: error: call to undeclared function 'dsb'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     626 |         dsb(sy);
         |         ^
   drivers/pinctrl/mediatek/mtk-eint.c:626:6: error: use of undeclared identifier 'sy'
     626 |         dsb(sy);
         |             ^
>> drivers/pinctrl/mediatek/mtk-eint.c:704:14: warning: no previous prototype for function 'mtk_eint_get_debounce_en' [-Wmissing-prototypes]
     704 | unsigned int mtk_eint_get_debounce_en(struct mtk_eint *eint,
         |              ^
   drivers/pinctrl/mediatek/mtk-eint.c:704:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
     704 | unsigned int mtk_eint_get_debounce_en(struct mtk_eint *eint,
         | ^
         | static 
>> drivers/pinctrl/mediatek/mtk-eint.c:727:14: warning: no previous prototype for function 'mtk_eint_get_debounce_value' [-Wmissing-prototypes]
     727 | unsigned int mtk_eint_get_debounce_value(struct mtk_eint *eint,
         |              ^
   drivers/pinctrl/mediatek/mtk-eint.c:727:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
     727 | unsigned int mtk_eint_get_debounce_value(struct mtk_eint *eint,
         | ^
         | static 
   3 warnings and 4 errors generated.


vim +/dsb +605 drivers/pinctrl/mediatek/mtk-eint.c

   589	
   590	int mtk_eint_do_suspend(struct mtk_eint *eint)
   591	{
   592		unsigned int i, j, port;
   593	
   594		for (i = 0; i < eint->instance_number; i++) {
   595			struct mtk_eint_instance inst = eint->instances[i];
   596	
   597			for (j = 0; j < inst.number; j += 32) {
   598				port = j >> 5;
   599				writel_relaxed(~inst.wake_mask[port],
   600					       inst.base + port * 4 + eint->comp->regs->mask_set);
   601				writel_relaxed(inst.wake_mask[port],
   602					       inst.base + port * 4 + eint->comp->regs->mask_clr);
   603			}
   604		}
 > 605		dsb(sy);
   606	
   607		return 0;
   608	}
   609	EXPORT_SYMBOL_GPL(mtk_eint_do_suspend);
   610	
   611	int mtk_eint_do_resume(struct mtk_eint *eint)
   612	{
   613		unsigned int i, j, port;
   614	
   615		for (i = 0; i < eint->instance_number; i++) {
   616			struct mtk_eint_instance inst = eint->instances[i];
   617	
   618			for (j = 0; j < inst.number; j += 32) {
   619				port = j >> 5;
   620				writel_relaxed(~inst.cur_mask[port],
   621					       inst.base + port * 4 + eint->comp->regs->mask_set);
   622				writel_relaxed(inst.cur_mask[port],
   623					       inst.base + port * 4 + eint->comp->regs->mask_clr);
   624			}
   625		}
   626		dsb(sy);
   627	
   628		return 0;
   629	}
   630	EXPORT_SYMBOL_GPL(mtk_eint_do_resume);
   631	
   632	int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
   633				  unsigned int debounce)
   634	{
   635		int virq, eint_offset;
   636		unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask,
   637			     dbnc;
   638		static const unsigned int debounce_time[] = { 156, 313, 625, 1250,
   639			20000, 40000, 80000, 160000, 320000, 640000 };
   640		struct irq_data *d;
   641		unsigned int instance, index;
   642		void __iomem *reg;
   643	
   644		/*
   645		 * Due to different number of bit field, we only decode
   646		 * the coordinate here, instead of get the VA.
   647		 */
   648		reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
   649					  &instance, &index);
   650	
   651		if (!reg) {
   652			dev_err(eint->dev, "%s invalid eint_num %lu\n",
   653				__func__, eint_num);
   654			return 0;
   655		}
   656	
   657		virq = irq_find_mapping(eint->domain, eint_num);
   658		eint_offset = (index % 4) * 8;
   659		d = irq_get_irq_data(virq);
   660	
   661		reg = eint->instances[instance].base;
   662		set_offset = (index / 4) * 4 + eint->comp->regs->dbnc_set;
   663		clr_offset = (index / 4) * 4 + eint->comp->regs->dbnc_clr;
   664	
   665		if (!mtk_eint_can_en_debounce(eint, eint_num))
   666			return -EINVAL;
   667	
   668		/*
   669		 * Check eint number to avoid access out-of-range
   670		 */
   671		dbnc = ARRAY_SIZE(debounce_time) - 1;
   672		for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
   673			if (debounce <= debounce_time[i]) {
   674				dbnc = i;
   675				break;
   676			}
   677		}
   678	
   679		if (!mtk_eint_get_mask(eint, eint_num)) {
   680			mtk_eint_mask(d);
   681			unmask = 1;
   682		} else {
   683			unmask = 0;
   684		}
   685	
   686		clr_bit = 0xff << eint_offset;
   687		writel(clr_bit, reg + clr_offset);
   688	
   689		bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS)
   690			| MTK_EINT_DBNC_SET_EN) << eint_offset;
   691		rst = MTK_EINT_DBNC_RST_BIT << eint_offset;
   692		writel(rst | bit, reg + set_offset);
   693	
   694		/* Delay should be (8T @ 32k) from dbc rst to work correctly. */
   695		udelay(250);
   696	
   697		if (unmask == 1)
   698			mtk_eint_unmask(d);
   699	
   700		return 0;
   701	}
   702	EXPORT_SYMBOL_GPL(mtk_eint_set_debounce);
   703	
 > 704	unsigned int mtk_eint_get_debounce_en(struct mtk_eint *eint,
   705					      unsigned int eint_num)
   706	{
   707		unsigned int instance, index, bit;
   708		void __iomem *reg;
   709	
   710		reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
   711					  &instance, &index);
   712	
   713		if (!reg) {
   714			dev_err(eint->dev, "%s invalid eint_num %d\n",
   715				__func__, eint_num);
   716			return 0;
   717		}
   718	
   719		reg = eint->instances[instance].base +
   720			(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
   721	
   722		bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
   723	
   724		return (readl(reg) & bit) ? 1 : 0;
   725	}
   726	
 > 727	unsigned int mtk_eint_get_debounce_value(struct mtk_eint *eint,
   728						 unsigned int eint_num)
   729	{
   730		unsigned int instance, index, mask, offset;
   731		void __iomem *reg;
   732	
   733		reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
   734					  &instance, &index);
   735	
   736		if (!reg) {
   737			dev_err(eint->dev, "%s invalid eint_num %d\n",
   738				__func__, eint_num);
   739			return 0;
   740		}
   741	
   742		reg = eint->instances[instance].base +
   743			(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
   744	
   745		offset = MTK_EINT_DBNC_SET_DBNC_BITS + ((index % 4) * 8);
   746		mask = 0xf << offset;
   747	
   748		return ((readl(reg) & mask) >> offset);
   749	}
   750	

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


From wahrenst at gmx.net  Mon Dec  2 03:51:40 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon,  2 Dec 2024 12:51:40 +0100
Subject: [PATCH V6] mmc: bcm2835: add suspend/resume pm support
Message-ID: <20241202115140.33492-1-wahrenst@gmx.net>

Add a minimalistic suspend/resume PM support.

Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/mmc/host/bcm2835.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Changes in V6:
- split out of series because there is no dependency
- remove unnecessary complete check

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index 7847f0c8b465..e5f151d092cd 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -1343,6 +1343,25 @@ static int bcm2835_add_host(struct bcm2835_host *host)
 	return 0;
 }

+static int bcm2835_suspend(struct device *dev)
+{
+	struct bcm2835_host *host = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(host->clk);
+
+	return 0;
+}
+
+static int bcm2835_resume(struct device *dev)
+{
+	struct bcm2835_host *host = dev_get_drvdata(dev);
+
+	return clk_prepare_enable(host->clk);
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(bcm2835_pm_ops, bcm2835_suspend,
+				bcm2835_resume);
+
 static int bcm2835_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1471,6 +1490,7 @@ static struct platform_driver bcm2835_driver = {
 		.name		= "sdhost-bcm2835",
 		.probe_type	= PROBE_PREFER_ASYNCHRONOUS,
 		.of_match_table	= bcm2835_match,
+		.pm = pm_ptr(&bcm2835_pm_ops),
 	},
 };
 module_platform_driver(bcm2835_driver);
--
2.34.1



From ryan.roberts at arm.com  Mon Dec  2 03:52:59 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 2 Dec 2024 11:52:59 +0000
Subject: [PATCH] arm64/mm: Ensure adequate HUGE_MAX_HSTATE
In-Reply-To: <20241202064407.53807-1-anshuman.khandual@arm.com>
References: <20241202064407.53807-1-anshuman.khandual@arm.com>
Message-ID: <7c49fa2c-b732-4b82-a853-22fdf241d361@arm.com>

On 02/12/2024 06:44, Anshuman Khandual wrote:
> This asserts that HUGE_MAX_HSTATE is sufficient enough preventing potential
> hugetlb_max_hstate runtime overflow in hugetlb_add_hstate() thus triggering
> a BUG_ON() there after.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Ryan Roberts <ryan.roberts at arm.com>
> 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 patch applies on v6.13-rc1
> 
>  arch/arm64/mm/hugetlbpage.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 3215adf48a1b..98a2a0e64e25 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -519,6 +519,18 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
>  
>  static int __init hugetlbpage_init(void)
>  {
> +	/*
> +	 * HugeTLB pages are supported on maximum four page table
> +	 * levels (PUD, CONT PMD, PMD, CONT PTE) for a given base
> +	 * page size, corresponding to hugetlb_add_hstate() calls
> +	 * here.
> +	 *
> +	 * HUGE_MAX_HSTATE should at least match maximum supported
> +	 * HugeTLB page sizes on the platform. Any new addition to
> +	 * supported HugeTLB page sizes will also require changing
> +	 * HUGE_MAX_HSTATE as well.
> +	 */
> +	BUILD_BUG_ON(HUGE_MAX_HSTATE < 4);

I guess we only technically need 3 if pud_sect_supported() == false ? Although
for simplicity (and to reduce my rebasing effort for boot-time page size :) ),
agree we should always just compare to 4.

Reviewed-by: Ryan Roberts <ryan.roberts at arm.com>

>  	if (pud_sect_supported())
>  		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
>  



From wahrenst at gmx.net  Mon Dec  2 03:54:37 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon,  2 Dec 2024 12:54:37 +0100
Subject: [PATCH] irqchip/bcm2836: Enable SKIP_SET_WAKE and MASK_ON_SUSPEND
Message-ID: <20241202115437.33552-1-wahrenst@gmx.net>

The BCM2836 interrupt controller doesn't provide any facility to
configure the wakeup sources. That's the reason why the driver lacks
the irq_set_wake() callback for the interrupt chip.

Enable the flags IRQCHIP_SKIP_SET_WAKE and IRQCHIP_MASK_ON_SUSPEND so
the interrupt suspend logic can handle the chip correctly.

This was inspired by the patch series "irqchip/irq-bcm283x update
for BCM7211" by Florian Fainelli.

Link: https://lore.kernel.org/lkml/20191001224842.9382-1-f.fainelli at gmail.com/
Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/irqchip/irq-bcm2836.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index e5f1059b989f..e366257684b5 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -58,6 +58,7 @@ static struct irq_chip bcm2836_arm_irqchip_timer = {
 	.name		= "bcm2836-timer",
 	.irq_mask	= bcm2836_arm_irqchip_mask_timer_irq,
 	.irq_unmask	= bcm2836_arm_irqchip_unmask_timer_irq,
+	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
 };

 static void bcm2836_arm_irqchip_mask_pmu_irq(struct irq_data *d)
@@ -74,6 +75,7 @@ static struct irq_chip bcm2836_arm_irqchip_pmu = {
 	.name		= "bcm2836-pmu",
 	.irq_mask	= bcm2836_arm_irqchip_mask_pmu_irq,
 	.irq_unmask	= bcm2836_arm_irqchip_unmask_pmu_irq,
+	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
 };

 static void bcm2836_arm_irqchip_mask_gpu_irq(struct irq_data *d)
@@ -88,6 +90,7 @@ static struct irq_chip bcm2836_arm_irqchip_gpu = {
 	.name		= "bcm2836-gpu",
 	.irq_mask	= bcm2836_arm_irqchip_mask_gpu_irq,
 	.irq_unmask	= bcm2836_arm_irqchip_unmask_gpu_irq,
+	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
 };

 static void bcm2836_arm_irqchip_dummy_op(struct irq_data *d)
--
2.34.1



From wahrenst at gmx.net  Mon Dec  2 03:58:32 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon,  2 Dec 2024 12:58:32 +0100
Subject: [PATCH] hwmon: raspberrypi: add PM suspend/resume support
Message-ID: <20241202115832.33628-1-wahrenst@gmx.net>

Add suspend/resume handler in order to stop firmware polling
during s2idle. This was just waking-up the system without a real
benefit.

Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/hwmon/raspberrypi-hwmon.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/hwmon/raspberrypi-hwmon.c b/drivers/hwmon/raspberrypi-hwmon.c
index 10ef1e1f9458..a2938881ccd2 100644
--- a/drivers/hwmon/raspberrypi-hwmon.c
+++ b/drivers/hwmon/raspberrypi-hwmon.c
@@ -128,10 +128,32 @@ static int rpi_hwmon_probe(struct platform_device *pdev)
 	return 0;
 }

+static int rpi_hwmon_suspend(struct device *dev)
+{
+	struct rpi_hwmon_data *data = dev_get_drvdata(dev);
+
+	cancel_delayed_work_sync(&data->get_values_poll_work);
+
+	return 0;
+}
+
+static int rpi_hwmon_resume(struct device *dev)
+{
+	struct rpi_hwmon_data *data = dev_get_drvdata(dev);
+
+	get_values_poll(&data->get_values_poll_work.work);
+
+	return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(rpi_hwmon_pm_ops, rpi_hwmon_suspend,
+				rpi_hwmon_resume);
+
 static struct platform_driver rpi_hwmon_driver = {
 	.probe = rpi_hwmon_probe,
 	.driver = {
 		.name = "raspberrypi-hwmon",
+		.pm = pm_ptr(&rpi_hwmon_pm_ops),
 	},
 };
 module_platform_driver(rpi_hwmon_driver);
--
2.34.1



From pavel at denx.de  Mon Dec  2 04:01:11 2024
From: pavel at denx.de (Pavel Machek)
Date: Mon, 2 Dec 2024 13:01:11 +0100
Subject: [PATCH AUTOSEL 5.10 4/6] ASoC: stm: Prevent potential division
 by zero in stm32_sai_mclk_round_rate()
In-Reply-To: <20241112103803.1654174-4-sashal@kernel.org>
References: <20241112103803.1654174-1-sashal@kernel.org>
 <20241112103803.1654174-4-sashal@kernel.org>
Message-ID: <Z02hh/K7okT4fvOc@duo.ucw.cz>

Hi!

> [ Upstream commit 63c1c87993e0e5bb11bced3d8224446a2bc62338 ]
> 
> This patch checks if div is less than or equal to zero (div <= 0). If
> div is zero or negative, the function returns -EINVAL, ensuring the
> division operation (*prate / div) is safe to perform.

Well, previous version propagated error code, now it is eaten. Is
stm32_sai_get_clk_div returning 0?

BR,
								Pavel

> Signed-off-by: Luo Yifan <luoyifan at cmss.chinamobile.com>
> Link: https://patch.msgid.link/20241106014654.206860-1-luoyifan at cmss.chinamobile.com
> Signed-off-by: Mark Brown <broonie at kernel.org>
> Signed-off-by: Sasha Levin <sashal at kernel.org>
> ---
>  sound/soc/stm/stm32_sai_sub.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
> index 3aa1cf2624020..3a7f0102b4c5c 100644
> --- a/sound/soc/stm/stm32_sai_sub.c
> +++ b/sound/soc/stm/stm32_sai_sub.c
> @@ -380,8 +380,8 @@ static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate,
>  	int div;
>  
>  	div = stm32_sai_get_clk_div(sai, *prate, rate);
> -	if (div < 0)
> -		return div;
> +	if (div <= 0)
> +		return -EINVAL;
>  
>  	mclk->freq = *prate / div;
>  

-- 
DENX Software Engineering GmbH,        Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241202/27030ff8/attachment.sig>

From mripard at kernel.org  Mon Dec  2 04:00:23 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 2 Dec 2024 13:00:23 +0100
Subject: [PATCH 00/10] drm/connector: add eld_mutex to protect
 connector->eld
In-Reply-To: <ohbtatnn33jj6y3q4milf4txi4n7yirnny2eefdjddlkn2dnhp@eqjedetct4q3>
References: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
 <77545786331df8bfaf5fdcb309437358@kernel.org>
 <ohbtatnn33jj6y3q4milf4txi4n7yirnny2eefdjddlkn2dnhp@eqjedetct4q3>
Message-ID: <20241202-hummingbird-of-hypothetical-aptitude-646def@houat>

On Mon, Dec 02, 2024 at 01:03:07PM +0200, Dmitry Baryshkov wrote:
> On Mon, Dec 02, 2024 at 10:19:41AM +0000, Maxime Ripard wrote:
> > On Sun, 1 Dec 2024 01:55:17 +0200, Dmitry Baryshkov wrote:
> > > The connector->eld is accessed by the .get_eld() callback. This access
> > > can collide with the drm_edid_to_eld() updating the data at the same
> > > time. Add drm_connector.eld_mutex to protect the data from concurrenct
> > > access.
> > > 
> > > 
> > > [ ... ]
> > 
> > Reviewed-by: Maxime Ripard <mripard at kernel.org>
> 
> Thanks!
> 
> I'm going to post v2 to fix Jani's comment, but what should be the merge
> strategy? Merge patches 1-3, 5, 9-10 through drm-misc and the rest (AMD,
> i915, MSM, radeon) through the driver trees?

The easiest is probably to merge everything through drm-misc if everyone agrees.

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

From didi.debian at cknow.org  Mon Dec  2 04:01:09 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Mon, 02 Dec 2024 13:01:09 +0100
Subject: [PATCH] arm64: dts: rockchip: enable rng on all rk356x
In-Reply-To: <b50376c7-c5d5-41ae-95ea-e2d68c1cc809@linaro.org>
References: <20241201234613.52322-1-pbrobinson@gmail.com>
 <302bdae2f4defeefe88ea4018a0be11f@manjaro.org>
 <b50376c7-c5d5-41ae-95ea-e2d68c1cc809@linaro.org>
Message-ID: <D6175VTSP13T.200HWIIHOIDQQ@cknow.org>

On Mon Dec 2, 2024 at 11:40 AM CET, Marcin Juszkiewicz wrote:
> W dniu 2.12.2024 o 04:55, Dragan Simic pisze:
>  > On 2024-12-02 00:46, Peter Robinson wrote:
>  >> The rk356x rng is available on both the rk3566 and rk3568
>  >> parts, the IP is all self contained within the SoCs so
>  >> it's enabled already by default on rk3568 so let's enable
>  >> it in the base rk356x.dtsi so it's enabled consistently
>  >> everywhere.
>  >
>  > Please, go through the mailing list threads [1][2] that have led us
>  > to the current state.  To sum it up, it isn't about what's supported
>  > in the two RK356x SoC variants, but about the RK3566's HWRNG being
>  > disabled because the testing showed that it produces unacceptably
>  > low quality of random data, for some yet unknown reason.
>
> So maybe there should be a comment in rockchip/rk3568.dtsi so we would 
> not get back to it again.

I suggested to put that in the (original) commit message:
https://lore.kernel.org/linux-rockchip/6690040.iosknibmi9 at bagend/
precisely because this was quite predictable to happen.

So a +1 on a comment in the dtsi with a link to the discussion in the
commit message.
-------------- 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/20241202/a6c5c34e/attachment.sig>

From pavel at denx.de  Mon Dec  2 04:04:57 2024
From: pavel at denx.de (Pavel Machek)
Date: Mon, 2 Dec 2024 13:04:57 +0100
Subject: [PATCH AUTOSEL 5.10 4/5] kselftest/arm64: Corrupt P0 in the
 irritator when testing SSVE
In-Reply-To: <20241124124210.3337020-4-sashal@kernel.org>
References: <20241124124210.3337020-1-sashal@kernel.org>
 <20241124124210.3337020-4-sashal@kernel.org>
Message-ID: <Z02iaXudPt42mby+@duo.ucw.cz>

Hi!

> From: Mark Brown <broonie at kernel.org>
> 
> [ Upstream commit 3e360ef0c0a1fb6ce9a302e40b8057c41ba8a9d2 ]
> 
> When building for streaming SVE the irritator for SVE skips updates of both
> P0 and FFR. While FFR is skipped since it might not be present there is no
> reason to skip corrupting P0 so switch to an instruction valid in streaming
> mode and move the ifdef.

This is mismerged. Original patch moves #ifdef. How did AUTOSEL came
up with this?

Best regards,
								Pavel

> +++ b/tools/testing/selftests/arm64/fp/sve-test.S
> @@ -459,7 +459,8 @@ function irritator_handler
>  	movi	v9.16b, #2
>  	movi	v31.8b, #3
>  	// And P0
> -	rdffr	p0.b
> +	ptrue	p0.d
> +#ifndef SSVE
>  	// And FFR
>  	wrffr	p15.b
>  

-- 
DENX Software Engineering GmbH,        Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241202/3449175b/attachment.sig>

From mripard at kernel.org  Mon Dec  2 04:06:09 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 2 Dec 2024 13:06:09 +0100
Subject: [PATCH v5 2/9] ASoC: hdmi-codec: move no_capture_mute to struct
 hdmi_codec_pdata
In-Reply-To: <20241201-drm-bridge-hdmi-connector-v5-2-b5316e82f61a@linaro.org>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-2-b5316e82f61a@linaro.org>
Message-ID: <20241202-bald-just-guan-c5d41b@houat>

Hi,

On Sun, Dec 01, 2024 at 02:44:06AM +0200, Dmitry Baryshkov wrote:
> The no_capture_mute flag might differ from platform to platform,
> especially in the case of the wrapping implementations, like the
> upcoming DRM HDMI Codec framework. Move the flag next to all other flags
> in struct hdmi_codec_pdata.
> 
> Acked-by: Mark Brown <broonie at kernel.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

I appreciate it might be a dumb question, but I never really understood
what no_capture_mute was all about. And in that context, why some
drivers would need / use it, and some won't.

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

From pavel at denx.de  Mon Dec  2 04:09:50 2024
From: pavel at denx.de (Pavel Machek)
Date: Mon, 2 Dec 2024 13:09:50 +0100
Subject: [PATCH AUTOSEL 5.10 6/6] USB: gadget: pxa27x_udc: Avoid using
 GPIOF_ACTIVE_LOW
In-Reply-To: <20241124125742.3341086-6-sashal@kernel.org>
References: <20241124125742.3341086-1-sashal@kernel.org>
 <20241124125742.3341086-6-sashal@kernel.org>
Message-ID: <Z02jjnoqlvRw8YV0@duo.ucw.cz>

Hi!

> From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> 
> [ Upstream commit 62d2a940f29e6aa5a1d844a90820ca6240a99b34 ]
> 
> Avoid using GPIOF_ACTIVE_LOW as it's deprecated and subject to remove.

Well, we won't be removing it in -stable, so we don't need this.

Best regards,
								Pavel
								
> +++ b/drivers/usb/gadget/udc/pxa27x_udc.c
> @@ -2356,18 +2356,19 @@ static int pxa_udc_probe(struct platform_device *pdev)
>  	struct pxa_udc *udc = &memory;
>  	int retval = 0, gpio;
>  	struct pxa2xx_udc_mach_info *mach = dev_get_platdata(&pdev->dev);
> -	unsigned long gpio_flags;
>  
>  	if (mach) {
> -		gpio_flags = mach->gpio_pullup_inverted ? GPIOF_ACTIVE_LOW : 0;
>  		gpio = mach->gpio_pullup;
>  		if (gpio_is_valid(gpio)) {
>  			retval = devm_gpio_request_one(&pdev->dev, gpio,
> -						       gpio_flags,
> +						       GPIOF_OUT_INIT_LOW,
>  						       "USB D+ pullup");
>  			if (retval)
>  				return retval;
>  			udc->gpiod = gpio_to_desc(mach->gpio_pullup);
> +
> +			if (mach->gpio_pullup_inverted ^ gpiod_is_active_low(udc->gpiod))
> +				gpiod_toggle_active_low(udc->gpiod);
>  		}
>  		udc->udc_command = mach->udc_command;
>  	} else {

-- 
DENX Software Engineering GmbH,        Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241202/4b79f851/attachment.sig>

From dmitry.baryshkov at linaro.org  Mon Dec  2 04:11:00 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 2 Dec 2024 14:11:00 +0200
Subject: [PATCH v3 00/11] Add support for videocc, camcc, dispcc and
 gpucc on Qualcomm QCS615 platform
In-Reply-To: <bfabfba2-6688-4461-83d6-b6f4c86b08ab@quicinc.com>
References: <20241108-qcs615-mm-clockcontroller-v3-0-7d3b2d235fdf@quicinc.com>
 <a4f6ojknv3hats4rwmdg5mw2rxhx7kq4u6axybdawak54crn5s@xnjbl7zno42s>
 <bfabfba2-6688-4461-83d6-b6f4c86b08ab@quicinc.com>
Message-ID: <urlb2pn3cezyx7e6fxxf4j7psmf37amshnlzu7buixp6sxkrgy@mg4zljxn5s3v>

On Mon, Dec 02, 2024 at 01:09:12PM +0530, Taniya Das wrote:
> 
> 
> On 12/2/2024 9:55 AM, Bjorn Andersson wrote:
> > On Fri, Nov 08, 2024 at 09:39:17AM +0530, Taniya Das wrote:
> > > Add support for multimedia clock controllers on Qualcomm QCS615 platform.
> > > Update the defconfig to enable these clock controllers.
> > > 
> > > Global clock controller support
> > > https://lore.kernel.org/all/20241022-qcs615-clock-driver-v4-0-3d716ad0d987 at quicinc.com/
> > > 
> > > Signed-off-by: Taniya Das<quic_tdas at quicinc.com>
> > Dropping this series from my queue, due to lack of response from author.
> > 
> > Taniya, please answer questions/feedback from Dmitry, Vladimir and
> > Bryan, and repose as necessary.
> 
> Sure, Bjorn, I had a dependency on the GCC patch.
> 
> https://lore.kernel.org/all/20241022-qcs615-clock-driver-v4-0-3d716ad0d987 at quicinc.com/
> 
> I will fix the comments once the Global clock controller patch is picked.

I think this makes a good generic feedback (I observe the antipattern in
other engineer's behaviour too): please try responding to the comment
after receiving it, not just before getting back to the series.

For this particular case: there is no need to wait on GCC. Please stop
using the external dt-bindings header and use <&gcc_foo_clock> instead.
This is just an example, not a c&p from the platform's DT.


-- 
With best wishes
Dmitry


From smostafa at google.com  Mon Dec  2 04:12:17 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Mon, 2 Dec 2024 12:12:17 +0000
Subject: [PATCH 1/2] iommu/io-pgtable-arm: Fix stage-2 map/umap for
 concatenated tables
In-Reply-To: <CAE2F3rDyj8WohXHTa1H3_gqTndyJL3cUEfBnXCEibNo1oYTt3A@mail.gmail.com>
References: <20241024162516.2005652-1-smostafa@google.com>
 <20241024162516.2005652-2-smostafa@google.com>
 <CAE2F3rDyj8WohXHTa1H3_gqTndyJL3cUEfBnXCEibNo1oYTt3A@mail.gmail.com>
Message-ID: <Z02kIaxP96am-P2f@google.com>

Hi Daniel,

On Sat, Nov 30, 2024 at 08:20:10PM -0800, Daniel Mentz wrote:
> On Thu, Oct 24, 2024 at 9:26?AM Mostafa Saleh <smostafa at google.com> wrote:
> >
> > When calculating the max number of entries in a table, Where
> > RM_LPAE_LVL_IDX() understands the concatenated pgds and can return
> > an index spanning more than one concatenated table (for ex for 4K
> > page size > 512).
> > But then, max_entries is calculated as follows:
> > max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start;
> >
> > This leads to a negative index in the page table, where for:
> > - map: do nothing (no OOB) as fortunately all comparisons are signed,
> >   but it would return a negative mapped value.
> >
> > - unmap: it would leak any child tables as it skips the loop over
> >   ?__arm_lpae_free_pgtable?
> >
> > This bug only happens when map/unmap is requested with a page size
> > equals to the first level of the concatenated table (for 40 bits input
> > and 4K granule would be 1GB) and can be triggered from userspace with
> > VFIO, by choosing a VM IPA in a concatenated table > 0 and using
> > huge pages to mmap with the first level size.
> >
> > For example, I was able to reproduce it with the following command
> > with mainline linux and mainline kvmtool:
> >
> > ./lkvm run --irqchip gicv3 -k {$KERNEL} -p "earlycon" -d {$ROOTFS}  --force-pci -c \
> > `nproc` --debug -m 4096 at 525312 --vfio-pci 0000:00:03.0  --hugetlbfs  /hugepages
> >
> > Where huge pages with 1GB would be used and using IPA in the second table
> > (512GB for 40 bits SMMU and 4K granule).
> >
> > Signed-off-by: Mostafa Saleh <smostafa at google.com>
> > ---
> >  drivers/iommu/io-pgtable-arm.c | 17 ++++++++++++++---
> >  1 file changed, 14 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> > index 0e67f1721a3d..3ecbc024e440 100644
> > --- a/drivers/iommu/io-pgtable-arm.c
> > +++ b/drivers/iommu/io-pgtable-arm.c
> > @@ -199,6 +199,17 @@ static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
> >         return (paddr | (paddr << (48 - 12))) & (ARM_LPAE_PTE_ADDR_MASK << 4);
> >  }
> >
> > +/*
> > + * Using an index returned from ARM_LPAE_PGD_IDX(), which can point to
> > + * concatenated PGD concatenated, get the max entries of a that table.
> 
> I believe the macro that returns an index is called ARM_LPAE_LVL_IDX
> not ARM_LPAE_PGD_IDX.
> 

Yes, the comment is not quite accurate, although ARM_LPAE_PGD_IDX()
calls ARM_LPAE_PGD_IDX() which is the problem.

Thanks,
Mostafa

> > + */
> > +static inline int arm_lpae_max_entries(int i, struct arm_lpae_io_pgtable *data)
> > +{
> > +       int ptes_per_table = ARM_LPAE_PTES_PER_TABLE(data);
> > +
> > +       return ptes_per_table - (i & (ptes_per_table - 1));
> > +}
> > +
> >  static bool selftest_running = false;
> >
> >  static dma_addr_t __arm_lpae_dma_addr(void *pages)
> > @@ -390,7 +401,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
> >
> >         /* If we can install a leaf entry at this level, then do so */
> >         if (size == block_size) {
> > -               max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start;
> > +               max_entries = arm_lpae_max_entries(map_idx_start, data);
> >                 num_entries = min_t(int, pgcount, max_entries);
> >                 ret = arm_lpae_init_pte(data, iova, paddr, prot, lvl, num_entries, ptep);
> >                 if (!ret)
> > @@ -592,7 +603,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
> >
> >         if (size == split_sz) {
> >                 unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
> > -               max_entries = ptes_per_table - unmap_idx_start;
> > +               max_entries = arm_lpae_max_entries(unmap_idx_start, data);
> >                 num_entries = min_t(int, pgcount, max_entries);
> >         }
> >
> > @@ -650,7 +661,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
> >
> >         /* If the size matches this level, we're in the right place */
> >         if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) {
> > -               max_entries = ARM_LPAE_PTES_PER_TABLE(data) - unmap_idx_start;
> > +               max_entries = arm_lpae_max_entries(unmap_idx_start, data);
> >                 num_entries = min_t(int, pgcount, max_entries);
> >
> >                 /* Find and handle non-leaf entries */
> > --
> > 2.47.0.105.g07ac214952-goog
> >
> >


From u.kleine-koenig at baylibre.com  Mon Dec  2 04:20:27 2024
From: u.kleine-koenig at baylibre.com (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Mon, 2 Dec 2024 13:20:27 +0100
Subject: [PATCH] PM / devfreq: sun8i-a33-mbus: Simplify by using more
 devm functions
In-Reply-To: <20241111112237.336310-2-u.kleine-koenig@baylibre.com>
References: <20241111112237.336310-2-u.kleine-koenig@baylibre.com>
Message-ID: <7taeakaeqyfu4x5h3r6z6lkdorxav4ox2sgjikw7zqkmnfmffs@2n2lpk4uqe4l>

Hello,

On Mon, Nov 11, 2024 at 12:22:36PM +0100, Uwe Kleine-K?nig wrote:
> Use devm allocators for enabling the bus clock and
> clk_rate_exclusive_get(). This simplifies error handling and the remove
> callback.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>

Is this patch still on someones radar for review (or application even)?

Best regards
Uwe
-------------- 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/20241202/45e524f6/attachment.sig>

From linux at fw-web.de  Mon Dec  2 04:25:41 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:41 +0100
Subject: [PATCH v2 00/18] continue mt7988 devicetree work
Message-ID: <20241202122602.30734-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This series adds some missing labels and new nodes to mt7988 DTS.

based on pinctrl-series
https://patchwork.kernel.org/project/linux-mediatek/list/?series=913700

changes:
v2:
- reorder and squash label-commits to where they are used
- add some more nodes
- add changes to bananapi-r4 board
- moving some nodes from SoC dtsi to board dts

Frank Wunderlich (18):
  arm64: dts: mediatek: mt7988: enable watchdog on bpi-r4
  arm64: dts: mediatek: mt7988: add mmc support
  arm64: dts: mediatek: mt7988: add fixed regulators for 1v8 and 3v3
  arm64: dts: mediatek: mt7988: add lvts node
  arm64: dts: mediatek: mt7988: add thermal-zone
  arm64: dts: mediatek: mt7988: add thermal trips to bpi-r4
  arm64: dts: mediatek: mt7988: add reserved memory
  arm64: dts: mediatek: mt7988: add mcu-sys node for cpu
  arm64: dts: mediatek: mt7988: add operating-points
  arm64: dts: mediatek: mt7988: enable serial0 on bpi-r4
  arm64: dts: mediatek: mt7988: add chosen node on bpi-r4
  arm64: dts: mediatek: mt7988: add missing clock-div property for i2c
  arm64: dts: mediatek: mt7988: add i2c to bpi-r4 board
  arm64: dts: mediatek: mt7988: add pmic on bpi-r4
  arm64: dts: mediatek: mt7988: add proc-supply for cpus on bpi-r4
  arm64: dts: mediatek: mt7988: add i2c-mux on bpi-r4
  arm64: dts: mediatek: mt7988: enable ssusb1 on bpi-r4
  arm64: dts: mediatek: mt7988: enable pwm on bpi-r4

 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 186 ++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi     | 137 +++++++++++--
 2 files changed, 311 insertions(+), 12 deletions(-)

-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:44 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:44 +0100
Subject: [PATCH v2 03/18] arm64: dts: mediatek: mt7988: add fixed regulators for 1v8 and 3v3
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-4-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add regulator nodes used for mmc to Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
v2:
- move mmc regulators to board dts of bpi-r4
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts   | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index d914eae2b524..df53512c6890 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -8,6 +8,24 @@ / {
 	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
 	model = "Banana Pi BPI-R4";
 	chassis-type = "embedded";
+
+	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;
+	};
 };
 
 &pio {
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:45 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:45 +0100
Subject: [PATCH v2 04/18] arm64: dts: mediatek: mt7988: add lvts node
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-5-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add Low Voltage Thermal Sensor (LVTS) node for mt7988 SoC.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
changes:

v2:
squash
- "arm64: dts: mediatek: mt7988: add label for efuse"
- "arm64: dts: mediatek: mt7988: extend efuse node" (drop other efuse subnodes)
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 5e40446cb7b3..f7748a840297 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -4,6 +4,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/pinctrl/mt65xx.h>
+#include <dt-bindings/reset/mediatek,mt7988-resets.h>
 
 / {
 	compatible = "mediatek,mt7988a";
@@ -85,6 +86,7 @@ infracfg: clock-controller at 10001000 {
 			compatible = "mediatek,mt7988-infracfg", "syscon";
 			reg = <0 0x10001000 0 0x1000>;
 			#clock-cells = <1>;
+			#reset-cells = <1>;
 		};
 
 		topckgen: clock-controller at 1001b000 {
@@ -250,6 +252,17 @@ i2c at 11005000 {
 			status = "disabled";
 		};
 
+		lvts: lvts at 1100a000 {
+			compatible = "mediatek,mt7988-lvts-ap";
+			#thermal-sensor-cells = <1>;
+			reg = <0 0x1100a000 0 0x1000>;
+			clocks = <&infracfg CLK_INFRA_26M_THERM_SYSTEM>;
+			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+			resets = <&infracfg MT7988_INFRA_RST1_THERM_CTRL_SWRST>;
+			nvmem-cells = <&lvts_calibration>;
+			nvmem-cell-names = "lvts-calib-data-1";
+		};
+
 		usb at 11190000 {
 			compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
 			reg = <0 0x11190000 0 0x2e00>,
@@ -307,11 +320,15 @@ clock-controller at 11f40000 {
 			#clock-cells = <1>;
 		};
 
-		efuse at 11f50000 {
+		efuse: efuse at 11f50000 {
 			compatible = "mediatek,mt7988-efuse", "mediatek,efuse";
 			reg = <0 0x11f50000 0 0x1000>;
 			#address-cells = <1>;
 			#size-cells = <1>;
+
+			lvts_calibration: calib at 918 {
+				reg = <0x918 0x28>;
+			};
 		};
 
 		clock-controller at 15000000 {
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:47 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:47 +0100
Subject: [PATCH v2 06/18] arm64: dts: mediatek: mt7988: add thermal trips to bpi-r4
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-7-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add additional thermal trips to Bananapi R4 board.
SoC only contains the critical trip.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index df53512c6890..8a320d9da443 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -28,6 +28,34 @@ reg_3p3v: regulator-3p3v {
 	};
 };
 
+&cpu_thermal {
+	trips {
+		cpu_trip_hot: hot {
+			temperature = <120000>;
+			hysteresis = <2000>;
+			type = "hot";
+		};
+
+		cpu_trip_active_high: active-high {
+			temperature = <115000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+
+		cpu_trip_active_med: active-med {
+			temperature = <85000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+
+		cpu_trip_active_low: active-low {
+			temperature = <40000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+	};
+};
+
 &pio {
 	mdio0_pins: mdio0-pins {
 		mux {
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:46 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:46 +0100
Subject: [PATCH v2 05/18] arm64: dts: mediatek: mt7988: add thermal-zone
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-6-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add basic thermal-zone node.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
v2:
- only add critical trip to SoC dtsi, lower trips have to go to board dts
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index f7748a840297..09dcb39ad098 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -346,6 +346,21 @@ clock-controller at 15031000 {
 		};
 	};
 
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+			thermal-sensors = <&lvts 0>;
+			trips {
+				cpu_trip_crit: crit {
+					temperature = <125000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupt-parent = <&gic>;
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:48 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:48 +0100
Subject: [PATCH v2 07/18] arm64: dts: mediatek: mt7988: add reserved memory
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-8-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add memory range handled by ATF to not be touched by linux kernel.
ATF is SoC specific and not board-specific so add it to mt7988.dtsi.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 09dcb39ad098..1cf801486e61 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -63,6 +63,18 @@ psci {
 		method = "smc";
 	};
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* 320 KiB reserved for ARM Trusted Firmware (BL31 and BL32) */
+		secmon_reserved: secmon at 43000000 {
+			reg = <0 0x43000000 0 0x50000>;
+			no-map;
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		ranges;
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:49 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:49 +0100
Subject: [PATCH v2 08/18] arm64: dts: mediatek: mt7988: add mcu-sys node for cpu
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-9-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add mcu-sys node which is used later as clock-controller for cpus.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 1cf801486e61..2af440510c86 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -192,6 +192,12 @@ pwm at 10048000 {
 			status = "disabled";
 		};
 
+		mcusys: mcusys at 100e0000 {
+			compatible = "mediatek,mt7988-mcusys", "syscon";
+			reg = <0 0x100e0000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
 		serial at 11000000 {
 			compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
 			reg = <0 0x11000000 0 0x100>;
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:50 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:50 +0100
Subject: [PATCH v2 09/18] arm64: dts: mediatek: mt7988: add operating-points
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-10-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add operating points defining frequency/voltages of cpu cores.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
changes:
v2:
- drop cpu-labels for now
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 38 +++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 2af440510c86..5609e3619be9 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -21,6 +21,10 @@ cpu at 0 {
 			reg = <0x0>;
 			device_type = "cpu";
 			enable-method = "psci";
+			clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
+				 <&topckgen CLK_TOP_XTAL>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		cpu at 1 {
@@ -28,6 +32,10 @@ cpu at 1 {
 			reg = <0x1>;
 			device_type = "cpu";
 			enable-method = "psci";
+			clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
+				 <&topckgen CLK_TOP_XTAL>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		cpu at 2 {
@@ -35,6 +43,10 @@ cpu at 2 {
 			reg = <0x2>;
 			device_type = "cpu";
 			enable-method = "psci";
+			clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
+				 <&topckgen CLK_TOP_XTAL>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		cpu at 3 {
@@ -42,6 +54,32 @@ cpu at 3 {
 			reg = <0x3>;
 			device_type = "cpu";
 			enable-method = "psci";
+			clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
+				 <&topckgen CLK_TOP_XTAL>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cluster0_opp>;
+		};
+
+		cluster0_opp: opp-table-0 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-800000000 {
+				opp-hz = /bits/ 64 <800000000>;
+				opp-microvolt = <850000>;
+			};
+			opp-1100000000 {
+				opp-hz = /bits/ 64 <1100000000>;
+				opp-microvolt = <850000>;
+			};
+			opp-1500000000 {
+				opp-hz = /bits/ 64 <1500000000>;
+				opp-microvolt = <850000>;
+			};
+			opp-1800000000 {
+				opp-hz = /bits/ 64 <1800000000>;
+				opp-microvolt = <900000>;
+			};
 		};
 	};
 
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:52 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:52 +0100
Subject: [PATCH v2 11/18] arm64: dts: mediatek: mt7988: add chosen node on bpi-r4
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-12-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add chosen node on Bananapi R4 board with stdout and default bootargs.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 9037f35857a9..1c2a806f6f6c 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -9,6 +9,11 @@ / {
 	model = "Banana Pi BPI-R4";
 	chassis-type = "embedded";
 
+	chosen {
+		stdout-path = &serial0;
+		bootargs = "console=ttyS0,115200n1";
+	};
+
 	reg_1p8v: regulator-1p8v {
 		compatible = "regulator-fixed";
 		regulator-name = "fixed-1.8V";
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:51 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:51 +0100
Subject: [PATCH v2 10/18] arm64: dts: mediatek: mt7988: enable serial0 on bpi-r4
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-11-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable the debug uart on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 8a320d9da443..9037f35857a9 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -245,6 +245,10 @@ mux {
 	};
 };
 
+&serial0 {
+	status = "okay";
+};
+
 &watchdog {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 5609e3619be9..abf81a7d02a5 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -236,7 +236,7 @@ mcusys: mcusys at 100e0000 {
 			#clock-cells = <1>;
 		};
 
-		serial at 11000000 {
+		serial0: serial at 11000000 {
 			compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
 			reg = <0 0x11000000 0 0x100>;
 			interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:53 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:53 +0100
Subject: [PATCH v2 12/18] arm64: dts: mediatek: mt7988: add missing clock-div property for i2c
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-13-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

I2C binding requires clock-div property.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index abf81a7d02a5..956f2be600a2 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -274,6 +274,7 @@ i2c at 11003000 {
 			reg = <0 0x11003000 0 0x1000>,
 			      <0 0x10217080 0 0x80>;
 			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+			clock-div = <1>;
 			clocks = <&infracfg CLK_INFRA_I2C_BCK>,
 				 <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
 			clock-names = "main", "dma";
@@ -287,6 +288,7 @@ i2c at 11004000 {
 			reg = <0 0x11004000 0 0x1000>,
 			      <0 0x10217100 0 0x80>;
 			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clock-div = <1>;
 			clocks = <&infracfg CLK_INFRA_I2C_BCK>,
 				 <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
 			clock-names = "main", "dma";
@@ -300,6 +302,7 @@ i2c at 11005000 {
 			reg = <0 0x11005000 0 0x1000>,
 			      <0 0x10217180 0 0x80>;
 			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clock-div = <1>;
 			clocks = <&infracfg CLK_INFRA_I2C_BCK>,
 				 <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
 			clock-names = "main", "dma";
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:54 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:54 +0100
Subject: [PATCH v2 13/18] arm64: dts: mediatek: mt7988: add i2c to bpi-r4 board
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-14-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add basic i2c nodes to bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 .../boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts    | 12 ++++++++++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi            |  6 +++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 1c2a806f6f6c..13ca016d6a67 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -61,6 +61,18 @@ cpu_trip_active_low: active-low {
 	};
 };
 
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_1_pins>;
+	status = "okay";
+};
+
 &pio {
 	mdio0_pins: mdio0-pins {
 		mux {
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 956f2be600a2..eebbdfe55774 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -269,7 +269,7 @@ serial at 11000200 {
 			status = "disabled";
 		};
 
-		i2c at 11003000 {
+		i2c0: i2c at 11003000 {
 			compatible = "mediatek,mt7981-i2c";
 			reg = <0 0x11003000 0 0x1000>,
 			      <0 0x10217080 0 0x80>;
@@ -283,7 +283,7 @@ i2c at 11003000 {
 			status = "disabled";
 		};
 
-		i2c at 11004000 {
+		i2c1: i2c at 11004000 {
 			compatible = "mediatek,mt7981-i2c";
 			reg = <0 0x11004000 0 0x1000>,
 			      <0 0x10217100 0 0x80>;
@@ -297,7 +297,7 @@ i2c at 11004000 {
 			status = "disabled";
 		};
 
-		i2c at 11005000 {
+		i2c2: i2c at 11005000 {
 			compatible = "mediatek,mt7981-i2c";
 			reg = <0 0x11005000 0 0x1000>,
 			      <0 0x10217180 0 0x80>;
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:55 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:55 +0100
Subject: [PATCH v2 14/18] arm64: dts: mediatek: mt7988: add pmic on bpi-r4
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-15-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Bananapi R4 Board contains a MT6682A pmic which is compatible to rt5190a.
Add its node to the i2 controller.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 13ca016d6a67..bc1ec73b8ddd 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -2,6 +2,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
+
 #include "mt7988a.dtsi"
 
 / {
@@ -65,6 +67,55 @@ &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins>;
 	status = "okay";
+
+	rt5190a_64: rt5190a at 64 {
+		compatible = "richtek,rt5190a";
+		reg = <0x64>;
+		vin2-supply = <&rt5190_buck1>;
+		vin3-supply = <&rt5190_buck1>;
+		vin4-supply = <&rt5190_buck1>;
+
+		regulators {
+			rt5190_buck1: buck1 {
+				regulator-name = "rt5190a-buck1";
+				regulator-min-microvolt = <5090000>;
+				regulator-max-microvolt = <5090000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+			buck2 {
+				regulator-name = "vcore";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+			rt5190_buck3: buck3 {
+				regulator-name = "vproc";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+			};
+			buck4 {
+				regulator-name = "rt5190a-buck4";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+			ldo {
+				regulator-name = "rt5190a-ldo";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
 };
 
 &i2c2 {
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:57 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:57 +0100
Subject: [PATCH v2 16/18] arm64: dts: mediatek: mt7988: add i2c-mux on bpi-r4
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-17-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Bananapi R4 uses an i2c multiplexer for SFP slots, rtc and eeprom.
Add its node to the right i2c controller.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 550c373b3d70..9ceefc990000 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -2,6 +2,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
 
 #include "mt7988a.dtsi"
@@ -138,6 +139,45 @@ &i2c2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c2_1_pins>;
 	status = "okay";
+
+	pca9545: i2c-mux at 70 {
+		reg = <0x70>;
+		compatible = "nxp,pca9545";
+		reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			pcf8563: rtc at 51 {
+				compatible = "nxp,pcf8563";
+				reg = <0x51>;
+				#clock-cells = <0>;
+			};
+
+			eeprom at 57 {
+				compatible = "atmel,24c02";
+				reg = <0x57>;
+				size = <256>;
+			};
+
+		};
+
+		i2c_sfp1: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		i2c_sfp2: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+	};
 };
 
 &pio {
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:56 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:56 +0100
Subject: [PATCH v2 15/18] arm64: dts: mediatek: mt7988: add proc-supply for cpus on bpi-r4
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-16-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add proc-supply property to cpus on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts     | 16 ++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi        |  8 ++++----
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index bc1ec73b8ddd..550c373b3d70 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -35,6 +35,22 @@ reg_3p3v: regulator-3p3v {
 	};
 };
 
+&cpu0 {
+	proc-supply = <&rt5190_buck3>;
+};
+
+&cpu1 {
+	proc-supply = <&rt5190_buck3>;
+};
+
+&cpu2 {
+	proc-supply = <&rt5190_buck3>;
+};
+
+&cpu3 {
+	proc-supply = <&rt5190_buck3>;
+};
+
 &cpu_thermal {
 	trips {
 		cpu_trip_hot: hot {
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index eebbdfe55774..93c21a5248fa 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -16,7 +16,7 @@ cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		cpu at 0 {
+		cpu0: cpu at 0 {
 			compatible = "arm,cortex-a73";
 			reg = <0x0>;
 			device_type = "cpu";
@@ -27,7 +27,7 @@ cpu at 0 {
 			operating-points-v2 = <&cluster0_opp>;
 		};
 
-		cpu at 1 {
+		cpu1: cpu at 1 {
 			compatible = "arm,cortex-a73";
 			reg = <0x1>;
 			device_type = "cpu";
@@ -38,7 +38,7 @@ cpu at 1 {
 			operating-points-v2 = <&cluster0_opp>;
 		};
 
-		cpu at 2 {
+		cpu2: cpu at 2 {
 			compatible = "arm,cortex-a73";
 			reg = <0x2>;
 			device_type = "cpu";
@@ -49,7 +49,7 @@ cpu at 2 {
 			operating-points-v2 = <&cluster0_opp>;
 		};
 
-		cpu at 3 {
+		cpu3: cpu at 3 {
 			compatible = "arm,cortex-a73";
 			reg = <0x3>;
 			device_type = "cpu";
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:59 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:59 +0100
Subject: [PATCH v2 18/18] arm64: dts: mediatek: mt7988: enable pwm on bpi-r4
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-19-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable pwm on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 12b45b18955b..181bb997cd8d 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -369,6 +369,10 @@ mux {
 	};
 };
 
+&pwm {
+	status = "okay";
+};
+
 &serial0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 2be84acac06a..11651f5e167d 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -211,7 +211,7 @@ mux {
 			};
 		};
 
-		pwm at 10048000 {
+		pwm: pwm at 10048000 {
 			compatible = "mediatek,mt7988-pwm";
 			reg = <0 0x10048000 0 0x1000>;
 			clocks = <&infracfg CLK_INFRA_66M_PWM_BCK>,
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:58 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:58 +0100
Subject: [PATCH v2 17/18] arm64: dts: mediatek: mt7988: enable ssusb1 on bpi-r4
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-18-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable front-usb on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 9ceefc990000..12b45b18955b 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -373,6 +373,10 @@ &serial0 {
 	status = "okay";
 };
 
+&ssusb1 {
+	status = "okay";
+};
+
 &watchdog {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 93c21a5248fa..2be84acac06a 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -336,7 +336,7 @@ usb at 11190000 {
 			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
 		};
 
-		usb at 11200000 {
+		ssusb1: usb at 11200000 {
 			compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
 			reg = <0 0x11200000 0 0x2e00>,
 			      <0 0x11203e00 0 0x0100>;
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:42 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:42 +0100
Subject: [PATCH v2 01/18] arm64: dts: mediatek: mt7988: enable watchdog on bpi-r4
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-2-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable the watchdog on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index aa2dabc041fd..d914eae2b524 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -198,3 +198,7 @@ mux {
 		};
 	};
 };
+
+&watchdog {
+	status = "okay";
+};
-- 
2.43.0



From linux at fw-web.de  Mon Dec  2 04:25:43 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  2 Dec 2024 13:25:43 +0100
Subject: [PATCH v2 02/18] arm64: dts: mediatek: mt7988: add mmc support
In-Reply-To: <20241202122602.30734-1-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
Message-ID: <20241202122602.30734-3-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add devicetree node for MMC controller.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
changes:
v2:
squash "add missing label for apmixedsys"
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 24 ++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 46969577c87a..5e40446cb7b3 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -100,7 +100,7 @@ watchdog: watchdog at 1001c000 {
 			#reset-cells = <1>;
 		};
 
-		clock-controller at 1001e000 {
+		apmixedsys: clock-controller at 1001e000 {
 			compatible = "mediatek,mt7988-apmixedsys";
 			reg = <0 0x1001e000 0 0x1000>;
 			#clock-cells = <1>;
@@ -278,6 +278,28 @@ usb at 11200000 {
 			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
 		};
 
+		mmc0: mmc at 11230000 {
+			compatible = "mediatek,mt7988-mmc";
+			reg = <0 0x11230000 0 0x1000>,
+			      <0 0x11D60000 0 0x1000>;
+			interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_MSDC400>,
+				 <&infracfg CLK_INFRA_MSDC2_HCK>,
+				 <&infracfg CLK_INFRA_66M_MSDC_0_HCK>,
+				 <&infracfg CLK_INFRA_133M_MSDC_0_HCK>;
+			assigned-clocks = <&topckgen CLK_TOP_EMMC_250M_SEL>,
+					  <&topckgen CLK_TOP_EMMC_400M_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_NET1PLL_D5_D2>,
+						 <&apmixedsys CLK_APMIXED_MSDCPLL>;
+			clock-names = "source",
+				      "hclk",
+				      "axi_cg",
+				      "ahb_cg";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		clock-controller at 11f40000 {
 			compatible = "mediatek,mt7988-xfi-pll";
 			reg = <0 0x11f40000 0 0x1000>;
-- 
2.43.0



From lkp at intel.com  Mon Dec  2 04:41:18 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 2 Dec 2024 20:41:18 +0800
Subject: [PATCH] pinctrl: mediatek: add eint new design for mt8196
In-Reply-To: <20241202085024.25375-1-ot_chhao.chang@mediatek.com>
References: <20241202085024.25375-1-ot_chhao.chang@mediatek.com>
Message-ID: <202412022033.G153neOU-lkp@intel.com>

Hi chang,

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 linus/master v6.13-rc1 next-20241128]
[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/chang-hao/pinctrl-mediatek-add-eint-new-design-for-mt8196/20241202-165544
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
patch link:    https://lore.kernel.org/r/20241202085024.25375-1-ot_chhao.chang%40mediatek.com
patch subject: [PATCH] pinctrl: mediatek: add eint new design for mt8196
config: arc-randconfig-001-20241202 (https://download.01.org/0day-ci/archive/20241202/202412022033.G153neOU-lkp at intel.com/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241202/202412022033.G153neOU-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/202412022033.G153neOU-lkp at intel.com/

All error/warnings (new ones prefixed by >>):

>> drivers/pinctrl/mediatek/mtk-eint.c:246:6: warning: no previous prototype for 'mt6983_eint_ack' [-Wmissing-prototypes]
     246 | void mt6983_eint_ack(struct irq_data *d)
         |      ^~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/mtk-eint.c: In function 'mtk_eint_do_suspend':
>> drivers/pinctrl/mediatek/mtk-eint.c:605:9: error: implicit declaration of function 'dsb' [-Werror=implicit-function-declaration]
     605 |         dsb(sy);
         |         ^~~
>> drivers/pinctrl/mediatek/mtk-eint.c:605:13: error: 'sy' undeclared (first use in this function); did you mean 's8'?
     605 |         dsb(sy);
         |             ^~
         |             s8
   drivers/pinctrl/mediatek/mtk-eint.c:605:13: note: each undeclared identifier is reported only once for each function it appears in
   drivers/pinctrl/mediatek/mtk-eint.c: In function 'mtk_eint_do_resume':
   drivers/pinctrl/mediatek/mtk-eint.c:626:13: error: 'sy' undeclared (first use in this function); did you mean 's8'?
     626 |         dsb(sy);
         |             ^~
         |             s8
   drivers/pinctrl/mediatek/mtk-eint.c: At top level:
>> drivers/pinctrl/mediatek/mtk-eint.c:704:14: warning: no previous prototype for 'mtk_eint_get_debounce_en' [-Wmissing-prototypes]
     704 | unsigned int mtk_eint_get_debounce_en(struct mtk_eint *eint,
         |              ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/pinctrl/mediatek/mtk-eint.c:727:14: warning: no previous prototype for 'mtk_eint_get_debounce_value' [-Wmissing-prototypes]
     727 | unsigned int mtk_eint_get_debounce_value(struct mtk_eint *eint,
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +/dsb +605 drivers/pinctrl/mediatek/mtk-eint.c

   589	
   590	int mtk_eint_do_suspend(struct mtk_eint *eint)
   591	{
   592		unsigned int i, j, port;
   593	
   594		for (i = 0; i < eint->instance_number; i++) {
   595			struct mtk_eint_instance inst = eint->instances[i];
   596	
   597			for (j = 0; j < inst.number; j += 32) {
   598				port = j >> 5;
   599				writel_relaxed(~inst.wake_mask[port],
   600					       inst.base + port * 4 + eint->comp->regs->mask_set);
   601				writel_relaxed(inst.wake_mask[port],
   602					       inst.base + port * 4 + eint->comp->regs->mask_clr);
   603			}
   604		}
 > 605		dsb(sy);
   606	
   607		return 0;
   608	}
   609	EXPORT_SYMBOL_GPL(mtk_eint_do_suspend);
   610	
   611	int mtk_eint_do_resume(struct mtk_eint *eint)
   612	{
   613		unsigned int i, j, port;
   614	
   615		for (i = 0; i < eint->instance_number; i++) {
   616			struct mtk_eint_instance inst = eint->instances[i];
   617	
   618			for (j = 0; j < inst.number; j += 32) {
   619				port = j >> 5;
   620				writel_relaxed(~inst.cur_mask[port],
   621					       inst.base + port * 4 + eint->comp->regs->mask_set);
   622				writel_relaxed(inst.cur_mask[port],
   623					       inst.base + port * 4 + eint->comp->regs->mask_clr);
   624			}
   625		}
   626		dsb(sy);
   627	
   628		return 0;
   629	}
   630	EXPORT_SYMBOL_GPL(mtk_eint_do_resume);
   631	
   632	int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
   633				  unsigned int debounce)
   634	{
   635		int virq, eint_offset;
   636		unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask,
   637			     dbnc;
   638		static const unsigned int debounce_time[] = { 156, 313, 625, 1250,
   639			20000, 40000, 80000, 160000, 320000, 640000 };
   640		struct irq_data *d;
   641		unsigned int instance, index;
   642		void __iomem *reg;
   643	
   644		/*
   645		 * Due to different number of bit field, we only decode
   646		 * the coordinate here, instead of get the VA.
   647		 */
   648		reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
   649					  &instance, &index);
   650	
   651		if (!reg) {
   652			dev_err(eint->dev, "%s invalid eint_num %lu\n",
   653				__func__, eint_num);
   654			return 0;
   655		}
   656	
   657		virq = irq_find_mapping(eint->domain, eint_num);
   658		eint_offset = (index % 4) * 8;
   659		d = irq_get_irq_data(virq);
   660	
   661		reg = eint->instances[instance].base;
   662		set_offset = (index / 4) * 4 + eint->comp->regs->dbnc_set;
   663		clr_offset = (index / 4) * 4 + eint->comp->regs->dbnc_clr;
   664	
   665		if (!mtk_eint_can_en_debounce(eint, eint_num))
   666			return -EINVAL;
   667	
   668		/*
   669		 * Check eint number to avoid access out-of-range
   670		 */
   671		dbnc = ARRAY_SIZE(debounce_time) - 1;
   672		for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
   673			if (debounce <= debounce_time[i]) {
   674				dbnc = i;
   675				break;
   676			}
   677		}
   678	
   679		if (!mtk_eint_get_mask(eint, eint_num)) {
   680			mtk_eint_mask(d);
   681			unmask = 1;
   682		} else {
   683			unmask = 0;
   684		}
   685	
   686		clr_bit = 0xff << eint_offset;
   687		writel(clr_bit, reg + clr_offset);
   688	
   689		bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS)
   690			| MTK_EINT_DBNC_SET_EN) << eint_offset;
   691		rst = MTK_EINT_DBNC_RST_BIT << eint_offset;
   692		writel(rst | bit, reg + set_offset);
   693	
   694		/* Delay should be (8T @ 32k) from dbc rst to work correctly. */
   695		udelay(250);
   696	
   697		if (unmask == 1)
   698			mtk_eint_unmask(d);
   699	
   700		return 0;
   701	}
   702	EXPORT_SYMBOL_GPL(mtk_eint_set_debounce);
   703	
 > 704	unsigned int mtk_eint_get_debounce_en(struct mtk_eint *eint,
   705					      unsigned int eint_num)
   706	{
   707		unsigned int instance, index, bit;
   708		void __iomem *reg;
   709	
   710		reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
   711					  &instance, &index);
   712	
   713		if (!reg) {
   714			dev_err(eint->dev, "%s invalid eint_num %d\n",
   715				__func__, eint_num);
   716			return 0;
   717		}
   718	
   719		reg = eint->instances[instance].base +
   720			(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
   721	
   722		bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
   723	
   724		return (readl(reg) & bit) ? 1 : 0;
   725	}
   726	
 > 727	unsigned int mtk_eint_get_debounce_value(struct mtk_eint *eint,
   728						 unsigned int eint_num)
   729	{
   730		unsigned int instance, index, mask, offset;
   731		void __iomem *reg;
   732	
   733		reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
   734					  &instance, &index);
   735	
   736		if (!reg) {
   737			dev_err(eint->dev, "%s invalid eint_num %d\n",
   738				__func__, eint_num);
   739			return 0;
   740		}
   741	
   742		reg = eint->instances[instance].base +
   743			(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
   744	
   745		offset = MTK_EINT_DBNC_SET_DBNC_BITS + ((index % 4) * 8);
   746		mask = 0xf << offset;
   747	
   748		return ((readl(reg) & mask) >> offset);
   749	}
   750	

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


From tabba at google.com  Mon Dec  2 04:57:44 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Dec 2024 12:57:44 +0000
Subject: [PATCH v3 14/15] KVM: arm64: Convert the SVE guest vcpu flag to a
 vm flag
In-Reply-To: <CA+EHjTyXj6NhUcxTfER=zPz3VOtd+HgqpfmyfR88cVyiXoxqwA@mail.gmail.com>
References: <20241128123515.1709777-1-tabba@google.com> <20241128123515.1709777-15-tabba@google.com>
 <864j3nv9tk.wl-maz@kernel.org> <CA+EHjTyXj6NhUcxTfER=zPz3VOtd+HgqpfmyfR88cVyiXoxqwA@mail.gmail.com>
Message-ID: <CA+EHjTysFaaxGBo212e8kSHi_VkpXx6N6ddxwB0UGC6bSoK0gA@mail.gmail.com>

Hi Marc,

On Sun, 1 Dec 2024 at 16:01, Fuad Tabba <tabba at google.com> wrote:
>
> Hi Marc,
>
>
> On Sun, 1 Dec 2024 at 12:58, Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Thu, 28 Nov 2024 12:35:14 +0000,
> > Fuad Tabba <tabba at google.com> wrote:
> > >
> > > The vcpu flag GUEST_HAS_SVE is per-vcpu, but it is based on what
> > > is now a per-vm feature. Make the flag per-vm.
> > >
> > > Signed-off-by: Fuad Tabba <tabba at google.com>
> > > ---
> > >  arch/arm64/include/asm/kvm_emulate.h    |  6 +++---
> > >  arch/arm64/include/asm/kvm_host.h       | 10 ++++++----
> > >  arch/arm64/kvm/hyp/include/hyp/switch.h |  2 +-
> > >  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  2 +-
> > >  arch/arm64/kvm/hyp/nvhe/pkvm.c          | 11 +++++++----
> > >  arch/arm64/kvm/hyp/nvhe/switch.c        |  8 ++++----
> > >  arch/arm64/kvm/hyp/vhe/switch.c         |  2 +-
> > >  arch/arm64/kvm/reset.c                  |  2 +-
> > >  8 files changed, 24 insertions(+), 19 deletions(-)
> > >
> > > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > > index 406e99a452bf..ae6d0dc0e4ff 100644
> > > --- a/arch/arm64/include/asm/kvm_emulate.h
> > > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > > @@ -620,7 +620,7 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
> > >  }
> > >
> > >  /* Resets the value of cptr_el2 when returning to the host. */
> > > -static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> > > +static __always_inline void kvm_reset_cptr_el2(struct kvm *kvm)
> >
> > I'd rather you avoid the resulting churn:
> >
> > static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> > {
> >         struct kvm *kvm = kern_hyp_va(vcpu->kvm);
> >         [...]
> >
> > which does the trick at zero cost. It is also more logical to keep the
> > vcpu as a parameter, as the per-VM-ness is only an implementation
> > detail.
>
> The reason for the churn (here and below for vcpu_has_sve()), which in
> hindsight I should have mentioned in the commit message or as a note,
> is that this code is called by the host kernel (e.g., in reset.c), and
> by the hypervisor). For nvhe, we need kern_hyp_va(), but not for the
> host. Should I gate the va conversion with is_hyp_nvhe()?

I spoke too soon. Your suggestion results in less churn, and of
course, solves the issue I had with kern_hyp_va.

I did have to convert kvm_reset_cptr_el2() into a macro, because it
now needs kern_hyp_va(), defined in kvm_mmu.h, which in turn includes
kvm_emulate.h. But since it's __always_inline, it shouldn't make any
difference in practice.

If this conversion to a macro is alright by you, I'll respin this.

Thanks again, and sorry for the noise.
/fuad

>
> > >  {
> > >       u64 val;
> > >
> > > @@ -631,14 +631,14 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> > >       } else if (has_hvhe()) {
> > >               val = CPACR_ELx_FPEN;
> > >
> > > -             if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
> > > +             if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
> > >                       val |= CPACR_ELx_ZEN;
> > >               if (cpus_have_final_cap(ARM64_SME))
> > >                       val |= CPACR_ELx_SMEN;
> > >       } else {
> > >               val = CPTR_NVHE_EL2_RES1;
> > >
> > > -             if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
> > > +             if (kvm_has_sve(kvm) && guest_owns_fp_regs())
> > >                       val |= CPTR_EL2_TZ;
> > >               if (!cpus_have_final_cap(ARM64_SME))
> > >                       val |= CPTR_EL2_TSM;
> > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > > index 680ecef1d7aa..c5c80c789ad0 100644
> > > --- a/arch/arm64/include/asm/kvm_host.h
> > > +++ b/arch/arm64/include/asm/kvm_host.h
> > > @@ -331,6 +331,8 @@ struct kvm_arch {
> > >  #define KVM_ARCH_FLAG_ID_REGS_INITIALIZED            7
> > >       /* Fine-Grained UNDEF initialised */
> > >  #define KVM_ARCH_FLAG_FGU_INITIALIZED                        8
> > > +     /* SVE exposed to guest */
> > > +#define KVM_ARCH_FLAG_GUEST_HAS_SVE                  9
> > >       unsigned long flags;
> > >
> > >       /* VM-wide vCPU feature set */
> > > @@ -862,8 +864,6 @@ struct kvm_vcpu_arch {
> > >  #define vcpu_set_flag(v, ...)        __vcpu_set_flag((v), __VA_ARGS__)
> > >  #define vcpu_clear_flag(v, ...)      __vcpu_clear_flag((v), __VA_ARGS__)
> > >
> > > -/* SVE exposed to guest */
> > > -#define GUEST_HAS_SVE                __vcpu_single_flag(cflags, BIT(0))
> > >  /* SVE config completed */
> > >  #define VCPU_SVE_FINALIZED   __vcpu_single_flag(cflags, BIT(1))
> > >  /* KVM_ARM_VCPU_INIT completed */
> > > @@ -956,8 +956,10 @@ struct kvm_vcpu_arch {
> > >                                KVM_GUESTDBG_USE_HW | \
> > >                                KVM_GUESTDBG_SINGLESTEP)
> > >
> > > -#define vcpu_has_sve(vcpu) (system_supports_sve() &&                 \
> > > -                         vcpu_get_flag(vcpu, GUEST_HAS_SVE))
> > > +#define kvm_has_sve(kvm)     \
> > > +     test_bit(KVM_ARCH_FLAG_GUEST_HAS_SVE, &(kvm)->arch.flags)
> > > +#define vcpu_has_sve(vcpu)   \
> > > +     kvm_has_sve((vcpu)->kvm)
> >
> > Two things:
> >
> > - it is definitely worth keeping the system_supports_sve() helper, so
> >   that we avoid checking flags for nothing
>
> Ack
>
> > - Since you preserve the vcpu_has_sve(), how about writing it as:
> >
> > #ifdef __KVM_NVHE_HYPERVISOR__
> > #define vcpu_has_sve(v)         kvm_has_sve(kern_hyp_va((v)->kvm))
> > #else
> > #define vcpu_has_sve(v)         kvm_has_sve((v)->kvm)
> > #endif
> >
> >   which will avoid the churn in this patch, and makes it hard to get
> >   it wrong?
>
> Same as I mentioned above. This macro is even used in more places by
> the host kernel.
>
> Thanks,
> /fuad
>
> > Thanks,
> >
> >         M.
> >
> > --
> > Without deviation from the norm, progress is not possible.


From broonie at kernel.org  Mon Dec  2 04:59:22 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Dec 2024 12:59:22 +0000
Subject: [PATCH v5 2/9] ASoC: hdmi-codec: move no_capture_mute to struct
 hdmi_codec_pdata
In-Reply-To: <20241202-bald-just-guan-c5d41b@houat>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-2-b5316e82f61a@linaro.org>
 <20241202-bald-just-guan-c5d41b@houat>
Message-ID: <0d4dfb60-e2e6-484a-993a-41d1229c62fb@sirena.org.uk>

On Mon, Dec 02, 2024 at 01:06:09PM +0100, Maxime Ripard wrote:
> On Sun, Dec 01, 2024 at 02:44:06AM +0200, Dmitry Baryshkov wrote:

> > The no_capture_mute flag might differ from platform to platform,
> > especially in the case of the wrapping implementations, like the

> I appreciate it might be a dumb question, but I never really understood
> what no_capture_mute was all about. And in that context, why some
> drivers would need / use it, and some won't.

It's just what it says, it's a flag saying the device doesn't support
muting the capture side.
-------------- 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/20241202/0ee26cab/attachment.sig>

From ciprianmarian.costea at oss.nxp.com  Mon Dec  2 05:06:38 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Marian Costea)
Date: Mon, 2 Dec 2024 15:06:38 +0200
Subject: [PATCH v5 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <2024112715321236991788@mail.local>
References: <20241126114940.421143-1-ciprianmarian.costea@oss.nxp.com>
 <20241126114940.421143-3-ciprianmarian.costea@oss.nxp.com>
 <Z0YN+5GfP6iR8a/A@lizhi-Precision-Tower-5810>
 <14e90ec7-3815-4f06-826c-3fcf0d8d53c8@oss.nxp.com>
 <2024112715321236991788@mail.local>
Message-ID: <e2329870-2e4b-4c38-ae20-c6aa5108a0da@oss.nxp.com>

On 11/27/2024 5:32 PM, Alexandre Belloni wrote:
> On 27/11/2024 17:07:48+0200, Ciprian Marian Costea wrote:
>>>> +	if (priv->dt_irq_id < 0)
>>>> +		return priv->dt_irq_id;
>>>> +
>>>> +	ret = devm_request_irq(dev, priv->dt_irq_id,
>>>> +			       s32g_rtc_handler, 0, dev_name(dev), pdev);
>>>> +	if (ret) {
>>>> +		dev_err(dev, "Request interrupt %d failed, error: %d\n",
>>>> +			priv->dt_irq_id, ret);
>>>> +		goto disable_rtc;
>>>
>>>
>>> Already enable rtc at rtc_clk_src_setup(), you direct return fail after
>>> check clk_get_rate();
>>>
>>> if you want to disable_rtc, you use devm_add_action_or_reset() to add
>>> a disable action callback and return dev_err_probe() here directly.
>>>
>>> Frank
>>>
>>
>> Thanks for pointing this out. I will use 'devm_add_action_or_reset' in V6.
>>
> 
> Won't this disable the RTC on driver unload which we already discussed
> should not be done?
> 

This is true. Thanks for reminding me about this discussion/issue.
I will just fix the error paths for 'clk_get_rate' and 'platform_get_irq'.

>>>> +	/* Reset RTC to prevent overflow.
>>>> +	 * RTCCNT (RTC Counter) cannot be individually reset
>>>> +	 * since it is RO (read-only).
>>>> +	 */
>>>
>>> what's happen if overflow happen? I suppose it should go back to 0 and
>>> continue increase?
>>>
>>
>> Indeed if overflow happens the 'RTCCNT' counter goes back to 0 and continues
>> to increase. The reason for resetting it here in 'suspend' routine comes
>> after dropping the rollover support (as agreed on V4 of this patchset) to
>> prevent an overflow during the standby state.
>>
> 
> I don't think the overflow matters as the comparator should continue to work
> properly after it happens so you always have the complete range to wait
> for the alarm to happen.
> 
> 

I think I can drop the RTC reset from the suspend routine for this 
current patchset.


Best Regards,
Ciprian



From devnull+t.antoine.uclouvain.be at kernel.org  Mon Dec  2 05:07:18 2024
From: devnull+t.antoine.uclouvain.be at kernel.org (Thomas Antoine via B4 Relay)
Date: Mon, 02 Dec 2024 14:07:18 +0100
Subject: [PATCH 4/4] arm64: dts: exynos: gs101-oriole: enable Maxim
 max77759 fuel gauge
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
Message-ID: <20241202-b4-gs101_max77759_fg-v1-4-98d2fa7bfe30@uclouvain.be>

From: Thomas Antoine <t.antoine at uclouvain.be>

Add the node for the max77759 fuel gauge as a slave of the i2c.

The fuel gauge has been tested and seems to give coherent results.
Manual activation of the charger via i2cset shows that the sign of
the current does indicate charging/discharging status.

Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
---
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
index 387fb779bd29ea3812331a7951f03b181c5fe659..4c45dd6fd0173889234b7b04d7abb4b382c7706c 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
@@ -90,6 +90,13 @@ eeprom: eeprom at 50 {
 &hsi2c_12 {
 	status = "okay";
 	/* TODO: add the devices once drivers exist */
+
+	fuel-gauge at 36 {
+		compatible = "maxim,max77759-fg";
+		reg = <0x36>;
+		reg-names = "m5";
+	};
+
 };
 
 &pinctrl_far_alive {

-- 
2.47.1




From devnull+t.antoine.uclouvain.be at kernel.org  Mon Dec  2 05:07:14 2024
From: devnull+t.antoine.uclouvain.be at kernel.org (Thomas Antoine via B4 Relay)
Date: Mon, 02 Dec 2024 14:07:14 +0100
Subject: [PATCH 0/4] Google Pixel 6 (oriole): max77759 fuel gauge
 enablement and driver support
Message-ID: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>

The Google Pixel 6 has a Maxim max77759 which provides a fuel gauge with
the same interface as the Maxim max1720x, except for the non-volatile
memory.

Modify the Maxim max1720x driver to be compatible with the Maxim max77759 and
enable it for the gs101-oriole board.

Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
---
Thomas Antoine (4):
      power: supply: add support for max77759 fuel gauge
      dt-bindings: power: supply: add max77759-fg flavor and don't require nvme address
      arm64: defconfig: enable Maxim max1720x driver
      arm64: dts: exynos: gs101-oriole: enable Maxim max77759 fuel gauge

 .../bindings/power/supply/maxim,max17201.yaml      | 14 +++++
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts |  7 +++
 arch/arm64/configs/defconfig                       |  1 +
 drivers/power/supply/max1720x_battery.c            | 71 ++++++++++++++++++----
 4 files changed, 81 insertions(+), 12 deletions(-)
---
base-commit: 12e0a4072e8edc49c99418a4303bd7b96916de95
change-id: 20241202-b4-gs101_max77759_fg-402e231a4b33

Best regards,
-- 
Thomas Antoine <t.antoine at uclouvain.be>




From devnull+t.antoine.uclouvain.be at kernel.org  Mon Dec  2 05:07:17 2024
From: devnull+t.antoine.uclouvain.be at kernel.org (Thomas Antoine via B4 Relay)
Date: Mon, 02 Dec 2024 14:07:17 +0100
Subject: [PATCH 3/4] arm64: defconfig: enable Maxim max1720x driver
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
Message-ID: <20241202-b4-gs101_max77759_fg-v1-3-98d2fa7bfe30@uclouvain.be>

From: Thomas Antoine <t.antoine at uclouvain.be>

Enable the Maxim max1720x as it is used by the gs101-oriole
(Google Pixel 6) board.

Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index d13218d0c30f458d9c555ab9771a1fd9139ce1aa..e7523e53f2ed26bab39e64f3b2d8c8afc7c1a1f0 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -675,6 +675,7 @@ CONFIG_NVMEM_REBOOT_MODE=m
 CONFIG_BATTERY_QCOM_BATTMGR=m
 CONFIG_BATTERY_SBS=m
 CONFIG_BATTERY_BQ27XXX=y
+CONFIG_BATTERY_MAX1720X=m
 CONFIG_BATTERY_MAX17042=m
 CONFIG_CHARGER_MT6360=m
 CONFIG_CHARGER_BQ25890=m

-- 
2.47.1




From devnull+t.antoine.uclouvain.be at kernel.org  Mon Dec  2 05:07:15 2024
From: devnull+t.antoine.uclouvain.be at kernel.org (Thomas Antoine via B4 Relay)
Date: Mon, 02 Dec 2024 14:07:15 +0100
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
Message-ID: <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>

From: Thomas Antoine <t.antoine at uclouvain.be>

The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
except for the non-volatile memory slave address which is not available.
No slave is available at address 0xb of the i2c bus, which is coherent
with the following driver from google: line 5836 disables non-volatile
memory for m5 gauge.

Link: https://android.googlesource.com/kernel/google-modules/bms/+/1a68c36bef474573cc8629cc1d121eb6a81ab68c/max1720x_battery.c

Add support for the max77759 by allowing to use the non-volatile
memory or not based on the chip. Value for RSense comes from the following
stock devicetree:

Link: https://android.googlesource.com/kernel/devices/google/gs101/+/33eca36d43da6c2b6a546806eb3e7411bbe6d60d/dts/gs101-raviole-battery.dtsi

Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
---
 drivers/power/supply/max1720x_battery.c | 71 +++++++++++++++++++++++++++------
 1 file changed, 59 insertions(+), 12 deletions(-)

diff --git a/drivers/power/supply/max1720x_battery.c b/drivers/power/supply/max1720x_battery.c
index 33105419e2427bb37963bda9948b647c239f8faa..faf336938dd4306dd2ceeb0a84b90ca80ad41a9f 100644
--- a/drivers/power/supply/max1720x_battery.c
+++ b/drivers/power/supply/max1720x_battery.c
@@ -13,6 +13,7 @@
 #include <linux/nvmem-provider.h>
 #include <linux/power_supply.h>
 #include <linux/regmap.h>
+#include <linux/types.h>
 
 #include <linux/unaligned.h>
 
@@ -39,6 +40,7 @@
 #define MAX172XX_DEV_NAME_TYPE_MASK	GENMASK(3, 0)
 #define MAX172XX_DEV_NAME_TYPE_MAX17201	BIT(0)
 #define MAX172XX_DEV_NAME_TYPE_MAX17205	(BIT(0) | BIT(2))
+#define MAX172XX_DEV_NAME_TYPE_MAX77759	0
 #define MAX172XX_QR_TABLE10		0x22
 #define MAX172XX_BATT			0xDA	/* Battery voltage */
 #define MAX172XX_ATAVCAP		0xDF
@@ -46,6 +48,7 @@
 static const char *const max1720x_manufacturer = "Maxim Integrated";
 static const char *const max17201_model = "MAX17201";
 static const char *const max17205_model = "MAX17205";
+static const char *const max77759_model = "MAX77759";
 
 struct max1720x_device_info {
 	struct regmap *regmap;
@@ -54,6 +57,21 @@ struct max1720x_device_info {
 	int rsense;
 };
 
+struct chip_data {
+	u16 default_nrsense; /* in regs in 10^-5 */
+	u8 has_nvmem;
+};
+
+static const struct chip_data max1720x_data  = {
+	.default_nrsense = 1000,
+	.has_nvmem = 1,
+};
+
+static const struct chip_data max77759_data = {
+	.default_nrsense = 500,
+	.has_nvmem = 0,
+};
+
 /*
  * Model Gauge M5 Algorithm output register
  * Volatile data (must not be cached)
@@ -369,6 +387,8 @@ static int max1720x_battery_get_property(struct power_supply *psy,
 			val->strval = max17201_model;
 		else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17205)
 			val->strval = max17205_model;
+		else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX77759)
+			val->strval = max77759_model;
 		else
 			return -ENODEV;
 		break;
@@ -416,7 +436,6 @@ static int max1720x_probe_nvmem(struct i2c_client *client,
 		.priv = info,
 	};
 	struct nvmem_device *nvmem;
-	unsigned int val;
 	int ret;
 
 	info->ancillary = i2c_new_ancillary_device(client, "nvmem", 0xb);
@@ -438,6 +457,27 @@ static int max1720x_probe_nvmem(struct i2c_client *client,
 		return PTR_ERR(info->regmap_nv);
 	}
 
+	nvmem = devm_nvmem_register(dev, &nvmem_config);
+	if (IS_ERR(nvmem)) {
+		dev_err(dev, "Could not register nvmem!");
+		return PTR_ERR(nvmem);
+	}
+
+	return 0;
+}
+
+static int max1720x_get_rsense(struct device *dev,
+					 struct max1720x_device_info *info,
+					 const struct chip_data *data)
+{
+	unsigned int val;
+	int ret;
+
+	if (!data->has_nvmem) {
+		info->rsense = data->default_nrsense;
+		return 0;
+	}
+
 	ret = regmap_read(info->regmap_nv, MAX1720X_NRSENSE, &val);
 	if (ret < 0) {
 		dev_err(dev, "Failed to read sense resistor value\n");
@@ -446,14 +486,9 @@ static int max1720x_probe_nvmem(struct i2c_client *client,
 
 	info->rsense = val;
 	if (!info->rsense) {
-		dev_warn(dev, "RSense not calibrated, set 10 mOhms!\n");
-		info->rsense = 1000; /* in regs in 10^-5 */
-	}
-
-	nvmem = devm_nvmem_register(dev, &nvmem_config);
-	if (IS_ERR(nvmem)) {
-		dev_err(dev, "Could not register nvmem!");
-		return PTR_ERR(nvmem);
+		dev_warn(dev, "RSense not calibrated, set %d mOhms!\n",
+						data->default_nrsense/100);
+		info->rsense = data->default_nrsense;
 	}
 
 	return 0;
@@ -474,6 +509,7 @@ static int max1720x_probe(struct i2c_client *client)
 	struct device *dev = &client->dev;
 	struct max1720x_device_info *info;
 	struct power_supply *bat;
+	const struct chip_data *data;
 	int ret;
 
 	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
@@ -488,9 +524,19 @@ static int max1720x_probe(struct i2c_client *client)
 		return dev_err_probe(dev, PTR_ERR(info->regmap),
 				     "regmap initialization failed\n");
 
-	ret = max1720x_probe_nvmem(client, info);
+	data = device_get_match_data(dev);
+	if (!data)
+		return dev_err_probe(dev, ret, "Failed to get chip data\n");
+
+	if (data->has_nvmem) {
+		ret = max1720x_probe_nvmem(client, info);
+		if (ret)
+			return dev_err_probe(dev, ret, "Failed to probe nvmem\n");
+	}
+
+	ret = max1720x_get_rsense(dev, info, data);
 	if (ret)
-		return dev_err_probe(dev, ret, "Failed to probe nvmem\n");
+		return dev_err_probe(dev, ret, "Failed to get RSense");
 
 	bat = devm_power_supply_register(dev, &max1720x_bat_desc, &psy_cfg);
 	if (IS_ERR(bat))
@@ -501,7 +547,8 @@ static int max1720x_probe(struct i2c_client *client)
 }
 
 static const struct of_device_id max1720x_of_match[] = {
-	{ .compatible = "maxim,max17201" },
+	{ .compatible = "maxim,max17201", .data = (void *) &max1720x_data },
+	{ .compatible = "maxim,max77759-fg", .data = (void *) &max77759_data},
 	{}
 };
 MODULE_DEVICE_TABLE(of, max1720x_of_match);

-- 
2.47.1




From devnull+t.antoine.uclouvain.be at kernel.org  Mon Dec  2 05:07:16 2024
From: devnull+t.antoine.uclouvain.be at kernel.org (Thomas Antoine via B4 Relay)
Date: Mon, 02 Dec 2024 14:07:16 +0100
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor and
 don't require nvme address
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
Message-ID: <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>

From: Thomas Antoine <t.antoine at uclouvain.be>

As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
make it non-obligatory. Except for this, the max77759 seems to behave the
same as the max1720x.

Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
---
 .../devicetree/bindings/power/supply/maxim,max17201.yaml   | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max17201.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max17201.yaml
index fe3dd9bd5585618e45220c51023391a5b21acfd2..417fc2c4a1c1961654bc54ec1ac24602012f3335 100644
--- a/Documentation/devicetree/bindings/power/supply/maxim,max17201.yaml
+++ b/Documentation/devicetree/bindings/power/supply/maxim,max17201.yaml
@@ -16,6 +16,7 @@ properties:
   compatible:
     oneOf:
       - const: maxim,max17201
+      - const: maxim,max77759-fg
       - items:
           - enum:
               - maxim,max17205
@@ -25,11 +26,13 @@ properties:
     items:
       - description: ModelGauge m5 registers
       - description: Nonvolatile registers
+    minItems: 1
 
   reg-names:
     items:
       - const: m5
       - const: nvmem
+    minItems: 1
 
   interrupts:
     maxItems: 1
@@ -56,3 +59,14 @@ examples:
         interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
       };
     };
+  - |
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      fuel-gauge at 36 {
+        compatible = "maxim,max77759-fg";
+        reg = <0x36>;
+        reg-names = "m5";
+      };
+    };

-- 
2.47.1




From broonie at kernel.org  Mon Dec  2 05:14:15 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Dec 2024 13:14:15 +0000
Subject: [PATCH v5 1/3] ASoC: sun4i-codec: Add DMA Max Burst field
In-Reply-To: <20241102125712.2647325-2-csokas.bence@prolan.hu>
References: <20241102125712.2647325-1-csokas.bence@prolan.hu>
 <20241102125712.2647325-2-csokas.bence@prolan.hu>
Message-ID: <fe02df7f-16ae-4128-9af8-7de7f76734bc@sirena.org.uk>

On Sat, Nov 02, 2024 at 01:57:10PM +0100, Cs?k?s, Bence wrote:
> From: Mesih Kilinc <mesihkilinc at gmail.com>
> 
> Allwinner suniv F1C100s has similar DMA engine to sun4i but it has
> smaller max burst size compared to sun4i. Add a quirk field to
> differantitate between them.

This doesn't apply against current code, please check and resend.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241202/f780f4e7/attachment.sig>

From festevam at gmail.com  Mon Dec  2 05:14:23 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Mon,  2 Dec 2024 10:14:23 -0300
Subject: [PATCH RESEND v2] ARM: dts: imx6qdl-apalis: Change to "adi,force-bt656-4"
Message-ID: <20241202131423.586743-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

According to adv7180.yaml, the correct property name is
"adi,force-bt656-4".

Update it accordingly to fix several dt-schema warnings:

adv7280 at 21: 'adv,force-bt656-4' does not match any of the regexes: ...

imx6qdl-apalis.dtsi is the only in-tree kernel user of this property.

BSD does have a adv7180 driver, so should not be impacted.

Signed-off-by: Fabio Estevam <festevam at denx.de>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
- Resending it as a standalone patch. The dt-bindings and driver
changes have alaready been applied in 6.13-rc1. 
Changes since v1:
- Explained that BSD is not impacted. (Krzysztof)
- Collected Krzysztof' Reviewed-by tag.

 arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi
index 1c72da417011..dffab5aa8b9c 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi
@@ -691,7 +691,7 @@ &i2c3 {
 
 	adv_7280: adv7280 at 21 {
 		compatible = "adi,adv7280";
-		adv,force-bt656-4;
+		adi,force-bt656-4;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_ipu1_csi0>;
 		reg = <0x21>;
-- 
2.34.1



From broonie at kernel.org  Mon Dec  2 05:16:51 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Dec 2024 13:16:51 +0000
Subject: [PATCH v2 1/3] ASoC: hdmi-codec: Add event handler for hdmi TX
In-Reply-To: <a699178dcef540fff5caae6291983a444886bff6.camel@mediatek.com>
References: <Y4Cysgk5Gic5ae9B@sirena.org.uk>
 <18c82f6f723cd97a9d6b9a7ff16c6ed62fd005d6.camel@mediatek.com>
 <Y4Y/vEWe3dw0FPQH@sirena.org.uk>
 <cf9ea98a3263ffb8fc8b542888ad0ad680facfc7.camel@mediatek.com>
 <Y4jHAJgmz/P58Q/C@sirena.org.uk>
 <7023a2c7b471d6888d9079563a6c01f22599201f.camel@mediatek.com>
 <Y43e+EsNCrCpZSIH@sirena.org.uk>
 <dc50d0b21795acbcc44c77e5fd81e7cb92c65c67.camel@mediatek.com>
 <Y5ipwqzHKTK8UdlC@sirena.org.uk>
 <a699178dcef540fff5caae6291983a444886bff6.camel@mediatek.com>
Message-ID: <00d5c728-3eb9-427a-bc60-5828c20fec09@sirena.org.uk>

On Sun, Dec 01, 2024 at 05:15:45PM +0000, Jiaxin Yu (???) wrote:

> So I want to ask if I can do it by just adding
> SOC_DAPM_PIN_SWITCH("Speakers") and SOC_DAPM_PIN_SWITCH("HDMI")?
> Correspondingly, dapm widget and route path need to be added. That is
> "SND_SOC_DAPM_SPK("Speakers", NULL)/ SND_SOC_DAPM_LINE("HDMI1", NULL)"
> and "{"Speakers", NULL, "Speaker"}/ {"HDMI1", NULL, "TX"}".

Yes, that's what I'd expect to see.
-------------- 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/20241202/7732bed9/attachment.sig>

From csokas.bence at prolan.hu  Mon Dec  2 05:19:51 2024
From: csokas.bence at prolan.hu (=?UTF-8?B?Q3PDs2vDoXMgQmVuY2U=?=)
Date: Mon, 2 Dec 2024 14:19:51 +0100
Subject: [PATCH v5 1/3] ASoC: sun4i-codec: Add DMA Max Burst field
In-Reply-To: <fe02df7f-16ae-4128-9af8-7de7f76734bc@sirena.org.uk>
References: <20241102125712.2647325-1-csokas.bence@prolan.hu>
 <20241102125712.2647325-2-csokas.bence@prolan.hu>
 <fe02df7f-16ae-4128-9af8-7de7f76734bc@sirena.org.uk>
Message-ID: <47344634-9681-43a0-995a-f7dc025d1d09@prolan.hu>

Hi,

On 2024. 12. 02. 14:14, Mark Brown wrote:
> On Sat, Nov 02, 2024 at 01:57:10PM +0100, Cs?k?s, Bence wrote:
>> From: Mesih Kilinc <mesihkilinc at gmail.com>
>>
>> Allwinner suniv F1C100s has similar DMA engine to sun4i but it has
>> smaller max burst size compared to sun4i. Add a quirk field to
>> differantitate between them.
> 
> This doesn't apply against current code, please check and resend.

Try v6: 
https://lore.kernel.org/linux-kernel/20241123123900.2656837-1-csokas.bence at prolan.hu/

If that doesn't apply either, then I'll look into it, but it seems we 
already missed the MW for 6.13... :(

Bence



From mripard at kernel.org  Mon Dec  2 05:20:04 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 2 Dec 2024 14:20:04 +0100
Subject: [PATCH v5 8/9] drm/vc4: hdmi: switch to using generic HDMI Codec
 infrastructure
In-Reply-To: <20241201-drm-bridge-hdmi-connector-v5-8-b5316e82f61a@linaro.org>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-8-b5316e82f61a@linaro.org>
Message-ID: <20241202-industrious-unnatural-beagle-7da5d4@houat>

Hi,

Sorry, I've been drowning under work and couldn't review that series before.

I'll review the driver API for now, and we can focus on the exact
implementation later on.

On Sun, Dec 01, 2024 at 02:44:12AM +0200, Dmitry Baryshkov wrote:
> Drop driver-specific implementation and use the generic HDMI Codec
> framework in order to implement the HDMI audio support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 68 ++++++++++--------------------------------
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  2 --
>  2 files changed, 15 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 7295834e75fb1ab0cd241ed274e675567e66870b..d0a9aff7ad43016647493263c00d593296a1e3ad 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -595,6 +595,9 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
>  	if (vc4_hdmi->variant->supports_hdr)
>  		max_bpc = 12;
>  
> +	connector->hdmi_codec.max_i2s_channels = 8;
> +	connector->hdmi_codec.i2s = 1;
> +

I guess it's a similar discussion than we had with HDMI2.0+ earlier
today, but I don't really like initializing by structs. Struct fields
are easy to miss, and can be easily uninitialized by mistake.

I think I'd prefer to have them as argument to the init function. And if
they are optional, we can explicitly mark them as unused.

Like, it looks like the get_dai_id implementation relies on it being set
to < 0 for it to be ignored, but it's not here, so I'd assume it's used
with an ID of 0, even though the driver didn't support get_dai_id so
far?

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

From festevam at gmail.com  Mon Dec  2 05:21:47 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Mon,  2 Dec 2024 10:21:47 -0300
Subject: [PATCH RESEND 2/2] dt-bindings: timer: fsl,imxgpt: Document fsl,imx35-gpt
In-Reply-To: <20241202132147.587799-1-festevam@gmail.com>
References: <20241202132147.587799-1-festevam@gmail.com>
Message-ID: <20241202132147.587799-2-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

The i.MX35 General Purpose Timer is compatible with i.MX31.

Document the fsl,imx35-gpt compatible.

This fixes the following dt-schema warning:

timer at 53f90000: compatible: 'oneOf' conditional failed, one must be fixed:
	['fsl,imx35-gpt', 'fsl,imx31-gpt'] is too long
	'fsl,imx1-gpt' was expected
	'fsl,imx21-gpt' was expected
	'fsl,imx27-gpt' was expected
	'fsl,imx31-gpt' was expected
	'fsl,imx35-gpt' is not one of ['fsl,imx25-gpt', 'fsl,imx50-gpt', 'fsl,imx51-gpt', 'fsl,imx53-gpt', 'fsl,imx6q-gpt']
	'fsl,imx6dl-gpt' was expected
	'fsl,imx35-gpt' is not one of ['fsl,imx6sl-gpt', 'fsl,imx6sx-gpt', 'fsl,imx8mp-gpt', 'fsl,imxrt1050-gpt', 'fsl,imxrt1170-gpt']
	'fsl,imx35-gpt' is not one of ['fsl,imx6ul-gpt', 'fsl,imx7d-gpt']
	'fsl,imx6sx-gpt' was expected

Signed-off-by: Fabio Estevam <festevam at denx.de>
Reviewed-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
index a2fcb1e8e74e..9898dc7ea97b 100644
--- a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
+++ b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
@@ -21,6 +21,7 @@ properties:
       - items:
           - enum:
               - fsl,imx25-gpt
+              - fsl,imx35-gpt
               - fsl,imx50-gpt
               - fsl,imx51-gpt
               - fsl,imx53-gpt
-- 
2.34.1



From festevam at gmail.com  Mon Dec  2 05:21:46 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Mon,  2 Dec 2024 10:21:46 -0300
Subject: [PATCH RESEND 1/2] dt-bindings: timer: fsl,imxgpt: Fix the fsl,imx7d-gpt fallback
Message-ID: <20241202132147.587799-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

imx7s.dtsi correctly describes the GPT node as:

compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt";

Document the fallback compatible to be "fsl,imx6dl-gpt" in the bindings.

This fixes the following dt-schema warnings:

timer at 302f0000: compatible: 'oneOf' conditional failed, one must be fixed:
	['fsl,imx7d-gpt', 'fsl,imx6dl-gpt'] is too long
	'fsl,imx1-gpt' was expected
	'fsl,imx21-gpt' was expected
	'fsl,imx27-gpt' was expected
	'fsl,imx31-gpt' was expected
	'fsl,imx7d-gpt' is not one of ['fsl,imx25-gpt', 'fsl,imx50-gpt', 'fsl,imx51-gpt', 'fsl,imx53-gpt', 'fsl,imx6q-gpt']
	'fsl,imx6dl-gpt' was expected
	'fsl,imx7d-gpt' is not one of ['fsl,imx6sl-gpt', 'fsl,imx6sx-gpt', 'fsl,imx8mp-gpt', 'fsl,imxrt1050-gpt', 'fsl,imxrt1170-gpt']
	'fsl,imx6sx-gpt' was expected

Signed-off-by: Fabio Estevam <festevam at denx.de>
Reviewed-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
index e2607377cbae..a2fcb1e8e74e 100644
--- a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
+++ b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
@@ -31,6 +31,7 @@ properties:
           - enum:
               - fsl,imx6sl-gpt
               - fsl,imx6sx-gpt
+              - fsl,imx7d-gpt
               - fsl,imx8mp-gpt
               - fsl,imxrt1050-gpt
               - fsl,imxrt1170-gpt
@@ -38,7 +39,6 @@ properties:
       - items:
           - enum:
               - fsl,imx6ul-gpt
-              - fsl,imx7d-gpt
           - const: fsl,imx6sx-gpt
 
   reg:
-- 
2.34.1



From broonie at kernel.org  Mon Dec  2 05:23:56 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Dec 2024 13:23:56 +0000
Subject: [PATCH v5 1/3] ASoC: sun4i-codec: Add DMA Max Burst field
In-Reply-To: <47344634-9681-43a0-995a-f7dc025d1d09@prolan.hu>
References: <20241102125712.2647325-1-csokas.bence@prolan.hu>
 <20241102125712.2647325-2-csokas.bence@prolan.hu>
 <fe02df7f-16ae-4128-9af8-7de7f76734bc@sirena.org.uk>
 <47344634-9681-43a0-995a-f7dc025d1d09@prolan.hu>
Message-ID: <a59c5425-4401-480f-bf26-a7d607071f75@sirena.org.uk>

On Mon, Dec 02, 2024 at 02:19:51PM +0100, Cs?k?s Bence wrote:

> Try v6: https://lore.kernel.org/linux-kernel/20241123123900.2656837-1-csokas.bence at prolan.hu/

> If that doesn't apply either, then I'll look into it, but it seems we
> already missed the MW for 6.13... :(

That was sent the day before the merge window opened...

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/20241202/be269eec/attachment.sig>

From mripard at kernel.org  Mon Dec  2 05:27:49 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 2 Dec 2024 14:27:49 +0100
Subject: [PATCH v5 9/9] drm/vc4: hdmi: use
 drm_atomic_helper_connector_hdmi_update_edid()
In-Reply-To: <20241201-drm-bridge-hdmi-connector-v5-9-b5316e82f61a@linaro.org>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-9-b5316e82f61a@linaro.org>
Message-ID: <20241202-married-bald-raven-7acd83@houat>

Hi,

On Sun, Dec 01, 2024 at 02:44:13AM +0200, Dmitry Baryshkov wrote:
> Use the helper function to update the connector's information. This
> makes sure that HDMI-related events are handled in a generic way.
> Currently it is limited to the HDMI state reporting to the sound system.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index d0a9aff7ad43016647493263c00d593296a1e3ad..d83f587ab69f4b8f7d5c37a00777f11da8301bc1 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -401,13 +401,16 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
>  	 */
>  
>  	if (status == connector_status_disconnected) {
> +		drm_atomic_helper_connector_hdmi_update_edid(connector, NULL);
>  		cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
>  		return;
>  	}
>  
>  	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
>  
> -	drm_edid_connector_update(connector, drm_edid);
> +	// TODO: use drm_atomic_helper_connector_hdmi_update() once it gains
> +	// CEC support
> +	drm_atomic_helper_connector_hdmi_update_edid(connector, drm_edid);

So, it's not just about EDID, and I think we shouldn't really focus on
that either.

As that patch points out, even if we only consider EDID's, we have
different path depending on the connector status. It shouldn't be up to
the drivers to get this right.

What I had in mind was something like a
drm_atomic_helper_connector_hdmi_hotplug function that would obviously
deal with EDID only here, but would expand to CEC, scrambling, etc.
later on.

And would cover both the connected/disconnected cases.

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

From mripard at kernel.org  Mon Dec  2 05:29:55 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 2 Dec 2024 14:29:55 +0100
Subject: [PATCH v5 2/9] ASoC: hdmi-codec: move no_capture_mute to struct
 hdmi_codec_pdata
In-Reply-To: <0d4dfb60-e2e6-484a-993a-41d1229c62fb@sirena.org.uk>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-2-b5316e82f61a@linaro.org>
 <20241202-bald-just-guan-c5d41b@houat>
 <0d4dfb60-e2e6-484a-993a-41d1229c62fb@sirena.org.uk>
Message-ID: <20241202-daft-fervent-grouse-2c0cf7@houat>

On Mon, Dec 02, 2024 at 12:59:22PM +0000, Mark Brown wrote:
> On Mon, Dec 02, 2024 at 01:06:09PM +0100, Maxime Ripard wrote:
> > On Sun, Dec 01, 2024 at 02:44:06AM +0200, Dmitry Baryshkov wrote:
> 
> > > The no_capture_mute flag might differ from platform to platform,
> > > especially in the case of the wrapping implementations, like the
> 
> > I appreciate it might be a dumb question, but I never really understood
> > what no_capture_mute was all about. And in that context, why some
> > drivers would need / use it, and some won't.
> 
> It's just what it says, it's a flag saying the device doesn't support
> muting the capture side.

Right, but then HDMI is output only, so it still doesn't really make
sense to me why we'd want to mute the capture side?

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

From broonie at kernel.org  Mon Dec  2 05:30:39 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 02 Dec 2024 13:30:39 +0000
Subject: [PATCH] spi: apple: Set use_gpio_descriptors to true
In-Reply-To: <20241127-gpio-descs-v1-1-c586b518a7d5@gmail.com>
References: <20241127-gpio-descs-v1-1-c586b518a7d5@gmail.com>
Message-ID: <173314623984.54221.9478516701597362964.b4-ty@kernel.org>

On Wed, 27 Nov 2024 23:18:29 +0100, Sasha Finkelstein wrote:
> There is at least one peripheral that is attached to this
> controller and can not use native CS. Make it possible to use
> a GPIO instead.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: apple: Set use_gpio_descriptors to true
      commit: 1b299bd0c22887543b276bcc5b4ed26f5bd83ae4

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  Mon Dec  2 05:39:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Dec 2024 13:39:58 +0000
Subject: [PATCH v5 2/9] ASoC: hdmi-codec: move no_capture_mute to struct
 hdmi_codec_pdata
In-Reply-To: <20241202-daft-fervent-grouse-2c0cf7@houat>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-2-b5316e82f61a@linaro.org>
 <20241202-bald-just-guan-c5d41b@houat>
 <0d4dfb60-e2e6-484a-993a-41d1229c62fb@sirena.org.uk>
 <20241202-daft-fervent-grouse-2c0cf7@houat>
Message-ID: <8a6bb3c4-73ee-4608-a59f-1590f52b8db4@sirena.org.uk>

On Mon, Dec 02, 2024 at 02:29:55PM +0100, Maxime Ripard wrote:
> On Mon, Dec 02, 2024 at 12:59:22PM +0000, Mark Brown wrote:
> > On Mon, Dec 02, 2024 at 01:06:09PM +0100, Maxime Ripard wrote:
> > > On Sun, Dec 01, 2024 at 02:44:06AM +0200, Dmitry Baryshkov wrote:

> > > > The no_capture_mute flag might differ from platform to platform,
> > > > especially in the case of the wrapping implementations, like the

> > > I appreciate it might be a dumb question, but I never really understood
> > > what no_capture_mute was all about. And in that context, why some
> > > drivers would need / use it, and some won't.

> > It's just what it says, it's a flag saying the device doesn't support
> > muting the capture side.

> Right, but then HDMI is output only, so it still doesn't really make
> sense to me why we'd want to mute the capture side?

This is an ASoC patch and you didn't mention where the flag was...
there's going to be HDMI capture hardware 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/20241202/9cd53645/attachment.sig>

From krzk at kernel.org  Mon Dec  2 05:40:42 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 14:40:42 +0100
Subject: [PATCH 3/4] arm64: defconfig: enable Maxim max1720x driver
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-3-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-3-98d2fa7bfe30@uclouvain.be>
Message-ID: <a917cb0b-68de-4916-9a4d-021a8da37289@kernel.org>

On 02/12/2024 14:07, Thomas Antoine via B4 Relay wrote:
> From: Thomas Antoine <t.antoine at uclouvain.be>
> 
> Enable the Maxim max1720x as it is used by the gs101-oriole
> (Google Pixel 6) board.
> 
> Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
> ---
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index d13218d0c30f458d9c555ab9771a1fd9139ce1aa..e7523e53f2ed26bab39e64f3b2d8c8afc7c1a1f0 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -675,6 +675,7 @@ CONFIG_NVMEM_REBOOT_MODE=m
>  CONFIG_BATTERY_QCOM_BATTMGR=m
>  CONFIG_BATTERY_SBS=m
>  CONFIG_BATTERY_BQ27XXX=y
> +CONFIG_BATTERY_MAX1720X=m
>  CONFIG_BATTERY_MAX17042=m

Are you sure this is placed according to savedefconfig order?

Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec  2 05:39:25 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 14:39:25 +0100
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
Message-ID: <ec4bd953-1cd7-46bc-9415-0983bb9cbe89@kernel.org>

On 02/12/2024 14:07, Thomas Antoine via B4 Relay wrote:
> From: Thomas Antoine <t.antoine at uclouvain.be>
> 
> As the Maxim max77759 fuel gauge has no non-volatile memory slave address,


s/max77759/MAX77759/

Please explain the device in general, e.g. fuel gauge is only one part
of the PMIC chip. Otherwise 'fg' compatible suffix would not be justified.

> make it non-obligatory. Except for this, the max77759 seems to behave the
> same as the max1720x.
> 
> Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
> ---
>  .../devicetree/bindings/power/supply/maxim,max17201.yaml   | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max17201.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max17201.yaml
> index fe3dd9bd5585618e45220c51023391a5b21acfd2..417fc2c4a1c1961654bc54ec1ac24602012f3335 100644
> --- a/Documentation/devicetree/bindings/power/supply/maxim,max17201.yaml
> +++ b/Documentation/devicetree/bindings/power/supply/maxim,max17201.yaml
> @@ -16,6 +16,7 @@ properties:
>    compatible:
>      oneOf:
>        - const: maxim,max17201
> +      - const: maxim,max77759-fg
>        - items:
>            - enum:
>                - maxim,max17205
> @@ -25,11 +26,13 @@ properties:
>      items:
>        - description: ModelGauge m5 registers
>        - description: Nonvolatile registers
> +    minItems: 1
>  
>    reg-names:
>      items:
>        - const: m5
>        - const: nvmem
> +    minItems: 1

You need allOf:if:then section narrowing it per each variant.

>  
>    interrupts:
>      maxItems: 1
> @@ -56,3 +59,14 @@ examples:
>          interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
>        };
>      };
> +  - |
> +    i2c {
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +
> +      fuel-gauge at 36 {
> +        compatible = "maxim,max77759-fg";


No need for new example if it differs with one property.



Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec  2 05:41:34 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 14:41:34 +0100
Subject: [PATCH 4/4] arm64: dts: exynos: gs101-oriole: enable Maxim
 max77759 fuel gauge
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-4-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-4-98d2fa7bfe30@uclouvain.be>
Message-ID: <68b897f0-5583-4d09-87d5-4ff4d3080ef7@kernel.org>

On 02/12/2024 14:07, Thomas Antoine via B4 Relay wrote:
> From: Thomas Antoine <t.antoine at uclouvain.be>
> 
> Add the node for the max77759 fuel gauge as a slave of the i2c.
> 
> The fuel gauge has been tested and seems to give coherent results.
> Manual activation of the charger via i2cset shows that the sign of
> the current does indicate charging/discharging status.
> 
> Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
> ---
>  arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
> index 387fb779bd29ea3812331a7951f03b181c5fe659..4c45dd6fd0173889234b7b04d7abb4b382c7706c 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
> +++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
> @@ -90,6 +90,13 @@ eeprom: eeprom at 50 {
>  &hsi2c_12 {
>  	status = "okay";
>  	/* TODO: add the devices once drivers exist */


Is this still applicable?

> +
> +	fuel-gauge at 36 {
> +		compatible = "maxim,max77759-fg";
> +		reg = <0x36>;
> +		reg-names = "m5";


No interrupts?

> +	};
> +


Do not add stray blank lines.

Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec  2 05:46:24 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 14:46:24 +0100
Subject: [PATCH v2 11/18] arm64: dts: mediatek: mt7988: add chosen node on
 bpi-r4
In-Reply-To: <20241202122602.30734-12-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-12-linux@fw-web.de>
Message-ID: <0fb58a4a-7bad-4623-99c8-67f5763558bb@kernel.org>

On 02/12/2024 13:25, Frank Wunderlich wrote:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add chosen node on Bananapi R4 board with stdout and default bootargs.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
>  arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> index 9037f35857a9..1c2a806f6f6c 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> @@ -9,6 +9,11 @@ / {
>  	model = "Banana Pi BPI-R4";
>  	chassis-type = "embedded";
>  
> +	chosen {
> +		stdout-path = &serial0;
> +		bootargs = "console=ttyS0,115200n1";

Drop or merge into stdout path.

Best regards,
Krzysztof


From yangyicong at huawei.com  Mon Dec  2 05:55:01 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 21:55:01 +0800
Subject: [PATCH 2/5] arm64: Add support for FEAT_{LS64, LS64_V, LS64_ACCDATA}
In-Reply-To: <20241202135504.14252-1-yangyicong@huawei.com>
References: <20241202135504.14252-1-yangyicong@huawei.com>
Message-ID: <20241202135504.14252-3-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Armv8.7 introduces single-copy atomic 64-byte loads and stores
instructions and its variants named under FEAT_{LS64, LS64_V,
LS64_ACCDATA}. These features are identified by ID_AA64ISAR1_EL1.LS64
and the use of such instructions in userspace (EL0) can be trapped.
In order to support the use of corresponding instructions in userspace:
- Make ID_AA64ISAR1_EL1.LS64 visbile to userspace
- Add identifying and enabling in the cpufeature list
- Expose these support of these features to userspace through HWCAP
  and cpuinfo

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 Documentation/arch/arm64/booting.rst    | 28 ++++++++++
 Documentation/arch/arm64/elf_hwcaps.rst |  9 ++++
 arch/arm64/include/asm/hwcap.h          |  3 ++
 arch/arm64/include/uapi/asm/hwcap.h     |  3 ++
 arch/arm64/kernel/cpufeature.c          | 70 ++++++++++++++++++++++++-
 arch/arm64/kernel/cpuinfo.c             |  3 ++
 arch/arm64/tools/cpucaps                |  3 ++
 7 files changed, 118 insertions(+), 1 deletion(-)

diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
index 3278fb4bf219..c35cfe9da501 100644
--- a/Documentation/arch/arm64/booting.rst
+++ b/Documentation/arch/arm64/booting.rst
@@ -449,6 +449,34 @@ Before jumping into the kernel, the following conditions must be met:
 
     - HFGWTR_EL2.nGCS_EL0 (bit 52) must be initialised to 0b1.
 
+  For CPUs support for 64-byte loads and stores without status (FEAT_LS64):
+
+  - If the kernel is entered at EL1 and EL2 is present:
+
+    - HCRX_EL2.EnALS (bit 1) must be initialised to 0b1.
+
+  For CPUs support for 64-byte loads and stores with status (FEAT_LS64_V):
+
+  - If the kernel is entered at EL1 and EL2 is present:
+
+    - HCRX_EL2.EnASR (bit 2) must be initialised to 0b1.
+
+  For CPUs support for 64-byte EL0 stores with status (FEAT_LS64_ACCDATA):
+
+  - If EL3 is present:
+
+    - SCR_EL3.EnAS0 (bit 36) must be initialised to 0b1.
+
+    - SCR_EL3.ADEn (bit 37) must be initialised to 0b1.
+
+  - If the kernel is entered at EL1 and EL2 is present:
+
+    - HCRX_EL2.EnAS0 (bit 0) must be initialised to 0b1.
+
+    - HFGRTR_EL2.nACCDATA_EL1 (bit 50) must be initialised to 0b1.
+
+    - HFGWTR_EL2.nACCDATA_EL1 (bit 50) 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
diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst
index 2ff922a406ad..6cb2594f0803 100644
--- a/Documentation/arch/arm64/elf_hwcaps.rst
+++ b/Documentation/arch/arm64/elf_hwcaps.rst
@@ -372,6 +372,15 @@ HWCAP2_SME_SF8DP4
 HWCAP2_POE
     Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001.
 
+HWCAP3_LS64
+    Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0001.
+
+HWCAP3_LS64_V
+    Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0010.
+
+HWCAP3_LS64_ACCDATA
+    Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0011.
+
 4. Unused AT_HWCAP bits
 -----------------------
 
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 2b6c61c608e2..ac1d576dfcd4 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -161,6 +161,9 @@
 #define KERNEL_HWCAP_POE		__khwcap2_feature(POE)
 
 #define __khwcap3_feature(x)		(const_ilog2(HWCAP3_ ## x) + 128)
+#define KERNEL_HWCAP_LS64              __khwcap3_feature(LS64)
+#define KERNEL_HWCAP_LS64_V            __khwcap3_feature(LS64_V)
+#define KERNEL_HWCAP_LS64_ACCDATA      __khwcap3_feature(LS64_ACCDATA)
 
 /*
  * 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 48d46b768eae..e70f91889fd6 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -128,5 +128,8 @@
 /*
  * HWCAP3 flags - for AT_HWCAP3
  */
+#define HWCAP3_LS64		(1UL << 0)
+#define HWCAP3_LS64_V		(1UL << 1)
+#define HWCAP3_LS64_ACCDATA	(1UL << 2)
 
 #endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 15f175e458c3..9e45c1b54372 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -229,7 +229,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
-	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_LS64_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_LS64_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_XS_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_I8MM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_DGH_SHIFT, 4, 0),
@@ -2246,6 +2246,47 @@ static void cpu_enable_e0pd(struct arm64_cpu_capabilities const *cap)
 }
 #endif /* CONFIG_ARM64_E0PD */
 
+static bool has_ls64(const struct arm64_cpu_capabilities *entry, int __unused)
+{
+	u64 ls64;
+
+	ls64 = cpuid_feature_extract_field(__read_sysreg_by_encoding(entry->sys_reg),
+					   entry->field_pos, entry->sign);
+
+	if (ls64 == ID_AA64ISAR1_EL1_LS64_NI ||
+	    ls64 > ID_AA64ISAR1_EL1_LS64_LS64_ACCDATA)
+		return false;
+
+	if (entry->capability == ARM64_HAS_LS64 &&
+	    ls64 >= ID_AA64ISAR1_EL1_LS64_LS64)
+		return true;
+
+	if (entry->capability == ARM64_HAS_LS64_V &&
+	    ls64 >= ID_AA64ISAR1_EL1_LS64_LS64_V)
+		return true;
+
+	if (entry->capability == ARM64_HAS_LS64_ACCDATA &&
+	    ls64 >= ID_AA64ISAR1_EL1_LS64_LS64_ACCDATA)
+		return true;
+
+	return false;
+}
+
+static void cpu_enable_ls64(struct arm64_cpu_capabilities const *cap)
+{
+	sysreg_clear_set(sctlr_el1, SCTLR_EL1_EnALS, SCTLR_EL1_EnALS);
+}
+
+static void cpu_enable_ls64_v(struct arm64_cpu_capabilities const *cap)
+{
+	sysreg_clear_set(sctlr_el1, SCTLR_EL1_EnASR, SCTLR_EL1_EnASR);
+}
+
+static void cpu_enable_ls64_accdata(struct arm64_cpu_capabilities const *cap)
+{
+	sysreg_clear_set(sctlr_el1, SCTLR_EL1_EnAS0, SCTLR_EL1_EnAS0);
+}
+
 #ifdef CONFIG_ARM64_PSEUDO_NMI
 static bool can_use_gic_priorities(const struct arm64_cpu_capabilities *entry,
 				   int scope)
@@ -2991,6 +3032,30 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, GCS, IMP)
 	},
 #endif
+	{
+		.desc = "LS64",
+		.capability = ARM64_HAS_LS64,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_ls64,
+		.cpu_enable = cpu_enable_ls64,
+		ARM64_CPUID_FIELDS(ID_AA64ISAR1_EL1, LS64, LS64)
+	},
+	{
+		.desc = "LS64_V",
+		.capability = ARM64_HAS_LS64_V,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_ls64,
+		.cpu_enable = cpu_enable_ls64_v,
+		ARM64_CPUID_FIELDS(ID_AA64ISAR1_EL1, LS64, LS64_V)
+	},
+	{
+		.desc = "LS64_ACCDATA",
+		.capability = ARM64_HAS_LS64_ACCDATA,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_ls64,
+		.cpu_enable = cpu_enable_ls64_accdata,
+		ARM64_CPUID_FIELDS(ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA)
+	},
 	{},
 };
 
@@ -3088,6 +3153,9 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64ISAR1_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_EBF16),
 	HWCAP_CAP(ID_AA64ISAR1_EL1, DGH, IMP, CAP_HWCAP, KERNEL_HWCAP_DGH),
 	HWCAP_CAP(ID_AA64ISAR1_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_I8MM),
+	HWCAP_CAP(ID_AA64ISAR1_EL1, LS64, LS64, CAP_HWCAP, KERNEL_HWCAP_LS64),
+	HWCAP_CAP(ID_AA64ISAR1_EL1, LS64, LS64_V, CAP_HWCAP, KERNEL_HWCAP_LS64_V),
+	HWCAP_CAP(ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA, CAP_HWCAP, KERNEL_HWCAP_LS64_ACCDATA),
 	HWCAP_CAP(ID_AA64ISAR2_EL1, LUT, IMP, CAP_HWCAP, KERNEL_HWCAP_LUT),
 	HWCAP_CAP(ID_AA64ISAR3_EL1, FAMINMAX, IMP, CAP_HWCAP, KERNEL_HWCAP_FAMINMAX),
 	HWCAP_CAP(ID_AA64MMFR2_EL1, AT, IMP, CAP_HWCAP, KERNEL_HWCAP_USCAT),
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index d79e88fccdfc..b140852955be 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -81,6 +81,9 @@ static const char *const hwcap_str[] = {
 	[KERNEL_HWCAP_PACA]		= "paca",
 	[KERNEL_HWCAP_PACG]		= "pacg",
 	[KERNEL_HWCAP_GCS]		= "gcs",
+	[KERNEL_HWCAP_LS64]		= "ls64",
+	[KERNEL_HWCAP_LS64_V]		= "ls64_v",
+	[KERNEL_HWCAP_LS64_ACCDATA]	= "ls64_accdata",
 	[KERNEL_HWCAP_DCPODP]		= "dcpodp",
 	[KERNEL_HWCAP_SVE2]		= "sve2",
 	[KERNEL_HWCAP_SVEAES]		= "sveaes",
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index eb17f59e543c..0454d5e64cbe 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -42,6 +42,9 @@ HAS_HCX
 HAS_LDAPR
 HAS_LPA2
 HAS_LSE_ATOMICS
+HAS_LS64
+HAS_LS64_V
+HAS_LS64_ACCDATA
 HAS_MOPS
 HAS_NESTED_VIRT
 HAS_PAN
-- 
2.24.0



From krzysztof.kozlowski at linaro.org  Mon Dec  2 06:02:06 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 02 Dec 2024 15:02:06 +0100
Subject: [PATCH] pinctrl: samsung: Fix irq handling if an error occurs
 in exynos_irq_demux_eint16_31()
In-Reply-To: <f148d823acfb3326a115bd49a0eed60f2345f909.1731844995.git.christophe.jaillet@wanadoo.fr>
References: <f148d823acfb3326a115bd49a0eed60f2345f909.1731844995.git.christophe.jaillet@wanadoo.fr>
Message-ID: <173314812685.47615.16378245073169097611.b4-ty@linaro.org>


On Sun, 17 Nov 2024 13:03:32 +0100, Christophe JAILLET wrote:
> chained_irq_enter(() should be paired with a corresponding
> chained_irq_exit().
> 
> Here, if clk_enable() fails, a early return occurs and chained_irq_exit()
> is not called.
> 
> Add a new label and a goto for fix it.
> 
> [...]

Applied, thanks!

[1/1] pinctrl: samsung: Fix irq handling if an error occurs in exynos_irq_demux_eint16_31()
      https://git.kernel.org/pinctrl/samsung/c/f686a2b52e9d78cf401f1b7f446bf0c3a81ebcc0

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



From robh at kernel.org  Mon Dec  2 05:55:27 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Dec 2024 07:55:27 -0600
Subject: [PATCH] PCI: check bridge->bus in pci_host_common_remove
In-Reply-To: <20241202092902.rp6xb3f64llpabbi@thinkpad>
References: <20241028084644.3778081-1-peng.fan@oss.nxp.com>
 <20241115062005.6ifvr6ens2qnrrrf@thinkpad> <PAXPR04MB8459D1507CA69498D8C38E0488242@PAXPR04MB8459.eurprd04.prod.outlook.com>
 <20241115144720.ovsyq2ani47norby@thinkpad> <20241127195650.GA4132105-robh@kernel.org>
 <20241202092902.rp6xb3f64llpabbi@thinkpad>
Message-ID: <CAL_Jsq+R39jtCeDecpEHbKq+4N-uirMQmsuNG1NaVe1Vnnnv3Q@mail.gmail.com>

On Mon, Dec 2, 2024 at 3:29?AM Manivannan Sadhasivam
<manivannan.sadhasivam at linaro.org> wrote:
>
> On Wed, Nov 27, 2024 at 01:56:50PM -0600, Rob Herring wrote:
> > On Fri, Nov 15, 2024 at 08:17:20PM +0530, Manivannan Sadhasivam wrote:
> > > On Fri, Nov 15, 2024 at 10:14:10AM +0000, Peng Fan wrote:
> > > > Hi Manivannan,
> > > >
> > > > > Subject: Re: [PATCH] PCI: check bridge->bus in
> > > > > pci_host_common_remove
> > > > >
> > > > > On Mon, Oct 28, 2024 at 04:46:43PM +0800, Peng Fan (OSS) wrote:
> > > > > > From: Peng Fan <peng.fan at nxp.com>
> > > > > >
> > > > > > When PCI node was created using an overlay and the overlay is
> > > > > > reverted/destroyed, the "linux,pci-domain" property no longer exists,
> > > > > > so of_get_pci_domain_nr will return failure. Then
> > > > > > of_pci_bus_release_domain_nr will actually use the dynamic IDA,
> > > > > even
> > > > > > if the IDA was allocated in static IDA. So the flow is as below:
> > > > > > A: of_changeset_revert
> > > > > >     pci_host_common_remove
> > > > > >      pci_bus_release_domain_nr
> > > > > >        of_pci_bus_release_domain_nr
> > > > > >          of_get_pci_domain_nr      # fails because overlay is gone
> > > > > >          ida_free(&pci_domain_nr_dynamic_ida)
> > > > > >
> > > > > > With driver calls pci_host_common_remove explicity, the flow
> > > > > becomes:
> > > > > > B pci_host_common_remove
> > > > > >    pci_bus_release_domain_nr
> > > > > >     of_pci_bus_release_domain_nr
> > > > > >      of_get_pci_domain_nr      # succeeds in this order
> > > > > >       ida_free(&pci_domain_nr_static_ida)
> > > > > > A of_changeset_revert
> > > > > >    pci_host_common_remove
> > > > > >
> > > > > > With updated flow, the pci_host_common_remove will be called
> > > > > twice, so
> > > > > > need to check 'bridge->bus' to avoid accessing invalid pointer.
> > > > > >
> > > > > > Fixes: c14f7ccc9f5d ("PCI: Assign PCI domain IDs by ida_alloc()")
> > > > > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > > >
> > > > > I went through the previous discussion [1] and I couldn't see an
> > > > > agreement on the point raised by Bjorn on 'removing the host bridge
> > > > > before the overlay'.
> > > >
> > > > This patch is an agreement to Bjorn's idea.
> > > >
> > > > I have added pci_host_common_remove to remove host bridge
> > > > before removing overlay as I wrote in commit log.
> > > >
> > > > But of_changeset_revert will still runs into pci_host_
> > > > common_remove to remove the host bridge again. Per
> > > > my view, the design of of_changeset_revert to remove
> > > > the device tree node will trigger device remove, so even
> > > > pci_host_common_remove was explicitly used before
> > > > of_changeset_revert. The following call to of_changeset_revert
> > > > will still call pci_host_common_remove.
> > > >
> > > > So I did this patch to add a check of 'bus' to avoid remove again.
> > > >
> > >
> > > Ok. I think there was a misunderstanding. Bjorn's example driver,
> > > 'i2c-demux-pinctrl' applies the changeset, then adds the i2c adapter for its
> > > own. And in remove(), it does the reverse.
> > >
> > > But in your case, the issue is with the host bridge driver that gets probed
> > > because of the changeset. While with 'i2c-demux-pinctrl' driver, it only
> > > applies the changeset. So we cannot compare both drivers. I believe in your
> > > case, 'i2c-demux-pinctrl' becomes 'jailhouse', isn't it?
> > >
> > > So in your case, changeset is applied by jailhouse and that causes the
> > > platform device to be created for the host bridge and then the host bridge
> > > driver gets probed. So during destroy(), you call of_changeset_revert() that
> > > removes the platform device and during that process it removes the host bridge
> > > driver. The issue happens because during host bridge remove, it calls
> > > pci_remove_root_bus() and that tries to remove the domain_nr using
> > > pci_bus_release_domain_nr().
> > >
> > > But pci_bus_release_domain_nr() uses DT node to check whether to free the
> > > domain_nr from static IDA or dynamic IDA. And because there is no DT node exist
> > > at this time (it was already removed by of_changeset_revert()), it forces
> > > pci_bus_release_domain_nr() to use dynamic IDA even though the IDA was initially
> > > allocated from static IDA.
> >
> > Putting linux,pci-domain in an overlay is the same problem as aliases in
> > overlays[1]. It's not going to work well.
> >
> > IMO, you can have overlays, or you can have static domains. You can't
> > have both.
> >
>
> Okay.
>
> > > I think a neat way to solve this issue would be by removing the OF node only
> > > after removing all platform devices/drivers associated with that node. But I
> > > honestly do not know whether that is possible or not. Otherwise, any other
> > > driver that relies on the OF node in its remove() callback, could suffer from
> > > the same issue. And whatever fix we may come up with in PCI core, it will be a
> > > band-aid only.
> > >
> > > I'd like to check with Rob first about his opinion.
> >
> > If the struct device has an of_node set, there should be a reference
> > count on that node. But I think that only prevents the node from being
> > freed. It does not prevent the overlay from being detached. This is one
> > of many of the issues with overlays Frank painstakingly documented[2].
> >
>
> Ah, I do remember this page as Frank ended up creating it based on my
> continuous nudge to add CONFIG_FS interface for applying overlays.
>
> So why are we applying overlays in kernel now?

That's been the case for some time. Mostly it's been for fixups of old
to new bindings, but those all got dropped at some point. The in
kernel users are very specific use cases where we know something about
what's in the overlay. In contrast, configfs interface allows for any
change to any node or property with no control over it by the kernel.
Never say never, but I just don't see that ever happening upstream.

Rob


From yangyicong at huawei.com  Mon Dec  2 05:55:04 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 21:55:04 +0800
Subject: [PATCH 5/5] KVM: arm64: Handle DABT caused by LS64* instructions on unsupported memory
In-Reply-To: <20241202135504.14252-1-yangyicong@huawei.com>
References: <20241202135504.14252-1-yangyicong@huawei.com>
Message-ID: <20241202135504.14252-6-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

FEAT_LS64* instructions only support to access Device/Uncacheable
memory, otherwise a data abort for unsupported Exclusive or atomic
access (0x35) is generated per spec. It's implementation defined
whether the target exception level is routed and is possible to
implemented as route to EL2 on a VHE VM. Per DDI0487K.a Section
C3.2.12.2 Single-copy atomic 64-byte load/store:

  The check is performed against the resulting memory type after all
  enabled stages of translation. In this case the fault is reported
  at the final enabled stage of translation.

If it's implemented as generate the DABT to the final enabled stage
(stage-2), inject a DABT to the guest to handle it.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 arch/arm64/kvm/mmu.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index c9d46ad57e52..b7e6f0a27537 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1787,6 +1787,20 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		return 1;
 	}
 
+	/*
+	 * If instructions of FEAT_{LS64, LS64_V, LS64_ACCDATA} operated on
+	 * unsupported memory regions, a DABT for unsupported Exclusive or
+	 * atomic access is generated. It's implementation defined whether
+	 * the exception will be taken to, a stage-1 DABT or the final enabled
+	 * stage of translation (stage-2 in this case as we hit here). Inject
+	 * a DABT to the guest to handle it if it's implemented as a stage-2
+	 * DABT.
+	 */
+	if (esr_fsc_is_excl_atomic_fault(esr)) {
+		kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
+		return 1;
+	}
+
 	trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_esr(vcpu),
 			      kvm_vcpu_get_hfar(vcpu), fault_ipa);
 
-- 
2.24.0



From yangyicong at huawei.com  Mon Dec  2 05:55:03 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 21:55:03 +0800
Subject: [PATCH 4/5] arm64: Add ESR.DFSC definition of unsupported exclusive or atomic access
In-Reply-To: <20241202135504.14252-1-yangyicong@huawei.com>
References: <20241202135504.14252-1-yangyicong@huawei.com>
Message-ID: <20241202135504.14252-5-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

0x35 indicates IMPLEMENTATION DEFINED fault for Unsupported Exclusive or
Atomic access. Add ESR_ELx_FSC definition and corresponding wrapper.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 arch/arm64/include/asm/esr.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 94c9d537a7ad..1639e99f2bd6 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -122,6 +122,7 @@
 #define ESR_ELx_FSC_SEA_TTW(n)	(0x14 + (n))
 #define ESR_ELx_FSC_SECC	(0x18)
 #define ESR_ELx_FSC_SECC_TTW(n)	(0x1c + (n))
+#define ESR_ELx_FSC_EXCL_ATOMIC	(0x35)
 
 /* Status codes for individual page table levels */
 #define ESR_ELx_FSC_ACCESS_L(n)	(ESR_ELx_FSC_ACCESS + (n))
@@ -470,6 +471,13 @@ static inline bool esr_fsc_is_access_flag_fault(unsigned long esr)
 	       (esr == ESR_ELx_FSC_ACCESS_L(0));
 }
 
+static inline bool esr_fsc_is_excl_atomic_fault(unsigned long esr)
+{
+	esr = esr & ESR_ELx_FSC;
+
+	return esr == ESR_ELx_FSC_EXCL_ATOMIC;
+}
+
 /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */
 static inline bool esr_iss_is_eretax(unsigned long esr)
 {
-- 
2.24.0



From yangyicong at huawei.com  Mon Dec  2 05:55:02 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 21:55:02 +0800
Subject: [PATCH 3/5] kselftest/arm64: Add HWCAP test for FEAT_{LS64, LS64_V, LS64_ACCDATA}
In-Reply-To: <20241202135504.14252-1-yangyicong@huawei.com>
References: <20241202135504.14252-1-yangyicong@huawei.com>
Message-ID: <20241202135504.14252-4-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Add tests for FEAT_{LS64, LS64_V, LS64_ACCDATA}. Issue related
instructions if feature presents, no SIGILL should be received.
Since such instructions can only operate on Device memory or
non-cacheable memory, we may received a SIGBUS during the test.
Just ignore it since we only tested whether the instruction itself
can be issued as expected on platforms declaring the support of
such features.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 tools/testing/selftests/arm64/abi/hwcap.c | 127 ++++++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c
index 0029ed9c5c9a..6c826d4bb056 100644
--- a/tools/testing/selftests/arm64/abi/hwcap.c
+++ b/tools/testing/selftests/arm64/abi/hwcap.c
@@ -11,6 +11,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <linux/auxvec.h>
+#include <linux/compiler.h>
 #include <sys/auxv.h>
 #include <sys/prctl.h>
 #include <asm/hwcap.h>
@@ -452,6 +454,107 @@ static void lrcpc3_sigill(void)
 	              : "=r" (data0), "=r" (data1) : "r" (src) :);
 }
 
+static void ignore_signal(int sig, siginfo_t *info, void *context)
+{
+	ucontext_t *uc = context;
+
+	uc->uc_mcontext.pc += 4;
+}
+
+static void ls64_sigill(void)
+{
+	struct sigaction ign, old;
+	char src[64] __aligned(64) = { 1 };
+
+	/*
+	 * LS64, LS64_V, LS64_ACCDATA require target memory to be
+	 * Device/Non-cacheable and the completer supports these
+	 * instructions, otherwise we'll receive a SIGBUS. Since
+	 * we are only testing the ABI here, so just ignore the
+	 * SIGBUS and see if we can execute the instructions
+	 * without receiving a SIGILL. Restore the handler of
+	 * SIGBUS after this test.
+	 */
+	ign.sa_sigaction = ignore_signal;
+	ign.sa_flags = SA_SIGINFO | SA_RESTART;
+	sigemptyset(&ign.sa_mask);
+	sigaction(SIGBUS, &ign, &old);
+
+	register void *xn asm ("x8") = src;
+	register u64 xt_1 asm ("x0");
+	register u64 __maybe_unused xt_2 asm ("x1");
+	register u64 __maybe_unused xt_3 asm ("x2");
+	register u64 __maybe_unused xt_4 asm ("x3");
+	register u64 __maybe_unused xt_5 asm ("x4");
+	register u64 __maybe_unused xt_6 asm ("x5");
+	register u64 __maybe_unused xt_7 asm ("x6");
+	register u64 __maybe_unused xt_8 asm ("x7");
+
+	/* LD64B x0, [x8] */
+	asm volatile(".inst 0xf83fd100" : "=r" (xt_1) : "r" (xn));
+
+	/* ST64B x0, [x8] */
+	asm volatile(".inst 0xf83f9100" : : "r" (xt_1), "r" (xn));
+
+	sigaction(SIGBUS, &old, NULL);
+}
+
+static void ls64_v_sigill(void)
+{
+	struct sigaction ign, old;
+	char dst[64] __aligned(64);
+
+	/* See comment in ls64_sigill() */
+	ign.sa_sigaction = ignore_signal;
+	ign.sa_flags = SA_SIGINFO | SA_RESTART;
+	sigemptyset(&ign.sa_mask);
+	sigaction(SIGBUS, &ign, &old);
+
+	register void *xn asm ("x8") = dst;
+	register u64 xt_1 asm ("x0") = 1;
+	register u64 __maybe_unused xt_2 asm ("x1") = 2;
+	register u64 __maybe_unused xt_3 asm ("x2") = 3;
+	register u64 __maybe_unused xt_4 asm ("x3") = 4;
+	register u64 __maybe_unused xt_5 asm ("x4") = 5;
+	register u64 __maybe_unused xt_6 asm ("x5") = 6;
+	register u64 __maybe_unused xt_7 asm ("x6") = 7;
+	register u64 __maybe_unused xt_8 asm ("x7") = 8;
+	register u64 st   asm ("x9");
+
+	/* ST64BV x9, x0, [x8] */
+	asm volatile(".inst 0xf829b100" : "=r" (st) : "r" (xt_1), "r" (xn));
+
+	sigaction(SIGBUS, &old, NULL);
+}
+
+static void ls64_accdata_sigill(void)
+{
+	struct sigaction ign, old;
+	char dst[64] __aligned(64);
+
+	/* See comment in ls64_sigill() */
+	ign.sa_sigaction = ignore_signal;
+	ign.sa_flags = SA_SIGINFO | SA_RESTART;
+	sigemptyset(&ign.sa_mask);
+	sigaction(SIGBUS, &ign, &old);
+
+	register void *xn asm ("x8") = dst;
+	register u64 xt_1 asm ("x0") = 1;
+	register u64 __maybe_unused xt_2 asm ("x1") = 2;
+	register u64 __maybe_unused xt_3 asm ("x2") = 3;
+	register u64 __maybe_unused xt_4 asm ("x3") = 4;
+	register u64 __maybe_unused xt_5 asm ("x4") = 5;
+	register u64 __maybe_unused xt_6 asm ("x5") = 6;
+	register u64 __maybe_unused xt_7 asm ("x6") = 7;
+	register u64 __maybe_unused xt_8 asm ("x7") = 8;
+	register u64 st asm ("x9");
+
+	/* ST64BV0 x9, x0, [x8] */
+	asm volatile(".inst 0xf829a100" : "=r" (st) : "r" (xt_1), "r" (xn));
+
+	sigaction(SIGBUS, &old, NULL);
+}
+
 static const struct hwcap_data {
 	const char *name;
 	unsigned long at_hwcap;
@@ -867,6 +970,30 @@ static const struct hwcap_data {
 		.sigill_fn = hbc_sigill,
 		.sigill_reliable = true,
 	},
+	{
+		.name = "LS64",
+		.at_hwcap = AT_HWCAP3,
+		.hwcap_bit = HWCAP3_LS64,
+		.cpuinfo = "ls64",
+		.sigill_fn = ls64_sigill,
+		.sigill_reliable = true,
+	},
+	{
+		.name = "LS64_V",
+		.at_hwcap = AT_HWCAP3,
+		.hwcap_bit = HWCAP3_LS64_V,
+		.cpuinfo = "ls64_v",
+		.sigill_fn = ls64_v_sigill,
+		.sigill_reliable = true,
+	},
+	{
+		.name = "LS64_ACCDATA",
+		.at_hwcap = AT_HWCAP3,
+		.hwcap_bit = HWCAP3_LS64_ACCDATA,
+		.cpuinfo = "ls64_accdata",
+		.sigill_fn = ls64_accdata_sigill,
+		.sigill_reliable = true,
+	},
 };
 
 typedef void (*sighandler_fn)(int, siginfo_t *, void *);
-- 
2.24.0



From yangyicong at huawei.com  Mon Dec  2 05:54:59 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 21:54:59 +0800
Subject: [PATCH 0/5] Add support for FEAT_{LS64, LS64_V, LS64_ACCDATA} and related tests
Message-ID: <20241202135504.14252-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Armv8.7 introduces single-copy atomic 64-byte loads and stores
instructions and its variants named under FEAT_{LS64, LS64_V,
LS64_ACCDATA}. Add support for Armv8.7 FEAT_{LS64, LS64_V, LS64_ACCDATA}:
- Add identifying and enabling in the cpufeature list
- Expose the support of these features to userspace through HWCAP3
  and cpuinfo
- Add related hwcap test
- Handle the trap of unsupported memory (normal/uncacheable) access in a VM

A real scenario for this feature is that the userspace driver can make use of
this to implement direct WQE (workqueue entry) - a mechanism to fill WQE
directly into the hardware.

This patchset also depends on Marc's patchset[1] for enabling related
features in a VM, HCRX trap handling, etc.

[1] https://lore.kernel.org/linux-arm-kernel/20240815125959.2097734-1-maz at kernel.org/

Tested with updated hwcap test:
On host:
root at localhost:/# dmesg | grep "All CPU(s) started"
[    1.600263] CPU: All CPU(s) started at EL2
root at localhost:/# ./hwcap
[snip...]
# LS64 present          
ok 169 cpuinfo_match_LS64
ok 170 sigill_LS64
ok 171 # SKIP sigbus_LS64
# LS64_V present
ok 172 cpuinfo_match_LS64_V
ok 173 sigill_LS64_V
ok 174 # SKIP sigbus_LS64_V
# LS64_ACCDATA present
ok 175 cpuinfo_match_LS64_ACCDATA
ok 176 sigill_LS64_ACCDATA
ok 177 # SKIP sigbus_LS64_ACCDATA
# Totals: pass:92 fail:0 xfail:0 xpass:0 skip:85 error:0

On guest:
root at localhost:/# dmesg | grep "All CPU(s) started"
[    1.375272] CPU: All CPU(s) started at EL1 
root at localhost:/# ./hwcap
[snip...]
# LS64 present
ok 169 cpuinfo_match_LS64
ok 170 sigill_LS64
ok 171 # SKIP sigbus_LS64
# LS64_V present
ok 172 cpuinfo_match_LS64_V
ok 173 sigill_LS64_V
ok 174 # SKIP sigbus_LS64_V
# LS64_ACCDATA present
ok 175 cpuinfo_match_LS64_ACCDATA
ok 176 sigill_LS64_ACCDATA
ok 177 # SKIP sigbus_LS64_ACCDATA
# Totals: pass:92 fail:0 xfail:0 xpass:0 skip:85 error:0

Yicong Yang (5):
  arm64: Provide basic EL2 setup for FEAT_{LS64, LS64_V, LS64_ACCDATA}
    usage at EL0/1
  arm64: Add support for FEAT_{LS64, LS64_V, LS64_ACCDATA}
  kselftest/arm64: Add HWCAP test for FEAT_{LS64, LS64_V, LS64_ACCDATA}
  arm64: Add ESR.DFSC definition of unsupported exclusive or atomic
    access
  KVM: arm64: Handle DABT caused by LS64* instructions on unsupported
    memory

 Documentation/arch/arm64/booting.rst      |  28 +++++
 Documentation/arch/arm64/elf_hwcaps.rst   |   9 ++
 arch/arm64/include/asm/el2_setup.h        |  26 ++++-
 arch/arm64/include/asm/esr.h              |   8 ++
 arch/arm64/include/asm/hwcap.h            |   3 +
 arch/arm64/include/uapi/asm/hwcap.h       |   3 +
 arch/arm64/kernel/cpufeature.c            |  70 +++++++++++-
 arch/arm64/kernel/cpuinfo.c               |   3 +
 arch/arm64/kvm/mmu.c                      |  14 +++
 arch/arm64/tools/cpucaps                  |   3 +
 tools/testing/selftests/arm64/abi/hwcap.c | 127 ++++++++++++++++++++++
 11 files changed, 291 insertions(+), 3 deletions(-)

-- 
2.24.0



From yangyicong at huawei.com  Mon Dec  2 05:55:00 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 2 Dec 2024 21:55:00 +0800
Subject: [PATCH 1/5] arm64: Provide basic EL2 setup for FEAT_{LS64, LS64_V, LS64_ACCDATA} usage at EL0/1
In-Reply-To: <20241202135504.14252-1-yangyicong@huawei.com>
References: <20241202135504.14252-1-yangyicong@huawei.com>
Message-ID: <20241202135504.14252-2-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Instructions introduced by FEAT_{LS64, LS64_V, LS64_ACCDATA} is
controlled by HCRX_EL2.{EnALS, EnASR, EnAS0}. Additionally
access of ACCDATA_EL1 for FEAT_LS64_ACCDATA is also affected by
FGT. Configure all of these to allow usage at EL0/1.

This doesn't mean these instructions are always available in
EL0/1 if provided. The hypervisor still have the control at
runtime.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 arch/arm64/include/asm/el2_setup.h | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 85ef966c08cd..446d3663840b 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -31,9 +31,22 @@
         /* Enable GCS if supported */
 	mrs_s	x1, SYS_ID_AA64PFR1_EL1
 	ubfx	x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
-	cbz	x1, .Lset_hcrx_\@
+	cbz	x1, .Lskip_gcs_hcrx_\@
 	orr	x0, x0, #HCRX_EL2_GCSEn
 
+.Lskip_gcs_hcrx_\@:
+	/* Enable LS64, LS64_V, LS64_ACCDATA if supported */
+	mrs_s	x1, SYS_ID_AA64ISAR1_EL1
+	ubfx	x1, x1, #ID_AA64ISAR1_EL1_LS64_SHIFT, #4
+	cbz	x1, .Lset_hcrx_\@
+	orr	x0, x0, #HCRX_EL2_EnALS
+	cmp	x1, #ID_AA64ISAR1_EL1_LS64_LS64_V
+	b.lt	.Lset_hcrx_\@
+	orr	x0, x0, #HCRX_EL2_EnASR
+	cmp	x1, #ID_AA64ISAR1_EL1_LS64_LS64_ACCDATA
+	b.lt	.Lset_hcrx_\@
+	orr	x0, x0, #HCRX_EL2_EnAS0
+
 .Lset_hcrx_\@:
 	msr_s	SYS_HCRX_EL2, x0
 .Lskip_hcrx_\@:
@@ -211,12 +224,21 @@
 	/* 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_\@
+	cbz	x1, .Lskip_gcs_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
 
+.Lskip_gcs_fgt_\@:
+	mrs_s	x1, SYS_ID_AA64ISAR1_EL1
+	ubfx	x1, x1, #ID_AA64ISAR1_EL1_LS64_SHIFT, #4
+	cmp	x1, #ID_AA64ISAR1_EL1_LS64_LS64_ACCDATA
+	b.ne	.Lset_fgt_\@
+
+	/* Disable the trapping of ACCDATA_EL1 */
+	orr	x0, x0, #HFGxTR_EL2_nACCDATA_EL1
+
 .Lset_fgt_\@:
 	msr_s	SYS_HFGRTR_EL2, x0
 	msr_s	SYS_HFGWTR_EL2, x0
-- 
2.24.0



From krzysztof.kozlowski at linaro.org  Mon Dec  2 06:02:11 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 02 Dec 2024 15:02:11 +0100
Subject: [PATCH v3 0/2] Add support for Samsung Galaxy S20 FE
 (SM-G780F/r8s) [SoC Exynos990]
In-Reply-To: <20241114143636.374-1-wachiturroxd150@gmail.com>
References: <20241114143636.374-1-wachiturroxd150@gmail.com>
Message-ID: <173314813121.47662.7729149107568659652.b4-ty@linaro.org>


On Thu, 14 Nov 2024 14:36:34 +0000, Sota4Ever wrote:
> From: Denzeel Oliva <wachiturroxd150 at gmail.com>
> 
> Hello :),
> 
> I'm a newbie and I started getting interested 1 year ago.
> Well, that's the beginning,
> until I learn more about kernels and the C language,
> which is important in that.
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: arm: samsung: Add compatible for Samsung Galaxy S20 FE (SM-G780F)
      https://git.kernel.org/krzk/linux/c/9163693d368f00c02fb8a07beabe2c2f18fe0a32
[2/2] arm64: dts: Add initial support for Samsung Galaxy S20 FE (r8s)
      https://git.kernel.org/krzk/linux/c/706119fbbdff2f95a62d1665fb4234ebe4e9392c

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



From rogerq at kernel.org  Mon Dec  2 06:02:39 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 2 Dec 2024 16:02:39 +0200
Subject: [PATCH net v2 1/2] net: ti: icssg-prueth: Fix firmware load
 sequence.
In-Reply-To: <9e06da02-52d1-48b3-84d2-d67789e42077@ti.com>
References: <20241128122931.2494446-1-m-malladi@ti.com>
 <20241128122931.2494446-2-m-malladi@ti.com>
 <a4071a1c-8c27-4464-9054-df9b3e317eab@kernel.org>
 <9e06da02-52d1-48b3-84d2-d67789e42077@ti.com>
Message-ID: <85affbbe-5793-4402-ad75-34eec3b318df@kernel.org>



On 02/12/2024 12:07, Malladi, Meghana wrote:
> 
> 
> On 11/29/2024 6:26 PM, Roger Quadros wrote:
>> Hi,
>>
>> On 28/11/2024 14:29, Meghana Malladi wrote:
>>> From: MD Danish Anwar <danishanwar at ti.com>
>>>
>>> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
>>> and SLICE1. Currently whenever any ICSSG interface comes up we load the
>>> respective firmwares to PRU cores and whenever interface goes down, we
>>> stop the resective cores. Due to this, when SLICE0 goes down while
>>> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
>>> stopped. This results in clock jump for SLICE1 interface as the timesync
>>> related operations are no longer running.
>>>
>>> As there are interdependencies between SLICE0 and SLICE1 firmwares,
>>> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
>>> ICSSG interface is up.
>>>
>>> Use emacs_initialized as reference count to load the firmwares for the
>>> first and last interface up/down. Moving init_emac_mode and fw_offload_mode
>>> API outside of icssg_config to icssg_common_start API as they need
>>> to be called only once per firmware boot.
>>>
>>> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
>>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>>> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
>>> ---
>>>
>>> Hi all,
>>>
>>> This patch is based on net-next tagged next-2024110.
>>> v1:https://lore.kernel.org/all/20241106074040.3361730-2-m-malladi at ti.com
>>>
>>> Changes since v1 (v2-v1):
>>> - Moving the NULL check inside the function as suggested by
>>> Simon Horman <horms at kernel.org>
>>> - Introduce prueth_emac_common_start() and prueth_emac_common_stop()
>>> and move common code there as suggested by Roger Quadros <rogerq at kernel.org>
>>> - Moving init_emac_mode and fw_offload_mode API outside of icssg_config
>>> to icssg_common_start API as they need to be called only once per
>>> firmware boot
>>>
>>> ? drivers/net/ethernet/ti/icssg/icssg_config.c |? 45 ++++--
>>> ? drivers/net/ethernet/ti/icssg/icssg_config.h |?? 1 +
>>> ? drivers/net/ethernet/ti/icssg/icssg_prueth.c | 150 ++++++++++++-------
>>> ? drivers/net/ethernet/ti/icssg/icssg_prueth.h |?? 3 +
>>> ? 4 files changed, 133 insertions(+), 66 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
>>> index 5d2491c2943a..342150756cf7 100644
>>> --- a/drivers/net/ethernet/ti/icssg/icssg_config.c
>>> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
>>> @@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>>> ????? return 0;
>>> ? }
>>> ? -static void icssg_init_emac_mode(struct prueth *prueth)
>>> +void icssg_init_emac_mode(struct prueth *prueth)
>>> ? {
>>> ????? /* When the device is configured as a bridge and it is being brought
>>> ?????? * back to the emac mode, the host mac address has to be set as 0.
>>> @@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>>> ????? int i;
>>> ????? u8 mac[ETH_ALEN] = { 0 };
>>> ? -??? if (prueth->emacs_initialized)
>>> -??????? return;
>>> -
>>> ????? /* Set VLAN TABLE address base */
>>> ????? regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>>> ???????????????? addr <<? SMEM_VLAN_OFFSET);
>>> @@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>>> ????? /* Clear host MAC address */
>>> ????? icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
>>> ? }
>>> +EXPORT_SYMBOL_GPL(icssg_init_emac_mode);
>>> ? -static void icssg_init_fw_offload_mode(struct prueth *prueth)
>>> +void icssg_init_fw_offload_mode(struct prueth *prueth)
>>> ? {
>>> ????? u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET;
>>> ????? int i;
>>> ? -??? if (prueth->emacs_initialized)
>>> -??????? return;
>>> -
>>> ????? /* Set VLAN TABLE address base */
>>> ????? regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>>> ???????????????? addr <<? SMEM_VLAN_OFFSET);
>>> @@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth)
>>> ????????? icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr);
>>> ????? icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST);
>>> ? }
>>> +EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode);
>>> ? ? int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>>> ? {
>>> @@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>>> ????? struct icssg_flow_cfg __iomem *flow_cfg;
>>> ????? int ret;
>>> ? -??? if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>>> -??????? icssg_init_fw_offload_mode(prueth);
>>> -??? else
>>> -??????? icssg_init_emac_mode(prueth);
>>> -
>>> ????? memset_io(config, 0, TAS_GATE_MASK_LIST0);
>>> ????? icssg_miig_queues_init(prueth, slice);
>>> ? @@ -786,3 +777,31 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port)
>>> ????????? writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET);
>>> ? }
>>> ? EXPORT_SYMBOL_GPL(icssg_set_pvid);
>>> +
>>> +int emac_fdb_flow_id_updated(struct prueth_emac *emac)
>>> +{
>>> +??? struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
>>> +??? int slice = prueth_emac_slice(emac);
>>> +??? struct mgmt_cmd fdb_cmd = { 0 };
>>> +??? int ret = 0;
>>> +
>>> +??? fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
>>> +??? fdb_cmd.type?? = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
>>> +??? fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq);
>>> +??? fdb_cmd.param? = 0;
>>> +
>>> +??? fdb_cmd.param |= (slice << 4);
>>> +??? fdb_cmd.cmd_args[0] = 0;
>>> +
>>> +??? ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp);
>>> +
>>> +??? if (ret)
>>> +??????? return ret;
>>> +
>>> +??? WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum);
>>> +??? if (fdb_cmd_rsp.status == 1)
>>> +??????? return 0;
>>> +
>>> +??? return -EINVAL;
>>> +}
>>> +EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated);
>>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
>>> index 92c2deaa3068..c884e9fa099e 100644
>>> --- a/drivers/net/ethernet/ti/icssg/icssg_config.h
>>> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
>>> @@ -55,6 +55,7 @@ struct icssg_rxq_ctx {
>>> ? #define ICSSG_FW_MGMT_FDB_CMD_TYPE??? 0x03
>>> ? #define ICSSG_FW_MGMT_CMD_TYPE??????? 0x04
>>> ? #define ICSSG_FW_MGMT_PKT??????? 0x80000000
>>> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW??? 0x05
>>> ? ? struct icssg_r30_cmd {
>>> ????? u32 cmd[4];
>>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>>> index c568c84a032b..3a495b5d010c 100644
>>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>>> @@ -164,11 +164,11 @@ static struct icssg_firmwares icssg_emac_firmwares[] = {
>>> ????? }
>>> ? };
>>> ? -static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>> +static int prueth_emac_start(struct prueth *prueth, int slice)
>>> ? {
>>> ????? struct icssg_firmwares *firmwares;
>>> ????? struct device *dev = prueth->dev;
>>> -??? int slice, ret;
>>> +??? int ret;
>>> ? ????? if (prueth->is_switch_mode)
>>> ????????? firmwares = icssg_switch_firmwares;
>>> @@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>> ????? else
>>> ????????? firmwares = icssg_emac_firmwares;
>>> ? -??? slice = prueth_emac_slice(emac);
>>> -??? if (slice < 0) {
>>> -??????? netdev_err(emac->ndev, "invalid port\n");
>>> -??????? return -EINVAL;
>>> -??? }
>>> -
>>> -??? ret = icssg_config(prueth, emac, slice);
>>> -??? if (ret)
>>> -??????? return ret;
>>> -
>>> ????? ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
>>> ????? ret = rproc_boot(prueth->pru[slice]);
>>> ????? if (ret) {
>>> @@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>> ????????? goto halt_rtu;
>>> ????? }
>>> ? -??? emac->fw_running = 1;
>>> ????? return 0;
>>> ? ? halt_rtu:
>>> @@ -220,6 +209,77 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>> ????? return ret;
>>> ? }
>>> ? +static int prueth_emac_common_start(struct prueth *prueth)
>>> +{
>>> +??? struct prueth_emac *emac;
>>> +??? int slice, ret;
>>> +
>>> +??? if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>>> +??????? return -EINVAL;
>>> +
>>> +??? /* clear SMEM and MSMC settings for all slices */
>>> +??? memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
>>> +??? memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
>>> +
>>> +??? icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
>>> +??? icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
>>> +
>>> +??? if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>>> +??????? icssg_init_fw_offload_mode(prueth);
>>> +??? else
>>> +??????? icssg_init_emac_mode(prueth);
>>> +
>>> +??? for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>>> +??????? emac = prueth->emac[slice];
>>> +??????? if (emac) {
>>> +??????????? ret = icssg_config(prueth, emac, slice);
>>> +??????????? if (ret)
>>> +??????????????? return ret;
>>> +??????? }
>>> +??????? ret = prueth_emac_start(prueth, slice);
>>
>> if (ret)
>> ????return ret;
>>
>>> +??????? if (!ret && emac)
>>
>> Then no need to check for !ret
>>
> 
> To set emac->fw_running to 1, we need to ensure all the firmwares started without any failures, hence checking for !ret from prueth_emac_start and non-NULL emac before setting emac->fw_running to 1.
> 
>>> +??????????? emac->fw_running = 1;
>>> +??? }
>>> +
>>> +??? emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>>> +?????????? prueth->emac[ICSS_SLICE1];
>>> +??? ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>>> +??????????????? emac, IEP_DEFAULT_CYCLE_TIME_NS);
>>> +??? if (ret) {
>>> +??????? dev_err(prueth->dev, "Failed to initialize IEP module\n");
>>> +??????? return ret;
>>> +??? }
>>
>> If we return error anywhere in this function will the caller take
>> care of cleaning up?
>> i.e. icssg_class_disable(), stopping any started cores, icss_iep_exit?
>>
> 
> No, caller of this function doesn't take care of the cleaning. What do you think about adding appropriate labels inside
> prueth_emac_common_start() to handle error cases instead of letting the caller handle them ?
> 
>> You can't rely on prueth_emac_common_stop() as all cores might not
>> have started and iep_init may not have been called.
>> But you can if you check and call only if required.
>> e.g. fw_running flag can be used to track if cores were started.
>>
> 
> Yes agreed. I will add this change and call prueth_emac_common_stop() in case of failure.
> 
>>> +
>>
>> Shouldn't we be setting emacs->initialized here and get rid of doing that
>> in emac_ndo_open()?
>>
>> then you can track it to call icss_iep_exit().
>>
> 
> No. I have tried that, but emacs->initialized is needed by the caller to call prueth_emac_common_start() and prueth_emac_common_stop() only once. Moving this inside will cause above two functions to never get called.
> Also we should have a good placeholder for emacs->initialized++/--, which is inside ndo_open() and ndo_stop().

ok.

> 
>>> +??? return 0;
>>> +}
>>> +
>>> +static int prueth_emac_common_stop(struct prueth *prueth)
>>> +{
>>> +??? struct prueth_emac *emac;
>>> +??? int slice;
>>> +
>>> +??? if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>>> +??????? return -EINVAL;
>>> +
>>> +??? icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
>>> +??? icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
>>> +
>>> +??? for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>>> +??????? emac = prueth->emac[slice];
>>> +??????? rproc_shutdown(prueth->txpru[slice]);
>>> +??????? rproc_shutdown(prueth->rtu[slice]);
>>> +??????? rproc_shutdown(prueth->pru[slice]);
>>> +??????? if (emac)
>>> +??????????? emac->fw_running = 0;
>>> +??? }
>>> +
>>> +??? emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>>> +?????????? prueth->emac[ICSS_SLICE1];
>>> +??? icss_iep_exit(emac->iep);
>>> +
>>
>> emacs->initialized = 0;
>>
> 
> This is already handled inside ndo_stop().
> 
>>> +??? return 0;
>>> +}
>>> +
>>> ? /* called back by PHY layer if there is change in link state of hw port*/
>>> ? static void emac_adjust_link(struct net_device *ndev)
>>> ? {
>>> @@ -543,23 +603,17 @@ 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;
>>> +??? struct icssg_flow_cfg __iomem *flow_cfg;
>>> ????? 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, false);
>>
>> This is changing existing behaviour.
>> If network device is stopped and started we expect all classifiers to be set to defaults?
>>
> 
> This is an expected change. When the firmwares are loaded the firmware sets the correct classifier values for that slice. Since we are loading firmwares for both the slices at once, we need to set the classifiers to default before firmware load to avoid overwriting these values after the firmware load.
> 
>>> ????? icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
>>> ? ????? /* Notify the stack of the actual queue counts. */
>>> @@ -597,18 +651,23 @@ static int emac_ndo_open(struct net_device *ndev)
>>> ????????? goto cleanup_napi;
>>> ????? }
>>> ? -??? /* reset and start PRU firmware */
>>> -??? ret = prueth_emac_start(prueth, emac);
>>> -??? if (ret)
>>> -??????? goto free_rx_irq;
>>> +??? if (!prueth->emacs_initialized) {
>>> +??????? ret = prueth_emac_common_start(prueth);
>>> +??????? if (ret)
>>> +??????????? goto free_rx_irq;
>>
>> goto stop;
>>
>> so you can use pruet_emac_common_stop() to do the necessary cleanup.
>>
> 
> Yeah ok.
> 
>>> +??? }
>>> ? -??? icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>>> +??? flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
>>> +??? writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
>>> +??? ret = emac_fdb_flow_id_updated(emac);
>>> ? -??? if (!prueth->emacs_initialized) {
>>> -??????? ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>>> -??????????????????? emac, IEP_DEFAULT_CYCLE_TIME_NS);
>>> +??? if (ret) {
>>> +??????? netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
>>> +??????? goto stop;
>>> ????? }
>>> ? +??? icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>>> +
>>> ????? ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
>>> ???????????????????? IRQF_ONESHOT, dev_name(dev), emac);
>>> ????? if (ret)
>>> @@ -653,7 +712,7 @@ static int emac_ndo_open(struct net_device *ndev)
>>> ? free_tx_ts_irq:
>>> ????? free_irq(emac->tx_ts_irq, emac);
>>> ? stop:
>>> -??? prueth_emac_stop(emac);
>>> +??? prueth_emac_common_stop(prueth);
>>> ? free_rx_irq:
>>> ????? free_irq(emac->rx_chns.irq[rx_flow], emac);
>>> ? cleanup_napi:
>>> @@ -689,8 +748,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>>> ????? if (ndev->phydev)
>>> ????????? phy_stop(ndev->phydev);
>>> ? -??? icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
>>> -
>>> ????? if (emac->prueth->is_hsr_offload_mode)
>>> ????????? __dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
>>> ????? else
>>> @@ -729,10 +786,8 @@ static int emac_ndo_stop(struct net_device *ndev)
>>> ????? cancel_delayed_work_sync(&emac->stats_work);
>>> ? ????? if (prueth->emacs_initialized == 1)
>>> -??????? icss_iep_exit(emac->iep);
>>> -
>>> -??? /* stop PRUs */
>>> -??? prueth_emac_stop(emac);
>>> +??????? /* stop PRUs */
>>> +??????? prueth_emac_common_stop(prueth);
>>
>> You don't need this anymore as we will rely on stop: label to call
>> prueth_emac_common_stop();
>>
> 
> But this is inside emac_ndo_stop(), why do we need label here?

Sorry please ignore my comment. I missed that this was in emac_ndo_stop().

> 
>>> ? ????? free_irq(emac->tx_ts_irq, emac);
>>> ? @@ -1069,16 +1124,10 @@ static void prueth_emac_restart(struct prueth *prueth)
>>> ????? icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
>>> ? ????? /* Stop both pru cores for both PRUeth ports*/
>>> -??? prueth_emac_stop(emac0);
>>> -??? prueth->emacs_initialized--;
>>> -??? prueth_emac_stop(emac1);
>>> -??? prueth->emacs_initialized--;
>>> +??? prueth_emac_common_stop(prueth);
>>> ? ????? /* Start both pru cores for both PRUeth ports */
>>> -??? prueth_emac_start(prueth, emac0);
>>> -??? prueth->emacs_initialized++;
>>> -??? prueth_emac_start(prueth, emac1);
>>> -??? prueth->emacs_initialized++;
>>> +??? prueth_emac_common_start(prueth);
>>> ? ????? /* Enable forwarding for both PRUeth ports */
>>> ????? icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
>>> @@ -1413,13 +1462,10 @@ static int prueth_probe(struct platform_device *pdev)
>>> ????????? prueth->pa_stats = NULL;
>>> ????? }
>>> ? -??? if (eth0_node) {
>>> +??? if (eth0_node || eth1_node) {
>>> ????????? ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
>>> ????????? if (ret)
>>> ????????????? goto put_cores;
>>> -??? }
>>> -
>>> -??? if (eth1_node) {
>>> ????????? ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
>>> ????????? if (ret)
>>> ????????????? goto put_cores;
>>> @@ -1618,14 +1664,12 @@ static int prueth_probe(struct platform_device *pdev)
>>> ????? pruss_put(prueth->pruss);
>>> ? ? put_cores:
>>> -??? if (eth1_node) {
>>> -??????? prueth_put_cores(prueth, ICSS_SLICE1);
>>> -??????? of_node_put(eth1_node);
>>> -??? }
>>> -
>>> -??? if (eth0_node) {
>>> +??? if (eth0_node || eth1_node) {
>>> ????????? prueth_put_cores(prueth, ICSS_SLICE0);
>>> ????????? of_node_put(eth0_node);
>>> +
>>> +??????? prueth_put_cores(prueth, ICSS_SLICE1);
>>> +??????? of_node_put(eth1_node);
>>> ????? }
>>> ? ????? return ret;
>>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>> index f5c1d473e9f9..9fc72614d990 100644
>>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>> @@ -361,6 +361,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
>>> ?????????????? enum icssg_port_state_cmd state);
>>> ? void icssg_config_set_speed(struct prueth_emac *emac);
>>> ? void icssg_config_half_duplex(struct prueth_emac *emac);
>>> +void icssg_init_emac_mode(struct prueth *prueth);
>>> +void icssg_init_fw_offload_mode(struct prueth *prueth);
>>> ? ? /* Buffer queue helpers */
>>> ? int icssg_queue_pop(struct prueth *prueth, u8 queue);
>>> @@ -377,6 +379,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
>>> ???????????????? u8 untag_mask, bool add);
>>> ? u16 icssg_get_pvid(struct prueth_emac *emac);
>>> ? void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
>>> +int emac_fdb_flow_id_updated(struct prueth_emac *emac);
>>> ? #define prueth_napi_to_tx_chn(pnapi) \
>>> ????? container_of(pnapi, struct prueth_tx_chn, napi_tx)
>>> ? 
>>
> 

-- 
cheers,
-roger



From smostafa at google.com  Mon Dec  2 06:06:03 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Mon,  2 Dec 2024 14:06:03 +0000
Subject: [PATCH v2 1/2] iommu/io-pgtable-arm: Fix stage-2 concatenation with 16K
In-Reply-To: <20241202140604.422235-1-smostafa@google.com>
References: <20241202140604.422235-1-smostafa@google.com>
Message-ID: <20241202140604.422235-2-smostafa@google.com>

At the moment, io-pgtable-arm uses concatenation only if it is
possible at level 0, which misses a case where concatenation is
mandatory at level 1 according to R_SRKBC in Arm spec DDI0487 K.a.

Also, that means concatenation can be used when not mandated,
contradicting the comment on the code. However, these cases can only
happen if the SMMUv3 driver is changed to use ias != oas for stage-2.

This patch re-writes the code to use concatenation only if mandatory,
fixing the missing case for level-1 and granule 16K with PA = 40 bits.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/io-pgtable-arm.c | 45 +++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 6b9bb58a414f..0055876b3527 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -223,6 +223,33 @@ static inline int arm_lpae_max_entries(int i, struct arm_lpae_io_pgtable *data)
 	return ptes_per_table - (i & (ptes_per_table - 1));
 }
 
+/*
+ * Check if concatenated PGDs are mandatory according to Arm DDI0487 (K.a)
+ * 1) R_DXBSH: For 16KB, and 48-bit input size, use level 1 instead of 0.
+ * 2) R_SRKBC: After de-ciphering the table for PA size and valid initial lookup
+ *   a) 40 bits PA size with 4K: use level 1 instead of level 0 (2 tables for ias = oas)
+ *   b) 40 bits PA size with 16K: use level 2 instead of level 1 (16 tables for ias = oas)
+ *   c) 42 bits PA size with 4K: use level 1 instead of level 0 (8 tables for ias = oas)
+ *   d) 48 bits PA size with 16K: use level 1 instead of level 0 (2 tables for ias = oas)
+ */
+static inline bool arm_lpae_concat_mandatory(struct arm_lpae_io_pgtable *data)
+{
+	unsigned int ias = data->iop.cfg.ias;
+	unsigned int oas = data->iop.cfg.oas;
+
+	/* Covers 1  and 2.d */
+	if ((ARM_LPAE_GRANULE(data) == SZ_16K) && (data->start_level == 0))
+		return (oas == 48) || (ias = 48);
+
+	/* Covers 2.a and 2.c */
+	if ((ARM_LPAE_GRANULE(data) == SZ_4K) && (data->start_level == 0))
+		return (oas == 40) || (oas == 42);
+
+	/* Case 2.b */
+	return (ARM_LPAE_GRANULE(data) == SZ_16K) &&
+	       (data->start_level == 1) && (oas == 40);
+}
+
 static bool selftest_running = false;
 
 static dma_addr_t __arm_lpae_dma_addr(void *pages)
@@ -1006,18 +1033,12 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 	if (!data)
 		return NULL;
 
-	/*
-	 * Concatenate PGDs at level 1 if possible in order to reduce
-	 * the depth of the stage-2 walk.
-	 */
-	if (data->start_level == 0) {
-		unsigned long pgd_pages;
-
-		pgd_pages = ARM_LPAE_PGD_SIZE(data) / sizeof(arm_lpae_iopte);
-		if (pgd_pages <= ARM_LPAE_S2_MAX_CONCAT_PAGES) {
-			data->pgd_bits += data->bits_per_level;
-			data->start_level++;
-		}
+	if (arm_lpae_concat_mandatory(data))  {
+		if (WARN_ON((ARM_LPAE_PGD_SIZE(data) / sizeof(arm_lpae_iopte)) >
+			    ARM_LPAE_S2_MAX_CONCAT_PAGES))
+			return NULL;
+		data->pgd_bits += data->bits_per_level;
+		data->start_level++;
 	}
 
 	/* VTCR */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Mon Dec  2 06:06:02 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Mon,  2 Dec 2024 14:06:02 +0000
Subject: [PATCH v2 0/2] Fix missing case for concatenation
Message-ID: <20241202140604.422235-1-smostafa@google.com>

First patch fixes a missing case for 16K granule and 40 bits SMMUs
where concatenation is mandatory but ignored.

Second patch, imporves coverage of OAS in selftests to make it
possible to test all concatenation cases.

Cc: Daniel Mentz <danielmentz at google.com>

Mostafa Saleh (2):
  iommu/io-pgtable-arm: Fix stage-2 concatenation with 16K
  iommu/io-pgtable-arm: Add coverage for different OAS in selftest

 drivers/iommu/io-pgtable-arm.c | 72 ++++++++++++++++++++++------------
 1 file changed, 48 insertions(+), 24 deletions(-)

-- 
V2:
- Rely on OAS and don't assume OAS = IAS
- Re-write the comment and commit message to be more clear
- Improve selftests
V1: https://lore.kernel.org/linux-iommu/20241115172235.1493328-1-smostafa at google.com/

2.47.0.338.g60cca15819-goog



From smostafa at google.com  Mon Dec  2 06:06:04 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Mon,  2 Dec 2024 14:06:04 +0000
Subject: [PATCH v2 2/2] iommu/io-pgtable-arm: Add coverage for different OAS
 in selftest
In-Reply-To: <20241202140604.422235-1-smostafa@google.com>
References: <20241202140604.422235-1-smostafa@google.com>
Message-ID: <20241202140604.422235-3-smostafa@google.com>

Run selftests with different OAS values intead of hardcoding it to 48
bits.

We always keep OAS >= IAS to make the config valid for stage-2.

This can be further improved, if we split IAS/OAS configuration for
stage-1 and stage-2 (to use input sizes compatible with VA_BITS as
SMMUv3 does, or IAS > OAS which is valid for stage-1).

However, that adds more complexity, and the current change improves
coverage and makes it possible to test all concatenation cases.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/io-pgtable-arm.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 0055876b3527..62015fdd6c6a 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -1385,15 +1385,14 @@ static int __init arm_lpae_do_selftests(void)
 		SZ_64K | SZ_512M,
 	};
 
-	static const unsigned int ias[] __initconst = {
+	static const unsigned int address_size[] __initconst = {
 		32, 36, 40, 42, 44, 48,
 	};
 
-	int i, j, pass = 0, fail = 0;
+	int i, j, k, pass = 0, fail = 0;
 	struct device dev;
 	struct io_pgtable_cfg cfg = {
 		.tlb = &dummy_tlb_ops,
-		.oas = 48,
 		.coherent_walk = true,
 		.iommu_dev = &dev,
 	};
@@ -1402,15 +1401,19 @@ static int __init arm_lpae_do_selftests(void)
 	set_dev_node(&dev, NUMA_NO_NODE);
 
 	for (i = 0; i < ARRAY_SIZE(pgsize); ++i) {
-		for (j = 0; j < ARRAY_SIZE(ias); ++j) {
-			cfg.pgsize_bitmap = pgsize[i];
-			cfg.ias = ias[j];
-			pr_info("selftest: pgsize_bitmap 0x%08lx, IAS %u\n",
-				pgsize[i], ias[j]);
-			if (arm_lpae_run_tests(&cfg))
-				fail++;
-			else
-				pass++;
+		for (j = 0; j < ARRAY_SIZE(address_size); ++j) {
+			/* Don't use ias > oas as it is not valid for stage-2. */
+			for (k = 0; k <= j; ++k) {
+				cfg.pgsize_bitmap = pgsize[i];
+				cfg.ias = address_size[k];
+				cfg.oas = address_size[j];
+				pr_info("selftest: pgsize_bitmap 0x%08lx, IAS %u OAS %u\n",
+					pgsize[i], cfg.ias, cfg.oas);
+				if (arm_lpae_run_tests(&cfg))
+					fail++;
+				else
+					pass++;
+			}
 		}
 	}
 
-- 
2.47.0.338.g60cca15819-goog



From krzysztof.kozlowski at linaro.org  Mon Dec  2 06:15:11 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 02 Dec 2024 15:15:11 +0100
Subject: [PATCH 0/2] pinctrl: samsung: fix fwnode refcount cleanup in
 error path and update comment
In-Reply-To: <20241106-samsung-pinctrl-put-v1-0-de854e26dd03@gmail.com>
References: <20241106-samsung-pinctrl-put-v1-0-de854e26dd03@gmail.com>
Message-ID: <173314891106.48956.4220732642073324618.b4-ty@linaro.org>


On Wed, 06 Nov 2024 23:04:38 +0100, Javier Carrasco wrote:
> The first patch completes a previous fix where one error path stayed as
> a direct return after the child nodes were acquired, and the second,
> completely trivial, updates the function name used in the comment to
> indicate where the references are released.
> 
> 

Applied, thanks!

[1/2] pinctrl: samsung: fix fwnode refcount cleanup if platform_get_irq_optional() fails
      https://git.kernel.org/pinctrl/samsung/c/459915f55509f4bfd6076daa1428e28490ddee3b
[2/2] pinctrl: samsung: update child reference drop comment
      https://git.kernel.org/pinctrl/samsung/c/0ebb1e9e1b12ddcb86105a14b59ccbed76b6ce00

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



From krzk at kernel.org  Mon Dec  2 06:24:40 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 15:24:40 +0100
Subject: [PATCH v4 10/10] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S9 (SM-G960F)
In-Reply-To: <20241028-exynos9810-v4-10-6191f9d0c0f1@gmail.com>
References: <20241028-exynos9810-v4-0-6191f9d0c0f1@gmail.com>
 <20241028-exynos9810-v4-10-6191f9d0c0f1@gmail.com>
Message-ID: <682e8a50-8247-4f98-9ecd-03e1b3b3c359@kernel.org>

On 28/10/2024 10:22, Markuss Broks wrote:
> Samsung Galaxy S9 (SM-G960F), codenamed starlte, is a mobile phone
> released in 2017. It has 4GB of RAM, 64GB of UFS storage, Exynos9810
> SoC and 1440x2960 Super AMOLED display.
> 
> This initial device tree enables the framebuffer pre-initialised
> by bootloader and physical buttons of the device, with more support
> to come in the future.
> 
> Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
> Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
> Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
> ---
>  arch/arm64/boot/dts/exynos/Makefile               |   1 +
>  arch/arm64/boot/dts/exynos/exynos9810-starlte.dts | 119 ++++++++++++++++++++++
>  2 files changed, 120 insertions(+)

This does not apply. Please rebase and resend.

Best regards,
Krzysztof


From linux at fw-web.de  Mon Dec  2 06:29:36 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon, 02 Dec 2024 15:29:36 +0100
Subject: =?US-ASCII?Q?Re=3A_=5BPATCH_v2_11/18=5D_arm64=3A_dts=3A_media?=
 =?US-ASCII?Q?tek=3A_mt7988=3A_add_chosen_node_on_bpi-r4?=
In-Reply-To: <0fb58a4a-7bad-4623-99c8-67f5763558bb@kernel.org>
References: <20241202122602.30734-1-linux@fw-web.de> <20241202122602.30734-12-linux@fw-web.de> <0fb58a4a-7bad-4623-99c8-67f5763558bb@kernel.org>
Message-ID: <D92CAF3C-F6B7-46DC-BF83-A71907E2D7EA@fw-web.de>

Am 2. Dezember 2024 14:46:24 MEZ schrieb Krzysztof Kozlowski <krzk at kernel.org>:
>On 02/12/2024 13:25, Frank Wunderlich wrote:
>> From: Frank Wunderlich <frank-w at public-files.de>
>> 
>> Add chosen node on Bananapi R4 board with stdout and default bootargs.
>> 
>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>> ---
>>  arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 5 +++++
>>  1 file changed, 5 insertions(+)
>> 
>> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>> index 9037f35857a9..1c2a806f6f6c 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>> @@ -9,6 +9,11 @@ / {
>>  	model = "Banana Pi BPI-R4";
>>  	chassis-type = "embedded";
>>  
>> +	chosen {
>> +		stdout-path = &serial0;
>> +		bootargs = "console=ttyS0,115200n1";
>
>Drop or merge into stdout path.

Have you an example to pass speed setting to stdout-path? As it is only a phandle it is not clear to me how to merge these 2...

>Best regards,
>Krzysztof


regards Frank


From maz at kernel.org  Mon Dec  2 06:29:53 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Dec 2024 14:29:53 +0000
Subject: [PATCH v3 14/15] KVM: arm64: Convert the SVE guest vcpu flag to a vm flag
In-Reply-To: <CA+EHjTysFaaxGBo212e8kSHi_VkpXx6N6ddxwB0UGC6bSoK0gA@mail.gmail.com>
References: <20241128123515.1709777-1-tabba@google.com>
	<20241128123515.1709777-15-tabba@google.com>
	<864j3nv9tk.wl-maz@kernel.org>
	<CA+EHjTyXj6NhUcxTfER=zPz3VOtd+HgqpfmyfR88cVyiXoxqwA@mail.gmail.com>
	<CA+EHjTysFaaxGBo212e8kSHi_VkpXx6N6ddxwB0UGC6bSoK0gA@mail.gmail.com>
Message-ID: <86v7w2taxq.wl-maz@kernel.org>

On Mon, 02 Dec 2024 12:57:44 +0000,
Fuad Tabba <tabba at google.com> wrote:
> 
> Hi Marc,
> 
> On Sun, 1 Dec 2024 at 16:01, Fuad Tabba <tabba at google.com> wrote:
> >
> > Hi Marc,
> >
> >
> > On Sun, 1 Dec 2024 at 12:58, Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > On Thu, 28 Nov 2024 12:35:14 +0000,
> > > Fuad Tabba <tabba at google.com> wrote:
> > > >
> > > > The vcpu flag GUEST_HAS_SVE is per-vcpu, but it is based on what
> > > > is now a per-vm feature. Make the flag per-vm.
> > > >
> > > > Signed-off-by: Fuad Tabba <tabba at google.com>
> > > > ---
> > > >  arch/arm64/include/asm/kvm_emulate.h    |  6 +++---
> > > >  arch/arm64/include/asm/kvm_host.h       | 10 ++++++----
> > > >  arch/arm64/kvm/hyp/include/hyp/switch.h |  2 +-
> > > >  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  2 +-
> > > >  arch/arm64/kvm/hyp/nvhe/pkvm.c          | 11 +++++++----
> > > >  arch/arm64/kvm/hyp/nvhe/switch.c        |  8 ++++----
> > > >  arch/arm64/kvm/hyp/vhe/switch.c         |  2 +-
> > > >  arch/arm64/kvm/reset.c                  |  2 +-
> > > >  8 files changed, 24 insertions(+), 19 deletions(-)
> > > >
> > > > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > > > index 406e99a452bf..ae6d0dc0e4ff 100644
> > > > --- a/arch/arm64/include/asm/kvm_emulate.h
> > > > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > > > @@ -620,7 +620,7 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
> > > >  }
> > > >
> > > >  /* Resets the value of cptr_el2 when returning to the host. */
> > > > -static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> > > > +static __always_inline void kvm_reset_cptr_el2(struct kvm *kvm)
> > >
> > > I'd rather you avoid the resulting churn:
> > >
> > > static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> > > {
> > >         struct kvm *kvm = kern_hyp_va(vcpu->kvm);
> > >         [...]
> > >
> > > which does the trick at zero cost. It is also more logical to keep the
> > > vcpu as a parameter, as the per-VM-ness is only an implementation
> > > detail.
> >
> > The reason for the churn (here and below for vcpu_has_sve()), which in
> > hindsight I should have mentioned in the commit message or as a note,
> > is that this code is called by the host kernel (e.g., in reset.c), and
> > by the hypervisor). For nvhe, we need kern_hyp_va(), but not for the
> > host. Should I gate the va conversion with is_hyp_nvhe()?
> 
> I spoke too soon. Your suggestion results in less churn, and of
> course, solves the issue I had with kern_hyp_va.
> 
> I did have to convert kvm_reset_cptr_el2() into a macro, because it
> now needs kern_hyp_va(), defined in kvm_mmu.h, which in turn includes
> kvm_emulate.h. But since it's __always_inline, it shouldn't make any
> difference in practice.
> 
> If this conversion to a macro is alright by you, I'll respin this.

If you can convert it to something like:

static __always_inline void __kvm_reset_cptr_el2(struct kvm *kvm)
{
	[...]
}

#define kvm_reset_cptr_el2(v)	__kvm_reset_cptr_el2(kern_hyp_va((v)->kvm))

that'd be great, as it keeps the body of the function as C code, which
helps with debugging.

Thanks,

	M.

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


From konrad.dybcio at oss.qualcomm.com  Mon Dec  2 06:32:09 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Mon, 2 Dec 2024 15:32:09 +0100
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint reader
In-Reply-To: <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
Message-ID: <30985d44-a460-437d-8423-615c198e02a2@oss.qualcomm.com>

On 18.11.2024 11:34 AM, Stephan Gerhold wrote:
> The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
> multiport controller on eUSB6. All other ports (including USB super-speed
> pins) are unused.
> 
> Set it up in the device tree together with the NXP PTN3222 repeater.
> 
> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

Konrad


From dave.stevenson at raspberrypi.com  Mon Dec  2 06:31:54 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Mon, 02 Dec 2024 14:31:54 +0000
Subject: [PATCH 1/7] dtbindings: display: bcm2711-hdmi: Correct bindings
 for 2712
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
Message-ID: <20241202-dt-bcm2712-fixes-v1-1-fac67cc2f98a@raspberrypi.com>

The previous patch just adding the compatible missed out that the
number of interrupts changed

Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 44 +++++++++++++++-------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
index 6d11f5955b51..6af342c9b6b8 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
@@ -56,22 +56,38 @@ properties:
       - const: cec
 
   interrupts:
-    items:
-      - description: CEC TX interrupt
-      - description: CEC RX interrupt
-      - description: CEC stuck at low interrupt
-      - description: Wake-up interrupt
-      - description: Hotplug connected interrupt
-      - description: Hotplug removed interrupt
+    oneOf:
+      - items:
+        - description: CEC TX interrupt
+        - description: CEC RX interrupt
+        - description: CEC stuck at low interrupt
+        - description: Wake-up interrupt
+        - description: Hotplug connected interrupt
+        - description: Hotplug removed interrupt
+
+      - items:
+        - description: CEC TX interrupt
+        - description: CEC RX interrupt
+        - description: CEC stuck at low interrupt
+        - description: Hotplug connected interrupt
+        - description: Hotplug removed interrupt
 
   interrupt-names:
-    items:
-      - const: cec-tx
-      - const: cec-rx
-      - const: cec-low
-      - const: wakeup
-      - const: hpd-connected
-      - const: hpd-removed
+    oneOf:
+      - items:
+        - const: cec-tx
+        - const: cec-rx
+        - const: cec-low
+        - const: wakeup
+        - const: hpd-connected
+        - const: hpd-removed
+
+      - items:
+        - const: cec-tx
+        - const: cec-rx
+        - const: cec-low
+        - const: hpd-connected
+        - const: hpd-removed
 
   ddc:
     $ref: /schemas/types.yaml#/definitions/phandle

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Mon Dec  2 06:31:58 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Mon, 02 Dec 2024 14:31:58 +0000
Subject: [PATCH 5/7] arm64: dts: broadcom: Add interrupt-controller flag
 for intc on BCM2712
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
Message-ID: <20241202-dt-bcm2712-fixes-v1-5-fac67cc2f98a@raspberrypi.com>

BCM2712 DT was producing dtbinding validation errors of

interrupt-controller at 7cd00000: 'interrupt-controller' is a required
property
interrupt-controller at 7cd00000: '#interrupt-cells' is a required property

Fix them by adding the required flags.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
index f42fad2d8b37..0ba076ab9caf 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -224,6 +224,8 @@ mailbox: mailbox at 7c013880 {
 		local_intc: interrupt-controller at 7cd00000 {
 			compatible = "brcm,bcm2836-l1-intc";
 			reg = <0x7cd00000 0x100>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 		};
 
 		uart10: serial at 7d001000 {

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Mon Dec  2 06:31:53 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Mon, 02 Dec 2024 14:31:53 +0000
Subject: [PATCH 0/7] drm/vc4: Fixup DT and DT binding issues from recent
 patchset
Message-ID: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>

I missed the DT errors from the recent patchset[1] (DT patches
in linux-next via Florian, DRM bindings patches on dri-misc-next)
as Rob's bot report got spam filtered, so this is a fixup set.

Largely it was changes to number of interrupts or clocks in the
bindings, so those are now covered.

I've fixed up the missing "interrupt-controller" flags for 2711
and 2712 whilst here.

I can't get my head around what is meant to happen with ranges:
"soc at 107c000000: firmware: 'ranges' is a required property"
The meaning seems obvious.

However if I add it then I get:
"firmware: '#address-cells', '#size-cells', 'dma-ranges', 'ranges' do
not match any of the regexes: 'pinctrl-[0-9]+'
from schema $id: http://devicetree.org/schemas/arm/bcm/raspberrypi,bcm2835-firmware.yaml#

There's obviously some other flag I need to set in the bindings,
but I can't work it out. We have similar errors for all the Pi
platforms for one or more nodes.
Please advise and I'll happily fix them all.

Thanks
  Dave

[1] https://lore.kernel.org/linux-arm-kernel/20241025-drm-vc4-2712-support-v2-0-35efa83c8fc0 at raspberrypi.com/

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
Dave Stevenson (7):
      dtbindings: display: bcm2711-hdmi: Correct bindings for 2712
      dtbindings: display: Fix BCM2835 HVS bindings for BCM2712
      dt-bindings: gpio: brcmstb: add gpio-line-name
      arm64: dts: broadcom: Fix device tree warnings for BCM2712 display pipeline
      arm64: dts: broadcom: Add interrupt-controller flag for intc on BCM2712
      arm: dts: broadcom: Add interrupt-controller flag for intc on BCM2711
      arm64: dts: broadcom: Fix device tree errors on BCM2712.

 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 44 +++++++++----
 .../bindings/display/brcm,bcm2835-hvs.yaml         | 77 +++++++++++++++++-----
 .../bindings/gpio/brcm,brcmstb-gpio.yaml           |  2 +
 arch/arm/boot/dts/broadcom/bcm2711.dtsi            |  2 +
 arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts   |  9 +--
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi          | 10 +--
 6 files changed, 106 insertions(+), 38 deletions(-)
---
base-commit: 8c3f4a248f35817d2f604c0e3df1bccf27590228
change-id: 20241128-dt-bcm2712-fixes-afb0e8a0a476

Best regards,
-- 
Dave Stevenson <dave.stevenson at raspberrypi.com>



From dave.stevenson at raspberrypi.com  Mon Dec  2 06:31:56 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Mon, 02 Dec 2024 14:31:56 +0000
Subject: [PATCH 3/7] dt-bindings: gpio: brcmstb: add gpio-line-name
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
Message-ID: <20241202-dt-bcm2712-fixes-v1-3-fac67cc2f98a@raspberrypi.com>

Support comes from gpiolib, so permit it through the binding.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
index f096f286da19..086d016df6ef 100644
--- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
@@ -64,6 +64,8 @@ properties:
 
   gpio-ranges: true
 
+  gpio-line-names: true
+
   wakeup-source:
     type: boolean
     description: >

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Mon Dec  2 06:31:57 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Mon, 02 Dec 2024 14:31:57 +0000
Subject: [PATCH 4/7] arm64: dts: broadcom: Fix device tree warnings for
 BCM2712 display pipeline
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
Message-ID: <20241202-dt-bcm2712-fixes-v1-4-fac67cc2f98a@raspberrypi.com>

Fixes up errors on HDMI and interrupt controllers that weren't
noticed before merging.

Fixes: de9bc2dba3db ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
index 39305e0869ec..f42fad2d8b37 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -336,7 +336,7 @@ ddc1: i2c at 7d508280 {
 			#size-cells = <0>;
 		};
 
-		bsc_irq: intc at 7d508380 {
+		bsc_irq: interrupt-controller at 7d508380 {
 			compatible = "brcm,bcm7271-l2-intc";
 			reg = <0x7d508380 0x10>;
 			interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
@@ -344,7 +344,7 @@ bsc_irq: intc at 7d508380 {
 			#interrupt-cells = <1>;
 		};
 
-		main_irq: intc at 7d508400 {
+		main_irq: interrupt-controller at 7d508400 {
 			compatible = "brcm,bcm7271-l2-intc";
 			reg = <0x7d508400 0x10>;
 			interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
@@ -352,7 +352,7 @@ main_irq: intc at 7d508400 {
 			#interrupt-cells = <1>;
 		};
 
-		hdmi0: hdmi at 7ef00700 {
+		hdmi0: hdmi at 7c701400 {
 			compatible = "brcm,bcm2712-hdmi0";
 			reg = <0x7c701400 0x300>,
 			      <0x7c701000 0x200>,
@@ -381,7 +381,7 @@ hdmi0: hdmi at 7ef00700 {
 			ddc = <&ddc0>;
 		};
 
-		hdmi1: hdmi at 7ef05700 {
+		hdmi1: hdmi at 7c706400 {
 			compatible = "brcm,bcm2712-hdmi1";
 			reg = <0x7c706400 0x300>,
 			      <0x7c706000 0x200>,

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Mon Dec  2 06:31:55 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Mon, 02 Dec 2024 14:31:55 +0000
Subject: [PATCH 2/7] dtbindings: display: Fix BCM2835 HVS bindings for
 BCM2712
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
Message-ID: <20241202-dt-bcm2712-fixes-v1-2-fac67cc2f98a@raspberrypi.com>

The previous patch adding the compatible string missed out that
the number of interrupts and clocks changed with BCM2712 too.

Update to validate clock and interrupts for the variants.

Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2835-hvs.yaml         | 77 +++++++++++++++++-----
 1 file changed, 61 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
index f91c9dce2a44..ab59edbcf32c 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
@@ -19,12 +19,13 @@ properties:
   reg:
     maxItems: 1
 
-  interrupts:
-    maxItems: 1
+  interrupts: true
 
-  clocks:
-    maxItems: 1
-    description: Core Clock
+  interrupt-names: true
+
+  clocks: true
+
+  clock-names: true
 
 required:
   - compatible
@@ -33,17 +34,61 @@ required:
 
 additionalProperties: false
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - brcm,bcm2711-hvs
-          - brcm,bcm2712-hvs
-
-then:
-  required:
-    - clocks
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2711-hvs
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Core Clock
+
+      required:
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2712-hvs
+
+    then:
+      properties:
+        clocks:
+          maxItems: 2
+        clock-names:
+          items:
+            - const: core
+            - const: disp
+        interrupts:
+          items:
+            - description: Channel 0 End of frame
+            - description: Channel 1 End of frame
+            - description: Channel 2 End of frame
+        interrupt-names:
+          items:
+            - const: ch0-eof
+            - const: ch1-eof
+            - const: ch2-eof
+      required:
+        - clocks
+        - clock-names
+        - interrupt-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2835-hvs
+
+    then:
+      properties:
+        interrupts:
+          maxItems: 1
 
 examples:
   - |

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Mon Dec  2 06:31:59 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Mon, 02 Dec 2024 14:31:59 +0000
Subject: [PATCH 6/7] arm: dts: broadcom: Add interrupt-controller flag for
 intc on BCM2711
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
Message-ID: <20241202-dt-bcm2712-fixes-v1-6-fac67cc2f98a@raspberrypi.com>

BCM2711 DT was producing dtbinding validation errors of

interrupt-controller at 40000000: 'interrupt-controller' is a required
property
interrupt-controller at 40000000: '#interrupt-cells' is a required property

Fix them by adding the required flags.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm/boot/dts/broadcom/bcm2711.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/broadcom/bcm2711.dtsi b/arch/arm/boot/dts/broadcom/bcm2711.dtsi
index e4e42af21ef3..313b1046d74f 100644
--- a/arch/arm/boot/dts/broadcom/bcm2711.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm2711.dtsi
@@ -51,6 +51,8 @@ soc {
 		local_intc: interrupt-controller at 40000000 {
 			compatible = "brcm,bcm2836-l1-intc";
 			reg = <0x40000000 0x100>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 		};
 
 		gicv2: interrupt-controller at 40041000 {

-- 
2.34.1



From romain.naour at smile.fr  Mon Dec  2 06:33:30 2024
From: romain.naour at smile.fr (Romain Naour)
Date: Mon,  2 Dec 2024 15:33:30 +0100
Subject: [PATCHv3 1/2] dt-bindings: mfd: syscon: Add ti,j721e-acspcie-proxy-ctrl compatible
Message-ID: <20241202143331.126800-1-romain.naour@smile.fr>

From: Romain Naour <romain.naour at skf.com>

The ACSPCIE_PROXY_CTRL registers within the CTRL_MMR space of TI's J721e
SoC are used to drive the reference clock to the PCIe Endpoint device via
the PAD IO Buffers. Add the compatible for allowing the PCIe driver to
obtain the regmap for the ACSPCIE_CTRL register within the System
Controller device-tree node in order to enable the PAD IO Buffers.

The Technical Reference Manual for J721e SoC with details of the
ASCPCIE_CTRL registers is available at:
https://www.ti.com/lit/zip/spruil1

Signed-off-by: Romain Naour <romain.naour at skf.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 b414de4fa779..032cdd30d95f 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -115,6 +115,7 @@ select:
           - ti,am625-dss-oldi-io-ctrl
           - ti,am62p-cpsw-mac-efuse
           - ti,am654-dss-oldi-io-ctrl
+          - ti,j721e-acspcie-proxy-ctrl
           - ti,j784s4-acspcie-proxy-ctrl
           - ti,j784s4-pcie-ctrl
           - ti,keystone-pllctrl
-- 
2.45.0



From dave.stevenson at raspberrypi.com  Mon Dec  2 06:32:00 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Mon, 02 Dec 2024 14:32:00 +0000
Subject: [PATCH 7/7] arm64: dts: broadcom: Fix device tree errors on
 BCM2712.
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
Message-ID: <20241202-dt-bcm2712-fixes-v1-7-fac67cc2f98a@raspberrypi.com>

Resolves the issues on clocks and power nodes

Fixes: 4254a647b6c9 ("arm64: dts: broadcom: Add firmware clocks and power nodes to Pi5 DT")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
index fbc56309660f..26e05601416f 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
@@ -66,11 +66,7 @@ &sdio1 {
 &soc {
 	firmware: firmware {
 		compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
-		#address-cells = <1>;
-		#size-cells = <1>;
-
 		mboxes = <&mailbox>;
-		dma-ranges;
 
 		firmware_clocks: clocks {
 			compatible = "raspberrypi,firmware-clocks";
@@ -85,6 +81,11 @@ reset: reset {
 
 	power: power {
 		compatible = "raspberrypi,bcm2835-power";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		dma-ranges;
+
 		firmware = <&firmware>;
 		#power-domain-cells = <1>;
 	};

-- 
2.34.1



From romain.naour at smile.fr  Mon Dec  2 06:33:31 2024
From: romain.naour at smile.fr (Romain Naour)
Date: Mon,  2 Dec 2024 15:33:31 +0100
Subject: [PATCHv3 2/2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable ACSPCIE output for PCIe1
In-Reply-To: <20241202143331.126800-1-romain.naour@smile.fr>
References: <20241202143331.126800-1-romain.naour@smile.fr>
Message-ID: <20241202143331.126800-2-romain.naour@smile.fr>

From: Romain Naour <romain.naour at skf.com>

Unlike the SK-TDA4VM (k3-j721e-sk) board, there is no clock generator
(CDCI6214RGET) on the BeagleBone AI-64 (k3-j721e-beagleboneai64) to
provide PCIe refclk signal to PCIe Endponts. So the ACSPCIE module must
provide refclk through PCIe_REFCLK pins.

Use the new "ti,syscon-acspcie-proxy-ctrl" property to enable ACSPCIE
module's PAD IO Buffers.

Cc: Siddharth Vadapalli <s-vadapalli at ti.com>
Signed-off-by: Romain Naour <romain.naour at skf.com>
---
With this patch, we can remove "HACK: Sierra: Drive clock out" patch
applied on vendor kernel for BeagleBone AI-64:
https://openbeagle.org/beagleboard/linux/-/commit/ad65d7ef675966cdbc5d75f2bd545fad1914ba9b

v3:
 - update "acspcie0_proxy_ctrl" compatible to "ti,j721e-acspcie-proxy-ctrl"
   since this property is specific to j721e variant.

v2:
 - use generic style comments
 - use "syscon" as generic node name for "acspcie0_proxy_ctrl" node
 - Keep the compatible "ti,j784s4-acspcie-proxy-ctrl" since the
   ACSPCIE buffer and its functionality is the same across all K3 SoCs.
   (Siddharth Vadapalli)

   "The compatible "ti,j784s4-acspcie-pcie-ctrl" should be reused for
   J721E and all other K3 SoCs.
   For example, see:
   https://lore.kernel.org/r/20240402105708.4114146-1-s-vadapalli at ti.com/
   which introduced "ti,am62p-cpsw-mac-efuse" compatible.

   The same compatible is reused across all K3 SoCs:
   https://lore.kernel.org/r/20240628151518.40100-1-afd at ti.com/ "
---
 arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts |  5 +++++
 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi          | 10 ++++++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
index fb899c99753e..741ad2ba6fdb 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
@@ -859,6 +859,11 @@ &pcie1_rc {
 	num-lanes = <2>;
 	max-link-speed = <3>;
 	reset-gpios = <&main_gpio0 22 GPIO_ACTIVE_HIGH>;
+	/*
+	 * There is no on-board or external reference clock generators,
+	 * use refclk from the ACSPCIE module's PAD IO Buffers.
+	 */
+	ti,syscon-acspcie-proxy-ctrl = <&acspcie0_proxy_ctrl 0x3>;
 };
 
 &ufs_wrapper {
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index af3d730154ac..32a232a90100 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -5,6 +5,7 @@
  * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
  */
 #include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-cadence.h>
 #include <dt-bindings/phy/phy-ti.h>
 #include <dt-bindings/mux/mux.h>
 
@@ -82,6 +83,11 @@ ehrpwm_tbclk: clock-controller at 4140 {
 			reg = <0x4140 0x18>;
 			#clock-cells = <1>;
 		};
+
+		acspcie0_proxy_ctrl: syscon at 18090 {
+			compatible = "ti,j721e-acspcie-proxy-ctrl", "syscon";
+			reg = <0x18090 0x4>;
+		};
 	};
 
 	main_ehrpwm0: pwm at 3000000 {
@@ -979,8 +985,8 @@ pcie1_rc: pcie at 2910000 {
 		max-link-speed = <3>;
 		num-lanes = <2>;
 		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 240 1>;
-		clock-names = "fck";
+		clocks = <&k3_clks 240 1>, <&serdes1 CDNS_SIERRA_DERIVED_REFCLK>;
+		clock-names = "fck", "pcie_refclk";
 		#address-cells = <3>;
 		#size-cells = <2>;
 		bus-range = <0x0 0xff>;
-- 
2.45.0



From t.antoine at uclouvain.be  Mon Dec  2 06:42:00 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Mon, 2 Dec 2024 15:42:00 +0100
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <ec4bd953-1cd7-46bc-9415-0983bb9cbe89@kernel.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
 <ec4bd953-1cd7-46bc-9415-0983bb9cbe89@kernel.org>
Message-ID: <86209e69-6eab-4a93-bbb5-6ee98d6bc83f@uclouvain.be>

On 12/2/24 14:39, Krzysztof Kozlowski wrote:
> On 02/12/2024 14:07, Thomas Antoine via B4 Relay wrote:
>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>
>> As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
> 
> 
> s/max77759/MAX77759/
> 
> Please explain the device in general, e.g. fuel gauge is only one part
> of the PMIC chip. Otherwise 'fg' compatible suffix would not be justified.

The max77759 is an IC used to manage the power supply of the battery and
the USB-C. Based on drivers from google, it contains at least a PMIC, a
fuel gauge, a TPCI and a charger.

Given I saw that the linked proposed patch, which adds a driver for the
TCPCI, used the "maxim,max77759" compatible, I didn't want to create a
possible eventual conflict.

Link: https://lore.kernel.org/linux-devicetree/20241127-gs101-phy-lanes-orientation-dts-v1-0-5222d8508b71 at linaro.org/

Will add this information to the commit description for v2.

>> @@ -16,6 +16,7 @@ properties:
>>    compatible:
>>      oneOf:
>>        - const: maxim,max17201
>> +      - const: maxim,max77759-fg
>>        - items:
>>            - enum:
>>                - maxim,max17205
>> @@ -25,11 +26,13 @@ properties:
>>      items:
>>        - description: ModelGauge m5 registers
>>        - description: Nonvolatile registers
>> +    minItems: 1
>>
>>    reg-names:
>>      items:
>>        - const: m5
>>        - const: nvmem
>> +    minItems: 1
> 
> You need allOf:if:then section narrowing it per each variant.
Will do in v2.

>>    interrupts:
>>      maxItems: 1
>> @@ -56,3 +59,14 @@ examples:
>>          interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
>>        };
>>      };
>> +  - |
>> +    i2c {
>> +      #address-cells = <1>;
>> +      #size-cells = <0>;
>> +
>> +      fuel-gauge at 36 {
>> +        compatible = "maxim,max77759-fg";
> 
> 
> No need for new example if it differs with one property.

Will remove in v2.


From sebastian.reichel at collabora.com  Mon Dec  2 06:41:47 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Mon, 2 Dec 2024 15:41:47 +0100
Subject: [PATCH v1 04/10] phy: phy-rockchip-samsung-hdptx: Add support
 for eDP mode
In-Reply-To: <2342f342-672c-447e-90d8-674b748af6a4@rock-chips.com>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <2131853.KlZ2vcFHjT@diego>
 <6e1f35c0-5ea8-414f-b3ea-4e7222c605ef@rock-chips.com>
 <2886747.Y6S9NjorxK@diego>
 <h4giob7bcrh7qmtepti6huym2llw4ujfmeff76vrgpahb5zy6x@dz6zghsifww5>
 <2342f342-672c-447e-90d8-674b748af6a4@rock-chips.com>
Message-ID: <abzu2chif2g3urxoqbm3gbe6cciexbmqvn44qezrx4hgllfkkn@7bzi5jl3stqe>

Hi,

On Mon, Dec 02, 2024 at 11:28:13AM +0800, Damon Ding wrote:
> Hi,
> 
> On 2024/12/2 6:59, Sebastian Reichel wrote:
> > Hi,
> > 
> > On Sat, Nov 30, 2024 at 09:25:12PM +0100, Heiko St?bner wrote:
> > > Am Freitag, 29. November 2024, 03:43:57 CET schrieb Damon Ding:
> > > > On 2024/11/27 19:04, Heiko St?bner wrote:
> > > > > Am Mittwoch, 27. November 2024, 12:00:10 CET schrieb Damon Ding:
> > > > > > On 2024/11/27 17:29, Heiko St?bner wrote:
> > > > > > > Am Mittwoch, 27. November 2024, 08:51:51 CET schrieb Damon Ding:
> > > > > > > > +static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode,
> > > > > > > > +				 int submode)
> > > > > > > > +{
> > > > > > > > +	return 0;
> > > > > > > > +}
> > > > > > > analogix_dp_phy_power_on
> > > > > > > I think it might make sense to go the same way as the DCPHY and also
> > > > > > > naneng combophy, to use #phy-cells = 1 to select the phy-mode via DT .
> > > > > > > 
> > > > > > > See [0] for Sebastians initial suggestion regarding the DC-PHY.
> > > > > > > The naneng combophy already uses that scheme of mode-selection too.
> > > > > > > 
> > > > > > > There is of course the issue of backwards-compatibility, but that can be
> > > > > > > worked around in the binding with something like:
> > > > > > > 
> > > > > > >     '#phy-cells':
> > > > > > >        enum: [0, 1]
> > > > > > >        description: |
> > > > > > >          If #phy-cells is 0, PHY mode is set to PHY_TYPE_HDMI
> > > > > > >          If #phy-cells is 1 mode is set in the PHY cells. Supported modes are:
> > > > > > >            - PHY_TYPE_HDMI
> > > > > > >            - PHY_TYPE_DP
> > > > > > >          See include/dt-bindings/phy/phy.h for constants.
> > > > > > > 
> > > > > > > PHY_TYPE_HDMI needs to be added to include/dt-bindings/phy/phy.h
> > > > > > > but PHY_TYPE_DP is already there.
> > > > > > > 
> > > > > > > That way we would standardize on one form of accessing phy-types
> > > > > > > on rk3588 :-) .
> > > > > > > 
> > > > > > > Also see the Mediatek CSI rx phy doing this too already [1]
> > > > > > > 
> > > > > > > 
> > > > > > > Heiko
> > > > > > > 
> > > > > > > [0] https://lore.kernel.org/linux-rockchip/udad4qf3o7kt45nuz6gxsvsmprh4rnyfxfogopmih6ucznizih at 7oj2jrnlfonz/
> > > > > > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/phy/mediatek,mt8365-csi-rx.yaml
> > > > > > > 
> > > > > > 
> > > > > > It is really a nice way to separate HDMI and DP modes.
> > > > 
> > > > I apologize for reopening the discussion about the phy-types setting.
> > > 
> > > there is definitly no need to apologize. We're trying to find the best
> > > solution afterall :-) .
> > > 
> > > > With the .set_mode() of struct phy_ops, the HDMI and eDP dynamic
> > > > switching can be achieved, which just depends on the right setting of
> > > > enum phy_mode in include/linux/phy/phy.h. So the previous way of
> > > > configuring phy mode may be also good.
> > > 
> > > I think the deciding factor is, is there a use-case for needing to switch
> > > modes at runtime.
> > > 
> > > I do think the mode for the dc-phy and also the hdptx-phy is pretty much
> > > decided by the board design.
> > > 
> > > I.e. when you end up in a DP-connector (or eDP-panel) on your board you
> > > need DP mode, and when you end up in a hdmi-connector you need the
> > > HDMI phy mode.
> > > 
> > > So I think the phy-mode for the hdptx-phy is largely dictated by the static
> > > board definition (like devicetree), hence going with the dt-argument for
> > > the mode.
> > > 
> > > Like similar to the Naneng combophy, selecting its mode via argument
> > > because deciding if it ends up in a sata port is a board-design thing.
> > > 
> > > Is there a use-case where you need to switch at runtime between
> > > HDMI and eDP? Like starting the phy in eDP mode but then needing
> > > to switch to HDMI mode, while the device is running?
> 
> Indeed, we have the board as you described, on which the DP-connector and
> HDMI-connector both have been configured.
> 
> And the dynamic switching is more useful for RK3576, which has the same
> eDP/HDMI design as RK3588 but only one eDP controller/HDMI controller/HDPTX
> phy. We can only enable both of eDP/HDMI by this way.
> 
> > 
> > I believe the eDP controller can only use the PHY in eDP mode and
> > the HDMI controller can only use it in HDMI mode. So in order to
> > support runtime switching, the following options are possible:
> > 
> > 1. Enable both controllers, the PHY decides which one is really
> >     used, the other one is basically a non-functional dummy device
> >     until the PHY is reconfigured. This requires the set_mode()
> >     callback, since the HDMI and eDP drivers both expect their
> >     PHY to be enabled.
> > 
> > 2. Properly enable / disable the used controller, so that only one
> >     controller is active at the same time. In this case the switching
> >     is handled one layer above and the PHY has nothing to do with it.
> >     The phy_enable call from each controller would just set it up in
> >     the right mode.
> > 
> > I guess option 1 is the hacked solution, which is easier to
> > implement as DRM's hotplug abilities are quite limited at the moment
> > as far as I know. I think the second solution looks much cleaner and
> > should be prefered for upstream. That solution does not require
> > calling set_mode() for runtime switching making this whole argument
> > void :)
> > 
> 
> Your friendly and detailed analysis has brought me some valuable insights.
> :)
> 
> The option 2 is really a better way to support the dynamic switching, and we
> still need the .set_mode() to select the configurations for either eDP or
> HDMI in HDPTX phy at the controller level. Would you mind
> elaborating on the useful way to choose the phy mode for the second
> solution?

The xlate function to handle the arguments is called when the PHY
device is looked up. So the devm_phy_get(dp->dev, "dp") call in
analogix_dp_probe() would setup the PHY in DP mode.

Similarily the call to devm_of_phy_get_by_index() in
dw_hdmi_qp_rockchip_bind() would set the PHY in HDMI mode.

So the PHY mode is correct as long as only one controller driver
is bound at the same time.

Greetings,

-- Sebastian

> > FWIW I think the DT argument based mode setting and the runtime set_mode
> > are not necessarily mutual exclusive. In theory one could support both
> > and adding set_mode support later does not change any ABI as far as
> > I can see. Basically handle it like pin mux/configuration settings,
> > which are usually automatically handled by the device core based on
> > DT information, except for some drivers which have special needs.
> > 
> 
> > > > And other phys may want to support dynamic switching too, like the
> > > > Rockchip USBDP combo phy.
> > > 
> > > I guess USBDP is special in that in also does both modes dynamical
> > > depending on its use (like type-c with option DP altmode)
> > 
> > The USBDP PHY is indeed quite different from the PHYs in your list
> > above, but for a different reason: All the combined PHYs you listed
> > above only support one mode at the same time. E.g. you need to
> > decide between PCIe, SATA and USB3 mode for the Naneng combophy.
> > 
> > For the USBDP PHY the modes are not mutually exclusive. The USB
> > controller can request the USBDP PHY in USB mode at the same time
> > as the DP controller requests it in DP mode. Some additional
> > registers configure how the lanes are being muxed. A typcial setup
> > would be 2 lanes for USB3 and 2 lanes for DP.
> > 
> > Greetings,
> > 
> > -- Sebastian
> 
> Best regards,
> Damon
> 
-------------- 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/20241202/f1f2c824/attachment.sig>

From dsimic at manjaro.org  Mon Dec  2 06:44:06 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon,  2 Dec 2024 15:44:06 +0100
Subject: [PATCH] arm64: dts: rockchip: Describe why is HWRNG disabled in RK356x base dtsi
Message-ID: <6b272e2f8f916c04b05db50df621659a5a7f29ab.1733149874.git.dsimic@manjaro.org>

Despite the presence of the hardware random number generator (HWRNG) in the
different Rockchip RK356x SoC variants, it remains disabled for the RK3566
SoC because testing showed [1] that it produces unacceptably low quality of
random data, for some yet unknown reason.  The HWRNG is enabled for the RK3568
SoC, on which the testing showed good quality of the generated random data.

To avoid possible confusion in the future, [2] let's have this described
briefly in the RK356x base SoC dtsi.

[1] https://lore.kernel.org/linux-rockchip/cover.1720969799.git.daniel at makrotopia.org/T/#u
[2] https://lore.kernel.org/linux-rockchip/20241201234613.52322-1-pbrobinson at gmail.com/T/#u

Signed-off-by: Dragan Simic <dsimic at manjaro.org>
---
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
index 62be06f3b863..ab8f42c0a843 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -1032,6 +1032,11 @@ sdhci: mmc at fe310000 {
 		status = "disabled";
 	};
 
+	/*
+	 * Testing showed that the HWRNG found in RK3566 produces unacceptably
+	 * low quality of random data, so the HWRNG isn't enabled for all RK356x
+	 * SoC variants despite its presence.
+	 */
 	rng: rng at fe388000 {
 		compatible = "rockchip,rk3568-rng";
 		reg = <0x0 0xfe388000 0x0 0x4000>;


From tabba at google.com  Mon Dec  2 06:47:59 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Dec 2024 14:47:59 +0000
Subject: [PATCH v3 14/15] KVM: arm64: Convert the SVE guest vcpu flag to a
 vm flag
In-Reply-To: <86v7w2taxq.wl-maz@kernel.org>
References: <20241128123515.1709777-1-tabba@google.com> <20241128123515.1709777-15-tabba@google.com>
 <864j3nv9tk.wl-maz@kernel.org> <CA+EHjTyXj6NhUcxTfER=zPz3VOtd+HgqpfmyfR88cVyiXoxqwA@mail.gmail.com>
 <CA+EHjTysFaaxGBo212e8kSHi_VkpXx6N6ddxwB0UGC6bSoK0gA@mail.gmail.com> <86v7w2taxq.wl-maz@kernel.org>
Message-ID: <CA+EHjTyzAcMPspvO8cAp=0_-i6hJHw2y--eieNkjZk2AuzG5FQ@mail.gmail.com>

On Mon, 2 Dec 2024 at 14:29, Marc Zyngier <maz at kernel.org> wrote:
>
> On Mon, 02 Dec 2024 12:57:44 +0000,
> Fuad Tabba <tabba at google.com> wrote:
> >
> > Hi Marc,
> >
> > On Sun, 1 Dec 2024 at 16:01, Fuad Tabba <tabba at google.com> wrote:
> > >
> > > Hi Marc,
> > >
> > >
> > > On Sun, 1 Dec 2024 at 12:58, Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > On Thu, 28 Nov 2024 12:35:14 +0000,
> > > > Fuad Tabba <tabba at google.com> wrote:
> > > > >
> > > > > The vcpu flag GUEST_HAS_SVE is per-vcpu, but it is based on what
> > > > > is now a per-vm feature. Make the flag per-vm.
> > > > >
> > > > > Signed-off-by: Fuad Tabba <tabba at google.com>
> > > > > ---
> > > > >  arch/arm64/include/asm/kvm_emulate.h    |  6 +++---
> > > > >  arch/arm64/include/asm/kvm_host.h       | 10 ++++++----
> > > > >  arch/arm64/kvm/hyp/include/hyp/switch.h |  2 +-
> > > > >  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  2 +-
> > > > >  arch/arm64/kvm/hyp/nvhe/pkvm.c          | 11 +++++++----
> > > > >  arch/arm64/kvm/hyp/nvhe/switch.c        |  8 ++++----
> > > > >  arch/arm64/kvm/hyp/vhe/switch.c         |  2 +-
> > > > >  arch/arm64/kvm/reset.c                  |  2 +-
> > > > >  8 files changed, 24 insertions(+), 19 deletions(-)
> > > > >
> > > > > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > > > > index 406e99a452bf..ae6d0dc0e4ff 100644
> > > > > --- a/arch/arm64/include/asm/kvm_emulate.h
> > > > > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > > > > @@ -620,7 +620,7 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
> > > > >  }
> > > > >
> > > > >  /* Resets the value of cptr_el2 when returning to the host. */
> > > > > -static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> > > > > +static __always_inline void kvm_reset_cptr_el2(struct kvm *kvm)
> > > >
> > > > I'd rather you avoid the resulting churn:
> > > >
> > > > static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
> > > > {
> > > >         struct kvm *kvm = kern_hyp_va(vcpu->kvm);
> > > >         [...]
> > > >
> > > > which does the trick at zero cost. It is also more logical to keep the
> > > > vcpu as a parameter, as the per-VM-ness is only an implementation
> > > > detail.
> > >
> > > The reason for the churn (here and below for vcpu_has_sve()), which in
> > > hindsight I should have mentioned in the commit message or as a note,
> > > is that this code is called by the host kernel (e.g., in reset.c), and
> > > by the hypervisor). For nvhe, we need kern_hyp_va(), but not for the
> > > host. Should I gate the va conversion with is_hyp_nvhe()?
> >
> > I spoke too soon. Your suggestion results in less churn, and of
> > course, solves the issue I had with kern_hyp_va.
> >
> > I did have to convert kvm_reset_cptr_el2() into a macro, because it
> > now needs kern_hyp_va(), defined in kvm_mmu.h, which in turn includes
> > kvm_emulate.h. But since it's __always_inline, it shouldn't make any
> > difference in practice.
> >
> > If this conversion to a macro is alright by you, I'll respin this.
>
> If you can convert it to something like:
>
> static __always_inline void __kvm_reset_cptr_el2(struct kvm *kvm)
> {
>         [...]
> }
>
> #define kvm_reset_cptr_el2(v)   __kvm_reset_cptr_el2(kern_hyp_va((v)->kvm))
>
> that'd be great, as it keeps the body of the function as C code, which
> helps with debugging.

Will do, thanks again!
/fuad

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


From dsimic at manjaro.org  Mon Dec  2 06:50:07 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 02 Dec 2024 15:50:07 +0100
Subject: [PATCH] arm64: dts: rockchip: enable rng on all rk356x
In-Reply-To: <D6175VTSP13T.200HWIIHOIDQQ@cknow.org>
References: <20241201234613.52322-1-pbrobinson@gmail.com>
 <302bdae2f4defeefe88ea4018a0be11f@manjaro.org>
 <b50376c7-c5d5-41ae-95ea-e2d68c1cc809@linaro.org>
 <D6175VTSP13T.200HWIIHOIDQQ@cknow.org>
Message-ID: <c50f603a9e1a819f17f72e97e92aeebd@manjaro.org>

Hello Diederik and Marcin,

On 2024-12-02 13:01, Diederik de Haas wrote:
> On Mon Dec 2, 2024 at 11:40 AM CET, Marcin Juszkiewicz wrote:
>> W dniu 2.12.2024 o 04:55, Dragan Simic pisze:
>>  > On 2024-12-02 00:46, Peter Robinson wrote:
>>  >> The rk356x rng is available on both the rk3566 and rk3568
>>  >> parts, the IP is all self contained within the SoCs so
>>  >> it's enabled already by default on rk3568 so let's enable
>>  >> it in the base rk356x.dtsi so it's enabled consistently
>>  >> everywhere.
>>  >
>>  > Please, go through the mailing list threads [1][2] that have led us
>>  > to the current state.  To sum it up, it isn't about what's 
>> supported
>>  > in the two RK356x SoC variants, but about the RK3566's HWRNG being
>>  > disabled because the testing showed that it produces unacceptably
>>  > low quality of random data, for some yet unknown reason.
>> 
>> So maybe there should be a comment in rockchip/rk3568.dtsi so we would
>> not get back to it again.
> 
> I suggested to put that in the (original) commit message:
> https://lore.kernel.org/linux-rockchip/6690040.iosknibmi9 at bagend/
> precisely because this was quite predictable to happen.
> 
> So a +1 on a comment in the dtsi with a link to the discussion in the
> commit message.

Totally agreed on adding a brief summary to the RK356x base SoC dtsi,
so I went ahead and sent a patch that adds it. [1]  I also expected
that to be described in the base dtsi back when the HWRNG support was
added, but it somehow went in without the description.

[1] 
https://lore.kernel.org/linux-rockchip/6b272e2f8f916c04b05db50df621659a5a7f29ab.1733149874.git.dsimic at manjaro.org/


From s-vadapalli at ti.com  Mon Dec  2 06:53:22 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Mon, 2 Dec 2024 20:23:22 +0530
Subject: [PATCHv2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable
 ACSPCIE output for PCIe1
In-Reply-To: <abeb632b-9efc-48e5-a28a-a9d7c02e0a6e@kernel.org>
References: <20241202101140.48778-1-romain.naour@smile.fr>
 <dabbad2b-f8a6-4ed7-86da-ec696cf67461@kernel.org>
 <k7udgqugqseweckb7hjniz3aops4kn35ttju2ju7f2pcbmndrg@dau5nr4leish>
 <abeb632b-9efc-48e5-a28a-a9d7c02e0a6e@kernel.org>
Message-ID: <cndc3fopwhwkotfikul2jtzfczpdpwlrs5uhuqq76ck36ndtfs@gvxavxt5tgd5>

On Mon, Dec 02, 2024 at 12:07:17PM +0100, Krzysztof Kozlowski wrote:

Hello Krzysztof,

> On 02/12/2024 11:58, Siddharth Vadapalli wrote:
> > On Mon, Dec 02, 2024 at 11:14:46AM +0100, Krzysztof Kozlowski wrote:
> > 
> > Hello Krzysztof,
> > 
> >> On 02/12/2024 11:11, Romain Naour wrote:
> >>> From: Romain Naour <romain.naour at skf.com>
> >>>
> >>> Unlike the SK-TDA4VM (k3-j721e-sk) board, there is no clock generator
> >>> (CDCI6214RGET) on the BeagleBone AI-64 (k3-j721e-beagleboneai64) to
> >>> provide PCIe refclk signal to PCIe Endponts. So the ACSPCIE module must
> >>> provide refclk through PCIe_REFCLK pins.
> >>>
> >>> Use the new "ti,syscon-acspcie-proxy-ctrl" property to enable ACSPCIE
> >>> module's PAD IO Buffers.
> >>>
> >>> Reuse the compatible "ti,j784s4-acspcie-proxy-ctrl" since the ACSPCIE
> >>> buffer and its functionality is the same across all K3 SoCs.
> >>>
> >>> Cc: Siddharth Vadapalli <s-vadapalli at ti.com>
> >>> Signed-off-by: Romain Naour <romain.naour at skf.com>
> >>> ---
> >>> With this patch, we can remove "HACK: Sierra: Drive clock out" patch
> >>> applied on vendor kernel for BeagleBone AI-64:
> >>> https://openbeagle.org/beagleboard/linux/-/commit/ad65d7ef675966cdbc5d75f2bd545fad1914ba9b
> >>>
> >>> v2:
> >>>  - use generic style comments
> >>>  - use "syscon" as generic node name for "acspcie0_proxy_ctrl" node
> >>>  - Keep the compatible "ti,j784s4-acspcie-proxy-ctrl" since the
> >>>    ACSPCIE buffer and its functionality is the same across all K3 SoCs.
> >>>    (Siddharth Vadapalli)
> >>>
> >>>    "The compatible "ti,j784s4-acspcie-pcie-ctrl" should be reused for
> >>>    J721E and all other K3 SoCs.
> >>
> >> No, it shouldn't and you got comment on this. You always need specific
> >> compatible, see writing bindings doc.
> > 
> > Could you please clarify in which cases reusing the compatible is
> > permissible? The list of compatibles at:
> 
> Never? You always need specific compatible. Did you read the writing
> bindings document?

I went through the bindings document again at:
https://www.kernel.org/doc/Documentation/devicetree/bindings/writing-bindings.rst
It mentions:
- DON'T use 'syscon' alone without a specific compatible string. A 'syscon'
  hardware block should have a compatible string unique enough to infer the
  register layout of the entire block (at a minimum).

The ACSCPCIE Block as well as its integration across all of TI's K3 SoCs
is the same i.e. same Hardware/IP. The register bits corresponding to
the feature to be enabled/disabled via the ACSPCIE block are the same as
well i.e. "register layout can be inferred". The same goes for the
compatibles listed below in my previous reply i.e. they aren't bugs.
Same IP and integration across SoCs and hence reused in the sense of
Hardware and not Software. I hope this clarifies the rationale for the
"reuse".

> 
> > https://github.com/torvalds/linux/blob/v6.12/Documentation/devicetree/bindings/mfd/syscon.yaml#L112
> > namely,
> >           - ti,am62-opp-efuse-table
> >           - ti,am62-usb-phy-ctrl
> >           - ti,am625-dss-oldi-io-ctrl
> >           - ti,am62p-cpsw-mac-efuse
> >           - ti,am654-dss-oldi-io-ctrl
> >           - ti,j784s4-pcie-ctrl
> > have all been reused for different TI SoCs since they all correspond to the
> > device functionality enabled via the CTRL_MMR System Controller registers.
> 
> If you find a bug, does it mean you can send new patch introducing the
> same bug?

[...]

Regards,
Siddharth.


From t.antoine at uclouvain.be  Mon Dec  2 06:54:10 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Mon, 2 Dec 2024 15:54:10 +0100
Subject: [PATCH 3/4] arm64: defconfig: enable Maxim max1720x driver
In-Reply-To: <a917cb0b-68de-4916-9a4d-021a8da37289@kernel.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-3-98d2fa7bfe30@uclouvain.be>
 <a917cb0b-68de-4916-9a4d-021a8da37289@kernel.org>
Message-ID: <08558b39-bf69-43a7-8f55-064995221099@uclouvain.be>

On 12/2/24 14:40, Krzysztof Kozlowski wrote:
> On 02/12/2024 14:07, Thomas Antoine via B4 Relay wrote:
>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>  CONFIG_BATTERY_QCOM_BATTMGR=m
>>  CONFIG_BATTERY_SBS=m
>>  CONFIG_BATTERY_BQ27XXX=y
>> +CONFIG_BATTERY_MAX1720X=m
>>  CONFIG_BATTERY_MAX17042=m
> 
> Are you sure this is placed according to savedefconfig order?

I ran menuconfig and it put CONFIG_BATTERY_MAX1720X below
CONFIG_BATTERY_MAX17042 so I think it is an error on my part.
Will fix in v2.

Best regards,
Thomas Antoine


From dsimic at manjaro.org  Mon Dec  2 06:55:44 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 02 Dec 2024 15:55:44 +0100
Subject: [PATCH] arm64: dts: rockchip: Describe why is HWRNG disabled in
 RK356x base dtsi
In-Reply-To: <6b272e2f8f916c04b05db50df621659a5a7f29ab.1733149874.git.dsimic@manjaro.org>
References: <6b272e2f8f916c04b05db50df621659a5a7f29ab.1733149874.git.dsimic@manjaro.org>
Message-ID: <2415bfe796ae9190a23d05d4c0d23d4d@manjaro.org>

On 2024-12-02 15:44, Dragan Simic wrote:
> Despite the presence of the hardware random number generator (HWRNG) in 
> the
> different Rockchip RK356x SoC variants, it remains disabled for the 
> RK3566
> SoC because testing showed [1] that it produces unacceptably low 
> quality of
> random data, for some yet unknown reason.  The HWRNG is enabled for the 
> RK3568
> SoC, on which the testing showed good quality of the generated random 
> data.
> 
> To avoid possible confusion in the future, [2] let's have this 
> described
> briefly in the RK356x base SoC dtsi.
> 
> [1] 
> https://lore.kernel.org/linux-rockchip/cover.1720969799.git.daniel at makrotopia.org/T/#u
> [2] 
> https://lore.kernel.org/linux-rockchip/20241201234613.52322-1-pbrobinson at gmail.com/T/#u
> 
> Signed-off-by: Dragan Simic <dsimic at manjaro.org>

Oh, I forgot to Cc Peter as well while sending this patch, so I did
that now.  Sorry for the noise.

> ---
>  arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> index 62be06f3b863..ab8f42c0a843 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> @@ -1032,6 +1032,11 @@ sdhci: mmc at fe310000 {
>  		status = "disabled";
>  	};
> 
> +	/*
> +	 * Testing showed that the HWRNG found in RK3566 produces 
> unacceptably
> +	 * low quality of random data, so the HWRNG isn't enabled for all 
> RK356x
> +	 * SoC variants despite its presence.
> +	 */
>  	rng: rng at fe388000 {
>  		compatible = "rockchip,rk3568-rng";
>  		reg = <0x0 0xfe388000 0x0 0x4000>;


From will at kernel.org  Mon Dec  2 06:57:29 2024
From: will at kernel.org (Will Deacon)
Date: Mon,  2 Dec 2024 14:57:29 +0000
Subject: [PATCH 1/2] drivers/virt: pkvm: Don't fail ioremap() call if MMIO_GUARD fails
In-Reply-To: <20241202145731.6422-1-will@kernel.org>
References: <20241202145731.6422-1-will@kernel.org>
Message-ID: <20241202145731.6422-2-will@kernel.org>

Calling the MMIO_GUARD hypercall from guests which have not been
enrolled (e.g. because they are running without pvmfw) results in
-EINVAL being returned. In this case, MMIO_GUARD is not active
and so we can simply proceed with the normal ioremap() routine.

Don't fail ioremap() if MMIO_GUARD fails; instead WARN_ON_ONCE()
to highlight that the pvm environment is slightly wonky.

Fixes: 0f1269495800 ("drivers/virt: pkvm: Intercept ioremap using pKVM MMIO_GUARD hypercal")
Signed-off-by: Will Deacon <will at kernel.org>
---
 drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
index 56a3859dda8a..4230b817a80b 100644
--- a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
+++ b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
@@ -87,12 +87,8 @@ static int mmio_guard_ioremap_hook(phys_addr_t phys, size_t size,
 
 	while (phys < end) {
 		const int func_id = ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID;
-		int err;
-
-		err = arm_smccc_do_one_page(func_id, phys);
-		if (err)
-			return err;
 
+		WARN_ON_ONCE(arm_smccc_do_one_page(func_id, phys));
 		phys += PAGE_SIZE;
 	}
 
-- 
2.47.0.338.g60cca15819-goog



From will at kernel.org  Mon Dec  2 06:57:30 2024
From: will at kernel.org (Will Deacon)
Date: Mon,  2 Dec 2024 14:57:30 +0000
Subject: [PATCH 2/2] MAINTAINERS: Add CCA and pKVM CoCO guest support to the ARM64 entry
In-Reply-To: <20241202145731.6422-1-will@kernel.org>
References: <20241202145731.6422-1-will@kernel.org>
Message-ID: <20241202145731.6422-3-will@kernel.org>

Commits 7999edc484ca ("virt: arm-cca-guest: TSM_REPORT support for
realm") and a06c3fad49a5 ("drivers/virt: pkvm: Add initial support for
running as a protected guest") added arm64 guest-side support for
running in CCA and pKVM confidential computing environments
respectively.

Unfortunately, these changes were not accompanied by a MAINTAINERS
entry and so aren't automatically picked up by the get_maintainer.pl
script. Since the initial support was merged via the arm64 tree, extend
the ARM64 entry to cover the two new directories.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Will Deacon <will at kernel.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..9378c0c4bbc9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3376,6 +3376,8 @@ S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
 F:	Documentation/arch/arm64/
 F:	arch/arm64/
+F:	drivers/virt/coco/arm-cca-guest/
+F:	drivers/virt/coco/pkvm-guest/
 F:	tools/testing/selftests/arm64/
 X:	arch/arm64/boot/dts/
 
-- 
2.47.0.338.g60cca15819-goog



From will at kernel.org  Mon Dec  2 06:57:28 2024
From: will at kernel.org (Will Deacon)
Date: Mon,  2 Dec 2024 14:57:28 +0000
Subject: [PATCH 0/2] Minor tweaks to arm64 CoCO guest support
Message-ID: <20241202145731.6422-1-will@kernel.org>

Hi folks,

Here are a couple of minor tweaks to the CoCO guest support on arm64.

The first enables protected guests under pKVM when pvmfw is not being
used (and therefore MMIO guard is not enabled). This is useful for pvmfw
development and for testing a VMM outside of the Android Virtualisation
Framework APIs.

The second extends the ARM64 MAINTAINERS entry to cover the CCA and pKVM
guest support, as neither of them are currently caught by an existing
rule.

Patches against v6.13-rc1.

Cheers,

Will

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Keir Fraser <keirf at google.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
Cc: Steven Price <steven.price at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Quentin Perret <qperret at google.com>

---->8

Will Deacon (2):
  drivers/virt: pkvm: Don't fail ioremap() call if MMIO_GUARD fails
  MAINTAINERS: Add CCA and pKVM CoCO guest support to the ARM64 entry

 MAINTAINERS                                   | 2 ++
 drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 6 +-----
 2 files changed, 3 insertions(+), 5 deletions(-)

-- 
2.47.0.338.g60cca15819-goog



From dmitry.baryshkov at linaro.org  Mon Dec  2 06:59:06 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 2 Dec 2024 16:59:06 +0200
Subject: [PATCH v5 2/9] ASoC: hdmi-codec: move no_capture_mute to struct
 hdmi_codec_pdata
In-Reply-To: <20241202-bald-just-guan-c5d41b@houat>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-2-b5316e82f61a@linaro.org>
 <20241202-bald-just-guan-c5d41b@houat>
Message-ID: <onq2djvtvxvr3a52s6sin3dstwdctyyz2lxpx47lk7ndxtza33@odldgvhryw4d>

On Mon, Dec 02, 2024 at 01:06:09PM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Sun, Dec 01, 2024 at 02:44:06AM +0200, Dmitry Baryshkov wrote:
> > The no_capture_mute flag might differ from platform to platform,
> > especially in the case of the wrapping implementations, like the
> > upcoming DRM HDMI Codec framework. Move the flag next to all other flags
> > in struct hdmi_codec_pdata.
> > 
> > Acked-by: Mark Brown <broonie at kernel.org>
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> 
> I appreciate it might be a dumb question, but I never really understood
> what no_capture_mute was all about. And in that context, why some
> drivers would need / use it, and some won't.

Some platforms can not mute the HDMI capture (ARC?) path. See the
following patches:
- https://lore.kernel.org/all/1606372608-2329-1-git-send-email-shengjiu.wang at nxp.com/
- https://lore.kernel.org/all/1606372608-2329-1-git-send-email-shengjiu.wang at nxp.com/

Russell added a way to disable capture / playback support, but only TDA
driver uses those. I think generally we should change those flags to be
opt-in for capture, but that requires carefully reviewing all the
platforms (and is a separate topic anyway).

-- 
With best wishes
Dmitry


From rgallaispou at gmail.com  Mon Dec  2 07:03:42 2024
From: rgallaispou at gmail.com (=?UTF-8?Q?Rapha=C3=ABl_Gallais-Pou?=)
Date: Mon, 2 Dec 2024 16:03:42 +0100
Subject: [PATCH 09/10] drm/sti: hdmi: use eld_mutex to protect access to
 connector->eld
In-Reply-To: <20241201-drm-connector-eld-mutex-v1-9-ba56a6545c03@linaro.org>
References: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
 <20241201-drm-connector-eld-mutex-v1-9-ba56a6545c03@linaro.org>
Message-ID: <0eb908f2-2304-4a91-9c91-e7f291da9dcd@gmail.com>



Le 01/12/2024 ? 00:55, Dmitry Baryshkov a ?crit?:
> Reading access to connector->eld can happen at the same time the
> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
> order to protect connector->eld from concurrent access.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Hi Dmitry,

Acked-by: Raphael Gallais-Pou <rgallaispou at gmail.com>

Thanks,
Rapha?l
> ---
>   drivers/gpu/drm/sti/sti_hdmi.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
> index 847470f747c0efad61c2ebdc3fb3746a7a13a863..3c8f3532c79723e7b1a720c855c90e40584cc6ca 100644
> --- a/drivers/gpu/drm/sti/sti_hdmi.c
> +++ b/drivers/gpu/drm/sti/sti_hdmi.c
> @@ -1225,7 +1225,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size
>   	struct drm_connector *connector = hdmi->drm_connector;
>   
>   	DRM_DEBUG_DRIVER("\n");
> +	mutex_lock(&connector->eld_mutex);
>   	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
> +	mutex_unlock(&connector->eld_mutex);
>   
>   	return 0;
>   }
> 



From t.antoine at uclouvain.be  Mon Dec  2 07:03:49 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Mon, 2 Dec 2024 16:03:49 +0100
Subject: [PATCH 4/4] arm64: dts: exynos: gs101-oriole: enable Maxim
 max77759 fuel gauge
In-Reply-To: <68b897f0-5583-4d09-87d5-4ff4d3080ef7@kernel.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-4-98d2fa7bfe30@uclouvain.be>
 <68b897f0-5583-4d09-87d5-4ff4d3080ef7@kernel.org>
Message-ID: <b8b72bde-31f3-4148-bd01-49826f9f9bd7@uclouvain.be>

On 12/2/24 14:41, Krzysztof Kozlowski wrote:
> On 02/12/2024 14:07, Thomas Antoine via B4 Relay wrote:
>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>  &hsi2c_12 {
>>       status = "okay";
>>       /* TODO: add the devices once drivers exist */
> 
> 
> Is this still applicable?

Yes, there are other devices on the bus (the Maxim max77759 pmic, charger
and TPCI, the Maxim max20339 OVP and the NXP PCA9468).

>> +
>> +     fuel-gauge at 36 {
>> +             compatible = "maxim,max77759-fg";
>> +             reg = <0x36>;
>> +             reg-names = "m5";
> 
> 
> No interrupts?

There are interrupts in the stock devicetree but they didn't compile out
of the box when adding them to the node without any other modification and
I didn't try further given the device worked without them. I can try to
get them to work for v2.

>> +     };
>> +
> 
> 
> Do not add stray blank lines.

Will remove in v2.

Best regards,
Thomas Antoine


From krzk at kernel.org  Mon Dec  2 07:09:51 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 16:09:51 +0100
Subject: [PATCHv2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable ACSPCIE
 output for PCIe1
In-Reply-To: <cndc3fopwhwkotfikul2jtzfczpdpwlrs5uhuqq76ck36ndtfs@gvxavxt5tgd5>
References: <20241202101140.48778-1-romain.naour@smile.fr>
 <dabbad2b-f8a6-4ed7-86da-ec696cf67461@kernel.org>
 <k7udgqugqseweckb7hjniz3aops4kn35ttju2ju7f2pcbmndrg@dau5nr4leish>
 <abeb632b-9efc-48e5-a28a-a9d7c02e0a6e@kernel.org>
 <cndc3fopwhwkotfikul2jtzfczpdpwlrs5uhuqq76ck36ndtfs@gvxavxt5tgd5>
Message-ID: <f332947a-d7b5-4f68-84d8-3ecce118c24c@kernel.org>

On 02/12/2024 15:53, Siddharth Vadapalli wrote:
> On Mon, Dec 02, 2024 at 12:07:17PM +0100, Krzysztof Kozlowski wrote:
> 
> Hello Krzysztof,
> 
>> On 02/12/2024 11:58, Siddharth Vadapalli wrote:
>>> On Mon, Dec 02, 2024 at 11:14:46AM +0100, Krzysztof Kozlowski wrote:
>>>
>>> Hello Krzysztof,
>>>
>>>> On 02/12/2024 11:11, Romain Naour wrote:
>>>>> From: Romain Naour <romain.naour at skf.com>
>>>>>
>>>>> Unlike the SK-TDA4VM (k3-j721e-sk) board, there is no clock generator
>>>>> (CDCI6214RGET) on the BeagleBone AI-64 (k3-j721e-beagleboneai64) to
>>>>> provide PCIe refclk signal to PCIe Endponts. So the ACSPCIE module must
>>>>> provide refclk through PCIe_REFCLK pins.
>>>>>
>>>>> Use the new "ti,syscon-acspcie-proxy-ctrl" property to enable ACSPCIE
>>>>> module's PAD IO Buffers.
>>>>>
>>>>> Reuse the compatible "ti,j784s4-acspcie-proxy-ctrl" since the ACSPCIE
>>>>> buffer and its functionality is the same across all K3 SoCs.
>>>>>
>>>>> Cc: Siddharth Vadapalli <s-vadapalli at ti.com>
>>>>> Signed-off-by: Romain Naour <romain.naour at skf.com>
>>>>> ---
>>>>> With this patch, we can remove "HACK: Sierra: Drive clock out" patch
>>>>> applied on vendor kernel for BeagleBone AI-64:
>>>>> https://openbeagle.org/beagleboard/linux/-/commit/ad65d7ef675966cdbc5d75f2bd545fad1914ba9b
>>>>>
>>>>> v2:
>>>>>  - use generic style comments
>>>>>  - use "syscon" as generic node name for "acspcie0_proxy_ctrl" node
>>>>>  - Keep the compatible "ti,j784s4-acspcie-proxy-ctrl" since the
>>>>>    ACSPCIE buffer and its functionality is the same across all K3 SoCs.
>>>>>    (Siddharth Vadapalli)
>>>>>
>>>>>    "The compatible "ti,j784s4-acspcie-pcie-ctrl" should be reused for
>>>>>    J721E and all other K3 SoCs.
>>>>
>>>> No, it shouldn't and you got comment on this. You always need specific
>>>> compatible, see writing bindings doc.
>>>
>>> Could you please clarify in which cases reusing the compatible is
>>> permissible? The list of compatibles at:
>>
>> Never? You always need specific compatible. Did you read the writing
>> bindings document?
> 
> I went through the bindings document again at:
> https://www.kernel.org/doc/Documentation/devicetree/bindings/writing-bindings.rst
> It mentions:
> - DON'T use 'syscon' alone without a specific compatible string. A 'syscon'
>   hardware block should have a compatible string unique enough to infer the
>   register layout of the entire block (at a minimum).
> 
> The ACSCPCIE Block as well as its integration across all of TI's K3 SoCs
> is the same i.e. same Hardware/IP. The register bits corresponding to


And first rule for compatible property? DT bindings maintainers keep
repeating it over and over - specific means soc as front compatible.

> the feature to be enabled/disabled via the ACSPCIE block are the same as
> well i.e. "register layout can be inferred". The same goes for the
> compatibles listed below in my previous reply i.e. they aren't bugs.
> Same IP and integration across SoCs and hence reused in the sense of
> Hardware and not Software. I hope this clarifies the rationale for the
> "reuse".


You mix re-use with fallback. These are almost never the same blocks,
which you imply here.

Best regards,
Krzysztof


From linux.amoon at gmail.com  Mon Dec  2 07:11:43 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  2 Dec 2024 20:41:43 +0530
Subject: [PATCH v11 2/3] PCI: rockchip: Simplify reset control handling by using reset_control_bulk*() function
In-Reply-To: <20241202151150.7393-1-linux.amoon@gmail.com>
References: <20241202151150.7393-1-linux.amoon@gmail.com>
Message-ID: <20241202151150.7393-3-linux.amoon@gmail.com>

Currently, the driver acquires and asserts/deasserts the resets
individually thereby making the driver complex to read. But this
can be simplified by using the reset_control_bulk APIs.
Use devm_reset_control_bulk_get_exclusive() API to acquire all
the resets and use reset_control_bulk_{assert/deassert}() APIs to
assert/deassert them in bulk.

Following the recommendations in 'Rockchip RK3399 TRM v1.3 Part2':

1. Split the reset controls into two groups as per section '17.5.8.1.1 PCIe
as Root Complex'.

2. Deassert the 'Pipe, MGMT Sticky, MGMT, Core' resets in groups as per
section '17.5.8.1.1 PCIe as Root Complex'. This is accomplished using the
reset_control_bulk APIs.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
V11: added R-B Manivannan, Fix small typo.
v10: Fix some typo
v9: Improved the commit message and try to fix few review comments.
v8: I tried to address reviews and comments from Mani.
    Follow the sequence of De-assert as per the driver code.
    Drop the comment in the driver.
    Improve the commit message with the description of the TMP section.
    Improve the reason for the core functional changes in the commit
    description.
    Improve the error handling messages of the code.
v7: replace devm_reset_control_bulk_get_optional_exclusive()
        with devm_reset_control_bulk_get_exclusive()
    update the functional changes.
V6: Add reason for the split of the RESET pins.
v5: Fix the De-assert reset core as per the TRM
    De-assert the PIPE_RESET_N/MGMT_STICKY_RESET_N/MGMT_RESET_N/RESET_N
    simultaneously.
v4: use dev_err_probe in error path.
v3: Fix typo in commit message, dropped reported by.
v2: Fix compilation error reported by Intel test robot
    fixed checkpatch warning.
---
 drivers/pci/controller/pcie-rockchip.c | 154 +++++--------------------
 drivers/pci/controller/pcie-rockchip.h |  26 +++--
 2 files changed, 48 insertions(+), 132 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
index 53aaba03aca6..693aadc99d6c 100644
--- a/drivers/pci/controller/pcie-rockchip.c
+++ b/drivers/pci/controller/pcie-rockchip.c
@@ -30,7 +30,7 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *node = dev->of_node;
 	struct resource *regs;
-	int err;
+	int err, i;
 
 	if (rockchip->is_rc) {
 		regs = platform_get_resource_byname(pdev,
@@ -69,55 +69,23 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
 		rockchip->link_gen = 2;
 
-	rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
-	if (IS_ERR(rockchip->core_rst)) {
-		if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing core reset property in node\n");
-		return PTR_ERR(rockchip->core_rst);
-	}
-
-	rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
-	if (IS_ERR(rockchip->mgmt_rst)) {
-		if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing mgmt reset property in node\n");
-		return PTR_ERR(rockchip->mgmt_rst);
-	}
-
-	rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
-								"mgmt-sticky");
-	if (IS_ERR(rockchip->mgmt_sticky_rst)) {
-		if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing mgmt-sticky reset property in node\n");
-		return PTR_ERR(rockchip->mgmt_sticky_rst);
-	}
-
-	rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
-	if (IS_ERR(rockchip->pipe_rst)) {
-		if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing pipe reset property in node\n");
-		return PTR_ERR(rockchip->pipe_rst);
-	}
+	for (i = 0; i < ROCKCHIP_NUM_PM_RSTS; i++)
+		rockchip->pm_rsts[i].id = rockchip_pci_pm_rsts[i];
 
-	rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
-	if (IS_ERR(rockchip->pm_rst)) {
-		if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing pm reset property in node\n");
-		return PTR_ERR(rockchip->pm_rst);
-	}
+	err = devm_reset_control_bulk_get_exclusive(dev,
+						    ROCKCHIP_NUM_PM_RSTS,
+						    rockchip->pm_rsts);
+	if (err)
+		return dev_err_probe(dev, err, "Cannot get the PM reset\n");
 
-	rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
-	if (IS_ERR(rockchip->pclk_rst)) {
-		if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing pclk reset property in node\n");
-		return PTR_ERR(rockchip->pclk_rst);
-	}
+	for (i = 0; i < ROCKCHIP_NUM_CORE_RSTS; i++)
+		rockchip->core_rsts[i].id = rockchip_pci_core_rsts[i];
 
-	rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
-	if (IS_ERR(rockchip->aclk_rst)) {
-		if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing aclk reset property in node\n");
-		return PTR_ERR(rockchip->aclk_rst);
-	}
+	err = devm_reset_control_bulk_get_exclusive(dev,
+						    ROCKCHIP_NUM_CORE_RSTS,
+						    rockchip->core_rsts);
+	if (err)
+		return dev_err_probe(dev, err, "Cannot get the Core resets\n");
 
 	if (rockchip->is_rc)
 		rockchip->perst_gpio = devm_gpiod_get_optional(dev, "ep",
@@ -149,23 +117,10 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
 	int err, i;
 	u32 regs;
 
-	err = reset_control_assert(rockchip->aclk_rst);
-	if (err) {
-		dev_err(dev, "assert aclk_rst err %d\n", err);
-		return err;
-	}
-
-	err = reset_control_assert(rockchip->pclk_rst);
-	if (err) {
-		dev_err(dev, "assert pclk_rst err %d\n", err);
-		return err;
-	}
-
-	err = reset_control_assert(rockchip->pm_rst);
-	if (err) {
-		dev_err(dev, "assert pm_rst err %d\n", err);
-		return err;
-	}
+	err = reset_control_bulk_assert(ROCKCHIP_NUM_PM_RSTS,
+					rockchip->pm_rsts);
+	if (err)
+		return dev_err_probe(dev, err, "Couldn't assert PM resets\n");
 
 	for (i = 0; i < MAX_LANE_NUM; i++) {
 		err = phy_init(rockchip->phys[i]);
@@ -175,47 +130,17 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
 		}
 	}
 
-	err = reset_control_assert(rockchip->core_rst);
-	if (err) {
-		dev_err(dev, "assert core_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_assert(rockchip->mgmt_rst);
-	if (err) {
-		dev_err(dev, "assert mgmt_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_assert(rockchip->mgmt_sticky_rst);
-	if (err) {
-		dev_err(dev, "assert mgmt_sticky_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_assert(rockchip->pipe_rst);
-	if (err) {
-		dev_err(dev, "assert pipe_rst err %d\n", err);
-		goto err_exit_phy;
-	}
+	err = reset_control_bulk_assert(ROCKCHIP_NUM_CORE_RSTS,
+					rockchip->core_rsts);
+	if (err)
+		return dev_err_probe(dev, err, "Couldn't assert Core resets\n");
 
 	udelay(10);
 
-	err = reset_control_deassert(rockchip->pm_rst);
-	if (err) {
-		dev_err(dev, "deassert pm_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_deassert(rockchip->aclk_rst);
+	err = reset_control_bulk_deassert(ROCKCHIP_NUM_PM_RSTS,
+					  rockchip->pm_rsts);
 	if (err) {
-		dev_err(dev, "deassert aclk_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_deassert(rockchip->pclk_rst);
-	if (err) {
-		dev_err(dev, "deassert pclk_rst err %d\n", err);
+		dev_err(dev, "Couldn't deassert PM resets %d\n", err);
 		goto err_exit_phy;
 	}
 
@@ -255,31 +180,10 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
 		goto err_power_off_phy;
 	}
 
-	/*
-	 * Please don't reorder the deassert sequence of the following
-	 * four reset pins.
-	 */
-	err = reset_control_deassert(rockchip->mgmt_sticky_rst);
-	if (err) {
-		dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
-
-	err = reset_control_deassert(rockchip->core_rst);
-	if (err) {
-		dev_err(dev, "deassert core_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
-
-	err = reset_control_deassert(rockchip->mgmt_rst);
-	if (err) {
-		dev_err(dev, "deassert mgmt_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
-
-	err = reset_control_deassert(rockchip->pipe_rst);
+	err = reset_control_bulk_deassert(ROCKCHIP_NUM_CORE_RSTS,
+					  rockchip->core_rsts);
 	if (err) {
-		dev_err(dev, "deassert pipe_rst err %d\n", err);
+		dev_err(dev, "Couldn't deassert Core reset %d\n", err);
 		goto err_power_off_phy;
 	}
 
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index f79c0a1cbbd0..87041ed88b38 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/pci-ecam.h>
+#include <linux/reset.h>
 
 /*
  * The upper 16 bits of PCIE_CLIENT_CONFIG are a write mask for the lower 16
@@ -310,18 +311,29 @@
 		(((c) << ((b) * 8 + 5)) & \
 		 ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b))
 
+#define ROCKCHIP_NUM_PM_RSTS   ARRAY_SIZE(rockchip_pci_pm_rsts)
+#define ROCKCHIP_NUM_CORE_RSTS ARRAY_SIZE(rockchip_pci_core_rsts)
+
+static const char * const rockchip_pci_pm_rsts[] = {
+	"pm",
+	"pclk",
+	"aclk",
+};
+
+static const char * const rockchip_pci_core_rsts[] = {
+	"mgmt-sticky",
+	"core",
+	"mgmt",
+	"pipe",
+};
+
 struct rockchip_pcie {
 	void	__iomem *reg_base;		/* DT axi-base */
 	void	__iomem *apb_base;		/* DT apb-base */
 	bool    legacy_phy;
 	struct  phy *phys[MAX_LANE_NUM];
-	struct	reset_control *core_rst;
-	struct	reset_control *mgmt_rst;
-	struct	reset_control *mgmt_sticky_rst;
-	struct	reset_control *pipe_rst;
-	struct	reset_control *pm_rst;
-	struct	reset_control *aclk_rst;
-	struct	reset_control *pclk_rst;
+	struct  reset_control_bulk_data pm_rsts[ROCKCHIP_NUM_PM_RSTS];
+	struct  reset_control_bulk_data core_rsts[ROCKCHIP_NUM_CORE_RSTS];
 	struct  clk_bulk_data *clks;
 	int	num_clks;
 	struct	regulator *vpcie12v; /* 12V power supply */
-- 
2.47.0



From linux.amoon at gmail.com  Mon Dec  2 07:11:42 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  2 Dec 2024 20:41:42 +0530
Subject: [PATCH v11 1/3] PCI: rockchip: Simplify clock handling by using clk_bulk*() function
In-Reply-To: <20241202151150.7393-1-linux.amoon@gmail.com>
References: <20241202151150.7393-1-linux.amoon@gmail.com>
Message-ID: <20241202151150.7393-2-linux.amoon@gmail.com>

Currently, the driver acquires clks and prepare enable/disable unprepare
the clks individually thereby making the driver complex to read.
But this can be simplified by using the clk_bulk*() APIs.
Use devm_clk_bulk_get_all() API to acquire all the clks and use
clk_bulk_prepare_enable() to prepare enable clks
and clk_bulk_disable_unprepare() APIs disable unprepare them in bulk.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
V11: None
V10: None
v9: Re write the commmit message.
v8: Improve the description of the code changes in commit messagee.
    Add Rb: Manivannan
v7: Update the functional change in commmit message.
v6: None.
v5: switch to use use devm_clk_bulk_get_all()? gets rid of hardcoding the
       clock names in driver.
v4: use dev_err_probe for error patch.
v3: Fix typo in commit message, dropped reported by.
v2: Fix compilation error reported by Intel test robot.
---
 drivers/pci/controller/pcie-rockchip.c | 65 +++-----------------------
 drivers/pci/controller/pcie-rockchip.h |  7 ++-
 2 files changed, 10 insertions(+), 62 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
index b9ade7632e11..53aaba03aca6 100644
--- a/drivers/pci/controller/pcie-rockchip.c
+++ b/drivers/pci/controller/pcie-rockchip.c
@@ -129,29 +129,9 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 		return dev_err_probe(dev, PTR_ERR(rockchip->perst_gpio),
 				     "failed to get PERST# GPIO\n");
 
-	rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
-	if (IS_ERR(rockchip->aclk_pcie)) {
-		dev_err(dev, "aclk clock not found\n");
-		return PTR_ERR(rockchip->aclk_pcie);
-	}
-
-	rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
-	if (IS_ERR(rockchip->aclk_perf_pcie)) {
-		dev_err(dev, "aclk_perf clock not found\n");
-		return PTR_ERR(rockchip->aclk_perf_pcie);
-	}
-
-	rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
-	if (IS_ERR(rockchip->hclk_pcie)) {
-		dev_err(dev, "hclk clock not found\n");
-		return PTR_ERR(rockchip->hclk_pcie);
-	}
-
-	rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
-	if (IS_ERR(rockchip->clk_pcie_pm)) {
-		dev_err(dev, "pm clock not found\n");
-		return PTR_ERR(rockchip->clk_pcie_pm);
-	}
+	rockchip->num_clks = devm_clk_bulk_get_all(dev, &rockchip->clks);
+	if (rockchip->num_clks < 0)
+		return dev_err_probe(dev, err, "failed to get clocks\n");
 
 	return 0;
 }
@@ -375,39 +355,11 @@ int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip)
 	struct device *dev = rockchip->dev;
 	int err;
 
-	err = clk_prepare_enable(rockchip->aclk_pcie);
-	if (err) {
-		dev_err(dev, "unable to enable aclk_pcie clock\n");
-		return err;
-	}
-
-	err = clk_prepare_enable(rockchip->aclk_perf_pcie);
-	if (err) {
-		dev_err(dev, "unable to enable aclk_perf_pcie clock\n");
-		goto err_aclk_perf_pcie;
-	}
-
-	err = clk_prepare_enable(rockchip->hclk_pcie);
-	if (err) {
-		dev_err(dev, "unable to enable hclk_pcie clock\n");
-		goto err_hclk_pcie;
-	}
-
-	err = clk_prepare_enable(rockchip->clk_pcie_pm);
-	if (err) {
-		dev_err(dev, "unable to enable clk_pcie_pm clock\n");
-		goto err_clk_pcie_pm;
-	}
+	err = clk_bulk_prepare_enable(rockchip->num_clks, rockchip->clks);
+	if (err)
+		return dev_err_probe(dev, err, "failed to enable clocks\n");
 
 	return 0;
-
-err_clk_pcie_pm:
-	clk_disable_unprepare(rockchip->hclk_pcie);
-err_hclk_pcie:
-	clk_disable_unprepare(rockchip->aclk_perf_pcie);
-err_aclk_perf_pcie:
-	clk_disable_unprepare(rockchip->aclk_pcie);
-	return err;
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_enable_clocks);
 
@@ -415,10 +367,7 @@ void rockchip_pcie_disable_clocks(void *data)
 {
 	struct rockchip_pcie *rockchip = data;
 
-	clk_disable_unprepare(rockchip->clk_pcie_pm);
-	clk_disable_unprepare(rockchip->hclk_pcie);
-	clk_disable_unprepare(rockchip->aclk_perf_pcie);
-	clk_disable_unprepare(rockchip->aclk_pcie);
+	clk_bulk_disable_unprepare(rockchip->num_clks, rockchip->clks);
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_disable_clocks);
 
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index a51b087ce878..f79c0a1cbbd0 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -11,6 +11,7 @@
 #ifndef _PCIE_ROCKCHIP_H
 #define _PCIE_ROCKCHIP_H
 
+#include <linux/clk.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/pci-ecam.h>
@@ -321,10 +322,8 @@ struct rockchip_pcie {
 	struct	reset_control *pm_rst;
 	struct	reset_control *aclk_rst;
 	struct	reset_control *pclk_rst;
-	struct	clk *aclk_pcie;
-	struct	clk *aclk_perf_pcie;
-	struct	clk *hclk_pcie;
-	struct	clk *clk_pcie_pm;
+	struct  clk_bulk_data *clks;
+	int	num_clks;
 	struct	regulator *vpcie12v; /* 12V power supply */
 	struct	regulator *vpcie3v3; /* 3.3V power supply */
 	struct	regulator *vpcie1v8; /* 1.8V power supply */
-- 
2.47.0



From linux.amoon at gmail.com  Mon Dec  2 07:11:44 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  2 Dec 2024 20:41:44 +0530
Subject: [PATCH v11 3/3] PCI: rockchip: Refactor rockchip_pcie_disable_clocks() function signature
In-Reply-To: <20241202151150.7393-1-linux.amoon@gmail.com>
References: <20241202151150.7393-1-linux.amoon@gmail.com>
Message-ID: <20241202151150.7393-4-linux.amoon@gmail.com>

Refactor the rockchip_pcie_disable_clocks() function to accept a
struct rockchip_pcie pointer instead of a void pointer. This change
improves type safety and code readability by explicitly specifying
the expected data type.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
v11: None
v10: None
v9: None
v8: add add the missing () in the function name.
v7: None
v6: Fix the subject, add the missing () in the function name.
v5: Fix the commit message and add r-b Manivannan.
v4: None
v3: None
v2: No
---
---
 drivers/pci/controller/pcie-rockchip.c | 3 +--
 drivers/pci/controller/pcie-rockchip.h | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
index 693aadc99d6c..fea867c24f75 100644
--- a/drivers/pci/controller/pcie-rockchip.c
+++ b/drivers/pci/controller/pcie-rockchip.c
@@ -267,9 +267,8 @@ int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip)
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_enable_clocks);
 
-void rockchip_pcie_disable_clocks(void *data)
+void rockchip_pcie_disable_clocks(struct rockchip_pcie *rockchip)
 {
-	struct rockchip_pcie *rockchip = data;
 
 	clk_bulk_disable_unprepare(rockchip->num_clks, rockchip->clks);
 }
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index 87041ed88b38..11def598534b 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -369,7 +369,7 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip);
 int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip);
 void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip);
 int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip);
-void rockchip_pcie_disable_clocks(void *data);
+void rockchip_pcie_disable_clocks(struct rockchip_pcie *rockchip);
 void rockchip_pcie_cfg_configuration_accesses(
 		struct rockchip_pcie *rockchip, u32 type);
 
-- 
2.47.0



From krzk at kernel.org  Mon Dec  2 07:16:58 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 16:16:58 +0100
Subject: [PATCH 1/7] dtbindings: display: bcm2711-hdmi: Correct bindings
 for 2712
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-1-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-1-fac67cc2f98a@raspberrypi.com>
Message-ID: <0167e83b-7b73-4784-b022-903272866fe1@kernel.org>

On 02/12/2024 15:31, Dave Stevenson wrote:
> The previous patch just adding the compatible missed out that the


"The previous" is meaningless in this context. There is nothing
previous. Refer to commit (see submitting patches).

> number of interrupts changed
> 
> Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")

There is no such commit in linux-next. Fix patches while they are on the
mailing list. If you refer here to broken DRM process, then basically
you are on your own because we won't able to see it.

> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>

Typo in subject prefix. It's dt-bindings.

> ---
>  .../bindings/display/brcm,bcm2711-hdmi.yaml        | 44 +++++++++++++++-------
>  1 file changed, 30 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> index 6d11f5955b51..6af342c9b6b8 100644
> --- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> @@ -56,22 +56,38 @@ properties:
>        - const: cec
>  
>    interrupts:
> -    items:
> -      - description: CEC TX interrupt
> -      - description: CEC RX interrupt
> -      - description: CEC stuck at low interrupt
> -      - description: Wake-up interrupt
> -      - description: Hotplug connected interrupt
> -      - description: Hotplug removed interrupt
> +    oneOf:
> +      - items:
> +        - description: CEC TX interrupt
> +        - description: CEC RX interrupt
> +        - description: CEC stuck at low interrupt
> +        - description: Wake-up interrupt
> +        - description: Hotplug connected interrupt
> +        - description: Hotplug removed interrupt

You need to narrow these per variant in allOf:if:then.
Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec  2 07:18:19 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 16:18:19 +0100
Subject: [PATCH 2/7] dtbindings: display: Fix BCM2835 HVS bindings for
 BCM2712
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-2-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-2-fac67cc2f98a@raspberrypi.com>
Message-ID: <36ea46ce-7add-4322-a030-1ee6c458d5db@kernel.org>

On 02/12/2024 15:31, Dave Stevenson wrote:
> The previous patch adding the compatible string missed out that
> the number of interrupts and clocks changed with BCM2712 too.
> 
> Update to validate clock and interrupts for the variants.
> 
> Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")


No such commit on current next.

> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  .../bindings/display/brcm,bcm2835-hvs.yaml         | 77 +++++++++++++++++-----
>  1 file changed, 61 insertions(+), 16 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> index f91c9dce2a44..ab59edbcf32c 100644
> --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> @@ -19,12 +19,13 @@ properties:
>    reg:
>      maxItems: 1
>  
> -  interrupts:
> -    maxItems: 1
> +  interrupts: true

No, widest constrains are *always* here.

>  
> -  clocks:
> -    maxItems: 1
> -    description: Core Clock
> +  interrupt-names: true
> +
> +  clocks: true
> +
> +  clock-names: true


No, this has to be complete (widest) here.


>  
>  required:
>    - compatible
> @@ -33,17 +34,61 @@ required:
>  
Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec  2 07:18:51 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 16:18:51 +0100
Subject: [PATCH 3/7] dt-bindings: gpio: brcmstb: add gpio-line-name
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-3-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-3-fac67cc2f98a@raspberrypi.com>
Message-ID: <39c73599-9bea-4b2e-afa6-3780726e27f5@kernel.org>

On 02/12/2024 15:31, Dave Stevenson wrote:
> Support comes from gpiolib, so permit it through the binding.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
> index f096f286da19..086d016df6ef 100644
> --- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
> +++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
> @@ -64,6 +64,8 @@ properties:
>  
>    gpio-ranges: true
>  
> +  gpio-line-names: true


maxItems


Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec  2 07:20:46 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 16:20:46 +0100
Subject: [PATCH 4/7] arm64: dts: broadcom: Fix device tree warnings for
 BCM2712 display pipeline
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-4-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-4-fac67cc2f98a@raspberrypi.com>
Message-ID: <c8093283-f2c1-4a66-823a-50aeabb3c82b@kernel.org>

On 02/12/2024 15:31, Dave Stevenson wrote:
> Fixes up errors on HDMI and interrupt controllers that weren't

What errors? I can't find anything in the commit. Describe the error.

> noticed before merging.
> 
> Fixes: de9bc2dba3db ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
> index 39305e0869ec..f42fad2d8b37 100644
> --- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
> +++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
> @@ -336,7 +336,7 @@ ddc1: i2c at 7d508280 {
>  			#size-cells = <0>;
>  		};
>  
> -		bsc_irq: intc at 7d508380 {
> +		bsc_irq: interrupt-controller at 7d508380 {


Do not mix cleanups with bugfixes.

BTW, do not mix DTS to DRM. DRM has its own development style. DTS
*cannot* be merged there, so combining these series is not welcomed and
leads to issues (like DRM applying DTS!).

>  			compatible = "brcm,bcm7271-l2-intc";
>  			reg = <0x7d508380 0x10>;
>  			interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
> @@ -344,7 +344,7 @@ bsc_irq: intc at 7d508380 {
>  			#interrupt-cells = <1>;
>  		};
>  
> -		main_irq: intc at 7d508400 {
> +		main_irq: interrupt-controller at 7d508400 {
>  			compatible = "brcm,bcm7271-l2-intc";
>  			reg = <0x7d508400 0x10>;
>  			interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
> @@ -352,7 +352,7 @@ main_irq: intc at 7d508400 {
>  			#interrupt-cells = <1>;
>  		};
Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec  2 07:22:06 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 16:22:06 +0100
Subject: [PATCH 5/7] arm64: dts: broadcom: Add interrupt-controller flag
 for intc on BCM2712
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-5-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-5-fac67cc2f98a@raspberrypi.com>
Message-ID: <8b2863e7-d504-49dc-a2ad-d34bfbeb6de8@kernel.org>

On 02/12/2024 15:31, Dave Stevenson wrote:
> BCM2712 DT was producing dtbinding validation errors of

s/DT/DTS/
No one uses term like "dtbinding". Use full make target name or DT schema.


> 
> interrupt-controller at 7cd00000: 'interrupt-controller' is a required
> property
> interrupt-controller at 7cd00000: '#interrupt-cells' is a required property
> 
> Fix them by adding the required flags.

But are these valid? Why do you think that binding is correct? Or you
just silence the warning regardless whether this matches the hardware?


Best regards,
Krzysztof


From ulf.hansson at linaro.org  Mon Dec  2 07:23:42 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 2 Dec 2024 16:23:42 +0100
Subject: [PATCH] mmc: sdhci-esdhc-imx: enable 'SDHCI_QUIRK_NO_LED' quirk
 for S32G
In-Reply-To: <20241125083357.1041949-1-ciprianmarian.costea@oss.nxp.com>
References: <20241125083357.1041949-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <CAPDyKFpkSRmGhZ68m7TyQNSqYKa7gnHigKpu4nKOpb-HWfCdeA@mail.gmail.com>

On Mon, 25 Nov 2024 at 09:34, Ciprian Costea
<ciprianmarian.costea at oss.nxp.com> wrote:
>
> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>
> Enable 'SDHCI_QUIRK_NO_LED' quirk for S32G2/S32G3 SoCs.
> S32G SDHCI controller does not have a LED signal line.
>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index d55d045ef236..e23177ea9d91 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -304,6 +304,7 @@ static struct esdhc_soc_data usdhc_s32g2_data = {
>                         | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
>                         | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
>                         | ESDHC_FLAG_SKIP_ERR004536 | ESDHC_FLAG_SKIP_CD_WAKE,
> +       .quirks = SDHCI_QUIRK_NO_LED,
>  };
>
>  static struct esdhc_soc_data usdhc_imx7ulp_data = {
> --
> 2.45.2
>


From ulf.hansson at linaro.org  Mon Dec  2 07:23:46 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 2 Dec 2024 16:23:46 +0100
Subject: [PATCH v2 0/2] Add mtk-sd support for ignoring cmd response CRC
In-Reply-To: <20241126125041.16071-1-andy-ld.lu@mediatek.com>
References: <20241126125041.16071-1-andy-ld.lu@mediatek.com>
Message-ID: <CAPDyKFpSQj295wZf=mOPmSaLZvi769EdgFTcPJ6QRY0sOHA89w@mail.gmail.com>

On Tue, 26 Nov 2024 at 13:50, Andy-ld Lu <andy-ld.lu at mediatek.com> wrote:
>
> Add the process flow in the host driver to handle the R1B cmd response
> type with ignoring CRC, which comes from mmc_cqe_recovery() in the mmc
> core. Additionally, the response type 'MMC_RSP_R1B_NO_CRC' is introduced
> to simplify code.
>
> ---
> Changes in v2:
> - Change mmc_cqe_recovery() to use MMC_RSP_R1B_NO_CRC response type.
> - Remove MMC_RSP_R1_NO_CRC in the host driver after it is dropped.
>
> Link to v1:
> https://patchwork.kernel.org/patch/13883787
>
> ---
> Andy-ld Lu (2):
>   mmc: core: Introduce the MMC_RSP_R1B_NO_CRC response
>   mmc: mtk-sd: Add support for ignoring cmd response CRC
>
>  drivers/mmc/core/core.c   | 6 ++----
>  drivers/mmc/host/mtk-sd.c | 6 ++++--
>  include/linux/mmc/core.h  | 2 ++
>  3 files changed, 8 insertions(+), 6 deletions(-)
>
> --
> 2.46.0
>

The series applied for next, thanks!

Kind regards
Uffe


From ulf.hansson at linaro.org  Mon Dec  2 07:23:30 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 2 Dec 2024 16:23:30 +0100
Subject: [PATCH 04/15] dt-bindings: mmc: atmel,sama5d2-sdhci: add microchip,sama7d65-sdhci
In-Reply-To: <e9e9e4cf0753422706bdc44fe7d20ca3a686ce7a.1732030972.git.Ryan.Wanner@microchip.com>
References: <cover.1732030972.git.Ryan.Wanner@microchip.com> <e9e9e4cf0753422706bdc44fe7d20ca3a686ce7a.1732030972.git.Ryan.Wanner@microchip.com>
Message-ID: <CAPDyKFpN-2kowdi_eCtbW1WEdc5OKh7tj60GfbPPBR0Hbpyj5Q@mail.gmail.com>

On Tue, 19 Nov 2024 at 17:42, <Ryan.Wanner at microchip.com> wrote:
>
> From: Dharma Balasubiramani <dharma.b at microchip.com>
>
> Add mmc binding documentation for SAMA7D65.
>
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml b/Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml
> index 8c8ade88e8fe..ba75623b7778 100644
> --- a/Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml
> +++ b/Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml
> @@ -22,6 +22,7 @@ properties:
>        - items:
>            - enum:
>                - microchip,sam9x7-sdhci
> +              - microchip,sama7d65-sdhci
>                - microchip,sama7g5-sdhci
>            - const: microchip,sam9x60-sdhci
>
> --
> 2.43.0
>
>


From krzk at kernel.org  Mon Dec  2 07:24:20 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 16:24:20 +0100
Subject: [PATCH 7/7] arm64: dts: broadcom: Fix device tree errors on
 BCM2712.
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-7-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-7-fac67cc2f98a@raspberrypi.com>
Message-ID: <44c233d7-87d7-4dbb-a0d0-9e93ea497622@kernel.org>

On 02/12/2024 15:32, Dave Stevenson wrote:
> Resolves the issues on clocks and power nodes

Which issues? Be specific. Such commit is unprecise and not really
helpful. We see it from the diff that this is "some issue". What we do
not see is WHY and WHAT the ISSUE is.

> 
> Fixes: 4254a647b6c9 ("arm64: dts: broadcom: Add firmware clocks and power nodes to Pi5 DT")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>


Nothing in the DTS patches suggested targeting DRM, so this patchset is
organized in pretty surprising way. Please split them per subsystem. DTS
is never for driver subsystem.

Subject: drop full stop.

> ---
>  arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
> index fbc56309660f..26e05601416f 100644
> --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
> +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
> @@ -66,11 +66,7 @@ &sdio1 {
>  &soc {
>  	firmware: firmware {
>  		compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
> -		#address-cells = <1>;
> -		#size-cells = <1>;
> -
>  		mboxes = <&mailbox>;
> -		dma-ranges;
>  
>  		firmware_clocks: clocks {
>  			compatible = "raspberrypi,firmware-clocks";
> @@ -85,6 +81,11 @@ reset: reset {
>  
>  	power: power {
>  		compatible = "raspberrypi,bcm2835-power";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +		dma-ranges;


No address space here, so why ranges?

> +
>  		firmware = <&firmware>;
>  		#power-domain-cells = <1>;
>  	};
> 


Best regards,
Krzysztof


From mripard at kernel.org  Mon Dec  2 07:24:31 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 2 Dec 2024 16:24:31 +0100
Subject: [PATCH 4/7] arm64: dts: broadcom: Fix device tree warnings for
 BCM2712 display pipeline
In-Reply-To: <c8093283-f2c1-4a66-823a-50aeabb3c82b@kernel.org>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-4-fac67cc2f98a@raspberrypi.com>
 <c8093283-f2c1-4a66-823a-50aeabb3c82b@kernel.org>
Message-ID: <20241202-goose-of-pragmatic-sympathy-3fbbe7@houat>

On Mon, Dec 02, 2024 at 04:20:46PM +0100, Krzysztof Kozlowski wrote:
> On 02/12/2024 15:31, Dave Stevenson wrote:
> > Fixes up errors on HDMI and interrupt controllers that weren't
> 
> What errors? I can't find anything in the commit. Describe the error.
> 
> > noticed before merging.
> > 
> > Fixes: de9bc2dba3db ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
> > Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> > ---
> >  arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
> > index 39305e0869ec..f42fad2d8b37 100644
> > --- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
> > +++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
> > @@ -336,7 +336,7 @@ ddc1: i2c at 7d508280 {
> >  			#size-cells = <0>;
> >  		};
> >  
> > -		bsc_irq: intc at 7d508380 {
> > +		bsc_irq: interrupt-controller at 7d508380 {
> 
> 
> Do not mix cleanups with bugfixes.
> 
> BTW, do not mix DTS to DRM. DRM has its own development style. DTS
> *cannot* be merged there, so combining these series is not welcomed and
> leads to issues (like DRM applying DTS!).

When did that ever happen?

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

From ulf.hansson at linaro.org  Mon Dec  2 07:24:20 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 2 Dec 2024 16:24:20 +0100
Subject: [PATCH V6] mmc: bcm2835: add suspend/resume pm support
In-Reply-To: <20241202115140.33492-1-wahrenst@gmx.net>
References: <20241202115140.33492-1-wahrenst@gmx.net>
Message-ID: <CAPDyKFpX2dcimEVQ8EpOFvbJ6fPybazNLT-j1yf8Uoo79UD=dg@mail.gmail.com>

On Mon, 2 Dec 2024 at 12:51, Stefan Wahren <wahrenst at gmx.net> wrote:
>
> Add a minimalistic suspend/resume PM support.
>
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/bcm2835.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> Changes in V6:
> - split out of series because there is no dependency
> - remove unnecessary complete check
>
> diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
> index 7847f0c8b465..e5f151d092cd 100644
> --- a/drivers/mmc/host/bcm2835.c
> +++ b/drivers/mmc/host/bcm2835.c
> @@ -1343,6 +1343,25 @@ static int bcm2835_add_host(struct bcm2835_host *host)
>         return 0;
>  }
>
> +static int bcm2835_suspend(struct device *dev)
> +{
> +       struct bcm2835_host *host = dev_get_drvdata(dev);
> +
> +       clk_disable_unprepare(host->clk);
> +
> +       return 0;
> +}
> +
> +static int bcm2835_resume(struct device *dev)
> +{
> +       struct bcm2835_host *host = dev_get_drvdata(dev);
> +
> +       return clk_prepare_enable(host->clk);
> +}
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(bcm2835_pm_ops, bcm2835_suspend,
> +                               bcm2835_resume);
> +
>  static int bcm2835_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> @@ -1471,6 +1490,7 @@ static struct platform_driver bcm2835_driver = {
>                 .name           = "sdhost-bcm2835",
>                 .probe_type     = PROBE_PREFER_ASYNCHRONOUS,
>                 .of_match_table = bcm2835_match,
> +               .pm = pm_ptr(&bcm2835_pm_ops),
>         },
>  };
>  module_platform_driver(bcm2835_driver);
> --
> 2.34.1
>


From u.kleine-koenig at baylibre.com  Mon Dec  2 07:31:44 2024
From: u.kleine-koenig at baylibre.com (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Mon, 2 Dec 2024 16:31:44 +0100
Subject: [PATCH] devfreq: Switch back to struct platform_driver::remove()
In-Reply-To: <20241130135813.895628-2-u.kleine-koenig@baylibre.com>
References: <20241130135813.895628-2-u.kleine-koenig@baylibre.com>
Message-ID: <ecae7326gzjpwpg4a3ba2dgddh4jg362ybsf64xla4lyff3mk4@x3q6bocz2car>

Hello,

On Sat, Nov 30, 2024 at 02:58:11PM +0100, Uwe Kleine-K?nig wrote:
> After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
> return void") .remove() is (again) the right callback to implement for
> platform drivers.
> 
> Convert all platform drivers below drivers/devfreq to use .remove(),
> with the eventual goal to drop struct platform_driver::remove_new(). As
> .remove() and .remove_new() have the same prototypes, conversion is done
> by just changing the structure member name in the driver initializer.
> 
> While touching these drivers, make the alignment of the touched
> initializers consistent.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>

Note this patch is obsoleted by
https://git.kernel.org/linus/e70140ba0d2b1a30467d4af6bcfe761327b9ec95
.

Best regards
Uwe
-------------- 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/20241202/45285b3a/attachment.sig>

From heiko at sntech.de  Mon Dec  2 07:32:19 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 02 Dec 2024 16:32:19 +0100
Subject: [PATCH] arm64: dts: rockchip: enable rng on all rk356x
In-Reply-To: <c50f603a9e1a819f17f72e97e92aeebd@manjaro.org>
References: <20241201234613.52322-1-pbrobinson@gmail.com>
 <D6175VTSP13T.200HWIIHOIDQQ@cknow.org>
 <c50f603a9e1a819f17f72e97e92aeebd@manjaro.org>
Message-ID: <2377405.n0HT0TaD9V@diego>

Am Montag, 2. Dezember 2024, 15:50:07 CET schrieb Dragan Simic:
> Hello Diederik and Marcin,
> 
> On 2024-12-02 13:01, Diederik de Haas wrote:
> > On Mon Dec 2, 2024 at 11:40 AM CET, Marcin Juszkiewicz wrote:
> >> W dniu 2.12.2024 o 04:55, Dragan Simic pisze:
> >>  > On 2024-12-02 00:46, Peter Robinson wrote:
> >>  >> The rk356x rng is available on both the rk3566 and rk3568
> >>  >> parts, the IP is all self contained within the SoCs so
> >>  >> it's enabled already by default on rk3568 so let's enable
> >>  >> it in the base rk356x.dtsi so it's enabled consistently
> >>  >> everywhere.
> >>  >
> >>  > Please, go through the mailing list threads [1][2] that have led us
> >>  > to the current state.  To sum it up, it isn't about what's 
> >> supported
> >>  > in the two RK356x SoC variants, but about the RK3566's HWRNG being
> >>  > disabled because the testing showed that it produces unacceptably
> >>  > low quality of random data, for some yet unknown reason.
> >> 
> >> So maybe there should be a comment in rockchip/rk3568.dtsi so we would
> >> not get back to it again.
> > 
> > I suggested to put that in the (original) commit message:
> > https://lore.kernel.org/linux-rockchip/6690040.iosknibmi9 at bagend/
> > precisely because this was quite predictable to happen.
> > 
> > So a +1 on a comment in the dtsi with a link to the discussion in the
> > commit message.
> 
> Totally agreed on adding a brief summary to the RK356x base SoC dtsi,
> so I went ahead and sent a patch that adds it. [1]  I also expected
> that to be described in the base dtsi back when the HWRNG support was
> added, but it somehow went in without the description.

thanks a lot for doing that, so I'll drop this patch here now from my inbox.


Heiko




From will at kernel.org  Mon Dec  2 07:36:19 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 2 Dec 2024 15:36:19 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
Message-ID: <20241202153618.GA6834@willie-the-truck>

[+ usual suspects]

On Mon, Dec 02, 2024 at 07:58:30AM +0300, Vitaly Chikunov wrote:
> v6.13-rc1 exhibits a boot failure on aarch64 under KVM. (QEMU 9.1.1, CPU
> Kunpeng-920). Boot log:

I've not tried to repro this locally, but from the log:

> + time qemu-system-aarch64 -M accel=kvm:tcg -smp cores=8 -m 4096 -serial mon:stdio -nodefaults -nographic -no-reboot -fsdev local,id=root,path=/,security_model=none,multidevs=remap -device virtio-9p-pci,fsdev=root,mount_tag=virtio-9p:/ -device virtio-rng-pci -kernel /usr/src/tmp/kernel-image-6.13-buildroot/boot/vmlinuz-6.13.0-6.13-alt0.rc1 -initrd /usr/src/tmp/initramfs-6.13.0-6.13-alt0.rc1.img -sandbox on,spawn=deny -M virt,gic-version=3 -cpu max -append 'console=ttyAMA0 mitigations=off nokaslr  panic=-1 SCRIPT=/usr/src/tmp/vm.SchsIm2FjB earlycon earlyprintk=serial ignore_loglevel debug rddebug'
> [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x481fd010]
> [    0.000000] Linux version 6.13.0-6.13-alt0.rc1 (builder at localhost.localdomain) (gcc-14 (GCC) 14.2.1 20241028 (ALT Sisyphus 14.2.1-alt1), GNU ld (GNU Binutils) 2.43.1.20241025) #1 SMP PREEMPT_DYNAMIC Mon Dec  2 03:33:29 UTC 2024
> [    0.000000] KASLR disabled on command line
> [    0.000000] random: crng init done
> [    0.000000] Machine model: linux,dummy-virt
> [    0.000000] printk: debug: ignoring loglevel setting.
> [    0.000000] efi: UEFI not found.
> [    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '')
> [    0.000000] printk: legacy bootconsole [pl11] enabled
> [    0.000000] OF: reserved mem: Reserved memory: No reserved-memory node in the DT
> [    0.000000] NUMA: Faking a node at [mem 0x0000000040000000-0x000000013fffffff]
> [    0.000000] NODE_DATA(0) allocated [mem 0x13f7f3540-0x13f7f947f]
> [    0.000000] Zone ranges:
> [    0.000000]   DMA      [mem 0x0000000040000000-0x00000000ffffffff]
> [    0.000000]   DMA32    empty
> [    0.000000]   Normal   [mem 0x0000000100000000-0x000000013fffffff]
> [    0.000000] Movable zone start for each node
> [    0.000000] Early memory node ranges
> [    0.000000]   node   0: [mem 0x0000000040000000-0x000000013fffffff]
> [    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000013fffffff]
> [    0.000000] cma: Reserved 256 MiB at 0x00000000f0000000 on node -1
> [    0.000000] psci: probing for conduit method from DT.
> [    0.000000] psci: PSCIv1.1 detected in firmware.
> [    0.000000] psci: Using standard PSCI v0.2 function IDs
> [    0.000000] psci: Trusted OS migration not required
> [    0.000000] psci: SMC Calling Convention v1.1
> [    0.000000] smccc: KVM: hypervisor services detected (0x00000000 0x00000000 0x00000000 0x00000003)
> [    0.000000] percpu: Embedded 34 pages/cpu s100632 r8192 d30440 u139264
> [    0.000000] pcpu-alloc: s100632 r8192 d30440 u139264 alloc=34*4096
> [    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7
> [    0.000000] Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP

We take an undefined instruction exception in the kernel early during
boot...

> [    0.000000] Modules linked in:
> [    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.13.0-6.13-alt0.rc1 #1
> [    0.000000] Hardware name: linux,dummy-virt (DT)
> [    0.000000] pstate: 004000c5 (nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [    0.000000] pc : __cpuinfo_store_cpu+0xe8/0x240
> [    0.000000] lr : cpuinfo_store_boot_cpu+0x34/0x88
> [    0.000000] sp : ffff800082013df0
> [    0.000000] x29: ffff800082013df0 x28: 000000000000008e x27: ffff800081e38128
> [    0.000000] x26: ffff800081702190 x25: ffff80008201f040 x24: ffff0000ff7d1d00
> [    0.000000] x23: ffff80008201ec00 x22: ffff800081e39100 x21: ffff8000816f9750
> [    0.000000] x20: ffff800081f55280 x19: ffff0000ff6be2e0 x18: 0000000000000000
> [    0.000000] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> [    0.000000] x14: 000000000000002f x13: 000000013f7f9490 x12: 0000008000000000
> [    0.000000] x11: 0000000000000000 x10: 00000000007f8000 x9 : 000000013f808000
> [    0.000000] x8 : 0000000000000000 x7 : 0000000000000000 x6 : 000000013f7f94c0
> [    0.000000] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 1100010011111111
> [    0.000000] x2 : 0000000000000001 x1 : 0000000084448004 x0 : ffff0000ff6be2e0
> [    0.000000] Call trace:
> [    0.000000]  __cpuinfo_store_cpu+0xe8/0x240 (P)
> [    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88 (L)
> [    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88
> [    0.000000]  smp_prepare_boot_cpu+0x30/0x58
> [    0.000000]  start_kernel+0x514/0x9d0
> [    0.000000]  __primary_switched+0x88/0x98
> [    0.000000] Code: f100085f 54000600 f2580c7f 54000060 (d538a482)

... and that's:

   0:	f100085f 	cmp	x2, #0x2
   4:	54000600 	b.eq	0xc4  // b.none
   8:	f2580c7f 	tst	x3, #0xf0000000000
   c:	54000060 	b.eq	0x18  // b.none
  10:*	d538a482 	mrs	x2, s3_0_c10_c4_4		<-- trapping instruction

Which I think corresponds to a read of MPAMIDR_EL1.

It looks like James routed accesses to this register to undef_access()
in 31ff96c38ea3 ("KVM: arm64: Fix missing traps of guest accesses to the
MPAM register") so I'm not really sure how this is supposed to work
given that it's an ID register.

James?

Will


From rostedt at goodmis.org  Mon Dec  2 07:38:53 2024
From: rostedt at goodmis.org (Steven Rostedt)
Date: Mon, 2 Dec 2024 10:38:53 -0500
Subject: [PATCH 1/9] coresight: change coresight_device lock type to
 raw_spinlock_t
In-Reply-To: <GV1PR08MB10521520ABD7B72D92FD60DE9FB292@GV1PR08MB10521.eurprd08.prod.outlook.com>
References: <20241125094816.365472-1-yeoreum.yun@arm.com>
	<20241125094816.365472-2-yeoreum.yun@arm.com>
	<20241127120954.0facd34f@gandalf.local.home>
	<GV1PR08MB10521520ABD7B72D92FD60DE9FB292@GV1PR08MB10521.eurprd08.prod.outlook.com>
Message-ID: <20241202103853.26db0c13@gandalf.local.home>

On Thu, 28 Nov 2024 07:39:22 +0000
Yeo Reum Yun <YeoReum.Yun at arm.com> wrote:

> Hi Steven,
> 
> > We should start documenting what is not real-time "safe". That is, if this
> > code is executed, we have a loop here that holds a raw spin lock. This
> > appears to make the time the raw spin lock held to be non deterministic.
> > 
> > If someone is running PREEMPT_RT and expects deterministic behavior, they
> > cannot be using this code. That is fine, but we should probably create a
> > document somewhere that notes this.
> >
> > -- Steve  
> 
> I think it's quite deterministic becase the number of loop currently
> determined by the number of preload_feats.
> 
> Also, I don't think the number of  feats will be loaded as much as
> it can do undeterministic behavior since 
> the number is not many and it is quite predictable.

Still should be documented somewhere. It should describe the maximum number
of feats that will ever be loaded. If there's a max, it makes it back to
O(1). With a 'k' of how long it takes to process the max number of feats.

-- Steve



From wahrenst at gmx.net  Mon Dec  2 07:40:04 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon, 2 Dec 2024 16:40:04 +0100
Subject: [PATCH 6/7] arm: dts: broadcom: Add interrupt-controller flag for
 intc on BCM2711
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-6-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-6-fac67cc2f98a@raspberrypi.com>
Message-ID: <b80097a1-4c8b-43f1-920f-b31489619111@gmx.net>

Hi Dave,

Am 02.12.24 um 15:31 schrieb Dave Stevenson:
> BCM2711 DT was producing dtbinding validation errors of
>
> interrupt-controller at 40000000: 'interrupt-controller' is a required
> property
> interrupt-controller at 40000000: '#interrupt-cells' is a required property
>
> Fix them by adding the required flags.
>
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Did you actually test these changes, because the last time [1] it broke
the boot of RPi 4 and likely for RPi 5, too?

Best regards

[1] -
https://lore.kernel.org/linux-arm-kernel/07154679-42bc-43ba-8b72-62083ed78a4d at gmx.net/
> ---
>   arch/arm/boot/dts/broadcom/bcm2711.dtsi | 2 ++
>   1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm/boot/dts/broadcom/bcm2711.dtsi b/arch/arm/boot/dts/broadcom/bcm2711.dtsi
> index e4e42af21ef3..313b1046d74f 100644
> --- a/arch/arm/boot/dts/broadcom/bcm2711.dtsi
> +++ b/arch/arm/boot/dts/broadcom/bcm2711.dtsi
> @@ -51,6 +51,8 @@ soc {
>   		local_intc: interrupt-controller at 40000000 {
>   			compatible = "brcm,bcm2836-l1-intc";
>   			reg = <0x40000000 0x100>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
>   		};
>
>   		gicv2: interrupt-controller at 40041000 {
>



From tabba at google.com  Mon Dec  2 07:47:28 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:28 +0000
Subject: [PATCH v4 01/14] KVM: arm64: Consolidate allowed and restricted VM
 feature checks
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-2-tabba@google.com>

The definitions for features allowed and allowed with
restrictions for protected guests, which are based on feature
registers, were defined and checked for separately, even though
they are handled in the same way. This could result in missing
checks for certain features, e.g., pointer authentication,
causing traps for allowed features.

Consolidate the definitions into one. Use that new definition to
construct the guest view of the feature registers for
consistency.

Fixes: 6c30bfb18d0b ("KVM: arm64: Add handlers for protected VM System Registers")
Reported-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Fuad Tabba <tabba at google.com>

---

Note: This patch ends up being a no-op, since none of the changes
in it survive the series. It's included because it makes the rest
of the series flow more smoothly.
---
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h | 55 +++++++------------
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  8 +--
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            |  6 +-
 3 files changed, 26 insertions(+), 43 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
index f957890c7e38..d1e59b88ff66 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
@@ -14,11 +14,8 @@
  * guest virtual machines, depending on the mode KVM is running in and on the
  * type of guest that is running.
  *
- * The ALLOW masks represent a bitmask of feature fields that are allowed
- * without any restrictions as long as they are supported by the system.
- *
- * The RESTRICT_UNSIGNED masks, if present, represent unsigned fields for
- * features that are restricted to support at most the specified feature.
+ * Each field in the masks represents the highest supported *unsigned* value for
+ * the feature, if supported by the system.
  *
  * If a feature field is not present in either, than it is not supported.
  *
@@ -34,16 +31,7 @@
  * - Floating-point and Advanced SIMD
  * - Data Independent Timing
  * - Spectre/Meltdown Mitigation
- */
-#define PVM_ID_AA64PFR0_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) \
-	)
-
-/*
+ *
  * Restrict to the following *unsigned* features for protected VMs:
  * - AArch64 guests only (no support for AArch32 guests):
  *	AArch32 adds complexity in trap handling, emulation, condition codes,
@@ -51,7 +39,12 @@
  * - RAS (v1)
  *	Supported by KVM
  */
-#define PVM_ID_AA64PFR0_RESTRICT_UNSIGNED (\
+#define PVM_ID_AA64PFR0_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) | \
 	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL0, IMP) | \
 	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL1, IMP) | \
 	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL2, IMP) | \
@@ -77,20 +70,16 @@
  * - Distinction between Secure and Non-secure Memory
  * - Mixed-endian at EL0 only
  * - Non-context synchronizing exception entry and exit
+ *
+ * Restrict to the following *unsigned* features for protected VMs:
+ * - 40-bit IPA
+ * - 16-bit ASID
  */
 #define PVM_ID_AA64MMFR0_ALLOW (\
 	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGEND) | \
 	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_SNSMEM) | \
 	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGENDEL0) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) \
-	)
-
-/*
- * Restrict to the following *unsigned* features for protected VMs:
- * - 40-bit IPA
- * - 16-bit ASID
- */
-#define PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED (\
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) | \
 	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_PARANGE), ID_AA64MMFR0_EL1_PARANGE_40) | \
 	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_ASIDBITS), ID_AA64MMFR0_EL1_ASIDBITS_16) \
 	)
@@ -185,15 +174,6 @@
 	)
 
 /* Restrict pointer authentication to the basic version. */
-#define PVM_ID_AA64ISAR1_RESTRICT_UNSIGNED (\
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), ID_AA64ISAR1_EL1_APA_PAuth) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), ID_AA64ISAR1_EL1_API_PAuth) \
-	)
-
-#define PVM_ID_AA64ISAR2_RESTRICT_UNSIGNED (\
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
-	)
-
 #define PVM_ID_AA64ISAR1_ALLOW (\
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DPB) | \
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_JSCVT) | \
@@ -206,13 +186,16 @@
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_SPECRES) | \
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_BF16) | \
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DGH) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_I8MM) \
+	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_I8MM) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), ID_AA64ISAR1_EL1_APA_PAuth) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), ID_AA64ISAR1_EL1_API_PAuth) \
 	)
 
 #define PVM_ID_AA64ISAR2_ALLOW (\
 	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_ATS1A)| \
 	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_MOPS) \
+	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_MOPS) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
 	)
 
 u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 01616c39a810..76a70fee7647 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -36,9 +36,9 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
 
 	/* Protected KVM does not support AArch32 guests. */
 	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
-		PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL0_IMP);
+		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
 	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL1_IMP);
+		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
 
 	/*
 	 * Linux guests assume support for floating-point and Advanced SIMD. Do
@@ -362,8 +362,8 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), PVM_ID_AA64PFR0_ALLOW))
 		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
 
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_RESTRICT_UNSIGNED) &&
-	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_RESTRICT_UNSIGNED))
+	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_ALLOW) &&
+	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_ALLOW))
 		set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
 
 	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI), PVM_ID_AA64ISAR1_ALLOW) &&
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 2860548d4250..59fb2f056177 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -89,7 +89,7 @@ static u64 get_pvm_id_aa64pfr0(const struct kvm_vcpu *vcpu)
 	u64 allow_mask = PVM_ID_AA64PFR0_ALLOW;
 
 	set_mask |= get_restricted_features_unsigned(id_aa64pfr0_el1_sys_val,
-		PVM_ID_AA64PFR0_RESTRICT_UNSIGNED);
+		PVM_ID_AA64PFR0_ALLOW);
 
 	return (id_aa64pfr0_el1_sys_val & allow_mask) | set_mask;
 }
@@ -189,7 +189,7 @@ static u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu)
 	u64 set_mask;
 
 	set_mask = get_restricted_features_unsigned(id_aa64mmfr0_el1_sys_val,
-		PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED);
+		PVM_ID_AA64MMFR0_ALLOW);
 
 	return (id_aa64mmfr0_el1_sys_val & PVM_ID_AA64MMFR0_ALLOW) | set_mask;
 }
@@ -276,7 +276,7 @@ static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
 	 * of AArch32 feature id registers.
 	 */
 	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		     PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) > ID_AA64PFR0_EL1_EL1_IMP);
+		     PVM_ID_AA64PFR0_ALLOW) > ID_AA64PFR0_EL1_EL1_IMP);
 
 	return pvm_access_raz_wi(vcpu, p, r);
 }
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:29 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:29 +0000
Subject: [PATCH v4 02/14] KVM: arm64: Group setting traps for protected VMs by
 control register
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-3-tabba@google.com>

Group setting protected VM traps by control register rather than
feature id register, since some trap values (e.g., PAuth), depend
on more than one feature id register.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 317 +++++++++++++++------------------
 1 file changed, 144 insertions(+), 173 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 76a70fee7647..1744574e79b2 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -23,233 +23,204 @@ unsigned int kvm_arm_vmid_bits;
 
 unsigned int kvm_host_sve_max_vl;
 
-/*
- * Set trap register values based on features in ID_AA64PFR0.
- */
-static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
+static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 {
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
-	u64 hcr_set = HCR_RW;
-	u64 hcr_clear = 0;
-	u64 cptr_set = 0;
-	u64 cptr_clear = 0;
-
-	/* Protected KVM does not support AArch32 guests. */
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
-		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
-
-	/*
-	 * Linux guests assume support for floating-point and Advanced SIMD. Do
-	 * not change the trapping behavior for these from the KVM default.
-	 */
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP),
-				PVM_ID_AA64PFR0_ALLOW));
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
-				PVM_ID_AA64PFR0_ALLOW));
+	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
 
 	if (has_hvhe())
-		hcr_set |= HCR_E2H;
+		vcpu->arch.hcr_el2 |= HCR_E2H;
 
-	/* Trap RAS unless all current versions are supported */
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), feature_ids) <
-	    ID_AA64PFR0_EL1_RAS_V1P1) {
-		hcr_set |= HCR_TERR | HCR_TEA;
-		hcr_clear |= HCR_FIEN;
+	if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
+		/* route synchronous external abort exceptions to EL2 */
+		vcpu->arch.hcr_el2 |= HCR_TEA;
+		/* trap error record accesses */
+		vcpu->arch.hcr_el2 |= HCR_TERR;
 	}
 
-	/* Trap AMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), feature_ids)) {
-		hcr_clear |= HCR_AMVOFFEN;
-		cptr_set |= CPTR_EL2_TAM;
-	}
+	if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
+		vcpu->arch.hcr_el2 |= HCR_FWB;
 
-	/* Trap SVE */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), feature_ids)) {
-		if (has_hvhe())
-			cptr_clear |= CPACR_ELx_ZEN;
-		else
-			cptr_set |= CPTR_EL2_TZ;
-	}
+	if (cpus_have_final_cap(ARM64_HAS_EVT) &&
+	    !cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE))
+		vcpu->arch.hcr_el2 |= HCR_TID4;
+	else
+		vcpu->arch.hcr_el2 |= HCR_TID2;
 
-	vcpu->arch.hcr_el2 |= hcr_set;
-	vcpu->arch.hcr_el2 &= ~hcr_clear;
-	vcpu->arch.cptr_el2 |= cptr_set;
-	vcpu->arch.cptr_el2 &= ~cptr_clear;
+	if (vcpu_has_ptrauth(vcpu))
+		vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
 }
 
-/*
- * Set trap register values based on features in ID_AA64PFR1.
- */
-static void pvm_init_traps_aa64pfr1(struct kvm_vcpu *vcpu)
+static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 {
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
-	u64 hcr_set = 0;
-	u64 hcr_clear = 0;
+	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
+	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
+	const u64 id_aa64mmfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
+	u64 val = vcpu->arch.hcr_el2;
+
+	/* No support for AArch32. */
+	val |= HCR_RW;
+
+	if (has_hvhe())
+		val |= HCR_E2H;
+
+	/*
+	 * Always trap:
+	 * - Feature id registers: to control features exposed to guests
+	 * - Implementation-defined features
+	 */
+	val |= HCR_TACR | HCR_TIDCP | HCR_TID3 | HCR_TID1;
+
+	/* Trap RAS unless all current versions are supported */
+	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0) <
+	    ID_AA64PFR0_EL1_RAS_V1P1) {
+		val |= HCR_TERR | HCR_TEA;
+		val &= ~(HCR_FIEN);
+	}
+
+	/* Trap AMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
+		val &= ~(HCR_AMVOFFEN);
 
 	/* Memory Tagging: Trap and Treat as Untagged if not supported. */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE), feature_ids)) {
-		hcr_set |= HCR_TID5;
-		hcr_clear |= HCR_DCT | HCR_ATA;
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE), id_aa64pfr1)) {
+		val |= HCR_TID5;
+		val &= ~(HCR_DCT | HCR_ATA);
 	}
 
-	vcpu->arch.hcr_el2 |= hcr_set;
-	vcpu->arch.hcr_el2 &= ~hcr_clear;
+	/* Trap LOR */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_LO), id_aa64mmfr1))
+		val |= HCR_TLOR;
+
+	vcpu->arch.hcr_el2 = val;
 }
 
-/*
- * Set trap register values based on features in ID_AA64DFR0.
- */
-static void pvm_init_traps_aa64dfr0(struct kvm_vcpu *vcpu)
+static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 {
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
-	u64 mdcr_set = 0;
-	u64 mdcr_clear = 0;
-	u64 cptr_set = 0;
+	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
+	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
+	const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
+	u64 val = vcpu->arch.cptr_el2;
 
-	/* Trap/constrain PMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), feature_ids)) {
-		mdcr_set |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
-		mdcr_clear |= MDCR_EL2_HPME | MDCR_EL2_MTPME |
-			      MDCR_EL2_HPMN_MASK;
+	if (!has_hvhe()) {
+		val |= CPTR_NVHE_EL2_RES1;
+		val &= ~(CPTR_NVHE_EL2_RES0);
 	}
 
-	/* Trap Debug */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DebugVer), feature_ids))
-		mdcr_set |= MDCR_EL2_TDRA | MDCR_EL2_TDA | MDCR_EL2_TDE;
-
-	/* Trap OS Double Lock */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DoubleLock), feature_ids))
-		mdcr_set |= MDCR_EL2_TDOSA;
+	/* Trap AMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
+		val |= CPTR_EL2_TAM;
 
-	/* Trap SPE */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMSVer), feature_ids)) {
-		mdcr_set |= MDCR_EL2_TPMS;
-		mdcr_clear |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT;
+	/* Trap SVE */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), id_aa64pfr0)) {
+		if (has_hvhe())
+			val &= ~(CPACR_ELx_ZEN);
+		else
+			val |= CPTR_EL2_TZ;
 	}
 
-	/* Trap Trace Filter */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), feature_ids))
-		mdcr_set |= MDCR_EL2_TTRF;
+	/* No SME support in KVM. */
+	BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME), id_aa64pfr1));
+	if (has_hvhe())
+		val &= ~(CPACR_ELx_SMEN);
+	else
+		val |= CPTR_EL2_TSM;
 
 	/* Trap Trace */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), feature_ids)) {
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), id_aa64dfr0)) {
 		if (has_hvhe())
-			cptr_set |= CPACR_EL1_TTA;
+			val |= CPACR_EL1_TTA;
 		else
-			cptr_set |= CPTR_EL2_TTA;
+			val |= CPTR_EL2_TTA;
 	}
 
-	/* Trap External Trace */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), feature_ids))
-		mdcr_clear |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
-
-	vcpu->arch.mdcr_el2 |= mdcr_set;
-	vcpu->arch.mdcr_el2 &= ~mdcr_clear;
-	vcpu->arch.cptr_el2 |= cptr_set;
-}
-
-/*
- * Set trap register values based on features in ID_AA64MMFR0.
- */
-static void pvm_init_traps_aa64mmfr0(struct kvm_vcpu *vcpu)
-{
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR0_EL1);
-	u64 mdcr_set = 0;
-
-	/* Trap Debug Communications Channel registers */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_FGT), feature_ids))
-		mdcr_set |= MDCR_EL2_TDCC;
-
-	vcpu->arch.mdcr_el2 |= mdcr_set;
+	vcpu->arch.cptr_el2 = val;
 }
 
-/*
- * Set trap register values based on features in ID_AA64MMFR1.
- */
-static void pvm_init_traps_aa64mmfr1(struct kvm_vcpu *vcpu)
-{
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
-	u64 hcr_set = 0;
-
-	/* Trap LOR */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_LO), feature_ids))
-		hcr_set |= HCR_TLOR;
-
-	vcpu->arch.hcr_el2 |= hcr_set;
-}
-
-/*
- * Set baseline trap register values.
- */
-static void pvm_init_trap_regs(struct kvm_vcpu *vcpu)
+static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 {
-	const u64 hcr_trap_feat_regs = HCR_TID3;
-	const u64 hcr_trap_impdef = HCR_TACR | HCR_TIDCP | HCR_TID1;
-
-	/*
-	 * Always trap:
-	 * - Feature id registers: to control features exposed to guests
-	 * - Implementation-defined features
-	 */
-	vcpu->arch.hcr_el2 |= hcr_trap_feat_regs | hcr_trap_impdef;
+	const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
+	const u64 id_aa64mmfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR0_EL1);
+	u64 val = vcpu->arch.mdcr_el2;
 
-	/* Clear res0 and set res1 bits to trap potential new features. */
-	vcpu->arch.hcr_el2 &= ~(HCR_RES0);
-	vcpu->arch.mdcr_el2 &= ~(MDCR_EL2_RES0);
-	if (!has_hvhe()) {
-		vcpu->arch.cptr_el2 |= CPTR_NVHE_EL2_RES1;
-		vcpu->arch.cptr_el2 &= ~(CPTR_NVHE_EL2_RES0);
+	/* Trap/constrain PMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), id_aa64dfr0)) {
+		val |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
+		val &= ~(MDCR_EL2_HPME | MDCR_EL2_MTPME | MDCR_EL2_HPMN_MASK);
 	}
-}
 
-static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
-{
-	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
+	/* Trap Debug */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DebugVer), id_aa64dfr0))
+		val |= MDCR_EL2_TDRA | MDCR_EL2_TDA;
 
-	if (has_hvhe())
-		vcpu->arch.hcr_el2 |= HCR_E2H;
+	/* Trap OS Double Lock */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DoubleLock), id_aa64dfr0))
+		val |= MDCR_EL2_TDOSA;
 
-	if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
-		/* route synchronous external abort exceptions to EL2 */
-		vcpu->arch.hcr_el2 |= HCR_TEA;
-		/* trap error record accesses */
-		vcpu->arch.hcr_el2 |= HCR_TERR;
+	/* Trap SPE */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMSVer), id_aa64dfr0)) {
+		val |= MDCR_EL2_TPMS;
+		val &= ~(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT);
 	}
 
-	if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
-		vcpu->arch.hcr_el2 |= HCR_FWB;
+	/* Trap Trace Filter */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), id_aa64dfr0))
+		val |= MDCR_EL2_TTRF;
 
-	if (cpus_have_final_cap(ARM64_HAS_EVT) &&
-	    !cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE))
-		vcpu->arch.hcr_el2 |= HCR_TID4;
-	else
-		vcpu->arch.hcr_el2 |= HCR_TID2;
+	/* Trap External Trace */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), id_aa64dfr0))
+		val |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
 
-	if (vcpu_has_ptrauth(vcpu))
-		vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
+	/* Trap Debug Communications Channel registers */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_FGT), id_aa64mmfr0))
+		val |= MDCR_EL2_TDCC;
+
+	vcpu->arch.mdcr_el2 = val;
 }
 
 /*
  * Initialize trap register values in protected mode.
  */
-static void pkvm_vcpu_init_traps(struct kvm_vcpu *vcpu)
+static void pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
 {
+	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
+
 	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
 	vcpu->arch.mdcr_el2 = 0;
 
 	pkvm_vcpu_reset_hcr(vcpu);
 
-	if ((!vcpu_is_protected(vcpu)))
+	if ((!pkvm_hyp_vcpu_is_protected(hyp_vcpu)))
 		return;
 
-	pvm_init_trap_regs(vcpu);
-	pvm_init_traps_aa64pfr0(vcpu);
-	pvm_init_traps_aa64pfr1(vcpu);
-	pvm_init_traps_aa64dfr0(vcpu);
-	pvm_init_traps_aa64mmfr0(vcpu);
-	pvm_init_traps_aa64mmfr1(vcpu);
+	/*
+	 * PAuth is allowed if supported by the system and the vcpu.
+	 * Properly checking for PAuth requires checking various fields in
+	 * ID_AA64ISAR1_EL1 and ID_AA64ISAR2_EL1. The way that fixed config
+	 * is controlled now in pKVM does not easily allow that. This will
+	 * change later to follow the changes upstream wrt fixed configuration
+	 * and nested virt.
+	 */
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI),
+				PVM_ID_AA64ISAR1_ALLOW));
+
+	/* Protected KVM does not support AArch32 guests. */
+	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
+		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
+	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
+		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
+
+	/*
+	 * Linux guests assume support for floating-point and Advanced SIMD. Do
+	 * not change the trapping behavior for these from the KVM default.
+	 */
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP),
+				PVM_ID_AA64PFR0_ALLOW));
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
+				PVM_ID_AA64PFR0_ALLOW));
+
+	pvm_init_traps_hcr(vcpu);
+	pvm_init_traps_cptr(vcpu);
+	pvm_init_traps_mdcr(vcpu);
 }
 
 /*
@@ -448,7 +419,7 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
 
 	pkvm_vcpu_init_sve(hyp_vcpu, host_vcpu);
 	pkvm_vcpu_init_ptrauth(hyp_vcpu);
-	pkvm_vcpu_init_traps(&hyp_vcpu->vcpu);
+	pkvm_vcpu_init_traps(hyp_vcpu);
 done:
 	if (ret)
 		unpin_host_vcpu(host_vcpu);
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:30 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:30 +0000
Subject: [PATCH v4 03/14] KVM: arm64: Move checking protected vcpu features to
 a separate function
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-4-tabba@google.com>

At the moment, checks for supported vcpu features for protected
VMs are build-time bugs. In the following patch, they will become
runtime checks based on the vcpu's features registers. Therefore,
consolidate them into one function that would return an error if
it encounters an unsupported feature.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 45 ++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 1744574e79b2..fb733b36c6c1 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -178,20 +178,11 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 }
 
 /*
- * Initialize trap register values in protected mode.
+ * Check that cpu features that are neither trapped nor supported are not
+ * enabled for protected VMs.
  */
-static void pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
+static int pkvm_check_pvm_cpu_features(struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
-
-	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
-	vcpu->arch.mdcr_el2 = 0;
-
-	pkvm_vcpu_reset_hcr(vcpu);
-
-	if ((!pkvm_hyp_vcpu_is_protected(hyp_vcpu)))
-		return;
-
 	/*
 	 * PAuth is allowed if supported by the system and the vcpu.
 	 * Properly checking for PAuth requires checking various fields in
@@ -218,9 +209,34 @@ static void pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
 	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
 				PVM_ID_AA64PFR0_ALLOW));
 
+	return 0;
+}
+
+/*
+ * Initialize trap register values in protected mode.
+ */
+static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
+{
+	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
+	int ret;
+
+	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
+	vcpu->arch.mdcr_el2 = 0;
+
+	pkvm_vcpu_reset_hcr(vcpu);
+
+	if ((!pkvm_hyp_vcpu_is_protected(hyp_vcpu)))
+		return 0;
+
+	ret = pkvm_check_pvm_cpu_features(vcpu);
+	if (ret)
+		return ret;
+
 	pvm_init_traps_hcr(vcpu);
 	pvm_init_traps_cptr(vcpu);
 	pvm_init_traps_mdcr(vcpu);
+
+	return 0;
 }
 
 /*
@@ -417,9 +433,12 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
 	hyp_vcpu->vcpu.arch.cflags = READ_ONCE(host_vcpu->arch.cflags);
 	hyp_vcpu->vcpu.arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
 
+	ret = pkvm_vcpu_init_traps(hyp_vcpu);
+	if (ret)
+		goto done;
+
 	pkvm_vcpu_init_sve(hyp_vcpu, host_vcpu);
 	pkvm_vcpu_init_ptrauth(hyp_vcpu);
-	pkvm_vcpu_init_traps(hyp_vcpu);
 done:
 	if (ret)
 		unpin_host_vcpu(host_vcpu);
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:31 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:31 +0000
Subject: [PATCH v4 04/14] KVM: arm64: Use KVM extension checks for allowed
 protected VM capabilities
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-5-tabba@google.com>

Use KVM extension checks as the source for determining which
capabilities are allowed for protected VMs. KVM extension checks
is the natural place for this, since it is also the interface
exposed to users.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_pkvm.h | 25 +++++++++++++++++++++++++
 arch/arm64/kvm/arm.c              | 29 ++---------------------------
 arch/arm64/kvm/hyp/nvhe/pkvm.c    | 26 ++++++--------------------
 3 files changed, 33 insertions(+), 47 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index cd56acd9a842..400f7cef1e81 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -20,6 +20,31 @@ int pkvm_init_host_vm(struct kvm *kvm);
 int pkvm_create_hyp_vm(struct kvm *kvm);
 void pkvm_destroy_hyp_vm(struct kvm *kvm);
 
+/*
+ * This functions as an allow-list of protected VM capabilities.
+ * Features not explicitly allowed by this function are denied.
+ */
+static inline bool kvm_pvm_ext_allowed(long ext)
+{
+	switch (ext) {
+	case KVM_CAP_IRQCHIP:
+	case KVM_CAP_ARM_PSCI:
+	case KVM_CAP_ARM_PSCI_0_2:
+	case KVM_CAP_NR_VCPUS:
+	case KVM_CAP_MAX_VCPUS:
+	case KVM_CAP_MAX_VCPU_ID:
+	case KVM_CAP_MSI_DEVID:
+	case KVM_CAP_ARM_VM_IPA_SIZE:
+	case KVM_CAP_ARM_PMU_V3:
+	case KVM_CAP_ARM_SVE:
+	case KVM_CAP_ARM_PTRAUTH_ADDRESS:
+	case KVM_CAP_ARM_PTRAUTH_GENERIC:
+		return true;
+	default:
+		return false;
+	}
+}
+
 extern struct memblock_region kvm_nvhe_sym(hyp_memory)[];
 extern unsigned int kvm_nvhe_sym(hyp_memblock_nr);
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..b295218cdc24 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -80,31 +80,6 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
 	return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
 }
 
-/*
- * This functions as an allow-list of protected VM capabilities.
- * Features not explicitly allowed by this function are denied.
- */
-static bool pkvm_ext_allowed(struct kvm *kvm, long ext)
-{
-	switch (ext) {
-	case KVM_CAP_IRQCHIP:
-	case KVM_CAP_ARM_PSCI:
-	case KVM_CAP_ARM_PSCI_0_2:
-	case KVM_CAP_NR_VCPUS:
-	case KVM_CAP_MAX_VCPUS:
-	case KVM_CAP_MAX_VCPU_ID:
-	case KVM_CAP_MSI_DEVID:
-	case KVM_CAP_ARM_VM_IPA_SIZE:
-	case KVM_CAP_ARM_PMU_V3:
-	case KVM_CAP_ARM_SVE:
-	case KVM_CAP_ARM_PTRAUTH_ADDRESS:
-	case KVM_CAP_ARM_PTRAUTH_GENERIC:
-		return true;
-	default:
-		return false;
-	}
-}
-
 int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 			    struct kvm_enable_cap *cap)
 {
@@ -113,7 +88,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 	if (cap->flags)
 		return -EINVAL;
 
-	if (kvm_vm_is_protected(kvm) && !pkvm_ext_allowed(kvm, cap->cap))
+	if (kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(cap->cap))
 		return -EINVAL;
 
 	switch (cap->cap) {
@@ -311,7 +286,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 {
 	int r;
 
-	if (kvm && kvm_vm_is_protected(kvm) && !pkvm_ext_allowed(kvm, ext))
+	if (kvm && kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(ext))
 		return 0;
 
 	switch (ext) {
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index fb733b36c6c1..59ff6aac514c 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -329,34 +329,20 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 
 	bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
 
-	/*
-	 * For protected VMs, always allow:
-	 * - CPU starting in poweroff state
-	 * - PSCI v0.2
-	 */
-	set_bit(KVM_ARM_VCPU_POWER_OFF, allowed_features);
 	set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
 
-	/*
-	 * Check if remaining features are allowed:
-	 * - Performance Monitoring
-	 * - Scalable Vectors
-	 * - Pointer Authentication
-	 */
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), PVM_ID_AA64DFR0_ALLOW))
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PMU_V3))
 		set_bit(KVM_ARM_VCPU_PMU_V3, allowed_features);
 
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), PVM_ID_AA64PFR0_ALLOW))
-		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
-
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_ALLOW) &&
-	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_ALLOW))
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_ADDRESS))
 		set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
 
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI), PVM_ID_AA64ISAR1_ALLOW) &&
-	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA), PVM_ID_AA64ISAR1_ALLOW))
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_GENERIC))
 		set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
 
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE))
+		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
+
 	bitmap_and(kvm->arch.vcpu_features, host_kvm->arch.vcpu_features,
 		   allowed_features, KVM_VCPU_MAX_FEATURES);
 }
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:32 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:32 +0000
Subject: [PATCH v4 05/14] KVM: arm64: Initialize feature id registers for
 protected VMs
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-6-tabba@google.com>

The hypervisor maintains the state of protected VMs. Initialize
the values for feature ID registers for protected VMs, to be used
when setting traps and when advertising features to protected
VMs.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h |  1 +
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  4 ++
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            | 42 +++++++++++++++++--
 3 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
index d1e59b88ff66..69e26d1a0ebe 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
@@ -201,6 +201,7 @@
 u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
 bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
 bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
+void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu);
 int kvm_check_pvm_sysreg_table(void);
 
 #endif /* __ARM64_KVM_FIXED_CONFIG_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 59ff6aac514c..4ef03294b2b4 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -381,6 +381,7 @@ static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
 	hyp_vm->kvm.created_vcpus = nr_vcpus;
 	hyp_vm->kvm.arch.mmu.vtcr = host_mmu.arch.mmu.vtcr;
 	hyp_vm->kvm.arch.pkvm.enabled = READ_ONCE(host_kvm->arch.pkvm.enabled);
+	hyp_vm->kvm.arch.flags = 0;
 	pkvm_init_features_from_host(hyp_vm, host_kvm);
 }
 
@@ -419,6 +420,9 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
 	hyp_vcpu->vcpu.arch.cflags = READ_ONCE(host_vcpu->arch.cflags);
 	hyp_vcpu->vcpu.arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
 
+	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		kvm_init_pvm_id_regs(&hyp_vcpu->vcpu);
+
 	ret = pkvm_vcpu_init_traps(hyp_vcpu);
 	if (ret)
 		goto done;
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 59fb2f056177..1261da6a2861 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -204,8 +204,7 @@ static u64 get_pvm_id_aa64mmfr2(const struct kvm_vcpu *vcpu)
 	return id_aa64mmfr2_el1_sys_val & PVM_ID_AA64MMFR2_ALLOW;
 }
 
-/* Read a sanitized cpufeature ID register by its encoding */
-u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
+static u64 pvm_calc_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 {
 	switch (id) {
 	case SYS_ID_AA64PFR0_EL1:
@@ -240,10 +239,25 @@ u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 	}
 }
 
+/* Read a sanitized cpufeature ID register by its encoding */
+u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
+{
+	return pvm_calc_id_reg(vcpu, id);
+}
+
 static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 		       struct sys_reg_desc const *r)
 {
-	return pvm_read_id_reg(vcpu, reg_to_encoding(r));
+	struct kvm *kvm = vcpu->kvm;
+	u32 reg = reg_to_encoding(r);
+
+	if (WARN_ON_ONCE(!test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags)))
+		return 0;
+
+	if (reg >= sys_reg(3, 0, 0, 1, 0) && reg <= sys_reg(3, 0, 0, 7, 7))
+		return kvm->arch.id_regs[IDREG_IDX(reg)];
+
+	return 0;
 }
 
 /* Handler to RAZ/WI sysregs */
@@ -448,6 +462,28 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = {
 	/* Performance Monitoring Registers are restricted. */
 };
 
+/*
+ * Initializes feature registers for protected vms.
+ */
+void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+	struct kvm_arch *ka = &kvm->arch;
+	u32 r;
+
+	if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags))
+		return;
+
+	/*
+	 * Initialize only AArch64 id registers since AArch32 isn't supported
+	 * for protected VMs.
+	 */
+	for (r = sys_reg(3, 0, 0, 4, 0); r <= sys_reg(3, 0, 0, 7, 7); r += sys_reg(0, 0, 0, 0, 1))
+		ka->id_regs[IDREG_IDX(r)] = pvm_calc_id_reg(vcpu, r);
+
+	set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
+}
+
 /*
  * Checks that the sysreg table is unique and in-order.
  *
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:33 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:33 +0000
Subject: [PATCH v4 06/14] KVM: arm64: Set protected VM traps based on its view
 of feature registers
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-7-tabba@google.com>

Now that the VM's feature id registers are initialized with the
values of the supported features, use those values to determine
which traps to set using kvm_has_feature().

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c     | 85 +++++++++++-------------------
 arch/arm64/kvm/hyp/nvhe/sys_regs.c |  7 ---
 2 files changed, 30 insertions(+), 62 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 4ef03294b2b4..3b4ea97148b9 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -52,9 +52,7 @@ static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 
 static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 {
-	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
-	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
-	const u64 id_aa64mmfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
+	struct kvm *kvm = vcpu->kvm;
 	u64 val = vcpu->arch.hcr_el2;
 
 	/* No support for AArch32. */
@@ -70,25 +68,20 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 	 */
 	val |= HCR_TACR | HCR_TIDCP | HCR_TID3 | HCR_TID1;
 
-	/* Trap RAS unless all current versions are supported */
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0) <
-	    ID_AA64PFR0_EL1_RAS_V1P1) {
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
 		val |= HCR_TERR | HCR_TEA;
 		val &= ~(HCR_FIEN);
 	}
 
-	/* Trap AMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
 		val &= ~(HCR_AMVOFFEN);
 
-	/* Memory Tagging: Trap and Treat as Untagged if not supported. */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE), id_aa64pfr1)) {
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, MTE, IMP)) {
 		val |= HCR_TID5;
 		val &= ~(HCR_DCT | HCR_ATA);
 	}
 
-	/* Trap LOR */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_LO), id_aa64mmfr1))
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
 		val |= HCR_TLOR;
 
 	vcpu->arch.hcr_el2 = val;
@@ -96,9 +89,7 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 
 static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 {
-	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
-	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
-	const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
+	struct kvm *kvm = vcpu->kvm;
 	u64 val = vcpu->arch.cptr_el2;
 
 	if (!has_hvhe()) {
@@ -106,12 +97,11 @@ static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 		val &= ~(CPTR_NVHE_EL2_RES0);
 	}
 
-	/* Trap AMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
 		val |= CPTR_EL2_TAM;
 
-	/* Trap SVE */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), id_aa64pfr0)) {
+	/* SVE can be disabled by userspace even if supported. */
+	if (!vcpu_has_sve(vcpu)) {
 		if (has_hvhe())
 			val &= ~(CPACR_ELx_ZEN);
 		else
@@ -119,14 +109,13 @@ static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 	}
 
 	/* No SME support in KVM. */
-	BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME), id_aa64pfr1));
+	BUG_ON(kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP));
 	if (has_hvhe())
 		val &= ~(CPACR_ELx_SMEN);
 	else
 		val |= CPTR_EL2_TSM;
 
-	/* Trap Trace */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), id_aa64dfr0)) {
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP)) {
 		if (has_hvhe())
 			val |= CPACR_EL1_TTA;
 		else
@@ -138,40 +127,33 @@ static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 
 static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 {
-	const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
-	const u64 id_aa64mmfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR0_EL1);
+	struct kvm *kvm = vcpu->kvm;
 	u64 val = vcpu->arch.mdcr_el2;
 
-	/* Trap/constrain PMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), id_aa64dfr0)) {
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP)) {
 		val |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
 		val &= ~(MDCR_EL2_HPME | MDCR_EL2_MTPME | MDCR_EL2_HPMN_MASK);
 	}
 
-	/* Trap Debug */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DebugVer), id_aa64dfr0))
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DebugVer, IMP))
 		val |= MDCR_EL2_TDRA | MDCR_EL2_TDA;
 
-	/* Trap OS Double Lock */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DoubleLock), id_aa64dfr0))
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
 		val |= MDCR_EL2_TDOSA;
 
-	/* Trap SPE */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMSVer), id_aa64dfr0)) {
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, IMP)) {
 		val |= MDCR_EL2_TPMS;
 		val &= ~(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT);
 	}
 
-	/* Trap Trace Filter */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), id_aa64dfr0))
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
 		val |= MDCR_EL2_TTRF;
 
-	/* Trap External Trace */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), id_aa64dfr0))
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, ExtTrcBuff, IMP))
 		val |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
 
 	/* Trap Debug Communications Channel registers */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_FGT), id_aa64mmfr0))
+	if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, FGT, IMP))
 		val |= MDCR_EL2_TDCC;
 
 	vcpu->arch.mdcr_el2 = val;
@@ -183,31 +165,24 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
  */
 static int pkvm_check_pvm_cpu_features(struct kvm_vcpu *vcpu)
 {
-	/*
-	 * PAuth is allowed if supported by the system and the vcpu.
-	 * Properly checking for PAuth requires checking various fields in
-	 * ID_AA64ISAR1_EL1 and ID_AA64ISAR2_EL1. The way that fixed config
-	 * is controlled now in pKVM does not easily allow that. This will
-	 * change later to follow the changes upstream wrt fixed configuration
-	 * and nested virt.
-	 */
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI),
-				PVM_ID_AA64ISAR1_ALLOW));
+	struct kvm *kvm = vcpu->kvm;
 
 	/* Protected KVM does not support AArch32 guests. */
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
-		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
+	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL0, AARCH32) ||
+	    kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL1, AARCH32))
+		return -EINVAL;
 
 	/*
 	 * Linux guests assume support for floating-point and Advanced SIMD. Do
 	 * not change the trapping behavior for these from the KVM default.
 	 */
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP),
-				PVM_ID_AA64PFR0_ALLOW));
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
-				PVM_ID_AA64PFR0_ALLOW));
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, FP, IMP) ||
+	    !kvm_has_feat(kvm, ID_AA64PFR0_EL1, AdvSIMD, IMP))
+		return -EINVAL;
+
+	/* No SME support in KVM right now. Check to catch if it changes. */
+	if (kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
+		return -EINVAL;
 
 	return 0;
 }
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 1261da6a2861..39b678d2c120 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -285,13 +285,6 @@ static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
 		return false;
 	}
 
-	/*
-	 * No support for AArch32 guests, therefore, pKVM has no sanitized copy
-	 * of AArch32 feature id registers.
-	 */
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		     PVM_ID_AA64PFR0_ALLOW) > ID_AA64PFR0_EL1_EL1_IMP);
-
 	return pvm_access_raz_wi(vcpu, p, r);
 }
 
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:34 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:34 +0000
Subject: [PATCH v4 07/14] KVM: arm64: Rework specifying restricted features
 for protected VMs
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-8-tabba@google.com>

The existing code didn't properly distinguish between signed and
unsigned features, and was difficult to read and to maintain.
Rework it using the same method used in other parts of KVM when
handling vcpu features.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_host.h             |   1 +
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h |   1 -
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            | 357 +++++++++---------
 3 files changed, 189 insertions(+), 170 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f333b189fb43..230b0638f0c2 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1422,6 +1422,7 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
 	return test_bit(feature, ka->vcpu_features);
 }
 
+#define kvm_vcpu_has_feature(k, f)	__vcpu_has_feature(&(k)->arch, (f))
 #define vcpu_has_feature(v, f)	__vcpu_has_feature(&(v)->kvm->arch, (f))
 
 #define kvm_vcpu_initialized(v) vcpu_get_flag(vcpu, VCPU_INITIALIZED)
diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
index 69e26d1a0ebe..37a6d2434e47 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
@@ -198,7 +198,6 @@
 	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
 	)
 
-u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
 bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
 bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
 void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 39b678d2c120..b6140590b569 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -28,221 +28,240 @@ u64 id_aa64mmfr1_el1_sys_val;
 u64 id_aa64mmfr2_el1_sys_val;
 u64 id_aa64smfr0_el1_sys_val;
 
-/*
- * Inject an unknown/undefined exception to an AArch64 guest while most of its
- * sysregs are live.
- */
-static void inject_undef64(struct kvm_vcpu *vcpu)
-{
-	u64 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
-
-	*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
-	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
-
-	kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
-
-	__kvm_adjust_pc(vcpu);
-
-	write_sysreg_el1(esr, SYS_ESR);
-	write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
-	write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
-	write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
-}
-
-/*
- * Returns the restricted features values of the feature register based on the
- * limitations in restrict_fields.
- * A feature id field value of 0b0000 does not impose any restrictions.
- * Note: Use only for unsigned feature field values.
- */
-static u64 get_restricted_features_unsigned(u64 sys_reg_val,
-					    u64 restrict_fields)
-{
-	u64 value = 0UL;
-	u64 mask = GENMASK_ULL(ARM64_FEATURE_FIELD_BITS - 1, 0);
+struct pvm_ftr_bits {
+	bool		sign;
+	u8		shift;
+	u8		width;
+	u8		max_val;
+	bool (*vm_supported)(const struct kvm *kvm);
+};
 
-	/*
-	 * According to the Arm Architecture Reference Manual, feature fields
-	 * use increasing values to indicate increases in functionality.
-	 * Iterate over the restricted feature fields and calculate the minimum
-	 * unsigned value between the one supported by the system, and what the
-	 * value is being restricted to.
-	 */
-	while (sys_reg_val && restrict_fields) {
-		value |= min(sys_reg_val & mask, restrict_fields & mask);
-		sys_reg_val &= ~mask;
-		restrict_fields &= ~mask;
-		mask <<= ARM64_FEATURE_FIELD_BITS;
+#define __MAX_FEAT_FUNC(id, fld, max, func, sgn)				\
+	{									\
+		.sign = sgn,							\
+		.shift = id##_##fld##_SHIFT,					\
+		.width = id##_##fld##_WIDTH,					\
+		.max_val = id##_##fld##_##max,					\
+		.vm_supported = func,						\
 	}
 
-	return value;
-}
-
-/*
- * Functions that return the value of feature id registers for protected VMs
- * based on allowed features, system features, and KVM support.
- */
-
-static u64 get_pvm_id_aa64pfr0(const struct kvm_vcpu *vcpu)
-{
-	u64 set_mask = 0;
-	u64 allow_mask = PVM_ID_AA64PFR0_ALLOW;
-
-	set_mask |= get_restricted_features_unsigned(id_aa64pfr0_el1_sys_val,
-		PVM_ID_AA64PFR0_ALLOW);
+#define MAX_FEAT_FUNC(id, fld, max, func)					\
+	__MAX_FEAT_FUNC(id, fld, max, func, id##_##fld##_SIGNED)
 
-	return (id_aa64pfr0_el1_sys_val & allow_mask) | set_mask;
-}
-
-static u64 get_pvm_id_aa64pfr1(const struct kvm_vcpu *vcpu)
-{
-	const struct kvm *kvm = (const struct kvm *)kern_hyp_va(vcpu->kvm);
-	u64 allow_mask = PVM_ID_AA64PFR1_ALLOW;
+#define MAX_FEAT(id, fld, max)							\
+	MAX_FEAT_FUNC(id, fld, max, NULL)
 
-	if (!kvm_has_mte(kvm))
-		allow_mask &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
+#define MAX_FEAT_ENUM(id, fld, max)						\
+	__MAX_FEAT_FUNC(id, fld, max, NULL, false)
 
-	return id_aa64pfr1_el1_sys_val & allow_mask;
-}
+#define FEAT_END {	.width = 0,	}
 
-static u64 get_pvm_id_aa64zfr0(const struct kvm_vcpu *vcpu)
+static bool vm_has_ptrauth(const struct kvm *kvm)
 {
-	/*
-	 * No support for Scalable Vectors, therefore, hyp has no sanitized
-	 * copy of the feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64ZFR0_ALLOW != 0ULL);
-	return 0;
-}
-
-static u64 get_pvm_id_aa64dfr0(const struct kvm_vcpu *vcpu)
-{
-	/*
-	 * No support for debug, including breakpoints, and watchpoints,
-	 * therefore, pKVM has no sanitized copy of the feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64DFR0_ALLOW != 0ULL);
-	return 0;
-}
-
-static u64 get_pvm_id_aa64dfr1(const struct kvm_vcpu *vcpu)
-{
-	/*
-	 * No support for debug, therefore, hyp has no sanitized copy of the
-	 * feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64DFR1_ALLOW != 0ULL);
-	return 0;
-}
+	if (!IS_ENABLED(CONFIG_ARM64_PTR_AUTH))
+		return false;
 
-static u64 get_pvm_id_aa64afr0(const struct kvm_vcpu *vcpu)
-{
-	/*
-	 * No support for implementation defined features, therefore, hyp has no
-	 * sanitized copy of the feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64AFR0_ALLOW != 0ULL);
-	return 0;
+	return (cpus_have_final_cap(ARM64_HAS_ADDRESS_AUTH) ||
+		cpus_have_final_cap(ARM64_HAS_GENERIC_AUTH)) &&
+		kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_PTRAUTH_GENERIC);
 }
 
-static u64 get_pvm_id_aa64afr1(const struct kvm_vcpu *vcpu)
+static bool vm_has_sve(const struct kvm *kvm)
 {
-	/*
-	 * No support for implementation defined features, therefore, hyp has no
-	 * sanitized copy of the feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64AFR1_ALLOW != 0ULL);
-	return 0;
+	return system_supports_sve() && kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_SVE);
 }
 
-static u64 get_pvm_id_aa64isar0(const struct kvm_vcpu *vcpu)
-{
-	return id_aa64isar0_el1_sys_val & PVM_ID_AA64ISAR0_ALLOW;
-}
+/*
+ * Definitions for features to be allowed or restricted for protected guests.
+ *
+ * Each field in the masks represents the highest supported value for the
+ * feature. If a feature field is not present, it is not supported. Moreover,
+ * these are used to generate the guest's view of the feature registers.
+ *
+ * The approach for protected VMs is to at least support features that are:
+ * - Needed by common Linux distributions (e.g., floating point)
+ * - Trivial to support, e.g., supporting the feature does not introduce or
+ * require tracking of additional state in KVM
+ * - Cannot be trapped or prevent the guest from using anyway
+ */
 
-static u64 get_pvm_id_aa64isar1(const struct kvm_vcpu *vcpu)
-{
-	u64 allow_mask = PVM_ID_AA64ISAR1_ALLOW;
+static const struct pvm_ftr_bits pvmid_aa64pfr0[] = {
+	MAX_FEAT(ID_AA64PFR0_EL1, EL0, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, EL1, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, EL2, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, EL3, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, FP, FP16),
+	MAX_FEAT(ID_AA64PFR0_EL1, AdvSIMD, FP16),
+	MAX_FEAT(ID_AA64PFR0_EL1, GIC, IMP),
+	MAX_FEAT_FUNC(ID_AA64PFR0_EL1, SVE, IMP, vm_has_sve),
+	MAX_FEAT(ID_AA64PFR0_EL1, RAS, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, DIT, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, CSV2, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, CSV3, IMP),
+	FEAT_END
+};
 
-	if (!vcpu_has_ptrauth(vcpu))
-		allow_mask &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA) |
-				ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API) |
-				ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA) |
-				ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI));
+static const struct pvm_ftr_bits pvmid_aa64pfr1[] = {
+	MAX_FEAT(ID_AA64PFR1_EL1, BT, IMP),
+	MAX_FEAT(ID_AA64PFR1_EL1, SSBS, SSBS2),
+	MAX_FEAT_ENUM(ID_AA64PFR1_EL1, MTE_frac, NI),
+	FEAT_END
+};
 
-	return id_aa64isar1_el1_sys_val & allow_mask;
-}
+static const struct pvm_ftr_bits pvmid_aa64mmfr0[] = {
+	MAX_FEAT_ENUM(ID_AA64MMFR0_EL1, PARANGE, 40),
+	MAX_FEAT_ENUM(ID_AA64MMFR0_EL1, ASIDBITS, 16),
+	MAX_FEAT(ID_AA64MMFR0_EL1, BIGEND, IMP),
+	MAX_FEAT(ID_AA64MMFR0_EL1, SNSMEM, IMP),
+	MAX_FEAT(ID_AA64MMFR0_EL1, BIGENDEL0, IMP),
+	MAX_FEAT(ID_AA64MMFR0_EL1, EXS, IMP),
+	FEAT_END
+};
 
-static u64 get_pvm_id_aa64isar2(const struct kvm_vcpu *vcpu)
-{
-	u64 allow_mask = PVM_ID_AA64ISAR2_ALLOW;
+static const struct pvm_ftr_bits pvmid_aa64mmfr1[] = {
+	MAX_FEAT(ID_AA64MMFR1_EL1, HAFDBS, DBM),
+	MAX_FEAT_ENUM(ID_AA64MMFR1_EL1, VMIDBits, 16),
+	MAX_FEAT(ID_AA64MMFR1_EL1, HPDS, HPDS2),
+	MAX_FEAT(ID_AA64MMFR1_EL1, PAN, PAN3),
+	MAX_FEAT(ID_AA64MMFR1_EL1, SpecSEI, IMP),
+	MAX_FEAT(ID_AA64MMFR1_EL1, ETS, IMP),
+	MAX_FEAT(ID_AA64MMFR1_EL1, CMOW, IMP),
+	FEAT_END
+};
 
-	if (!vcpu_has_ptrauth(vcpu))
-		allow_mask &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3) |
-				ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3));
+static const struct pvm_ftr_bits pvmid_aa64mmfr2[] = {
+	MAX_FEAT(ID_AA64MMFR2_EL1, CnP, IMP),
+	MAX_FEAT(ID_AA64MMFR2_EL1, UAO, IMP),
+	MAX_FEAT(ID_AA64MMFR2_EL1, IESB, IMP),
+	MAX_FEAT(ID_AA64MMFR2_EL1, AT, IMP),
+	MAX_FEAT_ENUM(ID_AA64MMFR2_EL1, IDS, 0x18),
+	MAX_FEAT(ID_AA64MMFR2_EL1, TTL, IMP),
+	MAX_FEAT(ID_AA64MMFR2_EL1, BBM, 2),
+	MAX_FEAT(ID_AA64MMFR2_EL1, E0PD, IMP),
+	FEAT_END
+};
 
-	return id_aa64isar2_el1_sys_val & allow_mask;
-}
+static const struct pvm_ftr_bits pvmid_aa64isar1[] = {
+	MAX_FEAT(ID_AA64ISAR1_EL1, DPB, DPB2),
+	MAX_FEAT_FUNC(ID_AA64ISAR1_EL1, APA, PAuth, vm_has_ptrauth),
+	MAX_FEAT_FUNC(ID_AA64ISAR1_EL1, API, PAuth, vm_has_ptrauth),
+	MAX_FEAT(ID_AA64ISAR1_EL1, JSCVT, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, FCMA, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, LRCPC, LRCPC3),
+	MAX_FEAT(ID_AA64ISAR1_EL1, GPA, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, GPI, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, FRINTTS, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, SB, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, SPECRES, COSP_RCTX),
+	MAX_FEAT(ID_AA64ISAR1_EL1, BF16, EBF16),
+	MAX_FEAT(ID_AA64ISAR1_EL1, DGH, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, I8MM, IMP),
+	FEAT_END
+};
 
-static u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu)
-{
-	u64 set_mask;
+static const struct pvm_ftr_bits pvmid_aa64isar2[] = {
+	MAX_FEAT_FUNC(ID_AA64ISAR2_EL1, GPA3, IMP, vm_has_ptrauth),
+	MAX_FEAT_FUNC(ID_AA64ISAR2_EL1, APA3, PAuth, vm_has_ptrauth),
+	MAX_FEAT(ID_AA64ISAR2_EL1, ATS1A, IMP),
+	FEAT_END
+};
 
-	set_mask = get_restricted_features_unsigned(id_aa64mmfr0_el1_sys_val,
-		PVM_ID_AA64MMFR0_ALLOW);
+/*
+ * None of the features in ID_AA64DFR0_EL1 nor ID_AA64MMFR4_EL1 are supported.
+ * However, both have Not-Implemented values that are non-zero. Define them
+ * so they can be used when getting the value of these registers.
+ */
+#define ID_AA64DFR0_EL1_NONZERO_NI					\
+(									\
+	SYS_FIELD_PREP_ENUM(ID_AA64DFR0_EL1, DoubleLock, NI)	|	\
+	SYS_FIELD_PREP_ENUM(ID_AA64DFR0_EL1, MTPMU, NI)			\
+)
 
-	return (id_aa64mmfr0_el1_sys_val & PVM_ID_AA64MMFR0_ALLOW) | set_mask;
-}
+#define ID_AA64MMFR4_EL1_NONZERO_NI					\
+	SYS_FIELD_PREP_ENUM(ID_AA64MMFR4_EL1, E2H0, NI)
 
-static u64 get_pvm_id_aa64mmfr1(const struct kvm_vcpu *vcpu)
+/*
+ * Returns the value of the feature registers based on the system register
+ * value, the vcpu support for the revelant features, and the additional
+ * restrictions for protected VMs.
+ */
+static u64 get_restricted_features(const struct kvm_vcpu *vcpu,
+				   u64 sys_reg_val,
+				   const struct pvm_ftr_bits restrictions[])
 {
-	return id_aa64mmfr1_el1_sys_val & PVM_ID_AA64MMFR1_ALLOW;
-}
+	u64 val = 0UL;
+	int i;
+
+	for (i = 0; restrictions[i].width != 0; i++) {
+		bool (*vm_supported)(const struct kvm *) = restrictions[i].vm_supported;
+		bool sign = restrictions[i].sign;
+		int shift = restrictions[i].shift;
+		int width = restrictions[i].width;
+		u64 min_signed = (1UL << width) - 1UL;
+		u64 sign_bit = 1UL << (width - 1);
+		u64 mask = GENMASK_ULL(width + shift - 1, shift);
+		u64 sys_val = (sys_reg_val & mask) >> shift;
+		u64 pvm_max = restrictions[i].max_val;
+
+		if (vm_supported && !vm_supported(vcpu->kvm))
+			val |= (sign ? min_signed : 0) << shift;
+		else if (sign && (sys_val >= sign_bit || pvm_max >= sign_bit))
+			val |= max(sys_val, pvm_max) << shift;
+		else
+			val |= min(sys_val, pvm_max) << shift;
+	}
 
-static u64 get_pvm_id_aa64mmfr2(const struct kvm_vcpu *vcpu)
-{
-	return id_aa64mmfr2_el1_sys_val & PVM_ID_AA64MMFR2_ALLOW;
+	return val;
 }
 
 static u64 pvm_calc_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 {
 	switch (id) {
 	case SYS_ID_AA64PFR0_EL1:
-		return get_pvm_id_aa64pfr0(vcpu);
+		return get_restricted_features(vcpu, id_aa64pfr0_el1_sys_val, pvmid_aa64pfr0);
 	case SYS_ID_AA64PFR1_EL1:
-		return get_pvm_id_aa64pfr1(vcpu);
-	case SYS_ID_AA64ZFR0_EL1:
-		return get_pvm_id_aa64zfr0(vcpu);
-	case SYS_ID_AA64DFR0_EL1:
-		return get_pvm_id_aa64dfr0(vcpu);
-	case SYS_ID_AA64DFR1_EL1:
-		return get_pvm_id_aa64dfr1(vcpu);
-	case SYS_ID_AA64AFR0_EL1:
-		return get_pvm_id_aa64afr0(vcpu);
-	case SYS_ID_AA64AFR1_EL1:
-		return get_pvm_id_aa64afr1(vcpu);
+		return get_restricted_features(vcpu, id_aa64pfr1_el1_sys_val, pvmid_aa64pfr1);
 	case SYS_ID_AA64ISAR0_EL1:
-		return get_pvm_id_aa64isar0(vcpu);
+		return id_aa64isar0_el1_sys_val;
 	case SYS_ID_AA64ISAR1_EL1:
-		return get_pvm_id_aa64isar1(vcpu);
+		return get_restricted_features(vcpu, id_aa64isar1_el1_sys_val, pvmid_aa64isar1);
 	case SYS_ID_AA64ISAR2_EL1:
-		return get_pvm_id_aa64isar2(vcpu);
+		return get_restricted_features(vcpu, id_aa64isar2_el1_sys_val, pvmid_aa64isar2);
 	case SYS_ID_AA64MMFR0_EL1:
-		return get_pvm_id_aa64mmfr0(vcpu);
+		return get_restricted_features(vcpu, id_aa64mmfr0_el1_sys_val, pvmid_aa64mmfr0);
 	case SYS_ID_AA64MMFR1_EL1:
-		return get_pvm_id_aa64mmfr1(vcpu);
+		return get_restricted_features(vcpu, id_aa64mmfr1_el1_sys_val, pvmid_aa64mmfr1);
 	case SYS_ID_AA64MMFR2_EL1:
-		return get_pvm_id_aa64mmfr2(vcpu);
+		return get_restricted_features(vcpu, id_aa64mmfr2_el1_sys_val, pvmid_aa64mmfr2);
+	case SYS_ID_AA64DFR0_EL1:
+		return ID_AA64DFR0_EL1_NONZERO_NI;
+	case SYS_ID_AA64MMFR4_EL1:
+		return ID_AA64MMFR4_EL1_NONZERO_NI;
 	default:
 		/* Unhandled ID register, RAZ */
 		return 0;
 	}
 }
 
-/* Read a sanitized cpufeature ID register by its encoding */
-u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
+/*
+ * Inject an unknown/undefined exception to an AArch64 guest while most of its
+ * sysregs are live.
+ */
+static void inject_undef64(struct kvm_vcpu *vcpu)
 {
-	return pvm_calc_id_reg(vcpu, id);
+	u64 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
+
+	*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
+	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
+
+	kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
+
+	__kvm_adjust_pc(vcpu);
+
+	write_sysreg_el1(esr, SYS_ESR);
+	write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
+	write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
+	write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
 }
 
 static u64 read_id_reg(const struct kvm_vcpu *vcpu,
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:35 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:35 +0000
Subject: [PATCH v4 08/14] KVM: arm64: Remove fixed_config.h header
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-9-tabba@google.com>

The few remaining items needed in fixed_config.h are better
suited for pkvm.h. Move them there and delete it.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h | 206 ------------------
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |   5 +
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |   1 -
 arch/arm64/kvm/hyp/nvhe/setup.c               |   1 -
 arch/arm64/kvm/hyp/nvhe/switch.c              |   1 -
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            |   2 +-
 6 files changed, 6 insertions(+), 210 deletions(-)
 delete mode 100644 arch/arm64/kvm/hyp/include/nvhe/fixed_config.h

diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
deleted file mode 100644
index 37a6d2434e47..000000000000
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2021 Google LLC
- * Author: Fuad Tabba <tabba at google.com>
- */
-
-#ifndef __ARM64_KVM_FIXED_CONFIG_H__
-#define __ARM64_KVM_FIXED_CONFIG_H__
-
-#include <asm/sysreg.h>
-
-/*
- * This file contains definitions for features to be allowed or restricted for
- * guest virtual machines, depending on the mode KVM is running in and on the
- * type of guest that is running.
- *
- * Each field in the masks represents the highest supported *unsigned* value for
- * the feature, if supported by the system.
- *
- * If a feature field is not present in either, than it is not supported.
- *
- * The approach taken for protected VMs is to allow features that are:
- * - Needed by common Linux distributions (e.g., floating point)
- * - Trivial to support, e.g., supporting the feature does not introduce or
- * require tracking of additional state in KVM
- * - Cannot be trapped or prevent the guest from using anyway
- */
-
-/*
- * Allow for protected VMs:
- * - Floating-point and Advanced SIMD
- * - Data Independent Timing
- * - Spectre/Meltdown Mitigation
- *
- * Restrict to the following *unsigned* features for protected VMs:
- * - AArch64 guests only (no support for AArch32 guests):
- *	AArch32 adds complexity in trap handling, emulation, condition codes,
- *	etc...
- * - RAS (v1)
- *	Supported by KVM
- */
-#define PVM_ID_AA64PFR0_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL0, IMP) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL1, IMP) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL2, IMP) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL3, IMP) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, RAS, IMP) \
-	)
-
-/*
- * Allow for protected VMs:
- * - Branch Target Identification
- * - Speculative Store Bypassing
- */
-#define PVM_ID_AA64PFR1_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_BT) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SSBS) \
-	)
-
-#define PVM_ID_AA64PFR2_ALLOW 0ULL
-
-/*
- * Allow for protected VMs:
- * - Mixed-endian
- * - Distinction between Secure and Non-secure Memory
- * - Mixed-endian at EL0 only
- * - Non-context synchronizing exception entry and exit
- *
- * Restrict to the following *unsigned* features for protected VMs:
- * - 40-bit IPA
- * - 16-bit ASID
- */
-#define PVM_ID_AA64MMFR0_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGEND) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_SNSMEM) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGENDEL0) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_PARANGE), ID_AA64MMFR0_EL1_PARANGE_40) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_ASIDBITS), ID_AA64MMFR0_EL1_ASIDBITS_16) \
-	)
-
-/*
- * Allow for protected VMs:
- * - Hardware translation table updates to Access flag and Dirty state
- * - Number of VMID bits from CPU
- * - Hierarchical Permission Disables
- * - Privileged Access Never
- * - SError interrupt exceptions from speculative reads
- * - Enhanced Translation Synchronization
- * - Control for cache maintenance permission
- */
-#define PVM_ID_AA64MMFR1_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_HAFDBS) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_VMIDBits) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_HPDS) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_PAN) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_SpecSEI) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_ETS) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_CMOW) \
-	)
-
-/*
- * Allow for protected VMs:
- * - Common not Private translations
- * - User Access Override
- * - IESB bit in the SCTLR_ELx registers
- * - Unaligned single-copy atomicity and atomic functions
- * - ESR_ELx.EC value on an exception by read access to feature ID space
- * - TTL field in address operations.
- * - Break-before-make sequences when changing translation block size
- * - E0PDx mechanism
- */
-#define PVM_ID_AA64MMFR2_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_CnP) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_UAO) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_IESB) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_AT) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_IDS) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_TTL) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_BBM) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_E0PD) \
-	)
-
-#define PVM_ID_AA64MMFR3_ALLOW (0ULL)
-
-/*
- * No support for Scalable Vectors for protected VMs:
- *	Requires additional support from KVM, e.g., context-switching and
- *	trapping at EL2
- */
-#define PVM_ID_AA64ZFR0_ALLOW (0ULL)
-
-/*
- * No support for debug, including breakpoints, and watchpoints for protected
- * VMs:
- *	The Arm architecture mandates support for at least the Armv8 debug
- *	architecture, which would include at least 2 hardware breakpoints and
- *	watchpoints. Providing that support to protected guests adds
- *	considerable state and complexity. Therefore, the reserved value of 0 is
- *	used for debug-related fields.
- */
-#define PVM_ID_AA64DFR0_ALLOW (0ULL)
-#define PVM_ID_AA64DFR1_ALLOW (0ULL)
-
-/*
- * No support for implementation defined features.
- */
-#define PVM_ID_AA64AFR0_ALLOW (0ULL)
-#define PVM_ID_AA64AFR1_ALLOW (0ULL)
-
-/*
- * No restrictions on instructions implemented in AArch64.
- */
-#define PVM_ID_AA64ISAR0_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_AES) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SHA1) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SHA2) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_CRC32) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_ATOMIC) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_RDM) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SHA3) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SM3) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SM4) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_DP) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_FHM) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_TS) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_TLB) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_RNDR) \
-	)
-
-/* Restrict pointer authentication to the basic version. */
-#define PVM_ID_AA64ISAR1_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DPB) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_JSCVT) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_FCMA) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_LRCPC) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_FRINTTS) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_SB) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_SPECRES) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_BF16) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DGH) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_I8MM) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), ID_AA64ISAR1_EL1_APA_PAuth) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), ID_AA64ISAR1_EL1_API_PAuth) \
-	)
-
-#define PVM_ID_AA64ISAR2_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_ATS1A)| \
-	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_MOPS) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
-	)
-
-bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
-bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
-void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu);
-int kvm_check_pvm_sysreg_table(void);
-
-#endif /* __ARM64_KVM_FIXED_CONFIG_H__ */
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 24a9a8330d19..6ff7cbc33000 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -70,4 +70,9 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 					 unsigned int vcpu_idx);
 void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
 
+bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
+bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
+void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu);
+int kvm_check_pvm_sysreg_table(void);
+
 #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 3b4ea97148b9..ffa500b500f2 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -9,7 +9,6 @@
 
 #include <asm/kvm_emulate.h>
 
-#include <nvhe/fixed_config.h>
 #include <nvhe/mem_protect.h>
 #include <nvhe/memory.h>
 #include <nvhe/pkvm.h>
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index cbdd18cd3f98..31bd729ea45c 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -12,7 +12,6 @@
 
 #include <nvhe/early_alloc.h>
 #include <nvhe/ffa.h>
-#include <nvhe/fixed_config.h>
 #include <nvhe/gfp.h>
 #include <nvhe/memory.h>
 #include <nvhe/mem_protect.h>
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index cc69106734ca..7786a83d0fa8 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -26,7 +26,6 @@
 #include <asm/debug-monitors.h>
 #include <asm/processor.h>
 
-#include <nvhe/fixed_config.h>
 #include <nvhe/mem_protect.h>
 
 /* Non-VHE specific context */
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index b6140590b569..2f2f1ca32b80 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -11,7 +11,7 @@
 
 #include <hyp/adjust_pc.h>
 
-#include <nvhe/fixed_config.h>
+#include <nvhe/pkvm.h>
 
 #include "../../sys_regs.h"
 
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:36 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:36 +0000
Subject: [PATCH v4 09/14] KVM: arm64: Remove redundant setting of HCR_EL2 trap bit
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-10-tabba@google.com>

In hVHE mode, HCR_E2H should be set for both protected and
non-protected VMs. Since commit 23c9d58cb458 ("KVM: arm64: Fix
initializing traps in protected mode"), this has been fixed, and
the setting of the flag here is redundant.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index ffa500b500f2..cede527a59d4 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -57,9 +57,6 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 	/* No support for AArch32. */
 	val |= HCR_RW;
 
-	if (has_hvhe())
-		val |= HCR_E2H;
-
 	/*
 	 * Always trap:
 	 * - Feature id registers: to control features exposed to guests
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:37 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:37 +0000
Subject: [PATCH v4 10/14] KVM: arm64: Calculate cptr_el2 traps on activating traps
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-11-tabba@google.com>

Similar to VHE, calculate the value of cptr_el2 from scratch on
activate traps. This removes the need to store cptr_el2 in every
vcpu structure. Moreover, some traps, such as whether the guest
owns the fp registers, need to be set on every vcpu run.

Reported-by: James Clark <james.clark at linaro.org>
Fixes: 5294afdbf45a ("KVM: arm64: Exclude FP ownership from kvm_vcpu_arch")
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  1 -
 arch/arm64/kvm/arm.c              |  1 -
 arch/arm64/kvm/hyp/nvhe/pkvm.c    | 42 -------------------------
 arch/arm64/kvm/hyp/nvhe/switch.c  | 51 +++++++++++++++++++------------
 4 files changed, 32 insertions(+), 63 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 230b0638f0c2..69cb88c9ce3e 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -708,7 +708,6 @@ struct kvm_vcpu_arch {
 	u64 hcr_el2;
 	u64 hcrx_el2;
 	u64 mdcr_el2;
-	u64 cptr_el2;
 
 	/* Exception Information */
 	struct kvm_vcpu_fault_info fault;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index b295218cdc24..8a3d02cf0a7a 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1546,7 +1546,6 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
 	}
 
 	vcpu_reset_hcr(vcpu);
-	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
 
 	/*
 	 * Handle the "start in power-off" case.
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index cede527a59d4..c8ab3e59f4b1 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -83,44 +83,6 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 	vcpu->arch.hcr_el2 = val;
 }
 
-static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
-{
-	struct kvm *kvm = vcpu->kvm;
-	u64 val = vcpu->arch.cptr_el2;
-
-	if (!has_hvhe()) {
-		val |= CPTR_NVHE_EL2_RES1;
-		val &= ~(CPTR_NVHE_EL2_RES0);
-	}
-
-	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
-		val |= CPTR_EL2_TAM;
-
-	/* SVE can be disabled by userspace even if supported. */
-	if (!vcpu_has_sve(vcpu)) {
-		if (has_hvhe())
-			val &= ~(CPACR_ELx_ZEN);
-		else
-			val |= CPTR_EL2_TZ;
-	}
-
-	/* No SME support in KVM. */
-	BUG_ON(kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP));
-	if (has_hvhe())
-		val &= ~(CPACR_ELx_SMEN);
-	else
-		val |= CPTR_EL2_TSM;
-
-	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP)) {
-		if (has_hvhe())
-			val |= CPACR_EL1_TTA;
-		else
-			val |= CPTR_EL2_TTA;
-	}
-
-	vcpu->arch.cptr_el2 = val;
-}
-
 static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 {
 	struct kvm *kvm = vcpu->kvm;
@@ -191,7 +153,6 @@ static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
 	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
 	int ret;
 
-	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
 	vcpu->arch.mdcr_el2 = 0;
 
 	pkvm_vcpu_reset_hcr(vcpu);
@@ -204,7 +165,6 @@ static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
 		return ret;
 
 	pvm_init_traps_hcr(vcpu);
-	pvm_init_traps_cptr(vcpu);
 	pvm_init_traps_mdcr(vcpu);
 
 	return 0;
@@ -644,8 +604,6 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
 		return ret;
 	}
 
-	hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu);
-
 	return 0;
 }
 
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 7786a83d0fa8..0ebf84a9f9e2 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -35,33 +35,46 @@ DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
 
 extern void kvm_nvhe_prepare_backtrace(unsigned long fp, unsigned long pc);
 
-static void __activate_traps(struct kvm_vcpu *vcpu)
+static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
 {
-	u64 val;
+	u64 val = CPTR_EL2_TAM;	/* Same bit irrespective of E2H */
 
-	___activate_traps(vcpu, vcpu->arch.hcr_el2);
-	__activate_traps_common(vcpu);
+	if (has_hvhe()) {
+		val |= CPACR_ELx_TTA;
 
-	val = vcpu->arch.cptr_el2;
-	val |= CPTR_EL2_TAM;	/* Same bit irrespective of E2H */
-	val |= has_hvhe() ? CPACR_EL1_TTA : CPTR_EL2_TTA;
-	if (cpus_have_final_cap(ARM64_SME)) {
-		if (has_hvhe())
-			val &= ~CPACR_ELx_SMEN;
-		else
-			val |= CPTR_EL2_TSM;
-	}
+		if (guest_owns_fp_regs()) {
+			val |= CPACR_ELx_FPEN;
+			if (vcpu_has_sve(vcpu))
+				val |= CPACR_ELx_ZEN;
+		}
+	} else {
+		val |= CPTR_EL2_TTA | CPTR_NVHE_EL2_RES1;
 
-	if (!guest_owns_fp_regs()) {
-		if (has_hvhe())
-			val &= ~(CPACR_ELx_FPEN | CPACR_ELx_ZEN);
-		else
-			val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
+		/*
+		 * Always trap SME since it's not supported in KVM.
+		 * TSM is RES1 if SME isn't implemented.
+		 */
+		val |= CPTR_EL2_TSM;
 
-		__activate_traps_fpsimd32(vcpu);
+		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
+			val |= CPTR_EL2_TZ;
+
+		if (!guest_owns_fp_regs())
+			val |= CPTR_EL2_TFP;
 	}
 
+	if (!guest_owns_fp_regs())
+		__activate_traps_fpsimd32(vcpu);
+
 	kvm_write_cptr_el2(val);
+}
+
+static void __activate_traps(struct kvm_vcpu *vcpu)
+{
+	___activate_traps(vcpu, vcpu->arch.hcr_el2);
+	__activate_traps_common(vcpu);
+	__activate_cptr_traps(vcpu);
+
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
 
 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:38 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:38 +0000
Subject: [PATCH v4 11/14] KVM: arm64: Refactor kvm_reset_cptr_el2()
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-12-tabba@google.com>

Fold kvm_get_reset_cptr_el2() into kvm_reset_cptr_el2(), since it
is its only caller. Add a comment to clarify that this function
is meant for the host value of cptr_el2.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_emulate.h | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index cf811009a33c..7b3dc52248ce 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -619,7 +619,8 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
 		write_sysreg(val, cptr_el2);
 }
 
-static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
+/* Resets the value of cptr_el2 when returning to the host. */
+static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
 {
 	u64 val;
 
@@ -643,13 +644,6 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
 			val &= ~CPTR_EL2_TSM;
 	}
 
-	return val;
-}
-
-static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
-{
-	u64 val = kvm_get_reset_cptr_el2(vcpu);
-
 	kvm_write_cptr_el2(val);
 }
 
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:39 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:39 +0000
Subject: [PATCH v4 12/14] KVM: arm64: Fix the value of the CPTR_EL2 RES1
 bitmask for nVHE
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-13-tabba@google.com>

Since the introduction of SME, bit 12 in CPTR_EL2 (nVHE) is TSM
for trapping SME, instead of RES1, as per ARM ARM DDI 0487K.a,
section D23.2.34.

Fix the value of CPTR_NVHE_EL2_RES1 to reflect that, and adjust
the code that relies on it accordingly.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_arm.h     | 2 +-
 arch/arm64/include/asm/kvm_emulate.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3e0f0de1d2da..24e4ac7c50f2 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -300,7 +300,7 @@
 #define CPTR_EL2_TSM	(1 << 12)
 #define CPTR_EL2_TFP	(1 << CPTR_EL2_TFP_SHIFT)
 #define CPTR_EL2_TZ	(1 << 8)
-#define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
+#define CPTR_NVHE_EL2_RES1	(BIT(13) | BIT(9) | GENMASK(7, 0))
 #define CPTR_NVHE_EL2_RES0	(GENMASK(63, 32) |	\
 				 GENMASK(29, 21) |	\
 				 GENMASK(19, 14) |	\
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 7b3dc52248ce..6602a4c091ac 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -640,8 +640,8 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
 
 		if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
 			val |= CPTR_EL2_TZ;
-		if (cpus_have_final_cap(ARM64_SME))
-			val &= ~CPTR_EL2_TSM;
+		if (!cpus_have_final_cap(ARM64_SME))
+			val |= CPTR_EL2_TSM;
 	}
 
 	kvm_write_cptr_el2(val);
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:40 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:40 +0000
Subject: [PATCH v4 13/14] KVM: arm64: Remove PtrAuth guest vcpu flag
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-14-tabba@google.com>

The vcpu flag GUEST_HAS_PTRAUTH is always associated with the
vcpu PtrAuth features, which are defined per vm rather than per
vcpu.

Remove the flag, and replace it with checks for the features
instead.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_emulate.h |  5 -----
 arch/arm64/include/asm/kvm_host.h    |  7 +++----
 arch/arm64/kvm/hyp/nvhe/pkvm.c       | 13 -------------
 arch/arm64/kvm/reset.c               |  4 ----
 4 files changed, 3 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 6602a4c091ac..406e99a452bf 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -691,9 +691,4 @@ static inline bool guest_hyp_sve_traps_enabled(const struct kvm_vcpu *vcpu)
 {
 	return __guest_hyp_cptr_xen_trap_enabled(vcpu, ZEN);
 }
-
-static inline void kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
-{
-	vcpu_set_flag(vcpu, GUEST_HAS_PTRAUTH);
-}
 #endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 69cb88c9ce3e..e6be8fe6627a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -866,10 +866,8 @@ struct kvm_vcpu_arch {
 #define GUEST_HAS_SVE		__vcpu_single_flag(cflags, BIT(0))
 /* SVE config completed */
 #define VCPU_SVE_FINALIZED	__vcpu_single_flag(cflags, BIT(1))
-/* PTRAUTH exposed to guest */
-#define GUEST_HAS_PTRAUTH	__vcpu_single_flag(cflags, BIT(2))
 /* KVM_ARM_VCPU_INIT completed */
-#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(3))
+#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(2))
 
 /* Exception pending */
 #define PENDING_EXCEPTION	__vcpu_single_flag(iflags, BIT(0))
@@ -965,7 +963,8 @@ struct kvm_vcpu_arch {
 #define vcpu_has_ptrauth(vcpu)						\
 	((cpus_have_final_cap(ARM64_HAS_ADDRESS_AUTH) ||		\
 	  cpus_have_final_cap(ARM64_HAS_GENERIC_AUTH)) &&		\
-	  vcpu_get_flag(vcpu, GUEST_HAS_PTRAUTH))
+	 (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_ADDRESS) ||       \
+	  vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_GENERIC)))
 #else
 #define vcpu_has_ptrauth(vcpu)		false
 #endif
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index c8ab3e59f4b1..dfd031acde31 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -278,18 +278,6 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 		   allowed_features, KVM_VCPU_MAX_FEATURES);
 }
 
-static void pkvm_vcpu_init_ptrauth(struct pkvm_hyp_vcpu *hyp_vcpu)
-{
-	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
-
-	if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_ADDRESS) ||
-	    vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_GENERIC)) {
-		kvm_vcpu_enable_ptrauth(vcpu);
-	} else {
-		vcpu_clear_flag(&hyp_vcpu->vcpu, GUEST_HAS_PTRAUTH);
-	}
-}
-
 static void unpin_host_vcpu(struct kvm_vcpu *host_vcpu)
 {
 	if (host_vcpu)
@@ -359,7 +347,6 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
 		goto done;
 
 	pkvm_vcpu_init_sve(hyp_vcpu, host_vcpu);
-	pkvm_vcpu_init_ptrauth(hyp_vcpu);
 done:
 	if (ret)
 		unpin_host_vcpu(host_vcpu);
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 470524b31951..1cfab6a5d8a5 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -211,10 +211,6 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 		kvm_vcpu_reset_sve(vcpu);
 	}
 
-	if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_ADDRESS) ||
-	    vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_GENERIC))
-		kvm_vcpu_enable_ptrauth(vcpu);
-
 	if (vcpu_el1_is_32bit(vcpu))
 		pstate = VCPU_RESET_PSTATE_SVC;
 	else if (vcpu_has_nv(vcpu))
-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:41 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:41 +0000
Subject: [PATCH v4 14/14] KVM: arm64: Convert the SVE guest vcpu flag to a vm flag
In-Reply-To: <20241202154742.3611749-1-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
Message-ID: <20241202154742.3611749-15-tabba@google.com>

The vcpu flag GUEST_HAS_SVE is per-vcpu, but it is based on what
is now a per-vm feature. Make the flag per-vm.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_emulate.h | 12 +++++++++---
 arch/arm64/include/asm/kvm_host.h    | 18 ++++++++++++------
 arch/arm64/kvm/hyp/nvhe/pkvm.c       | 11 +++++++----
 arch/arm64/kvm/reset.c               |  2 +-
 4 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 406e99a452bf..2d91fb88298a 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -620,7 +620,7 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
 }
 
 /* Resets the value of cptr_el2 when returning to the host. */
-static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
+static __always_inline void __kvm_reset_cptr_el2(struct kvm *kvm)
 {
 	u64 val;
 
@@ -631,14 +631,14 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
 	} else if (has_hvhe()) {
 		val = CPACR_ELx_FPEN;
 
-		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
+		if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
 			val |= CPACR_ELx_ZEN;
 		if (cpus_have_final_cap(ARM64_SME))
 			val |= CPACR_ELx_SMEN;
 	} else {
 		val = CPTR_NVHE_EL2_RES1;
 
-		if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
+		if (kvm_has_sve(kvm) && guest_owns_fp_regs())
 			val |= CPTR_EL2_TZ;
 		if (!cpus_have_final_cap(ARM64_SME))
 			val |= CPTR_EL2_TSM;
@@ -647,6 +647,12 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
 	kvm_write_cptr_el2(val);
 }
 
+#ifdef __KVM_NVHE_HYPERVISOR__
+#define kvm_reset_cptr_el2(v)	__kvm_reset_cptr_el2(kern_hyp_va((v)->kvm))
+#else
+#define kvm_reset_cptr_el2(v)	__kvm_reset_cptr_el2((v)->kvm)
+#endif
+
 /*
  * Returns a 'sanitised' view of CPTR_EL2, translating from nVHE to the VHE
  * format if E2H isn't set.
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e6be8fe6627a..c834b6768247 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -331,6 +331,8 @@ struct kvm_arch {
 #define KVM_ARCH_FLAG_ID_REGS_INITIALIZED		7
 	/* Fine-Grained UNDEF initialised */
 #define KVM_ARCH_FLAG_FGU_INITIALIZED			8
+	/* SVE exposed to guest */
+#define KVM_ARCH_FLAG_GUEST_HAS_SVE			9
 	unsigned long flags;
 
 	/* VM-wide vCPU feature set */
@@ -862,12 +864,10 @@ struct kvm_vcpu_arch {
 #define vcpu_set_flag(v, ...)	__vcpu_set_flag((v), __VA_ARGS__)
 #define vcpu_clear_flag(v, ...)	__vcpu_clear_flag((v), __VA_ARGS__)
 
-/* SVE exposed to guest */
-#define GUEST_HAS_SVE		__vcpu_single_flag(cflags, BIT(0))
+/* KVM_ARM_VCPU_INIT completed */
+#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(0))
 /* SVE config completed */
 #define VCPU_SVE_FINALIZED	__vcpu_single_flag(cflags, BIT(1))
-/* KVM_ARM_VCPU_INIT completed */
-#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(2))
 
 /* Exception pending */
 #define PENDING_EXCEPTION	__vcpu_single_flag(iflags, BIT(0))
@@ -956,8 +956,14 @@ struct kvm_vcpu_arch {
 				 KVM_GUESTDBG_USE_HW | \
 				 KVM_GUESTDBG_SINGLESTEP)
 
-#define vcpu_has_sve(vcpu) (system_supports_sve() &&			\
-			    vcpu_get_flag(vcpu, GUEST_HAS_SVE))
+#define kvm_has_sve(kvm)	(system_supports_sve() &&		\
+				 test_bit(KVM_ARCH_FLAG_GUEST_HAS_SVE, &(kvm)->arch.flags))
+
+#ifdef __KVM_NVHE_HYPERVISOR__
+#define vcpu_has_sve(vcpu)	kvm_has_sve(kern_hyp_va((vcpu)->kvm))
+#else
+#define vcpu_has_sve(vcpu)	kvm_has_sve((vcpu)->kvm)
+#endif
 
 #ifdef CONFIG_ARM64_PTR_AUTH
 #define vcpu_has_ptrauth(vcpu)						\
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index dfd031acde31..8a80e494f20c 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -248,10 +248,13 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
 {
 	struct kvm *kvm = &hyp_vm->kvm;
+	unsigned long host_arch_flags = READ_ONCE(host_kvm->arch.flags);
 	DECLARE_BITMAP(allowed_features, KVM_VCPU_MAX_FEATURES);
 
 	/* No restrictions for non-protected VMs. */
 	if (!kvm_vm_is_protected(kvm)) {
+		hyp_vm->kvm.arch.flags = host_arch_flags;
+
 		bitmap_copy(kvm->arch.vcpu_features,
 			    host_kvm->arch.vcpu_features,
 			    KVM_VCPU_MAX_FEATURES);
@@ -271,8 +274,10 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_GENERIC))
 		set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
 
-	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE))
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE)) {
 		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
+		kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_GUEST_HAS_SVE);
+	}
 
 	bitmap_and(kvm->arch.vcpu_features, host_kvm->arch.vcpu_features,
 		   allowed_features, KVM_VCPU_MAX_FEATURES);
@@ -308,10 +313,8 @@ static void pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *
 {
 	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
 
-	if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) {
-		vcpu_clear_flag(vcpu, GUEST_HAS_SVE);
+	if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE))
 		vcpu_clear_flag(vcpu, VCPU_SVE_FINALIZED);
-	}
 }
 
 static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 1cfab6a5d8a5..803e11b0dc8f 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -85,7 +85,7 @@ static void kvm_vcpu_enable_sve(struct kvm_vcpu *vcpu)
 	 * KVM_REG_ARM64_SVE_VLS.  Allocation is deferred until
 	 * kvm_arm_vcpu_finalize(), which freezes the configuration.
 	 */
-	vcpu_set_flag(vcpu, GUEST_HAS_SVE);
+	set_bit(KVM_ARCH_FLAG_GUEST_HAS_SVE, &vcpu->kvm->arch.flags);
 }
 
 /*
-- 
2.47.0.338.g60cca15819-goog



From thorsten.blum at linux.dev  Mon Dec  2 07:48:39 2024
From: thorsten.blum at linux.dev (Thorsten Blum)
Date: Mon,  2 Dec 2024 16:48:39 +0100
Subject: [PATCH] arm/pgtable: Remove duplicate included header file
Message-ID: <20241202154840.1343-2-thorsten.blum@linux.dev>

The header file asm-generic/pgtable-nopud.h is included whether
CONFIG_MMU is defined or not.

Include it only once before the #ifndef/#else/#endif preprocessor
directives and remove the following make includecheck warning:

  asm-generic/pgtable-nopud.h is included more than once

Signed-off-by: Thorsten Blum <thorsten.blum at linux.dev>
---
 arch/arm/include/asm/pgtable.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index be91e376df79..6b986ef6042f 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -19,14 +19,13 @@ extern struct page *empty_zero_page;
 #define ZERO_PAGE(vaddr)	(empty_zero_page)
 #endif
 
-#ifndef CONFIG_MMU
-
 #include <asm-generic/pgtable-nopud.h>
+
+#ifndef CONFIG_MMU
 #include <asm/pgtable-nommu.h>
 
 #else
 
-#include <asm-generic/pgtable-nopud.h>
 #include <asm/page.h>
 #include <asm/pgtable-hwdef.h>
 
-- 
2.47.0



From andersson at kernel.org  Mon Dec  2 07:51:01 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon,  2 Dec 2024 09:51:01 -0600
Subject: [PATCH v3] arm64: dts: qcom: Add coresight nodes for QCS615
In-Reply-To: <20241106094510.2654998-1-quic_jiegan@quicinc.com>
References: <20241106094510.2654998-1-quic_jiegan@quicinc.com>
Message-ID: <173315466531.263019.7584568403904604417.b4-ty@kernel.org>


On Wed, 06 Nov 2024 17:45:09 +0800, Jie Gan wrote:
> Add following coresight components on QCS615, EUD, TMC/ETF, TPDM, dynamic
> Funnel, TPDA, Replicator and ETM.
> 
> 

Applied, thanks!

[1/1] arm64: dts: qcom: Add coresight nodes for QCS615
      commit: bf469630552a3950d0370dd5fd1f9bf0145d09d5

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From andersson at kernel.org  Mon Dec  2 07:51:03 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon,  2 Dec 2024 09:51:03 -0600
Subject: (subset) [PATCH v5 0/5] Add initial support for QCS615 SoC and QCS615 RIDE board
In-Reply-To: <20241104-add_initial_support_for_qcs615-v5-0-9dde8d7b80b0@quicinc.com>
References: <20241104-add_initial_support_for_qcs615-v5-0-9dde8d7b80b0@quicinc.com>
Message-ID: <173315466527.263019.11318467939121751784.b4-ty@kernel.org>


On Mon, 04 Nov 2024 17:10:07 +0800, Lijuan Gao wrote:
> Introduces the Device Tree for the QCS615 platform.
> 
> Features added and enabled:
> - CPUs with PSCI idle states
> - Interrupt-controller with PDC wakeup support
> - Timers, TCSR Clock Controllers
> - Reserved Shared memory
> - QFPROM
> - TLMM
> - Watchdog
> - RPMH controller
> - Sleep stats driver
> - Rpmhpd power controller
> - Interconnect
> - GCC and Rpmhcc
> - QUP with Uart serial support
> 
> [...]

Applied, thanks!

[5/5] arm64: defconfig: enable clock controller, interconnect and pinctrl for QCS615
      commit: 9eec6ce36b5dc981327e9f58025d012e524687b4

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From maz at kernel.org  Mon Dec  2 07:53:59 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Dec 2024 15:53:59 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP
In-Reply-To: <20241202153618.GA6834@willie-the-truck>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
	<20241202153618.GA6834@willie-the-truck>
Message-ID: <86ttbmt71k.wl-maz@kernel.org>

On Mon, 02 Dec 2024 15:36:19 +0000,
Will Deacon <will at kernel.org> wrote:
> 
> [+ usual suspects]
> 
> On Mon, Dec 02, 2024 at 07:58:30AM +0300, Vitaly Chikunov wrote:
> > v6.13-rc1 exhibits a boot failure on aarch64 under KVM. (QEMU 9.1.1, CPU
> > Kunpeng-920). Boot log:
> 
> I've not tried to repro this locally, but from the log:
> 
> > + time qemu-system-aarch64 -M accel=kvm:tcg -smp cores=8 -m 4096 -serial mon:stdio -nodefaults -nographic -no-reboot -fsdev local,id=root,path=/,security_model=none,multidevs=remap -device virtio-9p-pci,fsdev=root,mount_tag=virtio-9p:/ -device virtio-rng-pci -kernel /usr/src/tmp/kernel-image-6.13-buildroot/boot/vmlinuz-6.13.0-6.13-alt0.rc1 -initrd /usr/src/tmp/initramfs-6.13.0-6.13-alt0.rc1.img -sandbox on,spawn=deny -M virt,gic-version=3 -cpu max -append 'console=ttyAMA0 mitigations=off nokaslr  panic=-1 SCRIPT=/usr/src/tmp/vm.SchsIm2FjB earlycon earlyprintk=serial ignore_loglevel debug rddebug'
> > [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x481fd010]
> > [    0.000000] Linux version 6.13.0-6.13-alt0.rc1 (builder at localhost.localdomain) (gcc-14 (GCC) 14.2.1 20241028 (ALT Sisyphus 14.2.1-alt1), GNU ld (GNU Binutils) 2.43.1.20241025) #1 SMP PREEMPT_DYNAMIC Mon Dec  2 03:33:29 UTC 2024
> > [    0.000000] KASLR disabled on command line
> > [    0.000000] random: crng init done
> > [    0.000000] Machine model: linux,dummy-virt
> > [    0.000000] printk: debug: ignoring loglevel setting.
> > [    0.000000] efi: UEFI not found.
> > [    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '')
> > [    0.000000] printk: legacy bootconsole [pl11] enabled
> > [    0.000000] OF: reserved mem: Reserved memory: No reserved-memory node in the DT
> > [    0.000000] NUMA: Faking a node at [mem 0x0000000040000000-0x000000013fffffff]
> > [    0.000000] NODE_DATA(0) allocated [mem 0x13f7f3540-0x13f7f947f]
> > [    0.000000] Zone ranges:
> > [    0.000000]   DMA      [mem 0x0000000040000000-0x00000000ffffffff]
> > [    0.000000]   DMA32    empty
> > [    0.000000]   Normal   [mem 0x0000000100000000-0x000000013fffffff]
> > [    0.000000] Movable zone start for each node
> > [    0.000000] Early memory node ranges
> > [    0.000000]   node   0: [mem 0x0000000040000000-0x000000013fffffff]
> > [    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000013fffffff]
> > [    0.000000] cma: Reserved 256 MiB at 0x00000000f0000000 on node -1
> > [    0.000000] psci: probing for conduit method from DT.
> > [    0.000000] psci: PSCIv1.1 detected in firmware.
> > [    0.000000] psci: Using standard PSCI v0.2 function IDs
> > [    0.000000] psci: Trusted OS migration not required
> > [    0.000000] psci: SMC Calling Convention v1.1
> > [    0.000000] smccc: KVM: hypervisor services detected (0x00000000 0x00000000 0x00000000 0x00000003)
> > [    0.000000] percpu: Embedded 34 pages/cpu s100632 r8192 d30440 u139264
> > [    0.000000] pcpu-alloc: s100632 r8192 d30440 u139264 alloc=34*4096
> > [    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7
> > [    0.000000] Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP
> 
> We take an undefined instruction exception in the kernel early during
> boot...
> 
> > [    0.000000] Modules linked in:
> > [    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.13.0-6.13-alt0.rc1 #1
> > [    0.000000] Hardware name: linux,dummy-virt (DT)
> > [    0.000000] pstate: 004000c5 (nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > [    0.000000] pc : __cpuinfo_store_cpu+0xe8/0x240
> > [    0.000000] lr : cpuinfo_store_boot_cpu+0x34/0x88
> > [    0.000000] sp : ffff800082013df0
> > [    0.000000] x29: ffff800082013df0 x28: 000000000000008e x27: ffff800081e38128
> > [    0.000000] x26: ffff800081702190 x25: ffff80008201f040 x24: ffff0000ff7d1d00
> > [    0.000000] x23: ffff80008201ec00 x22: ffff800081e39100 x21: ffff8000816f9750
> > [    0.000000] x20: ffff800081f55280 x19: ffff0000ff6be2e0 x18: 0000000000000000
> > [    0.000000] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> > [    0.000000] x14: 000000000000002f x13: 000000013f7f9490 x12: 0000008000000000
> > [    0.000000] x11: 0000000000000000 x10: 00000000007f8000 x9 : 000000013f808000
> > [    0.000000] x8 : 0000000000000000 x7 : 0000000000000000 x6 : 000000013f7f94c0
> > [    0.000000] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 1100010011111111
> > [    0.000000] x2 : 0000000000000001 x1 : 0000000084448004 x0 : ffff0000ff6be2e0
> > [    0.000000] Call trace:
> > [    0.000000]  __cpuinfo_store_cpu+0xe8/0x240 (P)
> > [    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88 (L)
> > [    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88
> > [    0.000000]  smp_prepare_boot_cpu+0x30/0x58
> > [    0.000000]  start_kernel+0x514/0x9d0
> > [    0.000000]  __primary_switched+0x88/0x98
> > [    0.000000] Code: f100085f 54000600 f2580c7f 54000060 (d538a482)
> 
> ... and that's:
> 
>    0:	f100085f 	cmp	x2, #0x2
>    4:	54000600 	b.eq	0xc4  // b.none
>    8:	f2580c7f 	tst	x3, #0xf0000000000
>    c:	54000060 	b.eq	0x18  // b.none
>   10:*	d538a482 	mrs	x2, s3_0_c10_c4_4		<-- trapping instruction
> 
> Which I think corresponds to a read of MPAMIDR_EL1.
> 
> It looks like James routed accesses to this register to undef_access()
> in 31ff96c38ea3 ("KVM: arm64: Fix missing traps of guest accesses to the
> MPAM register") so I'm not really sure how this is supposed to work
> given that it's an ID register.

It's not. Or rather, it is an IDREG that is only valid when MPAM is
advertised and implemented. From the spec:

"This register is present only when FEAT_MPAM is implemented.
Otherwise, direct accesses to MPAMIDR_EL1 are UNDEFINED."

So from a KVM perspective, I think this is doing the right thing.

What the log doesn't say is what the host is. Is it 6.13-rc1 as well?

Thanks,

	M.

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


From suzuki.poulose at arm.com  Mon Dec  2 07:54:02 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 2 Dec 2024 15:54:02 +0000
Subject: [PATCH 2/2] MAINTAINERS: Add CCA and pKVM CoCO guest support to
 the ARM64 entry
In-Reply-To: <20241202145731.6422-3-will@kernel.org>
References: <20241202145731.6422-1-will@kernel.org>
 <20241202145731.6422-3-will@kernel.org>
Message-ID: <932062a6-1d77-44f8-9efd-25f2eae34891@arm.com>

On 02/12/2024 14:57, Will Deacon wrote:
> Commits 7999edc484ca ("virt: arm-cca-guest: TSM_REPORT support for
> realm") and a06c3fad49a5 ("drivers/virt: pkvm: Add initial support for
> running as a protected guest") added arm64 guest-side support for
> running in CCA and pKVM confidential computing environments
> respectively.
> 
> Unfortunately, these changes were not accompanied by a MAINTAINERS
> entry and so aren't automatically picked up by the get_maintainer.pl
> script. Since the initial support was merged via the arm64 tree, extend
> the ARM64 entry to cover the two new directories.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oliver.upton at linux.dev>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Will Deacon <will at kernel.org>
> ---
>   MAINTAINERS | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1e930c7a58b1..9378c0c4bbc9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3376,6 +3376,8 @@ S:	Maintained
>   T:	git git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
>   F:	Documentation/arch/arm64/
>   F:	arch/arm64/
> +F:	drivers/virt/coco/arm-cca-guest/
> +F:	drivers/virt/coco/pkvm-guest/
>   F:	tools/testing/selftests/arm64/
>   X:	arch/arm64/boot/dts/
>   


FWIW,

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



From krzk at kernel.org  Mon Dec  2 07:54:59 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 16:54:59 +0100
Subject: [PATCHv2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable ACSPCIE
 output for PCIe1
In-Reply-To: <rjecpmr4bsedbfhu74sdlzmdz2mh2shsr5myawb3qveooawa3j@i2ysnnyf7hio>
References: <20241202101140.48778-1-romain.naour@smile.fr>
 <dabbad2b-f8a6-4ed7-86da-ec696cf67461@kernel.org>
 <k7udgqugqseweckb7hjniz3aops4kn35ttju2ju7f2pcbmndrg@dau5nr4leish>
 <abeb632b-9efc-48e5-a28a-a9d7c02e0a6e@kernel.org>
 <cndc3fopwhwkotfikul2jtzfczpdpwlrs5uhuqq76ck36ndtfs@gvxavxt5tgd5>
 <f332947a-d7b5-4f68-84d8-3ecce118c24c@kernel.org>
 <rjecpmr4bsedbfhu74sdlzmdz2mh2shsr5myawb3qveooawa3j@i2ysnnyf7hio>
Message-ID: <1bfdf1f1-7542-4149-a85d-2ac4b659b26b@kernel.org>

On 02/12/2024 16:45, Siddharth Vadapalli wrote:
>>> the feature to be enabled/disabled via the ACSPCIE block are the same as
>>> well i.e. "register layout can be inferred". The same goes for the
>>> compatibles listed below in my previous reply i.e. they aren't bugs.
>>> Same IP and integration across SoCs and hence reused in the sense of
>>> Hardware and not Software. I hope this clarifies the rationale for the
>>> "reuse".
>>
>>
>> You mix re-use with fallback. These are almost never the same blocks,
>> which you imply here.
> 
> I know that the IP is the same, the bits are the same and those bits enable
> the same functionality of the IP across the SoCs. If you still insist that
> they are not same, I don't know what to say anymore.


You can say what we have been saying on mailing lists all the time:
hardware datasheets lie and sometimes you find one, tiny tiny
difference. If you are uncertain, please consult your SoC maintainer on
this matter.

Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec  2 07:58:44 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 16:58:44 +0100
Subject: [PATCH v2 11/18] arm64: dts: mediatek: mt7988: add chosen node on
 bpi-r4
In-Reply-To: <D92CAF3C-F6B7-46DC-BF83-A71907E2D7EA@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-12-linux@fw-web.de>
 <0fb58a4a-7bad-4623-99c8-67f5763558bb@kernel.org>
 <D92CAF3C-F6B7-46DC-BF83-A71907E2D7EA@fw-web.de>
Message-ID: <e1343cc5-d5e8-40d6-a6f1-3eaf22a8cd6d@kernel.org>

On 02/12/2024 15:29, Frank Wunderlich wrote:
> Am 2. Dezember 2024 14:46:24 MEZ schrieb Krzysztof Kozlowski <krzk at kernel.org>:
>> On 02/12/2024 13:25, Frank Wunderlich wrote:
>>> From: Frank Wunderlich <frank-w at public-files.de>
>>>
>>> Add chosen node on Bananapi R4 board with stdout and default bootargs.
>>>
>>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>>> ---
>>>  arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 5 +++++
>>>  1 file changed, 5 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>>> index 9037f35857a9..1c2a806f6f6c 100644
>>> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>>> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>>> @@ -9,6 +9,11 @@ / {
>>>  	model = "Banana Pi BPI-R4";
>>>  	chassis-type = "embedded";
>>>  
>>> +	chosen {
>>> +		stdout-path = &serial0;
>>> +		bootargs = "console=ttyS0,115200n1";
>>
>> Drop or merge into stdout path.
> 
> Have you an example to pass speed setting to stdout-path? As it is only a phandle it is not clear to me how to merge these 2...
It is really trivial to find, considering that 66% of files have it.

git grep stdout

Best regards,
Krzysztof


From vt at altlinux.org  Mon Dec  2 07:59:40 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Mon, 2 Dec 2024 18:59:40 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <86ttbmt71k.wl-maz@kernel.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
Message-ID: <20241202155940.p267a3tz5ypj4sog@altlinux.org>

Marc,

On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> On Mon, 02 Dec 2024 15:36:19 +0000,
> Will Deacon <will at kernel.org> wrote:
> > 
> > [+ usual suspects]
> > 
> > On Mon, Dec 02, 2024 at 07:58:30AM +0300, Vitaly Chikunov wrote:
> > > v6.13-rc1 exhibits a boot failure on aarch64 under KVM. (QEMU 9.1.1, CPU
> > > Kunpeng-920). Boot log:
> > 
> > I've not tried to repro this locally, but from the log:
> > 
> > > + time qemu-system-aarch64 -M accel=kvm:tcg -smp cores=8 -m 4096 -serial mon:stdio -nodefaults -nographic -no-reboot -fsdev local,id=root,path=/,security_model=none,multidevs=remap -device virtio-9p-pci,fsdev=root,mount_tag=virtio-9p:/ -device virtio-rng-pci -kernel /usr/src/tmp/kernel-image-6.13-buildroot/boot/vmlinuz-6.13.0-6.13-alt0.rc1 -initrd /usr/src/tmp/initramfs-6.13.0-6.13-alt0.rc1.img -sandbox on,spawn=deny -M virt,gic-version=3 -cpu max -append 'console=ttyAMA0 mitigations=off nokaslr  panic=-1 SCRIPT=/usr/src/tmp/vm.SchsIm2FjB earlycon earlyprintk=serial ignore_loglevel debug rddebug'
> > > [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x481fd010]
> > > [    0.000000] Linux version 6.13.0-6.13-alt0.rc1 (builder at localhost.localdomain) (gcc-14 (GCC) 14.2.1 20241028 (ALT Sisyphus 14.2.1-alt1), GNU ld (GNU Binutils) 2.43.1.20241025) #1 SMP PREEMPT_DYNAMIC Mon Dec  2 03:33:29 UTC 2024
> > > [    0.000000] KASLR disabled on command line
> > > [    0.000000] random: crng init done
> > > [    0.000000] Machine model: linux,dummy-virt
> > > [    0.000000] printk: debug: ignoring loglevel setting.
> > > [    0.000000] efi: UEFI not found.
> > > [    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '')
> > > [    0.000000] printk: legacy bootconsole [pl11] enabled
> > > [    0.000000] OF: reserved mem: Reserved memory: No reserved-memory node in the DT
> > > [    0.000000] NUMA: Faking a node at [mem 0x0000000040000000-0x000000013fffffff]
> > > [    0.000000] NODE_DATA(0) allocated [mem 0x13f7f3540-0x13f7f947f]
> > > [    0.000000] Zone ranges:
> > > [    0.000000]   DMA      [mem 0x0000000040000000-0x00000000ffffffff]
> > > [    0.000000]   DMA32    empty
> > > [    0.000000]   Normal   [mem 0x0000000100000000-0x000000013fffffff]
> > > [    0.000000] Movable zone start for each node
> > > [    0.000000] Early memory node ranges
> > > [    0.000000]   node   0: [mem 0x0000000040000000-0x000000013fffffff]
> > > [    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000013fffffff]
> > > [    0.000000] cma: Reserved 256 MiB at 0x00000000f0000000 on node -1
> > > [    0.000000] psci: probing for conduit method from DT.
> > > [    0.000000] psci: PSCIv1.1 detected in firmware.
> > > [    0.000000] psci: Using standard PSCI v0.2 function IDs
> > > [    0.000000] psci: Trusted OS migration not required
> > > [    0.000000] psci: SMC Calling Convention v1.1
> > > [    0.000000] smccc: KVM: hypervisor services detected (0x00000000 0x00000000 0x00000000 0x00000003)
> > > [    0.000000] percpu: Embedded 34 pages/cpu s100632 r8192 d30440 u139264
> > > [    0.000000] pcpu-alloc: s100632 r8192 d30440 u139264 alloc=34*4096
> > > [    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7
> > > [    0.000000] Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP
> > 
> > We take an undefined instruction exception in the kernel early during
> > boot...
> > 
> > > [    0.000000] Modules linked in:
> > > [    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.13.0-6.13-alt0.rc1 #1
> > > [    0.000000] Hardware name: linux,dummy-virt (DT)
> > > [    0.000000] pstate: 004000c5 (nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > > [    0.000000] pc : __cpuinfo_store_cpu+0xe8/0x240
> > > [    0.000000] lr : cpuinfo_store_boot_cpu+0x34/0x88
> > > [    0.000000] sp : ffff800082013df0
> > > [    0.000000] x29: ffff800082013df0 x28: 000000000000008e x27: ffff800081e38128
> > > [    0.000000] x26: ffff800081702190 x25: ffff80008201f040 x24: ffff0000ff7d1d00
> > > [    0.000000] x23: ffff80008201ec00 x22: ffff800081e39100 x21: ffff8000816f9750
> > > [    0.000000] x20: ffff800081f55280 x19: ffff0000ff6be2e0 x18: 0000000000000000
> > > [    0.000000] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> > > [    0.000000] x14: 000000000000002f x13: 000000013f7f9490 x12: 0000008000000000
> > > [    0.000000] x11: 0000000000000000 x10: 00000000007f8000 x9 : 000000013f808000
> > > [    0.000000] x8 : 0000000000000000 x7 : 0000000000000000 x6 : 000000013f7f94c0
> > > [    0.000000] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 1100010011111111
> > > [    0.000000] x2 : 0000000000000001 x1 : 0000000084448004 x0 : ffff0000ff6be2e0
> > > [    0.000000] Call trace:
> > > [    0.000000]  __cpuinfo_store_cpu+0xe8/0x240 (P)
> > > [    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88 (L)
> > > [    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88
> > > [    0.000000]  smp_prepare_boot_cpu+0x30/0x58
> > > [    0.000000]  start_kernel+0x514/0x9d0
> > > [    0.000000]  __primary_switched+0x88/0x98
> > > [    0.000000] Code: f100085f 54000600 f2580c7f 54000060 (d538a482)
> > 
> > ... and that's:
> > 
> >    0:	f100085f 	cmp	x2, #0x2
> >    4:	54000600 	b.eq	0xc4  // b.none
> >    8:	f2580c7f 	tst	x3, #0xf0000000000
> >    c:	54000060 	b.eq	0x18  // b.none
> >   10:*	d538a482 	mrs	x2, s3_0_c10_c4_4		<-- trapping instruction
> > 
> > Which I think corresponds to a read of MPAMIDR_EL1.
> > 
> > It looks like James routed accesses to this register to undef_access()
> > in 31ff96c38ea3 ("KVM: arm64: Fix missing traps of guest accesses to the
> > MPAM register") so I'm not really sure how this is supposed to work
> > given that it's an ID register.
> 
> It's not. Or rather, it is an IDREG that is only valid when MPAM is
> advertised and implemented. From the spec:
> 
> "This register is present only when FEAT_MPAM is implemented.
> Otherwise, direct accesses to MPAMIDR_EL1 are UNDEFINED."
> 
> So from a KVM perspective, I think this is doing the right thing.
> 
> What the log doesn't say is what the host is. Is it 6.13-rc1 as well?

No, host is 6.6.60.

Thanks,

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


From umer.uddin at mentallysanemainliners.org  Mon Dec  2 08:00:11 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  2 Dec 2024 16:00:11 +0000
Subject: [PATCH v3 3/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
In-Reply-To: <88f6ab28-1b3f-4144-91c8-0131ee008838@kernel.org>
References: <88f6ab28-1b3f-4144-91c8-0131ee008838@kernel.org>
Message-ID: <20241202160011.3232-1-umer.uddin@mentallysanemainliners.org>

On 02/12/2024 8:53, Krzysztof Kozlowski wrote:

> Umer,
>
> I wanted to apply the series, but for two weeks you ignored this
> feedback/comment, so I am dropping the patchset from my queue.
>
> Be sure you respond to reviewers in timely manner (and if you give
> yourself more than two weeks to respond it also means other have more
> than two weeks...).
>
> Best regards,
> Krzysztof

Hi Krzysztof, I did not mean to ignore him, I had mock examinations coming
up when this feedback was sent. I had no chance to reply as i had to prepare
and do good in these examinations as they influence what colleges I get
accepted at. Sorry for any inconvenience caused to both of you.

Best regards,
Umer


From linux.amoon at gmail.com  Mon Dec  2 08:01:26 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon, 2 Dec 2024 21:31:26 +0530
Subject: [PATCH v3 0/6] RK3399: PCie Phy using new helper function
In-Reply-To: <20241012071919.3726-1-linux.amoon@gmail.com>
References: <20241012071919.3726-1-linux.amoon@gmail.com>
Message-ID: <CANAwSgSusXfr73LNySLJVnYPDNsyYmK_=2+YXAwm6bLE+NsWdQ@mail.gmail.com>

Hi All,

On Sat, 12 Oct 2024 at 12:49, Anand Moon <linux.amoon at gmail.com> wrote:
>
> Few clean of the phy change and Using guard notation makes the code
> more compact and error handling for mutex_lock/mutex_unlock.
>
> Plz review te code changes, I tend to do silly mistake.
>
> v1:
> [1] https://lore.kernel.org/all/20240901183221.240361-5-linux.amoon at gmail.com/
> v2: Fix some typo in the subjects.
> [2] https://lore.kernel.org/all/20241006182445.3713-1-linux.amoon at gmail.com/
>

Do you have any device comments on these code changes?

> Thanks
> -Anand
>
Thank
-Anand

> Anand Moon (6):
>   phy: rockchip-pcie: Simplify error handling with dev_err_probe()
>   phy: rockchip-pcie: Use devm_clk_get_enabled() helper
>   phy: rockchip-pcie: Use regmap_read_poll_timeout() for PCIe reference
>     clk PLL status
>   phy: rockchip-pcie: Refactor mutex handling in
>     rockchip_pcie_phy_power_off()
>   phy: rockchip-pcie: Refactor mutex handling in
>     rockchip_pcie_phy_power_on()
>   phy: rockchip-pcie: Use guard notation when acquiring mutex
>
>  drivers/phy/rockchip/phy-rockchip-pcie.c | 148 +++++++----------------
>  1 file changed, 47 insertions(+), 101 deletions(-)
>
>
> base-commit: 09f6b0c8904bfaa1e0601bc102e1b6aa6de8c98f
> --
> 2.44.0
>


From krzk at kernel.org  Mon Dec  2 08:03:07 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 2 Dec 2024 17:03:07 +0100
Subject: [PATCH v3 3/4] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S20 5G (x1s)
In-Reply-To: <20241202160011.3232-1-umer.uddin@mentallysanemainliners.org>
References: <88f6ab28-1b3f-4144-91c8-0131ee008838@kernel.org>
 <20241202160011.3232-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <a3a4296d-8a0b-4894-b979-00f3e8f8a75a@kernel.org>

On 02/12/2024 17:00, Umer Uddin wrote:
> On 02/12/2024 8:53, Krzysztof Kozlowski wrote:
> 
>> Umer,
>>
>> I wanted to apply the series, but for two weeks you ignored this
>> feedback/comment, so I am dropping the patchset from my queue.
>>
>> Be sure you respond to reviewers in timely manner (and if you give
>> yourself more than two weeks to respond it also means other have more
>> than two weeks...).
>>
>> Best regards,
>> Krzysztof
> 
> Hi Krzysztof, I did not mean to ignore him, I had mock examinations coming
> up when this feedback was sent. I had no chance to reply as i had to prepare
> and do good in these examinations as they influence what colleges I get
> accepted at. Sorry for any inconvenience caused to both of you.

I understand. No problem on my side, just wanted to share the reason of
dropping from my queue. After resolving the discussion somehow, please
send a new version (if something changed) or resend (if resolution
results in no changes).


Best regards,
Krzysztof


From catalin.marinas at arm.com  Mon Dec  2 08:05:08 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Dec 2024 16:05:08 +0000
Subject: [PATCH 2/2] MAINTAINERS: Add CCA and pKVM CoCO guest support to
 the ARM64 entry
In-Reply-To: <20241202145731.6422-3-will@kernel.org>
References: <20241202145731.6422-1-will@kernel.org>
 <20241202145731.6422-3-will@kernel.org>
Message-ID: <Z03atBO7Q18AVepI@arm.com>

On Mon, Dec 02, 2024 at 02:57:30PM +0000, Will Deacon wrote:
> Commits 7999edc484ca ("virt: arm-cca-guest: TSM_REPORT support for
> realm") and a06c3fad49a5 ("drivers/virt: pkvm: Add initial support for
> running as a protected guest") added arm64 guest-side support for
> running in CCA and pKVM confidential computing environments
> respectively.
> 
> Unfortunately, these changes were not accompanied by a MAINTAINERS
> entry and so aren't automatically picked up by the get_maintainer.pl
> script. Since the initial support was merged via the arm64 tree, extend
> the ARM64 entry to cover the two new directories.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oliver.upton at linux.dev>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Will Deacon <will at kernel.org>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From yang at os.amperecomputing.com  Mon Dec  2 08:05:44 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Mon, 2 Dec 2024 08:05:44 -0800
Subject: [GIT PULL] arm64 updates for 6.13-rc1
In-Reply-To: <Z0h6Qtleb-znhX3u@arm.com>
References: <20241118100623.2674026-1-catalin.marinas@arm.com>
 <Z0STR6VLt2MCalnY@sashalap> <Z0TLhc3uxa5RnK64@arm.com>
 <0c09425b-c8ba-4ed6-b429-0bce4e7d00e9@os.amperecomputing.com>
 <Z0dhc-DtVsvufv-E@arm.com>
 <dc5e8809-825f-4c38-b487-b16c7d516311@os.amperecomputing.com>
 <Z0h6Qtleb-znhX3u@arm.com>
Message-ID: <82e98235-4436-4f2f-901c-a25cfacd2673@os.amperecomputing.com>



On 11/28/24 6:12 AM, Catalin Marinas wrote:
> On Wed, Nov 27, 2024 at 05:21:37PM -0800, Yang Shi wrote:
>>>> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
>>>> index 87b3f1a25535..ef303a2262c5 100644
>>>> --- a/arch/arm64/mm/copypage.c
>>>> +++ b/arch/arm64/mm/copypage.c
>>>> @@ -30,9 +30,9 @@ void copy_highpage(struct page *to, struct page *from)
>>>>     	if (!system_supports_mte())
>>>>     		return;
>>>> -	if (folio_test_hugetlb(src) &&
>>>> -	    folio_test_hugetlb_mte_tagged(src)) {
>>>> -		if (!folio_try_hugetlb_mte_tagging(dst))
>>>> +	if (folio_test_hugetlb(src)) {
>>>> +		if (!folio_test_hugetlb_mte_tagged(src) ||
>>>> +		    !folio_try_hugetlb_mte_tagging(dst))
>>>>     			return;
>>>>     		/*
>>> I wonder why we had a 'return' here originally rather than a
>>> WARN_ON_ONCE() as we do further down for the page case. Do you seen any
>>> issue with the hunk below? Destination should be a new folio and not
>>> tagged yet:
>> Yes, I did see problem. Because we copy tags for all sub pages then set
>> folio mte tagged when copying the data for the first subpage. The warning
>> will be triggered when we copy the second subpage.
> Ah, good point, copy_highpage() will be called multiple times for each
> subpage but we only do the copying once for the folio.
>
> Now, I wonder whether we should actually defer the tag copying until
> copy_page() is called on the head page. This way we can keep the warning
> for consistency with the non-compound page case:

Yeah, we can do this. Looks fine to me.

>
> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
> index 87b3f1a25535..a86c897017df 100644
> --- a/arch/arm64/mm/copypage.c
> +++ b/arch/arm64/mm/copypage.c
> @@ -30,11 +30,13 @@ void copy_highpage(struct page *to, struct page *from)
>   	if (!system_supports_mte())
>   		return;
>   
> -	if (folio_test_hugetlb(src) &&
> -	    folio_test_hugetlb_mte_tagged(src)) {
> -		if (!folio_try_hugetlb_mte_tagging(dst))
> +	if (folio_test_hugetlb(src)) {
> +		if (!folio_test_hugetlb_mte_tagged(src) ||
> +		    from != folio_page(src, 0))
>   			return;
>   
> +		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
> +
>   		/*
>   		 * Populate tags for all subpages.
>   		 *
>



From umer.uddin at mentallysanemainliners.org  Mon Dec  2 08:05:48 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  2 Dec 2024 16:05:48 +0000
Subject: [PATCH v3 3/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
In-Reply-To: <9f48459e-f381-446a-86bf-c8d1bb8858bc@gmail.com>
References: <9f48459e-f381-446a-86bf-c8d1bb8858bc@gmail.com>
Message-ID: <20241202160548.3672-1-umer.uddin@mentallysanemainliners.org>

On 14/11/2024 10:09, Ivaylo Ivanov wrote:

>> +
>> +/ {
>> +	#address-cells = <2>;
>> +	#size-cells = <2>;
>> +
>> +	model = "Samsung Galaxy S20 5G";
>> +	compatible = "samsung,x1s", "samsung,exynos990";
>> +
>> +	memory at 80000000 {
>> +		device_type = "memory";
>> +		reg = <0x0 0x80000000 0x0 0x3ab00000>,
>> +		      /* Memory hole */
>> +		      <0x0 0xc1200000 0x0 0x1ee00000>,
>> +		      /* Memory hole */
>> +		      <0x0 0xe1900000 0x0 0x1e700000>,
>> +		      /* Memory hole */
> 
> The space from 0x100000000 to 0x880000000 isn't a hole in the memory
> though, is it? 0x880000000 is in the 64 bit address space.
> 
> Best regards, Ivo.

Hi Ivo, This device tree was based on the work done on c1s and
Igor had also labelled the part as a memory hole, also same with
the r8s device tree done by Denzeel, also downstream fdt skips out
on this region abruptly hence why I had also labelled it a memory
hole.


From shameerali.kolothum.thodi at huawei.com  Mon Dec  2 08:06:39 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Mon, 2 Dec 2024 16:06:39 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <20241202153618.GA6834@willie-the-truck>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
Message-ID: <98c9bd5ba3704eb190773ace350592bd@huawei.com>



> -----Original Message-----
> From: linux-arm-kernel <linux-arm-kernel-bounces at lists.infradead.org> On
> Behalf Of Will Deacon
> Sent: Monday, December 2, 2024 3:36 PM
> To: Vitaly Chikunov <vt at altlinux.org>; james.morse at arm.com
> Cc: linux-arm-kernel at lists.infradead.org; Catalin Marinas
> <catalin.marinas at arm.com>; linux-kernel at vger.kernel.org;
> maz at kernel.org; oliver.upton at linux.dev; mark.rutland at arm.com
> Subject: Re: v6.13-rc1: Internal error: Oops - Undefined instruction:
> 0000000002000000 [#1] SMP
> 
> [+ usual suspects]
> 
> On Mon, Dec 02, 2024 at 07:58:30AM +0300, Vitaly Chikunov wrote:
> > v6.13-rc1 exhibits a boot failure on aarch64 under KVM. (QEMU 9.1.1,
> > CPU Kunpeng-920). Boot log:
> 
> I've not tried to repro this locally, but from the log:
> 
> > + time qemu-system-aarch64 -M accel=kvm:tcg -smp cores=8 -m 4096 -
> serial mon:stdio -nodefaults -nographic -no-reboot -fsdev
> local,id=root,path=/,security_model=none,multidevs=remap -device virtio-
> 9p-pci,fsdev=root,mount_tag=virtio-9p:/ -device virtio-rng-pci -kernel
> /usr/src/tmp/kernel-image-6.13-buildroot/boot/vmlinuz-6.13.0-6.13-alt0.rc1
> -initrd /usr/src/tmp/initramfs-6.13.0-6.13-alt0.rc1.img -sandbox
> on,spawn=deny -M virt,gic-version=3 -cpu max -append 'console=ttyAMA0
> mitigations=off nokaslr  panic=-1 SCRIPT=/usr/src/tmp/vm.SchsIm2FjB
> earlycon earlyprintk=serial ignore_loglevel debug rddebug'
> > [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x481fd010]
> > [    0.000000] Linux version 6.13.0-6.13-alt0.rc1
> (builder at localhost.localdomain) (gcc-14 (GCC) 14.2.1 20241028 (ALT
> Sisyphus 14.2.1-alt1), GNU ld (GNU Binutils) 2.43.1.20241025) #1 SMP
> PREEMPT_DYNAMIC Mon Dec  2 03:33:29 UTC 2024
> > [    0.000000] KASLR disabled on command line
> > [    0.000000] random: crng init done
> > [    0.000000] Machine model: linux,dummy-virt
> > [    0.000000] printk: debug: ignoring loglevel setting.
> > [    0.000000] efi: UEFI not found.
> > [    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '')
> > [    0.000000] printk: legacy bootconsole [pl11] enabled
> > [    0.000000] OF: reserved mem: Reserved memory: No reserved-memory
> node in the DT
> > [    0.000000] NUMA: Faking a node at [mem 0x0000000040000000-
> 0x000000013fffffff]
> > [    0.000000] NODE_DATA(0) allocated [mem 0x13f7f3540-0x13f7f947f]
> > [    0.000000] Zone ranges:
> > [    0.000000]   DMA      [mem 0x0000000040000000-0x00000000ffffffff]
> > [    0.000000]   DMA32    empty
> > [    0.000000]   Normal   [mem 0x0000000100000000-0x000000013fffffff]
> > [    0.000000] Movable zone start for each node
> > [    0.000000] Early memory node ranges
> > [    0.000000]   node   0: [mem 0x0000000040000000-0x000000013fffffff]
> > [    0.000000] Initmem setup node 0 [mem 0x0000000040000000-
> 0x000000013fffffff]
> > [    0.000000] cma: Reserved 256 MiB at 0x00000000f0000000 on node -1
> > [    0.000000] psci: probing for conduit method from DT.
> > [    0.000000] psci: PSCIv1.1 detected in firmware.
> > [    0.000000] psci: Using standard PSCI v0.2 function IDs
> > [    0.000000] psci: Trusted OS migration not required
> > [    0.000000] psci: SMC Calling Convention v1.1
> > [    0.000000] smccc: KVM: hypervisor services detected (0x00000000
> 0x00000000 0x00000000 0x00000003)
> > [    0.000000] percpu: Embedded 34 pages/cpu s100632 r8192 d30440
> u139264
> > [    0.000000] pcpu-alloc: s100632 r8192 d30440 u139264 alloc=34*4096
> > [    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7
> > [    0.000000] Internal error: Oops - Undefined instruction:
> 0000000002000000 [#1] SMP
> 
> We take an undefined instruction exception in the kernel early during
> boot...
> 
> > [    0.000000] Modules linked in:
> > [    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.13.0-6.13-
> alt0.rc1 #1
> > [    0.000000] Hardware name: linux,dummy-virt (DT)
> > [    0.000000] pstate: 004000c5 (nzcv daIF +PAN -UAO -TCO -DIT -SSBS
> BTYPE=--)
> > [    0.000000] pc : __cpuinfo_store_cpu+0xe8/0x240
> > [    0.000000] lr : cpuinfo_store_boot_cpu+0x34/0x88
> > [    0.000000] sp : ffff800082013df0
> > [    0.000000] x29: ffff800082013df0 x28: 000000000000008e x27:
> ffff800081e38128
> > [    0.000000] x26: ffff800081702190 x25: ffff80008201f040 x24:
> ffff0000ff7d1d00
> > [    0.000000] x23: ffff80008201ec00 x22: ffff800081e39100 x21:
> ffff8000816f9750
> > [    0.000000] x20: ffff800081f55280 x19: ffff0000ff6be2e0 x18:
> 0000000000000000
> > [    0.000000] x17: 0000000000000000 x16: 0000000000000000 x15:
> 0000000000000000
> > [    0.000000] x14: 000000000000002f x13: 000000013f7f9490 x12:
> 0000008000000000
> > [    0.000000] x11: 0000000000000000 x10: 00000000007f8000 x9 :
> 000000013f808000
> > [    0.000000] x8 : 0000000000000000 x7 : 0000000000000000 x6 :
> 000000013f7f94c0
> > [    0.000000] x5 : 0000000000000000 x4 : 0000000000000000 x3 :
> 1100010011111111
> > [    0.000000] x2 : 0000000000000001 x1 : 0000000084448004 x0 :
> ffff0000ff6be2e0
> > [    0.000000] Call trace:
> > [    0.000000]  __cpuinfo_store_cpu+0xe8/0x240 (P)
> > [    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88 (L)
> > [    0.000000]  cpuinfo_store_boot_cpu+0x34/0x88
> > [    0.000000]  smp_prepare_boot_cpu+0x30/0x58
> > [    0.000000]  start_kernel+0x514/0x9d0
> > [    0.000000]  __primary_switched+0x88/0x98
> > [    0.000000] Code: f100085f 54000600 f2580c7f 54000060 (d538a482)
> 
> ... and that's:
> 
>    0:	f100085f 	cmp	x2, #0x2
>    4:	54000600 	b.eq	0xc4  // b.none
>    8:	f2580c7f 	tst	x3, #0xf0000000000
>    c:	54000060 	b.eq	0x18  // b.none
>   10:*	d538a482 	mrs	x2, s3_0_c10_c4_4		<-- trapping
> instruction
> 
> Which I think corresponds to a read of MPAMIDR_EL1.
> 
> It looks like James routed accesses to this register to undef_access() in
> 31ff96c38ea3 ("KVM: arm64: Fix missing traps of guest accesses to the
> MPAM register") so I'm not really sure how this is supposed to work given
> that it's an ID register.

It probably requires a firmware update as noted here,
https://lore.kernel.org/all/20241030160317.2528209-4-joey.gouly at arm.com/

I just tried it on a similar system with MPAM enabled and was not able to replicate the
above error.

Thanks,
Shameer


From maz at kernel.org  Mon Dec  2 08:07:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Dec 2024 16:07:03 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP
In-Reply-To: <20241202155940.p267a3tz5ypj4sog@altlinux.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
	<20241202153618.GA6834@willie-the-truck>
	<86ttbmt71k.wl-maz@kernel.org>
	<20241202155940.p267a3tz5ypj4sog@altlinux.org>
Message-ID: <86ser6t6fs.wl-maz@kernel.org>

On Mon, 02 Dec 2024 15:59:40 +0000,
Vitaly Chikunov <vt at altlinux.org> wrote:
> 
> Marc,
> 
> On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> >
> > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> 
> No, host is 6.6.60.

Right. I wouldn't be surprised if:

- this v6.6 kernel doesn't hide the MPAM feature as it should (and
  that's proably something we should backport)

- you get a nastygram in the host log telling you that the guest has
  executed something it shouldn't (you'll get the encoding of the
  instruction)

Can you confirm these two things?

	M.

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


From ulf.hansson at linaro.org  Mon Dec  2 08:07:33 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 2 Dec 2024 17:07:33 +0100
Subject: [PATCH v2 1/8] dt-bindings: power: mediatek: Add another nested
 power-domain layer
In-Reply-To: <20241001113052.3124869-2-fshao@chromium.org>
References: <20241001113052.3124869-1-fshao@chromium.org> <20241001113052.3124869-2-fshao@chromium.org>
Message-ID: <CAPDyKFocgdjSdek-sNHy_w1ZQkscgs8Z0TYwXPKC9phUbH-scg@mail.gmail.com>

On Tue, 1 Oct 2024 at 13:31, Fei Shao <fshao at chromium.org> wrote:
>
> The MT8188 SoC has a more in-depth power-domain tree, and the
> CHECK_DTBS=y check could fail because the current MediaTek power
> dt-binding is insufficient to cover its CAM_SUBA and CAM_SUBB
> sub-domains.
>
> Add one more nested power-domain layer to pass the check.
>
> Acked-by: Rob Herring (Arm) <robh at kernel.org>
> Signed-off-by: Fei Shao <fshao at chromium.org>

Applied for fixes (to silence the warning in v6.13-rc[n], thanks!

Kind regards
Uffe


> ---
>
> (no changes since v1)
>
>  .../devicetree/bindings/power/mediatek,power-controller.yaml  | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
> index 8985e2df8a56..a7df4041b745 100644
> --- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
> +++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
> @@ -54,6 +54,10 @@ patternProperties:
>              patternProperties:
>                "^power-domain@[0-9a-f]+$":
>                  $ref: "#/$defs/power-domain-node"
> +                patternProperties:
> +                  "^power-domain@[0-9a-f]+$":
> +                    $ref: "#/$defs/power-domain-node"
> +                    unevaluatedProperties: false
>                  unevaluatedProperties: false
>              unevaluatedProperties: false
>          unevaluatedProperties: false
> --
> 2.46.1.824.gd892dcdcdd-goog
>


From ulf.hansson at linaro.org  Mon Dec  2 08:07:42 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 2 Dec 2024 17:07:42 +0100
Subject: [PATCH v2 0/8] MT8188 DT and binding fixes
In-Reply-To: <CAGXv+5E4=dKkUo73x5vCMHawcr9AUd71LyLmDbdyOdJZv0ZBaQ@mail.gmail.com>
References: <20241001113052.3124869-1-fshao@chromium.org> <CAGXv+5E4=dKkUo73x5vCMHawcr9AUd71LyLmDbdyOdJZv0ZBaQ@mail.gmail.com>
Message-ID: <CAPDyKFor=KyPEfrfLWct0dLa03hj6uawM-R3z4rOEzHSrNCWCg@mail.gmail.com>

On Mon, 2 Dec 2024 at 05:24, Chen-Yu Tsai <wenst at chromium.org> wrote:
>
> Hi,
>
> On Tue, Oct 1, 2024 at 7:31?PM Fei Shao <fshao at chromium.org> wrote:
> >
> > Hi,
> >
> > This series is split from a previous series[*] to focus on few fixes and
> > improvements around MediaTek MT8188 device tree and associated bindings,
> > and addressed comments and carried tags from the previous series.
> >
> > [*]: https://lore.kernel.org/all/20240909111535.528624-1-fshao at chromium.org/
> > [v1]: https://lore.kernel.org/all/20240925110044.3678055-1-fshao at chromium.org/
> >
> > Regards,
> > Fei
> >
> > Changes in v2:
> > - new patch to MediaTek jpeg and vcodec bindings
> > - new patch to move MT8188 SPI NOR cell properties
> > - revise commit message of vdec power domain changes
> >
> > Fei Shao (8):
>
> >   dt-bindings: power: mediatek: Add another nested power-domain layer
>
> This one ^
>
> >   dt-bindings: PCI: mediatek-gen3: Allow exact number of clocks only
>
> >   dt-bindings: media: mediatek,jpeg: Relax IOMMU max item count
> >   dt-bindings: media: mediatek,vcodec: Revise description
>
> and these two ^ have not been picked up, and now v6.13-rc1 has DT
> validation errors for MT8188:
>
> /ssd1/wenst/linux/mtk/arch/arm64/boot/dts/mediatek/mt8188-evb.dtb:
> syscon at 10006000:
> power-controller:power-domain at 15:power-domain at 16:power-domain at 29:power-domain at 30:
> Unevaluated properties are not allowed ('power-domain at 31',
> 'power-domain at 32' were unexpected)
>     from schema $id:
> http://devicetree.org/schemas/mfd/mediatek,mt8195-scpsys.yaml#
> /ssd1/wenst/linux/mtk/arch/arm64/boot/dts/mediatek/mt8188-evb.dtb:
> power-controller:
> power-domain at 15:power-domain at 16:power-domain at 29:power-domain at 30:
> Unevaluated properties are not allowed ('power-domain at 31',
> 'power-domain at 32' were unexpected)
>     from schema $id:
> http://devicetree.org/schemas/power/mediatek,power-controller.yaml#
>
> /ssd1/wenst/linux/mtk/arch/arm64/boot/dts/mediatek/mt8188-evb.dtb:
> jpeg-decoder at 1a040000: iommus: [[101, 685], [101, 686], [101, 690],
> [101, 691], [101, 692], [101, 693]] is too long
>     from schema $id:
> http://devicetree.org/schemas/media/mediatek-jpeg-decoder.yaml#
>
>
> Is there any way we can get them into v6.13 as well?

I don't know why I missed picking up the DT power-domain patch for
v6.13. Sorry for the delay. Anyway, I have taken it now and applied it
as a fix for v6.13-rc[n], thanks!

I assume someone else can help to take the DT media patches.

Kind regards
Uffe


>
> ChenYu
>
> >   arm64: dts: mediatek: mt8188: Add missing dma-ranges to soc node
> >   arm64: dts: mediatek: mt8188: Update vppsys node names to syscon
> >   arm64: dts: mediatek: mt8188: Move vdec1 power domain under vdec0
> >   arm64: dts: mediatek: mt8188: Move SPI NOR *-cells properties
> >
> >  .../media/mediatek,vcodec-subdev-decoder.yaml | 100 +++++++++++-------
> >  .../bindings/media/mediatek-jpeg-decoder.yaml |   3 +-
> >  .../bindings/media/mediatek-jpeg-encoder.yaml |   2 +-
> >  .../bindings/pci/mediatek-pcie-gen3.yaml      |   5 +-
> >  .../power/mediatek,power-controller.yaml      |   4 +
> >  arch/arm64/boot/dts/mediatek/mt8188-evb.dts   |   2 -
> >  arch/arm64/boot/dts/mediatek/mt8188.dtsi      |  33 +++---
> >  7 files changed, 88 insertions(+), 61 deletions(-)
> >
> > --
> > 2.46.1.824.gd892dcdcdd-goog
> >
> >


From david at redhat.com  Mon Dec  2 08:10:58 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 2 Dec 2024 17:10:58 +0100
Subject: [GIT PULL] arm64 updates for 6.13-rc1
In-Reply-To: <Z0h6Qtleb-znhX3u@arm.com>
References: <20241118100623.2674026-1-catalin.marinas@arm.com>
 <Z0STR6VLt2MCalnY@sashalap> <Z0TLhc3uxa5RnK64@arm.com>
 <0c09425b-c8ba-4ed6-b429-0bce4e7d00e9@os.amperecomputing.com>
 <Z0dhc-DtVsvufv-E@arm.com>
 <dc5e8809-825f-4c38-b487-b16c7d516311@os.amperecomputing.com>
 <Z0h6Qtleb-znhX3u@arm.com>
Message-ID: <789f8be8-a423-43aa-baa7-b808d6c59072@redhat.com>

On 28.11.24 15:12, Catalin Marinas wrote:
> On Wed, Nov 27, 2024 at 05:21:37PM -0800, Yang Shi wrote:
>>>> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
>>>> index 87b3f1a25535..ef303a2262c5 100644
>>>> --- a/arch/arm64/mm/copypage.c
>>>> +++ b/arch/arm64/mm/copypage.c
>>>> @@ -30,9 +30,9 @@ void copy_highpage(struct page *to, struct page *from)
>>>>     	if (!system_supports_mte())
>>>>     		return;
>>>> -	if (folio_test_hugetlb(src) &&
>>>> -	    folio_test_hugetlb_mte_tagged(src)) {
>>>> -		if (!folio_try_hugetlb_mte_tagging(dst))
>>>> +	if (folio_test_hugetlb(src)) {
>>>> +		if (!folio_test_hugetlb_mte_tagged(src) ||
>>>> +		    !folio_try_hugetlb_mte_tagging(dst))
>>>>     			return;
>>>>     		/*
>>> I wonder why we had a 'return' here originally rather than a
>>> WARN_ON_ONCE() as we do further down for the page case. Do you seen any
>>> issue with the hunk below? Destination should be a new folio and not
>>> tagged yet:
>>
>> Yes, I did see problem. Because we copy tags for all sub pages then set
>> folio mte tagged when copying the data for the first subpage. The warning
>> will be triggered when we copy the second subpage.
> 
> Ah, good point, copy_highpage() will be called multiple times for each
> subpage but we only do the copying once for the folio.
> 

It makes me still a bit nervous that we assume both the src and the 
destination folio have the same #pages (and in particular, that both are 
hugetlb folios :) ).

Hopefully that's an invariant that will always hold :)

> Now, I wonder whether we should actually defer the tag copying until
> copy_page() is called on the head page. This way we can keep the warning
> for consistency with the non-compound page case:
> 
> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
> index 87b3f1a25535..a86c897017df 100644
> --- a/arch/arm64/mm/copypage.c
> +++ b/arch/arm64/mm/copypage.c
> @@ -30,11 +30,13 @@ void copy_highpage(struct page *to, struct page *from)
>   	if (!system_supports_mte())
>   		return;
>   
> -	if (folio_test_hugetlb(src) &&
> -	    folio_test_hugetlb_mte_tagged(src)) {
> -		if (!folio_try_hugetlb_mte_tagging(dst))
> +	if (folio_test_hugetlb(src)) {
> +		if (!folio_test_hugetlb_mte_tagged(src) ||
> +		    from != folio_page(src, 0))
>   			return;
>   
> +		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
> +
>   		/*
>   		 * Populate tags for all subpages.
>   		 *
> 

Yes, looks better. A comment describing the oddity of "copy single page 
but copy all tags on head page access" might be reasonable.

-- 
Cheers,

David / dhildenb



From ulf.hansson at linaro.org  Mon Dec  2 08:12:10 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 2 Dec 2024 17:12:10 +0100
Subject: [PATCH] pmdomain: imx: gpcv2: Adjust delay after power up handshake
In-Reply-To: <20241121075231.3910922-1-shengjiu.wang@nxp.com>
References: <20241121075231.3910922-1-shengjiu.wang@nxp.com>
Message-ID: <CAPDyKFrm8wv7uFAumx5d6uMhr=LLUT8_RsQhNMF4DyOUe7uMFg@mail.gmail.com>

On Thu, 21 Nov 2024 at 08:53, Shengjiu Wang <shengjiu.wang at nxp.com> wrote:
>
> The udelay(5) is not enough, sometimes below kernel panic
> still be triggered:
>
> [    4.012973] Kernel panic - not syncing: Asynchronous SError Interrupt
> [    4.012976] CPU: 2 UID: 0 PID: 186 Comm: (udev-worker) Not tainted 6.12.0-rc2-0.0.0-devel-00004-g8b1b79e88956 #1
> [    4.012982] Hardware name: Toradex Verdin iMX8M Plus WB on Dahlia Board (DT)
> [    4.012985] Call trace:
> [...]
> [    4.013029]  arm64_serror_panic+0x64/0x70
> [    4.013034]  do_serror+0x3c/0x70
> [    4.013039]  el1h_64_error_handler+0x30/0x54
> [    4.013046]  el1h_64_error+0x64/0x68
> [    4.013050]  clk_imx8mp_audiomix_runtime_resume+0x38/0x48
> [    4.013059]  __genpd_runtime_resume+0x30/0x80
> [    4.013066]  genpd_runtime_resume+0x114/0x29c
> [    4.013073]  __rpm_callback+0x48/0x1e0
> [    4.013079]  rpm_callback+0x68/0x80
> [    4.013084]  rpm_resume+0x3bc/0x6a0
> [    4.013089]  __pm_runtime_resume+0x50/0x9c
> [    4.013095]  pm_runtime_get_suppliers+0x60/0x8c
> [    4.013101]  __driver_probe_device+0x4c/0x14c
> [    4.013108]  driver_probe_device+0x3c/0x120
> [    4.013114]  __driver_attach+0xc4/0x200
> [    4.013119]  bus_for_each_dev+0x7c/0xe0
> [    4.013125]  driver_attach+0x24/0x30
> [    4.013130]  bus_add_driver+0x110/0x240
> [    4.013135]  driver_register+0x68/0x124
> [    4.013142]  __platform_driver_register+0x24/0x30
> [    4.013149]  sdma_driver_init+0x20/0x1000 [imx_sdma]
> [    4.013163]  do_one_initcall+0x60/0x1e0
> [    4.013168]  do_init_module+0x5c/0x21c
> [    4.013175]  load_module+0x1a98/0x205c
> [    4.013181]  init_module_from_file+0x88/0xd4
> [    4.013187]  __arm64_sys_finit_module+0x258/0x350
> [    4.013194]  invoke_syscall.constprop.0+0x50/0xe0
> [    4.013202]  do_el0_svc+0xa8/0xe0
> [    4.013208]  el0_svc+0x3c/0x140
> [    4.013215]  el0t_64_sync_handler+0x120/0x12c
> [    4.013222]  el0t_64_sync+0x190/0x194
> [    4.013228] SMP: stopping secondary CPUs
>
> The correct way is to wait handshake, but it needs BUS clock of
> BLK-CTL be enabled, which is in separate driver. So delay is the
> only option here. The udelay(10) is a data got by experiment.
>
> Fixes: e8dc41afca16 ("pmdomain: imx: gpcv2: Add delay after power up handshake")
> Reported-by: Francesco Dolcini <francesco at dolcini.it>
> Closes: https://lore.kernel.org/lkml/20241007132555.GA53279 at francesco-nb/
> Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>

Applied for fixes and by adding a stable tag, thanks!

Kind regards
Uffe

> ---
>  drivers/pmdomain/imx/gpcv2.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c
> index 6e6ecbf2e152..760301ad8e39 100644
> --- a/drivers/pmdomain/imx/gpcv2.c
> +++ b/drivers/pmdomain/imx/gpcv2.c
> @@ -403,7 +403,7 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
>                  * already reaches target before udelay()
>                  */
>                 regmap_read_bypassed(domain->regmap, domain->regs->hsk, &reg_val);
> -               udelay(5);
> +               udelay(10);
>         }
>
>         /* Disable reset clocks for all devices in the domain */
> --
> 2.34.1
>


From andy at kernel.org  Mon Dec  2 08:14:33 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Mon, 2 Dec 2024 18:14:33 +0200
Subject: [PATCH 2/3] media: atomisp: Use the actual value of the enum
 instead of the enum
In-Reply-To: <20241202-fix-llvm9-v1-2-2a50f5acfd0b@chromium.org>
References: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
 <20241202-fix-llvm9-v1-2-2a50f5acfd0b@chromium.org>
Message-ID: <Z03c6ZHOP9rUFtP_@smile.fi.intel.com>

On Mon, Dec 02, 2024 at 03:47:16PM +0000, Ricardo Ribalda wrote:
> hrt_isp_css_irq_sw_pin_0 has a different enum type than
> irq_sw_channel_id_t.
> 
> Replace it with the actual value of hrt_isp_css_irq_sw_pin_0 to avoid
> arithmetic operations between different enum types (and make the
> compiler happy).
> 
> It is required to build with llvm 9 without these warnings:

9?! Maybe 19?

> drivers/staging/media/atomisp/pci/sh_css_hrt.c:68:19: warning: arithmetic between different enumeration types ('irq_sw_channel_id_t' and 'enum hrt_isp_css_irq') [-Wenum-enum-conversion]
> drivers/staging/media/atomisp/pci/sh_css.c:1233:40: warning: arithmetic between different enumeration types ('irq_sw_channel_id_t' and 'enum hrt_isp_css_irq') [-Wenum-enum-conversion]
> drivers/staging/media/atomisp/pci/sh_css.c:1237:40: warning: arithmetic between different enumeration types ('irq_sw_channel_id_t' and 'enum hrt_isp_css_irq') [-Wenum-enum-conversion]
> ro

You can make the above lines shorter by dropping the obvious an duplicated (in
other places) part, i.e.  drivers/staging/media/atomisp/. I usually replace
this with "...".

.../pci/sh_css_hrt.c:68:19: warning: arithmetic between different enumeration types ('irq_sw_channel_id_t' and 'enum hrt_isp_css_irq') [-Wenum-enum-conversion]
.../pci/sh_css.c:1233:40: warning: arithmetic between different enumeration types ('irq_sw_channel_id_t' and 'enum hrt_isp_css_irq') [-Wenum-enum-conversion]
.../pci/sh_css.c:1237:40: warning: arithmetic between different enumeration types ('irq_sw_channel_id_t' and 'enum hrt_isp_css_irq') [-Wenum-enum-conversion]

Otherwise LGTM,
Reviewed-by: Andy Shevchenko <andy at kernel.org>

-- 
With Best Regards,
Andy Shevchenko




From umer.uddin at mentallysanemainliners.org  Mon Dec  2 08:21:54 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  2 Dec 2024 16:21:54 +0000
Subject: [RESEND,v3 0/4] Add minimal Samsung Galaxy S20 Series board, SM-G981B and SM-G980F support
Message-ID: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>

Hi folks,

This series adds initial support for the Samsung Galaxy S20 Series and also
initial board support for the Samsung Galaxy S20 5G (SM-G981B)
codenamed x1s.

The S20 Series feature a lot of similarities in their configuration
and internally Samsung named the common devicetrees in their
downstream kernel 'hubble', please note hubble excludes the
S20 FE series and Note20 series.
The device trees have been tested with dtbs_check W=1
and results in no warnings.

This initial bringup consists of:
 * pinctrl
 * gpio-keys
 * simple-framebuffer

This is enough to reach a shell in an initramfs. More platform support
will be added in the future.

Just like SM-N981B, the preferred way to boot the upstream kernel is
by using a shim bootloader, called uniLoader [1], which works around
some issues with the stock, non-replacable Samsung S-LK bootloader.
For example, the stock bootloader leaves the decon trigger control
unset, which causes the framebuffer not to refresh.

Device functionality depends on the patch series from Igor Belwon:
"Add minimal Exynos990 SoC and SM-N981B support"

[1] https://github.com/ivoszbg/uniLoader

Changes in v3:
 - Fix oversight in yaml
 - Decommonise memory map

Changes in v2:
 - Add Samsung Galaxy S20 into device tree bindings
 - Add support for Samsung Galaxy S20 as well as the 5G variant now
 - Fix typo in Samsung Galaxy S20 5G commit message

Kind regards,
Umer

Umer Uddin (4):
  dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B
    and SM-G980F board
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series
    boards (hubble)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G
    (x1s)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20
    (x1slte)

 .../bindings/arm/samsung/samsung-boards.yaml  |  2 +
 arch/arm64/boot/dts/exynos/Makefile           |  2 +
 .../dts/exynos/exynos990-hubble-common.dtsi   | 98 +++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts  | 28 ++++++
 .../boot/dts/exynos/exynos990-x1slte.dts      | 28 ++++++
 5 files changed, 158 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-hubble-common.dtsi
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Mon Dec  2 08:21:55 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  2 Dec 2024 16:21:55 +0000
Subject: [PATCH v3 1/4] dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
In-Reply-To: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>
References: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241202162158.5208-2-umer.uddin@mentallysanemainliners.org>

Add devicetree bindings for Samsung Galaxy S20 5G
and Samsung Galaxy S20 board.

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml         | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index b5ba5ffc3..f15228d5c 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -240,6 +240,8 @@ properties:
         items:
           - enum:
               - samsung,c1s                     # Samsung Galaxy Note20 5G (SM-N981B)
+              - samsung,x1s                     # Samsung Galaxy S20 5G (SM-G981B)
+              - samsung,x1slte                  # Samsung Galaxy S20 (SM-G980F)
           - const: samsung,exynos990
 
       - description: Exynos Auto v9 based boards
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Mon Dec  2 08:21:57 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  2 Dec 2024 16:21:57 +0000
Subject: [PATCH v3 3/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
In-Reply-To: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>
References: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241202162158.5208-4-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 5G (x1s/SM-G981B)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 12GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 12GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile          |  1 +
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts | 28 ++++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index 7a934499b..deb8dc509 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -9,5 +9,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos850-e850-96.dtb		\
 	exynos8895-dreamlte.dtb		\
 	exynos990-c1s.dtb		\
+	exynos990-x1s.dtb		\
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s.dts b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
new file mode 100644
index 000000000..162961446
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 5G (x1s/SM-G981B) device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990-hubble-common.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	model = "Samsung Galaxy S20 5G";
+	compatible = "samsung,x1s", "samsung,exynos990";
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x3ab00000>,
+		      /* Memory hole */
+		      <0x0 0xc1200000 0x0 0x1ee00000>,
+		      /* Memory hole */
+		      <0x0 0xe1900000 0x0 0x1e700000>,
+		      /* Memory hole */
+		      <0x8 0x80000000 0x2 0x7e800000>;
+	};
+};
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Mon Dec  2 08:21:56 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  2 Dec 2024 16:21:56 +0000
Subject: [PATCH v3 2/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series boards (hubble)
In-Reply-To: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>
References: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241202162158.5208-3-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 Series (hubble) phones.
They were launched in 2020, and are based on the Exynos 990 SoC.
The devices have multiple RAM configurations,
starting from 8GB going all the way up to 16GB for the S20 Ultra devices.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM (Any more will be mapped in device trees)
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../dts/exynos/exynos990-hubble-common.dtsi   | 98 +++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-hubble-common.dtsi

diff --git a/arch/arm64/boot/dts/exynos/exynos990-hubble-common.dtsi b/arch/arm64/boot/dts/exynos/exynos990-hubble-common.dtsi
new file mode 100644
index 000000000..55fa8e9e0
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-hubble-common.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 Series device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		framebuffer0: framebuffer at f1000000 {
+			compatible = "simple-framebuffer";
+			reg = <0 0xf1000000 0 (1440 * 3200 * 4)>;
+			width = <1440>;
+			height = <3200>;
+			stride = <(1440 * 4)>;
+			format = "a8r8g8b8";
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		cont_splash_mem: framebuffer at f1000000 {
+			reg = <0 0xf1000000 0 0x1194000>;
+			no-map;
+		};
+
+		abox_reserved: audio at f7fb0000 {
+			reg = <0 0xf7fb0000 0 0x2a50000>;
+			no-map;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&key_power &key_voldown &key_volup>;
+		pinctrl-names = "default";
+
+		power-key {
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpa2 4 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+
+		voldown-key {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			gpios = <&gpa0 4 GPIO_ACTIVE_LOW>;
+		};
+
+		volup-key {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&oscclk {
+	clock-frequency = <26000000>;
+};
+
+&pinctrl_alive {
+	key_power: key-power-pins {
+		samsung,pins = "gpa2-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_voldown: key-voldown-pins {
+		samsung,pins = "gpa0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_volup: key-volup-pins {
+		samsung,pins = "gpa0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Mon Dec  2 08:21:58 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  2 Dec 2024 16:21:58 +0000
Subject: [PATCH v3 4/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 (x1slte)
In-Reply-To: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>
References: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241202162158.5208-5-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 (x1slte/SM-G980F)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 8GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile           |  1 +
 .../boot/dts/exynos/exynos990-x1slte.dts      | 28 +++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index deb8dc509..783807249 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -10,5 +10,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos8895-dreamlte.dtb		\
 	exynos990-c1s.dtb		\
 	exynos990-x1s.dtb		\
+	exynos990-x1slte.dtb		\
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts b/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts
new file mode 100644
index 000000000..7bca641e5
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 (x1slte/SM-G980F) device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990-hubble-common.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	model = "Samsung Galaxy S20";
+	compatible = "samsung,x1slte", "samsung,exynos990";
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x3ab00000>,
+		      /* Memory hole */
+		      <0x0 0xc1200000 0x0 0x1ee00000>,
+		      /* Memory hole */
+		      <0x0 0xe1900000 0x0 0x1e700000>,
+		      /* Memory hole */
+		      <0x8 0x80000000 0x1 0x7ec00000>;
+	};
+};
-- 
2.47.1



From mripard at kernel.org  Mon Dec  2 07:44:53 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 02 Dec 2024 15:44:53 +0000
Subject: [PATCH v5 04/10] drm/display: hdmi: add generic mode_valid
 helper
In-Reply-To: <20241130-hdmi-mode-valid-v5-4-742644ec3b1f@linaro.org>
References: <20241130-hdmi-mode-valid-v5-4-742644ec3b1f@linaro.org>
Message-ID: <f7d5a7e084f01661572b2608c9a73db2@kernel.org>

On Sat, 30 Nov 2024 03:52:29 +0200, Dmitry Baryshkov wrote:
> Add drm_hdmi_connector_mode_valid(), generic helper for HDMI connectors.
> It can be either used directly or as a part of the .mode_valid callback.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From s-vadapalli at ti.com  Mon Dec  2 07:45:43 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Mon, 2 Dec 2024 21:15:43 +0530
Subject: [PATCHv2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable
 ACSPCIE output for PCIe1
In-Reply-To: <f332947a-d7b5-4f68-84d8-3ecce118c24c@kernel.org>
References: <20241202101140.48778-1-romain.naour@smile.fr>
 <dabbad2b-f8a6-4ed7-86da-ec696cf67461@kernel.org>
 <k7udgqugqseweckb7hjniz3aops4kn35ttju2ju7f2pcbmndrg@dau5nr4leish>
 <abeb632b-9efc-48e5-a28a-a9d7c02e0a6e@kernel.org>
 <cndc3fopwhwkotfikul2jtzfczpdpwlrs5uhuqq76ck36ndtfs@gvxavxt5tgd5>
 <f332947a-d7b5-4f68-84d8-3ecce118c24c@kernel.org>
Message-ID: <rjecpmr4bsedbfhu74sdlzmdz2mh2shsr5myawb3qveooawa3j@i2ysnnyf7hio>

On Mon, Dec 02, 2024 at 04:09:51PM +0100, Krzysztof Kozlowski wrote:
> On 02/12/2024 15:53, Siddharth Vadapalli wrote:
> > On Mon, Dec 02, 2024 at 12:07:17PM +0100, Krzysztof Kozlowski wrote:
> > 
> > Hello Krzysztof,
> > 
> >> On 02/12/2024 11:58, Siddharth Vadapalli wrote:
> >>> On Mon, Dec 02, 2024 at 11:14:46AM +0100, Krzysztof Kozlowski wrote:
> >>>
> >>> Hello Krzysztof,
> >>>
> >>>> On 02/12/2024 11:11, Romain Naour wrote:
> >>>>> From: Romain Naour <romain.naour at skf.com>
> >>>>>
> >>>>> Unlike the SK-TDA4VM (k3-j721e-sk) board, there is no clock generator
> >>>>> (CDCI6214RGET) on the BeagleBone AI-64 (k3-j721e-beagleboneai64) to
> >>>>> provide PCIe refclk signal to PCIe Endponts. So the ACSPCIE module must
> >>>>> provide refclk through PCIe_REFCLK pins.
> >>>>>
> >>>>> Use the new "ti,syscon-acspcie-proxy-ctrl" property to enable ACSPCIE
> >>>>> module's PAD IO Buffers.
> >>>>>
> >>>>> Reuse the compatible "ti,j784s4-acspcie-proxy-ctrl" since the ACSPCIE
> >>>>> buffer and its functionality is the same across all K3 SoCs.
> >>>>>
> >>>>> Cc: Siddharth Vadapalli <s-vadapalli at ti.com>
> >>>>> Signed-off-by: Romain Naour <romain.naour at skf.com>
> >>>>> ---
> >>>>> With this patch, we can remove "HACK: Sierra: Drive clock out" patch
> >>>>> applied on vendor kernel for BeagleBone AI-64:
> >>>>> https://openbeagle.org/beagleboard/linux/-/commit/ad65d7ef675966cdbc5d75f2bd545fad1914ba9b
> >>>>>
> >>>>> v2:
> >>>>>  - use generic style comments
> >>>>>  - use "syscon" as generic node name for "acspcie0_proxy_ctrl" node
> >>>>>  - Keep the compatible "ti,j784s4-acspcie-proxy-ctrl" since the
> >>>>>    ACSPCIE buffer and its functionality is the same across all K3 SoCs.
> >>>>>    (Siddharth Vadapalli)
> >>>>>
> >>>>>    "The compatible "ti,j784s4-acspcie-pcie-ctrl" should be reused for
> >>>>>    J721E and all other K3 SoCs.
> >>>>
> >>>> No, it shouldn't and you got comment on this. You always need specific
> >>>> compatible, see writing bindings doc.
> >>>
> >>> Could you please clarify in which cases reusing the compatible is
> >>> permissible? The list of compatibles at:
> >>
> >> Never? You always need specific compatible. Did you read the writing
> >> bindings document?
> > 
> > I went through the bindings document again at:
> > https://www.kernel.org/doc/Documentation/devicetree/bindings/writing-bindings.rst
> > It mentions:
> > - DON'T use 'syscon' alone without a specific compatible string. A 'syscon'
> >   hardware block should have a compatible string unique enough to infer the
> >   register layout of the entire block (at a minimum).
> > 
> > The ACSCPCIE Block as well as its integration across all of TI's K3 SoCs
> > is the same i.e. same Hardware/IP. The register bits corresponding to
> 
> 
> And first rule for compatible property? DT bindings maintainers keep
> repeating it over and over - specific means soc as front compatible.
> 
> > the feature to be enabled/disabled via the ACSPCIE block are the same as
> > well i.e. "register layout can be inferred". The same goes for the
> > compatibles listed below in my previous reply i.e. they aren't bugs.
> > Same IP and integration across SoCs and hence reused in the sense of
> > Hardware and not Software. I hope this clarifies the rationale for the
> > "reuse".
> 
> 
> You mix re-use with fallback. These are almost never the same blocks,
> which you imply here.

I know that the IP is the same, the bits are the same and those bits enable
the same functionality of the IP across the SoCs. If you still insist that
they are not same, I don't know what to say anymore.

Regards,
Siddharth.


From wahrenst at gmx.net  Mon Dec  2 07:45:53 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon, 2 Dec 2024 16:45:53 +0100
Subject: [PATCH 3/7] dt-bindings: gpio: brcmstb: add gpio-line-name
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-3-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-3-fac67cc2f98a@raspberrypi.com>
Message-ID: <31d19aae-e2d2-4219-abe1-10516c42befe@gmx.net>

Hi Dave,

Am 02.12.24 um 15:31 schrieb Dave Stevenson:
> Support comes from gpiolib, so permit it through the binding.
Sorry for the nitpicking, but gpiolib is a software part of Linux and we
should describe the hardware here.

Best regards
>
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>   Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml | 2 ++
>   1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
> index f096f286da19..086d016df6ef 100644
> --- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
> +++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
> @@ -64,6 +64,8 @@ properties:
>
>     gpio-ranges: true
>
> +  gpio-line-names: true
> +
>     wakeup-source:
>       type: boolean
>       description: >
>



From quic_jjohnson at quicinc.com  Mon Dec  2 07:46:07 2024
From: quic_jjohnson at quicinc.com (Jeff Johnson)
Date: Mon, 2 Dec 2024 07:46:07 -0800
Subject: [PATCH v2 2/4] input: apple_z2: Add a driver for Apple Z2
 touchscreens
In-Reply-To: <20241128-z2-v2-2-76cc59bbf117@gmail.com>
References: <20241128-z2-v2-0-76cc59bbf117@gmail.com>
 <20241128-z2-v2-2-76cc59bbf117@gmail.com>
Message-ID: <626c3135-9d8a-4e22-a3ad-6b637cbbd463@quicinc.com>

On 11/28/24 14:29, Sasha Finkelstein via B4 Relay wrote:
> From: Sasha Finkelstein <fnkl.kernel at gmail.com>
> 
> Adds a driver for Apple touchscreens using the Z2 protocol.
> 
> Signed-off-by: Janne Grunau <j at jannau.net>
> Signed-off-by: Sasha Finkelstein <fnkl.kernel at gmail.com>
> ---
...
> +MODULE_LICENSE("GPL");
> +MODULE_FIRMWARE("apple/dfrmtfw-*.bin");


Since commit 1fffe7a34c89 ("script: modpost: emit a warning when the
description is missing"), a module without a MODULE_DESCRIPTION() will
result in a warning when built with make W=1.

Please add the missing MODULE_DESCRIPTION()



From robh at kernel.org  Mon Dec  2 07:46:40 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 02 Dec 2024 09:46:40 -0600
Subject: [PATCH 1/7] dtbindings: display: bcm2711-hdmi: Correct
 bindings for 2712
In-Reply-To: <20241202-dt-bcm2712-fixes-v1-1-fac67cc2f98a@raspberrypi.com>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-1-fac67cc2f98a@raspberrypi.com>
Message-ID: <173315440083.2722567.15501799626521434805.robh@kernel.org>


On Mon, 02 Dec 2024 14:31:54 +0000, Dave Stevenson wrote:
> The previous patch just adding the compatible missed out that the
> number of interrupts changed
> 
> Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  .../bindings/display/brcm,bcm2711-hdmi.yaml        | 44 +++++++++++++++-------
>  1 file changed, 30 insertions(+), 14 deletions(-)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:
./Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml:59:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
./Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml:67:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
./Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml:76:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
./Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml:84:9: [warning] wrong indentation: expected 10 but found 8 (indentation)

dtschema/dtc warnings/errors:

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241202-dt-bcm2712-fixes-v1-1-fac67cc2f98a at raspberrypi.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 ribalda at chromium.org  Mon Dec  2 07:47:14 2024
From: ribalda at chromium.org (Ricardo Ribalda)
Date: Mon, 02 Dec 2024 15:47:14 +0000
Subject: [PATCH 0/3] media: Fix warnings with llvm9
Message-ID: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>

When we tried to build media with llvm we got some new warnings, lets
try to fix them before llvm is part of our CI.

Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
---
Ricardo Ribalda (3):
      media: cx231xx: Convert enum into a define
      media: atomisp: Use the actual value of the enum instead of the enum
      media: mediatek: vcodec: Workaround a compiler warning

 .../mediatek/vcodec/encoder/venc/venc_h264_if.c        |  6 ++++--
 drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h            | 18 +++++++-----------
 .../media/atomisp/pci/hive_isp_css_common/irq_global.h |  2 +-
 3 files changed, 12 insertions(+), 14 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241202-fix-llvm9-4c8d705c9e3e

Best regards,
-- 
Ricardo Ribalda <ribalda at chromium.org>



From ribalda at chromium.org  Mon Dec  2 07:47:15 2024
From: ribalda at chromium.org (Ricardo Ribalda)
Date: Mon, 02 Dec 2024 15:47:15 +0000
Subject: [PATCH 1/3] media: cx231xx: Convert enum into a define
In-Reply-To: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
References: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
Message-ID: <20241202-fix-llvm9-v1-1-2a50f5acfd0b@chromium.org>

The code is running arithmentics with the enum, which when not done with
care makes the compiler a bit nervous.

Because those enums are only used as defines (no argument or variable
from that enumeration type), convert it into a define and move on.

It is required to build with llvm 9 without these warnings:
drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:673:17: warning: bitwise operation between different enumeration types ('enum TS_PORT' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:680:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:687:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:702:17: warning: bitwise operation between different enumeration types ('enum TS_PORT' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:709:21: warning: bitwise operation between different enumeration types ('enum TS_PORT' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:718:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:727:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum TS_PORT') [-Wenum-enum-conversion]
drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:737:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum TS_PORT') [-Wenum-enum-conversion]
drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:749:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum TS_PORT') [-Wenum-enum-conversion]

Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
---
 drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
index 5bc44f194d0a..62ffa16bb82c 100644
--- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
@@ -57,19 +57,17 @@ enum USB_SPEED{
 };
 
 #define TS_MASK         0x6
-enum TS_PORT{
-	NO_TS_PORT = 0x0,	/* 2'b00: Neither port used. PCB not a Hybrid,
+#define NO_TS_PORT	0x0	/* 2'b00: Neither port used. PCB not a Hybrid,
 				   only offers Analog TV or Video */
-	TS1_PORT = 0x4,		/* 2'b10: TS1 Input (Hybrid mode :
+#define TS1_PORT	0x4	/* 2'b10: TS1 Input (Hybrid mode :
 				Digital or External Analog/Compressed source) */
-	TS1_TS2_PORT = 0x6,	/* 2'b11: TS1 & TS2 Inputs
+#define TS1_TS2_PORT	0x6	/* 2'b11: TS1 & TS2 Inputs
 				(Dual inputs from Digital and/or
 				External Analog/Compressed sources) */
-	TS1_EXT_CLOCK = 0x6,	/* 2'b11: TS1 & TS2 as selector
+#define TS1_EXT_CLOCK	0x6	/* 2'b11: TS1 & TS2 as selector
 						to external clock */
-	TS1VIP_TS2_PORT = 0x2	/* 2'b01: TS1 used as 656/VIP Output,
+#define TS1VIP_TS2_PORT 0x2	/* 2'b01: TS1 used as 656/VIP Output,
 				   TS2 Input (from Compressor) */
-};
 
 #define EAVP_MASK       0x8
 enum EAV_PRESENT{
@@ -89,10 +87,8 @@ enum AT_MODE{
 };
 
 #define PWR_SEL_MASK    0x40
-enum POWE_TYPE{
-	SELF_POWER = 0x0,	/* 0: self power */
-	BUS_POWER = 0x40	/* 1: bus power */
-};
+#define SELF_POWER	0x0	/* 0: self power */
+#define BUS_POWER	0x40	/* 1: bus power */
 
 enum USB_POWE_TYPE{
 	USB_SELF_POWER = 0,

-- 
2.47.0.338.g60cca15819-goog



From ribalda at chromium.org  Mon Dec  2 07:47:16 2024
From: ribalda at chromium.org (Ricardo Ribalda)
Date: Mon, 02 Dec 2024 15:47:16 +0000
Subject: [PATCH 2/3] media: atomisp: Use the actual value of the enum
 instead of the enum
In-Reply-To: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
References: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
Message-ID: <20241202-fix-llvm9-v1-2-2a50f5acfd0b@chromium.org>

hrt_isp_css_irq_sw_pin_0 has a different enum type than
irq_sw_channel_id_t.

Replace it with the actual value of hrt_isp_css_irq_sw_pin_0 to avoid
arithmetic operations between different enum types (and make the
compiler happy).

It is required to build with llvm 9 without these warnings:
drivers/staging/media/atomisp/pci/sh_css_hrt.c:68:19: warning: arithmetic between different enumeration types ('irq_sw_channel_id_t' and 'enum hrt_isp_css_irq') [-Wenum-enum-conversion]
drivers/staging/media/atomisp/pci/sh_css.c:1233:40: warning: arithmetic between different enumeration types ('irq_sw_channel_id_t' and 'enum hrt_isp_css_irq') [-Wenum-enum-conversion]
drivers/staging/media/atomisp/pci/sh_css.c:1237:40: warning: arithmetic between different enumeration types ('irq_sw_channel_id_t' and 'enum hrt_isp_css_irq') [-Wenum-enum-conversion]
ro

Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
---
 drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h
index 2c47e7820bd7..69e68ecd6bc3 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h
@@ -18,7 +18,7 @@
 #endif
 
 /* The IRQ is not mapped uniformly on its related interfaces */
-#define	IRQ_SW_CHANNEL_OFFSET	hrt_isp_css_irq_sw_pin_0
+#define	IRQ_SW_CHANNEL_OFFSET	HIVE_GP_DEV_IRQ_SW_PIN_0_BIT_ID
 
 typedef enum {
 	IRQ_SW_CHANNEL0_ID = hrt_isp_css_irq_sw_pin_0 - IRQ_SW_CHANNEL_OFFSET,

-- 
2.47.0.338.g60cca15819-goog



From ribalda at chromium.org  Mon Dec  2 07:47:17 2024
From: ribalda at chromium.org (Ricardo Ribalda)
Date: Mon, 02 Dec 2024 15:47:17 +0000
Subject: [PATCH 3/3] media: mediatek: vcodec: Workaround a compiler warning
In-Reply-To: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
References: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
Message-ID: <20241202-fix-llvm9-v1-3-2a50f5acfd0b@chromium.org>

llvm identifies that the SCP_IPI_VENC_H264 and IPI_VENC_H264 are from
the same enum type, but their are part of the same ternary operator.

vpu_inst.id is of type int, so we can just rewrite a bit the code and
avoid the following llvm9 warning:
drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c:597:29: warning: conditional expression between different enumeration types ('enum scp_ipi_id' and 'enum ipi_id') [-Wenum-compare-conditional]

Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
---
 drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
index f8145998fcaf..4786062e879a 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
@@ -584,7 +584,6 @@ static void h264_encode_filler(struct venc_h264_inst *inst, void *buf,
 
 static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx)
 {
-	const bool is_ext = MTK_ENC_CTX_IS_EXT(ctx);
 	int ret = 0;
 	struct venc_h264_inst *inst;
 
@@ -594,7 +593,10 @@ static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx)
 
 	inst->ctx = ctx;
 	inst->vpu_inst.ctx = ctx;
-	inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264;
+	if (MTK_ENC_CTX_IS_EXT(ctx))
+		inst->vpu_inst.id = SCP_IPI_VENC_H264;
+	else
+		inst->vpu_inst.id = IPI_VENC_H264;
 	inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx->dev->reg_base, VENC_SYS);
 
 	ret = vpu_enc_init(&inst->vpu_inst);

-- 
2.47.0.338.g60cca15819-goog



From tabba at google.com  Mon Dec  2 07:47:27 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon,  2 Dec 2024 15:47:27 +0000
Subject: [PATCH v4 00/14] KVM: arm64: Rework guest VM fixed feature handling
 and trapping in pKVM
Message-ID: <20241202154742.3611749-1-tabba@google.com>

Changes from v3 (Marc):
- Reduce churn from patch reworking SVE checks
- Fold in vcpu config flag renumbering patch

This patch series redoes how fixed features for protected guests
are specified in pKVM, as well as how trapping is handled based
on the features available for the VM. It also fixes a couple of
existing bugs in the process.

For protected VMs, some features should be trapped if the guest
tries to use them because they are not supported (e.g., SME), or
if they are not enabled for the particular VM (e.g., SVE).

Initially, pKVM took the approach of specifying these features
using macros and grouping their handling by feature id register.
This proved to be difficult to maintainbug prone. Moreover, since
the nested virt work there is a framework in KVM for storing
feature id register values per vm, as well as how to handle traps
based on these values.

This patch series uses the vm's feature id registers to track the
supported features, a framework similar to nested virt to set the
trap values, and removes the need to store cptr_el2 per vcpu in
favor of setting its value when traps are activated, as VHE mode
does.

The changes should not affect the behavior of non-protected VMs
nor the behavior of VMs outside of protected mode in general.

This series is based on kvmarm/next (60ad25e14ab5), since it
requires the patches from the series that fixes initialization of
trap register values in pKVM [2].

Cheers,
/fuad

[1] https://lore.kernel.org/all/20241128123515.1709777-1-tabba at google.com/
[2] https://lore.kernel.org/all/20241018074833.2563674-1-tabba at google.com/

Fuad Tabba (14):
  KVM: arm64: Consolidate allowed and restricted VM feature checks
  KVM: arm64: Group setting traps for protected VMs by control register
  KVM: arm64: Move checking protected vcpu features to a separate
    function
  KVM: arm64: Use KVM extension checks for allowed protected VM
    capabilities
  KVM: arm64: Initialize feature id registers for protected VMs
  KVM: arm64: Set protected VM traps based on its view of feature
    registers
  KVM: arm64: Rework specifying restricted features for protected VMs
  KVM: arm64: Remove fixed_config.h header
  KVM: arm64: Remove redundant setting of HCR_EL2 trap bit
  KVM: arm64: Calculate cptr_el2 traps on activating traps
  KVM: arm64: Refactor kvm_reset_cptr_el2()
  KVM: arm64: Fix the value of the CPTR_EL2 RES1 bitmask for nVHE
  KVM: arm64: Remove PtrAuth guest vcpu flag
  KVM: arm64: Convert the SVE guest vcpu flag to a vm flag

 arch/arm64/include/asm/kvm_arm.h              |   2 +-
 arch/arm64/include/asm/kvm_emulate.h          |  29 +-
 arch/arm64/include/asm/kvm_host.h             |  25 +-
 arch/arm64/include/asm/kvm_pkvm.h             |  25 ++
 arch/arm64/kvm/arm.c                          |  30 +-
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h | 223 ----------
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |   5 +
 arch/arm64/kvm/hyp/nvhe/pkvm.c                | 335 +++++----------
 arch/arm64/kvm/hyp/nvhe/setup.c               |   1 -
 arch/arm64/kvm/hyp/nvhe/switch.c              |  52 ++-
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            | 402 ++++++++++--------
 arch/arm64/kvm/reset.c                        |   6 +-
 12 files changed, 435 insertions(+), 700 deletions(-)
 delete mode 100644 arch/arm64/kvm/hyp/include/nvhe/fixed_config.h


base-commit: 60ad25e14ab5a4e56c8bf7f7d6846eacb9cd53df
-- 
2.47.0.338.g60cca15819-goog



From yang at os.amperecomputing.com  Mon Dec  2 08:22:57 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Mon, 2 Dec 2024 08:22:57 -0800
Subject: [GIT PULL] arm64 updates for 6.13-rc1
In-Reply-To: <e6b3e6c7-193d-43c4-a8c6-6023458723dd@redhat.com>
References: <20241118100623.2674026-1-catalin.marinas@arm.com>
 <Z0STR6VLt2MCalnY@sashalap> <Z0TLhc3uxa5RnK64@arm.com>
 <0c09425b-c8ba-4ed6-b429-0bce4e7d00e9@os.amperecomputing.com>
 <Z0dhc-DtVsvufv-E@arm.com>
 <dc5e8809-825f-4c38-b487-b16c7d516311@os.amperecomputing.com>
 <e6b3e6c7-193d-43c4-a8c6-6023458723dd@redhat.com>
Message-ID: <6aec1d44-4a89-4acf-a16b-4493626b93bb@os.amperecomputing.com>



On 11/28/24 1:56 AM, David Hildenbrand wrote:
> On 28.11.24 02:21, Yang Shi wrote:
>>>> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
>>>> index 87b3f1a25535..ef303a2262c5 100644
>>>> --- a/arch/arm64/mm/copypage.c
>>>> +++ b/arch/arm64/mm/copypage.c
>>>> @@ -30,9 +30,9 @@ void copy_highpage(struct page *to, struct page 
>>>> *from)
>>>> ??????? if (!system_supports_mte())
>>>> ??????????? return;
>>>> -??? if (folio_test_hugetlb(src) &&
>>>> -??????? folio_test_hugetlb_mte_tagged(src)) {
>>>> -??????? if (!folio_try_hugetlb_mte_tagging(dst))
>>>> +??? if (folio_test_hugetlb(src)) {
>>>> +??????? if (!folio_test_hugetlb_mte_tagged(src) ||
>>>> +??????????? !folio_try_hugetlb_mte_tagging(dst))
>>>> ??????????????? return;
>>>> ??????????? /*
>>> I wonder why we had a 'return' here originally rather than a
>>> WARN_ON_ONCE() as we do further down for the page case. Do you seen any
>>> issue with the hunk below? Destination should be a new folio and not
>>> tagged yet:
>>
>> Yes, I did see problem. Because we copy tags for all sub pages then set
>> folio mte tagged when copying the data for the first subpage. The
>> warning will be triggered when we copy the second subpage.
>
> It's rather weird, though. We're instructed to copy a single page, yet 
> copy tags for all pages.
>
> This really only makes sense when called from folio_copy(), where we 
> are guaranteed to copy all pages.
>
> I'm starting to wonder if we should be able to hook into / overload 
> folio_copy() instead, to just handle the complete hugetlb copy 
> ourselves in one shot, and assume that copy_highpage() will never be 
> called for hugetlb pages (WARN and don't copy tags).

Actually folio_copy() is just called by migration. Copy huge page in CoW 
is more complicated and uses copy_user_highpage()->copy_highpage() 
instead of folio_copy(). It may start the page copy from any subpage. 
For example, if the CoW is triggered by accessing to the address in the 
middle of 2M. Kernel may copy the second half first then the first half 
to guarantee the accessed data in cache.



From nathan at kernel.org  Mon Dec  2 08:24:54 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Mon, 2 Dec 2024 09:24:54 -0700
Subject: [PATCH 3/3] media: mediatek: vcodec: Workaround a compiler
 warning
In-Reply-To: <20241202-fix-llvm9-v1-3-2a50f5acfd0b@chromium.org>
References: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
 <20241202-fix-llvm9-v1-3-2a50f5acfd0b@chromium.org>
Message-ID: <20241202162454.GA2848026@thelio-3990X>

 Mon, Dec 02, 2024 at 03:47:17PM +0000, Ricardo Ribalda wrote:
> llvm identifies that the SCP_IPI_VENC_H264 and IPI_VENC_H264 are from
> the same enum type, but their are part of the same ternary operator.
> 
> vpu_inst.id is of type int, so we can just rewrite a bit the code and
> avoid the following llvm9 warning:

LLVM 19, not LLVM 9, as the minimum version for building the kernel is
LLVM 13.

> drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c:597:29: warning: conditional expression between different enumeration types ('enum scp_ipi_id' and 'enum ipi_id') [-Wenum-compare-conditional]
> 
> Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>

Reviewed-by: Nathan Chancellor <nathan at kernel.org>

FYI, Arnd basically sent the same patch October 18 but I guess it has
not been picked up?

https://lore.kernel.org/20241018152127.3958436-1-arnd at kernel.org/

Hopefully the new media committers model will help patches like that get
picked up in a more timely manner.

> ---
>  drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
> index f8145998fcaf..4786062e879a 100644
> --- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
> +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
> @@ -584,7 +584,6 @@ static void h264_encode_filler(struct venc_h264_inst *inst, void *buf,
>  
>  static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx)
>  {
> -	const bool is_ext = MTK_ENC_CTX_IS_EXT(ctx);
>  	int ret = 0;
>  	struct venc_h264_inst *inst;
>  
> @@ -594,7 +593,10 @@ static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx)
>  
>  	inst->ctx = ctx;
>  	inst->vpu_inst.ctx = ctx;
> -	inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264;
> +	if (MTK_ENC_CTX_IS_EXT(ctx))
> +		inst->vpu_inst.id = SCP_IPI_VENC_H264;
> +	else
> +		inst->vpu_inst.id = IPI_VENC_H264;
>  	inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx->dev->reg_base, VENC_SYS);
>  
>  	ret = vpu_enc_init(&inst->vpu_inst);
> 
> -- 
> 2.47.0.338.g60cca15819-goog
> 


From geert+renesas at glider.be  Mon Dec  2 08:30:07 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon,  2 Dec 2024 17:30:07 +0100
Subject: [PATCH 1/5] dt-bindings: soc: renesas: Move R8A779G0 White Hawk up
In-Reply-To: <cover.1733156661.git.geert+renesas@glider.be>
References: <cover.1733156661.git.geert+renesas@glider.be>
Message-ID: <d553ef4b1f969f72e384f274d42ac7a62fe45fd4.1733156661.git.geert+renesas@glider.be>

Move the R8A779G0-only White Hawk board stack section up, just below the
R8A779G0-only White Hawk CPU section, to improve sort order.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 .../devicetree/bindings/soc/renesas/renesas.yaml     | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
index b7acb65bdecd2a38..dab6667970325dcd 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
@@ -360,6 +360,12 @@ properties:
               - renesas,white-hawk-cpu # White Hawk CPU board (RTP8A779G0ASKB0FC0SA000)
           - const: renesas,r8a779g0
 
+      - items:
+          - enum:
+              - renesas,white-hawk-breakout # White Hawk BreakOut board (RTP8A779G0ASKB0SB0SA000)
+          - const: renesas,white-hawk-cpu
+          - const: renesas,r8a779g0
+
       - description: R-Car V4H (R8A779G2)
         items:
           - enum:
@@ -367,12 +373,6 @@ properties:
           - const: renesas,r8a779g2
           - const: renesas,r8a779g0
 
-      - items:
-          - enum:
-              - renesas,white-hawk-breakout # White Hawk BreakOut board (RTP8A779G0ASKB0SB0SA000)
-          - const: renesas,white-hawk-cpu
-          - const: renesas,r8a779g0
-
       - description: R-Car V4M (R8A779H0)
         items:
           - enum:
-- 
2.34.1



From fnkl.kernel at gmail.com  Mon Dec  2 08:36:28 2024
From: fnkl.kernel at gmail.com (Sasha Finkelstein)
Date: Mon, 2 Dec 2024 17:36:28 +0100
Subject: [PATCH] dmaengine: apple-admac: Avoid accessing registers in probe
In-Reply-To: <Z03f08Os/csGbMap@vaman>
References: <20241124-admac-power-v1-1-58f2165a4d55@gmail.com> <Z03f08Os/csGbMap@vaman>
Message-ID: <CAMT+MTTFkVcZHoC77BAVc+R_rvDfhoSQZujic9SCCqb8OkgSew@mail.gmail.com>

On Mon, 2 Dec 2024 at 17:27, Vinod Koul <vkoul at kernel.org> wrote:
> So looking at the driver, there is code to turn power, so what ensures
> that power is up while we are in alloc callback

There are two devices that use admacs, mca, and aop, with aop
only having a downstream driver for now. Aop's admac is controlled
by aop firmware, which does the power switching. Naturally, that firmware
has it's own idea of how power is supposed to be managed, so we can't
sequence it in such a way that the relevant admac has power when we
are running probe().


From vkoul at kernel.org  Mon Dec  2 08:26:59 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 2 Dec 2024 21:56:59 +0530
Subject: [PATCH] dmaengine: apple-admac: Avoid accessing registers in
 probe
In-Reply-To: <20241124-admac-power-v1-1-58f2165a4d55@gmail.com>
References: <20241124-admac-power-v1-1-58f2165a4d55@gmail.com>
Message-ID: <Z03f08Os/csGbMap@vaman>

On 24-11-24, 16:48, Sasha Finkelstein via B4 Relay wrote:
> From: Sasha Finkelstein <fnkl.kernel at gmail.com>
> 
> The ADMAC attached to the AOP has complex power sequencing, and is
> power gated when the probe callback runs. Move the register reads
> to other functions, where we can guarantee that the hardware is
> switched on.

So looking at the driver, there is code to turn power, so what ensures
that power is up while we are in alloc callback

> 
> Fixes: 568aa6dd641f ("dmaengine: apple-admac: Allocate cache SRAM to channels")
> Signed-off-by: Sasha Finkelstein <fnkl.kernel at gmail.com>
> ---
>  drivers/dma/apple-admac.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c
> index 9588773dd2eb670a2f6115fdaef39a0e88248015..037ec38730cf980eee11ebb8ec17be7623879cf8 100644
> --- a/drivers/dma/apple-admac.c
> +++ b/drivers/dma/apple-admac.c
> @@ -153,6 +153,8 @@ static int admac_alloc_sram_carveout(struct admac_data *ad,
>  {
>  	struct admac_sram *sram;
>  	int i, ret = 0, nblocks;

Empty line before this please

> +	ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
> +	ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
>  
>  	if (dir == DMA_MEM_TO_DEV)
>  		sram = &ad->txcache;
> @@ -912,12 +914,7 @@ static int admac_probe(struct platform_device *pdev)
>  		goto free_irq;
>  	}
>  
> -	ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
> -	ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
> -
>  	dev_info(&pdev->dev, "Audio DMA Controller\n");
> -	dev_info(&pdev->dev, "imprint %x TX cache %u RX cache %u\n",
> -		 readl_relaxed(ad->base + REG_IMPRINT), ad->txcache.size, ad->rxcache.size);
>  
>  	return 0;
>  
> 
> ---
> base-commit: 9f16d5e6f220661f73b36a4be1b21575651d8833
> change-id: 20241124-admac-power-7f32c2a1850a
> 

-- 
~Vinod


From geert+renesas at glider.be  Mon Dec  2 08:30:11 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon,  2 Dec 2024 17:30:11 +0100
Subject: [PATCH 5/5] arm64: dts: renesas: r8a779g3: Add White Hawk Single support
In-Reply-To: <cover.1733156661.git.geert+renesas@glider.be>
References: <cover.1733156661.git.geert+renesas@glider.be>
Message-ID: <66d0fe78c393e6df2775287c730464e91732ec56.1733156661.git.geert+renesas@glider.be>

The White Hawk Single board with R-Car V4H ES3.0 (R8A779G3) uses an
updated version of the R-Car V4H (R8A779G0) SoC.

For now, there are no visible differences compared to the variant
equipped with an R-Car V4H ES2.0 (R8A779G2) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/Makefile             |  2 ++
 .../dts/renesas/r8a779g3-white-hawk-single.dts   | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779g3-white-hawk-single.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 97228a3cb99c163d..df9ea5b2e20818f4 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -92,6 +92,8 @@ dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-ard-audio-da7212.dtb
 
 dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g2-white-hawk-single.dtb
 
+dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-white-hawk-single.dtb
+
 dtb-$(CONFIG_ARCH_R8A779H0) += r8a779h0-gray-hawk-single.dtb
 
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-salvator-xs.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-white-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779g3-white-hawk-single.dts
new file mode 100644
index 0000000000000000..cd466d858854bf92
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779g3-white-hawk-single.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the R-Car V4H ES3.0 White Hawk Single board
+ *
+ * Copyright (C) 2024 Glider bv
+ */
+
+/dts-v1/;
+#include "r8a779g3.dtsi"
+#include "white-hawk-single.dtsi"
+
+/ {
+	model = "Renesas White Hawk Single board based on r8a779g3";
+	compatible = "renesas,white-hawk-single", "renesas,r8a779g3",
+		     "renesas,r8a779g0";
+};
-- 
2.34.1



From geert+renesas at glider.be  Mon Dec  2 08:30:09 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon,  2 Dec 2024 17:30:09 +0100
Subject: [PATCH 3/5] arm64: dts: renesas: Factor out White Hawk Single board support
In-Reply-To: <cover.1733156661.git.geert+renesas@glider.be>
References: <cover.1733156661.git.geert+renesas@glider.be>
Message-ID: <1661743b18a9ff9fac716f98a663b39fc8488d7e.1733156661.git.geert+renesas@glider.be>

Move the common parts for the Renesas White Hawk Single board to
white-hawk-single.dtsi, to enable future reuse.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 .../renesas/r8a779g2-white-hawk-single.dts    | 62 +------------------
 ...hawk-single.dts => white-hawk-single.dtsi} | 11 ++--
 2 files changed, 5 insertions(+), 68 deletions(-)
 copy arch/arm64/boot/dts/renesas/{r8a779g2-white-hawk-single.dts => white-hawk-single.dtsi} (78%)

diff --git a/arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts
index 0062362b0ba06885..48befde389376bf2 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts
+++ b/arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts
@@ -7,70 +7,10 @@
 
 /dts-v1/;
 #include "r8a779g2.dtsi"
-#include "white-hawk-cpu-common.dtsi"
-#include "white-hawk-common.dtsi"
+#include "white-hawk-single.dtsi"
 
 / {
 	model = "Renesas White Hawk Single board based on r8a779g2";
 	compatible = "renesas,white-hawk-single", "renesas,r8a779g2",
 		     "renesas,r8a779g0";
 };
-
-&hscif0 {
-	uart-has-rtscts;
-};
-
-&hscif0_pins {
-	groups = "hscif0_data", "hscif0_ctrl";
-	function = "hscif0";
-};
-
-&pfc {
-	tsn0_pins: tsn0 {
-		mux {
-			groups = "tsn0_link", "tsn0_mdio", "tsn0_rgmii",
-				 "tsn0_txcrefclk";
-			function = "tsn0";
-		};
-
-		link {
-			groups = "tsn0_link";
-			bias-disable;
-		};
-
-		mdio {
-			groups = "tsn0_mdio";
-			drive-strength = <24>;
-			bias-disable;
-		};
-
-		rgmii {
-			groups = "tsn0_rgmii";
-			drive-strength = <24>;
-			bias-disable;
-		};
-	};
-};
-
-&tsn0 {
-	pinctrl-0 = <&tsn0_pins>;
-	pinctrl-names = "default";
-	phy-mode = "rgmii";
-	phy-handle = <&phy3>;
-	status = "okay";
-
-	mdio {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		reset-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
-		reset-post-delay-us = <4000>;
-
-		phy3: ethernet-phy at 0 {
-			compatible = "ethernet-phy-id002b.0980",
-				     "ethernet-phy-ieee802.3-c22";
-			reg = <0>;
-			interrupts-extended = <&gpio4 3 IRQ_TYPE_LEVEL_LOW>;
-		};
-	};
-};
diff --git a/arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts b/arch/arm64/boot/dts/renesas/white-hawk-single.dtsi
similarity index 78%
copy from arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts
copy to arch/arm64/boot/dts/renesas/white-hawk-single.dtsi
index 0062362b0ba06885..20e8232f2f3234e2 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts
+++ b/arch/arm64/boot/dts/renesas/white-hawk-single.dtsi
@@ -1,19 +1,16 @@
 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
- * Device Tree Source for the R-Car V4H ES2.0 White Hawk Single board
+ * Device Tree Source for the White Hawk Single board
  *
- * Copyright (C) 2023 Glider bv
+ * Copyright (C) 2023-2024 Glider bv
  */
 
-/dts-v1/;
-#include "r8a779g2.dtsi"
 #include "white-hawk-cpu-common.dtsi"
 #include "white-hawk-common.dtsi"
 
 / {
-	model = "Renesas White Hawk Single board based on r8a779g2";
-	compatible = "renesas,white-hawk-single", "renesas,r8a779g2",
-		     "renesas,r8a779g0";
+	model = "Renesas White Hawk Single board";
+	compatible = "renesas,white-hawk-single";
 };
 
 &hscif0 {
-- 
2.34.1



From geert+renesas at glider.be  Mon Dec  2 08:30:10 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon,  2 Dec 2024 17:30:10 +0100
Subject: [PATCH 4/5] arm64: dts: renesas: Add R8A779G3 SoC support
In-Reply-To: <cover.1733156661.git.geert+renesas@glider.be>
References: <cover.1733156661.git.geert+renesas@glider.be>
Message-ID: <978c41f932aa2dccd46ad91fc1ddfabacd1c254c.1733156661.git.geert+renesas@glider.be>

Add support for the Renesas R-Car V4H ES3.0 (R8A779G3) SoC, which is an
updated version of the R-Car V4H (R8A779G0) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/r8a779g3.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779g3.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r8a779g3.dtsi b/arch/arm64/boot/dts/renesas/r8a779g3.dtsi
new file mode 100644
index 0000000000000000..0295858a02602295
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779g3.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the R-Car V4H (R8A779G3) SoC
+ *
+ * Copyright (C) 2024 Glider bv
+ */
+
+#include "r8a779g0.dtsi"
+
+/ {
+	compatible = "renesas,r8a779g3", "renesas,r8a779g0";
+};
-- 
2.34.1



From geert+renesas at glider.be  Mon Dec  2 08:30:08 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon,  2 Dec 2024 17:30:08 +0100
Subject: [PATCH 2/5] dt-bindings: soc: renesas: Document R8A779G3 White Hawk Single
In-Reply-To: <cover.1733156661.git.geert+renesas@glider.be>
References: <cover.1733156661.git.geert+renesas@glider.be>
Message-ID: <1d2d2a6cbf31c817f574f6eed310a960e6175afe.1733156661.git.geert+renesas@glider.be>

Document the compatible value for the Renesas R-Car V4H ES3.0
(R8A779G3) SoC, as used on the Renesas White Hawk Single board.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 .../devicetree/bindings/soc/renesas/renesas.yaml          | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
index dab6667970325dcd..0f3fa341fd87924b 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
@@ -366,11 +366,13 @@ properties:
           - const: renesas,white-hawk-cpu
           - const: renesas,r8a779g0
 
-      - description: R-Car V4H (R8A779G2)
+      - description: R-Car V4H (R8A779G[23])
         items:
           - enum:
-              - renesas,white-hawk-single # White Hawk Single board (RTP8A779G2ASKB0F10SA001)
-          - const: renesas,r8a779g2
+              - renesas,white-hawk-single # White Hawk Single board (RTP8A779G[23]ASKB0F10SA001)
+          - enum:
+              - renesas,r8a779g2
+              - renesas,r8a779g3
           - const: renesas,r8a779g0
 
       - description: R-Car V4M (R8A779H0)
-- 
2.34.1



From geert+renesas at glider.be  Mon Dec  2 08:30:06 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon,  2 Dec 2024 17:30:06 +0100
Subject: [PATCH 0/5] arm64: renesas: Add R8A779G3 White Hawk Single support
Message-ID: <cover.1733156661.git.geert+renesas@glider.be>

	Hi all,

This patch series adds support for the Renesas R-Car V4H ES3.0 (R8A779G3)
SoC on the Renesas White Hawk Single board.  R-Car V4H ES3.0 (R8A779G3)
is an updated version of R-Car V4H (R8A779G0).

I intend to queue these in renesas-devel for v6.14.
Thanks for your comments!

Geert Uytterhoeven (5):
  dt-bindings: soc: renesas: Move R8A779G0 White Hawk up
  dt-bindings: soc: renesas: Document R8A779G3 White Hawk Single
  arm64: dts: renesas: Factor out White Hawk Single board support
  arm64: dts: renesas: Add R8A779G3 SoC support
  arm64: dts: renesas: r8a779g3: Add White Hawk Single support

 .../bindings/soc/renesas/renesas.yaml         | 16 ++---
 arch/arm64/boot/dts/renesas/Makefile          |  2 +
 .../renesas/r8a779g2-white-hawk-single.dts    | 62 +------------------
 .../renesas/r8a779g3-white-hawk-single.dts    | 16 +++++
 arch/arm64/boot/dts/renesas/r8a779g3.dtsi     | 12 ++++
 ...hawk-single.dts => white-hawk-single.dtsi} | 11 ++--
 6 files changed, 44 insertions(+), 75 deletions(-)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779g3-white-hawk-single.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779g3.dtsi
 copy arch/arm64/boot/dts/renesas/{r8a779g2-white-hawk-single.dts => white-hawk-single.dtsi} (78%)

-- 
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 yang at os.amperecomputing.com  Mon Dec  2 08:41:08 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Mon, 2 Dec 2024 08:41:08 -0800
Subject: [PATCH] arm64: mm: fix zone_dma_limit calculation
In-Reply-To: <Z0oYMXMGYgXoyon7@arm.com>
References: <20241125171650.77424-1-yang@os.amperecomputing.com>
 <87ttbu8q7s.fsf@tarshish>
 <98583682-a95e-440e-bd89-03828998b48e@os.amperecomputing.com>
 <Z0dbsRCsWT3hiVds@arm.com> <7720d275-bc52-49c3-949a-6a6a32157418@arm.com>
 <Z0oYMXMGYgXoyon7@arm.com>
Message-ID: <c1b5a5de-94b0-4b27-a597-a34e84c3ef08@os.amperecomputing.com>



On 11/29/24 11:38 AM, Catalin Marinas wrote:
> On Fri, Nov 29, 2024 at 06:06:50PM +0000, Robin Murphy wrote:
>> On 2024-11-27 5:49 pm, Catalin Marinas wrote:
>>> If IORT or DT indicate a large mask covering the whole RAM (i.e. no
>>> restrictions), in an ideal world, we should normally extend ZONE_DMA to
>>> the same.
>> That's not right, ZONE_DMA should still be relatively limited in size
>> (unless we really do only have a tiny amount of RAM) - just because a DT
>> dma-ranges property says the system interconnect can carry >32 address bits
>> in general doesn't mean that individual device DMA masks can't still be
>> 32-bit or smaller. IIRC we're still implicitly assuming that if DT does
>> describe an offset range into "high" RAM, it must represent a suitable
>> lowest common denominator for all relevant devices already, and therefore we
>> can get away with sizing ZONE_DMA off it blindly.
> Fine by me to keep ZONE_DMA in the low range always. I was thinking of
> only doing this if ZONE_DMA32 is enabled.
>
>> After staring at it for long enough, I think $SUBJECT patch is actually
>> correct as it is.
> Thanks Robin for having a look. Can I add your reviewed-by?
>
>> In fact I'm now wondering why the fix was put inside
>> max_zone_phys() in the first place, since it's clearly pointless to clamp
>> DMA_BIT_MASK(32) to U32_MAX in the dma32_phys_limit case...
> I came to the same conclusion. I think it might have been some left-over
> from when we had a ZONE_DMA32 in the above 4GB (AMD Seattle?). Than we
> changed it a few times but only focused on this function for setting the
> limits.
>
>> However the commit message is perhaps not as clear as it could be -
>> technically we are correctly *calculating* the appropriate effective
>> zone_dma_limt value within the scope of zone_sizes_init(), we're just
>> failing to properly update the actual zone_dma_limit variable for the
>> benefit of other users.
> I'll have a look next week at rewriting the commit message, unless Yang
> does it first. I'm planning to queue this patch for -rc2.

Hi Catalin and Robin,

Thanks for moving this forward.

How's about the below commit message?

We failed to properly update the actual zone_dma_limit variable. Now it is
the memsize limit in IORT or device tree instead of U32_MAX if the 
memsize limit
is greater than U32_MAX.

The zone_dma_limit is used to determine whether GFP_DMA should be used 
or not
when allocating DMA buffers.? The wrong zone_dma_limit resulted in DMA 
allocations
use GFP_DMA even though the devices don't require it then fall into DMA 
zone on
node 0.? It caused regression on our two sockets systems due to 
excessive remote
memory access.

>



From nicolas.ferre at microchip.com  Mon Dec  2 08:44:28 2024
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Mon, 2 Dec 2024 17:44:28 +0100
Subject: [PATCH] ARM: at91: pm: change BU Power Switch to automatic mode
In-Reply-To: <34a5b77b-e732-4393-a469-d9c719afa879@tuxon.dev>
References: <20241125165648.509162-1-nicolas.ferre@microchip.com>
 <34a5b77b-e732-4393-a469-d9c719afa879@tuxon.dev>
Message-ID: <24069031-9ed4-4592-af98-ff53222caf03@microchip.com>

On 02/12/2024 at 09:05, Claudiu Beznea wrote:
> Hi, Nicolas,
> 
> On 25.11.2024 18:56, nicolas.ferre at microchip.com wrote:
>> From: Nicolas Ferre <nicolas.ferre at microchip.com>
>>
>> Change how the Backup Unit Power is configured and force the
>> automatic/hardware mode.
>> This change eliminates the need for software management of the power
>> switch, ensuring it transitions to the backup power source before
>> entering low power modes.
>>
>> This is done in the only locaton where this swich was configured. It's
> 
> s/locaton/location
> 
>> usually done in the bootloader.
>>
>> Previously, the loss of the VDDANA (or VDDIN33) power source was not
>> automatically compensated by an alternative power source. This resulted
>> in the loss of Backup Unit content, including Backup Self-refresh low
>> power mode information, OTP emulation configuration, and boot
>> configuration, for instance.
> 
> Should we add a fixes for this?

Not so easy to tell as there's a loose dependency with the bootloader. 
But it's true that switching to automatic never harm. So probably yes.

>> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
>> ---
>>   arch/arm/mach-at91/pm.c | 31 ++++++++++++++++++++-----------
>>   1 file changed, 20 insertions(+), 11 deletions(-)
>>
>> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
>> index b9b995f8a36e..05a1547642b6 100644
>> --- a/arch/arm/mach-at91/pm.c
>> +++ b/arch/arm/mach-at91/pm.c
>> @@ -598,7 +598,21 @@ static int at91_suspend_finish(unsigned long val)
>>        return 0;
>>   }
>>
>> -static void at91_pm_switch_ba_to_vbat(void)
>> +/**
>> + * at91_pm_switch_ba_to_auto() - Configure Backup Unit Power Switch
>> + * to automatic/hardware mode.
>> + *
>> + * The Backup Unit Power Switch can be managed either by software or hardware.
>> + * Enabling hardware mode allows the automatic transition of power between
>> + * VDDANA (or VDDIN33) and VDDBU (or VBAT, respectively), based on the
>> + * availability of these power sources.
>> + *
>> + * If the Backup Unit Power Switch is already in automatic mode, no action is
>> + * required. If it is in software-controlled mode, it is switched to automatic
>> + * mode to enhance safety and eliminate the need for toggling between power
>> + * sources.
>> + */
>> +static void at91_pm_switch_ba_to_auto(void)
>>   {
>>        unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu);
>>        unsigned int val;
>> @@ -609,24 +623,19 @@ static void at91_pm_switch_ba_to_vbat(void)
>>
>>        val = readl(soc_pm.data.sfrbu + offset);
>>
>> -     /* Already on VBAT. */
>> -     if (!(val & soc_pm.sfrbu_regs.pswbu.state))
>> +     /* Already on auto/hardware. */
>> +     if (!(val & soc_pm.sfrbu_regs.pswbu.ctrl))
>>                return;
>>
>> -     val &= ~soc_pm.sfrbu_regs.pswbu.softsw;
> 
> It seems that softsw and state members of at91_pm_sfrbu_regs.pswbu along
> with their initialization could be dropped. What do you think?

I think that I tried when writing the patch but I think that there's a 
little difference with sama5d2 register layout. Give me a couple more 
days to come back to this and verify.

> I can do it while applying, if any.
> 
> Thank you,
> Claudiu
> 
> 
>> -     val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl;
>> +     val &= ~soc_pm.sfrbu_regs.pswbu.ctrl;
>> +     val |= soc_pm.sfrbu_regs.pswbu.key;
>>        writel(val, soc_pm.data.sfrbu + offset);
>> -
>> -     /* Wait for update. */
>> -     val = readl(soc_pm.data.sfrbu + offset);
>> -     while (val & soc_pm.sfrbu_regs.pswbu.state)
>> -             val = readl(soc_pm.data.sfrbu + offset);
>>   }
>>
>>   static void at91_pm_suspend(suspend_state_t state)
>>   {
>>        if (soc_pm.data.mode == AT91_PM_BACKUP) {
>> -             at91_pm_switch_ba_to_vbat();
>> +             at91_pm_switch_ba_to_auto();
>>
>>                cpu_suspend(0, at91_suspend_finish);
>>



From broonie at kernel.org  Mon Dec  2 08:51:07 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 02 Dec 2024 16:51:07 +0000
Subject: (subset) [PATCH 1/3] dt-bindings: misc: lwn,bk4-spi: Add
 binding
In-Reply-To: <20241023120015.1049008-1-festevam@gmail.com>
References: <20241023120015.1049008-1-festevam@gmail.com>
Message-ID: <173315826769.126887.7195905602758530196.b4-ty@kernel.org>

On Wed, 23 Oct 2024 09:00:13 -0300, Fabio Estevam wrote:
> Add a lwn,bk4-spi.yaml binding for Liebherr's BK4 external SPI controller.
> 
> Currently, the compatible string used for this device is "lwn,bk4",
> which is the same as the board compatible string documented at fsl.yaml.
> 
> This causes several dt-schema warnings:
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/3] dt-bindings: misc: lwn,bk4-spi: Add binding
      commit: 36e7886075262429158aec6f258e6a5a92f025b1
[2/3] spi: spidev: Add an entry for lwn,bk4-spi
      commit: 096c34ddf5835f02f5260719cd8a16fcf5e5e56f

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  Mon Dec  2 08:51:04 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 02 Dec 2024 16:51:04 +0000
Subject: [PATCH] spi: rockchip-sfc: Support ACPI
In-Reply-To: <20241120012208.1193034-1-jon.lin@rock-chips.com>
References: <20241120012208.1193034-1-jon.lin@rock-chips.com>
Message-ID: <173315826479.126887.9104664888049077624.b4-ty@kernel.org>

On Wed, 20 Nov 2024 09:22:08 +0800, Jon Lin wrote:
> Compatible with ACPI.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: rockchip-sfc: Support ACPI
      commit: e39531352aed30156b270a61ba075e5b8d3b8498

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 vkoul at kernel.org  Mon Dec  2 08:52:47 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 2 Dec 2024 22:22:47 +0530
Subject: [PATCH V5 2/9] dmaengine: bcm2835-dma: add suspend/resume pm
 support
In-Reply-To: <20241025103621.4780-3-wahrenst@gmx.net>
References: <20241025103621.4780-1-wahrenst@gmx.net>
 <20241025103621.4780-3-wahrenst@gmx.net>
Message-ID: <Z03l308ur7xuE1SB@vaman>

On 25-10-24, 12:36, Stefan Wahren wrote:
> bcm2835-dma provides the service to others, so it should
> suspend late and resume early.
> 
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
> ---
>  drivers/dma/bcm2835-dma.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index e1b92b4d7b05..647dda9f3376 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -875,6 +875,35 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
>  	return chan;
>  }
> 
> +static int bcm2835_dma_suspend_late(struct device *dev)
> +{
> +	struct bcm2835_dmadev *od = dev_get_drvdata(dev);
> +	struct bcm2835_chan *c, *next;
> +
> +	list_for_each_entry_safe(c, next, &od->ddev.channels,
> +				 vc.chan.device_node) {
> +		void __iomem *chan_base = c->chan_base;
> +
> +		if (readl(chan_base + BCM2835_DMA_ADDR)) {
> +			dev_warn(dev, "Suspend is prevented by chan %d\n",
> +				 c->ch);
> +			return -EBUSY;
> +		}

Can you help understand how this helps by logging... we are not adding
anything except checking this and resume is NOP as well!

> +	}
> +
> +	return 0;
> +}
> +
> +static int bcm2835_dma_resume_early(struct device *dev)
> +{
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops bcm2835_dma_pm_ops = {
> +	SET_LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late,
> +				     bcm2835_dma_resume_early)
> +};
> +
>  static int bcm2835_dma_probe(struct platform_device *pdev)
>  {
>  	struct bcm2835_dmadev *od;
> @@ -1033,6 +1062,7 @@ static struct platform_driver bcm2835_dma_driver = {
>  	.driver = {
>  		.name = "bcm2835-dma",
>  		.of_match_table = of_match_ptr(bcm2835_dma_of_match),
> +		.pm = pm_ptr(&bcm2835_dma_pm_ops),
>  	},
>  };
> 
> --
> 2.34.1

-- 
~Vinod


From florian.fainelli at broadcom.com  Mon Dec  2 08:56:59 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Mon, 2 Dec 2024 08:56:59 -0800
Subject: [PATCH] irqchip/bcm2836: Enable SKIP_SET_WAKE and MASK_ON_SUSPEND
In-Reply-To: <20241202115437.33552-1-wahrenst@gmx.net>
References: <20241202115437.33552-1-wahrenst@gmx.net>
Message-ID: <10f3e9a9-187e-4c1e-9e1c-9885da4ace79@broadcom.com>

On 12/2/24 03:54, Stefan Wahren wrote:
> The BCM2836 interrupt controller doesn't provide any facility to
> configure the wakeup sources. That's the reason why the driver lacks
> the irq_set_wake() callback for the interrupt chip.
> 
> Enable the flags IRQCHIP_SKIP_SET_WAKE and IRQCHIP_MASK_ON_SUSPEND so
> the interrupt suspend logic can handle the chip correctly.
> 
> This was inspired by the patch series "irqchip/irq-bcm283x update
> for BCM7211" by Florian Fainelli.
> 
> Link: https://lore.kernel.org/lkml/20191001224842.9382-1-f.fainelli at gmail.com/
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>

Acked-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From mark.rutland at arm.com  Mon Dec  2 09:03:59 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Dec 2024 17:03:59 +0000
Subject: [PATCH] arm64: patching: avoid early page_to_phys()
Message-ID: <20241202170359.1475019-1-mark.rutland@arm.com>

When arm64 is configured with CONFIG_DEBUG_VIRTUAL=y, a warning is
printed from the patching code because patch_map(), e.g.

| ------------[ cut here ]------------
| WARNING: CPU: 0 PID: 0 at arch/arm64/kernel/patching.c:45 patch_map.constprop.0+0x120/0xd00
| CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.13.0-rc1-00002-ge1a5d6c6be55 #1
| Hardware name: linux,dummy-virt (DT)
| pstate: 800003c5 (Nzcv DAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
| pc : patch_map.constprop.0+0x120/0xd00
| lr : patch_map.constprop.0+0x120/0xd00
| sp : ffffa9bb312a79a0
| x29: ffffa9bb312a79a0 x28: 0000000000000001 x27: 0000000000000001
| x26: 0000000000000000 x25: 0000000000000000 x24: 00000000000402e8
| x23: ffffa9bb2c94c1c8 x22: ffffa9bb2c94c000 x21: ffffa9bb222e883c
| x20: 0000000000000002 x19: ffffc1ffc100ba40 x18: ffffa9bb2cf0f21c
| x17: 0000000000000006 x16: 0000000000000000 x15: 0000000000000004
| x14: 1ffff5376625b4ac x13: ffff753766a67fb8 x12: ffff753766919cd1
| x11: 0000000000000003 x10: 1ffff5376625b4c3 x9 : 1ffff5376625b4af
| x8 : ffff753766254f0a x7 : 0000000041b58ab3 x6 : ffff753766254f18
| x5 : ffffa9bb312d9bc0 x4 : 0000000000000000 x3 : ffffa9bb29bd90e4
| x2 : 0000000000000002 x1 : ffffa9bb312d9bc0 x0 : 0000000000000000
| Call trace:
|  patch_map.constprop.0+0x120/0xd00 (P)
|  patch_map.constprop.0+0x120/0xd00 (L)
|  __aarch64_insn_write+0xa8/0x120
|  aarch64_insn_patch_text_nosync+0x4c/0xb8
|  arch_jump_label_transform_queue+0x7c/0x100
|  jump_label_update+0x154/0x460
|  static_key_enable_cpuslocked+0x1d8/0x280
|  static_key_enable+0x2c/0x48
|  early_randomize_kstack_offset+0x104/0x168
|  do_early_param+0xe4/0x148
|  parse_args+0x3a4/0x838
|  parse_early_options+0x50/0x68
|  parse_early_param+0x58/0xe0
|  setup_arch+0x78/0x1f0
|  start_kernel+0xa0/0x530
|  __primary_switched+0x8c/0xa0
| irq event stamp: 0
| hardirqs last  enabled at (0): [<0000000000000000>] 0x0
| hardirqs last disabled at (0): [<0000000000000000>] 0x0
| softirqs last  enabled at (0): [<0000000000000000>] 0x0
| softirqs last disabled at (0): [<0000000000000000>] 0x0
| ---[ end trace 0000000000000000 ]---

The warning has been produced since commit:

  3e25d5a49f99b75b ("asm-generic: add an optional pfn_valid check to page_to_phys")

... which added a pfn_valid() check into page_to_phys(), and at this
point in boot pfn_valid() will always return false because the vmemmap
has not yet been initialized and there are no valid mem_sections yet.

Before that commit, the arithmetic performed by page_to_phys() would
give the expected physical address, though it is somewhat dubious to use
vmemmap addresses before the vmemmap has been initialized.

For historical reasons, the structure of patch_map() is more complicated
than necessary and can be simplified. For kernel image addresses it's
sufficient to use __pa_symbol() directly without converting this to a
page address and back. Aside from kernel image addresses, all executable
code should be allocated from execmem (where all allocations will fall
within the vmalloc area), and the vmalloc area), and so there's no need
for the fallback case when case when CONFIG_EXECMEM=n.

Simplify patch_map() accordingly, directly converting kernel image
addresses and removing the redundant fallback case.

Fixes: 3e25d5a49f99b75b ("asm-generic: add an optional pfn_valid check to page_to_phys")
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Christoph Hellwig <hch at lst.de>
Cc: Mike Rapoport <rppt at kernel.org>
Cc: Thomas Huth <thuth at redhat.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/patching.c | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

Catalin, Will, I wasn't sure whether we'd prefer this or an explicit
check that the address is a vmalloc addr, e.g.

	if (is_image_text(...)) {
		phys = ...;
	} else if (is_vmalloc_addr(...)) {
		phys = ...;
	} else {
		BUG();
	}

I went for the style below because it was marginally simpler, I'm more
than happy to respin as above if that's preferable.

Mark.

diff --git a/arch/arm64/kernel/patching.c b/arch/arm64/kernel/patching.c
index 7f99723fbb8c4..1041bc67a3eee 100644
--- a/arch/arm64/kernel/patching.c
+++ b/arch/arm64/kernel/patching.c
@@ -30,20 +30,17 @@ static bool is_image_text(unsigned long addr)
 
 static void __kprobes *patch_map(void *addr, int fixmap)
 {
-	unsigned long uintaddr = (uintptr_t) addr;
-	bool image = is_image_text(uintaddr);
-	struct page *page;
-
-	if (image)
-		page = phys_to_page(__pa_symbol(addr));
-	else if (IS_ENABLED(CONFIG_EXECMEM))
-		page = vmalloc_to_page(addr);
-	else
-		return addr;
-
-	BUG_ON(!page);
-	return (void *)set_fixmap_offset(fixmap, page_to_phys(page) +
-			(uintaddr & ~PAGE_MASK));
+	phys_addr_t phys;
+
+	if (is_image_text((unsigned long)addr)) {
+		phys = __pa_symbol(addr);
+	} else {
+		struct page *page = vmalloc_to_page(addr);
+		BUG_ON(!page);
+		phys = page_to_phys(page) + offset_in_page(addr);
+	}
+
+	return (void *)set_fixmap_offset(fixmap, phys);
 }
 
 static void __kprobes patch_unmap(int fixmap)
-- 
2.30.2



From didi.debian at cknow.org  Mon Dec  2 09:05:03 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Mon, 02 Dec 2024 18:05:03 +0100
Subject: [PATCH] arm64: dts: rockchip: Describe why is HWRNG disabled in
 RK356x base dtsi
In-Reply-To: <6b272e2f8f916c04b05db50df621659a5a7f29ab.1733149874.git.dsimic@manjaro.org>
References: <6b272e2f8f916c04b05db50df621659a5a7f29ab.1733149874.git.dsimic@manjaro.org>
Message-ID: <D61DMK8O9JCR.1C62A5UGI51BT@cknow.org>

Hi,

I'd have swapped 'is' and 'HWRNG' in the subject, but otherwise ...

On Mon Dec 2, 2024 at 3:44 PM CET, Dragan Simic wrote:
> Despite the presence of the hardware random number generator (HWRNG) in the
> different Rockchip RK356x SoC variants, it remains disabled for the RK3566
> SoC because testing showed [1] that it produces unacceptably low quality of
> random data, for some yet unknown reason.  The HWRNG is enabled for the RK3568
> SoC, on which the testing showed good quality of the generated random data.
>
> To avoid possible confusion in the future, [2] let's have this described
> briefly in the RK356x base SoC dtsi.
>
> [1] https://lore.kernel.org/linux-rockchip/cover.1720969799.git.daniel at makrotopia.org/T/#u
> [2] https://lore.kernel.org/linux-rockchip/20241201234613.52322-1-pbrobinson at gmail.com/T/#u
>
> Signed-off-by: Dragan Simic <dsimic at manjaro.org>
> ---
>  arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> index 62be06f3b863..ab8f42c0a843 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> @@ -1032,6 +1032,11 @@ sdhci: mmc at fe310000 {
>  		status = "disabled";
>  	};
>  
> +	/*
> +	 * Testing showed that the HWRNG found in RK3566 produces unacceptably
> +	 * low quality of random data, so the HWRNG isn't enabled for all RK356x
> +	 * SoC variants despite its presence.
> +	 */
>  	rng: rng at fe388000 {
>  		compatible = "rockchip,rk3568-rng";
>  		reg = <0x0 0xfe388000 0x0 0x4000>;

Reviewed-by: Diederik de Haas <didi.debian at cknow.org>

Thanks for 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/20241202/c7f35dca/attachment.sig>

From miquel.raynal at bootlin.com  Mon Dec  2 09:12:22 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 02 Dec 2024 18:12:22 +0100
Subject: [PATCH v9 2/2] mtd: rawnand: nuvoton: add new driver for the
 Nuvoton MA35 SoC
In-Reply-To: <20241125052524.135362-3-hpchen0nvt@gmail.com> (Hui-Ping Chen's
	message of "Mon, 25 Nov 2024 05:25:24 +0000")
References: <20241125052524.135362-1-hpchen0nvt@gmail.com>
	<20241125052524.135362-3-hpchen0nvt@gmail.com>
Message-ID: <875xo257rd.fsf@bootlin.com>

Hello,

> +static int ma35_nand_attach_chip(struct nand_chip *chip)
> +{
> +	struct ma35_nand_info *nand = nand_get_controller_data(chip);
> +	struct mtd_info *mtd = nand_to_mtd(chip);
> +	struct device *dev = mtd->dev.parent;
> +	u32 reg;
> +
> +	if (chip->options & NAND_BUSWIDTH_16) {
> +		dev_err(dev, "16 bits bus width not supported");
> +		return -EINVAL;
> +	}
> +
> +	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~PSIZE_MASK);
> +	if (mtd->writesize == 2048)
> +		writel(reg | PSIZE_2K, nand->regs + MA35_NFI_REG_NANDCTL);
> +	else if (mtd->writesize == 4096)
> +		writel(reg | PSIZE_4K, nand->regs + MA35_NFI_REG_NANDCTL);
> +	else if (mtd->writesize == 8192)
> +		writel(reg | PSIZE_8K, nand->regs + MA35_NFI_REG_NANDCTL);

You should error out if the writesize is not supported.

Thanks,
Miqu?l


From vkoul at kernel.org  Mon Dec  2 09:31:15 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 02 Dec 2024 23:01:15 +0530
Subject: [PATCH][next] dmaengine: xilinx: xdma: remove redundant check
 on ret
In-Reply-To: <20241107114656.17611-1-colin.i.king@gmail.com>
References: <20241107114656.17611-1-colin.i.king@gmail.com>
Message-ID: <173316067527.538095.8720061974027462596.b4-ty@kernel.org>


On Thu, 07 Nov 2024 11:46:56 +0000, Colin Ian King wrote:
> The variable ret is being checked for an error and returning ret
> and the following statement returns ret too. The if check is
> redundant, and remove it. Just return the value returned from
> the call to regmap_write.
> 
> 

Applied, thanks!

[1/1] dmaengine: xilinx: xdma: remove redundant check on ret
      commit: 0f31c0912286f84b34b15e39b286db8f4765ced8

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Mon Dec  2 09:31:19 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 02 Dec 2024 23:01:19 +0530
Subject: [PATCH] dmaengine: xilinx_dma: Configure parking registers
 only if parking enabled
In-Reply-To: <20241031171132.56861-1-marex@denx.de>
References: <20241031171132.56861-1-marex@denx.de>
Message-ID: <173316067900.538095.9728729453604607068.b4-ty@kernel.org>


On Thu, 31 Oct 2024 18:11:04 +0100, Marek Vasut wrote:
> The VDMA can work in two modes, parking or circular. Do not program the
> parking mode registers in case circular mode is used, it is useless.
> 
> 

Applied, thanks!

[1/1] dmaengine: xilinx_dma: Configure parking registers only if parking enabled
      commit: 8a20040f9de3a4ea90ab900cdd7745d57bc2da82

Best regards,
-- 
~Vinod




From ribalda at chromium.org  Mon Dec  2 09:26:07 2024
From: ribalda at chromium.org (Ricardo Ribalda)
Date: Mon, 2 Dec 2024 18:26:07 +0100
Subject: [PATCH 3/3] media: mediatek: vcodec: Workaround a compiler warning
In-Reply-To: <20241202162454.GA2848026@thelio-3990X>
References: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
 <20241202-fix-llvm9-v1-3-2a50f5acfd0b@chromium.org> <20241202162454.GA2848026@thelio-3990X>
Message-ID: <CANiDSCu+gJb5aTywEnGDQUJYws++9x=be5QLsdSUqS=XjFZGnQ@mail.gmail.com>

Hi


On Mon, 2 Dec 2024 at 17:25, Nathan Chancellor <nathan at kernel.org> wrote:
>
>  Mon, Dec 02, 2024 at 03:47:17PM +0000, Ricardo Ribalda wrote:
> > llvm identifies that the SCP_IPI_VENC_H264 and IPI_VENC_H264 are from
> > the same enum type, but their are part of the same ternary operator.
> >
> > vpu_inst.id is of type int, so we can just rewrite a bit the code and
> > avoid the following llvm9 warning:
>
> LLVM 19, not LLVM 9, as the minimum version for building the kernel is
> LLVM 13.
>
> > drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c:597:29: warning: conditional expression between different enumeration types ('enum scp_ipi_id' and 'enum ipi_id') [-Wenum-compare-conditional]
> >
> > Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
>
> Reviewed-by: Nathan Chancellor <nathan at kernel.org>
>
> FYI, Arnd basically sent the same patch October 18 but I guess it has
> not been picked up?
>
> https://lore.kernel.org/20241018152127.3958436-1-arnd at kernel.org/
>
> Hopefully the new media committers model will help patches like that get
> picked up in a more timely manner.

We can take Arnd's patch.

Yeah, this is the kind of patches that the multi committers can really
help with :)

>
> > ---
> >  drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c | 6 ++++--
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
> > index f8145998fcaf..4786062e879a 100644
> > --- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
> > +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
> > @@ -584,7 +584,6 @@ static void h264_encode_filler(struct venc_h264_inst *inst, void *buf,
> >
> >  static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx)
> >  {
> > -     const bool is_ext = MTK_ENC_CTX_IS_EXT(ctx);
> >       int ret = 0;
> >       struct venc_h264_inst *inst;
> >
> > @@ -594,7 +593,10 @@ static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx)
> >
> >       inst->ctx = ctx;
> >       inst->vpu_inst.ctx = ctx;
> > -     inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264;
> > +     if (MTK_ENC_CTX_IS_EXT(ctx))
> > +             inst->vpu_inst.id = SCP_IPI_VENC_H264;
> > +     else
> > +             inst->vpu_inst.id = IPI_VENC_H264;
> >       inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx->dev->reg_base, VENC_SYS);
> >
> >       ret = vpu_enc_init(&inst->vpu_inst);
> >
> > --
> > 2.47.0.338.g60cca15819-goog
> >



--
Ricardo Ribalda


From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:22 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:22 +0900
Subject: [PATCH 00/10] compiler.h: refactor __is_constexpr() into
 is_const{,_true,_false}()
Message-ID: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>

This series is the spiritual successor of [1] which introduced
const_true(). In [1], following a comment from David Laight, Linus
came with a suggestion to simplify __is_constexpr() and its derived
macros using a _Generic() selection. Because of the total change of
scope, I am starting a new series.

The goal is to introduce a set of three macros:

  - is_const(): a one to one replacement of __is_constexpr() in term
    of features but written in a less hacky way thanks to _Generic().

  - is_const_true(): tells whether or not the argument is a true
    integer constant expression.

  - is_const_false(): tells whether or not the argument is a false
    integer constant expression.

Once defined, apply them tree-wide.

All those three macros will rely on a single building block:
__is_const_zero().

Patch 1 adds statically_false(). This is just done so that at the end
of this series, the full set of statically_true/false() and
is_const_true/false() is present.

Patch 2 adds __is_const_zero() and is_const().

Patch 3 adds is_const_true() and is_const_false().

Patch 4 to 9 do a tree-wide replacement to remove all the usages of
__is_constexpr() and replace them by is_const_true() or
is_const_false() whenever feasible, or by is_const() otherwise.

Patch 10 finally remove __is_constexpr(). RIP!

[1] add const_true() to simplify GENMASK_INPUT_CHECK()
Link: https://lore.kernel.org/all/20241113172939.747686-4-mailhol.vincent at wanadoo.fr/

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
Vincent Mailhol (10):
      compiler.h: add statically_false()
      compiler.h: add is_const() as a replacement of __is_constexpr()
      compiler.h: add is_const_true() and is_const_false()
      linux/bits.h: simplify GENMASK_INPUT_CHECK() by using is_const_true()
      minmax: simplify __clamp_once() by using is_const_false()
      fortify: replace __is_constexpr() by is_const() in strlen()
      overflow: replace __is_constexpr() by is_const()
      drm/i915/reg: replace __is_const_expr() by is_const_true() or is_const()
      coresight: etm4x: replace __is_const_expr() by is_const()
      compiler.h: remove __is_constexpr()

 drivers/gpu/drm/i915/i915_reg_defs.h          |  47 +++++------
 drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
 include/linux/bits.h                          |   5 +-
 include/linux/compiler.h                      | 112 +++++++++++++++-----------
 include/linux/fortify-string.h                |   4 +-
 include/linux/minmax.h                        |   3 +-
 include/linux/overflow.h                      |   8 +-
 7 files changed, 97 insertions(+), 84 deletions(-)
---
base-commit: e70140ba0d2b1a30467d4af6bcfe761327b9ec95
change-id: 20241129-is_constexpr-refactor-19460adedc48

Best regards,
-- 
Vincent Mailhol <mailhol.vincent at wanadoo.fr>




From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:23 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:23 +0900
Subject: [PATCH 01/10] compiler.h: add statically_false()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-1-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

For completion, add statically_false() which is the equivalent of
statically_true() except that it will return true only if the input is
known to be false at compile time.

The == operator is used instead of the ! negation to prevent a
-Wint-in-bool-context compiler warning when the argument is not a
boolean. For example:

  statically_false(var * 0)

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
 include/linux/compiler.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 469a64dd6495fefab2c85ffc279568a657b72660..a2a56a50dd85227a4fdc62236a2710ca37c5ba52 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -314,6 +314,7 @@ static inline void *offset_to_ptr(const int *off)
  * values to determine that the condition is statically true.
  */
 #define statically_true(x) (__builtin_constant_p(x) && (x))
+#define statically_false(x) (__builtin_constant_p(x) && (x) == 0)
 
 /*
  * This is needed in functions which generate the stack canary, see

-- 
2.45.2




From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:28 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:28 +0900
Subject: [PATCH 06/10] fortify: replace __is_constexpr() by is_const() in
 strlen()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-6-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

is_const() is a one to one replacement of __is_constexpr(). Do the
replacement so that __is_constexpr() can be removed.

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
 include/linux/fortify-string.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
index 0d99bf11d260a3482bbe46e35c7553c0ccfb8b94..e3f2f772c5439ef71eb4a904b4ce27956bc69743 100644
--- a/include/linux/fortify-string.h
+++ b/include/linux/fortify-string.h
@@ -254,8 +254,8 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size
  * Returns number of characters in @p (NOT including the final NUL).
  *
  */
-#define strlen(p)							\
-	__builtin_choose_expr(__is_constexpr(__builtin_strlen(p)),	\
+#define strlen(p)						\
+	__builtin_choose_expr(is_const(__builtin_strlen(p)),	\
 		__builtin_strlen(p), __fortify_strlen(p))
 __FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1)
 __kernel_size_t __fortify_strlen(const char * const POS p)

-- 
2.45.2




From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:32 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:32 +0900
Subject: [PATCH 10/10] compiler.h: remove __is_constexpr()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-10-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

Now that all the users of __is_constexpr() have been migrated to
is_const() or one of its friends, remove it.

The homage to Martin Uecker's genius hack remains in the documentation
of __is_const_zero().

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
 include/linux/compiler.h | 47 -----------------------------------------------
 1 file changed, 47 deletions(-)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 165aa5b9bc484376087a130a1ac1f3edb50c983d..7ba75044828129cf1f81f458ade695786dbf132a 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -252,53 +252,6 @@ static inline void *offset_to_ptr(const int *off)
 #define __must_be_cstr(p) \
 	__BUILD_BUG_ON_ZERO_MSG(__annotated(p, nonstring), "must be cstr (NUL-terminated)")
 
-/*
- * This returns a constant expression while determining if an argument is
- * a constant expression, most importantly without evaluating the argument.
- * Glory to Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
- *
- * Details:
- * - sizeof() return an integer constant expression, and does not evaluate
- *   the value of its operand; it only examines the type of its operand.
- * - The results of comparing two integer constant expressions is also
- *   an integer constant expression.
- * - The first literal "8" isn't important. It could be any literal value.
- * - The second literal "8" is to avoid warnings about unaligned pointers;
- *   this could otherwise just be "1".
- * - (long)(x) is used to avoid warnings about 64-bit types on 32-bit
- *   architectures.
- * - The C Standard defines "null pointer constant", "(void *)0", as
- *   distinct from other void pointers.
- * - If (x) is an integer constant expression, then the "* 0l" resolves
- *   it into an integer constant expression of value 0. Since it is cast to
- *   "void *", this makes the second operand a null pointer constant.
- * - If (x) is not an integer constant expression, then the second operand
- *   resolves to a void pointer (but not a null pointer constant: the value
- *   is not an integer constant 0).
- * - The conditional operator's third operand, "(int *)8", is an object
- *   pointer (to type "int").
- * - The behavior (including the return type) of the conditional operator
- *   ("operand1 ? operand2 : operand3") depends on the kind of expressions
- *   given for the second and third operands. This is the central mechanism
- *   of the macro:
- *   - When one operand is a null pointer constant (i.e. when x is an integer
- *     constant expression) and the other is an object pointer (i.e. our
- *     third operand), the conditional operator returns the type of the
- *     object pointer operand (i.e. "int *"). Here, within the sizeof(), we
- *     would then get:
- *       sizeof(*((int *)(...))  == sizeof(int)  == 4
- *   - When one operand is a void pointer (i.e. when x is not an integer
- *     constant expression) and the other is an object pointer (i.e. our
- *     third operand), the conditional operator returns a "void *" type.
- *     Here, within the sizeof(), we would then get:
- *       sizeof(*((void *)(...)) == sizeof(void) == 1
- * - The equality comparison to "sizeof(int)" therefore depends on (x):
- *     sizeof(int) == sizeof(int)     (x) was a constant expression
- *     sizeof(int) != sizeof(void)    (x) was not a constant expression
- */
-#define __is_constexpr(x) \
-	(sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
-
 /*
  * Whether 'type' is a signed type or an unsigned type. Supports scalar types,
  * bool and also pointer types.

-- 
2.45.2




From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:29 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:29 +0900
Subject: [PATCH 07/10] overflow: replace __is_constexpr() by is_const()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-7-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

is_const() is a one to one replacement of __is_constexpr(). Do the
replacement so that __is_constexpr() can be removed.

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
 include/linux/overflow.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index 0c7e3dcfe8670cb95f371a6f7d41bb8b63b1786c..d69361a3128897d493b5e2ec471f077ca2b9861d 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -234,7 +234,7 @@ static inline bool __must_check __must_check_overflow(bool overflow)
  * Returns: true if overflow can occur, false otherwise.
  */
 #define overflows_type(n, T)					\
-	__builtin_choose_expr(__is_constexpr(n),		\
+	__builtin_choose_expr(is_const(n),			\
 			      __overflows_type_constexpr(n, T),	\
 			      __overflows_type(n, T))
 
@@ -250,7 +250,7 @@ static inline bool __must_check __must_check_overflow(bool overflow)
  * back to __same_type().
  */
 #define castable_to_type(n, T)						\
-	__builtin_choose_expr(__is_constexpr(n),			\
+	__builtin_choose_expr(is_const(n),				\
 			      !__overflows_type_constexpr(n, T),	\
 			      __same_type(n, T))
 
@@ -352,7 +352,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
  * Return: number of bytes needed or SIZE_MAX on overflow.
  */
 #define flex_array_size(p, member, count)				\
-	__builtin_choose_expr(__is_constexpr(count),			\
+	__builtin_choose_expr(is_const(count),				\
 		(count) * sizeof(*(p)->member) + __must_be_array((p)->member),	\
 		size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member)))
 
@@ -368,7 +368,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
  * Return: number of bytes needed or SIZE_MAX on overflow.
  */
 #define struct_size(p, member, count)					\
-	__builtin_choose_expr(__is_constexpr(count),			\
+	__builtin_choose_expr(is_const(count),				\
 		sizeof(*(p)) + flex_array_size(p, member, count),	\
 		size_add(sizeof(*(p)), flex_array_size(p, member, count)))
 

-- 
2.45.2




From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:24 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:24 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

__is_constexpr(), while being one of the most glorious one liner hack
ever witnessed by mankind, is overly complex. Following the adoption
of C11 in the kernel, this macro can be simplified through the use of
a _Generic() selection.

First, split the macro in two:

  - __is_const_zero(x): an helper macro; tells whether x is the
    integer constant expression 0 or something else.

  - is_const(x): replacement of __is_constexpr(); tells whether x is a
    integer constant expression.

The split serves two purposes: first make it easier to understand;
second, __is_const_zero() will be reused as a building block for other
is_const_*() macros that will be introduced later on.

The core principle of __is_constexpr() to abuse the return type of the
ternary operator remains, but all the surrounding sizeof() hack
disappear.

On a side note, while not relevant to the kernel, __is_constexpr()
relied on the GNU extension that sizeof(void) is 1. const_expr() does
not use any GNU extensions, making it ISO C compliant.

__is_constexpr() is temporarily kept and will be removed once all its
users get migrated to is_const() (or one of its friend).

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
 include/linux/compiler.h | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index a2a56a50dd85227a4fdc62236a2710ca37c5ba52..30ce06df4153cfdc0fad9bc7bffab9097f8b0450 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -316,6 +316,47 @@ static inline void *offset_to_ptr(const int *off)
 #define statically_true(x) (__builtin_constant_p(x) && (x))
 #define statically_false(x) (__builtin_constant_p(x) && (x) == 0)
 
+/*
+ * Whether x is the integer constant expression 0 or something else.
+ *
+ * Details:
+ *   - The C11 standard defines in ?6.3.2.3.3
+ *       (void *)<integer constant expression with the value 0>
+ *     as a null pointer constant (c.f. the NULL macro).
+ *   - If x evaluates to the integer constant expression 0,
+ *       (void *)(x)
+ *     is a null pointer constant. Else, it is a void * expression.
+ *   - In a ternary expression:
+ *       condition ? operand1 : operand2
+ *     if one of the two operands is of type void * and the other one
+ *     some other pointer type, the C11 standard defines in ?6.5.15.6
+ *     the resulting type as below:
+ *       if one operand is a null pointer constant, the result has the
+ *       type of the other operand; otherwise [...] the result type is
+ *       a pointer to an appropriately qualified version of void.
+ *   - As such, in
+ *       0 ? (void *)(x) : (char *)0
+ *     if x is the integer constant expression 0, operand1 is a null
+ *     pointer constant and the resulting type is that of operand2:
+ *     char *. If x is anything else, the type is void *.
+ *   - The (long) cast silences a compiler warning for when x is not 0.
+ *   - Finally, the _Generic() dispatches the resulting type into a
+ *     Boolean.
+ *
+ * Glory to Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
+ */
+#define __is_const_zero(x) \
+	_Generic(0 ? (void *)(long)(x) : (char *)0, char *: 1, void *: 0)
+
+/*
+ * Returns a constant expression while determining if its argument is a
+ * constant expression, most importantly without evaluating the argument.
+ *
+ * If getting a constant expression is not relevant to you, use the more
+ * powerful __builtin_constant_p() instead.
+ */
+#define is_const(x) __is_const_zero(0 * (x))
+
 /*
  * This is needed in functions which generate the stack canary, see
  * arch/x86/kernel/smpboot.c::start_secondary() for an example.

-- 
2.45.2




From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:26 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:26 +0900
Subject: [PATCH 04/10] linux/bits.h: simplify GENMASK_INPUT_CHECK() by
 using is_const_true()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-4-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

In GENMASK_INPUT_CHECK(),

  __builtin_choose_expr(__is_constexpr((l) > (h)), (l) > (h), 0)

is equivalent to:

  is_const_true((l) > (h))

Apply is_const_true() to simplify GENMASK_INPUT_CHECK().

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
This change passes the unit tests from CONFIG_BITS_TEST, including the
extra negative tests provided under #ifdef TEST_GENMASK_FAILURES [1].

[1] commit 6d511020e13d ("lib/test_bits.c: add tests of GENMASK")
Link: https://git.kernel.org/torvalds/c/6d511020e13d
---
 include/linux/bits.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/include/linux/bits.h b/include/linux/bits.h
index 60044b6088172b3f26aa3f17cdaede9786863dae..ef0119e6179e1ca95345a3d4d3327ba19633028e 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -20,9 +20,8 @@
  */
 #if !defined(__ASSEMBLY__)
 #include <linux/build_bug.h>
-#define GENMASK_INPUT_CHECK(h, l) \
-	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
-		__is_constexpr((l) > (h)), (l) > (h), 0)))
+#include <linux/compiler.h>
+#define GENMASK_INPUT_CHECK(h, l) BUILD_BUG_ON_ZERO(is_const_true((l) > (h)))
 #else
 /*
  * BUILD_BUG_ON_ZERO is not available in h files included from asm files,

-- 
2.45.2




From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:25 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:25 +0900
Subject: [PATCH 03/10] compiler.h: add is_const_true() and is_const_false()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-3-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

__builtin_constant_p() is known for not always being able to produce
constant expression [1] which led to the introduction of
__is_constexpr() [2]. Because of its dependency on
__builtin_constant_p(), statically_true() suffers from the same
issues.

For example:

  void foo(int a)
  {
  	 /* fail on GCC */
  	BUILD_BUG_ON_ZERO(statically_true(a));

  	 /* fail on both clang and GCC */
  	static char arr[statically_true(a) ? 1 : 2];
  }

Define a new is_const_true() and is_const_false() pair of macros
which, by making use of __is_const_zero(), always produces a constant
expression.

Note that is_const_false() can not be directly defined as an alias to
__is_const_zero(). Otherwise, it could yield some false positives on
huge numbers because of a lost of precision when doing the (long) cast
in __is_const_zero(). Example:

  is_const_false((u128)ULONG_MAX << BITS_PER_LONG)

Furthermore, using the ! operator like this:

  #define is_const_true(x) __is_const_zero(!(x))
  #define is_const_false(x) __is_const_zero(!!(x))

would yield a -Wint-in-bool-context compiler warning if the argument
is not a boolean. Use the == and != operators instead.

It should be noted that statically_true/false() are the only ones
capable of folding tautologic expressions in which at least one on the
operands is not a constant expression. For example:

  statically_true(true || var)
  statically_true(var == var)
  statically_false(var * 0)
  statically_false(var * 8 % 4)

always evaluate to true, whereas all of these would be false under
is_const_true/false() if var is not a constant expression [3].

For this reason, usage of const_true/false() should be the exception.
Reflect in the documentation that const_true() is less powerful and
that statically_true() is the overall preferred solution.

[1] __builtin_constant_p cannot resolve to const when optimizing
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449

[2] commit 3c8ba0d61d04 ("kernel.h: Retain constant expression output for max()/min()")
Link: https://git.kernel.org/torvalds/c/3c8ba0d61d04

[3] https://godbolt.org/z/E4r7EaxW9

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
 include/linux/compiler.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 30ce06df4153cfdc0fad9bc7bffab9097f8b0450..165aa5b9bc484376087a130a1ac1f3edb50c983d 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -357,6 +357,29 @@ static inline void *offset_to_ptr(const int *off)
  */
 #define is_const(x) __is_const_zero(0 * (x))
 
+/*
+ * Similar to statically_true() but produces a constant expression
+ *
+ * To be used in conjunction with macros, such as BUILD_BUG_ON_ZERO(),
+ * which require their input to be a constant expression and for which
+ * statically_true() would otherwise fail.
+ *
+ * This is a trade-off: is_const_true() requires all its operands to
+ * be compile time constants. Else, it would always returns false even
+ * on the most trivial cases like:
+ *
+ *   true || non_const_expr
+ *
+ * On the opposite, statically_true() is able to fold more complex
+ * tautologies and will return true on expressions such as:
+ *
+ *   !(non_const_expr * 8 % 4)
+ *
+ * For the general case, statically_true() is better.
+ */
+#define is_const_true(x) __is_const_zero((x) == 0)
+#define is_const_false(x) __is_const_zero((x) != 0)
+
 /*
  * This is needed in functions which generate the stack canary, see
  * arch/x86/kernel/smpboot.c::start_secondary() for an example.

-- 
2.45.2




From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:27 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:27 +0900
Subject: [PATCH 05/10] minmax: simplify __clamp_once() by using
 is_const_false()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-5-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

In __clamp_once(),

  __builtin_choose_expr(__is_constexpr((lo) > (hi)), (lo) <= (hi), true)

is equivalent to:

  !is_const_false((lo) <= (hi))

Apply is_const_false() to simplify __clamp_once().

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
 include/linux/minmax.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 98008dd92153db10c672155bca93201ffabee994..431bf76ac460a11a2e4af23acd90c0d26e99c862 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -111,8 +111,7 @@
 	__auto_type uval = (val);						\
 	__auto_type ulo = (lo);							\
 	__auto_type uhi = (hi);							\
-	static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), 	\
-			(lo) <= (hi), true),					\
+	static_assert(!is_const_false((lo) <= (hi)),				\
 		"clamp() low limit " #lo " greater than high limit " #hi);	\
 	BUILD_BUG_ON_MSG(!__types_ok3(val,lo,hi,uval,ulo,uhi),			\
 		"clamp("#val", "#lo", "#hi") signedness error");		\

-- 
2.45.2




From maz at kernel.org  Mon Dec  2 09:21:23 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:23 +0000
Subject: [PATCH 00/11] KVM: arm64: Add NV timer support
Message-ID: <20241202172134.384923-1-maz@kernel.org>

Here's another batch of NV-related patches, this time bringing in most
of the timer support for EL2 as well as nested guests.

The code is pretty convoluted for a bunch of reasons:

- FEAT_NV2 breaks the timer semantics by redirecting HW controls to
  memory, meaning that a guest could setup a timer and never see it
  firing until the next exit

- We go try hard to reflect the timer state in memory, but that's not
  great.

- With FEAT_ECV, we can finally correctly emulate the virtual timer,
  but this emulation is pretty costly

- As a way to make things suck less, we handle timer reads as early as
  possible, and only defer writes to the normal trap handling

- Finally, some implementations are badly broken, and require some
  hand-holding, irrespective of NV support. So we try and reuse the NV
  infrastructure to make them usable. This could be further optimised,
  but I'm running out of patience for this sort of HW.

What this is not implementing is support for CNTPOFF_EL2. It appears
that the architecture doesn't let you correctly emulate it, so I guess
this will be trap/emulate for the foreseeable future.

This series is on top of v6.13-rc1, and has been tested on my usual M2
setup, but also on a Snapdragon X1 Elite devkit. I would like to thank
Qualcomm for the free hardware with no strings (nor support) attached!

If you are feeling brave, you can run the whole thing from [1].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/nv-next

Marc Zyngier (11):
  KVM: arm64: nv: Add handling of EL2-specific timer registers
  KVM: arm64: nv: Sync nested timer state with FEAT_NV2
  KVM: arm64: nv: Publish emulated timer interrupt state in the
    in-memory state
  KVM: arm64: nv: Use FEAT_ECV to trap access to EL0 timers
  KVM: arm64: nv: Accelerate EL0 timer read accesses when FEAT_ECV in
    use
  KVM: arm64: nv: Acceletate EL0 counter accesses from hypervisor
    context
  KVM: arm64: Handle counter access early in non-HYP context
  KVM: arm64: nv: Add trap routing for
    CNTHCTL_EL2.EL1{NVPCT,NVVCT,TVT,TVCT}
  KVM: arm64: nv: Propagate CNTHCTL_EL2.EL1NV{P,V}CT bits
  KVM: arm64: nv: Sanitise CNTHCTL_EL2
  KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity

 arch/arm64/include/asm/cputype.h        |   2 +
 arch/arm64/include/asm/kvm_host.h       |   2 +-
 arch/arm64/include/asm/sysreg.h         |   4 +
 arch/arm64/kernel/cpu_errata.c          |   8 ++
 arch/arm64/kernel/image-vars.h          |   3 +
 arch/arm64/kvm/arch_timer.c             | 177 +++++++++++++++++++++---
 arch/arm64/kvm/arm.c                    |   3 +
 arch/arm64/kvm/emulate-nested.c         |  58 +++++++-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  39 ++++--
 arch/arm64/kvm/hyp/nvhe/timer-sr.c      |  16 ++-
 arch/arm64/kvm/hyp/vhe/switch.c         |  84 +++++++++++
 arch/arm64/kvm/nested.c                 |  15 ++
 arch/arm64/kvm/sys_regs.c               | 146 ++++++++++++++++++-
 arch/arm64/tools/cpucaps                |   1 +
 include/clocksource/arm_arch_timer.h    |   6 +
 include/kvm/arm_arch_timer.h            |  23 +++
 16 files changed, 546 insertions(+), 41 deletions(-)

-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:26 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:26 +0000
Subject: [PATCH 03/11] KVM: arm64: nv: Publish emulated timer interrupt state in the in-memory state
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-4-maz@kernel.org>

With FEAT_NV2, the EL0 timer state is entirely stored in memory,
meaning that the hypervisor can only provide a very poor emulation.

The only thing we can really do is to publish the interrupt state
in the guest view of CNT{P,V}_CTL_EL0, and defer everything else
to the next exit.

Only FEAT_ECV will allow us to fix it, at the cost of extra trapping.

Suggested-by: Chase Conklin <chase.conklin at arm.com>
Suggested-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 81afafd62059f..231040090697e 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -446,6 +446,25 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
 {
 	int ret;
 
+	/*
+	 * Paper over NV2 brokenness by publishing the interrupt status
+	 * bit. This still results in a poor quality of emulation (guest
+	 * writes will have no effect until the next exit).
+	 *
+	 * But hey, it's fast, right?
+	 */
+	if (is_hyp_ctxt(vcpu) &&
+	    (timer_ctx == vcpu_vtimer(vcpu) || timer_ctx == vcpu_ptimer(vcpu))) {
+		u32 ctl = timer_get_ctl(timer_ctx);
+
+		if (new_level)
+			ctl |= ARCH_TIMER_CTRL_IT_STAT;
+		else
+			ctl &= ~ARCH_TIMER_CTRL_IT_STAT;
+
+		timer_set_ctl(timer_ctx, ctl);
+	}
+
 	timer_ctx->irq.level = new_level;
 	trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_irq(timer_ctx),
 				   timer_ctx->irq.level);
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:25 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:25 +0000
Subject: [PATCH 02/11] KVM: arm64: nv: Sync nested timer state with FEAT_NV2
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-3-maz@kernel.org>

Emulating the timers with FEAT_NV2 is a bit odd, as the timers
can be reconfigured behind our back without the hypervisor even
noticing. In the VHE case, that's an actual regression in the
architecture...

Co-developed-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c  | 44 ++++++++++++++++++++++++++++++++++++
 arch/arm64/kvm/arm.c         |  3 +++
 include/kvm/arm_arch_timer.h |  1 +
 3 files changed, 48 insertions(+)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 1215df5904185..81afafd62059f 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -905,6 +905,50 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
 		kvm_timer_blocking(vcpu);
 }
 
+void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * When NV2 is on, guest hypervisors have their EL0 timer register
+	 * accesses redirected to the VNCR page. Any guest action taken on
+	 * the timer is postponed until the next exit, leading to a very
+	 * poor quality of emulation.
+	 */
+	if (!is_hyp_ctxt(vcpu))
+		return;
+
+	if (!vcpu_el2_e2h_is_set(vcpu)) {
+		/*
+		 * A non-VHE guest hypervisor doesn't have any direct access
+		 * to its timers: the EL2 registers trap (and the HW is
+		 * fully emulated), while the EL0 registers access memory
+		 * despite the access being notionally direct. Boo.
+		 *
+		 * We update the hardware timer registers with the
+		 * latest value written by the guest to the VNCR page
+		 * and let the hardware take care of the rest.
+		 */
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CTL_EL0),  SYS_CNTV_CTL);
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CVAL_EL0), SYS_CNTV_CVAL);
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CTL_EL0),  SYS_CNTP_CTL);
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CVAL_EL0), SYS_CNTP_CVAL);
+	} else {
+		/*
+		 * For a VHE guest hypervisor, the EL2 state is directly
+		 * stored in the host EL0 timers, while the emulated EL0
+		 * state is stored in the VNCR page. The latter could have
+		 * been updated behind our back, and we must reset the
+		 * emulation of the timers.
+		 */
+		struct timer_map map;
+		get_timer_map(vcpu, &map);
+
+		soft_timer_cancel(&map.emul_vtimer->hrtimer);
+		soft_timer_cancel(&map.emul_ptimer->hrtimer);
+		timer_emulate(map.emul_vtimer);
+		timer_emulate(map.emul_ptimer);
+	}
+}
+
 /*
  * With a userspace irqchip we have to check if the guest de-asserted the
  * timer and if so, unmask the timer irq signal on the host interrupt
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc4..fa3089822f9f3 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1228,6 +1228,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
 			kvm_timer_sync_user(vcpu);
 
+		if (vcpu_has_nv(vcpu))
+			kvm_timer_sync_nested(vcpu);
+
 		kvm_arch_vcpu_ctxsync_fp(vcpu);
 
 		/*
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index fd650a8789b91..6e3f6b7ff2b22 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -98,6 +98,7 @@ int __init kvm_timer_hyp_init(bool has_gic);
 int kvm_timer_enable(struct kvm_vcpu *vcpu);
 void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu);
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
+void kvm_timer_sync_nested(struct kvm_vcpu *vcpu);
 void kvm_timer_sync_user(struct kvm_vcpu *vcpu);
 bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu);
 void kvm_timer_update_run(struct kvm_vcpu *vcpu);
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:30 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:30 +0000
Subject: [PATCH 07/11] KVM: arm64: Handle counter access early in non-HYP context
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-8-maz@kernel.org>

We already deal with CNTPCT_EL0 accesses in non-HYP context.
Let's add CNTVCT_EL0 as a good measure.

This is also an opportunity to simplify things and make it
plain that this code is only for non-HYP context handling.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 34 +++++++++++++++----------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 30e572de28749..719479b42b329 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -506,7 +506,7 @@ static inline u64 compute_counter_value(struct arch_timer_context *ctxt)
 	return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
 }
 
-static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
+static bool kvm_handle_cntxct(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_context *ctxt;
 	u32 sysreg;
@@ -516,18 +516,19 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
 	 * We only get here for 64bit guests, 32bit guests will hit
 	 * the long and winding road all the way to the standard
 	 * handling. Yes, it sucks to be irrelevant.
+	 *
+	 * Also, we only deal with non-hypervisor context here (either
+	 * an EL1 guest, or a non-HYP context of an EL2 guest).
 	 */
+	if (is_hyp_ctxt(vcpu))
+		return false;
+
 	sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
 
 	switch (sysreg) {
 	case SYS_CNTPCT_EL0:
 	case SYS_CNTPCTSS_EL0:
 		if (vcpu_has_nv(vcpu)) {
-			if (is_hyp_ctxt(vcpu)) {
-				ctxt = vcpu_hptimer(vcpu);
-				break;
-			}
-
 			/* Check for guest hypervisor trapping */
 			val = __vcpu_sys_reg(vcpu, CNTHCTL_EL2);
 			if (!vcpu_el2_e2h_is_set(vcpu))
@@ -539,16 +540,23 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
 
 		ctxt = vcpu_ptimer(vcpu);
 		break;
+	case SYS_CNTVCT_EL0:
+	case SYS_CNTVCTSS_EL0:
+		if (vcpu_has_nv(vcpu)) {
+			/* Check for guest hypervisor trapping */
+			val = __vcpu_sys_reg(vcpu, CNTHCTL_EL2);
+
+			if (val & CNTHCTL_EL1TVCT)
+				return false;
+		}
+
+		ctxt = vcpu_vtimer(vcpu);
+		break;
 	default:
 		return false;
 	}
 
-	val = arch_timer_read_cntpct_el0();
-
-	if (ctxt->offset.vm_offset)
-		val -= *kern_hyp_va(ctxt->offset.vm_offset);
-	if (ctxt->offset.vcpu_offset)
-		val -= *kern_hyp_va(ctxt->offset.vcpu_offset);
+	val = compute_counter_value(ctxt);
 
 	vcpu_set_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu), val);
 	__kvm_skip_instr(vcpu);
@@ -593,7 +601,7 @@ static bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
 	    __vgic_v3_perform_cpuif_access(vcpu) == 1)
 		return true;
 
-	if (kvm_hyp_handle_cntpct(vcpu))
+	if (kvm_handle_cntxct(vcpu))
 		return true;
 
 	return false;
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:29 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:29 +0000
Subject: [PATCH 06/11] KVM: arm64: nv: Acceletate EL0 counter accesses from hypervisor context
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-7-maz@kernel.org>

Similarly to handling the physical timer accesses early when FEAT_ECV
causes a trap, we try to handle the physical counter without returning
to the general sysreg handling.

More surprisingly, we introduce something similar for the virtual
counter. Although this isn't necessary yet, it will prove useful on
systems that have a broken CNTVOFF_EL2 implementation. Yes, they exist.

Special care is taken to offset reads of the counter with the host's
CNTPOFF_EL2, as we perform this with TGE clear.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h |  5 +++++
 arch/arm64/kvm/hyp/vhe/switch.c         | 13 +++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 34f53707892df..30e572de28749 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -501,6 +501,11 @@ static inline bool handle_tx2_tvm(struct kvm_vcpu *vcpu)
 	return true;
 }
 
+static inline u64 compute_counter_value(struct arch_timer_context *ctxt)
+{
+	return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
+}
+
 static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_context *ctxt;
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index b014b0b10bf5d..49815a8a4c9bc 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -296,6 +296,13 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
 			val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
 		}
 		break;
+	case SYS_CNTPCT_EL0:
+	case SYS_CNTPCTSS_EL0:
+		/* If !ELIsInHost(EL0), the guest's CNTPOFF_EL2 applies */
+		val = compute_counter_value(!(vcpu_el2_e2h_is_set(vcpu) &&
+					      vcpu_el2_tge_is_set(vcpu)) ?
+					    vcpu_ptimer(vcpu) : vcpu_hptimer(vcpu));
+		break;
 	case SYS_CNTV_CTL_EL02:
 		val = __vcpu_sys_reg(vcpu, CNTV_CTL_EL0);
 		break;
@@ -314,6 +321,12 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
 		else
 			val = __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
 		break;
+	case SYS_CNTVCT_EL0:
+	case SYS_CNTVCTSS_EL0:
+		/* If !ELIsInHost(EL2), the guest's CNTVOFF_EL2 applies */
+		val = compute_counter_value(!vcpu_el2_e2h_is_set(vcpu) ?
+					    vcpu_vtimer(vcpu) : vcpu_hvtimer(vcpu));
+		break;
 	default:
 		return false;
 	}
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:28 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:28 +0000
Subject: [PATCH 05/11] KVM: arm64: nv: Accelerate EL0 timer read accesses when FEAT_ECV in use
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-6-maz@kernel.org>

Although FEAT_ECV allows us to correctly emulate the timers, it also
reduces performances pretty badly.

Mitigate this by emulating the CTL/CVAL register reads in the
inner run loop, without returning to the general kernel.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c     | 15 -------
 arch/arm64/kvm/hyp/vhe/switch.c | 71 +++++++++++++++++++++++++++++++++
 include/kvm/arm_arch_timer.h    | 15 +++++++
 3 files changed, 86 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index c9a46d34b40cf..2c4499dd63732 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -101,21 +101,6 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
 	}
 }
 
-static u64 timer_get_offset(struct arch_timer_context *ctxt)
-{
-	u64 offset = 0;
-
-	if (!ctxt)
-		return 0;
-
-	if (ctxt->offset.vm_offset)
-		offset += *ctxt->offset.vm_offset;
-	if (ctxt->offset.vcpu_offset)
-		offset += *ctxt->offset.vcpu_offset;
-
-	return offset;
-}
-
 static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
 {
 	struct kvm_vcpu *vcpu = ctxt->vcpu;
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 80581b1c39959..b014b0b10bf5d 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -256,6 +256,74 @@ void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
 	host_data_ptr(host_ctxt)->__hyp_running_vcpu = NULL;
 }
 
+static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	u64 esr, val;
+
+	/*
+	 * Having FEAT_ECV allows for a better quality of timer emulation.
+	 * However, this comes at a huge cost in terms of traps. Try and
+	 * satisfy the reads from guest's hypervisor context without
+	 * returning to the kernel if we can.
+	 */
+	if (!is_hyp_ctxt(vcpu))
+		return false;
+
+	esr = kvm_vcpu_get_esr(vcpu);
+	if ((esr & ESR_ELx_SYS64_ISS_DIR_MASK) != ESR_ELx_SYS64_ISS_DIR_READ)
+		return false;
+
+	switch (esr_sys64_to_sysreg(esr)) {
+	case SYS_CNTP_CTL_EL02:
+		val = __vcpu_sys_reg(vcpu, CNTP_CTL_EL0);
+		break;
+	case SYS_CNTP_CTL_EL0:
+		if (vcpu_el2_e2h_is_set(vcpu))
+			val = read_sysreg_el0(SYS_CNTP_CTL);
+		else
+			val = __vcpu_sys_reg(vcpu, CNTP_CTL_EL0);
+		break;
+	case SYS_CNTP_CVAL_EL02:
+		val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
+		break;
+	case SYS_CNTP_CVAL_EL0:
+		if (vcpu_el2_e2h_is_set(vcpu)) {
+			val = read_sysreg_el0(SYS_CNTP_CVAL);
+
+			if (!has_cntpoff())
+				val -= timer_get_offset(vcpu_hptimer(vcpu));
+		} else {
+			val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
+		}
+		break;
+	case SYS_CNTV_CTL_EL02:
+		val = __vcpu_sys_reg(vcpu, CNTV_CTL_EL0);
+		break;
+	case SYS_CNTV_CTL_EL0:
+		if (vcpu_el2_e2h_is_set(vcpu))
+			val = read_sysreg_el0(SYS_CNTV_CTL);
+		else
+			val = __vcpu_sys_reg(vcpu, CNTV_CTL_EL0);
+		break;
+	case SYS_CNTV_CVAL_EL02:
+		val = __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
+		break;
+	case SYS_CNTV_CVAL_EL0:
+		if (vcpu_el2_e2h_is_set(vcpu))
+			val = read_sysreg_el0(SYS_CNTV_CVAL);
+		else
+			val = __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
+		break;
+	default:
+		return false;
+	}
+
+	vcpu_set_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu), val);
+	__kvm_skip_instr(vcpu);
+
+	return true;
+}
+
 static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	u64 esr = kvm_vcpu_get_esr(vcpu);
@@ -409,6 +477,9 @@ static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
 	if (kvm_hyp_handle_tlbi_el2(vcpu, exit_code))
 		return true;
 
+	if (kvm_hyp_handle_timer(vcpu, exit_code))
+		return true;
+
 	if (kvm_hyp_handle_cpacr_el1(vcpu, exit_code))
 		return true;
 
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 6e3f6b7ff2b22..c1ba31fab6f52 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -156,4 +156,19 @@ static inline bool has_cntpoff(void)
 	return (has_vhe() && cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF));
 }
 
+static inline u64 timer_get_offset(struct arch_timer_context *ctxt)
+{
+	u64 offset = 0;
+
+	if (!ctxt)
+		return 0;
+
+	if (ctxt->offset.vm_offset)
+		offset += *ctxt->offset.vm_offset;
+	if (ctxt->offset.vcpu_offset)
+		offset += *ctxt->offset.vcpu_offset;
+
+	return offset;
+}
+
 #endif
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:27 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:27 +0000
Subject: [PATCH 04/11] KVM: arm64: nv: Use FEAT_ECV to trap access to EL0 timers
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-5-maz@kernel.org>

Although FEAT_NV2 makes most things fast, it also makes it impossible
to correctly emulate the timers, as the sysreg accesses are redirected
to memory.

FEAT_ECV addresses this by giving a hypervisor the ability to trap
the EL02 sysregs as well as the virtual timer.

Add the required trap setting to make use of the feature, allowing
us to elide the ugly resync in the middle of the run loop.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c          | 36 +++++++++++++++++++++++++---
 include/clocksource/arm_arch_timer.h |  2 ++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 231040090697e..c9a46d34b40cf 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -781,7 +781,7 @@ static void kvm_timer_vcpu_load_nested_switch(struct kvm_vcpu *vcpu,
 
 static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 {
-	bool tpt, tpc;
+	bool tvt, tpt, tvc, tpc, tvt02, tpt02;
 	u64 clr, set;
 
 	/*
@@ -796,7 +796,29 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 	 * within this function, reality kicks in and we start adding
 	 * traps based on emulation requirements.
 	 */
-	tpt = tpc = false;
+	tvt = tpt = tvc = tpc = false;
+	tvt02 = tpt02 = false;
+
+	/*
+	 * NV2 badly breaks the timer semantics by redirecting accesses to
+	 * the EL0 timer state to memory, so let's call ECV to the rescue if
+	 * available: we trap all CNT{P,V}_{CTL,CVAL,TVAL}_EL0 accesses.
+	 *
+	 * The treatment slightly varies depending whether we run a nVHE or
+	 * VHE guest: nVHE will use the _EL0 registers directly, while VHE
+	 * will use the _EL02 accessors. This translates in different trap
+	 * bits.
+	 *
+	 * None of the trapping is required when running in non-HYP context,
+	 * unless required by the L1 hypervisor settings once we advertise
+	 * ECV+NV in the guest, or that we need trapping for other reasons.
+	 */
+	if (cpus_have_final_cap(ARM64_HAS_ECV) && is_hyp_ctxt(vcpu)) {
+		if (vcpu_el2_e2h_is_set(vcpu))
+			tvt02 = tpt02 = true;
+		else
+			tvt = tpt = true;
+	}
 
 	/*
 	 * We have two possibility to deal with a physical offset:
@@ -836,6 +858,10 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 
 	assign_clear_set_bit(tpt, CNTHCTL_EL1PCEN << 10, set, clr);
 	assign_clear_set_bit(tpc, CNTHCTL_EL1PCTEN << 10, set, clr);
+	assign_clear_set_bit(tvt, CNTHCTL_EL1TVT, clr, set);
+	assign_clear_set_bit(tvc, CNTHCTL_EL1TVCT, clr, set);
+	assign_clear_set_bit(tvt02, CNTHCTL_EL1NVVCT, clr, set);
+	assign_clear_set_bit(tpt02, CNTHCTL_EL1NVPCT, clr, set);
 
 	/* This only happens on VHE, so use the CNTHCTL_EL2 accessor. */
 	sysreg_clear_set(cnthctl_el2, clr, set);
@@ -931,8 +957,12 @@ void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
 	 * accesses redirected to the VNCR page. Any guest action taken on
 	 * the timer is postponed until the next exit, leading to a very
 	 * poor quality of emulation.
+	 *
+	 * This is an unmitigated disaster, only papered over by FEAT_ECV,
+	 * which allows trapping of the timer registers even with NV2.
+	 * Still, this is still worse than FEAT_NV on its own. Meh.
 	 */
-	if (!is_hyp_ctxt(vcpu))
+	if (cpus_have_final_cap(ARM64_HAS_ECV) || !is_hyp_ctxt(vcpu))
 		return;
 
 	if (!vcpu_el2_e2h_is_set(vcpu)) {
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index 877dcbb2601ae..c62811fb41309 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -24,6 +24,8 @@
 #define CNTHCTL_ECV			(1 << 12)
 #define CNTHCTL_EL1TVT			(1 << 13)
 #define CNTHCTL_EL1TVCT			(1 << 14)
+#define CNTHCTL_EL1NVPCT		(1 << 15)
+#define CNTHCTL_EL1NVVCT		(1 << 16)
 
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:24 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:24 +0000
Subject: [PATCH 01/11] KVM: arm64: nv: Add handling of EL2-specific timer registers
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-2-maz@kernel.org>

Add the required handling for EL2 and EL02 registers, as
well as EL1 registers used in the E2H context. This includes
handling the virtual timer accesses when CNTHCTL_EL2.EL1TVT
or CNTHCTL_EL2.EL1TVCT are set.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/sysreg.h      |   4 +
 arch/arm64/kvm/sys_regs.c            | 143 +++++++++++++++++++++++++++
 include/clocksource/arm_arch_timer.h |   2 +
 3 files changed, 149 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index b8303a83c0bff..2ed33737c7a99 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -477,6 +477,7 @@
 #define SYS_CNTFRQ_EL0			sys_reg(3, 3, 14, 0, 0)
 
 #define SYS_CNTPCT_EL0			sys_reg(3, 3, 14, 0, 1)
+#define SYS_CNTVCT_EL0			sys_reg(3, 3, 14, 0, 2)
 #define SYS_CNTPCTSS_EL0		sys_reg(3, 3, 14, 0, 5)
 #define SYS_CNTVCTSS_EL0		sys_reg(3, 3, 14, 0, 6)
 
@@ -484,14 +485,17 @@
 #define SYS_CNTP_CTL_EL0		sys_reg(3, 3, 14, 2, 1)
 #define SYS_CNTP_CVAL_EL0		sys_reg(3, 3, 14, 2, 2)
 
+#define SYS_CNTV_TVAL_EL0		sys_reg(3, 3, 14, 3, 0)
 #define SYS_CNTV_CTL_EL0		sys_reg(3, 3, 14, 3, 1)
 #define SYS_CNTV_CVAL_EL0		sys_reg(3, 3, 14, 3, 2)
 
 #define SYS_AARCH32_CNTP_TVAL		sys_reg(0, 0, 14, 2, 0)
 #define SYS_AARCH32_CNTP_CTL		sys_reg(0, 0, 14, 2, 1)
 #define SYS_AARCH32_CNTPCT		sys_reg(0, 0, 0, 14, 0)
+#define SYS_AARCH32_CNTVCT		sys_reg(0, 1, 0, 14, 0)
 #define SYS_AARCH32_CNTP_CVAL		sys_reg(0, 2, 0, 14, 0)
 #define SYS_AARCH32_CNTPCTSS		sys_reg(0, 8, 0, 14, 0)
+#define SYS_AARCH32_CNTVCTSS		sys_reg(0, 9, 0, 14, 0)
 
 #define __PMEV_op2(n)			((n) & 0x7)
 #define __CNTR_CRm(n)			(0x8 | (((n) >> 3) & 0x3))
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 83c6b4a07ef56..986e63d4f9faa 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1412,26 +1412,146 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
 
 	switch (reg) {
 	case SYS_CNTP_TVAL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
+	case SYS_CNTV_TVAL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HVTIMER;
+		else
+			tmr = TIMER_VTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
 	case SYS_AARCH32_CNTP_TVAL:
+	case SYS_CNTP_TVAL_EL02:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_TVAL;
 		break;
+
+	case SYS_CNTV_TVAL_EL02:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
+	case SYS_CNTHP_TVAL_EL2:
+		tmr = TIMER_HPTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
+	case SYS_CNTHV_TVAL_EL2:
+		tmr = TIMER_HVTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
 	case SYS_CNTP_CTL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
+	case SYS_CNTV_CTL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HVTIMER;
+		else
+			tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
 	case SYS_AARCH32_CNTP_CTL:
+	case SYS_CNTP_CTL_EL02:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_CTL;
 		break;
+
+	case SYS_CNTV_CTL_EL02:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
+	case SYS_CNTHP_CTL_EL2:
+		tmr = TIMER_HPTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
+	case SYS_CNTHV_CTL_EL2:
+		tmr = TIMER_HVTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
 	case SYS_CNTP_CVAL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
+	case SYS_CNTV_CVAL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HVTIMER;
+		else
+			tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
 	case SYS_AARCH32_CNTP_CVAL:
+	case SYS_CNTP_CVAL_EL02:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_CVAL;
 		break;
+
+	case SYS_CNTV_CVAL_EL02:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
+	case SYS_CNTHP_CVAL_EL2:
+		tmr = TIMER_HPTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
+	case SYS_CNTHV_CVAL_EL2:
+		tmr = TIMER_HVTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
 	case SYS_CNTPCT_EL0:
 	case SYS_CNTPCTSS_EL0:
+		if (is_hyp_ctxt(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_CNT;
+		break;
+
 	case SYS_AARCH32_CNTPCT:
+	case SYS_AARCH32_CNTPCTSS:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_CNT;
 		break;
+
+	case SYS_CNTVCT_EL0:
+	case SYS_CNTVCTSS_EL0:
+		if (is_hyp_ctxt(vcpu))
+			tmr = TIMER_HVTIMER;
+		else
+			tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CNT;
+		break;
+
+	case SYS_AARCH32_CNTVCT:
+	case SYS_AARCH32_CNTVCTSS:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CNT;
+		break;
+
 	default:
 		print_sys_reg_msg(p, "%s", "Unhandled trapped timer register");
 		return undef_access(vcpu, p, r);
@@ -2901,11 +3021,17 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	AMU_AMEVTYPER1_EL0(15),
 
 	{ SYS_DESC(SYS_CNTPCT_EL0), access_arch_timer },
+	{ SYS_DESC(SYS_CNTVCT_EL0), access_arch_timer },
 	{ SYS_DESC(SYS_CNTPCTSS_EL0), access_arch_timer },
+	{ SYS_DESC(SYS_CNTVCTSS_EL0), access_arch_timer },
 	{ SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },
 	{ SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer },
 	{ SYS_DESC(SYS_CNTP_CVAL_EL0), access_arch_timer },
 
+	{ SYS_DESC(SYS_CNTV_TVAL_EL0), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CTL_EL0), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CVAL_EL0), access_arch_timer },
+
 	/* PMEVCNTRn_EL0 */
 	PMU_PMEVCNTR_EL0(0),
 	PMU_PMEVCNTR_EL0(1),
@@ -3057,9 +3183,24 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	EL2_REG_VNCR(CNTVOFF_EL2, reset_val, 0),
 	EL2_REG(CNTHCTL_EL2, access_rw, reset_val, 0),
+	{ SYS_DESC(SYS_CNTHP_TVAL_EL2), access_arch_timer },
+	EL2_REG(CNTHP_CTL_EL2, access_arch_timer, reset_val, 0),
+	EL2_REG(CNTHP_CVAL_EL2, access_arch_timer, reset_val, 0),
+
+	{ SYS_DESC(SYS_CNTHV_TVAL_EL2), access_arch_timer },
+	EL2_REG(CNTHV_CTL_EL2, access_arch_timer, reset_val, 0),
+	EL2_REG(CNTHV_CVAL_EL2, access_arch_timer, reset_val, 0),
 
 	{ SYS_DESC(SYS_CNTKCTL_EL12), access_cntkctl_el12 },
 
+	{ SYS_DESC(SYS_CNTP_TVAL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTP_CTL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTP_CVAL_EL02), access_arch_timer },
+
+	{ SYS_DESC(SYS_CNTV_TVAL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CTL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CVAL_EL02), access_arch_timer },
+
 	EL2_REG(SP_EL2, NULL, reset_unknown, 0),
 };
 
@@ -3879,9 +4020,11 @@ static const struct sys_reg_desc cp15_64_regs[] = {
 	{ SYS_DESC(SYS_AARCH32_CNTPCT),	      access_arch_timer },
 	{ Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, TTBR1_EL1 },
 	{ Op1( 1), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_ASGI1R */
+	{ SYS_DESC(SYS_AARCH32_CNTVCT),	      access_arch_timer },
 	{ Op1( 2), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI0R */
 	{ SYS_DESC(SYS_AARCH32_CNTP_CVAL),    access_arch_timer },
 	{ SYS_DESC(SYS_AARCH32_CNTPCTSS),     access_arch_timer },
+	{ SYS_DESC(SYS_AARCH32_CNTVCTSS),     access_arch_timer },
 };
 
 static bool check_sysreg_table(const struct sys_reg_desc *table, unsigned int n,
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index cbbc9a6dc5715..877dcbb2601ae 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -22,6 +22,8 @@
 #define CNTHCTL_EVNTDIR			(1 << 3)
 #define CNTHCTL_EVNTI			(0xF << 4)
 #define CNTHCTL_ECV			(1 << 12)
+#define CNTHCTL_EL1TVT			(1 << 13)
+#define CNTHCTL_EL1TVCT			(1 << 14)
 
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:33 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:33 +0000
Subject: [PATCH 10/11] KVM: arm64: nv: Sanitise CNTHCTL_EL2
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-11-maz@kernel.org>

Inject some sanity in CNTHCTL_EL2, ensuring that we don't handle
more than we advertise to the guest.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h    |  2 +-
 arch/arm64/kvm/nested.c              | 15 +++++++++++++++
 include/clocksource/arm_arch_timer.h |  2 ++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e18e9244d17a4..cf571d41faa89 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -490,7 +490,6 @@ enum vcpu_sysreg {
 	VBAR_EL2,	/* Vector Base Address Register (EL2) */
 	RVBAR_EL2,	/* Reset Vector Base Address Register */
 	CONTEXTIDR_EL2,	/* Context ID Register (EL2) */
-	CNTHCTL_EL2,	/* Counter-timer Hypervisor Control register */
 	SP_EL2,		/* EL2 Stack Pointer */
 	CNTHP_CTL_EL2,
 	CNTHP_CVAL_EL2,
@@ -501,6 +500,7 @@ enum vcpu_sysreg {
 	MARKER(__SANITISED_REG_START__),
 	TCR2_EL2,	/* Extended Translation Control Register (EL2) */
 	MDCR_EL2,	/* Monitor Debug Configuration Register (EL2) */
+	CNTHCTL_EL2,	/* Counter-timer Hypervisor Control register */
 
 	/* Any VNCR-capable reg goes after this point */
 	MARKER(__VNCR_START__),
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 9b36218b48def..9113c6025d6f3 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1271,6 +1271,21 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		res0 |= MDCR_EL2_EnSTEPOP;
 	set_sysreg_masks(kvm, MDCR_EL2, res0, res1);
 
+	/* CNTHCTL_EL2 */
+	res0 = GENMASK(63, 20);
+	res1 = 0;
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RME, IMP))
+		res0 |= CNTHCTL_CNTPMASK | CNTHCTL_CNTVMASK;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, ECV, CNTPOFF)) {
+		res0 |= CNTHCTL_ECV;
+		if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, ECV, IMP))
+			res0 |= (CNTHCTL_EL1TVT | CNTHCTL_EL1TVCT |
+				 CNTHCTL_EL1NVPCT | CNTHCTL_EL1NVVCT);
+	}
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, VH, IMP))
+		res0 |= GENMASK(11, 8);
+	set_sysreg_masks(kvm, CNTHCTL_EL2, res0, res1);
+
 	return 0;
 }
 
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index c62811fb41309..ce6521ad04d12 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -26,6 +26,8 @@
 #define CNTHCTL_EL1TVCT			(1 << 14)
 #define CNTHCTL_EL1NVPCT		(1 << 15)
 #define CNTHCTL_EL1NVVCT		(1 << 16)
+#define CNTHCTL_CNTVMASK		(1 << 18)
+#define CNTHCTL_CNTPMASK		(1 << 19)
 
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:34 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:34 +0000
Subject: [PATCH 11/11] KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-12-maz@kernel.org>

It appears that on Qualcomm's x1e CPU, CNTVOFF_EL2 doesn't really
work, specially with HCR_EL2.E2H=1.

A non-zero offset results in a screaming virtual timer interrupt,
to the tune of a few 100k interrupts per second on a 4 vcpu VM.
This is also evidenced by this CPU's inability to correctly run
any of the timer selftests.

The only case this doesn't break is when this register is set to 0,
which breaks VM migration.

When HCR_EL2.E2H=0, the timer seems to behave normally, and does
not result in an interrupt storm.

As a workaround, use the fact that this CPU implements FEAT_ECV,
and trap all accesses to the virtual timer and counter, keeping
CNTVOFF_EL2 set to zero, and emulate accesses to CVAL/TVAL/CTL
and the counter itself, fixing up the timer to account for the
missing offset.

And if you think this is disgusting, you'd probably be right.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/cputype.h   |  2 ++
 arch/arm64/kernel/cpu_errata.c     |  8 +++++
 arch/arm64/kernel/image-vars.h     |  3 ++
 arch/arm64/kvm/arch_timer.c        | 58 ++++++++++++++++++++++++++++--
 arch/arm64/kvm/hyp/nvhe/timer-sr.c | 16 ++++++---
 arch/arm64/kvm/sys_regs.c          |  3 +-
 arch/arm64/tools/cpucaps           |  1 +
 include/kvm/arm_arch_timer.h       |  7 ++++
 8 files changed, 90 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 488f8e7513495..6f3f4142e214f 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -122,6 +122,7 @@
 #define QCOM_CPU_PART_KRYO_3XX_SILVER	0x803
 #define QCOM_CPU_PART_KRYO_4XX_GOLD	0x804
 #define QCOM_CPU_PART_KRYO_4XX_SILVER	0x805
+#define QCOM_CPU_PART_ORYON_X1		0x001
 
 #define NVIDIA_CPU_PART_DENVER		0x003
 #define NVIDIA_CPU_PART_CARMEL		0x004
@@ -198,6 +199,7 @@
 #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER)
 #define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD)
 #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
+#define MIDR_QCOM_ORYON_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_ORYON_X1)
 #define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER)
 #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL)
 #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index a78f247029aec..7ce5558628951 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -786,6 +786,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_RANGE_LIST(erratum_ac03_cpu_38_list),
 	},
 #endif
+	{
+		.desc = "Broken CNTVOFF_EL2",
+		.capability = ARM64_WORKAROUND_QCOM_ORYON_CNTVOFF,
+		ERRATA_MIDR_RANGE_LIST(((const struct midr_range[]) {
+					MIDR_ALL_VERSIONS(MIDR_QCOM_ORYON_X1),
+					{}
+				})),
+	},
 	{
 	}
 };
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 8f5422ed1b758..ef3a69cc398e5 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -105,6 +105,9 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors);
 KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);
 KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
 
+/* Static key which is set if CNTVOFF_EL2 is unusable */
+KVM_NVHE_ALIAS(broken_cntvoff_key);
+
 /* EL2 exception handling */
 KVM_NVHE_ALIAS(__start___kvm_ex_table);
 KVM_NVHE_ALIAS(__stop___kvm_ex_table);
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index f4607c4f68d2e..db4b96c22dfdb 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -30,6 +30,7 @@ static u32 host_vtimer_irq_flags;
 static u32 host_ptimer_irq_flags;
 
 static DEFINE_STATIC_KEY_FALSE(has_gic_active_state);
+DEFINE_STATIC_KEY_FALSE(broken_cntvoff_key);
 
 static const u8 default_ppi[] = {
 	[TIMER_PTIMER]  = 30,
@@ -517,7 +518,12 @@ static void timer_save_state(struct arch_timer_context *ctx)
 	case TIMER_VTIMER:
 	case TIMER_HVTIMER:
 		timer_set_ctl(ctx, read_sysreg_el0(SYS_CNTV_CTL));
-		timer_set_cval(ctx, read_sysreg_el0(SYS_CNTV_CVAL));
+		cval = read_sysreg_el0(SYS_CNTV_CVAL);
+
+		if (has_broken_cntvoff())
+			cval -= timer_get_offset(ctx);
+
+		timer_set_cval(ctx, cval);
 
 		/* Disable the timer */
 		write_sysreg_el0(0, SYS_CNTV_CTL);
@@ -622,8 +628,15 @@ static void timer_restore_state(struct arch_timer_context *ctx)
 
 	case TIMER_VTIMER:
 	case TIMER_HVTIMER:
-		set_cntvoff(timer_get_offset(ctx));
-		write_sysreg_el0(timer_get_cval(ctx), SYS_CNTV_CVAL);
+		cval = timer_get_cval(ctx);
+		offset = timer_get_offset(ctx);
+		if (has_broken_cntvoff()) {
+			set_cntvoff(0);
+			cval += offset;
+		} else {
+			set_cntvoff(offset);
+		}
+		write_sysreg_el0(cval, SYS_CNTV_CVAL);
 		isb();
 		write_sysreg_el0(timer_get_ctl(ctx), SYS_CNTV_CTL);
 		break;
@@ -818,6 +831,13 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 	if (!has_cntpoff() && timer_get_offset(map->direct_ptimer))
 		tpt = tpc = true;
 
+	/*
+	 * For the poor sods that could not correctly substract one value
+	 * from another, trap the full virtual timer and counter.
+	 */
+	if (has_broken_cntvoff() && timer_get_offset(map->direct_vtimer))
+		tvt = tvc = true;
+
 	/*
 	 * Apply the enable bits that the guest hypervisor has requested for
 	 * its own guest. We can only add traps that wouldn't have been set
@@ -1448,6 +1468,37 @@ static int kvm_irq_init(struct arch_timer_kvm_info *info)
 	return 0;
 }
 
+static void kvm_timer_handle_errata(void)
+{
+	u64 mmfr0, mmfr1, mmfr4;
+
+	/*
+	 * CNTVOFF_EL2 is broken on some implementations. For those, we trap
+	 * all virtual timer/counter accesses, requiring FEAT_ECV.
+	 *
+	 * However, a hypervisor supporting nesting is likely to mitigate the
+	 * erratum at L0, and not require other levels to mitigate it (which
+	 * would otherwise be a terrible performance sink due to trap
+	 * amplification).
+	 *
+	 * Given that the affected HW implements both FEAT_VHE and FEAT_E2H0,
+	 * and that NV is likely not to (because of limitations of the
+	 * architecture), only enable the workaround when FEAT_VHE and
+	 * FEAT_E2H0 are both detected. Time will tell if this actually holds.
+	 */
+	mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
+	mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
+	mmfr4 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR4_EL1);
+	if (SYS_FIELD_GET(ID_AA64MMFR1_EL1, VH, mmfr1)		&&
+	    !SYS_FIELD_GET(ID_AA64MMFR4_EL1, E2H0, mmfr4)	&&
+	    SYS_FIELD_GET(ID_AA64MMFR0_EL1, ECV, mmfr0)		&&
+	    (has_vhe() || has_hvhe())				&&
+	    cpus_have_final_cap(ARM64_WORKAROUND_QCOM_ORYON_CNTVOFF)) {
+		static_branch_enable(&broken_cntvoff_key);
+		kvm_info("Broken CNTVOFF_EL2, trapping virtual timer\n");
+	}
+}
+
 int __init kvm_timer_hyp_init(bool has_gic)
 {
 	struct arch_timer_kvm_info *info;
@@ -1516,6 +1567,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
 		goto out_free_vtimer_irq;
 	}
 
+	kvm_timer_handle_errata();
 	return 0;
 
 out_free_ptimer_irq:
diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index 3aaab20ae5b47..ff176f4ce7deb 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -22,15 +22,16 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
  */
 void __timer_disable_traps(struct kvm_vcpu *vcpu)
 {
-	u64 val, shift = 0;
+	u64 set, clr, shift = 0;
 
 	if (has_hvhe())
 		shift = 10;
 
 	/* Allow physical timer/counter access for the host */
-	val = read_sysreg(cnthctl_el2);
-	val |= (CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN) << shift;
-	write_sysreg(val, cnthctl_el2);
+	set = (CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN) << shift;
+	clr = CNTHCTL_EL1TVT | CNTHCTL_EL1TVCT;
+
+	sysreg_clear_set(cnthctl_el2, clr, set);
 }
 
 /*
@@ -58,5 +59,12 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
 		set <<= 10;
 	}
 
+	/*
+	 * Trap the virtual counter/timer if we have a broken cntvoff
+	 * implementation.
+	 */
+	if (has_broken_cntvoff())
+		set |= CNTHCTL_EL1TVT | CNTHCTL_EL1TVCT;
+
 	sysreg_clear_set(cnthctl_el2, clr, set);
 }
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 986e63d4f9faa..d161d6c05707a 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1721,7 +1721,8 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
 		if (!vcpu_has_ptrauth(vcpu))
 			val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3) |
 				 ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3));
-		if (!cpus_have_final_cap(ARM64_HAS_WFXT))
+		if (!cpus_have_final_cap(ARM64_HAS_WFXT) ||
+		    has_broken_cntvoff())
 			val &= ~ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_WFxT);
 		break;
 	case SYS_ID_AA64MMFR2_EL1:
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index eb17f59e543c4..1e65f2fb45bd1 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -105,6 +105,7 @@ WORKAROUND_CLEAN_CACHE
 WORKAROUND_DEVICE_LOAD_ACQUIRE
 WORKAROUND_NVIDIA_CARMEL_CNP
 WORKAROUND_QCOM_FALKOR_E1003
+WORKAROUND_QCOM_ORYON_CNTVOFF
 WORKAROUND_REPEAT_TLBI
 WORKAROUND_SPECULATIVE_AT
 WORKAROUND_SPECULATIVE_SSBS
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index c1ba31fab6f52..681cf0c8b9df4 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -151,6 +151,13 @@ void kvm_timer_cpu_down(void);
 /* CNTKCTL_EL1 valid bits as of DDI0487J.a */
 #define CNTKCTL_VALID_BITS	(BIT(17) | GENMASK_ULL(9, 0))
 
+DECLARE_STATIC_KEY_FALSE(broken_cntvoff_key);
+
+static inline bool has_broken_cntvoff(void)
+{
+	return static_branch_unlikely(&broken_cntvoff_key);
+}
+
 static inline bool has_cntpoff(void)
 {
 	return (has_vhe() && cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF));
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:32 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:32 +0000
Subject: [PATCH 09/11] KVM: arm64: nv: Propagate CNTHCTL_EL2.EL1NV{P,V}CT bits
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-10-maz@kernel.org>

Allow a guest hypervisor to trap accesses to CNT{P,V}CT_EL02 by
propagating these trap bits to the host trap configuration.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 2c4499dd63732..f4607c4f68d2e 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -822,6 +822,10 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 	 * Apply the enable bits that the guest hypervisor has requested for
 	 * its own guest. We can only add traps that wouldn't have been set
 	 * above.
+	 * Implementation choices: we do not support NV when E2H=0 in the
+	 * guest, and we don't support configuration where E2H is writable
+	 * by the guest (either FEAT_VHE or FEAT_E2H0 is implemented, but
+	 * not both). This simplifies the handling of the EL1NV* bits.
 	 */
 	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
 		u64 val = __vcpu_sys_reg(vcpu, CNTHCTL_EL2);
@@ -832,6 +836,9 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 
 		tpt |= !(val & (CNTHCTL_EL1PCEN << 10));
 		tpc |= !(val & (CNTHCTL_EL1PCTEN << 10));
+
+		tpt02 |= (val & CNTHCTL_EL1NVPCT);
+		tvt02 |= (val & CNTHCTL_EL1NVVCT);
 	}
 
 	/*
-- 
2.39.2



From maz at kernel.org  Mon Dec  2 09:21:31 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Dec 2024 17:21:31 +0000
Subject: [PATCH 08/11] KVM: arm64: nv: Add trap routing for CNTHCTL_EL2.EL1{NVPCT,NVVCT,TVT,TVCT}
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241202172134.384923-9-maz@kernel.org>

For completeness, fun, and cerebral meltdown, add the virtualisation
related traps to the counter and timers.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 58 +++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 1ffbfd1c3cf2e..03d21044c41f5 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -89,6 +89,9 @@ enum cgt_group_id {
 	CGT_HCRX_EnFPM,
 	CGT_HCRX_TCR2En,
 
+	CGT_CNTHCTL_EL1TVT,
+	CGT_CNTHCTL_EL1TVCT,
+
 	CGT_ICH_HCR_TC,
 	CGT_ICH_HCR_TALL0,
 	CGT_ICH_HCR_TALL1,
@@ -124,6 +127,8 @@ enum cgt_group_id {
 	__COMPLEX_CONDITIONS__,
 	CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
 	CGT_CNTHCTL_EL1PTEN,
+	CGT_CNTHCTL_EL1NVPCT,
+	CGT_CNTHCTL_EL1NVVCT,
 
 	CGT_CPTR_TTA,
 	CGT_MDCR_HPMN,
@@ -393,6 +398,18 @@ static const struct trap_bits coarse_trap_bits[] = {
 		.mask		= HCRX_EL2_TCR2En,
 		.behaviour	= BEHAVE_FORWARD_RW,
 	},
+	[CGT_CNTHCTL_EL1TVT] = {
+		.index		= CNTHCTL_EL2,
+		.value		= CNTHCTL_EL1TVT,
+		.mask		= CNTHCTL_EL1TVT,
+		.behaviour	= BEHAVE_FORWARD_RW,
+	},
+	[CGT_CNTHCTL_EL1TVCT] = {
+		.index		= CNTHCTL_EL2,
+		.value		= CNTHCTL_EL1TVCT,
+		.mask		= CNTHCTL_EL1TVCT,
+		.behaviour	= BEHAVE_FORWARD_READ,
+	},
 	[CGT_ICH_HCR_TC] = {
 		.index		= ICH_HCR_EL2,
 		.value		= ICH_HCR_TC,
@@ -487,6 +504,32 @@ static enum trap_behaviour check_cnthctl_el1pten(struct kvm_vcpu *vcpu)
 	return BEHAVE_FORWARD_RW;
 }
 
+static bool is_nested_nv2_guest(struct kvm_vcpu *vcpu)
+{
+	u64 val;
+
+	val = __vcpu_sys_reg(vcpu, HCR_EL2);
+	return ((val & (HCR_E2H | HCR_TGE | HCR_NV2 | HCR_NV1 | HCR_NV)) == (HCR_E2H | HCR_NV2 | HCR_NV));
+}
+
+static enum trap_behaviour check_cnthctl_el1nvpct(struct kvm_vcpu *vcpu)
+{
+	if (!is_nested_nv2_guest(vcpu) ||
+	    !(__vcpu_sys_reg(vcpu, CNTHCTL_EL2) & CNTHCTL_EL1NVPCT))
+		return BEHAVE_HANDLE_LOCALLY;
+
+	return BEHAVE_FORWARD_RW;
+}
+
+static enum trap_behaviour check_cnthctl_el1nvvct(struct kvm_vcpu *vcpu)
+{
+	if (!is_nested_nv2_guest(vcpu) ||
+	    !(__vcpu_sys_reg(vcpu, CNTHCTL_EL2) & CNTHCTL_EL1NVVCT))
+		return BEHAVE_HANDLE_LOCALLY;
+
+	return BEHAVE_FORWARD_RW;
+}
+
 static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
 {
 	u64 val = __vcpu_sys_reg(vcpu, CPTR_EL2);
@@ -534,6 +577,8 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
 static const complex_condition_check ccc[] = {
 	CCC(CGT_CNTHCTL_EL1PCTEN, check_cnthctl_el1pcten),
 	CCC(CGT_CNTHCTL_EL1PTEN, check_cnthctl_el1pten),
+	CCC(CGT_CNTHCTL_EL1NVPCT, check_cnthctl_el1nvpct),
+	CCC(CGT_CNTHCTL_EL1NVVCT, check_cnthctl_el1nvvct),
 	CCC(CGT_CPTR_TTA, check_cptr_tta),
 	CCC(CGT_MDCR_HPMN, check_mdcr_hpmn),
 };
@@ -850,11 +895,15 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
 		      SYS_CNTHP_CVAL_EL2, CGT_HCR_NV),
 	SR_RANGE_TRAP(SYS_CNTHV_TVAL_EL2,
 		      SYS_CNTHV_CVAL_EL2, CGT_HCR_NV),
-	/* All _EL02, _EL12 registers */
+	/* All _EL02, _EL12 registers up to CNTKCTL_EL12*/
 	SR_RANGE_TRAP(sys_reg(3, 5, 0, 0, 0),
 		      sys_reg(3, 5, 10, 15, 7), CGT_HCR_NV),
 	SR_RANGE_TRAP(sys_reg(3, 5, 12, 0, 0),
-		      sys_reg(3, 5, 14, 15, 7), CGT_HCR_NV),
+		      sys_reg(3, 5, 14, 1, 0), CGT_HCR_NV),
+	SR_TRAP(SYS_CNTP_CTL_EL02,	CGT_CNTHCTL_EL1NVPCT),
+	SR_TRAP(SYS_CNTP_CVAL_EL02,	CGT_CNTHCTL_EL1NVPCT),
+	SR_TRAP(SYS_CNTV_CTL_EL02,	CGT_CNTHCTL_EL1NVVCT),
+	SR_TRAP(SYS_CNTV_CVAL_EL02,	CGT_CNTHCTL_EL1NVVCT),
 	SR_TRAP(OP_AT_S1E2R,		CGT_HCR_NV),
 	SR_TRAP(OP_AT_S1E2W,		CGT_HCR_NV),
 	SR_TRAP(OP_AT_S12E1R,		CGT_HCR_NV),
@@ -1184,6 +1233,11 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
 	SR_TRAP(SYS_CNTP_CTL_EL0,	CGT_CNTHCTL_EL1PTEN),
 	SR_TRAP(SYS_CNTPCT_EL0,		CGT_CNTHCTL_EL1PCTEN),
 	SR_TRAP(SYS_CNTPCTSS_EL0,	CGT_CNTHCTL_EL1PCTEN),
+	SR_TRAP(SYS_CNTV_TVAL_EL0,	CGT_CNTHCTL_EL1TVT),
+	SR_TRAP(SYS_CNTV_CVAL_EL0,	CGT_CNTHCTL_EL1TVT),
+	SR_TRAP(SYS_CNTV_CTL_EL0,	CGT_CNTHCTL_EL1TVT),
+	SR_TRAP(SYS_CNTVCT_EL0,		CGT_CNTHCTL_EL1TVCT),
+	SR_TRAP(SYS_CNTVCTSS_EL0,	CGT_CNTHCTL_EL1TVCT),
 	SR_TRAP(SYS_FPMR,		CGT_HCRX_EnFPM),
 	/*
 	 * IMPDEF choice:
-- 
2.39.2



From neal at gompa.dev  Mon Dec  2 09:28:50 2024
From: neal at gompa.dev (Neal Gompa)
Date: Mon, 2 Dec 2024 12:28:50 -0500
Subject: [PATCH RESEND 0/5] Add Apple SPI controller and spi-nor dt nodes
In-Reply-To: <20241127-asahi-spi-dt-v1-0-907c9447f623@jannau.net>
References: <20241127-asahi-spi-dt-v1-0-907c9447f623@jannau.net>
Message-ID: <CAEg-Je-3w3koiqnAOMQO4RZ2DB+fRiSbZJSba-Z=L8OCF2B0Pg@mail.gmail.com>

On Wed, Nov 27, 2024 at 4:52?AM Janne Grunau via B4 Relay
<devnull+j.jannau.net at kernel.org> wrote:
>
> This series adds SPI controller and SPI NOR flash device nodes to the
> man Apple silicon SoC dts files. Only the subset of used SPI controllers
> is added. Five SPI controllers exists according to pmgr ADT data but the
> commits only add controllers found in use on any of the devices. The
> parameters for the missing nodes are guessable but there's no point in
> adding them since no further M1 or M2 devices are expected.
> Together with controller nodes the first SPI device is added. All Apple
> silicon devices connect a SPI NOR flash to spi1. This holds Apple's 1st
> stage bootloader, firmwares, platform and machine specific config data
> and a writeable key-value store (nvram). Expose only the nvram as mtd
> partition since it has use beyond exploring the content. Tools from
> asahi-nvram [1] can modify the (default) boot configuration
> (asahi-bless), read Bluetooth sync keys (asahi-btsync) and read and
> write arbitrary keys (asahi-nvram).
>
> Devicetree bindings are included in the driver series. Last version at
> https://lore.kernel.org/linux-devicetree/20241101-asahi-spi-v3-0-3b411c5fb8e5 at jannau.net/
>
> This series passes `make CHECK_DTBS=1 dtbs` with the spi bindings except
> for "local-mac-address" for the Bluetooth device (I need get back to
> this).
>
> [1] https://github.com/WhatAmISupposedToPutHere/asahi-nvram/
>
> Signed-off-by: Janne Grunau <j at jannau.net>
> ---
> Hector Martin (1):
>       arm64: dts: apple: t8103: Fix spi4 power domain sort order
>
> Janne Grunau (4):
>       arm64: dts: apple: t8103: Add spi controller nodes
>       arm64: dts: apple: t8112: Add spi controller nodes
>       arm64: dts: apple: t600x: Add spi controller nodes
>       arm64: dts: apple: Add SPI NOR nvram partition to all devices
>
>  arch/arm64/boot/dts/apple/spi1-nvram.dtsi      | 39 +++++++++++++++
>  arch/arm64/boot/dts/apple/t600x-common.dtsi    |  7 +++
>  arch/arm64/boot/dts/apple/t600x-die0.dtsi      | 28 +++++++++++
>  arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi | 14 ++++++
>  arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi |  2 +
>  arch/arm64/boot/dts/apple/t600x-j375.dtsi      |  2 +
>  arch/arm64/boot/dts/apple/t8103-jxxx.dtsi      |  2 +
>  arch/arm64/boot/dts/apple/t8103-pmgr.dtsi      | 18 +++----
>  arch/arm64/boot/dts/apple/t8103.dtsi           | 68 ++++++++++++++++++++++++++
>  arch/arm64/boot/dts/apple/t8112-jxxx.dtsi      |  2 +
>  arch/arm64/boot/dts/apple/t8112.dtsi           | 44 ++++++++++++++++-
>  11 files changed, 216 insertions(+), 10 deletions(-)
> ---
> base-commit: 98f7e32f20d28ec452afb208f9cffc08448a2652
> change-id: 20241101-asahi-spi-dt-58245bb1da3e
>
> Best regards,
> --
> Janne Grunau <j at jannau.net>
>

Series LGTM.

Reviewed-by: Neal Gompa <neal at gompa.dev>


-- 
?????????/ Always, there's only one truth!


From vkoul at kernel.org  Mon Dec  2 09:30:38 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 02 Dec 2024 23:00:38 +0530
Subject: [PATCH] dmaengine: at_xdmac: avoid null_prt_deref in
 at_xdmac_prep_dma_memset
In-Reply-To: <20241029082845.1185380-1-chenridong@huaweicloud.com>
References: <20241029082845.1185380-1-chenridong@huaweicloud.com>
Message-ID: <173316063896.537992.16601132301793620749.b4-ty@kernel.org>


On Tue, 29 Oct 2024 08:28:45 +0000, Chen Ridong wrote:
> The at_xdmac_memset_create_desc may return NULL, which will lead to a
> null pointer dereference. For example, the len input is error, or the
> atchan->free_descs_list is empty and memory is exhausted. Therefore, add
> check to avoid this.
> 
> 

Applied, thanks!

[1/1] dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset
      commit: c43ec96e8d34399bd9dab2f2dc316b904892133f

Best regards,
-- 
~Vinod




From neal at gompa.dev  Mon Dec  2 09:30:23 2024
From: neal at gompa.dev (Neal Gompa)
Date: Mon, 2 Dec 2024 12:30:23 -0500
Subject: [PATCH v2 0/4] Driver for Apple Z2 touchscreens.
In-Reply-To: <20241128-z2-v2-0-76cc59bbf117@gmail.com>
References: <20241128-z2-v2-0-76cc59bbf117@gmail.com>
Message-ID: <CAEg-Je_bx2aa-LpSgWjRjwWMGa9NDF9YbwkT1pP42s5=791oPQ@mail.gmail.com>

On Thu, Nov 28, 2024 at 5:29?PM Sasha Finkelstein via B4 Relay
<devnull+fnkl.kernel.gmail.com at kernel.org> wrote:
>
> Hi.
>
> This series adds support for Apple touchscreens using the Z2 protocol.
> Those are used as the primary touchscreen on mobile Apple devices, and for the
> touchbar on laptops using the M-series chips. (T1/T2 laptops have a coprocessor
> in charge of speaking Z2 to the touchbar).
>
> Originally sent as a RFC at https://lore.kernel.org/all/20230223-z2-for-ml-v1-0-028f2b85dc15 at gmail.com/
> The changes since then mostly address the review feedback, but also
> add another machine that has this specific controller.
>
> Signed-off-by: Sasha Finkelstein <fnkl.kernel at gmail.com>
> ---
> Changes in v2:
> - In a separate patch, fixed an issue that prevented the SPI controller
>   from using GPIO CS, and as such, moved the hardware quirk to there
> - Went back to uploading the firmware in probe() instad of open()
> - Other changes addressing the review feedback
> - Link to v1: https://lore.kernel.org/r/20241126-z2-v1-0-c43c4cc6200d at gmail.com
>
> ---
> Sasha Finkelstein (4):
>       dt-bindings: input: touchscreen: Add Z2 controller
>       input: apple_z2: Add a driver for Apple Z2 touchscreens
>       arm64: dts: apple: Add touchbar digitizer nodes
>       MAINTAINERS: Add entries for Apple Z2 touchscreen driver
>
>  .../input/touchscreen/apple,z2-multitouch.yaml     |  69 ++++
>  MAINTAINERS                                        |   2 +
>  arch/arm64/boot/dts/apple/t8103-j293.dts           |  26 ++
>  arch/arm64/boot/dts/apple/t8103.dtsi               |  20 +
>  arch/arm64/boot/dts/apple/t8112-j493.dts           |  24 ++
>  arch/arm64/boot/dts/apple/t8112.dtsi               |  14 +
>  drivers/input/touchscreen/Kconfig                  |  13 +
>  drivers/input/touchscreen/Makefile                 |   1 +
>  drivers/input/touchscreen/apple_z2.c               | 458 +++++++++++++++++++++
>  9 files changed, 627 insertions(+)
> ---
> base-commit: 9f16d5e6f220661f73b36a4be1b21575651d8833
> change-id: 20241124-z2-c012b528ea0d
>

Series LGTM.

Reviewed-by: Neal Gompa <neal at gompa.dev>


-- 
?????????/ Always, there's only one truth!


From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:30 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:30 +0900
Subject: [PATCH 08/10] drm/i915/reg: replace __is_const_expr() by
 is_const_true() or is_const()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-8-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

Most of the use of __is_const_expr() in i915_reg_defs.h are just to
test whether an expression is known to be true. Because those checks
are all done in a BUILD_BUG_ON_ZERO(), replace those with
is_const_true().

Replace the few other occurrences of __is_const_expr() with is_const().

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
 drivers/gpu/drm/i915/i915_reg_defs.h | 47 +++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h b/drivers/gpu/drm/i915/i915_reg_defs.h
index e251bcc0c89f5710125bc70f07851b2cb978c89c..6ed2fb9cf506a3bd6467ba30f9d0e863d62762f3 100644
--- a/drivers/gpu/drm/i915/i915_reg_defs.h
+++ b/drivers/gpu/drm/i915/i915_reg_defs.h
@@ -19,8 +19,7 @@
  */
 #define REG_BIT(__n)							\
 	((u32)(BIT(__n) +						\
-	       BUILD_BUG_ON_ZERO(__is_constexpr(__n) &&		\
-				 ((__n) < 0 || (__n) > 31))))
+	       BUILD_BUG_ON_ZERO(is_const_true((__n) < 0 || (__n) > 31))))
 
 /**
  * REG_BIT8() - Prepare a u8 bit value
@@ -32,8 +31,7 @@
  */
 #define REG_BIT8(__n)                                                   \
 	((u8)(BIT(__n) +                                                \
-	       BUILD_BUG_ON_ZERO(__is_constexpr(__n) &&         \
-				 ((__n) < 0 || (__n) > 7))))
+	      BUILD_BUG_ON_ZERO(is_const_true((__n) < 0 || (__n) > 7))))
 
 /**
  * REG_GENMASK() - Prepare a continuous u32 bitmask
@@ -46,9 +44,9 @@
  */
 #define REG_GENMASK(__high, __low)					\
 	((u32)(GENMASK(__high, __low) +					\
-	       BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&	\
-				 __is_constexpr(__low) &&		\
-				 ((__low) < 0 || (__high) > 31 || (__low) > (__high)))))
+	       BUILD_BUG_ON_ZERO(is_const_true((__low) < 0 ||		\
+					       (__high) > 31 ||		\
+					       (__low) > (__high)))))
 
 /**
  * REG_GENMASK64() - Prepare a continuous u64 bitmask
@@ -61,9 +59,9 @@
  */
 #define REG_GENMASK64(__high, __low)					\
 	((u64)(GENMASK_ULL(__high, __low) +				\
-	       BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&		\
-				 __is_constexpr(__low) &&		\
-				 ((__low) < 0 || (__high) > 63 || (__low) > (__high)))))
+	       BUILD_BUG_ON_ZERO(is_const_true((__low) < 0 ||		\
+					       (__high) > 63 ||		\
+					       (__low) > (__high)))))
 
 /**
  * REG_GENMASK8() - Prepare a continuous u8 bitmask
@@ -76,9 +74,9 @@
  */
 #define REG_GENMASK8(__high, __low)                                     \
 	((u8)(GENMASK(__high, __low) +                                  \
-	       BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&      \
-				 __is_constexpr(__low) &&               \
-				 ((__low) < 0 || (__high) > 7 || (__low) > (__high)))))
+	      BUILD_BUG_ON_ZERO(is_const_true((__low) < 0 ||            \
+					      (__high) > 7 ||           \
+					      (__low) > (__high)))))
 
 /*
  * Local integer constant expression version of is_power_of_2().
@@ -97,10 +95,10 @@
  */
 #define REG_FIELD_PREP(__mask, __val)						\
 	((u32)((((typeof(__mask))(__val) << __bf_shf(__mask)) & (__mask)) +	\
-	       BUILD_BUG_ON_ZERO(!__is_constexpr(__mask)) +		\
+	       BUILD_BUG_ON_ZERO(!is_const(__mask)) +				\
 	       BUILD_BUG_ON_ZERO((__mask) == 0 || (__mask) > U32_MAX) +		\
 	       BUILD_BUG_ON_ZERO(!IS_POWER_OF_2((__mask) + (1ULL << __bf_shf(__mask)))) + \
-	       BUILD_BUG_ON_ZERO(__builtin_choose_expr(__is_constexpr(__val), (~((__mask) >> __bf_shf(__mask)) & (__val)), 0))))
+	       BUILD_BUG_ON_ZERO(is_const_true(~((__mask) >> __bf_shf(__mask)) & (__val)))))
 
 /**
  * REG_FIELD_PREP8() - Prepare a u8 bitfield value
@@ -114,10 +112,10 @@
  */
 #define REG_FIELD_PREP8(__mask, __val)                                          \
 	((u8)((((typeof(__mask))(__val) << __bf_shf(__mask)) & (__mask)) +      \
-	       BUILD_BUG_ON_ZERO(!__is_constexpr(__mask)) +             \
+	       BUILD_BUG_ON_ZERO(!is_const(__mask)) +                           \
 	       BUILD_BUG_ON_ZERO((__mask) == 0 || (__mask) > U8_MAX) +          \
 	       BUILD_BUG_ON_ZERO(!IS_POWER_OF_2((__mask) + (1ULL << __bf_shf(__mask)))) + \
-	       BUILD_BUG_ON_ZERO(__builtin_choose_expr(__is_constexpr(__val), (~((__mask) >> __bf_shf(__mask)) & (__val)), 0))))
+	       BUILD_BUG_ON_ZERO(is_const_true(~((__mask) >> __bf_shf(__mask)) & (__val)))))
 
 /**
  * REG_FIELD_GET() - Extract a u32 bitfield value
@@ -154,8 +152,7 @@
  */
 #define REG_BIT16(__n)                                                   \
 	((u16)(BIT(__n) +                                                \
-	       BUILD_BUG_ON_ZERO(__is_constexpr(__n) &&         \
-				 ((__n) < 0 || (__n) > 15))))
+	       BUILD_BUG_ON_ZERO(is_const_true((__n) < 0 || (__n) > 15))))
 
 /**
  * REG_GENMASK16() - Prepare a continuous u8 bitmask
@@ -169,9 +166,9 @@
  */
 #define REG_GENMASK16(__high, __low)                                     \
 	((u16)(GENMASK(__high, __low) +                                  \
-	       BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&      \
-				 __is_constexpr(__low) &&               \
-				 ((__low) < 0 || (__high) > 15 || (__low) > (__high)))))
+	       BUILD_BUG_ON_ZERO(is_const_true((__low) < 0 ||            \
+					       (__high) > 15 ||          \
+					       (__low) > (__high)))))
 
 /**
  * REG_FIELD_PREP16() - Prepare a u16 bitfield value
@@ -186,10 +183,10 @@
  */
 #define REG_FIELD_PREP16(__mask, __val)                                          \
 	((u16)((((typeof(__mask))(__val) << __bf_shf(__mask)) & (__mask)) +      \
-	       BUILD_BUG_ON_ZERO(!__is_constexpr(__mask)) +             \
+	       BUILD_BUG_ON_ZERO(!is_const(__mask)) +                            \
 	       BUILD_BUG_ON_ZERO((__mask) == 0 || (__mask) > U16_MAX) +          \
 	       BUILD_BUG_ON_ZERO(!IS_POWER_OF_2((__mask) + (1ULL << __bf_shf(__mask)))) + \
-	       BUILD_BUG_ON_ZERO(__builtin_choose_expr(__is_constexpr(__val), (~((__mask) >> __bf_shf(__mask)) & (__val)), 0))))
+	       BUILD_BUG_ON_ZERO(is_const_true(~((__mask) >> __bf_shf(__mask)) & (__val)))))
 
 #define __MASKED_FIELD(mask, value) ((mask) << 16 | (value))
 #define _MASKED_FIELD(mask, value) ({					   \
@@ -237,7 +234,7 @@
  *	...
  */
 #define _PICK_EVEN_2RANGES(__index, __c_index, __a, __b, __c, __d)		\
-	(BUILD_BUG_ON_ZERO(!__is_constexpr(__c_index)) +			\
+	(BUILD_BUG_ON_ZERO(!is_const(__c_index)) +				\
 	 ((__index) < (__c_index) ? _PICK_EVEN(__index, __a, __b) :		\
 				   _PICK_EVEN((__index) - (__c_index), __c, __d)))
 

-- 
2.45.2




From devnull+mailhol.vincent.wanadoo.fr at kernel.org  Mon Dec  2 09:33:31 2024
From: devnull+mailhol.vincent.wanadoo.fr at kernel.org (Vincent Mailhol via B4 Relay)
Date: Tue, 03 Dec 2024 02:33:31 +0900
Subject: [PATCH 09/10] coresight: etm4x: replace __is_const_expr() by
 is_const()
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <20241203-is_constexpr-refactor-v1-9-4e4cbaecc216@wanadoo.fr>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

is_const() is a one to one replacement of __is_constexpr(). Do the
replacement so that __is_constexpr() can be removed.

Refer to [1] for an explaination of why __builtin_constant_p() can not
be used as a replacement here.

[1] commit 4d45bc82df66 ("coresight: etm4x: avoid build failure with unrolled loops")
Link: https://git.kernel.org/torvalds/c/4d45bc82df66

Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
---
 drivers/hwtracing/coresight/coresight-etm4x.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 9e9165f62e81fe5a87d35b4e30bc23f93cb211ec..91cf81ac46f44418f76783c102477d08f9abc70f 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -492,7 +492,7 @@
 	({									\
 		u64 __val;							\
 										\
-		if (__is_constexpr((offset)))					\
+		if (is_const(offset))						\
 			__val = read_etm4x_sysreg_const_offset((offset));	\
 		else								\
 			__val = etm4x_sysreg_read((offset), true, (_64bit));	\

-- 
2.45.2




From mark.rutland at arm.com  Mon Dec  2 09:45:11 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 2 Dec 2024 17:45:11 +0000
Subject: [PATCH] arm64: patching: avoid early page_to_phys()
In-Reply-To: <20241202170359.1475019-1-mark.rutland@arm.com>
References: <20241202170359.1475019-1-mark.rutland@arm.com>
Message-ID: <Z03tNWwlOz3Iil9J@J2N7QTR9R3>

Looks like I messed up my text editing and left some bonus words...

On Mon, Dec 02, 2024 at 05:03:59PM +0000, Mark Rutland wrote:
> When arm64 is configured with CONFIG_DEBUG_VIRTUAL=y, a warning is
> printed from the patching code because patch_map(), e.g.

That was meant to say:

| When arm64 is configured with CONFIG_DEBUG_VIRTUAL=y, a warning is
| printed from the patching code, e.g.

[...]

> For historical reasons, the structure of patch_map() is more complicated
> than necessary and can be simplified. For kernel image addresses it's
> sufficient to use __pa_symbol() directly without converting this to a
> page address and back. Aside from kernel image addresses, all executable
> code should be allocated from execmem (where all allocations will fall
> within the vmalloc area), and the vmalloc area), and so there's no need
> for the fallback case when case when CONFIG_EXECMEM=n.

That last sentence should have been:

| Aside from kernel image addresses, all executable code should be
| allocated from execmem (where all allocations will fall within the
| vmalloc area), and so there's no need for the fallback case when case
| when CONFIG_EXECMEM=n.

I can spin a v2 with those fixed if necessary.

Mark.


From mark.rutland at arm.com  Mon Dec  2 09:53:05 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 2 Dec 2024 17:53:05 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <86ser6t6fs.wl-maz@kernel.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
Message-ID: <Z030AVd1_uURWsgL@J2N7QTR9R3>

On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> On Mon, 02 Dec 2024 15:59:40 +0000,
> Vitaly Chikunov <vt at altlinux.org> wrote:
> > 
> > Marc,
> > 
> > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > >
> > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > 
> > No, host is 6.6.60.
> 
> Right. I wouldn't be surprised if:
> 
> - this v6.6 kernel doesn't hide the MPAM feature as it should (and
>   that's proably something we should backport)

Looks like v6.6.60 is missing:

  6685f5d572c22e10 ("KVM: arm64: Disable MPAM visibility by default and ignore VMM writes")

... which is a fix for:

  011e5f5bf529f8ec (" arm64/cpufeature: Add remaining feature bits in ID_AA64PFR0 register")

... which unintentionally exposed ID_AA64PFR0.MPAM to guests, and *is*
in v6.6.60.

Mark.

> - you get a nastygram in the host log telling you that the guest has
>   executed something it shouldn't (you'll get the encoding of the
>   instruction)
> 
> Can you confirm these two things?
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.


From frank-w at public-files.de  Mon Dec  2 09:54:35 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Mon, 2 Dec 2024 17:54:35 +0000
Subject: Aw: Re: [PATCH v2 11/18] arm64: dts: mediatek: mt7988: add chosen
 node on bpi-r4
In-Reply-To: <e1343cc5-d5e8-40d6-a6f1-3eaf22a8cd6d@kernel.org>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-12-linux@fw-web.de>
 <0fb58a4a-7bad-4623-99c8-67f5763558bb@kernel.org>
 <D92CAF3C-F6B7-46DC-BF83-A71907E2D7EA@fw-web.de>
 <e1343cc5-d5e8-40d6-a6f1-3eaf22a8cd6d@kernel.org>
Message-ID: <trinity-1c2ce600-fa6d-485e-93ee-1b66b6cf4939-1733162074956@trinity-msg-rest-gmx-gmx-live-5cd5dd5458-t4xzg>

regards Frank


&gt; Gesendet: Montag, 2. Dezember 2024 um 16:58
&gt; Von: "Krzysztof Kozlowski" <krzk at kernel.org>
&gt; An: "Frank Wunderlich" <linux at fw-web.de>, "Rob Herring" <robh at kernel.org>, "Krzysztof Kozlowski" <krzk+dt at kernel.org>, "Conor Dooley" <conor+dt at kernel.org>, "Matthias Brugger" <matthias.bgg at gmail.com>, "AngeloGioacchino Del Regno" <angelogioacchino.delregno at collabora.com>
&gt; CC: "Frank Wunderlich" <frank-w at public-files.de>, devicetree at vger.kernel.org, linux-kernel at vger.kernel.org, linux-arm-kernel at lists.infradead.org, linux-mediatek at lists.infradead.org
&gt; Betreff: Re: [PATCH v2 11/18] arm64: dts: mediatek: mt7988: add chosen node on bpi-r4
&gt;
&gt; On 02/12/2024 15:29, Frank Wunderlich wrote:
&gt; &gt; Am 2. Dezember 2024 14:46:24 MEZ schrieb Krzysztof Kozlowski <krzk at kernel.org>:
&gt; &gt;&gt; On 02/12/2024 13:25, Frank Wunderlich wrote:
&gt; &gt;&gt;&gt; From: Frank Wunderlich <frank-w at public-files.de>
&gt; &gt;&gt;&gt;
&gt; &gt;&gt;&gt; Add chosen node on Bananapi R4 board with stdout and default bootargs.
&gt; &gt;&gt;&gt;
&gt; &gt;&gt;&gt; Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
&gt; &gt;&gt;&gt; ---
&gt; &gt;&gt;&gt;  arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 5 +++++
&gt; &gt;&gt;&gt;  1 file changed, 5 insertions(+)
&gt; &gt;&gt;&gt;
&gt; &gt;&gt;&gt; diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
&gt; &gt;&gt;&gt; index 9037f35857a9..1c2a806f6f6c 100644
&gt; &gt;&gt;&gt; --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
&gt; &gt;&gt;&gt; +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
&gt; &gt;&gt;&gt; @@ -9,6 +9,11 @@ / {
&gt; &gt;&gt;&gt;  	model = "Banana Pi BPI-R4";
&gt; &gt;&gt;&gt;  	chassis-type = "embedded";
&gt; &gt;&gt;&gt;
&gt; &gt;&gt;&gt; +	chosen {
&gt; &gt;&gt;&gt; +		stdout-path = &amp;serial0;
&gt; &gt;&gt;&gt; +		bootargs = "console=ttyS0,115200n1";
&gt; &gt;&gt;
&gt; &gt;&gt; Drop or merge into stdout path.
&gt; &gt;
&gt; &gt; Have you an example to pass speed setting to stdout-path? As it is only a phandle it is not clear to me how to merge these 2...
&gt; It is really trivial to find, considering that 66% of files have it.
&gt;
&gt; git grep stdout

thanks, wasn't aware that string is here also accepted...found it ("git grep stdout-path" is much better here :) )

will change both lines to this single one:

stdout-path = "serial0:115200n8";

&gt; Best regards,
&gt; Krzysztof
&gt; </frank-w at public-files.de></frank-w at public-files.de></krzk at kernel.org></frank-w at public-files.de></angelogioacchino.delregno at collabora.com></matthias.bgg at gmail.com></conor+dt at kernel.org></krzk+dt at kernel.org></robh at kernel.org></linux at fw-web.de></krzk at kernel.org>


From broonie at kernel.org  Mon Dec  2 09:58:21 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 02 Dec 2024 17:58:21 +0000
Subject: [PATCH v1 1/1] ASoc: mediatek: mt8365: Don't use "proxy"
 headers
In-Reply-To: <20241031102725.2447711-1-andriy.shevchenko@linux.intel.com>
References: <20241031102725.2447711-1-andriy.shevchenko@linux.intel.com>
Message-ID: <173316230181.189181.7179970847637835365.b4-ty@kernel.org>

On Thu, 31 Oct 2024 12:27:25 +0200, Andy Shevchenko wrote:
> Update header inclusions to follow IWYU (Include What You Use)
> principle.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoc: mediatek: mt8365: Don't use "proxy" headers
      commit: 509544d1b6dbffe7bc1849593ff217f965ec0419

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  Mon Dec  2 09:58:17 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 02 Dec 2024 17:58:17 +0000
Subject: [PATCHv2,sound-next] ASoC: rockchip: i2s-tdm: Fix a useless
 call issue
In-Reply-To: <20241118045605.48440-1-dheeraj.linuxdev@gmail.com>
References: <20241118045605.48440-1-dheeraj.linuxdev@gmail.com>
Message-ID: <173316229709.189181.1009410834028591581.b4-ty@kernel.org>

On Mon, 18 Nov 2024 10:26:05 +0530, Dheeraj Reddy Jonnalagadda wrote:
> This commit fixes a useless call issue detected by Coverity
> (CID 1507978). The call to rockchip_i2s_ch_to_io is unnecessary as its
> return value is never checked or used. As a result, the function
> definition and call is removed.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: rockchip: i2s-tdm: Fix a useless call issue
      commit: 42c7af046aaf35c42ef864cbd96df025c48ce50f

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  Mon Dec  2 09:58:24 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 02 Dec 2024 17:58:24 +0000
Subject: [PATCH] ASoC: mediatek: mt8192-afe-pcm: Simplify probe() with
 local dev variable
In-Reply-To: <20241025080026.2393-1-tangbin@cmss.chinamobile.com>
References: <20241025080026.2393-1-tangbin@cmss.chinamobile.com>
Message-ID: <173316230432.189181.14465686239974996213.b4-ty@kernel.org>

On Fri, 25 Oct 2024 16:00:26 +0800, Tang Bin wrote:
> Simplify the function mt8192_afe_pcm_dev_probe() by
> using local 'dev' instead of '&pdev->dev'.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: mediatek: mt8192-afe-pcm: Simplify probe() with local dev variable
      commit: 01981565c764c554cc96e2d30a71c42975171416

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 neal at gompa.dev  Mon Dec  2 10:02:04 2024
From: neal at gompa.dev (Neal Gompa)
Date: Mon, 2 Dec 2024 13:02:04 -0500
Subject: [PATCH v4 00/10] Add PMGR nodes for Apple A7-A11 SoCs
In-Reply-To: <20241201155820.29259-1-towinchenmi@gmail.com>
References: <20241201155820.29259-1-towinchenmi@gmail.com>
Message-ID: <CAEg-Je97QmLUrOV+dvg2zbV56R44Ouj4gLwV36z-RdvG-H+hGw@mail.gmail.com>

On Sun, Dec 1, 2024 at 11:00?AM Nick Chan <towinchenmi at gmail.com> wrote:
>
> This series adds the PMGR nodes and all known power state subnodes for
> Apple A7-A11 SoCs, along with the associated dt-bindings.
>
> Changes since v3:
> - Add "apple,always-on" property to "ps_spmi" in t8015 power domains.
> This is required for cpufreq to function correctly which will be added
> in a later series.
>
> Changes since v2:
> - Removed "apple,always-on" property from "ps_pmp" from s8001, t8011,
> t8015 power domains. It is not on at boot. (Mixed up with ps_pms which
> is required to be on)
> - Add asahi-soc/dt back into the subject prefix, missing from v2.
>
> Link to v2: https://lore.kernel.org/asahi/20241102011004.59339-1-towinchenmi at gmail.com
>
> Changes since v1:
> - Removed "framebuffer0" dt aliases. It is not standard and not needed.
>
> Link to v1: https://lore.kernel.org/asahi/20241029010526.42052-1-towinchenmi at gmail.com
>
> Nick Chan
> ---
>
> Nick Chan (10):
>   dt-bindings: arm: apple: apple,pmgr: Add A7-A11 compatibles
>   dt-bindings: arm: apple: apple,pmgr-pwrstate: Add A7-A11 compatibles
>   arm64: dts: apple: s5l8960x: Add PMGR node
>   arm64: dts: apple: t7000: Add PMGR node
>   arm64: dts: apple: t7001: Add PMGR node
>   arm64: dts: apple: s8000: Add PMGR nodes
>   arm64: dts: apple: s8001: Add PMGR nodes
>   arm64: dts: apple: t8010: Add PMGR nodes
>   arm64: dts: apple: t8011: Add PMGR nodes
>   arm64: dts: apple: t8015: Add PMGR nodes
>
>  .../bindings/arm/apple/apple,pmgr.yaml        |   5 +
>  .../bindings/power/apple,pmgr-pwrstate.yaml   |   5 +
>  arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi    |   4 +
>  arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi  |   4 +
>  arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi |   4 +
>  arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi  | 610 ++++++++++++
>  arch/arm64/boot/dts/apple/s5l8960x.dtsi       |  13 +
>  arch/arm64/boot/dts/apple/s8000-pmgr.dtsi     | 757 ++++++++++++++
>  arch/arm64/boot/dts/apple/s8000.dtsi          |  22 +
>  arch/arm64/boot/dts/apple/s8001-common.dtsi   |   1 +
>  .../arm64/boot/dts/apple/s8001-j98a-j99a.dtsi |  26 +
>  arch/arm64/boot/dts/apple/s8001-j98a.dts      |   1 +
>  arch/arm64/boot/dts/apple/s8001-j99a.dts      |   1 +
>  arch/arm64/boot/dts/apple/s8001-pmgr.dtsi     | 822 ++++++++++++++++
>  arch/arm64/boot/dts/apple/s8001.dtsi          |  22 +
>  arch/arm64/boot/dts/apple/s800x-6s.dtsi       |   4 +
>  arch/arm64/boot/dts/apple/s800x-ipad5.dtsi    |   4 +
>  arch/arm64/boot/dts/apple/s800x-se.dtsi       |   4 +
>  arch/arm64/boot/dts/apple/t7000-6.dtsi        |   4 +
>  arch/arm64/boot/dts/apple/t7000-j42d.dts      |   1 +
>  arch/arm64/boot/dts/apple/t7000-mini4.dtsi    |   4 +
>  arch/arm64/boot/dts/apple/t7000-n102.dts      |   4 +
>  arch/arm64/boot/dts/apple/t7000-pmgr.dtsi     | 641 ++++++++++++
>  arch/arm64/boot/dts/apple/t7000.dtsi          |  14 +
>  arch/arm64/boot/dts/apple/t7001-air2.dtsi     |   1 +
>  arch/arm64/boot/dts/apple/t7001-pmgr.dtsi     | 650 ++++++++++++
>  arch/arm64/boot/dts/apple/t7001.dtsi          |  13 +
>  arch/arm64/boot/dts/apple/t8010-7.dtsi        |   4 +
>  arch/arm64/boot/dts/apple/t8010-ipad6.dtsi    |   4 +
>  arch/arm64/boot/dts/apple/t8010-n112.dts      |   4 +
>  arch/arm64/boot/dts/apple/t8010-pmgr.dtsi     | 772 +++++++++++++++
>  arch/arm64/boot/dts/apple/t8010.dtsi          |  22 +
>  arch/arm64/boot/dts/apple/t8011-common.dtsi   |   1 +
>  arch/arm64/boot/dts/apple/t8011-pmgr.dtsi     | 806 +++++++++++++++
>  arch/arm64/boot/dts/apple/t8011-pro2.dtsi     |   8 +
>  arch/arm64/boot/dts/apple/t8011.dtsi          |  22 +
>  arch/arm64/boot/dts/apple/t8015-common.dtsi   |   1 +
>  arch/arm64/boot/dts/apple/t8015-pmgr.dtsi     | 931 ++++++++++++++++++
>  arch/arm64/boot/dts/apple/t8015.dtsi          |  21 +
>  39 files changed, 6237 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
>  create mode 100644 arch/arm64/boot/dts/apple/s8000-pmgr.dtsi
>  create mode 100644 arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
>  create mode 100644 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
>  create mode 100644 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
>  create mode 100644 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
>  create mode 100644 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
>  create mode 100644 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
>  create mode 100644 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi
>
>
> base-commit: 9ad55a67a788c0806b0fe23be36fae6dbfbc3fc5
> --
> 2.47.1
>
>

These seem reasonable.

Acked-by: Neal Gompa <neal at gompa.dev>



--
?????????/ Always, there's only one truth!


From radhey.shyam.pandey at amd.com  Mon Dec  2 10:11:51 2024
From: radhey.shyam.pandey at amd.com (Radhey Shyam Pandey)
Date: Mon, 2 Dec 2024 23:41:51 +0530
Subject: [PATCH v3] usb: dwc3: xilinx: make sure pipe clock is deselected in usb2 only mode
Message-ID: <1733163111-1414816-1-git-send-email-radhey.shyam.pandey@amd.com>

From: Neal Frager <neal.frager at amd.com>

When the USB3 PHY is not defined in the Linux device tree, there could
still be a case where there is a USB3 PHY active on the board and enabled
by the first stage bootloader. If serdes clock is being used then the USB
will fail to enumerate devices in 2.0 only mode.

To solve this, make sure that the PIPE clock is deselected whenever the
USB3 PHY is not defined and guarantees that the USB2 only mode will work
in all cases.

Fixes: 9678f3361afc ("usb: dwc3: xilinx: Skip resets and USB3 register settings for USB2.0 mode")
Cc: stable at vger.kernel.org
Signed-off-by: Neal Frager <neal.frager at amd.com>
Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
Acked-by: Peter Korsgaard <peter at korsgaard.com>
---
Changes for v3:
- Modify commit description to drop second "is" and add Peter ack.

Changes for v2:
- Add stable at vger.kernel.org in CC.
---
 drivers/usb/dwc3/dwc3-xilinx.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
index e3738e1610db..a33a42ba0249 100644
--- a/drivers/usb/dwc3/dwc3-xilinx.c
+++ b/drivers/usb/dwc3/dwc3-xilinx.c
@@ -121,8 +121,11 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
 	 * in use but the usb3-phy entry is missing from the device tree.
 	 * Therefore, skip these operations in this case.
 	 */
-	if (!priv_data->usb3_phy)
+	if (!priv_data->usb3_phy) {
+		/* Deselect the PIPE Clock Select bit in FPD PIPE Clock register */
+		writel(PIPE_CLK_DESELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK);
 		goto skip_usb3_phy;
+	}
 
 	crst = devm_reset_control_get_exclusive(dev, "usb_crst");
 	if (IS_ERR(crst)) {
-- 
2.34.1



From catalin.marinas at arm.com  Mon Dec  2 10:16:29 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon,  2 Dec 2024 18:16:29 +0000
Subject: [PATCH v6.13-rc1] arm64: mte: set VM_MTE_ALLOWED for hugetlbfs at correct place
In-Reply-To: <20241119200914.1145249-1-yang@os.amperecomputing.com>
References: <20241119200914.1145249-1-yang@os.amperecomputing.com>
Message-ID: <173316338578.1186434.1700615074381764365.b4-ty@arm.com>

On Tue, 19 Nov 2024 12:09:14 -0800, Yang Shi wrote:
> The commit 5de195060b2e ("mm: resolve faulty mmap_region() error path
> behaviour") moved vm flags validation before fop->mmap for file
> mappings.  But when commit 25c17c4b55de ("hugetlb: arm64: add mte support")
> was rebased on top of it, the hugetlbfs part was missed.  Mmapping
> hugetlbfs file may not have MAP_HUGETLB set.
> 
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: mte: set VM_MTE_ALLOWED for hugetlbfs at correct place
      https://git.kernel.org/arm64/c/49ccf2c3cafb

-- 
Catalin



From atishp at rivosinc.com  Mon Dec  2 10:26:13 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Mon, 2 Dec 2024 10:26:13 -0800
Subject: [PATCH 2/8] drivers/perf: riscv: Fix Platform firmware event data
In-Reply-To: <77b7b44f-e05a-4845-8d45-0e0d831bb8e7@ghiti.fr>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-2-a4f9691421f8@rivosinc.com> <77b7b44f-e05a-4845-8d45-0e0d831bb8e7@ghiti.fr>
Message-ID: <CAHBxVyHZvLrKNCAPJfHxYYn30Mm++J=mff+tVU9GZ_8rt3WnEg@mail.gmail.com>

On Thu, Nov 28, 2024 at 5:10?AM Alexandre Ghiti <alex at ghiti.fr> wrote:
>
> Hi Atish,
>
> On 19/11/2024 21:29, Atish Patra wrote:
> > Platform firmware event data field is allowed to be 62 bits for
> > Linux as uppper most two bits are reserved to indicate SBI fw or
> > platform specific firmware events.
> > However, the event data field is masked as per the hardware raw
> > event mask which is not correct.
> >
> > Fix the platform firmware event data field with proper mask.
> >
> > Fixes: f0c9363db2dd ("perf/riscv-sbi: Add platform specific firmware event handling")
> >
> > Signed-off-by: Atish Patra <atishp at rivosinc.com>
> > ---
> >   arch/riscv/include/asm/sbi.h |  1 +
> >   drivers/perf/riscv_pmu_sbi.c | 12 +++++-------
> >   2 files changed, 6 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> > index 98f631b051db..9be38b05f4ad 100644
> > --- a/arch/riscv/include/asm/sbi.h
> > +++ b/arch/riscv/include/asm/sbi.h
> > @@ -158,6 +158,7 @@ struct riscv_pmu_snapshot_data {
> >   };
> >
> >   #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
> > +#define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
> >   #define RISCV_PMU_RAW_EVENT_IDX 0x20000
> >   #define RISCV_PLAT_FW_EVENT 0xFFFF
> >
> > diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> > index cb98efa9b106..50cbdbf66bb7 100644
> > --- a/drivers/perf/riscv_pmu_sbi.c
> > +++ b/drivers/perf/riscv_pmu_sbi.c
> > @@ -508,7 +508,6 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
> >   {
> >       u32 type = event->attr.type;
> >       u64 config = event->attr.config;
> > -     u64 raw_config_val;
> >       int ret;
> >
> >       /*
> > @@ -529,21 +528,20 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
> >       case PERF_TYPE_RAW:
> >               /*
> >                * As per SBI specification, the upper 16 bits must be unused
> > -              * for a raw event.
> > +              * for a hardware raw event.
> >                * Bits 63:62 are used to distinguish between raw events
> >                * 00 - Hardware raw event
> >                * 10 - SBI firmware events
> >                * 11 - Risc-V platform specific firmware event
> >                */
> > -             raw_config_val = config & RISCV_PMU_RAW_EVENT_MASK;
> > +
> >               switch (config >> 62) {
> >               case 0:
> >                       ret = RISCV_PMU_RAW_EVENT_IDX;
> > -                     *econfig = raw_config_val;
> > +                     *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
> >                       break;
> >               case 2:
> > -                     ret = (raw_config_val & 0xFFFF) |
> > -                             (SBI_PMU_EVENT_TYPE_FW << 16);
> > +                     ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
> >                       break;
> >               case 3:
> >                       /*
> > @@ -552,7 +550,7 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
> >                        * Event data - raw event encoding
> >                        */
> >                       ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
> > -                     *econfig = raw_config_val;
> > +                     *econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
> >                       break;
> >               }
> >               break;
> >
>
> It seems independent from the other patches, so I guess we should take
> it for 6.13 rcX.
>

Yes. This patch doesn't have any SBI v3.0 dependencies. I will send
this patch separately
so that it can be applied for 6.13 rcX

> Let me know if that's not the case.
>
> Thanks,
>
> Alex
>


From dsimic at manjaro.org  Mon Dec  2 10:33:18 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 02 Dec 2024 19:33:18 +0100
Subject: [PATCH] arm64: dts: rockchip: Describe why is HWRNG disabled in
 RK356x base dtsi
In-Reply-To: <D61DMK8O9JCR.1C62A5UGI51BT@cknow.org>
References: <6b272e2f8f916c04b05db50df621659a5a7f29ab.1733149874.git.dsimic@manjaro.org>
 <D61DMK8O9JCR.1C62A5UGI51BT@cknow.org>
Message-ID: <a6eaa2ca428abe2bedf10cc8c213513b@manjaro.org>

Hello Diederik,

On 2024-12-02 18:05, Diederik de Haas wrote:
> I'd have swapped 'is' and 'HWRNG' in the subject, but otherwise ...

Ah, I'd actually write it as "Describe why the HWRNG is disabled
in the RK356x base SoC dtsi", but that's way too long for a patch
summary, so I went with something shorter that also makes it sound
more like a question than a statement. :)

> On Mon Dec 2, 2024 at 3:44 PM CET, Dragan Simic wrote:
>> Despite the presence of the hardware random number generator (HWRNG) 
>> in the
>> different Rockchip RK356x SoC variants, it remains disabled for the 
>> RK3566
>> SoC because testing showed [1] that it produces unacceptably low 
>> quality of
>> random data, for some yet unknown reason.  The HWRNG is enabled for 
>> the RK3568
>> SoC, on which the testing showed good quality of the generated random 
>> data.
>> 
>> To avoid possible confusion in the future, [2] let's have this 
>> described
>> briefly in the RK356x base SoC dtsi.
>> 
>> [1] 
>> https://lore.kernel.org/linux-rockchip/cover.1720969799.git.daniel at makrotopia.org/T/#u
>> [2] 
>> https://lore.kernel.org/linux-rockchip/20241201234613.52322-1-pbrobinson at gmail.com/T/#u
>> 
>> Signed-off-by: Dragan Simic <dsimic at manjaro.org>
>> ---
>>  arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 5 +++++
>>  1 file changed, 5 insertions(+)
>> 
>> diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi 
>> b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
>> index 62be06f3b863..ab8f42c0a843 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
>> @@ -1032,6 +1032,11 @@ sdhci: mmc at fe310000 {
>>  		status = "disabled";
>>  	};
>> 
>> +	/*
>> +	 * Testing showed that the HWRNG found in RK3566 produces 
>> unacceptably
>> +	 * low quality of random data, so the HWRNG isn't enabled for all 
>> RK356x
>> +	 * SoC variants despite its presence.
>> +	 */
>>  	rng: rng at fe388000 {
>>  		compatible = "rockchip,rk3568-rng";
>>  		reg = <0x0 0xfe388000 0x0 0x4000>;
> 
> Reviewed-by: Diederik de Haas <didi.debian at cknow.org>
> 
> Thanks for this :-)

Thanks. :)


From seanjc at google.com  Mon Dec  2 10:47:48 2024
From: seanjc at google.com (Sean Christopherson)
Date: Mon, 2 Dec 2024 10:47:48 -0800
Subject: [PATCH v4 15/16] KVM: selftests: Use canonical $(ARCH) paths for
 KVM selftests directories
In-Reply-To: <20241128092546.7a5b3f30@p-imbrenda>
References: <20241128005547.4077116-1-seanjc@google.com> <20241128005547.4077116-16-seanjc@google.com>
 <20241128092546.7a5b3f30@p-imbrenda>
Message-ID: <Z04A1Oh0LCKtCN4p@google.com>

On Thu, Nov 28, 2024, Claudio Imbrenda wrote:
> On Wed, 27 Nov 2024 16:55:46 -0800
> > diff --git a/tools/testing/selftests/kvm/include/x86_64/svm_util.h b/tools/testing/selftests/kvm/include/x86/svm_util.h
> > similarity index 94%
> > rename from tools/testing/selftests/kvm/include/x86_64/svm_util.h
> > rename to tools/testing/selftests/kvm/include/x86/svm_util.h
> > index 044f0f872ba9..b74c6dcddcbd 100644
> > --- a/tools/testing/selftests/kvm/include/x86_64/svm_util.h
> > +++ b/tools/testing/selftests/kvm/include/x86/svm_util.h
> > @@ -1,8 +1,5 @@
> >  /* SPDX-License-Identifier: GPL-2.0-only */
> >  /*
> > - * tools/testing/selftests/kvm/include/x86_64/svm_utils.h
> 
> this line clearly has to go ^
> 
> > - * Header for nested SVM testing
> 
> but I think this one can stay? ^

It should go too, the header contains declarations for helpers that having nothing
to do with nested SVM.

On a somewhat related topic, the file should probably be "svm.h", but that's a
future cleanup.


From wahrenst at gmx.net  Mon Dec  2 10:51:28 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon, 2 Dec 2024 19:51:28 +0100
Subject: [PATCH V5 2/9] dmaengine: bcm2835-dma: add suspend/resume pm
 support
In-Reply-To: <Z03l308ur7xuE1SB@vaman>
References: <20241025103621.4780-1-wahrenst@gmx.net>
 <20241025103621.4780-3-wahrenst@gmx.net> <Z03l308ur7xuE1SB@vaman>
Message-ID: <d418a30d-f0b0-49c5-8f2a-ddda9a7eeb07@gmx.net>

Hi Vinod,

Am 02.12.24 um 17:52 schrieb Vinod Koul:
> On 25-10-24, 12:36, Stefan Wahren wrote:
>> bcm2835-dma provides the service to others, so it should
>> suspend late and resume early.
>>
>> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
>> ---
>>   drivers/dma/bcm2835-dma.c | 30 ++++++++++++++++++++++++++++++
>>   1 file changed, 30 insertions(+)
>>
>> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
>> index e1b92b4d7b05..647dda9f3376 100644
>> --- a/drivers/dma/bcm2835-dma.c
>> +++ b/drivers/dma/bcm2835-dma.c
>> @@ -875,6 +875,35 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
>>   	return chan;
>>   }
>>
>> +static int bcm2835_dma_suspend_late(struct device *dev)
>> +{
>> +	struct bcm2835_dmadev *od = dev_get_drvdata(dev);
>> +	struct bcm2835_chan *c, *next;
>> +
>> +	list_for_each_entry_safe(c, next, &od->ddev.channels,
>> +				 vc.chan.device_node) {
>> +		void __iomem *chan_base = c->chan_base;
>> +
>> +		if (readl(chan_base + BCM2835_DMA_ADDR)) {
>> +			dev_warn(dev, "Suspend is prevented by chan %d\n",
>> +				 c->ch);
>> +			return -EBUSY;
>> +		}
> Can you help understand how this helps by logging... we are not adding
> anything except checking this and resume is NOP as well!
My intention of this patch is just to make sure, that no DMA transfer is
in progress during late_suspend. So i followed the implementation of
fsldma.c

Additionally i added this warning mostly to know if this ever occurs.
But i wasn't able to trigger.

Should i drop the warning and make resume callback = NULL?

Best regards




From danielmentz at google.com  Mon Dec  2 11:06:44 2024
From: danielmentz at google.com (Daniel Mentz)
Date: Mon, 2 Dec 2024 11:06:44 -0800
Subject: [PATCH 1/2] iommu/io-pgtable-arm: Fix stage-2 map/umap for
 concatenated tables
In-Reply-To: <Z02kIaxP96am-P2f@google.com>
References: <20241024162516.2005652-1-smostafa@google.com> <20241024162516.2005652-2-smostafa@google.com>
 <CAE2F3rDyj8WohXHTa1H3_gqTndyJL3cUEfBnXCEibNo1oYTt3A@mail.gmail.com> <Z02kIaxP96am-P2f@google.com>
Message-ID: <CAE2F3rAj74u5cs_iVTuU+RqJRYPTceVMqww9EFwC7X03Xave5w@mail.gmail.com>

Hi Mostafa,

On Mon, Dec 2, 2024 at 4:12?AM Mostafa Saleh <smostafa at google.com> wrote:
>
> Hi Daniel,
>
> On Sat, Nov 30, 2024 at 08:20:10PM -0800, Daniel Mentz wrote:
> > On Thu, Oct 24, 2024 at 9:26?AM Mostafa Saleh <smostafa at google.com> wrote:
> > >
> > > When calculating the max number of entries in a table, Where
> > > RM_LPAE_LVL_IDX() understands the concatenated pgds and can return
> > > an index spanning more than one concatenated table (for ex for 4K
> > > page size > 512).
> > > But then, max_entries is calculated as follows:
> > > max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start;
> > >
> > > This leads to a negative index in the page table, where for:
> > > - map: do nothing (no OOB) as fortunately all comparisons are signed,
> > >   but it would return a negative mapped value.
> > >
> > > - unmap: it would leak any child tables as it skips the loop over
> > >   ?__arm_lpae_free_pgtable?
> > >
> > > This bug only happens when map/unmap is requested with a page size
> > > equals to the first level of the concatenated table (for 40 bits input
> > > and 4K granule would be 1GB) and can be triggered from userspace with
> > > VFIO, by choosing a VM IPA in a concatenated table > 0 and using
> > > huge pages to mmap with the first level size.
> > >
> > > For example, I was able to reproduce it with the following command
> > > with mainline linux and mainline kvmtool:
> > >
> > > ./lkvm run --irqchip gicv3 -k {$KERNEL} -p "earlycon" -d {$ROOTFS}  --force-pci -c \
> > > `nproc` --debug -m 4096 at 525312 --vfio-pci 0000:00:03.0  --hugetlbfs  /hugepages
> > >
> > > Where huge pages with 1GB would be used and using IPA in the second table
> > > (512GB for 40 bits SMMU and 4K granule).
> > >
> > > Signed-off-by: Mostafa Saleh <smostafa at google.com>
> > > ---
> > >  drivers/iommu/io-pgtable-arm.c | 17 ++++++++++++++---
> > >  1 file changed, 14 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> > > index 0e67f1721a3d..3ecbc024e440 100644
> > > --- a/drivers/iommu/io-pgtable-arm.c
> > > +++ b/drivers/iommu/io-pgtable-arm.c
> > > @@ -199,6 +199,17 @@ static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
> > >         return (paddr | (paddr << (48 - 12))) & (ARM_LPAE_PTE_ADDR_MASK << 4);
> > >  }
> > >
> > > +/*
> > > + * Using an index returned from ARM_LPAE_PGD_IDX(), which can point to
> > > + * concatenated PGD concatenated, get the max entries of a that table.
> >
> > I believe the macro that returns an index is called ARM_LPAE_LVL_IDX
> > not ARM_LPAE_PGD_IDX.
> >
>
> Yes, the comment is not quite accurate, although ARM_LPAE_PGD_IDX()
> calls ARM_LPAE_PGD_IDX() which is the problem.

I assume you mean the problem is that ARM_LPAE_LVL_IDX() calls into
ARM_LPAE_PGD_IDX().

I find that ARM_LPAE_PGD_IDX is a misnomer as it returns a number of
bits as opposed to an index. Something like ARM_LPAE_PGD_EXTRA_BITS
would be a more appropriate name.

>
> Thanks,
> Mostafa
>
> > > + */
> > > +static inline int arm_lpae_max_entries(int i, struct arm_lpae_io_pgtable *data)
> > > +{
> > > +       int ptes_per_table = ARM_LPAE_PTES_PER_TABLE(data);
> > > +
> > > +       return ptes_per_table - (i & (ptes_per_table - 1));
> > > +}
> > > +
> > >  static bool selftest_running = false;
> > >
> > >  static dma_addr_t __arm_lpae_dma_addr(void *pages)
> > > @@ -390,7 +401,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
> > >
> > >         /* If we can install a leaf entry at this level, then do so */
> > >         if (size == block_size) {
> > > -               max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start;
> > > +               max_entries = arm_lpae_max_entries(map_idx_start, data);
> > >                 num_entries = min_t(int, pgcount, max_entries);
> > >                 ret = arm_lpae_init_pte(data, iova, paddr, prot, lvl, num_entries, ptep);
> > >                 if (!ret)
> > > @@ -592,7 +603,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
> > >
> > >         if (size == split_sz) {
> > >                 unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
> > > -               max_entries = ptes_per_table - unmap_idx_start;
> > > +               max_entries = arm_lpae_max_entries(unmap_idx_start, data);
> > >                 num_entries = min_t(int, pgcount, max_entries);
> > >         }
> > >
> > > @@ -650,7 +661,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
> > >
> > >         /* If the size matches this level, we're in the right place */
> > >         if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) {
> > > -               max_entries = ARM_LPAE_PTES_PER_TABLE(data) - unmap_idx_start;
> > > +               max_entries = arm_lpae_max_entries(unmap_idx_start, data);
> > >                 num_entries = min_t(int, pgcount, max_entries);
> > >
> > >                 /* Find and handle non-leaf entries */
> > > --
> > > 2.47.0.105.g07ac214952-goog
> > >
> > >


From cl at os.amperecomputing.com  Mon Dec  2 11:19:07 2024
From: cl at os.amperecomputing.com (Christoph Lameter)
Date: Mon, 2 Dec 2024 11:19:07 -0800 (PST)
Subject: [PATCH v2 4/4] arm64: add a new document for the fine-tuning
 tips
In-Reply-To: <20241126085647.4993-5-shijie@os.amperecomputing.com>
References: <20241126085647.4993-1-shijie@os.amperecomputing.com> <20241126085647.4993-5-shijie@os.amperecomputing.com>
Message-ID: <76013b75-dce9-b37c-f2af-9556f14f6301@os.amperecomputing.com>

On Tue, 26 Nov 2024, Huang Shijie wrote:

> +slab_strict_numa
> +----------------
> +In NUMA, it will provide the local memory allocation by SLUB.

"Slab objects will be placed individually according to memory policies. 
Increases object locality which is useful for NUMA systems using SLC 
caches"


From afd at ti.com  Mon Dec  2 11:41:02 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 2 Dec 2024 13:41:02 -0600
Subject: [PATCH v4 0/5] Switch more ARM plats to sys-off handler API
Message-ID: <20241202194107.105119-1-afd@ti.com>

Hello all,

Continuing the quest to remove the legacy pm_power_off() global
function handler. Remove uses from arch/arm/ using the helper
register_platform_power_off().

Thanks,
Andrew

Changes for v4:
 - Drop already taken patches
 - Rebase on latest master

Changes for v3:
 - Rebase on v6.12-rc1

Changes for v2:
 - Collect Reviewed/Acked-bys
 - Rebase on v6.11-rc1

Andrew Davis (5):
  ARM: highbank: Switch to new sys-off handler API
  ARM: pxa: Switch to new sys-off handler API
  ARM: sa1100: Switch to new sys-off handler API
  ARM: vt8500: Switch to new sys-off handler API
  arm/xen: Switch to new sys-off handler API

 arch/arm/mach-highbank/highbank.c | 2 +-
 arch/arm/mach-pxa/spitz.c         | 2 +-
 arch/arm/mach-sa1100/generic.c    | 2 +-
 arch/arm/mach-vt8500/vt8500.c     | 2 +-
 arch/arm/xen/enlighten.c          | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

-- 
2.39.2



From afd at ti.com  Mon Dec  2 11:41:03 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 2 Dec 2024 13:41:03 -0600
Subject: [PATCH v4 1/5] ARM: highbank: Switch to new sys-off handler API
In-Reply-To: <20241202194107.105119-1-afd@ti.com>
References: <20241202194107.105119-1-afd@ti.com>
Message-ID: <20241202194107.105119-2-afd@ti.com>

Kernel now supports chained power-off handlers. Use
register_platform_power_off() that registers a platform level power-off
handler. Legacy pm_power_off() will be removed once all drivers and archs
are converted to the new sys-off API.

Signed-off-by: Andrew Davis <afd at ti.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm/mach-highbank/highbank.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 5d4f977ac7d2a..47335c7dadf8d 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -143,7 +143,7 @@ static void __init highbank_init(void)
 	sregs_base = of_iomap(np, 0);
 	WARN_ON(!sregs_base);
 
-	pm_power_off = highbank_power_off;
+	register_platform_power_off(highbank_power_off);
 	highbank_pm_init();
 
 	bus_register_notifier(&platform_bus_type, &highbank_platform_nb);
-- 
2.39.2



From afd at ti.com  Mon Dec  2 11:41:04 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 2 Dec 2024 13:41:04 -0600
Subject: [PATCH v4 2/5] ARM: pxa: Switch to new sys-off handler API
In-Reply-To: <20241202194107.105119-1-afd@ti.com>
References: <20241202194107.105119-1-afd@ti.com>
Message-ID: <20241202194107.105119-3-afd@ti.com>

Kernel now supports chained power-off handlers. Use
register_platform_power_off() that registers a platform level power-off
handler. Legacy pm_power_off() will be removed once all drivers and archs
are converted to the new sys-off API.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 arch/arm/mach-pxa/spitz.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 33533e35720f8..c0b1f7e6be874 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -1096,7 +1096,7 @@ static void __init spitz_init(void)
 		software_node_register(&spitz_scoop_2_gpiochip_node);
 
 	init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0);
-	pm_power_off = spitz_poweroff;
+	register_platform_power_off(spitz_poweroff);
 
 	PMCR = 0x00;
 
-- 
2.39.2



From afd at ti.com  Mon Dec  2 11:41:05 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 2 Dec 2024 13:41:05 -0600
Subject: [PATCH v4 3/5] ARM: sa1100: Switch to new sys-off handler API
In-Reply-To: <20241202194107.105119-1-afd@ti.com>
References: <20241202194107.105119-1-afd@ti.com>
Message-ID: <20241202194107.105119-4-afd@ti.com>

Kernel now supports chained power-off handlers. Use
register_platform_power_off() that registers a platform level power-off
handler. Legacy pm_power_off() will be removed once all drivers and archs
are converted to the new sys-off API.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 arch/arm/mach-sa1100/generic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 0c586047d130f..5383a26f51169 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -298,7 +298,7 @@ static struct platform_device *sa11x0_devices[] __initdata = {
 static int __init sa1100_init(void)
 {
 	struct resource wdt_res = DEFINE_RES_MEM(0x90000000, 0x20);
-	pm_power_off = sa1100_power_off;
+	register_platform_power_off(sa1100_power_off);
 
 	regulator_has_full_constraints();
 
-- 
2.39.2



From afd at ti.com  Mon Dec  2 11:41:06 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 2 Dec 2024 13:41:06 -0600
Subject: [PATCH v4 4/5] ARM: vt8500: Switch to new sys-off handler API
In-Reply-To: <20241202194107.105119-1-afd@ti.com>
References: <20241202194107.105119-1-afd@ti.com>
Message-ID: <20241202194107.105119-5-afd@ti.com>

Kernel now supports chained power-off handlers. Use
register_platform_power_off() that registers a platform level power-off
handler. Legacy pm_power_off() will be removed once all drivers and archs
are converted to the new sys-off API.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 arch/arm/mach-vt8500/vt8500.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c
index 0ab40087ae1cc..1d294255d7083 100644
--- a/arch/arm/mach-vt8500/vt8500.c
+++ b/arch/arm/mach-vt8500/vt8500.c
@@ -141,7 +141,7 @@ static void __init vt8500_init(void)
 			pr_err("%s:ioremap(power_off) failed\n", __func__);
 	}
 	if (pmc_base)
-		pm_power_off = &vt8500_power_off;
+		register_platform_power_off(vt8500_power_off);
 	else
 		pr_err("%s: PMC Hibernation register could not be remapped, not enabling power off!\n", __func__);
 }
-- 
2.39.2



From afd at ti.com  Mon Dec  2 11:41:07 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 2 Dec 2024 13:41:07 -0600
Subject: [PATCH v4 5/5] arm/xen: Switch to new sys-off handler API
In-Reply-To: <20241202194107.105119-1-afd@ti.com>
References: <20241202194107.105119-1-afd@ti.com>
Message-ID: <20241202194107.105119-6-afd@ti.com>

Kernel now supports chained power-off handlers. Use
register_platform_power_off() that registers a platform level power-off
handler. Legacy pm_power_off() will be removed once all drivers and archs
are converted to the new sys-off API.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 arch/arm/xen/enlighten.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index a395b6c0aae2a..8655bc3d36347 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -541,7 +541,7 @@ static int __init xen_late_init(void)
 	if (!xen_domain())
 		return -ENODEV;
 
-	pm_power_off = xen_power_off;
+	register_platform_power_off(xen_power_off);
 	register_restart_handler(&xen_restart_nb);
 	if (!xen_initial_domain()) {
 		struct timespec64 ts;
-- 
2.39.2



From eajames at linux.ibm.com  Mon Dec  2 11:43:24 2024
From: eajames at linux.ibm.com (Eddie James)
Date: Mon, 2 Dec 2024 13:43:24 -0600
Subject: [PATCH] fsc: Switch back to struct platform_driver::remove()
In-Reply-To: <20241130150530.901263-2-u.kleine-koenig@baylibre.com>
References: <20241130150530.901263-2-u.kleine-koenig@baylibre.com>
Message-ID: <8896a6db-6208-4095-bdf8-f5d21b519631@linux.ibm.com>


On 11/30/24 09:05, Uwe Kleine-K?nig wrote:
> After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
> return void") .remove() is (again) the right callback to implement for
> platform drivers.
>
> Convert all platform drivers below drivers/fsi to use .remove(), with
> the eventual goal to drop struct platform_driver::remove_new(). As
> .remove() and .remove_new() have the same prototypes, conversion is done
> by just changing the structure member name in the driver initializer.
>
> While touching these drivers, make the alignment of the touched
> initializers consistent.


Thanks.


Reviewed-by: Eddie James <eajames at linux.ibm.com>


>
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>
> ---
> Hello,
>
> this is based on Friday's next, feel free to drop changes that result in
> a conflict when you come around to apply this. I'll care for the fallout
> at a later time then. (Having said that, if you use b4 am -3 and git am
> -3, there should be hardly any conflict.)
>
> This is merge window material.
>
> Best regards
> Uwe
>
>   drivers/fsi/fsi-master-aspeed.c | 4 ++--
>   drivers/fsi/fsi-master-ast-cf.c | 4 ++--
>   drivers/fsi/fsi-master-gpio.c   | 4 ++--
>   drivers/fsi/fsi-occ.c           | 6 +++---
>   4 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
> index 6f5e1bdf7e40..0f66bc8ac2de 100644
> --- a/drivers/fsi/fsi-master-aspeed.c
> +++ b/drivers/fsi/fsi-master-aspeed.c
> @@ -661,12 +661,12 @@ static const struct of_device_id fsi_master_aspeed_match[] = {
>   MODULE_DEVICE_TABLE(of, fsi_master_aspeed_match);
>   
>   static struct platform_driver fsi_master_aspeed_driver = {
> -	.driver = {
> +	.driver	= {
>   		.name		= "fsi-master-aspeed",
>   		.of_match_table	= fsi_master_aspeed_match,
>   	},
>   	.probe	= fsi_master_aspeed_probe,
> -	.remove_new = fsi_master_aspeed_remove,
> +	.remove	= fsi_master_aspeed_remove,
>   };
>   
>   module_platform_driver(fsi_master_aspeed_driver);
> diff --git a/drivers/fsi/fsi-master-ast-cf.c b/drivers/fsi/fsi-master-ast-cf.c
> index a4c37ff8edd6..4ed2f33284cf 100644
> --- a/drivers/fsi/fsi-master-ast-cf.c
> +++ b/drivers/fsi/fsi-master-ast-cf.c
> @@ -1429,12 +1429,12 @@ static const struct of_device_id fsi_master_acf_match[] = {
>   MODULE_DEVICE_TABLE(of, fsi_master_acf_match);
>   
>   static struct platform_driver fsi_master_acf = {
> -	.driver = {
> +	.driver	= {
>   		.name		= "fsi-master-acf",
>   		.of_match_table	= fsi_master_acf_match,
>   	},
>   	.probe	= fsi_master_acf_probe,
> -	.remove_new = fsi_master_acf_remove,
> +	.remove	= fsi_master_acf_remove,
>   };
>   
>   module_platform_driver(fsi_master_acf);
> diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
> index f761344f4873..9f8bfc43ad93 100644
> --- a/drivers/fsi/fsi-master-gpio.c
> +++ b/drivers/fsi/fsi-master-gpio.c
> @@ -883,12 +883,12 @@ static const struct of_device_id fsi_master_gpio_match[] = {
>   MODULE_DEVICE_TABLE(of, fsi_master_gpio_match);
>   
>   static struct platform_driver fsi_master_gpio_driver = {
> -	.driver = {
> +	.driver	= {
>   		.name		= "fsi-master-gpio",
>   		.of_match_table	= fsi_master_gpio_match,
>   	},
>   	.probe	= fsi_master_gpio_probe,
> -	.remove_new = fsi_master_gpio_remove,
> +	.remove	= fsi_master_gpio_remove,
>   };
>   
>   module_platform_driver(fsi_master_gpio_driver);
> diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c
> index a6d4c8f123a5..b5a7372a680c 100644
> --- a/drivers/fsi/fsi-occ.c
> +++ b/drivers/fsi/fsi-occ.c
> @@ -737,10 +737,10 @@ MODULE_DEVICE_TABLE(of, occ_match);
>   static struct platform_driver occ_driver = {
>   	.driver = {
>   		.name = "occ",
> -		.of_match_table	= occ_match,
> +		.of_match_table = occ_match,
>   	},
> -	.probe	= occ_probe,
> -	.remove_new = occ_remove,
> +	.probe = occ_probe,
> +	.remove = occ_remove,
>   };
>   
>   static int occ_init(void)
>
> base-commit: f486c8aa16b8172f63bddc70116a0c897a7f3f02


From cristian.ciocaltea at collabora.com  Mon Dec  2 12:00:57 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 02 Dec 2024 22:00:57 +0200
Subject: [PATCH] arm64: defconfig: Enable Rockchip extensions for Synopsys
 DW HDMI QP
Message-ID: <20241202-dw-hdmi-qp-rk-defconfig-v1-1-38757fc053d0@collabora.com>

Enable Rockchip specific extensions for Synopsys DesignWare HDMI
Quad-Pixel (QP) driver.  This is needed to provide HDMI output support
for the boards based on RK3588 SoC.

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 c62831e6158633f07c1f3532fba62f09b31e7448..286a386496014cf6d7d03d1efaa84ef4cffd57af 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -872,6 +872,7 @@ CONFIG_ROCKCHIP_VOP2=y
 CONFIG_ROCKCHIP_ANALOGIX_DP=y
 CONFIG_ROCKCHIP_CDN_DP=y
 CONFIG_ROCKCHIP_DW_HDMI=y
+CONFIG_ROCKCHIP_DW_HDMI_QP=y
 CONFIG_ROCKCHIP_DW_MIPI_DSI=y
 CONFIG_ROCKCHIP_INNO_HDMI=y
 CONFIG_ROCKCHIP_LVDS=y

---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241202-dw-hdmi-qp-rk-defconfig-dd15747526aa



From Frank.li at nxp.com  Mon Dec  2 12:21:57 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 2 Dec 2024 15:21:57 -0500
Subject: [PATCH v3 0/4] Add i.MX91 platform support
In-Reply-To: <Z01gfuVIIhl0rYwI@pengfei-OptiPlex-Tower-Plus-7010>
References: <20241120094945.3032663-1-pengfei.li_1@nxp.com>
 <Z01gfuVIIhl0rYwI@pengfei-OptiPlex-Tower-Plus-7010>
Message-ID: <Z04W5chGq5TitB9f@lizhi-Precision-Tower-5810>

On Mon, Dec 02, 2024 at 03:24:44PM +0800, Pengfei Li wrote:
> On Wed, Nov 20, 2024 at 05:49:41PM +0800, Pengfei Li wrote:
> > The design of the i.MX91 platform is very similar to i.MX93.
> > The mainly difference between i.MX91 and i.MX93 is as follows:
> > - i.MX91 removed some clocks and modified the names of some clocks.
> > - i.MX91 only has one A core
> > - i.MX91 has different pinmux
> >
> > Therefore, i.MX91 can reuse i.MX93 dtsi.
> >
> > ---
> > Change for v3:
> > - Add Conor's ack on patch #1
> > - format imx91-11x11-evk.dts with the dt-format tool
> > - add lpi2c1 node
> > - link to v2: https://lore.kernel.org/all/20241118051541.2621360-1-pengfei.li_1 at nxp.com/
> >
> > Pengfei Li (4):
> >   dt-bindings: arm: fsl: Add i.MX91 11x11 evk board
> >   arm64: dts: freescale: Add i.MX91 dtsi support
> >   arm64: dts: freescale: Add i.MX91 11x11 EVK basic support
> >   arm64: defconfig: enable i.MX91 pinctrl
> >
> >  .../devicetree/bindings/arm/fsl.yaml          |   6 +
> >  arch/arm64/boot/dts/freescale/Makefile        |   1 +
> >  .../boot/dts/freescale/imx91-11x11-evk.dts    | 875 ++++++++++++++++++
> >  arch/arm64/boot/dts/freescale/imx91-pinfunc.h | 770 +++++++++++++++
> >  arch/arm64/boot/dts/freescale/imx91.dtsi      |  70 ++
> >  arch/arm64/configs/defconfig                  |   1 +
> >  6 files changed, 1723 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx91-pinfunc.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx91.dtsi
> >
> > --
> > 2.34.1
> >
> >
>
> Hi Rob Herring,
>
> I haven't received any comments from others about this version of the patch set, is this patch set applicable?

Pengfei:

	Conor Dooley have acked binding patch. Wait for guo shawn pick up
these. v6.13-rc1 just create.

Frank


>
> BR,
> Pengfei Li
>


From afd at ti.com  Mon Dec  2 12:27:19 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 2 Dec 2024 14:27:19 -0600
Subject: [PATCH v2] ARM: mach-hpe: Rework support and directory structure
Message-ID: <20241202202719.111739-1-afd@ti.com>

Having a platform need a mach-* directory should be seen as a negative,
it means the platform needs special non-standard handling. ARM64 support
does not allow mach-* directories at all. While we may not get to that
given all the non-standard architectures we support, we should still try
to get as close as we can and reduce the number of mach directories.

The mach-hpe/ directory and files, provides just one "feature":
having the kernel print the machine name if the DTB does not also contain
a "model" string (which they always do). To reduce the number of mach-*
directories let's do without that feature and remove this directory.

Note, we drop the l2c_aux_mask = ~0 line, but this is safe as
the fallback GENERIC_DT machine has that as the default.

Signed-off-by: Andrew Davis <afd at ti.com>
---

Changes for v2:
 - Rebased on v6.13-rc1

 MAINTAINERS                |  1 -
 arch/arm/Kconfig           |  2 --
 arch/arm/Kconfig.platforms | 25 +++++++++++++++++++++++++
 arch/arm/Makefile          |  1 -
 arch/arm/mach-hpe/Kconfig  | 23 -----------------------
 arch/arm/mach-hpe/Makefile |  1 -
 arch/arm/mach-hpe/gxp.c    | 15 ---------------
 7 files changed, 25 insertions(+), 43 deletions(-)
 delete mode 100644 arch/arm/mach-hpe/Kconfig
 delete mode 100644 arch/arm/mach-hpe/Makefile
 delete mode 100644 arch/arm/mach-hpe/gxp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b13..8d8f3caa4066d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2489,7 +2489,6 @@ F:	Documentation/devicetree/bindings/spi/hpe,gxp-spifi.yaml
 F:	Documentation/devicetree/bindings/timer/hpe,gxp-timer.yaml
 F:	Documentation/hwmon/gxp-fan-ctrl.rst
 F:	arch/arm/boot/dts/hpe/
-F:	arch/arm/mach-hpe/
 F:	drivers/clocksource/timer-gxp.c
 F:	drivers/hwmon/gxp-fan-ctrl.c
 F:	drivers/i2c/busses/i2c-gxp.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 202397be76d80..4053aee636ef1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -391,8 +391,6 @@ source "arch/arm/mach-highbank/Kconfig"
 
 source "arch/arm/mach-hisi/Kconfig"
 
-source "arch/arm/mach-hpe/Kconfig"
-
 source "arch/arm/mach-imx/Kconfig"
 
 source "arch/arm/mach-ixp4xx/Kconfig"
diff --git a/arch/arm/Kconfig.platforms b/arch/arm/Kconfig.platforms
index 845ab08e20a4b..5c19c1f2cff61 100644
--- a/arch/arm/Kconfig.platforms
+++ b/arch/arm/Kconfig.platforms
@@ -87,6 +87,31 @@ config MACH_ASM9260
 	help
 	  Support for Alphascale ASM9260 based platform.
 
+menuconfig ARCH_HPE
+	bool "HPE SoC support"
+	depends on ARCH_MULTI_V7
+	help
+	  This enables support for HPE ARM based BMC chips.
+
+if ARCH_HPE
+
+config ARCH_HPE_GXP
+	bool "HPE GXP SoC"
+	depends on ARCH_MULTI_V7
+	select ARM_VIC
+	select GENERIC_IRQ_CHIP
+	select CLKSRC_MMIO
+	help
+	  HPE GXP is the name of the HPE Soc. This SoC is used to implement many
+	  BMC features at HPE. It supports ARMv7 architecture based on the Cortex
+	  A9 core. It is capable of using an AXI bus to which a memory controller
+	  is attached. It has multiple SPI interfaces to connect boot flash and
+	  BIOS flash. It uses a 10/100/1000 MAC for network connectivity. It
+	  has multiple i2c engines to drive connectivity with a host
+	  infrastructure.
+
+endif
+
 menuconfig ARCH_MOXART
 	bool "MOXA ART SoC"
 	depends on ARCH_MULTI_V4
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 00ca7886b18ef..c1cd02a53aa3d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -188,7 +188,6 @@ machine-$(CONFIG_ARCH_FOOTBRIDGE)	+= footbridge
 machine-$(CONFIG_ARCH_GEMINI)		+= gemini
 machine-$(CONFIG_ARCH_HIGHBANK)		+= highbank
 machine-$(CONFIG_ARCH_HISI)		+= hisi
-machine-$(CONFIG_ARCH_HPE)		+= hpe
 machine-$(CONFIG_ARCH_IXP4XX)		+= ixp4xx
 machine-$(CONFIG_ARCH_KEYSTONE)		+= keystone
 machine-$(CONFIG_ARCH_LPC18XX)		+= lpc18xx
diff --git a/arch/arm/mach-hpe/Kconfig b/arch/arm/mach-hpe/Kconfig
deleted file mode 100644
index 3372bbf38d383..0000000000000
--- a/arch/arm/mach-hpe/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-menuconfig ARCH_HPE
-	bool "HPE SoC support"
-	depends on ARCH_MULTI_V7
-	help
-	  This enables support for HPE ARM based BMC chips.
-if ARCH_HPE
-
-config ARCH_HPE_GXP
-	bool "HPE GXP SoC"
-	depends on ARCH_MULTI_V7
-	select ARM_VIC
-	select GENERIC_IRQ_CHIP
-	select CLKSRC_MMIO
-	help
-	  HPE GXP is the name of the HPE Soc. This SoC is used to implement many
-	  BMC features at HPE. It supports ARMv7 architecture based on the Cortex
-	  A9 core. It is capable of using an AXI bus to which a memory controller
-	  is attached. It has multiple SPI interfaces to connect boot flash and
-	  BIOS flash. It uses a 10/100/1000 MAC for network connectivity. It
-	  has multiple i2c engines to drive connectivity with a host
-	  infrastructure.
-
-endif
diff --git a/arch/arm/mach-hpe/Makefile b/arch/arm/mach-hpe/Makefile
deleted file mode 100644
index 8b0a91234df4e..0000000000000
--- a/arch/arm/mach-hpe/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_ARCH_HPE_GXP) += gxp.o
diff --git a/arch/arm/mach-hpe/gxp.c b/arch/arm/mach-hpe/gxp.c
deleted file mode 100644
index 581c8da517b86..0000000000000
--- a/arch/arm/mach-hpe/gxp.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P. */
-
-#include <asm/mach/arch.h>
-
-static const char * const gxp_board_dt_compat[] = {
-	"hpe,gxp",
-	NULL,
-};
-
-DT_MACHINE_START(GXP_DT, "HPE GXP")
-	.dt_compat	= gxp_board_dt_compat,
-	.l2c_aux_val = 0,
-	.l2c_aux_mask = ~0,
-MACHINE_END
-- 
2.39.2



From cristian.ciocaltea at collabora.com  Mon Dec  2 12:27:34 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 02 Dec 2024 22:27:34 +0200
Subject: [PATCH] drm/rockchip: dw_hdmi_qp: Simplify clock handling
Message-ID: <20241202-dw-hdmi-qp-rk-clk-bulk-v1-1-60a7cc9cd74e@collabora.com>

Make use of the recently introduced devm_clk_bulk_get_all_enabled()
helper to simplify the code a bit.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 28 +++++++++++++-------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index c8b362cc2b95fd490029a9c0552ad9fbc5631d17..20ecc0729db9f5e321041ae7b3349bff5246a926 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -214,17 +214,13 @@ MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids);
 static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 				    void *data)
 {
-	static const char * const clk_names[] = {
-		"pclk", "earc", "aud", "hdp", "hclk_vo1",
-		"ref" /* keep "ref" last */
-	};
 	struct platform_device *pdev = to_platform_device(dev);
 	struct dw_hdmi_qp_plat_data plat_data;
 	struct drm_device *drm = data;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
 	struct rockchip_hdmi_qp *hdmi;
-	struct clk *clk;
+	struct clk_bulk_data *clks;
 	int ret, irq, i;
 	u32 val;
 
@@ -270,18 +266,22 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 		return PTR_ERR(hdmi->vo_regmap);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(clk_names); i++) {
-		clk = devm_clk_get_enabled(hdmi->dev, clk_names[i]);
+	ret = devm_clk_bulk_get_all_enabled(hdmi->dev, &clks);
+	if (ret < 0) {
+		drm_err(hdmi, "Failed to get clocks: %d\n", ret);
+		return ret;
+	}
 
-		if (IS_ERR(clk)) {
-			ret = PTR_ERR(clk);
-			if (ret != -EPROBE_DEFER)
-				drm_err(hdmi, "Failed to get %s clock: %d\n",
-					clk_names[i], ret);
-			return ret;
+	for (i = 0; i < ret; i++) {
+		if (!strcmp(clks[i].id, "ref")) {
+			hdmi->ref_clk = clks[1].clk;
+			break;
 		}
 	}
-	hdmi->ref_clk = clk;
+	if (!hdmi->ref_clk) {
+		drm_err(hdmi, "Missing ref clock\n");
+		return -EINVAL;
+	}
 
 	hdmi->enable_gpio = devm_gpiod_get_optional(hdmi->dev, "enable",
 						    GPIOD_OUT_HIGH);

---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241202-dw-hdmi-qp-rk-clk-bulk-3dfa0152e814



From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:51 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:51 +0100
Subject: [PATCH net-next v7 12/15] net: dwmac-sti: Use helper rgmii_clock
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-12-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index a6ff02d905a9..eabc4da9e1a9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -21,10 +21,7 @@
 
 #include "stmmac_platform.h"
 
-#define DWMAC_125MHZ	125000000
 #define DWMAC_50MHZ	50000000
-#define DWMAC_25MHZ	25000000
-#define DWMAC_2_5MHZ	2500000
 
 #define IS_PHY_IF_MODE_RGMII(iface)	(iface == PHY_INTERFACE_MODE_RGMII || \
 			iface == PHY_INTERFACE_MODE_RGMII_ID || \
@@ -140,7 +137,7 @@ static void stih4xx_fix_retime_src(void *priv, u32 spd, unsigned int mode)
 	struct sti_dwmac *dwmac = priv;
 	u32 src = dwmac->tx_retime_src;
 	u32 reg = dwmac->ctrl_reg;
-	u32 freq = 0;
+	long freq = 0;
 
 	if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
 		src = TX_RETIME_SRC_TXCLK;
@@ -153,19 +150,14 @@ static void stih4xx_fix_retime_src(void *priv, u32 spd, unsigned int mode)
 		}
 	} else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
 		/* On GiGa clk source can be either ext or from clkgen */
-		if (spd == SPEED_1000) {
-			freq = DWMAC_125MHZ;
-		} else {
+		freq = rgmii_clock(spd);
+
+		if (spd != SPEED_1000 && freq > 0)
 			/* Switch to clkgen for these speeds */
 			src = TX_RETIME_SRC_CLKGEN;
-			if (spd == SPEED_100)
-				freq = DWMAC_25MHZ;
-			else if (spd == SPEED_10)
-				freq = DWMAC_2_5MHZ;
-		}
 	}
 
-	if (src == TX_RETIME_SRC_CLKGEN && freq)
+	if (src == TX_RETIME_SRC_CLKGEN && freq > 0)
 		clk_set_rate(dwmac->clk, freq);
 
 	regmap_update_bits(dwmac->regmap, reg, STIH4XX_RETIME_SRC_MASK,

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:53 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:53 +0100
Subject: [PATCH net-next v7 14/15] net: stmmac: dwmac-s32: add basic NXP
 S32G/S32R glue driver
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-14-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

NXP S32G2xx/S32G3xx and S32R45 are automotive grade SoCs
that integrate one or two Synopsys DWMAC 5.10/5.20 IPs.

The basic driver supports only RGMII interface.

Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig     |  12 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile    |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c | 189 ++++++++++++++++++++++++
 3 files changed, 202 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 6658536a4e17..4cc85a36a1ab 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -154,6 +154,18 @@ config DWMAC_RZN1
 	  the stmmac device driver. This support can make use of a custom MII
 	  converter PCS device.
 
+config DWMAC_S32
+	tristate "NXP S32G/S32R GMAC support"
+	default ARCH_S32
+	depends on OF && (ARCH_S32 || COMPILE_TEST)
+	help
+	  Support for ethernet controller on NXP S32CC SOCs.
+
+	  This selects NXP SoC glue layer support for the stmmac
+	  device driver. This driver is used for the S32CC series
+	  SOCs GMAC ethernet controller, ie. S32G2xx, S32G3xx and
+	  S32R45.
+
 config DWMAC_SOCFPGA
 	tristate "SOCFPGA dwmac support"
 	default ARCH_INTEL_SOCFPGA
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 2389fd261344..b26f0e79c2b3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_DWMAC_MESON)	+= dwmac-meson.o dwmac-meson8b.o
 obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-ethqos.o
 obj-$(CONFIG_DWMAC_ROCKCHIP)	+= dwmac-rk.o
 obj-$(CONFIG_DWMAC_RZN1)	+= dwmac-rzn1.o
+obj-$(CONFIG_DWMAC_S32)		+= dwmac-s32.o
 obj-$(CONFIG_DWMAC_SOCFPGA)	+= dwmac-altr-socfpga.o
 obj-$(CONFIG_DWMAC_STARFIVE)	+= dwmac-starfive.o
 obj-$(CONFIG_DWMAC_STI)		+= dwmac-sti.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
new file mode 100644
index 000000000000..1853a6b26e46
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP S32G/R GMAC glue layer
+ *
+ * Copyright 2019-2024 NXP
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/ethtool.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_mdio.h>
+#include <linux/of_address.h>
+#include <linux/phy.h>
+#include <linux/phylink.h>
+#include <linux/platform_device.h>
+#include <linux/stmmac.h>
+
+#include "stmmac_platform.h"
+
+#define GMAC_TX_RATE_125M	125000000	/* 125MHz */
+
+/* SoC PHY interface control register */
+#define PHY_INTF_SEL_MII	0x00
+#define PHY_INTF_SEL_SGMII	0x01
+#define PHY_INTF_SEL_RGMII	0x02
+#define PHY_INTF_SEL_RMII	0x08
+
+struct s32_priv_data {
+	void __iomem *ioaddr;
+	void __iomem *ctrl_sts;
+	struct device *dev;
+	phy_interface_t *intf_mode;
+	struct clk *tx_clk;
+	struct clk *rx_clk;
+};
+
+static int s32_gmac_write_phy_intf_select(struct s32_priv_data *gmac)
+{
+	writel(PHY_INTF_SEL_RGMII, gmac->ctrl_sts);
+
+	dev_dbg(gmac->dev, "PHY mode set to %s\n", phy_modes(*gmac->intf_mode));
+
+	return 0;
+}
+
+static int s32_gmac_init(struct platform_device *pdev, void *priv)
+{
+	struct s32_priv_data *gmac = priv;
+	int ret;
+
+	ret = clk_set_rate(gmac->tx_clk, GMAC_TX_RATE_125M);
+	if (!ret)
+		ret = clk_prepare_enable(gmac->tx_clk);
+
+	if (ret) {
+		dev_err(&pdev->dev, "Can't set tx clock\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(gmac->rx_clk);
+	if (ret) {
+		clk_disable_unprepare(gmac->tx_clk);
+		dev_err(&pdev->dev, "Can't set rx clock\n");
+		return ret;
+	}
+
+	ret = s32_gmac_write_phy_intf_select(gmac);
+	if (ret) {
+		clk_disable_unprepare(gmac->tx_clk);
+		clk_disable_unprepare(gmac->rx_clk);
+		dev_err(&pdev->dev, "Can't set PHY interface mode\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void s32_gmac_exit(struct platform_device *pdev, void *priv)
+{
+	struct s32_priv_data *gmac = priv;
+
+	clk_disable_unprepare(gmac->tx_clk);
+	clk_disable_unprepare(gmac->rx_clk);
+}
+
+static void s32_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
+{
+	struct s32_priv_data *gmac = priv;
+	long tx_clk_rate;
+	int ret;
+
+	tx_clk_rate = rgmii_clock(speed);
+	if (tx_clk_rate < 0) {
+		dev_err(gmac->dev, "Unsupported/Invalid speed: %d\n", speed);
+		return;
+	}
+
+	dev_dbg(gmac->dev, "Set tx clock to %ld Hz\n", tx_clk_rate);
+	ret = clk_set_rate(gmac->tx_clk, tx_clk_rate);
+	if (ret)
+		dev_err(gmac->dev, "Can't set tx clock\n");
+}
+
+static int s32_dwmac_probe(struct platform_device *pdev)
+{
+	struct plat_stmmacenet_data *plat;
+	struct device *dev = &pdev->dev;
+	struct stmmac_resources res;
+	struct s32_priv_data *gmac;
+	int ret;
+
+	gmac = devm_kzalloc(&pdev->dev, sizeof(*gmac), GFP_KERNEL);
+	if (!gmac)
+		return -ENOMEM;
+
+	gmac->dev = &pdev->dev;
+
+	ret = stmmac_get_platform_resources(pdev, &res);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get platform resources\n");
+
+	plat = devm_stmmac_probe_config_dt(pdev, res.mac);
+	if (IS_ERR(plat))
+		return dev_err_probe(dev, PTR_ERR(plat),
+				     "dt configuration failed\n");
+
+	/* PHY interface mode control reg */
+	gmac->ctrl_sts = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
+	if (IS_ERR(gmac->ctrl_sts))
+		return dev_err_probe(dev, PTR_ERR(gmac->ctrl_sts),
+				     "S32CC config region is missing\n");
+
+	/* tx clock */
+	gmac->tx_clk = devm_clk_get(&pdev->dev, "tx");
+	if (IS_ERR(gmac->tx_clk))
+		return dev_err_probe(dev, PTR_ERR(gmac->tx_clk),
+				     "tx clock not found\n");
+
+	/* rx clock */
+	gmac->rx_clk = devm_clk_get(&pdev->dev, "rx");
+	if (IS_ERR(gmac->rx_clk))
+		return dev_err_probe(dev, PTR_ERR(gmac->rx_clk),
+				     "rx clock not found\n");
+
+	gmac->intf_mode = &plat->phy_interface;
+	gmac->ioaddr = res.addr;
+
+	/* S32CC core feature set */
+	plat->has_gmac4 = true;
+	plat->pmt = 1;
+	plat->flags |= STMMAC_FLAG_SPH_DISABLE;
+	plat->rx_fifo_size = 20480;
+	plat->tx_fifo_size = 20480;
+
+	plat->init = s32_gmac_init;
+	plat->exit = s32_gmac_exit;
+	plat->fix_mac_speed = s32_fix_mac_speed;
+
+	plat->bsp_priv = gmac;
+
+	return stmmac_pltfr_probe(pdev, plat, &res);
+}
+
+static const struct of_device_id s32_dwmac_match[] = {
+	{ .compatible = "nxp,s32g2-dwmac" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, s32_dwmac_match);
+
+static struct platform_driver s32_dwmac_driver = {
+	.probe = s32_dwmac_probe,
+	.remove = stmmac_pltfr_remove,
+	.driver = {
+		.name = "s32-dwmac",
+		.pm = &stmmac_pltfr_pm_ops,
+		.of_match_table = s32_dwmac_match,
+	},
+};
+module_platform_driver(s32_dwmac_driver);
+
+MODULE_AUTHOR("Jan Petrous (OSS) <jan.petrous at oss.nxp.com>");
+MODULE_DESCRIPTION("NXP S32G/R common chassis GMAC driver");
+MODULE_LICENSE("GPL");
+

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:52 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:52 +0100
Subject: [PATCH net-next v7 13/15] dt-bindings: net: Add DT bindings for
 DWMAC on NXP S32G/R SoCs
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-13-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Add basic description for DWMAC ethernet IP on NXP S32G2xx, S32G3xx
and S32R45 automotive series SoCs.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 .../devicetree/bindings/net/nxp,s32-dwmac.yaml     | 105 +++++++++++++++++++++
 .../devicetree/bindings/net/snps,dwmac.yaml        |   1 +
 2 files changed, 106 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml b/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
new file mode 100644
index 000000000000..2b8b74c5feec
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright 2021-2024 NXP
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/nxp,s32-dwmac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP S32G2xx/S32G3xx/S32R45 GMAC ethernet controller
+
+maintainers:
+  - Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
+
+description:
+  This device is a Synopsys DWC IP, integrated on NXP S32G/R SoCs.
+  The SoC series S32G2xx and S32G3xx feature one DWMAC instance,
+  the SoC S32R45 has two instances. The devices can use RGMII/RMII/MII
+  interface over Pinctrl device or the output can be routed
+  to the embedded SerDes for SGMII connectivity.
+
+properties:
+  compatible:
+    oneOf:
+      - const: nxp,s32g2-dwmac
+      - items:
+          - enum:
+              - nxp,s32g3-dwmac
+              - nxp,s32r45-dwmac
+          - const: nxp,s32g2-dwmac
+
+  reg:
+    items:
+      - description: Main GMAC registers
+      - description: GMAC PHY mode control register
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-names:
+    const: macirq
+
+  clocks:
+    items:
+      - description: Main GMAC clock
+      - description: Transmit clock
+      - description: Receive clock
+      - description: PTP reference clock
+
+  clock-names:
+    items:
+      - const: stmmaceth
+      - const: tx
+      - const: rx
+      - const: ptp_ref
+
+required:
+  - clocks
+  - clock-names
+
+allOf:
+  - $ref: snps,dwmac.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/phy/phy.h>
+    bus {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      ethernet at 4033c000 {
+        compatible = "nxp,s32g2-dwmac";
+        reg = <0x0 0x4033c000 0x0 0x2000>, /* gmac IP */
+              <0x0 0x4007c004 0x0 0x4>;    /* GMAC_0_CTRL_STS */
+        interrupt-parent = <&gic>;
+        interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "macirq";
+        snps,mtl-rx-config = <&mtl_rx_setup>;
+        snps,mtl-tx-config = <&mtl_tx_setup>;
+        clocks = <&clks 24>, <&clks 17>, <&clks 16>, <&clks 15>;
+        clock-names = "stmmaceth", "tx", "rx", "ptp_ref";
+        phy-mode = "rgmii-id";
+        phy-handle = <&phy0>;
+
+        mtl_rx_setup: rx-queues-config {
+          snps,rx-queues-to-use = <5>;
+        };
+
+        mtl_tx_setup: tx-queues-config {
+          snps,tx-queues-to-use = <5>;
+        };
+
+        mdio {
+          #address-cells = <1>;
+          #size-cells = <0>;
+          compatible = "snps,dwmac-mdio";
+
+          phy0: ethernet-phy at 0 {
+            reg = <0>;
+          };
+        };
+      };
+    };
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index eb1f3ae41ab9..91e75eb3f329 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -67,6 +67,7 @@ properties:
         - ingenic,x2000-mac
         - loongson,ls2k-dwmac
         - loongson,ls7a-dwmac
+        - nxp,s32g2-dwmac
         - qcom,qcs404-ethqos
         - qcom,sa8775p-ethqos
         - qcom,sc8280xp-ethqos

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:54 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:54 +0100
Subject: [PATCH net-next v7 15/15] MAINTAINERS: Add Jan Petrous as the NXP
 S32G/R DWMAC driver maintainer
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-15-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Add myself as NXP S32G/R DWMAC Ethernet driver maintainer.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..baf41d73d14e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2836,6 +2836,13 @@ S:	Maintained
 F:	arch/arm64/boot/dts/freescale/s32g*.dts*
 F:	drivers/pinctrl/nxp/
 
+ARM/NXP S32G/S32R DWMAC ETHERNET DRIVER
+M:	Jan Petrous <jan.petrous at oss.nxp.com>
+L:	NXP S32 Linux Team <s32 at nxp.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
+F:	drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
+
 ARM/Orion SoC/Technologic Systems TS-78xx platform support
 M:	Alexander Clouter <alex at digriz.org.uk>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:41 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:41 +0100
Subject: [PATCH net-next v7 02/15] net: driver: stmmac: Extend CSR calc
 support
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-2-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Add support for CSR clock range up to 800 MHz.

Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h      | 2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++++
 include/linux/stmmac.h                            | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1367fa5c9b8e..70d601f45481 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -257,6 +257,8 @@ struct stmmac_safety_stats {
 #define CSR_F_150M	150000000
 #define CSR_F_250M	250000000
 #define CSR_F_300M	300000000
+#define CSR_F_500M	500000000
+#define CSR_F_800M	800000000
 
 #define	MAC_CSR_H_FRQ_MASK	0x20
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9b262cdad60b..3cb7ad6ccc4e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -325,6 +325,10 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
 			priv->clk_csr = STMMAC_CSR_150_250M;
 		else if ((clk_rate >= CSR_F_250M) && (clk_rate <= CSR_F_300M))
 			priv->clk_csr = STMMAC_CSR_250_300M;
+		else if ((clk_rate >= CSR_F_300M) && (clk_rate < CSR_F_500M))
+			priv->clk_csr = STMMAC_CSR_300_500M;
+		else if ((clk_rate >= CSR_F_500M) && (clk_rate < CSR_F_800M))
+			priv->clk_csr = STMMAC_CSR_500_800M;
 	}
 
 	if (priv->plat->flags & STMMAC_FLAG_HAS_SUN8I) {
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 75cbfb576358..865d0fe26f98 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -34,6 +34,8 @@
 #define	STMMAC_CSR_35_60M	0x3	/* MDC = clk_scr_i/26 */
 #define	STMMAC_CSR_150_250M	0x4	/* MDC = clk_scr_i/102 */
 #define	STMMAC_CSR_250_300M	0x5	/* MDC = clk_scr_i/124 */
+#define	STMMAC_CSR_300_500M	0x6	/* MDC = clk_scr_i/204 */
+#define	STMMAC_CSR_500_800M	0x7	/* MDC = clk_scr_i/324 */
 
 /* MTL algorithms identifiers */
 #define MTL_TX_ALGORITHM_WRR	0x0

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:39 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:39 +0100
Subject: [PATCH net-next v7 00/15] Add support for Synopsis DWMAC IP on NXP
 Automotive SoCs S32G2xx/S32G3xx/S32R45
Message-ID: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>

The SoC series S32G2xx and S32G3xx feature one DWMAC instance,
the SoC S32R45 has two instances. The devices can use RGMII/RMII/MII
interface over Pinctrl device or the output can be routed
to the embedded SerDes for SGMII connectivity.

The provided stmmac glue code implements only basic functionality,
interface support is restricted to RGMII only. More, including
SGMII/SerDes support will come later.

This patchset adds stmmac glue driver based on downstream NXP git [0].

[0] https://github.com/nxp-auto-linux/linux

v7:
- rebased on v6.13-rc1 and removed RFC prefix
- Link to v6: https://lore.kernel.org/r/20241124-upstream_s32cc_gmac-v6-0-dc5718ccf001 at oss.nxp.com

v6:
- removed dead code in dwmac-intel-plat.c
- yaml: fix indention
- validate interface mode in probe
- dropped patch#16 to fit in max 15 patches in series
- Link to v5: https://lore.kernel.org/r/20241119-upstream_s32cc_gmac-v5-0-7dcc90fcffef at oss.nxp.com

v5:
- yaml: refactored compatible string to use fallback
- yaml: fix indention in example
- fix xmas tree formating in local variable declarations
- removed lazy rx clk setup
- drop PTP clock reading patch and replace it with stmmac_platform fix
- Link to v4: https://lore.kernel.org/r/20241028-upstream_s32cc_gmac-v4-0-03618f10e3e2 at oss.nxp.com

v4:
- fixed empty commit messages for rgmi_clock() helper patches
- fixed yaml path in MAINTAINERS
- switched to platform_driver::remove() as suggested Uwe
- yaml: returned back all compatibility sting values
- added better commit description for rgmii_clock() helper
- Link to v3: https://lore.kernel.org/r/20241013-upstream_s32cc_gmac-v3-0-d84b5a67b930 at oss.nxp.com

v3:
- switched to b4 WoW to overcome threading issue with b4
- extracted the hunk with the typo fix from v2 patch#1 to separate patch
  as Jacob suggested
- removed dead code for RMII/MII support, which will be added alter
- used new rgmii_clock() helper in other stmmac:dwmac glue drivers
- yaml: compatible strings compressed to simple one "nxp,s32-dwmac",
  removed duplicated required properties, already defined in snps,dwmac,
  fixed example

v2:
- send to wider audience as first version missed many maintainers
- created rgmi_clk() helper as Russell suggested (see patch#4)
- address Andrew's, Russell's, Serge's and Simon's comments

Message-ID: <AM9PR04MB85066576AD6848E2402DA354E2832 at AM9PR04MB8506.eurprd04.prod.outlook.com>

Cc: 

Cc: 

Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
---
Jan Petrous (OSS) (15):
      net: driver: stmmac: Fix CSR divider comment
      net: driver: stmmac: Extend CSR calc support
      net: stmmac: Fix clock rate variables size
      net: phy: Add helper for mapping RGMII link speed to clock rate
      net: dwmac-dwc-qos-eth: Use helper rgmii_clock
      net: dwmac-imx: Use helper rgmii_clock
      net: dwmac-intel-plat: Use helper rgmii_clock
      net: dwmac-rk: Use helper rgmii_clock
      net: dwmac-starfive: Use helper rgmii_clock
      net: macb: Use helper rgmii_clock
      net: xgene_enet: Use helper rgmii_clock
      net: dwmac-sti: Use helper rgmii_clock
      dt-bindings: net: Add DT bindings for DWMAC on NXP S32G/R SoCs
      net: stmmac: dwmac-s32: add basic NXP S32G/S32R glue driver
      MAINTAINERS: Add Jan Petrous as the NXP S32G/R DWMAC driver maintainer

 .../devicetree/bindings/net/nxp,s32-dwmac.yaml     | 105 ++++++++++++
 .../devicetree/bindings/net/snps,dwmac.yaml        |   1 +
 MAINTAINERS                                        |   7 +
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.c     |  16 +-
 drivers/net/ethernet/cadence/macb_main.c           |  14 +-
 drivers/net/ethernet/stmicro/stmmac/Kconfig        |  12 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile       |   1 +
 drivers/net/ethernet/stmicro/stmmac/common.h       |   2 +
 .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  11 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  15 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  22 +--
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  30 +---
 drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c    | 189 +++++++++++++++++++++
 .../net/ethernet/stmicro/stmmac/dwmac-starfive.c   |  19 +--
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  18 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c  |   2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   6 +-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   2 +-
 include/linux/phy.h                                |  23 +++
 include/linux/stmmac.h                             |  10 +-
 21 files changed, 386 insertions(+), 121 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20240923-upstream_s32cc_gmac-6891eb75b126

Best regards,
-- 
Jan Petrous (OSS) <jan.petrous at oss.nxp.com>




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:40 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:40 +0100
Subject: [PATCH net-next v7 01/15] net: driver: stmmac: Fix CSR divider
 comment
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-1-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

The comment in declaration of STMMAC_CSR_250_300M
incorrectly describes the constant as '/* MDC = clk_scr_i/122 */'
but the DWC Ether QOS Handbook version 5.20a says it is
CSR clock/124.

Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
---
 include/linux/stmmac.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index d79ff252cfdc..75cbfb576358 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -33,7 +33,7 @@
 #define	STMMAC_CSR_20_35M	0x2	/* MDC = clk_scr_i/16 */
 #define	STMMAC_CSR_35_60M	0x3	/* MDC = clk_scr_i/26 */
 #define	STMMAC_CSR_150_250M	0x4	/* MDC = clk_scr_i/102 */
-#define	STMMAC_CSR_250_300M	0x5	/* MDC = clk_scr_i/122 */
+#define	STMMAC_CSR_250_300M	0x5	/* MDC = clk_scr_i/124 */
 
 /* MTL algorithms identifiers */
 #define MTL_TX_ALGORITHM_WRR	0x0

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:44 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:44 +0100
Subject: [PATCH net-next v7 05/15] net: dwmac-dwc-qos-eth: Use helper
 rgmii_clock
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-5-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

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 83290e707df5..bd4eb187f8c6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
@@ -181,24 +181,19 @@ static void dwc_qos_remove(struct platform_device *pdev)
 static void tegra_eqos_fix_speed(void *priv, unsigned int speed, unsigned int mode)
 {
 	struct tegra_eqos *eqos = priv;
-	unsigned long rate = 125000000;
 	bool needs_calibration = false;
+	long rate = 125000000;
 	u32 value;
 	int err;
 
 	switch (speed) {
 	case SPEED_1000:
-		needs_calibration = true;
-		rate = 125000000;
-		break;
-
 	case SPEED_100:
 		needs_calibration = true;
-		rate = 25000000;
-		break;
+		fallthrough;
 
 	case SPEED_10:
-		rate = 2500000;
+		rate = rgmii_clock(speed);
 		break;
 
 	default:

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:43 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:43 +0100
Subject: [PATCH net-next v7 04/15] net: phy: Add helper for mapping RGMII
 link speed to clock rate
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-4-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

The RGMII interface supports three data rates: 10/100 Mbps
and 1 Gbps. These speeds correspond to clock frequencies
of 2.5/25 MHz and 125 MHz, respectively.

Many Ethernet drivers, including glues in stmmac, follow
a similar pattern of converting RGMII speed to clock frequency.

To simplify code, define the helper rgmii_clock(speed)
to convert connection speed to clock frequency.

Suggested-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 include/linux/phy.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/include/linux/phy.h b/include/linux/phy.h
index 563c46205685..a746f056ed57 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -298,6 +298,29 @@ static inline const char *phy_modes(phy_interface_t interface)
 	}
 }
 
+/**
+ * rgmii_clock - map link speed to the clock rate
+ * @speed: link speed value
+ *
+ * Description: maps RGMII supported link speeds
+ * into the clock rates.
+ *
+ * Returns: clock rate or negative errno
+ */
+static inline long rgmii_clock(int speed)
+{
+	switch (speed) {
+	case SPEED_10:
+		return 2500000;
+	case SPEED_100:
+		return 25000000;
+	case SPEED_1000:
+		return 125000000;
+	default:
+		return -EINVAL;
+	}
+}
+
 #define PHY_INIT_TIMEOUT	100000
 #define PHY_FORCE_TIMEOUT	10
 

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:42 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:42 +0100
Subject: [PATCH net-next v7 03/15] net: stmmac: Fix clock rate variables
 size
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-3-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

The clock API clk_get_rate() returns unsigned long value.
Expand affected members of stmmac platform data and
convert the stmmac_clk_csr_set() and dwmac4_core_init() methods
to defining the unsigned long clk_rate local variables.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c       | 2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c       | 2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c   | 2 +-
 include/linux/stmmac.h                                  | 6 +++---
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 901a3c1959fa..2a5b38723635 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -777,7 +777,7 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 		netdev_err(priv->dev, "Failed to max out clk_ptp_ref: %d\n", err);
 	plat_dat->clk_ptp_rate = clk_get_rate(plat_dat->clk_ptp_ref);
 
-	netdev_dbg(priv->dev, "PTP rate %d\n", plat_dat->clk_ptp_rate);
+	netdev_dbg(priv->dev, "PTP rate %lu\n", plat_dat->clk_ptp_rate);
 }
 
 static int qcom_ethqos_probe(struct platform_device *pdev)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index c25781874aa7..c36f90a782c5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -27,7 +27,7 @@ static void dwmac4_core_init(struct mac_device_info *hw,
 	struct stmmac_priv *priv = netdev_priv(dev);
 	void __iomem *ioaddr = hw->pcsr;
 	u32 value = readl(ioaddr + GMAC_CONFIG);
-	u32 clk_rate;
+	unsigned long clk_rate;
 
 	value |= GMAC_CORE_INIT;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3cb7ad6ccc4e..d45fd7a3acd5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -301,7 +301,7 @@ static void stmmac_global_err(struct stmmac_priv *priv)
  */
 static void stmmac_clk_csr_set(struct stmmac_priv *priv)
 {
-	u32 clk_rate;
+	unsigned long clk_rate;
 
 	clk_rate = clk_get_rate(priv->plat->stmmac_clk);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 3ac32444e492..06e07e6e180b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -640,7 +640,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 		dev_info(&pdev->dev, "PTP uses main clock\n");
 	} else {
 		plat->clk_ptp_rate = clk_get_rate(plat->clk_ptp_ref);
-		dev_dbg(&pdev->dev, "PTP rate %d\n", plat->clk_ptp_rate);
+		dev_dbg(&pdev->dev, "PTP rate %lu\n", plat->clk_ptp_rate);
 	}
 
 	plat->stmmac_rst = devm_reset_control_get_optional(&pdev->dev,
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 865d0fe26f98..c9878a612e53 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -252,8 +252,8 @@ struct plat_stmmacenet_data {
 	struct clk *stmmac_clk;
 	struct clk *pclk;
 	struct clk *clk_ptp_ref;
-	unsigned int clk_ptp_rate;
-	unsigned int clk_ref_rate;
+	unsigned long clk_ptp_rate;
+	unsigned long clk_ref_rate;
 	unsigned int mult_fact_100ns;
 	s32 ptp_max_adj;
 	u32 cdc_error_adj;
@@ -265,7 +265,7 @@ struct plat_stmmacenet_data {
 	int mac_port_sel_speed;
 	int has_xgmac;
 	u8 vlan_fail_q;
-	unsigned int eee_usecs_rate;
+	unsigned long eee_usecs_rate;
 	struct pci_dev *pdev;
 	int int_snapshot_num;
 	int msi_mac_vec;

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:48 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:48 +0100
Subject: [PATCH net-next v7 09/15] net: dwmac-starfive: Use helper
 rgmii_clock
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-9-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
index 421666279dd3..0a0a363d3730 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
@@ -34,24 +34,13 @@ struct starfive_dwmac {
 static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
 {
 	struct starfive_dwmac *dwmac = priv;
-	unsigned long rate;
+	long rate;
 	int err;
 
-	rate = clk_get_rate(dwmac->clk_tx);
-
-	switch (speed) {
-	case SPEED_1000:
-		rate = 125000000;
-		break;
-	case SPEED_100:
-		rate = 25000000;
-		break;
-	case SPEED_10:
-		rate = 2500000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dwmac->dev, "invalid speed %u\n", speed);
-		break;
+		return;
 	}
 
 	err = clk_set_rate(dwmac->clk_tx, rate);

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:46 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:46 +0100
Subject: [PATCH net-next v7 07/15] net: dwmac-intel-plat: Use helper
 rgmii_clock
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-7-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

When in, remove dead code in kmb_eth_fix_mac_speed().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
index d94f0a150e93..ddee6154d40b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
@@ -31,27 +31,13 @@ struct intel_dwmac_data {
 static void kmb_eth_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
 {
 	struct intel_dwmac *dwmac = priv;
-	unsigned long rate;
+	long rate;
 	int ret;
 
-	rate = clk_get_rate(dwmac->tx_clk);
-
-	switch (speed) {
-	case SPEED_1000:
-		rate = 125000000;
-		break;
-
-	case SPEED_100:
-		rate = 25000000;
-		break;
-
-	case SPEED_10:
-		rate = 2500000;
-		break;
-
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dwmac->dev, "Invalid speed\n");
-		break;
+		return;
 	}
 
 	ret = clk_set_rate(dwmac->tx_clk, rate);

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:47 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:47 +0100
Subject: [PATCH net-next v7 08/15] net: dwmac-rk: Use helper rgmii_clock
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-8-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 30 ++++++--------------------
 1 file changed, 6 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 8cb374668b74..a4dc89e23a68 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1079,20 +1079,11 @@ static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
 {
 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
 	struct device *dev = &bsp_priv->pdev->dev;
-	unsigned long rate;
+	long rate;
 	int ret;
 
-	switch (speed) {
-	case 10:
-		rate = 2500000;
-		break;
-	case 100:
-		rate = 25000000;
-		break;
-	case 1000:
-		rate = 125000000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
 		return;
 	}
@@ -1540,20 +1531,11 @@ static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
 {
 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
 	struct device *dev = &bsp_priv->pdev->dev;
-	unsigned long rate;
+	long rate;
 	int ret;
 
-	switch (speed) {
-	case 10:
-		rate = 2500000;
-		break;
-	case 100:
-		rate = 25000000;
-		break;
-	case 1000:
-		rate = 125000000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
 		return;
 	}

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:45 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:45 +0100
Subject: [PATCH net-next v7 06/15] net: dwmac-imx: Use helper rgmii_clock
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-6-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c | 15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
index 641f3cd019a3..43e0fbba4f77 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
@@ -186,7 +186,7 @@ static void imx_dwmac_fix_speed(void *priv, unsigned int speed, unsigned int mod
 {
 	struct plat_stmmacenet_data *plat_dat;
 	struct imx_priv_data *dwmac = priv;
-	unsigned long rate;
+	long rate;
 	int err;
 
 	plat_dat = dwmac->plat_dat;
@@ -196,17 +196,8 @@ static void imx_dwmac_fix_speed(void *priv, unsigned int speed, unsigned int mod
 	    (plat_dat->mac_interface == PHY_INTERFACE_MODE_MII))
 		return;
 
-	switch (speed) {
-	case SPEED_1000:
-		rate = 125000000;
-		break;
-	case SPEED_100:
-		rate = 25000000;
-		break;
-	case SPEED_10:
-		rate = 2500000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dwmac->dev, "invalid speed %u\n", speed);
 		return;
 	}

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:49 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:49 +0100
Subject: [PATCH net-next v7 10/15] net: macb: Use helper rgmii_clock
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-10-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/cadence/macb_main.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index daa416fb1724..640f500f989d 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -530,19 +530,9 @@ static void macb_set_tx_clk(struct macb *bp, int speed)
 	if (bp->phy_interface == PHY_INTERFACE_MODE_MII)
 		return;
 
-	switch (speed) {
-	case SPEED_10:
-		rate = 2500000;
-		break;
-	case SPEED_100:
-		rate = 25000000;
-		break;
-	case SPEED_1000:
-		rate = 125000000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0)
 		return;
-	}
 
 	rate_rounded = clk_round_rate(bp->tx_clk, rate);
 	if (rate_rounded < 0)

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Mon Dec  2 14:03:50 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Mon, 02 Dec 2024 23:03:50 +0100
Subject: [PATCH net-next v7 11/15] net: xgene_enet: Use helper rgmii_clock
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
Message-ID: <20241202-upstream_s32cc_gmac-v7-11-bc3e1f9f656e@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index e641dbbea1e2..b854b6b42d77 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -421,18 +421,12 @@ static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata)
 
 	if (dev->of_node) {
 		struct clk *parent = clk_get_parent(pdata->clk);
+		long rate = rgmii_clock(pdata->phy_speed);
 
-		switch (pdata->phy_speed) {
-		case SPEED_10:
-			clk_set_rate(parent, 2500000);
-			break;
-		case SPEED_100:
-			clk_set_rate(parent, 25000000);
-			break;
-		default:
-			clk_set_rate(parent, 125000000);
-			break;
-		}
+		if (rate < 0)
+			rate = 125000000;
+
+		clk_set_rate(parent, rate);
 	}
 #ifdef CONFIG_ACPI
 	else {

-- 
2.47.0




From linux at armlinux.org.uk  Mon Dec  2 14:06:48 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 2 Dec 2024 22:06:48 +0000
Subject: [PATCH net-next v7 01/15] net: driver: stmmac: Fix CSR divider
 comment
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-1-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
 <20241202-upstream_s32cc_gmac-v7-1-bc3e1f9f656e@oss.nxp.com>
Message-ID: <Z04veAM7wBJCLkhu@shell.armlinux.org.uk>

Hi,

No need for "driver:" in the subject line.

On Mon, Dec 02, 2024 at 11:03:40PM +0100, Jan Petrous via B4 Relay wrote:
> From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>
> 
> The comment in declaration of STMMAC_CSR_250_300M
> incorrectly describes the constant as '/* MDC = clk_scr_i/122 */'
> but the DWC Ether QOS Handbook version 5.20a says it is
> CSR clock/124.
> 
> Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
> Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>

With that fixed,

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  Mon Dec  2 14:07:28 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 2 Dec 2024 22:07:28 +0000
Subject: [PATCH net-next v7 02/15] net: driver: stmmac: Extend CSR calc
 support
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-2-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
 <20241202-upstream_s32cc_gmac-v7-2-bc3e1f9f656e@oss.nxp.com>
Message-ID: <Z04voJN9uj1Vefef@shell.armlinux.org.uk>

Hi,

As per patch 1, no need for "driver:" in the subject line.

Thanks.

On Mon, Dec 02, 2024 at 11:03:41PM +0100, Jan Petrous via B4 Relay wrote:
> From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>
> 
> Add support for CSR clock range up to 800 MHz.
> 
> Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
> Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/common.h      | 2 ++
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++++
>  include/linux/stmmac.h                            | 2 ++
>  3 files changed, 8 insertions(+)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 1367fa5c9b8e..70d601f45481 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -257,6 +257,8 @@ struct stmmac_safety_stats {
>  #define CSR_F_150M	150000000
>  #define CSR_F_250M	250000000
>  #define CSR_F_300M	300000000
> +#define CSR_F_500M	500000000
> +#define CSR_F_800M	800000000
>  
>  #define	MAC_CSR_H_FRQ_MASK	0x20
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 9b262cdad60b..3cb7ad6ccc4e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -325,6 +325,10 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
>  			priv->clk_csr = STMMAC_CSR_150_250M;
>  		else if ((clk_rate >= CSR_F_250M) && (clk_rate <= CSR_F_300M))
>  			priv->clk_csr = STMMAC_CSR_250_300M;
> +		else if ((clk_rate >= CSR_F_300M) && (clk_rate < CSR_F_500M))
> +			priv->clk_csr = STMMAC_CSR_300_500M;
> +		else if ((clk_rate >= CSR_F_500M) && (clk_rate < CSR_F_800M))
> +			priv->clk_csr = STMMAC_CSR_500_800M;
>  	}
>  
>  	if (priv->plat->flags & STMMAC_FLAG_HAS_SUN8I) {
> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
> index 75cbfb576358..865d0fe26f98 100644
> --- a/include/linux/stmmac.h
> +++ b/include/linux/stmmac.h
> @@ -34,6 +34,8 @@
>  #define	STMMAC_CSR_35_60M	0x3	/* MDC = clk_scr_i/26 */
>  #define	STMMAC_CSR_150_250M	0x4	/* MDC = clk_scr_i/102 */
>  #define	STMMAC_CSR_250_300M	0x5	/* MDC = clk_scr_i/124 */
> +#define	STMMAC_CSR_300_500M	0x6	/* MDC = clk_scr_i/204 */
> +#define	STMMAC_CSR_500_800M	0x7	/* MDC = clk_scr_i/324 */
>  
>  /* MTL algorithms identifiers */
>  #define MTL_TX_ALGORITHM_WRR	0x0
> 
> -- 
> 2.47.0
> 
> 
> 
> 

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


From u.kleine-koenig at baylibre.com  Mon Dec  2 14:14:35 2024
From: u.kleine-koenig at baylibre.com (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Mon, 2 Dec 2024 23:14:35 +0100
Subject: [PATCH] fsc: Switch back to struct platform_driver::remove()
In-Reply-To: <20241130150530.901263-2-u.kleine-koenig@baylibre.com>
References: <20241130150530.901263-2-u.kleine-koenig@baylibre.com>
Message-ID: <qey6imfeo3ntk45lbpadi2yo5gucgtllkgbymy6vmejin7pvye@oetb44ax2ynn>

Hello,

On Sat, Nov 30, 2024 at 04:05:30PM +0100, Uwe Kleine-K?nig wrote:
> After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
> return void") .remove() is (again) the right callback to implement for
> platform drivers.
> 
> Convert all platform drivers below drivers/fsi to use .remove(), with
> the eventual goal to drop struct platform_driver::remove_new(). As
> .remove() and .remove_new() have the same prototypes, conversion is done
> by just changing the structure member name in the driver initializer.
> 
> While touching these drivers, make the alignment of the touched
> initializers consistent.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>
Note that with e70140ba0d2b ("Get rid of 'remove_new' relic from
platform driver struct") (in Linus Torvald's tree) this patch isn't
needed any more.

Best regards
Uwe
-------------- 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/20241202/944dcc3e/attachment.sig>

From vt at altlinux.org  Mon Dec  2 14:31:19 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Tue, 3 Dec 2024 01:31:19 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <86ser6t6fs.wl-maz@kernel.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
Message-ID: <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>

Marc,

On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> On Mon, 02 Dec 2024 15:59:40 +0000,
> Vitaly Chikunov <vt at altlinux.org> wrote:
> > 
> > Marc,
> > 
> > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > >
> > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > 
> > No, host is 6.6.60.
> 
> Right. I wouldn't be surprised if:
> 
> - this v6.6 kernel doesn't hide the MPAM feature as it should (and
>   that's proably something we should backport)

How to confirm this? Currently I cannot find any (case-insensitive)
"MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM strings
in `strace -v` (as it decodes some KVM ioctls) of qemu process.

> 
> - you get a nastygram in the host log telling you that the guest has
>   executed something it shouldn't (you'll get the encoding of the
>   instruction)

I requested admins of the box for dmesg output since I don't have root
access myself and nowadays dmesg is not accessible for a user.

> 
> Can you confirm these two things?

Also, I tried to reproduce on another Kunpeng box with slightly
different HiSilicon CPU (presenting to the system as Cortex-A72) and the
problem is not reproducible there.

While things are not resolved, is it possible to workaround the problem
with some QEMU option, kernel command line, config option, or a patch?

Thanks,

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


From samuel.holland at sifive.com  Mon Dec  2 14:37:36 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Mon, 2 Dec 2024 16:37:36 -0600
Subject: [PATCH 3/8] drivers/perf: riscv: Add raw event v2 support
In-Reply-To: <20241119-pmu_event_info-v1-3-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-3-a4f9691421f8@rivosinc.com>
Message-ID: <e124c532-7a08-4788-843d-345827e35f5f@sifive.com>

Hi Atish,

On 2024-11-19 2:29 PM, Atish Patra wrote:
> SBI v3.0 introduced a new raw event type that allows wider
> mhpmeventX width to be programmed via CFG_MATCH.
> 
> Use the raw event v2 if SBI v3.0 is available.
> 
> Signed-off-by: Atish Patra <atishp at rivosinc.com>
> ---
>  arch/riscv/include/asm/sbi.h |  4 ++++
>  drivers/perf/riscv_pmu_sbi.c | 18 ++++++++++++------
>  2 files changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> index 9be38b05f4ad..3ee9bfa5e77c 100644
> --- a/arch/riscv/include/asm/sbi.h
> +++ b/arch/riscv/include/asm/sbi.h
> @@ -159,7 +159,10 @@ struct riscv_pmu_snapshot_data {
>  
>  #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
>  #define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
> +/* SBI v3.0 allows extended hpmeventX width value */
> +#define RISCV_PMU_RAW_EVENT_V2_MASK GENMASK_ULL(55, 0)
>  #define RISCV_PMU_RAW_EVENT_IDX 0x20000
> +#define RISCV_PMU_RAW_EVENT_V2_IDX 0x30000
>  #define RISCV_PLAT_FW_EVENT	0xFFFF
>  
>  /** General pmu event codes specified in SBI PMU extension */
> @@ -217,6 +220,7 @@ enum sbi_pmu_event_type {
>  	SBI_PMU_EVENT_TYPE_HW = 0x0,
>  	SBI_PMU_EVENT_TYPE_CACHE = 0x1,
>  	SBI_PMU_EVENT_TYPE_RAW = 0x2,
> +	SBI_PMU_EVENT_TYPE_RAW_V2 = 0x3,
>  	SBI_PMU_EVENT_TYPE_FW = 0xf,
>  };
>  
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index 50cbdbf66bb7..f0e845ff6b79 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -59,7 +59,7 @@ asm volatile(ALTERNATIVE(						\
>  #define PERF_EVENT_FLAG_USER_ACCESS	BIT(SYSCTL_USER_ACCESS)
>  #define PERF_EVENT_FLAG_LEGACY		BIT(SYSCTL_LEGACY)
>  
> -PMU_FORMAT_ATTR(event, "config:0-47");
> +PMU_FORMAT_ATTR(event, "config:0-55");
>  PMU_FORMAT_ATTR(firmware, "config:62-63");
>  
>  static bool sbi_v2_available;
> @@ -527,18 +527,24 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
>  		break;
>  	case PERF_TYPE_RAW:
>  		/*
> -		 * As per SBI specification, the upper 16 bits must be unused
> -		 * for a hardware raw event.
> +		 * As per SBI v0.3 specification,
> +		 *  -- the upper 16 bits must be unused for a hardware raw event.
> +		 * As per SBI v3.0 specification,
> +		 *  -- the upper 8 bits must be unused for a hardware raw event.
>  		 * Bits 63:62 are used to distinguish between raw events
>  		 * 00 - Hardware raw event
>  		 * 10 - SBI firmware events
>  		 * 11 - Risc-V platform specific firmware event
>  		 */
> -
>  		switch (config >> 62) {
>  		case 0:
> -			ret = RISCV_PMU_RAW_EVENT_IDX;
> -			*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
> +			if (sbi_v3_available) {
> +				*econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
> +				ret = RISCV_PMU_RAW_EVENT_V2_IDX;
> +			} else {
> +				*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
> +				ret = RISCV_PMU_RAW_EVENT_IDX;

Shouldn't we check to see if any of bits 48-55 are set and return an error,
instead of silently requesting the wrong event?

Regards,
Samuel

> +			}
>  			break;
>  		case 2:
>  			ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
> 



From samuel.holland at sifive.com  Mon Dec  2 14:49:09 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Mon, 2 Dec 2024 16:49:09 -0600
Subject: [PATCH 5/8] drivers/perf: riscv: Implement PMU event info
 function
In-Reply-To: <20241119-pmu_event_info-v1-5-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-5-a4f9691421f8@rivosinc.com>
Message-ID: <0a4a569e-dfab-4aed-90df-2fe9719a3803@sifive.com>

Hi Atish,

On 2024-11-19 2:29 PM, Atish Patra wrote:
> With the new SBI PMU event info function, we can query the availability
> of the all standard SBI PMU events at boot time with a single ecall.
> This improves the bootime by avoiding making an SBI call for each
> standard PMU event. Since this function is defined only in SBI v3.0,
> invoke this only if the underlying SBI implementation is v3.0 or higher.
> 
> Signed-off-by: Atish Patra <atishp at rivosinc.com>
> ---
>  arch/riscv/include/asm/sbi.h |  7 +++++
>  drivers/perf/riscv_pmu_sbi.c | 71 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 78 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> index 3ee9bfa5e77c..c04f64fbc01d 100644
> --- a/arch/riscv/include/asm/sbi.h
> +++ b/arch/riscv/include/asm/sbi.h
> @@ -134,6 +134,7 @@ enum sbi_ext_pmu_fid {
>  	SBI_EXT_PMU_COUNTER_FW_READ,
>  	SBI_EXT_PMU_COUNTER_FW_READ_HI,
>  	SBI_EXT_PMU_SNAPSHOT_SET_SHMEM,
> +	SBI_EXT_PMU_EVENT_GET_INFO,
>  };
>  
>  union sbi_pmu_ctr_info {
> @@ -157,6 +158,12 @@ struct riscv_pmu_snapshot_data {
>  	u64 reserved[447];
>  };
>  
> +struct riscv_pmu_event_info {
> +	u32 event_idx;
> +	u32 output;
> +	u64 event_data;
> +};
> +
>  #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
>  #define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
>  /* SBI v3.0 allows extended hpmeventX width value */
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index f0e845ff6b79..2a6527cc9d97 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -100,6 +100,7 @@ static unsigned int riscv_pmu_irq;
>  /* Cache the available counters in a bitmask */
>  static unsigned long cmask;
>  
> +static int pmu_event_find_cache(u64 config);

This new declaration does not appear to be used.

>  struct sbi_pmu_event_data {
>  	union {
>  		union {
> @@ -299,6 +300,68 @@ static struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
>  	},
>  };
>  
> +static int pmu_sbi_check_event_info(void)
> +{
> +	int num_events = ARRAY_SIZE(pmu_hw_event_map) + PERF_COUNT_HW_CACHE_MAX *
> +			 PERF_COUNT_HW_CACHE_OP_MAX * PERF_COUNT_HW_CACHE_RESULT_MAX;
> +	struct riscv_pmu_event_info *event_info_shmem;
> +	phys_addr_t base_addr;
> +	int i, j, k, result = 0, count = 0;
> +	struct sbiret ret;
> +
> +	event_info_shmem = (struct riscv_pmu_event_info *)
> +			   kcalloc(num_events, sizeof(*event_info_shmem), GFP_KERNEL);

Please drop the unnecessary cast.

> +	if (!event_info_shmem) {
> +		pr_err("Can not allocate memory for event info query\n");

Usually there's no need to print an error for allocation failure, since the
allocator already warns. And this isn't really an error, since we can (and do)
fall back to the existing way of checking for events.

> +		return -ENOMEM;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
> +		event_info_shmem[count++].event_idx = pmu_hw_event_map[i].event_idx;
> +
> +	for (i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) {
> +		for (int j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) {
> +			for (int k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++)
> +				event_info_shmem[count++].event_idx =
> +							pmu_cache_event_map[i][j][k].event_idx;
> +		}
> +	}
> +
> +	base_addr = __pa(event_info_shmem);
> +	if (IS_ENABLED(CONFIG_32BIT))
> +		ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_EVENT_GET_INFO, lower_32_bits(base_addr),
> +				upper_32_bits(base_addr), count, 0, 0, 0);
> +	else
> +		ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_EVENT_GET_INFO, base_addr, 0,
> +				count, 0, 0, 0);
> +	if (ret.error) {
> +		result = -EOPNOTSUPP;
> +		goto free_mem;
> +	}
> +	/* Do we need some barriers here or priv mode transition will ensure that */

No barrier is needed -- the SBI implementation is running on the same hart, so
coherency isn't even a consideration.

> +	for (i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++) {
> +		if (!(event_info_shmem[i].output & 0x01))

This bit mask should probably use a macro.

> +			pmu_hw_event_map[i].event_idx = -ENOENT;
> +	}
> +
> +	count = ARRAY_SIZE(pmu_hw_event_map);
> +
> +	for (i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) {
> +		for (j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) {
> +			for (k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++) {
> +				if (!(event_info_shmem[count].output & 0x01))

Same comment applies here.

Regards,
Samuel

> +					pmu_cache_event_map[i][j][k].event_idx = -ENOENT;
> +				count++;
> +			}
> +		}
> +	}
> +
> +free_mem:
> +	kfree(event_info_shmem);
> +
> +	return result;
> +}
> +
>  static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
>  {
>  	struct sbiret ret;
> @@ -316,6 +379,14 @@ static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
>  
>  static void pmu_sbi_check_std_events(struct work_struct *work)
>  {
> +	int ret;
> +
> +	if (sbi_v3_available) {
> +		ret = pmu_sbi_check_event_info();
> +		if (!ret)
> +			return;
> +	}
> +
>  	for (int i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
>  		pmu_sbi_check_event(&pmu_hw_event_map[i]);
>  
> 



From samuel.holland at sifive.com  Mon Dec  2 15:02:39 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Mon, 2 Dec 2024 17:02:39 -0600
Subject: [PATCH 7/8] RISC-V: KVM: Implement get event info function
In-Reply-To: <20241119-pmu_event_info-v1-7-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-7-a4f9691421f8@rivosinc.com>
Message-ID: <8dc7e94c-4bf2-4367-8561-166bec6ec315@sifive.com>

Hi Atish,

On 2024-11-19 2:29 PM, Atish Patra wrote:
> The new get_event_info funciton allows the guest to query the presence
> of multiple events with single SBI call. Currently, the perf driver
> in linux guest invokes it for all the standard SBI PMU events. Support
> the SBI function implementation in KVM as well.
> 
> Signed-off-by: Atish Patra <atishp at rivosinc.com>
> ---
>  arch/riscv/include/asm/kvm_vcpu_pmu.h |  3 ++
>  arch/riscv/kvm/vcpu_pmu.c             | 67 +++++++++++++++++++++++++++++++++++
>  arch/riscv/kvm/vcpu_sbi_pmu.c         |  3 ++
>  3 files changed, 73 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/kvm_vcpu_pmu.h b/arch/riscv/include/asm/kvm_vcpu_pmu.h
> index 1d85b6617508..9a930afc8f57 100644
> --- a/arch/riscv/include/asm/kvm_vcpu_pmu.h
> +++ b/arch/riscv/include/asm/kvm_vcpu_pmu.h
> @@ -98,6 +98,9 @@ void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu);
>  int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long saddr_low,
>  				      unsigned long saddr_high, unsigned long flags,
>  				      struct kvm_vcpu_sbi_return *retdata);
> +int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low,
> +				  unsigned long saddr_high, unsigned long num_events,
> +				  unsigned long flags, struct kvm_vcpu_sbi_return *retdata);
>  void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu);
>  void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu);
>  
> diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
> index efd66835c2b8..a30f7ec31479 100644
> --- a/arch/riscv/kvm/vcpu_pmu.c
> +++ b/arch/riscv/kvm/vcpu_pmu.c
> @@ -456,6 +456,73 @@ int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long s
>  	return 0;
>  }
>  
> +int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low,
> +				  unsigned long saddr_high, unsigned long num_events,
> +				  unsigned long flags, struct kvm_vcpu_sbi_return *retdata)
> +{
> +	unsigned long hva;
> +	struct riscv_pmu_event_info *einfo;
> +	int shmem_size = num_events * sizeof(*einfo);
> +	bool writable;
> +	gpa_t shmem;
> +	u32 eidx, etype;
> +	u64 econfig;
> +	int ret;
> +
> +	if (flags != 0 || (saddr_low & (SZ_16 - 1))) {
> +		ret = SBI_ERR_INVALID_PARAM;
> +		goto out;
> +	}
> +
> +	shmem = saddr_low;
> +	if (saddr_high != 0) {
> +		if (IS_ENABLED(CONFIG_32BIT)) {
> +			shmem |= ((gpa_t)saddr_high << 32);
> +		} else {
> +			ret = SBI_ERR_INVALID_ADDRESS;
> +			goto out;
> +		}
> +	}
> +
> +	hva = kvm_vcpu_gfn_to_hva_prot(vcpu, shmem >> PAGE_SHIFT, &writable);
> +	if (kvm_is_error_hva(hva) || !writable) {
> +		ret = SBI_ERR_INVALID_ADDRESS;

This only checks the first page if the address crosses a page boundary. Maybe
that is okay since kvm_vcpu_read_guest()/kvm_vcpu_write_guest() will fail if a
later page is inaccessible?

> +		goto out;
> +	}
> +
> +	einfo = kzalloc(shmem_size, GFP_KERNEL);
> +	if (!einfo)
> +		return -ENOMEM;
> +
> +	ret = kvm_vcpu_read_guest(vcpu, shmem, einfo, shmem_size);
> +	if (ret) {
> +		ret = SBI_ERR_FAILURE;
> +		goto free_mem;
> +	}
> +
> +	for (int i = 0; i < num_events; i++) {
> +		eidx = einfo[i].event_idx;
> +		etype = kvm_pmu_get_perf_event_type(eidx);
> +		econfig = kvm_pmu_get_perf_event_config(eidx, einfo[i].event_data);
> +		ret = riscv_pmu_get_event_info(etype, econfig, NULL);
> +		if (ret > 0)
> +			einfo[i].output = 1;

This also needs to write `output` in the else case to indicate that the event is
not supported; the spec does not require the caller to initialize bit 0 of
output to zero.

Regards,
Samuel

> +	}
> +
> +	kvm_vcpu_write_guest(vcpu, shmem, einfo, shmem_size);
> +	if (ret) {
> +		ret = SBI_ERR_FAILURE;
> +		goto free_mem;
> +	}
> +
> +free_mem:
> +	kfree(einfo);
> +out:
> +	retdata->err_val = ret;
> +
> +	return 0;
> +}
> +
>  int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu,
>  				struct kvm_vcpu_sbi_return *retdata)
>  {
> diff --git a/arch/riscv/kvm/vcpu_sbi_pmu.c b/arch/riscv/kvm/vcpu_sbi_pmu.c
> index e4be34e03e83..a020d979d179 100644
> --- a/arch/riscv/kvm/vcpu_sbi_pmu.c
> +++ b/arch/riscv/kvm/vcpu_sbi_pmu.c
> @@ -73,6 +73,9 @@ static int kvm_sbi_ext_pmu_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
>  	case SBI_EXT_PMU_SNAPSHOT_SET_SHMEM:
>  		ret = kvm_riscv_vcpu_pmu_snapshot_set_shmem(vcpu, cp->a0, cp->a1, cp->a2, retdata);
>  		break;
> +	case SBI_EXT_PMU_EVENT_GET_INFO:
> +		ret = kvm_riscv_vcpu_pmu_event_info(vcpu, cp->a0, cp->a1, cp->a2, cp->a3, retdata);
> +		break;
>  	default:
>  		retdata->err_val = SBI_ERR_NOT_SUPPORTED;
>  	}
> 



From heiko at sntech.de  Mon Dec  2 15:20:51 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 03 Dec 2024 00:20:51 +0100
Subject: [PATCH] arm64: dts: rockchip: Remove unused and undocumented "num-slots"
 property
In-Reply-To: <20241115193424.3618568-1-robh@kernel.org>
References: <20241115193424.3618568-1-robh@kernel.org>
Message-ID: <7106426.18pcnM708K@diego>

Am Freitag, 15. November 2024, 20:34:23 CET schrieb Rob Herring (Arm):
> Remove "num-slots" property which is both unused in the kernel and
> undocumented. Most likely they are leftovers from downstream.
> 
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>

this was already fixed in 
commit b1f8d3b81d92 ("arm64: dts: rockchip: remove num-slots property from rk3328-nanopi-r2s-plus")
at the beginning of october.




From heiko at sntech.de  Mon Dec  2 15:29:17 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 00:29:17 +0100
Subject: [PATCH] arm64: dts: rockchip: rk3308-rock-s0: Fix sdmmc access on v1.1 boards
In-Reply-To: <20241119230838.4137130-1-jonas@kwiboo.se>
References: <20241119230838.4137130-1-jonas@kwiboo.se>
Message-ID: <173318214614.1403925.10666094873905910081.b4-ty@sntech.de>


On Tue, 19 Nov 2024 23:08:36 +0000, Jonas Karlman wrote:
> BootROM leave GPIO4_D6 configured as SDMMC_PWREN function and DW MCI
> driver set PRWEN high on MMC_POWER_UP and low on MMC_POWER_OFF.
> Similarly U-Boot also set PRWEN high before accessing mmc.
> 
> However, HW revision prior to v1.2 must pull GPIO4_D6 low to access
> sdmmc. For HW revision v1.2 the state of GPIO4_D6 has no impact.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: rk3308-rock-s0: Fix sdmmc access on v1.1 boards
      commit: b89a4235eb8cdf1b4bd2f9e4ed096d8adf8994e7

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Mon Dec  2 15:29:15 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 00:29:15 +0100
Subject: [PATCH] arm64: dts: rockchip: enable the mmu600_pcie IOMMU on the rk3588 SoC
In-Reply-To: <20241107123732.1160063-2-cassel@kernel.org>
References: <20241107123732.1160063-2-cassel@kernel.org>
Message-ID: <173318214614.1403925.12812225885440711307.b4-ty@sntech.de>


On Thu, 07 Nov 2024 13:37:33 +0100, Niklas Cassel wrote:
> Commit cd81d3a0695c ("arm64: dts: rockchip: add rk3588 pcie and php
> IOMMUs") added the rk3588 SoC's pcie IOMMU and php IOMMU as disabled.
> 
> The mmu600_pcie is connected with the five PCIe controllers.
> See 8.2 Block Diagram, in rk3588 TRM (Technical Reference Manual).
> 
> The five PCIe controllers are:
> pcie3x4, pcie3x2, pcie2x1l0, pcie2x1l1, pcie2x1l2.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: enable the mmu600_pcie IOMMU on the rk3588 SoC
      commit: da92d3dfc871e821a1bface3ba5afcf8cda19805

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Mon Dec  2 15:29:16 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 00:29:16 +0100
Subject: [PATCH] arm64: dts: rockchip: rk3588: add msi-parent for pcie3x4_ep
In-Reply-To: <20241120171048.2839621-2-cassel@kernel.org>
References: <20241120171048.2839621-2-cassel@kernel.org>
Message-ID: <173318214613.1403925.10026428339576666444.b4-ty@sntech.de>


On Wed, 20 Nov 2024 18:10:49 +0100, Niklas Cassel wrote:
> Add msi-parent for the pcie3x4_ep PCI endpoint node.
> 
> The pcie3x4_ep node should use the same msi-parent as the pcie3x4 node
> (which represents the PCIe controller running in Root Complex mode).
> 
> The GIC ITS can be used to trigger an IRQ on the endpoint when any of
> the endpoint's PCI BARs are written to by the host[1].
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: rk3588: add msi-parent for pcie3x4_ep
      commit: b6f09f497b07008aa65c31341138cecafa78222c

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Mon Dec  2 15:29:14 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 00:29:14 +0100
Subject: (subset) [PATCH 1/2] arm64: dts: rockchip: rk3568: add reset-names for combphy
In-Reply-To: <20241122073006.99309-1-amadeus@jmu.edu.cn>
References: <20241122073006.99309-1-amadeus@jmu.edu.cn>
Message-ID: <173318214612.1403925.12222889205247999008.b4-ty@sntech.de>


On Fri, 22 Nov 2024 15:30:05 +0800, Chukun Pan wrote:
> The reset-names of combphy are missing, add it.
> 
> 

Applied, thanks!

[1/2] arm64: dts: rockchip: rk3568: add reset-names for combphy
      commit: 8b9c12757f919157752646faf3821abf2b7d2a64

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From yang at os.amperecomputing.com  Mon Dec  2 15:39:57 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Mon, 2 Dec 2024 15:39:57 -0800
Subject: [RFC PATCH 0/3] arm64: support FEAT_BBM level 2 and large block
 mapping when rodata=full
In-Reply-To: <20241118181711.962576-1-yang@os.amperecomputing.com>
References: <20241118181711.962576-1-yang@os.amperecomputing.com>
Message-ID: <d2f2d48e-bfa5-4fd8-a6fe-dc75b89ffe9e@os.amperecomputing.com>

Gently ping...


Any comments on this RFC? Look forward to discussing them.

Thanks,
Yang


On 11/18/24 10:16 AM, Yang Shi wrote:
> When rodata=full kernel linear mapping is mapped by PTE due to arm's
> break-before-make rule.
>
> This resulted in a couple of problems:
>    - performance degradation
>    - more TLB pressure
>    - memory waste for kernel page table
>
> There are some workarounds to mitigate the problems, for example, using
> rodata=on, but this compromises the security measurement.
>
> With FEAT_BBM level 2 support, splitting large block page table to
> smaller ones doesn't need to make the page table entry invalid anymore.
> This allows kernel split large block mapping on the fly.
>
> Add kernel page table split support and use large block mapping by
> default when FEAT_BBM level 2 is supported for rodata=full.  When
> changing permissions for kernel linear mapping, the page table will be
> split to PTE level.
>
> The machine without FEAT_BBM level 2 will fallback to have kernel linear
> mapping PTE-mapped when rodata=full.
>
> With this we saw significant performance boost with some benchmarks with
> keeping rodata=full security protection in the mean time.
>
> The test was done on AmpereOne machine (192 cores, 1P) with 256GB memory and
> 4K page size + 48 bit VA.
>
> Function test (4K/16K/64K page size)
>    - Kernel boot.  Kernel needs change kernel linear mapping permission at
>      boot stage, if the patch didn't work, kernel typically didn't boot.
>    - Module stress from stress-ng. Kernel module load change permission for
>      module sections.
>    - A test kernel module which allocates 80% of total memory via vmalloc(),
>      then change the vmalloc area permission to RO, then change it back
>      before vfree(). Then launch a VM which consumes almost all physical
>      memory.
>    - VM with the patchset applied in guest kernel too.
>    - Kernel build in VM with patched guest kernel.
>
> Memory consumption
> Before:
> MemTotal:       258988984 kB
> MemFree:        254821700 kB
>
> After:
> MemTotal:       259505132 kB
> MemFree:        255410264 kB
>
> Around 500MB more memory are free to use.  The larger the machine, the
> more memory saved.
>
> Performance benchmarking
> * Memcached
> We saw performance degradation when running Memcached benchmark with
> rodata=full vs rodata=on.  Our profiling pointed to kernel TLB pressure.
> With this patchset we saw ops/sec is increased by around 3.5%, P99
> latency is reduced by around 9.6%.
> The gain mainly came from reduced kernel TLB misses.  The kernel TLB
> MPKI is reduced by 28.5%.
>
> The benchmark data is now on par with rodata=on too.
>
> * Disk encryption (dm-crypt) benchmark
> Ran fio benchmark with the below command on a 128G ramdisk (ext4) with disk
> encryption (by dm-crypt).
> fio --directory=/data --random_generator=lfsr --norandommap --randrepeat 1 \
>      --status-interval=999 --rw=write --bs=4k --loops=1 --ioengine=sync \
>      --iodepth=1 --numjobs=1 --fsync_on_close=1 --group_reporting --thread \
>      --name=iops-test-job --eta-newline=1 --size 100G
>
> The IOPS is increased by 90% - 150% (the variance is high, but the worst
> number of good case is around 90% more than the best number of bad case).
> The bandwidth is increased and the avg clat is reduced proportionally.
>
> * Sequential file read
> Read 100G file sequentially on XFS (xfs_io read with page cache populated).
> The bandwidth is increased by 150%.
>
>
> Yang Shi (3):
>        arm64: cpufeature: detect FEAT_BBM level 2
>        arm64: mm: support large block mapping when rodata=full
>        arm64: cpufeature: workaround AmpereOne FEAT_BBM level 2
>
>   arch/arm64/include/asm/cpufeature.h |  24 ++++++++++++++++++
>   arch/arm64/include/asm/pgtable.h    |   7 +++++-
>   arch/arm64/kernel/cpufeature.c      |  11 ++++++++
>   arch/arm64/mm/mmu.c                 |  31 +++++++++++++++++++++--
>   arch/arm64/mm/pageattr.c            | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>   arch/arm64/tools/cpucaps            |   1 +
>   6 files changed, 238 insertions(+), 9 deletions(-)
>
>



From andrew at lunn.ch  Mon Dec  2 15:43:58 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 3 Dec 2024 00:43:58 +0100
Subject: [PATCH net-next v7 14/15] net: stmmac: dwmac-s32: add basic NXP
 S32G/S32R glue driver
In-Reply-To: <20241202-upstream_s32cc_gmac-v7-14-bc3e1f9f656e@oss.nxp.com>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
 <20241202-upstream_s32cc_gmac-v7-14-bc3e1f9f656e@oss.nxp.com>
Message-ID: <b9ad385b-7702-4c71-b14f-64f2714a35a4@lunn.ch>

> +static int s32_gmac_init(struct platform_device *pdev, void *priv)
> +{
> +	struct s32_priv_data *gmac = priv;
> +	int ret;
> +
> +	ret = clk_set_rate(gmac->tx_clk, GMAC_TX_RATE_125M);
> +	if (!ret)
> +		ret = clk_prepare_enable(gmac->tx_clk);
> +
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't set tx clock\n");
> +		return ret;
> +	}

The ordering is a bit odd here. Normally you would test each operation
individually for errors. So:

	ret = clk_set_rate(gmac->tx_clk, GMAC_TX_RATE_125M);
	if (ret) {
		dev_err(&pdev->dev, "Can't set tx clock\n");
		return ret;
	}
	ret = clk_prepare_enable(gmac->tx_clk);
	if (ret) {
		dev_err(&pdev->dev, "Can't enable tx clock\n");
		return ret;
	}


> +
> +	ret = clk_prepare_enable(gmac->rx_clk);
> +	if (ret) {
> +		clk_disable_unprepare(gmac->tx_clk);
> +		dev_err(&pdev->dev, "Can't set rx clock\n");
> +		return ret;
> +	}

Is there no need to set the TX clock rate?

	Andrew


From jeremy.linton at arm.com  Mon Dec  2 16:01:55 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Mon,  2 Dec 2024 18:01:55 -0600
Subject: [PATCH v2 0/1] arm64: CCA TSM module autoloading
Message-ID: <20241203000156.72451-1-jeremy.linton@arm.com>

The TSM module provides both guest identification as well as
attestation when a guest is run in CCA mode. Lets assure by creating a
dummy platform device that the module is automatically loaded during
boot.  The TSM module will be loaded by udev daemon after it receives
the device addition event. Once it is in place it can be used earlier
in the boot process to say decrypt a LUKS rootfs.

v1->v2:
	Various comment updates/variable renames
	Add missing __maybe_unused to the platform_device_id

Jeremy Linton (1):
  arm64: rsi: Add automatic arm-cca-guest module loading

 arch/arm64/include/asm/rsi.h                    |  2 ++
 arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
 3 files changed, 25 insertions(+)

-- 
2.46.0



From jeremy.linton at arm.com  Mon Dec  2 16:01:56 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Mon,  2 Dec 2024 18:01:56 -0600
Subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module loading
In-Reply-To: <20241203000156.72451-1-jeremy.linton@arm.com>
References: <20241203000156.72451-1-jeremy.linton@arm.com>
Message-ID: <20241203000156.72451-2-jeremy.linton@arm.com>

The TSM module provides both guest identification as well as
attestation when a guest is run in CCA mode. Lets assure by creating a
dummy platform device that the module is automatically loaded during
boot.  The TSM module will be loaded by udev daemon after it receives
the device addition event. Once it is in place it can be used earlier
in the boot process to say decrypt a LUKS rootfs.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 arch/arm64/include/asm/rsi.h                    |  2 ++
 arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
 3 files changed, 25 insertions(+)

diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
index 188cbb9b23f5..b42aeac05340 100644
--- a/arch/arm64/include/asm/rsi.h
+++ b/arch/arm64/include/asm/rsi.h
@@ -10,6 +10,8 @@
 #include <linux/jump_label.h>
 #include <asm/rsi_cmds.h>
 
+#define RSI_PDEV_NAME "arm-cca-dev"
+
 DECLARE_STATIC_KEY_FALSE(rsi_present);
 
 void __init arm64_rsi_init(void);
diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
index 3031f25c32ef..5434e5496ac2 100644
--- a/arch/arm64/kernel/rsi.c
+++ b/arch/arm64/kernel/rsi.c
@@ -8,6 +8,7 @@
 #include <linux/psci.h>
 #include <linux/swiotlb.h>
 #include <linux/cc_platform.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/mem_encrypt.h>
@@ -140,3 +141,17 @@ void __init arm64_rsi_init(void)
 	static_branch_enable(&rsi_present);
 }
 
+static struct platform_device rsi_dev = {
+	.name = RSI_PDEV_NAME,
+	.id = PLATFORM_DEVID_NONE
+};
+
+static int __init rsi_init(void)
+{
+	if (is_realm_world() &&
+	    platform_device_register(&rsi_dev))
+		pr_err("failed to register rsi platform device\n");
+	return 0;
+}
+
+arch_initcall(rsi_init)
diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
index 488153879ec9..1f8d8439f617 100644
--- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
+++ b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
@@ -6,6 +6,7 @@
 #include <linux/arm-smccc.h>
 #include <linux/cc_platform.h>
 #include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/tsm.h>
@@ -219,6 +220,13 @@ static void __exit arm_cca_guest_exit(void)
 }
 module_exit(arm_cca_guest_exit);
 
+/* modalias, so userspace can autoload this module when RSI is available */
+static const struct __maybe_unused platform_device_id arm_cca_match[] = {
+	{ RSI_PDEV_NAME, 0},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(platform, arm_cca_match);
 MODULE_AUTHOR("Sami Mujawar <sami.mujawar at arm.com>");
 MODULE_DESCRIPTION("Arm CCA Guest TSM Driver");
 MODULE_LICENSE("GPL");
-- 
2.46.0



From atishp at rivosinc.com  Mon Dec  2 16:15:23 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Mon, 2 Dec 2024 16:15:23 -0800
Subject: [PATCH 3/8] drivers/perf: riscv: Add raw event v2 support
In-Reply-To: <e124c532-7a08-4788-843d-345827e35f5f@sifive.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-3-a4f9691421f8@rivosinc.com> <e124c532-7a08-4788-843d-345827e35f5f@sifive.com>
Message-ID: <CAHBxVyEwkPUcut0L7K9eewcmhOOidU16WnGRiPiP3D7-OS7HvQ@mail.gmail.com>

On Mon, Dec 2, 2024 at 2:37?PM Samuel Holland <samuel.holland at sifive.com> wrote:
>
> Hi Atish,
>
> On 2024-11-19 2:29 PM, Atish Patra wrote:
> > SBI v3.0 introduced a new raw event type that allows wider
> > mhpmeventX width to be programmed via CFG_MATCH.
> >
> > Use the raw event v2 if SBI v3.0 is available.
> >
> > Signed-off-by: Atish Patra <atishp at rivosinc.com>
> > ---
> >  arch/riscv/include/asm/sbi.h |  4 ++++
> >  drivers/perf/riscv_pmu_sbi.c | 18 ++++++++++++------
> >  2 files changed, 16 insertions(+), 6 deletions(-)
> >
> > diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> > index 9be38b05f4ad..3ee9bfa5e77c 100644
> > --- a/arch/riscv/include/asm/sbi.h
> > +++ b/arch/riscv/include/asm/sbi.h
> > @@ -159,7 +159,10 @@ struct riscv_pmu_snapshot_data {
> >
> >  #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
> >  #define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
> > +/* SBI v3.0 allows extended hpmeventX width value */
> > +#define RISCV_PMU_RAW_EVENT_V2_MASK GENMASK_ULL(55, 0)
> >  #define RISCV_PMU_RAW_EVENT_IDX 0x20000
> > +#define RISCV_PMU_RAW_EVENT_V2_IDX 0x30000
> >  #define RISCV_PLAT_FW_EVENT  0xFFFF
> >
> >  /** General pmu event codes specified in SBI PMU extension */
> > @@ -217,6 +220,7 @@ enum sbi_pmu_event_type {
> >       SBI_PMU_EVENT_TYPE_HW = 0x0,
> >       SBI_PMU_EVENT_TYPE_CACHE = 0x1,
> >       SBI_PMU_EVENT_TYPE_RAW = 0x2,
> > +     SBI_PMU_EVENT_TYPE_RAW_V2 = 0x3,
> >       SBI_PMU_EVENT_TYPE_FW = 0xf,
> >  };
> >
> > diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> > index 50cbdbf66bb7..f0e845ff6b79 100644
> > --- a/drivers/perf/riscv_pmu_sbi.c
> > +++ b/drivers/perf/riscv_pmu_sbi.c
> > @@ -59,7 +59,7 @@ asm volatile(ALTERNATIVE(                                           \
> >  #define PERF_EVENT_FLAG_USER_ACCESS  BIT(SYSCTL_USER_ACCESS)
> >  #define PERF_EVENT_FLAG_LEGACY               BIT(SYSCTL_LEGACY)
> >
> > -PMU_FORMAT_ATTR(event, "config:0-47");
> > +PMU_FORMAT_ATTR(event, "config:0-55");
> >  PMU_FORMAT_ATTR(firmware, "config:62-63");
> >
> >  static bool sbi_v2_available;
> > @@ -527,18 +527,24 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
> >               break;
> >       case PERF_TYPE_RAW:
> >               /*
> > -              * As per SBI specification, the upper 16 bits must be unused
> > -              * for a hardware raw event.
> > +              * As per SBI v0.3 specification,
> > +              *  -- the upper 16 bits must be unused for a hardware raw event.
> > +              * As per SBI v3.0 specification,
> > +              *  -- the upper 8 bits must be unused for a hardware raw event.
> >                * Bits 63:62 are used to distinguish between raw events
> >                * 00 - Hardware raw event
> >                * 10 - SBI firmware events
> >                * 11 - Risc-V platform specific firmware event
> >                */
> > -
> >               switch (config >> 62) {
> >               case 0:
> > -                     ret = RISCV_PMU_RAW_EVENT_IDX;
> > -                     *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
> > +                     if (sbi_v3_available) {
> > +                             *econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
> > +                             ret = RISCV_PMU_RAW_EVENT_V2_IDX;
> > +                     } else {
> > +                             *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
> > +                             ret = RISCV_PMU_RAW_EVENT_IDX;
>
> Shouldn't we check to see if any of bits 48-55 are set and return an error,
> instead of silently requesting the wrong event?
>

We can. I did not add it originally as we can't do much validation for
the raw events for anyways.
If the encoding is not supported the user will get the error anyways
as it can't find a counter.
We will just save 1 SBI call if the kernel doesn't allow requesting an
event if bits 48-55 are set.

> Regards,
> Samuel
>
> > +                     }
> >                       break;
> >               case 2:
> >                       ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
> >
>


From hpchen0nvt at gmail.com  Mon Dec  2 16:27:04 2024
From: hpchen0nvt at gmail.com (Hui-Ping Chen)
Date: Tue, 3 Dec 2024 08:27:04 +0800
Subject: [PATCH v9 2/2] mtd: rawnand: nuvoton: add new driver for the
 Nuvoton MA35 SoC
In-Reply-To: <875xo257rd.fsf@bootlin.com>
References: <20241125052524.135362-1-hpchen0nvt@gmail.com>
 <20241125052524.135362-3-hpchen0nvt@gmail.com> <875xo257rd.fsf@bootlin.com>
Message-ID: <6395117f-4ed8-45b5-ba80-417d61beb55b@gmail.com>

Dear Mique,

Thank you for your reply.


On 2024/12/3 ?? 01:12, Miquel Raynal wrote:
> Hello,
>
>> +static int ma35_nand_attach_chip(struct nand_chip *chip)
>> +{
>> +	struct ma35_nand_info *nand = nand_get_controller_data(chip);
>> +	struct mtd_info *mtd = nand_to_mtd(chip);
>> +	struct device *dev = mtd->dev.parent;
>> +	u32 reg;
>> +
>> +	if (chip->options & NAND_BUSWIDTH_16) {
>> +		dev_err(dev, "16 bits bus width not supported");
>> +		return -EINVAL;
>> +	}
>> +
>> +	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~PSIZE_MASK);
>> +	if (mtd->writesize == 2048)
>> +		writel(reg | PSIZE_2K, nand->regs + MA35_NFI_REG_NANDCTL);
>> +	else if (mtd->writesize == 4096)
>> +		writel(reg | PSIZE_4K, nand->regs + MA35_NFI_REG_NANDCTL);
>> +	else if (mtd->writesize == 8192)
>> +		writel(reg | PSIZE_8K, nand->regs + MA35_NFI_REG_NANDCTL);
> You should error out if the writesize is not supported.

Okay. I will return -EINVAL if the writesize is not supported.


>
> Thanks,
> Miqu?l

Best regards,

Hui-Ping Chen



From kuba at kernel.org  Mon Dec  2 16:33:09 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 2 Dec 2024 16:33:09 -0800
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <20241128144501.0000619b@gmail.com>
References: <20241021061023.2162701-1-0x1207@gmail.com>
	<d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
	<20241128144501.0000619b@gmail.com>
Message-ID: <20241202163309.05603e96@kernel.org>

On Thu, 28 Nov 2024 14:45:01 +0800 Furong Xu wrote:
> > Let me know if you need any more information.
> 
> [  149.986210] dwc-eth-dwmac 2490000.ethernet eth0: Tx DMA map failed
> and
> [  245.571688] dwc-eth-dwmac 2490000.ethernet eth0: Tx DMA map failed
> [  245.575349] dwc-eth-dwmac 2490000.ethernet eth0: Tx DMA map failed
> are reported by stmmac_xmit() obviously, but not stmmac_tso_xmit().
> 
> And these crashes are caused by "Tx DMA map failed", as you can see that
> current driver code does not handle this kind of failure so well. It is clear
> that we need to figure out why Tx DMA map failed.
> 
> This patch corrects the sequence and timing of DMA unmap by waiting all
> DMA transmit descriptors to be closed by DMA engine for one DMA map in
> stmmac_tso_xmit(), it never leaks DMA addresses and never introduces
> other side effect.
> 
> "Tx DMA map failed" is a weird failure, and I cannot reproduce this failure
> on my device with DWMAC CORE 5.10a(Synopsys ID: 0x51) and DWXGMAC CORE 3.20a.

Let me repeat Jon's question - is there any info or test you need from
Jon to make progress with a fix?

If Jon's board worked before and doesn't work with this patch we will
need *a* fix, if no fix is provided our only choice is revert.


From hch at lst.de  Mon Dec  2 16:46:11 2024
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 3 Dec 2024 01:46:11 +0100
Subject: [PATCH] arm64: patching: avoid early page_to_phys()
In-Reply-To: <20241202170359.1475019-1-mark.rutland@arm.com>
References: <20241202170359.1475019-1-mark.rutland@arm.com>
Message-ID: <20241203004611.GA8116@lst.de>

On Mon, Dec 02, 2024 at 05:03:59PM +0000, Mark Rutland wrote:
> +	phys_addr_t phys;
> +
> +	if (is_image_text((unsigned long)addr)) {
> +		phys = __pa_symbol(addr);
> +	} else {
> +		struct page *page = vmalloc_to_page(addr);
> +		BUG_ON(!page);
> +		phys = page_to_phys(page) + offset_in_page(addr);
> +	}
> +
> +	return (void *)set_fixmap_offset(fixmap, phys);

This looks much better.  Btw, I recently open coded the vmalloc to phys
logic above in an unrelated fix, and noticed that
arch/powerpc/mm/pgtable.c has a nice vmalloc_to_phys that could
be generalized and move to common code.  Does anyone have an opinion
on that?



From myungjoo.ham at samsung.com  Mon Dec  2 17:12:00 2024
From: myungjoo.ham at samsung.com (MyungJoo Ham)
Date: Tue, 03 Dec 2024 10:12:00 +0900
Subject: [PATCH] devfreq: Switch back to struct
 platform_driver::remove()
In-Reply-To: <20241130135813.895628-2-u.kleine-koenig@baylibre.com>
References: <20241130135813.895628-2-u.kleine-koenig@baylibre.com>
	<CGME20241130135828epcas1p405d9dbb7df745f6aa81ae2033b9a281a@epcms1p3>
Message-ID: <20241203011200epcms1p3fbf79a0ca20c982ea472c5f19a2bfbee@epcms1p3>

>After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
>return void") .remove() is (again) the right callback to implement for
>platform drivers.
>
>Convert all platform drivers below drivers/devfreq to use .remove(),
>with the eventual goal to drop struct platform_driver::remove_new(). As
>.remove() and .remove_new() have the same prototypes, conversion is done
>by just changing the structure member name in the driver initializer.
>
>While touching these drivers, make the alignment of the touched
>initializers consistent.
>
>Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>

Acked-by: MyungJoo Ham <myungjoo.ham at samsung.com>


Cheers,
MyungJoo

>---
>Hello,
>
>this is based on Friday's next, feel free to drop changes that result in
>a conflict when you come around to apply this. I'll care for the fallout
>at a later time then. (Having said that, if you use b4 am -3 and git am
>-3, there should be hardly any conflict.)
>
>This is merge window material.
>
>Best regards
>Uwe
>
> drivers/devfreq/event/exynos-nocp.c | 6 +++---
> drivers/devfreq/event/exynos-ppmu.c | 6 +++---
> drivers/devfreq/mtk-cci-devfreq.c   | 4 ++--
> drivers/devfreq/rk3399_dmc.c        | 8 ++++----
> drivers/devfreq/sun8i-a33-mbus.c    | 2 +-
> 5 files changed, 13 insertions(+), 13 deletions(-)
>



From oliver.upton at linux.dev  Mon Dec  2 17:19:54 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 2 Dec 2024 17:19:54 -0800
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
Message-ID: <Z05cuuMMurzp1jx5@linux.dev>

On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> Marc,
> 
> On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > On Mon, 02 Dec 2024 15:59:40 +0000,
> > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > 
> > > Marc,
> > > 
> > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > >
> > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > 
> > > No, host is 6.6.60.
> > 
> > Right. I wouldn't be surprised if:
> > 
> > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> >   that's proably something we should backport)
> 
> How to confirm this? Currently I cannot find any (case-insensitive)
> "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM strings
> in `strace -v` (as it decodes some KVM ioctls) of qemu process.

If you can attach to the QEMU gdbstub of the VM, info registers will
dump ~everything.

If the value of ID_AA64PFR0_EL1.MPAM (bits 43:40) is nonzero then the
host KVM is erroneously advertising MPAM to the guest.

-- 
Thanks,
Oliver


From sboyd at kernel.org  Mon Dec  2 17:21:38 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 02 Dec 2024 17:21:38 -0800
Subject: [PATCH v2] clk: amlogic: axg-audio: revert reset implementation
In-Reply-To: <20241128-clk-audio-fix-rst-missing-v2-1-cf437d1a73da@baylibre.com>
References: <20241128-clk-audio-fix-rst-missing-v2-1-cf437d1a73da@baylibre.com>
Message-ID: <ff51b468ac71f9206d4ca8c6f345f38f.sboyd@kernel.org>

Quoting Jerome Brunet (2024-11-28 09:30:42)
> The audio subsystem of axg based platform is not probing anymore.
> This is due to the introduction of RESET_MESON_AUX and the config
> not being enabled with the default arm64 defconfig.
> 
> This brought another discussion around proper decoupling between
> the clock and reset part. While this discussion gets sorted out,
> revert back to the initial implementation.
> 
> This reverts
>  * commit 681ed497d676 ("clk: amlogic: axg-audio: fix Kconfig dependency on RESET_MESON_AUX")
>  * commit 664988eb47dd ("clk: amlogic: axg-audio: use the auxiliary reset driver")
> 
> Both are reverted with single change to avoid creating more compilation
> problems.
> 
> Fixes: 681ed497d676 ("clk: amlogic: axg-audio: fix Kconfig dependency on RESET_MESON_AUX")
> Cc: Arnd Bergmann <arnd at arndb.de>
> Reported-by: Mark Brown <broonie at kernel.org>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---

Applied to clk-fixes


From gshan at redhat.com  Mon Dec  2 17:22:19 2024
From: gshan at redhat.com (Gavin Shan)
Date: Tue, 3 Dec 2024 11:22:19 +1000
Subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module
 loading
In-Reply-To: <20241203000156.72451-2-jeremy.linton@arm.com>
References: <20241203000156.72451-1-jeremy.linton@arm.com>
 <20241203000156.72451-2-jeremy.linton@arm.com>
Message-ID: <2285bc57-bd9a-4696-ac29-73bb233c9b3e@redhat.com>

On 12/3/24 10:01 AM, Jeremy Linton wrote:
> The TSM module provides both guest identification as well as
> attestation when a guest is run in CCA mode. Lets assure by creating a
> dummy platform device that the module is automatically loaded during
> boot.  The TSM module will be loaded by udev daemon after it receives
> the device addition event. Once it is in place it can be used earlier
> in the boot process to say decrypt a LUKS rootfs.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>   arch/arm64/include/asm/rsi.h                    |  2 ++
>   arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
>   drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
>   3 files changed, 25 insertions(+)
> 

Reviewed-by: Gavin Shan <gshan at redhat.com>



From jon.lin at rock-chips.com  Mon Dec  2 17:35:13 2024
From: jon.lin at rock-chips.com (Jon Lin)
Date: Tue,  3 Dec 2024 09:35:13 +0800
Subject: [PATCH] spi: rockchip-sfc: Optimize the judgment mechanism completed by the controller
Message-ID: <20241203013513.2628810-1-jon.lin@rock-chips.com>

There is very little data left in fifo, and the controller will
complete the transmission in a short period of time, so
use readl_poll_timeout() for busy wait 10us to accelerate response.

Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

 drivers/spi/spi-rockchip-sfc.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
index 138508d2c736..14f5b9346050 100644
--- a/drivers/spi/spi-rockchip-sfc.c
+++ b/drivers/spi/spi-rockchip-sfc.c
@@ -472,6 +472,16 @@ static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
 	int ret = 0;
 	u32 status;
 
+	/*
+	 * There is very little data left in fifo, and the controller will
+	 * complete the transmission in a short period of time.
+	 */
+	ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
+				 !(status & SFC_SR_IS_BUSY),
+				 0, 10);
+	if (!ret)
+		return 0;
+
 	ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
 				 !(status & SFC_SR_IS_BUSY),
 				 20, timeout_us);
-- 
2.34.1



From andrew at lunn.ch  Mon Dec  2 17:43:30 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 3 Dec 2024 02:43:30 +0100
Subject: [PATCH v4 3/3] net: stmmac: dwmac-nuvoton: Add dwmac glue for
 Nuvoton MA35 family
In-Reply-To: <20241202023643.75010-4-a0987203069@gmail.com>
References: <20241202023643.75010-1-a0987203069@gmail.com>
 <20241202023643.75010-4-a0987203069@gmail.com>
Message-ID: <9f2c8532-8e52-439a-b253-ad2ceb07b21b@lunn.ch>

> +	/* We support WoL by magic packet, override pmt to make it work! */
> +	plat_dat->pmt = 1;
> +	device_set_wakeup_capable(&pdev->dev, 1);

It seems odd to me that there is no WoL support in this glue
driver. So i assume the core driver is doing it? So why does the core
driver not set pmt and wakeup_capable ?

	Andrew


From 0x1207 at gmail.com  Mon Dec  2 18:03:31 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Tue, 3 Dec 2024 10:03:31 +0800
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <20241202163309.05603e96@kernel.org>
References: <20241021061023.2162701-1-0x1207@gmail.com>
	<d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
	<20241128144501.0000619b@gmail.com>
	<20241202163309.05603e96@kernel.org>
Message-ID: <20241203100331.00007580@gmail.com>

Hi Jakub,

On Mon, 2 Dec 2024 16:33:09 -0800, Jakub Kicinski <kuba at kernel.org> wrote:
> On Thu, 28 Nov 2024 14:45:01 +0800 Furong Xu wrote:
> > > Let me know if you need any more information.  
> > 
> > [  149.986210] dwc-eth-dwmac 2490000.ethernet eth0: Tx DMA map failed
> > and
> > [  245.571688] dwc-eth-dwmac 2490000.ethernet eth0: Tx DMA map failed
> > [  245.575349] dwc-eth-dwmac 2490000.ethernet eth0: Tx DMA map failed
> > are reported by stmmac_xmit() obviously, but not stmmac_tso_xmit().
> > 
> > And these crashes are caused by "Tx DMA map failed", as you can see that
> > current driver code does not handle this kind of failure so well. It is clear
> > that we need to figure out why Tx DMA map failed.
> > 
> > This patch corrects the sequence and timing of DMA unmap by waiting all
> > DMA transmit descriptors to be closed by DMA engine for one DMA map in
> > stmmac_tso_xmit(), it never leaks DMA addresses and never introduces
> > other side effect.
> > 
> > "Tx DMA map failed" is a weird failure, and I cannot reproduce this failure
> > on my device with DWMAC CORE 5.10a(Synopsys ID: 0x51) and DWXGMAC CORE 3.20a.  
> 
> Let me repeat Jon's question - is there any info or test you need from
> Jon to make progress with a fix?
> 
> If Jon's board worked before and doesn't work with this patch we will
> need *a* fix, if no fix is provided our only choice is revert.

Thanks for your attention to this issue.

I requested Jon to provide more info about "Tx DMA map failed" in previous
reply, and he does not respond yet.
This seems to be a device-specific issue, no fix can be provided without
his reply :(


From kuba at kernel.org  Mon Dec  2 18:34:25 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 2 Dec 2024 18:34:25 -0800
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <20241203100331.00007580@gmail.com>
References: <20241021061023.2162701-1-0x1207@gmail.com>
	<d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
	<20241128144501.0000619b@gmail.com>
	<20241202163309.05603e96@kernel.org>
	<20241203100331.00007580@gmail.com>
Message-ID: <20241202183425.4021d14c@kernel.org>

On Tue, 3 Dec 2024 10:03:31 +0800 Furong Xu wrote:
> I requested Jon to provide more info about "Tx DMA map failed" in previous
> reply, and he does not respond yet.

What does it mean to provide "more info" about a print statement from
the driver? Is there a Kconfig which he needs to set to get more info?
Perhaps you should provide a debug patch he can apply on his tree, that
will print info about (1) which buffer mapping failed (head or frags);
(2) what the physical address was of the buffer that couldn't be mapped.


From samuel.holland at sifive.com  Mon Dec  2 18:39:17 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Mon, 2 Dec 2024 20:39:17 -0600
Subject: [PATCH 3/8] drivers/perf: riscv: Add raw event v2 support
In-Reply-To: <CAHBxVyEwkPUcut0L7K9eewcmhOOidU16WnGRiPiP3D7-OS7HvQ@mail.gmail.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-3-a4f9691421f8@rivosinc.com>
 <e124c532-7a08-4788-843d-345827e35f5f@sifive.com>
 <CAHBxVyEwkPUcut0L7K9eewcmhOOidU16WnGRiPiP3D7-OS7HvQ@mail.gmail.com>
Message-ID: <b48c4319-1fbc-4703-88d2-6f495af9c24e@sifive.com>

Hi Atish,

On 2024-12-02 6:15 PM, Atish Kumar Patra wrote:
> On Mon, Dec 2, 2024 at 2:37?PM Samuel Holland <samuel.holland at sifive.com> wrote:
>> On 2024-11-19 2:29 PM, Atish Patra wrote:
>>> SBI v3.0 introduced a new raw event type that allows wider
>>> mhpmeventX width to be programmed via CFG_MATCH.
>>>
>>> Use the raw event v2 if SBI v3.0 is available.
>>>
>>> Signed-off-by: Atish Patra <atishp at rivosinc.com>
>>> ---
>>>  arch/riscv/include/asm/sbi.h |  4 ++++
>>>  drivers/perf/riscv_pmu_sbi.c | 18 ++++++++++++------
>>>  2 files changed, 16 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
>>> index 9be38b05f4ad..3ee9bfa5e77c 100644
>>> --- a/arch/riscv/include/asm/sbi.h
>>> +++ b/arch/riscv/include/asm/sbi.h
>>> @@ -159,7 +159,10 @@ struct riscv_pmu_snapshot_data {
>>>
>>>  #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
>>>  #define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
>>> +/* SBI v3.0 allows extended hpmeventX width value */
>>> +#define RISCV_PMU_RAW_EVENT_V2_MASK GENMASK_ULL(55, 0)
>>>  #define RISCV_PMU_RAW_EVENT_IDX 0x20000
>>> +#define RISCV_PMU_RAW_EVENT_V2_IDX 0x30000
>>>  #define RISCV_PLAT_FW_EVENT  0xFFFF
>>>
>>>  /** General pmu event codes specified in SBI PMU extension */
>>> @@ -217,6 +220,7 @@ enum sbi_pmu_event_type {
>>>       SBI_PMU_EVENT_TYPE_HW = 0x0,
>>>       SBI_PMU_EVENT_TYPE_CACHE = 0x1,
>>>       SBI_PMU_EVENT_TYPE_RAW = 0x2,
>>> +     SBI_PMU_EVENT_TYPE_RAW_V2 = 0x3,
>>>       SBI_PMU_EVENT_TYPE_FW = 0xf,
>>>  };
>>>
>>> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
>>> index 50cbdbf66bb7..f0e845ff6b79 100644
>>> --- a/drivers/perf/riscv_pmu_sbi.c
>>> +++ b/drivers/perf/riscv_pmu_sbi.c
>>> @@ -59,7 +59,7 @@ asm volatile(ALTERNATIVE(                                           \
>>>  #define PERF_EVENT_FLAG_USER_ACCESS  BIT(SYSCTL_USER_ACCESS)
>>>  #define PERF_EVENT_FLAG_LEGACY               BIT(SYSCTL_LEGACY)
>>>
>>> -PMU_FORMAT_ATTR(event, "config:0-47");
>>> +PMU_FORMAT_ATTR(event, "config:0-55");
>>>  PMU_FORMAT_ATTR(firmware, "config:62-63");
>>>
>>>  static bool sbi_v2_available;
>>> @@ -527,18 +527,24 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
>>>               break;
>>>       case PERF_TYPE_RAW:
>>>               /*
>>> -              * As per SBI specification, the upper 16 bits must be unused
>>> -              * for a hardware raw event.
>>> +              * As per SBI v0.3 specification,
>>> +              *  -- the upper 16 bits must be unused for a hardware raw event.
>>> +              * As per SBI v3.0 specification,
>>> +              *  -- the upper 8 bits must be unused for a hardware raw event.
>>>                * Bits 63:62 are used to distinguish between raw events
>>>                * 00 - Hardware raw event
>>>                * 10 - SBI firmware events
>>>                * 11 - Risc-V platform specific firmware event
>>>                */
>>> -
>>>               switch (config >> 62) {
>>>               case 0:
>>> -                     ret = RISCV_PMU_RAW_EVENT_IDX;
>>> -                     *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
>>> +                     if (sbi_v3_available) {
>>> +                             *econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
>>> +                             ret = RISCV_PMU_RAW_EVENT_V2_IDX;
>>> +                     } else {
>>> +                             *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
>>> +                             ret = RISCV_PMU_RAW_EVENT_IDX;
>>
>> Shouldn't we check to see if any of bits 48-55 are set and return an error,
>> instead of silently requesting the wrong event?
>>
> 
> We can. I did not add it originally as we can't do much validation for
> the raw events for anyways.
> If the encoding is not supported the user will get the error anyways
> as it can't find a counter.
> We will just save 1 SBI call if the kernel doesn't allow requesting an
> event if bits 48-55 are set.

The scenario I'm concerned about is where masking off bits 48-55 results in a
valid, supported encoding for a different event. For example, in the HPM event
encoding scheme used by Rocket and inherited by SiFive cores, bits 8-55 are a
bitmap. So masking off some of those bits will exclude some events, but will not
create an invalid encoding. This could be very confusing for users.

Regards,
Samuel



From gshan at redhat.com  Mon Dec  2 18:46:13 2024
From: gshan at redhat.com (Gavin Shan)
Date: Tue, 3 Dec 2024 12:46:13 +1000
Subject: [PATCH] arm64/mm: Drop INIT_MM_CONTEXT()
In-Reply-To: <20241202043553.29592-1-anshuman.khandual@arm.com>
References: <20241202043553.29592-1-anshuman.khandual@arm.com>
Message-ID: <65823dec-8af2-494c-88a6-0d4683cbf5df@redhat.com>

On 12/2/24 2:35 PM, Anshuman Khandual wrote:
> Platform override for INIT_MM_CONTEXT() is redundant because swapper_pg_dir
> always gets assigned as the pgd during init_mm initialization. So just drop
> this override on arm64.
> 
> Originally this override was added via the 'commit 2b5548b68199 ("arm64/mm:
> Separate boot-time page tables from swapper_pg_dir")' because non standard
> init_pg_dir was assigned as the pgd. Subsequently it was changed as default
> swapper_pg_dir by the 'commit ba5b0333a847 ("arm64: mm: omit redundant
> remap of kernel image")', which might have also just dropped this override.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Ryan Roberts <ryan.roberts at arm.com>
> 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 patch applies on v6.13-rc1
> 
>   arch/arm64/include/asm/mmu.h | 3 ---
>   1 file changed, 3 deletions(-)
> 

Reviewed-by: Gavin Shan <gshan at redhat.com>



From gshan at redhat.com  Mon Dec  2 18:46:55 2024
From: gshan at redhat.com (Gavin Shan)
Date: Tue, 3 Dec 2024 12:46:55 +1000
Subject: [PATCH] arm64/mm: Replace open encodings with PXD_TABLE_BIT
In-Reply-To: <20241202083850.73207-1-anshuman.khandual@arm.com>
References: <20241202083850.73207-1-anshuman.khandual@arm.com>
Message-ID: <498151ad-6fa4-4f16-9044-e0b1f78d161a@redhat.com>

On 12/2/24 6:38 PM, Anshuman Khandual wrote:
> [pgd|p4d]_bad() helpers have open encodings for their respective table bits
> which can be replaced with corresponding macros. This makes things clearer,
> thus improving their readability as well.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Ryan Roberts <ryan.roberts at arm.com>
> 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 patch applies on v6.13-rc1
> 
>   arch/arm64/include/asm/pgtable.h | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 

Reviewed-by: Gavin Shan <gshan at redhat.com>



From gshan at redhat.com  Mon Dec  2 18:47:44 2024
From: gshan at redhat.com (Gavin Shan)
Date: Tue, 3 Dec 2024 12:47:44 +1000
Subject: [PATCH] arm64/mm: Ensure adequate HUGE_MAX_HSTATE
In-Reply-To: <20241202064407.53807-1-anshuman.khandual@arm.com>
References: <20241202064407.53807-1-anshuman.khandual@arm.com>
Message-ID: <e0e5d74c-5e5e-4448-aa83-9187daff5b2a@redhat.com>

On 12/2/24 4:44 PM, Anshuman Khandual wrote:
> This asserts that HUGE_MAX_HSTATE is sufficient enough preventing potential
> hugetlb_max_hstate runtime overflow in hugetlb_add_hstate() thus triggering
> a BUG_ON() there after.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Ryan Roberts <ryan.roberts at arm.com>
> 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 patch applies on v6.13-rc1
> 
>   arch/arm64/mm/hugetlbpage.c | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
> 

Reviewed-by: Gavin Shan <gshan at redhat.com>



From sboyd at kernel.org  Mon Dec  2 18:53:30 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 02 Dec 2024 18:53:30 -0800
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com>
References: <20241127-clk-audio-fix-rst-missing-v1-1-9f9d0ab98fce@baylibre.com> <12f29978-c8ce-4bee-a447-dcd086eb936d@app.fastmail.com> <1ja5dk2y5l.fsf@starbuckisacylon.baylibre.com> <f8de4a2a-776f-4c10-b75e-e845bcc38dde@app.fastmail.com> <1j4j3r32ld.fsf@starbuckisacylon.baylibre.com> <306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com> <1jy1131kxz.fsf@starbuckisacylon.baylibre.com> <c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com> <1jplmf1jqa.fsf@starbuckisacylon.baylibre.com> <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com>
Message-ID: <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org>

Happy Thanksgiving!

Quoting Arnd Bergmann (2024-11-28 07:34:46)
> On Thu, Nov 28, 2024, at 16:06, Jerome Brunet wrote:
> > On Thu 28 Nov 2024 at 15:51, "Arnd Bergmann" <arnd at arndb.de> wrote:
> >> On Thu, Nov 28, 2024, at 15:39, Jerome Brunet wrote:
> >>> On Thu 28 Nov 2024 at 15:11, "Arnd Bergmann" <arnd at arndb.de> wrote:
> >>> Eventually that will happen for the rest of the reset implemented
> >>> under drivers/clk/meson.
> >>>
> >>> It allows to make some code common between the platform reset
> >>> drivers and the aux ones. It also ease maintainance for both
> >>> Stephen and Philipp.
> >>
> >> I don't understand how this helps: the entire point of using
> >> an auxiliary device is to separate the lifetime rules of
> >> the different bits, but by doing the creation of the device
> >> in the same file as the implementation, you are not taking
> >> advantage of that at all, but instead get the complexity of
> >> a link-time dependency in addition to a lot of extra code
> >> for dealing with the additional device.
> >
> > My initial rework had the creation in clock (note: that is why I
> > initially used 'imply', and forgot to update when the creation moved to
> > reset).
> >
> > I was asked to move the creation in reset:
> > https://lore.kernel.org/r/217a785212d7c1a5b504c6040b3636e6.sboyd at kernel.org
> >
> > We are deviating a bit from the initial regression reported by Mark.
> > Is Ok with you to proceed with that fix and then continue this discussion
> > ?
> 
> I really don't want to see those stray 'select' statements
> in there, as that leave very little incentive for anyone to
> fix it properly.
> 
> It sounds like Stephen gave you bad advice for how it should
> be structured, so my best suggestion would be to move the
> the problem (and the reset driver) back into his subsystem
> and leave only a simple 'select RESET_CONTROLLER'.
> 
> From the message you cited, I think Stephen had the right
> intentions ("so that the clk and reset drivers are decoupled"),
> but the end result did not actually do what he intended
> even if you did what he asked for.
> 
> Stephen, can you please take a look here and see if you
> have a better idea for either decoupling the two drivers
> enough to avoid the link time dependency, or to reintegrate
> the reset controller code into the clk driver and avoid
> the complexity?

I think the best approach is to add the reset auxilary device with a
function that creates the auxiliary device directly by string name and
does nothing else. Maybe we can have some helper in the auxiliary
layer that does that all for us, because it's quite a bit of boiler
plate that we need to write over and over again. Something like:

  int devm_auxiliary_device_create(struct device *parent, const char *name)

that does the whole kzalloc() + ida dance that
devm_meson_rst_aux_register() is doing today and wraps it all up so that
the device is removed when the parent driver unbinds. Then this clk
driver can register the reset device with a single call and not need to
do anything besides select AUXILIARY_BUS. The regmap can be acquired
from the parent device in the auxiliary driver probe with
dev_get_regmap(adev->parent).


From 0x1207 at gmail.com  Mon Dec  2 19:16:37 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Tue, 3 Dec 2024 11:16:37 +0800
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <20241202183425.4021d14c@kernel.org>
References: <20241021061023.2162701-1-0x1207@gmail.com>
	<d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
	<20241128144501.0000619b@gmail.com>
	<20241202163309.05603e96@kernel.org>
	<20241203100331.00007580@gmail.com>
	<20241202183425.4021d14c@kernel.org>
Message-ID: <20241203111637.000023fe@gmail.com>

On Mon, 2 Dec 2024 18:34:25 -0800, Jakub Kicinski <kuba at kernel.org> wrote:

> On Tue, 3 Dec 2024 10:03:31 +0800 Furong Xu wrote:
> > I requested Jon to provide more info about "Tx DMA map failed" in previous
> > reply, and he does not respond yet.  
> 
> What does it mean to provide "more info" about a print statement from
> the driver? Is there a Kconfig which he needs to set to get more info?
> Perhaps you should provide a debug patch he can apply on his tree, that
> will print info about (1) which buffer mapping failed (head or frags);
> (2) what the physical address was of the buffer that couldn't be mapped.

A debug patch to print info about buffer makes no sense here.
Both Tegra186 Jetson TX2(tegra186-p2771-0000) and Tegra194 Jetson AGX Xavier
(tegra194-p2972-0000) enable IOMMU/SMMU for stmmac in its device-tree node,
buffer info should be investigated with detailed IOMMU/SMMU debug info from
drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c together.

I am not an expert in IOMMU, so I cannot help more.

Without the help from Jon, our only choice is revert as you said.

Thanks.


From quic_abhinavk at quicinc.com  Mon Dec  2 19:27:45 2024
From: quic_abhinavk at quicinc.com (Abhinav Kumar)
Date: Mon, 2 Dec 2024 19:27:45 -0800
Subject: [PATCH 07/10] drm/msm/dp: use eld_mutex to protect access to
 connector->eld
In-Reply-To: <20241201-drm-connector-eld-mutex-v1-7-ba56a6545c03@linaro.org>
References: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
 <20241201-drm-connector-eld-mutex-v1-7-ba56a6545c03@linaro.org>
Message-ID: <ca906dc4-ac72-4a76-a670-36c011c853c9@quicinc.com>



On 11/30/2024 3:55 PM, Dmitry Baryshkov wrote:
> Reading access to connector->eld can happen at the same time the
> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
> order to protect connector->eld from concurrent access.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_audio.c | 2 ++
>   1 file changed, 2 insertions(+)
> 

Reviewed-by: Abhinav Kumar <quic_abhinavk at quicinc.com>


From bwicaksono at nvidia.com  Mon Dec  2 19:43:55 2024
From: bwicaksono at nvidia.com (Besar Wicaksono)
Date: Tue, 3 Dec 2024 03:43:55 +0000
Subject: [PATCH 2/3] perf: arm_cspmu: nvidia: update CNVLINK PMU events
In-Reply-To: <20241028151725.GA2484@willie-the-truck>
References: <20240918215846.1424282-1-bwicaksono@nvidia.com>
 <20240918215846.1424282-3-bwicaksono@nvidia.com>
 <20241014131903.GB17353@willie-the-truck>
 <SJ0PR12MB5676697B93C267CE87C5A474A0452@SJ0PR12MB5676.namprd12.prod.outlook.com>
 <20241023162636.GA29251@willie-the-truck>
 <SJ0PR12MB567691F0F89F18EDC84C6092A04E2@SJ0PR12MB5676.namprd12.prod.outlook.com>
 <20241028151725.GA2484@willie-the-truck>
Message-ID: <SJ0PR12MB5676EFF6A0B1EEB4927FA06BA0362@SJ0PR12MB5676.namprd12.prod.outlook.com>

> -----Original Message-----
> From: Will Deacon <will at kernel.org>
> Sent: Monday, October 28, 2024 10:17 AM
> To: Besar Wicaksono <bwicaksono at nvidia.com>
> Cc: suzuki.poulose at arm.com; robin.murphy at arm.com;
> catalin.marinas at arm.com; mark.rutland at arm.com; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org; linux-
> tegra at vger.kernel.org; Thierry Reding <treding at nvidia.com>; Jon Hunter
> <jonathanh at nvidia.com>; Vikram Sethi <vsethi at nvidia.com>; Rich Wiley
> <rwiley at nvidia.com>; Bob Knight <rknight at nvidia.com>
> Subject: Re: [PATCH 2/3] perf: arm_cspmu: nvidia: update CNVLINK PMU
> events
> 
> External email: Use caution opening links or attachments
> 
> 
> On Thu, Oct 24, 2024 at 02:10:55PM +0000, Besar Wicaksono wrote:
> > > > > > diff --git a/drivers/perf/arm_cspmu/nvidia_cspmu.c
> > > > > b/drivers/perf/arm_cspmu/nvidia_cspmu.c
> > > > > > index ea2d44adfa7c..d1cd9975e71a 100644
> > > > > > --- a/drivers/perf/arm_cspmu/nvidia_cspmu.c
> > > > > > +++ b/drivers/perf/arm_cspmu/nvidia_cspmu.c
> > > > > > @@ -112,6 +112,25 @@ static struct attribute
> *mcf_pmu_event_attrs[]
> > > = {
> > > > > >       NULL,
> > > > > >  };
> > > > > >
> > > > > > +static struct attribute *mcf_cnvlink_pmu_event_attrs[] = {
> > > > > > +     ARM_CSPMU_EVENT_ATTR(rd_bytes_cmem,                     0x0),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(rd_bytes_gmem,                     0x1),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(wr_bytes_cmem,                     0x2),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(wr_bytes_gmem,                     0x3),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(total_bytes_cmem,                  0x4),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(total_bytes_gmem,                  0x5),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(rd_req_cmem,                       0x6),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(rd_req_gmem,                       0x7),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(wr_req_cmem,                       0x8),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(wr_req_gmem,                       0x9),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(total_req_cmem,                    0xa),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(total_req_gmem,                    0xb),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(rd_cum_outs_cmem,                  0xc),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(rd_cum_outs_gmem,                  0xd),
> > > > > > +     ARM_CSPMU_EVENT_ATTR(cycles,
> > > > > ARM_CSPMU_EVT_CYCLES_DEFAULT),
> > > > > > +     NULL,
> > > > > > +};
> > > > > > +
> > > > > >  static struct attribute *generic_pmu_event_attrs[] = {
> > > > > >       ARM_CSPMU_EVENT_ATTR(cycles,
> > > > > ARM_CSPMU_EVT_CYCLES_DEFAULT),
> > > > > >       NULL,
> > > > > > @@ -234,7 +253,7 @@ static const struct nv_cspmu_match
> > > > > nv_cspmu_match[] = {
> > > > > >         .filter_default_val = NV_CNVL_FILTER_ID_MASK,
> > > > > >         .name_pattern = "nvidia_cnvlink_pmu_%u",
> > > > > >         .name_fmt = NAME_FMT_SOCKET,
> > > > > > -       .event_attr = mcf_pmu_event_attrs,
> > > > > > +       .event_attr = mcf_cnvlink_pmu_event_attrs,
> > > > > >         .format_attr = cnvlink_pmu_format_attrs
> > > > > >       },
> > > > >
> > > > > Hmm. Isn't this a user-visible change? For example, will scripts driving
> > > > > 'perf' with the old event names continue to work after this patch?
> > > > >
> > > >
> > > > Yes this is user visible. I am expecting user script to be updated
> accordingly.
> > > > Would this be reasonable?
> > >
> > > I don't think so, no. We don't tend to require userspace changes as a
> > > result of upgrading the kernel.
> >
> > Are you referring to userspace change just on the perf tool side?
> > Cause this PMU doesn't have JSON scripts for alias/metric in the perf tool
> yet.
> 
> I'm not sure that matters, does it? If the mappings are exposed in sysfs,
> then the tool will pick them up.
> 
> > Do you have suggestion of the proper approach?
> 
> I'd say leave the event names like they are and if you want to add aliases,
> do that in userspace.

Hi Will,

Could you please review the V2 patches in https://lore.kernel.org/linux-arm-kernel/20241031142118.1865965-1-bwicaksono at nvidia.com/T/#t?

Thanks,
Besar


From vt at altlinux.org  Mon Dec  2 20:03:50 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Tue, 3 Dec 2024 07:03:50 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <Z05cuuMMurzp1jx5@linux.dev>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
 <Z05cuuMMurzp1jx5@linux.dev>
Message-ID: <20241203040350.4soyvaeqs75kjqoj@altlinux.org>

Oliver, Marc,

On Mon, Dec 02, 2024 at 05:19:54PM -0800, Oliver Upton wrote:
> On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> > Marc,
> > 
> > On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > > On Mon, 02 Dec 2024 15:59:40 +0000,
> > > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > > 
> > > > Marc,
> > > > 
> > > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > > >
> > > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > > 
> > > > No, host is 6.6.60.
> > > 
> > > Right. I wouldn't be surprised if:
> > > 
> > > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> > >   that's proably something we should backport)
> > 
> > How to confirm this? Currently I cannot find any (case-insensitive)
> > "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM strings
> > in `strace -v` (as it decodes some KVM ioctls) of qemu process.
> 
> If you can attach to the QEMU gdbstub of the VM, info registers will
> dump ~everything.
> 
> If the value of ID_AA64PFR0_EL1.MPAM (bits 43:40) is nonzero then the
> host KVM is erroneously advertising MPAM to the guest.

I don't find such register. There is what I get:

  (gdb) target remote :1234
  Remote debugging using :1234
  0x0000000040000000 in ?? ()

  (gdb) pipe i r | grep ID_AA64PFR

  ID_AA64PFR1_EL1 0x0                0
  ID_AA64PFR2_EL1_RESERVED 0x0       0
  ID_AA64PFR3_EL1_RESERVED 0x0       0
  ID_AA64PFR6_EL1_RESERVED 0x0       0
  ID_AA64PFR7_EL1_RESERVED 0x0       0
  (gdb)

This seems to be MPAM_frac, and it's 0, so "MPAM Extension not implemented"[1].

Thanks,

[1] https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/ID-AA64PFR1-EL1--AArch64-Processor-Feature-Register-1?lang=en#fieldset_0-19_16

> 
> -- 
> Thanks,
> Oliver


From mikhail.kshevetskiy at gmail.com  Mon Dec  2 20:33:55 2024
From: mikhail.kshevetskiy at gmail.com (Mikhail Kshevetskiy)
Date: Tue,  3 Dec 2024 07:33:55 +0300
Subject: [PATCH] arm64: dts: mediatek: mt7986: fix pwn fan settings for sinovoip bpi-r3 board
Message-ID: <20241203043355.2565797-1-mikhail.kshevetskiy@gmail.com>

Popular bpi-r3 pwm fans like this one

  https://www.amazon.com/youyeetoo-Barebone-Fan-BPI-R3-Integrated/dp/B0CCCTY8PS

will not work properly. Trying different pwm setting using a command

  echo $value > /sys/devices/platform/pwm-fan/hwmon/hwmon1/pwm1

I found:

  pwm1 value     fan rotation speed   cpu temperature     notes
  -----------------------------------------------------------------
    0            maximal              31.5 Celsius        too noisy
   40            optimal              35.2 Celsius        no noise hearable
   95            minimal
   above 95      does not rotate      55.5 Celsius
  -----------------------------------------------------------------

At the moment we have following cooling levels defined:

  cooling-levels = <255 96 0>;

for cpu-active-low, cpu-active-medium and cpu-active-high modes
correspondingly. Thus only cpu-active-high and cpu-active-low are usable.
I think this is wrong.

This patch fixes cpu-active-medium settings for bpi-r3 board.

PS: I know, the patch is not ideal as it can break pwm fan for some users.
    There are some peoples that use handmade cooling solutions, but:
      * discussed cooler is the only 'official' pwm cooler for bpi-r3
        available on the market.
      * most peoples will use passive cooling available on the market or
        the discussed cooler.
      * the pwm-fan dts section was added before the official cooler
        appears on the market.
    Thus it should not be a lot of harm from this fix.

This patch may not be enough. Users may wants to tweak their thermal_zone0
trip points, thus tuning fan rotation speed depending on cpu temperature.
That can be done on the base of the folloving example:

  === example =========
  # cpu temterature below 25 Celsius degrees, no rotation
  echo 25000 > /sys/class/thermal/thermal_zone0/trip_point_4_temp
  # cpu temperature in [25..32] Celsius degrees, normal rotation speed
  echo 32000 > /sys/class/thermal/thermal_zone0/trip_point_3_temp
  # cpu temperature above 50 Celsius degrees, max rotation speed
  echo 50000 > /sys/class/thermal/thermal_zone0/trip_point_2_temp
  =====================

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy at gmail.com>
---
 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 ed79ad1ae871..b0cc0cbdff0f 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
@@ -42,7 +42,7 @@ fan: pwm-fan {
 		compatible = "pwm-fan";
 		#cooling-cells = <2>;
 		/* cooling level (0, 1, 2) - pwm inverted */
-		cooling-levels = <255 96 0>;
+		cooling-levels = <255 40 0>;
 		pwms = <&pwm 0 10000>;
 		status = "okay";
 	};
-- 
2.45.2



From vigneshr at ti.com  Mon Dec  2 20:34:57 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 3 Dec 2024 10:04:57 +0530
Subject: [PATCH] dmaengine: dma_request_chan_by_mask() defer probing
 unconditionally
In-Reply-To: <4dd1caa7-4b95-4e06-a5ac-e2d33ce88d04@arm.com>
References: <20241127-defer-dma-request-chan-v1-1-203db7baf470@redhat.com>
 <4dd1caa7-4b95-4e06-a5ac-e2d33ce88d04@arm.com>
Message-ID: <ffccf100-469f-4e5b-a32c-5c06e196aacd@ti.com>

Hi Enric,

On 29/11/24 22:14, Robin Murphy wrote:
> On 2024-11-27 8:23 am, Enric Balletbo i Serra wrote:
>> Having no DMA devices registered is not a guarantee that the device
>> doesn't exist, it could be that is not registered yet, so return
>> EPROBE_DEFER unconditionally so the caller can wait for the required
>> DMA device registered.
>>
>> Signed-off-by: Enric Balletbo i Serra <eballetb at redhat.com>
>> ---
>> This patch fixes the following error on TI AM69-SK
>>
>> [??? 2.854501] cadence-qspi 47040000.spi: error -ENODEV: No Rx DMA
>> available
>>
>> The DMA device is probed after cadence-qspi driver, so deferring it
>> solves the problem.
> 
> Conversely, though, it does carry some risk that if there really is no
> DMA device/driver, other callers (e.g. spi-ti-qspi) may now get stuck
> deferring forever where the -ENODEV would have let them proceed with a
> fallback to non-DMA operation. driver_deferred_probe_check_state() is
> typically a good tool for these situations, but I guess it's a bit
> tricky in a context where we don't actually have the dependent device to
> hand :/


+1. There is no explicit dependency that can be modeled (via DT or
otherwise) for memcpy DMA channels. And the IP (cadence-qspi) is not
specific to TI platforms. Its very much possible that a non TI platform
may not have memcpy DMA channel at all. Wont this end up breaking such
platforms wrt using SPI flash using CPU bound IO?

> 
> Thanks,
> Robin.
> 
>> ---
>> ? drivers/dma/dmaengine.c | 8 ++++----
>> ? 1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
>> index
>> c1357d7f3dc6ca7899c4d68a039567e73b0f089d..57f07b477a5d9ad8f2656584b8c0d6dffb2ab469 100644
>> --- a/drivers/dma/dmaengine.c
>> +++ b/drivers/dma/dmaengine.c
>> @@ -889,10 +889,10 @@ struct dma_chan *dma_request_chan_by_mask(const
>> dma_cap_mask_t *mask)
>> ????? chan = __dma_request_channel(mask, NULL, NULL, NULL);
>> ????? if (!chan) {
>> ????????? mutex_lock(&dma_list_mutex);
>> -??????? if (list_empty(&dma_device_list))
>> -??????????? chan = ERR_PTR(-EPROBE_DEFER);
>> -??????? else
>> -??????????? chan = ERR_PTR(-ENODEV);
>> +??????? /* If the required DMA device is not registered yet,
>> +???????? * return EPROBE_DEFER
>> +???????? */
>> +??????? chan = ERR_PTR(-EPROBE_DEFER);
>> ????????? mutex_unlock(&dma_list_mutex);
>> ????? }
>> ?
>> ---
>> base-commit: 43fb83c17ba2d63dfb798f0be7453ed55ca3f9c2
>> change-id: 20241127-defer-dma-request-chan-4f26c62c8691
>>
>> Best regards,
> 

-- 
Regards
Vignesh
https://ti.com/opensource



From towinchenmi at gmail.com  Mon Dec  2 21:05:36 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:36 +0800
Subject: [PATCH v5 06/10] arm64: dts: apple: s8000: Add PMGR nodes
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-7-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s8000-pmgr.dtsi  | 757 +++++++++++++++++++++
 arch/arm64/boot/dts/apple/s8000.dtsi       |  22 +
 arch/arm64/boot/dts/apple/s800x-6s.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s800x-ipad5.dtsi |   4 +
 arch/arm64/boot/dts/apple/s800x-se.dtsi    |   4 +
 5 files changed, 791 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s8000-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/s8000-pmgr.dtsi b/arch/arm64/boot/dts/apple/s8000-pmgr.dtsi
new file mode 100644
index 000000000000..196b8e745a95
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s8000-pmgr.dtsi
@@ -0,0 +1,757 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple S8000/3 "A9" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80150 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80158 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80168 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80170 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80178 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80180 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80188 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 80190 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 80198 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801a0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801b0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 801f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 801f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80160 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_hsic1_phy: power-controller at 80130 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_isp_sens0: power-controller at 80138 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80140 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_usb: power-controller at 80250 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80258 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80260 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80270 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 80280 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 802c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 802e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 802b0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_pmp: power-controller at 802e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 802f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_uart5: power-controller at 80200 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80208 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80210 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80218 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 80220 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80228 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80230 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80238 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80240 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80248 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80268 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usb2host1_ohci: power-controller at 80278 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1_ohci";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_usb2host2_ohci: power-controller at 80288 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2_ohci";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_usbotg: power-controller at 80290 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 80298 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_dp: power-controller at 802c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_vdec: power-controller at 802f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc: power-controller at 80308 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 80310 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80318 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_pcie_link0: power-controller at 80320 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link0";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link1: power-controller at 80328 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link1";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link2: power-controller at 80330 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link2";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link3: power-controller at 80338 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link3";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_gfx: power-controller at 80340 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80340 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_venc_pipe: power-controller at 88000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 88008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_busif &ps_aop_cpu &ps_aop_filter>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+		power-domains = <&ps_aop>;
+	};
+
+	ps_aop_cpu: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80048 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80050 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s8000.dtsi b/arch/arm64/boot/dts/apple/s8000.dtsi
index 6e9046ea106c..84d6b4939ac4 100644
--- a/arch/arm64/boot/dts/apple/s8000.dtsi
+++ b/arch/arm64/boot/dts/apple/s8000.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,s8000-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -95,6 +106,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +125,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 119 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,s8000-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -132,6 +152,8 @@ timer {
 	};
 };
 
+#include "s8000-pmgr.dtsi"
+
 /*
  * The A9 was made by two separate fabs on two different process
  * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
diff --git a/arch/arm64/boot/dts/apple/s800x-6s.dtsi b/arch/arm64/boot/dts/apple/s800x-6s.dtsi
index 49b04db310c6..1dcf80cc2920 100644
--- a/arch/arm64/boot/dts/apple/s800x-6s.dtsi
+++ b/arch/arm64/boot/dts/apple/s800x-6s.dtsi
@@ -47,3 +47,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi
index 32570ed3cdf0..c1701e81f0c1 100644
--- a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi
+++ b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi
@@ -41,3 +41,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/s800x-se.dtsi b/arch/arm64/boot/dts/apple/s800x-se.dtsi
index a1a5690e8371..deb7c7cc90f6 100644
--- a/arch/arm64/boot/dts/apple/s800x-se.dtsi
+++ b/arch/arm64/boot/dts/apple/s800x-se.dtsi
@@ -47,3 +47,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:37 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:37 +0800
Subject: [PATCH v5 07/10] arm64: dts: apple: s8001: Add PMGR nodes
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-8-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s8001-common.dtsi   |   1 +
 .../arm64/boot/dts/apple/s8001-j98a-j99a.dtsi |  26 +
 arch/arm64/boot/dts/apple/s8001-j98a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-j99a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi     | 822 ++++++++++++++++++
 arch/arm64/boot/dts/apple/s8001.dtsi          |  22 +
 6 files changed, 873 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/s8001-common.dtsi b/arch/arm64/boot/dts/apple/s8001-common.dtsi
index e94d0e77653a..91b06e113894 100644
--- a/arch/arm64/boot/dts/apple/s8001-common.dtsi
+++ b/arch/arm64/boot/dts/apple/s8001-common.dtsi
@@ -24,6 +24,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0 &ps_dp0>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi b/arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
new file mode 100644
index 000000000000..e66a4c1c138f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple iPad Pro (12.9-inch)
+ *
+ * This file contains parts common to iPad Pro (12.9-inch).
+ *
+ * target-type: J98a, J99a
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+&ps_dcs4 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs5 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs6 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs7 {
+	apple,always-on; /* LPDDR4 interface */
+};
diff --git a/arch/arm64/boot/dts/apple/s8001-j98a.dts b/arch/arm64/boot/dts/apple/s8001-j98a.dts
index 6d6b841e7ab0..162eca05c2d9 100644
--- a/arch/arm64/boot/dts/apple/s8001-j98a.dts
+++ b/arch/arm64/boot/dts/apple/s8001-j98a.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s8001-pro.dtsi"
+#include "s8001-j98a-j99a.dtsi"
 
 / {
 	compatible = "apple,j98a", "apple,s8001", "apple,arm-platform";
diff --git a/arch/arm64/boot/dts/apple/s8001-j99a.dts b/arch/arm64/boot/dts/apple/s8001-j99a.dts
index d20194b1cae7..7b765820c69e 100644
--- a/arch/arm64/boot/dts/apple/s8001-j99a.dts
+++ b/arch/arm64/boot/dts/apple/s8001-j99a.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s8001-pro.dtsi"
+#include "s8001-j98a-j99a.dtsi"
 
 / {
 	compatible = "apple,j99a", "apple,s8001", "apple,arm-platform";
diff --git a/arch/arm64/boot/dts/apple/s8001-pmgr.dtsi b/arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
new file mode 100644
index 000000000000..859ab77ae92b
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
@@ -0,0 +1,822 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple S8001 "A9X" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80148 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80150 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pcie_ref: power-controller at 80140 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80160 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80168 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80170 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80178 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80180 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 80188 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 80190 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 80198 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801a0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801b0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 801e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 801f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 801f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80158 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_isp_sens0: power-controller at 80130 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80138 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb: power-controller at 80278 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80280 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80288 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80298 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 802a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_disp1mux: power-controller at 802e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1mux";
+	};
+
+	ps_disp0: power-controller at 802d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp1: power-controller at 802f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp1mux>;
+	};
+
+	ps_uart6: power-controller at 80200 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80208 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80210 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 80218 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80230 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80238 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80240 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80248 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80250 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs4: power-controller at 80258 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs4";
+	};
+
+	ps_dcs5: power-controller at 80260 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs5";
+	};
+
+	ps_dcs6: power-controller at 80268 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs6";
+	};
+
+	ps_dcs7: power-controller at 80270 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs7";
+	};
+
+	ps_usb2host0_ohci: power-controller at 80290 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 802b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 802c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_dp0: power-controller at 802e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp0";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_dp1: power-controller at 802f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp1";
+		power-domains = <&ps_disp1>;
+	};
+
+	ps_dpa0: power-controller at 80220 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa0";
+	};
+
+	ps_dpa1: power-controller at 80228 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa1";
+	};
+
+	ps_media: power-controller at 80308 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 80300 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 80318 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 80310 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc: power-controller at 80340 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80340 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 80348 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80348 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_srs: power-controller at 80390 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80390 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "srs";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie_aux: power-controller at 80350 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80350 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_pcie_link0: power-controller at 80358 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80358 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link0";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link1: power-controller at 80360 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80360 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link1";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link2: power-controller at 80368 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80368 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link2";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link3: power-controller at 80370 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80370 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link3";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link4: power-controller at 80378 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80378 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link4";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link5: power-controller at 80380 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80380 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link5";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_vdec: power-controller at 80330 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80388 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80388 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_pmp: power-controller at 80320 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 80328 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on*/
+	};
+
+	ps_venc_pipe: power-controller at 88000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 88008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_cpu &ps_aop_filter &ps_aop_busif>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+	};
+
+	ps_aop_cpu: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80048 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80050 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s8001.dtsi b/arch/arm64/boot/dts/apple/s8001.dtsi
index 23ee3238844d..3963c6d8ca5e 100644
--- a/arch/arm64/boot/dts/apple/s8001.dtsi
+++ b/arch/arm64/boot/dts/apple/s8001.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,s8000-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -95,6 +106,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +125,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 134 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,s8000-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -131,3 +151,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "s8001-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:38 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:38 +0800
Subject: [PATCH v5 08/10] arm64: dts: apple: t8010: Add PMGR nodes
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-9-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8010-7.dtsi     |   4 +
 arch/arm64/boot/dts/apple/t8010-ipad6.dtsi |   4 +
 arch/arm64/boot/dts/apple/t8010-n112.dts   |   4 +
 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi  | 772 +++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8010.dtsi       |  22 +
 5 files changed, 806 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8010-7.dtsi b/arch/arm64/boot/dts/apple/t8010-7.dtsi
index 1332fd73f50f..91fae47d25d0 100644
--- a/arch/arm64/boot/dts/apple/t8010-7.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010-7.dtsi
@@ -41,3 +41,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
index 81696c6e302c..b83fe153763e 100644
--- a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
@@ -42,3 +42,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0_fe &ps_disp0_be &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-n112.dts b/arch/arm64/boot/dts/apple/t8010-n112.dts
index 6e71c3cb5d92..48fdbedf74da 100644
--- a/arch/arm64/boot/dts/apple/t8010-n112.dts
+++ b/arch/arm64/boot/dts/apple/t8010-n112.dts
@@ -45,3 +45,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
new file mode 100644
index 000000000000..6d451088616a
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
@@ -0,0 +1,772 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8010 "A10" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80160 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80168 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_socuvd: power-controller at 80150 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "socuvd";
+	};
+
+	ps_mca0: power-controller at 80178 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80180 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80188 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80190 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80170 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_isp_sens0: power-controller at 80130 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80138 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_isp_sens2: power-controller at 80140 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens2";
+	};
+
+	ps_usb: power-controller at 80268 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80270 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80278 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80288 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp_sys: power-controller at 802d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 802e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp0_be: power-controller at 802b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_pmp: power-controller at 802f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 802f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_uart3: power-controller at 80200 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80208 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 80210 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80218 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80220 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80228 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80238 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80240 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80248 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80250 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80258 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80260 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80280 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 80290 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 80298 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_dp: power-controller at 802c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_venc_sys: power-controller at 80310 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 80318 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80320 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_vdec0: power-controller at 80300 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec0";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80328 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_dprx: power-controller at 84028 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dprx";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_pipe4: power-controller at 88000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_pipe5: power-controller at 88008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_me0: power-controller at 88010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_cpu &ps_aop_busif &ps_aop_filter>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+	};
+
+	ps_aop_cpu: power-controller at 80048 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80050 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80058 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8010.dtsi b/arch/arm64/boot/dts/apple/t8010.dtsi
index e3d6a8354103..ac1dda92f890 100644
--- a/arch/arm64/boot/dts/apple/t8010.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,t8010-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -95,6 +106,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +125,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 134 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,t8010-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -131,3 +151,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8010-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:39 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:39 +0800
Subject: [PATCH v5 09/10] arm64: dts: apple: t8011: Add PMGR nodes
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-10-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8011-common.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi   | 806 ++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8011-pro2.dtsi   |   8 +
 arch/arm64/boot/dts/apple/t8011.dtsi        |  22 +
 4 files changed, 837 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8011-common.dtsi b/arch/arm64/boot/dts/apple/t8011-common.dtsi
index 44a0d0ea2ee3..2010b56246f1 100644
--- a/arch/arm64/boot/dts/apple/t8011-common.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011-common.dtsi
@@ -22,6 +22,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0_fe &ps_disp0_be &ps_dp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t8011-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
new file mode 100644
index 000000000000..c44e3f9d7087
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
@@ -0,0 +1,806 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8011 "A10X" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu2: power-controller at 80010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu2";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80158 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80160 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80170 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80178 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80180 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80188 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80190 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 801f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80168 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb3host>;
+	};
+
+	ps_isp_sens0: power-controller at 80130 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80138 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_isp_sens2: power-controller at 80140 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens2";
+	};
+
+	ps_usb: power-controller at 80288 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80290 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host: power-controller at 80298 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2dev: power-controller at 802a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2dev";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb3host: power-controller at 802a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb3host";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb3dev: power-controller at 802b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb3dev";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_media: power-controller at 802e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp_sys: power-controller at 802e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+	};
+
+	ps_msr: power-controller at 802f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+	};
+
+	ps_disp0_be: power-controller at 802d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_dpa: power-controller at 80230 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80200 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 80208 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80210 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80218 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80220 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80238 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80240 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80248 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80250 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80258 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80260 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs4: power-controller at 80268 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs4";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs5: power-controller at 80270 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs5";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs6: power-controller at 80278 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs6";
+	};
+
+	ps_dcs7: power-controller at 80280 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs7";
+	};
+
+	ps_smx: power-controller at 802b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_dp: power-controller at 802d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_venc_sys: power-controller at 80320 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_srs: power-controller at 80390 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80390 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "srs";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pms_sram: power-controller at 80308 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_pmp: power-controller at 80300 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pcie: power-controller at 80328 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80330 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_vdec0: power-controller at 80310 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec0";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80338 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_dprx: power-controller at 84028 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dprx";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_pipe4: power-controller at 88000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_pipe5: power-controller at 88008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_me0: power-controller at 88010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_cpu &ps_aop_filter &ps_aop_busif>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+	};
+
+	ps_aop_cpu: power-controller at 80048 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80050 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80058 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8011-pro2.dtsi b/arch/arm64/boot/dts/apple/t8011-pro2.dtsi
index f4e707415003..5eaa0a73350f 100644
--- a/arch/arm64/boot/dts/apple/t8011-pro2.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011-pro2.dtsi
@@ -40,3 +40,11 @@ button-volup {
 		};
 	};
 };
+
+&ps_dcs6 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs7 {
+	apple,always-on; /* LPDDR4 interface */
+};
diff --git a/arch/arm64/boot/dts/apple/t8011.dtsi b/arch/arm64/boot/dts/apple/t8011.dtsi
index 6c4ed9dc4a50..b845fa6f6d64 100644
--- a/arch/arm64/boot/dts/apple/t8011.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011.dtsi
@@ -69,19 +69,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,t8010-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -103,6 +114,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -121,6 +133,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 131 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,t8010-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -139,3 +159,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8011-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:40 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:40 +0800
Subject: [PATCH v5 10/10] arm64: dts: apple: t8015: Add PMGR nodes
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-11-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8015-common.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi   | 931 ++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8015.dtsi        |  21 +
 3 files changed, 953 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8015-common.dtsi b/arch/arm64/boot/dts/apple/t8015-common.dtsi
index 69258a33ea50..498f58fb9715 100644
--- a/arch/arm64/boot/dts/apple/t8015-common.dtsi
+++ b/arch/arm64/boot/dts/apple/t8015-common.dtsi
@@ -24,6 +24,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0_be &ps_mipi_dsi &ps_disp0_hilo &ps_disp0_ppp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi
new file mode 100644
index 000000000000..e238c2d2732f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi
@@ -0,0 +1,931 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8015 "A11" SoC
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu2: power-controller at 80010 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu2";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu3: power-controller at 80018 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu3";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu4: power-controller at 80020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu4";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu5: power-controller at 80028 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu5";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80158 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80160 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80170 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80178 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80180 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80188 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80190 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 801a0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801b0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801c0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801c8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801d0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801d8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801e0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801e8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801f0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801f8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80168 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsicphy: power-controller at 80128 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsicphy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_ispsens0: power-controller at 80130 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 80138 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_ispsens2: power-controller at 80140 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens2";
+	};
+
+	ps_mca5: power-controller at 80198 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_usb: power-controller at 80270 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctlreg: power-controller at 80278 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctlreg";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80280 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctlreg>;
+	};
+
+	ps_usb2host1: power-controller at 80290 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctlreg>;
+	};
+
+	ps_rtmux: power-controller at 802b0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802f0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_jpg: power-controller at 802f8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802b8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp0_be: power-controller at 802c0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_disp0_gp: power-controller at 802c8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_gp";
+		power-domains = <&ps_disp0_be>;
+		status = "disabled";
+	};
+
+	ps_uart3: power-controller at 80200 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80208 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 80210 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80218 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80220 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80228 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80238 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80248 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80250 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_dcs1: power-controller at 80258 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_dcs2: power-controller at 80260 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_dcs3: power-controller at 80268 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80288 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usb2dev: power-controller at 80298 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2dev";
+		power-domains = <&ps_usbctlreg>;
+	};
+
+	ps_smx: power-controller at 802a0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802d8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_dp: power-controller at 802e0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_dpa: power-controller at 80230 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa";
+	};
+
+	ps_disp0_be_2x: power-controller at 802d0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be_2x";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_isp_sys: power-controller at 80350 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80350 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 80300 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc_sys: power-controller at 80398 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80398 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pmp: power-controller at 80308 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 80310 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_pcie: power-controller at 80318 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80320 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_vdec0: power-controller at 80388 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80388 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec0";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80338 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_ans2: power-controller at 80328 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans2";
+		apple,always-on;
+	};
+
+	ps_pcie_direct: power-controller at 80330 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_direct";
+		apple,always-on;
+	};
+
+	ps_avd_sys: power-controller at 803a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x803a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "avd_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_disp0_gp0: power-controller at 80830 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80830 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_gp0";
+		power-domains = <&ps_disp0_gp>;
+		status = "disabled";
+	};
+
+	ps_disp0_gp1: power-controller at 80838 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80838 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_gp1";
+		status = "disabled";
+	};
+
+	ps_disp0_ppp: power-controller at 80840 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80840 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_ppp";
+	};
+
+	ps_disp0_hilo: power-controller at 80848 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80848 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_hilo";
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_dprx: power-controller at 84028 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dprx";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_cnv: power-controller at 84030 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_cnv";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_dma: power-controller at 88000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_dma";
+	};
+
+	ps_venc_pipe4: power-controller at 88010 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+	};
+
+	ps_venc_pipe5: power-controller at 88018 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+	};
+
+	ps_venc_me0: power-controller at 88020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88028 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop_base: power-controller at 80008 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_base";
+		power-domains = <&ps_aop_cpu &ps_aop_filter>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80050 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_cpu: power-controller at 80020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_spmi: power-controller at 80058 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spmi";
+		apple,always-on; /* System Power Management Interface */
+	};
+
+	ps_smc_i2cm1: power-controller at 800a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x800a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_i2cm1";
+	};
+
+	ps_smc_fabric: power-controller at 80030 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_fabric";
+	};
+
+	ps_smc_cpu: power-controller at 80140 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_cpu";
+		power-domains = <&ps_smc_fabric &ps_smc_i2cm1>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8015.dtsi b/arch/arm64/boot/dts/apple/t8015.dtsi
index 8828d830e5be..fbff3a6c0ba4 100644
--- a/arch/arm64/boot/dts/apple/t8015.dtsi
+++ b/arch/arm64/boot/dts/apple/t8015.dtsi
@@ -119,6 +119,7 @@ serial0: serial at 22e600000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
@@ -127,11 +128,21 @@ aic: interrupt-controller at 232100000 {
 			reg = <0x2 0x32100000 0x0 0x8000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
+		};
+
+		pmgr: power-management at 232000000 {
+			compatible = "apple,t8015-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x32000000 0 0x8c000>;
 		};
 
 		pinctrl_ap: pinctrl at 233100000 {
 			compatible = "apple,t8015-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x33100000 0x0 0x1000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -188,6 +199,14 @@ pinctrl_nub: pinctrl at 2351f0000 {
 				     <AIC_IRQ 170 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 235200000 {
+			compatible = "apple,t8015-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x35200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2352b0000 {
 			compatible = "apple,t8015-wdt", "apple,wdt";
 			reg = <0x2 0x352b0000 0x0 0x4000>;
@@ -232,3 +251,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8015-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:10:26 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:10:26 +0800
Subject: [PATCH v2 0/3] Device Tree for Apple T2 (T8012) SoC devices
Message-ID: <20241203051147.110980-1-towinchenmi@gmail.com>

This series adds device trees for the Apple T2 Security Chip found on
some Intel Macs released after 2017. This SoC is based on Apple A10
(T8010) SoC and, for many hardware blocks, can share the A10 compatibles.

This series requires the PMGR power domains series for A7-A11[1] for
the "apple,t8010-pmgr-pwrstate" and "apple,t8010-pmgr" compaibles,
but otherwise can be applied cleanly.

Changes since v1:
- Use imperative mood in commit messages

Link to v1: https://lore.kernel.org/asahi/20241201161942.36027-1-towinchenmi at gmail.com/T

[1]: https://lore.kernel.org/asahi/20241201155820.29259-1-towinchenmi at gmail.com/T

Nick Chan
---

Nick Chan (3):
  dt-bindings: arm: apple: Add T2 devices
  arm64: dts: apple: Add T2 devices
  arm64: dts: apple: t8012: Add PMGR nodes

 .../devicetree/bindings/arm/apple.yaml        |  41 +
 arch/arm64/boot/dts/apple/Makefile            |  16 +
 arch/arm64/boot/dts/apple/t8012-j132.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j137.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j140a.dts     |  14 +
 arch/arm64/boot/dts/apple/t8012-j140k.dts     |  14 +
 arch/arm64/boot/dts/apple/t8012-j152f.dts     |  15 +
 arch/arm64/boot/dts/apple/t8012-j160.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j174.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j185.dts      |  14 +
 arch/arm64/boot/dts/apple/t8012-j185f.dts     |  14 +
 arch/arm64/boot/dts/apple/t8012-j213.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-j214k.dts     |  15 +
 arch/arm64/boot/dts/apple/t8012-j215.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-j223.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-j230k.dts     |  14 +
 arch/arm64/boot/dts/apple/t8012-j680.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-j780.dts      |  15 +
 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi     |  44 +
 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi     | 837 ++++++++++++++++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |  20 +
 arch/arm64/boot/dts/apple/t8012.dtsi          | 198 +++++
 22 files changed, 1387 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j132.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j137.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140a.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j152f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j160.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j174.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j213.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j214k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j215.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j223.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j230k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j680.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j780.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012.dtsi


base-commit: bcdb59aa6d1f196ec853235957aba5852d6697cc
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:10:27 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:10:27 +0800
Subject: [PATCH v2 1/3] dt-bindings: arm: apple: Add T2 devices
In-Reply-To: <20241203051147.110980-1-towinchenmi@gmail.com>
References: <20241203051147.110980-1-towinchenmi@gmail.com>
Message-ID: <20241203051147.110980-2-towinchenmi@gmail.com>

Add the following apple,t8012 based platforms:

- Apple T2 MacBookPro15,2 (j132)
- Apple T2 iMacPro1,1 (j137)
- Apple T2 MacBookAir8,2 (j140a)
- Apple T2 MacBookAir8,1 (j140k)
- Apple T2 MacBookPro16,1 (j152f)
- Apple T2 MacPro7,1 (j160)
- Apple T2 Macmini8,1 (j174)
- Apple T2 iMac20,1 (j185)
- Apple T2 iMac20,2 (j185f)
- Apple T2 MacBookPro15,4 (j213)
- Apple T2 MacBookPro16,2 (j214k)
- Apple T2 MacBookPro16,4 (j215)
- Apple T2 MacBookPro16,3 (j223)
- Apple T2 MacBookAir9,1 (j230k)
- Apple T2 MacBookPro15,1 (j680)
- Apple T2 MacBookPro15,3 (j780)

These devices have no offical names, the naming scheme is from
libirecovery.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../devicetree/bindings/arm/apple.yaml        | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/apple.yaml b/Documentation/devicetree/bindings/arm/apple.yaml
index dc9aab19ff11..da60e9de1cfb 100644
--- a/Documentation/devicetree/bindings/arm/apple.yaml
+++ b/Documentation/devicetree/bindings/arm/apple.yaml
@@ -57,6 +57,25 @@ description: |
   - iPad Pro (2nd Generation) (10.5 Inch)
   - iPad Pro (2nd Generation) (12.9 Inch)
 
+  Devices based on the "T2" SoC:
+
+  - Apple T2 MacBookPro15,2 (j132)
+  - Apple T2 iMacPro1,1 (j137)
+  - Apple T2 MacBookAir8,2 (j140a)
+  - Apple T2 MacBookAir8,1 (j140k)
+  - Apple T2 MacBookPro16,1 (j152f)
+  - Apple T2 MacPro7,1 (j160)
+  - Apple T2 Macmini8,1 (j174)
+  - Apple T2 iMac20,1 (j185)
+  - Apple T2 iMac20,2 (j185f)
+  - Apple T2 MacBookPro15,4 (j213)
+  - Apple T2 MacBookPro16,2 (j214k)
+  - Apple T2 MacBookPro16,4 (j215)
+  - Apple T2 MacBookPro16,3 (j223)
+  - Apple T2 MacBookAir9,1 (j230k)
+  - Apple T2 MacBookPro15,1 (j680)
+  - Apple T2 MacBookPro15,3 (j780)
+
   Devices based on the "A11" SoC:
 
   - iPhone 8
@@ -211,6 +230,28 @@ properties:
           - const: apple,t8011
           - const: apple,arm-platform
 
+      - description: Apple T2 SoC based platforms
+        items:
+          - enum:
+              - apple,j132  # Apple T2 MacBookPro15,2 (j132)
+              - apple,j137  # Apple T2 iMacPro1,1 (j137)
+              - apple,j140a # Apple T2 MacBookAir8,2 (j140a)
+              - apple,j140k # Apple T2 MacBookAir8,1 (j140k)
+              - apple,j152f # Apple T2 MacBookPro16,1 (j152f)
+              - apple,j160  # Apple T2 MacPro7,1 (j160)
+              - apple,j174  # Apple T2 Macmini8,1 (j174)
+              - apple,j185  # Apple T2 iMac20,1 (j185)
+              - apple,j185f # Apple T2 iMac20,2 (j185f)
+              - apple,j213  # Apple T2 MacBookPro15,4 (j213)
+              - apple,j214k # Apple T2 MacBookPro16,2 (j214k)
+              - apple,j215  # Apple T2 MacBookPro16,4 (j215)
+              - apple,j223  # Apple T2 MacBookPro16,3 (j223)
+              - apple,j230k # Apple T2 MacBookAir9,1 (j230k)
+              - apple,j680  # Apple T2 MacBookPro15,1 (j680)
+              - apple,j780  # Apple T2 MacBookPro15,3 (j780)
+          - const: apple,t8012
+          - const: apple,arm-platform
+
       - description: Apple A11 SoC based platforms
         items:
           - enum:
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:30 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:30 +0800
Subject: [PATCH v5 00/10] Add PMGR nodes for Apple A7-A11 SoCs
Message-ID: <20241203050640.109378-1-towinchenmi@gmail.com>

This series adds the PMGR nodes and all known power state subnodes for
Apple A7-A11 SoCs, along with the associated dt-bindings.

Changes since v4:
- Use imperative mood in commit messages.

Link to v4: https://lore.kernel.org/asahi/20241201161942.36027-1-towinchenmi at gmail.com/T

Changes since v3:
- Add "apple,always-on" property to "ps_spmi" in t8015 power domains.
This is required for cpufreq to function correctly which will be added
in a later series.

Link to v3: https://lore.kernel.org/asahi/20241122095136.35046-1-towinchenmi at gmail.com/T

Changes since v2:
- Removed "apple,always-on" property from "ps_pmp" from s8001, t8011,
t8015 power domains. It is not on at boot. (Mixed up with ps_pms which
is required to be on)
- Add asahi-soc/dt back into the subject prefix, missing from v2.

Link to v2: https://lore.kernel.org/asahi/20241102011004.59339-1-towinchenmi at gmail.com/T

Changes since v1:
- Removed "framebuffer0" dt aliases. It is not standard and not needed.

Link to v1: https://lore.kernel.org/asahi/20241029010526.42052-1-towinchenmi at gmail.com/T

Nick Chan
---

Nick Chan (10):
  dt-bindings: arm: apple: apple,pmgr: Add A7-A11 compatibles
  dt-bindings: arm: apple: apple,pmgr-pwrstate: Add A7-A11 compatibles
  arm64: dts: apple: s5l8960x: Add PMGR node
  arm64: dts: apple: t7000: Add PMGR node
  arm64: dts: apple: t7001: Add PMGR node
  arm64: dts: apple: s8000: Add PMGR nodes
  arm64: dts: apple: s8001: Add PMGR nodes
  arm64: dts: apple: t8010: Add PMGR nodes
  arm64: dts: apple: t8011: Add PMGR nodes
  arm64: dts: apple: t8015: Add PMGR nodes

 .../bindings/arm/apple/apple,pmgr.yaml        |   5 +
 .../bindings/power/apple,pmgr-pwrstate.yaml   |   5 +
 arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi  |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi  | 610 ++++++++++++
 arch/arm64/boot/dts/apple/s5l8960x.dtsi       |  13 +
 arch/arm64/boot/dts/apple/s8000-pmgr.dtsi     | 757 ++++++++++++++
 arch/arm64/boot/dts/apple/s8000.dtsi          |  22 +
 arch/arm64/boot/dts/apple/s8001-common.dtsi   |   1 +
 .../arm64/boot/dts/apple/s8001-j98a-j99a.dtsi |  26 +
 arch/arm64/boot/dts/apple/s8001-j98a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-j99a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi     | 822 ++++++++++++++++
 arch/arm64/boot/dts/apple/s8001.dtsi          |  22 +
 arch/arm64/boot/dts/apple/s800x-6s.dtsi       |   4 +
 arch/arm64/boot/dts/apple/s800x-ipad5.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s800x-se.dtsi       |   4 +
 arch/arm64/boot/dts/apple/t7000-6.dtsi        |   4 +
 arch/arm64/boot/dts/apple/t7000-j42d.dts      |   1 +
 arch/arm64/boot/dts/apple/t7000-mini4.dtsi    |   4 +
 arch/arm64/boot/dts/apple/t7000-n102.dts      |   4 +
 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi     | 641 ++++++++++++
 arch/arm64/boot/dts/apple/t7000.dtsi          |  14 +
 arch/arm64/boot/dts/apple/t7001-air2.dtsi     |   1 +
 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi     | 650 ++++++++++++
 arch/arm64/boot/dts/apple/t7001.dtsi          |  13 +
 arch/arm64/boot/dts/apple/t8010-7.dtsi        |   4 +
 arch/arm64/boot/dts/apple/t8010-ipad6.dtsi    |   4 +
 arch/arm64/boot/dts/apple/t8010-n112.dts      |   4 +
 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi     | 772 +++++++++++++++
 arch/arm64/boot/dts/apple/t8010.dtsi          |  22 +
 arch/arm64/boot/dts/apple/t8011-common.dtsi   |   1 +
 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi     | 806 +++++++++++++++
 arch/arm64/boot/dts/apple/t8011-pro2.dtsi     |   8 +
 arch/arm64/boot/dts/apple/t8011.dtsi          |  22 +
 arch/arm64/boot/dts/apple/t8015-common.dtsi   |   1 +
 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi     | 931 ++++++++++++++++++
 arch/arm64/boot/dts/apple/t8015.dtsi          |  21 +
 39 files changed, 6237 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8000-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi


base-commit: 9ad55a67a788c0806b0fe23be36fae6dbfbc3fc5
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:31 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:31 +0800
Subject: [PATCH v5 01/10] dt-bindings: arm: apple: apple,pmgr: Add A7-A11 compatibles
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-2-towinchenmi@gmail.com>

The blocks found on Apple A7-A11 SoCs are compatible with the existing
driver so add their per-SoC compatibles.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
index 673277a7a224..5001f4d5a0dc 100644
--- a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
+++ b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
@@ -22,6 +22,11 @@ properties:
   compatible:
     items:
       - enum:
+          - apple,s5l8960x-pmgr
+          - apple,t7000-pmgr
+          - apple,s8000-pmgr
+          - apple,t8010-pmgr
+          - apple,t8015-pmgr
           - apple,t8103-pmgr
           - apple,t8112-pmgr
           - apple,t6000-pmgr
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:32 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:32 +0800
Subject: [PATCH v5 02/10] dt-bindings: arm: apple: apple,pmgr-pwrstate: Add A7-A11 compatibles
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-3-towinchenmi@gmail.com>

The blocks found on Apple A7-A11 SoCs are compatible with the existing
driver so add their per-SoC compatible.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../devicetree/bindings/power/apple,pmgr-pwrstate.yaml       | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
index 59a6af735a21..6e9a670eaf56 100644
--- a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
+++ b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
@@ -31,6 +31,11 @@ properties:
   compatible:
     items:
       - enum:
+          - apple,s5l8960x-pmgr-pwrstate
+          - apple,t7000-pmgr-pwrstate
+          - apple,s8000-pmgr-pwrstate
+          - apple,t8010-pmgr-pwrstate
+          - apple,t8015-pmgr-pwrstate
           - apple,t8103-pmgr-pwrstate
           - apple,t8112-pmgr-pwrstate
           - apple,t6000-pmgr-pwrstate
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:33 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:33 +0800
Subject: [PATCH v5 03/10] arm64: dts: apple: s5l8960x: Add PMGR node
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-4-towinchenmi@gmail.com>

Add the PMGR node and all known power state subnodes. Since there are
a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi  |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi  | 610 ++++++++++++++++++
 arch/arm64/boot/dts/apple/s5l8960x.dtsi       |  13 +
 5 files changed, 635 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
index 0b16adf07f79..51c081923657 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
index 741c5a9f21dd..7d6e799c933a 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
index b27ef5680626..2ba846db2266 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
new file mode 100644
index 000000000000..da265f484307
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
@@ -0,0 +1,610 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple S5L8960X "A7" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 20000 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 20008 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_secuart0: power-controller at 200f0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "secuart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_secuart1: power-controller at 200f8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "secuart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_cpm: power-controller at 20010 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_lio: power-controller at 20018 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "lio";
+		apple,always-on; /* Core device */
+	};
+
+	ps_iomux: power-controller at 20020 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_aic: power-controller at 20028 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_debug: power-controller at 20030 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_dwi: power-controller at 20038 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20038 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 20040 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_mca0: power-controller at 20048 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 20050 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 20058 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 20060 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20060 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 20068 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20068 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 20070 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20070 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 20078 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20078 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 20080 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20080 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 20088 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20088 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 20090 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20090 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 20098 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20098 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 200a0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 200a8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 200b0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 200b8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 200c0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 200c8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 200d0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 200d8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 200e0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 200e8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio_p: power-controller at 20110 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+	};
+
+	ps_usb: power-controller at 20158 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 20160 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 20170 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 20180 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_disp_busmux: power-controller at 201a8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp_busmux";
+	};
+
+	ps_media: power-controller at 201d8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 201d0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+	};
+
+	ps_msr: power-controller at 201e0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 201e8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 201b0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_aes0: power-controller at 20100 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 20108 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 20118 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_hsic1_phy: power-controller at 20120 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_hsic2_phy: power-controller at 20128 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic2_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_ispsens0: power-controller at 20130 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 20138 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_mcc: power-controller at 20140 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Core device */
+	};
+
+	ps_mcu: power-controller at 20148 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcu";
+		apple,always-on; /* Core device */
+	};
+
+	ps_amp: power-controller at 20150 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "amp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb2host0_ohci: power-controller at 20168 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usb2host1_ohci: power-controller at 20178 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1_ohci";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_usbotg: power-controller at 20188 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 20190 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 20198 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_cp: power-controller at 201a0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_mipi_dsi: power-controller at 201b8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_dp: power-controller at 201c0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_disp1: power-controller at 201c8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_vdec: power-controller at 201f0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc: power-controller at 201f8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans: power-controller at 20200 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans";
+	};
+
+	ps_ans_dll: power-controller at 20208 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans_dll";
+		power-domains = <&ps_ans>;
+	};
+
+	ps_gfx: power-controller at 20218 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 20268 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		power-domains = <&ps_secuart1>, <&ps_secuart0>;
+		apple,always-on; /* Locked on */
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x.dtsi b/arch/arm64/boot/dts/apple/s5l8960x.dtsi
index 0218ecac1d83..7705215fbdc7 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x.dtsi
@@ -62,9 +62,18 @@ serial0: serial at 20a0a0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s5l8960x-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x24000>;
+		};
+
 		wdt: watchdog at 20e027000 {
 			compatible = "apple,s5l8960x-wdt", "apple,wdt";
 			reg = <0x2 0x0e027000 0x0 0x1000>;
@@ -78,11 +87,13 @@ aic: interrupt-controller at 20e100000 {
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl: pinctrl at 20e300000 {
 			compatible = "apple,s5l8960x-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0e300000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -111,3 +122,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "s5l8960x-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:34 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:34 +0800
Subject: [PATCH v5 04/10] arm64: dts: apple: t7000: Add PMGR node
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-5-towinchenmi@gmail.com>

Add the PMGR node and all known power state subnodes. Since there are
a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t7000-6.dtsi     |   4 +
 arch/arm64/boot/dts/apple/t7000-j42d.dts   |   1 +
 arch/arm64/boot/dts/apple/t7000-mini4.dtsi |   4 +
 arch/arm64/boot/dts/apple/t7000-n102.dts   |   4 +
 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi  | 641 +++++++++++++++++++++
 arch/arm64/boot/dts/apple/t7000.dtsi       |  14 +
 6 files changed, 668 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t7000-6.dtsi b/arch/arm64/boot/dts/apple/t7000-6.dtsi
index f60ea4a4a387..77d74d6af1c4 100644
--- a/arch/arm64/boot/dts/apple/t7000-6.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000-6.dtsi
@@ -48,3 +48,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-j42d.dts b/arch/arm64/boot/dts/apple/t7000-j42d.dts
index 2231db6a739d..4de5e6a3f230 100644
--- a/arch/arm64/boot/dts/apple/t7000-j42d.dts
+++ b/arch/arm64/boot/dts/apple/t7000-j42d.dts
@@ -20,6 +20,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0 &ps_dp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
index c64ddc402fda..e5a9656045f2 100644
--- a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-n102.dts b/arch/arm64/boot/dts/apple/t7000-n102.dts
index 9c55d339ba4e..99eb8a2b8c73 100644
--- a/arch/arm64/boot/dts/apple/t7000-n102.dts
+++ b/arch/arm64/boot/dts/apple/t7000-n102.dts
@@ -46,3 +46,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-pmgr.dtsi b/arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
new file mode 100644
index 000000000000..5948fa7afffc
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
@@ -0,0 +1,641 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T7000 "A8" SoC
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+&pmgr {
+	ps_cpu0: power-controller at 20000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 20008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 20040 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_p: power-controller at 201f8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+	};
+
+	ps_lio: power-controller at 20100 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "lio";
+		apple,always-on; /* Core device */
+	};
+
+	ps_iomux: power-controller at 20108 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_aic: power-controller at 20110 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_debug: power-controller at 20118 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_dwi: power-controller at 20120 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 20128 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_mca0: power-controller at 20130 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 20138 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 20140 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 20148 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 20150 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 20158 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 20160 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 20168 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 20170 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 20178 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 20180 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 20188 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 20190 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 20198 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 201a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 201a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 201b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 201b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 201c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 201c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 201d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 201d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 201e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 201e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 201f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb: power-controller at 20248 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 20250 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 20258 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 20268 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 20278 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_disp_busmux: power-controller at 202a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp_busmux";
+	};
+
+	ps_media: power-controller at 202d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 202d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+	};
+
+	ps_msr: power-controller at 202e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 202e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 202b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_disp1: power-controller at 202c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_pcie_ref: power-controller at 20220 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_hsic0_phy: power-controller at 20200 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_hsic1_phy: power-controller at 20208 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_ispsens0: power-controller at 20210 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 20218 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_mcc: power-controller at 20230 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_mcu: power-controller at 20238 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcu";
+		apple,always-on; /* Core device */
+	};
+
+	ps_amp: power-controller at 20240 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "amp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb2host0_ohci: power-controller at 20260 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 20288 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 20290 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple Fabric, critical block */
+	};
+
+	ps_sf: power-controller at 20298 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple Fabric, critical block */
+	};
+
+	ps_cp: power-controller at 202a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_mipi_dsi: power-controller at 202b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_dp: power-controller at 202c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_vdec: power-controller at 202f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans: power-controller at 20318 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans";
+	};
+
+	ps_venc: power-controller at 20300 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 20308 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 20310 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_gfx: power-controller at 20320 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 20400 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_venc_pipe: power-controller at 21000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 21008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me1: power-controller at 21010 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+		power-domains = <&ps_venc>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t7000.dtsi b/arch/arm64/boot/dts/apple/t7000.dtsi
index a7cc29e84c84..ed1e9a62ba05 100644
--- a/arch/arm64/boot/dts/apple/t7000.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000.dtsi
@@ -62,6 +62,7 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
@@ -74,9 +75,18 @@ serial6: serial at 20a0d8000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart6>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t7000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x24000>;
+		};
+
 		wdt: watchdog at 20e027000 {
 			compatible = "apple,t7000-wdt", "apple,wdt";
 			reg = <0x2 0x0e027000 0x0 0x1000>;
@@ -90,11 +100,13 @@ aic: interrupt-controller at 20e100000 {
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl: pinctrl at 20e300000 {
 			compatible = "apple,t7000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0e300000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -123,3 +135,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t7000-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:05:35 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:05:35 +0800
Subject: [PATCH v5 05/10] arm64: dts: apple: t7001: Add PMGR node
In-Reply-To: <20241203050640.109378-1-towinchenmi@gmail.com>
References: <20241203050640.109378-1-towinchenmi@gmail.com>
Message-ID: <20241203050640.109378-6-towinchenmi@gmail.com>

Add the PMGR node and all known power state subnodes. Since there are
a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t7001-air2.dtsi |   1 +
 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi | 650 ++++++++++++++++++++++
 arch/arm64/boot/dts/apple/t7001.dtsi      |  13 +
 3 files changed, 664 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t7001-air2.dtsi b/arch/arm64/boot/dts/apple/t7001-air2.dtsi
index 19fabd425c52..e4ec8c1977de 100644
--- a/arch/arm64/boot/dts/apple/t7001-air2.dtsi
+++ b/arch/arm64/boot/dts/apple/t7001-air2.dtsi
@@ -20,6 +20,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0 &ps_dp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t7001-pmgr.dtsi b/arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
new file mode 100644
index 000000000000..7321cfdcd189
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
@@ -0,0 +1,650 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T7001 "A8X" SoC
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 20000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 20008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu2: power-controller at 20010 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu2";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 20040 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_p: power-controller at 201f8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+	};
+
+	ps_lio: power-controller at 20100 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "lio";
+		apple,always-on; /* Core device */
+	};
+
+	ps_iomux: power-controller at 20108 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_aic: power-controller at 20110 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_debug: power-controller at 20118 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_dwi: power-controller at 20120 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 20128 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_mca0: power-controller at 20130 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 20138 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 20140 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 20148 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 20150 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 20158 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 20160 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 20168 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 20170 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 20178 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 20180 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 20188 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 20190 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 20198 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 201a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 201a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 201b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 201b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 201c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 201c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 201d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 201d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 201e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 201e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 201f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb: power-controller at 20248 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 20250 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 20258 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 20268 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 20278 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_disp_busmux: power-controller at 202a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp_busmux";
+	};
+
+	ps_disp1_busmux: power-controller at 202c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1_busmux";
+	};
+
+	ps_media: power-controller at 202d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 202d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+	};
+
+	ps_msr: power-controller at 202e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 202e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 202b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_disp1: power-controller at 202c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp1_busmux>;
+	};
+
+	ps_pcie_ref: power-controller at 20220 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_hsic0_phy: power-controller at 20200 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_hsic1_phy: power-controller at 20208 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_ispsens0: power-controller at 20210 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 20218 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_mcc: power-controller at 20230 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_mcu: power-controller at 20238 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcu";
+		apple,always-on; /* Core device */
+	};
+
+	ps_amp: power-controller at 20240 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "amp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb2host0_ohci: power-controller at 20260 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 20288 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 20290 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 20298 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_cp: power-controller at 202a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dp: power-controller at 202b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_vdec: power-controller at 202f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans: power-controller at 20318 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans";
+	};
+
+	ps_venc: power-controller at 20300 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 20308 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 20310 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_gfx: power-controller at 20320 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 20400 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_venc_pipe: power-controller at 21000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 21008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me1: power-controller at 21010 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+		power-domains = <&ps_venc>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t7001.dtsi b/arch/arm64/boot/dts/apple/t7001.dtsi
index a76e034c85e3..c471f57cca0e 100644
--- a/arch/arm64/boot/dts/apple/t7001.dtsi
+++ b/arch/arm64/boot/dts/apple/t7001.dtsi
@@ -72,9 +72,18 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t7000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x24000>;
+		};
+
 		wdt: watchdog at 20e027000 {
 			compatible = "apple,t7000-wdt", "apple,wdt";
 			reg = <0x2 0x0e027000 0x0 0x1000>;
@@ -88,11 +97,13 @@ aic: interrupt-controller at 20e100000 {
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl: pinctrl at 20e300000 {
 			compatible = "apple,t7000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0e300000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -121,3 +132,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t7001-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:10:28 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:10:28 +0800
Subject: [PATCH v2 2/3] arm64: dts: apple: Add T2 devices
In-Reply-To: <20241203051147.110980-1-towinchenmi@gmail.com>
References: <20241203051147.110980-1-towinchenmi@gmail.com>
Message-ID: <20241203051147.110980-3-towinchenmi@gmail.com>

Add DTS files for the T2 SoC and the following devices based on it:

- Apple T2 MacBookPro15,2 (j132)
- Apple T2 iMacPro1,1 (j137)
- Apple T2 MacBookAir8,2 (j140a)
- Apple T2 MacBookAir8,1 (j140k)
- Apple T2 MacBookPro16,1 (j152f)
- Apple T2 MacPro7,1 (j160)
- Apple T2 Macmini8,1 (j174)
- Apple T2 iMac20,1 (j185)
- Apple T2 iMac20,2 (j185f)
- Apple T2 MacBookPro15,4 (j213)
- Apple T2 MacBookPro16,2 (j214k)
- Apple T2 MacBookPro16,4 (j215)
- Apple T2 MacBookPro16,3 (j223)
- Apple T2 MacBookAir9,1 (j230k)
- Apple T2 MacBookPro15,1 (j680)
- Apple T2 MacBookPro15,3 (j780)

The Apple T2 is an A10-based security chip found on some Intel Macs
from 2017 onwards. On models with a touchbar, the touchbar's
display is wired to it. These devices have no offical names, the
naming scheme is from libirecovery.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/Makefile            |  16 ++
 arch/arm64/boot/dts/apple/t8012-j132.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j137.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j140a.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j140k.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j152f.dts     |  15 ++
 arch/arm64/boot/dts/apple/t8012-j160.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j174.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j185.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j185f.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j213.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j214k.dts     |  15 ++
 arch/arm64/boot/dts/apple/t8012-j215.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j223.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j230k.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j680.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j780.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi     |  44 +++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |  19 ++
 arch/arm64/boot/dts/apple/t8012.dtsi          | 176 ++++++++++++++++++
 20 files changed, 486 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j132.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j137.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140a.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j152f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j160.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j174.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j213.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j214k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j215.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j223.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j230k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j680.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j780.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012.dtsi

diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
index ab6ebb53218a..4f337bff36cd 100644
--- a/arch/arm64/boot/dts/apple/Makefile
+++ b/arch/arm64/boot/dts/apple/Makefile
@@ -46,6 +46,22 @@ dtb-$(CONFIG_ARCH_APPLE) += t8011-j120.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8011-j121.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8011-j207.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8011-j208.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j132.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j137.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j140a.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j140k.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j152f.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j160.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j174.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j185.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j185f.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j213.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j215.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j223.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j230k.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j214k.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j680.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j780.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8015-d201.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8015-d20.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8015-d211.dtb
diff --git a/arch/arm64/boot/dts/apple/t8012-j132.dts b/arch/arm64/boot/dts/apple/t8012-j132.dts
new file mode 100644
index 000000000000..778a69be18dd
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j132.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,2 (j132), J132, iBridge2,4
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,2 (j132)";
+	compatible = "apple,j132", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j137.dts b/arch/arm64/boot/dts/apple/t8012-j137.dts
new file mode 100644
index 000000000000..dbde1ad7ce14
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j137.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 iMacPro1,1 (j137), J137, iBridge2,1
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 iMacPro1,1 (j137)";
+	compatible = "apple,j137", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j140a.dts b/arch/arm64/boot/dts/apple/t8012-j140a.dts
new file mode 100644
index 000000000000..5df1ff74d2df
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j140a.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookAir8,2 (j140a), J140a, iBridge2,12
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookAir8,2 (j140a)";
+	compatible = "apple,j140a", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j140k.dts b/arch/arm64/boot/dts/apple/t8012-j140k.dts
new file mode 100644
index 000000000000..a0ef1585e5c2
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j140k.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookAir8,1 (j140k), J140k, iBridge2,8
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookAir8,1 (j140k)";
+	compatible = "apple,j140k", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j152f.dts b/arch/arm64/boot/dts/apple/t8012-j152f.dts
new file mode 100644
index 000000000000..261416eaf97e
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j152f.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,1 (j152f), J152f, iBridge2,14
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,1 (j152f)";
+	compatible = "apple,j152f", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j160.dts b/arch/arm64/boot/dts/apple/t8012-j160.dts
new file mode 100644
index 000000000000..fbcc0604f4a0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j160.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacPro7,1 (j160), J160, iBridge2,6
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacPro7,1 (j160)";
+	compatible = "apple,j160", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j174.dts b/arch/arm64/boot/dts/apple/t8012-j174.dts
new file mode 100644
index 000000000000..d11c70f84a71
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j174.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 Macmini8,1 (j174), J174, iBridge2,5
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 Macmini8,1 (j174)";
+	compatible = "apple,j174", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j185.dts b/arch/arm64/boot/dts/apple/t8012-j185.dts
new file mode 100644
index 000000000000..33492f5db46d
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j185.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 iMac20,1 (j185), J185, iBridge2,19
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 iMac20,1 (j185)";
+	compatible = "apple,j185", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j185f.dts b/arch/arm64/boot/dts/apple/t8012-j185f.dts
new file mode 100644
index 000000000000..3a4abdd8f7d7
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j185f.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 iMac20,2 (j185f), J185f, iBridge2,20
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 iMac20,2 (j185f)";
+	compatible = "apple,j185f", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j213.dts b/arch/arm64/boot/dts/apple/t8012-j213.dts
new file mode 100644
index 000000000000..8270812b9a68
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j213.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,4 (j213), J213, iBridge2,10
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,4 (j213)";
+	compatible = "apple,j213", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j214k.dts b/arch/arm64/boot/dts/apple/t8012-j214k.dts
new file mode 100644
index 000000000000..5b8e42512060
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j214k.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,2 (j214k), J214k, iBridge2,16
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,2 (j214k)";
+	compatible = "apple,j214k", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j215.dts b/arch/arm64/boot/dts/apple/t8012-j215.dts
new file mode 100644
index 000000000000..ad574fbf7f92
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j215.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,4 (j215), J215, iBridge2,22
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,4 (j215)";
+	compatible = "apple,j215", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j223.dts b/arch/arm64/boot/dts/apple/t8012-j223.dts
new file mode 100644
index 000000000000..de75d775aac5
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j223.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,3 (j223), J223, iBridge2,21
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,3 (j223)";
+	compatible = "apple,j223", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j230k.dts b/arch/arm64/boot/dts/apple/t8012-j230k.dts
new file mode 100644
index 000000000000..4b19bc70ab0f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j230k.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookAir9,1 (j230k), J230k, iBridge2,15
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookAir9,1 (j230k)";
+	compatible = "apple,j230k", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j680.dts b/arch/arm64/boot/dts/apple/t8012-j680.dts
new file mode 100644
index 000000000000..aa5a72e07d3f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j680.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,1 (j680), J680, iBridge2,3
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,1 (j680)";
+	compatible = "apple,j680", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j780.dts b/arch/arm64/boot/dts/apple/t8012-j780.dts
new file mode 100644
index 000000000000..9cee891cb16d
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j780.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,3 (j780), J780, iBridge2,7
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,3 (j780)";
+	compatible = "apple,j780", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
new file mode 100644
index 000000000000..36e82633bc52
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Common Device Tree for all T2 devices
+ *
+ * target-type: J132, J137, J140a, J140k, J152f, J160, J174, J185, J185f
+ * J213, J214k, J215, J223, J230k, J680, J780
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include "t8012.dtsi"
+
+/ {
+	chassis-type = "embedded";
+
+	aliases {
+		serial0 = &serial0;
+	};
+
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		stdout-path = "serial0";
+	};
+
+	memory at 800000000 {
+		device_type = "memory";
+		reg = <0x8 0 0 0>; /* To be filled by loader */
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* To be filled by loader */
+	};
+};
+
+&serial0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
new file mode 100644
index 000000000000..f4a8b12437f0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Common Device Tree for T2 devices with a Touch Bar
+ *
+ * target-type: J152f, J213, J214k, J215, J223, J680, J780
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/ {
+	chosen {
+		framebuffer0: framebuffer at 0 {
+			compatible = "apple,simple-framebuffer", "simple-framebuffer";
+			reg = <0 0 0 0>; /* To be filled by loader */
+			/* Format properties will be added by loader */
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8012.dtsi b/arch/arm64/boot/dts/apple/t8012.dtsi
new file mode 100644
index 000000000000..45d24ca091b0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012.dtsi
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T8012 "T2" SoC
+ *
+ * Other names: H9M, "Gibraltar"
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/apple.h>
+
+/ {
+	interrupt-parent = <&aic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clkref: clock-ref {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "clkref";
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 10000 {
+			compatible = "apple,hurricane-zephyr";
+			reg = <0x0 0x10000>;
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+
+		cpu1: cpu at 10001 {
+			compatible = "apple,hurricane-zephyr";
+			reg = <0x0 0x10001>;
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		nonposted-mmio;
+		ranges;
+
+		serial0: serial at 20a600000 {
+			compatible = "apple,s5l-uart";
+			reg = <0x2 0x0a600000 0x0 0x4000>;
+			reg-io-width = <4>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 271 IRQ_TYPE_LEVEL_HIGH>;
+			/* Use the bootloader-enabled clocks for now. */
+			clocks = <&clkref>, <&clkref>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		aic: interrupt-controller at 20e100000 {
+			compatible = "apple,t8010-aic", "apple,aic";
+			reg = <0x2 0x0e100000 0x0 0x100000>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+		};
+
+		pinctrl_ap: pinctrl at 20f100000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x0f100000 0x0 0x100000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_ap 0 0 221>;
+			apple,npins = <221>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 51 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_aop: pinctrl at 2100f0000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x0100f0000 0x0 0x10000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_aop 0 0 41>;
+			apple,npins = <41>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 131 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 132 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 133 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 134 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 135 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 136 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 137 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_nub: pinctrl at 2111f0000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x111f0000 0x0 0x1000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_nub 0 0 19>;
+			apple,npins = <19>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 164 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 165 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 166 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		wdt: watchdog at 2112b0000 {
+			compatible = "apple,t8010-wdt", "apple,wdt";
+			reg = <0x2 0x112b0000 0x0 0x4000>;
+			clocks = <&clkref>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 168 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_smc: pinctrl at 212024000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x12024000 0x0 0x1000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_smc 0 0 81>;
+			apple,npins = <81>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 195 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 196 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 197 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 198 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 199 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 200 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 201 IRQ_TYPE_LEVEL_HIGH>;
+			/*
+			 * SMC is not yet supported and accessing this pinctrl while SMC is
+			 * suspended results in a hang.
+			 */
+			status = "disabled";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&aic>;
+		interrupt-names = "phys", "virt";
+		/* Note that T2 doesn't actually have a hypervisor (EL2 is not implemented). */
+		interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>,
+			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
-- 
2.47.1



From towinchenmi at gmail.com  Mon Dec  2 21:10:29 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue,  3 Dec 2024 13:10:29 +0800
Subject: [PATCH v2 3/3] arm64: dts: apple: t8012: Add PMGR nodes
In-Reply-To: <20241203051147.110980-1-towinchenmi@gmail.com>
References: <20241203051147.110980-1-towinchenmi@gmail.com>
Message-ID: <20241203051147.110980-4-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

On models with only 1 GB of memory, only two memory channels are used,
and on models with 2 GB of memory, four memory channels are used. The
"apple,always-on" property of the extra memory channel power domains
(ps_dcs2, ps_dcs3) will be removed by loader on models with 1 GB of
memory.

The amount of memory depends on the storage configuration of the Mac.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi     | 837 ++++++++++++++++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8012.dtsi          |  22 +
 3 files changed, 860 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8012-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8012-pmgr.dtsi
new file mode 100644
index 000000000000..35a462edd4af
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-pmgr.dtsi
@@ -0,0 +1,837 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8012 "T2" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80158 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80160 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_iomux: power-controller at 80150 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_gpio: power-controller at 80110 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pcie_down_ref: power-controller at 80138 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_down_ref";
+	};
+
+	ps_pcie_stg0_ref: power-controller at 80140 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg0_ref";
+	};
+
+	ps_pcie_stg1_ref: power-controller at 80148 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg1_ref";
+	};
+
+	ps_mca0: power-controller at 80170 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80178 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80180 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80188 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80190 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca5: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80168 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_isp_sens0: power-controller at 80120 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80128 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_isp_sens2: power-controller at 80130 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens2";
+	};
+
+	ps_pms: power-controller at 80118 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_i2c4: power-controller at 801c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c5: power-controller at 801d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c6: power-controller at 801d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_usb: power-controller at 80268 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80270 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80278 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80288 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp_sys: power-controller at 802d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 802e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp0_be: power-controller at 802b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_uart0: power-controller at 80200 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 80208 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 80210 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 80218 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80220 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_dpa: power-controller at 80228 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80230 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80240 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80248 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80250 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80258 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		/* Not used on some devicecs, to be disabled by loader */
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80260 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		/* Not used on some devicecs, to be disabled by loader */
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80280 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 80290 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 80298 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_pmp: power-controller at 802f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 802f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_pcie_up_af: power-controller at 80320 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_up_af";
+		power-domains = <&ps_iomux>;
+	};
+
+	ps_pcie_up: power-controller at 80328 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_up";
+		power-domains = <&ps_pcie_up_af>;
+	};
+
+	ps_venc_sys: power-controller at 80300 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans2: power-controller at 80308 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans2";
+		power-domains = <&ps_iomux>;
+	};
+
+	ps_pcie_down: power-controller at 80310 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_down";
+		power-domains = <&ps_iomux>;
+	};
+
+	ps_pcie_down_aux: power-controller at 80318 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_down_aux";
+	};
+
+	ps_pcie_up_aux: power-controller at 80330 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_up_aux";
+		power-domains = <&ps_pcie_up>;
+	};
+
+	ps_pcie_stg0: power-controller at 80338 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg0";
+		power-domains = <&ps_ans2>;
+	};
+
+	ps_pcie_stg0_aux: power-controller at 80340 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80340 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg0_aux";
+	};
+
+	ps_pcie_stg1: power-controller at 80348 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80348 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg1";
+		power-domains = <&ps_ans2>;
+	};
+
+	ps_pcie_stg1_aux: power-controller at 80350 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80350 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg1_aux";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_pipe4: power-controller at 88000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+	};
+
+	ps_venc_pipe5: power-controller at 88008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+	};
+
+	ps_venc_me0: power-controller at 88010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_spmi: power-controller at 80058 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spmi";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_nub_aon: power-controller at 80060 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80060 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "nub_aon";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_smc_fabric: power-controller at 80030 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_fabric";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_smc_aon: power-controller at 80088 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80088 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_aon";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_debug: power-controller at 80050 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_nub_sram: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "nub_sram";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_nub_fabric: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "nub_fabric";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_smc_cpu: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_cpu";
+		power-domains = <&ps_smc_fabric &ps_smc_aon>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
index f4a8b12437f0..fc4a80d0c787 100644
--- a/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
+++ b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
@@ -12,6 +12,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t8012.dtsi b/arch/arm64/boot/dts/apple/t8012.dtsi
index 45d24ca091b0..907ba127be79 100644
--- a/arch/arm64/boot/dts/apple/t8012.dtsi
+++ b/arch/arm64/boot/dts/apple/t8012.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a600000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,t8010-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -130,6 +141,14 @@ pinctrl_nub: pinctrl at 2111f0000 {
 				     <AIC_IRQ 166 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 211200000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x11200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2112b0000 {
 			compatible = "apple,t8010-wdt", "apple,wdt";
 			reg = <0x2 0x112b0000 0x0 0x4000>;
@@ -141,6 +160,7 @@ wdt: watchdog at 2112b0000 {
 		pinctrl_smc: pinctrl at 212024000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x12024000 0x0 0x1000>;
+			power-domains = <&ps_smc_cpu>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -174,3 +194,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8012-pmgr.dtsi"
-- 
2.47.1



From lkp at intel.com  Mon Dec  2 22:03:52 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 3 Dec 2024 14:03:52 +0800
Subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module
 loading
In-Reply-To: <20241203000156.72451-2-jeremy.linton@arm.com>
References: <20241203000156.72451-2-jeremy.linton@arm.com>
Message-ID: <202412031348.bp5i3ws2-lkp@intel.com>

Hi Jeremy,

kernel test robot noticed the following build warnings:

[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on linus/master v6.13-rc1 next-20241128]
[cannot apply to kvmarm/next soc/for-next arm/for-next arm/fixes]
[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/Jeremy-Linton/arm64-rsi-Add-automatic-arm-cca-guest-module-loading/20241203-080347
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
patch link:    https://lore.kernel.org/r/20241203000156.72451-2-jeremy.linton%40arm.com
patch subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module loading
config: arm64-randconfig-004-20241203 (https://download.01.org/0day-ci/archive/20241203/202412031348.bp5i3ws2-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241203/202412031348.bp5i3ws2-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/202412031348.bp5i3ws2-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/virt/coco/arm-cca-guest/arm-cca-guest.c:224:21: warning: attribute declaration must precede definition [-Wignored-attributes]
     224 | static const struct __maybe_unused platform_device_id arm_cca_match[] = {
         |                     ^
   include/linux/compiler_attributes.h:356:56: note: expanded from macro '__maybe_unused'
     356 | #define __maybe_unused                  __attribute__((__unused__))
         |                                                        ^
   include/linux/mod_devicetable.h:607:8: note: previous definition is here
     607 | struct platform_device_id {
         |        ^
>> drivers/virt/coco/arm-cca-guest/arm-cca-guest.c:224:55: warning: unused variable 'arm_cca_match' [-Wunused-const-variable]
     224 | static const struct __maybe_unused platform_device_id arm_cca_match[] = {
         |                                                       ^~~~~~~~~~~~~
   2 warnings generated.


vim +224 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c

   222	
   223	/* modalias, so userspace can autoload this module when RSI is available */
 > 224	static const struct __maybe_unused platform_device_id arm_cca_match[] = {
   225		{ RSI_PDEV_NAME, 0},
   226		{ }
   227	};
   228	

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


From linux at roeck-us.net  Mon Dec  2 22:05:54 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 2 Dec 2024 22:05:54 -0800
Subject: [PATCH] hwmon: raspberrypi: add PM suspend/resume support
In-Reply-To: <20241202115832.33628-1-wahrenst@gmx.net>
References: <20241202115832.33628-1-wahrenst@gmx.net>
Message-ID: <bea80f92-11b6-4373-bb90-48c5a22a30a9@roeck-us.net>

On Mon, Dec 02, 2024 at 12:58:32PM +0100, Stefan Wahren wrote:
> Add suspend/resume handler in order to stop firmware polling
> during s2idle. This was just waking-up the system without a real
> benefit.
> 
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>

Applied.

Thanks,
Guenter


From jan.petrous at oss.nxp.com  Mon Dec  2 22:09:23 2024
From: jan.petrous at oss.nxp.com (Jan Petrous)
Date: Tue, 3 Dec 2024 07:09:23 +0100
Subject: [PATCH net-next v7 01/15] net: driver: stmmac: Fix CSR divider
 comment
In-Reply-To: <Z04veAM7wBJCLkhu@shell.armlinux.org.uk>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
 <20241202-upstream_s32cc_gmac-v7-1-bc3e1f9f656e@oss.nxp.com>
 <Z04veAM7wBJCLkhu@shell.armlinux.org.uk>
Message-ID: <Z06gk37G65vTJ/3z@lsv051416.swis.nl-cdc01.nxp.com>

On Mon, Dec 02, 2024 at 10:06:48PM +0000, Russell King (Oracle) wrote:
> Hi,
> 
> No need for "driver:" in the subject line.
> 

Will fix it in v8, thanks.
/Jan


From jan.petrous at oss.nxp.com  Mon Dec  2 22:10:08 2024
From: jan.petrous at oss.nxp.com (Jan Petrous)
Date: Tue, 3 Dec 2024 07:10:08 +0100
Subject: [PATCH net-next v7 02/15] net: driver: stmmac: Extend CSR calc
 support
In-Reply-To: <Z04voJN9uj1Vefef@shell.armlinux.org.uk>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
 <20241202-upstream_s32cc_gmac-v7-2-bc3e1f9f656e@oss.nxp.com>
 <Z04voJN9uj1Vefef@shell.armlinux.org.uk>
Message-ID: <Z06gwINwnA7Xcnd8@lsv051416.swis.nl-cdc01.nxp.com>

On Mon, Dec 02, 2024 at 10:07:28PM +0000, Russell King (Oracle) wrote:
> Hi,
> 
> As per patch 1, no need for "driver:" in the subject line.
> 

Will fix it in v8, thanks.
/Jan


From lkp at intel.com  Mon Dec  2 22:16:29 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 3 Dec 2024 14:16:29 +0800
Subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module
 loading
In-Reply-To: <20241203000156.72451-2-jeremy.linton@arm.com>
References: <20241203000156.72451-2-jeremy.linton@arm.com>
Message-ID: <202412031328.ybzEAJ4U-lkp@intel.com>

Hi Jeremy,

kernel test robot noticed the following build warnings:

[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on linus/master v6.13-rc1 next-20241128]
[cannot apply to kvmarm/next soc/for-next arm/for-next arm/fixes]
[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/Jeremy-Linton/arm64-rsi-Add-automatic-arm-cca-guest-module-loading/20241203-080347
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
patch link:    https://lore.kernel.org/r/20241203000156.72451-2-jeremy.linton%40arm.com
patch subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module loading
config: arm64-randconfig-001-20241203 (https://download.01.org/0day-ci/archive/20241203/202412031328.ybzEAJ4U-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241203/202412031328.ybzEAJ4U-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/202412031328.ybzEAJ4U-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/virt/coco/arm-cca-guest/arm-cca-guest.c:224:55: warning: 'arm_cca_match' defined but not used [-Wunused-const-variable=]
     224 | static const struct __maybe_unused platform_device_id arm_cca_match[] = {
         |                                                       ^~~~~~~~~~~~~


vim +/arm_cca_match +224 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c

   222	
   223	/* modalias, so userspace can autoload this module when RSI is available */
 > 224	static const struct __maybe_unused platform_device_id arm_cca_match[] = {
   225		{ RSI_PDEV_NAME, 0},
   226		{ }
   227	};
   228	

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


From jan.petrous at oss.nxp.com  Mon Dec  2 22:33:14 2024
From: jan.petrous at oss.nxp.com (Jan Petrous)
Date: Tue, 3 Dec 2024 07:33:14 +0100
Subject: [PATCH net-next v7 14/15] net: stmmac: dwmac-s32: add basic NXP
 S32G/S32R glue driver
In-Reply-To: <b9ad385b-7702-4c71-b14f-64f2714a35a4@lunn.ch>
References: <20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e@oss.nxp.com>
 <20241202-upstream_s32cc_gmac-v7-14-bc3e1f9f656e@oss.nxp.com>
 <b9ad385b-7702-4c71-b14f-64f2714a35a4@lunn.ch>
Message-ID: <Z06mKpcvBO23RSx+@lsv051416.swis.nl-cdc01.nxp.com>

On Tue, Dec 03, 2024 at 12:43:58AM +0100, Andrew Lunn wrote:
> > +static int s32_gmac_init(struct platform_device *pdev, void *priv)
> > +{
> > +	struct s32_priv_data *gmac = priv;
> > +	int ret;
> > +
> > +	ret = clk_set_rate(gmac->tx_clk, GMAC_TX_RATE_125M);
> > +	if (!ret)
> > +		ret = clk_prepare_enable(gmac->tx_clk);
> > +
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Can't set tx clock\n");
> > +		return ret;
> > +	}
> 
> The ordering is a bit odd here. Normally you would test each operation
> individually for errors. So:
> 
> 	ret = clk_set_rate(gmac->tx_clk, GMAC_TX_RATE_125M);
> 	if (ret) {
> 		dev_err(&pdev->dev, "Can't set tx clock\n");
> 		return ret;
> 	}
> 	ret = clk_prepare_enable(gmac->tx_clk);
> 	if (ret) {
> 		dev_err(&pdev->dev, "Can't enable tx clock\n");
> 		return ret;
> 	}
> 

Thanks for it. The ordering is incorrect, agree. I will fix it in v8.

> 
> > +
> > +	ret = clk_prepare_enable(gmac->rx_clk);
> > +	if (ret) {
> > +		clk_disable_unprepare(gmac->tx_clk);
> > +		dev_err(&pdev->dev, "Can't set rx clock\n");
> > +		return ret;
> > +	}
> 
> Is there no need to set the TX clock rate?
> 

Do you mean RX clock, right? Yes, I'll add it in v8 too.

BR.
/Jan


From peng.fan at nxp.com  Mon Dec  2 22:47:22 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Tue, 3 Dec 2024 06:47:22 +0000
Subject: [PATCH v2 0/4] nvmem: imx-ocotp-ele: fix reading from ELE OCOTP
In-Reply-To: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
References: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
Message-ID: <PAXPR04MB845905D963FC162FD46D4F2488362@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 0/4] nvmem: imx-ocotp-ele: fix reading from ELE
> OCOTP
> 
> Commits b2ab0edaf484 ("arm64: dts: imx93: add nvmem property for
> fec1") and 0d4fbaffbdca ("arm64: dts: imx93: add nvmem property for
> eqos") introduced NVMEM cell bindings for reading MAC addresses
> from the ELE OCOTP. This doesn't work as expected due to bugs in the
> driver:
> 
> - imx_ocotp_reg_read() interprets the incoming offset as 32bit word
>   offset, but it really is in bytes which means the driver reads bogus
>   values whenever the offset is non zero
> - imx_ocotp_reg_read() reads wrong results when the offset is not 32bit
>   word aligned
> - MAC addresses are stored in reverse byte order in the ELE OCOTP, we
>   have to swap the order before passing them to the upper layer
> 
> This likely went through unnoticed because the bootloader normally
> adds the MAC addresses to the ethernet nodes and in this case they are
> preferred over the NVMEM addresses.
> 
> This series fixes these issues.
> 
> Sascha
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>

For the patchset:
Reviewed-by: Peng Fan <peng.fan at nxp.com>

Thanks,
Peng.


From andre.draszik at linaro.org  Mon Dec  2 22:47:41 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 06:47:41 +0000
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
Message-ID: <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>

Hi Thomas,

Thanks for looking into this!

> From: Thomas Antoine <t.antoine at uclouvain.be>
> 
> The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
> except for the non-volatile memory slave address which is not available.

It is not fully compatible, and it also has a lot more registers.

For example, the voltage now is not in register 0xda as this driver assumes.
With these changes, POWER_SUPPLY_PROP_VOLTAGE_NOW just reads as 0. 0xda
doesn't exist in max77759

I haven't compared in depth yet, though.

> No slave is available at address 0xb of the i2c bus, which is coherent
> with the following driver from google: line 5836 disables non-volatile
> memory for m5 gauge.
> 
> Link:
> https://android.googlesource.com/kernel/google-modules/bms/+/1a68c36bef474573cc8629cc1d121eb6a81ab68c/max1720x_battery.c
> 
> Add support for the max77759 by allowing to use the non-volatile
> memory or not based on the chip. Value for RSense comes from the following
> stock devicetree:
> 
> Link:
> https://android.googlesource.com/kernel/devices/google/gs101/+/33eca36d43da6c2b6a546806eb3e7411bbe6d60d/dts/gs101-raviole-battery.dtsi
> 
> Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
> ---
> ?drivers/power/supply/max1720x_battery.c | 71 +++++++++++++++++++++++++++-
> -----
> ?1 file changed, 59 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/power/supply/max1720x_battery.c
> b/drivers/power/supply/max1720x_battery.c
> index
> 33105419e2427bb37963bda9948b647c239f8faa..faf336938dd4306dd2ceeb0a84b90ca8
> 0ad41a9f 100644
> --- a/drivers/power/supply/max1720x_battery.c
> +++ b/drivers/power/supply/max1720x_battery.c
> @@ -13,6 +13,7 @@
> ?#include <linux/nvmem-provider.h>
> ?#include <linux/power_supply.h>
> ?#include <linux/regmap.h>
> +#include <linux/types.h>

Please keep file names in alphabetical order.

> ?
> ?#include <linux/unaligned.h>
> ?
> @@ -39,6 +40,7 @@
> ?#define MAX172XX_DEV_NAME_TYPE_MASK	GENMASK(3, 0)
> ?#define MAX172XX_DEV_NAME_TYPE_MAX17201	BIT(0)
> ?#define MAX172XX_DEV_NAME_TYPE_MAX17205	(BIT(0) | BIT(2))
> +#define MAX172XX_DEV_NAME_TYPE_MAX77759	0
> ?#define MAX172XX_QR_TABLE10		0x22
> ?#define MAX172XX_BATT			0xDA	/* Battery voltage */
> ?#define MAX172XX_ATAVCAP		0xDF
> @@ -46,6 +48,7 @@
> ?static const char *const max1720x_manufacturer = "Maxim Integrated";
> ?static const char *const max17201_model = "MAX17201";
> ?static const char *const max17205_model = "MAX17205";
> +static const char *const max77759_model = "MAX77759";
> ?
> ?struct max1720x_device_info {
> ?	struct regmap *regmap;
> @@ -54,6 +57,21 @@ struct max1720x_device_info {
> ?	int rsense;
> ?};
> ?
> +struct chip_data {
> +	u16 default_nrsense; /* in regs in 10^-5 */
> +	u8 has_nvmem;
> +};
> +
> +static const struct chip_data max1720x_data? = {
> +	.default_nrsense = 1000,
> +	.has_nvmem = 1,
> +};
> +
> +static const struct chip_data max77759_data = {
> +	.default_nrsense = 500,
> +	.has_nvmem = 0,
> +};

This should be made a required devicetree property instead, at least for
max77759, as it's completely board dependent, 'shunt-resistor-micro-ohms'
is widely used.

I also don't think there should be a default. The driver should just fail
to probe if not specified in DT (for max77759).

> +
> ?/*
> ? * Model Gauge M5 Algorithm output register
> ? * Volatile data (must not be cached)
> @@ -369,6 +387,8 @@ static int max1720x_battery_get_property(struct
> power_supply *psy,
> ?			val->strval = max17201_model;
> ?		else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17205)
> ?			val->strval = max17205_model;
> +		else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX77759)
> +			val->strval = max77759_model;
> ?		else

This is a 16 bit register, and while yes, MAX172XX_DEV_NAME_TYPE_MASK only
cares about the bottom 4 bits, the register is described as 'Firmware
Version Information'.

But maybe it's ok to do it like that, at least for now.

> ?			return -ENODEV;
> ?		break;
> @@ -416,7 +436,6 @@ static int max1720x_probe_nvmem(struct i2c_client
> *client,
> ?		.priv = info,
> ?	};
> ?	struct nvmem_device *nvmem;
> -	unsigned int val;
> ?	int ret;
> ?
> ?	info->ancillary = i2c_new_ancillary_device(client, "nvmem", 0xb);
> @@ -438,6 +457,27 @@ static int max1720x_probe_nvmem(struct i2c_client
> *client,
> ?		return PTR_ERR(info->regmap_nv);
> ?	}
> ?
> +	nvmem = devm_nvmem_register(dev, &nvmem_config);
> +	if (IS_ERR(nvmem)) {
> +		dev_err(dev, "Could not register nvmem!");
> +		return PTR_ERR(nvmem);
> +	}
> +
> +	return 0;
> +}
> +
> +static int max1720x_get_rsense(struct device *dev,
> +					 struct max1720x_device_info
> *info,
> +					 const struct chip_data *data)
> +{
> +	unsigned int val;
> +	int ret;
> +
> +	if (!data->has_nvmem) {
> +		info->rsense = data->default_nrsense;
> +		return 0;
> +	}
> +
> ?	ret = regmap_read(info->regmap_nv, MAX1720X_NRSENSE, &val);
> ?	if (ret < 0) {
> ?		dev_err(dev, "Failed to read sense resistor value\n");
> @@ -446,14 +486,9 @@ static int max1720x_probe_nvmem(struct i2c_client
> *client,
> ?
> ?	info->rsense = val;
> ?	if (!info->rsense) {
> -		dev_warn(dev, "RSense not calibrated, set 10 mOhms!\n");
> -		info->rsense = 1000; /* in regs in 10^-5 */
> -	}
> -
> -	nvmem = devm_nvmem_register(dev, &nvmem_config);
> -	if (IS_ERR(nvmem)) {
> -		dev_err(dev, "Could not register nvmem!");
> -		return PTR_ERR(nvmem);
> +		dev_warn(dev, "RSense not calibrated, set %d mOhms!\n",
> +						data-
> >default_nrsense/100);
> +		info->rsense = data->default_nrsense;
> ?	}
> ?
> ?	return 0;
> @@ -474,6 +509,7 @@ static int max1720x_probe(struct i2c_client *client)
> ?	struct device *dev = &client->dev;
> ?	struct max1720x_device_info *info;
> ?	struct power_supply *bat;
> +	const struct chip_data *data;
> ?	int ret;
> ?
> ?	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
> @@ -488,9 +524,19 @@ static int max1720x_probe(struct i2c_client *client)
> ?		return dev_err_probe(dev, PTR_ERR(info->regmap),
> ?				???? "regmap initialization failed\n");
> ?
> -	ret = max1720x_probe_nvmem(client, info);
> +	data = device_get_match_data(dev);
> +	if (!data)
> +		return dev_err_probe(dev, ret, "Failed to get chip
> data\n");
> +
> +	if (data->has_nvmem) {
> +		ret = max1720x_probe_nvmem(client, info);
> +		if (ret)
> +			return dev_err_probe(dev, ret, "Failed to probe
> nvmem\n");
> +	}
> +
> +	ret = max1720x_get_rsense(dev, info, data);
> ?	if (ret)
> -		return dev_err_probe(dev, ret, "Failed to probe
> nvmem\n");
> +		return dev_err_probe(dev, ret, "Failed to get RSense");
> ?
> ?	bat = devm_power_supply_register(dev, &max1720x_bat_desc,
> &psy_cfg);
> ?	if (IS_ERR(bat))
> @@ -501,7 +547,8 @@ static int max1720x_probe(struct i2c_client *client)
> ?}
> ?
> ?static const struct of_device_id max1720x_of_match[] = {
> -	{ .compatible = "maxim,max17201" },
> +	{ .compatible = "maxim,max17201", .data = (void *) &max1720x_data
> },
> +	{ .compatible = "maxim,max77759-fg", .data = (void *)
> &max77759_data},

missing space before }

Cheers,
Andre'

> ?	{}
> ?};
> ?MODULE_DEVICE_TABLE(of, max1720x_of_match);
> 



From andre.draszik at linaro.org  Mon Dec  2 22:57:39 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 06:57:39 +0000
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
Message-ID: <fe254a002000f2bbfbe51d074cf28f7427a27f9a.camel@linaro.org>

On Mon, 2024-12-02 at 14:07 +0100, Thomas Antoine via B4 Relay wrote:
> From: Thomas Antoine <t.antoine at uclouvain.be>
> 
> As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
> make it non-obligatory. Except for this, the max77759 seems to behave the
> same as the max1720x.

It also needs an interrupt line, and the previously mentioned shunt-
resistor-micro-ohms, and probably a power supply.

Cheers,
Andre'



From andre.draszik at linaro.org  Mon Dec  2 23:12:47 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 07:12:47 +0000
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
Message-ID: <e23721ebd766f410103ddfb8705f3d7d6e5ae3e9.camel@linaro.org>

On Mon, 2024-12-02 at 14:07 +0100, Thomas Antoine via B4 Relay wrote:
> From: Thomas Antoine <t.antoine at uclouvain.be>
> 
> As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
> make it non-obligatory. Except for this, the max77759 seems to behave the
> same as the max1720x.

What about the battery characterization tables? Aren't they needed for
correct reporting?

Cheers,
Andre'



From andre.draszik at linaro.org  Mon Dec  2 23:23:12 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 07:23:12 +0000
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
	 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
Message-ID: <8f585460a1bc52f78a6d0867aed87398bde30152.camel@linaro.org>

On Tue, 2024-12-03 at 06:47 +0000, Andr? Draszik wrote:
> Hi Thomas,
> 
> Thanks for looking into this!
> 
> > From: Thomas Antoine <t.antoine at uclouvain.be>
> > 
> > The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
> > except for the non-volatile memory slave address which is not available.
> 
> It is not fully compatible, and it also has a lot more registers.
> 
> For example, the voltage now is not in register 0xda as this driver assumes.
> With these changes, POWER_SUPPLY_PROP_VOLTAGE_NOW just reads as 0. 0xda
> doesn't exist in max77759
> 
> I haven't compared in depth yet, though.

Regarding the regmap in this driver, please see below comparison I had
collected some time ago:

	regmap_reg_range(0x24, 0x26), // exists
	regmap_reg_range(0x30, 0x31), // exists
	regmap_reg_range(0x33, 0x34), // exists
	regmap_reg_range(0x37, 0x37), // exists
	regmap_reg_range(0x3B, 0x3C), // exists
	regmap_reg_range(0x40, 0x41), // exists
	regmap_reg_range(0x43, 0x44), // exists
	regmap_reg_range(0x47, 0x49), // exists
	regmap_reg_range(0x4B, 0x4C), // exists
	regmap_reg_range(0x4E, 0xAF), // 0x4e 0x4f exists
	regmap_reg_range(0xB1, 0xB3), // exists
	regmap_reg_range(0xB5, 0xB7), // exists
	regmap_reg_range(0xBF, 0xD0), // 0xd0 exists
	0xd1 .. 0xdb don't exist
	regmap_reg_range(0xDB, 0xDB),
	regmap_reg_range(0xE0, 0xFF), // 0xfb 0xff exist

the comments refer to whether or not the register exists in max77759

> 
> > No slave is available at address 0xb of the i2c bus, which is coherent
> > with the following driver from google: line 5836 disables non-volatile
> > memory for m5 gauge.
> > 
> > Link:
> > https://android.googlesource.com/kernel/google-modules/bms/+/1a68c36bef474573cc8629cc1d121eb6a81ab68c/max1720x_battery.c
> > 
> > Add support for the max77759 by allowing to use the non-volatile
> > memory or not based on the chip. Value for RSense comes from the following
> > stock devicetree:
> > 
> > Link:
> > https://android.googlesource.com/kernel/devices/google/gs101/+/33eca36d43da6c2b6a546806eb3e7411bbe6d60d/dts/gs101-raviole-battery.dtsi
> > 
> > Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
> > ---
> > ?drivers/power/supply/max1720x_battery.c | 71 +++++++++++++++++++++++++++-
> > -----
> > ?1 file changed, 59 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/power/supply/max1720x_battery.c
> > b/drivers/power/supply/max1720x_battery.c
> > index
> > 33105419e2427bb37963bda9948b647c239f8faa..faf336938dd4306dd2ceeb0a84b90ca8
> > 0ad41a9f 100644
> > --- a/drivers/power/supply/max1720x_battery.c
> > +++ b/drivers/power/supply/max1720x_battery.c
> > @@ -13,6 +13,7 @@
> > ?#include <linux/nvmem-provider.h>
> > ?#include <linux/power_supply.h>
> > ?#include <linux/regmap.h>
> > +#include <linux/types.h>
> 
> Please keep file names in alphabetical order.

Ignore that, it's too early :-)



Cheers,
Andre'



From krzk at kernel.org  Mon Dec  2 23:35:07 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 3 Dec 2024 08:35:07 +0100
Subject: [PATCHv3 1/2] dt-bindings: mfd: syscon: Add
 ti,j721e-acspcie-proxy-ctrl compatible
In-Reply-To: <20241202143331.126800-1-romain.naour@smile.fr>
References: <20241202143331.126800-1-romain.naour@smile.fr>
Message-ID: <douamjn7udsmbcouplhgg4i3drq5ayltraorgr43sb4lxwy2sj@gd4t3oy4rg5f>

On Mon, Dec 02, 2024 at 03:33:30PM +0100, Romain Naour wrote:
> From: Romain Naour <romain.naour at skf.com>
> 
> The ACSPCIE_PROXY_CTRL registers within the CTRL_MMR space of TI's J721e
> SoC are used to drive the reference clock to the PCIe Endpoint device via
> the PAD IO Buffers. Add the compatible for allowing the PCIe driver to
> obtain the regmap for the ACSPCIE_CTRL register within the System
> Controller device-tree node in order to enable the PAD IO Buffers.
> 
> The Technical Reference Manual for J721e SoC with details of the
> ASCPCIE_CTRL registers is available at:
> https://www.ti.com/lit/zip/spruil1
> 
> Signed-off-by: Romain Naour <romain.naour at skf.com>
> ---
>  Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
>  1 file changed, 1 insertion(+)

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

Best regards,
Krzysztof



From dima.fedrau at gmail.com  Mon Dec  2 23:35:56 2024
From: dima.fedrau at gmail.com (Dimitri Fedrau)
Date: Tue, 3 Dec 2024 08:35:56 +0100
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
Message-ID: <20241203073556.GA3936@debian>

Hi Antoine,

Am Mon, Dec 02, 2024 at 02:07:15PM +0100 schrieb Thomas Antoine via B4 Relay:
> From: Thomas Antoine <t.antoine at uclouvain.be>
> 
> The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
> except for the non-volatile memory slave address which is not available.
> No slave is available at address 0xb of the i2c bus, which is coherent
> with the following driver from google: line 5836 disables non-volatile
> memory for m5 gauge.
> 
> Link: https://android.googlesource.com/kernel/google-modules/bms/+/1a68c36bef474573cc8629cc1d121eb6a81ab68c/max1720x_battery.c
> 
> Add support for the max77759 by allowing to use the non-volatile
> memory or not based on the chip. Value for RSense comes from the following
> stock devicetree:
> 
> Link: https://android.googlesource.com/kernel/devices/google/gs101/+/33eca36d43da6c2b6a546806eb3e7411bbe6d60d/dts/gs101-raviole-battery.dtsi
> 
> Signed-off-by: Thomas Antoine <t.antoine at uclouvain.be>
> ---
>  drivers/power/supply/max1720x_battery.c | 71 +++++++++++++++++++++++++++------
>  1 file changed, 59 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/power/supply/max1720x_battery.c b/drivers/power/supply/max1720x_battery.c
> index 33105419e2427bb37963bda9948b647c239f8faa..faf336938dd4306dd2ceeb0a84b90ca80ad41a9f 100644
> --- a/drivers/power/supply/max1720x_battery.c
> +++ b/drivers/power/supply/max1720x_battery.c
> @@ -13,6 +13,7 @@
>  #include <linux/nvmem-provider.h>
>  #include <linux/power_supply.h>
>  #include <linux/regmap.h>
> +#include <linux/types.h>
>  
No need to include it, it is done by <linux/i2.c> which includes
<linux/device.h> which includes <linux/types.h>
>  #include <linux/unaligned.h>
>  
> @@ -39,6 +40,7 @@
>  #define MAX172XX_DEV_NAME_TYPE_MASK	GENMASK(3, 0)
>  #define MAX172XX_DEV_NAME_TYPE_MAX17201	BIT(0)
>  #define MAX172XX_DEV_NAME_TYPE_MAX17205	(BIT(0) | BIT(2))
> +#define MAX172XX_DEV_NAME_TYPE_MAX77759	0
>  #define MAX172XX_QR_TABLE10		0x22
>  #define MAX172XX_BATT			0xDA	/* Battery voltage */
>  #define MAX172XX_ATAVCAP		0xDF
> @@ -46,6 +48,7 @@
>  static const char *const max1720x_manufacturer = "Maxim Integrated";
>  static const char *const max17201_model = "MAX17201";
>  static const char *const max17205_model = "MAX17205";
> +static const char *const max77759_model = "MAX77759";
>  
>  struct max1720x_device_info {
>  	struct regmap *regmap;
> @@ -54,6 +57,21 @@ struct max1720x_device_info {
>  	int rsense;
>  };
>  
> +struct chip_data {
> +	u16 default_nrsense; /* in regs in 10^-5 */
> +	u8 has_nvmem;
> +};
> +
> +static const struct chip_data max1720x_data  = {
> +	.default_nrsense = 1000,
> +	.has_nvmem = 1,
> +};
> +
> +static const struct chip_data max77759_data = {
> +	.default_nrsense = 500,
> +	.has_nvmem = 0,
> +};
> +
You can get rid of chip_data by reading rsense from DT and moving
has_nvmem to max1720x_device_info. By doing so you don't have to rely on
default values. Either it is specified by DT or by rsense value in
nvmem.

Best regards,
Dimitri Fedrau


From krzk at kernel.org  Mon Dec  2 23:37:30 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 3 Dec 2024 08:37:30 +0100
Subject: [PATCH v3 2/4] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S20 Series boards (hubble)
In-Reply-To: <20241202162158.5208-3-umer.uddin@mentallysanemainliners.org>
References: <20241202162158.5208-1-umer.uddin@mentallysanemainliners.org>
 <20241202162158.5208-3-umer.uddin@mentallysanemainliners.org>
Message-ID: <p43dwymjwjhxur7v7x6dl5fl6fq2bt2oxh2zjhoonmqadgj2io@zc6s6bdcqrff>

On Mon, Dec 02, 2024 at 04:21:56PM +0000, Umer Uddin wrote:
> Add initial support for the Samsung Galaxy S20 Series (hubble) phones.
> They were launched in 2020, and are based on the Exynos 990 SoC.
> The devices have multiple RAM configurations,
> starting from 8GB going all the way up to 16GB for the S20 Ultra devices.
> 
> This device tree adds support for the following:
> 
> - SimpleFB
> - 8GB RAM (Any more will be mapped in device trees)
> - Buttons
> 
> Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
> ---
>  .../dts/exynos/exynos990-hubble-common.dtsi   | 98 +++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos990-hubble-common.dtsi

Filename matching boards, so:
exynos990-x1s-common.dtsi

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec  2 23:43:46 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 3 Dec 2024 08:43:46 +0100
Subject: [PATCH 2/5] dt-bindings: soc: renesas: Document R8A779G3 White
 Hawk Single
In-Reply-To: <1d2d2a6cbf31c817f574f6eed310a960e6175afe.1733156661.git.geert+renesas@glider.be>
References: <cover.1733156661.git.geert+renesas@glider.be>
 <1d2d2a6cbf31c817f574f6eed310a960e6175afe.1733156661.git.geert+renesas@glider.be>
Message-ID: <u7xrrqfnt5wbl5itftm4ibo63jbjcek2nzz33csmidkc4vynuq@ep2thd5dnkok>

On Mon, Dec 02, 2024 at 05:30:08PM +0100, Geert Uytterhoeven wrote:
> Document the compatible value for the Renesas R-Car V4H ES3.0
> (R8A779G3) SoC, as used on the Renesas White Hawk Single board.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
>  .../devicetree/bindings/soc/renesas/renesas.yaml          | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)

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

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec  2 23:43:08 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 3 Dec 2024 08:43:08 +0100
Subject: [PATCH 1/5] dt-bindings: soc: renesas: Move R8A779G0 White Hawk
 up
In-Reply-To: <d553ef4b1f969f72e384f274d42ac7a62fe45fd4.1733156661.git.geert+renesas@glider.be>
References: <cover.1733156661.git.geert+renesas@glider.be>
 <d553ef4b1f969f72e384f274d42ac7a62fe45fd4.1733156661.git.geert+renesas@glider.be>
Message-ID: <kqwisxsh64am76mmb5b4cxp7nhmsxafadvnkckadeywsvz6iqj@iyeo5sztpdrf>

On Mon, Dec 02, 2024 at 05:30:07PM +0100, Geert Uytterhoeven wrote:
> Move the R8A779G0-only White Hawk board stack section up, just below the
> R8A779G0-only White Hawk CPU section, to improve sort order.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
>  .../devicetree/bindings/soc/renesas/renesas.yaml     | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)

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

Best regards,
Krzysztof



From ck.hu at mediatek.com  Mon Dec  2 23:44:20 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 3 Dec 2024 07:44:20 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
Message-ID: <1b8da37e09c60778c876d163f34c54c4d15839fe.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
> +                                     struct drm_bridge_state *old_state)
> +{
> +       struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +       u8 buffer_spd[MTK_HDMI_V2_SPD_BUFFER_SIZE];
> +       u8 buffer_avi[HDMI_INFOFRAME_SIZE(AVI)];
> +
> +       mtk_hdmi_send_infoframe(hdmi, buffer_spd, sizeof(buffer_spd),
> +                               buffer_avi, sizeof(buffer_avi), &hdmi->mode);
> +       mtk_hdmi_hw_spd_infoframe(hdmi, buffer_spd, sizeof(buffer_spd));
> +       mtk_hdmi_hw_avi_infoframe(hdmi, buffer_avi, sizeof(buffer_avi));
> +
> +       mtk_hdmi_hw_vid_mute(hdmi, false);
> +       mtk_hdmi_hw_aud_mute(hdmi, false);

In v1, it does not unmute when bridge enable.
I would like v1 and v2 has the same behavior.
If possible, remove these code.
If remove thee code would result in some problem,
add comment to describe why need these code.

Regards,
CK

> +
> +       /* signal the connect event to audio codec */
> +       mtk_hdmi_handle_plugged_change(hdmi, true);
> +
> +       hdmi->enabled = true;
> +}
> +

From umer.uddin at mentallysanemainliners.org  Tue Dec  3 00:03:24 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Tue,  3 Dec 2024 08:03:24 +0000
Subject: [PATCH v4 2/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series boards (hubble)
In-Reply-To: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
References: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241203080327.4751-3-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 Series (hubble) phones.
They were launched in 2020, and are based on the Exynos 990 SoC.
The devices have multiple RAM configurations,
starting from 8GB going all the way up to 16GB for the S20 Ultra devices.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM (Any more will be mapped in device trees)
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../boot/dts/exynos/exynos990-x1s-common.dtsi | 98 +++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi

diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
new file mode 100644
index 000000000..55fa8e9e0
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 Series device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		framebuffer0: framebuffer at f1000000 {
+			compatible = "simple-framebuffer";
+			reg = <0 0xf1000000 0 (1440 * 3200 * 4)>;
+			width = <1440>;
+			height = <3200>;
+			stride = <(1440 * 4)>;
+			format = "a8r8g8b8";
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		cont_splash_mem: framebuffer at f1000000 {
+			reg = <0 0xf1000000 0 0x1194000>;
+			no-map;
+		};
+
+		abox_reserved: audio at f7fb0000 {
+			reg = <0 0xf7fb0000 0 0x2a50000>;
+			no-map;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&key_power &key_voldown &key_volup>;
+		pinctrl-names = "default";
+
+		power-key {
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpa2 4 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+
+		voldown-key {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			gpios = <&gpa0 4 GPIO_ACTIVE_LOW>;
+		};
+
+		volup-key {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&oscclk {
+	clock-frequency = <26000000>;
+};
+
+&pinctrl_alive {
+	key_power: key-power-pins {
+		samsung,pins = "gpa2-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_voldown: key-voldown-pins {
+		samsung,pins = "gpa0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_volup: key-volup-pins {
+		samsung,pins = "gpa0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Tue Dec  3 00:03:25 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Tue,  3 Dec 2024 08:03:25 +0000
Subject: [PATCH v4 3/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
In-Reply-To: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
References: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241203080327.4751-4-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 5G (x1s/SM-G981B)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 12GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 12GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile          |  1 +
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts | 28 ++++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index 948a2c6cb..6959acfbb 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -9,6 +9,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos850-e850-96.dtb		\
 	exynos8895-dreamlte.dtb		\
 	exynos990-c1s.dtb		\
+	exynos990-x1s.dtb		\
 	exynos990-r8s.dtb               \
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s.dts b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
new file mode 100644
index 000000000..1ae881015
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 5G (x1s/SM-G981B) device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990-x1s-common.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	model = "Samsung Galaxy S20 5G";
+	compatible = "samsung,x1s", "samsung,exynos990";
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x3ab00000>,
+		      /* Memory hole */
+		      <0x0 0xc1200000 0x0 0x1ee00000>,
+		      /* Memory hole */
+		      <0x0 0xe1900000 0x0 0x1e700000>,
+		      /* Memory hole */
+		      <0x8 0x80000000 0x2 0x7e800000>;
+	};
+};
-- 
2.47.1



From wenst at chromium.org  Mon Dec  2 23:56:55 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 3 Dec 2024 15:56:55 +0800
Subject: [PATCH v4 4/4] arm64: dts: mediatek: Modify audio codec name for pmic
In-Reply-To: <20241202032035.29045-5-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
 <20241202032035.29045-5-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <CAGXv+5Hp030iiCXDYHYX6F1mD5WnsL=EziHPfM7Hm4kMxnhgXw@mail.gmail.com>

On Mon, Dec 2, 2024 at 11:21?AM Zhengqiao Xia
<xiazhengqiao at huaqin.corp-partner.google.com> wrote:
>
> change `codec` in pmic (in mt8186-corsola.dtsi) to `audio-codec`
>
> Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

> ---
>  arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
> index e324e3fd347e..cebb134331fb 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
> @@ -1276,7 +1276,7 @@
>                 interrupts-extended = <&pio 201 IRQ_TYPE_LEVEL_HIGH>;
>                 #interrupt-cells = <2>;
>
> -               mt6366codec: codec {
> +               mt6366codec: audio-codec {
>                         compatible = "mediatek,mt6366-sound", "mediatek,mt6358-sound";
>                         Avdd-supply = <&mt6366_vaud28_reg>;
>                         mediatek,dmic-mode = <1>; /* one-wire */
> --
> 2.17.1
>


From devnull+j.jannau.net at kernel.org  Mon Dec  2 23:57:58 2024
From: devnull+j.jannau.net at kernel.org (Janne Grunau via B4 Relay)
Date: Tue, 03 Dec 2024 08:57:58 +0100
Subject: [PATCH v2 2/5] arm64: dts: apple: t8103: Add spi controller nodes
In-Reply-To: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
References: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
Message-ID: <20241203-asahi-spi-dt-v2-2-cd68bfaf0c84@jannau.net>

From: Janne Grunau <j at jannau.net>

Apple silicon devices have one or more SPI devices. Add device tree
nodes for all known controllers. The missing ones could be guessed and
tested with a little effort but since the devices expose no pins and
no new devices are expected there is no point in spending the effort.
SPI is used for spi-nor and input devices like keyboard, trackpad,
touchscreen and fingerprint reader. Only the spi-nor flash has upstream
drivers. Support for it will be added in a following commit.

Reviewed-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Janne Grunau <j at jannau.net>
---
 arch/arm64/boot/dts/apple/t8103.dtsi | 76 ++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
index 9b0dad6b618444ac6b1c9735c50cccfc3965f947..c9b789a2ff7e1757930b3fc3682e734c1e4dbef9 100644
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
@@ -326,6 +326,20 @@ clkref: clock-ref {
 		clock-output-names = "clkref";
 	};
 
+	clk_120m: clock-120m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <120000000>;
+		clock-output-names = "clk_120m";
+	};
+
+	clk_200m: clock-200m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <200000000>;
+		clock-output-names = "clk_200m";
+	};
+
 	/*
 	 * This is a fabulated representation of the input clock
 	 * to NCO since we don't know the true clock tree.
@@ -441,6 +455,48 @@ fpwm1: pwm at 235044000 {
 			status = "disabled";
 		};
 
+		spi0: spi at 235100000 {
+			compatible = "apple,t8103-spi", "apple,spi";
+			reg = <0x2 0x35100000 0x0 0x4000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 614 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk_200m>;
+			pinctrl-0 = <&spi0_pins>;
+			pinctrl-names = "default";
+			power-domains = <&ps_spi0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		spi1: spi at 235104000 {
+			compatible = "apple,t8103-spi", "apple,spi";
+			reg = <0x2 0x35104000 0x0 0x4000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 615 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk_200m>;
+			pinctrl-0 = <&spi1_pins>;
+			pinctrl-names = "default";
+			power-domains = <&ps_spi1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		spi3: spi at 23510c000 {
+			compatible = "apple,t8103-spi", "apple,spi";
+			reg = <0x2 0x3510c000 0x0 0x4000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 617 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk_120m>;
+			pinctrl-0 = <&spi3_pins>;
+			pinctrl-names = "default";
+			power-domains = <&ps_spi3>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		serial0: serial at 235200000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x35200000 0x0 0x1000>;
@@ -597,6 +653,26 @@ i2c4_pins: i2c4-pins {
 					 <APPLE_PINMUX(134, 1)>;
 			};
 
+			spi0_pins: spi0-pins {
+				pinmux = <APPLE_PINMUX(67, 1)>, /* CLK */
+					<APPLE_PINMUX(68, 1)>,  /* MOSI */
+					<APPLE_PINMUX(69, 1)>;  /* MISO */
+			};
+
+			spi1_pins: spi1-pins {
+				pinmux = <APPLE_PINMUX(42, 1)>,
+					<APPLE_PINMUX(43, 1)>,
+					<APPLE_PINMUX(44, 1)>,
+					<APPLE_PINMUX(45, 1)>;
+			};
+
+			spi3_pins: spi3-pins {
+				pinmux = <APPLE_PINMUX(46, 1)>,
+					<APPLE_PINMUX(47, 1)>,
+					<APPLE_PINMUX(48, 1)>,
+					<APPLE_PINMUX(49, 1)>;
+			};
+
 			pcie_pins: pcie-pins {
 				pinmux = <APPLE_PINMUX(150, 1)>,
 					 <APPLE_PINMUX(151, 1)>,

-- 
2.47.0




From devnull+j.jannau.net at kernel.org  Mon Dec  2 23:57:59 2024
From: devnull+j.jannau.net at kernel.org (Janne Grunau via B4 Relay)
Date: Tue, 03 Dec 2024 08:57:59 +0100
Subject: [PATCH v2 3/5] arm64: dts: apple: t8112: Add spi controller nodes
In-Reply-To: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
References: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
Message-ID: <20241203-asahi-spi-dt-v2-3-cd68bfaf0c84@jannau.net>

From: Janne Grunau <j at jannau.net>

Apple silicon devices have one or more SPI devices. Add device tree
nodes for all known controllers. The missing ones could be guessed and
tested with a little effort but since the devices expose no pins and
no new devices are expected there is no point in spending the effort.
SPI is used for spi-nor and input devices like keyboard, trackpad,
touchscreen and fingerprint reader. Only the spi-nor flash has upstream
drivers. Support for it will be added in a following commit.

Reviewed-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Janne Grunau <j at jannau.net>
---
 arch/arm64/boot/dts/apple/t8112.dtsi | 44 +++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/apple/t8112.dtsi b/arch/arm64/boot/dts/apple/t8112.dtsi
index 1666e6ab250bc0be9b8318e3c8fc903ccd3f3760..58d88f1ef92a32061765bd3b569fdae0255dcd7e 100644
--- a/arch/arm64/boot/dts/apple/t8112.dtsi
+++ b/arch/arm64/boot/dts/apple/t8112.dtsi
@@ -349,6 +349,13 @@ clkref: clock-ref {
 		clock-output-names = "clkref";
 	};
 
+	clk_200m: clock-200m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <200000000>;
+		clock-output-names = "clk_200m";
+	};
+
 	/*
 	 * This is a fabulated representation of the input clock
 	 * to NCO since we don't know the true clock tree.
@@ -467,6 +474,34 @@ fpwm1: pwm at 235044000 {
 			status = "disabled";
 		};
 
+		spi1: spi at 235104000 {
+			compatible = "apple,t8112-spi", "apple,spi";
+			reg = <0x2 0x35104000 0x0 0x4000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 749 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk_200m>;
+			pinctrl-0 = <&spi1_pins>;
+			pinctrl-names = "default";
+			power-domains = <&ps_spi1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		spi3: spi at 23510c000 {
+			compatible = "apple,t8112-spi", "apple,spi";
+			reg = <0x2 0x3510c000 0x0 0x4000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 751 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clkref>;
+			pinctrl-0 = <&spi3_pins>;
+			pinctrl-names = "default";
+			power-domains = <&ps_spi3>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		serial0: serial at 235200000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x35200000 0x0 0x1000>;
@@ -626,13 +661,20 @@ i2c4_pins: i2c4-pins {
 					 <APPLE_PINMUX(130, 1)>;
 			};
 
-			spi3_pins: spi3-pins {
+			spi1_pins: spi1-pins {
 				pinmux = <APPLE_PINMUX(46, 1)>,
 					<APPLE_PINMUX(47, 1)>,
 					<APPLE_PINMUX(48, 1)>,
 					<APPLE_PINMUX(49, 1)>;
 			};
 
+			spi3_pins: spi3-pins {
+				pinmux = <APPLE_PINMUX(93, 1)>,
+					<APPLE_PINMUX(94, 1)>,
+					<APPLE_PINMUX(95, 1)>,
+					<APPLE_PINMUX(96, 1)>;
+			};
+
 			pcie_pins: pcie-pins {
 				pinmux = <APPLE_PINMUX(162, 1)>,
 					 <APPLE_PINMUX(163, 1)>,

-- 
2.47.0




From devnull+j.jannau.net at kernel.org  Mon Dec  2 23:58:00 2024
From: devnull+j.jannau.net at kernel.org (Janne Grunau via B4 Relay)
Date: Tue, 03 Dec 2024 08:58:00 +0100
Subject: [PATCH v2 4/5] arm64: dts: apple: t600x: Add spi controller nodes
In-Reply-To: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
References: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
Message-ID: <20241203-asahi-spi-dt-v2-4-cd68bfaf0c84@jannau.net>

From: Janne Grunau <j at jannau.net>

Apple silicon devices have one or more SPI devices. Add device tree
nodes for all known controllers. The missing ones could be guessed and
tested with a little effort but since the devices expose no pins and
no new devices are expected there is no point in spending the effort.
SPI is used for spi-nor and input devices like keyboard, trackpad,
touchscreen and fingerprint reader. Only the spi-nor flash has upstream
drivers. Support for it will be added in a following commit.

Reviewed-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Janne Grunau <j at jannau.net>
---
 arch/arm64/boot/dts/apple/t600x-common.dtsi    |  7 +++++++
 arch/arm64/boot/dts/apple/t600x-die0.dtsi      | 28 ++++++++++++++++++++++++++
 arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi | 14 +++++++++++++
 3 files changed, 49 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t600x-common.dtsi b/arch/arm64/boot/dts/apple/t600x-common.dtsi
index fa8ead69936366999786cdd4910266ee08b5ca7a..87dfc13d74171f62bf3087401918d9d41eaac560 100644
--- a/arch/arm64/boot/dts/apple/t600x-common.dtsi
+++ b/arch/arm64/boot/dts/apple/t600x-common.dtsi
@@ -362,6 +362,13 @@ clkref: clock-ref {
 		clock-output-names = "clkref";
 	};
 
+	clk_200m: clock-200m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <200000000>;
+		clock-output-names = "clk_200m";
+	};
+
 	/*
 	 * This is a fabulated representation of the input clock
 	 * to NCO since we don't know the true clock tree.
diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
index b1c875e692c8fb9c0af46a23568a7b0cd720141b..e9b3140ba1a996eeb91b3f60470833060b632bd2 100644
--- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi
+++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
@@ -163,6 +163,34 @@ i2c5: i2c at 39b054000 {
 		status = "disabled";
 	};
 
+	spi1: spi at 39b104000 {
+		compatible = "apple,t6000-spi", "apple,spi";
+		reg = <0x3 0x9b104000 0x0 0x4000>;
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_IRQ 0 1107 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&clk_200m>;
+		pinctrl-0 = <&spi1_pins>;
+		pinctrl-names = "default";
+		power-domains = <&ps_spi1>;
+		status = "disabled";
+	};
+
+	spi3: spi at 39b10c000 {
+		compatible = "apple,t6000-spi", "apple,spi";
+		reg = <0x3 0x9b10c000 0x0 0x4000>;
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_IRQ 0 1109 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&clkref>;
+		pinctrl-0 = <&spi3_pins>;
+		pinctrl-names = "default";
+		power-domains = <&ps_spi3>;
+		status = "disabled";
+	};
+
 	serial0: serial at 39b200000 {
 		compatible = "apple,s5l-uart";
 		reg = <0x3 0x9b200000 0x0 0x1000>;
diff --git a/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi b/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi
index b31f1a7a2b3fc36e7dfa480d27012d6d0fd56f97..1a994c3c1b79f088d685e13d1dc16e7d1e6546f4 100644
--- a/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi
+++ b/arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi
@@ -36,6 +36,20 @@ i2c5_pins: i2c5-pins {
 			<APPLE_PINMUX(101, 1)>;
 	};
 
+	spi1_pins: spi1-pins {
+		pinmux = <APPLE_PINMUX(10, 1)>,
+			<APPLE_PINMUX(11, 1)>,
+			<APPLE_PINMUX(32, 1)>,
+			<APPLE_PINMUX(33, 1)>;
+	};
+
+	spi3_pins: spi3-pins {
+		pinmux = <APPLE_PINMUX(52, 1)>,
+			<APPLE_PINMUX(53, 1)>,
+			<APPLE_PINMUX(54, 1)>,
+			<APPLE_PINMUX(55, 1)>;
+	};
+
 	pcie_pins: pcie-pins {
 		pinmux = <APPLE_PINMUX(0, 1)>,
 				<APPLE_PINMUX(1, 1)>,

-- 
2.47.0




From devnull+j.jannau.net at kernel.org  Mon Dec  2 23:58:01 2024
From: devnull+j.jannau.net at kernel.org (Janne Grunau via B4 Relay)
Date: Tue, 03 Dec 2024 08:58:01 +0100
Subject: [PATCH v2 5/5] arm64: dts: apple: Add SPI NOR nvram partition to
 all devices
In-Reply-To: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
References: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
Message-ID: <20241203-asahi-spi-dt-v2-5-cd68bfaf0c84@jannau.net>

From: Janne Grunau <j at jannau.net>

All known M1* and M2* devices use an identical SPI NOR flash
configuration with a partition containing a non-volatile key:value
storage. Use a .dtsi and include it for every device.
The nvram partition parameters itself depend on the version of the
installed Apple iboot boot loader. m1n1 will fill in the current values
provided by Apple's iboot.

Reviewed-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Janne Grunau <j at jannau.net>
---
 arch/arm64/boot/dts/apple/spi1-nvram.dtsi      | 39 ++++++++++++++++++++++++++
 arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi |  2 ++
 arch/arm64/boot/dts/apple/t600x-j375.dtsi      |  2 ++
 arch/arm64/boot/dts/apple/t8103-jxxx.dtsi      |  2 ++
 arch/arm64/boot/dts/apple/t8112-jxxx.dtsi      |  2 ++
 5 files changed, 47 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/spi1-nvram.dtsi b/arch/arm64/boot/dts/apple/spi1-nvram.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..3df2fd3993b52884d7c00b65099c88d830a7a4c3
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/spi1-nvram.dtsi
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Devicetree include for common spi-nor nvram flash.
+//
+// Apple uses a consistent configiguration for the nvram on all known M1* and
+// M2* devices.
+//
+// Copyright The Asahi Linux Contributors
+
+/ {
+	aliases {
+		nvram = &nvram;
+	};
+};
+
+&spi1 {
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-max-frequency = <25000000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			nvram: partition at 700000 {
+				label = "nvram";
+				/* To be filled by the loader */
+				reg = <0x0 0x0>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
index 2e471dfe43cf885c1234d36bf0e0acfdc4904621..22ebc78e120bf8f0f71fd532e9dce4dcd117bbc6 100644
--- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
+++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi
@@ -119,3 +119,5 @@ sdhci0: mmc at 0,0 {
 &fpwm0 {
 	status = "okay";
 };
+
+#include "spi1-nvram.dtsi"
diff --git a/arch/arm64/boot/dts/apple/t600x-j375.dtsi b/arch/arm64/boot/dts/apple/t600x-j375.dtsi
index 1e5a19e49b089d4b3c5e12828b682d1993e35e75..d5b985ad567936111ee5cccc9ca9fc23d01d9edf 100644
--- a/arch/arm64/boot/dts/apple/t600x-j375.dtsi
+++ b/arch/arm64/boot/dts/apple/t600x-j375.dtsi
@@ -126,3 +126,5 @@ &pcie0_dart_2 {
 &pcie0_dart_3 {
 	status = "okay";
 };
+
+#include "spi1-nvram.dtsi"
diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
index 5988a4eb6efaa008c290b1842e0da2aae8052ba4..8e82231acab59ca0bffdcecfb6681f59661fcd96 100644
--- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
@@ -90,3 +90,5 @@ bluetooth0: bluetooth at 0,1 {
 &nco_clkref {
 	clock-frequency = <900000000>;
 };
+
+#include "spi1-nvram.dtsi"
diff --git a/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi
index f5edf61113e7aa869613d672b281f7b7e84efb79..6da35496a4c88dbaba125ebbe8c5a4a428c647c3 100644
--- a/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi
+++ b/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi
@@ -79,3 +79,5 @@ &i2c3 {
 &nco_clkref {
 	clock-frequency = <900000000>;
 };
+
+#include "spi1-nvram.dtsi"

-- 
2.47.0




From devnull+j.jannau.net at kernel.org  Mon Dec  2 23:57:57 2024
From: devnull+j.jannau.net at kernel.org (Janne Grunau via B4 Relay)
Date: Tue, 03 Dec 2024 08:57:57 +0100
Subject: [PATCH v2 1/5] arm64: dts: apple: t8103: Fix spi4 power domain
 sort order
In-Reply-To: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
References: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>
Message-ID: <20241203-asahi-spi-dt-v2-1-cd68bfaf0c84@jannau.net>

From: Hector Martin <marcan at marcan.st>

Signed-off-by: Hector Martin <marcan at marcan.st>
Reviewed-by: Neal Gompa <neal at gompa.dev>
---
 arch/arm64/boot/dts/apple/t8103-pmgr.dtsi | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
index 9645861a858c1a7c46c25a614c2cc4b03083bf46..c41c57d63997a59a9fe3c88de31fddb31781398e 100644
--- a/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103-pmgr.dtsi
@@ -387,6 +387,15 @@ ps_spi3: power-controller at 258 {
 		power-domains = <&ps_sio>, <&ps_spi_p>;
 	};
 
+	ps_spi4: power-controller at 260 {
+		compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi4";
+		power-domains = <&ps_sio>, <&ps_spi_p>;
+	};
+
 	ps_uart_n: power-controller at 268 {
 		compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
 		reg = <0x268 4>;
@@ -558,15 +567,6 @@ ps_mcc: power-controller at 2f8 {
 		apple,always-on; /* Memory controller */
 	};
 
-	ps_spi4: power-controller at 260 {
-		compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
-		reg = <0x260 4>;
-		#power-domain-cells = <0>;
-		#reset-cells = <0>;
-		label = "spi4";
-		power-domains = <&ps_sio>, <&ps_spi_p>;
-	};
-
 	ps_dcs0: power-controller at 300 {
 		compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate";
 		reg = <0x300 4>;

-- 
2.47.0




From devnull+j.jannau.net at kernel.org  Mon Dec  2 23:57:56 2024
From: devnull+j.jannau.net at kernel.org (Janne Grunau via B4 Relay)
Date: Tue, 03 Dec 2024 08:57:56 +0100
Subject: [PATCH v2 0/5] Add Apple SPI controller and spi-nor dt nodes
Message-ID: <20241203-asahi-spi-dt-v2-0-cd68bfaf0c84@jannau.net>

This series adds SPI controller and SPI NOR flash device nodes to the
man Apple silicon SoC dts files. Only the subset of used SPI controllers
is added. Five SPI controllers exists according to pmgr ADT data but the
commits only add controllers found in use on any of the devices. The
parameters for the missing nodes are guessable but there's no point in
adding them since no further M1 or M2 devices are expected.
Together with controller nodes the first SPI device is added. All Apple
silicon devices connect a SPI NOR flash to spi1. This holds Apple's 1st
stage bootloader, firmwares, platform and machine specific config data
and a writeable key-value store (nvram). Expose only the nvram as mtd
partition since it has use beyond exploring the content. Tools from
asahi-nvram [1] can modify the (default) boot configuration
(asahi-bless), read Bluetooth sync keys (asahi-btsync) and read and
write arbitrary keys (asahi-nvram).

Devicetree bindings are included in the driver series. Last version at
https://lore.kernel.org/linux-devicetree/20241101-asahi-spi-v3-0-3b411c5fb8e5 at jannau.net/

This series passes `make CHECK_DTBS=1 dtbs` with the spi bindings except
for "local-mac-address" for the Bluetooth device (I need get back to
this).

[1] https://github.com/WhatAmISupposedToPutHere/asahi-nvram/

Signed-off-by: Janne Grunau <j at jannau.net>
---
Changes in v2:
- added spi0 pins from https://lore.kernel.org/asahi/969b7440-5173-4ecc-af31-c3cd1f3f5acf at marcan.st/
- rebased onto v6.13-rc1
- added Neal's Rb:
- Link to v1: https://lore.kernel.org/r/20241102-asahi-spi-dt-v1-0-7ac44c0a88f9 at jannau.net
              https://lore.kernel.org/r/20241127-asahi-spi-dt-v1-0-907c9447f623 at jannau.net

---
Hector Martin (1):
      arm64: dts: apple: t8103: Fix spi4 power domain sort order

Janne Grunau (4):
      arm64: dts: apple: t8103: Add spi controller nodes
      arm64: dts: apple: t8112: Add spi controller nodes
      arm64: dts: apple: t600x: Add spi controller nodes
      arm64: dts: apple: Add SPI NOR nvram partition to all devices

 arch/arm64/boot/dts/apple/spi1-nvram.dtsi      | 39 +++++++++++++
 arch/arm64/boot/dts/apple/t600x-common.dtsi    |  7 +++
 arch/arm64/boot/dts/apple/t600x-die0.dtsi      | 28 ++++++++++
 arch/arm64/boot/dts/apple/t600x-gpio-pins.dtsi | 14 +++++
 arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi |  2 +
 arch/arm64/boot/dts/apple/t600x-j375.dtsi      |  2 +
 arch/arm64/boot/dts/apple/t8103-jxxx.dtsi      |  2 +
 arch/arm64/boot/dts/apple/t8103-pmgr.dtsi      | 18 +++---
 arch/arm64/boot/dts/apple/t8103.dtsi           | 76 ++++++++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8112-jxxx.dtsi      |  2 +
 arch/arm64/boot/dts/apple/t8112.dtsi           | 44 ++++++++++++++-
 11 files changed, 224 insertions(+), 10 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241101-asahi-spi-dt-58245bb1da3e

Best regards,
-- 
Janne Grunau <j at jannau.net>




From sumit.garg at linaro.org  Mon Dec  2 23:57:57 2024
From: sumit.garg at linaro.org (Sumit Garg)
Date: Tue, 3 Dec 2024 13:27:57 +0530
Subject: [PATCH v3 1/4] tee: add restricted memory allocation
In-Reply-To: <20241128150927.1377981-2-jens.wiklander@linaro.org>
References: <20241128150927.1377981-1-jens.wiklander@linaro.org> <20241128150927.1377981-2-jens.wiklander@linaro.org>
Message-ID: <CAFA6WYPVEzNLRL3sFUBgGGF_9m7tqGmg+h4TY5LDCAN5=qgBTg@mail.gmail.com>

Hi Jens,

On Thu, 28 Nov 2024 at 20:39, Jens Wiklander <jens.wiklander at linaro.org> wrote:
>
> Add restricted memory allocation to the TEE subsystem. Restricted memory
> is not be accessible by kernel during normal circumstances. A new ioctl

s/not be accessible/not accessible/

How about if we reword it as follows?

    Restricted memory refers to memory buffers behind a hardware enforced
    firewall. It is not accessible to the kernel during normal circumstances but
    rather only accessible to certain hardware IPs or CPUs executing in higher
    privileged mode than the kernel itself. This interface allows to
allocate and
    manage such restricted memory buffers via interaction with a TEE
    implementation.

> TEE_IOC_RSTMEM_ALLOC is added to allocate these restricted memory
> buffers.
>
> The restricted memory is allocated for a specific use-case, like Secure
> Video Playback, Trusted UI, or Secure Video Recording where certain
> hardware devices can access the memory.
>
> More use-cases can be added in userspace ABI, but it's up to the backend
> drivers to provide the implementation.
>
> Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> ---
>  drivers/tee/Makefile       |   1 +
>  drivers/tee/tee_core.c     |  37 ++++++-
>  drivers/tee/tee_private.h  |   2 +
>  drivers/tee/tee_rstmem.c   | 201 +++++++++++++++++++++++++++++++++++++
>  drivers/tee/tee_shm.c      |   2 +
>  drivers/tee/tee_shm_pool.c |  69 ++++++++++++-
>  include/linux/tee_core.h   |  15 +++
>  include/linux/tee_drv.h    |   4 +-
>  include/uapi/linux/tee.h   |  37 ++++++-
>  9 files changed, 363 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/tee/tee_rstmem.c
>
> diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
> index 5488cba30bd2..a4c6b55444b9 100644
> --- a/drivers/tee/Makefile
> +++ b/drivers/tee/Makefile
> @@ -3,6 +3,7 @@ obj-$(CONFIG_TEE) += tee.o
>  tee-objs += tee_core.o
>  tee-objs += tee_shm.o
>  tee-objs += tee_shm_pool.o
> +tee-objs += tee_rstmem.o
>  obj-$(CONFIG_OPTEE) += optee/
>  obj-$(CONFIG_AMDTEE) += amdtee/
>  obj-$(CONFIG_ARM_TSTEE) += tstee/
> diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
> index d113679b1e2d..e81167826002 100644
> --- a/drivers/tee/tee_core.c
> +++ b/drivers/tee/tee_core.c
> @@ -1,12 +1,13 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * Copyright (c) 2015-2016, Linaro Limited
> + * Copyright (c) 2015-2022, 2024, Linaro Limited
>   */
>
>  #define pr_fmt(fmt) "%s: " fmt, __func__
>
>  #include <linux/cdev.h>
>  #include <linux/cred.h>
> +#include <linux/dma-buf.h>
>  #include <linux/fs.h>
>  #include <linux/idr.h>
>  #include <linux/module.h>
> @@ -815,6 +816,38 @@ static int tee_ioctl_supp_send(struct tee_context *ctx,
>         return rc;
>  }
>
> +static int
> +tee_ioctl_rstmem_alloc(struct tee_context *ctx,
> +                      struct tee_ioctl_rstmem_alloc_data __user *udata)
> +{
> +       struct tee_ioctl_rstmem_alloc_data data;
> +       struct dma_buf *dmabuf;
> +       int id;
> +       int fd;
> +
> +       if (copy_from_user(&data, udata, sizeof(data)))
> +               return -EFAULT;
> +
> +       if (data.use_case == TEE_IOC_UC_RESERVED)
> +               return -EINVAL;
> +
> +       dmabuf = tee_rstmem_alloc(ctx, data.flags, data.use_case, data.size,
> +                                 &id);
> +       if (IS_ERR(dmabuf))
> +               return PTR_ERR(dmabuf);
> +       if (put_user(id, &udata->id)) {
> +               fd = -EFAULT;
> +               goto err;
> +       }
> +       fd = dma_buf_fd(dmabuf, O_CLOEXEC);
> +       if (fd < 0)
> +               goto err;
> +       return fd;
> +err:
> +       dma_buf_put(dmabuf);
> +       return fd;
> +}
> +
>  static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
>  {
>         struct tee_context *ctx = filp->private_data;
> @@ -839,6 +872,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
>                 return tee_ioctl_supp_recv(ctx, uarg);
>         case TEE_IOC_SUPPL_SEND:
>                 return tee_ioctl_supp_send(ctx, uarg);
> +       case TEE_IOC_RSTMEM_ALLOC:
> +               return tee_ioctl_rstmem_alloc(ctx, uarg);
>         default:
>                 return -EINVAL;
>         }
> diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h
> index 9bc50605227c..bf97796909c0 100644
> --- a/drivers/tee/tee_private.h
> +++ b/drivers/tee/tee_private.h
> @@ -23,5 +23,7 @@ void teedev_ctx_put(struct tee_context *ctx);
>  struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size);
>  struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx,
>                                           unsigned long addr, size_t length);
> +struct dma_buf *tee_rstmem_alloc(struct tee_context *ctx, u32 flags,
> +                                u32 use_case, size_t size, int *shm_id);
>
>  #endif /*TEE_PRIVATE_H*/
> diff --git a/drivers/tee/tee_rstmem.c b/drivers/tee/tee_rstmem.c
> new file mode 100644
> index 000000000000..536bca2901e2
> --- /dev/null
> +++ b/drivers/tee/tee_rstmem.c
> @@ -0,0 +1,201 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2024 Linaro Limited
> + */
> +#include <linux/device.h>
> +#include <linux/dma-buf.h>
> +#include <linux/genalloc.h>
> +#include <linux/scatterlist.h>
> +#include <linux/slab.h>
> +#include <linux/tee_core.h>
> +#include "tee_private.h"
> +
> +struct tee_rstmem_attachment {
> +       struct sg_table table;
> +       struct device *dev;
> +};
> +
> +static int rstmem_dma_attach(struct dma_buf *dmabuf,
> +                            struct dma_buf_attachment *attachment)
> +{
> +       struct tee_shm *shm = dmabuf->priv;
> +       struct tee_rstmem_attachment *a;
> +       int rc;
> +
> +       a = kzalloc(sizeof(*a), GFP_KERNEL);
> +       if (!a)
> +               return -ENOMEM;
> +
> +       if (shm->pages) {
> +               rc = sg_alloc_table_from_pages(&a->table, shm->pages,
> +                                              shm->num_pages, 0,
> +                                              shm->num_pages * PAGE_SIZE,
> +                                              GFP_KERNEL);
> +               if (rc)
> +                       goto err;
> +       } else {
> +               rc = sg_alloc_table(&a->table, 1, GFP_KERNEL);
> +               if (rc)
> +                       goto err;
> +               sg_set_page(a->table.sgl, phys_to_page(shm->paddr), shm->size,
> +                           0);
> +       }
> +
> +       a->dev = attachment->dev;
> +       attachment->priv = a;
> +
> +       return 0;
> +err:
> +       kfree(a);
> +       return rc;
> +}
> +
> +static void rstmem_dma_detach(struct dma_buf *dmabuf,
> +                             struct dma_buf_attachment *attachment)
> +{
> +       struct tee_rstmem_attachment *a = attachment->priv;
> +
> +       sg_free_table(&a->table);
> +       kfree(a);
> +}
> +
> +static struct sg_table *
> +rstmem_dma_map_dma_buf(struct dma_buf_attachment *attachment,
> +                      enum dma_data_direction direction)
> +{
> +       struct tee_rstmem_attachment *a = attachment->priv;
> +       int ret;
> +
> +       ret = dma_map_sgtable(attachment->dev, &a->table, direction,
> +                             DMA_ATTR_SKIP_CPU_SYNC);
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       return &a->table;
> +}
> +
> +static void rstmem_dma_unmap_dma_buf(struct dma_buf_attachment *attachment,
> +                                    struct sg_table *table,
> +                                    enum dma_data_direction direction)
> +{
> +       struct tee_rstmem_attachment *a = attachment->priv;
> +
> +       WARN_ON(&a->table != table);
> +
> +       dma_unmap_sgtable(attachment->dev, table, direction,
> +                         DMA_ATTR_SKIP_CPU_SYNC);
> +}
> +
> +static int rstmem_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
> +                                          enum dma_data_direction direction)
> +{
> +       return -EPERM;
> +}
> +
> +static int rstmem_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
> +                                        enum dma_data_direction direction)
> +{
> +       return -EPERM;
> +}
> +
> +static int rstmem_dma_buf_mmap(struct dma_buf *dmabuf,
> +                              struct vm_area_struct *vma)
> +{
> +       return -EPERM;
> +}
> +
> +static void rstmem_dma_buf_free(struct dma_buf *dmabuf)
> +{
> +       struct tee_shm *shm = dmabuf->priv;
> +
> +       tee_shm_put(shm);
> +}
> +
> +static const struct dma_buf_ops rstmem_generic_buf_ops = {
> +       .attach = rstmem_dma_attach,
> +       .detach = rstmem_dma_detach,
> +       .map_dma_buf = rstmem_dma_map_dma_buf,
> +       .unmap_dma_buf = rstmem_dma_unmap_dma_buf,
> +       .begin_cpu_access = rstmem_dma_buf_begin_cpu_access,
> +       .end_cpu_access = rstmem_dma_buf_end_cpu_access,
> +       .mmap = rstmem_dma_buf_mmap,
> +       .release = rstmem_dma_buf_free,
> +};
> +
> +struct dma_buf *tee_rstmem_alloc(struct tee_context *ctx, u32 flags,
> +                                u32 use_case, size_t size, int *shm_id)
> +{
> +       struct tee_device *teedev = ctx->teedev;
> +       DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
> +       struct dma_buf *dmabuf;
> +       struct tee_shm *shm;
> +       void *ret;
> +       int rc;
> +
> +       if (!tee_device_get(teedev))
> +               return ERR_PTR(-EINVAL);
> +
> +       if (!teedev->desc->ops->rstmem_alloc ||
> +           !teedev->desc->ops->rstmem_free) {
> +               dmabuf = ERR_PTR(-EINVAL);
> +               goto err;
> +       }
> +
> +       shm = kzalloc(sizeof(*shm), GFP_KERNEL);
> +       if (!shm) {
> +               dmabuf = ERR_PTR(-ENOMEM);
> +               goto err;
> +       }
> +
> +       refcount_set(&shm->refcount, 1);
> +       shm->flags = TEE_SHM_RESTRICTED;
> +       shm->use_case = use_case;
> +       shm->ctx = ctx;
> +
> +       mutex_lock(&teedev->mutex);
> +       shm->id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL);
> +       mutex_unlock(&teedev->mutex);
> +       if (shm->id < 0) {
> +               dmabuf = ERR_PTR(shm->id);
> +               goto err_kfree;
> +       }
> +
> +       rc = teedev->desc->ops->rstmem_alloc(ctx, shm, flags, use_case, size);
> +       if (rc) {
> +               dmabuf = ERR_PTR(rc);
> +               goto err_idr_remove;
> +       }
> +
> +       mutex_lock(&teedev->mutex);
> +       ret = idr_replace(&teedev->idr, shm, shm->id);
> +       mutex_unlock(&teedev->mutex);
> +       if (IS_ERR(ret)) {
> +               dmabuf = ret;
> +               goto err_rstmem_free;
> +       }
> +       teedev_ctx_get(ctx);
> +
> +       exp_info.ops = &rstmem_generic_buf_ops;
> +       exp_info.size = shm->size;
> +       exp_info.priv = shm;
> +       dmabuf = dma_buf_export(&exp_info);
> +       if (IS_ERR(dmabuf)) {
> +               tee_shm_put(shm);
> +               return dmabuf;
> +       }
> +
> +       *shm_id = shm->id;
> +       return dmabuf;
> +
> +err_rstmem_free:
> +       teedev->desc->ops->rstmem_free(ctx, shm);
> +err_idr_remove:
> +       mutex_lock(&teedev->mutex);
> +       idr_remove(&teedev->idr, shm->id);
> +       mutex_unlock(&teedev->mutex);
> +err_kfree:
> +       kfree(shm);
> +err:
> +       tee_device_put(teedev);
> +       return dmabuf;
> +}
> diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
> index daf6e5cfd59a..416f7f25d885 100644
> --- a/drivers/tee/tee_shm.c
> +++ b/drivers/tee/tee_shm.c
> @@ -55,6 +55,8 @@ static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm)
>                                 "unregister shm %p failed: %d", shm, rc);
>
>                 release_registered_pages(shm);
> +       } else if (shm->flags & TEE_SHM_RESTRICTED) {
> +               teedev->desc->ops->rstmem_free(shm->ctx, shm);
>         }
>
>         teedev_ctx_put(shm->ctx);
> diff --git a/drivers/tee/tee_shm_pool.c b/drivers/tee/tee_shm_pool.c
> index 80004b55628d..ee57ef157a77 100644
> --- a/drivers/tee/tee_shm_pool.c
> +++ b/drivers/tee/tee_shm_pool.c
> @@ -1,9 +1,8 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * Copyright (c) 2015, 2017, 2022 Linaro Limited
> + * Copyright (c) 2015, 2017, 2022, 2024 Linaro Limited
>   */
>  #include <linux/device.h>
> -#include <linux/dma-buf.h>
>  #include <linux/genalloc.h>
>  #include <linux/slab.h>
>  #include <linux/tee_core.h>
> @@ -90,3 +89,69 @@ struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
>         return ERR_PTR(rc);
>  }
>  EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem);
> +
> +static int rstmem_pool_op_gen_alloc(struct tee_shm_pool *pool,
> +                                   struct tee_shm *shm, size_t size,
> +                                   size_t align)
> +{
> +       size_t sz = ALIGN(size, PAGE_SIZE);
> +       phys_addr_t pa;
> +
> +       pa = gen_pool_alloc(pool->private_data, sz);
> +       if (!pa)
> +               return -ENOMEM;
> +
> +       shm->size = sz;
> +       shm->paddr = pa;
> +
> +       return 0;
> +}
> +
> +static void rstmem_pool_op_gen_free(struct tee_shm_pool *pool,
> +                                   struct tee_shm *shm)
> +{
> +       gen_pool_free(pool->private_data, shm->paddr, shm->size);
> +       shm->paddr = 0;
> +}
> +
> +static struct tee_shm_pool_ops rstmem_pool_ops_generic = {
> +       .alloc = rstmem_pool_op_gen_alloc,
> +       .free = rstmem_pool_op_gen_free,
> +       .destroy_pool = pool_op_gen_destroy_pool,
> +};
> +
> +struct tee_shm_pool *tee_rstmem_gen_pool_alloc(phys_addr_t paddr, size_t size)
> +{
> +       const size_t page_mask = PAGE_SIZE - 1;
> +       struct tee_shm_pool *pool;
> +       int rc;
> +
> +       /* Check it's page aligned */
> +       if ((paddr | size) & page_mask)
> +               return ERR_PTR(-EINVAL);
> +
> +       pool = kzalloc(sizeof(*pool), GFP_KERNEL);
> +       if (!pool)
> +               return ERR_PTR(-ENOMEM);
> +
> +       pool->private_data = gen_pool_create(PAGE_SHIFT, -1);
> +       if (!pool->private_data) {
> +               rc = -ENOMEM;
> +               goto err_free;
> +       }
> +
> +       rc = gen_pool_add(pool->private_data, paddr, size, -1);
> +       if (rc)
> +               goto err_free_pool;
> +
> +       pool->ops = &rstmem_pool_ops_generic;
> +       return pool;
> +
> +err_free_pool:
> +       gen_pool_destroy(pool->private_data);
> +err_free:
> +       kfree(pool);
> +
> +       return ERR_PTR(rc);
> +}
> +EXPORT_SYMBOL_GPL(tee_rstmem_gen_pool_alloc);
> diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h
> index a38494d6b5f4..608302f494fe 100644
> --- a/include/linux/tee_core.h
> +++ b/include/linux/tee_core.h
> @@ -26,6 +26,7 @@
>  #define TEE_SHM_USER_MAPPED    BIT(1)  /* Memory mapped in user space */
>  #define TEE_SHM_POOL           BIT(2)  /* Memory allocated from pool */
>  #define TEE_SHM_PRIV           BIT(3)  /* Memory private to TEE driver */
> +#define TEE_SHM_RESTRICTED     BIT(4)  /* Restricted memory */
>
>  #define TEE_DEVICE_FLAG_REGISTERED     0x1
>  #define TEE_MAX_DEV_NAME_LEN           32
> @@ -76,6 +77,8 @@ struct tee_device {
>   * @supp_send:         called for supplicant to send a response
>   * @shm_register:      register shared memory buffer in TEE
>   * @shm_unregister:    unregister shared memory buffer in TEE
> + * @rstmem_alloc:      allocate restricted memory
> + * @rstmem_free:       free restricted memory
>   */
>  struct tee_driver_ops {
>         void (*get_version)(struct tee_device *teedev,
> @@ -99,6 +102,9 @@ struct tee_driver_ops {
>                             struct page **pages, size_t num_pages,
>                             unsigned long start);
>         int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm);
> +       int (*rstmem_alloc)(struct tee_context *ctx, struct tee_shm *shm,
> +                           u32 flags, u32 use_case, size_t size);
> +       void (*rstmem_free)(struct tee_context *ctx, struct tee_shm *shm);
>  };
>
>  /**
> @@ -229,6 +235,15 @@ static inline void tee_shm_pool_free(struct tee_shm_pool *pool)
>         pool->ops->destroy_pool(pool);
>  }
>
> +/**
> + * tee_rstmem_gen_pool_alloc() - Create a restricted memory manager
> + * @paddr:     Physical address of start of pool
> + * @size:      Size in bytes of the pool
> + *
> + * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
> + */
> +struct tee_shm_pool *tee_rstmem_gen_pool_alloc(phys_addr_t paddr, size_t size);
> +
>  /**
>   * tee_get_drvdata() - Return driver_data pointer
>   * @returns the driver_data pointer supplied to tee_register().
> diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
> index a54c203000ed..b7ee346e5e44 100644
> --- a/include/linux/tee_drv.h
> +++ b/include/linux/tee_drv.h
> @@ -55,6 +55,7 @@ struct tee_context {
>   * @pages:     locked pages from userspace
>   * @num_pages: number of locked pages
>   * @refcount:  reference counter
> + * @use_case:  defined by TEE_IOC_UC_* in tee.h
>   * @flags:     defined by TEE_SHM_* in tee_core.h
>   * @id:                unique id of a shared memory object on this device, shared
>   *             with user space
> @@ -71,7 +72,8 @@ struct tee_shm {
>         struct page **pages;
>         size_t num_pages;
>         refcount_t refcount;
> -       u32 flags;
> +       u16 use_case;
> +       u16 flags;

Shouldn't we keep them u32 instead to be aligned with user-space inputs?

>         int id;
>         u64 sec_world_id;
>  };
> diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
> index d0430bee8292..cdc8c82c9a38 100644
> --- a/include/uapi/linux/tee.h
> +++ b/include/uapi/linux/tee.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2015-2016, Linaro Limited
> + * Copyright (c) 2015-2017, 2020, 2024, Linaro Limited
>   * All rights reserved.
>   *
>   * Redistribution and use in source and binary forms, with or without
> @@ -48,6 +48,7 @@
>  #define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */
>  #define TEE_GEN_CAP_REG_MEM    (1 << 2)/* Supports registering shared memory */
>  #define TEE_GEN_CAP_MEMREF_NULL        (1 << 3)/* NULL MemRef support */
> +#define TEE_GEN_CAP_RSTMEM     (1 << 4)/* Supports restricted memory */
>
>  #define TEE_MEMREF_NULL                (__u64)(-1) /* NULL MemRef Buffer */
>
> @@ -389,6 +390,40 @@ struct tee_ioctl_shm_register_data {
>   */
>  #define TEE_IOC_SHM_REGISTER   _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \
>                                      struct tee_ioctl_shm_register_data)
> +
> +#define TEE_IOC_UC_RESERVED            0
> +#define TEE_IOC_UC_SECURE_VIDEO_PLAY   1
> +#define TEE_IOC_UC_TRUSTED_UI          2
> +#define TEE_IOC_UC_SECURE_VIDEO_RECORD 3
> +
> +/**
> + * struct tee_ioctl_rstmem_alloc_data - Restricted memory allocate argument
> + * @size:      [in/out] Size of restricted memory to allocate
> + * @flags:     [in/out] Flags to/from allocate
> + * @use_case   [in] Restricted memory use case, TEE_IOC_UC_*
> + * @id:                [out] Identifier of the restricted memory
> + */
> +struct tee_ioctl_rstmem_alloc_data {
> +       __u64 size;
> +       __u32 flags;
> +       __u32 use_case;
> +       __s32 id;
> +};
> +
> +/**
> + * TEE_IOC_RSTMEM_ALLOC - allocate restricted memory
> + *
> + * Allocates restricted physically memory normally not accessible by the
> + * kernel.

Can we elaborate here as well on similar lines as per commit message?

-Sumit

> + *
> + * Returns a file descriptor on success or < 0 on failure
> + *
> + * The returned file descriptor is a dma-buf that can be attached and
> + * mapped for device with permission to access the physical memory.
> + */
> +#define TEE_IOC_RSTMEM_ALLOC     _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 10, \
> +                                      struct tee_ioctl_rstmem_alloc_data)
> +
>  /*
>   * Five syscalls are used when communicating with the TEE driver.
>   * open(): opens the device associated with the driver
> --
> 2.43.0
>


From umer.uddin at mentallysanemainliners.org  Tue Dec  3 00:03:23 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Tue,  3 Dec 2024 08:03:23 +0000
Subject: [PATCH v4 1/4] dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
In-Reply-To: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
References: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241203080327.4751-2-umer.uddin@mentallysanemainliners.org>

Add devicetree bindings for Samsung Galaxy S20 5G
and Samsung Galaxy S20 board.

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml         | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 168e77375..fab29f95d 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -241,6 +241,8 @@ properties:
           - enum:
               - samsung,c1s                     # Samsung Galaxy Note20 5G (SM-N981B)
               - samsung,r8s                     # Samsung Galaxy S20 FE (SM-G780F)
+              - samsung,x1s                     # Samsung Galaxy S20 5G (SM-G981B)
+              - samsung,x1slte                  # Samsung Galaxy S20 (SM-G980F)
           - const: samsung,exynos990
 
       - description: Exynos Auto v9 based boards
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Tue Dec  3 00:03:22 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Tue,  3 Dec 2024 08:03:22 +0000
Subject: [PATCH v4 0/4] Add minimal Samsung Galaxy S20 Series board, SM-G981B and SM-G980F support
Message-ID: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>

Hi folks,

This series adds initial support for the Samsung Galaxy S20 Series and also
initial board support for the Samsung Galaxy S20 5G (SM-G981B)
codenamed x1s.

The S20 Series feature a lot of similarities in their configuration
and internally Samsung named the common devicetrees in their
downstream kernel 'hubble', please note hubble excludes the
S20 FE series and Note20 series. To accomodate this, I've
now named the device tree common's matching the codenames
(x1s-common).
The device trees have been tested with dtbs_check W=1
and results in no warnings.

This initial bringup consists of:
 * pinctrl
 * gpio-keys
 * simple-framebuffer

This is enough to reach a shell in an initramfs. More platform support
will be added in the future.

Just like SM-N981B, the preferred way to boot the upstream kernel is
by using a shim bootloader, called uniLoader [1], which works around
some issues with the stock, non-replacable Samsung S-LK bootloader.
For example, the stock bootloader leaves the decon trigger control
unset, which causes the framebuffer not to refresh.

Device functionality depends on the patch series from Igor Belwon:
"Add minimal Exynos990 SoC and SM-N981B support"

[1] https://github.com/ivoszbg/uniLoader

Changes in v4:
 - Rebase from krzk's kernel tree to accomodate
   for the merge of r8s
 - Rename exynos990-hubble-common.dtsi
   to exynos990-x1s-common.dtsi

Changes in v3:
 - Fix oversight in yaml
 - Decommonise memory map

Changes in v2:
 - Add Samsung Galaxy S20 into device tree bindings
 - Add support for Samsung Galaxy S20 as well as the 5G variant now
 - Fix typo in Samsung Galaxy S20 5G commit message

Kind regards,
Umer

Umer Uddin (4):
  dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B
    and SM-G980F board
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series
    boards (hubble)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G
    (x1s)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20
    (x1slte)

 .../bindings/arm/samsung/samsung-boards.yaml  |  2 +
 arch/arm64/boot/dts/exynos/Makefile           |  2 +
 .../boot/dts/exynos/exynos990-x1s-common.dtsi | 98 +++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts  | 28 ++++++
 .../boot/dts/exynos/exynos990-x1slte.dts      | 28 ++++++
 5 files changed, 158 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Tue Dec  3 00:03:26 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Tue,  3 Dec 2024 08:03:26 +0000
Subject: [PATCH v4 4/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 (x1slte)
In-Reply-To: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
References: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241203080327.4751-5-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 (x1slte/SM-G980F)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 8GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile           |  1 +
 .../boot/dts/exynos/exynos990-x1slte.dts      | 28 +++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index 6959acfbb..b546b883a 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos8895-dreamlte.dtb		\
 	exynos990-c1s.dtb		\
 	exynos990-x1s.dtb		\
+	exynos990-x1slte.dtb		\
 	exynos990-r8s.dtb               \
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts b/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts
new file mode 100644
index 000000000..d3720996b
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 (x1slte/SM-G980F) device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990-x1s-common.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	model = "Samsung Galaxy S20";
+	compatible = "samsung,x1slte", "samsung,exynos990";
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x3ab00000>,
+		      /* Memory hole */
+		      <0x0 0xc1200000 0x0 0x1ee00000>,
+		      /* Memory hole */
+		      <0x0 0xe1900000 0x0 0x1e700000>,
+		      /* Memory hole */
+		      <0x8 0x80000000 0x1 0x7ec00000>;
+	};
+};
-- 
2.47.1



From j at jannau.net  Tue Dec  3 00:04:25 2024
From: j at jannau.net (Janne Grunau)
Date: Tue, 3 Dec 2024 09:04:25 +0100
Subject: [PATCH v2 3/4] arm64: dts: apple: Add touchbar digitizer nodes
In-Reply-To: <20241128-z2-v2-3-76cc59bbf117@gmail.com>
References: <20241128-z2-v2-0-76cc59bbf117@gmail.com>
 <20241128-z2-v2-3-76cc59bbf117@gmail.com>
Message-ID: <20241203080425.GA1282717@robin.jannau.net>

On Thu, Nov 28, 2024 at 11:29:18PM +0100, Sasha Finkelstein via B4 Relay wrote:
> From: Sasha Finkelstein <fnkl.kernel at gmail.com>
> 
> Adds device tree entries for the touchbar digitizer
> 
> Co-developed-by: Janne Grunau <j at jannau.net>
> Signed-off-by: Janne Grunau <j at jannau.net>
> Signed-off-by: Sasha Finkelstein <fnkl.kernel at gmail.com>
> ---
>  arch/arm64/boot/dts/apple/t8103-j293.dts | 26 ++++++++++++++++++++++++++
>  arch/arm64/boot/dts/apple/t8103.dtsi     | 20 ++++++++++++++++++++
>  arch/arm64/boot/dts/apple/t8112-j493.dts | 24 ++++++++++++++++++++++++
>  arch/arm64/boot/dts/apple/t8112.dtsi     | 14 ++++++++++++++
>  4 files changed, 84 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts
> index 56b0c67bfcda321b60c621de092643017693ff91..c31eb3f6f54268cafc9197a9244a5954fbb42802 100644
> --- a/arch/arm64/boot/dts/apple/t8103-j293.dts
> +++ b/arch/arm64/boot/dts/apple/t8103-j293.dts
> @@ -17,6 +17,14 @@ / {
>  	compatible = "apple,j293", "apple,t8103", "apple,arm-platform";
>  	model = "Apple MacBook Pro (13-inch, M1, 2020)";
>  
> +	/*
> +	 * All of those are used by the bootloader to pass calibration
> +	 * blobs and other device-specific properties
> +	 */
> +	aliases {
> +		touchbar0 = &touchbar0;
> +	};
> +
>  	led-controller {
>  		compatible = "pwm-leds";
>  		led-0 {
> @@ -49,3 +57,21 @@ &i2c4 {
>  &fpwm1 {
>  	status = "okay";
>  };
> +
> +&spi0 {
> +	status = "okay";
> +
> +	touchbar0: touchbar at 0 {
> +		compatible = "apple,j293-touchbar";
> +		reg = <0>;
> +		spi-max-frequency = <11500000>;
> +		spi-cs-setup-delay-ns = <2000>;
> +		spi-cs-hold-delay-ns = <2000>;
> +		reset-gpios = <&pinctrl_ap 139 GPIO_ACTIVE_LOW>;
> +		interrupts-extended = <&pinctrl_ap 194 IRQ_TYPE_EDGE_FALLING>;
> +		firmware-name = "apple/dfrmtfw-j293.bin";
> +		touchscreen-size-x = <23045>;
> +		touchscreen-size-y = <640>;
> +		touchscreen-inverted-y;
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
> index 9b0dad6b618444ac6b1c9735c50cccfc3965f947..9b83341a799d9a37578e5461e6b184f81ee7435c 100644
> --- a/arch/arm64/boot/dts/apple/t8103.dtsi
> +++ b/arch/arm64/boot/dts/apple/t8103.dtsi
> @@ -326,6 +326,13 @@ clkref: clock-ref {
>  		clock-output-names = "clkref";
>  	};
>  
> +	clk_200m: clock-200m {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <200000000>;
> +		clock-output-names = "clk_200m";
> +	};
> +
>  	/*
>  	 * This is a fabulated representation of the input clock
>  	 * to NCO since we don't know the true clock tree.
> @@ -441,6 +448,19 @@ fpwm1: pwm at 235044000 {
>  			status = "disabled";
>  		};
>  
> +		spi0: spi at 235100000 {
> +			compatible = "apple,t8103-spi", "apple,spi";
> +			reg = <0x2 0x35100000 0x0 0x4000>;
> +			interrupt-parent = <&aic>;
> +			interrupts = <AIC_IRQ 614 IRQ_TYPE_LEVEL_HIGH>;
> +			cs-gpios = <&pinctrl_ap 109 GPIO_ACTIVE_LOW>;

Since this appears to be a regular GPIO pin I think it should go into
the spi0 override in t8103-j293.dts. Kind of academic since that's the
only device using spi0. It will however allow to easily rebase this on
top of "Add Apple SPI controller and spi-nor dt nodes:
https://lore.kernel.org/asahi/20241203-asahi-spi-dt-v2-0-cd68bfaf0c84 at jannau.net/T/#u

Janne


From sumit.garg at linaro.org  Tue Dec  3 00:19:38 2024
From: sumit.garg at linaro.org (Sumit Garg)
Date: Tue, 3 Dec 2024 13:49:38 +0530
Subject: [PATCH v3 4/4] optee: support restricted memory allocation
In-Reply-To: <20241128150927.1377981-5-jens.wiklander@linaro.org>
References: <20241128150927.1377981-1-jens.wiklander@linaro.org> <20241128150927.1377981-5-jens.wiklander@linaro.org>
Message-ID: <CAFA6WYMi6X37=nKx4v52xYWU2wkW1dmcPMeXn6=6k4nv2igpPA@mail.gmail.com>

Hi Jens,

On Thu, 28 Nov 2024 at 20:39, Jens Wiklander <jens.wiklander at linaro.org> wrote:
>
> Add support in the OP-TEE backend driver for restricted memory
> allocation.
>
> The restricted memory can be allocated from a static carveout, but also
> be dynamically allocated from CMA and turned into restricted memory by
> OP-TEE, inaccessible by the kernel. The restricted memory configuration
> is depends on the platform and is probed by driver.
>
> A restricted memory pool is allocated during probe if a static carveout
> is available. The restricted memory pools for dynamically allocated
> restrict memory are instantiated when requested by user-space. This
> instantiation can fail if OP-TEE doesn't support the requested use-case
> of restricted memory.

Can we split this patch into smaller reviewable pieces as follows?

- Patch 1: Adds support for static carveout using SMC ABI
- Patch 2: Adds support for dynamic CMA pool using SMC ABI
- Patch 3: Adds support for both using FF-A ABI

-Sumit

>
> Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> ---
>  drivers/tee/optee/Makefile        |   1 +
>  drivers/tee/optee/core.c          |   1 +
>  drivers/tee/optee/ffa_abi.c       | 135 ++++++++++-
>  drivers/tee/optee/optee_private.h |  33 ++-
>  drivers/tee/optee/rstmem.c        | 380 ++++++++++++++++++++++++++++++
>  drivers/tee/optee/smc_abi.c       | 138 ++++++++++-
>  6 files changed, 683 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/tee/optee/rstmem.c
>
> diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
> index a6eff388d300..498969fb8e40 100644
> --- a/drivers/tee/optee/Makefile
> +++ b/drivers/tee/optee/Makefile
> @@ -4,6 +4,7 @@ optee-objs += core.o
>  optee-objs += call.o
>  optee-objs += notif.o
>  optee-objs += rpc.o
> +optee-objs += rstmem.o
>  optee-objs += supp.o
>  optee-objs += device.o
>  optee-objs += smc_abi.o
> diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
> index c75fddc83576..f4fa494789a4 100644
> --- a/drivers/tee/optee/core.c
> +++ b/drivers/tee/optee/core.c
> @@ -182,6 +182,7 @@ void optee_remove_common(struct optee *optee)
>         tee_device_unregister(optee->teedev);
>
>         tee_shm_pool_free(optee->pool);
> +       optee_rstmem_pools_uninit(optee);
>         optee_supp_uninit(&optee->supp);
>         mutex_destroy(&optee->call_queue.mutex);
>         rpmb_dev_put(optee->rpmb_dev);
> diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
> index 02e6175ac5f0..f500cf101c8d 100644
> --- a/drivers/tee/optee/ffa_abi.c
> +++ b/drivers/tee/optee/ffa_abi.c
> @@ -672,6 +672,122 @@ static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
>         return optee_ffa_yielding_call(ctx, &data, rpc_arg, system_thread);
>  }
>
> +static int do_call_lend_rstmem(struct optee *optee, u64 cookie, u32 use_case)
> +{
> +       struct optee_shm_arg_entry *entry;
> +       struct optee_msg_arg *msg_arg;
> +       struct tee_shm *shm;
> +       u_int offs;
> +       int rc;
> +
> +       msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs);
> +       if (IS_ERR(msg_arg))
> +               return PTR_ERR(msg_arg);
> +
> +       msg_arg->cmd = OPTEE_MSG_CMD_ASSIGN_RSTMEM;
> +       msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> +       msg_arg->params[0].u.value.a = cookie;
> +       msg_arg->params[0].u.value.b = use_case;
> +
> +       rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
> +       if (rc)
> +               goto out;
> +       if (msg_arg->ret != TEEC_SUCCESS) {
> +               rc = -EINVAL;
> +               goto out;
> +       }
> +
> +out:
> +       optee_free_msg_arg(optee->ctx, entry, offs);
> +       return rc;
> +}
> +
> +static int optee_ffa_lend_rstmem(struct optee *optee, struct tee_shm *rstmem,
> +                                u16 *end_points, unsigned int ep_count)
> +{
> +       struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
> +       const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops;
> +       const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops;
> +       struct ffa_send_direct_data data;
> +       struct ffa_mem_region_attributes *mem_attr;
> +       struct ffa_mem_ops_args args = {
> +               .use_txbuf = true,
> +               .tag = rstmem->use_case,
> +       };
> +       struct page *page;
> +       struct scatterlist sgl;
> +       unsigned int n;
> +       int rc;
> +
> +       mem_attr = kcalloc(ep_count, sizeof(*mem_attr), GFP_KERNEL);
> +       for (n = 0; n < ep_count; n++) {
> +               mem_attr[n].receiver = end_points[n];
> +               mem_attr[n].attrs = FFA_MEM_RW;
> +       }
> +       args.attrs = mem_attr;
> +       args.nattrs = ep_count;
> +
> +       page = phys_to_page(rstmem->paddr);
> +       sg_init_table(&sgl, 1);
> +       sg_set_page(&sgl, page, rstmem->size, 0);
> +
> +       args.sg = &sgl;
> +       rc = mem_ops->memory_lend(&args);
> +       kfree(mem_attr);
> +       if (rc)
> +               return rc;
> +
> +       rc = do_call_lend_rstmem(optee, args.g_handle, rstmem->use_case);
> +       if (rc)
> +               goto err_reclaim;
> +
> +       rc = optee_shm_add_ffa_handle(optee, rstmem, args.g_handle);
> +       if (rc)
> +               goto err_unreg;
> +
> +       rstmem->sec_world_id = args.g_handle;
> +
> +       return 0;
> +
> +err_unreg:
> +       data = (struct ffa_send_direct_data){
> +               .data0 = OPTEE_FFA_RELEASE_RSTMEM,
> +               .data1 = (u32)args.g_handle,
> +               .data2 = (u32)(args.g_handle >> 32),
> +       };
> +       msg_ops->sync_send_receive(ffa_dev, &data);
> +err_reclaim:
> +       mem_ops->memory_reclaim(args.g_handle, 0);
> +       return rc;
> +}
> +
> +static int optee_ffa_reclaim_rstmem(struct optee *optee, struct tee_shm *rstmem)
> +{
> +       struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
> +       const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops;
> +       const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops;
> +       u64 global_handle = rstmem->sec_world_id;
> +       struct ffa_send_direct_data data = {
> +               .data0 = OPTEE_FFA_RELEASE_RSTMEM,
> +               .data1 = (u32)global_handle,
> +               .data2 = (u32)(global_handle >> 32)
> +       };
> +       int rc;
> +
> +       optee_shm_rem_ffa_handle(optee, global_handle);
> +       rstmem->sec_world_id = 0;
> +
> +       rc = msg_ops->sync_send_receive(ffa_dev, &data);
> +       if (rc)
> +               pr_err("Release SHM id 0x%llx rc %d\n", global_handle, rc);
> +
> +       rc = mem_ops->memory_reclaim(global_handle, 0);
> +       if (rc)
> +               pr_err("mem_reclaim: 0x%llx %d", global_handle, rc);
> +
> +       return rc;
> +}
> +
>  /*
>   * 6. Driver initialization
>   *
> @@ -785,7 +901,10 @@ static void optee_ffa_get_version(struct tee_device *teedev,
>                 .gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM |
>                             TEE_GEN_CAP_MEMREF_NULL,
>         };
> +       struct optee *optee = tee_get_drvdata(teedev);
>
> +       if (optee->rstmem_pools)
> +               v.gen_caps |= TEE_GEN_CAP_RSTMEM;
>         *vers = v;
>  }
>
> @@ -804,6 +923,8 @@ static const struct tee_driver_ops optee_ffa_clnt_ops = {
>         .cancel_req = optee_cancel_req,
>         .shm_register = optee_ffa_shm_register,
>         .shm_unregister = optee_ffa_shm_unregister,
> +       .rstmem_alloc = optee_rstmem_alloc,
> +       .rstmem_free = optee_rstmem_free,
>  };
>
>  static const struct tee_desc optee_ffa_clnt_desc = {
> @@ -820,6 +941,8 @@ static const struct tee_driver_ops optee_ffa_supp_ops = {
>         .supp_send = optee_supp_send,
>         .shm_register = optee_ffa_shm_register, /* same as for clnt ops */
>         .shm_unregister = optee_ffa_shm_unregister_supp,
> +       .rstmem_alloc = optee_rstmem_alloc,
> +       .rstmem_free = optee_rstmem_free,
>  };
>
>  static const struct tee_desc optee_ffa_supp_desc = {
> @@ -833,6 +956,8 @@ static const struct optee_ops optee_ffa_ops = {
>         .do_call_with_arg = optee_ffa_do_call_with_arg,
>         .to_msg_param = optee_ffa_to_msg_param,
>         .from_msg_param = optee_ffa_from_msg_param,
> +       .lend_rstmem = optee_ffa_lend_rstmem,
> +       .reclaim_rstmem = optee_ffa_reclaim_rstmem,
>  };
>
>  static void optee_ffa_remove(struct ffa_device *ffa_dev)
> @@ -937,11 +1062,17 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
>             (sec_caps & OPTEE_FFA_SEC_CAP_RPMB_PROBE))
>                 optee->in_kernel_rpmb_routing = true;
>
> +       if (sec_caps & OPTEE_FFA_SEC_CAP_RSTMEM) {
> +               rc = optee_rstmem_pools_init(optee);
> +               if (rc)
> +                       goto err_free_pool;
> +       }
> +
>         teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool,
>                                   optee);
>         if (IS_ERR(teedev)) {
>                 rc = PTR_ERR(teedev);
> -               goto err_free_pool;
> +               goto err_free_rstmem_pools;
>         }
>         optee->teedev = teedev;
>
> @@ -1020,6 +1151,8 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
>         tee_device_unregister(optee->teedev);
>  err_free_pool:
>         tee_shm_pool_free(pool);
> +err_free_rstmem_pools:
> +       optee_rstmem_pools_uninit(optee);
>  err_free_optee:
>         kfree(optee);
>         return rc;
> diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
> index 20eda508dbac..dd2a3a2224bc 100644
> --- a/drivers/tee/optee/optee_private.h
> +++ b/drivers/tee/optee/optee_private.h
> @@ -174,9 +174,14 @@ struct optee;
>   * @do_call_with_arg:  enters OP-TEE in secure world
>   * @to_msg_param:      converts from struct tee_param to OPTEE_MSG parameters
>   * @from_msg_param:    converts from OPTEE_MSG parameters to struct tee_param
> + * @lend_rstmem:       lends physically contiguous memory as restricted
> + *                     memory, inaccessible by the kernel
> + * @reclaim_rstmem:    reclaims restricted memory previously lent with
> + *                     @lend_rstmem() and makes it accessible by the
> + *                     kernel again
>   *
>   * These OPs are only supposed to be used internally in the OP-TEE driver
> - * as a way of abstracting the different methogs of entering OP-TEE in
> + * as a way of abstracting the different methods of entering OP-TEE in
>   * secure world.
>   */
>  struct optee_ops {
> @@ -191,6 +196,23 @@ struct optee_ops {
>                               size_t num_params,
>                               const struct optee_msg_param *msg_params,
>                               bool update_out);
> +       int (*lend_rstmem)(struct optee *optee, struct tee_shm *rstmem,
> +                          u16 *end_points, unsigned int ep_count);
> +       int (*reclaim_rstmem)(struct optee *optee, struct tee_shm *rstmem);
> +};
> +
> +/**
> + * struct optee_rstmem_pools - restricted memory pools
> + * @mutex:     serializes write access to @xa when adding a new pool.
> + * @xa:                XArray of struct tee_shm_pool where the index is the
> + *             use case ID TEE_IOC_UC_* supplied for TEE_IOC_RSTMEM_ALLOC.
> + */
> +struct optee_rstmem_pools {
> +       /*
> +        * Serializes write access to @xa when adding a new pool.
> +        */
> +       struct mutex mutex;
> +       struct xarray xa;
>  };
>
>  /**
> @@ -206,6 +228,7 @@ struct optee_ops {
>   * @notif:             notification synchronization struct
>   * @supp:              supplicant synchronization struct for RPC to supplicant
>   * @pool:              shared memory pool
> + * @rstmem_pool:       restricted memory pool for secure data path
>   * @mutex:             mutex protecting @rpmb_dev
>   * @rpmb_dev:          current RPMB device or NULL
>   * @rpmb_scan_bus_done flag if device registation of RPMB dependent devices
> @@ -230,6 +253,7 @@ struct optee {
>         struct optee_notif notif;
>         struct optee_supp supp;
>         struct tee_shm_pool *pool;
> +       struct optee_rstmem_pools *rstmem_pools;
>         /* Protects rpmb_dev pointer */
>         struct mutex rpmb_dev_mutex;
>         struct rpmb_dev *rpmb_dev;
> @@ -286,6 +310,9 @@ void optee_supp_init(struct optee_supp *supp);
>  void optee_supp_uninit(struct optee_supp *supp);
>  void optee_supp_release(struct optee_supp *supp);
>
> +int optee_rstmem_pools_init(struct optee *optee);
> +void optee_rstmem_pools_uninit(struct optee *optee);
> +
>  int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
>                     struct tee_param *param);
>  int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
> @@ -378,6 +405,10 @@ void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
>  int optee_do_bottom_half(struct tee_context *ctx);
>  int optee_stop_async_notif(struct tee_context *ctx);
>
> +int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
> +                      u32 flags, u32 use_case, size_t size);
> +void optee_rstmem_free(struct tee_context *ctx, struct tee_shm *shm);
> +
>  /*
>   * Small helpers
>   */
> diff --git a/drivers/tee/optee/rstmem.c b/drivers/tee/optee/rstmem.c
> new file mode 100644
> index 000000000000..cf300929171f
> --- /dev/null
> +++ b/drivers/tee/optee/rstmem.c
> @@ -0,0 +1,380 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2024, Linaro Limited
> + */
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/cma.h>
> +#include <linux/dma-map-ops.h>
> +#include <linux/errno.h>
> +#include <linux/genalloc.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/tee_core.h>
> +#include <linux/types.h>
> +#include "optee_private.h"
> +
> +struct optee_rstmem_cma_pool {
> +       struct tee_shm_pool pool;
> +       struct page *page;
> +       struct optee *optee;
> +       size_t page_count;
> +       u16 *end_points;
> +       u_int end_point_count;
> +       u_int align;
> +       refcount_t refcount;
> +       struct tee_shm rstmem;
> +       /* Protects when initializing and tearing down this struct */
> +       struct mutex mutex;
> +};
> +
> +static struct optee_rstmem_cma_pool *
> +to_rstmem_cma_pool(struct tee_shm_pool *pool)
> +{
> +       return container_of(pool, struct optee_rstmem_cma_pool, pool);
> +}
> +
> +static int init_cma_rstmem(struct optee_rstmem_cma_pool *rp)
> +{
> +       struct cma *cma = dev_get_cma_area(&rp->optee->teedev->dev);
> +       int rc;
> +
> +       rp->page = cma_alloc(cma, rp->page_count, rp->align, true/*no_warn*/);
> +       if (!rp->page)
> +               return -ENOMEM;
> +
> +       /*
> +        * TODO unmap the memory range since the physical memory will
> +        * become inaccesible after the lend_rstmem() call.
> +        */
> +
> +       rp->rstmem.paddr = page_to_phys(rp->page);
> +       rp->rstmem.size = rp->page_count * PAGE_SIZE;
> +       rc = rp->optee->ops->lend_rstmem(rp->optee, &rp->rstmem,
> +                                        rp->end_points, rp->end_point_count);
> +       if (rc)
> +               goto err_release;
> +
> +       rp->pool.private_data = gen_pool_create(PAGE_SHIFT, -1);
> +       if (!rp->pool.private_data) {
> +               rc = -ENOMEM;
> +               goto err_reclaim;
> +       }
> +
> +       rc = gen_pool_add(rp->pool.private_data, rp->rstmem.paddr,
> +                         rp->rstmem.size, -1);
> +       if (rc)
> +               goto err_free_pool;
> +
> +       refcount_set(&rp->refcount, 1);
> +       return 0;
> +
> +err_free_pool:
> +       gen_pool_destroy(rp->pool.private_data);
> +err_reclaim:
> +       rp->optee->ops->reclaim_rstmem(rp->optee, &rp->rstmem);
> +err_release:
> +       cma_release(cma, rp->page, rp->page_count);
> +       rp->rstmem.paddr = 0;
> +       rp->rstmem.size = 0;
> +       rp->rstmem.sec_world_id = 0;
> +       return rc;
> +}
> +
> +static int get_cma_rstmem(struct optee_rstmem_cma_pool *rp)
> +{
> +       int rc = 0;
> +
> +       if (!refcount_inc_not_zero(&rp->refcount)) {
> +               mutex_lock(&rp->mutex);
> +               if (rp->pool.private_data) {
> +                       /*
> +                        * Another thread has already initialized the pool
> +                        * before us, or the pool was just about to be torn
> +                        * down. Either way we only need to increase the
> +                        * refcount and we're done.
> +                        */
> +                       refcount_inc(&rp->refcount);
> +               } else {
> +                       rc = init_cma_rstmem(rp);
> +               }
> +               mutex_unlock(&rp->mutex);
> +       }
> +
> +       return rc;
> +}
> +
> +static void release_cma_rstmem(struct optee_rstmem_cma_pool *rp)
> +{
> +       gen_pool_destroy(rp->pool.private_data);
> +       rp->optee->ops->reclaim_rstmem(rp->optee, &rp->rstmem);
> +       cma_release(dev_get_cma_area(&rp->optee->teedev->dev), rp->page,
> +                   rp->page_count);
> +
> +       rp->pool.private_data = NULL;
> +       rp->page = NULL;
> +       rp->rstmem.paddr = 0;
> +       rp->rstmem.size = 0;
> +       rp->rstmem.sec_world_id = 0;
> +}
> +
> +static void put_cma_rstmem(struct optee_rstmem_cma_pool *rp)
> +{
> +       if (refcount_dec_and_test(&rp->refcount)) {
> +               mutex_lock(&rp->mutex);
> +               if (rp->pool.private_data)
> +                       release_cma_rstmem(rp);
> +               mutex_unlock(&rp->mutex);
> +       }
> +}
> +
> +static int rstmem_pool_op_cma_alloc(struct tee_shm_pool *pool,
> +                                   struct tee_shm *shm, size_t size,
> +                                   size_t align)
> +{
> +       struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool);
> +       size_t sz = ALIGN(size, PAGE_SIZE);
> +       phys_addr_t pa;
> +       int rc;
> +
> +       rc = get_cma_rstmem(rp);
> +       if (rc)
> +               return rc;
> +
> +       pa = gen_pool_alloc(rp->pool.private_data, sz);
> +       if (!pa) {
> +               put_cma_rstmem(rp);
> +               return -ENOMEM;
> +       }
> +
> +       shm->size = sz;
> +       shm->paddr = pa;
> +       shm->offset = pa - page_to_phys(rp->page);
> +       shm->sec_world_id = rp->rstmem.sec_world_id;
> +
> +       return 0;
> +}
> +
> +static void rstmem_pool_op_cma_free(struct tee_shm_pool *pool,
> +                                   struct tee_shm *shm)
> +{
> +       struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool);
> +
> +       gen_pool_free(rp->pool.private_data, shm->paddr, shm->size);
> +       shm->size = 0;
> +       shm->paddr = 0;
> +       shm->offset = 0;
> +       shm->sec_world_id = 0;
> +       put_cma_rstmem(rp);
> +}
> +
> +static void pool_op_cma_destroy_pool(struct tee_shm_pool *pool)
> +{
> +       struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool);
> +
> +       mutex_destroy(&rp->mutex);
> +       kfree(rp);
> +}
> +
> +static struct tee_shm_pool_ops rstmem_pool_ops_cma = {
> +       .alloc = rstmem_pool_op_cma_alloc,
> +       .free = rstmem_pool_op_cma_free,
> +       .destroy_pool = pool_op_cma_destroy_pool,
> +};
> +
> +static int get_rstmem_config(struct optee *optee, u32 use_case,
> +                            size_t *min_size, u_int *min_align,
> +                            u16 *end_points, u_int *ep_count)
> +{
> +       struct tee_param params[2] = {
> +               [0] = {
> +                       .attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT,
> +                       .u.value.a = use_case,
> +               },
> +               [1] = {
> +                       .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT,
> +               },
> +       };
> +       struct optee_shm_arg_entry *entry;
> +       struct tee_shm *shm_param = NULL;
> +       struct optee_msg_arg *msg_arg;
> +       struct tee_shm *shm;
> +       u_int offs;
> +       int rc;
> +
> +       if (end_points && *ep_count) {
> +               params[1].u.memref.size = *ep_count * sizeof(*end_points);
> +               shm_param = tee_shm_alloc_priv_buf(optee->ctx,
> +                                                  params[1].u.memref.size);
> +               if (IS_ERR(shm_param))
> +                       return PTR_ERR(shm_param);
> +               params[1].u.memref.shm = shm_param;
> +       }
> +
> +       msg_arg = optee_get_msg_arg(optee->ctx, ARRAY_SIZE(params), &entry,
> +                                   &shm, &offs);
> +       if (IS_ERR(msg_arg)) {
> +               rc = PTR_ERR(msg_arg);
> +               goto out_free_shm;
> +       }
> +       msg_arg->cmd = OPTEE_MSG_CMD_GET_RSTMEM_CONFIG;
> +
> +       rc = optee->ops->to_msg_param(optee, msg_arg->params,
> +                                     ARRAY_SIZE(params), params,
> +                                     false /*!update_out*/);
> +       if (rc)
> +               goto out_free_msg;
> +
> +       rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
> +       if (rc)
> +               goto out_free_msg;
> +       if (msg_arg->ret && msg_arg->ret != TEEC_ERROR_SHORT_BUFFER) {
> +               rc = -EINVAL;
> +               goto out_free_msg;
> +       }
> +
> +       rc = optee->ops->from_msg_param(optee, params, ARRAY_SIZE(params),
> +                                       msg_arg->params, true /*update_out*/);
> +       if (rc)
> +               goto out_free_msg;
> +
> +       if (!msg_arg->ret && end_points &&
> +           *ep_count < params[1].u.memref.size / sizeof(u16)) {
> +               rc = -EINVAL;
> +               goto out_free_msg;
> +       }
> +
> +       *min_size = params[0].u.value.a;
> +       *min_align = params[0].u.value.b;
> +       *ep_count = params[1].u.memref.size / sizeof(u16);
> +
> +       if (msg_arg->ret == TEEC_ERROR_SHORT_BUFFER) {
> +               rc = -ENOSPC;
> +               goto out_free_msg;
> +       }
> +
> +       if (end_points)
> +               memcpy(end_points, tee_shm_get_va(shm_param, 0),
> +                      params[1].u.memref.size);
> +
> +out_free_msg:
> +       optee_free_msg_arg(optee->ctx, entry, offs);
> +out_free_shm:
> +       if (shm_param)
> +               tee_shm_free(shm_param);
> +       return rc;
> +}
> +
> +static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee, u32 use_case)
> +{
> +       struct optee_rstmem_cma_pool *rp;
> +       size_t min_size;
> +       int rc;
> +
> +       rp = kzalloc(sizeof(*rp), GFP_KERNEL);
> +       if (!rp)
> +               return ERR_PTR(-ENOMEM);
> +       rp->rstmem.use_case = use_case;
> +
> +       rc = get_rstmem_config(optee, use_case, &min_size, &rp->align, NULL,
> +                              &rp->end_point_count);
> +       if (rc) {
> +               if (rc != -ENOSPC)
> +                       goto err;
> +               rp->end_points = kcalloc(rp->end_point_count,
> +                                        sizeof(*rp->end_points), GFP_KERNEL);
> +               if (!rp->end_points) {
> +                       rc = -ENOMEM;
> +                       goto err;
> +               }
> +               rc = get_rstmem_config(optee, use_case, &min_size, &rp->align,
> +                                      rp->end_points, &rp->end_point_count);
> +               if (rc)
> +                       goto err_kfree_eps;
> +       }
> +
> +       rp->pool.ops = &rstmem_pool_ops_cma;
> +       rp->optee = optee;
> +       rp->page_count = min_size / PAGE_SIZE;
> +       mutex_init(&rp->mutex);
> +
> +       return &rp->pool;
> +
> +err_kfree_eps:
> +       kfree(rp->end_points);
> +err:
> +       kfree(rp);
> +       return ERR_PTR(rc);
> +}
> +
> +int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
> +                      u32 flags, u32 use_case, size_t size)
> +{
> +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> +       struct tee_shm_pool *pool;
> +       int rc;
> +
> +       if (!optee->rstmem_pools)
> +               return -EINVAL;
> +       if (flags)
> +               return -EINVAL;
> +
> +       pool = xa_load(&optee->rstmem_pools->xa, use_case);
> +       if (!pool) {
> +               pool = alloc_rstmem_pool(optee, use_case);
> +               if (IS_ERR(pool))
> +                       return PTR_ERR(pool);
> +               rc = xa_insert(&optee->rstmem_pools->xa, use_case, pool,
> +                              GFP_KERNEL);
> +               if (rc) {
> +                       pool->ops->destroy_pool(pool);
> +                       return rc;
> +               }
> +       }
> +
> +       return pool->ops->alloc(pool, shm, size, 0);
> +}
> +
> +void optee_rstmem_free(struct tee_context *ctx, struct tee_shm *shm)
> +{
> +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> +       struct tee_shm_pool *pool;
> +
> +       pool = xa_load(&optee->rstmem_pools->xa, shm->use_case);
> +       if (pool)
> +               pool->ops->free(pool, shm);
> +       else
> +               pr_err("Can't find pool for use_case %u\n", shm->use_case);
> +}
> +
> +int optee_rstmem_pools_init(struct optee *optee)
> +{
> +       struct optee_rstmem_pools *pools;
> +
> +       pools = kmalloc(sizeof(*pools), GFP_KERNEL);
> +       if (!pools)
> +               return -ENOMEM;
> +
> +       mutex_init(&pools->mutex);
> +       xa_init(&pools->xa);
> +       optee->rstmem_pools = pools;
> +       return 0;
> +}
> +
> +void optee_rstmem_pools_uninit(struct optee *optee)
> +{
> +       if (optee->rstmem_pools) {
> +               struct tee_shm_pool *pool;
> +               u_long idx;
> +
> +               xa_for_each(&optee->rstmem_pools->xa, idx, pool) {
> +                       xa_erase(&optee->rstmem_pools->xa, idx);
> +                       pool->ops->destroy_pool(pool);
> +               }
> +
> +               xa_destroy(&optee->rstmem_pools->xa);
> +               mutex_destroy(&optee->rstmem_pools->mutex);
> +               kfree(optee->rstmem_pools);
> +               optee->rstmem_pools = NULL;
> +       }
> +}
> diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
> index d1f79947f58a..7fa7d9d14c94 100644
> --- a/drivers/tee/optee/smc_abi.c
> +++ b/drivers/tee/optee/smc_abi.c
> @@ -1001,6 +1001,67 @@ static int optee_smc_do_call_with_arg(struct tee_context *ctx,
>         return rc;
>  }
>
> +static int optee_smc_lend_rstmem(struct optee *optee, struct tee_shm *rstmem,
> +                                u16 *end_points, unsigned int ep_count)
> +{
> +       struct optee_shm_arg_entry *entry;
> +       struct optee_msg_arg *msg_arg;
> +       struct tee_shm *shm;
> +       u_int offs;
> +       int rc;
> +
> +       msg_arg = optee_get_msg_arg(optee->ctx, 2, &entry, &shm, &offs);
> +       if (IS_ERR(msg_arg))
> +               return PTR_ERR(msg_arg);
> +
> +       msg_arg->cmd = OPTEE_MSG_CMD_LEND_RSTMEM;
> +       msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> +       msg_arg->params[0].u.value.a = OPTEE_MSG_RSTMEM_SECURE_VIDEO_PLAY;
> +       msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
> +       msg_arg->params[1].u.tmem.buf_ptr = rstmem->paddr;
> +       msg_arg->params[1].u.tmem.size = rstmem->size;
> +       msg_arg->params[1].u.tmem.shm_ref = (u_long)rstmem;
> +
> +       rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
> +       if (rc)
> +               goto out;
> +       if (msg_arg->ret != TEEC_SUCCESS) {
> +               rc = -EINVAL;
> +               goto out;
> +       }
> +
> +out:
> +       optee_free_msg_arg(optee->ctx, entry, offs);
> +       return rc;
> +}
> +
> +static int optee_smc_reclaim_rstmem(struct optee *optee, struct tee_shm *rstmem)
> +{
> +       struct optee_shm_arg_entry *entry;
> +       struct optee_msg_arg *msg_arg;
> +       struct tee_shm *shm;
> +       u_int offs;
> +       int rc;
> +
> +       msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs);
> +       if (IS_ERR(msg_arg))
> +               return PTR_ERR(msg_arg);
> +
> +       msg_arg->cmd = OPTEE_MSG_CMD_RECLAIM_RSTMEM;
> +       msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
> +       msg_arg->params[0].u.rmem.shm_ref = (u_long)rstmem;
> +
> +       rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
> +       if (rc)
> +               goto out;
> +       if (msg_arg->ret != TEEC_SUCCESS)
> +               rc = -EINVAL;
> +
> +out:
> +       optee_free_msg_arg(optee->ctx, entry, offs);
> +       return rc;
> +}
> +
>  /*
>   * 5. Asynchronous notification
>   */
> @@ -1201,6 +1262,8 @@ static void optee_get_version(struct tee_device *teedev,
>                 v.gen_caps |= TEE_GEN_CAP_REG_MEM;
>         if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
>                 v.gen_caps |= TEE_GEN_CAP_MEMREF_NULL;
> +       if (optee->rstmem_pools)
> +               v.gen_caps |= TEE_GEN_CAP_RSTMEM;
>         *vers = v;
>  }
>
> @@ -1223,6 +1286,8 @@ static const struct tee_driver_ops optee_clnt_ops = {
>         .cancel_req = optee_cancel_req,
>         .shm_register = optee_shm_register,
>         .shm_unregister = optee_shm_unregister,
> +       .rstmem_alloc = optee_rstmem_alloc,
> +       .rstmem_free = optee_rstmem_free,
>  };
>
>  static const struct tee_desc optee_clnt_desc = {
> @@ -1239,6 +1304,8 @@ static const struct tee_driver_ops optee_supp_ops = {
>         .supp_send = optee_supp_send,
>         .shm_register = optee_shm_register_supp,
>         .shm_unregister = optee_shm_unregister_supp,
> +       .rstmem_alloc = optee_rstmem_alloc,
> +       .rstmem_free = optee_rstmem_free,
>  };
>
>  static const struct tee_desc optee_supp_desc = {
> @@ -1252,6 +1319,9 @@ static const struct optee_ops optee_ops = {
>         .do_call_with_arg = optee_smc_do_call_with_arg,
>         .to_msg_param = optee_to_msg_param,
>         .from_msg_param = optee_from_msg_param,
> +       .lend_rstmem = optee_smc_lend_rstmem,
> +       .reclaim_rstmem = optee_smc_reclaim_rstmem,
> +       //.alloc_rstmem_pool = optee_smc_alloc_rstmem_pool,
>  };
>
>  static int enable_async_notif(optee_invoke_fn *invoke_fn)
> @@ -1619,6 +1689,62 @@ static inline int optee_load_fw(struct platform_device *pdev,
>  }
>  #endif
>
> +static int optee_sdp_pool_init(struct optee *optee)
> +{
> +       bool dyn_sdp = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_RSTMEM;
> +       bool sdp = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP;
> +       struct tee_shm_pool *pool;
> +       int rc;
> +
> +       /*
> +        * optee_sdp_pools_init() must be called if secure world has any
> +        * SDP capability. If the static carvout is available initialize
> +        * and add a pool for that. If there's an error from secure world
> +        * we complain but don't call optee_sdp_pools_uninit() unless we
> +        * know that there is no SDP capability left.
> +        */
> +       if (!dyn_sdp && !sdp)
> +               return 0;
> +
> +       rc = optee_rstmem_pools_init(optee);
> +       if (rc)
> +               return rc;
> +
> +       if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP) {
> +               union {
> +                       struct arm_smccc_res smccc;
> +                       struct optee_smc_get_sdp_config_result result;
> +               } res;
> +
> +               optee->smc.invoke_fn(OPTEE_SMC_GET_SDP_CONFIG, 0, 0, 0, 0, 0, 0,
> +                                    0, &res.smccc);
> +               if (res.result.status != OPTEE_SMC_RETURN_OK) {
> +                       pr_err("Secure Data Path service not available\n");
> +                       if (!dyn_sdp)
> +                               goto err;
> +                       return 0;
> +               }
> +
> +               pool = tee_rstmem_gen_pool_alloc(res.result.start,
> +                                                res.result.size);
> +               if (IS_ERR(pool)) {
> +                       rc = PTR_ERR(pool);
> +                       goto err;
> +               }
> +               rc = xa_insert(&optee->rstmem_pools->xa,
> +                              TEE_IOC_UC_SECURE_VIDEO_PLAY, pool, GFP_KERNEL);
> +               if (rc) {
> +                       pool->ops->destroy_pool(pool);
> +                       goto err;
> +               }
> +       }
> +
> +       return 0;
> +err:
> +       optee_rstmem_pools_uninit(optee);
> +       return rc;
> +}
> +
>  static int optee_probe(struct platform_device *pdev)
>  {
>         optee_invoke_fn *invoke_fn;
> @@ -1714,7 +1840,7 @@ static int optee_probe(struct platform_device *pdev)
>         optee = kzalloc(sizeof(*optee), GFP_KERNEL);
>         if (!optee) {
>                 rc = -ENOMEM;
> -               goto err_free_pool;
> +               goto err_free_shm_pool;
>         }
>
>         optee->ops = &optee_ops;
> @@ -1726,10 +1852,14 @@ static int optee_probe(struct platform_device *pdev)
>             (sec_caps & OPTEE_SMC_SEC_CAP_RPMB_PROBE))
>                 optee->in_kernel_rpmb_routing = true;
>
> +       rc = optee_sdp_pool_init(optee);
> +       if (rc)
> +               goto err_free_optee;
> +
>         teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
>         if (IS_ERR(teedev)) {
>                 rc = PTR_ERR(teedev);
> -               goto err_free_optee;
> +               goto err_rstmem_pools_uninit;
>         }
>         optee->teedev = teedev;
>
> @@ -1836,9 +1966,11 @@ static int optee_probe(struct platform_device *pdev)
>         tee_device_unregister(optee->supp_teedev);
>  err_unreg_teedev:
>         tee_device_unregister(optee->teedev);
> +err_rstmem_pools_uninit:
> +       optee_rstmem_pools_uninit(optee);
>  err_free_optee:
>         kfree(optee);
> -err_free_pool:
> +err_free_shm_pool:
>         tee_shm_pool_free(pool);
>         if (memremaped_shm)
>                 memunmap(memremaped_shm);
> --
> 2.43.0
>


From sumit.garg at linaro.org  Tue Dec  3 00:27:10 2024
From: sumit.garg at linaro.org (Sumit Garg)
Date: Tue, 3 Dec 2024 13:57:10 +0530
Subject: [PATCH v3 2/4] optee: account for direction while converting parameters
In-Reply-To: <20241128150927.1377981-3-jens.wiklander@linaro.org>
References: <20241128150927.1377981-1-jens.wiklander@linaro.org> <20241128150927.1377981-3-jens.wiklander@linaro.org>
Message-ID: <CAFA6WYPEqCWyvD=pCj6DEkZWN9SCfXMnq4tKbSx1-e8UmgXb=Q@mail.gmail.com>

Hi Jens,

On Thu, 28 Nov 2024 at 20:39, Jens Wiklander <jens.wiklander at linaro.org> wrote:
>
> The OP-TEE backend driver has two internal function pointers to convert
> between the subsystem type struct tee_param and the OP-TEE type struct
> optee_msg_param.
>
> The conversion is done from one of the types to the other, which is then
> involved in some operation and finally converted back to the original
> type. When converting to prepare the parameters for the operation, all
> fields must be taken into account, but then converting back, it's enough
> to update only out-values and out-sizes. So, an update_out parameter is
> added to the conversion functions to tell if all or only some fields
> must be copied.

Is this patch just a refactoring of TEE params handling? Or are we
fixing a real ABI issue here? Also, is this required for restricted
shared memory support to work? Just asking if we want to consider it
as a fix for backporting or if we can handle this refactoring patch
independently of this series?

-Sumit

>
> Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> ---
>  drivers/tee/optee/call.c          | 10 ++--
>  drivers/tee/optee/ffa_abi.c       | 43 +++++++++++++----
>  drivers/tee/optee/optee_private.h | 42 +++++++++++------
>  drivers/tee/optee/rpc.c           | 31 +++++++++----
>  drivers/tee/optee/smc_abi.c       | 76 +++++++++++++++++++++++--------
>  5 files changed, 144 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
> index 16eb953e14bb..f1533b894726 100644
> --- a/drivers/tee/optee/call.c
> +++ b/drivers/tee/optee/call.c
> @@ -400,7 +400,8 @@ int optee_open_session(struct tee_context *ctx,
>         export_uuid(msg_arg->params[1].u.octets, &client_uuid);
>
>         rc = optee->ops->to_msg_param(optee, msg_arg->params + 2,
> -                                     arg->num_params, param);
> +                                     arg->num_params, param,
> +                                     false /*!update_out*/);
>         if (rc)
>                 goto out;
>
> @@ -427,7 +428,8 @@ int optee_open_session(struct tee_context *ctx,
>         }
>
>         if (optee->ops->from_msg_param(optee, param, arg->num_params,
> -                                      msg_arg->params + 2)) {
> +                                      msg_arg->params + 2,
> +                                      true /*update_out*/)) {
>                 arg->ret = TEEC_ERROR_COMMUNICATION;
>                 arg->ret_origin = TEEC_ORIGIN_COMMS;
>                 /* Close session again to avoid leakage */
> @@ -541,7 +543,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
>         msg_arg->cancel_id = arg->cancel_id;
>
>         rc = optee->ops->to_msg_param(optee, msg_arg->params, arg->num_params,
> -                                     param);
> +                                     param, false /*!update_out*/);
>         if (rc)
>                 goto out;
>
> @@ -551,7 +553,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
>         }
>
>         if (optee->ops->from_msg_param(optee, param, arg->num_params,
> -                                      msg_arg->params)) {
> +                                      msg_arg->params, true /*update_out*/)) {
>                 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
>                 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
>         }
> diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
> index f3af5666bb11..02e6175ac5f0 100644
> --- a/drivers/tee/optee/ffa_abi.c
> +++ b/drivers/tee/optee/ffa_abi.c
> @@ -122,15 +122,21 @@ static int optee_shm_rem_ffa_handle(struct optee *optee, u64 global_id)
>   */
>
>  static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> -                                  u32 attr, const struct optee_msg_param *mp)
> +                                  u32 attr, const struct optee_msg_param *mp,
> +                                  bool update_out)
>  {
>         struct tee_shm *shm = NULL;
>         u64 offs_high = 0;
>         u64 offs_low = 0;
>
> +       if (update_out) {
> +               if (attr == OPTEE_MSG_ATTR_TYPE_FMEM_INPUT)
> +                       return;
> +               goto out;
> +       }
> +
>         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
>                   attr - OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
> -       p->u.memref.size = mp->u.fmem.size;
>
>         if (mp->u.fmem.global_id != OPTEE_MSG_FMEM_INVALID_GLOBAL_ID)
>                 shm = optee_shm_from_ffa_handle(optee, mp->u.fmem.global_id);
> @@ -141,6 +147,8 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
>                 offs_high = mp->u.fmem.offs_high;
>         }
>         p->u.memref.shm_offs = offs_low | offs_high << 32;
> +out:
> +       p->u.memref.size = mp->u.fmem.size;
>  }
>
>  /**
> @@ -150,12 +158,14 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
>   * @params:    subsystem internal parameter representation
>   * @num_params:        number of elements in the parameter arrays
>   * @msg_params:        OPTEE_MSG parameters
> + * @update_out: update parameter for output only
>   *
>   * Returns 0 on success or <0 on failure
>   */
>  static int optee_ffa_from_msg_param(struct optee *optee,
>                                     struct tee_param *params, size_t num_params,
> -                                   const struct optee_msg_param *msg_params)
> +                                   const struct optee_msg_param *msg_params,
> +                                   bool update_out)
>  {
>         size_t n;
>
> @@ -166,18 +176,20 @@ static int optee_ffa_from_msg_param(struct optee *optee,
>
>                 switch (attr) {
>                 case OPTEE_MSG_ATTR_TYPE_NONE:
> +                       if (update_out)
> +                               break;
>                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
>                         memset(&p->u, 0, sizeof(p->u));
>                         break;
>                 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
>                 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
>                 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
> -                       optee_from_msg_param_value(p, attr, mp);
> +                       optee_from_msg_param_value(p, attr, mp, update_out);
>                         break;
>                 case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
>                 case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
>                 case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
> -                       from_msg_param_ffa_mem(optee, p, attr, mp);
> +                       from_msg_param_ffa_mem(optee, p, attr, mp, update_out);
>                         break;
>                 default:
>                         return -EINVAL;
> @@ -188,10 +200,16 @@ static int optee_ffa_from_msg_param(struct optee *optee,
>  }
>
>  static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> -                               const struct tee_param *p)
> +                               const struct tee_param *p, bool update_out)
>  {
>         struct tee_shm *shm = p->u.memref.shm;
>
> +       if (update_out) {
> +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> +                       return 0;
> +               goto out;
> +       }
> +
>         mp->attr = OPTEE_MSG_ATTR_TYPE_FMEM_INPUT + p->attr -
>                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
>
> @@ -211,6 +229,7 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
>                 memset(&mp->u, 0, sizeof(mp->u));
>                 mp->u.fmem.global_id = OPTEE_MSG_FMEM_INVALID_GLOBAL_ID;
>         }
> +out:
>         mp->u.fmem.size = p->u.memref.size;
>
>         return 0;
> @@ -222,13 +241,15 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
>   * @optee:     main service struct
>   * @msg_params:        OPTEE_MSG parameters
>   * @num_params:        number of elements in the parameter arrays
> - * @params:    subsystem itnernal parameter representation
> + * @params:    subsystem internal parameter representation
> + * @update_out: update parameter for output only
>   * Returns 0 on success or <0 on failure
>   */
>  static int optee_ffa_to_msg_param(struct optee *optee,
>                                   struct optee_msg_param *msg_params,
>                                   size_t num_params,
> -                                 const struct tee_param *params)
> +                                 const struct tee_param *params,
> +                                 bool update_out)
>  {
>         size_t n;
>
> @@ -238,18 +259,20 @@ static int optee_ffa_to_msg_param(struct optee *optee,
>
>                 switch (p->attr) {
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
> +                       if (update_out)
> +                               break;
>                         mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
>                         memset(&mp->u, 0, sizeof(mp->u));
>                         break;
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
> -                       optee_to_msg_param_value(mp, p);
> +                       optee_to_msg_param_value(mp, p, update_out);
>                         break;
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
> -                       if (to_msg_param_ffa_mem(mp, p))
> +                       if (to_msg_param_ffa_mem(mp, p, update_out))
>                                 return -EINVAL;
>                         break;
>                 default:
> diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
> index dc0f355ef72a..20eda508dbac 100644
> --- a/drivers/tee/optee/optee_private.h
> +++ b/drivers/tee/optee/optee_private.h
> @@ -185,10 +185,12 @@ struct optee_ops {
>                                 bool system_thread);
>         int (*to_msg_param)(struct optee *optee,
>                             struct optee_msg_param *msg_params,
> -                           size_t num_params, const struct tee_param *params);
> +                           size_t num_params, const struct tee_param *params,
> +                           bool update_out);
>         int (*from_msg_param)(struct optee *optee, struct tee_param *params,
>                               size_t num_params,
> -                             const struct optee_msg_param *msg_params);
> +                             const struct optee_msg_param *msg_params,
> +                             bool update_out);
>  };
>
>  /**
> @@ -316,23 +318,35 @@ void optee_release(struct tee_context *ctx);
>  void optee_release_supp(struct tee_context *ctx);
>
>  static inline void optee_from_msg_param_value(struct tee_param *p, u32 attr,
> -                                             const struct optee_msg_param *mp)
> +                                             const struct optee_msg_param *mp,
> +                                             bool update_out)
>  {
> -       p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
> -                 attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> -       p->u.value.a = mp->u.value.a;
> -       p->u.value.b = mp->u.value.b;
> -       p->u.value.c = mp->u.value.c;
> +       if (!update_out)
> +               p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
> +                         attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> +
> +       if (attr == OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT ||
> +           attr == OPTEE_MSG_ATTR_TYPE_VALUE_INOUT || !update_out) {
> +               p->u.value.a = mp->u.value.a;
> +               p->u.value.b = mp->u.value.b;
> +               p->u.value.c = mp->u.value.c;
> +       }
>  }
>
>  static inline void optee_to_msg_param_value(struct optee_msg_param *mp,
> -                                           const struct tee_param *p)
> +                                           const struct tee_param *p,
> +                                           bool update_out)
>  {
> -       mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
> -                  TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> -       mp->u.value.a = p->u.value.a;
> -       mp->u.value.b = p->u.value.b;
> -       mp->u.value.c = p->u.value.c;
> +       if (!update_out)
> +               mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
> +                          TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> +
> +       if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
> +           p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT || !update_out) {
> +               mp->u.value.a = p->u.value.a;
> +               mp->u.value.b = p->u.value.b;
> +               mp->u.value.c = p->u.value.c;
> +       }
>  }
>
>  void optee_cq_init(struct optee_call_queue *cq, int thread_count);
> diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
> index ebbbd42b0e3e..580e6b9b0606 100644
> --- a/drivers/tee/optee/rpc.c
> +++ b/drivers/tee/optee/rpc.c
> @@ -63,7 +63,7 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
>         }
>
>         if (optee->ops->from_msg_param(optee, params, arg->num_params,
> -                                      arg->params))
> +                                      arg->params, false /*!update_out*/))
>                 goto bad;
>
>         for (i = 0; i < arg->num_params; i++) {
> @@ -107,7 +107,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
>         } else {
>                 params[3].u.value.a = msg.len;
>                 if (optee->ops->to_msg_param(optee, arg->params,
> -                                            arg->num_params, params))
> +                                            arg->num_params, params,
> +                                            true /*update_out*/))
>                         arg->ret = TEEC_ERROR_BAD_PARAMETERS;
>                 else
>                         arg->ret = TEEC_SUCCESS;
> @@ -188,6 +189,7 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
>  static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
>                                 struct optee_msg_arg *arg)
>  {
> +       bool update_out = false;
>         struct tee_param *params;
>
>         arg->ret_origin = TEEC_ORIGIN_COMMS;
> @@ -200,15 +202,21 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
>         }
>
>         if (optee->ops->from_msg_param(optee, params, arg->num_params,
> -                                      arg->params)) {
> +                                      arg->params, update_out)) {
>                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
>                 goto out;
>         }
>
>         arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
>
> +       /*
> +        * Special treatment for OPTEE_RPC_CMD_SHM_ALLOC since input is a
> +        * value type, but the output is a memref type.
> +        */
> +       if (arg->cmd != OPTEE_RPC_CMD_SHM_ALLOC)
> +               update_out = true;
>         if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
> -                                    params))
> +                                    params, update_out))
>                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
>  out:
>         kfree(params);
> @@ -270,7 +278,7 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
>
>         if (arg->num_params != ARRAY_SIZE(params) ||
>             optee->ops->from_msg_param(optee, params, arg->num_params,
> -                                      arg->params) ||
> +                                      arg->params, false /*!update_out*/) ||
>             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT) {
>                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
>                 return;
> @@ -280,7 +288,8 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
>         params[0].u.value.b = 0;
>         params[0].u.value.c = 0;
>         if (optee->ops->to_msg_param(optee, arg->params,
> -                                    arg->num_params, params)) {
> +                                    arg->num_params, params,
> +                                    true /*update_out*/)) {
>                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
>                 return;
>         }
> @@ -324,7 +333,7 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
>
>         if (arg->num_params != ARRAY_SIZE(params) ||
>             optee->ops->from_msg_param(optee, params, arg->num_params,
> -                                      arg->params) ||
> +                                      arg->params, false /*!update_out*/) ||
>             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
>             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
>                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> @@ -358,7 +367,8 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
>         params[0].u.value.b = rdev->descr.capacity;
>         params[0].u.value.c = rdev->descr.reliable_wr_count;
>         if (optee->ops->to_msg_param(optee, arg->params,
> -                                    arg->num_params, params)) {
> +                                    arg->num_params, params,
> +                                    true /*update_out*/)) {
>                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
>                 return;
>         }
> @@ -384,7 +394,7 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
>
>         if (arg->num_params != ARRAY_SIZE(params) ||
>             optee->ops->from_msg_param(optee, params, arg->num_params,
> -                                      arg->params) ||
> +                                      arg->params, false /*!update_out*/) ||
>             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT ||
>             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
>                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> @@ -401,7 +411,8 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
>                 goto out;
>         }
>         if (optee->ops->to_msg_param(optee, arg->params,
> -                                    arg->num_params, params)) {
> +                                    arg->num_params, params,
> +                                    true /*update_out*/)) {
>                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
>                 goto out;
>         }
> diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
> index e9456e3e74cc..d1f79947f58a 100644
> --- a/drivers/tee/optee/smc_abi.c
> +++ b/drivers/tee/optee/smc_abi.c
> @@ -81,20 +81,26 @@ static int optee_cpuhp_disable_pcpu_irq(unsigned int cpu)
>   */
>
>  static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
> -                                 const struct optee_msg_param *mp)
> +                                 const struct optee_msg_param *mp,
> +                                 bool update_out)
>  {
>         struct tee_shm *shm;
>         phys_addr_t pa;
>         int rc;
>
> +       if (update_out) {
> +               if (attr == OPTEE_MSG_ATTR_TYPE_TMEM_INPUT)
> +                       return 0;
> +               goto out;
> +       }
> +
>         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
>                   attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
> -       p->u.memref.size = mp->u.tmem.size;
>         shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
>         if (!shm) {
>                 p->u.memref.shm_offs = 0;
>                 p->u.memref.shm = NULL;
> -               return 0;
> +               goto out;
>         }
>
>         rc = tee_shm_get_pa(shm, 0, &pa);
> @@ -103,18 +109,25 @@ static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
>
>         p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
>         p->u.memref.shm = shm;
> -
> +out:
> +       p->u.memref.size = mp->u.tmem.size;
>         return 0;
>  }
>
>  static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> -                                  const struct optee_msg_param *mp)
> +                                  const struct optee_msg_param *mp,
> +                                  bool update_out)
>  {
>         struct tee_shm *shm;
>
> +       if (update_out) {
> +               if (attr == OPTEE_MSG_ATTR_TYPE_RMEM_INPUT)
> +                       return;
> +               goto out;
> +       }
> +
>         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
>                   attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
> -       p->u.memref.size = mp->u.rmem.size;
>         shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
>
>         if (shm) {
> @@ -124,6 +137,8 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
>                 p->u.memref.shm_offs = 0;
>                 p->u.memref.shm = NULL;
>         }
> +out:
> +       p->u.memref.size = mp->u.rmem.size;
>  }
>
>  /**
> @@ -133,11 +148,13 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
>   * @params:    subsystem internal parameter representation
>   * @num_params:        number of elements in the parameter arrays
>   * @msg_params:        OPTEE_MSG parameters
> + * @update_out:        update parameter for output only
>   * Returns 0 on success or <0 on failure
>   */
>  static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
>                                 size_t num_params,
> -                               const struct optee_msg_param *msg_params)
> +                               const struct optee_msg_param *msg_params,
> +                               bool update_out)
>  {
>         int rc;
>         size_t n;
> @@ -149,25 +166,27 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
>
>                 switch (attr) {
>                 case OPTEE_MSG_ATTR_TYPE_NONE:
> +                       if (update_out)
> +                               break;
>                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
>                         memset(&p->u, 0, sizeof(p->u));
>                         break;
>                 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
>                 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
>                 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
> -                       optee_from_msg_param_value(p, attr, mp);
> +                       optee_from_msg_param_value(p, attr, mp, update_out);
>                         break;
>                 case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
>                 case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
>                 case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
> -                       rc = from_msg_param_tmp_mem(p, attr, mp);
> +                       rc = from_msg_param_tmp_mem(p, attr, mp, update_out);
>                         if (rc)
>                                 return rc;
>                         break;
>                 case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
>                 case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
>                 case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
> -                       from_msg_param_reg_mem(p, attr, mp);
> +                       from_msg_param_reg_mem(p, attr, mp, update_out);
>                         break;
>
>                 default:
> @@ -178,20 +197,25 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
>  }
>
>  static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
> -                               const struct tee_param *p)
> +                               const struct tee_param *p, bool update_out)
>  {
>         int rc;
>         phys_addr_t pa;
>
> +       if (update_out) {
> +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> +                       return 0;
> +               goto out;
> +       }
> +
>         mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
>                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
>
>         mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
> -       mp->u.tmem.size = p->u.memref.size;
>
>         if (!p->u.memref.shm) {
>                 mp->u.tmem.buf_ptr = 0;
> -               return 0;
> +               goto out;
>         }
>
>         rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa);
> @@ -201,19 +225,27 @@ static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
>         mp->u.tmem.buf_ptr = pa;
>         mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
>                     OPTEE_MSG_ATTR_CACHE_SHIFT;
> -
> +out:
> +       mp->u.tmem.size = p->u.memref.size;
>         return 0;
>  }
>
>  static int to_msg_param_reg_mem(struct optee_msg_param *mp,
> -                               const struct tee_param *p)
> +                               const struct tee_param *p, bool update_out)
>  {
> +       if (update_out) {
> +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> +                       return 0;
> +               goto out;
> +       }
> +
>         mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
>                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
>
>         mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm;
> -       mp->u.rmem.size = p->u.memref.size;
>         mp->u.rmem.offs = p->u.memref.shm_offs;
> +out:
> +       mp->u.rmem.size = p->u.memref.size;
>         return 0;
>  }
>
> @@ -223,11 +255,13 @@ static int to_msg_param_reg_mem(struct optee_msg_param *mp,
>   * @msg_params:        OPTEE_MSG parameters
>   * @num_params:        number of elements in the parameter arrays
>   * @params:    subsystem itnernal parameter representation
> + * @update_out:        update parameter for output only
>   * Returns 0 on success or <0 on failure
>   */
>  static int optee_to_msg_param(struct optee *optee,
>                               struct optee_msg_param *msg_params,
> -                             size_t num_params, const struct tee_param *params)
> +                             size_t num_params, const struct tee_param *params,
> +                             bool update_out)
>  {
>         int rc;
>         size_t n;
> @@ -238,21 +272,23 @@ static int optee_to_msg_param(struct optee *optee,
>
>                 switch (p->attr) {
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
> +                       if (update_out)
> +                               break;
>                         mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
>                         memset(&mp->u, 0, sizeof(mp->u));
>                         break;
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
> -                       optee_to_msg_param_value(mp, p);
> +                       optee_to_msg_param_value(mp, p, update_out);
>                         break;
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
>                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
>                         if (tee_shm_is_dynamic(p->u.memref.shm))
> -                               rc = to_msg_param_reg_mem(mp, p);
> +                               rc = to_msg_param_reg_mem(mp, p, update_out);
>                         else
> -                               rc = to_msg_param_tmp_mem(mp, p);
> +                               rc = to_msg_param_tmp_mem(mp, p, update_out);
>                         if (rc)
>                                 return rc;
>                         break;
> --
> 2.43.0
>


From mchehab+huawei at kernel.org  Tue Dec  3 00:31:20 2024
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Tue, 3 Dec 2024 09:31:20 +0100
Subject: [PATCH 1/3] media: cx231xx: Convert enum into a define
In-Reply-To: <20241202-fix-llvm9-v1-1-2a50f5acfd0b@chromium.org>
References: <20241202-fix-llvm9-v1-0-2a50f5acfd0b@chromium.org>
	<20241202-fix-llvm9-v1-1-2a50f5acfd0b@chromium.org>
Message-ID: <20241203093114.0ca49c01@foz.lan>

Em Mon, 02 Dec 2024 15:47:15 +0000
Ricardo Ribalda <ribalda at chromium.org> escreveu:

> The code is running arithmentics with the enum, which when not done with
> care makes the compiler a bit nervous.
> 
> Because those enums are only used as defines (no argument or variable
> from that enumeration type), convert it into a define and move on.
> 
> It is required to build with llvm 9 without these warnings:
> drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:673:17: warning: bitwise operation between different enumeration types ('enum TS_PORT' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
> drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:680:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
> drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:687:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
> drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:702:17: warning: bitwise operation between different enumeration types ('enum TS_PORT' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
> drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:709:21: warning: bitwise operation between different enumeration types ('enum TS_PORT' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
> drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:718:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum POWE_TYPE') [-Wenum-enum-conversion]
> drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:727:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum TS_PORT') [-Wenum-enum-conversion]
> drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:737:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum TS_PORT') [-Wenum-enum-conversion]
> drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c:749:21: warning: bitwise operation between different enumeration types ('enum AVDEC_STATUS' and 'enum TS_PORT') [-Wenum-enum-conversion]
> 
> Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
> ---
>  drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h | 18 +++++++-----------
>  1 file changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
> index 5bc44f194d0a..62ffa16bb82c 100644
> --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
> +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
> @@ -57,19 +57,17 @@ enum USB_SPEED{
>  };
>  
>  #define TS_MASK         0x6
> -enum TS_PORT{
> -	NO_TS_PORT = 0x0,	/* 2'b00: Neither port used. PCB not a Hybrid,
> +#define NO_TS_PORT	0x0	/* 2'b00: Neither port used. PCB not a Hybrid,
>  				   only offers Analog TV or Video */
> -	TS1_PORT = 0x4,		/* 2'b10: TS1 Input (Hybrid mode :
> +#define TS1_PORT	0x4	/* 2'b10: TS1 Input (Hybrid mode :
>  				Digital or External Analog/Compressed source) */
> -	TS1_TS2_PORT = 0x6,	/* 2'b11: TS1 & TS2 Inputs
> +#define TS1_TS2_PORT	0x6	/* 2'b11: TS1 & TS2 Inputs
>  				(Dual inputs from Digital and/or
>  				External Analog/Compressed sources) */
> -	TS1_EXT_CLOCK = 0x6,	/* 2'b11: TS1 & TS2 as selector
> +#define TS1_EXT_CLOCK	0x6	/* 2'b11: TS1 & TS2 as selector
>  						to external clock */
> -	TS1VIP_TS2_PORT = 0x2	/* 2'b01: TS1 used as 656/VIP Output,
> +#define TS1VIP_TS2_PORT 0x2	/* 2'b01: TS1 used as 656/VIP Output,
>  				   TS2 Input (from Compressor) */
> -};
>  
>  #define EAVP_MASK       0x8
>  enum EAV_PRESENT{
> @@ -89,10 +87,8 @@ enum AT_MODE{
>  };
>  
>  #define PWR_SEL_MASK    0x40
> -enum POWE_TYPE{
> -	SELF_POWER = 0x0,	/* 0: self power */
> -	BUS_POWER = 0x40	/* 1: bus power */
> -};
> +#define SELF_POWER	0x0	/* 0: self power */
> +#define BUS_POWER	0x40	/* 1: bus power */
>  
>  enum USB_POWE_TYPE{
>  	USB_SELF_POWER = 0,
> 

IMO keeping them into enums are a lot better than defines.

Perhaps the right thing would be to join both enums here.


Thanks,
Mauro


From YeoReum.Yun at arm.com  Tue Dec  3 00:31:54 2024
From: YeoReum.Yun at arm.com (Yeo Reum Yun)
Date: Tue, 3 Dec 2024 08:31:54 +0000
Subject: [PATCH 1/9] coresight: change coresight_device lock type to
 raw_spinlock_t
In-Reply-To: <20241202103853.26db0c13@gandalf.local.home>
References: <20241125094816.365472-1-yeoreum.yun@arm.com>
	<20241125094816.365472-2-yeoreum.yun@arm.com>
	<20241127120954.0facd34f@gandalf.local.home>
	<GV1PR08MB10521520ABD7B72D92FD60DE9FB292@GV1PR08MB10521.eurprd08.prod.outlook.com>
 <20241202103853.26db0c13@gandalf.local.home>
Message-ID: <GV1PR08MB105212FEF9251CA2B3AAF7FFFFB362@GV1PR08MB10521.eurprd08.prod.outlook.com>

Hi Steve,

> Still should be documented somewhere. It should describe the maximum number
> of feats that will ever be loaded. If there's a max, it makes it back to
> O(1). With a 'k' of how long it takes to process the max number of feats.

But with other patchset seems better
since not only this function, but also for other functions too.

BTW, is there any example describing this I can refer? 

Thanks

From claudiu.beznea at tuxon.dev  Tue Dec  3 00:37:37 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Tue, 3 Dec 2024 10:37:37 +0200
Subject: [PATCH 2/2] ARM: dts: microchip: sam9x75_curiosity: Add power
 monitor support
In-Reply-To: <PH8PR11MB68043702680864433060E9B482352@PH8PR11MB6804.namprd11.prod.outlook.com>
References: <20241122080523.3941-1-mihai.sain@microchip.com>
 <20241122080523.3941-3-mihai.sain@microchip.com>
 <2d8dd1c8-fd4b-4dc1-ba62-312ac86335a6@tuxon.dev>
 <PH8PR11MB68043702680864433060E9B482352@PH8PR11MB6804.namprd11.prod.outlook.com>
Message-ID: <b1e053da-04dd-4b66-86c4-60e1d6b5a5a2@tuxon.dev>

Hi, Mihai,

On 02.12.2024 10:32, Mihai.Sain at microchip.com wrote:
> Hi Claudiu,
> 
>>> +             channel at 2 {
>>> +                     reg = <0x2>;
>>> +                     shunt-resistor-micro-ohms = <10000>;
>>> +                     label = "VDDOUT4";
>>
>> On the schematics at [1] this seems to be named DCDC4. Is there a mistake on
>> [1] or this patch needs adjustments? If so, I can do it while applying.
> 
> I just wanted to use a more friendly name for buck4, since this regulator is not used.

For consistency with the rest of the channel names and the fact that we
describe the HW though device tree, I would keep the schematics naming
("DCDC4" in this case). No need to re-send, I can adjust while applying.
Just let me know if all good with you, too.

Thank you,
Claudiu

> 
>>
>> Thank you,
>> Claudiu
>>
>> [1]
>> https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocumen
>> ts/UserGuides/SAM9X75-Curiosity-User-Guide-DS60001859.pdf
>>
> 
> Regards,
> Mihai


From rppt at kernel.org  Tue Dec  3 00:55:19 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Tue, 3 Dec 2024 10:55:19 +0200
Subject: [PATCH] arm64: patching: avoid early page_to_phys()
In-Reply-To: <20241203004611.GA8116@lst.de>
References: <20241202170359.1475019-1-mark.rutland@arm.com>
 <20241203004611.GA8116@lst.de>
Message-ID: <Z07Hd0UR3mQQW1f7@kernel.org>

On Tue, Dec 03, 2024 at 01:46:11AM +0100, Christoph Hellwig wrote:
> On Mon, Dec 02, 2024 at 05:03:59PM +0000, Mark Rutland wrote:
> > +	phys_addr_t phys;
> > +
> > +	if (is_image_text((unsigned long)addr)) {
> > +		phys = __pa_symbol(addr);
> > +	} else {
> > +		struct page *page = vmalloc_to_page(addr);
> > +		BUG_ON(!page);
> > +		phys = page_to_phys(page) + offset_in_page(addr);
> > +	}
> > +
> > +	return (void *)set_fixmap_offset(fixmap, phys);
> 
> This looks much better.  Btw, I recently open coded the vmalloc to phys
> logic above in an unrelated fix, and noticed that
> arch/powerpc/mm/pgtable.c has a nice vmalloc_to_phys that could
> be generalized and move to common code.  Does anyone have an opinion
> on that?

Maybe fold that check for !page into vmalloc_to_pfn() and make
vmalloc_to_phys() a static inline?
 
-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Tue Dec  3 00:56:52 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Tue, 3 Dec 2024 10:56:52 +0200
Subject: [PATCH] arm64: patching: avoid early page_to_phys()
In-Reply-To: <Z03tNWwlOz3Iil9J@J2N7QTR9R3>
References: <20241202170359.1475019-1-mark.rutland@arm.com>
 <Z03tNWwlOz3Iil9J@J2N7QTR9R3>
Message-ID: <Z07H1Gkzp-6fMlY-@kernel.org>

On Mon, Dec 02, 2024 at 05:45:11PM +0000, Mark Rutland wrote:
> Looks like I messed up my text editing and left some bonus words...
> 
> On Mon, Dec 02, 2024 at 05:03:59PM +0000, Mark Rutland wrote:
> > When arm64 is configured with CONFIG_DEBUG_VIRTUAL=y, a warning is
> > printed from the patching code because patch_map(), e.g.
> 
> That was meant to say:
> 
> | When arm64 is configured with CONFIG_DEBUG_VIRTUAL=y, a warning is
> | printed from the patching code, e.g.
> 
> [...]
> 
> > For historical reasons, the structure of patch_map() is more complicated
> > than necessary and can be simplified. For kernel image addresses it's
> > sufficient to use __pa_symbol() directly without converting this to a
> > page address and back. Aside from kernel image addresses, all executable
> > code should be allocated from execmem (where all allocations will fall
> > within the vmalloc area), and the vmalloc area), and so there's no need
> > for the fallback case when case when CONFIG_EXECMEM=n.
> 
> That last sentence should have been:
> 
> | Aside from kernel image addresses, all executable code should be
> | allocated from execmem (where all allocations will fall within the
> | vmalloc area), and so there's no need for the fallback case when case
> | when CONFIG_EXECMEM=n.

Still an extra "case when" ;-)
 
> I can spin a v2 with those fixed if necessary.
> 
> Mark.

-- 
Sincerely yours,
Mike.


From gshan at redhat.com  Tue Dec  3 00:56:49 2024
From: gshan at redhat.com (Gavin Shan)
Date: Tue, 3 Dec 2024 18:56:49 +1000
Subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module
 loading
In-Reply-To: <202412031348.bp5i3ws2-lkp@intel.com>
References: <20241203000156.72451-2-jeremy.linton@arm.com>
 <202412031348.bp5i3ws2-lkp@intel.com>
Message-ID: <b1923d68-726a-4864-8661-54588a634d95@redhat.com>



On 12/3/24 4:03 PM, kernel test robot wrote:
> Hi Jeremy,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on arm64/for-next/core]
> [also build test WARNING on linus/master v6.13-rc1 next-20241128]
> [cannot apply to kvmarm/next soc/for-next arm/for-next arm/fixes]
> [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/Jeremy-Linton/arm64-rsi-Add-automatic-arm-cca-guest-module-loading/20241203-080347
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
> patch link:    https://lore.kernel.org/r/20241203000156.72451-2-jeremy.linton%40arm.com
> patch subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module loading
> config: arm64-randconfig-004-20241203 (https://download.01.org/0day-ci/archive/20241203/202412031348.bp5i3ws2-lkp at intel.com/config)
> compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241203/202412031348.bp5i3ws2-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/202412031348.bp5i3ws2-lkp at intel.com/
> 
> All warnings (new ones prefixed by >>):
> 
>>> drivers/virt/coco/arm-cca-guest/arm-cca-guest.c:224:21: warning: attribute declaration must precede definition [-Wignored-attributes]
>       224 | static const struct __maybe_unused platform_device_id arm_cca_match[] = {
>           |                     ^
>     include/linux/compiler_attributes.h:356:56: note: expanded from macro '__maybe_unused'
>       356 | #define __maybe_unused                  __attribute__((__unused__))
>           |                                                        ^
>     include/linux/mod_devicetable.h:607:8: note: previous definition is here
>       607 | struct platform_device_id {
>           |        ^
>>> drivers/virt/coco/arm-cca-guest/arm-cca-guest.c:224:55: warning: unused variable 'arm_cca_match' [-Wunused-const-variable]
>       224 | static const struct __maybe_unused platform_device_id arm_cca_match[] = {
>           |                                                       ^~~~~~~~~~~~~
>     2 warnings generated.
> 
> 
> vim +224 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
> 
>     222	
>     223	/* modalias, so userspace can autoload this module when RSI is available */
>   > 224	static const struct __maybe_unused platform_device_id arm_cca_match[] = {
>     225		{ RSI_PDEV_NAME, 0},
>     226		{ }
>     227	};
>     228	
> 

The definition may have to be something like below, to avoid the compiling warning.

static const struct platform_device_id __maybe_unused arm_cca_match[] = {
        ...
};

Thanks,
Gavin



From andrej.picej at norik.com  Tue Dec  3 00:58:22 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue,  3 Dec 2024 09:58:22 +0100
Subject: [PATCH v2 3/3] arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing
In-Reply-To: <20241203085822.2475138-1-andrej.picej@norik.com>
References: <20241203085822.2475138-1-andrej.picej@norik.com>
Message-ID: <20241203085822.2475138-4-andrej.picej@norik.com>

Set custom differential output voltage for LVDS, to fulfill requirements
of the connected display. LVDS differential voltage for data-lanes and
clock output has to be between 200 mV and 600 mV.
Driver sets 200 Ohm near-end termination by default.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
- use new properties from previous patches
---
 .../boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso     | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
index a9de42cf14be..8bf9cc553bea 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
@@ -186,6 +186,8 @@ port at 2 {
 			reg = <2>;
 			bridge_out: endpoint {
 				remote-endpoint = <&panel_in>;
+				ti,lvds-vod-swing-clock-microvolt = <200000 600000>;
+				ti,lvds-vod-swing-data-microvolt = <200000 600000>;
 			};
 		};
 	};
-- 
2.34.1



From andrej.picej at norik.com  Tue Dec  3 00:58:21 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue,  3 Dec 2024 09:58:21 +0100
Subject: [PATCH v2 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
In-Reply-To: <20241203085822.2475138-1-andrej.picej@norik.com>
References: <20241203085822.2475138-1-andrej.picej@norik.com>
Message-ID: <20241203085822.2475138-3-andrej.picej@norik.com>

Add a optional properties to change LVDS output voltage. This should not
be static as this depends mainly on the connected display voltage
requirement. We have three properties:
- "ti,lvds-termination-ohms", which sets near end termination,
- "ti,lvds-vod-swing-data-microvolt" and
- "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
output voltage for data and clock lanes. They are defined as an array
with min and max values. The appropriate bitfiled will be set if
selected constraints can be met.

If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
end termination will be used. Selecting only one:
"ti,lvds-vod-swing-data-microvolt" or
"ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
constraint for only data/clock lanes will be met. Setting both is
recommended.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
- use datasheet tables to get the proper configuration
- since major change was done change the authorship to myself
---
 drivers/gpu/drm/bridge/ti-sn65dsi83.c | 144 +++++++++++++++++++++++++-
 1 file changed, 141 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 57a7ed13f996..44445d7ad52a 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -132,6 +132,16 @@
 #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
 #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
 
+enum sn65dsi83_channel {
+	CHANNEL_A,
+	CHANNEL_B
+};
+
+enum sn65dsi83_lvds_term {
+	OHM_100,
+	OHM_200
+};
+
 enum sn65dsi83_model {
 	MODEL_SN65DSI83,
 	MODEL_SN65DSI84,
@@ -147,6 +157,10 @@ struct sn65dsi83 {
 	struct regulator		*vcc;
 	bool				lvds_dual_link;
 	bool				lvds_dual_link_even_odd_swap;
+	int				lvdsA_vod_swing_conf;
+	int				lvdsB_vod_swing_conf;
+	int				lvdsA_term_conf;
+	int				lvdsB_term_conf;
 };
 
 static const struct regmap_range sn65dsi83_readable_ranges[] = {
@@ -237,6 +251,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
 	.max_register = REG_IRQ_STAT,
 };
 
+static const int lvds_vod_swing_data_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 180000, 313000 },
+		{ 215000, 372000 },
+		{ 250000, 430000 },
+		{ 290000, 488000 },
+	},
+	{	/* 200 Ohm */
+		{ 150000, 261000 },
+		{ 200000, 346000 },
+		{ 250000, 428000 },
+		{ 300000, 511000 },
+	},
+};
+
+static const int lvds_vod_swing_clock_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 140000, 244000 },
+		{ 168000, 290000 },
+		{ 195000, 335000 },
+		{ 226000, 381000 },
+	},
+	{	/* 200 Ohm */
+		{ 117000, 204000 },
+		{ 156000, 270000 },
+		{ 195000, 334000 },
+		{ 234000, 399000 },
+	},
+};
+
 static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
 {
 	return container_of(bridge, struct sn65dsi83, bridge);
@@ -435,12 +479,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
 		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
 
 	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
-	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
+	regmap_write(ctx->regmap, REG_LVDS_VCOM,
+			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvdsA_vod_swing_conf) |
+			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvdsB_vod_swing_conf));
 	regmap_write(ctx->regmap, REG_LVDS_LANE,
 		     (ctx->lvds_dual_link_even_odd_swap ?
 		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
-		     REG_LVDS_LANE_CHA_LVDS_TERM |
-		     REG_LVDS_LANE_CHB_LVDS_TERM);
+		     (ctx->lvdsA_term_conf ?
+			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
+		     (ctx->lvdsB_term_conf ?
+			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
 	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
 
 	le16val = cpu_to_le16(mode->hdisplay);
@@ -576,10 +624,96 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
 	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
 };
 
+static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
+	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
+{
+	int i;
+
+	for (i = 0; i <= 3; i++) {
+		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
+		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
+		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
+		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
+			return i;
+	}
+
+	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
+	return -EINVAL;
+}
+
+static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *endpoint;
+	/* Set so the property can be freely selected if not defined */
+	u32 lvds_vod_swing_data[2] = { 0, 1000 };
+	u32 lvds_vod_swing_clk[2] = { 0, 1000 };
+	u32 lvds_term = 200;
+	u8 lvds_term_conf;
+	int endpoint_reg;
+	int lvds_vod_swing_conf;
+	int ret = 0;
+	int ret_data;
+	int ret_clock;
+
+	if (channel == CHANNEL_A)
+		endpoint_reg = 2;
+	else
+		endpoint_reg = 3;
+
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
+	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
+
+	if (lvds_term == 200)
+		lvds_term_conf = OHM_200;
+	else
+		lvds_term_conf = OHM_100;
+
+	if (channel == CHANNEL_A)
+		ctx->lvdsA_term_conf = lvds_term_conf;
+	else
+		ctx->lvdsB_term_conf = lvds_term_conf;
+
+	ret_data = of_property_read_u32_array(endpoint,
+			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
+			ARRAY_SIZE(lvds_vod_swing_data));
+	ret_clock = of_property_read_u32_array(endpoint,
+			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
+			ARRAY_SIZE(lvds_vod_swing_clk));
+	/* If any of the two properties is defined. */
+	if (!ret_data || !ret_clock) {
+		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
+			lvds_vod_swing_data, lvds_vod_swing_clk,
+			lvds_term_conf);
+		if (lvds_vod_swing_conf < 0) {
+			ret = lvds_vod_swing_conf;
+			goto exit;
+		}
+		if (channel == CHANNEL_A)
+			ctx->lvdsA_vod_swing_conf = lvds_vod_swing_conf;
+		else
+			ctx->lvdsB_vod_swing_conf = lvds_vod_swing_conf;
+	}
+	ret = 0;
+exit:
+	of_node_put(endpoint);
+	return ret;
+}
+
 static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
 {
 	struct drm_bridge *panel_bridge;
 	struct device *dev = ctx->dev;
+	int ret;
+
+	ctx->lvdsA_vod_swing_conf = 0x1;
+	ctx->lvdsB_vod_swing_conf = 0x1;
+	ctx->lvdsA_term_conf = 0x1;
+	ctx->lvdsB_term_conf = 0x1;
+
+	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
+	if (ret < 0)
+		return ret;
 
 	ctx->lvds_dual_link = false;
 	ctx->lvds_dual_link_even_odd_swap = false;
@@ -587,6 +721,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
 		struct device_node *port2, *port3;
 		int dual_link;
 
+		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
+		if (ret < 0)
+			return ret;
+
 		port2 = of_graph_get_port_by_id(dev->of_node, 2);
 		port3 = of_graph_get_port_by_id(dev->of_node, 3);
 		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
-- 
2.34.1



From andrej.picej at norik.com  Tue Dec  3 00:58:20 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue,  3 Dec 2024 09:58:20 +0100
Subject: [PATCH v2 1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for ti,lvds-vod-swing
In-Reply-To: <20241203085822.2475138-1-andrej.picej@norik.com>
References: <20241203085822.2475138-1-andrej.picej@norik.com>
Message-ID: <20241203085822.2475138-2-andrej.picej@norik.com>

Add properties which can be used to specify LVDS differential output
voltage. Since this also depends on near-end signal termination also
include property which sets this. LVDS differential output voltage is
specified with an array (min, max), which should match the one from
connected device.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v2:
- move LVDS port schema to a $defs and reference it from there
- properties are now defined in microvolts/ohms
- use 1 property for data-lane and 1 for clock-lane LVDS voltage swing
- add 1 property which sets LVDS near-end termination
- since major change was done change the authorship to myself
---
 .../bindings/display/bridge/ti,sn65dsi83.yaml | 36 +++++++++++++++++--
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
index 48a97bb3e2e0..6da9b6e3beb9 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
@@ -80,12 +80,12 @@ properties:
                   - const: 4
 
       port at 2:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-A output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
       port at 3:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-B output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
     required:
       - port at 0
@@ -96,6 +96,36 @@ required:
   - reg
   - ports
 
+$defs:
+  lvds-port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    unevaluatedProperties: false
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          ti,lvds-termination-ohms:
+            description: The value of near end differential termination in ohms.
+            enum: [100, 200]
+            default: 200
+
+          ti,lvds-vod-swing-clock-microvolt:
+            description: LVDS diferential output voltage <min max> for clock
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
+          ti,lvds-vod-swing-data-microvolt:
+            description: LVDS diferential output voltage <min max> for data
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
 allOf:
   - if:
       properties:
@@ -120,7 +150,7 @@ allOf:
           properties:
             port at 1: false
 
-additionalProperties: false
+additionalProperties: true
 
 examples:
   - |
-- 
2.34.1



From andrej.picej at norik.com  Tue Dec  3 00:58:19 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue,  3 Dec 2024 09:58:19 +0100
Subject: [PATCH v2 0/3] SN65DSI83/4 lvds_vod_swing properties
Message-ID: <20241203085822.2475138-1-andrej.picej@norik.com>

Hi all,

this is a v2, which is quite different than the v1. The LVDS differential
voltage swing is now specified as arrays of min, max in microvolts. Two
arrays, one for data-lanes and one for clock-lane can be specified.
Additionally, because LVDS voltage swing depends on near-end termination
this can now also be specified with separate property.

Driver goes through the tables, taken from datasheet [1] and selects the
appropriate configuration. If appropriate configuration can not be found
the probe fails. If these properties are not defined default values are
used as before.

v1 is at: https://lore.kernel.org/all/20241127103031.1007893-1-andrej.picej at norik.com/
v2 changes are described in corresponding patches.

[1] https://www.ti.com/lit/ds/symlink/sn65dsi83.pdf?ts=1732738773429&ref_url=https%253A%252F%252Fwww.mouser.co.uk%252F

Best regards,
Andrej

Andrej Picej (3):
  dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for
    ti,lvds-vod-swing
  drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
  arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing

 .../bindings/display/bridge/ti,sn65dsi83.yaml |  36 ++++-
 .../imx8mm-phyboard-polis-peb-av-10.dtso      |   2 +
 drivers/gpu/drm/bridge/ti-sn65dsi83.c         | 144 +++++++++++++++++-
 3 files changed, 176 insertions(+), 6 deletions(-)

-- 
2.34.1



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:09:24 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:09:24 +0100
Subject: [PATCH v4 4/4] arm64: dts: mediatek: Modify audio codec name for
 pmic
In-Reply-To: <20241202032035.29045-5-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
 <20241202032035.29045-5-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <d640a13e-fa08-408f-82ac-fc169e2eb283@collabora.com>

Il 02/12/24 04:20, Zhengqiao Xia ha scritto:
> change `codec` in pmic (in mt8186-corsola.dtsi) to `audio-codec`
> 
> Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>


Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:09:23 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:09:23 +0100
Subject: [PATCH v4 2/4] arm64: dts: mediatek: Add MT8186 Chinchou
 Chromebooks
In-Reply-To: <20241202032035.29045-3-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
 <20241202032035.29045-3-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <9f55bfdb-d4c5-48d2-8a6b-fee5dc147d94@collabora.com>

Il 02/12/24 04:20, Zhengqiao Xia ha scritto:
> MT8186 chinchou, known as ASUS Chromebook CZ12 Flip (CZ1204F)
> and CZ12(CZ1204C), is a MT8186 based laptop.
> It is based on the "corsola" design.It includes chinchou and chinchou360,
> including LTE, stylus, touchscreen combinations.
> 
> Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
> ---
>   arch/arm64/boot/dts/mediatek/Makefile         |   3 +
>   .../mediatek/mt8186-corsola-chinchou-sku0.dts |  18 +
>   .../mediatek/mt8186-corsola-chinchou-sku1.dts |  35 ++
>   .../mt8186-corsola-chinchou-sku16.dts         |  29 ++
>   .../dts/mediatek/mt8186-corsola-chinchou.dtsi | 321 ++++++++++++++++++
>   5 files changed, 406 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
>   create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
>   create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts
>   create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi
> 
> diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> index 8fd7b2bb7a15..0db7770e8907 100644
> --- a/arch/arm64/boot/dts/mediatek/Makefile
> +++ b/arch/arm64/boot/dts/mediatek/Makefile
> @@ -55,6 +55,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb
> diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
> new file mode 100644
> index 000000000000..5d012bc4ff0d
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
> @@ -0,0 +1,18 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright 2024 Google LLC
> + */
> +
> +/dts-v1/;
> +#include "mt8186-corsola-chinchou.dtsi"
> +
> +/ {
> +	model = "Google chinchou CZ1104CM2A/CZ1204CM2A";
> +	compatible = "google,chinchou-sku0", "google,chinchou-sku2",
> +			"google,chinchou-sku4", "google,chinchou-sku5",
> +			"google,chinchou", "mediatek,mt8186";
> +};
> +
> +&gpio_keys {
> +	status = "disabled";
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
> new file mode 100644
> index 000000000000..c18f473f6a0f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
> @@ -0,0 +1,35 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright 2024 Google LLC
> + */
> +
> +/dts-v1/;
> +#include "mt8186-corsola-chinchou.dtsi"
> +
> +/ {
> +	model = "Google chinchou CZ1104FM2A/CZ1204FM2A/CZ1104CM2A/CZ1204CM2A";
> +	compatible = "google,chinchou-sku1", "google,chinchou-sku17",

As pointed out in the binding review, please move SKU17 after 7, before 20.

> +			"google,chinchou-sku3", "google,chinchou-sku6",
> +			"google,chinchou-sku7", "google,chinchou-sku20",
> +			"google,chinchou-sku22", "google,chinchou-sku23",
> +			"google,chinchou", "mediatek,mt8186";
> +};
> +

..snip..

> diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi
> new file mode 100644
> index 000000000000..c3835c7c4444
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi
> @@ -0,0 +1,321 @@

..snip..

> +
> +&mmc1_pins_default {
> +	pins-clk {
> +		drive-strength = <MTK_DRIVE_8mA>;

Please do not use the MTK_DRIVE_xxx definitions.

This is just `drive-strength = <8>;`

> +	};
> +
> +	pins-cmd-dat {
> +		drive-strength = <MTK_DRIVE_8mA>;
> +	};
> +};
> +
> +&mmc1_pins_uhs {
> +	pins-clk {
> +		drive-strength = <MTK_DRIVE_8mA>;
> +	};
> +
> +	pins-cmd-dat {
> +		drive-strength = <MTK_DRIVE_8mA>;
> +	};
> +};
> +
Everything else looks good.

Cheers,
Angelo


From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:09:27 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:09:27 +0100
Subject: [PATCH v4 3/4] arm64: dts: mediatek: Add exton node for DP bridge
In-Reply-To: <20241202032035.29045-4-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
 <20241202032035.29045-4-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <9c560103-4930-4cdf-b7f5-1c75785b7216@collabora.com>

Il 02/12/24 04:20, Zhengqiao Xia ha scritto:
> Add exton node for DP bridge to make the display work properly.
> 
> Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:09:28 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:09:28 +0100
Subject: [PATCH v4 1/4] dt-bindings: arm: mediatek: Add MT8186 Chinchou
 Chromebook
In-Reply-To: <20241202032035.29045-2-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
 <20241202032035.29045-2-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <1666021a-6840-4bb4-b5e2-225a528302fa@collabora.com>

Il 02/12/24 04:20, Zhengqiao Xia ha scritto:
> Add an entry for the MT8186 based Chinchou Chromebook, also known as the
> ASUS Chromebook CZ12 Flip (CZ1204F) and CZ12(CZ1204C).
> 
> Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>   .../devicetree/bindings/arm/mediatek.yaml     | 28 +++++++++++++++++++
>   1 file changed, 28 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
> index 1d4bb50fcd8d..3efab59b8a73 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
> @@ -239,6 +239,34 @@ properties:
>             - enum:
>                 - mediatek,mt8183-pumpkin
>             - const: mediatek,mt8183
> +      - description: Google Chinchou (Asus Chromebook CZ1104CM2A/CZ1204CM2A)
> +        items:
> +          - const: google,chinchou-sku0
> +          - const: google,chinchou-sku2
> +          - const: google,chinchou-sku4
> +          - const: google,chinchou-sku5
> +          - const: google,chinchou
> +          - const: mediatek,mt8186
> +      - description: Google Chinchou (Asus Chromebook CZ1104FM2A/CZ1204FM2A/CZ1104CM2A/CZ1204CM2A)
> +        items:
> +          - const: google,chinchou-sku1
> +          - const: google,chinchou-sku17
> +          - const: google,chinchou-sku3
> +          - const: google,chinchou-sku6
> +          - const: google,chinchou-sku7

Please move sku17 here to keep alphabetical order.
For consistency, please do the same in mt8186-corsola-chinchou-sku1.dts.

After which:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> +          - const: google,chinchou-sku20
> +          - const: google,chinchou-sku22
> +          - const: google,chinchou-sku23
> +          - const: google,chinchou
> +          - const: mediatek,mt8186
> +      - description: Google Chinchou360 (Asus Chromebook CZ1104FM2A/CZ1204FM2A Flip)
> +        items:
> +          - const: google,chinchou-sku16
> +          - const: google,chinchou-sku18
> +          - const: google,chinchou-sku19
> +          - const: google,chinchou-sku21
> +          - const: google,chinchou
> +          - const: mediatek,mt8186
>         - description: Google Magneton (Lenovo IdeaPad Slim 3 Chromebook (14M868))
>           items:
>             - const: google,steelix-sku393219





From hverkuil-cisco at xs4all.nl  Tue Dec  3 01:07:31 2024
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Tue, 3 Dec 2024 10:07:31 +0100
Subject: [PATCH v3 13/15] media: stm32: dcmipp: add core support for the
 stm32mp25
In-Reply-To: <20241118-csi_dcmipp_mp25-v3-13-c1914afb0a0f@foss.st.com>
References: <20241118-csi_dcmipp_mp25-v3-0-c1914afb0a0f@foss.st.com>
 <20241118-csi_dcmipp_mp25-v3-13-c1914afb0a0f@foss.st.com>
Message-ID: <832ee6b4-8238-4ef6-b870-f541b744880b@xs4all.nl>

Hi Alain,

On 18/11/2024 14:35, Alain Volmat wrote:
> The stm32mp25 supports both parallel & csi inputs.
> An additional clock control is necessary.
> Skeleton of the subdev structures for the stm32mp25 is added,
> identical for the time being to the stm32mp13 however more subdeves
> will be added in further commits.
> 
> Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> ---
>  .../platform/st/stm32/stm32-dcmipp/dcmipp-core.c   | 98 ++++++++++++++++++----
>  1 file changed, 80 insertions(+), 18 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 d2cc19bb40d77f67a1f5fe565bc62f45eff2d266..0087f9017f024ba6b918b99c1ef39212ad6b881a 100644
> --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
> +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
> @@ -40,6 +40,7 @@ struct dcmipp_device {
>  
>  	/* Hardware resources */
>  	void __iomem			*regs;
> +	struct clk			*mclk;
>  	struct clk			*kclk;
>  
>  	/* The pipeline configuration */
> @@ -132,6 +133,40 @@ static const struct dcmipp_pipeline_config stm32mp13_pipe_cfg = {
>  	.hw_revision	= DCMIPP_STM32MP13_VERR
>  };
>  
> +static const struct dcmipp_ent_config stm32mp25_ent_config[] = {
> +	{
> +		.name = "dcmipp_input",
> +		.init = dcmipp_inp_ent_init,
> +		.release = dcmipp_inp_ent_release,
> +	},
> +	{
> +		.name = "dcmipp_dump_postproc",
> +		.init = dcmipp_byteproc_ent_init,
> +		.release = dcmipp_byteproc_ent_release,
> +	},
> +	{
> +		.name = "dcmipp_dump_capture",
> +		.init = dcmipp_bytecap_ent_init,
> +		.release = dcmipp_bytecap_ent_release,
> +	},
> +};
> +
> +static const struct dcmipp_ent_link stm32mp25_ent_links[] = {
> +	DCMIPP_ENT_LINK(ID_INPUT, 1, ID_DUMP_BYTEPROC, 0,
> +			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
> +	DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE,  0,
> +			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
> +};
> +
> +#define DCMIPP_STM32MP25_VERR  0x30
> +static const struct dcmipp_pipeline_config stm32mp25_pipe_cfg = {
> +	.ents		= stm32mp25_ent_config,
> +	.num_ents	= ARRAY_SIZE(stm32mp25_ent_config),
> +	.links		= stm32mp25_ent_links,
> +	.num_links	= ARRAY_SIZE(stm32mp25_ent_links),
> +	.hw_revision    = DCMIPP_STM32MP25_VERR
> +};
> +
>  #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\
>  			     (f) == MEDIA_LNK_FL_ENABLED ? "ENABLED" :\
>  			     (f) == MEDIA_LNK_FL_IMMUTABLE ? "IMMUTABLE" :\
> @@ -212,6 +247,7 @@ static int dcmipp_create_subdevs(struct dcmipp_device *dcmipp)
>  
>  static const struct of_device_id dcmipp_of_match[] = {
>  	{ .compatible = "st,stm32mp13-dcmipp", .data = &stm32mp13_pipe_cfg },
> +	{ .compatible = "st,stm32mp25-dcmipp", .data = &stm32mp25_pipe_cfg },
>  	{ /* end node */ },
>  };
>  MODULE_DEVICE_TABLE(of, dcmipp_of_match);
> @@ -261,13 +297,22 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
>  {
>  	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
>  	unsigned int ret;
> -	int src_pad;
> +	int src_pad, i;
>  	struct dcmipp_ent_device *sink;
> -	struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL };
> +	struct v4l2_fwnode_endpoint vep = { 0 };
>  	struct fwnode_handle *ep;
> +	enum v4l2_mbus_type supported_types[] = {
> +		V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, V4L2_MBUS_CSI2_DPHY
> +	};
> +	int supported_types_nb = ARRAY_SIZE(supported_types);
>  
>  	dev_dbg(dcmipp->dev, "Subdev \"%s\" bound\n", subdev->name);
>  
> +	/* Only MP25 supports CSI input */
> +	if (!of_device_is_compatible(dcmipp->dev->of_node,
> +				     "st,stm32mp25-dcmipp"))
> +		supported_types_nb--;
> +
>  	/*
>  	 * Link this sub-device to DCMIPP, it could be
>  	 * a parallel camera sensor or a CSI-2 to parallel bridge
> @@ -284,21 +329,23 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
>  		return -ENODEV;
>  	}
>  
> -	/* Check for parallel bus-type first, then bt656 */
> -	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> -	if (ret) {
> -		vep.bus_type = V4L2_MBUS_BT656;
> +	/* Check for supported MBUS type */
> +	for (i = 0; i < supported_types_nb; i++) {
> +		vep.bus_type = supported_types[i];
>  		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> -		if (ret) {
> -			dev_err(dcmipp->dev, "Could not parse the endpoint\n");
> -			fwnode_handle_put(ep);
> -			return ret;
> -		}
> +		if (!ret)
> +			break;
>  	}
>  
>  	fwnode_handle_put(ep);
>  
> -	if (vep.bus.parallel.bus_width == 0) {
> +	if (ret) {
> +		dev_err(dcmipp->dev, "Could not parse the endpoint\n");
> +		return ret;
> +	}
> +
> +	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY &&
> +	    vep.bus.parallel.bus_width == 0) {
>  		dev_err(dcmipp->dev, "Invalid parallel interface bus-width\n");
>  		return -ENODEV;
>  	}
> @@ -311,11 +358,13 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
>  		return -ENODEV;
>  	}
>  
> -	/* Parallel input device detected, connect it to parallel subdev */
> +	/* Connect input device to the dcmipp_input subdev */
>  	sink = dcmipp->entity[ID_INPUT];
> -	sink->bus.flags = vep.bus.parallel.flags;
> -	sink->bus.bus_width = vep.bus.parallel.bus_width;
> -	sink->bus.data_shift = vep.bus.parallel.data_shift;
> +	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) {
> +		sink->bus.flags = vep.bus.parallel.flags;
> +		sink->bus.bus_width = vep.bus.parallel.bus_width;
> +		sink->bus.data_shift = vep.bus.parallel.data_shift;
> +	}
>  	sink->bus_type = vep.bus_type;
>  	ret = media_create_pad_link(&subdev->entity, src_pad, sink->ent, 0,
>  				    MEDIA_LNK_FL_IMMUTABLE |
> @@ -414,7 +463,7 @@ static int dcmipp_graph_init(struct dcmipp_device *dcmipp)
>  static int dcmipp_probe(struct platform_device *pdev)
>  {
>  	struct dcmipp_device *dcmipp;
> -	struct clk *kclk;
> +	struct clk *kclk, *mclk;
>  	const struct dcmipp_pipeline_config *pipe_cfg;
>  	struct reset_control *rstc;
>  	int irq;
> @@ -474,12 +523,20 @@ static int dcmipp_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> -	kclk = devm_clk_get(&pdev->dev, NULL);
> +	kclk = devm_clk_get(&pdev->dev, "kclk");
>  	if (IS_ERR(kclk))
>  		return dev_err_probe(&pdev->dev, PTR_ERR(kclk),
>  				     "Unable to get kclk\n");
>  	dcmipp->kclk = kclk;
>  
> +	if (!of_device_is_compatible(pdev->dev.of_node, "st,stm32mp13-dcmipp")) {
> +		mclk = devm_clk_get(&pdev->dev, "mclk");
> +		if (IS_ERR(mclk))
> +			return dev_err_probe(&pdev->dev, PTR_ERR(mclk),
> +					     "Unable to get mclk\n");
> +		dcmipp->mclk = mclk;
> +	}
> +
>  	dcmipp->entity = devm_kcalloc(&pdev->dev, dcmipp->pipe_cfg->num_ents,
>  				      sizeof(*dcmipp->entity), GFP_KERNEL);
>  	if (!dcmipp->entity)
> @@ -542,6 +599,7 @@ static int dcmipp_runtime_suspend(struct device *dev)
>  	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
>  
>  	clk_disable_unprepare(dcmipp->kclk);
> +	clk_disable_unprepare(dcmipp->mclk);
>  
>  	return 0;
>  }
> @@ -551,6 +609,10 @@ static int dcmipp_runtime_resume(struct device *dev)
>  	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
>  	int ret;
>  
> +	ret = clk_prepare_enable(dcmipp->mclk);
> +	if (ret)
> +		dev_err(dev, "%s: Failed to prepare_enable mclk\n", __func__);
> +

Shouldn't this return on error?

>  	ret = clk_prepare_enable(dcmipp->kclk);
>  	if (ret)
>  		dev_err(dev, "%s: Failed to prepare_enable kclk\n", __func__);

And on error here, it should call clk_disable_unprepare for mclk.

> 

This was reported by smatch:

.../dcmipp-core.c:620 dcmipp_runtime_resume() warn: 'dcmipp->mclk' from clk_prepare_enable() not released on lines: 620.

Everything else in this series looks good to me, so you can either post a fix for this
and I will fold it into this 13/15 patch, or you post an updated v3.1 13/15 patch.
Or of course a v4, if you prefer.

Regards,

	Hans


From rppt at kernel.org  Tue Dec  3 01:08:07 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Tue, 3 Dec 2024 11:08:07 +0200
Subject: [PATCH] arm64: patching: avoid early page_to_phys()
In-Reply-To: <20241202170359.1475019-1-mark.rutland@arm.com>
References: <20241202170359.1475019-1-mark.rutland@arm.com>
Message-ID: <Z07KdwY4P37oYVO4@kernel.org>

On Mon, Dec 02, 2024 at 05:03:59PM +0000, Mark Rutland wrote:
> When arm64 is configured with CONFIG_DEBUG_VIRTUAL=y, a warning is
> printed from the patching code because patch_map(), e.g.
> 
> | ------------[ cut here ]------------
> | WARNING: CPU: 0 PID: 0 at arch/arm64/kernel/patching.c:45 patch_map.constprop.0+0x120/0xd00
> | CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.13.0-rc1-00002-ge1a5d6c6be55 #1
> | Hardware name: linux,dummy-virt (DT)
> | pstate: 800003c5 (Nzcv DAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> | pc : patch_map.constprop.0+0x120/0xd00
> | lr : patch_map.constprop.0+0x120/0xd00
> | sp : ffffa9bb312a79a0
> | x29: ffffa9bb312a79a0 x28: 0000000000000001 x27: 0000000000000001
> | x26: 0000000000000000 x25: 0000000000000000 x24: 00000000000402e8
> | x23: ffffa9bb2c94c1c8 x22: ffffa9bb2c94c000 x21: ffffa9bb222e883c
> | x20: 0000000000000002 x19: ffffc1ffc100ba40 x18: ffffa9bb2cf0f21c
> | x17: 0000000000000006 x16: 0000000000000000 x15: 0000000000000004
> | x14: 1ffff5376625b4ac x13: ffff753766a67fb8 x12: ffff753766919cd1
> | x11: 0000000000000003 x10: 1ffff5376625b4c3 x9 : 1ffff5376625b4af
> | x8 : ffff753766254f0a x7 : 0000000041b58ab3 x6 : ffff753766254f18
> | x5 : ffffa9bb312d9bc0 x4 : 0000000000000000 x3 : ffffa9bb29bd90e4
> | x2 : 0000000000000002 x1 : ffffa9bb312d9bc0 x0 : 0000000000000000
> | Call trace:
> |  patch_map.constprop.0+0x120/0xd00 (P)
> |  patch_map.constprop.0+0x120/0xd00 (L)
> |  __aarch64_insn_write+0xa8/0x120
> |  aarch64_insn_patch_text_nosync+0x4c/0xb8
> |  arch_jump_label_transform_queue+0x7c/0x100
> |  jump_label_update+0x154/0x460
> |  static_key_enable_cpuslocked+0x1d8/0x280
> |  static_key_enable+0x2c/0x48
> |  early_randomize_kstack_offset+0x104/0x168
> |  do_early_param+0xe4/0x148
> |  parse_args+0x3a4/0x838
> |  parse_early_options+0x50/0x68
> |  parse_early_param+0x58/0xe0
> |  setup_arch+0x78/0x1f0
> |  start_kernel+0xa0/0x530
> |  __primary_switched+0x8c/0xa0
> | irq event stamp: 0
> | hardirqs last  enabled at (0): [<0000000000000000>] 0x0
> | hardirqs last disabled at (0): [<0000000000000000>] 0x0
> | softirqs last  enabled at (0): [<0000000000000000>] 0x0
> | softirqs last disabled at (0): [<0000000000000000>] 0x0
> | ---[ end trace 0000000000000000 ]---
> 
> The warning has been produced since commit:
> 
>   3e25d5a49f99b75b ("asm-generic: add an optional pfn_valid check to page_to_phys")
> 
> ... which added a pfn_valid() check into page_to_phys(), and at this
> point in boot pfn_valid() will always return false because the vmemmap
> has not yet been initialized and there are no valid mem_sections yet.
> 
> Before that commit, the arithmetic performed by page_to_phys() would
> give the expected physical address, though it is somewhat dubious to use
> vmemmap addresses before the vmemmap has been initialized.
> 
> For historical reasons, the structure of patch_map() is more complicated
> than necessary and can be simplified. For kernel image addresses it's
> sufficient to use __pa_symbol() directly without converting this to a
> page address and back. Aside from kernel image addresses, all executable
> code should be allocated from execmem (where all allocations will fall
> within the vmalloc area), and the vmalloc area), and so there's no need
> for the fallback case when case when CONFIG_EXECMEM=n.
> 
> Simplify patch_map() accordingly, directly converting kernel image
> addresses and removing the redundant fallback case.
> 
> Fixes: 3e25d5a49f99b75b ("asm-generic: add an optional pfn_valid check to page_to_phys")
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Christoph Hellwig <hch at lst.de>
> Cc: Mike Rapoport <rppt at kernel.org>
> Cc: Thomas Huth <thuth at redhat.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/kernel/patching.c | 25 +++++++++++--------------
>  1 file changed, 11 insertions(+), 14 deletions(-)
> 
> Catalin, Will, I wasn't sure whether we'd prefer this or an explicit
> check that the address is a vmalloc addr, e.g.
> 
> 	if (is_image_text(...)) {
> 		phys = ...;
> 	} else if (is_vmalloc_addr(...)) {
> 		phys = ...;
> 	} else {
> 		BUG();
> 	}
> 
> I went for the style below because it was marginally simpler, I'm more
> than happy to respin as above if that's preferable.
> 
> Mark.
> 
> diff --git a/arch/arm64/kernel/patching.c b/arch/arm64/kernel/patching.c
> index 7f99723fbb8c4..1041bc67a3eee 100644
> --- a/arch/arm64/kernel/patching.c
> +++ b/arch/arm64/kernel/patching.c
> @@ -30,20 +30,17 @@ static bool is_image_text(unsigned long addr)
>  
>  static void __kprobes *patch_map(void *addr, int fixmap)
>  {
> -	unsigned long uintaddr = (uintptr_t) addr;
> -	bool image = is_image_text(uintaddr);
> -	struct page *page;
> -
> -	if (image)
> -		page = phys_to_page(__pa_symbol(addr));
> -	else if (IS_ENABLED(CONFIG_EXECMEM))
> -		page = vmalloc_to_page(addr);
> -	else
> -		return addr;
> -
> -	BUG_ON(!page);
> -	return (void *)set_fixmap_offset(fixmap, page_to_phys(page) +
> -			(uintaddr & ~PAGE_MASK));
> +	phys_addr_t phys;
> +
> +	if (is_image_text((unsigned long)addr)) {
> +		phys = __pa_symbol(addr);
> +	} else {
> +		struct page *page = vmalloc_to_page(addr);
> +		BUG_ON(!page);

Not strictly related to this patch, but is it necessary to BUG() here?
Can't patch_map() return NULL and fail the patching more gracefully?

> +		phys = page_to_phys(page) + offset_in_page(addr);
> +	}
> +
> +	return (void *)set_fixmap_offset(fixmap, phys);
>  }
>  
>  static void __kprobes patch_unmap(int fixmap)
> -- 
> 2.30.2
> 

-- 
Sincerely yours,
Mike.


From t.antoine at uclouvain.be  Tue Dec  3 01:08:55 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Tue, 3 Dec 2024 10:08:55 +0100
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
Message-ID: <9387c0cf-d291-485a-8cd1-1aced7eba14e@uclouvain.be>

On 12/3/24 07:47, Andr? Draszik wrote:
> Hi Thomas,
> 
> Thanks for looking into this!

Hi,

With pleasure! This is my first time trying to contribute to the kernel
so sorry for any beginner mistakes I might do.
 
>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>
>> The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
>> except for the non-volatile memory slave address which is not available.
> 
> It is not fully compatible, and it also has a lot more registers.
> 
> For example, the voltage now is not in register 0xda as this driver assumes.
> With these changes, POWER_SUPPLY_PROP_VOLTAGE_NOW just reads as 0. 0xda
> doesn't exist in max77759
> 
> I haven't compared in depth yet, though.

Is the voltage necessary for the driver? If so, we could just not
read the voltage. If it is necessary, I can try to kook into it and try
to find in which register it is located (if there is one).

>>  static const char *const max17205_model = "MAX17205";
>> +static const char *const max77759_model = "MAX77759";
>>
>>  struct max1720x_device_info {
>>       struct regmap *regmap;
>> @@ -54,6 +57,21 @@ struct max1720x_device_info {
>>       int rsense;
>>  };
>>
>> +struct chip_data {
>> +     u16 default_nrsense; /* in regs in 10^-5 */
>> +     u8 has_nvmem;
>> +};
>> +
>> +static const struct chip_data max1720x_data  = {
>> +     .default_nrsense = 1000,
>> +     .has_nvmem = 1,
>> +};
>> +
>> +static const struct chip_data max77759_data = {
>> +     .default_nrsense = 500,
>> +     .has_nvmem = 0,
>> +};
> 
> This should be made a required devicetree property instead, at least for
> max77759, as it's completely board dependent, 'shunt-resistor-micro-ohms'
> is widely used.
> 
> I also don't think there should be a default. The driver should just fail
> to probe if not specified in DT (for max77759).

I hesitated to do this but I didn't know what would be better. Will change
for v2.

>> +
>>  /*
>>   * Model Gauge M5 Algorithm output register
>>   * Volatile data (must not be cached)
>> @@ -369,6 +387,8 @@ static int max1720x_battery_get_property(struct
>> power_supply *psy,
>>                       val->strval = max17201_model;
>>               else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17205)
>>                       val->strval = max17205_model;
>> +             else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX77759)
>> +                     val->strval = max77759_model;
>>               else
> 
> This is a 16 bit register, and while yes, MAX172XX_DEV_NAME_TYPE_MASK only
> cares about the bottom 4 bits, the register is described as 'Firmware
> Version Information'.
> 
> But maybe it's ok to do it like that, at least for now.

I thought this method would be ok as long as there is no collision on
values. I hesitated to change the model evaluation method based on chip
model, where the max77759 would thus have an hard-coded value and the
max1720x would still evaluate the register value. I did not do it because
it led to a lot more changes for no difference.

>> &max77759_data},
> 
> missing space before }

Will change for v2.

Best regards,
Thomas


From wenst at chromium.org  Tue Dec  3 01:15:55 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 3 Dec 2024 17:15:55 +0800
Subject: [PATCH v4 3/4] arm64: dts: mediatek: Add exton node for DP bridge
In-Reply-To: <20241202032035.29045-4-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241202032035.29045-1-xiazhengqiao@huaqin.corp-partner.google.com>
 <20241202032035.29045-4-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <CAGXv+5HsOgRCpGOFxEJorVD+=-6GbW_=K3AChkBSxTs27fNJ3w@mail.gmail.com>

On Mon, Dec 2, 2024 at 11:21?AM Zhengqiao Xia
<xiazhengqiao at huaqin.corp-partner.google.com> wrote:
>
> Add exton node for DP bridge to make the display work properly.
      ^ extcon.

Same for the subject.

> Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
> index cfcc7909dfe6..e324e3fd347e 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
> @@ -424,6 +424,7 @@
>                 ovdd-supply = <&mt6366_vsim2_reg>;
>                 pwr18-supply = <&pp1800_dpbrdg_dx>;
>                 reset-gpios = <&pio 177 GPIO_ACTIVE_LOW>;
> +               extcon = <&usbc_extcon>;
>
>                 ports {
>                         #address-cells = <1>;
> @@ -1656,6 +1657,11 @@
>                                 try-power-role = "source";
>                         };
>                 };
> +
> +               usbc_extcon: extcon0 {
> +                       compatible = "google,extcon-usbc-cros-ec";
> +                       google,usb-port-id = <0>;
> +               };
>         };
>  };
>
> --
> 2.17.1
>


From t.antoine at uclouvain.be  Tue Dec  3 01:25:13 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Tue, 3 Dec 2024 10:25:13 +0100
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <20241203073556.GA3936@debian>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
 <20241203073556.GA3936@debian>
Message-ID: <9426d88b-0a8b-4cd1-81a4-83cfa61bb595@uclouvain.be>

On 12/3/24 08:35, Dimitri Fedrau wrote:
> Hi Antoine,
> 
> Am Mon, Dec 02, 2024 at 02:07:15PM +0100 schrieb Thomas Antoine via B4 Relay:
>> From: Thomas Antoine <t.antoine at uclouvain.be>
>> +#include <linux/types.h>
>>  
> No need to include it, it is done by <linux/i2.c> which includes
> <linux/device.h> which includes <linux/types.h>

Hi,
Will remove for v2.

>>  static const char *const max17201_model = "MAX17201";
>>  static const char *const max17205_model = "MAX17205";
>> +static const char *const max77759_model = "MAX77759";
>>  
>>  struct max1720x_device_info {
>>  	struct regmap *regmap;
>> @@ -54,6 +57,21 @@ struct max1720x_device_info {
>>  	int rsense;
>>  };
>>  
>> +struct chip_data {
>> +	u16 default_nrsense; /* in regs in 10^-5 */
>> +	u8 has_nvmem;
>> +};
>> +
>> +static const struct chip_data max1720x_data  = {
>> +	.default_nrsense = 1000,
>> +	.has_nvmem = 1,
>> +};
>> +
>> +static const struct chip_data max77759_data = {
>> +	.default_nrsense = 500,
>> +	.has_nvmem = 0,
>> +};
>> +
> You can get rid of chip_data by reading rsense from DT and moving
> has_nvmem to max1720x_device_info. By doing so you don't have to rely on
> default values. Either it is specified by DT or by rsense value in
> nvmem.

I guess I can just get has_nvmem by seeing if of_property_read of the
rsense value fails. As long as the binding is well defined as to not
allow a rsense value for the max1720x, there should be no problem.
Will do that for v2.

Thanks, best regards,
Thomas


From quic_jingyw at quicinc.com  Tue Dec  3 01:27:11 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Tue, 3 Dec 2024 17:27:11 +0800
Subject: [PATCH v4 0/4] Add initial support for QCS8300 SoC and QCS8300
 RIDE board
Message-ID: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>

Introduce the Device Tree for the QCS8300 platform.

Features added and enabled:
- CPUs with PSCI idle states
- Interrupt-controller with PDC wakeup support
- Timers, TCSR Clock Controllers
- Reserved Shared memory
- GCC and RPMHCC
- TLMM
- Interconnect
- QuP with uart
- SMMU
- QFPROM
- Rpmhpd power controller
- UFS
- Inter-Processor Communication Controller
- SRAM
- Remoteprocs including ADSP,CDSP and GPDSP
- BWMONs

binding dependencies:
- remoteproc: https://lore.kernel.org/linux-arm-msm/20240925-qcs8300_remoteproc_binding-v3-1-21b0c52b142b at quicinc.com/ - Reviewed
- qfprom: https://lore.kernel.org/all/20240911-qcs8300_qfprom_binding-v2-1-d39226887493 at quicinc.com/ - Reviewed
- pdc: https://lore.kernel.org/all/20240911-qcs8300_binding-v2-1-de8641b3eaa1 at quicinc.com/ - Reviewed

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
Changes in v4:
- fixup typo in Makefile(Andrew & Krzysztof)
- add board name in the commit message of the defconfig change(Dmitry)
- separate cpus into 2 clusters in cpu-map(Konrad)
- use QCOM_ICC_TAG_ALWAYS instead of "0" for interconnect nodes(Konrad)
- Remove unused labels and drop redundant comments(Konrad)
- Move clocks to the dtsi file(Dmitry)
- drop reviewed-by tag for dts patch for the code change
- Link to v3: https://lore.kernel.org/r/20241128-qcs8300_initial_dtsi-v3-0-26aa8a164914 at quicinc.com

Changes in v3:
- Update title and cleanup signed-off-by tag(Bjorn)
- fix the INTID of EL2 non-secure physical timer(Cong)
- add reviewed-by tag(except for the dtsi patch for the code change)
- code rebase
- Link to v2: https://lore.kernel.org/r/20240925-qcs8300_initial_dtsi-v2-0-494c40fa2a42 at quicinc.com

Changes in v2:
- decoupled from the original series
- Drop compatible for QCS8275
- fix property order and add line breaks
- move sleep_clk node to qcs8300-ride.dts
- move l3-cache nodes out of l2-cache nodes and remove cluster1/cluster2
- add BWMON nodes
- commit-msg update
- Link to v1: https://lore.kernel.org/r/20240904-qcs8300_initial_dtsi-v1-0-d0ea9afdc007 at quicinc.com

---
Jingyi Wang (4):
      dt-bindings: arm: qcom: document QCS8300 SoC and reference board
      arm64: defconfig: enable clock controller, interconnect and pinctrl for QCS8300
      arm64: dts: qcom: add QCS8300 platform
      arm64: dts: qcom: add base QCS8300 RIDE board

 Documentation/devicetree/bindings/arm/qcom.yaml |    6 +
 arch/arm64/boot/dts/qcom/Makefile               |    1 +
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts       |  235 ++++
 arch/arm64/boot/dts/qcom/qcs8300.dtsi           | 1405 +++++++++++++++++++++++
 arch/arm64/configs/defconfig                    |    3 +
 5 files changed, 1650 insertions(+)
---
base-commit: f486c8aa16b8172f63bddc70116a0c897a7f3f02
change-id: 20241128-qcs8300_initial_dtsi-ad3f193ce1d7

Best regards,
-- 
Jingyi Wang <quic_jingyw at quicinc.com>



From quic_jingyw at quicinc.com  Tue Dec  3 01:27:12 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Tue, 3 Dec 2024 17:27:12 +0800
Subject: [PATCH v4 1/4] dt-bindings: arm: qcom: document QCS8300 SoC and
 reference board
In-Reply-To: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
References: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
Message-ID: <20241203-qcs8300_initial_dtsi-v4-1-d7c953484024@quicinc.com>

Document Qualcomm QCS8300 SoC and its reference board QCS8300 RIDE.

Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 Documentation/devicetree/bindings/arm/qcom.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index ca3990393510..87f1106767a2 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -52,6 +52,7 @@ description: |
         msm8996pro
         msm8998
         qcs404
+        qcs8300
         qcs8550
         qcm2290
         qcm6490
@@ -921,6 +922,11 @@ properties:
           - const: qcom,qcs404-evb
           - const: qcom,qcs404
 
+      - items:
+          - enum:
+              - qcom,qcs8300-ride
+          - const: qcom,qcs8300
+
       - items:
           - enum:
               - qcom,sa8155p-adp

-- 
2.25.1



From quic_jingyw at quicinc.com  Tue Dec  3 01:27:13 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Tue, 3 Dec 2024 17:27:13 +0800
Subject: [PATCH v4 2/4] arm64: defconfig: enable clock controller,
 interconnect and pinctrl for QCS8300
In-Reply-To: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
References: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
Message-ID: <20241203-qcs8300_initial_dtsi-v4-2-d7c953484024@quicinc.com>

Enable clock controller, interconnect and pinctrl for Qualcomm
QCS8300 platform to boot QCS8300 RIDE board to UART console.

The serial engine depends on gcc, interconnect and pinctrl. Since
the serial console driver is only available as built-in, so these
configs needs be built-in for the UART device to probe and register
the console.

Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>
Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index d13218d0c30f..3d9e48940c96 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -608,6 +608,7 @@ CONFIG_PINCTRL_MSM8996=y
 CONFIG_PINCTRL_MSM8998=y
 CONFIG_PINCTRL_QCM2290=y
 CONFIG_PINCTRL_QCS404=y
+CONFIG_PINCTRL_QCS8300=y
 CONFIG_PINCTRL_QDF2XXX=y
 CONFIG_PINCTRL_QDU1000=y
 CONFIG_PINCTRL_SA8775P=y
@@ -1327,6 +1328,7 @@ CONFIG_MSM_MMCC_8998=m
 CONFIG_QCM_GCC_2290=y
 CONFIG_QCM_DISPCC_2290=m
 CONFIG_QCS_GCC_404=y
+CONFIG_QCS_GCC_8300=y
 CONFIG_SC_CAMCC_7280=m
 CONFIG_QDU_GCC_1000=y
 CONFIG_SC_CAMCC_8280XP=m
@@ -1634,6 +1636,7 @@ CONFIG_INTERCONNECT_QCOM_MSM8996=y
 CONFIG_INTERCONNECT_QCOM_OSM_L3=m
 CONFIG_INTERCONNECT_QCOM_QCM2290=y
 CONFIG_INTERCONNECT_QCOM_QCS404=m
+CONFIG_INTERCONNECT_QCOM_QCS8300=y
 CONFIG_INTERCONNECT_QCOM_QDU1000=y
 CONFIG_INTERCONNECT_QCOM_SA8775P=y
 CONFIG_INTERCONNECT_QCOM_SC7180=y

-- 
2.25.1



From quic_jingyw at quicinc.com  Tue Dec  3 01:27:14 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Tue, 3 Dec 2024 17:27:14 +0800
Subject: [PATCH v4 3/4] arm64: dts: qcom: add QCS8300 platform
In-Reply-To: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
References: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
Message-ID: <20241203-qcs8300_initial_dtsi-v4-3-d7c953484024@quicinc.com>

Add initial DTSI for QCS8300 SoC.

Features added in this revision:
- CPUs with PSCI idle states
- Interrupt-controller with PDC wakeup support
- Timers, TCSR Clock Controllers
- Reserved Shared memory
- GCC and RPMHCC
- TLMM
- Interconnect
- QuP with uart
- SMMU
- QFPROM
- Rpmhpd power controller
- UFS
- Inter-Processor Communication Controller
- SRAM
- Remoteprocs including ADSP,CDSP and GPDSP
- BWMONs

Written with help from Zhenhua Huang(added the smmu node), Xin Liu(added
ufs, adsp and gpdsp nodes), Tingguo Cheng(added the rpmhpd node), Kyle
Deng(added the aoss_qmp node), Raviteja Laggyshetty(added interconnect
nodes) and Cong Zhang(added the INTID of EL2 non-secure physical timer).

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 arch/arm64/boot/dts/qcom/qcs8300.dtsi | 1405 +++++++++++++++++++++++++++++++++
 1 file changed, 1405 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300.dtsi b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
new file mode 100644
index 000000000000..73abf2ef9c9f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
@@ -0,0 +1,1405 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/power/qcom,rpmhpd.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+
+/ {
+	interrupt-parent = <&intc>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clocks {
+		xo_board_clk: xo-board-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <38400000>;
+		};
+
+		sleep_clk: sleep-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32000>;
+		};
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			next-level-cache = <&l2_0>;
+			power-domains = <&cpu_pd0>;
+			power-domain-names = "psci";
+
+			l2_0: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu1: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			next-level-cache = <&l2_1>;
+			power-domains = <&cpu_pd1>;
+			power-domain-names = "psci";
+
+			l2_1: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu2: cpu at 200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			next-level-cache = <&l2_2>;
+			power-domains = <&cpu_pd2>;
+			power-domain-names = "psci";
+
+			l2_2: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu3: cpu at 300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			next-level-cache = <&l2_3>;
+			power-domains = <&cpu_pd3>;
+			power-domain-names = "psci";
+
+			l2_3: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu4: cpu at 10000 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			next-level-cache = <&l2_4>;
+			power-domains = <&cpu_pd4>;
+			power-domain-names = "psci";
+
+			l2_4: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_1>;
+			};
+		};
+
+		cpu5: cpu at 10100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10100>;
+			enable-method = "psci";
+			next-level-cache = <&l2_5>;
+			power-domains = <&cpu_pd5>;
+			power-domain-names = "psci";
+
+			l2_5: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_1>;
+			};
+		};
+
+		cpu6: cpu at 10200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10200>;
+			enable-method = "psci";
+			next-level-cache = <&l2_6>;
+			power-domains = <&cpu_pd6>;
+			power-domain-names = "psci";
+
+			l2_6: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_1>;
+			};
+		};
+
+		cpu7: cpu at 10300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10300>;
+			enable-method = "psci";
+			next-level-cache = <&l2_7>;
+			power-domains = <&cpu_pd7>;
+			power-domain-names = "psci";
+
+			l2_7: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&l3_1>;
+			};
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+
+				core1 {
+					cpu = <&cpu5>;
+				};
+
+				core2 {
+					cpu = <&cpu6>;
+				};
+
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		l3_0: l3-cache-0 {
+			compatible = "cache";
+			cache-level = <3>;
+			cache-unified;
+		};
+
+		l3_1: l3-cache-1 {
+			compatible = "cache";
+			cache-level = <3>;
+			cache-unified;
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			little_cpu_sleep_0: cpu-sleep-0-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "silver-power-collapse";
+				arm,psci-suspend-param = <0x40000003>;
+				entry-latency-us = <449>;
+				exit-latency-us = <801>;
+				min-residency-us = <1574>;
+				local-timer-stop;
+			};
+
+			little_cpu_sleep_1: cpu-sleep-0-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "silver-rail-power-collapse";
+				arm,psci-suspend-param = <0x40000004>;
+				entry-latency-us = <602>;
+				exit-latency-us = <961>;
+				min-residency-us = <4288>;
+				local-timer-stop;
+			};
+
+			big_cpu_sleep_0: cpu-sleep-1-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "gold-power-collapse";
+				arm,psci-suspend-param = <0x40000003>;
+				entry-latency-us = <549>;
+				exit-latency-us = <901>;
+				min-residency-us = <1774>;
+				local-timer-stop;
+			};
+
+			big_cpu_sleep_1: cpu-sleep-1-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "gold-rail-power-collapse";
+				arm,psci-suspend-param = <0x40000004>;
+				entry-latency-us = <702>;
+				exit-latency-us = <1061>;
+				min-residency-us = <4488>;
+				local-timer-stop;
+			};
+		};
+
+		domain-idle-states {
+			silver_cluster_sleep: cluster-sleep-0 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x41000044>;
+				entry-latency-us = <2552>;
+				exit-latency-us = <2848>;
+				min-residency-us = <5908>;
+			};
+
+			gold_cluster_sleep: cluster-sleep-1 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x41000044>;
+				entry-latency-us = <2752>;
+				exit-latency-us = <3048>;
+				min-residency-us = <6118>;
+			};
+
+			system_sleep: domain-sleep {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x42000144>;
+				entry-latency-us = <3263>;
+				exit-latency-us = <6562>;
+				min-residency-us = <9987>;
+			};
+		};
+	};
+
+	firmware {
+		scm: scm {
+			compatible = "qcom,scm-qcs8300", "qcom,scm";
+			qcom,dload-mode = <&tcsr 0x13000>;
+		};
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		/* We expect the bootloader to fill in the size */
+		reg = <0x0 0x80000000 0x0 0x0>;
+	};
+
+	clk_virt: interconnect-0 {
+		compatible = "qcom,qcs8300-clk-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	mc_virt: interconnect-1 {
+		compatible = "qcom,qcs8300-mc-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+
+		cpu_pd0: power-domain-cpu0 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd0>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cpu_pd1: power-domain-cpu1 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd0>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cpu_pd2: power-domain-cpu2 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd0>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cpu_pd3: power-domain-cpu3 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd0>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cpu_pd4: power-domain-cpu4 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd1>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd5: power-domain-cpu5 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd1>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd6: power-domain-cpu6 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd1>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd7: power-domain-cpu7 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd1>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cluster_pd0: power-domain-cluster0 {
+			#power-domain-cells = <0>;
+			power-domains = <&system_pd>;
+			domain-idle-states = <&gold_cluster_sleep>;
+		};
+
+		cluster_pd1: power-domain-cluster1 {
+			#power-domain-cells = <0>;
+			power-domains = <&system_pd>;
+			domain-idle-states = <&silver_cluster_sleep>;
+		};
+
+		system_pd: power-domain-system {
+			#power-domain-cells = <0>;
+			domain-idle-states = <&system_sleep>;
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		aop_image_mem: aop-image-region at 90800000 {
+			reg = <0x0 0x90800000 0x0 0x60000>;
+			no-map;
+		};
+
+		aop_cmd_db_mem: aop-cmd-db-region at 90860000 {
+			compatible = "qcom,cmd-db";
+			reg = <0x0 0x90860000 0x0 0x20000>;
+			no-map;
+		};
+
+		smem_mem: smem at 90900000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x90900000 0x0 0x200000>;
+			no-map;
+			hwlocks = <&tcsr_mutex 3>;
+		};
+
+		lpass_machine_learning_mem: lpass-machine-learning-region at 93b00000 {
+			reg = <0x0 0x93b00000 0x0 0xf00000>;
+			no-map;
+		};
+
+		adsp_rpc_remote_heap_mem: adsp-rpc-remote-heap-region at 94a00000 {
+			reg = <0x0 0x94a00000 0x0 0x800000>;
+			no-map;
+		};
+
+		camera_mem: camera-region at 95200000 {
+			reg = <0x0 0x95200000 0x0 0x500000>;
+			no-map;
+		};
+
+		adsp_mem: adsp-region at 95c00000 {
+			no-map;
+			reg = <0x0 0x95c00000 0x0 0x1e00000>;
+		};
+
+		q6_adsp_dtb_mem: q6-adsp-dtb-region at 97a00000 {
+			reg = <0x0 0x97a00000 0x0 0x80000>;
+			no-map;
+		};
+
+		q6_gpdsp_dtb_mem: q6-gpdsp-dtb-region at 97a80000 {
+			reg = <0x0 0x97a80000 0x0 0x80000>;
+			no-map;
+		};
+
+		gpdsp_mem: gpdsp-region at 97b00000 {
+			reg = <0x0 0x97b00000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		q6_cdsp_dtb_mem: q6-cdsp-dtb-region at 99900000 {
+			reg = <0x0 0x99900000 0x0 0x80000>;
+			no-map;
+		};
+
+		cdsp_mem: cdsp-region at 99980000 {
+			reg = <0x0 0x99980000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		gpu_microcode_mem: gpu-microcode-region at 9b780000 {
+			reg = <0x0 0x9b780000 0x0 0x2000>;
+			no-map;
+		};
+
+		cvp_mem: cvp-region at 9b782000 {
+			reg = <0x0 0x9b782000 0x0 0x700000>;
+			no-map;
+		};
+
+		video_mem: video-region at 9be82000 {
+			reg = <0x0 0x9be82000 0x0 0x700000>;
+			no-map;
+		};
+	};
+
+	smp2p-adsp {
+		compatible = "qcom,smp2p";
+		interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_LPASS
+				IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,smem = <443>, <429>;
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <2>;
+
+		smp2p_adsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		smp2p_adsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+	};
+
+	smp2p-cdsp {
+		compatible = "qcom,smp2p";
+		interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_CDSP
+				IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,smem = <94>, <432>;
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <5>;
+
+		smp2p_cdsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		smp2p_cdsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+	};
+
+	smp2p-gpdsp {
+		compatible = "qcom,smp2p";
+		interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP0
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_GPDSP0
+				IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,smem = <617>, <616>;
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <17>;
+
+		smp2p_gpdsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		smp2p_gpdsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+		ranges = <0 0 0 0 0x10 0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		gcc: clock-controller at 100000 {
+			compatible = "qcom,qcs8300-gcc";
+			reg = <0x0 0x00100000 0x0 0xc7018>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&sleep_clk>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>;
+		};
+
+		ipcc: mailbox at 408000 {
+			compatible = "qcom,qcs8300-ipcc", "qcom,ipcc";
+			reg = <0x0 0x408000 0x0 0x1000>;
+			interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#mbox-cells = <2>;
+		};
+
+		qfprom: efuse at 784000 {
+			compatible = "qcom,qcs8300-qfprom", "qcom,qfprom";
+			reg = <0x0 0x00784000 0x0 0x1200>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+		};
+
+		qupv3_id_0: geniqup at 9c0000 {
+			compatible = "qcom,geni-se-qup";
+			reg = <0x0 0x9c0000 0x0 0x2000>;
+			ranges;
+			clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>,
+				 <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>;
+			clock-names = "m-ahb",
+				      "s-ahb";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			status = "disabled";
+
+			uart7: serial at 99c000 {
+				compatible = "qcom,geni-debug-uart";
+				reg = <0x0 0x0099c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart7_default>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				status = "disabled";
+			};
+		};
+
+		config_noc: interconnect at 14c0000 {
+			compatible = "qcom,qcs8300-config-noc";
+			reg = <0x0 0x014c0000 0x0 0x13080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		system_noc: interconnect at 1680000 {
+			compatible = "qcom,qcs8300-system-noc";
+			reg = <0x0 0x01680000 0x0 0x15080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		aggre1_noc: interconnect at 16c0000 {
+			compatible = "qcom,qcs8300-aggre1-noc";
+			reg = <0x0 0x016c0000 0x0 0x17080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		aggre2_noc: interconnect at 1700000 {
+			compatible = "qcom,qcs8300-aggre2-noc";
+			reg = <0x0 0x01700000 0x0 0x1a080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		pcie_anoc: interconnect at 1760000 {
+			compatible = "qcom,qcs8300-pcie-anoc";
+			reg = <0x0 0x01760000 0x0 0xc080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		gpdsp_anoc: interconnect at 1780000 {
+			compatible = "qcom,qcs8300-gpdsp-anoc";
+			reg = <0x0 0x01780000 0x0 0xd080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		mmss_noc: interconnect at 17a0000 {
+			compatible = "qcom,qcs8300-mmss-noc";
+			reg = <0x0 0x017a0000 0x0 0x40000>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		ufs_mem_hc: ufs at 1d84000 {
+			compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
+			reg = <0x0 0x01d84000 0x0 0x3000>;
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+			phys = <&ufs_mem_phy>;
+			phy-names = "ufsphy";
+			lanes-per-direction = <2>;
+			#reset-cells = <1>;
+			resets = <&gcc GCC_UFS_PHY_BCR>;
+			reset-names = "rst";
+
+			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
+
+			iommus = <&apps_smmu 0x100 0x0>;
+			dma-coherent;
+
+			interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+					 &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "ufs-ddr",
+					     "cpu-ufs";
+
+			clocks = <&gcc GCC_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_UFS_PHY_AHB_CLK>,
+				 <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
+				 <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>,
+				 <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
+			clock-names = "core_clk",
+				      "bus_aggr_clk",
+				      "iface_clk",
+				      "core_clk_unipro",
+				      "ref_clk",
+				      "tx_lane0_sync_clk",
+				      "rx_lane0_sync_clk",
+				      "rx_lane1_sync_clk";
+			freq-table-hz = <75000000 300000000>,
+					<0 0>,
+					<0 0>,
+					<75000000 300000000>,
+					<0 0>,
+					<0 0>,
+					<0 0>,
+					<0 0>;
+			status = "disabled";
+		};
+
+		ufs_mem_phy: phy at 1d87000 {
+			compatible = "qcom,qcs8300-qmp-ufs-phy", "qcom,sa8775p-qmp-ufs-phy";
+			reg = <0x0 0x01d87000 0x0 0xe10>;
+			/*
+			 * Yes, GCC_EDP_REF_CLKREF_EN is correct in qref. It
+			 * enables the CXO clock to eDP *and* UFS PHY.
+			 */
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+				 <&gcc GCC_EDP_REF_CLKREF_EN>;
+			clock-names = "ref",
+				      "ref_aux",
+				      "qref";
+			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+
+			resets = <&ufs_mem_hc 0>;
+			reset-names = "ufsphy";
+
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		tcsr_mutex: hwlock at 1f40000 {
+			compatible = "qcom,tcsr-mutex";
+			reg = <0x0 0x01f40000 0x0 0x20000>;
+			#hwlock-cells = <1>;
+		};
+
+		tcsr: syscon at 1fc0000 {
+			compatible = "qcom,qcs8300-tcsr", "syscon";
+			reg = <0x0 0x1fc0000 0x0 0x30000>;
+		};
+
+		remoteproc_adsp: remoteproc at 3000000 {
+			compatible = "qcom,qcs8300-adsp-pas", "qcom,sa8775p-adsp-pas";
+			reg = <0x0 0x3000000 0x0 0x00100>;
+
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog",
+					  "fatal",
+					  "ready",
+					  "handover",
+					  "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_LCX>,
+					<&rpmhpd RPMHPD_LMX>;
+			power-domain-names = "lcx",
+					     "lmx";
+
+			memory-region = <&adsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_adsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			remoteproc_adsp_glink: glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_LPASS
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "lpass";
+				qcom,remote-pid = <2>;
+			};
+		};
+
+		lpass_ag_noc: interconnect at 3c40000 {
+			compatible = "qcom,qcs8300-lpass-ag-noc";
+			reg = <0x0 0x03c40000 0x0 0x17200>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		pmu at 9091000 {
+			compatible = "qcom,qcs8300-llcc-bwmon", "qcom,sc7280-llcc-bwmon";
+			reg = <0x0 0x9091000 0x0 0x1000>;
+
+			interrupts = <GIC_SPI 620 IRQ_TYPE_LEVEL_HIGH>;
+
+			interconnects = <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&llcc_bwmon_opp_table>;
+
+			llcc_bwmon_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-0 {
+					opp-peak-kBps = <762000>;
+				};
+
+				opp-1 {
+					opp-peak-kBps = <1720000>;
+				};
+
+				opp-2 {
+					opp-peak-kBps = <2086000>;
+				};
+
+				opp-3 {
+					opp-peak-kBps = <2601000>;
+				};
+
+				opp-4 {
+					opp-peak-kBps = <2929000>;
+				};
+
+				opp-5 {
+					opp-peak-kBps = <5931000>;
+				};
+
+				opp-6 {
+					opp-peak-kBps = <6515000>;
+				};
+
+				opp-7 {
+					opp-peak-kBps = <7984000>;
+				};
+
+				opp-8 {
+					opp-peak-kBps = <10437000>;
+				};
+
+				opp-9 {
+					opp-peak-kBps = <12195000>;
+				};
+			};
+		};
+
+		pmu at 90b5400 {
+			compatible = "qcom,qcs8300-cpu-bwmon", "qcom,sdm845-bwmon";
+			reg = <0x0 0x90b5400 0x0 0x600>;
+			interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&cpu_bwmon_opp_table>;
+
+			cpu_bwmon_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-0 {
+					opp-peak-kBps = <9155000>;
+				};
+
+				opp-1 {
+					opp-peak-kBps = <12298000>;
+				};
+
+				opp-2 {
+					opp-peak-kBps = <14236000>;
+				};
+
+				opp-3 {
+					opp-peak-kBps = <16265000>;
+				};
+			};
+		};
+
+		pmu at 90b6400 {
+			compatible = "qcom,qcs8300-cpu-bwmon", "qcom,sdm845-bwmon";
+			reg = <0x0 0x90b6400 0x0 0x600>;
+			interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&cpu_bwmon_opp_table>;
+		};
+
+		dc_noc: interconnect at 90e0000 {
+			compatible = "qcom,qcs8300-dc-noc";
+			reg = <0x0 0x090e0000 0x0 0x5080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		gem_noc: interconnect at 9100000 {
+			compatible = "qcom,qcs8300-gem-noc";
+			reg = <0x0 0x9100000 0x0 0xf7080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		pdc: interrupt-controller at b220000 {
+			compatible = "qcom,qcs8300-pdc", "qcom,pdc";
+			reg = <0x0 0xb220000 0x0 0x30000>,
+			      <0x0 0x17c000f0 0x0 0x64>;
+			interrupt-parent = <&intc>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			qcom,pdc-ranges = <0 480 40>,
+					  <40 140 14>,
+					  <54 263 1>,
+					  <55 306 4>,
+					  <59 312 3>,
+					  <62 374 2>,
+					  <64 434 2>,
+					  <66 438 2>,
+					  <70 520 1>,
+					  <73 523 1>,
+					  <118 568 6>,
+					  <124 609 3>,
+					  <159 638 1>,
+					  <160 720 3>,
+					  <169 728 30>,
+					  <199 416 2>,
+					  <201 449 1>,
+					  <202 89 1>,
+					  <203 451 1>,
+					  <204 462 1>,
+					  <205 264 1>,
+					  <206 579 1>,
+					  <207 653 1>,
+					  <208 656 1>,
+					  <209 659 1>,
+					  <210 122 1>,
+					  <211 699 1>,
+					  <212 705 1>,
+					  <213 450 1>,
+					  <214 643 2>,
+					  <216 646 5>,
+					  <221 390 5>,
+					  <226 700 2>,
+					  <228 440 1>,
+					  <229 663 1>,
+					  <230 524 2>,
+					  <232 612 3>,
+					  <235 723 5>;
+		};
+
+		aoss_qmp: power-management at c300000 {
+			compatible = "qcom,qcs8300-aoss-qmp", "qcom,aoss-qmp";
+			reg = <0x0 0x0c300000 0x0 0x400>;
+			interrupts-extended = <&ipcc IPCC_CLIENT_AOP
+					       IPCC_MPROC_SIGNAL_GLINK_QMP
+					       IRQ_TYPE_EDGE_RISING>;
+			mboxes = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP>;
+			#clock-cells = <0>;
+		};
+
+		tlmm: pinctrl at f100000 {
+			compatible = "qcom,qcs8300-tlmm";
+			reg = <0x0 0x0f100000 0x0 0x300000>;
+			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&tlmm 0 0 133>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			wakeup-parent = <&pdc>;
+
+			qup_uart7_default: qup-uart7-state {
+				/* TX, RX */
+				pins = "gpio43", "gpio44";
+				function = "qup0_se7";
+			};
+		};
+
+		sram: sram at 146d8000 {
+			compatible = "qcom,qcs8300-imem", "syscon", "simple-mfd";
+			reg = <0x0 0x146d8000 0x0 0x1000>;
+			ranges = <0x0 0x0 0x146d8000 0x1000>;
+
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			pil-reloc at 94c {
+				compatible = "qcom,pil-reloc-info";
+				reg = <0x94c 0xc8>;
+			};
+		};
+
+		apps_smmu: iommu at 15000000 {
+			compatible = "qcom,qcs8300-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+
+			reg = <0x0 0x15000000 0x0 0x100000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+			dma-coherent;
+
+			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI  98 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI  99 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>,
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+				     <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 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>,
+				     <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 706 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 689 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 691 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 692 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 693 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 708 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 709 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 710 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 713 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 714 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 715 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 912 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 911 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 910 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 909 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 908 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 907 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 906 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 905 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 904 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 903 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 902 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 901 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 900 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 899 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 898 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 896 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 895 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		intc: interrupt-controller at 17a00000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x17a00000 0x0 0x10000>,
+			      <0x0 0x17a60000 0x0 0x100000>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			#redistributor-regions = <1>;
+			redistributor-stride = <0x0 0x20000>;
+		};
+
+		timer at 17c20000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x17c20000 0x0 0x1000>;
+			ranges = <0x0 0x0 0x0 0x20000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			frame at 17c21000 {
+				reg = <0x17c21000 0x1000>,
+				      <0x17c22000 0x1000>;
+				frame-number = <0>;
+				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+			frame at 17c23000 {
+				reg = <0x17c23000 0x1000>;
+				frame-number = <1>;
+				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c25000 {
+				reg = <0x17c25000 0x1000>;
+				frame-number = <2>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c27000 {
+				reg = <0x17c27000 0x1000>;
+				frame-number = <3>;
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c29000 {
+				reg = <0x17c29000 0x1000>;
+				frame-number = <4>;
+				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c2b000 {
+				reg = <0x17c2b000 0x1000>;
+				frame-number = <5>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame at 17c2d000 {
+				reg = <0x17c2d000 0x1000>;
+				frame-number = <6>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		apps_rsc: rsc at 18200000 {
+			compatible = "qcom,rpmh-rsc";
+			reg = <0x0 0x18200000 0x0 0x10000>,
+			      <0x0 0x18210000 0x0 0x10000>,
+			      <0x0 0x18220000 0x0 0x10000>;
+			reg-names = "drv-0",
+				    "drv-1",
+				    "drv-2";
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+
+			power-domains = <&system_pd>;
+			label = "apps_rsc";
+
+			qcom,tcs-offset = <0xd00>;
+			qcom,drv-id = <2>;
+			qcom,tcs-config = <ACTIVE_TCS 2>,
+					  <SLEEP_TCS 3>,
+					  <WAKE_TCS 3>,
+					  <CONTROL_TCS 0>;
+
+			apps_bcm_voter: bcm-voter {
+				compatible = "qcom,bcm-voter";
+			};
+
+			rpmhcc: clock-controller {
+				compatible = "qcom,sa8775p-rpmh-clk";
+				#clock-cells = <1>;
+				clocks = <&xo_board_clk>;
+				clock-names = "xo";
+			};
+
+			rpmhpd: power-controller {
+				compatible = "qcom,qcs8300-rpmhpd";
+				#power-domain-cells = <1>;
+				operating-points-v2 = <&rpmhpd_opp_table>;
+
+				rpmhpd_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					rpmhpd_opp_ret: opp-0 {
+						opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
+					};
+
+					rpmhpd_opp_min_svs: opp-1 {
+						opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+					};
+
+					rpmhpd_opp_low_svs: opp-2 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+					};
+
+					rpmhpd_opp_svs: opp-3 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+					};
+
+					rpmhpd_opp_svs_l1: opp-4 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+					};
+
+					rpmhpd_opp_nom: opp-5 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+					};
+
+					rpmhpd_opp_nom_l1: opp-6 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+					};
+
+					rpmhpd_opp_nom_l2: opp-7 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
+					};
+
+					rpmhpd_opp_turbo: opp-8 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+					};
+
+					rpmhpd_opp_turbo_l1: opp-9 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+					};
+				};
+			};
+		};
+
+		remoteproc_gpdsp: remoteproc at 20c00000 {
+			compatible = "qcom,qcs8300-gpdsp-pas", "qcom,sa8775p-gpdsp0-pas";
+			reg = <0x0 0x20c00000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 768 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_gpdsp_in 0 0>,
+					      <&smp2p_gpdsp_in 1 0>,
+					      <&smp2p_gpdsp_in 2 0>,
+					      <&smp2p_gpdsp_in 3 0>;
+			interrupt-names = "wdog",
+					  "fatal",
+					  "ready",
+					  "handover",
+					  "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>;
+			power-domain-names = "cx",
+					     "mxc";
+
+			interconnects = <&gpdsp_anoc MASTER_DSP0 QCOM_ICC_TAG_ALWAYS
+					 &config_noc SLAVE_CLK_CTL QCOM_ICC_TAG_ALWAYS>;
+
+			memory-region = <&gpdsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_gpdsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP0
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_GPDSP0
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "gpdsp";
+				qcom,remote-pid = <17>;
+			};
+		};
+
+		nspa_noc: interconnect at 260c0000 {
+			compatible = "qcom,qcs8300-nspa-noc";
+			reg = <0x0 0x260c0000 0x0 0x16080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		remoteproc_cdsp: remoteproc at 26300000 {
+			compatible = "qcom,qcs8300-cdsp-pas", "qcom,sa8775p-cdsp0-pas";
+			reg = <0x0 0x26300000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog",
+					  "fatal",
+					  "ready",
+					  "handover",
+					  "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>,
+					<&rpmhpd RPMHPD_NSP0>;
+
+			power-domain-names = "cx",
+					     "mxc",
+					     "nsp";
+
+			interconnects = <&nspa_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+
+			memory-region = <&cdsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_cdsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_CDSP
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "cdsp";
+				qcom,remote-pid = <5>;
+			};
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+};

-- 
2.25.1



From quic_jingyw at quicinc.com  Tue Dec  3 01:27:15 2024
From: quic_jingyw at quicinc.com (Jingyi Wang)
Date: Tue, 3 Dec 2024 17:27:15 +0800
Subject: [PATCH v4 4/4] arm64: dts: qcom: add base QCS8300 RIDE board
In-Reply-To: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
References: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
Message-ID: <20241203-qcs8300_initial_dtsi-v4-4-d7c953484024@quicinc.com>

Add initial support for Qualcomm QCS8300 RIDE board which enables DSPs,
UFS and booting to shell with uart console.

Written with help from Tingguo Cheng (added rpmhpd nodes) and Xin Liu
(added ufs, adsp and gpdsp nodes).

Signed-off-by: Jingyi Wang <quic_jingyw at quicinc.com>
---
 arch/arm64/boot/dts/qcom/Makefile         |   1 +
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 235 ++++++++++++++++++++++++++++++
 2 files changed, 236 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 9bb8b191aeb5..1df3dcc1ee5d 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -114,6 +114,7 @@ dtb-$(CONFIG_ARCH_QCOM)	+= qcm6490-shift-otter.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-1000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-4000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride-r3.dtb
diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
new file mode 100644
index 000000000000..85b84778e85a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "qcs8300.dtsi"
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8300 Ride";
+	compatible = "qcom,qcs8300-ride", "qcom,qcs8300";
+	chassis-type = "embedded";
+
+	aliases {
+		serial0 = &uart7;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vreg_s4a: smps4 {
+			regulator-name = "vreg_s4a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9a: smps9 {
+			regulator-name = "vreg_s9a";
+			regulator-min-microvolt = <1352000>;
+			regulator-max-microvolt = <1352000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3a: ldo3 {
+			regulator-name = "vreg_l3a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4a: ldo4 {
+			regulator-name = "vreg_l4a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5a: ldo5 {
+			regulator-name = "vreg_l5a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6a: ldo6 {
+			regulator-name = "vreg_l6a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a: ldo7 {
+			regulator-name = "vreg_l7a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a: ldo8 {
+			regulator-name = "vreg_l8a";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a: ldo9 {
+			regulator-name = "vreg_l9a";
+			regulator-min-microvolt = <2970000>;
+			regulator-max-microvolt = <3072000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vreg_s5c: smps5 {
+			regulator-name = "vreg_s5c";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1c: ldo1 {
+			regulator-name = "vreg_l1c";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <500000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c: ldo2 {
+			regulator-name = "vreg_l2c";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <904000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c: ldo4 {
+			regulator-name = "vreg_l4c";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6c: ldo6 {
+			regulator-name = "vreg_l6c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c: ldo7 {
+			regulator-name = "vreg_l7c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c: ldo8 {
+			regulator-name = "vreg_l8c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c: ldo9 {
+			regulator-name = "vreg_l9c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/qcs8300/adsp.mbn";
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/qcs8300/cdsp0.mbn";
+	status = "okay";
+};
+
+&remoteproc_gpdsp {
+	firmware-name = "qcom/qcs8300/gpdsp0.mbn";
+	status = "okay";
+};
+
+&uart7 {
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l8a>;
+	vcc-max-microamp = <1100000>;
+	vccq-supply = <&vreg_l4c>;
+	vccq-max-microamp = <1200000>;
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l4a>;
+	vdda-pll-supply = <&vreg_l5a>;
+	status = "okay";
+};

-- 
2.25.1



From andre.draszik at linaro.org  Tue Dec  3 01:31:58 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 09:31:58 +0000
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <9387c0cf-d291-485a-8cd1-1aced7eba14e@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
	 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
	 <9387c0cf-d291-485a-8cd1-1aced7eba14e@uclouvain.be>
Message-ID: <2883fb0dd22312d5da9039d4fef869276a0bd430.camel@linaro.org>

On Tue, 2024-12-03 at 10:08 +0100, Thomas Antoine wrote:
> On 12/3/24 07:47, Andr? Draszik wrote:
> > Hi Thomas,
> > 
> > Thanks for looking into this!
> 
> Hi,
> 
> With pleasure! This is my first time trying to contribute to the kernel
> so sorry for any beginner mistakes I might do.

No worries :-)

> ?
> > > From: Thomas Antoine <t.antoine at uclouvain.be>
> > > 
> > > The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
> > > except for the non-volatile memory slave address which is not available.
> > 
> > It is not fully compatible, and it also has a lot more registers.
> > 
> > For example, the voltage now is not in register 0xda as this driver assumes.
> > With these changes, POWER_SUPPLY_PROP_VOLTAGE_NOW just reads as 0. 0xda
> > doesn't exist in max77759
> > 
> > I haven't compared in depth yet, though.
> 
> Is the voltage necessary for the driver? If so, we could just not
> read the voltage. If it is necessary, I can try to kook into it and try
> to find in which register it is located (if there is one).

Downstream reports it in
https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max1720x_battery.c#2400

so upstream should do, too.

> > > ?static const char *const max17205_model = "MAX17205";
> > > +static const char *const max77759_model = "MAX77759";
> > > 
> > > ?struct max1720x_device_info {
> > > ????? struct regmap *regmap;
> > > @@ -54,6 +57,21 @@ struct max1720x_device_info {
> > > ????? int rsense;
> > > ?};
> > > 
> > > +struct chip_data {
> > > +???? u16 default_nrsense; /* in regs in 10^-5 */
> > > +???? u8 has_nvmem;
> > > +};
> > > +
> > > +static const struct chip_data max1720x_data? = {
> > > +???? .default_nrsense = 1000,
> > > +???? .has_nvmem = 1,
> > > +};
> > > +
> > > +static const struct chip_data max77759_data = {
> > > +???? .default_nrsense = 500,
> > > +???? .has_nvmem = 0,
> > > +};
> > 
> > This should be made a required devicetree property instead, at least for
> > max77759, as it's completely board dependent, 'shunt-resistor-micro-ohms'
> > is widely used.
> > 
> > I also don't think there should be a default. The driver should just fail
> > to probe if not specified in DT (for max77759).
> 
> I hesitated to do this but I didn't know what would be better. Will change
> for v2.

Just to clarify, has_nvmem can stay here in the driver, just rsense should
go into DT is what I mean.

> > > +
> > > ?/*
> > > ? * Model Gauge M5 Algorithm output register
> > > ? * Volatile data (must not be cached)
> > > @@ -369,6 +387,8 @@ static int max1720x_battery_get_property(struct
> > > power_supply *psy,
> > > ????????????????????? val->strval = max17201_model;
> > > ????????????? else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17205)
> > > ????????????????????? val->strval = max17205_model;
> > > +???????????? else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX77759)
> > > +???????????????????? val->strval = max77759_model;
> > > ????????????? else
> > 
> > This is a 16 bit register, and while yes, MAX172XX_DEV_NAME_TYPE_MASK only
> > cares about the bottom 4 bits, the register is described as 'Firmware
> > Version Information'.
> > 
> > But maybe it's ok to do it like that, at least for now.
> 
> I thought this method would be ok as long as there is no collision on
> values. I hesitated to change the model evaluation method based on chip
> model, where the max77759 would thus have an hard-coded value and the
> max1720x would still evaluate the register value. I did not do it because
> it led to a lot more changes for no difference.

Downstream uses the upper bits for max77759:
https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max_m5.h#135

I don't know what the original max17201/5 report in this register
for those bits, though. Given for max77759 this register returns
the firmware version, I assume the lower bits can change.

Cheers,
Andre'



From t.antoine at uclouvain.be  Tue Dec  3 01:32:42 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Tue, 3 Dec 2024 10:32:42 +0100
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <fe254a002000f2bbfbe51d074cf28f7427a27f9a.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
 <fe254a002000f2bbfbe51d074cf28f7427a27f9a.camel@linaro.org>
Message-ID: <20588923-a660-49fe-8efb-766bee22f215@uclouvain.be>

On 12/3/24 07:57, Andr? Draszik wrote:
> On Mon, 2024-12-02 at 14:07 +0100, Thomas Antoine via B4 Relay wrote:
>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>
>> As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
>> make it non-obligatory. Except for this, the max77759 seems to behave the
>> same as the max1720x.
> 
> It also needs an interrupt line, and the previously mentioned shunt-
> resistor-micro-ohms, and probably a power supply.

I will try to add the interrupt line for v2. About the power supply, I
didn't see anything about it in the devicetree from Google. Even it
there is one, I guess it would be a single power supply for the whole
max77759, not just the fuel gauge. Wouldn't it be more logical to have an
mfd which activates the supply when other functions of the max77759 have
been implemented?

Best regards,
Thomas


From vt at altlinux.org  Tue Dec  3 01:27:21 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Tue, 3 Dec 2024 12:27:21 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
Message-ID: <20241203092721.j473dthkbq6wzez7@altlinux.org>

Marc,

On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > On Mon, 02 Dec 2024 15:59:40 +0000,
> > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > 
> > > Marc,
> > > 
> > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > >
> > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > 
> > > No, host is 6.6.60.
> > 
> > Right. I wouldn't be surprised if:
> > 
> > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> >   that's proably something we should backport)
> 
> How to confirm this? Currently I cannot find any (case-insensitive)
> "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM strings
> in `strace -v` (as it decodes some KVM ioctls) of qemu process.
> 
> > 
> > - you get a nastygram in the host log telling you that the guest has
> >   executed something it shouldn't (you'll get the encoding of the
> >   instruction)
> 
> I requested admins of the box for dmesg output since I don't have root
> access myself and nowadays dmesg is not accessible for a user.

This is what they reported:

  kvm [2502822]: Unsupported guest sys_reg access at: ffff80008003e9f0 [000000c5]
                   { Op0( 3), Op1( 0), CRn(10), CRm( 4), Op2( 4), func_read },

Thanks,

> 
> > 
> > Can you confirm these two things?
> 
> Also, I tried to reproduce on another Kunpeng box with slightly
> different HiSilicon CPU (presenting to the system as Cortex-A72) and the
> problem is not reproducible there.
> 
> While things are not resolved, is it possible to workaround the problem
> with some QEMU option, kernel command line, config option, or a patch?
> 
> Thanks,
> 
> > 
> > 	M.
> > 
> > -- 
> > Without deviation from the norm, progress is not possible.


From zhujun2 at cmss.chinamobile.com  Tue Dec  3 01:33:23 2024
From: zhujun2 at cmss.chinamobile.com (Zhu Jun)
Date: Tue,  3 Dec 2024 01:33:23 -0800
Subject: [RESEND] arm64: asm: Fix typo in pgtable.h
Message-ID: <20241203093323.7831-1-zhujun2@cmss.chinamobile.com>

The word 'trasferring' is wrong, so fix it.

Signed-off-by: Zhu Jun <zhujun2 at cmss.chinamobile.com>
---
 arch/arm64/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index c329ea061dc9..4a5acf522c82 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1338,7 +1338,7 @@ static inline void ___ptep_set_wrprotect(struct mm_struct *mm,
 }
 
 /*
- * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
+ * __ptep_set_wrprotect - mark read-only while transferring potential hardware
  * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
  */
 static inline void __ptep_set_wrprotect(struct mm_struct *mm,
-- 
2.17.1





From maz at kernel.org  Tue Dec  3 01:38:10 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 03 Dec 2024 09:38:10 +0000
Subject: [PATCH 5/5] KVM: arm64: Handle DABT caused by LS64* instructions on unsupported memory
In-Reply-To: <20241202135504.14252-6-yangyicong@huawei.com>
References: <20241202135504.14252-1-yangyicong@huawei.com>
	<20241202135504.14252-6-yangyicong@huawei.com>
Message-ID: <87o71trtrx.wl-maz@kernel.org>

On Mon, 02 Dec 2024 13:55:04 +0000,
Yicong Yang <yangyicong at huawei.com> wrote:
> 
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> FEAT_LS64* instructions only support to access Device/Uncacheable
> memory, otherwise a data abort for unsupported Exclusive or atomic

Not quite. FEAT_LS64WB explicitly supports Write-Back mappings.

> access (0x35) is generated per spec. It's implementation defined
> whether the target exception level is routed and is possible to
> implemented as route to EL2 on a VHE VM. Per DDI0487K.a Section
> C3.2.12.2 Single-copy atomic 64-byte load/store:
> 
>   The check is performed against the resulting memory type after all
>   enabled stages of translation. In this case the fault is reported
>   at the final enabled stage of translation.
> 
> If it's implemented as generate the DABT to the final enabled stage
> (stage-2), inject a DABT to the guest to handle it.
> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>  arch/arm64/kvm/mmu.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index c9d46ad57e52..b7e6f0a27537 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1787,6 +1787,20 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>  		return 1;
>  	}
>  
> +	/*
> +	 * If instructions of FEAT_{LS64, LS64_V, LS64_ACCDATA} operated on
> +	 * unsupported memory regions, a DABT for unsupported Exclusive or
> +	 * atomic access is generated. It's implementation defined whether
> +	 * the exception will be taken to, a stage-1 DABT or the final enabled
> +	 * stage of translation (stage-2 in this case as we hit here). Inject
> +	 * a DABT to the guest to handle it if it's implemented as a stage-2
> +	 * DABT.
> +	 */
> +	if (esr_fsc_is_excl_atomic_fault(esr)) {
> +		kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
> +		return 1;
> +	}

This doesn't seem quite right. This is injecting an *External* Data
Abort, which is not what the spec says happens, as you are emulating
the *first* acceptable behaviour:

  "The check is performed at each enabled stage of translation, and
   the fault is reported for the first stage of translation that
   provides an inappropriate memory type. In this case, the value of
   the HCR_EL2.DC bit does not cause accesses generated by the
   instructions to generate a stage 1 Data abort,"

So while the exception is reported at a different EL, the fault should
still be an "unsupported Exclusive or atomic access". But that's also
assuming that S2 has a device mapping, and it is EL1 that did
something wrong. Surely you should check the IPA against its memory
type?

Further questions: what happens when a L2 guest triggers such fault?
I don't think you can't arbitrarily route it back to L2 without
looking at why it faulted.

Thanks,

	M.

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


From maz at kernel.org  Tue Dec  3 01:38:16 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 03 Dec 2024 09:38:16 +0000
Subject: [PATCH 2/5] arm64: Add support for FEAT_{LS64, LS64_V, LS64_ACCDATA}
In-Reply-To: <20241202135504.14252-3-yangyicong@huawei.com>
References: <20241202135504.14252-1-yangyicong@huawei.com>
	<20241202135504.14252-3-yangyicong@huawei.com>
Message-ID: <87mshdrtrr.wl-maz@kernel.org>

On Mon, 02 Dec 2024 13:55:01 +0000,
Yicong Yang <yangyicong at huawei.com> wrote:
> 
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> Armv8.7 introduces single-copy atomic 64-byte loads and stores
> instructions and its variants named under FEAT_{LS64, LS64_V,
> LS64_ACCDATA}. These features are identified by ID_AA64ISAR1_EL1.LS64
> and the use of such instructions in userspace (EL0) can be trapped.
> In order to support the use of corresponding instructions in userspace:
> - Make ID_AA64ISAR1_EL1.LS64 visbile to userspace
> - Add identifying and enabling in the cpufeature list
> - Expose these support of these features to userspace through HWCAP
>   and cpuinfo
> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>  Documentation/arch/arm64/booting.rst    | 28 ++++++++++
>  Documentation/arch/arm64/elf_hwcaps.rst |  9 ++++
>  arch/arm64/include/asm/hwcap.h          |  3 ++
>  arch/arm64/include/uapi/asm/hwcap.h     |  3 ++
>  arch/arm64/kernel/cpufeature.c          | 70 ++++++++++++++++++++++++-
>  arch/arm64/kernel/cpuinfo.c             |  3 ++
>  arch/arm64/tools/cpucaps                |  3 ++
>  7 files changed, 118 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
> index 3278fb4bf219..c35cfe9da501 100644
> --- a/Documentation/arch/arm64/booting.rst
> +++ b/Documentation/arch/arm64/booting.rst
> @@ -449,6 +449,34 @@ Before jumping into the kernel, the following conditions must be met:
>  
>      - HFGWTR_EL2.nGCS_EL0 (bit 52) must be initialised to 0b1.
>  
> +  For CPUs support for 64-byte loads and stores without status (FEAT_LS64):
> +
> +  - If the kernel is entered at EL1 and EL2 is present:
> +
> +    - HCRX_EL2.EnALS (bit 1) must be initialised to 0b1.
> +
> +  For CPUs support for 64-byte loads and stores with status (FEAT_LS64_V):
> +
> +  - If the kernel is entered at EL1 and EL2 is present:
> +
> +    - HCRX_EL2.EnASR (bit 2) must be initialised to 0b1.
> +
> +  For CPUs support for 64-byte EL0 stores with status (FEAT_LS64_ACCDATA):
> +
> +  - If EL3 is present:
> +
> +    - SCR_EL3.EnAS0 (bit 36) must be initialised to 0b1.
> +
> +    - SCR_EL3.ADEn (bit 37) must be initialised to 0b1.
> +
> +  - If the kernel is entered at EL1 and EL2 is present:
> +
> +    - HCRX_EL2.EnAS0 (bit 0) must be initialised to 0b1.
> +
> +    - HFGRTR_EL2.nACCDATA_EL1 (bit 50) must be initialised to 0b1.
> +
> +    - HFGWTR_EL2.nACCDATA_EL1 (bit 50) 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
> diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst
> index 2ff922a406ad..6cb2594f0803 100644
> --- a/Documentation/arch/arm64/elf_hwcaps.rst
> +++ b/Documentation/arch/arm64/elf_hwcaps.rst
> @@ -372,6 +372,15 @@ HWCAP2_SME_SF8DP4
>  HWCAP2_POE
>      Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001.
>  
> +HWCAP3_LS64
> +    Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0001.
> +
> +HWCAP3_LS64_V
> +    Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0010.
> +
> +HWCAP3_LS64_ACCDATA
> +    Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0011.
> +

I don't mind the two others, but I seriously question exposing ST64BV0
to userspace. How is ACCDATA_EL1 populated? How is it context-switched?

As it stands, this either does the wrong thing by always having the
low 32bit set to an UNKNOWN value, or actively leaks kernel data.
TBH, I don't see it being usable in practice (the more I read this
part of the architecture, the more broken it looks).

Thanks,

	M.

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


From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:45 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:45 +0100
Subject: [PATCH v2 12/18] arm64: dts: mediatek: mt7988: add missing
 clock-div property for i2c
In-Reply-To: <20241202122602.30734-13-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-13-linux@fw-web.de>
Message-ID: <6a547915-4a20-427c-ab91-9e64d3afeb67@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> I2C binding requires clock-div property.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Can you please group all of the DTSI commits at the beginning, and all of the
BPI-R4 commits after?
Of course, do that *only* where possible - like, this one can be moved as it
is only touching the dtsi and *nothing else*.

...Besides, this commit also needs a Fixes tag ;-)

After adding the relevant Fixes tag:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:45 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:45 +0100
Subject: [PATCH v2 10/18] arm64: dts: mediatek: mt7988: enable serial0 on
 bpi-r4
In-Reply-To: <20241202122602.30734-11-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-11-linux@fw-web.de>
Message-ID: <32ef5ab8-a163-4fdc-8603-f5a6f0e8526b@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 

arm64: dts: mediatek: mt7988a-bpi-r4: Enable serial0 debug uart

> Enable the debug uart on Bananapi R4 board.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:30 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:30 +0100
Subject: [PATCH v2 18/18] arm64: dts: mediatek: mt7988: enable pwm on
 bpi-r4
In-Reply-To: <20241202122602.30734-19-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-19-linux@fw-web.de>
Message-ID: <754b7179-a3b9-48b9-90eb-cb6d6754edf6@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Enable pwm on Bananapi R4 board.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:31 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:31 +0100
Subject: [PATCH v2 17/18] arm64: dts: mediatek: mt7988: enable ssusb1 on
 bpi-r4
In-Reply-To: <20241202122602.30734-18-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-18-linux@fw-web.de>
Message-ID: <79ac6523-b002-4e10-95ac-3df378f4f3f5@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Enable front-usb on Bananapi R4 board.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:33 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:33 +0100
Subject: [PATCH v2 16/18] arm64: dts: mediatek: mt7988: add i2c-mux on
 bpi-r4
In-Reply-To: <20241202122602.30734-17-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-17-linux@fw-web.de>
Message-ID: <a521663e-f2f3-4602-8d0e-2f3841eb080b@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 

arm64: dts: mediatek: mt7988-bpi-r4: Add PCA9545 I2C Mux

> Bananapi R4 uses an i2c multiplexer for SFP slots, rtc and eeprom.
> Add its node to the right i2c controller.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
> ---
>   .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 40 +++++++++++++++++++
>   1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> index 550c373b3d70..9ceefc990000 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> @@ -2,6 +2,7 @@
>   
>   /dts-v1/;
>   
> +#include <dt-bindings/gpio/gpio.h>
>   #include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
>   
>   #include "mt7988a.dtsi"
> @@ -138,6 +139,45 @@ &i2c2 {
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&i2c2_1_pins>;
>   	status = "okay";
> +
> +	pca9545: i2c-mux at 70 {
> +		reg = <0x70>;
> +		compatible = "nxp,pca9545";

reg goes after compatible... :-)

After which

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:35 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:35 +0100
Subject: [PATCH v2 14/18] arm64: dts: mediatek: mt7988: add pmic on bpi-r4
In-Reply-To: <20241202122602.30734-15-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-15-linux@fw-web.de>
Message-ID: <a0137698-43d7-4cb6-a69c-98a5e90b13f8@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 

arm64: dts: mediatek: mt7988a-bpi-r4: Add MediaTek MT6682A/RT5190A PMIC

The BananaPi R4 board has a MediaTek MT8862A PMIC, a rebrand of the
Richtek RT5190A chip, connected to the I2C0 bus.

Add the relevant node and, while at it, also configure the regulators
from this PMIC that are used on this board.

> Bananapi R4 Board contains a MT6682A pmic which is compatible to rt5190a.
> Add its node to the i2 controller.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
>   .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 51 +++++++++++++++++++
>   1 file changed, 51 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> index 13ca016d6a67..bc1ec73b8ddd 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> @@ -2,6 +2,8 @@
>   
>   /dts-v1/;
>   
> +#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
> +
>   #include "mt7988a.dtsi"
>   
>   / {
> @@ -65,6 +67,55 @@ &i2c0 {
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&i2c0_pins>;
>   	status = "okay";
> +
> +	rt5190a_64: rt5190a at 64 {
> +		compatible = "richtek,rt5190a";
> +		reg = <0x64>;
> +		vin2-supply = <&rt5190_buck1>;
> +		vin3-supply = <&rt5190_buck1>;
> +		vin4-supply = <&rt5190_buck1>;
> +
> +		regulators {
> +			rt5190_buck1: buck1 {
> +				regulator-name = "rt5190a-buck1";
> +				regulator-min-microvolt = <5090000>;
> +				regulator-max-microvolt = <5090000>;
> +				regulator-allowed-modes =
> +				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;

Does it work like that?

regulator-allowed-modes = <RT5190A_OPMODE_AUTO>,
			  <RT5190A_OPMODE_FPWM>;

If yes, please write it like that - if not, I'm sad - but regardless

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:36 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:36 +0100
Subject: [PATCH v2 15/18] arm64: dts: mediatek: mt7988: add proc-supply
 for cpus on bpi-r4
In-Reply-To: <20241202122602.30734-16-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-16-linux@fw-web.de>
Message-ID: <b3672b3d-a336-433e-aa8a-6ddc6c8997d2@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add proc-supply property to cpus on Bananapi R4 board.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:38 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:38 +0100
Subject: [PATCH v2 13/18] arm64: dts: mediatek: mt7988: add i2c to bpi-r4
 board
In-Reply-To: <20241202122602.30734-14-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-14-linux@fw-web.de>
Message-ID: <1ad355df-3f2a-4257-9374-1d125e138791@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add basic i2c nodes to bananapi R4 board.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C controllers

Enable the I2C0, I2C2 controllers found on the BananaPi R4 board; these
controllers are accessible at ... I don't know, a header on the board?

After which,

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:44 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:44 +0100
Subject: [PATCH v2 07/18] arm64: dts: mediatek: mt7988: add reserved
 memory
In-Reply-To: <20241202122602.30734-8-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-8-linux@fw-web.de>
Message-ID: <e2b381ee-f4d0-4780-b539-53de4477d1c3@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add memory range handled by ATF to not be touched by linux kernel.
> ATF is SoC specific and not board-specific so add it to mt7988.dtsi.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Since you have to send a v3, can you please move this to be the first commit
of the series?

Would make a lot of sense :-)

> ---
>   arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> index 09dcb39ad098..1cf801486e61 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> @@ -63,6 +63,18 @@ psci {
>   		method = "smc";
>   	};
>   
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		/* 320 KiB reserved for ARM Trusted Firmware (BL31 and BL32) */
> +		secmon_reserved: secmon at 43000000 {

Are you ever modifying this outside of mt7988a.dtsi?

No!

So you don't need to add the `secmon_reserved` handle..... :-)

> +			reg = <0 0x43000000 0 0x50000>;
> +			no-map;
> +		};
> +	};
> +
>   	soc {
>   		compatible = "simple-bus";
>   		ranges;




From andrej.picej at norik.com  Tue Dec  3 01:40:43 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue, 3 Dec 2024 10:40:43 +0100
Subject: [Upstream] [PATCH v2 2/3] drm/bridge: ti-sn65dsi83: Add ti,
 lvds-vod-swing optional properties
In-Reply-To: <20241203085822.2475138-3-andrej.picej@norik.com>
References: <20241203085822.2475138-1-andrej.picej@norik.com>
 <20241203085822.2475138-3-andrej.picej@norik.com>
Message-ID: <e503b751-7c4b-4fac-ab8e-1724fd3639d2@norik.com>

Hi all,

On 3. 12. 24 09:58, Andrej Picej wrote:
> Add a optional properties to change LVDS output voltage. This should not
> be static as this depends mainly on the connected display voltage
> requirement. We have three properties:
> - "ti,lvds-termination-ohms", which sets near end termination,
> - "ti,lvds-vod-swing-data-microvolt" and
> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> output voltage for data and clock lanes. They are defined as an array
> with min and max values. The appropriate bitfiled will be set if
> selected constraints can be met.
> 
> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> end termination will be used. Selecting only one:
> "ti,lvds-vod-swing-data-microvolt" or
> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> constraint for only data/clock lanes will be met. Setting both is
> recommended.
> 
> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> ---
> Changes in v2:
> - use datasheet tables to get the proper configuration
> - since major change was done change the authorship to myself
> ---
>   drivers/gpu/drm/bridge/ti-sn65dsi83.c | 144 +++++++++++++++++++++++++-
>   1 file changed, 141 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> index 57a7ed13f996..44445d7ad52a 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> @@ -132,6 +132,16 @@
>   #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>   #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>   
> +enum sn65dsi83_channel {
> +	CHANNEL_A,
> +	CHANNEL_B
> +};
> +
> +enum sn65dsi83_lvds_term {
> +	OHM_100,
> +	OHM_200
> +};
> +
>   enum sn65dsi83_model {
>   	MODEL_SN65DSI83,
>   	MODEL_SN65DSI84,
> @@ -147,6 +157,10 @@ struct sn65dsi83 {
>   	struct regulator		*vcc;
>   	bool				lvds_dual_link;
>   	bool				lvds_dual_link_even_odd_swap;
> +	int				lvdsA_vod_swing_conf;
> +	int				lvdsB_vod_swing_conf;
> +	int				lvdsA_term_conf;
> +	int				lvdsB_term_conf;
>   };
>   
>   static const struct regmap_range sn65dsi83_readable_ranges[] = {
> @@ -237,6 +251,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>   	.max_register = REG_IRQ_STAT,
>   };
>   
> +static const int lvds_vod_swing_data_table[2][4][2] = {
> +	{	/* 100 Ohm */
> +		{ 180000, 313000 },
> +		{ 215000, 372000 },
> +		{ 250000, 430000 },
> +		{ 290000, 488000 },
> +	},
> +	{	/* 200 Ohm */
> +		{ 150000, 261000 },
> +		{ 200000, 346000 },
> +		{ 250000, 428000 },
> +		{ 300000, 511000 },
> +	},
> +};
> +
> +static const int lvds_vod_swing_clock_table[2][4][2] = {
> +	{	/* 100 Ohm */
> +		{ 140000, 244000 },
> +		{ 168000, 290000 },
> +		{ 195000, 335000 },
> +		{ 226000, 381000 },
> +	},
> +	{	/* 200 Ohm */
> +		{ 117000, 204000 },
> +		{ 156000, 270000 },
> +		{ 195000, 334000 },
> +		{ 234000, 399000 },
> +	},
> +};
> +
>   static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>   {
>   	return container_of(bridge, struct sn65dsi83, bridge);
> @@ -435,12 +479,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>   		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>   
>   	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvdsA_vod_swing_conf) |
> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvdsB_vod_swing_conf));
>   	regmap_write(ctx->regmap, REG_LVDS_LANE,
>   		     (ctx->lvds_dual_link_even_odd_swap ?
>   		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
> +		     (ctx->lvdsA_term_conf ?
> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
> +		     (ctx->lvdsB_term_conf ?
> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>   	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>   
>   	le16val = cpu_to_le16(mode->hdisplay);
> @@ -576,10 +624,96 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>   	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>   };
>   
> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
> +{
> +	int i;
> +
> +	for (i = 0; i <= 3; i++) {
> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
> +			return i;
> +	}
> +
> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
> +	return -EINVAL;
> +}
> +
> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> +{
> +	struct device *dev = ctx->dev;
> +	struct device_node *endpoint;
> +	/* Set so the property can be freely selected if not defined */
> +	u32 lvds_vod_swing_data[2] = { 0, 1000 };
> +	u32 lvds_vod_swing_clk[2] = { 0, 1000 };

I moved the code from milivolts to standard kernel voltage units 
microvolts quite recently and accidentaly forgot to apply these changes 
from my src tree. These should be:
+	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
+	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };

The code was tested with it though.

Will send a v3 ASAP. Sorry for this.

BR,
Andrej

> +	u32 lvds_term = 200;
> +	u8 lvds_term_conf;
> +	int endpoint_reg;
> +	int lvds_vod_swing_conf;
> +	int ret = 0;
> +	int ret_data;
> +	int ret_clock;
> +
> +	if (channel == CHANNEL_A)
> +		endpoint_reg = 2;
> +	else
> +		endpoint_reg = 3;
> +
> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
> +	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
> +
> +	if (lvds_term == 200)
> +		lvds_term_conf = OHM_200;
> +	else
> +		lvds_term_conf = OHM_100;
> +
> +	if (channel == CHANNEL_A)
> +		ctx->lvdsA_term_conf = lvds_term_conf;
> +	else
> +		ctx->lvdsB_term_conf = lvds_term_conf;
> +
> +	ret_data = of_property_read_u32_array(endpoint,
> +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
> +			ARRAY_SIZE(lvds_vod_swing_data));
> +	ret_clock = of_property_read_u32_array(endpoint,
> +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
> +			ARRAY_SIZE(lvds_vod_swing_clk));
> +	/* If any of the two properties is defined. */
> +	if (!ret_data || !ret_clock) {
> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
> +			lvds_vod_swing_data, lvds_vod_swing_clk,
> +			lvds_term_conf);
> +		if (lvds_vod_swing_conf < 0) {
> +			ret = lvds_vod_swing_conf;
> +			goto exit;
> +		}
> +		if (channel == CHANNEL_A)
> +			ctx->lvdsA_vod_swing_conf = lvds_vod_swing_conf;
> +		else
> +			ctx->lvdsB_vod_swing_conf = lvds_vod_swing_conf;
> +	}
> +	ret = 0;
> +exit:
> +	of_node_put(endpoint);
> +	return ret;
> +}
> +
>   static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>   {
>   	struct drm_bridge *panel_bridge;
>   	struct device *dev = ctx->dev;
> +	int ret;
> +
> +	ctx->lvdsA_vod_swing_conf = 0x1;
> +	ctx->lvdsB_vod_swing_conf = 0x1;
> +	ctx->lvdsA_term_conf = 0x1;
> +	ctx->lvdsB_term_conf = 0x1;
> +
> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
> +	if (ret < 0)
> +		return ret;
>   
>   	ctx->lvds_dual_link = false;
>   	ctx->lvds_dual_link_even_odd_swap = false;
> @@ -587,6 +721,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>   		struct device_node *port2, *port3;
>   		int dual_link;
>   
> +		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
> +		if (ret < 0)
> +			return ret;
> +
>   		port2 = of_graph_get_port_by_id(dev->of_node, 2);
>   		port3 = of_graph_get_port_by_id(dev->of_node, 3);
>   		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);


From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:47 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:47 +0100
Subject: [PATCH v2 05/18] arm64: dts: mediatek: mt7988: add thermal-zone
In-Reply-To: <20241202122602.30734-6-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-6-linux@fw-web.de>
Message-ID: <d9ca723c-300b-4f38-9a1c-125df2fb982b@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add basic thermal-zone node.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:48 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:48 +0100
Subject: [PATCH v2 08/18] arm64: dts: mediatek: mt7988: add mcu-sys node
 for cpu
In-Reply-To: <20241202122602.30734-9-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-9-linux@fw-web.de>
Message-ID: <4ad16e9a-15ae-4b2f-964e-ea6d7981f49d@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add mcu-sys node which is used later as clock-controller for cpus.

In preparation for adding support for CPU DVFS and clock tables for it,
add the MCUSYS clock controller node.

> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:50 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:50 +0100
Subject: [PATCH v2 04/18] arm64: dts: mediatek: mt7988: add lvts node
In-Reply-To: <20241202122602.30734-5-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-5-linux@fw-web.de>
Message-ID: <aade3f32-b0c5-4f36-b3e4-f2ff077110e2@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add Low Voltage Thermal Sensor (LVTS) node for mt7988 SoC.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
> changes:
> 
> v2:
> squash
> - "arm64: dts: mediatek: mt7988: add label for efuse"
> - "arm64: dts: mediatek: mt7988: extend efuse node" (drop other efuse subnodes)
> ---
>   arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 19 ++++++++++++++++++-
>   1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> index 5e40446cb7b3..f7748a840297 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> @@ -4,6 +4,7 @@
>   #include <dt-bindings/interrupt-controller/arm-gic.h>
>   #include <dt-bindings/phy/phy.h>
>   #include <dt-bindings/pinctrl/mt65xx.h>
> +#include <dt-bindings/reset/mediatek,mt7988-resets.h>
>   
>   / {
>   	compatible = "mediatek,mt7988a";
> @@ -85,6 +86,7 @@ infracfg: clock-controller at 10001000 {
>   			compatible = "mediatek,mt7988-infracfg", "syscon";
>   			reg = <0 0x10001000 0 0x1000>;
>   			#clock-cells = <1>;
> +			#reset-cells = <1>;
>   		};
>   
>   		topckgen: clock-controller at 1001b000 {
> @@ -250,6 +252,17 @@ i2c at 11005000 {
>   			status = "disabled";
>   		};
>   
> +		lvts: lvts at 1100a000 {
> +			compatible = "mediatek,mt7988-lvts-ap";
> +			#thermal-sensor-cells = <1>;
> +			reg = <0 0x1100a000 0 0x1000>;
> +			clocks = <&infracfg CLK_INFRA_26M_THERM_SYSTEM>;
> +			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
> +			resets = <&infracfg MT7988_INFRA_RST1_THERM_CTRL_SWRST>;
> +			nvmem-cells = <&lvts_calibration>;
> +			nvmem-cell-names = "lvts-calib-data-1";
> +		};
> +
>   		usb at 11190000 {
>   			compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
>   			reg = <0 0x11190000 0 0x2e00>,
> @@ -307,11 +320,15 @@ clock-controller at 11f40000 {
>   			#clock-cells = <1>;
>   		};
>   
> -		efuse at 11f50000 {
> +		efuse: efuse at 11f50000 {

Okay but why are you adding the efuse handle name to this node?
You're not using it anywhere as far as I can see.

Please drop this change - after which:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

>   			compatible = "mediatek,mt7988-efuse", "mediatek,efuse";
>   			reg = <0 0x11f50000 0 0x1000>;
>   			#address-cells = <1>;
>   			#size-cells = <1>;
> +
> +			lvts_calibration: calib at 918 {
> +				reg = <0x918 0x28>;
> +			};
>   		};
>   
>   		clock-controller at 15000000 {



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:51 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:51 +0100
Subject: [PATCH v2 01/18] arm64: dts: mediatek: mt7988: enable watchdog on
 bpi-r4
In-Reply-To: <20241202122602.30734-2-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-2-linux@fw-web.de>
Message-ID: <fbda4aee-7b9d-4a13-848f-165097032df8@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Enable the watchdog on Bananapi R4 board.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:53 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:53 +0100
Subject: [PATCH v2 02/18] arm64: dts: mediatek: mt7988: add mmc support
In-Reply-To: <20241202122602.30734-3-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-3-linux@fw-web.de>
Message-ID: <d726c20e-a7fc-4477-b2f9-b933d993a566@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add devicetree node for MMC controller.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
> changes:
> v2:
> squash "add missing label for apmixedsys"
> ---
>   arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 24 ++++++++++++++++++++++-
>   1 file changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> index 46969577c87a..5e40446cb7b3 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> @@ -100,7 +100,7 @@ watchdog: watchdog at 1001c000 {
>   			#reset-cells = <1>;
>   		};
>   
> -		clock-controller at 1001e000 {
> +		apmixedsys: clock-controller at 1001e000 {
>   			compatible = "mediatek,mt7988-apmixedsys";
>   			reg = <0 0x1001e000 0 0x1000>;
>   			#clock-cells = <1>;
> @@ -278,6 +278,28 @@ usb at 11200000 {
>   			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
>   		};
>   
> +		mmc0: mmc at 11230000 {
> +			compatible = "mediatek,mt7988-mmc";
> +			reg = <0 0x11230000 0 0x1000>,
> +			      <0 0x11D60000 0 0x1000>;
> +			interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&infracfg CLK_INFRA_MSDC400>,
> +				 <&infracfg CLK_INFRA_MSDC2_HCK>,
> +				 <&infracfg CLK_INFRA_66M_MSDC_0_HCK>,
> +				 <&infracfg CLK_INFRA_133M_MSDC_0_HCK>;
> +			assigned-clocks = <&topckgen CLK_TOP_EMMC_250M_SEL>,
> +					  <&topckgen CLK_TOP_EMMC_400M_SEL>;
> +			assigned-clock-parents = <&topckgen CLK_TOP_NET1PLL_D5_D2>,
> +						 <&apmixedsys CLK_APMIXED_MSDCPLL>;
> +			clock-names = "source",
> +				      "hclk",
> +				      "axi_cg",
> +				      "ahb_cg";

One last nitpick: all of the clock-names *do* fit in one line.

			clock-names = "source", "hclk", "axi_cg", "ahb_cg";

After which

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:54 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:54 +0100
Subject: [PATCH v2 03/18] arm64: dts: mediatek: mt7988: add fixed
 regulators for 1v8 and 3v3
In-Reply-To: <20241202122602.30734-4-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-4-linux@fw-web.de>
Message-ID: <016b77dc-2d33-4639-b241-2574ad877971@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add regulator nodes used for mmc to Bananapi R4 board.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

If you're adding the eMMC regulators, I assume that there's an eMMC, or that even
if there's no device in some version of the board, these two regulators are always
assigned to the eMMC device - right?

You should, at this point, do exactly that: you can leave the mmc0 disabled and
only enable it in a DTBO.

&mmc0 {
	/* eMMC gets enabled by DTBO if present */
	vmmc-supply = <&reg_3p3v>;
	vqmmc-supply = <&reg_1p8v>;
};

Cheers,
Angelo

> ---
> v2:
> - move mmc regulators to board dts of bpi-r4
> ---
>   .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts   | 18 ++++++++++++++++++
>   1 file changed, 18 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> index d914eae2b524..df53512c6890 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> @@ -8,6 +8,24 @@ / {
>   	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
>   	model = "Banana Pi BPI-R4";
>   	chassis-type = "embedded";
> +
> +	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;
> +	};
>   };
>   
>   &pio {




From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:39 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:39 +0100
Subject: [PATCH v2 11/18] arm64: dts: mediatek: mt7988: add chosen node on
 bpi-r4
In-Reply-To: <20241202122602.30734-12-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-12-linux@fw-web.de>
Message-ID: <d4ccb1fd-29a8-474d-9fb8-1cdc327b83c2@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 

arm64: dts: mediatek: mt7988a-bpi-r4: Add default bootargs and UART stdout

> Add chosen node on Bananapi R4 board with stdout and default bootargs.

> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 5 +++++
>   1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> index 9037f35857a9..1c2a806f6f6c 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
> @@ -9,6 +9,11 @@ / {
>   	model = "Banana Pi BPI-R4";
>   	chassis-type = "embedded";
>   
> +	chosen {
> +		stdout-path = &serial0;
> +		bootargs = "console=ttyS0,115200n1";
> +	};
> +
>   	reg_1p8v: regulator-1p8v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "fixed-1.8V";




From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:40 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:40 +0100
Subject: [PATCH v2 06/18] arm64: dts: mediatek: mt7988: add thermal trips
 to bpi-r4
In-Reply-To: <20241202122602.30734-7-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-7-linux@fw-web.de>
Message-ID: <a564687c-3b9e-4f13-a671-ebdbdde30cc5@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 

arm64: dts: mediatek: mt7988a-bpi-r4: Add thermal configuration

> Add additional thermal trips to Bananapi R4 board.
> SoC only contains the critical trip.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Dec  3 01:40:41 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 10:40:41 +0100
Subject: [PATCH v2 09/18] arm64: dts: mediatek: mt7988: add
 operating-points
In-Reply-To: <20241202122602.30734-10-linux@fw-web.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-10-linux@fw-web.de>
Message-ID: <8196dbf8-983b-406d-aa85-db51b5609293@collabora.com>

Il 02/12/24 13:25, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 

arm64: dts: mediatek: mt7988: Add CPU OPP table for clock scaling

> Add operating points defining frequency/voltages of cpu cores.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From andre.draszik at linaro.org  Tue Dec  3 01:45:02 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 09:45:02 +0000
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <8f585460a1bc52f78a6d0867aed87398bde30152.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
	 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
	 <8f585460a1bc52f78a6d0867aed87398bde30152.camel@linaro.org>
Message-ID: <18629c9edd295a524a1c9764f013a0e97e0b275f.camel@linaro.org>

On Tue, 2024-12-03 at 07:23 +0000, Andr? Draszik wrote:
> On Tue, 2024-12-03 at 06:47 +0000, Andr? Draszik wrote:
> > Hi Thomas,
> > 
> > Thanks for looking into this!
> > 
> > > From: Thomas Antoine <t.antoine at uclouvain.be>
> > > 
> > > The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
> > > except for the non-volatile memory slave address which is not available.
> > 
> > It is not fully compatible, and it also has a lot more registers.
> > 
> > For example, the voltage now is not in register 0xda as this driver assumes.
> > With these changes, POWER_SUPPLY_PROP_VOLTAGE_NOW just reads as 0. 0xda
> > doesn't exist in max77759
> > 
> > I haven't compared in depth yet, though.
> 
> Regarding the regmap in this driver, please see below comparison I had
> collected some time ago:
> 
> 	regmap_reg_range(0x24, 0x26), // exists
> 	regmap_reg_range(0x30, 0x31), // exists
> 	regmap_reg_range(0x33, 0x34), // exists
> 	regmap_reg_range(0x37, 0x37), // exists
> 	regmap_reg_range(0x3B, 0x3C), // exists
> 	regmap_reg_range(0x40, 0x41), // exists
> 	regmap_reg_range(0x43, 0x44), // exists
> 	regmap_reg_range(0x47, 0x49), // exists
> 	regmap_reg_range(0x4B, 0x4C), // exists
> 	regmap_reg_range(0x4E, 0xAF), // 0x4e 0x4f exists
> 	regmap_reg_range(0xB1, 0xB3), // exists
> 	regmap_reg_range(0xB5, 0xB7), // exists
> 	regmap_reg_range(0xBF, 0xD0), // 0xd0 exists
> 	0xd1 .. 0xdb don't exist
> 	regmap_reg_range(0xDB, 0xDB),
> 	regmap_reg_range(0xE0, 0xFF), // 0xfb 0xff exist
> 
> the comments refer to whether or not the register exists in max77759

I think this should make it more clear:
allow:
	regmap_reg_range(0x00, 0xff),
deny:
	regmap_reg_range(0x50, 0xaf),
	regmap_reg_range(0xc0, 0xcf),
	regmap_reg_range(0xd1, 0xdb),
	regmap_reg_range(0xe0, 0xfa),
	regmap_reg_range(0xfc, 0xfe),

Cheers,
Andre'



From shameerali.kolothum.thodi at huawei.com  Tue Dec  3 02:03:11 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Tue, 3 Dec 2024 10:03:11 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <20241203092721.j473dthkbq6wzez7@altlinux.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck> <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org> <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
 <20241203092721.j473dthkbq6wzez7@altlinux.org>
Message-ID: <1847e34fa7724d28aeb22d93752f64f2@huawei.com>



> -----Original Message-----
> From: linux-arm-kernel <linux-arm-kernel-bounces at lists.infradead.org> On
> Behalf Of Vitaly Chikunov
> Sent: Tuesday, December 3, 2024 9:27 AM
> To: Marc Zyngier <maz at kernel.org>
> Cc: Will Deacon <will at kernel.org>; james.morse at arm.com; linux-arm-
> kernel at lists.infradead.org; Catalin Marinas <catalin.marinas at arm.com>;
> linux-kernel at vger.kernel.org; oliver.upton at linux.dev;
> mark.rutland at arm.com
> Subject: Re: v6.13-rc1: Internal error: Oops - Undefined instruction:
> 0000000002000000 [#1] SMP
> 
> Marc,
> 
> On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> > On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > > On Mon, 02 Dec 2024 15:59:40 +0000,
> > > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > >
> > > > Marc,
> > > >
> > > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > > >
> > > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > >
> > > > No, host is 6.6.60.
> > >
> > > Right. I wouldn't be surprised if:
> > >
> > > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> > >   that's proably something we should backport)
> >
> > How to confirm this? Currently I cannot find any (case-insensitive)
> > "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM
> > strings in `strace -v` (as it decodes some KVM ioctls) of qemu process.
> >
> > >
> > > - you get a nastygram in the host log telling you that the guest has
> > >   executed something it shouldn't (you'll get the encoding of the
> > >   instruction)
> >
> > I requested admins of the box for dmesg output since I don't have root
> > access myself and nowadays dmesg is not accessible for a user.
> 
> This is what they reported:
> 
>   kvm [2502822]: Unsupported guest sys_reg access at: ffff80008003e9f0
> [000000c5]
>                    { Op0( 3), Op1( 0), CRn(10), CRm( 4), Op2( 4), func_read },
> 

As Will pointed out I think this is access to MPAMIDR_EL1 and is from this
code here,

+++ b/arch/arm64/kernel/cpuinfo.c
@@ -478,6 +478,9 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
 		__cpuinfo_store_cpu_32bit(&info->aarch32);
 
+	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
+		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
+
 	cpuinfo_detect_icache_policy(info);
 }

I did manage to boot my setup in 6.6 and this is what happens,

Host kernel 6.6
Guest Kernel 6.13-rc1

[    0.195392] smp: Brought up 1 node, 8 CPUs
[    0.219000] SMP: Total of 8 processors activated.
[    0.219629] CPU: All CPU(s) started at EL1
...
[    0.223212] CPU features: detected: RAS Extension Support
[    0.223927] CPU features: detected: Memory Partitioning And Monitoring
[    0.224796] CPU features: detected: Memory Partitioning And Monitoring Virtualisation
[    0.225961] alternatives: applying system-wide alternatives
...

Guest detects MPAM and boots fine.

Host kernel 6.13-rc1
Guest Kernel 6.13-rc1

[    0.196625] smp: Brought up 1 node, 8 CPUs
[    0.222093] SMP: Total of 8 processors activated.
[    0.222769] CPU: All CPU(s) started at EL1
...
[    0.226620] CPU features: detected: RAS Extension Support
[    0.227453] alternatives: applying system-wide alternatives

MPAM is not visible to Guest in this case.

So as I pointed out earlier could it be a case where the ID register reports MPAM support
but the firmware has not enabled MPAM?

James seems to be mentioning that case here,

" (If you have a boot failure that bisects here its likely your CPUs
advertise MPAM in the id registers, but firmware failed to either enable
or MPAM, or emulate the trap as if it were disabled)"

https://lore.kernel.org/all/20241030160317.2528209-4-joey.gouly at arm.com/

Is there a way you can find out the BIOS version on that board?

Thanks,
Shameer



From kevin.brodsky at arm.com  Tue Dec  3 02:03:22 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Tue,  3 Dec 2024 10:03:22 +0000
Subject: [PATCH] arm64: signal: Ensure signal delivery failure is recoverable
Message-ID: <20241203100322.1626805-1-kevin.brodsky@arm.com>

Commit eaf62ce1563b ("arm64/signal: Set up and restore the GCS
context for signal handlers") introduced a potential failure point
at the end of setup_return(). This is unfortunate as it is too late
to deliver a SIGSEGV: if that SIGSEGV is handled, the subsequent
sigreturn will end up returning to the original handler, which is
not the intention (since we failed to deliver that signal).

Make sure this does not happen by calling gcs_signal_entry()
at the very beginning of setup_return(), and add a comment just
after to discourage error cases being introduced from that point
onwards.

While at it, also take care of copy_siginfo_to_user(): since it may
fail, we shouldn't be calling it after setup_return() either. Call
it before setup_return() instead, and move the setting of X1/X2
inside setup_return() where it belongs (after the "point of no
failure").

Background: the first part of setup_rt_frame(), including
setup_sigframe(), has no impact on the execution of the interrupted
thread. The signal frame is written to the stack, but the stack
pointer remains unchanged. Failure at this stage can be recovered by
a SIGSEGV handler, and sigreturn will restore the original context,
at the point where the original signal occurred. On the other hand,
once setup_return() has updated registers including SP, the thread's
control flow has been modified and we must deliver the original
signal.

Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")
Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
Cc: broonie at kernel.org
Cc: catalin.marinas at arm.com
Cc: Dave.Martin at arm.com
Cc: will at kernel.org
---
 arch/arm64/kernel/signal.c | 43 +++++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 14ac6fdb872b..0adaa165b876 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -1462,10 +1462,33 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
 			 struct rt_sigframe_user_layout *user, int usig)
 {
 	__sigrestore_t sigtramp;
+	int err;
+
+	if (ksig->ka.sa.sa_flags & SA_RESTORER)
+		sigtramp = ksig->ka.sa.sa_restorer;
+	else
+		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
+
+	err = gcs_signal_entry(sigtramp, ksig);
+	if (err)
+		return err;
+
+	/*
+	 * We must not fail from this point onwards. We are going to update
+	 * registers, including SP, in order to invoke the signal handler. If
+	 * we failed and attempted to deliver a nested SIGSEGV to a handler
+	 * after that point, the subsequent sigreturn would end up restoring
+	 * the (partial) state for the original signal handler.
+	 */
 
 	regs->regs[0] = usig;
+	if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+		regs->regs[1] = (unsigned long)&user->sigframe->info;
+		regs->regs[2] = (unsigned long)&user->sigframe->uc;
+	}
 	regs->sp = (unsigned long)user->sigframe;
 	regs->regs[29] = (unsigned long)&user->next_frame->fp;
+	regs->regs[30] = (unsigned long)sigtramp;
 	regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
 
 	/*
@@ -1506,14 +1529,7 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
 		sme_smstop();
 	}
 
-	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);
+	return 0;
 }
 
 static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
@@ -1537,14 +1553,11 @@ 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, &ua_state);
-	if (err == 0) {
+	if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+		err |= copy_siginfo_to_user(&frame->info, &ksig->info);
+
+	if (err == 0)
 		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;
-			regs->regs[2] = (unsigned long)&frame->uc;
-		}
-	}
 
 	if (err == 0)
 		set_handler_user_access_state();
-- 
2.47.0



From andre.draszik at linaro.org  Tue Dec  3 02:07:23 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 10:07:23 +0000
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <20588923-a660-49fe-8efb-766bee22f215@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
	 <fe254a002000f2bbfbe51d074cf28f7427a27f9a.camel@linaro.org>
	 <20588923-a660-49fe-8efb-766bee22f215@uclouvain.be>
Message-ID: <b311b50e0f54959cd8dac1ef21dd798dd6204331.camel@linaro.org>

On Tue, 2024-12-03 at 10:32 +0100, Thomas Antoine wrote:
> On 12/3/24 07:57, Andr? Draszik wrote:
> > On Mon, 2024-12-02 at 14:07 +0100, Thomas Antoine via B4 Relay wrote:
> > > From: Thomas Antoine <t.antoine at uclouvain.be>
> > > 
> > > As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
> > > make it non-obligatory. Except for this, the max77759 seems to behave the
> > > same as the max1720x.
> > 
> > It also needs an interrupt line, and the previously mentioned shunt-
> > resistor-micro-ohms, and probably a power supply.
> 
> I will try to add the interrupt line for v2. About the power supply, I
> didn't see anything about it in the devicetree from Google. Even it
> there is one, I guess it would be a single power supply for the whole
> max77759, not just the fuel gauge. Wouldn't it be more logical to have an
> mfd which activates the supply when other functions of the max77759 have
> been implemented?

I've looked it up now and for power supply nothing indeed seems necessary.


Cheers,
Andre'



From arnd at arndb.de  Tue Dec  3 02:08:17 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 03 Dec 2024 11:08:17 +0100
Subject: [PATCH] arm: Remove IO memcpy for Big-Endian
In-Reply-To: <20241203083838.3260036-1-jvetter@outer-limits.org>
References: <20241203083838.3260036-1-jvetter@outer-limits.org>
Message-ID: <609b026d-d54c-4a11-b7df-6ef0ac315f25@app.fastmail.com>

On Tue, Dec 3, 2024, at 09:38, Julian Vetter wrote:
> From: Julian Vetter <julian at outer-limits.org>
>
> Recently a new IO memcpy was added in libs/iomem_copy.c. So, remove the
> byte-wise IO memcpy operations used in ARM big endian builds and fall
> back to the new generic implementation. It will be slightly faster,
> because it uses machine word accesses if the memory is aligned and falls
> back to byte-wise accesses if its not.
>
> Signed-off-by: Julian Vetter <julian at outer-limits.org>
> ---
>  arch/arm/include/asm/io.h | 11 ----------
>  arch/arm/kernel/io.c      | 46 ---------------------------------------
>  2 files changed, 57 deletions(-)

I'm not sure if this is safe on all platforms. Big-endian arm
is extremely rare in practice, and in comes in multiple variants
that behave slightly differently:

- On modern ARMv7 the byte-invariant big-endian "BE8" mode
  generally well-behaved and works as one would expect it to.

- There is one ARMv5 "BE32" based platform, the ixp4xx, which
  works differently, and this in turn allows multiple configurations
  for its buses where a byte-swap is performed in the PCI
  controller.

When the little-endian I/O string operations got optimized to
calling the word-based helpers in commit 7ddfe625cbc1 ("ARM:
optimize memset_io()/memcpy_fromio()/memcpy_toio()"), Russell
intentionally left the big-endian versions alone, which I think
was done for the case of PCI on ixp4xx, but could have been
out of general caution.

Before we apply your patch, I think the minimum would be to
have Linus Walleij try it out on an an ixp4xx with a driver
that uses these functions. Maybe Russell remembers the exact
constraints that led to using byte access for big-endian
mmio string operations, and whether the new lib/iomem_copy.c
version causes problems.

I also looked at the little-endian arm32 version, and
it seems that here the generic code would work fine, but
the custom variant is likely much faster when both the
source and destination buffers are aligned, as it can
do larger MMIO transactions using ldm/stm instructions,
though the generic version would be a bit better if the
in-memory buffer is unaligned.
We could get the best of both by implementing optimized
arm32 versions __iowrite32_copy()/__ioread32_copy and
using those in the generic memcpy_{from,to}io.

       Arnd


From t.antoine at uclouvain.be  Tue Dec  3 02:11:15 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Tue, 3 Dec 2024 11:11:15 +0100
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <2883fb0dd22312d5da9039d4fef869276a0bd430.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
 <9387c0cf-d291-485a-8cd1-1aced7eba14e@uclouvain.be>
 <2883fb0dd22312d5da9039d4fef869276a0bd430.camel@linaro.org>
Message-ID: <bce22ca8-aed2-41ae-b2ef-fdc71266709a@uclouvain.be>

On 12/3/24 10:31, Andr? Draszik wrote:
> On Tue, 2024-12-03 at 10:08 +0100, Thomas Antoine wrote:
>> On 12/3/24 07:47, Andr? Draszik wrote:
>>>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>>>
>>>> The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
>>>> except for the non-volatile memory slave address which is not available.
>>>
>>> It is not fully compatible, and it also has a lot more registers.
>>>
>>> For example, the voltage now is not in register 0xda as this driver assumes.
>>> With these changes, POWER_SUPPLY_PROP_VOLTAGE_NOW just reads as 0. 0xda
>>> doesn't exist in max77759
>>>
>>> I haven't compared in depth yet, though.
>>
>> Is the voltage necessary for the driver? If so, we could just not
>> read the voltage. If it is necessary, I can try to kook into it and try
>> to find in which register it is located (if there is one).
> 
> Downstream reports it in
> https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max1720x_battery.c#2400
> 
> so upstream should do, too.

I should have checked before answering. Indeed, I will try to see the
best way to choose the register based on the chip. From what I see, it
will also be necessary to change the translation of the reg value to microvolt
as downstream does *78125/1000 when it is currently *1250 in mainline:
https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max1720x_battery.h#49
 
>>>>  static const char *const max17205_model = "MAX17205";
>>>> +static const char *const max77759_model = "MAX77759";
>>>>
>>>>  struct max1720x_device_info {
>>>>       struct regmap *regmap;
>>>> @@ -54,6 +57,21 @@ struct max1720x_device_info {
>>>>       int rsense;
>>>>  };
>>>>
>>>> +struct chip_data {
>>>> +     u16 default_nrsense; /* in regs in 10^-5 */
>>>> +     u8 has_nvmem;
>>>> +};
>>>> +
>>>> +static const struct chip_data max1720x_data  = {
>>>> +     .default_nrsense = 1000,
>>>> +     .has_nvmem = 1,
>>>> +};
>>>> +
>>>> +static const struct chip_data max77759_data = {
>>>> +     .default_nrsense = 500,
>>>> +     .has_nvmem = 0,
>>>> +};
>>>
>>> This should be made a required devicetree property instead, at least for
>>> max77759, as it's completely board dependent, 'shunt-resistor-micro-ohms'
>>> is widely used.
>>>
>>> I also don't think there should be a default. The driver should just fail
>>> to probe if not specified in DT (for max77759).
>>
>> I hesitated to do this but I didn't know what would be better. Will change
>> for v2.
> 
> Just to clarify, has_nvmem can stay here in the driver, just rsense should
> go into DT is what I mean.

It was clear don't worry. This answer is related to the same subject:
https://lore.kernel.org/linux-devicetree/20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30 at uclouvain.be/T/#ma55f41d42bf39be826d6cbf8987138bcc4eb52e3

>>>> +
>>>>  /*
>>>>   * Model Gauge M5 Algorithm output register
>>>>   * Volatile data (must not be cached)
>>>> @@ -369,6 +387,8 @@ static int max1720x_battery_get_property(struct
>>>> power_supply *psy,
>>>>                       val->strval = max17201_model;
>>>>               else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17205)
>>>>                       val->strval = max17205_model;
>>>> +             else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX77759)
>>>> +                     val->strval = max77759_model;
>>>>               else
>>>
>>> This is a 16 bit register, and while yes, MAX172XX_DEV_NAME_TYPE_MASK only
>>> cares about the bottom 4 bits, the register is described as 'Firmware
>>> Version Information'.
>>>
>>> But maybe it's ok to do it like that, at least for now.
>>
>> I thought this method would be ok as long as there is no collision on
>> values. I hesitated to change the model evaluation method based on chip
>> model, where the max77759 would thus have an hard-coded value and the
>> max1720x would still evaluate the register value. I did not do it because
>> it led to a lot more changes for no difference.
> 
> Downstream uses the upper bits for max77759:
> https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max_m5.h#135
> 
> I don't know what the original max17201/5 report in this register
> for those bits, though. Given for max77759 this register returns
> the firmware version, I assume the lower bits can change.

Based on this datasheet of the max1720x, the upper bits are the revision
and the four lower bits are device. So it could change.
https://www.analog.com/media/en/technical-documentation/data-sheets/MAX17201-MAX17215.pdf#MAX17201%20DS.indd%3A.213504%3A15892

If the four lower bits are not always 0 for the max77759 then I guess it
is necessary to change this as it wouldn't work with all max77759.


Best regards,
Thomas


From johan at kernel.org  Tue Dec  3 02:20:48 2024
From: johan at kernel.org (Johan Hovold)
Date: Tue, 3 Dec 2024 11:20:48 +0100
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint reader
In-Reply-To: <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
Message-ID: <Z07bgH5vVk44zuEH@hovoldconsulting.com>

[ +CC: Krishna, Thinh and the USB list ]

On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
> The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
> multiport controller on eUSB6. All other ports (including USB super-speed
> pins) are unused.
> 
> Set it up in the device tree together with the NXP PTN3222 repeater.
> 
> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 48 +++++++++++++++++++++++++++++++
>  1 file changed, 48 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> index 39f9d9cdc10d..44942931c18f 100644
> --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> @@ -735,6 +735,26 @@ keyboard at 3a {
>  	};
>  };
>  
> +&i2c5 {
> +	clock-frequency = <400000>;
> +
> +	status = "okay";
> +
> +	eusb6_repeater: redriver at 4f {
> +		compatible = "nxp,ptn3222";
> +		reg = <0x4f>;

The driver does not currently check that there's actually anything at
this address. Did you verify that this is the correct address? 

(Abel is adding a check to the driver as we speak to catch any such
mistakes going forward).

> +		#phy-cells = <0>;

nit: I'd put provider properties like this one last.

> +		vdd3v3-supply = <&vreg_l13b_3p0>;
> +		vdd1v8-supply = <&vreg_l4b_1p8>;

Sort by supply name?

> +		reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>;
> +
> +		pinctrl-0 = <&eusb6_reset_n>;
> +		pinctrl-names = "default";
> +	};
> +};
> +
>  &i2c8 {
>  	clock-frequency = <400000>;
>  
> @@ -1047,6 +1067,14 @@ edp_reg_en: edp-reg-en-state {
>  		bias-disable;
>  	};
>  
> +	eusb6_reset_n: eusb6-reset-n-state {
> +		pins = "gpio184";
> +		function = "gpio";
> +		drive-strength = <2>;
> +		bias-disable;
> +		output-low;

I don't think the pin config should assert reset, that should be up to
the driver to control.

> +	};
> +
>  	hall_int_n_default: hall-int-n-state {
>  		pins = "gpio92";
>  		function = "gpio";
> @@ -1260,3 +1288,23 @@ &usb_1_ss2_dwc3_hs {
>  &usb_1_ss2_qmpphy_out {
>  	remote-endpoint = <&pmic_glink_ss2_ss_in>;
>  };
> +
> +&usb_mp {
> +	status = "okay";
> +};
> +
> +&usb_mp_dwc3 {
> +	/* Limit to USB 2.0 and single port */
> +	maximum-speed = "high-speed";
> +	phys = <&usb_mp_hsphy1>;
> +	phy-names = "usb2-1";
> +};

The dwc3 driver determines (and acts on) the number of ports based on
the port interrupts in DT and controller capabilities. 

I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
that would still be there in the SoC (possibly initialised by the boot
firmware).

I had a local patch to enable the multiport controller (for the suspend
work) and I realise that you'd currently need to specify a repeater also
for the HS PHY which does not have one, but that should be possible to
fix somehow.

> +
> +&usb_mp_hsphy1 {
> +	vdd-supply = <&vreg_l2e_0p8>;
> +	vdda12-supply = <&vreg_l3e_1p2>;
> +
> +	phys = <&eusb6_repeater>;
> +
> +	status = "okay";
> +};

Johan


From t.antoine at uclouvain.be  Tue Dec  3 02:23:41 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Tue, 3 Dec 2024 11:23:41 +0100
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <e23721ebd766f410103ddfb8705f3d7d6e5ae3e9.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
 <e23721ebd766f410103ddfb8705f3d7d6e5ae3e9.camel@linaro.org>
Message-ID: <575b3275-b2fa-4e5c-bb6b-759394b02e18@uclouvain.be>

On 12/3/24 08:12, Andr? Draszik wrote:
> On Mon, 2024-12-02 at 14:07 +0100, Thomas Antoine via B4 Relay wrote:
>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>
>> As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
>> make it non-obligatory. Except for this, the max77759 seems to behave the
>> same as the max1720x.
> 
> What about the battery characterization tables? Aren't they needed for
> correct reporting?

I checked some other patches which added fuel gauge and other bindings and I
couldn't find such characterization table. Can you point me to an example or
explain what it should contain if there needs one?

Best regards,
Thomas


From jens.wiklander at linaro.org  Tue Dec  3 02:28:02 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 3 Dec 2024 11:28:02 +0100
Subject: [PATCH v3 2/4] optee: account for direction while converting parameters
In-Reply-To: <CAFA6WYPEqCWyvD=pCj6DEkZWN9SCfXMnq4tKbSx1-e8UmgXb=Q@mail.gmail.com>
References: <20241128150927.1377981-1-jens.wiklander@linaro.org>
 <20241128150927.1377981-3-jens.wiklander@linaro.org> <CAFA6WYPEqCWyvD=pCj6DEkZWN9SCfXMnq4tKbSx1-e8UmgXb=Q@mail.gmail.com>
Message-ID: <CAHUa44H0go3fSMt_jreWz4EQgYvo8GOZ5woc-x5Cyi680oWZWw@mail.gmail.com>

Hi Sumit,

On Tue, Dec 3, 2024 at 9:27?AM Sumit Garg <sumit.garg at linaro.org> wrote:
>
> Hi Jens,
>
> On Thu, 28 Nov 2024 at 20:39, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> >
> > The OP-TEE backend driver has two internal function pointers to convert
> > between the subsystem type struct tee_param and the OP-TEE type struct
> > optee_msg_param.
> >
> > The conversion is done from one of the types to the other, which is then
> > involved in some operation and finally converted back to the original
> > type. When converting to prepare the parameters for the operation, all
> > fields must be taken into account, but then converting back, it's enough
> > to update only out-values and out-sizes. So, an update_out parameter is
> > added to the conversion functions to tell if all or only some fields
> > must be copied.
>
> Is this patch just a refactoring of TEE params handling? Or are we
> fixing a real ABI issue here? Also, is this required for restricted
> shared memory support to work? Just asking if we want to consider it
> as a fix for backporting or if we can handle this refactoring patch
> independently of this series?

This is needed in this series. Without this patch, it might get
confusing when converting back in from_msg_param() callback since an
allocated restricted SHM can be using the sec_world_id of the pool and
that doesn't translate back well. params_to_user() in
drivers/tee/tee_core.c already takes the direction into account so it
wouldn't spread to user-space.

Cheers,
Jens

>
> -Sumit
>
> >
> > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > ---
> >  drivers/tee/optee/call.c          | 10 ++--
> >  drivers/tee/optee/ffa_abi.c       | 43 +++++++++++++----
> >  drivers/tee/optee/optee_private.h | 42 +++++++++++------
> >  drivers/tee/optee/rpc.c           | 31 +++++++++----
> >  drivers/tee/optee/smc_abi.c       | 76 +++++++++++++++++++++++--------
> >  5 files changed, 144 insertions(+), 58 deletions(-)
> >
> > diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
> > index 16eb953e14bb..f1533b894726 100644
> > --- a/drivers/tee/optee/call.c
> > +++ b/drivers/tee/optee/call.c
> > @@ -400,7 +400,8 @@ int optee_open_session(struct tee_context *ctx,
> >         export_uuid(msg_arg->params[1].u.octets, &client_uuid);
> >
> >         rc = optee->ops->to_msg_param(optee, msg_arg->params + 2,
> > -                                     arg->num_params, param);
> > +                                     arg->num_params, param,
> > +                                     false /*!update_out*/);
> >         if (rc)
> >                 goto out;
> >
> > @@ -427,7 +428,8 @@ int optee_open_session(struct tee_context *ctx,
> >         }
> >
> >         if (optee->ops->from_msg_param(optee, param, arg->num_params,
> > -                                      msg_arg->params + 2)) {
> > +                                      msg_arg->params + 2,
> > +                                      true /*update_out*/)) {
> >                 arg->ret = TEEC_ERROR_COMMUNICATION;
> >                 arg->ret_origin = TEEC_ORIGIN_COMMS;
> >                 /* Close session again to avoid leakage */
> > @@ -541,7 +543,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
> >         msg_arg->cancel_id = arg->cancel_id;
> >
> >         rc = optee->ops->to_msg_param(optee, msg_arg->params, arg->num_params,
> > -                                     param);
> > +                                     param, false /*!update_out*/);
> >         if (rc)
> >                 goto out;
> >
> > @@ -551,7 +553,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
> >         }
> >
> >         if (optee->ops->from_msg_param(optee, param, arg->num_params,
> > -                                      msg_arg->params)) {
> > +                                      msg_arg->params, true /*update_out*/)) {
> >                 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
> >                 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
> >         }
> > diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
> > index f3af5666bb11..02e6175ac5f0 100644
> > --- a/drivers/tee/optee/ffa_abi.c
> > +++ b/drivers/tee/optee/ffa_abi.c
> > @@ -122,15 +122,21 @@ static int optee_shm_rem_ffa_handle(struct optee *optee, u64 global_id)
> >   */
> >
> >  static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> > -                                  u32 attr, const struct optee_msg_param *mp)
> > +                                  u32 attr, const struct optee_msg_param *mp,
> > +                                  bool update_out)
> >  {
> >         struct tee_shm *shm = NULL;
> >         u64 offs_high = 0;
> >         u64 offs_low = 0;
> >
> > +       if (update_out) {
> > +               if (attr == OPTEE_MSG_ATTR_TYPE_FMEM_INPUT)
> > +                       return;
> > +               goto out;
> > +       }
> > +
> >         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> >                   attr - OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
> > -       p->u.memref.size = mp->u.fmem.size;
> >
> >         if (mp->u.fmem.global_id != OPTEE_MSG_FMEM_INVALID_GLOBAL_ID)
> >                 shm = optee_shm_from_ffa_handle(optee, mp->u.fmem.global_id);
> > @@ -141,6 +147,8 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> >                 offs_high = mp->u.fmem.offs_high;
> >         }
> >         p->u.memref.shm_offs = offs_low | offs_high << 32;
> > +out:
> > +       p->u.memref.size = mp->u.fmem.size;
> >  }
> >
> >  /**
> > @@ -150,12 +158,14 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> >   * @params:    subsystem internal parameter representation
> >   * @num_params:        number of elements in the parameter arrays
> >   * @msg_params:        OPTEE_MSG parameters
> > + * @update_out: update parameter for output only
> >   *
> >   * Returns 0 on success or <0 on failure
> >   */
> >  static int optee_ffa_from_msg_param(struct optee *optee,
> >                                     struct tee_param *params, size_t num_params,
> > -                                   const struct optee_msg_param *msg_params)
> > +                                   const struct optee_msg_param *msg_params,
> > +                                   bool update_out)
> >  {
> >         size_t n;
> >
> > @@ -166,18 +176,20 @@ static int optee_ffa_from_msg_param(struct optee *optee,
> >
> >                 switch (attr) {
> >                 case OPTEE_MSG_ATTR_TYPE_NONE:
> > +                       if (update_out)
> > +                               break;
> >                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> >                         memset(&p->u, 0, sizeof(p->u));
> >                         break;
> >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
> > -                       optee_from_msg_param_value(p, attr, mp);
> > +                       optee_from_msg_param_value(p, attr, mp, update_out);
> >                         break;
> >                 case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
> > -                       from_msg_param_ffa_mem(optee, p, attr, mp);
> > +                       from_msg_param_ffa_mem(optee, p, attr, mp, update_out);
> >                         break;
> >                 default:
> >                         return -EINVAL;
> > @@ -188,10 +200,16 @@ static int optee_ffa_from_msg_param(struct optee *optee,
> >  }
> >
> >  static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> > -                               const struct tee_param *p)
> > +                               const struct tee_param *p, bool update_out)
> >  {
> >         struct tee_shm *shm = p->u.memref.shm;
> >
> > +       if (update_out) {
> > +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> > +                       return 0;
> > +               goto out;
> > +       }
> > +
> >         mp->attr = OPTEE_MSG_ATTR_TYPE_FMEM_INPUT + p->attr -
> >                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> >
> > @@ -211,6 +229,7 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> >                 memset(&mp->u, 0, sizeof(mp->u));
> >                 mp->u.fmem.global_id = OPTEE_MSG_FMEM_INVALID_GLOBAL_ID;
> >         }
> > +out:
> >         mp->u.fmem.size = p->u.memref.size;
> >
> >         return 0;
> > @@ -222,13 +241,15 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> >   * @optee:     main service struct
> >   * @msg_params:        OPTEE_MSG parameters
> >   * @num_params:        number of elements in the parameter arrays
> > - * @params:    subsystem itnernal parameter representation
> > + * @params:    subsystem internal parameter representation
> > + * @update_out: update parameter for output only
> >   * Returns 0 on success or <0 on failure
> >   */
> >  static int optee_ffa_to_msg_param(struct optee *optee,
> >                                   struct optee_msg_param *msg_params,
> >                                   size_t num_params,
> > -                                 const struct tee_param *params)
> > +                                 const struct tee_param *params,
> > +                                 bool update_out)
> >  {
> >         size_t n;
> >
> > @@ -238,18 +259,20 @@ static int optee_ffa_to_msg_param(struct optee *optee,
> >
> >                 switch (p->attr) {
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
> > +                       if (update_out)
> > +                               break;
> >                         mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> >                         memset(&mp->u, 0, sizeof(mp->u));
> >                         break;
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
> > -                       optee_to_msg_param_value(mp, p);
> > +                       optee_to_msg_param_value(mp, p, update_out);
> >                         break;
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
> > -                       if (to_msg_param_ffa_mem(mp, p))
> > +                       if (to_msg_param_ffa_mem(mp, p, update_out))
> >                                 return -EINVAL;
> >                         break;
> >                 default:
> > diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
> > index dc0f355ef72a..20eda508dbac 100644
> > --- a/drivers/tee/optee/optee_private.h
> > +++ b/drivers/tee/optee/optee_private.h
> > @@ -185,10 +185,12 @@ struct optee_ops {
> >                                 bool system_thread);
> >         int (*to_msg_param)(struct optee *optee,
> >                             struct optee_msg_param *msg_params,
> > -                           size_t num_params, const struct tee_param *params);
> > +                           size_t num_params, const struct tee_param *params,
> > +                           bool update_out);
> >         int (*from_msg_param)(struct optee *optee, struct tee_param *params,
> >                               size_t num_params,
> > -                             const struct optee_msg_param *msg_params);
> > +                             const struct optee_msg_param *msg_params,
> > +                             bool update_out);
> >  };
> >
> >  /**
> > @@ -316,23 +318,35 @@ void optee_release(struct tee_context *ctx);
> >  void optee_release_supp(struct tee_context *ctx);
> >
> >  static inline void optee_from_msg_param_value(struct tee_param *p, u32 attr,
> > -                                             const struct optee_msg_param *mp)
> > +                                             const struct optee_msg_param *mp,
> > +                                             bool update_out)
> >  {
> > -       p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
> > -                 attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> > -       p->u.value.a = mp->u.value.a;
> > -       p->u.value.b = mp->u.value.b;
> > -       p->u.value.c = mp->u.value.c;
> > +       if (!update_out)
> > +               p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
> > +                         attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> > +
> > +       if (attr == OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT ||
> > +           attr == OPTEE_MSG_ATTR_TYPE_VALUE_INOUT || !update_out) {
> > +               p->u.value.a = mp->u.value.a;
> > +               p->u.value.b = mp->u.value.b;
> > +               p->u.value.c = mp->u.value.c;
> > +       }
> >  }
> >
> >  static inline void optee_to_msg_param_value(struct optee_msg_param *mp,
> > -                                           const struct tee_param *p)
> > +                                           const struct tee_param *p,
> > +                                           bool update_out)
> >  {
> > -       mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
> > -                  TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> > -       mp->u.value.a = p->u.value.a;
> > -       mp->u.value.b = p->u.value.b;
> > -       mp->u.value.c = p->u.value.c;
> > +       if (!update_out)
> > +               mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
> > +                          TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> > +
> > +       if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
> > +           p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT || !update_out) {
> > +               mp->u.value.a = p->u.value.a;
> > +               mp->u.value.b = p->u.value.b;
> > +               mp->u.value.c = p->u.value.c;
> > +       }
> >  }
> >
> >  void optee_cq_init(struct optee_call_queue *cq, int thread_count);
> > diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
> > index ebbbd42b0e3e..580e6b9b0606 100644
> > --- a/drivers/tee/optee/rpc.c
> > +++ b/drivers/tee/optee/rpc.c
> > @@ -63,7 +63,7 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
> >         }
> >
> >         if (optee->ops->from_msg_param(optee, params, arg->num_params,
> > -                                      arg->params))
> > +                                      arg->params, false /*!update_out*/))
> >                 goto bad;
> >
> >         for (i = 0; i < arg->num_params; i++) {
> > @@ -107,7 +107,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
> >         } else {
> >                 params[3].u.value.a = msg.len;
> >                 if (optee->ops->to_msg_param(optee, arg->params,
> > -                                            arg->num_params, params))
> > +                                            arg->num_params, params,
> > +                                            true /*update_out*/))
> >                         arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> >                 else
> >                         arg->ret = TEEC_SUCCESS;
> > @@ -188,6 +189,7 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
> >  static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
> >                                 struct optee_msg_arg *arg)
> >  {
> > +       bool update_out = false;
> >         struct tee_param *params;
> >
> >         arg->ret_origin = TEEC_ORIGIN_COMMS;
> > @@ -200,15 +202,21 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
> >         }
> >
> >         if (optee->ops->from_msg_param(optee, params, arg->num_params,
> > -                                      arg->params)) {
> > +                                      arg->params, update_out)) {
> >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> >                 goto out;
> >         }
> >
> >         arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
> >
> > +       /*
> > +        * Special treatment for OPTEE_RPC_CMD_SHM_ALLOC since input is a
> > +        * value type, but the output is a memref type.
> > +        */
> > +       if (arg->cmd != OPTEE_RPC_CMD_SHM_ALLOC)
> > +               update_out = true;
> >         if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
> > -                                    params))
> > +                                    params, update_out))
> >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> >  out:
> >         kfree(params);
> > @@ -270,7 +278,7 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
> >
> >         if (arg->num_params != ARRAY_SIZE(params) ||
> >             optee->ops->from_msg_param(optee, params, arg->num_params,
> > -                                      arg->params) ||
> > +                                      arg->params, false /*!update_out*/) ||
> >             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT) {
> >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> >                 return;
> > @@ -280,7 +288,8 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
> >         params[0].u.value.b = 0;
> >         params[0].u.value.c = 0;
> >         if (optee->ops->to_msg_param(optee, arg->params,
> > -                                    arg->num_params, params)) {
> > +                                    arg->num_params, params,
> > +                                    true /*update_out*/)) {
> >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> >                 return;
> >         }
> > @@ -324,7 +333,7 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
> >
> >         if (arg->num_params != ARRAY_SIZE(params) ||
> >             optee->ops->from_msg_param(optee, params, arg->num_params,
> > -                                      arg->params) ||
> > +                                      arg->params, false /*!update_out*/) ||
> >             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
> >             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
> >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > @@ -358,7 +367,8 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
> >         params[0].u.value.b = rdev->descr.capacity;
> >         params[0].u.value.c = rdev->descr.reliable_wr_count;
> >         if (optee->ops->to_msg_param(optee, arg->params,
> > -                                    arg->num_params, params)) {
> > +                                    arg->num_params, params,
> > +                                    true /*update_out*/)) {
> >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> >                 return;
> >         }
> > @@ -384,7 +394,7 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
> >
> >         if (arg->num_params != ARRAY_SIZE(params) ||
> >             optee->ops->from_msg_param(optee, params, arg->num_params,
> > -                                      arg->params) ||
> > +                                      arg->params, false /*!update_out*/) ||
> >             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT ||
> >             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
> >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > @@ -401,7 +411,8 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
> >                 goto out;
> >         }
> >         if (optee->ops->to_msg_param(optee, arg->params,
> > -                                    arg->num_params, params)) {
> > +                                    arg->num_params, params,
> > +                                    true /*update_out*/)) {
> >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> >                 goto out;
> >         }
> > diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
> > index e9456e3e74cc..d1f79947f58a 100644
> > --- a/drivers/tee/optee/smc_abi.c
> > +++ b/drivers/tee/optee/smc_abi.c
> > @@ -81,20 +81,26 @@ static int optee_cpuhp_disable_pcpu_irq(unsigned int cpu)
> >   */
> >
> >  static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
> > -                                 const struct optee_msg_param *mp)
> > +                                 const struct optee_msg_param *mp,
> > +                                 bool update_out)
> >  {
> >         struct tee_shm *shm;
> >         phys_addr_t pa;
> >         int rc;
> >
> > +       if (update_out) {
> > +               if (attr == OPTEE_MSG_ATTR_TYPE_TMEM_INPUT)
> > +                       return 0;
> > +               goto out;
> > +       }
> > +
> >         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> >                   attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
> > -       p->u.memref.size = mp->u.tmem.size;
> >         shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
> >         if (!shm) {
> >                 p->u.memref.shm_offs = 0;
> >                 p->u.memref.shm = NULL;
> > -               return 0;
> > +               goto out;
> >         }
> >
> >         rc = tee_shm_get_pa(shm, 0, &pa);
> > @@ -103,18 +109,25 @@ static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
> >
> >         p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
> >         p->u.memref.shm = shm;
> > -
> > +out:
> > +       p->u.memref.size = mp->u.tmem.size;
> >         return 0;
> >  }
> >
> >  static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> > -                                  const struct optee_msg_param *mp)
> > +                                  const struct optee_msg_param *mp,
> > +                                  bool update_out)
> >  {
> >         struct tee_shm *shm;
> >
> > +       if (update_out) {
> > +               if (attr == OPTEE_MSG_ATTR_TYPE_RMEM_INPUT)
> > +                       return;
> > +               goto out;
> > +       }
> > +
> >         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> >                   attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
> > -       p->u.memref.size = mp->u.rmem.size;
> >         shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
> >
> >         if (shm) {
> > @@ -124,6 +137,8 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> >                 p->u.memref.shm_offs = 0;
> >                 p->u.memref.shm = NULL;
> >         }
> > +out:
> > +       p->u.memref.size = mp->u.rmem.size;
> >  }
> >
> >  /**
> > @@ -133,11 +148,13 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> >   * @params:    subsystem internal parameter representation
> >   * @num_params:        number of elements in the parameter arrays
> >   * @msg_params:        OPTEE_MSG parameters
> > + * @update_out:        update parameter for output only
> >   * Returns 0 on success or <0 on failure
> >   */
> >  static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
> >                                 size_t num_params,
> > -                               const struct optee_msg_param *msg_params)
> > +                               const struct optee_msg_param *msg_params,
> > +                               bool update_out)
> >  {
> >         int rc;
> >         size_t n;
> > @@ -149,25 +166,27 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
> >
> >                 switch (attr) {
> >                 case OPTEE_MSG_ATTR_TYPE_NONE:
> > +                       if (update_out)
> > +                               break;
> >                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> >                         memset(&p->u, 0, sizeof(p->u));
> >                         break;
> >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
> > -                       optee_from_msg_param_value(p, attr, mp);
> > +                       optee_from_msg_param_value(p, attr, mp, update_out);
> >                         break;
> >                 case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
> > -                       rc = from_msg_param_tmp_mem(p, attr, mp);
> > +                       rc = from_msg_param_tmp_mem(p, attr, mp, update_out);
> >                         if (rc)
> >                                 return rc;
> >                         break;
> >                 case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
> >                 case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
> > -                       from_msg_param_reg_mem(p, attr, mp);
> > +                       from_msg_param_reg_mem(p, attr, mp, update_out);
> >                         break;
> >
> >                 default:
> > @@ -178,20 +197,25 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
> >  }
> >
> >  static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
> > -                               const struct tee_param *p)
> > +                               const struct tee_param *p, bool update_out)
> >  {
> >         int rc;
> >         phys_addr_t pa;
> >
> > +       if (update_out) {
> > +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> > +                       return 0;
> > +               goto out;
> > +       }
> > +
> >         mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
> >                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> >
> >         mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
> > -       mp->u.tmem.size = p->u.memref.size;
> >
> >         if (!p->u.memref.shm) {
> >                 mp->u.tmem.buf_ptr = 0;
> > -               return 0;
> > +               goto out;
> >         }
> >
> >         rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa);
> > @@ -201,19 +225,27 @@ static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
> >         mp->u.tmem.buf_ptr = pa;
> >         mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
> >                     OPTEE_MSG_ATTR_CACHE_SHIFT;
> > -
> > +out:
> > +       mp->u.tmem.size = p->u.memref.size;
> >         return 0;
> >  }
> >
> >  static int to_msg_param_reg_mem(struct optee_msg_param *mp,
> > -                               const struct tee_param *p)
> > +                               const struct tee_param *p, bool update_out)
> >  {
> > +       if (update_out) {
> > +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> > +                       return 0;
> > +               goto out;
> > +       }
> > +
> >         mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
> >                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> >
> >         mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm;
> > -       mp->u.rmem.size = p->u.memref.size;
> >         mp->u.rmem.offs = p->u.memref.shm_offs;
> > +out:
> > +       mp->u.rmem.size = p->u.memref.size;
> >         return 0;
> >  }
> >
> > @@ -223,11 +255,13 @@ static int to_msg_param_reg_mem(struct optee_msg_param *mp,
> >   * @msg_params:        OPTEE_MSG parameters
> >   * @num_params:        number of elements in the parameter arrays
> >   * @params:    subsystem itnernal parameter representation
> > + * @update_out:        update parameter for output only
> >   * Returns 0 on success or <0 on failure
> >   */
> >  static int optee_to_msg_param(struct optee *optee,
> >                               struct optee_msg_param *msg_params,
> > -                             size_t num_params, const struct tee_param *params)
> > +                             size_t num_params, const struct tee_param *params,
> > +                             bool update_out)
> >  {
> >         int rc;
> >         size_t n;
> > @@ -238,21 +272,23 @@ static int optee_to_msg_param(struct optee *optee,
> >
> >                 switch (p->attr) {
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
> > +                       if (update_out)
> > +                               break;
> >                         mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> >                         memset(&mp->u, 0, sizeof(mp->u));
> >                         break;
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
> > -                       optee_to_msg_param_value(mp, p);
> > +                       optee_to_msg_param_value(mp, p, update_out);
> >                         break;
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
> >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
> >                         if (tee_shm_is_dynamic(p->u.memref.shm))
> > -                               rc = to_msg_param_reg_mem(mp, p);
> > +                               rc = to_msg_param_reg_mem(mp, p, update_out);
> >                         else
> > -                               rc = to_msg_param_tmp_mem(mp, p);
> > +                               rc = to_msg_param_tmp_mem(mp, p, update_out);
> >                         if (rc)
> >                                 return rc;
> >                         break;
> > --
> > 2.43.0
> >


From t.antoine at uclouvain.be  Tue Dec  3 02:30:38 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Tue, 3 Dec 2024 11:30:38 +0100
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <18629c9edd295a524a1c9764f013a0e97e0b275f.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
 <8f585460a1bc52f78a6d0867aed87398bde30152.camel@linaro.org>
 <18629c9edd295a524a1c9764f013a0e97e0b275f.camel@linaro.org>
Message-ID: <61a54367-2406-4106-bf8b-9fda4f2d11a6@uclouvain.be>

On 12/3/24 10:45, Andr? Draszik wrote:
> On Tue, 2024-12-03 at 07:23 +0000, Andr? Draszik wrote:
>> On Tue, 2024-12-03 at 06:47 +0000, Andr? Draszik wrote:
>>> Hi Thomas,
>>>
>>> Thanks for looking into this!
>>>
>>>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>>>
>>>> The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
>>>> except for the non-volatile memory slave address which is not available.
>>>
>>> It is not fully compatible, and it also has a lot more registers.
>>>
>>> For example, the voltage now is not in register 0xda as this driver assumes.
>>> With these changes, POWER_SUPPLY_PROP_VOLTAGE_NOW just reads as 0. 0xda
>>> doesn't exist in max77759
>>>
>>> I haven't compared in depth yet, though.
>>
>> Regarding the regmap in this driver, please see below comparison I had
>> collected some time ago:
>>
>> 	regmap_reg_range(0x24, 0x26), // exists
>> 	regmap_reg_range(0x30, 0x31), // exists
>> 	regmap_reg_range(0x33, 0x34), // exists
>> 	regmap_reg_range(0x37, 0x37), // exists
>> 	regmap_reg_range(0x3B, 0x3C), // exists
>> 	regmap_reg_range(0x40, 0x41), // exists
>> 	regmap_reg_range(0x43, 0x44), // exists
>> 	regmap_reg_range(0x47, 0x49), // exists
>> 	regmap_reg_range(0x4B, 0x4C), // exists
>> 	regmap_reg_range(0x4E, 0xAF), // 0x4e 0x4f exists
>> 	regmap_reg_range(0xB1, 0xB3), // exists
>> 	regmap_reg_range(0xB5, 0xB7), // exists
>> 	regmap_reg_range(0xBF, 0xD0), // 0xd0 exists
>> 	0xd1 .. 0xdb don't exist
>> 	regmap_reg_range(0xDB, 0xDB),
>> 	regmap_reg_range(0xE0, 0xFF), // 0xfb 0xff exist
>>
>> the comments refer to whether or not the register exists in max77759
> 
> I think this should make it more clear:
> allow:
> 	regmap_reg_range(0x00, 0xff),
> deny:
> 	regmap_reg_range(0x50, 0xaf),
> 	regmap_reg_range(0xc0, 0xcf),
> 	regmap_reg_range(0xd1, 0xdb),
> 	regmap_reg_range(0xe0, 0xfa),
> 	regmap_reg_range(0xfc, 0xfe),

Should I explicitly deny their use in the code for the max77759 or is it
just for information?

Best regards,
Thomas


From sumit.garg at linaro.org  Tue Dec  3 02:35:37 2024
From: sumit.garg at linaro.org (Sumit Garg)
Date: Tue, 3 Dec 2024 16:05:37 +0530
Subject: [PATCH v3 2/4] optee: account for direction while converting parameters
In-Reply-To: <CAHUa44H0go3fSMt_jreWz4EQgYvo8GOZ5woc-x5Cyi680oWZWw@mail.gmail.com>
References: <20241128150927.1377981-1-jens.wiklander@linaro.org>
 <20241128150927.1377981-3-jens.wiklander@linaro.org> <CAFA6WYPEqCWyvD=pCj6DEkZWN9SCfXMnq4tKbSx1-e8UmgXb=Q@mail.gmail.com>
 <CAHUa44H0go3fSMt_jreWz4EQgYvo8GOZ5woc-x5Cyi680oWZWw@mail.gmail.com>
Message-ID: <CAFA6WYNJQEjs29AniqC7mdmo7Fe+fCmW1kFcJ1Z2HSjQQ36LBw@mail.gmail.com>

On Tue, 3 Dec 2024 at 15:58, Jens Wiklander <jens.wiklander at linaro.org> wrote:
>
> Hi Sumit,
>
> On Tue, Dec 3, 2024 at 9:27?AM Sumit Garg <sumit.garg at linaro.org> wrote:
> >
> > Hi Jens,
> >
> > On Thu, 28 Nov 2024 at 20:39, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> > >
> > > The OP-TEE backend driver has two internal function pointers to convert
> > > between the subsystem type struct tee_param and the OP-TEE type struct
> > > optee_msg_param.
> > >
> > > The conversion is done from one of the types to the other, which is then
> > > involved in some operation and finally converted back to the original
> > > type. When converting to prepare the parameters for the operation, all
> > > fields must be taken into account, but then converting back, it's enough
> > > to update only out-values and out-sizes. So, an update_out parameter is
> > > added to the conversion functions to tell if all or only some fields
> > > must be copied.
> >
> > Is this patch just a refactoring of TEE params handling? Or are we
> > fixing a real ABI issue here? Also, is this required for restricted
> > shared memory support to work? Just asking if we want to consider it
> > as a fix for backporting or if we can handle this refactoring patch
> > independently of this series?
>
> This is needed in this series. Without this patch, it might get
> confusing when converting back in from_msg_param() callback since an
> allocated restricted SHM can be using the sec_world_id of the pool and
> that doesn't translate back well. params_to_user() in
> drivers/tee/tee_core.c already takes the direction into account so it
> wouldn't spread to user-space.

Thanks Jens for the clarification, if you can update the commit text
accordingly will help clarify the motivation for the change.

-Sumit

>
> Cheers,
> Jens
>
> >
> > -Sumit
> >
> > >
> > > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > > ---
> > >  drivers/tee/optee/call.c          | 10 ++--
> > >  drivers/tee/optee/ffa_abi.c       | 43 +++++++++++++----
> > >  drivers/tee/optee/optee_private.h | 42 +++++++++++------
> > >  drivers/tee/optee/rpc.c           | 31 +++++++++----
> > >  drivers/tee/optee/smc_abi.c       | 76 +++++++++++++++++++++++--------
> > >  5 files changed, 144 insertions(+), 58 deletions(-)
> > >
> > > diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
> > > index 16eb953e14bb..f1533b894726 100644
> > > --- a/drivers/tee/optee/call.c
> > > +++ b/drivers/tee/optee/call.c
> > > @@ -400,7 +400,8 @@ int optee_open_session(struct tee_context *ctx,
> > >         export_uuid(msg_arg->params[1].u.octets, &client_uuid);
> > >
> > >         rc = optee->ops->to_msg_param(optee, msg_arg->params + 2,
> > > -                                     arg->num_params, param);
> > > +                                     arg->num_params, param,
> > > +                                     false /*!update_out*/);
> > >         if (rc)
> > >                 goto out;
> > >
> > > @@ -427,7 +428,8 @@ int optee_open_session(struct tee_context *ctx,
> > >         }
> > >
> > >         if (optee->ops->from_msg_param(optee, param, arg->num_params,
> > > -                                      msg_arg->params + 2)) {
> > > +                                      msg_arg->params + 2,
> > > +                                      true /*update_out*/)) {
> > >                 arg->ret = TEEC_ERROR_COMMUNICATION;
> > >                 arg->ret_origin = TEEC_ORIGIN_COMMS;
> > >                 /* Close session again to avoid leakage */
> > > @@ -541,7 +543,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
> > >         msg_arg->cancel_id = arg->cancel_id;
> > >
> > >         rc = optee->ops->to_msg_param(optee, msg_arg->params, arg->num_params,
> > > -                                     param);
> > > +                                     param, false /*!update_out*/);
> > >         if (rc)
> > >                 goto out;
> > >
> > > @@ -551,7 +553,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
> > >         }
> > >
> > >         if (optee->ops->from_msg_param(optee, param, arg->num_params,
> > > -                                      msg_arg->params)) {
> > > +                                      msg_arg->params, true /*update_out*/)) {
> > >                 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
> > >                 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
> > >         }
> > > diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
> > > index f3af5666bb11..02e6175ac5f0 100644
> > > --- a/drivers/tee/optee/ffa_abi.c
> > > +++ b/drivers/tee/optee/ffa_abi.c
> > > @@ -122,15 +122,21 @@ static int optee_shm_rem_ffa_handle(struct optee *optee, u64 global_id)
> > >   */
> > >
> > >  static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> > > -                                  u32 attr, const struct optee_msg_param *mp)
> > > +                                  u32 attr, const struct optee_msg_param *mp,
> > > +                                  bool update_out)
> > >  {
> > >         struct tee_shm *shm = NULL;
> > >         u64 offs_high = 0;
> > >         u64 offs_low = 0;
> > >
> > > +       if (update_out) {
> > > +               if (attr == OPTEE_MSG_ATTR_TYPE_FMEM_INPUT)
> > > +                       return;
> > > +               goto out;
> > > +       }
> > > +
> > >         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> > >                   attr - OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
> > > -       p->u.memref.size = mp->u.fmem.size;
> > >
> > >         if (mp->u.fmem.global_id != OPTEE_MSG_FMEM_INVALID_GLOBAL_ID)
> > >                 shm = optee_shm_from_ffa_handle(optee, mp->u.fmem.global_id);
> > > @@ -141,6 +147,8 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> > >                 offs_high = mp->u.fmem.offs_high;
> > >         }
> > >         p->u.memref.shm_offs = offs_low | offs_high << 32;
> > > +out:
> > > +       p->u.memref.size = mp->u.fmem.size;
> > >  }
> > >
> > >  /**
> > > @@ -150,12 +158,14 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> > >   * @params:    subsystem internal parameter representation
> > >   * @num_params:        number of elements in the parameter arrays
> > >   * @msg_params:        OPTEE_MSG parameters
> > > + * @update_out: update parameter for output only
> > >   *
> > >   * Returns 0 on success or <0 on failure
> > >   */
> > >  static int optee_ffa_from_msg_param(struct optee *optee,
> > >                                     struct tee_param *params, size_t num_params,
> > > -                                   const struct optee_msg_param *msg_params)
> > > +                                   const struct optee_msg_param *msg_params,
> > > +                                   bool update_out)
> > >  {
> > >         size_t n;
> > >
> > > @@ -166,18 +176,20 @@ static int optee_ffa_from_msg_param(struct optee *optee,
> > >
> > >                 switch (attr) {
> > >                 case OPTEE_MSG_ATTR_TYPE_NONE:
> > > +                       if (update_out)
> > > +                               break;
> > >                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> > >                         memset(&p->u, 0, sizeof(p->u));
> > >                         break;
> > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
> > > -                       optee_from_msg_param_value(p, attr, mp);
> > > +                       optee_from_msg_param_value(p, attr, mp, update_out);
> > >                         break;
> > >                 case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
> > > -                       from_msg_param_ffa_mem(optee, p, attr, mp);
> > > +                       from_msg_param_ffa_mem(optee, p, attr, mp, update_out);
> > >                         break;
> > >                 default:
> > >                         return -EINVAL;
> > > @@ -188,10 +200,16 @@ static int optee_ffa_from_msg_param(struct optee *optee,
> > >  }
> > >
> > >  static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> > > -                               const struct tee_param *p)
> > > +                               const struct tee_param *p, bool update_out)
> > >  {
> > >         struct tee_shm *shm = p->u.memref.shm;
> > >
> > > +       if (update_out) {
> > > +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> > > +                       return 0;
> > > +               goto out;
> > > +       }
> > > +
> > >         mp->attr = OPTEE_MSG_ATTR_TYPE_FMEM_INPUT + p->attr -
> > >                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> > >
> > > @@ -211,6 +229,7 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> > >                 memset(&mp->u, 0, sizeof(mp->u));
> > >                 mp->u.fmem.global_id = OPTEE_MSG_FMEM_INVALID_GLOBAL_ID;
> > >         }
> > > +out:
> > >         mp->u.fmem.size = p->u.memref.size;
> > >
> > >         return 0;
> > > @@ -222,13 +241,15 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> > >   * @optee:     main service struct
> > >   * @msg_params:        OPTEE_MSG parameters
> > >   * @num_params:        number of elements in the parameter arrays
> > > - * @params:    subsystem itnernal parameter representation
> > > + * @params:    subsystem internal parameter representation
> > > + * @update_out: update parameter for output only
> > >   * Returns 0 on success or <0 on failure
> > >   */
> > >  static int optee_ffa_to_msg_param(struct optee *optee,
> > >                                   struct optee_msg_param *msg_params,
> > >                                   size_t num_params,
> > > -                                 const struct tee_param *params)
> > > +                                 const struct tee_param *params,
> > > +                                 bool update_out)
> > >  {
> > >         size_t n;
> > >
> > > @@ -238,18 +259,20 @@ static int optee_ffa_to_msg_param(struct optee *optee,
> > >
> > >                 switch (p->attr) {
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
> > > +                       if (update_out)
> > > +                               break;
> > >                         mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> > >                         memset(&mp->u, 0, sizeof(mp->u));
> > >                         break;
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
> > > -                       optee_to_msg_param_value(mp, p);
> > > +                       optee_to_msg_param_value(mp, p, update_out);
> > >                         break;
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
> > > -                       if (to_msg_param_ffa_mem(mp, p))
> > > +                       if (to_msg_param_ffa_mem(mp, p, update_out))
> > >                                 return -EINVAL;
> > >                         break;
> > >                 default:
> > > diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
> > > index dc0f355ef72a..20eda508dbac 100644
> > > --- a/drivers/tee/optee/optee_private.h
> > > +++ b/drivers/tee/optee/optee_private.h
> > > @@ -185,10 +185,12 @@ struct optee_ops {
> > >                                 bool system_thread);
> > >         int (*to_msg_param)(struct optee *optee,
> > >                             struct optee_msg_param *msg_params,
> > > -                           size_t num_params, const struct tee_param *params);
> > > +                           size_t num_params, const struct tee_param *params,
> > > +                           bool update_out);
> > >         int (*from_msg_param)(struct optee *optee, struct tee_param *params,
> > >                               size_t num_params,
> > > -                             const struct optee_msg_param *msg_params);
> > > +                             const struct optee_msg_param *msg_params,
> > > +                             bool update_out);
> > >  };
> > >
> > >  /**
> > > @@ -316,23 +318,35 @@ void optee_release(struct tee_context *ctx);
> > >  void optee_release_supp(struct tee_context *ctx);
> > >
> > >  static inline void optee_from_msg_param_value(struct tee_param *p, u32 attr,
> > > -                                             const struct optee_msg_param *mp)
> > > +                                             const struct optee_msg_param *mp,
> > > +                                             bool update_out)
> > >  {
> > > -       p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
> > > -                 attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> > > -       p->u.value.a = mp->u.value.a;
> > > -       p->u.value.b = mp->u.value.b;
> > > -       p->u.value.c = mp->u.value.c;
> > > +       if (!update_out)
> > > +               p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
> > > +                         attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> > > +
> > > +       if (attr == OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT ||
> > > +           attr == OPTEE_MSG_ATTR_TYPE_VALUE_INOUT || !update_out) {
> > > +               p->u.value.a = mp->u.value.a;
> > > +               p->u.value.b = mp->u.value.b;
> > > +               p->u.value.c = mp->u.value.c;
> > > +       }
> > >  }
> > >
> > >  static inline void optee_to_msg_param_value(struct optee_msg_param *mp,
> > > -                                           const struct tee_param *p)
> > > +                                           const struct tee_param *p,
> > > +                                           bool update_out)
> > >  {
> > > -       mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
> > > -                  TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> > > -       mp->u.value.a = p->u.value.a;
> > > -       mp->u.value.b = p->u.value.b;
> > > -       mp->u.value.c = p->u.value.c;
> > > +       if (!update_out)
> > > +               mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
> > > +                          TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> > > +
> > > +       if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
> > > +           p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT || !update_out) {
> > > +               mp->u.value.a = p->u.value.a;
> > > +               mp->u.value.b = p->u.value.b;
> > > +               mp->u.value.c = p->u.value.c;
> > > +       }
> > >  }
> > >
> > >  void optee_cq_init(struct optee_call_queue *cq, int thread_count);
> > > diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
> > > index ebbbd42b0e3e..580e6b9b0606 100644
> > > --- a/drivers/tee/optee/rpc.c
> > > +++ b/drivers/tee/optee/rpc.c
> > > @@ -63,7 +63,7 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
> > >         }
> > >
> > >         if (optee->ops->from_msg_param(optee, params, arg->num_params,
> > > -                                      arg->params))
> > > +                                      arg->params, false /*!update_out*/))
> > >                 goto bad;
> > >
> > >         for (i = 0; i < arg->num_params; i++) {
> > > @@ -107,7 +107,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
> > >         } else {
> > >                 params[3].u.value.a = msg.len;
> > >                 if (optee->ops->to_msg_param(optee, arg->params,
> > > -                                            arg->num_params, params))
> > > +                                            arg->num_params, params,
> > > +                                            true /*update_out*/))
> > >                         arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > >                 else
> > >                         arg->ret = TEEC_SUCCESS;
> > > @@ -188,6 +189,7 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
> > >  static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
> > >                                 struct optee_msg_arg *arg)
> > >  {
> > > +       bool update_out = false;
> > >         struct tee_param *params;
> > >
> > >         arg->ret_origin = TEEC_ORIGIN_COMMS;
> > > @@ -200,15 +202,21 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
> > >         }
> > >
> > >         if (optee->ops->from_msg_param(optee, params, arg->num_params,
> > > -                                      arg->params)) {
> > > +                                      arg->params, update_out)) {
> > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > >                 goto out;
> > >         }
> > >
> > >         arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
> > >
> > > +       /*
> > > +        * Special treatment for OPTEE_RPC_CMD_SHM_ALLOC since input is a
> > > +        * value type, but the output is a memref type.
> > > +        */
> > > +       if (arg->cmd != OPTEE_RPC_CMD_SHM_ALLOC)
> > > +               update_out = true;
> > >         if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
> > > -                                    params))
> > > +                                    params, update_out))
> > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > >  out:
> > >         kfree(params);
> > > @@ -270,7 +278,7 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
> > >
> > >         if (arg->num_params != ARRAY_SIZE(params) ||
> > >             optee->ops->from_msg_param(optee, params, arg->num_params,
> > > -                                      arg->params) ||
> > > +                                      arg->params, false /*!update_out*/) ||
> > >             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT) {
> > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > >                 return;
> > > @@ -280,7 +288,8 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
> > >         params[0].u.value.b = 0;
> > >         params[0].u.value.c = 0;
> > >         if (optee->ops->to_msg_param(optee, arg->params,
> > > -                                    arg->num_params, params)) {
> > > +                                    arg->num_params, params,
> > > +                                    true /*update_out*/)) {
> > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > >                 return;
> > >         }
> > > @@ -324,7 +333,7 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
> > >
> > >         if (arg->num_params != ARRAY_SIZE(params) ||
> > >             optee->ops->from_msg_param(optee, params, arg->num_params,
> > > -                                      arg->params) ||
> > > +                                      arg->params, false /*!update_out*/) ||
> > >             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
> > >             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
> > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > @@ -358,7 +367,8 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
> > >         params[0].u.value.b = rdev->descr.capacity;
> > >         params[0].u.value.c = rdev->descr.reliable_wr_count;
> > >         if (optee->ops->to_msg_param(optee, arg->params,
> > > -                                    arg->num_params, params)) {
> > > +                                    arg->num_params, params,
> > > +                                    true /*update_out*/)) {
> > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > >                 return;
> > >         }
> > > @@ -384,7 +394,7 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
> > >
> > >         if (arg->num_params != ARRAY_SIZE(params) ||
> > >             optee->ops->from_msg_param(optee, params, arg->num_params,
> > > -                                      arg->params) ||
> > > +                                      arg->params, false /*!update_out*/) ||
> > >             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT ||
> > >             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
> > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > @@ -401,7 +411,8 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
> > >                 goto out;
> > >         }
> > >         if (optee->ops->to_msg_param(optee, arg->params,
> > > -                                    arg->num_params, params)) {
> > > +                                    arg->num_params, params,
> > > +                                    true /*update_out*/)) {
> > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > >                 goto out;
> > >         }
> > > diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
> > > index e9456e3e74cc..d1f79947f58a 100644
> > > --- a/drivers/tee/optee/smc_abi.c
> > > +++ b/drivers/tee/optee/smc_abi.c
> > > @@ -81,20 +81,26 @@ static int optee_cpuhp_disable_pcpu_irq(unsigned int cpu)
> > >   */
> > >
> > >  static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
> > > -                                 const struct optee_msg_param *mp)
> > > +                                 const struct optee_msg_param *mp,
> > > +                                 bool update_out)
> > >  {
> > >         struct tee_shm *shm;
> > >         phys_addr_t pa;
> > >         int rc;
> > >
> > > +       if (update_out) {
> > > +               if (attr == OPTEE_MSG_ATTR_TYPE_TMEM_INPUT)
> > > +                       return 0;
> > > +               goto out;
> > > +       }
> > > +
> > >         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> > >                   attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
> > > -       p->u.memref.size = mp->u.tmem.size;
> > >         shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
> > >         if (!shm) {
> > >                 p->u.memref.shm_offs = 0;
> > >                 p->u.memref.shm = NULL;
> > > -               return 0;
> > > +               goto out;
> > >         }
> > >
> > >         rc = tee_shm_get_pa(shm, 0, &pa);
> > > @@ -103,18 +109,25 @@ static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
> > >
> > >         p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
> > >         p->u.memref.shm = shm;
> > > -
> > > +out:
> > > +       p->u.memref.size = mp->u.tmem.size;
> > >         return 0;
> > >  }
> > >
> > >  static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> > > -                                  const struct optee_msg_param *mp)
> > > +                                  const struct optee_msg_param *mp,
> > > +                                  bool update_out)
> > >  {
> > >         struct tee_shm *shm;
> > >
> > > +       if (update_out) {
> > > +               if (attr == OPTEE_MSG_ATTR_TYPE_RMEM_INPUT)
> > > +                       return;
> > > +               goto out;
> > > +       }
> > > +
> > >         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> > >                   attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
> > > -       p->u.memref.size = mp->u.rmem.size;
> > >         shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
> > >
> > >         if (shm) {
> > > @@ -124,6 +137,8 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> > >                 p->u.memref.shm_offs = 0;
> > >                 p->u.memref.shm = NULL;
> > >         }
> > > +out:
> > > +       p->u.memref.size = mp->u.rmem.size;
> > >  }
> > >
> > >  /**
> > > @@ -133,11 +148,13 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> > >   * @params:    subsystem internal parameter representation
> > >   * @num_params:        number of elements in the parameter arrays
> > >   * @msg_params:        OPTEE_MSG parameters
> > > + * @update_out:        update parameter for output only
> > >   * Returns 0 on success or <0 on failure
> > >   */
> > >  static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
> > >                                 size_t num_params,
> > > -                               const struct optee_msg_param *msg_params)
> > > +                               const struct optee_msg_param *msg_params,
> > > +                               bool update_out)
> > >  {
> > >         int rc;
> > >         size_t n;
> > > @@ -149,25 +166,27 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
> > >
> > >                 switch (attr) {
> > >                 case OPTEE_MSG_ATTR_TYPE_NONE:
> > > +                       if (update_out)
> > > +                               break;
> > >                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> > >                         memset(&p->u, 0, sizeof(p->u));
> > >                         break;
> > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
> > > -                       optee_from_msg_param_value(p, attr, mp);
> > > +                       optee_from_msg_param_value(p, attr, mp, update_out);
> > >                         break;
> > >                 case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
> > > -                       rc = from_msg_param_tmp_mem(p, attr, mp);
> > > +                       rc = from_msg_param_tmp_mem(p, attr, mp, update_out);
> > >                         if (rc)
> > >                                 return rc;
> > >                         break;
> > >                 case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
> > >                 case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
> > > -                       from_msg_param_reg_mem(p, attr, mp);
> > > +                       from_msg_param_reg_mem(p, attr, mp, update_out);
> > >                         break;
> > >
> > >                 default:
> > > @@ -178,20 +197,25 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
> > >  }
> > >
> > >  static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
> > > -                               const struct tee_param *p)
> > > +                               const struct tee_param *p, bool update_out)
> > >  {
> > >         int rc;
> > >         phys_addr_t pa;
> > >
> > > +       if (update_out) {
> > > +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> > > +                       return 0;
> > > +               goto out;
> > > +       }
> > > +
> > >         mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
> > >                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> > >
> > >         mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
> > > -       mp->u.tmem.size = p->u.memref.size;
> > >
> > >         if (!p->u.memref.shm) {
> > >                 mp->u.tmem.buf_ptr = 0;
> > > -               return 0;
> > > +               goto out;
> > >         }
> > >
> > >         rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa);
> > > @@ -201,19 +225,27 @@ static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
> > >         mp->u.tmem.buf_ptr = pa;
> > >         mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
> > >                     OPTEE_MSG_ATTR_CACHE_SHIFT;
> > > -
> > > +out:
> > > +       mp->u.tmem.size = p->u.memref.size;
> > >         return 0;
> > >  }
> > >
> > >  static int to_msg_param_reg_mem(struct optee_msg_param *mp,
> > > -                               const struct tee_param *p)
> > > +                               const struct tee_param *p, bool update_out)
> > >  {
> > > +       if (update_out) {
> > > +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> > > +                       return 0;
> > > +               goto out;
> > > +       }
> > > +
> > >         mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
> > >                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> > >
> > >         mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm;
> > > -       mp->u.rmem.size = p->u.memref.size;
> > >         mp->u.rmem.offs = p->u.memref.shm_offs;
> > > +out:
> > > +       mp->u.rmem.size = p->u.memref.size;
> > >         return 0;
> > >  }
> > >
> > > @@ -223,11 +255,13 @@ static int to_msg_param_reg_mem(struct optee_msg_param *mp,
> > >   * @msg_params:        OPTEE_MSG parameters
> > >   * @num_params:        number of elements in the parameter arrays
> > >   * @params:    subsystem itnernal parameter representation
> > > + * @update_out:        update parameter for output only
> > >   * Returns 0 on success or <0 on failure
> > >   */
> > >  static int optee_to_msg_param(struct optee *optee,
> > >                               struct optee_msg_param *msg_params,
> > > -                             size_t num_params, const struct tee_param *params)
> > > +                             size_t num_params, const struct tee_param *params,
> > > +                             bool update_out)
> > >  {
> > >         int rc;
> > >         size_t n;
> > > @@ -238,21 +272,23 @@ static int optee_to_msg_param(struct optee *optee,
> > >
> > >                 switch (p->attr) {
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
> > > +                       if (update_out)
> > > +                               break;
> > >                         mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> > >                         memset(&mp->u, 0, sizeof(mp->u));
> > >                         break;
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
> > > -                       optee_to_msg_param_value(mp, p);
> > > +                       optee_to_msg_param_value(mp, p, update_out);
> > >                         break;
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
> > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
> > >                         if (tee_shm_is_dynamic(p->u.memref.shm))
> > > -                               rc = to_msg_param_reg_mem(mp, p);
> > > +                               rc = to_msg_param_reg_mem(mp, p, update_out);
> > >                         else
> > > -                               rc = to_msg_param_tmp_mem(mp, p);
> > > +                               rc = to_msg_param_tmp_mem(mp, p, update_out);
> > >                         if (rc)
> > >                                 return rc;
> > >                         break;
> > > --
> > > 2.43.0
> > >


From andre.draszik at linaro.org  Tue Dec  3 02:40:56 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 10:40:56 +0000
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <575b3275-b2fa-4e5c-bb6b-759394b02e18@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
	 <e23721ebd766f410103ddfb8705f3d7d6e5ae3e9.camel@linaro.org>
	 <575b3275-b2fa-4e5c-bb6b-759394b02e18@uclouvain.be>
Message-ID: <30b0995903fb7db3f866d1304783d878f563fe2f.camel@linaro.org>

On Tue, 2024-12-03 at 11:23 +0100, Thomas Antoine wrote:
> On 12/3/24 08:12, Andr? Draszik wrote:
> > On Mon, 2024-12-02 at 14:07 +0100, Thomas Antoine via B4 Relay wrote:
> > > From: Thomas Antoine <t.antoine at uclouvain.be>
> > > 
> > > As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
> > > make it non-obligatory. Except for this, the max77759 seems to behave the
> > > same as the max1720x.
> > 
> > What about the battery characterization tables? Aren't they needed for
> > correct reporting?
> 
> I checked some other patches which added fuel gauge and other bindings and I
> couldn't find such characterization table. Can you point me to an example or
> explain what it should contain if there needs one?

I haven't looked in detail, but there is


https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-oriole-battery.dtsi#13
https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-raven-battery.dtsi#13

which include
https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-oriole-battery-data.dtsi
https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-raven-battery-data.dtsi
respectively

Both overlay
https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-raviole-battery.dtsi#177


Cheers,
Andre'



From esben at geanix.com  Tue Dec  3 02:45:36 2024
From: esben at geanix.com (Esben Haabendal)
Date: Tue, 03 Dec 2024 11:45:36 +0100
Subject: [PATCH 6/6] rtc: interface: Ensure alarm irq is enabled when UIE
 is enabled
In-Reply-To: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
References: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
Message-ID: <20241203-rtc-uie-irq-fixes-v1-6-01286ecd9f3f@geanix.com>

When setting a normal alarm, user-space is responsible for using
RTC_AIE_ON/RTC_AIE_OFF to control if alarm irq should be enabled.

But when RTC_UIE_ON is used, interrupts must be so that the requested
irq events are generated.
When RTC_UIE_OFF is used, alarm irq is disabled if there are no other
alarms queued, so this commit brings symmetry to that.

Signed-off-by: Esben Haabendal <esben at geanix.com>
Cc: stable at vger.kernel.org
---
 drivers/rtc/interface.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index e365e8fd166db31f8b44fac9fb923d36881b1394..39db12f267cc627febb78e67400aaf8fc3301b0c 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -617,6 +617,10 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
 		rtc->uie_rtctimer.node.expires = ktime_add(now, onesec);
 		rtc->uie_rtctimer.period = ktime_set(1, 0);
 		err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer);
+		if (!err && rtc->ops && rtc->ops->alarm_irq_enable)
+			err = rtc->ops->alarm_irq_enable(rtc->dev.parent, 1);
+		if (err)
+			goto out;
 	} else {
 		rtc_timer_remove(rtc, &rtc->uie_rtctimer);
 	}

-- 
2.47.1



From esben at geanix.com  Tue Dec  3 02:45:32 2024
From: esben at geanix.com (Esben Haabendal)
Date: Tue, 03 Dec 2024 11:45:32 +0100
Subject: [PATCH 2/6] rtc: isl12022: Fix initial enable_irq/disable_irq
 balance
In-Reply-To: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
References: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
Message-ID: <20241203-rtc-uie-irq-fixes-v1-2-01286ecd9f3f@geanix.com>

Interrupts are automatically enabled when requested, so we need to
initialize irq_enabled accordingly to avoid causing an unbalanced enable
warning.

Fixes: c62d658e5253 ("rtc: isl12022: Add alarm support")
Signed-off-by: Esben Haabendal <esben at geanix.com>
---
 drivers/rtc/rtc-isl12022.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index 9b44839a7402c9ab7da634d95152c2520eb8552e..5fc52dc6421305e957a0c3a169009c3f6a6c7320 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -413,6 +413,7 @@ static int isl12022_setup_irq(struct device *dev, int irq)
 	if (ret)
 		return ret;
 
+	isl12022->irq_enabled = true;
 	ret = devm_request_threaded_irq(dev, irq, NULL,
 					isl12022_rtc_interrupt,
 					IRQF_SHARED | IRQF_ONESHOT,

-- 
2.47.1



From esben at geanix.com  Tue Dec  3 02:45:35 2024
From: esben at geanix.com (Esben Haabendal)
Date: Tue, 03 Dec 2024 11:45:35 +0100
Subject: [PATCH 5/6] rtc: tps6586x: Fix initial enable_irq/disable_irq
 balance
In-Reply-To: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
References: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
Message-ID: <20241203-rtc-uie-irq-fixes-v1-5-01286ecd9f3f@geanix.com>

Interrupts are automatically enabled when requested, so we need to
initialize irq_en accordingly to avoid causing an unbalanced enable
warning.

Signed-off-by: Esben Haabendal <esben at geanix.com>
---
 drivers/rtc/rtc-tps6586x.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c
index e796729fc817c1bd99f4c70b714a346fc1a795d2..c8ccb4779b50b2c5909e6a64748f52b61e78dac5 100644
--- a/drivers/rtc/rtc-tps6586x.c
+++ b/drivers/rtc/rtc-tps6586x.c
@@ -258,6 +258,7 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
 
 	irq_set_status_flags(rtc->irq, IRQ_NOAUTOEN);
 
+	rtc->irq_en = true;
 	ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
 				tps6586x_rtc_irq,
 				IRQF_ONESHOT,

-- 
2.47.1



From esben at geanix.com  Tue Dec  3 02:45:33 2024
From: esben at geanix.com (Esben Haabendal)
Date: Tue, 03 Dec 2024 11:45:33 +0100
Subject: [PATCH 3/6] rtc: cpcap: Fix initial enable_irq/disable_irq balance
In-Reply-To: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
References: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
Message-ID: <20241203-rtc-uie-irq-fixes-v1-3-01286ecd9f3f@geanix.com>

Interrupts are automatically enabled when requested, so we need to
initialize alarm_enabled accordingly to avoid causing an unbalanced enable
warning.

Signed-off-by: Esben Haabendal <esben at geanix.com>
---
 drivers/rtc/rtc-cpcap.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c
index afc8fcba8f8885c15730e47fe0a9d3f681e3cba4..b74148935d21ff69095e703e99bf024714e41ac1 100644
--- a/drivers/rtc/rtc-cpcap.c
+++ b/drivers/rtc/rtc-cpcap.c
@@ -268,6 +268,7 @@ static int cpcap_rtc_probe(struct platform_device *pdev)
 		return err;
 
 	rtc->alarm_irq = platform_get_irq(pdev, 0);
+	rtc->alarm_enabled = true;
 	err = devm_request_threaded_irq(dev, rtc->alarm_irq, NULL,
 					cpcap_rtc_alarm_irq,
 					IRQF_TRIGGER_NONE | IRQF_ONESHOT,

-- 
2.47.1



From esben at geanix.com  Tue Dec  3 02:45:30 2024
From: esben at geanix.com (Esben Haabendal)
Date: Tue, 03 Dec 2024 11:45:30 +0100
Subject: [PATCH 0/6] rtc: Fix problems with missing UIE irqs
Message-ID: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>

This fixes a couple of different problems, that can cause RTC (alarm)
irqs to be missing when generating UIE interrupts.

The first commit fixes a long-standing problem, which has been
documented in a comment since 2010. This fixes a race that could cause
UIE irqs to stop being generated, which was easily reproduced by
timing the use of RTC_UIE_ON ioctl with the seconds tick in the RTC.

The last commit ensures that RTC (alarm) irqs are enabled whenever
RTC_UIE_ON ioctl is used.

The driver specific commits avoids kernel warnings about unbalanced
enable_irq/disable_irq, which gets triggered on first RTC_UIE_ON with
the last commit. Before this series, the same warning should be seen
on initial RTC_AIE_ON with those drivers.

Signed-off-by: Esben Haabendal <esben at geanix.com>
---
Esben Haabendal (6):
      rtc: interface: Fix long-standing race when setting alarm
      rtc: isl12022: Fix initial enable_irq/disable_irq balance
      rtc: cpcap: Fix initial enable_irq/disable_irq balance
      rtc: st-lpc: Fix initial enable_irq/disable_irq balance
      rtc: tps6586x: Fix initial enable_irq/disable_irq balance
      rtc: interface: Ensure alarm irq is enabled when UIE is enabled

 drivers/rtc/interface.c    | 27 +++++++++++++++++++++++++++
 drivers/rtc/rtc-cpcap.c    |  1 +
 drivers/rtc/rtc-isl12022.c |  1 +
 drivers/rtc/rtc-st-lpc.c   |  1 +
 drivers/rtc/rtc-tps6586x.c |  1 +
 5 files changed, 31 insertions(+)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241203-rtc-uie-irq-fixes-f2838782d0f8

Best regards,
-- 
Esben Haabendal <esben at geanix.com>



From esben at geanix.com  Tue Dec  3 02:45:34 2024
From: esben at geanix.com (Esben Haabendal)
Date: Tue, 03 Dec 2024 11:45:34 +0100
Subject: [PATCH 4/6] rtc: st-lpc: Fix initial enable_irq/disable_irq
 balance
In-Reply-To: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
References: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
Message-ID: <20241203-rtc-uie-irq-fixes-v1-4-01286ecd9f3f@geanix.com>

Interrupts are automatically enabled when requested, so we need to
initialize irq_enabled accordingly to avoid causing an unbalanced enable
warning.

To: Patrice Chotard <patrice.chotard at foss.st.com>
Signed-off-by: Esben Haabendal <esben at geanix.com>
---
 drivers/rtc/rtc-st-lpc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index c6d4522411b312f94de2701ff4ff491e5323aa96..dbc2c23bca23f5de6de3fd4b39c9c67290bfd78d 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -218,6 +218,7 @@ static int st_rtc_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	rtc->irq_enabled = true;
 	ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler,
 			       IRQF_NO_AUTOEN, pdev->name, rtc);
 	if (ret) {

-- 
2.47.1



From esben at geanix.com  Tue Dec  3 02:45:31 2024
From: esben at geanix.com (Esben Haabendal)
Date: Tue, 03 Dec 2024 11:45:31 +0100
Subject: [PATCH 1/6] rtc: interface: Fix long-standing race when setting
 alarm
In-Reply-To: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
References: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
Message-ID: <20241203-rtc-uie-irq-fixes-v1-1-01286ecd9f3f@geanix.com>

As described in the old comment dating back to
commit 6610e0893b8b ("RTC: Rework RTC code to use timerqueue for events")
from 2010, we have been living with a race window when setting alarm
with an expiry in the near future (i.e. next second).
With 1 second resolution, it can happen that the second ticks after the
check for the timer having expired, but before the alarm is actually set.
When this happen, no alarm IRQ is generated, at least not with some RTC
chips (isl12022 is an example of this).

With UIE RTC timer being implemented on top of alarm irq, being re-armed
every second, UIE will occasionally fail to work, as an alarm irq lost
due to this race will stop the re-arming loop.

For now, I have limited the additional expiry check to only be done for
alarms set to next seconds. I expect it should be good enough, although I
don't know if we can now for sure that systems with loads could end up
causing the same problems for alarms set 2 seconds or even longer in the
future.

I haven't been able to reproduce the problem with this check in place.

Cc: stable at vger.kernel.org
Signed-off-by: Esben Haabendal <esben at geanix.com>
---
 drivers/rtc/interface.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index aaf76406cd7d7d2cfd5479fc1fc892fcb5efbb6b..e365e8fd166db31f8b44fac9fb923d36881b1394 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -443,6 +443,29 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 	else
 		err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
 
+	/*
+	 * Check for potential race described above. If the waiting for next
+	 * second, and the second just ticked since the check above, either
+	 *
+	 * 1) It ticked after the alarm was set, and an alarm irq should be
+	 *    generated.
+	 *
+	 * 2) It ticked before the alarm was set, and alarm irq most likely will
+	 * not be generated.
+	 *
+	 * While we cannot easily check for which of these two scenarios we
+	 * are in, we can return -ETIME to signal that the timer has already
+	 * expired, which is true in both cases.
+	 */
+	if ((scheduled - now) <= 1) {
+		err = __rtc_read_time(rtc, &tm);
+		if (err)
+			return err;
+		now = rtc_tm_to_time64(&tm);
+		if (scheduled <= now)
+			return -ETIME;
+	}
+
 	trace_rtc_set_alarm(rtc_tm_to_time64(&alarm->time), err);
 	return err;
 }

-- 
2.47.1



From peter.griffin at linaro.org  Tue Dec  3 02:50:02 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 3 Dec 2024 10:50:02 +0000
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <bce22ca8-aed2-41ae-b2ef-fdc71266709a@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
 <9387c0cf-d291-485a-8cd1-1aced7eba14e@uclouvain.be> <2883fb0dd22312d5da9039d4fef869276a0bd430.camel@linaro.org>
 <bce22ca8-aed2-41ae-b2ef-fdc71266709a@uclouvain.be>
Message-ID: <CADrjBPq2TbP6aZ+9Y1Mg61wPfisnXPsgGjnXJW2724hmox+78w@mail.gmail.com>

Hi Thomas,

Thanks for your contribution :)

On Tue, 3 Dec 2024 at 10:12, Thomas Antoine <t.antoine at uclouvain.be> wrote:
>
> On 12/3/24 10:31, Andr? Draszik wrote:
> > On Tue, 2024-12-03 at 10:08 +0100, Thomas Antoine wrote:
> >> On 12/3/24 07:47, Andr? Draszik wrote:
> >>>> From: Thomas Antoine <t.antoine at uclouvain.be>
> >>>>
> >>>> The Maxim max77759 fuel gauge has the same interface as the Maxim max1720x
> >>>> except for the non-volatile memory slave address which is not available.
> >>>
> >>> It is not fully compatible, and it also has a lot more registers.
> >>>
> >>> For example, the voltage now is not in register 0xda as this driver assumes.
> >>> With these changes, POWER_SUPPLY_PROP_VOLTAGE_NOW just reads as 0. 0xda
> >>> doesn't exist in max77759
> >>>
> >>> I haven't compared in depth yet, though.
> >>
> >> Is the voltage necessary for the driver? If so, we could just not
> >> read the voltage. If it is necessary, I can try to kook into it and try
> >> to find in which register it is located (if there is one).
> >
> > Downstream reports it in
> > https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max1720x_battery.c#2400
> >
> > so upstream should do, too.
>
> I should have checked before answering. Indeed, I will try to see the
> best way to choose the register based on the chip. From what I see, it
> will also be necessary to change the translation of the reg value to microvolt
> as downstream does *78125/1000 when it is currently *1250 in mainline:
> https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max1720x_battery.h#49
>
> >>>>  static const char *const max17205_model = "MAX17205";
> >>>> +static const char *const max77759_model = "MAX77759";
> >>>>
> >>>>  struct max1720x_device_info {
> >>>>       struct regmap *regmap;
> >>>> @@ -54,6 +57,21 @@ struct max1720x_device_info {
> >>>>       int rsense;
> >>>>  };
> >>>>
> >>>> +struct chip_data {
> >>>> +     u16 default_nrsense; /* in regs in 10^-5 */
> >>>> +     u8 has_nvmem;
> >>>> +};
> >>>> +
> >>>> +static const struct chip_data max1720x_data  = {
> >>>> +     .default_nrsense = 1000,
> >>>> +     .has_nvmem = 1,
> >>>> +};
> >>>> +
> >>>> +static const struct chip_data max77759_data = {
> >>>> +     .default_nrsense = 500,
> >>>> +     .has_nvmem = 0,
> >>>> +};
> >>>
> >>> This should be made a required devicetree property instead, at least for
> >>> max77759, as it's completely board dependent, 'shunt-resistor-micro-ohms'
> >>> is widely used.
> >>>
> >>> I also don't think there should be a default. The driver should just fail
> >>> to probe if not specified in DT (for max77759).
> >>
> >> I hesitated to do this but I didn't know what would be better. Will change
> >> for v2.
> >
> > Just to clarify, has_nvmem can stay here in the driver, just rsense should
> > go into DT is what I mean.
>
> It was clear don't worry. This answer is related to the same subject:
> https://lore.kernel.org/linux-devicetree/20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30 at uclouvain.be/T/#ma55f41d42bf39be826d6cbf8987138bcc4eb52e3
>
> >>>> +
> >>>>  /*
> >>>>   * Model Gauge M5 Algorithm output register
> >>>>   * Volatile data (must not be cached)
> >>>> @@ -369,6 +387,8 @@ static int max1720x_battery_get_property(struct
> >>>> power_supply *psy,
> >>>>                       val->strval = max17201_model;
> >>>>               else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17205)
> >>>>                       val->strval = max17205_model;
> >>>> +             else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX77759)
> >>>> +                     val->strval = max77759_model;
> >>>>               else
> >>>
> >>> This is a 16 bit register, and while yes, MAX172XX_DEV_NAME_TYPE_MASK only
> >>> cares about the bottom 4 bits, the register is described as 'Firmware
> >>> Version Information'.
> >>>
> >>> But maybe it's ok to do it like that, at least for now.
> >>
> >> I thought this method would be ok as long as there is no collision on
> >> values. I hesitated to change the model evaluation method based on chip
> >> model, where the max77759 would thus have an hard-coded value and the
> >> max1720x would still evaluate the register value. I did not do it because
> >> it led to a lot more changes for no difference.
> >
> > Downstream uses the upper bits for max77759:
> > https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max_m5.h#135
> >
> > I don't know what the original max17201/5 report in this register
> > for those bits, though. Given for max77759 this register returns
> > the firmware version, I assume the lower bits can change.
>
> Based on this datasheet of the max1720x, the upper bits are the revision
> and the four lower bits are device. So it could change.
> https://www.analog.com/media/en/technical-documentation/data-sheets/MAX17201-MAX17215.pdf#MAX17201%20DS.indd%3A.213504%3A15892
>
> If the four lower bits are not always 0 for the max77759 then I guess it
> is necessary to change this as it wouldn't work with all max77759.

The definition of this register for max77759 is

Register name(addr): DevName (0x21)
Rest value: 0x6200
Bitfield: DevName Bits: 15:0 Description: Firmware Version Information

So I don't think you can rely on the bottom bits always being zero

regards,

Peter


From biju.das.jz at bp.renesas.com  Tue Dec  3 02:49:40 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue,  3 Dec 2024 10:49:40 +0000
Subject: [PATCH v2 13/13] arm64: defconfig: Enable R9A09G047 SoC
In-Reply-To: <20241203105005.103927-1-biju.das.jz@bp.renesas.com>
References: <20241203105005.103927-1-biju.das.jz@bp.renesas.com>
Message-ID: <20241203105005.103927-14-biju.das.jz@bp.renesas.com>

Enable support for the Renesas RZ/G3E (R9A09G047) SoC in the ARM64
defconfig.

Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
---
v1->v2:
 * 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 d13218d0c30f..a14d48444bd8 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1458,6 +1458,7 @@ CONFIG_ARCH_R9A07G044=y
 CONFIG_ARCH_R9A07G054=y
 CONFIG_ARCH_R9A08G045=y
 CONFIG_ARCH_R9A09G011=y
+CONFIG_ARCH_R9A09G047=y
 CONFIG_ARCH_R9A09G057=y
 CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_ARCH_TEGRA_132_SOC=y
-- 
2.43.0



From frank-w at public-files.de  Tue Dec  3 02:51:54 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Tue, 03 Dec 2024 11:51:54 +0100
Subject: =?US-ASCII?Q?Re=3A_=5BPATCH_v2_03/18=5D_arm64=3A_dts=3A_mediatek=3A_?=
 =?US-ASCII?Q?mt7988=3A_add_fixed_regulators_for_1v8_and_3v3?=
In-Reply-To: <016b77dc-2d33-4639-b241-2574ad877971@collabora.com>
References: <20241202122602.30734-1-linux@fw-web.de> <20241202122602.30734-4-linux@fw-web.de> <016b77dc-2d33-4639-b241-2574ad877971@collabora.com>
Message-ID: <371B3F0C-D468-45C8-B1F6-F4619B7C72DD@public-files.de>

Am 3. Dezember 2024 10:40:54 MEZ schrieb AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>:
>Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>> From: Frank Wunderlich <frank-w at public-files.de>
>> 
>> Add regulator nodes used for mmc to Bananapi R4 board.
>> 
>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>
>If you're adding the eMMC regulators, I assume that there's an eMMC, or that even
>if there's no device in some version of the board, these two regulators are always
>assigned to the eMMC device - right?

Like BPi-R3 there is one mmc controller mapped to either sd or emmc. I can move the regulators to the dtbo,but then they are defined twice (at least 3v3).

>You should, at this point, do exactly that: you can leave the mmc0 disabled and
>only enable it in a DTBO.

I enable it only in dtbo...

>&mmc0 {
>	/* eMMC gets enabled by DTBO if present */
>	vmmc-supply = <&reg_3p3v>;
>	vqmmc-supply = <&reg_1p8v>;
>};

Problem is here that sdcard uses only the 3v3 twice

https://github.com/frank-w/BPI-Router-Linux/blob/6.12-main/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso

And emmc needs both

https://github.com/frank-w/BPI-Router-Linux/blob/6.12-main/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso

Only defining the vmmc-supply in dts and set only the other in dtso is possible but but imho not nice.

>Cheers,
>Angelo
>
>> ---
>> v2:
>> - move mmc regulators to board dts of bpi-r4
>> ---
>>   .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts   | 18 ++++++++++++++++++
>>   1 file changed, 18 insertions(+)
>> 
>> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>> index d914eae2b524..df53512c6890 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>> @@ -8,6 +8,24 @@ / {
>>   	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
>>   	model = "Banana Pi BPI-R4";
>>   	chassis-type = "embedded";
>> +
>> +	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;
>> +	};
>>   };
>>     &pio {
>
>


regards Frank


From frank-w at public-files.de  Tue Dec  3 02:58:07 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Tue, 03 Dec 2024 11:58:07 +0100
Subject: =?US-ASCII?Q?Re=3A_=5BPATCH_v2_13/18=5D_arm64=3A_dts=3A_medi?=
 =?US-ASCII?Q?atek=3A_mt7988=3A_add_i2c_to_bpi-r4_board?=
In-Reply-To: <1ad355df-3f2a-4257-9374-1d125e138791@collabora.com>
References: <20241202122602.30734-1-linux@fw-web.de> <20241202122602.30734-14-linux@fw-web.de> <1ad355df-3f2a-4257-9374-1d125e138791@collabora.com>
Message-ID: <CA7E06EB-D26A-45D0-BF13-9C6B640F27A0@public-files.de>

Am 3. Dezember 2024 10:40:38 MEZ schrieb AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>:
>Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>> From: Frank Wunderlich <frank-w at public-files.de>
>> 
>> Add basic i2c nodes to bananapi R4 board.
>> 
>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>
>arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C controllers
>
>Enable the I2C0, I2C2 controllers found on the BananaPi R4 board; these
>controllers are accessible at ... I don't know, a header on the board?

These 2 i2c have directly connected spare devices (pmic on i2c0 and i2c-mux on i2c2 added in later commits to have it a bit cleaner). I2c1 is on gpio header which i have not added to let user choose if he wants i2c option or gpio. I can also add i2c1 to r4 board with the right pinctrl but imho it should be disabled to have gpio function default.

>After which,
>
>Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>
>


regards Frank


From paulk at sys-base.io  Tue Dec  3 02:58:37 2024
From: paulk at sys-base.io (Paul Kocialkowski)
Date: Tue, 3 Dec 2024 11:58:37 +0100
Subject: [PATCH] pinctrl: sunxi: Use minimal debouncing period as default
In-Reply-To: <20241202-magnetic-curious-bear-1cc48e@houat>
References: <20241119140805.3345412-1-paulk@sys-base.io>
 <20241119-prudent-jasmine-lizard-195cef@houat>
 <ZzyoIABRArkGoZBn@collins>
 <20241119-vivacious-optimistic-squirrel-a2f3c5@houat>
 <ZzzdT0wr0u1ApVgV@collins>
 <20241120-wild-stimulating-prawn-ffefb7@houat>
 <Zz20dquzl5_2_3TQ@collins>
 <20241129-amazing-whale-of-proficiency-ee6fd2@houat>
 <Z0rqILFESdje9qUn@collins>
 <20241202-magnetic-curious-bear-1cc48e@houat>
Message-ID: <Z07kXSstqc2eJ_Y9@collins>

Hi,

Le Mon 02 Dec 24, 12:03, Maxime Ripard a ?crit :
> On Sat, Nov 30, 2024 at 11:34:08AM +0100, Paul Kocialkowski wrote:
> > Well I'm an electrical engineer and the first thing we were told about
> > buttons and connectors is to include hardware debouncing. The second thing
> > is that it can be done in software (which again is done in a number of drivers)
> > by just disabling the interrupt for a while if it happens too often.
> > 
> > So I'm quite affirmative that taking none of these into account is constitutive
> > of a broken hardware design. No electrical engineer is told that they shouldn't
> > care about this because the SoC will filter interrupts for them.
> 
> The SoC provides the hardware debouncing. There's no reason not to use
> it, or to choose something redundant. Some might, but it's also
> perfectly valid to just rely on the SoC there.
> 
> > Of course it's fine to use this mechanism when it exists, but it's not a
> > reasonable expectation to just assume it will always be there. This is why
> > I think it's not a legitimate reason to make it a default.
> 
> Nobody ever designed a board without considering the SoC features but
> rather by adhering to a dogma. The SoC features, components chosen and
> their price, etc. all play a role.

Okay that's fair enough. I guess what I had in mind was that it would be
unusual and unlikely. I don't think it disqualifies the fact that it would
be sensible to enable this behavior with the property and not the other way
round though.

> > > But let me rephrase if my main objection wasn't clear enough: you want
> > > to introduce an ABI breaking change. With the possibility of breaking
> > > devices that have worked fine so far. That's not ok.
> > 
> > I believe it is highly questionable that this constitutes ABI breakage.
> > To me there was no defined behavior in the first place, since the debouncing
> > configuration is inherited either from the reset value or the boot stage.
> > There is also no formal indication of what the default is, anywhere.
> 
> Depending on the interpretation, it either means that you change the
> default, or add a default, to a device-tree property. That constitutes
> an ABI breakage on its own right. And then we can introduce regressions
> for boards, which is another breakage.

It feels very questionable that adding a default over undefined behavior
constitutes an ABI breakage.

> > Changing the default configuration of hardware is commonplace. One might
> > for example introduce a reset to a driver to get a clean state because it
> > happened that some boot software would mess it up and it went unnoticed for
> > a while. Would you also call that ABI breakage?
> 
> No, because it doesn't require a change in the default state Linux
> expects when it boots, or changing anything in the device tree. It's a
> self-contained change, and thus there's no interface to break.

It could definitely result in changes in behavior though. One could imagine
the case of a sensor that was configured with 4x gain by the boot software,
which wasn't reset by the driver. Now when the driver is updated to include a
reset the sensor will fall back to 1x gain, with a direct result on the values
that are read with default configuration.

This would however be perfectly fine since it wasn't specified anywhere that the
sensor should report values with 4x gain in its default state. It's a behavior
change that has direct effect, but doesn't break any ABI at all.

> > I think there's a number of situations where it's much more sensible to change
> > a default state to avoid very visible and practical issues. And it does happen.
> > 
> > Also my understanding of the "ABI breakage" rule in the kernel is that no
> > userspace program should stop working when it was implemented to (correctly)
> > follow some kernel-related ABI. It doesn't mean that we cannot change any
> > default state
> 
> If applications rely on that default one way or another, it's absolutely
> what it means. The only criteria is whether this will create a
> regression for any application.

For any application *that uses the ABI correctly*. Any example of defaults that
are inherited from the boot phase clearly shows that it is not a reasonable
expectation to rely on them and doing so is not correct use of the ABI.
It is rather very clearly relying on undefined behavior.

Cheers,

Paul

-- 
Paul Kocialkowski,

Independent contractor - sys-base - https://www.sys-base.io/
Free software developer - https://www.paulk.fr/

Expert in multimedia, graphics and embedded hardware support with Linux.
-------------- 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/20241203/65558db6/attachment.sig>

From andrej.picej at norik.com  Tue Dec  3 03:00:51 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue,  3 Dec 2024 12:00:51 +0100
Subject: [PATCH v3 0/3] SN65DSI83/4 lvds_vod_swing properties
Message-ID: <20241203110054.2506123-1-andrej.picej@norik.com>

Hi all,

this is a v3, which has only a minor change in a second patch.

The LVDS differential voltage swing can be specified as arrays of min, max
in microvolts. Two arrays, one for data-lanes and one for clock-lane can
be specified. Additionally, because LVDS voltage swing depends on near-end
termination this can now also be specified with separate property.

Driver goes through the tables, taken from datasheet [1] and selects the
appropriate configuration. If appropriate configuration can not be found
the probe fails. If these properties are not defined default values are
used as before.

This patch series depends on the patch
"[PATCH v2 11/15] arm64: dts: imx8mm-phyboard-polis: Add support for PEB-AV-10"
(https://lore.kernel.org/all/20241202072052.2195283-12-andrej.picej at norik.com/)
which is currently under review. Please apply the dependent series first before
applying this one.

v1 is at: https://lore.kernel.org/all/20241127103031.1007893-1-andrej.picej at norik.com/
v2 is at: https://lore.kernel.org/all/20241203085822.2475138-1-andrej.picej at norik.com/

[1] https://www.ti.com/lit/ds/symlink/sn65dsi83.pdf?ts=1732738773429&ref_url=https%253A%252F%252Fwww.mouser.co.uk%252F

Best regards,
Andrej

Andrej Picej (3):
  dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for
    ti,lvds-vod-swing
  drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
  arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing

 .../bindings/display/bridge/ti,sn65dsi83.yaml |  36 ++++-
 .../imx8mm-phyboard-polis-peb-av-10.dtso      |   2 +
 drivers/gpu/drm/bridge/ti-sn65dsi83.c         | 144 +++++++++++++++++-
 3 files changed, 176 insertions(+), 6 deletions(-)

-- 
2.34.1



From andrej.picej at norik.com  Tue Dec  3 03:00:52 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue,  3 Dec 2024 12:00:52 +0100
Subject: [PATCH v3 1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for ti,lvds-vod-swing
In-Reply-To: <20241203110054.2506123-1-andrej.picej@norik.com>
References: <20241203110054.2506123-1-andrej.picej@norik.com>
Message-ID: <20241203110054.2506123-2-andrej.picej@norik.com>

Add properties which can be used to specify LVDS differential output
voltage. Since this also depends on near-end signal termination also
include property which sets this. LVDS differential output voltage is
specified with an array (min, max), which should match the one from
connected device.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v3:
- no change
Changes in v2:
- move LVDS port schema to a $defs and reference it from there
- properties are now defined in microvolts/ohms
- use 1 property for data-lane and 1 for clock-lane LVDS voltage swing
- add 1 property which sets LVDS near-end termination
- since major change was done change the authorship to myself
---
 .../bindings/display/bridge/ti,sn65dsi83.yaml | 36 +++++++++++++++++--
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
index 48a97bb3e2e0..6da9b6e3beb9 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
@@ -80,12 +80,12 @@ properties:
                   - const: 4
 
       port at 2:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-A output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
       port at 3:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-B output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
     required:
       - port at 0
@@ -96,6 +96,36 @@ required:
   - reg
   - ports
 
+$defs:
+  lvds-port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    unevaluatedProperties: false
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          ti,lvds-termination-ohms:
+            description: The value of near end differential termination in ohms.
+            enum: [100, 200]
+            default: 200
+
+          ti,lvds-vod-swing-clock-microvolt:
+            description: LVDS diferential output voltage <min max> for clock
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
+          ti,lvds-vod-swing-data-microvolt:
+            description: LVDS diferential output voltage <min max> for data
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
 allOf:
   - if:
       properties:
@@ -120,7 +150,7 @@ allOf:
           properties:
             port at 1: false
 
-additionalProperties: false
+additionalProperties: true
 
 examples:
   - |
-- 
2.34.1



From andrej.picej at norik.com  Tue Dec  3 03:00:53 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue,  3 Dec 2024 12:00:53 +0100
Subject: [PATCH v3 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
In-Reply-To: <20241203110054.2506123-1-andrej.picej@norik.com>
References: <20241203110054.2506123-1-andrej.picej@norik.com>
Message-ID: <20241203110054.2506123-3-andrej.picej@norik.com>

Add a optional properties to change LVDS output voltage. This should not
be static as this depends mainly on the connected display voltage
requirement. We have three properties:
- "ti,lvds-termination-ohms", which sets near end termination,
- "ti,lvds-vod-swing-data-microvolt" and
- "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
output voltage for data and clock lanes. They are defined as an array
with min and max values. The appropriate bitfiled will be set if
selected constraints can be met.

If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
end termination will be used. Selecting only one:
"ti,lvds-vod-swing-data-microvolt" or
"ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
constraint for only data/clock lanes will be met. Setting both is
recommended.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v3:
- use microvolts for default array values 1000 mV -> 1000000 uV.
Changes in v2:
- use datasheet tables to get the proper configuration
- since major change was done change the authorship to myself
---
 drivers/gpu/drm/bridge/ti-sn65dsi83.c | 144 +++++++++++++++++++++++++-
 1 file changed, 141 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 57a7ed13f996..1a070df5ea12 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -132,6 +132,16 @@
 #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
 #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
 
+enum sn65dsi83_channel {
+	CHANNEL_A,
+	CHANNEL_B
+};
+
+enum sn65dsi83_lvds_term {
+	OHM_100,
+	OHM_200
+};
+
 enum sn65dsi83_model {
 	MODEL_SN65DSI83,
 	MODEL_SN65DSI84,
@@ -147,6 +157,10 @@ struct sn65dsi83 {
 	struct regulator		*vcc;
 	bool				lvds_dual_link;
 	bool				lvds_dual_link_even_odd_swap;
+	int				lvdsA_vod_swing_conf;
+	int				lvdsB_vod_swing_conf;
+	int				lvdsA_term_conf;
+	int				lvdsB_term_conf;
 };
 
 static const struct regmap_range sn65dsi83_readable_ranges[] = {
@@ -237,6 +251,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
 	.max_register = REG_IRQ_STAT,
 };
 
+static const int lvds_vod_swing_data_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 180000, 313000 },
+		{ 215000, 372000 },
+		{ 250000, 430000 },
+		{ 290000, 488000 },
+	},
+	{	/* 200 Ohm */
+		{ 150000, 261000 },
+		{ 200000, 346000 },
+		{ 250000, 428000 },
+		{ 300000, 511000 },
+	},
+};
+
+static const int lvds_vod_swing_clock_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 140000, 244000 },
+		{ 168000, 290000 },
+		{ 195000, 335000 },
+		{ 226000, 381000 },
+	},
+	{	/* 200 Ohm */
+		{ 117000, 204000 },
+		{ 156000, 270000 },
+		{ 195000, 334000 },
+		{ 234000, 399000 },
+	},
+};
+
 static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
 {
 	return container_of(bridge, struct sn65dsi83, bridge);
@@ -435,12 +479,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
 		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
 
 	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
-	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
+	regmap_write(ctx->regmap, REG_LVDS_VCOM,
+			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvdsA_vod_swing_conf) |
+			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvdsB_vod_swing_conf));
 	regmap_write(ctx->regmap, REG_LVDS_LANE,
 		     (ctx->lvds_dual_link_even_odd_swap ?
 		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
-		     REG_LVDS_LANE_CHA_LVDS_TERM |
-		     REG_LVDS_LANE_CHB_LVDS_TERM);
+		     (ctx->lvdsA_term_conf ?
+			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
+		     (ctx->lvdsB_term_conf ?
+			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
 	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
 
 	le16val = cpu_to_le16(mode->hdisplay);
@@ -576,10 +624,96 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
 	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
 };
 
+static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
+	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
+{
+	int i;
+
+	for (i = 0; i <= 3; i++) {
+		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
+		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
+		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
+		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
+			return i;
+	}
+
+	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
+	return -EINVAL;
+}
+
+static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *endpoint;
+	/* Set so the property can be freely selected if not defined */
+	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
+	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
+	u32 lvds_term = 200;
+	u8 lvds_term_conf;
+	int endpoint_reg;
+	int lvds_vod_swing_conf;
+	int ret = 0;
+	int ret_data;
+	int ret_clock;
+
+	if (channel == CHANNEL_A)
+		endpoint_reg = 2;
+	else
+		endpoint_reg = 3;
+
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
+	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
+
+	if (lvds_term == 200)
+		lvds_term_conf = OHM_200;
+	else
+		lvds_term_conf = OHM_100;
+
+	if (channel == CHANNEL_A)
+		ctx->lvdsA_term_conf = lvds_term_conf;
+	else
+		ctx->lvdsB_term_conf = lvds_term_conf;
+
+	ret_data = of_property_read_u32_array(endpoint,
+			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
+			ARRAY_SIZE(lvds_vod_swing_data));
+	ret_clock = of_property_read_u32_array(endpoint,
+			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
+			ARRAY_SIZE(lvds_vod_swing_clk));
+	/* If any of the two properties is defined. */
+	if (!ret_data || !ret_clock) {
+		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
+			lvds_vod_swing_data, lvds_vod_swing_clk,
+			lvds_term_conf);
+		if (lvds_vod_swing_conf < 0) {
+			ret = lvds_vod_swing_conf;
+			goto exit;
+		}
+		if (channel == CHANNEL_A)
+			ctx->lvdsA_vod_swing_conf = lvds_vod_swing_conf;
+		else
+			ctx->lvdsB_vod_swing_conf = lvds_vod_swing_conf;
+	}
+	ret = 0;
+exit:
+	of_node_put(endpoint);
+	return ret;
+}
+
 static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
 {
 	struct drm_bridge *panel_bridge;
 	struct device *dev = ctx->dev;
+	int ret;
+
+	ctx->lvdsA_vod_swing_conf = 0x1;
+	ctx->lvdsB_vod_swing_conf = 0x1;
+	ctx->lvdsA_term_conf = 0x1;
+	ctx->lvdsB_term_conf = 0x1;
+
+	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
+	if (ret < 0)
+		return ret;
 
 	ctx->lvds_dual_link = false;
 	ctx->lvds_dual_link_even_odd_swap = false;
@@ -587,6 +721,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
 		struct device_node *port2, *port3;
 		int dual_link;
 
+		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
+		if (ret < 0)
+			return ret;
+
 		port2 = of_graph_get_port_by_id(dev->of_node, 2);
 		port3 = of_graph_get_port_by_id(dev->of_node, 3);
 		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
-- 
2.34.1



From andrej.picej at norik.com  Tue Dec  3 03:00:54 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue,  3 Dec 2024 12:00:54 +0100
Subject: [PATCH v3 3/3] arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing
In-Reply-To: <20241203110054.2506123-1-andrej.picej@norik.com>
References: <20241203110054.2506123-1-andrej.picej@norik.com>
Message-ID: <20241203110054.2506123-4-andrej.picej@norik.com>

Set custom differential output voltage for LVDS, to fulfill requirements
of the connected display. LVDS differential voltage for data-lanes and
clock output has to be between 200 mV and 600 mV.
Driver sets 200 Ohm near-end termination by default.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v3:
- no change
Changes in v2:
- use new properties from previous patches
---
 .../boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso     | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
index a9de42cf14be..8bf9cc553bea 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
@@ -186,6 +186,8 @@ port at 2 {
 			reg = <2>;
 			bridge_out: endpoint {
 				remote-endpoint = <&panel_in>;
+				ti,lvds-vod-swing-clock-microvolt = <200000 600000>;
+				ti,lvds-vod-swing-data-microvolt = <200000 600000>;
 			};
 		};
 	};
-- 
2.34.1



From qperret at google.com  Tue Dec  3 02:37:17 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:17 +0000
Subject: [PATCH v2 00/18] KVM: arm64: Non-protected guest stage-2 support for pKVM
Message-ID: <20241203103735.2267589-1-qperret@google.com>

Hi all,

This is the v2 of the series adding support for non-protected guests to
pKVM. Please refer to v1 for all the context:

  https://lore.kernel.org/kvmarm/20241104133204.85208-1-qperret at google.com/

The series is organized as follows:

 - Patches 01 to 04 move the host ownership state tracking from the
   host's stage-2 page-table to the hypervisor's vmemmap. This avoids
   fragmenting the host stage-2 for shared pages, which is only needed
   to store an annotation in the SW bits of the corresponding PTE. All
   pages mapped into non-protected guests are shared from pKVM's PoV,
   so the cost of stage-2 fragmentation will increase massively as we
   start tracking that at EL2. Note that these patches also help with
   the existing sharing for e.g. FF-A, so they could possibly be merged
   separately from the rest of the series.

 - Patches 05 to 07 implement a minor refactoring of the pgtable code to
   ease the integration of the pKVM MMU later on.

 - Patches 08 to 16 introduce all the infrastructure needed on the pKVM
   side for handling guest stage-2 page-tables at EL2.

 - Patches 17 and 18 plumb the newly introduced pKVM support into
   KVM/arm64.

Patches based on 6.13-rc1, tested on Pixel 6 and Qemu.

Changes in v2:
 - Rebased on 6.13-rc1 (small conflicts with 2362506f7cff ("KVM: arm64:
   Don't mark "struct page" accessed when making SPTE young") in
   particular)
 - Fixed kerneldoc breakage for __unmap_stage2_range()
 - Fixed pkvm_pgtable_test_clear_young() to use correct HVC
 - Folded guest_get_valid_pte() into __check_host_unshare_guest() for
   clarity

Thanks,
Quentin

Marc Zyngier (1):
  KVM: arm64: Introduce __pkvm_vcpu_{load,put}()

Quentin Perret (17):
  KVM: arm64: Change the layout of enum pkvm_page_state
  KVM: arm64: Move enum pkvm_page_state to memory.h
  KVM: arm64: Make hyp_page::order a u8
  KVM: arm64: Move host page ownership tracking to the hyp vmemmap
  KVM: arm64: Pass walk flags to kvm_pgtable_stage2_mkyoung
  KVM: arm64: Pass walk flags to kvm_pgtable_stage2_relax_perms
  KVM: arm64: Make kvm_pgtable_stage2_init() a static inline function
  KVM: arm64: Add {get,put}_pkvm_hyp_vm() helpers
  KVM: arm64: Introduce __pkvm_host_share_guest()
  KVM: arm64: Introduce __pkvm_host_unshare_guest()
  KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
  KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
  KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
  KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
  KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
  KVM: arm64: Introduce the EL1 pKVM MMU
  KVM: arm64: Plumb the pKVM MMU in KVM

 arch/arm64/include/asm/kvm_asm.h              |   9 +
 arch/arm64/include/asm/kvm_host.h             |   4 +
 arch/arm64/include/asm/kvm_pgtable.h          |  42 ++-
 arch/arm64/include/asm/kvm_pkvm.h             |  28 ++
 arch/arm64/kvm/arm.c                          |  23 +-
 arch/arm64/kvm/hyp/include/nvhe/gfp.h         |   6 +-
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  38 +--
 arch/arm64/kvm/hyp/include/nvhe/memory.h      |  43 ++-
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  15 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 210 +++++++++++-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 312 ++++++++++++++++--
 arch/arm64/kvm/hyp/nvhe/page_alloc.c          |  14 +-
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  56 ++++
 arch/arm64/kvm/hyp/nvhe/setup.c               |   7 +-
 arch/arm64/kvm/hyp/pgtable.c                  |  13 +-
 arch/arm64/kvm/mmu.c                          | 109 ++++--
 arch/arm64/kvm/pkvm.c                         | 195 +++++++++++
 arch/arm64/kvm/vgic/vgic-v3.c                 |   6 +-
 18 files changed, 987 insertions(+), 143 deletions(-)

-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:18 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:18 +0000
Subject: [PATCH v2 01/18] KVM: arm64: Change the layout of enum pkvm_page_state
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-2-qperret@google.com>

The 'concrete' (a.k.a non-meta) page states are currently encoded using
software bits in PTEs. For performance reasons, the abstract
pkvm_page_state enum uses the same bits to encode these states as that
makes conversions from and to PTEs easy.

In order to prepare the ground for moving the 'concrete' state storage
to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this
purpose.

No functional changes intended.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 0972faccc2af..ca3177481b78 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -24,25 +24,28 @@
  */
 enum pkvm_page_state {
 	PKVM_PAGE_OWNED			= 0ULL,
-	PKVM_PAGE_SHARED_OWNED		= KVM_PGTABLE_PROT_SW0,
-	PKVM_PAGE_SHARED_BORROWED	= KVM_PGTABLE_PROT_SW1,
-	__PKVM_PAGE_RESERVED		= KVM_PGTABLE_PROT_SW0 |
-					  KVM_PGTABLE_PROT_SW1,
+	PKVM_PAGE_SHARED_OWNED		= BIT(0),
+	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
+	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
 
 	/* Meta-states which aren't encoded directly in the PTE's SW bits */
-	PKVM_NOPAGE,
+	PKVM_NOPAGE			= BIT(2),
 };
+#define PKVM_PAGE_META_STATES_MASK	(~(BIT(0) | BIT(1)))
 
 #define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
 static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
 						 enum pkvm_page_state state)
 {
-	return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
+	BUG_ON(state & PKVM_PAGE_META_STATES_MASK);
+	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
+	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
+	return prot;
 }
 
 static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
 {
-	return prot & PKVM_PAGE_STATE_PROT_MASK;
+	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
 }
 
 struct host_mmu {
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:19 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:19 +0000
Subject: [PATCH v2 02/18] KVM: arm64: Move enum pkvm_page_state to memory.h
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-3-qperret@google.com>

In order to prepare the way for storing page-tracking information in
pKVM's vmemmap, move the enum pkvm_page_state definition to
nvhe/memory.h.

No functional changes intended.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 35 +------------------
 arch/arm64/kvm/hyp/include/nvhe/memory.h      | 34 ++++++++++++++++++
 2 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index ca3177481b78..25038ac705d8 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -11,43 +11,10 @@
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_pgtable.h>
 #include <asm/virt.h>
+#include <nvhe/memory.h>
 #include <nvhe/pkvm.h>
 #include <nvhe/spinlock.h>
 
-/*
- * SW bits 0-1 are reserved to track the memory ownership state of each page:
- *   00: The page is owned exclusively by the page-table owner.
- *   01: The page is owned by the page-table owner, but is shared
- *       with another entity.
- *   10: The page is shared with, but not owned by the page-table owner.
- *   11: Reserved for future use (lending).
- */
-enum pkvm_page_state {
-	PKVM_PAGE_OWNED			= 0ULL,
-	PKVM_PAGE_SHARED_OWNED		= BIT(0),
-	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
-	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
-
-	/* Meta-states which aren't encoded directly in the PTE's SW bits */
-	PKVM_NOPAGE			= BIT(2),
-};
-#define PKVM_PAGE_META_STATES_MASK	(~(BIT(0) | BIT(1)))
-
-#define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
-static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
-						 enum pkvm_page_state state)
-{
-	BUG_ON(state & PKVM_PAGE_META_STATES_MASK);
-	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
-	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
-	return prot;
-}
-
-static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
-{
-	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
-}
-
 struct host_mmu {
 	struct kvm_arch arch;
 	struct kvm_pgtable pgt;
diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index ab205c4d6774..6dfeb000371c 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -7,6 +7,40 @@
 
 #include <linux/types.h>
 
+/*
+ * SW bits 0-1 are reserved to track the memory ownership state of each page:
+ *   00: The page is owned exclusively by the page-table owner.
+ *   01: The page is owned by the page-table owner, but is shared
+ *       with another entity.
+ *   10: The page is shared with, but not owned by the page-table owner.
+ *   11: Reserved for future use (lending).
+ */
+enum pkvm_page_state {
+	PKVM_PAGE_OWNED			= 0ULL,
+	PKVM_PAGE_SHARED_OWNED		= BIT(0),
+	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
+	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
+
+	/* Meta-states which aren't encoded directly in the PTE's SW bits */
+	PKVM_NOPAGE			= BIT(2),
+};
+#define PKVM_PAGE_META_STATES_MASK	(~(BIT(0) | BIT(1)))
+
+#define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
+static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
+						 enum pkvm_page_state state)
+{
+	BUG_ON(state & PKVM_PAGE_META_STATES_MASK);
+	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
+	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
+	return prot;
+}
+
+static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
+{
+	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
+}
+
 struct hyp_page {
 	unsigned short refcount;
 	unsigned short order;
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:20 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:20 +0000
Subject: [PATCH v2 03/18] KVM: arm64: Make hyp_page::order a u8
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-4-qperret@google.com>

We don't need 16 bits to store the hyp page order, and we'll need some
bits to store page ownership data soon, so let's reduce the order
member.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/gfp.h    |  6 +++---
 arch/arm64/kvm/hyp/include/nvhe/memory.h |  5 +++--
 arch/arm64/kvm/hyp/nvhe/page_alloc.c     | 14 +++++++-------
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
index 97c527ef53c2..f1725bad6331 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
@@ -7,7 +7,7 @@
 #include <nvhe/memory.h>
 #include <nvhe/spinlock.h>
 
-#define HYP_NO_ORDER	USHRT_MAX
+#define HYP_NO_ORDER	0xff
 
 struct hyp_pool {
 	/*
@@ -19,11 +19,11 @@ struct hyp_pool {
 	struct list_head free_area[NR_PAGE_ORDERS];
 	phys_addr_t range_start;
 	phys_addr_t range_end;
-	unsigned short max_order;
+	u8 max_order;
 };
 
 /* Allocation */
-void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order);
+void *hyp_alloc_pages(struct hyp_pool *pool, u8 order);
 void hyp_split_page(struct hyp_page *page);
 void hyp_get_page(struct hyp_pool *pool, void *addr);
 void hyp_put_page(struct hyp_pool *pool, void *addr);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index 6dfeb000371c..88cb8ff9e769 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -42,8 +42,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
 }
 
 struct hyp_page {
-	unsigned short refcount;
-	unsigned short order;
+	u16 refcount;
+	u8 order;
+	u8 reserved;
 };
 
 extern u64 __hyp_vmemmap;
diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
index e691290d3765..a1eb27a1a747 100644
--- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
+++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
@@ -32,7 +32,7 @@ u64 __hyp_vmemmap;
  */
 static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool,
 					     struct hyp_page *p,
-					     unsigned short order)
+					     u8 order)
 {
 	phys_addr_t addr = hyp_page_to_phys(p);
 
@@ -51,7 +51,7 @@ static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool,
 /* Find a buddy page currently available for allocation */
 static struct hyp_page *__find_buddy_avail(struct hyp_pool *pool,
 					   struct hyp_page *p,
-					   unsigned short order)
+					   u8 order)
 {
 	struct hyp_page *buddy = __find_buddy_nocheck(pool, p, order);
 
@@ -94,7 +94,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
 			      struct hyp_page *p)
 {
 	phys_addr_t phys = hyp_page_to_phys(p);
-	unsigned short order = p->order;
+	u8 order = p->order;
 	struct hyp_page *buddy;
 
 	memset(hyp_page_to_virt(p), 0, PAGE_SIZE << p->order);
@@ -129,7 +129,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
 
 static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool,
 					   struct hyp_page *p,
-					   unsigned short order)
+					   u8 order)
 {
 	struct hyp_page *buddy;
 
@@ -183,7 +183,7 @@ void hyp_get_page(struct hyp_pool *pool, void *addr)
 
 void hyp_split_page(struct hyp_page *p)
 {
-	unsigned short order = p->order;
+	u8 order = p->order;
 	unsigned int i;
 
 	p->order = 0;
@@ -195,10 +195,10 @@ void hyp_split_page(struct hyp_page *p)
 	}
 }
 
-void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order)
+void *hyp_alloc_pages(struct hyp_pool *pool, u8 order)
 {
-	unsigned short i = order;
 	struct hyp_page *p;
+	u8 i = order;
 
 	hyp_spin_lock(&pool->lock);
 
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:21 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:21 +0000
Subject: [PATCH v2 04/18] KVM: arm64: Move host page ownership tracking to the
 hyp vmemmap
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-5-qperret@google.com>

We currently store part of the page-tracking state in PTE software bits
for the host, guests and the hypervisor. This is sub-optimal when e.g.
sharing pages as this forces to break block mappings purely to support
this software tracking. This causes an unnecessarily fragmented stage-2
page-table for the host in particular when it shares pages with Secure,
which can lead to measurable regressions. Moreover, having this state
stored in the page-table forces us to do multiple costly walks on the
page transition path, hence causing overhead.

In order to work around these problems, move the host-side page-tracking
logic from SW bits in its stage-2 PTEs to the hypervisor's vmemmap.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/memory.h |  6 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 94 ++++++++++++++++--------
 arch/arm64/kvm/hyp/nvhe/setup.c          |  7 +-
 3 files changed, 71 insertions(+), 36 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index 88cb8ff9e769..08f3a0416d4c 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -8,7 +8,7 @@
 #include <linux/types.h>
 
 /*
- * SW bits 0-1 are reserved to track the memory ownership state of each page:
+ * Bits 0-1 are reserved to track the memory ownership state of each page:
  *   00: The page is owned exclusively by the page-table owner.
  *   01: The page is owned by the page-table owner, but is shared
  *       with another entity.
@@ -44,7 +44,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
 struct hyp_page {
 	u16 refcount;
 	u8 order;
-	u8 reserved;
+
+	/* Host (non-meta) state. Guarded by the host stage-2 lock. */
+	enum pkvm_page_state host_state : 8;
 };
 
 extern u64 __hyp_vmemmap;
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index caba3e4bd09e..1595081c4f6b 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -201,8 +201,8 @@ static void *guest_s2_zalloc_page(void *mc)
 
 	memset(addr, 0, PAGE_SIZE);
 	p = hyp_virt_to_page(addr);
-	memset(p, 0, sizeof(*p));
 	p->refcount = 1;
+	p->order = 0;
 
 	return addr;
 }
@@ -268,6 +268,7 @@ int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd)
 
 void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
 {
+	struct hyp_page *page;
 	void *addr;
 
 	/* Dump all pgtable pages in the hyp_pool */
@@ -279,7 +280,9 @@ void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
 	/* Drain the hyp_pool into the memcache */
 	addr = hyp_alloc_pages(&vm->pool, 0);
 	while (addr) {
-		memset(hyp_virt_to_page(addr), 0, sizeof(struct hyp_page));
+		page = hyp_virt_to_page(addr);
+		page->refcount = 0;
+		page->order = 0;
 		push_hyp_memcache(mc, addr, hyp_virt_to_phys);
 		WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1));
 		addr = hyp_alloc_pages(&vm->pool, 0);
@@ -382,19 +385,25 @@ bool addr_is_memory(phys_addr_t phys)
 	return !!find_mem_range(phys, &range);
 }
 
-static bool addr_is_allowed_memory(phys_addr_t phys)
+static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
+{
+	return range->start <= addr && addr < range->end;
+}
+
+static int range_is_allowed_memory(u64 start, u64 end)
 {
 	struct memblock_region *reg;
 	struct kvm_mem_range range;
 
-	reg = find_mem_range(phys, &range);
+	/* Can't check the state of both MMIO and memory regions at once */
+	reg = find_mem_range(start, &range);
+	if (!is_in_mem_range(end - 1, &range))
+		return -EINVAL;
 
-	return reg && !(reg->flags & MEMBLOCK_NOMAP);
-}
+	if (!reg || reg->flags & MEMBLOCK_NOMAP)
+		return -EPERM;
 
-static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
-{
-	return range->start <= addr && addr < range->end;
+	return 0;
 }
 
 static bool range_is_memory(u64 start, u64 end)
@@ -454,8 +463,11 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
 	if (kvm_pte_valid(pte))
 		return -EAGAIN;
 
-	if (pte)
+	if (pte) {
+		WARN_ON(addr_is_memory(addr) &&
+			!(hyp_phys_to_page(addr)->host_state & PKVM_NOPAGE));
 		return -EPERM;
+	}
 
 	do {
 		u64 granule = kvm_granule_size(level);
@@ -477,10 +489,29 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
 	return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
 }
 
+static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm_page_state state)
+{
+	phys_addr_t end = addr + size;
+	for (; addr < end; addr += PAGE_SIZE)
+		hyp_phys_to_page(addr)->host_state = state;
+}
+
 int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
 {
-	return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
-			       addr, size, &host_s2_pool, owner_id);
+	int ret;
+
+	ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
+			      addr, size, &host_s2_pool, owner_id);
+	if (ret || !addr_is_memory(addr))
+		return ret;
+
+	/* Don't forget to update the vmemmap tracking for the host */
+	if (owner_id == PKVM_ID_HOST)
+		__host_update_page_state(addr, size, PKVM_PAGE_OWNED);
+	else
+		__host_update_page_state(addr, size, PKVM_NOPAGE);
+
+	return 0;
 }
 
 static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
@@ -604,35 +635,38 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size,
 	return kvm_pgtable_walk(pgt, addr, size, &walker);
 }
 
-static enum pkvm_page_state host_get_page_state(kvm_pte_t pte, u64 addr)
-{
-	if (!addr_is_allowed_memory(addr))
-		return PKVM_NOPAGE;
-
-	if (!kvm_pte_valid(pte) && pte)
-		return PKVM_NOPAGE;
-
-	return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
-}
-
 static int __host_check_page_state_range(u64 addr, u64 size,
 					 enum pkvm_page_state state)
 {
-	struct check_walk_data d = {
-		.desired	= state,
-		.get_page_state	= host_get_page_state,
-	};
+	u64 end = addr + size;
+	int ret;
+
+	ret = range_is_allowed_memory(addr, end);
+	if (ret)
+		return ret;
 
 	hyp_assert_lock_held(&host_mmu.lock);
-	return check_page_state_range(&host_mmu.pgt, addr, size, &d);
+	for (; addr < end; addr += PAGE_SIZE) {
+		if (hyp_phys_to_page(addr)->host_state != state)
+			return -EPERM;
+	}
+
+	return 0;
 }
 
 static int __host_set_page_state_range(u64 addr, u64 size,
 				       enum pkvm_page_state state)
 {
-	enum kvm_pgtable_prot prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, state);
+	if (hyp_phys_to_page(addr)->host_state & PKVM_NOPAGE) {
+		int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT);
 
-	return host_stage2_idmap_locked(addr, size, prot);
+		if (ret)
+			return ret;
+	}
+
+	__host_update_page_state(addr, size, state);
+
+	return 0;
 }
 
 static int host_request_owned_transition(u64 *completer_addr,
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index cbdd18cd3f98..7e04d1c2a03d 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -180,7 +180,6 @@ static void hpool_put_page(void *addr)
 static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
 				     enum kvm_pgtable_walk_flags visit)
 {
-	enum kvm_pgtable_prot prot;
 	enum pkvm_page_state state;
 	phys_addr_t phys;
 
@@ -203,16 +202,16 @@ static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
 	case PKVM_PAGE_OWNED:
 		return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP);
 	case PKVM_PAGE_SHARED_OWNED:
-		prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED);
+		hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_BORROWED;
 		break;
 	case PKVM_PAGE_SHARED_BORROWED:
-		prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
+		hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_OWNED;
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	return host_stage2_idmap_locked(phys, PAGE_SIZE, prot);
+	return 0;
 }
 
 static int fix_hyp_pgtable_refcnt_walker(const struct kvm_pgtable_visit_ctx *ctx,
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:22 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:22 +0000
Subject: [PATCH v2 05/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_mkyoung
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-6-qperret@google.com>

kvm_pgtable_stage2_mkyoung currently assumes that it is being called
from a 'shared' walker, which will not be true once called from pKVM.
To allow for the re-use of that function, make the walk flags one of
its parameters.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 4 +++-
 arch/arm64/kvm/hyp/pgtable.c         | 7 +++----
 arch/arm64/kvm/mmu.c                 | 3 ++-
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index aab04097b505..38b7ec1c8614 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -669,13 +669,15 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
  * kvm_pgtable_stage2_mkyoung() - Set the access flag in a page-table entry.
  * @pgt:	Page-table structure initialised by kvm_pgtable_stage2_init*().
  * @addr:	Intermediate physical address to identify the page-table entry.
+ * @flags:	Flags to control the page-table walk (ex. a shared walk)
  *
  * The offset of @addr within a page is ignored.
  *
  * If there is a valid, leaf page-table entry used to translate @addr, then
  * set the access flag in that entry.
  */
-void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr);
+void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
+				enum kvm_pgtable_walk_flags flags);
 
 /**
  * kvm_pgtable_stage2_test_clear_young() - Test and optionally clear the access
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 40bd55966540..0470aedb4bf4 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -1245,14 +1245,13 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
 					NULL, NULL, 0);
 }
 
-void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr)
+void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
+				enum kvm_pgtable_walk_flags flags)
 {
 	int ret;
 
 	ret = stage2_update_leaf_attrs(pgt, addr, 1, KVM_PTE_LEAF_ATTR_LO_S2_AF, 0,
-				       NULL, NULL,
-				       KVM_PGTABLE_WALK_HANDLE_FAULT |
-				       KVM_PGTABLE_WALK_SHARED);
+				       NULL, NULL, flags);
 	if (!ret)
 		dsb(ishst);
 }
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index c9d46ad57e52..a2339b76c826 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1718,13 +1718,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 /* Resolve the access fault by making the page young again. */
 static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 {
+	enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED;
 	struct kvm_s2_mmu *mmu;
 
 	trace_kvm_access_fault(fault_ipa);
 
 	read_lock(&vcpu->kvm->mmu_lock);
 	mmu = vcpu->arch.hw_mmu;
-	kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa);
+	kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa, flags);
 	read_unlock(&vcpu->kvm->mmu_lock);
 }
 
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:23 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:23 +0000
Subject: [PATCH v2 06/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_relax_perms
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-7-qperret@google.com>

kvm_pgtable_stage2_relax_perms currently assumes that it is being called
from a 'shared' walker, which will not be true once called from pKVM. To
allow for the re-use of that function, make the walk flags one of its
parameters.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 4 +++-
 arch/arm64/kvm/hyp/pgtable.c         | 6 ++----
 arch/arm64/kvm/mmu.c                 | 7 +++----
 3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 38b7ec1c8614..c2f4149283ef 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -707,6 +707,7 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
  * @pgt:	Page-table structure initialised by kvm_pgtable_stage2_init*().
  * @addr:	Intermediate physical address to identify the page-table entry.
  * @prot:	Additional permissions to grant for the mapping.
+ * @flags:	Flags to control the page-table walk (ex. a shared walk)
  *
  * The offset of @addr within a page is ignored.
  *
@@ -719,7 +720,8 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
  * Return: 0 on success, negative error code on failure.
  */
 int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
-				   enum kvm_pgtable_prot prot);
+				   enum kvm_pgtable_prot prot,
+				   enum kvm_pgtable_walk_flags flags);
 
 /**
  * kvm_pgtable_stage2_flush_range() - Clean and invalidate data cache to Point
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 0470aedb4bf4..b7a3b5363235 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -1307,7 +1307,7 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
 }
 
 int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
-				   enum kvm_pgtable_prot prot)
+				   enum kvm_pgtable_prot prot, enum kvm_pgtable_walk_flags flags)
 {
 	int ret;
 	s8 level;
@@ -1325,9 +1325,7 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
 	if (prot & KVM_PGTABLE_PROT_X)
 		clr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
 
-	ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level,
-				       KVM_PGTABLE_WALK_HANDLE_FAULT |
-				       KVM_PGTABLE_WALK_SHARED);
+	ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level, flags);
 	if (!ret || ret == -EAGAIN)
 		kvm_call_hyp(__kvm_tlb_flush_vmid_ipa_nsh, pgt->mmu, addr, level);
 	return ret;
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index a2339b76c826..641e4fec1659 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1452,6 +1452,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
 	struct kvm_pgtable *pgt;
 	struct page *page;
+	enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED;
 
 	if (fault_is_perm)
 		fault_granule = kvm_vcpu_trap_get_perm_fault_granule(vcpu);
@@ -1695,13 +1696,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		 * PTE, which will be preserved.
 		 */
 		prot &= ~KVM_NV_GUEST_MAP_SZ;
-		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot);
+		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot, flags);
 	} else {
 		ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
 					     __pfn_to_phys(pfn), prot,
-					     memcache,
-					     KVM_PGTABLE_WALK_HANDLE_FAULT |
-					     KVM_PGTABLE_WALK_SHARED);
+					     memcache, flags);
 	}
 
 out_unlock:
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:24 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:24 +0000
Subject: [PATCH v2 07/18] KVM: arm64: Make kvm_pgtable_stage2_init() a static
 inline function
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-8-qperret@google.com>

Turn kvm_pgtable_stage2_init() into a static inline function instead of
a macro. This will allow the usage of typeof() on it later on.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index c2f4149283ef..04418b5e3004 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -526,8 +526,11 @@ int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
 			      enum kvm_pgtable_stage2_flags flags,
 			      kvm_pgtable_force_pte_cb_t force_pte_cb);
 
-#define kvm_pgtable_stage2_init(pgt, mmu, mm_ops) \
-	__kvm_pgtable_stage2_init(pgt, mmu, mm_ops, 0, NULL)
+static inline int kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
+					  struct kvm_pgtable_mm_ops *mm_ops)
+{
+	return __kvm_pgtable_stage2_init(pgt, mmu, mm_ops, 0, NULL);
+}
 
 /**
  * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:25 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:25 +0000
Subject: [PATCH v2 08/18] KVM: arm64: Add {get,put}_pkvm_hyp_vm() helpers
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-9-qperret@google.com>

In preparation for accessing pkvm_hyp_vm structures at EL2 in a context
where we can't always expect a vCPU to be loaded (e.g. MMU notifiers),
introduce get/put helpers to get temporary references to hyp VMs from
any context.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  3 +++
 arch/arm64/kvm/hyp/nvhe/pkvm.c         | 20 ++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 24a9a8330d19..f361d8b91930 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -70,4 +70,7 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 					 unsigned int vcpu_idx);
 void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
 
+struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
+void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
+
 #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 01616c39a810..4db88bedf8d5 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -327,6 +327,26 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 	hyp_spin_unlock(&vm_table_lock);
 }
 
+struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
+{
+	struct pkvm_hyp_vm *hyp_vm;
+
+	hyp_spin_lock(&vm_table_lock);
+	hyp_vm = get_vm_by_handle(handle);
+	if (hyp_vm)
+		hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
+	hyp_spin_unlock(&vm_table_lock);
+
+	return hyp_vm;
+}
+
+void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm)
+{
+	hyp_spin_lock(&vm_table_lock);
+	hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
+	hyp_spin_unlock(&vm_table_lock);
+}
+
 static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
 {
 	struct kvm *kvm = &hyp_vm->kvm;
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:26 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:26 +0000
Subject: [PATCH v2 09/18] KVM: arm64: Introduce __pkvm_vcpu_{load,put}()
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-10-qperret@google.com>

From: Marc Zyngier <maz at kernel.org>

Rather than look-up the hyp vCPU on every run hypercall at EL2,
introduce a per-CPU 'loaded_hyp_vcpu' tracking variable which is updated
by a pair of load/put hypercalls called directly from
kvm_arch_vcpu_{load,put}() when pKVM is enabled.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_asm.h       |  2 ++
 arch/arm64/kvm/arm.c                   | 14 ++++++++
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  7 ++++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c     | 47 ++++++++++++++++++++------
 arch/arm64/kvm/hyp/nvhe/pkvm.c         | 29 ++++++++++++++++
 arch/arm64/kvm/vgic/vgic-v3.c          |  6 ++--
 6 files changed, 93 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index ca2590344313..89c0fac69551 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -79,6 +79,8 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
 	__KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu,
 	__KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
+	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
+	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
 };
 
 #define DECLARE_KVM_VHE_SYM(sym)	extern char sym[]
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..55cc62b2f469 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -619,12 +619,26 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 	kvm_arch_vcpu_load_debug_state_flags(vcpu);
 
+	if (is_protected_kvm_enabled()) {
+		kvm_call_hyp_nvhe(__pkvm_vcpu_load,
+				  vcpu->kvm->arch.pkvm.handle,
+				  vcpu->vcpu_idx, vcpu->arch.hcr_el2);
+		kvm_call_hyp(__vgic_v3_restore_vmcr_aprs,
+			     &vcpu->arch.vgic_cpu.vgic_v3);
+	}
+
 	if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus))
 		vcpu_set_on_unsupported_cpu(vcpu);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+	if (is_protected_kvm_enabled()) {
+		kvm_call_hyp(__vgic_v3_save_vmcr_aprs,
+			     &vcpu->arch.vgic_cpu.vgic_v3);
+		kvm_call_hyp_nvhe(__pkvm_vcpu_put);
+	}
+
 	kvm_arch_vcpu_put_debug_state_flags(vcpu);
 	kvm_arch_vcpu_put_fp(vcpu);
 	if (has_vhe())
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index f361d8b91930..be52c5b15e21 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -20,6 +20,12 @@ struct pkvm_hyp_vcpu {
 
 	/* Backpointer to the host's (untrusted) vCPU instance. */
 	struct kvm_vcpu *host_vcpu;
+
+	/*
+	 * If this hyp vCPU is loaded, then this is a backpointer to the
+	 * per-cpu pointer tracking us. Otherwise, NULL if not loaded.
+	 */
+	struct pkvm_hyp_vcpu **loaded_hyp_vcpu;
 };
 
 /*
@@ -69,6 +75,7 @@ int __pkvm_teardown_vm(pkvm_handle_t handle);
 struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 					 unsigned int vcpu_idx);
 void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
+struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void);
 
 struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
 void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 6aa0b13d86e5..95d78db315b3 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -141,16 +141,46 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 		host_cpu_if->vgic_lr[i] = hyp_cpu_if->vgic_lr[i];
 }
 
+static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(unsigned int, vcpu_idx, host_ctxt, 2);
+	DECLARE_REG(u64, hcr_el2, host_ctxt, 3);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+
+	if (!is_protected_kvm_enabled())
+		return;
+
+	hyp_vcpu = pkvm_load_hyp_vcpu(handle, vcpu_idx);
+	if (!hyp_vcpu)
+		return;
+
+	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
+		/* Propagate WFx trapping flags */
+		hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWE | HCR_TWI);
+		hyp_vcpu->vcpu.arch.hcr_el2 |= hcr_el2 & (HCR_TWE | HCR_TWI);
+	}
+}
+
+static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt)
+{
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+
+	if (!is_protected_kvm_enabled())
+		return;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (hyp_vcpu)
+		pkvm_put_hyp_vcpu(hyp_vcpu);
+}
+
 static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, host_vcpu, host_ctxt, 1);
 	int ret;
 
-	host_vcpu = kern_hyp_va(host_vcpu);
-
 	if (unlikely(is_protected_kvm_enabled())) {
-		struct pkvm_hyp_vcpu *hyp_vcpu;
-		struct kvm *host_kvm;
+		struct pkvm_hyp_vcpu *hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
 
 		/*
 		 * KVM (and pKVM) doesn't support SME guests for now, and
@@ -163,9 +193,6 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 			goto out;
 		}
 
-		host_kvm = kern_hyp_va(host_vcpu->kvm);
-		hyp_vcpu = pkvm_load_hyp_vcpu(host_kvm->arch.pkvm.handle,
-					      host_vcpu->vcpu_idx);
 		if (!hyp_vcpu) {
 			ret = -EINVAL;
 			goto out;
@@ -176,12 +203,10 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 		ret = __kvm_vcpu_run(&hyp_vcpu->vcpu);
 
 		sync_hyp_vcpu(hyp_vcpu);
-		pkvm_put_hyp_vcpu(hyp_vcpu);
 	} else {
 		/* The host is fully trusted, run its vCPU directly. */
-		ret = __kvm_vcpu_run(host_vcpu);
+		ret = __kvm_vcpu_run(kern_hyp_va(host_vcpu));
 	}
-
 out:
 	cpu_reg(host_ctxt, 1) =  ret;
 }
@@ -409,6 +434,8 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_init_vm),
 	HANDLE_FUNC(__pkvm_init_vcpu),
 	HANDLE_FUNC(__pkvm_teardown_vm),
+	HANDLE_FUNC(__pkvm_vcpu_load),
+	HANDLE_FUNC(__pkvm_vcpu_put),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 4db88bedf8d5..d5c23449a64c 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -23,6 +23,12 @@ unsigned int kvm_arm_vmid_bits;
 
 unsigned int kvm_host_sve_max_vl;
 
+/*
+ * The currently loaded hyp vCPU for each physical CPU. Used only when
+ * protected KVM is enabled, but for both protected and non-protected VMs.
+ */
+static DEFINE_PER_CPU(struct pkvm_hyp_vcpu *, loaded_hyp_vcpu);
+
 /*
  * Set trap register values based on features in ID_AA64PFR0.
  */
@@ -306,15 +312,30 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 	struct pkvm_hyp_vcpu *hyp_vcpu = NULL;
 	struct pkvm_hyp_vm *hyp_vm;
 
+	/* Cannot load a new vcpu without putting the old one first. */
+	if (__this_cpu_read(loaded_hyp_vcpu))
+		return NULL;
+
 	hyp_spin_lock(&vm_table_lock);
 	hyp_vm = get_vm_by_handle(handle);
 	if (!hyp_vm || hyp_vm->nr_vcpus <= vcpu_idx)
 		goto unlock;
 
 	hyp_vcpu = hyp_vm->vcpus[vcpu_idx];
+
+	/* Ensure vcpu isn't loaded on more than one cpu simultaneously. */
+	if (unlikely(hyp_vcpu->loaded_hyp_vcpu)) {
+		hyp_vcpu = NULL;
+		goto unlock;
+	}
+
+	hyp_vcpu->loaded_hyp_vcpu = this_cpu_ptr(&loaded_hyp_vcpu);
 	hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
 unlock:
 	hyp_spin_unlock(&vm_table_lock);
+
+	if (hyp_vcpu)
+		__this_cpu_write(loaded_hyp_vcpu, hyp_vcpu);
 	return hyp_vcpu;
 }
 
@@ -323,10 +344,18 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 	struct pkvm_hyp_vm *hyp_vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu);
 
 	hyp_spin_lock(&vm_table_lock);
+	hyp_vcpu->loaded_hyp_vcpu = NULL;
+	__this_cpu_write(loaded_hyp_vcpu, NULL);
 	hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
 	hyp_spin_unlock(&vm_table_lock);
 }
 
+struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void)
+{
+	return __this_cpu_read(loaded_hyp_vcpu);
+
+}
+
 struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
 {
 	struct pkvm_hyp_vm *hyp_vm;
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index f267bc2486a1..c2ef41fff079 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -734,7 +734,8 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
-	kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
+	if (likely(!is_protected_kvm_enabled()))
+		kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
 
 	if (has_vhe())
 		__vgic_v3_activate_traps(cpu_if);
@@ -746,7 +747,8 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
-	kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
+	if (likely(!is_protected_kvm_enabled()))
+		kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
 	WARN_ON(vgic_v4_put(vcpu));
 
 	if (has_vhe())
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:27 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:27 +0000
Subject: [PATCH v2 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-11-qperret@google.com>

In preparation for handling guest stage-2 mappings at EL2, introduce a
new pKVM hypercall allowing to share pages with non-protected guests.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/include/asm/kvm_host.h             |  3 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/include/nvhe/memory.h      |  2 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 34 +++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 70 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  7 ++
 7 files changed, 118 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 89c0fac69551..449337f5b2a3 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -65,6 +65,7 @@ enum __kvm_host_smccc_func {
 	/* Hypercalls available after pKVM finalisation */
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e18e9244d17a..f75988e3515b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -771,6 +771,9 @@ struct kvm_vcpu_arch {
 	/* Cache some mmu pages needed inside spinlock regions */
 	struct kvm_mmu_memory_cache mmu_page_cache;
 
+	/* Pages to be donated to pkvm/EL2 if it runs out */
+	struct kvm_hyp_memcache pkvm_memcache;
+
 	/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
 	u64 vsesr_el2;
 
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 25038ac705d8..a7976e50f556 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -39,6 +39,7 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages);
 int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
+int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index 08f3a0416d4c..457318215155 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -47,6 +47,8 @@ struct hyp_page {
 
 	/* Host (non-meta) state. Guarded by the host stage-2 lock. */
 	enum pkvm_page_state host_state : 8;
+
+	u32 host_share_guest_count;
 };
 
 extern u64 __hyp_vmemmap;
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 95d78db315b3..d659462fbf5d 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -211,6 +211,39 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+static int pkvm_refill_memcache(struct pkvm_hyp_vcpu *hyp_vcpu)
+{
+	struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
+
+	return refill_memcache(&hyp_vcpu->vcpu.arch.pkvm_memcache,
+			       host_vcpu->arch.pkvm_memcache.nr_pages,
+			       &host_vcpu->arch.pkvm_memcache);
+}
+
+static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, pfn, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 3);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		goto out;
+
+	ret = pkvm_refill_memcache(hyp_vcpu);
+	if (ret)
+		goto out;
+
+	ret = __pkvm_host_share_guest(pfn, gfn, hyp_vcpu, prot);
+out:
+	cpu_reg(host_ctxt, 1) =  ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -420,6 +453,7 @@ static const hcall_t host_hcall[] = {
 
 	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
+	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 1595081c4f6b..a69d7212b64c 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -861,6 +861,27 @@ static int hyp_complete_donation(u64 addr,
 	return pkvm_create_mappings_locked(start, end, prot);
 }
 
+static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr)
+{
+	if (!kvm_pte_valid(pte))
+		return PKVM_NOPAGE;
+
+	return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
+}
+
+static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
+					  u64 size, enum pkvm_page_state state)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	struct check_walk_data d = {
+		.desired	= state,
+		.get_page_state	= guest_get_page_state,
+	};
+
+	hyp_assert_lock_held(&vm->lock);
+	return check_page_state_range(&vm->pgt, addr, size, &d);
+}
+
 static int check_share(struct pkvm_mem_share *share)
 {
 	const struct pkvm_mem_transition *tx = &share->tx;
@@ -1343,3 +1364,52 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
 
 	return ret;
 }
+
+int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
+			    enum kvm_pgtable_prot prot)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	u64 phys = hyp_pfn_to_phys(pfn);
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	struct hyp_page *page;
+	int ret;
+
+	if (prot & ~KVM_PGTABLE_PROT_RWX)
+		return -EINVAL;
+
+	ret = range_is_allowed_memory(phys, phys + PAGE_SIZE);
+	if (ret)
+		return ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __guest_check_page_state_range(vcpu, ipa, PAGE_SIZE, PKVM_NOPAGE);
+	if (ret)
+		goto unlock;
+
+	page = hyp_phys_to_page(phys);
+	switch (page->host_state) {
+	case PKVM_PAGE_OWNED:
+		WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_OWNED));
+		break;
+	case PKVM_PAGE_SHARED_OWNED:
+		/* Only host to np-guest multi-sharing is tolerated */
+		WARN_ON(!page->host_share_guest_count);
+		break;
+	default:
+		ret = -EPERM;
+		goto unlock;
+	}
+
+	WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys,
+				       pkvm_mkstate(prot, PKVM_PAGE_SHARED_BORROWED),
+				       &vcpu->vcpu.arch.pkvm_memcache, 0));
+	page->host_share_guest_count++;
+
+unlock:
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index d5c23449a64c..d6c61a5e7b6e 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -795,6 +795,13 @@ int __pkvm_teardown_vm(pkvm_handle_t handle)
 	/* Push the metadata pages to the teardown memcache */
 	for (idx = 0; idx < hyp_vm->nr_vcpus; ++idx) {
 		struct pkvm_hyp_vcpu *hyp_vcpu = hyp_vm->vcpus[idx];
+		struct kvm_hyp_memcache *vcpu_mc = &hyp_vcpu->vcpu.arch.pkvm_memcache;
+
+		while (vcpu_mc->nr_pages) {
+			void *addr = pop_hyp_memcache(vcpu_mc, hyp_phys_to_virt);
+			push_hyp_memcache(mc, addr, hyp_virt_to_phys);
+			unmap_donated_memory_noclear(addr, PAGE_SIZE);
+		}
 
 		teardown_donated_memory(mc, hyp_vcpu, sizeof(*hyp_vcpu));
 	}
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:28 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:28 +0000
Subject: [PATCH v2 11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-12-qperret@google.com>

In preparation for letting the host unmap pages from non-protected
guests, introduce a new hypercall implementing the host-unshare-guest
transition.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  5 ++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 24 +++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 67 +++++++++++++++++++
 5 files changed, 98 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 449337f5b2a3..0b6c4d325134 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -66,6 +66,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index a7976e50f556..e528a42ed60e 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -40,6 +40,7 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
+int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index be52c5b15e21..5dfc9ece9aa5 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -64,6 +64,11 @@ static inline bool pkvm_hyp_vcpu_is_protected(struct pkvm_hyp_vcpu *hyp_vcpu)
 	return vcpu_is_protected(&hyp_vcpu->vcpu);
 }
 
+static inline bool pkvm_hyp_vm_is_protected(struct pkvm_hyp_vm *hyp_vm)
+{
+	return kvm_vm_is_protected(&hyp_vm->kvm);
+}
+
 void pkvm_hyp_vm_table_init(void *tbl);
 
 int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index d659462fbf5d..04a9053ae1d5 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -244,6 +244,29 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	struct pkvm_hyp_vm *hyp_vm;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vm = get_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		goto out;
+	if (pkvm_hyp_vm_is_protected(hyp_vm))
+		goto put_hyp_vm;
+
+	ret = __pkvm_host_unshare_guest(gfn, hyp_vm);
+put_hyp_vm:
+	put_pkvm_hyp_vm(hyp_vm);
+out:
+	cpu_reg(host_ctxt, 1) =  ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -454,6 +477,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
 	HANDLE_FUNC(__pkvm_host_share_guest),
+	HANDLE_FUNC(__pkvm_host_unshare_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index a69d7212b64c..aa27a3e42e5e 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1413,3 +1413,70 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
 
 	return ret;
 }
+
+static int __check_host_unshare_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)
+{
+	enum pkvm_page_state state;
+	struct hyp_page *page;
+	kvm_pte_t pte;
+	u64 phys;
+	s8 level;
+	int ret;
+
+	ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
+	if (ret)
+		return ret;
+	if (level != KVM_PGTABLE_LAST_LEVEL)
+		return -E2BIG;
+	if (!kvm_pte_valid(pte))
+		return -ENOENT;
+
+	state = guest_get_page_state(pte, ipa);
+	if (state != PKVM_PAGE_SHARED_BORROWED)
+		return -EPERM;
+
+	phys = kvm_pte_to_phys(pte);
+	ret = range_is_allowed_memory(phys, phys + PAGE_SIZE);
+	if (WARN_ON(ret))
+		return ret;
+
+	page = hyp_phys_to_page(phys);
+	if (page->host_state != PKVM_PAGE_SHARED_OWNED)
+		return -EPERM;
+	if (WARN_ON(!page->host_share_guest_count))
+		return -EINVAL;
+
+	*__phys = phys;
+
+	return 0;
+}
+
+int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm)
+{
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	struct hyp_page *page;
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(hyp_vm);
+
+	ret = __check_host_unshare_guest(hyp_vm, &phys, ipa);
+	if (ret)
+		goto unlock;
+
+	ret = kvm_pgtable_stage2_unmap(&hyp_vm->pgt, ipa, PAGE_SIZE);
+	if (ret)
+		goto unlock;
+
+	page = hyp_phys_to_page(phys);
+	page->host_share_guest_count--;
+	if (!page->host_share_guest_count)
+		WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_OWNED));
+
+unlock:
+	guest_unlock_component(hyp_vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:29 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:29 +0000
Subject: [PATCH v2 12/18] KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-13-qperret@google.com>

Introduce a new hypercall allowing the host to relax the stage-2
permissions of mappings in a non-protected guest page-table. It will be
used later once we start allowing RO memslots and dirty logging.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 20 ++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 23 +++++++++++++++++++
 4 files changed, 45 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 0b6c4d325134..5d51933e44fb 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -67,6 +67,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_guest_perms,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index e528a42ed60e..db0dd83c2457 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -41,6 +41,7 @@ int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
+int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 04a9053ae1d5..60dd56bbd743 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -267,6 +267,25 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+static void handle___pkvm_host_relax_guest_perms(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, gfn, host_ctxt, 1);
+	DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 2);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		goto out;
+
+	ret = __pkvm_host_relax_guest_perms(gfn, prot, hyp_vcpu);
+out:
+	cpu_reg(host_ctxt, 1) = ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -478,6 +497,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
 	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
+	HANDLE_FUNC(__pkvm_host_relax_guest_perms),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index aa27a3e42e5e..d4b28e93e790 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1480,3 +1480,26 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm)
 
 	return ret;
 }
+
+int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	if ((prot & KVM_PGTABLE_PROT_RWX) != prot)
+		return -EPERM;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_unshare_guest(vm, &phys, ipa);
+	if (!ret)
+		ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:30 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:30 +0000
Subject: [PATCH v2 13/18] KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-14-qperret@google.com>

Introduce a new hypercall to remove the write permission from a
non-protected guest stage-2 mapping. This will be used for e.g. enabling
dirty logging.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 24 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 +++++++++++++++
 4 files changed, 45 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 5d51933e44fb..4d7d20ea03df 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -68,6 +68,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_guest_perms,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index db0dd83c2457..8658b5932473 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -42,6 +42,7 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);
+int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 60dd56bbd743..3feaf2119e51 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -286,6 +286,29 @@ static void handle___pkvm_host_relax_guest_perms(struct kvm_cpu_context *host_ct
 	cpu_reg(host_ctxt, 1) = ret;
 }
 
+static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	struct pkvm_hyp_vm *hyp_vm;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vm = get_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		goto out;
+	if (pkvm_hyp_vm_is_protected(hyp_vm))
+		goto put_hyp_vm;
+
+	ret = __pkvm_host_wrprotect_guest(gfn, hyp_vm);
+put_hyp_vm:
+	put_pkvm_hyp_vm(hyp_vm);
+out:
+	cpu_reg(host_ctxt, 1) = ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -498,6 +521,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
 	HANDLE_FUNC(__pkvm_host_relax_guest_perms),
+	HANDLE_FUNC(__pkvm_host_wrprotect_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index d4b28e93e790..89312d7cde2a 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1503,3 +1503,22 @@ int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pk
 
 	return ret;
 }
+
+int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
+{
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_unshare_guest(vm, &phys, ipa);
+	if (!ret)
+		ret = kvm_pgtable_stage2_wrprotect(&vm->pgt, ipa, PAGE_SIZE);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:31 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:31 +0000
Subject: [PATCH v2 14/18] KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-15-qperret@google.com>

Plumb the kvm_stage2_test_clear_young() callback into pKVM for
non-protected guest. It will be later be called from MMU notifiers.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 25 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 ++++++++++++++
 4 files changed, 46 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 4d7d20ea03df..cb676017d591 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -69,6 +69,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_guest_perms,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 8658b5932473..554ce31882e6 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -43,6 +43,7 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum k
 int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);
 int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
+int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 3feaf2119e51..67cb6e284180 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -309,6 +309,30 @@ static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt
 	cpu_reg(host_ctxt, 1) = ret;
 }
 
+static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	DECLARE_REG(bool, mkold, host_ctxt, 3);
+	struct pkvm_hyp_vm *hyp_vm;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vm = get_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		goto out;
+	if (pkvm_hyp_vm_is_protected(hyp_vm))
+		goto put_hyp_vm;
+
+	ret = __pkvm_host_test_clear_young_guest(gfn, mkold, hyp_vm);
+put_hyp_vm:
+	put_pkvm_hyp_vm(hyp_vm);
+out:
+	cpu_reg(host_ctxt, 1) = ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -522,6 +546,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
 	HANDLE_FUNC(__pkvm_host_relax_guest_perms),
 	HANDLE_FUNC(__pkvm_host_wrprotect_guest),
+	HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 89312d7cde2a..0e064a7ed7c4 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1522,3 +1522,22 @@ int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
 
 	return ret;
 }
+
+int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm)
+{
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_unshare_guest(vm, &phys, ipa);
+	if (!ret)
+		ret = kvm_pgtable_stage2_test_clear_young(&vm->pgt, ipa, PAGE_SIZE, mkold);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:32 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:32 +0000
Subject: [PATCH v2 15/18] KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-16-qperret@google.com>

Plumb the kvm_pgtable_stage2_mkyoung() callback into pKVM for
non-protected guests. It will be called later from the fault handling
path.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 19 ++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 20 +++++++++++++++++++
 4 files changed, 41 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index cb676017d591..6178e12a0dbc 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -70,6 +70,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_guest_perms,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_mkyoung_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 554ce31882e6..3ae0c3ecff48 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -44,6 +44,7 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);
 int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
+int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 67cb6e284180..de0012a75827 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -333,6 +333,24 @@ static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *ho
 	cpu_reg(host_ctxt, 1) = ret;
 }
 
+static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, gfn, host_ctxt, 1);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		goto out;
+
+	ret = __pkvm_host_mkyoung_guest(gfn, hyp_vcpu);
+out:
+	cpu_reg(host_ctxt, 1) =  ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -547,6 +565,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_relax_guest_perms),
 	HANDLE_FUNC(__pkvm_host_wrprotect_guest),
 	HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
+	HANDLE_FUNC(__pkvm_host_mkyoung_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 0e064a7ed7c4..7605bd7f80b5 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1541,3 +1541,23 @@ int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *
 
 	return ret;
 }
+
+int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_unshare_guest(vm, &phys, ipa);
+	if (!ret)
+		kvm_pgtable_stage2_mkyoung(&vm->pgt, ipa, 0);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:33 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:33 +0000
Subject: [PATCH v2 16/18] KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-17-qperret@google.com>

Introduce a new hypercall to flush the TLBs of non-protected guests. The
host kernel will be responsible for issuing this hypercall after changing
stage-2 permissions using the __pkvm_host_relax_guest_perms() or
__pkvm_host_wrprotect_guest() paths. This is left under the host's
responsibility for performance reasons.

Note however that the TLB maintenance for all *unmap* operations still
remains entirely under the hypervisor's responsibility for security
reasons -- an unmapped page may be donated to another entity, so a stale
TLB entry could be used to leak private data.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h   |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 6178e12a0dbc..df6237d0459c 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -87,6 +87,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
 	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
 	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
+	__KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
 };
 
 #define DECLARE_KVM_VHE_SYM(sym)	extern char sym[]
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index de0012a75827..219d7fb850ec 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -398,6 +398,22 @@ static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
 	__kvm_tlb_flush_vmid(kern_hyp_va(mmu));
 }
 
+static void handle___pkvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	struct pkvm_hyp_vm *hyp_vm;
+
+	if (!is_protected_kvm_enabled())
+		return;
+
+	hyp_vm = get_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		return;
+
+	__kvm_tlb_flush_vmid(&hyp_vm->kvm.arch.mmu);
+	put_pkvm_hyp_vm(hyp_vm);
+}
+
 static void handle___kvm_flush_cpu_context(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1);
@@ -582,6 +598,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_teardown_vm),
 	HANDLE_FUNC(__pkvm_vcpu_load),
 	HANDLE_FUNC(__pkvm_vcpu_put),
+	HANDLE_FUNC(__pkvm_tlb_flush_vmid),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:34 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:34 +0000
Subject: [PATCH v2 17/18] KVM: arm64: Introduce the EL1 pKVM MMU
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-18-qperret@google.com>

Introduce a set of helper functions allowing to manipulate the pKVM
guest stage-2 page-tables from EL1 using pKVM's HVC interface.

Each helper has an exact one-to-one correspondance with the traditional
kvm_pgtable_stage2_*() functions from pgtable.c, with a strictly
matching prototype. This will ease plumbing later on in mmu.c.

These callbacks track the gfn->pfn mappings in a simple rb_tree indexed
by IPA in lieu of a page-table. This rb-tree is kept in sync with pKVM's
state and is protected by a new rwlock -- the existing mmu_lock
protection does not suffice in the map() path where the tree must be
modified while user_mem_abort() only acquires a read_lock.

Signed-off-by: Quentin Perret <qperret at google.com>
---

The embedded union inside struct kvm_pgtable is arguably a bit horrible
currently... I considered making the pgt argument to all kvm_pgtable_*()
functions an opaque void * ptr, and moving the definition of
struct kvm_pgtable to pgtable.c and the pkvm version into pkvm.c. Given
that the allocation of that data-structure is done by the caller, that
means we'd need to expose kvm_pgtable_get_pgd_size() or something that
each MMU (pgtable.c and pkvm.c) would have to implement and things like
that. But that felt like a bigger surgery, so I went with the simpler
option. Thoughts welcome :-)

Similarly, happy to drop the mappings_lock if we want to teach
user_mem_abort() about taking a write lock on the mmu_lock in the pKVM
case, but again this implementation is the least invasive into normal
KVM so that felt like a reasonable starting point.
---
 arch/arm64/include/asm/kvm_host.h    |   1 +
 arch/arm64/include/asm/kvm_pgtable.h |  27 ++--
 arch/arm64/include/asm/kvm_pkvm.h    |  28 ++++
 arch/arm64/kvm/pkvm.c                | 195 +++++++++++++++++++++++++++
 4 files changed, 242 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f75988e3515b..05936b57a3a4 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -85,6 +85,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
 struct kvm_hyp_memcache {
 	phys_addr_t head;
 	unsigned long nr_pages;
+	struct pkvm_mapping *mapping; /* only used from EL1 */
 };
 
 static inline void push_hyp_memcache(struct kvm_hyp_memcache *mc,
diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 04418b5e3004..d24d18874015 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -412,15 +412,24 @@ static inline bool kvm_pgtable_walk_lock_held(void)
  *			be used instead of block mappings.
  */
 struct kvm_pgtable {
-	u32					ia_bits;
-	s8					start_level;
-	kvm_pteref_t				pgd;
-	struct kvm_pgtable_mm_ops		*mm_ops;
-
-	/* Stage-2 only */
-	struct kvm_s2_mmu			*mmu;
-	enum kvm_pgtable_stage2_flags		flags;
-	kvm_pgtable_force_pte_cb_t		force_pte_cb;
+	union {
+		struct {
+			u32					ia_bits;
+			s8					start_level;
+			kvm_pteref_t				pgd;
+			struct kvm_pgtable_mm_ops		*mm_ops;
+
+			/* Stage-2 only */
+			struct kvm_s2_mmu			*mmu;
+			enum kvm_pgtable_stage2_flags		flags;
+			kvm_pgtable_force_pte_cb_t		force_pte_cb;
+		};
+		struct {
+			struct kvm				*kvm;
+			struct rb_root				mappings;
+			rwlock_t				mappings_lock;
+		} pkvm;
+	};
 };
 
 /**
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index cd56acd9a842..84211d5daf87 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -11,6 +11,12 @@
 #include <linux/scatterlist.h>
 #include <asm/kvm_pgtable.h>
 
+struct pkvm_mapping {
+	u64 gfn;
+	u64 pfn;
+	struct rb_node node;
+};
+
 /* Maximum number of VMs that can co-exist under pKVM. */
 #define KVM_MAX_PVMS 255
 
@@ -137,4 +143,26 @@ static inline size_t pkvm_host_sve_state_size(void)
 			SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_sve_max_vl)));
 }
 
+static inline pkvm_handle_t pkvm_pgt_to_handle(struct kvm_pgtable *pgt)
+{
+	return pgt->pkvm.kvm->arch.pkvm.handle;
+}
+
+int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops);
+void pkvm_pgtable_destroy(struct kvm_pgtable *pgt);
+int pkvm_pgtable_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
+			   u64 phys, enum kvm_pgtable_prot prot,
+			   void *mc, enum kvm_pgtable_walk_flags flags);
+int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
+int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
+int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
+bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold);
+int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
+			     enum kvm_pgtable_walk_flags flags);
+void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags);
+int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc);
+void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level);
+kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
+					enum kvm_pgtable_prot prot, void *mc, bool force_pte);
+
 #endif	/* __ARM64_KVM_PKVM_H__ */
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index 85117ea8f351..9c648a510671 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/kmemleak.h>
 #include <linux/kvm_host.h>
+#include <asm/kvm_mmu.h>
 #include <linux/memblock.h>
 #include <linux/mutex.h>
 #include <linux/sort.h>
@@ -268,3 +269,197 @@ static int __init finalize_pkvm(void)
 	return ret;
 }
 device_initcall_sync(finalize_pkvm);
+
+static int cmp_mappings(struct rb_node *node, const struct rb_node *parent)
+{
+	struct pkvm_mapping *a = rb_entry(node, struct pkvm_mapping, node);
+	struct pkvm_mapping *b = rb_entry(parent, struct pkvm_mapping, node);
+
+	if (a->gfn < b->gfn)
+		return -1;
+	if (a->gfn > b->gfn)
+		return 1;
+	return 0;
+}
+
+static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
+{
+	struct rb_node *node = root->rb_node, *prev = NULL;
+	struct pkvm_mapping *mapping;
+
+	while (node) {
+		mapping = rb_entry(node, struct pkvm_mapping, node);
+		if (mapping->gfn == gfn)
+			return node;
+		prev = node;
+		node = (gfn < mapping->gfn) ? node->rb_left : node->rb_right;
+	}
+
+	return prev;
+}
+
+#define for_each_mapping_in_range(pgt, start_ipa, end_ipa, mapping, tmp)				\
+	for (tmp = find_first_mapping_node(&pgt->pkvm.mappings, ((start_ipa) >> PAGE_SHIFT));		\
+	     tmp && ({ mapping = rb_entry(tmp, struct pkvm_mapping, node); tmp = rb_next(tmp); 1; });)	\
+		if (mapping->gfn < ((start_ipa) >> PAGE_SHIFT))						\
+			continue;									\
+		else if (mapping->gfn >= ((end_ipa) >> PAGE_SHIFT))					\
+			break;										\
+		else
+
+int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops)
+{
+	pgt->pkvm.kvm		= kvm_s2_mmu_to_kvm(mmu);
+	pgt->pkvm.mappings	= RB_ROOT;
+	rwlock_init(&pgt->pkvm.mappings_lock);
+
+	return 0;
+}
+
+void pkvm_pgtable_destroy(struct kvm_pgtable *pgt)
+{
+	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
+	struct pkvm_mapping *mapping;
+	struct rb_node *node;
+
+	if (!handle)
+		return;
+
+	node = rb_first(&pgt->pkvm.mappings);
+	while (node) {
+		mapping = rb_entry(node, struct pkvm_mapping, node);
+		kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
+		node = rb_next(node);
+		rb_erase(&mapping->node, &pgt->pkvm.mappings);
+		kfree(mapping);
+	}
+}
+
+int pkvm_pgtable_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
+			   u64 phys, enum kvm_pgtable_prot prot,
+			   void *mc, enum kvm_pgtable_walk_flags flags)
+{
+	struct pkvm_mapping *mapping = NULL;
+	struct kvm_hyp_memcache *cache = mc;
+	u64 gfn = addr >> PAGE_SHIFT;
+	u64 pfn = phys >> PAGE_SHIFT;
+	int ret;
+
+	if (size != PAGE_SIZE)
+		return -EINVAL;
+
+	write_lock(&pgt->pkvm.mappings_lock);
+	ret = kvm_call_hyp_nvhe(__pkvm_host_share_guest, pfn, gfn, prot);
+	if (ret) {
+		/* Is the gfn already mapped due to a racing vCPU? */
+		if (ret == -EPERM)
+			ret = -EAGAIN;
+		goto unlock;
+	}
+
+	swap(mapping, cache->mapping);
+	mapping->gfn = gfn;
+	mapping->pfn = pfn;
+	WARN_ON(rb_find_add(&mapping->node, &pgt->pkvm.mappings, cmp_mappings));
+unlock:
+	write_unlock(&pgt->pkvm.mappings_lock);
+
+	return ret;
+}
+
+int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
+	struct pkvm_mapping *mapping;
+	struct rb_node *tmp;
+	int ret = 0;
+
+	write_lock(&pgt->pkvm.mappings_lock);
+	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
+		if (WARN_ON(ret))
+			break;
+
+		rb_erase(&mapping->node, &pgt->pkvm.mappings);
+		kfree(mapping);
+	}
+	write_unlock(&pgt->pkvm.mappings_lock);
+
+	return ret;
+}
+
+int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
+	struct pkvm_mapping *mapping;
+	struct rb_node *tmp;
+	int ret = 0;
+
+	read_lock(&pgt->pkvm.mappings_lock);
+	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn);
+		if (WARN_ON(ret))
+			break;
+	}
+	read_unlock(&pgt->pkvm.mappings_lock);
+
+	return ret;
+}
+
+int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	struct pkvm_mapping *mapping;
+	struct rb_node *tmp;
+
+	read_lock(&pgt->pkvm.mappings_lock);
+	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp)
+		__clean_dcache_guest_page(pfn_to_kaddr(mapping->pfn), PAGE_SIZE);
+	read_unlock(&pgt->pkvm.mappings_lock);
+
+	return 0;
+}
+
+bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold)
+{
+	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
+	struct pkvm_mapping *mapping;
+	struct rb_node *tmp;
+	bool young = false;
+
+	read_lock(&pgt->pkvm.mappings_lock);
+	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp)
+		young |= kvm_call_hyp_nvhe(__pkvm_host_test_clear_young_guest, handle, mapping->gfn,
+					   mkold);
+	read_unlock(&pgt->pkvm.mappings_lock);
+
+	return young;
+}
+
+int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
+			     enum kvm_pgtable_walk_flags flags)
+{
+	return kvm_call_hyp_nvhe(__pkvm_host_relax_guest_perms, addr >> PAGE_SHIFT, prot);
+}
+
+void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags)
+{
+	WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_mkyoung_guest, addr >> PAGE_SHIFT));
+}
+
+void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
+{
+	WARN_ON(1);
+}
+
+kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
+					enum kvm_pgtable_prot prot, void *mc, bool force_pte)
+{
+	WARN_ON(1);
+	return NULL;
+}
+
+int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc)
+{
+	WARN_ON(1);
+	return -EINVAL;
+}
-- 
2.47.0.338.g60cca15819-goog



From qperret at google.com  Tue Dec  3 02:37:35 2024
From: qperret at google.com (Quentin Perret)
Date: Tue,  3 Dec 2024 10:37:35 +0000
Subject: [PATCH v2 18/18] KVM: arm64: Plumb the pKVM MMU in KVM
In-Reply-To: <20241203103735.2267589-1-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
Message-ID: <20241203103735.2267589-19-qperret@google.com>

Introduce the KVM_PGT_S2() helper macro to allow switching from the
traditional pgtable code to the pKVM version easily in mmu.c. The cost
of this 'indirection' is expected to be very minimal due to
is_protected_kvm_enabled() being backed by a static key.

With this, everything is in place to allow the delegation of
non-protected guest stage-2 page-tables to pKVM, so let's stop using the
host's kvm_s2_mmu from EL2 and enjoy the ride.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/arm.c               |   9 ++-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c |   2 -
 arch/arm64/kvm/mmu.c               | 103 +++++++++++++++++++++--------
 3 files changed, 83 insertions(+), 31 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 55cc62b2f469..9bcbc7b8ed38 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -502,7 +502,10 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 
 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
-	kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+	if (!is_protected_kvm_enabled())
+		kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+	else
+		free_hyp_memcache(&vcpu->arch.pkvm_memcache);
 	kvm_timer_vcpu_terminate(vcpu);
 	kvm_pmu_vcpu_destroy(vcpu);
 	kvm_vgic_vcpu_destroy(vcpu);
@@ -574,6 +577,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	struct kvm_s2_mmu *mmu;
 	int *last_ran;
 
+	if (is_protected_kvm_enabled())
+		goto nommu;
+
 	if (vcpu_has_nv(vcpu))
 		kvm_vcpu_load_hw_mmu(vcpu);
 
@@ -594,6 +600,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		*last_ran = vcpu->vcpu_idx;
 	}
 
+nommu:
 	vcpu->cpu = cpu;
 
 	kvm_vgic_load(vcpu);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 219d7fb850ec..64c7dc595218 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -103,8 +103,6 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 	/* Limit guest vector length to the maximum supported by the host.  */
 	hyp_vcpu->vcpu.arch.sve_max_vl	= min(host_vcpu->arch.sve_max_vl, kvm_host_sve_max_vl);
 
-	hyp_vcpu->vcpu.arch.hw_mmu	= host_vcpu->arch.hw_mmu;
-
 	hyp_vcpu->vcpu.arch.mdcr_el2	= host_vcpu->arch.mdcr_el2;
 	hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE);
 	hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2) &
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 641e4fec1659..058bc2c8f3c6 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -15,6 +15,7 @@
 #include <asm/kvm_arm.h>
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_pgtable.h>
+#include <asm/kvm_pkvm.h>
 #include <asm/kvm_ras.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
@@ -31,6 +32,14 @@ static phys_addr_t __ro_after_init hyp_idmap_vector;
 
 static unsigned long __ro_after_init io_map_base;
 
+#define KVM_PGT_S2(fn, ...)								\
+	({										\
+		typeof(kvm_pgtable_stage2_ ## fn) *__fn = kvm_pgtable_stage2_ ## fn;	\
+		if (is_protected_kvm_enabled())						\
+			__fn = pkvm_pgtable_ ## fn;					\
+		__fn(__VA_ARGS__);							\
+	})
+
 static phys_addr_t __stage2_range_addr_end(phys_addr_t addr, phys_addr_t end,
 					   phys_addr_t size)
 {
@@ -147,7 +156,7 @@ static int kvm_mmu_split_huge_pages(struct kvm *kvm, phys_addr_t addr,
 			return -EINVAL;
 
 		next = __stage2_range_addr_end(addr, end, chunk_size);
-		ret = kvm_pgtable_stage2_split(pgt, addr, next - addr, cache);
+		ret = KVM_PGT_S2(split, pgt, addr, next - addr, cache);
 		if (ret)
 			break;
 	} while (addr = next, addr != end);
@@ -168,15 +177,23 @@ static bool memslot_is_logging(struct kvm_memory_slot *memslot)
  */
 int kvm_arch_flush_remote_tlbs(struct kvm *kvm)
 {
-	kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
+	if (is_protected_kvm_enabled())
+		kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
+	else
+		kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
 	return 0;
 }
 
 int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm,
 				      gfn_t gfn, u64 nr_pages)
 {
-	kvm_tlb_flush_vmid_range(&kvm->arch.mmu,
-				gfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT);
+	u64 size = nr_pages << PAGE_SHIFT;
+	u64 addr = gfn << PAGE_SHIFT;
+
+	if (is_protected_kvm_enabled())
+		kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
+	else
+		kvm_tlb_flush_vmid_range(&kvm->arch.mmu, addr, size);
 	return 0;
 }
 
@@ -225,7 +242,7 @@ static void stage2_free_unlinked_table_rcu_cb(struct rcu_head *head)
 	void *pgtable = page_to_virt(page);
 	s8 level = page_private(page);
 
-	kvm_pgtable_stage2_free_unlinked(&kvm_s2_mm_ops, pgtable, level);
+	KVM_PGT_S2(free_unlinked, &kvm_s2_mm_ops, pgtable, level);
 }
 
 static void stage2_free_unlinked_table(void *addr, s8 level)
@@ -280,6 +297,11 @@ static void invalidate_icache_guest_page(void *va, size_t size)
 	__invalidate_icache_guest_page(va, size);
 }
 
+static int kvm_s2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	return KVM_PGT_S2(unmap, pgt, addr, size);
+}
+
 /*
  * Unmapping vs dcache management:
  *
@@ -324,8 +346,7 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
 
 	lockdep_assert_held_write(&kvm->mmu_lock);
 	WARN_ON(size & ~PAGE_MASK);
-	WARN_ON(stage2_apply_range(mmu, start, end, kvm_pgtable_stage2_unmap,
-				   may_block));
+	WARN_ON(stage2_apply_range(mmu, start, end, kvm_s2_unmap, may_block));
 }
 
 void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
@@ -334,9 +355,14 @@ void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
 	__unmap_stage2_range(mmu, start, size, may_block);
 }
 
+static int kvm_s2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	return KVM_PGT_S2(flush, pgt, addr, size);
+}
+
 void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
 {
-	stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_flush);
+	stage2_apply_range_resched(mmu, addr, end, kvm_s2_flush);
 }
 
 static void stage2_flush_memslot(struct kvm *kvm,
@@ -942,10 +968,14 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 		return -ENOMEM;
 
 	mmu->arch = &kvm->arch;
-	err = kvm_pgtable_stage2_init(pgt, mmu, &kvm_s2_mm_ops);
+	err = KVM_PGT_S2(init, pgt, mmu, &kvm_s2_mm_ops);
 	if (err)
 		goto out_free_pgtable;
 
+	mmu->pgt = pgt;
+	if (is_protected_kvm_enabled())
+		return 0;
+
 	mmu->last_vcpu_ran = alloc_percpu(typeof(*mmu->last_vcpu_ran));
 	if (!mmu->last_vcpu_ran) {
 		err = -ENOMEM;
@@ -959,7 +989,6 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 	mmu->split_page_chunk_size = KVM_ARM_EAGER_SPLIT_CHUNK_SIZE_DEFAULT;
 	mmu->split_page_cache.gfp_zero = __GFP_ZERO;
 
-	mmu->pgt = pgt;
 	mmu->pgd_phys = __pa(pgt->pgd);
 
 	if (kvm_is_nested_s2_mmu(kvm, mmu))
@@ -968,7 +997,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 	return 0;
 
 out_destroy_pgtable:
-	kvm_pgtable_stage2_destroy(pgt);
+	KVM_PGT_S2(destroy, pgt);
 out_free_pgtable:
 	kfree(pgt);
 	return err;
@@ -1065,7 +1094,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
 	write_unlock(&kvm->mmu_lock);
 
 	if (pgt) {
-		kvm_pgtable_stage2_destroy(pgt);
+		KVM_PGT_S2(destroy, pgt);
 		kfree(pgt);
 	}
 }
@@ -1082,9 +1111,11 @@ static void *hyp_mc_alloc_fn(void *unused)
 
 void free_hyp_memcache(struct kvm_hyp_memcache *mc)
 {
-	if (is_protected_kvm_enabled())
-		__free_hyp_memcache(mc, hyp_mc_free_fn,
-				    kvm_host_va, NULL);
+	if (!is_protected_kvm_enabled())
+		return;
+
+	kfree(mc->mapping);
+	__free_hyp_memcache(mc, hyp_mc_free_fn, kvm_host_va, NULL);
 }
 
 int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages)
@@ -1092,6 +1123,12 @@ int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages)
 	if (!is_protected_kvm_enabled())
 		return 0;
 
+	if (!mc->mapping) {
+		mc->mapping = kzalloc(sizeof(struct pkvm_mapping), GFP_KERNEL_ACCOUNT);
+		if (!mc->mapping)
+			return -ENOMEM;
+	}
+
 	return __topup_hyp_memcache(mc, min_pages, hyp_mc_alloc_fn,
 				    kvm_host_pa, NULL);
 }
@@ -1130,8 +1167,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 			break;
 
 		write_lock(&kvm->mmu_lock);
-		ret = kvm_pgtable_stage2_map(pgt, addr, PAGE_SIZE, pa, prot,
-					     &cache, 0);
+		ret = KVM_PGT_S2(map, pgt, addr, PAGE_SIZE, pa, prot, &cache, 0);
 		write_unlock(&kvm->mmu_lock);
 		if (ret)
 			break;
@@ -1143,6 +1179,10 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 	return ret;
 }
 
+static int kvm_s2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	return KVM_PGT_S2(wrprotect, pgt, addr, size);
+}
 /**
  * kvm_stage2_wp_range() - write protect stage2 memory region range
  * @mmu:        The KVM stage-2 MMU pointer
@@ -1151,7 +1191,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
  */
 void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
 {
-	stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_wrprotect);
+	stage2_apply_range_resched(mmu, addr, end, kvm_s2_wrprotect);
 }
 
 /**
@@ -1442,9 +1482,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	unsigned long mmu_seq;
 	phys_addr_t ipa = fault_ipa;
 	struct kvm *kvm = vcpu->kvm;
-	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
 	struct vm_area_struct *vma;
 	short vma_shift;
+	void *memcache;
 	gfn_t gfn;
 	kvm_pfn_t pfn;
 	bool logging_active = memslot_is_logging(memslot);
@@ -1472,8 +1512,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * and a write fault needs to collapse a block entry into a table.
 	 */
 	if (!fault_is_perm || (logging_active && write_fault)) {
-		ret = kvm_mmu_topup_memory_cache(memcache,
-						 kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu));
+		int min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu);
+
+		if (!is_protected_kvm_enabled()) {
+			memcache = &vcpu->arch.mmu_page_cache;
+			ret = kvm_mmu_topup_memory_cache(memcache, min_pages);
+		} else {
+			memcache = &vcpu->arch.pkvm_memcache;
+			ret = topup_hyp_memcache(memcache, min_pages);
+		}
 		if (ret)
 			return ret;
 	}
@@ -1494,7 +1541,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * logging_active is guaranteed to never be true for VM_PFNMAP
 	 * memslots.
 	 */
-	if (logging_active) {
+	if (logging_active || is_protected_kvm_enabled()) {
 		force_pte = true;
 		vma_shift = PAGE_SHIFT;
 	} else {
@@ -1696,9 +1743,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		 * PTE, which will be preserved.
 		 */
 		prot &= ~KVM_NV_GUEST_MAP_SZ;
-		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot, flags);
+		ret = KVM_PGT_S2(relax_perms, pgt, fault_ipa, prot, flags);
 	} else {
-		ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
+		ret = KVM_PGT_S2(map, pgt, fault_ipa, vma_pagesize,
 					     __pfn_to_phys(pfn), prot,
 					     memcache, flags);
 	}
@@ -1724,7 +1771,7 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 
 	read_lock(&vcpu->kvm->mmu_lock);
 	mmu = vcpu->arch.hw_mmu;
-	kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa, flags);
+	KVM_PGT_S2(mkyoung, mmu->pgt, fault_ipa, flags);
 	read_unlock(&vcpu->kvm->mmu_lock);
 }
 
@@ -1764,7 +1811,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		}
 
 		/* Falls between the IPA range and the PARange? */
-		if (fault_ipa >= BIT_ULL(vcpu->arch.hw_mmu->pgt->ia_bits)) {
+		if (fault_ipa >= BIT_ULL(VTCR_EL2_IPA(vcpu->arch.hw_mmu->vtcr))) {
 			fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
 
 			if (is_iabt)
@@ -1930,7 +1977,7 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
-	return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
+	return KVM_PGT_S2(test_clear_young, kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, true);
 	/*
@@ -1946,7 +1993,7 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
-	return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
+	return KVM_PGT_S2(test_clear_young, kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, false);
 }
-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 03:02:20 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 11:02:20 +0000
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <bce22ca8-aed2-41ae-b2ef-fdc71266709a@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
	 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
	 <9387c0cf-d291-485a-8cd1-1aced7eba14e@uclouvain.be>
	 <2883fb0dd22312d5da9039d4fef869276a0bd430.camel@linaro.org>
	 <bce22ca8-aed2-41ae-b2ef-fdc71266709a@uclouvain.be>
Message-ID: <16f9b5f8aed79e9313b4638512896743fa5a8d6d.camel@linaro.org>

On Tue, 2024-12-03 at 11:11 +0100, Thomas Antoine wrote:
> On 12/3/24 10:31, Andr? Draszik wrote:
> > On Tue, 2024-12-03 at 10:08 +0100, Thomas Antoine wrote:
> > > On 12/3/24 07:47, Andr? Draszik wrote:
> > > > > From: Thomas Antoine <t.antoine at uclouvain.be>
> > > > > 
[...]

> > > > > ?/*
> > > > > ? * Model Gauge M5 Algorithm output register
> > > > > ? * Volatile data (must not be cached)
> > > > > @@ -369,6 +387,8 @@ static int max1720x_battery_get_property(struct
> > > > > power_supply *psy,
> > > > > ????????????????????? val->strval = max17201_model;
> > > > > ????????????? else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17205)
> > > > > ????????????????????? val->strval = max17205_model;
> > > > > +???????????? else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX77759)
> > > > > +???????????????????? val->strval = max77759_model;
> > > > > ????????????? else
> > > > 
> > > > This is a 16 bit register, and while yes, MAX172XX_DEV_NAME_TYPE_MASK only
> > > > cares about the bottom 4 bits, the register is described as 'Firmware
> > > > Version Information'.
> > > > 
> > > > But maybe it's ok to do it like that, at least for now.
> > > 
> > > I thought this method would be ok as long as there is no collision on
> > > values. I hesitated to change the model evaluation method based on chip
> > > model, where the max77759 would thus have an hard-coded value and the
> > > max1720x would still evaluate the register value. I did not do it because
> > > it led to a lot more changes for no difference.
> > 
> > Downstream uses the upper bits for max77759:
> > https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max_m5.h#135
> > 
> > I don't know what the original max17201/5 report in this register
> > for those bits, though. Given for max77759 this register returns
> > the firmware version, I assume the lower bits can change.
> 
> Based on this datasheet of the max1720x, the upper bits are the revision
> and the four lower bits are device. So it could change.
> https://www.analog.com/media/en/technical-documentation/data-sheets/MAX17201-MAX17215.pdf#MAX17201%20DS.indd%3A.213504%3A15892
> 
> If the four lower bits are not always 0 for the max77759 then I guess it
> is necessary to change this as it wouldn't work with all max77759.

Maybe the best way forward is to go by the compatible (from DT), and
if max77759 to then print a warning if the upper bits are != 0x62 and
!= 0x63. And maybe even refuse to load in that case.

Cheers,
Andre'



From tglx at linutronix.de  Tue Dec  3 03:04:30 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 03 Dec 2024 12:04:30 +0100
Subject: [PATCH v5 1/2] kexec: Consolidate
 machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241130201143.48808-2-farbere@amazon.com>
References: <20241130201143.48808-1-farbere@amazon.com>
 <20241130201143.48808-2-farbere@amazon.com>
Message-ID: <87wmght4ch.ffs@tglx>

On Sat, Nov 30 2024 at 20:11, Eliav Farber wrote:
> +
> +config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
> +	bool "Clear forwarded VM interrupts during kexec"

This should not be user selectable. Just keep it as:

config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
	bool

which defaults to 'n'. Just add a comment what this is about like it's
done with the other options in that file which are only selectable.

Thanks,

        tglx


From andre.draszik at linaro.org  Tue Dec  3 03:06:14 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 03 Dec 2024 11:06:14 +0000
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <61a54367-2406-4106-bf8b-9fda4f2d11a6@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
	 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
	 <8f585460a1bc52f78a6d0867aed87398bde30152.camel@linaro.org>
	 <18629c9edd295a524a1c9764f013a0e97e0b275f.camel@linaro.org>
	 <61a54367-2406-4106-bf8b-9fda4f2d11a6@uclouvain.be>
Message-ID: <d1bade77b5281c1de6b2ddcb4dbbd033e455a116.camel@linaro.org>

On Tue, 2024-12-03 at 11:30 +0100, Thomas Antoine wrote:
> 
> Should I explicitly deny their use in the code for the max77759 or is it
> just for information?

I'd probably do something like this, which will indeed deny their reading
and/or writing, both via debugfs, and also normal driver access via
readmap_read()/write() etc:

static const struct regmap_range max77759_registers[] = {
	regmap_reg_range(0x00, 0x4f),
	regmap_reg_range(0xb0, 0xbf),
	regmap_reg_range(0xd0, 0xd0),
	regmap_reg_range(0xdc, 0xdf),
	regmap_reg_range(0xfb, 0xfb),
	regmap_reg_range(0xff, 0xff),
};

static const struct regmap_range max77759_ro_registers[] = {
	regmap_reg_range(0x3d, 0x3d),
	regmap_reg_range(0xfb, 0xfb),
	regmap_reg_range(0xff, 0xff),
};

static const struct regmap_access_table max77759_write_table = {
	.yes_ranges = max77759_registers,
	.n_yes_ranges = ARRAY_SIZE(max77759_registers),
	.no_ranges = max77759_ro_registers,
	.n_no_ranges = ARRAY_SIZE(max77759_ro_registers),
};

static const struct regmap_access_table max77759_rd_table = {
	.yes_ranges = max77759_registers,
	.n_yes_ranges = ARRAY_SIZE(max77759_registers),
};

static const struct regmap_config max77759_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = 0xff,
	.wr_table = &max77759_write_table,
	.rd_table = &max77759_rd_table,
	.cache_type = REGCACHE_NONE,
};

And maybe without cache for now. Most are probably not cacheable anyway.

Cheers,
Andre'



From jbrunet at baylibre.com  Tue Dec  3 03:15:41 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Tue, 03 Dec 2024 12:15:41 +0100
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org> (Stephen
	Boyd's message of "Mon, 02 Dec 2024 18:53:30 -0800")
References: <20241127-clk-audio-fix-rst-missing-v1-1-9f9d0ab98fce@baylibre.com>
	<12f29978-c8ce-4bee-a447-dcd086eb936d@app.fastmail.com>
	<1ja5dk2y5l.fsf@starbuckisacylon.baylibre.com>
	<f8de4a2a-776f-4c10-b75e-e845bcc38dde@app.fastmail.com>
	<1j4j3r32ld.fsf@starbuckisacylon.baylibre.com>
	<306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com>
	<1jy1131kxz.fsf@starbuckisacylon.baylibre.com>
	<c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com>
	<1jplmf1jqa.fsf@starbuckisacylon.baylibre.com>
	<ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com>
	<df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org>
Message-ID: <1jr06pkof6.fsf@starbuckisacylon.baylibre.com>

On Mon 02 Dec 2024 at 18:53, Stephen Boyd <sboyd at kernel.org> wrote:

> Happy Thanksgiving!
>
> Quoting Arnd Bergmann (2024-11-28 07:34:46)
>> On Thu, Nov 28, 2024, at 16:06, Jerome Brunet wrote:
>> > On Thu 28 Nov 2024 at 15:51, "Arnd Bergmann" <arnd at arndb.de> wrote:
>> >> On Thu, Nov 28, 2024, at 15:39, Jerome Brunet wrote:
>> >>> On Thu 28 Nov 2024 at 15:11, "Arnd Bergmann" <arnd at arndb.de> wrote:
>> >>> Eventually that will happen for the rest of the reset implemented
>> >>> under drivers/clk/meson.
>> >>>
>> >>> It allows to make some code common between the platform reset
>> >>> drivers and the aux ones. It also ease maintainance for both
>> >>> Stephen and Philipp.
>> >>
>> >> I don't understand how this helps: the entire point of using
>> >> an auxiliary device is to separate the lifetime rules of
>> >> the different bits, but by doing the creation of the device
>> >> in the same file as the implementation, you are not taking
>> >> advantage of that at all, but instead get the complexity of
>> >> a link-time dependency in addition to a lot of extra code
>> >> for dealing with the additional device.
>> >
>> > My initial rework had the creation in clock (note: that is why I
>> > initially used 'imply', and forgot to update when the creation moved to
>> > reset).
>> >
>> > I was asked to move the creation in reset:
>> > https://lore.kernel.org/r/217a785212d7c1a5b504c6040b3636e6.sboyd at kernel.org
>> >
>> > We are deviating a bit from the initial regression reported by Mark.
>> > Is Ok with you to proceed with that fix and then continue this discussion
>> > ?
>> 
>> I really don't want to see those stray 'select' statements
>> in there, as that leave very little incentive for anyone to
>> fix it properly.
>> 
>> It sounds like Stephen gave you bad advice for how it should
>> be structured, so my best suggestion would be to move the
>> the problem (and the reset driver) back into his subsystem
>> and leave only a simple 'select RESET_CONTROLLER'.
>> 
>> From the message you cited, I think Stephen had the right
>> intentions ("so that the clk and reset drivers are decoupled"),
>> but the end result did not actually do what he intended
>> even if you did what he asked for.
>> 
>> Stephen, can you please take a look here and see if you
>> have a better idea for either decoupling the two drivers
>> enough to avoid the link time dependency, or to reintegrate
>> the reset controller code into the clk driver and avoid
>> the complexity?
>
> I think the best approach is to add the reset auxilary device with a
> function that creates the auxiliary device directly by string name and
> does nothing else. Maybe we can have some helper in the auxiliary
> layer that does that all for us, because it's quite a bit of boiler
> plate that we need to write over and over again. Something like:
>
>   int devm_auxiliary_device_create(struct device *parent, const char *name)
>
> that does the whole kzalloc() + ida dance that
> devm_meson_rst_aux_register() is doing today and wraps it all up so that
> the device is removed when the parent driver unbinds. Then this clk
> driver can register the reset device with a single call and not need to
> do anything besides select AUXILIARY_BUS.

I think this is fairly close to what I proposed in the inital RFC, but
generic instead of specific.

I suspect the the generic path is likely to trigger more discussion.
I'd like to be able to finish this migration, instead of leaving half
finished like it is now.

May I add back the boiler plate code in drivers/clk/meson, similar to
what was proposed in the RFC [1] and propose the generic implementation
in parallel ? It will just be a matter of switching when/if it is approved.

[1] https://lore.kernel.org/r/20240516150842.705844-9-jbrunet at baylibre.com

> The regmap can be acquired
> from the parent device in the auxiliary driver probe with
> dev_get_regmap(adev->parent).

Did not think about that, I'll check, Thanks

-- 
Jerome


From frank-w at public-files.de  Tue Dec  3 03:27:44 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Tue, 03 Dec 2024 12:27:44 +0100
Subject: =?US-ASCII?Q?Re=3A_=5BPATCH_v2_10/18=5D_arm64=3A_dts=3A_medi?=
 =?US-ASCII?Q?atek=3A_mt7988=3A_enable_serial0_on_bpi-r4?=
In-Reply-To: <32ef5ab8-a163-4fdc-8603-f5a6f0e8526b@collabora.com>
References: <20241202122602.30734-1-linux@fw-web.de> <20241202122602.30734-11-linux@fw-web.de> <32ef5ab8-a163-4fdc-8603-f5a6f0e8526b@collabora.com>
Message-ID: <6964E096-7C19-450C-8434-6A4456AFDD55@public-files.de>

Am 3. Dezember 2024 10:40:45 MEZ schrieb AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>:
>Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>> From: Frank Wunderlich <frank-w at public-files.de>
>> 
>
>arm64: dts: mediatek: mt7988a-bpi-r4: Enable serial0 debug uart

You want new prefix here? That will change all r4 commits,right?

>> Enable the debug uart on Bananapi R4 board.
>> 
>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>
>Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>


regards Frank


From stephan.gerhold at linaro.org  Tue Dec  3 03:30:37 2024
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Tue, 3 Dec 2024 12:30:37 +0100
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint readery
In-Reply-To: <Z07bgH5vVk44zuEH@hovoldconsulting.com>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com>
Message-ID: <Z07r3Upr50vLluyn@linaro.org>

On Tue, Dec 03, 2024 at 11:20:48AM +0100, Johan Hovold wrote:
> [ +CC: Krishna, Thinh and the USB list ]
> 
> On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
> > The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
> > multiport controller on eUSB6. All other ports (including USB super-speed
> > pins) are unused.
> > 
> > Set it up in the device tree together with the NXP PTN3222 repeater.
> > 
> > Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> > ---
> >  arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 48 +++++++++++++++++++++++++++++++
> >  1 file changed, 48 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > index 39f9d9cdc10d..44942931c18f 100644
> > --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > @@ -735,6 +735,26 @@ keyboard at 3a {
> >  	};
> >  };
> >  
> > +&i2c5 {
> > +	clock-frequency = <400000>;
> > +
> > +	status = "okay";
> > +
> > +	eusb6_repeater: redriver at 4f {
> > +		compatible = "nxp,ptn3222";
> > +		reg = <0x4f>;
> 
> The driver does not currently check that there's actually anything at
> this address. Did you verify that this is the correct address? 
> 
> (Abel is adding a check to the driver as we speak to catch any such
> mistakes going forward).
> 

Yes, I verified this using
https://git.codelinaro.org/stephan.gerhold/linux/-/commit/45d5add498612387f88270ca944ee16e2236fddd

(I sent this to Abel back then, so I'm surprised he didn't run that :-))

> > +		#phy-cells = <0>;
> 
> nit: I'd put provider properties like this one last.
> 
> > +		vdd3v3-supply = <&vreg_l13b_3p0>;
> > +		vdd1v8-supply = <&vreg_l4b_1p8>;
> 
> Sort by supply name?
> 

Ack.

> > +		reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>;
> > +
> > +		pinctrl-0 = <&eusb6_reset_n>;
> > +		pinctrl-names = "default";
> > +	};
> > +};
> > +
> >  &i2c8 {
> >  	clock-frequency = <400000>;
> >  
> > @@ -1047,6 +1067,14 @@ edp_reg_en: edp-reg-en-state {
> >  		bias-disable;
> >  	};
> >  
> > +	eusb6_reset_n: eusb6-reset-n-state {
> > +		pins = "gpio184";
> > +		function = "gpio";
> > +		drive-strength = <2>;
> > +		bias-disable;
> > +		output-low;
> 
> I don't think the pin config should assert reset, that should be up to
> the driver to control.
> 

I can drop it I guess, but pinctrl is applied before the driver takes
control of the GPIO. This means if the GPIO happens to be in input mode
before the driver loads (with pull up or pull down), then we would
briefly leave it floating when applying the bias-disable.

Or I guess we could drop the bias-disable, since it shouldn't be
relevant for a pin we keep in output mode all the time?

> > +	};
> > +
> >  	hall_int_n_default: hall-int-n-state {
> >  		pins = "gpio92";
> >  		function = "gpio";
> > @@ -1260,3 +1288,23 @@ &usb_1_ss2_dwc3_hs {
> >  &usb_1_ss2_qmpphy_out {
> >  	remote-endpoint = <&pmic_glink_ss2_ss_in>;
> >  };
> > +
> > +&usb_mp {
> > +	status = "okay";
> > +};
> > +
> > +&usb_mp_dwc3 {
> > +	/* Limit to USB 2.0 and single port */
> > +	maximum-speed = "high-speed";
> > +	phys = <&usb_mp_hsphy1>;
> > +	phy-names = "usb2-1";
> > +};
> 
> The dwc3 driver determines (and acts on) the number of ports based on
> the port interrupts in DT and controller capabilities. 
> 
> I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
> that would still be there in the SoC (possibly initialised by the boot
> firmware).
> 
> I had a local patch to enable the multiport controller (for the suspend
> work) and I realise that you'd currently need to specify a repeater also
> for the HS PHY which does not have one, but that should be possible to
> fix somehow.
> 

I think there are two separate questions here:

 1. Should we (or do we even need to) enable unused PHYs?
 2. Do we need to power off unused PHYs left enabled by the firmware?

For (1), I'm not not sure if there is a technical reason that requires
us to. And given that PHYs typically consume quite a bit of power, I'm
not sure if we should. Perhaps it's not worth spending effort on this
minor optimization now, but then the device tree would ideally still
tell us which PHYs are actually used (for future optimizations).

For (2), yes, we probably need to. But my impression so far is that this
might be a larger problem that we need to handle on the SoC level. I
have seen some firmware versions that blindly power up all USB
controllers, even completely unused ones. Ideally we would power down
unused components during startup and then leave them off.

Thanks,
Stephan


From yeoreum.yun at arm.com  Tue Dec  3 03:49:37 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:37 +0000
Subject: [PATCH v2 4/9] coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <20241203114942.697188-5-yeoreum.yun@arm.com>

In coresight-cti drivers, cti_drvdata->spinlock can be held during __schedule()
by perf_event_task_sched_out()/in().

Since cti_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type cti_drvdata->spinlock in coresight-cti drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-cti-core.c  | 44 +++++------
 .../hwtracing/coresight/coresight-cti-sysfs.c | 76 +++++++++----------
 drivers/hwtracing/coresight/coresight-cti.h   |  2 +-
 3 files changed, 61 insertions(+), 61 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
index d2b5a5718c29..80f6265e3740 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -93,7 +93,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
 	unsigned long flags;
 	int rc = 0;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* no need to do anything if enabled or unpowered*/
 	if (config->hw_enabled || !config->hw_powered)
@@ -108,7 +108,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
 
 	config->hw_enabled = true;
 	drvdata->config.enable_req_count++;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return rc;
 
 cti_state_unchanged:
@@ -116,7 +116,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
 
 	/* cannot enable due to error */
 cti_err_not_enabled:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return rc;
 }
 
@@ -125,7 +125,7 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata)
 {
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->hw_powered = true;
 
 	/* no need to do anything if no enable request */
@@ -138,12 +138,12 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata)
 
 	cti_write_all_hw_regs(drvdata);
 	config->hw_enabled = true;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return;
 
 	/* did not re-enable due to no claim / no request */
 cti_hp_not_enabled:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 }
 
 /* disable hardware */
@@ -153,7 +153,7 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
 	struct coresight_device *csdev = drvdata->csdev;
 	int ret = 0;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* don't allow negative refcounts, return an error */
 	if (!drvdata->config.enable_req_count) {
@@ -177,12 +177,12 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
 
 	coresight_disclaim_device_unlocked(csdev);
 	CS_LOCK(drvdata->base);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return ret;
 
 	/* not disabled this call */
 cti_not_disabled:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return ret;
 }
 
@@ -198,11 +198,11 @@ void cti_write_intack(struct device *dev, u32 ackval)
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* write if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIINTACK, ackval);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 }
 
 /*
@@ -369,7 +369,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 	reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) :
 		      CTIOUTEN(trigger_idx));
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* read - modify write - the trigger / channel enable value */
 	reg_value = direction == CTI_TRIG_IN ? config->ctiinen[trigger_idx] :
@@ -388,7 +388,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, reg_offset, reg_value);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return 0;
 }
 
@@ -406,7 +406,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
 
 	chan_bitmask = BIT(channel_idx);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	reg_value = config->ctigate;
 	switch (op) {
 	case CTI_GATE_CHAN_ENABLE:
@@ -426,7 +426,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
 		if (cti_active(config))
 			cti_write_single_reg(drvdata, CTIGATE, reg_value);
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return err;
 }
 
@@ -445,7 +445,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
 
 	chan_bitmask = BIT(channel_idx);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	reg_value = config->ctiappset;
 	switch (op) {
 	case CTI_CHAN_SET:
@@ -473,7 +473,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
 
 	if ((err == 0) && cti_active(config))
 		cti_write_single_reg(drvdata, reg_offset, reg_value);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return err;
 }
@@ -676,7 +676,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
 	if (WARN_ON_ONCE(drvdata->ctidev.cpu != cpu))
 		return NOTIFY_BAD;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	switch (cmd) {
 	case CPU_PM_ENTER:
@@ -716,7 +716,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
 	}
 
 cti_notify_exit:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return notify_res;
 }
 
@@ -743,11 +743,11 @@ static int cti_dying_cpu(unsigned int cpu)
 	if (!drvdata)
 		return 0;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.hw_powered = false;
 	if (drvdata->config.hw_enabled)
 		coresight_disclaim_device(drvdata->csdev);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return 0;
 }
 
@@ -888,7 +888,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 	drvdata->ctidev.ctm_id = 0;
 	INIT_LIST_HEAD(&drvdata->ctidev.trig_cons);
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	/* initialise CTI driver config values */
 	cti_set_default_config(dev, drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
index d25dd2737b49..572b80ee96fb 100644
--- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
@@ -84,11 +84,11 @@ static ssize_t enable_show(struct device *dev,
 	bool enabled, powered;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	enable_req = drvdata->config.enable_req_count;
 	powered = drvdata->config.hw_powered;
 	enabled = drvdata->config.hw_enabled;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	if (powered)
 		return sprintf(buf, "%d\n", enabled);
@@ -134,9 +134,9 @@ static ssize_t powered_show(struct device *dev,
 	bool powered;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	powered = drvdata->config.hw_powered;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return sprintf(buf, "%d\n", powered);
 }
@@ -181,10 +181,10 @@ static ssize_t coresight_cti_reg_show(struct device *dev,
 	u32 val = 0;
 
 	pm_runtime_get_sync(dev->parent);
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (drvdata->config.hw_powered)
 		val = readl_relaxed(drvdata->base + cti_attr->off);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	pm_runtime_put_sync(dev->parent);
 	return sysfs_emit(buf, "0x%x\n", val);
 }
@@ -202,10 +202,10 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev,
 		return -EINVAL;
 
 	pm_runtime_get_sync(dev->parent);
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (drvdata->config.hw_powered)
 		cti_write_single_reg(drvdata, cti_attr->off, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	pm_runtime_put_sync(dev->parent);
 	return size;
 }
@@ -264,7 +264,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf,
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if ((reg_offset >= 0) && cti_active(config)) {
 		CS_UNLOCK(drvdata->base);
 		val = readl_relaxed(drvdata->base + reg_offset);
@@ -274,7 +274,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf,
 	} else if (pcached_val) {
 		val = *pcached_val;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%#x\n", val);
 }
 
@@ -293,7 +293,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* local store */
 	if (pcached_val)
 		*pcached_val = (u32)val;
@@ -301,7 +301,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf,
 	/* write through if offset and enabled */
 	if ((reg_offset >= 0) && cti_active(config))
 		cti_write_single_reg(drvdata, reg_offset, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 
@@ -349,9 +349,9 @@ static ssize_t inout_sel_store(struct device *dev,
 	if (val > (CTIINOUTEN_MAX - 1))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.ctiinout_sel = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(inout_sel);
@@ -364,10 +364,10 @@ static ssize_t inen_show(struct device *dev,
 	int index;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = drvdata->config.ctiinout_sel;
 	val = drvdata->config.ctiinen[index];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%#lx\n", val);
 }
 
@@ -383,14 +383,14 @@ static ssize_t inen_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = config->ctiinout_sel;
 	config->ctiinen[index] = val;
 
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIINEN(index), val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(inen);
@@ -403,10 +403,10 @@ static ssize_t outen_show(struct device *dev,
 	int index;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = drvdata->config.ctiinout_sel;
 	val = drvdata->config.ctiouten[index];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%#lx\n", val);
 }
 
@@ -422,14 +422,14 @@ static ssize_t outen_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = config->ctiinout_sel;
 	config->ctiouten[index] = val;
 
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIOUTEN(index), val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(outen);
@@ -463,7 +463,7 @@ static ssize_t appclear_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* a 1'b1 in appclr clears down the same bit in appset*/
 	config->ctiappset &= ~val;
@@ -471,7 +471,7 @@ static ssize_t appclear_store(struct device *dev,
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(appclear);
@@ -487,12 +487,12 @@ static ssize_t apppulse_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIAPPPULSE, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(apppulse);
@@ -681,9 +681,9 @@ static ssize_t trig_filter_enable_show(struct device *dev,
 	u32 val;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = drvdata->config.trig_filter_enable;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%d\n", val);
 }
 
@@ -697,9 +697,9 @@ static ssize_t trig_filter_enable_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.trig_filter_enable = !!val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(trig_filter_enable);
@@ -728,7 +728,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev,
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* clear the CTI trigger / channel programming registers */
 	for (i = 0; i < config->nr_trig_max; i++) {
@@ -747,7 +747,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev,
 	if (cti_active(config))
 		cti_write_all_hw_regs(drvdata);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(chan_xtrigs_reset);
@@ -768,9 +768,9 @@ static ssize_t chan_xtrigs_sel_store(struct device *dev,
 	if (val > (drvdata->config.nr_ctm_channels - 1))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.xtrig_rchan_sel = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 
@@ -781,9 +781,9 @@ static ssize_t chan_xtrigs_sel_show(struct device *dev,
 	unsigned long val;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = drvdata->config.xtrig_rchan_sel;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return sprintf(buf, "%ld\n", val);
 }
@@ -838,12 +838,12 @@ static ssize_t print_chan_list(struct device *dev,
 	unsigned long inuse_bits = 0, chan_mask;
 
 	/* scan regs to get bitmap of channels in use. */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	for (i = 0; i < config->nr_trig_max; i++) {
 		inuse_bits |= config->ctiinen[i];
 		inuse_bits |= config->ctiouten[i];
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	/* inverse bits if printing free channels */
 	if (!inuse)
diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h
index cb9ee616d01f..16e310e7e9d4 100644
--- a/drivers/hwtracing/coresight/coresight-cti.h
+++ b/drivers/hwtracing/coresight/coresight-cti.h
@@ -175,7 +175,7 @@ struct cti_drvdata {
 	void __iomem *base;
 	struct coresight_device	*csdev;
 	struct cti_device ctidev;
-	spinlock_t spinlock;
+	raw_spinlock_t spinlock;
 	struct cti_config config;
 	struct list_head node;
 	void (*csdev_release)(struct device *dev);
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 03:49:38 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:38 +0000
Subject: [PATCH v2 5/9] coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <20241203114942.697188-6-yeoreum.yun@arm.com>

In coresight-etb10 drivers, etb_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since etb_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type etb_drvdata->spinlock in coresight-etb10 drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-etb10.c | 26 +++++++++----------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index aea9ac9c4bd0..7948597d483d 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -84,7 +84,7 @@ struct etb_drvdata {
 	struct clk		*atclk;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 	local_t			reading;
 	pid_t			pid;
 	u8			*buf;
@@ -145,7 +145,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
 	unsigned long flags;
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't messup with perf sessions. */
 	if (coresight_get_mode(csdev) == CS_MODE_PERF) {
@@ -163,7 +163,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
 
 	csdev->refcnt++;
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return ret;
 }
 
@@ -176,7 +176,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
 	struct perf_output_handle *handle = data;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* No need to continue if the component is already in used by sysFS. */
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
@@ -219,7 +219,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
 	}
 
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return ret;
 }
 
@@ -352,11 +352,11 @@ static int etb_disable(struct coresight_device *csdev)
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	unsigned long flags;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	csdev->refcnt--;
 	if (csdev->refcnt) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -366,7 +366,7 @@ static int etb_disable(struct coresight_device *csdev)
 	/* Dissociate from monitored process. */
 	drvdata->pid = -1;
 	coresight_set_mode(csdev, CS_MODE_DISABLED);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&csdev->dev, "ETB disabled\n");
 	return 0;
@@ -443,7 +443,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
 
 	capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't do anything if another tracer is using this sink */
 	if (csdev->refcnt != 1)
@@ -566,7 +566,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
 	__etb_enable_hw(drvdata);
 	CS_LOCK(drvdata->base);
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return to_read;
 }
@@ -587,13 +587,13 @@ static void etb_dump(struct etb_drvdata *drvdata)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
 		__etb_disable_hw(drvdata);
 		etb_dump_hw(drvdata);
 		__etb_enable_hw(drvdata);
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&drvdata->csdev->dev, "ETB dumped\n");
 }
@@ -746,7 +746,7 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
 	drvdata->base = base;
 	desc.access = CSDEV_ACCESS_IOMEM(base);
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	drvdata->buffer_depth = etb_get_buffer_depth(drvdata);
 
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 03:49:39 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:39 +0000
Subject: [PATCH v2 6/9] coresight-funnel: change funnel_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <20241203114942.697188-7-yeoreum.yun@arm.com>

In coresight-funnel drivers, cti_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since funnel_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type funnel_drvdata->spinlock in
coresight-funnel drivers, which can be called by
perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-funnel.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 33efe1acbef7..a566c8854327 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -47,7 +47,7 @@ struct funnel_drvdata {
 	struct clk		*pclk;
 	struct coresight_device	*csdev;
 	unsigned long		priority;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 };
 
 static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port)
@@ -85,7 +85,7 @@ static int funnel_enable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool first_enable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_read(&in->dest_refcnt) == 0) {
 		if (drvdata->base)
 			rc = dynamic_funnel_enable_hw(drvdata, in->dest_port);
@@ -94,7 +94,7 @@ static int funnel_enable(struct coresight_device *csdev,
 	}
 	if (!rc)
 		atomic_inc(&in->dest_refcnt);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (first_enable)
 		dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n",
@@ -129,13 +129,13 @@ static void funnel_disable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool last_disable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_dec_return(&in->dest_refcnt) == 0) {
 		if (drvdata->base)
 			dynamic_funnel_disable_hw(drvdata, in->dest_port);
 		last_disable = true;
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (last_disable)
 		dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n",
@@ -266,7 +266,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
 	}
 	dev->platform_data = pdata;
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	desc.type = CORESIGHT_DEV_TYPE_LINK;
 	desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG;
 	desc.ops = &funnel_cs_ops;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 03:49:41 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:41 +0000
Subject: [PATCH v2 8/9] coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <20241203114942.697188-9-yeoreum.yun@arm.com>

In coresight-tmc drivers, tmc_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since tmc_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type tmc_drvdata->spinlock in coresight-tmc drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-tmc-core.c  |  6 +--
 .../hwtracing/coresight/coresight-tmc-etf.c   | 48 +++++++++----------
 .../hwtracing/coresight/coresight-tmc-etr.c   | 40 ++++++++--------
 drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
 4 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index e9876252a789..4e9925300931 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -492,7 +492,7 @@ static int __tmc_probe(struct device *dev, struct resource *res)
 	drvdata->base = base;
 	desc.access = CSDEV_ACCESS_IOMEM(base);
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
 	drvdata->config_type = BMVAL(devid, 6, 7);
@@ -596,7 +596,7 @@ static void tmc_shutdown(struct amba_device *adev)
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = amba_get_drvdata(adev);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_DISABLED)
 		goto out;
@@ -610,7 +610,7 @@ static void tmc_shutdown(struct amba_device *adev)
 	 * the system is going down after this.
 	 */
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 }
 
 static void __tmc_remove(struct device *dev)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index d4f641cd9de6..fca8e9ffb3cf 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -182,9 +182,9 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 	 * If we don't have a buffer release the lock and allocate memory.
 	 * Otherwise keep the lock and move along.
 	 */
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (!drvdata->buf) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 		/* Allocating the memory here while outside of the spinlock */
 		buf = kzalloc(drvdata->size, GFP_KERNEL);
@@ -192,7 +192,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 			return -ENOMEM;
 
 		/* Let's try again */
-		spin_lock_irqsave(&drvdata->spinlock, flags);
+		raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	}
 
 	if (drvdata->reading) {
@@ -235,7 +235,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 		used = false;
 	}
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/* Free memory outside the spinlock if need be */
 	if (!used)
@@ -253,7 +253,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
 	struct perf_output_handle *handle = data;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	do {
 		ret = -EINVAL;
 		if (drvdata->reading)
@@ -296,7 +296,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
 			csdev->refcnt++;
 		}
 	} while (0);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -331,16 +331,16 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
 	csdev->refcnt--;
 	if (csdev->refcnt) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -351,7 +351,7 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
 	drvdata->pid = -1;
 	coresight_set_mode(csdev, CS_MODE_DISABLED);
 
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n");
 	return 0;
@@ -366,9 +366,9 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	bool first_enable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -381,7 +381,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
 	}
 	if (!ret)
 		csdev->refcnt++;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (first_enable)
 		dev_dbg(&csdev->dev, "TMC-ETF enabled\n");
@@ -396,9 +396,9 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	bool last_disable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return;
 	}
 
@@ -408,7 +408,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
 		coresight_set_mode(csdev, CS_MODE_DISABLED);
 		last_disable = true;
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (last_disable)
 		dev_dbg(&csdev->dev, "TMC-ETF disabled\n");
@@ -488,7 +488,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
 	if (WARN_ON_ONCE(coresight_get_mode(csdev) != CS_MODE_PERF))
 		return 0;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't do anything if another tracer is using this sink */
 	if (csdev->refcnt != 1)
@@ -585,7 +585,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
 	 */
 	CS_LOCK(drvdata->base);
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return to_read;
 }
@@ -623,7 +623,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
 			 drvdata->config_type != TMC_CONFIG_TYPE_ETF))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (drvdata->reading) {
 		ret = -EBUSY;
@@ -655,7 +655,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
 
 	drvdata->reading = true;
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -672,14 +672,14 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
 			 drvdata->config_type != TMC_CONFIG_TYPE_ETF))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Re-enable the TMC if need be */
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
 		/* There is no point in reading a TMC in HW FIFO mode */
 		mode = readl_relaxed(drvdata->base + TMC_MODE);
 		if (mode != TMC_MODE_CIRCULAR_BUFFER) {
-			spin_unlock_irqrestore(&drvdata->spinlock, flags);
+			raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 			return -EINVAL;
 		}
 		/*
@@ -693,7 +693,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
 		memset(drvdata->buf, 0, drvdata->size);
 		rc = __tmc_etb_enable_hw(drvdata);
 		if (rc) {
-			spin_unlock_irqrestore(&drvdata->spinlock, flags);
+			raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 			return rc;
 		}
 	} else {
@@ -706,7 +706,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
 	}
 
 	drvdata->reading = false;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/*
 	 * Free allocated memory outside of the spinlock.  There is no need
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..a0a90ce7333e 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1176,10 +1176,10 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 	 * buffer, provided the size matches. Any allocation has to be done
 	 * with the lock released.
 	 */
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	sysfs_buf = READ_ONCE(drvdata->sysfs_buf);
 	if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 		/* Allocate memory with the locks released */
 		free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata);
@@ -1187,7 +1187,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 			return new_buf;
 
 		/* Let's try again */
-		spin_lock_irqsave(&drvdata->spinlock, flags);
+		raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	}
 
 	if (drvdata->reading || coresight_get_mode(csdev) == CS_MODE_PERF) {
@@ -1206,7 +1206,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 	}
 
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/* Free memory outside the spinlock if need be */
 	if (free_buf)
@@ -1224,7 +1224,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 	if (IS_ERR(sysfs_buf))
 		return PTR_ERR(sysfs_buf);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/*
 	 * In sysFS mode we can have multiple writers per sink.  Since this
@@ -1243,7 +1243,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 	}
 
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (!ret)
 		dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
@@ -1562,17 +1562,17 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
 	struct etr_perf_buffer *etr_perf = config;
 	struct etr_buf *etr_buf = etr_perf->etr_buf;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't do anything if another tracer is using this sink */
 	if (csdev->refcnt != 1) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		goto out;
 	}
 
 	if (WARN_ON(drvdata->perf_buf != etr_buf)) {
 		lost = true;
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		goto out;
 	}
 
@@ -1582,7 +1582,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
 	tmc_sync_etr_buf(drvdata);
 
 	CS_LOCK(drvdata->base);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	lost = etr_buf->full;
 	offset = etr_buf->offset;
@@ -1651,7 +1651,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 	struct perf_output_handle *handle = data;
 	struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	 /* Don't use this sink if it is already claimed by sysFS */
 	if (coresight_get_mode(csdev) == CS_MODE_SYSFS) {
 		rc = -EBUSY;
@@ -1691,7 +1691,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 	}
 
 unlock_out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return rc;
 }
 
@@ -1713,16 +1713,16 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
 	csdev->refcnt--;
 	if (csdev->refcnt) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -1735,7 +1735,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
 	/* Reset perf specific data */
 	drvdata->perf_buf = NULL;
 
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&csdev->dev, "TMC-ETR disabled\n");
 	return 0;
@@ -1762,7 +1762,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
 		ret = -EBUSY;
 		goto out;
@@ -1784,7 +1784,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
 
 	drvdata->reading = true;
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -1798,7 +1798,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* RE-enable the TMC if need be */
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
@@ -1818,7 +1818,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
 	}
 
 	drvdata->reading = false;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/* Free allocated memory out side of the spinlock */
 	if (sysfs_buf)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 2671926be62a..60b395025bc4 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -195,7 +195,7 @@ struct tmc_drvdata {
 	void __iomem		*base;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
 	union {
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 03:49:42 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:42 +0000
Subject: [PATCH v2 9/9] coresight/ultrasoc: change cti_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <20241203114942.697188-10-yeoreum.yun@arm.com>

In ultrasoc-smb drivers, smb_drv_data->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since smb__drv_data->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type smb_drv_data->spinlock in ultrasoc-smb drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/ultrasoc-smb.c | 12 ++++++------
 drivers/hwtracing/coresight/ultrasoc-smb.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index dc3c9504dd7c..26cfc939e5bd 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -98,7 +98,7 @@ static int smb_open(struct inode *inode, struct file *file)
 	struct smb_drv_data *drvdata = container_of(file->private_data,
 					struct smb_drv_data, miscdev);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	if (drvdata->reading)
 		return -EBUSY;
@@ -152,7 +152,7 @@ static int smb_release(struct inode *inode, struct file *file)
 	struct smb_drv_data *drvdata = container_of(file->private_data,
 					struct smb_drv_data, miscdev);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 	drvdata->reading = false;
 
 	return 0;
@@ -245,7 +245,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 	int ret = 0;
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	/* Do nothing, the trace data is reading by other interface now */
 	if (drvdata->reading)
@@ -280,7 +280,7 @@ static int smb_disable(struct coresight_device *csdev)
 {
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	if (drvdata->reading)
 		return -EBUSY;
@@ -378,7 +378,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev,
 	if (!buf)
 		return 0;
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	/* Don't do anything if another tracer is using this sink. */
 	if (csdev->refcnt != 1)
@@ -563,7 +563,7 @@ static int smb_probe(struct platform_device *pdev)
 
 	smb_reset_buffer(drvdata);
 	platform_set_drvdata(pdev, drvdata);
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	drvdata->pid = -1;
 
 	ret = smb_register_sink(pdev, drvdata);
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing/coresight/ultrasoc-smb.h
index a91d39cfccb8..c4c111275627 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.h
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.h
@@ -115,7 +115,7 @@ struct smb_drv_data {
 	struct coresight_device	*csdev;
 	struct smb_data_buffer sdb;
 	struct miscdevice miscdev;
-	spinlock_t spinlock;
+	raw_spinlock_t spinlock;
 	bool reading;
 	pid_t pid;
 };
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 03:49:40 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:40 +0000
Subject: [PATCH v2 7/9] coresight-replicator: change replicator_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <20241203114942.697188-8-yeoreum.yun@arm.com>

In coresight-replicator drivers, replicator_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since replicator_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type replicator_drvdata->spinlock in
coresight-replicator drivers, which can be called
by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-replicator.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 0fba87de6d1a..7d36fe2176cc 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -41,7 +41,7 @@ struct replicator_drvdata {
 	struct clk		*atclk;
 	struct clk		*pclk;
 	struct coresight_device	*csdev;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 	bool			check_idfilter_val;
 };
 
@@ -125,7 +125,7 @@ static int replicator_enable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool first_enable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_read(&out->src_refcnt) == 0) {
 		if (drvdata->base)
 			rc = dynamic_replicator_enable(drvdata, in->dest_port,
@@ -135,7 +135,7 @@ static int replicator_enable(struct coresight_device *csdev,
 	}
 	if (!rc)
 		atomic_inc(&out->src_refcnt);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (first_enable)
 		dev_dbg(&csdev->dev, "REPLICATOR enabled\n");
@@ -179,14 +179,14 @@ static void replicator_disable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool last_disable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_dec_return(&out->src_refcnt) == 0) {
 		if (drvdata->base)
 			dynamic_replicator_disable(drvdata, in->dest_port,
 						   out->src_port);
 		last_disable = true;
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (last_disable)
 		dev_dbg(&csdev->dev, "REPLICATOR disabled\n");
@@ -277,7 +277,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
 	}
 	dev->platform_data = pdata;
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	desc.type = CORESIGHT_DEV_TYPE_LINK;
 	desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT;
 	desc.ops = &replicator_cs_ops;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 03:49:33 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:33 +0000
Subject: [PATCH v2 0/9] coresight: change some driver' spinlock type to raw_spinlock_t
Message-ID: <20241203114942.697188-1-yeoreum.yun@arm.com>

In some coresight drivers, drvdata->spinlock can be held during __schedule()
by perf_event_task_sched_out()/in().

Since drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this,change type drvdata->spinlock in some coresight drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>

v1 to v2:
    - seperate patchsets to change locktype and apply gurad API.

Levi Yun (9):
  coresight: change coresight_device lock type to raw_spinlock_t
  coresight-etm4x: change etmv4_drvdata spinlock type to raw_spinlock_t
  coresight: change coresight_trace_id_map's lock type to raw_spinlock_t
  coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
  coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
  coresight-funnel: change funnel_drvdata spinlock's type to
    raw_spinlock_t
  coresight-replicator: change replicator_drvdata spinlock's type to
    raw_spinlock_t
  coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
  coresight/ultrasoc: change cti_drvdata spinlock's type to
    raw_spinlock_t

 .../hwtracing/coresight/coresight-config.c    |  21 +-
 .../hwtracing/coresight/coresight-config.h    |   2 +-
 drivers/hwtracing/coresight/coresight-core.c  |   2 +-
 .../hwtracing/coresight/coresight-cti-core.c  |  65 +-
 .../hwtracing/coresight/coresight-cti-sysfs.c | 135 +++--
 drivers/hwtracing/coresight/coresight-cti.h   |   2 +-
 drivers/hwtracing/coresight/coresight-etb10.c |  62 +-
 .../coresight/coresight-etm4x-core.c          |  71 ++-
 .../coresight/coresight-etm4x-sysfs.c         | 566 +++++++++---------
 drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
 .../hwtracing/coresight/coresight-funnel.c    |  34 +-
 .../coresight/coresight-replicator.c          |  36 +-
 .../hwtracing/coresight/coresight-syscfg.c    |  75 ++-
 .../hwtracing/coresight/coresight-tmc-core.c  |   9 +-
 .../hwtracing/coresight/coresight-tmc-etf.c   | 195 +++---
 .../hwtracing/coresight/coresight-tmc-etr.c   | 199 +++---
 drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
 .../hwtracing/coresight/coresight-trace-id.c  |  93 ++-
 drivers/hwtracing/coresight/ultrasoc-smb.c    |  12 +-
 drivers/hwtracing/coresight/ultrasoc-smb.h    |   2 +-
 include/linux/coresight.h                     |   4 +-
 21 files changed, 751 insertions(+), 838 deletions(-)

--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 03:49:34 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:34 +0000
Subject: [PATCH v2 1/9] coresight: change coresight_device lock type to  raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <20241203114942.697188-2-yeoreum.yun@arm.com>

coresight_device->cscfg_csdev_lock can be held during __schedule()
by perf_event_task_sched_out()/in().

Since coresight->cscfg_csdev_lock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type of coresight_device->cscfg_csdev_lock
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-syscfg.c    | 26 +++++++++----------
 include/linux/coresight.h                     |  2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 11138a9762b0..a70c1454b410 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -89,9 +89,9 @@ static int cscfg_add_csdev_cfg(struct coresight_device *csdev,
 	}
 	/* if matched features, add config to device.*/
 	if (config_csdev) {
-		spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+		raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 		list_add(&config_csdev->node, &csdev->config_csdev_list);
-		spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+		raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 	}
 
 	return 0;
@@ -194,9 +194,9 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev,
 
 	/* add to internal csdev feature list & initialise using reset call */
 	cscfg_reset_feat(feat_csdev);
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	list_add(&feat_csdev->node, &csdev->feature_csdev_list);
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	return 0;
 }
@@ -765,7 +765,7 @@ static int cscfg_list_add_csdev(struct coresight_device *csdev,
 
 	INIT_LIST_HEAD(&csdev->feature_csdev_list);
 	INIT_LIST_HEAD(&csdev->config_csdev_list);
-	spin_lock_init(&csdev->cscfg_csdev_lock);
+	raw_spin_lock_init(&csdev->cscfg_csdev_lock);
 
 	return 0;
 }
@@ -855,7 +855,7 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
 	struct cscfg_feature_csdev *feat_csdev;
 	unsigned long flags;
 
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	if (list_empty(&csdev->feature_csdev_list))
 		goto unlock_exit;
 
@@ -863,7 +863,7 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
 		cscfg_reset_feat(feat_csdev);
 
 unlock_exit:
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 }
 EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
 
@@ -1059,7 +1059,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 	 * Look for matching configuration - set the active configuration
 	 * context if found.
 	 */
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
 		config_desc = config_csdev_item->config_desc;
 		if ((atomic_read(&config_desc->active_cnt)) &&
@@ -1069,7 +1069,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 			break;
 		}
 	}
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	/*
 	 * If found, attempt to enable
@@ -1090,12 +1090,12 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 			 *
 			 * Set enabled if OK, err if not.
 			 */
-			spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+			raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 			if (csdev->active_cscfg_ctxt)
 				config_csdev_active->enabled = true;
 			else
 				err = -EBUSY;
-			spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+			raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 		}
 	}
 	return err;
@@ -1124,7 +1124,7 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
 	 * If it was not enabled, we have no work to do, otherwise mark as disabled.
 	 * Clear the active config pointer.
 	 */
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	config_csdev = (struct cscfg_config_csdev *)csdev->active_cscfg_ctxt;
 	if (config_csdev) {
 		if (!config_csdev->enabled)
@@ -1133,7 +1133,7 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
 			config_csdev->enabled = false;
 	}
 	csdev->active_cscfg_ctxt = NULL;
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	/* true if there was an enabled active config */
 	if (config_csdev)
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index c13342594278..924b58c343b3 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -296,7 +296,7 @@ struct coresight_device {
 	/* system configuration and feature lists */
 	struct list_head feature_csdev_list;
 	struct list_head config_csdev_list;
-	spinlock_t cscfg_csdev_lock;
+	raw_spinlock_t cscfg_csdev_lock;
 	void *active_cscfg_ctxt;
 };
 
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 03:49:35 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:35 +0000
Subject: [PATCH v2 2/9] coresight-etm4x: change etmv4_drvdata spinlock type to raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <20241203114942.697188-3-yeoreum.yun@arm.com>

In coresight-etm4x drivers, etmv4_drvdata->spinlock can be held during
__schedule() by perf_event_task_sched_out()/in().

Since etmv4_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type etmv4_drvdata->spinlock
in coresight-etm4x drivers, which can be called
by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-config.c    |   8 +-
 .../hwtracing/coresight/coresight-config.h    |   2 +-
 .../coresight/coresight-etm4x-core.c          |  10 +-
 .../coresight/coresight-etm4x-sysfs.c         | 250 +++++++++---------
 drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
 5 files changed, 136 insertions(+), 136 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c
index 4723bf7402a2..4f72ae71b696 100644
--- a/drivers/hwtracing/coresight/coresight-config.c
+++ b/drivers/hwtracing/coresight/coresight-config.c
@@ -76,10 +76,10 @@ static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat_csdev)
 	unsigned long flags;
 	int i;
 
-	spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
+	raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
 	for (i = 0; i < feat_csdev->nr_regs; i++)
 		cscfg_set_reg(&feat_csdev->regs_csdev[i]);
-	spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+	raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
 	dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
 		feat_csdev->feat_desc->name, "set on enable");
 	return 0;
@@ -91,10 +91,10 @@ static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat_csdev)
 	unsigned long flags;
 	int i;
 
-	spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
+	raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
 	for (i = 0; i < feat_csdev->nr_regs; i++)
 		cscfg_save_reg(&feat_csdev->regs_csdev[i]);
-	spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+	raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
 	dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
 		feat_csdev->feat_desc->name, "save on disable");
 }
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 6ba013975741..b9ebc9fcfb7f 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -206,7 +206,7 @@ struct cscfg_feature_csdev {
 	const struct cscfg_feature_desc *feat_desc;
 	struct coresight_device *csdev;
 	struct list_head node;
-	spinlock_t *drv_spinlock;
+	raw_spinlock_t *drv_spinlock;
 	int nr_params;
 	struct cscfg_parameter_csdev *params_csdev;
 	int nr_regs;
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index dd8c74f893db..8cf1d4090533 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -807,7 +807,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 			return ret;
 	}
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* sysfs needs to read and allocate a trace ID */
 	ret = etm4_read_alloc_trace_id(drvdata);
@@ -830,7 +830,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 		etm4_release_trace_id(drvdata);
 
 unlock_sysfs_enable:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	if (!ret)
 		dev_dbg(&csdev->dev, "ETM tracing enabled\n");
@@ -977,7 +977,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	 * DYING hotplug callback is serviced by the ETM driver.
 	 */
 	cpus_read_lock();
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/*
 	 * Executing etm4_disable_hw on the cpu whose ETM is being disabled
@@ -985,7 +985,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	 */
 	smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	cpus_read_unlock();
 
 	/*
@@ -2125,7 +2125,7 @@ static int etm4_probe(struct device *dev)
 			return -ENOMEM;
 	}
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	drvdata->cpu = coresight_get_cpu(dev);
 	if (drvdata->cpu < 0)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a9f19629f3f8..11e865b8e824 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -174,7 +174,7 @@ static ssize_t reset_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (val)
 		config->mode = 0x0;
 
@@ -266,7 +266,7 @@ static ssize_t reset_store(struct device *dev,
 	config->vmid_mask0 = 0x0;
 	config->vmid_mask1 = 0x0;
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	/* for sysfs - only release trace id when resetting */
 	etm4_release_trace_id(drvdata);
@@ -300,7 +300,7 @@ static ssize_t mode_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->mode = val & ETMv4_MODE_ALL;
 
 	if (drvdata->instrp0 == true) {
@@ -437,7 +437,7 @@ static ssize_t mode_store(struct device *dev,
 	if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
 		etm4_config_trace_mode(config);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -466,14 +466,14 @@ static ssize_t pe_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (val > drvdata->nr_pe) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EINVAL;
 	}
 
 	config->pe_sel = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(pe);
@@ -501,7 +501,7 @@ static ssize_t event_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	switch (drvdata->nr_event) {
 	case 0x0:
 		/* EVENT0, bits[7:0] */
@@ -522,7 +522,7 @@ static ssize_t event_store(struct device *dev,
 	default:
 		break;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(event);
@@ -550,7 +550,7 @@ static ssize_t event_instren_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* start by clearing all instruction event enable bits */
 	config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;
 	switch (drvdata->nr_event) {
@@ -578,7 +578,7 @@ static ssize_t event_instren_store(struct device *dev,
 	default:
 		break;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(event_instren);
@@ -739,11 +739,11 @@ static ssize_t event_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val &= TRCVICTLR_EVENT_MASK >> __bf_shf(TRCVICTLR_EVENT_MASK);
 	config->vinst_ctrl &= ~TRCVICTLR_EVENT_MASK;
 	config->vinst_ctrl |= FIELD_PREP(TRCVICTLR_EVENT_MASK, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(event_vinst);
@@ -771,13 +771,13 @@ static ssize_t s_exlevel_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* clear all EXLEVEL_S bits  */
 	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;
 	/* enable instruction tracing for corresponding exception level */
 	val &= drvdata->s_ex_level;
 	config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_S_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(s_exlevel_vinst);
@@ -806,13 +806,13 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* clear EXLEVEL_NS bits  */
 	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;
 	/* enable instruction tracing for corresponding exception level */
 	val &= drvdata->ns_ex_level;
 	config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_NS_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ns_exlevel_vinst);
@@ -846,9 +846,9 @@ static ssize_t addr_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->addr_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_idx);
@@ -862,7 +862,7 @@ static ssize_t addr_instdatatype_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	val = FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]);
 	len = scnprintf(buf, PAGE_SIZE, "%s\n",
@@ -870,7 +870,7 @@ static ssize_t addr_instdatatype_show(struct device *dev,
 			(val == TRCACATRn_TYPE_DATA_LOAD_ADDR ? "data_load" :
 			(val == TRCACATRn_TYPE_DATA_STORE_ADDR ? "data_store" :
 			"data_load_store")));
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return len;
 }
 
@@ -888,13 +888,13 @@ static ssize_t addr_instdatatype_store(struct device *dev,
 	if (sscanf(buf, "%s", str) != 1)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!strcmp(str, "instr"))
 		/* TYPE, bits[1:0] */
 		config->addr_acc[idx] &= ~TRCACATRn_TYPE_MASK;
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_instdatatype);
@@ -909,14 +909,14 @@ static ssize_t addr_single_show(struct device *dev,
 	struct etmv4_config *config = &drvdata->config;
 
 	idx = config->addr_idx;
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 	val = (unsigned long)config->addr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -932,17 +932,17 @@ static ssize_t addr_single_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	config->addr_val[idx] = (u64)val;
 	config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_single);
@@ -956,23 +956,23 @@ static ssize_t addr_range_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 	if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
 	      (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	val1 = (unsigned long)config->addr_val[idx];
 	val2 = (unsigned long)config->addr_val[idx + 1];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
 }
 
@@ -995,10 +995,10 @@ static ssize_t addr_range_store(struct device *dev,
 	if (val1 > val2)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
@@ -1006,7 +1006,7 @@ static ssize_t addr_range_store(struct device *dev,
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
 	      (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
@@ -1023,7 +1023,7 @@ static ssize_t addr_range_store(struct device *dev,
 		exclude = config->mode & ETM_MODE_EXCLUDE;
 	etm4_set_mode_exclude(drvdata, exclude ? true : false);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_range);
@@ -1037,17 +1037,17 @@ static ssize_t addr_start_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	val = (unsigned long)config->addr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1063,22 +1063,22 @@ static ssize_t addr_start_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!drvdata->nr_addr_cmp) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EINVAL;
 	}
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	config->addr_val[idx] = (u64)val;
 	config->addr_type[idx] = ETM_ADDR_TYPE_START;
 	config->vissctlr |= BIT(idx);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_start);
@@ -1092,17 +1092,17 @@ static ssize_t addr_stop_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	val = (unsigned long)config->addr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1118,22 +1118,22 @@ static ssize_t addr_stop_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!drvdata->nr_addr_cmp) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EINVAL;
 	}
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	       config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	config->addr_val[idx] = (u64)val;
 	config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
 	config->vissctlr |= BIT(idx + 16);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_stop);
@@ -1147,14 +1147,14 @@ static ssize_t addr_ctxtype_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* CONTEXTTYPE, bits[3:2] */
 	val = FIELD_GET(TRCACATRn_CONTEXTTYPE_MASK, config->addr_acc[idx]);
 	len = scnprintf(buf, PAGE_SIZE, "%s\n", val == ETM_CTX_NONE ? "none" :
 			(val == ETM_CTX_CTXID ? "ctxid" :
 			(val == ETM_CTX_VMID ? "vmid" : "all")));
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return len;
 }
 
@@ -1172,7 +1172,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
 	if (sscanf(buf, "%s", str) != 1)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!strcmp(str, "none"))
 		/* start by clearing context type bits */
@@ -1199,7 +1199,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
 		if (drvdata->numvmidc)
 			config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_ctxtype);
@@ -1213,11 +1213,11 @@ static ssize_t addr_context_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* context ID comparator bits[6:4] */
 	val = FIELD_GET(TRCACATRn_CONTEXT_MASK, config->addr_acc[idx]);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1238,12 +1238,12 @@ static ssize_t addr_context_store(struct device *dev,
 		     drvdata->numcidc : drvdata->numvmidc))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* clear context ID comparator bits[6:4] */
 	config->addr_acc[idx] &= ~TRCACATRn_CONTEXT_MASK;
 	config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_CONTEXT_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_context);
@@ -1257,10 +1257,10 @@ static ssize_t addr_exlevel_s_ns_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	val = FIELD_GET(TRCACATRn_EXLEVEL_MASK, config->addr_acc[idx]);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1279,12 +1279,12 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
 	if (val & ~(TRCACATRn_EXLEVEL_MASK >> __bf_shf(TRCACATRn_EXLEVEL_MASK)))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8], bit[15] is res0 */
 	config->addr_acc[idx] &= ~TRCACATRn_EXLEVEL_MASK;
 	config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_EXLEVEL_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_exlevel_s_ns);
@@ -1307,7 +1307,7 @@ static ssize_t addr_cmp_view_show(struct device *dev,
 	int size = 0;
 	bool exclude = false;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	addr_v = config->addr_val[idx];
 	addr_ctrl = config->addr_acc[idx];
@@ -1322,7 +1322,7 @@ static ssize_t addr_cmp_view_show(struct device *dev,
 		}
 		exclude = config->viiectlr & BIT(idx / 2 + 16);
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	if (addr_type) {
 		size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] %s %#lx", idx,
 				 addr_type_names[addr_type], addr_v);
@@ -1366,9 +1366,9 @@ static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
 	if (!drvdata->nr_pe_cmp)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->vipcssctlr = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vinst_pe_cmp_start_stop);
@@ -1402,9 +1402,9 @@ static ssize_t seq_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->seq_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(seq_idx);
@@ -1448,10 +1448,10 @@ static ssize_t seq_event_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->seq_idx;
 	val = config->seq_ctrl[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1467,11 +1467,11 @@ static ssize_t seq_event_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->seq_idx;
 	/* Seq control has two masks B[15:8] F[7:0] */
 	config->seq_ctrl[idx] = val & 0xFFFF;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(seq_event);
@@ -1535,9 +1535,9 @@ static ssize_t cntr_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->cntr_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntr_idx);
@@ -1551,10 +1551,10 @@ static ssize_t cntrldvr_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	val = config->cntrldvr[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1572,10 +1572,10 @@ static ssize_t cntrldvr_store(struct device *dev,
 	if (val > ETM_CNTR_MAX_VAL)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntrldvr[idx] = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntrldvr);
@@ -1589,10 +1589,10 @@ static ssize_t cntr_val_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	val = config->cntr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1610,10 +1610,10 @@ static ssize_t cntr_val_store(struct device *dev,
 	if (val > ETM_CNTR_MAX_VAL)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntr_val[idx] = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntr_val);
@@ -1627,10 +1627,10 @@ static ssize_t cntr_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	val = config->cntr_ctrl[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1646,10 +1646,10 @@ static ssize_t cntr_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntr_ctrl[idx] = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntr_ctrl);
@@ -1687,9 +1687,9 @@ static ssize_t res_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->res_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(res_idx);
@@ -1703,10 +1703,10 @@ static ssize_t res_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->res_idx;
 	val = config->res_ctrl[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1722,7 +1722,7 @@ static ssize_t res_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->res_idx;
 	/* For odd idx pair inversal bit is RES0 */
 	if (idx % 2 != 0)
@@ -1732,7 +1732,7 @@ static ssize_t res_ctrl_store(struct device *dev,
 				       TRCRSCTLRn_INV |
 				       TRCRSCTLRn_GROUP_MASK |
 				       TRCRSCTLRn_SELECT_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(res_ctrl);
@@ -1761,9 +1761,9 @@ static ssize_t sshot_idx_store(struct device *dev,
 	if (val >= drvdata->nr_ss_cmp)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->ss_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(sshot_idx);
@@ -1776,9 +1776,9 @@ static ssize_t sshot_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = config->ss_ctrl[config->ss_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1794,12 +1794,12 @@ static ssize_t sshot_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ss_idx;
 	config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
 	/* must clear bit 31 in related status register on programming */
 	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(sshot_ctrl);
@@ -1811,9 +1811,9 @@ static ssize_t sshot_status_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = config->ss_status[config->ss_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 static DEVICE_ATTR_RO(sshot_status);
@@ -1826,9 +1826,9 @@ static ssize_t sshot_pe_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = config->ss_pe_cmp[config->ss_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1844,12 +1844,12 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ss_idx;
 	config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
 	/* must clear bit 31 in related status register on programming */
 	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(sshot_pe_ctrl);
@@ -1883,9 +1883,9 @@ static ssize_t ctxid_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->ctxid_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_idx);
@@ -1906,10 +1906,10 @@ static ssize_t ctxid_pid_show(struct device *dev,
 	if (task_active_pid_ns(current) != &init_pid_ns)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ctxid_idx;
 	val = (unsigned long)config->ctxid_pid[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1944,10 +1944,10 @@ static ssize_t ctxid_pid_store(struct device *dev,
 	if (kstrtoul(buf, 16, &pid))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ctxid_idx;
 	config->ctxid_pid[idx] = (u64)pid;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_pid);
@@ -1967,10 +1967,10 @@ static ssize_t ctxid_masks_show(struct device *dev,
 	if (task_active_pid_ns(current) != &init_pid_ns)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val1 = config->ctxid_mask0;
 	val2 = config->ctxid_mask1;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
 }
 
@@ -2003,7 +2003,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
 	if ((drvdata->numcidc > 4) && (nr_inputs != 2))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/*
 	 * each byte[0..3] controls mask value applied to ctxid
 	 * comparator[0..3]
@@ -2075,7 +2075,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
 			mask >>= 0x8;
 	}
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_masks);
@@ -2109,9 +2109,9 @@ static ssize_t vmid_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->vmid_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vmid_idx);
@@ -2131,9 +2131,9 @@ static ssize_t vmid_val_show(struct device *dev,
 	if (!task_is_in_init_pid_ns(current))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = (unsigned long)config->vmid_val[config->vmid_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -2161,9 +2161,9 @@ static ssize_t vmid_val_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->vmid_val[config->vmid_idx] = (u64)val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vmid_val);
@@ -2182,10 +2182,10 @@ static ssize_t vmid_masks_show(struct device *dev,
 	if (!task_is_in_init_pid_ns(current))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val1 = config->vmid_mask0;
 	val2 = config->vmid_mask1;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
 }
 
@@ -2217,7 +2217,7 @@ static ssize_t vmid_masks_store(struct device *dev,
 	if ((drvdata->numvmidc > 4) && (nr_inputs != 2))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/*
 	 * each byte[0..3] controls mask value applied to vmid
@@ -2290,7 +2290,7 @@ static ssize_t vmid_masks_store(struct device *dev,
 		else
 			mask >>= 0x8;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vmid_masks);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 9e9165f62e81..366f8f23a3e5 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -989,7 +989,7 @@ struct etmv4_drvdata {
 	struct clk			*pclk;
 	void __iomem			*base;
 	struct coresight_device		*csdev;
-	spinlock_t			spinlock;
+	raw_spinlock_t			spinlock;
 	int				cpu;
 	u8				arch;
 	u8				nr_pe;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 03:49:36 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 11:49:36 +0000
Subject: [PATCH v2 3/9] coresight: change coresight_trace_id_map's lock type to  raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <20241203114942.697188-4-yeoreum.yun@arm.com>

coresight_trace_id_map->lock can be acquired while coresight devices'
drvdata_lock.

But the drvdata_lock can be raw_spinlock_t (i.e) coresight-etm4x.

To address this, change type of coresight_trace_id_map->lock to
raw_spinlock_t

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-core.c  |  2 +-
 .../hwtracing/coresight/coresight-trace-id.c  | 20 +++++++++----------
 include/linux/coresight.h                     |  2 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index ea38ecf26fcb..cc2d87b2f248 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1164,7 +1164,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
 
 	if (csdev->type == CORESIGHT_DEV_TYPE_SINK ||
 	    csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) {
-		spin_lock_init(&csdev->perf_sink_id_map.lock);
+		raw_spin_lock_init(&csdev->perf_sink_id_map.lock);
 		csdev->perf_sink_id_map.cpu_map = alloc_percpu(atomic_t);
 		if (!csdev->perf_sink_id_map.cpu_map) {
 			kfree(csdev);
diff --git a/drivers/hwtracing/coresight/coresight-trace-id.c b/drivers/hwtracing/coresight/coresight-trace-id.c
index d98e12cb30ec..c3a2cbc7a3d8 100644
--- a/drivers/hwtracing/coresight/coresight-trace-id.c
+++ b/drivers/hwtracing/coresight/coresight-trace-id.c
@@ -121,11 +121,11 @@ static void coresight_trace_id_release_all(struct coresight_trace_id_map *id_map
 	unsigned long flags;
 	int cpu;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 	bitmap_zero(id_map->used_ids, CORESIGHT_TRACE_IDS_MAX);
 	for_each_possible_cpu(cpu)
 		atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), 0);
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 	DUMP_ID_MAP(id_map);
 }
 
@@ -134,7 +134,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map
 	unsigned long flags;
 	int id;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 
 	/* check for existing allocation for this CPU */
 	id = _coresight_trace_id_read_cpu_id(cpu, id_map);
@@ -161,7 +161,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map
 	atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), id);
 
 get_cpu_id_out_unlock:
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 
 	DUMP_ID_CPU(cpu, id);
 	DUMP_ID_MAP(id_map);
@@ -178,12 +178,12 @@ static void _coresight_trace_id_put_cpu_id(int cpu, struct coresight_trace_id_ma
 	if (!id)
 		return;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 
 	coresight_trace_id_free(id, id_map);
 	atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), 0);
 
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 	DUMP_ID_CPU(cpu, id);
 	DUMP_ID_MAP(id_map);
 }
@@ -193,10 +193,10 @@ static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *i
 	unsigned long flags;
 	int id;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 	/* prefer odd IDs for system components to avoid legacy CPU IDS */
 	id = coresight_trace_id_alloc_new_id(id_map, 0, true);
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 
 	DUMP_ID(id);
 	DUMP_ID_MAP(id_map);
@@ -207,9 +207,9 @@ static void coresight_trace_id_map_put_system_id(struct coresight_trace_id_map *
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 	coresight_trace_id_free(id, id_map);
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 
 	DUMP_ID(id);
 	DUMP_ID_MAP(id_map);
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 924b58c343b3..6446ca1f09d8 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -233,7 +233,7 @@ struct coresight_trace_id_map {
 	DECLARE_BITMAP(used_ids, CORESIGHT_TRACE_IDS_MAX);
 	atomic_t __percpu *cpu_map;
 	atomic_t perf_cs_etm_session_active;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 };
 
 /**
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From Dave.Martin at arm.com  Tue Dec  3 03:56:27 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 3 Dec 2024 11:56:27 +0000
Subject: [PATCH] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <20241203100322.1626805-1-kevin.brodsky@arm.com>
References: <20241203100322.1626805-1-kevin.brodsky@arm.com>
Message-ID: <Z07x69L6Mssncg/7@e133380.arm.com>

On Tue, Dec 03, 2024 at 10:03:22AM +0000, Kevin Brodsky wrote:
> Commit eaf62ce1563b ("arm64/signal: Set up and restore the GCS
> context for signal handlers") introduced a potential failure point
> at the end of setup_return(). This is unfortunate as it is too late
> to deliver a SIGSEGV: if that SIGSEGV is handled, the subsequent
> sigreturn will end up returning to the original handler, which is
> not the intention (since we failed to deliver that signal).
> 
> Make sure this does not happen by calling gcs_signal_entry()
> at the very beginning of setup_return(), and add a comment just
> after to discourage error cases being introduced from that point
> onwards.
> 
> While at it, also take care of copy_siginfo_to_user(): since it may
> fail, we shouldn't be calling it after setup_return() either. Call
> it before setup_return() instead, and move the setting of X1/X2
> inside setup_return() where it belongs (after the "point of no
> failure").
> 
> Background: the first part of setup_rt_frame(), including
> setup_sigframe(), has no impact on the execution of the interrupted
> thread. The signal frame is written to the stack, but the stack
> pointer remains unchanged. Failure at this stage can be recovered by
> a SIGSEGV handler, and sigreturn will restore the original context,
> at the point where the original signal occurred. On the other hand,
> once setup_return() has updated registers including SP, the thread's
> control flow has been modified and we must deliver the original
> signal.
> 
> Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")
> Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
> ---
> Cc: broonie at kernel.org
> Cc: catalin.marinas at arm.com
> Cc: Dave.Martin at arm.com
> Cc: will at kernel.org
> ---
>  arch/arm64/kernel/signal.c | 43 +++++++++++++++++++++++++-------------
>  1 file changed, 28 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 14ac6fdb872b..0adaa165b876 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -1462,10 +1462,33 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
>  			 struct rt_sigframe_user_layout *user, int usig)
>  {
>  	__sigrestore_t sigtramp;
> +	int err;
> +
> +	if (ksig->ka.sa.sa_flags & SA_RESTORER)
> +		sigtramp = ksig->ka.sa.sa_restorer;
> +	else
> +		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
> +
> +	err = gcs_signal_entry(sigtramp, ksig);
> +	if (err)
> +		return err;
> +
> +	/*
> +	 * We must not fail from this point onwards. We are going to update
> +	 * registers, including SP, in order to invoke the signal handler. If
> +	 * we failed and attempted to deliver a nested SIGSEGV to a handler
> +	 * after that point, the subsequent sigreturn would end up restoring
> +	 * the (partial) state for the original signal handler.
> +	 */

The same is true at the call site of this function; could problems
creep back in there?

>  
>  	regs->regs[0] = usig;
> +	if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
> +		regs->regs[1] = (unsigned long)&user->sigframe->info;
> +		regs->regs[2] = (unsigned long)&user->sigframe->uc;

Nit: This looks like it should work, but it's not really anything to do
with setting up how the handler returns (we're in setup_return() here).

Would it be cleaner just to stage the destructive state changes
somewhere and apply them right at the end (as with POR_EL0)?

> +	}
>  	regs->sp = (unsigned long)user->sigframe;
>  	regs->regs[29] = (unsigned long)&user->next_frame->fp;
> +	regs->regs[30] = (unsigned long)sigtramp;
>  	regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
>  
>  	/*
> @@ -1506,14 +1529,7 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
>  		sme_smstop();
>  	}
>  
> -	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);
> +	return 0;
>  }
>  
>  static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
> @@ -1537,14 +1553,11 @@ 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, &ua_state);
> -	if (err == 0) {
> +	if (ksig->ka.sa.sa_flags & SA_SIGINFO)
> +		err |= copy_siginfo_to_user(&frame->info, &ksig->info);
> +
> +	if (err == 0)
>  		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;
> -			regs->regs[2] = (unsigned long)&frame->uc;
> -		}
> -	}
>  
>  	if (err == 0)
>  		set_handler_user_access_state();

[...]

Cheers
---Dave


From abel.vesa at linaro.org  Tue Dec  3 04:03:05 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Tue, 3 Dec 2024 14:03:05 +0200
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint readery
In-Reply-To: <Z07r3Upr50vLluyn@linaro.org>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com>
 <Z07r3Upr50vLluyn@linaro.org>
Message-ID: <Z07zeVJU3Y1GiSLL@linaro.org>

On 24-12-03 12:30:37, Stephan Gerhold wrote:
> On Tue, Dec 03, 2024 at 11:20:48AM +0100, Johan Hovold wrote:
> > [ +CC: Krishna, Thinh and the USB list ]
> > 
> > On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
> > > The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
> > > multiport controller on eUSB6. All other ports (including USB super-speed
> > > pins) are unused.
> > > 
> > > Set it up in the device tree together with the NXP PTN3222 repeater.
> > > 
> > > Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> > > ---
> > >  arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 48 +++++++++++++++++++++++++++++++
> > >  1 file changed, 48 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > > index 39f9d9cdc10d..44942931c18f 100644
> > > --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > > +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > > @@ -735,6 +735,26 @@ keyboard at 3a {
> > >  	};
> > >  };
> > >  
> > > +&i2c5 {
> > > +	clock-frequency = <400000>;
> > > +
> > > +	status = "okay";
> > > +
> > > +	eusb6_repeater: redriver at 4f {
> > > +		compatible = "nxp,ptn3222";
> > > +		reg = <0x4f>;
> > 
> > The driver does not currently check that there's actually anything at
> > this address. Did you verify that this is the correct address? 
> > 
> > (Abel is adding a check to the driver as we speak to catch any such
> > mistakes going forward).
> > 
> 
> Yes, I verified this using
> https://git.codelinaro.org/stephan.gerhold/linux/-/commit/45d5add498612387f88270ca944ee16e2236fddd
> 
> (I sent this to Abel back then, so I'm surprised he didn't run that :-))

I don't remember seeing this commit back then. Maybe I didn't look
careful enough. Sorry.

Since you already did the work, can you send that on the list?

So if you remember, back then I hunted down all of these with i2cget on
my t14s (it has 3 such repeaters, unlike CRD).

> 
> > > +		#phy-cells = <0>;
> > 
> > nit: I'd put provider properties like this one last.
> > 
> > > +		vdd3v3-supply = <&vreg_l13b_3p0>;
> > > +		vdd1v8-supply = <&vreg_l4b_1p8>;
> > 
> > Sort by supply name?
> > 
> 
> Ack.
> 
> > > +		reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>;
> > > +
> > > +		pinctrl-0 = <&eusb6_reset_n>;
> > > +		pinctrl-names = "default";
> > > +	};
> > > +};
> > > +
> > >  &i2c8 {
> > >  	clock-frequency = <400000>;
> > >  
> > > @@ -1047,6 +1067,14 @@ edp_reg_en: edp-reg-en-state {
> > >  		bias-disable;
> > >  	};
> > >  
> > > +	eusb6_reset_n: eusb6-reset-n-state {
> > > +		pins = "gpio184";
> > > +		function = "gpio";
> > > +		drive-strength = <2>;
> > > +		bias-disable;
> > > +		output-low;
> > 
> > I don't think the pin config should assert reset, that should be up to
> > the driver to control.
> > 
> 
> I can drop it I guess, but pinctrl is applied before the driver takes
> control of the GPIO. This means if the GPIO happens to be in input mode
> before the driver loads (with pull up or pull down), then we would
> briefly leave it floating when applying the bias-disable.
> 
> Or I guess we could drop the bias-disable, since it shouldn't be
> relevant for a pin we keep in output mode all the time?
> 
> > > +	};
> > > +
> > >  	hall_int_n_default: hall-int-n-state {
> > >  		pins = "gpio92";
> > >  		function = "gpio";
> > > @@ -1260,3 +1288,23 @@ &usb_1_ss2_dwc3_hs {
> > >  &usb_1_ss2_qmpphy_out {
> > >  	remote-endpoint = <&pmic_glink_ss2_ss_in>;
> > >  };
> > > +
> > > +&usb_mp {
> > > +	status = "okay";
> > > +};
> > > +
> > > +&usb_mp_dwc3 {
> > > +	/* Limit to USB 2.0 and single port */
> > > +	maximum-speed = "high-speed";
> > > +	phys = <&usb_mp_hsphy1>;
> > > +	phy-names = "usb2-1";
> > > +};
> > 
> > The dwc3 driver determines (and acts on) the number of ports based on
> > the port interrupts in DT and controller capabilities. 
> > 
> > I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
> > that would still be there in the SoC (possibly initialised by the boot
> > firmware).
> > 
> > I had a local patch to enable the multiport controller (for the suspend
> > work) and I realise that you'd currently need to specify a repeater also
> > for the HS PHY which does not have one, but that should be possible to
> > fix somehow.
> > 
> 
> I think there are two separate questions here:
> 
>  1. Should we (or do we even need to) enable unused PHYs?
>  2. Do we need to power off unused PHYs left enabled by the firmware?
> 
> For (1), I'm not not sure if there is a technical reason that requires
> us to. And given that PHYs typically consume quite a bit of power, I'm
> not sure if we should. Perhaps it's not worth spending effort on this
> minor optimization now, but then the device tree would ideally still
> tell us which PHYs are actually used (for future optimizations).
> 
> For (2), yes, we probably need to. But my impression so far is that this
> might be a larger problem that we need to handle on the SoC level. I
> have seen some firmware versions that blindly power up all USB
> controllers, even completely unused ones. Ideally we would power down
> unused components during startup and then leave them off.
> 
> Thanks,
> Stephan


From andre.draszik at linaro.org  Tue Dec  3 04:13:52 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:13:52 +0000
Subject: [PATCH v2 4/8] phy: exynos5-usbdrd: fix EDS distribution tuning
 (gs101)
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-phy-v2-4-40dcf1b7670d@linaro.org>

This code's intention is to configure lane0 and lane2 tunings, but for
lane2 there is a typo and it ends up tuning something else.

Fix the typo, as it doesn't appear to make sense to apply different
tunings for lane0 vs lane2.

The same typo appears to exist in the bootloader, hence we restore the
original value in the typo'd registers as well. This can be removed
once / if the bootloader is updated.

Note that this is incorrect in the downstream driver as well - the
values had been copied from there.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index ceae4b47cece..2a724d362c2d 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1510,8 +1510,11 @@ static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_preinit[] = {
 	PHY_TUNING_ENTRY_PMA(0x09e0, -1, 0x00),
 	PHY_TUNING_ENTRY_PMA(0x09e4, -1, 0x36),
 	PHY_TUNING_ENTRY_PMA(0x1e7c, -1, 0x06),
-	PHY_TUNING_ENTRY_PMA(0x1e90, -1, 0x00),
-	PHY_TUNING_ENTRY_PMA(0x1e94, -1, 0x36),
+	PHY_TUNING_ENTRY_PMA(0x19e0, -1, 0x00),
+	PHY_TUNING_ENTRY_PMA(0x19e4, -1, 0x36),
+	/* fix bootloader bug */
+	PHY_TUNING_ENTRY_PMA(0x1e90, -1, 0x02),
+	PHY_TUNING_ENTRY_PMA(0x1e94, -1, 0x0b),
 	/* improve LVCC */
 	PHY_TUNING_ENTRY_PMA(0x08f0, -1, 0x30),
 	PHY_TUNING_ENTRY_PMA(0x18f0, -1, 0x30),

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:13:54 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:13:54 +0000
Subject: [PATCH v2 6/8] phy: exynos5-usbdrd: gs101: configure SS lanes
 based on orientation
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-phy-v2-6-40dcf1b7670d@linaro.org>

USB SS lanes need to be configured based on the connector orientation -
at most two lanes will be in use for USB (and the remaining two for
alternate modes like DP).

For the USB link to come up in SS, the lane configuration registers
have to be programmed accordingly.

While we still need a way to be notified of the actual connector
orientation and then reprogram the registers accordingly (at the moment
the configuration happens just once during phy_init() and never again),
we can prepare the code doing the configuration to take the orientation
into account.

Do so.

Note: the mutex is needed to synchronize this with the upcoming
connector orientation callback.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
* replace #include typec_mux.h with typec.h, and move the former into
  next patch (Peter)
* commit message typo (Peter)
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 72 ++++++++++++++++++++++----------
 1 file changed, 51 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index c1ce6fdeef31..206483c7ca55 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -23,6 +23,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
+#include <linux/usb/typec.h>
 
 /* Exynos USB PHY registers */
 #define EXYNOS5_FSEL_9MHZ6		0x0
@@ -209,6 +210,10 @@
 
 #define EXYNOS9_PMA_USBDP_CMN_REG00B8		0x02e0
 #define CMN_REG00B8_LANE_MUX_SEL_DP		GENMASK(3, 0)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE3	BIT(3)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE2	BIT(2)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE1	BIT(1)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE0	BIT(0)
 
 #define EXYNOS9_PMA_USBDP_CMN_REG01C0		0x0700
 #define CMN_REG01C0_ANA_LCPLL_LOCK_DONE		BIT(7)
@@ -383,11 +388,13 @@ struct exynos5_usbdrd_phy_drvdata {
  * @clks: clocks for register access
  * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required)
  * @drv_data: pointer to SoC level driver data structure
+ * @phy_mutex: mutex protecting phy_init/exit & TCPC callbacks
  * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY
  *	    instances each with its 'phy' and 'phy_cfg'.
  * @extrefclk: frequency select settings when using 'separate
  *	       reference clocks' for SS and HS operations
  * @regulators: regulators for phy
+ * @orientation: TypeC connector orientation - normal or flipped
  */
 struct exynos5_usbdrd_phy {
 	struct device *dev;
@@ -397,6 +404,7 @@ struct exynos5_usbdrd_phy {
 	struct clk_bulk_data *clks;
 	struct clk_bulk_data *core_clks;
 	const struct exynos5_usbdrd_phy_drvdata *drv_data;
+	struct mutex phy_mutex;
 	struct phy_usb_instance {
 		struct phy *phy;
 		u32 index;
@@ -406,6 +414,8 @@ struct exynos5_usbdrd_phy {
 	} phys[EXYNOS5_DRDPHYS_NUM];
 	u32 extrefclk;
 	struct regulator_bulk_data *regulators;
+
+	enum typec_orientation orientation;
 };
 
 static inline
@@ -647,22 +657,38 @@ exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(struct exynos5_usbdrd_phy *phy_drd)
 	/* lane configuration: USB on all lanes */
 	reg = readl(regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8);
 	reg &= ~CMN_REG00B8_LANE_MUX_SEL_DP;
-	writel(reg, regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8);
-
 	/*
-	 * FIXME: below code supports one connector orientation only. It needs
-	 * updating once we can receive connector events.
+	 * USB on lanes 0 & 1 in normal mode, or 2 & 3 if reversed, DP on the
+	 * other ones.
 	 */
+	reg |= FIELD_PREP(CMN_REG00B8_LANE_MUX_SEL_DP,
+			  ((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL)
+			   ? (CMN_REG00B8_LANE_MUX_SEL_DP_LANE3
+			      | CMN_REG00B8_LANE_MUX_SEL_DP_LANE2)
+			   : (CMN_REG00B8_LANE_MUX_SEL_DP_LANE1
+			      | CMN_REG00B8_LANE_MUX_SEL_DP_LANE0)));
+	writel(reg, regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8);
+
 	/* override of TX receiver detector and comparator: lane 1 */
 	reg = readl(regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0413);
-	reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN;
-	reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_EN;
+	if (phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) {
+		reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN;
+		reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_EN;
+	} else {
+		reg |= TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN;
+		reg |= TRSV_REG0413_OVRD_LN1_TX_RXD_EN;
+	}
 	writel(reg, regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0413);
 
 	/* lane 3 */
 	reg = readl(regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0813);
-	reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN;
-	reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_EN;
+	if (phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) {
+		reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN;
+		reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_EN;
+	} else {
+		reg &= ~TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN;
+		reg &= ~TRSV_REG0813_OVRD_LN3_TX_RXD_EN;
+	}
 	writel(reg, regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0813);
 }
 
@@ -700,21 +726,18 @@ exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock(struct exynos5_usbdrd_phy *phy_drd
 	int err;
 
 	err = readl_poll_timeout(
-			phy_drd->reg_pma + EXYNOS9_PMA_USBDP_TRSV_REG03C3,
-			reg, (reg & locked) == locked, sleep_us, timeout_us);
-	if (!err)
-		return;
-
-	dev_err(phy_drd->dev,
-		"timed out waiting for CDR lock (l0): %#.8x, retrying\n", reg);
-
-	/* based on cable orientation, this might be on the other phy port */
-	err = readl_poll_timeout(
-			phy_drd->reg_pma + EXYNOS9_PMA_USBDP_TRSV_REG07C3,
+			/* lane depends on cable orientation */
+			(phy_drd->reg_pma
+			 + ((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL)
+			    ? EXYNOS9_PMA_USBDP_TRSV_REG03C3
+			    : EXYNOS9_PMA_USBDP_TRSV_REG07C3)),
 			reg, (reg & locked) == locked, sleep_us, timeout_us);
 	if (err)
 		dev_err(phy_drd->dev,
-			"timed out waiting for CDR lock (l2): %#.8x\n", reg);
+			"timed out waiting for CDR(l%d) lock: %#.8x\n",
+			((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL)
+			 ? 0
+			 : 2), reg);
 }
 
 static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
@@ -1184,7 +1207,8 @@ static int exynos850_usbdrd_phy_init(struct phy *phy)
 		return ret;
 
 	/* UTMI or PIPE3 specific init */
-	inst->phy_cfg->phy_init(phy_drd);
+	scoped_guard(mutex, &phy_drd->phy_mutex)
+		inst->phy_cfg->phy_init(phy_drd);
 
 	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
 
@@ -1203,6 +1227,8 @@ static int exynos850_usbdrd_phy_exit(struct phy *phy)
 	if (ret)
 		return ret;
 
+	guard(mutex)(&phy_drd->phy_mutex);
+
 	/* Set PHY clock and control HS PHY */
 	reg = readl(regs_base + EXYNOS850_DRD_UTMI);
 	reg &= ~(UTMI_DP_PULLDOWN | UTMI_DM_PULLDOWN);
@@ -1701,6 +1727,10 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 		return -EINVAL;
 	phy_drd->drv_data = drv_data;
 
+	ret = devm_mutex_init(dev, &phy_drd->phy_mutex);
+	if (ret)
+		return ret;
+
 	if (of_property_present(dev->of_node, "reg-names")) {
 		void __iomem *reg;
 

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:13:55 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:13:55 +0000
Subject: [PATCH v2 7/8] phy: exynos5-usbdrd: subscribe to orientation
 notifier if required
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-phy-v2-7-40dcf1b7670d@linaro.org>

gs101's SS phy needs to be configured differently based on the
connector orientation, as the SS link can only be established if the
mux is configured correctly.

The code to handle programming of the mux is in place already, this commit
now adds the missing pieces to subscribe to the Type-C orientation
switch event.

Note that for this all to work we rely on the USB controller
re-initialising us. It should invoke our .exit() upon cable unplug, and
during cable plug we'll receive the orientation event after which we
expect our .init() to be called.

Above reinitialisation happens if the DWC3 controller can enter runtime
suspend automatically. For the DWC3 driver, this is an opt-in:
    echo auto > /sys/devices/.../11110000.usb/power/control
Once done, things work as long as the UDC is not bound as otherwise it
stays busy because it doesn't cancel / stop outstanding TRBs. For now
we have to manually unbind the UDC in that case:
     echo "" > sys/kernel/config/usb_gadget/.../UDC

Note that if the orientation-switch property is missing from the DT,
the code will behave as before this commit (meaning for gs101 it will
work in SS mode in one orientation only). Other platforms are not
affected either way.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* move #include typec_mux.h from parent patch into this one (Peter)
---
 drivers/phy/samsung/Kconfig              |  1 +
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 61 ++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig
index f10afa3d7ff5..fc7bd1088576 100644
--- a/drivers/phy/samsung/Kconfig
+++ b/drivers/phy/samsung/Kconfig
@@ -80,6 +80,7 @@ config PHY_EXYNOS5_USBDRD
 	tristate "Exynos5 SoC series USB DRD PHY driver"
 	depends on (ARCH_EXYNOS && OF) || COMPILE_TEST
 	depends on HAS_IOMEM
+	depends on TYPEC || (TYPEC=n && COMPILE_TEST)
 	depends on USB_DWC3_EXYNOS
 	select GENERIC_PHY
 	select MFD_SYSCON
diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 206483c7ca55..b1914c6c806d 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -24,6 +24,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/usb/typec.h>
+#include <linux/usb/typec_mux.h>
 
 /* Exynos USB PHY registers */
 #define EXYNOS5_FSEL_9MHZ6		0x0
@@ -394,6 +395,7 @@ struct exynos5_usbdrd_phy_drvdata {
  * @extrefclk: frequency select settings when using 'separate
  *	       reference clocks' for SS and HS operations
  * @regulators: regulators for phy
+ * @sw: TypeC orientation switch handle
  * @orientation: TypeC connector orientation - normal or flipped
  */
 struct exynos5_usbdrd_phy {
@@ -415,6 +417,7 @@ struct exynos5_usbdrd_phy {
 	u32 extrefclk;
 	struct regulator_bulk_data *regulators;
 
+	struct typec_switch_dev *sw;
 	enum typec_orientation orientation;
 };
 
@@ -1400,6 +1403,60 @@ static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd)
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_TYPEC)
+static int exynos5_usbdrd_orien_sw_set(struct typec_switch_dev *sw,
+				       enum typec_orientation orientation)
+{
+	struct exynos5_usbdrd_phy *phy_drd = typec_switch_get_drvdata(sw);
+
+	scoped_guard(mutex, &phy_drd->phy_mutex)
+		phy_drd->orientation = orientation;
+
+	return 0;
+}
+
+static void exynos5_usbdrd_orien_switch_unregister(void *data)
+{
+	struct exynos5_usbdrd_phy *phy_drd = data;
+
+	typec_switch_unregister(phy_drd->sw);
+}
+
+static int exynos5_usbdrd_setup_notifiers(struct exynos5_usbdrd_phy *phy_drd)
+{
+	int ret;
+
+	phy_drd->orientation = (enum typec_orientation)-1;
+	if (device_property_present(phy_drd->dev, "orientation-switch")) {
+		struct typec_switch_desc sw_desc = { };
+
+		sw_desc.drvdata = phy_drd;
+		sw_desc.fwnode = dev_fwnode(phy_drd->dev);
+		sw_desc.set = exynos5_usbdrd_orien_sw_set;
+
+		phy_drd->sw = typec_switch_register(phy_drd->dev, &sw_desc);
+		if (IS_ERR(phy_drd->sw))
+			return dev_err_probe(phy_drd->dev,
+					     PTR_ERR(phy_drd->sw),
+					     "Failed to register TypeC orientation switch\n");
+
+		ret = devm_add_action_or_reset(phy_drd->dev,
+					       exynos5_usbdrd_orien_switch_unregister,
+					       phy_drd);
+		if (ret)
+			return dev_err_probe(phy_drd->dev, ret,
+					     "Failed to register TypeC orientation devm action\n");
+	}
+
+	return 0;
+}
+#else /* CONFIG_TYPEC */
+static int exynos5_usbdrd_setup_notifiers(struct exynos5_usbdrd_phy *phy_drd)
+{
+	return 0;
+}
+#endif /* CONFIG_TYPEC */
+
 static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
 	{
 		.id		= EXYNOS5_DRDPHY_UTMI,
@@ -1789,6 +1846,10 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to get regulators\n");
 
+	ret = exynos5_usbdrd_setup_notifiers(phy_drd);
+	if (ret)
+		return ret;
+
 	dev_vdbg(dev, "Creating usbdrd_phy phy\n");
 
 	for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:13:56 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:13:56 +0000
Subject: [PATCH v2 8/8] phy: exynos5-usbdrd: allow DWC3 runtime suspend
 with UDC bound (E850+)
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-phy-v2-8-40dcf1b7670d@linaro.org>

To make USB runtime suspend work when a UDC has been bound, the phy
needs to inform the USBDRD controller (DWC3) that Vbus and bvalid are
gone, so that it can in turn raise the respective gadget interrupt with
event == DWC3_DEVICE_EVENT_DISCONNECT, which will cause the USB stack
to clean up, allowing DWC3 to enter runtime suspend.

On e850 and gs101 this isn't working, as the respective signals are not
directly connected, and instead this driver uses override bits in the
PHY IP to set those signals. It currently forcefully sets them to 'on',
so the above mentioned interrupt will not be raised, preventing runtime
suspend.

To detect that state, update this driver to act on the TCPC's
orientation signal - when orientation == NONE, Vbus is gone and we can
clear the respective bits. Similarly, for other orientation values we
re-enable them.

This makes runtime suspend work on platforms with a TCPC (like Pixel6),
while keeping compatibility with platforms without (e850-96).

With runtime suspend working, USB-C cable orientation detection now
also fully works on such platforms, and the link comes up as Superspeed
as expected irrespective of the cable orientation and whether UDC /
gadget are configured and active.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 53 +++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index b1914c6c806d..94e4f78340ff 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1137,13 +1137,15 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
 	reg |= LINKCTRL_BUS_FILTER_BYPASS(0xf);
 	writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL);
 
-	reg = readl(regs_base + EXYNOS850_DRD_UTMI);
-	reg |= UTMI_FORCE_BVALID | UTMI_FORCE_VBUSVALID;
-	writel(reg, regs_base + EXYNOS850_DRD_UTMI);
-
-	reg = readl(regs_base + EXYNOS850_DRD_HSP);
-	reg |= HSP_VBUSVLDEXT | HSP_VBUSVLDEXTSEL;
-	writel(reg, regs_base + EXYNOS850_DRD_HSP);
+	if (!phy_drd->sw) {
+		reg = readl(regs_base + EXYNOS850_DRD_UTMI);
+		reg |= UTMI_FORCE_BVALID | UTMI_FORCE_VBUSVALID;
+		writel(reg, regs_base + EXYNOS850_DRD_UTMI);
+
+		reg = readl(regs_base + EXYNOS850_DRD_HSP);
+		reg |= HSP_VBUSVLDEXT | HSP_VBUSVLDEXTSEL;
+		writel(reg, regs_base + EXYNOS850_DRD_HSP);
+	}
 
 	reg = readl(regs_base + EXYNOS850_DRD_SSPPLLCTL);
 	reg &= ~SSPPLLCTL_FSEL;
@@ -1408,9 +1410,44 @@ static int exynos5_usbdrd_orien_sw_set(struct typec_switch_dev *sw,
 				       enum typec_orientation orientation)
 {
 	struct exynos5_usbdrd_phy *phy_drd = typec_switch_get_drvdata(sw);
+	int ret;
+
+	if (phy_drd->orientation == orientation)
+		return 0;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret) {
+		dev_err(phy_drd->dev, "Failed to enable PHY clocks(s)\n");
+		return ret;
+	}
+
+	scoped_guard(mutex, &phy_drd->phy_mutex) {
+		void __iomem * const regs_base = phy_drd->reg_phy;
+		unsigned int reg;
+
+		if (orientation == TYPEC_ORIENTATION_NONE) {
+			reg = readl(regs_base + EXYNOS850_DRD_UTMI);
+			reg &= ~(UTMI_FORCE_VBUSVALID | UTMI_FORCE_BVALID);
+			writel(reg, regs_base +  EXYNOS850_DRD_UTMI);
+
+			reg = readl(regs_base + EXYNOS850_DRD_HSP);
+			reg |= HSP_VBUSVLDEXTSEL;
+			reg &= ~HSP_VBUSVLDEXT;
+			writel(reg, regs_base + EXYNOS850_DRD_HSP);
+		} else {
+			reg = readl(regs_base + EXYNOS850_DRD_UTMI);
+			reg |= UTMI_FORCE_VBUSVALID | UTMI_FORCE_BVALID;
+			writel(reg, regs_base +  EXYNOS850_DRD_UTMI);
+
+			reg = readl(regs_base + EXYNOS850_DRD_HSP);
+			reg |= HSP_VBUSVLDEXTSEL | HSP_VBUSVLDEXT;
+			writel(reg, regs_base + EXYNOS850_DRD_HSP);
+		}
 
-	scoped_guard(mutex, &phy_drd->phy_mutex)
 		phy_drd->orientation = orientation;
+	}
+
+	clk_bulk_disable(phy_drd->drv_data->n_clks, phy_drd->clks);
 
 	return 0;
 }

-- 
2.47.0.338.g60cca15819-goog



From sudeep.holla at arm.com  Tue Dec  3 04:14:00 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 3 Dec 2024 12:14:00 +0000
Subject: [PATCH 1/3] firmware/arm_ffa: change ffa_device_register()'s
 parameters and return
In-Reply-To: <20241125095251.366866-2-yeoreum.yun@arm.com>
References: <20241125095251.366866-1-yeoreum.yun@arm.com>
 <20241125095251.366866-2-yeoreum.yun@arm.com>
Message-ID: <Z072CGn6fhnT0hED@bogus>

On Mon, Nov 25, 2024 at 09:52:49AM +0000, Yeoreum Yun wrote:
> From: Levi Yun <yeoreum.yun at arm.com>
> 
> Currently, ffa_dev->properties is set after ffa_device_register() in
> ffa_setup_partitions().
> This means it couldn't validate partition's properties
> while probing ffa_device.
> 
> Change parameter of ffa_device_register() to receive ffa_partition_info
> so that before device_register(), ffa_device->properties can be setup
> and any other data.
> 
> Also, change return value of ffa_device_register() from NULL to ERR_PTR
> so that it passes error code.
> 
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  drivers/firmware/arm_ffa/bus.c    | 22 +++++++++++++++-------
>  drivers/firmware/arm_ffa/driver.c | 12 ++++--------
>  include/linux/arm_ffa.h           | 12 ++++++++----
>  3 files changed, 27 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
> index eb17d03b66fe..95c0e9518556 100644
> --- a/drivers/firmware/arm_ffa/bus.c
> +++ b/drivers/firmware/arm_ffa/bus.c
> @@ -38,6 +38,7 @@ static int ffa_device_match(struct device *dev, const struct device_driver *drv)
>  
>  		if (uuid_equal(&ffa_dev->uuid, &id_table->uuid))
>  			return 1;
> +

Spurious, don't add formatting or style changes in functional change. We
can take it up later when there are other formatting issues.

>  		id_table++;
>  	}
>  
> @@ -187,21 +188,26 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev)
>  	return valid;
>  }
>  
> -struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
> -				       const struct ffa_ops *ops)
> +struct ffa_device *ffa_device_register(
> +		const struct ffa_partition_info *part_info,
> +		const struct ffa_ops *ops)
>  {
>  	int id, ret;
> +	uuid_t uuid;
>  	struct device *dev;
>  	struct ffa_device *ffa_dev;
>  
> +	if (!part_info)
> +		return ERR_PTR(-EINVAL);
> +
>  	id = ida_alloc_min(&ffa_bus_id, 1, GFP_KERNEL);
>  	if (id < 0)
> -		return NULL;
> +		return ERR_PTR(-ENOMEM);
>  
>  	ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL);
>  	if (!ffa_dev) {
>  		ida_free(&ffa_bus_id, id);
> -		return NULL;
> +		return ERR_PTR(-ENOMEM);

I am not keen on changing the error from NULL here. -ENOMEM has its own
logging. ida_alloc failing is very unlikely unless you have so many
partitions in the system.

>  	}
>  
>  	dev = &ffa_dev->dev;
> @@ -210,16 +216,18 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
>  	dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id);
>  
>  	ffa_dev->id = id;
> -	ffa_dev->vm_id = vm_id;
> +	ffa_dev->vm_id = part_info->id;
> +	ffa_dev->properties = part_info->properties;
>  	ffa_dev->ops = ops;
> -	uuid_copy(&ffa_dev->uuid, uuid);
> +	import_uuid(&uuid, (u8 *)part_info->uuid);
> +	uuid_copy(&ffa_dev->uuid, &uuid);
>  
>  	ret = device_register(&ffa_dev->dev);
>  	if (ret) {
>  		dev_err(dev, "unable to register device %s err=%d\n",
>  			dev_name(dev), ret);

This error log will give the information you are adding in driver.c, so
it is again not needed to change that.

>  		put_device(dev);
> -		return NULL;
> +		return ERR_PTR(ret);
>  	}
>  
>  	return ffa_dev;
> diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> index b14cbdae94e8..a3a9cdec7389 100644
> --- a/drivers/firmware/arm_ffa/driver.c
> +++ b/drivers/firmware/arm_ffa/driver.c
> @@ -1406,23 +1406,19 @@ static int ffa_setup_partitions(void)
>  
>  	xa_init(&drv_info->partition_info);
>  	for (idx = 0, tpbuf = pbuf; idx < count; idx++, tpbuf++) {
> -		import_uuid(&uuid, (u8 *)tpbuf->uuid);
> -
>  		/* Note that if the UUID will be uuid_null, that will require
>  		 * ffa_bus_notifier() to find the UUID of this partition id
>  		 * with help of ffa_device_match_uuid(). FF-A v1.1 and above
>  		 * provides UUID here for each partition as part of the
>  		 * discovery API and the same is passed.
>  		 */
> -		ffa_dev = ffa_device_register(&uuid, tpbuf->id, &ffa_drv_ops);
> -		if (!ffa_dev) {
> -			pr_err("%s: failed to register partition ID 0x%x\n",
> -			       __func__, tpbuf->id);
> +		ffa_dev = ffa_device_register(tpbuf, &ffa_drv_ops);
> +		if (IS_ERR_OR_NULL(ffa_dev)) {
> +			pr_err("%s: failed to register partition ID 0x%x, error %ld\n",
> +			       __func__, tpbuf->id, PTR_ERR(ffa_dev));

Drop this additional error info you are adding as bus.c will provide it.

-- 
Regards,
Sudeep


From sudeep.holla at arm.com  Tue Dec  3 04:14:22 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 3 Dec 2024 12:14:22 +0000
Subject: [PATCH 2/3] arm_ffa.h: add properties bit related direct msg
 version 2
In-Reply-To: <20241125095251.366866-3-yeoreum.yun@arm.com>
References: <20241125095251.366866-1-yeoreum.yun@arm.com>
 <20241125095251.366866-3-yeoreum.yun@arm.com>
Message-ID: <Z072HgItfbrUl9K2@bogus>

On Mon, Nov 25, 2024 at 09:52:50AM +0000, Yeoreum Yun wrote:
> From: Levi Yun <yeoreum.yun at arm.com>
> 
> According to FF-A specificaiton [0], There are flags to be used to
> check whether partition supports send/receive direct msg version 2.
> 
> Add related flags.
>

I will delay this to next release, this is not a fix.

-- 
Regards,
Sudeep


From sudeep.holla at arm.com  Tue Dec  3 04:14:42 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 3 Dec 2024 12:14:42 +0000
Subject: [PATCH 3/3] firmware/arm_ffa: remove __le64_to_cpu() when set
 uuid for direct msg v2
In-Reply-To: <20241125095251.366866-4-yeoreum.yun@arm.com>
References: <20241125095251.366866-1-yeoreum.yun@arm.com>
 <20241125095251.366866-4-yeoreum.yun@arm.com>
Message-ID: <Z072Mm61eE_Twx1B@bogus>

On Mon, Nov 25, 2024 at 09:52:51AM +0000, Yeoreum Yun wrote:
> From: Levi Yun <yeoreum.yun at arm.com>
> 
> UUID is saved in big endian format.
> i.e) For uuid "378daedc-f06b-4446-8314-40ab933c87a3",
> 
> It should be saved in memory like:
>     37 8d ae dc
>     f0 6b 44 46
>     83 14 40 ab
>     93 3c 87 a3
> 
> Accoding to FF-A specification[0] 15.4 FFA_MSG_SEND_DRIECT_REQ2,
> then UUID is saved in register:
>     UUID Lo  x2  Bytes[0...7] of UUID with byte 0 in the low-order bits.
>     UUID Hi  x3  Bytes[8...15] of UUID with byte 8 in the low-order bits.
> 
> That means, we don't need to swap the uuid when it send via direct
> message request version 2, just send it as saved in memory.
> 
> Remove le64_to_cpu() for uuid in direct message request version 2,
> and change uuid_regs' type to __be64 because UUID is saved in network
> byte order.
>

  |   warning: incorrect type in initializer (different base types)
  |      expected unsigned long a2
  |      got restricted __be64
  |   warning: incorrect type in initializer (different base types)
  |      expected unsigned long a3
  |      got restricted __be64

We will get this warning back with this change, wondering if we can take
up BE support separately.

--
Regards,
Sudeep


From andre.draszik at linaro.org  Tue Dec  3 04:13:48 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:13:48 +0000
Subject: [PATCH v2 0/8] USB31DRD phy updates for Google Tensor gs101
 (orientation & DWC3 rpm)
Message-ID: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>

Hi,

This series enables USB3 Type-C lane orientation detection and
configuration on platforms that support this (Google gs101), and it
also allows the DWC3 core to enter runtime suspend even when UDC is
active.

For lane orientation, this driver now optionally (based on DT)
subscribes to the TCPC's lane orientation notifier and remembers the
orientation to later be used during phy_init().

To enable DWC3 runtime suspend, the gadget needs to inform the core via
dwc3_gadget_interrupt() with event type == DWC3_DEVICE_EVENT_DISCONNECT
of a cable disconnect. For that to allow to happen, this driver
therefore needs to stop forcing the Vbus and bvalid signals to active
and instead change their state based on actual conditions. The same
TCPC notifier is used to detect this, and program the hardware
accordingly.

That signal state is based on advice given by Thinh in
https://lore.kernel.org/all/20240813230625.jgkatqstyhcmpezv at synopsys.com/

Both changes together now allow cable orientation detection to work, as
the DWC3 will now call phy_exit() on cable disconnect, and we can
reprogram the lane mux in phy_init().

On top of that, there are some small related cleanup patches.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
Changes in v2:
- squash patches #2 and #3 from v1 to actually disallow
  orientation-switch on !gs101 (not just optional) (Conor)
- update bindings commit message to clarify that the intention for the
  driver is to work with old and new DTS (Conor)
- add cc-stable and fixes tags to power gating patch (Krzysztof)
- fix an #include and typo (Peter)
- Link to v1: https://lore.kernel.org/r/20241127-gs101-phy-lanes-orientation-phy-v1-0-1b7fce24960b at linaro.org

---
Andr? Draszik (8):
      dt-bindings: phy: samsung,usb3-drd-phy: align to universal style
      dt-bindings: phy: samsung,usb3-drd-phy: gs101: require Type-C properties
      phy: exynos5-usbdrd: convert to dev_err_probe
      phy: exynos5-usbdrd: fix EDS distribution tuning (gs101)
      phy: exynos5-usbdrd: gs101: ensure power is gated to SS phy in phy_exit()
      phy: exynos5-usbdrd: gs101: configure SS lanes based on orientation
      phy: exynos5-usbdrd: subscribe to orientation notifier if required
      phy: exynos5-usbdrd: allow DWC3 runtime suspend with UDC bound (E850+)

 .../bindings/phy/samsung,usb3-drd-phy.yaml         |  24 +++
 drivers/phy/samsung/Kconfig                        |   1 +
 drivers/phy/samsung/phy-exynos5-usbdrd.c           | 223 ++++++++++++++++-----
 3 files changed, 202 insertions(+), 46 deletions(-)
---
base-commit: ed9a4ad6e5bd3a443e81446476718abebee47e82
change-id: 20241127-gs101-phy-lanes-orientation-phy-29d20c6d84d2

Best regards,
-- 
Andr? Draszik <andre.draszik at linaro.org>



From andre.draszik at linaro.org  Tue Dec  3 04:13:49 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:13:49 +0000
Subject: [PATCH v2 1/8] dt-bindings: phy: samsung,usb3-drd-phy: align to
 universal style
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-phy-v2-1-40dcf1b7670d@linaro.org>

In [1], Rob pointed out that we should really be separating properties
with blank lines in between, which is universal style. Only where
properties are booleans, empty lines are not required.

Do so.

Link: https://lore.kernel.org/all/20240711212359.GA3023490-robh at kernel.org/ [1]
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
---
 .../devicetree/bindings/phy/samsung,usb3-drd-phy.yaml     | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index 16321cdd4919..1f8b35917b11 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -83,14 +83,19 @@ properties:
 
   pll-supply:
     description: Power supply for the USB PLL.
+
   dvdd-usb20-supply:
     description: DVDD power supply for the USB 2.0 phy.
+
   vddh-usb20-supply:
     description: VDDh power supply for the USB 2.0 phy.
+
   vdd33-usb20-supply:
     description: 3.3V power supply for the USB 2.0 phy.
+
   vdda-usbdp-supply:
     description: VDDa power supply for the USB DP phy.
+
   vddh-usbdp-supply:
     description: VDDh power supply for the USB DP phy.
 
@@ -117,6 +122,7 @@ allOf:
             - description: Gate of control interface AXI clock
             - description: Gate of control interface APB clock
             - description: Gate of SCL APB clock
+
         clock-names:
           items:
             - const: phy
@@ -124,10 +130,13 @@ allOf:
             - const: ctrl_aclk
             - const: ctrl_pclk
             - const: scl_pclk
+
         reg:
           minItems: 3
+
         reg-names:
           minItems: 3
+
       required:
         - reg-names
         - pll-supply
@@ -149,6 +158,7 @@ allOf:
         clocks:
           minItems: 5
           maxItems: 5
+
         clock-names:
           items:
             - const: phy
@@ -156,8 +166,10 @@ allOf:
             - const: phy_utmi
             - const: phy_pipe
             - const: itp
+
         reg:
           maxItems: 1
+
         reg-names:
           maxItems: 1
 
@@ -174,12 +186,15 @@ allOf:
         clocks:
           minItems: 2
           maxItems: 2
+
         clock-names:
           items:
             - const: phy
             - const: ref
+
         reg:
           maxItems: 1
+
         reg-names:
           maxItems: 1
 

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:13:50 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:13:50 +0000
Subject: [PATCH v2 2/8] dt-bindings: phy: samsung,usb3-drd-phy: gs101:
 require Type-C properties
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-phy-v2-2-40dcf1b7670d@linaro.org>

orientation-switch is the standard declaration to inform the Type-C mux
layer that a remote-endpoint is capable of processing orientation
change messages.

The USB PHY on gs101 needs to be configured based on the orientation of
the connector. For that the DTS needs a link between the phy's port and
a TCPCi, and we'll need to inform the phy driver that it should handle
the orientation (register a handler).

Update the schema to enforce that by requiring the orientation-switch
and port properties on gs101 (only). We disallow orientation-switch on
all other supported platforms, since other versions of this phy (or its
system integration) don't currently support or even need it.

Even though this new required gs101 property is an ABI break, the
intention for the driver is to behave as before if it's missing
(meaning for gs101 it will work in SS mode in one orientation only).
Other platforms are not affected.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* squash original patches #2 and #3
* actually disallow orientation-switch on !gs101 (not just optional) (Conor)
* update commit message to clarify that the intention for the driver is
  to work with old and new DTS (Conor)
* collect tags
---
 Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index 1f8b35917b11..c1d16254aeec 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -51,6 +51,9 @@ properties:
   "#phy-cells":
     const: 1
 
+  orientation-switch:
+    $ref: /schemas/usb/usb-switch.yaml#/properties/orientation-switch
+
   port:
     $ref: /schemas/graph.yaml#/properties/port
     description:
@@ -139,6 +142,8 @@ allOf:
 
       required:
         - reg-names
+        - orientation-switch
+        - port
         - pll-supply
         - dvdd-usb20-supply
         - vddh-usb20-supply
@@ -146,6 +151,10 @@ allOf:
         - vdda-usbdp-supply
         - vddh-usbdp-supply
 
+    else:
+      properties:
+        orientation-switch: false
+
   - if:
       properties:
         compatible:

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:13:51 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:13:51 +0000
Subject: [PATCH v2 3/8] phy: exynos5-usbdrd: convert to dev_err_probe
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-phy-v2-3-40dcf1b7670d@linaro.org>

dev_err_probe() exists to simplify code.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index c421b495eb0f..ceae4b47cece 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1725,10 +1725,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 
 	reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node,
 						   "samsung,pmu-syscon");
-	if (IS_ERR(reg_pmu)) {
-		dev_err(dev, "Failed to lookup PMU regmap\n");
-		return PTR_ERR(reg_pmu);
-	}
+	if (IS_ERR(reg_pmu))
+		return dev_err_probe(dev, PTR_ERR(reg_pmu),
+				     "Failed to lookup PMU regmap\n");
 
 	/*
 	 * Exynos5420 SoC has multiple channels for USB 3.0 PHY, with
@@ -1759,10 +1758,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 	for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {
 		struct phy *phy = devm_phy_create(dev, NULL, drv_data->phy_ops);
 
-		if (IS_ERR(phy)) {
-			dev_err(dev, "Failed to create usbdrd_phy phy\n");
-			return PTR_ERR(phy);
-		}
+		if (IS_ERR(phy))
+			return dev_err_probe(dev, PTR_ERR(phy),
+					     "Failed to create usbdrd_phy phy\n");
 
 		phy_drd->phys[i].phy = phy;
 		phy_drd->phys[i].index = i;
@@ -1786,10 +1784,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 
 	phy_provider = devm_of_phy_provider_register(dev,
 						     exynos5_usbdrd_phy_xlate);
-	if (IS_ERR(phy_provider)) {
-		dev_err(phy_drd->dev, "Failed to register phy provider\n");
-		return PTR_ERR(phy_provider);
-	}
+	if (IS_ERR(phy_provider))
+		return dev_err_probe(phy_drd->dev, PTR_ERR(phy_provider),
+				     "Failed to register phy provider\n");
 
 	return 0;
 }

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:13:53 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:13:53 +0000
Subject: [PATCH v2 5/8] phy: exynos5-usbdrd: gs101: ensure power is gated
 to SS phy in phy_exit()
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-phy-v2-5-40dcf1b7670d@linaro.org>

We currently don't gate the power to the SS phy in phy_exit().

Shuffle the code slightly to ensure the power is gated to the SS phy as
well.

Fixes: 32267c29bc7d ("phy: exynos5-usbdrd: support Exynos USBDRD 3.1 combo phy (HS & SS)")
CC: stable at vger.kernel.org # 6.11+
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* add cc-stable and fixes tags (Krzysztof)
* collect tags
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 2a724d362c2d..c1ce6fdeef31 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1296,14 +1296,17 @@ static int exynos5_usbdrd_gs101_phy_exit(struct phy *phy)
 	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
 	int ret;
 
+	if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) {
+		ret = exynos850_usbdrd_phy_exit(phy);
+		if (ret)
+			return ret;
+	}
+
+	exynos5_usbdrd_phy_isol(inst, true);
+
 	if (inst->phy_cfg->id != EXYNOS5_DRDPHY_UTMI)
 		return 0;
 
-	ret = exynos850_usbdrd_phy_exit(phy);
-	if (ret)
-		return ret;
-
-	exynos5_usbdrd_phy_isol(inst, true);
 	return regulator_bulk_disable(phy_drd->drv_data->n_regulators,
 				      phy_drd->regulators);
 }

-- 
2.47.0.338.g60cca15819-goog



From dmitry.baryshkov at linaro.org  Tue Dec  3 04:19:41 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 3 Dec 2024 14:19:41 +0200
Subject: [PATCH v5 8/9] drm/vc4: hdmi: switch to using generic HDMI Codec
 infrastructure
In-Reply-To: <20241202-industrious-unnatural-beagle-7da5d4@houat>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-8-b5316e82f61a@linaro.org>
 <20241202-industrious-unnatural-beagle-7da5d4@houat>
Message-ID: <e7jngrc4nljdsksekinbkir2h76ztsth2xj4yqcyapfv43uryh@356yrxv3j4x6>

On Mon, Dec 02, 2024 at 02:20:04PM +0100, Maxime Ripard wrote:
> Hi,
> 
> Sorry, I've been drowning under work and couldn't review that series before.

No worries, at this point I'm more concerned about my IGT series rather
than this one.

> 
> I'll review the driver API for now, and we can focus on the exact
> implementation later on.
> 
> On Sun, Dec 01, 2024 at 02:44:12AM +0200, Dmitry Baryshkov wrote:
> > Drop driver-specific implementation and use the generic HDMI Codec
> > framework in order to implement the HDMI audio support.
> > 
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >  drivers/gpu/drm/vc4/vc4_hdmi.c | 68 ++++++++++--------------------------------
> >  drivers/gpu/drm/vc4/vc4_hdmi.h |  2 --
> >  2 files changed, 15 insertions(+), 55 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > index 7295834e75fb1ab0cd241ed274e675567e66870b..d0a9aff7ad43016647493263c00d593296a1e3ad 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > @@ -595,6 +595,9 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
> >  	if (vc4_hdmi->variant->supports_hdr)
> >  		max_bpc = 12;
> >  
> > +	connector->hdmi_codec.max_i2s_channels = 8;
> > +	connector->hdmi_codec.i2s = 1;
> > +
> 
> I guess it's a similar discussion than we had with HDMI2.0+ earlier
> today, but I don't really like initializing by structs. Struct fields
> are easy to miss, and can be easily uninitialized by mistake.
> 
> I think I'd prefer to have them as argument to the init function. And if
> they are optional, we can explicitly mark them as unused.

Do you mean drm_connector_hdmi_init()? I think it's overloaded already,
but I defintely can think about:

drmm_connector_hdmi_init(..., max_bpc, HDMI_CODEC_I2S_PLAYBACK(8) |
HDMI_CODEC_NO_CAPTURE | HDMI_CODEC_DAI_ID(4));

or

... | HDMI_CODEC_NO_DAI_ID)

The default (0) being equivalent to:

HDMI_CODEC_NO_I2S | HDMI_CODEC_NO_SPDIF | HDMI_CODEC_NO_CAPTURE | HDMI_CODEC_NO_DAI_ID

WDYT?

> 
> Like, it looks like the get_dai_id implementation relies on it being set
> to < 0 for it to be ignored, but it's not here, so I'd assume it's used
> with an ID of 0, even though the driver didn't support get_dai_id so
> far?


-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Tue Dec  3 04:27:44 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 3 Dec 2024 14:27:44 +0200
Subject: [PATCH v5 9/9] drm/vc4: hdmi: use
 drm_atomic_helper_connector_hdmi_update_edid()
In-Reply-To: <20241202-married-bald-raven-7acd83@houat>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-9-b5316e82f61a@linaro.org>
 <20241202-married-bald-raven-7acd83@houat>
Message-ID: <ae24x2bo736jpzi77l34hybejawwe4rp47v2idedga344ye6zr@bxsxz34dwrd2>

On Mon, Dec 02, 2024 at 02:27:49PM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Sun, Dec 01, 2024 at 02:44:13AM +0200, Dmitry Baryshkov wrote:
> > Use the helper function to update the connector's information. This
> > makes sure that HDMI-related events are handled in a generic way.
> > Currently it is limited to the HDMI state reporting to the sound system.
> > 
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >  drivers/gpu/drm/vc4/vc4_hdmi.c | 9 +++++++--
> >  1 file changed, 7 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > index d0a9aff7ad43016647493263c00d593296a1e3ad..d83f587ab69f4b8f7d5c37a00777f11da8301bc1 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > @@ -401,13 +401,16 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
> >  	 */
> >  
> >  	if (status == connector_status_disconnected) {
> > +		drm_atomic_helper_connector_hdmi_update_edid(connector, NULL);
> >  		cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
> >  		return;
> >  	}
> >  
> >  	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
> >  
> > -	drm_edid_connector_update(connector, drm_edid);
> > +	// TODO: use drm_atomic_helper_connector_hdmi_update() once it gains
> > +	// CEC support
> > +	drm_atomic_helper_connector_hdmi_update_edid(connector, drm_edid);
> 
> So, it's not just about EDID, and I think we shouldn't really focus on
> that either.
> 
> As that patch points out, even if we only consider EDID's, we have
> different path depending on the connector status. It shouldn't be up to
> the drivers to get this right.
> 
> What I had in mind was something like a
> drm_atomic_helper_connector_hdmi_hotplug function that would obviously
> deal with EDID only here, but would expand to CEC, scrambling, etc.
> later on.

I thought about it, after our discussion, but in the end I had to
implement the EDID-specific function, using edid == NULL as
"disconnected" event. The issue is pretty simple: there is no standard
way to get EDID from the connector. The devices can call
drm_edid_read(), drm_edid_read_ddc(connector->ddc) or (especially
embedded bridges) use drm_edid_read_custom().

Of course we can go with the functional way and add the
.read_edid(drm_connector) callback to the HDMI funcs. Then the
drm_atomic_helper_connector_hdmi_hotplug() function can read EDID on its
own.

Also the function that you proposed perfectly fits the HPD notification
callbacks, but which function should be called from the .get_modes()?
The _hdmi_hotplug() doesn't fit there. Do we still end up with both
drm_atomic_helper_connector_hdmi_hotplug() and
drm_atomic_helper_connector_hdmi_update_edid()?

> 
> And would cover both the connected/disconnected cases.
> 
> Maxime



-- 
With best wishes
Dmitry


From eballetb at redhat.com  Tue Dec  3 04:35:44 2024
From: eballetb at redhat.com (Enric Balletbo i Serra)
Date: Tue, 3 Dec 2024 13:35:44 +0100
Subject: [PATCH] dmaengine: dma_request_chan_by_mask() defer probing unconditionally
In-Reply-To: <ffccf100-469f-4e5b-a32c-5c06e196aacd@ti.com>
References: <20241127-defer-dma-request-chan-v1-1-203db7baf470@redhat.com>
 <4dd1caa7-4b95-4e06-a5ac-e2d33ce88d04@arm.com> <ffccf100-469f-4e5b-a32c-5c06e196aacd@ti.com>
Message-ID: <CALE0LRt9W41Gr0dvDXpt3fV-=jMvrD1X6e4bS9+EMy8J-Qv14w@mail.gmail.com>

Hi,

On Tue, Dec 3, 2024 at 5:35?AM Vignesh Raghavendra <vigneshr at ti.com> wrote:
>
> Hi Enric,
>
> On 29/11/24 22:14, Robin Murphy wrote:
> > On 2024-11-27 8:23 am, Enric Balletbo i Serra wrote:
> >> Having no DMA devices registered is not a guarantee that the device
> >> doesn't exist, it could be that is not registered yet, so return
> >> EPROBE_DEFER unconditionally so the caller can wait for the required
> >> DMA device registered.
> >>
> >> Signed-off-by: Enric Balletbo i Serra <eballetb at redhat.com>
> >> ---
> >> This patch fixes the following error on TI AM69-SK
> >>
> >> [    2.854501] cadence-qspi 47040000.spi: error -ENODEV: No Rx DMA
> >> available
> >>
> >> The DMA device is probed after cadence-qspi driver, so deferring it
> >> solves the problem.
> >
> > Conversely, though, it does carry some risk that if there really is no
> > DMA device/driver, other callers (e.g. spi-ti-qspi) may now get stuck
> > deferring forever where the -ENODEV would have let them proceed with a
> > fallback to non-DMA operation. driver_deferred_probe_check_state() is
> > typically a good tool for these situations, but I guess it's a bit
> > tricky in a context where we don't actually have the dependent device to
> > hand :/
>
>
> +1. There is no explicit dependency that can be modeled (via DT or
> otherwise) for memcpy DMA channels. And the IP (cadence-qspi) is not
> specific to TI platforms. Its very much possible that a non TI platform
> may not have memcpy DMA channel at all. Wont this end up breaking such
> platforms wrt using SPI flash using CPU bound IO?
>

To be honest, I didn't take into account this, so yes, this patch will
break such platforms. But isn't it already broken in such cases? If I
understand correctly, if there are no dma devices at all, we're
already deferring the probe [1].

        if (list_empty(&dma_device_list))
             chan = ERR_PTR(-EPROBE_DEFER);

[1] https://elixir.bootlin.com/linux/v6.13-rc1/source/drivers/dma/dmaengine.c#L892

Thanks,
   Enric

> >
> > Thanks,
> > Robin.
> >
> >> ---
> >>   drivers/dma/dmaengine.c | 8 ++++----
> >>   1 file changed, 4 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> >> index
> >> c1357d7f3dc6ca7899c4d68a039567e73b0f089d..57f07b477a5d9ad8f2656584b8c0d6dffb2ab469 100644
> >> --- a/drivers/dma/dmaengine.c
> >> +++ b/drivers/dma/dmaengine.c
> >> @@ -889,10 +889,10 @@ struct dma_chan *dma_request_chan_by_mask(const
> >> dma_cap_mask_t *mask)
> >>       chan = __dma_request_channel(mask, NULL, NULL, NULL);
> >>       if (!chan) {
> >>           mutex_lock(&dma_list_mutex);
> >> -        if (list_empty(&dma_device_list))
> >> -            chan = ERR_PTR(-EPROBE_DEFER);
> >> -        else
> >> -            chan = ERR_PTR(-ENODEV);
> >> +        /* If the required DMA device is not registered yet,
> >> +         * return EPROBE_DEFER
> >> +         */
> >> +        chan = ERR_PTR(-EPROBE_DEFER);
> >>           mutex_unlock(&dma_list_mutex);
> >>       }
> >>
> >> ---
> >> base-commit: 43fb83c17ba2d63dfb798f0be7453ed55ca3f9c2
> >> change-id: 20241127-defer-dma-request-chan-4f26c62c8691
> >>
> >> Best regards,
> >
>
> --
> Regards
> Vignesh
> https://ti.com/opensource
>



From yangyicong at huawei.com  Tue Dec  3 04:50:42 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:42 +0800
Subject: [PATCH v4 03/10] drivers/perf: hisi: Migrate to one online CPU if no associated one online
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-4-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

If the selected CPU hisi_pmu::on_cpu goes offline, driver will select
a new online CPU from hisi_pmu::associated_cpus, or if no online CPU
found the PMU context won't be migrated. However for uncore PMUs the
associated CPUs are just a peference and it also works to schedule
the events on any online CPUs. So add a fallback to choose an online
CPU if no associated CPUs found.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index dbe7299f0f05..3a4db5c5d70f 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -499,9 +499,16 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 	/* Give up ownership of the PMU */
 	hisi_pmu->on_cpu = -1;
 
-	/* Choose a new CPU to migrate ownership of the PMU to */
+	/*
+	 * Migrate ownership of the PMU to a new CPU chosen from PMU's online
+	 * associated CPUs if possible, if no associated CPU online then
+	 * migrate to one online CPU.
+	 */
 	target = cpumask_any_and_but(&hisi_pmu->associated_cpus,
 				     cpu_online_mask, cpu);
+	if (target >= nr_cpu_ids)
+		target = cpumask_any_but(cpu_online_mask, cpu);
+
 	if (target >= nr_cpu_ids)
 		return 0;
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec  3 04:50:40 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:40 +0800
Subject: [PATCH v4 01/10] drivers/perf: hisi: Define a symbol namespace for HiSilicon Uncore PMUs
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-2-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

The HiSilicon Uncore PMU framework implements some common functions
and exported them to the drivers. Use a specific HISI_PMU namespace
for the exported symbols to avoid pollute the generic ones.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  |  1 +
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c |  1 +
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  |  1 +
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  |  1 +
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   |  1 +
 drivers/perf/hisilicon/hisi_uncore_pmu.c      | 36 +++++++++----------
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c |  1 +
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   |  1 +
 8 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
index 3f3fb1de11f5..d2dc848956af 100644
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
@@ -389,6 +389,7 @@ static void __exit hisi_cpa_pmu_module_exit(void)
 }
 module_exit(hisi_cpa_pmu_module_exit);
 
+MODULE_IMPORT_NS(HISI_PMU);
 MODULE_DESCRIPTION("HiSilicon SoC CPA PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Qi Liu <liuqi115 at huawei.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index a6ebf2ec99d3..e323f0c339ec 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -579,6 +579,7 @@ static void __exit hisi_ddrc_pmu_module_exit(void)
 }
 module_exit(hisi_ddrc_pmu_module_exit);
 
+MODULE_IMPORT_NS(HISI_PMU);
 MODULE_DESCRIPTION("HiSilicon SoC DDRC uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Shaokun Zhang <zhangshaokun at hisilicon.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index 32624872596f..d5c2eab8023e 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -581,6 +581,7 @@ static void __exit hisi_hha_pmu_module_exit(void)
 }
 module_exit(hisi_hha_pmu_module_exit);
 
+MODULE_IMPORT_NS(HISI_PMU);
 MODULE_DESCRIPTION("HiSilicon SoC HHA uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Shaokun Zhang <zhangshaokun at hisilicon.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index c235b46ce873..0d1b5d17ba26 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -615,6 +615,7 @@ static void __exit hisi_l3c_pmu_module_exit(void)
 }
 module_exit(hisi_l3c_pmu_module_exit);
 
+MODULE_IMPORT_NS(HISI_PMU);
 MODULE_DESCRIPTION("HiSilicon SoC L3C uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Anurup M <anurup.m at huawei.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
index c0f5d7c73e06..eaaad28871a3 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
@@ -569,6 +569,7 @@ static void __exit hisi_pa_pmu_module_exit(void)
 }
 module_exit(hisi_pa_pmu_module_exit);
 
+MODULE_IMPORT_NS(HISI_PMU);
 MODULE_DESCRIPTION("HiSilicon Protocol Adapter uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Shaokun Zhang <zhangshaokun at hisilicon.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 918cdc31de57..416f72a813fc 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -34,7 +34,7 @@ ssize_t hisi_event_sysfs_show(struct device *dev,
 
 	return sysfs_emit(page, "config=0x%lx\n", (unsigned long)eattr->var);
 }
-EXPORT_SYMBOL_GPL(hisi_event_sysfs_show);
+EXPORT_SYMBOL_NS_GPL(hisi_event_sysfs_show, HISI_PMU);
 
 /*
  * sysfs cpumask attributes. For uncore PMU, we only have a single CPU to show
@@ -46,7 +46,7 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
 
 	return sysfs_emit(buf, "%d\n", hisi_pmu->on_cpu);
 }
-EXPORT_SYMBOL_GPL(hisi_cpumask_sysfs_show);
+EXPORT_SYMBOL_NS_GPL(hisi_cpumask_sysfs_show, HISI_PMU);
 
 static bool hisi_validate_event_group(struct perf_event *event)
 {
@@ -96,7 +96,7 @@ int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
 
 	return idx;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_get_event_idx);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_get_event_idx, HISI_PMU);
 
 ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
 					     struct device_attribute *attr,
@@ -106,7 +106,7 @@ ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
 
 	return sysfs_emit(page, "0x%08x\n", hisi_pmu->identifier);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_identifier_attr_show);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_identifier_attr_show, HISI_PMU);
 
 static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
 {
@@ -165,7 +165,7 @@ int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_init_irq);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_init_irq, HISI_PMU);
 
 int hisi_uncore_pmu_event_init(struct perf_event *event)
 {
@@ -219,7 +219,7 @@ int hisi_uncore_pmu_event_init(struct perf_event *event)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_init);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_event_init, HISI_PMU);
 
 /*
  * Set the counter to count the event that we're interested in,
@@ -273,7 +273,7 @@ void hisi_uncore_pmu_set_event_period(struct perf_event *event)
 	/* Write start value to the hardware event counter */
 	hisi_pmu->ops->write_counter(hisi_pmu, hwc, val);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_set_event_period);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_set_event_period, HISI_PMU);
 
 void hisi_uncore_pmu_event_update(struct perf_event *event)
 {
@@ -294,7 +294,7 @@ void hisi_uncore_pmu_event_update(struct perf_event *event)
 		HISI_MAX_PERIOD(hisi_pmu->counter_bits);
 	local64_add(delta, &event->count);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_update);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_event_update, HISI_PMU);
 
 void hisi_uncore_pmu_start(struct perf_event *event, int flags)
 {
@@ -317,7 +317,7 @@ void hisi_uncore_pmu_start(struct perf_event *event, int flags)
 	hisi_uncore_pmu_enable_event(event);
 	perf_event_update_userpage(event);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_start);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_start, HISI_PMU);
 
 void hisi_uncore_pmu_stop(struct perf_event *event, int flags)
 {
@@ -334,7 +334,7 @@ void hisi_uncore_pmu_stop(struct perf_event *event, int flags)
 	hisi_uncore_pmu_event_update(event);
 	hwc->state |= PERF_HES_UPTODATE;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_stop);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_stop, HISI_PMU);
 
 int hisi_uncore_pmu_add(struct perf_event *event, int flags)
 {
@@ -357,7 +357,7 @@ int hisi_uncore_pmu_add(struct perf_event *event, int flags)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_add);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_add, HISI_PMU);
 
 void hisi_uncore_pmu_del(struct perf_event *event, int flags)
 {
@@ -369,14 +369,14 @@ void hisi_uncore_pmu_del(struct perf_event *event, int flags)
 	perf_event_update_userpage(event);
 	hisi_pmu->pmu_events.hw_events[hwc->idx] = NULL;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_del);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_del, HISI_PMU);
 
 void hisi_uncore_pmu_read(struct perf_event *event)
 {
 	/* Read hardware counter and update the perf counter statistics */
 	hisi_uncore_pmu_event_update(event);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_read);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_read, HISI_PMU);
 
 void hisi_uncore_pmu_enable(struct pmu *pmu)
 {
@@ -389,7 +389,7 @@ void hisi_uncore_pmu_enable(struct pmu *pmu)
 
 	hisi_pmu->ops->start_counters(hisi_pmu);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_enable);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_enable, HISI_PMU);
 
 void hisi_uncore_pmu_disable(struct pmu *pmu)
 {
@@ -397,7 +397,7 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
 
 	hisi_pmu->ops->stop_counters(hisi_pmu);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_disable);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_disable, HISI_PMU);
 
 
 /*
@@ -484,7 +484,7 @@ int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_online_cpu);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_online_cpu, HISI_PMU);
 
 int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 {
@@ -515,7 +515,7 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_offline_cpu);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_offline_cpu, HISI_PMU);
 
 void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 {
@@ -535,7 +535,7 @@ void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 	pmu->attr_groups        = hisi_pmu->pmu_events.attr_groups;
 	pmu->capabilities       = PERF_PMU_CAP_NO_EXCLUDE;
 }
-EXPORT_SYMBOL_GPL(hisi_pmu_init);
+EXPORT_SYMBOL_NS_GPL(hisi_pmu_init, HISI_PMU);
 
 MODULE_DESCRIPTION("HiSilicon SoC uncore Performance Monitor driver framework");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
index c5f4764ee888..0ef2f6797109 100644
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
@@ -507,6 +507,7 @@ static void __exit hisi_sllc_pmu_module_exit(void)
 }
 module_exit(hisi_sllc_pmu_module_exit);
 
+MODULE_IMPORT_NS(HISI_PMU);
 MODULE_DESCRIPTION("HiSilicon SLLC uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Shaokun Zhang <zhangshaokun at hisilicon.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
index 481dcc9e8fbf..9c724dab6b64 100644
--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
@@ -613,6 +613,7 @@ static void __exit hisi_uc_pmu_module_exit(void)
 }
 module_exit(hisi_uc_pmu_module_exit);
 
+MODULE_IMPORT_NS(HISI_PMU);
 MODULE_DESCRIPTION("HiSilicon SoC UC uncore PMU driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Junhao He <hejunhao3 at huawei.com>");
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec  3 04:50:48 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:48 +0800
Subject: [PATCH v4 09/10] drivers/perf: hisi: Fix incorrect variable name "hha_pmu" in DDRC PMU driver
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-10-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

In the callback function write_evtype(), the variable name of struct
hisi_pmu should be "ddrc_pmu" instead of "hha_pmu".

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index fb596f43ef9a..0caa15aa836f 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -111,14 +111,14 @@ static void hisi_ddrc_pmu_v2_write_counter(struct hisi_pmu *ddrc_pmu,
  * so there is no need to write event type, while it is programmable counter in
  * PMU v2.
  */
-static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
+static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *ddrc_pmu, int idx,
 				       u32 type)
 {
 	u32 offset;
 
-	if (hha_pmu->identifier >= HISI_PMU_V2) {
+	if (ddrc_pmu->identifier >= HISI_PMU_V2) {
 		offset = DDRC_V2_EVENT_TYPE + 4 * idx;
-		writel(type, hha_pmu->base + offset);
+		writel(type, ddrc_pmu->base + offset);
 	}
 }
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec  3 04:50:41 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:41 +0800
Subject: [PATCH v4 02/10] drivers/perf: hisi: Don't update the associated_cpus on CPU offline
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-3-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Event will be scheduled on CPU of hisi_pmu::on_cpu which is selected
from the intersection of hisi_pmu::associated_cpus and online CPUs.
So the associated_cpus don't need to be maintained with online CPUs.
This will save one update operation if one associated CPU is offlined.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 416f72a813fc..dbe7299f0f05 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -492,9 +492,6 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 						     node);
 	unsigned int target;
 
-	if (!cpumask_test_and_clear_cpu(cpu, &hisi_pmu->associated_cpus))
-		return 0;
-
 	/* Nothing to do if this CPU doesn't own the PMU */
 	if (hisi_pmu->on_cpu != cpu)
 		return 0;
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec  3 04:50:43 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:43 +0800
Subject: [PATCH v4 04/10] drivers/perf: hisi: Refactor the detection of associated CPUs
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-5-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

There are two type of PMUs supported currently:
1) PMUs locate on SCCL (Super CPU Cluster [1]), associated with certain
   CCL (CPU cluster [1])(e.g. L3C PMU) or not (e.g. DDRC PMU)
2) PMUs locate on the SICL (Super IO Cluster [1]), which has no
   association with certain CPU topology (e.g. CPA PMU)

Currently the associated CPUs of the PMU is detected in the cpuhp online
callback as below:
- for type 1) the CPUs match PMU's sccl_id and ccl_id
- for type 2) PMU's sccl_id is -1 and all online CPUs will be associated

Since uncore PMUs are not bound to certain CPU context and event could be
counting started by any online CPU, the associated CPUs are just a
preference. Below disadvantages are observed in current implementation:
- the PMU cannot be used if its associated CPUs are offline
- SICL PMUs are associated to all the online CPUs implicitly without
  the consideration of locality

So refactor the way we detect the associated CPUs in below aspects:
- add a clear definition of hisi_pmu::associated_cpus
- initialize hisi_pmu::on_cpu based on locality if no associated CPU
  found, otherwise update it from associated CPUs
- drop the detection with a sccl_id of -1 for SICL PMUs

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/perf/hisi-pmu.rst?h=v6.12-rc1
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 22 +++++++++++++++-------
 drivers/perf/hisilicon/hisi_uncore_pmu.h |  6 +++++-
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 3a4db5c5d70f..dda8cff4baf4 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -446,10 +446,6 @@ static bool hisi_pmu_cpu_is_associated_pmu(struct hisi_pmu *hisi_pmu)
 {
 	int sccl_id, ccl_id;
 
-	/* If SCCL_ID is -1, the PMU is in a SICL and has no CPU affinity */
-	if (hisi_pmu->sccl_id == -1)
-		return true;
-
 	if (hisi_pmu->ccl_id == -1) {
 		/* If CCL_ID is -1, the PMU only shares the same SCCL */
 		hisi_read_sccl_and_ccl_id(&sccl_id, NULL);
@@ -467,13 +463,25 @@ int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
 	struct hisi_pmu *hisi_pmu = hlist_entry_safe(node, struct hisi_pmu,
 						     node);
 
-	if (!hisi_pmu_cpu_is_associated_pmu(hisi_pmu))
+	/*
+	 * If the CPU is not associated to PMU, initialize the hisi_pmu->on_cpu
+	 * based on the locality if it hasn't been initialized yet. For PMUs
+	 * do have associated CPUs, it'll be updated later.
+	 */
+	if (!hisi_pmu_cpu_is_associated_pmu(hisi_pmu)) {
+		if (hisi_pmu->on_cpu != -1)
+			return 0;
+
+		hisi_pmu->on_cpu = cpumask_local_spread(0, dev_to_node(hisi_pmu->dev));
+		WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(cpu)));
 		return 0;
+	}
 
 	cpumask_set_cpu(cpu, &hisi_pmu->associated_cpus);
 
-	/* If another CPU is already managing this PMU, simply return. */
-	if (hisi_pmu->on_cpu != -1)
+	/* If another associated CPU is already managing this PMU, simply return. */
+	if (hisi_pmu->on_cpu != -1 &&
+	    cpumask_test_cpu(hisi_pmu->on_cpu, &hisi_pmu->associated_cpus))
 		return 0;
 
 	/* Use this CPU in cpumask for event counting */
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
index 25b2d43b72bf..bd48338ce937 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
@@ -87,7 +87,11 @@ struct hisi_pmu {
 	const struct hisi_uncore_ops *ops;
 	const struct hisi_pmu_dev_info *dev_info;
 	struct hisi_pmu_hwevents pmu_events;
-	/* associated_cpus: All CPUs associated with the PMU */
+	/*
+	 * CPUs associated to the PMU and are preferred to use for counting.
+	 * Could be empty if PMU has no association (e.g. PMU on SICL), in
+	 * which case any online CPU will be used.
+	 */
 	cpumask_t associated_cpus;
 	/* CPU used for counting */
 	int on_cpu;
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec  3 04:50:45 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:45 +0800
Subject: [PATCH v4 06/10] drivers/perf: hisi: Add a common function to retrieve topology from firmware
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-7-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Currently each type of uncore PMU driver uses almost the same routine
and the same firmware interface (or properties) to retrieve the topology
information, then reset the unused IDs to -1. Extract the common parts
to the framework in hisi_uncore_pmu_init_topology().

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  | 10 +++----
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 10 +++----
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  | 10 +++----
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  |  8 ++---
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   | 11 +++----
 drivers/perf/hisilicon/hisi_uncore_pmu.c      | 30 +++++++++++++++++++
 drivers/perf/hisilicon/hisi_uncore_pmu.h      |  1 +
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 11 +++----
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   | 12 ++++----
 9 files changed, 60 insertions(+), 43 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
index 826e25c14cec..c9b5016fafdb 100644
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
@@ -180,20 +180,18 @@ MODULE_DEVICE_TABLE(acpi, hisi_cpa_pmu_acpi_match);
 static int hisi_cpa_pmu_init_data(struct platform_device *pdev,
 				  struct hisi_pmu *cpa_pmu)
 {
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &cpa_pmu->topo.sicl_id)) {
+	hisi_uncore_pmu_init_topology(cpa_pmu, &pdev->dev);
+
+	if (cpa_pmu->topo.sicl_id < 0) {
 		dev_err(&pdev->dev, "Can not read sicl-id\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &cpa_pmu->topo.index_id)) {
+	if (cpa_pmu->topo.index_id < 0) {
 		dev_err(&pdev->dev, "Cannot read idx-id\n");
 		return -EINVAL;
 	}
 
-	cpa_pmu->topo.ccl_id = -1;
-	cpa_pmu->topo.sccl_id = -1;
 	cpa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(cpa_pmu->base))
 		return PTR_ERR(cpa_pmu->base);
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index f7bc86644ebe..56a4068d6568 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -297,6 +297,8 @@ MODULE_DEVICE_TABLE(acpi, hisi_ddrc_pmu_acpi_match);
 static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 				   struct hisi_pmu *ddrc_pmu)
 {
+	hisi_uncore_pmu_init_topology(ddrc_pmu, &pdev->dev);
+
 	/*
 	 * Use the SCCL_ID and DDRC channel ID to identify the
 	 * DDRC PMU, while SCCL_ID is in MPIDR[aff2].
@@ -307,13 +309,10 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &ddrc_pmu->topo.sccl_id)) {
+	if (ddrc_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read ddrc sccl-id!\n");
 		return -EINVAL;
 	}
-	/* DDRC PMUs only share the same SCCL */
-	ddrc_pmu->topo.ccl_id = -1;
 
 	ddrc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ddrc_pmu->base)) {
@@ -323,8 +322,7 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 
 	ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
 	if (ddrc_pmu->identifier >= HISI_PMU_V2) {
-		if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-					     &ddrc_pmu->topo.sub_id)) {
+		if (ddrc_pmu->topo.sub_id < 0) {
 			dev_err(&pdev->dev, "Can not read sub-id!\n");
 			return -EINVAL;
 		}
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index c5a8f61b5ad5..e59b31fdc4e4 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -295,12 +295,13 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 	unsigned long long id;
 	acpi_status status;
 
+	hisi_uncore_pmu_init_topology(hha_pmu, &pdev->dev);
+
 	/*
 	 * Use SCCL_ID and UID to identify the HHA PMU, while
 	 * SCCL_ID is in MPIDR[aff2].
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &hha_pmu->topo.sccl_id)) {
+	if (hha_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read hha sccl-id!\n");
 		return -EINVAL;
 	}
@@ -309,8 +310,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 	 * Early versions of BIOS support _UID by mistake, so we support
 	 * both "hisilicon, idx-id" as preference, if available.
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &hha_pmu->topo.index_id)) {
+	if (hha_pmu->topo.index_id < 0) {
 		status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
 					       "_UID", NULL, &id);
 		if (ACPI_FAILURE(status)) {
@@ -320,8 +320,6 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 
 		hha_pmu->topo.index_id = id;
 	}
-	/* HHA PMUs only share the same SCCL */
-	hha_pmu->topo.ccl_id = -1;
 
 	hha_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hha_pmu->base)) {
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index 94546738f6ba..290a9e311f48 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -355,18 +355,18 @@ MODULE_DEVICE_TABLE(acpi, hisi_l3c_pmu_acpi_match);
 static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
 				  struct hisi_pmu *l3c_pmu)
 {
+	hisi_uncore_pmu_init_topology(l3c_pmu, &pdev->dev);
+
 	/*
 	 * Use the SCCL_ID and CCL_ID to identify the L3C PMU, while
 	 * SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &l3c_pmu->topo.sccl_id)) {
+	if (l3c_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read l3c sccl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-				     &l3c_pmu->topo.ccl_id)) {
+	if (l3c_pmu->topo.ccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read l3c ccl-id!\n");
 		return -EINVAL;
 	}
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
index 3130b19e8afc..d7b525f634b9 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
@@ -269,25 +269,22 @@ static void hisi_pa_pmu_clear_int_status(struct hisi_pmu *pa_pmu, int idx)
 static int hisi_pa_pmu_init_data(struct platform_device *pdev,
 				   struct hisi_pmu *pa_pmu)
 {
+	hisi_uncore_pmu_init_topology(pa_pmu, &pdev->dev);
+
 	/*
 	 * As PA PMU is in a SICL, use the SICL_ID and the index ID
 	 * to identify the PA PMU.
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &pa_pmu->topo.sicl_id)) {
+	if (pa_pmu->topo.sicl_id < 0) {
 		dev_err(&pdev->dev, "Cannot read sicl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &pa_pmu->topo.index_id)) {
+	if (pa_pmu->topo.index_id < 0) {
 		dev_err(&pdev->dev, "Cannot read idx-id!\n");
 		return -EINVAL;
 	}
 
-	pa_pmu->topo.ccl_id = -1;
-	pa_pmu->topo.sccl_id = -1;
-
 	pa_pmu->dev_info = device_get_match_data(&pdev->dev);
 	if (!pa_pmu->dev_info)
 		return -ENODEV;
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 5d4de5f27819..1132822ff97a 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -14,6 +14,7 @@
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/property.h>
 
 #include <asm/cputype.h>
 #include <asm/local64.h>
@@ -530,6 +531,35 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 }
 EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_offline_cpu, HISI_PMU);
 
+/*
+ * Retrieve the topology information from the firmware for the hisi_pmu device.
+ * The topology ID will be -1 if we cannot initialize it, it may either due to
+ * the PMU doesn't locate on this certain topology or the firmware needs to be
+ * fixed.
+ */
+void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct device *dev)
+{
+	struct hisi_pmu_topology *topo = &hisi_pmu->topo;
+
+	topo->sccl_id = -1;
+	topo->ccl_id = -1;
+	topo->index_id = -1;
+	topo->sub_id = -1;
+
+	if (device_property_read_u32(dev, "hisilicon,scl-id", &topo->sccl_id))
+		dev_dbg(dev, "no scl-id present\n");
+
+	if (device_property_read_u32(dev, "hisilicon,ccl-id", &topo->ccl_id))
+		dev_dbg(dev, "no ccl-id present\n");
+
+	if (device_property_read_u32(dev, "hisilicon,idx-id", &topo->index_id))
+		dev_dbg(dev, "no idx-id present\n");
+
+	if (device_property_read_u32(dev, "hisilicon,sub-id", &topo->sub_id))
+		dev_dbg(dev, "no sub-id present\n");
+}
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_init_topology, HISI_PMU);
+
 void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 {
 	struct pmu *pmu = &hisi_pmu->pmu;
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
index f162a1b6c6d1..53b1331b8565 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
@@ -160,6 +160,7 @@ ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
 					     char *page);
 int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
 			     struct platform_device *pdev);
+void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct device *dev);
 
 void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module);
 #endif /* __HISI_UNCORE_PMU_H__ */
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
index 276534c12fa4..a342ef3d9916 100644
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
@@ -288,25 +288,22 @@ MODULE_DEVICE_TABLE(acpi, hisi_sllc_pmu_acpi_match);
 static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
 				   struct hisi_pmu *sllc_pmu)
 {
+	hisi_uncore_pmu_init_topology(sllc_pmu, &pdev->dev);
+
 	/*
 	 * Use the SCCL_ID and the index ID to identify the SLLC PMU,
 	 * while SCCL_ID is from MPIDR_EL1 by CPU.
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &sllc_pmu->topo.sccl_id)) {
+	if (sllc_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Cannot read sccl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &sllc_pmu->topo.index_id)) {
+	if (sllc_pmu->topo.index_id < 0) {
 		dev_err(&pdev->dev, "Cannot read idx-id!\n");
 		return -EINVAL;
 	}
 
-	/* SLLC PMUs only share the same SCCL */
-	sllc_pmu->topo.ccl_id = -1;
-
 	sllc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(sllc_pmu->base)) {
 		dev_err(&pdev->dev, "ioremap failed for sllc_pmu resource.\n");
diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
index 19a44498758f..2df8976ab4be 100644
--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
@@ -11,7 +11,6 @@
 #include <linux/irq.h>
 #include <linux/list.h>
 #include <linux/mod_devicetable.h>
-#include <linux/property.h>
 
 #include "hisi_uncore_pmu.h"
 
@@ -366,25 +365,24 @@ static void hisi_uc_pmu_clear_int_status(struct hisi_pmu *uc_pmu, int idx)
 static int hisi_uc_pmu_init_data(struct platform_device *pdev,
 				 struct hisi_pmu *uc_pmu)
 {
+	hisi_uncore_pmu_init_topology(uc_pmu, &pdev->dev);
+
 	/*
 	 * Use SCCL (Super CPU Cluster) ID and CCL (CPU Cluster) ID to
 	 * identify the topology information of UC PMU devices in the chip.
 	 * They have some CCLs per SCCL and then 4 UC PMU per CCL.
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &uc_pmu->topo.sccl_id)) {
+	if (uc_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read uc sccl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-				     &uc_pmu->topo.ccl_id)) {
+	if (uc_pmu->topo.ccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read uc ccl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-				     &uc_pmu->topo.sub_id)) {
+	if (uc_pmu->topo.sub_id < 0) {
 		dev_err(&pdev->dev, "Can not read sub-id!\n");
 		return -EINVAL;
 	}
-- 
2.24.0



From andre.draszik at linaro.org  Tue Dec  3 04:40:23 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:40:23 +0000
Subject: [PATCH v2 0/5] Google Pixel 6 (oriole): TCPCI enablement & USB
 updates
Message-ID: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>

Hi,

This series adds and enables the Maxim MAX77759 TCPCI for Google Pixel
6 (Oriole).

It relies on the bindings updates proposed as part of
https://lore.kernel.org/all/20241203-dtbinding-max77759-v3-1-e1a1d86aca8e at linaro.org/
and
https://lore.kernel.org/all/20241203-gs101-phy-lanes-orientation-phy-v2-2-40dcf1b7670d at linaro.org/

With these patches, we allow the usb phy to detect usb cable
orientation, and we make it possible for the USB DWC3 core to enter
runtime suspend upon cable disconnect.

To: Catalin Marinas <catalin.marinas at arm.com>
To: Will Deacon <will at kernel.org>
To: Peter Griffin <peter.griffin at linaro.org>
To: Rob Herring <robh at kernel.org>
To: Krzysztof Kozlowski <krzk+dt at kernel.org>
To: Conor Dooley <conor+dt at kernel.org>
To: Alim Akhtar <alim.akhtar at samsung.com>
Cc: Peter Griffin <peter.griffin at linaro.org>
Cc: Tudor Ambarus <tudor.ambarus at linaro.org>
Cc: Sam Protsenko <semen.protsenko at linaro.org>
Cc: Will McVicker <willmcvicker at google.com>   
Cc: Roy Luo <royluo at google.com>
Cc: kernel-team at android.com
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-samsung-soc at vger.kernel.org
Cc: devicetree at vger.kernel.org
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

Changes in v2:
- more appropriate dwc3 quirks to achieve reliable Vbus state detection (patch 3)
- drop patch 'dt-bindings: usb: max33359: add max77759 flavor' from
  this series as it should go via linux-usb (Krzysztof)
- max77759 tcpci compatible has changed
- Link to v1: https://lore.kernel.org/r/20241127-gs101-phy-lanes-orientation-dts-v1-0-5222d8508b71 at linaro.org

---
Andr? Draszik (5):
      arm64: defconfig: enable Maxim TCPCI driver
      arm64: dts: exynos: gs101: phy region for exynos5-usbdrd is larger
      arm64: dts: exynos: gs101: allow stable USB phy Vbus detection
      arm64: dts: exynos: gs101-oriole: enable Maxim max77759 TCPCi
      arm64: dts: exynos: gs101-oriole: add pd-disable and typec-power-opmode

 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 104 +++++++++++++++++++++
 arch/arm64/boot/dts/exynos/google/gs101.dtsi       |   5 +-
 arch/arm64/configs/defconfig                       |   1 +
 3 files changed, 109 insertions(+), 1 deletion(-)
---
base-commit: ed9a4ad6e5bd3a443e81446476718abebee47e82
change-id: 20241127-gs101-phy-lanes-orientation-dts-9ace74a2c25c

Best regards,
-- 
Andr? Draszik <andre.draszik at linaro.org>



From andre.draszik at linaro.org  Tue Dec  3 04:40:24 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:40:24 +0000
Subject: [PATCH v2 1/5] arm64: defconfig: enable Maxim TCPCI driver
In-Reply-To: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-dts-v2-1-1412783a6b01@linaro.org>

Enable the Maxim max33359 as this is used by the gs101-oriole (Google
Pixel 6) board.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index d13218d0c30f..5080fe2ce776 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1121,6 +1121,7 @@ CONFIG_USB_MASS_STORAGE=m
 CONFIG_TYPEC=m
 CONFIG_TYPEC_TCPM=m
 CONFIG_TYPEC_TCPCI=m
+CONFIG_TYPEC_TCPCI_MAXIM=m
 CONFIG_TYPEC_FUSB302=m
 CONFIG_TYPEC_QCOM_PMIC=m
 CONFIG_TYPEC_UCSI=m

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:40:25 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:40:25 +0000
Subject: [PATCH v2 2/5] arm64: dts: exynos: gs101: phy region for
 exynos5-usbdrd is larger
In-Reply-To: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-dts-v2-2-1412783a6b01@linaro.org>

Turns out there are some additional registers in the phy region, update
the DT accordingly.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 302c5beb224a..18d4e7852a1a 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -1267,7 +1267,7 @@ cmu_hsi0: clock-controller at 11000000 {
 
 		usbdrd31_phy: phy at 11100000 {
 			compatible = "google,gs101-usb31drd-phy";
-			reg = <0x11100000 0x0100>,
+			reg = <0x11100000 0x0200>,
 			      <0x110f0000 0x0800>,
 			      <0x110e0000 0x2800>;
 			reg-names = "phy", "pcs", "pma";

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:40:26 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:40:26 +0000
Subject: [PATCH v2 3/5] arm64: dts: exynos: gs101: allow stable USB phy
 Vbus detection
In-Reply-To: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-dts-v2-3-1412783a6b01@linaro.org>

For the DWC3 core to reliably detect the connected phy's Vbus state, we
need to disable phy suspend.

Add
    snps,dis_u2_susphy_quirk
    snps,dis_u3_susphy_quirk
to do that.

While at it, also add
    snps,has-lpm-erratum
as this is set downstream which implies that the core was configured
with LPM Erratum. We should do the same here.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
- drop snps,dis_rxdet_inp3_quirk and instead use the mentioned
  properties. The former alone wasn't reliable enough in all
  situations, e.g. when attached to certain USB hubs.
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 18d4e7852a1a..c5335dd59dfe 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -1302,6 +1302,9 @@ usbdrd31_dwc3: usb at 0 {
 				interrupts = <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH 0>;
 				phys = <&usbdrd31_phy 0>, <&usbdrd31_phy 1>;
 				phy-names = "usb2-phy", "usb3-phy";
+				snps,has-lpm-erratum;
+				snps,dis_u2_susphy_quirk;
+				snps,dis_u3_susphy_quirk;
 				status = "disabled";
 			};
 		};

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:40:27 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:40:27 +0000
Subject: [PATCH v2 4/5] arm64: dts: exynos: gs101-oriole: enable Maxim
 max77759 TCPCi
In-Reply-To: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-dts-v2-4-1412783a6b01@linaro.org>

On Pixel 6 (and Pro), a max77759 companion PMIC for USB Type-C
applications is used, which contains four functional blocks (at
distinct I2C addresses):
  * top (including GPIO)
  * charger
  * fuel gauge
  * TCPCi

While in the same package, TCPCi and Fuel Gauge have separate I2C
addresses, interrupt lines and interrupt status registers and can be
treated independently.

The TCPCi is required to detect and handle connector orientation in
Pixel's USB PHY driver, and to configure the USB controller's role
(host vs device).

This change adds the TCPCi part as it can be independent and doesn't
need a top-level MFD.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* compatible has changed to maxim,max77759-tcpci
* clarify that GPIO is actually part of 'top' in commit message, not
  separate
---
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 99 ++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
index 387fb779bd29..a5cbf1e10c7b 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
@@ -10,6 +10,7 @@
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
+#include <dt-bindings/usb/pd.h>
 #include "gs101-pinctrl.h"
 #include "gs101.dtsi"
 
@@ -90,6 +91,84 @@ eeprom: eeprom at 50 {
 &hsi2c_12 {
 	status = "okay";
 	/* TODO: add the devices once drivers exist */
+
+	usb-typec at 25 {
+		compatible = "maxim,max77759-tcpci", "maxim,max33359";
+		reg = <0x25>;
+		interrupts-extended = <&gpa8 2 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-0 = <&typec_int>;
+		pinctrl-names = "default";
+
+		connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "dual";
+			self-powered;
+			try-power-role = "sink";
+			op-sink-microwatt = <2600000>;
+			new-source-frs-typec-current = <FRS_5V_1P5A>;
+			slow-charger-loop;
+			/*
+			 * max77759 operating in reverse boost mode (0xA) can
+			 * source up to 1.5A while extboost can only do ~1A.
+			 * Since extboost is the primary path, advertise 900mA.
+			 */
+			source-pdos = <PDO_FIXED(5000, 900,
+						 (PDO_FIXED_SUSPEND
+						  | PDO_FIXED_USB_COMM
+						  | PDO_FIXED_DATA_SWAP
+						  | PDO_FIXED_DUAL_ROLE))>;
+			sink-pdos = <PDO_FIXED(5000, 3000,
+					       (PDO_FIXED_DATA_SWAP
+						| PDO_FIXED_USB_COMM
+						| PDO_FIXED_HIGHER_CAP
+						| PDO_FIXED_DUAL_ROLE))
+				     PDO_FIXED(9000, 2200, 0)
+				     PDO_PPS_APDO(5000, 11000, 3000)>;
+			sink-vdos = <VDO_IDH(1, 1, IDH_PTYPE_PERIPH, 0,
+					     IDH_PTYPE_DFP_HOST, 2, 0x18d1)
+				     VDO_CERT(0x0)
+				     VDO_PRODUCT(0x4ee1, 0x0)
+				     VDO_UFP(UFP_VDO_VER1_2,
+					     (DEV_USB2_CAPABLE
+					      | DEV_USB3_CAPABLE),
+					     UFP_RECEPTACLE, 0,
+					     AMA_VCONN_NOT_REQ, 0,
+					     UFP_ALTMODE_NOT_SUPP,
+					     UFP_USB32_GEN1)
+				     /* padding */ 0
+				     VDO_DFP(DFP_VDO_VER1_1,
+					     (HOST_USB2_CAPABLE
+					      | HOST_USB3_CAPABLE),
+					     DFP_RECEPTACLE, 0)>;
+			sink-vdos-v1 = <VDO_IDH(1, 1, IDH_PTYPE_PERIPH, 0,
+						0, 0, 0x18d1)
+					VDO_CERT(0x0)
+					VDO_PRODUCT(0x4ee1, 0x0)>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_orien_sw: endpoint {
+						remote-endpoint = <&usbdrd31_phy_orien_switch>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_role_sw: endpoint {
+						remote-endpoint = <&usbdrd31_dwc3_role_switch>;
+					};
+				};
+			};
+		};
+	};
 };
 
 &pinctrl_far_alive {
@@ -106,6 +185,13 @@ key_volup: key-volup-pins {
 		samsung,pin-pud = <GS101_PIN_PULL_NONE>;
 		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
 	};
+
+	typec_int: typec-int-pins {
+		samsung,pins = "gpa8-2";
+		samsung,pin-function = <GS101_PIN_FUNC_EINT>;
+		samsung,pin-pud = <GS101_PIN_PULL_UP>;
+		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
+	};
 };
 
 &pinctrl_gpio_alive {
@@ -142,9 +228,16 @@ &usbdrd31_dwc3 {
 	role-switch-default-mode = "peripheral";
 	maximum-speed = "super-speed-plus";
 	status = "okay";
+
+	port {
+		usbdrd31_dwc3_role_switch: endpoint {
+			remote-endpoint = <&usbc0_role_sw>;
+		};
+	};
 };
 
 &usbdrd31_phy {
+	orientation-switch;
 	/* TODO: Update these once PMIC is implemented */
 	pll-supply = <&reg_placeholder>;
 	dvdd-usb20-supply = <&reg_placeholder>;
@@ -153,6 +246,12 @@ &usbdrd31_phy {
 	vdda-usbdp-supply = <&reg_placeholder>;
 	vddh-usbdp-supply = <&reg_placeholder>;
 	status = "okay";
+
+	port {
+		usbdrd31_phy_orien_switch: endpoint {
+			remote-endpoint = <&usbc0_orien_sw>;
+		};
+	};
 };
 
 &usi_uart {

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Tue Dec  3 04:40:28 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 12:40:28 +0000
Subject: [PATCH v2 5/5] arm64: dts: exynos: gs101-oriole: add pd-disable
 and typec-power-opmode
In-Reply-To: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
Message-ID: <20241203-gs101-phy-lanes-orientation-dts-v2-5-1412783a6b01@linaro.org>

When the serial console is enabled, we need to disable power delivery
since serial uses the SBU1/2 pins and appears to confuse the TCPCI,
resulting in endless interrupts.

For now, change the DT such that the serial console continues working.

Note1: We can not have both typec-power-opmode and
new-source-frs-typec-current active at the same time, as otherwise DT
binding checks complain.

Note2: When using a downstream DT, the Pixel boot-loader will modify
the DT accordingly before boot, but for this upstream DT it doesn't
know where to find the TCPCI node. The intention is for this commit to
be reverted once an updated Pixel boot-loader becomes available.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
index a5cbf1e10c7b..e58881c61d53 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
@@ -107,7 +107,6 @@ connector {
 			self-powered;
 			try-power-role = "sink";
 			op-sink-microwatt = <2600000>;
-			new-source-frs-typec-current = <FRS_5V_1P5A>;
 			slow-charger-loop;
 			/*
 			 * max77759 operating in reverse boost mode (0xA) can
@@ -146,6 +145,12 @@ VDO_DFP(DFP_VDO_VER1_1,
 						0, 0, 0x18d1)
 					VDO_CERT(0x0)
 					VDO_PRODUCT(0x4ee1, 0x0)>;
+			/*
+			 * Until bootloader is updated to set those two when
+			 * console is enabled, we disable PD here.
+			 */
+			pd-disable;
+			typec-power-opmode = "default";
 
 			ports {
 				#address-cells = <1>;

-- 
2.47.0.338.g60cca15819-goog



From arnd at arndb.de  Tue Dec  3 04:43:03 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 03 Dec 2024 13:43:03 +0100
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org>
References: <20241127-clk-audio-fix-rst-missing-v1-1-9f9d0ab98fce@baylibre.com>
 <12f29978-c8ce-4bee-a447-dcd086eb936d@app.fastmail.com>
 <1ja5dk2y5l.fsf@starbuckisacylon.baylibre.com>
 <f8de4a2a-776f-4c10-b75e-e845bcc38dde@app.fastmail.com>
 <1j4j3r32ld.fsf@starbuckisacylon.baylibre.com>
 <306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com>
 <1jy1131kxz.fsf@starbuckisacylon.baylibre.com>
 <c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com>
 <1jplmf1jqa.fsf@starbuckisacylon.baylibre.com>
 <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com>
 <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org>
Message-ID: <0f07300a-8b32-4d3e-a447-b3fe3cf1ca81@app.fastmail.com>

On Tue, Dec 3, 2024, at 03:53, Stephen Boyd wrote:
> Quoting Arnd Bergmann (2024-11-28 07:34:46)
>> On Thu, Nov 28, 2024, at 16:06, Jerome Brunet wrote:
>> Stephen, can you please take a look here and see if you
>> have a better idea for either decoupling the two drivers
>> enough to avoid the link time dependency, or to reintegrate
>> the reset controller code into the clk driver and avoid
>> the complexity?
>
> I think the best approach is to add the reset auxilary device with a
> function that creates the auxiliary device directly by string name and
> does nothing else. Maybe we can have some helper in the auxiliary
> layer that does that all for us, because it's quite a bit of boiler
> plate that we need to write over and over again. Something like:
>
>   int devm_auxiliary_device_create(struct device *parent, const char *name)
>
> that does the whole kzalloc() + ida dance that
> devm_meson_rst_aux_register() is doing today and wraps it all up so that
> the device is removed when the parent driver unbinds. Then this clk
> driver can register the reset device with a single call and not need to
> do anything besides select AUXILIARY_BUS. The regmap can be acquired
> from the parent device in the auxiliary driver probe with
> dev_get_regmap(adev->parent).

I like the idea. Two questions about the interface:

 - should there be a 'void *platform_data' argument anyway?
   Even if this can be looked up from the parent, it seems
   useful enough

 - What is the scope of the 'ida' number? My impression was
   this should be local to one parent device, but I don't
   know how the number is used in the end, so maybe a global
   number allocator is sufficient.

       Arnd


From broonie at kernel.org  Tue Dec  3 04:39:19 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:19 +0000
Subject: [PATCH v3 0/9] arm64: Support 2024 dpISA extensions
Message-ID: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>

The 2024 architecture release includes a number of data processing
extensions, mostly SVE and SME additions with a few others.  These are
all very straightforward extensions which add instructions but no
architectural state so only need hwcaps and exposing of the ID registers
to KVM guests and userspace.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v3:
- Commit log update for the hwcap test.
- Link to v2: https://lore.kernel.org/r/20241030-arm64-2024-dpisa-v2-0-b6601a15d2a5 at kernel.org

Changes in v2:
- Filter KVM guest visible bitfields in ID_AA64ISAR3_EL1 to only those
  we make writeable.
- Link to v1: https://lore.kernel.org/r/20241028-arm64-2024-dpisa-v1-0-a38d08b008a8 at kernel.org

---
Mark Brown (9):
      arm64/sysreg: Update ID_AA64PFR2_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64FPFR0_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64ZFR0_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64SMFR0_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64ISAR2_EL1 to DDI0601 2024-09
      arm64/hwcap: Describe 2024 dpISA extensions to userspace
      KVM: arm64: Allow control of dpISA extensions in ID_AA64ISAR3_EL1
      kselftest/arm64: Add 2024 dpISA extensions to hwcap test

 Documentation/arch/arm64/elf_hwcaps.rst   |  51 ++++++
 arch/arm64/include/asm/hwcap.h            |  17 ++
 arch/arm64/include/uapi/asm/hwcap.h       |  17 ++
 arch/arm64/kernel/cpufeature.c            |  35 ++++
 arch/arm64/kernel/cpuinfo.c               |  17 ++
 arch/arm64/kvm/sys_regs.c                 |   6 +-
 arch/arm64/tools/sysreg                   |  87 +++++++++-
 tools/testing/selftests/arm64/abi/hwcap.c | 273 +++++++++++++++++++++++++++++-
 8 files changed, 493 insertions(+), 10 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241008-arm64-2024-dpisa-8091074a7f48

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Tue Dec  3 04:39:20 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:20 +0000
Subject: [PATCH v3 1/9] arm64/sysreg: Update ID_AA64PFR2_EL1 to DDI0601
 2024-09
In-Reply-To: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
Message-ID: <20241203-arm64-2024-dpisa-v3-1-a6c78b1aa297@kernel.org>

DDI0601 2024-09 defines a new feature flags in ID_AA64PFR2_EL1
describing support for injecting UNDEF exceptions, update sysreg to
include this.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index b081b54d6d227ed8300a6f129896647316f0b673..911f16c82ebd3ee98ffed965b02a5c6b153bc50c 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1010,7 +1010,12 @@ UnsignedEnum	35:32	FPMR
 	0b0000	NI
 	0b0001	IMP
 EndEnum
-Res0	31:12
+Res0	31:20
+UnsignedEnum	19:16	UINJ
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+Res0	15:12
 UnsignedEnum	11:8	MTEFAR
 	0b0000	NI
 	0b0001	IMP

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:39:21 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:21 +0000
Subject: [PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
Message-ID: <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>

DDI0601 2024-09 defines several new feature flags in ID_AA64ISAR3_EL1,
update our description in sysreg to reflect these.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 911f16c82ebd3ee98ffed965b02a5c6b153bc50c..c5af604eda6a721cedf5c9c68d6f7038156de651 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1566,7 +1566,23 @@ EndEnum
 EndSysreg
 
 Sysreg	ID_AA64ISAR3_EL1	3	0	0	6	3
-Res0	63:16
+Res0	63:32
+UnsignedEnum	31:28	FPRCVT
+	0b0000	NI
+	0b0010	IMP
+EndEnum
+UnsignedEnum	27:24	LSUI
+	0b0000	NI
+	0b0010	IMP
+EndEnum
+UnsignedEnum	23:20	OCCMO
+	0b0000	NI
+	0b0010	IMP
+EndEnum
+UnsignedEnum	19:16	LSFE
+	0b0000	NI
+	0b0010	IMP
+EndEnum
 UnsignedEnum	15:12	PACM
 	0b0000	NI
 	0b0001	TRIVIAL_IMP

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:39:22 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:22 +0000
Subject: [PATCH v3 3/9] arm64/sysreg: Update ID_AA64FPFR0_EL1 to DDI0601
 2024-09
In-Reply-To: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
Message-ID: <20241203-arm64-2024-dpisa-v3-3-a6c78b1aa297@kernel.org>

DDI0601 2024-09 defines two new feature flags in ID_AA64FPFR0_EL1
describing new FP8 operations, describe them in sysreg.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index c5af604eda6a721cedf5c9c68d6f7038156de651..b44ab511cf5d9d33efd7dca304d0e2f53ce47810 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1180,7 +1180,15 @@ UnsignedEnum	28	F8DP2
 	0b0	NI
 	0b1	IMP
 EndEnum
-Res0	27:2
+UnsignedEnum	27	F8MM8
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	26	F8MM4
+	0b0	NI
+	0b1	IMP
+EndEnum
+Res0	25:2
 UnsignedEnum	1	F8E4M3
 	0b0	NI
 	0b1	IMP

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:39:23 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:23 +0000
Subject: [PATCH v3 4/9] arm64/sysreg: Update ID_AA64ZFR0_EL1 to DDI0601
 2024-09
In-Reply-To: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
Message-ID: <20241203-arm64-2024-dpisa-v3-4-a6c78b1aa297@kernel.org>

DDI0601 2024-09 introduces SVE 2.2 as well as a few new optional features,
update sysreg to reflect the changes in ID_AA64ZFR0_EL1 enumerating them.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index b44ab511cf5d9d33efd7dca304d0e2f53ce47810..7e6b204e83270daabd0036c8109b2fdb0e9b700a 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1040,7 +1040,10 @@ UnsignedEnum	55:52	F32MM
 	0b0000	NI
 	0b0001	IMP
 EndEnum
-Res0	51:48
+UnsignedEnum	51:48	F16MM
+	0b0000	NI
+	0b0001	IMP
+EndEnum
 UnsignedEnum	47:44	I8MM
 	0b0000	NI
 	0b0001	IMP
@@ -1058,6 +1061,7 @@ Res0	31:28
 UnsignedEnum	27:24	B16B16
 	0b0000	NI
 	0b0001	IMP
+	0b0010	BFSCALE
 EndEnum
 UnsignedEnum	23:20	BF16
 	0b0000	NI
@@ -1068,16 +1072,22 @@ UnsignedEnum	19:16	BitPerm
 	0b0000	NI
 	0b0001	IMP
 EndEnum
-Res0	15:8
+UnsignedEnum	15:12	EltPerm
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+Res0	11:8
 UnsignedEnum	7:4	AES
 	0b0000	NI
 	0b0001	IMP
 	0b0010	PMULL128
+	0b0011	AES2
 EndEnum
 UnsignedEnum	3:0	SVEver
 	0b0000	IMP
 	0b0001	SVE2
 	0b0010	SVE2p1
+	0b0011	SVE2p2
 EndEnum
 EndSysreg
 

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:39:24 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:24 +0000
Subject: [PATCH v3 5/9] arm64/sysreg: Update ID_AA64SMFR0_EL1 to DDI0601
 2024-09
In-Reply-To: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
Message-ID: <20241203-arm64-2024-dpisa-v3-5-a6c78b1aa297@kernel.org>

DDI0601 2024-09 introduces SME 2.2 as well as a few new optional features,
update sysreg to reflect the changes in ID_AA64SMFR0_EL1 enumerating them.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 7e6b204e83270daabd0036c8109b2fdb0e9b700a..0253d3847aeb2294da04b2b0b3f33f81f32c849f 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1105,6 +1105,7 @@ UnsignedEnum	59:56	SMEver
 	0b0000	SME
 	0b0001	SME2
 	0b0010	SME2p1
+	0b0011	SME2p2
 	0b0000	IMP
 EndEnum
 UnsignedEnum	55:52	I16I64
@@ -1169,7 +1170,36 @@ UnsignedEnum	28	SF8DP2
 	0b0	NI
 	0b1	IMP
 EndEnum
-Res0	27:0
+UnsignedEnum	27	SF8MM8
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	26	SF8MM4
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	25	SBitPerm
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	24	AES
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	23	SFEXPA
+	0b0	NI
+	0b1	IMP
+EndEnum
+Res0	22:17
+UnsignedEnum	16	STMOP
+	0b0	NI
+	0b1	IMP
+EndEnum
+Res0	15:1
+UnsignedEnum	0	SMOP4
+	0b0	NI
+	0b1	IMP
+EndEnum
 EndSysreg
 
 Sysreg	ID_AA64FPFR0_EL1	3	0	0	4	7

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:39:25 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:25 +0000
Subject: [PATCH v3 6/9] arm64/sysreg: Update ID_AA64ISAR2_EL1 to DDI0601
 2024-09
In-Reply-To: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
Message-ID: <20241203-arm64-2024-dpisa-v3-6-a6c78b1aa297@kernel.org>

DDI0601 2024-09 introduces new features which are enumerated via
ID_AA64ISAR2_EL1, update the sysreg file to reflect these updates.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 0253d3847aeb2294da04b2b0b3f33f81f32c849f..fe55c04624de74a6c1a5e0be45363b9c46ff1340 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1556,12 +1556,16 @@ EndEnum
 UnsignedEnum	55:52	CSSC
 	0b0000	NI
 	0b0001	IMP
+	0b0010	CMPBR
 EndEnum
 UnsignedEnum	51:48	RPRFM
 	0b0000	NI
 	0b0001	IMP
 EndEnum
-Res0	47:44
+UnsignedEnum	47:44	PCDPHINT
+	0b0000	NI
+	0b0001	IMP
+EndEnum
 UnsignedEnum	43:40	PRFMSLC
 	0b0000	NI
 	0b0001	IMP

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:39:26 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:26 +0000
Subject: [PATCH v3 7/9] arm64/hwcap: Describe 2024 dpISA extensions to
 userspace
In-Reply-To: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
Message-ID: <20241203-arm64-2024-dpisa-v3-7-a6c78b1aa297@kernel.org>

The 2024 dpISA introduces a number of architecture features all of which
only add new instructions so only require the addition of hwcaps and ID
register visibility.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arch/arm64/elf_hwcaps.rst | 51 +++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/hwcap.h          | 17 +++++++++++
 arch/arm64/include/uapi/asm/hwcap.h     | 17 +++++++++++
 arch/arm64/kernel/cpufeature.c          | 35 ++++++++++++++++++++++
 arch/arm64/kernel/cpuinfo.c             | 17 +++++++++++
 5 files changed, 137 insertions(+)

diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst
index 2ff922a406ad83d0dff8104a6e362ac6b02d0e1f..7c99894ca3e8f5433b1a0db6a4679395e5cd9ecc 100644
--- a/Documentation/arch/arm64/elf_hwcaps.rst
+++ b/Documentation/arch/arm64/elf_hwcaps.rst
@@ -174,6 +174,57 @@ HWCAP_GCS
     Functionality implied by ID_AA64PFR1_EL1.GCS == 0b1, as
     described by Documentation/arch/arm64/gcs.rst.
 
+HWCAP_CMPBR
+    Functionality implied by ID_AA64ISAR2_EL1.CSSC == 0b0010.
+
+HWCAP_FPRCVT
+    Functionality implied by ID_AA64ISAR3_EL1.FPRCVT == 0b0001.
+
+HWCAP_F8MM8
+    Functionality implied by ID_AA64FPFR0_EL1.F8MM8 == 0b0001.
+
+HWCAP_F8MM4
+    Functionality implied by ID_AA64FPFR0_EL1.F8MM4 == 0b0001.
+
+HWCAP_SVE_F16MM
+    Functionality implied by ID_AA64ZFR0_EL1.F16MM == 0b0001.
+
+HWCAP_SVE_ELTPERM
+    Functionality implied by ID_AA64ZFR0_EL1.ELTPERM == 0b0001.
+
+HWCAP_SVE_AES2
+    Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0011.
+
+HWCAP_SVE_BFSCALE
+    Functionality implied by ID_AA64ZFR0_EL1.B16B16 == 0b0010.
+
+HWCAP_SVE2P2
+    Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0011.
+
+HWCAP_SME2P2
+    Functionality implied by ID_AA64SMFR0_EL1.SMEver == 0b0011.
+
+HWCAP_SME_SF8MM8
+    Functionality implied by ID_AA64SMFR0_EL1.SF8MM8 == 0b1.
+
+HWCAP_SME_SF8MM4
+    Functionality implied by ID_AA64SMFR0_EL1.SF8MM4 == 0b1.
+
+HWCAP_SME_SBITPERM
+    Functionality implied by ID_AA64SMFR0_EL1.SBitPerm == 0b1.
+
+HWCAP_SME_AES
+    Functionality implied by ID_AA64SMFR0_EL1.AES == 0b1.
+
+HWCAP_SME_SFEXPA
+    Functionality implied by ID_AA64SMFR0_EL1.SFEXPA == 0b1.
+
+HWCAP_SME_STMOP
+    Functionality implied by ID_AA64SMFR0_EL1.STMOP == 0b1.
+
+HWCAP_SME_SMOP4
+    Functionality implied by ID_AA64SMFR0_EL1.SMOP4 == 0b1.
+
 HWCAP2_DCPODP
     Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010.
 
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 2b6c61c608e2cd107503b09aba5aaeab639b759a..dbec921ee39c8c897f3e1e1c84d522b5b57130bb 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -93,6 +93,23 @@
 #define KERNEL_HWCAP_PACA		__khwcap_feature(PACA)
 #define KERNEL_HWCAP_PACG		__khwcap_feature(PACG)
 #define KERNEL_HWCAP_GCS		__khwcap_feature(GCS)
+#define KERNEL_HWCAP_CMPBR		__khwcap_feature(CMPBR)
+#define KERNEL_HWCAP_FPRCVT		__khwcap_feature(FPRCVT)
+#define KERNEL_HWCAP_F8MM8		__khwcap_feature(F8MM8)
+#define KERNEL_HWCAP_F8MM4		__khwcap_feature(F8MM4)
+#define KERNEL_HWCAP_SVE_F16MM		__khwcap_feature(SVE_F16MM)
+#define KERNEL_HWCAP_SVE_ELTPERM	__khwcap_feature(SVE_ELTPERM)
+#define KERNEL_HWCAP_SVE_AES2		__khwcap_feature(SVE_AES2)
+#define KERNEL_HWCAP_SVE_BFSCALE	__khwcap_feature(SVE_BFSCALE)
+#define KERNEL_HWCAP_SVE2P2		__khwcap_feature(SVE2P2)
+#define KERNEL_HWCAP_SME2P2		__khwcap_feature(SME2P2)
+#define KERNEL_HWCAP_SME_SF8MM8		__khwcap_feature(SME_SF8MM8)
+#define KERNEL_HWCAP_SME_SF8MM4		__khwcap_feature(SME_SF8MM4)
+#define KERNEL_HWCAP_SME_SBITPERM	__khwcap_feature(SME_SBITPERM)
+#define KERNEL_HWCAP_SME_AES		__khwcap_feature(SME_AES)
+#define KERNEL_HWCAP_SME_SFEXPA		__khwcap_feature(SME_SFEXPA)
+#define KERNEL_HWCAP_SME_STMOP		__khwcap_feature(SME_STMOP)
+#define KERNEL_HWCAP_SME_SMOP4		__khwcap_feature(SME_SMOP4)
 
 #define __khwcap2_feature(x)		(const_ilog2(HWCAP2_ ## x) + 64)
 #define KERNEL_HWCAP_DCPODP		__khwcap2_feature(DCPODP)
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index 48d46b768eaec4c307360cd3bee8b564687f4b88..61fbc88d2bfb81d0bad639ed533ac67440ae2fc4 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -56,6 +56,23 @@
 #define HWCAP_PACA		(1 << 30)
 #define HWCAP_PACG		(1UL << 31)
 #define HWCAP_GCS		(1UL << 32)
+#define HWCAP_CMPBR		(1UL << 33)
+#define HWCAP_FPRCVT		(1UL << 34)
+#define HWCAP_F8MM8		(1UL << 35)
+#define HWCAP_F8MM4		(1UL << 36)
+#define HWCAP_SVE_F16MM		(1UL << 37)
+#define HWCAP_SVE_ELTPERM	(1UL << 38)
+#define HWCAP_SVE_AES2		(1UL << 39)
+#define HWCAP_SVE_BFSCALE	(1UL << 40)
+#define HWCAP_SVE2P2		(1UL << 41)
+#define HWCAP_SME2P2		(1UL << 42)
+#define HWCAP_SME_SF8MM8	(1UL << 43)
+#define HWCAP_SME_SF8MM4	(1UL << 44)
+#define HWCAP_SME_SBITPERM	(1UL << 45)
+#define HWCAP_SME_AES		(1UL << 46)
+#define HWCAP_SME_SFEXPA	(1UL << 47)
+#define HWCAP_SME_STMOP		(1UL << 48)
+#define HWCAP_SME_SMOP4		(1UL << 49)
 
 /*
  * HWCAP2 flags - for AT_HWCAP2
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed84f9056196bb21bbfac61c9687e30..7ba73fdee6deb57cd745ff684eeb97f66d2ea85f 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -268,6 +268,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64isar3[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR3_EL1_FPRCVT_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR3_EL1_FAMINMAX_SHIFT, 4, 0),
 	ARM64_FTR_END,
 };
@@ -317,6 +318,8 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_F64MM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_F32MM_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
+		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_F16MM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_I8MM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
@@ -329,6 +332,8 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_BF16_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_BitPerm_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
+		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_EltPerm_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_AES_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
@@ -373,6 +378,20 @@ static const struct arm64_ftr_bits ftr_id_aa64smfr0[] = {
 		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8DP4_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
 		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8DP2_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8MM8_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8MM4_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SBitPerm_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_AES_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SFEXPA_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_STMOP_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SMOP4_SHIFT, 1, 0),
 	ARM64_FTR_END,
 };
 
@@ -381,6 +400,8 @@ static const struct arm64_ftr_bits ftr_id_aa64fpfr0[] = {
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8FMA_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8DP4_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8DP2_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8MM8_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8MM4_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8E4M3_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8E5M2_SHIFT, 1, 0),
 	ARM64_FTR_END,
@@ -3092,12 +3113,15 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64MMFR2_EL1, AT, IMP, CAP_HWCAP, KERNEL_HWCAP_USCAT),
 #ifdef CONFIG_ARM64_SVE
 	HWCAP_CAP(ID_AA64PFR0_EL1, SVE, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2p2, CAP_HWCAP, KERNEL_HWCAP_SVE2P2),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, AES, AES2, CAP_HWCAP, KERNEL_HWCAP_SVE_AES2),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_B16B16),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, B16B16, BFSCALE, CAP_HWCAP, KERNEL_HWCAP_SVE_BFSCALE),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
@@ -3105,6 +3129,8 @@ 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),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, F16MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_F16MM),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, EltPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_ELTPERM),
 #endif
 #ifdef CONFIG_ARM64_GCS
 	HWCAP_CAP(ID_AA64PFR1_EL1, GCS, IMP, CAP_HWCAP, KERNEL_HWCAP_GCS),
@@ -3124,6 +3150,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64MMFR0_EL1, ECV, IMP, CAP_HWCAP, KERNEL_HWCAP_ECV),
 	HWCAP_CAP(ID_AA64MMFR1_EL1, AFP, IMP, CAP_HWCAP, KERNEL_HWCAP_AFP),
 	HWCAP_CAP(ID_AA64ISAR2_EL1, CSSC, IMP, CAP_HWCAP, KERNEL_HWCAP_CSSC),
+	HWCAP_CAP(ID_AA64ISAR2_EL1, CSSC, CMPBR, CAP_HWCAP, KERNEL_HWCAP_CMPBR),
 	HWCAP_CAP(ID_AA64ISAR2_EL1, RPRFM, IMP, CAP_HWCAP, KERNEL_HWCAP_RPRFM),
 	HWCAP_CAP(ID_AA64ISAR2_EL1, RPRES, IMP, CAP_HWCAP, KERNEL_HWCAP_RPRES),
 	HWCAP_CAP(ID_AA64ISAR2_EL1, WFxT, IMP, CAP_HWCAP, KERNEL_HWCAP_WFXT),
@@ -3133,6 +3160,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64PFR1_EL1, SME, IMP, CAP_HWCAP, KERNEL_HWCAP_SME),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, FA64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_FA64),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, LUTv2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_LUTV2),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2p2, CAP_HWCAP, KERNEL_HWCAP_SME2P2),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2p1, CAP_HWCAP, KERNEL_HWCAP_SME2P1),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2, CAP_HWCAP, KERNEL_HWCAP_SME2),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, I16I64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64),
@@ -3150,6 +3178,13 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8FMA),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP4),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP2),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8MM8, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8MM8),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8MM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8MM4),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SBitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SBITPERM),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_AES),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SFEXPA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SFEXPA),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, STMOP, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_STMOP),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SMOP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SMOP4),
 #endif /* CONFIG_ARM64_SME */
 	HWCAP_CAP(ID_AA64FPFR0_EL1, F8CVT, IMP, CAP_HWCAP, KERNEL_HWCAP_F8CVT),
 	HWCAP_CAP(ID_AA64FPFR0_EL1, F8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_F8FMA),
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index d79e88fccdfce427507e7a34c5959ce6309cbd12..9861291843d8fbcc5f8e68e2b9eaac65a0b37c22 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -145,6 +145,23 @@ static const char *const hwcap_str[] = {
 	[KERNEL_HWCAP_SME_SF8DP4]	= "smesf8dp4",
 	[KERNEL_HWCAP_SME_SF8DP2]	= "smesf8dp2",
 	[KERNEL_HWCAP_POE]		= "poe",
+	[KERNEL_HWCAP_CMPBR]		= "cmpbr",
+	[KERNEL_HWCAP_FPRCVT]		= "fprcvt",
+	[KERNEL_HWCAP_F8MM8]		= "f8mm8",
+	[KERNEL_HWCAP_F8MM4]		= "f8mm4",
+	[KERNEL_HWCAP_SVE_F16MM]	= "svef16mm",
+	[KERNEL_HWCAP_SVE_ELTPERM]	= "sveeltperm",
+	[KERNEL_HWCAP_SVE_AES2]		= "sveaes2",
+	[KERNEL_HWCAP_SVE_BFSCALE]	= "svebfscale",
+	[KERNEL_HWCAP_SVE2P2]		= "sve2p2",
+	[KERNEL_HWCAP_SME2P2]		= "sme2p2",
+	[KERNEL_HWCAP_SME_SF8MM8]	= "smesf8mm8",
+	[KERNEL_HWCAP_SME_SF8MM4]	= "smesf8mm4",
+	[KERNEL_HWCAP_SME_SBITPERM]	= "smesbitperm",
+	[KERNEL_HWCAP_SME_AES]		= "smeaes",
+	[KERNEL_HWCAP_SME_SFEXPA]	= "smesfexpa",
+	[KERNEL_HWCAP_SME_STMOP]	= "smestmop",
+	[KERNEL_HWCAP_SME_SMOP4]	= "smesmop4",
 };
 
 #ifdef CONFIG_COMPAT

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:39:27 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:27 +0000
Subject: [PATCH v3 8/9] KVM: arm64: Allow control of dpISA extensions in
 ID_AA64ISAR3_EL1
In-Reply-To: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
Message-ID: <20241203-arm64-2024-dpisa-v3-8-a6c78b1aa297@kernel.org>

ID_AA64ISAR3_EL1 is currently marked as unallocated in KVM but does have a
number of bitfields defined in it. Expose FPRCVT and FAMINMAX, two simple
instruction only extensions to guests.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 83c6b4a07ef56cf0ed9c8751ec80686f45dca6b2..6efbe3f4a579afd1874c4cf844c1c1249ae8b942 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1604,6 +1604,9 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
 		if (!cpus_have_final_cap(ARM64_HAS_WFXT))
 			val &= ~ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_WFxT);
 		break;
+	case SYS_ID_AA64ISAR3_EL1:
+		val &= ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_FAMINMAX;
+		break;
 	case SYS_ID_AA64MMFR2_EL1:
 		val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK;
 		break;
@@ -2608,7 +2611,8 @@ 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_FPRCVT |
+				       ID_AA64ISAR3_EL1_FAMINMAX)),
 	ID_UNALLOCATED(6,4),
 	ID_UNALLOCATED(6,5),
 	ID_UNALLOCATED(6,6),

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:39:28 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:39:28 +0000
Subject: [PATCH v3 9/9] kselftest/arm64: Add 2024 dpISA extensions to hwcap
 test
In-Reply-To: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
Message-ID: <20241203-arm64-2024-dpisa-v3-9-a6c78b1aa297@kernel.org>

Add coverage of the hwcaps for the 2024 dpISA extensions to the hwcap
test.

We don't actually test SIGILL generation for CMPBR since the need to
branch makes it a pain to generate and the SIGILL detection would be
unreliable anyway. Since this should be very unusual we provide a stub
function rather than supporting a missing test.

The sigill functions aren't well sorted in the file so the ordering is a
bit random.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/hwcap.c | 273 +++++++++++++++++++++++++++++-
 1 file changed, 271 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c
index 0029ed9c5c9aa4451f3d0573ee672eca993fb2f4..2a230cfa4cb4108580a16161e2df03a513710dbc 100644
--- a/tools/testing/selftests/arm64/abi/hwcap.c
+++ b/tools/testing/selftests/arm64/abi/hwcap.c
@@ -46,6 +46,12 @@ static void atomics_sigill(void)
 	asm volatile(".inst 0xb82003ff" : : : );
 }
 
+static void cmpbr_sigill(void)
+{
+	/* Not implemented, too complicated and unreliable anyway */
+}
+
+
 static void crc32_sigill(void)
 {
 	/* CRC32W W0, W0, W1 */
@@ -82,6 +88,18 @@ static void f8fma_sigill(void)
 	asm volatile(".inst 0xec0fc00");
 }
 
+static void f8mm4_sigill(void)
+{
+	/* FMMLA V0.4SH, V0.16B, V0.16B */
+	asm volatile(".inst 0x6e00ec00");
+}
+
+static void f8mm8_sigill(void)
+{
+	/* FMMLA V0.4S, V0.16B, V0.16B */
+	asm volatile(".inst 0x6e80ec00");
+}
+
 static void faminmax_sigill(void)
 {
 	/* FAMIN V0.4H, V0.4H, V0.4H */
@@ -98,6 +116,12 @@ static void fpmr_sigill(void)
 	asm volatile("mrs x0, S3_3_C4_C4_2" : : : "x0");
 }
 
+static void fprcvt_sigill(void)
+{
+	/* FCVTAS S0, H0 */
+	asm volatile(".inst 0x1efa0000");
+}
+
 static void gcs_sigill(void)
 {
 	unsigned long *gcspr;
@@ -226,6 +250,42 @@ static void sme2p1_sigill(void)
 	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
 }
 
+static void sme2p2_sigill(void)
+{
+	/* SMSTART SM */
+	asm volatile("msr S0_3_C4_C3_3, xzr" : : : );
+
+	/* UXTB Z0.D, P0/Z, Z0.D  */
+	asm volatile(".inst 0x4c1a000" : : : );
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void sme_aes_sigill(void)
+{
+	/* SMSTART SM */
+	asm volatile("msr S0_3_C4_C3_3, xzr" : : : );
+
+	/* AESD z0.b, z0.b, z0.b */
+	asm volatile(".inst 0x4522e400" : : : "z0");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void sme_sbitperm_sigill(void)
+{
+	/* SMSTART SM */
+	asm volatile("msr S0_3_C4_C3_3, xzr" : : : );
+
+	/* BDEP Z0.B, Z0.B, Z0.B */
+	asm volatile(".inst 0x4500b400" : : : "z0");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
 static void smei16i32_sigill(void)
 {
 	/* SMSTART */
@@ -334,13 +394,73 @@ static void smesf8dp4_sigill(void)
 	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
 }
 
+static void smesf8mm8_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* FMMLA V0.4S, V0.16B, V0.16B */
+	asm volatile(".inst 0x6e80ec00");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smesf8mm4_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* FMMLA V0.4SH, V0.16B, V0.16B */
+	asm volatile(".inst 0x6e00ec00");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
 static void smesf8fma_sigill(void)
 {
 	/* SMSTART */
 	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
 
-	/* FMLALB V0.8H, V0.16B, V0.16B */
-	asm volatile(".inst 0xec0fc00");
+	/* FMLALB Z0.8H, Z0.B, Z0.B */
+	asm volatile(".inst 0x64205000");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smesfexpa_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* FEXPA Z0.D, Z0.D */
+	asm volatile(".inst 0x04e0b800");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smesmop4_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* SMOP4A ZA0.S, Z0.B, { Z0.B - Z1.B } */
+	asm volatile(".inst 0x80108000");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smestmop_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* STMOPA ZA0.S, { Z0.H - Z1.H }, Z0.H, Z20[0] */
+	asm volatile(".inst 0x80408008");
 
 	/* SMSTOP */
 	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
@@ -364,18 +484,42 @@ static void sve2p1_sigill(void)
 	asm volatile(".inst 0x65000000" : : : "z0");
 }
 
+static void sve2p2_sigill(void)
+{
+	/* NOT Z0.D, P0/Z, Z0.D */
+	asm volatile(".inst 0x4cea000" : : : "z0");
+}
+
 static void sveaes_sigill(void)
 {
 	/* AESD z0.b, z0.b, z0.b */
 	asm volatile(".inst 0x4522e400" : : : "z0");
 }
 
+static void sveaes2_sigill(void)
+{
+	/* AESD {Z0.B - Z1.B }, { Z0.B - Z1.B }, Z0.Q */
+	asm volatile(".inst 0x4522ec00" : : : "z0");
+}
+
 static void sveb16b16_sigill(void)
 {
 	/* BFADD Z0.H, Z0.H, Z0.H */
 	asm volatile(".inst 0x65000000" : : : );
 }
 
+static void svebfscale_sigill(void)
+{
+	/* BFSCALE Z0.H, P0/M, Z0.H, Z0.H */
+	asm volatile(".inst 0x65098000" : : : "z0");
+}
+
+static void svef16mm_sigill(void)
+{
+	/* FMMLA Z0.S, Z0.H, Z0.H */
+	asm volatile(".inst 0x6420e400");
+}
+
 static void svepmull_sigill(void)
 {
 	/* PMULLB Z0.Q, Z0.D, Z0.D */
@@ -394,6 +538,12 @@ static void svesha3_sigill(void)
 	asm volatile(".inst 0x4203800" : : : "z0");
 }
 
+static void sveeltperm_sigill(void)
+{
+	/* COMPACT Z0.B, P0, Z0.B */
+	asm volatile(".inst 0x5218000" : : : "x0");
+}
+
 static void svesm4_sigill(void)
 {
 	/* SM4E Z0.S, Z0.S, Z0.S */
@@ -469,6 +619,13 @@ static const struct hwcap_data {
 		.cpuinfo = "aes",
 		.sigill_fn = aes_sigill,
 	},
+	{
+		.name = "CMPBR",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_CMPBR,
+		.cpuinfo = "cmpbr",
+		.sigill_fn = cmpbr_sigill,
+	},
 	{
 		.name = "CRC32",
 		.at_hwcap = AT_HWCAP,
@@ -523,6 +680,20 @@ static const struct hwcap_data {
 		.cpuinfo = "f8fma",
 		.sigill_fn = f8fma_sigill,
 	},
+	{
+		.name = "F8MM8",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_F8MM8,
+		.cpuinfo = "f8mm8",
+		.sigill_fn = f8mm8_sigill,
+	},
+	{
+		.name = "F8MM4",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_F8MM4,
+		.cpuinfo = "f8mm4",
+		.sigill_fn = f8mm4_sigill,
+	},
 	{
 		.name = "FAMINMAX",
 		.at_hwcap = AT_HWCAP2,
@@ -545,6 +716,13 @@ static const struct hwcap_data {
 		.sigill_fn = fpmr_sigill,
 		.sigill_reliable = true,
 	},
+	{
+		.name = "FPRCVT",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_FPRCVT,
+		.cpuinfo = "fprcvt",
+		.sigill_fn = fprcvt_sigill,
+	},
 	{
 		.name = "GCS",
 		.at_hwcap = AT_HWCAP,
@@ -691,6 +869,20 @@ static const struct hwcap_data {
 		.cpuinfo = "sme2p1",
 		.sigill_fn = sme2p1_sigill,
 	},
+	{
+		.name = "SME 2.2",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME2P2,
+		.cpuinfo = "sme2p2",
+		.sigill_fn = sme2p2_sigill,
+	},
+	{
+		.name = "SME AES",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_AES,
+		.cpuinfo = "smeaes",
+		.sigill_fn = sme_aes_sigill,
+	},
 	{
 		.name = "SME I16I32",
 		.at_hwcap = AT_HWCAP2,
@@ -740,6 +932,13 @@ static const struct hwcap_data {
 		.cpuinfo = "smelutv2",
 		.sigill_fn = smelutv2_sigill,
 	},
+	{
+		.name = "SME SBITPERM",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SBITPERM,
+		.cpuinfo = "smesbitperm",
+		.sigill_fn = sme_sbitperm_sigill,
+	},
 	{
 		.name = "SME SF8FMA",
 		.at_hwcap = AT_HWCAP2,
@@ -747,6 +946,20 @@ static const struct hwcap_data {
 		.cpuinfo = "smesf8fma",
 		.sigill_fn = smesf8fma_sigill,
 	},
+	{
+		.name = "SME SF8MM8",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SF8MM8,
+		.cpuinfo = "smesf8mm8",
+		.sigill_fn = smesf8mm8_sigill,
+	},
+	{
+		.name = "SME SF8MM4",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SF8MM8,
+		.cpuinfo = "smesf8mm4",
+		.sigill_fn = smesf8mm4_sigill,
+	},
 	{
 		.name = "SME SF8DP2",
 		.at_hwcap = AT_HWCAP2,
@@ -761,6 +974,27 @@ static const struct hwcap_data {
 		.cpuinfo = "smesf8dp4",
 		.sigill_fn = smesf8dp4_sigill,
 	},
+	{
+		.name = "SME SFEXPA",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SFEXPA,
+		.cpuinfo = "smesfexpa",
+		.sigill_fn = smesfexpa_sigill,
+	},
+	{
+		.name = "SME SMOP4",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SMOP4,
+		.cpuinfo = "smesmop4",
+		.sigill_fn = smesmop4_sigill,
+	},
+	{
+		.name = "SME STMOP",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_STMOP,
+		.cpuinfo = "smestmop",
+		.sigill_fn = smestmop_sigill,
+	},
 	{
 		.name = "SVE",
 		.at_hwcap = AT_HWCAP,
@@ -783,6 +1017,13 @@ static const struct hwcap_data {
 		.cpuinfo = "sve2p1",
 		.sigill_fn = sve2p1_sigill,
 	},
+	{
+		.name = "SVE 2.2",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE2P2,
+		.cpuinfo = "sve2p2",
+		.sigill_fn = sve2p2_sigill,
+	},
 	{
 		.name = "SVE AES",
 		.at_hwcap = AT_HWCAP2,
@@ -790,6 +1031,34 @@ static const struct hwcap_data {
 		.cpuinfo = "sveaes",
 		.sigill_fn = sveaes_sigill,
 	},
+	{
+		.name = "SVE AES2",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE_AES2,
+		.cpuinfo = "sveaes2",
+		.sigill_fn = sveaes2_sigill,
+	},
+	{
+		.name = "SVE BFSCALE",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE_BFSCALE,
+		.cpuinfo = "svebfscale",
+		.sigill_fn = svebfscale_sigill,
+	},
+	{
+		.name = "SVE ELTPERM",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE_ELTPERM,
+		.cpuinfo = "sveeltperm",
+		.sigill_fn = sveeltperm_sigill,
+	},
+	{
+		.name = "SVE F16MM",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE_F16MM,
+		.cpuinfo = "svef16mm",
+		.sigill_fn = svef16mm_sigill,
+	},
 	{
 		.name = "SVE2 B16B16",
 		.at_hwcap = AT_HWCAP2,

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:45:52 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:45:52 +0000
Subject: [PATCH 0/6] arm64/sme: Collected SME fixes
Message-ID: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>

This series collects the various SME related fixes that were previously
posted separately.  These should address all the issues I am aware of so
a patch which reenables the SME configuration option is also included.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Mark Brown (6):
      arm64/sme: Flush foreign register state in do_sme_acc()
      arm64/fp: Don't corrupt FPMR when streaming mode changes
      arm64/ptrace: Zero FPMR on streaming mode entry/exit
      arm64/signal: Consistently invalidate the in register FP state in restore
      arm64/signal: Avoid corruption of SME state when entering signal handler
      arm64/sme: Reenable SME

 arch/arm64/Kconfig              |  1 -
 arch/arm64/include/asm/fpsimd.h |  1 +
 arch/arm64/kernel/fpsimd.c      | 49 +++++++++++++++++++++--
 arch/arm64/kernel/ptrace.c      | 12 +++++-
 arch/arm64/kernel/signal.c      | 89 +++++++++++------------------------------
 5 files changed, 79 insertions(+), 73 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241202-arm64-sme-reenable-98e64c161a8e

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Tue Dec  3 04:45:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:45:53 +0000
Subject: [PATCH 1/6] arm64/sme: Flush foreign register state in
 do_sme_acc()
In-Reply-To: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
Message-ID: <20241203-arm64-sme-reenable-v1-1-d853479d1b77@kernel.org>

When do_sme_acc() runs with foreign FP state it does not do any updates of
the task structure, relying on the next return to userspace to reload the
register state appropriately, but leaves the task's last loaded CPU
untouched. This means that if the task returns to userspace on the last
CPU it ran on then the checks in fpsimd_bind_task_to_cpu() will incorrectly
determine that the register state on the CPU is current and suppress reload
of the floating point register state before returning to userspace. This
will result in spurious warnings due to SME access traps occuring for the
task after TIF_SME is set.

Call fpsimd_flush_task_state() to invalidate the last loaded CPU
recorded in the task, forcing detection of the task as foreign.

Fixes: 8bd7f91c03d8 ("arm64/sme: Implement traps and syscall handling for SME")
Reported-by: Mark Rutlamd <mark.rutland at arm.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: stable at vger.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 8c4c1a2186cc510a7826d15ec36225857c07ed71..eca0b6a2fc6fa25d8c850a5b9e109b4d58809f54 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1460,6 +1460,8 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
 		sme_set_vq(vq_minus_one);
 
 		fpsimd_bind_task_to_cpu();
+	} else {
+		fpsimd_flush_task_state(current);
 	}
 
 	put_cpu_fpsimd_context();

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:45:54 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:45:54 +0000
Subject: [PATCH 2/6] arm64/fp: Don't corrupt FPMR when streaming mode
 changes
In-Reply-To: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
Message-ID: <20241203-arm64-sme-reenable-v1-2-d853479d1b77@kernel.org>

When we enter or exit streaming more FPMR is reset to 0.  This means
that when restoring the floating point state from memory we need to
restore FPMR after we restore SVCR, otherwise if we are entering or
exiting streaming mode as part of loading the new state the value of
FPMR will be corrupted.

Fixes: 203f2b95a882 ("arm64/fpsimd: Support FEAT_FPMR")
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index eca0b6a2fc6fa25d8c850a5b9e109b4d58809f54..a3bb17c88942eba031d26e9f75ad46f37b6dc621 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -359,9 +359,6 @@ 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:
@@ -413,6 +410,9 @@ static void task_fpsimd_load(void)
 			restore_ffr = system_supports_fa64();
 	}
 
+	if (system_supports_fpmr())
+		write_sysreg_s(current->thread.uw.fpmr, SYS_FPMR);
+
 	if (restore_sve_regs) {
 		WARN_ON_ONCE(current->thread.fp_type != FP_STATE_SVE);
 		sve_load_state(sve_pffr(&current->thread),

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:45:55 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:45:55 +0000
Subject: [PATCH 3/6] arm64/ptrace: Zero FPMR on streaming mode entry/exit
In-Reply-To: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
Message-ID: <20241203-arm64-sme-reenable-v1-3-d853479d1b77@kernel.org>

When FPMR and SME are both present then entering and exiting streaming mode
clears FPMR in the same manner as it clears the V/Z and P registers.
Since entering and exiting streaming mode via ptrace is expected to have
the same effect as doing so via SMSTART/SMSTOP it should clear FPMR too
but this was missed when FPMR support was added. Add the required reset
of FPMR.

Since changing the vector length resets SVCR a SME vector length change
implemented via a write to ZA can trigger an exit of streaming mode and
we need to check when writing to ZA as well.

Fixes: 4035c22ef7d4 ("arm64/ptrace: Expose FPMR via ptrace")
Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: stable at vger.kernel.org
---
 arch/arm64/kernel/ptrace.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index e4437f62a2cda93734052c44b48886db83d75b3e..43a9397d5903ff87b608befdcaed3f9a7e48f976 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -877,6 +877,7 @@ static int sve_set_common(struct task_struct *target,
 			  const void *kbuf, const void __user *ubuf,
 			  enum vec_type type)
 {
+	u64 old_svcr = target->thread.svcr;
 	int ret;
 	struct user_sve_header header;
 	unsigned int vq;
@@ -908,8 +909,6 @@ static int sve_set_common(struct task_struct *target,
 
 	/* Enter/exit streaming mode */
 	if (system_supports_sme()) {
-		u64 old_svcr = target->thread.svcr;
-
 		switch (type) {
 		case ARM64_VEC_SVE:
 			target->thread.svcr &= ~SVCR_SM_MASK;
@@ -1008,6 +1007,10 @@ static int sve_set_common(struct task_struct *target,
 				 start, end);
 
 out:
+	/* If we entered or exited streaming mode then reset FPMR */
+	if ((target->thread.svcr & SVCR_SM) != (old_svcr & SVCR_SM))
+		target->thread.uw.fpmr = 0;
+
 	fpsimd_flush_task_state(target);
 	return ret;
 }
@@ -1104,6 +1107,7 @@ static int za_set(struct task_struct *target,
 		  unsigned int pos, unsigned int count,
 		  const void *kbuf, const void __user *ubuf)
 {
+	u64 old_svcr = target->thread.svcr;
 	int ret;
 	struct user_za_header header;
 	unsigned int vq;
@@ -1184,6 +1188,10 @@ static int za_set(struct task_struct *target,
 	target->thread.svcr |= SVCR_ZA_MASK;
 
 out:
+	/* If we entered or exited streaming mode then reset FPMR */
+	if ((target->thread.svcr & SVCR_SM) != (old_svcr & SVCR_SM))
+		target->thread.uw.fpmr = 0;
+
 	fpsimd_flush_task_state(target);
 	return ret;
 }

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:45:56 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:45:56 +0000
Subject: [PATCH 4/6] arm64/signal: Consistently invalidate the in register
 FP state in restore
In-Reply-To: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
Message-ID: <20241203-arm64-sme-reenable-v1-4-d853479d1b77@kernel.org>

When restoring the SVE and SME specific floating point register states we
flush the task floating point state, marking the hardware state as stale so
that preemption does not result in us saving register state from the signal
handler on top of the restored context and forcing a reload from memory.
For the plain FPSIMD state we don't do this, we just copy the state from
userspace and then force an immediate reload of the register state.
This isn't racy against context switch since we copy the incoming data
onto the stack rather than directly into the task struct but it's still
messy and inconsistent.

Simplify things and avoid a potential source of error by moving the
invalidation of the CPU state to the main restore_sigframe() and
reworking the restore of the FPSIMD state to update the task struct and
rely on loading as part of the general do_notify_resume() handling for
return to user like we do for the SVE and SME state.

As a result of this the only user of fpsimd_update_current_state() is
the 32 bit signal code which should not have any SVE state, add an
assert there that we don't have SVE enabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c |  2 +-
 arch/arm64/kernel/signal.c | 70 +++++++++++++++-------------------------------
 2 files changed, 23 insertions(+), 49 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a3bb17c88942eba031d26e9f75ad46f37b6dc621..f02762762dbcf954e9add6dfd3575ae7055b6b0e 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1828,7 +1828,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state)
 	get_cpu_fpsimd_context();
 
 	current->thread.uw.fpsimd_state = *state;
-	if (test_thread_flag(TIF_SVE))
+	if (WARN_ON_ONCE(test_thread_flag(TIF_SVE)))
 		fpsimd_to_sve(current);
 
 	task_fpsimd_load();
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 14ac6fdb872b9672e4b16a097f1b577aae8dec50..abd0907061fe664bf22d1995319f9559c4bbed91 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -271,7 +271,7 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 
 static int restore_fpsimd_context(struct user_ctxs *user)
 {
-	struct user_fpsimd_state fpsimd;
+	struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
 	int err = 0;
 
 	/* check the size information */
@@ -279,18 +279,14 @@ static int restore_fpsimd_context(struct user_ctxs *user)
 		return -EINVAL;
 
 	/* copy the FP and status/control registers */
-	err = __copy_from_user(fpsimd.vregs, &(user->fpsimd->vregs),
-			       sizeof(fpsimd.vregs));
-	__get_user_error(fpsimd.fpsr, &(user->fpsimd->fpsr), err);
-	__get_user_error(fpsimd.fpcr, &(user->fpsimd->fpcr), err);
+	err = __copy_from_user(fpsimd->vregs, &(user->fpsimd->vregs),
+			       sizeof(fpsimd->vregs));
+	__get_user_error(fpsimd->fpsr, &(user->fpsimd->fpsr), err);
+	__get_user_error(fpsimd->fpcr, &(user->fpsimd->fpcr), err);
 
 	clear_thread_flag(TIF_SVE);
 	current->thread.fp_type = FP_STATE_FPSIMD;
 
-	/* load the hardware registers from the fpsimd_state structure */
-	if (!err)
-		fpsimd_update_current_state(&fpsimd);
-
 	return err ? -EFAULT : 0;
 }
 
@@ -396,7 +392,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 {
 	int err = 0;
 	unsigned int vl, vq;
-	struct user_fpsimd_state fpsimd;
+	struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
 	u16 user_vl, flags;
 
 	if (user->sve_size < sizeof(*user->sve))
@@ -439,16 +435,6 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 	if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq))
 		return -EINVAL;
 
-	/*
-	 * Careful: we are about __copy_from_user() directly into
-	 * thread.sve_state with preemption enabled, so protection is
-	 * needed to prevent a racing context switch from writing stale
-	 * registers back over the new data.
-	 */
-
-	fpsimd_flush_task_state(current);
-	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
-
 	sve_alloc(current, true);
 	if (!current->thread.sve_state) {
 		clear_thread_flag(TIF_SVE);
@@ -471,14 +457,10 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 fpsimd_only:
 	/* copy the FP and status/control registers */
 	/* restore_sigframe() already checked that user->fpsimd != NULL. */
-	err = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs,
-			       sizeof(fpsimd.vregs));
-	__get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err);
-	__get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err);
-
-	/* load the hardware registers from the fpsimd_state structure */
-	if (!err)
-		fpsimd_update_current_state(&fpsimd);
+	err = __copy_from_user(fpsimd->vregs, user->fpsimd->vregs,
+			       sizeof(fpsimd->vregs));
+	__get_user_error(fpsimd->fpsr, &user->fpsimd->fpsr, err);
+	__get_user_error(fpsimd->fpcr, &user->fpsimd->fpcr, err);
 
 	return err ? -EFAULT : 0;
 }
@@ -587,16 +569,6 @@ static int restore_za_context(struct user_ctxs *user)
 	if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq))
 		return -EINVAL;
 
-	/*
-	 * Careful: we are about __copy_from_user() directly into
-	 * thread.sme_state with preemption enabled, so protection is
-	 * needed to prevent a racing context switch from writing stale
-	 * registers back over the new data.
-	 */
-
-	fpsimd_flush_task_state(current);
-	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
-
 	sme_alloc(current, true);
 	if (!current->thread.sme_state) {
 		current->thread.svcr &= ~SVCR_ZA_MASK;
@@ -664,16 +636,6 @@ static int restore_zt_context(struct user_ctxs *user)
 	if (nregs != 1)
 		return -EINVAL;
 
-	/*
-	 * Careful: we are about __copy_from_user() directly into
-	 * thread.zt_state with preemption enabled, so protection is
-	 * needed to prevent a racing context switch from writing stale
-	 * registers back over the new data.
-	 */
-
-	fpsimd_flush_task_state(current);
-	/* From now, fpsimd_thread_switch() won't touch ZT in thread state */
-
 	err = __copy_from_user(thread_zt_state(&current->thread),
 			       (char __user const *)user->zt +
 					ZT_SIG_REGS_OFFSET,
@@ -1028,6 +990,18 @@ static int restore_sigframe(struct pt_regs *regs,
 	if (err == 0)
 		err = parse_user_sigframe(&user, sf);
 
+	/*
+	 * Careful: we are about __copy_from_user() directly into
+	 * thread floating point state with preemption enabled, so
+	 * protection is needed to prevent a racing context switch
+	 * from writing stale registers back over the new data. Mark
+	 * the register floating point state as invalid and unbind the
+	 * task from the CPU to force a reload before we return to
+	 * userspace. fpsimd_flush_task_state() has a check for FP
+	 * support.
+	 */
+	fpsimd_flush_task_state(current);
+
 	if (err == 0 && system_supports_fpsimd()) {
 		if (!user.fpsimd)
 			return -EINVAL;

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:45:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:45:57 +0000
Subject: [PATCH 5/6] arm64/signal: Avoid corruption of SME state when
 entering signal handler
In-Reply-To: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
Message-ID: <20241203-arm64-sme-reenable-v1-5-d853479d1b77@kernel.org>

We intend that signal handlers are entered with PSTATE.{SM,ZA}={0,0}.
The logic for this in setup_return() manipulates the saved state and
live CPU state in an unsafe manner, and consequently, when a task enters
a signal handler:

 * The task entering the signal handler might not have its PSTATE.{SM,ZA}
   bits cleared, and other register state that is affected by changes to
   PSTATE.{SM,ZA} might not be zeroed as expected.

 * An unrelated task might have its PSTATE.{SM,ZA} bits cleared
   unexpectedly, potentially zeroing other register state that is
   affected by changes to PSTATE.{SM,ZA}.

   Tasks which do not set PSTATE.{SM,ZA} (i.e. those only using plain
   FPSIMD or non-streaming SVE) are not affected, as there is no
   resulting change to PSTATE.{SM,ZA}.

Consider for example two tasks on one CPU:

 A: Begins signal entry in kernel mode, is preempted prior to SMSTOP.
 B: Using SM and/or ZA in userspace with register state current on the
    CPU, is preempted.
 A: Scheduled in, no register state changes made as in kernel mode.
 A: Executes SMSTOP, modifying live register state.
 A: Scheduled out.
 B: Scheduled in, fpsimd_thread_switch() sees the register state on the
    CPU is tracked as being that for task B so the state is not reloaded
    prior to returning to userspace.

Task B is now running with SM and ZA incorrectly cleared.

Fix this by:

 * Checking TIF_FOREIGN_FPSTATE, and only updating the saved or live
   state as appropriate.

 * Using {get,put}_cpu_fpsimd_context() to ensure mutual exclusion
   against other code which manipulates this state. To allow their use,
   the logic is moved into a new fpsimd_enter_sighandler() helper in
   fpsimd.c.

This race has been observed intermittently with fp-stress, especially
with preempt disabled, commonly but not exclusively reporting "Bad SVCR: 0".

While we're at it also fix a discrepancy between in register and in memory
entries. When operating on the register state we issue a SMSTOP, exiting
streaming mode if we were in it. This clears the V/Z and P register and
FPMR but nothing else. The in memory version clears all the user FPSIMD
state including FPCR and FPSR but does not clear FPMR. Add the clear of
FPMR and limit the existing memset() to only cover the vregs, preserving
the state of FPCR and FPSR like SMSTOP does.

Fixes: 40a8e87bb3285 ("arm64/sme: Disable ZA and streaming mode when handling signals")
Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: stable at vger.kernel.org
---
 arch/arm64/include/asm/fpsimd.h |  1 +
 arch/arm64/kernel/fpsimd.c      | 39 +++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/signal.c      | 19 +------------------
 3 files changed, 41 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index f2a84efc361858d4deda99faf1967cc7cac386c1..09af7cfd9f6c2cec26332caa4c254976e117b1bf 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -76,6 +76,7 @@ extern void fpsimd_load_state(struct user_fpsimd_state *state);
 extern void fpsimd_thread_switch(struct task_struct *next);
 extern void fpsimd_flush_thread(void);
 
+extern void fpsimd_enter_sighandler(void);
 extern void fpsimd_signal_preserve_current_state(void);
 extern void fpsimd_preserve_current_state(void);
 extern void fpsimd_restore_current_state(void);
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index f02762762dbcf954e9add6dfd3575ae7055b6b0e..c5465c8ec467cb1ab8bd211dc5370f91aa2bcf35 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1696,6 +1696,45 @@ void fpsimd_signal_preserve_current_state(void)
 		sve_to_fpsimd(current);
 }
 
+/*
+ * Called by the signal handling code when preparing current to enter
+ * a signal handler. Currently this only needs to take care of exiting
+ * streaming mode and clearing ZA on SME systems.
+ */
+void fpsimd_enter_sighandler(void)
+{
+	if (!system_supports_sme())
+		return;
+
+	get_cpu_fpsimd_context();
+
+	if (test_thread_flag(TIF_FOREIGN_FPSTATE)) {
+		/*
+		 * Exiting streaming mode zeros the V/Z and P
+		 * registers and FPMR.  Zero FPMR and the V registers,
+		 * marking the state as FPSIMD only to force a clear
+		 * of the remaining bits during reload if needed.
+		 */
+		if (current->thread.svcr & SVCR_SM_MASK) {
+			memset(&current->thread.uw.fpsimd_state.vregs, 0,
+			       sizeof(current->thread.uw.fpsimd_state.vregs));
+			current->thread.uw.fpmr = 0;
+			current->thread.fp_type = FP_STATE_FPSIMD;
+		}
+
+		current->thread.svcr &= ~(SVCR_ZA_MASK |
+					  SVCR_SM_MASK);
+
+		/* Ensure any copies on other CPUs aren't reused */
+		fpsimd_flush_task_state(current);
+	} else {
+		/* The register state is current, just update it. */
+		sme_smstop();
+	}
+
+	put_cpu_fpsimd_context();
+}
+
 /*
  * Called by KVM when entering the guest.
  */
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index abd0907061fe664bf22d1995319f9559c4bbed91..335c2327baf74eac9634cf594855dbf26a7d6b01 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -1461,24 +1461,7 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
 	/* TCO (Tag Check Override) always cleared for signal handlers */
 	regs->pstate &= ~PSR_TCO_BIT;
 
-	/* Signal handlers are invoked with ZA and streaming mode disabled */
-	if (system_supports_sme()) {
-		/*
-		 * If we were in streaming mode the saved register
-		 * state was SVE but we will exit SM and use the
-		 * FPSIMD register state - flush the saved FPSIMD
-		 * register state in case it gets loaded.
-		 */
-		if (current->thread.svcr & SVCR_SM_MASK) {
-			memset(&current->thread.uw.fpsimd_state, 0,
-			       sizeof(current->thread.uw.fpsimd_state));
-			current->thread.fp_type = FP_STATE_FPSIMD;
-		}
-
-		current->thread.svcr &= ~(SVCR_ZA_MASK |
-					  SVCR_SM_MASK);
-		sme_smstop();
-	}
+	fpsimd_enter_sighandler();
 
 	if (ksig->ka.sa.sa_flags & SA_RESTORER)
 		sigtramp = ksig->ka.sa.sa_restorer;

-- 
2.39.5



From broonie at kernel.org  Tue Dec  3 04:45:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 12:45:58 +0000
Subject: [PATCH 6/6] arm64/sme: Reenable SME
In-Reply-To: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
Message-ID: <20241203-arm64-sme-reenable-v1-6-d853479d1b77@kernel.org>

Now that fixes for all the known issues with SME have been applied
remove the BROKEN dependency from it so it's generally available again.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5e8892c0112704f9ca74c4fc55b27..7e3182dd6fa0dadd961c352f88484cff0e520eaa 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2270,7 +2270,6 @@ config ARM64_SME
 	bool "ARM Scalable Matrix Extension support"
 	default y
 	depends on ARM64_SVE
-	depends on BROKEN
 	help
 	  The Scalable Matrix Extension (SME) is an extension to the AArch64
 	  execution state which utilises a substantial subset of the SVE

-- 
2.39.5



From yangyicong at huawei.com  Tue Dec  3 04:50:46 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:46 +0800
Subject: [PATCH v4 07/10] drivers/perf: hisi: Provide a generic implementation of cpumask/identifier
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-8-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Each type of HiSilicon Uncore PMU has the following sysfs attributes:

- format: bitmask in perf_event_attr::config[012] of corresponding
  attribute
- event: events name and corresponding event code
- cpumask: range of CPUs the events can be opened on
- identifier: the version of this PMU

Different types of PMU have different implementations of the "format"
and "event" but all share the same implementation of the "cpumask"
and "identifier". Thus we can move cpumask and identifier to the
hisi_uncore_pmu framework and drivers can use the generic
implementation.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  | 27 +----------
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 31 ++-----------
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  | 31 ++-----------
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  | 31 ++-----------
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   | 35 +++------------
 drivers/perf/hisilicon/hisi_uncore_pmu.c      | 45 ++++++++++++++-----
 drivers/perf/hisilicon/hisi_uncore_pmu.h      |  4 ++
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 27 +----------
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   | 27 +----------
 9 files changed, 63 insertions(+), 195 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
index c9b5016fafdb..0d6a1683892a 100644
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
@@ -225,34 +225,11 @@ static const struct attribute_group hisi_cpa_pmu_events_group = {
 	.attrs = hisi_cpa_pmu_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_cpa_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_cpa_pmu_cpumask_attr_group = {
-	.attrs = hisi_cpa_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_cpa_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_cpa_pmu_identifier_attrs[] = {
-	&hisi_cpa_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_cpa_pmu_identifier_group = {
-	.attrs = hisi_cpa_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_cpa_pmu_attr_groups[] = {
 	&hisi_cpa_pmu_format_group,
 	&hisi_cpa_pmu_events_group,
-	&hisi_cpa_pmu_cpumask_attr_group,
-	&hisi_cpa_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index 56a4068d6568..fb596f43ef9a 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -380,42 +380,19 @@ static const struct attribute_group hisi_ddrc_pmu_v2_events_group = {
 	.attrs = hisi_ddrc_pmu_v2_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_ddrc_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static const struct attribute_group hisi_ddrc_pmu_cpumask_attr_group = {
-	.attrs = hisi_ddrc_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_ddrc_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_ddrc_pmu_identifier_attrs[] = {
-	&hisi_ddrc_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_ddrc_pmu_identifier_group = {
-	.attrs = hisi_ddrc_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_ddrc_pmu_v1_attr_groups[] = {
 	&hisi_ddrc_pmu_v1_format_group,
 	&hisi_ddrc_pmu_v1_events_group,
-	&hisi_ddrc_pmu_cpumask_attr_group,
-	&hisi_ddrc_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL,
 };
 
 static const struct attribute_group *hisi_ddrc_pmu_v2_attr_groups[] = {
 	&hisi_ddrc_pmu_v2_format_group,
 	&hisi_ddrc_pmu_v2_events_group,
-	&hisi_ddrc_pmu_cpumask_attr_group,
-	&hisi_ddrc_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index e59b31fdc4e4..0a7c44f72ecc 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -405,42 +405,19 @@ static const struct attribute_group hisi_hha_pmu_v2_events_group = {
 	.attrs = hisi_hha_pmu_v2_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_hha_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static const struct attribute_group hisi_hha_pmu_cpumask_attr_group = {
-	.attrs = hisi_hha_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_hha_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_hha_pmu_identifier_attrs[] = {
-	&hisi_hha_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_hha_pmu_identifier_group = {
-	.attrs = hisi_hha_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_hha_pmu_v1_attr_groups[] = {
 	&hisi_hha_pmu_v1_format_group,
 	&hisi_hha_pmu_v1_events_group,
-	&hisi_hha_pmu_cpumask_attr_group,
-	&hisi_hha_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL,
 };
 
 static const struct attribute_group *hisi_hha_pmu_v2_attr_groups[] = {
 	&hisi_hha_pmu_v2_format_group,
 	&hisi_hha_pmu_v2_events_group,
-	&hisi_hha_pmu_cpumask_attr_group,
-	&hisi_hha_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index 290a9e311f48..602d8d0b72f7 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -441,42 +441,19 @@ static const struct attribute_group hisi_l3c_pmu_v2_events_group = {
 	.attrs = hisi_l3c_pmu_v2_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_l3c_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static const struct attribute_group hisi_l3c_pmu_cpumask_attr_group = {
-	.attrs = hisi_l3c_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_l3c_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_l3c_pmu_identifier_attrs[] = {
-	&hisi_l3c_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_l3c_pmu_identifier_group = {
-	.attrs = hisi_l3c_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_l3c_pmu_v1_attr_groups[] = {
 	&hisi_l3c_pmu_v1_format_group,
 	&hisi_l3c_pmu_v1_events_group,
-	&hisi_l3c_pmu_cpumask_attr_group,
-	&hisi_l3c_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL,
 };
 
 static const struct attribute_group *hisi_l3c_pmu_v2_attr_groups[] = {
 	&hisi_l3c_pmu_v2_format_group,
 	&hisi_l3c_pmu_v2_events_group,
-	&hisi_l3c_pmu_cpumask_attr_group,
-	&hisi_l3c_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
index d7b525f634b9..bd7640516d17 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
@@ -353,29 +353,6 @@ static const struct attribute_group hisi_h60pa_pmu_events_group = {
 	.attrs = hisi_h60pa_pmu_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_pa_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_pa_pmu_cpumask_attr_group = {
-	.attrs = hisi_pa_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_pa_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_pa_pmu_identifier_attrs[] = {
-	&hisi_pa_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_pa_pmu_identifier_group = {
-	.attrs = hisi_pa_pmu_identifier_attrs,
-};
-
 static struct hisi_pa_pmu_int_regs hisi_pa_pmu_regs = {
 	.mask_offset = PA_INT_MASK,
 	.clear_offset = PA_INT_CLEAR,
@@ -385,8 +362,8 @@ static struct hisi_pa_pmu_int_regs hisi_pa_pmu_regs = {
 static const struct attribute_group *hisi_pa_pmu_v2_attr_groups[] = {
 	&hisi_pa_pmu_v2_format_group,
 	&hisi_pa_pmu_v2_events_group,
-	&hisi_pa_pmu_cpumask_attr_group,
-	&hisi_pa_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
@@ -399,8 +376,8 @@ static const struct hisi_pmu_dev_info hisi_h32pa_v2 = {
 static const struct attribute_group *hisi_pa_pmu_v3_attr_groups[] = {
 	&hisi_pa_pmu_v2_format_group,
 	&hisi_pa_pmu_v3_events_group,
-	&hisi_pa_pmu_cpumask_attr_group,
-	&hisi_pa_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
@@ -419,8 +396,8 @@ static struct hisi_pa_pmu_int_regs hisi_h60pa_pmu_regs = {
 static const struct attribute_group *hisi_h60pa_pmu_attr_groups[] = {
 	&hisi_pa_pmu_v2_format_group,
 	&hisi_h60pa_pmu_events_group,
-	&hisi_pa_pmu_cpumask_attr_group,
-	&hisi_pa_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 1132822ff97a..339e346e94ee 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -49,6 +49,41 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
 }
 EXPORT_SYMBOL_NS_GPL(hisi_cpumask_sysfs_show, HISI_PMU);
 
+static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
+
+static struct attribute *hisi_pmu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL
+};
+
+const struct attribute_group hisi_pmu_cpumask_attr_group = {
+	.attrs = hisi_pmu_cpumask_attrs,
+};
+EXPORT_SYMBOL_NS_GPL(hisi_pmu_cpumask_attr_group, HISI_PMU);
+
+ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
+					     struct device_attribute *attr,
+					     char *page)
+{
+	struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
+
+	return sysfs_emit(page, "0x%08x\n", hisi_pmu->identifier);
+}
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_identifier_attr_show, HISI_PMU);
+
+static struct device_attribute hisi_pmu_identifier_attr =
+	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
+
+static struct attribute *hisi_pmu_identifier_attrs[] = {
+	&hisi_pmu_identifier_attr.attr,
+	NULL
+};
+
+const struct attribute_group hisi_pmu_identifier_group = {
+	.attrs = hisi_pmu_identifier_attrs,
+};
+EXPORT_SYMBOL_NS_GPL(hisi_pmu_identifier_group, HISI_PMU);
+
 static bool hisi_validate_event_group(struct perf_event *event)
 {
 	struct perf_event *sibling, *leader = event->group_leader;
@@ -99,16 +134,6 @@ int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
 }
 EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_get_event_idx, HISI_PMU);
 
-ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
-					     struct device_attribute *attr,
-					     char *page)
-{
-	struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
-
-	return sysfs_emit(page, "0x%08x\n", hisi_pmu->identifier);
-}
-EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_identifier_attr_show, HISI_PMU);
-
 static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
 {
 	clear_bit(idx, hisi_pmu->pmu_events.used_mask);
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
index 53b1331b8565..f4fed2544877 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
@@ -137,6 +137,10 @@ struct hisi_pmu {
 	u32 identifier;
 };
 
+/* Generic implementation of cpumask/identifier group */
+extern const struct attribute_group hisi_pmu_cpumask_attr_group;
+extern const struct attribute_group hisi_pmu_identifier_group;
+
 int hisi_uncore_pmu_get_event_idx(struct perf_event *event);
 void hisi_uncore_pmu_read(struct perf_event *event);
 int hisi_uncore_pmu_add(struct perf_event *event, int flags);
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
index a342ef3d9916..b55a06f351aa 100644
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
@@ -344,34 +344,11 @@ static const struct attribute_group hisi_sllc_pmu_v2_events_group = {
 	.attrs = hisi_sllc_pmu_v2_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_sllc_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_sllc_pmu_cpumask_attr_group = {
-	.attrs = hisi_sllc_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_sllc_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_sllc_pmu_identifier_attrs[] = {
-	&hisi_sllc_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_sllc_pmu_identifier_group = {
-	.attrs = hisi_sllc_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_sllc_pmu_v2_attr_groups[] = {
 	&hisi_sllc_pmu_v2_format_group,
 	&hisi_sllc_pmu_v2_events_group,
-	&hisi_sllc_pmu_cpumask_attr_group,
-	&hisi_sllc_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
index 2df8976ab4be..f90f752f32dd 100644
--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
@@ -437,34 +437,11 @@ static const struct attribute_group hisi_uc_pmu_events_group = {
 	.attrs = hisi_uc_pmu_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_uc_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static const struct attribute_group hisi_uc_pmu_cpumask_attr_group = {
-	.attrs = hisi_uc_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_uc_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_uc_pmu_identifier_attrs[] = {
-	&hisi_uc_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_uc_pmu_identifier_group = {
-	.attrs = hisi_uc_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_uc_pmu_attr_groups[] = {
 	&hisi_uc_pmu_format_group,
 	&hisi_uc_pmu_events_group,
-	&hisi_uc_pmu_cpumask_attr_group,
-	&hisi_uc_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec  3 04:50:39 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:39 +0800
Subject: [PATCH v4 00/10] Refactor the common parts to the HiSilicon Uncore PMU core and cleanups
Message-ID: <20241203125049.39458-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

This series mainly contains the refactor of the HiSilicon Uncore PMU by
extracting the common parts from each drivers into the core:
- the retrieving of the PMU topology ID
- the common sysfs attributes like cpumask and identifier

In order to achieve this, we need to do below preparation:
- refactor the detection of associated CPUs for PMUs locates on a SICL
- maintain the topology information in a dedicated data structure
- provides a generic implementation of cpumask/identifier attributes

Besides also include below changes/cleanups in this patchset
- add one new sysfs attributes for better describing the topology information
  of the associated CPUs of the PMU.
- define a symbol namespace for HiSilicon Uncore PMUs to avoid pollute the
  common ones
- two minor nonfunctional cleanups of DDRC PMU

Change since v3:
- Split the associated_cpus refactor patches according to the functions, hope
  will be easier to review
- Drop the use of cpu_online_mask out of cpuhp
Link: https://lore.kernel.org/linux-arm-kernel/20241026072424.29887-1-yangyicong at huawei.com/

Change since v2:
- remove one redundant newline and add Jonathan's tag for Patch 1 and 5
Link: https://lore.kernel.org/linux-arm-kernel/20241022145305.47056-1-yangyicong at huawei.com/

Changes since v1:
Address Jonathan's comments and add tags for some patches
- Provide a generic cpumask/identifier attribute group
- refine the comments/commit as suggested
Link: https://lore.kernel.org/linux-arm-kernel/20241018095745.57057-1-yangyicong at huawei.com/

Junhao He (2):
  drivers/perf: hisi: Fix incorrect variable name "hha_pmu" in DDRC PMU
    driver
  drivers/perf: hisi: Delete redundant blank line of DDRC PMU

Yicong Yang (8):
  drivers/perf: hisi: Define a symbol namespace for HiSilicon Uncore
    PMUs
  drivers/perf: hisi: Don't update the associated_cpus on CPU offline
  drivers/perf: hisi: Migrate to one online CPU if no associated one
    online
  drivers/perf: hisi: Refactor the detection of associated CPUs
  drivers/perf: hisi: Extract topology information to a separate
    structure
  drivers/perf: hisi: Add a common function to retrieve topology from
    firmware
  drivers/perf: hisi: Provide a generic implementation of
    cpumask/identifier
  drivers/perf: hisi: Export associated CPUs of each PMU through sysfs

 Documentation/admin-guide/perf/hisi-pmu.rst   |   5 +-
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  |  42 +----
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c |  61 ++-----
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  |  48 ++----
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  |  44 ++---
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   |  53 ++----
 drivers/perf/hisilicon/hisi_uncore_pmu.c      | 160 +++++++++++++-----
 drivers/perf/hisilicon/hisi_uncore_pmu.h      |  49 +++++-
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c |  43 +----
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   |  45 ++---
 10 files changed, 248 insertions(+), 302 deletions(-)

-- 
2.24.0



From yangyicong at huawei.com  Tue Dec  3 04:50:47 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:47 +0800
Subject: [PATCH v4 08/10] drivers/perf: hisi: Export associated CPUs of each PMU through sysfs
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-9-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Although the event of the uncore PMU can only be opened on a single
CPU, some PMU does have the affinity on a range of CPUs. For example
the L3C PMU is associated to the CPUs sharing the L3T it monitors.
Users may infer this affinity by the PMU name which may have SCCL ID
and CCL ID encoded (for L3C etc), but it's not that straightforward.
So export this information by adding an "associated_cpus" sysfs
attribute then user can get this directly.

Reviewed-by: Jonathan Cameron <Joanthan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 Documentation/admin-guide/perf/hisi-pmu.rst |  5 ++++-
 drivers/perf/hisilicon/hisi_uncore_pmu.c    | 10 ++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
index 5cc248d18c63..48992a0b8e94 100644
--- a/Documentation/admin-guide/perf/hisi-pmu.rst
+++ b/Documentation/admin-guide/perf/hisi-pmu.rst
@@ -35,7 +35,10 @@ e.g. hisi_sccl1_hha0/rx_operations is RX_OPERATIONS event of HHA index #0 in
 SCCL ID #1.
 
 The driver also provides a "cpumask" sysfs attribute, which shows the CPU core
-ID used to count the uncore PMU event.
+ID used to count the uncore PMU event. An "associated_cpus" sysfs attribute is
+also provided to show the CPUs associated with this PMU. The "cpumask" indicates
+the CPUs to open the events, usually as a hint for userspaces tools like perf.
+It only contains one associated CPU from the "associated_cpus".
 
 Example usage of perf::
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 339e346e94ee..f86aba567224 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -51,8 +51,18 @@ EXPORT_SYMBOL_NS_GPL(hisi_cpumask_sysfs_show, HISI_PMU);
 
 static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
 
+static ssize_t hisi_associated_cpus_sysfs_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
+
+	return cpumap_print_to_pagebuf(true, buf, &hisi_pmu->associated_cpus);
+}
+static DEVICE_ATTR(associated_cpus, 0444, hisi_associated_cpus_sysfs_show, NULL);
+
 static struct attribute *hisi_pmu_cpumask_attrs[] = {
 	&dev_attr_cpumask.attr,
+	&dev_attr_associated_cpus.attr,
 	NULL
 };
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec  3 04:50:49 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:49 +0800
Subject: [PATCH v4 10/10] drivers/perf: hisi: Delete redundant blank line of DDRC PMU
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-11-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

Do not add blank line at the end of a code block defined by braces.

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index 0caa15aa836f..6af84807ac3d 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -550,7 +550,6 @@ static void __exit hisi_ddrc_pmu_module_exit(void)
 {
 	platform_driver_unregister(&hisi_ddrc_pmu_driver);
 	cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE);
-
 }
 module_exit(hisi_ddrc_pmu_module_exit);
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec  3 04:50:44 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 3 Dec 2024 20:50:44 +0800
Subject: [PATCH v4 05/10] drivers/perf: hisi: Extract topology information to a separate structure
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241203125049.39458-6-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

HiSilicon Uncore PMUs are identified by the IDs of the topology element
on which the PMUs are located. Add a new separate struct hisi_pmu_toplogy
to encapsulate this information. Add additional documentation on the
meaning of each ID.

- make sccl_id and sicl_id into a union since they're exclusive. It can
  also be accessed by scl_id if the SICL/SCCL distinction is not
  relevant
- make index_id and sub_id signed so -1 may be used to indicate the PMU
  doesn't have this topology element or it could not be retrieved.

This patch should have no functional changes.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  | 12 +++---
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 18 ++++-----
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  | 12 +++---
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  |  8 ++--
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   | 14 +++----
 drivers/perf/hisilicon/hisi_uncore_pmu.c      |  7 ++--
 drivers/perf/hisilicon/hisi_uncore_pmu.h      | 38 +++++++++++++++----
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 10 ++---
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   | 11 +++---
 9 files changed, 78 insertions(+), 52 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
index d2dc848956af..826e25c14cec 100644
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
@@ -181,19 +181,19 @@ static int hisi_cpa_pmu_init_data(struct platform_device *pdev,
 				  struct hisi_pmu *cpa_pmu)
 {
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &cpa_pmu->sicl_id)) {
+				     &cpa_pmu->topo.sicl_id)) {
 		dev_err(&pdev->dev, "Can not read sicl-id\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &cpa_pmu->index_id)) {
+				     &cpa_pmu->topo.index_id)) {
 		dev_err(&pdev->dev, "Cannot read idx-id\n");
 		return -EINVAL;
 	}
 
-	cpa_pmu->ccl_id = -1;
-	cpa_pmu->sccl_id = -1;
+	cpa_pmu->topo.ccl_id = -1;
+	cpa_pmu->topo.sccl_id = -1;
 	cpa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(cpa_pmu->base))
 		return PTR_ERR(cpa_pmu->base);
@@ -311,8 +311,8 @@ static int hisi_cpa_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%d_cpa%u",
-			      cpa_pmu->sicl_id, cpa_pmu->index_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%d_cpa%d",
+			      cpa_pmu->topo.sicl_id, cpa_pmu->topo.index_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index e323f0c339ec..f7bc86644ebe 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -302,18 +302,18 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 	 * DDRC PMU, while SCCL_ID is in MPIDR[aff2].
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,ch-id",
-				     &ddrc_pmu->index_id)) {
+				     &ddrc_pmu->topo.index_id)) {
 		dev_err(&pdev->dev, "Can not read ddrc channel-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &ddrc_pmu->sccl_id)) {
+				     &ddrc_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Can not read ddrc sccl-id!\n");
 		return -EINVAL;
 	}
 	/* DDRC PMUs only share the same SCCL */
-	ddrc_pmu->ccl_id = -1;
+	ddrc_pmu->topo.ccl_id = -1;
 
 	ddrc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ddrc_pmu->base)) {
@@ -324,7 +324,7 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 	ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
 	if (ddrc_pmu->identifier >= HISI_PMU_V2) {
 		if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-					     &ddrc_pmu->sub_id)) {
+					     &ddrc_pmu->topo.sub_id)) {
 			dev_err(&pdev->dev, "Can not read sub-id!\n");
 			return -EINVAL;
 		}
@@ -501,13 +501,13 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
 
 	if (ddrc_pmu->identifier >= HISI_PMU_V2)
 		name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
-				      "hisi_sccl%u_ddrc%u_%u",
-				      ddrc_pmu->sccl_id, ddrc_pmu->index_id,
-				      ddrc_pmu->sub_id);
+				      "hisi_sccl%d_ddrc%d_%d",
+				      ddrc_pmu->topo.sccl_id, ddrc_pmu->topo.index_id,
+				      ddrc_pmu->topo.sub_id);
 	else
 		name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
-				      "hisi_sccl%u_ddrc%u", ddrc_pmu->sccl_id,
-				      ddrc_pmu->index_id);
+				      "hisi_sccl%d_ddrc%d", ddrc_pmu->topo.sccl_id,
+				      ddrc_pmu->topo.index_id);
 
 	if (!name)
 		return -ENOMEM;
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index d5c2eab8023e..c5a8f61b5ad5 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -300,7 +300,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 	 * SCCL_ID is in MPIDR[aff2].
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &hha_pmu->sccl_id)) {
+				     &hha_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Can not read hha sccl-id!\n");
 		return -EINVAL;
 	}
@@ -310,7 +310,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 	 * both "hisilicon, idx-id" as preference, if available.
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &hha_pmu->index_id)) {
+				     &hha_pmu->topo.index_id)) {
 		status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
 					       "_UID", NULL, &id);
 		if (ACPI_FAILURE(status)) {
@@ -318,10 +318,10 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 			return -EINVAL;
 		}
 
-		hha_pmu->index_id = id;
+		hha_pmu->topo.index_id = id;
 	}
 	/* HHA PMUs only share the same SCCL */
-	hha_pmu->ccl_id = -1;
+	hha_pmu->topo.ccl_id = -1;
 
 	hha_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hha_pmu->base)) {
@@ -510,8 +510,8 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u",
-			      hha_pmu->sccl_id, hha_pmu->index_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_hha%d",
+			      hha_pmu->topo.sccl_id, hha_pmu->topo.index_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index 0d1b5d17ba26..94546738f6ba 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -360,13 +360,13 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
 	 * SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &l3c_pmu->sccl_id)) {
+				     &l3c_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Can not read l3c sccl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-				     &l3c_pmu->ccl_id)) {
+				     &l3c_pmu->topo.ccl_id)) {
 		dev_err(&pdev->dev, "Can not read l3c ccl-id!\n");
 		return -EINVAL;
 	}
@@ -544,8 +544,8 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
-			      l3c_pmu->sccl_id, l3c_pmu->ccl_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_l3c%d",
+			      l3c_pmu->topo.sccl_id, l3c_pmu->topo.ccl_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
index eaaad28871a3..3130b19e8afc 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
@@ -274,19 +274,19 @@ static int hisi_pa_pmu_init_data(struct platform_device *pdev,
 	 * to identify the PA PMU.
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &pa_pmu->sicl_id)) {
+				     &pa_pmu->topo.sicl_id)) {
 		dev_err(&pdev->dev, "Cannot read sicl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &pa_pmu->index_id)) {
+				     &pa_pmu->topo.index_id)) {
 		dev_err(&pdev->dev, "Cannot read idx-id!\n");
 		return -EINVAL;
 	}
 
-	pa_pmu->ccl_id = -1;
-	pa_pmu->sccl_id = -1;
+	pa_pmu->topo.ccl_id = -1;
+	pa_pmu->topo.sccl_id = -1;
 
 	pa_pmu->dev_info = device_get_match_data(&pdev->dev);
 	if (!pa_pmu->dev_info)
@@ -488,9 +488,9 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%d_%s%u",
-			      pa_pmu->sicl_id, pa_pmu->dev_info->name,
-			      pa_pmu->index_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%d_%s%d",
+			      pa_pmu->topo.sicl_id, pa_pmu->dev_info->name,
+			      pa_pmu->topo.index_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index dda8cff4baf4..5d4de5f27819 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -444,18 +444,19 @@ static void hisi_read_sccl_and_ccl_id(int *scclp, int *cclp)
  */
 static bool hisi_pmu_cpu_is_associated_pmu(struct hisi_pmu *hisi_pmu)
 {
+	struct hisi_pmu_topology *topo = &hisi_pmu->topo;
 	int sccl_id, ccl_id;
 
-	if (hisi_pmu->ccl_id == -1) {
+	if (topo->ccl_id == -1) {
 		/* If CCL_ID is -1, the PMU only shares the same SCCL */
 		hisi_read_sccl_and_ccl_id(&sccl_id, NULL);
 
-		return sccl_id == hisi_pmu->sccl_id;
+		return sccl_id == topo->sccl_id;
 	}
 
 	hisi_read_sccl_and_ccl_id(&sccl_id, &ccl_id);
 
-	return sccl_id == hisi_pmu->sccl_id && ccl_id == hisi_pmu->ccl_id;
+	return sccl_id == topo->sccl_id && ccl_id == topo->ccl_id;
 }
 
 int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
index bd48338ce937..f162a1b6c6d1 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
@@ -81,12 +81,43 @@ struct hisi_pmu_hwevents {
 	const struct attribute_group **attr_groups;
 };
 
+/**
+ * struct hisi_pmu_topology - Describe the topology hierarchy on which the PMU
+ *                            is located.
+ * @sccl_id: ID of the SCCL on which the PMU locate is located.
+ * @sicl_id: ID of the SICL on which the PMU locate is located.
+ * @scl_id:  ID used by the core which is unaware of the SCCL/SICL.
+ * @ccl_id: ID of the CCL (CPU cluster) on which the PMU is located.
+ * @index_id: the ID of the PMU module if there're several PMUs at a
+ *            particularly location in the topology.
+ * @sub_id: submodule ID of the PMU. For example we use this for DDRC PMU v2
+ *          since each DDRC has more than one DMC
+ *
+ * The ID will be -1 if the PMU isn't located on a certain topology.
+ */
+struct hisi_pmu_topology {
+	/*
+	 * SCCL (Super CPU CLuster) and SICL (Super I/O Cluster) are parallel
+	 * so a PMU cannot locate on a SCCL and a SICL. If the SCCL/SICL
+	 * distinction is not relevant, use scl_id instead.
+	 */
+	union {
+		int sccl_id;
+		int sicl_id;
+		int scl_id;
+	};
+	int ccl_id;
+	int index_id;
+	int sub_id;
+};
+
 /* Generic pmu struct for different pmu types */
 struct hisi_pmu {
 	struct pmu pmu;
 	const struct hisi_uncore_ops *ops;
 	const struct hisi_pmu_dev_info *dev_info;
 	struct hisi_pmu_hwevents pmu_events;
+	struct hisi_pmu_topology topo;
 	/*
 	 * CPUs associated to the PMU and are preferred to use for counting.
 	 * Could be empty if PMU has no association (e.g. PMU on SICL), in
@@ -98,14 +129,7 @@ struct hisi_pmu {
 	int irq;
 	struct device *dev;
 	struct hlist_node node;
-	int sccl_id;
-	int sicl_id;
-	int ccl_id;
 	void __iomem *base;
-	/* the ID of the PMU modules */
-	u32 index_id;
-	/* For DDRC PMU v2: each DDRC has more than one DMC */
-	u32 sub_id;
 	int num_counters;
 	int counter_bits;
 	/* check event code range */
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
index 0ef2f6797109..276534c12fa4 100644
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
@@ -293,19 +293,19 @@ static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
 	 * while SCCL_ID is from MPIDR_EL1 by CPU.
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &sllc_pmu->sccl_id)) {
+				     &sllc_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Cannot read sccl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &sllc_pmu->index_id)) {
+				     &sllc_pmu->topo.index_id)) {
 		dev_err(&pdev->dev, "Cannot read idx-id!\n");
 		return -EINVAL;
 	}
 
 	/* SLLC PMUs only share the same SCCL */
-	sllc_pmu->ccl_id = -1;
+	sllc_pmu->topo.ccl_id = -1;
 
 	sllc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(sllc_pmu->base)) {
@@ -433,8 +433,8 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_sllc%u",
-			      sllc_pmu->sccl_id, sllc_pmu->index_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_sllc%d",
+			      sllc_pmu->topo.sccl_id, sllc_pmu->topo.index_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
index 9c724dab6b64..19a44498758f 100644
--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
@@ -372,19 +372,19 @@ static int hisi_uc_pmu_init_data(struct platform_device *pdev,
 	 * They have some CCLs per SCCL and then 4 UC PMU per CCL.
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &uc_pmu->sccl_id)) {
+				     &uc_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Can not read uc sccl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-				     &uc_pmu->ccl_id)) {
+				     &uc_pmu->topo.ccl_id)) {
 		dev_err(&pdev->dev, "Can not read uc ccl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-				     &uc_pmu->sub_id)) {
+				     &uc_pmu->topo.sub_id)) {
 		dev_err(&pdev->dev, "Can not read sub-id!\n");
 		return -EINVAL;
 	}
@@ -538,8 +538,9 @@ static int hisi_uc_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_uc%d_%u",
-			      uc_pmu->sccl_id, uc_pmu->ccl_id, uc_pmu->sub_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_uc%d_%d",
+			      uc_pmu->topo.sccl_id, uc_pmu->topo.ccl_id,
+			      uc_pmu->topo.sub_id);
 	if (!name)
 		return -ENOMEM;
 
-- 
2.24.0



From peng.fan at oss.nxp.com  Tue Dec  3 05:05:29 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue,  3 Dec 2024 21:05:29 +0800
Subject: [PATCH] clk: imx: Enable IMX93_CLK_LVDS_GATE only for i.MX93
Message-ID: <20241203130530.1206526-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Enable the LVDS gate only for i.MX93, because i.MX91 does not support
LVDS.

Fixes: a27bfff88dd2 ("clk: imx: add i.MX91 clk")
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/clk/imx/clk-imx93.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
index 58a516dd385b..a0d2972ba9cd 100644
--- a/drivers/clk/imx/clk-imx93.c
+++ b/drivers/clk/imx/clk-imx93.c
@@ -239,7 +239,7 @@ static const struct imx93_clk_ccgr {
 	{ IMX93_CLK_SAI3_IPG,		"sai3_ipg_clk", "bus_wakeup_root",	0x94c0, 0, &share_count_sai3},
 	{ IMX93_CLK_MIPI_CSI_GATE,	"mipi_csi",	"media_apb_root",	0x9580, },
 	{ IMX93_CLK_MIPI_DSI_GATE,	"mipi_dsi",	"media_apb_root",	0x95c0, },
-	{ IMX93_CLK_LVDS_GATE,		"lvds",		"media_ldb_root",	0x9600, },
+	{ IMX93_CLK_LVDS_GATE,		"lvds",		"media_ldb_root",	0x9600, 0, NULL, PLAT_IMX93 },
 	{ IMX93_CLK_LCDIF_GATE,		"lcdif",	"media_apb_root",	0x9640, },
 	{ IMX93_CLK_PXP_GATE,		"pxp",		"media_apb_root",	0x9680, },
 	{ IMX93_CLK_ISI_GATE,		"isi",		"media_apb_root",	0x96c0, },
-- 
2.37.1



From tudor.ambarus at linaro.org  Tue Dec  3 05:09:20 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue, 3 Dec 2024 13:09:20 +0000
Subject: [PATCH] MAINTAINERS: add myself and Tudor as reviewers for Google
 Tensor SoC
In-Reply-To: <20241203-gs101-maintainers-v1-1-f287036dbde5@linaro.org>
References: <20241203-gs101-maintainers-v1-1-f287036dbde5@linaro.org>
Message-ID: <dad1bbd4-0eee-480a-8a2a-08157dd609d8@linaro.org>


On 12/3/24 1:03 PM, Andr? Draszik wrote:
> Add myself and Tudor as reviewers for the Google Tensor SoC alongside

Acked-by: Tudor Ambarus <tudor.ambarus at linaro.org>


From ot_chhao.chang at mediatek.com  Tue Dec  3 05:12:54 2024
From: ot_chhao.chang at mediatek.com (chang hao)
Date: Tue, 3 Dec 2024 21:12:54 +0800
Subject: [PATCH] v1 pinctrl: mtk-eint: add eint new design for mt8196
Message-ID: <20241203131302.16022-1-ot_chhao.chang@mediatek.com>

From: Chhao Chang <ot_chhao.chang at mediatek.com>

Change 1: change EINT from 1 address to 5 addresses,
Eint number is stored on each base.
Change 2: Compatible with 1 address design

Signed-off-by: Chhao Chang <ot_chhao.chang at mediatek.com>
---
 drivers/pinctrl/mediatek/mtk-eint.c           | 943 ++++++++++++++----
 drivers/pinctrl/mediatek/mtk-eint.h           |  87 +-
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  |  50 +-
 3 files changed, 843 insertions(+), 237 deletions(-)

diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
index 27f0a54e12bf..f7788166c335 100644
--- a/drivers/pinctrl/mediatek/mtk-eint.c
+++ b/drivers/pinctrl/mediatek/mtk-eint.c
@@ -1,21 +1,24 @@
 // SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2014-2018 MediaTek Inc.
-
+// Copyright (c) 2014-2024 MediaTek Inc.
 /*
  * Library for MediaTek External Interrupt Support
  *
  * Author: Maoguang Meng <maoguang.meng at mediatek.com>
- *	   Sean Wang <sean.wang at mediatek.com>
- *
+ * Sean Wang <sean.wang at mediatek.com>
+ * Chhao Chang <ot_chhao.chang at mediatek.com>
  */
 
+#include <linux/atomic.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
 #include <linux/io.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
 
@@ -23,10 +26,14 @@
 
 #define MTK_EINT_EDGE_SENSITIVE           0
 #define MTK_EINT_LEVEL_SENSITIVE          1
-#define MTK_EINT_DBNC_SET_DBNC_BITS	  4
-#define MTK_EINT_DBNC_MAX		  16
-#define MTK_EINT_DBNC_RST_BIT		  (0x1 << 1)
-#define MTK_EINT_DBNC_SET_EN		  (0x1 << 0)
+#define MTK_EINT_DBNC_SET_DBNC_BITS       4
+#define MTK_EINT_DBNC_MAX                 32
+#define MTK_EINT_DBNC_RST_BIT             (0x1 << 1)
+#define MTK_EINT_DBNC_SET_EN              (0x1 << 0)
+
+#define MTK_EINT_NO_OFFSET                0
+
+static struct mtk_eint *global_eintc;
 
 static const struct mtk_eint_regs mtk_generic_eint_regs = {
 	.stat      = 0x000,
@@ -47,6 +54,10 @@ static const struct mtk_eint_regs mtk_generic_eint_regs = {
 	.dbnc_ctrl = 0x500,
 	.dbnc_set  = 0x600,
 	.dbnc_clr  = 0x700,
+	.event     = 0x800,
+	.event_set = 0x840,
+	.event_clr = 0x880,
+	.raw_stat  = 0xa00,
 };
 
 const unsigned int debounce_time_mt2701[] = {
@@ -64,60 +75,122 @@ const unsigned int debounce_time_mt6795[] = {
 };
 EXPORT_SYMBOL_GPL(debounce_time_mt6795);
 
+/*
+ * Return the iomem of specific register offset and decode the coordinate
+ * (instance, index) from global eint number.
+ * If return NULL, then it must be either out-of-range or do-not-support.
+ */
 static void __iomem *mtk_eint_get_offset(struct mtk_eint *eint,
 					 unsigned int eint_num,
-					 unsigned int offset)
+					 unsigned int offset,
+					 unsigned int *instance,
+					 unsigned int *index)
 {
-	unsigned int eint_base = 0;
 	void __iomem *reg;
 
-	if (eint_num >= eint->hw->ap_num)
-		eint_base = eint->hw->ap_num;
+	if (eint_num >= eint->total_pin_number ||
+	    !eint->pins[eint_num].enabled) {
+		WARN_ON(1);
+		return NULL;
+	}
 
-	reg = eint->base + offset + ((eint_num - eint_base) / 32) * 4;
+	*instance = eint->pins[eint_num].instance;
+	*index = eint->pins[eint_num].index;
+	reg = eint->instances[*instance].base + offset + (*index / 32 * 4);
 
 	return reg;
 }
 
+/*
+ * Generate helper function to access property register of a dedicate pin.
+ */
+#define DEFINE_EINT_GET_FUNCTION(_NAME, _OFFSET) \
+static unsigned int mtk_eint_get_##_NAME(struct mtk_eint *eint, \
+				   unsigned int eint_num) \
+{ \
+	unsigned int instance, index; \
+	void __iomem *reg = mtk_eint_get_offset(eint, eint_num, \
+						_OFFSET, \
+						&instance, &index); \
+	unsigned int bit = BIT(index & 0x1f);\
+\
+	if (!reg) { \
+		dev_err(eint->dev, "%s invalid eint_num %d\n", \
+			__func__, eint_num); \
+		return 0;\
+	} \
+\
+	return !!(readl(reg) & bit); \
+}
+
+DEFINE_EINT_GET_FUNCTION(stat, eint->comp->regs->stat);
+DEFINE_EINT_GET_FUNCTION(mask, eint->comp->regs->mask);
+DEFINE_EINT_GET_FUNCTION(sens, eint->comp->regs->sens);
+DEFINE_EINT_GET_FUNCTION(pol, eint->comp->regs->pol);
+DEFINE_EINT_GET_FUNCTION(soft, eint->comp->regs->soft);
+DEFINE_EINT_GET_FUNCTION(raw_stat, eint->comp->regs->raw_stat);
+
 static unsigned int mtk_eint_can_en_debounce(struct mtk_eint *eint,
 					     unsigned int eint_num)
 {
 	unsigned int sens;
-	unsigned int bit = BIT(eint_num % 32);
+	unsigned int instance, index;
 	void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
-						eint->regs->sens);
+						eint->comp->regs->sens,
+						&instance, &index);
+	unsigned int bit = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return 0;
+	}
 
 	if (readl(reg) & bit)
 		sens = MTK_EINT_LEVEL_SENSITIVE;
 	else
 		sens = MTK_EINT_EDGE_SENSITIVE;
 
-	if (eint_num < eint->hw->db_cnt && sens != MTK_EINT_EDGE_SENSITIVE)
+	if (eint->pins[eint_num].debounce &&
+	    sens != MTK_EINT_EDGE_SENSITIVE)
 		return 1;
 	else
 		return 0;
 }
 
-static int mtk_eint_flip_edge(struct mtk_eint *eint, int hwirq)
+static int mtk_eint_flip_edge(struct mtk_eint *eint, int eint_num)
 {
 	int start_level, curr_level;
 	unsigned int reg_offset;
-	u32 mask = BIT(hwirq & 0x1f);
-	u32 port = (hwirq >> 5) & eint->hw->port_mask;
-	void __iomem *reg = eint->base + (port << 2);
+	unsigned int instance, index, mask, port;
+	void __iomem *reg;
+
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return 0;
+	}
+
+	mask = BIT(index & 0x1f);
+	port = index >> 5;
+	reg = eint->instances[instance].base + port * 4;
 
-	curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl, hwirq);
+	curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl, eint_num);
 
 	do {
 		start_level = curr_level;
 		if (start_level)
-			reg_offset = eint->regs->pol_clr;
+			reg_offset = eint->comp->regs->pol_clr;
 		else
-			reg_offset = eint->regs->pol_set;
+			reg_offset = eint->comp->regs->pol_set;
+
 		writel(mask, reg + reg_offset);
 
 		curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl,
-							      hwirq);
+							      eint_num);
 	} while (start_level != curr_level);
 
 	return start_level;
@@ -126,11 +199,19 @@ static int mtk_eint_flip_edge(struct mtk_eint *eint, int hwirq)
 static void mtk_eint_mask(struct irq_data *d)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	u32 mask = BIT(d->hwirq & 0x1f);
+	unsigned int instance, index;
 	void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
-						eint->regs->mask_set);
+						eint->comp->regs->mask_set,
+						&instance, &index);
+	u32 mask = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, d->hwirq);
+		return;
+	}
 
-	eint->cur_mask[d->hwirq >> 5] &= ~mask;
+	eint->instances[instance].cur_mask[index >> 5] &= ~mask;
 
 	writel(mask, reg);
 }
@@ -138,43 +219,89 @@ static void mtk_eint_mask(struct irq_data *d)
 static void mtk_eint_unmask(struct irq_data *d)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	u32 mask = BIT(d->hwirq & 0x1f);
+	unsigned int instance, index;
 	void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
-						eint->regs->mask_clr);
+						eint->comp->regs->mask_clr,
+						&instance, &index);
+	u32 mask = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, d->hwirq);
+		return;
+	}
 
-	eint->cur_mask[d->hwirq >> 5] |= mask;
+	eint->instances[instance].cur_mask[index >> 5] |= mask;
 
 	writel(mask, reg);
 
-	if (eint->dual_edge[d->hwirq])
+	if (eint->pins[d->hwirq].dual_edge)
 		mtk_eint_flip_edge(eint, d->hwirq);
 }
 
-static unsigned int mtk_eint_get_mask(struct mtk_eint *eint,
-				      unsigned int eint_num)
+static void mtk_eint_ack(struct irq_data *d)
+{
+	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+	unsigned int instance, index;
+	void __iomem *reg;
+	unsigned int bit;
+
+	if (eint->comp->ops.ack) {
+		eint->comp->ops.ack(d);
+	} else {
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->ack,
+					  &instance, &index);
+		bit = BIT(index & 0x1f);
+		if (!reg) {
+			dev_err(eint->dev, "%s invalid eint_num %lu\n",
+				__func__, d->hwirq);
+			return;
+		}
+
+		writel(bit, reg);
+	}
+}
+
+static void mtk_eint_soft_set(struct mtk_eint *eint, unsigned int eint_num)
 {
-	unsigned int bit = BIT(eint_num % 32);
+	unsigned int instance, index;
 	void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
-						eint->regs->mask);
+						eint->comp->regs->soft_set,
+						&instance, &index);
+	unsigned int bit = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return;
+	}
 
-	return !!(readl(reg) & bit);
+	writel(bit, reg);
 }
 
-static void mtk_eint_ack(struct irq_data *d)
+static void mtk_eint_soft_clr(struct mtk_eint *eint, unsigned int eint_num)
 {
-	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	u32 mask = BIT(d->hwirq & 0x1f);
-	void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
-						eint->regs->ack);
+	unsigned int instance, index;
+	void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
+						eint->comp->regs->soft_clr,
+						&instance, &index);
+	unsigned int bit = BIT(index & 0x1f);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return;
+	}
 
-	writel(mask, reg);
+	writel(bit, reg);
 }
 
 static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	bool masked;
-	u32 mask = BIT(d->hwirq & 0x1f);
+	u32 mask;
+	unsigned int instance, index;
 	void __iomem *reg;
 
 	if (((type & IRQ_TYPE_EDGE_BOTH) && (type & IRQ_TYPE_LEVEL_MASK)) ||
@@ -186,36 +313,42 @@ static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
 	}
 
 	if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
-		eint->dual_edge[d->hwirq] = 1;
+		eint->pins[d->hwirq].dual_edge = 1;
 	else
-		eint->dual_edge[d->hwirq] = 0;
+		eint->pins[d->hwirq].dual_edge = 0;
 
-	if (!mtk_eint_get_mask(eint, d->hwirq)) {
-		mtk_eint_mask(d);
-		masked = false;
-	} else {
-		masked = true;
-	}
+	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->pol_clr,
+					  &instance, &index);
+	else
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->pol_set,
+					  &instance, &index);
 
-	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) {
-		reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_clr);
-		writel(mask, reg);
-	} else {
-		reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_set);
-		writel(mask, reg);
-	}
+	mask = BIT(index & 0x1f);
+	writel(mask, reg);
 
-	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
-		reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_clr);
-		writel(mask, reg);
-	} else {
-		reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_set);
-		writel(mask, reg);
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->sens_clr,
+					  &instance, &index);
+	else
+		reg = mtk_eint_get_offset(eint, d->hwirq,
+					  eint->comp->regs->sens_set,
+					  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, d->hwirq);
+		return 0;
 	}
 
-	mtk_eint_ack(d);
-	if (!masked)
-		mtk_eint_unmask(d);
+	mask = BIT(index & 0x1f);
+	writel(mask, reg);
+
+	if (eint->pins[d->hwirq].dual_edge)
+		mtk_eint_flip_edge(eint, d->hwirq);
 
 	return 0;
 }
@@ -223,30 +356,28 @@ static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
 static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
-	int shift = d->hwirq & 0x1f;
-	int reg = d->hwirq >> 5;
+	unsigned int instance, index, shift, port;
+	void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
+						MTK_EINT_NO_OFFSET,
+						&instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, d->hwirq);
+		return 0;
+	}
+
+	shift = index & 0x1f;
+	port = index >> 5;
 
 	if (on)
-		eint->wake_mask[reg] |= BIT(shift);
+		eint->instances[instance].wake_mask[port] |= BIT(shift);
 	else
-		eint->wake_mask[reg] &= ~BIT(shift);
+		eint->instances[instance].wake_mask[port] &= ~BIT(shift);
 
 	return 0;
 }
 
-static void mtk_eint_chip_write_mask(const struct mtk_eint *eint,
-				     void __iomem *base, u32 *buf)
-{
-	int port;
-	void __iomem *reg;
-
-	for (port = 0; port < eint->hw->ports; port++) {
-		reg = base + (port << 2);
-		writel_relaxed(~buf[port], reg + eint->regs->mask_set);
-		writel_relaxed(buf[port], reg + eint->regs->mask_clr);
-	}
-}
-
 static int mtk_eint_irq_request_resources(struct irq_data *d)
 {
 	struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
@@ -258,23 +389,25 @@ static int mtk_eint_irq_request_resources(struct irq_data *d)
 					   &gpio_n, &gpio_c);
 	if (err < 0) {
 		dev_err(eint->dev, "Can not find pin\n");
-		return err;
+		goto err_out;
 	}
 
 	err = gpiochip_lock_as_irq(gpio_c, gpio_n);
 	if (err < 0) {
 		dev_err(eint->dev, "unable to lock HW IRQ %lu for IRQ\n",
 			irqd_to_hwirq(d));
-		return err;
+		goto err_out;
 	}
 
 	err = eint->gpio_xlate->set_gpio_as_eint(eint->pctl, d->hwirq);
 	if (err < 0) {
 		dev_err(eint->dev, "Can not eint mode\n");
-		return err;
+		goto err_out;
 	}
 
 	return 0;
+err_out:
+	return err;
 }
 
 static void mtk_eint_irq_release_resources(struct irq_data *d)
@@ -290,7 +423,7 @@ static void mtk_eint_irq_release_resources(struct irq_data *d)
 }
 
 static struct irq_chip mtk_eint_irq_chip = {
-	.name = "mt-eint",
+	.name = "mtk-eint",
 	.irq_disable = mtk_eint_mask,
 	.irq_mask = mtk_eint_mask,
 	.irq_unmask = mtk_eint_unmask,
@@ -301,35 +434,53 @@ static struct irq_chip mtk_eint_irq_chip = {
 	.irq_release_resources = mtk_eint_irq_release_resources,
 };
 
+/*
+ * Configure all EINT pins as domain 0, which only belongs to AP.
+ */
 static unsigned int mtk_eint_hw_init(struct mtk_eint *eint)
 {
-	void __iomem *dom_en = eint->base + eint->regs->dom_en;
-	void __iomem *mask_set = eint->base + eint->regs->mask_set;
-	unsigned int i;
-
-	for (i = 0; i < eint->hw->ap_num; i += 32) {
-		writel(0xffffffff, dom_en);
-		writel(0xffffffff, mask_set);
-		dom_en += 4;
-		mask_set += 4;
+	void __iomem *dom_en, *event_clr;
+	unsigned int i, j;
+
+	for (i = 0; i < eint->instance_number; i++) {
+		dom_en = eint->instances[i].base + eint->comp->regs->dom_en;
+		event_clr = eint->instances[i].base + eint->comp->regs->event_clr;
+		for (j = 0; j < eint->instances[i].number; j += 32) {
+			writel(0xffffffff, dom_en);
+			writel(0xffffffff, event_clr);
+			dom_en += 4;
+			event_clr += 4;
+		}
 	}
 
 	return 0;
 }
 
 static inline void
-mtk_eint_debounce_process(struct mtk_eint *eint, int index)
+mtk_eint_debounce_process(struct mtk_eint *eint, int eint_num)
 {
 	unsigned int rst, ctrl_offset;
 	unsigned int bit, dbnc;
+	unsigned int instance, index;
+	void __iomem *reg;
+
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
 
-	ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_ctrl;
-	dbnc = readl(eint->base + ctrl_offset);
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return;
+	}
+
+	ctrl_offset = (index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
+	dbnc = readl(eint->instances[instance].base + ctrl_offset);
 	bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
+
 	if ((bit & dbnc) > 0) {
-		ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_set;
+		ctrl_offset = (index / 4) * 4 + eint->comp->regs->dbnc_set;
 		rst = MTK_EINT_DBNC_RST_BIT << ((index % 4) * 8);
-		writel(rst, eint->base + ctrl_offset);
+		writel(rst, eint->instances[instance].base + ctrl_offset);
 	}
 }
 
@@ -337,65 +488,66 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct mtk_eint *eint = irq_desc_get_handler_data(desc);
-	unsigned int status, eint_num;
-	int offset, mask_offset, index;
-	void __iomem *reg =  mtk_eint_get_offset(eint, 0, eint->regs->stat);
-	int dual_edge, start_level, curr_level;
+	unsigned int status, i, j;
+	int shift, port, eint_num, virq;
+	unsigned int dual_edge, start_level, curr_level;
+	struct mtk_eint_instance eint_instance;
+	void __iomem *addr;
 
 	chained_irq_enter(chip, desc);
-	for (eint_num = 0; eint_num < eint->hw->ap_num; eint_num += 32,
-	     reg += 4) {
-		status = readl(reg);
-		while (status) {
-			offset = __ffs(status);
-			mask_offset = eint_num >> 5;
-			index = eint_num + offset;
-			status &= ~BIT(offset);
-
-			/*
-			 * If we get an interrupt on pin that was only required
-			 * for wake (but no real interrupt requested), mask the
-			 * interrupt (as would mtk_eint_resume do anyway later
-			 * in the resume sequence).
-			 */
-			if (eint->wake_mask[mask_offset] & BIT(offset) &&
-			    !(eint->cur_mask[mask_offset] & BIT(offset))) {
-				writel_relaxed(BIT(offset), reg -
-					eint->regs->stat +
-					eint->regs->mask_set);
-			}
 
-			dual_edge = eint->dual_edge[index];
-			if (dual_edge) {
-				/*
-				 * Clear soft-irq in case we raised it last
-				 * time.
-				 */
-				writel(BIT(offset), reg - eint->regs->stat +
-				       eint->regs->soft_clr);
-
-				start_level =
-				eint->gpio_xlate->get_gpio_state(eint->pctl,
-								 index);
-			}
+	for (i = 0; i < eint->instance_number; i++) {
+		eint_instance = eint->instances[i];
 
-			generic_handle_domain_irq(eint->domain, index);
+		/* Iterate all pins by port */
+		for (j = 0; j < eint_instance.number; j += 32) {
+			port = j >> 5;
+			status = readl(eint_instance.base + port * 4 +
+				       eint->comp->regs->stat);
+			while (status) {
+				shift = __ffs(status);
+				status &= ~BIT(shift);
 
-			if (dual_edge) {
-				curr_level = mtk_eint_flip_edge(eint, index);
+				eint_num = eint->instances[i].pin_list[shift + j];
+				virq = irq_find_mapping(eint->domain, eint_num);
 
 				/*
-				 * If level changed, we might lost one edge
-				 * interrupt, raised it through soft-irq.
+				 * If we get an interrupt on pin that was only required
+				 * for wake (but no real interrupt requested), mask the
+				 * interrupt (as would mtk_eint_resume do anyway later
+				 * in the resume sequence).
 				 */
-				if (start_level != curr_level)
-					writel(BIT(offset), reg -
-					       eint->regs->stat +
-					       eint->regs->soft_set);
+				if (eint->instances[i].wake_mask[port] & BIT(shift) &&
+				    !(eint->instances[i].cur_mask[port] & BIT(shift))) {
+					addr = eint_instance.base + port * 4 +
+						eint->comp->regs->mask_set;
+					writel_relaxed(BIT(shift), addr);
+				}
+
+				dual_edge = eint->pins[eint_num].dual_edge;
+				if (dual_edge)
+					start_level =
+					eint->gpio_xlate->get_gpio_state(eint->pctl,
+									 eint_num);
+
+				generic_handle_irq(virq);
+
+				if (dual_edge) {
+					curr_level = mtk_eint_flip_edge(eint, eint_num);
+
+					/*
+					 * If level changed, we might lost one edge
+					 * interrupt, raised it through soft-irq.
+					 */
+					if (start_level != curr_level)
+						mtk_eint_soft_set(eint, eint_num);
+
+					mtk_eint_soft_clr(eint, eint_num);
+				}
+
+				if (eint->pins[eint_num].debounce)
+					mtk_eint_debounce_process(eint, eint_num);
 			}
-
-			if (index < eint->hw->db_cnt)
-				mtk_eint_debounce_process(eint, index);
 		}
 	}
 	chained_irq_exit(chip, desc);
@@ -403,7 +555,19 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
 
 int mtk_eint_do_suspend(struct mtk_eint *eint)
 {
-	mtk_eint_chip_write_mask(eint, eint->base, eint->wake_mask);
+	unsigned int i, j, port;
+
+	for (i = 0; i < eint->instance_number; i++) {
+		struct mtk_eint_instance inst = eint->instances[i];
+
+		for (j = 0; j < inst.number; j += 32) {
+			port = j >> 5;
+			writel_relaxed(~inst.wake_mask[port],
+				       inst.base + port * 4 + eint->comp->regs->mask_set);
+			writel_relaxed(inst.wake_mask[port],
+				       inst.base + port * 4 + eint->comp->regs->mask_clr);
+		}
+	}
 
 	return 0;
 }
@@ -411,7 +575,19 @@ EXPORT_SYMBOL_GPL(mtk_eint_do_suspend);
 
 int mtk_eint_do_resume(struct mtk_eint *eint)
 {
-	mtk_eint_chip_write_mask(eint, eint->base, eint->cur_mask);
+	unsigned int i, j, port;
+
+	for (i = 0; i < eint->instance_number; i++) {
+		struct mtk_eint_instance inst = eint->instances[i];
+
+		for (j = 0; j < inst.number; j += 32) {
+			port = j >> 5;
+			writel_relaxed(~inst.cur_mask[port],
+				       inst.base + port * 4 + eint->comp->regs->mask_set);
+			writel_relaxed(inst.cur_mask[port],
+				       inst.base + port * 4 + eint->comp->regs->mask_clr);
+		}
+	}
 
 	return 0;
 }
@@ -423,24 +599,42 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
 	int virq, eint_offset;
 	unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask,
 		     dbnc;
+	static const unsigned int debounce_time[] = { 156, 313, 625, 1250,
+		20000, 40000, 80000, 160000, 320000, 640000 };
 	struct irq_data *d;
+	unsigned int instance, index;
+	void __iomem *reg;
+
+	/*
+	 * Due to different number of bit field, we only decode
+	 * the coordinate here, instead of get the VA.
+	 */
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
 
-	if (!eint->hw->db_time)
-		return -EOPNOTSUPP;
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %lu\n",
+			__func__, eint_num);
+		return 0;
+	}
 
 	virq = irq_find_mapping(eint->domain, eint_num);
-	eint_offset = (eint_num % 4) * 8;
+	eint_offset = (index % 4) * 8;
 	d = irq_get_irq_data(virq);
 
-	set_offset = (eint_num / 4) * 4 + eint->regs->dbnc_set;
-	clr_offset = (eint_num / 4) * 4 + eint->regs->dbnc_clr;
+	reg = eint->instances[instance].base;
+	set_offset = (index / 4) * 4 + eint->comp->regs->dbnc_set;
+	clr_offset = (index / 4) * 4 + eint->comp->regs->dbnc_clr;
 
 	if (!mtk_eint_can_en_debounce(eint, eint_num))
 		return -EINVAL;
 
-	dbnc = eint->num_db_time;
-	for (i = 0; i < eint->num_db_time; i++) {
-		if (debounce <= eint->hw->db_time[i]) {
+	/*
+	 * Check eint number to avoid access out-of-range
+	 */
+	dbnc = ARRAY_SIZE(debounce_time) - 1;
+	for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
+		if (debounce <= debounce_time[i]) {
 			dbnc = i;
 			break;
 		}
@@ -454,18 +648,16 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
 	}
 
 	clr_bit = 0xff << eint_offset;
-	writel(clr_bit, eint->base + clr_offset);
+	writel(clr_bit, reg + clr_offset);
 
-	bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS) | MTK_EINT_DBNC_SET_EN) <<
-		eint_offset;
+	bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS)
+		| MTK_EINT_DBNC_SET_EN) << eint_offset;
 	rst = MTK_EINT_DBNC_RST_BIT << eint_offset;
-	writel(rst | bit, eint->base + set_offset);
+	writel(rst | bit, reg + set_offset);
+
+	/* Delay should be (8T @ 32k) from dbc rst to work correctly. */
+	udelay(250);
 
-	/*
-	 * Delay a while (more than 2T) to wait for hw debounce counter reset
-	 * work correctly.
-	 */
-	udelay(1);
 	if (unmask == 1)
 		mtk_eint_unmask(d);
 
@@ -473,6 +665,53 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
 }
 EXPORT_SYMBOL_GPL(mtk_eint_set_debounce);
 
+static unsigned int mtk_eint_get_debounce_en(struct mtk_eint *eint,
+				      unsigned int eint_num)
+{
+	unsigned int instance, index, bit;
+	void __iomem *reg;
+
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return 0;
+	}
+
+	reg = eint->instances[instance].base +
+		(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
+
+	bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
+
+	return (readl(reg) & bit) ? 1 : 0;
+}
+
+static unsigned int mtk_eint_get_debounce_value(struct mtk_eint *eint,
+					 unsigned int eint_num)
+{
+	unsigned int instance, index, mask, offset;
+	void __iomem *reg;
+
+	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
+				  &instance, &index);
+
+	if (!reg) {
+		dev_err(eint->dev, "%s invalid eint_num %d\n",
+			__func__, eint_num);
+		return 0;
+	}
+
+	reg = eint->instances[instance].base +
+		(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
+
+	offset = MTK_EINT_DBNC_SET_DBNC_BITS + ((index % 4) * 8);
+	mask = 0xf << offset;
+
+	return ((readl(reg) & mask) >> offset);
+}
+
 int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
 {
 	int irq;
@@ -485,44 +724,349 @@ int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
 }
 EXPORT_SYMBOL_GPL(mtk_eint_find_irq);
 
+/*
+ * Dump the properties/states of the specific EINT pin.
+ * @eint_num: the global EINT number.
+ * @buf: the pointer of a string buffer.
+ * @buf_size: the size of the buffer.
+ *
+ * If the return value < 0, it means that the @eint_num is invalid;
+ * Otherwise, return 0;
+ */
+int dump_eint_pin_status(unsigned int eint_num, char *buf, unsigned int buf_size)
+{
+	unsigned int len = 0, enabled, stat, raw_stat, soft, mask, sens, pol,
+		     deb_en, deb_val;
+
+	if (eint_num < 0 || eint_num >= global_eintc->total_pin_number)
+		return -ENODEV;
+
+	enabled = global_eintc->pins[eint_num].enabled;
+	stat = mtk_eint_get_stat(global_eintc, eint_num);
+	raw_stat = mtk_eint_get_raw_stat(global_eintc, eint_num);
+	soft = mtk_eint_get_soft(global_eintc, eint_num);
+	mask = mtk_eint_get_mask(global_eintc, eint_num);
+	sens = mtk_eint_get_sens(global_eintc, eint_num);
+	pol = mtk_eint_get_pol(global_eintc, eint_num);
+
+	len += snprintf(buf + len, buf_size - len,
+			"%s=%u(%s)\n%s=%s_%s\n%s=%u\n%s=%u\n%s=%u\n%s=%u\n",
+			"Pin", eint_num, enabled ? "enabled" : "disabled",
+			"Type", (sens == 1) ? "level" : "edge",
+			(pol == 1) ? "high" : "low",
+			"Pending", stat,
+			"Raw", raw_stat,
+			"Soft", soft,
+			"Mask", mask);
+
+	if (mtk_eint_can_en_debounce(global_eintc, eint_num)) {
+		deb_en	= mtk_eint_get_debounce_en(global_eintc, eint_num);
+		deb_val = mtk_eint_get_debounce_value(global_eintc, eint_num);
+
+		len += snprintf(buf + len, buf_size - len,
+				"Support debounce, %s=%u, %s=%u\n",
+				"enable", deb_en,
+				"setting", deb_val);
+	} else {
+		len += snprintf(buf + len, buf_size - len,
+				"Not support debounce\n");
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dump_eint_pin_status);
+
+static ssize_t eintc_status_show(struct device_driver *driver, char *buf)
+{
+	struct mtk_eint *eint = global_eintc;
+	unsigned int i, j, len = 0,
+		     instance_num = eint->instance_number;
+
+	len += snprintf(buf + len, PAGE_SIZE - len, "=====EINTC Dump=====\n");
+
+	for (i = 0; i < instance_num; i++) {
+		struct mtk_eint_instance inst = eint->instances[i];
+
+		len += snprintf(buf + len, PAGE_SIZE - len,
+				"Instance %d name=%s with %u pins\n",
+				i, inst.name, inst.number);
+
+		for (j = 0; j < inst.number; j++)
+			len += snprintf(buf + len, PAGE_SIZE - len,
+					"%d ", inst.pin_list[j]);
+
+		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+	}
+
+	return strlen(buf);
+}
+
+static DRIVER_ATTR_RO(eintc_status);
+
+static ssize_t eint_pin_status_show(struct device_driver *driver, char *buf)
+{
+	struct mtk_eint *eint = global_eintc;
+	unsigned int len = 0;
+
+	len += snprintf(buf + len, PAGE_SIZE - len,
+			"=====EINT Pin Dump=====\n");
+
+	dump_eint_pin_status(eint->dump_target_eint,
+			     buf + len, PAGE_SIZE - len);
+
+	return strlen(buf);
+}
+
+static ssize_t eint_pin_status_store(struct device_driver *driver,
+				     const char *buf, size_t count)
+{
+	int eint_num, ret;
+
+	ret = kstrtouint(buf, 10, &eint_num);
+
+	if (ret || eint_num >= global_eintc->total_pin_number) {
+		dev_err(global_eintc->dev,
+			"%s invalid input: %s.\n", __func__, buf);
+		goto err_out;
+	}
+
+	global_eintc->dump_target_eint = (unsigned int)eint_num;
+
+err_out:
+	return count;
+}
+
+static DRIVER_ATTR_RW(eint_pin_status);
+
+static const struct mtk_eint_compatible default_compat = {
+	.regs = &mtk_generic_eint_regs,
+};
+
 int mtk_eint_do_init(struct mtk_eint *eint)
 {
-	int i;
+	int i, virq;
+	unsigned int ret, size, inst = 0;
 
-	/* If clients don't assign a specific regs, let's use generic one */
-	if (!eint->regs)
-		eint->regs = &mtk_generic_eint_regs;
+	eint->instance_number = 1;
+	eint->total_pin_number = eint->hw->ap_num;
 
-	eint->wake_mask = devm_kcalloc(eint->dev, eint->hw->ports,
-				       sizeof(*eint->wake_mask), GFP_KERNEL);
-	if (!eint->wake_mask)
-		return -ENOMEM;
+	dev_info(eint->dev, "%s read ap_num: %u\n", __func__, eint->hw->ap_num);
 
-	eint->cur_mask = devm_kcalloc(eint->dev, eint->hw->ports,
-				      sizeof(*eint->cur_mask), GFP_KERNEL);
-	if (!eint->cur_mask)
+	size = eint->instance_number * sizeof(struct mtk_eint_instance);
+	eint->instances = devm_kzalloc(eint->dev, size, GFP_KERNEL);
+	if (!eint->instances)
 		return -ENOMEM;
 
-	eint->dual_edge = devm_kcalloc(eint->dev, eint->hw->ap_num,
-				       sizeof(int), GFP_KERNEL);
-	if (!eint->dual_edge)
+	size = eint->total_pin_number * sizeof(struct mtk_eint_pin);
+	eint->pins = devm_kzalloc(eint->dev, size, GFP_KERNEL);
+	if (!eint->pins)
 		return -ENOMEM;
 
+	for (i = 0; i < eint->total_pin_number; i++) {
+		eint->pins[i].enabled = true;
+		eint->pins[i].instance = inst;
+		eint->pins[i].index = i;
+		eint->pins[i].debounce =  (i < eint->hw->db_cnt) ? 1 : 0;
+
+		eint->instances[inst].pin_list[i] = i;
+		eint->instances[inst].number++;
+	}
+
+	for (i = 0; i < eint->instance_number; i++) {
+		size = (eint->instances[i].number / 32 + 1) * sizeof(unsigned int);
+		eint->instances[i].wake_mask =
+			devm_kzalloc(eint->dev, size, GFP_KERNEL);
+		eint->instances[i].cur_mask =
+			devm_kzalloc(eint->dev, size, GFP_KERNEL);
+
+		if (!eint->instances[i].wake_mask ||
+		    !eint->instances[i].cur_mask)
+			return -ENOMEM;
+	}
+
+	eint->comp = &default_compat;
+
 	eint->domain = irq_domain_add_linear(eint->dev->of_node,
-					     eint->hw->ap_num,
+					     eint->total_pin_number,
 					     &irq_domain_simple_ops, NULL);
 	if (!eint->domain)
 		return -ENOMEM;
 
-	if (eint->hw->db_time) {
-		for (i = 0; i < MTK_EINT_DBNC_MAX; i++)
-			if (eint->hw->db_time[i] == 0)
-				break;
-		eint->num_db_time = i;
+	eint->instances[inst].base = eint->base;
+
+	mtk_eint_hw_init(eint);
+
+	for (i = 0; i < eint->total_pin_number; i++) {
+		virq = irq_create_mapping(eint->domain, i);
+
+		irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
+					 handle_level_irq);
+		irq_set_chip_data(virq, eint);
+	}
+
+	irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler,
+					 eint);
+
+	ret = driver_create_file(eint->dev->driver,
+				 &driver_attr_eintc_status);
+
+	ret |= driver_create_file(eint->dev->driver,
+				  &driver_attr_eint_pin_status);
+
+	if (ret)
+		dev_err(eint->dev, "%s create sysfs files failed.\n", __func__);
+
+	global_eintc = eint;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mtk_eint_do_init);
+
+int mtk_eint_do_init_v2(struct mtk_eint *eint)
+{
+	int i, matrix_number = 0;
+	struct device_node *node;
+	unsigned int ret, size, offset;
+	unsigned int id, inst, idx, support_deb;
+
+	const phandle *ph;
+
+#if defined(MTK_EINT_DEBUG)
+	struct mtk_eint_pin pin;
+#endif
+
+	ph = of_get_property(eint->dev->of_node, "mediatek,eint", NULL);
+	if (!ph) {
+		dev_err(eint->dev, "Cannot find EINT phandle in PIO node.\n");
+		return -ENODEV;
+	}
+
+	node = of_find_node_by_phandle(be32_to_cpup(ph));
+	if (!node) {
+		dev_err(eint->dev, "Cannot find EINT node by phandle.\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(node, "mediatek,total-pin-number",
+				   &eint->total_pin_number);
+	if (ret) {
+		dev_err(eint->dev, "%s Get total pin Fail.\n", __func__);
+		return -EINVAL;
+	}
+
+	dev_info(eint->dev, "%s eint total pins:%u.\n",
+		 __func__, eint->total_pin_number);
+
+	ret = of_property_read_u32(node, "mediatek,instance-num",
+				   &eint->instance_number);
+	if (ret)
+		eint->instance_number = 1;
+
+	size = eint->instance_number * sizeof(struct mtk_eint_instance);
+	eint->instances = devm_kzalloc(eint->dev, size, GFP_KERNEL);
+	if (!eint->instances)
+		return -ENOMEM;
+
+	size = eint->total_pin_number * sizeof(struct mtk_eint_pin);
+	eint->pins = devm_kzalloc(eint->dev, size, GFP_KERNEL);
+	if (!eint->pins)
+		return -ENOMEM;
+
+	for (i = 0; i < eint->instance_number; i++) {
+		ret = of_property_read_string_index(node, "reg-name", i,
+						    &(eint->instances[i].name));
+		if (ret) {
+			dev_info(eint->dev,
+				 "%s cannot read the name of instance %d.\n",
+				 __func__, i);
+		}
+
+		eint->instances[i].base = of_iomap(node, i);
+		if (!eint->instances[i].base)
+			return -ENOMEM;
 	}
 
+	matrix_number = of_property_count_u32_elems(node, "mediatek,pins") / 4;
+	if (matrix_number < 0) {
+		matrix_number = eint->total_pin_number;
+		dev_info(eint->dev, "%s eint in legacy mode, matrix number is %u.\n",
+			 __func__, matrix_number);
+	} else {
+		dev_info(eint->dev, "%s eint in new mode, matrix number is %u.\n",
+			 __func__, matrix_number);
+	}
+
+	for (i = 0; i < matrix_number ; i++) {
+		offset = i * 4;
+
+		ret = of_property_read_u32_index(node, "mediatek,pins",
+						 offset, &id);
+		ret |= of_property_read_u32_index(node, "mediatek,pins",
+						  offset + 1, &inst);
+		ret |= of_property_read_u32_index(node, "mediatek,pins",
+						  offset + 2, &idx);
+		ret |= of_property_read_u32_index(node, "mediatek,pins",
+						  offset + 3, &support_deb);
+
+		/* Legacy chip which no need to give coordinate list */
+		if (ret) {
+			id = i;
+			inst = 0;
+			idx = i;
+			support_deb = (i < MTK_EINT_DBNC_MAX) ? 1 : 0;
+		}
+
+		eint->pins[id].enabled = true;
+		eint->pins[id].instance = inst;
+		eint->pins[id].index = idx;
+		eint->pins[id].debounce = support_deb;
+
+		eint->instances[inst].pin_list[idx] = id;
+		eint->instances[inst].number++;
+
+#if defined(MTK_EINT_DEBUG)
+		pin = eint->pins[id];
+		dev_info(eint->dev,
+			 "EINT%u in (%u-%u, %u), deb = %u. %u",
+			 id,
+			 pin.instance,
+			 eint->instances[inst].number,
+			 pin.index,
+			 pin.debounce,
+			 eint->instances[pin.instance].pin_list[pin.index]);
+#endif
+		BUG_ON(idx >= MAX_PIN);
+	}
+
+	for (i = 0; i < eint->instance_number; i++) {
+		size = (eint->instances[i].number / 32 + 1) * sizeof(unsigned int);
+		eint->instances[i].wake_mask =
+			devm_kzalloc(eint->dev, size, GFP_KERNEL);
+		eint->instances[i].cur_mask =
+			devm_kzalloc(eint->dev, size, GFP_KERNEL);
+
+		if (!eint->instances[i].wake_mask ||
+		    !eint->instances[i].cur_mask)
+			return -ENOMEM;
+	}
+
+	eint->comp = &default_compat;
+
+	eint->irq = irq_of_parse_and_map(node, 0);
+	if (!eint->irq) {
+		dev_err(eint->dev,
+			"%s IRQ parse fail.\n", __func__);
+		return -EINVAL;
+	}
+
+	eint->domain = irq_domain_add_linear(eint->dev->of_node,
+					     eint->total_pin_number,
+					     &irq_domain_simple_ops, NULL);
+	if (!eint->domain)
+		return -ENOMEM;
+
 	mtk_eint_hw_init(eint);
-	for (i = 0; i < eint->hw->ap_num; i++) {
+	for (i = 0; i < eint->total_pin_number; i++) {
 		int virq = irq_create_mapping(eint->domain, i);
 
 		irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
@@ -533,9 +1077,20 @@ int mtk_eint_do_init(struct mtk_eint *eint)
 	irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler,
 					 eint);
 
+	ret = driver_create_file(eint->dev->driver,
+				 &driver_attr_eintc_status);
+
+	ret |= driver_create_file(eint->dev->driver,
+				  &driver_attr_eint_pin_status);
+
+	if (ret)
+		dev_err(eint->dev, "%s create sysfs files failed.\n", __func__);
+
+	global_eintc = eint;
+
 	return 0;
 }
-EXPORT_SYMBOL_GPL(mtk_eint_do_init);
+EXPORT_SYMBOL_GPL(mtk_eint_do_init_v2);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("MediaTek EINT Driver");
diff --git a/drivers/pinctrl/mediatek/mtk-eint.h b/drivers/pinctrl/mediatek/mtk-eint.h
index 6139b16cd225..30be50308b44 100644
--- a/drivers/pinctrl/mediatek/mtk-eint.h
+++ b/drivers/pinctrl/mediatek/mtk-eint.h
@@ -1,16 +1,19 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (C) 2014-2018 MediaTek Inc.
+ * Copyright (C) 2014-2024 MediaTek Inc.
  *
  * Author: Maoguang Meng <maoguang.meng at mediatek.com>
- *	   Sean Wang <sean.wang at mediatek.com>
- *
+ * Sean Wang <sean.wang at mediatek.com>
+ * Chhao Chang <ot_chhao.chang at mediatek.com>
  */
 #ifndef __MTK_EINT_H
 #define __MTK_EINT_H
 
 #include <linux/irqdomain.h>
 
+#define MAX_PIN 256
+//#define MTK_EINT_DEBUG
+
 struct mtk_eint_regs {
 	unsigned int	stat;
 	unsigned int	ack;
@@ -30,19 +33,37 @@ struct mtk_eint_regs {
 	unsigned int	dbnc_ctrl;
 	unsigned int	dbnc_set;
 	unsigned int	dbnc_clr;
+	unsigned int	event;
+	unsigned int	event_set;
+	unsigned int	event_clr;
+	unsigned int	raw_stat;
 };
 
-struct mtk_eint_hw {
-	u8		port_mask;
-	u8		ports;
-	unsigned int	ap_num;
-	unsigned int	db_cnt;
-	const unsigned int *db_time;
+struct mtk_eint_ops {
+	void (*ack)(struct irq_data *d);
 };
 
-extern const unsigned int debounce_time_mt2701[];
-extern const unsigned int debounce_time_mt6765[];
-extern const unsigned int debounce_time_mt6795[];
+struct mtk_eint_compatible {
+	struct mtk_eint_ops ops;
+	const struct mtk_eint_regs *regs;
+};
+
+struct mtk_eint_pin {
+	bool enabled;
+	u8 instance;
+	u8 index;
+	bool debounce;
+	bool dual_edge;
+};
+
+struct mtk_eint_instance {
+	const char *name;
+	void __iomem *base;
+	unsigned int number;
+	u16 pin_list[MAX_PIN];
+	unsigned int *wake_mask;
+	unsigned int *cur_mask;
+};
 
 struct mtk_eint;
 
@@ -54,33 +75,49 @@ struct mtk_eint_xt {
 	int (*set_gpio_as_eint)(void *data, unsigned long eint_n);
 };
 
+struct mtk_eint_hw {
+	u8              port_mask;
+	u8              ports;
+	unsigned int    ap_num;
+	unsigned int    db_cnt;
+	const unsigned int *db_time;
+};
+
+extern const unsigned int debounce_time_mt2701[];
+extern const unsigned int debounce_time_mt6765[];
+extern const unsigned int debounce_time_mt6795[];
+
 struct mtk_eint {
 	struct device *dev;
 	void __iomem *base;
 	struct irq_domain *domain;
 	int irq;
 
-	int *dual_edge;
-	u32 *wake_mask;
-	u32 *cur_mask;
-
-	/* Used to fit into various EINT device */
+	/* An array to record the coordinate, index by global EINT ID */
+	struct mtk_eint_pin *pins;
+	/* An array to record the global EINT ID, index by coordinate */
+	struct mtk_eint_instance *instances;
+	unsigned int total_pin_number;
+	unsigned int instance_number;
+	unsigned int dump_target_eint;
+	const struct mtk_eint_compatible *comp;
 	const struct mtk_eint_hw *hw;
 	const struct mtk_eint_regs *regs;
-	u16 num_db_time;
 
 	/* Used to fit into various pinctrl device */
 	void *pctl;
 	const struct mtk_eint_xt *gpio_xlate;
 };
 
-#if IS_ENABLED(CONFIG_EINT_MTK)
+#if (IS_ENABLED(CONFIG_EINT_MTK) || IS_ENABLED(CONFIG_DEVICE_MODULES_EINT_MTK))
 int mtk_eint_do_init(struct mtk_eint *eint);
+int mtk_eint_do_init_v2(struct mtk_eint *eint);
 int mtk_eint_do_suspend(struct mtk_eint *eint);
 int mtk_eint_do_resume(struct mtk_eint *eint);
 int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n,
 			  unsigned int debounce);
 int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n);
+int dump_eint_pin_status(unsigned int eint_num, char *buf, unsigned int buf_size);
 
 #else
 static inline int mtk_eint_do_init(struct mtk_eint *eint)
@@ -88,6 +125,11 @@ static inline int mtk_eint_do_init(struct mtk_eint *eint)
 	return -EOPNOTSUPP;
 }
 
+static inline int mtk_eint_do_init_v2(struct mtk_eint *eint)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int mtk_eint_do_suspend(struct mtk_eint *eint)
 {
 	return -EOPNOTSUPP;
@@ -108,5 +150,10 @@ static inline int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
 {
 	return -EOPNOTSUPP;
 }
+
+static inline int dump_eint_pin_status(unsigned int eint_num)
+{
+	return -EOPNOTSUPP;
+}
 #endif
 #endif /* __MTK_EINT_H */
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 54301fbba524..59d5ca2405f3 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -375,33 +375,37 @@ int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
 	if (!of_property_read_bool(np, "interrupt-controller"))
 		return -ENODEV;
 
-	hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
-	if (!hw->eint)
-		return -ENOMEM;
-
-	hw->eint->base = devm_platform_ioremap_resource_byname(pdev, "eint");
-	if (IS_ERR(hw->eint->base)) {
-		ret = PTR_ERR(hw->eint->base);
-		goto err_free_eint;
-	}
+	if (hw->soc->eint_hw) {
+		hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
+		if (!hw->eint)
+			return -ENOMEM;
+
+		hw->eint->base = devm_platform_ioremap_resource_byname(pdev, "eint");
+		if (IS_ERR(hw->eint->base)) {
+			ret = PTR_ERR(hw->eint->base);
+			goto err_free_eint;
+		}
 
-	hw->eint->irq = irq_of_parse_and_map(np, 0);
-	if (!hw->eint->irq) {
-		ret = -EINVAL;
-		goto err_free_eint;
-	}
+		hw->eint->irq = irq_of_parse_and_map(np, 0);
+		if (!hw->eint->irq) {
+			ret = -EINVAL;
+			goto err_free_eint;
+		}
 
-	if (!hw->soc->eint_hw) {
-		ret = -ENODEV;
-		goto err_free_eint;
-	}
+		hw->eint->dev = &pdev->dev;
+		hw->eint->hw = hw->soc->eint_hw;
+		hw->eint->pctl = hw;
+		hw->eint->gpio_xlate = &mtk_eint_xt;
+
+		return mtk_eint_do_init(hw->eint);
 
-	hw->eint->dev = &pdev->dev;
-	hw->eint->hw = hw->soc->eint_hw;
-	hw->eint->pctl = hw;
-	hw->eint->gpio_xlate = &mtk_eint_xt;
+	} else {
+		hw->eint->dev = &pdev->dev;
+		hw->eint->pctl = hw;
+		hw->eint->gpio_xlate = &mtk_eint_xt;
 
-	return mtk_eint_do_init(hw->eint);
+		return mtk_eint_do_init_v2(hw->eint);
+	}
 
 err_free_eint:
 	devm_kfree(hw->dev, hw->eint);
-- 
2.34.1



From krishna.kurapati at oss.qualcomm.com  Tue Dec  3 05:15:25 2024
From: krishna.kurapati at oss.qualcomm.com (Krishna Kurapati)
Date: Tue, 3 Dec 2024 18:45:25 +0530
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint reader
In-Reply-To: <Z07bgH5vVk44zuEH@hovoldconsulting.com>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com>
Message-ID: <d095ae2a-3f9d-464c-9dc8-a3e73eac6598@oss.qualcomm.com>



On 12/3/2024 3:50 PM, Johan Hovold wrote:
> [ +CC: Krishna, Thinh and the USB list ]
> 
> On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
>> The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
>> multiport controller on eUSB6. All other ports (including USB super-speed
>> pins) are unused.
>>
>> Set it up in the device tree together with the NXP PTN3222 repeater.
>>
>> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
>> ---
>>   arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 48 +++++++++++++++++++++++++++++++
>>   1 file changed, 48 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>> index 39f9d9cdc10d..44942931c18f 100644
>> --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>> +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>> @@ -735,6 +735,26 @@ keyboard at 3a {
>>   	};
>>   };
>>   
>> +&i2c5 {
>> +	clock-frequency = <400000>;
>> +
>> +	status = "okay";
>> +
>> +	eusb6_repeater: redriver at 4f {
>> +		compatible = "nxp,ptn3222";
>> +		reg = <0x4f>;
> 
> The driver does not currently check that there's actually anything at
> this address. Did you verify that this is the correct address?
> 
> (Abel is adding a check to the driver as we speak to catch any such
> mistakes going forward).
> 
>> +		#phy-cells = <0>;
> 
> nit: I'd put provider properties like this one last.
> 
>> +		vdd3v3-supply = <&vreg_l13b_3p0>;
>> +		vdd1v8-supply = <&vreg_l4b_1p8>;
> 
> Sort by supply name?
> 
>> +		reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>;
>> +
>> +		pinctrl-0 = <&eusb6_reset_n>;
>> +		pinctrl-names = "default";
>> +	};
>> +};
>> +
>>   &i2c8 {
>>   	clock-frequency = <400000>;
>>   
>> @@ -1047,6 +1067,14 @@ edp_reg_en: edp-reg-en-state {
>>   		bias-disable;
>>   	};
>>   
>> +	eusb6_reset_n: eusb6-reset-n-state {
>> +		pins = "gpio184";
>> +		function = "gpio";
>> +		drive-strength = <2>;
>> +		bias-disable;
>> +		output-low;
> 
> I don't think the pin config should assert reset, that should be up to
> the driver to control.
> 
>> +	};
>> +
>>   	hall_int_n_default: hall-int-n-state {
>>   		pins = "gpio92";
>>   		function = "gpio";
>> @@ -1260,3 +1288,23 @@ &usb_1_ss2_dwc3_hs {
>>   &usb_1_ss2_qmpphy_out {
>>   	remote-endpoint = <&pmic_glink_ss2_ss_in>;
>>   };
>> +
>> +&usb_mp {
>> +	status = "okay";
>> +};
>> +
>> +&usb_mp_dwc3 {
>> +	/* Limit to USB 2.0 and single port */
>> +	maximum-speed = "high-speed";
>> +	phys = <&usb_mp_hsphy1>;
>> +	phy-names = "usb2-1";
>> +};
> 
> The dwc3 driver determines (and acts on) the number of ports based on
> the port interrupts in DT and controller capabilities.
> 
> I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
> that would still be there in the SoC (possibly initialised by the boot
> firmware).
>

The DWC3 core driver identifies number of ports based on xHCI registers. 
The QC Wrapper reads this number via interrupts. But these two values 
are independent of each other. The core driver uses these values to 
identify and manipulate phys. Even if only one HS is given in multiport 
it would be sufficient if the name is "usb2-1". If the others are 
missing, those phys would be read by driver as NULL and any ops to phys 
would be NOP.

Regards,
Krishna,

> I had a local patch to enable the multiport controller (for the suspend
> work) and I realise that you'd currently need to specify a repeater also
> for the HS PHY which does not have one, but that should be possible to
> fix somehow.
>  >> +
>> +&usb_mp_hsphy1 {
>> +	vdd-supply = <&vreg_l2e_0p8>;
>> +	vdda12-supply = <&vreg_l3e_1p2>;
>> +
>> +	phys = <&eusb6_repeater>;
>> +
>> +	status = "okay";
>> +};
> 
> Johan
> 


From andre.draszik at linaro.org  Tue Dec  3 05:03:52 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Tue, 03 Dec 2024 13:03:52 +0000
Subject: [PATCH] MAINTAINERS: add myself and Tudor as reviewers for Google
 Tensor SoC
Message-ID: <20241203-gs101-maintainers-v1-1-f287036dbde5@linaro.org>

Add myself and Tudor as reviewers for the Google Tensor SoC alongside
Peter.

While at it, also add our IRC channel.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index cf1d81bd04a7..2039cc57d8a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9754,9 +9754,12 @@ F:	drivers/firmware/google/
 
 GOOGLE TENSOR SoC SUPPORT
 M:	Peter Griffin <peter.griffin at linaro.org>
+R:	Andr? Draszik <andre.draszik at linaro.org>
+R:	Tudor Ambarus <tudor.ambarus at linaro.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
+C:	irc://irc.oftc.net/pixel6-kernel-dev
 F:	Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
 F:	arch/arm64/boot/dts/exynos/google/
 F:	drivers/clk/samsung/clk-gs101.c

---
base-commit: ed9a4ad6e5bd3a443e81446476718abebee47e82
change-id: 20241203-gs101-maintainers-9a24c8b220e3

Best regards,
-- 
Andr? Draszik <andre.draszik at linaro.org>



From devnull+manojkiran.eda.gmail.com at kernel.org  Tue Dec  3 05:22:45 2024
From: devnull+manojkiran.eda.gmail.com at kernel.org (Manojkiran Eda via B4 Relay)
Date: Tue, 03 Dec 2024 18:52:45 +0530
Subject: [PATCH] ARM: dts: aspeed: Enable video engine for IBM System1
Message-ID: <20241203-dts-system1-video-v1-1-008e5e660106@gmail.com>

From: Manojkiran Eda <manojkiran.eda at gmail.com>

Signed-off-by: Manojkiran Eda <manojkiran.eda at gmail.com>
---
This patch enables the aspeed video engine support in ASPEED BMC for
IBM System1. It is crucial for facilitating the BMC's video capture
and redirection capabilities, which are integral to remote management
and KVM (Keyboard-Video-Mouse) over IP functionality.
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index c8597dcded31..bea858b2eee6 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -479,6 +479,10 @@ &lpc_snoop {
 	snoop-ports = <0x80>, <0x81>;
 };
 
+&video {
+	status = "okay";
+};
+
 &i2c0 {
 	status = "okay";
 

---
base-commit: f6d73b12ca9fd3b1c29a6a725cd751b972c740cf
change-id: 20241203-dts-system1-video-0081d55a156e

Best regards,
-- 
Manojkiran Eda <manojkiran.eda at gmail.com>




From alexandre.belloni at bootlin.com  Tue Dec  3 05:25:40 2024
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Tue, 3 Dec 2024 14:25:40 +0100
Subject: [PATCH 4/6] rtc: st-lpc: Fix initial enable_irq/disable_irq
 balance
In-Reply-To: <20241203-rtc-uie-irq-fixes-v1-4-01286ecd9f3f@geanix.com>
References: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
 <20241203-rtc-uie-irq-fixes-v1-4-01286ecd9f3f@geanix.com>
Message-ID: <202412031325408acbe302@mail.local>

On 03/12/2024 11:45:34+0100, Esben Haabendal wrote:
> Interrupts are automatically enabled when requested, so we need to
> initialize irq_enabled accordingly to avoid causing an unbalanced enable
> warning.
> 
> To: Patrice Chotard <patrice.chotard at foss.st.com>
> Signed-off-by: Esben Haabendal <esben at geanix.com>
> ---
>  drivers/rtc/rtc-st-lpc.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
> index c6d4522411b312f94de2701ff4ff491e5323aa96..dbc2c23bca23f5de6de3fd4b39c9c67290bfd78d 100644
> --- a/drivers/rtc/rtc-st-lpc.c
> +++ b/drivers/rtc/rtc-st-lpc.c
> @@ -218,6 +218,7 @@ static int st_rtc_probe(struct platform_device *pdev)
>  		return -EINVAL;
>  	}
>  
> +	rtc->irq_enabled = true;
>  	ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler,
>  			       IRQF_NO_AUTOEN, pdev->name, rtc);

Seeing the IRQF_NO_AUTOEN here, I guess the patch is not correct.

>  	if (ret) {
> 
> -- 
> 2.47.1
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From yeoreum.yun at arm.com  Tue Dec  3 05:33:05 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue, 3 Dec 2024 13:33:05 +0000
Subject: [PATCH 3/3] firmware/arm_ffa: remove __le64_to_cpu() when set
 uuid for direct msg v2
In-Reply-To: <Z072Mm61eE_Twx1B@bogus>
References: <20241125095251.366866-1-yeoreum.yun@arm.com>
 <20241125095251.366866-4-yeoreum.yun@arm.com>
 <Z072Mm61eE_Twx1B@bogus>
Message-ID: <Z08IkRcxpBGUDozj@e129823.arm.com>

Hi, Sudeep.
>
>   |   warning: incorrect type in initializer (different base types)
>   |      expected unsigned long a2
>   |      got restricted __be64
>   |   warning: incorrect type in initializer (different base types)
>   |      expected unsigned long a3
>   |      got restricted __be64
>
> We will get this warning back with this change, wondering if we can take
> up BE support separately.

Sorry. I'll change the type :\ Thanks to let me know!


From manivannan.sadhasivam at linaro.org  Tue Dec  3 05:34:34 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Tue, 3 Dec 2024 19:04:34 +0530
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <20241126155119.1574564-2-christian.bruel@foss.st.com>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-2-christian.bruel@foss.st.com>
Message-ID: <20241203133434.2qbohwi3wrjjja5a@thinkpad>

On Tue, Nov 26, 2024 at 04:51:15PM +0100, Christian Bruel wrote:
> Document the bindings for STM32MP25 PCIe Controller configured in
> root complex mode.
> 
> Supports 4 legacy interrupts and MSI interrupts from the ARM
> GICv2m controller.
> 
> STM32 PCIe may be in a power domain which is the case for the STM32MP25
> based boards.
> 
> Supports wake# from wake-gpios
> 
> Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
> ---
>  .../bindings/pci/st,stm32-pcie-common.yaml    | 45 +++++++++
>  .../bindings/pci/st,stm32-pcie-host.yaml      | 99 +++++++++++++++++++
>  2 files changed, 144 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/st,stm32-pcie-common.yaml
>  create mode 100644 Documentation/devicetree/bindings/pci/st,stm32-pcie-host.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pci/st,stm32-pcie-common.yaml b/Documentation/devicetree/bindings/pci/st,stm32-pcie-common.yaml
> new file mode 100644
> index 000000000000..479c03134da3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/st,stm32-pcie-common.yaml
> @@ -0,0 +1,45 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/st,stm32-pcie-common.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: STM32MP25 PCIe RC/EP controller
> +
> +maintainers:
> +  - Christian Bruel <christian.bruel at foss.st.com>
> +
> +description:
> +  STM32MP25 PCIe RC/EP common properties
> +
> +properties:
> +  clocks:
> +    maxItems: 1
> +    description: PCIe system clock
> +
> +  resets:
> +    maxItems: 1
> +
> +  phys:
> +    maxItems: 1
> +
> +  phy-names:
> +    const: pcie-phy
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  access-controllers:
> +    maxItems: 1
> +
> +  reset-gpios:
> +    description: GPIO controlled connection to PERST# signal
> +    maxItems: 1
> +
> +required:
> +  - clocks
> +  - resets
> +  - phys
> +  - phy-names
> +
> +additionalProperties: true
> diff --git a/Documentation/devicetree/bindings/pci/st,stm32-pcie-host.yaml b/Documentation/devicetree/bindings/pci/st,stm32-pcie-host.yaml
> new file mode 100644
> index 000000000000..18083cc69024
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/st,stm32-pcie-host.yaml
> @@ -0,0 +1,99 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/st,stm32-pcie-host.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: STM32MP25 PCIe root complex driver
> +
> +maintainers:
> +  - Christian Bruel <christian.bruel at foss.st.com>
> +
> +description:
> +  PCIe root complex controller based on the Synopsys DesignWare PCIe core.
> +
> +allOf:
> +  - $ref: /schemas/pci/snps,dw-pcie.yaml#
> +  - $ref: /schemas/pci/st,stm32-pcie-common.yaml#
> +
> +select:
> +  properties:
> +    compatible:
> +      const: st,stm32mp25-pcie-rc
> +  required:
> +    - compatible
> +
> +properties:
> +  compatible:
> +    const: st,stm32mp25-pcie-rc
> +
> +  reg:
> +    items:
> +      - description: Data Bus Interface (DBI) registers.
> +      - description: PCIe configuration registers.
> +
> +  reg-names:
> +    items:
> +      - const: dbi
> +      - const: config
> +
> +  num-lanes:
> +    const: 1
> +
> +  msi-parent:
> +    maxItems: 1
> +
> +  wake-gpios:
> +    description: GPIO controlled connection to WAKE# input signal
> +    maxItems: 1
> +
> +  wakeup-source: true
> +
> +dependentRequired:
> +  wakeup-source: [ wake-gpios ]
> +
> +required:
> +  - interrupt-map
> +  - interrupt-map-mask
> +  - ranges
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/phy/phy.h>
> +    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
> +
> +    pcie at 48400000 {
> +        compatible = "st,stm32mp25-pcie-rc";
> +        device_type = "pci";
> +        num-lanes = <1>;
> +        reg = <0x48400000 0x400000>,
> +              <0x10000000 0x10000>;
> +        reg-names = "dbi", "config";
> +        #interrupt-cells = <1>;
> +        interrupt-map-mask = <0 0 0 7>;
> +        interrupt-map = <0 0 0 1 &intc 0 0 GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
> +                        <0 0 0 2 &intc 0 0 GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
> +                        <0 0 0 3 &intc 0 0 GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
> +                        <0 0 0 4 &intc 0 0 GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
> +        #address-cells = <3>;
> +        #size-cells = <2>;
> +        ranges = <0x01000000 0 0x10010000 0x10010000 0 0x10000>,

PCI address of I/O region should start from address 0x00000000.

Also use hex notation for all values.

- Mani

-- 
????????? ????????


From esben at geanix.com  Tue Dec  3 05:37:32 2024
From: esben at geanix.com (Esben Haabendal)
Date: Tue, 03 Dec 2024 14:37:32 +0100
Subject: [PATCH 4/6] rtc: st-lpc: Fix initial enable_irq/disable_irq
 balance
In-Reply-To: <202412031325408acbe302@mail.local> (Alexandre Belloni's message
	of "Tue, 3 Dec 2024 14:25:40 +0100")
References: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
	<20241203-rtc-uie-irq-fixes-v1-4-01286ecd9f3f@geanix.com>
	<202412031325408acbe302@mail.local>
Message-ID: <87h67klwf7.fsf@geanix.com>

Alexandre Belloni <alexandre.belloni at bootlin.com> writes:

> On 03/12/2024 11:45:34+0100, Esben Haabendal wrote:
>> Interrupts are automatically enabled when requested, so we need to
>> initialize irq_enabled accordingly to avoid causing an unbalanced enable
>> warning.
>> 
>> To: Patrice Chotard <patrice.chotard at foss.st.com>
>> Signed-off-by: Esben Haabendal <esben at geanix.com>
>> ---
>>  drivers/rtc/rtc-st-lpc.c | 1 +
>>  1 file changed, 1 insertion(+)
>> 
>> diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
>> index c6d4522411b312f94de2701ff4ff491e5323aa96..dbc2c23bca23f5de6de3fd4b39c9c67290bfd78d 100644
>> --- a/drivers/rtc/rtc-st-lpc.c
>> +++ b/drivers/rtc/rtc-st-lpc.c
>> @@ -218,6 +218,7 @@ static int st_rtc_probe(struct platform_device *pdev)
>>  		return -EINVAL;
>>  	}
>>  
>> +	rtc->irq_enabled = true;
>>  	ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler,
>>  			       IRQF_NO_AUTOEN, pdev->name, rtc);
>
> Seeing the IRQF_NO_AUTOEN here, I guess the patch is not correct.

I guess you are right :)
Sorry about that. I only have HW available for testing the rtc-isl12022
driver here.

This patch should be dropped.

>
>>  	if (ret) {
>> 
>> -- 
>> 2.47.1
>> 


From dmitry.baryshkov at linaro.org  Tue Dec  3 05:58:07 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 3 Dec 2024 15:58:07 +0200
Subject: [PATCH 07/10] drm/msm/dp: use eld_mutex to protect access to
 connector->eld
In-Reply-To: <ca906dc4-ac72-4a76-a670-36c011c853c9@quicinc.com>
References: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
 <20241201-drm-connector-eld-mutex-v1-7-ba56a6545c03@linaro.org>
 <ca906dc4-ac72-4a76-a670-36c011c853c9@quicinc.com>
Message-ID: <n2zmw4wquxzht6gvlx6yjurpobgwlsryh75n5gw65j5vjclhgr@jqubqjispqsr>

On Mon, Dec 02, 2024 at 07:27:45PM -0800, Abhinav Kumar wrote:
> 
> 
> On 11/30/2024 3:55 PM, Dmitry Baryshkov wrote:
> > Reading access to connector->eld can happen at the same time the
> > drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
> > order to protect connector->eld from concurrent access.
> > 
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >   drivers/gpu/drm/msm/dp/dp_audio.c | 2 ++
> >   1 file changed, 2 insertions(+)
> > 
> 
> Reviewed-by: Abhinav Kumar <quic_abhinavk at quicinc.com>

Ack to merge through drm-misc?

-- 
With best wishes
Dmitry


From linux at fw-web.de  Tue Dec  3 06:04:07 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 03 Dec 2024 15:04:07 +0100
Subject: [PATCH v2 14/18] arm64: dts: mediatek: mt7988: add pmic on bpi-r4
In-Reply-To: <a0137698-43d7-4cb6-a69c-98a5e90b13f8@collabora.com>
References: <20241202122602.30734-1-linux@fw-web.de> <20241202122602.30734-15-linux@fw-web.de> <a0137698-43d7-4cb6-a69c-98a5e90b13f8@collabora.com>
Message-ID: <9CCD2C57-7632-482F-80A1-8786403243B7@fw-web.de>

Am 3. Dezember 2024 10:40:35 MEZ schrieb AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>:
>Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>> From: Frank Wunderlich <frank-w at public-files.de>
>> 
>
>arm64: dts: mediatek: mt7988a-bpi-r4: Add MediaTek MT6682A/RT5190A PMIC
>
>The BananaPi R4 board has a MediaTek MT8862A PMIC, a rebrand of the
>Richtek RT5190A chip, connected to the I2C0 bus.
>
>Add the relevant node and, while at it, also configure the regulators
>from this PMIC that are used on this board.
>
>> Bananapi R4 Board contains a MT6682A pmic which is compatible to rt5190a.
>> Add its node to the i2 controller.
>> 
>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>> ---
>>   .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 51 +++++++++++++++++++
>>   1 file changed, 51 insertions(+)
>> 
>> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>> index 13ca016d6a67..bc1ec73b8ddd 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>> @@ -2,6 +2,8 @@
>>     /dts-v1/;
>>   +#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
>> +
>>   #include "mt7988a.dtsi"
>>     / {
>> @@ -65,6 +67,55 @@ &i2c0 {
>>   	pinctrl-names = "default";
>>   	pinctrl-0 = <&i2c0_pins>;
>>   	status = "okay";
>> +
>> +	rt5190a_64: rt5190a at 64 {
>> +		compatible = "richtek,rt5190a";
>> +		reg = <0x64>;
>> +		vin2-supply = <&rt5190_buck1>;
>> +		vin3-supply = <&rt5190_buck1>;
>> +		vin4-supply = <&rt5190_buck1>;
>> +
>> +		regulators {
>> +			rt5190_buck1: buck1 {
>> +				regulator-name = "rt5190a-buck1";
>> +				regulator-min-microvolt = <5090000>;
>> +				regulator-max-microvolt = <5090000>;
>> +				regulator-allowed-modes =
>> +				<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
>
>Does it work like that?
>
>regulator-allowed-modes = <RT5190A_OPMODE_AUTO>,
>			  <RT5190A_OPMODE_FPWM>;

It seems working, dtbs_check accepts it and i can boot up with this change and see no errors caused by it.

>If yes, please write it like that - if not, I'm sad - but regardless
>
>Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>


regards Frank


From yeoreum.yun at arm.com  Tue Dec  3 06:09:47 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue, 3 Dec 2024 14:09:47 +0000
Subject: [PATCH 1/3] firmware/arm_ffa: change ffa_device_register()'s
 parameters and return
In-Reply-To: <Z072CGn6fhnT0hED@bogus>
References: <20241125095251.366866-1-yeoreum.yun@arm.com>
 <20241125095251.366866-2-yeoreum.yun@arm.com>
 <Z072CGn6fhnT0hED@bogus>
Message-ID: <Z08RK7JWG6ko1yvt@e129823.arm.com>

Hi Sudeep.

> >  	ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL);
> >  	if (!ffa_dev) {
> >  		ida_free(&ffa_bus_id, id);
> > -		return NULL;
> > +		return ERR_PTR(-ENOMEM);
>
> I am not keen on changing the error from NULL here. -ENOMEM has its own
> logging. ida_alloc failing is very unlikely unless you have so many
> partitions in the system.
>

Okay I'll restore.

> >  	}
> >
> >  	dev = &ffa_dev->dev;
> > @@ -210,16 +216,18 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
> >  	dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id);
> >
> >  	ffa_dev->id = id;
> > -	ffa_dev->vm_id = vm_id;
> > +	ffa_dev->vm_id = part_info->id;
> > +	ffa_dev->properties = part_info->properties;
> >  	ffa_dev->ops = ops;
> > -	uuid_copy(&ffa_dev->uuid, uuid);
> > +	import_uuid(&uuid, (u8 *)part_info->uuid);
> > +	uuid_copy(&ffa_dev->uuid, &uuid);
> >
> >  	ret = device_register(&ffa_dev->dev);
> >  	if (ret) {
> >  		dev_err(dev, "unable to register device %s err=%d\n",
> >  			dev_name(dev), ret);
>
> This error log will give the information you are adding in driver.c, so
> it is again not needed to change that.
>
> >  		put_device(dev);
> > -		return NULL;
> > +		return ERR_PTR(ret);
> >  	}
> >
> >  	return ffa_dev;
> > diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> > index b14cbdae94e8..a3a9cdec7389 100644
> > --- a/drivers/firmware/arm_ffa/driver.c
> > +++ b/drivers/firmware/arm_ffa/driver.c
> > @@ -1406,23 +1406,19 @@ static int ffa_setup_partitions(void)
> >
> >  	xa_init(&drv_info->partition_info);
> >  	for (idx = 0, tpbuf = pbuf; idx < count; idx++, tpbuf++) {
> > -		import_uuid(&uuid, (u8 *)tpbuf->uuid);
> > -
> >  		/* Note that if the UUID will be uuid_null, that will require
> >  		 * ffa_bus_notifier() to find the UUID of this partition id
> >  		 * with help of ffa_device_match_uuid(). FF-A v1.1 and above
> >  		 * provides UUID here for each partition as part of the
> >  		 * discovery API and the same is passed.
> >  		 */
> > -		ffa_dev = ffa_device_register(&uuid, tpbuf->id, &ffa_drv_ops);
> > -		if (!ffa_dev) {
> > -			pr_err("%s: failed to register partition ID 0x%x\n",
> > -			       __func__, tpbuf->id);
> > +		ffa_dev = ffa_device_register(tpbuf, &ffa_drv_ops);
> > +		if (IS_ERR_OR_NULL(ffa_dev)) {
> > +			pr_err("%s: failed to register partition ID 0x%x, error %ld\n",
> > +			       __func__, tpbuf->id, PTR_ERR(ffa_dev));
>
> Drop this additional error info you are adding as bus.c will provide it.

Okay. Thanks!


From angelogioacchino.delregno at collabora.com  Tue Dec  3 06:20:15 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 15:20:15 +0100
Subject: [PATCH v2 03/18] arm64: dts: mediatek: mt7988: add fixed
 regulators for 1v8 and 3v3
In-Reply-To: <371B3F0C-D468-45C8-B1F6-F4619B7C72DD@public-files.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-4-linux@fw-web.de>
 <016b77dc-2d33-4639-b241-2574ad877971@collabora.com>
 <371B3F0C-D468-45C8-B1F6-F4619B7C72DD@public-files.de>
Message-ID: <4da0ab36-34c2-413a-90b3-bcdbdd4a6ac0@collabora.com>

Il 03/12/24 11:51, Frank Wunderlich ha scritto:
> Am 3. Dezember 2024 10:40:54 MEZ schrieb AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>:
>> Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>>> From: Frank Wunderlich <frank-w at public-files.de>
>>>
>>> Add regulator nodes used for mmc to Bananapi R4 board.
>>>
>>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>>
>> If you're adding the eMMC regulators, I assume that there's an eMMC, or that even
>> if there's no device in some version of the board, these two regulators are always
>> assigned to the eMMC device - right?
> 
> Like BPi-R3 there is one mmc controller mapped to either sd or emmc. I can move the regulators to the dtbo,but then they are defined twice (at least 3v3).
> 
>> You should, at this point, do exactly that: you can leave the mmc0 disabled and
>> only enable it in a DTBO.
> 
> I enable it only in dtbo...
> 
>> &mmc0 {
>> 	/* eMMC gets enabled by DTBO if present */
>> 	vmmc-supply = <&reg_3p3v>;
>> 	vqmmc-supply = <&reg_1p8v>;
>> };
> 
> Problem is here that sdcard uses only the 3v3 twice
> 
> https://github.com/frank-w/BPI-Router-Linux/blob/6.12-main/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
> 
> And emmc needs both
> 
> https://github.com/frank-w/BPI-Router-Linux/blob/6.12-main/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
> 
> Only defining the vmmc-supply in dts and set only the other in dtso is possible but but imho not nice.
> 

If you added that in the commit description in the first place, I wouldn't
have sent you that suggestion ;-)

So, please add the reason that you just explained to me in the description
of this commit and just leave the code as-is.

Cheers!

>> Cheers,
>> Angelo
>>
>>> ---
>>> v2:
>>> - move mmc regulators to board dts of bpi-r4
>>> ---
>>>    .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts   | 18 ++++++++++++++++++
>>>    1 file changed, 18 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>>> index d914eae2b524..df53512c6890 100644
>>> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>>> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>>> @@ -8,6 +8,24 @@ / {
>>>    	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
>>>    	model = "Banana Pi BPI-R4";
>>>    	chassis-type = "embedded";
>>> +
>>> +	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;
>>> +	};
>>>    };
>>>      &pio {
>>
>>
> 
> 
> regards Frank




From angelogioacchino.delregno at collabora.com  Tue Dec  3 06:22:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 15:22:21 +0100
Subject: [PATCH v2 13/18] arm64: dts: mediatek: mt7988: add i2c to bpi-r4
 board
In-Reply-To: <CA7E06EB-D26A-45D0-BF13-9C6B640F27A0@public-files.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-14-linux@fw-web.de>
 <1ad355df-3f2a-4257-9374-1d125e138791@collabora.com>
 <CA7E06EB-D26A-45D0-BF13-9C6B640F27A0@public-files.de>
Message-ID: <f47f08c0-0fb4-4826-9b25-1277cabe4bb6@collabora.com>

Il 03/12/24 11:58, Frank Wunderlich ha scritto:
> Am 3. Dezember 2024 10:40:38 MEZ schrieb AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>:
>> Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>>> From: Frank Wunderlich <frank-w at public-files.de>
>>>
>>> Add basic i2c nodes to bananapi R4 board.
>>>
>>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>>
>> arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C controllers
>>
>> Enable the I2C0, I2C2 controllers found on the BananaPi R4 board; these
>> controllers are accessible at ... I don't know, a header on the board?
> 
> These 2 i2c have directly connected spare devices (pmic on i2c0 and i2c-mux on i2c2 added in later commits to have it a bit cleaner). I2c1 is on gpio header which i have not added to let user choose if he wants i2c option or gpio. I can also add i2c1 to r4 board with the right pinctrl but imho it should be disabled to have gpio function default.

And again, you should really add all that information to the commit description,
as that not only helps me to review your submission, but also helps other people
checking the commit history....!

Cheers

> 
>> After which,
>>
>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>
>>
> 
> 
> regards Frank





From angelogioacchino.delregno at collabora.com  Tue Dec  3 06:23:44 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 3 Dec 2024 15:23:44 +0100
Subject: [PATCH v2 10/18] arm64: dts: mediatek: mt7988: enable serial0 on
 bpi-r4
In-Reply-To: <6964E096-7C19-450C-8434-6A4456AFDD55@public-files.de>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-11-linux@fw-web.de>
 <32ef5ab8-a163-4fdc-8603-f5a6f0e8526b@collabora.com>
 <6964E096-7C19-450C-8434-6A4456AFDD55@public-files.de>
Message-ID: <fea3783a-0ca2-4a46-8b82-ef1156dc8f3c@collabora.com>

Il 03/12/24 12:27, Frank Wunderlich ha scritto:
> Am 3. Dezember 2024 10:40:45 MEZ schrieb AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>:
>> Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>>> From: Frank Wunderlich <frank-w at public-files.de>
>>>
>>
>> arm64: dts: mediatek: mt7988a-bpi-r4: Enable serial0 debug uart
> 
> You want new prefix here? That will change all r4 commits,right?
> 

Yeah - that prefix should be shortening the commit titles but mainly will
make it more straightforward when reading the commit history with --oneline.

Thanks,
Angelo

>>> Enable the debug uart on Bananapi R4 board.
>>>
>>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>>
>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>
> 
> 
> regards Frank





From james.clark at linaro.org  Tue Dec  3 06:25:12 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 3 Dec 2024 14:25:12 +0000
Subject: [PATCH v7 8/9] coresight: tools: Add configuration table test
 tools
In-Reply-To: <20241127134256.2254851-9-mike.leach@linaro.org>
References: <20241127134256.2254851-1-mike.leach@linaro.org>
 <20241127134256.2254851-9-mike.leach@linaro.org>
Message-ID: <9cb1ef5e-eb61-4177-a039-4049850196a5@linaro.org>



On 27/11/2024 1:42 pm, Mike Leach wrote:
> Add an example config table generator to test loading configuration
> tables.
> 
> Provides a table buffer writer function that can be re-used in other
> userspace programs.
> 
> Table write format matches that expected by the corresponding reader
> in the configfs driver code.
> 
> Generates tables and outputs in form of binary files.
> 
> Add a config table file reader and printer. Takes in config table files
> and prints the contents. Uses table reader source from kernel driver.
> 
> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>   MAINTAINERS                                   |   1 +
>   .../coresight/coresight-config-table.h        |   5 +

Hi Mike,

Isn't there some convention about maintaining a copy of kernel headers 
in the tools? Especially as you wouldn't rebuild the tools after 
updating the kernel headers so breakages might go unnoticed.

[...]

> +
> +/*
> + * sets of presets leaves strobing window constant while varying period to allow
> + * experimentation with mark / space ratios for various workloads
> + */
> +static u64 afdo_set_a_presets[AFDO_NR_PRESETS][AFDO_NR_PARAM_SUM] = {
> +	{ 2000, 100 },
> +	{ 2000, 1000 },
> +	{ 2000, 5000 },
> +	{ 2000, 10000 },
> +	{ 4000, 100 },

The comment above here looks like its for example1, this one does vary 
the window size.

Probably only example2 is enough, I assumed they were different but 
example2 is basically the same as example1 with an extra preset list. We 
could comment that the second preset list is optional and delete 
example1. Saves people reading more and wondering what the difference is.

I tried to make an example that doesn't use an existing feature by 
reacreating afdo from scratch which I thought would be a good example. 
It's pasted at the end. I had to copy paste the ETMv4 macros and 
constants though, I couldn't include them in the userspace generator 
because of this error:

   coresight-config.h:10:10: fatal error: linux/coresight.h: No such 
file
   or directory
    10 | #include <linux/coresight.h>

I also got this error when loading it:

Unable to handle kernel NULL pointer dereference at virtual address 
0000000000000008

cscfg_reset_feat (drivers/hwtracing/coresight/coresight-config.c:64 
coresight-config.c:124) coresight
cscfg_load_config_sets 
(drivers/hwtracing/coresight/coresight-syscfg.c:217 
coresight-syscfg.c:262 coresight-syscfg.c:492 coresight-syscfg.c:610) 
coresight
cscfg_dyn_load_cfg_table 
(drivers/hwtracing/coresight/coresight-syscfg-configfs.c:294) coresight
cscfg_cfg_load_table_write 
(drivers/hwtracing/coresight/coresight-syscfg-configfs.c:799) coresight
configfs_release_bin_file (fs/configfs/file.c:415)
__fput (fs/file_table.c:432)
__fput_sync (fs/file_table.c:517)
__arm64_sys_close (fs/open.c:1568 fs/open.c:1550 fs/open.c:1550)
invoke_syscall (arch/arm64/kernel/syscall.c:? 
arch/arm64/kernel/syscall.c:49)
el0_svc_common (include/linux/thread_info.h:127 
arch/arm64/kernel/syscall.c:140)
do_el0_svc (arch/arm64/kernel/syscall.c:152)


So I'm wondering if we can do the same thing by setting values via 
individual files rather than one binary blob which would avoid some of 
these issues. From what I understand the feature params can already be 
set directly this way via 
/sys/kernel/config/cs-syscfg/features/strobing/params/period/value

We'd have to add a way to add new configs with a mkdir, then the same
things can be configured without needing an additional tool. Links 
between features and configs can be done with symlinks which is also 
mentioned in the configfs docs.

Something like this would be a bit like the current version:

  # ls /config/cs-syscfg
  configurations
  features

  # mkdir /config/cs-syscfg/features/my_config
  # ls /config/cs-syscfg/features/my_config
  description
  matches
  regs_desc
  params

  # mkdir /config/cs-syscfg/features/my_config/regs_desc/TRCRSCTLRn0
  # ls /config/cs-syscfg/features/my_config/TRCRSCTLRn0
  type
  offset
  val
  mask

But another way could be to enumerate all possible regs for each device. 
This would remove the need to have all the #defines in whatever tool is
making the config (avoiding the #include issue from above):

  # mkdir /config/cs-syscfg/features/my_config
  # ls /config/cs-syscfg/features/my_config/regs_desc

  regs_desc is initially empty, but specify what device it's for to make
  all the properties appear (or the mkdir could be done in an etmv4
  folder):

  # echo "SRC_ETM4" > matches
  # ls /config/cs-syscfg/features/my_config/regs_desc
  TRCRSCTLRn0
  TRCRSCTLRn1
  TRCRSCTLRn2
  ... etc ...

  Now type and offset don't need to be set:

  # ls /config/cs-syscfg/features/my_config/regs_desc/TRCRSCTLRn0
  val
  mask
  save

Don't we already have the full list of parameters in 
etm4_cfg_map_reg_offset(), so we can expose this to users via configfs 
directly rather than needing any tooling. And doesn't any new device 
that's supported by the config mechanism need to know about all its 
parameters, so it wouldn't remove any flexibility?




From jani.nikula at linux.intel.com  Tue Dec  3 06:25:58 2024
From: jani.nikula at linux.intel.com (Jani Nikula)
Date: Tue, 03 Dec 2024 16:25:58 +0200
Subject: [PATCH v5 7/9] drm/bridge_connector: hook
 drm_atomic_helper_connector_hdmi_update_edid()
In-Reply-To: <20241201-drm-bridge-hdmi-connector-v5-7-b5316e82f61a@linaro.org>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-7-b5316e82f61a@linaro.org>
Message-ID: <87a5dc4zd5.fsf@intel.com>

On Sun, 01 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> Extend drm_bridge_connector code to read the EDID and use it to update
> connector status if the bridge chain implements HDMI bridge. Performing
> it from the generic location minimizes individual bridge's code and
> enforces standard behaviour from all corresponding drivers.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/display/drm_bridge_connector.c | 67 ++++++++++++++++++++------
>  1 file changed, 53 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
> index 12ab9f14cc8a8672478ae2804c9a68d766d88ea5..71ae3b2c9049016d1cc0d39a787f6461633efd53 100644
> --- a/drivers/gpu/drm/display/drm_bridge_connector.c
> +++ b/drivers/gpu/drm/display/drm_bridge_connector.c
> @@ -17,6 +17,7 @@
>  #include <drm/drm_edid.h>
>  #include <drm/drm_managed.h>
>  #include <drm/drm_modeset_helper_vtables.h>
> +#include <drm/drm_print.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/display/drm_hdmi_state_helper.h>
>  
> @@ -175,17 +176,55 @@ static void drm_bridge_connector_disable_hpd(struct drm_connector *connector)
>   * Bridge Connector Functions
>   */
>  
> +static const struct drm_edid *
> +drm_bridge_connector_read_edid(struct drm_connector *connector,
> +			       enum drm_connector_status status)
> +{
> +	struct drm_bridge_connector *bridge_connector =
> +		to_drm_bridge_connector(connector);
> +	const struct drm_edid *drm_edid;
> +	struct drm_bridge *bridge;
> +
> +	bridge = bridge_connector->bridge_edid;
> +	if (!bridge)
> +		return NULL;
> +
> +	if (status != connector_status_connected)
> +		return NULL;
> +
> +	drm_edid = drm_bridge_edid_read(bridge, connector);
> +	if (!drm_edid_valid(drm_edid)) {

What's the case this check is for?

My preference would be that bridge->funcs->edid_read() uses
drm_edid_read*() family of functions that do the checks and return the
EDID.

There are some cases that just allocate a blob and return it. Would be
nice if they could be converted, but in the mean time could use
drm_edid_valid() right there. Additional validity checks are redundant.

BR,
Jani.


> +		drm_edid_free(drm_edid);
> +		return NULL;
> +	}
> +
> +	return drm_edid;
> +}
> +
>  static enum drm_connector_status
>  drm_bridge_connector_detect(struct drm_connector *connector, bool force)
>  {
>  	struct drm_bridge_connector *bridge_connector =
>  		to_drm_bridge_connector(connector);
>  	struct drm_bridge *detect = bridge_connector->bridge_detect;
> +	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
>  	enum drm_connector_status status;
>  
>  	if (detect) {
>  		status = detect->funcs->detect(detect);
>  
> +		if (hdmi) {
> +			const struct drm_edid *drm_edid;
> +			int ret;
> +
> +			drm_edid = drm_bridge_connector_read_edid(connector, status);
> +			ret = drm_atomic_helper_connector_hdmi_update_edid(connector, drm_edid);
> +			if (ret)
> +				drm_warn(connector->dev, "updating EDID failed with %d\n", ret);
> +
> +			drm_edid_free(drm_edid);
> +		}
> +
>  		drm_bridge_connector_hpd_notify(connector, status);
>  	} else {
>  		switch (connector->connector_type) {
> @@ -246,29 +285,29 @@ static const struct drm_connector_funcs drm_bridge_connector_funcs = {
>  static int drm_bridge_connector_get_modes_edid(struct drm_connector *connector,
>  					       struct drm_bridge *bridge)
>  {
> +	struct drm_bridge_connector *bridge_connector =
> +		to_drm_bridge_connector(connector);
> +	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
>  	enum drm_connector_status status;
>  	const struct drm_edid *drm_edid;
> -	int n;
>  
>  	status = drm_bridge_connector_detect(connector, false);
>  	if (status != connector_status_connected)
> -		goto no_edid;
> +		return 0;
>  
> -	drm_edid = drm_bridge_edid_read(bridge, connector);
> -	if (!drm_edid_valid(drm_edid)) {
> +	/* In HDMI setup the EDID has been read and handled as a part of .detect() */
> +	if (!hdmi) {
> +		drm_edid = drm_bridge_connector_read_edid(connector, status);
> +		if (!drm_edid) {
> +			drm_edid_connector_update(connector, NULL);
> +			return 0;
> +		}
> +
> +		drm_edid_connector_update(connector, drm_edid);
>  		drm_edid_free(drm_edid);
> -		goto no_edid;
>  	}
>  
> -	drm_edid_connector_update(connector, drm_edid);
> -	n = drm_edid_connector_add_modes(connector);
> -
> -	drm_edid_free(drm_edid);
> -	return n;
> -
> -no_edid:
> -	drm_edid_connector_update(connector, NULL);
> -	return 0;
> +	return drm_edid_connector_add_modes(connector);
>  }
>  
>  static int drm_bridge_connector_get_modes(struct drm_connector *connector)

-- 
Jani Nikula, Intel


From james.clark at linaro.org  Tue Dec  3 06:29:12 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 3 Dec 2024 14:29:12 +0000
Subject: [PATCH v7 8/9] coresight: tools: Add configuration table test
 tools
In-Reply-To: <9cb1ef5e-eb61-4177-a039-4049850196a5@linaro.org>
References: <20241127134256.2254851-1-mike.leach@linaro.org>
 <20241127134256.2254851-9-mike.leach@linaro.org>
 <9cb1ef5e-eb61-4177-a039-4049850196a5@linaro.org>
Message-ID: <d4a10ba4-e580-4fe6-9706-d3ec6e5856e3@linaro.org>



On 03/12/2024 2:25 pm, James Clark wrote:
> 
> 
> On 27/11/2024 1:42 pm, Mike Leach wrote:
>> Add an example config table generator to test loading configuration
>> tables.
>>
>> Provides a table buffer writer function that can be re-used in other
>> userspace programs.
>>
>> Table write format matches that expected by the corresponding reader
>> in the configfs driver code.
>>
>> Generates tables and outputs in form of binary files.
>>
>> Add a config table file reader and printer. Takes in config table files
>> and prints the contents. Uses table reader source from kernel driver.
>>
>> Signed-off-by: Mike Leach <mike.leach at linaro.org>
>> ---
>> ? MAINTAINERS?????????????????????????????????? |?? 1 +
>> ? .../coresight/coresight-config-table.h??????? |?? 5 +
> 
> Hi Mike,
> 
> Isn't there some convention about maintaining a copy of kernel headers 
> in the tools? Especially as you wouldn't rebuild the tools after 
> updating the kernel headers so breakages might go unnoticed.
> 
> [...]
> 
>> +
>> +/*
>> + * sets of presets leaves strobing window constant while varying 
>> period to allow
>> + * experimentation with mark / space ratios for various workloads
>> + */
>> +static u64 afdo_set_a_presets[AFDO_NR_PRESETS][AFDO_NR_PARAM_SUM] = {
>> +??? { 2000, 100 },
>> +??? { 2000, 1000 },
>> +??? { 2000, 5000 },
>> +??? { 2000, 10000 },
>> +??? { 4000, 100 },
> 
> The comment above here looks like its for example1, this one does vary 
> the window size.
> 
> Probably only example2 is enough, I assumed they were different but 
> example2 is basically the same as example1 with an extra preset list. We 
> could comment that the second preset list is optional and delete 
> example1. Saves people reading more and wondering what the difference is.
> 
> I tried to make an example that doesn't use an existing feature by 
> reacreating afdo from scratch which I thought would be a good example. 
> It's pasted at the end.

I've attached it here instead

-------------- next part --------------
A non-text attachment was scrubbed...
Name: coresight-cfg-afdo.c
Type: text/x-csrc
Size: 6063 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241203/f5a36a50/attachment.bin>

From yeoreum.yun at arm.com  Tue Dec  3 06:31:08 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 14:31:08 +0000
Subject: [PATCH v2 1/2] firmware/arm_ffa: change ffa_device_register()'s parameters and return
In-Reply-To: <20241203143109.1030514-1-yeoreum.yun@arm.com>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
Message-ID: <20241203143109.1030514-2-yeoreum.yun@arm.com>

From: Levi Yun <yeoreum.yun at arm.com>

Currently, ffa_dev->properties is set after ffa_device_register() in
ffa_setup_partitions().
This means it couldn't validate partition's properties
while probing ffa_device.

Change parameter of ffa_device_register() to receive ffa_partition_info
so that before device_register(), ffa_device->properties can be setup
and any other data.

Also, change return value of ffa_device_register() from NULL to ERR_PTR
so that it passes error code.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/firmware/arm_ffa/bus.c    | 15 +++++++++++----
 drivers/firmware/arm_ffa/driver.c |  7 +------
 include/linux/arm_ffa.h           | 12 ++++++++----
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
index eb17d03b66fe..a4ab6d14afef 100644
--- a/drivers/firmware/arm_ffa/bus.c
+++ b/drivers/firmware/arm_ffa/bus.c
@@ -187,13 +187,18 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev)
 	return valid;
 }
 
-struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
-				       const struct ffa_ops *ops)
+struct ffa_device *ffa_device_register(
+		const struct ffa_partition_info *part_info,
+		const struct ffa_ops *ops)
 {
 	int id, ret;
+	uuid_t uuid;
 	struct device *dev;
 	struct ffa_device *ffa_dev;
 
+	if (!part_info)
+		return NULL;
+
 	id = ida_alloc_min(&ffa_bus_id, 1, GFP_KERNEL);
 	if (id < 0)
 		return NULL;
@@ -210,9 +215,11 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
 	dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id);
 
 	ffa_dev->id = id;
-	ffa_dev->vm_id = vm_id;
+	ffa_dev->vm_id = part_info->id;
+	ffa_dev->properties = part_info->properties;
 	ffa_dev->ops = ops;
-	uuid_copy(&ffa_dev->uuid, uuid);
+	import_uuid(&uuid, (u8 *)part_info->uuid);
+	uuid_copy(&ffa_dev->uuid, &uuid);
 
 	ret = device_register(&ffa_dev->dev);
 	if (ret) {
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index b14cbdae94e8..2c2ec3c35f15 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1387,7 +1387,6 @@ static struct notifier_block ffa_bus_nb = {
 static int ffa_setup_partitions(void)
 {
 	int count, idx, ret;
-	uuid_t uuid;
 	struct ffa_device *ffa_dev;
 	struct ffa_dev_part_info *info;
 	struct ffa_partition_info *pbuf, *tpbuf;
@@ -1406,23 +1405,19 @@ static int ffa_setup_partitions(void)
 
 	xa_init(&drv_info->partition_info);
 	for (idx = 0, tpbuf = pbuf; idx < count; idx++, tpbuf++) {
-		import_uuid(&uuid, (u8 *)tpbuf->uuid);
-
 		/* Note that if the UUID will be uuid_null, that will require
 		 * ffa_bus_notifier() to find the UUID of this partition id
 		 * with help of ffa_device_match_uuid(). FF-A v1.1 and above
 		 * provides UUID here for each partition as part of the
 		 * discovery API and the same is passed.
 		 */
-		ffa_dev = ffa_device_register(&uuid, tpbuf->id, &ffa_drv_ops);
+		ffa_dev = ffa_device_register(tpbuf, &ffa_drv_ops);
 		if (!ffa_dev) {
 			pr_err("%s: failed to register partition ID 0x%x\n",
 			       __func__, tpbuf->id);
 			continue;
 		}
 
-		ffa_dev->properties = tpbuf->properties;
-
 		if (drv_info->version > FFA_VERSION_1_0 &&
 		    !(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
 			ffa_mode_32bit_set(ffa_dev);
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index a28e2a6a13d0..3fb9c7a3453b 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -166,9 +166,12 @@ static inline void *ffa_dev_get_drvdata(struct ffa_device *fdev)
 	return dev_get_drvdata(&fdev->dev);
 }
 
+struct ffa_partition_info;
+
 #if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)
-struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
-				       const struct ffa_ops *ops);
+struct ffa_device *ffa_device_register(
+		const struct ffa_partition_info *part_info,
+		const struct ffa_ops *ops);
 void ffa_device_unregister(struct ffa_device *ffa_dev);
 int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
 			const char *mod_name);
@@ -177,8 +180,9 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev);
 
 #else
 static inline
-struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
-				       const struct ffa_ops *ops)
+struct ffa_device *ffa_device_register(
+		const struct ffa_partition_info *part_info,
+		const struct ffa_ops *ops)
 {
 	return NULL;
 }
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 06:31:09 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 14:31:09 +0000
Subject: [PATCH v2 2/2] firmware/arm_ffa: remove __le64_to_cpu() when set uuid for direct msg v2
In-Reply-To: <20241203143109.1030514-1-yeoreum.yun@arm.com>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
Message-ID: <20241203143109.1030514-3-yeoreum.yun@arm.com>

From: Levi Yun <yeoreum.yun at arm.com>

UUID is saved in big endian format.
i.e) For uuid "378daedc-f06b-4446-8314-40ab933c87a3",

It should be saved in memory like:
    37 8d ae dc
    f0 6b 44 46
    83 14 40 ab
    93 3c 87 a3

Accoding to FF-A specification[0] 15.4 FFA_MSG_SEND_DRIECT_REQ2,
then UUID is saved in register:
    UUID Lo  x2  Bytes[0...7] of UUID with byte 0 in the low-order bits.
    UUID Hi  x3  Bytes[8...15] of UUID with byte 8 in the low-order bits.

That means, we don't need to swap the uuid when it send via direct
message request version 2, just send it as saved in memory.

Remove le64_to_cpu() for uuid in direct message request version 2,
and change uuid_regs' type to unsigned long.

Link: https://developer.arm.com/documentation/den0077/latest [0]
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/firmware/arm_ffa/driver.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 2c2ec3c35f15..8bfeca9d0d2a 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -483,13 +483,13 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
 	u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id);
 	union {
 		uuid_t uuid;
-		__le64 regs[2];
+		unsigned long regs[2];
 	} uuid_regs = { .uuid = *uuid };
 	ffa_value_t ret, args = {
 		.a0 = FFA_MSG_SEND_DIRECT_REQ2,
 		.a1 = src_dst_ids,
-		.a2 = le64_to_cpu(uuid_regs.regs[0]),
-		.a3 = le64_to_cpu(uuid_regs.regs[1]),
+		.a2 = uuid_regs.regs[0],
+		.a3 = uuid_regs.regs[1],
 	};
 	memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data));

--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Tue Dec  3 06:31:07 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue,  3 Dec 2024 14:31:07 +0000
Subject: [PATCH v2 0/2] small fixes for arm_ffa driver
Message-ID: <20241203143109.1030514-1-yeoreum.yun@arm.com>

This patchset small fixes for arm_ffa driver:
    - change ffa_device_register()'s declaration and its return value.
    - fix direct message request version 2 uuid setup.


v1 -> v2:
    - Restore error return in ffa_device_register().
    - change type __be64 to unsigned long to suppress warning.

Levi Yun (2):
  firmware/arm_ffa: change ffa_device_register()'s parameters and return
  firmware/arm_ffa: remove __le64_to_cpu() when set uuid for direct msg
    v2

 drivers/firmware/arm_ffa/bus.c    | 15 +++++++++++----
 drivers/firmware/arm_ffa/driver.c | 13 ++++---------
 include/linux/arm_ffa.h           | 12 ++++++++----
 3 files changed, 23 insertions(+), 17 deletions(-)

--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From jani.nikula at linux.intel.com  Tue Dec  3 06:32:44 2024
From: jani.nikula at linux.intel.com (Jani Nikula)
Date: Tue, 03 Dec 2024 16:32:44 +0200
Subject: [PATCH v5 9/9] drm/vc4: hdmi: use
 drm_atomic_helper_connector_hdmi_update_edid()
In-Reply-To: <ae24x2bo736jpzi77l34hybejawwe4rp47v2idedga344ye6zr@bxsxz34dwrd2>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-9-b5316e82f61a@linaro.org>
 <20241202-married-bald-raven-7acd83@houat>
 <ae24x2bo736jpzi77l34hybejawwe4rp47v2idedga344ye6zr@bxsxz34dwrd2>
Message-ID: <877c8g4z1v.fsf@intel.com>

On Tue, 03 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> On Mon, Dec 02, 2024 at 02:27:49PM +0100, Maxime Ripard wrote:
>> Hi,
>> 
>> On Sun, Dec 01, 2024 at 02:44:13AM +0200, Dmitry Baryshkov wrote:
>> > Use the helper function to update the connector's information. This
>> > makes sure that HDMI-related events are handled in a generic way.
>> > Currently it is limited to the HDMI state reporting to the sound system.
>> > 
>> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>> > ---
>> >  drivers/gpu/drm/vc4/vc4_hdmi.c | 9 +++++++--
>> >  1 file changed, 7 insertions(+), 2 deletions(-)
>> > 
>> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
>> > index d0a9aff7ad43016647493263c00d593296a1e3ad..d83f587ab69f4b8f7d5c37a00777f11da8301bc1 100644
>> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
>> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
>> > @@ -401,13 +401,16 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
>> >  	 */
>> >  
>> >  	if (status == connector_status_disconnected) {
>> > +		drm_atomic_helper_connector_hdmi_update_edid(connector, NULL);
>> >  		cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
>> >  		return;
>> >  	}
>> >  
>> >  	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
>> >  
>> > -	drm_edid_connector_update(connector, drm_edid);
>> > +	// TODO: use drm_atomic_helper_connector_hdmi_update() once it gains
>> > +	// CEC support
>> > +	drm_atomic_helper_connector_hdmi_update_edid(connector, drm_edid);
>> 
>> So, it's not just about EDID, and I think we shouldn't really focus on
>> that either.
>> 
>> As that patch points out, even if we only consider EDID's, we have
>> different path depending on the connector status. It shouldn't be up to
>> the drivers to get this right.
>> 
>> What I had in mind was something like a
>> drm_atomic_helper_connector_hdmi_hotplug function that would obviously
>> deal with EDID only here, but would expand to CEC, scrambling, etc.
>> later on.
>
> I thought about it, after our discussion, but in the end I had to
> implement the EDID-specific function, using edid == NULL as
> "disconnected" event. The issue is pretty simple: there is no standard
> way to get EDID from the connector. The devices can call
> drm_edid_read(), drm_edid_read_ddc(connector->ddc) or (especially
> embedded bridges) use drm_edid_read_custom().

Lack of EDID may be a good approximation of disconnected for displays
that should have one, but just a reminder that having an EDID should not
be the only approximation for connected.

This is relevant for the debugfs/firmware EDID case. You'll want to be
able to have that, without it implying connected.

BR,
Jani.


>
> Of course we can go with the functional way and add the
> .read_edid(drm_connector) callback to the HDMI funcs. Then the
> drm_atomic_helper_connector_hdmi_hotplug() function can read EDID on its
> own.
>
> Also the function that you proposed perfectly fits the HPD notification
> callbacks, but which function should be called from the .get_modes()?
> The _hdmi_hotplug() doesn't fit there. Do we still end up with both
> drm_atomic_helper_connector_hdmi_hotplug() and
> drm_atomic_helper_connector_hdmi_update_edid()?
>
>> 
>> And would cover both the connected/disconnected cases.
>> 
>> Maxime

-- 
Jani Nikula, Intel


From peter.griffin at linaro.org  Tue Dec  3 06:47:16 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 3 Dec 2024 14:47:16 +0000
Subject: [PATCH] MAINTAINERS: add myself and Tudor as reviewers for Google
 Tensor SoC
In-Reply-To: <20241203-gs101-maintainers-v1-1-f287036dbde5@linaro.org>
References: <20241203-gs101-maintainers-v1-1-f287036dbde5@linaro.org>
Message-ID: <CADrjBPrYvz6yNdvZUmTGVAvOtP53kHBLVt6A7zCcRwK3rDg2FQ@mail.gmail.com>

Hi Andr? and Krzysztof,

On Tue, 3 Dec 2024 at 13:03, Andr? Draszik <andre.draszik at linaro.org> wrote:
>
> Add myself and Tudor as reviewers for the Google Tensor SoC alongside
> Peter.
>
> While at it, also add our IRC channel.
>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>

@Krzysztof could you take this via the Samsung Exynos tree?

Thanks,

Peter

>  MAINTAINERS | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index cf1d81bd04a7..2039cc57d8a7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -9754,9 +9754,12 @@ F:       drivers/firmware/google/
>
>  GOOGLE TENSOR SoC SUPPORT
>  M:     Peter Griffin <peter.griffin at linaro.org>
> +R:     Andr? Draszik <andre.draszik at linaro.org>
> +R:     Tudor Ambarus <tudor.ambarus at linaro.org>
>  L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>  L:     linux-samsung-soc at vger.kernel.org
>  S:     Maintained
> +C:     irc://irc.oftc.net/pixel6-kernel-dev
>  F:     Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
>  F:     arch/arm64/boot/dts/exynos/google/
>  F:     drivers/clk/samsung/clk-gs101.c
>
> ---
> base-commit: ed9a4ad6e5bd3a443e81446476718abebee47e82
> change-id: 20241203-gs101-maintainers-9a24c8b220e3
>
> Best regards,
> --
> Andr? Draszik <andre.draszik at linaro.org>
>


From manivannan.sadhasivam at linaro.org  Tue Dec  3 06:52:44 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Tue, 3 Dec 2024 20:22:44 +0530
Subject: [PATCH v2 2/5] PCI: stm32: Add PCIe host support for STM32MP25
In-Reply-To: <20241126155119.1574564-3-christian.bruel@foss.st.com>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-3-christian.bruel@foss.st.com>
Message-ID: <20241203145244.trgrobtfmumtiwuc@thinkpad>

On Tue, Nov 26, 2024 at 04:51:16PM +0100, Christian Bruel wrote:
> Add driver for the STM32MP25 SoC PCIe Gen2 controller based on the
> DesignWare PCIe core.
> 
> Supports MSI via GICv2m, Single Virtual Channel, Single Function
> 
> Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
> ---
>  drivers/pci/controller/dwc/Kconfig      |  12 +
>  drivers/pci/controller/dwc/Makefile     |   1 +
>  drivers/pci/controller/dwc/pcie-stm32.c | 402 ++++++++++++++++++++++++
>  drivers/pci/controller/dwc/pcie-stm32.h |  15 +
>  4 files changed, 430 insertions(+)
>  create mode 100644 drivers/pci/controller/dwc/pcie-stm32.c
>  create mode 100644 drivers/pci/controller/dwc/pcie-stm32.h
> 
> diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> index b6d6778b0698..0c18879b604c 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -389,6 +389,18 @@ config PCIE_SPEAR13XX
>  	help
>  	  Say Y here if you want PCIe support on SPEAr13XX SoCs.
>  
> +config PCIE_STM32
> +	tristate "STMicroelectronics STM32MP25 PCIe Controller (host mode)"
> +	depends on ARCH_STM32 || COMPILE_TEST
> +	depends on PCI_MSI
> +	select PCIE_DW_HOST
> +	help
> +	  Enables support for the DesignWare core based PCIe host controller
> +	  found in STM32MP25 SoC.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called pcie-stm32.
> +
>  config PCI_DRA7XX
>  	tristate
>  
> diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> index a8308d9ea986..576d99cb3bc5 100644
> --- a/drivers/pci/controller/dwc/Makefile
> +++ b/drivers/pci/controller/dwc/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
>  obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
>  obj-$(CONFIG_PCIE_VISCONTI_HOST) += pcie-visconti.o
>  obj-$(CONFIG_PCIE_RCAR_GEN4) += pcie-rcar-gen4.o
> +obj-$(CONFIG_PCIE_STM32) += pcie-stm32.o
>  
>  # The following drivers are for devices that use the generic ACPI
>  # pci_root.c driver but don't support standard ECAM config access.
> diff --git a/drivers/pci/controller/dwc/pcie-stm32.c b/drivers/pci/controller/dwc/pcie-stm32.c
> new file mode 100644
> index 000000000000..fa787406c0e4
> --- /dev/null
> +++ b/drivers/pci/controller/dwc/pcie-stm32.c
> @@ -0,0 +1,402 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * STMicroelectronics STM32MP25 PCIe root complex driver.
> + *
> + * Copyright (C) 2024 STMicroelectronics
> + * Author: Christian Bruel <christian.bruel at foss.st.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_platform.h>
> +#include <linux/phy/phy.h>
> +#include <linux/pinctrl/devinfo.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include "pcie-designware.h"
> +#include "pcie-stm32.h"
> +#include "../../pci.h"
> +
> +struct stm32_pcie {
> +	struct dw_pcie *pci;
> +	struct regmap *regmap;
> +	struct reset_control *rst;
> +	struct phy *phy;
> +	struct clk *clk;
> +	struct gpio_desc *perst_gpio;
> +	struct gpio_desc *wake_gpio;
> +	unsigned int wake_irq;
> +	bool link_is_up;
> +};
> +
> +static int stm32_pcie_start_link(struct dw_pcie *pci)
> +{
> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
> +	u32 ret;
> +
> +	if (stm32_pcie->perst_gpio) {

gpiod_set_value() will bail out if 'perst_gpio' is NULL. So no need to add a
check.

> +		/* Make sure PERST# is asserted. */

Why?

> +		gpiod_set_value(stm32_pcie->perst_gpio, 1);
> +
> +		fsleep(PCIE_T_PERST_CLK_US);
> +		gpiod_set_value(stm32_pcie->perst_gpio, 0);

Why can't you deassert PERST# in stm32_add_pcie_port()?

> +	}
> +
> +	ret = regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
> +				 STM32MP25_PCIECR_LTSSM_EN,
> +				 STM32MP25_PCIECR_LTSSM_EN);
> +
> +	if (stm32_pcie->perst_gpio)

It doesn't hurt to call msleep() always.

> +		msleep(PCIE_T_RRS_READY_MS);
> +
> +	return ret;
> +}
> +
> +static void stm32_pcie_stop_link(struct dw_pcie *pci)
> +{
> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
> +
> +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
> +			   STM32MP25_PCIECR_LTSSM_EN, 0);
> +
> +	/* Assert PERST# */
> +	if (stm32_pcie->perst_gpio)
> +		gpiod_set_value(stm32_pcie->perst_gpio, 1);

I don't like tying PERST# handling with start/stop link. PERST# should be
handled based on the power/clock state.

> +}
> +
> +static int stm32_pcie_suspend(struct device *dev)
> +{
> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> +
> +	if (device_may_wakeup(dev) || device_wakeup_path(dev))
> +		enable_irq_wake(stm32_pcie->wake_irq);
> +
> +	return 0;
> +}
> +
> +static int stm32_pcie_resume(struct device *dev)
> +{
> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> +
> +	if (device_may_wakeup(dev) || device_wakeup_path(dev))
> +		disable_irq_wake(stm32_pcie->wake_irq);
> +
> +	return 0;
> +}
> +
> +static int stm32_pcie_suspend_noirq(struct device *dev)
> +{
> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> +
> +	stm32_pcie->link_is_up = dw_pcie_link_up(stm32_pcie->pci);
> +
> +	stm32_pcie_stop_link(stm32_pcie->pci);

I don't understand how endpoint can wakeup the host if PERST# gets asserted.

> +	clk_disable_unprepare(stm32_pcie->clk);
> +
> +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev))
> +		phy_exit(stm32_pcie->phy);
> +
> +	return pinctrl_pm_select_sleep_state(dev);
> +}
> +
> +static int stm32_pcie_resume_noirq(struct device *dev)
> +{
> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> +	struct dw_pcie *pci = stm32_pcie->pci;
> +	struct dw_pcie_rp *pp = &pci->pp;
> +	int ret;
> +
> +	/* init_state must be called first to force clk_req# gpio when no

CLKREQ#

Why RC should control CLKREQ#?

Also please use preferred style for multi-line comments:

	/*
	 * ...
	 */

> +	 * device is plugged.
> +	 */
> +	if (!IS_ERR(dev->pins->init_state))
> +		ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
> +	else
> +		ret = pinctrl_pm_select_default_state(dev);
> +
> +	if (ret) {
> +		dev_err(dev, "Failed to activate pinctrl pm state: %d\n", ret);
> +		return ret;
> +	}
> +
> +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev)) {
> +		ret = phy_init(stm32_pcie->phy);
> +		if (ret) {
> +			pinctrl_pm_select_default_state(dev);
> +			return ret;
> +		}
> +	}
> +
> +	ret = clk_prepare_enable(stm32_pcie->clk);
> +	if (ret)
> +		goto clk_err;

Please name the goto labels of their purpose. Like err_phy_exit.

> +
> +	ret = dw_pcie_setup_rc(pp);
> +	if (ret)
> +		goto pcie_err;

This should be, 'err_disable_clk'.

> +
> +	if (stm32_pcie->link_is_up) {

Why do you need this check? You cannot start the link in the absence of an
endpoint?

> +		ret = stm32_pcie_start_link(stm32_pcie->pci);
> +		if (ret)
> +			goto pcie_err;
> +
> +		/* Ignore errors, the link may come up later */
> +		dw_pcie_wait_for_link(stm32_pcie->pci);
> +	}
> +
> +	pinctrl_pm_select_default_state(dev);
> +
> +	return 0;
> +
> +pcie_err:
> +	dw_pcie_host_deinit(pp);
> +	clk_disable_unprepare(stm32_pcie->clk);
> +clk_err:
> +	phy_exit(stm32_pcie->phy);
> +	pinctrl_pm_select_default_state(dev);
> +
> +	return ret;
> +}
> +
> +static const struct dev_pm_ops stm32_pcie_pm_ops = {
> +	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_pcie_suspend_noirq,
> +				  stm32_pcie_resume_noirq)

Can you make use of dw_pcie_{suspend/resume}_noirq() APIs?

> +	SYSTEM_SLEEP_PM_OPS(stm32_pcie_suspend, stm32_pcie_resume)
> +};
> +
> +static const struct dw_pcie_host_ops stm32_pcie_host_ops = {
> +};
> +
> +static const struct dw_pcie_ops dw_pcie_ops = {
> +	.start_link = stm32_pcie_start_link,
> +	.stop_link = stm32_pcie_stop_link
> +};
> +

[...]

> +	if (device_property_read_bool(dev, "wakeup-source")) {
> +		stm32_pcie->wake_gpio = devm_gpiod_get_optional(dev, "wake",
> +								GPIOD_IN);
> +		if (IS_ERR(stm32_pcie->wake_gpio))
> +			return dev_err_probe(dev, PTR_ERR(stm32_pcie->wake_gpio),
> +					     "Failed to get wake GPIO\n");
> +	}
> +
> +	if (stm32_pcie->wake_gpio) {
> +		stm32_pcie->wake_irq = gpiod_to_irq(stm32_pcie->wake_gpio);
> +
> +		ret = devm_request_threaded_irq(&pdev->dev,
> +						stm32_pcie->wake_irq, NULL,
> +						stm32_pcie_wake_irq_handler,
> +						IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> +						"wake_irq", stm32_pcie);
> +
> +		if (ret)
> +			return dev_err_probe(dev, ret, "Failed to request WAKE IRQ: %d\n", ret);
> +	}

Can we move WAKE# gpio handling to DWC core? There is nothing STM32 specific
here.

> +
> +	ret = devm_pm_runtime_enable(dev);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to enable runtime PM %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = pm_runtime_resume_and_get(dev);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to get runtime PM %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = stm32_add_pcie_port(stm32_pcie, pdev);
> +	if (ret)  {
> +		pm_runtime_put_sync(&pdev->dev);
> +		return ret;
> +	}
> +
> +	if (stm32_pcie->wake_gpio)
> +		device_set_wakeup_capable(dev, true);
> +
> +	return 0;
> +}
> +
> +static void stm32_pcie_remove(struct platform_device *pdev)
> +{
> +	struct stm32_pcie *stm32_pcie = platform_get_drvdata(pdev);
> +	struct dw_pcie_rp *pp = &stm32_pcie->pci->pp;
> +
> +	if (stm32_pcie->wake_gpio)
> +		device_init_wakeup(&pdev->dev, false);
> +
> +	dw_pcie_host_deinit(pp);
> +	clk_disable_unprepare(stm32_pcie->clk);
> +
> +	phy_exit(stm32_pcie->phy);
> +
> +	pm_runtime_put_sync(&pdev->dev);
> +}
> +
> +static const struct of_device_id stm32_pcie_of_match[] = {
> +	{ .compatible = "st,stm32mp25-pcie-rc" },
> +	{},
> +};
> +
> +static struct platform_driver stm32_pcie_driver = {
> +	.probe = stm32_pcie_probe,
> +	.remove = stm32_pcie_remove,
> +	.driver = {
> +		.name = "stm32-pcie",
> +		.of_match_table = stm32_pcie_of_match,
> +		.pm		= &stm32_pcie_pm_ops,

Just use a single space instead of tab.

Could you also set PROBE_PREFER_ASYNCHRONOUS to allow async probing of
controller drivers?

> +	},
> +};
> +
> +static bool is_stm32_pcie_driver(struct device *dev)
> +{
> +	/* PCI bridge */
> +	dev = get_device(dev);
> +
> +	/* Platform driver */
> +	dev = get_device(dev->parent);
> +
> +	return (dev->driver == &stm32_pcie_driver.driver);
> +}
> +
> +/*
> + * DMA masters can only access the first 4GB of memory space,
> + * so we setup the bus DMA limit accordingly.
> + */
> +static int stm32_dma_limit(struct pci_dev *pdev, void *data)
> +{
> +	dev_dbg(&pdev->dev, "disabling DMA DAC for device");
> +
> +	pdev->dev.bus_dma_limit = DMA_BIT_MASK(32);
> +
> +	return 0;
> +}
> +
> +static void quirk_stm32_dma_mask(struct pci_dev *pci)
> +{
> +	struct pci_dev *root_port;
> +
> +	root_port = pcie_find_root_port(pci);
> +
> +	if (root_port && is_stm32_pcie_driver(root_port->dev.parent))
> +		pci_walk_bus(pci->bus, stm32_dma_limit, NULL);
> +}
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SYNOPSYS, 0x0550, quirk_stm32_dma_mask);

This is not the correct way of using DMA masks as Bjorn noted.

- Mani

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Tue Dec  3 06:54:01 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Tue, 3 Dec 2024 20:24:01 +0530
Subject: [PATCH v2 3/5] dt-bindings: PCI: Add STM32MP25 PCIe endpoint
 bindings
In-Reply-To: <20241126155119.1574564-4-christian.bruel@foss.st.com>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-4-christian.bruel@foss.st.com>
Message-ID: <20241203145401.7snlxk3sybufaqp2@thinkpad>

On Tue, Nov 26, 2024 at 04:51:17PM +0100, Christian Bruel wrote:
> STM32MP25 PCIe Controller is based on the DesignWare core configured as
> end point mode from the SYSCFG register.
> 
> Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>

Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

- Mani

> ---
>  .../bindings/pci/st,stm32-pcie-ep.yaml        | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/st,stm32-pcie-ep.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pci/st,stm32-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/st,stm32-pcie-ep.yaml
> new file mode 100644
> index 000000000000..0da3ee012ba8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/st,stm32-pcie-ep.yaml
> @@ -0,0 +1,61 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/st,stm32-pcie-ep.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: STM32MP25 PCIe endpoint driver
> +
> +maintainers:
> +  - Christian Bruel <christian.bruel at foss.st.com>
> +
> +description:
> +  PCIe endpoint controller based on the Synopsys DesignWare PCIe core.
> +
> +allOf:
> +  - $ref: /schemas/pci/snps,dw-pcie-ep.yaml#
> +  - $ref: /schemas/pci/st,stm32-pcie-common.yaml#
> +
> +properties:
> +  compatible:
> +    const: st,stm32mp25-pcie-ep
> +
> +  reg:
> +    items:
> +      - description: Data Bus Interface (DBI) registers.
> +      - description: PCIe configuration registers.
> +
> +  reg-names:
> +    items:
> +      - const: dbi
> +      - const: addr_space
> +
> +required:
> +  - reset-gpios
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +    #include <dt-bindings/phy/phy.h>
> +    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
> +
> +    pcie-ep at 48400000 {
> +        compatible = "st,stm32mp25-pcie-ep";
> +        num-lanes = <1>;
> +        reg = <0x48400000 0x400000>,
> +              <0x10000000 0x8000000>;
> +        reg-names = "dbi", "addr_space";
> +        clocks = <&rcc CK_BUS_PCIE>;
> +        phys = <&combophy PHY_TYPE_PCIE>;
> +        phy-names = "pcie-phy";
> +        resets = <&rcc PCIE_R>;
> +        pinctrl-names = "default", "init";
> +        pinctrl-0 = <&pcie_pins_a>;
> +        pinctrl-1 = <&pcie_init_pins_a>;
> +        reset-gpios = <&gpioj 8 GPIO_ACTIVE_LOW>;
> +        access-controllers = <&rifsc 68>;
> +        power-domains = <&CLUSTER_PD>;
> +    };
> -- 
> 2.34.1
> 

-- 
????????? ????????


From jani.nikula at linux.intel.com  Tue Dec  3 06:56:04 2024
From: jani.nikula at linux.intel.com (Jani Nikula)
Date: Tue, 03 Dec 2024 16:56:04 +0200
Subject: [PATCH 06/10] drm/i915/audio: use eld_mutex to protect access
 to connector->eld
In-Reply-To: <20241201-drm-connector-eld-mutex-v1-6-ba56a6545c03@linaro.org>
References: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
 <20241201-drm-connector-eld-mutex-v1-6-ba56a6545c03@linaro.org>
Message-ID: <874j3k4xyz.fsf@intel.com>

On Sun, 01 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> Reading access to connector->eld can happen at the same time the
> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
> order to protect connector->eld from concurrent access.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Reviewed-by: Jani Nikula <jani.nikula at intel.com>

and

Acked-by: Jani Nikula <jani.nikula at intel.com>

for merging via whichever tree you find best.



> ---
>  drivers/gpu/drm/i915/display/intel_audio.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
> index 32aa9ec1a204d2ecde46cad36598aa768a3af671..3902ab8431139c3ff4dc17b841d94b6d3241dec3 100644
> --- a/drivers/gpu/drm/i915/display/intel_audio.c
> +++ b/drivers/gpu/drm/i915/display/intel_audio.c
> @@ -699,10 +699,12 @@ bool intel_audio_compute_config(struct intel_encoder *encoder,
>  	const struct drm_display_mode *adjusted_mode =
>  		&crtc_state->hw.adjusted_mode;
>  
> +	mutex_lock(&connector->eld_mutex);
>  	if (!connector->eld[0]) {
>  		drm_dbg_kms(&i915->drm,
>  			    "Bogus ELD on [CONNECTOR:%d:%s]\n",
>  			    connector->base.id, connector->name);
> +		mutex_unlock(&connector->eld_mutex);
>  		return false;
>  	}
>  
> @@ -710,6 +712,7 @@ bool intel_audio_compute_config(struct intel_encoder *encoder,
>  	memcpy(crtc_state->eld, connector->eld, sizeof(crtc_state->eld));
>  
>  	crtc_state->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2;
> +	mutex_unlock(&connector->eld_mutex);
>  
>  	return true;
>  }

-- 
Jani Nikula, Intel


From andrew at lunn.ch  Tue Dec  3 06:58:42 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 3 Dec 2024 15:58:42 +0100
Subject: [PATCH v4 3/3] net: stmmac: dwmac-nuvoton: Add dwmac glue for
 Nuvoton MA35 family
In-Reply-To: <75eb13d7-b582-4056-b707-706865611706@gmail.com>
References: <20241202023643.75010-1-a0987203069@gmail.com>
 <20241202023643.75010-4-a0987203069@gmail.com>
 <9f2c8532-8e52-439a-b253-ad2ceb07b21b@lunn.ch>
 <75eb13d7-b582-4056-b707-706865611706@gmail.com>
Message-ID: <ba09cea2-4cf7-4203-ae98-ea5d8413f69e@lunn.ch>

On Tue, Dec 03, 2024 at 05:12:24PM +0800, Joey Lu wrote:
> Dear Andrew,
> 
> You're correct. In the stmmac_hw_init function within stmmac_main.c, whether
> pmt is true is determined by checking the pmt_remote_wake_up bit in the
> hardware feature register. However, our hardware configuration only supports
> magic packet and not remote wakeup, so it must be overwritten in the glue
> driver.

Please add a comment explaining this. 


I'm not sure why the original code doesn't include magic packet as part
> of pmt.
> 
> source code:
> 
> ??? ??? stmmac_hw_init() @net/ethernet/stmicro/stmmac/stmmac_main.c
> 
> ??????? priv->plat->enh_desc = priv->dma_cap.enh_desc;
> ??????? priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up &&
> ??????????????? !(priv->plat->flags & STMMAC_FLAG_USE_PHY_WOL);
> ??????? priv->hw->pmt = priv->plat->pmt;
> 
> Or modify the condition as follows:
> 
> ??? ??? priv->plat->pmt = (priv->dma_cap.pmt_remote_wake_up || priv->
> dma_cap.pmt_magic_frame) &&
> ??????????????? !(priv->plat->flags & STMMAC_FLAG_USE_PHY_WOL);

Are there other glue drivers which would benefit from this? It is hard
for me to say if you hardware is odd, or if this should be a generic
feature which other glue drivers would use.

	Andrew


From kevin.brodsky at arm.com  Tue Dec  3 07:06:24 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Tue, 3 Dec 2024 16:06:24 +0100
Subject: [PATCH] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <Z07x69L6Mssncg/7@e133380.arm.com>
References: <20241203100322.1626805-1-kevin.brodsky@arm.com>
 <Z07x69L6Mssncg/7@e133380.arm.com>
Message-ID: <a9aa36eb-d5c2-4d1c-bf5d-e63e4cb55404@arm.com>

On 03/12/2024 12:56, Dave Martin wrote:
> On Tue, Dec 03, 2024 at 10:03:22AM +0000, Kevin Brodsky wrote:
>> [...]
>> @@ -1462,10 +1462,33 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
>>  			 struct rt_sigframe_user_layout *user, int usig)
>>  {
>>  	__sigrestore_t sigtramp;
>> +	int err;
>> +
>> +	if (ksig->ka.sa.sa_flags & SA_RESTORER)
>> +		sigtramp = ksig->ka.sa.sa_restorer;
>> +	else
>> +		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
>> +
>> +	err = gcs_signal_entry(sigtramp, ksig);
>> +	if (err)
>> +		return err;
>> +
>> +	/*
>> +	 * We must not fail from this point onwards. We are going to update
>> +	 * registers, including SP, in order to invoke the signal handler. If
>> +	 * we failed and attempted to deliver a nested SIGSEGV to a handler
>> +	 * after that point, the subsequent sigreturn would end up restoring
>> +	 * the (partial) state for the original signal handler.
>> +	 */
> The same is true at the call site of this function; could problems
> creep back in there?

That's a fair point, I could add a short comment after the call to
setup_return() to clarify this.

>>  
>>  	regs->regs[0] = usig;
>> +	if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
>> +		regs->regs[1] = (unsigned long)&user->sigframe->info;
>> +		regs->regs[2] = (unsigned long)&user->sigframe->uc;
> Nit: This looks like it should work, but it's not really anything to do
> with setting up how the handler returns (we're in setup_return() here).

setup_return() is a bit of a misnomer, unless you interpret "return" as
"return to userspace". Aside from setting LR, setup_return() isn't about
how the handler returns but simply how it is invoked. For instance the
line just above sets X0 to the signal number, the first argument of the
handler. Setting X1/X2 here seems pretty natural (they're also arguments
for the handler).

- Kevin


From linux at fw-web.de  Tue Dec  3 07:08:22 2024
From: linux at fw-web.de (Frank Wunderlich (linux))
Date: Tue, 03 Dec 2024 16:08:22 +0100
Subject: [PATCH v2 03/18] arm64: dts: mediatek: mt7988: add fixed
 regulators for 1v8 and 3v3
In-Reply-To: <4da0ab36-34c2-413a-90b3-bcdbdd4a6ac0@collabora.com>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-4-linux@fw-web.de>
 <016b77dc-2d33-4639-b241-2574ad877971@collabora.com>
 <371B3F0C-D468-45C8-B1F6-F4619B7C72DD@public-files.de>
 <4da0ab36-34c2-413a-90b3-bcdbdd4a6ac0@collabora.com>
Message-ID: <942f0a95284be1e0c0c043b965fb42c2@fw-web.de>

Am 2024-12-03 15:20, schrieb AngeloGioacchino Del Regno:
> Il 03/12/24 11:51, Frank Wunderlich ha scritto:
>> Am 3. Dezember 2024 10:40:54 MEZ schrieb AngeloGioacchino Del Regno 
>> <angelogioacchino.delregno at collabora.com>:
>>> Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>>>> From: Frank Wunderlich <frank-w at public-files.de>
>>>> 
>>>> Add regulator nodes used for mmc to Bananapi R4 board.
>>>> 
>>>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>>> 
>>> If you're adding the eMMC regulators, I assume that there's an eMMC, 
>>> or that even
>>> if there's no device in some version of the board, these two 
>>> regulators are always
>>> assigned to the eMMC device - right?
>> 
>> Like BPi-R3 there is one mmc controller mapped to either sd or emmc. I 
>> can move the regulators to the dtbo,but then they are defined twice 
>> (at least 3v3).
>> 
>>> You should, at this point, do exactly that: you can leave the mmc0 
>>> disabled and
>>> only enable it in a DTBO.
>> 
>> I enable it only in dtbo...
>> 
>>> &mmc0 {
>>> 	/* eMMC gets enabled by DTBO if present */
>>> 	vmmc-supply = <&reg_3p3v>;
>>> 	vqmmc-supply = <&reg_1p8v>;
>>> };
>> 
>> Problem is here that sdcard uses only the 3v3 twice
>> 
>> https://github.com/frank-w/BPI-Router-Linux/blob/6.12-main/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
>> 
>> And emmc needs both
>> 
>> https://github.com/frank-w/BPI-Router-Linux/blob/6.12-main/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
>> 
>> Only defining the vmmc-supply in dts and set only the other in dtso is 
>> possible but but imho not nice.
>> 
> 
> If you added that in the commit description in the first place, I 
> wouldn't
> have sent you that suggestion ;-)
> 
> So, please add the reason that you just explained to me in the 
> description
> of this commit and just leave the code as-is.

OK, would this be ok?

arm64: dts: mediatek: mt7988a-bpi-r4: add fixed regulators for 1v8 and 
3v3

Add regulator nodes used for mmc to Bananapi R4 board.
This board has 1 MMC controller used for SDMMC and eMMC where only one 
can
be used at one time, selected by hardware switches. SD use 3v3 for both
supplies and emmc uses both regulators.
So defining both regulators in board dts and referencing them in the dt
overlay.

> Cheers!
> 
>>> Cheers,
>>> Angelo
>>> 
>>>> ---
>>>> v2:
>>>> - move mmc regulators to board dts of bpi-r4
>>>> ---
>>>>    .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts   | 18 
>>>> ++++++++++++++++++
>>>>    1 file changed, 18 insertions(+)
>>>> 
>>>> diff --git 
>>>> a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts 
>>>> b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>>>> index d914eae2b524..df53512c6890 100644
>>>> --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>>>> +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
>>>> @@ -8,6 +8,24 @@ / {
>>>>    	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
>>>>    	model = "Banana Pi BPI-R4";
>>>>    	chassis-type = "embedded";
>>>> +
>>>> +	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;
>>>> +	};
>>>>    };
>>>>      &pio {
>>> 
>>> 
>> 
>> 
>> regards Frank


From stephan.gerhold at linaro.org  Tue Dec  3 07:11:22 2024
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Tue, 3 Dec 2024 16:11:22 +0100
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint readery
In-Reply-To: <Z07zeVJU3Y1GiSLL@linaro.org>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com>
 <Z07r3Upr50vLluyn@linaro.org>
 <Z07zeVJU3Y1GiSLL@linaro.org>
Message-ID: <Z08fmvBEh6dYQimN@linaro.org>

+Cc Dmitry

On Tue, Dec 03, 2024 at 02:03:05PM +0200, Abel Vesa wrote:
> On 24-12-03 12:30:37, Stephan Gerhold wrote:
> > On Tue, Dec 03, 2024 at 11:20:48AM +0100, Johan Hovold wrote:
> > > [ +CC: Krishna, Thinh and the USB list ]
> > > 
> > > On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
> > > > The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
> > > > multiport controller on eUSB6. All other ports (including USB super-speed
> > > > pins) are unused.
> > > > 
> > > > Set it up in the device tree together with the NXP PTN3222 repeater.
> > > > 
> > > > Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> > > > ---
> > > >  arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 48 +++++++++++++++++++++++++++++++
> > > >  1 file changed, 48 insertions(+)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > > > index 39f9d9cdc10d..44942931c18f 100644
> > > > --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > > > +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > > > @@ -735,6 +735,26 @@ keyboard at 3a {
> > > >  	};
> > > >  };
> > > >  
> > > > +&i2c5 {
> > > > +	clock-frequency = <400000>;
> > > > +
> > > > +	status = "okay";
> > > > +
> > > > +	eusb6_repeater: redriver at 4f {
> > > > +		compatible = "nxp,ptn3222";
> > > > +		reg = <0x4f>;
> > > 
> > > The driver does not currently check that there's actually anything at
> > > this address. Did you verify that this is the correct address? 
> > > 
> > > (Abel is adding a check to the driver as we speak to catch any such
> > > mistakes going forward).
> > > 
> > 
> > Yes, I verified this using
> > https://git.codelinaro.org/stephan.gerhold/linux/-/commit/45d5add498612387f88270ca944ee16e2236fddd
> > 
> > (I sent this to Abel back then, so I'm surprised he didn't run that :-))
> 
> I don't remember seeing this commit back then. Maybe I didn't look
> careful enough. Sorry.
> 
> Since you already did the work, can you send that on the list?
> 

Sure, no problem. What exactly do we want for upstream?

My patch above isn't ideal, because it checks the CHIP_ID on every PHY
power up. But briefly powering up the PHY during probe() just for
reading the CHIP_ID is also a bit weird. Not sure what the best approach
here is.

Thanks,
Stephan


From gregkh at linuxfoundation.org  Tue Dec  3 06:40:58 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue,  3 Dec 2024 15:40:58 +0100
Subject: [PATCH 6.11 486/817] perf stat: Uniquify event name improvements
In-Reply-To: <20241203143955.605130076@linuxfoundation.org>
References: <20241203143955.605130076@linuxfoundation.org>
Message-ID: <20241203144014.842031727@linuxfoundation.org>

6.11-stable review patch.  If anyone has any objections, please let me know.

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

From: Ian Rogers <irogers at google.com>

[ Upstream commit 057f8bfc6f7070577523d1e3081081bbf4229c1c ]

Without aggregation on Intel:
```
$ perf stat -e instructions,cycles ...
```
Will use "cycles" for the name of the legacy cycles event but as
"instructions" has a sysfs name it will and a "[cpu]" PMU suffix. This
often breaks things as the space between the event and the PMU name
look like an extra column. The existing uniquify logic was also
uniquifying in cases when all events are core and not with uncore
events, it was not correctly handling modifiers, etc.

Change the logic so that an initial pass that can disable
uniquification is run. For individual counters, disable uniquification
in more cases such as for consistency with legacy events or for
libpfm4 events. Don't use the "[pmu]" style suffix in uniquification,
always use "pmu/.../". Change how modifiers/terms are handled in the
uniquification so that they look like parse-able events.

This fixes "102: perf stat metrics (shadow stat) test:" that has been
failing due to "instructions [cpu]" breaking its column/awk logic when
values aren't aggregated. This started happening when instructions
could match a sysfs rather than a legacy event, so the fixes tag
reflects this.

Fixes: 617824a7f0f7 ("perf parse-events: Prefer sysfs/JSON hardware events over legacy")
Acked-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
[ Fix Intel TPEBS counting mode test ]
Acked-by: Kan Liang <kan.liang at linux.intel.com>
Signed-off-by: James Clark <james.clark at linaro.org>
Cc: Yang Jihong <yangjihong at bytedance.com>
Cc: Dominique Martinet <asmadeus at codewreck.org>
Cc: Colin Ian King <colin.i.king at gmail.com>
Cc: Howard Chu <howardchu95 at gmail.com>
Cc: Ze Gao <zegao2021 at gmail.com>
Cc: Yicong Yang <yangyicong at hisilicon.com>
Cc: Weilin Wang <weilin.wang at intel.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Jing Zhang <renyu.zj at linux.alibaba.com>
Cc: Yang Li <yang.lee at linux.alibaba.com>
Cc: Leo Yan <leo.yan at linux.dev>
Cc: ak at linux.intel.com
Cc: Athira Rajeev <atrajeev at linux.vnet.ibm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: Sun Haiyong <sunhaiyong at loongson.cn>
Cc: John Garry <john.g.garry at oracle.com>
Link: https://lore.kernel.org/r/20240926144851.245903-3-james.clark at linaro.org
Signed-off-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 .../perf/tests/shell/test_stat_intel_tpebs.sh |  11 +-
 tools/perf/util/stat-display.c                | 101 ++++++++++++++----
 2 files changed, 85 insertions(+), 27 deletions(-)

diff --git a/tools/perf/tests/shell/test_stat_intel_tpebs.sh b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
index c60b29add9801..9a11f42d153ca 100755
--- a/tools/perf/tests/shell/test_stat_intel_tpebs.sh
+++ b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
@@ -8,12 +8,15 @@ grep -q GenuineIntel /proc/cpuinfo || { echo Skipping non-Intel; exit 2; }
 # Use this event for testing because it should exist in all platforms
 event=cache-misses:R
 
+# Hybrid platforms output like "cpu_atom/cache-misses/R", rather than as above
+alt_name=/cache-misses/R
+
 # Without this cmd option, default value or zero is returned
-echo "Testing without --record-tpebs"
-result=$(perf stat -e "$event" true 2>&1)
-[[ "$result" =~ $event ]] || exit 1
+#echo "Testing without --record-tpebs"
+#result=$(perf stat -e "$event" true 2>&1)
+#[[ "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
 
 # In platforms that do not support TPEBS, it should execute without error.
 echo "Testing with --record-tpebs"
 result=$(perf stat -e "$event" --record-tpebs -a sleep 0.01 2>&1)
-[[ "$result" =~ "perf record" && "$result" =~ $event ]] || exit 1
+[[ "$result" =~ "perf record" && "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index ea96e4ebad8c8..cbff43ff8d0fb 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -871,38 +871,66 @@ static void printout(struct perf_stat_config *config, struct outstate *os,
 
 static void uniquify_event_name(struct evsel *counter)
 {
-	char *new_name;
-	char *config;
-	int ret = 0;
+	const char *name, *pmu_name;
+	char *new_name, *config;
+	int ret;
 
-	if (counter->uniquified_name || counter->use_config_name ||
-	    !counter->pmu_name || !strncmp(evsel__name(counter), counter->pmu_name,
-					   strlen(counter->pmu_name)))
+	/* The evsel was already uniquified. */
+	if (counter->uniquified_name)
 		return;
 
-	config = strchr(counter->name, '/');
+	/* Avoid checking to uniquify twice. */
+	counter->uniquified_name = true;
+
+	/* The evsel has a "name=" config term or is from libpfm. */
+	if (counter->use_config_name || counter->is_libpfm_event)
+		return;
+
+	/* Legacy no PMU event, don't uniquify. */
+	if  (!counter->pmu ||
+	     (counter->pmu->type < PERF_TYPE_MAX && counter->pmu->type != PERF_TYPE_RAW))
+		return;
+
+	/* A sysfs or json event replacing a legacy event, don't uniquify. */
+	if (counter->pmu->is_core && counter->alternate_hw_config != PERF_COUNT_HW_MAX)
+		return;
+
+	name = evsel__name(counter);
+	pmu_name = counter->pmu->name;
+	/* Already prefixed by the PMU name. */
+	if (!strncmp(name, pmu_name, strlen(pmu_name)))
+		return;
+
+	config = strchr(name, '/');
 	if (config) {
-		if (asprintf(&new_name,
-			     "%s%s", counter->pmu_name, config) > 0) {
-			free(counter->name);
-			counter->name = new_name;
-		}
-	} else {
-		if (evsel__is_hybrid(counter)) {
-			ret = asprintf(&new_name, "%s/%s/",
-				       counter->pmu_name, counter->name);
+		int len = config - name;
+
+		if (config[1] == '/') {
+			/* case: event// */
+			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 2);
 		} else {
-			ret = asprintf(&new_name, "%s [%s]",
-				       counter->name, counter->pmu_name);
+			/* case: event/.../ */
+			ret = asprintf(&new_name, "%s/%.*s,%s", pmu_name, len, name, config + 1);
 		}
+	} else {
+		config = strchr(name, ':');
+		if (config) {
+			/* case: event:.. */
+			int len = config - name;
 
-		if (ret) {
-			free(counter->name);
-			counter->name = new_name;
+			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 1);
+		} else {
+			/* case: event */
+			ret = asprintf(&new_name, "%s/%s/", pmu_name, name);
 		}
 	}
-
-	counter->uniquified_name = true;
+	if (ret > 0) {
+		free(counter->name);
+		counter->name = new_name;
+	} else {
+		/* ENOMEM from asprintf. */
+		counter->uniquified_name = false;
+	}
 }
 
 static bool hybrid_uniquify(struct evsel *evsel, struct perf_stat_config *config)
@@ -1559,6 +1587,31 @@ static void print_cgroup_counter(struct perf_stat_config *config, struct evlist
 		print_metric_end(config, os);
 }
 
+static void disable_uniquify(struct evlist *evlist)
+{
+	struct evsel *counter;
+	struct perf_pmu *last_pmu = NULL;
+	bool first = true;
+
+	evlist__for_each_entry(evlist, counter) {
+		/* If PMUs vary then uniquify can be useful. */
+		if (!first && counter->pmu != last_pmu)
+			return;
+		first = false;
+		if (counter->pmu) {
+			/* Allow uniquify for uncore PMUs. */
+			if (!counter->pmu->is_core)
+				return;
+			/* Keep hybrid event names uniquified for clarity. */
+			if (perf_pmus__num_core_pmus() > 1)
+				return;
+		}
+	}
+	evlist__for_each_entry_continue(evlist, counter) {
+		counter->uniquified_name = true;
+	}
+}
+
 void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config,
 			    struct target *_target, struct timespec *ts,
 			    int argc, const char **argv)
@@ -1572,6 +1625,8 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
 		.first = true,
 	};
 
+	disable_uniquify(evlist);
+
 	if (config->iostat_run)
 		evlist->selected = evlist__first(evlist);
 
-- 
2.43.0





From gregkh at linuxfoundation.org  Tue Dec  3 06:40:53 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue,  3 Dec 2024 15:40:53 +0100
Subject: [PATCH 6.11 481/817] perf cs-etm: Dont flush when packet_queue fills up
In-Reply-To: <20241203143955.605130076@linuxfoundation.org>
References: <20241203143955.605130076@linuxfoundation.org>
Message-ID: <20241203144014.646375317@linuxfoundation.org>

6.11-stable review patch.  If anyone has any objections, please let me know.

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

From: James Clark <james.clark at linaro.org>

[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]

cs_etm__flush(), like cs_etm__sample() is an operation that generates a
sample and then swaps the current with the previous packet. Calling
flush after processing the queues results in two swaps which corrupts
the next sample. Therefore it wasn't appropriate to call flush here so
remove it.

Flushing is still done on a discontinuity to explicitly clear the last
branch buffer, but when the packet_queue fills up before reaching a
timestamp, that's not a discontinuity and the call to
cs_etm__process_traceid_queue() already generated samples and drained
the buffers correctly.

This is visible by looking for a branch that has the same target as the
previous branch and the following source is before the address of the
last target, which is impossible as execution would have had to have
gone backwards:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
   (packet_queue fills here before a timestamp, resulting in a flush and
    branch target ffff80008011cadc is duplicated.)
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

After removing the flush the correct branch target is used for the
second sample, and ffff8000801117c4 is no longer before the previous
address:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

Make sure that a final branch stack is output at the end of the trace
by calling cs_etm__end_block(). This is already done for both the
timeless decode paths.

Fixes: 21fe8dc1191a ("perf cs-etm: Add support for CPU-wide trace scenarios")
Reported-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Closes: https://lore.kernel.org/all/20240719092619.274730-1-gankulkarni at os.amperecomputing.com/
Reviewed-by: Leo Yan <leo.yan at arm.com>
Signed-off-by: James Clark <james.clark at linaro.org>
Tested-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Cc: Ben Gainey <ben.gainey at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Ruidong Tian <tianruidong at linux.alibaba.com>
Cc: Benjamin Gray <bgray at linux.ibm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: coresight at lists.linaro.org
Cc: John Garry <john.g.garry at oracle.com>
Cc: scclevenger at os.amperecomputing.com
Link: https://lore.kernel.org/r/20240916135743.1490403-2-james.clark at linaro.org
Signed-off-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/perf/util/cs-etm.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 5e9fbcfad7d44..f4615fa4280d8 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2439,12 +2439,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
 
 		/* Ignore return value */
 		cs_etm__process_traceid_queue(etmq, tidq);
-
-		/*
-		 * Generate an instruction sample with the remaining
-		 * branchstack entries.
-		 */
-		cs_etm__flush(etmq, tidq);
 	}
 }
 
@@ -2587,7 +2581,7 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)
 
 	while (1) {
 		if (!etm->heap.heap_cnt)
-			goto out;
+			break;
 
 		/* Take the entry at the top of the min heap */
 		cs_queue_nr = etm->heap.heap_array[0].queue_nr;
@@ -2670,6 +2664,23 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)
 		ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp);
 	}
 
+	for (i = 0; i < etm->queues.nr_queues; i++) {
+		struct int_node *inode;
+
+		etmq = etm->queues.queue_array[i].priv;
+		if (!etmq)
+			continue;
+
+		intlist__for_each_entry(inode, etmq->traceid_queues_list) {
+			int idx = (int)(intptr_t)inode->priv;
+
+			/* Flush any remaining branch stack entries */
+			tidq = etmq->traceid_queues[idx];
+			ret = cs_etm__end_block(etmq, tidq);
+			if (ret)
+				return ret;
+		}
+	}
 out:
 	return ret;
 }
-- 
2.43.0





From catalin.marinas at arm.com  Tue Dec  3 07:19:41 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue,  3 Dec 2024 15:19:41 +0000
Subject: [PATCH] arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs
Message-ID: <20241203151941.353796-1-catalin.marinas@arm.com>

Linux currently sets the TCR_EL1.AS bit unconditionally during CPU
bring-up. On an 8-bit ASID CPU, this is RES0 and ignored, otherwise
16-bit ASIDs are enabled. However, if running in a VM and the hypervisor
reports 8-bit ASIDs (ID_AA64MMFR0_EL1.ASIDBits == 0) on a 16-bit ASIDs
CPU, Linux uses bits 8 to 63 as a generation number for tracking old
process ASIDs. The bottom 8 bits of this generation end up being written
to TTBR1_EL1 and also used for the ASID-based TLBI operations as the
upper 8 bits of the ASID. Following an ASID roll-over event we can have
threads of the same application with the same 8-bit ASID but different
generation numbers running on separate CPUs. Both TLB caching and the
TLBI operations will end up using different actual 16-bit ASIDs for the
same process.

A similar scenario can happen in a big.LITTLE configuration if the boot
CPU only uses 8-bit ASIDs while secondary CPUs have 16-bit ASIDs.

Ensure that the ASID generation is only tracked by bits 16 and up,
leaving bits 15:8 as 0 if the kernel uses 8-bit ASIDs. Note that
clearing TCR_EL1.AS is not sufficient since the architecture requires
that the top 8 bits of the ASID passed to TLBI instructions are 0 rather
than ignored in such configuration.

Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Cc: <stable at vger.kernel.org>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
---
 arch/arm64/mm/context.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
index 188197590fc9..b2ac06246327 100644
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -32,9 +32,9 @@ static unsigned long nr_pinned_asids;
 static unsigned long *pinned_asid_map;
 
 #define ASID_MASK		(~GENMASK(asid_bits - 1, 0))
-#define ASID_FIRST_VERSION	(1UL << asid_bits)
+#define ASID_FIRST_VERSION	(1UL << 16)
 
-#define NUM_USER_ASIDS		ASID_FIRST_VERSION
+#define NUM_USER_ASIDS		(1UL << asid_bits)
 #define ctxid2asid(asid)	((asid) & ~ASID_MASK)
 #define asid2ctxid(asid, genid)	((asid) | (genid))
 


From rostedt at goodmis.org  Tue Dec  3 07:20:47 2024
From: rostedt at goodmis.org (Steven Rostedt)
Date: Tue, 3 Dec 2024 10:20:47 -0500
Subject: [PATCH 1/9] coresight: change coresight_device lock type to
 raw_spinlock_t
In-Reply-To: <GV1PR08MB105212FEF9251CA2B3AAF7FFFFB362@GV1PR08MB10521.eurprd08.prod.outlook.com>
References: <20241125094816.365472-1-yeoreum.yun@arm.com>
	<20241125094816.365472-2-yeoreum.yun@arm.com>
	<20241127120954.0facd34f@gandalf.local.home>
	<GV1PR08MB10521520ABD7B72D92FD60DE9FB292@GV1PR08MB10521.eurprd08.prod.outlook.com>
	<20241202103853.26db0c13@gandalf.local.home>
	<GV1PR08MB105212FEF9251CA2B3AAF7FFFFB362@GV1PR08MB10521.eurprd08.prod.outlook.com>
Message-ID: <20241203102047.5844de81@gandalf.local.home>

On Tue, 3 Dec 2024 08:31:54 +0000
Yeo Reum Yun <YeoReum.Yun at arm.com> wrote:

> Hi Steve,
> 
> > Still should be documented somewhere. It should describe the maximum number
> > of feats that will ever be loaded. If there's a max, it makes it back to
> > O(1). With a 'k' of how long it takes to process the max number of feats.  
> 
> But with other patchset seems better
> since not only this function, but also for other functions too.

Which other patchset?

> 
> BTW, is there any example describing this I can refer? 

No, it's on our todo list for RT. To document the RT behavior of the
kernel. This is just one location.

-- Steve


From manivannan.sadhasivam at linaro.org  Tue Dec  3 07:22:30 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Tue, 3 Dec 2024 20:52:30 +0530
Subject: [PATCH v2 4/5] PCI: stm32: Add PCIe endpoint support for
 STM32MP25
In-Reply-To: <20241126155119.1574564-5-christian.bruel@foss.st.com>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-5-christian.bruel@foss.st.com>
Message-ID: <20241203152230.5mdrt27u5u5ecwcz@thinkpad>

On Tue, Nov 26, 2024 at 04:51:18PM +0100, Christian Bruel wrote:

[...]

> +static int stm32_pcie_start_link(struct dw_pcie *pci)
> +{
> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
> +	int ret;
> +
> +	if (stm32_pcie->link_status == STM32_PCIE_EP_LINK_ENABLED) {
> +		dev_dbg(pci->dev, "Link is already enabled\n");
> +		return 0;
> +	}
> +
> +	ret = stm32_pcie_enable_link(pci);
> +	if (ret) {
> +		dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret);
> +		return ret;
> +	}

How the REFCLK is supplied to the endpoint? From host or generated locally?

> +
> +	stm32_pcie->link_status = STM32_PCIE_EP_LINK_ENABLED;
> +
> +	enable_irq(stm32_pcie->perst_irq);
> +
> +	return 0;
> +}
> +
> +static void stm32_pcie_stop_link(struct dw_pcie *pci)
> +{
> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
> +
> +	if (stm32_pcie->link_status == STM32_PCIE_EP_LINK_DISABLED) {
> +		dev_dbg(pci->dev, "Link is already disabled\n");
> +		return;
> +	}
> +
> +	disable_irq(stm32_pcie->perst_irq);
> +
> +	stm32_pcie_disable_link(pci);
> +
> +	stm32_pcie->link_status = STM32_PCIE_EP_LINK_DISABLED;
> +}
> +
> +static int stm32_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
> +				unsigned int type, u16 interrupt_num)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> +
> +	switch (type) {
> +	case PCI_IRQ_INTX:
> +		return dw_pcie_ep_raise_intx_irq(ep, func_no);
> +	case PCI_IRQ_MSI:
> +		return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
> +	default:
> +		dev_err(pci->dev, "UNKNOWN IRQ type\n");
> +		return -EINVAL;
> +	}
> +}
> +
> +static const struct pci_epc_features stm32_pcie_epc_features = {
> +	.msi_capable = true,
> +	.align = 1 << 16,

Use SZ_64K

> +};
> +

[...]

> +static int stm32_add_pcie_ep(struct stm32_pcie *stm32_pcie,
> +			     struct platform_device *pdev)
> +{
> +	struct dw_pcie *pci = stm32_pcie->pci;
> +	struct dw_pcie_ep *ep = &pci->ep;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +
> +	ret = regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
> +				 STM32MP25_PCIECR_TYPE_MASK,
> +				 STM32MP25_PCIECR_EP);
> +	if (ret)
> +		return ret;
> +
> +	ret = pm_runtime_resume_and_get(dev);
> +	if (ret < 0) {
> +		dev_err(dev, "pm runtime resume failed: %d\n", ret);
> +		return ret;
> +	}

You might want to do runtime resume before accessing regmap.

> +
> +	reset_control_assert(stm32_pcie->rst);
> +	reset_control_deassert(stm32_pcie->rst);
> +
> +	ep->ops = &stm32_pcie_ep_ops;
> +
> +	ret = dw_pcie_ep_init(ep);
> +	if (ret) {
> +		dev_err(dev, "failed to initialize ep: %d\n", ret);
> +		goto err_init;
> +	}
> +
> +	ret = stm32_pcie_enable_resources(stm32_pcie);
> +	if (ret) {
> +		dev_err(dev, "failed to enable resources: %d\n", ret);
> +		goto err_clk;
> +	}
> +
> +	ret = dw_pcie_ep_init_registers(ep);
> +	if (ret) {
> +		dev_err(dev, "Failed to initialize DWC endpoint registers\n");
> +		goto err_init_regs;
> +	}
> +
> +	pci_epc_init_notify(ep->epc);
> +
> +	return 0;
> +
> +err_init_regs:
> +	stm32_pcie_disable_resources(stm32_pcie);
> +
> +err_clk:
> +	dw_pcie_ep_deinit(ep);
> +
> +err_init:
> +	pm_runtime_put_sync(dev);
> +	return ret;
> +}
> +
> +static int stm32_pcie_probe(struct platform_device *pdev)
> +{
> +	struct stm32_pcie *stm32_pcie;
> +	struct dw_pcie *dw;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +
> +	stm32_pcie = devm_kzalloc(dev, sizeof(*stm32_pcie), GFP_KERNEL);
> +	if (!stm32_pcie)
> +		return -ENOMEM;
> +
> +	dw = devm_kzalloc(dev, sizeof(*dw), GFP_KERNEL);
> +	if (!dw)
> +		return -ENOMEM;

Why can't you allocate it statically inside 'struct stm32_pcie'?

> +
> +	stm32_pcie->pci = dw;
> +
> +	dw->dev = dev;
> +	dw->ops = &dw_pcie_ops;
> +
> +	stm32_pcie->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
> +	if (IS_ERR(stm32_pcie->regmap))
> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->regmap),
> +				     "No syscfg specified\n");
> +
> +	stm32_pcie->phy = devm_phy_get(dev, "pcie-phy");
> +	if (IS_ERR(stm32_pcie->phy))
> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->phy),
> +				     "failed to get pcie-phy\n");
> +
> +	stm32_pcie->clk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(stm32_pcie->clk))
> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->clk),
> +				     "Failed to get PCIe clock source\n");
> +
> +	stm32_pcie->rst = devm_reset_control_get_exclusive(dev, NULL);
> +	if (IS_ERR(stm32_pcie->rst))
> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->rst),
> +				     "Failed to get PCIe reset\n");
> +
> +	stm32_pcie->perst_gpio = devm_gpiod_get(dev, "reset", GPIOD_IN);
> +	if (IS_ERR(stm32_pcie->perst_gpio))
> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->perst_gpio),
> +				     "Failed to get reset GPIO\n");
> +
> +	ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE);

Hmm, so PHY mode is common for both endpoint and host?

- Mani

-- 
????????? ????????


From linux at fw-web.de  Tue Dec  3 07:28:25 2024
From: linux at fw-web.de (Frank Wunderlich (linux))
Date: Tue, 03 Dec 2024 16:28:25 +0100
Subject: [PATCH v2 13/18] arm64: dts: mediatek: mt7988: add i2c to bpi-r4
 board
In-Reply-To: <f47f08c0-0fb4-4826-9b25-1277cabe4bb6@collabora.com>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-14-linux@fw-web.de>
 <1ad355df-3f2a-4257-9374-1d125e138791@collabora.com>
 <CA7E06EB-D26A-45D0-BF13-9C6B640F27A0@public-files.de>
 <f47f08c0-0fb4-4826-9b25-1277cabe4bb6@collabora.com>
Message-ID: <b12e215af5aa5b6bb2fadbeda1117c94@fw-web.de>

Am 2024-12-03 15:22, schrieb AngeloGioacchino Del Regno:
> Il 03/12/24 11:58, Frank Wunderlich ha scritto:
>> Am 3. Dezember 2024 10:40:38 MEZ schrieb AngeloGioacchino Del Regno 
>> <angelogioacchino.delregno at collabora.com>:
>>> Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>>>> From: Frank Wunderlich <frank-w at public-files.de>
>>>> 
>>>> Add basic i2c nodes to bananapi R4 board.
>>>> 
>>>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>>> 
>>> arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C controllers
>>> 
>>> Enable the I2C0, I2C2 controllers found on the BananaPi R4 board; 
>>> these
>>> controllers are accessible at ... I don't know, a header on the 
>>> board?
>> 
>> These 2 i2c have directly connected spare devices (pmic on i2c0 and 
>> i2c-mux on i2c2 added in later commits to have it a bit cleaner). I2c1 
>> is on gpio header which i have not added to let user choose if he 
>> wants i2c option or gpio. I can also add i2c1 to r4 board with the 
>> right pinctrl but imho it should be disabled to have gpio function 
>> default.
> 
> And again, you should really add all that information to the commit 
> description,
> as that not only helps me to review your submission, but also helps 
> other people
> checking the commit history....!

this ine i would rephrase like this

     arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C controllers

     Enable the I2C0, I2C2 controllers found on the BananaPi R4 board.
     Both controllers are not accessible from user and having fixed spare
     devices. I2C0 have a pmic connected, I2C2 is used with 
I2C-multiplexer
     for e.g. SFP cages.
     The missing I2C1 is connected to GPIO header which can have either 
GPIO
     mode or I2C mode.


> Cheers
> 
>> 
>>> After which,
>>> 
>>> Reviewed-by: AngeloGioacchino Del Regno 
>>> <angelogioacchino.delregno at collabora.com>
>>> 
>>> 
>> 
>> 
>> regards Frank


From eballetb at redhat.com  Tue Dec  3 07:29:02 2024
From: eballetb at redhat.com (Enric Balletbo i Serra)
Date: Tue, 3 Dec 2024 16:29:02 +0100
Subject: [PATCH] arm64: dts: ti: k3-am69-sk: Add USB SuperSpeed support
In-Reply-To: <wbsg3fmco6rwjj7vtiqtqv7trfjor73j7rjx7efnlafo4pz4bc@awixm2iygd55>
References: <20241126-am69sk-dt-usb-v1-1-aa55aed7b89e@redhat.com>
 <2nuncc5rscu6h74ylaiu6yozg34aoigaj5d4uzvdtolt5q7bmv@6hacpxyb2532>
 <CALE0LRtUN2N_Z05jH_BMSg7yvirSRob0pSErmQxTu8AatmODgw@mail.gmail.com>
 <CALE0LRu-Sx5oTVNY3hm+Msu-zb04a7_ZD+r3xF1eRfR_WtK0VA@mail.gmail.com> <wbsg3fmco6rwjj7vtiqtqv7trfjor73j7rjx7efnlafo4pz4bc@awixm2iygd55>
Message-ID: <CALE0LRvZNnNJ8jBG35bU8Ev5Fvr2400O5qXUsRn0zufkidJeJw@mail.gmail.com>

Hi,

On Thu, Nov 28, 2024 at 10:58?AM s-vadapalli <s-vadapalli at ti.com> wrote:
>
> On Thu, Nov 28, 2024 at 10:47:42AM +0100, Enric Balletbo i Serra wrote:
> > Hi,
>
> [...]
>
> > So I changed the dr_mode to otg instead of host and tried to configure
> > a usb mass storage gadget but unfortunately didn't work, but this
> > could be a driver problem, I got the following error
> >
> >   UDC core: g1: couldn't find an available UDC
> >
> > As the devicetree should describe the hardware, and as far as I can
> > see it should support the type-c port act as a gadget, I'm fine with
> > changing the dr_mode, unless anyone have more information about this,
> > the thing that makes me think a bit more is that, in the TI kernel
> > this is set to host, so I'm wondering if I'm missing something or is
> > just that was never tested.
>
> Are all interfaces (Type-A and Type-C) functional as Host when the
> dr_mode is set to "otg"? (Do USB devices connected to the interfaces
> enumerate on AM69-SK?) If yes, then it could be a DIP Switch setting
> that is related to OTG mode of operation or a USB-C Mux that needs to be
> configured.
>

Yes, all interfaces (Type-A and Type-C) are functional as host when
the dr_mode is set to "otg". Looking at SK-AM69 Processor Start Kit
User's Guide (Rev. A) [1] I don't see any DIP Switch related to the
OTG  mode. Looks like the type-c connector connects directly to the
SoC through a USB HUB (TUSB4041).

[1] https://www.ti.com/lit/ug/spruj70a/spruj70a.pdf?ts=1733215039014

Regards,
  Enric

> Regards,
> Siddharth.
>



From YeoReum.Yun at arm.com  Tue Dec  3 07:30:43 2024
From: YeoReum.Yun at arm.com (Yeo Reum Yun)
Date: Tue, 3 Dec 2024 15:30:43 +0000
Subject: [PATCH 1/9] coresight: change coresight_device lock type to
 raw_spinlock_t
In-Reply-To: <20241203102047.5844de81@gandalf.local.home>
References: <20241125094816.365472-1-yeoreum.yun@arm.com>
	<20241125094816.365472-2-yeoreum.yun@arm.com>
	<20241127120954.0facd34f@gandalf.local.home>
	<GV1PR08MB10521520ABD7B72D92FD60DE9FB292@GV1PR08MB10521.eurprd08.prod.outlook.com>
	<20241202103853.26db0c13@gandalf.local.home>
	<GV1PR08MB105212FEF9251CA2B3AAF7FFFFB362@GV1PR08MB10521.eurprd08.prod.outlook.com>
 <20241203102047.5844de81@gandalf.local.home>
Message-ID: <GV1PR08MB105213222FB18FF328443148BFB362@GV1PR08MB10521.eurprd08.prod.outlook.com>

 Hi Steve,

> > > Still should be documented somewhere. It should describe the maximum number
> > > of feats that will ever be loaded. If there's a max, it makes it back to
> > > O(1). With a 'k' of how long it takes to process the max number of feats.
> >
> > But with other patchset seems better
> > since not only this function, but also for other functions too.

> Which other patchset?

I mean I'll send with seperate patchset to documents this.
Because I'm not sure documents here or in other file...

>
> BTW, is there any example describing this I can refer?

> No, it's on our todo list for RT. To document the RT behavior of the
> kernel. This is just one location.

Thanks to let me know :)


From Dave.Martin at arm.com  Tue Dec  3 07:32:22 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 3 Dec 2024 15:32:22 +0000
Subject: [PATCH 1/6] arm64/sme: Flush foreign register state in
 do_sme_acc()
In-Reply-To: <20241203-arm64-sme-reenable-v1-1-d853479d1b77@kernel.org>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-1-d853479d1b77@kernel.org>
Message-ID: <Z08khk6Mg6+T6VV9@e133380.arm.com>

On Tue, Dec 03, 2024 at 12:45:53PM +0000, Mark Brown wrote:
> When do_sme_acc() runs with foreign FP state it does not do any updates of
> the task structure, relying on the next return to userspace to reload the
> register state appropriately, but leaves the task's last loaded CPU
> untouched. This means that if the task returns to userspace on the last
> CPU it ran on then the checks in fpsimd_bind_task_to_cpu() will incorrectly
> determine that the register state on the CPU is current and suppress reload
> of the floating point register state before returning to userspace. This
> will result in spurious warnings due to SME access traps occuring for the
> task after TIF_SME is set.
> 
> Call fpsimd_flush_task_state() to invalidate the last loaded CPU
> recorded in the task, forcing detection of the task as foreign.
> 
> Fixes: 8bd7f91c03d8 ("arm64/sme: Implement traps and syscall handling for SME")
> Reported-by: Mark Rutlamd <mark.rutland at arm.com>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> Cc: stable at vger.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 8c4c1a2186cc510a7826d15ec36225857c07ed71..eca0b6a2fc6fa25d8c850a5b9e109b4d58809f54 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -1460,6 +1460,8 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
>  		sme_set_vq(vq_minus_one);
>  
>  		fpsimd_bind_task_to_cpu();
> +	} else {
> +		fpsimd_flush_task_state(current);

TIF_FOREIGN_FPSTATE is (or was) a cache of the task<->CPU binding that
you're clobbering here.

So, this fpsimd_flush_task_state() should have no effect unless
TIF_FOREIGN_FPSTATE is already wrong?  I'm wondering if the apparent
need for this means that there is an undiagnosed bug elsewhere.

(My understanding is based on FPSIMD/SVE; I'm less familiar with the
SME changes, so I may be missing something important here.)

[...]

Cheers
---Dave


From Dave.Martin at arm.com  Tue Dec  3 07:33:18 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 3 Dec 2024 15:33:18 +0000
Subject: [PATCH 5/6] arm64/signal: Avoid corruption of SME state when
 entering signal handler
In-Reply-To: <20241203-arm64-sme-reenable-v1-5-d853479d1b77@kernel.org>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-5-d853479d1b77@kernel.org>
Message-ID: <Z08kvi0znVM2RHx4@e133380.arm.com>

On Tue, Dec 03, 2024 at 12:45:57PM +0000, Mark Brown wrote:
> We intend that signal handlers are entered with PSTATE.{SM,ZA}={0,0}.
> The logic for this in setup_return() manipulates the saved state and
> live CPU state in an unsafe manner, and consequently, when a task enters
> a signal handler:
> 
>  * The task entering the signal handler might not have its PSTATE.{SM,ZA}
>    bits cleared, and other register state that is affected by changes to
>    PSTATE.{SM,ZA} might not be zeroed as expected.
> 
>  * An unrelated task might have its PSTATE.{SM,ZA} bits cleared
>    unexpectedly, potentially zeroing other register state that is
>    affected by changes to PSTATE.{SM,ZA}.
> 
>    Tasks which do not set PSTATE.{SM,ZA} (i.e. those only using plain
>    FPSIMD or non-streaming SVE) are not affected, as there is no
>    resulting change to PSTATE.{SM,ZA}.
> 
> Consider for example two tasks on one CPU:
> 
>  A: Begins signal entry in kernel mode, is preempted prior to SMSTOP.
>  B: Using SM and/or ZA in userspace with register state current on the
>     CPU, is preempted.
>  A: Scheduled in, no register state changes made as in kernel mode.
>  A: Executes SMSTOP, modifying live register state.
>  A: Scheduled out.
>  B: Scheduled in, fpsimd_thread_switch() sees the register state on the
>     CPU is tracked as being that for task B so the state is not reloaded
>     prior to returning to userspace.
> 
> Task B is now running with SM and ZA incorrectly cleared.
> 
> Fix this by:
> 
>  * Checking TIF_FOREIGN_FPSTATE, and only updating the saved or live
>    state as appropriate.
> 
>  * Using {get,put}_cpu_fpsimd_context() to ensure mutual exclusion
>    against other code which manipulates this state. To allow their use,
>    the logic is moved into a new fpsimd_enter_sighandler() helper in
>    fpsimd.c.
> 
> This race has been observed intermittently with fp-stress, especially
> with preempt disabled, commonly but not exclusively reporting "Bad SVCR: 0".
> 
> While we're at it also fix a discrepancy between in register and in memory
> entries. When operating on the register state we issue a SMSTOP, exiting
> streaming mode if we were in it. This clears the V/Z and P register and
> FPMR but nothing else. The in memory version clears all the user FPSIMD
> state including FPCR and FPSR but does not clear FPMR. Add the clear of
> FPMR and limit the existing memset() to only cover the vregs, preserving
> the state of FPCR and FPSR like SMSTOP does.
> 
> Fixes: 40a8e87bb3285 ("arm64/sme: Disable ZA and streaming mode when handling signals")
> Signed-off-by: Mark Brown <broonie at kernel.org>
> Cc: stable at vger.kernel.org
> ---
>  arch/arm64/include/asm/fpsimd.h |  1 +
>  arch/arm64/kernel/fpsimd.c      | 39 +++++++++++++++++++++++++++++++++++++++
>  arch/arm64/kernel/signal.c      | 19 +------------------
>  3 files changed, 41 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index f2a84efc361858d4deda99faf1967cc7cac386c1..09af7cfd9f6c2cec26332caa4c254976e117b1bf 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -76,6 +76,7 @@ extern void fpsimd_load_state(struct user_fpsimd_state *state);
>  extern void fpsimd_thread_switch(struct task_struct *next);
>  extern void fpsimd_flush_thread(void);
>  
> +extern void fpsimd_enter_sighandler(void);
>  extern void fpsimd_signal_preserve_current_state(void);
>  extern void fpsimd_preserve_current_state(void);
>  extern void fpsimd_restore_current_state(void);
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index f02762762dbcf954e9add6dfd3575ae7055b6b0e..c5465c8ec467cb1ab8bd211dc5370f91aa2bcf35 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -1696,6 +1696,45 @@ void fpsimd_signal_preserve_current_state(void)
>  		sve_to_fpsimd(current);
>  }
>  
> +/*
> + * Called by the signal handling code when preparing current to enter
> + * a signal handler. Currently this only needs to take care of exiting
> + * streaming mode and clearing ZA on SME systems.
> + */
> +void fpsimd_enter_sighandler(void)
> +{
> +	if (!system_supports_sme())
> +		return;
> +
> +	get_cpu_fpsimd_context();
> +
> +	if (test_thread_flag(TIF_FOREIGN_FPSTATE)) {
> +		/*
> +		 * Exiting streaming mode zeros the V/Z and P
> +		 * registers and FPMR.  Zero FPMR and the V registers,
> +		 * marking the state as FPSIMD only to force a clear
> +		 * of the remaining bits during reload if needed.
> +		 */
> +		if (current->thread.svcr & SVCR_SM_MASK) {
> +			memset(&current->thread.uw.fpsimd_state.vregs, 0,
> +			       sizeof(current->thread.uw.fpsimd_state.vregs));

Do we need to hold the CPU fpsimd context across this memset?

IIRC, TIF_FOREIGN_FPSTATE can be spontaneously cleared along with
dumping of the regs into thread_struct (from current's PoV), but never
spontaneously set again.  So ... -> [*]

> +			current->thread.uw.fpmr = 0;
> +			current->thread.fp_type = FP_STATE_FPSIMD;
> +		}
> +
> +		current->thread.svcr &= ~(SVCR_ZA_MASK |
> +					  SVCR_SM_MASK);
> +
> +		/* Ensure any copies on other CPUs aren't reused */
> +		fpsimd_flush_task_state(current);

(This is very similar to fpsimd_flush_thread(); can they be unified?)

> +	} else {
> +		/* The register state is current, just update it. */
> +		sme_smstop();

... [*] the critical thing seems to be that the CPU fpsimd context is
held from the test on TIF_FOREIGN_FPSTATE, across this else clause.

(Whether or not this is a worthwhile optimisation is another matter.
But if the behaviour of TIF_FOREIGN_FPSTATE is still the same, then it
may be a good idea to avoid sending mixed messages about this in the
code.)

(A similar argument applies in fpsimd_flush_thread().)

[...]

Cheers
---Dave


From Dave.Martin at arm.com  Tue Dec  3 07:34:01 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 3 Dec 2024 15:34:01 +0000
Subject: [PATCH 4/6] arm64/signal: Consistently invalidate the in
 register FP state in restore
In-Reply-To: <20241203-arm64-sme-reenable-v1-4-d853479d1b77@kernel.org>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-4-d853479d1b77@kernel.org>
Message-ID: <Z08k6QsYRzO8+O4t@e133380.arm.com>

On Tue, Dec 03, 2024 at 12:45:56PM +0000, Mark Brown wrote:
> When restoring the SVE and SME specific floating point register states we
> flush the task floating point state, marking the hardware state as stale so
> that preemption does not result in us saving register state from the signal
> handler on top of the restored context and forcing a reload from memory.
> For the plain FPSIMD state we don't do this, we just copy the state from
> userspace and then force an immediate reload of the register state.
> This isn't racy against context switch since we copy the incoming data
> onto the stack rather than directly into the task struct but it's still
> messy and inconsistent.
> 
> Simplify things and avoid a potential source of error by moving the
> invalidation of the CPU state to the main restore_sigframe() and
> reworking the restore of the FPSIMD state to update the task struct and
> rely on loading as part of the general do_notify_resume() handling for
> return to user like we do for the SVE and SME state.
> 
> As a result of this the only user of fpsimd_update_current_state() is
> the 32 bit signal code which should not have any SVE state, add an
> assert there that we don't have SVE enabled.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/kernel/fpsimd.c |  2 +-
>  arch/arm64/kernel/signal.c | 70 +++++++++++++++-------------------------------
>  2 files changed, 23 insertions(+), 49 deletions(-)
> 
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index a3bb17c88942eba031d26e9f75ad46f37b6dc621..f02762762dbcf954e9add6dfd3575ae7055b6b0e 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -1828,7 +1828,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state)
>  	get_cpu_fpsimd_context();
>  
>  	current->thread.uw.fpsimd_state = *state;
> -	if (test_thread_flag(TIF_SVE))

Add a comment here?

(I guess people can dig for the commit message, but it's easy to miss
the original intent of WARNs when editing code.)

> +	if (WARN_ON_ONCE(test_thread_flag(TIF_SVE)))
>  		fpsimd_to_sve(current);
>  
>  	task_fpsimd_load();
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 14ac6fdb872b9672e4b16a097f1b577aae8dec50..abd0907061fe664bf22d1995319f9559c4bbed91 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -271,7 +271,7 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
>  
>  static int restore_fpsimd_context(struct user_ctxs *user)
>  {
> -	struct user_fpsimd_state fpsimd;
> +	struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
>  	int err = 0;
>  
>  	/* check the size information */
> @@ -279,18 +279,14 @@ static int restore_fpsimd_context(struct user_ctxs *user)
>  		return -EINVAL;
>  
>  	/* copy the FP and status/control registers */
> -	err = __copy_from_user(fpsimd.vregs, &(user->fpsimd->vregs),
> -			       sizeof(fpsimd.vregs));
> -	__get_user_error(fpsimd.fpsr, &(user->fpsimd->fpsr), err);
> -	__get_user_error(fpsimd.fpcr, &(user->fpsimd->fpcr), err);
> +	err = __copy_from_user(fpsimd->vregs, &(user->fpsimd->vregs),
> +			       sizeof(fpsimd->vregs));
> +	__get_user_error(fpsimd->fpsr, &(user->fpsimd->fpsr), err);
> +	__get_user_error(fpsimd->fpcr, &(user->fpsimd->fpcr), err);

It does kinda make sense to align this with the way SVE/SME are handled.

I just left this as-is when developing the SVE support, because it
wasn't feasible to stage the SVE state via the stack, and I didn't want
to break the world by messing with the FPSIMD-only code paths any more
than I had to.

But you're right that we don't really gain anything any more by doing
things a special way for the plain FPSIMD case...

Doing everything the same way should help maintainability.

>  
>  	clear_thread_flag(TIF_SVE);
>  	current->thread.fp_type = FP_STATE_FPSIMD;
>  
> -	/* load the hardware registers from the fpsimd_state structure */
> -	if (!err)
> -		fpsimd_update_current_state(&fpsimd);
> -
>  	return err ? -EFAULT : 0;
>  }
>  
> @@ -396,7 +392,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
>  {
>  	int err = 0;
>  	unsigned int vl, vq;
> -	struct user_fpsimd_state fpsimd;
> +	struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
>  	u16 user_vl, flags;
>  
>  	if (user->sve_size < sizeof(*user->sve))
> @@ -439,16 +435,6 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
>  	if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq))
>  		return -EINVAL;
>  
> -	/*
> -	 * Careful: we are about __copy_from_user() directly into
> -	 * thread.sve_state with preemption enabled, so protection is
> -	 * needed to prevent a racing context switch from writing stale
> -	 * registers back over the new data.
> -	 */
> -
> -	fpsimd_flush_task_state(current);
> -	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
> -
>  	sve_alloc(current, true);
>  	if (!current->thread.sve_state) {
>  		clear_thread_flag(TIF_SVE);
> @@ -471,14 +457,10 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
>  fpsimd_only:
>  	/* copy the FP and status/control registers */
>  	/* restore_sigframe() already checked that user->fpsimd != NULL. */
> -	err = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs,
> -			       sizeof(fpsimd.vregs));
> -	__get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err);
> -	__get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err);
> -
> -	/* load the hardware registers from the fpsimd_state structure */
> -	if (!err)
> -		fpsimd_update_current_state(&fpsimd);
> +	err = __copy_from_user(fpsimd->vregs, user->fpsimd->vregs,
> +			       sizeof(fpsimd->vregs));
> +	__get_user_error(fpsimd->fpsr, &user->fpsimd->fpsr, err);
> +	__get_user_error(fpsimd->fpcr, &user->fpsimd->fpcr, err);
>  
>  	return err ? -EFAULT : 0;
>  }
> @@ -587,16 +569,6 @@ static int restore_za_context(struct user_ctxs *user)
>  	if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq))
>  		return -EINVAL;
>  
> -	/*
> -	 * Careful: we are about __copy_from_user() directly into
> -	 * thread.sme_state with preemption enabled, so protection is
> -	 * needed to prevent a racing context switch from writing stale
> -	 * registers back over the new data.
> -	 */
> -
> -	fpsimd_flush_task_state(current);
> -	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
> -
>  	sme_alloc(current, true);
>  	if (!current->thread.sme_state) {
>  		current->thread.svcr &= ~SVCR_ZA_MASK;
> @@ -664,16 +636,6 @@ static int restore_zt_context(struct user_ctxs *user)
>  	if (nregs != 1)
>  		return -EINVAL;
>  
> -	/*
> -	 * Careful: we are about __copy_from_user() directly into
> -	 * thread.zt_state with preemption enabled, so protection is
> -	 * needed to prevent a racing context switch from writing stale
> -	 * registers back over the new data.
> -	 */
> -
> -	fpsimd_flush_task_state(current);
> -	/* From now, fpsimd_thread_switch() won't touch ZT in thread state */
> -
>  	err = __copy_from_user(thread_zt_state(&current->thread),
>  			       (char __user const *)user->zt +
>  					ZT_SIG_REGS_OFFSET,
> @@ -1028,6 +990,18 @@ static int restore_sigframe(struct pt_regs *regs,
>  	if (err == 0)
>  		err = parse_user_sigframe(&user, sf);
>  
> +	/*
> +	 * Careful: we are about __copy_from_user() directly into

Nit: we are about _to_ __copy_from_user()...

(Looks like this was my typo in the original ancestor of this comment
block!  Might as well fix it now, since the comments are being unified
here.)

> +	 * thread floating point state with preemption enabled, so
> +	 * protection is needed to prevent a racing context switch
> +	 * from writing stale registers back over the new data. Mark
> +	 * the register floating point state as invalid and unbind the
> +	 * task from the CPU to force a reload before we return to
> +	 * userspace. fpsimd_flush_task_state() has a check for FP
> +	 * support.
> +	 */

Maybe add a comment in fpsimd_flush_task_state() about why the
system_supports_fpsimd() check is important?  It's not obvious there
why we should ever be calling that function on non-FPSIMD systems.

> +	fpsimd_flush_task_state(current);
> +

This seems a definite improvement.  We know we're about to load
something over the task's FPSIMD / vector state, even if we don't know
exactly what.

But would it be a good idea to stick a
WARN_ON(!test_thread_flag(TIF_FOREIGN_FPSTATE)) at the start of the
functions that rely on this?

This code isn't super hot-path.

[...]

Cheers
---Dave


From wens at csie.org  Tue Dec  3 07:34:23 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 3 Dec 2024 23:34:23 +0800
Subject: [PATCH 2/2] arm64: dts: allwinner: a100: Add syscon nodes
In-Reply-To: <20241202-a100-syscon-v1-2-86c6524f24d7@epochal.quest>
References: <20241202-a100-syscon-v1-0-86c6524f24d7@epochal.quest> <20241202-a100-syscon-v1-2-86c6524f24d7@epochal.quest>
Message-ID: <CAGb2v66RAyKrpn7EJMoPUzM6W6J-3ch0xwQnY7uBm6dXgFJ5bg@mail.gmail.com>

On Mon, Dec 2, 2024 at 12:43?PM Cody Eksal <masterr3c0rd at epochal.quest> wrote:
>
> The Allwinner A100 has a system configuration block, denoted as SYS_CFG
> in the user manual's memory map. It is undocumented in the manual, but
> a glance at the vendor tree shows this block is similar to its
> predecessors in the A64 and H6. The A100 also has 3 SRAM blocks: A1, A2,
> and C. Add all of these to the SoC's device tree.
>
> Signed-off-by: Cody Eksal <masterr3c0rd at epochal.quest>
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 31 ++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
> index 29ac7716c7a5284ccf8af675db9c7d016785f0ff..31540a7ca1f01c6c2e69e329054aca16ffd112c4 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
> @@ -101,6 +101,37 @@ soc {
>                 #size-cells = <1>;
>                 ranges = <0 0 0 0x3fffffff>;
>
> +               syscon: syscon at 3000000 {
> +                       compatible = "allwinner,sun50i-a100-system-control",
> +                                    "allwinner,sun50i-a64-system-control";
> +                       reg = <0x03000000 0x1000>;
> +                       #address-cells = <1>;
> +                       #size-cells = <1>;
> +                       ranges;
> +
> +                       sram_a1: sram at 20000 {
> +                               compatible = "mmio-sram";
> +                               reg = <0x00020000 0x4000>;
> +                               #address-cells = <1>;
> +                               #size-cells = <1>;
> +                               ranges = <0 0x00020000 0x4000>;
> +                       };

Each child node should have an empty line preceding it, as mentioned
in the dts coding style doc:

    Documentation/devicetree/bindings/dts-coding-style.rst

ChenYu

> +                       sram_c: sram at 24000 {
> +                               compatible = "mmio-sram";
> +                               reg = <0x024000 0x21000>;
> +                               #address-cells = <1>;
> +                               #size-cells = <1>;
> +                               ranges = <0 0x024000 0x21000>;
> +                       };
> +                       sram_a2: sram at 100000 {
> +                               compatible = "mmio-sram";
> +                               reg = <0x0100000 0x14000>;
> +                               #address-cells = <1>;
> +                               #size-cells = <1>;
> +                               ranges = <0 0x0100000 0x14000>;
> +                       };
> +               };
> +
>                 ccu: clock at 3001000 {
>                         compatible = "allwinner,sun50i-a100-ccu";
>                         reg = <0x03001000 0x1000>;
>
> --
> 2.47.1
>


From wens at csie.org  Tue Dec  3 07:36:35 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 3 Dec 2024 23:36:35 +0800
Subject: [PATCH] PM / devfreq: sun8i-a33-mbus: Simplify by using more devm functions
In-Reply-To: <20241111112237.336310-2-u.kleine-koenig@baylibre.com>
References: <20241111112237.336310-2-u.kleine-koenig@baylibre.com>
Message-ID: <CAGb2v65i=Ttij+pnK9nhdPzsk9kTdP0ZXS1MGboAud+QudbEDA@mail.gmail.com>

On Mon, Nov 11, 2024 at 7:22?PM Uwe Kleine-K?nig
<u.kleine-koenig at baylibre.com> wrote:
>
> Use devm allocators for enabling the bus clock and
> clk_rate_exclusive_get(). This simplifies error handling and the remove
> callback.
>
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>

Reviewed-by: Chen-Yu Tsai <wens at csie.org>

> ---
>  drivers/devfreq/sun8i-a33-mbus.c | 38 ++++++++------------------------
>  1 file changed, 9 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/devfreq/sun8i-a33-mbus.c b/drivers/devfreq/sun8i-a33-mbus.c
> index bcf654f4ff96..5b630c6e602e 100644
> --- a/drivers/devfreq/sun8i-a33-mbus.c
> +++ b/drivers/devfreq/sun8i-a33-mbus.c
> @@ -360,7 +360,7 @@ static int sun8i_a33_mbus_probe(struct platform_device *pdev)
>         if (IS_ERR(priv->reg_mbus))
>                 return PTR_ERR(priv->reg_mbus);
>
> -       priv->clk_bus = devm_clk_get(dev, "bus");
> +       priv->clk_bus = devm_clk_get_enabled(dev, "bus");
>         if (IS_ERR(priv->clk_bus))
>                 return dev_err_probe(dev, PTR_ERR(priv->clk_bus),
>                                      "failed to get bus clock\n");
> @@ -375,24 +375,15 @@ static int sun8i_a33_mbus_probe(struct platform_device *pdev)
>                 return dev_err_probe(dev, PTR_ERR(priv->clk_mbus),
>                                      "failed to get mbus clock\n");
>
> -       ret = clk_prepare_enable(priv->clk_bus);
> -       if (ret)
> -               return dev_err_probe(dev, ret,
> -                                    "failed to enable bus clock\n");
> -
>         /* Lock the DRAM clock rate to keep priv->nominal_bw in sync. */
> -       ret = clk_rate_exclusive_get(priv->clk_dram);
> -       if (ret) {
> -               err = "failed to lock dram clock rate\n";
> -               goto err_disable_bus;
> -       }
> +       ret = devm_clk_rate_exclusive_get(dev, priv->clk_dram);
> +       if (ret)
> +               return dev_err_probe(dev, ret, "failed to lock dram clock rate\n");
>
>         /* Lock the MBUS clock rate to keep MBUS_TMR_PERIOD in sync. */
> -       ret = clk_rate_exclusive_get(priv->clk_mbus);
> -       if (ret) {
> -               err = "failed to lock mbus clock rate\n";
> -               goto err_unlock_dram;
> -       }
> +       ret = devm_clk_rate_exclusive_get(priv->clk_mbus);
> +       if (ret)
> +               return dev_err_probe(dev, ret, "failed to lock mbus clock rate\n");
>
>         priv->gov_data.upthreshold      = 10;
>         priv->gov_data.downdifferential =  5;
> @@ -405,10 +396,8 @@ static int sun8i_a33_mbus_probe(struct platform_device *pdev)
>         priv->profile.max_state         = max_state;
>
>         ret = devm_pm_opp_set_clkname(dev, "dram");
> -       if (ret) {
> -               err = "failed to add OPP table\n";
> -               goto err_unlock_mbus;
> -       }
> +       if (ret)
> +               return dev_err_probe(dev, ret, "failed to add OPP table\n");
>
>         base_freq = clk_get_rate(clk_get_parent(priv->clk_dram));
>         for (i = 0; i < max_state; ++i) {
> @@ -448,12 +437,6 @@ static int sun8i_a33_mbus_probe(struct platform_device *pdev)
>
>  err_remove_opps:
>         dev_pm_opp_remove_all_dynamic(dev);
> -err_unlock_mbus:
> -       clk_rate_exclusive_put(priv->clk_mbus);
> -err_unlock_dram:
> -       clk_rate_exclusive_put(priv->clk_dram);
> -err_disable_bus:
> -       clk_disable_unprepare(priv->clk_bus);
>
>         return dev_err_probe(dev, ret, err);
>  }
> @@ -472,9 +455,6 @@ static void sun8i_a33_mbus_remove(struct platform_device *pdev)
>                 dev_warn(dev, "failed to restore DRAM frequency: %d\n", ret);
>
>         dev_pm_opp_remove_all_dynamic(dev);
> -       clk_rate_exclusive_put(priv->clk_mbus);
> -       clk_rate_exclusive_put(priv->clk_dram);
> -       clk_disable_unprepare(priv->clk_bus);
>  }
>
>  static const struct sun8i_a33_mbus_variant sun50i_a64_mbus = {
>
> base-commit: 6d59cab07b8d74d0f0422b750038123334f6ecc2
> --
> 2.45.2
>
>


From krishna.kurapati at oss.qualcomm.com  Tue Dec  3 07:37:22 2024
From: krishna.kurapati at oss.qualcomm.com (Krishna Kurapati)
Date: Tue, 3 Dec 2024 21:07:22 +0530
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint readery
In-Reply-To: <Z07r3Upr50vLluyn@linaro.org>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com> <Z07r3Upr50vLluyn@linaro.org>
Message-ID: <41106fd7-5348-4d21-9ae7-8466f5634b4c@oss.qualcomm.com>



On 12/3/2024 5:00 PM, Stephan Gerhold wrote:
> On Tue, Dec 03, 2024 at 11:20:48AM +0100, Johan Hovold wrote:
>> [ +CC: Krishna, Thinh and the USB list ]
>>
>> On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
>>> The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
>>> multiport controller on eUSB6. All other ports (including USB super-speed
>>> pins) are unused.
>>>
>>> Set it up in the device tree together with the NXP PTN3222 repeater.
>>>
>>> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
>>> ---
>>>   arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 48 +++++++++++++++++++++++++++++++
>>>   1 file changed, 48 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>>> index 39f9d9cdc10d..44942931c18f 100644
>>> --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>>> +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>>> @@ -735,6 +735,26 @@ keyboard at 3a {
>>>   	};
>>>   };
>>>   
>>> +&i2c5 {
>>> +	clock-frequency = <400000>;
>>> +
>>> +	status = "okay";
>>> +
>>> +	eusb6_repeater: redriver at 4f {
>>> +		compatible = "nxp,ptn3222";
>>> +		reg = <0x4f>;
>>
>> The driver does not currently check that there's actually anything at
>> this address. Did you verify that this is the correct address?
>>
>> (Abel is adding a check to the driver as we speak to catch any such
>> mistakes going forward).
>>
> 
> Yes, I verified this using
> https://git.codelinaro.org/stephan.gerhold/linux/-/commit/45d5add498612387f88270ca944ee16e2236fddd
> 
> (I sent this to Abel back then, so I'm surprised he didn't run that :-))
> 
>>> +		#phy-cells = <0>;
>>
>> nit: I'd put provider properties like this one last.
>>
>>> +		vdd3v3-supply = <&vreg_l13b_3p0>;
>>> +		vdd1v8-supply = <&vreg_l4b_1p8>;
>>
>> Sort by supply name?
>>
> 
> Ack.
> 
>>> +		reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>;
>>> +
>>> +		pinctrl-0 = <&eusb6_reset_n>;
>>> +		pinctrl-names = "default";
>>> +	};
>>> +};
>>> +
>>>   &i2c8 {
>>>   	clock-frequency = <400000>;
>>>   
>>> @@ -1047,6 +1067,14 @@ edp_reg_en: edp-reg-en-state {
>>>   		bias-disable;
>>>   	};
>>>   
>>> +	eusb6_reset_n: eusb6-reset-n-state {
>>> +		pins = "gpio184";
>>> +		function = "gpio";
>>> +		drive-strength = <2>;
>>> +		bias-disable;
>>> +		output-low;
>>
>> I don't think the pin config should assert reset, that should be up to
>> the driver to control.
>>
> 
> I can drop it I guess, but pinctrl is applied before the driver takes
> control of the GPIO. This means if the GPIO happens to be in input mode
> before the driver loads (with pull up or pull down), then we would
> briefly leave it floating when applying the bias-disable.
> 
> Or I guess we could drop the bias-disable, since it shouldn't be
> relevant for a pin we keep in output mode all the time?
> 
>>> +	};
>>> +
>>>   	hall_int_n_default: hall-int-n-state {
>>>   		pins = "gpio92";
>>>   		function = "gpio";
>>> @@ -1260,3 +1288,23 @@ &usb_1_ss2_dwc3_hs {
>>>   &usb_1_ss2_qmpphy_out {
>>>   	remote-endpoint = <&pmic_glink_ss2_ss_in>;
>>>   };
>>> +
>>> +&usb_mp {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&usb_mp_dwc3 {
>>> +	/* Limit to USB 2.0 and single port */
>>> +	maximum-speed = "high-speed";
>>> +	phys = <&usb_mp_hsphy1>;
>>> +	phy-names = "usb2-1";
>>> +};
>>
>> The dwc3 driver determines (and acts on) the number of ports based on
>> the port interrupts in DT and controller capabilities.
>>
>> I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
>> that would still be there in the SoC (possibly initialised by the boot
>> firmware).
>>
>> I had a local patch to enable the multiport controller (for the suspend
>> work) and I realise that you'd currently need to specify a repeater also
>> for the HS PHY which does not have one, but that should be possible to
>> fix somehow.
>>
> 
> I think there are two separate questions here:
> 
>   1. Should we (or do we even need to) enable unused PHYs?
>   2. Do we need to power off unused PHYs left enabled by the firmware?
> 
> For (1), I'm not not sure if there is a technical reason that requires
> us to. And given that PHYs typically consume quite a bit of power, I'm
> not sure if we should. Perhaps it's not worth spending effort on this
> minor optimization now, but then the device tree would ideally still
> tell us which PHYs are actually used (for future optimizations).
> 
> For (2), yes, we probably need to. But my impression so far is that this
> might be a larger problem that we need to handle on the SoC level. I
> have seen some firmware versions that blindly power up all USB
> controllers, even completely unused ones. Ideally we would power down
> unused components during startup and then leave them off.
>

This question might be a dumb one, if so please ignore it.

But if we skip adding unused phys in DTS node, the core driver wouldn't 
have access to all phys and we wouldn't be able to get references to 
unused ones (un-mentioned ones in DTS). So how can we power them off 
from core driver if we don't have reference to them ?

Regards,
Krishna,


From jeremy.linton at arm.com  Tue Dec  3 07:30:43 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Tue, 3 Dec 2024 09:30:43 -0600
Subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module
 loading
In-Reply-To: <b1923d68-726a-4864-8661-54588a634d95@redhat.com>
References: <20241203000156.72451-2-jeremy.linton@arm.com>
 <202412031348.bp5i3ws2-lkp@intel.com>
 <b1923d68-726a-4864-8661-54588a634d95@redhat.com>
Message-ID: <a64a21cc-6d10-4e8f-9ab9-87aca44ca858@arm.com>

On 12/3/24 2:56 AM, Gavin Shan wrote:
> 
> 
> On 12/3/24 4:03 PM, kernel test robot wrote:
>> Hi Jeremy,
>>
>> kernel test robot noticed the following build warnings:
>>
>> [auto build test WARNING on arm64/for-next/core]
>> [also build test WARNING on linus/master v6.13-rc1 next-20241128]
>> [cannot apply to kvmarm/next soc/for-next arm/for-next arm/fixes]
>> [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/Jeremy-Linton/ 
>> arm64-rsi-Add-automatic-arm-cca-guest-module-loading/20241203-080347
>> base:?? https://git.kernel.org/pub/scm/linux/kernel/git/arm64/ 
>> linux.git for-next/core
>> patch link:??? https://lore.kernel.org/r/20241203000156.72451-2- 
>> jeremy.linton%40arm.com
>> patch subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest 
>> module loading
>> config: arm64-randconfig-004-20241203 (https://download.01.org/0day- 
>> ci/archive/20241203/202412031348.bp5i3ws2-lkp at intel.com/config)
>> compiler: clang version 20.0.0git (https://github.com/llvm/llvm- 
>> project 592c0fe55f6d9a811028b5f3507be91458ab2713)
>> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/ 
>> archive/20241203/202412031348.bp5i3ws2-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/202412031348.bp5i3ws2- 
>> lkp at intel.com/
>>
>> All warnings (new ones prefixed by >>):
>>
>>>> drivers/virt/coco/arm-cca-guest/arm-cca-guest.c:224:21: warning: 
>>>> attribute declaration must precede definition [-Wignored-attributes]
>> ????? 224 | static const struct __maybe_unused platform_device_id 
>> arm_cca_match[] = {
>> ????????? |???????????????????? ^
>> ??? include/linux/compiler_attributes.h:356:56: note: expanded from 
>> macro '__maybe_unused'
>> ????? 356 | #define __maybe_unused                  
>> __attribute__((__unused__))
>> ????????? |??????????????????????????????????????????????????????? ^
>> ??? include/linux/mod_devicetable.h:607:8: note: previous definition 
>> is here
>> ????? 607 | struct platform_device_id {
>> ????????? |??????? ^
>>>> drivers/virt/coco/arm-cca-guest/arm-cca-guest.c:224:55: warning: 
>>>> unused variable 'arm_cca_match' [-Wunused-const-variable]
>> ????? 224 | static const struct __maybe_unused platform_device_id 
>> arm_cca_match[] = {
>> ????????? |                                                       
>> ^~~~~~~~~~~~~
>> ??? 2 warnings generated.
>>
>>
>> vim +224 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
>>
>> ??? 222
>> ??? 223??? /* modalias, so userspace can autoload this module when RSI 
>> is available */
>> ? > 224??? static const struct __maybe_unused platform_device_id 
>> arm_cca_match[] = {
>> ??? 225??????? { RSI_PDEV_NAME, 0},
>> ??? 226??????? { }
>> ??? 227??? };
>> ??? 228
>>
> 
> The definition may have to be something like below, to avoid the 
> compiling warning.
> 
> static const struct platform_device_id __maybe_unused arm_cca_match[] = {

I should have tested this with clang rather than copy/pasting the 
utilization from somewhere else! It looks like a number of other kernel 
users are putting it before the '=', but its sorta annoying because it 
seems like the kind of warning that should be suppressed globally for 
this case (module device description in module that can be built in).



>  ?????? ...
> };
> 
> Thanks,
> Gavin
> 



From Dave.Martin at arm.com  Tue Dec  3 07:37:53 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 3 Dec 2024 15:37:53 +0000
Subject: [PATCH] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <a9aa36eb-d5c2-4d1c-bf5d-e63e4cb55404@arm.com>
References: <20241203100322.1626805-1-kevin.brodsky@arm.com>
 <Z07x69L6Mssncg/7@e133380.arm.com>
 <a9aa36eb-d5c2-4d1c-bf5d-e63e4cb55404@arm.com>
Message-ID: <Z08l0Q9KO6haeSSI@e133380.arm.com>

Hi,

On Tue, Dec 03, 2024 at 04:06:24PM +0100, Kevin Brodsky wrote:
> On 03/12/2024 12:56, Dave Martin wrote:
> > On Tue, Dec 03, 2024 at 10:03:22AM +0000, Kevin Brodsky wrote:
> >> [...]
> >> @@ -1462,10 +1462,33 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
> >>  			 struct rt_sigframe_user_layout *user, int usig)
> >>  {
> >>  	__sigrestore_t sigtramp;
> >> +	int err;
> >> +
> >> +	if (ksig->ka.sa.sa_flags & SA_RESTORER)
> >> +		sigtramp = ksig->ka.sa.sa_restorer;
> >> +	else
> >> +		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
> >> +
> >> +	err = gcs_signal_entry(sigtramp, ksig);
> >> +	if (err)
> >> +		return err;
> >> +
> >> +	/*
> >> +	 * We must not fail from this point onwards. We are going to update
> >> +	 * registers, including SP, in order to invoke the signal handler. If
> >> +	 * we failed and attempted to deliver a nested SIGSEGV to a handler
> >> +	 * after that point, the subsequent sigreturn would end up restoring
> >> +	 * the (partial) state for the original signal handler.
> >> +	 */
> > The same is true at the call site of this function; could problems
> > creep back in there?
> 
> That's a fair point, I could add a short comment after the call to
> setup_return() to clarify this.

That would make sense.

(Or refactor so that the point of no return is at a function boundary;
but since this is a Fixes: patch, it's probably best to keep things
simple.)
> 
> >>  
> >>  	regs->regs[0] = usig;
> >> +	if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
> >> +		regs->regs[1] = (unsigned long)&user->sigframe->info;
> >> +		regs->regs[2] = (unsigned long)&user->sigframe->uc;
> > Nit: This looks like it should work, but it's not really anything to do
> > with setting up how the handler returns (we're in setup_return() here).
> 
> setup_return() is a bit of a misnomer, unless you interpret "return" as
> "return to userspace". Aside from setting LR, setup_return() isn't about
> how the handler returns but simply how it is invoked. For instance the
> line just above sets X0 to the signal number, the first argument of the
> handler. Setting X1/X2 here seems pretty natural (they're also arguments
> for the handler).
> 
> - Kevin

I guess.  I remember the function names here already being a bit
counterintuitive, so this patch is not making things much more
confusing than they already were.

Cheers
---Dave
> 


From broonie at kernel.org  Tue Dec  3 08:00:45 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 3 Dec 2024 16:00:45 +0000
Subject: [PATCH 1/6] arm64/sme: Flush foreign register state in
 do_sme_acc()
In-Reply-To: <Z08khk6Mg6+T6VV9@e133380.arm.com>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-1-d853479d1b77@kernel.org>
 <Z08khk6Mg6+T6VV9@e133380.arm.com>
Message-ID: <9365be76-8da6-47ce-b88e-dfa244b9e5b7@sirena.org.uk>

On Tue, Dec 03, 2024 at 03:32:22PM +0000, Dave Martin wrote:
> On Tue, Dec 03, 2024 at 12:45:53PM +0000, Mark Brown wrote:

> > @@ -1460,6 +1460,8 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
> >  		sme_set_vq(vq_minus_one);
> >  
> >  		fpsimd_bind_task_to_cpu();
> > +	} else {
> > +		fpsimd_flush_task_state(current);

> TIF_FOREIGN_FPSTATE is (or was) a cache of the task<->CPU binding that
> you're clobbering here.

> So, this fpsimd_flush_task_state() should have no effect unless
> TIF_FOREIGN_FPSTATE is already wrong?  I'm wondering if the apparent
> need for this means that there is an undiagnosed bug elsewhere.

> (My understanding is based on FPSIMD/SVE; I'm less familiar with the
> SME changes, so I may be missing something important here.)

It's to ensure that the last recorded CPU for the current task is
invalid so that if the state was loaded on another CPU and we switch
back to that CPU we reload the state from memory, we need to at least
trigger configuration of the SME VL.
-------------- 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/20241203/e52f2cde/attachment.sig>

From gregkh at linuxfoundation.org  Tue Dec  3 06:43:13 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue,  3 Dec 2024 15:43:13 +0100
Subject: [PATCH 6.12 466/826] perf cs-etm: Dont flush when packet_queue fills up
In-Reply-To: <20241203144743.428732212@linuxfoundation.org>
References: <20241203144743.428732212@linuxfoundation.org>
Message-ID: <20241203144801.941516477@linuxfoundation.org>

6.12-stable review patch.  If anyone has any objections, please let me know.

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

From: James Clark <james.clark at linaro.org>

[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]

cs_etm__flush(), like cs_etm__sample() is an operation that generates a
sample and then swaps the current with the previous packet. Calling
flush after processing the queues results in two swaps which corrupts
the next sample. Therefore it wasn't appropriate to call flush here so
remove it.

Flushing is still done on a discontinuity to explicitly clear the last
branch buffer, but when the packet_queue fills up before reaching a
timestamp, that's not a discontinuity and the call to
cs_etm__process_traceid_queue() already generated samples and drained
the buffers correctly.

This is visible by looking for a branch that has the same target as the
previous branch and the following source is before the address of the
last target, which is impossible as execution would have had to have
gone backwards:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
   (packet_queue fills here before a timestamp, resulting in a flush and
    branch target ffff80008011cadc is duplicated.)
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

After removing the flush the correct branch target is used for the
second sample, and ffff8000801117c4 is no longer before the previous
address:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

Make sure that a final branch stack is output at the end of the trace
by calling cs_etm__end_block(). This is already done for both the
timeless decode paths.

Fixes: 21fe8dc1191a ("perf cs-etm: Add support for CPU-wide trace scenarios")
Reported-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Closes: https://lore.kernel.org/all/20240719092619.274730-1-gankulkarni at os.amperecomputing.com/
Reviewed-by: Leo Yan <leo.yan at arm.com>
Signed-off-by: James Clark <james.clark at linaro.org>
Tested-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Cc: Ben Gainey <ben.gainey at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Ruidong Tian <tianruidong at linux.alibaba.com>
Cc: Benjamin Gray <bgray at linux.ibm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: coresight at lists.linaro.org
Cc: John Garry <john.g.garry at oracle.com>
Cc: scclevenger at os.amperecomputing.com
Link: https://lore.kernel.org/r/20240916135743.1490403-2-james.clark at linaro.org
Signed-off-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/perf/util/cs-etm.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 40f047baef810..0bf9e5c27b599 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2490,12 +2490,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
 
 		/* Ignore return value */
 		cs_etm__process_traceid_queue(etmq, tidq);
-
-		/*
-		 * Generate an instruction sample with the remaining
-		 * branchstack entries.
-		 */
-		cs_etm__flush(etmq, tidq);
 	}
 }
 
@@ -2638,7 +2632,7 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)
 
 	while (1) {
 		if (!etm->heap.heap_cnt)
-			goto out;
+			break;
 
 		/* Take the entry at the top of the min heap */
 		cs_queue_nr = etm->heap.heap_array[0].queue_nr;
@@ -2721,6 +2715,23 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)
 		ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp);
 	}
 
+	for (i = 0; i < etm->queues.nr_queues; i++) {
+		struct int_node *inode;
+
+		etmq = etm->queues.queue_array[i].priv;
+		if (!etmq)
+			continue;
+
+		intlist__for_each_entry(inode, etmq->traceid_queues_list) {
+			int idx = (int)(intptr_t)inode->priv;
+
+			/* Flush any remaining branch stack entries */
+			tidq = etmq->traceid_queues[idx];
+			ret = cs_etm__end_block(etmq, tidq);
+			if (ret)
+				return ret;
+		}
+	}
 out:
 	return ret;
 }
-- 
2.43.0





From gregkh at linuxfoundation.org  Tue Dec  3 06:43:17 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue,  3 Dec 2024 15:43:17 +0100
Subject: [PATCH 6.12 470/826] perf stat: Uniquify event name improvements
In-Reply-To: <20241203144743.428732212@linuxfoundation.org>
References: <20241203144743.428732212@linuxfoundation.org>
Message-ID: <20241203144802.097952233@linuxfoundation.org>

6.12-stable review patch.  If anyone has any objections, please let me know.

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

From: Ian Rogers <irogers at google.com>

[ Upstream commit 057f8bfc6f7070577523d1e3081081bbf4229c1c ]

Without aggregation on Intel:
```
$ perf stat -e instructions,cycles ...
```
Will use "cycles" for the name of the legacy cycles event but as
"instructions" has a sysfs name it will and a "[cpu]" PMU suffix. This
often breaks things as the space between the event and the PMU name
look like an extra column. The existing uniquify logic was also
uniquifying in cases when all events are core and not with uncore
events, it was not correctly handling modifiers, etc.

Change the logic so that an initial pass that can disable
uniquification is run. For individual counters, disable uniquification
in more cases such as for consistency with legacy events or for
libpfm4 events. Don't use the "[pmu]" style suffix in uniquification,
always use "pmu/.../". Change how modifiers/terms are handled in the
uniquification so that they look like parse-able events.

This fixes "102: perf stat metrics (shadow stat) test:" that has been
failing due to "instructions [cpu]" breaking its column/awk logic when
values aren't aggregated. This started happening when instructions
could match a sysfs rather than a legacy event, so the fixes tag
reflects this.

Fixes: 617824a7f0f7 ("perf parse-events: Prefer sysfs/JSON hardware events over legacy")
Acked-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
[ Fix Intel TPEBS counting mode test ]
Acked-by: Kan Liang <kan.liang at linux.intel.com>
Signed-off-by: James Clark <james.clark at linaro.org>
Cc: Yang Jihong <yangjihong at bytedance.com>
Cc: Dominique Martinet <asmadeus at codewreck.org>
Cc: Colin Ian King <colin.i.king at gmail.com>
Cc: Howard Chu <howardchu95 at gmail.com>
Cc: Ze Gao <zegao2021 at gmail.com>
Cc: Yicong Yang <yangyicong at hisilicon.com>
Cc: Weilin Wang <weilin.wang at intel.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Jing Zhang <renyu.zj at linux.alibaba.com>
Cc: Yang Li <yang.lee at linux.alibaba.com>
Cc: Leo Yan <leo.yan at linux.dev>
Cc: ak at linux.intel.com
Cc: Athira Rajeev <atrajeev at linux.vnet.ibm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: Sun Haiyong <sunhaiyong at loongson.cn>
Cc: John Garry <john.g.garry at oracle.com>
Link: https://lore.kernel.org/r/20240926144851.245903-3-james.clark at linaro.org
Signed-off-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 .../perf/tests/shell/test_stat_intel_tpebs.sh |  11 +-
 tools/perf/util/stat-display.c                | 101 ++++++++++++++----
 2 files changed, 85 insertions(+), 27 deletions(-)

diff --git a/tools/perf/tests/shell/test_stat_intel_tpebs.sh b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
index c60b29add9801..9a11f42d153ca 100755
--- a/tools/perf/tests/shell/test_stat_intel_tpebs.sh
+++ b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
@@ -8,12 +8,15 @@ grep -q GenuineIntel /proc/cpuinfo || { echo Skipping non-Intel; exit 2; }
 # Use this event for testing because it should exist in all platforms
 event=cache-misses:R
 
+# Hybrid platforms output like "cpu_atom/cache-misses/R", rather than as above
+alt_name=/cache-misses/R
+
 # Without this cmd option, default value or zero is returned
-echo "Testing without --record-tpebs"
-result=$(perf stat -e "$event" true 2>&1)
-[[ "$result" =~ $event ]] || exit 1
+#echo "Testing without --record-tpebs"
+#result=$(perf stat -e "$event" true 2>&1)
+#[[ "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
 
 # In platforms that do not support TPEBS, it should execute without error.
 echo "Testing with --record-tpebs"
 result=$(perf stat -e "$event" --record-tpebs -a sleep 0.01 2>&1)
-[[ "$result" =~ "perf record" && "$result" =~ $event ]] || exit 1
+[[ "$result" =~ "perf record" && "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index ea96e4ebad8c8..cbff43ff8d0fb 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -871,38 +871,66 @@ static void printout(struct perf_stat_config *config, struct outstate *os,
 
 static void uniquify_event_name(struct evsel *counter)
 {
-	char *new_name;
-	char *config;
-	int ret = 0;
+	const char *name, *pmu_name;
+	char *new_name, *config;
+	int ret;
 
-	if (counter->uniquified_name || counter->use_config_name ||
-	    !counter->pmu_name || !strncmp(evsel__name(counter), counter->pmu_name,
-					   strlen(counter->pmu_name)))
+	/* The evsel was already uniquified. */
+	if (counter->uniquified_name)
 		return;
 
-	config = strchr(counter->name, '/');
+	/* Avoid checking to uniquify twice. */
+	counter->uniquified_name = true;
+
+	/* The evsel has a "name=" config term or is from libpfm. */
+	if (counter->use_config_name || counter->is_libpfm_event)
+		return;
+
+	/* Legacy no PMU event, don't uniquify. */
+	if  (!counter->pmu ||
+	     (counter->pmu->type < PERF_TYPE_MAX && counter->pmu->type != PERF_TYPE_RAW))
+		return;
+
+	/* A sysfs or json event replacing a legacy event, don't uniquify. */
+	if (counter->pmu->is_core && counter->alternate_hw_config != PERF_COUNT_HW_MAX)
+		return;
+
+	name = evsel__name(counter);
+	pmu_name = counter->pmu->name;
+	/* Already prefixed by the PMU name. */
+	if (!strncmp(name, pmu_name, strlen(pmu_name)))
+		return;
+
+	config = strchr(name, '/');
 	if (config) {
-		if (asprintf(&new_name,
-			     "%s%s", counter->pmu_name, config) > 0) {
-			free(counter->name);
-			counter->name = new_name;
-		}
-	} else {
-		if (evsel__is_hybrid(counter)) {
-			ret = asprintf(&new_name, "%s/%s/",
-				       counter->pmu_name, counter->name);
+		int len = config - name;
+
+		if (config[1] == '/') {
+			/* case: event// */
+			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 2);
 		} else {
-			ret = asprintf(&new_name, "%s [%s]",
-				       counter->name, counter->pmu_name);
+			/* case: event/.../ */
+			ret = asprintf(&new_name, "%s/%.*s,%s", pmu_name, len, name, config + 1);
 		}
+	} else {
+		config = strchr(name, ':');
+		if (config) {
+			/* case: event:.. */
+			int len = config - name;
 
-		if (ret) {
-			free(counter->name);
-			counter->name = new_name;
+			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 1);
+		} else {
+			/* case: event */
+			ret = asprintf(&new_name, "%s/%s/", pmu_name, name);
 		}
 	}
-
-	counter->uniquified_name = true;
+	if (ret > 0) {
+		free(counter->name);
+		counter->name = new_name;
+	} else {
+		/* ENOMEM from asprintf. */
+		counter->uniquified_name = false;
+	}
 }
 
 static bool hybrid_uniquify(struct evsel *evsel, struct perf_stat_config *config)
@@ -1559,6 +1587,31 @@ static void print_cgroup_counter(struct perf_stat_config *config, struct evlist
 		print_metric_end(config, os);
 }
 
+static void disable_uniquify(struct evlist *evlist)
+{
+	struct evsel *counter;
+	struct perf_pmu *last_pmu = NULL;
+	bool first = true;
+
+	evlist__for_each_entry(evlist, counter) {
+		/* If PMUs vary then uniquify can be useful. */
+		if (!first && counter->pmu != last_pmu)
+			return;
+		first = false;
+		if (counter->pmu) {
+			/* Allow uniquify for uncore PMUs. */
+			if (!counter->pmu->is_core)
+				return;
+			/* Keep hybrid event names uniquified for clarity. */
+			if (perf_pmus__num_core_pmus() > 1)
+				return;
+		}
+	}
+	evlist__for_each_entry_continue(evlist, counter) {
+		counter->uniquified_name = true;
+	}
+}
+
 void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config,
 			    struct target *_target, struct timespec *ts,
 			    int argc, const char **argv)
@@ -1572,6 +1625,8 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
 		.first = true,
 	};
 
+	disable_uniquify(evlist);
+
 	if (config->iostat_run)
 		evlist->selected = evlist__first(evlist);
 
-- 
2.43.0





From zichenxie0106 at gmail.com  Tue Dec  3 08:02:00 2024
From: zichenxie0106 at gmail.com (Gax-c)
Date: Tue,  3 Dec 2024 10:02:00 -0600
Subject: [PATCH] drm: cast calculation to __u64 to fix potential integer overflow
Message-ID: <20241203160159.8129-1-zichenxie0106@gmail.com>

From: Zichen Xie <zichenxie0106 at gmail.com>

Like commit b0b0d811eac6 ("drm/mediatek: Fix coverity issue with
unintentional integer overflow"), directly multiply pitch and
height may lead to integer overflow. Add a cast to avoid it.

Fixes: 6d1782919dc9 ("drm/cma: Introduce drm_gem_cma_dumb_create_internal()")
Fixes: dc5698e80cf7 ("Add virtio gpu driver.")
Fixes: dc6057ecb39e ("drm/tegra: gem: dumb: pitch and size are outputs")
Signed-off-by: Zichen Xie <zichenxie0106 at gmail.com>
Cc: stable at vger.kernel.org
---
 drivers/gpu/drm/drm_gem_dma_helper.c | 6 +++---
 drivers/gpu/drm/tegra/gem.c          | 2 +-
 drivers/gpu/drm/virtio/virtgpu_gem.c | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/drm_gem_dma_helper.c
index 870b90b78bc4..020c3b17fc02 100644
--- a/drivers/gpu/drm/drm_gem_dma_helper.c
+++ b/drivers/gpu/drm/drm_gem_dma_helper.c
@@ -272,8 +272,8 @@ int drm_gem_dma_dumb_create_internal(struct drm_file *file_priv,
 	if (args->pitch < min_pitch)
 		args->pitch = min_pitch;
 
-	if (args->size < args->pitch * args->height)
-		args->size = args->pitch * args->height;
+	if (args->size < (__u64)args->pitch * args->height)
+		args->size = (__u64)args->pitch * args->height;
 
 	dma_obj = drm_gem_dma_create_with_handle(file_priv, drm, args->size,
 						 &args->handle);
@@ -306,7 +306,7 @@ int drm_gem_dma_dumb_create(struct drm_file *file_priv,
 	struct drm_gem_dma_object *dma_obj;
 
 	args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
-	args->size = args->pitch * args->height;
+	args->size = (__u64)args->pitch * args->height;
 
 	dma_obj = drm_gem_dma_create_with_handle(file_priv, drm, args->size,
 						 &args->handle);
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index d275404ad0e9..a84acdbbbe3f 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -548,7 +548,7 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
 	struct tegra_bo *bo;
 
 	args->pitch = round_up(min_pitch, tegra->pitch_align);
-	args->size = args->pitch * args->height;
+	args->size = (__u64)args->pitch * args->height;
 
 	bo = tegra_bo_create_with_handle(file, drm, args->size, 0,
 					 &args->handle);
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 7db48d17ee3a..d5407316b12e 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -72,7 +72,7 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
 		return -EINVAL;
 
 	pitch = args->width * 4;
-	args->size = pitch * args->height;
+	args->size = (__u64)pitch * args->height;
 	args->size = ALIGN(args->size, PAGE_SIZE);
 
 	params.format = virtio_gpu_translate_format(DRM_FORMAT_HOST_XRGB8888);
-- 
2.34.1



From stephan.gerhold at linaro.org  Tue Dec  3 08:05:06 2024
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Tue, 3 Dec 2024 17:05:06 +0100
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint readery
In-Reply-To: <41106fd7-5348-4d21-9ae7-8466f5634b4c@oss.qualcomm.com>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com>
 <Z07r3Upr50vLluyn@linaro.org>
 <41106fd7-5348-4d21-9ae7-8466f5634b4c@oss.qualcomm.com>
Message-ID: <Z08sMkbLF0b1DZTp@linaro.org>

On Tue, Dec 03, 2024 at 09:07:22PM +0530, Krishna Kurapati wrote:
> On 12/3/2024 5:00 PM, Stephan Gerhold wrote:
> > On Tue, Dec 03, 2024 at 11:20:48AM +0100, Johan Hovold wrote:
> > > [ +CC: Krishna, Thinh and the USB list ]
> > > 
> > > On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
> > > > The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
> > > > multiport controller on eUSB6. All other ports (including USB super-speed
> > > > pins) are unused.
> > > > 
> > > > Set it up in the device tree together with the NXP PTN3222 repeater.
> > > > 
> > > > Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> > > > ---
> > > >   arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 48 +++++++++++++++++++++++++++++++
> > > >   1 file changed, 48 insertions(+)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > > > index 39f9d9cdc10d..44942931c18f 100644
> > > > --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > > > +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
> > > > @@ -735,6 +735,26 @@ keyboard at 3a {
> > > > [...]
> > > > @@ -1260,3 +1288,23 @@ &usb_1_ss2_dwc3_hs {
> > > >   &usb_1_ss2_qmpphy_out {
> > > >   	remote-endpoint = <&pmic_glink_ss2_ss_in>;
> > > >   };
> > > > +
> > > > +&usb_mp {
> > > > +	status = "okay";
> > > > +};
> > > > +
> > > > +&usb_mp_dwc3 {
> > > > +	/* Limit to USB 2.0 and single port */
> > > > +	maximum-speed = "high-speed";
> > > > +	phys = <&usb_mp_hsphy1>;
> > > > +	phy-names = "usb2-1";
> > > > +};
> > > 
> > > The dwc3 driver determines (and acts on) the number of ports based on
> > > the port interrupts in DT and controller capabilities.
> > > 
> > > I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
> > > that would still be there in the SoC (possibly initialised by the boot
> > > firmware).
> > > 
> > > I had a local patch to enable the multiport controller (for the suspend
> > > work) and I realise that you'd currently need to specify a repeater also
> > > for the HS PHY which does not have one, but that should be possible to
> > > fix somehow.
> > > 
> > 
> > I think there are two separate questions here:
> > 
> >   1. Should we (or do we even need to) enable unused PHYs?
> >   2. Do we need to power off unused PHYs left enabled by the firmware?
> > 
> > For (1), I'm not not sure if there is a technical reason that requires
> > us to. And given that PHYs typically consume quite a bit of power, I'm
> > not sure if we should. Perhaps it's not worth spending effort on this
> > minor optimization now, but then the device tree would ideally still
> > tell us which PHYs are actually used (for future optimizations).
> > 
> > For (2), yes, we probably need to. But my impression so far is that this
> > might be a larger problem that we need to handle on the SoC level. I
> > have seen some firmware versions that blindly power up all USB
> > controllers, even completely unused ones. Ideally we would power down
> > unused components during startup and then leave them off.
> > 
> 
> This question might be a dumb one, if so please ignore it.
> 
> But if we skip adding unused phys in DTS node, the core driver wouldn't have
> access to all phys and we wouldn't be able to get references to unused ones
> (un-mentioned ones in DTS). So how can we power them off from core driver if
> we don't have reference to them ?
> 

The question is not dumb at all, it's a very valid one. :-)

Perhaps it's easier if we keep them all listed on the USB controllers
and have something else to mark them as unused. The downside of that
option is that we might not be able to have a complete description of
the PHY with all resources. For example on the CRD there is no eUSB
repeater we could model for the first USB port (usb2-0), but it's needed
to enable the qcom,x1e80100-snps-eusb2-phy.

Thanks,
Stephan


From broonie at kernel.org  Tue Dec  3 08:12:33 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 3 Dec 2024 16:12:33 +0000
Subject: [PATCH 5/6] arm64/signal: Avoid corruption of SME state when
 entering signal handler
In-Reply-To: <Z08kvi0znVM2RHx4@e133380.arm.com>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-5-d853479d1b77@kernel.org>
 <Z08kvi0znVM2RHx4@e133380.arm.com>
Message-ID: <537fe318-a679-4b5c-b87f-93a7812dbeca@sirena.org.uk>

On Tue, Dec 03, 2024 at 03:33:18PM +0000, Dave Martin wrote:
> On Tue, Dec 03, 2024 at 12:45:57PM +0000, Mark Brown wrote:

> > +	get_cpu_fpsimd_context();

> > +		if (current->thread.svcr & SVCR_SM_MASK) {
> > +			memset(&current->thread.uw.fpsimd_state.vregs, 0,
> > +			       sizeof(current->thread.uw.fpsimd_state.vregs));

> Do we need to hold the CPU fpsimd context across this memset?

> IIRC, TIF_FOREIGN_FPSTATE can be spontaneously cleared along with
> dumping of the regs into thread_struct (from current's PoV), but never
> spontaneously set again.  So ... -> [*]

Yes, we could drop the lock here.  OTOH this is very simple and easy to
understand.

> > +		/* Ensure any copies on other CPUs aren't reused */
> > +		fpsimd_flush_task_state(current);

> (This is very similar to fpsimd_flush_thread(); can they be unified?)

I have a half finished series to replace the whole setup around
accessing the state with get/put operations for working on the state
which should remove all these functions.  The pile of similarly and
confusingly named operations we have for working on the state is one of
the major sources of issues with this code, even when actively working
on the code it's hard to remember exactly which operation does what
never mind the rules for which is needed.
-------------- 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/20241203/eae3702e/attachment.sig>

From mark.rutland at arm.com  Tue Dec  3 08:22:20 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 3 Dec 2024 16:22:20 +0000
Subject: [PATCH] arm64: Ensure bits ASID[15:8] are masked out when the
 kernel uses 8-bit ASIDs
In-Reply-To: <20241203151941.353796-1-catalin.marinas@arm.com>
References: <20241203151941.353796-1-catalin.marinas@arm.com>
Message-ID: <Z08wPAbb1SGYJfdH@J2N7QTR9R3.cambridge.arm.com>

On Tue, Dec 03, 2024 at 03:19:41PM +0000, Catalin Marinas wrote:
> Linux currently sets the TCR_EL1.AS bit unconditionally during CPU
> bring-up. On an 8-bit ASID CPU, this is RES0 and ignored, otherwise
> 16-bit ASIDs are enabled. However, if running in a VM and the hypervisor
> reports 8-bit ASIDs (ID_AA64MMFR0_EL1.ASIDBits == 0) on a 16-bit ASIDs
> CPU, Linux uses bits 8 to 63 as a generation number for tracking old
> process ASIDs. The bottom 8 bits of this generation end up being written
> to TTBR1_EL1 and also used for the ASID-based TLBI operations as the
> upper 8 bits of the ASID. Following an ASID roll-over event we can have
> threads of the same application with the same 8-bit ASID but different
> generation numbers running on separate CPUs. Both TLB caching and the
> TLBI operations will end up using different actual 16-bit ASIDs for the
> same process.
> 
> A similar scenario can happen in a big.LITTLE configuration if the boot
> CPU only uses 8-bit ASIDs while secondary CPUs have 16-bit ASIDs.
> 
> Ensure that the ASID generation is only tracked by bits 16 and up,
> leaving bits 15:8 as 0 if the kernel uses 8-bit ASIDs. Note that
> clearing TCR_EL1.AS is not sufficient since the architecture requires
> that the top 8 bits of the ASID passed to TLBI instructions are 0 rather
> than ignored in such configuration.
> 
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> Cc: <stable at vger.kernel.org>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: James Morse <james.morse at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/mm/context.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
> index 188197590fc9..b2ac06246327 100644
> --- a/arch/arm64/mm/context.c
> +++ b/arch/arm64/mm/context.c
> @@ -32,9 +32,9 @@ static unsigned long nr_pinned_asids;
>  static unsigned long *pinned_asid_map;
>  
>  #define ASID_MASK		(~GENMASK(asid_bits - 1, 0))
> -#define ASID_FIRST_VERSION	(1UL << asid_bits)
> +#define ASID_FIRST_VERSION	(1UL << 16)
>  
> -#define NUM_USER_ASIDS		ASID_FIRST_VERSION
> +#define NUM_USER_ASIDS		(1UL << asid_bits)
>  #define ctxid2asid(asid)	((asid) & ~ASID_MASK)
>  #define asid2ctxid(asid, genid)	((asid) | (genid))
>  


From geert+renesas at glider.be  Tue Dec  3 08:23:16 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  3 Dec 2024 17:23:16 +0100
Subject: [PATCH] gpio: GPIO_MVEBU should not default to y when compile-testing
Message-ID: <6b9e55dbf544297d5acf743f6fa473791ab10644.1733242798.git.geert+renesas@glider.be>

Merely enabling compile-testing should not enable additional
functionality.

Fixes: 956ee0c5c969c9ca ("gpio: mvebu: allow building the module with COMPILE_TEST=y")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 drivers/gpio/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index f483201637062cab..d371ce2578ee9703 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -491,8 +491,9 @@ config GPIO_MT7621
 	  Say yes here to support the Mediatek MT7621 SoC GPIO device.
 
 config GPIO_MVEBU
-	def_bool y
+	bool "Marvell Orion and EBU GPIO support" if COMPILE_TEST
 	depends on PLAT_ORION || ARCH_MVEBU || COMPILE_TEST
+	default PLAT_ORION || ARCH_MVEBU
 	select GENERIC_IRQ_CHIP
 	select REGMAP_MMIO
 
-- 
2.34.1



From geert+renesas at glider.be  Tue Dec  3 08:25:05 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  3 Dec 2024 17:25:05 +0100
Subject: [PATCH] rtc: RTC_DRV_SPEAR should not default to y when compile-testing
Message-ID: <7b8eefe3b0150101ba01c3ea55e45aa3134059ba.1733243007.git.geert+renesas@glider.be>

Merely enabling compile-testing should not enable additional
functionality.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 drivers/rtc/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index a60bcc791a4803b7..0bbbf778ecfa3e4c 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1316,7 +1316,7 @@ config RTC_DRV_SC27XX
 config RTC_DRV_SPEAR
 	tristate "SPEAR ST RTC"
 	depends on PLAT_SPEAR || COMPILE_TEST
-	default y
+	default PLAT_SPEAR
 	help
 	 If you say Y here you will get support for the RTC found on
 	 spear
-- 
2.34.1



From robh at kernel.org  Tue Dec  3 08:29:47 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 3 Dec 2024 10:29:47 -0600
Subject: [PATCH 1/2] dt-bindings: timer: fsl,imxgpt: Fix the fsl,imx7d-gpt fallback
In-Reply-To: <CAOMZO5AgQxd2_gkcPSdhfSDArEEkBVvo_yAW3hdHVXtHH5FyAg@mail.gmail.com>
References: <20241023185841.1183706-1-festevam@gmail.com> <20241024-pep-proud-d714705c9ddf@spud>
 <CAOMZO5BSZ4YAZ7Lqa3eGP9Wx=Ed7cgug==_UZqc7F57=XCJv3A@mail.gmail.com> <CAOMZO5AgQxd2_gkcPSdhfSDArEEkBVvo_yAW3hdHVXtHH5FyAg@mail.gmail.com>
Message-ID: <CAL_JsqKeAknYwaR_VRfrT7bHf9q6iNMyC9VV+dNBPd5VZNTLAg@mail.gmail.com>

On Wed, Nov 13, 2024 at 11:57?AM Fabio Estevam <festevam at gmail.com> wrote:
>
> Rob,
>
> On Tue, Nov 5, 2024 at 7:48?AM Fabio Estevam <festevam at gmail.com> wrote:
>
> > > Acked-by: Conor Dooley <conor.dooley at microchip.com>
> >
> > Can you apply this series via your tree?
>
> A gentle ping.

Daniel should apply this. That was my assumption and it was out of my
queue (which drops the chances of me ever reading this ping).

Rob


From robh at kernel.org  Tue Dec  3 08:30:37 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 3 Dec 2024 10:30:37 -0600
Subject: [PATCH RESEND 1/2] dt-bindings: timer: fsl,imxgpt: Fix the
 fsl,imx7d-gpt fallback
In-Reply-To: <20241202132147.587799-1-festevam@gmail.com>
References: <20241202132147.587799-1-festevam@gmail.com>
Message-ID: <20241203163037.GA1916867-robh@kernel.org>

On Mon, Dec 02, 2024 at 10:21:46AM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> imx7s.dtsi correctly describes the GPT node as:
> 
> compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt";
> 
> Document the fallback compatible to be "fsl,imx6dl-gpt" in the bindings.
> 
> This fixes the following dt-schema warnings:
> 
> timer at 302f0000: compatible: 'oneOf' conditional failed, one must be fixed:
> 	['fsl,imx7d-gpt', 'fsl,imx6dl-gpt'] is too long
> 	'fsl,imx1-gpt' was expected
> 	'fsl,imx21-gpt' was expected
> 	'fsl,imx27-gpt' was expected
> 	'fsl,imx31-gpt' was expected
> 	'fsl,imx7d-gpt' is not one of ['fsl,imx25-gpt', 'fsl,imx50-gpt', 'fsl,imx51-gpt', 'fsl,imx53-gpt', 'fsl,imx6q-gpt']
> 	'fsl,imx6dl-gpt' was expected
> 	'fsl,imx7d-gpt' is not one of ['fsl,imx6sl-gpt', 'fsl,imx6sx-gpt', 'fsl,imx8mp-gpt', 'fsl,imxrt1050-gpt', 'fsl,imxrt1170-gpt']
> 	'fsl,imx6sx-gpt' was expected
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>
> Reviewed-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> ---
>  Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

I'm assuming Daniel will apply, but I'll keep these in my queue until 
that happens.

> 
> diff --git a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> index e2607377cbae..a2fcb1e8e74e 100644
> --- a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> +++ b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> @@ -31,6 +31,7 @@ properties:
>            - enum:
>                - fsl,imx6sl-gpt
>                - fsl,imx6sx-gpt
> +              - fsl,imx7d-gpt
>                - fsl,imx8mp-gpt
>                - fsl,imxrt1050-gpt
>                - fsl,imxrt1170-gpt
> @@ -38,7 +39,6 @@ properties:
>        - items:
>            - enum:
>                - fsl,imx6ul-gpt
> -              - fsl,imx7d-gpt
>            - const: fsl,imx6sx-gpt
>  
>    reg:
> -- 
> 2.34.1
> 


From tglx at linutronix.de  Tue Dec  3 08:36:59 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 03 Dec 2024 17:36:59 +0100
Subject: [PATCH v5 1/2] kexec: Consolidate
 machine_kexec_mask_interrupts() implementation
In-Reply-To: <077908c5f02545f0a9e02ae77cbd771c@amazon.com>
References: <077908c5f02545f0a9e02ae77cbd771c@amazon.com>
Message-ID: <87ed2ou3is.ffs@tglx>

On Tue, Dec 03 2024 at 12:55, Eliav Farber wrote:
> On 12/3/2024 1:04 PM, Thomas Gleixner wrote:
>>> +
>>> +config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
>>> +     bool "Clear forwarded VM interrupts during kexec"
>>
>> This should not be user selectable. Just keep it as:
>>
>> config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
>>         bool
>>
>> which defaults to 'n'. Just add a comment what this is about like it's
>> done with the other options in that file which are only selectable.
> Question: Should this new configuration option be placed inside or
> outside the following section:
> ```
> menu "IRQ subsystem"
>
>
> endmenu
> ```
> In my patch, I have added the new configuration option at the end of
> the file, outside the "IRQ subsystem" section.

It does not really matter when the option is silent, but keeping it in
the menu section as the others is the most intuitive IMO.

Thanks,

        tglx





From afd at ti.com  Tue Dec  3 08:40:31 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 3 Dec 2024 10:40:31 -0600
Subject: [PATCH] arm64: dts: ti: k3-am625-sk: Remove M4 mailbox node redefinition
Message-ID: <20241203164031.20211-1-afd@ti.com>

This node is already defined in the included k3-am62x-sk-common.dtsi.
Remove this redefinition.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am625-sk.dts | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am625-sk.dts b/arch/arm64/boot/dts/ti/k3-am625-sk.dts
index ae81ebb39d02d..2fbfa37193457 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk.dts
@@ -219,13 +219,6 @@ cpsw3g_phy1: ethernet-phy at 1 {
 	};
 };
 
-&mailbox0_cluster0 {
-	mbox_m4_0: mbox-m4-0 {
-		ti,mbox-rx = <0 0 0>;
-		ti,mbox-tx = <1 0 0>;
-	};
-};
-
 &fss {
 	bootph-all;
 };
-- 
2.39.2



From kevin.brodsky at arm.com  Tue Dec  3 08:48:10 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Tue, 3 Dec 2024 17:48:10 +0100
Subject: [PATCH] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <Z08l0Q9KO6haeSSI@e133380.arm.com>
References: <20241203100322.1626805-1-kevin.brodsky@arm.com>
 <Z07x69L6Mssncg/7@e133380.arm.com>
 <a9aa36eb-d5c2-4d1c-bf5d-e63e4cb55404@arm.com>
 <Z08l0Q9KO6haeSSI@e133380.arm.com>
Message-ID: <3da4f6d2-5869-4515-a86a-e821d9276640@arm.com>

On 03/12/2024 16:37, Dave Martin wrote:
> Hi,
>
> On Tue, Dec 03, 2024 at 04:06:24PM +0100, Kevin Brodsky wrote:
>> On 03/12/2024 12:56, Dave Martin wrote:
>>> On Tue, Dec 03, 2024 at 10:03:22AM +0000, Kevin Brodsky wrote:
>>>> [...]
>>>> @@ -1462,10 +1462,33 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
>>>>  			 struct rt_sigframe_user_layout *user, int usig)
>>>>  {
>>>>  	__sigrestore_t sigtramp;
>>>> +	int err;
>>>> +
>>>> +	if (ksig->ka.sa.sa_flags & SA_RESTORER)
>>>> +		sigtramp = ksig->ka.sa.sa_restorer;
>>>> +	else
>>>> +		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
>>>> +
>>>> +	err = gcs_signal_entry(sigtramp, ksig);
>>>> +	if (err)
>>>> +		return err;
>>>> +
>>>> +	/*
>>>> +	 * We must not fail from this point onwards. We are going to update
>>>> +	 * registers, including SP, in order to invoke the signal handler. If
>>>> +	 * we failed and attempted to deliver a nested SIGSEGV to a handler
>>>> +	 * after that point, the subsequent sigreturn would end up restoring
>>>> +	 * the (partial) state for the original signal handler.
>>>> +	 */
>>> The same is true at the call site of this function; could problems
>>> creep back in there?
>> That's a fair point, I could add a short comment after the call to
>> setup_return() to clarify this.
> That would make sense.
>
> (Or refactor so that the point of no return is at a function boundary;
> but since this is a Fixes: patch, it's probably best to keep things
> simple.)

I did consider this, in fact this is what I did initially. However I
then realised that gcs_signal_entry() itself modifies thread state that
affects control flow. In other words, if it succeeds, then we are
already in a situation where failure should be avoided, so pulling it
out of setup_return() wouldn't necessarily be clearer. There may be more
operations that can fail like gcs_signal_entry() in the future, meaning
we'd have to "revert" such operations if any fails. I think it makes
sense for this to be handled in setup_return(). At least we don't need
to complicate things for now.

- Kevin


From heiko at sntech.de  Tue Dec  3 08:49:31 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 17:49:31 +0100
Subject: [PATCH v5 1/2] dt-bindings: phy: Add Rockchip MIPI C-/D-PHY schema
In-Reply-To: <20241203164934.1500616-1-heiko@sntech.de>
References: <20241203164934.1500616-1-heiko@sntech.de>
Message-ID: <20241203164934.1500616-2-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

Add dt-binding schema for the MIPI C-/D-PHY found on
Rockchip RK3588 SoCs.

Tested-by: Daniel Semkowicz <dse at thaumatec.com>
Tested-by: Sebastian Reichel <sebastian.reichel at collabora.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 .../phy/rockchip,rk3588-mipi-dcphy.yaml       | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml
new file mode 100644
index 000000000000..c8ff5ba22a86
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/rockchip,rk3588-mipi-dcphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip MIPI D-/C-PHY with Samsung IP block
+
+maintainers:
+  - Guochun Huang <hero.huang at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3576-mipi-dcphy
+      - rockchip,rk3588-mipi-dcphy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 1
+    description: |
+      Argument is mode to operate in. Supported modes are:
+        - PHY_TYPE_DPHY
+        - PHY_TYPE_CPHY
+      See include/dt-bindings/phy/phy.h for constants.
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: ref
+
+  resets:
+    maxItems: 4
+
+  reset-names:
+    items:
+      - const: m_phy
+      - const: apb
+      - const: grf
+      - const: s_phy
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon managing the 'mipi dcphy general register files'.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - "#phy-cells"
+
+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 feda0000 {
+        compatible = "rockchip,rk3588-mipi-dcphy";
+        reg = <0x0 0xfeda0000 0x0 0x10000>;
+        clocks = <&cru PCLK_MIPI_DCPHY0>,
+                 <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>;
+        clock-names = "pclk", "ref";
+        resets = <&cru SRST_M_MIPI_DCPHY0>,
+                 <&cru SRST_P_MIPI_DCPHY0>,
+                 <&cru SRST_P_MIPI_DCPHY0_GRF>,
+                 <&cru SRST_S_MIPI_DCPHY0>;
+        reset-names = "m_phy", "apb", "grf", "s_phy";
+        rockchip,grf = <&mipidcphy0_grf>;
+        #phy-cells = <1>;
+      };
+    };
-- 
2.45.2



From conor at kernel.org  Tue Dec  3 08:49:39 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 3 Dec 2024 16:49:39 +0000
Subject: [PATCH] dt-bindings: soc: fsl: cpm_qe: Limit matching to nodes
 with "fsl,qe"
In-Reply-To: <20241202045757.39244-1-wenst@chromium.org>
References: <20241202045757.39244-1-wenst@chromium.org>
Message-ID: <20241203-egotistic-certainly-116f38bd39b6@spud>

On Mon, Dec 02, 2024 at 12:57:55PM +0800, Chen-Yu Tsai wrote:
> Otherwise the binding matches against random nodes with "simple-bus"
> giving out all kinds of invalid warnings:
> 
>     $ make CHECK_DTBS=y mediatek/mt8188-evb.dtb
>       SYNC    include/config/auto.conf.cmd
>       UPD     include/config/kernel.release
>       SCHEMA  Documentation/devicetree/bindings/processed-schema.json
>       DTC [C] arch/arm64/boot/dts/mediatek/mt8188-evb.dtb
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: compatible:0: 'fsl,qe' was expected
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: compatible: ['simple-bus'] is too short
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:compatible:0: 'fsl,qe-ic' was expected
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:reg: [[0, 201326592, 0, 262144], [0, 201588736, 0, 2097152]] is too long
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:#interrupt-cells:0:0: 1 was expected
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000: '#redistributor-regions', 'ppi-partitions' do not match any of the regexes: 'pinctrl-[0-9]+'
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: 'reg' is a required property
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: 'bus-frequency' is a required property
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#

I'm curious why this is only coming up now, Rob applied this apparently
in July.

> 
> Fixes: ecbfc6ff94a2 ("dt-bindings: soc: fsl: cpm_qe: convert to yaml format")
> Cc: Frank Li <Frank.Li at nxp.com>
> Cc: <stable at vger.kernel.org> # v6.11+
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  .../devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml        | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
> index 89cdf5e1d0a8..9e07a2c4d05b 100644
> --- a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
> +++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
> @@ -21,6 +21,14 @@ description: |
>    The description below applies to the qe of MPC8360 and
>    more nodes and properties would be extended in the future.
>  
> +select:
> +  properties:
> +    compatible:
> +      contains:
> +        const: fsl,qe
> +  required:
> +    - compatible
> +
>  properties:
>    compatible:
>      items:
> -- 
> 2.47.0.338.g60cca15819-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/20241203/af0ef4a3/attachment.sig>

From heiko at sntech.de  Tue Dec  3 08:49:30 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 17:49:30 +0100
Subject: [PATCH v5 0/2] MIPI DSI phy for rk3588
Message-ID: <20241203164934.1500616-1-heiko@sntech.de>

This adds the phy driver need for DSI output on rk3588.

The phy itself is used for both DSI output and CSI input, though the
CSI part for the whole chain needs a lot more work, so is left out for
now and only the DSI part implemented.

This allows the rk3588 with its current VOP support to drive a DSI display
using the DSI2 controller driver I'll submit in a next step.

Only generic phy interfaces are used, so the DSI part is pretty straight
forward.

changes in v5:
- add bitfield.h for the FIELD_PROP definition
  (reported by kernel-test-robot)
- add Sebastian's Reviewed-by
- add Conor's Ack to the dt-binding

changes in v4:
- moved to #phy-cells = 1 as suggested by Sebastian, with the argument
  denoting the requested phy-type (C-PHY, D-PHY). This works similarly
  how the Mediatek C/D-PHY already implements this, see mails around:
  https://lore.kernel.org/all/20230608200552.GA3303349-robh at kernel.org/
- dropped Krzysztof's review tag from the binding because of this
- dropped custom UPDATE macro and use FIELD_PREP instead
- build a FIELD_PREP_HIWORD macro for the GRF settings
- add received Tested-by tags

changes in v3:
- add Krzysztof review tag to the binding
- address Sebastian's review comments
  - better error handling
  - dropping empty function
  - headers
  - not using of_match_ptr - this should also make the
    test-robot happier

changes in v2:
- fix error in dt-binding example
- drop unused frequency table
- pull in some more recent improvements from the vendor-kernel
  which includes a lot less magic values
- already include the support for rk3576
- use dev_err_probe

Heiko Stuebner (2):
  dt-bindings: phy: Add Rockchip MIPI C-/D-PHY schema
  phy: rockchip: Add Samsung MIPI D-/C-PHY driver

 .../phy/rockchip,rk3588-mipi-dcphy.yaml       |   87 +
 drivers/phy/rockchip/Kconfig                  |   12 +
 drivers/phy/rockchip/Makefile                 |    1 +
 .../phy/rockchip/phy-rockchip-samsung-dcphy.c | 1604 +++++++++++++++++
 4 files changed, 1704 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/rockchip,rk3588-mipi-dcphy.yaml
 create mode 100644 drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c

-- 
2.45.2



From robh at kernel.org  Tue Dec  3 08:50:07 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 3 Dec 2024 10:50:07 -0600
Subject: [PATCH v1 1/7] dt-bindings: display: mediatek: Add binding for
 HDMIv2 DDC
In-Reply-To: <20241120124512.134278-2-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
 <20241120124512.134278-2-angelogioacchino.delregno@collabora.com>
Message-ID: <173324460711.1946104.15731375026648249870.robh@kernel.org>


On Wed, 20 Nov 2024 13:45:06 +0100, AngeloGioacchino Del Regno wrote:
> Add a binding for the Display Data Channel (DDC) IP in MediaTek
> SoCs with version 2 HDMI TX IP.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  .../mediatek/mediatek,mt8195-hdmi-ddc.yaml    | 41 +++++++++++++++++++
>  1 file changed, 41 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From heiko at sntech.de  Tue Dec  3 08:49:32 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 17:49:32 +0100
Subject: [PATCH v5 2/2] phy: rockchip: Add Samsung MIPI D-/C-PHY driver
In-Reply-To: <20241203164934.1500616-1-heiko@sntech.de>
References: <20241203164934.1500616-1-heiko@sntech.de>
Message-ID: <20241203164934.1500616-3-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

Add driver for the MIPI D-/C-PHY block based around a Samsung IP-block
that is for example needed to drive a MIPI DSI output on rk3588.

Right now only the D-PHY portion is implemented, with the C-PHY part
needing separate work.

Tested-by: Daniel Semkowicz <dse at thaumatec.com>
Tested-by: Sebastian Reichel <sebastian.reichel at collabora.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 drivers/phy/rockchip/Kconfig                  |   12 +
 drivers/phy/rockchip/Makefile                 |    1 +
 .../phy/rockchip/phy-rockchip-samsung-dcphy.c | 1604 +++++++++++++++++
 3 files changed, 1617 insertions(+)
 create mode 100644 drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 2f7a05f21dc5..2bfb42996503 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -83,6 +83,18 @@ config PHY_ROCKCHIP_PCIE
 	help
 	  Enable this to support the Rockchip PCIe PHY.
 
+config PHY_ROCKCHIP_SAMSUNG_DCPHY
+	tristate "Rockchip Samsung MIPI DCPHY driver"
+	depends on (ARCH_ROCKCHIP || COMPILE_TEST)
+	select GENERIC_PHY
+	select GENERIC_PHY_MIPI_DPHY
+	help
+	  Enable this to support the Rockchip MIPI DCPHY with
+	  Samsung IP block.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called phy-rockchip-samsung-dcphy
+
 config PHY_ROCKCHIP_SAMSUNG_HDPTX
 	tristate "Rockchip Samsung HDMI/eDP Combo PHY driver"
 	depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index 010a824e32ce..117aaffd037d 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_DCPHY)	+= phy-rockchip-samsung-dcphy.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
diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
new file mode 100644
index 000000000000..7e4f82f87855
--- /dev/null
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
@@ -0,0 +1,1604 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Rockchip Electronics Co.Ltd
+ * Author:
+ *      Guochun Huang <hero.huang at rock-chips.com>
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define FIELD_PREP_HIWORD(_mask, _val)		\
+	(					\
+		FIELD_PREP((_mask), (_val)) |	\
+		((_mask) << 16)			\
+	)
+
+#define BIAS_CON0		0x0000
+#define BIAS_CON1		0x0004
+#define BIAS_CON2		0x0008
+#define BIAS_CON4		0x0010
+#define I_MUX_SEL_MASK		GENMASK(6, 5)
+#define I_MUX_SEL(x)		FIELD_PREP(I_MUX_SEL_MASK, x)
+#define I_MUX_SEL_400MV		I_MUX_SEL(0)
+#define I_MUX_SEL_200MV		I_MUX_SEL(1)
+#define I_MUX_SEL_530MV		I_MUX_SEL(2)
+
+#define PLL_CON0		0x0100
+#define PLL_EN			BIT(12)
+#define S_MASK			GENMASK(10, 8)
+#define S(x)			FIELD_PREP(S_MASK, x)
+#define P_MASK			GENMASK(5, 0)
+#define P(x)			FIELD_PREP(P_MASK, x)
+#define PLL_CON1		0x0104
+#define PLL_CON2		0x0108
+#define M_MASK			GENMASK(9, 0)
+#define M(x)			FIELD_PREP(M_MASK, x)
+#define PLL_CON3		0x010c
+#define MRR_MASK		GENMASK(13, 8)
+#define MRR(x)			FIELD_PREP(MRR_MASK, x)
+#define MFR_MASK		GENMASK(7, 0)
+#define MFR(x)			FIELD_PREP(MFR_MASK, x)
+#define PLL_CON4		0x0110
+#define SSCG_EN			BIT(11)
+#define PLL_CON5		0x0114
+#define RESET_N_SEL		BIT(10)
+#define PLL_ENABLE_SEL		BIT(8)
+#define PLL_CON6		0x0118
+#define PLL_CON7		0x011c
+#define PLL_LOCK_CNT(x)		FIELD_PREP(GENMASK(15, 0), x)
+#define PLL_CON8		0x0120
+#define PLL_STB_CNT(x)		FIELD_PREP(GENMASK(15, 0), x)
+#define PLL_STAT0		0x0140
+#define PLL_LOCK		BIT(0)
+
+#define DPHY_MC_GNR_CON0	0x0300
+#define PHY_READY		BIT(1)
+#define PHY_ENABLE		BIT(0)
+#define DPHY_MC_GNR_CON1	0x0304
+#define T_PHY_READY(x)		FIELD_PREP(GENMASK(15, 0), x)
+#define DPHY_MC_ANA_CON0	0x0308
+#define EDGE_CON(x)		FIELD_PREP(GENMASK(14, 12), x)
+#define EDGE_CON_DIR(x)		FIELD_PREP(BIT(9), x)
+#define EDGE_CON_EN		BIT(8)
+#define RES_UP(x)		FIELD_PREP(GENMASK(7, 4), x)
+#define RES_DN(x)		FIELD_PREP(GENMASK(3, 0), x)
+#define DPHY_MC_ANA_CON1	0x030c
+#define DPHY_MC_ANA_CON2	0x0310
+#define HS_VREG_AMP_ICON(x)	FIELD_PREP(GENMASK(1, 0), x)
+#define DPHY_MC_TIME_CON0	0x0330
+#define HSTX_CLK_SEL		BIT(12)
+#define T_LPX(x)		FIELD_PREP(GENMASK(11, 4), x)
+#define DPHY_MC_TIME_CON1	0x0334
+#define T_CLK_ZERO(x)		FIELD_PREP(GENMASK(15, 8), x)
+#define T_CLK_PREPARE(x)	FIELD_PREP(GENMASK(7, 0), x)
+#define DPHY_MC_TIME_CON2	0x0338
+#define T_HS_EXIT(x)		FIELD_PREP(GENMASK(15, 8), x)
+#define T_CLK_TRAIL(x)		FIELD_PREP(GENMASK(7, 0), x)
+#define DPHY_MC_TIME_CON3	0x033c
+#define T_CLK_POST(x)		FIELD_PREP(GENMASK(7, 0), x)
+#define DPHY_MC_TIME_CON4	0x0340
+#define T_ULPS_EXIT(x)		FIELD_PREP(GENMASK(9, 0), x)
+#define DPHY_MC_DESKEW_CON0	0x0350
+#define SKEW_CAL_RUN_TIME(x)	FIELD_PREP(GENMASK(15, 12), x)
+
+#define SKEW_CAL_INIT_RUN_TIME(x)	FIELD_PREP(GENMASK(11, 8), x)
+#define SKEW_CAL_INIT_WAIT_TIME(x)	FIELD_PREP(GENMASK(7, 4), x)
+#define SKEW_CAL_EN			BIT(0)
+
+#define COMBO_MD0_GNR_CON0	0x0400
+#define COMBO_MD0_GNR_CON1	0x0404
+#define COMBO_MD0_ANA_CON0	0x0408
+#define COMBO_MD0_ANA_CON1      0x040C
+#define COMBO_MD0_ANA_CON2	0x0410
+
+#define COMBO_MD0_TIME_CON0	0x0430
+#define COMBO_MD0_TIME_CON1	0x0434
+#define COMBO_MD0_TIME_CON2	0x0438
+#define COMBO_MD0_TIME_CON3	0x043C
+#define COMBO_MD0_TIME_CON4	0x0440
+#define COMBO_MD0_DATA_CON0	0x0444
+
+#define COMBO_MD1_GNR_CON0	0x0500
+#define COMBO_MD1_GNR_CON1	0x0504
+#define COMBO_MD1_ANA_CON0	0x0508
+#define COMBO_MD1_ANA_CON1	0x050c
+#define COMBO_MD1_ANA_CON2	0x0510
+#define COMBO_MD1_TIME_CON0	0x0530
+#define COMBO_MD1_TIME_CON1	0x0534
+#define COMBO_MD1_TIME_CON2	0x0538
+#define COMBO_MD1_TIME_CON3	0x053C
+#define COMBO_MD1_TIME_CON4	0x0540
+#define COMBO_MD1_DATA_CON0	0x0544
+
+#define COMBO_MD2_GNR_CON0	0x0600
+#define COMBO_MD2_GNR_CON1	0x0604
+#define COMBO_MD2_ANA_CON0	0X0608
+#define COMBO_MD2_ANA_CON1	0X060C
+#define COMBO_MD2_ANA_CON2	0X0610
+#define COMBO_MD2_TIME_CON0	0x0630
+#define COMBO_MD2_TIME_CON1	0x0634
+#define COMBO_MD2_TIME_CON2	0x0638
+#define COMBO_MD2_TIME_CON3	0x063C
+#define COMBO_MD2_TIME_CON4	0x0640
+#define COMBO_MD2_DATA_CON0	0x0644
+
+#define DPHY_MD3_GNR_CON0	0x0700
+#define DPHY_MD3_GNR_CON1	0x0704
+#define DPHY_MD3_ANA_CON0	0X0708
+#define DPHY_MD3_ANA_CON1	0X070C
+#define DPHY_MD3_ANA_CON2	0X0710
+#define DPHY_MD3_TIME_CON0	0x0730
+#define DPHY_MD3_TIME_CON1	0x0734
+#define DPHY_MD3_TIME_CON2	0x0738
+#define DPHY_MD3_TIME_CON3	0x073C
+#define DPHY_MD3_TIME_CON4	0x0740
+#define DPHY_MD3_DATA_CON0	0x0744
+
+#define T_LP_EXIT_SKEW(x)	FIELD_PREP(GENMASK(3, 2), x)
+#define T_LP_ENTRY_SKEW(x)	FIELD_PREP(GENMASK(1, 0), x)
+#define T_HS_ZERO(x)		FIELD_PREP(GENMASK(15, 8), x)
+#define T_HS_PREPARE(x)		FIELD_PREP(GENMASK(7, 0), x)
+#define T_HS_EXIT(x)		FIELD_PREP(GENMASK(15, 8), x)
+#define T_HS_TRAIL(x)		FIELD_PREP(GENMASK(7, 0), x)
+#define T_TA_GET(x)		FIELD_PREP(GENMASK(7, 4), x)
+#define T_TA_GO(x)		FIELD_PREP(GENMASK(3, 0), x)
+
+/* MIPI_CDPHY_GRF registers */
+#define MIPI_DCPHY_GRF_CON0		0x0000
+#define S_CPHY_MODE			FIELD_PREP_HIWORD(BIT(3), 1)
+#define M_CPHY_MODE			FIELD_PREP_HIWORD(BIT(0), 1)
+
+enum hs_drv_res_ohm {
+	STRENGTH_30_OHM = 0x8,
+	STRENGTH_31_2_OHM,
+	STRENGTH_32_5_OHM,
+	STRENGTH_34_OHM,
+	STRENGTH_35_5_OHM,
+	STRENGTH_37_OHM,
+	STRENGTH_39_OHM,
+	STRENGTH_41_OHM,
+	STRENGTH_43_OHM = 0x0,
+	STRENGTH_46_OHM,
+	STRENGTH_49_OHM,
+	STRENGTH_52_OHM,
+	STRENGTH_56_OHM,
+	STRENGTH_60_OHM,
+	STRENGTH_66_OHM,
+	STRENGTH_73_OHM,
+};
+
+struct hs_drv_res_cfg {
+	enum hs_drv_res_ohm clk_hs_drv_up_ohm;
+	enum hs_drv_res_ohm clk_hs_drv_down_ohm;
+	enum hs_drv_res_ohm data_hs_drv_up_ohm;
+	enum hs_drv_res_ohm data_hs_drv_down_ohm;
+};
+
+struct samsung_mipi_dcphy_plat_data {
+	const struct hs_drv_res_cfg *dphy_hs_drv_res_cfg;
+	u32 dphy_tx_max_lane_kbps;
+};
+
+struct samsung_mipi_dcphy {
+	struct device *dev;
+	struct clk *ref_clk;
+	struct clk *pclk;
+	struct regmap *regmap;
+	struct regmap *grf_regmap;
+	struct reset_control *m_phy_rst;
+	struct reset_control *s_phy_rst;
+	struct reset_control *apb_rst;
+	struct reset_control *grf_apb_rst;
+	unsigned int lanes;
+	struct phy *phy;
+	u8 type;
+
+	const struct samsung_mipi_dcphy_plat_data *pdata;
+	struct {
+		unsigned long long rate;
+		u8 prediv;
+		u16 fbdiv;
+		long dsm;
+		u8 scaler;
+
+		bool ssc_en;
+		u8 mfr;
+		u8 mrr;
+	} pll;
+};
+
+struct samsung_mipi_dphy_timing {
+	unsigned int max_lane_mbps;
+	u8 clk_prepare;
+	u8 clk_zero;
+	u8 clk_post;
+	u8 clk_trail_eot;
+	u8 hs_prepare;
+	u8 hs_zero;
+	u8 hs_trail_eot;
+	u8 lpx;
+	u8 hs_exit;
+	u8 hs_settle;
+};
+
+static const
+struct samsung_mipi_dphy_timing samsung_mipi_dphy_timing_table[] = {
+	{6500, 32, 117, 31, 28, 30, 56, 27, 24, 44, 37},
+	{6490, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
+	{6480, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
+	{6470, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
+	{6460, 32, 116, 31, 28, 30, 56, 27, 24, 44, 37},
+	{6450, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37},
+	{6440, 32, 115, 31, 28, 30, 56, 27, 24, 44, 37},
+	{6430, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37},
+	{6420, 31, 116, 31, 28, 30, 55, 27, 24, 44, 37},
+	{6410, 31, 116, 31, 27, 30, 55, 27, 24, 44, 37},
+	{6400, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
+	{6390, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
+	{6380, 31, 115, 30, 27, 30, 55, 27, 23, 43, 36},
+	{6370, 31, 115, 30, 27, 30, 55, 26, 23, 43, 36},
+	{6360, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
+	{6350, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
+	{6340, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
+	{6330, 31, 114, 30, 27, 30, 54, 26, 23, 43, 36},
+	{6320, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
+	{6310, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
+	{6300, 31, 113, 30, 27, 30, 54, 26, 23, 43, 36},
+	{6290, 31, 113, 30, 27, 29, 54, 26, 23, 43, 36},
+	{6280, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
+	{6270, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
+	{6260, 31, 112, 30, 27, 29, 54, 26, 23, 43, 36},
+	{6250, 31, 112, 30, 27, 29, 54, 26, 23, 42, 36},
+	{6240, 30, 113, 30, 27, 29, 54, 26, 23, 42, 36},
+	{6230, 30, 112, 30, 27, 29, 54, 26, 23, 42, 35},
+	{6220, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35},
+	{6210, 30, 112, 30, 27, 29, 53, 26, 23, 42, 35},
+	{6200, 30, 112, 29, 27, 29, 53, 26, 23, 42, 35},
+	{6190, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35},
+	{6180, 30, 111, 29, 27, 29, 53, 26, 23, 42, 35},
+	{6170, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35},
+	{6160, 30, 111, 29, 26, 29, 53, 26, 23, 42, 35},
+	{6150, 30, 110, 29, 26, 29, 53, 26, 23, 42, 35},
+	{6140, 30, 110, 29, 26, 29, 52, 26, 23, 42, 35},
+	{6130, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
+	{6120, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
+	{6110, 30, 110, 29, 26, 29, 52, 25, 22, 42, 35},
+	{6100, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35},
+	{6090, 30, 109, 29, 26, 29, 52, 25, 22, 41, 35},
+	{6080, 30, 109, 29, 26, 28, 53, 25, 22, 41, 35},
+	{6070, 30, 109, 29, 26, 28, 52, 25, 22, 41, 34},
+	{6060, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34},
+	{6050, 30, 108, 29, 26, 28, 52, 25, 22, 41, 34},
+	{6040, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34},
+	{6030, 29, 109, 29, 26, 28, 52, 25, 22, 41, 34},
+	{6020, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34},
+	{6010, 29, 108, 29, 26, 28, 52, 25, 22, 41, 34},
+	{6000, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34},
+	{5990, 29, 108, 28, 26, 28, 51, 25, 22, 41, 34},
+	{5980, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34},
+	{5970, 29, 107, 28, 26, 28, 51, 25, 22, 41, 34},
+	{5960, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34},
+	{5950, 29, 107, 28, 26, 28, 51, 25, 22, 40, 34},
+	{5940, 29, 107, 28, 25, 28, 51, 25, 22, 40, 34},
+	{5930, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
+	{5920, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
+	{5910, 29, 106, 28, 25, 28, 50, 25, 22, 40, 34},
+	{5900, 29, 106, 28, 25, 28, 50, 24, 22, 40, 33},
+	{5890, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33},
+	{5880, 29, 105, 28, 25, 28, 50, 24, 22, 40, 33},
+	{5870, 29, 105, 28, 25, 27, 51, 24, 22, 40, 33},
+	{5860, 29, 105, 28, 25, 27, 51, 24, 21, 40, 33},
+	{5850, 29, 104, 28, 25, 27, 50, 24, 21, 40, 33},
+	{5840, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
+	{5830, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
+	{5820, 28, 105, 28, 25, 27, 50, 24, 21, 40, 33},
+	{5810, 28, 104, 28, 25, 27, 50, 24, 21, 39, 33},
+	{5800, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33},
+	{5790, 28, 104, 27, 25, 27, 50, 24, 21, 39, 33},
+	{5780, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33},
+	{5770, 28, 104, 27, 25, 27, 49, 24, 21, 39, 33},
+	{5760, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
+	{5750, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
+	{5740, 28, 103, 27, 25, 27, 49, 24, 21, 39, 33},
+	{5730, 28, 103, 27, 25, 27, 49, 24, 21, 39, 32},
+	{5720, 28, 102, 27, 25, 27, 49, 24, 21, 39, 32},
+	{5710, 28, 102, 27, 25, 27, 48, 24, 21, 39, 32},
+	{5700, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32},
+	{5690, 28, 102, 27, 24, 27, 48, 24, 21, 39, 32},
+	{5680, 28, 101, 27, 24, 27, 48, 24, 21, 39, 32},
+	{5670, 28, 101, 27, 24, 27, 48, 23, 21, 38, 32},
+	{5660, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32},
+	{5650, 28, 101, 27, 24, 26, 49, 23, 21, 38, 32},
+	{5640, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
+	{5630, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
+	{5620, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
+	{5610, 27, 101, 27, 24, 26, 48, 23, 21, 38, 32},
+	{5600, 27, 101, 26, 24, 26, 48, 23, 20, 38, 32},
+	{5590, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32},
+	{5580, 27, 100, 26, 24, 26, 48, 23, 20, 38, 32},
+	{5570, 27, 100, 26, 24, 26, 48, 23, 20, 38, 31},
+	{5560, 27, 100, 26, 24, 26, 47, 23, 20, 38, 31},
+	{5550, 27,  99, 26, 24, 26, 47, 23, 20, 38, 31},
+	{5540, 27,  99, 26, 24, 26, 47, 23, 20, 38, 31},
+	{5530, 27,  99, 26, 24, 26, 47, 23, 20, 38, 31},
+	{5520, 27,  99, 26, 24, 26, 47, 23, 20, 37, 31},
+	{5510, 27,  98, 26, 24, 26, 47, 23, 20, 37, 31},
+	{5500, 27,  98, 26, 24, 26, 47, 23, 20, 37, 31},
+	{5490, 27,  98, 26, 24, 26, 46, 23, 20, 37, 31},
+	{5480, 27,  98, 26, 24, 26, 46, 23, 20, 37, 31},
+	{5470, 27,  97, 26, 23, 26, 46, 23, 20, 37, 31},
+	{5460, 27,  97, 26, 23, 26, 46, 23, 20, 37, 31},
+	{5450, 27,  97, 26, 23, 25, 47, 23, 20, 37, 31},
+	{5440, 26,  98, 26, 23, 25, 47, 23, 20, 37, 31},
+	{5430, 26,  98, 26, 23, 25, 47, 22, 20, 37, 31},
+	{5420, 26,  97, 26, 23, 25, 46, 22, 20, 37, 31},
+	{5410, 26,  97, 26, 23, 25, 46, 22, 20, 37, 31},
+	{5400, 26,  97, 25, 23, 25, 46, 22, 20, 37, 30},
+	{5390, 26,  97, 25, 23, 25, 46, 22, 20, 37, 30},
+	{5380, 26,  96, 25, 23, 25, 46, 22, 20, 36, 30},
+	{5370, 26,  96, 25, 23, 25, 46, 22, 20, 36, 30},
+	{5360, 26,  96, 25, 23, 25, 46, 22, 20, 36, 30},
+	{5350, 26,  96, 25, 23, 25, 46, 22, 20, 36, 30},
+	{5340, 26,  95, 25, 23, 25, 45, 22, 20, 36, 30},
+	{5330, 26,  95, 25, 23, 25, 45, 22, 19, 36, 30},
+	{5320, 26,  95, 25, 23, 25, 45, 22, 19, 36, 30},
+	{5310, 26,  95, 25, 23, 25, 45, 22, 19, 36, 30},
+	{5300, 26,  95, 25, 23, 25, 45, 22, 19, 36, 30},
+	{5290, 26,  94, 25, 23, 25, 45, 22, 19, 36, 30},
+	{5280, 26,  94, 25, 23, 25, 45, 22, 19, 36, 30},
+	{5270, 26,  94, 25, 23, 25, 44, 22, 19, 36, 30},
+	{5260, 26,  94, 25, 23, 25, 44, 22, 19, 36, 30},
+	{5250, 25,  94, 25, 23, 24, 45, 22, 19, 36, 30},
+	{5240, 25,  94, 25, 23, 24, 45, 22, 19, 36, 29},
+	{5230, 25,  94, 25, 22, 24, 45, 22, 19, 35, 29},
+	{5220, 25,  94, 25, 22, 24, 45, 22, 19, 35, 29},
+	{5210, 25,  93, 25, 22, 24, 45, 22, 19, 35, 29},
+	{5200, 25,  93, 24, 22, 24, 44, 21, 19, 35, 29},
+	{5190, 25,  93, 24, 22, 24, 44, 21, 19, 35, 29},
+	{5180, 25,  93, 24, 22, 24, 44, 21, 19, 35, 29},
+	{5170, 25,  92, 24, 22, 24, 44, 21, 19, 35, 29},
+	{5160, 25,  92, 24, 22, 24, 44, 21, 19, 35, 29},
+	{5150, 25,  92, 24, 22, 24, 44, 21, 19, 35, 29},
+	{5140, 25,  92, 24, 22, 24, 44, 21, 19, 35, 29},
+	{5130, 25,  92, 24, 22, 24, 43, 21, 19, 35, 29},
+	{5120, 25,  91, 24, 22, 24, 43, 21, 19, 35, 29},
+	{5110, 25,  91, 24, 22, 24, 43, 21, 19, 35, 29},
+	{5100, 25,  91, 24, 22, 24, 43, 21, 19, 35, 29},
+	{5090, 25,  91, 24, 22, 24, 43, 21, 19, 34, 29},
+	{5080, 25,  90, 24, 22, 24, 43, 21, 19, 34, 29},
+	{5070, 25,  90, 24, 22, 24, 43, 21, 19, 34, 28},
+	{5060, 25,  90, 24, 22, 24, 43, 21, 18, 34, 28},
+	{5050, 24,  91, 24, 22, 24, 42, 21, 18, 34, 28},
+	{5040, 24,  90, 24, 22, 23, 43, 21, 18, 34, 28},
+	{5030, 24,  90, 24, 22, 23, 43, 21, 18, 34, 28},
+	{5020, 24,  90, 24, 22, 23, 43, 21, 18, 34, 28},
+	{5010, 24,  90, 24, 22, 23, 43, 21, 18, 34, 28},
+	{5000, 24,  89, 23, 21, 23, 43, 21, 18, 34, 28},
+	{4990, 24,  89, 23, 21, 23, 43, 21, 18, 34, 28},
+	{4980, 24,  89, 23, 21, 23, 42, 21, 18, 34, 28},
+	{4970, 24,  89, 23, 21, 23, 42, 21, 18, 34, 28},
+	{4960, 24,  89, 23, 21, 23, 42, 20, 18, 34, 28},
+	{4950, 24,  88, 23, 21, 23, 42, 20, 18, 34, 28},
+	{4940, 24,  88, 23, 21, 23, 42, 20, 18, 33, 28},
+	{4930, 24,  88, 23, 21, 23, 42, 20, 18, 33, 28},
+	{4920, 24,  88, 23, 21, 23, 42, 20, 18, 33, 28},
+	{4910, 24,  87, 23, 21, 23, 41, 20, 18, 33, 28},
+	{4900, 24,  87, 23, 21, 23, 41, 20, 18, 33, 27},
+	{4890, 24,  87, 23, 21, 23, 41, 20, 18, 33, 27},
+	{4880, 24,  87, 23, 21, 23, 41, 20, 18, 33, 27},
+	{4870, 24,  86, 23, 21, 23, 41, 20, 18, 33, 27},
+	{4860, 24,  86, 23, 21, 23, 41, 20, 18, 33, 27},
+	{4850, 23,  87, 23, 21, 23, 41, 20, 18, 33, 27},
+	{4840, 23,  87, 23, 21, 23, 40, 20, 18, 33, 27},
+	{4830, 23,  86, 23, 21, 22, 41, 20, 18, 33, 27},
+	{4820, 23,  86, 23, 21, 22, 41, 20, 18, 33, 27},
+	{4810, 23,  86, 23, 21, 22, 41, 20, 18, 33, 27},
+	{4800, 23,  86, 22, 21, 22, 41, 20, 17, 32, 27},
+	{4790, 23,  86, 22, 21, 22, 41, 20, 17, 32, 27},
+	{4780, 23,  85, 22, 21, 22, 41, 20, 17, 32, 27},
+	{4770, 23,  85, 22, 21, 22, 41, 20, 17, 32, 27},
+	{4760, 23,  85, 22, 20, 22, 40, 20, 17, 32, 27},
+	{4750, 23,  85, 22, 20, 22, 40, 20, 17, 32, 27},
+	{4740, 23,  84, 22, 20, 22, 40, 20, 17, 32, 26},
+	{4730, 23,  84, 22, 20, 22, 40, 19, 17, 32, 26},
+	{4720, 23,  84, 22, 20, 22, 40, 19, 17, 32, 26},
+	{4710, 23,  84, 22, 20, 22, 40, 19, 17, 32, 26},
+	{4700, 23,  83, 22, 20, 22, 40, 19, 17, 32, 26},
+	{4690, 23,  83, 22, 20, 22, 39, 19, 17, 32, 26},
+	{4680, 23,  83, 22, 20, 22, 39, 19, 17, 32, 26},
+	{4670, 23,  83, 22, 20, 22, 39, 19, 17, 32, 26},
+	{4660, 23,  82, 22, 20, 22, 39, 19, 17, 32, 26},
+	{4650, 22,  83, 22, 20, 22, 39, 19, 17, 31, 26},
+	{4640, 22,  83, 22, 20, 22, 39, 19, 17, 31, 26},
+	{4630, 22,  83, 22, 20, 22, 39, 19, 17, 31, 26},
+	{4620, 22,  83, 22, 20, 21, 39, 19, 17, 31, 26},
+	{4610, 22,  82, 22, 20, 21, 39, 19, 17, 31, 26},
+	{4600, 22,  82, 21, 20, 21, 39, 19, 17, 31, 26},
+	{4590, 22,  82, 21, 20, 21, 39, 19, 17, 31, 26},
+	{4580, 22,  82, 21, 20, 21, 39, 19, 17, 31, 26},
+	{4570, 22,  81, 21, 20, 21, 39, 19, 17, 31, 25},
+	{4560, 22,  81, 21, 20, 21, 39, 19, 17, 31, 25},
+	{4550, 22,  81, 21, 20, 21, 38, 19, 17, 31, 25},
+	{4540, 22,  81, 21, 20, 21, 38, 19, 17, 31, 25},
+	{4530, 22,  80, 21, 19, 21, 38, 19, 16, 31, 25},
+	{4520, 22,  80, 21, 19, 21, 38, 19, 16, 31, 25},
+	{4510, 22,  80, 21, 19, 21, 38, 19, 16, 31, 25},
+	{4500, 22,  80, 21, 19, 21, 38, 19, 16, 30, 25},
+	{4490, 22,  80, 21, 19, 21, 38, 18, 16, 30, 25},
+	{4480, 22,  79, 21, 19, 21, 38, 18, 16, 30, 25},
+	{4470, 22,  79, 21, 19, 21, 37, 18, 16, 30, 25},
+	{4460, 22,  79, 21, 19, 21, 37, 18, 16, 30, 25},
+	{4450, 21,  80, 21, 19, 21, 37, 18, 16, 30, 25},
+	{4440, 21,  79, 21, 19, 21, 37, 18, 16, 30, 25},
+	{4430, 21,  79, 21, 19, 21, 37, 18, 16, 30, 25},
+	{4420, 21,  79, 21, 19, 21, 37, 18, 16, 30, 25},
+	{4410, 21,  79, 21, 19, 20, 38, 18, 16, 30, 25},
+	{4400, 21,  78, 20, 19, 20, 37, 18, 16, 30, 24},
+	{4390, 21,  78, 20, 19, 20, 37, 18, 16, 30, 24},
+	{4380, 21,  78, 20, 19, 20, 37, 18, 16, 30, 24},
+	{4370, 21,  78, 20, 19, 20, 37, 18, 16, 30, 24},
+	{4360, 21,  77, 20, 19, 20, 37, 18, 16, 29, 24},
+	{4350, 21,  77, 20, 19, 20, 37, 18, 16, 29, 24},
+	{4340, 21,  77, 20, 19, 20, 37, 18, 16, 29, 24},
+	{4330, 21,  77, 20, 19, 20, 36, 18, 16, 29, 24},
+	{4320, 21,  77, 20, 19, 20, 36, 18, 16, 29, 24},
+	{4310, 21,  76, 20, 19, 20, 36, 18, 16, 29, 24},
+	{4300, 21,  76, 20, 18, 20, 36, 18, 16, 29, 24},
+	{4290, 21,  76, 20, 18, 20, 36, 18, 16, 29, 24},
+	{4280, 21,  76, 20, 18, 20, 36, 18, 16, 29, 24},
+	{4270, 21,  75, 20, 18, 20, 36, 18, 16, 29, 24},
+	{4260, 21,  75, 20, 18, 20, 35, 17, 15, 29, 24},
+	{4250, 20,  76, 20, 18, 20, 35, 17, 15, 29, 24},
+	{4240, 20,  76, 20, 18, 20, 35, 17, 15, 29, 23},
+	{4230, 20,  75, 20, 18, 20, 35, 17, 15, 29, 23},
+	{4220, 20,  75, 20, 18, 20, 35, 17, 15, 29, 23},
+	{4210, 20,  75, 20, 18, 20, 35, 17, 15, 28, 23},
+	{4200, 20,  75, 19, 18, 19, 36, 17, 15, 28, 23},
+	{4190, 20,  74, 19, 18, 19, 36, 17, 15, 28, 23},
+	{4180, 20,  74, 19, 18, 19, 35, 17, 15, 28, 23},
+	{4170, 20,  74, 19, 18, 19, 35, 17, 15, 28, 23},
+	{4160, 20,  74, 19, 18, 19, 35, 17, 15, 28, 23},
+	{4150, 20,  74, 19, 18, 19, 35, 17, 15, 28, 23},
+	{4140, 20,  73, 19, 18, 19, 35, 17, 15, 28, 23},
+	{4130, 20,  73, 19, 18, 19, 35, 17, 15, 28, 23},
+	{4120, 20,  73, 19, 18, 19, 35, 17, 15, 28, 23},
+	{4110, 20,  73, 19, 18, 19, 34, 17, 15, 28, 23},
+	{4100, 20,  72, 19, 18, 19, 34, 17, 15, 28, 23},
+	{4090, 20,  72, 19, 18, 19, 34, 17, 15, 28, 23},
+	{4080, 20,  72, 19, 18, 19, 34, 17, 15, 28, 23},
+	{4070, 20,  72, 19, 18, 19, 34, 17, 15, 27, 22},
+	{4060, 19,  72, 19, 17, 19, 34, 17, 15, 27, 22},
+	{4050, 19,  72, 19, 17, 19, 34, 17, 15, 27, 22},
+	{4040, 19,  72, 19, 17, 19, 33, 17, 15, 27, 22},
+	{4030, 19,  72, 19, 17, 19, 33, 17, 15, 27, 22},
+	{4020, 19,  71, 19, 17, 19, 33, 16, 15, 27, 22},
+	{4010, 19,  71, 19, 17, 19, 33, 16, 15, 27, 22},
+	{4000, 19,  71, 18, 17, 19, 33, 16, 14, 27, 22},
+	{3990, 19,  71, 18, 17, 18, 34, 16, 14, 27, 22},
+	{3980, 19,  71, 18, 17, 18, 34, 16, 14, 27, 22},
+	{3970, 19,  70, 18, 17, 18, 33, 16, 14, 27, 22},
+	{3960, 19,  70, 18, 17, 18, 33, 16, 14, 27, 22},
+	{3950, 19,  70, 18, 17, 18, 33, 16, 14, 27, 22},
+	{3940, 19,  70, 18, 17, 18, 33, 16, 14, 27, 22},
+	{3930, 19,  69, 18, 17, 18, 33, 16, 14, 27, 22},
+	{3920, 19,  69, 18, 17, 18, 33, 16, 14, 26, 22},
+	{3910, 19,  69, 18, 17, 18, 33, 16, 14, 26, 22},
+	{3900, 19,  69, 18, 17, 18, 33, 16, 14, 26, 21},
+	{3890, 19,  68, 18, 17, 18, 32, 16, 14, 26, 21},
+	{3880, 19,  68, 18, 17, 18, 32, 16, 14, 26, 21},
+	{3870, 19,  68, 18, 17, 18, 32, 16, 14, 26, 21},
+	{3860, 18,  69, 18, 17, 18, 32, 16, 14, 26, 21},
+	{3850, 18,  68, 18, 17, 18, 32, 16, 14, 26, 21},
+	{3840, 18,  68, 18, 17, 18, 32, 16, 14, 26, 21},
+	{3830, 18,  68, 18, 16, 18, 32, 16, 14, 26, 21},
+	{3820, 18,  68, 18, 16, 18, 31, 16, 14, 26, 21},
+	{3810, 18,  68, 18, 16, 18, 31, 16, 14, 26, 21},
+	{3800, 18,  67, 17, 16, 18, 31, 16, 14, 26, 21},
+	{3790, 18,  67, 17, 16, 17, 32, 15, 14, 26, 21},
+	{3780, 18,  67, 17, 16, 17, 32, 15, 14, 25, 21},
+	{3770, 18,  67, 17, 16, 17, 32, 15, 14, 25, 21},
+	{3760, 18,  66, 17, 16, 17, 32, 15, 14, 25, 21},
+	{3750, 18,  66, 17, 16, 17, 31, 15, 14, 25, 21},
+	{3740, 18,  66, 17, 16, 17, 31, 15, 14, 25, 20},
+	{3730, 18,  66, 17, 16, 17, 31, 15, 13, 25, 20},
+	{3720, 18,  65, 17, 16, 17, 31, 15, 13, 25, 20},
+	{3710, 18,  65, 17, 16, 17, 31, 15, 13, 25, 20},
+	{3700, 18,  65, 17, 16, 17, 31, 15, 13, 25, 20},
+	{3690, 18,  65, 17, 16, 17, 31, 15, 13, 25, 20},
+	{3680, 18,  64, 17, 16, 17, 31, 15, 13, 25, 20},
+	{3670, 18,  64, 17, 16, 17, 30, 15, 13, 25, 20},
+	{3660, 17,  65, 17, 16, 17, 30, 15, 13, 25, 20},
+	{3650, 17,  65, 17, 16, 17, 30, 15, 13, 25, 20},
+	{3640, 17,  65, 17, 16, 17, 30, 15, 13, 25, 20},
+	{3630, 17,  64, 17, 16, 17, 30, 15, 13, 24, 20},
+	{3620, 17,  64, 17, 16, 17, 30, 15, 13, 24, 20},
+	{3610, 17,  64, 17, 16, 17, 30, 15, 13, 24, 20},
+	{3600, 17,  64, 16, 16, 17, 29, 15, 13, 24, 20},
+	{3590, 17,  63, 16, 15, 17, 29, 15, 13, 24, 20},
+	{3580, 17,  63, 16, 15, 16, 30, 15, 13, 24, 20},
+	{3570, 17,  63, 16, 15, 16, 30, 15, 13, 24, 19},
+	{3560, 17,  63, 16, 15, 16, 30, 14, 13, 24, 19},
+	{3550, 17,  62, 16, 15, 16, 30, 14, 13, 24, 19},
+	{3540, 17,  62, 16, 15, 16, 30, 14, 13, 24, 19},
+	{3530, 17,  62, 16, 15, 16, 29, 14, 13, 24, 19},
+	{3520, 17,  62, 16, 15, 16, 29, 14, 13, 24, 19},
+	{3510, 17,  62, 16, 15, 16, 29, 14, 13, 24, 19},
+	{3500, 17,  61, 16, 15, 16, 29, 14, 13, 24, 19},
+	{3490, 17,  61, 16, 15, 16, 29, 14, 13, 23, 19},
+	{3480, 17,  61, 16, 15, 16, 29, 14, 13, 23, 19},
+	{3470, 17,  61, 16, 15, 16, 29, 14, 13, 23, 19},
+	{3460, 16,  61, 16, 15, 16, 28, 14, 12, 23, 19},
+	{3450, 16,  61, 16, 15, 16, 28, 14, 12, 23, 19},
+	{3440, 16,  61, 16, 15, 16, 28, 14, 12, 23, 19},
+	{3430, 16,  61, 16, 15, 16, 28, 14, 12, 23, 19},
+	{3420, 16,  60, 16, 15, 16, 28, 14, 12, 23, 19},
+	{3410, 16,  60, 16, 15, 16, 28, 14, 12, 23, 18},
+	{3400, 16,  60, 15, 15, 16, 28, 14, 12, 23, 18},
+	{3390, 16,  60, 15, 15, 16, 28, 14, 12, 23, 18},
+	{3380, 16,  59, 15, 15, 16, 27, 14, 12, 23, 18},
+	{3370, 16,  59, 15, 15, 15, 28, 14, 12, 23, 18},
+	{3360, 16,  59, 15, 14, 15, 28, 14, 12, 23, 18},
+	{3350, 16,  59, 15, 14, 15, 28, 14, 12, 23, 18},
+	{3340, 16,  59, 15, 14, 15, 28, 14, 12, 22, 18},
+	{3330, 16,  58, 15, 14, 15, 28, 14, 12, 22, 18},
+	{3320, 16,  58, 15, 14, 15, 28, 13, 12, 22, 18},
+	{3310, 16,  58, 15, 14, 15, 27, 13, 12, 22, 18},
+	{3300, 16,  58, 15, 14, 15, 27, 13, 12, 22, 18},
+	{3290, 16,  57, 15, 14, 15, 27, 13, 12, 22, 18},
+	{3280, 16,  57, 15, 14, 15, 27, 13, 12, 22, 18},
+	{3270, 16,  57, 15, 14, 15, 27, 13, 12, 22, 18},
+	{3260, 15,  58, 15, 14, 15, 27, 13, 12, 22, 18},
+	{3250, 15,  57, 15, 14, 15, 27, 13, 12, 22, 18},
+	{3240, 15,  57, 15, 14, 15, 26, 13, 12, 22, 17},
+	{3230, 15,  57, 15, 14, 15, 26, 13, 12, 22, 17},
+	{3220, 15,  57, 15, 14, 15, 26, 13, 12, 22, 17},
+	{3210, 15,  56, 15, 14, 15, 26, 13, 12, 22, 17},
+	{3200, 15,  56, 14, 14, 15, 26, 13, 11, 21, 17},
+	{3190, 15,  56, 14, 14, 15, 26, 13, 11, 21, 17},
+	{3180, 15,  56, 14, 14, 15, 26, 13, 11, 21, 17},
+	{3170, 15,  56, 14, 14, 15, 25, 13, 11, 21, 17},
+	{3160, 15,  55, 14, 14, 14, 26, 13, 11, 21, 17},
+	{3150, 15,  55, 14, 14, 14, 26, 13, 11, 21, 17},
+	{3140, 15,  55, 14, 14, 14, 26, 13, 11, 21, 17},
+	{3130, 15,  55, 14, 14, 14, 26, 13, 11, 21, 17},
+	{3120, 15,  54, 14, 13, 14, 26, 13, 11, 21, 17},
+	{3110, 15,  54, 14, 13, 14, 26, 13, 11, 21, 17},
+	{3100, 15,  54, 14, 13, 14, 26, 13, 11, 21, 17},
+	{3090, 15,  54, 14, 13, 14, 25, 12, 11, 21, 17},
+	{3080, 15,  53, 14, 13, 14, 25, 12, 11, 21, 17},
+	{3070, 14,  54, 14, 13, 14, 25, 12, 11, 21, 16},
+	{3060, 14,  54, 14, 13, 14, 25, 12, 11, 21, 16},
+	{3050, 14,  54, 14, 13, 14, 25, 12, 11, 20, 16},
+	{3040, 14,  53, 14, 13, 14, 25, 12, 11, 20, 16},
+	{3030, 14,  53, 14, 13, 14, 25, 12, 11, 20, 16},
+	{3020, 14,  53, 14, 13, 14, 24, 12, 11, 20, 16},
+	{3010, 14,  53, 14, 13, 14, 24, 12, 11, 20, 16},
+	{3000, 14,  53, 13, 13, 14, 24, 12, 11, 20, 16},
+	{2990, 14,  52, 13, 13, 14, 24, 12, 11, 20, 16},
+	{2980, 14,  52, 13, 13, 14, 24, 12, 11, 20, 16},
+	{2970, 14,  52, 13, 13, 14, 24, 12, 11, 20, 16},
+	{2960, 14,  52, 13, 13, 14, 24, 12, 11, 20, 16},
+	{2950, 14,  51, 13, 13, 13, 24, 12, 11, 20, 16},
+	{2940, 14,  51, 13, 13, 13, 24, 12, 11, 20, 16},
+	{2930, 14,  51, 13, 13, 13, 24, 12, 10, 20, 16},
+	{2920, 14,  51, 13, 13, 13, 24, 12, 10, 20, 16},
+	{2910, 14,  50, 13, 13, 13, 24, 12, 10, 20, 15},
+	{2900, 14,  50, 13, 13, 13, 24, 12, 10, 19, 15},
+	{2890, 14,  50, 13, 12, 13, 24, 12, 10, 19, 15},
+	{2880, 14,  50, 13, 12, 13, 23, 12, 10, 19, 15},
+	{2870, 13,  50, 13, 12, 13, 23, 12, 10, 19, 15},
+	{2860, 13,  50, 13, 12, 13, 23, 12, 10, 19, 15},
+	{2850, 13,  50, 13, 12, 13, 23, 11, 10, 19, 15},
+	{2840, 13,  50, 13, 12, 13, 23, 11, 10, 19, 15},
+	{2830, 13,  50, 13, 12, 13, 23, 11, 10, 19, 15},
+	{2820, 13,  49, 13, 12, 13, 23, 11, 10, 19, 15},
+	{2810, 13,  49, 13, 12, 13, 23, 11, 10, 19, 15},
+	{2800, 13,  49, 12, 12, 13, 22, 11, 10, 19, 15},
+	{2790, 13,  49, 12, 12, 13, 22, 11, 10, 19, 15},
+	{2780, 13,  48, 12, 12, 13, 22, 11, 10, 19, 15},
+	{2770, 13,  48, 12, 12, 13, 22, 11, 10, 19, 15},
+	{2760, 13,  48, 12, 12, 13, 22, 11, 10, 18, 15},
+	{2750, 13,  48, 12, 12, 13, 22, 11, 10, 18, 15},
+	{2740, 13,  47, 12, 12, 12, 23, 11, 10, 18, 14},
+	{2730, 13,  47, 12, 12, 12, 22, 11, 10, 18, 14},
+	{2720, 13,  47, 12, 12, 12, 22, 11, 10, 18, 14},
+	{2710, 13,  47, 12, 12, 12, 22, 11, 10, 18, 14},
+	{2700, 13,  47, 12, 12, 12, 22, 11, 10, 18, 14},
+	{2690, 13,  46, 12, 12, 12, 22, 11, 10, 18, 14},
+	{2680, 13,  46, 12, 12, 12, 22, 11, 10, 18, 14},
+	{2670, 12,  47, 12, 12, 12, 22, 11, 10, 18, 14},
+	{2660, 12,  47, 12, 12, 12, 21, 11,  9, 18, 14},
+	{2650, 12,  46, 12, 11, 12, 21, 11,  9, 18, 14},
+	{2640, 12,  46, 12, 11, 12, 21, 11,  9, 18, 14},
+	{2630, 12,  46, 12, 11, 12, 21, 11,  9, 18, 14},
+	{2620, 12,  46, 12, 11, 12, 21, 10,  9, 18, 14},
+	{2610, 12,  45, 12, 11, 12, 21, 10,  9, 17, 14},
+	{2600, 12,  45, 11, 11, 12, 21, 10,  9, 17, 14},
+	{2590, 12,  45, 11, 11, 12, 20, 10,  9, 17, 14},
+	{2580, 12,  45, 11, 11, 12, 20, 10,  9, 17, 14},
+	{2570, 12,  44, 11, 11, 12, 20, 10,  9, 17, 13},
+	{2560, 12,  44, 11, 11, 12, 20, 10,  9, 17, 13},
+	{2550, 12,  44, 11, 11, 12, 20, 10,  9, 17, 13},
+	{2540, 12,  44, 11, 11, 11, 21, 10,  9, 17, 13},
+	{2530, 12,  44, 11, 11, 11, 21, 10,  9, 17, 13},
+	{2520, 12,  43, 11, 11, 11, 21, 10,  9, 17, 13},
+	{2510, 12,  43, 11, 11, 11, 20, 10,  9, 17, 13},
+	{2500, 12,  43, 11, 11, 11, 20, 10,  9, 17, 13},
+	{2490, 12,  43, 11, 11, 11, 20, 10,  9, 17, 13},
+	{2480, 12,  42, 11, 11, 11, 20, 10,  9, 17, 13},
+	{2470, 11,  43, 11, 11, 11, 20, 10,  9, 16, 13},
+	{2460, 11,  43, 11, 11, 11, 20, 10,  9, 16, 13},
+	{2450, 11,  43, 11, 11, 11, 20, 10,  9, 16, 13},
+	{2440, 11,  42, 11, 11, 11, 19, 10,  9, 16, 13},
+	{2430, 11,  42, 11, 11, 11, 19, 10,  9, 16, 13},
+	{2420, 11,  42, 11, 10, 11, 19, 10,  9, 16, 13},
+	{2410, 11,  42, 11, 10, 11, 19, 10,  9, 16, 12},
+	{2400, 11,  41, 10, 10, 11, 19, 10,  8, 16, 12},
+	{2390, 11,  41, 10, 10, 11, 19, 10,  8, 16, 12},
+	{2380, 11,  41, 10, 10, 11, 19,  9,  8, 16, 12},
+	{2370, 11,  41, 10, 10, 11, 18,  9,  8, 16, 12},
+	{2360, 11,  41, 10, 10, 11, 18,  9,  8, 16, 12},
+	{2350, 11,  40, 10, 10, 11, 18,  9,  8, 16, 12},
+	{2340, 11,  40, 10, 10, 11, 18,  9,  8, 16, 12},
+	{2330, 11,  40, 10, 10, 10, 19,  9,  8, 16, 12},
+	{2320, 11,  40, 10, 10, 10, 19,  9,  8, 15, 12},
+	{2310, 11,  39, 10, 10, 10, 19,  9,  8, 15, 12},
+	{2300, 11,  39, 10, 10, 10, 18,  9,  8, 15, 12},
+	{2290, 11,  39, 10, 10, 10, 18,  9,  8, 15, 12},
+	{2280, 11,  39, 10, 10, 10, 18,  9,  8, 15, 12},
+	{2270, 10,  39, 10, 10, 10, 18,  9,  8, 15, 12},
+	{2260, 10,  39, 10, 10, 10, 18,  9,  8, 15, 12},
+	{2250, 10,  39, 10, 10, 10, 18,  9,  8, 15, 12},
+	{2240, 10,  39, 10, 10, 10, 18,  9,  8, 15, 11},
+	{2230, 10,  38, 10, 10, 10, 18,  9,  8, 15, 11},
+	{2220, 10,  38, 10, 10, 10, 17,  9,  8, 15, 11},
+	{2210, 10,  38, 10, 10, 10, 17,  9,  8, 15, 11},
+	{2200, 10,  38,  9, 10, 10, 17,  9,  8, 15, 11},
+	{2190, 10,  38,  9,  9, 10, 17,  9,  8, 15, 11},
+	{2180, 10,  37,  9,  9, 10, 17,  9,  8, 14, 11},
+	{2170, 10,  37,  9,  9, 10, 17,  9,  8, 14, 11},
+	{2160, 10,  37,  9,  9, 10, 17,  9,  8, 14, 11},
+	{2150, 10,  37,  9,  9, 10, 16,  8,  8, 14, 11},
+	{2140, 10,  36,  9,  9, 10, 16,  8,  8, 14, 11},
+	{2130, 10,  36,  9,  9, 10, 16,  8,  7, 14, 11},
+	{2120, 10,  36,  9,  9,  9, 17,  8,  7, 14, 11},
+	{2110, 10,  36,  9,  9,  9, 17,  8,  7, 14, 11},
+	{2100, 10,  35,  9,  9,  9, 17,  8,  7, 14, 11},
+	{2090, 10,  35,  9,  9,  9, 17,  8,  7, 14, 11},
+	{2080,  9,  36,  9,  9,  9, 16,  8,  7, 14, 11},
+	{2070,  9,  36,  9,  9,  9, 16,  8,  7, 14, 10},
+	{2060,  9,  35,  9,  9,  9, 16,  8,  7, 14, 10},
+	{2050,  9,  35,  9,  9,  9, 16,  8,  7, 14, 10},
+	{2040,  9,  35,  9,  9,  9, 16,  8,  7, 14, 10},
+	{2030,  9,  35,  9,  9,  9, 16,  8,  7, 13, 10},
+	{2020,  9,  35,  9,  9,  9, 16,  8,  7, 13, 10},
+	{2010,  9,  34,  9,  9,  9, 15,  8,  7, 13, 10},
+	{2000,  9,  34,  8,  9,  9, 15,  8,  7, 13, 10},
+	{1990,  9,  34,  8,  9,  9, 15,  8,  7, 13, 10},
+	{1980,  9,  34,  8,  9,  9, 15,  8,  7, 13, 10},
+	{1970,  9,  33,  8,  9,  9, 15,  8,  7, 13, 10},
+	{1960,  9,  33,  8,  9,  9, 15,  8,  7, 13, 10},
+	{1950,  9,  33,  8,  8,  9, 15,  8,  7, 13, 10},
+	{1940,  9,  33,  8,  8,  9, 15,  8,  7, 13, 10},
+	{1930,  9,  32,  8,  8,  9, 14,  8,  7, 13, 10},
+	{1920,  9,  32,  8,  8,  9, 14,  8,  7, 13, 10},
+	{1910,  9,  32,  8,  8,  8, 15,  7,  7, 13,  9},
+	{1900,  9,  32,  8,  8,  8, 15,  7,  7, 13,  9},
+	{1890,  9,  31,  8,  8,  8, 15,  7,  7, 12,  9},
+	{1880,  8,  32,  8,  8,  8, 15,  7,  7, 12,  9},
+	{1870,  8,  32,  8,  8,  8, 15,  7,  7, 12,  9},
+	{1860,  8,  32,  8,  8,  8, 14,  7,  6, 12,  9},
+	{1850,  8,  32,  8,  8,  8, 14,  7,  6, 12,  9},
+	{1840,  8,  31,  8,  8,  8, 14,  7,  6, 12,  9},
+	{1830,  8,  31,  8,  8,  8, 14,  7,  6, 12,  9},
+	{1820,  8,  31,  8,  8,  8, 14,  7,  6, 12,  9},
+	{1810,  8,  31,  8,  8,  8, 14,  7,  6, 12,  9},
+	{1800,  8,  30,  7,  8,  8, 14,  7,  6, 12,  9},
+	{1790,  8,  30,  7,  8,  8, 13,  7,  6, 12,  9},
+	{1780,  8,  30,  7,  8,  8, 13,  7,  6, 12,  9},
+	{1770,  8,  30,  7,  8,  8, 13,  7,  6, 12,  9},
+	{1760,  8,  29,  7,  8,  8, 13,  7,  6, 12,  9},
+	{1750,  8,  29,  7,  8,  8, 13,  7,  6, 12,  9},
+	{1740,  8,  29,  7,  8,  8, 13,  7,  6, 11,  8},
+	{1730,  8,  29,  7,  8,  8, 13,  7,  6, 11,  8},
+	{1720,  8,  29,  7,  7,  8, 13,  7,  6, 11,  8},
+	{1710,  8,  28,  7,  7,  8, 12,  7,  6, 11,  8},
+	{1700,  8,  28,  7,  7,  7, 13,  7,  6, 11,  8},
+	{1690,  8,  28,  7,  7,  7, 13,  7,  6, 11,  8},
+	{1680,  7,  29,  7,  7,  7, 13,  6,  6, 11,  8},
+	{1670,  7,  28,  7,  7,  7, 13,  6,  6, 11,  8},
+	{1660,  7,  28,  7,  7,  7, 13,  6,  6, 11,  8},
+	{1650,  7,  28,  7,  7,  7, 13,  6,  6, 11,  8},
+	{1640,  7,  28,  7,  7,  7, 12,  6,  6, 11,  8},
+	{1630,  7,  27,  7,  7,  7, 12,  6,  6, 11,  8},
+	{1620,  7,  27,  7,  7,  7, 12,  6,  6, 11,  8},
+	{1610,  7,  27,  7,  7,  7, 12,  6,  6, 11,  8},
+	{1600,  7,  27,  6,  7,  7, 12,  6,  5, 10,  8},
+	{1590,  7,  26,  6,  7,  7, 12,  6,  5, 10,  8},
+	{1580,  7,  26,  6,  7,  7, 12,  6,  5, 10,  7},
+	{1570,  7,  26,  6,  7,  7, 11,  6,  5, 10,  7},
+	{1560,  7,  26,  6,  7,  7, 11,  6,  5, 10,  7},
+	{1550,  7,  26,  6,  7,  7, 11,  6,  5, 10,  7},
+	{1540,  7,  25,  6,  7,  7, 11,  6,  5, 10,  7},
+	{1530,  7,  25,  6,  7,  7, 11,  6,  5, 10,  7},
+	{1520,  7,  25,  6,  7,  7, 11,  6,  5, 10,  7},
+	{1510,  7,  25,  6,  7,  7, 11,  6,  5, 10,  7},
+	{1500,  7,  24,  6,  7,  7, 10,  6,  5, 10,  7},
+	{1490, 59,  25,  6, 77, 59, 10, 70, 44,  9, 73},
+	{1480, 59,  24,  6, 76, 58, 10, 70, 44,  9, 73},
+	{1470, 58,  24,  6, 76, 58, 10, 69, 44,  9, 72},
+	{1460, 58,  24,  6, 76, 58, 10, 69, 43,  9, 72},
+	{1450, 58,  24,  6, 75, 57, 10, 68, 43,  9, 71},
+	{1440, 57,  24,  6, 75, 57, 10, 68, 43,  9, 71},
+	{1430, 57,  23,  6, 75, 57, 10, 68, 43,  8, 70},
+	{1420, 56,  23,  6, 74, 57,  9, 67, 43,  8, 70},
+	{1410, 56,  23,  6, 74, 57,  9, 67, 43,  8, 69},
+	{1400, 56,  23,  5, 74, 55,  9, 67, 41,  8, 69},
+	{1390, 55,  23,  5, 73, 55,  9, 66, 41,  8, 68},
+	{1380, 55,  23,  5, 73, 54,  9, 66, 41,  8, 68},
+	{1370, 54,  22,  5, 72, 54,  9, 66, 41,  8, 67},
+	{1360, 54,  22,  5, 72, 54,  9, 65, 40,  8, 67},
+	{1350, 54,  22,  5, 72, 53,  9, 65, 40,  8, 66},
+	{1340, 53,  22,  5, 71, 53,  9, 65, 40,  8, 66},
+	{1330, 53,  22,  5, 71, 53,  9, 64, 39,  8, 65},
+	{1320, 52,  22,  5, 71, 53,  8, 64, 40,  8, 65},
+	{1310, 52,  21,  5, 70, 53,  8, 64, 40,  8, 64},
+	{1300, 51,  21,  5, 70, 51,  8, 63, 38,  8, 64},
+	{1290, 51,  21,  5, 70, 51,  8, 63, 38,  7, 64},
+	{1280, 51,  21,  5, 69, 51,  8, 63, 38,  7, 63},
+	{1270, 50,  21,  5, 69, 50,  8, 62, 38,  7, 63},
+	{1260, 50,  20,  5, 69, 50,  8, 62, 37,  7, 62},
+	{1250, 49,  20,  5, 68, 49,  8, 62, 37,  7, 62},
+	{1240, 49,  20,  5, 68, 49,  8, 61, 37,  7, 61},
+	{1230, 49,  20,  5, 68, 49,  8, 61, 36,  7, 61},
+	{1220, 48,  20,  5, 67, 48,  8, 61, 36,  7, 60},
+	{1210, 48,  19,  5, 67, 48,  7, 60, 36,  7, 60},
+	{1200, 49,  19,  4, 67, 49,  7, 60, 36,  7, 59},
+	{1190, 48,  19,  4, 66, 48,  7, 60, 36,  7, 59},
+	{1180, 48,  19,  4, 66, 48,  7, 59, 36,  7, 58},
+	{1170, 46,  19,  4, 66, 46,  7, 59, 35,  7, 58},
+	{1160, 46,  18,  4, 65, 46,  7, 59, 34,  7, 57},
+	{1150, 45,  18,  4, 65, 46,  7, 58, 34,  7, 57},
+	{1140, 45,  18,  4, 65, 45,  7, 58, 34,  6, 56},
+	{1130, 45,  18,  4, 64, 45,  7, 58, 33,  6, 56},
+	{1120, 44,  18,  4, 64, 44,  7, 57, 33,  6, 55},
+	{1110, 44,  18,  4, 64, 44,  7, 57, 33,  6, 55},
+	{1100, 43,  17,  4, 63, 44,  6, 57, 32,  6, 54},
+	{1090, 43,  17,  4, 63, 44,  6, 56, 33,  6, 54},
+	{1080, 43,  17,  4, 63, 44,  6, 56, 33,  6, 53},
+	{1070, 42,  17,  4, 62, 44,  6, 56, 33,  6, 53},
+	{1060, 42,  17,  4, 62, 42,  6, 55, 31,  6, 52},
+	{1050, 41,  17,  4, 62, 42,  6, 55, 31,  6, 52},
+	{1040, 41,  16,  4, 61, 41,  6, 54, 31,  6, 52},
+	{1030, 41,  16,  4, 61, 41,  6, 54, 30,  6, 51},
+	{1020, 40,  16,  4, 61, 41,  6, 54, 30,  6, 51},
+	{1010, 40,  16,  4, 60, 40,  6, 53, 30,  6, 50},
+	{1000, 39,  16,  3, 60, 40,  6, 53, 29,  5, 50},
+	{ 990, 39,  15,  3, 60, 39,  6, 53, 29,  5, 49},
+	{ 980, 39,  15,  3, 59, 39,  5, 52, 29,  5, 49},
+	{ 970, 38,  15,  3, 59, 39,  5, 52, 29,  5, 48},
+	{ 960, 38,  15,  3, 59, 39,  5, 52, 29,  5, 48},
+	{ 950, 37,  15,  3, 58, 39,  5, 51, 29,  5, 47},
+	{ 940, 37,  14,  3, 58, 39,  5, 51, 29,  5, 47},
+	{ 930, 37,  14,  3, 57, 37,  5, 51, 27,  5, 46},
+	{ 920, 36,  14,  3, 57, 37,  5, 50, 27,  5, 46},
+	{ 910, 36,  14,  3, 57, 36,  5, 50, 27,  5, 45},
+	{ 900, 35,  14,  3, 56, 36,  5, 50, 26,  5, 45},
+	{ 890, 35,  14,  3, 56, 36,  5, 49, 26,  5, 44},
+	{ 880, 35,  13,  3, 56, 35,  5, 49, 26,  5, 44},
+	{ 870, 34,  13,  3, 55, 35,  4, 49, 26,  5, 43},
+	{ 860, 34,  13,  3, 55, 35,  4, 48, 25,  5, 43},
+	{ 850, 33,  13,  3, 55, 35,  4, 48, 26,  4, 42},
+	{ 840, 33,  13,  3, 54, 35,  4, 48, 26,  4, 42},
+	{ 830, 33,  12,  3, 54, 33,  4, 47, 24,  4, 41},
+	{ 820, 32,  12,  3, 54, 33,  4, 47, 24,  4, 41},
+	{ 810, 32,  12,  3, 53, 33,  4, 47, 24,  4, 40},
+	{ 800, 31,  12,  2, 53, 32,  4, 46, 23,  4, 40},
+	{ 790, 31,  12,  2, 53, 32,  4, 46, 23,  4, 39},
+	{ 780, 30,  12,  2, 52, 31,  4, 46, 23,  4, 39},
+	{ 770, 30,  11,  2, 52, 31,  4, 45, 23,  4, 39},
+	{ 760, 30,  11,  2, 52, 31,  3, 45, 22,  4, 38},
+	{ 750, 29,  11,  2, 51, 30,  3, 45, 22,  4, 38},
+	{ 740, 29,  11,  2, 51, 30,  3, 44, 22,  4, 37},
+	{ 730, 28,  11,  2, 51, 31,  3, 44, 22,  4, 37},
+	{ 720, 28,  10,  2, 50, 30,  3, 44, 22,  4, 36},
+	{ 710, 28,  10,  2, 50, 30,  3, 43, 22,  4, 36},
+	{ 700, 27,  10,  2, 50, 28,  3, 43, 20,  3, 35},
+	{ 690, 27,  10,  2, 49, 28,  3, 43, 20,  3, 35},
+	{ 680, 26,  10,  2, 49, 28,  3, 42, 20,  3, 34},
+	{ 670, 26,  10,  2, 49, 27,  3, 42, 20,  3, 34},
+	{ 660, 26,   9,  2, 48, 27,  3, 42, 19,  3, 33},
+	{ 650, 25,   9,  2, 48, 26,  3, 41, 19,  3, 33},
+	{ 640, 25,   9,  2, 48, 26,  2, 41, 19,  3, 32},
+	{ 630, 24,   9,  2, 47, 26,  2, 40, 18,  3, 32},
+	{ 620, 24,   9,  2, 47, 26,  2, 40, 19,  3, 31},
+	{ 610, 24,   8,  2, 47, 26,  2, 40, 19,  3, 31},
+	{ 600, 23,   8,  1, 46, 26,  2, 39, 18,  3, 30},
+	{ 590, 23,   8,  1, 46, 24,  2, 39, 17,  3, 30},
+	{ 580, 22,   8,  1, 46, 24,  2, 39, 17,  3, 29},
+	{ 570, 22,   8,  1, 45, 23,  2, 38, 17,  3, 29},
+	{ 560, 22,   7,  1, 45, 23,  2, 38, 16,  2, 28},
+	{ 550, 21,   7,  1, 45, 23,  2, 38, 16,  2, 28},
+	{ 540, 21,   7,  1, 44, 22,  2, 37, 16,  2, 27},
+	{ 530, 20,   7,  1, 44, 22,  1, 37, 15,  2, 27},
+	{ 520, 20,   7,  1, 43, 21,  1, 37, 15,  2, 27},
+	{ 510, 20,   6,  1, 43, 21,  1, 36, 15,  2, 26},
+	{ 500, 19,   6,  1, 43, 22,  1, 36, 15,  2, 26},
+	{ 490, 19,   6,  1, 42, 21,  1, 36, 15,  2, 25},
+	{ 480, 18,   6,  1, 42, 21,  1, 35, 15,  2, 25},
+	{ 470, 18,   6,  1, 42, 21,  1, 35, 15,  2, 24},
+	{ 460, 18,   6,  1, 41, 19,  1, 35, 13,  2, 24},
+	{ 450, 17,   5,  1, 41, 19,  1, 34, 13,  2, 23},
+	{ 440, 17,   5,  1, 41, 18,  1, 34, 13,  2, 23},
+	{ 430, 16,   5,  1, 40, 18,  0, 34, 12,  2, 22},
+	{ 420, 16,   5,  1, 40, 18,  0, 33, 12,  2, 22},
+	{ 410, 16,   5,  1, 40, 17,  0, 33, 12,  1, 21},
+	{ 400, 15,   5,  0, 39, 17,  0, 33, 11,  1, 21},
+	{ 390, 15,   4,  0, 39, 17,  0, 32, 12,  1, 20},
+	{ 380, 14,   4,  0, 39, 17,  0, 32, 12,  1, 20},
+	{ 370, 14,   4,  0, 38, 17,  0, 32, 12,  1, 19},
+	{ 360, 14,   4,  0, 38, 15,  0, 31, 10,  1, 19},
+	{ 350, 13,   4,  0, 38, 15,  0, 31, 10,  1, 18},
+	{ 340, 13,   3,  0, 37, 15,  0, 31, 10,  1, 18},
+	{ 330, 12,   3,  0, 37, 14,  0, 30,  9,  1, 17},
+	{ 320, 12,   3,  0, 37, 14,  0, 30,  9,  1, 17},
+	{ 310, 12,   3,  0, 36, 13,  0, 30,  9,  1, 16},
+	{ 300, 11,   3,  0, 36, 13,  0, 29,  8,  1, 16},
+	{ 290, 11,   2,  0, 36, 13,  0, 29,  8,  1, 15},
+	{ 280, 10,   2,  0, 35, 12,  0, 29,  8,  1, 15},
+	{ 270, 10,   2,  0, 35, 12,  0, 28,  8,  0, 14},
+	{ 260,  9,   2,  0, 35, 12,  0, 28,  8,  0, 14},
+	{ 250,  9,   2,  0, 34, 12,  0, 28,  8,  0, 14},
+	{ 240,  9,   2,  0, 34, 12,  0, 27,  8,  0, 13},
+	{ 230,  8,   1,  0, 34, 10,  0, 27,  6,  0, 13},
+	{ 220,  8,   1,  0, 33, 10,  0, 27,  6,  0, 12},
+	{ 210,  7,   1,  0, 33, 10,  0, 26,  6,  0, 12},
+	{ 200,  7,   1,  0, 33,  9,  0, 26,  5,  0, 11},
+	{ 190,  7,   1,  0, 32,  9,  0, 25,  5,  0, 11},
+	{ 180,  6,   1,  0, 32,  8,  0, 25,  5,  0, 10},
+	{ 170,  6,   0,  0, 32,  8,  0, 25,  5,  0, 10},
+	{ 160,  5,   0,  0, 31,  8,  0, 24,  4,  0,  9},
+	{ 150,  5,   0,  0, 31,  8,  0, 24,  5,  0,  9},
+	{ 140,  5,   0,  0, 31,  8,  0, 24,  5,  0,  8},
+	{ 130,  4,   0,  0, 30,  6,  0, 23,  3,  0,  8},
+	{ 120,  4,   0,  0, 30,  6,  0, 23,  3,  0,  7},
+	{ 110,  3,   0,  0, 30,  6,  0, 23,  3,  0,  7},
+	{ 100,  3,   0,  0, 29,  5,  0, 22,  2,  0,  6},
+	{  90,  3,   0,  0, 29,  5,  0, 22,  2,  0,  6},
+	{  80,  2,   0,  0, 28,  5,  0, 22,  2,  0,  5},
+};
+
+static void samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy *samsung)
+{
+	u32 bias_con2 = 0x3223;
+
+	regmap_write(samsung->regmap, BIAS_CON0, 0x0010);
+	regmap_write(samsung->regmap, BIAS_CON1, 0x0110);
+	regmap_write(samsung->regmap, BIAS_CON2, bias_con2);
+
+	/* default output voltage select:
+	 * dphy: 400mv
+	 * cphy: 530mv
+	 */
+	regmap_update_bits(samsung->regmap, BIAS_CON4,
+			   I_MUX_SEL_MASK, I_MUX_SEL_400MV);
+}
+
+static void samsung_mipi_dphy_lane_enable(struct samsung_mipi_dcphy *samsung)
+{
+	regmap_write(samsung->regmap, DPHY_MC_GNR_CON1, T_PHY_READY(0x2000));
+	regmap_update_bits(samsung->regmap, DPHY_MC_GNR_CON0,
+			   PHY_ENABLE, PHY_ENABLE);
+
+	switch (samsung->lanes) {
+	case 4:
+		regmap_write(samsung->regmap, DPHY_MD3_GNR_CON1,
+			     T_PHY_READY(0x2000));
+		regmap_update_bits(samsung->regmap, DPHY_MD3_GNR_CON0,
+				   PHY_ENABLE, PHY_ENABLE);
+		fallthrough;
+	case 3:
+		regmap_write(samsung->regmap, COMBO_MD2_GNR_CON1,
+			     T_PHY_READY(0x2000));
+		regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0,
+				   PHY_ENABLE, PHY_ENABLE);
+		fallthrough;
+	case 2:
+		regmap_write(samsung->regmap, COMBO_MD1_GNR_CON1,
+			     T_PHY_READY(0x2000));
+		regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0,
+				   PHY_ENABLE, PHY_ENABLE);
+		fallthrough;
+	case 1:
+	default:
+		regmap_write(samsung->regmap, COMBO_MD0_GNR_CON1,
+			     T_PHY_READY(0x2000));
+		regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0,
+				   PHY_ENABLE, PHY_ENABLE);
+		break;
+	}
+}
+
+static void samsung_mipi_dphy_lane_disable(struct samsung_mipi_dcphy *samsung)
+{
+	regmap_update_bits(samsung->regmap, DPHY_MC_GNR_CON0, PHY_ENABLE, 0);
+	regmap_update_bits(samsung->regmap, COMBO_MD0_GNR_CON0, PHY_ENABLE, 0);
+	regmap_update_bits(samsung->regmap, COMBO_MD1_GNR_CON0, PHY_ENABLE, 0);
+	regmap_update_bits(samsung->regmap, COMBO_MD2_GNR_CON0, PHY_ENABLE, 0);
+	regmap_update_bits(samsung->regmap, DPHY_MD3_GNR_CON0, PHY_ENABLE, 0);
+}
+
+static void samsung_mipi_dcphy_pll_configure(struct samsung_mipi_dcphy *samsung)
+{
+	regmap_update_bits(samsung->regmap, PLL_CON0, S_MASK | P_MASK,
+			   S(samsung->pll.scaler) | P(samsung->pll.prediv));
+
+	if (samsung->pll.dsm < 0) {
+		u16 dsm_tmp;
+
+		/* Using opposite number subtraction to find complement */
+		dsm_tmp = abs(samsung->pll.dsm);
+		dsm_tmp = dsm_tmp - 1;
+		dsm_tmp ^= 0xffff;
+		regmap_write(samsung->regmap, PLL_CON1, dsm_tmp);
+	} else {
+		regmap_write(samsung->regmap, PLL_CON1, samsung->pll.dsm);
+	}
+
+	regmap_update_bits(samsung->regmap, PLL_CON2,
+			   M_MASK, M(samsung->pll.fbdiv));
+
+	if (samsung->pll.ssc_en) {
+		regmap_write(samsung->regmap, PLL_CON3,
+			     MRR(samsung->pll.mrr) | MFR(samsung->pll.mfr));
+		regmap_update_bits(samsung->regmap, PLL_CON4, SSCG_EN, SSCG_EN);
+	}
+
+	regmap_write(samsung->regmap, PLL_CON5, RESET_N_SEL | PLL_ENABLE_SEL);
+	regmap_write(samsung->regmap, PLL_CON7, PLL_LOCK_CNT(0xf000));
+	regmap_write(samsung->regmap, PLL_CON8, PLL_STB_CNT(0xf000));
+}
+
+static int samsung_mipi_dcphy_pll_enable(struct samsung_mipi_dcphy *samsung)
+{
+	u32 sts;
+	int ret;
+
+	regmap_update_bits(samsung->regmap, PLL_CON0, PLL_EN, PLL_EN);
+
+	ret = regmap_read_poll_timeout(samsung->regmap, PLL_STAT0,
+				       sts, (sts & PLL_LOCK), 1000, 20000);
+	if (ret < 0)
+		dev_err(samsung->dev, "DC-PHY pll failed to lock\n");
+
+	return ret;
+}
+
+static void samsung_mipi_dcphy_pll_disable(struct samsung_mipi_dcphy *samsung)
+{
+	regmap_update_bits(samsung->regmap, PLL_CON0, PLL_EN, 0);
+}
+
+static const struct samsung_mipi_dphy_timing *
+samsung_mipi_dphy_get_timing(struct samsung_mipi_dcphy *samsung)
+{
+	const struct samsung_mipi_dphy_timing *timings;
+	unsigned int num_timings;
+	unsigned int lane_mbps = div64_ul(samsung->pll.rate, USEC_PER_SEC);
+	unsigned int i;
+
+	timings = samsung_mipi_dphy_timing_table;
+	num_timings = ARRAY_SIZE(samsung_mipi_dphy_timing_table);
+
+	for (i = num_timings; i > 1; i--)
+		if (lane_mbps <= timings[i - 1].max_lane_mbps)
+			break;
+
+	return &timings[i - 1];
+}
+
+static unsigned long
+samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy *samsung,
+				  unsigned long prate, unsigned long rate,
+				  u8 *prediv, u16 *fbdiv, int *dsm, u8 *scaler)
+{
+	u32 max_fout = samsung->pdata->dphy_tx_max_lane_kbps;
+	u64 best_freq = 0;
+	u64 fin, fvco, fout;
+	u8 min_prediv, max_prediv;
+	u8 _prediv, best_prediv = 1;
+	u16 _fbdiv, best_fbdiv = 1;
+	u8 _scaler, best_scaler = 0;
+	u32 min_delta = UINT_MAX;
+	long _dsm, best_dsm = 0;
+
+	if (!prate) {
+		dev_err(samsung->dev, "parent rate of PLL can not be zero\n");
+		return 0;
+	}
+
+	/*
+	 * The PLL output frequency can be calculated using a simple formula:
+	 * Fvco = ((m+k/65536) x 2 x Fin) / p
+	 * Fout = ((m+k/65536) x 2 x Fin) / (p x 2^s)
+	 */
+	fin = div64_ul(prate, MSEC_PER_SEC);
+
+	while (!best_freq) {
+		fout = div64_ul(rate, MSEC_PER_SEC);
+		if (fout > max_fout)
+			fout = max_fout;
+
+		/* 0 ? S[2:0] ? 6 */
+		for (_scaler = 0; _scaler < 7; _scaler++) {
+			fvco = fout << _scaler;
+
+			/*
+			 * 2600MHz ? FVCO ? 6600MHz
+			 */
+			if (fvco < 2600 * MSEC_PER_SEC || fvco > 6600 * MSEC_PER_SEC)
+				continue;
+
+			/* 6MHz ? Fref(Fin / p) ? 30MHz */
+			min_prediv = DIV_ROUND_UP_ULL(fin, 30 * MSEC_PER_SEC);
+			max_prediv = DIV_ROUND_CLOSEST_ULL(fin, 6 * MSEC_PER_SEC);
+
+			for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
+				u64 delta, tmp;
+
+				_fbdiv = DIV_ROUND_CLOSEST_ULL(fvco * _prediv, 2 * fin);
+
+				 /* 64 ? M[9:0] ? 1023 */
+				if (_fbdiv < 64 || _fbdiv > 1023)
+					continue;
+
+				/* -32767 ? K[15:0] ? 32767 */
+				_dsm = ((_prediv * fvco) - (2 * _fbdiv * fin));
+				_dsm = DIV_ROUND_UP_ULL(_dsm << 15, fin);
+				if (abs(_dsm) > 32767)
+					continue;
+
+				tmp = DIV_ROUND_CLOSEST_ULL((_fbdiv * fin * 2 * 1000), _prediv);
+				tmp += DIV_ROUND_CLOSEST_ULL((_dsm * fin * 1000), _prediv << 15);
+
+				delta = abs(fvco * MSEC_PER_SEC - tmp);
+				if (delta < min_delta) {
+					best_prediv = _prediv;
+					best_fbdiv = _fbdiv;
+					best_dsm = _dsm;
+					best_scaler = _scaler;
+					min_delta = delta;
+					best_freq = DIV_ROUND_CLOSEST_ULL(tmp, 1000) * MSEC_PER_SEC;
+				}
+			}
+		}
+
+		rate += 100 * MSEC_PER_SEC;
+	}
+
+	*prediv = best_prediv;
+	*fbdiv = best_fbdiv;
+	*dsm = (int)best_dsm & 0xffff;
+	*scaler = best_scaler;
+	dev_dbg(samsung->dev, "p: %d, m: %d, dsm:%ld, scaler: %d\n",
+		best_prediv, best_fbdiv, best_dsm, best_scaler);
+
+	return best_freq >> best_scaler;
+}
+
+static void
+samsung_mipi_dphy_clk_lane_timing_init(struct samsung_mipi_dcphy *samsung)
+{
+	const struct samsung_mipi_dphy_timing *timing;
+	unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
+	u32 val, res_up, res_down;
+
+	timing = samsung_mipi_dphy_get_timing(samsung);
+	regmap_write(samsung->regmap, DPHY_MC_GNR_CON0, 0xf000);
+
+	/*
+	 * The Drive-Strength / Voltage-Amplitude is adjusted by setting
+	 * the Driver-Up Resistor and Driver-Down Resistor.
+	 */
+	res_up = samsung->pdata->dphy_hs_drv_res_cfg->clk_hs_drv_up_ohm;
+	res_down = samsung->pdata->dphy_hs_drv_res_cfg->clk_hs_drv_down_ohm;
+	val = EDGE_CON(7) | EDGE_CON_DIR(0) | EDGE_CON_EN |
+	      RES_UP(res_up) | RES_DN(res_down);
+	regmap_write(samsung->regmap, DPHY_MC_ANA_CON0, val);
+
+	if (lane_hs_rate >= 4500)
+		regmap_write(samsung->regmap, DPHY_MC_ANA_CON1, 0x0001);
+
+	val = 0;
+	/*
+	 * Divide-by-2 Clock from Serial Clock. Use this when data rate is under
+	 * 1500Mbps, otherwise divide-by-16 Clock from Serial Clock
+	 */
+	if (lane_hs_rate < 1500)
+		val = HSTX_CLK_SEL;
+
+	val |= T_LPX(timing->lpx);
+	/*  T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
+	regmap_write(samsung->regmap, DPHY_MC_TIME_CON0, val);
+
+	val = T_CLK_ZERO(timing->clk_zero) | T_CLK_PREPARE(timing->clk_prepare);
+	regmap_write(samsung->regmap, DPHY_MC_TIME_CON1, val);
+
+	val = T_HS_EXIT(timing->hs_exit) | T_CLK_TRAIL(timing->clk_trail_eot);
+	regmap_write(samsung->regmap, DPHY_MC_TIME_CON2, val);
+
+	val = T_CLK_POST(timing->clk_post);
+	regmap_write(samsung->regmap, DPHY_MC_TIME_CON3, val);
+
+	/* Escape Clock is 20.00MHz */
+	regmap_write(samsung->regmap, DPHY_MC_TIME_CON4, 0x1f4);
+
+	/*
+	 * skew calibration should be off, if the operation data rate is
+	 * under 1.5Gbps or equal to 1.5Gbps.
+	 */
+	if (lane_hs_rate > 1500)
+		regmap_write(samsung->regmap, DPHY_MC_DESKEW_CON0, 0x9cb1);
+}
+
+static void
+samsung_mipi_dphy_data_lane_timing_init(struct samsung_mipi_dcphy *samsung)
+{
+	const struct samsung_mipi_dphy_timing *timing;
+	unsigned int lane_hs_rate = div64_ul(samsung->pll.rate, USEC_PER_SEC);
+	u32 val, res_up, res_down;
+
+	timing = samsung_mipi_dphy_get_timing(samsung);
+
+	/*
+	 * The Drive-Strength / Voltage-Amplitude is adjusted by adjusting the
+	 *  Driver-Up Resistor and Driver-Down Resistor.
+	 */
+	res_up = samsung->pdata->dphy_hs_drv_res_cfg->data_hs_drv_up_ohm;
+	res_down = samsung->pdata->dphy_hs_drv_res_cfg->data_hs_drv_down_ohm;
+	val = EDGE_CON(7) | EDGE_CON_DIR(0) | EDGE_CON_EN |
+	      RES_UP(res_up) | RES_DN(res_down);
+	regmap_write(samsung->regmap, COMBO_MD0_ANA_CON0, val);
+	regmap_write(samsung->regmap, COMBO_MD1_ANA_CON0, val);
+	regmap_write(samsung->regmap, COMBO_MD2_ANA_CON0, val);
+	regmap_write(samsung->regmap, DPHY_MD3_ANA_CON0, val);
+
+	if (lane_hs_rate >= 4500) {
+		regmap_write(samsung->regmap, COMBO_MD0_ANA_CON1, 0x0001);
+		regmap_write(samsung->regmap, COMBO_MD1_ANA_CON1, 0x0001);
+		regmap_write(samsung->regmap, COMBO_MD2_ANA_CON1, 0x0001);
+		regmap_write(samsung->regmap, DPHY_MD3_ANA_CON1, 0x0001);
+	}
+
+	val = 0;
+	/*
+	 * Divide-by-2 Clock from Serial Clock. Use this when data rate is under
+	 * 1500Mbps, otherwise divide-by-16 Clock from Serial Clock
+	 */
+	if (lane_hs_rate < 1500)
+		val = HSTX_CLK_SEL;
+
+	val |= T_LPX(timing->lpx);
+	/*  T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
+	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON0, val);
+	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON0, val);
+	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON0, val);
+	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON0, val);
+
+	val = T_HS_ZERO(timing->hs_zero) | T_HS_PREPARE(timing->hs_prepare);
+	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON1, val);
+	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON1, val);
+	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON1, val);
+	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON1, val);
+
+	val = T_HS_EXIT(timing->hs_exit) | T_HS_TRAIL(timing->hs_trail_eot);
+	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON2, val);
+	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON2, val);
+	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON2, val);
+	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON2, val);
+
+	/* TTA-GET/TTA-GO Timing Counter register use default value */
+	val = T_TA_GET(0x3) | T_TA_GO(0x0);
+	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON3, val);
+	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON3, val);
+	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON3, val);
+	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON3, val);
+
+	/* Escape Clock is 20.00MHz */
+	regmap_write(samsung->regmap, COMBO_MD0_TIME_CON4, 0x1f4);
+	regmap_write(samsung->regmap, COMBO_MD1_TIME_CON4, 0x1f4);
+	regmap_write(samsung->regmap, COMBO_MD2_TIME_CON4, 0x1f4);
+	regmap_write(samsung->regmap, DPHY_MD3_TIME_CON4, 0x1f4);
+}
+
+static int samsung_mipi_dphy_power_on(struct samsung_mipi_dcphy *samsung)
+{
+	int ret;
+
+	reset_control_assert(samsung->m_phy_rst);
+
+	samsung_mipi_dcphy_bias_block_enable(samsung);
+	samsung_mipi_dcphy_pll_configure(samsung);
+	samsung_mipi_dphy_clk_lane_timing_init(samsung);
+	samsung_mipi_dphy_data_lane_timing_init(samsung);
+	ret = samsung_mipi_dcphy_pll_enable(samsung);
+	if (ret < 0)
+		return ret;
+
+	samsung_mipi_dphy_lane_enable(samsung);
+
+	reset_control_deassert(samsung->m_phy_rst);
+
+	/* The TSKEWCAL maximum is 100 ?sec
+	 * at initial calibration.
+	 */
+	usleep_range(100, 110);
+
+	return 0;
+}
+
+static int samsung_mipi_dcphy_power_on(struct phy *phy)
+{
+	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
+
+	reset_control_assert(samsung->apb_rst);
+	udelay(1);
+	reset_control_deassert(samsung->apb_rst);
+
+	switch (samsung->type) {
+	case PHY_TYPE_DPHY:
+		return samsung_mipi_dphy_power_on(samsung);
+	default:
+		/* CPHY part to be implemented later */
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int samsung_mipi_dcphy_power_off(struct phy *phy)
+{
+	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
+
+	switch (samsung->type) {
+	case PHY_TYPE_DPHY:
+		samsung_mipi_dphy_lane_disable(samsung);
+		break;
+	default:
+		/* CPHY part to be implemented later */
+		return -EOPNOTSUPP;
+	}
+
+	samsung_mipi_dcphy_pll_disable(samsung);
+
+	return 0;
+}
+
+static int
+samsung_mipi_dcphy_pll_ssc_modulation_calc(struct samsung_mipi_dcphy *samsung,
+					   u8 *mfr, u8 *mrr)
+{
+	unsigned long fin = div64_ul(clk_get_rate(samsung->ref_clk), MSEC_PER_SEC);
+	u16 prediv = samsung->pll.prediv;
+	u16 fbdiv = samsung->pll.fbdiv;
+	u16 min_mfr, max_mfr;
+	u16 _mfr, best_mfr = 0;
+	u16 mr, _mrr, best_mrr = 0;
+
+	/* 20KHz ? MF ? 150KHz */
+	max_mfr = DIV_ROUND_UP(fin, (20 * prediv) << 5);
+	min_mfr = div64_ul(fin, ((150 * prediv) << 5));
+	/*0 ? mfr ? 255 */
+	if (max_mfr > 256)
+		max_mfr = 256;
+
+	for (_mfr = min_mfr; _mfr < max_mfr; _mfr++) {
+		/* 1 ? mrr ? 31 */
+		for (_mrr = 1; _mrr < 32; _mrr++) {
+			mr = DIV_ROUND_UP(_mfr * _mrr * 100, fbdiv << 6);
+			/* 0 ? MR ? 5% */
+			if (mr > 5)
+				continue;
+
+			if (_mfr * _mrr < 513) {
+				best_mfr = _mfr;
+				best_mrr = _mrr;
+				break;
+			}
+		}
+	}
+
+	if (best_mrr) {
+		*mfr = best_mfr & 0xff;
+		*mrr = best_mrr & 0x3f;
+	} else {
+		dev_err(samsung->dev, "failed to calc ssc parameter mfr and mrr\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void
+samsung_mipi_dcphy_pll_calc_rate(struct samsung_mipi_dcphy *samsung,
+				 unsigned long long rate)
+{
+	unsigned long prate = clk_get_rate(samsung->ref_clk);
+	unsigned long fout;
+	u8 scaler = 0, mfr = 0, mrr = 0;
+	u16 fbdiv = 0;
+	u8 prediv = 1;
+	int dsm = 0;
+	int ret;
+
+	fout = samsung_mipi_dcphy_pll_round_rate(samsung, prate, rate,
+						 &prediv, &fbdiv, &dsm,
+						 &scaler);
+
+	dev_dbg(samsung->dev, "%s: fin=%lu, req_rate=%llu\n",
+		__func__, prate, rate);
+	dev_dbg(samsung->dev, "%s: fout=%lu, prediv=%u, fbdiv=%u\n",
+		__func__, fout, prediv, fbdiv);
+
+	samsung->pll.prediv = prediv;
+	samsung->pll.fbdiv = fbdiv;
+	samsung->pll.dsm = dsm;
+	samsung->pll.scaler = scaler;
+	samsung->pll.rate = fout;
+
+	/*
+	 * All DPHY 2.0 compliant Transmitters shall support SSC operating above
+	 * 2.5 Gbps
+	 */
+	if (fout > 2500000000LL) {
+		ret = samsung_mipi_dcphy_pll_ssc_modulation_calc(samsung,
+								 &mfr, &mrr);
+		if (!ret) {
+			samsung->pll.ssc_en = true;
+			samsung->pll.mfr = mfr;
+			samsung->pll.mrr = mrr;
+		}
+	}
+}
+
+static int samsung_mipi_dcphy_configure(struct phy *phy,
+					union phy_configure_opts *opts)
+{
+	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
+	unsigned long long target_rate = opts->mipi_dphy.hs_clk_rate;
+
+	samsung->lanes = opts->mipi_dphy.lanes > 4 ? 4 : opts->mipi_dphy.lanes;
+
+	samsung_mipi_dcphy_pll_calc_rate(samsung, target_rate);
+	opts->mipi_dphy.hs_clk_rate = samsung->pll.rate;
+
+	return 0;
+}
+
+static int samsung_mipi_dcphy_init(struct phy *phy)
+{
+	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
+
+	return pm_runtime_resume_and_get(samsung->dev);
+}
+
+static int samsung_mipi_dcphy_exit(struct phy *phy)
+{
+	struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
+
+	return pm_runtime_put(samsung->dev);
+}
+
+static const struct phy_ops samsung_mipi_dcphy_ops = {
+	.configure = samsung_mipi_dcphy_configure,
+	.power_on  = samsung_mipi_dcphy_power_on,
+	.power_off = samsung_mipi_dcphy_power_off,
+	.init = samsung_mipi_dcphy_init,
+	.exit = samsung_mipi_dcphy_exit,
+	.owner	   = THIS_MODULE,
+};
+
+static const struct regmap_config samsung_mipi_dcphy_regmap_config = {
+	.name = "dcphy",
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = 0x10000,
+};
+
+static struct phy *samsung_mipi_dcphy_xlate(struct device *dev,
+					    const struct of_phandle_args *args)
+{
+	struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev);
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of arguments\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (samsung->type != PHY_NONE && samsung->type != args->args[0])
+		dev_warn(dev, "phy type select %d overwriting type %d\n",
+			 args->args[0], samsung->type);
+
+	samsung->type = args->args[0];
+
+	return samsung->phy;
+}
+
+static int samsung_mipi_dcphy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct samsung_mipi_dcphy *samsung;
+	struct phy_provider *phy_provider;
+	struct resource *res;
+	void __iomem *regs;
+	int ret;
+
+	samsung = devm_kzalloc(dev, sizeof(*samsung), GFP_KERNEL);
+	if (!samsung)
+		return -ENOMEM;
+
+	samsung->dev = dev;
+	samsung->pdata = device_get_match_data(dev);
+	platform_set_drvdata(pdev, samsung);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	samsung->regmap = devm_regmap_init_mmio(dev, regs,
+						&samsung_mipi_dcphy_regmap_config);
+	if (IS_ERR(samsung->regmap))
+		return dev_err_probe(dev, PTR_ERR(samsung->regmap), "Failed to init regmap\n");
+
+	samsung->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(samsung->grf_regmap))
+		return dev_err_probe(dev, PTR_ERR(samsung->grf_regmap),
+				     "Unable to get rockchip,grf\n");
+
+	samsung->ref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(samsung->ref_clk))
+		return dev_err_probe(dev, PTR_ERR(samsung->ref_clk),
+				     "Failed to get reference clock\n");
+
+	samsung->pclk = devm_clk_get(dev, "pclk");
+	if (IS_ERR(samsung->pclk))
+		return dev_err_probe(dev, PTR_ERR(samsung->pclk), "Failed to get pclk\n");
+
+	samsung->m_phy_rst = devm_reset_control_get(dev, "m_phy");
+	if (IS_ERR(samsung->m_phy_rst))
+		return dev_err_probe(dev, PTR_ERR(samsung->m_phy_rst),
+				     "Failed to get system m_phy_rst control\n");
+
+	samsung->s_phy_rst = devm_reset_control_get(dev, "s_phy");
+	if (IS_ERR(samsung->s_phy_rst))
+		return dev_err_probe(dev, PTR_ERR(samsung->s_phy_rst),
+				     "Failed to get system s_phy_rst control\n");
+
+	samsung->apb_rst = devm_reset_control_get(dev, "apb");
+	if (IS_ERR(samsung->apb_rst))
+		return dev_err_probe(dev, PTR_ERR(samsung->apb_rst),
+				     "Failed to get system apb_rst control\n");
+
+	samsung->grf_apb_rst = devm_reset_control_get(dev, "grf");
+	if (IS_ERR(samsung->grf_apb_rst))
+		return dev_err_probe(dev, PTR_ERR(samsung->grf_apb_rst),
+				     "Failed to get system grf_apb_rst control\n");
+
+	samsung->phy = devm_phy_create(dev, NULL, &samsung_mipi_dcphy_ops);
+	if (IS_ERR(samsung->phy))
+		return dev_err_probe(dev, PTR_ERR(samsung->phy), "Failed to create MIPI DC-PHY\n");
+
+	phy_set_drvdata(samsung->phy, samsung);
+
+	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, samsung_mipi_dcphy_xlate);
+	if (IS_ERR(phy_provider))
+		return dev_err_probe(dev, PTR_ERR(phy_provider),
+				     "Failed to register phy provider\n");
+
+	return 0;
+}
+
+static __maybe_unused int samsung_mipi_dcphy_runtime_suspend(struct device *dev)
+{
+	struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(samsung->pclk);
+	clk_disable_unprepare(samsung->ref_clk);
+
+	return 0;
+}
+
+static __maybe_unused int samsung_mipi_dcphy_runtime_resume(struct device *dev)
+{
+	struct samsung_mipi_dcphy *samsung = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(samsung->pclk);
+	if (ret) {
+		dev_err(samsung->dev, "Failed to enable pclk, %d\n", ret);
+		return ret;
+	}
+
+	clk_prepare_enable(samsung->ref_clk);
+	if (ret) {
+		dev_err(samsung->dev, "Failed to enable reference clock, %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops samsung_mipi_dcphy_pm_ops = {
+	SET_RUNTIME_PM_OPS(samsung_mipi_dcphy_runtime_suspend,
+			   samsung_mipi_dcphy_runtime_resume, NULL)
+};
+
+static const struct hs_drv_res_cfg rk3576_dphy_hs_drv_res_cfg = {
+	.clk_hs_drv_up_ohm = STRENGTH_52_OHM,
+	.clk_hs_drv_down_ohm = STRENGTH_52_OHM,
+	.data_hs_drv_up_ohm = STRENGTH_39_OHM,
+	.data_hs_drv_down_ohm = STRENGTH_39_OHM,
+};
+
+static const struct hs_drv_res_cfg rk3588_dphy_hs_drv_res_cfg = {
+	.clk_hs_drv_up_ohm = STRENGTH_34_OHM,
+	.clk_hs_drv_down_ohm = STRENGTH_34_OHM,
+	.data_hs_drv_up_ohm = STRENGTH_43_OHM,
+	.data_hs_drv_down_ohm = STRENGTH_43_OHM,
+};
+
+static const struct samsung_mipi_dcphy_plat_data rk3576_samsung_mipi_dcphy_plat_data = {
+	.dphy_hs_drv_res_cfg = &rk3576_dphy_hs_drv_res_cfg,
+	.dphy_tx_max_lane_kbps = 2500000L,
+};
+
+static const struct samsung_mipi_dcphy_plat_data rk3588_samsung_mipi_dcphy_plat_data = {
+	.dphy_hs_drv_res_cfg = &rk3588_dphy_hs_drv_res_cfg,
+	.dphy_tx_max_lane_kbps = 4500000L,
+};
+
+static const struct of_device_id samsung_mipi_dcphy_of_match[] = {
+	{
+		.compatible = "rockchip,rk3576-mipi-dcphy",
+		.data = &rk3576_samsung_mipi_dcphy_plat_data,
+	}, {
+		.compatible = "rockchip,rk3588-mipi-dcphy",
+		.data = &rk3588_samsung_mipi_dcphy_plat_data,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, samsung_mipi_dcphy_of_match);
+
+static struct platform_driver samsung_mipi_dcphy_driver = {
+	.driver = {
+		.name = "samsung-mipi-dcphy",
+		.of_match_table	= samsung_mipi_dcphy_of_match,
+		.pm = &samsung_mipi_dcphy_pm_ops,
+	},
+	.probe	= samsung_mipi_dcphy_probe,
+};
+module_platform_driver(samsung_mipi_dcphy_driver);
+
+MODULE_AUTHOR("Guochun Huang <hero.huang at rock-chips.com>");
+MODULE_DESCRIPTION("Samsung MIPI DCPHY Driver");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From eballetb at redhat.com  Tue Dec  3 08:51:33 2024
From: eballetb at redhat.com (Enric Balletbo i Serra)
Date: Tue, 3 Dec 2024 17:51:33 +0100
Subject: [PATCH 0/2] Enable PCIe Multilink and USB support in Cadence
 Torrent SERDES driver
In-Reply-To: <20240615093433.3659829-1-s-vadapalli@ti.com>
References: <20240615093433.3659829-1-s-vadapalli@ti.com>
Message-ID: <CALE0LRssDPn2UAscbCdx2UsO3cQYuYHpBsdGxEWje9LCf4Hr4w@mail.gmail.com>

Hi Siddharth,

On Sat, Jun 15, 2024 at 11:35?AM Siddharth Vadapalli <s-vadapalli at ti.com> wrote:
>
> Hello,
>
> This series adds support for standalone PCIe Multilink configuration
> along with the support for PCIe Multilink + USB configuration in the
> Torrent SERDES driver.
>
> Series is based on linux-next tagged next-20240613.
>

Seems that these series didn't land, I think they are still required
for the AM69-SK board? There is any chance that it could be rebased
and resend?

Thanks,
  Enric

> Regards,
> Siddharth.
>
> Swapnil Jakhade (2):
>   phy: cadence-torrent: Add PCIe multilink configuration for 100MHz
>     refclk
>   phy: cadence-torrent: Add PCIe multilink + USB with same SSC register
>     config for 100 MHz refclk
>
>  drivers/phy/cadence/phy-cadence-torrent.c | 276 ++++++++++++++++++++--
>  1 file changed, 257 insertions(+), 19 deletions(-)
>
> --
> 2.40.1
>
>



From heiko at sntech.de  Tue Dec  3 08:54:48 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 17:54:48 +0100
Subject: [PATCH v3 2/3] dt-bindings: display: rockchip: Add schema for RK3588 DW DSI2 controller
In-Reply-To: <20241203165450.1501219-1-heiko@sntech.de>
References: <20241203165450.1501219-1-heiko@sntech.de>
Message-ID: <20241203165450.1501219-3-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

The Display Serial Interface 2 (DSI-2) is part of a group of communication
protocols defined by the MIPI Alliance. The RK3588 implements this
specification in its two MIPI DSI-2 Host Controllers that are based on a
new Synopsis IP.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 .../rockchip/rockchip,rk3588-mipi-dsi2.yaml   | 119 ++++++++++++++++++
 1 file changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml
new file mode 100644
index 000000000000..7c017e927223
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.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/rockchip/rockchip,rk3588-mipi-dsi2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip specific extensions to the Synopsys Designware MIPI DSI2
+
+maintainers:
+  - Heiko Stuebner <heiko at sntech.de>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3588-mipi-dsi2
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: sys
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      This SoC uses GRF regs to switch between vopl/vopb.
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: dcphy
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: apb
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Input node to receive pixel data.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: DSI output node to panel.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - rockchip,grf
+  - phys
+  - phy-names
+  - ports
+  - reg
+
+allOf:
+  - $ref: /schemas/display/dsi-controller.yaml#
+
+unevaluatedProperties: 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>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      dsi at fde20000 {
+        compatible = "rockchip,rk3588-mipi-dsi2";
+        reg = <0x0 0xfde20000 0x0 0x10000>;
+        interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&cru PCLK_DSIHOST0>, <&cru CLK_DSIHOST0>;
+        clock-names = "pclk", "sys";
+        resets = <&cru SRST_P_DSIHOST0>;
+        reset-names = "apb";
+        power-domains = <&power RK3588_PD_VOP>;
+        phys = <&mipidcphy0>;
+        phy-names = "dcphy";
+        rockchip,grf = <&vop_grf>;
+
+        ports {
+          #address-cells = <1>;
+          #size-cells = <0>;
+          dsi0_in: port at 0 {
+            reg = <0>;
+          };
+
+          dsi0_out: port at 1 {
+            reg = <1>;
+          };
+        };
+      };
+    };
-- 
2.45.2



From heiko at sntech.de  Tue Dec  3 08:54:49 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 17:54:49 +0100
Subject: [PATCH v3 3/3] drm/rockchip: Add MIPI DSI2 glue driver for RK3588
In-Reply-To: <20241203165450.1501219-1-heiko@sntech.de>
References: <20241203165450.1501219-1-heiko@sntech.de>
Message-ID: <20241203165450.1501219-4-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

This adds the glue code for the MIPI DSI2 bridge on Rockchip SoCs and
enables its use on the RK3588.

Right now the DSI2 controller is always paired with a DC-phy based on a
Samsung IP, so the interface values are set statically for now.
This stays true for the upcoming RK3576 as well.

Tested-by: Daniel Semkowicz <dse at thaumatec.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 drivers/gpu/drm/rockchip/Kconfig              |  10 +
 drivers/gpu/drm/rockchip/Makefile             |   1 +
 .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c  | 524 ++++++++++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |   2 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |   1 +
 5 files changed, 538 insertions(+)
 create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 448fadd4ba15..84af423b7f90 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -10,6 +10,7 @@ config DRM_ROCKCHIP
 	select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
 	select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP
 	select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
+	select DRM_DW_MIPI_DSI2 if ROCKCHIP_DW_MIPI_DSI2
 	select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
 	select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
 	select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
@@ -81,6 +82,15 @@ config ROCKCHIP_DW_MIPI_DSI
 	  enable MIPI DSI on RK3288 or RK3399 based SoC, you should
 	  select this option.
 
+config ROCKCHIP_DW_MIPI_DSI2
+	bool "Rockchip specific extensions for Synopsys DW MIPI DSI2"
+	select GENERIC_PHY_MIPI_DPHY
+	help
+	  This selects support for Rockchip SoC specific extensions
+	  for the Synopsys DesignWare dsi driver. If you want to
+	  enable MIPI DSI on RK3576 or RK3588 based SoC, you should
+	  select this option.
+
 config ROCKCHIP_INNO_HDMI
 	bool "Rockchip specific extensions for Innosilicon HDMI"
 	select DRM_DISPLAY_HDMI_HELPER
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index 3eab662a5a1d..2b867cebbc12 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -13,6 +13,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o
+rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI2) += dw-mipi-dsi2-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
 rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
 rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
new file mode 100644
index 000000000000..55eed4001634
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
@@ -0,0 +1,524 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Rockchip Electronics Co.Ltd
+ * Author:
+ *      Guochun Huang <hero.huang at rock-chips.com>
+ *      Heiko Stuebner <heiko.stuebner at cherry.de>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/media-bus-format.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/mfd/syscon.h>
+#include <linux/phy/phy.h>
+
+#include <drm/bridge/dw_mipi_dsi2.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
+#include <drm/drm_simple_kms_helper.h>
+
+#include <uapi/linux/videodev2.h>
+
+#include "rockchip_drm_drv.h"
+#include "rockchip_drm_vop.h"
+
+#define PSEC_PER_SEC			1000000000000LL
+
+struct dsigrf_reg {
+	u16 offset;
+	u16 lsb;
+	u16 msb;
+};
+
+enum grf_reg_fields {
+	TXREQCLKHS_EN,
+	GATING_EN,
+	IPI_SHUTDN,
+	IPI_COLORM,
+	IPI_COLOR_DEPTH,
+	IPI_FORMAT,
+	MAX_FIELDS,
+};
+
+#define IPI_DEPTH_5_6_5_BITS		0x02
+#define IPI_DEPTH_6_BITS		0x03
+#define IPI_DEPTH_8_BITS		0x05
+#define IPI_DEPTH_10_BITS		0x06
+
+struct rockchip_dw_dsi2_chip_data {
+	u32 reg;
+	const struct dsigrf_reg *grf_regs;
+	unsigned long long max_bit_rate_per_lane;
+};
+
+struct dw_mipi_dsi2_rockchip {
+	struct device *dev;
+	struct rockchip_encoder encoder;
+	struct regmap *regmap;
+	struct clk *pclk;
+	struct clk *sys_clk;
+
+	unsigned int lane_mbps; /* per lane */
+	u32 format;
+
+	struct regmap *grf_regmap;
+	struct phy *phy;
+	union phy_configure_opts phy_opts;
+
+	struct dw_mipi_dsi2 *dmd;
+	struct dw_mipi_dsi2_plat_data pdata;
+	const struct rockchip_dw_dsi2_chip_data *cdata;
+};
+
+static inline struct dw_mipi_dsi2_rockchip *to_dsi2(struct drm_encoder *encoder)
+{
+	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
+
+	return container_of(rkencoder, struct dw_mipi_dsi2_rockchip, encoder);
+}
+
+static void grf_field_write(struct dw_mipi_dsi2_rockchip *dsi2, enum grf_reg_fields index,
+			    unsigned int val)
+{
+	const struct dsigrf_reg *field = &dsi2->cdata->grf_regs[index];
+
+	if (!field)
+		return;
+
+	regmap_write(dsi2->grf_regmap, field->offset,
+		     (val << field->lsb) | (GENMASK(field->msb, field->lsb) << 16));
+}
+
+static int dw_mipi_dsi2_phy_init(void *priv_data)
+{
+	return 0;
+}
+
+static void dw_mipi_dsi2_phy_power_on(void *priv_data)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+	int ret;
+
+	ret = phy_set_mode(dsi2->phy, PHY_MODE_MIPI_DPHY);
+	if (ret) {
+		dev_err(dsi2->dev, "Failed to set phy mode: %d\n", ret);
+		return;
+	}
+
+	phy_configure(dsi2->phy, &dsi2->phy_opts);
+	phy_power_on(dsi2->phy);
+}
+
+static void dw_mipi_dsi2_phy_power_off(void *priv_data)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+
+	phy_power_off(dsi2->phy);
+}
+
+static int
+dw_mipi_dsi2_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
+			   unsigned long mode_flags, u32 lanes, u32 format,
+			   unsigned int *lane_mbps)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+	u64 max_lane_rate, target_phyclk;
+	unsigned int lane_rate_kbps;
+	int bpp;
+
+	max_lane_rate = dsi2->cdata->max_bit_rate_per_lane;
+
+	dsi2->format = format;
+	bpp = mipi_dsi_pixel_format_to_bpp(format);
+	if (bpp < 0) {
+		dev_err(dsi2->dev, "failed to get bpp for pixel format %d\n", format);
+		return bpp;
+	}
+
+	lane_rate_kbps = mode->clock * bpp / lanes;
+
+	/*
+	 * Set BW a little larger only in video burst mode in
+	 * consideration of the protocol overhead and HS mode
+	 * switching to BLLP mode, take 1 / 0.9, since Mbps must
+	 * big than bandwidth of RGB
+	 */
+	if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+		lane_rate_kbps = (lane_rate_kbps * 10) / 9;
+
+	if (lane_rate_kbps > max_lane_rate) {
+		dev_err(dsi2->dev, "DPHY clock frequency is out of range\n");
+		return -ERANGE;
+	}
+
+	dsi2->lane_mbps = lane_rate_kbps / 1000;
+	*lane_mbps = dsi2->lane_mbps;
+
+	if (dsi2->phy) {
+		target_phyclk = DIV_ROUND_CLOSEST_ULL(lane_rate_kbps * lanes * 1000, bpp);
+		phy_mipi_dphy_get_default_config(target_phyclk, bpp, lanes,
+						 &dsi2->phy_opts.mipi_dphy);
+	}
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_phy_get_iface(void *priv_data, struct dw_mipi_dsi2_phy_iface *iface)
+{
+	/* PPI width is fixed to 16 bits in DCPHY */
+	iface->ppi_width = 16;
+	iface->phy_type = DW_MIPI_DSI2_DPHY;
+}
+
+static int
+dw_mipi_dsi2_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+			    struct dw_mipi_dsi2_phy_timing *timing)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+	struct phy_configure_opts_mipi_dphy *cfg = &dsi2->phy_opts.mipi_dphy;
+	unsigned long long tmp, ui;
+	unsigned long long hstx_clk;
+
+	hstx_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
+
+	ui = ALIGN(PSEC_PER_SEC, hstx_clk);
+	do_div(ui, hstx_clk);
+
+	/* PHY_LP2HS_TIME = (TLPX + THS-PREPARE + THS-ZERO) / Tphy_hstx_clk */
+	tmp = cfg->lpx + cfg->hs_prepare + cfg->hs_zero;
+	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
+	timing->data_lp2hs = tmp;
+
+	/* PHY_HS2LP_TIME = (THS-TRAIL + THS-EXIT) / Tphy_hstx_clk */
+	tmp = cfg->hs_trail + cfg->hs_exit;
+	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
+	timing->data_hs2lp = tmp;
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi2_phy_ops dw_mipi_dsi2_rockchip_phy_ops = {
+	.init = dw_mipi_dsi2_phy_init,
+	.power_on = dw_mipi_dsi2_phy_power_on,
+	.power_off = dw_mipi_dsi2_phy_power_off,
+	.get_interface = dw_mipi_dsi2_phy_get_iface,
+	.get_lane_mbps = dw_mipi_dsi2_get_lane_mbps,
+	.get_timing = dw_mipi_dsi2_phy_get_timing,
+};
+
+static void dw_mipi_dsi2_encoder_atomic_enable(struct drm_encoder *encoder,
+					       struct drm_atomic_state *state)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
+	u32 color_depth;
+
+	switch (dsi2->format) {
+	case MIPI_DSI_FMT_RGB666:
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		color_depth = IPI_DEPTH_6_BITS;
+		break;
+	case MIPI_DSI_FMT_RGB565:
+		color_depth = IPI_DEPTH_5_6_5_BITS;
+		break;
+	case MIPI_DSI_FMT_RGB888:
+		color_depth = IPI_DEPTH_8_BITS;
+		break;
+	default:
+		/* Should've been caught by atomic_check */
+		WARN_ON(1);
+		return;
+	}
+
+	grf_field_write(dsi2, IPI_COLOR_DEPTH, color_depth);
+}
+
+static int
+dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder,
+				  struct drm_crtc_state *crtc_state,
+				  struct drm_connector_state *conn_state)
+{
+	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
+	struct drm_connector *connector = conn_state->connector;
+	struct drm_display_info *info = &connector->display_info;
+
+	switch (dsi2->format) {
+	case MIPI_DSI_FMT_RGB666:
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		s->output_mode = ROCKCHIP_OUT_MODE_P666;
+		break;
+	case MIPI_DSI_FMT_RGB565:
+		s->output_mode = ROCKCHIP_OUT_MODE_P565;
+		break;
+	case MIPI_DSI_FMT_RGB888:
+		s->output_mode = ROCKCHIP_OUT_MODE_P888;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	if (info->num_bus_formats)
+		s->bus_format = info->bus_formats[0];
+	else
+		s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+
+	s->output_type = DRM_MODE_CONNECTOR_DSI;
+	s->bus_flags = info->bus_flags;
+	s->color_space = V4L2_COLORSPACE_DEFAULT;
+
+	return 0;
+}
+
+static const struct drm_encoder_helper_funcs
+dw_mipi_dsi2_encoder_helper_funcs = {
+	.atomic_enable = dw_mipi_dsi2_encoder_atomic_enable,
+	.atomic_check = dw_mipi_dsi2_encoder_atomic_check,
+};
+
+static int rockchip_dsi2_drm_create_encoder(struct dw_mipi_dsi2_rockchip *dsi2,
+					    struct drm_device *drm_dev)
+{
+	struct drm_encoder *encoder = &dsi2->encoder.encoder;
+	int ret;
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
+							     dsi2->dev->of_node);
+
+	ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		dev_err(dsi2->dev, "Failed to initialize encoder with drm\n");
+		return ret;
+	}
+
+	drm_encoder_helper_add(encoder, &dw_mipi_dsi2_encoder_helper_funcs);
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_rockchip_bind(struct device *dev, struct device *master,
+				      void *data)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
+	struct drm_device *drm_dev = data;
+	int ret;
+
+	ret = rockchip_dsi2_drm_create_encoder(dsi2, drm_dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to create drm encoder\n");
+
+	rockchip_drm_encoder_set_crtc_endpoint_id(&dsi2->encoder,
+						  dev->of_node, 0, 0);
+
+	ret = dw_mipi_dsi2_bind(dsi2->dmd, &dsi2->encoder.encoder);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to bind\n");
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_rockchip_unbind(struct device *dev, struct device *master,
+					 void *data)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
+
+	dw_mipi_dsi2_unbind(dsi2->dmd);
+}
+
+static const struct component_ops dw_mipi_dsi2_rockchip_ops = {
+	.bind	= dw_mipi_dsi2_rockchip_bind,
+	.unbind	= dw_mipi_dsi2_rockchip_unbind,
+};
+
+static int dw_mipi_dsi2_rockchip_host_attach(void *priv_data,
+					     struct mipi_dsi_device *device)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+	int ret;
+
+	ret = component_add(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
+	if (ret)
+		return dev_err_probe(dsi2->dev, ret, "Failed to register component\n");
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_rockchip_host_detach(void *priv_data,
+					     struct mipi_dsi_device *device)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+
+	component_del(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi2_host_ops dw_mipi_dsi2_rockchip_host_ops = {
+	.attach = dw_mipi_dsi2_rockchip_host_attach,
+	.detach = dw_mipi_dsi2_rockchip_host_detach,
+};
+
+static __maybe_unused int dw_mipi_dsi2_runtime_suspend(struct device *dev)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(dsi2->pclk);
+	clk_disable_unprepare(dsi2->sys_clk);
+
+	return 0;
+}
+
+static __maybe_unused int dw_mipi_dsi2_runtime_resume(struct device *dev)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
+
+	clk_prepare_enable(dsi2->pclk);
+	clk_prepare_enable(dsi2->sys_clk);
+
+	return 0;
+}
+
+static const struct dev_pm_ops dw_mipi_dsi2_rockchip_pm_ops = {
+	SET_RUNTIME_PM_OPS(dw_mipi_dsi2_runtime_suspend,
+			   dw_mipi_dsi2_runtime_resume, NULL)
+};
+
+static const struct regmap_config dw_mipi_dsi2_rockchip_regmap_config = {
+	.name = "dsi2-host",
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.fast_io = true,
+};
+
+static int dw_mipi_dsi2_rockchip_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	const struct rockchip_dw_dsi2_chip_data *cdata =
+						of_device_get_match_data(dev);
+	struct dw_mipi_dsi2_rockchip *dsi2;
+	struct resource *res;
+	void __iomem *base;
+	int i;
+
+	dsi2 = devm_kzalloc(dev, sizeof(*dsi2), GFP_KERNEL);
+	if (!dsi2)
+		return -ENOMEM;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base), "Unable to get dsi registers\n");
+
+	dsi2->regmap = devm_regmap_init_mmio(dev, base, &dw_mipi_dsi2_rockchip_regmap_config);
+	if (IS_ERR(dsi2->regmap))
+		return dev_err_probe(dev, PTR_ERR(dsi2->regmap), "failed to init register map\n");
+
+	i = 0;
+	while (cdata[i].reg) {
+		if (cdata[i].reg == res->start) {
+			dsi2->cdata = &cdata[i];
+			break;
+		}
+
+		i++;
+	}
+
+	if (!dsi2->cdata)
+		return dev_err_probe(dev, -EINVAL, "No dsi-config for %s node\n", np->name);
+
+	dsi2->pclk = devm_clk_get(dev, "pclk");
+	if (IS_ERR(dsi2->pclk))
+		return dev_err_probe(dev, PTR_ERR(dsi2->pclk), "Unable to get pclk\n");
+
+	dsi2->sys_clk = devm_clk_get(dev, "sys");
+	if (IS_ERR(dsi2->sys_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi2->sys_clk), "Unable to get sys_clk\n");
+
+	dsi2->grf_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
+	if (IS_ERR(dsi2->grf_regmap))
+		return dev_err_probe(dsi2->dev, PTR_ERR(dsi2->grf_regmap), "Unable to get grf\n");
+
+	dsi2->phy = devm_phy_optional_get(dev, "dcphy");
+	if (IS_ERR(dsi2->phy))
+		return dev_err_probe(dev, PTR_ERR(dsi2->phy), "failed to get mipi phy\n");
+
+	dsi2->dev = dev;
+	dsi2->pdata.regmap = dsi2->regmap;
+	dsi2->pdata.max_data_lanes = 4;
+	dsi2->pdata.phy_ops = &dw_mipi_dsi2_rockchip_phy_ops;
+	dsi2->pdata.host_ops = &dw_mipi_dsi2_rockchip_host_ops;
+	dsi2->pdata.priv_data = dsi2;
+	platform_set_drvdata(pdev, dsi2);
+
+	dsi2->dmd = dw_mipi_dsi2_probe(pdev, &dsi2->pdata);
+	if (IS_ERR(dsi2->dmd))
+		return dev_err_probe(dev, PTR_ERR(dsi2->dmd), "Failed to probe dw_mipi_dsi2\n");
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_rockchip_remove(struct platform_device *pdev)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = platform_get_drvdata(pdev);
+
+	dw_mipi_dsi2_remove(dsi2->dmd);
+}
+
+static const struct dsigrf_reg rk3588_dsi0_grf_reg_fields[MAX_FIELDS] = {
+	[TXREQCLKHS_EN]		= { 0x0000, 11, 11 },
+	[GATING_EN]		= { 0x0000, 10, 10 },
+	[IPI_SHUTDN]		= { 0x0000,  9,  9 },
+	[IPI_COLORM]		= { 0x0000,  8,  8 },
+	[IPI_COLOR_DEPTH]	= { 0x0000,  4,  7 },
+	[IPI_FORMAT]		= { 0x0000,  0,  3 },
+};
+
+static const struct dsigrf_reg rk3588_dsi1_grf_reg_fields[MAX_FIELDS] = {
+	[TXREQCLKHS_EN]		= { 0x0004, 11, 11 },
+	[GATING_EN]		= { 0x0004, 10, 10 },
+	[IPI_SHUTDN]		= { 0x0004,  9,  9 },
+	[IPI_COLORM]		= { 0x0004,  8,  8 },
+	[IPI_COLOR_DEPTH]	= { 0x0004,  4,  7 },
+	[IPI_FORMAT]		= { 0x0004,  0,  3 },
+};
+
+static const struct rockchip_dw_dsi2_chip_data rk3588_chip_data[] = {
+	{
+		.reg = 0xfde20000,
+		.grf_regs = rk3588_dsi0_grf_reg_fields,
+		.max_bit_rate_per_lane = 4500000ULL,
+	},
+	{
+		.reg = 0xfde30000,
+		.grf_regs = rk3588_dsi1_grf_reg_fields,
+		.max_bit_rate_per_lane = 4500000ULL,
+	}
+};
+
+static const struct of_device_id dw_mipi_dsi2_rockchip_dt_ids[] = {
+	{
+		.compatible = "rockchip,rk3588-mipi-dsi2",
+		.data = &rk3588_chip_data,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, dw_mipi_dsi2_rockchip_dt_ids);
+
+struct platform_driver dw_mipi_dsi2_rockchip_driver = {
+	.probe	= dw_mipi_dsi2_rockchip_probe,
+	.remove = dw_mipi_dsi2_rockchip_remove,
+	.driver = {
+		.of_match_table = dw_mipi_dsi2_rockchip_dt_ids,
+		.pm = &dw_mipi_dsi2_rockchip_pm_ops,
+		.name = "dw-mipi-dsi2",
+	},
+};
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index ddf0be331c0a..5327ce035003 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -511,6 +511,8 @@ static int __init rockchip_drm_init(void)
 				CONFIG_ROCKCHIP_DW_HDMI_QP);
 	ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver,
 				CONFIG_ROCKCHIP_DW_MIPI_DSI);
+	ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi2_rockchip_driver,
+				CONFIG_ROCKCHIP_DW_MIPI_DSI2);
 	ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI);
 	ADD_ROCKCHIP_SUB_DRIVER(rk3066_hdmi_driver,
 				CONFIG_ROCKCHIP_RK3066_HDMI);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 24b4ce5ceaf1..9c9d38a06cdf 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -90,6 +90,7 @@ extern struct platform_driver cdn_dp_driver;
 extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
 extern struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver;
 extern struct platform_driver dw_mipi_dsi_rockchip_driver;
+extern struct platform_driver dw_mipi_dsi2_rockchip_driver;
 extern struct platform_driver inno_hdmi_driver;
 extern struct platform_driver rockchip_dp_driver;
 extern struct platform_driver rockchip_lvds_driver;
-- 
2.45.2



From heiko at sntech.de  Tue Dec  3 08:54:47 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 17:54:47 +0100
Subject: [PATCH v3 1/3] drm/bridge/synopsys: Add MIPI DSI2 host controller bridge
In-Reply-To: <20241203165450.1501219-1-heiko@sntech.de>
References: <20241203165450.1501219-1-heiko@sntech.de>
Message-ID: <20241203165450.1501219-2-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

Add a Synopsys Designware MIPI DSI host DRM bridge driver for their
DSI2 host controller, based on the Rockchip version from the driver
rockchip/dw-mipi-dsi2.c in their vendor-kernel with phy & bridge APIs.

While the driver is heavily modelled after the previous IP, the register
set of this DSI2 controller is completely different and there are also
additional properties like the variable-width phy interface.

Tested-by: Daniel Semkowicz <dse at thaumatec.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 drivers/gpu/drm/bridge/synopsys/Kconfig       |    6 +
 drivers/gpu/drm/bridge/synopsys/Makefile      |    1 +
 .../gpu/drm/bridge/synopsys/dw-mipi-dsi2.c    | 1030 +++++++++++++++++
 include/drm/bridge/dw_mipi_dsi2.h             |   95 ++
 4 files changed, 1132 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
 create mode 100644 include/drm/bridge/dw_mipi_dsi2.h

diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
index ca416dab156d..f3ab2f985f8c 100644
--- a/drivers/gpu/drm/bridge/synopsys/Kconfig
+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
@@ -59,3 +59,9 @@ config DRM_DW_MIPI_DSI
 	select DRM_KMS_HELPER
 	select DRM_MIPI_DSI
 	select DRM_PANEL_BRIDGE
+
+config DRM_DW_MIPI_DSI2
+	tristate
+	select DRM_KMS_HELPER
+	select DRM_MIPI_DSI
+	select DRM_PANEL_BRIDGE
diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
index 9869d9651ed1..9dc376d220ad 100644
--- a/drivers/gpu/drm/bridge/synopsys/Makefile
+++ b/drivers/gpu/drm/bridge/synopsys/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
 obj-$(CONFIG_DRM_DW_HDMI_QP) += dw-hdmi-qp.o
 
 obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
+obj-$(CONFIG_DRM_DW_MIPI_DSI2) += dw-mipi-dsi2.o
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
new file mode 100644
index 000000000000..e143a083f423
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
@@ -0,0 +1,1030 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Modified by Heiko Stuebner <heiko.stuebner at cherry.de>
+ * This generic Synopsys DesignWare MIPI DSI2 host driver is based on the
+ * Rockchip version from rockchip/dw-mipi-dsi2.c converted to use bridge APIs.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/bridge/dw_mipi_dsi2.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
+#include <drm/drm_print.h>
+
+#define DSI2_PWR_UP			0x000c
+#define RESET				0
+#define POWER_UP			BIT(0)
+#define CMD_TX_MODE(x)			FIELD_PREP(BIT(24), x)
+#define DSI2_SOFT_RESET			0x0010
+#define SYS_RSTN			BIT(2)
+#define PHY_RSTN			BIT(1)
+#define IPI_RSTN			BIT(0)
+#define INT_ST_MAIN			0x0014
+#define DSI2_MODE_CTRL			0x0018
+#define DSI2_MODE_STATUS		0x001c
+#define DSI2_CORE_STATUS		0x0020
+#define PRI_RD_DATA_AVAIL		BIT(26)
+#define PRI_FIFOS_NOT_EMPTY		BIT(25)
+#define PRI_BUSY			BIT(24)
+#define CRI_RD_DATA_AVAIL		BIT(18)
+#define CRT_FIFOS_NOT_EMPTY		BIT(17)
+#define CRI_BUSY			BIT(16)
+#define IPI_FIFOS_NOT_EMPTY		BIT(9)
+#define IPI_BUSY			BIT(8)
+#define CORE_FIFOS_NOT_EMPTY		BIT(1)
+#define CORE_BUSY			BIT(0)
+#define MANUAL_MODE_CFG			0x0024
+#define MANUAL_MODE_EN			BIT(0)
+#define DSI2_TIMEOUT_HSTX_CFG		0x0048
+#define TO_HSTX(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_HSTXRDY_CFG	0x004c
+#define TO_HSTXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_LPRX_CFG		0x0050
+#define TO_LPRXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_LPTXRDY_CFG	0x0054
+#define TO_LPTXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_LPTXTRIG_CFG	0x0058
+#define TO_LPTXTRIG(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_LPTXULPS_CFG	0x005c
+#define TO_LPTXULPS(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_BTA_CFG		0x60
+#define TO_BTA(x)			FIELD_PREP(GENMASK(15, 0), x)
+
+#define DSI2_PHY_MODE_CFG		0x0100
+#define PPI_WIDTH(x)			FIELD_PREP(GENMASK(9, 8), x)
+#define PHY_LANES(x)			FIELD_PREP(GENMASK(5, 4), (x) - 1)
+#define PHY_TYPE(x)			FIELD_PREP(BIT(0), x)
+#define DSI2_PHY_CLK_CFG		0X0104
+#define PHY_LPTX_CLK_DIV(x)		FIELD_PREP(GENMASK(12, 8), x)
+#define CLK_TYPE_MASK			BIT(0)
+#define NON_CONTINUOUS_CLK		BIT(0)
+#define CONTINUOUS_CLK			0
+#define DSI2_PHY_LP2HS_MAN_CFG		0x010c
+#define PHY_LP2HS_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
+#define DSI2_PHY_HS2LP_MAN_CFG		0x0114
+#define PHY_HS2LP_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
+#define DSI2_PHY_MAX_RD_T_MAN_CFG	0x011c
+#define PHY_MAX_RD_TIME(x)		FIELD_PREP(GENMASK(26, 0), x)
+#define DSI2_PHY_ESC_CMD_T_MAN_CFG	0x0124
+#define PHY_ESC_CMD_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
+#define DSI2_PHY_ESC_BYTE_T_MAN_CFG	0x012c
+#define PHY_ESC_BYTE_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
+
+#define DSI2_PHY_IPI_RATIO_MAN_CFG	0x0134
+#define PHY_IPI_RATIO(x)		FIELD_PREP(GENMASK(21, 0), x)
+#define DSI2_PHY_SYS_RATIO_MAN_CFG	0x013C
+#define PHY_SYS_RATIO(x)		FIELD_PREP(GENMASK(16, 0), x)
+
+#define DSI2_DSI_GENERAL_CFG		0x0200
+#define BTA_EN				BIT(1)
+#define EOTP_TX_EN			BIT(0)
+#define DSI2_DSI_VCID_CFG		0x0204
+#define TX_VCID(x)			FIELD_PREP(GENMASK(1, 0), x)
+#define DSI2_DSI_SCRAMBLING_CFG		0x0208
+#define SCRAMBLING_SEED(x)		FIELD_PREP(GENMASK(31, 16), x)
+#define SCRAMBLING_EN			BIT(0)
+#define DSI2_DSI_VID_TX_CFG		0x020c
+#define LPDT_DISPLAY_CMD_EN		BIT(20)
+#define BLK_VFP_HS_EN			BIT(14)
+#define BLK_VBP_HS_EN			BIT(13)
+#define BLK_VSA_HS_EN			BIT(12)
+#define BLK_HFP_HS_EN			BIT(6)
+#define BLK_HBP_HS_EN			BIT(5)
+#define BLK_HSA_HS_EN			BIT(4)
+#define VID_MODE_TYPE(x)		FIELD_PREP(GENMASK(1, 0), x)
+#define DSI2_CRI_TX_HDR			0x02c0
+#define CMD_TX_MODE(x)			FIELD_PREP(BIT(24), x)
+#define DSI2_CRI_TX_PLD			0x02c4
+#define DSI2_CRI_RX_HDR			0x02c8
+#define DSI2_CRI_RX_PLD			0x02cc
+
+#define DSI2_IPI_COLOR_MAN_CFG		0x0300
+#define IPI_DEPTH(x)			FIELD_PREP(GENMASK(7, 4), x)
+#define IPI_DEPTH_5_6_5_BITS		0x02
+#define IPI_DEPTH_6_BITS		0x03
+#define IPI_DEPTH_8_BITS		0x05
+#define IPI_DEPTH_10_BITS		0x06
+#define IPI_FORMAT(x)			FIELD_PREP(GENMASK(3, 0), x)
+#define IPI_FORMAT_RGB			0x0
+#define IPI_FORMAT_DSC			0x0b
+#define DSI2_IPI_VID_HSA_MAN_CFG	0x0304
+#define VID_HSA_TIME(x)			FIELD_PREP(GENMASK(29, 0), x)
+#define DSI2_IPI_VID_HBP_MAN_CFG	0x030c
+#define VID_HBP_TIME(x)			FIELD_PREP(GENMASK(29, 0), x)
+#define DSI2_IPI_VID_HACT_MAN_CFG	0x0314
+#define VID_HACT_TIME(x)		FIELD_PREP(GENMASK(29, 0), x)
+#define DSI2_IPI_VID_HLINE_MAN_CFG	0x031c
+#define VID_HLINE_TIME(x)		FIELD_PREP(GENMASK(29, 0), x)
+#define DSI2_IPI_VID_VSA_MAN_CFG	0x0324
+#define VID_VSA_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
+#define DSI2_IPI_VID_VBP_MAN_CFG	0X032C
+#define VID_VBP_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
+#define DSI2_IPI_VID_VACT_MAN_CFG	0X0334
+#define VID_VACT_LINES(x)		FIELD_PREP(GENMASK(13, 0), x)
+#define DSI2_IPI_VID_VFP_MAN_CFG	0X033C
+#define VID_VFP_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
+#define DSI2_IPI_PIX_PKT_CFG		0x0344
+#define MAX_PIX_PKT(x)			FIELD_PREP(GENMASK(15, 0), x)
+
+#define DSI2_INT_ST_PHY			0x0400
+#define DSI2_INT_MASK_PHY		0x0404
+#define DSI2_INT_ST_TO			0x0410
+#define DSI2_INT_MASK_TO		0x0414
+#define DSI2_INT_ST_ACK			0x0420
+#define DSI2_INT_MASK_ACK		0x0424
+#define DSI2_INT_ST_IPI			0x0430
+#define DSI2_INT_MASK_IPI		0x0434
+#define DSI2_INT_ST_FIFO		0x0440
+#define DSI2_INT_MASK_FIFO		0x0444
+#define DSI2_INT_ST_PRI			0x0450
+#define DSI2_INT_MASK_PRI		0x0454
+#define DSI2_INT_ST_CRI			0x0460
+#define DSI2_INT_MASK_CRI		0x0464
+#define DSI2_INT_FORCE_CRI		0x0468
+#define DSI2_MAX_REGISGER		DSI2_INT_FORCE_CRI
+
+#define MODE_STATUS_TIMEOUT_US		10000
+#define CMD_PKT_STATUS_TIMEOUT_US	20000
+
+enum vid_mode_type {
+	VID_MODE_TYPE_NON_BURST_SYNC_PULSES,
+	VID_MODE_TYPE_NON_BURST_SYNC_EVENTS,
+	VID_MODE_TYPE_BURST,
+};
+
+enum mode_ctrl {
+	IDLE_MODE,
+	AUTOCALC_MODE,
+	COMMAND_MODE,
+	VIDEO_MODE,
+	DATA_STREAM_MODE,
+	VIDEO_TEST_MODE,
+	DATA_STREAM_TEST_MODE,
+};
+
+enum ppi_width {
+	PPI_WIDTH_8_BITS,
+	PPI_WIDTH_16_BITS,
+	PPI_WIDTH_32_BITS,
+};
+
+struct cmd_header {
+	u8 cmd_type;
+	u8 delay;
+	u8 payload_length;
+};
+
+struct dw_mipi_dsi2 {
+	struct drm_bridge bridge;
+	struct mipi_dsi_host dsi_host;
+	struct drm_bridge *panel_bridge;
+	struct device *dev;
+	struct regmap *regmap;
+	struct clk *pclk;
+	struct clk *sys_clk;
+
+	unsigned int lane_mbps; /* per lane */
+	u32 channel;
+	u32 lanes;
+	u32 format;
+	unsigned long mode_flags;
+
+	struct drm_display_mode mode;
+	const struct dw_mipi_dsi2_plat_data *plat_data;
+};
+
+static inline struct dw_mipi_dsi2 *host_to_dsi2(struct mipi_dsi_host *host)
+{
+	return container_of(host, struct dw_mipi_dsi2, dsi_host);
+}
+
+static inline struct dw_mipi_dsi2 *bridge_to_dsi2(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct dw_mipi_dsi2, bridge);
+}
+
+static int cri_fifos_wait_avail(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 sts, mask;
+	int ret;
+
+	mask = CRI_BUSY | CRT_FIFOS_NOT_EMPTY;
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS, sts,
+				       !(sts & mask), 0, CMD_PKT_STATUS_TIMEOUT_US);
+	if (ret < 0) {
+		dev_err(dsi2->dev, "command interface is busy\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_set_vid_mode(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 val = 0, mode;
+	int ret;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP)
+		val |= BLK_HFP_HS_EN;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP)
+		val |= BLK_HBP_HS_EN;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HSA)
+		val |= BLK_HSA_HS_EN;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+		val |= VID_MODE_TYPE_BURST;
+	else if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+		val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES;
+	else
+		val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
+
+	regmap_write(dsi2->regmap, DSI2_DSI_VID_TX_CFG, val);
+
+	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, VIDEO_MODE);
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
+				       mode, mode & VIDEO_MODE,
+				       1000, MODE_STATUS_TIMEOUT_US);
+	if (ret < 0)
+		dev_err(dsi2->dev, "failed to enter video mode\n");
+}
+
+static void dw_mipi_dsi2_set_data_stream_mode(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 mode;
+	int ret;
+
+	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, DATA_STREAM_MODE);
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
+				       mode, mode & DATA_STREAM_MODE,
+				       1000, MODE_STATUS_TIMEOUT_US);
+	if (ret < 0)
+		dev_err(dsi2->dev, "failed to enter data stream mode\n");
+}
+
+static void dw_mipi_dsi2_set_cmd_mode(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 mode;
+	int ret;
+
+	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, COMMAND_MODE);
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
+				       mode, mode & COMMAND_MODE,
+				       1000, MODE_STATUS_TIMEOUT_US);
+	if (ret < 0)
+		dev_err(dsi2->dev, "failed to enter data stream mode\n");
+}
+
+static void dw_mipi_dsi2_host_softrst(struct dw_mipi_dsi2 *dsi2)
+{
+	regmap_write(dsi2->regmap, DSI2_SOFT_RESET, 0x0);
+	usleep_range(50, 100);
+	regmap_write(dsi2->regmap, DSI2_SOFT_RESET,
+		   SYS_RSTN | PHY_RSTN | IPI_RSTN);
+}
+
+static void dw_mipi_dsi2_phy_clk_mode_cfg(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 sys_clk, esc_clk_div;
+	u32 val = 0;
+
+	/*
+	 * clk_type should be NON_CONTINUOUS_CLK before
+	 * initial deskew calibration be sent.
+	 */
+	val |= NON_CONTINUOUS_CLK;
+
+	/* The maximum value of the escape clock frequency is 20MHz */
+	sys_clk = clk_get_rate(dsi2->sys_clk) / USEC_PER_SEC;
+	esc_clk_div = DIV_ROUND_UP(sys_clk, 20 * 2);
+	val |= PHY_LPTX_CLK_DIV(esc_clk_div);
+
+	regmap_write(dsi2->regmap, DSI2_PHY_CLK_CFG, val);
+}
+
+static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2)
+{
+	struct drm_display_mode *mode = &dsi2->mode;
+	u64 sys_clk = clk_get_rate(dsi2->sys_clk);
+	u64 pixel_clk, ipi_clk, phy_hsclk;
+	u64 tmp;
+
+	/*
+	 * in DPHY mode, the phy_hstx_clk is exactly 1/16 the Lane high-speed
+	 * data rate; In CPHY mode, the phy_hstx_clk is exactly 1/7 the trio
+	 * high speed symbol rate.
+	 */
+	phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
+
+	/* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */
+	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
+	ipi_clk = pixel_clk / 4;
+
+	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, ipi_clk);
+	regmap_write(dsi2->regmap, DSI2_PHY_IPI_RATIO_MAN_CFG,
+		   PHY_IPI_RATIO(tmp));
+
+	/*
+	 * SYS_RATIO_MAN_CFG = MIPI_DCPHY_HSCLK_Freq / MIPI_DCPHY_HSCLK_Freq
+	 */
+	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, sys_clk);
+	regmap_write(dsi2->regmap, DSI2_PHY_SYS_RATIO_MAN_CFG,
+		   PHY_SYS_RATIO(tmp));
+}
+
+static void dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(struct dw_mipi_dsi2 *dsi2)
+{
+	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
+	struct dw_mipi_dsi2_phy_timing timing;
+	int ret;
+
+	ret = phy_ops->get_timing(dsi2->plat_data->priv_data,
+				  dsi2->lane_mbps, &timing);
+	if (ret)
+		dev_err(dsi2->dev, "Retrieving phy timings failed\n");
+
+	regmap_write(dsi2->regmap, DSI2_PHY_LP2HS_MAN_CFG, PHY_LP2HS_TIME(timing.data_lp2hs));
+	regmap_write(dsi2->regmap, DSI2_PHY_HS2LP_MAN_CFG, PHY_HS2LP_TIME(timing.data_hs2lp));
+}
+
+static void dw_mipi_dsi2_phy_init(struct dw_mipi_dsi2 *dsi2)
+{
+	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
+	struct dw_mipi_dsi2_phy_iface iface;
+	u32 val = 0;
+
+	phy_ops->get_interface(dsi2->plat_data->priv_data, &iface);
+
+	switch (iface.ppi_width) {
+	case 8:
+		val |= PPI_WIDTH(PPI_WIDTH_8_BITS);
+		break;
+	case 16:
+		val |= PPI_WIDTH(PPI_WIDTH_16_BITS);
+		break;
+	case 32:
+		val |= PPI_WIDTH(PPI_WIDTH_32_BITS);
+		break;
+	default:
+		/* Caught in probe */
+		break;
+	}
+
+	val |= PHY_LANES(dsi2->lanes);
+	val |= PHY_TYPE(DW_MIPI_DSI2_DPHY);
+	regmap_write(dsi2->regmap, DSI2_PHY_MODE_CFG, val);
+
+	dw_mipi_dsi2_phy_clk_mode_cfg(dsi2);
+	dw_mipi_dsi2_phy_ratio_cfg(dsi2);
+	dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2);
+
+	/* phy configuration 8 - 10 */
+}
+
+static void dw_mipi_dsi2_tx_option_set(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 val;
+
+	val = BTA_EN | EOTP_TX_EN;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
+		val &= ~EOTP_TX_EN;
+
+	regmap_write(dsi2->regmap, DSI2_DSI_GENERAL_CFG, val);
+	regmap_write(dsi2->regmap, DSI2_DSI_VCID_CFG, TX_VCID(dsi2->channel));
+}
+
+static void dw_mipi_dsi2_ipi_color_coding_cfg(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 val, color_depth;
+
+	switch (dsi2->format) {
+	case MIPI_DSI_FMT_RGB666:
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		color_depth = IPI_DEPTH_6_BITS;
+		break;
+	case MIPI_DSI_FMT_RGB565:
+		color_depth = IPI_DEPTH_5_6_5_BITS;
+		break;
+	case MIPI_DSI_FMT_RGB888:
+	default:
+		color_depth = IPI_DEPTH_8_BITS;
+		break;
+	}
+
+	val = IPI_DEPTH(color_depth) |
+	      IPI_FORMAT(IPI_FORMAT_RGB);
+	regmap_write(dsi2->regmap, DSI2_IPI_COLOR_MAN_CFG, val);
+}
+
+static void dw_mipi_dsi2_vertical_timing_config(struct dw_mipi_dsi2 *dsi2,
+						const struct drm_display_mode *mode)
+{
+	u32 vactive, vsa, vfp, vbp;
+
+	vactive = mode->vdisplay;
+	vsa = mode->vsync_end - mode->vsync_start;
+	vfp = mode->vsync_start - mode->vdisplay;
+	vbp = mode->vtotal - mode->vsync_end;
+
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_VSA_MAN_CFG, VID_VSA_LINES(vsa));
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_VBP_MAN_CFG, VID_VBP_LINES(vbp));
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_VACT_MAN_CFG, VID_VACT_LINES(vactive));
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_VFP_MAN_CFG, VID_VFP_LINES(vfp));
+}
+
+static void dw_mipi_dsi2_ipi_set(struct dw_mipi_dsi2 *dsi2)
+{
+	struct drm_display_mode *mode = &dsi2->mode;
+	u32 hline, hsa, hbp, hact;
+	u64 hline_time, hsa_time, hbp_time, hact_time, tmp;
+	u64 pixel_clk, phy_hs_clk;
+	u16 val;
+
+	val = mode->hdisplay;
+
+	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, MAX_PIX_PKT(val));
+
+	dw_mipi_dsi2_ipi_color_coding_cfg(dsi2);
+
+	/*
+	 * if the controller is intended to operate in data stream mode,
+	 * no more steps are required.
+	 */
+	if (!(dsi2->mode_flags & MIPI_DSI_MODE_VIDEO))
+		return;
+
+	hact = mode->hdisplay;
+	hsa = mode->hsync_end - mode->hsync_start;
+	hbp = mode->htotal - mode->hsync_end;
+	hline = mode->htotal;
+
+	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
+
+	phy_hs_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
+
+	tmp = hsa * phy_hs_clk;
+	hsa_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_HSA_MAN_CFG, VID_HSA_TIME(hsa_time));
+
+	tmp = hbp * phy_hs_clk;
+	hbp_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_HBP_MAN_CFG, VID_HBP_TIME(hbp_time));
+
+	tmp = hact * phy_hs_clk;
+	hact_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_HACT_MAN_CFG, VID_HACT_TIME(hact_time));
+
+	tmp = hline * phy_hs_clk;
+	hline_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_HLINE_MAN_CFG, VID_HLINE_TIME(hline_time));
+
+	dw_mipi_dsi2_vertical_timing_config(dsi2, mode);
+}
+
+static void
+dw_mipi_dsi2_work_mode(struct dw_mipi_dsi2 *dsi2, u32 mode)
+{
+	/*
+	 * select controller work in Manual mode
+	 * Manual: MANUAL_MODE_EN
+	 * Automatic: 0
+	 */
+	regmap_write(dsi2->regmap, MANUAL_MODE_CFG, mode);
+}
+
+static int dw_mipi_dsi2_host_attach(struct mipi_dsi_host *host,
+				    struct mipi_dsi_device *device)
+{
+	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	struct drm_bridge *bridge;
+	int ret;
+
+	if (device->lanes > dsi2->plat_data->max_data_lanes) {
+		dev_err(dsi2->dev, "the number of data lanes(%u) is too many\n",
+			device->lanes);
+		return -EINVAL;
+	}
+
+	dsi2->lanes = device->lanes;
+	dsi2->channel = device->channel;
+	dsi2->format = device->format;
+	dsi2->mode_flags = device->mode_flags;
+
+	bridge = devm_drm_of_get_bridge(dsi2->dev, dsi2->dev->of_node, 1, 0);
+	if (IS_ERR(bridge))
+		return PTR_ERR(bridge);
+
+	bridge->pre_enable_prev_first = true;
+	dsi2->panel_bridge = bridge;
+
+	drm_bridge_add(&dsi2->bridge);
+
+	if (pdata->host_ops && pdata->host_ops->attach) {
+		ret = pdata->host_ops->attach(pdata->priv_data, device);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_host_detach(struct mipi_dsi_host *host,
+				    struct mipi_dsi_device *device)
+{
+	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	int ret;
+
+	if (pdata->host_ops && pdata->host_ops->detach) {
+		ret = pdata->host_ops->detach(pdata->priv_data, device);
+		if (ret < 0)
+			return ret;
+	}
+
+	drm_bridge_remove(&dsi2->bridge);
+
+	drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_gen_pkt_hdr_write(struct dw_mipi_dsi2 *dsi2,
+					  u32 hdr_val, bool lpm)
+{
+	int ret;
+
+	regmap_write(dsi2->regmap, DSI2_CRI_TX_HDR, hdr_val | CMD_TX_MODE(lpm));
+
+	ret = cri_fifos_wait_avail(dsi2);
+	if (ret) {
+		dev_err(dsi2->dev, "failed to write command header\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_write(struct dw_mipi_dsi2 *dsi2,
+			      const struct mipi_dsi_packet *packet, bool lpm)
+{
+	const u8 *tx_buf = packet->payload;
+	int len = packet->payload_length, pld_data_bytes = sizeof(u32);
+	__le32 word;
+
+	/* Send payload */
+	while (len) {
+		if (len < pld_data_bytes) {
+			word = 0;
+			memcpy(&word, tx_buf, len);
+			regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, le32_to_cpu(word));
+			len = 0;
+		} else {
+			memcpy(&word, tx_buf, pld_data_bytes);
+			regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, le32_to_cpu(word));
+			tx_buf += pld_data_bytes;
+			len -= pld_data_bytes;
+		}
+	}
+
+	word = 0;
+	memcpy(&word, packet->header, sizeof(packet->header));
+	return dw_mipi_dsi2_gen_pkt_hdr_write(dsi2, le32_to_cpu(word), lpm);
+}
+
+static int dw_mipi_dsi2_read(struct dw_mipi_dsi2 *dsi2,
+			     const struct mipi_dsi_msg *msg)
+{
+	u8 *payload = msg->rx_buf;
+	int i, j, ret, len = msg->rx_len;
+	u8 data_type;
+	u16 wc;
+	u32 val;
+
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS,
+				       val, val & CRI_RD_DATA_AVAIL,
+				       100, CMD_PKT_STATUS_TIMEOUT_US);
+	if (ret) {
+		dev_err(dsi2->dev, "CRI has no available read data\n");
+		return ret;
+	}
+
+	regmap_read(dsi2->regmap, DSI2_CRI_RX_HDR, &val);
+	data_type = val & 0x3f;
+
+	if (mipi_dsi_packet_format_is_short(data_type)) {
+		for (i = 0; i < len && i < 2; i++)
+			payload[i] = (val >> (8 * (i + 1))) & 0xff;
+
+		return 0;
+	}
+
+	wc = (val >> 8) & 0xffff;
+	/* Receive payload */
+	for (i = 0; i < len && i < wc; i += 4) {
+		regmap_read(dsi2->regmap, DSI2_CRI_RX_PLD, &val);
+		for (j = 0; j < 4 && j + i < len && j + i < wc; j++)
+			payload[i + j] = val >> (8 * j);
+	}
+
+	return 0;
+}
+
+static ssize_t dw_mipi_dsi2_host_transfer(struct mipi_dsi_host *host,
+					  const struct mipi_dsi_msg *msg)
+{
+	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
+	bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM;
+	struct mipi_dsi_packet packet;
+	int ret, nb_bytes;
+
+	regmap_update_bits(dsi2->regmap, DSI2_DSI_VID_TX_CFG,
+			   LPDT_DISPLAY_CMD_EN,
+			   lpm ? LPDT_DISPLAY_CMD_EN : 0);
+
+	/* create a packet to the DSI protocol */
+	ret = mipi_dsi_create_packet(&packet, msg);
+	if (ret) {
+		dev_err(dsi2->dev, "failed to create packet: %d\n", ret);
+		return ret;
+	}
+
+	ret = cri_fifos_wait_avail(dsi2);
+	if (ret)
+		return ret;
+
+	ret = dw_mipi_dsi2_write(dsi2, &packet, lpm);
+	if (ret)
+		return ret;
+
+	if (msg->rx_buf && msg->rx_len) {
+		ret = dw_mipi_dsi2_read(dsi2, msg);
+		if (ret < 0)
+			return ret;
+		nb_bytes = msg->rx_len;
+	} else {
+		nb_bytes = packet.size;
+	}
+
+	return nb_bytes;
+}
+
+static const struct mipi_dsi_host_ops dw_mipi_dsi2_host_ops = {
+	.attach = dw_mipi_dsi2_host_attach,
+	.detach = dw_mipi_dsi2_host_detach,
+	.transfer = dw_mipi_dsi2_host_transfer,
+};
+
+static u32 *
+dw_mipi_dsi2_bridge_atomic_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 dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	u32 *input_fmts;
+
+	if (pdata->get_input_bus_fmts)
+		return pdata->get_input_bus_fmts(pdata->priv_data,
+						 bridge, bridge_state,
+						 crtc_state, conn_state,
+						 output_fmt, num_input_fmts);
+
+	/* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */
+	input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
+	if (!input_fmts)
+		return NULL;
+	input_fmts[0] = MEDIA_BUS_FMT_FIXED;
+	*num_input_fmts = 1;
+
+	return input_fmts;
+}
+
+static int dw_mipi_dsi2_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 dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	bool ret;
+
+	bridge_state->input_bus_cfg.flags =
+		DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE;
+
+	if (pdata->mode_fixup) {
+		ret = pdata->mode_fixup(pdata->priv_data, &crtc_state->mode,
+					&crtc_state->adjusted_mode);
+		if (!ret) {
+			DRM_DEBUG_DRIVER("failed to fixup mode " DRM_MODE_FMT "\n",
+					 DRM_MODE_ARG(&crtc_state->mode));
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_bridge_post_atomic_disable(struct drm_bridge *bridge,
+						    struct drm_bridge_state *old_bridge_state)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
+
+	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, 0);
+
+	/*
+	 * Switch to command mode before panel-bridge post_disable &
+	 * panel unprepare.
+	 * Note: panel-bridge disable & panel disable has been called
+	 * before by the drm framework.
+	 */
+	dw_mipi_dsi2_set_cmd_mode(dsi2);
+
+	regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET);
+
+	if (phy_ops->power_off)
+		phy_ops->power_off(dsi2->plat_data->priv_data);
+
+	clk_disable_unprepare(dsi2->pclk);
+	pm_runtime_put(dsi2->dev);
+}
+
+static unsigned int dw_mipi_dsi2_get_lanes(struct dw_mipi_dsi2 *dsi2)
+{
+	/* single-dsi, so no other instance to consider */
+	return dsi2->lanes;
+}
+
+static void dw_mipi_dsi2_mode_set(struct dw_mipi_dsi2 *dsi2,
+				  const struct drm_display_mode *adjusted_mode)
+{
+	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
+	void *priv_data = dsi2->plat_data->priv_data;
+	u32 lanes = dw_mipi_dsi2_get_lanes(dsi2);
+	int ret;
+
+	clk_prepare_enable(dsi2->pclk);
+
+	ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi2->mode_flags,
+				     lanes, dsi2->format, &dsi2->lane_mbps);
+	if (ret)
+		DRM_DEBUG_DRIVER("Phy get_lane_mbps() failed\n");
+
+	pm_runtime_get_sync(dsi2->dev);
+
+	dw_mipi_dsi2_host_softrst(dsi2);
+	regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET);
+
+	dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN);
+	dw_mipi_dsi2_phy_init(dsi2);
+
+	if (phy_ops->power_on)
+		phy_ops->power_on(dsi2->plat_data->priv_data);
+
+	dw_mipi_dsi2_tx_option_set(dsi2);
+
+	/*
+	 * initial deskew calibration is send after phy_power_on,
+	 * then we can configure clk_type.
+	 */
+
+	regmap_update_bits(dsi2->regmap, DSI2_PHY_CLK_CFG, CLK_TYPE_MASK,
+			   dsi2->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS ? NON_CONTINUOUS_CLK :
+									      CONTINUOUS_CLK);
+
+	regmap_write(dsi2->regmap, DSI2_PWR_UP, POWER_UP);
+	dw_mipi_dsi2_set_cmd_mode(dsi2);
+
+	dw_mipi_dsi2_ipi_set(dsi2);
+}
+
+static void dw_mipi_dsi2_bridge_atomic_pre_enable(struct drm_bridge *bridge,
+						  struct drm_bridge_state *old_bridge_state)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+
+	/* Power up the dsi ctl into a command mode */
+	dw_mipi_dsi2_mode_set(dsi2, &dsi2->mode);
+}
+
+static void dw_mipi_dsi2_bridge_mode_set(struct drm_bridge *bridge,
+					 const struct drm_display_mode *mode,
+					 const struct drm_display_mode *adjusted_mode)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+
+	/* Store the display mode for later use in pre_enable callback */
+	drm_mode_copy(&dsi2->mode, adjusted_mode);
+}
+
+static void dw_mipi_dsi2_bridge_atomic_enable(struct drm_bridge *bridge,
+					      struct drm_bridge_state *old_bridge_state)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+
+	/* Switch to video mode for panel-bridge enable & panel enable */
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)
+		dw_mipi_dsi2_set_vid_mode(dsi2);
+	else
+		dw_mipi_dsi2_set_data_stream_mode(dsi2);
+}
+
+static enum drm_mode_status
+dw_mipi_dsi2_bridge_mode_valid(struct drm_bridge *bridge,
+			       const struct drm_display_info *info,
+			       const struct drm_display_mode *mode)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	enum drm_mode_status mode_status = MODE_OK;
+
+	if (pdata->mode_valid)
+		mode_status = pdata->mode_valid(pdata->priv_data, mode,
+						dsi2->mode_flags,
+						dw_mipi_dsi2_get_lanes(dsi2),
+						dsi2->format);
+
+	return mode_status;
+}
+
+static int dw_mipi_dsi2_bridge_attach(struct drm_bridge *bridge,
+				      enum drm_bridge_attach_flags flags)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+
+	/* Set the encoder type as caller does not know it */
+	bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
+
+	/* Attach the panel-bridge to the dsi bridge */
+	return drm_bridge_attach(bridge->encoder, dsi2->panel_bridge, bridge,
+				 flags);
+}
+
+static const struct drm_bridge_funcs dw_mipi_dsi2_bridge_funcs = {
+	.atomic_duplicate_state	= drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state,
+	.atomic_get_input_bus_fmts = dw_mipi_dsi2_bridge_atomic_get_input_bus_fmts,
+	.atomic_check		= dw_mipi_dsi2_bridge_atomic_check,
+	.atomic_reset		= drm_atomic_helper_bridge_reset,
+	.atomic_pre_enable	= dw_mipi_dsi2_bridge_atomic_pre_enable,
+	.atomic_enable		= dw_mipi_dsi2_bridge_atomic_enable,
+	.atomic_post_disable	= dw_mipi_dsi2_bridge_post_atomic_disable,
+	.mode_set		= dw_mipi_dsi2_bridge_mode_set,
+	.mode_valid		= dw_mipi_dsi2_bridge_mode_valid,
+	.attach			= dw_mipi_dsi2_bridge_attach,
+};
+
+static const struct regmap_config dw_mipi_dsi2_regmap_config = {
+	.name = "dsi2-host",
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.fast_io = true,
+};
+
+static struct dw_mipi_dsi2 *
+__dw_mipi_dsi2_probe(struct platform_device *pdev,
+		     const struct dw_mipi_dsi2_plat_data *plat_data)
+{
+	struct device *dev = &pdev->dev;
+	struct reset_control *apb_rst;
+	struct dw_mipi_dsi2 *dsi2;
+	int ret;
+
+	dsi2 = devm_kzalloc(dev, sizeof(*dsi2), GFP_KERNEL);
+	if (!dsi2)
+		return ERR_PTR(-ENOMEM);
+
+	dsi2->dev = dev;
+	dsi2->plat_data = plat_data;
+
+	if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps ||
+	    !plat_data->phy_ops->get_timing)
+		return dev_err_ptr_probe(dev, -ENODEV, "Phy not properly configured\n");
+
+	if (!plat_data->regmap) {
+		void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
+
+		if (IS_ERR(base))
+			return dev_err_cast_probe(dev, base, "failed to registers\n");
+
+		dsi2->regmap = devm_regmap_init_mmio(dev, base,
+						     &dw_mipi_dsi2_regmap_config);
+		if (IS_ERR(dsi2->regmap))
+			return dev_err_cast_probe(dev, dsi2->regmap, "failed to init regmap\n");
+	} else {
+		dsi2->regmap = plat_data->regmap;
+	}
+
+	dsi2->pclk = devm_clk_get(dev, "pclk");
+	if (IS_ERR(dsi2->pclk))
+		return dev_err_cast_probe(dev, dsi2->pclk, "Unable to get pclk\n");
+
+	dsi2->sys_clk = devm_clk_get(dev, "sys");
+	if (IS_ERR(dsi2->sys_clk))
+		return dev_err_cast_probe(dev, dsi2->sys_clk, "Unable to get sys_clk\n");
+
+	/*
+	 * Note that the reset was not defined in the initial device tree, so
+	 * we have to be prepared for it not being found.
+	 */
+	apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb");
+	if (IS_ERR(apb_rst))
+		return dev_err_cast_probe(dev, apb_rst, "Unable to get reset control\n");
+
+	if (apb_rst) {
+		ret = clk_prepare_enable(dsi2->pclk);
+		if (ret) {
+			dev_err(dev, "%s: Failed to enable pclk\n", __func__);
+			return ERR_PTR(ret);
+		}
+
+		reset_control_assert(apb_rst);
+		usleep_range(10, 20);
+		reset_control_deassert(apb_rst);
+
+		clk_disable_unprepare(dsi2->pclk);
+	}
+
+	pm_runtime_enable(dev);
+
+	dsi2->dsi_host.ops = &dw_mipi_dsi2_host_ops;
+	dsi2->dsi_host.dev = dev;
+	ret = mipi_dsi_host_register(&dsi2->dsi_host);
+	if (ret) {
+		dev_err(dev, "Failed to register MIPI host: %d\n", ret);
+		pm_runtime_disable(dev);
+		return ERR_PTR(ret);
+	}
+
+	dsi2->bridge.driver_private = dsi2;
+	dsi2->bridge.funcs = &dw_mipi_dsi2_bridge_funcs;
+	dsi2->bridge.of_node = pdev->dev.of_node;
+
+	return dsi2;
+}
+
+static void __dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2)
+{
+	mipi_dsi_host_unregister(&dsi2->dsi_host);
+
+	pm_runtime_disable(dsi2->dev);
+}
+
+/*
+ * Probe/remove API, used to create the bridge instance.
+ */
+struct dw_mipi_dsi2 *
+dw_mipi_dsi2_probe(struct platform_device *pdev,
+		   const struct dw_mipi_dsi2_plat_data *plat_data)
+{
+	return __dw_mipi_dsi2_probe(pdev, plat_data);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi2_probe);
+
+void dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2)
+{
+	__dw_mipi_dsi2_remove(dsi2);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi2_remove);
+
+/*
+ * Bind/unbind API, used from platforms based on the component framework
+ * to attach the bridge to an encoder.
+ */
+int dw_mipi_dsi2_bind(struct dw_mipi_dsi2 *dsi2, struct drm_encoder *encoder)
+{
+	return drm_bridge_attach(encoder, &dsi2->bridge, NULL, 0);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi2_bind);
+
+void dw_mipi_dsi2_unbind(struct dw_mipi_dsi2 *dsi2)
+{
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi2_unbind);
+
+MODULE_AUTHOR("Guochun Huang <hero.huang at rock-chips.com>");
+MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner at cherry.de>");
+MODULE_DESCRIPTION("DW MIPI DSI2 host controller driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dw-mipi-dsi2");
diff --git a/include/drm/bridge/dw_mipi_dsi2.h b/include/drm/bridge/dw_mipi_dsi2.h
new file mode 100644
index 000000000000..c18c49379247
--- /dev/null
+++ b/include/drm/bridge/dw_mipi_dsi2.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Authors: Guochun Huang <hero.huang at rock-chips.com>
+ *          Heiko Stuebner <heiko.stuebner at cherry.de>
+ */
+
+#ifndef __DW_MIPI_DSI2__
+#define __DW_MIPI_DSI2__
+
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_modes.h>
+
+struct drm_display_mode;
+struct drm_encoder;
+struct dw_mipi_dsi2;
+struct mipi_dsi_device;
+struct platform_device;
+
+enum dw_mipi_dsi2_phy_type {
+	DW_MIPI_DSI2_DPHY,
+	DW_MIPI_DSI2_CPHY,
+};
+
+struct dw_mipi_dsi2_phy_iface {
+	int ppi_width;
+	enum dw_mipi_dsi2_phy_type phy_type;
+};
+
+struct dw_mipi_dsi2_phy_timing {
+	u32 data_hs2lp;
+	u32 data_lp2hs;
+};
+
+struct dw_mipi_dsi2_phy_ops {
+	int (*init)(void *priv_data);
+	void (*power_on)(void *priv_data);
+	void (*power_off)(void *priv_data);
+	void (*get_interface)(void *priv_data, struct dw_mipi_dsi2_phy_iface *iface);
+	int (*get_lane_mbps)(void *priv_data,
+			     const struct drm_display_mode *mode,
+			     unsigned long mode_flags, u32 lanes, u32 format,
+			     unsigned int *lane_mbps);
+	int (*get_timing)(void *priv_data, unsigned int lane_mbps,
+			  struct dw_mipi_dsi2_phy_timing *timing);
+	int (*get_esc_clk_rate)(void *priv_data, unsigned int *esc_clk_rate);
+};
+
+struct dw_mipi_dsi2_host_ops {
+	int (*attach)(void *priv_data,
+		      struct mipi_dsi_device *dsi);
+	int (*detach)(void *priv_data,
+		      struct mipi_dsi_device *dsi);
+};
+
+struct dw_mipi_dsi2_plat_data {
+	struct regmap *regmap;
+	unsigned int max_data_lanes;
+
+	enum drm_mode_status (*mode_valid)(void *priv_data,
+					   const struct drm_display_mode *mode,
+					   unsigned long mode_flags,
+					   u32 lanes, u32 format);
+
+	bool (*mode_fixup)(void *priv_data, const struct drm_display_mode *mode,
+			   struct drm_display_mode *adjusted_mode);
+
+	u32 *(*get_input_bus_fmts)(void *priv_data,
+				   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);
+
+	const struct dw_mipi_dsi2_phy_ops *phy_ops;
+	const struct dw_mipi_dsi2_host_ops *host_ops;
+
+	void *priv_data;
+};
+
+struct dw_mipi_dsi2 *dw_mipi_dsi2_probe(struct platform_device *pdev,
+					const struct dw_mipi_dsi2_plat_data *plat_data);
+void dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2);
+int dw_mipi_dsi2_bind(struct dw_mipi_dsi2 *dsi2, struct drm_encoder *encoder);
+void dw_mipi_dsi2_unbind(struct dw_mipi_dsi2 *dsi2);
+
+#endif /* __DW_MIPI_DSI2__ */
-- 
2.45.2



From robh at kernel.org  Tue Dec  3 08:58:27 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 3 Dec 2024 10:58:27 -0600
Subject: [PATCH v1 07/10] dt-bindings: display: rockchip: Fix label name
 of hdptxphy for RK3588 HDMI TX Controller
In-Reply-To: <20241127075157.856029-8-damon.ding@rock-chips.com>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <20241127075157.856029-8-damon.ding@rock-chips.com>
Message-ID: <173324510682.1955832.14077962445640350158.robh@kernel.org>


On Wed, 27 Nov 2024 15:51:54 +0800, Damon Ding wrote:
> The hdptxphy is a combo transmit-PHY for HDMI2.1 TMDS Link, FRL Link, DP
> and eDP Link. Therefore, it is better to name it hdptxphy0 other than
> hdptxphy_hdmi0, which will be referenced by both hdmi0 and edp0 nodes.
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> ---
>  .../bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml   | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From christian.bruel at foss.st.com  Tue Dec  3 08:55:28 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 3 Dec 2024 17:55:28 +0100
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <20241203133434.2qbohwi3wrjjja5a@thinkpad>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-2-christian.bruel@foss.st.com>
 <20241203133434.2qbohwi3wrjjja5a@thinkpad>
Message-ID: <4a56d133-0173-4ad5-8d36-70d538c88ba7@foss.st.com>



On 12/3/24 14:34, Manivannan Sadhasivam wrote:
> On Tue, Nov 26, 2024 at 04:51:15PM +0100, Christian Bruel wrote:
>> Document the bindings for STM32MP25 PCIe Controller configured in
>> root complex mode.
>>
>> Supports 4 legacy interrupts and MSI interrupts from the ARM
>> GICv2m controller.
>>
>> STM32 PCIe may be in a power domain which is the case for the STM32MP25
>> based boards.
>>
>> Supports wake# from wake-gpios
>>
>> Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
>> ---
>>   .../bindings/pci/st,stm32-pcie-common.yaml    | 45 +++++++++
>>   .../bindings/pci/st,stm32-pcie-host.yaml      | 99 +++++++++++++++++++
>>   2 files changed, 144 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/pci/st,stm32-pcie-common.yaml
>>   create mode 100644 Documentation/devicetree/bindings/pci/st,stm32-pcie-host.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/pci/st,stm32-pcie-common.yaml b/Documentation/devicetree/bindings/pci/st,stm32-pcie-common.yaml
>> new file mode 100644
>> index 000000000000..479c03134da3
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/st,stm32-pcie-common.yaml
>> @@ -0,0 +1,45 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/pci/st,stm32-pcie-common.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: STM32MP25 PCIe RC/EP controller
>> +
>> +maintainers:
>> +  - Christian Bruel <christian.bruel at foss.st.com>
>> +
>> +description:
>> +  STM32MP25 PCIe RC/EP common properties
>> +
>> +properties:
>> +  clocks:
>> +    maxItems: 1
>> +    description: PCIe system clock
>> +
>> +  resets:
>> +    maxItems: 1
>> +
>> +  phys:
>> +    maxItems: 1
>> +
>> +  phy-names:
>> +    const: pcie-phy
>> +
>> +  power-domains:
>> +    maxItems: 1
>> +
>> +  access-controllers:
>> +    maxItems: 1
>> +
>> +  reset-gpios:
>> +    description: GPIO controlled connection to PERST# signal
>> +    maxItems: 1
>> +
>> +required:
>> +  - clocks
>> +  - resets
>> +  - phys
>> +  - phy-names
>> +
>> +additionalProperties: true
>> diff --git a/Documentation/devicetree/bindings/pci/st,stm32-pcie-host.yaml b/Documentation/devicetree/bindings/pci/st,stm32-pcie-host.yaml
>> new file mode 100644
>> index 000000000000..18083cc69024
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/st,stm32-pcie-host.yaml
>> @@ -0,0 +1,99 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/pci/st,stm32-pcie-host.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: STM32MP25 PCIe root complex driver
>> +
>> +maintainers:
>> +  - Christian Bruel <christian.bruel at foss.st.com>
>> +
>> +description:
>> +  PCIe root complex controller based on the Synopsys DesignWare PCIe core.
>> +
>> +allOf:
>> +  - $ref: /schemas/pci/snps,dw-pcie.yaml#
>> +  - $ref: /schemas/pci/st,stm32-pcie-common.yaml#
>> +
>> +select:
>> +  properties:
>> +    compatible:
>> +      const: st,stm32mp25-pcie-rc
>> +  required:
>> +    - compatible
>> +
>> +properties:
>> +  compatible:
>> +    const: st,stm32mp25-pcie-rc
>> +
>> +  reg:
>> +    items:
>> +      - description: Data Bus Interface (DBI) registers.
>> +      - description: PCIe configuration registers.
>> +
>> +  reg-names:
>> +    items:
>> +      - const: dbi
>> +      - const: config
>> +
>> +  num-lanes:
>> +    const: 1
>> +
>> +  msi-parent:
>> +    maxItems: 1
>> +
>> +  wake-gpios:
>> +    description: GPIO controlled connection to WAKE# input signal
>> +    maxItems: 1
>> +
>> +  wakeup-source: true
>> +
>> +dependentRequired:
>> +  wakeup-source: [ wake-gpios ]
>> +
>> +required:
>> +  - interrupt-map
>> +  - interrupt-map-mask
>> +  - ranges
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
>> +    #include <dt-bindings/gpio/gpio.h>
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +    #include <dt-bindings/phy/phy.h>
>> +    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
>> +
>> +    pcie at 48400000 {
>> +        compatible = "st,stm32mp25-pcie-rc";
>> +        device_type = "pci";
>> +        num-lanes = <1>;
>> +        reg = <0x48400000 0x400000>,
>> +              <0x10000000 0x10000>;
>> +        reg-names = "dbi", "config";
>> +        #interrupt-cells = <1>;
>> +        interrupt-map-mask = <0 0 0 7>;
>> +        interrupt-map = <0 0 0 1 &intc 0 0 GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
>> +                        <0 0 0 2 &intc 0 0 GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
>> +                        <0 0 0 3 &intc 0 0 GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
>> +                        <0 0 0 4 &intc 0 0 GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
>> +        #address-cells = <3>;
>> +        #size-cells = <2>;
>> +        ranges = <0x01000000 0 0x10010000 0x10010000 0 0x10000>,
> 
> PCI address of I/O region should start from address 0x00000000.
> 
ok, thanks !

> Also use hex notation for all values.
> 
> - Mani
> 


From broonie at kernel.org  Tue Dec  3 08:53:11 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 3 Dec 2024 16:53:11 +0000
Subject: [PATCH 4/6] arm64/signal: Consistently invalidate the in
 register FP state in restore
In-Reply-To: <Z08k6QsYRzO8+O4t@e133380.arm.com>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-4-d853479d1b77@kernel.org>
 <Z08k6QsYRzO8+O4t@e133380.arm.com>
Message-ID: <f9e297ab-8325-4b48-b8fc-21486ff48cd2@sirena.org.uk>

On Tue, Dec 03, 2024 at 03:34:01PM +0000, Dave Martin wrote:
> On Tue, Dec 03, 2024 at 12:45:56PM +0000, Mark Brown wrote:
> > When restoring the SVE and SME specific floating point register states we
> > flush the task floating point state, marking the hardware state as stale so
> > that preemption does not result in us saving register state from the signal

Now I think about it again this should probably be dropped from the
series, or at least ordered after the reenablement.

> > +	 * thread floating point state with preemption enabled, so
> > +	 * protection is needed to prevent a racing context switch
> > +	 * from writing stale registers back over the new data. Mark
> > +	 * the register floating point state as invalid and unbind the
> > +	 * task from the CPU to force a reload before we return to
> > +	 * userspace. fpsimd_flush_task_state() has a check for FP
> > +	 * support.
> > +	 */

> Maybe add a comment in fpsimd_flush_task_state() about why the
> system_supports_fpsimd() check is important?  It's not obvious there
> why we should ever be calling that function on non-FPSIMD systems.

There already is a comment in there about it?

> But would it be a good idea to stick a
> WARN_ON(!test_thread_flag(TIF_FOREIGN_FPSTATE)) at the start of the
> functions that rely on this?

As I mentioned in reply to one of your other messages I want to just gut
the whole API here and replace it with get/put functions for the state
which would include the get/put functions making sure they're paired
with each other.

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/20241203/595016b4/attachment.sig>

From heiko at sntech.de  Tue Dec  3 08:54:46 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  3 Dec 2024 17:54:46 +0100
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2 controller
Message-ID: <20241203165450.1501219-1-heiko@sntech.de>

This series adds a bridge and glue driver for the DSI2 controller found
in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.

As the manual states:
The Display Serial Interface 2 (DSI-2) is part of a group of communication
protocols defined by the MIPI Alliance. The MIPI DSI-2 Host Controller is
a digital core that implements all protocol functions defined in the
MIPI DSI-2 Specification.


While the driver structure is very similar to the previous DSI controller,
the programming model of the core is quite different, with a completely
new register set.

Another notable difference is that the phy interface is variable now too
in its width and some other settings.

changes in v3:
- remove double-empty line in bridge part (Neil)
- add bitfield.h to both bridge and glue for FIELD_PROP
  (reported by kernel test robot)
- add Neil's Reviewed-by to bridge part
- add Rob's Reviewed-by to binding

changes in v2:
- clean up includes (Diederik)
- fix Kconfig description (Diederik)
- constant naming (Diederik)
- binding fixes (paths, sorting, labels) (Rob)
- move to use regmap
- drop custom UPDATE macro and use FIELD_PREP instead
- use dev_err instead of DRM_DEV_ERROR

Heiko Stuebner (3):
  drm/bridge/synopsys: Add MIPI DSI2 host controller bridge
  dt-bindings: display: rockchip: Add schema for RK3588 DW DSI2
    controller
  drm/rockchip: Add MIPI DSI2 glue driver for RK3588

 .../rockchip/rockchip,rk3588-mipi-dsi2.yaml   |  119 ++
 drivers/gpu/drm/bridge/synopsys/Kconfig       |    6 +
 drivers/gpu/drm/bridge/synopsys/Makefile      |    1 +
 .../gpu/drm/bridge/synopsys/dw-mipi-dsi2.c    | 1030 +++++++++++++++++
 drivers/gpu/drm/rockchip/Kconfig              |   10 +
 drivers/gpu/drm/rockchip/Makefile             |    1 +
 .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c  |  524 +++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |    2 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |    1 +
 include/drm/bridge/dw_mipi_dsi2.h             |   95 ++
 10 files changed, 1789 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml
 create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
 create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
 create mode 100644 include/drm/bridge/dw_mipi_dsi2.h

-- 
2.45.2



From Dave.Martin at arm.com  Tue Dec  3 09:00:08 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 3 Dec 2024 17:00:08 +0000
Subject: [PATCH 1/6] arm64/sme: Flush foreign register state in
 do_sme_acc()
In-Reply-To: <9365be76-8da6-47ce-b88e-dfa244b9e5b7@sirena.org.uk>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-1-d853479d1b77@kernel.org>
 <Z08khk6Mg6+T6VV9@e133380.arm.com>
 <9365be76-8da6-47ce-b88e-dfa244b9e5b7@sirena.org.uk>
Message-ID: <Z085GKS8jzEhcZdW@e133380.arm.com>

On Tue, Dec 03, 2024 at 04:00:45PM +0000, Mark Brown wrote:
> On Tue, Dec 03, 2024 at 03:32:22PM +0000, Dave Martin wrote:
> > On Tue, Dec 03, 2024 at 12:45:53PM +0000, Mark Brown wrote:
> 
> > > @@ -1460,6 +1460,8 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
> > >  		sme_set_vq(vq_minus_one);
> > >  
> > >  		fpsimd_bind_task_to_cpu();
> > > +	} else {
> > > +		fpsimd_flush_task_state(current);
> 
> > TIF_FOREIGN_FPSTATE is (or was) a cache of the task<->CPU binding that
> > you're clobbering here.
> 
> > So, this fpsimd_flush_task_state() should have no effect unless
> > TIF_FOREIGN_FPSTATE is already wrong?  I'm wondering if the apparent
> > need for this means that there is an undiagnosed bug elsewhere.
> 
> > (My understanding is based on FPSIMD/SVE; I'm less familiar with the
> > SME changes, so I may be missing something important here.)
> 
> It's to ensure that the last recorded CPU for the current task is
> invalid so that if the state was loaded on another CPU and we switch
> back to that CPU we reload the state from memory, we need to at least
> trigger configuration of the SME VL.

OK, so the logic here is something like:

Disregarding SME, the FPSIMD/SVE regs are up to date, which is fine
because SME is trapped.

When we take the SME trap, we suddenly have some work to do in order to
make sure that the SME-specific parts of the register state are up to
date, so we need to mark the state as stale before setting TIF_SME and
returning.

fpsimd_flush_task_state() means that we do the necessary work when re-
entering userspace, but is there a problem with simply marking all the
FPSIMD/vector state as stale?  If FPSR or FPCR is dirty for example, it
now looks like they won't get written back to thread struct if there is
a context switch before current re-enters userspace?

Maybe the other flags distinguish these cases -- I haven't fully got my
head around it.


(Actually, the ARM ARM says (IMHTLZ) that toggling PSTATE.SM by any
means causes FPSR to become 0x800009f.  I'm not sure where that fits in
-- do we handle that anywhere?  I guess the "soft" SM toggling via
ptrace, signal delivery or maybe exec, ought to set this?  Not sure how
that interacts with the expected behaviour of the fenv(3) API...  Hmm.
I see no corresponding statement about FPCR.)

Cheers
---Dave


From Dave.Martin at arm.com  Tue Dec  3 09:06:34 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 3 Dec 2024 17:06:34 +0000
Subject: [PATCH 4/6] arm64/signal: Consistently invalidate the in
 register FP state in restore
In-Reply-To: <f9e297ab-8325-4b48-b8fc-21486ff48cd2@sirena.org.uk>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-4-d853479d1b77@kernel.org>
 <Z08k6QsYRzO8+O4t@e133380.arm.com>
 <f9e297ab-8325-4b48-b8fc-21486ff48cd2@sirena.org.uk>
Message-ID: <Z086mm/qzNCRB2jH@e133380.arm.com>

Hi,

On Tue, Dec 03, 2024 at 04:53:11PM +0000, Mark Brown wrote:
> On Tue, Dec 03, 2024 at 03:34:01PM +0000, Dave Martin wrote:
> > On Tue, Dec 03, 2024 at 12:45:56PM +0000, Mark Brown wrote:
> > > When restoring the SVE and SME specific floating point register states we
> > > flush the task floating point state, marking the hardware state as stale so
> > > that preemption does not result in us saving register state from the signal
> 
> Now I think about it again this should probably be dropped from the
> series, or at least ordered after the reenablement.
> 
> > > +	 * thread floating point state with preemption enabled, so
> > > +	 * protection is needed to prevent a racing context switch
> > > +	 * from writing stale registers back over the new data. Mark
> > > +	 * the register floating point state as invalid and unbind the
> > > +	 * task from the CPU to force a reload before we return to
> > > +	 * userspace. fpsimd_flush_task_state() has a check for FP
> > > +	 * support.
> > > +	 */
> 
> > Maybe add a comment in fpsimd_flush_task_state() about why the
> > system_supports_fpsimd() check is important?  It's not obvious there
> > why we should ever be calling that function on non-FPSIMD systems.
> 
> There already is a comment in there about it?

There's a comment, but it's not clear that calling that function is
considered correct / useful if there is no FPSIMD.

Not a big deal, anyhow.

> > But would it be a good idea to stick a
> > WARN_ON(!test_thread_flag(TIF_FOREIGN_FPSTATE)) at the start of the
> > functions that rely on this?
> 
> As I mentioned in reply to one of your other messages I want to just gut
> the whole API here and replace it with get/put functions for the state
> which would include the get/put functions making sure they're paired
> with each other.

No argument from me on that, but it would be good to have a way to
check that functions that expect to be called with the FP context held,
actually are (similar to lockdep_assert_held() etc.)

If the number of affected functions is low, I guess comments may be
enough, though.

> 
> 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.

Ack, but opinions can differ about what context is unneeded.

I'll try to keep the noise down on these threads.

Cheers
---Dave


From Dave.Martin at arm.com  Tue Dec  3 09:10:23 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 3 Dec 2024 17:10:23 +0000
Subject: [PATCH 5/6] arm64/signal: Avoid corruption of SME state when
 entering signal handler
In-Reply-To: <537fe318-a679-4b5c-b87f-93a7812dbeca@sirena.org.uk>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-5-d853479d1b77@kernel.org>
 <Z08kvi0znVM2RHx4@e133380.arm.com>
 <537fe318-a679-4b5c-b87f-93a7812dbeca@sirena.org.uk>
Message-ID: <Z087f9lkTBPFyOzA@e133380.arm.com>

Hi,

On Tue, Dec 03, 2024 at 04:12:33PM +0000, Mark Brown wrote:
> On Tue, Dec 03, 2024 at 03:33:18PM +0000, Dave Martin wrote:
> > On Tue, Dec 03, 2024 at 12:45:57PM +0000, Mark Brown wrote:
> 
> > > +	get_cpu_fpsimd_context();
> 
> > > +		if (current->thread.svcr & SVCR_SM_MASK) {
> > > +			memset(&current->thread.uw.fpsimd_state.vregs, 0,
> > > +			       sizeof(current->thread.uw.fpsimd_state.vregs));
> 
> > Do we need to hold the CPU fpsimd context across this memset?
> 
> > IIRC, TIF_FOREIGN_FPSTATE can be spontaneously cleared along with
> > dumping of the regs into thread_struct (from current's PoV), but never
> > spontaneously set again.  So ... -> [*]
> 
> Yes, we could drop the lock here.  OTOH this is very simple and easy to
> understand.

Ack; it works either way.

Since this is a Fixes: patch, it may be better to keep it simple.

> 
> > > +		/* Ensure any copies on other CPUs aren't reused */
> > > +		fpsimd_flush_task_state(current);
> 
> > (This is very similar to fpsimd_flush_thread(); can they be unified?)
> 
> I have a half finished series to replace the whole setup around
> accessing the state with get/put operations for working on the state
> which should remove all these functions.  The pile of similarly and
> confusingly named operations we have for working on the state is one of
> the major sources of issues with this code, even when actively working
> on the code it's hard to remember exactly which operation does what
> never mind the rules for which is needed.

Sure, something like that would definitely help.

Cheers
---Dave


From robh at kernel.org  Tue Dec  3 09:20:26 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 3 Dec 2024 11:20:26 -0600
Subject: [PATCH] dt-bindings: soc: fsl: cpm_qe: Limit matching to nodes
 with "fsl,qe"
In-Reply-To: <20241202045757.39244-1-wenst@chromium.org>
References: <20241202045757.39244-1-wenst@chromium.org>
Message-ID: <20241203172026.GA1988559-robh@kernel.org>

On Mon, Dec 02, 2024 at 12:57:55PM +0800, Chen-Yu Tsai wrote:
> Otherwise the binding matches against random nodes with "simple-bus"
> giving out all kinds of invalid warnings:
> 
>     $ make CHECK_DTBS=y mediatek/mt8188-evb.dtb
>       SYNC    include/config/auto.conf.cmd
>       UPD     include/config/kernel.release
>       SCHEMA  Documentation/devicetree/bindings/processed-schema.json
>       DTC [C] arch/arm64/boot/dts/mediatek/mt8188-evb.dtb
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: compatible:0: 'fsl,qe' was expected
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: compatible: ['simple-bus'] is too short
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:compatible:0: 'fsl,qe-ic' was expected
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:reg: [[0, 201326592, 0, 262144], [0, 201588736, 0, 2097152]] is too long
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:#interrupt-cells:0:0: 1 was expected
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000: '#redistributor-regions', 'ppi-partitions' do not match any of the regexes: 'pinctrl-[0-9]+'
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: 'reg' is a required property
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
>     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: 'bus-frequency' is a required property
> 	    from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
> 
> Fixes: ecbfc6ff94a2 ("dt-bindings: soc: fsl: cpm_qe: convert to yaml format")
> Cc: Frank Li <Frank.Li at nxp.com>
> Cc: <stable at vger.kernel.org> # v6.11+
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  .../devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml        | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
> index 89cdf5e1d0a8..9e07a2c4d05b 100644
> --- a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
> +++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
> @@ -21,6 +21,14 @@ description: |
>    The description below applies to the qe of MPC8360 and
>    more nodes and properties would be extended in the future.
>  
> +select:
> +  properties:
> +    compatible:
> +      contains:
> +        const: fsl,qe
> +  required:
> +    - compatible

Update your dtschema. The select is no longer necessary. dtbs_check will 
also run 5x faster.

Rob


From linux at leemhuis.info  Tue Dec  3 09:24:19 2024
From: linux at leemhuis.info (Thorsten Leemhuis)
Date: Tue, 3 Dec 2024 18:24:19 +0100
Subject: [PATCH 6.12 470/826] perf stat: Uniquify event name improvements
In-Reply-To: <20241203144802.097952233@linuxfoundation.org>
References: <20241203144743.428732212@linuxfoundation.org>
 <20241203144802.097952233@linuxfoundation.org>
Message-ID: <f2ada8a7-165b-41fb-8b7b-3c0d16bb8216@leemhuis.info>

On 03.12.24 15:43, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Ian Rogers <irogers at google.com>
> 
> [ Upstream commit 057f8bfc6f7070577523d1e3081081bbf4229c1c ]
> 
> Without aggregation on Intel:

My 6.11.y-rc and 6.12.y-rc builds for Fedora failed when building perf. 
I did not bisect, but from a brief look at the error message (see
below) I suspect it might be caused by this patch, which is the
second of the patch-set "Event parsing fixes":
https://lore.kernel.org/all/20240926144851.245903-1-james.clark at linaro.org/

To my untrained eyes and from a quick look I guess the first patch
in the series needs to be backported as well:
perf evsel: Add alternate_hw_config and use in evsel__match
https://lore.kernel.org/all/20240926144851.245903-2-james.clark at linaro.org/

This is 22a4db3c36034e ("perf evsel: Add alternate_hw_config
and use in evsel__match") in mainline. I tried to cherry-pick it
on-top of 6.12.2-rc1, but there were a few small conflicts. 

Ciao, Thorsten

P.S.: The build error:

  gcc -Wp,-MD,util/.topdown.o.d -Wp,-MT,util/topdown.o -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wno-system-headers -Wold-style-definition -Wpacked -Wredundant-decls -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wundef -Wwrite-strings -Wformat -Wno-type-limits -Wstrict-aliasing=3 -Wshadow -DHAVE_SYSCALL_TABLE_SUPPORT -Iarch/x86/include/generated -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET -DNDEBUG=1 -O3 -fno-omit-frame-pointer -Wall -Wextra -std=gnu11 -fstack-protector-all -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/util/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/arch/x86/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/include/ -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/arch/x86/include/uapi -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/include/uapi -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/arch/x86/include/ -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/arch/x86/ -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/util -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf -DHAVE_PTHREAD_ATTR_SETAFFINITY_NP -DHAVE_PTHREAD_BARRIER -DHAVE_EVENTFD_SUPPORT -DHAVE_GET_CURRENT_DIR_NAME -DHAVE_GETTID -DHAVE_FILE_HANDLE -DHAVE_DWARF_GETLOCATIONS_SUPPORT -DHAVE_DWARF_CFI_SUPPORT -DHAVE_AIO_SUPPORT -DHAVE_SCANDIRAT_SUPPORT -DHAVE_SCHED_GETCPU_SUPPORT -DHAVE_SETNS_SUPPORT -DHAVE_ZLIB_SUPPORT -DHAVE_LIBELF_SUPPORT -DHAVE_ELF_GETPHDRNUM_SUPPORT -DHAVE_GELF_GETNOTE_SUPPORT -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT -DHAVE_DWARF_SUPPORT -DHAVE_LIBBPF_SUPPORT -DHAVE_SDT_EVENT -DHAVE_JITDUMP -DHAVE_BPF_SKEL -DHAVE_DWARF_UNWIND_SUPPORT -DHAVE_LIBCRYPTO_SUPPORT -DHAVE_SLANG_SUPPORT -DHAVE_LIBPERL_SUPPORT -DHAVE_TIMERFD_SUPPORT -DHAVE_LIBPYTHON_SUPPORT -fPIC -DHAVE_LIBLLVM_SUPPORT -I/usr/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DHAVE_CXA_DEMANGLE_SUPPORT -DHAVE_LZMA_SUPPORT -DHAVE_ZSTD_SUPPORT -DHAVE_BACKTRACE_SUPPORT -DHAVE_LIBNUMA_SUPPORT -DHAVE_KVM_STAT_SUPPORT -DDISASM_FOUR_ARGS_SIGNATURE -DDISASM_INIT_STYLED -DHAVE_LIBBABELTRACE_SUPPORT -DHAVE_AUXTRACE_SUPPORT -DHAVE_JVMTI_CMLR -DHAVE_LIBTRACEEVENT -I/usr/include/traceevent -DLIBTRACEEVENT_VERSION=67067 -I/usr/include/tracefs -I/usr/include/traceevent -DLIBTRACEFS_VERSION=67065 -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libapi/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libsubcmd/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libsymbol/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libperf/include -D"BUILD_STR(s)=#s" -c -o util/topdown.o util/topdown.c
util/stat-display.c: In function ?uniquify_event_name?:
util/stat-display.c:895:45: error: ?struct evsel? has no member named ?alternate_hw_config?
  895 |         if (counter->pmu->is_core && counter->alternate_hw_config != PERF_COUNT_HW_MAX)
      |                                             ^~
make[4]: *** [/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/build/Makefile.build:106: util/stat-display.o] Error 1
make[4]: *** Waiting for unfinished jobs....

> ```
> $ perf stat -e instructions,cycles ...
> ```
> Will use "cycles" for the name of the legacy cycles event but as
> "instructions" has a sysfs name it will and a "[cpu]" PMU suffix. This
> often breaks things as the space between the event and the PMU name
> look like an extra column. The existing uniquify logic was also
> uniquifying in cases when all events are core and not with uncore
> events, it was not correctly handling modifiers, etc.
> 
> Change the logic so that an initial pass that can disable
> uniquification is run. For individual counters, disable uniquification
> in more cases such as for consistency with legacy events or for
> libpfm4 events. Don't use the "[pmu]" style suffix in uniquification,
> always use "pmu/.../". Change how modifiers/terms are handled in the
> uniquification so that they look like parse-able events.
> 
> This fixes "102: perf stat metrics (shadow stat) test:" that has been
> failing due to "instructions [cpu]" breaking its column/awk logic when
> values aren't aggregated. This started happening when instructions
> could match a sysfs rather than a legacy event, so the fixes tag
> reflects this.
> 
> Fixes: 617824a7f0f7 ("perf parse-events: Prefer sysfs/JSON hardware events over legacy")
> Acked-by: Namhyung Kim <namhyung at kernel.org>
> Signed-off-by: Ian Rogers <irogers at google.com>
> [ Fix Intel TPEBS counting mode test ]
> Acked-by: Kan Liang <kan.liang at linux.intel.com>
> Signed-off-by: James Clark <james.clark at linaro.org>
> Cc: Yang Jihong <yangjihong at bytedance.com>
> Cc: Dominique Martinet <asmadeus at codewreck.org>
> Cc: Colin Ian King <colin.i.king at gmail.com>
> Cc: Howard Chu <howardchu95 at gmail.com>
> Cc: Ze Gao <zegao2021 at gmail.com>
> Cc: Yicong Yang <yangyicong at hisilicon.com>
> Cc: Weilin Wang <weilin.wang at intel.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Jing Zhang <renyu.zj at linux.alibaba.com>
> Cc: Yang Li <yang.lee at linux.alibaba.com>
> Cc: Leo Yan <leo.yan at linux.dev>
> Cc: ak at linux.intel.com
> Cc: Athira Rajeev <atrajeev at linux.vnet.ibm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: Sun Haiyong <sunhaiyong at loongson.cn>
> Cc: John Garry <john.g.garry at oracle.com>
> Link: https://lore.kernel.org/r/20240926144851.245903-3-james.clark at linaro.org
> Signed-off-by: Namhyung Kim <namhyung at kernel.org>
> Signed-off-by: Sasha Levin <sashal at kernel.org>
> ---
>  .../perf/tests/shell/test_stat_intel_tpebs.sh |  11 +-
>  tools/perf/util/stat-display.c                | 101 ++++++++++++++----
>  2 files changed, 85 insertions(+), 27 deletions(-)
> 
> diff --git a/tools/perf/tests/shell/test_stat_intel_tpebs.sh b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
> index c60b29add9801..9a11f42d153ca 100755
> --- a/tools/perf/tests/shell/test_stat_intel_tpebs.sh
> +++ b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
> @@ -8,12 +8,15 @@ grep -q GenuineIntel /proc/cpuinfo || { echo Skipping non-Intel; exit 2; }
>  # Use this event for testing because it should exist in all platforms
>  event=cache-misses:R
>  
> +# Hybrid platforms output like "cpu_atom/cache-misses/R", rather than as above
> +alt_name=/cache-misses/R
> +
>  # Without this cmd option, default value or zero is returned
> -echo "Testing without --record-tpebs"
> -result=$(perf stat -e "$event" true 2>&1)
> -[[ "$result" =~ $event ]] || exit 1
> +#echo "Testing without --record-tpebs"
> +#result=$(perf stat -e "$event" true 2>&1)
> +#[[ "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
>  
>  # In platforms that do not support TPEBS, it should execute without error.
>  echo "Testing with --record-tpebs"
>  result=$(perf stat -e "$event" --record-tpebs -a sleep 0.01 2>&1)
> -[[ "$result" =~ "perf record" && "$result" =~ $event ]] || exit 1
> +[[ "$result" =~ "perf record" && "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
> index ea96e4ebad8c8..cbff43ff8d0fb 100644
> --- a/tools/perf/util/stat-display.c
> +++ b/tools/perf/util/stat-display.c
> @@ -871,38 +871,66 @@ static void printout(struct perf_stat_config *config, struct outstate *os,
>  
>  static void uniquify_event_name(struct evsel *counter)
>  {
> -	char *new_name;
> -	char *config;
> -	int ret = 0;
> +	const char *name, *pmu_name;
> +	char *new_name, *config;
> +	int ret;
>  
> -	if (counter->uniquified_name || counter->use_config_name ||
> -	    !counter->pmu_name || !strncmp(evsel__name(counter), counter->pmu_name,
> -					   strlen(counter->pmu_name)))
> +	/* The evsel was already uniquified. */
> +	if (counter->uniquified_name)
>  		return;
>  
> -	config = strchr(counter->name, '/');
> +	/* Avoid checking to uniquify twice. */
> +	counter->uniquified_name = true;
> +
> +	/* The evsel has a "name=" config term or is from libpfm. */
> +	if (counter->use_config_name || counter->is_libpfm_event)
> +		return;
> +
> +	/* Legacy no PMU event, don't uniquify. */
> +	if  (!counter->pmu ||
> +	     (counter->pmu->type < PERF_TYPE_MAX && counter->pmu->type != PERF_TYPE_RAW))
> +		return;
> +
> +	/* A sysfs or json event replacing a legacy event, don't uniquify. */
> +	if (counter->pmu->is_core && counter->alternate_hw_config != PERF_COUNT_HW_MAX)
> +		return;
> +
> +	name = evsel__name(counter);
> +	pmu_name = counter->pmu->name;
> +	/* Already prefixed by the PMU name. */
> +	if (!strncmp(name, pmu_name, strlen(pmu_name)))
> +		return;
> +
> +	config = strchr(name, '/');
>  	if (config) {
> -		if (asprintf(&new_name,
> -			     "%s%s", counter->pmu_name, config) > 0) {
> -			free(counter->name);
> -			counter->name = new_name;
> -		}
> -	} else {
> -		if (evsel__is_hybrid(counter)) {
> -			ret = asprintf(&new_name, "%s/%s/",
> -				       counter->pmu_name, counter->name);
> +		int len = config - name;
> +
> +		if (config[1] == '/') {
> +			/* case: event// */
> +			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 2);
>  		} else {
> -			ret = asprintf(&new_name, "%s [%s]",
> -				       counter->name, counter->pmu_name);
> +			/* case: event/.../ */
> +			ret = asprintf(&new_name, "%s/%.*s,%s", pmu_name, len, name, config + 1);
>  		}
> +	} else {
> +		config = strchr(name, ':');
> +		if (config) {
> +			/* case: event:.. */
> +			int len = config - name;
>  
> -		if (ret) {
> -			free(counter->name);
> -			counter->name = new_name;
> +			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 1);
> +		} else {
> +			/* case: event */
> +			ret = asprintf(&new_name, "%s/%s/", pmu_name, name);
>  		}
>  	}
> -
> -	counter->uniquified_name = true;
> +	if (ret > 0) {
> +		free(counter->name);
> +		counter->name = new_name;
> +	} else {
> +		/* ENOMEM from asprintf. */
> +		counter->uniquified_name = false;
> +	}
>  }
>  
>  static bool hybrid_uniquify(struct evsel *evsel, struct perf_stat_config *config)
> @@ -1559,6 +1587,31 @@ static void print_cgroup_counter(struct perf_stat_config *config, struct evlist
>  		print_metric_end(config, os);
>  }
>  
> +static void disable_uniquify(struct evlist *evlist)
> +{
> +	struct evsel *counter;
> +	struct perf_pmu *last_pmu = NULL;
> +	bool first = true;
> +
> +	evlist__for_each_entry(evlist, counter) {
> +		/* If PMUs vary then uniquify can be useful. */
> +		if (!first && counter->pmu != last_pmu)
> +			return;
> +		first = false;
> +		if (counter->pmu) {
> +			/* Allow uniquify for uncore PMUs. */
> +			if (!counter->pmu->is_core)
> +				return;
> +			/* Keep hybrid event names uniquified for clarity. */
> +			if (perf_pmus__num_core_pmus() > 1)
> +				return;
> +		}
> +	}
> +	evlist__for_each_entry_continue(evlist, counter) {
> +		counter->uniquified_name = true;
> +	}
> +}
> +
>  void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config,
>  			    struct target *_target, struct timespec *ts,
>  			    int argc, const char **argv)
> @@ -1572,6 +1625,8 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
>  		.first = true,
>  	};
>  
> +	disable_uniquify(evlist);
> +
>  	if (config->iostat_run)
>  		evlist->selected = evlist__first(evlist);
>  



From broonie at kernel.org  Tue Dec  3 09:24:39 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 3 Dec 2024 17:24:39 +0000
Subject: [PATCH 1/6] arm64/sme: Flush foreign register state in
 do_sme_acc()
In-Reply-To: <Z085GKS8jzEhcZdW@e133380.arm.com>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-1-d853479d1b77@kernel.org>
 <Z08khk6Mg6+T6VV9@e133380.arm.com>
 <9365be76-8da6-47ce-b88e-dfa244b9e5b7@sirena.org.uk>
 <Z085GKS8jzEhcZdW@e133380.arm.com>
Message-ID: <44d67835-1e43-47cc-9a18-c279c885dcec@sirena.org.uk>

On Tue, Dec 03, 2024 at 05:00:08PM +0000, Dave Martin wrote:
> On Tue, Dec 03, 2024 at 04:00:45PM +0000, Mark Brown wrote:

> > It's to ensure that the last recorded CPU for the current task is
> > invalid so that if the state was loaded on another CPU and we switch
> > back to that CPU we reload the state from memory, we need to at least
> > trigger configuration of the SME VL.

> OK, so the logic here is something like:

> Disregarding SME, the FPSIMD/SVE regs are up to date, which is fine
> because SME is trapped.

> When we take the SME trap, we suddenly have some work to do in order to
> make sure that the SME-specific parts of the register state are up to
> date, so we need to mark the state as stale before setting TIF_SME and
> returning.

We know that the only bit of register state which is not up to date at
this point is the SME vector length, we don't configure that for tasks
that do not have SME.  SVCR is always configured since we have to exit
streaming mode for FPSIMD and SVE to work properly so we know it's
already 0, all the other SME specific state is gated by controls in
SVCR.

> fpsimd_flush_task_state() means that we do the necessary work when re-
> entering userspace, but is there a problem with simply marking all the
> FPSIMD/vector state as stale?  If FPSR or FPCR is dirty for example, it
> now looks like they won't get written back to thread struct if there is
> a context switch before current re-enters userspace?

> Maybe the other flags distinguish these cases -- I haven't fully got my
> head around it.

We are doing fpsimd_flush_task_state() in the TIF_FOREIGN_FPSTATE case
so we know there is no dirty state in the registers.

> (Actually, the ARM ARM says (IMHTLZ) that toggling PSTATE.SM by any
> means causes FPSR to become 0x800009f.  I'm not sure where that fits in
> -- do we handle that anywhere?  I guess the "soft" SM toggling via

Urgh, not seen that one - that needs handling in the signal entry path
and ptrace.  That will have been defined while the feature was being
implemented.  It's not relevant here though since we are in the SME
access trap, we might be trapping due to a SMSTART or equivalent
operation but that SMSTART has not yet run at the point where we return
to userspace.

> ptrace, signal delivery or maybe exec, ought to set this?  Not sure how
> that interacts with the expected behaviour of the fenv(3) API...  Hmm.
> I see no corresponding statement about FPCR.)

Fun.  I'm not sure how the ABI is defined there by libc.
-------------- 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/20241203/5a94b72e/attachment.sig>

From dmitry.baryshkov at linaro.org  Tue Dec  3 09:26:31 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 3 Dec 2024 19:26:31 +0200
Subject: [PATCH v3 2/3] drm/bridge: ti-sn65dsi83: Add ti, lvds-vod-swing
 optional properties
In-Reply-To: <20241203110054.2506123-3-andrej.picej@norik.com>
References: <20241203110054.2506123-1-andrej.picej@norik.com>
 <20241203110054.2506123-3-andrej.picej@norik.com>
Message-ID: <sjcspny5lmynm4q2dnkhktvwte5e3gigtujynaiqp5gr5rkqfn@j2h5f6xiwz34>

On Tue, Dec 03, 2024 at 12:00:53PM +0100, Andrej Picej wrote:
> Add a optional properties to change LVDS output voltage. This should not
> be static as this depends mainly on the connected display voltage
> requirement. We have three properties:
> - "ti,lvds-termination-ohms", which sets near end termination,
> - "ti,lvds-vod-swing-data-microvolt" and
> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> output voltage for data and clock lanes. They are defined as an array
> with min and max values. The appropriate bitfiled will be set if
> selected constraints can be met.
> 
> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> end termination will be used. Selecting only one:
> "ti,lvds-vod-swing-data-microvolt" or
> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> constraint for only data/clock lanes will be met. Setting both is
> recommended.
> 
> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> ---
> Changes in v3:
> - use microvolts for default array values 1000 mV -> 1000000 uV.
> Changes in v2:
> - use datasheet tables to get the proper configuration
> - since major change was done change the authorship to myself
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi83.c | 144 +++++++++++++++++++++++++-
>  1 file changed, 141 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> index 57a7ed13f996..1a070df5ea12 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> @@ -132,6 +132,16 @@
>  #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>  #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>  
> +enum sn65dsi83_channel {
> +	CHANNEL_A,
> +	CHANNEL_B
> +};
> +
> +enum sn65dsi83_lvds_term {
> +	OHM_100,
> +	OHM_200
> +};
> +
>  enum sn65dsi83_model {
>  	MODEL_SN65DSI83,
>  	MODEL_SN65DSI84,
> @@ -147,6 +157,10 @@ struct sn65dsi83 {
>  	struct regulator		*vcc;
>  	bool				lvds_dual_link;
>  	bool				lvds_dual_link_even_odd_swap;
> +	int				lvdsA_vod_swing_conf;
> +	int				lvdsB_vod_swing_conf;
> +	int				lvdsA_term_conf;
> +	int				lvdsB_term_conf;
>  };
>  
>  static const struct regmap_range sn65dsi83_readable_ranges[] = {
> @@ -237,6 +251,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>  	.max_register = REG_IRQ_STAT,
>  };
>  
> +static const int lvds_vod_swing_data_table[2][4][2] = {
> +	{	/* 100 Ohm */
> +		{ 180000, 313000 },
> +		{ 215000, 372000 },
> +		{ 250000, 430000 },
> +		{ 290000, 488000 },
> +	},
> +	{	/* 200 Ohm */
> +		{ 150000, 261000 },
> +		{ 200000, 346000 },
> +		{ 250000, 428000 },
> +		{ 300000, 511000 },
> +	},
> +};
> +
> +static const int lvds_vod_swing_clock_table[2][4][2] = {
> +	{	/* 100 Ohm */
> +		{ 140000, 244000 },
> +		{ 168000, 290000 },
> +		{ 195000, 335000 },
> +		{ 226000, 381000 },
> +	},
> +	{	/* 200 Ohm */
> +		{ 117000, 204000 },
> +		{ 156000, 270000 },
> +		{ 195000, 334000 },
> +		{ 234000, 399000 },
> +	},
> +};
> +
>  static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>  {
>  	return container_of(bridge, struct sn65dsi83, bridge);
> @@ -435,12 +479,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>  		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>  
>  	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvdsA_vod_swing_conf) |
> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvdsB_vod_swing_conf));
>  	regmap_write(ctx->regmap, REG_LVDS_LANE,
>  		     (ctx->lvds_dual_link_even_odd_swap ?
>  		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
> +		     (ctx->lvdsA_term_conf ?
> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
> +		     (ctx->lvdsB_term_conf ?
> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>  	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>  
>  	le16val = cpu_to_le16(mode->hdisplay);
> @@ -576,10 +624,96 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>  	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>  };
>  
> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
> +{
> +	int i;
> +
> +	for (i = 0; i <= 3; i++) {
> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
> +			return i;
> +	}
> +
> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
> +	return -EINVAL;
> +}
> +
> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> +{
> +	struct device *dev = ctx->dev;
> +	struct device_node *endpoint;
> +	/* Set so the property can be freely selected if not defined */
> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
> +	u32 lvds_term = 200;
> +	u8 lvds_term_conf;
> +	int endpoint_reg;
> +	int lvds_vod_swing_conf;
> +	int ret = 0;
> +	int ret_data;
> +	int ret_clock;
> +
> +	if (channel == CHANNEL_A)
> +		endpoint_reg = 2;
> +	else
> +		endpoint_reg = 3;
> +
> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
> +	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
> +
> +	if (lvds_term == 200)
> +		lvds_term_conf = OHM_200;
> +	else
> +		lvds_term_conf = OHM_100;
> +
> +	if (channel == CHANNEL_A)
> +		ctx->lvdsA_term_conf = lvds_term_conf;
> +	else
> +		ctx->lvdsB_term_conf = lvds_term_conf;

This sounds like ctx->lvds_term_conf[channel] = ...;

And so on for other properties.

> +
> +	ret_data = of_property_read_u32_array(endpoint,
> +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
> +			ARRAY_SIZE(lvds_vod_swing_data));
> +	ret_clock = of_property_read_u32_array(endpoint,
> +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
> +			ARRAY_SIZE(lvds_vod_swing_clk));
> +	/* If any of the two properties is defined. */
> +	if (!ret_data || !ret_clock) {

I think it's not that easy. We were usually ignoring errors for a
single-value properties, but for the arrays I think we should make a
diffence between the property being not present in DT and the property
being erroneous or not being parsed correctly.

> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
> +			lvds_vod_swing_data, lvds_vod_swing_clk,
> +			lvds_term_conf);
> +		if (lvds_vod_swing_conf < 0) {
> +			ret = lvds_vod_swing_conf;
> +			goto exit;
> +		}
> +		if (channel == CHANNEL_A)
> +			ctx->lvdsA_vod_swing_conf = lvds_vod_swing_conf;
> +		else
> +			ctx->lvdsB_vod_swing_conf = lvds_vod_swing_conf;
> +	}
> +	ret = 0;
> +exit:
> +	of_node_put(endpoint);
> +	return ret;
> +}
> +
>  static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>  {
>  	struct drm_bridge *panel_bridge;
>  	struct device *dev = ctx->dev;
> +	int ret;
> +
> +	ctx->lvdsA_vod_swing_conf = 0x1;
> +	ctx->lvdsB_vod_swing_conf = 0x1;
> +	ctx->lvdsA_term_conf = 0x1;
> +	ctx->lvdsB_term_conf = 0x1;
> +
> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
> +	if (ret < 0)
> +		return ret;
>  
>  	ctx->lvds_dual_link = false;
>  	ctx->lvds_dual_link_even_odd_swap = false;
> @@ -587,6 +721,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>  		struct device_node *port2, *port3;
>  		int dual_link;
>  
> +		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
> +		if (ret < 0)
> +			return ret;
> +
>  		port2 = of_graph_get_port_by_id(dev->of_node, 2);
>  		port3 = of_graph_get_port_by_id(dev->of_node, 3);
>  		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From afd at ti.com  Tue Dec  3 09:31:11 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 3 Dec 2024 11:31:11 -0600
Subject: [PATCH 2/4] dt-bindings: soc: ti: ti,j721e-system-controller: Add ICSSG ctrl property
In-Reply-To: <20241203173113.90009-1-afd@ti.com>
References: <20241203173113.90009-1-afd@ti.com>
Message-ID: <20241203173113.90009-2-afd@ti.com>

Add a pattern property for icssg-ctrl which can be part of this controller.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 .../bindings/soc/ti/ti,j721e-system-controller.yaml         | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
index 378e9cc5fac2a..9ba9cb100ab30 100644
--- a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
+++ b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
@@ -68,6 +68,12 @@ patternProperties:
     description:
       The node corresponding to SoC chip identification.
 
+  "^icssg-ctrl@[0-9a-f]+$":
+    type: object
+    $ref: /schemas/mfd/syscon.yaml#
+    description:
+      This is the ICSSG control region.
+
 required:
   - compatible
   - reg
-- 
2.39.2



From afd at ti.com  Tue Dec  3 09:31:13 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 3 Dec 2024 11:31:13 -0600
Subject: [PATCH 4/4] dt-bindings: soc: ti: ti,j721e-system-controller: Add MAC efuse property
In-Reply-To: <20241203173113.90009-1-afd@ti.com>
References: <20241203173113.90009-1-afd@ti.com>
Message-ID: <20241203173113.90009-4-afd@ti.com>

Add a pattern property for MAC efuse which can be part of this controller.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 .../bindings/soc/ti/ti,j721e-system-controller.yaml         | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
index ead0679b30e3f..fbaae3d1bef60 100644
--- a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
+++ b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
@@ -80,6 +80,12 @@ patternProperties:
     description:
       This is the PCIe control region.
 
+  "^ethernet-mac-syscon@[0-9a-f]+$":
+    type: object
+    $ref: /schemas/mfd/syscon.yaml#
+    description:
+      This is the Ethernet MAC efuse region.
+
 required:
   - compatible
   - reg
-- 
2.39.2



From afd at ti.com  Tue Dec  3 09:31:10 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 3 Dec 2024 11:31:10 -0600
Subject: [PATCH 1/4] dt-bindings: mfd: syscon: Add ti,am654-icssg-ctrl compatible
Message-ID: <20241203173113.90009-1-afd@ti.com>

Add TI ICSSG control registers compatible. This is a region found in the
TI AM65 CTRL_MMR0 register space[0]. Each instance is used to control a
an ICSSG's RGMII delay and GPO mode.

[0] https://www.ti.com/lit/pdf/spruid7

Signed-off-by: Andrew Davis <afd at ti.com>
---
 Documentation/devicetree/bindings/mfd/syscon.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index b414de4fa779b..34943d9fc0ab5 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -115,6 +115,7 @@ select:
           - ti,am625-dss-oldi-io-ctrl
           - ti,am62p-cpsw-mac-efuse
           - ti,am654-dss-oldi-io-ctrl
+          - ti,am654-icssg-ctrl
           - ti,j784s4-acspcie-proxy-ctrl
           - ti,j784s4-pcie-ctrl
           - ti,keystone-pllctrl
@@ -213,6 +214,7 @@ properties:
           - ti,am625-dss-oldi-io-ctrl
           - ti,am62p-cpsw-mac-efuse
           - ti,am654-dss-oldi-io-ctrl
+          - ti,am654-icssg-ctrl
           - ti,j784s4-pcie-ctrl
           - ti,keystone-pllctrl
       - const: syscon
-- 
2.39.2



From afd at ti.com  Tue Dec  3 09:31:12 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 3 Dec 2024 11:31:12 -0600
Subject: [PATCH 3/4] dt-bindings: soc: ti: ti,j721e-system-controller: Add PCIe ctrl property
In-Reply-To: <20241203173113.90009-1-afd@ti.com>
References: <20241203173113.90009-1-afd@ti.com>
Message-ID: <20241203173113.90009-3-afd@ti.com>

Add a pattern property for pcie-ctrl which can be part of this controller.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 .../bindings/soc/ti/ti,j721e-system-controller.yaml         | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
index 9ba9cb100ab30..ead0679b30e3f 100644
--- a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
+++ b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
@@ -74,6 +74,12 @@ patternProperties:
     description:
       This is the ICSSG control region.
 
+  "^pcie-ctrl@[0-9a-f]+$":
+    type: object
+    $ref: /schemas/mfd/syscon.yaml#
+    description:
+      This is the PCIe control region.
+
 required:
   - compatible
   - reg
-- 
2.39.2



From etienne.carriere at foss.st.com  Tue Dec  3 09:39:07 2024
From: etienne.carriere at foss.st.com (Etienne Carriere)
Date: Tue, 3 Dec 2024 18:39:07 +0100
Subject: [PATCH v2 1/2] firmware: arm_scmi: get only min/max clock rates
In-Reply-To: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
Message-ID: <20241203173908.3148794-2-etienne.carriere@foss.st.com>

Remove limitation of 16 clock rates max for discrete clock rates
description when the SCMI firmware supports SCMI Clock protocol v2.0
or later.

Driver clk-scmi.c is only interested in the min and max clock rates.
Get these by querying the first and last discrete rates with SCMI
clock protocol message ID CLOCK_DESCRIBE_RATES since the SCMI
specification v2.0 and later states that rates enumerated by this
command are to be enumerated in "numeric ascending order" [1].

Preserve the implementation that queries all discrete rates (16 rates
max) to support SCMI firmware built on SCMI specification v1.0 [2]
where SCMI Clock protocol v1.0 does not explicitly require rates
described with CLOCK_DESCRIBE_RATES to be in ascending order.

Link: https://developer.arm.com/documentation/den0056 [1]
Link: https://developer.arm.com/documentation/den0056/a [2]
Signed-off-by: Etienne Carriere <etienne.carriere at foss.st.com>
---
Changes since patch series v1:
- Preserve the original implementation and keep using it for SCMI
  Clock protocol v1.0.

---
 drivers/clk/clk-scmi.c            |   4 +-
 drivers/firmware/arm_scmi/clock.c | 112 ++++++++++++++++++++++++++++--
 include/linux/scmi_protocol.h     |   4 +-
 3 files changed, 110 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 15510c2ff21c..09ccd6cea7f2 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -244,8 +244,8 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
 		if (num_rates <= 0)
 			return -EINVAL;
 
-		min_rate = sclk->info->list.rates[0];
-		max_rate = sclk->info->list.rates[num_rates - 1];
+		min_rate = sclk->info->list.min_rate;
+		max_rate = sclk->info->list.max_rate;
 	} else {
 		min_rate = sclk->info->range.min_rate;
 		max_rate = sclk->info->range.max_rate;
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 2ed2279388f0..34fde0b88098 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -223,10 +223,21 @@ scmi_clock_protocol_attributes_get(const struct scmi_protocol_handle *ph,
 	return ret;
 }
 
+/*
+ * Support SCMI_CLOCK protocol v1.0 as described in SCMI specification v1.0
+ * that do not explicitly require clock rates described with command
+ * CLOCK_DESCRIBE_RATES to be in ascending order. The Linux legacy
+ * implementation for these clock supports a max of 16 rates.
+ * In SCMI specification v2.0 and later, rates must be in ascending order
+ * to we query only to min and max rates values.
+ */
+#define SCMI_MAX_NUM_RATES_V1		16
+
 struct scmi_clk_ipriv {
 	struct device *dev;
 	u32 clk_id;
 	struct scmi_clock_info *clk;
+	u64 rates[SCMI_MAX_NUM_RATES_V1];
 };
 
 static void iter_clk_possible_parents_prepare_message(void *message, unsigned int desc_index,
@@ -493,7 +504,7 @@ iter_clk_describe_process_response(const struct scmi_protocol_handle *ph,
 			break;
 		}
 	} else {
-		u64 *rate = &p->clk->list.rates[st->desc_index + st->loop_idx];
+		u64 *rate = &p->rates[st->desc_index + st->loop_idx];
 
 		*rate = RATE_TO_U64(r->rate[st->loop_idx]);
 		p->clk->list.num_rates++;
@@ -519,7 +530,7 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id,
 		.dev = ph->dev,
 	};
 
-	iter = ph->hops->iter_response_init(ph, &ops, SCMI_MAX_NUM_RATES,
+	iter = ph->hops->iter_response_init(ph, &ops, ARRAY_SIZE(cpriv.rates),
 					    CLOCK_DESCRIBE_RATES,
 					    sizeof(struct scmi_msg_clock_describe_rates),
 					    &cpriv);
@@ -535,10 +546,95 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id,
 			clk->range.min_rate, clk->range.max_rate,
 			clk->range.step_size);
 	} else if (clk->list.num_rates) {
-		sort(clk->list.rates, clk->list.num_rates,
-		     sizeof(clk->list.rates[0]), rate_cmp_func, NULL);
+		sort(cpriv.rates, clk->list.num_rates,
+		     sizeof(cpriv.rates[0]), rate_cmp_func, NULL);
+		clk->list.min_rate = cpriv.rates[0];
+		clk->list.max_rate = cpriv.rates[clk->list.num_rates - 1];
+	}
+
+	return ret;
+}
+
+static int scmi_clock_get_rates_bound(const struct scmi_protocol_handle *ph,
+				      u32 clk_id, struct scmi_clock_info *clk)
+{
+	struct scmi_msg_clock_describe_rates *msg;
+	const struct scmi_msg_resp_clock_describe_rates *resp;
+	unsigned int num_returned, num_remaining;
+	struct scmi_xfer *t;
+	int ret;
+
+	/* Get either the range triplet or the min rate & rates count */
+	ret = ph->xops->xfer_get_init(ph, CLOCK_DESCRIBE_RATES, sizeof(*msg), 0,
+				      &t);
+	if (ret)
+		return ret;
+
+	msg = t->tx.buf;
+	msg->id = cpu_to_le32(clk_id);
+	msg->rate_index = 0;
+
+	resp = t->rx.buf;
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (ret)
+		goto out;
+
+	clk->rate_discrete = RATE_DISCRETE(resp->num_rates_flags);
+	num_returned = NUM_RETURNED(resp->num_rates_flags);
+	num_remaining = NUM_REMAINING(resp->num_rates_flags);
+
+	if (clk->rate_discrete) {
+		clk->list.num_rates = num_returned + num_remaining;
+		clk->list.min_rate = RATE_TO_U64(resp->rate[0]);
+
+		if (num_remaining) {
+			ph->xops->reset_rx_to_maxsz(ph, t);
+			msg->id = cpu_to_le32(clk_id);
+			msg->rate_index = cpu_to_le32(clk->list.num_rates - 1);
+			ret = ph->xops->do_xfer(ph, t);
+			if (!ret)
+				clk->list.max_rate = RATE_TO_U64(resp->rate[0]);
+		} else {
+			u64 max = RATE_TO_U64(resp->rate[num_returned - 1]);
+
+			clk->list.max_rate = max;
+		}
+	} else {
+		/* We expect a triplet, warn about out of spec replies ... */
+		if (num_returned != 3 || num_remaining != 0) {
+			dev_warn(ph->dev,
+				 "Out-of-spec CLOCK_DESCRIBE_RATES reply for %s - returned:%d remaining:%d rx_len:%zd\n",
+				 clk->name, num_returned, num_remaining,
+				 t->rx.len);
+
+			/*
+			 * A known quirk: a triplet is returned but
+			 * num_returned != 3, check for a safe payload
+			 * size to use returned info.
+			 */
+			if (num_remaining != 0 ||
+			    t->rx.len != sizeof(*resp) +
+					 sizeof(__le32) * 2 * 3) {
+				dev_err(ph->dev,
+					"Cannot fix out-of-spec reply !\n");
+				ret = -EPROTO;
+				goto out;
+			}
+		}
+
+		clk->range.min_rate = RATE_TO_U64(resp->rate[0]);
+		clk->range.max_rate = RATE_TO_U64(resp->rate[1]);
+		clk->range.step_size = RATE_TO_U64(resp->rate[2]);
+
+		dev_dbg(ph->dev, "Min %llu Max %llu Step %llu Hz\n",
+			clk->range.min_rate, clk->range.max_rate,
+			clk->range.step_size);
 	}
 
+out:
+	ph->xops->xfer_put(ph, t);
+
 	return ret;
 }
 
@@ -1089,8 +1185,12 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
 		struct scmi_clock_info *clk = cinfo->clk + clkid;
 
 		ret = scmi_clock_attributes_get(ph, clkid, cinfo, version);
-		if (!ret)
-			scmi_clock_describe_rates_get(ph, clkid, clk);
+		if (!ret) {
+			if (PROTOCOL_REV_MAJOR(version) >= 0x2)
+				scmi_clock_get_rates_bound(ph, clkid, clk);
+			else
+				scmi_clock_describe_rates_get(ph, clkid, clk);
+		}
 	}
 
 	if (PROTOCOL_REV_MAJOR(version) >= 0x3) {
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 688466a0e816..240478bb8476 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -15,7 +15,6 @@
 
 #define SCMI_MAX_STR_SIZE		64
 #define SCMI_SHORT_NAME_MAX_SIZE	16
-#define SCMI_MAX_NUM_RATES		16
 
 /**
  * struct scmi_revision_info - version information structure
@@ -54,7 +53,8 @@ struct scmi_clock_info {
 	union {
 		struct {
 			int num_rates;
-			u64 rates[SCMI_MAX_NUM_RATES];
+			u64 min_rate;
+			u64 max_rate;
 		} list;
 		struct {
 			u64 min_rate;
-- 
2.25.1



From etienne.carriere at foss.st.com  Tue Dec  3 09:39:08 2024
From: etienne.carriere at foss.st.com (Etienne Carriere)
Date: Tue, 3 Dec 2024 18:39:08 +0100
Subject: [PATCH v2 2/2] firmware: arm_scmi: round rate bisecting in discrete rates
In-Reply-To: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
Message-ID: <20241203173908.3148794-3-etienne.carriere@foss.st.com>

Implement clock round_rate operation for SCMI clocks that describe a
discrete rates list. Bisect into the supported rates when using SCMI
message CLOCK_DESCRIBE_RATES to optimize SCMI communication transfers.
Parse the rate list array when the target rate fit in the bounds
of the command response for simplicity.

If so some reason the sequence fails or if the SCMI driver has no
round_rate SCMI clock handler, then fallback to the legacy strategy that
returned the target rate value.

Operation handle scmi_clk_determine_rate() is change to get the effective
supported rounded rate when there is no clock re-parenting operation
supported. Otherwise, preserve the implementation that assumed any
clock rate could be obtained.

Signed-off-by: Etienne Carriere <etienne.carriere at foss.st.com>
---
Changes since patch series v1:
- New patch introduced in this v2 series.

---
 drivers/clk/clk-scmi.c            | 17 +++++-
 drivers/firmware/arm_scmi/clock.c | 93 +++++++++++++++++++++++++++++++
 include/linux/scmi_protocol.h     |  3 +
 3 files changed, 110 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 09ccd6cea7f2..7bbb2ee55f4f 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -61,13 +61,20 @@ static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	struct scmi_clk *clk = to_scmi_clk(hw);
 
 	/*
-	 * We can't figure out what rate it will be, so just return the
+	 * In case we can't figure out what rate it will be when the clock
+	 * describes a list of discrete rates, then just return the
 	 * rate back to the caller. scmi_clk_recalc_rate() will be called
 	 * after the rate is set and we'll know what rate the clock is
 	 * running at then.
 	 */
-	if (clk->info->rate_discrete)
+	if (clk->info->rate_discrete) {
+		ftmp = rate;
+		if (scmi_proto_clk_ops->round_rate &&
+		    !scmi_proto_clk_ops->round_rate(clk->ph, clk->id, &ftmp))
+			return ftmp;
+
 		return rate;
+	}
 
 	fmin = clk->info->range.min_rate;
 	fmax = clk->info->range.max_rate;
@@ -122,9 +129,13 @@ static u8 scmi_clk_get_parent(struct clk_hw *hw)
 static int scmi_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
 {
 	/*
-	 * Suppose all the requested rates are supported, and let firmware
+	 * If not several parents look into supported rates. Otherwise
+	 * suppose all the requested rates are supported, and let firmware
 	 * to handle the left work.
 	 */
+	if (to_scmi_clk(hw)->info->num_parents < 2)
+		req->rate = scmi_clk_round_rate(hw, req->rate, NULL);
+
 	return 0;
 }
 
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 34fde0b88098..e416476dd336 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -999,6 +999,98 @@ static int scmi_clock_config_oem_get(const struct scmi_protocol_handle *ph,
 				    NULL, oem_val, atomic);
 }
 
+static int scmi_clock_round_rate(const struct scmi_protocol_handle *ph,
+				 u32 clk_id, u64 *rate)
+
+{
+	const struct scmi_msg_resp_clock_describe_rates *resp;
+	size_t index_low, index_high, index_tmp, count, i;
+	struct scmi_msg_clock_describe_rates *msg;
+	u64 rate_low, rate_high, target_rate;
+	struct scmi_xfer *xfer;
+	int ret;
+	struct clock_info *ci = ph->get_priv(ph);
+	struct scmi_clock_info *clk = ci->clk + clk_id;
+
+	if (clk_id >= ci->num_clocks ||
+	    WARN_ONCE(!clk->rate_discrete, "Unexpected linear rates"))
+		return -EINVAL;
+
+	target_rate = *rate;
+	index_low = 0;
+	index_high = clk->list.num_rates - 1;
+	rate_low = clk->list.min_rate;
+	rate_high = clk->list.max_rate;
+
+	if (target_rate <= rate_low) {
+		*rate = rate_low;
+		return 0;
+	}
+	if (target_rate >= rate_high) {
+		*rate = rate_high;
+		return 0;
+	}
+
+	ret = ph->xops->xfer_get_init(ph, CLOCK_DESCRIBE_RATES, sizeof(*msg), 0,
+				      &xfer);
+	if (ret)
+		return ret;
+
+	resp = xfer->rx.buf;
+	msg = xfer->tx.buf;
+	msg->id = cpu_to_le32(clk_id);
+
+	while (true) {
+		index_tmp = (index_low + index_high) / 2;
+
+		ph->xops->reset_rx_to_maxsz(ph, xfer);
+		msg->id = cpu_to_le32(clk_id);
+		msg->rate_index = cpu_to_le32(index_tmp);
+
+		ret = ph->xops->do_xfer(ph, xfer);
+		if (!ret && (!RATE_DISCRETE(resp->num_rates_flags) ||
+			     !NUM_RETURNED(resp->num_rates_flags)))
+			ret = -EPROTO;
+		if (ret)
+			break;
+
+		count = NUM_RETURNED(resp->num_rates_flags);
+
+		if (target_rate < RATE_TO_U64(resp->rate[0])) {
+			index_high = index_tmp;
+			rate_high = RATE_TO_U64(resp->rate[0]);
+		} else if (target_rate > RATE_TO_U64(resp->rate[count - 1])) {
+			index_low = index_tmp + count - 1;
+			rate_low = RATE_TO_U64(resp->rate[count - 1]);
+		} else {
+			for (i = 1; i < count; i++)
+				if (target_rate <= RATE_TO_U64(resp->rate[i]))
+					break;
+
+			index_low = index_tmp + i - 1;
+			rate_low = RATE_TO_U64(resp->rate[i - 1]);
+
+			if (i < count) {
+				index_high = index_tmp + i;
+				rate_high = RATE_TO_U64(resp->rate[i]);
+			}
+		}
+
+		if (index_high <= index_low + 1) {
+			if (target_rate - rate_low > rate_high - target_rate)
+				*rate = rate_high;
+			else
+				*rate = rate_low;
+
+			break;
+		}
+	}
+
+	ph->xops->xfer_put(ph, xfer);
+
+	return ret;
+}
+
 static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
 {
 	struct clock_info *ci = ph->get_priv(ph);
@@ -1027,6 +1119,7 @@ static const struct scmi_clk_proto_ops clk_proto_ops = {
 	.info_get = scmi_clock_info_get,
 	.rate_get = scmi_clock_rate_get,
 	.rate_set = scmi_clock_rate_set,
+	.round_rate = scmi_clock_round_rate,
 	.enable = scmi_clock_enable,
 	.disable = scmi_clock_disable,
 	.state_get = scmi_clock_state_get,
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 240478bb8476..30cf373c3f8b 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -91,6 +91,7 @@ enum scmi_clock_oem_config {
  * @info_get: get the information of the specified clock
  * @rate_get: request the current clock rate of a clock
  * @rate_set: set the clock rate of a clock
+ * @round_rate: tell which is the nearest rate a clock supports (w/o setting it)
  * @enable: enables the specified clock
  * @disable: disables the specified clock
  * @state_get: get the status of the specified clock
@@ -108,6 +109,8 @@ struct scmi_clk_proto_ops {
 			u64 *rate);
 	int (*rate_set)(const struct scmi_protocol_handle *ph, u32 clk_id,
 			u64 rate);
+	int (*round_rate)(const struct scmi_protocol_handle *ph, u32 clk_id,
+			  u64 *rate);
 	int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id,
 		      bool atomic);
 	int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id,
-- 
2.25.1



From etienne.carriere at foss.st.com  Tue Dec  3 09:39:06 2024
From: etienne.carriere at foss.st.com (Etienne Carriere)
Date: Tue, 3 Dec 2024 18:39:06 +0100
Subject: [PATCH v2 0/2] firmware: arm_scmi: unbound discrete rates, support round rate
Message-ID: <20241203173908.3148794-1-etienne.carriere@foss.st.com>

These 2 patches propose to remove the limitation of 16 discrete rate max on
SCMI clocks and implements an effective round_rate operation on SCMI clocks
that provides non-linear possible rates.

The 1st patch removes a limitation on SCMI clocks that is not really needed
since the SCMI clock driver does not need to store the full list of
supported discrete rates but only require to store the min and max rate
values. This change was initially proposed in:
https://lore.kernel.org/lkml/20240729065306.1210733-1-etienne.carriere at foss.st.com/

The second patch implements a real round_rate operation that is needed for
example on STM32MP25 platforms for the video and the sound drivers that needs
to know the effective possible clock rates in order to select a compliant sample
clock frequency regarding the audio quality constraints.

STM32MP25 platforms also need the 1st patch of this series since many of the
audio clocks (SAIx and MDFx interfaces) and the LTDC video clock are provided
by SCMI clocks (CK_SCMI_FLEXGEN_x).

Etienne Carriere (2):
  firmware: arm_scmi: get only min/max clock rates
  firmware: arm_scmi: round rate bisecting in discrete rates

 drivers/clk/clk-scmi.c            |  21 ++-
 drivers/firmware/arm_scmi/clock.c | 205 +++++++++++++++++++++++++++++-
 include/linux/scmi_protocol.h     |   7 +-
 3 files changed, 220 insertions(+), 13 deletions(-)

-- 
2.25.1



From afd at ti.com  Tue Dec  3 09:41:13 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 3 Dec 2024 11:41:13 -0600
Subject: [PATCH 1/2] arm64: dts: ti: k3-am62p: Enable Mailbox nodes at the board level
Message-ID: <20241203174114.94751-1-afd@ti.com>

Mailbox nodes defined in the top-level J722s/AM62p SoC dtsi files are
incomplete and may not be functional unless they are extended with a
chosen interrupt and connection to a remote processor.

Disable the Mailbox nodes in the dtsi files and only enable the ones
that are actually used on a given board.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi | 4 ++++
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts                | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
index 41e1c24b11441..39f5c2d12fadb 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
@@ -768,6 +768,7 @@ mailbox0_cluster0: mailbox at 29000000 {
 		#mbox-cells = <1>;
 		ti,mbox-num-users = <4>;
 		ti,mbox-num-fifos = <16>;
+		status = "disabled";
 	};
 
 	mailbox0_cluster1: mailbox at 29010000 {
@@ -777,6 +778,7 @@ mailbox0_cluster1: mailbox at 29010000 {
 		#mbox-cells = <1>;
 		ti,mbox-num-users = <4>;
 		ti,mbox-num-fifos = <16>;
+		status = "disabled";
 	};
 
 	mailbox0_cluster2: mailbox at 29020000 {
@@ -786,6 +788,7 @@ mailbox0_cluster2: mailbox at 29020000 {
 		#mbox-cells = <1>;
 		ti,mbox-num-users = <4>;
 		ti,mbox-num-fifos = <16>;
+		status = "disabled";
 	};
 
 	mailbox0_cluster3: mailbox at 29030000 {
@@ -795,6 +798,7 @@ mailbox0_cluster3: mailbox at 29030000 {
 		#mbox-cells = <1>;
 		ti,mbox-num-users = <4>;
 		ti,mbox-num-fifos = <16>;
+		status = "disabled";
 	};
 
 	ecap0: pwm at 23100000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 7f3dc39e12bc9..ad71d2f27f538 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -621,6 +621,8 @@ partition at 3fc0000 {
 };
 
 &mailbox0_cluster0 {
+	status = "okay";
+
 	mbox_r5_0: mbox-r5-0 {
 		ti,mbox-rx = <0 0 0>;
 		ti,mbox-tx = <1 0 0>;
@@ -628,6 +630,8 @@ mbox_r5_0: mbox-r5-0 {
 };
 
 &mailbox0_cluster1 {
+	status = "okay";
+
 	mbox_mcu_r5_0: mbox-mcu-r5-0 {
 		ti,mbox-rx = <0 0 0>;
 		ti,mbox-tx = <1 0 0>;
-- 
2.39.2



From afd at ti.com  Tue Dec  3 09:41:14 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 3 Dec 2024 11:41:14 -0600
Subject: [PATCH 2/2] arm64: dts: ti: k3-am67a-beagley-ai: Add remote processor nodes
In-Reply-To: <20241203174114.94751-1-afd@ti.com>
References: <20241203174114.94751-1-afd@ti.com>
Message-ID: <20241203174114.94751-2-afd@ti.com>

Add nodes for the R5F and C7x cores on the SoC. This includes the mailbox
and memory carveouts used by these remote cores.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 .../arm64/boot/dts/ti/k3-am67a-beagley-ai.dts | 158 ++++++++++++++++++
 1 file changed, 158 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
index 44dfbdf892775..9be6bba28c26f 100644
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
@@ -50,11 +50,71 @@ secure_ddr: optee at 9e800000 {
 			no-map;
 		};
 
+		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory at a0000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0000000 0x00 0x100000>;
+			no-map;
+		};
+
 		wkup_r5fss0_core0_memory_region: r5f-memory at a0100000 {
 			compatible = "shared-dma-pool";
 			reg = <0x00 0xa0100000 0x00 0xf00000>;
 			no-map;
 		};
+
+		mcu_r5fss0_core0_dma_memory_region: mcu-r5fss-dma-memory-region at a1000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1000000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core0_memory_region: mcu-r5fss-memory-region at a1100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_dma_memory_region: main-r5fss-dma-memory-region at a2000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_memory_region: main-r5fss-memory-region at a2100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		c7x_0_dma_memory_region: c7x-dma-memory at a3000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3000000 0x00 0x100000>;
+			no-map;
+		};
+
+		c7x_0_memory_region: c7x-memory at a3100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		c7x_1_dma_memory_region: c7x-dma-memory at a4000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4000000 0x00 0x100000>;
+			no-map;
+		};
+
+		c7x_1_memory_region: c7x-memory at a4100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		rtos_ipc_memory_region: ipc-memories at a5000000 {
+			reg = <0x00 0xa5000000 0x00 0x1c00000>;
+			alignment = <0x1000>;
+			no-map;
+		};
 	};
 
 	vsys_5v0: regulator-1 {
@@ -391,3 +451,101 @@ &sdhci1 {
 	ti,fails-without-test-cd;
 	status = "okay";
 };
+
+&mailbox0_cluster0 {
+	status = "okay";
+
+	mbox_wkup_r5_0: mbox-wkup-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster1 {
+	status = "okay";
+
+	mbox_mcu_r5_0: mbox-mcu-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster2 {
+	status = "okay";
+
+	mbox_c7x_0: mbox-c7x-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster3 {
+	status = "okay";
+
+	mbox_main_r5_0: mbox-main-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+
+	mbox_c7x_1: mbox-c7x-1 {
+		ti,mbox-rx = <2 0 0>;
+		ti,mbox-tx = <3 0 0>;
+	};
+};
+
+/* Timers are used by Remoteproc firmware */
+&main_timer0 {
+	status = "reserved";
+};
+
+&main_timer1 {
+	status = "reserved";
+};
+
+&main_timer2 {
+	status = "reserved";
+};
+
+&wkup_r5fss0 {
+	status = "okay";
+};
+
+&wkup_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster0 &mbox_wkup_r5_0>;
+	memory-region = <&wkup_r5fss0_core0_dma_memory_region>,
+			<&wkup_r5fss0_core0_memory_region>;
+};
+
+&mcu_r5fss0 {
+	status = "okay";
+};
+
+&mcu_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster1 &mbox_mcu_r5_0>;
+	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
+			<&mcu_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0 {
+	status = "okay";
+};
+
+&main_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster3 &mbox_main_r5_0>;
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>;
+};
+
+&c7x_0 {
+	mboxes = <&mailbox0_cluster2 &mbox_c7x_0>;
+	memory-region = <&c7x_0_dma_memory_region>,
+			<&c7x_0_memory_region>;
+	status = "okay";
+};
+
+&c7x_1 {
+	mboxes = <&mailbox0_cluster3 &mbox_c7x_1>;
+	memory-region = <&c7x_1_dma_memory_region>,
+			<&c7x_1_memory_region>;
+	status = "okay";
+};
-- 
2.39.2



From broonie at kernel.org  Tue Dec  3 09:50:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 17:50:53 +0000
Subject: [PATCH v5 0/3] Add support for codec of F1C100s
In-Reply-To: <20241102125712.2647325-1-csokas.bence@prolan.hu>
References: <20241102125712.2647325-1-csokas.bence@prolan.hu>
Message-ID: <173324825387.459040.17438717506518048504.b4-ty@kernel.org>

On Sat, 02 Nov 2024 13:57:09 +0100, Cs?k?s, Bence wrote:
> Support for Allwinner F1C100s/200s series audio was
> submitted in 2018 as an RFC series, but was not merged,
> despite having only minor errors. However, this is
> essential for having audio on these SoCs.
> This series was forward-ported/rebased to the best of
> my abilities, on top of Linus' tree as of now:
> commit c2ee9f594da8 ("KVM: selftests: Fix build on on non-x86 architectures")
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/3] ASoC: sun4i-codec: Add DMA Max Burst field
      commit: cabd4ac290a6ceb87c8dbfb5a3251750e24529e7
[2/3] dt-bindings: sound: Add Allwinner suniv F1C100s Audio Codec
      (no commit info)
[3/3] ASoC: sun4i-codec: Add support for Allwinner suniv F1C100s
      commit: 2198deb823a6ebe110b737614421a4687d3327f4

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 Dec  3 09:50:59 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 03 Dec 2024 17:50:59 +0000
Subject: (subset) [PATCH v6 0/3] Add support for codec of F1C100s
In-Reply-To: <20241123123900.2656837-1-csokas.bence@prolan.hu>
References: <20241123123900.2656837-1-csokas.bence@prolan.hu>
Message-ID: <173324825989.459040.3874572873005288609.b4-ty@kernel.org>

On Sat, 23 Nov 2024 13:38:55 +0100, Cs?k?s, Bence wrote:
> Support for Allwinner F1C100s/200s series audio was
> submitted in 2018 as an RFC series, but was not merged,
> despite having only minor errors. However, this is
> essential for having audio on these SoCs.
> This series was forward-ported/rebased to the best of
> my abilities, on top of Linus' tree as of now:
> commit 28eb75e178d3 ("Merge tag 'drm-next-2024-11-21' of https://gitlab.freedesktop.org/drm/kernel")
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/5] ASoC: sun4i-codec: Add DMA Max Burst field
      commit: cabd4ac290a6ceb87c8dbfb5a3251750e24529e7
[2/5] dt-bindings: sound: Add Allwinner suniv F1C100s Audio Codec
      commit: bb2cc3014d74dfdab0b358b4539a9d2747598663
[3/5] ASoC: sun4i-codec: Add support for Allwinner suniv F1C100s
      commit: 2198deb823a6ebe110b737614421a4687d3327f4

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 maz at kernel.org  Tue Dec  3 10:24:26 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 03 Dec 2024 18:24:26 +0000
Subject: [PATCH] arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs
In-Reply-To: <20241203151941.353796-1-catalin.marinas@arm.com>
References: <20241203151941.353796-1-catalin.marinas@arm.com>
Message-ID: <86o71styjp.wl-maz@kernel.org>

On Tue, 03 Dec 2024 15:19:41 +0000,
Catalin Marinas <catalin.marinas at arm.com> wrote:
> 
> Linux currently sets the TCR_EL1.AS bit unconditionally during CPU
> bring-up. On an 8-bit ASID CPU, this is RES0 and ignored, otherwise
> 16-bit ASIDs are enabled. However, if running in a VM and the hypervisor
> reports 8-bit ASIDs (ID_AA64MMFR0_EL1.ASIDBits == 0) on a 16-bit ASIDs
> CPU, Linux uses bits 8 to 63 as a generation number for tracking old
> process ASIDs. The bottom 8 bits of this generation end up being written
> to TTBR1_EL1 and also used for the ASID-based TLBI operations as the
> upper 8 bits of the ASID. Following an ASID roll-over event we can have
> threads of the same application with the same 8-bit ASID but different
> generation numbers running on separate CPUs. Both TLB caching and the
> TLBI operations will end up using different actual 16-bit ASIDs for the
> same process.
> 
> A similar scenario can happen in a big.LITTLE configuration if the boot
> CPU only uses 8-bit ASIDs while secondary CPUs have 16-bit ASIDs.
> 
> Ensure that the ASID generation is only tracked by bits 16 and up,
> leaving bits 15:8 as 0 if the kernel uses 8-bit ASIDs. Note that
> clearing TCR_EL1.AS is not sufficient since the architecture requires
> that the top 8 bits of the ASID passed to TLBI instructions are 0 rather
> than ignored in such configuration.
> 
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> Cc: <stable at vger.kernel.org>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: James Morse <james.morse at arm.com>
> ---
>  arch/arm64/mm/context.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
> index 188197590fc9..b2ac06246327 100644
> --- a/arch/arm64/mm/context.c
> +++ b/arch/arm64/mm/context.c
> @@ -32,9 +32,9 @@ static unsigned long nr_pinned_asids;
>  static unsigned long *pinned_asid_map;
>  
>  #define ASID_MASK		(~GENMASK(asid_bits - 1, 0))
> -#define ASID_FIRST_VERSION	(1UL << asid_bits)
> +#define ASID_FIRST_VERSION	(1UL << 16)
>  
> -#define NUM_USER_ASIDS		ASID_FIRST_VERSION
> +#define NUM_USER_ASIDS		(1UL << asid_bits)
>  #define ctxid2asid(asid)	((asid) & ~ASID_MASK)
>  #define asid2ctxid(asid, genid)	((asid) | (genid))

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

In the light of this, I think we also need to prevent VM migration
from machines that have 8bit ASIDs to those that have 16bit ASIDs,
because lying to the guest is potentially deadly, for the exact
reasons outlined in the commit message.

I'll post something tomorrow.

Thanks,

	M.

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


From maz at kernel.org  Tue Dec  3 11:02:36 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue,  3 Dec 2024 19:02:36 +0000
Subject: [PATCH] KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden
Message-ID: <20241203190236.505759-1-maz@kernel.org>

Catalin reports that a hypervisor lying to a guest about the size
of the ASID field may result in unexpected issues:

- if the underlying HW does only supports 8 bit ASIDs, the ASID
  field in a TLBI VAE1* operation is only 8 bits, and the HW will
  ignore the other 8 bits

- if on the contrary the HW is 16 bit capable, the ASID field
  in the same TLBI operation is always 16 bits, irrespective of
  the value of TCR_ELx.AS.

This could lead to missed invalidations if the guest was lead to
assume that the HW had 8 bit ASIDs while they really are 16 bit wide.

In order to avoid any potential disaster that would be hard to debug,
prenent the migration between a host with 8 bit ASIDs to one with
wider ASIDs (the converse was obviously always forbidden). This is
also consistent with what we already do for VMIDs.

If it becomes absolutely mandatory to support such a migration path
in the future, we will have to trap and emulate all TLBIs, something
that nobody should look forward to.

Fixes: d5a32b60dc18 ("KVM: arm64: Allow userspace to change ID_AA64MMFR{0-2}_EL1")
Reported-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: stable at vger.kernel.org
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/sys_regs.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index a26f02ec8748..b1918adbd0aa 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2674,7 +2674,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	ID_WRITABLE(ID_AA64MMFR0_EL1, ~(ID_AA64MMFR0_EL1_RES0 |
 					ID_AA64MMFR0_EL1_TGRAN4_2 |
 					ID_AA64MMFR0_EL1_TGRAN64_2 |
-					ID_AA64MMFR0_EL1_TGRAN16_2)),
+					ID_AA64MMFR0_EL1_TGRAN16_2 |
+					ID_AA64MMFR0_EL1_ASIDBITS)),
 	ID_WRITABLE(ID_AA64MMFR1_EL1, ~(ID_AA64MMFR1_EL1_RES0 |
 					ID_AA64MMFR1_EL1_HCX |
 					ID_AA64MMFR1_EL1_TWED |
-- 
2.43.0



From nfraprado at collabora.com  Tue Dec  3 11:20:58 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Tue, 03 Dec 2024 16:20:58 -0300
Subject: [PATCH] ASoC: mediatek: mt8188-mt6359: Remove hardcoded dmic codec
Message-ID: <20241203-mt8188-6359-unhardcode-dmic-v1-1-346e3e5cbe6d@collabora.com>

Remove hardcoded dmic codec from the UL_SRC dai link to avoid requiring
a dmic codec to be present for the driver to probe, as not every
MT8188-based platform might need a dmic codec. The codec can be assigned
to the dai link through the dai-link property in Devicetree on the
platforms where it is needed.

No Devicetree currently relies on it so it is safe to remove without
worrying about backward compatibility.

Fixes: 9f08dcbddeb3 ("ASoC: mediatek: mt8188-mt6359: support new board with nau88255")
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 sound/soc/mediatek/mt8188/mt8188-mt6359.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
index 08ae962afeb92965109b303439419bc6e7c2a896..1550e56ab57d54b179ebe5cbd60db1660bb0bd2c 100644
--- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c
+++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
@@ -188,9 +188,7 @@ SND_SOC_DAILINK_DEFS(pcm1,
 SND_SOC_DAILINK_DEFS(ul_src,
 		     DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC")),
 		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
-						   "mt6359-snd-codec-aif1"),
-					COMP_CODEC("dmic-codec",
-						   "dmic-hifi")),
+						   "mt6359-snd-codec-aif1")),
 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
 
 SND_SOC_DAILINK_DEFS(AFE_SOF_DL2,

---
base-commit: b852e1e7a0389ed6168ef1d38eb0bad71a6b11e8
change-id: 20241203-mt8188-6359-unhardcode-dmic-ba7649f8a72b

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From oliver.upton at linux.dev  Tue Dec  3 11:32:16 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:16 -0800
Subject: [RFC PATCH 10/14] KVM: arm64: Move PMUVer filtering into KVM code
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-11-oliver.upton@linux.dev>

The supported guest PMU version on a particular platform is ultimately a
KVM decision. Move PMUVer filtering into KVM code.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/include/asm/cpufeature.h | 23 -----------------------
 arch/arm64/kvm/pmu-emul.c           | 15 +++++++++------
 2 files changed, 9 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 3718840e9767..50ffb09132e9 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -525,29 +525,6 @@ cpuid_feature_extract_unsigned_field(u64 features, int field)
 	return cpuid_feature_extract_unsigned_field_width(features, field, 4);
 }
 
-/*
- * Fields that identify the version of the Performance Monitors Extension do
- * not follow the standard ID scheme. See ARM DDI 0487E.a page D13-2825,
- * "Alternative ID scheme used for the Performance Monitors Extension version".
- */
-static inline u64 __attribute_const__
-cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap)
-{
-	u64 val = cpuid_feature_extract_unsigned_field(features, field);
-	u64 mask = GENMASK_ULL(field + 3, field);
-
-	/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
-	if (val == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
-		val = 0;
-
-	if (val > cap) {
-		features &= ~mask;
-		features |= (cap << field) & mask;
-	}
-
-	return features;
-}
-
 static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp)
 {
 	return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index b9756a0d054a..8a565817a814 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -1255,13 +1255,16 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 
 u8 kvm_arm_pmu_get_pmuver_limit(void)
 {
-	u64 tmp;
+	unsigned int pmuver;
 
-	tmp = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
-	tmp = cpuid_feature_cap_perfmon_field(tmp,
-					      ID_AA64DFR0_EL1_PMUVer_SHIFT,
-					      ID_AA64DFR0_EL1_PMUVer_V3P5);
-	return FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), tmp);
+	pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer,
+			       read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1));
+
+	/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
+	if (pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
+		return 0;
+
+	return min(pmuver, ID_AA64DFR0_EL1_PMUVer_V3P5);
 }
 
 /**
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:17 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:17 -0800
Subject: [RFC PATCH 11/14] KVM: arm64: Compute synthetic sysreg ESR for Apple PMUv3 traps
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-12-oliver.upton@linux.dev>

Apple M* CPUs provide an IMPDEF trap for PMUv3 sysregs, where ESR_EL2.EC
is a reserved value (0x3F) and a sysreg-like ISS is reported in
AFSR1_EL2.

Compute a synthetic ESR for these PMUv3 traps, giving the illusion of
something architectural to the rest of KVM.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 22 ++++++++++++++++++++++
 arch/arm64/tools/cpucaps        |  1 +
 2 files changed, 23 insertions(+)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 80581b1c3995..da2ccaefaf6f 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -418,6 +418,25 @@ static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return kvm_hyp_handle_sysreg(vcpu, exit_code);
 }
 
+static bool kvm_hyp_handle_impdef(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	u64 iss;
+
+	if (!cpus_have_final_cap(ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS))
+		return false;
+
+	/*
+	 * Compute a synthetic ESR for a sysreg trap. Conveniently, AFSR1_EL2
+	 * is populated with a correct ISS for a sysreg trap. These fruity
+	 * parts are 64bit only, so unconditionally set IL.
+	 */
+	iss = ESR_ELx_ISS(read_sysreg_s(SYS_AFSR1_EL2));
+	vcpu->arch.fault.esr_el2 = FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SYS64) |
+				   FIELD_PREP(ESR_ELx_ISS_MASK, iss) |
+				   ESR_ELx_IL;
+	return false;
+}
+
 static const exit_handler_fn hyp_exit_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= NULL,
 	[ESR_ELx_EC_CP15_32]		= kvm_hyp_handle_cp15_32,
@@ -429,6 +448,9 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[ESR_ELx_EC_WATCHPT_LOW]	= kvm_hyp_handle_watchpt_low,
 	[ESR_ELx_EC_ERET]		= kvm_hyp_handle_eret,
 	[ESR_ELx_EC_MOPS]		= kvm_hyp_handle_mops,
+
+	/* Apple shenanigans */
+	[0x3F]				= kvm_hyp_handle_impdef,
 };
 
 static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b291eb73f5e0..a9c7111b831e 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -105,6 +105,7 @@ WORKAROUND_CAVIUM_TX2_219_TVM
 WORKAROUND_CLEAN_CACHE
 WORKAROUND_DEVICE_LOAD_ACQUIRE
 WORKAROUND_NVIDIA_CARMEL_CNP
+WORKAROUND_PMUV3_IMPDEF_TRAPS
 WORKAROUND_QCOM_FALKOR_E1003
 WORKAROUND_REPEAT_TLBI
 WORKAROUND_SPECULATIVE_AT
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:18 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:18 -0800
Subject: [RFC PATCH 12/14] KVM: arm64: Advertise PMUv3 if IMPDEF traps are present
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-13-oliver.upton@linux.dev>

Advertise a baseline PMUv3 implementation when running on hardware with
IMPDEF traps of the PMUv3 sysregs.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 8a565817a814..34d9c08af209 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -1260,7 +1260,17 @@ u8 kvm_arm_pmu_get_pmuver_limit(void)
 	pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer,
 			       read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1));
 
-	/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
+	/*
+	 * Spoof a barebones PMUv3 implementation if the system supports IMPDEF
+	 * traps of the PMUv3 sysregs
+	 */
+	if (cpus_have_final_cap(ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS))
+		return ID_AA64DFR0_EL1_PMUVer_IMP;
+
+	/*
+	 * Otherwise, treat IMPLEMENTATION DEFINED functionality as
+	 * unimplemented
+	 */
 	if (pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
 		return 0;
 
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:19 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:19 -0800
Subject: [RFC PATCH 13/14] KVM: arm64: Advertise 0 event counters for IMPDEF PMU
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-14-oliver.upton@linux.dev>

The programmable event counters on Apple M* parts are quite different
from what's available in PMUv3, as the event counters aren't fungible
(some events only work on specific counters) and the event ID space
doesn't match the architecture.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 34d9c08af209..8ac4eee781c9 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -1044,6 +1044,9 @@ u8 kvm_arm_pmu_get_max_counters(struct kvm *kvm)
 {
 	struct arm_pmu *arm_pmu = kvm->arch.arm_pmu;
 
+	if (cpus_have_final_cap(ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS))
+		return 0;
+
 	/*
 	 * The arm_pmu->cntr_mask considers the fixed counter(s) as well.
 	 * Ignore those and return only the general-purpose counters.
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:06 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:06 -0800
Subject: [RFC PATCH 00/14] KVM: arm64: Support FEAT_PMUv3 on Apple hardware
Message-ID: <20241203193220.1070811-1-oliver.upton@linux.dev>

One of the interesting features of some Apple M* parts is an IMPDEF trap
that routes EL1/EL0 accesses of the PMUv3 registers to EL2. This allows
a hypervisor to emulate an architectural PMUv3 on top of the IMPDEF PMU
hardware present in the CPU.

And if you squint, this _might_ look like a CPU erratum :-)

This series takes advantage of these IMPDEF traps to provide PMUv3 to
KVM guests. As a starting point, only expose the fixed CPU cycle counter
and no event counters. Conveniently, this is enough to get Windows
running as a KVM guest on Apple hardware.

I've tried to keep the deviation to a minimum by refactoring some of the
flows used for PMUv3, e.g. computing PMCEID from the arm_pmu bitmap
instead of reading hardware directly.

Sending this as an RFC as there are some obvious open Qs:

 - Does enabling PMUv3 meet the bar for allowing IMPDEF crap to slide
   into KVM?

   I certainly think the answer is 'yes', especially considering this
   enables Windows guests.

 - Do we want to support programmable event counters?

   I'm sitting on some extra patches to do this, which maps a few
   architectural event IDs into the PERF_TYPE_HARDWARE space, allowing
   the perf driver to select the right hardware event ID.

   Deciding on a sensible number of counters in this case is a bit of a
   mess, as the M* PMCs aren't entirely fungible (some events only work
   on specific counters).

Applies to 6.13-rc1. I've only enabled this for M2 as it is the hardware
I have, but it is extremely likely this feature works on other M* parts.

It is also very possible I've broken something for true PMUv3 hardware,
as I've only tested on the M2.

Oliver Upton (14):
  drivers/perf: apple_m1: Refactor event select/filter configuration
  drivers/perf: apple_m1: Support host/guest event filtering
  drivers/perf: apple_m1: Map generic branch events
  KVM: arm64: Compute PMCEID from arm_pmu's event bitmaps
  KVM: arm64: Always allow fixed cycle counter
  KVM: arm64: Use PERF_COUNT_HW_CPU_CYCLES for fixed cycle counter
  KVM: arm64: Use a cpucap to determine if system supports FEAT_PMUv3
  KVM: arm64: Drop kvm_arm_pmu_available static key
  KVM: arm64: Use guard() to cleanup usage of arm_pmus_lock
  KVM: arm64: Move PMUVer filtering into KVM code
  KVM: arm64: Compute synthetic sysreg ESR for Apple PMUv3 traps
  KVM: arm64: Advertise PMUv3 if IMPDEF traps are present
  KVM: arm64: Advertise 0 event counters for IMPDEF PMU
  arm64: Enable IMP DEF PMUv3 traps on Apple M2

 arch/arm64/include/asm/apple_m1_pmu.h   |   1 +
 arch/arm64/include/asm/cpufeature.h     |  28 +----
 arch/arm64/kernel/cpu_errata.c          |  38 ++++++
 arch/arm64/kernel/cpufeature.c          |  19 +++
 arch/arm64/kernel/image-vars.h          |   5 -
 arch/arm64/kvm/arm.c                    |   4 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h |   4 +-
 arch/arm64/kvm/hyp/vhe/switch.c         |  22 ++++
 arch/arm64/kvm/pmu-emul.c               | 159 +++++++++++++++---------
 arch/arm64/kvm/pmu.c                    |  10 +-
 arch/arm64/tools/cpucaps                |   2 +
 drivers/perf/apple_m1_cpu_pmu.c         |  68 ++++++----
 include/kvm/arm_pmu.h                   |  15 +--
 13 files changed, 248 insertions(+), 127 deletions(-)


base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
-- 
2.39.5


From oliver.upton at linux.dev  Tue Dec  3 11:32:07 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:07 -0800
Subject: [RFC PATCH 01/14] drivers/perf: apple_m1: Refactor event select/filter configuration
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-2-oliver.upton@linux.dev>

Supporting guest mode events will necessitate programming two event
filters. Prepare by splitting up the programming of the event selector +
event filter into separate headers.

Opportunistically replace RMW patterns with sysreg_clear_set_s().

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/include/asm/apple_m1_pmu.h |  1 +
 drivers/perf/apple_m1_cpu_pmu.c       | 52 ++++++++++++++++-----------
 2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/apple_m1_pmu.h b/arch/arm64/include/asm/apple_m1_pmu.h
index 99483b19b99f..02e05d05851f 100644
--- a/arch/arm64/include/asm/apple_m1_pmu.h
+++ b/arch/arm64/include/asm/apple_m1_pmu.h
@@ -37,6 +37,7 @@
 #define PMCR0_PMI_ENABLE_8_9	GENMASK(45, 44)
 
 #define SYS_IMP_APL_PMCR1_EL1	sys_reg(3, 1, 15, 1, 0)
+#define SYS_IMP_APL_PMCR1_EL12	sys_reg(3, 1, 15, 7, 2)
 #define PMCR1_COUNT_A64_EL0_0_7	GENMASK(15, 8)
 #define PMCR1_COUNT_A64_EL1_0_7	GENMASK(23, 16)
 #define PMCR1_COUNT_A64_EL0_8_9	GENMASK(41, 40)
diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index 1d4d01e1275e..ecc71f6808dd 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -325,11 +325,10 @@ static void m1_pmu_disable_counter_interrupt(unsigned int index)
 	__m1_pmu_enable_counter_interrupt(index, false);
 }
 
-static void m1_pmu_configure_counter(unsigned int index, u8 event,
-				     bool user, bool kernel)
+static void __m1_pmu_configure_event_filter(unsigned int index, bool user,
+					    bool kernel)
 {
-	u64 val, user_bit, kernel_bit;
-	int shift;
+	u64 clear, set, user_bit, kernel_bit;
 
 	switch (index) {
 	case 0 ... 7:
@@ -344,19 +343,24 @@ static void m1_pmu_configure_counter(unsigned int index, u8 event,
 		BUG();
 	}
 
-	val = read_sysreg_s(SYS_IMP_APL_PMCR1_EL1);
-
+	clear = set = 0;
 	if (user)
-		val |= user_bit;
+		set |= user_bit;
 	else
-		val &= ~user_bit;
+		clear |= user_bit;
 
 	if (kernel)
-		val |= kernel_bit;
+		set |= kernel_bit;
 	else
-		val &= ~kernel_bit;
+		clear |= kernel_bit;
 
-	write_sysreg_s(val, SYS_IMP_APL_PMCR1_EL1);
+	sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL1, clear, set);
+}
+
+static void __m1_pmu_configure_eventsel(unsigned int index, u8 event)
+{
+	u64 clear = 0, set = 0;
+	int shift;
 
 	/*
 	 * Counters 0 and 1 have fixed events. For anything else,
@@ -369,21 +373,29 @@ static void m1_pmu_configure_counter(unsigned int index, u8 event,
 		break;
 	case 2 ... 5:
 		shift = (index - 2) * 8;
-		val = read_sysreg_s(SYS_IMP_APL_PMESR0_EL1);
-		val &= ~((u64)0xff << shift);
-		val |= (u64)event << shift;
-		write_sysreg_s(val, SYS_IMP_APL_PMESR0_EL1);
+		clear |= (u64)0xff << shift;
+		set |= (u64)event << shift;
+		sysreg_clear_set_s(SYS_IMP_APL_PMESR0_EL1, clear, set);
 		break;
 	case 6 ... 9:
 		shift = (index - 6) * 8;
-		val = read_sysreg_s(SYS_IMP_APL_PMESR1_EL1);
-		val &= ~((u64)0xff << shift);
-		val |= (u64)event << shift;
-		write_sysreg_s(val, SYS_IMP_APL_PMESR1_EL1);
+		clear |= (u64)0xff << shift;
+		set |= (u64)event << shift;
+		sysreg_clear_set_s(SYS_IMP_APL_PMESR1_EL1, clear, set);
 		break;
 	}
 }
 
+static void m1_pmu_configure_counter(unsigned int index, unsigned long config_base)
+{
+	bool kernel = config_base & M1_PMU_CFG_COUNT_KERNEL;
+	bool user = config_base & M1_PMU_CFG_COUNT_USER;
+	u8 evt = config_base & M1_PMU_CFG_EVENT;
+
+	__m1_pmu_configure_event_filter(index, user, kernel);
+	__m1_pmu_configure_eventsel(index, evt);
+}
+
 /* arm_pmu backend */
 static void m1_pmu_enable_event(struct perf_event *event)
 {
@@ -398,7 +410,7 @@ static void m1_pmu_enable_event(struct perf_event *event)
 	m1_pmu_disable_counter(event->hw.idx);
 	isb();
 
-	m1_pmu_configure_counter(event->hw.idx, evt, user, kernel);
+	m1_pmu_configure_counter(event->hw.idx, event->hw.config_base);
 	m1_pmu_enable_counter(event->hw.idx);
 	m1_pmu_enable_counter_interrupt(event->hw.idx);
 	isb();
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:08 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:08 -0800
Subject: [RFC PATCH 02/14] drivers/perf: apple_m1: Support host/guest event filtering
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-3-oliver.upton@linux.dev>

The PMU appears to have a separate register for filtering 'guest'
exception levels (i.e. EL1 and !ELIsInHost(EL0)) which has the same
layout as PMCR1_EL1. Conveniently, there exists a VHE register alias
(PMCR1_EL12) that can be used to configure it.

Support guest events by programming the EL12 register with the intended
guest kernel/userspace filters. Limit support for guest events to VHE
(i.e. kernel running at EL2), as it avoids involving KVM to context
switch PMU registers. VHE is the only supported mode on M* parts anyway,
so this isn't an actual feature limitation.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 drivers/perf/apple_m1_cpu_pmu.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index ecc71f6808dd..2a34523500f8 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -120,6 +120,8 @@ enum m1_pmu_events {
 	 */
 	M1_PMU_CFG_COUNT_USER					= BIT(8),
 	M1_PMU_CFG_COUNT_KERNEL					= BIT(9),
+	M1_PMU_CFG_COUNT_HOST					= BIT(10),
+	M1_PMU_CFG_COUNT_GUEST					= BIT(11),
 };
 
 /*
@@ -326,7 +328,7 @@ static void m1_pmu_disable_counter_interrupt(unsigned int index)
 }
 
 static void __m1_pmu_configure_event_filter(unsigned int index, bool user,
-					    bool kernel)
+					    bool kernel, bool host)
 {
 	u64 clear, set, user_bit, kernel_bit;
 
@@ -354,7 +356,10 @@ static void __m1_pmu_configure_event_filter(unsigned int index, bool user,
 	else
 		clear |= kernel_bit;
 
-	sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL1, clear, set);
+	if (host)
+		sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL1, clear, set);
+	else if (is_kernel_in_hyp_mode())
+		sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL12, clear, set);
 }
 
 static void __m1_pmu_configure_eventsel(unsigned int index, u8 event)
@@ -389,10 +394,13 @@ static void __m1_pmu_configure_eventsel(unsigned int index, u8 event)
 static void m1_pmu_configure_counter(unsigned int index, unsigned long config_base)
 {
 	bool kernel = config_base & M1_PMU_CFG_COUNT_KERNEL;
+	bool guest = config_base & M1_PMU_CFG_COUNT_GUEST;
+	bool host = config_base & M1_PMU_CFG_COUNT_HOST;
 	bool user = config_base & M1_PMU_CFG_COUNT_USER;
 	u8 evt = config_base & M1_PMU_CFG_EVENT;
 
-	__m1_pmu_configure_event_filter(index, user, kernel);
+	__m1_pmu_configure_event_filter(index, user && host, kernel && host, true);
+	__m1_pmu_configure_event_filter(index, user && guest, kernel && guest, false);
 	__m1_pmu_configure_eventsel(index, evt);
 }
 
@@ -568,7 +576,7 @@ static int m1_pmu_set_event_filter(struct hw_perf_event *event,
 {
 	unsigned long config_base = 0;
 
-	if (!attr->exclude_guest) {
+	if (!attr->exclude_guest && !is_kernel_in_hyp_mode()) {
 		pr_debug("ARM performance counters do not support mode exclusion\n");
 		return -EOPNOTSUPP;
 	}
@@ -576,6 +584,10 @@ static int m1_pmu_set_event_filter(struct hw_perf_event *event,
 		config_base |= M1_PMU_CFG_COUNT_KERNEL;
 	if (!attr->exclude_user)
 		config_base |= M1_PMU_CFG_COUNT_USER;
+	if (!attr->exclude_host)
+		config_base |= M1_PMU_CFG_COUNT_HOST;
+	if (!attr->exclude_guest)
+		config_base |= M1_PMU_CFG_COUNT_GUEST;
 
 	event->config_base = config_base;
 
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:09 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:09 -0800
Subject: [RFC PATCH 03/14] drivers/perf: apple_m1: Map generic branch events
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-4-oliver.upton@linux.dev>

Map the generic perf events for branch prediction stats to the
corresponding hardware events.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 drivers/perf/apple_m1_cpu_pmu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index 2a34523500f8..d6d4ff6da862 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -170,6 +170,8 @@ static const unsigned m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
 	PERF_MAP_ALL_UNSUPPORTED,
 	[PERF_COUNT_HW_CPU_CYCLES]		= M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE,
 	[PERF_COUNT_HW_INSTRUCTIONS]		= M1_PMU_PERFCTR_INST_ALL,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= M1_PMU_PERFCTR_INST_BRANCH,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= M1_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,
 };
 
 /* sysfs definitions */
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:10 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:10 -0800
Subject: [RFC PATCH 04/14] KVM: arm64: Compute PMCEID from arm_pmu's event bitmaps
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-5-oliver.upton@linux.dev>

The PMUv3 driver populates a couple of bitmaps with the values of
PMCEID{0,1}, from which the guest's PMCEID{0,1} can be derived. This
is particularly convenient when virtualizing PMUv3 on IMP DEF hardware,
as reading the nonexistent PMCEID registers leads to a rather unpleasant
UNDEF.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 47 ++++++++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 456102bc0b55..809d65b912e8 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -861,8 +861,42 @@ static struct arm_pmu *kvm_pmu_probe_armpmu(void)
 	return pmu;
 }
 
+static u64 __compute_pmceid(struct arm_pmu *pmu, bool pmceid1)
+{
+	u32 hi[2], lo[2];
+
+	bitmap_to_arr32(lo, pmu->pmceid_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
+	bitmap_to_arr32(hi, pmu->pmceid_ext_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
+
+	return ((u64)hi[pmceid1] << 32) | lo[pmceid1];
+}
+
+static u64 compute_pmceid0(struct arm_pmu *pmu)
+{
+	u64 val = __compute_pmceid(pmu, 0);
+
+	/* always support CHAIN */
+	val |= BIT(ARMV8_PMUV3_PERFCTR_CHAIN);
+	return val;
+}
+
+static u64 compute_pmceid1(struct arm_pmu *pmu)
+{
+	u64 val = __compute_pmceid(pmu, 1);
+
+	/*
+	 * Don't advertise STALL_SLOT*, as PMMIR_EL0 is handled
+	 * as RAZ
+	 */
+	val &= ~(BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32) |
+		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND - 32) |
+		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND - 32));
+	return val;
+}
+
 u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
 {
+	struct arm_pmu *cpu_pmu = vcpu->kvm->arch.arm_pmu;
 	unsigned long *bmap = vcpu->kvm->arch.pmu_filter;
 	u64 val, mask = 0;
 	int base, i, nr_events;
@@ -871,19 +905,10 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
 		return 0;
 
 	if (!pmceid1) {
-		val = read_sysreg(pmceid0_el0);
-		/* always support CHAIN */
-		val |= BIT(ARMV8_PMUV3_PERFCTR_CHAIN);
+		val = compute_pmceid0(cpu_pmu);
 		base = 0;
 	} else {
-		val = read_sysreg(pmceid1_el0);
-		/*
-		 * Don't advertise STALL_SLOT*, as PMMIR_EL0 is handled
-		 * as RAZ
-		 */
-		val &= ~(BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32) |
-			 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND - 32) |
-			 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND - 32));
+		val = compute_pmceid1(cpu_pmu);
 		base = 32;
 	}
 
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:11 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:11 -0800
Subject: [RFC PATCH 05/14] KVM: arm64: Always allow fixed cycle counter
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-6-oliver.upton@linux.dev>

The fixed CPU cycle counter is mandatory for PMUv3, so it doesn't make a
lot of sense allowing userspace to filter it. Only apply the PMU event
filter to *programmed* event counters.

While at it, use the generic CPU_CYCLES perf event to back the cycle
counter, potentially allowing non-PMUv3 drivers to map the event onto
the underlying implementation.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 809d65b912e8..3e7091e1a2e4 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -707,26 +707,27 @@ static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc)
 	evtreg = kvm_pmc_read_evtreg(pmc);
 
 	kvm_pmu_stop_counter(pmc);
-	if (pmc->idx == ARMV8_PMU_CYCLE_IDX)
+	if (pmc->idx == ARMV8_PMU_CYCLE_IDX) {
 		eventsel = ARMV8_PMUV3_PERFCTR_CPU_CYCLES;
-	else
+	} else {
 		eventsel = evtreg & kvm_pmu_event_mask(vcpu->kvm);
 
-	/*
-	 * Neither SW increment nor chained events need to be backed
-	 * by a perf event.
-	 */
-	if (eventsel == ARMV8_PMUV3_PERFCTR_SW_INCR ||
-	    eventsel == ARMV8_PMUV3_PERFCTR_CHAIN)
-		return;
+		/*
+		 * If we have a filter in place and that the event isn't
+		 * allowed, do not install a perf event either.
+		 */
+		if (vcpu->kvm->arch.pmu_filter &&
+		    !test_bit(eventsel, vcpu->kvm->arch.pmu_filter))
+			return;
 
-	/*
-	 * If we have a filter in place and that the event isn't allowed, do
-	 * not install a perf event either.
-	 */
-	if (vcpu->kvm->arch.pmu_filter &&
-	    !test_bit(eventsel, vcpu->kvm->arch.pmu_filter))
-		return;
+		/*
+		 * Neither SW increment nor chained events need to be backed
+		 * by a perf event.
+		 */
+		if (eventsel == ARMV8_PMUV3_PERFCTR_SW_INCR ||
+		    eventsel == ARMV8_PMUV3_PERFCTR_CHAIN)
+			return;
+	}
 
 	memset(&attr, 0, sizeof(struct perf_event_attr));
 	attr.type = arm_pmu->pmu.type;
@@ -877,6 +878,8 @@ static u64 compute_pmceid0(struct arm_pmu *pmu)
 
 	/* always support CHAIN */
 	val |= BIT(ARMV8_PMUV3_PERFCTR_CHAIN);
+	/* always support CPU_CYCLES */
+	val |= BIT(ARMV8_PMUV3_PERFCTR_CPU_CYCLES);
 	return val;
 }
 
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:12 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:12 -0800
Subject: [RFC PATCH 06/14] KVM: arm64: Use PERF_COUNT_HW_CPU_CYCLES for fixed cycle counter
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-7-oliver.upton@linux.dev>

KVM will soon be able to emulate PMUv3 on non-PMUv3 hardware. Use the
generic event for CPU cycles to allow a non-PMUv3 driver to map the
event correctly on underlying hardware.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 3e7091e1a2e4..0b2ad60717e8 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -700,16 +700,27 @@ static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc)
 {
 	struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc);
 	struct arm_pmu *arm_pmu = vcpu->kvm->arch.arm_pmu;
+	struct perf_event_attr attr = {};
 	struct perf_event *event;
-	struct perf_event_attr attr;
 	u64 eventsel, evtreg;
 
 	evtreg = kvm_pmc_read_evtreg(pmc);
 
 	kvm_pmu_stop_counter(pmc);
 	if (pmc->idx == ARMV8_PMU_CYCLE_IDX) {
-		eventsel = ARMV8_PMUV3_PERFCTR_CPU_CYCLES;
+		/*
+		 * Use the common event space for the cycle counter, allowing
+		 * the underlying PMU driver to map it onto hardware in the
+		 * unlikely case the host doesn't actually have PMUv3.
+		 */
+		attr.type = PERF_TYPE_HARDWARE;
+		eventsel = PERF_COUNT_HW_CPU_CYCLES;
 	} else {
+		/*
+		 * Otherwise, treat the event as a raw event for the selected
+		 * PMU.
+		 */
+		attr.type = arm_pmu->pmu.type;
 		eventsel = evtreg & kvm_pmu_event_mask(vcpu->kvm);
 
 		/*
@@ -729,8 +740,6 @@ static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc)
 			return;
 	}
 
-	memset(&attr, 0, sizeof(struct perf_event_attr));
-	attr.type = arm_pmu->pmu.type;
 	attr.size = sizeof(attr);
 	attr.pinned = 1;
 	attr.disabled = !kvm_pmu_counter_is_enabled(pmc);
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:13 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:13 -0800
Subject: [RFC PATCH 07/14] KVM: arm64: Use a cpucap to determine if system supports FEAT_PMUv3
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-8-oliver.upton@linux.dev>

KVM is about to learn some new tricks to virtualize PMUv3 on IMPDEF
hardware. As part of that, we now need to differentiate host support
from guest support for PMUv3.

Add a cpucap to determine if an architectural PMUv3 is present to guard
host usage of PMUv3 controls.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/include/asm/cpufeature.h     |  5 +++++
 arch/arm64/kernel/cpufeature.c          | 19 +++++++++++++++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 ++--
 arch/arm64/kvm/pmu.c                    | 10 +++++-----
 arch/arm64/tools/cpucaps                |  1 +
 include/kvm/arm_pmu.h                   |  2 +-
 6 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index b64e49bd9d10..3718840e9767 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -867,6 +867,11 @@ static __always_inline bool system_supports_mpam_hcr(void)
 	return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
 }
 
+static inline bool system_supports_pmuv3(void)
+{
+	return cpus_have_final_cap(ARM64_HAS_PMUV3);
+}
+
 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 6ce71f444ed8..fa73fbdd8617 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1889,6 +1889,19 @@ static bool has_lpa2(const struct arm64_cpu_capabilities *entry, int scope)
 }
 #endif
 
+static bool has_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
+	unsigned int pmuver;
+
+	pmuver = cpuid_feature_extract_unsigned_field(dfr0,
+						      ID_AA64DFR0_EL1_PMUVer_SHIFT);
+	if (pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
+		return false;
+
+	return pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP;
+}
+
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 #define KPTI_NG_TEMP_VA		(-(1UL << PMD_SHIFT))
 
@@ -2990,6 +3003,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, GCS, IMP)
 	},
 #endif
+	{
+		.desc = "PMUv3",
+		.capability = ARM64_HAS_PMUV3,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_pmuv3,
+	},
 	{},
 };
 
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 34f53707892d..995aca419b1e 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -244,7 +244,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
 	 * counter, which could make a PMXEVCNTR_EL0 access UNDEF at
 	 * EL1 instead of being trapped to EL2.
 	 */
-	if (kvm_arm_support_pmu_v3()) {
+	if (system_supports_pmuv3()) {
 		struct kvm_cpu_context *hctxt;
 
 		write_sysreg(0, pmselr_el0);
@@ -281,7 +281,7 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
 	write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);
 
 	write_sysreg(0, hstr_el2);
-	if (kvm_arm_support_pmu_v3()) {
+	if (system_supports_pmuv3()) {
 		struct kvm_cpu_context *hctxt;
 
 		hctxt = host_data_ptr(host_ctxt);
diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c
index 0b3adf3e17b4..6b48a3d16d0d 100644
--- a/arch/arm64/kvm/pmu.c
+++ b/arch/arm64/kvm/pmu.c
@@ -41,7 +41,7 @@ void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr)
 {
 	struct kvm_pmu_events *pmu = kvm_get_pmu_events();
 
-	if (!kvm_arm_support_pmu_v3() || !kvm_pmu_switch_needed(attr))
+	if (!system_supports_pmuv3() || !kvm_pmu_switch_needed(attr))
 		return;
 
 	if (!attr->exclude_host)
@@ -57,7 +57,7 @@ void kvm_clr_pmu_events(u64 clr)
 {
 	struct kvm_pmu_events *pmu = kvm_get_pmu_events();
 
-	if (!kvm_arm_support_pmu_v3())
+	if (!system_supports_pmuv3())
 		return;
 
 	pmu->events_host &= ~clr;
@@ -133,7 +133,7 @@ void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu)
 	struct kvm_pmu_events *pmu;
 	u64 events_guest, events_host;
 
-	if (!kvm_arm_support_pmu_v3() || !has_vhe())
+	if (!system_supports_pmuv3() || !has_vhe())
 		return;
 
 	preempt_disable();
@@ -154,7 +154,7 @@ void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu)
 	struct kvm_pmu_events *pmu;
 	u64 events_guest, events_host;
 
-	if (!kvm_arm_support_pmu_v3() || !has_vhe())
+	if (!system_supports_pmuv3() || !has_vhe())
 		return;
 
 	pmu = kvm_get_pmu_events();
@@ -180,7 +180,7 @@ bool kvm_set_pmuserenr(u64 val)
 	struct kvm_cpu_context *hctxt;
 	struct kvm_vcpu *vcpu;
 
-	if (!kvm_arm_support_pmu_v3() || !has_vhe())
+	if (!system_supports_pmuv3() || !has_vhe())
 		return false;
 
 	vcpu = kvm_get_running_vcpu();
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index eb17f59e543c..b291eb73f5e0 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -45,6 +45,7 @@ HAS_LSE_ATOMICS
 HAS_MOPS
 HAS_NESTED_VIRT
 HAS_PAN
+HAS_PMUV3
 HAS_S1PIE
 HAS_S1POE
 HAS_RAS_EXTN
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index e61dd7dd2286..7ef9eb3cede5 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -87,7 +87,7 @@ void kvm_vcpu_pmu_resync_el0(void);
  */
 #define kvm_pmu_update_vcpu_events(vcpu)				\
 	do {								\
-		if (!has_vhe() && kvm_arm_support_pmu_v3())		\
+		if (!has_vhe() && system_supports_pmuv3())		\
 			vcpu->arch.pmu.events = *kvm_get_pmu_events();	\
 	} while (0)
 
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:14 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:14 -0800
Subject: [RFC PATCH 08/14] KVM: arm64: Drop kvm_arm_pmu_available static key
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-9-oliver.upton@linux.dev>

With the PMUv3 cpucap, kvm_arm_pmu_available is no longer used in the
hot path of guest entry/exit. On top of that, guest support for PMUv3
may not correlate with host support for the feature, e.g. on IMPDEF
hardware.

Throw out the static key and just inspect the list of PMUs to determine
if PMUv3 is supported for KVM guests.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kernel/image-vars.h |  5 -----
 arch/arm64/kvm/arm.c           |  4 ++--
 arch/arm64/kvm/pmu-emul.c      | 11 ++++++-----
 include/kvm/arm_pmu.h          | 13 +------------
 4 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 8f5422ed1b75..5919320bc802 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -109,11 +109,6 @@ KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
 KVM_NVHE_ALIAS(__start___kvm_ex_table);
 KVM_NVHE_ALIAS(__stop___kvm_ex_table);
 
-/* PMU available static key */
-#ifdef CONFIG_HW_PERF_EVENTS
-KVM_NVHE_ALIAS(kvm_arm_pmu_available);
-#endif
-
 /* Position-independent library routines */
 KVM_NVHE_ALIAS_HYP(clear_page, __pi_clear_page);
 KVM_NVHE_ALIAS_HYP(copy_page, __pi_copy_page);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..081e638c674f 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -391,7 +391,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		r = get_num_wrps();
 		break;
 	case KVM_CAP_ARM_PMU_V3:
-		r = kvm_arm_support_pmu_v3();
+		r = kvm_supports_guest_pmuv3();
 		break;
 	case KVM_CAP_ARM_INJECT_SERROR_ESR:
 		r = cpus_have_final_cap(ARM64_HAS_RAS_EXTN);
@@ -1397,7 +1397,7 @@ static unsigned long system_supported_vcpu_features(void)
 	if (!cpus_have_final_cap(ARM64_HAS_32BIT_EL1))
 		clear_bit(KVM_ARM_VCPU_EL1_32BIT, &features);
 
-	if (!kvm_arm_support_pmu_v3())
+	if (!kvm_supports_guest_pmuv3())
 		clear_bit(KVM_ARM_VCPU_PMU_V3, &features);
 
 	if (!system_supports_sve())
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 0b2ad60717e8..1ff343d43b61 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -17,14 +17,18 @@
 
 #define PERF_ATTR_CFG1_COUNTER_64BIT	BIT(0)
 
-DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
-
 static LIST_HEAD(arm_pmus);
 static DEFINE_MUTEX(arm_pmus_lock);
 
 static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc);
 static void kvm_pmu_release_perf_event(struct kvm_pmc *pmc);
 
+bool kvm_supports_guest_pmuv3(void)
+{
+	guard(mutex)(&arm_pmus_lock);
+	return !list_empty(&arm_pmus);
+}
+
 static struct kvm_vcpu *kvm_pmc_to_vcpu(const struct kvm_pmc *pmc)
 {
 	return container_of(pmc, struct kvm_vcpu, arch.pmu.pmc[pmc->idx]);
@@ -824,9 +828,6 @@ void kvm_host_pmu_init(struct arm_pmu *pmu)
 	entry->arm_pmu = pmu;
 	list_add_tail(&entry->entry, &arm_pmus);
 
-	if (list_is_singular(&arm_pmus))
-		static_branch_enable(&kvm_arm_pmu_available);
-
 out_unlock:
 	mutex_unlock(&arm_pmus_lock);
 }
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 7ef9eb3cede5..d3dcf5438315 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -37,13 +37,7 @@ struct arm_pmu_entry {
 	struct arm_pmu *arm_pmu;
 };
 
-DECLARE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
-
-static __always_inline bool kvm_arm_support_pmu_v3(void)
-{
-	return static_branch_likely(&kvm_arm_pmu_available);
-}
-
+bool kvm_supports_guest_pmuv3(void);
 #define kvm_arm_pmu_irq_initialized(v)	((v)->arch.pmu.irq_num >= VGIC_NR_SGIS)
 u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx);
 void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64 select_idx, u64 val);
@@ -103,11 +97,6 @@ void kvm_pmu_nested_transition(struct kvm_vcpu *vcpu);
 struct kvm_pmu {
 };
 
-static inline bool kvm_arm_support_pmu_v3(void)
-{
-	return false;
-}
-
 #define kvm_arm_pmu_irq_initialized(v)	(false)
 static inline u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu,
 					    u64 select_idx)
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:32:15 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:32:15 -0800
Subject: [RFC PATCH 09/14] KVM: arm64: Use guard() to cleanup usage of arm_pmus_lock
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193220.1070811-10-oliver.upton@linux.dev>

Get rid of some goto label patterns by using guard() to drop the
arm_pmus_lock when returning from a function.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 1ff343d43b61..b9756a0d054a 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -819,26 +819,23 @@ void kvm_host_pmu_init(struct arm_pmu *pmu)
 	if (!pmuv3_implemented(kvm_arm_pmu_get_pmuver_limit()))
 		return;
 
-	mutex_lock(&arm_pmus_lock);
+	guard(mutex)(&arm_pmus_lock);
 
 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
 	if (!entry)
-		goto out_unlock;
+		return;
 
 	entry->arm_pmu = pmu;
 	list_add_tail(&entry->entry, &arm_pmus);
-
-out_unlock:
-	mutex_unlock(&arm_pmus_lock);
 }
 
 static struct arm_pmu *kvm_pmu_probe_armpmu(void)
 {
-	struct arm_pmu *tmp, *pmu = NULL;
 	struct arm_pmu_entry *entry;
+	struct arm_pmu *pmu;
 	int cpu;
 
-	mutex_lock(&arm_pmus_lock);
+	guard(mutex)(&arm_pmus_lock);
 
 	/*
 	 * It is safe to use a stale cpu to iterate the list of PMUs so long as
@@ -859,17 +856,13 @@ static struct arm_pmu *kvm_pmu_probe_armpmu(void)
 	 */
 	cpu = raw_smp_processor_id();
 	list_for_each_entry(entry, &arm_pmus, entry) {
-		tmp = entry->arm_pmu;
+		pmu = entry->arm_pmu;
 
-		if (cpumask_test_cpu(cpu, &tmp->supported_cpus)) {
-			pmu = tmp;
-			break;
-		}
+		if (cpumask_test_cpu(cpu, &pmu->supported_cpus))
+			return pmu;
 	}
 
-	mutex_unlock(&arm_pmus_lock);
-
-	return pmu;
+	return NULL;
 }
 
 static u64 __compute_pmceid(struct arm_pmu *pmu, bool pmceid1)
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec  3 11:34:15 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 11:34:15 -0800
Subject: [RFC PATCH 14/14] arm64: Enable IMP DEF PMUv3 traps on Apple M2
In-Reply-To: <20241203193220.1070811-1-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
Message-ID: <20241203193415.1070917-1-oliver.upton@linux.dev>

Apple M2 CPUs support IMPDEF traps of the PMUv3 sysregs, allowing a
hypervisor to virtualize an architectural PMU for a VM. Flip the
appropriate bit in HACR_EL2 on supporting hardware.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kernel/cpu_errata.c | 38 ++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index a78f247029ae..441ee4ffc770 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -194,6 +194,37 @@ has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
 	return is_midr_in_range(midr, &range) && has_dic;
 }
 
+static const struct midr_range impdef_pmuv3_cpus[] = {
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_PRO),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_PRO),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_MAX),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_MAX),
+	{},
+};
+
+static bool has_impdef_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
+	unsigned int pmuver;
+
+	if (!is_kernel_in_hyp_mode())
+		return false;
+
+	pmuver = cpuid_feature_extract_unsigned_field(dfr0,
+						      ID_AA64DFR0_EL1_PMUVer_SHIFT);
+	if (pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
+		return false;
+
+	return is_midr_in_range_list(read_cpuid_id(), impdef_pmuv3_cpus);
+}
+
+static void cpu_enable_impdef_pmuv3_traps(const struct arm64_cpu_capabilities *__unused)
+{
+	sysreg_clear_set_s(SYS_HACR_EL2, 0, BIT(56));
+}
+
 #ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
 static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
 #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009
@@ -786,6 +817,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_RANGE_LIST(erratum_ac03_cpu_38_list),
 	},
 #endif
+	{
+		.desc = "Apple IMPDEF PMUv3 Traps",
+		.capability = ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS,
+		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+		.matches = has_impdef_pmuv3,
+		.cpu_enable = cpu_enable_impdef_pmuv3_traps,
+	},
 	{
 	}
 };
-- 
2.39.5



From cristian.marussi at arm.com  Tue Dec  3 11:35:44 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Dec 2024 19:35:44 +0000
Subject: [PATCH] firmware: arm_scmi: Allow transport properties for multiple instances
Message-ID: <20241203193544.3895173-1-cristian.marussi@arm.com>

Default SCMI transport properties values can be overridden with devicetree
provided descriptors; in order to support multiple SCMI instances, make the
properties-update happen on a per-instance copy of the original transport
descriptor.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/common.h |  4 ++--
 drivers/firmware/arm_scmi/driver.c | 18 +++++++++---------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 48b12f81141d..10ea7962323e 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -442,7 +442,7 @@ struct scmi_transport_core_operations {
  */
 struct scmi_transport {
 	struct device *supplier;
-	struct scmi_desc *desc;
+	struct scmi_desc desc;
 	struct scmi_transport_core_operations **core_ops;
 };
 
@@ -468,7 +468,7 @@ static int __tag##_probe(struct platform_device *pdev)			       \
 	device_set_of_node_from_dev(&spdev->dev, dev);			       \
 									       \
 	strans.supplier = dev;						       \
-	strans.desc = &(__desc);					       \
+	memcpy(&strans.desc, &(__desc), sizeof(strans.desc));		       \
 	strans.core_ops = &(__core_ops);				       \
 									       \
 	ret = platform_device_add_data(spdev, &strans, sizeof(strans));	       \
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 1b5fb2c4ce86..eeed1689b208 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -3028,7 +3028,7 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev)
 	int ret;
 
 	trans = dev_get_platdata(dev);
-	if (!trans || !trans->desc || !trans->supplier || !trans->core_ops)
+	if (!trans || !trans->supplier || !trans->core_ops)
 		return NULL;
 
 	if (!device_link_add(dev, trans->supplier, DL_FLAG_AUTOREMOVE_CONSUMER)) {
@@ -3043,33 +3043,33 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev)
 	dev_info(dev, "Using %s\n", dev_driver_string(trans->supplier));
 
 	ret = of_property_read_u32(dev->of_node, "arm,max-rx-timeout-ms",
-				   &trans->desc->max_rx_timeout_ms);
+				   &trans->desc.max_rx_timeout_ms);
 	if (ret && ret != -EINVAL)
 		dev_err(dev, "Malformed arm,max-rx-timeout-ms DT property.\n");
 
 	ret = of_property_read_u32(dev->of_node, "arm,max-msg-size",
-				   &trans->desc->max_msg_size);
+				   &trans->desc.max_msg_size);
 	if (ret && ret != -EINVAL)
 		dev_err(dev, "Malformed arm,max-msg-size DT property.\n");
 
 	ret = of_property_read_u32(dev->of_node, "arm,max-msg",
-				   &trans->desc->max_msg);
+				   &trans->desc.max_msg);
 	if (ret && ret != -EINVAL)
 		dev_err(dev, "Malformed arm,max-msg DT property.\n");
 
 	dev_info(dev,
 		 "SCMI max-rx-timeout: %dms / max-msg-size: %dbytes / max-msg: %d\n",
-		 trans->desc->max_rx_timeout_ms, trans->desc->max_msg_size,
-		 trans->desc->max_msg);
+		 trans->desc.max_rx_timeout_ms, trans->desc.max_msg_size,
+		 trans->desc.max_msg);
 
 	/* System wide atomic threshold for atomic ops .. if any */
 	if (!of_property_read_u32(dev->of_node, "atomic-threshold-us",
-				  &trans->desc->atomic_threshold))
+				  &trans->desc.atomic_threshold))
 		dev_info(dev,
 			 "SCMI System wide atomic threshold set to %u us\n",
-			 trans->desc->atomic_threshold);
+			 trans->desc.atomic_threshold);
 
-	return trans->desc;
+	return &trans->desc;
 }
 
 static int scmi_probe(struct platform_device *pdev)
-- 
2.47.0



From cristian.marussi at arm.com  Tue Dec  3 12:00:37 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Dec 2024 20:00:37 +0000
Subject: [PATCH 1/2] firmware: arm_scmi: Support vendor protocol modules autoloading
In-Reply-To: <20241203200038.3961090-1-cristian.marussi@arm.com>
References: <20241203200038.3961090-1-cristian.marussi@arm.com>
Message-ID: <20241203200038.3961090-2-cristian.marussi@arm.com>

SCMI vendor protocols namespace is shared amongst all vendors so that there
can be multiple implementation for the same protocol ID by different
vendors, exposing completely different functionalities and used by distinct
SCMI vendor drivers.

For these reasons, at runtime, when some driver asks for a protocol, the
proper implementation to use is chosen based on the SCMI vendor/subvendor/
impl_version data as advertised by the platform SCMI server and gathered
from the SCMI core during stack initialization: this enables proper runtime
selection of vendor protocols even when many different protocols from
different vendors are built into the same image via a common defconfig.

This same selection mechanism works similarly well even when all the vendor
protocols are compiled as loadable modules, as long as all such required
protocol modules have been previously loaded by some other means.

Add support for the automatic loading of vendor protocol modules, based on
protocol/vendor IDs, when an SCMI driver attempts to use such a protocol.

Reported-by: Johan Hovold <johan+linaro at kernel.org>
Closes: https://lore.kernel.org/lkml/ZytnRc94iKUfMYH0 at hovoldconsulting.com/
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c | 56 ++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index eeed1689b208..60050da54bf2 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/io-64-nonatomic-hi-lo.h>
 #include <linux/kernel.h>
+#include <linux/kmod.h>
 #include <linux/ktime.h>
 #include <linux/hashtable.h>
 #include <linux/list.h>
@@ -43,6 +44,8 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/scmi.h>
 
+#define SCMI_VENDOR_MODULE_ALIAS_FMT	"scmi-protocol-0x%02x-%s"
+
 static DEFINE_IDA(scmi_id);
 
 static DEFINE_XARRAY(scmi_protocols);
@@ -275,6 +278,44 @@ scmi_vendor_protocol_lookup(int protocol_id, char *vendor_id,
 	return proto;
 }
 
+static const struct scmi_protocol *
+scmi_vendor_protocol_get(int protocol_id, struct scmi_revision_info *version)
+{
+	const struct scmi_protocol *proto;
+
+	proto = scmi_vendor_protocol_lookup(protocol_id, version->vendor_id,
+					    version->sub_vendor_id,
+					    version->impl_ver);
+	if (!proto) {
+		int ret;
+
+		pr_debug("Looking for '" SCMI_VENDOR_MODULE_ALIAS_FMT "'\n",
+			 protocol_id, version->vendor_id);
+
+		/* Note that vendor_id is mandatory for vendor protocols */
+		ret = request_module(SCMI_VENDOR_MODULE_ALIAS_FMT,
+				     protocol_id, version->vendor_id);
+		if (ret) {
+			pr_warn("Problem loading module for protocol 0x%x\n",
+				protocol_id);
+			return NULL;
+		}
+
+		/* Lookup again, once modules loaded */
+		proto = scmi_vendor_protocol_lookup(protocol_id,
+						    version->vendor_id,
+						    version->sub_vendor_id,
+						    version->impl_ver);
+	}
+
+	if (proto)
+		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 const struct scmi_protocol *
 scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
 {
@@ -283,10 +324,8 @@ scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
 	if (protocol_id < SCMI_PROTOCOL_VENDOR_BASE)
 		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);
+		proto = scmi_vendor_protocol_get(protocol_id, version);
+
 	if (!proto || !try_module_get(proto->owner)) {
 		pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
 		return NULL;
@@ -294,11 +333,6 @@ scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
 
 	pr_debug("Found SCMI Protocol 0x%x\n", protocol_id);
 
-	if (protocol_id >= SCMI_PROTOCOL_VENDOR_BASE)
-		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;
 }
 
@@ -366,7 +400,9 @@ int scmi_protocol_register(const struct scmi_protocol *proto)
 		return ret;
 	}
 
-	pr_debug("Registered SCMI Protocol 0x%x\n", proto->id);
+	pr_debug("Registered SCMI Protocol 0x%x - %s  %s  0x%08X\n",
+		 proto->id, proto->vendor_id, proto->sub_vendor_id,
+		 proto->impl_ver);
 
 	return 0;
 }
-- 
2.47.0



From cristian.marussi at arm.com  Tue Dec  3 12:00:36 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Dec 2024 20:00:36 +0000
Subject: [PATCH 0/2] Add SCMI Vendor module autoload support
Message-ID: <20241203200038.3961090-1-cristian.marussi@arm.com>

Hi,

a tiny series to add the capability to automatically load the proper
vendor protocol module when an SCMI driver tries to use it; while proper
vendor protocol selection is already provided by the SCMI core, automatic
loading of vendor protocols was not.

Lookup is now based on module aliases following the pattern:

	scmi-protocol-0x<PROTO_ID_NN>-<VENDOR_ID>

In [2/2] proper aliases are added to existing i.MX Vendor protocols...
...could not find a better way to build the alias string automagically...

...any advice is welcome in these regards...and any feedback too !

Thanks,
Cristian

Cristian Marussi (2):
  firmware: arm_scmi: Support vendor protocol modules autoloading
  firmware: arm_scmi: Add module aliases to i.MX vendor protocols

 drivers/firmware/arm_scmi/driver.c            | 56 +++++++++++++++----
 .../arm_scmi/vendors/imx/imx-sm-bbm.c         |  5 +-
 .../arm_scmi/vendors/imx/imx-sm-misc.c        |  5 +-
 include/linux/scmi_imx_protocol.h             |  9 +--
 4 files changed, 57 insertions(+), 18 deletions(-)

-- 
2.47.0



From cristian.marussi at arm.com  Tue Dec  3 12:00:38 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Dec 2024 20:00:38 +0000
Subject: [PATCH 2/2] firmware: arm_scmi: Add module aliases to i.MX vendor protocols
In-Reply-To: <20241203200038.3961090-1-cristian.marussi@arm.com>
References: <20241203200038.3961090-1-cristian.marussi@arm.com>
Message-ID: <20241203200038.3961090-3-cristian.marussi@arm.com>

Using the pattern 'scmi-protocol-0x<PROTO_ID>-<VEND_ID>' as MODULE_ALIAS
allows the SCMI core to autoload this protocol, if built as a module, when
its protocol operations are requested by an SCMI driver.

Cc: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c  | 5 +++--
 drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c | 5 +++--
 include/linux/scmi_imx_protocol.h                   | 9 +++++----
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c
index 17799eacf06c..aa176c1a5eef 100644
--- a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c
+++ b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c
@@ -374,10 +374,11 @@ static const struct scmi_protocol scmi_imx_bbm = {
 	.ops = &scmi_imx_bbm_proto_ops,
 	.events = &scmi_imx_bbm_protocol_events,
 	.supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,
-	.vendor_id = "NXP",
-	.sub_vendor_id = "IMX",
+	.vendor_id = SCMI_IMX_VENDOR,
+	.sub_vendor_id = SCMI_IMX_SUBVENDOR,
 };
 module_scmi_protocol(scmi_imx_bbm);
 
+MODULE_ALIAS("scmi-protocol-" __stringify(SCMI_PROTOCOL_IMX_BBM) "-" SCMI_IMX_VENDOR);
 MODULE_DESCRIPTION("i.MX SCMI BBM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c
index a86ab9b35953..83b69fc4fba5 100644
--- a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c
+++ b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c
@@ -309,10 +309,11 @@ static const struct scmi_protocol scmi_imx_misc = {
 	.ops = &scmi_imx_misc_proto_ops,
 	.events = &scmi_imx_misc_protocol_events,
 	.supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,
-	.vendor_id = "NXP",
-	.sub_vendor_id = "IMX",
+	.vendor_id = SCMI_IMX_VENDOR,
+	.sub_vendor_id = SCMI_IMX_SUBVENDOR,
 };
 module_scmi_protocol(scmi_imx_misc);
 
+MODULE_ALIAS("scmi-protocol-" __stringify(SCMI_PROTOCOL_IMX_MISC) "-" SCMI_IMX_VENDOR);
 MODULE_DESCRIPTION("i.MX SCMI MISC driver");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/scmi_imx_protocol.h b/include/linux/scmi_imx_protocol.h
index 066216f1357a..53b356a26414 100644
--- a/include/linux/scmi_imx_protocol.h
+++ b/include/linux/scmi_imx_protocol.h
@@ -13,10 +13,11 @@
 #include <linux/notifier.h>
 #include <linux/types.h>
 
-enum scmi_nxp_protocol {
-	SCMI_PROTOCOL_IMX_BBM = 0x81,
-	SCMI_PROTOCOL_IMX_MISC = 0x84,
-};
+#define	SCMI_PROTOCOL_IMX_BBM	0x81
+#define	SCMI_PROTOCOL_IMX_MISC	0x84
+
+#define SCMI_IMX_VENDOR		"NXP"
+#define SCMI_IMX_SUBVENDOR	"IMX"
 
 struct scmi_imx_bbm_proto_ops {
 	int (*rtc_time_set)(const struct scmi_protocol_handle *ph, u32 id,
-- 
2.47.0



From nfraprado at collabora.com  Tue Dec  3 12:07:54 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Tue, 03 Dec 2024 17:07:54 -0300
Subject: [PATCH] ASoC: mediatek: mt8188: Enable apll1 clock during reg rw
 to prevent hang
Message-ID: <20241203-mt8188-afe-fix-hang-disabled-apll1-clk-v1-1-07cdd7760834@collabora.com>

Currently, booting the Genio 700 EVK board with the MT8188 sound
platform driver configured as a module (CONFIG_SND_SOC_MT8188=m) results
in a system hang right when the HW registers for the audio controller
are read:

  mt8188-audio 10b10000.audio-controller: No cache defaults, reading back from HW

The hang doesn't occur with the driver configured as builtin as then the
unused clocks are still enabled.

Enable the apll1 clock during register read/write to prevent the hang.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
index e69c1bb2cb239596dee50b166c20192d5408be10..fb8cf286df3f02ac076528b898fd0d7a708ec1ea 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
@@ -587,6 +587,8 @@ int mt8188_afe_enable_reg_rw_clk(struct mtk_base_afe *afe)
 	mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS_HP]);
 	mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
 
+	mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_APMIXED_APLL1]);
+
 	return 0;
 }
 
@@ -594,6 +596,8 @@ int mt8188_afe_disable_reg_rw_clk(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_APMIXED_APLL1]);
+
 	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
 	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS_HP]);
 	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE]);

---
base-commit: b852e1e7a0389ed6168ef1d38eb0bad71a6b11e8
change-id: 20241203-mt8188-afe-fix-hang-disabled-apll1-clk-b3c11782cbaf

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From andrew at lunn.ch  Tue Dec  3 12:13:00 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 3 Dec 2024 21:13:00 +0100
Subject: [PATCH] gpio: GPIO_MVEBU should not default to y when
 compile-testing
In-Reply-To: <6b9e55dbf544297d5acf743f6fa473791ab10644.1733242798.git.geert+renesas@glider.be>
References: <6b9e55dbf544297d5acf743f6fa473791ab10644.1733242798.git.geert+renesas@glider.be>
Message-ID: <f552b813-1817-4507-9699-fae87575a762@lunn.ch>

On Tue, Dec 03, 2024 at 05:23:16PM +0100, Geert Uytterhoeven wrote:
> Merely enabling compile-testing should not enable additional
> functionality.

Sorry for being dumb, but i don't actually see what is wrong here.

There are 4 GPIO drivers which have

	def_bool y

COMPILE_TEST is about building as much as possible, in order to find
build bugs. So i don't get what you mean by additional
functionality. No additional functionality within the MVEBU driver
gets enabled by COMPILE_TEST.

	Andrew


From sboyd at kernel.org  Tue Dec  3 12:15:48 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 03 Dec 2024 12:15:48 -0800
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <1jr06pkof6.fsf@starbuckisacylon.baylibre.com>
References: <20241127-clk-audio-fix-rst-missing-v1-1-9f9d0ab98fce@baylibre.com> <f8de4a2a-776f-4c10-b75e-e845bcc38dde@app.fastmail.com> <1j4j3r32ld.fsf@starbuckisacylon.baylibre.com> <306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com> <1jy1131kxz.fsf@starbuckisacylon.baylibre.com> <c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com> <1jplmf1jqa.fsf@starbuckisacylon.baylibre.com> <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com> <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org> <1jr06pkof6.fsf@starbuckisacylon.baylibre.com>
Message-ID: <37b656cc8272552ba07c93c5a9a59641.sboyd@kernel.org>

Quoting Jerome Brunet (2024-12-03 03:15:41)
> On Mon 02 Dec 2024 at 18:53, Stephen Boyd <sboyd at kernel.org> wrote:
> >
> > I think the best approach is to add the reset auxilary device with a
> > function that creates the auxiliary device directly by string name and
> > does nothing else. Maybe we can have some helper in the auxiliary
> > layer that does that all for us, because it's quite a bit of boiler
> > plate that we need to write over and over again. Something like:
> >
> >   int devm_auxiliary_device_create(struct device *parent, const char *name)
> >
> > that does the whole kzalloc() + ida dance that
> > devm_meson_rst_aux_register() is doing today and wraps it all up so that
> > the device is removed when the parent driver unbinds. Then this clk
> > driver can register the reset device with a single call and not need to
> > do anything besides select AUXILIARY_BUS.
> 
> I think this is fairly close to what I proposed in the inital RFC, but
> generic instead of specific.

Ok :-/ I've realized that we need this sort of approach in more places
to logically split the device without making it SoC specific. It's only
useful to have the registration API live in the driver when we need to
call functions provided by that module from the driver registering the
auxiliary device.

> 
> I suspect the the generic path is likely to trigger more discussion.
> I'd like to be able to finish this migration, instead of leaving half
> finished like it is now.

Is the half finished migration a problem for this cycle? I was intending
to send the revert later this week and try again next cycle.

> 
> May I add back the boiler plate code in drivers/clk/meson, similar to
> what was proposed in the RFC [1] and propose the generic implementation
> in parallel ? It will just be a matter of switching when/if it is approved.

Sure. You can make devm_meson_clk_rst_aux_register() use the same
signature as I proposed above so that it's a one line patch later. And
definitely drop the imply RESET_MESON and depends on REGMAP part. Maybe
you can put it in the clkc-utils file?


From sboyd at kernel.org  Tue Dec  3 12:21:52 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 03 Dec 2024 12:21:52 -0800
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <0f07300a-8b32-4d3e-a447-b3fe3cf1ca81@app.fastmail.com>
References: <20241127-clk-audio-fix-rst-missing-v1-1-9f9d0ab98fce@baylibre.com> <f8de4a2a-776f-4c10-b75e-e845bcc38dde@app.fastmail.com> <1j4j3r32ld.fsf@starbuckisacylon.baylibre.com> <306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com> <1jy1131kxz.fsf@starbuckisacylon.baylibre.com> <c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com> <1jplmf1jqa.fsf@starbuckisacylon.baylibre.com> <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com> <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org> <0f07300a-8b32-4d3e-a447-b3fe3cf1ca81@app.fastmail.com>
Message-ID: <c9556de589e289cb1d278d41014791a6.sboyd@kernel.org>

Quoting Arnd Bergmann (2024-12-03 04:43:03)
> On Tue, Dec 3, 2024, at 03:53, Stephen Boyd wrote:
> > Quoting Arnd Bergmann (2024-11-28 07:34:46)
> >> On Thu, Nov 28, 2024, at 16:06, Jerome Brunet wrote:
> >> Stephen, can you please take a look here and see if you
> >> have a better idea for either decoupling the two drivers
> >> enough to avoid the link time dependency, or to reintegrate
> >> the reset controller code into the clk driver and avoid
> >> the complexity?
> >
> > I think the best approach is to add the reset auxilary device with a
> > function that creates the auxiliary device directly by string name and
> > does nothing else. Maybe we can have some helper in the auxiliary
> > layer that does that all for us, because it's quite a bit of boiler
> > plate that we need to write over and over again. Something like:
> >
> >   int devm_auxiliary_device_create(struct device *parent, const char *name)
> >
> > that does the whole kzalloc() + ida dance that
> > devm_meson_rst_aux_register() is doing today and wraps it all up so that
> > the device is removed when the parent driver unbinds. Then this clk
> > driver can register the reset device with a single call and not need to
> > do anything besides select AUXILIARY_BUS. The regmap can be acquired
> > from the parent device in the auxiliary driver probe with
> > dev_get_regmap(adev->parent).
> 
> I like the idea. Two questions about the interface:
> 
>  - should there be a 'void *platform_data' argument anyway?
>    Even if this can be looked up from the parent, it seems
>    useful enough

Sure. Probably that can be added as some variant like
devm_auxiliary_device_create_pdata() when/if it's needed.

> 
>  - What is the scope of the 'ida' number? My impression was
>    this should be local to one parent device, but I don't
>    know how the number is used in the end, so maybe a global
>    number allocator is sufficient.
> 

>From what I can tell it's only used for the device name and not for
driver matching. That's probably to make it so we don't get conflicts in
sysfs with devices because they all share the same bus. I'd guess that a
global allocator is sufficient.


From simons.philippe at gmail.com  Tue Dec  3 12:24:06 2024
From: simons.philippe at gmail.com (Philippe Simons)
Date: Tue, 3 Dec 2024 21:24:06 +0100
Subject: [PATCH] Update H700 opp values
In-Reply-To: <CAGb2v64b-m8XoXWXyPFLZKpfTJd2beE_QjUUbf17o4y_rfTmJg@mail.gmail.com>
References: <20241128154556.2743839-1-simons.philippe@gmail.com> <CAGb2v64b-m8XoXWXyPFLZKpfTJd2beE_QjUUbf17o4y_rfTmJg@mail.gmail.com>
Message-ID: <CADomA48EED-yfwdR8O+3Xd0YKzn=QodECfmdiuFUu9YPWn0GdQ@mail.gmail.com>

It seems I was looking at the correct source of instabilities, but
not with the correct solution.

incorrect cpu voltages were indeed causing the crashes but only
because the cpu regulator was missing the property
regulator-ramp-delay. The patch can be discarded, I'll post a new
that adds the missing properties on the regulators.

Philippe

On Fri, Nov 29, 2024 at 6:13?AM Chen-Yu Tsai <wens at csie.org> wrote:
>
> On Thu, Nov 28, 2024 at 11:46?PM Philippe Simons
> <simons.philippe at gmail.com> wrote:
> >
> > My H700 (RG35XX-H, RG40XX-V and RG CubeXX) devices are very unstable,
> > especially with some OPPs.
> > Crashes were fairly easy to reproduce with any dynamic cpufreq governor
> > and some load on CPU, usually in matter of minutes.
> > Crashes manifested randomly as simply hanging or various kernel oops
> >
> > Manufacturer (Anbernic) is using more conservative mircrovolt values,
> > so let's use these.
> > While using performance gov seems stables at 1.5Ghz, it still crashes
> > using a dynamic gov (even with Andre reparenting patch), so let's drop
> > it for now, like manufacturer does.
> >
> > Signed-off-by: Philippe Simons <simons.philippe at gmail.com
> > ---
> >  .../dts/allwinner/sun50i-h616-cpu-opp.dtsi    | 19 +++++++++----------
> >  1 file changed, 9 insertions(+), 10 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
> > index dd10aaf47..ac13fe169 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
> > @@ -50,24 +50,21 @@ opp-1008000000 {
> >                         opp-microvolt-speed2 = <950000>;
> >                         opp-microvolt-speed3 = <950000>;
> >                         opp-microvolt-speed4 = <1020000>;
> > -                       opp-microvolt-speed5 = <900000>;
> > +                       opp-microvolt-speed5 = <950000>;
>
> It seems that you are encountering the issues on this particular binning.
> Could you mention that in the commit message?
>
> It's not very obvious that H700 == a particular speed bin of H616.
>
> ChenYu
>
> >                         clock-latency-ns = <244144>; /* 8 32k periods */
> >                         opp-supported-hw = <0x3f>;
> >                 };
> >
> >                 opp-1032000000 {
> >                         opp-hz = /bits/ 64 <1032000000>;
> > -                       opp-microvolt = <900000>;
> > +                       opp-microvolt = <950000>;
> >                         clock-latency-ns = <244144>; /* 8 32k periods */
> >                         opp-supported-hw = <0x20>;
> >                 };
> >
> >                 opp-1104000000 {
> >                         opp-hz = /bits/ 64 <1104000000>;
> > -                       opp-microvolt-speed0 = <1000000>;
> > -                       opp-microvolt-speed2 = <1000000>;
> > -                       opp-microvolt-speed3 = <1000000>;
> > -                       opp-microvolt-speed5 = <950000>;
> > +                       opp-microvolt = <1000000>;
> >                         clock-latency-ns = <244144>; /* 8 32k periods */
> >                         opp-supported-hw = <0x2d>;
> >                 };
> > @@ -79,7 +76,7 @@ opp-1200000000 {
> >                         opp-microvolt-speed2 = <1050000>;
> >                         opp-microvolt-speed3 = <1050000>;
> >                         opp-microvolt-speed4 = <1100000>;
> > -                       opp-microvolt-speed5 = <1020000>;
> > +                       opp-microvolt-speed5 = <1050000>;
> >                         clock-latency-ns = <244144>; /* 8 32k periods */
> >                         opp-supported-hw = <0x3f>;
> >                 };
> > @@ -93,7 +90,10 @@ opp-1320000000 {
> >
> >                 opp-1416000000 {
> >                         opp-hz = /bits/ 64 <1416000000>;
> > -                       opp-microvolt = <1100000>;
> > +                       opp-microvolt-speed0 = <1100000>;
> > +                       opp-microvolt-speed2 = <1100000>;
> > +                       opp-microvolt-speed3 = <1100000>;
> > +                       opp-microvolt-speed5 = <1160000>;
> >                         clock-latency-ns = <244144>; /* 8 32k periods */
> >                         opp-supported-hw = <0x2d>;
> >                 };
> > @@ -102,9 +102,8 @@ opp-1512000000 {
> >                         opp-hz = /bits/ 64 <1512000000>;
> >                         opp-microvolt-speed1 = <1100000>;
> >                         opp-microvolt-speed3 = <1100000>;
> > -                       opp-microvolt-speed5 = <1160000>;
> >                         clock-latency-ns = <244144>; /* 8 32k periods */
> > -                       opp-supported-hw = <0x2a>;
> > +                       opp-supported-hw = <0x0a>;
> >                 };
> >         };
> >  };
> > --
> > 2.46.1
> >


From brgl at bgdev.pl  Tue Dec  3 12:29:02 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 3 Dec 2024 21:29:02 +0100
Subject: [PATCH] gpio: GPIO_MVEBU should not default to y when compile-testing
In-Reply-To: <f552b813-1817-4507-9699-fae87575a762@lunn.ch>
References: <6b9e55dbf544297d5acf743f6fa473791ab10644.1733242798.git.geert+renesas@glider.be>
 <f552b813-1817-4507-9699-fae87575a762@lunn.ch>
Message-ID: <CAMRc=Mfh5Rv8OKWOcPVzJp-_e_bXgywT2=+N2cF1ONT3kiw7tQ@mail.gmail.com>

On Tue, Dec 3, 2024 at 9:13?PM Andrew Lunn <andrew at lunn.ch> wrote:
>
> On Tue, Dec 03, 2024 at 05:23:16PM +0100, Geert Uytterhoeven wrote:
> > Merely enabling compile-testing should not enable additional
> > functionality.
>
> Sorry for being dumb, but i don't actually see what is wrong here.
>
> There are 4 GPIO drivers which have
>
>         def_bool y
>
> COMPILE_TEST is about building as much as possible, in order to find
> build bugs. So i don't get what you mean by additional
> functionality. No additional functionality within the MVEBU driver
> gets enabled by COMPILE_TEST.
>
>         Andrew

No, Geert is right. I have been yelled at by Linus Torvalds already
for too eagerly enabling too many options. COMPILE_TEST is really
about making it possible to build more things with make allmodconfig,
not necessarily defaulting to y for everything.

Bart


From simons.philippe at gmail.com  Tue Dec  3 12:38:23 2024
From: simons.philippe at gmail.com (Philippe Simons)
Date: Tue,  3 Dec 2024 21:38:23 +0100
Subject: [PATCH] arm64: dts: allwinner: h616: rg35xx add missing regulator-ramp-delay
Message-ID: <20241203203824.23306-1-simons.philippe@gmail.com>

AXP datasheet says that ramp delay is 15.625 us/step,
which is 10mV in our case.

add missing regulator-ramp-delay to dcdc regulators accordingly

Signed-off-by: Philippe Simons <simons.philippe at gmail.com>
---
 .../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts    | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
index 80ccab7b5..b6e76a804 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
@@ -238,6 +238,7 @@ reg_dcdc1: dcdc1 {
 				regulator-always-on;
 				regulator-min-microvolt = <900000>;
 				regulator-max-microvolt = <1160000>;
+				regulator-ramp-delay = <640>;
 				regulator-name = "vdd-cpu";
 			};
 
@@ -245,6 +246,7 @@ reg_dcdc2: dcdc2 {
 				regulator-always-on;
 				regulator-min-microvolt = <940000>;
 				regulator-max-microvolt = <940000>;
+				regulator-ramp-delay = <640>;
 				regulator-name = "vdd-gpu-sys";
 			};
 
@@ -252,6 +254,7 @@ reg_dcdc3: dcdc3 {
 				regulator-always-on;
 				regulator-min-microvolt = <1100000>;
 				regulator-max-microvolt = <1100000>;
+				regulator-ramp-delay = <640>;
 				regulator-name = "vdd-dram";
 			};
 
-- 
2.47.1



From sboyd at kernel.org  Tue Dec  3 12:40:32 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 03 Dec 2024 12:40:32 -0800
Subject: [PATCH 00/37] drm/vc4: Add support for BCM2712 / Pi5 display hardware
In-Reply-To: <CAPY8ntD7tf6+PXKdWe8_KjCiPoemR0RQDiaHHndtjutOLGbR1w@mail.gmail.com>
References: <20241023-drm-vc4-2712-support-v1-0-1cc2d5594907@raspberrypi.com> <CAPY8ntBM=34pTiQ=t-CjtYEE5Ax6D=EtiY-sLT1keUkUMXuLeA@mail.gmail.com> <20241122-orthodox-mantis-of-reading-2dcdcf@houat> <13cfb66b-f904-4720-8829-a6d9db85aaa5@broadcom.com> <CAPY8ntD7tf6+PXKdWe8_KjCiPoemR0RQDiaHHndtjutOLGbR1w@mail.gmail.com>
Message-ID: <0c17fbef1e4dd692e2459255af0b4ace.sboyd@kernel.org>

Quoting Dave Stevenson (2024-11-27 06:43:38)
> 
> V2 includes fixing Maxime's comment on "[PATCH 31/37] clk: bcm: rpi:
> Allow cpufreq driver to also adjust gpu clocks" that Stephen also
> commented on.
> 
> Stephen: Sorry, maintaining newbie, particularly for clocks. I see in
> linux-clk patchwork they are marked as "Awaiting Upstream". What, if
> anything, do I need to do on those?

I wasn't expecting to take the patches. If you want me to do so please
resend the clk patches and I'll apply them for the next merge window..


From Frank.li at nxp.com  Tue Dec  3 12:42:32 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 3 Dec 2024 15:42:32 -0500
Subject: [PATCH v5 1/2] PCI: Add enable_device() and disable_device()
 callbacks for bridges
In-Reply-To: <20241104-imx95_lut-v5-1-feb972f3f13b@nxp.com>
References: <20241104-imx95_lut-v5-0-feb972f3f13b@nxp.com>
 <20241104-imx95_lut-v5-1-feb972f3f13b@nxp.com>
Message-ID: <Z09tOGxAK6nBB8wV@lizhi-Precision-Tower-5810>

On Mon, Nov 04, 2024 at 02:22:59PM -0500, Frank Li wrote:
> Some PCIe host bridges require special handling when enabling or disabling
> PCIe Endpoints. For example, the i.MX95 platform has a lookup table to map
> Requester IDs to StreamIDs, which are used by the SMMU and MSI controller
> to identify the source of DMA accesses.
>
> Without this mapping, DMA accesses may target unintended memory, which
> would corrupt memory or read the wrong data.
>
> Add a host bridge .enable_device() hook the imx6 driver can use to
> configure the Requester ID to StreamID mapping. The hardware table isn't
> big enough to map all possible Requester IDs, so this hook may fail if no
> table space is available. In that case, return failure from
> pci_enable_device().
>
> It might make more sense to make pci_set_master() decline to enable bus
> mastering and return failure, but it currently doesn't have a way to return
> failure.
>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---

Bjorn Helgaas:

	Can I keep your acked tag? Compared V4, just use static helper
functions.

Frank

> Change from v4 to v5
> - Add two static help functions
> int pci_host_bridge_enable_device(dev);
> void pci_host_bridge_disable_device(dev);
> - remove tags because big change
> Acked-by: Bjorn Helgaas <bhelgaas at google.com>
> Reviewed-by: Marc Zyngier <maz at kernel.org>
> Tested-by: Marc Zyngier <maz at kernel.org>
>
> Change from v3 to v4
> - Add Bjorn's ack tag
>
> Change from v2 to v3
> - use Bjorn suggest's commit message.
> - call disable_device() when error happen.
>
> Change from v1 to v2
> - move enable(disable)device ops to pci_host_bridge
> ---
>  drivers/pci/pci.c   | 36 +++++++++++++++++++++++++++++++++++-
>  include/linux/pci.h |  2 ++
>  2 files changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 67013df89a694..4735bc665ab3b 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -2055,6 +2055,28 @@ int __weak pcibios_enable_device(struct pci_dev *dev, int bars)
>  	return pci_enable_resources(dev, bars);
>  }
>
> +static int pci_host_bridge_enable_device(struct pci_dev *dev)
> +{
> +	struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus);
> +	int err;
> +
> +	if (host_bridge && host_bridge->enable_device) {
> +		err = host_bridge->enable_device(host_bridge, dev);
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static void pci_host_bridge_disable_device(struct pci_dev *dev)
> +{
> +	struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus);
> +
> +	if (host_bridge && host_bridge->disable_device)
> +		host_bridge->disable_device(host_bridge, dev);
> +}
> +
>  static int do_pci_enable_device(struct pci_dev *dev, int bars)
>  {
>  	int err;
> @@ -2070,9 +2092,13 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
>  	if (bridge)
>  		pcie_aspm_powersave_config_link(bridge);
>
> +	err = pci_host_bridge_enable_device(dev);
> +	if (err)
> +		return err;
> +
>  	err = pcibios_enable_device(dev, bars);
>  	if (err < 0)
> -		return err;
> +		goto err_enable;
>  	pci_fixup_device(pci_fixup_enable, dev);
>
>  	if (dev->msi_enabled || dev->msix_enabled)
> @@ -2087,6 +2113,12 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
>  	}
>
>  	return 0;
> +
> +err_enable:
> +	pci_host_bridge_disable_device(dev);
> +
> +	return err;
> +
>  }
>
>  /**
> @@ -2270,6 +2302,8 @@ void pci_disable_device(struct pci_dev *dev)
>  	if (atomic_dec_return(&dev->enable_cnt) != 0)
>  		return;
>
> +	pci_host_bridge_disable_device(dev);
> +
>  	do_pci_disable_device(dev);
>
>  	dev->is_busmaster = 0;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index a17edc6c28fda..5f75c30f263be 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -596,6 +596,8 @@ struct pci_host_bridge {
>  	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
>  	int (*map_irq)(const struct pci_dev *, u8, u8);
>  	void (*release_fn)(struct pci_host_bridge *);
> +	int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
> +	void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
>  	void		*release_data;
>  	unsigned int	ignore_reset_delay:1;	/* For entire hierarchy */
>  	unsigned int	no_ext_tags:1;		/* No Extended Tags */
>
> --
> 2.34.1
>


From andrew at lunn.ch  Tue Dec  3 12:59:56 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 3 Dec 2024 21:59:56 +0100
Subject: [PATCH] gpio: GPIO_MVEBU should not default to y when
 compile-testing
In-Reply-To: <CAMRc=Mfh5Rv8OKWOcPVzJp-_e_bXgywT2=+N2cF1ONT3kiw7tQ@mail.gmail.com>
References: <6b9e55dbf544297d5acf743f6fa473791ab10644.1733242798.git.geert+renesas@glider.be>
 <f552b813-1817-4507-9699-fae87575a762@lunn.ch>
 <CAMRc=Mfh5Rv8OKWOcPVzJp-_e_bXgywT2=+N2cF1ONT3kiw7tQ@mail.gmail.com>
Message-ID: <44126f2f-92ce-412b-ad9d-e0e0ea28d36d@lunn.ch>

On Tue, Dec 03, 2024 at 09:29:02PM +0100, Bartosz Golaszewski wrote:
> On Tue, Dec 3, 2024 at 9:13?PM Andrew Lunn <andrew at lunn.ch> wrote:
> >
> > On Tue, Dec 03, 2024 at 05:23:16PM +0100, Geert Uytterhoeven wrote:
> > > Merely enabling compile-testing should not enable additional
> > > functionality.
> >
> > Sorry for being dumb, but i don't actually see what is wrong here.
> >
> > There are 4 GPIO drivers which have
> >
> >         def_bool y
> >
> > COMPILE_TEST is about building as much as possible, in order to find
> > build bugs. So i don't get what you mean by additional
> > functionality. No additional functionality within the MVEBU driver
> > gets enabled by COMPILE_TEST.
> >
> >         Andrew
> 
> No, Geert is right. I have been yelled at by Linus Torvalds already
> for too eagerly enabling too many options. COMPILE_TEST is really
> about making it possible to build more things with make allmodconfig,
> not necessarily defaulting to y for everything.

So are you saying COMPILE_TEST should allow something to be enabled,
but should not actually enable it?

	Andrew


From igor.belwon at mentallysanemainliners.org  Tue Dec  3 13:13:43 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Tue,  3 Dec 2024 22:13:43 +0100
Subject: [PATCH v1 1/2] dt-bindings: soc: samsung: exynos-pmu: Add exynos990-pmu compatible
In-Reply-To: <20241203211344.515431-1-igor.belwon@mentallysanemainliners.org>
References: <20241203211344.515431-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241203211344.515431-2-igor.belwon@mentallysanemainliners.org>

Add a dt-binding compatible for the exynos990-pmu.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
index 6cdfe7e059a3..8e6d051d8c97 100644
--- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
+++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
@@ -55,6 +55,7 @@ properties:
               - samsung,exynos7885-pmu
               - samsung,exynos8895-pmu
               - samsung,exynos9810-pmu
+              - samsung,exynos990-pmu
               - samsung,exynosautov9-pmu
               - samsung,exynosautov920-pmu
               - tesla,fsd-pmu
-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Tue Dec  3 13:13:44 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Tue,  3 Dec 2024 22:13:44 +0100
Subject: [PATCH v1 2/2] arm64: dts: exynos990: Add pmu and syscon-reboot nodes
In-Reply-To: <20241203211344.515431-1-igor.belwon@mentallysanemainliners.org>
References: <20241203211344.515431-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241203211344.515431-3-igor.belwon@mentallysanemainliners.org>

Add PMU syscon, and syscon-reboot nodes to the Exynos990 dtsi.

Reboot of the Exynos990 SoC is handled by setting bit(SWRESET_TRIGGER[1])
of SWRESET register (PMU + 0x3a00).

Tested using the "reboot" command.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/exynos990.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos990.dtsi b/arch/arm64/boot/dts/exynos/exynos990.dtsi
index c1986f00e443..2619f821bc7c 100644
--- a/arch/arm64/boot/dts/exynos/exynos990.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos990.dtsi
@@ -227,6 +227,20 @@ wakeup-interrupt-controller {
 			};
 		};
 
+		pmu_system_controller: system-controller at 15860000 {
+			compatible = "samsung,exynos990-pmu",
+				     "samsung,exynos7-pmu", "syscon";
+			reg = <0x15860000 0x10000>;
+
+			reboot: syscon-reboot {
+				compatible = "syscon-reboot";
+				regmap = <&pmu_system_controller>;
+				offset = <0x3a00>; /* SWRESET */
+				mask = <0x2>; /* SWRESET_TRIGGER */
+				value = <0x2>;
+			};
+		};
+
 		pinctrl_cmgp: pinctrl at 15c30000 {
 			compatible = "samsung,exynos990-pinctrl";
 			reg = <0x15c30000 0x1000>;
-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Tue Dec  3 13:13:42 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Tue,  3 Dec 2024 22:13:42 +0100
Subject: [PATCH v1 0/2] Add pmu and syscon-reboot support to Exynos990
Message-ID: <20241203211344.515431-1-igor.belwon@mentallysanemainliners.org>

Hi all,

This small series adds support for the pmu, as well as syscon-reboot support to
the Exynos990 SoC. It has been tested with the reboot command in an initramfs.

Typically, this would be added during the initial SoC bringup, however I was
unsure as to if the syscon would work correctly until I could test it
(especially when it comes to reboot), which I just got around to doing.

Kind regards,

Igor

Igor Belwon (2):
  dt-bindings: soc: samsung: exynos-pmu: Add exynos990-pmu compatible
  arm64: dts: exynos990: Add pmu and syscon-reboot nodes

 .../bindings/soc/samsung/exynos-pmu.yaml           |  1 +
 arch/arm64/boot/dts/exynos/exynos990.dtsi          | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

-- 
2.45.2



From catalin.marinas at arm.com  Tue Dec  3 13:20:10 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue,  3 Dec 2024 21:20:10 +0000
Subject: [PATCH] arm64: mm: fix zone_dma_limit calculation
In-Reply-To: <20241125171650.77424-1-yang@os.amperecomputing.com>
References: <20241125171650.77424-1-yang@os.amperecomputing.com>
Message-ID: <173326077457.517002.14427872059455527771.b4-ty@arm.com>

On Mon, 25 Nov 2024 09:16:50 -0800, Yang Shi wrote:
> The commit ba0fb44aed47 ("dma-mapping: replace zone_dma_bits by
> zone_dma_limit") changed how zone_dma_limit was calculated.  Now it
> returns the memsize limit in IORT or device tree instead of U32_MAX if
> the memsize limit is greater than U32_MAX.
> 
> This resulted in DMA allocations may use GFP_DMA even though the devices
> don't require it.  It caused regression on our two sockets systems due
> to excessive remote memory access.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: mm: fix zone_dma_limit calculation
      https://git.kernel.org/arm64/c/56a708742a8b

-- 
Catalin



From catalin.marinas at arm.com  Tue Dec  3 13:19:43 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue,  3 Dec 2024 21:19:43 +0000
Subject: [PATCH] arm64: patching: avoid early page_to_phys()
In-Reply-To: <20241202170359.1475019-1-mark.rutland@arm.com>
References: <20241202170359.1475019-1-mark.rutland@arm.com>
Message-ID: <173326077458.517002.4357104295343949029.b4-ty@arm.com>

On Mon, 02 Dec 2024 17:03:59 +0000, Mark Rutland wrote:
> When arm64 is configured with CONFIG_DEBUG_VIRTUAL=y, a warning is
> printed from the patching code because patch_map(), e.g.
> 
> | ------------[ cut here ]------------
> | WARNING: CPU: 0 PID: 0 at arch/arm64/kernel/patching.c:45 patch_map.constprop.0+0x120/0xd00
> | CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.13.0-rc1-00002-ge1a5d6c6be55 #1
> | Hardware name: linux,dummy-virt (DT)
> | pstate: 800003c5 (Nzcv DAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> | pc : patch_map.constprop.0+0x120/0xd00
> | lr : patch_map.constprop.0+0x120/0xd00
> | sp : ffffa9bb312a79a0
> | x29: ffffa9bb312a79a0 x28: 0000000000000001 x27: 0000000000000001
> | x26: 0000000000000000 x25: 0000000000000000 x24: 00000000000402e8
> | x23: ffffa9bb2c94c1c8 x22: ffffa9bb2c94c000 x21: ffffa9bb222e883c
> | x20: 0000000000000002 x19: ffffc1ffc100ba40 x18: ffffa9bb2cf0f21c
> | x17: 0000000000000006 x16: 0000000000000000 x15: 0000000000000004
> | x14: 1ffff5376625b4ac x13: ffff753766a67fb8 x12: ffff753766919cd1
> | x11: 0000000000000003 x10: 1ffff5376625b4c3 x9 : 1ffff5376625b4af
> | x8 : ffff753766254f0a x7 : 0000000041b58ab3 x6 : ffff753766254f18
> | x5 : ffffa9bb312d9bc0 x4 : 0000000000000000 x3 : ffffa9bb29bd90e4
> | x2 : 0000000000000002 x1 : ffffa9bb312d9bc0 x0 : 0000000000000000
> | Call trace:
> |  patch_map.constprop.0+0x120/0xd00 (P)
> |  patch_map.constprop.0+0x120/0xd00 (L)
> |  __aarch64_insn_write+0xa8/0x120
> |  aarch64_insn_patch_text_nosync+0x4c/0xb8
> |  arch_jump_label_transform_queue+0x7c/0x100
> |  jump_label_update+0x154/0x460
> |  static_key_enable_cpuslocked+0x1d8/0x280
> |  static_key_enable+0x2c/0x48
> |  early_randomize_kstack_offset+0x104/0x168
> |  do_early_param+0xe4/0x148
> |  parse_args+0x3a4/0x838
> |  parse_early_options+0x50/0x68
> |  parse_early_param+0x58/0xe0
> |  setup_arch+0x78/0x1f0
> |  start_kernel+0xa0/0x530
> |  __primary_switched+0x8c/0xa0
> | irq event stamp: 0
> | hardirqs last  enabled at (0): [<0000000000000000>] 0x0
> | hardirqs last disabled at (0): [<0000000000000000>] 0x0
> | softirqs last  enabled at (0): [<0000000000000000>] 0x0
> | softirqs last disabled at (0): [<0000000000000000>] 0x0
> | ---[ end trace 0000000000000000 ]---
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: patching: avoid early page_to_phys()
      https://git.kernel.org/arm64/c/8d09e2d569f6

-- 
Catalin



From catalin.marinas at arm.com  Tue Dec  3 13:19:53 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue,  3 Dec 2024 21:19:53 +0000
Subject: [PATCH 0/2] Minor tweaks to arm64 CoCO guest support
In-Reply-To: <20241202145731.6422-1-will@kernel.org>
References: <20241202145731.6422-1-will@kernel.org>
Message-ID: <173326077458.517002.938138434185834868.b4-ty@arm.com>

On Mon, 02 Dec 2024 14:57:28 +0000, Will Deacon wrote:
> Here are a couple of minor tweaks to the CoCO guest support on arm64.
> 
> The first enables protected guests under pKVM when pvmfw is not being
> used (and therefore MMIO guard is not enabled). This is useful for pvmfw
> development and for testing a VMM outside of the Android Virtualisation
> Framework APIs.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/2] drivers/virt: pkvm: Don't fail ioremap() call if MMIO_GUARD fails
      https://git.kernel.org/arm64/c/d44679fb954f
[2/2] MAINTAINERS: Add CCA and pKVM CoCO guest support to the ARM64 entry
      https://git.kernel.org/arm64/c/92230596252a

-- 
Catalin



From catalin.marinas at arm.com  Tue Dec  3 13:22:35 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 3 Dec 2024 21:22:35 +0000
Subject: [PATCH] KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be
 overridden
In-Reply-To: <20241203190236.505759-1-maz@kernel.org>
References: <20241203190236.505759-1-maz@kernel.org>
Message-ID: <Z092m3iNQYbKljHN@arm.com>

On Tue, Dec 03, 2024 at 07:02:36PM +0000, Marc Zyngier wrote:
> Catalin reports that a hypervisor lying to a guest about the size
> of the ASID field may result in unexpected issues:
> 
> - if the underlying HW does only supports 8 bit ASIDs, the ASID
>   field in a TLBI VAE1* operation is only 8 bits, and the HW will
>   ignore the other 8 bits
> 
> - if on the contrary the HW is 16 bit capable, the ASID field
>   in the same TLBI operation is always 16 bits, irrespective of
>   the value of TCR_ELx.AS.
> 
> This could lead to missed invalidations if the guest was lead to
> assume that the HW had 8 bit ASIDs while they really are 16 bit wide.
> 
> In order to avoid any potential disaster that would be hard to debug,
> prenent the migration between a host with 8 bit ASIDs to one with
> wider ASIDs (the converse was obviously always forbidden). This is
> also consistent with what we already do for VMIDs.
> 
> If it becomes absolutely mandatory to support such a migration path
> in the future, we will have to trap and emulate all TLBIs, something
> that nobody should look forward to.
> 
> Fixes: d5a32b60dc18 ("KVM: arm64: Allow userspace to change ID_AA64MMFR{0-2}_EL1")
> Reported-by: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Cc: stable at vger.kernel.org
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: James Morse <james.morse at arm.com>
> Cc: Oliver Upton <oliver.upton at linux.dev>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From paul at os.amperecomputing.com  Tue Dec  3 13:28:54 2024
From: paul at os.amperecomputing.com (Paul Benoit)
Date: Tue,  3 Dec 2024 13:28:54 -0800
Subject: [PATCH v2] firmware: smccc: Support optional Arm SMC SOC_ID name
In-Reply-To: <20241114030452.10149-1-paul@os.amperecomputing.com>
References: <20241114030452.10149-1-paul@os.amperecomputing.com>
Message-ID: <20241203212854.5565-1-paul@os.amperecomputing.com>

Issue Number 1.6 of the Arm SMC Calling Convention introduces an
optional SOC_ID name string.  If available, point the 'machine' field of
the SoC Device Attributes at this string so that it will appear under
/sys/bus/soc/devices/soc0/machine.  On Arm SMC compliant SoCs, this will
allow things like 'lscpu' to eventually get a SoC provider model name
from there rather than each tool/utility needing to get a possibly
inconsistent, obsolete, or incorrect model/machine name from its own
hardcoded model/machine name table.

Signed-off-by: Paul Benoit <paul at os.amperecomputing.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
---

v1->v2: Address code review identified issues.

 drivers/firmware/smccc/soc_id.c | 75 +++++++++++++++++++++++++++++++++
 include/linux/arm-smccc.h       | 37 ++++++++++++++++
 2 files changed, 112 insertions(+)

diff --git a/drivers/firmware/smccc/soc_id.c b/drivers/firmware/smccc/soc_id.c
index 1990263fbba0..b72d100bdf31 100644
--- a/drivers/firmware/smccc/soc_id.c
+++ b/drivers/firmware/smccc/soc_id.c
@@ -32,6 +32,10 @@
 static struct soc_device *soc_dev;
 static struct soc_device_attribute *soc_dev_attr;
 
+static char __init *smccc_soc_name_init(void);
+
+static char __ro_after_init smccc_soc_id_name[136] = "";
+
 static int __init smccc_soc_init(void)
 {
 	int soc_id_rev, soc_id_version;
@@ -72,6 +76,7 @@ static int __init smccc_soc_init(void)
 	soc_dev_attr->soc_id = soc_id_str;
 	soc_dev_attr->revision = soc_id_rev_str;
 	soc_dev_attr->family = soc_id_jep106_id_str;
+	soc_dev_attr->machine = smccc_soc_name_init();
 
 	soc_dev = soc_device_register(soc_dev_attr);
 	if (IS_ERR(soc_dev)) {
@@ -93,3 +98,73 @@ static void __exit smccc_soc_exit(void)
 	kfree(soc_dev_attr);
 }
 module_exit(smccc_soc_exit);
+
+
+static inline void str_fragment_from_reg(char *dst, unsigned long reg)
+{
+	dst[0] = (reg >> 0)  & 0xff;
+	dst[1] = (reg >> 8)  & 0xff;
+	dst[2] = (reg >> 16) & 0xff;
+	dst[3] = (reg >> 24) & 0xff;
+	dst[4] = (reg >> 32) & 0xff;
+	dst[5] = (reg >> 40) & 0xff;
+	dst[6] = (reg >> 48) & 0xff;
+	dst[7] = (reg >> 56) & 0xff;
+}
+
+static char __init *smccc_soc_name_init(void)
+{
+#ifdef CONFIG_ARM64
+	struct arm_smccc_1_2_regs args;
+	struct arm_smccc_1_2_regs res;
+	size_t len;
+
+	/*
+	 * Issue Number 1.6 of the Arm SMC Calling Convention
+	 * specification introduces an optional "name" string
+	 * to the ARM_SMCCC_ARCH_SOC_ID function.  Fetch it if
+	 * available.
+	 */
+	args.a0 = ARM_SMCCC_ARCH_SOC_ID;
+	args.a1 = 2;    /* SOC_ID name */
+	arm_smccc_1_2_invoke(&args, &res);
+	if ((u32)res.a0 == 0) {
+		const unsigned int regsize = sizeof(res.a1);
+
+		/*
+		 * Copy res.a1..res.a17 to the smccc_soc_id_name string
+		 * 8 bytes at a time.  As per Issue 1.6 of the Arm SMC
+		 * Calling Convention, the string will be NUL terminated
+		 * and padded, from the end of the string to the end of the
+		 * 136 byte buffer, with NULs.
+		 */
+		str_fragment_from_reg(smccc_soc_id_name + 0*regsize, res.a1);
+		str_fragment_from_reg(smccc_soc_id_name + 1*regsize, res.a2);
+		str_fragment_from_reg(smccc_soc_id_name + 2*regsize, res.a3);
+		str_fragment_from_reg(smccc_soc_id_name + 3*regsize, res.a4);
+		str_fragment_from_reg(smccc_soc_id_name + 4*regsize, res.a5);
+		str_fragment_from_reg(smccc_soc_id_name + 5*regsize, res.a6);
+		str_fragment_from_reg(smccc_soc_id_name + 6*regsize, res.a7);
+		str_fragment_from_reg(smccc_soc_id_name + 7*regsize, res.a8);
+		str_fragment_from_reg(smccc_soc_id_name + 8*regsize, res.a9);
+		str_fragment_from_reg(smccc_soc_id_name + 9*regsize, res.a10);
+		str_fragment_from_reg(smccc_soc_id_name + 10*regsize, res.a11);
+		str_fragment_from_reg(smccc_soc_id_name + 11*regsize, res.a12);
+		str_fragment_from_reg(smccc_soc_id_name + 12*regsize, res.a13);
+		str_fragment_from_reg(smccc_soc_id_name + 13*regsize, res.a14);
+		str_fragment_from_reg(smccc_soc_id_name + 14*regsize, res.a15);
+		str_fragment_from_reg(smccc_soc_id_name + 15*regsize, res.a16);
+		str_fragment_from_reg(smccc_soc_id_name + 16*regsize, res.a17);
+
+		len = strnlen(smccc_soc_id_name, sizeof(smccc_soc_id_name));
+		if (len) {
+			if (len == sizeof(smccc_soc_id_name))
+				pr_warn(FW_BUG "Ignoring improperly formatted Name\n");
+			else
+				return smccc_soc_id_name;
+		}
+	}
+#endif
+
+	return NULL;
+}
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 67f6fdf2e7cd..9d444e5862fe 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -607,6 +607,12 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 			___res->a0 = SMCCC_RET_NOT_SUPPORTED;		\
 	} while (0)
 
+#define __fail_smccc_1_2(___res)					\
+	do {								\
+		if (___res)						\
+			___res->a0 = SMCCC_RET_NOT_SUPPORTED;		\
+	} while (0)
+
 /*
  * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
  *
@@ -639,5 +645,36 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 		method;							\
 	})
 
+/*
+ * arm_smccc_1_2_invoke() - make an SMCCC v1.2 compliant call
+ *
+ * @args: SMC args are in the a0..a17 fields of the arm_smcc_1_2_regs structure
+ * @res: result values from registers 0 to 17
+ *
+ * This macro will make either an HVC call or an SMC call depending on the
+ * current SMCCC conduit. If no valid conduit is available then -1
+ * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
+ *
+ * The return value also provides the conduit that was used.
+ */
+#define arm_smccc_1_2_invoke(args, res) ({				\
+		struct arm_smccc_1_2_regs *__args = args;		\
+		struct arm_smccc_1_2_regs *__res = res;			\
+		int method = arm_smccc_1_1_get_conduit();		\
+		switch (method) {					\
+		case SMCCC_CONDUIT_HVC:					\
+			arm_smccc_1_2_hvc(__args, __res);		\
+			break;						\
+		case SMCCC_CONDUIT_SMC:					\
+			arm_smccc_1_2_smc(__args, __res);		\
+			break;						\
+		default:						\
+			__fail_smccc_1_2(__res);			\
+			method = SMCCC_CONDUIT_NONE;			\
+			break;						\
+		}							\
+		method;							\
+	})
+
 #endif /*__ASSEMBLY__*/
 #endif /*__LINUX_ARM_SMCCC_H*/
-- 
2.46.2



From maz at kernel.org  Tue Dec  3 13:32:10 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 03 Dec 2024 21:32:10 +0000
Subject: [RFC PATCH 05/14] KVM: arm64: Always allow fixed cycle counter
In-Reply-To: <20241203193220.1070811-6-oliver.upton@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
	<20241203193220.1070811-6-oliver.upton@linux.dev>
Message-ID: <87ldwwsbad.wl-maz@kernel.org>

On Tue, 03 Dec 2024 19:32:11 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> The fixed CPU cycle counter is mandatory for PMUv3, so it doesn't make a
> lot of sense allowing userspace to filter it. Only apply the PMU event
> filter to *programmed* event counters.

But that's a change in ABI, isn't it? We explicitly say in the
documentation that the cycle counter can be filtered by specifying
event 0x11.

More importantly, the current filtering works in terms of events, and
not in terms of counters.

Instead of changing the ABI, how about simply not supporting filtering
on such non-compliant HW? Surely that would simplify a few things.

Thanks,

	M.

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


From nicolinc at nvidia.com  Tue Dec  3 14:10:12 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:12 -0800
Subject: [PATCH v2 07/13] iommufd/viommu: Add iommufd_viommu_report_irq helper
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <7e9842376e6235d9e3471356d035afe2bfe8f33b.1733263737.git.nicolinc@nvidia.com>

Similar to iommu_report_device_fault, this allows IOMMU drivers to report,
from threaded IRQ handlers to user space hypervisors, IRQs or events that
belong to a vIOMMU.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 include/linux/iommufd.h        |  9 ++++++++
 drivers/iommu/iommufd/driver.c | 41 ++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 1f5376476cfa..2ce78edec4e9 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -192,6 +192,8 @@ struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 				       unsigned long vdev_id);
 unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
 					 struct device *dev);
+int iommufd_viommu_report_irq(struct iommufd_viommu *viommu, unsigned int type,
+			      void *irq_ptr, size_t irq_len);
 #else /* !CONFIG_IOMMUFD_DRIVER_CORE */
 static inline struct iommufd_object *
 _iommufd_object_alloc(struct iommufd_ctx *ictx, size_t size,
@@ -211,6 +213,13 @@ iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu, struct device *dev)
 {
 	return 0;
 }
+
+static inline int iommufd_viommu_report_irq(struct iommufd_viommu *viommu,
+					    unsigned int type, void *irq_ptr,
+					    size_t irq_len)
+{
+	return -EOPNOTSUPP;
+}
 #endif /* CONFIG_IOMMUFD_DRIVER_CORE */
 
 /*
diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c
index 817e430a11bc..339baa270d1e 100644
--- a/drivers/iommu/iommufd/driver.c
+++ b/drivers/iommu/iommufd/driver.c
@@ -67,5 +67,46 @@ unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_viommu_get_vdev_id, IOMMUFD);
 
+/* Typically called in driver's threaded IRQ handler */
+int iommufd_viommu_report_irq(struct iommufd_viommu *viommu, unsigned int type,
+			      void *irq_ptr, size_t irq_len)
+{
+	struct iommufd_eventq_virq *eventq_virq;
+	struct iommufd_virq *virq;
+	int rc = 0;
+
+	might_sleep();
+
+	if (!viommu)
+		return -ENODEV;
+	if (WARN_ON_ONCE(!irq_len || !irq_ptr))
+		return -EINVAL;
+
+	down_read(&viommu->virqs_rwsem);
+
+	eventq_virq = iommufd_viommu_find_eventq_virq(viommu, type);
+	if (!eventq_virq) {
+		rc = -EOPNOTSUPP;
+		goto out_unlock_vdev_ids;
+	}
+
+	virq = kzalloc(sizeof(*virq) + irq_len, GFP_KERNEL);
+	if (!virq) {
+		rc = -ENOMEM;
+		goto out_unlock_vdev_ids;
+	}
+	virq->irq_data = (void *)virq + sizeof(*virq);
+	memcpy(virq->irq_data, irq_ptr, irq_len);
+
+	virq->eventq_virq = eventq_virq;
+	virq->irq_len = irq_len;
+
+	iommufd_eventq_virq_handler(virq);
+out_unlock_vdev_ids:
+	up_read(&viommu->virqs_rwsem);
+	return rc;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_viommu_report_irq, IOMMUFD);
+
 MODULE_DESCRIPTION("iommufd code shared with builtin modules");
 MODULE_LICENSE("GPL");
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:18 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:18 -0800
Subject: [PATCH v2 13/13] iommu/arm-smmu-v3: Report IRQs that belong to devices attached to vIOMMU
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <d335936fdeccfcf785589800b7e5d9b1b26a766d.1733263737.git.nicolinc@nvidia.com>

Aside from the IOPF framework, iommufd provides an additional pathway to
report a hardware event or IRQ, via the vIRQ of vIOMMU infrastructure.

Define an iommu_virq_arm_smmuv3 uAPI structure, and report stage-1 faults
in the threaded IRQ handler.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  7 +++
 include/uapi/linux/iommufd.h                  | 14 +++++
 .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c     | 16 +++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 62 ++++++++++---------
 4 files changed, 71 insertions(+), 28 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 ec7cff33a0b1..05915f141eb8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -1037,6 +1037,7 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
 int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
 				    struct iommu_domain *domain);
 void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state);
+int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt);
 #else
 #define arm_smmu_hw_info NULL
 #define arm_vsmmu_alloc NULL
@@ -1052,6 +1053,12 @@ static inline void
 arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
 {
 }
+
+static inline int
+arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt)
+{
+	return -EOPNOTSUPP;
+}
 #endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
 
 #endif /* _ARM_SMMU_V3_H */
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index d9319f5b7c69..164920d7f0ab 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -1016,9 +1016,23 @@ struct iommu_ioas_change_process {
 /**
  * enum iommu_virq_type - Virtual IRQ Type
  * @IOMMU_VIRQ_TYPE_NONE: INVALID type
+ * @IOMMU_VIRQ_TYPE_ARM_SMMUV3: ARM SMMUv3 Virtual Event
  */
 enum iommu_virq_type {
 	IOMMU_VIRQ_TYPE_NONE = 0,
+	IOMMU_VIRQ_TYPE_ARM_SMMUV3 = 1,
+};
+
+/**
+ * struct iommu_virq_arm_smmuv3 - ARM SMMUv3 Virtual IRQ
+ *                                (IOMMU_VIRQ_TYPE_ARM_SMMUV3)
+ * @evt: 256-bit ARM SMMUv3 Event record, little-endian.
+ *
+ * StreamID field reports a virtual device ID. To receive a virtual IRQ for a
+ * device, a vDEVICE must be allocated via IOMMU_VDEVICE_ALLOC.
+ */
+struct iommu_virq_arm_smmuv3 {
+	__aligned_le64 evt[4];
 };
 
 /**
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 3a77eca949e6..e3ef77e0bffd 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -447,4 +447,20 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
 	return &vsmmu->core;
 }
 
+int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt)
+{
+	struct iommu_virq_arm_smmuv3 virq_data =
+		*(struct iommu_virq_arm_smmuv3 *)evt;
+
+	virq_data.evt[0] &= ~EVTQ_0_SID;
+	virq_data.evt[0] |= FIELD_PREP(EVTQ_0_SID, vmaster->vsid);
+
+	virq_data.evt[0] = cpu_to_le64(virq_data.evt[0]);
+	virq_data.evt[1] = cpu_to_le64(virq_data.evt[1]);
+
+	return iommufd_viommu_report_irq(&vmaster->vsmmu->core,
+					 IOMMU_VIRQ_TYPE_ARM_SMMUV3, &virq_data,
+					 sizeof(virq_data));
+}
+
 MODULE_IMPORT_NS(IOMMUFD);
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 6a6113b36360..215c2d811eb7 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1779,33 +1779,6 @@ static int arm_smmu_handle_evt(struct arm_smmu_device *smmu, u64 *evt)
 		return -EOPNOTSUPP;
 	}
 
-	if (!(evt[1] & EVTQ_1_STALL))
-		return -EOPNOTSUPP;
-
-	if (evt[1] & EVTQ_1_RnW)
-		perm |= IOMMU_FAULT_PERM_READ;
-	else
-		perm |= IOMMU_FAULT_PERM_WRITE;
-
-	if (evt[1] & EVTQ_1_InD)
-		perm |= IOMMU_FAULT_PERM_EXEC;
-
-	if (evt[1] & EVTQ_1_PnU)
-		perm |= IOMMU_FAULT_PERM_PRIV;
-
-	flt->type = IOMMU_FAULT_PAGE_REQ;
-	flt->prm = (struct iommu_fault_page_request) {
-		.flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
-		.grpid = FIELD_GET(EVTQ_1_STAG, evt[1]),
-		.perm = perm,
-		.addr = FIELD_GET(EVTQ_2_ADDR, evt[2]),
-	};
-
-	if (ssid_valid) {
-		flt->prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
-		flt->prm.pasid = FIELD_GET(EVTQ_0_SSID, evt[0]);
-	}
-
 	mutex_lock(&smmu->streams_mutex);
 	master = arm_smmu_find_master(smmu, sid);
 	if (!master) {
@@ -1813,7 +1786,40 @@ static int arm_smmu_handle_evt(struct arm_smmu_device *smmu, u64 *evt)
 		goto out_unlock;
 	}
 
-	ret = iommu_report_device_fault(master->dev, &fault_evt);
+	down_read(&master->vmaster_rwsem);
+	if (evt[1] & EVTQ_1_STALL) {
+		if (evt[1] & EVTQ_1_RnW)
+			perm |= IOMMU_FAULT_PERM_READ;
+		else
+			perm |= IOMMU_FAULT_PERM_WRITE;
+
+		if (evt[1] & EVTQ_1_InD)
+			perm |= IOMMU_FAULT_PERM_EXEC;
+
+		if (evt[1] & EVTQ_1_PnU)
+			perm |= IOMMU_FAULT_PERM_PRIV;
+
+		flt->type = IOMMU_FAULT_PAGE_REQ;
+		flt->prm = (struct iommu_fault_page_request){
+			.flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
+			.grpid = FIELD_GET(EVTQ_1_STAG, evt[1]),
+			.perm = perm,
+			.addr = FIELD_GET(EVTQ_2_ADDR, evt[2]),
+		};
+
+		if (ssid_valid) {
+			flt->prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
+			flt->prm.pasid = FIELD_GET(EVTQ_0_SSID, evt[0]);
+		}
+
+		ret = iommu_report_device_fault(master->dev, &fault_evt);
+	} else if (master->vmaster && !(evt[1] & EVTQ_1_S2)) {
+		ret = arm_vmaster_report_event(master->vmaster, evt);
+	} else {
+		/* Unhandled events should be pinned */
+		ret = -EFAULT;
+	}
+	up_read(&master->vmaster_rwsem);
 out_unlock:
 	mutex_unlock(&smmu->streams_mutex);
 	return ret;
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:13 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:13 -0800
Subject: [PATCH v2 08/13] iommufd/selftest: Require vdev_id when attaching to a nested domain
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <cb654aaceb5976ff34b80e3c783182ebd51840d4.1733263737.git.nicolinc@nvidia.com>

When attaching a device to a vIOMMU-based nested domain, vdev_id must be
present. Add a piece of code hard-requesting it, for vIRQ support in the
following patch. Then, update the TEST_F.

A HWPT-based nested domain will return a NULL new_viommu, thus no such a
vDEVICE requirement.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/selftest.c        | 23 +++++++++++++++++++++++
 tools/testing/selftests/iommu/iommufd.c |  5 +++++
 2 files changed, 28 insertions(+)

diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index a0de6d6d4e68..d1438d81e664 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -161,7 +161,10 @@ enum selftest_obj_type {
 
 struct mock_dev {
 	struct device dev;
+	struct mock_viommu *viommu;
+	struct rw_semaphore viommu_rwsem;
 	unsigned long flags;
+	unsigned long vdev_id;
 	int id;
 	u32 cache[MOCK_DEV_CACHE_NUM];
 };
@@ -193,10 +196,29 @@ static int mock_domain_nop_attach(struct iommu_domain *domain,
 				  struct device *dev)
 {
 	struct mock_dev *mdev = to_mock_dev(dev);
+	struct mock_viommu *new_viommu = NULL;
+	unsigned long vdev_id = 0;
 
 	if (domain->dirty_ops && (mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
 		return -EINVAL;
 
+	iommu_group_mutex_assert(dev);
+	if (domain->type == IOMMU_DOMAIN_NESTED) {
+		new_viommu = to_mock_nested(domain)->mock_viommu;
+		if (new_viommu) {
+			vdev_id = iommufd_viommu_get_vdev_id(&new_viommu->core,
+							     dev);
+			if (!vdev_id)
+				return -ENOENT;
+		}
+	}
+	if (new_viommu != mdev->viommu) {
+		down_write(&mdev->viommu_rwsem);
+		mdev->viommu = new_viommu;
+		mdev->vdev_id = vdev_id;
+		up_write(&mdev->viommu_rwsem);
+	}
+
 	return 0;
 }
 
@@ -861,6 +883,7 @@ static struct mock_dev *mock_dev_create(unsigned long dev_flags)
 	if (!mdev)
 		return ERR_PTR(-ENOMEM);
 
+	init_rwsem(&mdev->viommu_rwsem);
 	device_initialize(&mdev->dev);
 	mdev->flags = dev_flags;
 	mdev->dev.release = mock_dev_release;
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index a1b2b657999d..212e5d62e13d 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -2736,6 +2736,7 @@ TEST_F(iommufd_viommu, viommu_alloc_nested_iopf)
 	uint32_t iopf_hwpt_id;
 	uint32_t fault_id;
 	uint32_t fault_fd;
+	uint32_t vdev_id;
 
 	if (self->device_id) {
 		test_ioctl_fault_alloc(&fault_id, &fault_fd);
@@ -2752,6 +2753,10 @@ TEST_F(iommufd_viommu, viommu_alloc_nested_iopf)
 			&iopf_hwpt_id, IOMMU_HWPT_DATA_SELFTEST, &data,
 			sizeof(data));
 
+		/* Must allocate vdevice before attaching to a nested hwpt */
+		test_err_mock_domain_replace(ENOENT, self->stdev_id,
+					     iopf_hwpt_id);
+		test_cmd_vdevice_alloc(viommu_id, dev_id, 0x99, &vdev_id);
 		test_cmd_mock_domain_replace(self->stdev_id, iopf_hwpt_id);
 		EXPECT_ERRNO(EBUSY,
 			     _test_ioctl_destroy(self->fd, iopf_hwpt_id));
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:15 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:15 -0800
Subject: [PATCH v2 10/13] iommufd/selftest: Add EVENT_VIRQ test coverage
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <20abd6d02d07f2d53ed75c2a55fc055859d0ce9e.1733263737.git.nicolinc@nvidia.com>

Trigger an IRQ giving an idev ID, to test the loopback whether receiving
or not the vdev_id that was set to the idev by the line above.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 tools/testing/selftests/iommu/iommufd_utils.h | 63 +++++++++++++++++++
 tools/testing/selftests/iommu/iommufd.c       | 22 +++++++
 .../selftests/iommu/iommufd_fail_nth.c        |  6 ++
 3 files changed, 91 insertions(+)

diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
index d979f5b0efe8..7e3e07c943cc 100644
--- a/tools/testing/selftests/iommu/iommufd_utils.h
+++ b/tools/testing/selftests/iommu/iommufd_utils.h
@@ -9,6 +9,7 @@
 #include <sys/ioctl.h>
 #include <stdint.h>
 #include <assert.h>
+#include <poll.h>
 
 #include "../kselftest_harness.h"
 #include "../../../../drivers/iommu/iommufd/iommufd_test.h"
@@ -936,3 +937,65 @@ static int _test_cmd_vdevice_alloc(int fd, __u32 viommu_id, __u32 idev_id,
 	EXPECT_ERRNO(_errno,                                                 \
 		     _test_cmd_vdevice_alloc(self->fd, viommu_id, idev_id,   \
 					     virt_id, vdev_id))
+
+static int _test_cmd_virq_alloc(int fd, __u32 viommu_id, __u32 type,
+				__u32 *virq_id, __u32 *virq_fd)
+{
+	struct iommu_virq_alloc cmd = {
+		.size = sizeof(cmd),
+		.type = type,
+		.viommu_id = viommu_id,
+	};
+	int ret;
+
+	ret = ioctl(fd, IOMMU_VIRQ_ALLOC, &cmd);
+	if (ret)
+		return ret;
+	if (virq_id)
+		*virq_id = cmd.out_virq_id;
+	if (virq_fd)
+		*virq_fd = cmd.out_virq_fd;
+	return 0;
+}
+
+#define test_cmd_virq_alloc(viommu_id, type, virq_id, virq_fd)       \
+	ASSERT_EQ(0, _test_cmd_virq_alloc(self->fd, viommu_id, type, \
+					    virq_id, virq_fd))
+#define test_err_virq_alloc(_errno, viommu_id, type, virq_id, virq_fd)       \
+	EXPECT_ERRNO(_errno, _test_cmd_virq_alloc(self->fd, viommu_id, type, \
+						    virq_id, virq_fd))
+
+static int _test_cmd_trigger_virq(int fd, __u32 dev_id, __u32 event_fd,
+				  __u32 virt_id)
+{
+	struct iommu_test_cmd trigger_virq_cmd = {
+		.size = sizeof(trigger_virq_cmd),
+		.op = IOMMU_TEST_OP_TRIGGER_VIRQ,
+		.trigger_virq = {
+			.dev_id = dev_id,
+		},
+	};
+	struct pollfd pollfd = { .fd = event_fd, .events = POLLIN };
+	struct iommu_viommu_irq_selftest irq;
+	ssize_t bytes;
+	int ret;
+
+	ret = ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_TRIGGER_VIRQ),
+		    &trigger_virq_cmd);
+	if (ret)
+		return ret;
+
+	ret = poll(&pollfd, 1, 1000);
+	if (ret < 0)
+		return ret;
+
+	bytes = read(event_fd, &irq, sizeof(irq));
+	if (bytes <= 0)
+		return -EIO;
+
+	return irq.virt_id == virt_id ? 0 : -EINVAL;
+}
+
+#define test_cmd_trigger_virq(dev_id, event_fd, vdev_id) \
+	ASSERT_EQ(0,                                     \
+		  _test_cmd_trigger_virq(self->fd, dev_id, event_fd, vdev_id))
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index 212e5d62e13d..b15ebc963e56 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -2774,15 +2774,37 @@ TEST_F(iommufd_viommu, vdevice_alloc)
 	uint32_t viommu_id = self->viommu_id;
 	uint32_t dev_id = self->device_id;
 	uint32_t vdev_id = 0;
+	uint32_t virq_id;
+	uint32_t virq_fd;
 
 	if (dev_id) {
+		/* Must allocate vdevice before attaching to a nested hwpt */
+		test_err_mock_domain_replace(ENOENT, self->stdev_id,
+					     self->nested_hwpt_id);
+
+		test_cmd_virq_alloc(viommu_id, IOMMU_VIRQ_TYPE_SELFTEST,
+				    &virq_id, &virq_fd);
+		test_err_virq_alloc(EEXIST, viommu_id, IOMMU_VIRQ_TYPE_SELFTEST,
+				    NULL, NULL);
 		/* Set vdev_id to 0x99, unset it, and set to 0x88 */
 		test_cmd_vdevice_alloc(viommu_id, dev_id, 0x99, &vdev_id);
+		test_cmd_mock_domain_replace(self->stdev_id,
+					     self->nested_hwpt_id);
+		test_cmd_trigger_virq(dev_id, virq_fd, 0x99);
 		test_err_vdevice_alloc(EEXIST, viommu_id, dev_id, 0x99,
 				       &vdev_id);
+		test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
 		test_ioctl_destroy(vdev_id);
+
+		/* Try again with 0x88 */
 		test_cmd_vdevice_alloc(viommu_id, dev_id, 0x88, &vdev_id);
+		test_cmd_mock_domain_replace(self->stdev_id,
+					     self->nested_hwpt_id);
+		test_cmd_trigger_virq(dev_id, virq_fd, 0x88);
+		close(virq_fd);
+		test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
 		test_ioctl_destroy(vdev_id);
+		test_ioctl_destroy(virq_id);
 	} else {
 		test_err_vdevice_alloc(ENOENT, viommu_id, dev_id, 0x99, NULL);
 	}
diff --git a/tools/testing/selftests/iommu/iommufd_fail_nth.c b/tools/testing/selftests/iommu/iommufd_fail_nth.c
index 64b1f8e1b0cf..442442de3a75 100644
--- a/tools/testing/selftests/iommu/iommufd_fail_nth.c
+++ b/tools/testing/selftests/iommu/iommufd_fail_nth.c
@@ -620,6 +620,7 @@ TEST_FAIL_NTH(basic_fail_nth, device)
 	};
 	struct iommu_test_hw_info info;
 	uint32_t fault_id, fault_fd;
+	uint32_t virq_id, virq_fd;
 	uint32_t fault_hwpt_id;
 	uint32_t ioas_id;
 	uint32_t ioas_id2;
@@ -692,6 +693,11 @@ TEST_FAIL_NTH(basic_fail_nth, device)
 				 IOMMU_HWPT_DATA_SELFTEST, &data, sizeof(data)))
 		return -1;
 
+	if (_test_cmd_virq_alloc(self->fd, viommu_id, IOMMU_VIRQ_TYPE_SELFTEST,
+				 &virq_id, &virq_fd))
+		return -1;
+	close(virq_fd);
+
 	return 0;
 }
 
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:14 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:14 -0800
Subject: [PATCH v2 09/13] iommufd/selftest: Add IOMMU_TEST_OP_TRIGGER_VIRQ for vIRQ coverage
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <7993411d7634d6bf5e7da4459ca4ee540f59188a.1733263737.git.nicolinc@nvidia.com>

The handler will get vDEVICE object from the given mdev and convert it to
its per-vIOMMU virtual ID to mimic a real IOMMU driver.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/iommufd_test.h | 10 ++++++++++
 drivers/iommu/iommufd/selftest.c     | 30 ++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h
index a6b7a163f636..3037904f2e52 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -24,6 +24,7 @@ enum {
 	IOMMU_TEST_OP_MD_CHECK_IOTLB,
 	IOMMU_TEST_OP_TRIGGER_IOPF,
 	IOMMU_TEST_OP_DEV_CHECK_CACHE,
+	IOMMU_TEST_OP_TRIGGER_VIRQ,
 };
 
 enum {
@@ -145,6 +146,9 @@ struct iommu_test_cmd {
 			__u32 id;
 			__u32 cache;
 		} check_dev_cache;
+		struct {
+			__u32 dev_id;
+		} trigger_virq;
 	};
 	__u32 last;
 };
@@ -212,4 +216,10 @@ struct iommu_viommu_invalidate_selftest {
 	__u32 cache_id;
 };
 
+#define IOMMU_VIRQ_TYPE_SELFTEST 0xbeefbeef
+
+struct iommu_viommu_irq_selftest {
+	__u32 virt_id;
+};
+
 #endif
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index d1438d81e664..0785c9447102 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -1631,6 +1631,34 @@ static int iommufd_test_trigger_iopf(struct iommufd_ucmd *ucmd,
 	return 0;
 }
 
+static int iommufd_test_trigger_virq(struct iommufd_ucmd *ucmd,
+				     struct iommu_test_cmd *cmd)
+{
+	struct iommu_viommu_irq_selftest test = {};
+	struct iommufd_device *idev;
+	struct mock_dev *mdev;
+	int rc = -ENOENT;
+
+	idev = iommufd_get_device(ucmd, cmd->trigger_virq.dev_id);
+	if (IS_ERR(idev))
+		return PTR_ERR(idev);
+	mdev = to_mock_dev(idev->dev);
+
+	down_read(&mdev->viommu_rwsem);
+	if (!mdev->viommu || !mdev->vdev_id)
+		goto out_unlock;
+
+	test.virt_id = mdev->vdev_id;
+	rc = iommufd_viommu_report_irq(&mdev->viommu->core,
+				       IOMMU_VIRQ_TYPE_SELFTEST, &test,
+				       sizeof(test));
+out_unlock:
+	up_read(&mdev->viommu_rwsem);
+	iommufd_put_object(ucmd->ictx, &idev->obj);
+
+	return rc;
+}
+
 void iommufd_selftest_destroy(struct iommufd_object *obj)
 {
 	struct selftest_obj *sobj = to_selftest_obj(obj);
@@ -1712,6 +1740,8 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
 					  cmd->dirty.flags);
 	case IOMMU_TEST_OP_TRIGGER_IOPF:
 		return iommufd_test_trigger_iopf(ucmd, cmd);
+	case IOMMU_TEST_OP_TRIGGER_VIRQ:
+		return iommufd_test_trigger_virq(ucmd, cmd);
 	default:
 		return -EOPNOTSUPP;
 	}
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:17 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:17 -0800
Subject: [PATCH v2 12/13] iommu/arm-smmu-v3: Introduce struct arm_smmu_vmaster
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <6270c905fc8537ffc51f6f2ab2db0601c9f08a8d.1733263737.git.nicolinc@nvidia.com>

Use it to store all vSMMU-related data. The vsid (Virtual Stream ID) will
be the first use case. Then, add a rw_semaphore to protect it.

Also add a pair of arm_smmu_attach_prepare/commit_vmaster helpers and put
them in the existing arm_smmu_attach_prepare/commit(). Note that identity
and blocked ops don't call arm_smmu_attach_prepare/commit(), thus simply
call the new helpers at the top.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   | 23 +++++++++
 .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c     | 49 +++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 32 +++++++++++-
 3 files changed, 103 insertions(+), 1 deletion(-)

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 0107d3f333a1..ec7cff33a0b1 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -789,11 +789,18 @@ struct arm_smmu_stream {
 	struct rb_node			node;
 };
 
+struct arm_smmu_vmaster {
+	struct arm_vsmmu		*vsmmu;
+	unsigned long			vsid;
+};
+
 /* SMMU private data for each master */
 struct arm_smmu_master {
 	struct arm_smmu_device		*smmu;
 	struct device			*dev;
 	struct arm_smmu_stream		*streams;
+	struct arm_smmu_vmaster		*vmaster;
+	struct rw_semaphore		vmaster_rwsem;
 	/* Locked by the iommu core using the group mutex */
 	struct arm_smmu_ctx_desc_cfg	cd_table;
 	unsigned int			num_streams;
@@ -943,6 +950,7 @@ struct arm_smmu_attach_state {
 	bool disable_ats;
 	ioasid_t ssid;
 	/* Resulting state */
+	struct arm_smmu_vmaster *vmaster;
 	bool ats_enabled;
 };
 
@@ -1026,9 +1034,24 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
 				       struct iommu_domain *parent,
 				       struct iommufd_ctx *ictx,
 				       unsigned int viommu_type);
+int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+				    struct iommu_domain *domain);
+void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state);
 #else
 #define arm_smmu_hw_info NULL
 #define arm_vsmmu_alloc NULL
+
+static inline int
+arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+				struct iommu_domain *domain)
+{
+	return 0; /* NOP */
+}
+
+static inline void
+arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
+{
+}
 #endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
 
 #endif /* _ARM_SMMU_V3_H */
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 6cc14d82399f..3a77eca949e6 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -85,6 +85,55 @@ static void arm_smmu_make_nested_domain_ste(
 	}
 }
 
+int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+				    struct iommu_domain *domain)
+{
+	struct arm_smmu_nested_domain *nested_domain;
+	struct arm_smmu_vmaster *vmaster;
+	unsigned long vsid;
+	unsigned int cfg;
+
+	iommu_group_mutex_assert(state->master->dev);
+
+	if (domain->type != IOMMU_DOMAIN_NESTED)
+		return 0;
+	nested_domain = to_smmu_nested_domain(domain);
+
+	/* Skip ABORT/BYPASS or invalid vSTE */
+	cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(nested_domain->ste[0]));
+	if (cfg == STRTAB_STE_0_CFG_ABORT || cfg == STRTAB_STE_0_CFG_BYPASS)
+		return 0;
+	if (!(nested_domain->ste[0] & cpu_to_le64(STRTAB_STE_0_V)))
+		return 0;
+
+	vsid = iommufd_viommu_get_vdev_id(&nested_domain->vsmmu->core,
+					  state->master->dev);
+	/* Fail the attach if vSID is not correct set by the user space */
+	if (!vsid)
+		return -ENOENT;
+
+	vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
+	if (!vmaster)
+		return -ENOMEM;
+	vmaster->vsmmu = nested_domain->vsmmu;
+	vmaster->vsid = vsid;
+	state->vmaster = vmaster;
+
+	return 0;
+}
+
+void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
+{
+	struct arm_smmu_master *master = state->master;
+
+	down_write(&master->vmaster_rwsem);
+	if (state->vmaster != master->vmaster) {
+		kfree(master->vmaster);
+		master->vmaster = state->vmaster;
+	}
+	up_write(&master->vmaster_rwsem);
+}
+
 static int arm_smmu_attach_dev_nested(struct iommu_domain *domain,
 				      struct device *dev)
 {
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 e4ebd9e12ad4..6a6113b36360 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2730,6 +2730,7 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
 	struct arm_smmu_domain *smmu_domain =
 		to_smmu_domain_devices(new_domain);
 	unsigned long flags;
+	int ret;
 
 	/*
 	 * arm_smmu_share_asid() must not see two domains pointing to the same
@@ -2754,9 +2755,15 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
 	}
 
 	if (smmu_domain) {
+		ret = arm_smmu_attach_prepare_vmaster(state, new_domain);
+		if (ret)
+			return ret;
+
 		master_domain = kzalloc(sizeof(*master_domain), GFP_KERNEL);
-		if (!master_domain)
+		if (!master_domain) {
+			kfree(state->vmaster);
 			return -ENOMEM;
+		}
 		master_domain->master = master;
 		master_domain->ssid = state->ssid;
 		if (new_domain->type == IOMMU_DOMAIN_NESTED)
@@ -2783,6 +2790,7 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
 			spin_unlock_irqrestore(&smmu_domain->devices_lock,
 					       flags);
 			kfree(master_domain);
+			kfree(state->vmaster);
 			return -EINVAL;
 		}
 
@@ -2815,6 +2823,8 @@ void arm_smmu_attach_commit(struct arm_smmu_attach_state *state)
 
 	lockdep_assert_held(&arm_smmu_asid_lock);
 
+	arm_smmu_attach_commit_vmaster(state);
+
 	if (state->ats_enabled && !master->ats_enabled) {
 		arm_smmu_enable_ats(master);
 	} else if (state->ats_enabled && master->ats_enabled) {
@@ -3094,8 +3104,17 @@ static void arm_smmu_attach_dev_ste(struct iommu_domain *domain,
 static int arm_smmu_attach_dev_identity(struct iommu_domain *domain,
 					struct device *dev)
 {
+	int ret;
 	struct arm_smmu_ste ste;
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct arm_smmu_attach_state state = {
+		.master = master,
+	};
+
+	ret = arm_smmu_attach_prepare_vmaster(&state, domain);
+	if (ret)
+		return ret;
+	arm_smmu_attach_commit_vmaster(&state);
 
 	arm_smmu_make_bypass_ste(master->smmu, &ste);
 	arm_smmu_attach_dev_ste(domain, dev, &ste, STRTAB_STE_1_S1DSS_BYPASS);
@@ -3114,7 +3133,17 @@ static struct iommu_domain arm_smmu_identity_domain = {
 static int arm_smmu_attach_dev_blocked(struct iommu_domain *domain,
 					struct device *dev)
 {
+	int ret;
 	struct arm_smmu_ste ste;
+	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct arm_smmu_attach_state state = {
+		.master = master,
+	};
+
+	ret = arm_smmu_attach_prepare_vmaster(&state, domain);
+	if (ret)
+		return ret;
+	arm_smmu_attach_commit_vmaster(&state);
 
 	arm_smmu_make_abort_ste(&ste);
 	arm_smmu_attach_dev_ste(domain, dev, &ste,
@@ -3345,6 +3374,7 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 	master->dev = dev;
 	master->smmu = smmu;
+	init_rwsem(&master->vmaster_rwsem);
 	dev_iommu_priv_set(dev, master);
 
 	ret = arm_smmu_insert_master(smmu, master);
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:16 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:16 -0800
Subject: [PATCH v2 11/13] Documentation: userspace-api: iommufd: Update EVENTQ_IOPF and EVENTQ_VIRQ
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <a5025cbbd16f9c12dcaae7a14868419f17ce1d16.1733263737.git.nicolinc@nvidia.com>

With the introduction of the new objects, update the doc to reflect that.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 Documentation/userspace-api/iommufd.rst | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/userspace-api/iommufd.rst b/Documentation/userspace-api/iommufd.rst
index 70289d6815d2..798520d9344d 100644
--- a/Documentation/userspace-api/iommufd.rst
+++ b/Documentation/userspace-api/iommufd.rst
@@ -63,6 +63,14 @@ Following IOMMUFD objects are exposed to userspace:
   space usually has mappings from guest-level I/O virtual addresses to guest-
   level physical addresses.
 
+- IOMMUFD_OBJ_EVENTQ_IOPF, representing a software queue for an HWPT_NESTED
+  reporting IO Page Fault using the IOMMU HW's PRI (Page Request Interface).
+  This queue object provides user space an FD to poll the page fault events
+  and also to respond to those events. An EVENTQ_IOPF object must be created
+  first to get a fault_id that could be then used to allocate an HWPT_NESTED
+  via the IOMMU_HWPT_ALLOC command setting IOMMU_HWPT_FAULT_ID_VALID set in
+  its flags field.
+
 - IOMMUFD_OBJ_VIOMMU, representing a slice of the physical IOMMU instance,
   passed to or shared with a VM. It may be some HW-accelerated virtualization
   features and some SW resources used by the VM. For examples:
@@ -109,6 +117,15 @@ Following IOMMUFD objects are exposed to userspace:
   vIOMMU, which is a separate ioctl call from attaching the same device to an
   HWPT_PAGING that the vIOMMU holds.
 
+- IOMMUFD_OBJ_EVENTQ_VIRQ, representing a software queue for IOMMUFD_OBJ_VIOMMU
+  reporting its non-affiliated events, such as translation faults occurred to a
+  nested stage-1 and HW-specific events/irqs e.g. events to invalidation queues
+  that are assigned to VMs via vIOMMUs. This queue object provides user space an
+  FD to poll the vIOMMU events. A vIOMMU object must be created first to get its
+  viommu_id that could be then used to allocate an EVENTQ_VIRQ. Each vIOMMU can
+  support multiple types of EVENTQ_VIRQs, but is confined to one EVENTQ_VIRQ per
+  vIRQ type.
+
 All user-visible objects are destroyed via the IOMMU_DESTROY uAPI.
 
 The diagrams below show relationships between user-visible objects and kernel
@@ -251,8 +268,10 @@ User visible objects are backed by following datastructures:
 - iommufd_device for IOMMUFD_OBJ_DEVICE.
 - iommufd_hwpt_paging for IOMMUFD_OBJ_HWPT_PAGING.
 - iommufd_hwpt_nested for IOMMUFD_OBJ_HWPT_NESTED.
+- iommufd_eventq_iopf for IOMMUFD_OBJ_EVENTQ_IOPF.
 - iommufd_viommu for IOMMUFD_OBJ_VIOMMU.
 - iommufd_vdevice for IOMMUFD_OBJ_VDEVICE.
+- iommufd_eventq_virq for IOMMUFD_OBJ_EVENTQ_VIRQ.
 
 Several terminologies when looking at these datastructures:
 
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:11 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:11 -0800
Subject: [PATCH v2 06/13] iommufd/viommu: Add iommufd_viommu_get_vdev_id helper
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <d1e5f16d2fa4e9950e9caa93c5f98a5115c1580f.1733263737.git.nicolinc@nvidia.com>

This is a reverse search v.s. iommufd_viommu_find_dev, as drivers may want
to convert a struct device pointer (physical) to its virtual device ID for
an event injection to the user space VM.

Again, this avoids exposing more core structures to the drivers, than the
iommufd_viommu alone.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 include/linux/iommufd.h        |  8 ++++++++
 drivers/iommu/iommufd/driver.c | 18 ++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 40cc9bbb1d24..1f5376476cfa 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -190,6 +190,8 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
 					     enum iommufd_object_type type);
 struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 				       unsigned long vdev_id);
+unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
+					 struct device *dev);
 #else /* !CONFIG_IOMMUFD_DRIVER_CORE */
 static inline struct iommufd_object *
 _iommufd_object_alloc(struct iommufd_ctx *ictx, size_t size,
@@ -203,6 +205,12 @@ iommufd_viommu_find_dev(struct iommufd_viommu *viommu, unsigned long vdev_id)
 {
 	return NULL;
 }
+
+static inline unsigned long
+iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu, struct device *dev)
+{
+	return 0;
+}
 #endif /* CONFIG_IOMMUFD_DRIVER_CORE */
 
 /*
diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c
index 7b67fdf44134..817e430a11bc 100644
--- a/drivers/iommu/iommufd/driver.c
+++ b/drivers/iommu/iommufd/driver.c
@@ -49,5 +49,23 @@ struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_viommu_find_dev, IOMMUFD);
 
+/* Return 0 if device is not associated to the vIOMMU */
+unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
+					 struct device *dev)
+{
+	struct iommufd_vdevice *vdev;
+	unsigned long vdev_id = 0;
+	unsigned long index;
+
+	xa_lock(&viommu->vdevs);
+	xa_for_each(&viommu->vdevs, index, vdev) {
+		if (vdev && vdev->dev == dev)
+			vdev_id = (unsigned long)vdev->id;
+	}
+	xa_unlock(&viommu->vdevs);
+	return vdev_id;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_viommu_get_vdev_id, IOMMUFD);
+
 MODULE_DESCRIPTION("iommufd code shared with builtin modules");
 MODULE_LICENSE("GPL");
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:09 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:09 -0800
Subject: [PATCH v2 04/13] iommufd: Rename fault.c to eventq.c
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <9e37e420e46844d5a10b055e512e7d94f1446a0b.1733263737.git.nicolinc@nvidia.com>

Rename the file, aligning with the new eventq object.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/Makefile              | 2 +-
 drivers/iommu/iommufd/{fault.c => eventq.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/iommu/iommufd/{fault.c => eventq.c} (100%)

diff --git a/drivers/iommu/iommufd/Makefile b/drivers/iommu/iommufd/Makefile
index cb784da6cddc..71d692c9a8f4 100644
--- a/drivers/iommu/iommufd/Makefile
+++ b/drivers/iommu/iommufd/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 iommufd-y := \
 	device.o \
-	fault.o \
+	eventq.o \
 	hw_pagetable.o \
 	io_pagetable.o \
 	ioas.o \
diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/eventq.c
similarity index 100%
rename from drivers/iommu/iommufd/fault.c
rename to drivers/iommu/iommufd/eventq.c
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:08 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:08 -0800
Subject: [PATCH v2 03/13] iommufd: Rename IOMMUFD_OBJ_FAULT to IOMMUFD_OBJ_EVENTQ_IOPF
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <2e2dc5c9cd8013147d4a8ee0d6c9d59c9ebe1954.1733263737.git.nicolinc@nvidia.com>

The fault object was designed exclusively for hwpt's IO page faults (PRI).
But its implementation can actually be reused for other purposes too, such
as hardware IRQ and event injections to user space.

Meanwhile, a fault object holds a list of faults. So it's more accurate to
call it a "fault queue". Combining the reusing idea above, a "fault queue"
can further rephrase to an "Event Queue for IOPF".

Rename the struct iommufd_fault to struct iommufd_eventq_iopf that holds a
common Event Queue struct, similar to hwpt_paging holding a common hwpt.

Roll out a minimal level of renamings to all the related functions.

Add a common iommufd_eventq_ops and iommufd_eventq_init to prepare for an
IOMMUFD_OBJ_EVENTQ_VIRQ. Also, add missing xa_destroy and mutex_destroy in
iommufd_fault_destroy().

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/iommufd_private.h |  87 ++++++----
 include/linux/iommufd.h                 |   2 +-
 drivers/iommu/iommufd/fault.c           | 221 ++++++++++++++----------
 drivers/iommu/iommufd/hw_pagetable.c    |  12 +-
 drivers/iommu/iommufd/main.c            |   8 +-
 5 files changed, 195 insertions(+), 135 deletions(-)

diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index 8b378705ee71..1c9a101cc435 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -18,6 +18,8 @@ struct iommu_domain;
 struct iommu_group;
 struct iommu_option;
 struct iommufd_device;
+struct iommufd_eventq;
+struct iommufd_eventq_iopf;
 
 struct iommufd_ctx {
 	struct file *file;
@@ -275,7 +277,7 @@ int iommufd_check_iova_range(struct io_pagetable *iopt,
 struct iommufd_hw_pagetable {
 	struct iommufd_object obj;
 	struct iommu_domain *domain;
-	struct iommufd_fault *fault;
+	struct iommufd_eventq_iopf *fault;
 };
 
 struct iommufd_hwpt_paging {
@@ -433,32 +435,35 @@ void iopt_remove_access(struct io_pagetable *iopt,
 			u32 iopt_access_list_id);
 void iommufd_access_destroy_object(struct iommufd_object *obj);
 
-/*
- * An iommufd_fault object represents an interface to deliver I/O page faults
- * to the user space. These objects are created/destroyed by the user space and
- * associated with hardware page table objects during page-table allocation.
- */
-struct iommufd_fault {
+struct iommufd_eventq_ops {
+	ssize_t (*read)(struct iommufd_eventq *eventq, char __user *buf,
+			size_t count, loff_t *ppos);
+	ssize_t (*write)(struct iommufd_eventq *eventq, const char __user *buf,
+			 size_t count, loff_t *ppos);
+};
+
+struct iommufd_eventq {
 	struct iommufd_object obj;
 	struct iommufd_ctx *ictx;
 	struct file *filep;
 
-	/* The lists of outstanding faults protected by below mutex. */
+	const struct iommufd_eventq_ops *ops;
+
+	/* The lists of outstanding events protected by below mutex. */
 	struct mutex mutex;
 	struct list_head deliver;
-	struct xarray response;
 
 	struct wait_queue_head wait_queue;
 };
 
-static inline int iommufd_fault_notify(struct iommufd_fault *fault,
-				       struct list_head *new_fault)
+static inline int iommufd_eventq_notify(struct iommufd_eventq *eventq,
+					struct list_head *new_event)
 {
-	mutex_lock(&fault->mutex);
-	list_add_tail(new_fault, &fault->deliver);
-	mutex_unlock(&fault->mutex);
+	mutex_lock(&eventq->mutex);
+	list_add_tail(new_event, &eventq->deliver);
+	mutex_unlock(&eventq->mutex);
 
-	wake_up_interruptible(&fault->wait_queue);
+	wake_up_interruptible(&eventq->wait_queue);
 	return 0;
 }
 
@@ -470,38 +475,54 @@ struct iommufd_attach_handle {
 /* Convert an iommu attach handle to iommufd handle. */
 #define to_iommufd_handle(hdl)	container_of(hdl, struct iommufd_attach_handle, handle)
 
-static inline struct iommufd_fault *
-iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id)
+/*
+ * An iommufd_eventq_iopf object represents a queue to deliver I/O page faults
+ * to the user space. These objects are created/destroyed by the user space and
+ * associated with hardware page table objects during page-table allocation.
+ */
+struct iommufd_eventq_iopf {
+	struct iommufd_eventq common;
+	struct xarray response;
+};
+
+static inline struct iommufd_eventq_iopf *
+to_eventq_iopf(struct iommufd_eventq *eventq)
+{
+	return container_of(eventq, struct iommufd_eventq_iopf, common);
+}
+
+static inline struct iommufd_eventq_iopf *
+iommufd_get_eventq_iopf(struct iommufd_ucmd *ucmd, u32 id)
 {
 	return container_of(iommufd_get_object(ucmd->ictx, id,
-					       IOMMUFD_OBJ_FAULT),
-			    struct iommufd_fault, obj);
+					       IOMMUFD_OBJ_EVENTQ_IOPF),
+			    struct iommufd_eventq_iopf, common.obj);
 }
 
-int iommufd_fault_alloc(struct iommufd_ucmd *ucmd);
-void iommufd_fault_destroy(struct iommufd_object *obj);
+int iommufd_eventq_iopf_alloc(struct iommufd_ucmd *ucmd);
+void iommufd_eventq_iopf_destroy(struct iommufd_object *obj);
 
-static inline int iommufd_fault_iopf_handler(struct iopf_group *group)
+static inline int iommufd_eventq_iopf_handler(struct iopf_group *group)
 {
 	struct iommufd_hw_pagetable *hwpt =
 		group->attach_handle->domain->fault_data;
 
-	return iommufd_fault_notify(hwpt->fault, &group->node);
+	return iommufd_eventq_notify(&hwpt->fault->common, &group->node);
 }
 
-int iommufd_fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
-				    struct iommufd_device *idev);
-void iommufd_fault_domain_detach_dev(struct iommufd_hw_pagetable *hwpt,
-				     struct iommufd_device *idev);
-int iommufd_fault_domain_replace_dev(struct iommufd_device *idev,
-				     struct iommufd_hw_pagetable *hwpt,
-				     struct iommufd_hw_pagetable *old);
+int iommufd_eventq_iopf_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
+					  struct iommufd_device *idev);
+void iommufd_eventq_iopf_domain_detach_dev(struct iommufd_hw_pagetable *hwpt,
+					   struct iommufd_device *idev);
+int iommufd_eventq_iopf_domain_replace_dev(struct iommufd_device *idev,
+					   struct iommufd_hw_pagetable *hwpt,
+					   struct iommufd_hw_pagetable *old);
 
 static inline int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
 					     struct iommufd_device *idev)
 {
 	if (hwpt->fault)
-		return iommufd_fault_domain_attach_dev(hwpt, idev);
+		return iommufd_eventq_iopf_domain_attach_dev(hwpt, idev);
 
 	return iommu_attach_group(hwpt->domain, idev->igroup->group);
 }
@@ -510,7 +531,7 @@ static inline void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
 					      struct iommufd_device *idev)
 {
 	if (hwpt->fault) {
-		iommufd_fault_domain_detach_dev(hwpt, idev);
+		iommufd_eventq_iopf_domain_detach_dev(hwpt, idev);
 		return;
 	}
 
@@ -522,7 +543,7 @@ static inline int iommufd_hwpt_replace_device(struct iommufd_device *idev,
 					      struct iommufd_hw_pagetable *old)
 {
 	if (old->fault || hwpt->fault)
-		return iommufd_fault_domain_replace_dev(idev, hwpt, old);
+		return iommufd_eventq_iopf_domain_replace_dev(idev, hwpt, old);
 
 	return iommu_group_replace_domain(idev->igroup->group, hwpt->domain);
 }
diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 11110c749200..7ad105ab8090 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -31,7 +31,7 @@ enum iommufd_object_type {
 	IOMMUFD_OBJ_HWPT_NESTED,
 	IOMMUFD_OBJ_IOAS,
 	IOMMUFD_OBJ_ACCESS,
-	IOMMUFD_OBJ_FAULT,
+	IOMMUFD_OBJ_EVENTQ_IOPF,
 	IOMMUFD_OBJ_VIOMMU,
 	IOMMUFD_OBJ_VDEVICE,
 #ifdef CONFIG_IOMMUFD_TEST
diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
index 5694b04a48bd..3674961a45c2 100644
--- a/drivers/iommu/iommufd/fault.c
+++ b/drivers/iommu/iommufd/fault.c
@@ -17,7 +17,9 @@
 #include "../iommu-priv.h"
 #include "iommufd_private.h"
 
-static int iommufd_fault_iopf_enable(struct iommufd_device *idev)
+/* IOMMUFD_OBJ_EVENTQ_IOPF Functions */
+
+static int iommufd_eventq_iopf_enable(struct iommufd_device *idev)
 {
 	struct device *dev = idev->dev;
 	int ret;
@@ -50,7 +52,7 @@ static int iommufd_fault_iopf_enable(struct iommufd_device *idev)
 	return ret;
 }
 
-static void iommufd_fault_iopf_disable(struct iommufd_device *idev)
+static void iommufd_eventq_iopf_disable(struct iommufd_device *idev)
 {
 	mutex_lock(&idev->iopf_lock);
 	if (!WARN_ON(idev->iopf_enabled == 0)) {
@@ -60,8 +62,8 @@ static void iommufd_fault_iopf_disable(struct iommufd_device *idev)
 	mutex_unlock(&idev->iopf_lock);
 }
 
-static int __fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
-				     struct iommufd_device *idev)
+static int __eventq_iopf_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
+					   struct iommufd_device *idev)
 {
 	struct iommufd_attach_handle *handle;
 	int ret;
@@ -79,37 +81,38 @@ static int __fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
 	return ret;
 }
 
-int iommufd_fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
-				    struct iommufd_device *idev)
+int iommufd_eventq_iopf_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
+					  struct iommufd_device *idev)
 {
 	int ret;
 
 	if (!hwpt->fault)
 		return -EINVAL;
 
-	ret = iommufd_fault_iopf_enable(idev);
+	ret = iommufd_eventq_iopf_enable(idev);
 	if (ret)
 		return ret;
 
-	ret = __fault_domain_attach_dev(hwpt, idev);
+	ret = __eventq_iopf_domain_attach_dev(hwpt, idev);
 	if (ret)
-		iommufd_fault_iopf_disable(idev);
+		iommufd_eventq_iopf_disable(idev);
 
 	return ret;
 }
 
-static void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
-					 struct iommufd_attach_handle *handle)
+static void
+iommufd_eventq_iopf_auto_response(struct iommufd_hw_pagetable *hwpt,
+				  struct iommufd_attach_handle *handle)
 {
-	struct iommufd_fault *fault = hwpt->fault;
+	struct iommufd_eventq_iopf *fault = hwpt->fault;
 	struct iopf_group *group, *next;
 	unsigned long index;
 
 	if (!fault)
 		return;
 
-	mutex_lock(&fault->mutex);
-	list_for_each_entry_safe(group, next, &fault->deliver, node) {
+	mutex_lock(&fault->common.mutex);
+	list_for_each_entry_safe(group, next, &fault->common.deliver, node) {
 		if (group->attach_handle != &handle->handle)
 			continue;
 		list_del(&group->node);
@@ -124,7 +127,7 @@ static void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
 		iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
 		iopf_free_group(group);
 	}
-	mutex_unlock(&fault->mutex);
+	mutex_unlock(&fault->common.mutex);
 }
 
 static struct iommufd_attach_handle *
@@ -139,21 +142,21 @@ iommufd_device_get_attach_handle(struct iommufd_device *idev)
 	return to_iommufd_handle(handle);
 }
 
-void iommufd_fault_domain_detach_dev(struct iommufd_hw_pagetable *hwpt,
-				     struct iommufd_device *idev)
+void iommufd_eventq_iopf_domain_detach_dev(struct iommufd_hw_pagetable *hwpt,
+					   struct iommufd_device *idev)
 {
 	struct iommufd_attach_handle *handle;
 
 	handle = iommufd_device_get_attach_handle(idev);
 	iommu_detach_group_handle(hwpt->domain, idev->igroup->group);
-	iommufd_auto_response_faults(hwpt, handle);
-	iommufd_fault_iopf_disable(idev);
+	iommufd_eventq_iopf_auto_response(hwpt, handle);
+	iommufd_eventq_iopf_disable(idev);
 	kfree(handle);
 }
 
-static int __fault_domain_replace_dev(struct iommufd_device *idev,
-				      struct iommufd_hw_pagetable *hwpt,
-				      struct iommufd_hw_pagetable *old)
+static int __eventq_iopf_domain_replace_dev(struct iommufd_device *idev,
+					    struct iommufd_hw_pagetable *hwpt,
+					    struct iommufd_hw_pagetable *old)
 {
 	struct iommufd_attach_handle *handle, *curr = NULL;
 	int ret;
@@ -175,43 +178,44 @@ static int __fault_domain_replace_dev(struct iommufd_device *idev,
 	}
 
 	if (!ret && curr) {
-		iommufd_auto_response_faults(old, curr);
+		iommufd_eventq_iopf_auto_response(old, curr);
 		kfree(curr);
 	}
 
 	return ret;
 }
 
-int iommufd_fault_domain_replace_dev(struct iommufd_device *idev,
-				     struct iommufd_hw_pagetable *hwpt,
-				     struct iommufd_hw_pagetable *old)
+int iommufd_eventq_iopf_domain_replace_dev(struct iommufd_device *idev,
+					   struct iommufd_hw_pagetable *hwpt,
+					   struct iommufd_hw_pagetable *old)
 {
 	bool iopf_off = !hwpt->fault && old->fault;
 	bool iopf_on = hwpt->fault && !old->fault;
 	int ret;
 
 	if (iopf_on) {
-		ret = iommufd_fault_iopf_enable(idev);
+		ret = iommufd_eventq_iopf_enable(idev);
 		if (ret)
 			return ret;
 	}
 
-	ret = __fault_domain_replace_dev(idev, hwpt, old);
+	ret = __eventq_iopf_domain_replace_dev(idev, hwpt, old);
 	if (ret) {
 		if (iopf_on)
-			iommufd_fault_iopf_disable(idev);
+			iommufd_eventq_iopf_disable(idev);
 		return ret;
 	}
 
 	if (iopf_off)
-		iommufd_fault_iopf_disable(idev);
+		iommufd_eventq_iopf_disable(idev);
 
 	return 0;
 }
 
-void iommufd_fault_destroy(struct iommufd_object *obj)
+void iommufd_eventq_iopf_destroy(struct iommufd_object *obj)
 {
-	struct iommufd_fault *fault = container_of(obj, struct iommufd_fault, obj);
+	struct iommufd_eventq *eventq =
+		container_of(obj, struct iommufd_eventq, obj);
 	struct iopf_group *group, *next;
 
 	/*
@@ -220,17 +224,19 @@ void iommufd_fault_destroy(struct iommufd_object *obj)
 	 * accessing this pointer. Therefore, acquiring the mutex here
 	 * is unnecessary.
 	 */
-	list_for_each_entry_safe(group, next, &fault->deliver, node) {
+	list_for_each_entry_safe(group, next, &eventq->deliver, node) {
 		list_del(&group->node);
 		iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
 		iopf_free_group(group);
 	}
+	xa_destroy(&to_eventq_iopf(eventq)->response);
+	mutex_destroy(&eventq->mutex);
 }
 
-static void iommufd_compose_fault_message(struct iommu_fault *fault,
-					  struct iommu_hwpt_pgfault *hwpt_fault,
-					  struct iommufd_device *idev,
-					  u32 cookie)
+static void iommufd_compose_iopf_message(struct iommu_fault *fault,
+					 struct iommu_hwpt_pgfault *hwpt_fault,
+					 struct iommufd_device *idev,
+					 u32 cookie)
 {
 	hwpt_fault->flags = fault->prm.flags;
 	hwpt_fault->dev_id = idev->obj.id;
@@ -242,11 +248,12 @@ static void iommufd_compose_fault_message(struct iommu_fault *fault,
 	hwpt_fault->cookie = cookie;
 }
 
-static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
-				       size_t count, loff_t *ppos)
+static ssize_t iommufd_eventq_iopf_fops_read(struct iommufd_eventq *eventq,
+					     char __user *buf, size_t count,
+					     loff_t *ppos)
 {
+	struct iommufd_eventq_iopf *fault = to_eventq_iopf(eventq);
 	size_t fault_size = sizeof(struct iommu_hwpt_pgfault);
-	struct iommufd_fault *fault = filep->private_data;
 	struct iommu_hwpt_pgfault data;
 	struct iommufd_device *idev;
 	struct iopf_group *group;
@@ -257,10 +264,10 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
 	if (*ppos || count % fault_size)
 		return -ESPIPE;
 
-	mutex_lock(&fault->mutex);
-	while (!list_empty(&fault->deliver) && count > done) {
-		group = list_first_entry(&fault->deliver,
-					 struct iopf_group, node);
+	mutex_lock(&eventq->mutex);
+	while (!list_empty(&eventq->deliver) && count > done) {
+		group = list_first_entry(&eventq->deliver, struct iopf_group,
+					 node);
 
 		if (group->fault_count * fault_size > count - done)
 			break;
@@ -272,9 +279,8 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
 
 		idev = to_iommufd_handle(group->attach_handle)->idev;
 		list_for_each_entry(iopf, &group->faults, list) {
-			iommufd_compose_fault_message(&iopf->fault,
-						      &data, idev,
-						      group->cookie);
+			iommufd_compose_iopf_message(&iopf->fault, &data, idev,
+						     group->cookie);
 			if (copy_to_user(buf + done, &data, fault_size)) {
 				xa_erase(&fault->response, group->cookie);
 				rc = -EFAULT;
@@ -285,16 +291,17 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
 
 		list_del(&group->node);
 	}
-	mutex_unlock(&fault->mutex);
+	mutex_unlock(&eventq->mutex);
 
 	return done == 0 ? rc : done;
 }
 
-static ssize_t iommufd_fault_fops_write(struct file *filep, const char __user *buf,
-					size_t count, loff_t *ppos)
+static ssize_t iommufd_eventq_iopf_fops_write(struct iommufd_eventq *eventq,
+					      const char __user *buf,
+					      size_t count, loff_t *ppos)
 {
 	size_t response_size = sizeof(struct iommu_hwpt_page_response);
-	struct iommufd_fault *fault = filep->private_data;
+	struct iommufd_eventq_iopf *fault = to_eventq_iopf(eventq);
 	struct iommu_hwpt_page_response response;
 	struct iopf_group *group;
 	size_t done = 0;
@@ -303,7 +310,7 @@ static ssize_t iommufd_fault_fops_write(struct file *filep, const char __user *b
 	if (*ppos || count % response_size)
 		return -ESPIPE;
 
-	mutex_lock(&fault->mutex);
+	mutex_lock(&eventq->mutex);
 	while (count > done) {
 		rc = copy_from_user(&response, buf + done, response_size);
 		if (rc)
@@ -329,62 +336,92 @@ static ssize_t iommufd_fault_fops_write(struct file *filep, const char __user *b
 		iopf_free_group(group);
 		done += response_size;
 	}
-	mutex_unlock(&fault->mutex);
+	mutex_unlock(&eventq->mutex);
 
 	return done == 0 ? rc : done;
 }
 
-static __poll_t iommufd_fault_fops_poll(struct file *filep,
-					struct poll_table_struct *wait)
+static const struct iommufd_eventq_ops iommufd_eventq_iopf_ops = {
+	.read = &iommufd_eventq_iopf_fops_read,
+	.write = &iommufd_eventq_iopf_fops_write,
+};
+
+/* Common Event Queue Functions */
+
+static ssize_t iommufd_eventq_fops_read(struct file *filep, char __user *buf,
+					size_t count, loff_t *ppos)
+{
+	struct iommufd_eventq *eventq = filep->private_data;
+
+	if (!eventq->ops || !eventq->ops->read)
+		return -EOPNOTSUPP;
+	return eventq->ops->read(eventq, buf, count, ppos);
+}
+
+static ssize_t iommufd_eventq_fops_write(struct file *filep,
+					 const char __user *buf, size_t count,
+					 loff_t *ppos)
+{
+	struct iommufd_eventq *eventq = filep->private_data;
+
+	if (!eventq->ops || !eventq->ops->write)
+		return -EOPNOTSUPP;
+	return eventq->ops->write(eventq, buf, count, ppos);
+}
+
+static __poll_t iommufd_eventq_fops_poll(struct file *filep,
+					 struct poll_table_struct *wait)
 {
-	struct iommufd_fault *fault = filep->private_data;
+	struct iommufd_eventq *eventq = filep->private_data;
 	__poll_t pollflags = EPOLLOUT;
 
-	poll_wait(filep, &fault->wait_queue, wait);
-	mutex_lock(&fault->mutex);
-	if (!list_empty(&fault->deliver))
+	poll_wait(filep, &eventq->wait_queue, wait);
+	mutex_lock(&eventq->mutex);
+	if (!list_empty(&eventq->deliver))
 		pollflags |= EPOLLIN | EPOLLRDNORM;
-	mutex_unlock(&fault->mutex);
+	mutex_unlock(&eventq->mutex);
 
 	return pollflags;
 }
 
-static int iommufd_fault_fops_release(struct inode *inode, struct file *filep)
+static int iommufd_eventq_fops_release(struct inode *inode, struct file *filep)
 {
-	struct iommufd_fault *fault = filep->private_data;
+	struct iommufd_eventq *eventq = filep->private_data;
 
-	refcount_dec(&fault->obj.users);
-	iommufd_ctx_put(fault->ictx);
+	refcount_dec(&eventq->obj.users);
+	iommufd_ctx_put(eventq->ictx);
 	return 0;
 }
 
-static const struct file_operations iommufd_fault_fops = {
+static const struct file_operations iommufd_eventq_fops = {
 	.owner		= THIS_MODULE,
 	.open		= nonseekable_open,
-	.read		= iommufd_fault_fops_read,
-	.write		= iommufd_fault_fops_write,
-	.poll		= iommufd_fault_fops_poll,
-	.release	= iommufd_fault_fops_release,
+	.read		= iommufd_eventq_fops_read,
+	.write		= iommufd_eventq_fops_write,
+	.poll		= iommufd_eventq_fops_poll,
+	.release	= iommufd_eventq_fops_release,
 };
 
-static int iommufd_fault_init(struct iommufd_fault *fault, char *name,
-			      struct iommufd_ctx *ictx)
+static int iommufd_eventq_init(struct iommufd_eventq *eventq, char *name,
+			       struct iommufd_ctx *ictx,
+			       const struct iommufd_eventq_ops *ops)
 {
 	struct file *filep;
 	int fdno;
 
-	fault->ictx = ictx;
-	mutex_init(&fault->mutex);
-	INIT_LIST_HEAD(&fault->deliver);
-	init_waitqueue_head(&fault->wait_queue);
+	eventq->ops = ops;
+	eventq->ictx = ictx;
+	mutex_init(&eventq->mutex);
+	INIT_LIST_HEAD(&eventq->deliver);
+	init_waitqueue_head(&eventq->wait_queue);
 
-	filep = anon_inode_getfile(name, &iommufd_fault_fops, fault, O_RDWR);
+	filep = anon_inode_getfile(name, &iommufd_eventq_fops, eventq, O_RDWR);
 	if (IS_ERR(filep))
 		return PTR_ERR(filep);
 
-	fault->filep = filep;
-	iommufd_ctx_get(fault->ictx);
-	refcount_inc(&fault->obj.users);
+	eventq->filep = filep;
+	iommufd_ctx_get(eventq->ictx);
+	refcount_inc(&eventq->obj.users);
 
 	fdno = get_unused_fd_flags(O_CLOEXEC);
 	if (fdno < 0)
@@ -392,44 +429,46 @@ static int iommufd_fault_init(struct iommufd_fault *fault, char *name,
 	return fdno;
 }
 
-int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
+int iommufd_eventq_iopf_alloc(struct iommufd_ucmd *ucmd)
 {
 	struct iommu_fault_alloc *cmd = ucmd->cmd;
-	struct iommufd_fault *fault;
+	struct iommufd_eventq_iopf *eventq_iopf;
 	int fdno;
 	int rc;
 
 	if (cmd->flags)
 		return -EOPNOTSUPP;
 
-	fault = iommufd_object_alloc(ucmd->ictx, fault, IOMMUFD_OBJ_FAULT);
-	if (IS_ERR(fault))
-		return PTR_ERR(fault);
+	eventq_iopf = __iommufd_object_alloc(
+		ucmd->ictx, eventq_iopf, IOMMUFD_OBJ_EVENTQ_IOPF, common.obj);
+	if (IS_ERR(eventq_iopf))
+		return PTR_ERR(eventq_iopf);
 
-	xa_init_flags(&fault->response, XA_FLAGS_ALLOC1);
+	xa_init_flags(&eventq_iopf->response, XA_FLAGS_ALLOC1);
 
-	fdno = iommufd_fault_init(fault, "[iommufd-pgfault]", ucmd->ictx);
+	fdno = iommufd_eventq_init(&eventq_iopf->common, "[iommufd-pgfault]",
+				   ucmd->ictx, &iommufd_eventq_iopf_ops);
 	if (fdno < 0) {
 		rc = fdno;
 		goto out_abort;
 	}
 
-	cmd->out_fault_id = fault->obj.id;
+	cmd->out_fault_id = eventq_iopf->common.obj.id;
 	cmd->out_fault_fd = fdno;
 
 	rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
 	if (rc)
 		goto out_put_fdno;
-	iommufd_object_finalize(ucmd->ictx, &fault->obj);
+	iommufd_object_finalize(ucmd->ictx, &eventq_iopf->common.obj);
 
-	fd_install(fdno, fault->filep);
+	fd_install(fdno, eventq_iopf->common.filep);
 
 	return 0;
 out_put_fdno:
 	put_unused_fd(fdno);
-	fput(fault->filep);
+	fput(eventq_iopf->common.filep);
 out_abort:
-	iommufd_object_abort_and_destroy(ucmd->ictx, &fault->obj);
+	iommufd_object_abort_and_destroy(ucmd->ictx, &eventq_iopf->common.obj);
 
 	return rc;
 }
diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c
index ce03c3804651..a89d9018f96b 100644
--- a/drivers/iommu/iommufd/hw_pagetable.c
+++ b/drivers/iommu/iommufd/hw_pagetable.c
@@ -14,7 +14,7 @@ static void __iommufd_hwpt_destroy(struct iommufd_hw_pagetable *hwpt)
 		iommu_domain_free(hwpt->domain);
 
 	if (hwpt->fault)
-		refcount_dec(&hwpt->fault->obj.users);
+		refcount_dec(&hwpt->fault->common.obj.users);
 }
 
 void iommufd_hwpt_paging_destroy(struct iommufd_object *obj)
@@ -393,18 +393,18 @@ int iommufd_hwpt_alloc(struct iommufd_ucmd *ucmd)
 	}
 
 	if (cmd->flags & IOMMU_HWPT_FAULT_ID_VALID) {
-		struct iommufd_fault *fault;
+		struct iommufd_eventq_iopf *fault;
 
-		fault = iommufd_get_fault(ucmd, cmd->fault_id);
+		fault = iommufd_get_eventq_iopf(ucmd, cmd->fault_id);
 		if (IS_ERR(fault)) {
 			rc = PTR_ERR(fault);
 			goto out_hwpt;
 		}
 		hwpt->fault = fault;
-		hwpt->domain->iopf_handler = iommufd_fault_iopf_handler;
+		hwpt->domain->iopf_handler = iommufd_eventq_iopf_handler;
 		hwpt->domain->fault_data = hwpt;
-		refcount_inc(&fault->obj.users);
-		iommufd_put_object(ucmd->ictx, &fault->obj);
+		refcount_inc(&fault->common.obj.users);
+		iommufd_put_object(ucmd->ictx, &fault->common.obj);
 	}
 
 	cmd->out_hwpt_id = hwpt->obj.id;
diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index 0a96cc8f27da..539c24ada6d0 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -333,8 +333,8 @@ struct iommufd_ioctl_op {
 	}
 static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = {
 	IOCTL_OP(IOMMU_DESTROY, iommufd_destroy, struct iommu_destroy, id),
-	IOCTL_OP(IOMMU_FAULT_QUEUE_ALLOC, iommufd_fault_alloc, struct iommu_fault_alloc,
-		 out_fault_fd),
+	IOCTL_OP(IOMMU_FAULT_QUEUE_ALLOC, iommufd_eventq_iopf_alloc,
+		 struct iommu_fault_alloc, out_fault_fd),
 	IOCTL_OP(IOMMU_GET_HW_INFO, iommufd_get_hw_info, struct iommu_hw_info,
 		 __reserved),
 	IOCTL_OP(IOMMU_HWPT_ALLOC, iommufd_hwpt_alloc, struct iommu_hwpt_alloc,
@@ -501,8 +501,8 @@ static const struct iommufd_object_ops iommufd_object_ops[] = {
 		.destroy = iommufd_hwpt_nested_destroy,
 		.abort = iommufd_hwpt_nested_abort,
 	},
-	[IOMMUFD_OBJ_FAULT] = {
-		.destroy = iommufd_fault_destroy,
+	[IOMMUFD_OBJ_EVENTQ_IOPF] = {
+		.destroy = iommufd_eventq_iopf_destroy,
 	},
 	[IOMMUFD_OBJ_VIOMMU] = {
 		.destroy = iommufd_viommu_destroy,
-- 
2.43.0



From vt at altlinux.org  Tue Dec  3 14:14:53 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Wed, 4 Dec 2024 01:14:53 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <1847e34fa7724d28aeb22d93752f64f2@huawei.com>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
 <20241203092721.j473dthkbq6wzez7@altlinux.org>
 <1847e34fa7724d28aeb22d93752f64f2@huawei.com>
Message-ID: <20241203221453.mwh6sozyczi4ec2k@altlinux.org>

Shameer, Marc, Oliver, Will,

On Tue, Dec 03, 2024 at 10:03:11AM +0000, Shameerali Kolothum Thodi wrote:
> > -----Original Message-----
> > From: linux-arm-kernel <linux-arm-kernel-bounces at lists.infradead.org> On
> > Behalf Of Vitaly Chikunov
> > Sent: Tuesday, December 3, 2024 9:27 AM
> > To: Marc Zyngier <maz at kernel.org>
> > Cc: Will Deacon <will at kernel.org>; james.morse at arm.com; linux-arm-
> > kernel at lists.infradead.org; Catalin Marinas <catalin.marinas at arm.com>;
> > linux-kernel at vger.kernel.org; oliver.upton at linux.dev;
> > mark.rutland at arm.com
> > Subject: Re: v6.13-rc1: Internal error: Oops - Undefined instruction:
> > 0000000002000000 [#1] SMP
> > 
> > Marc,
> > 
> > On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> > > On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > > > On Mon, 02 Dec 2024 15:59:40 +0000,
> > > > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > > >
> > > > > Marc,
> > > > >
> > > > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > > > >
> > > > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > > >
> > > > > No, host is 6.6.60.
> > > >
> > > > Right. I wouldn't be surprised if:
> > > >
> > > > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> > > >   that's proably something we should backport)
> > >
> > > How to confirm this? Currently I cannot find any (case-insensitive)
> > > "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM
> > > strings in `strace -v` (as it decodes some KVM ioctls) of qemu process.
> > >
> > > >
> > > > - you get a nastygram in the host log telling you that the guest has
> > > >   executed something it shouldn't (you'll get the encoding of the
> > > >   instruction)
> > >
> > > I requested admins of the box for dmesg output since I don't have root
> > > access myself and nowadays dmesg is not accessible for a user.
> > 
> > This is what they reported:
> > 
> >   kvm [2502822]: Unsupported guest sys_reg access at: ffff80008003e9f0
> > [000000c5]
> >                    { Op0( 3), Op1( 0), CRn(10), CRm( 4), Op2( 4), func_read },
> > 
> 
> As Will pointed out I think this is access to MPAMIDR_EL1 and is from this
> code here,
> 
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -478,6 +478,9 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
>  	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
>  		__cpuinfo_store_cpu_32bit(&info->aarch32);
>  
> +	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
> +		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
> +
>  	cpuinfo_detect_icache_policy(info);
>  }
> 
> I did manage to boot my setup in 6.6 and this is what happens,
> 
> Host kernel 6.6
> Guest Kernel 6.13-rc1
> 
> [    0.195392] smp: Brought up 1 node, 8 CPUs
> [    0.219000] SMP: Total of 8 processors activated.
> [    0.219629] CPU: All CPU(s) started at EL1
> ...
> [    0.223212] CPU features: detected: RAS Extension Support
> [    0.223927] CPU features: detected: Memory Partitioning And Monitoring
> [    0.224796] CPU features: detected: Memory Partitioning And Monitoring Virtualisation
> [    0.225961] alternatives: applying system-wide alternatives
> ...
> 
> Guest detects MPAM and boots fine.
> 
> Host kernel 6.13-rc1
> Guest Kernel 6.13-rc1
> 
> [    0.196625] smp: Brought up 1 node, 8 CPUs
> [    0.222093] SMP: Total of 8 processors activated.
> [    0.222769] CPU: All CPU(s) started at EL1
> ...
> [    0.226620] CPU features: detected: RAS Extension Support
> [    0.227453] alternatives: applying system-wide alternatives
> 
> MPAM is not visible to Guest in this case.
> 
> So as I pointed out earlier could it be a case where the ID register reports MPAM support
> but the firmware has not enabled MPAM?
> 
> James seems to be mentioning that case here,
> 
> " (If you have a boot failure that bisects here its likely your CPUs
> advertise MPAM in the id registers, but firmware failed to either enable
> or MPAM, or emulate the trap as if it were disabled)"

I tried to verify that MPAM is advertised with qemu+gdb method, as
suggested by Oliver, but ID_AA64PFR0_EL1 register is not there.

  (gdb) i r ID_AA64PFR0_EL1
  Invalid register `ID_AA64PFR0_EL1'

Are there other suggestions?

> 
> https://lore.kernel.org/all/20241030160317.2528209-4-joey.gouly at arm.com/
> 
> Is there a way you can find out the BIOS version on that board?

Unfortunately, admins of the server do not provide me with this info.

For such cases, when MPAM is incorrectly advertised, can we have kernel
command line parameter like mpam=0 to override it's detection?

I think with "If you have a boot failure that bisects here" it's
acknowledged possibility and it's confirmed by our server.

Thanks,

> 
> Thanks,
> Shameer


From broonie at kernel.org  Tue Dec  3 14:22:04 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 3 Dec 2024 22:22:04 +0000
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <37b656cc8272552ba07c93c5a9a59641.sboyd@kernel.org>
References: <f8de4a2a-776f-4c10-b75e-e845bcc38dde@app.fastmail.com>
 <1j4j3r32ld.fsf@starbuckisacylon.baylibre.com>
 <306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com>
 <1jy1131kxz.fsf@starbuckisacylon.baylibre.com>
 <c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com>
 <1jplmf1jqa.fsf@starbuckisacylon.baylibre.com>
 <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com>
 <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org>
 <1jr06pkof6.fsf@starbuckisacylon.baylibre.com>
 <37b656cc8272552ba07c93c5a9a59641.sboyd@kernel.org>
Message-ID: <dbb2de3c-cb29-4384-a00b-4fdedeab1a10@sirena.org.uk>

On Tue, Dec 03, 2024 at 12:15:48PM -0800, Stephen Boyd wrote:
> Quoting Jerome Brunet (2024-12-03 03:15:41)

> > I suspect the the generic path is likely to trigger more discussion.
> > I'd like to be able to finish this migration, instead of leaving half
> > finished like it is now.

> Is the half finished migration a problem for this cycle? I was intending
> to send the revert later this week and try again next cycle.

Yes, this patch was triggered by me reporting that multiple boards in my
test farm have completely broken audio with defconfig.  It's already a
bit frustrating that -rc1 isn't working.
-------------- 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/20241203/487f9ff4/attachment.sig>

From nicolinc at nvidia.com  Tue Dec  3 14:10:07 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:07 -0800
Subject: [PATCH v2 02/13] iommufd/fault: Move iommufd_fault_iopf_handler() to header
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <137e3357f00b30a08c2b49c00b968a88af8cb5d1.1733263737.git.nicolinc@nvidia.com>

The new vIRQ object will need a similar function for drivers to report the
vIOMMU related interrupts. Split the common part out to a smaller helper,
and place it in the header so that CONFIG_IOMMUFD_DRIVER_CORE can include
that in the driver.c file for drivers to use.

Then keep iommufd_fault_iopf_handler() in the header too, since it's quite
simple after all.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/iommufd_private.h | 20 +++++++++++++++++++-
 drivers/iommu/iommufd/fault.c           | 17 -----------------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index b6d706cf2c66..8b378705ee71 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -451,6 +451,17 @@ struct iommufd_fault {
 	struct wait_queue_head wait_queue;
 };
 
+static inline int iommufd_fault_notify(struct iommufd_fault *fault,
+				       struct list_head *new_fault)
+{
+	mutex_lock(&fault->mutex);
+	list_add_tail(new_fault, &fault->deliver);
+	mutex_unlock(&fault->mutex);
+
+	wake_up_interruptible(&fault->wait_queue);
+	return 0;
+}
+
 struct iommufd_attach_handle {
 	struct iommu_attach_handle handle;
 	struct iommufd_device *idev;
@@ -469,7 +480,14 @@ iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id)
 
 int iommufd_fault_alloc(struct iommufd_ucmd *ucmd);
 void iommufd_fault_destroy(struct iommufd_object *obj);
-int iommufd_fault_iopf_handler(struct iopf_group *group);
+
+static inline int iommufd_fault_iopf_handler(struct iopf_group *group)
+{
+	struct iommufd_hw_pagetable *hwpt =
+		group->attach_handle->domain->fault_data;
+
+	return iommufd_fault_notify(hwpt->fault, &group->node);
+}
 
 int iommufd_fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
 				    struct iommufd_device *idev);
diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
index 87c811b9c0d0..5694b04a48bd 100644
--- a/drivers/iommu/iommufd/fault.c
+++ b/drivers/iommu/iommufd/fault.c
@@ -433,20 +433,3 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 
 	return rc;
 }
-
-int iommufd_fault_iopf_handler(struct iopf_group *group)
-{
-	struct iommufd_hw_pagetable *hwpt;
-	struct iommufd_fault *fault;
-
-	hwpt = group->attach_handle->domain->fault_data;
-	fault = hwpt->fault;
-
-	mutex_lock(&fault->mutex);
-	list_add_tail(&group->node, &fault->deliver);
-	mutex_unlock(&fault->mutex);
-
-	wake_up_interruptible(&fault->wait_queue);
-
-	return 0;
-}
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:06 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:06 -0800
Subject: [PATCH v2 01/13] iommufd/fault: Add an iommufd_fault_init() helper
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <3bc49512a42b88130cf447a7ac10acf5c02e056c.1733263737.git.nicolinc@nvidia.com>

A fault object will be renamed and shared with a new vIRQ object in one of
the following changes. Add a helper for the new allocator to call it too.

Reorder the iommufd_ctx_get and refcount_inc to keep them symmetrical with
the iommufd_fault_fops_release().

Since the new vIRQ object doesn't need "response", leave the xa_init_flags
in its original location.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/fault.c | 48 ++++++++++++++++++++---------------
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
index 1fe804e28a86..87c811b9c0d0 100644
--- a/drivers/iommu/iommufd/fault.c
+++ b/drivers/iommu/iommufd/fault.c
@@ -367,11 +367,35 @@ static const struct file_operations iommufd_fault_fops = {
 	.release	= iommufd_fault_fops_release,
 };
 
+static int iommufd_fault_init(struct iommufd_fault *fault, char *name,
+			      struct iommufd_ctx *ictx)
+{
+	struct file *filep;
+	int fdno;
+
+	fault->ictx = ictx;
+	mutex_init(&fault->mutex);
+	INIT_LIST_HEAD(&fault->deliver);
+	init_waitqueue_head(&fault->wait_queue);
+
+	filep = anon_inode_getfile(name, &iommufd_fault_fops, fault, O_RDWR);
+	if (IS_ERR(filep))
+		return PTR_ERR(filep);
+
+	fault->filep = filep;
+	iommufd_ctx_get(fault->ictx);
+	refcount_inc(&fault->obj.users);
+
+	fdno = get_unused_fd_flags(O_CLOEXEC);
+	if (fdno < 0)
+		fput(filep);
+	return fdno;
+}
+
 int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 {
 	struct iommu_fault_alloc *cmd = ucmd->cmd;
 	struct iommufd_fault *fault;
-	struct file *filep;
 	int fdno;
 	int rc;
 
@@ -382,27 +406,12 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 	if (IS_ERR(fault))
 		return PTR_ERR(fault);
 
-	fault->ictx = ucmd->ictx;
-	INIT_LIST_HEAD(&fault->deliver);
 	xa_init_flags(&fault->response, XA_FLAGS_ALLOC1);
-	mutex_init(&fault->mutex);
-	init_waitqueue_head(&fault->wait_queue);
-
-	filep = anon_inode_getfile("[iommufd-pgfault]", &iommufd_fault_fops,
-				   fault, O_RDWR);
-	if (IS_ERR(filep)) {
-		rc = PTR_ERR(filep);
-		goto out_abort;
-	}
 
-	refcount_inc(&fault->obj.users);
-	iommufd_ctx_get(fault->ictx);
-	fault->filep = filep;
-
-	fdno = get_unused_fd_flags(O_CLOEXEC);
+	fdno = iommufd_fault_init(fault, "[iommufd-pgfault]", ucmd->ictx);
 	if (fdno < 0) {
 		rc = fdno;
-		goto out_fput;
+		goto out_abort;
 	}
 
 	cmd->out_fault_id = fault->obj.id;
@@ -418,8 +427,7 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 	return 0;
 out_put_fdno:
 	put_unused_fd(fdno);
-out_fput:
-	fput(filep);
+	fput(fault->filep);
 out_abort:
 	iommufd_object_abort_and_destroy(ucmd->ictx, &fault->obj);
 
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:10 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:10 -0800
Subject: [PATCH v2 05/13] iommufd: Add IOMMUFD_OBJ_EVENTQ_VIRQ and IOMMUFD_CMD_VIRQ_ALLOC
In-Reply-To: <cover.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
Message-ID: <7f5f7adc2493c7bca7edf76ca15b377c8dc0d397.1733263737.git.nicolinc@nvidia.com>

Allow a vIOMMU object to allocate vIRQ Event Queues, with a condition that
each vIOMMU can only have one single vIRQ event queue per type.

Add iommufd_eventq_virq_alloc with an iommufd_eventq_virq_ops for this new
ioctl.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/iommufd_private.h |  59 ++++++++++
 include/linux/iommufd.h                 |   3 +
 include/uapi/linux/iommufd.h            |  31 ++++++
 drivers/iommu/iommufd/eventq.c          | 138 ++++++++++++++++++++++++
 drivers/iommu/iommufd/main.c            |   6 ++
 drivers/iommu/iommufd/viommu.c          |   2 +
 6 files changed, 239 insertions(+)

diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index 1c9a101cc435..fd0b87707967 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -548,6 +548,51 @@ static inline int iommufd_hwpt_replace_device(struct iommufd_device *idev,
 	return iommu_group_replace_domain(idev->igroup->group, hwpt->domain);
 }
 
+/*
+ * An iommufd_eventq_virq object represents a queue to deliver vIOMMU interrupts
+ * to the user space. These objects are created/destroyed by the user space and
+ * associated with vIOMMU object(s) during the allocations.
+ */
+struct iommufd_eventq_virq {
+	struct iommufd_eventq common;
+	struct iommufd_viommu *viommu;
+	struct workqueue_struct *irq_wq;
+	struct list_head node;
+
+	unsigned int type;
+};
+
+static inline struct iommufd_eventq_virq *
+to_eventq_virq(struct iommufd_eventq *eventq)
+{
+	return container_of(eventq, struct iommufd_eventq_virq, common);
+}
+
+static inline struct iommufd_eventq_virq *
+iommufd_get_eventq_virq(struct iommufd_ucmd *ucmd, u32 id)
+{
+	return container_of(iommufd_get_object(ucmd->ictx, id,
+					       IOMMUFD_OBJ_EVENTQ_VIRQ),
+			    struct iommufd_eventq_virq, common.obj);
+}
+
+int iommufd_eventq_virq_alloc(struct iommufd_ucmd *ucmd);
+void iommufd_eventq_virq_destroy(struct iommufd_object *obj);
+void iommufd_eventq_virq_abort(struct iommufd_object *obj);
+
+/* An iommufd_virq represents a vIOMMU interrupt in an eventq_virq queue */
+struct iommufd_virq {
+	struct iommufd_eventq_virq *eventq_virq;
+	struct list_head node;
+	ssize_t irq_len;
+	void *irq_data;
+};
+
+static inline int iommufd_eventq_virq_handler(struct iommufd_virq *virq)
+{
+	return iommufd_eventq_notify(&virq->eventq_virq->common, &virq->node);
+}
+
 static inline struct iommufd_viommu *
 iommufd_get_viommu(struct iommufd_ucmd *ucmd, u32 id)
 {
@@ -556,6 +601,20 @@ iommufd_get_viommu(struct iommufd_ucmd *ucmd, u32 id)
 			    struct iommufd_viommu, obj);
 }
 
+static inline struct iommufd_eventq_virq *
+iommufd_viommu_find_eventq_virq(struct iommufd_viommu *viommu, u32 type)
+{
+	struct iommufd_eventq_virq *eventq_virq, *next;
+
+	lockdep_assert_held(&viommu->virqs_rwsem);
+
+	list_for_each_entry_safe(eventq_virq, next, &viommu->virqs, node) {
+		if (eventq_virq->type == type)
+			return eventq_virq;
+	}
+	return NULL;
+}
+
 int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd);
 void iommufd_viommu_destroy(struct iommufd_object *obj);
 int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd);
diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 7ad105ab8090..40cc9bbb1d24 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -32,6 +32,7 @@ enum iommufd_object_type {
 	IOMMUFD_OBJ_IOAS,
 	IOMMUFD_OBJ_ACCESS,
 	IOMMUFD_OBJ_EVENTQ_IOPF,
+	IOMMUFD_OBJ_EVENTQ_VIRQ,
 	IOMMUFD_OBJ_VIOMMU,
 	IOMMUFD_OBJ_VDEVICE,
 #ifdef CONFIG_IOMMUFD_TEST
@@ -93,6 +94,8 @@ struct iommufd_viommu {
 	const struct iommufd_viommu_ops *ops;
 
 	struct xarray vdevs;
+	struct list_head virqs;
+	struct rw_semaphore virqs_rwsem;
 
 	unsigned int type;
 };
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index 34810f6ae2b5..d9319f5b7c69 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -55,6 +55,7 @@ enum {
 	IOMMUFD_CMD_VIOMMU_ALLOC = 0x90,
 	IOMMUFD_CMD_VDEVICE_ALLOC = 0x91,
 	IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92,
+	IOMMUFD_CMD_VIRQ_ALLOC = 0x93,
 };
 
 /**
@@ -1012,4 +1013,34 @@ struct iommu_ioas_change_process {
 #define IOMMU_IOAS_CHANGE_PROCESS \
 	_IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS)
 
+/**
+ * enum iommu_virq_type - Virtual IRQ Type
+ * @IOMMU_VIRQ_TYPE_NONE: INVALID type
+ */
+enum iommu_virq_type {
+	IOMMU_VIRQ_TYPE_NONE = 0,
+};
+
+/**
+ * struct iommu_virq_alloc - ioctl(IOMMU_VIRQ_ALLOC)
+ * @size: sizeof(struct iommu_virq_alloc)
+ * @flags: Must be 0
+ * @viommu: virtual IOMMU ID to associate the virtual IRQ with
+ * @type: Type of the virtual IRQ. Must be defined in enum iommu_virq_type
+ * @out_virq_id: The ID of the new virtual IRQ
+ * @out_fault_fd: The fd of the new virtual IRQ. User space must close the
+ *                successfully returned fd after using it
+ *
+ * Explicitly allocate a virtual IRQ handler for a vIOMMU. A vIOMMU can have
+ * multiple FDs for different @type, but is confined to one FD per @type.
+ */
+struct iommu_virq_alloc {
+	__u32 size;
+	__u32 flags;
+	__u32 viommu_id;
+	__u32 type;
+	__u32 out_virq_id;
+	__u32 out_virq_fd;
+};
+#define IOMMU_VIRQ_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VIRQ_ALLOC)
 #endif
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
index 3674961a45c2..cf07b3c21f1e 100644
--- a/drivers/iommu/iommufd/eventq.c
+++ b/drivers/iommu/iommufd/eventq.c
@@ -346,6 +346,75 @@ static const struct iommufd_eventq_ops iommufd_eventq_iopf_ops = {
 	.write = &iommufd_eventq_iopf_fops_write,
 };
 
+/* IOMMUFD_OBJ_EVENTQ_VIRQ Functions */
+
+void iommufd_eventq_virq_abort(struct iommufd_object *obj)
+{
+	struct iommufd_eventq *eventq =
+		container_of(obj, struct iommufd_eventq, obj);
+	struct iommufd_eventq_virq *eventq_virq = to_eventq_virq(eventq);
+	struct iommufd_viommu *viommu = eventq_virq->viommu;
+	struct iommufd_virq *virq, *next;
+
+	lockdep_assert_held_write(&viommu->virqs_rwsem);
+
+	list_for_each_entry_safe(virq, next, &eventq->deliver, node) {
+		list_del(&virq->node);
+		kfree(virq);
+	}
+
+	if (eventq_virq->irq_wq)
+		destroy_workqueue(eventq_virq->irq_wq);
+	refcount_dec(&viommu->obj.users);
+	mutex_destroy(&eventq->mutex);
+	list_del(&eventq_virq->node);
+}
+
+void iommufd_eventq_virq_destroy(struct iommufd_object *obj)
+{
+	struct iommufd_eventq_virq *eventq_virq =
+		to_eventq_virq(container_of(obj, struct iommufd_eventq, obj));
+
+	down_write(&eventq_virq->viommu->virqs_rwsem);
+	iommufd_eventq_virq_abort(obj);
+	up_write(&eventq_virq->viommu->virqs_rwsem);
+}
+
+static ssize_t iommufd_eventq_virq_fops_read(struct iommufd_eventq *eventq,
+					     char __user *buf, size_t count,
+					     loff_t *ppos)
+{
+	size_t done = 0;
+	int rc = 0;
+
+	if (*ppos)
+		return -ESPIPE;
+
+	mutex_lock(&eventq->mutex);
+	while (!list_empty(&eventq->deliver) && count > done) {
+		struct iommufd_virq *virq = list_first_entry(
+			&eventq->deliver, struct iommufd_virq, node);
+
+		if (virq->irq_len > count - done)
+			break;
+
+		if (copy_to_user(buf + done, virq->irq_data, virq->irq_len)) {
+			rc = -EFAULT;
+			break;
+		}
+		done += virq->irq_len;
+		list_del(&virq->node);
+		kfree(virq);
+	}
+	mutex_unlock(&eventq->mutex);
+
+	return done == 0 ? rc : done;
+}
+
+static const struct iommufd_eventq_ops iommufd_eventq_virq_ops = {
+	.read = &iommufd_eventq_virq_fops_read,
+};
+
 /* Common Event Queue Functions */
 
 static ssize_t iommufd_eventq_fops_read(struct file *filep, char __user *buf,
@@ -472,3 +541,72 @@ int iommufd_eventq_iopf_alloc(struct iommufd_ucmd *ucmd)
 
 	return rc;
 }
+
+int iommufd_eventq_virq_alloc(struct iommufd_ucmd *ucmd)
+{
+	struct iommu_virq_alloc *cmd = ucmd->cmd;
+	struct iommufd_eventq_virq *eventq_virq;
+	struct iommufd_viommu *viommu;
+	int fdno;
+	int rc;
+
+	if (cmd->flags || cmd->type == IOMMU_VIRQ_TYPE_NONE)
+		return -EOPNOTSUPP;
+
+	viommu = iommufd_get_viommu(ucmd, cmd->viommu_id);
+	if (IS_ERR(viommu))
+		return PTR_ERR(viommu);
+	down_write(&viommu->virqs_rwsem);
+
+	if (iommufd_viommu_find_eventq_virq(viommu, cmd->type)) {
+		rc = -EEXIST;
+		goto out_unlock_virqs;
+	}
+
+	eventq_virq = __iommufd_object_alloc(
+		ucmd->ictx, eventq_virq, IOMMUFD_OBJ_EVENTQ_VIRQ, common.obj);
+	if (IS_ERR(eventq_virq)) {
+		rc = PTR_ERR(eventq_virq);
+		goto out_unlock_virqs;
+	}
+
+	eventq_virq->type = cmd->type;
+	eventq_virq->viommu = viommu;
+	refcount_inc(&viommu->obj.users);
+	list_add_tail(&eventq_virq->node, &viommu->virqs);
+
+	fdno = iommufd_eventq_init(&eventq_virq->common, "[iommufd-viommu-irq]",
+				 ucmd->ictx, &iommufd_eventq_virq_ops);
+	if (fdno < 0) {
+		rc = fdno;
+		goto out_abort;
+	}
+
+	eventq_virq->irq_wq = alloc_workqueue("viommu_irq/%d", WQ_UNBOUND, 0,
+					      eventq_virq->common.obj.id);
+	if (!eventq_virq->irq_wq) {
+		rc = -ENOMEM;
+		goto out_put_fdno;
+	}
+
+	cmd->out_virq_id = eventq_virq->common.obj.id;
+	cmd->out_virq_fd = fdno;
+
+	rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
+	if (rc)
+		goto out_put_fdno;
+
+	iommufd_object_finalize(ucmd->ictx, &eventq_virq->common.obj);
+	fd_install(fdno, eventq_virq->common.filep);
+	goto out_unlock_virqs;
+
+out_put_fdno:
+	put_unused_fd(fdno);
+	fput(eventq_virq->common.filep);
+out_abort:
+	iommufd_object_abort_and_destroy(ucmd->ictx, &eventq_virq->common.obj);
+out_unlock_virqs:
+	up_write(&viommu->virqs_rwsem);
+	iommufd_put_object(ucmd->ictx, &viommu->obj);
+	return rc;
+}
diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index 539c24ada6d0..89e8ac56f4ce 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -335,6 +335,8 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = {
 	IOCTL_OP(IOMMU_DESTROY, iommufd_destroy, struct iommu_destroy, id),
 	IOCTL_OP(IOMMU_FAULT_QUEUE_ALLOC, iommufd_eventq_iopf_alloc,
 		 struct iommu_fault_alloc, out_fault_fd),
+	IOCTL_OP(IOMMU_VIRQ_ALLOC, iommufd_eventq_virq_alloc,
+		 struct iommu_virq_alloc, out_virq_fd),
 	IOCTL_OP(IOMMU_GET_HW_INFO, iommufd_get_hw_info, struct iommu_hw_info,
 		 __reserved),
 	IOCTL_OP(IOMMU_HWPT_ALLOC, iommufd_hwpt_alloc, struct iommu_hwpt_alloc,
@@ -504,6 +506,10 @@ static const struct iommufd_object_ops iommufd_object_ops[] = {
 	[IOMMUFD_OBJ_EVENTQ_IOPF] = {
 		.destroy = iommufd_eventq_iopf_destroy,
 	},
+	[IOMMUFD_OBJ_EVENTQ_VIRQ] = {
+		.destroy = iommufd_eventq_virq_destroy,
+		.abort = iommufd_eventq_virq_abort,
+	},
 	[IOMMUFD_OBJ_VIOMMU] = {
 		.destroy = iommufd_viommu_destroy,
 	},
diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c
index 69b88e8c7c26..075b6aed79bc 100644
--- a/drivers/iommu/iommufd/viommu.c
+++ b/drivers/iommu/iommufd/viommu.c
@@ -59,6 +59,8 @@ int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd)
 	viommu->ictx = ucmd->ictx;
 	viommu->hwpt = hwpt_paging;
 	refcount_inc(&viommu->hwpt->common.obj.users);
+	INIT_LIST_HEAD(&viommu->virqs);
+	init_rwsem(&viommu->virqs_rwsem);
 	/*
 	 * It is the most likely case that a physical IOMMU is unpluggable. A
 	 * pluggable IOMMU instance (if exists) is responsible for refcounting
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec  3 14:10:05 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 3 Dec 2024 14:10:05 -0800
Subject: [PATCH v2 00/13] iommufd: Add vIOMMU infrastructure (Part-3: vIRQ)
Message-ID: <cover.1733263737.git.nicolinc@nvidia.com>

As the part-3 of the vIOMMU infrastructure, this series introduces a vIRQ
object. The existing FAULT object provides a nice notification pathway to
the user space already, so let vIRQ reuse the infrastructure.

Mimicing the HWPT structure, add a common EVENTQ structure to support its
derivatives: EVENTQ_IOPF (the prior FAULT object) and EVENTQ_VIRQ (new).
IOMMUFD_CMD_VIRQ_ALLOC is introduced to allocate EVENTQ_VIRQ for vIOMMUs.
One vIOMMU can have multiple vIRQs in different types but can not support
multiple vIRQs with the same types.

The forwarding part is fairly simple but might need to replace a physical
device ID with a virtual device ID in a driver-level IRQ data structure.
So, this comes with some helpers for drivers to use.

As usual, this series comes with the selftest coverage for this new vIRQ,
and with a real world use case in the ARM SMMUv3 driver.

This is on Github:
https://github.com/nicolinc/iommufd/commits/iommufd_virq-v2

Testing with RMR patches for MSI:
https://github.com/nicolinc/iommufd/commits/iommufd_virq-v2-with-rmr
Paring QEMU branch for testing:
https://github.com/nicolinc/qemu/commits/wip/for_iommufd_virq-v2

Changelog
v2
 * Rebased on v6.13-rc1
 * Added IOPF and vIRQ in iommufd.rst (userspace-api)
 * Added a proper locking in iommufd_event_virq_destroy
 * Added iommufd_event_virq_abort with a lockdep_assert_held
 * Renamed "EVENT_*" to "EVENTQ_*" to describe the objects better
 * Reorganized flows in iommufd_eventq_virq_alloc for abort() to work
 * Added struct arm_smmu_vmaster to store vSID upon attaching to a nested
   domain, calling a newly added iommufd_viommu_get_vdev_id helper
 * Added an arm_vmaster_report_event helper in arm-smmu-v3-iommufd file
   to simplify the routine in arm_smmu_handle_evt() of the main driver
v1
 https://lore.kernel.org/all/cover.1724777091.git.nicolinc at nvidia.com/

Thanks!
Nicolin

Nicolin Chen (13):
  iommufd/fault: Add an iommufd_fault_init() helper
  iommufd/fault: Move iommufd_fault_iopf_handler() to header
  iommufd: Rename IOMMUFD_OBJ_FAULT to IOMMUFD_OBJ_EVENTQ_IOPF
  iommufd: Rename fault.c to eventq.c
  iommufd: Add IOMMUFD_OBJ_EVENTQ_VIRQ and IOMMUFD_CMD_VIRQ_ALLOC
  iommufd/viommu: Add iommufd_viommu_get_vdev_id helper
  iommufd/viommu: Add iommufd_viommu_report_irq helper
  iommufd/selftest: Require vdev_id when attaching to a nested domain
  iommufd/selftest: Add IOMMU_TEST_OP_TRIGGER_VIRQ for vIRQ coverage
  iommufd/selftest: Add EVENT_VIRQ test coverage
  Documentation: userspace-api: iommufd: Update EVENTQ_IOPF and
    EVENTQ_VIRQ
  iommu/arm-smmu-v3: Introduce struct arm_smmu_vmaster
  iommu/arm-smmu-v3: Report IRQs that belong to devices attached to
    vIOMMU

 drivers/iommu/iommufd/Makefile                |   2 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  30 +
 drivers/iommu/iommufd/iommufd_private.h       | 150 ++++-
 drivers/iommu/iommufd/iommufd_test.h          |  10 +
 include/linux/iommufd.h                       |  22 +-
 include/uapi/linux/iommufd.h                  |  45 ++
 tools/testing/selftests/iommu/iommufd_utils.h |  63 ++
 .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c     |  65 ++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  94 ++-
 drivers/iommu/iommufd/driver.c                |  59 ++
 drivers/iommu/iommufd/eventq.c                | 612 ++++++++++++++++++
 drivers/iommu/iommufd/fault.c                 | 444 -------------
 drivers/iommu/iommufd/hw_pagetable.c          |  12 +-
 drivers/iommu/iommufd/main.c                  |  14 +-
 drivers/iommu/iommufd/selftest.c              |  53 ++
 drivers/iommu/iommufd/viommu.c                |   2 +
 tools/testing/selftests/iommu/iommufd.c       |  27 +
 .../selftests/iommu/iommufd_fail_nth.c        |   6 +
 Documentation/userspace-api/iommufd.rst       |  19 +
 19 files changed, 1218 insertions(+), 511 deletions(-)
 create mode 100644 drivers/iommu/iommufd/eventq.c
 delete mode 100644 drivers/iommu/iommufd/fault.c


base-commit: 2ca704f55e22b7b00cc7025953091af3c82fa5c0
-- 
2.43.0



From helgaas at kernel.org  Tue Dec  3 14:25:15 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 3 Dec 2024 16:25:15 -0600
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <20241126155119.1574564-2-christian.bruel@foss.st.com>
Message-ID: <20241203222515.GA2967814@bhelgaas>

On Tue, Nov 26, 2024 at 04:51:15PM +0100, Christian Bruel wrote:
> Document the bindings for STM32MP25 PCIe Controller configured in
> root complex mode.
> 
> Supports 4 legacy interrupts and MSI interrupts from the ARM
> GICv2m controller.

s/legacy/INTx/

> STM32 PCIe may be in a power domain which is the case for the STM32MP25
> based boards.
> 
> Supports wake# from wake-gpios

s/wake#/WAKE#/

> +  wake-gpios:
> +    description: GPIO controlled connection to WAKE# input signal

I'm not a hardware guy, but this sounds like a GPIO that *reads*
WAKE#, not controls it.

> +    pcie at 48400000 {
> +        compatible = "st,stm32mp25-pcie-rc";
> +        device_type = "pci";
> +        num-lanes = <1>;

num-lanes applies to a Root Port, not to a Root Complex.  I know most
bindings conflate Root Ports with the Root Complex, maybe because many
of these controllers only support a single Root Port?

But are we ever going to separate these out?  I assume someday
controllers will support multiple Root Ports and/or additional devices
on the root bus, like RCiEPs, RCECs, etc., and we'll need per-RP phys,
max-link-speed, num-lanes, reset-gpios, etc.

Seems like it would be to our benefit to split out the Root Ports when
we can, even if the current hardware only supports one, so we can
start untangling the code and data structures.

Bjorn


From oliver.upton at linux.dev  Tue Dec  3 14:32:38 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 3 Dec 2024 14:32:38 -0800
Subject: [RFC PATCH 05/14] KVM: arm64: Always allow fixed cycle counter
In-Reply-To: <87ldwwsbad.wl-maz@kernel.org>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
 <20241203193220.1070811-6-oliver.upton@linux.dev>
 <87ldwwsbad.wl-maz@kernel.org>
Message-ID: <Z0-HBsBgf6WB7x4R@linux.dev>

On Tue, Dec 03, 2024 at 09:32:10PM +0000, Marc Zyngier wrote:
> On Tue, 03 Dec 2024 19:32:11 +0000,
> Oliver Upton <oliver.upton at linux.dev> wrote:
> > 
> > The fixed CPU cycle counter is mandatory for PMUv3, so it doesn't make a
> > lot of sense allowing userspace to filter it. Only apply the PMU event
> > filter to *programmed* event counters.
> 
> But that's a change in ABI, isn't it? We explicitly say in the
> documentation that the cycle counter can be filtered by specifying
> event 0x11.

Yeah... A bit of a dirty shortcut I took because I don't like the ABI,
but distaste isn't enough to break it :)

> More importantly, the current filtering works in terms of events, and
> not in terms of counters.
> 
> Instead of changing the ABI, how about simply not supporting filtering
> on such non-compliant HW? Surely that would simplify a few things.

Yeah, that sounds reasonable. Especially if we allow programmable event
counters where the event ID space doesn't match the architecture.

-- 
Thanks,
Oliver


From sboyd at kernel.org  Tue Dec  3 14:32:56 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 03 Dec 2024 14:32:56 -0800
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <dbb2de3c-cb29-4384-a00b-4fdedeab1a10@sirena.org.uk>
References: <f8de4a2a-776f-4c10-b75e-e845bcc38dde@app.fastmail.com> <306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com> <1jy1131kxz.fsf@starbuckisacylon.baylibre.com> <c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com> <1jplmf1jqa.fsf@starbuckisacylon.baylibre.com> <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com> <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org> <1jr06pkof6.fsf@starbuckisacylon.baylibre.com> <37b656cc8272552ba07c93c5a9a59641.sboyd@kernel.org> <dbb2de3c-cb29-4384-a00b-4fdedeab1a10@sirena.org.uk>
Message-ID: <c982c5061ea6b0d465dd8b7fefc59cc7.sboyd@kernel.org>

Quoting Mark Brown (2024-12-03 14:22:04)
> On Tue, Dec 03, 2024 at 12:15:48PM -0800, Stephen Boyd wrote:
> > Quoting Jerome Brunet (2024-12-03 03:15:41)
> 
> > > I suspect the the generic path is likely to trigger more discussion.
> > > I'd like to be able to finish this migration, instead of leaving half
> > > finished like it is now.
> 
> > Is the half finished migration a problem for this cycle? I was intending
> > to send the revert later this week and try again next cycle.
> 
> Yes, this patch was triggered by me reporting that multiple boards in my
> test farm have completely broken audio with defconfig. 

I thought that commit 5ae1a43486fb ("clk: amlogic: axg-audio: revert
reset implementation") was sufficient to fix the problem. Is that
incorrect?


From helgaas at kernel.org  Tue Dec  3 14:39:20 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 3 Dec 2024 16:39:20 -0600
Subject: [PATCH v5 1/2] PCI: Add enable_device() and disable_device()
 callbacks for bridges
In-Reply-To: <Z09tOGxAK6nBB8wV@lizhi-Precision-Tower-5810>
Message-ID: <20241203223920.GA2969750@bhelgaas>

On Tue, Dec 03, 2024 at 03:42:32PM -0500, Frank Li wrote:
> On Mon, Nov 04, 2024 at 02:22:59PM -0500, Frank Li wrote:
> > Some PCIe host bridges require special handling when enabling or disabling
> > PCIe Endpoints. For example, the i.MX95 platform has a lookup table to map
> > Requester IDs to StreamIDs, which are used by the SMMU and MSI controller
> > to identify the source of DMA accesses.
> >
> > Without this mapping, DMA accesses may target unintended memory, which
> > would corrupt memory or read the wrong data.
> >
> > Add a host bridge .enable_device() hook the imx6 driver can use to
> > configure the Requester ID to StreamID mapping. The hardware table isn't
> > big enough to map all possible Requester IDs, so this hook may fail if no
> > table space is available. In that case, return failure from
> > pci_enable_device().
> >
> > It might make more sense to make pci_set_master() decline to enable bus
> > mastering and return failure, but it currently doesn't have a way to return
> > failure.
> >
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> 
> Bjorn Helgaas:
> 
> 	Can I keep your acked tag? Compared V4, just use static helper
> functions.

Can you rebase this to pci/main (v6.13-rc1)?  This would go via the
PCI tree, so it will need to be rebased anyway, and then I can ack
that.

Bjorn


From sboyd at kernel.org  Tue Dec  3 14:50:31 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 03 Dec 2024 14:50:31 -0800
Subject: [PATCH v1 08/11] clk: move meson clk-regmap implementation to common code
In-Reply-To: <20241128-monstrous-embargo-a665d921410d@wendy>
References: <20241002-private-unequal-33cfa6101338@spud> <20241002-hula-unwashed-1c4ddbadbec2@spud> <2b49c4df-a34a-42c5-8d44-9e47da630fe8@linaro.org> <1jwmiqsks3.fsf@starbuckisacylon.baylibre.com> <20241003-tacking-ladylike-dfe2b633e647@spud> <20241106-freefall-slider-db379b05821e@spud> <430bde3b35382e640843e32a9f351326.sboyd@kernel.org> <20241128-monstrous-embargo-a665d921410d@wendy>
Message-ID: <e53adbf9fdf6e3f142083b0d40d074ca.sboyd@kernel.org>

Quoting Conor Dooley (2024-11-28 02:36:16)
> On Thu, Nov 14, 2024 at 05:29:54PM -0800, Stephen Boyd wrote:
> > Quoting Conor Dooley (2024-11-06 04:56:25)
> > > My use case doesn't
> > > actually need the registration code changes either as, currently, only reg
> > > gets set at runtime, but leaving that out is a level of incomplete I'd not
> > > let myself away with.
> > > Obviously shoving the extra members into the clk structs has the downside
> > > of taking up a pointer and a offset worth of memory for each clock of
> > > that type registered, but it is substantially easier to support devices
> > > with multiple regmaps that way. Probably moot though since the approach you
> > > suggested in the thread linked above that implements a clk_hw_get_regmap()
> > > has to store a pointer to the regmap's identifier which would take up an
> > > identical amount of memory.
> > 
> > We don't need to store the regmap identifier in the struct clk. We can
> > store it in the 'struct clk_init_data' with some new field, and only do
> > that when/if we actually need to. We would need to pass the init data to
> > the clk_ops::init() callback though. We currently knock that out during
> > registration so that clk_hw->init is NULL. Probably we can just set that
> > to NULL after the init routine runs in __clk_core_init().
> > 
> > Long story short, don't add something to 'struct clk_core', 'struct
> > clk', or 'struct clk_hw' for these details. We can have a 'struct
> > clk_regmap_hw' that everyone else can build upon:
> > 
> >   struct clk_regmap_hw {
> >         struct regmap *regmap;
> >         struct clk_hw hw;
> >   };
> 
> What's the point of this? I don't understand why you want to do this over
> what clk_divider et al already do, where clk_hw and the iomem pointer
> are in the struct itself.

Can you give an example? I don't understand what you're suggesting. I
prefer a struct clk_regmap_hw like above so that the existing struct
clk_hw in the kernel aren't increased by a pointer. SoC drivers can use
the same struct as a replacement for their struct clk_hw member today.


From broonie at kernel.org  Tue Dec  3 14:59:14 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 3 Dec 2024 22:59:14 +0000
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <c982c5061ea6b0d465dd8b7fefc59cc7.sboyd@kernel.org>
References: <306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com>
 <1jy1131kxz.fsf@starbuckisacylon.baylibre.com>
 <c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com>
 <1jplmf1jqa.fsf@starbuckisacylon.baylibre.com>
 <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com>
 <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org>
 <1jr06pkof6.fsf@starbuckisacylon.baylibre.com>
 <37b656cc8272552ba07c93c5a9a59641.sboyd@kernel.org>
 <dbb2de3c-cb29-4384-a00b-4fdedeab1a10@sirena.org.uk>
 <c982c5061ea6b0d465dd8b7fefc59cc7.sboyd@kernel.org>
Message-ID: <31edf979-e03a-4c9c-bb93-59ceea6b44a1@sirena.org.uk>

On Tue, Dec 03, 2024 at 02:32:56PM -0800, Stephen Boyd wrote:
> Quoting Mark Brown (2024-12-03 14:22:04)

> > Yes, this patch was triggered by me reporting that multiple boards in my
> > test farm have completely broken audio with defconfig. 

> I thought that commit 5ae1a43486fb ("clk: amlogic: axg-audio: revert
> reset implementation") was sufficient to fix the problem. Is that
> incorrect?

Yes, it should be - it didn't appear in mainline or -next yet and was a
bit more buried in my mailbox than this thread but I see it's in now.
-------------- 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/20241203/41f72efa/attachment.sig>

From dmitry.torokhov at gmail.com  Tue Dec  3 15:07:49 2024
From: dmitry.torokhov at gmail.com (Dmitry Torokhov)
Date: Tue, 3 Dec 2024 15:07:49 -0800
Subject: [PATCH v2 2/4] input: apple_z2: Add a driver for Apple Z2
 touchscreens
In-Reply-To: <20241128-z2-v2-2-76cc59bbf117@gmail.com>
References: <20241128-z2-v2-0-76cc59bbf117@gmail.com>
 <20241128-z2-v2-2-76cc59bbf117@gmail.com>
Message-ID: <Z0-PRapfiAUGvr4W@google.com>

Hi Sasha,

On Thu, Nov 28, 2024 at 11:29:17PM +0100, Sasha Finkelstein via B4 Relay wrote:
> From: Sasha Finkelstein <fnkl.kernel at gmail.com>
> 
> Adds a driver for Apple touchscreens using the Z2 protocol.
> 
> Signed-off-by: Janne Grunau <j at jannau.net>
> Signed-off-by: Sasha Finkelstein <fnkl.kernel at gmail.com>
> ---
>  drivers/input/touchscreen/Kconfig    |  13 +
>  drivers/input/touchscreen/Makefile   |   1 +
>  drivers/input/touchscreen/apple_z2.c | 458 +++++++++++++++++++++++++++++++++++
>  3 files changed, 472 insertions(+)
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 1ac26fc2e3eb94a4f62a49962c25ec853b567a43..4ad5002191f77a17414f9e1494b0afd6447355c0 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -103,6 +103,19 @@ config TOUCHSCREEN_ADC
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called resistive-adc-touch.ko.
>  
> +config TOUCHSCREEN_APPLE_Z2
> +	tristate "Apple Z2 touchscreens"
> +	default ARCH_APPLE
> +	depends on SPI
> +	help
> +	  Say Y here if you have an Apple device with
> +	  a touchscreen or a touchbar.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called apple_z2.
> +
>  config TOUCHSCREEN_AR1021_I2C
>  	tristate "Microchip AR1020/1021 i2c touchscreen"
>  	depends on I2C && OF
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index 82bc837ca01e2ee18c5e9c578765d55ef9fab6d4..97a025c6a3770fb80255246eb63c11688ebd79eb 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C)	+= ad7879-i2c.o
>  obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI)	+= ad7879-spi.o
>  obj-$(CONFIG_TOUCHSCREEN_ADC)		+= resistive-adc-touch.o
>  obj-$(CONFIG_TOUCHSCREEN_ADS7846)	+= ads7846.o
> +obj-$(CONFIG_TOUCHSCREEN_APPLE_Z2)	+= apple_z2.o
>  obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C)	+= ar1021_i2c.o
>  obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT)	+= atmel_mxt_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR)	+= auo-pixcir-ts.o
> diff --git a/drivers/input/touchscreen/apple_z2.c b/drivers/input/touchscreen/apple_z2.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..05f8e8d01a242415ad79f1b7bae2306dd30d94e3
> --- /dev/null
> +++ b/drivers/input/touchscreen/apple_z2.c
> @@ -0,0 +1,458 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Apple Z2 touchscreen driver
> + *
> + * Copyright (C) The Asahi Linux Contributors
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/firmware.h>
> +#include <linux/input.h>
> +#include <linux/input/mt.h>
> +#include <linux/input/touchscreen.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/spi/spi.h>
> +#include <linux/unaligned.h>
> +
> +#define APPLE_Z2_NUM_FINGERS_OFFSET      16
> +#define APPLE_Z2_FINGERS_OFFSET          24
> +#define APPLE_Z2_TOUCH_STARTED           3
> +#define APPLE_Z2_TOUCH_MOVED             4
> +#define APPLE_Z2_CMD_READ_INTERRUPT_DATA 0xEB
> +#define APPLE_Z2_HBPP_CMD_BLOB           0x3001
> +#define APPLE_Z2_FW_MAGIC                0x5746325A
> +#define LOAD_COMMAND_INIT_PAYLOAD        0
> +#define LOAD_COMMAND_SEND_BLOB           1
> +#define LOAD_COMMAND_SEND_CALIBRATION    2
> +#define CAL_PROP_NAME                    "apple,z2-cal-blob"
> +
> +struct apple_z2 {
> +	struct spi_device *spidev;
> +	struct gpio_desc *reset_gpio;
> +	struct input_dev *input_dev;
> +	struct completion boot_irq;
> +	int booted;

bool.

> +	int counter;
> +	struct touchscreen_properties props;
> +	const char *fw_name;
> +};
> +
> +struct apple_z2_finger {
> +	u8 finger;
> +	u8 state;
> +	__le16 unknown2;
> +	__le16 abs_x;
> +	__le16 abs_y;
> +	__le16 rel_x;
> +	__le16 rel_y;
> +	__le16 tool_major;
> +	__le16 tool_minor;
> +	__le16 orientation;
> +	__le16 touch_major;
> +	__le16 touch_minor;
> +	__le16 unused[2];
> +	__le16 pressure;
> +	__le16 multi;
> +};
> +
> +struct apple_z2_hbpp_blob_hdr {
> +	__le16 cmd;
> +	__le16 len;
> +	__le32 addr;
> +	__le16 checksum;
> +};
> +
> +struct apple_z2_fw_hdr {
> +	__le32 magic;
> +	__le32 version;
> +};
> +
> +struct apple_z2_read_interrupt_cmd {
> +	u8 cmd;
> +	u8 counter;
> +	u8 unused[12];
> +	__le16 checksum;
> +};
> +
> +static void apple_z2_parse_touches(struct apple_z2 *z2, char *msg, size_t msg_len)
> +{
> +	int i;
> +	int nfingers;
> +	int slot;
> +	int slot_valid;
> +	struct apple_z2_finger *fingers;
> +
> +	if (msg_len <= APPLE_Z2_NUM_FINGERS_OFFSET)
> +		return;
> +	nfingers = msg[APPLE_Z2_NUM_FINGERS_OFFSET];
> +	fingers = (struct apple_z2_finger *)(msg + APPLE_Z2_FINGERS_OFFSET);
> +	for (i = 0; i < nfingers; i++) {
> +		slot = input_mt_get_slot_by_key(z2->input_dev, fingers[i].finger);
> +		if (slot < 0) {
> +			dev_warn(&z2->spidev->dev, "unable to get slot for finger\n");
> +			continue;
> +		}
> +		slot_valid = fingers[i].state == APPLE_Z2_TOUCH_STARTED ||
> +			     fingers[i].state == APPLE_Z2_TOUCH_MOVED;
> +		input_mt_slot(z2->input_dev, slot);
> +		if (!input_mt_report_slot_state(z2->input_dev, MT_TOOL_FINGER, slot_valid))
> +			continue;
> +		touchscreen_report_pos(z2->input_dev, &z2->props, le16_to_cpu(fingers[i].abs_x),
> +				       le16_to_cpu(fingers[i].abs_y), true);
> +		input_report_abs(z2->input_dev, ABS_MT_WIDTH_MAJOR,
> +				 le16_to_cpu(fingers[i].tool_major));
> +		input_report_abs(z2->input_dev, ABS_MT_WIDTH_MINOR,
> +				 le16_to_cpu(fingers[i].tool_minor));
> +		input_report_abs(z2->input_dev, ABS_MT_ORIENTATION,
> +				 le16_to_cpu(fingers[i].orientation));
> +		input_report_abs(z2->input_dev, ABS_MT_TOUCH_MAJOR,
> +				 le16_to_cpu(fingers[i].touch_major));
> +		input_report_abs(z2->input_dev, ABS_MT_TOUCH_MINOR,
> +				 le16_to_cpu(fingers[i].touch_minor));
> +	}
> +	input_mt_sync_frame(z2->input_dev);
> +	input_sync(z2->input_dev);
> +}
> +
> +static int apple_z2_read_packet(struct apple_z2 *z2)
> +{
> +	struct spi_message msg;
> +	struct spi_transfer xfer;
> +	int error;
> +	size_t pkt_len;
> +	struct apple_z2_read_interrupt_cmd *len_cmd __free(kfree) = NULL;
> +	char *len_rx __free(kfree) = NULL;
> +	char *pkt_rx __free(kfree) = NULL;

Have you considered pre-allocating rx and tx buffers instead of doing
these allocations in the interrupt handler? You can probably have tx
buffer as part of apple_z2 structure annotated as ____cacheline_aligned,
and rx allocated separately (depending on how large it is).

> +
> +	spi_message_init(&msg);
> +	memset(&xfer, 0, sizeof(xfer));
> +	len_cmd = kzalloc(sizeof(*len_cmd), GFP_KERNEL);
> +	len_rx = kzalloc(16, GFP_KERNEL);
> +	if (!len_cmd || !len_rx)
> +		return -ENOMEM;
> +
> +	len_cmd->cmd = APPLE_Z2_CMD_READ_INTERRUPT_DATA;
> +	len_cmd->counter = z2->counter + 1;
> +	len_cmd->checksum = cpu_to_le16(APPLE_Z2_CMD_READ_INTERRUPT_DATA + 1 + z2->counter);
> +	z2->counter = 1 - z2->counter;

Is this toggling between 1 and 0? Should it be "counter = !counter"? And
is there better name than counter?

> +	xfer.tx_buf = len_cmd;
> +	xfer.rx_buf = len_rx;
> +	xfer.len = sizeof(*len_cmd);
> +
> +	spi_message_add_tail(&xfer, &msg);
> +	error = spi_sync(z2->spidev, &msg);
> +	if (error)
> +		return error;
> +
> +	pkt_len = (get_unaligned_le16(len_rx + 1) + 8) & (-4);
> +	pkt_rx = kzalloc(pkt_len, GFP_KERNEL);
> +	if (!pkt_rx)
> +		return -ENOMEM;
> +
> +	spi_message_init(&msg);
> +	memset(&xfer, 0, sizeof(xfer));
> +	xfer.rx_buf = pkt_rx;
> +	xfer.len = pkt_len;
> +
> +	spi_message_add_tail(&xfer, &msg);
> +	error = spi_sync(z2->spidev, &msg);
> +
> +	if (!error)
> +		apple_z2_parse_touches(z2, pkt_rx + 5, pkt_len - 5);
> +
> +	return error;

The preferred form is:

	error = spi_sync(...);
	if (error)
		return error;

	apple_z2_parse_touches(...);

	return 0;

> +}
> +
> +static irqreturn_t apple_z2_irq(int irq, void *data)
> +{
> +	struct spi_device *spi = data;
> +	struct apple_z2 *z2 = spi_get_drvdata(spi);
> +
> +	if (unlikely(!z2->booted))
> +		complete(&z2->boot_irq);
> +	else
> +		apple_z2_read_packet(z2);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int apple_z2_build_cal_blob(struct apple_z2 *z2, u32 address, size_t cal_size, char *data)
> +{
> +	u16 len_words = (cal_size + 3) / 4;
> +	u32 checksum = 0;
> +	u16 checksum_hdr = 0;
> +	int i;
> +	struct apple_z2_hbpp_blob_hdr *hdr;
> +	int error;
> +
> +	hdr = (struct apple_z2_hbpp_blob_hdr *)data;
> +	hdr->cmd = cpu_to_le16(APPLE_Z2_HBPP_CMD_BLOB);
> +	hdr->len = cpu_to_le16(len_words);
> +	hdr->addr = cpu_to_le32(address);
> +
> +	for (i = 2; i < 8; i++)
> +		checksum_hdr += data[i];
> +
> +	hdr->checksum = cpu_to_le16(checksum_hdr);
> +	error = device_property_read_u8_array(&z2->spidev->dev, CAL_PROP_NAME, data + 10, cal_size);

What is 10? Can we have a #define for it?

> +	if (error < 0)

Does device_property_read_u8_array() return positive values on success?
If not then just "if (error)". Same for the rest of the checks.

> +		return error;
> +
> +	for (i = 0; i < cal_size; i++)
> +		checksum += data[i + 10];
> +
> +	put_unaligned_le32(checksum, data + cal_size + 10);
> +	return 0;
> +}
> +
> +static int apple_z2_send_firmware_blob(struct apple_z2 *z2, const char *data, u32 size, u8 bpw)
> +{
> +	struct spi_message msg;
> +	struct spi_transfer blob_xfer, ack_xfer;
> +	int error;
> +	char *int_ack __free(kfree) = NULL;
> +
> +	int_ack = kzalloc(2, GFP_KERNEL);
> +	if (!int_ack)
> +		return -ENOMEM;
> +	int_ack[0] = 0x1a;
> +	int_ack[1] = 0xa1;
> +
> +	spi_message_init(&msg);
> +	memset(&blob_xfer, 0, sizeof(blob_xfer));
> +	memset(&ack_xfer, 0, sizeof(ack_xfer));
> +
> +	blob_xfer.tx_buf = data;
> +	blob_xfer.len = size;
> +	blob_xfer.bits_per_word = bpw;
> +	spi_message_add_tail(&blob_xfer, &msg);
> +
> +	ack_xfer.tx_buf = int_ack;
> +	ack_xfer.len = 2;
> +	spi_message_add_tail(&ack_xfer, &msg);
> +
> +	reinit_completion(&z2->boot_irq);
> +	error = spi_sync(z2->spidev, &msg);
> +	if (error)
> +		return error;
> +	wait_for_completion_timeout(&z2->boot_irq, msecs_to_jiffies(20));
> +	return 0;
> +}
> +
> +static int apple_z2_upload_firmware(struct apple_z2 *z2)
> +{
> +	const struct firmware *fw __free(firmware) = NULL;

Please keep __free() annotated definitions close to the site of first
use. In this case directly above call to request_firmware().

> +	struct apple_z2_fw_hdr *fw_hdr;
> +	size_t fw_idx = sizeof(struct apple_z2_fw_hdr);
> +	int error;
> +	u32 load_cmd;
> +	u32 size;
> +	u32 address;
> +	char *data;
> +	u8 bits_per_word;
> +	size_t cal_size;
> +	error = request_firmware(&fw, z2->fw_name, &z2->spidev->dev);
> +	if (error) {
> +		dev_err(&z2->spidev->dev, "unable to load firmware");
> +		return error;
> +	}
> +
> +	fw_hdr = (struct apple_z2_fw_hdr *)fw->data;

You are losing constness think.

> +	if (le32_to_cpu(fw_hdr->magic) != APPLE_Z2_FW_MAGIC || le32_to_cpu(fw_hdr->version) != 1) {
> +		dev_err(&z2->spidev->dev, "invalid firmware header");
> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * This will interrupt the upload half-way if the file is malformed
> +	 * As the device has no non-volatile storage to corrupt, and gets reset
> +	 * on boot anyway, this is fine.
> +	 */
> +	while (fw_idx < fw->size) {
> +		if (fw->size - fw_idx < 8) {
> +			dev_err(&z2->spidev->dev, "firmware malformed");
> +			return -EINVAL;
> +		}
> +
> +		load_cmd = le32_to_cpu(*(__le32 *)(fw->data + fw_idx));
> +		fw_idx += 4;

sizeof(u32)?

> +		if (load_cmd == LOAD_COMMAND_INIT_PAYLOAD || load_cmd == LOAD_COMMAND_SEND_BLOB) {
> +			size = le32_to_cpu(*(__le32 *)(fw->data + fw_idx));
> +			fw_idx += 4;
> +			if (fw->size - fw_idx < size) {
> +				dev_err(&z2->spidev->dev, "firmware malformed");
> +				return -EINVAL;
> +			}
> +			bits_per_word = load_cmd == LOAD_COMMAND_SEND_BLOB ? 16 : 8;
> +			error = apple_z2_send_firmware_blob(z2, fw->data + fw_idx,
> +							    size, bits_per_word);
> +			if (error)
> +				return error;
> +			fw_idx += size;
> +		} else if (load_cmd == 2) {
> +			address = le32_to_cpu(*(u32 *)(fw->data + fw_idx));
> +			fw_idx += 4;
> +			cal_size = device_property_count_u8(&z2->spidev->dev, CAL_PROP_NAME);
> +			if (cal_size != 0) {
> +				size = cal_size + sizeof(struct apple_z2_hbpp_blob_hdr) + 4;
> +				data = kzalloc(size, GFP_KERNEL);
> +				error = apple_z2_build_cal_blob(z2, address, cal_size, data);
> +				if (!error)
> +					error = apple_z2_send_firmware_blob(z2, data, size, 16);
> +				kfree(data);
> +				if (error)
> +					return error;
> +			}
> +		} else {
> +			dev_err(&z2->spidev->dev, "firmware malformed");
> +			return -EINVAL;
> +		}
> +		if (fw_idx % 4 != 0)
> +			fw_idx += 4 - (fw_idx % 4);
> +	}
> +
> +
> +	z2->booted = 1;
> +	apple_z2_read_packet(z2);
> +	return 0;
> +}
> +
> +static int apple_z2_boot(struct apple_z2 *z2)
> +{
> +	int timeout;
> +	int error;
> +
> +	enable_irq(z2->spidev->irq);
> +	gpiod_direction_output(z2->reset_gpio, 0);
> +	timeout = wait_for_completion_timeout(&z2->boot_irq, msecs_to_jiffies(20));
> +	if (timeout == 0)
> +		return -ETIMEDOUT;
> +
> +	error = apple_z2_upload_firmware(z2);
> +	if (error) {
> +		gpiod_direction_output(z2->reset_gpio, 1);
> +		disable_irq(z2->spidev->irq);
> +	}
> +	return error;
> +}
> +
> +static int apple_z2_probe(struct spi_device *spi)
> +{
> +	struct device *dev = &spi->dev;
> +	struct apple_z2 *z2;
> +	int error;
> +
> +	z2 = devm_kzalloc(dev, sizeof(*z2), GFP_KERNEL);
> +	if (!z2)
> +		return -ENOMEM;
> +
> +	z2->spidev = spi;
> +	init_completion(&z2->boot_irq);
> +	spi_set_drvdata(spi, z2);
> +
> +	z2->reset_gpio = devm_gpiod_get_index(dev, "reset", 0, 0);
> +	if (IS_ERR(z2->reset_gpio))
> +		return dev_err_probe(dev, PTR_ERR(z2->reset_gpio), "unable to get reset");
> +
> +	error = devm_request_threaded_irq(dev, z2->spidev->irq, NULL,
> +					apple_z2_irq, IRQF_ONESHOT | IRQF_NO_AUTOEN,
> +					"apple-z2-irq", spi);
> +	if (error < 0)
> +		return dev_err_probe(dev, z2->spidev->irq, "unable to request irq");
> +
> +	error = device_property_read_string(dev, "firmware-name", &z2->fw_name);
> +	if (error)
> +		return dev_err_probe(dev, error, "unable to get firmware name");
> +
> +	z2->input_dev = devm_input_allocate_device(dev);
> +	if (!z2->input_dev)
> +		return -ENOMEM;
> +	z2->input_dev->name = (char *)spi_get_device_id(spi)->driver_data;
> +	z2->input_dev->phys = "apple_z2";
> +	z2->input_dev->id.bustype = BUS_SPI;
> +
> +	/* Allocate the axes before setting from DT */
> +	input_set_abs_params(z2->input_dev, ABS_MT_POSITION_X, 0, 0, 0, 0);
> +	input_set_abs_params(z2->input_dev, ABS_MT_POSITION_Y, 0, 0, 0, 0);
> +	touchscreen_parse_properties(z2->input_dev, true, &z2->props);
> +	input_abs_set_res(z2->input_dev, ABS_MT_POSITION_X, 100);
> +	input_abs_set_res(z2->input_dev, ABS_MT_POSITION_Y, 100);
> +	input_set_abs_params(z2->input_dev, ABS_MT_WIDTH_MAJOR, 0, 65535, 0, 0);
> +	input_set_abs_params(z2->input_dev, ABS_MT_WIDTH_MINOR, 0, 65535, 0, 0);
> +	input_set_abs_params(z2->input_dev, ABS_MT_TOUCH_MAJOR, 0, 65535, 0, 0);
> +	input_set_abs_params(z2->input_dev, ABS_MT_TOUCH_MINOR, 0, 65535, 0, 0);
> +	input_set_abs_params(z2->input_dev, ABS_MT_ORIENTATION, -32768, 32767, 0, 0);
> +
> +	input_set_drvdata(z2->input_dev, z2);
> +
> +	error = input_mt_init_slots(z2->input_dev, 256, INPUT_MT_DIRECT);
> +	if (error < 0)
> +		return dev_err_probe(dev, error, "unable to initialize multitouch slots");
> +
> +	error = input_register_device(z2->input_dev);
> +	if (error < 0)
> +		return dev_err_probe(dev, error, "unable to register input device");
> +
> +	/* Reset the device on boot */
> +	gpiod_direction_output(z2->reset_gpio, 1);
> +	usleep_range(5000, 10000);
> +	return apple_z2_boot(z2);

	error = apple_z2_boot(z2);
	if (error)
		return error;

	return 0;

> +}
> +
> +static void apple_z2_shutdown(struct spi_device *spi)
> +{
> +	struct apple_z2 *z2 = spi_get_drvdata(spi);
> +
> +	disable_irq(z2->spidev->irq);
> +	gpiod_direction_output(z2->reset_gpio, 1);
> +	z2->booted = 0;
> +}
> +
> +static int apple_z2_suspend(struct device *dev)
> +{
> +	apple_z2_shutdown(to_spi_device(dev));
> +	return 0;
> +}
> +
> +static int apple_z2_resume(struct device *dev)
> +{
> +	struct apple_z2 *z2 = spi_get_drvdata(to_spi_device(dev));
> +
> +	return apple_z2_boot(z2);
> +}
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(apple_z2_pm, apple_z2_suspend, apple_z2_resume);
> +
> +static const struct of_device_id apple_z2_of_match[] = {
> +	{ .compatible = "apple,j293-touchbar" },
> +	{ .compatible = "apple,j493-touchbar" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, apple_z2_of_match);
> +
> +static struct spi_device_id apple_z2_of_id[] = {
> +	{ .name = "j293-touchbar", .driver_data = (kernel_ulong_t)"MacBookPro17,1 Touch Bar" },
> +	{ .name = "j493-touchbar", .driver_data = (kernel_ulong_t)"Mac14,7 Touch Bar" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(spi, apple_z2_of_id);
> +
> +static struct spi_driver apple_z2_driver = {
> +	.driver = {
> +		.name	= "apple-z2",
> +		.pm	= pm_sleep_ptr(&apple_z2_pm),
> +		.of_match_table = apple_z2_of_match,
> +	},
> +	.id_table = apple_z2_of_id,
> +	.probe    = apple_z2_probe,
> +	.remove   = apple_z2_shutdown,

Purring the device into reset state before tearing down interrupt
handler, etc, may lead to weird errors. Why do you need to do this on
removal instead of letting devm tear down the device?

> +	.shutdown = apple_z2_shutdown,

Are you sure you need shutdown? Why?

> +};
> +
> +module_spi_driver(apple_z2_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_FIRMWARE("apple/dfrmtfw-*.bin");
> 
> -- 
> 2.47.1
> 
> 

Thanks.

-- 
Dmitry


From Frank.Li at nxp.com  Tue Dec  3 15:27:15 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 03 Dec 2024 18:27:15 -0500
Subject: [PATCH v7 1/2] PCI: Add enable_device() and disable_device()
 callbacks for bridges
In-Reply-To: <20241203-imx95_lut-v7-0-d0cd6293225e@nxp.com>
References: <20241203-imx95_lut-v7-0-d0cd6293225e@nxp.com>
Message-ID: <20241203-imx95_lut-v7-1-d0cd6293225e@nxp.com>

Some PCIe host bridges require special handling when enabling or disabling
PCIe Endpoints. For example, the i.MX95 platform has a lookup table to map
Requester IDs to StreamIDs, which are used by the SMMU and MSI controller
to identify the source of DMA accesses.

Without this mapping, DMA accesses may target unintended memory, which
would corrupt memory or read the wrong data.

Add a host bridge .enable_device() hook the imx6 driver can use to
configure the Requester ID to StreamID mapping. The hardware table isn't
big enough to map all possible Requester IDs, so this hook may fail if no
table space is available. In that case, return failure from
pci_enable_device().

It might make more sense to make pci_set_master() decline to enable bus
mastering and return failure, but it currently doesn't have a way to return
failure.

Reviewed-by: Marc Zyngier <maz at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v5 to v6
- Add Marc testedby and Reviewed-by tag
- Add Mani's acked tag

Change from v4 to v5
- Add two static help functions
int pci_host_bridge_enable_device(dev);
void pci_host_bridge_disable_device(dev);
- remove tags because big change
Acked-by: Bjorn Helgaas <bhelgaas at google.com>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>

Change from v3 to v4
- Add Bjorn's ack tag

Change from v2 to v3
- use Bjorn suggest's commit message.
- call disable_device() when error happen.

Change from v1 to v2
- move enable(disable)device ops to pci_host_bridge
---
 drivers/pci/pci.c   | 36 +++++++++++++++++++++++++++++++++++-
 include/linux/pci.h |  2 ++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0b29ec6e8e5e2..773ca3cbd3221 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2059,6 +2059,28 @@ int __weak pcibios_enable_device(struct pci_dev *dev, int bars)
 	return pci_enable_resources(dev, bars);
 }
 
+static int pci_host_bridge_enable_device(struct pci_dev *dev)
+{
+	struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus);
+	int err;
+
+	if (host_bridge && host_bridge->enable_device) {
+		err = host_bridge->enable_device(host_bridge, dev);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static void pci_host_bridge_disable_device(struct pci_dev *dev)
+{
+	struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus);
+
+	if (host_bridge && host_bridge->disable_device)
+		host_bridge->disable_device(host_bridge, dev);
+}
+
 static int do_pci_enable_device(struct pci_dev *dev, int bars)
 {
 	int err;
@@ -2074,9 +2096,13 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
 	if (bridge)
 		pcie_aspm_powersave_config_link(bridge);
 
+	err = pci_host_bridge_enable_device(dev);
+	if (err)
+		return err;
+
 	err = pcibios_enable_device(dev, bars);
 	if (err < 0)
-		return err;
+		goto err_enable;
 	pci_fixup_device(pci_fixup_enable, dev);
 
 	if (dev->msi_enabled || dev->msix_enabled)
@@ -2091,6 +2117,12 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
 	}
 
 	return 0;
+
+err_enable:
+	pci_host_bridge_disable_device(dev);
+
+	return err;
+
 }
 
 /**
@@ -2274,6 +2306,8 @@ void pci_disable_device(struct pci_dev *dev)
 	if (atomic_dec_return(&dev->enable_cnt) != 0)
 		return;
 
+	pci_host_bridge_disable_device(dev);
+
 	do_pci_disable_device(dev);
 
 	dev->is_busmaster = 0;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index db9b47ce3eefd..bcbef004dd561 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -595,6 +595,8 @@ struct pci_host_bridge {
 	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
 	int (*map_irq)(const struct pci_dev *, u8, u8);
 	void (*release_fn)(struct pci_host_bridge *);
+	int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
+	void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
 	void		*release_data;
 	unsigned int	ignore_reset_delay:1;	/* For entire hierarchy */
 	unsigned int	no_ext_tags:1;		/* No Extended Tags */

-- 
2.34.1



From Frank.Li at nxp.com  Tue Dec  3 15:27:14 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 03 Dec 2024 18:27:14 -0500
Subject: [PATCH v7 0/2] PCI: add enabe(disable)_device() hook for bridge
Message-ID: <20241203-imx95_lut-v7-0-d0cd6293225e@nxp.com>

Some system's IOMMU stream(master) ID bits(such as 6bits) less than
pci_device_id (16bit). It needs add hardware configuration to enable
pci_device_id to stream ID convert.

https://lore.kernel.org/imx/20240622173849.GA1432357 at bhelgaas/
This ways use pcie bus notifier (like apple pci controller), when new PCIe
device added, bus notifier will call register specific callback to handle
look up table (LUT) configuration.

https://lore.kernel.org/imx/20240429150842.GC1709920-robh at kernel.org/
which parse dt's 'msi-map' and 'iommu-map' property to static config LUT
table (qcom use this way). This way is rejected by DT maintainer Rob.

Above ways can resolve LUT take or stream id out of usage the problem. If
there are not enough stream id resource, not error return, EP hardware
still issue DMA to do transfer, which may transfer to wrong possition.

Add enable(disable)_device() hook for bridge can return error when not
enough resource, and PCI device can't enabled.

Basicallly this version can match Bjorn's requirement:
1: simple, because it is rare that there are no LUT resource.
2: EP driver probe failure when no LUT, but lspci can see such device.

[    2.164415] nvme nvme0: pci function 0000:01:00.0
[    2.169142] pci 0000:00:00.0: Error enabling bridge (-1), continuing
[    2.175654] nvme 0000:01:00.0: probe with driver nvme failed with error -12

> lspci
0000:00:00.0 PCI bridge: Philips Semiconductors Device 0000
0000:01:00.0 Non-Volatile memory controller: Micron Technology Inc 2100AI NVMe SSD [Nitro] (rev 03)

To: Bjorn Helgaas <bhelgaas at google.com>
To: Richard Zhu <hongxing.zhu at nxp.com>
To: Lucas Stach <l.stach at pengutronix.de>
To: Lorenzo Pieralisi <lpieralisi at kernel.org>
To: Krzysztof Wilczy?ski <kw at linux.com>
To: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
To: Rob Herring <robh 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>
Cc: linux-pci at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: imx at lists.linux.dev
Cc: Frank.li at nxp.com \
Cc: alyssa at rosenzweig.io \
Cc: bpf at vger.kernel.org \
Cc: broonie at kernel.org \
Cc: jgg at ziepe.ca \
Cc: joro at 8bytes.org \
Cc: l.stach at pengutronix.de \
Cc: lgirdwood at gmail.com \
Cc: maz at kernel.org \
Cc: p.zabel at pengutronix.de \
Cc: robin.murphy at arm.com \
Cc: will at kernel.org \
Cc: Robin Murphy <robin.murphy at arm.com>
Cc: Marc Zyngier <maz at kernel.org>

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Changes in v7:
- Rebase v6.13-rc1
- Update patch 2 according to mani's feedback
- Link to v6: https://lore.kernel.org/r/20241118-imx95_lut-v6-0-a2951ba13347 at nxp.com

Changes in v6:
- Bjorn give review tags at v4, but v5 have big change, drop Bjorn's review
tag.
- Add back Marc Zyngier't review and test tags
- Add mani's ack at first patch
- Mini change for patch 2 according to mani's feedback
- Link to v5: https://lore.kernel.org/r/20241104-imx95_lut-v5-0-feb972f3f13b at nxp.com

Changes in v5:
- Add help function of pci_bridge_enable(disable)_device
- Because big change, removed Bjorn's review tags and have not
added
Marc Zyngier't review and test tags
- Fix pci-imx6.c according to Mani's feedback
- Link to v4: https://lore.kernel.org/r/20241101-imx95_lut-v4-0-0fdf9a2fe754 at nxp.com

Changes in v4:
- Add Bjorn Helgaas review tag for patch1
- check 'target' value for patch2
- detail see each patches
- Link to v3: https://lore.kernel.org/r/20241024-imx95_lut-v3-0-7509c9bbab86 at nxp.com

Changes in v3:
- disable_device when error happen
- use target for of_map_id
- Check if rid already in lut table when enable deviced
- Link to v2: https://lore.kernel.org/r/20240930-imx95_lut-v2-0-3b6467ba539a at nxp.com

Changes in v2:
- see each patch
- Link to v1: https://lore.kernel.org/r/20240926-imx95_lut-v1-0-d0c62087dbab at nxp.com

---
Frank Li (2):
      PCI: Add enable_device() and disable_device() callbacks for bridges
      PCI: imx6: Add IOMMU and ITS MSI support for i.MX95

 drivers/pci/controller/dwc/pci-imx6.c | 183 +++++++++++++++++++++++++++++++++-
 drivers/pci/pci.c                     |  36 ++++++-
 include/linux/pci.h                   |   2 +
 3 files changed, 219 insertions(+), 2 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20240926-imx95_lut-1c68222e0944

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Tue Dec  3 15:27:16 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 03 Dec 2024 18:27:16 -0500
Subject: [PATCH v7 2/2] PCI: imx6: Add IOMMU and ITS MSI support for i.MX95
In-Reply-To: <20241203-imx95_lut-v7-0-d0cd6293225e@nxp.com>
References: <20241203-imx95_lut-v7-0-d0cd6293225e@nxp.com>
Message-ID: <20241203-imx95_lut-v7-2-d0cd6293225e@nxp.com>

For the i.MX95, configuration of a LUT is necessary to convert Bus Device
Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
This involves examining the msi-map and smmu-map to ensure consistent
mapping of PCI BDF to the same stream IDs. Subsequently, LUT-related
registers are configured. In the absence of an msi-map, the built-in MSI
controller is utilized as a fallback.

Register a PCI bus callback function to handle enable_device() and
disable_device() operations, setting up the LUT whenever a new PCI device
is enabled.

Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v5 to v6
- change comment rid to RID
- some mini change according to mani's feedback

Change from v4 to v5
- rework commt message
- add comment for mutex
- s/reqid/rid/
- keep only one loop when enable lut
- add warning when try to add duplicate rid
- Replace hardcode 0xffff with IMX95_PE0_LUT_MASK
- Fix some error message

Change from v3 to v4
- Check target value at of_map_id().
- of_node_put() for target.
- add case for msi-map exist, but rid entry is not exist.

Change from v2 to v3
- Use the "target" argument of of_map_id()
- Check if rid already in lut table when enable device

change from v1 to v2
- set callback to pci_host_bridge instead pci->ops.
---
 drivers/pci/controller/dwc/pci-imx6.c | 183 +++++++++++++++++++++++++++++++++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index c8d5c90aa4d45..ac5caa7b05075 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -55,6 +55,22 @@
 #define IMX95_PE0_GEN_CTRL_3			0x1058
 #define IMX95_PCIE_LTSSM_EN			BIT(0)
 
+#define IMX95_PE0_LUT_ACSCTRL			0x1008
+#define IMX95_PEO_LUT_RWA			BIT(16)
+#define IMX95_PE0_LUT_ENLOC			GENMASK(4, 0)
+
+#define IMX95_PE0_LUT_DATA1			0x100c
+#define IMX95_PE0_LUT_VLD			BIT(31)
+#define IMX95_PE0_LUT_DAC_ID			GENMASK(10, 8)
+#define IMX95_PE0_LUT_STREAM_ID			GENMASK(5, 0)
+
+#define IMX95_PE0_LUT_DATA2			0x1010
+#define IMX95_PE0_LUT_REQID			GENMASK(31, 16)
+#define IMX95_PE0_LUT_MASK			GENMASK(15, 0)
+
+#define IMX95_SID_MASK				GENMASK(5, 0)
+#define IMX95_MAX_LUT				32
+
 #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
 
 enum imx_pcie_variants {
@@ -87,6 +103,7 @@ enum imx_pcie_variants {
  * workaround suspend resume on some devices which are affected by this errata.
  */
 #define IMX_PCIE_FLAG_BROKEN_SUSPEND		BIT(9)
+#define IMX_PCIE_FLAG_HAS_LUT			BIT(10)
 
 #define imx_check_flag(pci, val)	(pci->drvdata->flags & val)
 
@@ -139,6 +156,9 @@ struct imx_pcie {
 	struct device		*pd_pcie_phy;
 	struct phy		*phy;
 	const struct imx_pcie_drvdata *drvdata;
+
+	/* Ensure that only one device's LUT is configured at any given time */
+	struct mutex		lock;
 };
 
 /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -930,6 +950,159 @@ static void imx_pcie_stop_link(struct dw_pcie *pci)
 	imx_pcie_ltssm_disable(dev);
 }
 
+static int imx_pcie_add_lut(struct imx_pcie *imx_pcie, u16 rid, u8 sid)
+{
+	struct dw_pcie *pci = imx_pcie->pci;
+	struct device *dev = pci->dev;
+	u32 data1, data2;
+	int free = -1;
+	int i;
+
+	if (sid >= 64) {
+		dev_err(dev, "Invalid SID for index %d\n", sid);
+		return -EINVAL;
+	}
+
+	guard(mutex)(&imx_pcie->lock);
+
+	/*
+	 * Iterate through all LUT entries to check for duplicate RID and
+	 * identify the first available entry. Configure this available entry
+	 * immediately after verification to avoid rescanning it.
+	 */
+	for (i = 0; i < IMX95_MAX_LUT; i++) {
+		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
+		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, &data1);
+
+		if (!(data1 & IMX95_PE0_LUT_VLD)) {
+			if (free < 0)
+				free = i;
+			continue;
+		}
+
+		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
+
+		/* Do not add duplicate RID */
+		if (rid == FIELD_GET(IMX95_PE0_LUT_REQID, data2)) {
+			dev_warn(dev, "Existing LUT entry available for RID (%d)", rid);
+			return 0;
+		}
+	}
+
+	if (free < 0) {
+		dev_err(dev, "LUT entry is not available\n");
+		return -ENOSPC;
+	}
+
+	data1 = FIELD_PREP(IMX95_PE0_LUT_DAC_ID, 0);
+	data1 |= FIELD_PREP(IMX95_PE0_LUT_STREAM_ID, sid);
+	data1 |= IMX95_PE0_LUT_VLD;
+	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, data1);
+
+	data2 = IMX95_PE0_LUT_MASK; /* Match all bits of RID */
+	data2 |= FIELD_PREP(IMX95_PE0_LUT_REQID, rid);
+	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, data2);
+
+	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, free);
+
+	return 0;
+}
+
+static void imx_pcie_remove_lut(struct imx_pcie *imx_pcie, u16 rid)
+{
+	u32 data2;
+	int i;
+
+	guard(mutex)(&imx_pcie->lock);
+
+	for (i = 0; i < IMX95_MAX_LUT; i++) {
+		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
+		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
+		if (FIELD_GET(IMX95_PE0_LUT_REQID, data2) == rid) {
+			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, 0);
+			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, 0);
+			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i);
+
+			break;
+		}
+	}
+}
+
+static int imx_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
+{
+	struct imx_pcie *imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
+	u32 sid_i, sid_m, rid = pci_dev_id(pdev);
+	struct device_node *target;
+	struct device *dev;
+	int err_i, err_m;
+
+	dev = imx_pcie->pci->dev;
+
+	target = NULL;
+	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
+	if (target)
+		of_node_put(target);
+	else
+		err_i = -EINVAL;
+
+	target = NULL;
+	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
+
+	/*
+	 * Return failure if msi-map exist and no entry for RID because dwc common
+	 * driver will skip setting up built-in MSI controller if msi-map existed.
+	 *
+	 *   err_m      target
+	 *	0	NULL		Return failure, function not work.
+	 *      !0      NULL		msi-map not exist, use built-in MSI.
+	 *	0	!NULL		Find one entry.
+	 *	!0	!NULL		Invalidate case.
+	 */
+	if (!err_m && !target)
+		return -EINVAL;
+	else if (target)
+		of_node_put(target); /* Find entry for RID in msi-map */
+
+	/*
+	 * msi-map        iommu-map
+	 *   Y                Y            ITS + SMMU, require the same sid
+	 *   Y                N            ITS
+	 *   N                Y            DWC MSI Ctrl + SMMU
+	 *   N                N            DWC MSI Ctrl
+	 */
+	if (!err_i && !err_m)
+		if ((sid_i & IMX95_SID_MASK) != (sid_m & IMX95_SID_MASK)) {
+			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
+			return -EINVAL;
+		}
+
+	/*
+	 * Both iommu-map and msi-map not exist, use dwc built-in MSI
+	 * controller, do nothing here.
+	 */
+	if (err_i && err_m)
+		return 0;
+
+	if (!err_i)
+		return imx_pcie_add_lut(imx_pcie, rid, sid_i);
+	else if (!err_m)
+		/*
+		 * Hardware auto add 2 bits controller id ahead of stream ID,
+		 * so mask this 2bits to get stream ID.
+		 */
+		return imx_pcie_add_lut(imx_pcie, rid, sid_m & IMX95_SID_MASK);
+
+	return 0;
+}
+
+static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
+{
+	struct imx_pcie *imx_pcie;
+
+	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
+	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
+}
+
 static int imx_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -946,6 +1119,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
 		}
 	}
 
+	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
+		pp->bridge->enable_device = imx_pcie_enable_device;
+		pp->bridge->disable_device = imx_pcie_disable_device;
+	}
+
 	imx_pcie_assert_core_reset(imx_pcie);
 
 	if (imx_pcie->drvdata->init_phy)
@@ -1330,6 +1508,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
 	imx_pcie->pci = pci;
 	imx_pcie->drvdata = of_device_get_match_data(dev);
 
+	mutex_init(&imx_pcie->lock);
+
 	/* Find the PHY if one is defined, only imx7d uses it */
 	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
 	if (np) {
@@ -1627,7 +1807,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
 	},
 	[IMX95] = {
 		.variant = IMX95,
-		.flags = IMX_PCIE_FLAG_HAS_SERDES,
+		.flags = IMX_PCIE_FLAG_HAS_SERDES |
+			 IMX_PCIE_FLAG_HAS_LUT,
 		.clk_names = imx8mq_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
 		.ltssm_off = IMX95_PE0_GEN_CTRL_3,

-- 
2.34.1



From rosenp at gmail.com  Tue Dec  3 15:36:32 2024
From: rosenp at gmail.com (Rosen Penev)
Date: Tue,  3 Dec 2024 15:36:32 -0800
Subject: [PATCH] arm64: dts: bcm4908: nvmem-layout conversion
Message-ID: <20241203233632.184861-1-rosenp@gmail.com>

nvmem-layout is a more flexible replacement for nvmem-cells.

Signed-off-by: Rosen Penev <rosenp at gmail.com>
---
 .../dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts   | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

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 999d93730240..a5f9ec92bd5e 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
@@ -144,16 +144,20 @@ partitions {
 		#size-cells = <1>;
 
 		partition at 0 {
-			compatible = "nvmem-cells";
 			label = "cferom";
 			reg = <0x0 0x100000>;
-
 			#address-cells = <1>;
 			#size-cells = <1>;
 			ranges = <0 0x0 0x100000>;
 
-			base_mac_addr: mac at 106a0 {
-				reg = <0x106a0 0x6>;
+			nvmem-layout {
+				compatible = "fixed-layout";
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				base_mac_addr: mac at 106a0 {
+					reg = <0x106a0 0x6>;
+				};
 			};
 		};
 
-- 
2.47.0



From rosenp at gmail.com  Tue Dec  3 15:37:17 2024
From: rosenp at gmail.com (Rosen Penev)
Date: Tue,  3 Dec 2024 15:37:17 -0800
Subject: [PATCH] arm64: dts: armada-3720-gl-mv1000: use nvmem-layout
Message-ID: <20241203233717.185016-1-rosenp@gmail.com>

nvmem-layout is a more flexible replacement for nvmem-cells.

Signed-off-by: Rosen Penev <rosenp at gmail.com>
---
 .../dts/marvell/armada-3720-gl-mv1000.dts     | 30 +++++++++----------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts b/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
index 56930f2ce481..7b801b60862d 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
@@ -98,10 +98,24 @@ partition at f0000 {
 				reg = <0xf0000 0x8000>;
 			};
 
-			factory: partition at f8000 {
+			partition at f8000 {
 				label = "factory";
 				reg = <0xf8000 0x8000>;
 				read-only;
+
+				nvmem-layout {
+					compatible = "fixed-layout";
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					macaddr_factory_0: macaddr at 0 {
+						reg = <0x0 0x6>;
+					};
+
+					macaddr_factory_6: macaddr at 6 {
+						reg = <0x6 0x6>;
+					};
+				};
 			};
 
 			partition at 100000 {
@@ -221,17 +235,3 @@ fixed-link {
 		full-duplex;
 	};
 };
-
-&factory {
-	compatible = "nvmem-cells";
-	#address-cells = <1>;
-	#size-cells = <1>;
-
-	macaddr_factory_0: macaddr at 0 {
-		reg = <0x0 0x6>;
-	};
-
-	macaddr_factory_6: macaddr at 6 {
-		reg = <0x6 0x6>;
-	};
-};
-- 
2.47.0



From andrew at lunn.ch  Tue Dec  3 15:44:35 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 4 Dec 2024 00:44:35 +0100
Subject: [PATCH] arm64: dts: armada-3720-gl-mv1000: use nvmem-layout
In-Reply-To: <20241203233717.185016-1-rosenp@gmail.com>
References: <20241203233717.185016-1-rosenp@gmail.com>
Message-ID: <560369d3-e37c-4c44-86df-a0b81c899f9a@lunn.ch>

On Tue, Dec 03, 2024 at 03:37:17PM -0800, Rosen Penev wrote:
> nvmem-layout is a more flexible replacement for nvmem-cells.

Do you have this reference board? How did you test this patch?

	Andrew


From skhan at linuxfoundation.org  Tue Dec  3 16:23:56 2024
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Tue, 3 Dec 2024 17:23:56 -0700
Subject: [PATCH] selftests: arm coresight: sysfsmode testing
In-Reply-To: <20241129083813.3056909-1-lcherian@marvell.com>
References: <20241129083813.3056909-1-lcherian@marvell.com>
Message-ID: <115bb206-8401-4475-977d-7dd98a2b872c@linuxfoundation.org>

On 11/29/24 01:38, Linu Cherian wrote:
> Add sysfs mode selftest for ARM Coresight hardware tracer.

Please add details on what this test does in here. Include
the output from the test?

Does this test have dependencies on config? If it does, does
this test detect and skip if config isn't enabled?

> 
> Signed-off-by: Linu Cherian <lcherian at marvell.com>
> ---
>   .../drivers/hwtracing/coresight/Makefile      |   5 +
>   .../hwtracing/coresight/sysfs_test_trace.sh   | 144 ++++++++++++++++++
>   2 files changed, 149 insertions(+)
>   create mode 100644 tools/testing/selftests/drivers/hwtracing/coresight/Makefile
>   create mode 100755 tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> 
> diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/Makefile b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> new file mode 100644
> index 000000000000..7dc68ae1c0a9
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> @@ -0,0 +1,5 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +TEST_PROGS = sysfs_test_trace.sh
> +
> +include ../../../lib.mk
> diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> new file mode 100755
> index 000000000000..0d6307fff1d2
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> @@ -0,0 +1,144 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (C) 2024 Marvell.
> +
> +# Test Arm CoreSight trace capture in sysfs mode
> +# Based on tools/perf/tests/shell/test_arm_coresight.sh
> +
> +glb_err=0
> +
> +arm_cs_report() {
> +	if [ $2 != 0 ]; then
> +		echo "$1: FAIL"
> +		glb_err=$2
> +	else
> +		echo "$1: PASS"
> +	fi
> +}
> +
> +is_device_sink() {
> +	# If the node of "enable_sink" is existed under the device path, this
> +	# means the device is a sink device.
> +
> +	if [ -e "$1/enable_sink" ]; then
> +
> +		return 0
> +	else
> +		return 1
> +	fi
> +}
> +
> +# Configure sink for buffer mode
> +cfg_sink_buf_mode() {
> +	sink_dev=$1
> +	mode=$2
> +	# Set buffer mode if supported
> +	if [ -e "$sink_dev/buf_modes_available" ]; then
> +		cat $sink_dev/buf_modes_available | grep -E -q $mode
> +		if [ $? -eq 0 ]; then
> +			echo $mode > $sink_dev/buf_mode_preferred
> +			return 0
> +		fi
> +	fi
> +
> +	return 1
> +}
> +
> +run_app() {
> +
> +	taskset -c $1 dd if=/dev/urandom  of=/dev/null bs=1M count=64
> +}
> +
> +sysfs_trace() {
> +	src_dev=$1
> +	sink_dev=$2
> +	cpu=$3
> +
> +	# Enable sink device
> +	echo 1 > $sink_dev/enable_sink
> +	# Enable source device
> +	echo 1 > $src_dev/enable_source
> +
> +	# Run app to be traced
> +	run_app $cpu
> +
> +	# Read back trace data
> +	dd if=/dev/$sink_dev_name of=/tmp/tracedata
> +
> +	# Verify if read is successful
> +	err=$?
> +
> +	# Disable source device
> +	echo 0 > $src_dev/enable_source
> +
> +	# Diskable sink device
> +	echo 0 > $sink_dev/enable_sink
> +
> +	arm_cs_report "CoreSight path testing (CPU$cpu -> $sink_dev_name)" $err
> +}
> +
> +try_sysfs_trace_resrv_buf() {
> +	src_dev=$1
> +	sink_dev=$2
> +	cpu=$3
> +
> +	# Configure the resrved buffer mode if available
> +	cfg_sink_buf_mode $sink_dev "resrv"
> +	if [ $? -eq 0 ]; then
> +		echo "Running sysfs trace with resrv buf mode"
> +		sysfs_trace $src_dev $sink_dev $cpu
> +		# Restore buffer mode
> +		cfg_sink_buf_mode $sink_dev "auto"
> +		if [ $? -eq 1 ]; then
> +			echo "Failed to restore default buf mode"
> +		fi
> +	fi
> +}
> +
> +arm_cs_iterate_devices() {
> +	src_dev=$1
> +	cpu=$3
> +	for cdev in $2/connections/out\:*; do
> +
> +		# Skip testing if it's not a directory
> +		! [ -d $cdev ] && continue;
> +
> +		# Read out its symbol link file name
> +		sink_dev=`readlink -f $cdev`
> +
> +		# Extract device name from path, e.g.
> +		#   sink_dev = '/sys/devices/platform/20010000.etf/tmc_etf0'
> +		#     `> sink_dev_name = 'tmc_etf0'
> +		sink_dev_name=$(basename $sink_dev)
> +
> +		if is_device_sink $sink_dev; then
> +			# Run trace with resrv buf mode (if available)
> +			try_sysfs_trace_resrv_buf $src_dev $sink_dev $cpu
> +
> +			# Run the default mode
> +			echo "Running sysfs trace with default settings"
> +			sysfs_trace $src_dev $sink_dev $cpu
> +		fi
> +
> +		arm_cs_iterate_devices $src_dev $cdev $cpu
> +
> +	done
> +}
> +
> +arm_cs_etm_traverse_path_test() {
> +	# Iterate for every ETM device
> +	for dev in /sys/bus/event_source/devices/cs_etm/cpu*; do
> +		# Canonicalize the path
> +		dev=`readlink -f $dev`
> +
> +		# Find the ETM device belonging to which CPU
> +		cpu=`cat $dev/cpu`
> +
> +		# Use depth-first search (DFS) to iterate outputs
> +		arm_cs_iterate_devices $dev $dev $cpu
> +	done
> +}
> +
> +arm_cs_etm_traverse_path_test
> +
> +exit $glb_err

thanks,
-- Shuah


From oliver.upton at linux.dev  Tue Dec  3 16:38:54 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 16:38:54 -0800
Subject: [PATCH v2] KVM: arm/arm64: vgic-its: Add error handling in vgic_its_cache_translation
In-Reply-To: <20241130144952.23729-1-keisuke.nishimura@inria.fr>
References: <20241130144952.23729-1-keisuke.nishimura@inria.fr>
Message-ID: <173327270647.1289915.12344203563872763499.b4-ty@linux.dev>

On Sat, 30 Nov 2024 15:49:53 +0100, Keisuke Nishimura wrote:
> The return value of xa_store() needs to be checked. This fix adds an
> error handling path that resolves the kref inconsistency on failure. As
> suggested by Oliver Upton, this function does not return the error code
> intentionally because the translation cache is best effort.
> 
> 

Applied to fixes, thanks!

[1/1] KVM: arm/arm64: vgic-its: Add error handling in vgic_its_cache_translation
      https://git.kernel.org/kvmarm/kvmarm/c/be7e61127422

--
Best,
Oliver


From oliver.upton at linux.dev  Tue Dec  3 16:38:55 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue,  3 Dec 2024 16:38:55 -0800
Subject: [PATCH] KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden
In-Reply-To: <20241203190236.505759-1-maz@kernel.org>
References: <20241203190236.505759-1-maz@kernel.org>
Message-ID: <173327270646.1289915.18344519507054696527.b4-ty@linux.dev>

On Tue, 03 Dec 2024 19:02:36 +0000, Marc Zyngier wrote:
> Catalin reports that a hypervisor lying to a guest about the size
> of the ASID field may result in unexpected issues:
> 
> - if the underlying HW does only supports 8 bit ASIDs, the ASID
>   field in a TLBI VAE1* operation is only 8 bits, and the HW will
>   ignore the other 8 bits
> 
> [...]

Applied to fixes, thanks!

[1/1] KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden
      https://git.kernel.org/kvmarm/kvmarm/c/03c7527e97f7

--
Best,
Oliver


From kuninori.morimoto.gx at renesas.com  Tue Dec  3 16:55:52 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Wed, 4 Dec 2024 00:55:52 +0000
Subject: [PATCH 0/5] arm64: renesas: Add R8A779G3 White Hawk Single support
In-Reply-To: <cover.1733156661.git.geert+renesas@glider.be>
References: <cover.1733156661.git.geert+renesas@glider.be>
Message-ID: <87jzcg1d2f.wl-kuninori.morimoto.gx@renesas.com>


Hi Geert

> This patch series adds support for the Renesas R-Car V4H ES3.0 (R8A779G3)
> SoC on the Renesas White Hawk Single board.  R-Car V4H ES3.0 (R8A779G3)
> is an updated version of R-Car V4H (R8A779G0).
> 
> I intend to queue these in renesas-devel for v6.14.
> Thanks for your comments!

Thank you for the patch-set. For all patches

Reviewed-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>

But small nitpick is that R8A779G2 is not only for ES2.0 but for ES2.x



Thank you for your help !!

Best regards
---
Kuninori Morimoto


From rosenp at gmail.com  Tue Dec  3 17:27:22 2024
From: rosenp at gmail.com (Rosen Penev)
Date: Tue, 3 Dec 2024 17:27:22 -0800
Subject: [PATCH] arm64: dts: armada-3720-gl-mv1000: use nvmem-layout
In-Reply-To: <560369d3-e37c-4c44-86df-a0b81c899f9a@lunn.ch>
References: <20241203233717.185016-1-rosenp@gmail.com> <560369d3-e37c-4c44-86df-a0b81c899f9a@lunn.ch>
Message-ID: <CAKxU2N8gVqUKmD0hj_rXwJEOL8KStNHm+O23Sww-yVT5cp2yWQ@mail.gmail.com>

On Tue, Dec 3, 2024 at 3:44?PM Andrew Lunn <andrew at lunn.ch> wrote:
>
> On Tue, Dec 03, 2024 at 03:37:17PM -0800, Rosen Penev wrote:
> > nvmem-layout is a more flexible replacement for nvmem-cells.
>
> Do you have this reference board? How did you test this patch?
Only compile time tested.

2cc3b37f5b6df8189d55d0e812d9658ce256dfec marks nvmem-cells as legacy
and most dts files have already been converted.

This is not a crazy API change that would break anything.

>
>         Andrew


From mjchen0829 at gmail.com  Tue Dec  3 18:10:13 2024
From: mjchen0829 at gmail.com (Ming-Jen Chen)
Date: Wed,  4 Dec 2024 02:10:13 +0000
Subject: [PATCH v4 1/2] input: keypad: add new keypad driver for MA35D1
In-Reply-To: <20241204021014.5083-1-mjchen0829@gmail.com>
References: <20241204021014.5083-1-mjchen0829@gmail.com>
Message-ID: <20241204021014.5083-2-mjchen0829@gmail.com>

Adds a new keypad driver for the MA35D1 platform.
The driver supports key scanning and interrupt handling.

Signed-off-by: Ming-Jen Chen <mjchen0829 at gmail.com>
---
 drivers/input/keyboard/Kconfig         |  10 +
 drivers/input/keyboard/Makefile        |   1 +
 drivers/input/keyboard/ma35d1_keypad.c | 386 +++++++++++++++++++++++++
 3 files changed, 397 insertions(+)
 create mode 100644 drivers/input/keyboard/ma35d1_keypad.c

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 721ab69e84ac..d7c0d0f4a88d 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -797,4 +797,14 @@ config KEYBOARD_CYPRESS_SF
 	  To compile this driver as a module, choose M here: the
 	  module will be called cypress-sf.
 
+config KEYBOARD_MA35D1
+	tristate "Nuvoton MA35D1 keypad driver"
+	depends on ARCH_MA35 || COMPILE_TEST
+	select INPUT_MATRIXKMAP
+	help
+	  Say Y here if you want to use Nuvoton MA35D1 keypad.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ma35d1-keypad.
+
 endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 1e0721c30709..9b858cdd1b6b 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -70,3 +70,4 @@ obj-$(CONFIG_KEYBOARD_TEGRA)		+= tegra-kbc.o
 obj-$(CONFIG_KEYBOARD_TM2_TOUCHKEY)	+= tm2-touchkey.o
 obj-$(CONFIG_KEYBOARD_TWL4030)		+= twl4030_keypad.o
 obj-$(CONFIG_KEYBOARD_XTKBD)		+= xtkbd.o
+obj-$(CONFIG_KEYBOARD_MA35D1)		+= ma35d1_keypad.o
diff --git a/drivers/input/keyboard/ma35d1_keypad.c b/drivers/input/keyboard/ma35d1_keypad.c
new file mode 100644
index 000000000000..8410f7dd2e56
--- /dev/null
+++ b/drivers/input/keyboard/ma35d1_keypad.c
@@ -0,0 +1,386 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  MA35D1 keypad driver
+ *  Copyright (C) 2024 Nuvoton Technology Corp.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/bitops.h>
+#include <linux/pm_wakeirq.h>
+
+/* Keypad Interface Registers */
+#define KPI_CONF		0x00
+#define KPI_3KCONF		0x04
+#define KPI_STATUS		0x08
+#define KPI_RSTC		0x0C
+#define KPI_KEST		0x10
+#define KPI_KPE0		0x18
+#define KPI_KPE1		0x1C
+#define KPI_KRE0		0x20
+#define KPI_KRE1		0x24
+#define KPI_PRESCALDIV		0x28
+
+/* KPI_CONF - Keypad Configuration Register */
+#define KROW			GENMASK(30, 28) /* Keypad Matrix ROW number */
+#define KCOL			GENMASK(26, 24) /* Keypad Matrix COL Number */
+#define DB_CLKSEL		GENMASK(19, 16) /* De-bounce sampling cycle selection */
+#define PRESCALE		GENMASK(15, 8)  /* Row Scan Cycle Pre-scale Value */
+#define WAKEUP			BIT(5) /* Lower Power Wakeup Enable */
+#define INTEN			BIT(3) /* Key Interrupt Enable Control */
+#define RKINTEN			BIT(2) /* Release Key Interrupt Enable */
+#define PKINTEN			BIT(1) /* Press Key Interrupt Enable Control */
+#define ENKP			BIT(0) /* Keypad Scan Enable */
+
+/* KPI_STATUS - Keypad Status Register */
+#define PKEY_INT		BIT(4) /* Press key interrupt */
+#define RKEY_INT		BIT(3) /* Release key interrupt */
+#define KEY_INT			BIT(2) /* Key Interrupt */
+#define RST_3KEY		BIT(1) /* 3-Keys Reset Flag */
+#define PDWAKE			BIT(0) /* Power Down Wakeup Flag */
+
+#define KEY_EVENT_BITS		64
+
+#define NUM_SETTINGS		12
+#define PRE_SCALE_MAX		256
+#define PRE_SCALE_DIV_MAX	256
+
+static const unsigned int debounce_values[NUM_SETTINGS] = {
+	0, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192
+};
+
+static const unsigned int debounce_register[NUM_SETTINGS] = {
+	0x0, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD
+};
+
+struct ma35d1_keypad {
+	struct clk *clk;
+	struct input_dev *input_dev;
+	void __iomem *mmio_base;
+	int irq;
+	u32 kpi_row;
+	u32 kpi_col;
+	u32 debounce_val;
+	u32 pre_scale;
+	u32 pre_scale_div;
+};
+
+static void ma35d1_keypad_scan_matrix(struct ma35d1_keypad *keypad, unsigned int status)
+{
+	struct input_dev *input_dev = keypad->input_dev;
+	u32 row_shift = get_count_order(keypad->kpi_col);
+	u32 *keymap = input_dev->keycode;
+	u32 code, key, index;
+	u32 key_event[4];
+	u64 pressed_keys = 0, released_keys = 0;
+
+	/* Read key event status */
+	key_event[0] = readl(keypad->mmio_base + KPI_KPE0);
+	key_event[1] = readl(keypad->mmio_base + KPI_KPE1);
+	key_event[2] = readl(keypad->mmio_base + KPI_KRE0);
+	key_event[3] = readl(keypad->mmio_base + KPI_KRE1);
+
+	/* Clear key event status */
+	writel(key_event[0], (keypad->mmio_base + KPI_KPE0));
+	writel(key_event[1], (keypad->mmio_base + KPI_KPE1));
+	writel(key_event[2], (keypad->mmio_base + KPI_KRE0));
+	writel(key_event[3], (keypad->mmio_base + KPI_KRE1));
+
+	pressed_keys  = key_event[0] | ((u64)key_event[1] << 32);
+	released_keys = key_event[2] | ((u64)key_event[3] << 32);
+
+	/* Process pressed keys */
+	for_each_set_bit(index, (const unsigned long *)&pressed_keys, KEY_EVENT_BITS) {
+		code = MATRIX_SCAN_CODE(index / 8, (index % 8), row_shift);
+		key = keymap[code];
+
+		input_event(input_dev, EV_MSC, MSC_SCAN, code);
+		input_report_key(input_dev, key, 1);
+	}
+
+	/* Process released keys */
+	for_each_set_bit(index, (const unsigned long *)&released_keys, KEY_EVENT_BITS) {
+		code = MATRIX_SCAN_CODE(index / 8, (index % 8), row_shift);
+		key = keymap[code];
+
+		input_event(input_dev, EV_MSC, MSC_SCAN, code);
+		input_report_key(input_dev, key, 0);
+	}
+
+	input_sync(input_dev);
+}
+
+static irqreturn_t ma35d1_keypad_interrupt(int irq, void *dev_id)
+{
+	struct ma35d1_keypad *keypad = dev_id;
+	unsigned int  kstatus;
+
+	kstatus = readl(keypad->mmio_base + KPI_STATUS);
+
+	if (kstatus & (PKEY_INT | RKEY_INT)) {
+		ma35d1_keypad_scan_matrix(keypad, kstatus);
+	} else {
+		if (kstatus & PDWAKE)
+			writel(PDWAKE, (keypad->mmio_base + KPI_STATUS));
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int ma35d1_keypad_open(struct input_dev *dev)
+{
+	struct ma35d1_keypad *keypad = input_get_drvdata(dev);
+	u32 val, config;
+
+	val = RKINTEN | PKINTEN | INTEN | ENKP;
+	val |= FIELD_PREP(KCOL, (keypad->kpi_col - 1)) | FIELD_PREP(KROW, (keypad->kpi_row - 1));
+
+	config = FIELD_PREP(PRESCALE, (keypad->pre_scale - 1)) |
+		 FIELD_PREP(DB_CLKSEL, keypad->debounce_val);
+
+	val |= config;
+
+	writel(val, keypad->mmio_base + KPI_CONF);
+	writel((keypad->pre_scale_div - 1), keypad->mmio_base + KPI_PRESCALDIV);
+
+	return 0;
+}
+
+static void ma35d1_keypad_close(struct input_dev *dev)
+{
+	struct ma35d1_keypad *keypad = input_get_drvdata(dev);
+	u32 val;
+
+	val = readl(keypad->mmio_base + KPI_KPE0) & ~ENKP;
+	writel(val, keypad->mmio_base + KPI_CONF);
+}
+
+static int ma35d1_parse_dt(struct ma35d1_keypad *keypad, u32 debounce_ms, u32 scan_interval)
+{
+	u32 clk_rate = clk_get_rate(keypad->clk);
+	u32 min_diff = debounce_values[NUM_SETTINGS];
+	u32 i, clk_cycles, diff, p, d;
+	u32 best_diff = 0xffff;
+
+	/* Calculate debounce cycles */
+	clk_cycles = clk_rate * debounce_ms / 1000;
+
+	keypad->debounce_val = debounce_register[NUM_SETTINGS];
+
+	for (i = 0; i < NUM_SETTINGS; i++) {
+		diff = abs((s32)(clk_cycles - debounce_values[i]));
+		if (diff < min_diff) {
+			min_diff = diff;
+			keypad->debounce_val = debounce_register[i];
+		}
+	}
+
+	/* Find scan time setting */
+	clk_cycles = clk_rate * scan_interval / 1000;
+	clk_cycles = clk_cycles / keypad->kpi_row;
+
+	if (clk_cycles == 0) {
+		keypad->pre_scale = 1;
+		keypad->pre_scale_div = 1;
+	} else if (clk_cycles >= PRE_SCALE_MAX * PRE_SCALE_DIV_MAX) {
+		keypad->pre_scale = PRE_SCALE_MAX;
+		keypad->pre_scale_div = PRE_SCALE_DIV_MAX;
+	} else {
+		for (p = 1; p <= PRE_SCALE_MAX; p++) {
+			d = (clk_cycles + (p / 2)) / p;
+
+			if (d > 0 && d <= PRE_SCALE_DIV_MAX) {
+				diff = abs((s32)(p * d) - clk_cycles);
+
+				if (diff < best_diff) {
+					best_diff = diff;
+					keypad->pre_scale = p;
+					keypad->pre_scale_div = d;
+
+					if (diff == 0)
+						break;
+				}
+			}
+		}
+	}
+
+	/*
+	 * Hardware Limitation:
+	 * Due to the hardware design, the keypad debounce time must not exceed
+	 * half of the row scan time.
+	 *
+	 * The row scan time is determined by the formula:
+	 *     Row Scan Time = pre_scale * pre_scale_div
+	 *
+	 * Therefore, the debounce time must satisfy the following condition:
+	 *     Debounce Time < (Row Scan Time / 2)
+	 *
+	 * For example:
+	 * If pre_scale = 64, pre_scale_div = 32,
+	 * then Row Scan Time = 64 * 32 = 2048 keypad clock.
+	 * Hence, the maximum allowable debounce time is 1024 keypad clock.
+	 */
+
+	if (keypad->debounce_val >= (keypad->pre_scale * keypad->pre_scale_div) / 2)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int ma35d1_keypad_probe(struct platform_device *pdev)
+{
+	struct ma35d1_keypad *keypad;
+	struct input_dev *input_dev;
+	struct resource *res;
+	u32 debounce, scan_interval;
+	int error = 0;
+
+	keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
+	if (!keypad)
+		return -ENOMEM;
+
+	input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!input_dev)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(keypad->mmio_base))
+		return dev_err_probe(&pdev->dev, PTR_ERR(keypad->mmio_base),
+					"failed to remap I/O memor\n");
+
+	keypad->irq = platform_get_irq(pdev, 0);
+	if (keypad->irq < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ\n");
+		return keypad->irq;
+	}
+
+	keypad->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+	if (IS_ERR(keypad->clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(keypad->clk), "failed to get core clk\n");
+
+	error = matrix_keypad_parse_properties(&pdev->dev, &keypad->kpi_row, &keypad->kpi_col);
+	if (error) {
+		dev_err(&pdev->dev, "failed to parse keypad params\n");
+		return error;
+	}
+
+	error = matrix_keypad_build_keymap(NULL, NULL, keypad->kpi_row, keypad->kpi_col,
+					   NULL, input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "failed to build keymap\n");
+		return error;
+	}
+
+	keypad->input_dev = input_dev;
+	input_dev->name = pdev->name;
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->open = ma35d1_keypad_open;
+	input_dev->close = ma35d1_keypad_close;
+	input_dev->dev.parent = &pdev->dev;
+
+	error = device_property_read_u32(&pdev->dev, "debounce-delay-ms", &debounce);
+	if (error) {
+		dev_err(&pdev->dev, "failed to acquire 'debounce-delay-ms'\n");
+		return error;
+	}
+
+	error = device_property_read_u32(&pdev->dev, "scan-interval-ms", &scan_interval);
+	if (error) {
+		dev_err(&pdev->dev, "failed to acquire 'scan-interval'\n");
+		return error;
+	}
+
+	error = ma35d1_parse_dt(keypad, debounce, scan_interval);
+	if (error) {
+		dev_err(&pdev->dev, "keypad dt params error\n");
+		return error;
+	}
+
+	__set_bit(EV_REP, input_dev->evbit);
+	input_set_drvdata(input_dev, keypad);
+	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+	error = devm_request_irq(&pdev->dev, keypad->irq, ma35d1_keypad_interrupt,
+				 IRQF_NO_SUSPEND, pdev->name, keypad);
+	if (error) {
+		dev_err(&pdev->dev, "failed to request IRQ\n");
+		return error;
+	}
+
+	platform_set_drvdata(pdev, keypad);
+	device_init_wakeup(&pdev->dev, 1);
+
+	error = dev_pm_set_wake_irq(&pdev->dev, keypad->irq);
+	if (error) {
+		dev_err(&pdev->dev, "failed to enable irq wake\n");
+		return error;
+	}
+
+	error = input_register_device(input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "failed to register input device\n");
+		return error;
+	}
+
+	return 0;
+}
+
+static void ma35d1_keypad_remove(struct platform_device *pdev)
+{
+	struct ma35d1_keypad *keypad = platform_get_drvdata(pdev);
+
+	input_unregister_device(keypad->input_dev);
+}
+
+static int ma35d1_keypad_suspend(struct device *dev)
+{
+	struct ma35d1_keypad *keypad = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		writel(readl(keypad->mmio_base + KPI_CONF) | WAKEUP, keypad->mmio_base + KPI_CONF);
+
+	return 0;
+}
+
+static int ma35d1_keypad_resume(struct device *dev)
+{
+	struct ma35d1_keypad *keypad = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		writel(readl(keypad->mmio_base + KPI_CONF) & ~(WAKEUP),
+		       keypad->mmio_base + KPI_CONF);
+
+	return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(ma35d1_pm_ops, ma35d1_keypad_suspend, ma35d1_keypad_resume);
+
+static const struct of_device_id ma35d1_kpi_of_match[] = {
+	{ .compatible = "nuvoton,ma35d1-kpi"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, ma35d1_kpi_of_match);
+
+static struct platform_driver ma35d1_keypad_driver = {
+	.probe		= ma35d1_keypad_probe,
+	.remove		= ma35d1_keypad_remove,
+	.driver		= {
+		.name	= "ma35d1-kpi",
+		.pm	= pm_sleep_ptr(&ma35d1_pm_ops),
+		.of_match_table = ma35d1_kpi_of_match,
+	},
+};
+module_platform_driver(ma35d1_keypad_driver);
+
+MODULE_AUTHOR("Ming-Jen Chen");
+MODULE_DESCRIPTION("MA35D1 Keypad Driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From mjchen0829 at gmail.com  Tue Dec  3 18:10:12 2024
From: mjchen0829 at gmail.com (Ming-Jen Chen)
Date: Wed,  4 Dec 2024 02:10:12 +0000
Subject: [PATCH v4 0/2] Add support for nuvoton ma35d1 keypad controller
Message-ID: <20241204021014.5083-1-mjchen0829@gmail.com>

This patch series adds keypad driver for the nuvoton ma35 ARMv8 SoC.
It includes DT binding documentation and the ma35d1 keypad driver.

v4:
  - Update nuvoton,ma35d1-keypad.yaml
    - Kept the same order of properties as in the required block.
    - Changed register addresses to lowercase.
v3:
  - Update nuvoton,ma35d1-keypad.yaml
    - Removed vendor-specific properties and replaced them with common properties
  - Update ma35d1_keypad.c
    - Modified the driver to reflect changes in the YAML properties
v2:
  - Update nuvoton,ma35d1-keypad.yaml
    - Fixed warnings and errors generated by running checkpatch.pl
    - Removed the previous version's properties and rewrote the
      properties in the Device Tree schema.
    - Renamed the Device Tree binding file to nuvoton,ma35d1-keypad.yaml
  - Update Kconfig
    - Added COMPILE_TEST to the depends on line in the Kconfig
  - Update ma35d1_keypad.c
    - Refactored error handling within the probe function.
    - Fixed the mixed use of devm and non-devm resource management.
    - Corrected alignment issues in the code.
    - Updated suspend and resume handling methods.
    - Fixed variable naming to remove camel casing.
    - Used for_each_set_bit() to check key states.
    - Modified the code to align with updates in the device tree binding

Ming-Jen Chen (2):
  input: keypad: add new keypad driver for MA35D1
  dt-bindings: input: Add Nuvoton MA35D1 keypad

 .../bindings/input/nuvoton,ma35d1-keypad.yaml |  69 ++++
 drivers/input/keyboard/Kconfig                |  10 +
 drivers/input/keyboard/Makefile               |   1 +
 drivers/input/keyboard/ma35d1_keypad.c        | 386 ++++++++++++++++++
 4 files changed, 466 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/nuvoton,ma35d1-keypad.yaml
 create mode 100644 drivers/input/keyboard/ma35d1_keypad.c

-- 
2.25.1



From mjchen0829 at gmail.com  Tue Dec  3 18:10:14 2024
From: mjchen0829 at gmail.com (Ming-Jen Chen)
Date: Wed,  4 Dec 2024 02:10:14 +0000
Subject: [PATCH v4 2/2] dt-bindings: input: Add Nuvoton MA35D1 keypad
In-Reply-To: <20241204021014.5083-1-mjchen0829@gmail.com>
References: <20241204021014.5083-1-mjchen0829@gmail.com>
Message-ID: <20241204021014.5083-3-mjchen0829@gmail.com>

Add YAML bindings for MA35D1 SoC keypad.

Signed-off-by: Ming-Jen Chen <mjchen0829 at gmail.com>
---
 .../bindings/input/nuvoton,ma35d1-keypad.yaml | 69 +++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/nuvoton,ma35d1-keypad.yaml

diff --git a/Documentation/devicetree/bindings/input/nuvoton,ma35d1-keypad.yaml b/Documentation/devicetree/bindings/input/nuvoton,ma35d1-keypad.yaml
new file mode 100644
index 000000000000..54a81583bf2b
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/nuvoton,ma35d1-keypad.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/nuvoton,ma35d1-keypad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton MA35D1 Keypad
+
+maintainers:
+  - Ming-jen Chen <mjchen0829 at gmail.com>
+
+allOf:
+  - $ref: /schemas/input/matrix-keymap.yaml#
+
+properties:
+  compatible:
+    const: nuvoton,ma35d1-kpi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  debounce-delay-ms:
+    description: Debounce delay time in milliseconds.
+    maxItems: 1
+
+  scan-interval-ms:
+    description: Scan interval time in milliseconds.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - debounce-delay-ms
+  - scan-interval-ms
+  - linux,keymap
+  - keypad,num-rows
+  - keypad,num-columns
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/input/input.h>
+    keypad at 404a0000 {
+      compatible = "nuvoton,ma35d1-kpi";
+      reg = <0x404a0000 0x10000>;
+      interrupts = <79>;
+      clocks = <&clk>;
+      keypad,num-rows = <2>;
+      keypad,num-columns = <2>;
+
+      linux,keymap = <
+         MATRIX_KEY(0, 0, KEY_ENTER)
+         MATRIX_KEY(0, 1, KEY_ENTER)
+         MATRIX_KEY(1, 0, KEY_SPACE)
+         MATRIX_KEY(1, 1, KEY_Z)
+      >;
+
+      debounce-delay-ms = <1>;
+      scan-interval-ms = <20>;
+    };
-- 
2.25.1



From kever.yang at rock-chips.com  Tue Dec  3 18:16:00 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Wed, 4 Dec 2024 10:16:00 +0800
Subject: [PATCH v3 3/3] drm/rockchip: Add MIPI DSI2 glue driver for RK3588
In-Reply-To: <20241203165450.1501219-4-heiko@sntech.de>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241203165450.1501219-4-heiko@sntech.de>
Message-ID: <af1cce1a-c46d-470f-a1b9-bfbc90b46415@rock-chips.com>

Hi Heiko,

On 2024/12/4 00:54, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
>
> This adds the glue code for the MIPI DSI2 bridge on Rockchip SoCs and
> enables its use on the RK3588.
>
> Right now the DSI2 controller is always paired with a DC-phy based on a
> Samsung IP, so the interface values are set statically for now.
> This stays true for the upcoming RK3576 as well.
>
> Tested-by: Daniel Semkowicz <dse at thaumatec.com>
> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
> ---
>   drivers/gpu/drm/rockchip/Kconfig              |  10 +
>   drivers/gpu/drm/rockchip/Makefile             |   1 +
>   .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c  | 524 ++++++++++++++++++
>   drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |   2 +
>   drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |   1 +
>   5 files changed, 538 insertions(+)
>   create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
>
> diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
> index 448fadd4ba15..84af423b7f90 100644
> --- a/drivers/gpu/drm/rockchip/Kconfig
> +++ b/drivers/gpu/drm/rockchip/Kconfig
> @@ -10,6 +10,7 @@ config DRM_ROCKCHIP
>   	select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
>   	select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP
>   	select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
> +	select DRM_DW_MIPI_DSI2 if ROCKCHIP_DW_MIPI_DSI2
>   	select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
>   	select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
>   	select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
> @@ -81,6 +82,15 @@ config ROCKCHIP_DW_MIPI_DSI
>   	  enable MIPI DSI on RK3288 or RK3399 based SoC, you should
>   	  select this option.
>   
> +config ROCKCHIP_DW_MIPI_DSI2
> +	bool "Rockchip specific extensions for Synopsys DW MIPI DSI2"
> +	select GENERIC_PHY_MIPI_DPHY
> +	help
> +	  This selects support for Rockchip SoC specific extensions
> +	  for the Synopsys DesignWare dsi driver. If you want to
> +	  enable MIPI DSI on RK3576 or RK3588 based SoC, you should
> +	  select this option.
> +
>   config ROCKCHIP_INNO_HDMI
>   	bool "Rockchip specific extensions for Innosilicon HDMI"
>   	select DRM_DISPLAY_HDMI_HELPER
> diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
> index 3eab662a5a1d..2b867cebbc12 100644
> --- a/drivers/gpu/drm/rockchip/Makefile
> +++ b/drivers/gpu/drm/rockchip/Makefile
> @@ -13,6 +13,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o
> +rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI2) += dw-mipi-dsi2-rockchip.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> new file mode 100644
> index 000000000000..55eed4001634
> --- /dev/null
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> @@ -0,0 +1,524 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2024 Rockchip Electronics Co.Ltd
This should be:

Rockchip Electronics Co., Ltd.

This typo is from vendor kernel, we will correct all this kind of issue locally,
and Andy is going to correct other files in drm for mainline kernel.

Thanks,
- Kever



From wenst at chromium.org  Tue Dec  3 18:38:40 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 4 Dec 2024 10:38:40 +0800
Subject: [PATCH] dt-bindings: soc: fsl: cpm_qe: Limit matching to nodes
 with "fsl,qe"
In-Reply-To: <20241203172026.GA1988559-robh@kernel.org>
References: <20241202045757.39244-1-wenst@chromium.org> <20241203172026.GA1988559-robh@kernel.org>
Message-ID: <CAGXv+5GPacXtcrxJVHUGuRWOSY+k5tn4kvwgu_nkjdQ6=srayQ@mail.gmail.com>

On Wed, Dec 4, 2024 at 1:20?AM Rob Herring <robh at kernel.org> wrote:
>
> On Mon, Dec 02, 2024 at 12:57:55PM +0800, Chen-Yu Tsai wrote:
> > Otherwise the binding matches against random nodes with "simple-bus"
> > giving out all kinds of invalid warnings:
> >
> >     $ make CHECK_DTBS=y mediatek/mt8188-evb.dtb
> >       SYNC    include/config/auto.conf.cmd
> >       UPD     include/config/kernel.release
> >       SCHEMA  Documentation/devicetree/bindings/processed-schema.json
> >       DTC [C] arch/arm64/boot/dts/mediatek/mt8188-evb.dtb
> >     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: compatible:0: 'fsl,qe' was expected
> >           from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
> >     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: compatible: ['simple-bus'] is too short
> >           from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
> >     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:compatible:0: 'fsl,qe-ic' was expected
> >           from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
> >     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:reg: [[0, 201326592, 0, 262144], [0, 201588736, 0, 2097152]] is too long
> >           from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
> >     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000:#interrupt-cells:0:0: 1 was expected
> >           from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
> >     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: interrupt-controller at c000000: '#redistributor-regions', 'ppi-partitions' do not match any of the regexes: 'pinctrl-[0-9]+'
> >           from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
> >     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: 'reg' is a required property
> >           from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
> >     arch/arm64/boot/dts/mediatek/mt8188-evb.dtb: soc: 'bus-frequency' is a required property
> >           from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml#
> >
> > Fixes: ecbfc6ff94a2 ("dt-bindings: soc: fsl: cpm_qe: convert to yaml format")
> > Cc: Frank Li <Frank.Li at nxp.com>
> > Cc: <stable at vger.kernel.org> # v6.11+
> > Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> > ---
> >  .../devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml        | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
> > index 89cdf5e1d0a8..9e07a2c4d05b 100644
> > --- a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
> > +++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml
> > @@ -21,6 +21,14 @@ description: |
> >    The description below applies to the qe of MPC8360 and
> >    more nodes and properties would be extended in the future.
> >
> > +select:
> > +  properties:
> > +    compatible:
> > +      contains:
> > +        const: fsl,qe
> > +  required:
> > +    - compatible
>
> Update your dtschema. The select is no longer necessary. dtbs_check will
> also run 5x faster.

That did the trick. Thanks Rob!

And sorry for the noise.


ChenYu


From hpchen0nvt at gmail.com  Tue Dec  3 18:51:28 2024
From: hpchen0nvt at gmail.com (Hui-Ping Chen)
Date: Wed,  4 Dec 2024 02:51:28 +0000
Subject: [PATCH v10 1/2] dt-bindings: mtd: nuvoton,ma35d1-nand: add new bindings
In-Reply-To: <20241204025129.150525-1-hpchen0nvt@gmail.com>
References: <20241204025129.150525-1-hpchen0nvt@gmail.com>
Message-ID: <20241204025129.150525-2-hpchen0nvt@gmail.com>

Add dt-bindings for the Nuvoton MA35 SoC NAND Controller.

Signed-off-by: Hui-Ping Chen <hpchen0nvt at gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../bindings/mtd/nuvoton,ma35d1-nand.yaml     | 95 +++++++++++++++++++
 1 file changed, 95 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml b/Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml
new file mode 100644
index 000000000000..0b651450a8f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/nuvoton,ma35d1-nand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton MA35D1 NAND Flash Interface (NFI) Controller
+
+maintainers:
+  - Hui-Ping Chen <hpchen0nvt at gmail.com>
+
+allOf:
+  - $ref: nand-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - nuvoton,ma35d1-nand-controller
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+patternProperties:
+  "^nand@[a-f0-9]$":
+    type: object
+    $ref: raw-nand-chip.yaml
+    properties:
+      reg:
+        minimum: 0
+        maximum: 1
+
+      nand-ecc-step-size:
+        enum: [512, 1024]
+
+      nand-ecc-strength:
+        enum: [8, 12, 24]
+
+    required:
+      - reg
+
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        nand-controller at 401A0000 {
+            compatible = "nuvoton,ma35d1-nand-controller";
+            reg = <0x0 0x401A0000 0x0 0x1000>;
+            interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&clk NAND_GATE>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            nand at 0 {
+                reg = <0>;
+                nand-on-flash-bbt;
+                nand-ecc-step-size = <512>;
+                nand-ecc-strength = <8>;
+
+                partitions {
+                    compatible = "fixed-partitions";
+                    #address-cells = <1>;
+                    #size-cells = <1>;
+
+                    uboot at 0 {
+                        label = "nand-uboot";
+                        read-only;
+                        reg = <0x0 0x300000>;
+                    };
+                };
+            };
+        };
+    };
+
+...
-- 
2.25.1



From hpchen0nvt at gmail.com  Tue Dec  3 18:51:27 2024
From: hpchen0nvt at gmail.com (Hui-Ping Chen)
Date: Wed,  4 Dec 2024 02:51:27 +0000
Subject: [PATCH v10 0/2] Add support for nuvoton ma35 nand controller
Message-ID: <20241204025129.150525-1-hpchen0nvt@gmail.com>

This patch series adds the mtd nand driver for the nuvoton ma35 ARMv8 SoC.
It includes DT binding documentation and the ma35 mtd nand driver.

v10:
  - Update ma35d1 mtd nand driver
    - Add unsupported write page handling.

v9:
  - Update ma35d1 mtd nand driver
    - Remove NAND_NO_SUBPAGE_WRITE flag.
    - Remove of_get_property().
    - Add ecc.write_subpage and ecc.read_subpage.

v8:
  - Update ma35d1 mtd nand driver
    - Rename to nuvoton-ma35d1-nand-controller.c.
    - Use switch case instead of if else.
    - Move some parameters to be set during initialization.
    - Fix the ecc.read_page return value issue.
    - Add enable/disable ECC engine before and after reading/writing the page.
    - Return IRQ_NONE if (isr & INT_DMA) == 0.
    - Move the HW ECC related settings to ON_HOST.
    - Move hw_init() to probe.

v7:
  - Update nuvoton,ma35d1-nand.yaml
    - Remove required 'nand-ecc-step-size' and 'nand-ecc-strength'.
    - Add 'reg' for chip select.
  - Update ma35d1 mtd nand driver
    - Update space and comments style.
    - Add chip select setting from DT.
    - Add switch case which supports various ECC configurations.
    - Set reset before NAND controller enable.

v6:
  - Update ma35d1 mtd nand driver
    - Remove extra blank lines and add comments.

v5:
  - Update ma35d1 mtd nand driver
    - Remove unnecessary definitions and comments.
    - Modified DMA API call sequence.
    - Move the ECC check out of the interrupt handler.
      Check it after reading a page.

v4:
  - Update nuvoton,ma35d1-nand.yaml
    - rename 'nuvoton,ma35d1-nand' to 'nuvoton,ma35d1-nand-controller'.
  - Update ma35d1 mtd nand driver
    - Rewrite the NAND driver using the exec_op API.

v3:
  - Update ma35d1 mtd nand driver
    - Release IRQ handler.
    - Remove unused functions.
    - Remove '.owner'.

v2:
  - Update nuvoton,ma35d1-nand.yaml
    - Adjust the order and remove any unnecessary items.
    - Add 'nand-ecc-step-size' and 'nand-ecc-strength' to the required list.
  - Update ma35d1 mtd nand driver
    - Fix coding style.
    - Use 'devm_clk_get' instead of 'of_clk_get'.
    - Use 'dev_err_probe' instead of 'dev_err'.
    - Remove 'pr_info' and 'of_match_ptr'.
    - Remove 'module_init' and 'module_exit'.


Hui-Ping Chen (2):
  dt-bindings: mtd: nuvoton,ma35d1-nand: add new bindings
  mtd: rawnand: nuvoton: add new driver for the Nuvoton MA35 SoC

 .../bindings/mtd/nuvoton,ma35d1-nand.yaml     |   95 ++
 drivers/mtd/nand/raw/Kconfig                  |    8 +
 drivers/mtd/nand/raw/Makefile                 |    1 +
 .../nand/raw/nuvoton-ma35d1-nand-controller.c | 1032 +++++++++++++++++
 4 files changed, 1136 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml
 create mode 100644 drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c

-- 
2.25.1



From hpchen0nvt at gmail.com  Tue Dec  3 18:51:29 2024
From: hpchen0nvt at gmail.com (Hui-Ping Chen)
Date: Wed,  4 Dec 2024 02:51:29 +0000
Subject: [PATCH v10 2/2] mtd: rawnand: nuvoton: add new driver for the Nuvoton MA35 SoC
In-Reply-To: <20241204025129.150525-1-hpchen0nvt@gmail.com>
References: <20241204025129.150525-1-hpchen0nvt@gmail.com>
Message-ID: <20241204025129.150525-3-hpchen0nvt@gmail.com>

Nuvoton MA35 SoCs NAND Flash Interface Controller
supports 2kiB, 4kiB and 8kiB page size, and up to
8-bit, 12-bit, and 24-bit hardware ECC calculation
circuit to protect data.

Signed-off-by: Hui-Ping Chen <hpchen0nvt at gmail.com>
---
 drivers/mtd/nand/raw/Kconfig                  |    8 +
 drivers/mtd/nand/raw/Makefile                 |    1 +
 .../nand/raw/nuvoton-ma35d1-nand-controller.c | 1032 +++++++++++++++++
 3 files changed, 1041 insertions(+)
 create mode 100644 drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index d0aaccf72d78..e3677bcaf035 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -454,6 +454,14 @@ config MTD_NAND_TS72XX
 	help
 	  Enables support for NAND controller on ts72xx SBCs.
 
+config MTD_NAND_NUVOTON_MA35
+	tristate "Nuvoton MA35 SoC NAND controller"
+	depends on ARCH_MA35 || COMPILE_TEST
+	depends on OF
+	help
+	  Enables support for the NAND controller found on
+	  the Nuvoton MA35 series SoCs.
+
 comment "Misc"
 
 config MTD_SM_COMMON
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index d0b0e6b83568..99e79c448847 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_INTEL_LGM)	+= intel-nand-controller.o
 obj-$(CONFIG_MTD_NAND_ROCKCHIP)		+= rockchip-nand-controller.o
 obj-$(CONFIG_MTD_NAND_PL35X)		+= pl35x-nand-controller.o
 obj-$(CONFIG_MTD_NAND_RENESAS)		+= renesas-nand-controller.o
+obj-$(CONFIG_MTD_NAND_NUVOTON_MA35)	+= nuvoton-ma35d1-nand-controller.o
 
 nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
 nand-objs += nand_onfi.o
diff --git a/drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c b/drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c
new file mode 100644
index 000000000000..d8d830cd6823
--- /dev/null
+++ b/drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c
@@ -0,0 +1,1032 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 Nuvoton Technology Corp.
+ */
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* NFI Registers */
+#define MA35_NFI_REG_DMACTL		0x400
+#define   DMA_EN				BIT(0)
+#define   DMA_RST				BIT(1)
+#define   DMA_BUSY				BIT(9)
+
+#define MA35_NFI_REG_DMASA		0x408
+#define MA35_NFI_REG_GCTL		0x800
+#define   GRST					BIT(0)
+#define   NAND_EN				BIT(3)
+
+#define MA35_NFI_REG_NANDCTL		0x8A0
+#define   SWRST				BIT(0)
+#define   DMA_R_EN				BIT(1)
+#define   DMA_W_EN				BIT(2)
+#define   ECC_CHK				BIT(7)
+#define   PROT3BEN				BIT(8)
+#define   PSIZE_2K				BIT(16)
+#define   PSIZE_4K				BIT(17)
+#define   PSIZE_8K				GENMASK(17, 16)
+#define   PSIZE_MASK				GENMASK(17, 16)
+#define   BCH_T24				BIT(18)
+#define   BCH_T8				BIT(20)
+#define   BCH_T12				BIT(21)
+#define   BCH_NONE				(0x0)
+#define   BCH_MASK				GENMASK(22, 18)
+#define   ECC_EN				BIT(23)
+#define   DISABLE_CS0				BIT(25)
+
+#define MA35_NFI_REG_NANDINTEN	0x8A8
+#define MA35_NFI_REG_NANDINTSTS	0x8AC
+#define   INT_DMA				BIT(0)
+#define   INT_ECC				BIT(2)
+#define   INT_RB0				BIT(10)
+
+#define MA35_NFI_REG_NANDCMD		0x8B0
+#define MA35_NFI_REG_NANDADDR		0x8B4
+#define   ENDADDR				BIT(31)
+
+#define MA35_NFI_REG_NANDDATA		0x8B8
+#define MA35_NFI_REG_NANDRACTL	0x8BC
+#define MA35_NFI_REG_NANDECTL		0x8C0
+#define   ENABLE_WP				0x0
+#define   DISABLE_WP				BIT(0)
+
+#define MA35_NFI_REG_NANDECCES0	0x8D0
+#define   ECC_STATUS_MASK			GENMASK(1, 0)
+#define   ECC_ERR_CNT_MASK			GENMASK(4, 0)
+
+#define MA35_NFI_REG_NANDECCEA0	0x900
+#define MA35_NFI_REG_NANDECCED0	0x960
+#define MA35_NFI_REG_NANDRA0		0xA00
+
+/* Define for the BCH hardware ECC engine */
+/* define the total padding bytes for 512/1024 data segment */
+#define MA35_BCH_PADDING_512	32
+#define MA35_BCH_PADDING_1024	64
+/* define the BCH parity code length for 512 bytes data pattern */
+#define MA35_PARITY_BCH8	15
+#define MA35_PARITY_BCH12	23
+/* define the BCH parity code length for 1024 bytes data pattern */
+#define MA35_PARITY_BCH24	45
+
+#define MA35_MAX_NSELS		(2)
+#define PREFIX_RA_IS_EMPTY(reg)	FIELD_GET(GENMASK(31, 16), (reg))
+
+struct ma35_nand_chip {
+	struct list_head node;
+	struct nand_chip chip;
+
+	u32 eccstatus;
+	u8 nsels;
+	u8 sels[] __counted_by(nsels);
+};
+
+struct ma35_nand_info {
+	struct nand_controller controller;
+	struct device *dev;
+	void __iomem *regs;
+	int irq;
+	struct clk *clk;
+	struct completion complete;
+	struct list_head chips;
+
+	u8 *buffer;
+	unsigned long assigned_cs;
+};
+
+static inline struct ma35_nand_chip *to_ma35_nand(struct nand_chip *chip)
+{
+	return container_of(chip, struct ma35_nand_chip, chip);
+}
+
+static int ma35_ooblayout_ecc(struct mtd_info *mtd, int section,
+			      struct mtd_oob_region *oob_region)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+
+	if (section)
+		return -ERANGE;
+
+	oob_region->length = chip->ecc.total;
+	oob_region->offset = mtd->oobsize - oob_region->length;
+
+	return 0;
+}
+
+static int ma35_ooblayout_free(struct mtd_info *mtd, int section,
+			       struct mtd_oob_region *oob_region)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+
+	if (section)
+		return -ERANGE;
+
+	oob_region->length = mtd->oobsize - chip->ecc.total - 2;
+	oob_region->offset = 2;
+
+	return 0;
+}
+
+static const struct mtd_ooblayout_ops ma35_ooblayout_ops = {
+	.free = ma35_ooblayout_free,
+	.ecc = ma35_ooblayout_ecc,
+};
+
+static inline void ma35_clear_spare(struct nand_chip *chip, int size)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	int i;
+
+	for (i = 0; i < size / 4; i++)
+		writel(0xff, nand->regs + MA35_NFI_REG_NANDRA0);
+}
+
+static inline void read_remaining_bytes(struct ma35_nand_info *nand, u32 *buf,
+					u32 offset, int size, int swap)
+{
+	u32 value = readl(nand->regs + MA35_NFI_REG_NANDRA0 + offset);
+	u8 *ptr = (u8 *)buf;
+	int i, shift;
+
+	for (i = 0; i < size; i++) {
+		shift = (swap ? 3 - i : i) * 8;
+		ptr[i] = (value >> shift) & 0xff;
+	}
+}
+
+static inline void ma35_read_spare(struct nand_chip *chip, int size, u32 *buf, u32 offset)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	u32 off = round_down(offset, 4);
+	int len = offset % 4;
+	int i;
+
+	if (len) {
+		read_remaining_bytes(nand, buf, off, 4 - len, 1);
+		off += 4;
+		size -= (4 - len);
+	}
+
+	for (i = 0; i < size / 4; i++)
+		*buf++ = readl(nand->regs + MA35_NFI_REG_NANDRA0 + off + (i * 4));
+
+	read_remaining_bytes(nand, buf, off + (size & ~3), size % 4, 0);
+}
+
+static inline void ma35_write_spare(struct nand_chip *chip, int size, u32 *buf)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	u32 value;
+	int i, j;
+	u8 *ptr;
+
+	for (i = 0, j = 0; i < size / 4; i++, j += 4)
+		writel(*buf++, nand->regs + MA35_NFI_REG_NANDRA0 + j);
+
+	ptr = (u8 *)buf;
+	switch (size % 4) {
+	case 1:
+		writel(*ptr, nand->regs + MA35_NFI_REG_NANDRA0 + j);
+		break;
+	case 2:
+		value = *ptr | (*(ptr+1) << 8);
+		writel(value, nand->regs + MA35_NFI_REG_NANDRA0 + j);
+		break;
+	case 3:
+		value = *ptr | (*(ptr+1) << 8) | (*(ptr+2) << 16);
+		writel(value, nand->regs + MA35_NFI_REG_NANDRA0 + j);
+		break;
+	default:
+		break;
+	}
+}
+
+static void ma35_nand_target_enable(struct nand_chip *chip, unsigned int cs)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	u32 reg;
+
+	switch (cs) {
+	case 0:
+		reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+		writel(reg & ~DISABLE_CS0, nand->regs + MA35_NFI_REG_NANDCTL);
+
+		reg = readl(nand->regs + MA35_NFI_REG_NANDINTSTS);
+		reg |= INT_RB0;
+		writel(reg, nand->regs + MA35_NFI_REG_NANDINTSTS);
+		break;
+	default:
+		break;
+	}
+}
+
+static int ma35_nand_hwecc_init(struct nand_chip *chip, struct ma35_nand_info *nand)
+{
+	struct ma35_nand_chip *nvtnand = to_ma35_nand(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct device *dev = mtd->dev.parent;
+	u32 reg;
+
+	nand->buffer = devm_kzalloc(dev, mtd->writesize, GFP_KERNEL);
+	if (!nand->buffer)
+		return -ENOMEM;
+
+	/* Redundant area size */
+	writel(mtd->oobsize, nand->regs + MA35_NFI_REG_NANDRACTL);
+
+	/* Protect redundant 3 bytes and disable ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	reg |= (PROT3BEN | ECC_CHK);
+	reg &= ~ECC_EN;
+
+	if (chip->ecc.strength != 0) {
+		chip->ecc.steps = mtd->writesize / chip->ecc.size;
+		nvtnand->eccstatus = (chip->ecc.steps < 4) ? 1 : chip->ecc.steps / 4;
+		/* Set BCH algorithm */
+		reg &= ~BCH_MASK;
+		switch (chip->ecc.strength) {
+		case 8:
+			chip->ecc.total = chip->ecc.steps * MA35_PARITY_BCH8;
+			reg |= BCH_T8;
+			break;
+		case 12:
+			chip->ecc.total = chip->ecc.steps * MA35_PARITY_BCH12;
+			reg |= BCH_T12;
+			break;
+		case 24:
+			chip->ecc.total = chip->ecc.steps * MA35_PARITY_BCH24;
+			reg |= BCH_T24;
+			break;
+		default:
+			dev_err(nand->dev, "ECC strength unsupported\n");
+			return -EINVAL;
+		}
+
+		chip->ecc.bytes = chip->ecc.total / chip->ecc.steps;
+	}
+	writel(reg, nand->regs + MA35_NFI_REG_NANDCTL);
+	return 0;
+}
+
+/* Correct data by BCH alrogithm */
+static void ma35_nfi_correct(struct nand_chip *chip, u8 index,
+				u8 err_cnt, u8 *addr)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	u32 temp_data[24], temp_addr[24];
+	u32 padding_len, parity_len;
+	u32 value, offset, remain;
+	u32 err_data[6];
+	u8  i, j;
+
+	/* Configurations */
+	if (chip->ecc.strength <= 8) {
+		parity_len = MA35_PARITY_BCH8;
+		padding_len = MA35_BCH_PADDING_512;
+	} else if (chip->ecc.strength <= 12) {
+		parity_len = MA35_PARITY_BCH12;
+		padding_len = MA35_BCH_PADDING_512;
+	} else if (chip->ecc.strength <= 24) {
+		parity_len = MA35_PARITY_BCH24;
+		padding_len = MA35_BCH_PADDING_1024;
+	} else {
+		dev_err(nand->dev, "Invalid BCH_TSEL = 0x%lx\n",
+			readl(nand->regs + MA35_NFI_REG_NANDCTL) & BCH_MASK);
+		return;
+	}
+
+	/*
+	 * got valid BCH_ECC_DATAx and parse them to temp_data[]
+	 * got the valid register number of BCH_ECC_DATAx since
+	 * one register include 4 error bytes
+	 */
+	j = (err_cnt + 3) / 4;
+	j = (j > 6) ? 6 : j;
+	for (i = 0; i < j; i++)
+		err_data[i] = readl(nand->regs + MA35_NFI_REG_NANDECCED0 + i * 4);
+
+	for (i = 0; i < j; i++) {
+		temp_data[i*4+0] = err_data[i] & 0xff;
+		temp_data[i*4+1] = (err_data[i] >> 8) & 0xff;
+		temp_data[i*4+2] = (err_data[i] >> 16) & 0xff;
+		temp_data[i*4+3] = (err_data[i] >> 24) & 0xff;
+	}
+
+	/*
+	 * got valid REG_BCH_ECC_ADDRx and parse them to temp_addr[]
+	 * got the valid register number of REG_BCH_ECC_ADDRx since
+	 * one register include 2 error addresses
+	 */
+	j = (err_cnt + 1) / 2;
+	j = (j > 12) ? 12 : j;
+	for (i = 0; i < j; i++) {
+		temp_addr[i*2+0] = readl(nand->regs + MA35_NFI_REG_NANDECCEA0 + i * 4)
+					& 0x07ff;
+		temp_addr[i*2+1] = (readl(nand->regs + MA35_NFI_REG_NANDECCEA0 + i * 4)
+					>> 16) & 0x07ff;
+	}
+
+	/* pointer to begin address of field that with data error */
+	addr += index * chip->ecc.size;
+
+	/* correct each error bytes */
+	for (i = 0; i < err_cnt; i++) {
+		u32 corrected_index = temp_addr[i];
+
+		/* for wrong data in field */
+		if (corrected_index < chip->ecc.size)
+			*(addr + corrected_index) ^= temp_data[i];
+
+		/* for wrong first-3-bytes in redundancy area */
+		else if (corrected_index < (chip->ecc.size + 3)) {
+			corrected_index -= chip->ecc.size;
+			temp_addr[i] += (parity_len * index);	/* field offset */
+
+			value = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+			value ^= temp_data[i] << (8 * corrected_index);
+			writel(value, nand->regs + MA35_NFI_REG_NANDRA0);
+		}
+		/*
+		 * for wrong parity code in redundancy area
+		 * BCH_ERR_ADDRx = [data in field] + [3 bytes] + [xx] + [parity code]
+		 *                                   |<--     padding bytes      -->|
+		 * The BCH_ERR_ADDRx for last parity code always = field size + padding size.
+		 * So, the first parity code = field size + padding size - parity code length.
+		 * For example, for BCH T12, the first parity code = 512 + 32 - 23 = 521.
+		 * That is, error byte address offset within field is
+		 */
+		else {
+			corrected_index -= (chip->ecc.size + padding_len - parity_len);
+
+			/*
+			 * final address = first parity code of first field +
+			 *                 offset of fields +
+			 *                 offset within field
+			 */
+			offset = (readl(nand->regs + MA35_NFI_REG_NANDRACTL) & 0x1ff) -
+				(parity_len * chip->ecc.steps) +
+				(parity_len * index) + corrected_index;
+
+			remain = offset % 4;
+			value = readl(nand->regs + MA35_NFI_REG_NANDRA0 + offset - remain);
+			value ^= temp_data[i] << (8 * remain);
+			writel(value, nand->regs + MA35_NFI_REG_NANDRA0 + offset - remain);
+		}
+	}
+}
+
+static int ma35_nfi_ecc_check(struct nand_chip *chip, u8 *addr)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct ma35_nand_chip *nvtnand = to_ma35_nand(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int maxbitflips = 0;
+	int cnt = 0;
+	u32 status;
+	int i, j;
+
+	for (j = 0; j < nvtnand->eccstatus; j++) {
+		status = readl(nand->regs + MA35_NFI_REG_NANDECCES0 + j * 4);
+		if (!status)
+			continue;
+
+		for (i = 0; i < 4; i++) {
+			if ((status & ECC_STATUS_MASK) == 0x01) {
+				/* Correctable error */
+				cnt = (status >> 2) & ECC_ERR_CNT_MASK;
+				ma35_nfi_correct(chip, j * 4 + i, cnt, addr);
+				maxbitflips = max_t(u32, maxbitflips, cnt);
+				mtd->ecc_stats.corrected += cnt;
+			} else {
+				/* Uncorrectable error */
+				mtd->ecc_stats.failed++;
+				dev_err(nand->dev, "uncorrectable error! 0x%4x\n", status);
+				return -EBADMSG;
+			}
+			status >>= 8;
+		}
+	}
+	return maxbitflips;
+}
+
+static void ma35_nand_dmac_init(struct ma35_nand_info *nand)
+{
+	/* DMAC reset and enable */
+	writel(DMA_RST | DMA_EN, nand->regs + MA35_NFI_REG_DMACTL);
+	writel(DMA_EN, nand->regs + MA35_NFI_REG_DMACTL);
+
+	/* Clear DMA finished flag and enable */
+	writel(INT_DMA | INT_ECC, nand->regs + MA35_NFI_REG_NANDINTSTS);
+	writel(INT_DMA, nand->regs + MA35_NFI_REG_NANDINTEN);
+}
+
+static int ma35_nand_do_write(struct nand_chip *chip, const u8 *addr, u32 len)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	dma_addr_t dma_addr;
+	int ret = 0, i;
+	u32 reg;
+
+	if (len != mtd->writesize) {
+		for (i = 0; i < len; i++)
+			writel(addr[i], nand->regs + MA35_NFI_REG_NANDDATA);
+		return 0;
+	}
+
+	ma35_nand_dmac_init(nand);
+
+	/* To mark this page as dirty. */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+	if (reg & 0xffff0000)
+		writel(reg & 0xffff, nand->regs + MA35_NFI_REG_NANDRA0);
+
+	dma_addr = dma_map_single(nand->dev, (void *)addr, len, DMA_TO_DEVICE);
+	ret = dma_mapping_error(nand->dev, dma_addr);
+	if (ret) {
+		dev_err(nand->dev, "dma mapping error\n");
+		return -EINVAL;
+	}
+	dma_sync_single_for_device(nand->dev, dma_addr, len, DMA_TO_DEVICE);
+
+	reinit_completion(&nand->complete);
+	writel(dma_addr, nand->regs + MA35_NFI_REG_DMASA);
+	writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DMA_W_EN,
+		nand->regs + MA35_NFI_REG_NANDCTL);
+	ret = wait_for_completion_timeout(&nand->complete, msecs_to_jiffies(1000));
+	if (!ret) {
+		dev_err(nand->dev, "write timeout\n");
+		ret = -ETIMEDOUT;
+	}
+
+	dma_unmap_single(nand->dev, dma_addr, len, DMA_TO_DEVICE);
+
+	return ret;
+}
+
+static int ma35_nand_do_read(struct nand_chip *chip, u8 *addr, u32 len)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int ret = 0, cnt = 0, i;
+	dma_addr_t dma_addr;
+	u32 reg;
+
+	if (len != mtd->writesize) {
+		for (i = 0; i < len; i++)
+			addr[i] = readb(nand->regs + MA35_NFI_REG_NANDDATA);
+		return 0;
+	}
+
+	ma35_nand_dmac_init(nand);
+
+	/* Setup and start DMA using dma_addr */
+	dma_addr = dma_map_single(nand->dev, (void *)addr, len, DMA_FROM_DEVICE);
+	ret = dma_mapping_error(nand->dev, dma_addr);
+	if (ret) {
+		dev_err(nand->dev, "dma mapping error\n");
+		return -EINVAL;
+	}
+
+	reinit_completion(&nand->complete);
+	writel(dma_addr, nand->regs + MA35_NFI_REG_DMASA);
+	writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DMA_R_EN,
+		nand->regs + MA35_NFI_REG_NANDCTL);
+	ret = wait_for_completion_timeout(&nand->complete, msecs_to_jiffies(1000));
+	if (!ret) {
+		dev_err(nand->dev, "read timeout\n");
+		ret = -ETIMEDOUT;
+	}
+
+	dma_unmap_single(nand->dev, dma_addr, len, DMA_FROM_DEVICE);
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDINTSTS);
+	if (reg & INT_ECC) {
+		cnt = ma35_nfi_ecc_check(chip, addr);
+		if (cnt < 0) {
+			writel(DMA_RST | DMA_EN, nand->regs + MA35_NFI_REG_DMACTL);
+			writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | SWRST,
+				nand->regs + MA35_NFI_REG_NANDCTL);
+		}
+		writel(INT_ECC, nand->regs + MA35_NFI_REG_NANDINTSTS);
+	}
+
+	ret = ret < 0 ? ret : cnt;
+	return ret;
+}
+
+static int ma35_nand_format_subpage(struct nand_chip *chip, u32 offset,
+					u32 len, const u8 *buf)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	u32 page_off = round_down(offset, chip->ecc.size);
+	u32 end = DIV_ROUND_UP(page_off + len, chip->ecc.size);
+	u32 start = page_off / chip->ecc.size;
+	u32 reg;
+	int i;
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRACTL) | 0xffff0000;
+	memset(nand->buffer, 0xff, mtd->writesize);
+	for (i = start; i < end; i++) {
+		memcpy(nand->buffer + i * chip->ecc.size,
+			buf + i * chip->ecc.size,
+			chip->ecc.size);
+		reg &= ~(1 << (i + 16));
+	}
+	writel(reg, nand->regs + MA35_NFI_REG_NANDRACTL);
+
+	return 0;
+}
+
+static int ma35_nand_write_subpage_hwecc(struct nand_chip *chip, u32 offset,
+					u32 data_len, const u8 *buf,
+					int oob_required, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	u32 reg, oobpoi, index;
+	int i;
+
+	/* Enable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg | ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+
+	ma35_clear_spare(chip, mtd->oobsize);
+	ma35_write_spare(chip, mtd->oobsize - chip->ecc.total,
+			(u32 *)chip->oob_poi);
+
+	ma35_nand_format_subpage(chip, offset, data_len, buf);
+	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+	ma35_nand_do_write(chip, nand->buffer, mtd->writesize);
+	nand_prog_page_end_op(chip);
+
+	oobpoi = mtd->oobsize - chip->ecc.total;
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRACTL);
+	for (i = 0; i < chip->ecc.steps; i++) {
+		index = i * chip->ecc.bytes;
+		if (!(reg & (1 << (i + 16)))) {
+			ma35_read_spare(chip, chip->ecc.bytes,
+					(u32 *)(chip->oob_poi + oobpoi + index),
+					oobpoi + index);
+		}
+	}
+
+	writel(mtd->oobsize, nand->regs + MA35_NFI_REG_NANDRACTL);
+	/* Disable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg & ~ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	return 0;
+}
+
+static int ma35_nand_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
+				      int oob_required, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	u32 reg;
+
+	/* Enable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg | ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+
+	ma35_clear_spare(chip, mtd->oobsize);
+	ma35_write_spare(chip, mtd->oobsize - chip->ecc.total,
+			(u32 *)chip->oob_poi);
+
+	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+	ma35_nand_do_write(chip, buf, mtd->writesize);
+	nand_prog_page_end_op(chip);
+
+	ma35_read_spare(chip, chip->ecc.total,
+			(u32 *)(chip->oob_poi + (mtd->oobsize - chip->ecc.total)),
+			mtd->oobsize - chip->ecc.total);
+
+	/* Disable HW ECC engine */
+	writel(reg & ~ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	return 0;
+}
+
+static int ma35_nand_read_subpage_hwecc(struct nand_chip *chip, u32 offset,
+					u32 data_len, u8 *buf, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int bitflips = 0;
+	u32 reg;
+
+	/* Enable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg | ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+	nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
+	ma35_write_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi);
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+	if (PREFIX_RA_IS_EMPTY(reg)) {
+		memset((void *)buf, 0xff, mtd->writesize);
+	} else {
+		nand_read_page_op(chip, page, offset, NULL, 0);
+		bitflips = ma35_nand_do_read(chip, buf + offset, data_len);
+		ma35_read_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi, 0);
+	}
+
+	/* Disable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg & ~ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	return bitflips;
+}
+
+static int ma35_nand_read_page_hwecc(struct nand_chip *chip, u8 *buf,
+					int oob_required, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int bitflips = 0;
+	u32 reg;
+
+	/* Enable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg | ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+	nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
+	ma35_write_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi);
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+	if (PREFIX_RA_IS_EMPTY(reg)) {
+		memset((void *)buf, 0xff, mtd->writesize);
+	} else {
+		nand_read_page_op(chip, page, 0, NULL, 0);
+		bitflips = ma35_nand_do_read(chip, buf, mtd->writesize);
+		ma35_read_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi, 0);
+	}
+
+	/* Disable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg & ~ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	return bitflips;
+}
+
+static int ma35_nand_read_oob_hwecc(struct nand_chip *chip, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	u32 reg;
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+	nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
+
+	/* copy OOB data to controller redundant area for page read */
+	ma35_write_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi);
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+	if (PREFIX_RA_IS_EMPTY(reg))
+		memset((void *)chip->oob_poi, 0xff, mtd->oobsize);
+
+	return 0;
+}
+
+static inline void ma35_hw_init(struct ma35_nand_info *nand)
+{
+	u32 reg;
+
+	/* Disable flash wp. */
+	writel(DISABLE_WP, nand->regs + MA35_NFI_REG_NANDECTL);
+
+	/* resets the internal state machine and counters */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	reg |= SWRST;
+	writel(reg, nand->regs + MA35_NFI_REG_NANDCTL);
+}
+
+static irqreturn_t ma35_nand_irq(int irq, void *id)
+{
+	struct ma35_nand_info *nand = (struct ma35_nand_info *)id;
+	u32 isr;
+
+	isr = readl(nand->regs + MA35_NFI_REG_NANDINTSTS);
+	if (isr & INT_DMA) {
+		writel(INT_DMA, nand->regs + MA35_NFI_REG_NANDINTSTS);
+		complete(&nand->complete);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int ma35_nand_attach_chip(struct nand_chip *chip)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct device *dev = mtd->dev.parent;
+	u32 reg;
+
+	if (chip->options & NAND_BUSWIDTH_16) {
+		dev_err(dev, "16 bits bus width not supported");
+		return -EINVAL;
+	}
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~PSIZE_MASK);
+	switch (mtd->writesize) {
+	case SZ_2K:
+		writel(reg | PSIZE_2K, nand->regs + MA35_NFI_REG_NANDCTL);
+		break;
+	case SZ_4K:
+		writel(reg | PSIZE_4K, nand->regs + MA35_NFI_REG_NANDCTL);
+		break;
+	case SZ_8K:
+		writel(reg | PSIZE_8K, nand->regs + MA35_NFI_REG_NANDCTL);
+		break;
+	default:
+		dev_err(dev, "Unsupported page size");
+		return -EINVAL;
+	}
+
+	switch (chip->ecc.engine_type) {
+	case NAND_ECC_ENGINE_TYPE_ON_HOST:
+		/* Do not store BBT bits in the OOB section as it is not protected */
+		if (chip->bbt_options & NAND_BBT_USE_FLASH)
+			chip->bbt_options |= NAND_BBT_NO_OOB;
+		chip->options |= NAND_USES_DMA | NAND_SUBPAGE_READ;
+		chip->ecc.write_subpage = ma35_nand_write_subpage_hwecc;
+		chip->ecc.write_page = ma35_nand_write_page_hwecc;
+		chip->ecc.read_subpage = ma35_nand_read_subpage_hwecc;
+		chip->ecc.read_page  = ma35_nand_read_page_hwecc;
+		chip->ecc.read_oob   = ma35_nand_read_oob_hwecc;
+		return ma35_nand_hwecc_init(chip, nand);
+	case NAND_ECC_ENGINE_TYPE_NONE:
+	case NAND_ECC_ENGINE_TYPE_SOFT:
+	case NAND_ECC_ENGINE_TYPE_ON_DIE:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ma35_nfc_exec_instr(struct nand_chip *chip,
+			      const struct nand_op_instr *instr)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	unsigned int i;
+	int ret = 0;
+	u32 status;
+
+	switch (instr->type) {
+	case NAND_OP_CMD_INSTR:
+		writel(instr->ctx.cmd.opcode, nand->regs + MA35_NFI_REG_NANDCMD);
+		break;
+	case NAND_OP_ADDR_INSTR:
+		for (i = 0; i < instr->ctx.addr.naddrs; i++) {
+			if (i == (instr->ctx.addr.naddrs - 1))
+				writel(instr->ctx.addr.addrs[i] | ENDADDR,
+					nand->regs + MA35_NFI_REG_NANDADDR);
+			else
+				writel(instr->ctx.addr.addrs[i],
+					nand->regs + MA35_NFI_REG_NANDADDR);
+		}
+		break;
+	case NAND_OP_DATA_IN_INSTR:
+		ret = ma35_nand_do_read(chip, instr->ctx.data.buf.in, instr->ctx.data.len);
+		break;
+	case NAND_OP_DATA_OUT_INSTR:
+		ret = ma35_nand_do_write(chip, instr->ctx.data.buf.out, instr->ctx.data.len);
+		break;
+	case NAND_OP_WAITRDY_INSTR:
+		return readl_poll_timeout(nand->regs + MA35_NFI_REG_NANDINTSTS, status,
+					  status & INT_RB0, 20,
+					  instr->ctx.waitrdy.timeout_ms * MSEC_PER_SEC);
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int ma35_nfc_exec_op(struct nand_chip *chip,
+			  const struct nand_operation *op,
+			  bool check_only)
+{
+	int ret = 0;
+	u32 i;
+
+	if (check_only)
+		return 0;
+
+	ma35_nand_target_enable(chip, op->cs);
+
+	for (i = 0; i < op->ninstrs; i++) {
+		ret = ma35_nfc_exec_instr(chip, &op->instrs[i]);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static const struct nand_controller_ops ma35_nfc_ops = {
+	.attach_chip = ma35_nand_attach_chip,
+	.exec_op = ma35_nfc_exec_op,
+};
+
+static int ma35_nand_chip_init(struct device *dev, struct ma35_nand_info *nand,
+				 struct device_node *np)
+{
+	struct ma35_nand_chip *nvtnand;
+	struct nand_chip *chip;
+	struct mtd_info *mtd;
+	int nsels;
+	int ret;
+	u32 cs;
+	int i;
+
+	nsels = of_property_count_elems_of_size(np, "reg", sizeof(u32));
+	if (!nsels || nsels > MA35_MAX_NSELS) {
+		dev_err(dev, "invalid reg property size %d\n", nsels);
+		return -EINVAL;
+	}
+
+	nvtnand = devm_kzalloc(dev, struct_size(nvtnand, sels, nsels),
+			      GFP_KERNEL);
+	if (!nvtnand)
+		return -ENOMEM;
+
+	nvtnand->nsels = nsels;
+	for (i = 0; i < nsels; i++) {
+		ret = of_property_read_u32_index(np, "reg", i, &cs);
+		if (ret) {
+			dev_err(dev, "reg property failure : %d\n", ret);
+			return ret;
+		}
+
+		if (cs >= MA35_MAX_NSELS) {
+			dev_err(dev, "invalid CS: %u\n", cs);
+			return -EINVAL;
+		}
+
+		if (test_and_set_bit(cs, &nand->assigned_cs)) {
+			dev_err(dev, "CS %u already assigned\n", cs);
+			return -EINVAL;
+		}
+
+		nvtnand->sels[i] = cs;
+	}
+
+	chip = &nvtnand->chip;
+	chip->controller = &nand->controller;
+
+	nand_set_flash_node(chip, np);
+	nand_set_controller_data(chip, nand);
+
+	mtd = nand_to_mtd(chip);
+	mtd->owner = THIS_MODULE;
+	mtd->dev.parent = dev;
+
+	mtd_set_ooblayout(mtd, &ma35_ooblayout_ops);
+	ret = nand_scan(chip, nsels);
+	if (ret)
+		return ret;
+
+	ret = mtd_device_register(mtd, NULL, 0);
+	if (ret) {
+		nand_cleanup(chip);
+		return ret;
+	}
+
+	list_add_tail(&nvtnand->node, &nand->chips);
+
+	return 0;
+}
+
+static void ma35_chips_cleanup(struct ma35_nand_info *nand)
+{
+	struct ma35_nand_chip *nvtnand, *tmp;
+	struct nand_chip *chip;
+	int ret;
+
+	list_for_each_entry_safe(nvtnand, tmp, &nand->chips, node) {
+		chip = &nvtnand->chip;
+		ret = mtd_device_unregister(nand_to_mtd(chip));
+		WARN_ON(ret);
+		nand_cleanup(chip);
+		list_del(&nvtnand->node);
+	}
+}
+
+static int ma35_nand_chips_init(struct device *dev, struct ma35_nand_info *nand)
+{
+	struct device_node *np = dev->of_node, *nand_np;
+	int ret;
+
+	for_each_child_of_node(np, nand_np) {
+		ret = ma35_nand_chip_init(dev, nand, nand_np);
+		if (ret) {
+			ma35_chips_cleanup(nand);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int ma35_nand_probe(struct platform_device *pdev)
+{
+	struct ma35_nand_info *nand;
+	int ret = 0;
+
+	nand = devm_kzalloc(&pdev->dev, sizeof(*nand), GFP_KERNEL);
+	if (!nand)
+		return -ENOMEM;
+
+	nand_controller_init(&nand->controller);
+	INIT_LIST_HEAD(&nand->chips);
+	nand->controller.ops = &ma35_nfc_ops;
+
+	init_completion(&nand->complete);
+
+	nand->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(nand->regs))
+		return PTR_ERR(nand->regs);
+
+	nand->dev = &pdev->dev;
+
+	nand->clk = devm_clk_get_enabled(&pdev->dev, "nand_gate");
+	if (IS_ERR(nand->clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(nand->clk),
+				     "failed to find NAND clock\n");
+
+	nand->irq = platform_get_irq(pdev, 0);
+	if (nand->irq < 0)
+		return dev_err_probe(&pdev->dev, nand->irq,
+				     "failed to get platform irq\n");
+
+	ret = devm_request_irq(&pdev->dev, nand->irq, ma35_nand_irq,
+				  IRQF_TRIGGER_HIGH, "ma35d1-nand", nand);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request NAND irq\n");
+		return -ENXIO;
+	}
+
+	platform_set_drvdata(pdev, nand);
+
+	writel(GRST | NAND_EN, nand->regs + MA35_NFI_REG_GCTL);
+	ma35_hw_init(nand);
+	ret = ma35_nand_chips_init(&pdev->dev, nand);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to init NAND chips\n");
+		clk_disable(nand->clk);
+		return ret;
+	}
+
+	return ret;
+}
+
+static void ma35_nand_remove(struct platform_device *pdev)
+{
+	struct ma35_nand_info *nand = platform_get_drvdata(pdev);
+
+	ma35_chips_cleanup(nand);
+}
+
+static const struct of_device_id ma35_nand_of_match[] = {
+	{ .compatible = "nuvoton,ma35d1-nand" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ma35_nand_of_match);
+
+static struct platform_driver ma35_nand_driver = {
+	.driver = {
+		.name = "ma35d1-nand",
+		.of_match_table = ma35_nand_of_match,
+	},
+	.probe = ma35_nand_probe,
+	.remove = ma35_nand_remove,
+};
+
+module_platform_driver(ma35_nand_driver);
+
+MODULE_DESCRIPTION("Nuvoton ma35 NAND driver");
+MODULE_AUTHOR("Hui-Ping Chen <hpchen0nvt at gmail.com>");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From dmitry.baryshkov at linaro.org  Tue Dec  3 19:18:11 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 4 Dec 2024 05:18:11 +0200
Subject: [PATCH v5 7/9] drm/bridge_connector: hook
 drm_atomic_helper_connector_hdmi_update_edid()
In-Reply-To: <87a5dc4zd5.fsf@intel.com>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-7-b5316e82f61a@linaro.org>
 <87a5dc4zd5.fsf@intel.com>
Message-ID: <txzri7x4pdeakx4juandk3hfhsbx3dhlulxfuehqlmrr7b3wpw@jaunqktsro6x>

On Tue, Dec 03, 2024 at 04:25:58PM +0200, Jani Nikula wrote:
> On Sun, 01 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> > Extend drm_bridge_connector code to read the EDID and use it to update
> > connector status if the bridge chain implements HDMI bridge. Performing
> > it from the generic location minimizes individual bridge's code and
> > enforces standard behaviour from all corresponding drivers.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >  drivers/gpu/drm/display/drm_bridge_connector.c | 67 ++++++++++++++++++++------
> >  1 file changed, 53 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
> > index 12ab9f14cc8a8672478ae2804c9a68d766d88ea5..71ae3b2c9049016d1cc0d39a787f6461633efd53 100644
> > --- a/drivers/gpu/drm/display/drm_bridge_connector.c
> > +++ b/drivers/gpu/drm/display/drm_bridge_connector.c
> > @@ -17,6 +17,7 @@
> >  #include <drm/drm_edid.h>
> >  #include <drm/drm_managed.h>
> >  #include <drm/drm_modeset_helper_vtables.h>
> > +#include <drm/drm_print.h>
> >  #include <drm/drm_probe_helper.h>
> >  #include <drm/display/drm_hdmi_state_helper.h>
> >  
> > @@ -175,17 +176,55 @@ static void drm_bridge_connector_disable_hpd(struct drm_connector *connector)
> >   * Bridge Connector Functions
> >   */
> >  
> > +static const struct drm_edid *
> > +drm_bridge_connector_read_edid(struct drm_connector *connector,
> > +			       enum drm_connector_status status)
> > +{
> > +	struct drm_bridge_connector *bridge_connector =
> > +		to_drm_bridge_connector(connector);
> > +	const struct drm_edid *drm_edid;
> > +	struct drm_bridge *bridge;
> > +
> > +	bridge = bridge_connector->bridge_edid;
> > +	if (!bridge)
> > +		return NULL;
> > +
> > +	if (status != connector_status_connected)
> > +		return NULL;
> > +
> > +	drm_edid = drm_bridge_edid_read(bridge, connector);
> > +	if (!drm_edid_valid(drm_edid)) {
> 
> What's the case this check is for?
> 
> My preference would be that bridge->funcs->edid_read() uses
> drm_edid_read*() family of functions that do the checks and return the
> EDID.
> 
> There are some cases that just allocate a blob and return it. Would be
> nice if they could be converted, but in the mean time could use
> drm_edid_valid() right there. Additional validity checks are redundant.

This was c&p from drm_bridge_connector_get_modes_edid(). If you think
that the check is redundant, could you please send a patch dropping the
check?

> 
> BR,
> Jani.
> 
> 
> > +		drm_edid_free(drm_edid);
> > +		return NULL;
> > +	}
> > +
> > +	return drm_edid;
> > +}
> > +
> >  static enum drm_connector_status
> >  drm_bridge_connector_detect(struct drm_connector *connector, bool force)
> >  {
> >  	struct drm_bridge_connector *bridge_connector =
> >  		to_drm_bridge_connector(connector);
> >  	struct drm_bridge *detect = bridge_connector->bridge_detect;
> > +	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
> >  	enum drm_connector_status status;
> >  
> >  	if (detect) {
> >  		status = detect->funcs->detect(detect);
> >  
> > +		if (hdmi) {
> > +			const struct drm_edid *drm_edid;
> > +			int ret;
> > +
> > +			drm_edid = drm_bridge_connector_read_edid(connector, status);
> > +			ret = drm_atomic_helper_connector_hdmi_update_edid(connector, drm_edid);
> > +			if (ret)
> > +				drm_warn(connector->dev, "updating EDID failed with %d\n", ret);
> > +
> > +			drm_edid_free(drm_edid);
> > +		}
> > +
> >  		drm_bridge_connector_hpd_notify(connector, status);
> >  	} else {
> >  		switch (connector->connector_type) {
> > @@ -246,29 +285,29 @@ static const struct drm_connector_funcs drm_bridge_connector_funcs = {
> >  static int drm_bridge_connector_get_modes_edid(struct drm_connector *connector,
> >  					       struct drm_bridge *bridge)
> >  {
> > +	struct drm_bridge_connector *bridge_connector =
> > +		to_drm_bridge_connector(connector);
> > +	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
> >  	enum drm_connector_status status;
> >  	const struct drm_edid *drm_edid;
> > -	int n;
> >  
> >  	status = drm_bridge_connector_detect(connector, false);
> >  	if (status != connector_status_connected)
> > -		goto no_edid;
> > +		return 0;
> >  
> > -	drm_edid = drm_bridge_edid_read(bridge, connector);
> > -	if (!drm_edid_valid(drm_edid)) {
> > +	/* In HDMI setup the EDID has been read and handled as a part of .detect() */
> > +	if (!hdmi) {
> > +		drm_edid = drm_bridge_connector_read_edid(connector, status);
> > +		if (!drm_edid) {
> > +			drm_edid_connector_update(connector, NULL);
> > +			return 0;
> > +		}
> > +
> > +		drm_edid_connector_update(connector, drm_edid);
> >  		drm_edid_free(drm_edid);
> > -		goto no_edid;
> >  	}
> >  
> > -	drm_edid_connector_update(connector, drm_edid);
> > -	n = drm_edid_connector_add_modes(connector);
> > -
> > -	drm_edid_free(drm_edid);
> > -	return n;
> > -
> > -no_edid:
> > -	drm_edid_connector_update(connector, NULL);
> > -	return 0;
> > +	return drm_edid_connector_add_modes(connector);
> >  }
> >  
> >  static int drm_bridge_connector_get_modes(struct drm_connector *connector)
> 
> -- 
> Jani Nikula, Intel

-- 
With best wishes
Dmitry


From andersson at kernel.org  Tue Dec  3 19:29:00 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Tue,  3 Dec 2024 21:29:00 -0600
Subject: (subset) [PATCH v4 0/4] Add initial support for QCS8300 SoC and QCS8300 RIDE board
In-Reply-To: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
References: <20241203-qcs8300_initial_dtsi-v4-0-d7c953484024@quicinc.com>
Message-ID: <173328293797.350699.5295104276161877235.b4-ty@kernel.org>


On Tue, 03 Dec 2024 17:27:11 +0800, Jingyi Wang wrote:
> Introduce the Device Tree for the QCS8300 platform.
> 
> Features added and enabled:
> - CPUs with PSCI idle states
> - Interrupt-controller with PDC wakeup support
> - Timers, TCSR Clock Controllers
> - Reserved Shared memory
> - GCC and RPMHCC
> - TLMM
> - Interconnect
> - QuP with uart
> - SMMU
> - QFPROM
> - Rpmhpd power controller
> - UFS
> - Inter-Processor Communication Controller
> - SRAM
> - Remoteprocs including ADSP,CDSP and GPDSP
> - BWMONs
> 
> [...]

Applied, thanks!

[1/4] dt-bindings: arm: qcom: document QCS8300 SoC and reference board
      commit: d511280ce9cc5920442e78a589946f63c247dd3b
[3/4] arm64: dts: qcom: add QCS8300 platform
      commit: 7be190e4bdd2bd1aca84afef06bb755c06a85473
[4/4] arm64: dts: qcom: add base QCS8300 RIDE board
      commit: 45d55e2da9bd10d24c4730b452b11a76dc3960b8

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From viresh.kumar at linaro.org  Tue Dec  3 19:37:15 2024
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 4 Dec 2024 09:07:15 +0530
Subject: [PATCH] rtc: RTC_DRV_SPEAR should not default to y when
 compile-testing
In-Reply-To: <7b8eefe3b0150101ba01c3ea55e45aa3134059ba.1733243007.git.geert+renesas@glider.be>
References: <7b8eefe3b0150101ba01c3ea55e45aa3134059ba.1733243007.git.geert+renesas@glider.be>
Message-ID: <20241204033715.xzojqni2byocnt5m@vireshk-i7>

On 03-12-24, 17:25, Geert Uytterhoeven wrote:
> Merely enabling compile-testing should not enable additional
> functionality.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
>  drivers/rtc/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index a60bcc791a4803b7..0bbbf778ecfa3e4c 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1316,7 +1316,7 @@ config RTC_DRV_SC27XX
>  config RTC_DRV_SPEAR
>  	tristate "SPEAR ST RTC"
>  	depends on PLAT_SPEAR || COMPILE_TEST
> -	default y
> +	default PLAT_SPEAR
>  	help
>  	 If you say Y here you will get support for the RTC found on
>  	 spear

Acked-by: Viresh Kumar <viresh.kumar at linaro.org>

-- 
viresh


From andrew at codeconstruct.com.au  Tue Dec  3 20:08:53 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Wed, 04 Dec 2024 14:38:53 +1030
Subject: [PATCH] ARM: dts: aspeed: Enable video engine for IBM System1
In-Reply-To: <20241203-dts-system1-video-v1-1-008e5e660106@gmail.com>
References: <20241203-dts-system1-video-v1-1-008e5e660106@gmail.com>
Message-ID: <9ff74b8a13ff58921a4f7f18dbded9c06b195c06.camel@codeconstruct.com.au>

Hi Manoj,

On Tue, 2024-12-03 at 18:52 +0530, Manojkiran Eda via B4 Relay wrote:
> From: Manojkiran Eda <manojkiran.eda at gmail.com>
> 
> Signed-off-by: Manojkiran Eda <manojkiran.eda at gmail.com>
> ---
> This patch enables the aspeed video engine support in ASPEED BMC for
> IBM System1. It is crucial for facilitating the BMC's video capture
> and redirection capabilities, which are integral to remote management
> and KVM (Keyboard-Video-Mouse) over IP functionality.

Can you please put this in the body of the commit message rather than
in a comment?

Commit messages need a body and not just a subject.

Cheers,

Andrew



From s-vadapalli at ti.com  Tue Dec  3 21:01:50 2024
From: s-vadapalli at ti.com (s-vadapalli)
Date: Wed, 4 Dec 2024 10:31:50 +0530
Subject: [PATCH] arm64: dts: ti: k3-am69-sk: Add USB SuperSpeed support
In-Reply-To: <CALE0LRvZNnNJ8jBG35bU8Ev5Fvr2400O5qXUsRn0zufkidJeJw@mail.gmail.com>
References: <20241126-am69sk-dt-usb-v1-1-aa55aed7b89e@redhat.com>
 <2nuncc5rscu6h74ylaiu6yozg34aoigaj5d4uzvdtolt5q7bmv@6hacpxyb2532>
 <CALE0LRtUN2N_Z05jH_BMSg7yvirSRob0pSErmQxTu8AatmODgw@mail.gmail.com>
 <CALE0LRu-Sx5oTVNY3hm+Msu-zb04a7_ZD+r3xF1eRfR_WtK0VA@mail.gmail.com>
 <wbsg3fmco6rwjj7vtiqtqv7trfjor73j7rjx7efnlafo4pz4bc@awixm2iygd55>
 <CALE0LRvZNnNJ8jBG35bU8Ev5Fvr2400O5qXUsRn0zufkidJeJw@mail.gmail.com>
Message-ID: <o37g5m3qvod4mydnjytyubobmvit7zjmh5xhv6jxjze3reiqct@wkwm36yvftyr>

On Tue, Dec 03, 2024 at 04:29:02PM +0100, Enric Balletbo i Serra wrote:
> Hi,
> 
> On Thu, Nov 28, 2024 at 10:58?AM s-vadapalli <s-vadapalli at ti.com> wrote:
> >
> > On Thu, Nov 28, 2024 at 10:47:42AM +0100, Enric Balletbo i Serra wrote:
> > > Hi,
> >
> > [...]
> >
> > > So I changed the dr_mode to otg instead of host and tried to configure
> > > a usb mass storage gadget but unfortunately didn't work, but this
> > > could be a driver problem, I got the following error
> > >
> > >   UDC core: g1: couldn't find an available UDC
> > >
> > > As the devicetree should describe the hardware, and as far as I can
> > > see it should support the type-c port act as a gadget, I'm fine with
> > > changing the dr_mode, unless anyone have more information about this,
> > > the thing that makes me think a bit more is that, in the TI kernel
> > > this is set to host, so I'm wondering if I'm missing something or is
> > > just that was never tested.
> >
> > Are all interfaces (Type-A and Type-C) functional as Host when the
> > dr_mode is set to "otg"? (Do USB devices connected to the interfaces
> > enumerate on AM69-SK?) If yes, then it could be a DIP Switch setting
> > that is related to OTG mode of operation or a USB-C Mux that needs to be
> > configured.
> >
> 
> Yes, all interfaces (Type-A and Type-C) are functional as host when
> the dr_mode is set to "otg". Looking at SK-AM69 Processor Start Kit
> User's Guide (Rev. A) [1] I don't see any DIP Switch related to the
> OTG  mode. Looks like the type-c connector connects directly to the
> SoC through a USB HUB (TUSB4041).
> 
> [1] https://www.ti.com/lit/ug/spruj70a/spruj70a.pdf?ts=1733215039014

In that case, please post the patch setting "dr_mode" to "otg". As to
why "peripheral"/"gadget" operation doesn't work could be addressed
separately and seems to be independent of the device-tree. The reason
for suggesting "otg" instead of "host" is to ensure that the device-tree
describes the Hardware. Since "host" mode is still functional with
"dr_mode" set to "otg", at-least for the use-cases that you have in mind,
I believe that "otg" should be acceptable.

Regards,
Siddharth.


From xu.yang_2 at nxp.com  Tue Dec  3 21:09:06 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed,  4 Dec 2024 13:09:06 +0800
Subject: [PATCH v11 2/3] arm64: dts: imx95: add usb3 related nodes
In-Reply-To: <20241204050907.1081781-1-xu.yang_2@nxp.com>
References: <20241204050907.1081781-1-xu.yang_2@nxp.com>
Message-ID: <20241204050907.1081781-2-xu.yang_2@nxp.com>

Add usb3 phy and controller nodes for imx95.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - no changes
Changes in v4:
 - reorder nodes
Changes in v5:
 - no changes
Changes in v6:
 - rebase to latest
Changes in v7:
 - no changes
Changes in v8:
 - no changes
Changes in v9:
 - no changes
Changes in v10:
 - move orientation-switch to dts
 - rebase to latest
Changes in v11:
 - no changes
---
 arch/arm64/boot/dts/freescale/imx95.dtsi | 42 ++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index d10f62eacfe0..facdfa37073e 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -1537,6 +1537,48 @@ smmu: iommu at 490d0000 {
 			};
 		};
 
+		usb3: usb at 4c010010 {
+			compatible = "fsl,imx95-dwc3", "fsl,imx8mp-dwc3";
+			reg = <0x0 0x4c010010 0x0 0x04>,
+			      <0x0 0x4c1f0000 0x0 0x20>;
+			clocks = <&scmi_clk IMX95_CLK_HSIO>,
+				 <&scmi_clk IMX95_CLK_32K>;
+			clock-names = "hsio", "suspend";
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+			dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+			status = "disabled";
+
+			usb3_dwc3: usb at 4c100000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x4c100000 0x0 0x10000>;
+				clocks = <&scmi_clk IMX95_CLK_HSIO>,
+					 <&scmi_clk IMX95_CLK_24M>,
+					 <&scmi_clk IMX95_CLK_32K>;
+				clock-names = "bus_early", "ref", "suspend";
+				interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+				phys = <&usb3_phy>, <&usb3_phy>;
+				phy-names = "usb2-phy", "usb3-phy";
+				snps,gfladj-refclk-lpm-sel-quirk;
+				snps,parkmode-disable-ss-quirk;
+				iommus = <&smmu 0xe>;
+			};
+		};
+
+		usb3_phy: phy at 4c1f0040 {
+			compatible = "fsl,imx95-usb-phy", "fsl,imx8mp-usb-phy";
+			reg = <0x0 0x4c1f0040 0x0 0x40>,
+			      <0x0 0x4c1fc000 0x0 0x100>;
+			clocks = <&scmi_clk IMX95_CLK_HSIO>;
+			clock-names = "phy";
+			#phy-cells = <0>;
+			power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
+			status = "disabled";
+		};
+
 		pcie0: pcie at 4c300000 {
 			compatible = "fsl,imx95-pcie";
 			reg = <0 0x4c300000 0 0x10000>,
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Dec  3 21:09:05 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed,  4 Dec 2024 13:09:05 +0800
Subject: [PATCH v11 1/3] phy: fsl-imx8mq-usb: add tca function driver for imx95
Message-ID: <20241204050907.1081781-1-xu.yang_2@nxp.com>

The i.MX95 USB3 phy has a Type-C Assist block (TCA). This block consists
two functional blocks (XBar assist and VBus assist) and one system
access interface using APB.

The primary functionality of XBar assist is:
 - switching lane for flip
 - moving unused lanes into lower power states.

This info can be get from:
i.MX95 RM Chapter 163.3.8 Type-C assist (TCA) block.

This will add support for TCA block to achieve lane switching and tca
lower power functionality.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
Reviewed-by: Jun Li <jun.li at nxp.com>

---
Changes in v2:
 - return the value of imx95_usb_phy_get_tca()
Changes in v3:
 - no changes
Changes in v4:
 - remove compatible check for imx95
 - check whether tca register region exist or not, yes means has tca,
   otherwise skip tca setup
Changes in v5:
 - no changes
Changes in v6:
 - no changes
Changes in v7:
 - fix sparse warnings in imx95_usb_phy_get_tca()
Changes in v8:
 - #define TCA_INFO 0xFC -> 0xfc
Changes in v9:
 - no changes
Changes in v10:
 - no changes
Changes in v11:
 - remove some unnecessary readl() as suggested by Amit Singh Tomar
---
 drivers/phy/freescale/Kconfig              |   1 +
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 240 +++++++++++++++++++++
 2 files changed, 241 insertions(+)

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index dcd9acff6d01..81f53564ee15 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -5,6 +5,7 @@ if (ARCH_MXC && ARM64) || COMPILE_TEST
 config PHY_FSL_IMX8MQ_USB
 	tristate "Freescale i.MX8M USB3 PHY"
 	depends on OF && HAS_IOMEM
+	depends on TYPEC || TYPEC=n
 	select GENERIC_PHY
 	default ARCH_MXC && ARM64
 
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index adc6394626ce..a974ef94de9a 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -10,6 +10,7 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/usb/typec_mux.h>
 
 #define PHY_CTRL0			0x0
 #define PHY_CTRL0_REF_SSP_EN		BIT(2)
@@ -50,11 +51,66 @@
 
 #define PHY_TUNE_DEFAULT		0xffffffff
 
+#define TCA_CLK_RST			0x00
+#define TCA_CLK_RST_SW			BIT(9)
+#define TCA_CLK_RST_REF_CLK_EN		BIT(1)
+#define TCA_CLK_RST_SUSPEND_CLK_EN	BIT(0)
+
+#define TCA_INTR_EN			0x04
+#define TCA_INTR_STS			0x08
+
+#define TCA_GCFG			0x10
+#define TCA_GCFG_ROLE_HSTDEV		BIT(4)
+#define TCA_GCFG_OP_MODE		GENMASK(1, 0)
+#define TCA_GCFG_OP_MODE_SYSMODE	0
+#define TCA_GCFG_OP_MODE_SYNCMODE	1
+
+#define TCA_TCPC			0x14
+#define TCA_TCPC_VALID			BIT(4)
+#define TCA_TCPC_LOW_POWER_EN		BIT(3)
+#define TCA_TCPC_ORIENTATION_NORMAL	BIT(2)
+#define TCA_TCPC_MUX_CONTRL		GENMASK(1, 0)
+#define TCA_TCPC_MUX_CONTRL_NO_CONN	0
+#define TCA_TCPC_MUX_CONTRL_USB_CONN	1
+
+#define TCA_SYSMODE_CFG			0x18
+#define TCA_SYSMODE_TCPC_DISABLE	BIT(3)
+#define TCA_SYSMODE_TCPC_FLIP		BIT(2)
+
+#define TCA_CTRLSYNCMODE_CFG0		0x20
+#define TCA_CTRLSYNCMODE_CFG1           0x20
+
+#define TCA_PSTATE			0x30
+#define TCA_PSTATE_CM_STS		BIT(4)
+#define TCA_PSTATE_TX_STS		BIT(3)
+#define TCA_PSTATE_RX_PLL_STS		BIT(2)
+#define TCA_PSTATE_PIPE0_POWER_DOWN	GENMASK(1, 0)
+
+#define TCA_GEN_STATUS			0x34
+#define TCA_GEN_DEV_POR			BIT(12)
+#define TCA_GEN_REF_CLK_SEL		BIT(8)
+#define TCA_GEN_TYPEC_FLIP_INVERT	BIT(4)
+#define TCA_GEN_PHY_TYPEC_DISABLE	BIT(3)
+#define TCA_GEN_PHY_TYPEC_FLIP		BIT(2)
+
+#define TCA_VBUS_CTRL			0x40
+#define TCA_VBUS_STATUS			0x44
+
+#define TCA_INFO			0xfc
+
+struct tca_blk {
+	struct typec_switch_dev *sw;
+	void __iomem *base;
+	struct mutex mutex;
+	enum typec_orientation orientation;
+};
+
 struct imx8mq_usb_phy {
 	struct phy *phy;
 	struct clk *clk;
 	void __iomem *base;
 	struct regulator *vbus;
+	struct tca_blk *tca;
 	u32 pcs_tx_swing_full;
 	u32 pcs_tx_deemph_3p5db;
 	u32 tx_vref_tune;
@@ -64,6 +120,172 @@ struct imx8mq_usb_phy {
 	u32 comp_dis_tune;
 };
 
+
+static void tca_blk_orientation_set(struct tca_blk *tca,
+				enum typec_orientation orientation);
+
+#ifdef CONFIG_TYPEC
+
+static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
+				enum typec_orientation orientation)
+{
+	struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
+	struct tca_blk *tca = imx_phy->tca;
+	int ret;
+
+	if (tca->orientation == orientation)
+		return 0;
+
+	ret = clk_prepare_enable(imx_phy->clk);
+	if (ret)
+		return ret;
+
+	tca_blk_orientation_set(tca, orientation);
+	clk_disable_unprepare(imx_phy->clk);
+
+	return 0;
+}
+
+static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
+					struct imx8mq_usb_phy *imx_phy)
+{
+	struct device *dev = &pdev->dev;
+	struct typec_switch_dev *sw;
+	struct typec_switch_desc sw_desc = { };
+
+	sw_desc.drvdata = imx_phy;
+	sw_desc.fwnode = dev->fwnode;
+	sw_desc.set = tca_blk_typec_switch_set;
+	sw_desc.name = NULL;
+
+	sw = typec_switch_register(dev, &sw_desc);
+	if (IS_ERR(sw)) {
+		dev_err(dev, "Error register tca orientation switch: %ld",
+				PTR_ERR(sw));
+		return NULL;
+	}
+
+	return sw;
+}
+
+static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
+{
+	typec_switch_unregister(sw);
+}
+
+#else
+
+static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
+			struct imx8mq_usb_phy *imx_phy)
+{
+	return NULL;
+}
+
+static void tca_blk_put_typec_switch(struct typec_switch_dev *sw) {}
+
+#endif /* CONFIG_TYPEC */
+
+static void tca_blk_orientation_set(struct tca_blk *tca,
+				enum typec_orientation orientation)
+{
+	u32 val;
+
+	mutex_lock(&tca->mutex);
+
+	if (orientation == TYPEC_ORIENTATION_NONE) {
+		/*
+		 * use Controller Synced Mode for TCA low power enable and
+		 * put PHY to USB safe state.
+		 */
+		val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYNCMODE);
+		writel(val, tca->base + TCA_GCFG);
+
+		val = TCA_TCPC_VALID | TCA_TCPC_LOW_POWER_EN;
+		writel(val, tca->base + TCA_TCPC);
+
+		goto out;
+	}
+
+	/* use System Configuration Mode for TCA mux control. */
+	val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYSMODE);
+	writel(val, tca->base + TCA_GCFG);
+
+	/* Disable TCA module */
+	val = readl(tca->base + TCA_SYSMODE_CFG);
+	val |= TCA_SYSMODE_TCPC_DISABLE;
+	writel(val, tca->base + TCA_SYSMODE_CFG);
+
+	if (orientation == TYPEC_ORIENTATION_REVERSE)
+		val |= TCA_SYSMODE_TCPC_FLIP;
+	else if (orientation == TYPEC_ORIENTATION_NORMAL)
+		val &= ~TCA_SYSMODE_TCPC_FLIP;
+
+	writel(val, tca->base + TCA_SYSMODE_CFG);
+
+	/* Enable TCA module */
+	val &= ~TCA_SYSMODE_TCPC_DISABLE;
+	writel(val, tca->base + TCA_SYSMODE_CFG);
+
+out:
+	tca->orientation = orientation;
+	mutex_unlock(&tca->mutex);
+}
+
+static void tca_blk_init(struct tca_blk *tca)
+{
+	u32 val;
+
+	/* reset XBar block */
+	val = readl(tca->base + TCA_CLK_RST);
+	val &= ~TCA_CLK_RST_SW;
+	writel(val, tca->base + TCA_CLK_RST);
+
+	udelay(100);
+
+	/* clear reset */
+	val |= TCA_CLK_RST_SW;
+	writel(val, tca->base + TCA_CLK_RST);
+
+	tca_blk_orientation_set(tca, tca->orientation);
+}
+
+static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
+				struct imx8mq_usb_phy *imx_phy)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct tca_blk *tca;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res)
+		return NULL;
+
+	tca = devm_kzalloc(dev, sizeof(*tca), GFP_KERNEL);
+	if (!tca)
+		return ERR_PTR(-ENOMEM);
+
+	tca->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tca->base))
+		return ERR_CAST(tca->base);
+
+	mutex_init(&tca->mutex);
+
+	tca->orientation = TYPEC_ORIENTATION_NORMAL;
+	tca->sw = tca_blk_get_typec_switch(pdev, imx_phy);
+
+	return tca;
+}
+
+static void imx95_usb_phy_put_tca(struct imx8mq_usb_phy *imx_phy)
+{
+	struct tca_blk *tca = imx_phy->tca;
+
+	if (!tca)
+		return;
+
+	tca_blk_put_typec_switch(tca->sw);
+}
+
 static u32 phy_tx_vref_tune_from_property(u32 percent)
 {
 	percent = clamp(percent, 94U, 124U);
@@ -315,6 +537,9 @@ static int imx8mp_usb_phy_init(struct phy *phy)
 
 	imx8m_phy_tune(imx_phy);
 
+	if (imx_phy->tca)
+		tca_blk_init(imx_phy->tca);
+
 	return 0;
 }
 
@@ -359,6 +584,8 @@ static const struct of_device_id imx8mq_usb_phy_of_match[] = {
 	 .data = &imx8mq_usb_phy_ops,},
 	{.compatible = "fsl,imx8mp-usb-phy",
 	 .data = &imx8mp_usb_phy_ops,},
+	{.compatible = "fsl,imx95-usb-phy",
+	 .data = &imx8mp_usb_phy_ops,},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
@@ -398,6 +625,11 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 
 	phy_set_drvdata(imx_phy->phy, imx_phy);
 
+	imx_phy->tca = imx95_usb_phy_get_tca(pdev, imx_phy);
+	if (IS_ERR(imx_phy->tca))
+		return dev_err_probe(dev, PTR_ERR(imx_phy->tca),
+					"failed to get tca\n");
+
 	imx8m_get_phy_tuning_data(imx_phy);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
@@ -405,8 +637,16 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	return PTR_ERR_OR_ZERO(phy_provider);
 }
 
+static void imx8mq_usb_phy_remove(struct platform_device *pdev)
+{
+	struct imx8mq_usb_phy *imx_phy = platform_get_drvdata(pdev);
+
+	imx95_usb_phy_put_tca(imx_phy);
+}
+
 static struct platform_driver imx8mq_usb_phy_driver = {
 	.probe	= imx8mq_usb_phy_probe,
+	.remove = imx8mq_usb_phy_remove,
 	.driver = {
 		.name	= "imx8mq-usb-phy",
 		.of_match_table	= imx8mq_usb_phy_of_match,
-- 
2.34.1



From xu.yang_2 at nxp.com  Tue Dec  3 21:09:07 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed,  4 Dec 2024 13:09:07 +0800
Subject: [PATCH v11 3/3] arm64: dts: imx95-19x19-evk: add typec nodes and enable usb3 node
In-Reply-To: <20241204050907.1081781-1-xu.yang_2@nxp.com>
References: <20241204050907.1081781-1-xu.yang_2@nxp.com>
Message-ID: <20241204050907.1081781-3-xu.yang_2@nxp.com>

This board has one Type-C port which has USB3 capability. This will
add typec nodes and enable usb3 node.

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:
 - correct nodes order
Changes in v6:
 - rebase to latest
Changes in v7:
 - no changes
Changes in v8:
 - no changes
Changes in v9:
 - add tunning param for usb3_phy
Changes in v10:
 - move orientation-switch from dtsi
 - rebase to latest
Changes in v11:
 - no changes
---
 .../boot/dts/freescale/imx95-19x19-evk.dts    | 83 +++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
index 6086cb7fa5a0..68b2ae091279 100644
--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/usb/pd.h>
 #include "imx95.dtsi"
 
 #define FALLING_EDGE			1
@@ -308,6 +309,48 @@ i2c7_pcal6524: i2c7-gpio at 22 {
 		interrupt-parent = <&gpio5>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
 	};
+
+	ptn5110: tcpc at 50 {
+		compatible = "nxp,ptn5110", "tcpci";
+		reg = <0x50>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_typec>;
+		interrupt-parent = <&gpio5>;
+		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+
+		typec_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, 0, PDO_FIXED_USB_COMM)>;
+			op-sink-microwatt = <0>;
+			self-powered;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					typec_con_hs: endpoint {
+						remote-endpoint = <&usb3_data_hs>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					typec_con_ss: endpoint {
+						remote-endpoint = <&usb3_data_ss>;
+					};
+				};
+			};
+		};
+	};
 };
 
 &lpuart1 {
@@ -390,6 +433,40 @@ &sai3 {
 	status = "okay";
 };
 
+&usb3 {
+	status = "okay";
+};
+
+&usb3_dwc3 {
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	usb-role-switch;
+	role-switch-default-mode = "peripheral";
+	snps,dis-u1-entry-quirk;
+	snps,dis-u2-entry-quirk;
+	status = "okay";
+
+	port {
+		usb3_data_hs: endpoint {
+			remote-endpoint = <&typec_con_hs>;
+		};
+	};
+};
+
+&usb3_phy {
+	fsl,phy-tx-preemp-amp-tune-microamp = <600>;
+	orientation-switch;
+	status = "okay";
+
+	port {
+		usb3_data_ss: endpoint {
+			remote-endpoint = <&typec_con_ss>;
+		};
+	};
+};
+
 &usdhc1 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
 	pinctrl-0 = <&pinctrl_usdhc1>;
@@ -624,6 +701,12 @@ IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7		0x31e
 		>;
 	};
 
+	pinctrl_typec: typecgrp {
+		fsl,pins = <
+			IMX95_PAD_GPIO_IO34__GPIO5_IO_BIT14			0x31e
+		>;
+	};
+
 	pinctrl_usdhc2_gpio: usdhc2gpiogrp {
 		fsl,pins = <
 			IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0		0x31e
-- 
2.34.1



From fshao at chromium.org  Tue Dec  3 21:32:33 2024
From: fshao at chromium.org (Fei Shao)
Date: Wed,  4 Dec 2024 13:32:33 +0800
Subject: [PATCH] drm/mediatek: dp: Support flexible length of DP calibration data
Message-ID: <20241204053634.1365491-1-fshao@chromium.org>

The DP calibration data is stored in nvmem cells, and the data layout is
described in the `mtk_dp_efuse_fmt` arrays for each platform.

There is no guarantee that the data is always a 4-length u32 buffer.
For example, MT8188 has a data length of 3, preventing it from passing
the preliminary check and undergoing calibration.

Update the logic to support flexible data lengths. Specifically, we
validate the length returned from `nvmem_cell_read()` against the
platform-specific efuse format. If out-of-bound access is detected, fall
back to the default calibration values. This likely indicates an error
in either the efuse data length described in DT or the efuse format
within the driver.

Signed-off-by: Fei Shao <fshao at chromium.org>
---

 drivers/gpu/drm/mediatek/mtk_dp.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 1cc916b16471..e9ff6fdfd6ee 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -1165,17 +1165,25 @@ static void mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
 	buf = (u32 *)nvmem_cell_read(cell, &len);
 	nvmem_cell_put(cell);
 
-	if (IS_ERR(buf) || ((len / sizeof(u32)) != 4)) {
+	if (IS_ERR(buf)) {
 		dev_warn(dev, "Failed to read nvmem_cell_read\n");
-
-		if (!IS_ERR(buf))
-			kfree(buf);
-
 		goto use_default_val;
 	}
 
+	/* The cell length is in bytes. Convert it to be compatible with u32 buffer. */
+	len /= sizeof(u32);
+
 	for (i = 0; i < MTK_DP_CAL_MAX; i++) {
 		fmt = &mtk_dp->data->efuse_fmt[i];
+
+		if (fmt->idx >= len) {
+			dev_warn(mtk_dp->dev,
+				 "Out-of-bound efuse data access, fmt idx = %d, buf len = %lu\n",
+				 fmt->idx, len);
+			kfree(buf);
+			goto use_default_val;
+		}
+
 		cal_data[i] = (buf[fmt->idx] >> fmt->shift) & fmt->mask;
 
 		if (cal_data[i] < fmt->min_val || cal_data[i] > fmt->max_val) {
-- 
2.47.0.338.g60cca15819-goog



From lkp at intel.com  Tue Dec  3 22:42:17 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 4 Dec 2024 14:42:17 +0800
Subject: [PATCH v2 2/9] coresight-etm4x: change etmv4_drvdata spinlock
 type to raw_spinlock_t
In-Reply-To: <20241203114942.697188-3-yeoreum.yun@arm.com>
References: <20241203114942.697188-3-yeoreum.yun@arm.com>
Message-ID: <202412041452.KCrCJWWm-lkp@intel.com>

Hi Yeoreum,

kernel test robot noticed the following build errors:

[auto build test ERROR on soc/for-next]
[also build test ERROR on linus/master v6.13-rc1 next-20241128]
[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/Yeoreum-Yun/coresight-change-coresight_device-lock-type-to-raw_spinlock_t/20241203-203214
base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
patch link:    https://lore.kernel.org/r/20241203114942.697188-3-yeoreum.yun%40arm.com
patch subject: [PATCH v2 2/9] coresight-etm4x: change etmv4_drvdata spinlock type to raw_spinlock_t
config: arm64-randconfig-001-20241204 (https://download.01.org/0day-ci/archive/20241204/202412041452.KCrCJWWm-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241204/202412041452.KCrCJWWm-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/202412041452.KCrCJWWm-lkp at intel.com/

All errors (new ones prefixed by >>):

   drivers/hwtracing/coresight/coresight-etm4x-core.c: In function 'etm4_starting_cpu':
>> drivers/hwtracing/coresight/coresight-etm4x-core.c:1666:19: error: passing argument 1 of 'spin_lock' from incompatible pointer type [-Wincompatible-pointer-types]
    1666 |         spin_lock(&etmdrvdata[cpu]->spinlock);
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~
         |                   |
         |                   raw_spinlock_t * {aka struct raw_spinlock *}
   In file included from include/linux/mmzone.h:8,
                    from include/linux/gfp.h:7,
                    from include/linux/slab.h:16,
                    from include/linux/resource_ext.h:11,
                    from include/linux/acpi.h:13,
                    from drivers/hwtracing/coresight/coresight-etm4x-core.c:6:
   include/linux/spinlock.h:349:51: note: expected 'spinlock_t *' {aka 'struct spinlock *'} but argument is of type 'raw_spinlock_t *' {aka 'struct raw_spinlock *'}
     349 | static __always_inline void spin_lock(spinlock_t *lock)
         |                                       ~~~~~~~~~~~~^~~~
>> drivers/hwtracing/coresight/coresight-etm4x-core.c:1672:21: error: passing argument 1 of 'spin_unlock' from incompatible pointer type [-Wincompatible-pointer-types]
    1672 |         spin_unlock(&etmdrvdata[cpu]->spinlock);
         |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~
         |                     |
         |                     raw_spinlock_t * {aka struct raw_spinlock *}
   include/linux/spinlock.h:389:53: note: expected 'spinlock_t *' {aka 'struct spinlock *'} but argument is of type 'raw_spinlock_t *' {aka 'struct raw_spinlock *'}
     389 | static __always_inline void spin_unlock(spinlock_t *lock)
         |                                         ~~~~~~~~~~~~^~~~
   drivers/hwtracing/coresight/coresight-etm4x-core.c: In function 'etm4_dying_cpu':
   drivers/hwtracing/coresight/coresight-etm4x-core.c:1681:19: error: passing argument 1 of 'spin_lock' from incompatible pointer type [-Wincompatible-pointer-types]
    1681 |         spin_lock(&etmdrvdata[cpu]->spinlock);
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~
         |                   |
         |                   raw_spinlock_t * {aka struct raw_spinlock *}
   include/linux/spinlock.h:349:51: note: expected 'spinlock_t *' {aka 'struct spinlock *'} but argument is of type 'raw_spinlock_t *' {aka 'struct raw_spinlock *'}
     349 | static __always_inline void spin_lock(spinlock_t *lock)
         |                                       ~~~~~~~~~~~~^~~~
   drivers/hwtracing/coresight/coresight-etm4x-core.c:1684:21: error: passing argument 1 of 'spin_unlock' from incompatible pointer type [-Wincompatible-pointer-types]
    1684 |         spin_unlock(&etmdrvdata[cpu]->spinlock);
         |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~
         |                     |
         |                     raw_spinlock_t * {aka struct raw_spinlock *}
   include/linux/spinlock.h:389:53: note: expected 'spinlock_t *' {aka 'struct spinlock *'} but argument is of type 'raw_spinlock_t *' {aka 'struct raw_spinlock *'}
     389 | static __always_inline void spin_unlock(spinlock_t *lock)
         |                                         ~~~~~~~~~~~~^~~~


vim +/spin_lock +1666 drivers/hwtracing/coresight/coresight-etm4x-core.c

2e1cdfe184b520 drivers/hwtracing/coresight/coresight-etm4x.c      Pratik Patel              2015-05-13  1660  
58eb457be0283d drivers/hwtracing/coresight/coresight-etm4x.c      Sebastian Andrzej Siewior 2016-07-13  1661  static int etm4_starting_cpu(unsigned int cpu)
58eb457be0283d drivers/hwtracing/coresight/coresight-etm4x.c      Sebastian Andrzej Siewior 2016-07-13  1662  {
2e1cdfe184b520 drivers/hwtracing/coresight/coresight-etm4x.c      Pratik Patel              2015-05-13  1663  	if (!etmdrvdata[cpu])
58eb457be0283d drivers/hwtracing/coresight/coresight-etm4x.c      Sebastian Andrzej Siewior 2016-07-13  1664  		return 0;
2e1cdfe184b520 drivers/hwtracing/coresight/coresight-etm4x.c      Pratik Patel              2015-05-13  1665  
2e1cdfe184b520 drivers/hwtracing/coresight/coresight-etm4x.c      Pratik Patel              2015-05-13 @1666  	spin_lock(&etmdrvdata[cpu]->spinlock);
6d7651015c16e1 drivers/hwtracing/coresight/coresight-etm4x.c      Andrew Murray             2019-08-29  1667  	if (!etmdrvdata[cpu]->os_unlock)
2e1cdfe184b520 drivers/hwtracing/coresight/coresight-etm4x.c      Pratik Patel              2015-05-13  1668  		etm4_os_unlock(etmdrvdata[cpu]);
2e1cdfe184b520 drivers/hwtracing/coresight/coresight-etm4x.c      Pratik Patel              2015-05-13  1669  
c95c2733e5feb1 drivers/hwtracing/coresight/coresight-etm4x-core.c James Clark               2024-01-29  1670  	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
2e1cdfe184b520 drivers/hwtracing/coresight/coresight-etm4x.c      Pratik Patel              2015-05-13  1671  		etm4_enable_hw(etmdrvdata[cpu]);
2e1cdfe184b520 drivers/hwtracing/coresight/coresight-etm4x.c      Pratik Patel              2015-05-13 @1672  	spin_unlock(&etmdrvdata[cpu]->spinlock);
58eb457be0283d drivers/hwtracing/coresight/coresight-etm4x.c      Sebastian Andrzej Siewior 2016-07-13  1673  	return 0;
58eb457be0283d drivers/hwtracing/coresight/coresight-etm4x.c      Sebastian Andrzej Siewior 2016-07-13  1674  }
2e1cdfe184b520 drivers/hwtracing/coresight/coresight-etm4x.c      Pratik Patel              2015-05-13  1675  

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


From ck.hu at mediatek.com  Tue Dec  3 23:08:51 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Wed, 4 Dec 2024 07:08:51 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
Message-ID: <d9fa43f9c9b49e26160cad506bfd06c37def064c.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
> +                                         struct drm_bridge_state *old_state)
> +{
> +       struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +       struct drm_atomic_state *state = old_state->base.state;
> +       union phy_configure_opts opts = {
> +               .dp = { .link_rate = hdmi->mode.clock * KILO }
> +       };
> +
> +       /* Retrieve the connector through the atomic state */
> +       hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);

I would like v1 and v2 has the same behavior. In v1, this is done in bridge enable function.
If it should be here in v2, add comment to describe the reason.

> +       mtk_hdmi_output_set_display_mode(hdmi, &hdmi->mode);

Ditto.

> +
> +       /* Reconfigure phy clock link with appropriate rate */
> +       phy_configure(hdmi->phy, &opts);
> +
> +       /* Power on the PHY here to make sure that DPI_HDMI is clocked */
> +       phy_power_on(hdmi->phy);

Ditto.

> +
> +       /* Enable VSync interrupt */
> +       regmap_set_bits(hdmi->regs, TOP_INT_ENABLE00, HDMI_VSYNC_INT);

I do not see software do anything in vsync.
I think this is not necessary, so drop it.

Regards,
CK

> +
> +       hdmi->powered = true;
> +}
> +

From krzysztof.kozlowski at linaro.org  Tue Dec  3 23:21:36 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 08:21:36 +0100
Subject: [PATCH] ARM: dts: aspeed: Enable video engine for IBM System1
In-Reply-To: <20241203-dts-system1-video-v1-1-008e5e660106@gmail.com>
References: <20241203-dts-system1-video-v1-1-008e5e660106@gmail.com>
Message-ID: <068c4e43-d64c-4f08-abff-675334e8f5e9@linaro.org>

On 03/12/2024 14:22, Manojkiran Eda via B4 Relay wrote:
> From: Manojkiran Eda <manojkiran.eda at gmail.com>
> 
> Signed-off-by: Manojkiran Eda <manojkiran.eda at gmail.com>
You CC-ed an address, which suggests you do not work on mainline kernel
or you do not use get_maintainers.pl/b4/patman. Regardless of the
reason, process needs improvement: please CC correct address.

Best regards,
Krzysztof


From ansuelsmth at gmail.com  Tue Dec  3 23:24:07 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Wed,  4 Dec 2024 08:24:07 +0100
Subject: [net-next PATCH v8 0/4] net: dsa: Add Airoha AN8855 support
Message-ID: <20241204072427.17778-1-ansuelsmth@gmail.com>

This small series add the initial support for the Airoha AN8855 Switch.

It's a 5 port Gigabit Switch with SGMII/HSGMII upstream port.

This is starting to get in the wild and there are already some router
having this switch chip.

It's conceptually similar to mediatek switch but register and bits
are different. And there is that massive Hell that is the PCS
configuration.
Saddly for that part we have absolutely NO documentation currently.

There is this special thing where PHY needs to be calibrated with values
from the switch efuse. (the thing have a whole cpu timer and MCU)

>From v8 Driver is now evaluated with Kernel selftest scripts for DSA:

Output local_termination.sh
TEST: lan2: Unicast IPv4 to primary MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to macvlan MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address, promisc            [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address, allmulti           [ OK ]
TEST: lan2: Multicast IPv4 to joined group                          [ OK ]
TEST: lan2: Multicast IPv4 to unknown group                         [XFAIL]
        reception succeeded, but should have failed
TEST: lan2: Multicast IPv4 to unknown group, promisc                [ OK ]
TEST: lan2: Multicast IPv4 to unknown group, allmulti               [ OK ]
TEST: lan2: Multicast IPv6 to joined group                          [ OK ]
TEST: lan2: Multicast IPv6 to unknown group                         [XFAIL]
        reception succeeded, but should have failed
TEST: lan2: Multicast IPv6 to unknown group, promisc                [ OK ]
TEST: lan2: Multicast IPv6 to unknown group, allmulti               [ OK ]
TEST: lan2: 1588v2 over L2 transport, Sync                          [ OK ]
TEST: lan2: 1588v2 over L2 transport, Follow-Up                     [ OK ]
TEST: lan2: 1588v2 over L2 transport, Peer Delay Request            [ OK ]
TEST: lan2: 1588v2 over IPv4, Sync                                  [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv4, Follow-Up                             [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv4, Peer Delay Request                    [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Sync                                  [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Follow-Up                             [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Peer Delay Request                    [FAIL]
        reception failed
TEST: vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to joined group       [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to joined group       [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to joined group       [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to joined group       [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN upper: Unicast IPv4 to primary MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to macvlan MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address, promisc      [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address, allmulti     [ OK ]
TEST: VLAN upper: Multicast IPv4 to joined group                    [ OK ]
TEST: VLAN upper: Multicast IPv4 to unknown group                   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN upper: Multicast IPv4 to unknown group, promisc          [ OK ]
TEST: VLAN upper: Multicast IPv4 to unknown group, allmulti         [ OK ]
TEST: VLAN upper: Multicast IPv6 to joined group                    [ OK ]
TEST: VLAN upper: Multicast IPv6 to unknown group                   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN upper: Multicast IPv6 to unknown group, promisc          [ OK ]
TEST: VLAN upper: Multicast IPv6 to unknown group, allmulti         [ OK ]
TEST: VLAN upper: 1588v2 over L2 transport, Sync                    [ OK ]
TEST: VLAN upper: 1588v2 over L2 transport, Follow-Up               [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over L2 transport, Peer Delay Request      [ OK ]
TEST: VLAN upper: 1588v2 over IPv4, Sync                            [FAIL]
        reception failed
;TEST: VLAN upper: 1588v2 over IPv4, Follow-Up                       [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv4, Peer Delay Request              [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Sync                            [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Follow-Up                       [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Peer Delay Request              [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Sync   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Follow-Up   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Peer Delay Request   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address   [FAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, allmulti   [FAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Sync   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Follow-Up   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Peer Delay Request   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]

Output bridge_vlan_unaware.sh
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: FDB learning                                                  [ OK ]
TEST: Unknown unicast flood                                         [ OK ]
TEST: Unregistered multicast flood                                  [ OK ]

Output bridge_vlan_aware.sh
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: FDB learning                                                  [ OK ]
TEST: Unknown unicast flood                                         [ OK ]
TEST: Unregistered multicast flood                                  [ OK ]
INFO: Add and delete a VLAN on bridge port lan2
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: Externally learned FDB entry - ageing & roaming               [ OK ]
TEST: FDB entry in PVID for VLAN-tagged with other TPID             [FAIL]
        FDB entry was not learned when it should
TEST: Reception of VLAN with other TPID as untagged                 [FAIL]
        Packet was not forwarded when it should
TEST: Reception of VLAN with other TPID as untagged (no PVID)       [FAIL]
        Packet was forwarded when should not

Changes v8:
- Add port Fast Age support
- Add support for Port Isolation
- Use correct register for Learning Disable
- Add support for Ageing Time OP
- Set default PVID to 0 by default
- Add mdb OPs
- Add port change MTU
- Fix support for Upper VLAN
Changes v7:
- Fix devm_dsa_register_switch wrong export symbol
Changes v6:
- Drop standard MIB and handle with ethtool OPs (as requested by Jakub)
- Cosmetic: use bool instead of 0 or 1
Changes v5:
- Add devm_dsa_register_switch() patch
- Add Reviewed-by tag for DT patch
Changes v4:
- Set regmap readable_table static (mute compilation warning)
- Add support for port_bridge flags (LEARNING, FLOOD)
- Reset fdb struct in fdb_dump
- Drop support_asym_pause in port_enable
- Add define for get_phy_flags
- Fix bug for port not inititially part of a bridge
  (in an8855_setup the port matrix was always cleared but
   the CPU port was never initially added)
- Disable learning and flood for user port by default
- Set CPU port to flood and learning by default
- Correctly AND force duplex and flow control in an8855_phylink_mac_link_up
- Drop RGMII from pcs_config
- Check ret in "Disable AN if not in autoneg"
- Use devm_mutex_init
- Fix typo for AN8855_PORT_CHECK_MODE
- Better define AN8855_STP_LISTENING = AN8855_STP_BLOCKING
- Fix typo in AN8855_PHY_EN_DOWN_SHIFT
- Use paged helper for PHY
- Skip calibration in config_init if priv not defined
Changes v3:
- Out of RFC
- Switch PHY code to select_page API
- Better describe masks and bits in PHY driver for ADC register
- Drop raw values and use define for mii read/write
- Switch to absolute PHY address
- Replace raw values with mask and bits for pcs_config
- Fix typo for ext-surge property name
- Drop support for relocating Switch base PHY address on the bus
Changes v2:
- Drop mutex guard patch
- Drop guard usage in DSA driver
- Use __mdiobus_write/read
- Check return condition and return errors for mii read/write
- Fix wrong logic for EEE
- Fix link_down (don't force link down with autoneg)
- Fix forcing speed on sgmii autoneg
- Better document link speed for sgmii reg
- Use standard define for sgmii reg
- Imlement nvmem support to expose switch EFUSE
- Rework PHY calibration with the use of NVMEM producer/consumer
- Update DT with new NVMEM property
- Move aneg validation for 2500-basex in pcs_config
- Move r50Ohm table and function to PHY driver

Christian Marangi (4):
  net: dsa: add devm_dsa_register_switch()
  dt-bindings: net: dsa: Add Airoha AN8855 Gigabit Switch documentation
  net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
  net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY

 .../bindings/net/dsa/airoha,an8855.yaml       |  242 ++
 MAINTAINERS                                   |   11 +
 drivers/net/dsa/Kconfig                       |    9 +
 drivers/net/dsa/Makefile                      |    1 +
 drivers/net/dsa/an8855.c                      | 2673 +++++++++++++++++
 drivers/net/dsa/an8855.h                      |  810 +++++
 drivers/net/phy/Kconfig                       |    5 +
 drivers/net/phy/Makefile                      |    1 +
 drivers/net/phy/air_an8855.c                  |  267 ++
 include/net/dsa.h                             |    1 +
 net/dsa/dsa.c                                 |   19 +
 11 files changed, 4039 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml
 create mode 100644 drivers/net/dsa/an8855.c
 create mode 100644 drivers/net/dsa/an8855.h
 create mode 100644 drivers/net/phy/air_an8855.c

-- 
2.45.2



From ansuelsmth at gmail.com  Tue Dec  3 23:24:08 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Wed,  4 Dec 2024 08:24:08 +0100
Subject: [net-next PATCH v8 1/4] net: dsa: add devm_dsa_register_switch()
In-Reply-To: <20241204072427.17778-1-ansuelsmth@gmail.com>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
Message-ID: <20241204072427.17778-2-ansuelsmth@gmail.com>

Some DSA driver can be simplified if devres takes care of unregistering
the DSA switch. This permits to effectively drop the remove OP from
driver that just execute the dsa_unregister_switch() and nothing else.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 include/net/dsa.h |  1 +
 net/dsa/dsa.c     | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 72ae65e7246a..c703d5dc3fb0 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -1355,6 +1355,7 @@ static inline void dsa_tag_generic_flow_dissect(const struct sk_buff *skb,
 
 void dsa_unregister_switch(struct dsa_switch *ds);
 int dsa_register_switch(struct dsa_switch *ds);
+int devm_dsa_register_switch(struct device *dev, struct dsa_switch *ds);
 void dsa_switch_shutdown(struct dsa_switch *ds);
 struct dsa_switch *dsa_switch_find(int tree_index, int sw_index);
 void dsa_flush_workqueue(void);
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 5a7c0e565a89..aca6aee68248 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -1544,6 +1544,25 @@ int dsa_register_switch(struct dsa_switch *ds)
 }
 EXPORT_SYMBOL_GPL(dsa_register_switch);
 
+static void devm_dsa_unregister_switch(void *data)
+{
+	struct dsa_switch *ds = data;
+
+	dsa_unregister_switch(ds);
+}
+
+int devm_dsa_register_switch(struct device *dev, struct dsa_switch *ds)
+{
+	int err;
+
+	err = dsa_register_switch(ds);
+	if (err)
+		return err;
+
+	return devm_add_action_or_reset(dev, devm_dsa_unregister_switch, ds);
+}
+EXPORT_SYMBOL_GPL(devm_dsa_register_switch);
+
 static void dsa_switch_remove(struct dsa_switch *ds)
 {
 	struct dsa_switch_tree *dst = ds->dst;
-- 
2.45.2



From ansuelsmth at gmail.com  Tue Dec  3 23:24:09 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Wed,  4 Dec 2024 08:24:09 +0100
Subject: [net-next PATCH v8 2/4] dt-bindings: net: dsa: Add Airoha AN8855 Gigabit Switch documentation
In-Reply-To: <20241204072427.17778-1-ansuelsmth@gmail.com>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
Message-ID: <20241204072427.17778-3-ansuelsmth@gmail.com>

Add Airoha AN8855 5 port Gigabit Switch documentation.

The switch node requires an additional mdio node to describe each internal
PHY absolute address on the bus.

Calibration values might be stored in switch EFUSE and internal PHY
might need to be calibrated, in such case, airoha,ext-surge needs to be
enabled and relative NVMEM cells needs to be defined in nvmem-layout
node.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
 .../bindings/net/dsa/airoha,an8855.yaml       | 242 ++++++++++++++++++
 1 file changed, 242 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml

diff --git a/Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml b/Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml
new file mode 100644
index 000000000000..8ea2fadbab85
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml
@@ -0,0 +1,242 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/dsa/airoha,an8855.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 Gigabit switch
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description: >
+  Airoha AN8855 is a 5-port Gigabit Switch.
+
+  The switch node requires an additional mdio node to describe each internal
+  PHY relative offset as the PHY address for the switch match the one for
+  the PHY ports. On top of internal PHY address, the switch base PHY address
+  is added.
+
+  Also the switch base PHY address can be configured and changed after the
+  first initialization. On reset, the switch PHY address is ALWAYS 1.
+
+properties:
+  compatible:
+    const: airoha,an8855
+
+  reg:
+    maxItems: 1
+
+  reset-gpios:
+    description:
+      GPIO to be used to reset the whole device
+    maxItems: 1
+
+  airoha,ext-surge:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Calibrate the internal PHY with the calibration values stored in EFUSE
+      for the r50Ohm values.
+
+  '#nvmem-cell-cells':
+    const: 0
+
+  nvmem-layout:
+    $ref: /schemas/nvmem/layouts/nvmem-layout.yaml
+    description:
+      NVMEM Layout for exposed EFUSE. (for example to propagate calibration
+      value for r50Ohm for internal PHYs)
+
+  mdio:
+    $ref: /schemas/net/mdio.yaml#
+    unevaluatedProperties: false
+    description:
+      Define the absolute address of the internal PHY for each port.
+
+$ref: dsa.yaml#
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    mdio {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        switch at 1 {
+            compatible = "airoha,an8855";
+            reg = <1>;
+            reset-gpios = <&pio 39 0>;
+
+            airoha,ext-surge;
+
+            #nvmem-cell-cells = <0>;
+
+            nvmem-layout {
+                compatible = "fixed-layout";
+                #address-cells = <1>;
+                #size-cells = <1>;
+
+                shift_sel_port0_tx_a: shift-sel-port0-tx-a at c {
+                    reg = <0xc 0x4>;
+                };
+
+                shift_sel_port0_tx_b: shift-sel-port0-tx-b at 10 {
+                    reg = <0x10 0x4>;
+                };
+
+                shift_sel_port0_tx_c: shift-sel-port0-tx-c at 14 {
+                    reg = <0x14 0x4>;
+                };
+
+                shift_sel_port0_tx_d: shift-sel-port0-tx-d at 18 {
+                    reg = <0x18 0x4>;
+                };
+
+                shift_sel_port1_tx_a: shift-sel-port1-tx-a at 1c {
+                    reg = <0x1c 0x4>;
+                };
+
+                shift_sel_port1_tx_b: shift-sel-port1-tx-b at 20 {
+                    reg = <0x20 0x4>;
+                };
+
+                shift_sel_port1_tx_c: shift-sel-port1-tx-c at 24 {
+                    reg = <0x24 0x4>;
+                };
+
+                shift_sel_port1_tx_d: shift-sel-port1-tx-d at 28 {
+                    reg = <0x28 0x4>;
+                };
+
+                shift_sel_port2_tx_a: shift-sel-port2-tx-a at 2c {
+                    reg = <0x2c 0x4>;
+                };
+
+                shift_sel_port2_tx_b: shift-sel-port2-tx-b at 30 {
+                    reg = <0x30 0x4>;
+                };
+
+                shift_sel_port2_tx_c: shift-sel-port2-tx-c at 34 {
+                    reg = <0x34 0x4>;
+                };
+
+                shift_sel_port2_tx_d: shift-sel-port2-tx-d at 38 {
+                    reg = <0x38 0x4>;
+                };
+
+                shift_sel_port3_tx_a: shift-sel-port3-tx-a at 4c {
+                    reg = <0x4c 0x4>;
+                };
+
+                shift_sel_port3_tx_b: shift-sel-port3-tx-b at 50 {
+                    reg = <0x50 0x4>;
+                };
+
+                shift_sel_port3_tx_c: shift-sel-port3-tx-c at 54 {
+                    reg = <0x54 0x4>;
+                };
+
+                shift_sel_port3_tx_d: shift-sel-port3-tx-d at 58 {
+                    reg = <0x58 0x4>;
+                };
+            };
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port at 0 {
+                    reg = <0>;
+                    label = "lan1";
+                    phy-mode = "internal";
+                    phy-handle = <&internal_phy1>;
+                };
+
+                port at 1 {
+                    reg = <1>;
+                    label = "lan2";
+                    phy-mode = "internal";
+                    phy-handle = <&internal_phy2>;
+                };
+
+                port at 2 {
+                    reg = <2>;
+                    label = "lan3";
+                    phy-mode = "internal";
+                    phy-handle = <&internal_phy3>;
+                };
+
+                port at 3 {
+                    reg = <3>;
+                    label = "lan4";
+                    phy-mode = "internal";
+                    phy-handle = <&internal_phy4>;
+                };
+
+                port at 5 {
+                    reg = <5>;
+                    label = "cpu";
+                    ethernet = <&gmac0>;
+                    phy-mode = "2500base-x";
+
+                    fixed-link {
+                        speed = <2500>;
+                        full-duplex;
+                        pause;
+                    };
+                };
+            };
+
+            mdio {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                internal_phy1: phy at 1 {
+                    reg = <1>;
+
+                    nvmem-cells = <&shift_sel_port0_tx_a>,
+                                  <&shift_sel_port0_tx_b>,
+                                  <&shift_sel_port0_tx_c>,
+                                  <&shift_sel_port0_tx_d>;
+                    nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+
+                internal_phy2: phy at 2 {
+                    reg = <2>;
+
+                    nvmem-cells = <&shift_sel_port1_tx_a>,
+                                  <&shift_sel_port1_tx_b>,
+                                  <&shift_sel_port1_tx_c>,
+                                  <&shift_sel_port1_tx_d>;
+                    nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+
+                internal_phy3: phy at 3 {
+                    reg = <3>;
+
+                    nvmem-cells = <&shift_sel_port2_tx_a>,
+                                  <&shift_sel_port2_tx_b>,
+                                  <&shift_sel_port2_tx_c>,
+                                  <&shift_sel_port2_tx_d>;
+                    nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+
+                internal_phy4: phy at 4 {
+                    reg = <4>;
+
+                    nvmem-cells = <&shift_sel_port3_tx_a>,
+                                  <&shift_sel_port3_tx_b>,
+                                  <&shift_sel_port3_tx_c>,
+                                  <&shift_sel_port3_tx_d>;
+                    nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+            };
+        };
+    };
-- 
2.45.2



From ansuelsmth at gmail.com  Tue Dec  3 23:24:11 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Wed,  4 Dec 2024 08:24:11 +0100
Subject: [net-next PATCH v8 4/4] net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY
In-Reply-To: <20241204072427.17778-1-ansuelsmth@gmail.com>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
Message-ID: <20241204072427.17778-5-ansuelsmth@gmail.com>

Add support for Airoha AN8855 Internal Switch Gigabit PHY.

This is a simple PHY driver to configure and calibrate the PHY for the
AN8855 Switch with the use of NVMEM cells.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                  |   1 +
 drivers/net/phy/Kconfig      |   5 +
 drivers/net/phy/Makefile     |   1 +
 drivers/net/phy/air_an8855.c | 267 +++++++++++++++++++++++++++++++++++
 4 files changed, 274 insertions(+)
 create mode 100644 drivers/net/phy/air_an8855.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e3077d9feee2..cf34add2a0bb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -726,6 +726,7 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml
 F:	drivers/net/dsa/an8855.c
 F:	drivers/net/dsa/an8855.h
+F:	drivers/net/phy/air_an8855.c
 
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index ee3ea0b56d48..1d474038ea7f 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -79,6 +79,11 @@ config SFP
 
 comment "MII PHY device drivers"
 
+config AIR_AN8855_PHY
+	tristate "Airoha AN8855 Internal Gigabit PHY"
+	help
+	  Currently supports the internal Airoha AN8855 Switch PHY.
+
 config AIR_EN8811H_PHY
 	tristate "Airoha EN8811H 2.5 Gigabit PHY"
 	help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 90f886844381..baba7894785b 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -35,6 +35,7 @@ obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
 
 obj-$(CONFIG_ADIN_PHY)		+= adin.o
 obj-$(CONFIG_ADIN1100_PHY)	+= adin1100.o
+obj-$(CONFIG_AIR_AN8855_PHY)   += air_an8855.o
 obj-$(CONFIG_AIR_EN8811H_PHY)   += air_en8811h.o
 obj-$(CONFIG_AMD_PHY)		+= amd.o
 obj-$(CONFIG_AMCC_QT2025_PHY)	+= qt2025.o
diff --git a/drivers/net/phy/air_an8855.c b/drivers/net/phy/air_an8855.c
new file mode 100644
index 000000000000..7ede6674994f
--- /dev/null
+++ b/drivers/net/phy/air_an8855.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth at gmail.com>
+ */
+
+#include <linux/phy.h>
+#include <linux/module.h>
+#include <linux/bitfield.h>
+#include <linux/nvmem-consumer.h>
+
+#define AN8855_PHY_SELECT_PAGE			0x1f
+#define   AN8855_PHY_PAGE			GENMASK(2, 0)
+#define   AN8855_PHY_PAGE_STANDARD		FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
+#define   AN8855_PHY_PAGE_EXTENDED_1		FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
+
+/* MII Registers Page 1 */
+#define AN8855_PHY_EXT_REG_14			0x14
+#define   AN8855_PHY_EN_DOWN_SHIFT		BIT(4)
+
+/* R50 Calibration regs in MDIO_MMD_VEND1 */
+#define AN8855_PHY_R500HM_RSEL_TX_AB		0x174
+#define AN8855_PHY_R50OHM_RSEL_TX_A_EN		BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_A		GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_B_EN		BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_B		GENMASK(6, 0)
+#define AN8855_PHY_R500HM_RSEL_TX_CD		0x175
+#define AN8855_PHY_R50OHM_RSEL_TX_C_EN		BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_C		GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_D_EN		BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_D		GENMASK(6, 0)
+
+#define AN8855_SWITCH_EFUSE_R50O		GENMASK(30, 24)
+
+/* PHY TX PAIR DELAY SELECT Register */
+#define AN8855_PHY_TX_PAIR_DLY_SEL_GBE		0x013
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE GENMASK(14, 12)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_B_GBE GENMASK(10, 8)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE GENMASK(6, 4)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_D_GBE GENMASK(2, 0)
+/* PHY ADC Register */
+#define AN8855_PHY_RXADC_CTRL			0x0d8
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A	BIT(12)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_B	BIT(8)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C	BIT(4)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_D	BIT(0)
+#define AN8855_PHY_RXADC_REV_0			0x0d9
+#define   AN8855_PHY_RG_AD_RESERVE0_A		GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_B		GENMASK(7, 0)
+#define AN8855_PHY_RXADC_REV_1			0x0da
+#define   AN8855_PHY_RG_AD_RESERVE0_C		GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_D		GENMASK(7, 0)
+
+#define AN8855_PHY_ID				0xc0ff0410
+
+#define AN8855_PHY_FLAGS_EN_CALIBRATION		BIT(0)
+
+struct air_an8855_priv {
+	u8 calibration_data[4];
+};
+
+static const u8 dsa_r50ohm_table[] = {
+	127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+	127, 127, 127, 127, 127, 127, 127, 126, 122, 117,
+	112, 109, 104, 101,  97,  94,  90,  88,  84,  80,
+	78,  74,  72,  68,  66,  64,  61,  58,  56,  53,
+	51,  48,  47,  44,  42,  40,  38,  36,  34,  32,
+	31,  28,  27,  24,  24,  22,  20,  18,  16,  16,
+	14,  12,  11,   9
+};
+
+static int en8855_get_r50ohm_val(struct device *dev, const char *calib_name,
+				 u8 *dest)
+{
+	u32 shift_sel, val;
+	int ret;
+	int i;
+
+	ret = nvmem_cell_read_u32(dev, calib_name, &val);
+	if (ret)
+		return ret;
+
+	shift_sel = FIELD_GET(AN8855_SWITCH_EFUSE_R50O, val);
+	for (i = 0; i < ARRAY_SIZE(dsa_r50ohm_table); i++)
+		if (dsa_r50ohm_table[i] == shift_sel)
+			break;
+
+	if (i < 8 || i >= ARRAY_SIZE(dsa_r50ohm_table))
+		*dest = dsa_r50ohm_table[25];
+	else
+		*dest = dsa_r50ohm_table[i - 8];
+
+	return 0;
+}
+
+static int an8855_probe(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	struct device_node *node = dev->of_node;
+	struct air_an8855_priv *priv;
+	int ret;
+
+	/* If we don't have a node, skip get calib */
+	if (!node)
+		return 0;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	ret = en8855_get_r50ohm_val(dev, "tx_a", &priv->calibration_data[0]);
+	if (ret)
+		return ret;
+
+	ret = en8855_get_r50ohm_val(dev, "tx_b", &priv->calibration_data[1]);
+	if (ret)
+		return ret;
+
+	ret = en8855_get_r50ohm_val(dev, "tx_c", &priv->calibration_data[2]);
+	if (ret)
+		return ret;
+
+	ret = en8855_get_r50ohm_val(dev, "tx_d", &priv->calibration_data[3]);
+	if (ret)
+		return ret;
+
+	phydev->priv = priv;
+
+	return 0;
+}
+
+static int an8855_get_downshift(struct phy_device *phydev, u8 *data)
+{
+	int val;
+
+	val = phy_read_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1, AN8855_PHY_EXT_REG_14);
+	if (val < 0)
+		return val;
+
+	*data = val & AN8855_PHY_EN_DOWN_SHIFT ? DOWNSHIFT_DEV_DEFAULT_COUNT :
+						 DOWNSHIFT_DEV_DISABLE;
+
+	return 0;
+}
+
+static int an8855_set_downshift(struct phy_device *phydev, u8 cnt)
+{
+	u16 ds = cnt != DOWNSHIFT_DEV_DISABLE ? AN8855_PHY_EN_DOWN_SHIFT : 0;
+
+	return phy_modify_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1,
+				AN8855_PHY_EXT_REG_14, AN8855_PHY_EN_DOWN_SHIFT,
+				ds);
+}
+
+static int an8855_config_init(struct phy_device *phydev)
+{
+	struct air_an8855_priv *priv = phydev->priv;
+	int ret;
+
+	/* Enable HW auto downshift */
+	ret = an8855_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT);
+	if (ret)
+		return ret;
+
+	/* Apply calibration values, if needed.
+	 * AN8855_PHY_FLAGS_EN_CALIBRATION signal this.
+	 */
+	if (priv && phydev->dev_flags & AN8855_PHY_FLAGS_EN_CALIBRATION) {
+		u8 *calibration_data = priv->calibration_data;
+
+		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_AB,
+				     AN8855_PHY_R50OHM_RSEL_TX_A | AN8855_PHY_R50OHM_RSEL_TX_B,
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_A, calibration_data[0]) |
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_B, calibration_data[1]));
+		if (ret)
+			return ret;
+		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_CD,
+				     AN8855_PHY_R50OHM_RSEL_TX_C | AN8855_PHY_R50OHM_RSEL_TX_D,
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_C, calibration_data[2]) |
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_D, calibration_data[3]));
+		if (ret)
+			return ret;
+	}
+
+	/* Apply values to reduce signal noise */
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_TX_PAIR_DLY_SEL_GBE,
+			    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE, 0x4) |
+			    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE, 0x4));
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_CTRL,
+			    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A |
+			    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C);
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_0,
+			    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_A, 0x1));
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_1,
+			    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_C, 0x1));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int an8855_get_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, void *data)
+{
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT:
+		return an8855_get_downshift(phydev, data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int an8855_set_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, const void *data)
+{
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT:
+		return an8855_set_downshift(phydev, *(const u8 *)data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int an8855_read_page(struct phy_device *phydev)
+{
+	return __phy_read(phydev, AN8855_PHY_SELECT_PAGE);
+}
+
+static int an8855_write_page(struct phy_device *phydev, int page)
+{
+	return __phy_write(phydev, AN8855_PHY_SELECT_PAGE, page);
+}
+
+static struct phy_driver an8855_driver[] = {
+{
+	PHY_ID_MATCH_EXACT(AN8855_PHY_ID),
+	.name			= "Airoha AN8855 internal PHY",
+	/* PHY_GBIT_FEATURES */
+	.flags			= PHY_IS_INTERNAL,
+	.probe			= an8855_probe,
+	.config_init		= an8855_config_init,
+	.soft_reset		= genphy_soft_reset,
+	.get_tunable		= an8855_get_tunable,
+	.set_tunable		= an8855_set_tunable,
+	.suspend		= genphy_suspend,
+	.resume			= genphy_resume,
+	.read_page		= an8855_read_page,
+	.write_page		= an8855_write_page,
+}, };
+
+module_phy_driver(an8855_driver);
+
+static struct mdio_device_id __maybe_unused an8855_tbl[] = {
+	{ PHY_ID_MATCH_EXACT(AN8855_PHY_ID) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(mdio, an8855_tbl);
+
+MODULE_DESCRIPTION("Airoha AN8855 PHY driver");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From julian at outer-limits.org  Tue Dec  3 23:27:48 2024
From: julian at outer-limits.org (Julian Vetter)
Date: Wed, 4 Dec 2024 08:27:48 +0100
Subject: [PATCH] arm: Remove IO memcpy for Big-Endian
In-Reply-To: <609b026d-d54c-4a11-b7df-6ef0ac315f25@app.fastmail.com>
References: <20241203083838.3260036-1-jvetter@outer-limits.org>
 <609b026d-d54c-4a11-b7df-6ef0ac315f25@app.fastmail.com>
Message-ID: <8d674373-0f30-4d0b-aac7-53eb38c81513@outer-limits.org>



On 03.12.24 11:08, Arnd Bergmann wrote:
> On Tue, Dec 3, 2024, at 09:38, Julian Vetter wrote:
>> From: Julian Vetter <julian at outer-limits.org>
>>
>> Recently a new IO memcpy was added in libs/iomem_copy.c. So, remove the
>> byte-wise IO memcpy operations used in ARM big endian builds and fall
>> back to the new generic implementation. It will be slightly faster,
>> because it uses machine word accesses if the memory is aligned and falls
>> back to byte-wise accesses if its not.
>>
>> Signed-off-by: Julian Vetter <julian at outer-limits.org>
>> ---
>>   arch/arm/include/asm/io.h | 11 ----------
>>   arch/arm/kernel/io.c      | 46 ---------------------------------------
>>   2 files changed, 57 deletions(-)
> 

Hello Arnd,
first, sorry, that I messed up my sender email while sending the patch.

> I'm not sure if this is safe on all platforms. Big-endian arm
> is extremely rare in practice, and in comes in multiple variants
> that behave slightly differently:
> 
> - On modern ARMv7 the byte-invariant big-endian "BE8" mode
>    generally well-behaved and works as one would expect it to.
> 
> - There is one ARMv5 "BE32" based platform, the ixp4xx, which
>    works differently, and this in turn allows multiple configurations
>    for its buses where a byte-swap is performed in the PCI
>    controller.
> 
> When the little-endian I/O string operations got optimized to
> calling the word-based helpers in commit 7ddfe625cbc1 ("ARM:
> optimize memset_io()/memcpy_fromio()/memcpy_toio()"), Russell
> intentionally left the big-endian versions alone, which I think
> was done for the case of PCI on ixp4xx, but could have been
> out of general caution.
> 

Wow, thank you for the explanation!

> Before we apply your patch, I think the minimum would be to
> have Linus Walleij try it out on an an ixp4xx with a driver
> that uses these functions. Maybe Russell remembers the exact
> constraints that led to using byte access for big-endian
> mmio string operations, and whether the new lib/iomem_copy.c
> version causes problems.
> 
> I also looked at the little-endian arm32 version, and
> it seems that here the generic code would work fine, but
> the custom variant is likely much faster when both the
> source and destination buffers are aligned, as it can
> do larger MMIO transactions using ldm/stm instructions,
> though the generic version would be a bit better if the
> in-memory buffer is unaligned.
> We could get the best of both by implementing optimized
> arm32 versions __iowrite32_copy()/__ioread32_copy and
> using those in the generic memcpy_{from,to}io.
> 

ok, then I will wait for now, to see if it works with the current 
version. If not, I will have a look at using the 
__iowrite32_copy/__ioread32_copy functions.

>         Arnd



From krzk at kernel.org  Tue Dec  3 23:35:37 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 08:35:37 +0100
Subject: [PATCH v5 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241202110045.22084-4-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-4-linux@fw-web.de>
Message-ID: <iwmnxlqpaijvr4kmzwk3elacqj5ukqlchfs67ca6c6gxrycpbb@pc6a6scqkdi5>

On Mon, Dec 02, 2024 at 12:00:37PM +0100, Frank Wunderlich wrote:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> This adds bindings for MT7988 pinctrl driver.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
> changes in v5 (so not adding RB from Rob given in v4):
> - do not use MTK_DRIVE_8mA in example
> - add _0 functions for pwm
>

<form letter>
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.
</form letter>

Best regards,
Krzysztof



From krzk at kernel.org  Tue Dec  3 23:39:34 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 08:39:34 +0100
Subject: [PATCH v5 1/2] dt-bindings: phy: Add Rockchip MIPI C-/D-PHY
 schema
In-Reply-To: <20241203164934.1500616-2-heiko@sntech.de>
References: <20241203164934.1500616-1-heiko@sntech.de>
 <20241203164934.1500616-2-heiko@sntech.de>
Message-ID: <mdlcm57lway2wqwh7tp6bj6mi3nlwuaeadbsmgx3h6kcfdisq5@76ikce4yqfs4>

On Tue, Dec 03, 2024 at 05:49:31PM +0100, Heiko Stuebner wrote:
> +properties:
> +  compatible:
> +    enum:
> +      - rockchip,rk3576-mipi-dcphy
> +      - rockchip,rk3588-mipi-dcphy
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#phy-cells":
> +    const: 1
> +    description: |
> +      Argument is mode to operate in. Supported modes are:
> +        - PHY_TYPE_DPHY
> +        - PHY_TYPE_CPHY
> +      See include/dt-bindings/phy/phy.h for constants.


That's the only difference from version I gave review. It is approved
style of passing phy type/mode, so adding this is not valid reason to
drop my review tag and request re-review.

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

Best regards,
Krzysztof



From frank-w at public-files.de  Tue Dec  3 23:41:26 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Wed, 04 Dec 2024 08:41:26 +0100
Subject: [PATCH v5 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <iwmnxlqpaijvr4kmzwk3elacqj5ukqlchfs67ca6c6gxrycpbb@pc6a6scqkdi5>
References: <20241202110045.22084-1-linux@fw-web.de> <20241202110045.22084-4-linux@fw-web.de> <iwmnxlqpaijvr4kmzwk3elacqj5ukqlchfs67ca6c6gxrycpbb@pc6a6scqkdi5>
Message-ID: <1DBA844B-4DB2-4AA2-BF04-B3CC39B3C3F8@public-files.de>

Am 4. Dezember 2024 08:35:37 MEZ schrieb Krzysztof Kozlowski <krzk at kernel.org>:
>On Mon, Dec 02, 2024 at 12:00:37PM +0100, Frank Wunderlich wrote:
>> From: Frank Wunderlich <frank-w at public-files.de>
>> 
>> This adds bindings for MT7988 pinctrl driver.
>> 
>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>> ---
>> changes in v5 (so not adding RB from Rob given in v4):
>> - do not use MTK_DRIVE_8mA in example
>> - add _0 functions for pwm
>>
>
><form letter>
>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.
></form letter>

Is this an automatic message? I guess yes...

I have not added it (robs reviewed-by) from v4 due to changes and explained why in changelog. If i'm wrong please let me know.

>Best regards,
>Krzysztof
>


regards Frank


From jani.nikula at linux.intel.com  Tue Dec  3 23:42:11 2024
From: jani.nikula at linux.intel.com (Jani Nikula)
Date: Wed, 04 Dec 2024 09:42:11 +0200
Subject: [PATCH v5 7/9] drm/bridge_connector: hook
 drm_atomic_helper_connector_hdmi_update_edid()
In-Reply-To: <txzri7x4pdeakx4juandk3hfhsbx3dhlulxfuehqlmrr7b3wpw@jaunqktsro6x>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-7-b5316e82f61a@linaro.org>
 <87a5dc4zd5.fsf@intel.com>
 <txzri7x4pdeakx4juandk3hfhsbx3dhlulxfuehqlmrr7b3wpw@jaunqktsro6x>
Message-ID: <87v7vz3ne4.fsf@intel.com>

On Wed, 04 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> On Tue, Dec 03, 2024 at 04:25:58PM +0200, Jani Nikula wrote:
>> On Sun, 01 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
>> > +	drm_edid = drm_bridge_edid_read(bridge, connector);
>> > +	if (!drm_edid_valid(drm_edid)) {
>> 
>> What's the case this check is for?
>> 
>> My preference would be that bridge->funcs->edid_read() uses
>> drm_edid_read*() family of functions that do the checks and return the
>> EDID.
>> 
>> There are some cases that just allocate a blob and return it. Would be
>> nice if they could be converted, but in the mean time could use
>> drm_edid_valid() right there. Additional validity checks are redundant.
>
> This was c&p from drm_bridge_connector_get_modes_edid(). If you think
> that the check is redundant, could you please send a patch dropping the
> check?

Mmmh. It's just scary to *remove* them, and that's the reason I didn't
want you to add one in the first place! :)

BR,
Jani.


-- 
Jani Nikula, Intel


From geert at linux-m68k.org  Tue Dec  3 23:44:15 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 4 Dec 2024 08:44:15 +0100
Subject: [PATCH] gpio: GPIO_MVEBU should not default to y when compile-testing
In-Reply-To: <44126f2f-92ce-412b-ad9d-e0e0ea28d36d@lunn.ch>
References: <6b9e55dbf544297d5acf743f6fa473791ab10644.1733242798.git.geert+renesas@glider.be>
 <f552b813-1817-4507-9699-fae87575a762@lunn.ch> <CAMRc=Mfh5Rv8OKWOcPVzJp-_e_bXgywT2=+N2cF1ONT3kiw7tQ@mail.gmail.com>
 <44126f2f-92ce-412b-ad9d-e0e0ea28d36d@lunn.ch>
Message-ID: <CAMuHMdUaPkpSzrkqPRzZZfj6Npmj-8Ax5dXEGbjKXAyCW_DLXA@mail.gmail.com>

Hi Andrew,

On Tue, Dec 3, 2024 at 9:59?PM Andrew Lunn <andrew at lunn.ch> wrote:
> On Tue, Dec 03, 2024 at 09:29:02PM +0100, Bartosz Golaszewski wrote:
> > On Tue, Dec 3, 2024 at 9:13?PM Andrew Lunn <andrew at lunn.ch> wrote:
> > >
> > > On Tue, Dec 03, 2024 at 05:23:16PM +0100, Geert Uytterhoeven wrote:
> > > > Merely enabling compile-testing should not enable additional
> > > > functionality.
> > >
> > > Sorry for being dumb, but i don't actually see what is wrong here.
> > >
> > > There are 4 GPIO drivers which have
> > >
> > >         def_bool y

None of these depend on || COMPILE_TEST.

> > > COMPILE_TEST is about building as much as possible, in order to find
> > > build bugs. So i don't get what you mean by additional
> > > functionality. No additional functionality within the MVEBU driver
> > > gets enabled by COMPILE_TEST.
> >
> > No, Geert is right. I have been yelled at by Linus Torvalds already
> > for too eagerly enabling too many options. COMPILE_TEST is really
> > about making it possible to build more things with make allmodconfig,
> > not necessarily defaulting to y for everything.
>
> So are you saying COMPILE_TEST should allow something to be enabled,
> but should not actually enable it?

It is meant for relaxing dependencies, i.e. to allow you to do
build-testing of drivers that cannot possibly work on the system you
are compiling a kernel for.

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 krzk at kernel.org  Tue Dec  3 23:49:05 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 08:49:05 +0100
Subject: [PATCH v4 2/2] dt-bindings: input: Add Nuvoton MA35D1 keypad
In-Reply-To: <20241204021014.5083-3-mjchen0829@gmail.com>
References: <20241204021014.5083-1-mjchen0829@gmail.com>
 <20241204021014.5083-3-mjchen0829@gmail.com>
Message-ID: <2a47hwrbl3r6h5umwikt7bd7rp3njj6wnlo5e67f5kl6zhaq7g@cnolynoswb37>

On Wed, Dec 04, 2024 at 02:10:14AM +0000, Ming-Jen Chen wrote:
> Add YAML bindings for MA35D1 SoC keypad.
> 
> Signed-off-by: Ming-Jen Chen <mjchen0829 at gmail.com>


Repeating same comment third or fourth time is a waste of my time.

NAK.

It seems my or other reviewer's previous comments were not fully
addressed. Maybe the feedback got lost between the quotes, maybe you
just forgot to apply it. Please go back to the previous discussion and
either implement all requested changes or keep discussing them.

Best regards,
Krzysztof



From n-francis at ti.com  Tue Dec  3 23:51:59 2024
From: n-francis at ti.com (Neha Malcom Francis)
Date: Wed, 4 Dec 2024 13:21:59 +0530
Subject: [PATCH v4 0/6] arm64: dts: ti: k3-j7*: Add missing ESM and
In-Reply-To: <20240425211233.2006233-1-n-francis@ti.com>
References: <20240425211233.2006233-1-n-francis@ti.com>
Message-ID: <e280d338-d05d-4910-8017-bc121eb2b94b@ti.com>

Hi Vignesh,

Pinging on the below old patch series, applies cleanly with 3-way merge on the 
latest tip as well, so should be okay to pick up if all looks fine.

On 26/04/24 02:42, Neha Malcom Francis wrote:
> Add missing ESM and watchdog nodes for the sake of devicetree completion
> of hardware description w.r.t Linux and ESM and WDT enablement on
> U-Boot. This patch series adds the missing nodes for J721E and J7200.
> 
> Boot logs (updated for v3):
> https://gist.github.com/nehamalcom/5dc94ab60f57df5d515d0a6d0da6e0d1
> 
> Changes since v3:
> - added patch (6/6) for adding bootph-pre-ram in main_esm nodes (Udit)
> - no change to boot logs
> 
> Changes since v2:
> https://lore.kernel.org/all/20240412042537.666137-1-n-francis at ti.com/
> - corrected register size for MCU watchdog instance in J7200 (Udit)
> - added Reviewed-by tag (Udit)
> 
> Changes since v1:
> https://lore.kernel.org/all/20240326122723.2329402-1-n-francis at ti.com/
> - modified node name numbering to be in sync with TRM (Udit)
> - disabled wkup_esm node in J721E (Udit)
> - added patch (5/5) for MCU domain watchdog instances in J7200 (Udit)
> Neha Malcom Francis (6):
> 
> arm64: dts: ti: k3-j721e-mcu: Add the WKUP ESM instance
>    arm64: dts: ti: k3-j721e-mcu: Add the MCU domain watchdog instances
>    arm64: dts: ti: k3-j721e-main: Add the MAIN domain watchdog instances
>    arm64: dts: ti: k3-j7200-main: Add the MAIN domain watchdog instances
>    arm64: dts: ti: k3-j7200-mcu: Add the MCU domain watchdog instances
>    arm64: dts: ti: k3-j7*-main: Add bootph-pre-ram to main_esm
> 
>   arch/arm64/boot/dts/ti/k3-j7200-main.dtsi     | 28 ++++++
>   .../boot/dts/ti/k3-j7200-mcu-wakeup.dtsi      | 26 +++++
>   arch/arm64/boot/dts/ti/k3-j721e-main.dtsi     | 94 +++++++++++++++++++
>   .../boot/dts/ti/k3-j721e-mcu-wakeup.dtsi      | 32 +++++++
>   4 files changed, 180 insertions(+)
> 

-- 
Thanking You
Neha Malcom Francis


From krzk at kernel.org  Tue Dec  3 23:54:09 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 08:54:09 +0100
Subject: [PATCH v3 1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add
 properties for ti,lvds-vod-swing
In-Reply-To: <20241203110054.2506123-2-andrej.picej@norik.com>
References: <20241203110054.2506123-1-andrej.picej@norik.com>
 <20241203110054.2506123-2-andrej.picej@norik.com>
Message-ID: <vgg3bygtmj6sotatddkqfapset5bofsqvkzuj7ejuvomn6hs3n@mscq2jbhtaux>

On Tue, Dec 03, 2024 at 12:00:52PM +0100, Andrej Picej wrote:
> Add properties which can be used to specify LVDS differential output
> voltage. Since this also depends on near-end signal termination also
> include property which sets this. LVDS differential output voltage is
> specified with an array (min, max), which should match the one from
> connected device.
> 
> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> ---
> Changes in v3:
> - no change


One version of patchset per 24h.

> Changes in v2:
> - move LVDS port schema to a $defs and reference it from there
> - properties are now defined in microvolts/ohms
> - use 1 property for data-lane and 1 for clock-lane LVDS voltage swing
> - add 1 property which sets LVDS near-end termination
> - since major change was done change the authorship to myself
> ---
>  .../bindings/display/bridge/ti,sn65dsi83.yaml | 36 +++++++++++++++++--
>  1 file changed, 33 insertions(+), 3 deletions(-)

...

>  allOf:
>    - if:
>        properties:
> @@ -120,7 +150,7 @@ allOf:
>            properties:
>              port at 1: false
>  
> -additionalProperties: false
> +additionalProperties: true

This cannot be true. Not explained in commit msg and this is not shared
schema.

>  
>  examples:
>    - |
> -- 
> 2.34.1
> 


From esben at geanix.com  Wed Dec  4 00:09:19 2024
From: esben at geanix.com (Esben Haabendal)
Date: Wed, 04 Dec 2024 09:09:19 +0100
Subject: [PATCH 0/6] rtc: Fix problems with missing UIE irqs
In-Reply-To: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com> (Esben
	Haabendal's message of "Tue, 03 Dec 2024 11:45:30 +0100")
References: <20241203-rtc-uie-irq-fixes-v1-0-01286ecd9f3f@geanix.com>
Message-ID: <87cyi798eo.fsf@geanix.com>

Esben Haabendal <esben at geanix.com> writes:

> This fixes a couple of different problems, that can cause RTC (alarm)
> irqs to be missing when generating UIE interrupts.
>
> The first commit fixes a long-standing problem, which has been
> documented in a comment since 2010. This fixes a race that could cause
> UIE irqs to stop being generated, which was easily reproduced by
> timing the use of RTC_UIE_ON ioctl with the seconds tick in the RTC.
>
> The last commit ensures that RTC (alarm) irqs are enabled whenever
> RTC_UIE_ON ioctl is used.
>
> The driver specific commits avoids kernel warnings about unbalanced
> enable_irq/disable_irq, which gets triggered on first RTC_UIE_ON with
> the last commit. Before this series, the same warning should be seen
> on initial RTC_AIE_ON with those drivers.

I don't have access to hardware using cpcap, st-lpc or tps6586x rtc
drivers, so I have not been able to test those 3 patches.

/Esben

> Signed-off-by: Esben Haabendal <esben at geanix.com>
> ---
> Esben Haabendal (6):
>       rtc: interface: Fix long-standing race when setting alarm
>       rtc: isl12022: Fix initial enable_irq/disable_irq balance
>       rtc: cpcap: Fix initial enable_irq/disable_irq balance
>       rtc: st-lpc: Fix initial enable_irq/disable_irq balance
>       rtc: tps6586x: Fix initial enable_irq/disable_irq balance
>       rtc: interface: Ensure alarm irq is enabled when UIE is enabled
>
>  drivers/rtc/interface.c    | 27 +++++++++++++++++++++++++++
>  drivers/rtc/rtc-cpcap.c    |  1 +
>  drivers/rtc/rtc-isl12022.c |  1 +
>  drivers/rtc/rtc-st-lpc.c   |  1 +
>  drivers/rtc/rtc-tps6586x.c |  1 +
>  5 files changed, 31 insertions(+)
> ---
> base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
> change-id: 20241203-rtc-uie-irq-fixes-f2838782d0f8
>
> Best regards,


From andy.yan at rock-chips.com  Wed Dec  4 00:22:24 2024
From: andy.yan at rock-chips.com (Andy Yan)
Date: Wed, 4 Dec 2024 16:22:24 +0800
Subject: [PATCH v3 2/3] dt-bindings: display: rockchip: Add schema for
 RK3588 DW DSI2 controller
In-Reply-To: <20241203165450.1501219-3-heiko@sntech.de>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241203165450.1501219-3-heiko@sntech.de>
Message-ID: <0f76db0b-3860-432e-a203-51ada754edd7@rock-chips.com>

Hi Heiko,

On 12/4/24 00:54, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> The Display Serial Interface 2 (DSI-2) is part of a group of communication
> protocols defined by the MIPI Alliance. The RK3588 implements this
> specification in its two MIPI DSI-2 Host Controllers that are based on a
> new Synopsis IP.

   Synopsys ?

> 
> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
> ---
>   .../rockchip/rockchip,rk3588-mipi-dsi2.yaml   | 119 ++++++++++++++++++
>   1 file changed, 119 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml
> new file mode 100644
> index 000000000000..7c017e927223
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.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/rockchip/rockchip,rk3588-mipi-dsi2.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip specific extensions to the Synopsys Designware MIPI DSI2
> +
> +maintainers:
> +  - Heiko Stuebner <heiko at sntech.de>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - rockchip,rk3588-mipi-dsi2
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 2
> +
> +  clock-names:
> +    items:
> +      - const: pclk
> +      - const: sys
> +
> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      This SoC uses GRF regs to switch between vopl/vopb.
> +
> +  phys:
> +    maxItems: 1
> +
> +  phy-names:
> +    const: dcphy
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 1
> +
> +  reset-names:
> +    const: apb
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Input node to receive pixel data.
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: DSI output node to panel.
> +
> +    required:
> +      - port at 0
> +      - port at 1
> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - rockchip,grf
> +  - phys
> +  - phy-names
> +  - ports
> +  - reg
> +
> +allOf:
> +  - $ref: /schemas/display/dsi-controller.yaml#
> +
> +unevaluatedProperties: 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>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      dsi at fde20000 {
> +        compatible = "rockchip,rk3588-mipi-dsi2";
> +        reg = <0x0 0xfde20000 0x0 0x10000>;
> +        interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>;
> +        clocks = <&cru PCLK_DSIHOST0>, <&cru CLK_DSIHOST0>;
> +        clock-names = "pclk", "sys";
> +        resets = <&cru SRST_P_DSIHOST0>;
> +        reset-names = "apb";
> +        power-domains = <&power RK3588_PD_VOP>;
> +        phys = <&mipidcphy0>;
> +        phy-names = "dcphy";
> +        rockchip,grf = <&vop_grf>;
> +
> +        ports {
> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +          dsi0_in: port at 0 {
> +            reg = <0>;
> +          };
> +
> +          dsi0_out: port at 1 {
> +            reg = <1>;
> +          };
> +        };
> +      };
> +    };


From krzk at kernel.org  Wed Dec  4 00:34:52 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 09:34:52 +0100
Subject: [PATCH 4/4] dt-bindings: soc: ti: ti,j721e-system-controller:
 Add MAC efuse property
In-Reply-To: <20241203173113.90009-4-afd@ti.com>
References: <20241203173113.90009-1-afd@ti.com>
 <20241203173113.90009-4-afd@ti.com>
Message-ID: <xknwuwjuedakc2f4ln3nsvsc2lux7ma55ivcetdoao6qq7jyzo@6nqyex3h2v4n>

On Tue, Dec 03, 2024 at 11:31:13AM -0600, Andrew Davis wrote:
> Add a pattern property for MAC efuse which can be part of this controller.

Can be or is? Please describe the hardware what do you have there.

> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/soc/ti/ti,j721e-system-controller.yaml         | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> index ead0679b30e3f..fbaae3d1bef60 100644
> --- a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> +++ b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> @@ -80,6 +80,12 @@ patternProperties:
>      description:
>        This is the PCIe control region.
>  
> +  "^ethernet-mac-syscon@[0-9a-f]+$":

Drop syscon, unless this is system controller because in such case drop
ethernet-mac.

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec  4 00:36:31 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 09:36:31 +0100
Subject: [PATCH 4/4] dt-bindings: soc: ti: ti,j721e-system-controller:
 Add MAC efuse property
In-Reply-To: <20241203173113.90009-4-afd@ti.com>
References: <20241203173113.90009-1-afd@ti.com>
 <20241203173113.90009-4-afd@ti.com>
Message-ID: <f34b7uedhfvsebtluy4wca3l7u5rl2iwfmwbsfjjyvqizv3zk3@fsfjn5ezpeke>

On Tue, Dec 03, 2024 at 11:31:13AM -0600, Andrew Davis wrote:
> Add a pattern property for MAC efuse which can be part of this controller.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/soc/ti/ti,j721e-system-controller.yaml         | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> index ead0679b30e3f..fbaae3d1bef60 100644
> --- a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> +++ b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> @@ -80,6 +80,12 @@ patternProperties:
>      description:
>        This is the PCIe control region.
>  
> +  "^ethernet-mac-syscon@[0-9a-f]+$":
> +    type: object
> +    $ref: /schemas/mfd/syscon.yaml#
> +    description:
> +      This is the Ethernet MAC efuse region.

Actually considering my comment on the previous patch - drop.

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec  4 00:36:48 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 09:36:48 +0100
Subject: [PATCH 2/4] dt-bindings: soc: ti: ti,j721e-system-controller:
 Add ICSSG ctrl property
In-Reply-To: <20241203173113.90009-2-afd@ti.com>
References: <20241203173113.90009-1-afd@ti.com>
 <20241203173113.90009-2-afd@ti.com>
Message-ID: <6b4xyh6wjbwt6l44as53wnj57wrga4xscczzjpnxpewd6epxcs@q5odjtm237ny>

On Tue, Dec 03, 2024 at 11:31:11AM -0600, Andrew Davis wrote:
> Add a pattern property for icssg-ctrl which can be part of this controller.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/soc/ti/ti,j721e-system-controller.yaml         | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> index 378e9cc5fac2a..9ba9cb100ab30 100644
> --- a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> +++ b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> @@ -68,6 +68,12 @@ patternProperties:
>      description:
>        The node corresponding to SoC chip identification.
>  
> +  "^icssg-ctrl@[0-9a-f]+$":
> +    type: object
> +    $ref: /schemas/mfd/syscon.yaml#
> +    description:
> +      This is the ICSSG control region.

Drop, regions are not described in DTS.

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec  4 00:36:08 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 09:36:08 +0100
Subject: [PATCH 3/4] dt-bindings: soc: ti: ti,j721e-system-controller:
 Add PCIe ctrl property
In-Reply-To: <20241203173113.90009-3-afd@ti.com>
References: <20241203173113.90009-1-afd@ti.com>
 <20241203173113.90009-3-afd@ti.com>
Message-ID: <kno3z5nszu4437kvon5nxmxv6qzhjagdjti2guljowmmvkbskr@6falbmmpidki>

On Tue, Dec 03, 2024 at 11:31:12AM -0600, Andrew Davis wrote:
> Add a pattern property for pcie-ctrl which can be part of this controller.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/soc/ti/ti,j721e-system-controller.yaml         | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> index 9ba9cb100ab30..ead0679b30e3f 100644
> --- a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> +++ b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
> @@ -74,6 +74,12 @@ patternProperties:
>      description:
>        This is the ICSSG control region.
>  
> +  "^pcie-ctrl@[0-9a-f]+$":
> +    type: object
> +    $ref: /schemas/mfd/syscon.yaml#
> +    description:
> +      This is the PCIe control region.

This device (parent) is a syscon already. There is no sub-block
representation, because what would be next? Third child with a node per
each register?

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec  4 00:38:22 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 09:38:22 +0100
Subject: [PATCH 1/4] dt-bindings: mfd: syscon: Add ti,am654-icssg-ctrl
 compatible
In-Reply-To: <20241203173113.90009-1-afd@ti.com>
References: <20241203173113.90009-1-afd@ti.com>
Message-ID: <ii7dbehl2ecvgc6e4kqy5nk2e22hnbk43tldqfxjk7xxapnp5x@7ojnf36ej3fm>

On Tue, Dec 03, 2024 at 11:31:10AM -0600, Andrew Davis wrote:
> Add TI ICSSG control registers compatible. This is a region found in the
> TI AM65 CTRL_MMR0 register space[0]. Each instance is used to control a
> an ICSSG's RGMII delay and GPO mode.
> 
> [0] https://www.ti.com/lit/pdf/spruid7
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  Documentation/devicetree/bindings/mfd/syscon.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
> index b414de4fa779b..34943d9fc0ab5 100644
> --- a/Documentation/devicetree/bindings/mfd/syscon.yaml
> +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
> @@ -115,6 +115,7 @@ select:
>            - ti,am625-dss-oldi-io-ctrl
>            - ti,am62p-cpsw-mac-efuse
>            - ti,am654-dss-oldi-io-ctrl
> +          - ti,am654-icssg-ctrl

Considering your patch #2 adding something with similar name, this is
quite confusing.

Anyway, where is any user of this? If there is no user, then why? If
there is, then commit msg should explain that you document existing
device.

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec  4 00:40:52 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 4 Dec 2024 09:40:52 +0100
Subject: [PATCH v1 1/2] dt-bindings: soc: samsung: exynos-pmu: Add
 exynos990-pmu compatible
In-Reply-To: <20241203211344.515431-2-igor.belwon@mentallysanemainliners.org>
References: <20241203211344.515431-1-igor.belwon@mentallysanemainliners.org>
 <20241203211344.515431-2-igor.belwon@mentallysanemainliners.org>
Message-ID: <yqdtp6gllg4x5a4sysmgvgyd4y6z6h6ly556bzbuafkkaba3e5@pgnuhlbx7e2j>

On Tue, Dec 03, 2024 at 10:13:43PM +0100, Igor Belwon wrote:
> Add a dt-binding compatible for the exynos990-pmu.

s/exynos990-pmu/Exynos990 PMU (and here goes explanation of PMU). You
just copied subject and basically copied patch contents which is
obvious. Instead say something useful about hardware, e.g.
is it different or is it compatible with anything?

Best regards,
Krzysztof



From t.antoine at uclouvain.be  Wed Dec  4 00:49:55 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Wed, 4 Dec 2024 09:49:55 +0100
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <d1bade77b5281c1de6b2ddcb4dbbd033e455a116.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
 <8f585460a1bc52f78a6d0867aed87398bde30152.camel@linaro.org>
 <18629c9edd295a524a1c9764f013a0e97e0b275f.camel@linaro.org>
 <61a54367-2406-4106-bf8b-9fda4f2d11a6@uclouvain.be>
 <d1bade77b5281c1de6b2ddcb4dbbd033e455a116.camel@linaro.org>
Message-ID: <ed9cf02b-6f6e-46b5-a583-4fd32fa31a91@uclouvain.be>

On 12/3/24 12:06, Andr? Draszik wrote:
> On Tue, 2024-12-03 at 11:30 +0100, Thomas Antoine wrote:
>> Should I explicitly deny their use in the code for the max77759 or is it
>> just for information?
> I'd probably do something like this, which will indeed deny their reading
> and/or writing, both via debugfs, and also normal driver access via
> readmap_read()/write() etc:
> 
> static const struct regmap_range max77759_registers[] = {
> 	regmap_reg_range(0x00, 0x4f),
> 	regmap_reg_range(0xb0, 0xbf),
> 	regmap_reg_range(0xd0, 0xd0),
> 	regmap_reg_range(0xdc, 0xdf),
> 	regmap_reg_range(0xfb, 0xfb),
> 	regmap_reg_range(0xff, 0xff),
> };
> 
> static const struct regmap_range max77759_ro_registers[] = {
> 	regmap_reg_range(0x3d, 0x3d),
> 	regmap_reg_range(0xfb, 0xfb),
> 	regmap_reg_range(0xff, 0xff),
> };
> 
> static const struct regmap_access_table max77759_write_table = {
> 	.yes_ranges = max77759_registers,
> 	.n_yes_ranges = ARRAY_SIZE(max77759_registers),
> 	.no_ranges = max77759_ro_registers,
> 	.n_no_ranges = ARRAY_SIZE(max77759_ro_registers),
> };
> 
> static const struct regmap_access_table max77759_rd_table = {
> 	.yes_ranges = max77759_registers,
> 	.n_yes_ranges = ARRAY_SIZE(max77759_registers),
> };
> 
> static const struct regmap_config max77759_regmap_config = {
> 	.reg_bits = 8,
> 	.val_bits = 8,
> 	.max_register = 0xff,
> 	.wr_table = &max77759_write_table,
> 	.rd_table = &max77759_rd_table,
> 	.cache_type = REGCACHE_NONE,
> };
> 
> And maybe without cache for now. Most are probably not cacheable anyway.

Thank you very much, I'll try this out.

Best regards,
Thomas


From maz at kernel.org  Wed Dec  4 00:51:26 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Dec 2024 08:51:26 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP
In-Reply-To: <20241203221453.mwh6sozyczi4ec2k@altlinux.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
	<20241202153618.GA6834@willie-the-truck>
	<86ttbmt71k.wl-maz@kernel.org>
	<20241202155940.p267a3tz5ypj4sog@altlinux.org>
	<86ser6t6fs.wl-maz@kernel.org>
	<20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
	<20241203092721.j473dthkbq6wzez7@altlinux.org>
	<1847e34fa7724d28aeb22d93752f64f2@huawei.com>
	<20241203221453.mwh6sozyczi4ec2k@altlinux.org>
Message-ID: <87jzcfsuep.wl-maz@kernel.org>

On Tue, 03 Dec 2024 22:14:53 +0000,
Vitaly Chikunov <vt at altlinux.org> wrote:
> 
> Shameer, Marc, Oliver, Will,
> 
> On Tue, Dec 03, 2024 at 10:03:11AM +0000, Shameerali Kolothum Thodi wrote:
> > > -----Original Message-----
> > > From: linux-arm-kernel <linux-arm-kernel-bounces at lists.infradead.org> On
> > > Behalf Of Vitaly Chikunov
> > > Sent: Tuesday, December 3, 2024 9:27 AM
> > > To: Marc Zyngier <maz at kernel.org>
> > > Cc: Will Deacon <will at kernel.org>; james.morse at arm.com; linux-arm-
> > > kernel at lists.infradead.org; Catalin Marinas <catalin.marinas at arm.com>;
> > > linux-kernel at vger.kernel.org; oliver.upton at linux.dev;
> > > mark.rutland at arm.com
> > > Subject: Re: v6.13-rc1: Internal error: Oops - Undefined instruction:
> > > 0000000002000000 [#1] SMP
> > > 
> > > Marc,
> > > 
> > > On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> > > > On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > > > > On Mon, 02 Dec 2024 15:59:40 +0000,
> > > > > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > > > >
> > > > > > Marc,
> > > > > >
> > > > > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > > > > >
> > > > > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > > > >
> > > > > > No, host is 6.6.60.
> > > > >
> > > > > Right. I wouldn't be surprised if:
> > > > >
> > > > > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> > > > >   that's proably something we should backport)
> > > >
> > > > How to confirm this? Currently I cannot find any (case-insensitive)
> > > > "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM
> > > > strings in `strace -v` (as it decodes some KVM ioctls) of qemu process.
> > > >
> > > > >
> > > > > - you get a nastygram in the host log telling you that the guest has
> > > > >   executed something it shouldn't (you'll get the encoding of the
> > > > >   instruction)
> > > >
> > > > I requested admins of the box for dmesg output since I don't have root
> > > > access myself and nowadays dmesg is not accessible for a user.
> > > 
> > > This is what they reported:
> > > 
> > >   kvm [2502822]: Unsupported guest sys_reg access at: ffff80008003e9f0
> > > [000000c5]
> > >                    { Op0( 3), Op1( 0), CRn(10), CRm( 4), Op2( 4), func_read },
> > > 
> > 
> > As Will pointed out I think this is access to MPAMIDR_EL1 and is from this
> > code here,
> > 
> > +++ b/arch/arm64/kernel/cpuinfo.c
> > @@ -478,6 +478,9 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
> >  	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
> >  		__cpuinfo_store_cpu_32bit(&info->aarch32);
> >  
> > +	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
> > +		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
> > +
> >  	cpuinfo_detect_icache_policy(info);
> >  }
> > 
> > I did manage to boot my setup in 6.6 and this is what happens,
> > 
> > Host kernel 6.6
> > Guest Kernel 6.13-rc1
> > 
> > [    0.195392] smp: Brought up 1 node, 8 CPUs
> > [    0.219000] SMP: Total of 8 processors activated.
> > [    0.219629] CPU: All CPU(s) started at EL1
> > ...
> > [    0.223212] CPU features: detected: RAS Extension Support
> > [    0.223927] CPU features: detected: Memory Partitioning And Monitoring
> > [    0.224796] CPU features: detected: Memory Partitioning And Monitoring Virtualisation
> > [    0.225961] alternatives: applying system-wide alternatives
> > ...
> > 
> > Guest detects MPAM and boots fine.
> > 
> > Host kernel 6.13-rc1
> > Guest Kernel 6.13-rc1
> > 
> > [    0.196625] smp: Brought up 1 node, 8 CPUs
> > [    0.222093] SMP: Total of 8 processors activated.
> > [    0.222769] CPU: All CPU(s) started at EL1
> > ...
> > [    0.226620] CPU features: detected: RAS Extension Support
> > [    0.227453] alternatives: applying system-wide alternatives
> > 
> > MPAM is not visible to Guest in this case.
> > 
> > So as I pointed out earlier could it be a case where the ID register reports MPAM support
> > but the firmware has not enabled MPAM?
> > 
> > James seems to be mentioning that case here,
> > 
> > " (If you have a boot failure that bisects here its likely your CPUs
> > advertise MPAM in the id registers, but firmware failed to either enable
> > or MPAM, or emulate the trap as if it were disabled)"
> 
> I tried to verify that MPAM is advertised with qemu+gdb method, as
> suggested by Oliver, but ID_AA64PFR0_EL1 register is not there.
> 
>   (gdb) i r ID_AA64PFR0_EL1
>   Invalid register `ID_AA64PFR0_EL1'

Then there is a bug in either QEMU or the GDB stubs. This register
exists, or you wouldn't be here.

> 
> Are there other suggestions?

Mark has described what the problem is likely to be. 6.6-stable needs
to have 6685f5d572c22e10 backported, and it probably should have been
Cc: to stable. Can you please apply the following patch to your *host*
machine and retest?

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 370a1a7bd369..258a39bcd3c7 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1330,6 +1330,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
 			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
 
 		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MPAM_frac);
 		break;
 	case SYS_ID_AA64ISAR1_EL1:
 		if (!vcpu_has_ptrauth(vcpu))
@@ -1472,6 +1473,13 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
 
 	val &= ~ID_AA64PFR0_EL1_AMU_MASK;
 
+	/*
+	 * MPAM is disabled by default as KVM also needs a set of PARTID to
+	 * program the MPAMVPMx_EL2 PARTID remapping registers with. But some
+	 * older kernels let the guest see the ID bit.
+	 */
+	val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
+
 	return val;
 }
 
@@ -1560,6 +1568,29 @@ static int set_id_dfr0_el1(struct kvm_vcpu *vcpu,
 	return set_id_reg(vcpu, rd, val);
 }
 
+static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
+			       const struct sys_reg_desc *rd, u64 user_val)
+{
+	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+	u64 mpam_mask = ID_AA64PFR0_EL1_MPAM_MASK;
+
+	/*
+	 * Commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits
+	 * in ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to
+	 * guests, but didn't add trap handling. KVM doesn't support MPAM and
+	 * always returns an UNDEF for these registers. The guest must see 0
+	 * for this field.
+	 *
+	 * But KVM must also accept values from user-space that were provided
+	 * by KVM. On CPUs that support MPAM, permit user-space to write
+	 * the sanitizied value to ID_AA64PFR0_EL1.MPAM, but ignore this field.
+	 */
+	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
+		user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
+
+	return set_id_reg(vcpu, rd, user_val);
+}
+
 /*
  * cpufeature ID register user accessors
  *
@@ -2018,7 +2049,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_ID_AA64PFR0_EL1),
 	  .access = access_id_reg,
 	  .get_user = get_id_reg,
-	  .set_user = set_id_reg,
+	  .set_user = set_id_aa64pfr0_el1,
 	  .reset = read_sanitised_id_aa64pfr0_el1,
 	  .val = ID_AA64PFR0_EL1_CSV2_MASK | ID_AA64PFR0_EL1_CSV3_MASK, },
 	ID_SANITISED(ID_AA64PFR1_EL1),

> > https://lore.kernel.org/all/20241030160317.2528209-4-joey.gouly at arm.com/
> > 
> > Is there a way you can find out the BIOS version on that board?
> 
> Unfortunately, admins of the server do not provide me with this
> info.

This doesn't really help, I'm afraid.

> For such cases, when MPAM is incorrectly advertised, can we have kernel
> command line parameter like mpam=0 to override it's detection?

We could, but only when we can confirm what the problem is.

> I think with "If you have a boot failure that bisects here" it's
> acknowledged possibility and it's confirmed by our server.

Not really. This talks about firmware. We are debugging the hypervisor
here. This might be closely related, but these are not the same
things.

Thanks,

	M.

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


From t.antoine at uclouvain.be  Wed Dec  4 00:53:11 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Wed, 4 Dec 2024 09:53:11 +0100
Subject: [PATCH 1/4] power: supply: add support for max77759 fuel gauge
In-Reply-To: <16f9b5f8aed79e9313b4638512896743fa5a8d6d.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-1-98d2fa7bfe30@uclouvain.be>
 <c377f3302c6c282ad826211c859e2b65bb1222cb.camel@linaro.org>
 <9387c0cf-d291-485a-8cd1-1aced7eba14e@uclouvain.be>
 <2883fb0dd22312d5da9039d4fef869276a0bd430.camel@linaro.org>
 <bce22ca8-aed2-41ae-b2ef-fdc71266709a@uclouvain.be>
 <16f9b5f8aed79e9313b4638512896743fa5a8d6d.camel@linaro.org>
Message-ID: <7d63c607-dbd7-4109-812a-3936074f231f@uclouvain.be>

On 12/3/24 12:02, Andr? Draszik wrote:
> On Tue, 2024-12-03 at 11:11 +0100, Thomas Antoine wrote:
>> On 12/3/24 10:31, Andr? Draszik wrote:
>>> On Tue, 2024-12-03 at 10:08 +0100, Thomas Antoine wrote:
>>>> On 12/3/24 07:47, Andr? Draszik wrote:
>>>>>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>>>>>
> [...]
> 
>>>>>>  /*
>>>>>>   * Model Gauge M5 Algorithm output register
>>>>>>   * Volatile data (must not be cached)
>>>>>> @@ -369,6 +387,8 @@ static int max1720x_battery_get_property(struct
>>>>>> power_supply *psy,
>>>>>>                       val->strval = max17201_model;
>>>>>>               else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17205)
>>>>>>                       val->strval = max17205_model;
>>>>>> +             else if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX77759)
>>>>>> +                     val->strval = max77759_model;
>>>>>>               else
>>>>>
>>>>> This is a 16 bit register, and while yes, MAX172XX_DEV_NAME_TYPE_MASK only
>>>>> cares about the bottom 4 bits, the register is described as 'Firmware
>>>>> Version Information'.
>>>>>
>>>>> But maybe it's ok to do it like that, at least for now.
>>>>
>>>> I thought this method would be ok as long as there is no collision on
>>>> values. I hesitated to change the model evaluation method based on chip
>>>> model, where the max77759 would thus have an hard-coded value and the
>>>> max1720x would still evaluate the register value. I did not do it because
>>>> it led to a lot more changes for no difference.
>>>
>>> Downstream uses the upper bits for max77759:
>>> https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max_m5.h#135
>>>
>>> I don't know what the original max17201/5 report in this register
>>> for those bits, though. Given for max77759 this register returns
>>> the firmware version, I assume the lower bits can change.
>>
>> Based on this datasheet of the max1720x, the upper bits are the revision
>> and the four lower bits are device. So it could change.
>> https://www.analog.com/media/en/technical-documentation/data-sheets/MAX17201-MAX17215.pdf#MAX17201%20DS.indd%3A.213504%3A15892
>>
>> If the four lower bits are not always 0 for the max77759 then I guess it
>> is necessary to change this as it wouldn't work with all max77759.
> 
> Maybe the best way forward is to go by the compatible (from DT), and
> if max77759 to then print a warning if the upper bits are != 0x62 and
> != 0x63. And maybe even refuse to load in that case.

Will implement this for v2, thank you.

Best regards,
Thomas


From maz at kernel.org  Wed Dec  4 01:04:26 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Dec 2024 09:04:26 +0000
Subject: [RFC PATCH 05/14] KVM: arm64: Always allow fixed cycle counter
In-Reply-To: <Z0-HBsBgf6WB7x4R@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
	<20241203193220.1070811-6-oliver.upton@linux.dev>
	<87ldwwsbad.wl-maz@kernel.org>
	<Z0-HBsBgf6WB7x4R@linux.dev>
Message-ID: <87ikrzstt1.wl-maz@kernel.org>

On Tue, 03 Dec 2024 22:32:38 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Tue, Dec 03, 2024 at 09:32:10PM +0000, Marc Zyngier wrote:
> > On Tue, 03 Dec 2024 19:32:11 +0000,
> > Oliver Upton <oliver.upton at linux.dev> wrote:
> > > 
> > > The fixed CPU cycle counter is mandatory for PMUv3, so it doesn't make a
> > > lot of sense allowing userspace to filter it. Only apply the PMU event
> > > filter to *programmed* event counters.
> > 
> > But that's a change in ABI, isn't it? We explicitly say in the
> > documentation that the cycle counter can be filtered by specifying
> > event 0x11.
> 
> Yeah... A bit of a dirty shortcut I took because I don't like the ABI,
> but distaste isn't enough to break it :)
> 
> > More importantly, the current filtering works in terms of events, and
> > not in terms of counters.
> > 
> > Instead of changing the ABI, how about simply not supporting filtering
> > on such non-compliant HW? Surely that would simplify a few things.
> 
> Yeah, that sounds reasonable. Especially if we allow programmable event
> counters where the event ID space doesn't match the architecture.

Another thing I have been wondering is if a slightly better approach
would be to move some of the handling to the PMU driver itself, and
let it emulate PMUv3 if it can. This would allow conversion of event
numbers in situ rather than polluting the PMUv3 code in KVM.

	M.

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


From yangyicong at huawei.com  Wed Dec  4 01:08:39 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 4 Dec 2024 17:08:39 +0800
Subject: [PATCH 5/5] KVM: arm64: Handle DABT caused by LS64* instructions
 on unsupported memory
In-Reply-To: <87o71trtrx.wl-maz@kernel.org>
References: <20241202135504.14252-1-yangyicong@huawei.com>
 <20241202135504.14252-6-yangyicong@huawei.com> <87o71trtrx.wl-maz@kernel.org>
Message-ID: <357fbc9b-c73e-7494-0c48-27917b95005f@huawei.com>

On 2024/12/3 17:38, Marc Zyngier wrote:
> On Mon, 02 Dec 2024 13:55:04 +0000,
> Yicong Yang <yangyicong at huawei.com> wrote:
>>
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> FEAT_LS64* instructions only support to access Device/Uncacheable
>> memory, otherwise a data abort for unsupported Exclusive or atomic
> 
> Not quite. FEAT_LS64WB explicitly supports Write-Back mappings.

thanks for the information, I didn't know this since it's not listed on DDI0487K.a,
have seen this feature from [1]. will refine the comments and mention the behaviour
applies when no FEAT_LS64WB.

[1] https://developer.arm.com/documentation/109697/2024_09/Feature-descriptions/The-Armv9-6-architecture-extension

> 
>> access (0x35) is generated per spec. It's implementation defined
>> whether the target exception level is routed and is possible to
>> implemented as route to EL2 on a VHE VM. Per DDI0487K.a Section
>> C3.2.12.2 Single-copy atomic 64-byte load/store:
>>
>>   The check is performed against the resulting memory type after all
>>   enabled stages of translation. In this case the fault is reported
>>   at the final enabled stage of translation.
>>
>> If it's implemented as generate the DABT to the final enabled stage
>> (stage-2), inject a DABT to the guest to handle it.
>>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> ---
>>  arch/arm64/kvm/mmu.c | 14 ++++++++++++++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
>> index c9d46ad57e52..b7e6f0a27537 100644
>> --- a/arch/arm64/kvm/mmu.c
>> +++ b/arch/arm64/kvm/mmu.c
>> @@ -1787,6 +1787,20 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>>  		return 1;
>>  	}
>>  
>> +	/*
>> +	 * If instructions of FEAT_{LS64, LS64_V, LS64_ACCDATA} operated on
>> +	 * unsupported memory regions, a DABT for unsupported Exclusive or
>> +	 * atomic access is generated. It's implementation defined whether
>> +	 * the exception will be taken to, a stage-1 DABT or the final enabled
>> +	 * stage of translation (stage-2 in this case as we hit here). Inject
>> +	 * a DABT to the guest to handle it if it's implemented as a stage-2
>> +	 * DABT.
>> +	 */
>> +	if (esr_fsc_is_excl_atomic_fault(esr)) {
>> +		kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
>> +		return 1;
>> +	}
> 
> This doesn't seem quite right. This is injecting an *External* Data
> Abort, which is not what the spec says happens, as you are emulating
> the *first* acceptable behaviour:
> 
>   "The check is performed at each enabled stage of translation, and
>    the fault is reported for the first stage of translation that
>    provides an inappropriate memory type. In this case, the value of
>    the HCR_EL2.DC bit does not cause accesses generated by the
>    instructions to generate a stage 1 Data abort,"
> 
> So while the exception is reported at a different EL, the fault should
> still be an "unsupported Exclusive or atomic access". 

yes it's trying to emulate the first behaviour to let guest OS handle it
as how host OS handle it - send a SIGBUS to the EL0 task if it's performing
on unsupported memory type. Currently if such cases happens the VM will be
killed without the handling here. Keep the injected FSC as "unsupported
Exclusive or atomic access" should be more proper, will make it in next
version.

> But that's also
> assuming that S2 has a device mapping, and it is EL1 that did
> something wrong. Surely you should check the IPA against its memory
> type?

in my case it happens when both S1 and S2 mapping is normal memory, for example
running the hwcap test (PATCH 3/5) in the VM. But yes the memory type should
be checked here.

> 
> Further questions: what happens when a L2 guest triggers such fault?
> I don't think you can't arbitrarily route it back to L2 without
> looking at why it faulted.
> 

will see what affect to the nested VM case. but as you point out, it's
too early to inject the abort here, at least we should check the memory
type. will address it.

Thanks.






From thomas.richard at bootlin.com  Wed Dec  4 01:08:43 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Wed, 4 Dec 2024 10:08:43 +0100
Subject: [PATCH] arm64: dts: ti: k3-j784s4: use ti,j7200-padconf
 compatible
In-Reply-To: <20241119190106.GA70080@francesco-nb>
References: <20241113-j784s4-s2r-pinctrl-v1-1-19aeb62739bc@bootlin.com>
 <20241119190106.GA70080@francesco-nb>
Message-ID: <6e47e420-84c4-4539-ba54-5e1e939a37a5@bootlin.com>

On 11/19/24 20:01, Francesco Dolcini wrote:
> Hello Thomas and TI folks,
> 
> On Wed, Nov 13, 2024 at 11:43:05AM +0100, Thomas Richard wrote:
>> Like on j7200, pinctrl contexts shall be saved and restored during
>> suspend-to-ram.
>>
>> So use ti,j7200-padconf compatible.
>>
>> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
>> ---
>> Use ti,j7200-padconf compatible to save and restore pinctrl contexts during
>> suspend-to-ram.
>> ---
>>  arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi       |  6 +++---
>>  arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 12 ++++++------
> 
> Do j784s4 supports any kind of low power mode and/or suspend to ram? My
> understanding was that this was not supported, but maybe there is some
> details that was lost when I was told this information.

Hello Francesco,

We are working on suspend-to-ram support for j7200 and j784s4.
During suspend-to-ram the SoC is fully powered-off (thanks to the PMIC
which powers off all the power rails except the DDR which is in
self-refresh), like on j7200.
Please let me know if you want more details.

Regards,

Thomas


From maxime.chevallier at bootlin.com  Wed Dec  4 01:09:22 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Wed, 4 Dec 2024 10:09:22 +0100
Subject: [net-next PATCH v8 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241204072427.17778-4-ansuelsmth@gmail.com>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
	<20241204072427.17778-4-ansuelsmth@gmail.com>
Message-ID: <20241204100922.0af25d7e@fedora.home>

Hello Christian,

On Wed,  4 Dec 2024 08:24:10 +0100
Christian Marangi <ansuelsmth at gmail.com> wrote:

> Add Airoha AN8855 5-Port Gigabit DSA switch.
> 
> The switch is also a nvmem-provider as it does have EFUSE to calibrate
> the internal PHYs.
> 
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>

[...]

My two-cents review below :)

> +static void
> +an8855_phylink_mac_config(struct phylink_config *config, unsigned int mode,
> +			  const struct phylink_link_state *state)
> +{
> +	struct dsa_port *dp = dsa_phylink_to_port(config);
> +	struct dsa_switch *ds = dp->ds;
> +	struct an8855_priv *priv;
> +	int port = dp->index;
> +
> +	priv = ds->priv;
> +
> +	if (port != 5) {
> +		if (port > 5)
> +			dev_err(ds->dev, "unsupported port: %d", port);
> +		return;
> +	}

Looks like the above condition can be simplified to :

	if (port > 5)
		dev_err(...);


> +
> +	regmap_update_bits(priv->regmap, AN8855_PMCR_P(port),
> +			   AN8855_PMCR_IFG_XMIT | AN8855_PMCR_MAC_MODE |
> +			   AN8855_PMCR_BACKOFF_EN | AN8855_PMCR_BACKPR_EN,
> +			   FIELD_PREP(AN8855_PMCR_IFG_XMIT, 0x1) |
> +			   AN8855_PMCR_MAC_MODE | AN8855_PMCR_BACKOFF_EN |
> +			   AN8855_PMCR_BACKPR_EN);
> +}
> +
> +static void an8855_phylink_get_caps(struct dsa_switch *ds, int port,
> +				    struct phylink_config *config)
> +{
> +	switch (port) {
> +	case 0:
> +	case 1:
> +	case 2:
> +	case 3:
> +	case 4:
> +		__set_bit(PHY_INTERFACE_MODE_GMII,
> +			  config->supported_interfaces);
> +		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
> +			  config->supported_interfaces);
> +		break;
> +	case 5:
> +		phy_interface_set_rgmii(config->supported_interfaces);
> +		__set_bit(PHY_INTERFACE_MODE_SGMII,
> +			  config->supported_interfaces);
> +		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
> +			  config->supported_interfaces);
> +		break;
> +	}
> +
> +	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
> +				   MAC_10 | MAC_100 | MAC_1000FD;

For port 5, you may also add the MAC_2500FD capability as it supports
2500BASEX ?

> +}
> +

[...]

> +
> +static void
> +an8855_phylink_mac_link_up(struct phylink_config *config,
> +			   struct phy_device *phydev, unsigned int mode,
> +			   phy_interface_t interface, int speed, int duplex,
> +			   bool tx_pause, bool rx_pause)
> +{
> +	struct dsa_port *dp = dsa_phylink_to_port(config);
> +	struct an8855_priv *priv = dp->ds->priv;
> +	int port = dp->index;
> +	u32 reg;
> +
> +	reg = regmap_read(priv->regmap, AN8855_PMCR_P(port), &reg);
> +	if (phylink_autoneg_inband(mode)) {
> +		reg &= ~AN8855_PMCR_FORCE_MODE;
> +	} else {
> +		reg |= AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK;
> +
> +		reg &= ~AN8855_PMCR_FORCE_SPEED;
> +		switch (speed) {
> +		case SPEED_10:
> +			reg |= AN8855_PMCR_FORCE_SPEED_10;
> +			break;
> +		case SPEED_100:
> +			reg |= AN8855_PMCR_FORCE_SPEED_100;
> +			break;
> +		case SPEED_1000:
> +			reg |= AN8855_PMCR_FORCE_SPEED_1000;
> +			break;
> +		case SPEED_2500:
> +			reg |= AN8855_PMCR_FORCE_SPEED_2500;
> +			break;
> +		case SPEED_5000:
> +			reg |= AN8855_PMCR_FORCE_SPEED_5000;
> +			break;

There's no mention of any mode that can give support for the 5000Mbps
speed, is it a leftover from previous work on the driver ?

> +		}
> +
> +		reg &= ~AN8855_PMCR_FORCE_FDX;
> +		if (duplex == DUPLEX_FULL)
> +			reg |= AN8855_PMCR_FORCE_FDX;
> +
> +		reg &= ~AN8855_PMCR_RX_FC_EN;
> +		if (rx_pause || dsa_port_is_cpu(dp))
> +			reg |= AN8855_PMCR_RX_FC_EN;
> +
> +		reg &= ~AN8855_PMCR_TX_FC_EN;
> +		if (rx_pause || dsa_port_is_cpu(dp))
> +			reg |= AN8855_PMCR_TX_FC_EN;
> +
> +		/* Disable any EEE options */
> +		reg &= ~(AN8855_PMCR_FORCE_EEE5G | AN8855_PMCR_FORCE_EEE2P5G |
> +			 AN8855_PMCR_FORCE_EEE1G | AN8855_PMCR_FORCE_EEE100);
> +	}
> +
> +	reg |= AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN;
> +
> +	regmap_write(priv->regmap, AN8855_PMCR_P(port), reg);
> +}
> +
> +static void an8855_pcs_get_state(struct phylink_pcs *pcs,
> +				 struct phylink_link_state *state)
> +{
> +	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
> +	u32 val;
> +	int ret;
> +
> +	ret = regmap_read(priv->regmap, AN8855_PMSR_P(AN8855_CPU_PORT), &val);
> +	if (ret < 0) {
> +		state->link = false;
> +		return;
> +	}
> +
> +	state->link = !!(val & AN8855_PMSR_LNK);
> +	state->an_complete = state->link;
> +	state->duplex = (val & AN8855_PMSR_DPX) ? DUPLEX_FULL :
> +						  DUPLEX_HALF;
> +
> +	switch (val & AN8855_PMSR_SPEED) {
> +	case AN8855_PMSR_SPEED_10:
> +		state->speed = SPEED_10;
> +		break;
> +	case AN8855_PMSR_SPEED_100:
> +		state->speed = SPEED_100;
> +		break;
> +	case AN8855_PMSR_SPEED_1000:
> +		state->speed = SPEED_1000;
> +		break;
> +	case AN8855_PMSR_SPEED_2500:
> +		state->speed = SPEED_2500;
> +		break;
> +	case AN8855_PMSR_SPEED_5000:
> +		state->speed = SPEED_5000;

Same here for the SPEED_5000, unless i'm missing something :)

Thanks,

Maxime


From yangyicong at huawei.com  Wed Dec  4 01:13:10 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 4 Dec 2024 17:13:10 +0800
Subject: [PATCH 2/5] arm64: Add support for FEAT_{LS64, LS64_V,
 LS64_ACCDATA}
In-Reply-To: <87mshdrtrr.wl-maz@kernel.org>
References: <20241202135504.14252-1-yangyicong@huawei.com>
 <20241202135504.14252-3-yangyicong@huawei.com> <87mshdrtrr.wl-maz@kernel.org>
Message-ID: <01b65d7a-19ae-d26a-845c-4b47c82bd6e8@huawei.com>

On 2024/12/3 17:38, Marc Zyngier wrote:
> On Mon, 02 Dec 2024 13:55:01 +0000,
> Yicong Yang <yangyicong at huawei.com> wrote:
>>
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> Armv8.7 introduces single-copy atomic 64-byte loads and stores
>> instructions and its variants named under FEAT_{LS64, LS64_V,
>> LS64_ACCDATA}. These features are identified by ID_AA64ISAR1_EL1.LS64
>> and the use of such instructions in userspace (EL0) can be trapped.
>> In order to support the use of corresponding instructions in userspace:
>> - Make ID_AA64ISAR1_EL1.LS64 visbile to userspace
>> - Add identifying and enabling in the cpufeature list
>> - Expose these support of these features to userspace through HWCAP
>>   and cpuinfo
>>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> ---
>>  Documentation/arch/arm64/booting.rst    | 28 ++++++++++
>>  Documentation/arch/arm64/elf_hwcaps.rst |  9 ++++
>>  arch/arm64/include/asm/hwcap.h          |  3 ++
>>  arch/arm64/include/uapi/asm/hwcap.h     |  3 ++
>>  arch/arm64/kernel/cpufeature.c          | 70 ++++++++++++++++++++++++-
>>  arch/arm64/kernel/cpuinfo.c             |  3 ++
>>  arch/arm64/tools/cpucaps                |  3 ++
>>  7 files changed, 118 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
>> index 3278fb4bf219..c35cfe9da501 100644
>> --- a/Documentation/arch/arm64/booting.rst
>> +++ b/Documentation/arch/arm64/booting.rst
>> @@ -449,6 +449,34 @@ Before jumping into the kernel, the following conditions must be met:
>>  
>>      - HFGWTR_EL2.nGCS_EL0 (bit 52) must be initialised to 0b1.
>>  
>> +  For CPUs support for 64-byte loads and stores without status (FEAT_LS64):
>> +
>> +  - If the kernel is entered at EL1 and EL2 is present:
>> +
>> +    - HCRX_EL2.EnALS (bit 1) must be initialised to 0b1.
>> +
>> +  For CPUs support for 64-byte loads and stores with status (FEAT_LS64_V):
>> +
>> +  - If the kernel is entered at EL1 and EL2 is present:
>> +
>> +    - HCRX_EL2.EnASR (bit 2) must be initialised to 0b1.
>> +
>> +  For CPUs support for 64-byte EL0 stores with status (FEAT_LS64_ACCDATA):
>> +
>> +  - If EL3 is present:
>> +
>> +    - SCR_EL3.EnAS0 (bit 36) must be initialised to 0b1.
>> +
>> +    - SCR_EL3.ADEn (bit 37) must be initialised to 0b1.
>> +
>> +  - If the kernel is entered at EL1 and EL2 is present:
>> +
>> +    - HCRX_EL2.EnAS0 (bit 0) must be initialised to 0b1.
>> +
>> +    - HFGRTR_EL2.nACCDATA_EL1 (bit 50) must be initialised to 0b1.
>> +
>> +    - HFGWTR_EL2.nACCDATA_EL1 (bit 50) 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
>> diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst
>> index 2ff922a406ad..6cb2594f0803 100644
>> --- a/Documentation/arch/arm64/elf_hwcaps.rst
>> +++ b/Documentation/arch/arm64/elf_hwcaps.rst
>> @@ -372,6 +372,15 @@ HWCAP2_SME_SF8DP4
>>  HWCAP2_POE
>>      Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001.
>>  
>> +HWCAP3_LS64
>> +    Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0001.
>> +
>> +HWCAP3_LS64_V
>> +    Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0010.
>> +
>> +HWCAP3_LS64_ACCDATA
>> +    Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0011.
>> +
> 
> I don't mind the two others, but I seriously question exposing ST64BV0
> to userspace. How is ACCDATA_EL1 populated? How is it context-switched?
> 
> As it stands, this either does the wrong thing by always having the
> low 32bit set to an UNKNOWN value, or actively leaks kernel data.
> TBH, I don't see it being usable in practice (the more I read this
> part of the architecture, the more broken it looks).
> 

you're right, expose this LS64_ACCDATA alone to userspace won't make it
usable since ACCDATA_EL1 cannot be accessed from EL0. will drop this at
this stage.

Thanks.



From ansuelsmth at gmail.com  Wed Dec  4 01:14:31 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Wed, 4 Dec 2024 10:14:31 +0100
Subject: [net-next PATCH v8 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241204100922.0af25d7e@fedora.home>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
 <20241204072427.17778-4-ansuelsmth@gmail.com>
 <20241204100922.0af25d7e@fedora.home>
Message-ID: <67501d7b.050a0220.3390ac.353c@mx.google.com>

On Wed, Dec 04, 2024 at 10:09:22AM +0100, Maxime Chevallier wrote:
> Hello Christian,
> 
> On Wed,  4 Dec 2024 08:24:10 +0100
> Christian Marangi <ansuelsmth at gmail.com> wrote:
> 
> > Add Airoha AN8855 5-Port Gigabit DSA switch.
> > 
> > The switch is also a nvmem-provider as it does have EFUSE to calibrate
> > the internal PHYs.
> > 
> > Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> 
> [...]
> 
> My two-cents review below :)
> 
> > +static void
> > +an8855_phylink_mac_config(struct phylink_config *config, unsigned int mode,
> > +			  const struct phylink_link_state *state)
> > +{
> > +	struct dsa_port *dp = dsa_phylink_to_port(config);
> > +	struct dsa_switch *ds = dp->ds;
> > +	struct an8855_priv *priv;
> > +	int port = dp->index;
> > +
> > +	priv = ds->priv;
> > +
> > +	if (port != 5) {
> > +		if (port > 5)
> > +			dev_err(ds->dev, "unsupported port: %d", port);
> > +		return;
> > +	}
> 
> Looks like the above condition can be simplified to :
> 
> 	if (port > 5)
> 		dev_err(...);
> 
>

Well.... yep AHHAHA.

> > +
> > +	regmap_update_bits(priv->regmap, AN8855_PMCR_P(port),
> > +			   AN8855_PMCR_IFG_XMIT | AN8855_PMCR_MAC_MODE |
> > +			   AN8855_PMCR_BACKOFF_EN | AN8855_PMCR_BACKPR_EN,
> > +			   FIELD_PREP(AN8855_PMCR_IFG_XMIT, 0x1) |
> > +			   AN8855_PMCR_MAC_MODE | AN8855_PMCR_BACKOFF_EN |
> > +			   AN8855_PMCR_BACKPR_EN);
> > +}
> > +
> > +static void an8855_phylink_get_caps(struct dsa_switch *ds, int port,
> > +				    struct phylink_config *config)
> > +{
> > +	switch (port) {
> > +	case 0:
> > +	case 1:
> > +	case 2:
> > +	case 3:
> > +	case 4:
> > +		__set_bit(PHY_INTERFACE_MODE_GMII,
> > +			  config->supported_interfaces);
> > +		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
> > +			  config->supported_interfaces);
> > +		break;
> > +	case 5:
> > +		phy_interface_set_rgmii(config->supported_interfaces);
> > +		__set_bit(PHY_INTERFACE_MODE_SGMII,
> > +			  config->supported_interfaces);
> > +		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
> > +			  config->supported_interfaces);
> > +		break;
> > +	}
> > +
> > +	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
> > +				   MAC_10 | MAC_100 | MAC_1000FD;
> 
> For port 5, you may also add the MAC_2500FD capability as it supports
> 2500BASEX ?
> 

I didn't account for the CPU port that runs at 2.5. The LAN port are
only 1g. Will add or maybe add the 2500FD only for cpu port?

Maybe Russel can help in this?

> > +}
> > +
> 
> [...]
> 
> > +
> > +static void
> > +an8855_phylink_mac_link_up(struct phylink_config *config,
> > +			   struct phy_device *phydev, unsigned int mode,
> > +			   phy_interface_t interface, int speed, int duplex,
> > +			   bool tx_pause, bool rx_pause)
> > +{
> > +	struct dsa_port *dp = dsa_phylink_to_port(config);
> > +	struct an8855_priv *priv = dp->ds->priv;
> > +	int port = dp->index;
> > +	u32 reg;
> > +
> > +	reg = regmap_read(priv->regmap, AN8855_PMCR_P(port), &reg);
> > +	if (phylink_autoneg_inband(mode)) {
> > +		reg &= ~AN8855_PMCR_FORCE_MODE;
> > +	} else {
> > +		reg |= AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK;
> > +
> > +		reg &= ~AN8855_PMCR_FORCE_SPEED;
> > +		switch (speed) {
> > +		case SPEED_10:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_10;
> > +			break;
> > +		case SPEED_100:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_100;
> > +			break;
> > +		case SPEED_1000:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_1000;
> > +			break;
> > +		case SPEED_2500:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_2500;
> > +			break;
> > +		case SPEED_5000:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_5000;
> > +			break;
> 
> There's no mention of any mode that can give support for the 5000Mbps
> speed, is it a leftover from previous work on the driver ?
> 

Added 5000 as this is present in documentation bits but CPU can only go
up to 2.5. Should I drop it? Idea was to futureproof it since it really
seems they added these bits with the intention of having a newer switch
with more advanced ports.

> > +		}
> > +
> > +		reg &= ~AN8855_PMCR_FORCE_FDX;
> > +		if (duplex == DUPLEX_FULL)
> > +			reg |= AN8855_PMCR_FORCE_FDX;
> > +
> > +		reg &= ~AN8855_PMCR_RX_FC_EN;
> > +		if (rx_pause || dsa_port_is_cpu(dp))
> > +			reg |= AN8855_PMCR_RX_FC_EN;
> > +
> > +		reg &= ~AN8855_PMCR_TX_FC_EN;
> > +		if (rx_pause || dsa_port_is_cpu(dp))
> > +			reg |= AN8855_PMCR_TX_FC_EN;
> > +
> > +		/* Disable any EEE options */
> > +		reg &= ~(AN8855_PMCR_FORCE_EEE5G | AN8855_PMCR_FORCE_EEE2P5G |
> > +			 AN8855_PMCR_FORCE_EEE1G | AN8855_PMCR_FORCE_EEE100);
> > +	}
> > +
> > +	reg |= AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN;
> > +
> > +	regmap_write(priv->regmap, AN8855_PMCR_P(port), reg);
> > +}
> > +
> > +static void an8855_pcs_get_state(struct phylink_pcs *pcs,
> > +				 struct phylink_link_state *state)
> > +{
> > +	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
> > +	u32 val;
> > +	int ret;
> > +
> > +	ret = regmap_read(priv->regmap, AN8855_PMSR_P(AN8855_CPU_PORT), &val);
> > +	if (ret < 0) {
> > +		state->link = false;
> > +		return;
> > +	}
> > +
> > +	state->link = !!(val & AN8855_PMSR_LNK);
> > +	state->an_complete = state->link;
> > +	state->duplex = (val & AN8855_PMSR_DPX) ? DUPLEX_FULL :
> > +						  DUPLEX_HALF;
> > +
> > +	switch (val & AN8855_PMSR_SPEED) {
> > +	case AN8855_PMSR_SPEED_10:
> > +		state->speed = SPEED_10;
> > +		break;
> > +	case AN8855_PMSR_SPEED_100:
> > +		state->speed = SPEED_100;
> > +		break;
> > +	case AN8855_PMSR_SPEED_1000:
> > +		state->speed = SPEED_1000;
> > +		break;
> > +	case AN8855_PMSR_SPEED_2500:
> > +		state->speed = SPEED_2500;
> > +		break;
> > +	case AN8855_PMSR_SPEED_5000:
> > +		state->speed = SPEED_5000;
> 
> Same here for the SPEED_5000, unless i'm missing something :)
>

Ditto same explaination above.

-- 
	Ansuel


From linux at armlinux.org.uk  Wed Dec  4 01:21:55 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Dec 2024 09:21:55 +0000
Subject: [net-next PATCH v8 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241204100922.0af25d7e@fedora.home>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
 <20241204072427.17778-4-ansuelsmth@gmail.com>
 <20241204100922.0af25d7e@fedora.home>
Message-ID: <Z1AfM5PzlTN19hF3@shell.armlinux.org.uk>

On Wed, Dec 04, 2024 at 10:09:22AM +0100, Maxime Chevallier wrote:
> Hello Christian,
> 
> On Wed,  4 Dec 2024 08:24:10 +0100
> Christian Marangi <ansuelsmth at gmail.com> wrote:
> 
> > +static void
> > +an8855_phylink_mac_config(struct phylink_config *config, unsigned int mode,
> > +			  const struct phylink_link_state *state)
> > +{
> > +	struct dsa_port *dp = dsa_phylink_to_port(config);
> > +	struct dsa_switch *ds = dp->ds;
> > +	struct an8855_priv *priv;
> > +	int port = dp->index;
> > +
> > +	priv = ds->priv;
> > +
> > +	if (port != 5) {
> > +		if (port > 5)
> > +			dev_err(ds->dev, "unsupported port: %d", port);
> > +		return;
> > +	}
> 
> Looks like the above condition can be simplified to :
> 
> 	if (port > 5)
> 		dev_err(...);

Not quite, since if port is 0..4, the function returns at this point.
If >5, then it prints an error and returns. So:

	if (port > 5)
		dev_err(...);
	if (port != 5)
		return;

However, net/dsa/dsa.c::dsa_switch_parse_ports_of() already validates
that the port number will not exceed ds->num_ports, so if that is set
appropriately, the phylink functions will never be called with a port
number larger than this, and checking it is redundant.

So I think this should just be:

	if (port != 5)
		return;

> > +	case 5:
> > +		phy_interface_set_rgmii(config->supported_interfaces);
> > +		__set_bit(PHY_INTERFACE_MODE_SGMII,
> > +			  config->supported_interfaces);
> > +		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
> > +			  config->supported_interfaces);
> > +		break;
> > +	}
> > +
> > +	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
> > +				   MAC_10 | MAC_100 | MAC_1000FD;
> 
> For port 5, you may also add the MAC_2500FD capability as it supports
> 2500BASEX ?

Agreed, that's needed.

> > +		case SPEED_5000:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_5000;
> > +			break;
> 
> There's no mention of any mode that can give support for the 5000Mbps
> speed, is it a leftover from previous work on the driver ?

Or maybe it's because 5GBASE-R wasn't a phy interface type when the
driver was originally developed (iirc it's a relatively recent
addition.)

-- 
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 Dec  4 01:24:45 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Dec 2024 09:24:45 +0000
Subject: [net-next PATCH v8 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <67501d7b.050a0220.3390ac.353c@mx.google.com>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
 <20241204072427.17778-4-ansuelsmth@gmail.com>
 <20241204100922.0af25d7e@fedora.home>
 <67501d7b.050a0220.3390ac.353c@mx.google.com>
Message-ID: <Z1Af3YaN3xjq_Gtb@shell.armlinux.org.uk>

On Wed, Dec 04, 2024 at 10:14:31AM +0100, Christian Marangi wrote:
> On Wed, Dec 04, 2024 at 10:09:22AM +0100, Maxime Chevallier wrote:
> > > +	case 5:
> > > +		phy_interface_set_rgmii(config->supported_interfaces);
> > > +		__set_bit(PHY_INTERFACE_MODE_SGMII,
> > > +			  config->supported_interfaces);
> > > +		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
> > > +			  config->supported_interfaces);
> > > +		break;
> > > +	}
> > > +
> > > +	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
> > > +				   MAC_10 | MAC_100 | MAC_1000FD;
> > 
> > For port 5, you may also add the MAC_2500FD capability as it supports
> > 2500BASEX ?
> > 
> 
> I didn't account for the CPU port that runs at 2.5. The LAN port are
> only 1g. Will add or maybe add the 2500FD only for cpu port?
> 
> Maybe Russel can help in this?

*ll* please.

Well, 2500BASE-X runs at 2.5G, so if MAC_2500FD isn't set in the mask,
validation will fail for 2500BASE-X.

> > > +		case SPEED_5000:
> > > +			reg |= AN8855_PMCR_FORCE_SPEED_5000;
> > > +			break;
> > 
> > There's no mention of any mode that can give support for the 5000Mbps
> > speed, is it a leftover from previous work on the driver ?
> > 
> 
> Added 5000 as this is present in documentation bits but CPU can only go
> up to 2.5. Should I drop it? Idea was to futureproof it since it really
> seems they added these bits with the intention of having a newer switch
> with more advanced ports.

Is there any mention of supporting interfaces faster than 2500BASE-X ?

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


From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:02 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:02 +0200
Subject: [PATCH 02/10] drm/fourcc: Add DRM_FORMAT_XV15/XV20
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-2-0bf2c5147db1@ideasonboard.com>

Add two new pixel formats:

DRM_FORMAT_XV15 ("XV15")
DRM_FORMAT_XV20 ("XV20")

The formats are 2 plane 10 bit per component YCbCr, with the XV15 2x2
subsampled whereas XV20 is 2x1 subsampled.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/drm_fourcc.c  | 8 ++++++++
 include/uapi/drm/drm_fourcc.h | 8 ++++++++
 2 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index e84c4ed6928c..adb2d44630ee 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -318,6 +318,14 @@ const struct drm_format_info *__drm_format_info(u32 format)
 		{ .format = DRM_FORMAT_P030,            .depth = 0,  .num_planes = 2,
 		  .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
 		  .hsub = 2, .vsub = 2, .is_yuv = true},
+		{ .format = DRM_FORMAT_XV15,		.depth = 0,
+		  .num_planes = 2, .char_per_block = { 4, 8, 0 },
+		  .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
+		  .vsub = 2, .is_yuv = true },
+		{ .format = DRM_FORMAT_XV20,		.depth = 0,
+		  .num_planes = 2, .char_per_block = { 4, 8, 0 },
+		  .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
+		  .vsub = 1, .is_yuv = true },
 	};
 
 	unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 78abd819fd62..2a00adcfb1ff 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -304,6 +304,14 @@ extern "C" {
 #define DRM_FORMAT_RGB565_A8	fourcc_code('R', '5', 'A', '8')
 #define DRM_FORMAT_BGR565_A8	fourcc_code('B', '5', 'A', '8')
 
+/*
+ * 2 plane 10 bit per component YCrCb
+ * index 0 = Y plane, [31:0] x:Y2:Y1:Y0 2:10:10:10 little endian
+ * index 1 = Cb:Cr plane, [63:0] x:Cr2:Cb2:Cr1:x:Cb1:Cr0:Cb0 2:10:10:10:2:10:10:10 little endian
+ */
+#define DRM_FORMAT_XV15		fourcc_code('X', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane 2:10:10:10 */
+#define DRM_FORMAT_XV20		fourcc_code('X', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane 2:10:10:10 */
+
 /*
  * 2 plane YCbCr
  * index 0 = Y plane, [7:0] Y

-- 
2.43.0



From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:04 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:04 +0200
Subject: [PATCH 04/10] drm/fourcc: Add DRM_FORMAT_Y10_LE32
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-4-0bf2c5147db1@ideasonboard.com>

Add Y10_LE32, a 10 bit greyscale format, with 3 pixels packed into
32-bit container.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/drm_fourcc.c  | 4 ++++
 include/uapi/drm/drm_fourcc.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index d721d9fdbe98..6048e0a191dc 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -327,6 +327,10 @@ const struct drm_format_info *__drm_format_info(u32 format)
 		  .num_planes = 2, .char_per_block = { 4, 8, 0 },
 		  .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
 		  .vsub = 1, .is_yuv = true },
+		{ .format = DRM_FORMAT_Y10_LE32,        .depth = 0,
+		  .num_planes = 1, .char_per_block =  { 4, 0, 0 },
+		  .block_w = { 3, 0, 0 }, .block_h = { 1, 0, 0 }, .hsub = 1,
+		  .vsub = 1, .is_yuv = true },
 	};
 
 	unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index f79ee3b93f09..82f255eb3d1b 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -408,6 +408,7 @@ extern "C" {
 /* Greyscale formats */
 
 #define DRM_FORMAT_Y8		fourcc_code('G', 'R', 'E', 'Y')  /* 8-bit Y-only */
+#define DRM_FORMAT_Y10_LE32	fourcc_code('Y', '1', '0', 'P')  /* [31:0] x:Y2:Y1:Y0 2:10:10:10 little endian */
 
 /*
  * Format Modifiers:

-- 
2.43.0



From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:07 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:07 +0200
Subject: [PATCH 07/10] drm: xlnx: zynqmp: Add support for XV15 & XV20
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-7-0bf2c5147db1@ideasonboard.com>

Add support for XV15 & XV20 formats.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/xlnx/zynqmp_disp.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 57221575cbd6..3998754e367e 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -299,6 +299,16 @@ static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
 		.swap		= true,
 		.sf		= scaling_factors_888,
+	}, {
+		.drm_fmt	= DRM_FORMAT_XV15,
+		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420_10,
+		.swap		= false,
+		.sf		= scaling_factors_101010,
+	}, {
+		.drm_fmt	= DRM_FORMAT_XV20,
+		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_10,
+		.swap		= false,
+		.sf		= scaling_factors_101010,
 	},
 };
 

-- 
2.43.0



From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:06 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:06 +0200
Subject: [PATCH 06/10] drm: xlnx: zynqmp: Use drm helpers when calculating
 buffer sizes
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-6-0bf2c5147db1@ideasonboard.com>

Use drm helpers, drm_format_info_plane_width(),
drm_format_info_plane_height() and drm_format_info_min_pitch() to
calculate sizes for the DMA.

This cleans up the code, but also makes it possible to support more
complex formats (like XV15, XV20).

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/xlnx/zynqmp_disp.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 9368acf56eaf..57221575cbd6 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -1154,16 +1154,18 @@ int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
 		return 0;
 
 	for (i = 0; i < info->num_planes; i++) {
-		unsigned int width = state->crtc_w / (i ? info->hsub : 1);
-		unsigned int height = state->crtc_h / (i ? info->vsub : 1);
 		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
 		struct dma_async_tx_descriptor *desc;
+		unsigned int width, height;
 		dma_addr_t dma_addr;
 
+		width = drm_format_info_plane_width(info, state->crtc_w, i);
+		height = drm_format_info_plane_height(info, state->crtc_h, i);
+
 		dma_addr = drm_fb_dma_get_gem_addr(state->fb, state, i);
 
 		dma->xt.numf = height;
-		dma->sgl.size = width * info->cpp[i];
+		dma->sgl.size = drm_format_info_min_pitch(info, i, width);
 		dma->sgl.icg = state->fb->pitches[i] - dma->sgl.size;
 		dma->xt.src_start = dma_addr;
 		dma->xt.frame_size = 1;

-- 
2.43.0



From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:05 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:05 +0200
Subject: [PATCH 05/10] drm/fourcc: Add DRM_FORMAT_X403
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-5-0bf2c5147db1@ideasonboard.com>

Add X403, a 3 plane non-subsampled YCbCr format.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/drm_fourcc.c  | 4 ++++
 include/uapi/drm/drm_fourcc.h | 8 ++++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 6048e0a191dc..219113b5924c 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -331,6 +331,10 @@ const struct drm_format_info *__drm_format_info(u32 format)
 		  .num_planes = 1, .char_per_block =  { 4, 0, 0 },
 		  .block_w = { 3, 0, 0 }, .block_h = { 1, 0, 0 }, .hsub = 1,
 		  .vsub = 1, .is_yuv = true },
+		{ .format = DRM_FORMAT_X403,		.depth = 0,
+		  .num_planes = 3, .char_per_block =  { 4, 4, 4 },
+		  .block_w = { 3, 3, 3 }, .block_h = { 1, 1, 1 },
+		  .hsub = 1, .vsub = 1, .is_yuv = true },
 	};
 
 	unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 82f255eb3d1b..097904407617 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -385,6 +385,14 @@ extern "C" {
  */
 #define DRM_FORMAT_Q401		fourcc_code('Q', '4', '0', '1')
 
+/* 3 plane non-subsampled (444) YCbCr
+ * 10 bpc, 30 bits per sample image data in a single contiguous buffer.
+ * index 0: Y plane,  [31:0] x:Y2:Y1:Y0    [2:10:10:10] little endian
+ * index 1: Cb plane, [31:0] x:Cb2:Cb1:Cb0 [2:10:10:10] little endian
+ * index 2: Cr plane, [31:0] x:Cr2:Cr1:Cr0 [2:10:10:10] little endian
+ */
+#define DRM_FORMAT_X403		fourcc_code('X', '4', '0', '3')
+
 /*
  * 3 plane YCbCr
  * index 0: Y plane, [7:0] Y

-- 
2.43.0



From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:08 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:08 +0200
Subject: [PATCH 08/10] drm: xlnx: zynqmp: Add support for Y8 and Y10_LE32
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-8-0bf2c5147db1@ideasonboard.com>

Add support for Y8 and Y10_LE32 formats. We also need to add new csc
matrices for the y-only formats.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/xlnx/zynqmp_disp.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 3998754e367e..44cfee6a0e32 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -309,6 +309,16 @@ static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_10,
 		.swap		= false,
 		.sf		= scaling_factors_101010,
+	}, {
+		.drm_fmt	= DRM_FORMAT_Y8,
+		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MONO,
+		.swap		= false,
+		.sf		= scaling_factors_888,
+	}, {
+		.drm_fmt	= DRM_FORMAT_Y10_LE32,
+		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YONLY_10,
+		.swap		= false,
+		.sf		= scaling_factors_101010,
 	},
 };
 
@@ -699,6 +709,16 @@ static const u32 csc_sdtv_to_rgb_offsets[] = {
 	0x0, 0x1800, 0x1800
 };
 
+static const u16 csc_sdtv_to_rgb_yonly_matrix[] = {
+	0x0, 0x0, 0x1000,
+	0x0, 0x0, 0x1000,
+	0x0, 0x0, 0x1000,
+};
+
+static const u32 csc_sdtv_to_rgb_yonly_offsets[] = {
+	0x1800, 0x1800, 0x0
+};
+
 /**
  * zynqmp_disp_blend_set_output_format - Set the output format of the blender
  * @disp: Display controller
@@ -848,7 +868,11 @@ static void zynqmp_disp_blend_layer_enable(struct zynqmp_disp *disp,
 				ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id),
 				val);
 
-	if (layer->drm_fmt->is_yuv) {
+	if (layer->drm_fmt->format == DRM_FORMAT_Y8 ||
+	    layer->drm_fmt->format == DRM_FORMAT_Y10_LE32) {
+		coeffs = csc_sdtv_to_rgb_yonly_matrix;
+		offsets = csc_sdtv_to_rgb_yonly_offsets;
+	} else if (layer->drm_fmt->is_yuv) {
 		coeffs = csc_sdtv_to_rgb_matrix;
 		offsets = csc_sdtv_to_rgb_offsets;
 	} else {

-- 
2.43.0



From fnkl.kernel at gmail.com  Wed Dec  4 01:28:48 2024
From: fnkl.kernel at gmail.com (Sasha Finkelstein)
Date: Wed, 4 Dec 2024 10:28:48 +0100
Subject: [PATCH v2 2/4] input: apple_z2: Add a driver for Apple Z2 touchscreens
In-Reply-To: <Z0-PRapfiAUGvr4W@google.com>
References: <20241128-z2-v2-0-76cc59bbf117@gmail.com> <20241128-z2-v2-2-76cc59bbf117@gmail.com>
 <Z0-PRapfiAUGvr4W@google.com>
Message-ID: <CAMT+MTQ3M1gfz5aLWd17R-RODJi-wnxKJvf9zoX+TjoZMKjCKA@mail.gmail.com>

On Wed, 4 Dec 2024 at 00:07, Dmitry Torokhov <dmitry.torokhov at gmail.com> wrote:
> > +     z2->counter = 1 - z2->counter;
>
> Is this toggling between 1 and 0? Should it be "counter = !counter"? And
> is there better name than counter?

message_index_parity? Kind of a mouthful.

> > +     .remove   = apple_z2_shutdown,
>
> Purring the device into reset state before tearing down interrupt
> handler, etc, may lead to weird errors. Why do you need to do this on
> removal instead of letting devm tear down the device?

The interrupt is masked before putting the device into reset,
and i do need to put it into reset when removing it.


From wenst at chromium.org  Wed Dec  4 01:28:51 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed,  4 Dec 2024 17:28:51 +0800
Subject: [PATCH 0/2] mmc: mtk-sd: Limit second register range to SoCs requiring it
Message-ID: <20241204092855.1365638-1-wenst@chromium.org>

Currently the usage of a second register range for MediaTek's MMC
controller is seen only on a few platforms. However the driver tries
to grab the register base regardless, and then ignores any errors.
This makes all the other platforms that don't need it produce confusing
error messages.

Instead, make the driver only grab the register range for platforms that
actually require it, and correctly handle the error. Also fix up the
binding so that validation of the "reg" property is as strict as
possible.

Please take a look.


Thanks
ChenYu

Chen-Yu Tsai (2):
  dt-bindings: mmc: mtk-sd: Document compatibles that need two register
    ranges
  mmc: mtk-sd: Limit getting top_base to SoCs that require it

 Documentation/devicetree/bindings/mmc/mtk-sd.yaml |  9 ++++++++-
 drivers/mmc/host/mtk-sd.c                         | 15 +++++++++++----
 2 files changed, 19 insertions(+), 5 deletions(-)

-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Wed Dec  4 01:28:52 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed,  4 Dec 2024 17:28:52 +0800
Subject: [PATCH 1/2] dt-bindings: mmc: mtk-sd: Document compatibles that need two register ranges
In-Reply-To: <20241204092855.1365638-1-wenst@chromium.org>
References: <20241204092855.1365638-1-wenst@chromium.org>
Message-ID: <20241204092855.1365638-2-wenst@chromium.org>

Besides the MT8183's MMC controller and all its compatible derivatives,
the recently added MT7986 and MT8196 also require two register ranges.
This is based on the actual device trees.

Properly enforce this in the binding.

Fixes: 4a8bd2b07d88 ("dt-bindings: mmc: mtk-sd: Add mt7988 SoC")
Fixes: 58927c9dc4ab ("dt-bindings: mmc: mtk-sd: Add support for MT8196")
Cc: Frank Wunderlich <frank-w at public-files.de>
Cc: Andy-ld Lu <andy-ld.lu at mediatek.com>
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
index f86ebd81f5a5..9ea035928563 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
@@ -235,11 +235,18 @@ allOf:
       properties:
         compatible:
           contains:
-            const: mediatek,mt8183-mmc
+            enum:
+              - mediatek,mt7986-mmc
+              - mediatek,mt8183-mmc
+              - mediatek,mt8196-mmc
     then:
       properties:
         reg:
           minItems: 2
+    else:
+      properties:
+        reg:
+          maxItems: 1
 
   - if:
       properties:
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Wed Dec  4 01:28:53 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed,  4 Dec 2024 17:28:53 +0800
Subject: [PATCH 2/2] mmc: mtk-sd: Limit getting top_base to SoCs that require it
In-Reply-To: <20241204092855.1365638-1-wenst@chromium.org>
References: <20241204092855.1365638-1-wenst@chromium.org>
Message-ID: <20241204092855.1365638-3-wenst@chromium.org>

Currently the mtk-sd driver tries to get and map the second register
base, named top_base in the code, regardless of whether the SoC model
actually has it or not. This produces confusing big error messages on
the platforms that don't need it:

    mtk-msdc 11260000.mmc: error -EINVAL: invalid resource (null)

Limit it to the platforms that actually require it, based on their
device tree entries, and properly fail if it is missing. There is
no MMC node in the MT6779 dts, so it's currently unknown if that
platform needs it or not.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/mmc/host/mtk-sd.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index e2c385853eef..1bb7044f4ca1 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -414,6 +414,7 @@ struct mtk_mmc_compatible {
 	u8 clk_div_bits;
 	bool recheck_sdio_irq;
 	bool hs400_tune; /* only used for MT8173 */
+	bool needs_top_base;
 	u32 pad_tune_reg;
 	bool async_fifo;
 	bool data_tune;
@@ -587,6 +588,7 @@ static const struct mtk_mmc_compatible mt7986_compat = {
 	.clk_div_bits = 12,
 	.recheck_sdio_irq = true,
 	.hs400_tune = false,
+	.needs_top_base = true,
 	.pad_tune_reg = MSDC_PAD_TUNE0,
 	.async_fifo = true,
 	.data_tune = true,
@@ -627,6 +629,7 @@ static const struct mtk_mmc_compatible mt8183_compat = {
 	.clk_div_bits = 12,
 	.recheck_sdio_irq = false,
 	.hs400_tune = false,
+	.needs_top_base = true,
 	.pad_tune_reg = MSDC_PAD_TUNE0,
 	.async_fifo = true,
 	.data_tune = true,
@@ -653,6 +656,7 @@ static const struct mtk_mmc_compatible mt8196_compat = {
 	.clk_div_bits = 12,
 	.recheck_sdio_irq = false,
 	.hs400_tune = false,
+	.needs_top_base = true,
 	.pad_tune_reg = MSDC_PAD_TUNE0,
 	.async_fifo = true,
 	.data_tune = true,
@@ -2887,9 +2891,13 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	if (IS_ERR(host->base))
 		return PTR_ERR(host->base);
 
-	host->top_base = devm_platform_ioremap_resource(pdev, 1);
-	if (IS_ERR(host->top_base))
-		host->top_base = NULL;
+	host->dev_comp = of_device_get_match_data(&pdev->dev);
+
+	if (host->dev_comp->needs_top_base) {
+		host->top_base = devm_platform_ioremap_resource(pdev, 1);
+		if (IS_ERR(host->top_base))
+			return PTR_ERR(host->top_base);
+	}
 
 	ret = mmc_regulator_get_supply(mmc);
 	if (ret)
@@ -2951,7 +2959,6 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	msdc_of_property_parse(pdev, host);
 
 	host->dev = &pdev->dev;
-	host->dev_comp = of_device_get_match_data(&pdev->dev);
 	host->src_clk_freq = clk_get_rate(host->src_clk);
 	/* Set host parameters to mmc */
 	mmc->ops = &mt_msdc_ops;
-- 
2.47.0.338.g60cca15819-goog



From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:03 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:03 +0200
Subject: [PATCH 03/10] drm/fourcc: Add DRM_FORMAT_Y8
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-3-0bf2c5147db1@ideasonboard.com>

Add greyscale Y8 format.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/drm_fourcc.c  | 1 +
 include/uapi/drm/drm_fourcc.h | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index adb2d44630ee..d721d9fdbe98 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -239,6 +239,7 @@ const struct drm_format_info *__drm_format_info(u32 format)
 		{ .format = DRM_FORMAT_YVU422,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true },
 		{ .format = DRM_FORMAT_YUV444,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },
 		{ .format = DRM_FORMAT_YVU444,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+		{ .format = DRM_FORMAT_Y8,		.depth = 8,  .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
 		{ .format = DRM_FORMAT_NV12,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
 		{ .format = DRM_FORMAT_NV21,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
 		{ .format = DRM_FORMAT_NV16,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 2a00adcfb1ff..f79ee3b93f09 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -405,6 +405,9 @@ extern "C" {
 #define DRM_FORMAT_YUV444	fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
 #define DRM_FORMAT_YVU444	fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
 
+/* Greyscale formats */
+
+#define DRM_FORMAT_Y8		fourcc_code('G', 'R', 'E', 'Y')  /* 8-bit Y-only */
 
 /*
  * Format Modifiers:

-- 
2.43.0



From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:00 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:00 +0200
Subject: [PATCH 00/10] drm: Add new pixel formats for Xilinx Zynqmp
Message-ID: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>

Add new DRM pixel formats and add support for those in the Xilinx zynqmp
display driver.

All of these formats are already supported in upstream gstreamer, except
in the gstreamer kmssink, which obviously cannot support the formats
without kernel having the formats.

Xilinx has support for these formats in their BSP kernel, and Xilinx has
a branch here, adding the support to gstreamer kmssink:

https://github.com/Xilinx/gst-plugins-bad.git xlnx-rebase-v1.18.5

New formats added:

DRM_FORMAT_Y8
- 8-bit Y-only
- fourcc: "GREY"
- gstreamer: GRAY8

DRM_FORMAT_Y10_LE32
- 10-bit Y-only
- fourcc: "Y10P"
- gstreamer: GRAY10_LE32

DRM_FORMAT_XV15
- Like NV12, but with 10-bit components
- fourcc: "XV15"
- gstreamer: NV12_10LE32

DRM_FORMAT_XV20
- Like NV16, but with 10-bit components
- fourcc: "XV20"
- gstreamer: NV16_10LE32

DRM_FORMAT_X403
- 10-bit 4:4:4
- fourcc: "X403"
- gstreamer: Y444_10LE32

Some notes:

I know the 8-bit greyscale format has been discussed before, and the
guidance was to use DRM_FORMAT_R8. While I'm not totally against that, I
would argue that adding DRM_FORMAT_Y8 makes sense, as: 1) we can mark it
as 'is_yuv' in the drm_format_info, 2) we can have the same fourcc as in
v4l2, 3) it makes more sense for the user to use Y8/GREY format instead
of R8.

Also, if we go with DRM_FORMAT_R8, then I think it would make sense to
also add the 10-bit grayscale version as R10, instead of Y10, and it
would also have to have 'is_yuv' false, and I feel that would just
create even more confusion.

I have made some adjustments to the formats compared to the Xilinx's
branch. E.g. The DRM_FORMAT_Y10_LE32 format in Xilinx's kmssink uses
fourcc "Y10 ", and DRM_FORMAT_Y10. I didn't like those, as the format is
a packed format, three 10-bit pixels in a 32-bit container, and I think
Y10 means a 10-bit pixel in a 16-bit container.

Generally speaking, if someone has good ideas for the format define
names or fourccs, speak up, as it's not easy to invent good names =).
That said, keeping them the same as in the Xilinx trees will, of course,
be slightly easier for the users of Xilinx platforms.

There's also a bit unrelated path on top, fixing the missing max dma
seegment size in the zynqmp driver which I encountered while testing
these.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
Tomi Valkeinen (10):
      drm/fourcc: Add warning for bad bpp
      drm/fourcc: Add DRM_FORMAT_XV15/XV20
      drm/fourcc: Add DRM_FORMAT_Y8
      drm/fourcc: Add DRM_FORMAT_Y10_LE32
      drm/fourcc: Add DRM_FORMAT_X403
      drm: xlnx: zynqmp: Use drm helpers when calculating buffer sizes
      drm: xlnx: zynqmp: Add support for XV15 & XV20
      drm: xlnx: zynqmp: Add support for Y8 and Y10_LE32
      drm: xlnx: zynqmp: Add support for X403
      drm: xlnx: zynqmp: Fix max dma segment size

 drivers/gpu/drm/drm_fourcc.c        | 24 ++++++++++++++++++
 drivers/gpu/drm/xlnx/zynqmp_disp.c  | 49 ++++++++++++++++++++++++++++++++++---
 drivers/gpu/drm/xlnx/zynqmp_dpsub.c |  2 ++
 include/uapi/drm/drm_fourcc.h       | 20 +++++++++++++++
 4 files changed, 91 insertions(+), 4 deletions(-)
---
base-commit: adc218676eef25575469234709c2d87185ca223a
change-id: 20241120-xilinx-formats-f71901621833

Best regards,
-- 
Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>



From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:01 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:01 +0200
Subject: [PATCH 01/10] drm/fourcc: Add warning for bad bpp
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-1-0bf2c5147db1@ideasonboard.com>

drm_format_info_bpp() cannot be used for formats which do not have an
integer bits-per-pixel. Handle wrong calls by printing a warning and
returning 0.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/drm_fourcc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 193cf8ed7912..e84c4ed6928c 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -429,6 +429,13 @@ unsigned int drm_format_info_bpp(const struct drm_format_info *info, int plane)
 	if (!info || plane < 0 || plane >= info->num_planes)
 		return 0;
 
+	if (info->char_per_block[plane] * 8 %
+	    (drm_format_info_block_width(info, plane) *
+	     drm_format_info_block_height(info, plane))) {
+		pr_warn("unable to return an integer bpp\n");
+		return 0;
+	}
+
 	return info->char_per_block[plane] * 8 /
 	       (drm_format_info_block_width(info, plane) *
 		drm_format_info_block_height(info, plane));

-- 
2.43.0



From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:10 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:10 +0200
Subject: [PATCH 10/10] drm: xlnx: zynqmp: Fix max dma segment size
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-10-0bf2c5147db1@ideasonboard.com>

Fix "mapping sg segment longer than device claims to support" warning by
setting the max segment size.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/xlnx/zynqmp_dpsub.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
index f5781939de9c..a25b22238e3d 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
@@ -231,6 +231,8 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
+
 	/* Try the reserved memory. Proceed if there's none. */
 	of_reserved_mem_device_init(&pdev->dev);
 

-- 
2.43.0



From ansuelsmth at gmail.com  Wed Dec  4 01:33:33 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Wed, 4 Dec 2024 10:33:33 +0100
Subject: [net-next PATCH v8 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <Z1Af3YaN3xjq_Gtb@shell.armlinux.org.uk>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
 <20241204072427.17778-4-ansuelsmth@gmail.com>
 <20241204100922.0af25d7e@fedora.home>
 <67501d7b.050a0220.3390ac.353c@mx.google.com>
 <Z1Af3YaN3xjq_Gtb@shell.armlinux.org.uk>
Message-ID: <675021f1.050a0220.34c00a.3a0c@mx.google.com>

On Wed, Dec 04, 2024 at 09:24:45AM +0000, Russell King (Oracle) wrote:
> On Wed, Dec 04, 2024 at 10:14:31AM +0100, Christian Marangi wrote:
> > On Wed, Dec 04, 2024 at 10:09:22AM +0100, Maxime Chevallier wrote:
> > > > +	case 5:
> > > > +		phy_interface_set_rgmii(config->supported_interfaces);
> > > > +		__set_bit(PHY_INTERFACE_MODE_SGMII,
> > > > +			  config->supported_interfaces);
> > > > +		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
> > > > +			  config->supported_interfaces);
> > > > +		break;
> > > > +	}
> > > > +
> > > > +	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
> > > > +				   MAC_10 | MAC_100 | MAC_1000FD;
> > > 
> > > For port 5, you may also add the MAC_2500FD capability as it supports
> > > 2500BASEX ?
> > > 
> > 
> > I didn't account for the CPU port that runs at 2.5. The LAN port are
> > only 1g. Will add or maybe add the 2500FD only for cpu port?
> > 
> > Maybe Russel can help in this?
> 
> *ll* please.

emabrassing... sorry.

> 
> Well, 2500BASE-X runs at 2.5G, so if MAC_2500FD isn't set in the mask,
> validation will fail for 2500BASE-X.
> 
> > > > +		case SPEED_5000:
> > > > +			reg |= AN8855_PMCR_FORCE_SPEED_5000;
> > > > +			break;
> > > 
> > > There's no mention of any mode that can give support for the 5000Mbps
> > > speed, is it a leftover from previous work on the driver ?
> > > 
> > 
> > Added 5000 as this is present in documentation bits but CPU can only go
> > up to 2.5. Should I drop it? Idea was to futureproof it since it really
> > seems they added these bits with the intention of having a newer switch
> > with more advanced ports.
> 
> Is there any mention of supporting interfaces faster than 2500BASE-X ?
>

In MAC Layer function description, they say:
- Support 10/100/1000/2500/5000 Mbps bit rates

So in theory it can support up to that speed.

-- 
	Ansuel


From tomi.valkeinen at ideasonboard.com  Wed Dec  4 01:31:09 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 04 Dec 2024 11:31:09 +0200
Subject: [PATCH 09/10] drm: xlnx: zynqmp: Add support for X403
In-Reply-To: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
Message-ID: <20241204-xilinx-formats-v1-9-0bf2c5147db1@ideasonboard.com>

Add support for X403 format.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/xlnx/zynqmp_disp.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 44cfee6a0e32..622d1dfac42d 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -319,6 +319,11 @@ static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
 		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YONLY_10,
 		.swap		= false,
 		.sf		= scaling_factors_101010,
+	}, {
+		.drm_fmt	= DRM_FORMAT_X403,
+		.buf_fmt	= ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24_10,
+		.swap		= false,
+		.sf		= scaling_factors_101010,
 	},
 };
 

-- 
2.43.0



From ck.hu at mediatek.com  Wed Dec  4 01:41:05 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Wed, 4 Dec 2024 09:41:05 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
Message-ID: <de8b0cb760cd0586014426536138f79fe5dd1ed8.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static const struct drm_edid *mtk_hdmi_v2_bridge_edid_read(struct drm_bridge *bridge,
> +                                                       struct drm_connector *connector)
> +{

This function is identical to v1, so make edid read as common function.

Regards,
CK

> +       struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +       const struct drm_edid *drm_edid;
> +
> +       if (!hdmi->ddc_adpt)
> +               return NULL;
> +
> +       drm_edid = drm_edid_read_ddc(connector, hdmi->ddc_adpt);
> +       if (drm_edid) {
> +               /*
> +                * This should use !connector->display_info.has_audio (or
> +                * !connector->display_info.is_hdmi) from a path that has read
> +                * the EDID and called drm_edid_connector_update().
> +                */
> +               const struct edid *edid = drm_edid_raw(drm_edid);
> +
> +               hdmi->dvi_mode = !drm_detect_monitor_audio(edid);
> +       }
> +
> +       return drm_edid;
> +}
> +

> 

From francesco at dolcini.it  Wed Dec  4 01:59:19 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Wed, 4 Dec 2024 10:59:19 +0100
Subject: [PATCH] arm64: dts: ti: k3-j784s4: use ti,j7200-padconf
 compatible
In-Reply-To: <6e47e420-84c4-4539-ba54-5e1e939a37a5@bootlin.com>
References: <20241113-j784s4-s2r-pinctrl-v1-1-19aeb62739bc@bootlin.com>
 <20241119190106.GA70080@francesco-nb>
 <6e47e420-84c4-4539-ba54-5e1e939a37a5@bootlin.com>
Message-ID: <Z1An9_auC3dRyPln@gaggiata.pivistrello.it>

Hello Thomas,
thanks for the update.

On Wed, Dec 04, 2024 at 10:08:43AM +0100, Thomas Richard wrote:
> On 11/19/24 20:01, Francesco Dolcini wrote:
> > Hello Thomas and TI folks,
> > 
> > On Wed, Nov 13, 2024 at 11:43:05AM +0100, Thomas Richard wrote:
> >> Like on j7200, pinctrl contexts shall be saved and restored during
> >> suspend-to-ram.
> >>
> >> So use ti,j7200-padconf compatible.
> >>
> >> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
> >> ---
> >> Use ti,j7200-padconf compatible to save and restore pinctrl contexts during
> >> suspend-to-ram.
> >> ---
> >>  arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi       |  6 +++---
> >>  arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 12 ++++++------
> > 
> > Do j784s4 supports any kind of low power mode and/or suspend to ram? My
> > understanding was that this was not supported, but maybe there is some
> > details that was lost when I was told this information.
> 
> We are working on suspend-to-ram support for j7200 and j784s4.
> During suspend-to-ram the SoC is fully powered-off (thanks to the PMIC
> which powers off all the power rails except the DDR which is in
> self-refresh), like on j7200.
> Please let me know if you want more details.

ok, that's quite different from the common suspend-to-ram we use to have
implemented on other SoC. You would have some boot firmware (likely U-Boot)
code executing during resume, taking some different code path, in a similar way
to what it is being done for the partial-io support on am62p. It's going to be
more similar to hibernation from some point of view.

Do you expect to have this feature nicely integrated within the standard
suspend/resume "framework" in Linux?

It would be interesting to understand how to handle all the peripherals outside
the SoC, if you have reset/regulator controlled by GPIO from the SoC stuff will
happen as soon as the SoC is powered off since no one will drive this pins any
longer. From my understanding the only solution would be to not have such
regulator/reset connect to the SoC.

Francesco



From quic_vikramsa at quicinc.com  Wed Dec  4 01:59:59 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Wed, 4 Dec 2024 15:29:59 +0530
Subject: [PATCH v7 1/5] media: dt-bindings: Add qcom,sc7280-camss
In-Reply-To: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
Message-ID: <20241204100003.300123-2-quic_vikramsa@quicinc.com>

Add bindings for qcom,sc7280-camss to support the camera subsystem
on the SC7280 platform.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
---
 .../bindings/media/qcom,sc7280-camss.yaml     | 418 ++++++++++++++++++
 1 file changed, 418 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml

diff --git a/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
new file mode 100644
index 000000000000..b613dfbc47fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
@@ -0,0 +1,418 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/qcom,sc7280-camss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SC7280 CAMSS ISP
+
+maintainers:
+  - Azam Sadiq Pasha Kapatrala Syed <akapatra at quicinc.com>
+  - Hariram Purushothaman <hariramp at quicinc.com>
+
+description:
+  The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
+
+properties:
+  compatible:
+    const: qcom,sc7280-camss
+
+  reg:
+    maxItems: 15
+
+  reg-names:
+    items:
+      - const: csid0
+      - const: csid1
+      - const: csid2
+      - const: csid_lite0
+      - const: csid_lite1
+      - const: csiphy0
+      - const: csiphy1
+      - const: csiphy2
+      - const: csiphy3
+      - const: csiphy4
+      - const: vfe0
+      - const: vfe1
+      - const: vfe2
+      - const: vfe_lite0
+      - const: vfe_lite1
+
+  clocks:
+    maxItems: 33
+
+  clock-names:
+    items:
+      - const: camnoc_axi
+      - const: cpas_ahb
+      - const: csiphy0
+      - const: csiphy0_timer
+      - const: csiphy1
+      - const: csiphy1_timer
+      - const: csiphy2
+      - const: csiphy2_timer
+      - const: csiphy3
+      - const: csiphy3_timer
+      - const: csiphy4
+      - const: csiphy4_timer
+      - const: gcc_camera_ahb
+      - const: gcc_cam_hf_axi
+      - const: icp_ahb
+      - const: vfe0
+      - const: vfe0_axi
+      - const: vfe0_cphy_rx
+      - const: vfe0_csid
+      - const: vfe1
+      - const: vfe1_axi
+      - const: vfe1_cphy_rx
+      - const: vfe1_csid
+      - const: vfe2
+      - const: vfe2_axi
+      - const: vfe2_cphy_rx
+      - const: vfe2_csid
+      - const: vfe_lite0
+      - const: vfe_lite0_cphy_rx
+      - const: vfe_lite0_csid
+      - const: vfe_lite1
+      - const: vfe_lite1_cphy_rx
+      - const: vfe_lite1_csid
+
+  interrupts:
+    maxItems: 15
+
+  interrupt-names:
+    items:
+      - const: csid0
+      - const: csid1
+      - const: csid2
+      - const: csid_lite0
+      - const: csid_lite1
+      - const: csiphy0
+      - const: csiphy1
+      - const: csiphy2
+      - const: csiphy3
+      - const: csiphy4
+      - const: vfe0
+      - const: vfe1
+      - const: vfe2
+      - const: vfe_lite0
+      - const: vfe_lite1
+
+  interconnects:
+    maxItems: 2
+
+  interconnect-names:
+    items:
+      - const: ahb
+      - const: hf_0
+
+  iommus:
+    maxItems: 1
+
+  power-domains:
+    items:
+      - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: IFE2 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller.
+
+  power-domain-names:
+    items:
+      - const: ife0
+      - const: ife1
+      - const: ife2
+      - const: top
+
+  vdda-phy-supply:
+    description:
+      Phandle to a regulator supply to PHY core block.
+
+  vdda-pll-supply:
+    description:
+      Phandle to 1.8V regulator supply to PHY refclk pll block.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    description:
+      CSI input ports.
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 0.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 1.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+      port at 2:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 2.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+      port at 3:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 3.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+      port at 4:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 4.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - interrupts
+  - interrupt-names
+  - interconnects
+  - interconnect-names
+  - iommus
+  - power-domains
+  - power-domain-names
+  - vdda-phy-supply
+  - vdda-pll-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,camcc-sc7280.h>
+    #include <dt-bindings/clock/qcom,gcc-sc7280.h>
+    #include <dt-bindings/interconnect/qcom,sc7280.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        camss at acb3000 {
+            compatible = "qcom,sc7280-camss";
+
+            reg = <0x0 0x0acb3000 0x0 0x1000>,
+                  <0x0 0x0acba000 0x0 0x1000>,
+                  <0x0 0x0acc1000 0x0 0x1000>,
+                  <0x0 0x0acc8000 0x0 0x1000>,
+                  <0x0 0x0accf000 0x0 0x1000>,
+                  <0x0 0x0ace0000 0x0 0x2000>,
+                  <0x0 0x0ace2000 0x0 0x2000>,
+                  <0x0 0x0ace4000 0x0 0x2000>,
+                  <0x0 0x0ace6000 0x0 0x2000>,
+                  <0x0 0x0ace8000 0x0 0x2000>,
+                  <0x0 0x0acaf000 0x0 0x4000>,
+                  <0x0 0x0acb6000 0x0 0x4000>,
+                  <0x0 0x0acbd000 0x0 0x4000>,
+                  <0x0 0x0acc4000 0x0 0x4000>,
+                  <0x0 0x0accb000 0x0 0x4000>;
+            reg-names = "csid0",
+                        "csid1",
+                        "csid2",
+                        "csid_lite0",
+                        "csid_lite1",
+                        "csiphy0",
+                        "csiphy1",
+                        "csiphy2",
+                        "csiphy3",
+                        "csiphy4",
+                        "vfe0",
+                        "vfe1",
+                        "vfe2",
+                        "vfe_lite0",
+                        "vfe_lite1";
+
+            clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+                     <&camcc CAM_CC_CPAS_AHB_CLK>,
+                     <&camcc CAM_CC_CSIPHY0_CLK>,
+                     <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+                     <&camcc CAM_CC_CSIPHY1_CLK>,
+                     <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+                     <&camcc CAM_CC_CSIPHY2_CLK>,
+                     <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+                     <&camcc CAM_CC_CSIPHY3_CLK>,
+                     <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+                     <&camcc CAM_CC_CSIPHY4_CLK>,
+                     <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+                     <&gcc GCC_CAMERA_AHB_CLK>,
+                     <&gcc GCC_CAMERA_HF_AXI_CLK>,
+                     <&camcc CAM_CC_ICP_AHB_CLK>,
+                     <&camcc CAM_CC_IFE_0_CLK>,
+                     <&camcc CAM_CC_IFE_0_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_0_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_1_CLK>,
+                     <&camcc CAM_CC_IFE_1_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_1_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_2_CLK>,
+                     <&camcc CAM_CC_IFE_2_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_2_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>;
+            clock-names = "camnoc_axi",
+                          "cpas_ahb",
+                          "csiphy0",
+                          "csiphy0_timer",
+                          "csiphy1",
+                          "csiphy1_timer",
+                          "csiphy2",
+                          "csiphy2_timer",
+                          "csiphy3",
+                          "csiphy3_timer",
+                          "csiphy4",
+                          "csiphy4_timer",
+                          "gcc_camera_ahb",
+                          "gcc_cam_hf_axi",
+                          "icp_ahb",
+                          "vfe0",
+                          "vfe0_axi",
+                          "vfe0_cphy_rx",
+                          "vfe0_csid",
+                          "vfe1",
+                          "vfe1_axi",
+                          "vfe1_cphy_rx",
+                          "vfe1_csid",
+                          "vfe2",
+                          "vfe2_axi",
+                          "vfe2_cphy_rx",
+                          "vfe2_csid",
+                          "vfe_lite0",
+                          "vfe_lite0_cphy_rx",
+                          "vfe_lite0_csid",
+                          "vfe_lite1",
+                          "vfe_lite1_cphy_rx",
+                          "vfe_lite1_csid";
+
+            interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+            interrupt-names = "csid0",
+                              "csid1",
+                              "csid2",
+                              "csid_lite0",
+                              "csid_lite1",
+                              "csiphy0",
+                              "csiphy1",
+                              "csiphy2",
+                              "csiphy3",
+                              "csiphy4",
+                              "vfe0",
+                              "vfe1",
+                              "vfe2",
+                              "vfe_lite0",
+                              "vfe_lite1";
+
+            interconnects = <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_CAMERA_CFG 0>,
+                            <&mmss_noc MASTER_CAMNOC_HF 0 &mc_virt SLAVE_EBI1 0>;
+            interconnect-names = "ahb", "hf_0";
+
+            iommus = <&apps_smmu 0x800 0x4e0>;
+
+            power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
+                            <&camcc CAM_CC_IFE_1_GDSC>,
+                            <&camcc CAM_CC_IFE_2_GDSC>,
+                            <&camcc CAM_CC_TITAN_TOP_GDSC>;
+            power-domain-names = "ife0", "ife1", "ife2", "top";
+
+            vdda-phy-supply = <&vreg_l10c_0p88>;
+            vdda-pll-supply = <&vreg_l6b_1p2>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+            };
+        };
+    };
-- 
2.25.1



From quic_vikramsa at quicinc.com  Wed Dec  4 02:00:00 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Wed, 4 Dec 2024 15:30:00 +0530
Subject: [PATCH v7 2/5] media: qcom: camss: Sort camss version enums and compatible strings
In-Reply-To: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
Message-ID: <20241204100003.300123-3-quic_vikramsa@quicinc.com>

Sort CAMSS version enums and compatible strings alphanumerically.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
---
 .../media/platform/qcom/camss/camss-csiphy-3ph-1-0.c   | 10 +++++-----
 drivers/media/platform/qcom/camss/camss-vfe.c          |  6 +++---
 drivers/media/platform/qcom/camss/camss.c              |  2 +-
 drivers/media/platform/qcom/camss/camss.h              |  4 ++--
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index df7e93a5a4f6..7d2490c9de01 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -505,10 +505,6 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
 	u32 val;
 
 	switch (csiphy->camss->res->version) {
-	case CAMSS_845:
-		r = &lane_regs_sdm845[0][0];
-		array_size = ARRAY_SIZE(lane_regs_sdm845[0]);
-		break;
 	case CAMSS_8250:
 		r = &lane_regs_sm8250[0][0];
 		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
@@ -517,6 +513,10 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
 		r = &lane_regs_sc8280xp[0][0];
 		array_size = ARRAY_SIZE(lane_regs_sc8280xp[0]);
 		break;
+	case CAMSS_845:
+		r = &lane_regs_sdm845[0][0];
+		array_size = ARRAY_SIZE(lane_regs_sdm845[0]);
+		break;
 	default:
 		WARN(1, "unknown cspi version\n");
 		return;
@@ -557,9 +557,9 @@ static bool csiphy_is_gen2(u32 version)
 	bool ret = false;
 
 	switch (version) {
-	case CAMSS_845:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
+	case CAMSS_845:
 		ret = true;
 		break;
 	}
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 80a62ba11295..fb3234c65403 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -334,11 +334,11 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
 			return sink_code;
 		}
 		break;
-	case CAMSS_8x96:
 	case CAMSS_660:
-	case CAMSS_845:
+	case CAMSS_8x96:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
+	case CAMSS_845:
 		switch (sink_code) {
 		case MEDIA_BUS_FMT_YUYV8_1X16:
 		{
@@ -1693,9 +1693,9 @@ static int vfe_bpl_align(struct vfe_device *vfe)
 	int ret = 8;
 
 	switch (vfe->camss->res->version) {
-	case CAMSS_845:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
+	case CAMSS_845:
 		ret = 16;
 		break;
 	default:
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 9fb31f4c18ad..f5704c23766a 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -2626,10 +2626,10 @@ static const struct of_device_id camss_dt_match[] = {
 	{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
 	{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
 	{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
+	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
 	{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
 	{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
 	{ .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
-	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
 	{ }
 };
 
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 9da7f48f5dd7..ffce0a0edbc5 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -77,13 +77,13 @@ enum pm_domain {
 };
 
 enum camss_version {
+	CAMSS_660,
 	CAMSS_8x16,
 	CAMSS_8x53,
 	CAMSS_8x96,
-	CAMSS_660,
-	CAMSS_845,
 	CAMSS_8250,
 	CAMSS_8280XP,
+	CAMSS_845,
 };
 
 enum icc_count {
-- 
2.25.1



From quic_vikramsa at quicinc.com  Wed Dec  4 02:00:01 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Wed, 4 Dec 2024 15:30:01 +0530
Subject: [PATCH v7 3/5] media: qcom: camss: Add support for camss driver on sc7280
In-Reply-To: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
Message-ID: <20241204100003.300123-4-quic_vikramsa@quicinc.com>

From: Suresh Vankadara <quic_svankada at quicinc.com>

Add support for the camss driver on the sc7280 soc.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
---
 .../qcom/camss/camss-csiphy-3ph-1-0.c         |   5 +
 .../media/platform/qcom/camss/camss-csiphy.c  |   5 +
 .../media/platform/qcom/camss/camss-csiphy.h  |   1 +
 drivers/media/platform/qcom/camss/camss-vfe.c |   2 +
 drivers/media/platform/qcom/camss/camss.c     | 319 ++++++++++++++++++
 drivers/media/platform/qcom/camss/camss.h     |   1 +
 6 files changed, 333 insertions(+)

diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index 7d2490c9de01..f341f7b7fd8a 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -505,6 +505,10 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
 	u32 val;
 
 	switch (csiphy->camss->res->version) {
+	case CAMSS_7280:
+		r = &lane_regs_sm8250[0][0];
+		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
+		break;
 	case CAMSS_8250:
 		r = &lane_regs_sm8250[0][0];
 		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
@@ -557,6 +561,7 @@ static bool csiphy_is_gen2(u32 version)
 	bool ret = false;
 
 	switch (version) {
+	case CAMSS_7280:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
 	case CAMSS_845:
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index 5af2b382a843..3791c2d8a6cf 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -103,6 +103,11 @@ const struct csiphy_formats csiphy_formats_8x96 = {
 	.formats = formats_8x96
 };
 
+const struct csiphy_formats csiphy_formats_sc7280 = {
+	.nformats = ARRAY_SIZE(formats_sdm845),
+	.formats = formats_sdm845
+};
+
 const struct csiphy_formats csiphy_formats_sdm845 = {
 	.nformats = ARRAY_SIZE(formats_sdm845),
 	.formats = formats_sdm845
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
index eebc1ff1cfab..b6209bddfb61 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.h
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
@@ -111,6 +111,7 @@ void msm_csiphy_unregister_entity(struct csiphy_device *csiphy);
 
 extern const struct csiphy_formats csiphy_formats_8x16;
 extern const struct csiphy_formats csiphy_formats_8x96;
+extern const struct csiphy_formats csiphy_formats_sc7280;
 extern const struct csiphy_formats csiphy_formats_sdm845;
 
 extern const struct csiphy_hw_ops csiphy_ops_2ph_1_0;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index fb3234c65403..95f6a1ac7eaf 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -335,6 +335,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
 		}
 		break;
 	case CAMSS_660:
+	case CAMSS_7280:
 	case CAMSS_8x96:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
@@ -1693,6 +1694,7 @@ static int vfe_bpl_align(struct vfe_device *vfe)
 	int ret = 8;
 
 	switch (vfe->camss->res->version) {
+	case CAMSS_7280:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
 	case CAMSS_845:
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index f5704c23766a..4fa16ff6e614 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1266,6 +1266,310 @@ static const struct resources_icc icc_res_sm8250[] = {
 	},
 };
 
+static const struct camss_subdev_resources csiphy_res_7280[] = {
+	/* CSIPHY0 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy0", "csiphy0_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy0" },
+		.interrupt = { "csiphy0" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY1 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy1", "csiphy1_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy1" },
+		.interrupt = { "csiphy1" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY2 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy2", "csiphy2_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy2" },
+		.interrupt = { "csiphy2" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY3 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy3", "csiphy3_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy3" },
+		.interrupt = { "csiphy3" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY4 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy4", "csiphy4_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy4" },
+		.interrupt = { "csiphy4" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+};
+
+static const struct camss_subdev_resources csid_res_7280[] = {
+	/* CSID0 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 }
+		},
+
+		.reg = { "csid0" },
+		.interrupt = { "csid0" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID1 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 }
+		},
+
+		.reg = { "csid1" },
+		.interrupt = { "csid1" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID2 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 }
+		},
+
+		.reg = { "csid2" },
+		.interrupt = { "csid2" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID3 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 320000000, 400000000, 480000000, 600000000 }
+		},
+
+		.reg = { "csid_lite0" },
+		.interrupt = { "csid_lite0" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID4 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 320000000, 400000000, 480000000, 600000000 }
+		},
+
+		.reg = { "csid_lite1" },
+		.interrupt = { "csid_lite1" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+};
+
+static const struct camss_subdev_resources vfe_res_7280[] = {
+	/* VFE0 */
+	{
+		.regulators = {},
+
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0",
+			   "vfe0_axi", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 },
+				{ 0 },
+				{ 0 } },
+
+		.reg = { "vfe0" },
+		.interrupt = { "vfe0" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = true,
+			.pd_name = "ife0",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE1 */
+	{
+		.regulators = {},
+
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe1",
+			   "vfe1_axi", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 },
+				{ 0 },
+				{ 0 } },
+
+		.reg = { "vfe1" },
+		.interrupt = { "vfe1" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = true,
+			.pd_name = "ife1",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE2 */
+	{
+		.regulators = {},
+
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe2",
+			   "vfe2_axi", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 },
+				{ 0 },
+				{ 0 } },
+
+		.reg = { "vfe2" },
+		.interrupt = { "vfe2" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.hw_ops = &vfe_ops_170,
+			.has_pd = true,
+			.pd_name = "ife2",
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE3 (lite) */
+	{
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
+			   "vfe_lite0", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 320000000, 400000000, 480000000, 600000000 },
+				{ 0 } },
+
+		.regulators = {},
+		.reg = { "vfe_lite0" },
+		.interrupt = { "vfe_lite0" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE4 (lite) */
+	{
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
+			   "vfe_lite1", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 320000000, 400000000, 480000000, 600000000 },
+				{ 0 } },
+
+		.regulators = {},
+		.reg = { "vfe_lite1" },
+		.interrupt = { "vfe_lite1" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+};
+
+static const struct resources_icc icc_res_sc7280[] = {
+	{
+		.name = "ahb",
+		.icc_bw_tbl.avg = 38400,
+		.icc_bw_tbl.peak = 76800,
+	},
+	{
+		.name = "hf_0",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+};
+
 static const struct camss_subdev_resources csiphy_res_sc8280xp[] = {
 	/* CSIPHY0 */
 	{
@@ -2622,10 +2926,25 @@ static const struct camss_resources sc8280xp_resources = {
 	.link_entities = camss_link_entities
 };
 
+static const struct camss_resources sc7280_resources = {
+	.version = CAMSS_7280,
+	.pd_name = "top",
+	.csiphy_res = csiphy_res_7280,
+	.csid_res = csid_res_7280,
+	.vfe_res = vfe_res_7280,
+	.icc_res = icc_res_sc7280,
+	.icc_path_num = ARRAY_SIZE(icc_res_sc7280),
+	.csiphy_num = ARRAY_SIZE(csiphy_res_7280),
+	.csid_num = ARRAY_SIZE(csid_res_7280),
+	.vfe_num = ARRAY_SIZE(vfe_res_7280),
+	.link_entities = camss_link_entities
+};
+
 static const struct of_device_id camss_dt_match[] = {
 	{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
 	{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
 	{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
+	{ .compatible = "qcom,sc7280-camss", .data = &sc7280_resources },
 	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
 	{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
 	{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index ffce0a0edbc5..9a046eea334f 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -78,6 +78,7 @@ enum pm_domain {
 
 enum camss_version {
 	CAMSS_660,
+	CAMSS_7280,
 	CAMSS_8x16,
 	CAMSS_8x53,
 	CAMSS_8x96,
-- 
2.25.1



From quic_vikramsa at quicinc.com  Wed Dec  4 02:00:02 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Wed, 4 Dec 2024 15:30:02 +0530
Subject: [PATCH v7 4/5] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
Message-ID: <20241204100003.300123-5-quic_vikramsa@quicinc.com>

Add changes to support the camera subsystem on the SC7280.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 172 +++++++++++++++++++++++++++
 1 file changed, 172 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 55db1c83ef55..e363996602d6 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -4426,6 +4426,178 @@ cci1_i2c1: i2c-bus at 1 {
 			};
 		};
 
+		camss: camss at acb3000 {
+			compatible = "qcom,sc7280-camss";
+
+			reg = <0x0 0x0acb3000 0x0 0x1000>,
+			      <0x0 0x0acba000 0x0 0x1000>,
+			      <0x0 0x0acc1000 0x0 0x1000>,
+			      <0x0 0x0acc8000 0x0 0x1000>,
+			      <0x0 0x0accf000 0x0 0x1000>,
+			      <0x0 0x0ace0000 0x0 0x2000>,
+			      <0x0 0x0ace2000 0x0 0x2000>,
+			      <0x0 0x0ace4000 0x0 0x2000>,
+			      <0x0 0x0ace6000 0x0 0x2000>,
+			      <0x0 0x0ace8000 0x0 0x2000>,
+			      <0x0 0x0acaf000 0x0 0x4000>,
+			      <0x0 0x0acb6000 0x0 0x4000>,
+			      <0x0 0x0acbd000 0x0 0x4000>,
+			      <0x0 0x0acc4000 0x0 0x4000>,
+			      <0x0 0x0accb000 0x0 0x4000>;
+			reg-names = "csid0",
+				    "csid1",
+				    "csid2",
+				    "csid_lite0",
+				    "csid_lite1",
+				    "csiphy0",
+				    "csiphy1",
+				    "csiphy2",
+				    "csiphy3",
+				    "csiphy4",
+				    "vfe0",
+				    "vfe1",
+				    "vfe2",
+				    "vfe_lite0",
+				    "vfe_lite1";
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_CSIPHY0_CLK>,
+				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY1_CLK>,
+				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY2_CLK>,
+				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY3_CLK>,
+				 <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY4_CLK>,
+				 <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+				 <&gcc GCC_CAMERA_AHB_CLK>,
+				 <&gcc GCC_CAMERA_HF_AXI_CLK>,
+				 <&camcc CAM_CC_ICP_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_0_CLK>,
+				 <&camcc CAM_CC_IFE_0_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_1_CLK>,
+				 <&camcc CAM_CC_IFE_1_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_1_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_2_CLK>,
+				 <&camcc CAM_CC_IFE_2_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_2_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>;
+			clock-names = "camnoc_axi",
+				      "cpas_ahb",
+				      "csiphy0",
+				      "csiphy0_timer",
+				      "csiphy1",
+				      "csiphy1_timer",
+				      "csiphy2",
+				      "csiphy2_timer",
+				      "csiphy3",
+				      "csiphy3_timer",
+				      "csiphy4",
+				      "csiphy4_timer",
+				      "gcc_camera_ahb",
+				      "gcc_cam_hf_axi",
+				      "icp_ahb",
+				      "vfe0",
+				      "vfe0_axi",
+				      "vfe0_cphy_rx",
+				      "vfe0_csid",
+				      "vfe1",
+				      "vfe1_axi",
+				      "vfe1_cphy_rx",
+				      "vfe1_csid",
+				      "vfe2",
+				      "vfe2_axi",
+				      "vfe2_cphy_rx",
+				      "vfe2_csid",
+				      "vfe_lite0",
+				      "vfe_lite0_cphy_rx",
+				      "vfe_lite0_csid",
+				      "vfe_lite1",
+				      "vfe_lite1_cphy_rx",
+				      "vfe_lite1_csid";
+
+			interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "csid0",
+					  "csid1",
+					  "csid2",
+					  "csid_lite0",
+					  "csid_lite1",
+					  "csiphy0",
+					  "csiphy1",
+					  "csiphy2",
+					  "csiphy3",
+					  "csiphy4",
+					  "vfe0",
+					  "vfe1",
+					  "vfe2",
+					  "vfe_lite0",
+					  "vfe_lite1";
+
+			interconnects = <&gem_noc  MASTER_APPSS_PROC 0 &cnoc2 SLAVE_CAMERA_CFG 0>,
+					<&mmss_noc MASTER_CAMNOC_HF  0 &mc_virt SLAVE_EBI1     0>;
+			interconnect-names = "ahb", "hf_0";
+
+			iommus = <&apps_smmu 0x800 0x4e0>;
+
+			power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
+					<&camcc CAM_CC_IFE_1_GDSC>,
+					<&camcc CAM_CC_IFE_2_GDSC>,
+					<&camcc CAM_CC_TITAN_TOP_GDSC>;
+			power-domain-names = "ife0", "ife1", "ife2", "top";
+
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+				};
+
+				port at 1 {
+					reg = <1>;
+				};
+
+				port at 2 {
+					reg = <2>;
+				};
+
+				port at 3 {
+					reg = <3>;
+				};
+
+				port at 4 {
+					reg = <4>;
+				};
+			};
+		};
+
 		camcc: clock-controller at ad00000 {
 			compatible = "qcom,sc7280-camcc";
 			reg = <0 0x0ad00000 0 0x10000>;
-- 
2.25.1



From linux at armlinux.org.uk  Wed Dec  4 02:00:41 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Dec 2024 10:00:41 +0000
Subject: [net-next PATCH v8 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <675021f1.050a0220.34c00a.3a0c@mx.google.com>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
 <20241204072427.17778-4-ansuelsmth@gmail.com>
 <20241204100922.0af25d7e@fedora.home>
 <67501d7b.050a0220.3390ac.353c@mx.google.com>
 <Z1Af3YaN3xjq_Gtb@shell.armlinux.org.uk>
 <675021f1.050a0220.34c00a.3a0c@mx.google.com>
Message-ID: <Z1AoSSDqAbEisuzK@shell.armlinux.org.uk>

On Wed, Dec 04, 2024 at 10:33:33AM +0100, Christian Marangi wrote:
> On Wed, Dec 04, 2024 at 09:24:45AM +0000, Russell King (Oracle) wrote:
> > > Added 5000 as this is present in documentation bits but CPU can only go
> > > up to 2.5. Should I drop it? Idea was to futureproof it since it really
> > > seems they added these bits with the intention of having a newer switch
> > > with more advanced ports.
> > 
> > Is there any mention of supporting interfaces faster than 2500BASE-X ?
> >
> 
> In MAC Layer function description, they say:
> - Support 10/100/1000/2500/5000 Mbps bit rates
> 
> So in theory it can support up to that speed.

Maybe the internal IP supports this but the SoC doesn't?

However, I was asking about interfaces rather than speeds - so RGMII,
SGMII, 2500BASE-X... is there a mention of anything else?

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


From quic_vikramsa at quicinc.com  Wed Dec  4 02:00:03 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Wed, 4 Dec 2024 15:30:03 +0530
Subject: [PATCH v7 5/5] arm64: dts: qcom: qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
Message-ID: <20241204100003.300123-6-quic_vikramsa@quicinc.com>

The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
Enable the IMX577 on the vision mezzanine.

An example media-ctl pipeline for the imx577 is:

media-ctl --reset
media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'

yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0

Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
---
 arch/arm64/boot/dts/qcom/Makefile             |   4 +
 .../qcs6490-rb3gen2-vision-mezzanine.dtso     | 110 ++++++++++++++++++
 2 files changed, 114 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 9bb8b191aeb5..4ee57b3871dd 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -114,6 +114,10 @@ dtb-$(CONFIG_ARCH_QCOM)	+= qcm6490-shift-otter.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-1000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-4000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
+
+qcs6490-rb3gen2-vision-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2-vision-mezzanine.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride-r3.dtb
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
new file mode 100644
index 000000000000..d6085637d0c3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/*
+ * Camera Sensor overlay on top of rb3gen2 core kit.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/qcom,camcc-sc7280.h>
+
+/dts-v1/;
+/plugin/;
+
+&camcc {
+	status = "okay";
+};
+
+&camss {
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* The port index denotes CSIPHY id i.e. csiphy3 */
+		port at 3 {
+			reg = <3>;
+			csiphy3_ep: endpoint {
+				clock-lanes = <7>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&imx577_ep>;
+			};
+		};
+	};
+};
+
+&cci1 {
+	status = "okay";
+};
+
+&cci1_i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	camera at 1a {
+		compatible = "sony,imx577";
+		reg = <0x1a>;
+
+		reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default", "suspend";
+		pinctrl-0 = <&cam2_default>;
+		pinctrl-1 = <&cam2_suspend>;
+
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clock-rates = <24000000>;
+
+		dovdd-supply  = <&vreg_l18b_1p8>;
+		avdd-supply = <&vph_pwr>;
+		dvdd-supply = <&vph_pwr>;
+
+		port {
+			imx577_ep: endpoint {
+				clock-lanes = <7>;
+				link-frequencies = /bits/ 64 <600000000>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&csiphy3_ep>;
+			};
+		};
+	};
+};
+
+&tlmm {
+	cam2_default: cam2-default-state {
+		rst-pins {
+			pins = "gpio78";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+		};
+
+		mclk-pins {
+			pins = "gpio67";
+			function = "cam_mclk";
+			drive-strength = <2>;
+			bias-disable;
+		};
+	};
+
+	cam2_suspend: cam2-suspend-state {
+		rst-pins {
+			pins = "gpio78";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+			output-low;
+		};
+
+		mclk-pins {
+			pins = "gpio67";
+			function = "cam_mclk";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
+};
-- 
2.25.1



From ck.hu at mediatek.com  Wed Dec  4 01:46:44 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Wed, 4 Dec 2024 09:46:44 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
Message-ID: <278d55ed1b6d6f8240e8df98e915bc3ad329c2ec.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static void mtk_hdmi_v2_audio_init(struct mtk_hdmi *hdmi, struct hdmi_codec_pdata *codec_data)
> +{
> +       struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> +
> +       aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +       aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +       aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> +       aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> +       aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> +       aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> +       codec_data->ops = &mtk_hdmi_v2_audio_codec_ops;

This function is almost the same as v1. The only difference is codec_data->ops, so make audio init as common function.
And

codec_data->ops = hdmi->conf->ver_conf->audio_codec_ops;

Regards,
CK

> +}
> +


From quic_vikramsa at quicinc.com  Wed Dec  4 01:59:58 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Wed, 4 Dec 2024 15:29:58 +0530
Subject: [PATCH v7 0/5] media: qcom: camss: Add sc7280 support
Message-ID: <20241204100003.300123-1-quic_vikramsa@quicinc.com>

SC7280 is a Qualcomm SoC. This series adds support to bring up the CSIPHY,
CSID, VFE/RDI interfaces in SC7280.

SC7280 provides

- 3 x VFE, 3 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE
- 3 x CSID
- 2 x CSID Lite
- 5 x CSI PHY

The changes are verified on SC7280 qcs6490-rb3gen2 board, with attached vision mezzanine
TPG (mode 1-9) and IMX577 sensor.
The base dts for qcs6490-rb3gen2 is:
https://lore.kernel.org/all/20231103184655.23555-1-quic_kbajaj at quicinc.com/

This change is dependent on below series. As it is raised on top of
this. Please take both to validate.
https://lore.kernel.org/lkml/20241126100126.2743795-1-quic_vikramsa at quicinc.com/

Used following tools for the sanity check of these changes.

- make CHECK_DTBS=y W=1 DT_SCHEMA_FILES=media/qcom,sc7280-camss.yaml
qcom/qcs6490-rb3gen2-vision-mezzanine.dtb
- make DT_CHECKER_FLAGS=-m W=1
DT_SCHEMA_FILES=media/qcom,sc7280-camss.yaml dt_binding_check
- Smatch: make CHECK="smatch --full-path"
M=drivers/media/platform/qcom/camss/
- Sparse: make C=2 M=drivers/media/platform/qcom/camss/
- coccicheck : make coccicheck M=drivers/media/platform/qcom/camss/
- make -j32 W=1
- ./scripts/checkpatch.pl
 
Changes in V7:
- Changed unit address for camss in documention and dts.
- Added avdd-supply and dvdd-supply for sensor.
- Changed reg/clocks/interrupts name for vfe_lite and csid_lite.
- Link to v6: https://lore.kernel.org/linux-arm-msm/20241127100421.3447601-1-quic_vikramsa at quicinc.com/

Changes in V6:
- Changed order of properties in Documentation [PATCH 1/5].
- Updated description for ports in Documentaion [PATCH 1/5].
- Moved regulators from csid to csiphy [PATCH 3/5].
- Link to v5: https://lore.kernel.org/linux-arm-msm/20241112173032.2740119-1-quic_vikramsa at quicinc.com/ 

Changes in V5:
- Updated Commit text for [PATCH v5 1/6].
- Moved reg after compatible string.
- Renamed csi'x' clocks to vfe'x'_csid
- Removed [PATCH v4 4/6] and raised a seprate series for this one.
- Moved gpio states to mezzanine dtso.
- Added more clock levels to address TPG related issues.
- Renamed power-domains-names -> power-domain-names. 
- Link to v4: https://lore.kernel.org/linux-arm-msm/20241030105347.2117034-1-quic_vikramsa at quicinc.com/ 

Changes in V4:
- V3 had 8 patches and V4 is reduced to 6.
- Removed [Patch v3 2/8] as binding change is not required for dtso.
- Removed [Patch v3 3/8] as the fix is already taken care in latest
  kernel tip. 
- Updated alignment for dtsi and dt-bindings.
- Adding qcs6490-rb3gen2-vision-mezzanine as overlay. 
- Link to v3: https://lore.kernel.org/linux-arm-msm/20241011140932.1744124-1-quic_vikramsa at quicinc.com/

Changes in V3:
- Added missed subject line for cover letter of V2.
- Updated Alignment, indentation and properties order.
- edit commit text for [PATCH 02/10] and [PATCH 03/10].
- Refactor camss_link_entities.
- Removed camcc enablement changes as it already done.
- Link to v2: https://lore.kernel.org/linux-arm-msm/20240904-camss_on_sc7280_rb3gen2_vision_v2_patches-v1-0-b18ddcd7d9df at quicinc.com/

Changes in V2:
- Improved indentation/formatting.
- Removed _src clocks and misleading code comments.
- Added name fields for power domains and csid register offset in DTSI.
- Dropped minItems field from YAML file.
- Listed changes in alphabetical order.
- Updated description and commit text to reflect changes
- Changed the compatible string from imx412 to imx577.
- Added board-specific enablement changes in the newly created vision
  board DTSI file.
- Fixed bug encountered during testing.
- Moved logically independent changes to a new/seprate patch.
- Removed cci0 as no sensor is on this port and MCLK2, which was a
  copy-paste error from the RB5 board reference.
- Added power rails, referencing the RB5 board.
- Discarded Patch 5/6 completely (not required).
- Removed unused enums.
- Link to v1: https://lore.kernel.org/linux-arm-msm/20240629-camss_first_post_linux_next-v1-0-bc798edabc3a at quicinc.com/

Suresh Vankadara (1):
  media: qcom: camss: Add support for camss driver on sc7280

Vikram Sharma (4):
  media: dt-bindings: Add qcom,sc7280-camss
  media: qcom: camss: Sort camss version enums and compatible strings
  arm64: dts: qcom: sc7280: Add support for camss
  arm64: dts: qcom: qcs6490-rb3gen2-vision-mezzanine: Add vision
    mezzanine

 .../bindings/media/qcom,sc7280-camss.yaml     | 418 ++++++++++++++++++
 arch/arm64/boot/dts/qcom/Makefile             |   4 +
 .../qcs6490-rb3gen2-vision-mezzanine.dtso     | 110 +++++
 arch/arm64/boot/dts/qcom/sc7280.dtsi          | 172 +++++++
 .../qcom/camss/camss-csiphy-3ph-1-0.c         |  13 +-
 .../media/platform/qcom/camss/camss-csiphy.c  |   5 +
 .../media/platform/qcom/camss/camss-csiphy.h  |   1 +
 drivers/media/platform/qcom/camss/camss-vfe.c |   8 +-
 drivers/media/platform/qcom/camss/camss.c     | 321 +++++++++++++-
 drivers/media/platform/qcom/camss/camss.h     |   5 +-
 10 files changed, 1047 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
 create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso

-- 
2.25.1



From ansuelsmth at gmail.com  Wed Dec  4 02:07:08 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Wed, 4 Dec 2024 11:07:08 +0100
Subject: [net-next PATCH v8 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <Z1AoSSDqAbEisuzK@shell.armlinux.org.uk>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
 <20241204072427.17778-4-ansuelsmth@gmail.com>
 <20241204100922.0af25d7e@fedora.home>
 <67501d7b.050a0220.3390ac.353c@mx.google.com>
 <Z1Af3YaN3xjq_Gtb@shell.armlinux.org.uk>
 <675021f1.050a0220.34c00a.3a0c@mx.google.com>
 <Z1AoSSDqAbEisuzK@shell.armlinux.org.uk>
Message-ID: <675029cf.df0a0220.1d1837.a877@mx.google.com>

On Wed, Dec 04, 2024 at 10:00:41AM +0000, Russell King (Oracle) wrote:
> On Wed, Dec 04, 2024 at 10:33:33AM +0100, Christian Marangi wrote:
> > On Wed, Dec 04, 2024 at 09:24:45AM +0000, Russell King (Oracle) wrote:
> > > > Added 5000 as this is present in documentation bits but CPU can only go
> > > > up to 2.5. Should I drop it? Idea was to futureproof it since it really
> > > > seems they added these bits with the intention of having a newer switch
> > > > with more advanced ports.
> > > 
> > > Is there any mention of supporting interfaces faster than 2500BASE-X ?
> > >
> > 
> > In MAC Layer function description, they say:
> > - Support 10/100/1000/2500/5000 Mbps bit rates
> > 
> > So in theory it can support up to that speed.
> 
> Maybe the internal IP supports this but the SoC doesn't?
> 
> However, I was asking about interfaces rather than speeds - so RGMII,
> SGMII, 2500BASE-X... is there a mention of anything else?
>

I can see mention of 5g Base-R so I assume supported but in the sdk
there isn't any code to configure it/I don't have any hardware.

(and documentation is empty for anything PCS related for register, just
block diagram)

I can ask it that is expected to work tho.

-- 
	Ansuel


From smostafa at google.com  Wed Dec  4 02:12:24 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Wed, 4 Dec 2024 10:12:24 +0000
Subject: [PATCH v10 1/4] iommu/io-pgtable-arm: Make pgtable walker more
 generic
In-Reply-To: <20241028213146.238941-2-robdclark@gmail.com>
References: <20241028213146.238941-1-robdclark@gmail.com>
 <20241028213146.238941-2-robdclark@gmail.com>
Message-ID: <Z1ArCCTGtJY9gxP3@google.com>

Hi Rob,

On Mon, Oct 28, 2024 at 02:31:37PM -0700, Rob Clark wrote:
> From: Rob Clark <robdclark at chromium.org>
> 
> We can re-use this basic pgtable walk logic in a few places.
> 
> Signed-off-by: Rob Clark <robdclark at chromium.org>
Reviewed-by: Mostafa Saleh <smostafa at google.com>

> ---
>  drivers/iommu/io-pgtable-arm.c | 67 ++++++++++++++++++++++------------
>  1 file changed, 43 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 0e67f1721a3d..7e9c0f8ae138 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -749,33 +749,33 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
>  }
>  
>  struct io_pgtable_walk_data {
> -	struct iommu_dirty_bitmap	*dirty;
> +	struct io_pgtable		*iop;
> +	void				*data;
> +	int (*visit)(struct io_pgtable_walk_data *walk_data, int lvl,
> +		     arm_lpae_iopte *ptep, size_t size);
>  	unsigned long			flags;
>  	u64				addr;
>  	const u64			end;
>  };
>  
> -static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
> -				       struct io_pgtable_walk_data *walk_data,
> -				       arm_lpae_iopte *ptep,
> -				       int lvl);
> +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 io_pgtable_visit_dirty(struct arm_lpae_io_pgtable *data,
> -				  struct io_pgtable_walk_data *walk_data,
> -				  arm_lpae_iopte *ptep, int lvl)
> +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 (iopte_leaf(pte, lvl, iop->fmt)) {
> -		size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
> +	size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
> +	int ret = walk_data->visit(walk_data, lvl, ptep, size);
> +	if (ret)
> +		return ret;
>  
> -		if (iopte_writeable_dirty(pte)) {
> -			iommu_dirty_bitmap_record(walk_data->dirty,
> -						  walk_data->addr, size);
> -			if (!(walk_data->flags & IOMMU_DIRTY_NO_CLEAR))
> -				iopte_set_writeable_clean(ptep);
> -		}
> +	if (iopte_leaf(pte, lvl, iop->fmt)) {
>  		walk_data->addr += size;
>  		return 0;
>  	}
> @@ -784,13 +784,13 @@ static int io_pgtable_visit_dirty(struct arm_lpae_io_pgtable *data,
>  		return -EINVAL;
>  
>  	ptep = iopte_deref(pte, data);
> -	return __arm_lpae_iopte_walk_dirty(data, walk_data, ptep, lvl + 1);
> +	return __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);
>  }
>  
> -static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
> -				       struct io_pgtable_walk_data *walk_data,
> -				       arm_lpae_iopte *ptep,
> -				       int lvl)
> +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;
> @@ -805,7 +805,7 @@ static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
>  
>  	for (idx = ARM_LPAE_LVL_IDX(walk_data->addr, lvl, data);
>  	     (idx < max_entries) && (walk_data->addr < walk_data->end); ++idx) {
> -		ret = io_pgtable_visit_dirty(data, walk_data, ptep + idx, lvl);
> +		ret = io_pgtable_visit(data, walk_data, ptep + idx, lvl);
>  		if (ret)
>  			return ret;
>  	}
> @@ -813,6 +813,23 @@ static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
>  	return 0;
>  }
>  
> +static int visit_dirty(struct io_pgtable_walk_data *walk_data, int lvl,
> +		       arm_lpae_iopte *ptep, size_t size)
> +{
> +	struct iommu_dirty_bitmap *dirty = walk_data->data;
> +
> +	if (!iopte_leaf(*ptep, lvl, walk_data->iop->fmt))
> +		return 0;
> +
> +	if (iopte_writeable_dirty(*ptep)) {
> +		iommu_dirty_bitmap_record(dirty, walk_data->addr, size);
> +		if (!(walk_data->flags & IOMMU_DIRTY_NO_CLEAR))
> +			iopte_set_writeable_clean(ptep);
> +	}
> +
> +	return 0;
> +}
> +
>  static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
>  					 unsigned long iova, size_t size,
>  					 unsigned long flags,
> @@ -821,7 +838,9 @@ static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
>  	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
>  	struct io_pgtable_cfg *cfg = &data->iop.cfg;
>  	struct io_pgtable_walk_data walk_data = {
> -		.dirty = dirty,
> +		.iop = &data->iop,
> +		.data = dirty,
> +		.visit = visit_dirty,
>  		.flags = flags,
>  		.addr = iova,
>  		.end = iova + size,
> @@ -836,7 +855,7 @@ static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
>  	if (data->iop.fmt != ARM_64_LPAE_S1)
>  		return -EINVAL;
>  
> -	return __arm_lpae_iopte_walk_dirty(data, &walk_data, ptep, lvl);
> +	return __arm_lpae_iopte_walk(data, &walk_data, ptep, lvl);
>  }
>  
>  static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
> -- 
> 2.47.0
> 


From quic_yuanfang at quicinc.com  Wed Dec  4 02:13:20 2024
From: quic_yuanfang at quicinc.com (yuanfang zhang)
Date: Wed, 4 Dec 2024 18:13:20 +0800
Subject: [PATCH] coresight-etm4x: add isb() before reading the TRCSTATR
Message-ID: <20241204101320.3692167-1-quic_yuanfang@quicinc.com>

From: Yuanfang Zhang <quic_yuanfang at quicinc.com>

As recommended by section 4.3.7 ("Synchronization when using system
instructions to progrom the trace unit") of ARM IHI 0064H.b, the
self-hosted trace analyzer must perform a Context synchronization
event between writing to the TRCPRGCTLR and reading the TRCSTATR.

Signed-off-by: Yuanfang Zhang <quic_yuanfang at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-etm4x-core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 66d44a404ad0..5da2c523c30a 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -906,6 +906,7 @@ static void etm4_disable_hw(void *info)
 	tsb_csync();
 	etm4x_relaxed_write32(csa, control, TRCPRGCTLR);
 
+	isb();
 	/* wait for TRCSTATR.PMSTABLE to go to '1' */
 	if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1))
 		dev_err(etm_dev,
-- 
2.34.1



From smostafa at google.com  Wed Dec  4 02:14:04 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Wed, 4 Dec 2024 10:14:04 +0000
Subject: [PATCH v10 2/4] iommu/io-pgtable-arm: Re-use the pgtable walk
 for iova_to_phys
In-Reply-To: <20241028213146.238941-3-robdclark@gmail.com>
References: <20241028213146.238941-1-robdclark@gmail.com>
 <20241028213146.238941-3-robdclark@gmail.com>
Message-ID: <Z1ArbJbqAnD-Qn52@google.com>

Hi Rob,

On Mon, Oct 28, 2024 at 02:31:38PM -0700, Rob Clark wrote:
> From: Rob Clark <robdclark at chromium.org>
> 
> Re-use the generic pgtable walk path.
> 
> Signed-off-by: Rob Clark <robdclark at chromium.org>
Reviewed-by: Mostafa Saleh <smostafa at google.com>

Thanks,
Mostafa

> ---
>  drivers/iommu/io-pgtable-arm.c | 74 +++++++++++++++++-----------------
>  1 file changed, 37 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 7e9c0f8ae138..88b128c77893 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -712,42 +712,6 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
>  				data->start_level, ptep);
>  }
>  
> -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> -					 unsigned long iova)
> -{
> -	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
> -	arm_lpae_iopte pte, *ptep = data->pgd;
> -	int lvl = data->start_level;
> -
> -	do {
> -		/* Valid IOPTE pointer? */
> -		if (!ptep)
> -			return 0;
> -
> -		/* Grab the IOPTE we're interested in */
> -		ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
> -		pte = READ_ONCE(*ptep);
> -
> -		/* Valid entry? */
> -		if (!pte)
> -			return 0;
> -
> -		/* Leaf entry? */
> -		if (iopte_leaf(pte, lvl, data->iop.fmt))
> -			goto found_translation;
> -
> -		/* Take it to the next level */
> -		ptep = iopte_deref(pte, data);
> -	} while (++lvl < ARM_LPAE_MAX_LEVELS);
> -
> -	/* Ran out of page tables to walk */
> -	return 0;
> -
> -found_translation:
> -	iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1);
> -	return iopte_to_paddr(pte, data) | iova;
> -}
> -
>  struct io_pgtable_walk_data {
>  	struct io_pgtable		*iop;
>  	void				*data;
> @@ -763,6 +727,41 @@ static int __arm_lpae_iopte_walk(struct arm_lpae_io_pgtable *data,
>  				 arm_lpae_iopte *ptep,
>  				 int lvl);
>  
> +struct iova_to_phys_data {
> +	arm_lpae_iopte pte;
> +	int lvl;
> +};
> +
> +static int visit_iova_to_phys(struct io_pgtable_walk_data *walk_data, int lvl,
> +			      arm_lpae_iopte *ptep, size_t size)
> +{
> +	struct iova_to_phys_data *data = walk_data->data;
> +	data->pte = *ptep;
> +	data->lvl = lvl;
> +	return 0;
> +}
> +
> +static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> +					 unsigned long iova)
> +{
> +	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
> +	struct iova_to_phys_data d;
> +	struct io_pgtable_walk_data walk_data = {
> +		.data = &d,
> +		.visit = visit_iova_to_phys,
> +		.addr = iova,
> +		.end = iova + 1,
> +	};
> +	int ret;
> +
> +	ret = __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
> +	if (ret)
> +		return 0;
> +
> +	iova &= (ARM_LPAE_BLOCK_SIZE(d.lvl, data) - 1);
> +	return iopte_to_paddr(d.pte, data) | iova;
> +}
> +
>  static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
>  			    struct io_pgtable_walk_data *walk_data,
>  			    arm_lpae_iopte *ptep, int lvl)
> @@ -780,8 +779,9 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
>  		return 0;
>  	}
>  
> -	if (WARN_ON(!iopte_table(pte, lvl)))
> +	if (!iopte_table(pte, lvl)) {
>  		return -EINVAL;
> +	}
>  
>  	ptep = iopte_deref(pte, data);
>  	return __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);
> -- 
> 2.47.0
> 


From suzuki.poulose at arm.com  Wed Dec  4 02:21:11 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 4 Dec 2024 10:21:11 +0000
Subject: [PATCH] coresight-etm4x: add isb() before reading the TRCSTATR
In-Reply-To: <20241204101320.3692167-1-quic_yuanfang@quicinc.com>
References: <20241204101320.3692167-1-quic_yuanfang@quicinc.com>
Message-ID: <7860c682-f6a8-4b97-86bc-c5e706a7bb34@arm.com>

Hi


On 04/12/2024 10:13, yuanfang zhang wrote:
> From: Yuanfang Zhang <quic_yuanfang at quicinc.com>
> 
> As recommended by section 4.3.7 ("Synchronization when using system
> instructions to progrom the trace unit") of ARM IHI 0064H.b, the
> self-hosted trace analyzer must perform a Context synchronization
> event between writing to the TRCPRGCTLR and reading the TRCSTATR.
> 

Thanks for the patch. Please could you add the above in a comment
in the changes below ?

Also, add Fixes tag ? (It may go all the way back to initial support)

Otherwise looks sensible to me.

Suzuki

> Signed-off-by: Yuanfang Zhang <quic_yuanfang at quicinc.com>
> ---
>   drivers/hwtracing/coresight/coresight-etm4x-core.c | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 66d44a404ad0..5da2c523c30a 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -906,6 +906,7 @@ static void etm4_disable_hw(void *info)
>   	tsb_csync();
>   	etm4x_relaxed_write32(csa, control, TRCPRGCTLR);
>   
> +	isb();
>   	/* wait for TRCSTATR.PMSTABLE to go to '1' */
>   	if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1))
>   		dev_err(etm_dev,



From smostafa at google.com  Wed Dec  4 02:21:02 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Wed, 4 Dec 2024 10:21:02 +0000
Subject: [PATCH v10 3/4] iommu/io-pgtable-arm: Add way to debug pgtable
 walk
In-Reply-To: <20241028213146.238941-4-robdclark@gmail.com>
References: <20241028213146.238941-1-robdclark@gmail.com>
 <20241028213146.238941-4-robdclark@gmail.com>
Message-ID: <Z1AtDgLD0SDUxDHl@google.com>

Hi Rob,

On Mon, Oct 28, 2024 at 02:31:39PM -0700, Rob Clark wrote:
> From: Rob Clark <robdclark at chromium.org>
> 
> Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> would be traversed for a given iova access.
> 
> Signed-off-by: Rob Clark <robdclark at chromium.org>
> ---
>  drivers/iommu/io-pgtable-arm.c | 25 +++++++++++++++++++++++++
>  include/linux/io-pgtable.h     | 15 +++++++++++++++
>  2 files changed, 40 insertions(+)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 88b128c77893..6739e1fa54ec 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -762,6 +762,30 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
>  	return iopte_to_paddr(d.pte, data) | iova;
>  }
>  
> +static int visit_pgtable_walk(struct io_pgtable_walk_data *walk_data, int lvl,
> +			      arm_lpae_iopte *ptep, size_t size)
> +{
> +	struct arm_lpae_io_pgtable_walk_data *data = walk_data->data;
> +	data->ptes[data->level++] = *ptep;
> +	return 0;
> +}
> +
> +static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
> +				 void *wd)
> +{
> +	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
> +	struct io_pgtable_walk_data walk_data = {
> +		.data = wd,
> +		.visit = visit_pgtable_walk,
> +		.addr = iova,
> +		.end = iova + 1,
> +	};
> +
> +	((struct arm_lpae_io_pgtable_walk_data *)wd)->level = 0;

I think this is a bit fragile, as it only works because the walk spans
one address, otherwise it breaks, the visitor will keep incrementing
the level. IMO, this should be removed, and the visitor already knows
the level as it's passed as an argument, so something like this:

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 6739e1fa54ec..bc73f9edae8a 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -766,7 +766,8 @@ static int visit_pgtable_walk(struct io_pgtable_walk_data *walk_data, int lvl,
 			      arm_lpae_iopte *ptep, size_t size)
 {
 	struct arm_lpae_io_pgtable_walk_data *data = walk_data->data;
-	data->ptes[data->level++] = *ptep;
+	data->ptes[lvl] = *ptep;
+	data->level = lvl + 1;
 	return 0;
 }
 
@@ -781,8 +782,6 @@ static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
 		.end = iova + 1,
 	};
 
-	((struct arm_lpae_io_pgtable_walk_data *)wd)->level = 0;
-
 	return __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
 }
 
Thanks,
Mostafa
> +
> +	return __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
> +}
> +
>  static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
>  			    struct io_pgtable_walk_data *walk_data,
>  			    arm_lpae_iopte *ptep, int lvl)
> @@ -937,6 +961,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
>  		.unmap_pages	= arm_lpae_unmap_pages,
>  		.iova_to_phys	= arm_lpae_iova_to_phys,
>  		.read_and_clear_dirty = arm_lpae_read_and_clear_dirty,
> +		.pgtable_walk	= arm_lpae_pgtable_walk,
>  	};
>  
>  	return data;
> diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
> index b1ecfc3cd5bc..d7bfbf351975 100644
> --- a/include/linux/io-pgtable.h
> +++ b/include/linux/io-pgtable.h
> @@ -178,12 +178,26 @@ struct io_pgtable_cfg {
>  	};
>  };
>  
> +/**
> + * struct arm_lpae_io_pgtable_walk_data - information from a pgtable walk
> + *
> + * @ptes:     The recorded PTE values from the walk
> + * @level:    The level of the last PTE
> + *
> + * @level also specifies the last valid index in @ptes
> + */
> +struct arm_lpae_io_pgtable_walk_data {
> +	u64 ptes[4];
> +	int level;
> +};
> +
>  /**
>   * struct io_pgtable_ops - Page table manipulation API for IOMMU drivers.
>   *
>   * @map_pages:    Map a physically contiguous range of pages of the same size.
>   * @unmap_pages:  Unmap a range of virtually contiguous pages of the same size.
>   * @iova_to_phys: Translate iova to physical address.
> + * @pgtable_walk: (optional) Perform a page table walk for a given iova.
>   *
>   * These functions map directly onto the iommu_ops member functions with
>   * the same names.
> @@ -197,6 +211,7 @@ struct io_pgtable_ops {
>  			      struct iommu_iotlb_gather *gather);
>  	phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops,
>  				    unsigned long iova);
> +	int (*pgtable_walk)(struct io_pgtable_ops *ops, unsigned long iova, void *wd);
>  	int (*read_and_clear_dirty)(struct io_pgtable_ops *ops,
>  				    unsigned long iova, size_t size,
>  				    unsigned long flags,
> -- 
> 2.47.0
> 


From thomas.richard at bootlin.com  Wed Dec  4 02:21:39 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Wed, 4 Dec 2024 11:21:39 +0100
Subject: [PATCH] arm64: dts: ti: k3-j784s4: use ti,j7200-padconf
 compatible
In-Reply-To: <Z1An9_auC3dRyPln@gaggiata.pivistrello.it>
References: <20241113-j784s4-s2r-pinctrl-v1-1-19aeb62739bc@bootlin.com>
 <20241119190106.GA70080@francesco-nb>
 <6e47e420-84c4-4539-ba54-5e1e939a37a5@bootlin.com>
 <Z1An9_auC3dRyPln@gaggiata.pivistrello.it>
Message-ID: <e405b65e-e9b7-451b-9b40-64d5d9cafa98@bootlin.com>

On 12/4/24 10:59, Francesco Dolcini wrote:
> Hello Thomas,
> thanks for the update.
> 
> On Wed, Dec 04, 2024 at 10:08:43AM +0100, Thomas Richard wrote:
>> On 11/19/24 20:01, Francesco Dolcini wrote:
>>> Hello Thomas and TI folks,
>>>
>>> On Wed, Nov 13, 2024 at 11:43:05AM +0100, Thomas Richard wrote:
>>>> Like on j7200, pinctrl contexts shall be saved and restored during
>>>> suspend-to-ram.
>>>>
>>>> So use ti,j7200-padconf compatible.
>>>>
>>>> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
>>>> ---
>>>> Use ti,j7200-padconf compatible to save and restore pinctrl contexts during
>>>> suspend-to-ram.
>>>> ---
>>>>  arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi       |  6 +++---
>>>>  arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 12 ++++++------
>>>
>>> Do j784s4 supports any kind of low power mode and/or suspend to ram? My
>>> understanding was that this was not supported, but maybe there is some
>>> details that was lost when I was told this information.
>>
>> We are working on suspend-to-ram support for j7200 and j784s4.
>> During suspend-to-ram the SoC is fully powered-off (thanks to the PMIC
>> which powers off all the power rails except the DDR which is in
>> self-refresh), like on j7200.
>> Please let me know if you want more details.
> 
> ok, that's quite different from the common suspend-to-ram we use to have
> implemented on other SoC. You would have some boot firmware (likely U-Boot)
> code executing during resume, taking some different code path, in a similar way
> to what it is being done for the partial-io support on am62p. It's going to be
> more similar to hibernation from some point of view.

If you want more details you can have a look to this presentation [1]
(from my colleague Gregory CLEMENT).

[1] https://www.youtube.com/watch?v=sN4krurp8bM

> 
> Do you expect to have this feature nicely integrated within the standard
> suspend/resume "framework" in Linux?

Yes.

Regards,

Thomas


From arnd at kernel.org  Wed Dec  4 02:28:53 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:53 +0100
Subject: [PATCH 04/15] ARM: deprecate support for ARM1136r0
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-5-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

This CPU revision remains a special case as it is now incompatible
with CONFIG_SMP. Only the Nokia N8x0 is used in practice, and even
that one is fairly rare these days, so let's plan to remove all of
them after the 2025 LTS kernel release.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/mach-imx/Kconfig       |  5 ++++-
 arch/arm/mach-omap2/Kconfig     | 15 ++++++++++++---
 arch/arm/mach-versatile/Kconfig |  5 ++++-
 arch/arm/mm/Kconfig             |  2 ++
 4 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index dce9cfc510b7..de9da57f0db4 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -39,12 +39,15 @@ if ARCH_MULTI_V6
 comment "ARM1136 platforms"
 
 config SOC_IMX31
-	bool "i.MX31 support"
+	bool "i.MX31 support (DEPRECATED)"
 	select CPU_ARM1136R0
 	select MXC_AVIC
 	help
 	  This enables support for Freescale i.MX31 processor
 
+	  This SoC is scheduled for removal in early 2026,
+	  since it uses the ARM1136r0 CPU revision.
+
 config SOC_IMX35
 	bool "i.MX35 support"
 	select CPU_ARM1136R1
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index c2b379850f59..3c4e55eb9d1d 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -207,18 +207,24 @@ comment "OMAP Core Type"
 	depends on ARCH_OMAP2
 
 config SOC_OMAP2420
-	bool "OMAP2420 support"
+	bool "OMAP2420 support (DEPRECATED)"
 	depends on ARCH_OMAP2
 	default y
 	select OMAP_DM_SYSTIMER
 	select OMAP_DM_TIMER
 	select SOC_HAS_OMAP2_SDRC
+	help
+	  This SoC is scheduled for removal in early 2026,
+	  since it uses the ARM1136r0 CPU revision.
 
 config SOC_OMAP2430
-	bool "OMAP2430 support"
+	bool "OMAP2430 support (DEPRECATED)"
 	depends on ARCH_OMAP2
 	default y
 	select SOC_HAS_OMAP2_SDRC
+	help
+	  This SoC is scheduled for removal in early 2026,
+	  since it uses the ARM1136r0 CPU revision.
 
 config SOC_OMAP3430
 	bool "OMAP3430 support"
@@ -249,11 +255,14 @@ config MACH_NOKIA_N810_WIMAX
 	bool
 
 config MACH_NOKIA_N8X0
-	bool "Nokia N800/N810"
+	bool "Nokia N800/N810 (DEPRECATED)"
 	depends on SOC_OMAP2420
 	default y
 	select MACH_NOKIA_N810
 	select MACH_NOKIA_N810_WIMAX
+	help
+	  This machine is scheduled for removal in early 2026,
+	  since it uses the ARM1136r0 CPU revision.
 
 endmenu
 
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
index de42da7de8c8..ef7c02dd0d8e 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -110,11 +110,14 @@ config INTEGRATOR_CM1026EJS
 	select CPU_ARM1026
 
 config INTEGRATOR_CM1136JFS
-	bool "Integrator/CM1136JF-S core module"
+	bool "Integrator/CM1136JF-S core module (DEPRECATED)"
 	depends on ARCH_INTEGRATOR_AP
 	depends on ARCH_MULTI_V6
 	depends on !SMP
 	select CPU_ARM1136R0
+	help
+	  This machine is scheduled for removal in early 2026,
+	  since it uses the ARM1136r0 CPU revision.
 
 config ARCH_INTEGRATOR_CP
 	bool "Support Integrator/CP platform"
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index f5c1c6f82892..6c970c81d079 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -410,6 +410,8 @@ config CPU_ARM1136R0
 	help
 	  These early revisions of ARM1136 lack support for the
 	  ARMv6k extensions for multiprocessing.
+	  Support for this revision is scheduled for removal
+	  from the kernel in early 2026.
 
 config CPU_ARM1136R1
 	bool
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:28:54 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:54 +0100
Subject: [PATCH 05/15] ARM: turn CONFIG_ATAGS off by default
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-6-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Only a very small number of machines remain that rely on
traditional board files with the ATAGS boot data instead
of devicetree, and we have not accepted new ones for
a decade.

Most of the remaining ones are on their way out of the
kernel, but the Kconfig option that controls ATAGS
is still enabled by default.

To reflect the actual status of ATAGS support and alert
the remaining users of upstream and out-of-tree platforms
with this, chanyge it to being default-disabled and
add a dependency on CONFIG_EXPERT.

The board specific defconfig files that rely on ATAGS
are changed to turn on both EXPERT and ATAGS if they
were not doing thath already, and the ones that explicitly
turned it off before no longer need to.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/Kconfig                       | 13 ++++++++-----
 arch/arm/configs/am200epdkit_defconfig |  1 +
 arch/arm/configs/aspeed_g4_defconfig   |  1 -
 arch/arm/configs/aspeed_g5_defconfig   |  1 -
 arch/arm/configs/assabet_defconfig     |  2 ++
 arch/arm/configs/at91_dt_defconfig     |  1 -
 arch/arm/configs/collie_defconfig      |  1 +
 arch/arm/configs/dove_defconfig        |  1 +
 arch/arm/configs/footbridge_defconfig  |  1 +
 arch/arm/configs/h3600_defconfig       |  2 ++
 arch/arm/configs/integrator_defconfig  |  1 -
 arch/arm/configs/jornada720_defconfig  |  2 ++
 arch/arm/configs/moxart_defconfig      |  1 -
 arch/arm/configs/mps2_defconfig        |  1 -
 arch/arm/configs/multi_v4t_defconfig   |  1 -
 arch/arm/configs/mv78xx0_defconfig     |  1 +
 arch/arm/configs/neponset_defconfig    |  2 ++
 arch/arm/configs/netwinder_defconfig   |  2 ++
 arch/arm/configs/omap1_defconfig       |  1 +
 arch/arm/configs/rpc_defconfig         |  2 ++
 arch/arm/configs/s3c6400_defconfig     |  2 ++
 arch/arm/configs/sama5_defconfig       |  1 -
 arch/arm/configs/sama7_defconfig       |  1 -
 arch/arm/configs/spitz_defconfig       |  1 +
 arch/arm/configs/stm32_defconfig       |  1 -
 arch/arm/configs/wpcm450_defconfig     |  1 -
 26 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 54f5cc12dea4..2167f71f184b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1400,12 +1400,15 @@ config ARCH_WANT_FLAT_DTB_INSTALL
 
 config ATAGS
 	bool "Support for the traditional ATAGS boot data passing"
-	default y
+	depends on EXPERT
 	help
-	  This is the traditional way of passing data to the kernel at boot
-	  time. If you are solely relying on the flattened device tree (or
-	  the ARM_ATAG_DTB_COMPAT option) then you may unselect this option
-	  to remove ATAGS support from your kernel binary.
+	  This is the traditional way of passing data to the kernel at
+	  boot but is now only used by a few of the oldest ARMv4 and
+	  ARMv5 machines.  Users that still rely on ATAGS should plan
+	  on migrating to devicetree based booting.
+
+	  Support for ATAGS will be removed when the last machine using
+	  it is either converted to DT or removed.
 
 config DEPRECATED_PARAM_STRUCT
 	bool "Provide old way to pass kernel parameters"
diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
index 55c5c08a5f96..7a67118f8489 100644
--- a/arch/arm/configs/am200epdkit_defconfig
+++ b/arch/arm/configs/am200epdkit_defconfig
@@ -7,6 +7,7 @@ CONFIG_EXPERT=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_PXA=y
 CONFIG_ARCH_GUMSTIX=y
+CONFIG_ATAGS=y
 CONFIG_CMDLINE="console=ttyS0,115200n8 root=1f01 rootfstype=jffs2"
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig
index 7a73c891371d..ebbd5ad12c73 100644
--- a/arch/arm/configs/aspeed_g4_defconfig
+++ b/arch/arm/configs/aspeed_g4_defconfig
@@ -23,7 +23,6 @@ CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G4=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_UACCESS_WITH_MEMCPY=y
-# CONFIG_ATAGS is not set
 CONFIG_JUMP_LABEL=y
 CONFIG_STRICT_KERNEL_RWX=y
 # CONFIG_BLK_DEBUG_FS is not set
diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig
index 61cee1e7ebea..99da4f5be25a 100644
--- a/arch/arm/configs/aspeed_g5_defconfig
+++ b/arch/arm/configs/aspeed_g5_defconfig
@@ -29,7 +29,6 @@ CONFIG_VMSPLIT_2G=y
 CONFIG_NR_CPUS=2
 CONFIG_HIGHMEM=y
 CONFIG_UACCESS_WITH_MEMCPY=y
-# CONFIG_ATAGS is not set
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_KERNEL_MODE_NEON=y
diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig
index df63889b0c4c..e4264fdac2e5 100644
--- a/arch/arm/configs/assabet_defconfig
+++ b/arch/arm/configs/assabet_defconfig
@@ -1,11 +1,13 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
 CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_ASSABET=y
 # CONFIG_AEABI is not set
+CONFIG_ATAGS=y
 CONFIG_CMDLINE="mem=32M console=ttySA0,38400n8 initrd=0xc0800000,3M root=/dev/ram"
 CONFIG_FPE_NWFPE=y
 CONFIG_PM=y
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index be9e02b133e6..5950f8274646 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -19,7 +19,6 @@ CONFIG_SOC_SAM9X60=y
 CONFIG_SOC_SAM9X7=y
 # CONFIG_ATMEL_CLOCKSOURCE_PIT is not set
 CONFIG_UACCESS_WITH_MEMCPY=y
-# CONFIG_ATAGS is not set
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index ea95e339f51b..7a6fd164e263 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -9,6 +9,7 @@ CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_COLLIE=y
+CONFIG_ATAGS=y
 CONFIG_CMDLINE="noinitrd root=/dev/mtdblock2 rootfstype=jffs2 fbcon=rotate:1"
 CONFIG_PM=y
 # CONFIG_SWAP is not set
diff --git a/arch/arm/configs/dove_defconfig b/arch/arm/configs/dove_defconfig
index a0d77193ceb6..8cfeec7415b2 100644
--- a/arch/arm/configs/dove_defconfig
+++ b/arch/arm/configs/dove_defconfig
@@ -8,6 +8,7 @@ CONFIG_ARCH_MULTI_V7=y
 CONFIG_ARCH_DOVE=y
 CONFIG_MACH_CM_A510=y
 CONFIG_HIGHMEM=y
+CONFIG_ATAGS=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_VFP=y
diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig
index e8bf9847d35d..0872dba5de79 100644
--- a/arch/arm/configs/footbridge_defconfig
+++ b/arch/arm/configs/footbridge_defconfig
@@ -10,6 +10,7 @@ CONFIG_ARCH_FOOTBRIDGE=y
 CONFIG_ARCH_EBSA285_HOST=y
 CONFIG_ARCH_NETWINDER=y
 # CONFIG_AEABI is not set
+CONFIG_ATAGS=y
 CONFIG_FPE_NWFPE=y
 CONFIG_FPE_NWFPE_XP=y
 CONFIG_MODULES=y
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index 0923d331190a..3e8da62d959d 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -4,11 +4,13 @@ CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
 CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_H3600=y
 # CONFIG_CPU_FREQ_STAT is not set
+CONFIG_ATAGS=y
 CONFIG_MODULES=y
 CONFIG_NET=y
 CONFIG_UNIX=y
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index ba38ec810a61..82180381bf3c 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -13,7 +13,6 @@ CONFIG_ARCH_INTEGRATOR=y
 CONFIG_ARCH_INTEGRATOR_AP=y
 CONFIG_INTEGRATOR_IMPD1=y
 CONFIG_ARCH_INTEGRATOR_CP=y
-# CONFIG_ATAGS is not set
 CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp"
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index 46f0d8eed82d..036a96d2b72a 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -1,11 +1,13 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
 CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_JORNADA720=y
 CONFIG_SA1100_JORNADA720_SSP=y
 CONFIG_PM=y
+CONFIG_ATAGS=y
 CONFIG_MODULES=y
 CONFIG_NET=y
 CONFIG_PACKET=y
diff --git a/arch/arm/configs/moxart_defconfig b/arch/arm/configs/moxart_defconfig
index 86a6edb50df0..32e3c8692cb2 100644
--- a/arch/arm/configs/moxart_defconfig
+++ b/arch/arm/configs/moxart_defconfig
@@ -16,7 +16,6 @@ CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_MOXART=y
 CONFIG_MACH_UC7112LX=y
-# CONFIG_ATAGS is not set
 CONFIG_ARM_APPENDED_DTB=y
 # CONFIG_SWAP is not set
 # CONFIG_COMPAT_BRK is not set
diff --git a/arch/arm/configs/mps2_defconfig b/arch/arm/configs/mps2_defconfig
index e995e50537ef..cacf3876f6e4 100644
--- a/arch/arm/configs/mps2_defconfig
+++ b/arch/arm/configs/mps2_defconfig
@@ -16,7 +16,6 @@ CONFIG_ARCH_MPS2=y
 CONFIG_SET_MEM_PARAM=y
 CONFIG_DRAM_BASE=0x21000000
 CONFIG_DRAM_SIZE=0x1000000
-# CONFIG_ATAGS is not set
 # CONFIG_SUSPEND is not set
 # CONFIG_BLOCK is not set
 CONFIG_BINFMT_FLAT=y
diff --git a/arch/arm/configs/multi_v4t_defconfig b/arch/arm/configs/multi_v4t_defconfig
index 84811b78cc59..0704358e6c39 100644
--- a/arch/arm/configs/multi_v4t_defconfig
+++ b/arch/arm/configs/multi_v4t_defconfig
@@ -17,7 +17,6 @@ CONFIG_INTEGRATOR_IMPD1=y
 CONFIG_INTEGRATOR_CM720T=y
 CONFIG_INTEGRATOR_CM920T=y
 CONFIG_INTEGRATOR_CM922T_XA10=y
-# CONFIG_ATAGS is not set
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_ARM_CLPS711X_CPUIDLE=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index 512445c755da..68ea1fabc00c 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -12,6 +12,7 @@ CONFIG_ARCH_MULTI_V5=y
 CONFIG_ARCH_MV78XX0=y
 CONFIG_MACH_TERASTATION_WXL=y
 CONFIG_HIGHMEM=y
+CONFIG_ATAGS=y
 CONFIG_VFP=y
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig
index 7a7b6a896f85..6d35eae8311b 100644
--- a/arch/arm/configs/neponset_defconfig
+++ b/arch/arm/configs/neponset_defconfig
@@ -1,12 +1,14 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
 CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_ASSABET=y
 CONFIG_ASSABET_NEPONSET=y
 # CONFIG_AEABI is not set
+CONFIG_ATAGS=y
 CONFIG_ZBOOT_ROM_TEXT=0x80000
 CONFIG_ZBOOT_ROM_BSS=0xc1000000
 CONFIG_ZBOOT_ROM=y
diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig
index 7ff70439458d..77d4a2b5916b 100644
--- a/arch/arm/configs/netwinder_defconfig
+++ b/arch/arm/configs/netwinder_defconfig
@@ -1,10 +1,12 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
 CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_FOOTBRIDGE=y
 CONFIG_ARCH_NETWINDER=y
 # CONFIG_AEABI is not set
+CONFIG_ATAGS=y
 CONFIG_DEPRECATED_PARAM_STRUCT=y
 CONFIG_CMDLINE="root=0x801"
 CONFIG_FPE_NWFPE=y
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index 589ee6b68e08..3b487a25c8b7 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -28,6 +28,7 @@ CONFIG_MACH_OMAP_PALMTE=y
 CONFIG_MACH_SX1=y
 CONFIG_MACH_NOKIA770=y
 CONFIG_MACH_AMS_DELTA=y
+CONFIG_ATAGS=y
 CONFIG_CMDLINE="root=1f03 rootfstype=jffs2"
 # CONFIG_SUSPEND is not set
 CONFIG_PM=y
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig
index 23f10216c615..b75fc8570348 100644
--- a/arch/arm/configs/rpc_defconfig
+++ b/arch/arm/configs/rpc_defconfig
@@ -2,12 +2,14 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
 CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_RPC=y
 CONFIG_CPU_SA110=y
 CONFIG_FPE_NWFPE=y
 # CONFIG_AEABI is not set
+CONFIG_ATAGS=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
diff --git a/arch/arm/configs/s3c6400_defconfig b/arch/arm/configs/s3c6400_defconfig
index a37e6ac40825..64378bb55be5 100644
--- a/arch/arm/configs/s3c6400_defconfig
+++ b/arch/arm/configs/s3c6400_defconfig
@@ -2,8 +2,10 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_ARCH_MULTI_V6=y
 # CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_EXPERT=y
 CONFIG_ARCH_S3C64XX=y
 CONFIG_MACH_WLF_CRAGG_6410=y
+CONFIG_ATAGS=y
 CONFIG_CMDLINE="console=ttySAC0,115200 root=/dev/ram init=/linuxrc initrd=0x51000000,6M ramdisk_size=6144"
 CONFIG_VFP=y
 CONFIG_MODULES=y
diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig
index e447329398d5..84cfc5c3584e 100644
--- a/arch/arm/configs/sama5_defconfig
+++ b/arch/arm/configs/sama5_defconfig
@@ -13,7 +13,6 @@ CONFIG_SOC_SAMA5D3=y
 CONFIG_SOC_SAMA5D4=y
 # CONFIG_ATMEL_CLOCKSOURCE_PIT is not set
 CONFIG_UACCESS_WITH_MEMCPY=y
-# CONFIG_ATAGS is not set
 CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
 CONFIG_VFP=y
 CONFIG_NEON=y
diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 1a2e93c8ee71..650bced07bc4 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -19,7 +19,6 @@ CONFIG_ATMEL_CLOCKSOURCE_TCB=y
 # CONFIG_CPU_SW_DOMAIN_PAN is not set
 CONFIG_ARCH_FORCE_MAX_ORDER=14
 CONFIG_UACCESS_WITH_MEMCPY=y
-# CONFIG_ATAGS is not set
 CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk ignore_loglevel"
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index adf3422e0836..bffd4fe566ea 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -10,6 +10,7 @@ CONFIG_ARCH_PXA=y
 CONFIG_PXA_SHARPSL=y
 CONFIG_MACH_AKITA=y
 CONFIG_MACH_BORZOI=y
+CONFIG_ATAGS=y
 CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2   debug"
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 3baec075d1ef..2fc1eee042d2 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -20,7 +20,6 @@ CONFIG_SET_MEM_PARAM=y
 CONFIG_DRAM_BASE=0x90000000
 CONFIG_FLASH_MEM_BASE=0x08000000
 CONFIG_FLASH_SIZE=0x00200000
-# CONFIG_ATAGS is not set
 CONFIG_XIP_KERNEL=y
 CONFIG_XIP_PHYS_ADDR=0x08008000
 CONFIG_BINFMT_FLAT=y
diff --git a/arch/arm/configs/wpcm450_defconfig b/arch/arm/configs/wpcm450_defconfig
index 2edcf5f1a826..b4194afeb209 100644
--- a/arch/arm/configs/wpcm450_defconfig
+++ b/arch/arm/configs/wpcm450_defconfig
@@ -14,7 +14,6 @@ CONFIG_ARCH_NPCM=y
 CONFIG_ARCH_WPCM450=y
 CONFIG_CPU_DCACHE_WRITETHROUGH=y
 CONFIG_UACCESS_WITH_MEMCPY=y
-# CONFIG_ATAGS is not set
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_CPU_IDLE=y
 CONFIG_KPROBES=y
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:28:55 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:55 +0100
Subject: [PATCH 06/15] ARM: update DEPRECATED_PARAM_STRUCT removal timeline
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-7-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

This configuration option is for the older boot method that preceeded
ATAGS. This was scheduled for removal back in 2001, but the removal
never happened, presumably because nobody cared enough to actually do it,
not because there are any users left.

Add "(DEPRECATED)' to the Kconfig line and update the timeline so we can
remove it next year along with the other options that are not scheduled
for that timeframe.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2167f71f184b..5278764162f8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1411,11 +1411,11 @@ config ATAGS
 	  it is either converted to DT or removed.
 
 config DEPRECATED_PARAM_STRUCT
-	bool "Provide old way to pass kernel parameters"
+	bool "Provide old way to pass kernel parameters (DEPRECATED)"
 	depends on ATAGS
 	help
 	  This was deprecated in 2001 and announced to live on for 5 years.
-	  Some old boot loaders still use this way.
+	  It is now scheduled for removal in early 2025.
 
 # Compressed boot loader in ROM.  Yes, we really want to ask about
 # TEXT and BSS so we preserve their values in the config files.
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:28:56 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:56 +0100
Subject: [PATCH 07/15] ARM: s3c64xx: extend deprecation schedule
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-8-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Mark Brown is still using this machine for regular work, so it should
not be removed as originally scheduled.

Give the platform another year, with the option to extend it further
based on the state of ATAGS support next year.

I expect that we end up removing all of s3c64xx when either Mark has
moved his test setup to other hardware, or when all other ATAGS based
machines are getting removed.

Cc: Mark Brown <broonie at kernel.org>
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/mach-s3c/Kconfig.s3c64xx | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-s3c/Kconfig.s3c64xx b/arch/arm/mach-s3c/Kconfig.s3c64xx
index 8f40af063ad6..3120a40ef102 100644
--- a/arch/arm/mach-s3c/Kconfig.s3c64xx
+++ b/arch/arm/mach-s3c/Kconfig.s3c64xx
@@ -23,10 +23,17 @@ menuconfig ARCH_S3C64XX
 	help
 	  Samsung S3C64XX series based systems
 
-	  The platform is deprecated and scheduled for removal. Please reach to
-	  the maintainers of the platform and linux-samsung-soc at vger.kernel.org if
-	  you still use it.
-	  Without such feedback, the platform will be removed after 2024.
+	  The use of ATAGS based board files is on its way out, and
+	  the only remaining S3C64xx machine in the kernel (Wolfson
+	  Cragganmore 6410) relies on this, without any realistic way
+	  to migrate it to devicetree.
+
+	  Support for S3C64XX will be kept until the 2025 LTS kernel
+	  release and may be removed in early 2026.
+
+	  Please reach out to the maintainers of the platform and
+	  linux-samsung-soc at vger.kernel.org if you use any additional
+	  s3c64xx machines based on devicetree.
 
 if ARCH_S3C64XX
 
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:28:57 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:57 +0100
Subject: [PATCH 08/15] ARM: update FPE_NWFPE help text
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-9-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

The help text is seriously outdated and predates the introduction of
VFP floating point units that were available as early as some ARM926
based systems.

Change the help text to reflect that this is now a legacy feature
and that it will go away along with OABI support in the future.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/Kconfig | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5278764162f8..d92531c3f982 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1661,16 +1661,16 @@ menu "Floating point emulation"
 comment "At least one emulation must be selected"
 
 config FPE_NWFPE
-	bool "NWFPE math emulation"
+	bool "NWFPE math emulation (DEPRECATED)"
 	depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL
 	help
 	  Say Y to include the NWFPE floating point emulator in the kernel.
-	  This is necessary to run most binaries. Linux does not currently
-	  support floating point hardware so you need to say Y here even if
-	  your machine has an FPA or floating point co-processor podule.
 
-	  You may say N here if you are going to load the Acorn FPEmulator
-	  early in the bootup.
+	  This is only used on OABI userspace binaries, either using a
+	  pure OABI (!CONFIG_AEABI) kernel, or the OABI emulation.
+
+	  Support for NWFPE will be removed in the future when OABI
+	  support is removed.
 
 config FPE_NWFPE_XP
 	bool "Support extended precision"
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:28:58 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:58 +0100
Subject: [PATCH 09/15] ARM: mark IWMMXT as deprecated
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-10-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

With no remaining users and support getting removed from future compilers,
there seems little point in keeping iwmmxt around much longer.

On the other hand, the iwmmxt support in the kernel rarely gets in the
way, so there is little cost, so set a removal date of early 2026 for
the moment. If anyone is still using this, it can be extended as long
there is binutils support.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/Kconfig | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d92531c3f982..9e8f100ad514 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -509,13 +509,21 @@ config PLAT_VERSATILE
 source "arch/arm/mm/Kconfig"
 
 config IWMMXT
-	bool "Enable iWMMXt support"
-	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
-	default y if PXA27x || PXA3xx || ARCH_MMP
+	bool "Enable iWMMXt support (DEPRECATED)"
+	depends on PXA27x || PXA3xx || ARCH_MMP
 	help
 	  Enable support for iWMMXt context switching at run time if
 	  running on a CPU that supports it.
 
+	  Machines that actually support this feature are very rare,
+	  and support is deprecated in new gcc-14.  While there were a
+	  few applications that used this in the past, none are known
+	  to still do so.
+
+	  If you use this, please send a patch to remove the
+	  deprecation, otherwise this will be removed in early
+	  2026.
+
 if !MMU
 source "arch/arm/Kconfig-nommu"
 endif
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:28:59 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:59 +0100
Subject: [PATCH 10/15] ARM: deprecate ARCH_DOVE
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-11-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

The Marvell Armada 510 (Dove) platform is supported both as devicetree
and atags/boardfile variants, with varying degrees of hardware support.

Russell was the last known user of the board file version, and there
are very few users overall. Unless Russell still needs this variant,
let's remove it soon, in order to simplify the DT conversion of the
remaining plat-orion machines (mv78xx0 and orion5x).

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/mach-dove/Kconfig | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
index 996888ffcfe7..01e79945ddcf 100644
--- a/arch/arm/mach-dove/Kconfig
+++ b/arch/arm/mach-dove/Kconfig
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 menuconfig ARCH_DOVE
-	bool "Marvell Dove" if ARCH_MULTI_V7
+	bool "Marvell Dove (DEPRECATED)" if ARCH_MULTI_V7
 	depends on ATAGS
 	select CPU_PJ4
 	select GPIOLIB
@@ -11,7 +11,11 @@ menuconfig ARCH_DOVE
 	select PM_GENERIC_DOMAINS if PM
 	select PCI_QUIRKS if PCI
 	help
-	  Support for the Marvell Dove SoC 88AP510
+	  Support for the Marvell Dove SoC 88AP510 using board files.
+
+	  Support for this machine will be removed in early 2025, unless
+	  there is a strong reason to keep it. Users should migrate to
+	  the devicetree-enabled version (CONFIG_MACH_DOVE) instead.
 
 if ARCH_DOVE
 
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:29:00 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:29:00 +0100
Subject: [PATCH 11/15] ARM: PXA: deprecate remaining board file support
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-12-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

In the 2021 board file removal, the gumstix and sharpsl
support was left around in order to make it easier to convert
more of the PXA platform to device tree, given that both
platforms had some level of support in qemu.

As far as I can tell, nobody has worked on additional DT
conversion in that time, and qemu has in turn deprecated
the entire PXA platform.

Schedule the remaining board files for removal now, as they
are unlikely to be of any help in the future. If anyone
wants to revive support for these machines, they can
obviously still contribute device tree based code and
work on updating the corresponding drivers.

Any drivers that are only usable on legacy PXA board files
can also get removed along with the boards, or saved by
adding devicetree support.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/configs/pxa_defconfig |  4 ----
 arch/arm/mach-pxa/Kconfig      | 10 ++++++++--
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig
index 3b9e67546f8c..96cef84dbb8e 100644
--- a/arch/arm/configs/pxa_defconfig
+++ b/arch/arm/configs/pxa_defconfig
@@ -16,10 +16,6 @@ CONFIG_PROFILING=y
 CONFIG_KEXEC=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_PXA=y
-CONFIG_ARCH_GUMSTIX=y
-CONFIG_PXA_SHARPSL=y
-CONFIG_MACH_AKITA=y
-CONFIG_MACH_BORZOI=y
 CONFIG_ARCH_FORCE_MAX_ORDER=8
 CONFIG_CMDLINE="root=/dev/ram0 ro"
 CONFIG_CPU_FREQ=y
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 10e472f4fa43..79d9785453c9 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -57,12 +57,15 @@ if ATAGS
 comment "Legacy board files"
 
 config ARCH_GUMSTIX
-	bool "Gumstix XScale 255 boards"
+	bool "Gumstix XScale 255 boards (DEPRECATED)"
 	select PXA25x
 	help
 	  Say Y here if you intend to run this kernel on
 	  Basix, Connex, ws-200ax, ws-400ax systems
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 choice
 	prompt "Gumstix Carrier/Expansion Board"
 	depends on ARCH_GUMSTIX
@@ -76,7 +79,7 @@ config GUMSTIX_AM300EPD
 endchoice
 
 config PXA_SHARPSL
-	bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
+	bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models (DEPRECATED)"
 	select SHARP_PARAM
 	select SHARP_SCOOP
 	help
@@ -86,6 +89,9 @@ config PXA_SHARPSL
 	  SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
 	  handheld computer.
 
+	  Support for these machines will go away in early 2025,
+	  unless they get converted to device tree.
+
 config PXA_SHARPSL_DETECT_MACH_ID
 	bool "Detect machine ID at run-time in the decompressor"
 	depends on PXA_SHARPSL
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:29:01 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:29:01 +0100
Subject: [PATCH 12/15] ARM: orion5x: mark all board files as deprecated
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-13-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Conversion of the old orion5x board files to devicetree has
stalled over the past few years, so it seems better to remove
the remaining ones in order to allow  cleaning up the device
drivers.

Debian has previously removed the orion/kirkwood kernel
binary from the armel distro, but building custom kernels
from the Debian source code should keep working, so
removing the board files after the 6.12 release ensures
that this remains possible for the Debian Trixie release,
assuming this will use the 6.12 LTS kernel.

Jeremy Peper still plans to convert the Terastation 2 Pro
to devicetree in the future, but that can be done even
after it is removed.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/configs/multi_v5_defconfig |  9 ------
 arch/arm/configs/mvebu_v5_defconfig | 10 ------
 arch/arm/configs/orion5x_defconfig  |  9 ------
 arch/arm/mach-orion5x/Kconfig       | 47 +++++++++++++++++++++++------
 4 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
index e40276a28760..588366672b75 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -23,17 +23,8 @@ CONFIG_ARCH_NPCM=y
 CONFIG_ARCH_WPCM450=y
 CONFIG_ARCH_ORION5X=y
 CONFIG_MACH_RD88F5182_DT=y
-CONFIG_MACH_KUROBOX_PRO=y
-CONFIG_MACH_DNS323=y
-CONFIG_MACH_TS209=y
-CONFIG_MACH_TERASTATION_PRO2=y
-CONFIG_MACH_LINKSTATION_PRO=y
 CONFIG_MACH_LINKSTATION_MINI=y
-CONFIG_MACH_TS409=y
-CONFIG_MACH_TS78XX=y
-CONFIG_MACH_MV2120=y
 CONFIG_MACH_D2NET_DT=y
-CONFIG_MACH_NET2BIG=y
 CONFIG_MACH_MSS2_DT=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_VERSATILE=y
diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig
index b8d20e1d9c5d..b3396964863b 100644
--- a/arch/arm/configs/mvebu_v5_defconfig
+++ b/arch/arm/configs/mvebu_v5_defconfig
@@ -10,18 +10,8 @@ CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_KIRKWOOD=y
 CONFIG_ARCH_ORION5X=y
 CONFIG_MACH_RD88F5182_DT=y
-CONFIG_MACH_KUROBOX_PRO=y
-CONFIG_MACH_DNS323=y
-CONFIG_MACH_TS209=y
-CONFIG_MACH_TERASTATION_PRO2=y
-CONFIG_MACH_LINKSTATION_PRO=y
-CONFIG_MACH_LINKSTATION_LSCHL=y
 CONFIG_MACH_LINKSTATION_MINI=y
-CONFIG_MACH_TS409=y
-CONFIG_MACH_TS78XX=y
-CONFIG_MACH_MV2120=y
 CONFIG_MACH_D2NET_DT=y
-CONFIG_MACH_NET2BIG=y
 CONFIG_MACH_MSS2_DT=y
 CONFIG_HIGHMEM=y
 CONFIG_ARM_APPENDED_DTB=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 8e10c53818a3..664d11938143 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -10,16 +10,7 @@ CONFIG_ARCH_MULTI_V5=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_ORION5X=y
 CONFIG_MACH_RD88F5182_DT=y
-CONFIG_MACH_KUROBOX_PRO=y
-CONFIG_MACH_DNS323=y
-CONFIG_MACH_TS209=y
-CONFIG_MACH_TERASTATION_PRO2=y
-CONFIG_MACH_LINKSTATION_PRO=y
 CONFIG_MACH_LINKSTATION_MINI=y
-CONFIG_MACH_TS409=y
-CONFIG_MACH_TS78XX=y
-CONFIG_MACH_MV2120=y
-CONFIG_MACH_NET2BIG=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_VFP=y
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index ee449ca032d2..cf1bf4cd3733 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -18,7 +18,7 @@ menuconfig ARCH_ORION5X
 if ARCH_ORION5X
 
 config ARCH_ORION5X_DT
-	bool "Marvell Orion5x Flattened Device Tree"
+	def_bool y
 	select ORION_CLK
 	select ORION_IRQCHIP
 	select ORION_TIMER
@@ -37,37 +37,49 @@ config MACH_RD88F5182_DT
 	  Orion-NAS (88F5182) RD2, Flattened Device Tree.
 
 config MACH_KUROBOX_PRO
-	bool "KuroBox Pro"
+	bool "KuroBox Pro (DEPRECATED)"
 	select I2C_BOARDINFO if I2C
 	depends on ATAGS
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  KuroBox Pro platform.
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 config MACH_DNS323
-	bool "D-Link DNS-323"
+	bool "D-Link DNS-323 (DEPRECATED)"
 	select I2C_BOARDINFO if I2C
 	depends on ATAGS
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  D-Link DNS-323 platform.
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 config MACH_TS209
-	bool "QNAP TS-109/TS-209"
+	bool "QNAP TS-109/TS-209 (DEPRECATED)"
 	depends on ATAGS
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  QNAP TS-109/TS-209 platform.
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 config MACH_TERASTATION_PRO2
-	bool "Buffalo Terastation Pro II/Live"
+	bool "Buffalo Terastation Pro II/Live (DEPRECATED)"
 	depends on ATAGS
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Buffalo Terastation Pro II/Live platform.
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 config MACH_LINKSTATION_PRO
-	bool "Buffalo Linkstation Pro/Live"
+	bool "Buffalo Linkstation Pro/Live (DEPRECATED)"
 	depends on ATAGS
 	select I2C_BOARDINFO if I2C
 	help
@@ -75,6 +87,9 @@ config MACH_LINKSTATION_PRO
 	  Buffalo Linkstation Pro/Live platform. Both v1 and
 	  v2 devices are supported.
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 config MACH_LINKSTATION_MINI
 	bool "Buffalo Linkstation Mini (Flattened Device Tree)"
 	select ARCH_ORION5X_DT
@@ -83,26 +98,35 @@ config MACH_LINKSTATION_MINI
 	  Buffalo Linkstation Mini (LS-WSGL) platform.
 
 config MACH_TS409
-	bool "QNAP TS-409"
+	bool "QNAP TS-409 (DEPRECATED)"
 	depends on ATAGS
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  QNAP TS-409 platform.
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 config MACH_TS78XX
-	bool "Technologic Systems TS-78xx"
+	bool "Technologic Systems TS-78xx (DEPRECATED)"
 	depends on ATAGS
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Technologic Systems TS-78xx platform.
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 config MACH_MV2120
-	bool "HP Media Vault mv2120"
+	bool "HP Media Vault mv2120 (DEPRECATED)"
 	depends on ATAGS
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  HP Media Vault mv2120 or mv5100.
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 config MACH_D2NET_DT
 	bool "LaCie d2 Network / Big Disk Network (Flattened Device Tree)"
 	select ARCH_ORION5X_DT
@@ -111,13 +135,16 @@ config MACH_D2NET_DT
 	  LaCie d2 Network NAS.
 
 config MACH_NET2BIG
-	bool "LaCie 2Big Network"
+	bool "LaCie 2Big Network (DEPRECATED)"
 	depends on ATAGS
 	select I2C_BOARDINFO if I2C
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  LaCie 2Big Network NAS.
 
+	  Support for this machine will go away in early 2025,
+	  unless it gets converted to device tree.
+
 config MACH_MSS2_DT
 	bool "Maxtor Shared Storage II (Flattened Device Tree)"
 	select ARCH_ORION5X_DT
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:29:02 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:29:02 +0100
Subject: [PATCH 13/15] ARM: mark mach-sa1100 as deprecated
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-14-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Most of the old StrongARM1100 machines were removed two years ago as part
of a wider cleanup, the remaining four were left either because someone
showed interest in converting them to devicetree, or because they were
still supported by qemu and therefore useful to keep the platform alive.

None of the devicetree conversion actually happened, and qemu has
marked the platform as deprecated, so do the same in the kernel now.

If anyone is still running one of these four machines and planning
to keep updating their kernels, please speak up now so we can adapt
the plans as needed.

If nobody is found using StrongARM1100 any more, it can be removing
during 2025, leaving 6.12-LTS as the last longterm support kernel
for it.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/mach-sa1100/Kconfig | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 0fb4c24cfad5..f3fa215fd254 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 menuconfig ARCH_SA1100
-	bool "SA11x0 Implementations"
+	bool "SA11x0 Implementations (DEPRECATED)"
 	depends on ARCH_MULTI_V4 && !(ARCH_MULTI_V4T || ARCH_MULTI_V5)
 	depends on !(ARCH_MOXART || ARCH_GEMINI)
 	depends on ATAGS
@@ -19,6 +19,9 @@ menuconfig ARCH_SA1100
 	help
 	  Support for StrongARM 11x0 based boards.
 
+	  Support for these machines will go away in 2025,
+	  unless there are any remaining users that speak up.
+
 if ARCH_SA1100
 
 config SA1100_ASSABET
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:29:03 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:29:03 +0100
Subject: [PATCH 14/15] ARM: mark RiscPC as deprecated
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-15-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

This platform is the oldest still supported machine, dating back
to the original 1994 ARM610 version.  The only currently supported
configuration uses an ARMv4 StrongARM but still requires building
for ARMv3 because of the board design not supporting 16-bit
data access.

ARMv3 support has been removed in gcc-9, and the gcc-8 release
is already old but still supported for building the kernel.

The only set of machines that lacks support for 16-bit load/store
instructions (Alpha EV5 and older) was recently removed from
the kernel.

Since there is little hope of this being maintainable much
longer, plan to remove it in early 2025 while it is still expected
to mostly work.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/mach-rpc/Kconfig | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-rpc/Kconfig b/arch/arm/mach-rpc/Kconfig
index 55f6d829b677..90c13eaeec1f 100644
--- a/arch/arm/mach-rpc/Kconfig
+++ b/arch/arm/mach-rpc/Kconfig
@@ -1,5 +1,5 @@
 config ARCH_RPC
-	bool "RiscPC"
+	bool "RiscPC (DEPRECATED)"
 	depends on ARCH_MULTI_V4 && !(ARCH_MULTI_V4T || ARCH_MULTI_V5)
 	depends on !(ARCH_FOOTBRIDGE || ARCH_SA1100 || ARCH_MOXART || ARCH_GEMINI)
 	depends on !CC_IS_CLANG && GCC_VERSION < 90100 && GCC_VERSION >= 60000
@@ -19,3 +19,6 @@ config ARCH_RPC
 	help
 	  On the Acorn Risc-PC, Linux can support the internal IDE disk and
 	  CD-ROM interface, serial and parallel port, and the floppy drive.
+
+	  Support for these machines will go away in 2025,
+	  unless there are any remaining users that speak up.
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:29:04 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:29:04 +0100
Subject: [PATCH 15/15] ARM: mark footbridge as deprecated
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-16-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Along with RiscPC and SA1100, these are the last remaining Intel StrongARM
machines. The Corel NetWinder used to be particular popular in the late
1990s, but was discontinued during the bankruptcy of rebel.com in 2001.
The other machine is the DEC (later Intel) EBSA285 evaluation board that
was made in small numbers in 1997 for software developers.

The footbridge/netwinder platform was the main target for the first Debian
2.0 "Hamm" release on the Arm architecture back in 1998, but was dropped
in Debian 6.0 "Squeeze" in 2011, which only supported ARMv4T and higher
with the EABI based ports as ARMv4 hardware had fallen already out of
use by that time.

Link: http://netwinder.org/
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Russell King <linux at armlinux.org.uk>
Cc: Ralph Siemsen <ralph.siemsen at linaro.org>
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/mach-footbridge/Kconfig | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
index 78189997caa1..1ac37cadb201 100644
--- a/arch/arm/mach-footbridge/Kconfig
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 menuconfig ARCH_FOOTBRIDGE
-	bool "FootBridge Implementations"
+	bool "FootBridge Implementations (DEPRECATED)"
 	depends on ARCH_MULTI_V4 && !(ARCH_MULTI_V4T || ARCH_MULTI_V5)
 	depends on !(ARCH_MOXART || ARCH_GEMINI || ARCH_SA1100)
 	depends on ATAGS
@@ -12,7 +12,10 @@ menuconfig ARCH_FOOTBRIDGE
 	select NEED_MACH_MEMORY_H
 	help
 	  Support for systems based on the DC21285 companion chip
-	  ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
+	  ("FootBridge"), used in the EBSA285 and the Rebel NetWinder.
+
+	  Support for these machines will go away in 2025,
+	  unless there are any remaining users that speak up.
 
 if ARCH_FOOTBRIDGE
 
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:28:49 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:49 +0100
Subject: [PATCH 00/15] ARM: platform and feature deprecation
Message-ID: <20241204102904.1863796-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

This is attempt to bring the source code to the state that we discussed
this summer[1], regarding a timeline for deprecating and removing
features:

 - DEPRECATED_PARAM_STRUCT and ARCH_S3C64XX were meant to be
   removed by now, but get an extension

 - all board files except for OMAP1 and S3C get an tentative
   end-of-life date in either 2025 or early 2026.

 - IWMMXT is scheduled for removal in 2026

 - ARMv6/ARM1136r0 (not ARMv6K/ARM1136r1/ARM1176) is scheduled
   for removal in 2026, along with the OMAP24xx and i.MX31 SoCs
   using it

 - OABI, OABI-compat and NWFPE are confined to StrongARM based
   builds and scheduled for removal once StrongARM is gone.

Regarding actually removing the code, I would plan for linux-6.15 (June
2025), removing both the board files and any drivers that have either
become newly unused or were missed in a previous machine removal series.
For the 2026 removals, I would plan on the release after the next LTS
kernel, most likely 6.19.

The timeline for the three StrongARM platforms is missing feedback from
Russell, who is listed as maintainer for two of them and last confirmed
using all three roughly five years ago[2]. I put those patches last
in the series so they can be dropped if Russell still plans to run
kernels after 6.12-LTS on one or more of these.

      Arnd

[1] https://lore.kernel.org/linux-arm-kernel/2831c5a6-cfbf-4fe0-b51c-0396e5b0aeb7 at app.fastmail.com/
[2] https://lore.kernel.org/linux-arm-kernel/20210109174357.GB1551 at shell.armlinux.org.uk/

Arnd Bergmann (15):
  ARM: use CONFIG_AEABI by default everywhere
  ARM: limit OABI support to StrongARM CPUs
  ARM: rework ARM11 CPU selection logic
  ARM: deprecate support for ARM1136r0
  ARM: turn CONFIG_ATAGS off by default
  ARM: update DEPRECATED_PARAM_STRUCT removal timeline
  ARM: s3c64xx: extend deprecation schedule
  ARM: update FPE_NWFPE help text
  ARM: mark IWMMXT as deprecated
  ARM: deprecate ARCH_DOVE
  ARM: PXA: deprecate remaining board file support
  ARM: orion5x: mark all board files as deprecated
  ARM: mark mach-sa1100 as deprecated
  ARM: mark RiscPC as deprecated
  ARM: mark footbridge as deprecated

 arch/arm/Kconfig                        | 72 +++++++++++++------------
 arch/arm/Kconfig.platforms              |  2 +-
 arch/arm/configs/am200epdkit_defconfig  |  3 +-
 arch/arm/configs/aspeed_g4_defconfig    |  2 -
 arch/arm/configs/aspeed_g5_defconfig    |  1 -
 arch/arm/configs/assabet_defconfig      |  3 ++
 arch/arm/configs/at91_dt_defconfig      |  2 -
 arch/arm/configs/axm55xx_defconfig      |  2 -
 arch/arm/configs/bcm2835_defconfig      |  1 -
 arch/arm/configs/clps711x_defconfig     |  1 -
 arch/arm/configs/collie_defconfig       |  2 +-
 arch/arm/configs/davinci_all_defconfig  |  1 -
 arch/arm/configs/dove_defconfig         |  2 +-
 arch/arm/configs/ep93xx_defconfig       |  1 -
 arch/arm/configs/footbridge_defconfig   |  2 +
 arch/arm/configs/gemini_defconfig       |  1 -
 arch/arm/configs/h3600_defconfig        |  3 +-
 arch/arm/configs/hisi_defconfig         |  1 -
 arch/arm/configs/imx_v4_v5_defconfig    |  1 -
 arch/arm/configs/integrator_defconfig   |  2 -
 arch/arm/configs/ixp4xx_defconfig       |  1 -
 arch/arm/configs/jornada720_defconfig   |  3 +-
 arch/arm/configs/keystone_defconfig     |  1 -
 arch/arm/configs/lpc32xx_defconfig      |  1 -
 arch/arm/configs/mmp2_defconfig         |  1 -
 arch/arm/configs/moxart_defconfig       |  2 -
 arch/arm/configs/mps2_defconfig         |  1 -
 arch/arm/configs/multi_v4t_defconfig    |  2 -
 arch/arm/configs/multi_v5_defconfig     | 10 ----
 arch/arm/configs/mv78xx0_defconfig      |  3 +-
 arch/arm/configs/mvebu_v5_defconfig     | 11 ----
 arch/arm/configs/mxs_defconfig          |  1 -
 arch/arm/configs/neponset_defconfig     |  3 ++
 arch/arm/configs/netwinder_defconfig    |  3 ++
 arch/arm/configs/nhk8815_defconfig      |  1 -
 arch/arm/configs/omap1_defconfig        |  3 +-
 arch/arm/configs/orion5x_defconfig      | 11 ----
 arch/arm/configs/pxa168_defconfig       |  2 -
 arch/arm/configs/pxa3xx_defconfig       |  2 -
 arch/arm/configs/pxa910_defconfig       |  2 -
 arch/arm/configs/pxa_defconfig          |  5 --
 arch/arm/configs/rpc_defconfig          |  3 ++
 arch/arm/configs/s3c6400_defconfig      |  2 +
 arch/arm/configs/sama5_defconfig        |  1 -
 arch/arm/configs/sama7_defconfig        |  1 -
 arch/arm/configs/spear13xx_defconfig    |  1 -
 arch/arm/configs/spitz_defconfig        |  2 +-
 arch/arm/configs/stm32_defconfig        |  1 -
 arch/arm/configs/versatile_defconfig    |  2 -
 arch/arm/configs/vt8500_v6_v7_defconfig |  1 -
 arch/arm/configs/wpcm450_defconfig      |  2 -
 arch/arm/mach-dove/Kconfig              |  8 ++-
 arch/arm/mach-footbridge/Kconfig        |  7 ++-
 arch/arm/mach-imx/Kconfig               |  8 ++-
 arch/arm/mach-omap2/Kconfig             | 17 ++++--
 arch/arm/mach-orion5x/Kconfig           | 47 ++++++++++++----
 arch/arm/mach-pxa/Kconfig               | 10 +++-
 arch/arm/mach-rpc/Kconfig               |  5 +-
 arch/arm/mach-s3c/Kconfig.s3c64xx       | 15 ++++--
 arch/arm/mach-sa1100/Kconfig            |  5 +-
 arch/arm/mach-versatile/Kconfig         | 15 +++---
 arch/arm/mm/Kconfig                     | 26 ++++++++-
 62 files changed, 194 insertions(+), 159 deletions(-)

-- 
2.39.5

Cc: Aaro Koskinen <aaro.koskinen at iki.fi>
Cc: Andrew Lunn <andrew at lunn.ch>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Daniel Mack <daniel at zonque.org>
Cc: Gregory Clement <gregory.clement at bootlin.com>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: "Jeremy J. Peper" <jeremy at jeremypeper.com>
Cc: Kristoffer Ericson <kristoffer.ericson at gmail.com>
Cc: Krzysztof Kozlowski <krzk at kernel.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Mark Brown <broonie at kernel.org>
Cc: Ralph Siemsen <ralph.siemsen at linaro.org>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Cc: Russell King <linux at armlinux.org.uk>
Cc: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
Cc: Tony Lindgren <tony at atomide.com>
Cc: linux-arm-kernel at lists.infradead.org


From arnd at kernel.org  Wed Dec  4 02:28:50 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:50 +0100
Subject: [PATCH 01/15] ARM: use CONFIG_AEABI by default everywhere
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-2-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

On ARMv4 and ARMv5, the default is still to build for OABI, with
CONFIG_AEABI disabled, even though distros and toolchains no longer
support OABI as a target.

Change the default to EABI for all architecture levels and change
the defconfig entries as follows:

 - All machines that used to explicitly enable EABI can drop that line now
 - Machines that are likely to actually use old distros and had NWFPE
   enabled in combination with OABI (rpc, footrbridge, netwinder,
   assabet, neponset) explicitly turn it on now.
 - Machines that already had both EABI and NWFPE disabled in defconfig
   (at91_dt, collie, ep93xx, gemini, h3600, imx_v4_v5, integrator, jornada,
   moxart, multi_v4t, omap1) were likely not usable with either OABI or
   EABI and now use EABI instead implicitly, making it more likely that
   they could work.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/Kconfig                        | 17 ++++++-----------
 arch/arm/configs/am200epdkit_defconfig  |  1 -
 arch/arm/configs/aspeed_g4_defconfig    |  1 -
 arch/arm/configs/assabet_defconfig      |  1 +
 arch/arm/configs/at91_dt_defconfig      |  1 -
 arch/arm/configs/axm55xx_defconfig      |  1 -
 arch/arm/configs/bcm2835_defconfig      |  1 -
 arch/arm/configs/clps711x_defconfig     |  1 -
 arch/arm/configs/collie_defconfig       |  1 -
 arch/arm/configs/davinci_all_defconfig  |  1 -
 arch/arm/configs/dove_defconfig         |  1 -
 arch/arm/configs/ep93xx_defconfig       |  1 -
 arch/arm/configs/footbridge_defconfig   |  1 +
 arch/arm/configs/gemini_defconfig       |  1 -
 arch/arm/configs/h3600_defconfig        |  1 -
 arch/arm/configs/hisi_defconfig         |  1 -
 arch/arm/configs/imx_v4_v5_defconfig    |  1 -
 arch/arm/configs/integrator_defconfig   |  1 -
 arch/arm/configs/ixp4xx_defconfig       |  1 -
 arch/arm/configs/jornada720_defconfig   |  1 -
 arch/arm/configs/keystone_defconfig     |  1 -
 arch/arm/configs/lpc32xx_defconfig      |  1 -
 arch/arm/configs/mmp2_defconfig         |  1 -
 arch/arm/configs/moxart_defconfig       |  1 -
 arch/arm/configs/multi_v4t_defconfig    |  1 -
 arch/arm/configs/multi_v5_defconfig     |  1 -
 arch/arm/configs/mv78xx0_defconfig      |  2 --
 arch/arm/configs/mvebu_v5_defconfig     |  1 -
 arch/arm/configs/mxs_defconfig          |  1 -
 arch/arm/configs/neponset_defconfig     |  1 +
 arch/arm/configs/netwinder_defconfig    |  1 +
 arch/arm/configs/nhk8815_defconfig      |  1 -
 arch/arm/configs/omap1_defconfig        |  2 --
 arch/arm/configs/orion5x_defconfig      |  2 --
 arch/arm/configs/pxa168_defconfig       |  2 --
 arch/arm/configs/pxa3xx_defconfig       |  2 --
 arch/arm/configs/pxa910_defconfig       |  2 --
 arch/arm/configs/pxa_defconfig          |  1 -
 arch/arm/configs/rpc_defconfig          |  1 +
 arch/arm/configs/spear13xx_defconfig    |  1 -
 arch/arm/configs/spitz_defconfig        |  1 -
 arch/arm/configs/versatile_defconfig    |  1 -
 arch/arm/configs/vt8500_v6_v7_defconfig |  1 -
 arch/arm/configs/wpcm450_defconfig      |  1 -
 44 files changed, 11 insertions(+), 55 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 202397be76d8..f8f127650ace 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1163,19 +1163,14 @@ config ARM_PATCH_IDIV
 config AEABI
 	bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && \
 		!CPU_V7M && !CPU_V6 && !CPU_V6K && !CC_IS_CLANG
-	default CPU_V7 || CPU_V7M || CPU_V6 || CPU_V6K || CC_IS_CLANG
+	default y
 	help
-	  This option allows for the kernel to be compiled using the latest
-	  ARM ABI (aka EABI).  This is only useful if you are using a user
-	  space environment that is also compiled with EABI.
-
-	  Since there are major incompatibilities between the legacy ABI and
-	  EABI, especially with regard to structure member alignment, this
-	  option also changes the kernel syscall calling convention to
-	  disambiguate both ABIs and allow for backward compatibility support
-	  (selected with CONFIG_OABI_COMPAT).
+	  The Arm EABI is the default ABI on all modern Linux
+	  distributions, replacing the obsolete and "OABI" that was
+	  commonly used on ARMv4 distributions before ca. 2013.
 
-	  To use this you need GCC version 4.0.0 or later.
+	  Everyone should enable this, as support for OABI user space
+	  was dropped in gcc-4.8 and most distributions after ca. 2013.
 
 config OABI_COMPAT
 	bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
index 134a559aba3d..22397d45f4a0 100644
--- a/arch/arm/configs/am200epdkit_defconfig
+++ b/arch/arm/configs/am200epdkit_defconfig
@@ -7,7 +7,6 @@ CONFIG_EXPERT=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_PXA=y
 CONFIG_ARCH_GUMSTIX=y
-CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
 CONFIG_CMDLINE="console=ttyS0,115200n8 root=1f01 rootfstype=jffs2"
 CONFIG_MODULES=y
diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig
index 28b724d59e7e..7a73c891371d 100644
--- a/arch/arm/configs/aspeed_g4_defconfig
+++ b/arch/arm/configs/aspeed_g4_defconfig
@@ -22,7 +22,6 @@ CONFIG_KEXEC=y
 CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G4=y
 CONFIG_VMSPLIT_2G=y
-CONFIG_AEABI=y
 CONFIG_UACCESS_WITH_MEMCPY=y
 # CONFIG_ATAGS is not set
 CONFIG_JUMP_LABEL=y
diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig
index 07ab9eaac4af..df63889b0c4c 100644
--- a/arch/arm/configs/assabet_defconfig
+++ b/arch/arm/configs/assabet_defconfig
@@ -5,6 +5,7 @@ CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_ASSABET=y
+# CONFIG_AEABI is not set
 CONFIG_CMDLINE="mem=32M console=ttySA0,38400n8 initrd=0xc0800000,3M root=/dev/ram"
 CONFIG_FPE_NWFPE=y
 CONFIG_PM=y
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index f2596a1b2f7d..be9e02b133e6 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -18,7 +18,6 @@ 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
 # CONFIG_ATAGS is not set
 CONFIG_ARM_APPENDED_DTB=y
diff --git a/arch/arm/configs/axm55xx_defconfig b/arch/arm/configs/axm55xx_defconfig
index 516689dc6cf1..39b06d59d87a 100644
--- a/arch/arm/configs/axm55xx_defconfig
+++ b/arch/arm/configs/axm55xx_defconfig
@@ -38,7 +38,6 @@ CONFIG_PCIE_AXXIA=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=16
 CONFIG_HOTPLUG_CPU=y
-CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
 CONFIG_HIGHMEM=y
 CONFIG_ARM_APPENDED_DTB=y
diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index b5f0bd8dd536..1a9af028635a 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -26,7 +26,6 @@ CONFIG_CRASH_DUMP=y
 CONFIG_ARCH_MULTI_V6=y
 CONFIG_ARCH_BCM=y
 CONFIG_ARCH_BCM2835=y
-CONFIG_AEABI=y
 CONFIG_SECCOMP=y
 CONFIG_KEXEC=y
 CONFIG_CPU_FREQ=y
diff --git a/arch/arm/configs/clps711x_defconfig b/arch/arm/configs/clps711x_defconfig
index 6fa3477e6b02..2e993845b5a8 100644
--- a/arch/arm/configs/clps711x_defconfig
+++ b/arch/arm/configs/clps711x_defconfig
@@ -6,7 +6,6 @@ CONFIG_RD_LZMA=y
 CONFIG_EXPERT=y
 CONFIG_JUMP_LABEL=y
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_AEABI=y
 # CONFIG_COREDUMP is not set
 CONFIG_SLUB_TINY=y
 CONFIG_NET=y
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 42cb1c854118..ea95e339f51b 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -10,7 +10,6 @@ CONFIG_ARCH_MULTI_V4=y
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_COLLIE=y
 CONFIG_CMDLINE="noinitrd root=/dev/mtdblock2 rootfstype=jffs2 fbcon=rotate:1"
-CONFIG_FPE_NWFPE=y
 CONFIG_PM=y
 # CONFIG_SWAP is not set
 CONFIG_SLUB_TINY=y
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 3474e475373a..604ec294913d 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -18,7 +18,6 @@ CONFIG_ARCH_DAVINCI_DA830=y
 CONFIG_ARCH_DAVINCI_DA850=y
 CONFIG_DAVINCI_MUX_DEBUG=y
 CONFIG_DAVINCI_MUX_WARNINGS=y
-CONFIG_AEABI=y
 CONFIG_SECCOMP=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
diff --git a/arch/arm/configs/dove_defconfig b/arch/arm/configs/dove_defconfig
index 2849d17f5856..a0d77193ceb6 100644
--- a/arch/arm/configs/dove_defconfig
+++ b/arch/arm/configs/dove_defconfig
@@ -7,7 +7,6 @@ CONFIG_EXPERT=y
 CONFIG_ARCH_MULTI_V7=y
 CONFIG_ARCH_DOVE=y
 CONFIG_MACH_CM_A510=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig
index 7dece9d98828..f68de8de1885 100644
--- a/arch/arm/configs/ep93xx_defconfig
+++ b/arch/arm/configs/ep93xx_defconfig
@@ -18,7 +18,6 @@ CONFIG_MACH_EDB9315=y
 CONFIG_MACH_EDB9315A=y
 CONFIG_MACH_TS72XX=y
 CONFIG_MACH_VISION_EP9307=y
-CONFIG_AEABI=y
 CONFIG_CMDLINE="console=ttyAM0,115200 root=/dev/nfs ip=bootp"
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig
index 5f6963687ee4..589b7b1df8c6 100644
--- a/arch/arm/configs/footbridge_defconfig
+++ b/arch/arm/configs/footbridge_defconfig
@@ -11,6 +11,7 @@ CONFIG_ARCH_EBSA285_HOST=y
 CONFIG_ARCH_NETWINDER=y
 CONFIG_FPE_NWFPE=y
 CONFIG_FPE_NWFPE_XP=y
+# CONFIG_AEABI is not set
 CONFIG_MODULES=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_ACORN_PARTITION=y
diff --git a/arch/arm/configs/gemini_defconfig b/arch/arm/configs/gemini_defconfig
index 7b1daec630cb..5860b2fe7d1f 100644
--- a/arch/arm/configs/gemini_defconfig
+++ b/arch/arm/configs/gemini_defconfig
@@ -11,7 +11,6 @@ CONFIG_KEXEC=y
 CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_GEMINI=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_CMDLINE="console=ttyS0,115200n8"
 CONFIG_PM=y
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index 4e272875c797..0923d331190a 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -9,7 +9,6 @@ CONFIG_ARCH_MULTI_V4=y
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_H3600=y
 # CONFIG_CPU_FREQ_STAT is not set
-CONFIG_FPE_NWFPE=y
 CONFIG_MODULES=y
 CONFIG_NET=y
 CONFIG_UNIX=y
diff --git a/arch/arm/configs/hisi_defconfig b/arch/arm/configs/hisi_defconfig
index e19c1039fb93..d91975e95f3d 100644
--- a/arch/arm/configs/hisi_defconfig
+++ b/arch/arm/configs/hisi_defconfig
@@ -10,7 +10,6 @@ CONFIG_ARCH_HIP04=y
 CONFIG_ARCH_HIX5HD2=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=16
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index 875c8cdbada7..15c588649378 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -15,7 +15,6 @@ CONFIG_ARCH_MXC=y
 CONFIG_SOC_IMX1=y
 CONFIG_SOC_IMX25=y
 CONFIG_SOC_IMX27=y
-CONFIG_AEABI=y
 CONFIG_PM_DEBUG=y
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index 61711d4bbf74..ba38ec810a61 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -13,7 +13,6 @@ CONFIG_ARCH_INTEGRATOR=y
 CONFIG_ARCH_INTEGRATOR_AP=y
 CONFIG_INTEGRATOR_IMPD1=y
 CONFIG_ARCH_INTEGRATOR_CP=y
-CONFIG_AEABI=y
 # CONFIG_ATAGS is not set
 CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp"
 CONFIG_CPU_FREQ=y
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index 3cb995b9616a..908edafd6d4a 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -9,7 +9,6 @@ CONFIG_EXPERT=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_IXP4XX=y
 CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_AEABI=y
 CONFIG_CMDLINE="console=ttyS0,115200"
 CONFIG_STRICT_KERNEL_RWX=y
 CONFIG_STRICT_MODULE_RWX=y
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index e6ec768f42e2..46f0d8eed82d 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -5,7 +5,6 @@ CONFIG_ARCH_MULTI_V4=y
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_JORNADA720=y
 CONFIG_SA1100_JORNADA720_SSP=y
-CONFIG_FPE_NWFPE=y
 CONFIG_PM=y
 CONFIG_MODULES=y
 CONFIG_NET=y
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index c1291ca290b2..abf542e37e43 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -22,7 +22,6 @@ CONFIG_PCI_KEYSTONE=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
 CONFIG_ARM_PSCI=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_VFP=y
 CONFIG_NEON=y
diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig
index 98e267213b21..7ef893f05f34 100644
--- a/arch/arm/configs/lpc32xx_defconfig
+++ b/arch/arm/configs/lpc32xx_defconfig
@@ -10,7 +10,6 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_EXPERT=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_LPC32XX=y
-CONFIG_AEABI=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="console=ttyS0,115200n81 root=/dev/ram0"
diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig
index f6f9e135353e..61fbedf55fe9 100644
--- a/arch/arm/configs/mmp2_defconfig
+++ b/arch/arm/configs/mmp2_defconfig
@@ -4,7 +4,6 @@ CONFIG_PREEMPT=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_MMP=y
-CONFIG_AEABI=y
 CONFIG_MACH_MMP2_DT=y
 CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS2,38400 mem=128M user_debug=255 earlyprintk"
 CONFIG_VFP=y
diff --git a/arch/arm/configs/moxart_defconfig b/arch/arm/configs/moxart_defconfig
index 34d079e03b3c..86a6edb50df0 100644
--- a/arch/arm/configs/moxart_defconfig
+++ b/arch/arm/configs/moxart_defconfig
@@ -16,7 +16,6 @@ CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_MOXART=y
 CONFIG_MACH_UC7112LX=y
-CONFIG_AEABI=y
 # CONFIG_ATAGS is not set
 CONFIG_ARM_APPENDED_DTB=y
 # CONFIG_SWAP is not set
diff --git a/arch/arm/configs/multi_v4t_defconfig b/arch/arm/configs/multi_v4t_defconfig
index 27d650635d9b..84811b78cc59 100644
--- a/arch/arm/configs/multi_v4t_defconfig
+++ b/arch/arm/configs/multi_v4t_defconfig
@@ -17,7 +17,6 @@ CONFIG_INTEGRATOR_IMPD1=y
 CONFIG_INTEGRATOR_CM720T=y
 CONFIG_INTEGRATOR_CM920T=y
 CONFIG_INTEGRATOR_CM922T_XA10=y
-CONFIG_AEABI=y
 # CONFIG_ATAGS is not set
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
index 3f4ddcf49ec7..e40276a28760 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -37,7 +37,6 @@ CONFIG_MACH_NET2BIG=y
 CONFIG_MACH_MSS2_DT=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_VERSATILE=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index 3343f72de7ea..512445c755da 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -11,9 +11,7 @@ CONFIG_ARCH_MULTI_V5=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_MV78XX0=y
 CONFIG_MACH_TERASTATION_WXL=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
-CONFIG_FPE_NWFPE=y
 CONFIG_VFP=y
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig
index 2467afd32146..b8d20e1d9c5d 100644
--- a/arch/arm/configs/mvebu_v5_defconfig
+++ b/arch/arm/configs/mvebu_v5_defconfig
@@ -23,7 +23,6 @@ CONFIG_MACH_MV2120=y
 CONFIG_MACH_D2NET_DT=y
 CONFIG_MACH_NET2BIG=y
 CONFIG_MACH_MSS2_DT=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 43bc1255a5db..24dae023a491 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -17,7 +17,6 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_PERF_EVENTS=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_MXS=y
-CONFIG_AEABI=y
 CONFIG_MODULES=y
 CONFIG_MODULE_FORCE_LOAD=y
 CONFIG_MODULE_UNLOAD=y
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig
index 2227f86100ad..a8833b2ce335 100644
--- a/arch/arm/configs/neponset_defconfig
+++ b/arch/arm/configs/neponset_defconfig
@@ -11,6 +11,7 @@ CONFIG_ZBOOT_ROM_BSS=0xc1000000
 CONFIG_ZBOOT_ROM=y
 CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) load_ramdisk=1 prompt_ramdisk=0 mem=32M noinitrd initrd=0xc0800000,3M"
 CONFIG_FPE_NWFPE=y
+# CONFIG_AEABI is not set
 CONFIG_PM=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig
index e639e6ad02cb..7ff70439458d 100644
--- a/arch/arm/configs/netwinder_defconfig
+++ b/arch/arm/configs/netwinder_defconfig
@@ -4,6 +4,7 @@ CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_FOOTBRIDGE=y
 CONFIG_ARCH_NETWINDER=y
+# CONFIG_AEABI is not set
 CONFIG_DEPRECATED_PARAM_STRUCT=y
 CONFIG_CMDLINE="root=0x801"
 CONFIG_FPE_NWFPE=y
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index ea28ed8991b4..c0b7bfbe2e23 100644
--- a/arch/arm/configs/nhk8815_defconfig
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -12,7 +12,6 @@ CONFIG_KALLSYMS_ALL=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_NOMADIK=y
 CONFIG_MACH_NOMADIK_8815NHK=y
-CONFIG_AEABI=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_SWAP is not set
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index 025b595dd837..589ee6b68e08 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -28,9 +28,7 @@ CONFIG_MACH_OMAP_PALMTE=y
 CONFIG_MACH_SX1=y
 CONFIG_MACH_NOKIA770=y
 CONFIG_MACH_AMS_DELTA=y
-CONFIG_AEABI=y
 CONFIG_CMDLINE="root=1f03 rootfstype=jffs2"
-CONFIG_FPE_NWFPE=y
 # CONFIG_SUSPEND is not set
 CONFIG_PM=y
 CONFIG_MODULES=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 0629b088a584..8e10c53818a3 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -20,10 +20,8 @@ CONFIG_MACH_TS409=y
 CONFIG_MACH_TS78XX=y
 CONFIG_MACH_MV2120=y
 CONFIG_MACH_NET2BIG=y
-CONFIG_AEABI=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_FPE_NWFPE=y
 CONFIG_VFP=y
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig
index ce10fe2104bf..65513b313e88 100644
--- a/arch/arm/configs/pxa168_defconfig
+++ b/arch/arm/configs/pxa168_defconfig
@@ -3,11 +3,9 @@ CONFIG_SYSVIPC=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
-CONFIG_AEABI=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_ARCH_MMP=y
 CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.2.100:/nfsroot/ ip=192.168.2.101:192.168.2.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M"
-CONFIG_FPE_NWFPE=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig
index 381356faf382..42e31ee8e5e2 100644
--- a/arch/arm/configs/pxa3xx_defconfig
+++ b/arch/arm/configs/pxa3xx_defconfig
@@ -7,9 +7,7 @@ CONFIG_KALLSYMS_ALL=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_PXA=y
 CONFIG_MACH_PXA3XX_DT=y
-CONFIG_AEABI=y
 CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=64M debug"
-CONFIG_FPE_NWFPE=y
 CONFIG_MODULES=y
 CONFIG_NET=y
 CONFIG_PACKET=y
diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig
index 1f28aea86014..d8eaf6c42159 100644
--- a/arch/arm/configs/pxa910_defconfig
+++ b/arch/arm/configs/pxa910_defconfig
@@ -10,8 +10,6 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
-CONFIG_AEABI=y
-CONFIG_FPE_NWFPE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig
index 38916ac4bce4..3b9e67546f8c 100644
--- a/arch/arm/configs/pxa_defconfig
+++ b/arch/arm/configs/pxa_defconfig
@@ -20,7 +20,6 @@ CONFIG_ARCH_GUMSTIX=y
 CONFIG_PXA_SHARPSL=y
 CONFIG_MACH_AKITA=y
 CONFIG_MACH_BORZOI=y
-CONFIG_AEABI=y
 CONFIG_ARCH_FORCE_MAX_ORDER=8
 CONFIG_CMDLINE="root=/dev/ram0 ro"
 CONFIG_CPU_FREQ=y
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig
index 24f1fa868230..23f10216c615 100644
--- a/arch/arm/configs/rpc_defconfig
+++ b/arch/arm/configs/rpc_defconfig
@@ -7,6 +7,7 @@ CONFIG_ARCH_MULTI_V4=y
 CONFIG_ARCH_RPC=y
 CONFIG_CPU_SA110=y
 CONFIG_FPE_NWFPE=y
+# CONFIG_AEABI is not set
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig
index a8f992fdb30d..7c7eef615924 100644
--- a/arch/arm/configs/spear13xx_defconfig
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -9,7 +9,6 @@ CONFIG_MACH_SPEAR1340=y
 CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
 # CONFIG_ARM_CPU_TOPOLOGY is not set
-CONFIG_AEABI=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_VFP=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index 294d16ddeb18..adf3422e0836 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -11,7 +11,6 @@ CONFIG_PXA_SHARPSL=y
 CONFIG_MACH_AKITA=y
 CONFIG_MACH_BORZOI=y
 CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2   debug"
-CONFIG_FPE_NWFPE=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index 849118cbbb44..8e89debb5a5b 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -6,7 +6,6 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_VERSATILE=y
-CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
 CONFIG_CMDLINE="root=1f03 mem=32M"
 CONFIG_FPE_NWFPE=y
diff --git a/arch/arm/configs/vt8500_v6_v7_defconfig b/arch/arm/configs/vt8500_v6_v7_defconfig
index 41607a84abc8..2925a1f1dbb6 100644
--- a/arch/arm/configs/vt8500_v6_v7_defconfig
+++ b/arch/arm/configs/vt8500_v6_v7_defconfig
@@ -8,7 +8,6 @@ CONFIG_ARM_ERRATA_720789=y
 CONFIG_ARM_ERRATA_754322=y
 CONFIG_ARM_ERRATA_775420=y
 CONFIG_HAVE_ARM_ARCH_TIMER=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_HIGHPTE=y
 CONFIG_ARM_APPENDED_DTB=y
diff --git a/arch/arm/configs/wpcm450_defconfig b/arch/arm/configs/wpcm450_defconfig
index 45483deab034..2edcf5f1a826 100644
--- a/arch/arm/configs/wpcm450_defconfig
+++ b/arch/arm/configs/wpcm450_defconfig
@@ -13,7 +13,6 @@ CONFIG_PROFILING=y
 CONFIG_ARCH_NPCM=y
 CONFIG_ARCH_WPCM450=y
 CONFIG_CPU_DCACHE_WRITETHROUGH=y
-CONFIG_AEABI=y
 CONFIG_UACCESS_WITH_MEMCPY=y
 # CONFIG_ATAGS is not set
 CONFIG_ARM_APPENDED_DTB=y
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:28:51 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:51 +0100
Subject: [PATCH 02/15] ARM: limit OABI support to StrongARM CPUs
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-3-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

As discussed on the mailing lists, there is no way to build OABI userspace
binaries any more since gcc-4.8, and now support is also getting dropped in
binutils, which will make it impossible to build pure OABI kernels at some
point in the future.

I found no evidence of anyone still sing OABI userspace on embedded systems
that keep getting kernel updates, but there are a few desktop-class machines
that date back to the 1990s using Intel StrongARM processors that were
supported by old versions of Debian, Red Hat or the official Corel
Netwinder distribution.

Add a much stricter Kconfig dependency for both native OABI and OABI_COMPAT
enabled kernels, only allowing either of them to be selected when building
a kernel that targets a StrongARM based machine.

Link: https://lore.kernel.org/lkml/2831c5a6-cfbf-4fe0-b51c-0396e5b0aeb7 at app.fastmail.com/
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/Kconfig                       | 14 +++++++-------
 arch/arm/configs/am200epdkit_defconfig |  1 -
 arch/arm/configs/axm55xx_defconfig     |  1 -
 arch/arm/configs/footbridge_defconfig  |  2 +-
 arch/arm/configs/neponset_defconfig    |  2 +-
 arch/arm/configs/versatile_defconfig   |  1 -
 6 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f8f127650ace..54f5cc12dea4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1161,8 +1161,7 @@ config ARM_PATCH_IDIV
 	  code to do integer division.
 
 config AEABI
-	bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && \
-		!CPU_V7M && !CPU_V6 && !CPU_V6K && !CC_IS_CLANG
+	bool "Use the ARM EABI to compile the kernel" if CPU_SA110 || CPU_SA1100
 	default y
 	help
 	  The Arm EABI is the default ABI on all modern Linux
@@ -1172,9 +1171,13 @@ config AEABI
 	  Everyone should enable this, as support for OABI user space
 	  was dropped in gcc-4.8 and most distributions after ca. 2013.
 
+	  Support for OABI mode will be removed from the kernel
+	  once Intel StrongARM CPUs are phased out.
+
 config OABI_COMPAT
 	bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
 	depends on AEABI && !THUMB2_KERNEL
+	depends on CPU_SA110 || CPU_SA1100
 	help
 	  This option preserves the old syscall interface along with the
 	  new (ARM EABI) one. It also provides a compatibility layer to
@@ -1187,11 +1190,8 @@ config OABI_COMPAT
 	  selected, since there is no way yet to sensibly distinguish
 	  between calling conventions during filtering.
 
-	  If you know you'll be using only pure EABI user space then you
-	  can say N here. If this option is not selected and you attempt
-	  to execute a legacy ABI binary then the result will be
-	  UNPREDICTABLE (in fact it can be predicted that it won't work
-	  at all). If in doubt say N.
+	  Support for OABI_COMPAT will be removed from the kernel
+	  once Intel StrongARM CPUs are phased out.
 
 config ARCH_SELECT_MEMORY_MODEL
 	def_bool y
diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
index 22397d45f4a0..55c5c08a5f96 100644
--- a/arch/arm/configs/am200epdkit_defconfig
+++ b/arch/arm/configs/am200epdkit_defconfig
@@ -7,7 +7,6 @@ CONFIG_EXPERT=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_PXA=y
 CONFIG_ARCH_GUMSTIX=y
-# CONFIG_OABI_COMPAT is not set
 CONFIG_CMDLINE="console=ttyS0,115200n8 root=1f01 rootfstype=jffs2"
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
diff --git a/arch/arm/configs/axm55xx_defconfig b/arch/arm/configs/axm55xx_defconfig
index 39b06d59d87a..9d14b987ee94 100644
--- a/arch/arm/configs/axm55xx_defconfig
+++ b/arch/arm/configs/axm55xx_defconfig
@@ -38,7 +38,6 @@ CONFIG_PCIE_AXXIA=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=16
 CONFIG_HOTPLUG_CPU=y
-CONFIG_OABI_COMPAT=y
 CONFIG_HIGHMEM=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig
index 589b7b1df8c6..e8bf9847d35d 100644
--- a/arch/arm/configs/footbridge_defconfig
+++ b/arch/arm/configs/footbridge_defconfig
@@ -9,9 +9,9 @@ CONFIG_ARCH_MULTI_V4=y
 CONFIG_ARCH_FOOTBRIDGE=y
 CONFIG_ARCH_EBSA285_HOST=y
 CONFIG_ARCH_NETWINDER=y
+# CONFIG_AEABI is not set
 CONFIG_FPE_NWFPE=y
 CONFIG_FPE_NWFPE_XP=y
-# CONFIG_AEABI is not set
 CONFIG_MODULES=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_ACORN_PARTITION=y
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig
index a8833b2ce335..7a7b6a896f85 100644
--- a/arch/arm/configs/neponset_defconfig
+++ b/arch/arm/configs/neponset_defconfig
@@ -6,12 +6,12 @@ CONFIG_ARCH_MULTI_V4=y
 CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_ASSABET=y
 CONFIG_ASSABET_NEPONSET=y
+# CONFIG_AEABI is not set
 CONFIG_ZBOOT_ROM_TEXT=0x80000
 CONFIG_ZBOOT_ROM_BSS=0xc1000000
 CONFIG_ZBOOT_ROM=y
 CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) load_ramdisk=1 prompt_ramdisk=0 mem=32M noinitrd initrd=0xc0800000,3M"
 CONFIG_FPE_NWFPE=y
-# CONFIG_AEABI is not set
 CONFIG_PM=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index 8e89debb5a5b..bb9eb9ccbbde 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -6,7 +6,6 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_VERSATILE=y
-CONFIG_OABI_COMPAT=y
 CONFIG_CMDLINE="root=1f03 mem=32M"
 CONFIG_FPE_NWFPE=y
 CONFIG_VFP=y
-- 
2.39.5



From arnd at kernel.org  Wed Dec  4 02:28:52 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Dec 2024 11:28:52 +0100
Subject: [PATCH 03/15] ARM: rework ARM11 CPU selection logic
In-Reply-To: <20241204102904.1863796-1-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
Message-ID: <20241204102904.1863796-4-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Support for SMP on ARM1136r0 has been broken for a while, and nobody
is working on fixing it. I had a plan to change ARMv6 support to no
longer coexist in a common kernel with ARMv7 CPUs but instead ARMv5 and
below. This would have addressed the problem, but after a recent mailing
list discussion, we concluded that an easier approach is to just forbid
ARM1136r0 CPU support on SMP-enabled kernels.

This mainly affects users of the Nokia N800/N810 tablets using an
OMAP2420 SoC, which is the only commercial product with an ARM1136r0
that is still supported by the kernel.

The other machines that are still in the same hardware catogory are:

 - TI OMAP2420 H4 reference board
 - TI OMAP2430 SDP software development platform
 - Freescale/NXP i.MX31 Lite Development Kit
 - Buglabs i.MX31 Bug 1.x prototype
 - Arm Integrator/AP with CM1136JF-S core module

To my knowledge, none of these have any actual users aside from
reference boards being used more easily test the platforms.

There are also a few ARM1136r1 machines, which implement the
ARMv6K SMP support (barriers, atomics and TLS):

 - Eukrea CPUIMX35 reference platform
 - Freescale/NXP i.MX35 Product Development Kit
 - ARM Integrator/CP/IM-LT3 with ARM1136J Core Tile
 - ARM Realview/EB with ARM1136J Core Tile

Again, these are mainly reference implementations rather than
actual products, but since they support ARMv6K, they should
continue to work correctly in SMP-enabled kernels. For the
ARM Core Tile, I have not found a datasheet but instead use
the revision based on what the respective virtual models
report.

All the other ARMv6 platforms use an ARM1176 with ARMv6K,
VMSAv7 and Trustzone support.

To avoid the broken configuration, annotate the ARM1136 based
machines with specific CPU_ARM1136R0 or CPU_ARM1136R2 symbols
in Kconfig and make the r0 variants depend on !SMP.

Link: https://lore.kernel.org/linux-arm-kernel/2831c5a6-cfbf-4fe0-b51c-0396e5b0aeb7 at app.fastmail.com/T/
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/Kconfig.platforms      |  2 +-
 arch/arm/mach-imx/Kconfig       |  3 ++-
 arch/arm/mach-omap2/Kconfig     |  2 +-
 arch/arm/mach-versatile/Kconfig | 10 +++++-----
 arch/arm/mm/Kconfig             | 24 +++++++++++++++++++++++-
 5 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/arch/arm/Kconfig.platforms b/arch/arm/Kconfig.platforms
index 845ab08e20a4..e56d47eadfdf 100644
--- a/arch/arm/Kconfig.platforms
+++ b/arch/arm/Kconfig.platforms
@@ -37,7 +37,7 @@ config ARCH_MULTI_V4_V5
 config ARCH_MULTI_V6
 	bool "ARMv6 based platforms (ARM11)"
 	select ARCH_MULTI_V6_V7
-	select CPU_V6K
+	select CPU_1176
 
 config ARCH_MULTI_V7
 	bool "ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)"
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index e4fe059cd861..dce9cfc510b7 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -40,13 +40,14 @@ comment "ARM1136 platforms"
 
 config SOC_IMX31
 	bool "i.MX31 support"
-	select CPU_V6
+	select CPU_ARM1136R0
 	select MXC_AVIC
 	help
 	  This enables support for Freescale i.MX31 processor
 
 config SOC_IMX35
 	bool "i.MX35 support"
+	select CPU_ARM1136R1
 	select MXC_AVIC
 	help
 	  This enables support for Freescale i.MX35 processor
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 821727eefd5a..c2b379850f59 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -9,7 +9,7 @@ config ARCH_OMAP2
 	bool "TI OMAP2"
 	depends on ARCH_MULTI_V6
 	select ARCH_OMAP2PLUS
-	select CPU_V6
+	select CPU_ARM1136R0
 	select OMAP_HWMOD
 	select SOC_HAS_OMAP2_SDRC
 
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
index 513618078440..de42da7de8c8 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -113,7 +113,8 @@ config INTEGRATOR_CM1136JFS
 	bool "Integrator/CM1136JF-S core module"
 	depends on ARCH_INTEGRATOR_AP
 	depends on ARCH_MULTI_V6
-	select CPU_V6
+	depends on !SMP
+	select CPU_ARM1136R0
 
 config ARCH_INTEGRATOR_CP
 	bool "Support Integrator/CP platform"
@@ -135,7 +136,7 @@ config INTEGRATOR_CTB36
 	bool "Integrator/CTB36 (ARM1136JF-S) core tile"
 	depends on ARCH_INTEGRATOR_CP
 	depends on ARCH_MULTI_V6
-	select CPU_V6
+	select CPU_ARM1136R1
 
 config ARCH_CINTEGRATOR
 	depends on ARCH_INTEGRATOR_CP
@@ -182,7 +183,7 @@ config MACH_REALVIEW_EB
 config REALVIEW_EB_ARM1136
 	bool "Support ARM1136J(F)-S Tile"
 	depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
-	select CPU_V6
+	select CPU_ARM1136R1
 	help
 	  Enable support for the ARM1136 tile fitted to the
 	  Realview(R) Emulation Baseboard platform.
@@ -201,11 +202,10 @@ config REALVIEW_EB_A9MP
 	  Enable support for the Cortex-A9MPCore tile fitted to the
 	  Realview(R) Emulation Baseboard platform.
 
-# ARMv6 CPU without K extensions, but does have the new exclusive ops
 config MACH_REALVIEW_PB1176
 	bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S"
 	depends on ARCH_MULTI_V6
-	select CPU_V6
+	select CPU_ARM1176
 	select HAVE_TCM
 	help
 	  Include support for the ARM(R) RealView(R) Platform Baseboard for
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 2b6f50dd5478..f5c1c6f82892 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -376,6 +376,7 @@ config CPU_PJ4B
 # ARMv6
 config CPU_V6
 	bool
+	depends on !SMP
 	select CPU_32v6
 	select CPU_ABRT_EV6
 	select CPU_CACHE_V6
@@ -386,7 +387,6 @@ config CPU_V6
 	select CPU_PABRT_V6
 	select CPU_THUMB_CAPABLE
 	select CPU_TLB_V6 if MMU
-	select SMP_ON_UP if SMP
 
 # ARMv6k
 config CPU_V6K
@@ -403,6 +403,28 @@ config CPU_V6K
 	select CPU_THUMB_CAPABLE
 	select CPU_TLB_V6 if MMU
 
+config CPU_ARM1136R0
+	bool
+	select CPU_V6
+	depends on !SMP
+	help
+	  These early revisions of ARM1136 lack support for the
+	  ARMv6k extensions for multiprocessing.
+
+config CPU_ARM1136R1
+	bool
+	select CPU_V6K
+	help
+	  Later revisions of ARM1136 add ARMv6k (atomics, barriers
+	  and TLS register) in addition to the features from r0.
+
+config CPU_ARM1176
+	bool
+	select CPU_V6K
+	help
+	  ARM1176 implements ARMv6k, VMSAv7 and Trustzone in
+	  addition to the ARMv6 baseline.
+
 # ARMv7 and ARMv8 architectures
 config CPU_V7
 	bool
-- 
2.39.5



From frank-w at public-files.de  Wed Dec  4 02:33:19 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Wed, 04 Dec 2024 11:33:19 +0100
Subject: =?US-ASCII?Q?Re=3A_=5BPATCH_1/2=5D_dt-bindings=3A_mmc=3A_mtk-sd=3A_Docu?=
 =?US-ASCII?Q?ment_compatibles_that_need_two_register_ranges?=
In-Reply-To: <20241204092855.1365638-2-wenst@chromium.org>
References: <20241204092855.1365638-1-wenst@chromium.org> <20241204092855.1365638-2-wenst@chromium.org>
Message-ID: <4762E5F1-59F2-40D1-9D22-724107623AAB@public-files.de>

Am 4. Dezember 2024 10:28:52 MEZ schrieb Chen-Yu Tsai <wenst at chromium.org>:
>Besides the MT8183's MMC controller and all its compatible derivatives,
>the recently added MT7986 and MT8196 also require two register ranges.
>This is based on the actual device trees.

Hi

Mt7988 is similar to mt7986 (only using different clock settings) and using 2 reg too.

Currently there is no mmc node in mt7988 dts (i currently upstreaming it) so i guess this is why you have not yet noticed it.

See this for more:

https://patchwork.kernel.org/project/linux-mediatek/patch/20241202122602.30734-3-linux at fw-web.de/

Maybe you can add mt7988 compatible here too in v2.

Regards Frank

>Properly enforce this in the binding.
>
>Fixes: 4a8bd2b07d88 ("dt-bindings: mmc: mtk-sd: Add mt7988 SoC")
>Fixes: 58927c9dc4ab ("dt-bindings: mmc: mtk-sd: Add support for MT8196")
>Cc: Frank Wunderlich <frank-w at public-files.de>
>Cc: Andy-ld Lu <andy-ld.lu at mediatek.com>
>Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>---
> Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
>diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
>index f86ebd81f5a5..9ea035928563 100644
>--- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
>+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
>@@ -235,11 +235,18 @@ allOf:
>       properties:
>         compatible:
>           contains:
>-            const: mediatek,mt8183-mmc
>+            enum:
>+              - mediatek,mt7986-mmc
>+              - mediatek,mt8183-mmc
>+              - mediatek,mt8196-mmc
>     then:
>       properties:
>         reg:
>           minItems: 2
>+    else:
>+      properties:
>+        reg:
>+          maxItems: 1
> 
>   - if:
>       properties:


regards Frank


From didi.debian at cknow.org  Wed Dec  4 02:48:02 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Wed, 04 Dec 2024 11:48:02 +0100
Subject: [PATCH v3 3/3] drm/rockchip: Add MIPI DSI2 glue driver for
 RK3588
In-Reply-To: <af1cce1a-c46d-470f-a1b9-bfbc90b46415@rock-chips.com>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241203165450.1501219-4-heiko@sntech.de>
 <af1cce1a-c46d-470f-a1b9-bfbc90b46415@rock-chips.com>
Message-ID: <D62UUZI7C1GD.1YSCGFIH9N60N@cknow.org>

If there's going to be another version (to fix this) ...

On Wed Dec 4, 2024 at 3:16 AM CET, Kever Yang wrote:
> On 2024/12/4 00:54, Heiko Stuebner wrote:
> > From: Heiko Stuebner <heiko.stuebner at cherry.de>
> >
> > This adds the glue code for the MIPI DSI2 bridge on Rockchip SoCs and
> > enables its use on the RK3588.
> >
> > Right now the DSI2 controller is always paired with a DC-phy based on a
> > Samsung IP, so the interface values are set statically for now.
> > This stays true for the upcoming RK3576 as well.
> >
> > Tested-by: Daniel Semkowicz <dse at thaumatec.com>
> > Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
> > ---
> >   drivers/gpu/drm/rockchip/Kconfig              |  10 +
> >   drivers/gpu/drm/rockchip/Makefile             |   1 +
> >   .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c  | 524 ++++++++++++++++++
> >   drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |   2 +
> >   drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |   1 +
> >   5 files changed, 538 insertions(+)
> >   create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> >
> > diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
> > index 448fadd4ba15..84af423b7f90 100644
> > --- a/drivers/gpu/drm/rockchip/Kconfig
> > +++ b/drivers/gpu/drm/rockchip/Kconfig
> > @@ -10,6 +10,7 @@ config DRM_ROCKCHIP
> >   	select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
> >   	select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP
> >   	select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
> > +	select DRM_DW_MIPI_DSI2 if ROCKCHIP_DW_MIPI_DSI2
> >   	select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
> >   	select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
> >   	select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
> > @@ -81,6 +82,15 @@ config ROCKCHIP_DW_MIPI_DSI
> >   	  enable MIPI DSI on RK3288 or RK3399 based SoC, you should
> >   	  select this option.
> >   
> > +config ROCKCHIP_DW_MIPI_DSI2
> > +	bool "Rockchip specific extensions for Synopsys DW MIPI DSI2"
> > +	select GENERIC_PHY_MIPI_DPHY
> > +	help
> > +	  This selects support for Rockchip SoC specific extensions
> > +	  for the Synopsys DesignWare dsi driver. If you want to

... could you then also s/dsi/DSI/ ?

Cheers,
  Diederik

> > +	  enable MIPI DSI on RK3576 or RK3588 based SoC, you should
> > +	  select this option.
> > +
> >   config ROCKCHIP_INNO_HDMI
> >   	bool "Rockchip specific extensions for Innosilicon HDMI"
> >   	select DRM_DISPLAY_HDMI_HELPER
> > diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
> > index 3eab662a5a1d..2b867cebbc12 100644
> > --- a/drivers/gpu/drm/rockchip/Makefile
> > +++ b/drivers/gpu/drm/rockchip/Makefile
> > @@ -13,6 +13,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
> >   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
> >   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o
> >   rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o
> > +rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI2) += dw-mipi-dsi2-rockchip.o
> >   rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
> >   rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
> >   rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o
> > diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> > new file mode 100644
> > index 000000000000..55eed4001634
> > --- /dev/null
> > +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> > @@ -0,0 +1,524 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2024 Rockchip Electronics Co.Ltd
> This should be:
>
> Rockchip Electronics Co., Ltd.
>
> This typo is from vendor kernel, we will correct all this kind of issue locally,
> and Andy is going to correct other files in drm for mainline kernel.
>
> Thanks,
> - Kever
-------------- 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/20241204/b514ef68/attachment.sig>

From jirislaby at kernel.org  Wed Dec  4 03:02:56 2024
From: jirislaby at kernel.org (Jiri Slaby)
Date: Wed, 4 Dec 2024 12:02:56 +0100
Subject: [PATCH v5 1/2] kexec: Consolidate machine_kexec_mask_interrupts()
 implementation
In-Reply-To: <20241130201143.48808-2-farbere@amazon.com>
References: <20241130201143.48808-1-farbere@amazon.com>
 <20241130201143.48808-2-farbere@amazon.com>
Message-ID: <96cdb630-5c9e-4364-93fc-67f9ee34a403@kernel.org>

On 30. 11. 24, 21:11, Eliav Farber wrote:
> Consolidate the machine_kexec_mask_interrupts implementation into a common
> function located in a new file: kernel/irq/kexec.c. This removes duplicate
> implementations from architecture-specific files in arch/arm, arch/arm64,
> arch/powerpc, and arch/riscv, reducing code duplication and improving
> maintainability.
> 
> The new implementation retains architecture-specific behavior for
> CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD, which was previously implemented
> for ARM64. When enabled (currently for ARM64), it clears the active state
> of interrupts forwarded to virtual machines (VMs) before handling other
> interrupt masking operations.
...
> --- a/kernel/irq/Kconfig
> +++ b/kernel/irq/Kconfig
> @@ -154,3 +154,12 @@ config DEPRECATED_IRQ_CPU_ONOFFLINE
>   	bool
>   	depends on CAVIUM_OCTEON_SOC
>   	default CAVIUM_OCTEON_SOC
> +
> +config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
> +	bool "Clear forwarded VM interrupts during kexec"
> +	default n
> +	help
> +	  When enabled, this option allows the kernel to clear the active state
> +	  of interrupts that are forwarded to virtual machines (VMs) during a
> +	  machine kexec. For interrupts that are not forwarded, if supported,
> +	  the kernel will attempt to trigger an End of Interrupt (EOI).

This caught my attention. It looks like you want to allow people 
toggling it? I believe only arch code should turn it on as you do by 
"select", not users.

thanks,
-- 
js
suse labs



From eballetb at redhat.com  Wed Dec  4 03:05:26 2024
From: eballetb at redhat.com (Enric Balletbo i Serra)
Date: Wed, 04 Dec 2024 12:05:26 +0100
Subject: [PATCH v2] arm64: dts: ti: k3-am69-sk: Add USB SuperSpeed support
Message-ID: <20241204-am69sk-dt-usb-v2-1-d59b2ac45c6e@redhat.com>

From: Dasnavis Sabiya <sabiya.d at ti.com>

AM69 SK board has two stacked USB3 connectors:
   1. USB3 (Stacked TypeA + TypeC)
   2. USB3 TypeA Hub interfaced through TUSB8041.

The board uses SERDES0 Lane 3 for USB3 IP. So update the
SerDes lane info for PCIe and USB. Add the pin mux data
and enable USB 3.0 support with its respective SERDES settings.

Signed-off-by: Dasnavis Sabiya <sabiya.d at ti.com>
Signed-off-by: Enric Balletbo i Serra <eballetb at redhat.com>
---
I've been carrying this patch for quite long time in my builds to have
support for USB on my AM69-SK board without problems. For some reason this
patch was never send to upstream or I couldn't find it. So I took the
opportunity, now that I rebased my build, to send upstream.

I have maintained the original author of the downstream patch as is
basically his work.
---
Changes in v2:
- Set dr_mode to otg to fully describe the hardware proprieties
- Link to v1: https://lore.kernel.org/r/20241126-am69sk-dt-usb-v1-1-aa55aed7b89e at redhat.com
---
 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 1e36965a14032ca07143230855e04b9549f1d0d1..353579dedb19a4f9809913570143666f4c4ec53e 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -484,6 +484,12 @@ J784S4_IOPAD(0x09C, PIN_OUTPUT, 0) /* (AF35) MCAN7_TX */
 		>;
 	};
 
+	main_usbss0_pins_default: main-usbss0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0EC, PIN_OUTPUT, 6) /* (AN37) TIMER_IO1.USB0_DRVVBUS */
+		>;
+	};
+
 };
 
 &wkup_pmx0 {
@@ -1299,6 +1305,14 @@ serdes0_pcie_link: phy at 0 {
 		cdns,phy-type = <PHY_TYPE_PCIE>;
 		resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>, <&serdes_wiz0 3>;
 	};
+
+	serdes0_usb_link: phy at 3 {
+		reg = <3>;
+		cdns,num-lanes = <1>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_USB3>;
+		resets = <&serdes_wiz0 4>;
+	};
 };
 
 &serdes_wiz1 {
@@ -1339,3 +1353,22 @@ &pcie3_rc {
 	phy-names = "pcie-phy";
 	num-lanes = <1>;
 };
+
+&usb_serdes_mux {
+	idle-states = <0>; /* USB0 to SERDES0 */
+};
+
+&usbss0 {
+	status = "okay";
+	pinctrl-0 = <&main_usbss0_pins_default>;
+	pinctrl-names = "default";
+	ti,vbus-divider;
+};
+
+&usb0 {
+	status = "okay";
+	dr_mode = "otg";
+	maximum-speed = "super-speed";
+	phys = <&serdes0_usb_link>;
+	phy-names = "cdns3,usb3-phy";
+};

---
base-commit: 7eef7e306d3c40a0c5b9ff6adc9b273cc894dbd5
change-id: 20241126-am69sk-dt-usb-89180ef58f8d

Best regards,
-- 
Enric Balletbo i Serra <eballetb at redhat.com>



From james.clark at linaro.org  Wed Dec  4 03:15:42 2024
From: james.clark at linaro.org (James Clark)
Date: Wed, 4 Dec 2024 11:15:42 +0000
Subject: [PATCH] selftests: arm coresight: sysfsmode testing
In-Reply-To: <20241129083813.3056909-1-lcherian@marvell.com>
References: <20241129083813.3056909-1-lcherian@marvell.com>
Message-ID: <1b7aaa17-48b7-45cd-b468-ef54ca048e31@linaro.org>



On 29/11/2024 8:38 am, Linu Cherian wrote:
> Add sysfs mode selftest for ARM Coresight hardware tracer.
> 
> Signed-off-by: Linu Cherian <lcherian at marvell.com>
> ---
>   .../drivers/hwtracing/coresight/Makefile      |   5 +
>   .../hwtracing/coresight/sysfs_test_trace.sh   | 144 ++++++++++++++++++
>   2 files changed, 149 insertions(+)
>   create mode 100644 tools/testing/selftests/drivers/hwtracing/coresight/Makefile

Hi Linu,

You need to add this path into TARGETS for make install to work:

  TARGETS += drivers/dma-buf
+TARGETS += drivers/hwtracing/coresight
  TARGETS += drivers/s390x/uvdevice


>   create mode 100755 tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> 
> diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/Makefile b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> new file mode 100644
> index 000000000000..7dc68ae1c0a9
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> @@ -0,0 +1,5 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +TEST_PROGS = sysfs_test_trace.sh
> +
> +include ../../../lib.mk
> diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> new file mode 100755
> index 000000000000..0d6307fff1d2
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> @@ -0,0 +1,144 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (C) 2024 Marvell.
> +
> +# Test Arm CoreSight trace capture in sysfs mode
> +# Based on tools/perf/tests/shell/test_arm_coresight.sh
> +
> +glb_err=0
> +
> +arm_cs_report() {
> +	if [ $2 != 0 ]; then
> +		echo "$1: FAIL"
> +		glb_err=$2
> +	else
> +		echo "$1: PASS"
> +	fi
> +}
> +
> +is_device_sink() {
> +	# If the node of "enable_sink" is existed under the device path, this
> +	# means the device is a sink device.
> +

Looks like you still need the skip for TPIU here the same as the Perf 
test. It's an external sink and doesn't have a readable file so the test 
fails.

With those changes, looks good. Thanks for adding the first sysfs test. 
Hopefully we can expand them more in the future.

Reviewed-by: James Clark <james.clark at linaro.org>



From james.clark at linaro.org  Wed Dec  4 03:18:07 2024
From: james.clark at linaro.org (James Clark)
Date: Wed, 4 Dec 2024 11:18:07 +0000
Subject: [PATCH] selftests: arm coresight: sysfsmode testing
In-Reply-To: <115bb206-8401-4475-977d-7dd98a2b872c@linuxfoundation.org>
References: <20241129083813.3056909-1-lcherian@marvell.com>
 <115bb206-8401-4475-977d-7dd98a2b872c@linuxfoundation.org>
Message-ID: <91bb1592-4311-4afe-a728-fc9000b04aca@linaro.org>



On 04/12/2024 12:23 am, Shuah Khan wrote:
> On 11/29/24 01:38, Linu Cherian wrote:
>> Add sysfs mode selftest for ARM Coresight hardware tracer.
> 
> Please add details on what this test does in here. Include
> the output from the test?
> 
> Does this test have dependencies on config? If it does, does
> this test detect and skip if config isn't enabled?
> 

Without the config the test won't find any devices and it will still 
pass. But yes it would still be good to explicitly mark the dependency.

>>
>> Signed-off-by: Linu Cherian <lcherian at marvell.com>
>> ---
>> ? .../drivers/hwtracing/coresight/Makefile????? |?? 5 +
>> ? .../hwtracing/coresight/sysfs_test_trace.sh?? | 144 ++++++++++++++++++
>> ? 2 files changed, 149 insertions(+)
>> ? create mode 100644 tools/testing/selftests/drivers/hwtracing/ 
>> coresight/Makefile
>> ? create mode 100755 tools/testing/selftests/drivers/hwtracing/ 
>> coresight/sysfs_test_trace.sh
>>
>> diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/ 
>> Makefile b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
>> new file mode 100644
>> index 000000000000..7dc68ae1c0a9
>> --- /dev/null
>> +++ b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
>> @@ -0,0 +1,5 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +
>> +TEST_PROGS = sysfs_test_trace.sh
>> +
>> +include ../../../lib.mk
>> diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/ 
>> sysfs_test_trace.sh b/tools/testing/selftests/drivers/hwtracing/ 
>> coresight/sysfs_test_trace.sh
>> new file mode 100755
>> index 000000000000..0d6307fff1d2
>> --- /dev/null
>> +++ b/tools/testing/selftests/drivers/hwtracing/coresight/ 
>> sysfs_test_trace.sh
>> @@ -0,0 +1,144 @@
>> +#!/bin/sh
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2024 Marvell.
>> +
>> +# Test Arm CoreSight trace capture in sysfs mode
>> +# Based on tools/perf/tests/shell/test_arm_coresight.sh
>> +
>> +glb_err=0
>> +
>> +arm_cs_report() {
>> +??? if [ $2 != 0 ]; then
>> +??????? echo "$1: FAIL"
>> +??????? glb_err=$2
>> +??? else
>> +??????? echo "$1: PASS"
>> +??? fi
>> +}
>> +
>> +is_device_sink() {
>> +??? # If the node of "enable_sink" is existed under the device path, 
>> this
>> +??? # means the device is a sink device.
>> +
>> +??? if [ -e "$1/enable_sink" ]; then
>> +
>> +??????? return 0
>> +??? else
>> +??????? return 1
>> +??? fi
>> +}
>> +
>> +# Configure sink for buffer mode
>> +cfg_sink_buf_mode() {
>> +??? sink_dev=$1
>> +??? mode=$2
>> +??? # Set buffer mode if supported
>> +??? if [ -e "$sink_dev/buf_modes_available" ]; then
>> +??????? cat $sink_dev/buf_modes_available | grep -E -q $mode
>> +??????? if [ $? -eq 0 ]; then
>> +??????????? echo $mode > $sink_dev/buf_mode_preferred
>> +??????????? return 0
>> +??????? fi
>> +??? fi
>> +
>> +??? return 1
>> +}
>> +
>> +run_app() {
>> +
>> +??? taskset -c $1 dd if=/dev/urandom? of=/dev/null bs=1M count=64
>> +}
>> +
>> +sysfs_trace() {
>> +??? src_dev=$1
>> +??? sink_dev=$2
>> +??? cpu=$3
>> +
>> +??? # Enable sink device
>> +??? echo 1 > $sink_dev/enable_sink
>> +??? # Enable source device
>> +??? echo 1 > $src_dev/enable_source
>> +
>> +??? # Run app to be traced
>> +??? run_app $cpu
>> +
>> +??? # Read back trace data
>> +??? dd if=/dev/$sink_dev_name of=/tmp/tracedata
>> +
>> +??? # Verify if read is successful
>> +??? err=$?
>> +
>> +??? # Disable source device
>> +??? echo 0 > $src_dev/enable_source
>> +
>> +??? # Diskable sink device
>> +??? echo 0 > $sink_dev/enable_sink
>> +
>> +??? arm_cs_report "CoreSight path testing (CPU$cpu -> 
>> $sink_dev_name)" $err
>> +}
>> +
>> +try_sysfs_trace_resrv_buf() {
>> +??? src_dev=$1
>> +??? sink_dev=$2
>> +??? cpu=$3
>> +
>> +??? # Configure the resrved buffer mode if available
>> +??? cfg_sink_buf_mode $sink_dev "resrv"
>> +??? if [ $? -eq 0 ]; then
>> +??????? echo "Running sysfs trace with resrv buf mode"
>> +??????? sysfs_trace $src_dev $sink_dev $cpu
>> +??????? # Restore buffer mode
>> +??????? cfg_sink_buf_mode $sink_dev "auto"
>> +??????? if [ $? -eq 1 ]; then
>> +??????????? echo "Failed to restore default buf mode"
>> +??????? fi
>> +??? fi
>> +}
>> +
>> +arm_cs_iterate_devices() {
>> +??? src_dev=$1
>> +??? cpu=$3
>> +??? for cdev in $2/connections/out\:*; do
>> +
>> +??????? # Skip testing if it's not a directory
>> +??????? ! [ -d $cdev ] && continue;
>> +
>> +??????? # Read out its symbol link file name
>> +??????? sink_dev=`readlink -f $cdev`
>> +
>> +??????? # Extract device name from path, e.g.
>> +??????? #?? sink_dev = '/sys/devices/platform/20010000.etf/tmc_etf0'
>> +??????? #???? `> sink_dev_name = 'tmc_etf0'
>> +??????? sink_dev_name=$(basename $sink_dev)
>> +
>> +??????? if is_device_sink $sink_dev; then
>> +??????????? # Run trace with resrv buf mode (if available)
>> +??????????? try_sysfs_trace_resrv_buf $src_dev $sink_dev $cpu
>> +
>> +??????????? # Run the default mode
>> +??????????? echo "Running sysfs trace with default settings"
>> +??????????? sysfs_trace $src_dev $sink_dev $cpu
>> +??????? fi
>> +
>> +??????? arm_cs_iterate_devices $src_dev $cdev $cpu
>> +
>> +??? done
>> +}
>> +
>> +arm_cs_etm_traverse_path_test() {
>> +??? # Iterate for every ETM device
>> +??? for dev in /sys/bus/event_source/devices/cs_etm/cpu*; do
>> +??????? # Canonicalize the path
>> +??????? dev=`readlink -f $dev`
>> +
>> +??????? # Find the ETM device belonging to which CPU
>> +??????? cpu=`cat $dev/cpu`
>> +
>> +??????? # Use depth-first search (DFS) to iterate outputs
>> +??????? arm_cs_iterate_devices $dev $dev $cpu
>> +??? done
>> +}
>> +
>> +arm_cs_etm_traverse_path_test
>> +
>> +exit $glb_err
> 
> thanks,
> -- Shuah
> 



From Dave.Martin at arm.com  Wed Dec  4 03:20:32 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 4 Dec 2024 11:20:32 +0000
Subject: [PATCH] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <3da4f6d2-5869-4515-a86a-e821d9276640@arm.com>
References: <20241203100322.1626805-1-kevin.brodsky@arm.com>
 <Z07x69L6Mssncg/7@e133380.arm.com>
 <a9aa36eb-d5c2-4d1c-bf5d-e63e4cb55404@arm.com>
 <Z08l0Q9KO6haeSSI@e133380.arm.com>
 <3da4f6d2-5869-4515-a86a-e821d9276640@arm.com>
Message-ID: <Z1A7ACC+0Vb2bT9p@e133380.arm.com>

On Tue, Dec 03, 2024 at 05:48:10PM +0100, Kevin Brodsky wrote:
> On 03/12/2024 16:37, Dave Martin wrote:
> > Hi,
> >
> > On Tue, Dec 03, 2024 at 04:06:24PM +0100, Kevin Brodsky wrote:
> >> On 03/12/2024 12:56, Dave Martin wrote:
> >>> On Tue, Dec 03, 2024 at 10:03:22AM +0000, Kevin Brodsky wrote:
> >>>> [...]
> >>>> @@ -1462,10 +1462,33 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
> >>>>  			 struct rt_sigframe_user_layout *user, int usig)
> >>>>  {

[...]

> >>>> +	/*
> >>>> +	 * We must not fail from this point onwards. We are going to update
> >>>> +	 * registers, including SP, in order to invoke the signal handler. If
> >>>> +	 * we failed and attempted to deliver a nested SIGSEGV to a handler
> >>>> +	 * after that point, the subsequent sigreturn would end up restoring
> >>>> +	 * the (partial) state for the original signal handler.
> >>>> +	 */
> >>> The same is true at the call site of this function; could problems
> >>> creep back in there?
> >> That's a fair point, I could add a short comment after the call to
> >> setup_return() to clarify this.
> > That would make sense.
> >
> > (Or refactor so that the point of no return is at a function boundary;
> > but since this is a Fixes: patch, it's probably best to keep things
> > simple.)
> 
> I did consider this, in fact this is what I did initially. However I
> then realised that gcs_signal_entry() itself modifies thread state that
> affects control flow. In other words, if it succeeds, then we are
> already in a situation where failure should be avoided, so pulling it
> out of setup_return() wouldn't necessarily be clearer. There may be more
> operations that can fail like gcs_signal_entry() in the future, meaning
> we'd have to "revert" such operations if any fails. I think it makes
> sense for this to be handled in setup_return(). At least we don't need
> to complicate things for now.

That seems fair.  A one-line comment at the call to setup_return()
should be enough.  I guess we can live with the slightly confusing
function naming (since it was already a bit confusing, and this isn't
trivial to sort out).

So, with the comment, feel free to add:

Reviewed-by: Dave Martin <Dave.Martin at arm.com>

Cheers
---Dave


From lkp at intel.com  Wed Dec  4 03:22:40 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 4 Dec 2024 19:22:40 +0800
Subject: [PATCH v2] firmware: smccc: Support optional Arm SMC SOC_ID name
In-Reply-To: <20241203212854.5565-1-paul@os.amperecomputing.com>
References: <20241203212854.5565-1-paul@os.amperecomputing.com>
Message-ID: <202412041926.d2p2hcQe-lkp@intel.com>

Hi Paul,

kernel test robot noticed the following build warnings:

[auto build test WARNING on soc/for-next]
[also build test WARNING on linus/master v6.13-rc1 next-20241203]
[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/Paul-Benoit/firmware-smccc-Support-optional-Arm-SMC-SOC_ID-name/20241204-124243
base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
patch link:    https://lore.kernel.org/r/20241203212854.5565-1-paul%40os.amperecomputing.com
patch subject: [PATCH v2] firmware: smccc: Support optional Arm SMC SOC_ID name
config: arm-sp7021_defconfig (https://download.01.org/0day-ci/archive/20241204/202412041926.d2p2hcQe-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241204/202412041926.d2p2hcQe-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/202412041926.d2p2hcQe-lkp at intel.com/

All warnings (new ones prefixed by >>):

   drivers/firmware/smccc/soc_id.c: In function 'str_fragment_from_reg':
>> drivers/firmware/smccc/soc_id.c:109:23: warning: right shift count >= width of type [-Wshift-count-overflow]
     109 |         dst[4] = (reg >> 32) & 0xff;
         |                       ^~
   drivers/firmware/smccc/soc_id.c:110:23: warning: right shift count >= width of type [-Wshift-count-overflow]
     110 |         dst[5] = (reg >> 40) & 0xff;
         |                       ^~
   drivers/firmware/smccc/soc_id.c:111:23: warning: right shift count >= width of type [-Wshift-count-overflow]
     111 |         dst[6] = (reg >> 48) & 0xff;
         |                       ^~
   drivers/firmware/smccc/soc_id.c:112:23: warning: right shift count >= width of type [-Wshift-count-overflow]
     112 |         dst[7] = (reg >> 56) & 0xff;
         |                       ^~
   drivers/firmware/smccc/soc_id.c: At top level:
>> drivers/firmware/smccc/soc_id.c:37:29: warning: 'smccc_soc_id_name' defined but not used [-Wunused-variable]
      37 | static char __ro_after_init smccc_soc_id_name[136] = "";
         |                             ^~~~~~~~~~~~~~~~~


vim +109 drivers/firmware/smccc/soc_id.c

    36	
  > 37	static char __ro_after_init smccc_soc_id_name[136] = "";
    38	
    39	static int __init smccc_soc_init(void)
    40	{
    41		int soc_id_rev, soc_id_version;
    42		static char soc_id_str[20], soc_id_rev_str[12];
    43		static char soc_id_jep106_id_str[12];
    44	
    45		if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
    46			return 0;
    47	
    48		soc_id_version = arm_smccc_get_soc_id_version();
    49		if (soc_id_version == SMCCC_RET_NOT_SUPPORTED) {
    50			pr_info("ARCH_SOC_ID not implemented, skipping ....\n");
    51			return 0;
    52		}
    53	
    54		if (soc_id_version < 0) {
    55			pr_err("Invalid SoC Version: %x\n", soc_id_version);
    56			return -EINVAL;
    57		}
    58	
    59		soc_id_rev = arm_smccc_get_soc_id_revision();
    60		if (soc_id_rev < 0) {
    61			pr_err("Invalid SoC Revision: %x\n", soc_id_rev);
    62			return -EINVAL;
    63		}
    64	
    65		soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
    66		if (!soc_dev_attr)
    67			return -ENOMEM;
    68	
    69		sprintf(soc_id_rev_str, "0x%08x", soc_id_rev);
    70		sprintf(soc_id_jep106_id_str, "jep106:%02x%02x",
    71			JEP106_BANK_CONT_CODE(soc_id_version),
    72			JEP106_ID_CODE(soc_id_version));
    73		sprintf(soc_id_str, "%s:%04x", soc_id_jep106_id_str,
    74			IMP_DEF_SOC_ID(soc_id_version));
    75	
    76		soc_dev_attr->soc_id = soc_id_str;
    77		soc_dev_attr->revision = soc_id_rev_str;
    78		soc_dev_attr->family = soc_id_jep106_id_str;
    79		soc_dev_attr->machine = smccc_soc_name_init();
    80	
    81		soc_dev = soc_device_register(soc_dev_attr);
    82		if (IS_ERR(soc_dev)) {
    83			kfree(soc_dev_attr);
    84			return PTR_ERR(soc_dev);
    85		}
    86	
    87		pr_info("ID = %s Revision = %s\n", soc_dev_attr->soc_id,
    88			soc_dev_attr->revision);
    89	
    90		return 0;
    91	}
    92	module_init(smccc_soc_init);
    93	
    94	static void __exit smccc_soc_exit(void)
    95	{
    96		if (soc_dev)
    97			soc_device_unregister(soc_dev);
    98		kfree(soc_dev_attr);
    99	}
   100	module_exit(smccc_soc_exit);
   101	
   102	
   103	static inline void str_fragment_from_reg(char *dst, unsigned long reg)
   104	{
   105		dst[0] = (reg >> 0)  & 0xff;
   106		dst[1] = (reg >> 8)  & 0xff;
   107		dst[2] = (reg >> 16) & 0xff;
   108		dst[3] = (reg >> 24) & 0xff;
 > 109		dst[4] = (reg >> 32) & 0xff;
   110		dst[5] = (reg >> 40) & 0xff;
   111		dst[6] = (reg >> 48) & 0xff;
   112		dst[7] = (reg >> 56) & 0xff;
   113	}
   114	

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


From quic_yuanfang at quicinc.com  Wed Dec  4 03:23:32 2024
From: quic_yuanfang at quicinc.com (yuanfang zhang)
Date: Wed, 4 Dec 2024 19:23:32 +0800
Subject: [PATCH v2] coresight-etm4x: add isb() before reading the TRCSTATR
Message-ID: <20241204112332.3706137-1-quic_yuanfang@quicinc.com>

From: Yuanfang Zhang <quic_yuanfang at quicinc.com>

As recommended by section 4.3.7 ("Synchronization when using system
instructions to progrom the trace unit") of ARM IHI 0064H.b, the
self-hosted trace analyzer must perform a Context synchronization
event between writing to the TRCPRGCTLR and reading the TRCSTATR.

Fixes: ebddaad09e10 ("coresight: etm4x: Add missing single-shot control API to sysfs")
Signed-off-by: Yuanfang Zhang <quic_yuanfang at quicinc.com>
---
Change in V2:
Added comments in the code.
 drivers/hwtracing/coresight/coresight-etm4x-core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 66d44a404ad0..decb3a87e27e 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -906,6 +906,13 @@ static void etm4_disable_hw(void *info)
 	tsb_csync();
 	etm4x_relaxed_write32(csa, control, TRCPRGCTLR);
 
+	/*
+	 * As recommended by section 4.3.7 ("Synchronization when using system
+	 * instructions to progrom the trace unit") of ARM IHI 0064H.b, the
+	 * self-hosted trace analyzer must perform a Context synchronization
+	 * event between writing to the TRCPRGCTLR and reading the TRCSTATR.
+	 */
+	isb();
 	/* wait for TRCSTATR.PMSTABLE to go to '1' */
 	if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1))
 		dev_err(etm_dev,
-- 
2.34.1



From quic_bibekkum at quicinc.com  Wed Dec  4 03:27:45 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Wed, 4 Dec 2024 16:57:45 +0530
Subject: [PATCH RESEND v17 3/5] iommu/arm-smmu: add support for PRR bit
 setup
In-Reply-To: <CAF6AEGuMmdnOmATMy8f+YgGxfrYb5mkG_qgy870wZPebKaZjVQ@mail.gmail.com>
References: <20241114160721.1527934-1-quic_bibekkum@quicinc.com>
 <20241114160721.1527934-4-quic_bibekkum@quicinc.com>
 <CAF6AEGuwWsAkRyF-h5Aj3KzM7iksb12HsfJ5Ks+-P8hv60MWFg@mail.gmail.com>
 <CAF6AEGvVteuOOMod6yw9_6eOn2PxAx+BR8sVOHAHp7Ts8XigBw@mail.gmail.com>
 <5696afa2-c4ab-42fe-b29a-6ecee622fbb4@quicinc.com>
 <CAF6AEGuMmdnOmATMy8f+YgGxfrYb5mkG_qgy870wZPebKaZjVQ@mail.gmail.com>
Message-ID: <04da6036-56c4-4b8c-b75b-b5e96a089efc@quicinc.com>



On 11/22/2024 10:04 PM, Rob Clark wrote:
> On Fri, Nov 22, 2024 at 8:20?AM Bibek Kumar Patro
> <quic_bibekkum at quicinc.com> wrote:
>>
>>
>>
>> On 11/21/2024 3:40 AM, Rob Clark wrote:
>>> On Wed, Nov 20, 2024 at 9:17?AM Rob Clark <robdclark at gmail.com> wrote:
>>>>
>>>> On Thu, Nov 14, 2024 at 8:10?AM Bibek Kumar Patro
>>>> <quic_bibekkum at quicinc.com> wrote:
>>>>>
>>>>> Add an adreno-smmu-priv interface for drm/msm to call
>>>>> into arm-smmu-qcom and initiate the PRR bit setup or reset
>>>>> sequence as per request.
>>>>>
>>>>> This will be used by GPU to setup the PRR bit and related
>>>>> configuration registers through adreno-smmu private
>>>>> interface instead of directly poking the smmu hardware.
>>>>>
>>>>> Suggested-by: Rob Clark <robdclark at gmail.com>
>>>>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
>>>>> ---
>>>>>    drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 37 ++++++++++++++++++++++
>>>>>    drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 ++
>>>>>    include/linux/adreno-smmu-priv.h           | 14 ++++++++
>>>>>    3 files changed, 53 insertions(+)
>>>>>
>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>> index d26f5aea248e..0e4f3fbda961 100644
>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>> @@ -16,6 +16,8 @@
>>>>>
>>>>>    #define QCOM_DUMMY_VAL -1
>>>>>
>>>>> +#define GFX_ACTLR_PRR          (1 << 5)
>>>>> +
>>>>>    static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
>>>>>    {
>>>>>           return container_of(smmu, struct qcom_smmu, smmu);
>>>>> @@ -99,6 +101,32 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
>>>>>           arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
>>>>>    }
>>>>>
>>>>> +static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
>>>>> +{
>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>>> +       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>>>>> +       u32 reg = 0;
>>>>> +
>>>>> +       reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
>>>>> +       reg &= ~GFX_ACTLR_PRR;
>>>>> +       if (set)
>>>>> +               reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
>>>>> +       arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
>>>>> +}
>>>>> +
>>>>> +static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
>>>>> +{
>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>>> +
>>>>> +       writel_relaxed(lower_32_bits(page_addr),
>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
>>>>> +
>>>>> +       writel_relaxed(upper_32_bits(page_addr),
>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
>>>>> +}
>>>>> +
>>>>>    #define QCOM_ADRENO_SMMU_GPU_SID 0
>>>>>
>>>>>    static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
>>>>> @@ -210,6 +238,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>>>>>    static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>>                   struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>>>>>    {
>>>>> +       const struct device_node *np = smmu_domain->smmu->dev->of_node;
>>>>>           struct adreno_smmu_priv *priv;
>>>>>
>>>>>           smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>>>> @@ -239,6 +268,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>>           priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
>>>>>           priv->set_stall = qcom_adreno_smmu_set_stall;
>>>>>           priv->resume_translation = qcom_adreno_smmu_resume_translation;
>>>>> +       priv->set_prr_bit = NULL;
>>>>> +       priv->set_prr_addr = NULL;
>>>>> +
>>>>> +       if (of_device_is_compatible(np, "qcom,smmu-500") &&
>>>>> +                       of_device_is_compatible(np, "qcom,adreno-smmu")) {
>>>>
>>>> fwiw, it seems like PRR actually works on sc7180, which is _not_
>>>> mmu-500, so I guess the support actually goes back further.
>>>>
>>>> I'm curious if we can just rely on this being supported by any hw that
>>>> has a6xx or newer?
>>>
>>>
>>> Also, unrelated, but we can't assume the smmu is powered when drm
>>> driver calls set_prr_bit/addr, could you add in runpm get/put around
>>> the register access?
>>>
>>
>> I see, thanks for this observation.
>> It's surely a possible case, when they access these registers
>> SMMU state is off.
>> I will add the suggested runpm ops around the register access.
>>
>>> Otherwise Conner and I have vk sparse residency working now
>>>
>>
>> Sorry, could not get this. Did you mean that vk sparse residency
>> is working now using this patch?
> 
> Yes, vk sparse residency is working with this patch (plus addition of
> runpm get/put, plus drm/msm patches plus turnip patches) ;-)
> 

Thanks for testing the sparse residency feature with our patch Rob,
I have an additional query regarding the adreno private interfaces. 
Specifically, I was referring to other interfaces such as 
qcom_adreno_smmu_get_fault_info [1]. It appears that we do not have a 
runpm get/put around the register access in this context.

Could you please clarify whether we need an SMMU vote around register 
access in the case of PRR? IMO, should the users of this callback ensure 
they put a vote before accessing the cb?

[1]: 
https://lore.kernel.org/all/20210610214431.539029-1-robdclark at gmail.com/

Thanks & regards,
Bibek

> BR,
> -R
> 
>> Thanks & regards,
>> Bibek
>>
>>> BR,
>>> -R
>>>
>>>>
>>>>> +               priv->set_prr_bit = qcom_adreno_smmu_set_prr_bit;
>>>>> +               priv->set_prr_addr = qcom_adreno_smmu_set_prr_addr;
>>>>> +       }
>>>>>
>>>>>           return 0;
>>>>>    }
>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>> index e2aeb511ae90..2dbf3243b5ad 100644
>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>> @@ -154,6 +154,8 @@ enum arm_smmu_cbar_type {
>>>>>    #define ARM_SMMU_SCTLR_M               BIT(0)
>>>>>
>>>>>    #define ARM_SMMU_CB_ACTLR              0x4
>>>>> +#define ARM_SMMU_GFX_PRR_CFG_LADDR     0x6008
>>>>> +#define ARM_SMMU_GFX_PRR_CFG_UADDR     0x600C
>>>>>
>>>>>    #define ARM_SMMU_CB_RESUME             0x8
>>>>>    #define ARM_SMMU_RESUME_TERMINATE      BIT(0)
>>>>> diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
>>>>> index c637e0997f6d..614665153b3e 100644
>>>>> --- a/include/linux/adreno-smmu-priv.h
>>>>> +++ b/include/linux/adreno-smmu-priv.h
>>>>> @@ -50,6 +50,18 @@ struct adreno_smmu_fault_info {
>>>>>     *                 the GPU driver must call resume_translation()
>>>>>     * @resume_translation: Resume translation after a fault
>>>>>     *
>>>>> + * *CAUTION* : PRR callbacks (set_prr_bit/set_prr_addr) are NULL terminated for
>>>>> + *             targets without PRR support. Exercise caution and verify target
>>>>> + *             capabilities before invoking these callbacks to prevent potential
>>>>> + *             runtime errors or unexpected behavior.
>>>>> + *
>>>>> + * @set_prr_bit:   Extendible interface to be used by GPU to modify the
>>>>> + *                ACTLR register bits, currently used to configure
>>>>> + *                Partially-Resident-Region (PRR) bit for feature's
>>>>> + *                setup and reset sequence as requested.
>>>>> + * @set_prr_addr:  Configure the PRR_CFG_*ADDR register with the
>>>>> + *                physical address of PRR page passed from
>>>>> + *                GPU driver.
>>>>>     *
>>>>>     * The GPU driver (drm/msm) and adreno-smmu work together for controlling
>>>>>     * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
>>>>> @@ -67,6 +79,8 @@ struct adreno_smmu_priv {
>>>>>        void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
>>>>>        void (*set_stall)(const void *cookie, bool enabled);
>>>>>        void (*resume_translation)(const void *cookie, bool terminate);
>>>>> +    void (*set_prr_bit)(const void *cookie, bool set);
>>>>> +    void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
>>>>>    };
>>>>>
>>>>>    #endif /* __ADRENO_SMMU_PRIV_H */
>>>>> --
>>>>> 2.34.1
>>>>>
>>



From quic_bibekkum at quicinc.com  Wed Dec  4 03:27:02 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Wed, 4 Dec 2024 16:57:02 +0530
Subject: [PATCH RESEND v17 3/5] iommu/arm-smmu: add support for PRR bit
 setup
In-Reply-To: <CAF6AEGvAOswFTpS5PHrgCsG_2-QN_Bi4YjZbPpV+r3x=9D2aUQ@mail.gmail.com>
References: <20241114160721.1527934-1-quic_bibekkum@quicinc.com>
 <20241114160721.1527934-4-quic_bibekkum@quicinc.com>
 <CAF6AEGuwWsAkRyF-h5Aj3KzM7iksb12HsfJ5Ks+-P8hv60MWFg@mail.gmail.com>
 <9beca099-5cf3-42b5-b1f9-fb1551219b18@quicinc.com>
 <CAF6AEGvAOswFTpS5PHrgCsG_2-QN_Bi4YjZbPpV+r3x=9D2aUQ@mail.gmail.com>
Message-ID: <d2d8d9e9-74b1-4b05-84a2-dcfa204e6e00@quicinc.com>



On 11/22/2024 10:33 PM, Rob Clark wrote:
> On Fri, Nov 22, 2024 at 8:19?AM Bibek Kumar Patro
> <quic_bibekkum at quicinc.com> wrote:
>>
>>
>>
>> On 11/20/2024 10:47 PM, Rob Clark wrote:
>>> On Thu, Nov 14, 2024 at 8:10?AM Bibek Kumar Patro
>>> <quic_bibekkum at quicinc.com> wrote:
>>>>
>>>> Add an adreno-smmu-priv interface for drm/msm to call
>>>> into arm-smmu-qcom and initiate the PRR bit setup or reset
>>>> sequence as per request.
>>>>
>>>> This will be used by GPU to setup the PRR bit and related
>>>> configuration registers through adreno-smmu private
>>>> interface instead of directly poking the smmu hardware.
>>>>
>>>> Suggested-by: Rob Clark <robdclark at gmail.com>
>>>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
>>>> ---
>>>>    drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 37 ++++++++++++++++++++++
>>>>    drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 ++
>>>>    include/linux/adreno-smmu-priv.h           | 14 ++++++++
>>>>    3 files changed, 53 insertions(+)
>>>>
>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>> index d26f5aea248e..0e4f3fbda961 100644
>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>> @@ -16,6 +16,8 @@
>>>>
>>>>    #define QCOM_DUMMY_VAL -1
>>>>
>>>> +#define GFX_ACTLR_PRR          (1 << 5)
>>>> +
>>>>    static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
>>>>    {
>>>>           return container_of(smmu, struct qcom_smmu, smmu);
>>>> @@ -99,6 +101,32 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
>>>>           arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
>>>>    }
>>>>
>>>> +static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
>>>> +{
>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>> +       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>>>> +       u32 reg = 0;
>>>> +
>>>> +       reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
>>>> +       reg &= ~GFX_ACTLR_PRR;
>>>> +       if (set)
>>>> +               reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
>>>> +       arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
>>>> +}
>>>> +
>>>> +static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
>>>> +{
>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>> +
>>>> +       writel_relaxed(lower_32_bits(page_addr),
>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
>>>> +
>>>> +       writel_relaxed(upper_32_bits(page_addr),
>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
>>>> +}
>>>> +
>>>>    #define QCOM_ADRENO_SMMU_GPU_SID 0
>>>>
>>>>    static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
>>>> @@ -210,6 +238,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>>>>    static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>                   struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>>>>    {
>>>> +       const struct device_node *np = smmu_domain->smmu->dev->of_node;
>>>>           struct adreno_smmu_priv *priv;
>>>>
>>>>           smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>>> @@ -239,6 +268,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>           priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
>>>>           priv->set_stall = qcom_adreno_smmu_set_stall;
>>>>           priv->resume_translation = qcom_adreno_smmu_resume_translation;
>>>> +       priv->set_prr_bit = NULL;
>>>> +       priv->set_prr_addr = NULL;
>>>> +
>>>> +       if (of_device_is_compatible(np, "qcom,smmu-500") &&
>>>> +                       of_device_is_compatible(np, "qcom,adreno-smmu")) {
>>>
>>> fwiw, it seems like PRR actually works on sc7180, which is _not_
>>> mmu-500, so I guess the support actually goes back further.
>>>
>>
>> As I checked sc7180 was on previous variant of SMMU,
>> so targets on this variant have different steps to set PRR bit.
>> <Do not have both prr bit and PRR page registers>.
> 
> Experimentally, I have to set both the PRR LADDR/UADDR regs and
> ACTLR.PRR bit on sc7180 to get the sparse-residency tests passing.  So
> the underlying hw seems to work in the same way as mmu-500.  _But_
> this is on a sc7180 chromebook, the situation might be different
> depending on fw on things that have QC hyp.
> 

I checked on sc7180 chipset which is based on the smmu-v2,
this time by looking for these offsets specifically. I can see the 
nomenclature of the PRR related registers are a bit different
compared to MMU-500 variant.
Also the implementation register is 64 bit instead of
dual 32 bit as in case of MMU-500. and PRR bit is not marked in
ACTLR register offset.

So turns out PRR is supported but with some modification and
can be carried out with same compatible based approach only - as per
my understanding.

In current patch plan was to provide support for MMU-500 based targets
and won't break any legacy targets, so we can take the PRR support
for legacy targets in different series once our evaluation is done on 
smmu-v2 ?
We would explore more on this PRR feature for smmu-v2 based targets,
before supporting it.

Thanks & regards,
Bibek

>> It's MMU-500 targets only where PRR support is with both PRR bit
>> and PRR page addr registers. As I was re-visiting our discussions on v13
>> regarding this - I remember that's why we started using the SMMU-
>> compatible string based PRR procedure selection instead of the reserved-
>> memory node. [1] i.e Based on SMMU variant (as selected by compatible
>> string), specific sequence will be selected.
>>
>> So for now only MMU-500 based selection has been supported as part of
>> this series and will add subsequent support for other SMMU-variants
>> thereafter.
>>
>>> I'm curious if we can just rely on this being supported by any hw that
>>> has a6xx or newer?
>>>
>>
>> I'd need to check on targets which will be based on a6xx onwards, on
>> what will be the procedure planned to support PRR feature. I'll update
>> the information over this space.
> 
> One of the open questions about the drm/msm sparse-memory patchset is
> whether we need to expose to userspace whether PRR is supported, or if
> we can just rely on sparse-binding support implying sparse residency
> (ie, PRR) support. All a6xx devices support per-process pgtables,
> which is the only requirement for basic sparseBinding support.  But
> PRR is required to additionally expose
> sparseResidencyBuffer/sparseResidencyImage2D.
> 
> I think, long term, turnip probably will want to drop support for
> older kernels and remove support for legacy buffer mapping.  But if we
> have some a6xx devices without PRR, then to do that we'd need to
> decouple sparse binding and sparse residency.  (Vulkan allows a driver
> to expose the former without the latter.)
> 
> BR,
> -R
> 
>> [1]:
>> https://lore.kernel.org/all/5790afa3-f9c0-4720-9804-8a7ff3d91854 at quicinc.com/#:~:text=%3E%20I%20guess%20if,part%20as%20well.
>>
>> Thanks & regards,
>> Bibek
>>
>>> BR,
>>> -R
>>>
>>>> +               priv->set_prr_bit = qcom_adreno_smmu_set_prr_bit;
>>>> +               priv->set_prr_addr = qcom_adreno_smmu_set_prr_addr;
>>>> +       }
>>>>
>>>>           return 0;
>>>>    }
>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>> index e2aeb511ae90..2dbf3243b5ad 100644
>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>> @@ -154,6 +154,8 @@ enum arm_smmu_cbar_type {
>>>>    #define ARM_SMMU_SCTLR_M               BIT(0)
>>>>
>>>>    #define ARM_SMMU_CB_ACTLR              0x4
>>>> +#define ARM_SMMU_GFX_PRR_CFG_LADDR     0x6008
>>>> +#define ARM_SMMU_GFX_PRR_CFG_UADDR     0x600C
>>>>
>>>>    #define ARM_SMMU_CB_RESUME             0x8
>>>>    #define ARM_SMMU_RESUME_TERMINATE      BIT(0)
>>>> diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
>>>> index c637e0997f6d..614665153b3e 100644
>>>> --- a/include/linux/adreno-smmu-priv.h
>>>> +++ b/include/linux/adreno-smmu-priv.h
>>>> @@ -50,6 +50,18 @@ struct adreno_smmu_fault_info {
>>>>     *                 the GPU driver must call resume_translation()
>>>>     * @resume_translation: Resume translation after a fault
>>>>     *
>>>> + * *CAUTION* : PRR callbacks (set_prr_bit/set_prr_addr) are NULL terminated for
>>>> + *             targets without PRR support. Exercise caution and verify target
>>>> + *             capabilities before invoking these callbacks to prevent potential
>>>> + *             runtime errors or unexpected behavior.
>>>> + *
>>>> + * @set_prr_bit:   Extendible interface to be used by GPU to modify the
>>>> + *                ACTLR register bits, currently used to configure
>>>> + *                Partially-Resident-Region (PRR) bit for feature's
>>>> + *                setup and reset sequence as requested.
>>>> + * @set_prr_addr:  Configure the PRR_CFG_*ADDR register with the
>>>> + *                physical address of PRR page passed from
>>>> + *                GPU driver.
>>>>     *
>>>>     * The GPU driver (drm/msm) and adreno-smmu work together for controlling
>>>>     * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
>>>> @@ -67,6 +79,8 @@ struct adreno_smmu_priv {
>>>>        void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
>>>>        void (*set_stall)(const void *cookie, bool enabled);
>>>>        void (*resume_translation)(const void *cookie, bool terminate);
>>>> +    void (*set_prr_bit)(const void *cookie, bool set);
>>>> +    void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
>>>>    };
>>>>
>>>>    #endif /* __ADRENO_SMMU_PRIV_H */
>>>> --
>>>> 2.34.1
>>>>
>>



From linux at fw-web.de  Wed Dec  4 03:29:49 2024
From: linux at fw-web.de (Frank Wunderlich (linux))
Date: Wed, 04 Dec 2024 12:29:49 +0100
Subject: [PATCH v2 17/18] arm64: dts: mediatek: mt7988: enable ssusb1 on
 bpi-r4
In-Reply-To: <79ac6523-b002-4e10-95ac-3df378f4f3f5@collabora.com>
References: <20241202122602.30734-1-linux@fw-web.de>
 <20241202122602.30734-18-linux@fw-web.de>
 <79ac6523-b002-4e10-95ac-3df378f4f3f5@collabora.com>
Message-ID: <3ab54dacf32dac008ff88855abb53415@fw-web.de>

Am 2024-12-03 10:40, schrieb AngeloGioacchino Del Regno:
> Il 02/12/24 13:25, Frank Wunderlich ha scritto:
>> From: Frank Wunderlich <frank-w at public-files.de>
>> 
>> Enable front-usb on Bananapi R4 board.
>> 
>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> 
> Reviewed-by: AngeloGioacchino Del Regno 
> <angelogioacchino.delregno at collabora.com>

thanks, but i noticed, that the controllers in dtsi are not disabled 
like in my final dtsi. Imho controllers should be disabled by default 
and only enabled when used on board. Should i add disabling in this 
patch too?

and i noticed that usb phys have to be added to get working usb. Here 
for ssusb1 a tphy is used where i now have prepared patch so i can add 
it in next version (reusing mt7986 compatible). ssusb0 uses a different 
phy (xsphy) which needs a bit more work before (driver and binding 
change).

regards Frank


From Dave.Martin at arm.com  Wed Dec  4 03:33:02 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 4 Dec 2024 11:33:02 +0000
Subject: [PATCH 1/6] arm64/sme: Flush foreign register state in
 do_sme_acc()
In-Reply-To: <44d67835-1e43-47cc-9a18-c279c885dcec@sirena.org.uk>
References: <20241203-arm64-sme-reenable-v1-0-d853479d1b77@kernel.org>
 <20241203-arm64-sme-reenable-v1-1-d853479d1b77@kernel.org>
 <Z08khk6Mg6+T6VV9@e133380.arm.com>
 <9365be76-8da6-47ce-b88e-dfa244b9e5b7@sirena.org.uk>
 <Z085GKS8jzEhcZdW@e133380.arm.com>
 <44d67835-1e43-47cc-9a18-c279c885dcec@sirena.org.uk>
Message-ID: <Z1A97pR+un1Trtyg@e133380.arm.com>

On Tue, Dec 03, 2024 at 05:24:39PM +0000, Mark Brown wrote:
> On Tue, Dec 03, 2024 at 05:00:08PM +0000, Dave Martin wrote:
> > On Tue, Dec 03, 2024 at 04:00:45PM +0000, Mark Brown wrote:

[...]

> We know that the only bit of register state which is not up to date at
> this point is the SME vector length, we don't configure that for tasks
> that do not have SME.  SVCR is always configured since we have to exit
> streaming mode for FPSIMD and SVE to work properly so we know it's
> already 0, all the other SME specific state is gated by controls in
> SVCR.
> 
> > fpsimd_flush_task_state() means that we do the necessary work when re-
> > entering userspace, but is there a problem with simply marking all the
> > FPSIMD/vector state as stale?  If FPSR or FPCR is dirty for example, it
> > now looks like they won't get written back to thread struct if there is
> > a context switch before current re-enters userspace?
> 
> > Maybe the other flags distinguish these cases -- I haven't fully got my
> > head around it.
> 
> We are doing fpsimd_flush_task_state() in the TIF_FOREIGN_FPSTATE case
> so we know there is no dirty state in the registers.

Ah, that wasn't obvious from the diff context, but you're right.

I was confused by the fpsimd_bind_task_to_cpu() call; I forgot that
there are reasons to call this even when TIF_FOREIGN_FPSTATE is clear.
Perhaps it would be worth splitting some of those uses up, but it would
need some thinking about.  Doesn't really belong in this series anyway.

> > (Actually, the ARM ARM says (IMHTLZ) that toggling PSTATE.SM by any
> > means causes FPSR to become 0x800009f.  I'm not sure where that fits in
> > -- do we handle that anywhere?  I guess the "soft" SM toggling via
> 
> Urgh, not seen that one - that needs handling in the signal entry path
> and ptrace.  That will have been defined while the feature was being
> implemented.  It's not relevant here though since we are in the SME
> access trap, we might be trapping due to a SMSTART or equivalent
> operation but that SMSTART has not yet run at the point where we return
> to userspace.
> 
> > ptrace, signal delivery or maybe exec, ought to set this?  Not sure how
> > that interacts with the expected behaviour of the fenv(3) API...  Hmm.
> > I see no corresponding statement about FPCR.)
> 
> Fun.  I'm not sure how the ABI is defined there by libc.

I guess this should be left as-is, for now.  There's an argument for
sanitising FPCR/FPSR on signal delivery, but neither signal(7) nor
fenv(3) give any clue about the expected behaviour...

For ptrace, the user has the opportunity to specify exactly what they
want to happen to all the registers, so I suppose it's best to stick to
the current model and require the tracer to specify all changes
explicitly rather than add new magic ptrace behaviour.

Not relevant for this series, in any case.

Cheers
---Dave


From cristian.marussi at arm.com  Wed Dec  4 03:48:26 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 4 Dec 2024 11:48:26 +0000
Subject: [PATCH V5 1/2] firmware: arm_scmi: Add QCOM Generic Vendor
 Protocol documentation
In-Reply-To: <20241115011515.1313447-2-quic_sibis@quicinc.com>
References: <20241115011515.1313447-1-quic_sibis@quicinc.com>
 <20241115011515.1313447-2-quic_sibis@quicinc.com>
Message-ID: <Z1BBirNWH1eaSKtr@pluto>

On Fri, Nov 15, 2024 at 06:45:14AM +0530, Sibi Sankar wrote:
> Add QCOM System Control Management Interface (SCMI) Generic Vendor
> Extensions Protocol documentation.
> 
> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
> ---
> 
> v4:
> * Update the protol attributes doc with more information. [Cristian]
> 
>  .../arm_scmi/vendors/qcom/qcom_generic.rst    | 211 ++++++++++++++++++
>  1 file changed, 211 insertions(+)
>  create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> 
> diff --git a/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> new file mode 100644
> index 000000000000..141bc932e30f
> --- /dev/null
> +++ b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> @@ -0,0 +1,211 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +.. include:: <isonum.txt>
> +
> +===============================================================================
> +QCOM System Control and Management Interface(SCMI) Vendor Protocols Extension
> +===============================================================================
> +
> +:Copyright: |copy| 2024, Qualcomm Innovation Center, Inc. All rights reserved.
> +
> +:Author: Sibi Sankar <quic_sibis at quicinc.com>
> +
> +SCMI_GENERIC: System Control and Management Interface QCOM Generic Vendor Protocol
> +==================================================================================
> +
> +This protocol is intended as a generic way of exposing a number of Qualcomm
> +SoC specific features through a mixture of pre-determined algorithm string and
> +param_id pairs hosted on the SCMI controller. It implements an interface compliant
> +with the Arm SCMI Specification with additional vendor specific commands as
> +detailed below.
> +
> +Commands:
> +_________
> +
> +PROTOCOL_VERSION
> +~~~~~~~~~~~~~~~~
> +
> +message_id: 0x0
> +protocol_id: 0x80
> +
> ++---------------+--------------------------------------------------------------+
> +|Return values                                                                 |
> ++---------------+--------------------------------------------------------------+
> +|Name           |Description                                                   |
> ++---------------+--------------------------------------------------------------+
> +|int32 status   |See ARM SCMI Specification for status code definitions.       |
> ++---------------+--------------------------------------------------------------+
> +|uint32 version |For this revision of the specification, this value must be    |
> +|               |0x10000.                                                      |
> ++---------------+--------------------------------------------------------------+
> +
> +PROTOCOL_ATTRIBUTES
> +~~~~~~~~~~~~~~~~~~~
> +
> +message_id: 0x1
> +protocol_id: 0x80
> +
> ++---------------+--------------------------------------------------------------+
> +|Return values                                                                 |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|int32 status      |See ARM SCMI Specification for status code definitions.    |
> ++------------------+-----------------------------------------------------------+
> +|uint32 attributes |Bits[31:16] Reserved, must be to 0.                        |
> +|                  |Bits[15:8] Number of agents in the system                  |
> +|                  |Bits[7:0] Number of vendor protocols in the system         |
> ++------------------+-----------------------------------------------------------+

Thanks of clarifing this....may I ask why number of agents is reported
here too given that it is already exposed by Base protocol ?

Not really arguing about this so much, but you will end up having to maintain this
on 2 different protocols fw side...or are they not 'agents' in the SCMI meaning ?

Anyway, I'm fine with it, even though you dont seem to use this
anywhere.

> +
> +PROTOCOL_MESSAGE_ATTRIBUTES
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +message_id: 0x2
> +protocol_id: 0x80
> +
> ++---------------+--------------------------------------------------------------+
> +|Return values                                                                 |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|int32 status      |See ARM SCMI Specification for status code definitions.    |
> ++------------------+-----------------------------------------------------------+
> +|uint32 attributes |For all message id's the parameter has a value of 0.       |
> ++------------------+-----------------------------------------------------------+
> +
> +QCOM_SCMI_SET_PARAM
> +~~~~~~~~~~~~~~~~~~~
> +
> +message_id: 0x10
> +protocol_id: 0x80
> +
> ++------------------+-----------------------------------------------------------+
> +|Parameters                                                                    |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|uint32 ext_id     |Reserved, must be zero.                                    |
> ++------------------+-----------------------------------------------------------+
> +|uint32 algo_low   |Lower 32-bit value of the algorithm string.                |
> ++------------------+-----------------------------------------------------------+
> +|uint32 algo_high  |Upper 32-bit value of the algorithm string.                |
> ++------------------+-----------------------------------------------------------+
> +|uint32 param_id   |Serves as the token message id for the algorithm string    |
> +|                  |and is used to set various parameters supported by it.     |
> ++------------------+-----------------------------------------------------------+
> +|uint32 buf[]      |Serves as the payload for the specified param_id and       |
> +|                  |algorithm string pair.                                     |
> ++------------------+-----------------------------------------------------------+
> +|Return values                                                                 |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|int32 status      |SUCCESS: if the param_id and buf[] is parsed successfully  |
> +|                  |by the chosen algorithm string.                            |
> +|                  |NOT_SUPPORTED: if the algorithm string does not have any   |
> +|                  |matches.                                                   |
> +|                  |INVALID_PARAMETERS: if the param_id and the buf[] passed   |
> +|                  |is rejected by the algorithm string.                       |
> ++------------------+-----------------------------------------------------------+
> +
> +QCOM_SCMI_GET_PARAM
> +~~~~~~~~~~~~~~~~~~~
> +
> +message_id: 0x11
> +protocol_id: 0x80
> +
> ++------------------+-----------------------------------------------------------+
> +|Parameters                                                                    |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|uint32 ext_id     |Reserved, must be zero.                                    |
> ++------------------+-----------------------------------------------------------+
> +|uint32 algo_low   |Lower 32-bit value of the algorithm string.                |
> ++------------------+-----------------------------------------------------------+
> +|uint32 algo_high  |Upper 32-bit value of the algorithm string.                |
> ++------------------+-----------------------------------------------------------+
> +|uint32 param_id   |Serves as the token message id for the algorithm string.   |
> ++------------------+-----------------------------------------------------------+
> +|uint32 buf[]      |Serves as the payload and store of value for the specified |
> +|                  |param_id and algorithm string pair.                        |
> ++------------------+-----------------------------------------------------------+
> +|Return values                                                                 |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|int32 status      |SUCCESS: if the param_id and buf[] is parsed successfully  |
> +|                  |by the chosen algorithm string and the result is copied    |
> +|                  |into buf[].                                                |
> +|                  |NOT_SUPPORTED: if the algorithm string does not have any   |
> +|                  |matches.                                                   |
> +|                  |INVALID_PARAMETERS: if the param_id and the buf[] passed   |
> +|                  |is rejected by the algorithm string.                       |
> ++------------------+-----------------------------------------------------------+

..missed this last time...so you should add here also a field describing
the reply buf right ? (as it happenns really in your code) something
like:

 ++------------------+-----------------------------------------------------------+
 +|uint32 buf[]      |Holds the payload of the result of the query.	 	 |
 +|                  |					                         |
 ++------------------+-----------------------------------------------------------+

Thanks,
Cristian


From kevin.brodsky at arm.com  Wed Dec  4 04:07:37 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Wed, 4 Dec 2024 13:07:37 +0100
Subject: [PATCH] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <Z1A7ACC+0Vb2bT9p@e133380.arm.com>
References: <20241203100322.1626805-1-kevin.brodsky@arm.com>
 <Z07x69L6Mssncg/7@e133380.arm.com>
 <a9aa36eb-d5c2-4d1c-bf5d-e63e4cb55404@arm.com>
 <Z08l0Q9KO6haeSSI@e133380.arm.com>
 <3da4f6d2-5869-4515-a86a-e821d9276640@arm.com>
 <Z1A7ACC+0Vb2bT9p@e133380.arm.com>
Message-ID: <a69093a6-2778-4588-9566-c57cdba14867@arm.com>

On 04/12/2024 12:20, Dave Martin wrote:
> That seems fair.  A one-line comment at the call to setup_return()
> should be enough.  I guess we can live with the slightly confusing
> function naming (since it was already a bit confusing, and this isn't
> trivial to sort out).
>
> So, with the comment, feel free to add:
>
> Reviewed-by: Dave Martin <Dave.Martin at arm.com>

I'll add that comment in v2 - thanks for the review, very appreciated!

- Kevin


From Trevor.Wu at mediatek.com  Wed Dec  4 04:17:01 2024
From: Trevor.Wu at mediatek.com (=?utf-8?B?VHJldm9yIFd1ICjlkLPmlofoia8p?=)
Date: Wed, 4 Dec 2024 12:17:01 +0000
Subject: [PATCH] ASoC: mediatek: mt8188: Enable apll1 clock during reg rw
 to prevent hang
In-Reply-To: <20241203-mt8188-afe-fix-hang-disabled-apll1-clk-v1-1-07cdd7760834@collabora.com>
References: <20241203-mt8188-afe-fix-hang-disabled-apll1-clk-v1-1-07cdd7760834@collabora.com>
Message-ID: <a10dbdf265194e77a69b6e40afa3df9636b3ab14.camel@mediatek.com>

On Tue, 2024-12-03 at 17:07 -0300, N?colas F. R. A. Prado wrote:

> 
> Currently, booting the Genio 700 EVK board with the MT8188 sound
> platform driver configured as a module (CONFIG_SND_SOC_MT8188=m)
> results
> in a system hang right when the HW registers for the audio controller
> are read:
> 
>   mt8188-audio 10b10000.audio-controller: No cache defaults, reading
> back from HW
> 
> The hang doesn't occur with the driver configured as builtin as then
> the
> unused clocks are still enabled.
> 
> Enable the apll1 clock during register read/write to prevent the
> hang.
> 
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> ---
>  sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> index
> e69c1bb2cb239596dee50b166c20192d5408be10..fb8cf286df3f02ac076528b898f
> d0d7a708ec1ea 100644
> --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> @@ -587,6 +587,8 @@ int mt8188_afe_enable_reg_rw_clk(struct
> mtk_base_afe *afe)
>         mt8188_afe_enable_clk(afe, afe_priv-
> >clk[MT8188_CLK_AUD_A1SYS_HP]);
>         mt8188_afe_enable_clk(afe, afe_priv-
> >clk[MT8188_CLK_AUD_A1SYS]);
> 
> +       mt8188_afe_enable_clk(afe, afe_priv-
> >clk[MT8188_CLK_APMIXED_APLL1]);
> +
>         return 0;
>  }
Hi Nicolas,

If I understand correctly, APLL1 should be the parent clock of
AUD_A1SYS_HP and AUD_A1SYS, so it should be enabled automatically by
CCF.

I'm not sure why you resolved the hang issue after enabling APLL1.
Could you share more details about the solution?

Thanks,
Trevor

> 
> @@ -594,6 +596,8 @@ int mt8188_afe_disable_reg_rw_clk(struct
> mtk_base_afe *afe)
>  {
>         struct mt8188_afe_private *afe_priv = afe->platform_priv;
> 
> +       mt8188_afe_disable_clk(afe, afe_priv-
> >clk[MT8188_CLK_APMIXED_APLL1]);
> +
>         mt8188_afe_disable_clk(afe, afe_priv-
> >clk[MT8188_CLK_AUD_A1SYS]);
>         mt8188_afe_disable_clk(afe, afe_priv-
> >clk[MT8188_CLK_AUD_A1SYS_HP]);
>         mt8188_afe_disable_clk(afe, afe_priv-
> >clk[MT8188_CLK_AUD_AFE]);
> 
> ---
> base-commit: b852e1e7a0389ed6168ef1d38eb0bad71a6b11e8
> change-id: 20241203-mt8188-afe-fix-hang-disabled-apll1-clk-
> b3c11782cbaf
> 
> Best regards,
> --
> N?colas F. R. A. Prado <nfraprado at collabora.com>
> 
> 

From faraz.ata at samsung.com  Wed Dec  4 04:23:33 2024
From: faraz.ata at samsung.com (Faraz Ata)
Date: Wed,  4 Dec 2024 17:53:33 +0530
Subject: [PATCH] arm64: dts: exynosautov920: add DMA nodes
References: <CGME20241204122402epcas5p2412733eb46d495fadfa30e5af3c5ce83@epcas5p2.samsung.com>
Message-ID: <20241204122335.1578-1-faraz.ata@samsung.com>

ExynosAutov920 SoC has 7 DMA controllers. Two secure DMAC
(SPDMA0 & SPDMA1) and five non-secure DMAC (PDMA0 to PDMA4).
Adds the required dt node for the same.

Signed-off-by: Faraz Ata <faraz.ata at samsung.com>
---
 .../arm64/boot/dts/exynos/exynosautov920.dtsi | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
index c759134c909e..e65be0c97f7e 100644
--- a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
@@ -193,6 +193,69 @@ gic: interrupt-controller at 10400000 {
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		spdma0: dma-controller at 10180000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x10180000 0x1000>;
+			interrupts = <GIC_SPI 918 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		spdma1: dma-controller at 10190000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x10190000 0x1000>;
+			interrupts = <GIC_SPI 917 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma0: dma-controller at 101A0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101A0000 0x1000>;
+			interrupts = <GIC_SPI 916 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma1: dma-controller at 101B0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101B0000 0x1000>;
+			interrupts = <GIC_SPI 915 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma2: dma-controller at 101C0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101C0000 0x1000>;
+			interrupts = <GIC_SPI 914 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma3: dma-controller at 101D0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101D0000 0x1000>;
+			interrupts = <GIC_SPI 913 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma4: dma-controller at 101E0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101E0000 0x1000>;
+			interrupts = <GIC_SPI 912 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
 		cmu_peric0: clock-controller at 10800000 {
 			compatible = "samsung,exynosautov920-cmu-peric0";
 			reg = <0x10800000 0x8000>;
-- 
2.34.1



From vkoul at kernel.org  Wed Dec  4 04:27:32 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 4 Dec 2024 17:57:32 +0530
Subject: [PATCH V5 2/9] dmaengine: bcm2835-dma: add suspend/resume pm
 support
In-Reply-To: <d418a30d-f0b0-49c5-8f2a-ddda9a7eeb07@gmx.net>
References: <20241025103621.4780-1-wahrenst@gmx.net>
 <20241025103621.4780-3-wahrenst@gmx.net>
 <Z03l308ur7xuE1SB@vaman>
 <d418a30d-f0b0-49c5-8f2a-ddda9a7eeb07@gmx.net>
Message-ID: <Z1BKtHPN+2qiveHJ@vaman>

On 02-12-24, 19:51, Stefan Wahren wrote:
> Hi Vinod,
> 
> Am 02.12.24 um 17:52 schrieb Vinod Koul:
> > On 25-10-24, 12:36, Stefan Wahren wrote:
> > > bcm2835-dma provides the service to others, so it should
> > > suspend late and resume early.
> > > 
> > > Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
> > > ---
> > >   drivers/dma/bcm2835-dma.c | 30 ++++++++++++++++++++++++++++++
> > >   1 file changed, 30 insertions(+)
> > > 
> > > diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> > > index e1b92b4d7b05..647dda9f3376 100644
> > > --- a/drivers/dma/bcm2835-dma.c
> > > +++ b/drivers/dma/bcm2835-dma.c
> > > @@ -875,6 +875,35 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
> > >   	return chan;
> > >   }
> > > 
> > > +static int bcm2835_dma_suspend_late(struct device *dev)
> > > +{
> > > +	struct bcm2835_dmadev *od = dev_get_drvdata(dev);
> > > +	struct bcm2835_chan *c, *next;
> > > +
> > > +	list_for_each_entry_safe(c, next, &od->ddev.channels,
> > > +				 vc.chan.device_node) {
> > > +		void __iomem *chan_base = c->chan_base;
> > > +
> > > +		if (readl(chan_base + BCM2835_DMA_ADDR)) {
> > > +			dev_warn(dev, "Suspend is prevented by chan %d\n",
> > > +				 c->ch);
> > > +			return -EBUSY;
> > > +		}
> > Can you help understand how this helps by logging... we are not adding
> > anything except checking this and resume is NOP as well!
> My intention of this patch is just to make sure, that no DMA transfer is
> in progress during late_suspend. So i followed the implementation of
> fsldma.c
> 
> Additionally i added this warning mostly to know if this ever occurs.
> But i wasn't able to trigger.

Okay in the case I dont think it is a abd idea. But the patch
description should mention that add a warning while suspending if
channels are active or something like that.
Patch title and description should mention this..

> 
> Should i drop the warning and make resume callback = NULL?

Yes that would be better as well, no point in having dummy code

-- 
~Vinod


From lkp at intel.com  Wed Dec  4 04:26:35 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 4 Dec 2024 20:26:35 +0800
Subject: [PATCH v2] firmware: smccc: Support optional Arm SMC SOC_ID name
In-Reply-To: <20241203212854.5565-1-paul@os.amperecomputing.com>
References: <20241203212854.5565-1-paul@os.amperecomputing.com>
Message-ID: <202412042020.U9EEV8mE-lkp@intel.com>

Hi Paul,

kernel test robot noticed the following build warnings:

[auto build test WARNING on soc/for-next]
[also build test WARNING on linus/master v6.13-rc1 next-20241203]
[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/Paul-Benoit/firmware-smccc-Support-optional-Arm-SMC-SOC_ID-name/20241204-124243
base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
patch link:    https://lore.kernel.org/r/20241203212854.5565-1-paul%40os.amperecomputing.com
patch subject: [PATCH v2] firmware: smccc: Support optional Arm SMC SOC_ID name
config: arm-qcom_defconfig (https://download.01.org/0day-ci/archive/20241204/202412042020.U9EEV8mE-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241204/202412042020.U9EEV8mE-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/202412042020.U9EEV8mE-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/firmware/smccc/soc_id.c:109:16: warning: shift count >= width of type [-Wshift-count-overflow]
     109 |         dst[4] = (reg >> 32) & 0xff;
         |                       ^  ~~
   drivers/firmware/smccc/soc_id.c:110:16: warning: shift count >= width of type [-Wshift-count-overflow]
     110 |         dst[5] = (reg >> 40) & 0xff;
         |                       ^  ~~
   drivers/firmware/smccc/soc_id.c:111:16: warning: shift count >= width of type [-Wshift-count-overflow]
     111 |         dst[6] = (reg >> 48) & 0xff;
         |                       ^  ~~
   drivers/firmware/smccc/soc_id.c:112:16: warning: shift count >= width of type [-Wshift-count-overflow]
     112 |         dst[7] = (reg >> 56) & 0xff;
         |                       ^  ~~
>> drivers/firmware/smccc/soc_id.c:37:29: warning: unused variable 'smccc_soc_id_name' [-Wunused-variable]
      37 | static char __ro_after_init smccc_soc_id_name[136] = "";
         |                             ^~~~~~~~~~~~~~~~~
   drivers/firmware/smccc/soc_id.c:103:20: warning: unused function 'str_fragment_from_reg' [-Wunused-function]
     103 | static inline void str_fragment_from_reg(char *dst, unsigned long reg)
         |                    ^~~~~~~~~~~~~~~~~~~~~
   6 warnings generated.


vim +109 drivers/firmware/smccc/soc_id.c

    36	
  > 37	static char __ro_after_init smccc_soc_id_name[136] = "";
    38	
    39	static int __init smccc_soc_init(void)
    40	{
    41		int soc_id_rev, soc_id_version;
    42		static char soc_id_str[20], soc_id_rev_str[12];
    43		static char soc_id_jep106_id_str[12];
    44	
    45		if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
    46			return 0;
    47	
    48		soc_id_version = arm_smccc_get_soc_id_version();
    49		if (soc_id_version == SMCCC_RET_NOT_SUPPORTED) {
    50			pr_info("ARCH_SOC_ID not implemented, skipping ....\n");
    51			return 0;
    52		}
    53	
    54		if (soc_id_version < 0) {
    55			pr_err("Invalid SoC Version: %x\n", soc_id_version);
    56			return -EINVAL;
    57		}
    58	
    59		soc_id_rev = arm_smccc_get_soc_id_revision();
    60		if (soc_id_rev < 0) {
    61			pr_err("Invalid SoC Revision: %x\n", soc_id_rev);
    62			return -EINVAL;
    63		}
    64	
    65		soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
    66		if (!soc_dev_attr)
    67			return -ENOMEM;
    68	
    69		sprintf(soc_id_rev_str, "0x%08x", soc_id_rev);
    70		sprintf(soc_id_jep106_id_str, "jep106:%02x%02x",
    71			JEP106_BANK_CONT_CODE(soc_id_version),
    72			JEP106_ID_CODE(soc_id_version));
    73		sprintf(soc_id_str, "%s:%04x", soc_id_jep106_id_str,
    74			IMP_DEF_SOC_ID(soc_id_version));
    75	
    76		soc_dev_attr->soc_id = soc_id_str;
    77		soc_dev_attr->revision = soc_id_rev_str;
    78		soc_dev_attr->family = soc_id_jep106_id_str;
    79		soc_dev_attr->machine = smccc_soc_name_init();
    80	
    81		soc_dev = soc_device_register(soc_dev_attr);
    82		if (IS_ERR(soc_dev)) {
    83			kfree(soc_dev_attr);
    84			return PTR_ERR(soc_dev);
    85		}
    86	
    87		pr_info("ID = %s Revision = %s\n", soc_dev_attr->soc_id,
    88			soc_dev_attr->revision);
    89	
    90		return 0;
    91	}
    92	module_init(smccc_soc_init);
    93	
    94	static void __exit smccc_soc_exit(void)
    95	{
    96		if (soc_dev)
    97			soc_device_unregister(soc_dev);
    98		kfree(soc_dev_attr);
    99	}
   100	module_exit(smccc_soc_exit);
   101	
   102	
   103	static inline void str_fragment_from_reg(char *dst, unsigned long reg)
   104	{
   105		dst[0] = (reg >> 0)  & 0xff;
   106		dst[1] = (reg >> 8)  & 0xff;
   107		dst[2] = (reg >> 16) & 0xff;
   108		dst[3] = (reg >> 24) & 0xff;
 > 109		dst[4] = (reg >> 32) & 0xff;
 > 110		dst[5] = (reg >> 40) & 0xff;
   111		dst[6] = (reg >> 48) & 0xff;
   112		dst[7] = (reg >> 56) & 0xff;
   113	}
   114	

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


From linux at fw-web.de  Wed Dec  4 04:27:05 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Wed,  4 Dec 2024 13:27:05 +0100
Subject: [RFC] phy: mediatek: xsphy: support type switch by pericfg
Message-ID: <20241204122706.25190-1-linux@fw-web.de>

From: Daniel Golle <daniel at makrotopia.org>

Patch from Sam Shih <sam.shih at mediatek.com> found in MediaTek SDK
released under GPL.

Get syscon and use it to set the PHY type.
Extend support to PCIe and SGMII mode in addition to USB2 and USB3.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
xsphy is needed on mt7988 to get ssusb0 working

current way is using a syscon node like this

	topmisc: topmisc at 11d10000 {
		compatible = "mediatek,mt7988-topmisc", "syscon",
			     "mediatek,mt7988-power-controller";
		reg = <0 0x11d10000 0 0x10000>;
		#clock-cells = <1>;
		#power-domain-cells = <1>;
		#address-cells = <1>;
		#size-cells = <0>;
	};

	xs-phy at 11e10000 {
		compatible = "mediatek,mt7988-xsphy",
			     "mediatek,xsphy";
		#address-cells = <2>;
		#size-cells = <2>;
		ranges;
		status = "disabled";

		xphyu2port0: usb-phy at 11e10000 {
			reg = <0 0x11e10000 0 0x400>;
			clocks = <&infracfg CLK_INFRA_USB_UTMI>;
			clock-names = "ref";
			#phy-cells = <1>;
		};

		xphyu3port0: usb-phy at 11e13000 {
			reg = <0 0x11e13400 0 0x500>;
			clocks = <&infracfg CLK_INFRA_USB_PIPE>;
			clock-names = "ref";
			#phy-cells = <1>;
			mediatek,syscon-type = <&topmisc 0x218 0>;
		};
	};

maybe there are ways to avoid syscon without writing a dedicated driver
for the topmisc.
topmisc node itself is also used in ethernet-block mapped to the
mediatek,infracfg property.
---
 drivers/phy/mediatek/phy-mtk-xsphy.c | 85 +++++++++++++++++++++++++++-
 1 file changed, 84 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/mediatek/phy-mtk-xsphy.c b/drivers/phy/mediatek/phy-mtk-xsphy.c
index 7c248f5cfca5..3f94d0dee1b9 100644
--- a/drivers/phy/mediatek/phy-mtk-xsphy.c
+++ b/drivers/phy/mediatek/phy-mtk-xsphy.c
@@ -11,10 +11,12 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 
 #include "phy-mtk-io.h"
 
@@ -81,12 +83,22 @@
 #define XSP_SR_COEF_DIVISOR	1000
 #define XSP_FM_DET_CYCLE_CNT	1024
 
+/* PHY switch between pcie/usb3/sgmii */
+#define USB_PHY_SWITCH_CTRL	0x0
+#define RG_PHY_SW_TYPE		GENMASK(3, 0)
+#define RG_PHY_SW_PCIE		0x0
+#define RG_PHY_SW_USB3		0x1
+#define RG_PHY_SW_SGMII		0x2
+
 struct xsphy_instance {
 	struct phy *phy;
 	void __iomem *port_base;
 	struct clk *ref_clk;	/* reference clock of anolog phy */
 	u32 index;
 	u32 type;
+	struct regmap *type_sw;
+	u32 type_sw_reg;
+	u32 type_sw_index;
 	/* only for HQA test */
 	int efuse_intr;
 	int efuse_tx_imp;
@@ -259,6 +271,10 @@ static void phy_parse_property(struct mtk_xsphy *xsphy,
 			inst->efuse_intr, inst->efuse_tx_imp,
 			inst->efuse_rx_imp);
 		break;
+	case PHY_TYPE_PCIE:
+	case PHY_TYPE_SGMII:
+		/* nothing to do */
+		break;
 	default:
 		dev_err(xsphy->dev, "incompatible phy type\n");
 		return;
@@ -305,6 +321,62 @@ static void u3_phy_props_set(struct mtk_xsphy *xsphy,
 				     RG_XTP_LN0_RX_IMPSEL, inst->efuse_rx_imp);
 }
 
+/* type switch for usb3/pcie/sgmii */
+static int phy_type_syscon_get(struct xsphy_instance *instance,
+			       struct device_node *dn)
+{
+	struct of_phandle_args args;
+	int ret;
+
+	/* type switch function is optional */
+	if (!of_property_read_bool(dn, "mediatek,syscon-type"))
+		return 0;
+
+	ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type",
+					       2, 0, &args);
+	if (ret)
+		return ret;
+
+	instance->type_sw_reg = args.args[0];
+	instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
+	instance->type_sw = syscon_node_to_regmap(args.np);
+	of_node_put(args.np);
+	dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n",
+		 instance->type_sw_reg, instance->type_sw_index);
+
+	return PTR_ERR_OR_ZERO(instance->type_sw);
+}
+
+static int phy_type_set(struct xsphy_instance *instance)
+{
+	int type;
+	u32 offset;
+
+	if (!instance->type_sw)
+		return 0;
+
+	switch (instance->type) {
+	case PHY_TYPE_USB3:
+		type = RG_PHY_SW_USB3;
+		break;
+	case PHY_TYPE_PCIE:
+		type = RG_PHY_SW_PCIE;
+		break;
+	case PHY_TYPE_SGMII:
+		type = RG_PHY_SW_SGMII;
+		break;
+	case PHY_TYPE_USB2:
+	default:
+		return 0;
+	}
+
+	offset = instance->type_sw_index * BITS_PER_BYTE;
+	regmap_update_bits(instance->type_sw, instance->type_sw_reg,
+			   RG_PHY_SW_TYPE << offset, type << offset);
+
+	return 0;
+}
+
 static int mtk_phy_init(struct phy *phy)
 {
 	struct xsphy_instance *inst = phy_get_drvdata(phy);
@@ -325,6 +397,10 @@ static int mtk_phy_init(struct phy *phy)
 	case PHY_TYPE_USB3:
 		u3_phy_props_set(xsphy, inst);
 		break;
+	case PHY_TYPE_PCIE:
+	case PHY_TYPE_SGMII:
+		/* nothing to do, only used to set type */
+		break;
 	default:
 		dev_err(xsphy->dev, "incompatible phy type\n");
 		clk_disable_unprepare(inst->ref_clk);
@@ -403,12 +479,15 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 
 	inst->type = args->args[0];
 	if (!(inst->type == PHY_TYPE_USB2 ||
-	      inst->type == PHY_TYPE_USB3)) {
+	      inst->type == PHY_TYPE_USB3 ||
+	      inst->type == PHY_TYPE_PCIE ||
+	      inst->type == PHY_TYPE_SGMII)) {
 		dev_err(dev, "unsupported phy type: %d\n", inst->type);
 		return ERR_PTR(-EINVAL);
 	}
 
 	phy_parse_property(xsphy, inst);
+	phy_type_set(inst);
 
 	return inst->phy;
 }
@@ -510,6 +589,10 @@ static int mtk_xsphy_probe(struct platform_device *pdev)
 			dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
 			return PTR_ERR(inst->ref_clk);
 		}
+
+		retval = phy_type_syscon_get(inst, child_np);
+		if (retval)
+			return retval;
 	}
 
 	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-- 
2.43.0



From vkoul at kernel.org  Wed Dec  4 04:28:18 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 4 Dec 2024 17:58:18 +0530
Subject: [PATCH V6] dmaengine: bcm2835-dma: add suspend/resume pm support
In-Reply-To: <20241202114627.33401-1-wahrenst@gmx.net>
References: <20241202114627.33401-1-wahrenst@gmx.net>
Message-ID: <Z1BK4rcOvCoA+xdH@vaman>

On 02-12-24, 12:46, Stefan Wahren wrote:
> bcm2835-dma provides the service to others, so it should
> suspend late and resume early.

Expecting v7 with updated title and changelog and dropping resume

> 
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
> ---
>  drivers/dma/bcm2835-dma.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
>  Changes in V6:
>  - split out of series because there is no dependency
> 
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index 7ba52dee40a9..cf8a01a5b884 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -875,6 +875,35 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
>  	return chan;
>  }
> 
> +static int bcm2835_dma_suspend_late(struct device *dev)
> +{
> +	struct bcm2835_dmadev *od = dev_get_drvdata(dev);
> +	struct bcm2835_chan *c, *next;
> +
> +	list_for_each_entry_safe(c, next, &od->ddev.channels,
> +				 vc.chan.device_node) {
> +		void __iomem *chan_base = c->chan_base;
> +
> +		if (readl(chan_base + BCM2835_DMA_ADDR)) {
> +			dev_warn(dev, "Suspend is prevented by chan %d\n",
> +				 c->ch);
> +			return -EBUSY;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int bcm2835_dma_resume_early(struct device *dev)
> +{
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops bcm2835_dma_pm_ops = {
> +	SET_LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late,
> +				     bcm2835_dma_resume_early)
> +};
> +
>  static int bcm2835_dma_probe(struct platform_device *pdev)
>  {
>  	struct bcm2835_dmadev *od;
> @@ -1033,6 +1062,7 @@ static struct platform_driver bcm2835_dma_driver = {
>  	.driver = {
>  		.name = "bcm2835-dma",
>  		.of_match_table = of_match_ptr(bcm2835_dma_of_match),
> +		.pm = pm_ptr(&bcm2835_dma_pm_ops),
>  	},
>  };
> 
> --
> 2.34.1

-- 
~Vinod


From andy.yan at rock-chips.com  Wed Dec  4 04:41:01 2024
From: andy.yan at rock-chips.com (Andy Yan)
Date: Wed, 4 Dec 2024 20:41:01 +0800
Subject: [PATCH v3 3/3] drm/rockchip: Add MIPI DSI2 glue driver for RK3588
In-Reply-To: <20241203165450.1501219-4-heiko@sntech.de>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241203165450.1501219-4-heiko@sntech.de>
Message-ID: <06fa9c22-9b5c-4d22-bdcf-be011bbf14ca@rock-chips.com>

Hi Heiko,

On 12/4/24 00:54, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> This adds the glue code for the MIPI DSI2 bridge on Rockchip SoCs and
> enables its use on the RK3588.
> 
> Right now the DSI2 controller is always paired with a DC-phy based on a
> Samsung IP, so the interface values are set statically for now.
> This stays true for the upcoming RK3576 as well.
> 
> Tested-by: Daniel Semkowicz <dse at thaumatec.com>
> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
> ---
>   drivers/gpu/drm/rockchip/Kconfig              |  10 +
>   drivers/gpu/drm/rockchip/Makefile             |   1 +
>   .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c  | 524 ++++++++++++++++++
>   drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |   2 +
>   drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |   1 +
>   5 files changed, 538 insertions(+)
>   create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> 
> diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
> index 448fadd4ba15..84af423b7f90 100644
> --- a/drivers/gpu/drm/rockchip/Kconfig
> +++ b/drivers/gpu/drm/rockchip/Kconfig
> @@ -10,6 +10,7 @@ config DRM_ROCKCHIP
>   	select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
>   	select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP
>   	select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
> +	select DRM_DW_MIPI_DSI2 if ROCKCHIP_DW_MIPI_DSI2
>   	select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
>   	select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
>   	select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
> @@ -81,6 +82,15 @@ config ROCKCHIP_DW_MIPI_DSI
>   	  enable MIPI DSI on RK3288 or RK3399 based SoC, you should
>   	  select this option.
>   
> +config ROCKCHIP_DW_MIPI_DSI2
> +	bool "Rockchip specific extensions for Synopsys DW MIPI DSI2"
> +	select GENERIC_PHY_MIPI_DPHY
> +	help
> +	  This selects support for Rockchip SoC specific extensions
> +	  for the Synopsys DesignWare dsi driver. If you want to
           
          Maybe we should emphasize dsi2 driver here ?

> +	  enable MIPI DSI on RK3576 or RK3588 based SoC, you should
> +	  select this option.
> +
>   config ROCKCHIP_INNO_HDMI
>   	bool "Rockchip specific extensions for Innosilicon HDMI"
>   	select DRM_DISPLAY_HDMI_HELPER
> diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
> index 3eab662a5a1d..2b867cebbc12 100644
> --- a/drivers/gpu/drm/rockchip/Makefile
> +++ b/drivers/gpu/drm/rockchip/Makefile
> @@ -13,6 +13,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o
> +rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI2) += dw-mipi-dsi2-rockchip.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> new file mode 100644
> index 000000000000..55eed4001634
> --- /dev/null
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> @@ -0,0 +1,524 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2024 Rockchip Electronics Co.Ltd
> + * Author:
> + *      Guochun Huang <hero.huang at rock-chips.com>
> + *      Heiko Stuebner <heiko.stuebner at cherry.de>
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/media-bus-format.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/phy/phy.h>
> +
> +#include <drm/bridge/dw_mipi_dsi2.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_simple_kms_helper.h>
> +
> +#include <uapi/linux/videodev2.h>
> +
> +#include "rockchip_drm_drv.h"
> +#include "rockchip_drm_vop.h"

It seems that we don't use anything from rockchip_drm_vop.h ?

> +
> +#define PSEC_PER_SEC			1000000000000LL
> +
> +struct dsigrf_reg {
> +	u16 offset;
> +	u16 lsb;
> +	u16 msb;
> +};
> +
> +enum grf_reg_fields {
> +	TXREQCLKHS_EN,
> +	GATING_EN,
> +	IPI_SHUTDN,
> +	IPI_COLORM,
> +	IPI_COLOR_DEPTH,
> +	IPI_FORMAT,
> +	MAX_FIELDS,
> +};
> +
> +#define IPI_DEPTH_5_6_5_BITS		0x02
> +#define IPI_DEPTH_6_BITS		0x03
> +#define IPI_DEPTH_8_BITS		0x05
> +#define IPI_DEPTH_10_BITS		0x06
> +
> +struct rockchip_dw_dsi2_chip_data {
> +	u32 reg;
> +	const struct dsigrf_reg *grf_regs;
> +	unsigned long long max_bit_rate_per_lane;
> +};
> +
> +struct dw_mipi_dsi2_rockchip {
> +	struct device *dev;
> +	struct rockchip_encoder encoder;
> +	struct regmap *regmap;
> +	struct clk *pclk;
> +	struct clk *sys_clk;
> +
> +	unsigned int lane_mbps; /* per lane */
> +	u32 format;
> +
> +	struct regmap *grf_regmap;
> +	struct phy *phy;
> +	union phy_configure_opts phy_opts;
> +
> +	struct dw_mipi_dsi2 *dmd;
> +	struct dw_mipi_dsi2_plat_data pdata;
> +	const struct rockchip_dw_dsi2_chip_data *cdata;
> +};
> +
> +static inline struct dw_mipi_dsi2_rockchip *to_dsi2(struct drm_encoder *encoder)
> +{
> +	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
> +
> +	return container_of(rkencoder, struct dw_mipi_dsi2_rockchip, encoder);
> +}
> +
> +static void grf_field_write(struct dw_mipi_dsi2_rockchip *dsi2, enum grf_reg_fields index,
> +			    unsigned int val)
> +{
> +	const struct dsigrf_reg *field = &dsi2->cdata->grf_regs[index];
> +
> +	if (!field)
> +		return;
> +
> +	regmap_write(dsi2->grf_regmap, field->offset,
> +		     (val << field->lsb) | (GENMASK(field->msb, field->lsb) << 16));
> +}
> +
> +static int dw_mipi_dsi2_phy_init(void *priv_data)
> +{
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_phy_power_on(void *priv_data)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +	int ret;
> +
> +	ret = phy_set_mode(dsi2->phy, PHY_MODE_MIPI_DPHY);
> +	if (ret) {
> +		dev_err(dsi2->dev, "Failed to set phy mode: %d\n", ret);
> +		return;
> +	}
> +
> +	phy_configure(dsi2->phy, &dsi2->phy_opts);
> +	phy_power_on(dsi2->phy);
> +}
> +
> +static void dw_mipi_dsi2_phy_power_off(void *priv_data)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +
> +	phy_power_off(dsi2->phy);
> +}
> +
> +static int
> +dw_mipi_dsi2_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
> +			   unsigned long mode_flags, u32 lanes, u32 format,
> +			   unsigned int *lane_mbps)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +	u64 max_lane_rate, target_phyclk;
> +	unsigned int lane_rate_kbps;
> +	int bpp;
> +
> +	max_lane_rate = dsi2->cdata->max_bit_rate_per_lane;
> +
> +	dsi2->format = format;
> +	bpp = mipi_dsi_pixel_format_to_bpp(format);
> +	if (bpp < 0) {
> +		dev_err(dsi2->dev, "failed to get bpp for pixel format %d\n", format);
> +		return bpp;
> +	}
> +
> +	lane_rate_kbps = mode->clock * bpp / lanes;
> +
> +	/*
> +	 * Set BW a little larger only in video burst mode in
> +	 * consideration of the protocol overhead and HS mode
> +	 * switching to BLLP mode, take 1 / 0.9, since Mbps must
> +	 * big than bandwidth of RGB
> +	 */
> +	if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
> +		lane_rate_kbps = (lane_rate_kbps * 10) / 9;
> +
> +	if (lane_rate_kbps > max_lane_rate) {
> +		dev_err(dsi2->dev, "DPHY clock frequency is out of range\n");
> +		return -ERANGE;
> +	}
> +
> +	dsi2->lane_mbps = lane_rate_kbps / 1000;
> +	*lane_mbps = dsi2->lane_mbps;
> +
> +	if (dsi2->phy) {
> +		target_phyclk = DIV_ROUND_CLOSEST_ULL(lane_rate_kbps * lanes * 1000, bpp);
> +		phy_mipi_dphy_get_default_config(target_phyclk, bpp, lanes,
> +						 &dsi2->phy_opts.mipi_dphy);
> +	}
> +
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_phy_get_iface(void *priv_data, struct dw_mipi_dsi2_phy_iface *iface)
> +{
> +	/* PPI width is fixed to 16 bits in DCPHY */
> +	iface->ppi_width = 16;
> +	iface->phy_type = DW_MIPI_DSI2_DPHY;
> +}
> +
> +static int
> +dw_mipi_dsi2_phy_get_timing(void *priv_data, unsigned int lane_mbps,
> +			    struct dw_mipi_dsi2_phy_timing *timing)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +	struct phy_configure_opts_mipi_dphy *cfg = &dsi2->phy_opts.mipi_dphy;
> +	unsigned long long tmp, ui;
> +	unsigned long long hstx_clk;
> +
> +	hstx_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
> +
> +	ui = ALIGN(PSEC_PER_SEC, hstx_clk);
> +	do_div(ui, hstx_clk);
> +
> +	/* PHY_LP2HS_TIME = (TLPX + THS-PREPARE + THS-ZERO) / Tphy_hstx_clk */
> +	tmp = cfg->lpx + cfg->hs_prepare + cfg->hs_zero;
> +	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
> +	timing->data_lp2hs = tmp;
> +
> +	/* PHY_HS2LP_TIME = (THS-TRAIL + THS-EXIT) / Tphy_hstx_clk */
> +	tmp = cfg->hs_trail + cfg->hs_exit;
> +	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
> +	timing->data_hs2lp = tmp;
> +
> +	return 0;
> +}
> +
> +static const struct dw_mipi_dsi2_phy_ops dw_mipi_dsi2_rockchip_phy_ops = {
> +	.init = dw_mipi_dsi2_phy_init,
> +	.power_on = dw_mipi_dsi2_phy_power_on,
> +	.power_off = dw_mipi_dsi2_phy_power_off,
> +	.get_interface = dw_mipi_dsi2_phy_get_iface,
> +	.get_lane_mbps = dw_mipi_dsi2_get_lane_mbps,
> +	.get_timing = dw_mipi_dsi2_phy_get_timing,
> +};
> +
> +static void dw_mipi_dsi2_encoder_atomic_enable(struct drm_encoder *encoder,
> +					       struct drm_atomic_state *state)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
> +	u32 color_depth;
> +
> +	switch (dsi2->format) {
> +	case MIPI_DSI_FMT_RGB666:
> +	case MIPI_DSI_FMT_RGB666_PACKED:
> +		color_depth = IPI_DEPTH_6_BITS;
> +		break;
> +	case MIPI_DSI_FMT_RGB565:
> +		color_depth = IPI_DEPTH_5_6_5_BITS;
> +		break;
> +	case MIPI_DSI_FMT_RGB888:
> +		color_depth = IPI_DEPTH_8_BITS;
> +		break;
> +	default:
> +		/* Should've been caught by atomic_check */
> +		WARN_ON(1);
> +		return;
> +	}
> +
> +	grf_field_write(dsi2, IPI_COLOR_DEPTH, color_depth);
> +}
> +
> +static int
> +dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder,
> +				  struct drm_crtc_state *crtc_state,
> +				  struct drm_connector_state *conn_state)
> +{
> +	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
> +	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
> +	struct drm_connector *connector = conn_state->connector;
> +	struct drm_display_info *info = &connector->display_info;
> +
> +	switch (dsi2->format) {
> +	case MIPI_DSI_FMT_RGB666:
> +	case MIPI_DSI_FMT_RGB666_PACKED:
> +		s->output_mode = ROCKCHIP_OUT_MODE_P666;
> +		break;
> +	case MIPI_DSI_FMT_RGB565:
> +		s->output_mode = ROCKCHIP_OUT_MODE_P565;
> +		break;
> +	case MIPI_DSI_FMT_RGB888:
> +		s->output_mode = ROCKCHIP_OUT_MODE_P888;
> +		break;
> +	default:
> +		WARN_ON(1);
> +		return -EINVAL;
> +	}
> +
> +	if (info->num_bus_formats)
> +		s->bus_format = info->bus_formats[0];
> +	else
> +		s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
> +
> +	s->output_type = DRM_MODE_CONNECTOR_DSI;
> +	s->bus_flags = info->bus_flags;
> +	s->color_space = V4L2_COLORSPACE_DEFAULT;
> +
> +	return 0;
> +}
> +
> +static const struct drm_encoder_helper_funcs
> +dw_mipi_dsi2_encoder_helper_funcs = {
> +	.atomic_enable = dw_mipi_dsi2_encoder_atomic_enable,
> +	.atomic_check = dw_mipi_dsi2_encoder_atomic_check,
> +};
> +
> +static int rockchip_dsi2_drm_create_encoder(struct dw_mipi_dsi2_rockchip *dsi2,
> +					    struct drm_device *drm_dev)
> +{
> +	struct drm_encoder *encoder = &dsi2->encoder.encoder;
> +	int ret;
> +
> +	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
> +							     dsi2->dev->of_node);
> +
> +	ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI);
> +	if (ret) {
> +		dev_err(dsi2->dev, "Failed to initialize encoder with drm\n");
> +		return ret;
> +	}
> +
> +	drm_encoder_helper_add(encoder, &dw_mipi_dsi2_encoder_helper_funcs);
> +
> +	return 0;
> +}
> +
> +static int dw_mipi_dsi2_rockchip_bind(struct device *dev, struct device *master,
> +				      void *data)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
> +	struct drm_device *drm_dev = data;
> +	int ret;
> +
> +	ret = rockchip_dsi2_drm_create_encoder(dsi2, drm_dev);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to create drm encoder\n");
> +
> +	rockchip_drm_encoder_set_crtc_endpoint_id(&dsi2->encoder,
> +						  dev->of_node, 0, 0);
> +
> +	ret = dw_mipi_dsi2_bind(dsi2->dmd, &dsi2->encoder.encoder);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to bind\n");
> +
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_rockchip_unbind(struct device *dev, struct device *master,
> +					 void *data)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
> +
> +	dw_mipi_dsi2_unbind(dsi2->dmd);
> +}
> +
> +static const struct component_ops dw_mipi_dsi2_rockchip_ops = {
> +	.bind	= dw_mipi_dsi2_rockchip_bind,
> +	.unbind	= dw_mipi_dsi2_rockchip_unbind,
> +};
> +
> +static int dw_mipi_dsi2_rockchip_host_attach(void *priv_data,
> +					     struct mipi_dsi_device *device)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +	int ret;
> +
> +	ret = component_add(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
> +	if (ret)
> +		return dev_err_probe(dsi2->dev, ret, "Failed to register component\n");
> +
> +	return 0;
> +}
> +
> +static int dw_mipi_dsi2_rockchip_host_detach(void *priv_data,
> +					     struct mipi_dsi_device *device)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +
> +	component_del(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
> +
> +	return 0;
> +}
> +
> +static const struct dw_mipi_dsi2_host_ops dw_mipi_dsi2_rockchip_host_ops = {
> +	.attach = dw_mipi_dsi2_rockchip_host_attach,
> +	.detach = dw_mipi_dsi2_rockchip_host_detach,
> +};
> +
> +static __maybe_unused int dw_mipi_dsi2_runtime_suspend(struct device *dev)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
> +
> +	clk_disable_unprepare(dsi2->pclk);
> +	clk_disable_unprepare(dsi2->sys_clk);
> +
> +	return 0;
> +}
> +
> +static __maybe_unused int dw_mipi_dsi2_runtime_resume(struct device *dev)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
> +
> +	clk_prepare_enable(dsi2->pclk);
> +	clk_prepare_enable(dsi2->sys_clk);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops dw_mipi_dsi2_rockchip_pm_ops = {
> +	SET_RUNTIME_PM_OPS(dw_mipi_dsi2_runtime_suspend,
> +			   dw_mipi_dsi2_runtime_resume, NULL)
> +};
> +
> +static const struct regmap_config dw_mipi_dsi2_rockchip_regmap_config = {
> +	.name = "dsi2-host",
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.fast_io = true,
> +};
> +
> +static int dw_mipi_dsi2_rockchip_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	const struct rockchip_dw_dsi2_chip_data *cdata =
> +						of_device_get_match_data(dev);
> +	struct dw_mipi_dsi2_rockchip *dsi2;
> +	struct resource *res;
> +	void __iomem *base;
> +	int i;
> +
> +	dsi2 = devm_kzalloc(dev, sizeof(*dsi2), GFP_KERNEL);
> +	if (!dsi2)
> +		return -ENOMEM;
> +
> +	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> +	if (IS_ERR(base))
> +		return dev_err_probe(dev, PTR_ERR(base), "Unable to get dsi registers\n");
> +
> +	dsi2->regmap = devm_regmap_init_mmio(dev, base, &dw_mipi_dsi2_rockchip_regmap_config);
> +	if (IS_ERR(dsi2->regmap))
> +		return dev_err_probe(dev, PTR_ERR(dsi2->regmap), "failed to init register map\n");
> +
> +	i = 0;
> +	while (cdata[i].reg) {
> +		if (cdata[i].reg == res->start) {
> +			dsi2->cdata = &cdata[i];
> +			break;
> +		}
> +
> +		i++;
> +	}
> +
> +	if (!dsi2->cdata)
> +		return dev_err_probe(dev, -EINVAL, "No dsi-config for %s node\n", np->name);
> +
> +	dsi2->pclk = devm_clk_get(dev, "pclk");
> +	if (IS_ERR(dsi2->pclk))
> +		return dev_err_probe(dev, PTR_ERR(dsi2->pclk), "Unable to get pclk\n");
> +
> +	dsi2->sys_clk = devm_clk_get(dev, "sys");
> +	if (IS_ERR(dsi2->sys_clk))
> +		return dev_err_probe(dev, PTR_ERR(dsi2->sys_clk), "Unable to get sys_clk\n");

Do we really need to get pclk and sys clk here? __dw_mipi_dsi2_probe will also do this .

> +
> +	dsi2->grf_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
> +	if (IS_ERR(dsi2->grf_regmap))
> +		return dev_err_probe(dsi2->dev, PTR_ERR(dsi2->grf_regmap), "Unable to get grf\n");
> +
> +	dsi2->phy = devm_phy_optional_get(dev, "dcphy");
> +	if (IS_ERR(dsi2->phy))
> +		return dev_err_probe(dev, PTR_ERR(dsi2->phy), "failed to get mipi phy\n");
> +
> +	dsi2->dev = dev;
> +	dsi2->pdata.regmap = dsi2->regmap;
> +	dsi2->pdata.max_data_lanes = 4;
> +	dsi2->pdata.phy_ops = &dw_mipi_dsi2_rockchip_phy_ops;
> +	dsi2->pdata.host_ops = &dw_mipi_dsi2_rockchip_host_ops;
> +	dsi2->pdata.priv_data = dsi2;
> +	platform_set_drvdata(pdev, dsi2);
> +
> +	dsi2->dmd = dw_mipi_dsi2_probe(pdev, &dsi2->pdata);
> +	if (IS_ERR(dsi2->dmd))
> +		return dev_err_probe(dev, PTR_ERR(dsi2->dmd), "Failed to probe dw_mipi_dsi2\n");
> +
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_rockchip_remove(struct platform_device *pdev)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = platform_get_drvdata(pdev);
> +
> +	dw_mipi_dsi2_remove(dsi2->dmd);
> +}
> +
> +static const struct dsigrf_reg rk3588_dsi0_grf_reg_fields[MAX_FIELDS] = {
> +	[TXREQCLKHS_EN]		= { 0x0000, 11, 11 },
> +	[GATING_EN]		= { 0x0000, 10, 10 },
> +	[IPI_SHUTDN]		= { 0x0000,  9,  9 },
> +	[IPI_COLORM]		= { 0x0000,  8,  8 },
> +	[IPI_COLOR_DEPTH]	= { 0x0000,  4,  7 },
> +	[IPI_FORMAT]		= { 0x0000,  0,  3 },
> +};
> +
> +static const struct dsigrf_reg rk3588_dsi1_grf_reg_fields[MAX_FIELDS] = {
> +	[TXREQCLKHS_EN]		= { 0x0004, 11, 11 },
> +	[GATING_EN]		= { 0x0004, 10, 10 },
> +	[IPI_SHUTDN]		= { 0x0004,  9,  9 },
> +	[IPI_COLORM]		= { 0x0004,  8,  8 },
> +	[IPI_COLOR_DEPTH]	= { 0x0004,  4,  7 },
> +	[IPI_FORMAT]		= { 0x0004,  0,  3 },
> +};
> +
> +static const struct rockchip_dw_dsi2_chip_data rk3588_chip_data[] = {
> +	{
> +		.reg = 0xfde20000,
> +		.grf_regs = rk3588_dsi0_grf_reg_fields,
> +		.max_bit_rate_per_lane = 4500000ULL,
> +	},
> +	{
> +		.reg = 0xfde30000,
> +		.grf_regs = rk3588_dsi1_grf_reg_fields,
> +		.max_bit_rate_per_lane = 4500000ULL,
> +	}
> +};
> +
> +static const struct of_device_id dw_mipi_dsi2_rockchip_dt_ids[] = {
> +	{
> +		.compatible = "rockchip,rk3588-mipi-dsi2",
> +		.data = &rk3588_chip_data,
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, dw_mipi_dsi2_rockchip_dt_ids);
> +
> +struct platform_driver dw_mipi_dsi2_rockchip_driver = {
> +	.probe	= dw_mipi_dsi2_rockchip_probe,
> +	.remove = dw_mipi_dsi2_rockchip_remove,
> +	.driver = {
> +		.of_match_table = dw_mipi_dsi2_rockchip_dt_ids,
> +		.pm = &dw_mipi_dsi2_rockchip_pm_ops,
> +		.name = "dw-mipi-dsi2",
> +	},
> +};
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index ddf0be331c0a..5327ce035003 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -511,6 +511,8 @@ static int __init rockchip_drm_init(void)
>   				CONFIG_ROCKCHIP_DW_HDMI_QP);
>   	ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver,
>   				CONFIG_ROCKCHIP_DW_MIPI_DSI);
> +	ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi2_rockchip_driver,
> +				CONFIG_ROCKCHIP_DW_MIPI_DSI2);
>   	ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI);
>   	ADD_ROCKCHIP_SUB_DRIVER(rk3066_hdmi_driver,
>   				CONFIG_ROCKCHIP_RK3066_HDMI);
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> index 24b4ce5ceaf1..9c9d38a06cdf 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> @@ -90,6 +90,7 @@ extern struct platform_driver cdn_dp_driver;
>   extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
>   extern struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver;
>   extern struct platform_driver dw_mipi_dsi_rockchip_driver;
> +extern struct platform_driver dw_mipi_dsi2_rockchip_driver;
>   extern struct platform_driver inno_hdmi_driver;
>   extern struct platform_driver rockchip_dp_driver;
>   extern struct platform_driver rockchip_lvds_driver;


From maz at kernel.org  Wed Dec  4 04:45:45 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:45 +0000
Subject: [PATCH 07/11] irqchip/loongson-pch-msi: Convert to msi_create_parent_irq_domain() helper
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-8-maz@kernel.org>

Now that we have a concise helper to create an MSI parent domain,
switch the Loongson MSI stuff over to that.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-loongson-pch-msi.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-loongson-pch-msi.c b/drivers/irqchip/irq-loongson-pch-msi.c
index 3f6f4e9887c53..f15528f76a647 100644
--- a/drivers/irqchip/irq-loongson-pch-msi.c
+++ b/drivers/irqchip/irq-loongson-pch-msi.c
@@ -158,20 +158,15 @@ static int pch_msi_init_domains(struct pch_msi_data *priv,
 {
 	struct irq_domain *middle_domain;
 
-	middle_domain = irq_domain_create_hierarchy(parent, 0, priv->num_irqs,
-						    domain_handle,
-						    &pch_msi_middle_domain_ops,
-						    priv);
+	middle_domain = msi_create_parent_irq_domain(domain_handle,
+						     &pch_msi_parent_ops,
+						     &pch_msi_middle_domain_ops, 0,
+						     priv->num_irqs, priv, parent);
 	if (!middle_domain) {
 		pr_err("Failed to create the MSI middle domain\n");
 		return -ENOMEM;
 	}
 
-	irq_domain_update_bus_token(middle_domain, DOMAIN_BUS_NEXUS);
-
-	middle_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-	middle_domain->msi_parent_ops = &pch_msi_parent_ops;
-
 	return 0;
 }
 
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:39 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:39 +0000
Subject: [PATCH 01/11] irqchip: Make irq-msi-lib.h globally available
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-2-maz@kernel.org>

Move irq-msi-lib.h into include/linux/irqchip, making it available
to compilation units outside of drivers/irqchip. This requires some
churn in drivers to fetch it from the new location.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-gic-v2m.c                    | 2 +-
 drivers/irqchip/irq-gic-v3-its-msi-parent.c      | 2 +-
 drivers/irqchip/irq-gic-v3-its.c                 | 2 +-
 drivers/irqchip/irq-gic-v3-mbi.c                 | 2 +-
 drivers/irqchip/irq-imx-mu-msi.c                 | 2 +-
 drivers/irqchip/irq-loongarch-avec.c             | 2 +-
 drivers/irqchip/irq-loongson-pch-msi.c           | 2 +-
 drivers/irqchip/irq-msi-lib.c                    | 2 +-
 drivers/irqchip/irq-mvebu-gicp.c                 | 2 +-
 drivers/irqchip/irq-mvebu-icu.c                  | 2 +-
 drivers/irqchip/irq-mvebu-odmi.c                 | 2 +-
 drivers/irqchip/irq-mvebu-sei.c                  | 2 +-
 {drivers => include/linux}/irqchip/irq-msi-lib.h | 6 +++---
 13 files changed, 15 insertions(+), 15 deletions(-)
 rename {drivers => include/linux}/irqchip/irq-msi-lib.h (84%)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index be35c5349986a..db79ae622f3c4 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -26,7 +26,7 @@
 #include <linux/irqchip/arm-gic.h>
 #include <linux/irqchip/arm-gic-common.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 /*
 * MSI_TYPER:
diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
index e150365fbe892..b4adee2a1aaae 100644
--- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
@@ -8,7 +8,7 @@
 #include <linux/pci.h>
 
 #include "irq-gic-common.h"
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 #define ITS_MSI_FLAGS_REQUIRED  (MSI_FLAG_USE_DEF_DOM_OPS |	\
 				 MSI_FLAG_USE_DEF_CHIP_OPS |	\
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 92244cfa04647..334fd15be1de1 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -41,7 +41,7 @@
 #include <asm/exception.h>
 
 #include "irq-gic-common.h"
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375	(1ULL << 1)
diff --git a/drivers/irqchip/irq-gic-v3-mbi.c b/drivers/irqchip/irq-gic-v3-mbi.c
index 3fe870f8ee174..63c658375fd55 100644
--- a/drivers/irqchip/irq-gic-v3-mbi.c
+++ b/drivers/irqchip/irq-gic-v3-mbi.c
@@ -18,7 +18,7 @@
 
 #include <linux/irqchip/arm-gic-v3.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 struct mbi_range {
 	u32			spi_start;
diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c
index 4342a21de1eb0..b3f656c6e7708 100644
--- a/drivers/irqchip/irq-imx-mu-msi.c
+++ b/drivers/irqchip/irq-imx-mu-msi.c
@@ -24,7 +24,7 @@
 #include <linux/pm_domain.h>
 #include <linux/spinlock.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 #define IMX_MU_CHANS            4
 
diff --git a/drivers/irqchip/irq-loongarch-avec.c b/drivers/irqchip/irq-loongarch-avec.c
index 0f6e465dd3095..c95704707219d 100644
--- a/drivers/irqchip/irq-loongarch-avec.c
+++ b/drivers/irqchip/irq-loongarch-avec.c
@@ -18,7 +18,7 @@
 #include <asm/loongarch.h>
 #include <asm/setup.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 #include "irq-loongson.h"
 
 #define VECTORS_PER_REG		64
diff --git a/drivers/irqchip/irq-loongson-pch-msi.c b/drivers/irqchip/irq-loongson-pch-msi.c
index bd337ecddb409..3f6f4e9887c53 100644
--- a/drivers/irqchip/irq-loongson-pch-msi.c
+++ b/drivers/irqchip/irq-loongson-pch-msi.c
@@ -15,7 +15,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 #include "irq-loongson.h"
 
 static int nr_pics;
diff --git a/drivers/irqchip/irq-msi-lib.c b/drivers/irqchip/irq-msi-lib.c
index d8e29fc0d4068..514b2616d9559 100644
--- a/drivers/irqchip/irq-msi-lib.c
+++ b/drivers/irqchip/irq-msi-lib.c
@@ -4,7 +4,7 @@
 
 #include <linux/export.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 /**
  * msi_lib_init_dev_msi_info - Domain info setup for MSI domains
diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c
index 2b6183919ea48..b206b7fe03f17 100644
--- a/drivers/irqchip/irq-mvebu-gicp.c
+++ b/drivers/irqchip/irq-mvebu-gicp.c
@@ -17,7 +17,7 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
diff --git a/drivers/irqchip/irq-mvebu-icu.c b/drivers/irqchip/irq-mvebu-icu.c
index b337f6c05f184..30d51a26ea05f 100644
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -20,7 +20,7 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 #include <dt-bindings/interrupt-controller/mvebu-icu.h>
 
diff --git a/drivers/irqchip/irq-mvebu-odmi.c b/drivers/irqchip/irq-mvebu-odmi.c
index ff19bfd258dce..0ba39fbdb451f 100644
--- a/drivers/irqchip/irq-mvebu-odmi.c
+++ b/drivers/irqchip/irq-mvebu-odmi.c
@@ -18,7 +18,7 @@
 #include <linux/of_address.h>
 #include <linux/slab.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c
index 065166ab5dbc0..c12e650ae7c92 100644
--- a/drivers/irqchip/irq-mvebu-sei.c
+++ b/drivers/irqchip/irq-mvebu-sei.c
@@ -14,7 +14,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
 
 /* Cause register */
 #define GICP_SECR(idx)		(0x0  + ((idx) * 0x4))
diff --git a/drivers/irqchip/irq-msi-lib.h b/include/linux/irqchip/irq-msi-lib.h
similarity index 84%
rename from drivers/irqchip/irq-msi-lib.h
rename to include/linux/irqchip/irq-msi-lib.h
index 681ceabb7bc74..dd8d1d1385449 100644
--- a/drivers/irqchip/irq-msi-lib.h
+++ b/include/linux/irqchip/irq-msi-lib.h
@@ -2,8 +2,8 @@
 // Copyright (C) 2022 Linutronix GmbH
 // Copyright (C) 2022 Intel
 
-#ifndef _DRIVERS_IRQCHIP_IRQ_MSI_LIB_H
-#define _DRIVERS_IRQCHIP_IRQ_MSI_LIB_H
+#ifndef _IRQCHIP_IRQ_MSI_LIB_H
+#define _IRQCHIP_IRQ_MSI_LIB_H
 
 #include <linux/bits.h>
 #include <linux/irqdomain.h>
@@ -24,4 +24,4 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 			       struct irq_domain *real_parent,
 			       struct msi_domain_info *info);
 
-#endif /* _DRIVERS_IRQCHIP_IRQ_MSI_LIB_H */
+#endif /* _IRQCHIP_IRQ_MSI_LIB_H */
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:38 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:38 +0000
Subject: [PATCH 00/11] irqchip: MSI parent cleanup and PCI host driver conversion
Message-ID: <20241204124549.607054-1-maz@kernel.org>

I've become annoyed by the couple of machines I have around that
haven't been converted to the per-device MSI infrastructure.  At the
same time, I've also moaned at the amount of boilerplate code required
to make use of this infrastructure.

This series therefore does a number of things:

- make irq-msi-lib.h globally available, so that PCI (and other
  subsystems) may make use of it

- add a new helper (msi_create_parent_irq_domain()) that encapsulates
  most of the magic required to create an MSI-parent domain

- convert all the existing users *except* arch/x86/kernel/apic/msi.c,
  which is far too esoteric for me to touch it

- convert the Apple and XGene MSI drivers to the MSI-parent
  infrastructure, which is why I came here the first place.

I've only tested the arm64 stuff I have access to (or care about), and
I would appreciate the respective maintainers/users of the other
drivers to give it a go, or at least a cursory look.

Patches on top of 6.13-rc1.

Marc Zyngier (11):
  irqchip: Make irq-msi-lib.h globally available
  genirq/msi: Add helper for creating MSI-parent irq domains
  irqchip/gic: Convert to msi_create_parent_irq_domain() helper
  irqchip/mvebu: Convert to msi_create_parent_irq_domain() helper
  irqchip/riscv-imsic: Convert to msi_create_parent_irq_domain() helper
  irqchip/imx-mu-msi: Convert to msi_create_parent_irq_domain() helper
  irqchip/loongson-pch-msi: Convert to msi_create_parent_irq_domain()
    helper
  iommu/amd: Convert to msi_create_parent_irq_domain() helper
  iommu/intel: Convert to msi_create_parent_irq_domain() helper
  PCI: apple: Convert to MSI parent infrastructure
  PCI: xgene: Convert to MSI parent infrastructure

 drivers/iommu/amd/iommu.c                     | 12 ++--
 drivers/iommu/intel/irq_remapping.c           | 16 ++----
 drivers/irqchip/irq-gic-v2m.c                 | 11 ++--
 drivers/irqchip/irq-gic-v3-its-msi-parent.c   |  2 +-
 drivers/irqchip/irq-gic-v3-its.c              | 16 ++----
 drivers/irqchip/irq-gic-v3-mbi.c              | 11 ++--
 drivers/irqchip/irq-imx-mu-msi.c              | 10 ++--
 drivers/irqchip/irq-loongarch-avec.c          |  2 +-
 drivers/irqchip/irq-loongson-pch-msi.c        | 15 ++---
 drivers/irqchip/irq-msi-lib.c                 |  2 +-
 drivers/irqchip/irq-mvebu-gicp.c              | 14 ++---
 drivers/irqchip/irq-mvebu-icu.c               |  2 +-
 drivers/irqchip/irq-mvebu-odmi.c              | 15 ++---
 drivers/irqchip/irq-mvebu-sei.c               | 16 ++----
 drivers/irqchip/irq-riscv-imsic-platform.c    | 11 ++--
 drivers/pci/controller/Kconfig                |  2 +
 drivers/pci/controller/pci-xgene-msi.c        | 44 +++++---------
 drivers/pci/controller/pcie-apple.c           | 57 ++++++-------------
 .../linux}/irqchip/irq-msi-lib.h              |  6 +-
 include/linux/msi.h                           |  7 +++
 kernel/irq/msi.c                              | 40 +++++++++++++
 21 files changed, 146 insertions(+), 165 deletions(-)
 rename {drivers => include/linux}/irqchip/irq-msi-lib.h (84%)

-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:40 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:40 +0000
Subject: [PATCH 02/11] genirq/msi: Add helper for creating MSI-parent irq domains
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-3-maz@kernel.org>

Creating an irq domain that serves as an MSI parent requires
a substantial amount of esoteric boiler-plate code, some of
which is often provided twice (such as the bus token).

To make things a bit simpler for the unsuspecting MSI tinkerer,
provide a helper that does it for them, and serves as documentation
of what needs to be provided.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 include/linux/msi.h |  7 +++++++
 kernel/irq/msi.c    | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/include/linux/msi.h b/include/linux/msi.h
index b10093c4d00ea..f08d14cf07103 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -594,6 +594,13 @@ struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
 					 struct msi_domain_info *info,
 					 struct irq_domain *parent);
 
+struct irq_domain *msi_create_parent_irq_domain(struct fwnode_handle *fwnode,
+						const struct msi_parent_ops *msi_parent_ops,
+						const struct irq_domain_ops *ops,
+						unsigned long flags, unsigned long size,
+						void *host_data,
+						struct irq_domain *parent);
+
 bool msi_create_device_irq_domain(struct device *dev, unsigned int domid,
 				  const struct msi_domain_template *template,
 				  unsigned int hwsize, void *domain_data,
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index 396a067a8a56b..037d85cf0b21c 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -885,6 +885,46 @@ struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
 	return __msi_create_irq_domain(fwnode, info, 0, parent);
 }
 
+/**
+ * msi_create_parent_irq_domain - Create an MSI-parent interrupt domain
+ * @fwnode:		Optional fwnode of the interrupt controller
+ * @msi_parent_ops:	MSI parent callbacks and configuration
+ * @ops:		Interrupt domain ballbacks
+ * @flags:		Interrupt domain flags
+ * @size:		Interrupt domain size (0 if arbitrarily large)
+ * @host_data:		Interrupt domain private data
+ * @parent:		Parent irq domain
+ *
+ * Return: pointer to the created &struct irq_domain or %NULL on failure
+ */
+struct irq_domain *msi_create_parent_irq_domain(struct fwnode_handle *fwnode,
+						const struct msi_parent_ops *msi_parent_ops,
+						const struct irq_domain_ops *ops,
+						unsigned long flags, unsigned long size,
+						void *host_data,
+						struct irq_domain *parent)
+{
+	struct irq_domain_info info = {
+		.fwnode		= fwnode,
+		.size		= size,
+		.hwirq_max	= size,
+		.ops		= ops,
+		.host_data	= host_data,
+		.domain_flags	= flags | IRQ_DOMAIN_FLAG_MSI_PARENT,
+		.parent		= parent,
+		.bus_token	= msi_parent_ops->bus_select_token,
+	};
+	struct irq_domain *d;
+
+	d = irq_domain_instantiate(&info);
+	if (IS_ERR(d))
+		return NULL;
+
+	d->msi_parent_ops = msi_parent_ops;
+	return d;
+}
+EXPORT_SYMBOL_GPL(msi_create_parent_irq_domain);
+
 /**
  * msi_parent_init_dev_msi_info - Delegate initialization of device MSI info down
  *				  in the domain hierarchy
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:41 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:41 +0000
Subject: [PATCH 03/11] irqchip/gic: Convert to msi_create_parent_irq_domain() helper
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-4-maz@kernel.org>

Now that we have a concise helper to create an MSI parent domain,
switch the GIC family over to that.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-gic-v2m.c    |  9 ++++-----
 drivers/irqchip/irq-gic-v3-its.c | 14 +++++---------
 drivers/irqchip/irq-gic-v3-mbi.c |  9 ++++-----
 3 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index db79ae622f3c4..4916743aed314 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -270,16 +270,15 @@ static __init int gicv2m_allocate_domains(struct irq_domain *parent)
 	if (!v2m)
 		return 0;
 
-	inner_domain = irq_domain_create_hierarchy(parent, 0, 0, v2m->fwnode,
-						   &gicv2m_domain_ops, v2m);
+	inner_domain = msi_create_parent_irq_domain(v2m->fwnode,
+						    &gicv2m_msi_parent_ops,
+						    &gicv2m_domain_ops,
+						    0, 0, v2m, parent);
 	if (!inner_domain) {
 		pr_err("Failed to create GICv2m domain\n");
 		return -ENOMEM;
 	}
 
-	irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
-	inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-	inner_domain->msi_parent_ops = &gicv2m_msi_parent_ops;
 	return 0;
 }
 
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 334fd15be1de1..6f61ee7c5d394 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -5114,20 +5114,16 @@ static int its_init_domain(struct its_node *its)
 	info->ops = &its_msi_domain_ops;
 	info->data = its;
 
-	inner_domain = irq_domain_create_hierarchy(its_parent,
-						   its->msi_domain_flags, 0,
-						   its->fwnode_handle, &its_domain_ops,
-						   info);
+	inner_domain = msi_create_parent_irq_domain(its->fwnode_handle,
+						    &gic_v3_its_msi_parent_ops,
+						    &its_domain_ops,
+						    its->msi_domain_flags, 0,
+						    info, its_parent);
 	if (!inner_domain) {
 		kfree(info);
 		return -ENOMEM;
 	}
 
-	irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
-
-	inner_domain->msi_parent_ops = &gic_v3_its_msi_parent_ops;
-	inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-
 	return 0;
 }
 
diff --git a/drivers/irqchip/irq-gic-v3-mbi.c b/drivers/irqchip/irq-gic-v3-mbi.c
index 63c658375fd55..e5f532f95148d 100644
--- a/drivers/irqchip/irq-gic-v3-mbi.c
+++ b/drivers/irqchip/irq-gic-v3-mbi.c
@@ -211,14 +211,13 @@ static int mbi_allocate_domain(struct irq_domain *parent)
 {
 	struct irq_domain *nexus_domain;
 
-	nexus_domain = irq_domain_create_hierarchy(parent, 0, 0, parent->fwnode,
-						   &mbi_domain_ops, NULL);
+	nexus_domain = msi_create_parent_irq_domain(parent->fwnode,
+						    &gic_v3_mbi_msi_parent_ops,
+						    &mbi_domain_ops,
+						    0, 0, NULL, parent);
 	if (!nexus_domain)
 		return -ENOMEM;
 
-	irq_domain_update_bus_token(nexus_domain, DOMAIN_BUS_NEXUS);
-	nexus_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-	nexus_domain->msi_parent_ops = &gic_v3_mbi_msi_parent_ops;
 	return 0;
 }
 
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:42 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:42 +0000
Subject: [PATCH 04/11] irqchip/mvebu: Convert to msi_create_parent_irq_domain() helper
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-5-maz@kernel.org>

Now that we have a concise helper to create an MSI parent domain,
switch the mvebu family of interrupt controllers over to that.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-mvebu-gicp.c | 12 +++++-------
 drivers/irqchip/irq-mvebu-odmi.c | 13 +++++--------
 drivers/irqchip/irq-mvebu-sei.c  | 14 +++++---------
 3 files changed, 15 insertions(+), 24 deletions(-)

diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c
index b206b7fe03f17..783bfc83c2607 100644
--- a/drivers/irqchip/irq-mvebu-gicp.c
+++ b/drivers/irqchip/irq-mvebu-gicp.c
@@ -229,16 +229,14 @@ static int mvebu_gicp_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	inner_domain = irq_domain_create_hierarchy(parent_domain, 0,
-						   gicp->spi_cnt,
-						   of_node_to_fwnode(node),
-						   &gicp_domain_ops, gicp);
+	inner_domain = msi_create_parent_irq_domain(of_node_to_fwnode(node),
+						    &gicp_msi_parent_ops,
+						    &gicp_domain_ops,
+						    0, gicp->spi_cnt, gicp,
+						    parent_domain);
 	if (!inner_domain)
 		return -ENOMEM;
 
-	irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_GENERIC_MSI);
-	inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-	inner_domain->msi_parent_ops = &gicp_msi_parent_ops;
 	return 0;
 }
 
diff --git a/drivers/irqchip/irq-mvebu-odmi.c b/drivers/irqchip/irq-mvebu-odmi.c
index 0ba39fbdb451f..74308b1cc01f1 100644
--- a/drivers/irqchip/irq-mvebu-odmi.c
+++ b/drivers/irqchip/irq-mvebu-odmi.c
@@ -204,19 +204,16 @@ static int __init mvebu_odmi_init(struct device_node *node,
 
 	parent_domain = irq_find_host(parent);
 
-	inner_domain = irq_domain_create_hierarchy(parent_domain, 0,
-						   odmis_count * NODMIS_PER_FRAME,
-						   of_node_to_fwnode(node),
-						   &odmi_domain_ops, NULL);
+	inner_domain = msi_create_parent_irq_domain(of_node_to_fwnode(node),
+						    &odmi_msi_parent_ops,
+						    &odmi_domain_ops, 0,
+						    odmis_count * NODMIS_PER_FRAME,
+						    NULL, parent_domain);
 	if (!inner_domain) {
 		ret = -ENOMEM;
 		goto err_unmap;
 	}
 
-	irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_GENERIC_MSI);
-	inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-	inner_domain->msi_parent_ops = &odmi_msi_parent_ops;
-
 	return 0;
 
 err_unmap:
diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c
index c12e650ae7c92..26e1a436af2d1 100644
--- a/drivers/irqchip/irq-mvebu-sei.c
+++ b/drivers/irqchip/irq-mvebu-sei.c
@@ -429,21 +429,17 @@ static int mvebu_sei_probe(struct platform_device *pdev)
 	irq_domain_update_bus_token(sei->ap_domain, DOMAIN_BUS_WIRED);
 
 	/* Create the 'MSI' domain */
-	sei->cp_domain = irq_domain_create_hierarchy(sei->sei_domain, 0,
-						     sei->caps->cp_range.size,
-						     of_node_to_fwnode(node),
-						     &mvebu_sei_cp_domain_ops,
-						     sei);
+	sei->cp_domain = msi_create_parent_irq_domain(of_node_to_fwnode(node),
+						      &sei_msi_parent_ops,
+						      &mvebu_sei_cp_domain_ops,
+						      0, sei->caps->cp_range.size,
+						      sei, sei->sei_domain);
 	if (!sei->cp_domain) {
 		pr_err("Failed to create CPs IRQ domain\n");
 		ret = -ENOMEM;
 		goto remove_ap_domain;
 	}
 
-	irq_domain_update_bus_token(sei->cp_domain, DOMAIN_BUS_GENERIC_MSI);
-	sei->cp_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-	sei->cp_domain->msi_parent_ops = &sei_msi_parent_ops;
-
 	mvebu_sei_reset(sei);
 
 	irq_set_chained_handler_and_data(parent_irq, mvebu_sei_handle_cascade_irq, sei);
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:43 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:43 +0000
Subject: [PATCH 05/11] irqchip/riscv-imsic: Convert to msi_create_parent_irq_domain() helper
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-6-maz@kernel.org>

Now that we have a concise helper to create an MSI parent domain,
switch the RISC-V letter soup over to that.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index c708780e8760f..3fbc3a8eb3be8 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -325,16 +325,15 @@ int imsic_irqdomain_init(void)
 	}
 
 	/* Create Base IRQ domain */
-	imsic->base_domain = irq_domain_create_tree(imsic->fwnode,
-						    &imsic_base_domain_ops, imsic);
+	imsic->base_domain = msi_create_parent_irq_domain(imsic->fwnode,
+							  &imsic_msi_parent_ops,
+							  &imsic_base_domain_ops,
+							  0, 0, imsic, NULL);
+	
 	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",
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:44 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:44 +0000
Subject: [PATCH 06/11] irqchip/imx-mu-msi: Convert to msi_create_parent_irq_domain() helper
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-7-maz@kernel.org>

Now that we have a concise helper to create an MSI parent domain,
switch the IMX letter soup over to that.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-imx-mu-msi.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c
index b3f656c6e7708..b73968423bb9f 100644
--- a/drivers/irqchip/irq-imx-mu-msi.c
+++ b/drivers/irqchip/irq-imx-mu-msi.c
@@ -226,17 +226,15 @@ static int imx_mu_msi_domains_init(struct imx_mu_msi *msi_data, struct device *d
 	struct irq_domain *parent;
 
 	/* Initialize MSI domain parent */
-	parent = irq_domain_create_linear(fwnodes, IMX_MU_CHANS,
-					  &imx_mu_msi_domain_ops, msi_data);
+	parent = msi_create_parent_irq_domain(fwnodes, &imx_mu_msi_parent_ops,
+					      &imx_mu_msi_domain_ops, 0,
+					      IMX_MU_CHANS, msi_data, NULL);
 	if (!parent) {
 		dev_err(dev, "failed to create IRQ domain\n");
 		return -ENOMEM;
 	}
 
-	irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS);
 	parent->dev = parent->pm_dev = dev;
-	parent->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-	parent->msi_parent_ops = &imx_mu_msi_parent_ops;
 	return 0;
 }
 
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:47 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:47 +0000
Subject: [PATCH 09/11] iommu/intel: Convert to msi_create_parent_irq_domain() helper
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-10-maz@kernel.org>

Now that we have a concise helper to create an MSI parent domain,
switch the Intel IOMMU remapping over to that.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/iommu/intel/irq_remapping.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/intel/irq_remapping.c b/drivers/iommu/intel/irq_remapping.c
index 466c1412dd456..7ca3ee4c985c9 100644
--- a/drivers/iommu/intel/irq_remapping.c
+++ b/drivers/iommu/intel/irq_remapping.c
@@ -557,21 +557,16 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu)
 	if (!fn)
 		goto out_free_bitmap;
 
-	iommu->ir_domain =
-		irq_domain_create_hierarchy(arch_get_ir_parent_domain(),
-					    0, INTR_REMAP_TABLE_ENTRIES,
-					    fn, &intel_ir_domain_ops,
-					    iommu);
+	iommu->ir_domain = msi_create_parent_irq_domain(fn, &dmar_msi_parent_ops,
+							&intel_ir_domain_ops,
+							IRQ_DOMAIN_FLAG_ISOLATED_MSI,
+							INTR_REMAP_TABLE_ENTRIES,
+							iommu, arch_get_ir_parent_domain());
 	if (!iommu->ir_domain) {
 		pr_err("IR%d: failed to allocate irqdomain\n", iommu->seq_id);
 		goto out_free_fwnode;
 	}
 
-	irq_domain_update_bus_token(iommu->ir_domain,  DOMAIN_BUS_DMAR);
-	iommu->ir_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT |
-				   IRQ_DOMAIN_FLAG_ISOLATED_MSI;
-	iommu->ir_domain->msi_parent_ops = &dmar_msi_parent_ops;
-
 	ir_table->base = ir_table_base;
 	ir_table->bitmap = bitmap;
 	iommu->ir_table = ir_table;
@@ -1522,6 +1517,7 @@ static const struct irq_domain_ops intel_ir_domain_ops = {
 
 static const struct msi_parent_ops dmar_msi_parent_ops = {
 	.supported_flags	= X86_VECTOR_MSI_FLAGS_SUPPORTED | MSI_FLAG_MULTI_PCI_MSI,
+	.bus_token		= DOMAIN_BUS_DMAR,
 	.prefix			= "IR-",
 	.init_dev_msi_info	= msi_parent_init_dev_msi_info,
 };
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:48 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:48 +0000
Subject: [PATCH 10/11] PCI: apple: Convert to MSI parent infrastructure
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-11-maz@kernel.org>

In an effort to move arm64 away from the legacy MSI setup,
convert the apple PCIe driver to the MSI-parent infrastructure
and let each device have its own MSI domain.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/pci/controller/Kconfig      |  1 +
 drivers/pci/controller/pcie-apple.c | 57 ++++++++---------------------
 2 files changed, 17 insertions(+), 41 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 9800b76810540..98a62f4559dfd 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -40,6 +40,7 @@ config PCIE_APPLE
 	depends on OF
 	depends on PCI_MSI
 	select PCI_HOST_COMMON
+	select IRQ_MSI_LIB
 	help
 	  Say Y here if you want to enable PCIe controller support on Apple
 	  system-on-chips, like the Apple M1. This is required for the USB
diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
index fefab2758a064..945070ac31cf8 100644
--- a/drivers/pci/controller/pcie-apple.c
+++ b/drivers/pci/controller/pcie-apple.c
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/iopoll.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/list.h>
 #include <linux/module.h>
@@ -134,7 +135,6 @@ struct apple_pcie {
 	struct mutex		lock;
 	struct device		*dev;
 	void __iomem            *base;
-	struct irq_domain	*domain;
 	unsigned long		*bitmap;
 	struct list_head	ports;
 	struct completion	event;
@@ -163,27 +163,6 @@ static void rmw_clear(u32 clr, void __iomem *addr)
 	writel_relaxed(readl_relaxed(addr) & ~clr, addr);
 }
 
-static void apple_msi_top_irq_mask(struct irq_data *d)
-{
-	pci_msi_mask_irq(d);
-	irq_chip_mask_parent(d);
-}
-
-static void apple_msi_top_irq_unmask(struct irq_data *d)
-{
-	pci_msi_unmask_irq(d);
-	irq_chip_unmask_parent(d);
-}
-
-static struct irq_chip apple_msi_top_chip = {
-	.name			= "PCIe MSI",
-	.irq_mask		= apple_msi_top_irq_mask,
-	.irq_unmask		= apple_msi_top_irq_unmask,
-	.irq_eoi		= irq_chip_eoi_parent,
-	.irq_set_affinity	= irq_chip_set_affinity_parent,
-	.irq_set_type		= irq_chip_set_type_parent,
-};
-
 static void apple_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
 {
 	msg->address_hi = upper_32_bits(DOORBELL_ADDR);
@@ -227,8 +206,7 @@ static int apple_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
 
 	for (i = 0; i < nr_irqs; i++) {
 		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
-					      &apple_msi_bottom_chip,
-					      domain->host_data);
+					      &apple_msi_bottom_chip, pcie);
 	}
 
 	return 0;
@@ -252,12 +230,6 @@ static const struct irq_domain_ops apple_msi_domain_ops = {
 	.free	= apple_msi_domain_free,
 };
 
-static struct msi_domain_info apple_msi_info = {
-	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		   MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX),
-	.chip	= &apple_msi_top_chip,
-};
-
 static void apple_port_irq_mask(struct irq_data *data)
 {
 	struct apple_pcie_port *port = irq_data_get_irq_chip_data(data);
@@ -596,6 +568,17 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
 	return 0;
 }
 
+static const struct msi_parent_ops apple_msi_parent_ops = {
+	.supported_flags	= (MSI_GENERIC_FLAGS_MASK	|
+				   MSI_FLAG_PCI_MSIX		|
+				   MSI_FLAG_MULTI_PCI_MSI),
+	.required_flags		= (MSI_FLAG_USE_DEF_DOM_OPS	|
+				   MSI_FLAG_USE_DEF_CHIP_OPS	|
+				   MSI_FLAG_PCI_MSI_MASK_PARENT),
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
+};
+
 static int apple_msi_init(struct apple_pcie *pcie)
 {
 	struct fwnode_handle *fwnode = dev_fwnode(pcie->dev);
@@ -626,21 +609,13 @@ static int apple_msi_init(struct apple_pcie *pcie)
 		return -ENXIO;
 	}
 
-	parent = irq_domain_create_hierarchy(parent, 0, pcie->nvecs, fwnode,
-					     &apple_msi_domain_ops, pcie);
+	parent = msi_create_parent_irq_domain(fwnode, &apple_msi_parent_ops,
+					      &apple_msi_domain_ops, 0,
+					      pcie->nvecs, pcie, parent);
 	if (!parent) {
 		dev_err(pcie->dev, "failed to create IRQ domain\n");
 		return -ENOMEM;
 	}
-	irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS);
-
-	pcie->domain = pci_msi_create_irq_domain(fwnode, &apple_msi_info,
-						 parent);
-	if (!pcie->domain) {
-		dev_err(pcie->dev, "failed to create MSI domain\n");
-		irq_domain_remove(parent);
-		return -ENOMEM;
-	}
 
 	return 0;
 }
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:46 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:46 +0000
Subject: [PATCH 08/11] iommu/amd: Convert to msi_create_parent_irq_domain() helper
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-9-maz@kernel.org>

Now that we have a concise helper to create an MSI parent domain,
switch the AMD IOMMU remapping over to that.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/iommu/amd/iommu.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 3f691e1fd22ce..8137674aca51d 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -3807,6 +3807,7 @@ static struct irq_chip amd_ir_chip = {
 
 static const struct msi_parent_ops amdvi_msi_parent_ops = {
 	.supported_flags	= X86_VECTOR_MSI_FLAGS_SUPPORTED | MSI_FLAG_MULTI_PCI_MSI,
+	.bus_token		= DOMAIN_BUS_AMDVI,
 	.prefix			= "IR-",
 	.init_dev_msi_info	= msi_parent_init_dev_msi_info,
 };
@@ -3818,18 +3819,15 @@ int amd_iommu_create_irq_domain(struct amd_iommu *iommu)
 	fn = irq_domain_alloc_named_id_fwnode("AMD-IR", iommu->index);
 	if (!fn)
 		return -ENOMEM;
-	iommu->ir_domain = irq_domain_create_hierarchy(arch_get_ir_parent_domain(), 0, 0,
-						       fn, &amd_ir_domain_ops, iommu);
+	iommu->ir_domain = msi_create_parent_irq_domain(fn, &amdvi_msi_parent_ops,
+							&amd_ir_domain_ops,
+							IRQ_DOMAIN_FLAG_ISOLATED_MSI, 0,
+							iommu, arch_get_ir_parent_domain());
 	if (!iommu->ir_domain) {
 		irq_domain_free_fwnode(fn);
 		return -ENOMEM;
 	}
 
-	irq_domain_update_bus_token(iommu->ir_domain,  DOMAIN_BUS_AMDVI);
-	iommu->ir_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT |
-				   IRQ_DOMAIN_FLAG_ISOLATED_MSI;
-	iommu->ir_domain->msi_parent_ops = &amdvi_msi_parent_ops;
-
 	return 0;
 }
 
-- 
2.39.2



From maz at kernel.org  Wed Dec  4 04:45:49 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 12:45:49 +0000
Subject: [PATCH 11/11] PCI: xgene: Convert to MSI parent infrastructure
In-Reply-To: <20241204124549.607054-1-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
Message-ID: <20241204124549.607054-12-maz@kernel.org>

In an effort to move arm64 away from the legacy MSI setup,
convert the xgene PCIe driver to the MSI-parent infrastructure
and let each device have its own MSI domain.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/pci/controller/Kconfig         |  1 +
 drivers/pci/controller/pci-xgene-msi.c | 44 +++++++++-----------------
 2 files changed, 16 insertions(+), 29 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 98a62f4559dfd..205e0e365c6b1 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -304,6 +304,7 @@ config PCI_XGENE_MSI
 	bool "X-Gene v1 PCIe MSI feature"
 	depends on PCI_XGENE
 	depends on PCI_MSI
+	select IRQ_MSI_LIB
 	default y
 	help
 	  Say Y here if you want PCIe MSI support for the APM X-Gene v1 SoC.
diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c
index 88c0977bc41a4..d9e4d1e136f77 100644
--- a/drivers/pci/controller/pci-xgene-msi.c
+++ b/drivers/pci/controller/pci-xgene-msi.c
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/of_pci.h>
@@ -32,7 +33,6 @@ struct xgene_msi_group {
 struct xgene_msi {
 	struct device_node	*node;
 	struct irq_domain	*inner_domain;
-	struct irq_domain	*msi_domain;
 	u64			msi_addr;
 	void __iomem		*msi_regs;
 	unsigned long		*bitmap;
@@ -44,20 +44,6 @@ struct xgene_msi {
 /* Global data */
 static struct xgene_msi xgene_msi_ctrl;
 
-static struct irq_chip xgene_msi_top_irq_chip = {
-	.name		= "X-Gene1 MSI",
-	.irq_enable	= pci_msi_unmask_irq,
-	.irq_disable	= pci_msi_mask_irq,
-	.irq_mask	= pci_msi_mask_irq,
-	.irq_unmask	= pci_msi_unmask_irq,
-};
-
-static struct  msi_domain_info xgene_msi_domain_info = {
-	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_PCI_MSIX),
-	.chip	= &xgene_msi_top_irq_chip,
-};
-
 /*
  * X-Gene v1 has 16 groups of MSI termination registers MSInIRx, where
  * n is group number (0..F), x is index of registers in each group (0..7)
@@ -235,34 +221,34 @@ static void xgene_irq_domain_free(struct irq_domain *domain,
 	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
 }
 
-static const struct irq_domain_ops msi_domain_ops = {
+static const struct irq_domain_ops xgene_msi_domain_ops = {
 	.alloc  = xgene_irq_domain_alloc,
 	.free   = xgene_irq_domain_free,
 };
 
+static const struct msi_parent_ops xgene_msi_parent_ops = {
+	.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_PCI_MSI,
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
+};
+
 static int xgene_allocate_domains(struct xgene_msi *msi)
 {
-	msi->inner_domain = irq_domain_add_linear(NULL, NR_MSI_VEC,
-						  &msi_domain_ops, msi);
+	msi->inner_domain = msi_create_parent_irq_domain(of_node_to_fwnode(msi->node),
+							 &xgene_msi_parent_ops,
+							 &xgene_msi_domain_ops,
+							 0, NR_MSI_VEC, msi, NULL);
 	if (!msi->inner_domain)
 		return -ENOMEM;
 
-	msi->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(msi->node),
-						    &xgene_msi_domain_info,
-						    msi->inner_domain);
-
-	if (!msi->msi_domain) {
-		irq_domain_remove(msi->inner_domain);
-		return -ENOMEM;
-	}
-
 	return 0;
 }
 
 static void xgene_free_domains(struct xgene_msi *msi)
 {
-	if (msi->msi_domain)
-		irq_domain_remove(msi->msi_domain);
 	if (msi->inner_domain)
 		irq_domain_remove(msi->inner_domain);
 }
-- 
2.39.2



From cristian.marussi at arm.com  Wed Dec  4 05:01:00 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 4 Dec 2024 13:01:00 +0000
Subject: [PATCH V5 2/2] firmware: arm_scmi: vendors: Add QCOM SCMI
 Generic Extensions
In-Reply-To: <20241115011515.1313447-3-quic_sibis@quicinc.com>
References: <20241115011515.1313447-1-quic_sibis@quicinc.com>
 <20241115011515.1313447-3-quic_sibis@quicinc.com>
Message-ID: <Z1BSjM5heBoRFCYk@pluto>

On Fri, Nov 15, 2024 at 06:45:15AM +0530, Sibi Sankar wrote:
> The QCOM SCMI Generic Extensions Protocol provides a generic way of
> exposing a number of Qualcomm SoC specific features (like memory bus
> scaling) through a mixture of pre-determined algorithm strings and
> param_id pairs hosted on the SCMI controller.
>

Hi,
 
> Co-developed-by: Shivnandan Kumar <quic_kshivnan at quicinc.com>
> Signed-off-by: Shivnandan Kumar <quic_kshivnan at quicinc.com>
> Co-developed-by: Ramakrishna Gottimukkula <quic_rgottimu at quicinc.com>
> Signed-off-by: Ramakrishna Gottimukkula <quic_rgottimu at quicinc.com>
> Co-developed-by: Amir Vajid <avajid at quicinc.com>
> Signed-off-by: Amir Vajid <avajid at quicinc.com>
> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
> Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>

You reworked/refactored quite a lot the internals since V4, you should
have dropped the Reviewed-by tag.

> ---
> 
> v4:
> * Splitting the series into vendor protocol and memlat client.
>   Also the move the memlat client implementation back to RFC
>   due to multiple opens.
> * Use common xfer helper to avoid code duplication [Dmitry]
> * Update enum documentation without duplicate enum info [Dmitry]
> 
>  drivers/firmware/arm_scmi/Kconfig             |   1 +
>  drivers/firmware/arm_scmi/Makefile            |   1 +
>  .../firmware/arm_scmi/vendors/qcom/Kconfig    |  15 ++
>  .../firmware/arm_scmi/vendors/qcom/Makefile   |   2 +
>  .../arm_scmi/vendors/qcom/qcom-generic-ext.c  | 139 ++++++++++++++++++
>  include/linux/scmi_qcom_protocol.h            |  37 +++++
>  6 files changed, 195 insertions(+)
>  create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/Kconfig
>  create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/Makefile
>  create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/qcom-generic-ext.c
>  create mode 100644 include/linux/scmi_qcom_protocol.h
> 
> diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
> index dabd874641d0..73128442d97b 100644
> --- a/drivers/firmware/arm_scmi/Kconfig
> +++ b/drivers/firmware/arm_scmi/Kconfig
> @@ -71,6 +71,7 @@ config ARM_SCMI_DEBUG_COUNTERS
>  
>  source "drivers/firmware/arm_scmi/transports/Kconfig"
>  source "drivers/firmware/arm_scmi/vendors/imx/Kconfig"
> +source "drivers/firmware/arm_scmi/vendors/qcom/Kconfig"
>  
>  endif #ARM_SCMI_PROTOCOL
>  
> diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
> index 9ac81adff567..58cf4d656cbb 100644
> --- a/drivers/firmware/arm_scmi/Makefile
> +++ b/drivers/firmware/arm_scmi/Makefile
> @@ -12,6 +12,7 @@ scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
>  
>  obj-$(CONFIG_ARM_SCMI_PROTOCOL) += transports/
>  obj-$(CONFIG_ARM_SCMI_PROTOCOL) += vendors/imx/
> +obj-$(CONFIG_ARM_SCMI_PROTOCOL) += vendors/qcom/
>  
>  obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
>  obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o
> diff --git a/drivers/firmware/arm_scmi/vendors/qcom/Kconfig b/drivers/firmware/arm_scmi/vendors/qcom/Kconfig
> new file mode 100644
> index 000000000000..5dd9e8a6b75f
> --- /dev/null
> +++ b/drivers/firmware/arm_scmi/vendors/qcom/Kconfig
> @@ -0,0 +1,15 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +menu "ARM SCMI QCOM Vendor Protocols"
> +
> +config QCOM_SCMI_GENERIC_EXT
> +	tristate "Qualcomm Technologies, Inc. Qcom SCMI vendor Protocol"
> +	depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
> +	help
> +	  The QCOM SCMI vendor protocol provides a generic way of exposing
> +	  a number of Qualcomm SoC specific features (like memory bus scaling)
> +	  through a mixture of pre-determined algorithm strings and param_id
> +	  pairs hosted on the SCMI controller.
> +
> +	  This driver defines/documents the message ID's used for this
> +	  communication and also exposes the operations used by the clients.
> +endmenu
> diff --git a/drivers/firmware/arm_scmi/vendors/qcom/Makefile b/drivers/firmware/arm_scmi/vendors/qcom/Makefile
> new file mode 100644
> index 000000000000..6b98fabbebb8
> --- /dev/null
> +++ b/drivers/firmware/arm_scmi/vendors/qcom/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_QCOM_SCMI_GENERIC_EXT) += qcom-generic-ext.o
> diff --git a/drivers/firmware/arm_scmi/vendors/qcom/qcom-generic-ext.c b/drivers/firmware/arm_scmi/vendors/qcom/qcom-generic-ext.c
> new file mode 100644
> index 000000000000..1b209093d275
> --- /dev/null
> +++ b/drivers/firmware/arm_scmi/vendors/qcom/qcom-generic-ext.c
> @@ -0,0 +1,139 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <linux/scmi_qcom_protocol.h>
> +
> +#include "../../common.h"
> +
> +/**
> + * enum qcom_generic_ext_protocol_cmd - vendor specific commands supported by SCMI Qualcomm
> + *                                      generic vendor protocol.
> + *
> + * This protocol is intended as a generic way of exposing a number of Qualcomm SoC
> + * specific features through a mixture of pre-determined algorithm string and param_id
> + * pairs hosted on the SCMI controller.
> + *
> + * The QCOM SCMI Vendor Protocol has the protocol id as 0x80 and vendor id set to
> + * Qualcomm and the implementation version set to 0x20000. The PROTOCOL_VERSION command
> + * returns version 1.0.

The chosen protocol ID is already defined in the protocol doc in the
series, and the note about the implementation version seems redundant,
it is indeed specified as needed in scmi_protocol.

> + *
> + * @QCOM_SCMI_SET_PARAM: is used to set the parameter of a specific algo_str hosted on
> + *			 QCOM SCMI Vendor Protocol. The tx len depends on the algo_str used.
> + * @QCOM_SCMI_GET_PARAM: is used to get parameter information of a specific algo_str
> + *			 hosted on QCOM SCMI Vendor Protocol. The tx and rx len depends
> + *			 on the algo_str used.
> + * @QCOM_SCMI_START_ACTIVITY: is used to start the activity performed by the algo_str.
> + * @QCOM_SCMI_STOP_ACTIVITY: is used to stop a pre-existing activity performed by the algo_str.
> + */
> +enum qcom_generic_ext_protocol_cmd {
> +	QCOM_SCMI_SET_PARAM = 0x10,
> +	QCOM_SCMI_GET_PARAM = 0x11,
> +	QCOM_SCMI_START_ACTIVITY = 0x12,
> +	QCOM_SCMI_STOP_ACTIVITY = 0x13,
> +};
> +
> +/**
> + * struct qcom_scmi_msg - represents the various parameters to be populated
> + *                        for using the QCOM SCMI Vendor Protocol
> + *
> + * @ext_id: reserved, must be zero
> + * @algo_low: lower 32 bits of the algo_str
> + * @algo_high: upper 32 bits of the algo_str
> + * @param_id: serves as token message id to the specific algo_str
> + * @buf: serves as the payload to the specified param_id and algo_str pair
> + */
> +struct qcom_scmi_msg {
> +	__le32 ext_id;
> +	__le32 algo_low;
> +	__le32 algo_high;
> +	__le32 param_id;
> +	__le32 buf[];
> +};
> +
> +static int qcom_scmi_common_xfer(const struct scmi_protocol_handle *ph,
> +				 enum qcom_generic_ext_protocol_cmd cmd_id, void *buf,
> +				 size_t buf_len, u64 algo_str, u32 param_id, size_t rx_size)
> +{
> +	struct scmi_xfer *t;
> +	struct qcom_scmi_msg *msg;
> +	int ret;
> +
> +	ret = ph->xops->xfer_get_init(ph, cmd_id, buf_len + sizeof(*msg), rx_size, &t);
> +	if (ret)
> +		return ret;
> +
> +	msg = t->tx.buf;
> +	msg->algo_low = cpu_to_le32(lower_32_bits(algo_str));
> +	msg->algo_high = cpu_to_le32(upper_32_bits(algo_str));
> +	msg->param_id = cpu_to_le32(param_id);
> +	memcpy(msg->buf, buf, buf_len);
> +
> +	ret = ph->xops->do_xfer(ph, t);
> +	if (rx_size)

You should check ret == 0 also here before considering to pick up the reply
if a non-zero rx_size was specified.

> +		memcpy(buf, t->rx.buf, t->rx.len);

...you are using the same buf/buf_len to hold the TX request and get back
the reply content if a non-zero rx_size was provided but while you can
be sure that the reply payload rx.len <= rx_size by construction
(via xfer_get_init) you cannot be equally sure that rx_size <= buf_len
...it depends on te caller how this operation is invoked...so you could
end up oveflowing buf depending on the caller-provided params...

...please add some additional check at the start of this function like:

	if (rx_size > buf_len)
		return -EINVAL;

...to catch such bad invcations...

> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static int qcom_scmi_set_param(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
> +			       u64 algo_str, u32 param_id)
> +{
> +	return qcom_scmi_common_xfer(ph, QCOM_SCMI_SET_PARAM, buf, buf_len, algo_str,
> +				     param_id, 0);
> +}
> +
> +static int qcom_scmi_get_param(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
> +			       u64 algo_str, u32 param_id, size_t rx_size)
> +{
> +	return qcom_scmi_common_xfer(ph, QCOM_SCMI_GET_PARAM, buf, buf_len, algo_str,
> +				     param_id, rx_size);
> +}
> +
> +static int qcom_scmi_start_activity(const struct scmi_protocol_handle *ph, void *buf,
> +				    size_t buf_len, u64 algo_str, u32 param_id)
> +{
> +	return qcom_scmi_common_xfer(ph, QCOM_SCMI_START_ACTIVITY, buf, buf_len, algo_str,
> +				     param_id, 0);
> +}
> +
> +static int qcom_scmi_stop_activity(const struct scmi_protocol_handle *ph, void *buf,
> +				   size_t buf_len, u64 algo_str, u32 param_id)
> +{
> +	return qcom_scmi_common_xfer(ph, QCOM_SCMI_STOP_ACTIVITY, buf, buf_len, algo_str,
> +				     param_id, 0);
> +}
> +
> +static struct qcom_generic_ext_ops qcom_proto_ops = {
> +	.set_param = qcom_scmi_set_param,
> +	.get_param = qcom_scmi_get_param,
> +	.start_activity = qcom_scmi_start_activity,
> +	.stop_activity = qcom_scmi_stop_activity,
> +};
> +
> +static int qcom_generic_ext_protocol_init(const struct scmi_protocol_handle *ph)
> +{
> +	u32 version;
> +
> +	ph->xops->version_get(ph, &version);

... please check retval and bailout on error when not even a basic version_get
succedeed...

> +
> +	dev_dbg(ph->dev, "QCOM Generic Vendor Version %d.%d\n",
> +		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
> +
> +	return 0;
> +}
> +
> +static const struct scmi_protocol qcom_generic_ext = {
> +	.id = SCMI_PROTOCOL_QCOM_GENERIC,
> +	.owner = THIS_MODULE,
> +	.instance_init = &qcom_generic_ext_protocol_init,
> +	.ops = &qcom_proto_ops,
> +	.vendor_id = "Qualcomm",
> +	.impl_ver = 0x20000,
> +};
> +module_scmi_protocol(qcom_generic_ext);
> +

You may have to add a proper MODULE_ALIAS, if the series on autoload
goes through

https://lore.kernel.org/linux-arm-kernel/20241203200038.3961090-1-cristian.marussi at arm.com/

> +MODULE_DESCRIPTION("QCOM SCMI Generic Vendor protocol");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/scmi_qcom_protocol.h b/include/linux/scmi_qcom_protocol.h
> new file mode 100644
> index 000000000000..465b2522ca29
> --- /dev/null
> +++ b/include/linux/scmi_qcom_protocol.h
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * SCMI Message Protocol driver QCOM extension header
> + *
> + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#ifndef _LINUX_SCMI_QCOM_PROTOCOL_H
> +#define _LINUX_SCMI_QCOM_PROTOCOL_H
> +
> +#include <linux/types.h>
> +
> +#define SCMI_PROTOCOL_QCOM_GENERIC    0x80
> +
> +struct scmi_protocol_handle;
> +
> +/**
> + * struct qcom_generic_ext_ops - represents the various operations provided
> + *				 by QCOM Generic Vendor Protocol
> + *
> + * @set_param: set parameter specified by param_id and algo_str pair.
> + * @get_param: retrieve parameter specified by param_id and algo_str pair.
> + * @start_activity: initiate a specific activity defined by algo_str.
> + * @stop_activity: halt previously initiated activity defined by algo_str.
> + */
> +struct qcom_generic_ext_ops {
> +	int (*set_param)(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
> +			 u64 algo_str, u32 param_id);
> +	int (*get_param)(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
> +			 u64 algo_str, u32 param_id, size_t rx_size);
> +	int (*start_activity)(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
> +			      u64 algo_str, u32 param_id);
> +	int (*stop_activity)(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
> +			     u64 algo_str, u32 param_id);
> +};
> +
> +#endif /* _LINUX_SCMI_QCOM_PROTOCOL_H */
> -- 

Thanks,
Cristian


From peter at korsgaard.com  Wed Dec  4 05:09:29 2024
From: peter at korsgaard.com (Peter Korsgaard)
Date: Wed, 4 Dec 2024 14:09:29 +0100
Subject: [PATCH] rtc: zynqmp: Fix optional clock name property
In-Reply-To: <cd5f0c9d01ec1f5a240e37a7e0d85b8dacb3a869.1732723280.git.michal.simek@amd.com>
References: <cd5f0c9d01ec1f5a240e37a7e0d85b8dacb3a869.1732723280.git.michal.simek@amd.com>
Message-ID: <3b79fb8a-d927-4261-abd7-b7918d927454@korsgaard.com>

On 11/27/24 17:01, Michal Simek wrote:
> Clock description in DT binding introduced by commit f69060c14431
> ("dt-bindings: rtc: zynqmp: Add clock information") is talking about "rtc"
> clock name but driver is checking "rtc_clk" name instead.
> Because clock is optional property likely in was never handled properly by
> the driver.
> 
> Fixes: 07dcc6f9c762 ("rtc: zynqmp: Add calibration set and get support")
> Signed-off-by: Michal Simek <michal.simek at amd.com>
> Cc: <stable at kernel.org>

Reviewed-by: Peter Korsgaard <peter at korsgaard.com>


>   drivers/rtc/rtc-zynqmp.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
> index 08ed171bdab4..b6f96c10196a 100644
> --- a/drivers/rtc/rtc-zynqmp.c
> +++ b/drivers/rtc/rtc-zynqmp.c
> @@ -318,8 +318,8 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
>   		return ret;
>   	}
>   
> -	/* Getting the rtc_clk info */
> -	xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc_clk");
> +	/* Getting the rtc info */
> +	xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc");
>   	if (IS_ERR(xrtcdev->rtc_clk)) {
>   		if (PTR_ERR(xrtcdev->rtc_clk) != -EPROBE_DEFER)
>   			dev_warn(&pdev->dev, "Device clock not found.\n");

-- 
Bye, Peter Korsgaard



From lkp at intel.com  Wed Dec  4 05:10:42 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 4 Dec 2024 21:10:42 +0800
Subject: [PATCH] drm/mediatek: dp: Support flexible length of DP
 calibration data
In-Reply-To: <20241204053634.1365491-1-fshao@chromium.org>
References: <20241204053634.1365491-1-fshao@chromium.org>
Message-ID: <202412042020.FZmfgvza-lkp@intel.com>

Hi Fei,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.13-rc1 next-20241203]
[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/Fei-Shao/drm-mediatek-dp-Support-flexible-length-of-DP-calibration-data/20241204-133854
base:   linus/master
patch link:    https://lore.kernel.org/r/20241204053634.1365491-1-fshao%40chromium.org
patch subject: [PATCH] drm/mediatek: dp: Support flexible length of DP calibration data
config: mips-allyesconfig (https://download.01.org/0day-ci/archive/20241204/202412042020.FZmfgvza-lkp at intel.com/config)
compiler: mips-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241204/202412042020.FZmfgvza-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/202412042020.FZmfgvza-lkp at intel.com/

All warnings (new ones prefixed by >>):

   In file included from include/linux/device.h:15,
                    from include/drm/display/drm_dp_aux_bus.h:13,
                    from drivers/gpu/drm/mediatek/mtk_dp.c:7:
   drivers/gpu/drm/mediatek/mtk_dp.c: In function 'mtk_dp_get_calibration_data':
>> drivers/gpu/drm/mediatek/mtk_dp.c:1181:34: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'size_t' {aka 'unsigned int'} [-Wformat=]
    1181 |                                  "Out-of-bound efuse data access, fmt idx = %d, buf len = %lu\n",
         |                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                              ^~~
   include/linux/dev_printk.h:156:61: note: in expansion of macro 'dev_fmt'
     156 |         dev_printk_index_wrap(_dev_warn, KERN_WARNING, dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                                                             ^~~~~~~
   drivers/gpu/drm/mediatek/mtk_dp.c:1180:25: note: in expansion of macro 'dev_warn'
    1180 |                         dev_warn(mtk_dp->dev,
         |                         ^~~~~~~~
   drivers/gpu/drm/mediatek/mtk_dp.c:1181:93: note: format string is defined here
    1181 |                                  "Out-of-bound efuse data access, fmt idx = %d, buf len = %lu\n",
         |                                                                                           ~~^
         |                                                                                             |
         |                                                                                             long unsigned int
         |                                                                                           %u


vim +1181 drivers/gpu/drm/mediatek/mtk_dp.c

  1148	
  1149	static void mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
  1150	{
  1151		const struct mtk_dp_efuse_fmt *fmt;
  1152		struct device *dev = mtk_dp->dev;
  1153		struct nvmem_cell *cell;
  1154		u32 *cal_data = mtk_dp->cal_data;
  1155		u32 *buf;
  1156		int i;
  1157		size_t len;
  1158	
  1159		cell = nvmem_cell_get(dev, "dp_calibration_data");
  1160		if (IS_ERR(cell)) {
  1161			dev_warn(dev, "Failed to get nvmem cell dp_calibration_data\n");
  1162			goto use_default_val;
  1163		}
  1164	
  1165		buf = (u32 *)nvmem_cell_read(cell, &len);
  1166		nvmem_cell_put(cell);
  1167	
  1168		if (IS_ERR(buf)) {
  1169			dev_warn(dev, "Failed to read nvmem_cell_read\n");
  1170			goto use_default_val;
  1171		}
  1172	
  1173		/* The cell length is in bytes. Convert it to be compatible with u32 buffer. */
  1174		len /= sizeof(u32);
  1175	
  1176		for (i = 0; i < MTK_DP_CAL_MAX; i++) {
  1177			fmt = &mtk_dp->data->efuse_fmt[i];
  1178	
  1179			if (fmt->idx >= len) {
  1180				dev_warn(mtk_dp->dev,
> 1181					 "Out-of-bound efuse data access, fmt idx = %d, buf len = %lu\n",
  1182					 fmt->idx, len);
  1183				kfree(buf);
  1184				goto use_default_val;
  1185			}
  1186	
  1187			cal_data[i] = (buf[fmt->idx] >> fmt->shift) & fmt->mask;
  1188	
  1189			if (cal_data[i] < fmt->min_val || cal_data[i] > fmt->max_val) {
  1190				dev_warn(mtk_dp->dev, "Invalid efuse data, idx = %d\n", i);
  1191				kfree(buf);
  1192				goto use_default_val;
  1193			}
  1194		}
  1195		kfree(buf);
  1196	
  1197		return;
  1198	
  1199	use_default_val:
  1200		dev_warn(mtk_dp->dev, "Use default calibration data\n");
  1201		for (i = 0; i < MTK_DP_CAL_MAX; i++)
  1202			cal_data[i] = mtk_dp->data->efuse_fmt[i].default_val;
  1203	}
  1204	

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


From t.antoine at uclouvain.be  Wed Dec  4 05:13:13 2024
From: t.antoine at uclouvain.be (Thomas Antoine)
Date: Wed, 4 Dec 2024 14:13:13 +0100
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <30b0995903fb7db3f866d1304783d878f563fe2f.camel@linaro.org>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
 <e23721ebd766f410103ddfb8705f3d7d6e5ae3e9.camel@linaro.org>
 <575b3275-b2fa-4e5c-bb6b-759394b02e18@uclouvain.be>
 <30b0995903fb7db3f866d1304783d878f563fe2f.camel@linaro.org>
Message-ID: <5281f86d-6917-4f4e-b85d-70502a24c5bd@uclouvain.be>

On 12/3/24 11:40, Andr? Draszik wrote:
> On Tue, 2024-12-03 at 11:23 +0100, Thomas Antoine wrote:
>> On 12/3/24 08:12, Andr? Draszik wrote:
>>> On Mon, 2024-12-02 at 14:07 +0100, Thomas Antoine via B4 Relay wrote:
>>>> From: Thomas Antoine <t.antoine at uclouvain.be>
>>>>
>>>> As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
>>>> make it non-obligatory. Except for this, the max77759 seems to behave the
>>>> same as the max1720x.
>>>
>>> What about the battery characterization tables? Aren't they needed for
>>> correct reporting?
>>
>> I checked some other patches which added fuel gauge and other bindings and I
>> couldn't find such characterization table. Can you point me to an example or
>> explain what it should contain if there needs one?
> 
> I haven't looked in detail, but there is
> 
> 
> https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-oriole-battery.dtsi#13
> https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-raven-battery.dtsi#13
> 
> which include
> https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-oriole-battery-data.dtsi
> https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-raven-battery-data.dtsi
> respectively
> 
> Both overlay
> https://android.googlesource.com/kernel/google-modules/raviole-device/+/refs/heads/android-gs-raviole-mainline/arch/arm64/boot/dts/google/gs101-raviole-battery.dtsi#177

I looked into it. The probe function launches a delay work
max1720x_model_work which will try multiple times to run
max1720x_model_load which leads to
max_m5_load_gauge_model -> max_m5_update_custom_model

This last function writes 0x0059 to 0x62 and 0x00c4 to 0x63 which unlocks
the addresses from 0x80 to 0xaf. Those actually contain the model but are
usually locked, returning only 0xff. It then writes the model and locks
back the register.

I tried it and I was indeed able to access this data on my device. The
registers contained a model very close to the default-a1-0k fg-model
contained in the downstream devicetree. The only diffrence is that all the
0x0100 are replaced with 0x0080.

I think those registers are similar to the registers 180h to 1AFh of the
max1720x ("ModelGauge m5 Algorithm Model registers" in the datasheet).

The fg-params is used to set individual registers like CGAIN or CONFIG2 but
from what I see, those are also on the max1720x.

If it is indeed the case and that all of those are equivalent to their
max1720x counterpart, I think the management of those values should be
added in another patch which implements it for both the max1720x (and possibly the
max77759) as the mainline driver does not do anything with those values
currently.

Best,
Thomas


From vkoul at kernel.org  Wed Dec  4 05:18:42 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 04 Dec 2024 18:48:42 +0530
Subject: [PATCH] dmaengine: apple-admac: Avoid accessing registers in
 probe
In-Reply-To: <20241124-admac-power-v1-1-58f2165a4d55@gmail.com>
References: <20241124-admac-power-v1-1-58f2165a4d55@gmail.com>
Message-ID: <173331832270.673314.2577106831553574713.b4-ty@kernel.org>


On Sun, 24 Nov 2024 16:48:28 +0100, Sasha Finkelstein wrote:
> The ADMAC attached to the AOP has complex power sequencing, and is
> power gated when the probe callback runs. Move the register reads
> to other functions, where we can guarantee that the hardware is
> switched on.
> 
> 

Applied, thanks!

[1/1] dmaengine: apple-admac: Avoid accessing registers in probe
      commit: 8d55e8a16f019211163f1180fd9f9fbe05901900

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Wed Dec  4 05:18:58 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 04 Dec 2024 18:48:58 +0530
Subject: (subset) [PATCH v5 0/5] Add support for DMA of F1C100s
In-Reply-To: <20241122161128.2619172-1-csokas.bence@prolan.hu>
References: <20241122161128.2619172-1-csokas.bence@prolan.hu>
Message-ID: <173331833897.673424.223627111827356616.b4-ty@kernel.org>


On Fri, 22 Nov 2024 17:11:23 +0100, Cs?k?s, Bence wrote:
> Support for Allwinner F1C100s/200s series audio was
> submitted in 2018 as an RFC series, but was not merged,
> despite having only minor errors. However, this is
> essential for having audio on these SoCs.
> This series was forward-ported/rebased to the best of
> my abilities, on top of Linus' tree as of now:
> commit 28eb75e178d3 ("Merge tag 'drm-next-2024-11-21' of https://gitlab.freedesktop.org/drm/kernel")
> 
> [...]

Applied, thanks!

[1/5] dma-engine: sun4i: Add a quirk to support different chips
      commit: eeca1b60138189ef1b9636709e578d0c9e0de517
[2/5] dma-engine: sun4i: Add has_reset option to quirk
      commit: 1f738d0c2f67ae3551e4543e8dddbfb44cdd9f53
[3/5] dt-bindings: dmaengine: Add Allwinner suniv F1C100s DMA
      commit: 1ad2ebf3be836e62792788f4cd105b30ca9178b6
[4/5] dma-engine: sun4i: Add support for Allwinner suniv F1C100s
      commit: 61785259d1eb4e4c4acef8551a2524441683dbf3

Best regards,
-- 
~Vinod




From wahrenst at gmx.net  Wed Dec  4 05:27:24 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Wed, 4 Dec 2024 14:27:24 +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: <5ab9b62a-6577-4a3f-9dfe-c7362bf725db@gmx.net>

Hi,

Am 13.02.24 um 18:22 schrieb Fabio Estevam:
> 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>
I noticed that this patch hasn't applied to stable yet.

Are there reason for not doing this or is it just because the patch
missed the Cc: stable at vger.kernel.org ?


From vkoul at kernel.org  Wed Dec  4 05:46:07 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 4 Dec 2024 19:16:07 +0530
Subject: [PATCH v18 2/8] phy: Add HDMI configuration options
In-Reply-To: <64f6885b5a5ca89c8214b3138cb58c3133ac2109.1730172244.git.Sandor.yu@nxp.com>
References: <cover.1730172244.git.Sandor.yu@nxp.com>
 <64f6885b5a5ca89c8214b3138cb58c3133ac2109.1730172244.git.Sandor.yu@nxp.com>
Message-ID: <Z1BdHzfcnj6XJ9D4@vaman>

On 29-10-24, 14:02, Sandor Yu wrote:
> 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.

Acked-by: Vinod Koul <vkoul at kernel.org>


-- 
~Vinod


From linus.walleij at linaro.org  Wed Dec  4 05:54:23 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 14:54:23 +0100
Subject: [PATCH 01/15] ARM: use CONFIG_AEABI by default everywhere
In-Reply-To: <20241204102904.1863796-2-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-2-arnd@kernel.org>
Message-ID: <CACRpkdYmCzYT6s3XaQURLW9ak1xvzuKPpm_LB5GM+AzNUHtv7g@mail.gmail.com>

On Wed, Dec 4, 2024 at 11:29?AM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> On ARMv4 and ARMv5, the default is still to build for OABI, with
> CONFIG_AEABI disabled, even though distros and toolchains no longer
> support OABI as a target.
>
> Change the default to EABI for all architecture levels and change
> the defconfig entries as follows:
>
>  - All machines that used to explicitly enable EABI can drop that line now
>  - Machines that are likely to actually use old distros and had NWFPE
>    enabled in combination with OABI (rpc, footrbridge, netwinder,
>    assabet, neponset) explicitly turn it on now.
>  - Machines that already had both EABI and NWFPE disabled in defconfig
>    (at91_dt, collie, ep93xx, gemini, h3600, imx_v4_v5, integrator, jornada,
>    moxart, multi_v4t, omap1) were likely not usable with either OABI or
>    EABI and now use EABI instead implicitly, making it more likely that
>    they could work.
>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

For these:

>  arch/arm/configs/gemini_defconfig       |  1 -
>  arch/arm/configs/integrator_defconfig   |  1 -
>  arch/arm/configs/ixp4xx_defconfig       |  1 -
>  arch/arm/configs/netwinder_defconfig    |  1 +
>  arch/arm/configs/nhk8815_defconfig      |  1 -
>  arch/arm/configs/versatile_defconfig    |  1 -

Acked-by: Linus Walleij <linus.walleij at linaro.org>

I only ever use these platforms with AEABI, and a corresponding
userspace.

My userspace for the Faraday FA526 uses the OpenWrt-resident
GCC --fix-v4bx hack:
https://github.com/openwrt/openwrt/blob/main/toolchain/gcc/patches-14.x/840-armv4_pass_fix-v4bx_to_ld.patch
(maybe this is a bit sloppy but it works for us)

Maybe LLVM CLANG can build an ARMv4 userspace without this
hack? I haven't looked closer.

Yours,
Linus Walleij


From tglx at linutronix.de  Wed Dec  4 05:57:47 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Wed, 04 Dec 2024 14:57:47 +0100
Subject: [PATCH 02/11] genirq/msi: Add helper for creating MSI-parent
 irq domains
In-Reply-To: <20241204124549.607054-3-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
 <20241204124549.607054-3-maz@kernel.org>
Message-ID: <878qsvsg84.ffs@tglx>

On Wed, Dec 04 2024 at 12:45, Marc Zyngier wrote:
> Creating an irq domain that serves as an MSI parent requires
> a substantial amount of esoteric boiler-plate code, some of
> which is often provided twice (such as the bus token).
>
> To make things a bit simpler for the unsuspecting MSI tinkerer,
> provide a helper that does it for them, and serves as documentation
> of what needs to be provided.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  include/linux/msi.h |  7 +++++++
>  kernel/irq/msi.c    | 40 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 47 insertions(+)
>
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index b10093c4d00ea..f08d14cf07103 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -594,6 +594,13 @@ struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
>  					 struct msi_domain_info *info,
>  					 struct irq_domain *parent);
>  
> +struct irq_domain *msi_create_parent_irq_domain(struct fwnode_handle *fwnode,
> +						const struct msi_parent_ops *msi_parent_ops,
> +						const struct irq_domain_ops *ops,
> +						unsigned long flags, unsigned long size,
> +						void *host_data,
> +						struct irq_domain *parent);

Can we please make this a template based interface similar to
msi_create_device_irq_domain()?

> +/**
> + * msi_create_parent_irq_domain - Create an MSI-parent interrupt domain
> + * @fwnode:		Optional fwnode of the interrupt controller
> + * @msi_parent_ops:	MSI parent callbacks and configuration
> + * @ops:		Interrupt domain ballbacks
> + * @flags:		Interrupt domain flags
> + * @size:		Interrupt domain size (0 if arbitrarily large)
> + * @host_data:		Interrupt domain private data
> + * @parent:		Parent irq domain
> + *
> + * Return: pointer to the created &struct irq_domain or %NULL on failure
> + */
> +struct irq_domain *msi_create_parent_irq_domain(struct fwnode_handle *fwnode,
> +						const struct msi_parent_ops *msi_parent_ops,
> +						const struct irq_domain_ops *ops,
> +						unsigned long flags, unsigned long size,
> +						void *host_data,
> +						struct irq_domain *parent)
> +{
> +	struct irq_domain_info info = {
> +		.fwnode		= fwnode,
> +		.size		= size,
> +		.hwirq_max	= size,
> +		.ops		= ops,
> +		.host_data	= host_data,
> +		.domain_flags	= flags | IRQ_DOMAIN_FLAG_MSI_PARENT,
> +		.parent		= parent,
> +		.bus_token	= msi_parent_ops->bus_select_token,
> +	};

Instead of hiding the template in the function?

We've been burnt with interfaces which might require extensions over
time before and I just converted the GIC patch (3/11) over to a template
at call site model. It results in the same code size reduction at the
call sites, but allows us to expand the template without touching any
existing driver in the future. See below.

It might be a good idea to have a specific msi_irq_domain_info template
which only contains the information required instead of reusing and
expanding irq_domain_info.

Hmm?

Thanks,

        tglx
---
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -263,24 +263,25 @@ static struct msi_parent_ops gicv2m_msi_
 
 static __init int gicv2m_allocate_domains(struct irq_domain *parent)
 {
-	struct irq_domain *inner_domain;
 	struct v2m_data *v2m;
+	struct irq_domain_info info = {
+		.ops		= &gic2m_domain_ops,
+		.parent		= parent,
+		.msi_parent_ops = &gicv2m_msi_parent_ops,
+	};
 
 	v2m = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
 	if (!v2m)
 		return 0;
 
-	inner_domain = irq_domain_create_hierarchy(parent, 0, 0, v2m->fwnode,
-						   &gicv2m_domain_ops, v2m);
-	if (!inner_domain) {
-		pr_err("Failed to create GICv2m domain\n");
-		return -ENOMEM;
-	}
-
-	irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
-	inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-	inner_domain->msi_parent_ops = &gicv2m_msi_parent_ops;
-	return 0;
+	info->fwnode = v2m->fwnode;
+	info->host_data = v2m;
+
+	if (msi_create_parent_irq_domain(&info))
+		return 0;
+
+	pr_err("Failed to create GICv2m domain\n");
+	return -ENOMEM;
 }
 
 static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -5076,31 +5076,27 @@ static void __init __iomem *its_map_one(
 
 static int its_init_domain(struct its_node *its)
 {
-	struct irq_domain *inner_domain;
-	struct msi_domain_info *info;
+	struct msi_domain_info *msi_info;
+	struct irq_domain_info info = {
+		.fwnode		= its->fwnode_handle,
+		.ops		= &its_domain_ops,
+		.parent		= its_parent,
+		.msi_parent_ops = &gic_v3_its_msi_parent_ops,
+		.flags		= its->msi_domain_flags,
+	};
 
-	info = kzalloc(sizeof(*info), GFP_KERNEL);
-	if (!info)
+	msi_info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!msi_info)
 		return -ENOMEM;
 
-	info->ops = &its_msi_domain_ops;
-	info->data = its;
-
-	inner_domain = irq_domain_create_hierarchy(its_parent,
-						   its->msi_domain_flags, 0,
-						   its->fwnode_handle, &its_domain_ops,
-						   info);
-	if (!inner_domain) {
-		kfree(info);
-		return -ENOMEM;
-	}
-
-	irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
-
-	inner_domain->msi_parent_ops = &gic_v3_its_msi_parent_ops;
-	inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-
-	return 0;
+	msi_info->ops = &its_msi_domain_ops;
+	msi_info->data = its;
+	info.host_data = msi_info;
+
+	if (msi_create_parent_irq_domain(&info))
+		return 0;
+	kfree(info);
+	return -ENOMEM;
 }
 
 static int its_init_vpe_domain(void)
--- a/drivers/irqchip/irq-gic-v3-mbi.c
+++ b/drivers/irqchip/irq-gic-v3-mbi.c
@@ -209,17 +209,14 @@ static const struct msi_parent_ops gic_v
 
 static int mbi_allocate_domain(struct irq_domain *parent)
 {
-	struct irq_domain *nexus_domain;
+	struct irq_domain_info info = {
+		.fwnode		= parent->fwnode,
+		.ops		= &mbi_domain_ops,
+		.parent		= parent,
+		.msi_parent_ops = &gic_v3_mbi_msi_parent_ops,
+	};
 
-	nexus_domain = irq_domain_create_hierarchy(parent, 0, 0, parent->fwnode,
-						   &mbi_domain_ops, NULL);
-	if (!nexus_domain)
-		return -ENOMEM;
-
-	irq_domain_update_bus_token(nexus_domain, DOMAIN_BUS_NEXUS);
-	nexus_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-	nexus_domain->msi_parent_ops = &gic_v3_mbi_msi_parent_ops;
-	return 0;
+	return msi_create_parent_irq_domain(&info) ? 0 : -ENOMEM;
 }
 
 int __init mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent)





From thierry.reding at gmail.com  Wed Dec  4 05:57:22 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 4 Dec 2024 14:57:22 +0100
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <20241203111637.000023fe@gmail.com>
References: <20241021061023.2162701-1-0x1207@gmail.com>
 <d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
 <20241128144501.0000619b@gmail.com>
 <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com>
 <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
Message-ID: <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>

On Tue, Dec 03, 2024 at 11:16:37AM +0800, Furong Xu wrote:
> On Mon, 2 Dec 2024 18:34:25 -0800, Jakub Kicinski <kuba at kernel.org> wrote:
> 
> > On Tue, 3 Dec 2024 10:03:31 +0800 Furong Xu wrote:
> > > I requested Jon to provide more info about "Tx DMA map failed" in previous
> > > reply, and he does not respond yet.  
> > 
> > What does it mean to provide "more info" about a print statement from
> > the driver? Is there a Kconfig which he needs to set to get more info?
> > Perhaps you should provide a debug patch he can apply on his tree, that
> > will print info about (1) which buffer mapping failed (head or frags);
> > (2) what the physical address was of the buffer that couldn't be mapped.
> 
> A debug patch to print info about buffer makes no sense here.
> Both Tegra186 Jetson TX2(tegra186-p2771-0000) and Tegra194 Jetson AGX Xavier
> (tegra194-p2972-0000) enable IOMMU/SMMU for stmmac in its device-tree node,
> buffer info should be investigated with detailed IOMMU/SMMU debug info from
> drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c together.
> 
> I am not an expert in IOMMU, so I cannot help more.
> 
> Without the help from Jon, our only choice is revert as you said.

I was able to reproduce this locally and I get this splat:

--- >8 ---
[  228.179234] WARNING: CPU: 0 PID: 0 at drivers/iommu/io-pgtable-arm.c:346 __arm_lpae_map+0x388/0x4e4
[  228.188300] Modules linked in: snd_soc_tegra210_mixer snd_soc_tegra210_admaif snd_soc_tegra_pcm snd_soc_tegra186_asrc snd_soc_tegra210_ope snd_soc_tegra210_adx snd_soc_tegra210_mvc snd_soc_tegra210_dmic snd_soc_tegra186_dspk snd_soc_tegra210_sfc snd_soc_tegra210_amx snd_soc_tegra210_i2s tegra_drm drm_dp_aux_bus cec drm_display_helper drm_client_lib tegra210_adma snd_soc_tegra210_ahub drm_kms_helper snd_hda_codec_hdmi snd_hda_tegra snd_soc_tegra_audio_graph_card at24 snd_hda_codec ina3221 snd_soc_audio_graph_card snd_soc_simple_card_utils tegra_bpmp_thermal tegra_xudc snd_hda_core tegra_aconnect host1x fuse drm backlight ipv6
[  228.243750] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S                 6.13.0-rc1-next-20241203 #30
[  228.253412] Tainted: [S]=CPU_OUT_OF_SPEC
[  228.257336] Hardware name: nvidia NVIDIA P2771-0000-500/NVIDIA P2771-0000-500, BIOS 2025.01-rc3-00040-g36352ae2e68e-dirty 01/01/2025
[  228.269239] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  228.276205] pc : __arm_lpae_map+0x388/0x4e4
[  228.280398] lr : __arm_lpae_map+0x120/0x4e4
[  228.284587] sp : ffff8000800037f0
[  228.287901] x29: ffff800080003800 x28: 0000000000000002 x27: 0000000000000001
[  228.295050] x26: 0000000000000001 x25: 0000000111580000 x24: 0000000000001000
[  228.302197] x23: 000000ffffc72000 x22: 0000000000000ec0 x21: 0000000000000003
[  228.309342] x20: 0000000000000001 x19: ffff00008574b000 x18: 0000000000000001
[  228.316486] x17: 0000000000000000 x16: 0000000000000001 x15: ffff800080003ad0
[  228.323631] x14: ffff00008574d000 x13: 0000000000000000 x12: 0000000000000001
[  228.330775] x11: 0000000000000001 x10: 0000000000000001 x9 : 0000000000001000
[  228.337921] x8 : ffff00008674c390 x7 : ffff00008674c000 x6 : 0000000000000003
[  228.345066] x5 : 0000000000000003 x4 : 0000000000000001 x3 : 0000000000000002
[  228.352209] x2 : 0000000000000001 x1 : 0000000000000000 x0 : ffff00008574b000
[  228.359356] Call trace:
[  228.361807]  __arm_lpae_map+0x388/0x4e4 (P)
[  228.366002]  __arm_lpae_map+0x120/0x4e4 (L)
[  228.370198]  __arm_lpae_map+0x120/0x4e4
[  228.374042]  __arm_lpae_map+0x120/0x4e4
[  228.377886]  __arm_lpae_map+0x120/0x4e4
[  228.381730]  arm_lpae_map_pages+0x108/0x250
[  228.385922]  arm_smmu_map_pages+0x40/0x120
[  228.390029]  __iommu_map+0xfc/0x1bc
[  228.393525]  iommu_map+0x38/0xc0
[  228.396759]  __iommu_dma_map+0xb4/0x1a4
[  228.400604]  iommu_dma_map_page+0x14c/0x27c
[  228.404795]  dma_map_page_attrs+0x1fc/0x280
[  228.408987]  stmmac_tso_xmit+0x2d0/0xbac
[  228.412920]  stmmac_xmit+0x230/0xd14
[  228.416505]  dev_hard_start_xmit+0x94/0x11c
[  228.420697]  sch_direct_xmit+0x8c/0x380
[  228.424540]  __qdisc_run+0x11c/0x66c
[  228.428121]  net_tx_action+0x168/0x228
[  228.431875]  handle_softirqs+0x100/0x244
[  228.435809]  __do_softirq+0x14/0x20
[  228.439303]  ____do_softirq+0x10/0x20
[  228.442972]  call_on_irq_stack+0x24/0x64
[  228.446903]  do_softirq_own_stack+0x1c/0x40
[  228.451091]  __irq_exit_rcu+0xd4/0x10c
[  228.454847]  irq_exit_rcu+0x10/0x1c
[  228.458343]  el1_interrupt+0x38/0x68
[  228.461927]  el1h_64_irq_handler+0x18/0x24
[  228.466032]  el1h_64_irq+0x6c/0x70
[  228.469438]  default_idle_call+0x28/0x58 (P)
[  228.473718]  default_idle_call+0x24/0x58 (L)
[  228.477998]  do_idle+0x1fc/0x260
[  228.481234]  cpu_startup_entry+0x34/0x3c
[  228.485163]  rest_init+0xdc/0xe0
[  228.488401]  console_on_rootfs+0x0/0x6c
[  228.492250]  __primary_switched+0x88/0x90
[  228.496270] ---[ end trace 0000000000000000 ]---
[  228.500950] dwc-eth-dwmac 2490000.ethernet: Tx dma map failed
--- >8 ---

This looks to be slightly different from what Jon was seeing. Looking at
the WARN_ON() that triggers this, it seems like for some reason the page
is getting mapped twice.

Not exactly sure why that would be happening, so adding Robin and Will,
maybe they can shed some light on this from the ARM SMMU side.

Robin, Will, any idea who could be the culprit here? Is this a map/unmap
imbalance or something else entirely?

A lot of the context isn't present in this thread anymore, but here's a
link to the top of the thread:

	https://lore.kernel.org/netdev/d8112193-0386-4e14-b516-37c2d838171a at nvidia.com/T/

Thanks,
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/20241204/7c37092b/attachment.sig>

From linus.walleij at linaro.org  Wed Dec  4 05:58:51 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 14:58:51 +0100
Subject: [PATCH 02/15] ARM: limit OABI support to StrongARM CPUs
In-Reply-To: <20241204102904.1863796-3-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-3-arnd@kernel.org>
Message-ID: <CACRpkdY243J4C3A9_13eTN84T2SeOjyoh0bWk6U1mqffUd6urw@mail.gmail.com>

On Wed, Dec 4, 2024 at 11:29?AM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> As discussed on the mailing lists, there is no way to build OABI userspace
> binaries any more since gcc-4.8, and now support is also getting dropped in
> binutils, which will make it impossible to build pure OABI kernels at some
> point in the future.
>
> I found no evidence of anyone still sing OABI userspace on embedded systems
> that keep getting kernel updates, but there are a few desktop-class machines
> that date back to the 1990s using Intel StrongARM processors that were
> supported by old versions of Debian, Red Hat or the official Corel
> Netwinder distribution.
>
> Add a much stricter Kconfig dependency for both native OABI and OABI_COMPAT
> enabled kernels, only allowing either of them to be selected when building
> a kernel that targets a StrongARM based machine.
>
> Link: https://lore.kernel.org/lkml/2831c5a6-cfbf-4fe0-b51c-0396e5b0aeb7 at app.fastmail.com/
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

For
>  arch/arm/configs/versatile_defconfig   |  1 -

Acked-by: Linus Walleij <linus.walleij at linaro.org>


> diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig
(...)
>  CONFIG_ARCH_NETWINDER=y
> +# CONFIG_AEABI is not set
>  CONFIG_FPE_NWFPE=y
>  CONFIG_FPE_NWFPE_XP=y
> -# CONFIG_AEABI is not set

Hm why do we need a separate netwinder_defconfig if this defconfig already
supports it?

I am occasionally booting the NetWinder and then I use this defconfig,
the netwinder_defconfig wasn't even working for me.

Do you want to propose a separate patch to delete netwinder_defconfig,
otherwise I can send one. I think everyone (which is like ... 3 people) are
using footbridge_defconfig.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Dec  4 06:06:54 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 15:06:54 +0100
Subject: [PATCH 08/15] ARM: update FPE_NWFPE help text
In-Reply-To: <20241204102904.1863796-9-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-9-arnd@kernel.org>
Message-ID: <CACRpkdaj4DqETs8ueH9mVuGWfu4LgvWNKy-fb+3NKaUaCZY=tQ@mail.gmail.com>

On Wed, Dec 4, 2024 at 11:30?AM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> The help text is seriously outdated and predates the introduction of
> VFP floating point units that were available as early as some ARM926
> based systems.
>
> Change the help text to reflect that this is now a legacy feature
> and that it will go away along with OABI support in the future.
>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

On my affected silicon everything is custom compiled with
software floating point, so:
Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From geert+renesas at glider.be  Wed Dec  4 06:01:47 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed,  4 Dec 2024 15:01:47 +0100
Subject: [PATCH] ARM: shmobile: defconfig: Refresh for v6.13-rc1
Message-ID: <b8727e642508433016290a998c880b54de2e208d.1733320866.git.geert+renesas@glider.be>

Refresh the defconfig for Renesas ARM systems:
  - Enable RZ DMA Controller support, as used on the Genmai and RSK+RZA1
    development boards.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
To be queued in renesas-devel for v6.14.

 arch/arm/configs/shmobile_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 0e380e450a620e61..fd28f3176c6ba181 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -192,6 +192,7 @@ CONFIG_DW_DMAC=y
 CONFIG_RZN1_DMAMUX=y
 CONFIG_RCAR_DMAC=y
 CONFIG_RENESAS_USB_DMAC=y
+CONFIG_RZ_DMAC=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_ARCH_EMEV2=y
 CONFIG_ARCH_R8A7794=y
-- 
2.34.1



From linus.walleij at linaro.org  Wed Dec  4 06:02:03 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 15:02:03 +0100
Subject: [PATCH 03/15] ARM: rework ARM11 CPU selection logic
In-Reply-To: <20241204102904.1863796-4-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-4-arnd@kernel.org>
Message-ID: <CACRpkdYws_rfGPe--xj8d4Gu1pON=_T2sSAoTi3=sMz7wpSFHQ@mail.gmail.com>

On Wed, Dec 4, 2024 at 11:29?AM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> Support for SMP on ARM1136r0 has been broken for a while, and nobody
> is working on fixing it. I had a plan to change ARMv6 support to no
> longer coexist in a common kernel with ARMv7 CPUs but instead ARMv5 and
> below. This would have addressed the problem, but after a recent mailing
> list discussion, we concluded that an easier approach is to just forbid
> ARM1136r0 CPU support on SMP-enabled kernels.
>
> This mainly affects users of the Nokia N800/N810 tablets using an
> OMAP2420 SoC, which is the only commercial product with an ARM1136r0
> that is still supported by the kernel.
>
> The other machines that are still in the same hardware catogory are:
>
>  - TI OMAP2420 H4 reference board
>  - TI OMAP2430 SDP software development platform
>  - Freescale/NXP i.MX31 Lite Development Kit
>  - Buglabs i.MX31 Bug 1.x prototype
>  - Arm Integrator/AP with CM1136JF-S core module
>
> To my knowledge, none of these have any actual users aside from
> reference boards being used more easily test the platforms.
>
> There are also a few ARM1136r1 machines, which implement the
> ARMv6K SMP support (barriers, atomics and TLS):
>
>  - Eukrea CPUIMX35 reference platform
>  - Freescale/NXP i.MX35 Product Development Kit
>  - ARM Integrator/CP/IM-LT3 with ARM1136J Core Tile

I can't test that, I doubt anyone can. I think this support can
be simply deleted unless there is some QEMU support or
so.

>  - ARM Realview/EB with ARM1136J Core Tile

I will check if I have this one, otherwise this can probably go
as well.

>  arch/arm/mach-versatile/Kconfig | 10 +++++-----

For Versatile:
Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Dec  4 06:03:24 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 15:03:24 +0100
Subject: [PATCH 04/15] ARM: deprecate support for ARM1136r0
In-Reply-To: <20241204102904.1863796-5-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-5-arnd@kernel.org>
Message-ID: <CACRpkdYN0b9LqpPzrw1Xx-A0sUzUhjevT_J7S-sOyLE7Aeym2A@mail.gmail.com>

On Wed, Dec 4, 2024 at 11:29?AM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> This CPU revision remains a special case as it is now incompatible
> with CONFIG_SMP. Only the Nokia N8x0 is used in practice, and even
> that one is fairly rare these days, so let's plan to remove all of
> them after the 2025 LTS kernel release.
>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

For:
>  arch/arm/mach-versatile/Kconfig |  5 ++++-

Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Dec  4 06:04:22 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 15:04:22 +0100
Subject: [PATCH 05/15] ARM: turn CONFIG_ATAGS off by default
In-Reply-To: <20241204102904.1863796-6-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-6-arnd@kernel.org>
Message-ID: <CACRpkdbMjRbn3D5T26FtfUPN16b-3BMHr4Teak-Cd8O=iufU0A@mail.gmail.com>

On Wed, Dec 4, 2024 at 11:29?AM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> Only a very small number of machines remain that rely on
> traditional board files with the ATAGS boot data instead
> of devicetree, and we have not accepted new ones for
> a decade.
>
> Most of the remaining ones are on their way out of the
> kernel, but the Kconfig option that controls ATAGS
> is still enabled by default.
>
> To reflect the actual status of ATAGS support and alert
> the remaining users of upstream and out-of-tree platforms
> with this, chanyge it to being default-disabled and
> add a dependency on CONFIG_EXPERT.
>
> The board specific defconfig files that rely on ATAGS
> are changed to turn on both EXPERT and ATAGS if they
> were not doing thath already, and the ones that explicitly
> turned it off before no longer need to.
>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

For:

>  arch/arm/configs/integrator_defconfig  |  1 -
>  arch/arm/configs/multi_v4t_defconfig   |  1 -
>  arch/arm/configs/netwinder_defconfig   |  2 ++

Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Dec  4 06:04:53 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 15:04:53 +0100
Subject: [PATCH 06/15] ARM: update DEPRECATED_PARAM_STRUCT removal timeline
In-Reply-To: <20241204102904.1863796-7-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-7-arnd@kernel.org>
Message-ID: <CACRpkda2JoofOaep-TG90qi_Nik72a6ovuVCp-MRKQ6_U_NSbQ@mail.gmail.com>

On Wed, Dec 4, 2024 at 11:29?AM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> This configuration option is for the older boot method that preceeded
> ATAGS. This was scheduled for removal back in 2001, but the removal
> never happened, presumably because nobody cared enough to actually do it,
> not because there are any users left.
>
> Add "(DEPRECATED)' to the Kconfig line and update the timeline so we can
> remove it next year along with the other options that are not scheduled
> for that timeframe.
>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From robin.murphy at arm.com  Wed Dec  4 06:06:00 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 4 Dec 2024 14:06:00 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap for
 non-paged SKB data
In-Reply-To: <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
References: <20241021061023.2162701-1-0x1207@gmail.com>
 <d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
 <20241128144501.0000619b@gmail.com> <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com> <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
 <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
Message-ID: <df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>

On 2024-12-04 1:57 pm, Thierry Reding wrote:
> On Tue, Dec 03, 2024 at 11:16:37AM +0800, Furong Xu wrote:
>> On Mon, 2 Dec 2024 18:34:25 -0800, Jakub Kicinski <kuba at kernel.org> wrote:
>>
>>> On Tue, 3 Dec 2024 10:03:31 +0800 Furong Xu wrote:
>>>> I requested Jon to provide more info about "Tx DMA map failed" in previous
>>>> reply, and he does not respond yet.
>>>
>>> What does it mean to provide "more info" about a print statement from
>>> the driver? Is there a Kconfig which he needs to set to get more info?
>>> Perhaps you should provide a debug patch he can apply on his tree, that
>>> will print info about (1) which buffer mapping failed (head or frags);
>>> (2) what the physical address was of the buffer that couldn't be mapped.
>>
>> A debug patch to print info about buffer makes no sense here.
>> Both Tegra186 Jetson TX2(tegra186-p2771-0000) and Tegra194 Jetson AGX Xavier
>> (tegra194-p2972-0000) enable IOMMU/SMMU for stmmac in its device-tree node,
>> buffer info should be investigated with detailed IOMMU/SMMU debug info from
>> drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c together.
>>
>> I am not an expert in IOMMU, so I cannot help more.
>>
>> Without the help from Jon, our only choice is revert as you said.
> 
> I was able to reproduce this locally and I get this splat:
> 
> --- >8 ---
> [  228.179234] WARNING: CPU: 0 PID: 0 at drivers/iommu/io-pgtable-arm.c:346 __arm_lpae_map+0x388/0x4e4
> [  228.188300] Modules linked in: snd_soc_tegra210_mixer snd_soc_tegra210_admaif snd_soc_tegra_pcm snd_soc_tegra186_asrc snd_soc_tegra210_ope snd_soc_tegra210_adx snd_soc_tegra210_mvc snd_soc_tegra210_dmic snd_soc_tegra186_dspk snd_soc_tegra210_sfc snd_soc_tegra210_amx snd_soc_tegra210_i2s tegra_drm drm_dp_aux_bus cec drm_display_helper drm_client_lib tegra210_adma snd_soc_tegra210_ahub drm_kms_helper snd_hda_codec_hdmi snd_hda_tegra snd_soc_tegra_audio_graph_card at24 snd_hda_codec ina3221 snd_soc_audio_graph_card snd_soc_simple_card_utils tegra_bpmp_thermal tegra_xudc snd_hda_core tegra_aconnect host1x fuse drm backlight ipv6
> [  228.243750] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S                 6.13.0-rc1-next-20241203 #30
> [  228.253412] Tainted: [S]=CPU_OUT_OF_SPEC
> [  228.257336] Hardware name: nvidia NVIDIA P2771-0000-500/NVIDIA P2771-0000-500, BIOS 2025.01-rc3-00040-g36352ae2e68e-dirty 01/01/2025
> [  228.269239] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [  228.276205] pc : __arm_lpae_map+0x388/0x4e4
> [  228.280398] lr : __arm_lpae_map+0x120/0x4e4
> [  228.284587] sp : ffff8000800037f0
> [  228.287901] x29: ffff800080003800 x28: 0000000000000002 x27: 0000000000000001
> [  228.295050] x26: 0000000000000001 x25: 0000000111580000 x24: 0000000000001000
> [  228.302197] x23: 000000ffffc72000 x22: 0000000000000ec0 x21: 0000000000000003
> [  228.309342] x20: 0000000000000001 x19: ffff00008574b000 x18: 0000000000000001
> [  228.316486] x17: 0000000000000000 x16: 0000000000000001 x15: ffff800080003ad0
> [  228.323631] x14: ffff00008574d000 x13: 0000000000000000 x12: 0000000000000001
> [  228.330775] x11: 0000000000000001 x10: 0000000000000001 x9 : 0000000000001000
> [  228.337921] x8 : ffff00008674c390 x7 : ffff00008674c000 x6 : 0000000000000003
> [  228.345066] x5 : 0000000000000003 x4 : 0000000000000001 x3 : 0000000000000002
> [  228.352209] x2 : 0000000000000001 x1 : 0000000000000000 x0 : ffff00008574b000
> [  228.359356] Call trace:
> [  228.361807]  __arm_lpae_map+0x388/0x4e4 (P)
> [  228.366002]  __arm_lpae_map+0x120/0x4e4 (L)
> [  228.370198]  __arm_lpae_map+0x120/0x4e4
> [  228.374042]  __arm_lpae_map+0x120/0x4e4
> [  228.377886]  __arm_lpae_map+0x120/0x4e4
> [  228.381730]  arm_lpae_map_pages+0x108/0x250
> [  228.385922]  arm_smmu_map_pages+0x40/0x120
> [  228.390029]  __iommu_map+0xfc/0x1bc
> [  228.393525]  iommu_map+0x38/0xc0
> [  228.396759]  __iommu_dma_map+0xb4/0x1a4
> [  228.400604]  iommu_dma_map_page+0x14c/0x27c
> [  228.404795]  dma_map_page_attrs+0x1fc/0x280
> [  228.408987]  stmmac_tso_xmit+0x2d0/0xbac
> [  228.412920]  stmmac_xmit+0x230/0xd14
> [  228.416505]  dev_hard_start_xmit+0x94/0x11c
> [  228.420697]  sch_direct_xmit+0x8c/0x380
> [  228.424540]  __qdisc_run+0x11c/0x66c
> [  228.428121]  net_tx_action+0x168/0x228
> [  228.431875]  handle_softirqs+0x100/0x244
> [  228.435809]  __do_softirq+0x14/0x20
> [  228.439303]  ____do_softirq+0x10/0x20
> [  228.442972]  call_on_irq_stack+0x24/0x64
> [  228.446903]  do_softirq_own_stack+0x1c/0x40
> [  228.451091]  __irq_exit_rcu+0xd4/0x10c
> [  228.454847]  irq_exit_rcu+0x10/0x1c
> [  228.458343]  el1_interrupt+0x38/0x68
> [  228.461927]  el1h_64_irq_handler+0x18/0x24
> [  228.466032]  el1h_64_irq+0x6c/0x70
> [  228.469438]  default_idle_call+0x28/0x58 (P)
> [  228.473718]  default_idle_call+0x24/0x58 (L)
> [  228.477998]  do_idle+0x1fc/0x260
> [  228.481234]  cpu_startup_entry+0x34/0x3c
> [  228.485163]  rest_init+0xdc/0xe0
> [  228.488401]  console_on_rootfs+0x0/0x6c
> [  228.492250]  __primary_switched+0x88/0x90
> [  228.496270] ---[ end trace 0000000000000000 ]---
> [  228.500950] dwc-eth-dwmac 2490000.ethernet: Tx dma map failed
> --- >8 ---
> 
> This looks to be slightly different from what Jon was seeing. Looking at
> the WARN_ON() that triggers this, it seems like for some reason the page
> is getting mapped twice.
> 
> Not exactly sure why that would be happening, so adding Robin and Will,
> maybe they can shed some light on this from the ARM SMMU side.
> 
> Robin, Will, any idea who could be the culprit here? Is this a map/unmap
> imbalance or something else entirely?

If valid PTEs are getting left behind in the pagetable, that would 
indicate that a previous dma_unmap_page() was called with a size smaller 
than its original dma_map_page(). Throwing CONFIG_DMA_API_DEBUG at it 
should hopefully shed more light.

Cheers,
Robin.

> A lot of the context isn't present in this thread anymore, but here's a
> link to the top of the thread:
> 
> 	https://lore.kernel.org/netdev/d8112193-0386-4e14-b516-37c2d838171a at nvidia.com/T/
> 
> Thanks,
> Thierry



From tglx at linutronix.de  Wed Dec  4 06:07:04 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Wed, 04 Dec 2024 15:07:04 +0100
Subject: [PATCH v5 1/2] kexec: Consolidate
 machine_kexec_mask_interrupts() implementation
In-Reply-To: <4192766c8f02494a82db68f5732c6dd2@amazon.com>
References: <4192766c8f02494a82db68f5732c6dd2@amazon.com>
Message-ID: <875xnzsfsn.ffs@tglx>

On Wed, Dec 04 2024 at 11:40, Eliav Farber wrote:
> I'm just waiting for a reply if the new configuration option should be
> placed inside or after the following section:

I think you got one yesterday :)


From thierry.reding at gmail.com  Wed Dec  4 06:10:02 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 4 Dec 2024 15:10:02 +0100
Subject: [PATCH] drm: cast calculation to __u64 to fix potential integer
 overflow
In-Reply-To: <20241203160159.8129-1-zichenxie0106@gmail.com>
References: <20241203160159.8129-1-zichenxie0106@gmail.com>
Message-ID: <xlmfl2rhjgczu6oycgogchqi2gc65w7s3qy33yxzsrf6mbri3q@7onulkroaa7z>

On Tue, Dec 03, 2024 at 10:02:00AM -0600, Gax-c wrote:
> From: Zichen Xie <zichenxie0106 at gmail.com>
> 
> Like commit b0b0d811eac6 ("drm/mediatek: Fix coverity issue with
> unintentional integer overflow"), directly multiply pitch and
> height may lead to integer overflow. Add a cast to avoid it.
> 
> Fixes: 6d1782919dc9 ("drm/cma: Introduce drm_gem_cma_dumb_create_internal()")
> Fixes: dc5698e80cf7 ("Add virtio gpu driver.")
> Fixes: dc6057ecb39e ("drm/tegra: gem: dumb: pitch and size are outputs")
> Signed-off-by: Zichen Xie <zichenxie0106 at gmail.com>
> Cc: stable at vger.kernel.org
> ---
>  drivers/gpu/drm/drm_gem_dma_helper.c | 6 +++---
>  drivers/gpu/drm/tegra/gem.c          | 2 +-
>  drivers/gpu/drm/virtio/virtgpu_gem.c | 2 +-
>  3 files changed, 5 insertions(+), 5 deletions(-)

I don't think this can ever happen. All of these functions should only
ever be called via drm_mode_create_dumb(), which already ensures that
these won't overflow.

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/20241204/938743ed/attachment.sig>

From vkoul at kernel.org  Wed Dec  4 06:10:34 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 4 Dec 2024 19:40:34 +0530
Subject: [PATCH 8/9] phy: exynos5-usbdrd: subscribe to orientation
 notifier if required
In-Reply-To: <20241127-gs101-phy-lanes-orientation-phy-v1-8-1b7fce24960b@linaro.org>
References: <20241127-gs101-phy-lanes-orientation-phy-v1-0-1b7fce24960b@linaro.org>
 <20241127-gs101-phy-lanes-orientation-phy-v1-8-1b7fce24960b@linaro.org>
Message-ID: <Z1Bi2gRJefYy1tyo@vaman>

On 27-11-24, 10:58, Andr? Draszik wrote:
> gs101's SS phy needs to be configured differently based on the
> connector orientation, as the SS link can only be established if the
> mux is configured correctly.
> 
> The code to handle programming of the mux is in place already, this commit
> now adds the missing pieces to subscribe to the Type-C orientation
> switch event.
> 
> Note that for this all to work we rely on the USB controller
> re-initialising us. It should invoke our .exit() upon cable unplug, and
> during cable plug we'll receive the orientation event after which we
> expect our .init() to be called.
> 
> Above reinitialisation happens if the DWC3 controller can enter runtime
> suspend automatically. For the DWC3 driver, this is an opt-in:
>     echo auto > /sys/devices/.../11110000.usb/power/control
> Once done, things work as long as the UDC is not bound as otherwise it
> stays busy because it doesn't cancel / stop outstanding TRBs. For now
> we have to manually unbind the UDC in that case:
>      echo "" > sys/kernel/config/usb_gadget/.../UDC
> 
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> ---
>  drivers/phy/samsung/Kconfig              |  1 +
>  drivers/phy/samsung/phy-exynos5-usbdrd.c | 60 ++++++++++++++++++++++++++++++++
>  2 files changed, 61 insertions(+)
> 
> diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig
> index f10afa3d7ff5..fc7bd1088576 100644
> --- a/drivers/phy/samsung/Kconfig
> +++ b/drivers/phy/samsung/Kconfig
> @@ -80,6 +80,7 @@ config PHY_EXYNOS5_USBDRD
>  	tristate "Exynos5 SoC series USB DRD PHY driver"
>  	depends on (ARCH_EXYNOS && OF) || COMPILE_TEST
>  	depends on HAS_IOMEM
> +	depends on TYPEC || (TYPEC=n && COMPILE_TEST)
>  	depends on USB_DWC3_EXYNOS
>  	select GENERIC_PHY
>  	select MFD_SYSCON
> diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> index 1a34e9b4618a..2010d25ee817 100644
> --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> @@ -394,6 +394,7 @@ struct exynos5_usbdrd_phy_drvdata {
>   * @extrefclk: frequency select settings when using 'separate
>   *	       reference clocks' for SS and HS operations
>   * @regulators: regulators for phy
> + * @sw: TypeC orientation switch handle
>   * @orientation: TypeC connector orientation - normal or flipped
>   */
>  struct exynos5_usbdrd_phy {
> @@ -415,6 +416,7 @@ struct exynos5_usbdrd_phy {
>  	u32 extrefclk;
>  	struct regulator_bulk_data *regulators;
>  
> +	struct typec_switch_dev *sw;
>  	enum typec_orientation orientation;
>  };
>  
> @@ -1400,6 +1402,60 @@ static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd)
>  	return 0;
>  }
>  
> +#if IS_ENABLED(CONFIG_TYPEC)
> +static int exynos5_usbdrd_orien_sw_set(struct typec_switch_dev *sw,
> +				       enum typec_orientation orientation)
> +{
> +	struct exynos5_usbdrd_phy *phy_drd = typec_switch_get_drvdata(sw);
> +
> +	scoped_guard(mutex, &phy_drd->phy_mutex)
> +		phy_drd->orientation = orientation;
> +
> +	return 0;
> +}
> +
> +static void exynos5_usbdrd_orien_switch_unregister(void *data)
> +{
> +	struct exynos5_usbdrd_phy *phy_drd = data;
> +
> +	typec_switch_unregister(phy_drd->sw);
> +}
> +
> +static int exynos5_usbdrd_setup_notifiers(struct exynos5_usbdrd_phy *phy_drd)
> +{
> +	int ret;
> +
> +	phy_drd->orientation = (enum typec_orientation)-1;

Should this be TYPEC_ORIENTATION_NONE?

> +	if (device_property_present(phy_drd->dev, "orientation-switch")) {
> +		struct typec_switch_desc sw_desc = { };
> +
> +		sw_desc.drvdata = phy_drd;
> +		sw_desc.fwnode = dev_fwnode(phy_drd->dev);
> +		sw_desc.set = exynos5_usbdrd_orien_sw_set;
> +
> +		phy_drd->sw = typec_switch_register(phy_drd->dev, &sw_desc);
> +		if (IS_ERR(phy_drd->sw))
> +			return dev_err_probe(phy_drd->dev,
> +					     PTR_ERR(phy_drd->sw),
> +					     "Failed to register TypeC orientation switch\n");
> +
> +		ret = devm_add_action_or_reset(phy_drd->dev,
> +					       exynos5_usbdrd_orien_switch_unregister,
> +					       phy_drd);
> +		if (ret)
> +			return dev_err_probe(phy_drd->dev, ret,
> +					     "Failed to register TypeC orientation devm action\n");
> +	}
> +
> +	return 0;
> +}
> +#else /* CONFIG_TYPEC */
> +static int exynos5_usbdrd_setup_notifiers(struct exynos5_usbdrd_phy *phy_drd)
> +{
> +	return 0;
> +}
> +#endif /* CONFIG_TYPEC */
> +
>  static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
>  	{
>  		.id		= EXYNOS5_DRDPHY_UTMI,
> @@ -1789,6 +1845,10 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
>  	if (ret)
>  		return dev_err_probe(dev, ret, "failed to get regulators\n");
>  
> +	ret = exynos5_usbdrd_setup_notifiers(phy_drd);
> +	if (ret)
> +		return ret;
> +
>  	dev_vdbg(dev, "Creating usbdrd_phy phy\n");
>  
>  	for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {
> 
> -- 
> 2.47.0.338.g60cca15819-goog

-- 
~Vinod


From robh at kernel.org  Wed Dec  4 06:15:28 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 4 Dec 2024 08:15:28 -0600
Subject: [PATCH v4 1/5] dt-bindings: mmc: controller: clarify the
 address-cells description
In-Reply-To: <20241128-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v4-1-11d9f9200a59@linaro.org>
References: <20241128-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v4-0-11d9f9200a59@linaro.org>
 <20241128-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v4-1-11d9f9200a59@linaro.org>
Message-ID: <173332172731.169103.7423360262255147051.robh@kernel.org>


On Thu, 28 Nov 2024 16:16:41 +0100, Neil Armstrong wrote:
> The term "slot ID" has nothing to do with the SDIO function number
> which is specified in the reg property of the subnodes, rephrase
> the description to be more accurate.
> 
> Fixes: f9b7989859dd ("dt-bindings: mmc: Add YAML schemas for the generic MMC options")
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---
>  Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From robh at kernel.org  Wed Dec  4 06:15:37 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 4 Dec 2024 08:15:37 -0600
Subject: [PATCH v4 3/5] dt-bindings: mmc: controller: remove '|' when not
 needed
In-Reply-To: <20241128-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v4-3-11d9f9200a59@linaro.org>
References: <20241128-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v4-0-11d9f9200a59@linaro.org>
 <20241128-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v4-3-11d9f9200a59@linaro.org>
Message-ID: <173332173692.169425.77201239393030979.robh@kernel.org>


On Thu, 28 Nov 2024 16:16:43 +0100, Neil Armstrong wrote:
> Adding "|" is used to keep the description format, remove it when
> not needed after the split into mmc-controller.yaml and
> mmc-controller-common.yaml files.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---
>  Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml | 6 +++---
>  Documentation/devicetree/bindings/mmc/mmc-controller.yaml        | 2 +-
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From linus.walleij at linaro.org  Wed Dec  4 06:18:27 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 15:18:27 +0100
Subject: [PATCH 13/15] ARM: mark mach-sa1100 as deprecated
In-Reply-To: <20241204102904.1863796-14-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-14-arnd@kernel.org>
Message-ID: <CACRpkdYQUiN8VNTgK7-9bnr40TiACT3MSScb5QF3mz4MawzXHQ@mail.gmail.com>

On Wed, Dec 4, 2024 at 11:30?AM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> Most of the old StrongARM1100 machines were removed two years ago as part
> of a wider cleanup, the remaining four were left either because someone
> showed interest in converting them to devicetree, or because they were
> still supported by qemu and therefore useful to keep the platform alive.
>
> None of the devicetree conversion actually happened, and qemu has
> marked the platform as deprecated, so do the same in the kernel now.
>
> If anyone is still running one of these four machines and planning
> to keep updating their kernels, please speak up now so we can adapt
> the plans as needed.
>
> If nobody is found using StrongARM1100 any more, it can be removing
> during 2025, leaving 6.12-LTS as the last longterm support kernel
> for it.
>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

I do have an HP Compaq iPAQ still running.

BUT. I know very well that me and anyone else who actually want
to keep running that platform better get our act together and convert
it to device tree if we want to continue using it. If others are up
for testing I can surely help out.

Kristoffer Ericson is still listed as MAINTAINER for the Journada
so including him in the mail thread.

Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From farbere at amazon.com  Wed Dec  4 06:20:03 2024
From: farbere at amazon.com (Eliav Farber)
Date: Wed, 4 Dec 2024 14:20:03 +0000
Subject: [PATCH v6 2/2] kexec: Prevent redundant IRQ masking by checking state before shutdown
In-Reply-To: <20241204142003.32859-1-farbere@amazon.com>
References: <20241204142003.32859-1-farbere@amazon.com>
Message-ID: <20241204142003.32859-3-farbere@amazon.com>

During machine kexec, the function machine_kexec_mask_interrupts() is
responsible for disabling or masking all interrupts. While the irq_disable
hook ensures that an already-disabled IRQ is not disabled again, the
current implementation unconditionally invokes the irq_mask() function for
every interrupt descriptor, even when the interrupt is already masked.

A specific issue was observed in the crash kernel flow after unbinding a
device (prior to kexec) that used a GPIO as an IRQ source. The warning was
triggered by the gpiochip_disable_irq() function, which attempted to clear
the FLAG_IRQ_IS_ENABLED flag when FLAG_USED_AS_IRQ was not set:

```
void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset)
{
	struct gpio_desc *desc = gpiochip_get_desc(gc, offset);

	if (!IS_ERR(desc) &&
	    !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags)))
		clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
}
```

This issue surfaced after commit a8173820f441 ("gpio: gpiolib: Allow GPIO
IRQs to lazy disable") introduced lazy disablement for GPIO IRQs. It
replaced disable/enable hooks with mask/unmask hooks. Unlike the disable
hook, the mask hook doesn't handle already-masked IRQs.

When a GPIO-IRQ driver is unbound, the IRQ is released, triggering
__irq_disable() and irq_state_set_masked(). A subsequent call to
machine_kexec_mask_interrupts() re-invokes chip->irq_mask(). This results
in a call chain, including gpiochip_irq_mask() and gpiochip_disable_irq().
Since FLAG_USED_AS_IRQ was cleared earlier, a warning occurs.

Replace calls to irq_mask() and irq_disable() hooks with a simplified call
to irq_shutdown(), and check if the interrupt is started (irqd_is_started)
before calling the shutdown.

Signed-off-by: Eliav Farber <farbere at amazon.com>
---
V5 -> V6: No changes.

 kernel/irq/kexec.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/kernel/irq/kexec.c b/kernel/irq/kexec.c
index 0f9548c1708d..1a3deffe6b5b 100644
--- a/kernel/irq/kexec.c
+++ b/kernel/irq/kexec.c
@@ -17,7 +17,7 @@ void machine_kexec_mask_interrupts(void)
 		int check_eoi = 1;
 
 		chip = irq_desc_get_chip(desc);
-		if (!chip)
+		if (!chip || !irqd_is_started(&desc->irq_data))
 			continue;
 
 		if (IS_ENABLED(CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD)) {
@@ -31,10 +31,6 @@ void machine_kexec_mask_interrupts(void)
 		if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
 			chip->irq_eoi(&desc->irq_data);
 
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
+		irq_shutdown(desc);
 	}
 }
-- 
2.40.1



From farbere at amazon.com  Wed Dec  4 06:20:01 2024
From: farbere at amazon.com (Eliav Farber)
Date: Wed, 4 Dec 2024 14:20:01 +0000
Subject: [PATCH v6 0/2] Improve interrupt handling during machine kexec
Message-ID: <20241204142003.32859-1-farbere@amazon.com>

This patch series focuses on improving the machine_kexec_mask_interrupts()
function by consolidating its implementation and optimizing its behavior to
avoid redundant interrupt masking.

Patch Summary:
[PATCH v6 1/2] Move machine_kexec_mask_interrupts() to kernel/irq/kexec.c,
               removing duplicate architecture-specific implementations.
[PATCH v6 2/2] Refine machine_kexec_mask_interrupts() to avoid re-masking
               already-masked interrupts, resolving specific warnings
               triggered in GPIO IRQ flows.

Changes between v5 and v6:
 - Change GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD to not be user selectable.

Changes between v4 and v5:
 - The function machine_kexec_mask_interrupts() has been moved
   from kernel/kexec_core.c to a new file kernel/irq/kexec.c.
 - A new configuration option, GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD, has been
   added.
 - The parameters for the machine_kexec_mask_interrupts() function have
   been defined in reverse Christmas Tree style.
 - The comment explaining the call to irq_set_irqchip_state() has been
   improved for clarity.
 - The phrase 'This patch' has been removed from the commit message.

Changes between v3 and v4:
 - Add missing <linux/irqdesc.h> and <linux/irq.h> includes.

Eliav Farber (2):
  kexec: Consolidate machine_kexec_mask_interrupts() implementation
  kexec: Prevent redundant IRQ masking by checking state before shutdown

 arch/arm/kernel/machine_kexec.c   | 23 --------------------
 arch/arm64/Kconfig                |  1 +
 arch/arm64/kernel/machine_kexec.c | 31 --------------------------
 arch/powerpc/include/asm/kexec.h  |  1 -
 arch/powerpc/kexec/core.c         | 22 -------------------
 arch/powerpc/kexec/core_32.c      |  1 +
 arch/riscv/kernel/machine_kexec.c | 23 --------------------
 include/linux/irq.h               |  3 +++
 kernel/irq/Kconfig                |  6 ++++++
 kernel/irq/Makefile               |  2 +-
 kernel/irq/kexec.c                | 36 +++++++++++++++++++++++++++++++
 11 files changed, 48 insertions(+), 101 deletions(-)
 create mode 100644 kernel/irq/kexec.c

-- 
2.40.1



From farbere at amazon.com  Wed Dec  4 06:20:02 2024
From: farbere at amazon.com (Eliav Farber)
Date: Wed, 4 Dec 2024 14:20:02 +0000
Subject: [PATCH v6 1/2] kexec: Consolidate machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241204142003.32859-1-farbere@amazon.com>
References: <20241204142003.32859-1-farbere@amazon.com>
Message-ID: <20241204142003.32859-2-farbere@amazon.com>

Consolidate the machine_kexec_mask_interrupts implementation into a common
function located in a new file: kernel/irq/kexec.c. This removes duplicate
implementations from architecture-specific files in arch/arm, arch/arm64,
arch/powerpc, and arch/riscv, reducing code duplication and improving
maintainability.

The new implementation retains architecture-specific behavior for
CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD, which was previously implemented
for ARM64. When enabled (currently for ARM64), it clears the active state
of interrupts forwarded to virtual machines (VMs) before handling other
interrupt masking operations.

Signed-off-by: Eliav Farber <farbere at amazon.com>
---
V5 -> V6:
 - Change GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD to not be user selectable.

 arch/arm/kernel/machine_kexec.c   | 23 ------------------
 arch/arm64/Kconfig                |  1 +
 arch/arm64/kernel/machine_kexec.c | 31 ------------------------
 arch/powerpc/include/asm/kexec.h  |  1 -
 arch/powerpc/kexec/core.c         | 22 -----------------
 arch/powerpc/kexec/core_32.c      |  1 +
 arch/riscv/kernel/machine_kexec.c | 23 ------------------
 include/linux/irq.h               |  3 +++
 kernel/irq/Kconfig                |  6 +++++
 kernel/irq/Makefile               |  2 +-
 kernel/irq/kexec.c                | 40 +++++++++++++++++++++++++++++++
 11 files changed, 52 insertions(+), 101 deletions(-)
 create mode 100644 kernel/irq/kexec.c

diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 80ceb5bd2680..dd430477e7c1 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -127,29 +127,6 @@ void crash_smp_send_stop(void)
 	cpus_stopped = 1;
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 void machine_crash_shutdown(struct pt_regs *regs)
 {
 	local_irq_disable();
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..dcc3551cf6c2 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -149,6 +149,7 @@ config ARM64
 	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_IOREMAP
 	select GENERIC_IRQ_IPI
+	select GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IRQ_SHOW_LEVEL
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 82e2203d86a3..6f121a0164a4 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -207,37 +207,6 @@ void machine_kexec(struct kimage *kimage)
 	BUG(); /* Should never get here. */
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-		int ret;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		/*
-		 * First try to remove the active state. If this
-		 * fails, try to EOI the interrupt.
-		 */
-		ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
-
-		if (ret && irqd_irq_inprogress(&desc->irq_data) &&
-		    chip->irq_eoi)
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 /**
  * machine_crash_shutdown - shutdown non-crashing cpus and save registers
  */
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 270ee93a0f7d..601e569303e1 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -61,7 +61,6 @@ struct pt_regs;
 extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
 					  master to copy new code to 0 */
 extern void default_machine_kexec(struct kimage *image);
-extern void machine_kexec_mask_interrupts(void);
 
 void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer,
 			 unsigned long start_address) __noreturn;
diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
index b8333a49ea5d..58a930a47422 100644
--- a/arch/powerpc/kexec/core.c
+++ b/arch/powerpc/kexec/core.c
@@ -22,28 +22,6 @@
 #include <asm/setup.h>
 #include <asm/firmware.h>
 
-void machine_kexec_mask_interrupts(void) {
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 #ifdef CONFIG_CRASH_DUMP
 void machine_crash_shutdown(struct pt_regs *regs)
 {
diff --git a/arch/powerpc/kexec/core_32.c b/arch/powerpc/kexec/core_32.c
index c95f96850c9e..deb28eb44f30 100644
--- a/arch/powerpc/kexec/core_32.c
+++ b/arch/powerpc/kexec/core_32.c
@@ -7,6 +7,7 @@
  * Copyright (C) 2005 IBM Corporation.
  */
 
+#include <linux/irq.h>
 #include <linux/kexec.h>
 #include <linux/mm.h>
 #include <linux/string.h>
diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
index 3c830a6f7ef4..2306ce3e5f22 100644
--- a/arch/riscv/kernel/machine_kexec.c
+++ b/arch/riscv/kernel/machine_kexec.c
@@ -114,29 +114,6 @@ void machine_shutdown(void)
 #endif
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 /*
  * machine_crash_shutdown - Prepare to kexec after a kernel crash
  *
diff --git a/include/linux/irq.h b/include/linux/irq.h
index fa711f80957b..25f51bf3c351 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -694,6 +694,9 @@ extern int irq_chip_request_resources_parent(struct irq_data *data);
 extern void irq_chip_release_resources_parent(struct irq_data *data);
 #endif
 
+/* Disable or mask interrupts during a kernel kexec */
+extern void machine_kexec_mask_interrupts(void);
+
 /* Handling of unhandled and spurious interrupts: */
 extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
 
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 529adb1f5859..875f25ed6f71 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -141,6 +141,12 @@ config GENERIC_IRQ_DEBUGFS
 
 	  If you don't know what to do here, say N.
 
+# Clear forwarded VM interrupts during kexec.
+# This option ensures the kernel clears active states for interrupts
+# forwarded to virtual machines (VMs) during a machine kexec.
+config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
+	bool
+
 endmenu
 
 config GENERIC_IRQ_MULTI_HANDLER
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
index f19d3080bf11..c0f44c06d69d 100644
--- a/kernel/irq/Makefile
+++ b/kernel/irq/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o
+obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o kexec.o
 obj-$(CONFIG_IRQ_TIMINGS) += timings.o
 ifeq ($(CONFIG_TEST_IRQ_TIMINGS),y)
 	CFLAGS_timings.o += -DDEBUG
diff --git a/kernel/irq/kexec.c b/kernel/irq/kexec.c
new file mode 100644
index 000000000000..0f9548c1708d
--- /dev/null
+++ b/kernel/irq/kexec.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+#include <linux/irqnr.h>
+
+#include "internals.h"
+
+void machine_kexec_mask_interrupts(void)
+{
+	struct irq_desc *desc;
+	unsigned int i;
+
+	for_each_irq_desc(i, desc) {
+		struct irq_chip *chip;
+		int check_eoi = 1;
+
+		chip = irq_desc_get_chip(desc);
+		if (!chip)
+			continue;
+
+		if (IS_ENABLED(CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD)) {
+			/*
+			 * First try to remove the active state from an interrupt which is forwarded
+			 * to a VM. If the interrupt is not forwarded, try to EOI the interrupt.
+			 */
+			check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
+		}
+
+		if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
+			chip->irq_eoi(&desc->irq_data);
+
+		if (chip->irq_mask)
+			chip->irq_mask(&desc->irq_data);
+
+		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
+			chip->irq_disable(&desc->irq_data);
+	}
+}
-- 
2.40.1



From fshao at chromium.org  Wed Dec  4 06:25:38 2024
From: fshao at chromium.org (Fei Shao)
Date: Wed,  4 Dec 2024 22:25:38 +0800
Subject: [PATCH v2] drm/mediatek: dp: Support flexible length of DP calibration data
Message-ID: <20241204142626.158395-1-fshao@chromium.org>

The DP calibration data is stored in nvmem cells, and the data layout is
described in the `mtk_dp_efuse_fmt` arrays for each platform.

There is no guarantee that the data is always a 4-length u32 cell array.
For example, MT8188 has a data length of 3, preventing it from passing
the preliminary check and undergoing calibration.

Update the logic to support flexible data lengths. Specifically, we
validate the length returned from `nvmem_cell_read()` against the
platform-specific efuse format. If out-of-bound access is detected, fall
back to the default calibration values. This likely indicates an error
in either the efuse data length described in DT or the efuse format
within the driver.

Signed-off-by: Fei Shao <fshao at chromium.org>
---

Changes in v2:
- use %zu identifier for size_t in dev_warn()

 drivers/gpu/drm/mediatek/mtk_dp.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 36713c176cfc..55671701459a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -1165,17 +1165,25 @@ static void mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
 	buf = (u32 *)nvmem_cell_read(cell, &len);
 	nvmem_cell_put(cell);
 
-	if (IS_ERR(buf) || ((len / sizeof(u32)) != 4)) {
+	if (IS_ERR(buf)) {
 		dev_warn(dev, "Failed to read nvmem_cell_read\n");
-
-		if (!IS_ERR(buf))
-			kfree(buf);
-
 		goto use_default_val;
 	}
 
+	/* The cell length is in bytes. Convert it to be compatible with u32 buffer. */
+	len /= sizeof(u32);
+
 	for (i = 0; i < MTK_DP_CAL_MAX; i++) {
 		fmt = &mtk_dp->data->efuse_fmt[i];
+
+		if (fmt->idx >= len) {
+			dev_warn(mtk_dp->dev,
+				 "Out-of-bound efuse data access, fmt idx = %d, buf len = %zu\n",
+				 fmt->idx, len);
+			kfree(buf);
+			goto use_default_val;
+		}
+
 		cal_data[i] = (buf[fmt->idx] >> fmt->shift) & fmt->mask;
 
 		if (cal_data[i] < fmt->min_val || cal_data[i] > fmt->max_val) {
-- 
2.47.0.338.g60cca15819-goog



From robh at kernel.org  Wed Dec  4 06:27:22 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 4 Dec 2024 08:27:22 -0600
Subject: [PATCH v4 1/3] dt-bindings: net: nuvoton: Add schema for Nuvoton
 MA35 family GMAC
In-Reply-To: <20241202023643.75010-2-a0987203069@gmail.com>
References: <20241202023643.75010-1-a0987203069@gmail.com>
 <20241202023643.75010-2-a0987203069@gmail.com>
Message-ID: <20241204142722.GA177756-robh@kernel.org>

On Mon, Dec 02, 2024 at 10:36:41AM +0800, Joey Lu wrote:
> Create initial schema for Nuvoton MA35 family Gigabit MAC.
> 
> Signed-off-by: Joey Lu <a0987203069 at gmail.com>
> ---
>  .../bindings/net/nuvoton,ma35d1-dwmac.yaml    | 134 ++++++++++++++++++
>  .../devicetree/bindings/net/snps,dwmac.yaml   |   1 +
>  2 files changed, 135 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml b/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
> new file mode 100644
> index 000000000000..e44abaf4da3e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
> @@ -0,0 +1,134 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/nuvoton,ma35d1-dwmac.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Nuvoton DWMAC glue layer controller
> +
> +maintainers:
> +  - Joey Lu <yclu4 at nuvoton.com>
> +
> +description:
> +  Nuvoton 10/100/1000Mbps Gigabit Ethernet MAC Controller is based on
> +  Synopsys DesignWare MAC (version 3.73a).
> +
> +allOf:
> +  - $ref: snps,dwmac.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - nuvoton,ma35d1-dwmac
> +
> +  reg:
> +    maxItems: 1
> +    description:
> +      Register range should be one of the GMAC interface.
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: MAC clock
> +      - description: PTP clock
> +
> +  clock-names:
> +    items:
> +      - const: stmmaceth
> +      - const: ptp_ref
> +
> +  nuvoton,sys:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    items:
> +      - items:
> +          - description: phandle to access syscon registers.
> +          - description: GMAC interface ID.
> +            enum:
> +              - 0
> +              - 1
> +    description:
> +      A phandle to the syscon with one argument that configures system registers
> +      for MA35D1's two GMACs. The argument specifies the GMAC interface ID.
> +
> +  resets:
> +    maxItems: 1
> +
> +  reset-names:
> +    items:
> +      - const: stmmaceth
> +
> +  phy-mode:
> +    enum:
> +      - rmii
> +      - rgmii
> +      - rgmii-id
> +      - rgmii-txid
> +      - rgmii-rxid
> +
> +  tx-internal-delay-ps:
> +    default: 0
> +    minimum: 0
> +    maximum: 2000
> +    description:
> +      RGMII TX path delay used only when PHY operates in RGMII mode with
> +      internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds.
> +      Allowed values are from 0 to 2000.
> +
> +  rx-internal-delay-ps:
> +    default: 0
> +    minimum: 0
> +    maximum: 2000
> +    description:
> +      RGMII RX path delay used only when PHY operates in RGMII mode with
> +      internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds.
> +      Allowed values are from 0 to 2000.
> +
> +  mdio:
> +    $ref: /schemas/net/mdio.yaml#

Drop. snps,dwmac.yaml already has this.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - interrupt-names

Drop all 4. Already required by snps,dwmac.yaml.

> +  - clocks
> +  - clock-names
> +  - nuvoton,sys
> +  - resets
> +  - reset-names
> +  - phy-mode

Drop this one too.

> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
> +    #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
> +    ethernet at 40120000 {
> +        compatible = "nuvoton,ma35d1-dwmac";
> +        reg = <0x40120000 0x10000>;
> +        interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-names = "macirq";
> +        clocks = <&clk EMAC0_GATE>, <&clk EPLL_DIV8>;
> +        clock-names = "stmmaceth", "ptp_ref";
> +
> +        nuvoton,sys = <&sys 0>;
> +        resets = <&sys MA35D1_RESET_GMAC0>;
> +        reset-names = "stmmaceth";
> +
> +        phy-mode = "rgmii-id";
> +        phy-handle = <&eth_phy0>;
> +        mdio {
> +            compatible = "snps,dwmac-mdio";
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            ethernet-phy at 0 {
> +                reg = <0>;
> +            };
> +        };
> +    };
> diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> index eb1f3ae41ab9..4bf59ab910cc 100644
> --- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> +++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> @@ -67,6 +67,7 @@ properties:
>          - ingenic,x2000-mac
>          - loongson,ls2k-dwmac
>          - loongson,ls7a-dwmac
> +        - nuvoton,ma35d1-dwmac
>          - qcom,qcs404-ethqos
>          - qcom,sa8775p-ethqos
>          - qcom,sc8280xp-ethqos
> -- 
> 2.34.1
> 


From linus.walleij at linaro.org  Wed Dec  4 06:29:09 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 15:29:09 +0100
Subject: [PATCH 15/15] ARM: mark footbridge as deprecated
In-Reply-To: <20241204102904.1863796-16-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-16-arnd@kernel.org>
Message-ID: <CACRpkdahQhj5u9ATghszi-N2OYhFbvHF_W_eAMDAU+vhmvdrJA@mail.gmail.com>

On Wed, Dec 4, 2024 at 11:30?AM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> Along with RiscPC and SA1100, these are the last remaining Intel StrongARM
> machines. The Corel NetWinder used to be particular popular in the late
> 1990s, but was discontinued during the bankruptcy of rebel.com in 2001.
> The other machine is the DEC (later Intel) EBSA285 evaluation board that
> was made in small numbers in 1997 for software developers.

IIRC David Rusling at DEC was sending this board out to interested
developers.

> The footbridge/netwinder platform was the main target for the first Debian
> 2.0 "Hamm" release on the Arm architecture back in 1998, but was dropped
> in Debian 6.0 "Squeeze" in 2011, which only supported ARMv4T and higher
> with the EABI based ports as ARMv4 hardware had fallen already out of
> use by that time.
>
> Link: http://netwinder.org/
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Ralph Siemsen <ralph.siemsen at linaro.org>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

I am booting it occasionally, last time to test my KCFI patches.
But admittedly that is only to test it for other SA110 users. I remember
that Christoph had problems consolidating the DMA used in this
machine as well so it is standing in the way of useful work.

Apart from Ralph and me I know Marc Z has been known to boot
this machine, so paging him as well.

My machine is using an OABI RedHat MontaVista Hard Hat
derivative but the default userspace doesn't even have a /sys
directory so it's quite dated. I have a minimal homebrew
busybox userspace that I actually use for tests, admittedly
built with an OpenWrt compiler using the --fix-v4bx trick.

So from my point of view this system is on life support:
Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From alchark at gmail.com  Wed Dec  4 06:30:00 2024
From: alchark at gmail.com (Alexey Charkov)
Date: Wed, 4 Dec 2024 17:30:00 +0300
Subject: [PATCH v4 4/5] ARM: vt8500: Switch to new sys-off handler API
In-Reply-To: <20241202194107.105119-5-afd@ti.com>
References: <20241202194107.105119-1-afd@ti.com> <20241202194107.105119-5-afd@ti.com>
Message-ID: <CABjd4YxYjX2bHSBMmPxH-5muQL5TG_ATS8B0+vCdNKJARke6BQ@mail.gmail.com>

Hi Andrew,

On Mon, Dec 2, 2024 at 10:41?PM Andrew Davis <afd at ti.com> wrote:
>
> Kernel now supports chained power-off handlers. Use
> register_platform_power_off() that registers a platform level power-off
> handler. Legacy pm_power_off() will be removed once all drivers and archs
> are converted to the new sys-off API.
>
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  arch/arm/mach-vt8500/vt8500.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c
> index 0ab40087ae1cc..1d294255d7083 100644
> --- a/arch/arm/mach-vt8500/vt8500.c
> +++ b/arch/arm/mach-vt8500/vt8500.c
> @@ -141,7 +141,7 @@ static void __init vt8500_init(void)
>                         pr_err("%s:ioremap(power_off) failed\n", __func__);
>         }
>         if (pmc_base)
> -               pm_power_off = &vt8500_power_off;
> +               register_platform_power_off(vt8500_power_off);

This really calls for a separate tiny driver under drivers/power to
remove the legacy single-register remapping higher up in this
function... Pending that:

Acked-by: Alexey Charkov <alchark at gmail.com>

Best regards,
Alexey


From jani.nikula at intel.com  Wed Dec  4 06:31:12 2024
From: jani.nikula at intel.com (Jani Nikula)
Date: Wed,  4 Dec 2024 16:31:12 +0200
Subject: [PATCH v2 3/3] drm: remove driver date from struct drm_driver and all drivers
In-Reply-To: <cover.1733322525.git.jani.nikula@intel.com>
References: <cover.1733322525.git.jani.nikula@intel.com>
Message-ID: <1f2bf2543aed270a06f6c707fd6ed1b78bf16712.1733322525.git.jani.nikula@intel.com>

We stopped using the driver initialized date in commit 7fb8af6798e8
("drm: deprecate driver date") and (eventually) started returning "0"
for drm_version ioctl instead.

Finish the job, and remove the unused date member from struct
drm_driver, its initialization from drivers, along with the common
DRIVER_DATE macros.

v2: Also update drivers/accel (kernel test robot)

Reviewed-by: Javier Martinez Canillas <javierm at redhat.com>
Acked-by: Alex Deucher <alexander.deucher at amd.com>
Acked-by: Simon Ser <contact at emersion.fr>
Acked-by: Jeffrey Hugo <quic_jhugo at quicinc.com>
Signed-off-by: Jani Nikula <jani.nikula at intel.com>

---

Cc: David Airlie <airlied at gmail.com>
Cc: Hamza Mahfooz <hamza.mahfooz at amd.com>
Cc: Javier Martinez Canillas <javierm at redhat.com>
Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko at epam.com>
Cc: Simon Ser <contact at emersion.fr>
Cc: Simona Vetter <simona at ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann at suse.de>
Cc: Ville Syrj?l? <ville.syrjala at linux.intel.com>
Cc: amd-gfx at lists.freedesktop.org
Cc: dri-devel at lists.freedesktop.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: nouveau at lists.freedesktop.org
Cc: xen-devel at lists.xenproject.org
---
 drivers/accel/habanalabs/common/habanalabs_drv.c | 1 -
 drivers/accel/ivpu/ivpu_drv.c                    | 1 -
 drivers/accel/qaic/qaic_drv.c                    | 1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c          | 2 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h          | 1 -
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c  | 1 -
 drivers/gpu/drm/arm/hdlcd_drv.c                  | 1 -
 drivers/gpu/drm/arm/malidp_drv.c                 | 1 -
 drivers/gpu/drm/armada/armada_drv.c              | 1 -
 drivers/gpu/drm/aspeed/aspeed_gfx_drv.c          | 1 -
 drivers/gpu/drm/ast/ast_drv.c                    | 1 -
 drivers/gpu/drm/ast/ast_drv.h                    | 1 -
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c     | 1 -
 drivers/gpu/drm/etnaviv/etnaviv_drv.c            | 1 -
 drivers/gpu/drm/exynos/exynos_drm_drv.c          | 2 --
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c        | 1 -
 drivers/gpu/drm/gma500/psb_drv.c                 | 1 -
 drivers/gpu/drm/gma500/psb_drv.h                 | 1 -
 drivers/gpu/drm/gud/gud_drv.c                    | 1 -
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c  | 1 -
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c  | 1 -
 drivers/gpu/drm/hyperv/hyperv_drm_drv.c          | 2 --
 drivers/gpu/drm/i915/i915_driver.c               | 1 -
 drivers/gpu/drm/i915/i915_driver.h               | 1 -
 drivers/gpu/drm/i915/i915_gpu_error.c            | 1 -
 drivers/gpu/drm/imagination/pvr_drv.c            | 1 -
 drivers/gpu/drm/imagination/pvr_drv.h            | 1 -
 drivers/gpu/drm/imx/dcss/dcss-kms.c              | 1 -
 drivers/gpu/drm/imx/ipuv3/imx-drm-core.c         | 1 -
 drivers/gpu/drm/imx/lcdc/imx-lcdc.c              | 1 -
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c        | 1 -
 drivers/gpu/drm/kmb/kmb_drv.c                    | 1 -
 drivers/gpu/drm/kmb/kmb_drv.h                    | 1 -
 drivers/gpu/drm/lima/lima_drv.c                  | 1 -
 drivers/gpu/drm/logicvc/logicvc_drm.c            | 1 -
 drivers/gpu/drm/loongson/lsdc_drv.c              | 2 --
 drivers/gpu/drm/mcde/mcde_drv.c                  | 1 -
 drivers/gpu/drm/mediatek/mtk_drm_drv.c           | 2 --
 drivers/gpu/drm/meson/meson_drv.c                | 1 -
 drivers/gpu/drm/mgag200/mgag200_drv.c            | 1 -
 drivers/gpu/drm/mgag200/mgag200_drv.h            | 1 -
 drivers/gpu/drm/msm/msm_drv.c                    | 1 -
 drivers/gpu/drm/mxsfb/lcdif_drv.c                | 1 -
 drivers/gpu/drm/mxsfb/mxsfb_drv.c                | 1 -
 drivers/gpu/drm/nouveau/nouveau_drm.c            | 5 -----
 drivers/gpu/drm/nouveau/nouveau_drv.h            | 1 -
 drivers/gpu/drm/omapdrm/omap_drv.c               | 2 --
 drivers/gpu/drm/panfrost/panfrost_drv.c          | 1 -
 drivers/gpu/drm/panthor/panthor_drv.c            | 1 -
 drivers/gpu/drm/pl111/pl111_drv.c                | 1 -
 drivers/gpu/drm/qxl/qxl_drv.c                    | 1 -
 drivers/gpu/drm/qxl/qxl_drv.h                    | 1 -
 drivers/gpu/drm/radeon/radeon_drv.c              | 1 -
 drivers/gpu/drm/radeon/radeon_drv.h              | 1 -
 drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c    | 1 -
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c     | 1 -
 drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 1 -
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c      | 2 --
 drivers/gpu/drm/solomon/ssd130x.c                | 2 --
 drivers/gpu/drm/sprd/sprd_drm.c                  | 2 --
 drivers/gpu/drm/sti/sti_drv.c                    | 2 --
 drivers/gpu/drm/stm/drv.c                        | 1 -
 drivers/gpu/drm/sun4i/sun4i_drv.c                | 1 -
 drivers/gpu/drm/tegra/drm.c                      | 2 --
 drivers/gpu/drm/tidss/tidss_drv.c                | 1 -
 drivers/gpu/drm/tilcdc/tilcdc_drv.c              | 1 -
 drivers/gpu/drm/tiny/arcpgu.c                    | 1 -
 drivers/gpu/drm/tiny/bochs.c                     | 1 -
 drivers/gpu/drm/tiny/cirrus-qemu.c               | 2 --
 drivers/gpu/drm/tiny/gm12u320.c                  | 2 --
 drivers/gpu/drm/tiny/hx8357d.c                   | 1 -
 drivers/gpu/drm/tiny/ili9163.c                   | 1 -
 drivers/gpu/drm/tiny/ili9225.c                   | 1 -
 drivers/gpu/drm/tiny/ili9341.c                   | 1 -
 drivers/gpu/drm/tiny/ili9486.c                   | 1 -
 drivers/gpu/drm/tiny/mi0283qt.c                  | 1 -
 drivers/gpu/drm/tiny/ofdrm.c                     | 2 --
 drivers/gpu/drm/tiny/panel-mipi-dbi.c            | 1 -
 drivers/gpu/drm/tiny/repaper.c                   | 1 -
 drivers/gpu/drm/tiny/sharp-memory.c              | 1 -
 drivers/gpu/drm/tiny/simpledrm.c                 | 2 --
 drivers/gpu/drm/tiny/st7586.c                    | 1 -
 drivers/gpu/drm/tiny/st7735r.c                   | 1 -
 drivers/gpu/drm/tve200/tve200_drv.c              | 1 -
 drivers/gpu/drm/udl/udl_drv.c                    | 1 -
 drivers/gpu/drm/udl/udl_drv.h                    | 1 -
 drivers/gpu/drm/v3d/v3d_drv.c                    | 2 --
 drivers/gpu/drm/vboxvideo/vbox_drv.c             | 1 -
 drivers/gpu/drm/vboxvideo/vbox_drv.h             | 1 -
 drivers/gpu/drm/vc4/vc4_drv.c                    | 3 ---
 drivers/gpu/drm/vgem/vgem_drv.c                  | 2 --
 drivers/gpu/drm/virtio/virtgpu_drv.c             | 1 -
 drivers/gpu/drm/virtio/virtgpu_drv.h             | 1 -
 drivers/gpu/drm/vkms/vkms_drv.c                  | 2 --
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c              | 1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h              | 1 -
 drivers/gpu/drm/xe/xe_device.c                   | 1 -
 drivers/gpu/drm/xe/xe_drv.h                      | 1 -
 drivers/gpu/drm/xen/xen_drm_front.c              | 1 -
 drivers/gpu/drm/xlnx/zynqmp_kms.c                | 1 -
 include/drm/drm_drv.h                            | 2 --
 101 files changed, 126 deletions(-)

diff --git a/drivers/accel/habanalabs/common/habanalabs_drv.c b/drivers/accel/habanalabs/common/habanalabs_drv.c
index 708dfd10f39c..5409b2c656c8 100644
--- a/drivers/accel/habanalabs/common/habanalabs_drv.c
+++ b/drivers/accel/habanalabs/common/habanalabs_drv.c
@@ -101,7 +101,6 @@ static const struct drm_driver hl_driver = {
 	.major = LINUX_VERSION_MAJOR,
 	.minor = LINUX_VERSION_PATCHLEVEL,
 	.patchlevel = LINUX_VERSION_SUBLEVEL,
-	.date = "20190505",
 
 	.fops = &hl_fops,
 	.open = hl_device_open,
diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
index 1f359dbe5150..1e8ffbe25eee 100644
--- a/drivers/accel/ivpu/ivpu_drv.c
+++ b/drivers/accel/ivpu/ivpu_drv.c
@@ -458,7 +458,6 @@ static const struct drm_driver driver = {
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
 
-	.date = UTS_RELEASE,
 	.major = 1,
 };
 
diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c
index 3575e0c984d6..542c5d24e499 100644
--- a/drivers/accel/qaic/qaic_drv.c
+++ b/drivers/accel/qaic/qaic_drv.c
@@ -208,7 +208,6 @@ static const struct drm_driver qaic_accel_driver = {
 
 	.name			= QAIC_NAME,
 	.desc			= QAIC_DESC,
-	.date			= "20190618",
 
 	.fops			= &qaic_accel_fops,
 	.open			= qaic_open,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 346746d6c233..eaeaaddb32cd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2916,7 +2916,6 @@ static const struct drm_driver amdgpu_kms_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = KMS_DRIVER_MAJOR,
 	.minor = KMS_DRIVER_MINOR,
 	.patchlevel = KMS_DRIVER_PATCHLEVEL,
@@ -2940,7 +2939,6 @@ const struct drm_driver amdgpu_partition_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = KMS_DRIVER_MAJOR,
 	.minor = KMS_DRIVER_MINOR,
 	.patchlevel = KMS_DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h
index 5bc2cb661af7..2d86cc6f7f4d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h
@@ -40,7 +40,6 @@
 
 #define DRIVER_NAME		"amdgpu"
 #define DRIVER_DESC		"AMD GPU"
-#define DRIVER_DATE		"20150101"
 
 extern const struct drm_driver amdgpu_partition_driver;
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index 1e7b1fcb2848..6ed504099188 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -63,7 +63,6 @@ static const struct drm_driver komeda_kms_driver = {
 	.fops = &komeda_cma_fops,
 	.name = "komeda",
 	.desc = "Arm Komeda Display Processor driver",
-	.date = "20181101",
 	.major = 0,
 	.minor = 1,
 };
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 4af8fce7dab7..8617d10940d8 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -233,7 +233,6 @@ static const struct drm_driver hdlcd_driver = {
 	.fops = &fops,
 	.name = "hdlcd",
 	.desc = "ARM HDLCD Controller DRM",
-	.date = "20151021",
 	.major = 1,
 	.minor = 0,
 };
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 38b1b5b6bf69..3abc9339464b 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -570,7 +570,6 @@ static const struct drm_driver malidp_driver = {
 	.fops = &fops,
 	.name = "mali-dp",
 	.desc = "ARM Mali Display Processor driver",
-	.date = "20160106",
 	.major = 1,
 	.minor = 0,
 };
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index ddf0eaf546a6..5d5b7435970a 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -45,7 +45,6 @@ static const struct drm_driver armada_drm_driver = {
 	.minor			= 0,
 	.name			= "armada-drm",
 	.desc			= "Armada SoC DRM",
-	.date			= "20120730",
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.ioctls			= armada_ioctls,
 	.num_ioctls = ARRAY_SIZE(armada_ioctls),
diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
index 55e90ab9b231..90189a3cf886 100644
--- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
+++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
@@ -252,7 +252,6 @@ static const struct drm_driver aspeed_gfx_driver = {
 	.fops = &fops,
 	.name = "aspeed-gfx-drm",
 	.desc = "ASPEED GFX DRM",
-	.date = "20180319",
 	.major = 1,
 	.minor = 0,
 };
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 8e9c9cb89a50..ff3bcdd1cff2 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -60,7 +60,6 @@ static const struct drm_driver ast_driver = {
 	.fops = &ast_fops,
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 21ce3769bf0d..6b4305ac07d4 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -43,7 +43,6 @@
 
 #define DRIVER_NAME		"ast"
 #define DRIVER_DESC		"AST"
-#define DRIVER_DATE		"20120228"
 
 #define DRIVER_MAJOR		0
 #define DRIVER_MINOR		1
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 506289a937e2..b51528b2166c 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -846,7 +846,6 @@ static const struct drm_driver atmel_hlcdc_dc_driver = {
 	.fops = &fops,
 	.name = "atmel-hlcdc",
 	.desc = "Atmel HLCD Controller DRM",
-	.date = "20141504",
 	.major = 1,
 	.minor = 0,
 };
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 9b4e2f4b1bc7..c4ddabe3cabd 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -503,7 +503,6 @@ static const struct drm_driver etnaviv_drm_driver = {
 	.fops               = &fops,
 	.name               = "etnaviv",
 	.desc               = "etnaviv DRM",
-	.date               = "20151214",
 	.major              = 1,
 	.minor              = 4,
 };
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 7e517a2ec681..91ab42b56716 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -35,7 +35,6 @@
 
 #define DRIVER_NAME	"exynos"
 #define DRIVER_DESC	"Samsung SoC DRM"
-#define DRIVER_DATE	"20180330"
 
 /*
  * Interface history:
@@ -118,7 +117,6 @@ static const struct drm_driver exynos_drm_driver = {
 	.fops			= &exynos_drm_driver_fops,
 	.name	= DRIVER_NAME,
 	.desc	= DRIVER_DESC,
-	.date	= DRIVER_DATE,
 	.major	= DRIVER_MAJOR,
 	.minor	= DRIVER_MINOR,
 };
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index 12b2096b6c9d..e1183644ec39 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -174,7 +174,6 @@ static const struct drm_driver fsl_dcu_drm_driver = {
 	.fops			= &fsl_dcu_drm_fops,
 	.name			= "fsl-dcu-drm",
 	.desc			= "Freescale DCU DRM",
-	.date			= "20160425",
 	.major			= 1,
 	.minor			= 1,
 };
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 2c56ece17d71..85d3557c2eb9 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -513,7 +513,6 @@ static const struct drm_driver driver = {
 	.fops = &psb_gem_fops,
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index de62cbfcdc72..7f77cb2b2751 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -26,7 +26,6 @@
 
 #define DRIVER_NAME "gma500"
 #define DRIVER_DESC "DRM driver for the Intel GMA500, GMA600, GMA3600, GMA3650"
-#define DRIVER_DATE "20140314"
 
 #define DRIVER_MAJOR 1
 #define DRIVER_MINOR 0
diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
index 65a16f009ea6..cb405771d6e2 100644
--- a/drivers/gpu/drm/gud/gud_drv.c
+++ b/drivers/gpu/drm/gud/gud_drv.c
@@ -381,7 +381,6 @@ static const struct drm_driver gud_drm_driver = {
 
 	.name			= "gud",
 	.desc			= "Generic USB Display",
-	.date			= "20200422",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 69bdae604982..7f814c32ed34 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -57,7 +57,6 @@ static const struct drm_driver hibmc_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &hibmc_fops,
 	.name			= "hibmc",
-	.date			= "20160828",
 	.desc			= "hibmc drm driver",
 	.major			= 1,
 	.minor			= 0,
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index 5616c3917c03..2eb49177ac42 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -929,7 +929,6 @@ static const struct drm_driver ade_driver = {
 	DRM_FBDEV_DMA_DRIVER_OPS,
 	.name = "kirin",
 	.desc = "Hisilicon Kirin620 SoC DRM Driver",
-	.date = "20150718",
 	.major = 1,
 	.minor = 0,
 };
diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
index c5ac240f7a7a..f59abfa7622a 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
+++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
@@ -20,7 +20,6 @@
 
 #define DRIVER_NAME "hyperv_drm"
 #define DRIVER_DESC "DRM driver for Hyper-V synthetic video device"
-#define DRIVER_DATE "2020"
 #define DRIVER_MAJOR 1
 #define DRIVER_MINOR 0
 
@@ -31,7 +30,6 @@ static struct drm_driver hyperv_driver = {
 
 	.name		 = DRIVER_NAME,
 	.desc		 = DRIVER_DESC,
-	.date		 = DRIVER_DATE,
 	.major		 = DRIVER_MAJOR,
 	.minor		 = DRIVER_MINOR,
 
diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
index c1edf5e1f61e..e35aa0274d76 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -1797,7 +1797,6 @@ static const struct drm_driver i915_drm_driver = {
 	.fops = &i915_driver_fops,
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/i915/i915_driver.h b/drivers/gpu/drm/i915/i915_driver.h
index 94a70d8ec5d5..4b67ad9a61cd 100644
--- a/drivers/gpu/drm/i915/i915_driver.h
+++ b/drivers/gpu/drm/i915/i915_driver.h
@@ -15,7 +15,6 @@ struct drm_printer;
 
 #define DRIVER_NAME		"i915"
 #define DRIVER_DESC		"Intel Graphics"
-#define DRIVER_DATE		"20230929"
 #define DRIVER_TIMESTAMP	1695980603
 
 extern const struct dev_pm_ops i915_pm_ops;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 4eb58887819a..eb975b3815df 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -841,7 +841,6 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
 	err_printf(m, "Kernel: %s %s\n",
 		   init_utsname()->release,
 		   init_utsname()->machine);
-	err_printf(m, "Driver: %s\n", DRIVER_DATE);
 	ts = ktime_to_timespec64(error->time);
 	err_printf(m, "Time: %lld s %ld us\n",
 		   (s64)ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC);
diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c
index 36c0e768698e..6ab023593476 100644
--- a/drivers/gpu/drm/imagination/pvr_drv.c
+++ b/drivers/gpu/drm/imagination/pvr_drv.c
@@ -1387,7 +1387,6 @@ static struct drm_driver pvr_drm_driver = {
 
 	.name = PVR_DRIVER_NAME,
 	.desc = PVR_DRIVER_DESC,
-	.date = PVR_DRIVER_DATE,
 	.major = PVR_DRIVER_MAJOR,
 	.minor = PVR_DRIVER_MINOR,
 	.patchlevel = PVR_DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/imagination/pvr_drv.h b/drivers/gpu/drm/imagination/pvr_drv.h
index 378fe477b759..7fa147312dd1 100644
--- a/drivers/gpu/drm/imagination/pvr_drv.h
+++ b/drivers/gpu/drm/imagination/pvr_drv.h
@@ -9,7 +9,6 @@
 
 #define PVR_DRIVER_NAME "powervr"
 #define PVR_DRIVER_DESC "Imagination PowerVR (Series 6 and later) & IMG Graphics"
-#define PVR_DRIVER_DATE "20230904"
 
 /*
  * Driver interface version:
diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c
index 490b5c269f39..3633e8f3aff6 100644
--- a/drivers/gpu/drm/imx/dcss/dcss-kms.c
+++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c
@@ -34,7 +34,6 @@ static const struct drm_driver dcss_kms_driver = {
 	.fops			= &dcss_cma_fops,
 	.name			= "imx-dcss",
 	.desc			= "i.MX8MQ Display Subsystem",
-	.date			= "20190917",
 	.major			= 1,
 	.minor			= 0,
 	.patchlevel		= 0,
diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
index 6b84429735d6..bcb35ba670fc 100644
--- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
@@ -163,7 +163,6 @@ static const struct drm_driver imx_drm_driver = {
 	.fops			= &imx_drm_driver_fops,
 	.name			= "imx-drm",
 	.desc			= "i.MX DRM graphics",
-	.date			= "20120507",
 	.major			= 1,
 	.minor			= 0,
 	.patchlevel		= 0,
diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
index c5121fed80fd..d70981295f88 100644
--- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
+++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
@@ -352,7 +352,6 @@ static struct drm_driver imx_lcdc_drm_driver = {
 	DRM_FBDEV_DMA_DRIVER_OPS,
 	.name = "imx-lcdc",
 	.desc = "i.MX LCDC driver",
-	.date = "20200716",
 };
 
 static const struct of_device_id imx_lcdc_of_dev_id[] = {
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index 0a4eb3994cd6..6546d9ec410a 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -953,7 +953,6 @@ static const struct drm_driver ingenic_drm_driver_data = {
 	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
 	.name			= "ingenic-drm",
 	.desc			= "DRM module for Ingenic SoCs",
-	.date			= "20200716",
 	.major			= 1,
 	.minor			= 1,
 	.patchlevel		= 0,
diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c
index 4173344ba32c..c340b4c6a74b 100644
--- a/drivers/gpu/drm/kmb/kmb_drv.c
+++ b/drivers/gpu/drm/kmb/kmb_drv.c
@@ -445,7 +445,6 @@ static const struct drm_driver kmb_driver = {
 	DRM_FBDEV_DMA_DRIVER_OPS,
 	.name = "kmb-drm",
 	.desc = "KEEMBAY DISPLAY DRIVER",
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 };
diff --git a/drivers/gpu/drm/kmb/kmb_drv.h b/drivers/gpu/drm/kmb/kmb_drv.h
index bf085e95b28f..1f0c10d317fe 100644
--- a/drivers/gpu/drm/kmb/kmb_drv.h
+++ b/drivers/gpu/drm/kmb/kmb_drv.h
@@ -16,7 +16,6 @@
 #define KMB_MIN_WIDTH                   1920 /*Max width in pixels */
 #define KMB_MIN_HEIGHT                  1080 /*Max height in pixels */
 
-#define DRIVER_DATE			"20210223"
 #define DRIVER_MAJOR			1
 #define DRIVER_MINOR			1
 
diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
index 10bce18b7c31..4b70c5189f7c 100644
--- a/drivers/gpu/drm/lima/lima_drv.c
+++ b/drivers/gpu/drm/lima/lima_drv.c
@@ -271,7 +271,6 @@ static const struct drm_driver lima_drm_driver = {
 	.fops               = &lima_drm_driver_fops,
 	.name               = "lima",
 	.desc               = "lima DRM",
-	.date               = "20191231",
 	.major              = 1,
 	.minor              = 1,
 	.patchlevel         = 0,
diff --git a/drivers/gpu/drm/logicvc/logicvc_drm.c b/drivers/gpu/drm/logicvc/logicvc_drm.c
index 9152034e54a3..bda2a689d928 100644
--- a/drivers/gpu/drm/logicvc/logicvc_drm.c
+++ b/drivers/gpu/drm/logicvc/logicvc_drm.c
@@ -52,7 +52,6 @@ static struct drm_driver logicvc_drm_driver = {
 	.fops				= &logicvc_drm_fops,
 	.name				= "logicvc-drm",
 	.desc				= "Xylon LogiCVC DRM driver",
-	.date				= "20200403",
 	.major				= 1,
 	.minor				= 0,
 
diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
index a55aa1fe2c21..12193d2a301a 100644
--- a/drivers/gpu/drm/loongson/lsdc_drv.c
+++ b/drivers/gpu/drm/loongson/lsdc_drv.c
@@ -26,7 +26,6 @@
 #define DRIVER_AUTHOR               "Sui Jingfeng <suijingfeng at loongson.cn>"
 #define DRIVER_NAME                 "loongson"
 #define DRIVER_DESC                 "drm driver for loongson graphics"
-#define DRIVER_DATE                 "20220701"
 #define DRIVER_MAJOR                1
 #define DRIVER_MINOR                0
 #define DRIVER_PATCHLEVEL           0
@@ -39,7 +38,6 @@ static const struct drm_driver lsdc_drm_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index f8c7aa9d7f33..324a95d7f15b 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -208,7 +208,6 @@ static const struct drm_driver mcde_drm_driver = {
 	.fops = &drm_fops,
 	.name = "mcde",
 	.desc = DRIVER_DESC,
-	.date = "20180529",
 	.major = 1,
 	.minor = 0,
 	.patchlevel = 0,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 38297d705df6..723782e75c55 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -33,7 +33,6 @@
 
 #define DRIVER_NAME "mediatek"
 #define DRIVER_DESC "Mediatek SoC DRM"
-#define DRIVER_DATE "20150513"
 #define DRIVER_MAJOR 1
 #define DRIVER_MINOR 0
 
@@ -615,7 +614,6 @@ static const struct drm_driver mtk_drm_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 };
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 83ee18024682..64c8c4bb60f1 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -105,7 +105,6 @@ static const struct drm_driver meson_driver = {
 	.fops			= &fops,
 	.name			= DRIVER_NAME,
 	.desc			= DRIVER_DESC,
-	.date			= "20161109",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index b7ed763addfa..069fdd2dc8f6 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -97,7 +97,6 @@ static const struct drm_driver mgag200_driver = {
 	.fops = &mgag200_driver_fops,
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 988967eafbf2..0608fc63e588 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -25,7 +25,6 @@
 
 #define DRIVER_NAME		"mgag200"
 #define DRIVER_DESC		"MGA G200 SE"
-#define DRIVER_DATE		"20110418"
 
 #define DRIVER_MAJOR		1
 #define DRIVER_MINOR		0
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index b5fa715cbfb0..73e72aee6ec5 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -910,7 +910,6 @@ static const struct drm_driver msm_driver = {
 	.fops               = &fops,
 	.name               = "msm",
 	.desc               = "MSM Snapdragon DRM",
-	.date               = "20130625",
 	.major              = MSM_VERSION_MAJOR,
 	.minor              = MSM_VERSION_MINOR,
 	.patchlevel         = MSM_VERSION_PATCHLEVEL,
diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c
index 81ec91cef66c..02fe6b89f3aa 100644
--- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
+++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
@@ -248,7 +248,6 @@ static const struct drm_driver lcdif_driver = {
 	.fops	= &fops,
 	.name	= "imx-lcdif",
 	.desc	= "i.MX LCDIF Controller DRM",
-	.date	= "20220417",
 	.major	= 1,
 	.minor	= 0,
 };
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 1c27a97dce03..129cc3fb4448 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -336,7 +336,6 @@ static const struct drm_driver mxsfb_driver = {
 	.fops	= &fops,
 	.name	= "mxsfb-drm",
 	.desc	= "MXSFB Controller DRM",
-	.date	= "20160824",
 	.major	= 1,
 	.minor	= 0,
 };
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index a99c1d9855c9..744ae9d3305d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -1326,11 +1326,6 @@ driver_stub = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-#ifdef GIT_REVISION
-	.date = GIT_REVISION,
-#else
-	.date = DRIVER_DATE,
-#endif
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 685d6ca3d8aa..55abc510067b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -7,7 +7,6 @@
 
 #define DRIVER_NAME		"nouveau"
 #define DRIVER_DESC		"nVidia Riva/TNT/GeForce/Quadro/Tesla/Tegra K1+"
-#define DRIVER_DATE		"20120801"
 
 #define DRIVER_MAJOR		1
 #define DRIVER_MINOR		4
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 1796cd20a877..a80e0f375a0e 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -28,7 +28,6 @@
 
 #define DRIVER_NAME		MODULE_NAME
 #define DRIVER_DESC		"OMAP DRM"
-#define DRIVER_DATE		"20110917"
 #define DRIVER_MAJOR		1
 #define DRIVER_MINOR		0
 #define DRIVER_PATCHLEVEL	0
@@ -653,7 +652,6 @@ static const struct drm_driver omap_drm_driver = {
 	.fops = &omapdriver_fops,
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 04d615df5259..fbaef3afcd66 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -636,7 +636,6 @@ static const struct drm_driver panfrost_drm_driver = {
 	.fops			= &panfrost_drm_driver_fops,
 	.name			= "panfrost",
 	.desc			= "panfrost DRM",
-	.date			= "20180908",
 	.major			= 1,
 	.minor			= 3,
 
diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
index ac7e53f6e3f0..ad46a40ed9e1 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -1505,7 +1505,6 @@ static const struct drm_driver panthor_drm_driver = {
 	.fops = &panthor_drm_driver_fops,
 	.name = "panthor",
 	.desc = "Panthor DRM driver",
-	.date = "20230801",
 	.major = 1,
 	.minor = 2,
 
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index 4b96f48cf630..56ff6a3fb483 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -220,7 +220,6 @@ static const struct drm_driver pl111_drm_driver = {
 	.fops = &drm_fops,
 	.name = "pl111",
 	.desc = DRIVER_DESC,
-	.date = "20170317",
 	.major = 1,
 	.minor = 0,
 	.patchlevel = 0,
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index f15e9583b098..417061ae59eb 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -300,7 +300,6 @@ static struct drm_driver qxl_driver = {
 	.num_ioctls = ARRAY_SIZE(qxl_ioctls),
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = 0,
 	.minor = 1,
 	.patchlevel = 0,
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index b5fc14c9525d..cc02b5f10ad9 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -54,7 +54,6 @@ struct iosys_map;
 
 #define DRIVER_NAME		"qxl"
 #define DRIVER_DESC		"RH QXL"
-#define DRIVER_DATE		"20120117"
 
 #define DRIVER_MAJOR 0
 #define DRIVER_MINOR 1
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 5ce7e91bedad..267f082bc430 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -603,7 +603,6 @@ static const struct drm_driver kms_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = KMS_DRIVER_MAJOR,
 	.minor = KMS_DRIVER_MINOR,
 	.patchlevel = KMS_DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 02a65971d140..0f3dbffc492d 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -43,7 +43,6 @@
 
 #define DRIVER_NAME		"radeon"
 #define DRIVER_DESC		"ATI Radeon"
-#define DRIVER_DATE		"20080528"
 
 /* Interface history:
  *
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
index 0f5204ef996e..be39b107b98c 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
@@ -611,7 +611,6 @@ static const struct drm_driver rcar_du_driver = {
 	.fops			= &rcar_du_fops,
 	.name			= "rcar-du",
 	.desc			= "Renesas R-Car Display Unit",
-	.date			= "20130110",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
index 0a03a20f663b..9bbdc4d63d88 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
@@ -84,7 +84,6 @@ static const struct drm_driver rzg2l_du_driver = {
 	.fops			= &rzg2l_du_fops,
 	.name			= "rzg2l-du",
 	.desc			= "Renesas RZ/G2L Display Unit",
-	.date			= "20230410",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index 40b582ee178e..387eb602dadf 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -107,7 +107,6 @@ static const struct drm_driver shmob_drm_driver = {
 	.fops			= &shmob_drm_fops,
 	.name			= "shmob-drm",
 	.desc			= "Renesas SH Mobile DRM",
-	.date			= "20120424",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 0393b48ad65b..1fe4399d6901 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -39,7 +39,6 @@
 
 #define DRIVER_NAME	"rockchip"
 #define DRIVER_DESC	"RockChip Soc DRM"
-#define DRIVER_DATE	"20140818"
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
@@ -235,7 +234,6 @@ static const struct drm_driver rockchip_drm_driver = {
 	.fops			= &rockchip_drm_driver_fops,
 	.name	= DRIVER_NAME,
 	.desc	= DRIVER_DESC,
-	.date	= DRIVER_DATE,
 	.major	= DRIVER_MAJOR,
 	.minor	= DRIVER_MINOR,
 };
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
index a737f650c2bc..7b9f8fc193ac 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -39,7 +39,6 @@
 
 #define DRIVER_NAME	"ssd130x"
 #define DRIVER_DESC	"DRM driver for Solomon SSD13xx OLED displays"
-#define DRIVER_DATE	"20220131"
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
@@ -1784,7 +1783,6 @@ static const struct drm_driver ssd130x_drm_driver = {
 	DRM_FBDEV_SHMEM_DRIVER_OPS,
 	.name			= DRIVER_NAME,
 	.desc			= DRIVER_DESC,
-	.date			= DRIVER_DATE,
 	.major			= DRIVER_MAJOR,
 	.minor			= DRIVER_MINOR,
 	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
diff --git a/drivers/gpu/drm/sprd/sprd_drm.c b/drivers/gpu/drm/sprd/sprd_drm.c
index a74cd0caf645..867ee2d8997f 100644
--- a/drivers/gpu/drm/sprd/sprd_drm.c
+++ b/drivers/gpu/drm/sprd/sprd_drm.c
@@ -23,7 +23,6 @@
 
 #define DRIVER_NAME	"sprd"
 #define DRIVER_DESC	"Spreadtrum SoCs' DRM Driver"
-#define DRIVER_DATE	"20200201"
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
@@ -59,7 +58,6 @@ static struct drm_driver sprd_drm_drv = {
 
 	.name			= DRIVER_NAME,
 	.desc			= DRIVER_DESC,
-	.date			= DRIVER_DATE,
 	.major			= DRIVER_MAJOR,
 	.minor			= DRIVER_MINOR,
 };
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index a6c13318aa0b..46e6b674fa54 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -29,7 +29,6 @@
 
 #define DRIVER_NAME	"sti"
 #define DRIVER_DESC	"STMicroelectronics SoC DRM"
-#define DRIVER_DATE	"20140601"
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
@@ -143,7 +142,6 @@ static const struct drm_driver sti_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 };
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index d181d11b277b..40a62c57e04c 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -62,7 +62,6 @@ static const struct drm_driver drv_driver = {
 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
 	.name = "stm",
 	.desc = "STMicroelectronics SoC DRM",
-	.date = "20170330",
 	.major = 1,
 	.minor = 0,
 	.patchlevel = 0,
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index a7c11b795e98..025b0bdcbfd9 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -50,7 +50,6 @@ static const struct drm_driver sun4i_drv_driver = {
 	.fops			= &sun4i_drv_fops,
 	.name			= "sun4i-drm",
 	.desc			= "Allwinner sun4i Display Engine",
-	.date			= "20150629",
 	.major			= 1,
 	.minor			= 0,
 
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 34878f5d2918..4596073fe28f 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -35,7 +35,6 @@
 
 #define DRIVER_NAME "tegra"
 #define DRIVER_DESC "NVIDIA Tegra graphics"
-#define DRIVER_DATE "20120330"
 #define DRIVER_MAJOR 1
 #define DRIVER_MINOR 0
 #define DRIVER_PATCHLEVEL 0
@@ -901,7 +900,6 @@ static const struct drm_driver tegra_drm_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index 53bc219c097f..ee1132d581f5 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -113,7 +113,6 @@ static const struct drm_driver tidss_driver = {
 	DRM_FBDEV_DMA_DRIVER_OPS,
 	.name			= "tidss",
 	.desc			= "TI Keystone DSS",
-	.date			= "20180215",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 821d0ba26287..8013f01dbdf0 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -481,7 +481,6 @@ static const struct drm_driver tilcdc_driver = {
 	.fops               = &fops,
 	.name               = "tilcdc",
 	.desc               = "TI LCD Controller DRM",
-	.date               = "20121205",
 	.major              = 1,
 	.minor              = 0,
 };
diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c
index 5a0c8a874421..1e570f6f639f 100644
--- a/drivers/gpu/drm/tiny/arcpgu.c
+++ b/drivers/gpu/drm/tiny/arcpgu.c
@@ -367,7 +367,6 @@ static const struct drm_driver arcpgu_drm_driver = {
 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
 	.name = "arcpgu",
 	.desc = "ARC PGU Controller",
-	.date = "20160219",
 	.major = 1,
 	.minor = 0,
 	.patchlevel = 0,
diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
index 71a1f15d6ac9..89a699370a59 100644
--- a/drivers/gpu/drm/tiny/bochs.c
+++ b/drivers/gpu/drm/tiny/bochs.c
@@ -680,7 +680,6 @@ static const struct drm_driver bochs_driver = {
 	.fops			= &bochs_fops,
 	.name			= "bochs-drm",
 	.desc			= "bochs dispi vga interface (qemu stdvga)",
-	.date			= "20130925",
 	.major			= 1,
 	.minor			= 0,
 	DRM_GEM_SHMEM_DRIVER_OPS,
diff --git a/drivers/gpu/drm/tiny/cirrus-qemu.c b/drivers/gpu/drm/tiny/cirrus-qemu.c
index c0ae316888e2..52ec1e4ea9e5 100644
--- a/drivers/gpu/drm/tiny/cirrus-qemu.c
+++ b/drivers/gpu/drm/tiny/cirrus-qemu.c
@@ -48,7 +48,6 @@
 
 #define DRIVER_NAME "cirrus-qemu"
 #define DRIVER_DESC "qemu cirrus vga"
-#define DRIVER_DATE "2019"
 #define DRIVER_MAJOR 2
 #define DRIVER_MINOR 0
 
@@ -659,7 +658,6 @@ static const struct drm_driver cirrus_driver = {
 
 	.name		 = DRIVER_NAME,
 	.desc		 = DRIVER_DESC,
-	.date		 = DRIVER_DATE,
 	.major		 = DRIVER_MAJOR,
 	.minor		 = DRIVER_MINOR,
 
diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index 47dbee84d58b..41e9bfb2e2ff 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -34,7 +34,6 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
 
 #define DRIVER_NAME		"gm12u320"
 #define DRIVER_DESC		"Grain Media GM12U320 USB projector display"
-#define DRIVER_DATE		"2019"
 #define DRIVER_MAJOR		1
 #define DRIVER_MINOR		0
 
@@ -626,7 +625,6 @@ static const struct drm_driver gm12u320_drm_driver = {
 
 	.name		 = DRIVER_NAME,
 	.desc		 = DRIVER_DESC,
-	.date		 = DRIVER_DATE,
 	.major		 = DRIVER_MAJOR,
 	.minor		 = DRIVER_MINOR,
 
diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c
index 910279ebbbaa..df263818f45f 100644
--- a/drivers/gpu/drm/tiny/hx8357d.c
+++ b/drivers/gpu/drm/tiny/hx8357d.c
@@ -199,7 +199,6 @@ static const struct drm_driver hx8357d_driver = {
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "hx8357d",
 	.desc			= "HX8357D",
-	.date			= "20181023",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c
index e54ce120692f..62cadf5e033d 100644
--- a/drivers/gpu/drm/tiny/ili9163.c
+++ b/drivers/gpu/drm/tiny/ili9163.c
@@ -118,7 +118,6 @@ static struct drm_driver ili9163_driver = {
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "ili9163",
 	.desc			= "Ilitek ILI9163",
-	.date			= "20210208",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
index f322e67f473a..6de44ff69b51 100644
--- a/drivers/gpu/drm/tiny/ili9225.c
+++ b/drivers/gpu/drm/tiny/ili9225.c
@@ -364,7 +364,6 @@ static const struct drm_driver ili9225_driver = {
 	DRM_FBDEV_DMA_DRIVER_OPS,
 	.name			= "ili9225",
 	.desc			= "Ilitek ILI9225",
-	.date			= "20171106",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c
index 356c7f107c3e..e55029433509 100644
--- a/drivers/gpu/drm/tiny/ili9341.c
+++ b/drivers/gpu/drm/tiny/ili9341.c
@@ -155,7 +155,6 @@ static const struct drm_driver ili9341_driver = {
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "ili9341",
 	.desc			= "Ilitek ILI9341",
-	.date			= "20180514",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
index f5b1d21f7109..093661c771a0 100644
--- a/drivers/gpu/drm/tiny/ili9486.c
+++ b/drivers/gpu/drm/tiny/ili9486.c
@@ -177,7 +177,6 @@ static const struct drm_driver ili9486_driver = {
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "ili9486",
 	.desc			= "Ilitek ILI9486",
-	.date			= "20200118",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
index 61e33376fbc9..b6b4664908ae 100644
--- a/drivers/gpu/drm/tiny/mi0283qt.c
+++ b/drivers/gpu/drm/tiny/mi0283qt.c
@@ -159,7 +159,6 @@ static const struct drm_driver mi0283qt_driver = {
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "mi0283qt",
 	.desc			= "Multi-Inno MI0283QT",
-	.date			= "20160614",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c
index b27ed3677bfd..cd5916752507 100644
--- a/drivers/gpu/drm/tiny/ofdrm.c
+++ b/drivers/gpu/drm/tiny/ofdrm.c
@@ -25,7 +25,6 @@
 
 #define DRIVER_NAME	"ofdrm"
 #define DRIVER_DESC	"DRM driver for OF platform devices"
-#define DRIVER_DATE	"20220501"
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
@@ -1348,7 +1347,6 @@ static struct drm_driver ofdrm_driver = {
 	DRM_FBDEV_SHMEM_DRIVER_OPS,
 	.name			= DRIVER_NAME,
 	.desc			= DRIVER_DESC,
-	.date			= DRIVER_DATE,
 	.major			= DRIVER_MAJOR,
 	.minor			= DRIVER_MINOR,
 	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
index 79d5818cbbe6..4786b8144a9f 100644
--- a/drivers/gpu/drm/tiny/panel-mipi-dbi.c
+++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
@@ -269,7 +269,6 @@ static const struct drm_driver panel_mipi_dbi_driver = {
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "panel-mipi-dbi",
 	.desc			= "MIPI DBI compatible display panel",
-	.date			= "20220103",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index 9373063a13fc..52ba6c699bc8 100644
--- a/drivers/gpu/drm/tiny/repaper.c
+++ b/drivers/gpu/drm/tiny/repaper.c
@@ -917,7 +917,6 @@ static const struct drm_driver repaper_driver = {
 	DRM_FBDEV_DMA_DRIVER_OPS,
 	.name			= "repaper",
 	.desc			= "Pervasive Displays RePaper e-ink panels",
-	.date			= "20170405",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/sharp-memory.c b/drivers/gpu/drm/tiny/sharp-memory.c
index d87068126f9b..03d2850310c4 100644
--- a/drivers/gpu/drm/tiny/sharp-memory.c
+++ b/drivers/gpu/drm/tiny/sharp-memory.c
@@ -107,7 +107,6 @@ static const struct drm_driver sharp_memory_drm_driver = {
 	DRM_FBDEV_DMA_DRIVER_OPS,
 	.name			= "sharp_memory_display",
 	.desc			= "Sharp Display Memory LCD",
-	.date			= "20231129",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index b3a2fc11dcf0..b47ca2d902d9 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -31,7 +31,6 @@
 
 #define DRIVER_NAME	"simpledrm"
 #define DRIVER_DESC	"DRM driver for simple-framebuffer platform devices"
-#define DRIVER_DATE	"20200625"
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
@@ -1015,7 +1014,6 @@ static struct drm_driver simpledrm_driver = {
 	DRM_FBDEV_SHMEM_DRIVER_OPS,
 	.name			= DRIVER_NAME,
 	.desc			= DRIVER_DESC,
-	.date			= DRIVER_DATE,
 	.major			= DRIVER_MAJOR,
 	.minor			= DRIVER_MINOR,
 	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
index 7bfd4296c1c9..a29672d84ede 100644
--- a/drivers/gpu/drm/tiny/st7586.c
+++ b/drivers/gpu/drm/tiny/st7586.c
@@ -295,7 +295,6 @@ static const struct drm_driver st7586_driver = {
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "st7586",
 	.desc			= "Sitronix ST7586",
-	.date			= "20170801",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
index 6832ca590127..1d60f6e5b3bc 100644
--- a/drivers/gpu/drm/tiny/st7735r.c
+++ b/drivers/gpu/drm/tiny/st7735r.c
@@ -160,7 +160,6 @@ static const struct drm_driver st7735r_driver = {
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "st7735r",
 	.desc			= "Sitronix ST7735R",
-	.date			= "20171128",
 	.major			= 1,
 	.minor			= 0,
 };
diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c
index cb66dbbe2801..65a0d4301160 100644
--- a/drivers/gpu/drm/tve200/tve200_drv.c
+++ b/drivers/gpu/drm/tve200/tve200_drv.c
@@ -146,7 +146,6 @@ static const struct drm_driver tve200_drm_driver = {
 	.fops = &drm_fops,
 	.name = "tve200",
 	.desc = DRIVER_DESC,
-	.date = "20170703",
 	.major = 1,
 	.minor = 0,
 	.patchlevel = 0,
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index 6c182b21028e..05b3a152cc33 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -78,7 +78,6 @@ static const struct drm_driver driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index 1eb716d9dad5..be00dc1d87a1 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -26,7 +26,6 @@ struct drm_mode_create_dumb;
 
 #define DRIVER_NAME		"udl"
 #define DRIVER_DESC		"DisplayLink"
-#define DRIVER_DATE		"20120220"
 
 #define DRIVER_MAJOR		0
 #define DRIVER_MINOR		0
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index fb35c5c3f1a7..9d8de9146cb0 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -31,7 +31,6 @@
 
 #define DRIVER_NAME "v3d"
 #define DRIVER_DESC "Broadcom V3D graphics"
-#define DRIVER_DATE "20180419"
 #define DRIVER_MAJOR 1
 #define DRIVER_MINOR 0
 #define DRIVER_PATCHLEVEL 0
@@ -248,7 +247,6 @@ static const struct drm_driver v3d_drm_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
index d9d884aad97f..bb861f0a0a31 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
@@ -189,7 +189,6 @@ static const struct drm_driver driver = {
 	.fops = &vbox_fops,
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h
index e77bd6512eb1..dfa935f381a6 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
+++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
@@ -25,7 +25,6 @@
 
 #define DRIVER_NAME         "vboxvideo"
 #define DRIVER_DESC         "Oracle VM VirtualBox Graphics Card"
-#define DRIVER_DATE         "20130823"
 
 #define DRIVER_MAJOR        1
 #define DRIVER_MINOR        0
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index ee5df153c2a6..e88a7ee486c6 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -47,7 +47,6 @@
 
 #define DRIVER_NAME "vc4"
 #define DRIVER_DESC "Broadcom VC4 graphics"
-#define DRIVER_DATE "20140616"
 #define DRIVER_MAJOR 0
 #define DRIVER_MINOR 0
 #define DRIVER_PATCHLEVEL 0
@@ -222,7 +221,6 @@ const struct drm_driver vc4_drm_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
@@ -244,7 +242,6 @@ const struct drm_driver vc5_drm_driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index c5e3e5457737..2752ab4f1c97 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -47,7 +47,6 @@
 
 #define DRIVER_NAME	"vgem"
 #define DRIVER_DESC	"Virtual GEM provider"
-#define DRIVER_DATE	"20120112"
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
@@ -121,7 +120,6 @@ static const struct drm_driver vgem_driver = {
 
 	.name	= DRIVER_NAME,
 	.desc	= DRIVER_DESC,
-	.date	= DRIVER_DATE,
 	.major	= DRIVER_MAJOR,
 	.minor	= DRIVER_MINOR,
 };
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index e216123ce6a5..6a67c6297d58 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -201,7 +201,6 @@ static const struct drm_driver driver = {
 
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 8328107edf78..f42ca9d8ed10 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -45,7 +45,6 @@
 
 #define DRIVER_NAME "virtio_gpu"
 #define DRIVER_DESC "virtio GPU"
-#define DRIVER_DATE "0"
 
 #define DRIVER_MAJOR 0
 #define DRIVER_MINOR 1
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index fa3331f612e3..e0409aba9349 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -34,7 +34,6 @@
 
 #define DRIVER_NAME	"vkms"
 #define DRIVER_DESC	"Virtual Kernel Mode Setting"
-#define DRIVER_DATE	"20180514"
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
@@ -116,7 +115,6 @@ static const struct drm_driver vkms_driver = {
 
 	.name			= DRIVER_NAME,
 	.desc			= DRIVER_DESC,
-	.date			= DRIVER_DATE,
 	.major			= DRIVER_MAJOR,
 	.minor			= DRIVER_MINOR,
 };
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index ded48554568a..1699236fca5a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1634,7 +1634,6 @@ static const struct drm_driver driver = {
 	.fops = &vmwgfx_driver_fops,
 	.name = VMWGFX_DRIVER_NAME,
 	.desc = VMWGFX_DRIVER_DESC,
-	.date = VMWGFX_DRIVER_DATE,
 	.major = VMWGFX_DRIVER_MAJOR,
 	.minor = VMWGFX_DRIVER_MINOR,
 	.patchlevel = VMWGFX_DRIVER_PATCHLEVEL
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index b21831ef214a..5275ef632d4b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -57,7 +57,6 @@
 
 
 #define VMWGFX_DRIVER_NAME "vmwgfx"
-#define VMWGFX_DRIVER_DATE "20211206"
 #define VMWGFX_DRIVER_MAJOR 2
 #define VMWGFX_DRIVER_MINOR 20
 #define VMWGFX_DRIVER_PATCHLEVEL 0
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index d6fccea1e083..56d4ffb650da 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -271,7 +271,6 @@ static struct drm_driver driver = {
 	.fops = &xe_driver_fops,
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
-	.date = DRIVER_DATE,
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
diff --git a/drivers/gpu/drm/xe/xe_drv.h b/drivers/gpu/drm/xe/xe_drv.h
index d45b71426cc8..d61650d4aa0b 100644
--- a/drivers/gpu/drm/xe/xe_drv.h
+++ b/drivers/gpu/drm/xe/xe_drv.h
@@ -10,7 +10,6 @@
 
 #define DRIVER_NAME		"xe"
 #define DRIVER_DESC		"Intel Xe Graphics"
-#define DRIVER_DATE		"20201103"
 
 /* Interface history:
  *
diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
index 931d855bfbe8..1bda7ef606cc 100644
--- a/drivers/gpu/drm/xen/xen_drm_front.c
+++ b/drivers/gpu/drm/xen/xen_drm_front.c
@@ -478,7 +478,6 @@ static const struct drm_driver xen_drm_driver = {
 	.fops                      = &xen_drm_dev_fops,
 	.name                      = "xendrm-du",
 	.desc                      = "Xen PV DRM Display Unit",
-	.date                      = "20180221",
 	.major                     = 1,
 	.minor                     = 0,
 
diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c
index e272ecbce78d..b47463473472 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_kms.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c
@@ -409,7 +409,6 @@ static const struct drm_driver zynqmp_dpsub_drm_driver = {
 
 	.name				= "zynqmp-dpsub",
 	.desc				= "Xilinx DisplayPort Subsystem Driver",
-	.date				= "20130509",
 	.major				= 1,
 	.minor				= 0,
 };
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 1bbbcb8e2d23..1b6e59139e6c 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -401,8 +401,6 @@ struct drm_driver {
 	char *name;
 	/** @desc: driver description */
 	char *desc;
-	/** @date: driver date, unused, to be removed */
-	char *date;
 
 	/**
 	 * @driver_features:
-- 
2.39.5



From linux at armlinux.org.uk  Wed Dec  4 06:37:41 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Dec 2024 14:37:41 +0000
Subject: [PATCH 15/15] ARM: mark footbridge as deprecated
In-Reply-To: <CACRpkdahQhj5u9ATghszi-N2OYhFbvHF_W_eAMDAU+vhmvdrJA@mail.gmail.com>
References: <20241204102904.1863796-1-arnd@kernel.org>
 <20241204102904.1863796-16-arnd@kernel.org>
 <CACRpkdahQhj5u9ATghszi-N2OYhFbvHF_W_eAMDAU+vhmvdrJA@mail.gmail.com>
Message-ID: <Z1BpNQjWwxEKFbg0@shell.armlinux.org.uk>

On Wed, Dec 04, 2024 at 03:29:09PM +0100, Linus Walleij wrote:
> On Wed, Dec 4, 2024 at 11:30?AM Arnd Bergmann <arnd at kernel.org> wrote:
> 
> > From: Arnd Bergmann <arnd at arndb.de>
> >
> > Along with RiscPC and SA1100, these are the last remaining Intel StrongARM
> > machines. The Corel NetWinder used to be particular popular in the late
> > 1990s, but was discontinued during the bankruptcy of rebel.com in 2001.
> > The other machine is the DEC (later Intel) EBSA285 evaluation board that
> > was made in small numbers in 1997 for software developers.
> 
> IIRC David Rusling at DEC was sending this board out to interested
> developers.
> 
> > The footbridge/netwinder platform was the main target for the first Debian
> > 2.0 "Hamm" release on the Arm architecture back in 1998, but was dropped
> > in Debian 6.0 "Squeeze" in 2011, which only supported ARMv4T and higher
> > with the EABI based ports as ARMv4 hardware had fallen already out of
> > use by that time.
> >
> > Link: http://netwinder.org/
> > Cc: Linus Walleij <linus.walleij at linaro.org>
> > Cc: Russell King <linux at armlinux.org.uk>
> > Cc: Ralph Siemsen <ralph.siemsen at linaro.org>
> > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> 
> I am booting it occasionally, last time to test my KCFI patches.
> But admittedly that is only to test it for other SA110 users. I remember
> that Christoph had problems consolidating the DMA used in this
> machine as well so it is standing in the way of useful work.

What problems with DMA? The fact that it uses an offset between
physical and PCI bus space should be nothing that causes a problem
for the kernel. As maintainer for Footbridge, I've heard nothing
about there being any issue.

-- 
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 Dec  4 06:41:03 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Wed,  4 Dec 2024 15:41:03 +0100
Subject: [PATCH] gpio: GPIO_MVEBU should not default to y when compile-testing
In-Reply-To: <6b9e55dbf544297d5acf743f6fa473791ab10644.1733242798.git.geert+renesas@glider.be>
References: <6b9e55dbf544297d5acf743f6fa473791ab10644.1733242798.git.geert+renesas@glider.be>
Message-ID: <173332326029.11398.6855202202316597607.b4-ty@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>


On Tue, 03 Dec 2024 17:23:16 +0100, Geert Uytterhoeven wrote:
> Merely enabling compile-testing should not enable additional
> functionality.
> 
> 

Applied, thanks!

[1/1] gpio: GPIO_MVEBU should not default to y when compile-testing
      commit: 70327137eb3eb64f346191dcd0ee5140d5ab34d8

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski at linaro.org>


From maz at kernel.org  Wed Dec  4 06:44:07 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Dec 2024 14:44:07 +0000
Subject: [PATCH 15/15] ARM: mark footbridge as deprecated
In-Reply-To: <CACRpkdahQhj5u9ATghszi-N2OYhFbvHF_W_eAMDAU+vhmvdrJA@mail.gmail.com>
References: <20241204102904.1863796-1-arnd@kernel.org>
	<20241204102904.1863796-16-arnd@kernel.org>
	<CACRpkdahQhj5u9ATghszi-N2OYhFbvHF_W_eAMDAU+vhmvdrJA@mail.gmail.com>
Message-ID: <86ldwvtsnc.wl-maz@kernel.org>

On Wed, 04 Dec 2024 14:29:09 +0000,
Linus Walleij <linus.walleij at linaro.org> wrote:
> 
> On Wed, Dec 4, 2024 at 11:30?AM Arnd Bergmann <arnd at kernel.org> wrote:
> 
> > From: Arnd Bergmann <arnd at arndb.de>
> >
> > Along with RiscPC and SA1100, these are the last remaining Intel StrongARM
> > machines. The Corel NetWinder used to be particular popular in the late
> > 1990s, but was discontinued during the bankruptcy of rebel.com in 2001.
> > The other machine is the DEC (later Intel) EBSA285 evaluation board that
> > was made in small numbers in 1997 for software developers.
> 
> IIRC David Rusling at DEC was sending this board out to interested
> developers.
> 
> > The footbridge/netwinder platform was the main target for the first Debian
> > 2.0 "Hamm" release on the Arm architecture back in 1998, but was dropped
> > in Debian 6.0 "Squeeze" in 2011, which only supported ARMv4T and higher
> > with the EABI based ports as ARMv4 hardware had fallen already out of
> > use by that time.
> >
> > Link: http://netwinder.org/
> > Cc: Linus Walleij <linus.walleij at linaro.org>
> > Cc: Russell King <linux at armlinux.org.uk>
> > Cc: Ralph Siemsen <ralph.siemsen at linaro.org>
> > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> 
> I am booting it occasionally, last time to test my KCFI patches.
> But admittedly that is only to test it for other SA110 users. I remember
> that Christoph had problems consolidating the DMA used in this
> machine as well so it is standing in the way of useful work.
> 
> Apart from Ralph and me I know Marc Z has been known to boot
> this machine, so paging him as well.

I won't be crying. It's probably been a couple of years since I last
switched it on, and it is IMO ready to join the DEC Shark on the shelf
of "used to be great" HW.

FWIW,

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

	M.

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


From yassine.ouaissa at allegrodvt.com  Wed Dec  4 06:44:31 2024
From: yassine.ouaissa at allegrodvt.com (Yassine Ouaissa)
Date: Wed, 4 Dec 2024 14:44:31 +0000
Subject: [PATCH] media: allegro-dvt: Moving the current driver to
 subdirectory
In-Reply-To: <Z02SLI05JhNDtXFn@pengutronix.de>
References: <20241202102654.40472-1-yassine.ouaissa@allegrodvt.com>
 <Z02SLI05JhNDtXFn@pengutronix.de>
Message-ID: <abshbp4blqxasxvf4ibumtfqcr7hytehmhzs2yag3nfpbcl47x@ndjg7al4iysk>

Hi Michael,

Thank you for the feedback.

On 02.12.2024 11:55, Michael Tretter wrote:
>Hi Yassine,
>
>On Mon, 02 Dec 2024 11:26:38 +0100, Yassine Ouaissa wrote:
>What kind of conflicts do you encounter or expect? It's kind of
>surprising that your driver would conflict with anything in the existing
>driver.

The current "NOT allegro" driver support only the ZynqMP (ex : ZCU106/ZCU104 ).
And the upcoming driver, has support for many platforms.

>I'd like to see how you plan to integrate your driver, what it looks
>like and what conflicts with the existing driver actually occur. Without
>that information I don't see the point in moving the driver to a
>sub-directory.

The upcoming driver is not using the parsing, conversion inside of the
driver. Actually the new Gen of ALLEGRO IP does that.
>
>Michael
>
>>
>> Signed-off-by: Yassine Ouaissa <yassine.ouaissa at allegrodvt.com>
>> ---
>>  MAINTAINERS                                               | 2 +-
>>  drivers/media/platform/allegro-dvt/Kconfig                | 4 ++--
>>  drivers/media/platform/allegro-dvt/Makefile               | 8 ++------
>>  drivers/media/platform/allegro-dvt/zynqmp/Makefile        | 6 ++++++
>>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c    | 0
>>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h    | 0
>>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c    | 0
>>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h    | 0
>>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c    | 0
>>  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h    | 0
>>  .../{allegro-core.c => zynqmp/zynqmp-allegro-core.c}      | 2 +-
>>  .../{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c}      | 2 +-
>>  .../{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h}      | 0
>>  13 files changed, 13 insertions(+), 11 deletions(-)
>>  create mode 100644 drivers/media/platform/allegro-dvt/zynqmp/Makefile
>>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c (100%)
>>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h (100%)
>>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c (100%)
>>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h (100%)
>>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c (100%)
>>  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h (100%)
>>  rename drivers/media/platform/allegro-dvt/{allegro-core.c => zynqmp/zynqmp-allegro-core.c} (99%)
>>  rename drivers/media/platform/allegro-dvt/{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c} (99%)
>>  rename drivers/media/platform/allegro-dvt/{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h} (100%)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 7292e4a1ddb8..d79efe6f8992 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -795,7 +795,7 @@ R:	Pengutronix Kernel Team <kernel at pengutronix.de>
>>  L:	linux-media at vger.kernel.org
>>  S:	Maintained
>>  F:	Documentation/devicetree/bindings/media/allegro,al5e.yaml
>> -F:	drivers/media/platform/allegro-dvt/
>> +F:	drivers/media/platform/allegro-dvt/zynqmp
>>
>>  ALLIED VISION ALVIUM CAMERA DRIVER
>>  M:	Tommaso Merciai <tomm.merciai at gmail.com>
>> diff --git a/drivers/media/platform/allegro-dvt/Kconfig b/drivers/media/platform/allegro-dvt/Kconfig
>> index 2182e1277568..9bc7e99788b8 100644
>> --- a/drivers/media/platform/allegro-dvt/Kconfig
>> +++ b/drivers/media/platform/allegro-dvt/Kconfig
>> @@ -2,8 +2,8 @@
>>
>>  comment "Allegro DVT media platform drivers"
>>
>> -config VIDEO_ALLEGRO_DVT
>> -	tristate "Allegro DVT Video IP Core"
>> +config VIDEO_ZYNQMP_ALLEGRO_DVT
>> +	tristate "Allegro DVT Video IP Core for ZynqMP"
>>  	depends on V4L_MEM2MEM_DRIVERS
>>  	depends on VIDEO_DEV
>>  	depends on ARCH_ZYNQMP || COMPILE_TEST
>> diff --git a/drivers/media/platform/allegro-dvt/Makefile b/drivers/media/platform/allegro-dvt/Makefile
>> index 66108a303774..04727c5f7ef4 100644
>> --- a/drivers/media/platform/allegro-dvt/Makefile
>> +++ b/drivers/media/platform/allegro-dvt/Makefile
>> @@ -1,6 +1,2 @@
>> -# SPDX-License-Identifier: GPL-2.0
>> -
>> -allegro-objs := allegro-core.o allegro-mail.o
>> -allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
>> -
>> -obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +obj-y += zynqmp/
>> diff --git a/drivers/media/platform/allegro-dvt/zynqmp/Makefile b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
>> new file mode 100644
>> index 000000000000..a8ddb9cf93a8
>> --- /dev/null
>> +++ b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
>> @@ -0,0 +1,6 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +
>> +zynqmp-allegro-objs := zynqmp-allegro-core.o zynqmp-allegro-mail.o
>> +zynqmp-allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
>> +
>> +obj-$(CONFIG_VIDEO_ZYNQMP_ALLEGRO_DVT) += zynqmp-allegro.o
>> diff --git a/drivers/media/platform/allegro-dvt/nal-h264.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
>> similarity index 100%
>> rename from drivers/media/platform/allegro-dvt/nal-h264.c
>> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
>> diff --git a/drivers/media/platform/allegro-dvt/nal-h264.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
>> similarity index 100%
>> rename from drivers/media/platform/allegro-dvt/nal-h264.h
>> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
>> diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
>> similarity index 100%
>> rename from drivers/media/platform/allegro-dvt/nal-hevc.c
>> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
>> diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
>> similarity index 100%
>> rename from drivers/media/platform/allegro-dvt/nal-hevc.h
>> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
>> diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
>> similarity index 100%
>> rename from drivers/media/platform/allegro-dvt/nal-rbsp.c
>> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
>> diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
>> similarity index 100%
>> rename from drivers/media/platform/allegro-dvt/nal-rbsp.h
>> rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
>> diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
>> similarity index 99%
>> rename from drivers/media/platform/allegro-dvt/allegro-core.c
>> rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
>> index e491399afcc9..8895d7755987 100644
>> --- a/drivers/media/platform/allegro-dvt/allegro-core.c
>> +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
>> @@ -31,7 +31,7 @@
>>  #include <media/videobuf2-dma-contig.h>
>>  #include <media/videobuf2-v4l2.h>
>>
>> -#include "allegro-mail.h"
>> +#include "zynqmp-allegro-mail.h"
>>  #include "nal-h264.h"
>>  #include "nal-hevc.h"
>>
>> diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
>> similarity index 99%
>> rename from drivers/media/platform/allegro-dvt/allegro-mail.c
>> rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
>> index aadc947a77ae..88a98f9e5d00 100644
>> --- a/drivers/media/platform/allegro-dvt/allegro-mail.c
>> +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
>> @@ -12,7 +12,7 @@
>>  #include <linux/string.h>
>>  #include <linux/videodev2.h>
>>
>> -#include "allegro-mail.h"
>> +#include "zynqmp-allegro-mail.h"
>>
>>  const char *msg_type_name(enum mcu_msg_type type)
>>  {
>> diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.h b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
>> similarity index 100%
>> rename from drivers/media/platform/allegro-dvt/allegro-mail.h
>> rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
>> --
>> 2.30.2
>>
>>
>
>-- 
>Pengutronix e.K.                           | Michael Tretter             |
>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 robh at kernel.org  Wed Dec  4 06:43:41 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 4 Dec 2024 08:43:41 -0600
Subject: [PATCH v5 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241202110045.22084-4-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-4-linux@fw-web.de>
Message-ID: <20241204144341.GA191772-robh@kernel.org>

On Mon, Dec 02, 2024 at 12:00:37PM +0100, Frank Wunderlich wrote:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> This adds bindings for MT7988 pinctrl driver.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
> changes in v5 (so not adding RB from Rob given in v4):
> - do not use MTK_DRIVE_8mA in example
> - add _0 functions for pwm

Minor enough to keep my R-by, but if I review it again I can always find 
more. :)

> 
> changes in v4:
> - dt-binding: pinctrl: fix dt_binding_check fixed-string error
> 
> '^mux$' should not be valid under {'pattern': '^\\^[a-zA-Z0-9,\\-._#@]+\\$$'}
> 	hint: Fixed strings belong in 'properties', not 'patternProperties'
> 
> changes in v3:
> - limit conf subnode name with optional suffix like mmc on mt7986
> - match mux subnode without wildcards
> 
> changes in v2:
> - drop gpio-cells description
> - move ref in mux subnode up
> - order uart-functions alphanumeric and fix typo
> ---
>  .../pinctrl/mediatek,mt7988-pinctrl.yaml      | 578 ++++++++++++++++++
>  1 file changed, 578 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
> new file mode 100644
> index 000000000000..dd5584557135
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
> @@ -0,0 +1,578 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7988-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek MT7988 Pin Controller
> +
> +maintainers:
> +  - Sean Wang <sean.wang at kernel.org>
> +
> +description:
> +  The MediaTek's MT7988 Pin controller is used to control SoC pins.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt7988-pinctrl
> +
> +  reg:
> +    minItems: 7
> +    maxItems: 7
> +
> +  reg-names:
> +    items:
> +      - const: gpio
> +      - const: iocfg_tr
> +      - const: iocfg_br
> +      - const: iocfg_rb
> +      - const: iocfg_lb
> +      - const: iocfg_tl
> +      - const: eint
> +
> +  gpio-controller: true
> +
> +  "#gpio-cells":
> +    const: 2
> +
> +  gpio-ranges:
> +    minItems: 1
> +    maxItems: 5
> +    description:
> +      GPIO valid number range.
> +
> +  interrupt-controller: true
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  "#interrupt-cells":
> +    const: 2
> +
> +allOf:
> +  - $ref: pinctrl.yaml#
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - gpio-controller
> +  - "#gpio-cells"
> +
> +patternProperties:
> +  '-pins$':
> +    type: object
> +    additionalProperties: false
> +
> +    properties:
> +      'mux':

Drop quotes.


> +        type: object
> +        additionalProperties: false
> +        $ref: /schemas/pinctrl/pinmux-node.yaml
> +        description: |
> +          pinmux configuration nodes.
> +
> +          The following table shows the effective values of "group", "function"
> +          properties and chip pinout pins
> +
> +          groups               function           pins (in pin#)
> +          ---------------------------------------------------------------------
> +          "tops_jtag0_0"       "jtag"             0, 1, 2, 3, 4
> +          "wo0_jtag"           "jtag"             50, 51, 52, 53, 54
> +          "wo1_jtag"           "jtag"             50, 51, 52, 53, 54
> +          "wo2_jtag"           "jtag"             50, 51, 52, 53, 54
> +          "jtag"               "jtag"             58, 59, 60, 61, 62
> +          "tops_jtag0_1"       "jtag"             58, 59, 60, 61, 62
> +          "int_usxgmii"        "int_usxgmii"      2, 3
> +          "pwm0"               "pwm"              57
> +          "pwm1"               "pwm"              21
> +          "pwm2"               "pwm"              80
> +          "pwm2_0"             "pwm"              58
> +          "pwm3"               "pwm"              81
> +          "pwm3_0"             "pwm"              59
> +          "pwm4"               "pwm"              82
> +          "pwm4_0"             "pwm"              60
> +          "pwm5"               "pwm"              83
> +          "pwm5_0"             "pwm"              61
> +          "pwm6"               "pwm"              69
> +          "pwm6_0"             "pwm"              62
> +          "pwm7"               "pwm"              70
> +          "pwm7_0"             "pwm"              4
> +          "dfd"                "dfd"              0, 1, 2, 3, 4
> +          "xfi_phy0_i2c0"      "i2c"              0, 1
> +          "xfi_phy1_i2c0"      "i2c"              0, 1
> +          "xfi_phy_pll_i2c0"   "i2c"              3, 4
> +          "xfi_phy_pll_i2c1"   "i2c"              3, 4
> +          "i2c0_0"             "i2c"              5, 6
> +          "i2c1_sfp"           "i2c"              5, 6
> +          "xfi_pextp_phy0_i2c" "i2c"              5, 6
> +          "xfi_pextp_phy1_i2c" "i2c"              5, 6
> +          "i2c0_1"             "i2c"              15, 16
> +          "u30_phy_i2c0"       "i2c"              15, 16
> +          "u32_phy_i2c0"       "i2c"              15, 16
> +          "xfi_phy0_i2c1"      "i2c"              15, 16
> +          "xfi_phy1_i2c1"      "i2c"              15, 16
> +          "xfi_phy_pll_i2c2"   "i2c"              15, 16
> +          "i2c1_0"             "i2c"              17, 18
> +          "u30_phy_i2c1"       "i2c"              17, 18
> +          "u32_phy_i2c1"       "i2c"              17, 18
> +          "xfi_phy_pll_i2c3"   "i2c"              17, 18
> +          "sgmii0_i2c"         "i2c"              17, 18
> +          "sgmii1_i2c"         "i2c"              17, 18
> +          "i2c1_2"             "i2c"              69, 70
> +          "i2c2_0"             "i2c"              69, 70
> +          "i2c2_1"             "i2c"              71, 72
> +          "mdc_mdio0"          "eth"              5, 6
> +          "2p5g_ext_mdio"      "eth"              28, 29
> +          "gbe_ext_mdio"       "eth"              30, 31
> +          "mdc_mdio1"          "eth"              69, 70
> +          "pcie_wake_n0_0"     "pcie"             7
> +          "pcie_clk_req_n0_0"  "pcie"             8
> +          "pcie_wake_n3_0"     "pcie"             9
> +          "pcie_clk_req_n3"    "pcie"             10
> +          "pcie_clk_req_n0_1"  "pcie"             10
> +          "pcie_p0_phy_i2c"    "pcie"             7, 8
> +          "pcie_p1_phy_i2c"    "pcie"             7, 8
> +          "pcie_p3_phy_i2c"    "pcie"             9, 10
> +          "pcie_p2_phy_i2c"    "pcie"             7, 8
> +          "ckm_phy_i2c"        "pcie"             9, 10
> +          "pcie_wake_n0_1"     "pcie"             13
> +          "pcie_wake_n3_1"     "pcie"             14
> +          "pcie_2l_0_pereset"  "pcie"             19
> +          "pcie_1l_1_pereset"  "pcie"             20
> +          "pcie_clk_req_n2_1"  "pcie"             63
> +          "pcie_2l_1_pereset"  "pcie"             73
> +          "pcie_1l_0_pereset"  "pcie"             74
> +          "pcie_wake_n1_0"     "pcie"             75
> +          "pcie_clk_req_n1"    "pcie"             76
> +          "pcie_wake_n2_0"     "pcie"             77
> +          "pcie_clk_req_n2_0"  "pcie"             78
> +          "pcie_wake_n2_1"     "pcie"             79
> +          "pmic"               "pmic"             11
> +          "watchdog"           "watchdog"         12
> +          "spi0_wp_hold"       "spi"              22, 23
> +          "spi0"               "spi"              24, 25, 26, 27
> +          "spi1"               "spi"              28, 29, 30, 31
> +          "spi2"               "spi"              32, 33, 34, 35
> +          "spi2_wp_hold"       "spi"              36, 37
> +          "snfi"               "flash"            22, 23, 24, 25, 26, 27
> +          "emmc_45"            "flash"            21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
> +          "sdcard"             "flash"            32, 33, 34, 35, 36, 37
> +          "emmc_51"            "flash"            38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49
> +          "uart2"              "uart"             0, 1, 2, 3
> +          "tops_uart0_0"       "uart"             22, 23
> +          "uart2_0"            "uart"             28, 29, 30, 31
> +          "uart1_0"            "uart"             32, 33, 34, 35
> +          "uart2_1"            "uart"             32, 33, 34, 35
> +          "net_wo0_uart_txd_0" "uart"             28
> +          "net_wo1_uart_txd_0" "uart"             29
> +          "net_wo2_uart_txd_0" "uart"             30
> +          "tops_uart1_0"       "uart"             28, 29
> +          "tops_uart0_1"       "uart"             30, 31
> +          "tops_uart1_1"       "uart"             36, 37
> +          "uart0"              "uart"             55, 56
> +          "tops_uart0_2"       "uart"             55, 56
> +          "uart2_2"            "uart"             50, 51, 52, 53
> +          "uart1_1"            "uart"             58, 59, 60, 61
> +          "uart2_3"            "uart"             58, 59, 60, 61
> +          "uart1_2"            "uart"             80, 81, 82, 83
> +          "uart1_2_lite"       "uart"             80, 81
> +          "tops_uart1_2"       "uart"             80, 81
> +          "net_wo0_uart_txd_1" "uart"             80
> +          "net_wo1_uart_txd_1" "uart"             81
> +          "net_wo2_uart_txd_1" "uart"             82
> +          "udi"                "udi"              32, 33, 34, 35, 36
> +          "i2s"                "audio"            50, 51, 52, 53, 54
> +          "pcm"                "audio"            50, 51, 52, 53
> +          "gbe0_led1"          "led"              58
> +          "gbe1_led1"          "led"              59
> +          "gbe2_led1"          "led"              60
> +          "gbe3_led1"          "led"              61
> +          "2p5gbe_led1"        "led"              62
> +          "gbe0_led0"          "led"              64
> +          "gbe1_led0"          "led"              65
> +          "gbe2_led0"          "led"              66
> +          "gbe3_led0"          "led"              67
> +          "2p5gbe_led0"        "led"              68
> +          "drv_vbus_p1"        "usb"              63
> +          "drv_vbus"           "usb"              79
> +
> +        properties:
> +          function:
> +            description:
> +              A string containing the name of the function to mux to the group.
> +            enum: [audio, dfd, eth, flash, i2c, int_usxgmii, jtag, led, pcie, pmic, pwm, spi,
> +                   uart, udi, usb, watchdog]
> +          groups:
> +            description:
> +              An array of strings. Each string contains the name of a group.

blank line

> +        required:
> +          - function
> +          - groups
> +
> +        allOf:
> +          - if:
> +              properties:
> +                function:
> +                  const: audio
> +            then:
> +              properties:
> +                groups:
> +                  enum: [i2s, pcm]
> +          - if:
> +              properties:
> +                function:
> +                  const: jtag
> +            then:
> +              properties:
> +                groups:
> +                  enum: [jtag, tops_jtag0_0, tops_jtag0_1, wo0_jtag, wo1_jtag, wo2_jtag]
> +          - if:
> +              properties:
> +                function:
> +                  const: int_usxgmii
> +            then:
> +              properties:
> +                groups:
> +                  enum: [int_usxgmii]

Use const if only 1. Elsewhere too.

> +          - if:
> +              properties:
> +                function:
> +                  const: dfd
> +            then:
> +              properties:
> +                groups:
> +                  enum: [dfd]
> +          - if:
> +              properties:
> +                function:
> +                  const: flash
> +            then:
> +              properties:
> +                groups:
> +                  enum: [emmc_45, emmc_51, sdcard, snfi]
> +          - if:
> +              properties:
> +                function:
> +                  const: eth
> +            then:
> +              properties:
> +                groups:
> +                  enum: [2p5g_ext_mdio, gbe_ext_mdio, mdc_mdio0, mdc_mdio1]
> +          - if:
> +              properties:
> +                function:
> +                  const: i2c
> +            then:
> +              properties:
> +                groups:
> +                  enum: [xfi_phy0_i2c0, xfi_phy1_i2c0, xfi_phy_pll_i2c0,
> +                         xfi_phy_pll_i2c1, i2c0_0, i2c1_sfp, xfi_pextp_phy0_i2c,
> +                         xfi_pextp_phy1_i2c, i2c0_1, u30_phy_i2c0, u32_phy_i2c0,
> +                         xfi_phy0_i2c1, xfi_phy1_i2c1, xfi_phy_pll_i2c2, i2c1_0,
> +                         u30_phy_i2c1, u32_phy_i2c1, xfi_phy_pll_i2c3, sgmii0_i2c,
> +                         sgmii1_i2c, i2c1_2, i2c2_0, i2c2_1]
> +          - if:
> +              properties:
> +                function:
> +                  const: led
> +            then:
> +              properties:
> +                groups:
> +                  enum: [2p5gbe_led0, 2p5gbe_led1, gbe0_led0, gbe0_led1, gbe1_led0, gbe1_led1,
> +                         gbe2_led0, gbe2_led1, gbe3_led0, gbe3_led1, wf5g_led0, wf5g_led1]
> +          - if:
> +              properties:
> +                function:
> +                  const: pcie
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [pcie_wake_n0_0, pcie_clk_req_n0_0, pcie_wake_n3_0,
> +                           pcie_clk_req_n3, pcie_p0_phy_i2c, pcie_p1_phy_i2c,
> +                           pcie_p3_phy_i2c, pcie_p2_phy_i2c, ckm_phy_i2c,
> +                           pcie_wake_n0_1, pcie_wake_n3_1, pcie_2l_0_pereset,
> +                           pcie_1l_1_pereset, pcie_clk_req_n2_1, pcie_2l_1_pereset,
> +                           pcie_1l_0_pereset, pcie_wake_n1_0, pcie_clk_req_n1,
> +                           pcie_wake_n2_0, pcie_clk_req_n2_0, pcie_wake_n2_1,
> +                           pcie_clk_req_n0_1]
> +                  maxItems: 3
> +          - if:
> +              properties:
> +                function:
> +                  const: pmic
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [pmic]
> +                  maxItems: 1

This can be just:

groups:
  const: pmic

A few other places too.

Rob


From angelogioacchino.delregno at collabora.com  Wed Dec  4 06:44:48 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 4 Dec 2024 15:44:48 +0100
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <559ac08df6614e47c3e8d9d8160b35c9e683c503.camel@mediatek.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
 <559ac08df6614e47c3e8d9d8160b35c9e683c503.camel@mediatek.com>
Message-ID: <716b8630-66ef-4497-8cba-d5d20da2382a@collabora.com>

Il 02/12/24 08:27, CK Hu (???) ha scritto:
> Hi, Angelo:
> 
> On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>
>>
>> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
>> found in MediaTek's MT8195, MT8188 SoC and their variants, and
>> including support for display modes up to 4k60 and for HDMI
>> Audio, as per the HDMI 2.0 spec.
>>
>> HDCP and CEC functionalities are also supported by this hardware,
>> but are not included in this commit.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
> 
> [snip]
> 
>> +static int mtk_hdmi_v2_enable(struct mtk_hdmi *hdmi)
>> +{
>> +       int ret;
>> +
>> +       ret = pm_runtime_resume_and_get(hdmi->dev);
> 
> Why turn on power when attach?
> Should hot-plug detection be always on so power on when attach?
> If so, maybe we need to use CEC to detect hot-plug because CEC has lower power and HDMI power would not be always on.
> As you describe previously, CEC just need some hack to support both HDMI Tx and HDMI Rx.
> So there is a software solution to use CEC to detect hot-plug in a lower power mode.
> And v1 use CEC to detect hot-plug, so it's worth to make v1 and v2 has the same behavior.
> 

As I said, we can't use CEC to detect hotplug, because the same CEC controller
can be used for both HDMI TX and RX at the same time.

If you use CEC to detect cable attach and you have both HDMI RX and HDMI TX drivers
probed and ready, if you attach the cable to HDMI RX port, HDMI TX will try to get
enabled and will error out.
Same happens if you attach a cable to HDMI TX: HDMI RX will try to get enabled and
will error out.

The only way to use CEC for hotplug detection is to detect twice: CEC for HDMI
TX/RX controllers wakeup, then reset both, wait for autodetect in both controllers,
suppress errors, and start signal transmit or receive.

While it is technically possible to do so, it's very complicated and hacky.

Please keep in mind that on the new SoCs (8188/8195) the CEC block is different
from the one in the old SoCs (6795, 8173, etc) and requires an entirely new driver
to get it working.

Using CEC for hotplug detection would mean that we need 3 full drivers:
1. HDMI TX
2. HDMI RX
3. CEC

This is because the CEC is shared, so we need to have all three to properly test
the functionality - and this is not possible to do all at once.

To save some power (not much, though!), we can eventually go for your proposed
CEC detection *in the future*, but really not right now - and we can do that only
after upstreaming both HDMI TX and HDMI RX drivers.

The plan (time/effort pemitting!) would look like this:

Series 1 - Upstream HDMIv2 TX (HPD through HDMIv2 TX controller) - drivers/gpu/drm
Series 2 - Upstream HDMIv2 RX (HPD through HDMIv2 RX controller) - drivers/media
Series 3 - Upstream CEC driver (No HPD in CEC)                   - drivers/media
Series 4 - Implement HPD in CEC and use it in HDMIv2 TX and HDMIv2 RX - media,drm

You can see how complicated this is - and I'm sure that you understand why that
cannot be done all at once.

Adding up some: the HDMI driver is used only on IoT boards for now, which typically
run off AC and not battery - so the (again) very little power consumption raise is
not critical for now.

Cheers,
Angelo

> Regards,
> CK
> 
> 
>> +       if (ret) {
>> +               dev_err(hdmi->dev, "Cannot resume HDMI\n");
>> +               return ret;
>> +       }
>> +
>> +       mtk_hdmi_v2_clk_enable(hdmi);
>> +       mtk_hdmi_hw_reset(hdmi);
>> +       mtk_hdmi_set_sw_hpd(hdmi, true);
>> +
>> +       return 0;
>> +}
>> +
> 


From lkp at intel.com  Wed Dec  4 06:48:53 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 4 Dec 2024 22:48:53 +0800
Subject: [PATCH v4 1/2] input: keypad: add new keypad driver for MA35D1
In-Reply-To: <20241204021014.5083-2-mjchen0829@gmail.com>
References: <20241204021014.5083-2-mjchen0829@gmail.com>
Message-ID: <202412042245.5jwzbfGS-lkp@intel.com>

Hi Ming-Jen,

kernel test robot noticed the following build errors:

[auto build test ERROR on dtor-input/next]
[also build test ERROR on dtor-input/for-linus hid/for-next soc/for-next linus/master v6.13-rc1 next-20241203]
[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/Ming-Jen-Chen/input-keypad-add-new-keypad-driver-for-MA35D1/20241204-123001
base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
patch link:    https://lore.kernel.org/r/20241204021014.5083-2-mjchen0829%40gmail.com
patch subject: [PATCH v4 1/2] input: keypad: add new keypad driver for MA35D1
config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20241204/202412042245.5jwzbfGS-lkp at intel.com/config)
compiler: s390-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241204/202412042245.5jwzbfGS-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/202412042245.5jwzbfGS-lkp at intel.com/

All errors (new ones prefixed by >>):

   drivers/input/keyboard/ma35d1_keypad.c: In function 'ma35d1_keypad_scan_matrix':
   drivers/input/keyboard/ma35d1_keypad.c:83:24: error: implicit declaration of function 'readl' [-Wimplicit-function-declaration]
      83 |         key_event[0] = readl(keypad->mmio_base + KPI_KPE0);
         |                        ^~~~~
>> drivers/input/keyboard/ma35d1_keypad.c:89:9: error: implicit declaration of function 'writel' [-Wimplicit-function-declaration]
      89 |         writel(key_event[0], (keypad->mmio_base + KPI_KPE0));
         |         ^~~~~~


vim +/writel +89 drivers/input/keyboard/ma35d1_keypad.c

    72	
    73	static void ma35d1_keypad_scan_matrix(struct ma35d1_keypad *keypad, unsigned int status)
    74	{
    75		struct input_dev *input_dev = keypad->input_dev;
    76		u32 row_shift = get_count_order(keypad->kpi_col);
    77		u32 *keymap = input_dev->keycode;
    78		u32 code, key, index;
    79		u32 key_event[4];
    80		u64 pressed_keys = 0, released_keys = 0;
    81	
    82		/* Read key event status */
    83		key_event[0] = readl(keypad->mmio_base + KPI_KPE0);
    84		key_event[1] = readl(keypad->mmio_base + KPI_KPE1);
    85		key_event[2] = readl(keypad->mmio_base + KPI_KRE0);
    86		key_event[3] = readl(keypad->mmio_base + KPI_KRE1);
    87	
    88		/* Clear key event status */
  > 89		writel(key_event[0], (keypad->mmio_base + KPI_KPE0));
    90		writel(key_event[1], (keypad->mmio_base + KPI_KPE1));
    91		writel(key_event[2], (keypad->mmio_base + KPI_KRE0));
    92		writel(key_event[3], (keypad->mmio_base + KPI_KRE1));
    93	
    94		pressed_keys  = key_event[0] | ((u64)key_event[1] << 32);
    95		released_keys = key_event[2] | ((u64)key_event[3] << 32);
    96	
    97		/* Process pressed keys */
    98		for_each_set_bit(index, (const unsigned long *)&pressed_keys, KEY_EVENT_BITS) {
    99			code = MATRIX_SCAN_CODE(index / 8, (index % 8), row_shift);
   100			key = keymap[code];
   101	
   102			input_event(input_dev, EV_MSC, MSC_SCAN, code);
   103			input_report_key(input_dev, key, 1);
   104		}
   105	
   106		/* Process released keys */
   107		for_each_set_bit(index, (const unsigned long *)&released_keys, KEY_EVENT_BITS) {
   108			code = MATRIX_SCAN_CODE(index / 8, (index % 8), row_shift);
   109			key = keymap[code];
   110	
   111			input_event(input_dev, EV_MSC, MSC_SCAN, code);
   112			input_report_key(input_dev, key, 0);
   113		}
   114	
   115		input_sync(input_dev);
   116	}
   117	

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


From ralph.siemsen at linaro.org  Wed Dec  4 06:50:57 2024
From: ralph.siemsen at linaro.org (Ralph Siemsen)
Date: Wed, 4 Dec 2024 09:50:57 -0500
Subject: [PATCH 02/15] ARM: limit OABI support to StrongARM CPUs
In-Reply-To: <CACRpkdY243J4C3A9_13eTN84T2SeOjyoh0bWk6U1mqffUd6urw@mail.gmail.com>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-3-arnd@kernel.org>
 <CACRpkdY243J4C3A9_13eTN84T2SeOjyoh0bWk6U1mqffUd6urw@mail.gmail.com>
Message-ID: <CANp-EDb27XE0SMpDFUKm-L3j=rZhugbK20cQZGtAmP5D0r2C6w@mail.gmail.com>

On Wed, Dec 4, 2024 at 8:59?AM Linus Walleij <linus.walleij at linaro.org> wrote:

> Hm why do we need a separate netwinder_defconfig if this defconfig already
> supports it?

AFAIK footbridge_defconfig is for the "Compaq Personal Server", which
is different than NetWinder. They could probably be reconciled by
using devicetree and converting any platform devices. However testing
could be a challenge, not sure who has working hardware anymore.

> I am occasionally booting the NetWinder and then I use this defconfig,
> the netwinder_defconfig wasn't even working for me.

Interesting. I successfully used netwinder_defconfig a few years ago.

I have several times thought about updating the netwinder, starting
with a more modern bootloader (I got u-boot working at one point), so
we no longer need ATAGS. However toolchain support is problematic
("bx" hack anyone?) and there are so many cheaper faster boards (RPi
for example) which require much less effort.

Regards
-Ralph


From maz at kernel.org  Wed Dec  4 07:01:43 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 15:01:43 +0000
Subject: [PATCH 0/2] PCI: Convert the Apple controller to host bridge hooks
Message-ID: <20241204150145.800408-1-maz@kernel.org>

The Apple PCIe controller requires some additional attention when
enabling an endpoint device, so that the RID gets correctly mapped to
a SID on its way to the IOMMU.

So far, we have need relying on a custom bus notifier to perform this
task, but Frank Li's series [1] is a better approach as it puts the
complexity in the core code instead of the host controller driver, and
this series builds on that:

- allow the new {en,dis}able_device() to be provided via pci_ecam_ops

- convert the Apple PCIe driver to that infrastructure

Patches on top of 6.13-rc1, plus Frank's v7 series.

[1] https://lore.kernel.org/r/20241203-imx95_lut-v7-0-d0cd6293225e at nxp.com

Marc Zyngier (2):
  PCI: host-generic: Allow {en,dis}able_device() to be provided via
    pci_ecam_ops
  PCI: apple: Convert to {en,dis}able_device() callbacks

 drivers/pci/controller/pci-host-common.c |  2 +
 drivers/pci/controller/pcie-apple.c      | 75 +++++-------------------
 include/linux/pci-ecam.h                 |  4 ++
 3 files changed, 21 insertions(+), 60 deletions(-)

-- 
2.39.2



From maz at kernel.org  Wed Dec  4 07:01:45 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 15:01:45 +0000
Subject: [PATCH 2/2] PCI: apple: Convert to {en,dis}able_device() callbacks
In-Reply-To: <20241204150145.800408-1-maz@kernel.org>
References: <20241204150145.800408-1-maz@kernel.org>
Message-ID: <20241204150145.800408-3-maz@kernel.org>

Now that the core host-bridge infrastructure is able to give
us a callback on each device being added or removed, convert
the bus-notifier hack to it.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/pci/controller/pcie-apple.c | 75 ++++++-----------------------
 1 file changed, 15 insertions(+), 60 deletions(-)

diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
index fefab2758a064..a7e51bc1c2fe8 100644
--- a/drivers/pci/controller/pcie-apple.c
+++ b/drivers/pci/controller/pcie-apple.c
@@ -26,7 +26,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/msi.h>
-#include <linux/notifier.h>
 #include <linux/of_irq.h>
 #include <linux/pci-ecam.h>
 
@@ -667,12 +666,16 @@ static struct apple_pcie_port *apple_pcie_get_port(struct pci_dev *pdev)
 	return NULL;
 }
 
-static int apple_pcie_add_device(struct apple_pcie_port *port,
-				 struct pci_dev *pdev)
+static int apple_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
 {
 	u32 sid, rid = pci_dev_id(pdev);
+	struct apple_pcie_port *port;
 	int idx, err;
 
+	port = apple_pcie_get_port(pdev);
+	if (!port)
+		return 0;
+
 	dev_dbg(&pdev->dev, "added to bus %s, index %d\n",
 		pci_name(pdev->bus->self), port->idx);
 
@@ -698,12 +701,16 @@ static int apple_pcie_add_device(struct apple_pcie_port *port,
 	return idx >= 0 ? 0 : -ENOSPC;
 }
 
-static void apple_pcie_release_device(struct apple_pcie_port *port,
-				      struct pci_dev *pdev)
+static void apple_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
 {
+	struct apple_pcie_port *port;
 	u32 rid = pci_dev_id(pdev);
 	int idx;
 
+	port = apple_pcie_get_port(pdev);
+	if (!port)
+		return;
+
 	mutex_lock(&port->pcie->lock);
 
 	for_each_set_bit(idx, port->sid_map, port->sid_map_sz) {
@@ -721,45 +728,6 @@ static void apple_pcie_release_device(struct apple_pcie_port *port,
 	mutex_unlock(&port->pcie->lock);
 }
 
-static int apple_pcie_bus_notifier(struct notifier_block *nb,
-				   unsigned long action,
-				   void *data)
-{
-	struct device *dev = data;
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct apple_pcie_port *port;
-	int err;
-
-	/*
-	 * This is a bit ugly. We assume that if we get notified for
-	 * any PCI device, we must be in charge of it, and that there
-	 * is no other PCI controller in the whole system. It probably
-	 * holds for now, but who knows for how long?
-	 */
-	port = apple_pcie_get_port(pdev);
-	if (!port)
-		return NOTIFY_DONE;
-
-	switch (action) {
-	case BUS_NOTIFY_ADD_DEVICE:
-		err = apple_pcie_add_device(port, pdev);
-		if (err)
-			return notifier_from_errno(err);
-		break;
-	case BUS_NOTIFY_DEL_DEVICE:
-		apple_pcie_release_device(port, pdev);
-		break;
-	default:
-		return NOTIFY_DONE;
-	}
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block apple_pcie_nb = {
-	.notifier_call = apple_pcie_bus_notifier,
-};
-
 static int apple_pcie_init(struct pci_config_window *cfg)
 {
 	struct device *dev = cfg->parent;
@@ -799,23 +767,10 @@ static int apple_pcie_init(struct pci_config_window *cfg)
 	return 0;
 }
 
-static int apple_pcie_probe(struct platform_device *pdev)
-{
-	int ret;
-
-	ret = bus_register_notifier(&pci_bus_type, &apple_pcie_nb);
-	if (ret)
-		return ret;
-
-	ret = pci_host_common_probe(pdev);
-	if (ret)
-		bus_unregister_notifier(&pci_bus_type, &apple_pcie_nb);
-
-	return ret;
-}
-
 static const struct pci_ecam_ops apple_pcie_cfg_ecam_ops = {
 	.init		= apple_pcie_init,
+	.enable_device	= apple_pcie_enable_device,
+	.disable_device	= apple_pcie_disable_device,
 	.pci_ops	= {
 		.map_bus	= pci_ecam_map_bus,
 		.read		= pci_generic_config_read,
@@ -830,7 +785,7 @@ static const struct of_device_id apple_pcie_of_match[] = {
 MODULE_DEVICE_TABLE(of, apple_pcie_of_match);
 
 static struct platform_driver apple_pcie_driver = {
-	.probe	= apple_pcie_probe,
+	.probe	= pci_host_common_probe,
 	.driver	= {
 		.name			= "pcie-apple",
 		.of_match_table		= apple_pcie_of_match,
-- 
2.39.2



From igor.belwon at mentallysanemainliners.org  Wed Dec  4 06:55:58 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Wed,  4 Dec 2024 15:55:58 +0100
Subject: [PATCH v2 1/2] dt-bindings: soc: samsung: exynos-pmu: Add exynos990-pmu compatible
In-Reply-To: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>
References: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241204145559.524932-2-igor.belwon@mentallysanemainliners.org>

Add a dt-binding compatible for the Exynos990 PMU. It's compatible
with the Exynos7 PMU design. It handles system reboot, as well as
other system control registers (i.e registers for the USB PHY).

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
index 6cdfe7e059a3..8e6d051d8c97 100644
--- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
+++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
@@ -55,6 +55,7 @@ properties:
               - samsung,exynos7885-pmu
               - samsung,exynos8895-pmu
               - samsung,exynos9810-pmu
+              - samsung,exynos990-pmu
               - samsung,exynosautov9-pmu
               - samsung,exynosautov920-pmu
               - tesla,fsd-pmu
-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Wed Dec  4 06:55:57 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Wed,  4 Dec 2024 15:55:57 +0100
Subject: [PATCH v2 0/2] Add pmu and syscon-reboot support to Exynos990
Message-ID: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>

Hi all,

This small series adds support for the pmu, as well as syscon-reboot
support to the Exynos990 SoC. It has been tested with the reboot command
in an initramfs.

Typically, this would be added during the initial SoC bringup,
however I was unsure as to if the syscon would work correctly until I
could test it (especially when it comes to reboot), which I just got
around to doing.

---
Changes since v1:
- Wrote a description for the PMU in the dt-bindings commit (thanks Krzysztof!)

Kind regards,

Igor

Igor Belwon (2):
  dt-bindings: soc: samsung: exynos-pmu: Add exynos990-pmu compatible
  arm64: dts: exynos990: Add pmu and syscon-reboot nodes

 .../bindings/soc/samsung/exynos-pmu.yaml           |  1 +
 arch/arm64/boot/dts/exynos/exynos990.dtsi          | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Wed Dec  4 06:55:59 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Wed,  4 Dec 2024 15:55:59 +0100
Subject: [PATCH v2 2/2] arm64: dts: exynos990: Add pmu and syscon-reboot nodes
In-Reply-To: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>
References: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241204145559.524932-3-igor.belwon@mentallysanemainliners.org>

Add PMU syscon, and syscon-reboot nodes to the Exynos990 dtsi.

Reboot of the Exynos990 SoC is handled by setting bit(SWRESET_TRIGGER[1])
of SWRESET register (PMU + 0x3a00).

Tested using the "reboot" command.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/exynos990.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos990.dtsi b/arch/arm64/boot/dts/exynos/exynos990.dtsi
index c1986f00e443..2619f821bc7c 100644
--- a/arch/arm64/boot/dts/exynos/exynos990.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos990.dtsi
@@ -227,6 +227,20 @@ wakeup-interrupt-controller {
 			};
 		};
 
+		pmu_system_controller: system-controller at 15860000 {
+			compatible = "samsung,exynos990-pmu",
+				     "samsung,exynos7-pmu", "syscon";
+			reg = <0x15860000 0x10000>;
+
+			reboot: syscon-reboot {
+				compatible = "syscon-reboot";
+				regmap = <&pmu_system_controller>;
+				offset = <0x3a00>; /* SWRESET */
+				mask = <0x2>; /* SWRESET_TRIGGER */
+				value = <0x2>;
+			};
+		};
+
 		pinctrl_cmgp: pinctrl at 15c30000 {
 			compatible = "samsung,exynos990-pinctrl";
 			reg = <0x15c30000 0x1000>;
-- 
2.45.2



From robh at kernel.org  Wed Dec  4 07:00:04 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 4 Dec 2024 09:00:04 -0600
Subject: [PATCH v2 1/8] dt-bindings: phy: samsung,usb3-drd-phy: align to
 universal style
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-1-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
 <20241203-gs101-phy-lanes-orientation-phy-v2-1-40dcf1b7670d@linaro.org>
Message-ID: <20241204150004.GA217165-robh@kernel.org>

On Tue, Dec 03, 2024 at 12:13:49PM +0000, Andr? Draszik wrote:
> In [1], Rob pointed out that we should really be separating properties
> with blank lines in between, which is universal style. Only where
> properties are booleans, empty lines are not required.

In the subject, just say 'add blank lines between DT properties'. 
'universal style' could be anything.

> 
> Do so.
> 
> Link: https://lore.kernel.org/all/20240711212359.GA3023490-robh at kernel.org/ [1]
> Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> 
> ---
> v2:
> * collect tags
> ---
>  .../devicetree/bindings/phy/samsung,usb3-drd-phy.yaml     | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)

Acked-by: Rob Herring (Arm) <robh at kernel.org>


From linus.walleij at linaro.org  Wed Dec  4 06:59:56 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 15:59:56 +0100
Subject: [PATCH] arm: Remove IO memcpy for Big-Endian
In-Reply-To: <609b026d-d54c-4a11-b7df-6ef0ac315f25@app.fastmail.com>
References: <20241203083838.3260036-1-jvetter@outer-limits.org> <609b026d-d54c-4a11-b7df-6ef0ac315f25@app.fastmail.com>
Message-ID: <CACRpkdZZ0vrYT1-76SBa0XN00p33sRTmpT1JPLjvBuyGD_yu0Q@mail.gmail.com>

On Tue, Dec 3, 2024 at 11:08?AM Arnd Bergmann <arnd at arndb.de> wrote:

> - There is one ARMv5 "BE32" based platform, the ixp4xx, which
>   works differently, and this in turn allows multiple configurations
>   for its buses where a byte-swap is performed in the PCI
>   controller.

Actually it affects all memory-mapped I/O. E.g.
drivers/irqchip/irq-ixp4xx.c
for this reason IXP4xx drivers that are not PCI usually
use __raw_readl() and __raw_writel() to let the bus
do its thing.

IXP4xx PCI drivers are however *not* doing this, because
PCI is (IIUC) specified to be little-endian, and the hardware
deals with this. (Except for the PCI host driver itself, using
__raw accesses.)

> Before we apply your patch, I think the minimum would be to
> have Linus Walleij try it out on an an ixp4xx with a driver
> that uses these functions.

I applied the patch, compiled v6.13-rc1 HEAD for the
Linksys NSLU2 (oldest system there is! also a classic!)

+ Boots cleanly
+ Mounts root - this is on a USB drive which is on a
   PCI-attached USB controller, so PCI is tested
+ Reaches userspace and console
+ Gets network and IP address
+ LuCI web user inteface works (browsed to web server on device)
+ Dropbear SSH login works fine

Tested-by: Linus Walleij <linus.walleij at linaro.org>

I doubt any IXP4xx driver uses ioread/iowrite. The
MTD driver does not for example, because of other weirdness
with address swizzling (drivers/mtd/maps/physmap-ixp4xx.c)
For similar reasons drivers/ata/pata_ixp4xx_cf.c is
using readw/writew exclusively.

It also looks like a good idea:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Your,
Linus Walleij


From maz at kernel.org  Wed Dec  4 07:01:44 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Dec 2024 15:01:44 +0000
Subject: [PATCH 1/2] PCI: host-generic: Allow {en,dis}able_device() to be provided via pci_ecam_ops
In-Reply-To: <20241204150145.800408-1-maz@kernel.org>
References: <20241204150145.800408-1-maz@kernel.org>
Message-ID: <20241204150145.800408-2-maz@kernel.org>

In order to let host controller drivers using the host-generic
infrastructure use the {en,dis}able_device() callbacks that can
be used to configure sideband RID mapping hardware, provide these
two callbacks as part of the pci_ecap_ops structure.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/pci/controller/pci-host-common.c | 2 ++
 include/linux/pci-ecam.h                 | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index cf5f59a745b37..f441bfd6f96a8 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -75,6 +75,8 @@ int pci_host_common_probe(struct platform_device *pdev)
 
 	bridge->sysdata = cfg;
 	bridge->ops = (struct pci_ops *)&ops->pci_ops;
+	bridge->enable_device = ops->enable_device;
+	bridge->disable_device = ops->disable_device;
 	bridge->msi_domain = true;
 
 	return pci_host_probe(bridge);
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
index 3a4860bd27586..3a10f8cfc3ad5 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -45,6 +45,10 @@ struct pci_ecam_ops {
 	unsigned int			bus_shift;
 	struct pci_ops			pci_ops;
 	int				(*init)(struct pci_config_window *);
+	int				(*enable_device)(struct pci_host_bridge *,
+							 struct pci_dev *);
+	void				(*disable_device)(struct pci_host_bridge *,
+							  struct pci_dev *);
 };
 
 /*
-- 
2.39.2



From angelogioacchino.delregno at collabora.com  Wed Dec  4 07:01:57 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 4 Dec 2024 16:01:57 +0100
Subject: [PATCH v1 2/7] dt-bindings: display: mediatek: Add binding for
 MT8195 HDMI-TX v2
In-Reply-To: <4b1eb13d027717abaaaf4ee7aa927239ba314572.camel@mediatek.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
 <20241120124512.134278-3-angelogioacchino.delregno@collabora.com>
 <721896498fe9a5ba5a942fe837deb90d461b5090.camel@mediatek.com>
 <3d5f7106-6425-420c-abac-39feed11c95c@collabora.com>
 <4b1eb13d027717abaaaf4ee7aa927239ba314572.camel@mediatek.com>
Message-ID: <272b76ed-0ccc-46f2-8c43-92c047f2f0d3@collabora.com>

Il 29/11/24 03:51, CK Hu (???) ha scritto:
> On Thu, 2024-11-28 at 11:32 +0100, AngeloGioacchino Del Regno wrote:
>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>
>>
>> Il 28/11/24 07:02, CK Hu (???) ha scritto:
>>> Hi, Angelo:
>>>
>>> On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
>>>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>>>
>>>>
>>>> Add a binding for the HDMI TX v2 Encoder found in MediaTek MT8195
>>>> and MT8188 SoCs.
>>>>
>>>> This fully supports the HDMI Specification 2.0b, hence it provides
>>>> support for 3D-HDMI, Polarity inversion, up to 16 bits Deep Color,
>>>> color spaces including RGB444, YCBCR420/422/444 (ITU601/ITU709) and
>>>> xvYCC, with output resolutions up to 3840x2160p at 60Hz.
>>>>
>>>> Moreover, it also supports HDCP 1.4 and 2.3, Variable Refresh Rate
>>>> (VRR) and Consumer Electronics Control (CEC).
>>>>
>>>> This IP also includes support for HDMI Audio, including IEC60958
>>>> and IEC61937 SPDIF, 8-channel PCM, DSD, and other lossless audio
>>>> according to HDMI 2.0.
>>>>
>>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>>> ---
>>>>    .../mediatek/mediatek,mt8195-hdmi.yaml        | 150 ++++++++++++++++++
>>>>    1 file changed, 150 insertions(+)
>>>>    create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
>>>> new file mode 100644
>>>> index 000000000000..273a8871461e
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
>>>> @@ -0,0 +1,150 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: https://urldefense.com/v3/__http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml*__;Iw!!CTRNKA9wMg0ARbw!lu0D_C3TwQ2-02jWYABnMIQ8vEoUwP0O4gbQndJnPUMpdi6wXdAHra9ivCfB7zoelDI7qsS20YdRlmP4bEKAABletXFX$
>>>> +$schema: https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!lu0D_C3TwQ2-02jWYABnMIQ8vEoUwP0O4gbQndJnPUMpdi6wXdAHra9ivCfB7zoelDI7qsS20YdRlmP4bEKAAFlnY-KY$
>>>> +
>>>> +title: MediaTek HDMI-TX v2 Encoder
>>>> +
>>>> +maintainers:
>>>> +  - AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>>> +  - CK Hu <ck.hu at mediatek.com>
>>>> +
>>>> +description: |
>>>> +  The MediaTek HDMI-TX v2 encoder can generate HDMI format data based on
>>>> +  the HDMI Specification 2.0b.
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    enum:
>>>> +      - mediatek,mt8188-hdmi-tx
>>>> +      - mediatek,mt8195-hdmi-tx
>>>> +
>>>> +  reg:
>>>> +    maxItems: 1
>>>> +
>>>> +  interrupts:
>>>> +    maxItems: 1
>>>> +
>>>> +  clocks:
>>>> +    items:
>>>> +      - description: HDMI APB clock
>>>> +      - description: HDCP top clock
>>>> +      - description: HDCP reference clock
>>>> +      - description: VPP HDMI Split clock
>>>
>>> I would like to know more about HDMI v2.
>>> Would you map each v2 clock to v1 clock?
>>> If one clock has no mapping, is it a new feature that v1 does not has?
>>>
>>
>> The HDMIv2 HW block seems to be almost completely different from the v1, and
>> it is also interconnected in a different way compared to MT8173 (the path goes
>> through VPP1, while the v1 is just direct to DPI/MMSYS).
>>
>> The v1 block had specific clocks for the audio (i2s, I believe) and for the SPDIF,
>> and I have no idea how v1 does HDCP, but I don't see any specific clock for that.
>>
>> The v2 block is clocked from the HDCP clock, the (apb) bus has its own clock, and
>> the video out needs the vpp split clock.
>>
>> It's just different, and we can't shove the v2 binding inside of the v1 one, but
>> even if we could, since the v2 block is *that much* different from v1, it'd be a
>> mistake to do so.
>>
>> Since the binding describes hardware, and since this v2 HW is *very* different
>> from v1, it needs a new binding document, that is true even if you find a way to
>> get the clocks to match (which is not possible, anyway).
> 

Hey. Sorry about the late reply, it's been quite busy days here :-)

> v2 indeed is very different from v1, so it's not necessary to merge binding document.
> I would like to have more information about the difference in binding document,
> so that we could clearly understand that v1 and v2 are so different.
> 

Sounds reasonable.

> I think pixel clock is important for HDMI hardware, but I do not see it in HDMI v2.
> It is better has some documentation about why pixel clock disappear in HDMI v2.

Right. I'll write it in the PHY description.

   phys:
     maxItems: 1
     description:
        The HDMI TX PHY, clocking TMDS and pixel to this controller

> 
> I've some 'WHY' about v2.
> Why no audio clock in v2?

It's clocked by the HDCP CGs...

> Audio control part is moved out of HDMI block?
> 
> For HDCP, maybe v1 driver has not implement it so forget to add it in binding document.
> So just skip the HDCP.

...and the controller needs HDCP clocks for register access, so these are
main clocks and cannot be skipped.

> 
> The four clock in v2 does not exist in v1, so what is the function of each one?
> If possible, ask MediaTek staff for more information.

I'll try to ask to shove more information in this binding, let's see.

Cheers,
Angelo

> 
> Regards,
> CK
> 
>>
>> Cheers,
>> Angelo
>>
>>> Regards,
>>> CK
>>>
>>>> +
>>>> +  clock-names:
>>>> +    items:
>>>> +      - const: bus
>>>> +      - const: hdcp
>>>> +      - const: hdcp24m
>>>> +      - const: hdmi-split
>>>> +
>>>>
>>>> --
>>>> 2.47.0
>>>>
>>
>>




From robh at kernel.org  Wed Dec  4 07:07:58 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 4 Dec 2024 09:07:58 -0600
Subject: [PATCH v2 2/8] dt-bindings: phy: samsung,usb3-drd-phy: gs101:
 require Type-C properties
In-Reply-To: <20241203-gs101-phy-lanes-orientation-phy-v2-2-40dcf1b7670d@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d@linaro.org>
 <20241203-gs101-phy-lanes-orientation-phy-v2-2-40dcf1b7670d@linaro.org>
Message-ID: <20241204150758.GA220712-robh@kernel.org>

On Tue, Dec 03, 2024 at 12:13:50PM +0000, Andr? Draszik wrote:
> orientation-switch is the standard declaration to inform the Type-C mux
> layer that a remote-endpoint is capable of processing orientation
> change messages.
> 
> The USB PHY on gs101 needs to be configured based on the orientation of
> the connector. For that the DTS needs a link between the phy's port and
> a TCPCi, and we'll need to inform the phy driver that it should handle
> the orientation (register a handler).
> 
> Update the schema to enforce that by requiring the orientation-switch
> and port properties on gs101 (only). We disallow orientation-switch on
> all other supported platforms, since other versions of this phy (or its
> system integration) don't currently support or even need it.
> 
> Even though this new required gs101 property is an ABI break, the
> intention for the driver is to behave as before if it's missing
> (meaning for gs101 it will work in SS mode in one orientation only).
> Other platforms are not affected.
> 
> Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> 
> ---
> v2:
> * squash original patches #2 and #3
> * actually disallow orientation-switch on !gs101 (not just optional) (Conor)
> * update commit message to clarify that the intention for the driver is
>   to work with old and new DTS (Conor)
> * collect tags
> ---
>  Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> index 1f8b35917b11..c1d16254aeec 100644
> --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> @@ -51,6 +51,9 @@ properties:
>    "#phy-cells":
>      const: 1
>  
> +  orientation-switch:
> +    $ref: /schemas/usb/usb-switch.yaml#/properties/orientation-switch

Generally, we don't reference things at a property level, but node 
level. You can just do:

  - if:
      properties:
        compatible:
          contains:
            const: google,gs101-usb31drd-phy
    then:
      $ref: /schemas/usb/usb-switch.yaml#


And switch additionalProperties with unevaluatedProperties.

Rob


From linus.walleij at linaro.org  Wed Dec  4 07:14:07 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Dec 2024 16:14:07 +0100
Subject: [PATCH 15/15] ARM: mark footbridge as deprecated
In-Reply-To: <Z1BpNQjWwxEKFbg0@shell.armlinux.org.uk>
References: <20241204102904.1863796-1-arnd@kernel.org> <20241204102904.1863796-16-arnd@kernel.org>
 <CACRpkdahQhj5u9ATghszi-N2OYhFbvHF_W_eAMDAU+vhmvdrJA@mail.gmail.com> <Z1BpNQjWwxEKFbg0@shell.armlinux.org.uk>
Message-ID: <CACRpkdY-uKYqAR2Sj_cG7dPAtXMFG0Ldka7U13qZSFr+w15WxQ@mail.gmail.com>

On Wed, Dec 4, 2024 at 3:37?PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:

> > I am booting it occasionally, last time to test my KCFI patches.
> > But admittedly that is only to test it for other SA110 users. I remember
> > that Christoph had problems consolidating the DMA used in this
> > machine as well so it is standing in the way of useful work.
>
> What problems with DMA? The fact that it uses an offset between
> physical and PCI bus space should be nothing that causes a problem
> for the kernel. As maintainer for Footbridge, I've heard nothing
> about there being any issue.

No issue other than testing and iterating the patches I think.

I was thinking of this patchset to do dma_direct_set_offset():
https://lore.kernel.org/linux-arm-kernel/20200917173229.3311382-3-hch at lst.de/

It seems to have stalled some years ago, but maybe there was
some other reason.

IIRC Christoph was onto me to test it on the NetWinder, but I
couldn't locate a good DMA capable device to test it with.
(Would be the soundblaster but then I needed some userspace...)

Yours,
Linus Walleij


From leo.yan at arm.com  Wed Dec  4 07:16:50 2024
From: leo.yan at arm.com (Leo Yan)
Date: Wed, 4 Dec 2024 15:16:50 +0000
Subject: [PATCH v2] coresight-etm4x: add isb() before reading the TRCSTATR
In-Reply-To: <20241204112332.3706137-1-quic_yuanfang@quicinc.com>
References: <20241204112332.3706137-1-quic_yuanfang@quicinc.com>
Message-ID: <20241204151650.GA1976757@e132581.arm.com>

Hi Yuanfang,

Recently I just acrossed this part, so some comments.

On Wed, Dec 04, 2024 at 07:23:32PM +0800, yuanfang zhang wrote:
> 
> From: Yuanfang Zhang <quic_yuanfang at quicinc.com>
> 
> As recommended by section 4.3.7 ("Synchronization when using system
> instructions to progrom the trace unit") of ARM IHI 0064H.b, the
> self-hosted trace analyzer must perform a Context synchronization
> event between writing to the TRCPRGCTLR and reading the TRCSTATR.
> 
> Fixes: ebddaad09e10 ("coresight: etm4x: Add missing single-shot control API to sysfs")
> Signed-off-by: Yuanfang Zhang <quic_yuanfang at quicinc.com>
> ---
> Change in V2:
> Added comments in the code.
>  drivers/hwtracing/coresight/coresight-etm4x-core.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 66d44a404ad0..decb3a87e27e 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -906,6 +906,13 @@ static void etm4_disable_hw(void *info)
>         tsb_csync();
>         etm4x_relaxed_write32(csa, control, TRCPRGCTLR);
> 
> +       /*
> +        * As recommended by section 4.3.7 ("Synchronization when using system
> +        * instructions to progrom the trace unit") of ARM IHI 0064H.b, the
> +        * self-hosted trace analyzer must perform a Context synchronization
> +        * event between writing to the TRCPRGCTLR and reading the TRCSTATR.
> +        */
> +       isb();

As described in the doc, the "isb" is only required for system
instructions case.  It is good to only apply the ISB on system
register case:

        if (!csa->io_mem)
                isb();

>         /* wait for TRCSTATR.PMSTABLE to go to '1' */
>         if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1))
>                 dev_err(etm_dev,

As mentioned in system register case: "Arm recommends that the
self-hosted trace analyzer always executes an ISB instruction after
programming the trace unit registers, to ensure that all updates are
committed to the trace unit before normal code execution resumes."

And for MMIO case:

"When the memory is marked as Device-nGnRE or stronger.
 ...
 - Poll TRCSTATR to ensure the previous write has completed.
 ? Execute an ISB operation."

Thus we need to add an ISB after polling.

        isb();

For consistent behaviour, a relevant thing is the dsb(sy) in
etm4_enable_hw().  I do not think the dsb(sy) is necessary, as the
driver uses the sequence "write TRCPRGCTLR + polling TRCSTATR" to
ensure the data has been populated to trace unit, the polling
operations somehow act as a read back.  And the ETM manual does not
mention the requirement for DSB when enabling trace unit.  Thus, we
should remove dsb(sy) (maybe use a separte patch).

Mike / Suzuki / James, please confirm if my conclusions are valid.

Thanks,
Leo


From robdclark at gmail.com  Wed Dec  4 07:21:10 2024
From: robdclark at gmail.com (Rob Clark)
Date: Wed, 4 Dec 2024 07:21:10 -0800
Subject: [PATCH RESEND v17 3/5] iommu/arm-smmu: add support for PRR bit setup
In-Reply-To: <d2d8d9e9-74b1-4b05-84a2-dcfa204e6e00@quicinc.com>
References: <20241114160721.1527934-1-quic_bibekkum@quicinc.com>
 <20241114160721.1527934-4-quic_bibekkum@quicinc.com> <CAF6AEGuwWsAkRyF-h5Aj3KzM7iksb12HsfJ5Ks+-P8hv60MWFg@mail.gmail.com>
 <9beca099-5cf3-42b5-b1f9-fb1551219b18@quicinc.com> <CAF6AEGvAOswFTpS5PHrgCsG_2-QN_Bi4YjZbPpV+r3x=9D2aUQ@mail.gmail.com>
 <d2d8d9e9-74b1-4b05-84a2-dcfa204e6e00@quicinc.com>
Message-ID: <CAF6AEGtBva41Fz0tS4gRwK21ZqzDH5yGrWLY6TMeS6u7OFfS0Q@mail.gmail.com>

On Wed, Dec 4, 2024 at 3:27?AM Bibek Kumar Patro
<quic_bibekkum at quicinc.com> wrote:
>
>
>
> On 11/22/2024 10:33 PM, Rob Clark wrote:
> > On Fri, Nov 22, 2024 at 8:19?AM Bibek Kumar Patro
> > <quic_bibekkum at quicinc.com> wrote:
> >>
> >>
> >>
> >> On 11/20/2024 10:47 PM, Rob Clark wrote:
> >>> On Thu, Nov 14, 2024 at 8:10?AM Bibek Kumar Patro
> >>> <quic_bibekkum at quicinc.com> wrote:
> >>>>
> >>>> Add an adreno-smmu-priv interface for drm/msm to call
> >>>> into arm-smmu-qcom and initiate the PRR bit setup or reset
> >>>> sequence as per request.
> >>>>
> >>>> This will be used by GPU to setup the PRR bit and related
> >>>> configuration registers through adreno-smmu private
> >>>> interface instead of directly poking the smmu hardware.
> >>>>
> >>>> Suggested-by: Rob Clark <robdclark at gmail.com>
> >>>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
> >>>> ---
> >>>>    drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 37 ++++++++++++++++++++++
> >>>>    drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 ++
> >>>>    include/linux/adreno-smmu-priv.h           | 14 ++++++++
> >>>>    3 files changed, 53 insertions(+)
> >>>>
> >>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>> index d26f5aea248e..0e4f3fbda961 100644
> >>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>> @@ -16,6 +16,8 @@
> >>>>
> >>>>    #define QCOM_DUMMY_VAL -1
> >>>>
> >>>> +#define GFX_ACTLR_PRR          (1 << 5)
> >>>> +
> >>>>    static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> >>>>    {
> >>>>           return container_of(smmu, struct qcom_smmu, smmu);
> >>>> @@ -99,6 +101,32 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
> >>>>           arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
> >>>>    }
> >>>>
> >>>> +static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
> >>>> +{
> >>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
> >>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
> >>>> +       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
> >>>> +       u32 reg = 0;
> >>>> +
> >>>> +       reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
> >>>> +       reg &= ~GFX_ACTLR_PRR;
> >>>> +       if (set)
> >>>> +               reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
> >>>> +       arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
> >>>> +}
> >>>> +
> >>>> +static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
> >>>> +{
> >>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
> >>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
> >>>> +
> >>>> +       writel_relaxed(lower_32_bits(page_addr),
> >>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
> >>>> +
> >>>> +       writel_relaxed(upper_32_bits(page_addr),
> >>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
> >>>> +}
> >>>> +
> >>>>    #define QCOM_ADRENO_SMMU_GPU_SID 0
> >>>>
> >>>>    static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
> >>>> @@ -210,6 +238,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
> >>>>    static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> >>>>                   struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> >>>>    {
> >>>> +       const struct device_node *np = smmu_domain->smmu->dev->of_node;
> >>>>           struct adreno_smmu_priv *priv;
> >>>>
> >>>>           smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
> >>>> @@ -239,6 +268,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> >>>>           priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
> >>>>           priv->set_stall = qcom_adreno_smmu_set_stall;
> >>>>           priv->resume_translation = qcom_adreno_smmu_resume_translation;
> >>>> +       priv->set_prr_bit = NULL;
> >>>> +       priv->set_prr_addr = NULL;
> >>>> +
> >>>> +       if (of_device_is_compatible(np, "qcom,smmu-500") &&
> >>>> +                       of_device_is_compatible(np, "qcom,adreno-smmu")) {
> >>>
> >>> fwiw, it seems like PRR actually works on sc7180, which is _not_
> >>> mmu-500, so I guess the support actually goes back further.
> >>>
> >>
> >> As I checked sc7180 was on previous variant of SMMU,
> >> so targets on this variant have different steps to set PRR bit.
> >> <Do not have both prr bit and PRR page registers>.
> >
> > Experimentally, I have to set both the PRR LADDR/UADDR regs and
> > ACTLR.PRR bit on sc7180 to get the sparse-residency tests passing.  So
> > the underlying hw seems to work in the same way as mmu-500.  _But_
> > this is on a sc7180 chromebook, the situation might be different
> > depending on fw on things that have QC hyp.
> >
>
> I checked on sc7180 chipset which is based on the smmu-v2,
> this time by looking for these offsets specifically. I can see the
> nomenclature of the PRR related registers are a bit different
> compared to MMU-500 variant.
> Also the implementation register is 64 bit instead of
> dual 32 bit as in case of MMU-500. and PRR bit is not marked in
> ACTLR register offset.

Interesting.. in my experiments it needed both the ACTLR.PRR bit set
and the LADDR/UADDR.  Maybe it was just happy coincidence that two 32b
writes worked?

> So turns out PRR is supported but with some modification and
> can be carried out with same compatible based approach only - as per
> my understanding.
>
> In current patch plan was to provide support for MMU-500 based targets
> and won't break any legacy targets, so we can take the PRR support
> for legacy targets in different series once our evaluation is done on
> smmu-v2 ?

I guess it wouldn't be the end of the world, but it would mean that
drm would need to expose PRR support to userspace separately from
sparse binding support.  Maybe we need to do that anyways.  (I'm not
really sure how many different a6xx+smmu-v2 devices are out there, but
I guess they are all based on the same generation of snapdragon?)

BR,
-R

> We would explore more on this PRR feature for smmu-v2 based targets,
> before supporting it.
>
> Thanks & regards,
> Bibek
>
> >> It's MMU-500 targets only where PRR support is with both PRR bit
> >> and PRR page addr registers. As I was re-visiting our discussions on v13
> >> regarding this - I remember that's why we started using the SMMU-
> >> compatible string based PRR procedure selection instead of the reserved-
> >> memory node. [1] i.e Based on SMMU variant (as selected by compatible
> >> string), specific sequence will be selected.
> >>
> >> So for now only MMU-500 based selection has been supported as part of
> >> this series and will add subsequent support for other SMMU-variants
> >> thereafter.
> >>
> >>> I'm curious if we can just rely on this being supported by any hw that
> >>> has a6xx or newer?
> >>>
> >>
> >> I'd need to check on targets which will be based on a6xx onwards, on
> >> what will be the procedure planned to support PRR feature. I'll update
> >> the information over this space.
> >
> > One of the open questions about the drm/msm sparse-memory patchset is
> > whether we need to expose to userspace whether PRR is supported, or if
> > we can just rely on sparse-binding support implying sparse residency
> > (ie, PRR) support. All a6xx devices support per-process pgtables,
> > which is the only requirement for basic sparseBinding support.  But
> > PRR is required to additionally expose
> > sparseResidencyBuffer/sparseResidencyImage2D.
> >
> > I think, long term, turnip probably will want to drop support for
> > older kernels and remove support for legacy buffer mapping.  But if we
> > have some a6xx devices without PRR, then to do that we'd need to
> > decouple sparse binding and sparse residency.  (Vulkan allows a driver
> > to expose the former without the latter.)
> >
> > BR,
> > -R
> >
> >> [1]:
> >> https://lore.kernel.org/all/5790afa3-f9c0-4720-9804-8a7ff3d91854 at quicinc.com/#:~:text=%3E%20I%20guess%20if,part%20as%20well.
> >>
> >> Thanks & regards,
> >> Bibek
> >>
> >>> BR,
> >>> -R
> >>>
> >>>> +               priv->set_prr_bit = qcom_adreno_smmu_set_prr_bit;
> >>>> +               priv->set_prr_addr = qcom_adreno_smmu_set_prr_addr;
> >>>> +       }
> >>>>
> >>>>           return 0;
> >>>>    }
> >>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> >>>> index e2aeb511ae90..2dbf3243b5ad 100644
> >>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> >>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> >>>> @@ -154,6 +154,8 @@ enum arm_smmu_cbar_type {
> >>>>    #define ARM_SMMU_SCTLR_M               BIT(0)
> >>>>
> >>>>    #define ARM_SMMU_CB_ACTLR              0x4
> >>>> +#define ARM_SMMU_GFX_PRR_CFG_LADDR     0x6008
> >>>> +#define ARM_SMMU_GFX_PRR_CFG_UADDR     0x600C
> >>>>
> >>>>    #define ARM_SMMU_CB_RESUME             0x8
> >>>>    #define ARM_SMMU_RESUME_TERMINATE      BIT(0)
> >>>> diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
> >>>> index c637e0997f6d..614665153b3e 100644
> >>>> --- a/include/linux/adreno-smmu-priv.h
> >>>> +++ b/include/linux/adreno-smmu-priv.h
> >>>> @@ -50,6 +50,18 @@ struct adreno_smmu_fault_info {
> >>>>     *                 the GPU driver must call resume_translation()
> >>>>     * @resume_translation: Resume translation after a fault
> >>>>     *
> >>>> + * *CAUTION* : PRR callbacks (set_prr_bit/set_prr_addr) are NULL terminated for
> >>>> + *             targets without PRR support. Exercise caution and verify target
> >>>> + *             capabilities before invoking these callbacks to prevent potential
> >>>> + *             runtime errors or unexpected behavior.
> >>>> + *
> >>>> + * @set_prr_bit:   Extendible interface to be used by GPU to modify the
> >>>> + *                ACTLR register bits, currently used to configure
> >>>> + *                Partially-Resident-Region (PRR) bit for feature's
> >>>> + *                setup and reset sequence as requested.
> >>>> + * @set_prr_addr:  Configure the PRR_CFG_*ADDR register with the
> >>>> + *                physical address of PRR page passed from
> >>>> + *                GPU driver.
> >>>>     *
> >>>>     * The GPU driver (drm/msm) and adreno-smmu work together for controlling
> >>>>     * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
> >>>> @@ -67,6 +79,8 @@ struct adreno_smmu_priv {
> >>>>        void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
> >>>>        void (*set_stall)(const void *cookie, bool enabled);
> >>>>        void (*resume_translation)(const void *cookie, bool terminate);
> >>>> +    void (*set_prr_bit)(const void *cookie, bool set);
> >>>> +    void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
> >>>>    };
> >>>>
> >>>>    #endif /* __ADRENO_SMMU_PRIV_H */
> >>>> --
> >>>> 2.34.1
> >>>>
> >>
>


From broonie at kernel.org  Wed Dec  4 07:20:48 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 04 Dec 2024 15:20:48 +0000
Subject: [PATCH v2 0/6] arm64/sme: Collected SME fixes
Message-ID: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>

This series collects the various SME related fixes that were previously
posted separately.  These should address all the issues I am aware of so
a patch which reenables the SME configuration option is also included.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v2:
- Pull simplification of the signal restore code after the SME
  reenablement, it's not a fix but there's some code overlap.
- Comment updates.
- Link to v1: https://lore.kernel.org/r/20241203-arm64-sme-reenable-v1-0-d853479d1b77 at kernel.org

---
Mark Brown (6):
      arm64/sme: Flush foreign register state in do_sme_acc()
      arm64/fp: Don't corrupt FPMR when streaming mode changes
      arm64/ptrace: Zero FPMR on streaming mode entry/exit
      arm64/signal: Avoid corruption of SME state when entering signal handler
      arm64/sme: Reenable SME
      arm64/signal: Consistently invalidate the in register FP state in restore

 arch/arm64/Kconfig              |  1 -
 arch/arm64/include/asm/fpsimd.h |  1 +
 arch/arm64/kernel/fpsimd.c      | 57 ++++++++++++++++++++++----
 arch/arm64/kernel/ptrace.c      | 12 +++++-
 arch/arm64/kernel/signal.c      | 89 +++++++++++------------------------------
 5 files changed, 84 insertions(+), 76 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241202-arm64-sme-reenable-98e64c161a8e

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Wed Dec  4 07:20:49 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 04 Dec 2024 15:20:49 +0000
Subject: [PATCH v2 1/6] arm64/sme: Flush foreign register state in
 do_sme_acc()
In-Reply-To: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
References: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
Message-ID: <20241204-arm64-sme-reenable-v2-1-bae87728251d@kernel.org>

When do_sme_acc() runs with foreign FP state it does not do any updates of
the task structure, relying on the next return to userspace to reload the
register state appropriately, but leaves the task's last loaded CPU
untouched. This means that if the task returns to userspace on the last
CPU it ran on then the checks in fpsimd_bind_task_to_cpu() will incorrectly
determine that the register state on the CPU is current and suppress reload
of the floating point register state before returning to userspace. This
will result in spurious warnings due to SME access traps occuring for the
task after TIF_SME is set.

Call fpsimd_flush_task_state() to invalidate the last loaded CPU
recorded in the task, forcing detection of the task as foreign.

Fixes: 8bd7f91c03d8 ("arm64/sme: Implement traps and syscall handling for SME")
Reported-by: Mark Rutlamd <mark.rutland at arm.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: stable at vger.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 8c4c1a2186cc510a7826d15ec36225857c07ed71..eca0b6a2fc6fa25d8c850a5b9e109b4d58809f54 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1460,6 +1460,8 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
 		sme_set_vq(vq_minus_one);
 
 		fpsimd_bind_task_to_cpu();
+	} else {
+		fpsimd_flush_task_state(current);
 	}
 
 	put_cpu_fpsimd_context();

-- 
2.39.5



From broonie at kernel.org  Wed Dec  4 07:20:50 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 04 Dec 2024 15:20:50 +0000
Subject: [PATCH v2 2/6] arm64/fp: Don't corrupt FPMR when streaming mode
 changes
In-Reply-To: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
References: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
Message-ID: <20241204-arm64-sme-reenable-v2-2-bae87728251d@kernel.org>

When we enter or exit streaming more FPMR is reset to 0.  This means
that when restoring the floating point state from memory we need to
restore FPMR after we restore SVCR, otherwise if we are entering or
exiting streaming mode as part of loading the new state the value of
FPMR will be corrupted.

Fixes: 203f2b95a882 ("arm64/fpsimd: Support FEAT_FPMR")
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index eca0b6a2fc6fa25d8c850a5b9e109b4d58809f54..a3bb17c88942eba031d26e9f75ad46f37b6dc621 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -359,9 +359,6 @@ 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:
@@ -413,6 +410,9 @@ static void task_fpsimd_load(void)
 			restore_ffr = system_supports_fa64();
 	}
 
+	if (system_supports_fpmr())
+		write_sysreg_s(current->thread.uw.fpmr, SYS_FPMR);
+
 	if (restore_sve_regs) {
 		WARN_ON_ONCE(current->thread.fp_type != FP_STATE_SVE);
 		sve_load_state(sve_pffr(&current->thread),

-- 
2.39.5



From broonie at kernel.org  Wed Dec  4 07:20:51 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 04 Dec 2024 15:20:51 +0000
Subject: [PATCH v2 3/6] arm64/ptrace: Zero FPMR on streaming mode
 entry/exit
In-Reply-To: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
References: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
Message-ID: <20241204-arm64-sme-reenable-v2-3-bae87728251d@kernel.org>

When FPMR and SME are both present then entering and exiting streaming mode
clears FPMR in the same manner as it clears the V/Z and P registers.
Since entering and exiting streaming mode via ptrace is expected to have
the same effect as doing so via SMSTART/SMSTOP it should clear FPMR too
but this was missed when FPMR support was added. Add the required reset
of FPMR.

Since changing the vector length resets SVCR a SME vector length change
implemented via a write to ZA can trigger an exit of streaming mode and
we need to check when writing to ZA as well.

Fixes: 4035c22ef7d4 ("arm64/ptrace: Expose FPMR via ptrace")
Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: stable at vger.kernel.org
---
 arch/arm64/kernel/ptrace.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index e4437f62a2cda93734052c44b48886db83d75b3e..43a9397d5903ff87b608befdcaed3f9a7e48f976 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -877,6 +877,7 @@ static int sve_set_common(struct task_struct *target,
 			  const void *kbuf, const void __user *ubuf,
 			  enum vec_type type)
 {
+	u64 old_svcr = target->thread.svcr;
 	int ret;
 	struct user_sve_header header;
 	unsigned int vq;
@@ -908,8 +909,6 @@ static int sve_set_common(struct task_struct *target,
 
 	/* Enter/exit streaming mode */
 	if (system_supports_sme()) {
-		u64 old_svcr = target->thread.svcr;
-
 		switch (type) {
 		case ARM64_VEC_SVE:
 			target->thread.svcr &= ~SVCR_SM_MASK;
@@ -1008,6 +1007,10 @@ static int sve_set_common(struct task_struct *target,
 				 start, end);
 
 out:
+	/* If we entered or exited streaming mode then reset FPMR */
+	if ((target->thread.svcr & SVCR_SM) != (old_svcr & SVCR_SM))
+		target->thread.uw.fpmr = 0;
+
 	fpsimd_flush_task_state(target);
 	return ret;
 }
@@ -1104,6 +1107,7 @@ static int za_set(struct task_struct *target,
 		  unsigned int pos, unsigned int count,
 		  const void *kbuf, const void __user *ubuf)
 {
+	u64 old_svcr = target->thread.svcr;
 	int ret;
 	struct user_za_header header;
 	unsigned int vq;
@@ -1184,6 +1188,10 @@ static int za_set(struct task_struct *target,
 	target->thread.svcr |= SVCR_ZA_MASK;
 
 out:
+	/* If we entered or exited streaming mode then reset FPMR */
+	if ((target->thread.svcr & SVCR_SM) != (old_svcr & SVCR_SM))
+		target->thread.uw.fpmr = 0;
+
 	fpsimd_flush_task_state(target);
 	return ret;
 }

-- 
2.39.5



From broonie at kernel.org  Wed Dec  4 07:20:52 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 04 Dec 2024 15:20:52 +0000
Subject: [PATCH v2 4/6] arm64/signal: Avoid corruption of SME state when
 entering signal handler
In-Reply-To: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
References: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
Message-ID: <20241204-arm64-sme-reenable-v2-4-bae87728251d@kernel.org>

We intend that signal handlers are entered with PSTATE.{SM,ZA}={0,0}.
The logic for this in setup_return() manipulates the saved state and
live CPU state in an unsafe manner, and consequently, when a task enters
a signal handler:

 * The task entering the signal handler might not have its PSTATE.{SM,ZA}
   bits cleared, and other register state that is affected by changes to
   PSTATE.{SM,ZA} might not be zeroed as expected.

 * An unrelated task might have its PSTATE.{SM,ZA} bits cleared
   unexpectedly, potentially zeroing other register state that is
   affected by changes to PSTATE.{SM,ZA}.

   Tasks which do not set PSTATE.{SM,ZA} (i.e. those only using plain
   FPSIMD or non-streaming SVE) are not affected, as there is no
   resulting change to PSTATE.{SM,ZA}.

Consider for example two tasks on one CPU:

 A: Begins signal entry in kernel mode, is preempted prior to SMSTOP.
 B: Using SM and/or ZA in userspace with register state current on the
    CPU, is preempted.
 A: Scheduled in, no register state changes made as in kernel mode.
 A: Executes SMSTOP, modifying live register state.
 A: Scheduled out.
 B: Scheduled in, fpsimd_thread_switch() sees the register state on the
    CPU is tracked as being that for task B so the state is not reloaded
    prior to returning to userspace.

Task B is now running with SM and ZA incorrectly cleared.

Fix this by:

 * Checking TIF_FOREIGN_FPSTATE, and only updating the saved or live
   state as appropriate.

 * Using {get,put}_cpu_fpsimd_context() to ensure mutual exclusion
   against other code which manipulates this state. To allow their use,
   the logic is moved into a new fpsimd_enter_sighandler() helper in
   fpsimd.c.

This race has been observed intermittently with fp-stress, especially
with preempt disabled, commonly but not exclusively reporting "Bad SVCR: 0".

While we're at it also fix a discrepancy between in register and in memory
entries. When operating on the register state we issue a SMSTOP, exiting
streaming mode if we were in it. This clears the V/Z and P register and
FPMR, and resets FPSR to 0x800009f but does not change ZA, ZT or FPCR.
The in memory version clears all the user FPSIMD state including FPCR
and FPSR but does not clear FPMR. Update the code to implement the
changes the hardware implements.

Fixes: 40a8e87bb3285 ("arm64/sme: Disable ZA and streaming mode when handling signals")
Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: stable at vger.kernel.org
---
 arch/arm64/include/asm/fpsimd.h |  1 +
 arch/arm64/kernel/fpsimd.c      | 40 ++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/signal.c      | 19 +------------------
 3 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index f2a84efc361858d4deda99faf1967cc7cac386c1..09af7cfd9f6c2cec26332caa4c254976e117b1bf 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -76,6 +76,7 @@ extern void fpsimd_load_state(struct user_fpsimd_state *state);
 extern void fpsimd_thread_switch(struct task_struct *next);
 extern void fpsimd_flush_thread(void);
 
+extern void fpsimd_enter_sighandler(void);
 extern void fpsimd_signal_preserve_current_state(void);
 extern void fpsimd_preserve_current_state(void);
 extern void fpsimd_restore_current_state(void);
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a3bb17c88942eba031d26e9f75ad46f37b6dc621..2b045d4d8f71ace5bf01a596dda279285a0998a5 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1696,6 +1696,46 @@ void fpsimd_signal_preserve_current_state(void)
 		sve_to_fpsimd(current);
 }
 
+/*
+ * Called by the signal handling code when preparing current to enter
+ * a signal handler. Currently this only needs to take care of exiting
+ * streaming mode and clearing ZA on SME systems.
+ */
+void fpsimd_enter_sighandler(void)
+{
+	if (!system_supports_sme())
+		return;
+
+	get_cpu_fpsimd_context();
+
+	if (test_thread_flag(TIF_FOREIGN_FPSTATE)) {
+		/*
+		 * Exiting streaming mode zeros the V/Z and P
+		 * registers and FPMR.  Zero FPMR and the V registers,
+		 * marking the state as FPSIMD only to force a clear
+		 * of the remaining bits during reload if needed.
+		 */
+		if (current->thread.svcr & SVCR_SM_MASK) {
+			memset(&current->thread.uw.fpsimd_state.vregs, 0,
+			       sizeof(current->thread.uw.fpsimd_state.vregs));
+			current->thread.uw.fpsimd_state.fpsr = 0x800009f;
+			current->thread.uw.fpmr = 0;
+			current->thread.fp_type = FP_STATE_FPSIMD;
+		}
+
+		current->thread.svcr &= ~(SVCR_ZA_MASK |
+					  SVCR_SM_MASK);
+
+		/* Ensure any copies on other CPUs aren't reused */
+		fpsimd_flush_task_state(current);
+	} else {
+		/* The register state is current, just update it. */
+		sme_smstop();
+	}
+
+	put_cpu_fpsimd_context();
+}
+
 /*
  * Called by KVM when entering the guest.
  */
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 14ac6fdb872b9672e4b16a097f1b577aae8dec50..79c9c5cd0802149b3cde20b398617437d79181f2 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -1487,24 +1487,7 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
 	/* TCO (Tag Check Override) always cleared for signal handlers */
 	regs->pstate &= ~PSR_TCO_BIT;
 
-	/* Signal handlers are invoked with ZA and streaming mode disabled */
-	if (system_supports_sme()) {
-		/*
-		 * If we were in streaming mode the saved register
-		 * state was SVE but we will exit SM and use the
-		 * FPSIMD register state - flush the saved FPSIMD
-		 * register state in case it gets loaded.
-		 */
-		if (current->thread.svcr & SVCR_SM_MASK) {
-			memset(&current->thread.uw.fpsimd_state, 0,
-			       sizeof(current->thread.uw.fpsimd_state));
-			current->thread.fp_type = FP_STATE_FPSIMD;
-		}
-
-		current->thread.svcr &= ~(SVCR_ZA_MASK |
-					  SVCR_SM_MASK);
-		sme_smstop();
-	}
+	fpsimd_enter_sighandler();
 
 	if (ksig->ka.sa.sa_flags & SA_RESTORER)
 		sigtramp = ksig->ka.sa.sa_restorer;

-- 
2.39.5



From broonie at kernel.org  Wed Dec  4 07:20:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 04 Dec 2024 15:20:53 +0000
Subject: [PATCH v2 5/6] arm64/sme: Reenable SME
In-Reply-To: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
References: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
Message-ID: <20241204-arm64-sme-reenable-v2-5-bae87728251d@kernel.org>

Now that fixes for all the known issues with SME have been applied
remove the BROKEN dependency from it so it's generally available again.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5e8892c0112704f9ca74c4fc55b27..7e3182dd6fa0dadd961c352f88484cff0e520eaa 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2270,7 +2270,6 @@ config ARM64_SME
 	bool "ARM Scalable Matrix Extension support"
 	default y
 	depends on ARM64_SVE
-	depends on BROKEN
 	help
 	  The Scalable Matrix Extension (SME) is an extension to the AArch64
 	  execution state which utilises a substantial subset of the SVE

-- 
2.39.5



From broonie at kernel.org  Wed Dec  4 07:20:54 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 04 Dec 2024 15:20:54 +0000
Subject: [PATCH v2 6/6] arm64/signal: Consistently invalidate the in
 register FP state in restore
In-Reply-To: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
References: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
Message-ID: <20241204-arm64-sme-reenable-v2-6-bae87728251d@kernel.org>

When restoring the SVE and SME specific floating point register states we
flush the task floating point state, marking the hardware state as stale so
that preemption does not result in us saving register state from the signal
handler on top of the restored context and forcing a reload from memory.
For the plain FPSIMD state we don't do this, we just copy the state from
userspace and then force an immediate reload of the register state.
This isn't racy against context switch since we copy the incoming data
onto the stack rather than directly into the task struct but it's still
messy and inconsistent.

Simplify things and avoid a potential source of error by moving the
invalidation of the CPU state to the main restore_sigframe() and
reworking the restore of the FPSIMD state to update the task struct and
rely on loading as part of the general do_notify_resume() handling for
return to user like we do for the SVE and SME state.

As a result of this the only user of fpsimd_update_current_state() is
the 32 bit signal code which should not have any SVE state, add an
assert there that we don't have SVE enabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c |  9 +++---
 arch/arm64/kernel/signal.c | 70 +++++++++++++++-------------------------------
 2 files changed, 27 insertions(+), 52 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 2b045d4d8f71ace5bf01a596dda279285a0998a5..74080204073d06819838873996b8cb60043d89de 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1868,7 +1868,8 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state)
 	get_cpu_fpsimd_context();
 
 	current->thread.uw.fpsimd_state = *state;
-	if (test_thread_flag(TIF_SVE))
+	/* This should only ever be used for 32 bit processes */
+	if (WARN_ON_ONCE(test_thread_flag(TIF_SVE)))
 		fpsimd_to_sve(current);
 
 	task_fpsimd_load();
@@ -1894,9 +1895,9 @@ void fpsimd_flush_task_state(struct task_struct *t)
 {
 	t->thread.fpsimd_cpu = NR_CPUS;
 	/*
-	 * If we don't support fpsimd, bail out after we have
-	 * reset the fpsimd_cpu for this task and clear the
-	 * FPSTATE.
+	 * If we don't support fpsimd, bail out after we have reset
+	 * the fpsimd_cpu for this task and clear the FPSTATE.  We
+	 * check here rather than forcing callers to check.
 	 */
 	if (!system_supports_fpsimd())
 		return;
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 79c9c5cd0802149b3cde20b398617437d79181f2..335c2327baf74eac9634cf594855dbf26a7d6b01 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -271,7 +271,7 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 
 static int restore_fpsimd_context(struct user_ctxs *user)
 {
-	struct user_fpsimd_state fpsimd;
+	struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
 	int err = 0;
 
 	/* check the size information */
@@ -279,18 +279,14 @@ static int restore_fpsimd_context(struct user_ctxs *user)
 		return -EINVAL;
 
 	/* copy the FP and status/control registers */
-	err = __copy_from_user(fpsimd.vregs, &(user->fpsimd->vregs),
-			       sizeof(fpsimd.vregs));
-	__get_user_error(fpsimd.fpsr, &(user->fpsimd->fpsr), err);
-	__get_user_error(fpsimd.fpcr, &(user->fpsimd->fpcr), err);
+	err = __copy_from_user(fpsimd->vregs, &(user->fpsimd->vregs),
+			       sizeof(fpsimd->vregs));
+	__get_user_error(fpsimd->fpsr, &(user->fpsimd->fpsr), err);
+	__get_user_error(fpsimd->fpcr, &(user->fpsimd->fpcr), err);
 
 	clear_thread_flag(TIF_SVE);
 	current->thread.fp_type = FP_STATE_FPSIMD;
 
-	/* load the hardware registers from the fpsimd_state structure */
-	if (!err)
-		fpsimd_update_current_state(&fpsimd);
-
 	return err ? -EFAULT : 0;
 }
 
@@ -396,7 +392,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 {
 	int err = 0;
 	unsigned int vl, vq;
-	struct user_fpsimd_state fpsimd;
+	struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
 	u16 user_vl, flags;
 
 	if (user->sve_size < sizeof(*user->sve))
@@ -439,16 +435,6 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 	if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq))
 		return -EINVAL;
 
-	/*
-	 * Careful: we are about __copy_from_user() directly into
-	 * thread.sve_state with preemption enabled, so protection is
-	 * needed to prevent a racing context switch from writing stale
-	 * registers back over the new data.
-	 */
-
-	fpsimd_flush_task_state(current);
-	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
-
 	sve_alloc(current, true);
 	if (!current->thread.sve_state) {
 		clear_thread_flag(TIF_SVE);
@@ -471,14 +457,10 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 fpsimd_only:
 	/* copy the FP and status/control registers */
 	/* restore_sigframe() already checked that user->fpsimd != NULL. */
-	err = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs,
-			       sizeof(fpsimd.vregs));
-	__get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err);
-	__get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err);
-
-	/* load the hardware registers from the fpsimd_state structure */
-	if (!err)
-		fpsimd_update_current_state(&fpsimd);
+	err = __copy_from_user(fpsimd->vregs, user->fpsimd->vregs,
+			       sizeof(fpsimd->vregs));
+	__get_user_error(fpsimd->fpsr, &user->fpsimd->fpsr, err);
+	__get_user_error(fpsimd->fpcr, &user->fpsimd->fpcr, err);
 
 	return err ? -EFAULT : 0;
 }
@@ -587,16 +569,6 @@ static int restore_za_context(struct user_ctxs *user)
 	if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq))
 		return -EINVAL;
 
-	/*
-	 * Careful: we are about __copy_from_user() directly into
-	 * thread.sme_state with preemption enabled, so protection is
-	 * needed to prevent a racing context switch from writing stale
-	 * registers back over the new data.
-	 */
-
-	fpsimd_flush_task_state(current);
-	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
-
 	sme_alloc(current, true);
 	if (!current->thread.sme_state) {
 		current->thread.svcr &= ~SVCR_ZA_MASK;
@@ -664,16 +636,6 @@ static int restore_zt_context(struct user_ctxs *user)
 	if (nregs != 1)
 		return -EINVAL;
 
-	/*
-	 * Careful: we are about __copy_from_user() directly into
-	 * thread.zt_state with preemption enabled, so protection is
-	 * needed to prevent a racing context switch from writing stale
-	 * registers back over the new data.
-	 */
-
-	fpsimd_flush_task_state(current);
-	/* From now, fpsimd_thread_switch() won't touch ZT in thread state */
-
 	err = __copy_from_user(thread_zt_state(&current->thread),
 			       (char __user const *)user->zt +
 					ZT_SIG_REGS_OFFSET,
@@ -1028,6 +990,18 @@ static int restore_sigframe(struct pt_regs *regs,
 	if (err == 0)
 		err = parse_user_sigframe(&user, sf);
 
+	/*
+	 * Careful: we are about __copy_from_user() directly into
+	 * thread floating point state with preemption enabled, so
+	 * protection is needed to prevent a racing context switch
+	 * from writing stale registers back over the new data. Mark
+	 * the register floating point state as invalid and unbind the
+	 * task from the CPU to force a reload before we return to
+	 * userspace. fpsimd_flush_task_state() has a check for FP
+	 * support.
+	 */
+	fpsimd_flush_task_state(current);
+
 	if (err == 0 && system_supports_fpsimd()) {
 		if (!user.fpsimd)
 			return -EINVAL;

-- 
2.39.5



From robdclark at gmail.com  Wed Dec  4 07:24:52 2024
From: robdclark at gmail.com (Rob Clark)
Date: Wed, 4 Dec 2024 07:24:52 -0800
Subject: [PATCH RESEND v17 3/5] iommu/arm-smmu: add support for PRR bit setup
In-Reply-To: <04da6036-56c4-4b8c-b75b-b5e96a089efc@quicinc.com>
References: <20241114160721.1527934-1-quic_bibekkum@quicinc.com>
 <20241114160721.1527934-4-quic_bibekkum@quicinc.com> <CAF6AEGuwWsAkRyF-h5Aj3KzM7iksb12HsfJ5Ks+-P8hv60MWFg@mail.gmail.com>
 <CAF6AEGvVteuOOMod6yw9_6eOn2PxAx+BR8sVOHAHp7Ts8XigBw@mail.gmail.com>
 <5696afa2-c4ab-42fe-b29a-6ecee622fbb4@quicinc.com> <CAF6AEGuMmdnOmATMy8f+YgGxfrYb5mkG_qgy870wZPebKaZjVQ@mail.gmail.com>
 <04da6036-56c4-4b8c-b75b-b5e96a089efc@quicinc.com>
Message-ID: <CAF6AEGt-e_4kGyfiO=_oCLX8E3z76zeZ2MbRe1GicZj4hTEu+g@mail.gmail.com>

On Wed, Dec 4, 2024 at 3:28?AM Bibek Kumar Patro
<quic_bibekkum at quicinc.com> wrote:
>
>
>
> On 11/22/2024 10:04 PM, Rob Clark wrote:
> > On Fri, Nov 22, 2024 at 8:20?AM Bibek Kumar Patro
> > <quic_bibekkum at quicinc.com> wrote:
> >>
> >>
> >>
> >> On 11/21/2024 3:40 AM, Rob Clark wrote:
> >>> On Wed, Nov 20, 2024 at 9:17?AM Rob Clark <robdclark at gmail.com> wrote:
> >>>>
> >>>> On Thu, Nov 14, 2024 at 8:10?AM Bibek Kumar Patro
> >>>> <quic_bibekkum at quicinc.com> wrote:
> >>>>>
> >>>>> Add an adreno-smmu-priv interface for drm/msm to call
> >>>>> into arm-smmu-qcom and initiate the PRR bit setup or reset
> >>>>> sequence as per request.
> >>>>>
> >>>>> This will be used by GPU to setup the PRR bit and related
> >>>>> configuration registers through adreno-smmu private
> >>>>> interface instead of directly poking the smmu hardware.
> >>>>>
> >>>>> Suggested-by: Rob Clark <robdclark at gmail.com>
> >>>>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
> >>>>> ---
> >>>>>    drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 37 ++++++++++++++++++++++
> >>>>>    drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 ++
> >>>>>    include/linux/adreno-smmu-priv.h           | 14 ++++++++
> >>>>>    3 files changed, 53 insertions(+)
> >>>>>
> >>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>>> index d26f5aea248e..0e4f3fbda961 100644
> >>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>>> @@ -16,6 +16,8 @@
> >>>>>
> >>>>>    #define QCOM_DUMMY_VAL -1
> >>>>>
> >>>>> +#define GFX_ACTLR_PRR          (1 << 5)
> >>>>> +
> >>>>>    static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> >>>>>    {
> >>>>>           return container_of(smmu, struct qcom_smmu, smmu);
> >>>>> @@ -99,6 +101,32 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
> >>>>>           arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
> >>>>>    }
> >>>>>
> >>>>> +static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
> >>>>> +{
> >>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
> >>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
> >>>>> +       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
> >>>>> +       u32 reg = 0;
> >>>>> +
> >>>>> +       reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
> >>>>> +       reg &= ~GFX_ACTLR_PRR;
> >>>>> +       if (set)
> >>>>> +               reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
> >>>>> +       arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
> >>>>> +}
> >>>>> +
> >>>>> +static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
> >>>>> +{
> >>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
> >>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
> >>>>> +
> >>>>> +       writel_relaxed(lower_32_bits(page_addr),
> >>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
> >>>>> +
> >>>>> +       writel_relaxed(upper_32_bits(page_addr),
> >>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
> >>>>> +}
> >>>>> +
> >>>>>    #define QCOM_ADRENO_SMMU_GPU_SID 0
> >>>>>
> >>>>>    static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
> >>>>> @@ -210,6 +238,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
> >>>>>    static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> >>>>>                   struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> >>>>>    {
> >>>>> +       const struct device_node *np = smmu_domain->smmu->dev->of_node;
> >>>>>           struct adreno_smmu_priv *priv;
> >>>>>
> >>>>>           smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
> >>>>> @@ -239,6 +268,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> >>>>>           priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
> >>>>>           priv->set_stall = qcom_adreno_smmu_set_stall;
> >>>>>           priv->resume_translation = qcom_adreno_smmu_resume_translation;
> >>>>> +       priv->set_prr_bit = NULL;
> >>>>> +       priv->set_prr_addr = NULL;
> >>>>> +
> >>>>> +       if (of_device_is_compatible(np, "qcom,smmu-500") &&
> >>>>> +                       of_device_is_compatible(np, "qcom,adreno-smmu")) {
> >>>>
> >>>> fwiw, it seems like PRR actually works on sc7180, which is _not_
> >>>> mmu-500, so I guess the support actually goes back further.
> >>>>
> >>>> I'm curious if we can just rely on this being supported by any hw that
> >>>> has a6xx or newer?
> >>>
> >>>
> >>> Also, unrelated, but we can't assume the smmu is powered when drm
> >>> driver calls set_prr_bit/addr, could you add in runpm get/put around
> >>> the register access?
> >>>
> >>
> >> I see, thanks for this observation.
> >> It's surely a possible case, when they access these registers
> >> SMMU state is off.
> >> I will add the suggested runpm ops around the register access.
> >>
> >>> Otherwise Conner and I have vk sparse residency working now
> >>>
> >>
> >> Sorry, could not get this. Did you mean that vk sparse residency
> >> is working now using this patch?
> >
> > Yes, vk sparse residency is working with this patch (plus addition of
> > runpm get/put, plus drm/msm patches plus turnip patches) ;-)
> >
>
> Thanks for testing the sparse residency feature with our patch Rob,
> I have an additional query regarding the adreno private interfaces.
> Specifically, I was referring to other interfaces such as
> qcom_adreno_smmu_get_fault_info [1]. It appears that we do not have a
> runpm get/put around the register access in this context.

get_fault_info() is called from the iommu fault handler callback, so
from the fault irq handler, which is why it didn't need the runpm
get/put.  Maybe it is bad to make this assumption about usage, but
then again adreno_smmu_priv isn't really a general purpose interface.

> Could you please clarify whether we need an SMMU vote around register
> access in the case of PRR? IMO, should the users of this callback ensure
> they put a vote before accessing the cb?

How can drm vote for the smmu device?  I guess it could power up
itself and rely on device-link.. but that is pretty overkill to power
up the entire gpu in this case.  I think it is best for the vote to
happen in the PRR callbacks.

BR,
-R

> [1]:
> https://lore.kernel.org/all/20210610214431.539029-1-robdclark at gmail.com/
>
> Thanks & regards,
> Bibek
>
> > BR,
> > -R
> >
> >> Thanks & regards,
> >> Bibek
> >>
> >>> BR,
> >>> -R
> >>>
> >>>>
> >>>>> +               priv->set_prr_bit = qcom_adreno_smmu_set_prr_bit;
> >>>>> +               priv->set_prr_addr = qcom_adreno_smmu_set_prr_addr;
> >>>>> +       }
> >>>>>
> >>>>>           return 0;
> >>>>>    }
> >>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> >>>>> index e2aeb511ae90..2dbf3243b5ad 100644
> >>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> >>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> >>>>> @@ -154,6 +154,8 @@ enum arm_smmu_cbar_type {
> >>>>>    #define ARM_SMMU_SCTLR_M               BIT(0)
> >>>>>
> >>>>>    #define ARM_SMMU_CB_ACTLR              0x4
> >>>>> +#define ARM_SMMU_GFX_PRR_CFG_LADDR     0x6008
> >>>>> +#define ARM_SMMU_GFX_PRR_CFG_UADDR     0x600C
> >>>>>
> >>>>>    #define ARM_SMMU_CB_RESUME             0x8
> >>>>>    #define ARM_SMMU_RESUME_TERMINATE      BIT(0)
> >>>>> diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
> >>>>> index c637e0997f6d..614665153b3e 100644
> >>>>> --- a/include/linux/adreno-smmu-priv.h
> >>>>> +++ b/include/linux/adreno-smmu-priv.h
> >>>>> @@ -50,6 +50,18 @@ struct adreno_smmu_fault_info {
> >>>>>     *                 the GPU driver must call resume_translation()
> >>>>>     * @resume_translation: Resume translation after a fault
> >>>>>     *
> >>>>> + * *CAUTION* : PRR callbacks (set_prr_bit/set_prr_addr) are NULL terminated for
> >>>>> + *             targets without PRR support. Exercise caution and verify target
> >>>>> + *             capabilities before invoking these callbacks to prevent potential
> >>>>> + *             runtime errors or unexpected behavior.
> >>>>> + *
> >>>>> + * @set_prr_bit:   Extendible interface to be used by GPU to modify the
> >>>>> + *                ACTLR register bits, currently used to configure
> >>>>> + *                Partially-Resident-Region (PRR) bit for feature's
> >>>>> + *                setup and reset sequence as requested.
> >>>>> + * @set_prr_addr:  Configure the PRR_CFG_*ADDR register with the
> >>>>> + *                physical address of PRR page passed from
> >>>>> + *                GPU driver.
> >>>>>     *
> >>>>>     * The GPU driver (drm/msm) and adreno-smmu work together for controlling
> >>>>>     * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
> >>>>> @@ -67,6 +79,8 @@ struct adreno_smmu_priv {
> >>>>>        void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
> >>>>>        void (*set_stall)(const void *cookie, bool enabled);
> >>>>>        void (*resume_translation)(const void *cookie, bool terminate);
> >>>>> +    void (*set_prr_bit)(const void *cookie, bool set);
> >>>>> +    void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
> >>>>>    };
> >>>>>
> >>>>>    #endif /* __ADRENO_SMMU_PRIV_H */
> >>>>> --
> >>>>> 2.34.1
> >>>>>
> >>
>


From frank-w at public-files.de  Wed Dec  4 07:27:50 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Wed, 04 Dec 2024 16:27:50 +0100
Subject: [PATCH v5 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241204144341.GA191772-robh@kernel.org>
References: <20241202110045.22084-1-linux@fw-web.de> <20241202110045.22084-4-linux@fw-web.de> <20241204144341.GA191772-robh@kernel.org>
Message-ID: <52A93441-8BF5-412A-8BE1-F662A4BE8BE0@public-files.de>

Am 4. Dezember 2024 15:43:41 MEZ schrieb Rob Herring <robh at kernel.org>:
>On Mon, Dec 02, 2024 at 12:00:37PM +0100, Frank Wunderlich wrote:
>> From: Frank Wunderlich <frank-w at public-files.de>
>> changes in v5 (so not adding RB from Rob given in v4):
>> - do not use MTK_DRIVE_8mA in example
>> - add _0 functions for pwm
>
>Minor enough to keep my R-by, but if I review it again I can always find 
>more. :)

Sorry for the additional work now...thought changes are enough to not add the RB...ok, doc says "substantially" changes for dropping the given tags.
Imho it can make the "code" better :) I will fix the issues reporter in next version but wait a bit for the other parts to get reviewed.

regards Frank


From catalin.marinas at arm.com  Wed Dec  4 07:29:25 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 4 Dec 2024 15:29:25 +0000
Subject: [GIT PULL] arm64 updates for 6.13-rc1
In-Reply-To: <6aec1d44-4a89-4acf-a16b-4493626b93bb@os.amperecomputing.com>
References: <20241118100623.2674026-1-catalin.marinas@arm.com>
 <Z0STR6VLt2MCalnY@sashalap>
 <Z0TLhc3uxa5RnK64@arm.com>
 <0c09425b-c8ba-4ed6-b429-0bce4e7d00e9@os.amperecomputing.com>
 <Z0dhc-DtVsvufv-E@arm.com>
 <dc5e8809-825f-4c38-b487-b16c7d516311@os.amperecomputing.com>
 <e6b3e6c7-193d-43c4-a8c6-6023458723dd@redhat.com>
 <6aec1d44-4a89-4acf-a16b-4493626b93bb@os.amperecomputing.com>
Message-ID: <Z1B1VS8PayXsXDzl@arm.com>

On Mon, Dec 02, 2024 at 08:22:57AM -0800, Yang Shi wrote:
> On 11/28/24 1:56 AM, David Hildenbrand wrote:
> > On 28.11.24 02:21, Yang Shi wrote:
> > > > > diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
> > > > > index 87b3f1a25535..ef303a2262c5 100644
> > > > > --- a/arch/arm64/mm/copypage.c
> > > > > +++ b/arch/arm64/mm/copypage.c
> > > > > @@ -30,9 +30,9 @@ void copy_highpage(struct page *to, struct
> > > > > page *from)
> > > > > ??????? if (!system_supports_mte())
> > > > > ??????????? return;
> > > > > -??? if (folio_test_hugetlb(src) &&
> > > > > -??????? folio_test_hugetlb_mte_tagged(src)) {
> > > > > -??????? if (!folio_try_hugetlb_mte_tagging(dst))
> > > > > +??? if (folio_test_hugetlb(src)) {
> > > > > +??????? if (!folio_test_hugetlb_mte_tagged(src) ||
> > > > > +??????????? !folio_try_hugetlb_mte_tagging(dst))
> > > > > ??????????????? return;
> > > > > ??????????? /*
> > > > I wonder why we had a 'return' here originally rather than a
> > > > WARN_ON_ONCE() as we do further down for the page case. Do you seen any
> > > > issue with the hunk below? Destination should be a new folio and not
> > > > tagged yet:
> > > 
> > > Yes, I did see problem. Because we copy tags for all sub pages then set
> > > folio mte tagged when copying the data for the first subpage. The
> > > warning will be triggered when we copy the second subpage.
> > 
> > It's rather weird, though. We're instructed to copy a single page, yet
> > copy tags for all pages.
> > 
> > This really only makes sense when called from folio_copy(), where we are
> > guaranteed to copy all pages.
> > 
> > I'm starting to wonder if we should be able to hook into / overload
> > folio_copy() instead, to just handle the complete hugetlb copy ourselves
> > in one shot, and assume that copy_highpage() will never be called for
> > hugetlb pages (WARN and don't copy tags).
> 
> Actually folio_copy() is just called by migration. Copy huge page in CoW is
> more complicated and uses copy_user_highpage()->copy_highpage() instead of
> folio_copy(). It may start the page copy from any subpage. For example, if
> the CoW is triggered by accessing to the address in the middle of 2M. Kernel
> may copy the second half first then the first half to guarantee the accessed
> data in cache.

Still trying to understand the possible call paths here. If we get a
write fault on a large folio, does the core code allocate a folio of the
same size for CoW or it starts with smaller ones? wp_page_copy()
allocates order 0 AFAICT, though if it was a pmd fault, it takes a
different path in handle_mm_fault(). But we also have huge pages using
contiguous ptes.

Unless the source and destinations folios are exactly the same size, it
will break many assumptions in the code above. Going the other way
around is also wrong, dst larger than src, we are not initialising the
whole dst folio.

Maybe going back to per-page PG_mte_tagged flag rather than per-folio
would keep things simple, less risk of wrong assumptions.

-- 
Catalin


From linux at armlinux.org.uk  Wed Dec  4 07:30:51 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Dec 2024 15:30:51 +0000
Subject: [PATCH 15/15] ARM: mark footbridge as deprecated
In-Reply-To: <CACRpkdY-uKYqAR2Sj_cG7dPAtXMFG0Ldka7U13qZSFr+w15WxQ@mail.gmail.com>
References: <20241204102904.1863796-1-arnd@kernel.org>
 <20241204102904.1863796-16-arnd@kernel.org>
 <CACRpkdahQhj5u9ATghszi-N2OYhFbvHF_W_eAMDAU+vhmvdrJA@mail.gmail.com>
 <Z1BpNQjWwxEKFbg0@shell.armlinux.org.uk>
 <CACRpkdY-uKYqAR2Sj_cG7dPAtXMFG0Ldka7U13qZSFr+w15WxQ@mail.gmail.com>
Message-ID: <Z1B1q3Q3B_3TFlMn@shell.armlinux.org.uk>

On Wed, Dec 04, 2024 at 04:14:07PM +0100, Linus Walleij wrote:
> On Wed, Dec 4, 2024 at 3:37?PM Russell King (Oracle)
> <linux at armlinux.org.uk> wrote:
> 
> > > I am booting it occasionally, last time to test my KCFI patches.
> > > But admittedly that is only to test it for other SA110 users. I remember
> > > that Christoph had problems consolidating the DMA used in this
> > > machine as well so it is standing in the way of useful work.
> >
> > What problems with DMA? The fact that it uses an offset between
> > physical and PCI bus space should be nothing that causes a problem
> > for the kernel. As maintainer for Footbridge, I've heard nothing
> > about there being any issue.
> 
> No issue other than testing and iterating the patches I think.
> 
> I was thinking of this patchset to do dma_direct_set_offset():
> https://lore.kernel.org/linux-arm-kernel/20200917173229.3311382-3-hch at lst.de/
> 
> It seems to have stalled some years ago, but maybe there was
> some other reason.
> 
> IIRC Christoph was onto me to test it on the NetWinder, but I
> couldn't locate a good DMA capable device to test it with.
> (Would be the soundblaster but then I needed some userspace...)

It isn't soundblaster, but waveartist, and needs special setup to be
functional (which was all in my OSS waveartist driver.)

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


From david at redhat.com  Wed Dec  4 07:32:11 2024
From: david at redhat.com (David Hildenbrand)
Date: Wed, 4 Dec 2024 16:32:11 +0100
Subject: [GIT PULL] arm64 updates for 6.13-rc1
In-Reply-To: <Z1B1VS8PayXsXDzl@arm.com>
References: <20241118100623.2674026-1-catalin.marinas@arm.com>
 <Z0STR6VLt2MCalnY@sashalap> <Z0TLhc3uxa5RnK64@arm.com>
 <0c09425b-c8ba-4ed6-b429-0bce4e7d00e9@os.amperecomputing.com>
 <Z0dhc-DtVsvufv-E@arm.com>
 <dc5e8809-825f-4c38-b487-b16c7d516311@os.amperecomputing.com>
 <e6b3e6c7-193d-43c4-a8c6-6023458723dd@redhat.com>
 <6aec1d44-4a89-4acf-a16b-4493626b93bb@os.amperecomputing.com>
 <Z1B1VS8PayXsXDzl@arm.com>
Message-ID: <4919faec-3e35-459f-a7d3-b5b3f188bd9c@redhat.com>

On 04.12.24 16:29, Catalin Marinas wrote:
> On Mon, Dec 02, 2024 at 08:22:57AM -0800, Yang Shi wrote:
>> On 11/28/24 1:56 AM, David Hildenbrand wrote:
>>> On 28.11.24 02:21, Yang Shi wrote:
>>>>>> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
>>>>>> index 87b3f1a25535..ef303a2262c5 100644
>>>>>> --- a/arch/arm64/mm/copypage.c
>>>>>> +++ b/arch/arm64/mm/copypage.c
>>>>>> @@ -30,9 +30,9 @@ void copy_highpage(struct page *to, struct
>>>>>> page *from)
>>>>>>  ??????? if (!system_supports_mte())
>>>>>>  ??????????? return;
>>>>>> -??? if (folio_test_hugetlb(src) &&
>>>>>> -??????? folio_test_hugetlb_mte_tagged(src)) {
>>>>>> -??????? if (!folio_try_hugetlb_mte_tagging(dst))
>>>>>> +??? if (folio_test_hugetlb(src)) {
>>>>>> +??????? if (!folio_test_hugetlb_mte_tagged(src) ||
>>>>>> +??????????? !folio_try_hugetlb_mte_tagging(dst))
>>>>>>  ??????????????? return;
>>>>>>  ??????????? /*
>>>>> I wonder why we had a 'return' here originally rather than a
>>>>> WARN_ON_ONCE() as we do further down for the page case. Do you seen any
>>>>> issue with the hunk below? Destination should be a new folio and not
>>>>> tagged yet:
>>>>
>>>> Yes, I did see problem. Because we copy tags for all sub pages then set
>>>> folio mte tagged when copying the data for the first subpage. The
>>>> warning will be triggered when we copy the second subpage.
>>>
>>> It's rather weird, though. We're instructed to copy a single page, yet
>>> copy tags for all pages.
>>>
>>> This really only makes sense when called from folio_copy(), where we are
>>> guaranteed to copy all pages.
>>>
>>> I'm starting to wonder if we should be able to hook into / overload
>>> folio_copy() instead, to just handle the complete hugetlb copy ourselves
>>> in one shot, and assume that copy_highpage() will never be called for
>>> hugetlb pages (WARN and don't copy tags).
>>
>> Actually folio_copy() is just called by migration. Copy huge page in CoW is
>> more complicated and uses copy_user_highpage()->copy_highpage() instead of
>> folio_copy(). It may start the page copy from any subpage. For example, if
>> the CoW is triggered by accessing to the address in the middle of 2M. Kernel
>> may copy the second half first then the first half to guarantee the accessed
>> data in cache.
> 
> Still trying to understand the possible call paths here. If we get a
> write fault on a large folio, does the core code allocate a folio of the
> same size for CoW or it starts with smaller ones? wp_page_copy()
> allocates order 0 AFAICT, though if it was a pmd fault, it takes a
> different path in handle_mm_fault(). But we also have huge pages using
> contiguous ptes.
> 
> Unless the source and destinations folios are exactly the same size, it
> will break many assumptions in the code above. Going the other way
> around is also wrong, dst larger than src, we are not initialising the
> whole dst folio.
> 
> Maybe going back to per-page PG_mte_tagged flag rather than per-folio
> would keep things simple, less risk of wrong assumptions.

I think the magic bit here is that for hugetlb, we only get hugetlb 
folios of the same size, and no mixtures.

-- 
Cheers,

David / dhildenb



From linux at armlinux.org.uk  Wed Dec  4 07:42:34 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Dec 2024 15:42:34 +0000
Subject: [PATCH 02/15] ARM: limit OABI support to StrongARM CPUs
In-Reply-To: <CANp-EDb27XE0SMpDFUKm-L3j=rZhugbK20cQZGtAmP5D0r2C6w@mail.gmail.com>
References: <20241204102904.1863796-1-arnd@kernel.org>
 <20241204102904.1863796-3-arnd@kernel.org>
 <CACRpkdY243J4C3A9_13eTN84T2SeOjyoh0bWk6U1mqffUd6urw@mail.gmail.com>
 <CANp-EDb27XE0SMpDFUKm-L3j=rZhugbK20cQZGtAmP5D0r2C6w@mail.gmail.com>
Message-ID: <Z1B4aqtmfz19VMjv@shell.armlinux.org.uk>

On Wed, Dec 04, 2024 at 09:50:57AM -0500, Ralph Siemsen wrote:
> On Wed, Dec 4, 2024 at 8:59?AM Linus Walleij <linus.walleij at linaro.org> wrote:
> 
> > Hm why do we need a separate netwinder_defconfig if this defconfig already
> > supports it?
> 
> AFAIK footbridge_defconfig is for the "Compaq Personal Server", which
> is different than NetWinder. They could probably be reconciled by
> using devicetree and converting any platform devices. However testing
> could be a challenge, not sure who has working hardware anymore.

It's entirely possible to build one kernel that supports the EBSA285,
NetWinder and Compaq Personal Server. They're all the same machine at
the end of the day (PCI based SA110.) As long as the boot loaders pass
the correct machine type, the correct board file will be selected to
set things up.

However, if I remember correctly, Compaq seemed to be anti-mainline, so
didn't implement the machine ID and other things. I ended up
implementing a shim around the kernel to make mainline bootable on the
platform to correct the stuff that they couldn't be bothered to
implement. I may be adversely blaming them, as history from back then
is rather fuzzy, but I do remember mainline doesn't work because of all
sorts of weirdness they did.

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


From andre.draszik at linaro.org  Wed Dec  4 07:42:46 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Wed, 04 Dec 2024 15:42:46 +0000
Subject: [PATCH 8/9] phy: exynos5-usbdrd: subscribe to orientation
 notifier if required
In-Reply-To: <Z1Bi2gRJefYy1tyo@vaman>
References: <20241127-gs101-phy-lanes-orientation-phy-v1-0-1b7fce24960b@linaro.org>
	 <20241127-gs101-phy-lanes-orientation-phy-v1-8-1b7fce24960b@linaro.org>
	 <Z1Bi2gRJefYy1tyo@vaman>
Message-ID: <8c1c633bbd5a81a06ee9c9f52dfa8b43cf493b7b.camel@linaro.org>

Hi Vinod,

Thanks for your review.

On Wed, 2024-12-04 at 19:40 +0530, Vinod Koul wrote:
> On 27-11-24, 10:58, Andr? Draszik wrote:
> > gs101's SS phy needs to be configured differently based on the
> > connector orientation, as the SS link can only be established if the
> > mux is configured correctly.
> > 
> > The code to handle programming of the mux is in place already, this commit
> > now adds the missing pieces to subscribe to the Type-C orientation
> > switch event.
> > 
> > Note that for this all to work we rely on the USB controller
> > re-initialising us. It should invoke our .exit() upon cable unplug, and
> > during cable plug we'll receive the orientation event after which we
> > expect our .init() to be called.
> > 
> > Above reinitialisation happens if the DWC3 controller can enter runtime
> > suspend automatically. For the DWC3 driver, this is an opt-in:
> > ??? echo auto > /sys/devices/.../11110000.usb/power/control
> > Once done, things work as long as the UDC is not bound as otherwise it
> > stays busy because it doesn't cancel / stop outstanding TRBs. For now
> > we have to manually unbind the UDC in that case:
> > ???? echo "" > sys/kernel/config/usb_gadget/.../UDC
> > 
> > Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> > ---
> > ?drivers/phy/samsung/Kconfig????????????? |? 1 +
> > ?drivers/phy/samsung/phy-exynos5-usbdrd.c | 60 ++++++++++++++++++++++++++++++++
> > ?2 files changed, 61 insertions(+)
> > 
> > diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig
> > index f10afa3d7ff5..fc7bd1088576 100644
> > --- a/drivers/phy/samsung/Kconfig
> > +++ b/drivers/phy/samsung/Kconfig
> > @@ -80,6 +80,7 @@ config PHY_EXYNOS5_USBDRD
> > ?	tristate "Exynos5 SoC series USB DRD PHY driver"
> > ?	depends on (ARCH_EXYNOS && OF) || COMPILE_TEST
> > ?	depends on HAS_IOMEM
> > +	depends on TYPEC || (TYPEC=n && COMPILE_TEST)
> > ?	depends on USB_DWC3_EXYNOS
> > ?	select GENERIC_PHY
> > ?	select MFD_SYSCON
> > diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > index 1a34e9b4618a..2010d25ee817 100644
> > --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > @@ -394,6 +394,7 @@ struct exynos5_usbdrd_phy_drvdata {
> > ? * @extrefclk: frequency select settings when using 'separate
> > ? *	?????? reference clocks' for SS and HS operations
> > ? * @regulators: regulators for phy
> > + * @sw: TypeC orientation switch handle
> > ? * @orientation: TypeC connector orientation - normal or flipped
> > ? */
> > ?struct exynos5_usbdrd_phy {
> > @@ -415,6 +416,7 @@ struct exynos5_usbdrd_phy {
> > ?	u32 extrefclk;
> > ?	struct regulator_bulk_data *regulators;
> > ?
> > +	struct typec_switch_dev *sw;
> > ?	enum typec_orientation orientation;
> > ?};
> > ?
> > @@ -1400,6 +1402,60 @@ static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd)
> > ?	return 0;
> > ?}
> > ?
> > +#if IS_ENABLED(CONFIG_TYPEC)
> > +static int exynos5_usbdrd_orien_sw_set(struct typec_switch_dev *sw,
> > +				?????? enum typec_orientation orientation)
> > +{
> > +	struct exynos5_usbdrd_phy *phy_drd = typec_switch_get_drvdata(sw);
> > +
> > +	scoped_guard(mutex, &phy_drd->phy_mutex)
> > +		phy_drd->orientation = orientation;
> > +
> > +	return 0;
> > +}
> > +
> > +static void exynos5_usbdrd_orien_switch_unregister(void *data)
> > +{
> > +	struct exynos5_usbdrd_phy *phy_drd = data;
> > +
> > +	typec_switch_unregister(phy_drd->sw);
> > +}
> > +
> > +static int exynos5_usbdrd_setup_notifiers(struct exynos5_usbdrd_phy *phy_drd)
> > +{
> > +	int ret;
> > +
> > +	phy_drd->orientation = (enum typec_orientation)-1;
> 
> Should this be TYPEC_ORIENTATION_NONE?

It's -1 so that exynos5_usbdrd_orien_sw_set() (patch 9) can
check against the current value after driver load.

That said, it should probably be moved into patch 9 where it
actually matters, or even be removed altogether, in combination
with that check in exynos5_usbdrd_orien_sw_set() from patch 9.

I had added the check because some (not all) other phy drivers
do that, but looking further at that, I believe it's not
actually necessary, exynos5_usbdrd_orien_sw_set() can execute
unconditionally.

Will remove this and related code in next version.

Cheers,
Andre'



From pZ010001011111 at proton.me  Wed Dec  4 07:45:21 2024
From: pZ010001011111 at proton.me (Piotr Zalewski)
Date: Wed, 04 Dec 2024 15:45:21 +0000
Subject: [PATCH v7] rockchip/drm: vop2: add support for gamma LUT
In-Reply-To: <20241101185545.559090-3-pZ010001011111@proton.me>
References: <20241101185545.559090-3-pZ010001011111@proton.me>
Message-ID: <9Rp0NJW2QG5qDduowVaialZWN6xTe9KJFciu7Q2LERJZQXsUgFvMGXfcFaNznIEJEBpZeOdZPuL4fxOEFduaSJLuQJ3cIvN-fx2lEzYSBKE=@proton.me>

Hi all,

I just noticed that after coming out of suspend gamma LUT is lost and must
be rewritten by userspace.

So I guess it will be needed to save LUT to a buffer and rewrite it after
going out of suspend during modeset?

I checked the patch isn't yet in the "official" linux-next.

Regards, Piotr Zalewski


From andrew at lunn.ch  Wed Dec  4 07:48:58 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 4 Dec 2024 16:48:58 +0100
Subject: [PATCH 12/15] ARM: orion5x: mark all board files as deprecated
In-Reply-To: <20241204102904.1863796-13-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
 <20241204102904.1863796-13-arnd@kernel.org>
Message-ID: <11006329-8f7c-4c8d-8754-cd1a068490e2@lunn.ch>

On Wed, Dec 04, 2024 at 11:29:01AM +0100, Arnd Bergmann wrote:
61;7801;1c> From: Arnd Bergmann <arnd at arndb.de>
> 
> Conversion of the old orion5x board files to devicetree has
> stalled over the past few years, so it seems better to remove
> the remaining ones in order to allow  cleaning up the device
> drivers.
> 
> Debian has previously removed the orion/kirkwood kernel
> binary from the armel distro, but building custom kernels
> from the Debian source code should keep working, so
> removing the board files after the 6.12 release ensures
> that this remains possible for the Debian Trixie release,
> assuming this will use the 6.12 LTS kernel.
> 
> Jeremy Peper still plans to convert the Terastation 2 Pro
> to devicetree in the future, but that can be done even
> after it is removed.
> 
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

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

    Andrew


From andrew at lunn.ch  Wed Dec  4 07:48:17 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 4 Dec 2024 16:48:17 +0100
Subject: [net-next PATCH v8 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <67501d7b.050a0220.3390ac.353c@mx.google.com>
References: <20241204072427.17778-1-ansuelsmth@gmail.com>
 <20241204072427.17778-4-ansuelsmth@gmail.com>
 <20241204100922.0af25d7e@fedora.home>
 <67501d7b.050a0220.3390ac.353c@mx.google.com>
Message-ID: <af078f6a-08ba-4a68-ae54-2d49a59ce1bb@lunn.ch>

> Added 5000 as this is present in documentation bits but CPU can only go
> up to 2.5. Should I drop it? Idea was to futureproof it since it really
> seems they added these bits with the intention of having a newer switch
> with more advanced ports.

The other way to future proof this is to have a dev_err() and
-EINVAL. Testing will then quickly find any missing places in the
code.

	Andrew


From catalin.marinas at arm.com  Wed Dec  4 07:50:16 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 4 Dec 2024 15:50:16 +0000
Subject: [GIT PULL] arm64 updates for 6.13-rc1
In-Reply-To: <4919faec-3e35-459f-a7d3-b5b3f188bd9c@redhat.com>
References: <20241118100623.2674026-1-catalin.marinas@arm.com>
 <Z0STR6VLt2MCalnY@sashalap>
 <Z0TLhc3uxa5RnK64@arm.com>
 <0c09425b-c8ba-4ed6-b429-0bce4e7d00e9@os.amperecomputing.com>
 <Z0dhc-DtVsvufv-E@arm.com>
 <dc5e8809-825f-4c38-b487-b16c7d516311@os.amperecomputing.com>
 <e6b3e6c7-193d-43c4-a8c6-6023458723dd@redhat.com>
 <6aec1d44-4a89-4acf-a16b-4493626b93bb@os.amperecomputing.com>
 <Z1B1VS8PayXsXDzl@arm.com>
 <4919faec-3e35-459f-a7d3-b5b3f188bd9c@redhat.com>
Message-ID: <Z1B6OMqEZitgBVEx@arm.com>

On Wed, Dec 04, 2024 at 04:32:11PM +0100, David Hildenbrand wrote:
> On 04.12.24 16:29, Catalin Marinas wrote:
> > On Mon, Dec 02, 2024 at 08:22:57AM -0800, Yang Shi wrote:
> > > On 11/28/24 1:56 AM, David Hildenbrand wrote:
> > > > On 28.11.24 02:21, Yang Shi wrote:
> > > > > > > diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
> > > > > > > index 87b3f1a25535..ef303a2262c5 100644
> > > > > > > --- a/arch/arm64/mm/copypage.c
> > > > > > > +++ b/arch/arm64/mm/copypage.c
> > > > > > > @@ -30,9 +30,9 @@ void copy_highpage(struct page *to, struct
> > > > > > > page *from)
> > > > > > >  ??????? if (!system_supports_mte())
> > > > > > >  ??????????? return;
> > > > > > > -??? if (folio_test_hugetlb(src) &&
> > > > > > > -??????? folio_test_hugetlb_mte_tagged(src)) {
> > > > > > > -??????? if (!folio_try_hugetlb_mte_tagging(dst))
> > > > > > > +??? if (folio_test_hugetlb(src)) {
> > > > > > > +??????? if (!folio_test_hugetlb_mte_tagged(src) ||
> > > > > > > +??????????? !folio_try_hugetlb_mte_tagging(dst))
> > > > > > >  ??????????????? return;
> > > > > > >  ??????????? /*
> > > > > > I wonder why we had a 'return' here originally rather than a
> > > > > > WARN_ON_ONCE() as we do further down for the page case. Do you seen any
> > > > > > issue with the hunk below? Destination should be a new folio and not
> > > > > > tagged yet:
> > > > > 
> > > > > Yes, I did see problem. Because we copy tags for all sub pages then set
> > > > > folio mte tagged when copying the data for the first subpage. The
> > > > > warning will be triggered when we copy the second subpage.
> > > > 
> > > > It's rather weird, though. We're instructed to copy a single page, yet
> > > > copy tags for all pages.
> > > > 
> > > > This really only makes sense when called from folio_copy(), where we are
> > > > guaranteed to copy all pages.
> > > > 
> > > > I'm starting to wonder if we should be able to hook into / overload
> > > > folio_copy() instead, to just handle the complete hugetlb copy ourselves
> > > > in one shot, and assume that copy_highpage() will never be called for
> > > > hugetlb pages (WARN and don't copy tags).
> > > 
> > > Actually folio_copy() is just called by migration. Copy huge page in CoW is
> > > more complicated and uses copy_user_highpage()->copy_highpage() instead of
> > > folio_copy(). It may start the page copy from any subpage. For example, if
> > > the CoW is triggered by accessing to the address in the middle of 2M. Kernel
> > > may copy the second half first then the first half to guarantee the accessed
> > > data in cache.
> > 
> > Still trying to understand the possible call paths here. If we get a
> > write fault on a large folio, does the core code allocate a folio of the
> > same size for CoW or it starts with smaller ones? wp_page_copy()
> > allocates order 0 AFAICT, though if it was a pmd fault, it takes a
> > different path in handle_mm_fault(). But we also have huge pages using
> > contiguous ptes.
> > 
> > Unless the source and destinations folios are exactly the same size, it
> > will break many assumptions in the code above. Going the other way
> > around is also wrong, dst larger than src, we are not initialising the
> > whole dst folio.
> > 
> > Maybe going back to per-page PG_mte_tagged flag rather than per-folio
> > would keep things simple, less risk of wrong assumptions.
> 
> I think the magic bit here is that for hugetlb, we only get hugetlb folios
> of the same size, and no mixtures.

Ah, ok, we do check for this and only do the advance copy for hugetlb
folios. I'd add a check for folio size just in case, something like
below (I'll add some description and post it properly):

diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
index 87b3f1a25535..c3a83db46ec6 100644
--- a/arch/arm64/mm/copypage.c
+++ b/arch/arm64/mm/copypage.c
@@ -30,11 +30,14 @@ void copy_highpage(struct page *to, struct page *from)
 	if (!system_supports_mte())
 		return;
 
-	if (folio_test_hugetlb(src) &&
-	    folio_test_hugetlb_mte_tagged(src)) {
-		if (!folio_try_hugetlb_mte_tagging(dst))
+	if (folio_test_hugetlb(src)) {
+		if (!folio_test_hugetlb_mte_tagged(src) ||
+		    from != folio_page(src, 0) ||
+		    WARN_ON_ONCE(folio_nr_pages(src) != folio_nr_pages(dst)))
 			return;
 
+		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
+
 		/*
 		 * Populate tags for all subpages.
 		 *

-- 
Catalin


From john.g.garry at oracle.com  Wed Dec  4 07:54:30 2024
From: john.g.garry at oracle.com (John Garry)
Date: Wed, 4 Dec 2024 15:54:30 +0000
Subject: arm allmodconfig build issue with bpf
Message-ID: <9950a25d-1a79-42c9-ade7-dc51ef569ad2@oracle.com>

Hi all,

For some time, the arm allmodconfig build has had this following build 
issue for me:

$ make net/bpf/test_run.o
   CALL    scripts/checksyscalls.sh
   CC      net/bpf/test_run.o
net/bpf/test_run.c:522:1: error: ?retain? attribute ignored 
[-Werror=attributes]
   522 | {
       | ^
net/bpf/test_run.c:568:1: error: ?retain? attribute ignored 
[-Werror=attributes]
   568 | {
       | ^
net/bpf/test_run.c:577:1: error: ?retain? attribute ignored 
[-Werror=attributes]
   577 | {
       | ^
net/bpf/test_run.c:584:1: error: ?retain? attribute ignored 
[-Werror=attributes]
   584 | {
       | ^
net/bpf/test_run.c:590:1: error: ?retain? attribute ignored 
[-Werror=attributes]
   590 | {
       | ^
net/bpf/test_run.c:619:1: error: ?retain? attribute ignored 
[-Werror=attributes]
   619 | {
       | ^
net/bpf/test_run.c:624:1: error: ?retain? attribute ignored 
[-Werror=attributes]
   624 | {
       | ^
net/bpf/test_run.c:630:1: error: ?retain? attribute ignored 
[-Werror=attributes]
   630 | {
       | ^
net/bpf/test_run.c:634:1: error: ?retain? attribute ignored 
[-Werror=attributes]
   634 | {
       | ^
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:194: net/bpf/test_run.o] Error 1
make[3]: *** [scripts/Makefile.build:440: net/bpf] Error 2
make[2]: *** [scripts/Makefile.build:440: net] Error 2
make[1]: *** [/home/ubuntu/mnt/linux2/Makefile:1989: .] Error 2
make: *** [Makefile:251: __sub-make] Error 2
ubuntu at jgarry-ubuntu-bm5-instance-20230215-1843:~/mnt/linux2$

The issue comes the definition of __bpf_kfunc from include/linux/btf.h

Other files which include btf.h, like kernel/cgroup/rstat.c, have this 
same issue.

I am crossing compiling with the following:

$ /usr/bin/arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Normally I bodge a fix like:

---->8----

diff --git a/include/linux/btf.h b/include/linux/btf.h
index b12c63af9e78..4214e76c9168 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -83,7 +83,7 @@
   * as to avoid issues such as the compiler inlining or eliding either 
a static
   * kfunc, or a global kfunc in an LTO build.
   */
-#define __bpf_kfunc
+#define __bpf_kfunc __used __retain noinline

  #define __bpf_kfunc_start_defs() 
        \
         __diag_push();


----8<----

Any proposals to properly fix this?

Thanks,
John


From marcus.folkesson at gmail.com  Wed Dec  4 07:56:47 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:47 +0100
Subject: [PATCH 5/9] ARM: mvebu_v5_defconfig: rebuild default configuration
In-Reply-To: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
Message-ID: <20241204-defconfigs-v1-5-86587652d37a@gmail.com>

This configuration contains obsolete configuration options e.g.
CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.

Rebuild this configuration by run:
make ARCH=arm mvebu_v5_defconfig
make ARCH=arm savedefconfig

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
 arch/arm/configs/mvebu_v5_defconfig | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig
index 2467afd32146ba7ba2bf4b71053a6747bc58d1cc..0e3da23baab417378afcbc40fca88ace5cd51e57 100644
--- a/arch/arm/configs/mvebu_v5_defconfig
+++ b/arch/arm/configs/mvebu_v5_defconfig
@@ -1,5 +1,4 @@
 CONFIG_SYSVIPC=y
-CONFIG_FHANDLE=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
@@ -15,7 +14,6 @@ CONFIG_MACH_DNS323=y
 CONFIG_MACH_TS209=y
 CONFIG_MACH_TERASTATION_PRO2=y
 CONFIG_MACH_LINKSTATION_PRO=y
-CONFIG_MACH_LINKSTATION_LSCHL=y
 CONFIG_MACH_LINKSTATION_MINI=y
 CONFIG_MACH_TS409=y
 CONFIG_MACH_TS78XX=y
@@ -45,7 +43,6 @@ CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IPV6 is not set
 CONFIG_NET_DSA=y
-CONFIG_NET_SWITCHDEV=y
 CONFIG_NET_PKTGEN=m
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
@@ -63,7 +60,6 @@ CONFIG_MTD_CFI_GEOMETRY=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_ORION=y
 CONFIG_MTD_SPI_NOR=y
@@ -96,12 +92,10 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=2
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
-# CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MV64XXX=y
 CONFIG_SPI=y
 CONFIG_SPI_ORION=y
-CONFIG_GPIO_SYSFS=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_POWER_RESET_QNAP=y
@@ -166,7 +160,6 @@ CONFIG_RTC_DRV_MV=y
 CONFIG_DMADEVICES=y
 CONFIG_MV_XOR=y
 CONFIG_STAGING=y
-CONFIG_FB_XGI=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_ISO9660_FS=m
@@ -194,6 +187,5 @@ CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 # CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y

-- 
2.47.0



From marcus.folkesson at gmail.com  Wed Dec  4 07:56:48 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:48 +0100
Subject: [PATCH 6/9] ARM: mxs_defconfig: rebuild default configuration
In-Reply-To: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
Message-ID: <20241204-defconfigs-v1-6-86587652d37a@gmail.com>

This configuration contains obsolete configuration options e.g.
CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.

Rebuild this configuration by run:
make ARCH=arm mxs_defconfig
make ARCH=arm savedefconfig

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
 arch/arm/configs/mxs_defconfig | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 43bc1255a5db9f4ed8f65a98a69284e1439e44d2..946f508ad62c326a0651c8a5da0626ee33c9bfd3 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -32,9 +32,6 @@ CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_SYN_COOKIES=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 CONFIG_CAN=m
@@ -45,7 +42,6 @@ CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_SST25L=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_GPMI_NAND=y
@@ -60,7 +56,6 @@ CONFIG_ENC28J60=y
 CONFIG_ICPLUS_PHY=y
 CONFIG_MICREL_PHY=y
 CONFIG_REALTEK_PHY=y
-CONFIG_SMSC_PHY=y
 CONFIG_CAN_FLEXCAN=m
 CONFIG_USB_USBNET=y
 CONFIG_USB_NET_SMSC95XX=y
@@ -77,13 +72,11 @@ CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_SERIAL_MXS_AUART=y
 # CONFIG_HW_RANDOM is not set
-# CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MXS=y
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=m
 CONFIG_SPI_MXS=y
-CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_STMP3XXX_RTC_WATCHDOG=y
@@ -138,10 +131,6 @@ CONFIG_PWM_MXS=y
 CONFIG_NVMEM_MXS_OCOTP=y
 CONFIG_EXT4_FS=y
 # CONFIG_DNOTIFY is not set
-CONFIG_NETFS_SUPPORT=m
-CONFIG_FSCACHE=y
-CONFIG_FSCACHE_STATS=y
-CONFIG_CACHEFILES=m
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y

-- 
2.47.0



From marcus.folkesson at gmail.com  Wed Dec  4 07:56:49 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:49 +0100
Subject: [PATCH 7/9] ARM: pxa_defconfig: rebuild default configuration
In-Reply-To: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
Message-ID: <20241204-defconfigs-v1-7-86587652d37a@gmail.com>

This configuration contains obsolete configuration options e.g.
CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.

Rebuild this configuration by run:
make ARCH=arm pxa_defconfig
make ARCH=arm savedefconfig

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
 arch/arm/configs/pxa_defconfig | 69 ++----------------------------------------
 1 file changed, 2 insertions(+), 67 deletions(-)

diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig
index 38916ac4bce481a17ced58faad73ceeef31fae0f..dbac3b6dbb99b13b21c8f6461b4063346363acab 100644
--- a/arch/arm/configs/pxa_defconfig
+++ b/arch/arm/configs/pxa_defconfig
@@ -1,6 +1,5 @@
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
@@ -80,7 +79,6 @@ CONFIG_BT_HCIBFUSB=m
 CONFIG_BT_HCIDTL1=m
 CONFIG_BT_HCIBT3C=m
 CONFIG_BT_HCIBLUECARD=m
-CONFIG_BT_HCIBTUART=m
 CONFIG_BT_HCIVHCI=m
 CONFIG_BT_MRVL=m
 CONFIG_BT_MRVL_SDIO=m
@@ -123,7 +121,6 @@ CONFIG_MTD_ROM=m
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PXA2XX=m
-CONFIG_MTD_M25P80=m
 CONFIG_MTD_BLOCK2MTD=y
 CONFIG_MTD_DOCG3=m
 CONFIG_MTD_ONENAND=m
@@ -131,7 +128,6 @@ CONFIG_MTD_ONENAND_VERIFY_WRITE=y
 CONFIG_MTD_ONENAND_GENERIC=m
 CONFIG_MTD_RAW_NAND=m
 CONFIG_MTD_NAND_SHARPSL=m
-CONFIG_MTD_NAND_TMIO=m
 CONFIG_MTD_NAND_BRCMNAND=m
 CONFIG_MTD_NAND_GPIO=m
 CONFIG_MTD_NAND_PLATFORM=m
@@ -140,13 +136,11 @@ CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
 CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000
 CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
 CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
-CONFIG_MTD_NAND_CM_X270=m
 CONFIG_MTD_NAND_ECC_SW_BCH=y
 CONFIG_MTD_SPI_NOR=m
 CONFIG_MTD_UBI=m
 CONFIG_MTD_UBI_BLOCK=y
 CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=8
@@ -160,7 +154,6 @@ CONFIG_SENSORS_LIS3_SPI=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=m
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=m
 CONFIG_CHR_DEV_SG=y
 CONFIG_ATA=m
@@ -169,7 +162,6 @@ CONFIG_SATA_AHCI_PLATFORM=m
 CONFIG_SATA_MV=m
 CONFIG_PATA_PXA=m
 CONFIG_PATA_PCMCIA=m
-CONFIG_PATA_PLATFORM=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 CONFIG_MACB=m
@@ -184,12 +176,8 @@ CONFIG_R8169=m
 CONFIG_SMC91X=m
 CONFIG_SMSC911X=m
 CONFIG_STMMAC_ETH=m
-CONFIG_PHYLIB=y
-CONFIG_SMSC_PHY=m
 CONFIG_BROADCOM_PHY=y
 CONFIG_ICPLUS_PHY=m
-CONFIG_MICREL_PHY=m
-CONFIG_FIXED_PHY=m
 CONFIG_MARVELL_PHY=m
 CONFIG_AT803X_PHY=m
 CONFIG_MDIO_BITBANG=y
@@ -211,13 +199,6 @@ CONFIG_USB_NET_SMSC75XX=m
 CONFIG_USB_NET_SMSC95XX=m
 CONFIG_USB_NET_MCS7830=m
 CONFIG_BRCMFMAC=m
-CONFIG_HOSTAP=m
-CONFIG_HOSTAP_FIRMWARE=y
-CONFIG_HOSTAP_FIRMWARE_NVRAM=y
-CONFIG_HOSTAP_CS=m
-CONFIG_HERMES=m
-CONFIG_PCMCIA_HERMES=m
-CONFIG_PCMCIA_SPECTRUM=m
 CONFIG_LIBERTAS=m
 CONFIG_LIBERTAS_SDIO=m
 CONFIG_MWIFIEX=m
@@ -225,7 +206,6 @@ CONFIG_MWIFIEX_SDIO=m
 CONFIG_RT2X00=m
 CONFIG_RT73USB=m
 CONFIG_RT2800USB=m
-CONFIG_INPUT_FF_MEMLESS=m
 CONFIG_INPUT_MATRIXKMAP=y
 CONFIG_INPUT_MOUSEDEV=m
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
@@ -243,7 +223,6 @@ CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_MOUSE_SERIAL=m
 CONFIG_MOUSE_CYAPA=m
 CONFIG_MOUSE_ELAN_I2C=m
-CONFIG_MOUSE_NAVPOINT_PXA27x=m
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=m
 CONFIG_TOUCHSCREEN_ATMEL_MXT=m
@@ -260,7 +239,6 @@ CONFIG_TOUCHSCREEN_TOUCHIT213=m
 CONFIG_TOUCHSCREEN_PCAP=m
 CONFIG_TOUCHSCREEN_ST1232=m
 CONFIG_INPUT_MISC=y
-CONFIG_INPUT_AXP20X_PEK=m
 CONFIG_INPUT_UINPUT=m
 CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
 CONFIG_INPUT_PCAP=m
@@ -275,10 +253,7 @@ CONFIG_SERIAL_PXA=y
 CONFIG_SERIAL_PXA_CONSOLE=y
 CONFIG_HW_RANDOM=y
 CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_MUX_PCA954x=m
-CONFIG_I2C_MUX_PINCTRL=m
 CONFIG_I2C_DESIGNWARE_CORE=m
-CONFIG_I2C_DESIGNWARE_PLATFORM=m
 CONFIG_I2C_GPIO=y
 CONFIG_I2C_PXA_SLAVE=y
 CONFIG_I2C_XILINX=m
@@ -288,10 +263,8 @@ CONFIG_SPI_BITBANG=y
 CONFIG_SPI_CADENCE=m
 CONFIG_SPI_GPIO=m
 CONFIG_SPI_PXA2XX=m
-CONFIG_SPI_ROCKCHIP=m
 CONFIG_SPI_XILINX=m
 CONFIG_SPI_SPIDEV=m
-CONFIG_PPS=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_DWAPB=m
@@ -305,7 +278,6 @@ CONFIG_GPIO_TPS6586X=y
 CONFIG_GPIO_TPS65910=y
 CONFIG_GPIO_MAX7301=m
 CONFIG_POWER_SUPPLY_DEBUG=y
-CONFIG_PDA_POWER=m
 CONFIG_BATTERY_SBS=m
 CONFIG_BATTERY_DA9030=m
 CONFIG_BATTERY_MAX17040=m
@@ -313,7 +285,6 @@ CONFIG_BATTERY_MAX17042=m
 CONFIG_CHARGER_MAX14577=m
 CONFIG_CHARGER_MAX77693=m
 CONFIG_CHARGER_TPS65090=m
-CONFIG_SENSORS_ADM1021=m
 CONFIG_SENSORS_MAX6650=m
 CONFIG_SENSORS_LM75=m
 CONFIG_SENSORS_LM90=m
@@ -325,30 +296,21 @@ CONFIG_XILINX_WATCHDOG=m
 CONFIG_SA1100_WATCHDOG=m
 CONFIG_MFD_AS3711=y
 CONFIG_MFD_BCM590XX=m
-CONFIG_MFD_AXP20X=y
-CONFIG_MFD_CROS_EC_DEV=m
-CONFIG_MFD_ASIC3=y
 CONFIG_PMIC_DA903X=y
-CONFIG_HTC_PASIC3=m
 CONFIG_MFD_MAX14577=y
 CONFIG_MFD_MAX77693=y
 CONFIG_MFD_MAX8907=m
 CONFIG_EZX_PCAP=y
-CONFIG_UCB1400_CORE=m
 CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_PALMAS=y
 CONFIG_MFD_TPS65090=y
 CONFIG_MFD_TPS6586X=y
 CONFIG_MFD_TPS65910=y
-CONFIG_MFD_T7L66XB=y
-CONFIG_MFD_TC6387XB=y
-CONFIG_MFD_TC6393XB=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_DEBUG=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=m
 CONFIG_REGULATOR_ACT8865=m
 CONFIG_REGULATOR_AS3711=m
-CONFIG_REGULATOR_AXP20X=m
 CONFIG_REGULATOR_BCM590XX=m
 CONFIG_REGULATOR_DA903X=m
 CONFIG_REGULATOR_DA9210=m
@@ -370,9 +332,6 @@ CONFIG_REGULATOR_TPS65090=m
 CONFIG_REGULATOR_TPS6586X=m
 CONFIG_REGULATOR_TPS65910=m
 CONFIG_MEDIA_SUPPORT=m
-CONFIG_MEDIA_CAMERA_SUPPORT=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
@@ -384,23 +343,16 @@ CONFIG_FB_PXA=y
 CONFIG_FB_PXA_OVERLAY=y
 CONFIG_FB_PXA_PARAMETERS=y
 CONFIG_PXA3XX_GCU=m
-CONFIG_FB_MBX=m
 CONFIG_FB_VIRTUAL=m
 CONFIG_FB_SIMPLE=y
-CONFIG_LCD_CORGI=m
-CONFIG_LCD_PLATFORM=m
-CONFIG_BACKLIGHT_PWM=m
-CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_TILEBLITTING=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
 CONFIG_LOGO=y
 CONFIG_SOUND=m
 CONFIG_SND=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
 CONFIG_SND_DYNAMIC_MINORS=y
-CONFIG_SND_VERBOSE_PRINTK=y
 CONFIG_SND_DEBUG=y
 CONFIG_SND_SEQUENCER=m
 CONFIG_SND_USB_AUDIO=m
@@ -413,7 +365,6 @@ CONFIG_SND_SOC_AK4642=m
 CONFIG_SND_SOC_WM8731_I2C=m
 CONFIG_SND_SOC_WM8978=m
 CONFIG_SND_SIMPLE_CARD=m
-CONFIG_SOUND_PRIME=m
 CONFIG_HID=m
 CONFIG_HID_A4TECH=m
 CONFIG_HID_APPLE=m
@@ -498,7 +449,6 @@ CONFIG_USB_LEGOTOWER=m
 CONFIG_USB_LCD=m
 CONFIG_USB_CYTHERM=m
 CONFIG_USB_IDMOUSE=m
-CONFIG_USB_GPIO_VBUS=y
 CONFIG_USB_GPIO_VBUS=m
 CONFIG_USB_ISP1301=m
 CONFIG_USB_GADGET=m
@@ -519,7 +469,6 @@ CONFIG_SDIO_UART=m
 CONFIG_MMC_PXA=m
 CONFIG_MMC_SDHCI=m
 CONFIG_MMC_SDHCI_PLTFM=m
-CONFIG_MMC_TMIO=m
 CONFIG_MMC_DW=m
 CONFIG_MMC_DW_EXYNOS=m
 CONFIG_NEW_LEDS=y
@@ -539,7 +488,6 @@ CONFIG_LEDS_TRIGGER_GPIO=m
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
 CONFIG_LEDS_TRIGGER_TRANSIENT=m
 CONFIG_LEDS_TRIGGER_CAMERA=m
-CONFIG_EDAC=m
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DEBUG=y
 CONFIG_RTC_DRV_DS1307=m
@@ -555,21 +503,18 @@ CONFIG_RTC_DRV_S35390A=m
 CONFIG_RTC_DRV_RX8581=m
 CONFIG_RTC_DRV_EM3027=m
 CONFIG_RTC_DRV_S5M=m
-CONFIG_RTC_DRV_V3020=m
 CONFIG_RTC_DRV_PXA=m
 CONFIG_RTC_DRV_PCAP=m
 CONFIG_DMADEVICES=y
 CONFIG_PXA_DMA=y
 CONFIG_DW_DMAC=m
 CONFIG_UIO=y
-CONFIG_CROS_EC_CHARDEV=m
 CONFIG_CHROME_PLATFORMS=y
 CONFIG_CROS_EC=m
 CONFIG_CROS_EC_I2C=m
 CONFIG_CROS_EC_SPI=m
 CONFIG_COMMON_CLK_S2MPS11=m
 CONFIG_PM_DEVFREQ=y
-CONFIG_EXTCON=y
 CONFIG_MEMORY=y
 CONFIG_IIO=m
 CONFIG_AD5446=m
@@ -587,9 +532,8 @@ CONFIG_XFS_FS=m
 CONFIG_AUTOFS_FS=m
 CONFIG_FUSE_FS=m
 CONFIG_CUSE=m
-CONFIG_FSCACHE=y
 CONFIG_FSCACHE_STATS=y
-CONFIG_CACHEFILES=y
+CONFIG_CACHEFILES=m
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
@@ -623,7 +567,6 @@ CONFIG_NFSD=m
 CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_CIFS=m
-CONFIG_CIFS_STATS=y
 CONFIG_CIFS_XATTR=y
 CONFIG_CIFS_POSIX=y
 CONFIG_NLS_DEFAULT="utf8"
@@ -634,9 +577,7 @@ CONFIG_NLS_ASCII=m
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_UTF8=m
-CONFIG_TIMER_STATS=y
 CONFIG_SECURITY=y
-CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_TEST=m
@@ -644,19 +585,13 @@ CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
 CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_VMAC=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_LZO=y

-- 
2.47.0



From marcus.folkesson at gmail.com  Wed Dec  4 07:56:50 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:50 +0100
Subject: [PATCH 8/9] ARM: qcom_defconfig: rebuild default configuration
In-Reply-To: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
Message-ID: <20241204-defconfigs-v1-8-86587652d37a@gmail.com>

This configuration contains obsolete configuration options e.g.
CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.

Rebuild this configuration by run:
make ARCH=arm qcom_defconfig
make ARCH=arm savedefconfig

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
 arch/arm/configs/qcom_defconfig | 27 +--------------------------
 1 file changed, 1 insertion(+), 26 deletions(-)

diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index ec52ccece0ca7d6471f04ef4a6953f02530655c5..bc58e76eee18a583da4a591d57dcd632eaae862c 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -10,10 +10,6 @@ CONFIG_EXPERT=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_PROFILING=y
 CONFIG_ARCH_QCOM=y
-CONFIG_ARCH_MSM8X60=y
-CONFIG_ARCH_MSM8960=y
-CONFIG_ARCH_MSM8974=y
-CONFIG_ARCH_MDM9615=y
 CONFIG_SMP=y
 CONFIG_ARM_PSCI=y
 CONFIG_HIGHMEM=y
@@ -43,9 +39,6 @@ CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_IPV6 is not set
 CONFIG_QRTR=m
 CONFIG_QRTR_SMD=m
@@ -63,7 +56,6 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_QCOMSMEM_PARTS=y
 CONFIG_MTD_BLOCK=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
@@ -105,7 +97,6 @@ CONFIG_KEYBOARD_PMIC8XXX=y
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_INPUT_MISC=y
-CONFIG_INPUT_MSM_VIBRATOR=m
 CONFIG_INPUT_PM8941_PWRKEY=m
 CONFIG_INPUT_PM8XXX_VIBRATOR=y
 CONFIG_INPUT_PMIC8XXX_PWRKEY=y
@@ -120,7 +111,6 @@ CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_CONSOLE=y
 CONFIG_SERIAL_DEV_BUS=y
 CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_QUP=y
 CONFIG_SPI=y
@@ -139,7 +129,6 @@ CONFIG_PINCTRL_MDM9615=y
 CONFIG_PINCTRL_MSM8X74=y
 CONFIG_PINCTRL_MSM8909=y
 CONFIG_PINCTRL_MSM8916=y
-CONFIG_GPIOLIB=y
 CONFIG_PINCTRL_SDX55=y
 CONFIG_PINCTRL_SDX65=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
@@ -156,7 +145,6 @@ CONFIG_QCOM_WDT=y
 CONFIG_MFD_PM8XXX=y
 CONFIG_MFD_QCOM_RPM=y
 CONFIG_MFD_SPMI_PMIC=y
-CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_QCOM_RPM=y
 CONFIG_REGULATOR_QCOM_RPMH=y
@@ -165,15 +153,13 @@ CONFIG_REGULATOR_QCOM_SPMI=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_DRM=y
 CONFIG_DRM_MSM=m
-CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_PANEL_EDP=y
+CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_ANALOGIX_ANX78XX=m
 CONFIG_FB=y
-# CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_LM3630A=y
 CONFIG_BACKLIGHT_LP855X=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_DYNAMIC_MINORS=y
@@ -187,16 +173,13 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_OTG=y
 CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_MSM=y
 CONFIG_USB_ACM=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_UDC=y
 CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_CHIPIDEA_ULPI=y
 CONFIG_USB_SERIAL=y
 CONFIG_USB_HSIC_USB4604=y
-CONFIG_USB_MSM_OTG=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_VBUS_DRAW=500
@@ -204,7 +187,6 @@ CONFIG_USB_CONFIGFS=y
 CONFIG_USB_CONFIGFS_NCM=y
 CONFIG_USB_CONFIGFS_ECM=y
 CONFIG_USB_CONFIGFS_F_FS=y
-CONFIG_USB_ULPI_BUS=y
 CONFIG_USB_ETH=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
@@ -234,7 +216,6 @@ CONFIG_IPQ_GCC_4019=y
 CONFIG_IPQ_LCC_806X=y
 CONFIG_MSM_GCC_8660=y
 CONFIG_MSM_LCC_8960=y
-CONFIG_MDM_LCC_9615=y
 CONFIG_MSM_MMCC_8960=y
 CONFIG_MSM_MMCC_8974=y
 CONFIG_SDX_GCC_55=y
@@ -245,9 +226,7 @@ CONFIG_QCOM_APCS_IPC=y
 CONFIG_MSM_IOMMU=y
 CONFIG_ARM_SMMU=y
 CONFIG_REMOTEPROC=y
-CONFIG_QCOM_ADSP_PIL=y
 CONFIG_QCOM_Q6V5_PAS=y
-CONFIG_QCOM_Q6V5_PIL=y
 CONFIG_QCOM_WCNSS_PIL=y
 CONFIG_RPMSG_CHAR=y
 CONFIG_RPMSG_CTRL=y
@@ -256,7 +235,6 @@ CONFIG_RPMSG_QCOM_SMD=y
 CONFIG_QCOM_COMMAND_DB=y
 CONFIG_QCOM_GSBI=y
 CONFIG_QCOM_OCMEM=y
-CONFIG_QCOM_PM=y
 CONFIG_QCOM_RMTFS_MEM=y
 CONFIG_QCOM_RPMH=y
 CONFIG_QCOM_SMEM=y
@@ -289,7 +267,6 @@ CONFIG_PHY_QCOM_USB_HS=y
 CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
 CONFIG_PHY_QCOM_USB_HSIC=y
 CONFIG_NVMEM_QCOM_QFPROM=y
-CONFIG_INTERCONNECT=y
 CONFIG_INTERCONNECT_QCOM=y
 CONFIG_INTERCONNECT_QCOM_MSM8974=m
 CONFIG_INTERCONNECT_QCOM_SDX55=m
@@ -298,7 +275,6 @@ CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_UBIFS_FS=y
 CONFIG_NFS_FS=y
@@ -310,7 +286,6 @@ CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_UTF8=y
 CONFIG_CRYPTO_USER=m
-CONFIG_CRYPTO_USER_API=m
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m

-- 
2.47.0



From marcus.folkesson at gmail.com  Wed Dec  4 07:56:42 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:42 +0100
Subject: [PATCH 0/9] Rebuild default configurations for some ARM boards
Message-ID: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>

I was building Yocto for a davinci based board and got the following:

[INFO]: the following symbols were not found in the active configuration:
     - CONFIG_MTD_M25P80
     - CONFIG_DRM_TINYDRM

Both of these configuration options are obsolete in newer kernels.
When searching the tree for other instances of these I found a few in
other defconfig files.

This series is simply a
$ make foo_defconfig
$ make savedefconfig
$ cp defconfig arch/arm/configs/foo_defconfig

for those defconfigs that contained any of the options listed above.

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
Marcus Folkesson (9):
      ARM: axm55xx_defconfig: rebuild default configuration
      ARM: davinci_all_defconfig: rebuild default configuration
      ARM: dove_defconfig: rebuild default configuration
      ARM: keystone_defconfig: rebuild default configuration
      ARM: mvebu_v5_defconfig: rebuild default configuration
      ARM: mxs_defconfig: rebuild default configuration
      ARM: pxa_defconfig: rebuild default configuration
      ARM: qcom_defconfig: rebuild default configuration
      ARM: socfpga_defconfig: rebuild default configuration

 arch/arm/configs/axm55xx_defconfig     | 30 ---------------
 arch/arm/configs/davinci_all_defconfig | 18 ---------
 arch/arm/configs/dove_defconfig        | 11 ------
 arch/arm/configs/keystone_defconfig    | 12 +-----
 arch/arm/configs/mvebu_v5_defconfig    |  8 ----
 arch/arm/configs/mxs_defconfig         | 11 ------
 arch/arm/configs/pxa_defconfig         | 69 +---------------------------------
 arch/arm/configs/qcom_defconfig        | 27 +------------
 arch/arm/configs/socfpga_defconfig     |  3 --
 9 files changed, 4 insertions(+), 185 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241204-defconfigs-706a21dc5e4c

Best regards,
-- 
Marcus Folkesson <marcus.folkesson at gmail.com>



From marcus.folkesson at gmail.com  Wed Dec  4 07:56:43 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:43 +0100
Subject: [PATCH 1/9] ARM: axm55xx_defconfig: rebuild default configuration
In-Reply-To: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
Message-ID: <20241204-defconfigs-v1-1-86587652d37a@gmail.com>

This configuration contains obsolete configuration options e.g.
CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.

Rebuild this configuration by run:
make ARCH=arm axm55xx_defconfig
make ARCH=arm savedefconfig

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
 arch/arm/configs/axm55xx_defconfig | 30 ------------------------------
 1 file changed, 30 deletions(-)

diff --git a/arch/arm/configs/axm55xx_defconfig b/arch/arm/configs/axm55xx_defconfig
index 516689dc6cf16407f2b82370ed08df8da1b5770f..d30e8a350ed26e07af6722666cde763ab3196c85 100644
--- a/arch/arm/configs/axm55xx_defconfig
+++ b/arch/arm/configs/axm55xx_defconfig
@@ -1,6 +1,5 @@
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_AUDIT=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
@@ -27,18 +26,15 @@ CONFIG_ARCH_AXXIA=y
 CONFIG_ARM_LPAE=y
 CONFIG_ARM_THUMBEE=y
 CONFIG_ARM_ERRATA_430973=y
-CONFIG_ARM_ERRATA_643719=y
 CONFIG_ARM_ERRATA_720789=y
 CONFIG_ARM_ERRATA_754322=y
 CONFIG_ARM_ERRATA_754327=y
 CONFIG_ARM_ERRATA_764369=y
 CONFIG_ARM_ERRATA_775420=y
 CONFIG_ARM_ERRATA_798181=y
-CONFIG_PCIE_AXXIA=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=16
 CONFIG_HOTPLUG_CPU=y
-CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
 CONFIG_HIGHMEM=y
 CONFIG_ARM_APPENDED_DTB=y
@@ -85,8 +81,6 @@ CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_M25P80=y
-CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_EEPROM_AT24=y
@@ -94,7 +88,6 @@ CONFIG_EEPROM_AT25=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 CONFIG_ATA=y
-CONFIG_PATA_PLATFORM=y
 CONFIG_PATA_OF_PLATFORM=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_DM=y
@@ -103,7 +96,6 @@ CONFIG_NETDEVICES=y
 CONFIG_TUN=y
 CONFIG_VETH=y
 CONFIG_VIRTIO_NET=y
-# CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_CIRRUS is not set
 # CONFIG_NET_VENDOR_FARADAY is not set
@@ -116,7 +108,6 @@ CONFIG_VIRTIO_NET=y
 # CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
-CONFIG_BROADCOM_PHY=y
 # CONFIG_WLAN is not set
 # CONFIG_MOUSE_PS2_ALPS is not set
 # CONFIG_MOUSE_PS2_LOGIPS2PP is not set
@@ -132,10 +123,8 @@ CONFIG_VIRTIO_CONSOLE=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
-CONFIG_I2C_AXXIA=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
-CONFIG_DP83640_PHY=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PL061=y
@@ -150,10 +139,7 @@ CONFIG_PMBUS=y
 CONFIG_SENSORS_LTC2978=y
 CONFIG_WATCHDOG=y
 CONFIG_ARM_SP805_WATCHDOG=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_HID_A4TECH=y
-CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
 CONFIG_HID_CHERRY=y
 CONFIG_HID_CHICONY=y
@@ -164,7 +150,6 @@ CONFIG_HID_KYE=y
 CONFIG_HID_GYRATION=y
 CONFIG_HID_TWINHAN=y
 CONFIG_HID_KENSINGTON=y
-CONFIG_HID_LOGITECH=y
 CONFIG_HID_MICROSOFT=y
 CONFIG_HID_MONTEREY=y
 CONFIG_HID_NTRIG=y
@@ -182,7 +167,6 @@ CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_EHCI_HCD_AXXIA=y
 CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
@@ -195,18 +179,9 @@ CONFIG_PL320_MBOX=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT4_FS=y
 CONFIG_AUTOFS_FS=y
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=y
-CONFIG_FSCACHE=y
-CONFIG_FSCACHE_STATS=y
-CONFIG_FSCACHE_HISTOGRAM=y
-CONFIG_FSCACHE_DEBUG=y
-CONFIG_FSCACHE_OBJECT_LIST=y
-CONFIG_CACHEFILES=y
-CONFIG_CACHEFILES_HISTOGRAM=y
 CONFIG_ISO9660_FS=y
 CONFIG_UDF_FS=y
 CONFIG_MSDOS_FS=y
@@ -218,19 +193,14 @@ CONFIG_CRAMFS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
-CONFIG_NFS_FSCACHE=y
 CONFIG_SUNRPC_DEBUG=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_CRYPTO_XCBC=y
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
-CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_RCU_CPU_STALL_TIMEOUT=60
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_GCM=y
-CONFIG_CRYPTO_SHA256=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set

-- 
2.47.0



From marcus.folkesson at gmail.com  Wed Dec  4 07:56:44 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:44 +0100
Subject: [PATCH 2/9] ARM: davinci_all_defconfig: rebuild default
 configuration
In-Reply-To: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
Message-ID: <20241204-defconfigs-v1-2-86587652d37a@gmail.com>

This configuration contains obsolete configuration options e.g.
CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.

Rebuild this configuration by run:
make ARCH=arm davinci_all_defconfig
make ARCH=arm savedefconfig

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
 arch/arm/configs/davinci_all_defconfig | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 3474e475373ae89a90bb5af8f11fca2aa9c289dc..6465a56cb51f5cf89b6bb1b00e1ff82707758e6a 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -10,8 +10,6 @@ CONFIG_CGROUPS=y
 CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V5=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_DAVINCI=y
 CONFIG_ARCH_DAVINCI_DA830=y
@@ -19,10 +17,8 @@ CONFIG_ARCH_DAVINCI_DA850=y
 CONFIG_DAVINCI_MUX_DEBUG=y
 CONFIG_DAVINCI_MUX_WARNINGS=y
 CONFIG_AEABI=y
-CONFIG_SECCOMP=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_AUTO_ZRELADDR=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=m
@@ -53,7 +49,6 @@ CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_LL=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_FW_LOADER=m
 CONFIG_DA8XX_MSTPRI=y
 CONFIG_MTD=m
 CONFIG_MTD_TESTS=m
@@ -63,7 +58,6 @@ CONFIG_MTD_CFI=m
 CONFIG_MTD_CFI_INTELEXT=m
 CONFIG_MTD_CFI_AMDSTD=m
 CONFIG_MTD_PHYSMAP=m
-CONFIG_MTD_M25P80=m
 CONFIG_MTD_RAW_NAND=m
 CONFIG_MTD_NAND_DAVINCI=m
 CONFIG_MTD_SPI_NOR=m
@@ -77,7 +71,6 @@ CONFIG_EEPROM_AT24=y
 CONFIG_BLK_DEV_SD=m
 CONFIG_ATA=m
 CONFIG_AHCI_DA850=m
-CONFIG_PATA_BK3710=m
 CONFIG_NETDEVICES=y
 CONFIG_NETCONSOLE=y
 CONFIG_TUN=m
@@ -116,12 +109,10 @@ CONFIG_I2C_DAVINCI=y
 CONFIG_SPI=y
 CONFIG_SPI_DAVINCI=m
 CONFIG_PINCTRL_DA850_PUPD=m
-CONFIG_PINCTRL_SINGLE=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCA953X_IRQ=y
-CONFIG_RESET_CONTROLLER=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_SYSCON_REBOOT_MODE=m
@@ -133,32 +124,26 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_TPS6507X=y
 CONFIG_MEDIA_SUPPORT=m
-CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY=m
 CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE=m
-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_TVP514X=m
 CONFIG_VIDEO_ADV7343=m
 CONFIG_DRM=m
 CONFIG_DRM_TILCDC=m
 CONFIG_DRM_SIMPLE_BRIDGE=m
-CONFIG_DRM_TINYDRM=m
 CONFIG_TINYDRM_ST7586=m
 CONFIG_FB=y
-CONFIG_FB_DA8XX=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_BACKLIGHT_PWM=m
 CONFIG_BACKLIGHT_GPIO=m
-CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 CONFIG_SOUND=m
 CONFIG_SND=m
 CONFIG_SND_USB_AUDIO=m
 CONFIG_SND_SOC=m
-CONFIG_SND_SOC_TLV320AIC3X=m
 CONFIG_SND_SOC_DAVINCI_MCASP=m
 CONFIG_SND_SOC_DAVINCI_EVM=m
 CONFIG_SND_SIMPLE_CARD=m
@@ -204,14 +189,12 @@ CONFIG_MMC_DAVINCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=m
 CONFIG_LEDS_GPIO=m
-CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_OMAP=m
 CONFIG_DMADEVICES=y
-CONFIG_TI_EDMA=y
 CONFIG_COMMON_CLK_PWM=m
 CONFIG_REMOTEPROC=y
 CONFIG_DA8XX_REMOTEPROC=m
@@ -254,5 +237,4 @@ CONFIG_DMA_CMA=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_RT_MUTEXES=y
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_ARM_UNWIND is not set
 CONFIG_DEBUG_USER=y

-- 
2.47.0



From marcus.folkesson at gmail.com  Wed Dec  4 07:56:45 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:45 +0100
Subject: [PATCH 3/9] ARM: dove_defconfig: rebuild default configuration
In-Reply-To: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
Message-ID: <20241204-defconfigs-v1-3-86587652d37a@gmail.com>

This configuration contains obsolete configuration options e.g.
CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.

Rebuild this configuration by run:
make ARCH=arm dove_defconfig
make ARCH=arm savedefconfig

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
 arch/arm/configs/dove_defconfig | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/arch/arm/configs/dove_defconfig b/arch/arm/configs/dove_defconfig
index 2849d17f585660aa8ff6aad5d554c4bb2d794c60..c3e19e6aa6c9d8e40ecee7d97d185909db61b6c2 100644
--- a/arch/arm/configs/dove_defconfig
+++ b/arch/arm/configs/dove_defconfig
@@ -3,11 +3,8 @@ CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_EXPERT=y
-# CONFIG_ARCH_MULTI_V6 is not set
-CONFIG_ARCH_MULTI_V7=y
 CONFIG_ARCH_DOVE=y
 CONFIG_MACH_CM_A510=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
@@ -40,7 +37,6 @@ CONFIG_MTD_CFI_GEOMETRY=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
@@ -53,7 +49,6 @@ CONFIG_ATA=y
 CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
 CONFIG_MV643XX_ETH=y
-# CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_MOUSE_PS2 is not set
@@ -96,8 +91,6 @@ CONFIG_DMADEVICES=y
 CONFIG_MV_XOR=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=y
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_UDF_FS=m
@@ -112,12 +105,9 @@ CONFIG_NLS_CODEPAGE_850=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_ISO8859_2=y
 CONFIG_NLS_UTF8=y
-CONFIG_TIMER_STATS=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TEA=y
 CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_MD4=y
@@ -126,7 +116,6 @@ CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_LZO=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_DEV_MARVELL_CESA=y
 CONFIG_CRC_CCITT=y
 CONFIG_LIBCRC32C=y

-- 
2.47.0



From marcus.folkesson at gmail.com  Wed Dec  4 07:56:46 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:46 +0100
Subject: [PATCH 4/9] ARM: keystone_defconfig: rebuild default configuration
In-Reply-To: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
Message-ID: <20241204-defconfigs-v1-4-86587652d37a@gmail.com>

This configuration contains obsolete configuration options e.g.
CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.

Rebuild this configuration by run:
make ARCH=arm keystone_defconfig
make ARCH=arm savedefconfig

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
 arch/arm/configs/keystone_defconfig | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index c1291ca290b23c7519a0c34ac5951fc0942c45bf..c5682f2728a176c054313f351186f6e548cff8e0 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -11,18 +11,16 @@ CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_SMALL=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_EXPERT=y
 CONFIG_PROFILING=y
 CONFIG_ARCH_KEYSTONE=y
 CONFIG_ARM_LPAE=y
-CONFIG_PCI_KEYSTONE=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
 CONFIG_ARM_PSCI=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_VFP=y
 CONFIG_NEON=y
@@ -62,9 +60,6 @@ CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
 CONFIG_IP_PIMSM_V2=y
 CONFIG_INET_AH=y
 CONFIG_INET_IPCOMP=y
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
 CONFIG_IPV6_SIT=m
 CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_IPV6_SUBTREES=y
@@ -90,7 +85,6 @@ CONFIG_NETFILTER_XT_MATCH_MARK=y
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
-CONFIG_NF_CONNTRACK_IPV4=y
 CONFIG_IP_NF_IPTABLES=y
 CONFIG_IP_NF_MATCH_AH=y
 CONFIG_IP_NF_MATCH_ECN=y
@@ -101,7 +95,6 @@ CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_TARGET_ECN=y
 CONFIG_IP_NF_TARGET_TTL=y
 CONFIG_IP_NF_RAW=y
-CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
 CONFIG_IP6_NF_IPTABLES=m
@@ -117,7 +110,6 @@ CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_PLATRAM=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_DAVINCI=y
 CONFIG_MTD_SPI_NOR=y
@@ -144,7 +136,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
-# CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_DAVINCI=y
 CONFIG_SPI=y
@@ -189,7 +180,6 @@ CONFIG_LEDS_TRIGGER_CPU=y
 CONFIG_LEDS_TRIGGER_ACTIVITY=y
 CONFIG_LEDS_TRIGGER_GPIO=y
 CONFIG_DMADEVICES=y
-CONFIG_TI_EDMA=y
 CONFIG_MAILBOX=y
 CONFIG_TI_MESSAGE_MANAGER=y
 CONFIG_SOC_TI=y

-- 
2.47.0



From marcus.folkesson at gmail.com  Wed Dec  4 07:56:51 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 04 Dec 2024 16:56:51 +0100
Subject: [PATCH 9/9] ARM: socfpga_defconfig: rebuild default configuration
In-Reply-To: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
Message-ID: <20241204-defconfigs-v1-9-86587652d37a@gmail.com>

This configuration contains obsolete configuration options e.g.
CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.

Rebuild this configuration by run:
make ARCH=arm socfpga_defconfig
make ARCH=arm savedefconfig

Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
---
 arch/arm/configs/socfpga_defconfig | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index 294906c8f16e8f4f5f6a4af5770d79a68528fb34..90c3aca7f8afde7db0062e46261ad6def7e8c146 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -41,7 +41,6 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_DENALI_DT=y
 CONFIG_MTD_SPI_NOR=y
@@ -84,7 +83,6 @@ CONFIG_SERIAL_8250_DW=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_DESIGNWARE_CORE=y
-CONFIG_I2C_DESIGNWARE_PLATFORM=y
 CONFIG_SPI=y
 CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_SPI_DESIGNWARE=y
@@ -140,7 +138,6 @@ CONFIG_EXT3_FS=y
 CONFIG_AUTOFS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_NTFS_FS=y
-CONFIG_NTFS_RW=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_NFS_FS=y

-- 
2.47.0



From thierry.reding at gmail.com  Wed Dec  4 07:58:34 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 4 Dec 2024 16:58:34 +0100
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>
References: <20241021061023.2162701-1-0x1207@gmail.com>
 <d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
 <20241128144501.0000619b@gmail.com>
 <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com>
 <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
 <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
 <df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>
Message-ID: <2g2lp3bkadc4wpeslmdoexpidoiqzt7vejar5xhjx5ayt3uox3@dqdyfzn6khn6>

On Wed, Dec 04, 2024 at 02:06:00PM +0000, Robin Murphy wrote:
> On 2024-12-04 1:57 pm, Thierry Reding wrote:
> > On Tue, Dec 03, 2024 at 11:16:37AM +0800, Furong Xu wrote:
> > > On Mon, 2 Dec 2024 18:34:25 -0800, Jakub Kicinski <kuba at kernel.org> wrote:
> > > 
> > > > On Tue, 3 Dec 2024 10:03:31 +0800 Furong Xu wrote:
> > > > > I requested Jon to provide more info about "Tx DMA map failed" in previous
> > > > > reply, and he does not respond yet.
> > > > 
> > > > What does it mean to provide "more info" about a print statement from
> > > > the driver? Is there a Kconfig which he needs to set to get more info?
> > > > Perhaps you should provide a debug patch he can apply on his tree, that
> > > > will print info about (1) which buffer mapping failed (head or frags);
> > > > (2) what the physical address was of the buffer that couldn't be mapped.
> > > 
> > > A debug patch to print info about buffer makes no sense here.
> > > Both Tegra186 Jetson TX2(tegra186-p2771-0000) and Tegra194 Jetson AGX Xavier
> > > (tegra194-p2972-0000) enable IOMMU/SMMU for stmmac in its device-tree node,
> > > buffer info should be investigated with detailed IOMMU/SMMU debug info from
> > > drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c together.
> > > 
> > > I am not an expert in IOMMU, so I cannot help more.
> > > 
> > > Without the help from Jon, our only choice is revert as you said.
> > 
> > I was able to reproduce this locally and I get this splat:
> > 
> > --- >8 ---
> > [  228.179234] WARNING: CPU: 0 PID: 0 at drivers/iommu/io-pgtable-arm.c:346 __arm_lpae_map+0x388/0x4e4
> > [  228.188300] Modules linked in: snd_soc_tegra210_mixer snd_soc_tegra210_admaif snd_soc_tegra_pcm snd_soc_tegra186_asrc snd_soc_tegra210_ope snd_soc_tegra210_adx snd_soc_tegra210_mvc snd_soc_tegra210_dmic snd_soc_tegra186_dspk snd_soc_tegra210_sfc snd_soc_tegra210_amx snd_soc_tegra210_i2s tegra_drm drm_dp_aux_bus cec drm_display_helper drm_client_lib tegra210_adma snd_soc_tegra210_ahub drm_kms_helper snd_hda_codec_hdmi snd_hda_tegra snd_soc_tegra_audio_graph_card at24 snd_hda_codec ina3221 snd_soc_audio_graph_card snd_soc_simple_card_utils tegra_bpmp_thermal tegra_xudc snd_hda_core tegra_aconnect host1x fuse drm backlight ipv6
> > [  228.243750] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S                 6.13.0-rc1-next-20241203 #30
> > [  228.253412] Tainted: [S]=CPU_OUT_OF_SPEC
> > [  228.257336] Hardware name: nvidia NVIDIA P2771-0000-500/NVIDIA P2771-0000-500, BIOS 2025.01-rc3-00040-g36352ae2e68e-dirty 01/01/2025
> > [  228.269239] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > [  228.276205] pc : __arm_lpae_map+0x388/0x4e4
> > [  228.280398] lr : __arm_lpae_map+0x120/0x4e4
> > [  228.284587] sp : ffff8000800037f0
> > [  228.287901] x29: ffff800080003800 x28: 0000000000000002 x27: 0000000000000001
> > [  228.295050] x26: 0000000000000001 x25: 0000000111580000 x24: 0000000000001000
> > [  228.302197] x23: 000000ffffc72000 x22: 0000000000000ec0 x21: 0000000000000003
> > [  228.309342] x20: 0000000000000001 x19: ffff00008574b000 x18: 0000000000000001
> > [  228.316486] x17: 0000000000000000 x16: 0000000000000001 x15: ffff800080003ad0
> > [  228.323631] x14: ffff00008574d000 x13: 0000000000000000 x12: 0000000000000001
> > [  228.330775] x11: 0000000000000001 x10: 0000000000000001 x9 : 0000000000001000
> > [  228.337921] x8 : ffff00008674c390 x7 : ffff00008674c000 x6 : 0000000000000003
> > [  228.345066] x5 : 0000000000000003 x4 : 0000000000000001 x3 : 0000000000000002
> > [  228.352209] x2 : 0000000000000001 x1 : 0000000000000000 x0 : ffff00008574b000
> > [  228.359356] Call trace:
> > [  228.361807]  __arm_lpae_map+0x388/0x4e4 (P)
> > [  228.366002]  __arm_lpae_map+0x120/0x4e4 (L)
> > [  228.370198]  __arm_lpae_map+0x120/0x4e4
> > [  228.374042]  __arm_lpae_map+0x120/0x4e4
> > [  228.377886]  __arm_lpae_map+0x120/0x4e4
> > [  228.381730]  arm_lpae_map_pages+0x108/0x250
> > [  228.385922]  arm_smmu_map_pages+0x40/0x120
> > [  228.390029]  __iommu_map+0xfc/0x1bc
> > [  228.393525]  iommu_map+0x38/0xc0
> > [  228.396759]  __iommu_dma_map+0xb4/0x1a4
> > [  228.400604]  iommu_dma_map_page+0x14c/0x27c
> > [  228.404795]  dma_map_page_attrs+0x1fc/0x280
> > [  228.408987]  stmmac_tso_xmit+0x2d0/0xbac
> > [  228.412920]  stmmac_xmit+0x230/0xd14
> > [  228.416505]  dev_hard_start_xmit+0x94/0x11c
> > [  228.420697]  sch_direct_xmit+0x8c/0x380
> > [  228.424540]  __qdisc_run+0x11c/0x66c
> > [  228.428121]  net_tx_action+0x168/0x228
> > [  228.431875]  handle_softirqs+0x100/0x244
> > [  228.435809]  __do_softirq+0x14/0x20
> > [  228.439303]  ____do_softirq+0x10/0x20
> > [  228.442972]  call_on_irq_stack+0x24/0x64
> > [  228.446903]  do_softirq_own_stack+0x1c/0x40
> > [  228.451091]  __irq_exit_rcu+0xd4/0x10c
> > [  228.454847]  irq_exit_rcu+0x10/0x1c
> > [  228.458343]  el1_interrupt+0x38/0x68
> > [  228.461927]  el1h_64_irq_handler+0x18/0x24
> > [  228.466032]  el1h_64_irq+0x6c/0x70
> > [  228.469438]  default_idle_call+0x28/0x58 (P)
> > [  228.473718]  default_idle_call+0x24/0x58 (L)
> > [  228.477998]  do_idle+0x1fc/0x260
> > [  228.481234]  cpu_startup_entry+0x34/0x3c
> > [  228.485163]  rest_init+0xdc/0xe0
> > [  228.488401]  console_on_rootfs+0x0/0x6c
> > [  228.492250]  __primary_switched+0x88/0x90
> > [  228.496270] ---[ end trace 0000000000000000 ]---
> > [  228.500950] dwc-eth-dwmac 2490000.ethernet: Tx dma map failed
> > --- >8 ---
> > 
> > This looks to be slightly different from what Jon was seeing. Looking at
> > the WARN_ON() that triggers this, it seems like for some reason the page
> > is getting mapped twice.
> > 
> > Not exactly sure why that would be happening, so adding Robin and Will,
> > maybe they can shed some light on this from the ARM SMMU side.
> > 
> > Robin, Will, any idea who could be the culprit here? Is this a map/unmap
> > imbalance or something else entirely?
> 
> If valid PTEs are getting left behind in the pagetable, that would indicate
> that a previous dma_unmap_page() was called with a size smaller than its
> original dma_map_page(). Throwing CONFIG_DMA_API_DEBUG at it should
> hopefully shed more light.

Bull's-eye! DMA_API_DEBUG does flag this:

--- >8 ---
[   60.469121] DMA-API: dwc-eth-dwmac 2490000.ethernet: device driver tries to free DMA memory it has not allocated [device add ress=0x000000ffffcf65c0] [size=66 bytes]
1
[   60.486534] WARNING: CPU: 0 PID: 0 at kernel/dma/debug.c:972 check_unmap+0x564/0x8f0
[   60.494493] Modules linked in: snd_soc_tegra210_admaif snd_soc_tegra_pcm snd_soc_tegra210_ope snd_soc_tegra186_asrc snd_soc_tegra210_amx snd_soc_tegra210_mv
c snd_soc_tegra210_mixer snd_soc_tegra210_dmic snd_soc_tegra210_sfc snd_soc_tegra186_dspk snd_soc_tegra210_i2s snd_soc_tegra210_adx tegra_drm drm_dp_aux_bus ce
c drm_display_helper drm_client_lib drm_kms_helper tegra210_adma snd_soc_tegra210_ahub snd_hda_codec_hdmi snd_soc_tegra_audio_graph_card snd_hda_tegra snd_soc_
audio_graph_card snd_hda_codec snd_soc_simple_card_utils at24 snd_hda_core ina3221 tegra_aconnect tegra_xudc tegra_bpmp_thermal host1x fuse drm backlight ipv6
[   60.549857] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S                 6.13.0-rc1-next-20241203 #31
[   60.559504] Tainted: [S]=CPU_OUT_OF_SPEC
[   60.563423] Hardware name: nvidia NVIDIA P2771-0000-500/NVIDIA P2771-0000-500, BIOS 2025.01-rc3-00040-g36352ae2e68e-dirty 01/01/2025
[   60.575317] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   60.582273] pc : check_unmap+0x564/0x8f0
[   60.586197] lr : check_unmap+0x564/0x8f0
[   60.590117] sp : ffff800080003b50
[   60.593428] x29: ffff800080003b50 x28: ffff0000825309c0 x27: ffff0000825313c0
[   60.600562] x26: 00000000000001b9 x25: 0000000000000001 x24: ffff00008011b410
[   60.607696] x23: ffff800082059ec0 x22: 0000000000000000 x21: ffff8000825b25c8
[   60.614829] x20: ffff800080003bc0 x19: 000000ffffcf65c0 x18: 0000000000000006
[   60.621962] x17: 645b206465746163 x16: 0000000000000000 x15: 0720072007200720
[   60.629095] x14: ffff800082074960 x13: 0720072007200720 x12: 0720072007200720
[   60.636229] x11: ffff800082074960 x10: 0000000000000299 x9 : ffff8000820cc960
[   60.643362] x8 : 0000000000017fe8 x7 : 00000000fffff000 x6 : ffff8000820cc960
[   60.650496] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
[   60.657629] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff800082064900
[   60.664763] Call trace:
[   60.667206]  check_unmap+0x564/0x8f0 (P)
[   60.671131]  check_unmap+0x564/0x8f0 (L)
[   60.675055]  debug_dma_unmap_page+0xac/0xc0
[   60.679239]  dma_unmap_page_attrs+0xf4/0x200
[   60.683508]  stmmac_tx_clean.constprop.0+0x1ac/0x7bc
[   60.688474]  stmmac_napi_poll_tx+0xdc/0x168
[   60.692657]  __napi_poll+0x38/0x180
[   60.696148]  net_rx_action+0x158/0x2c0
[   60.699897]  handle_softirqs+0x100/0x244
[   60.703821]  __do_softirq+0x14/0x20
[   60.707309]  ____do_softirq+0x10/0x20
[   60.710970]  call_on_irq_stack+0x24/0x64
[   60.714891]  do_softirq_own_stack+0x1c/0x40
[   60.719072]  __irq_exit_rcu+0xd4/0x10c
[   60.722821]  irq_exit_rcu+0x10/0x1c
[   60.726308]  el1_interrupt+0x38/0x68
[   60.729886]  el1h_64_irq_handler+0x18/0x24
[   60.733980]  el1h_64_irq+0x6c/0x70
[   60.737381]  default_idle_call+0x28/0x58 (P)
[   60.741652]  default_idle_call+0x24/0x58 (L)
[   60.745920]  do_idle+0x1fc/0x260
[   60.749149]  cpu_startup_entry+0x34/0x3c
[   60.753068]  rest_init+0xdc/0xe0
[   60.756296]  console_on_rootfs+0x0/0x6c
[   60.760135]  __primary_switched+0x88/0x90
[   60.764146] ---[ end trace 0000000000000000 ]---
--- >8 ---

This doesn't match the location from earlier, but at least there's
something afoot here that needs fixing. I suppose this could simply be
hiding any subsequent errors, so once this is fixed we might see other
similar issues.

Furong, I can look into this some more, but I'm not at all familiar with
this part of the driver, so I don't really know where this could be
originating from. Any pointers would be appreciated. Also, if you think
there's anything I should try, I do have this setup that I can test on
locally.

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/20241204/0ad73009/attachment.sig>

From devnull+nikolaos.pasaloukos.blaize.com at kernel.org  Wed Dec  4 08:05:28 2024
From: devnull+nikolaos.pasaloukos.blaize.com at kernel.org (Nikolaos Pasaloukos via B4 Relay)
Date: Wed, 04 Dec 2024 16:05:28 +0000
Subject: [PATCH v5 5/6] arm64: defconfig: Enable Blaize BLZP1600 platform
In-Reply-To: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
Message-ID: <20241204-blaize-blzp1600_init_board_support-v5-5-b642bcc49307@blaize.com>

From: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>

Enable ARCH_BLAIZE to support the BLZP1600 SoC and the CB2
development board.

Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski 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 5fdbfea7a5b295c4569f34773394ffe6eda778e9..4921669f89ae0a89e0c1489a2a4359be9698e5a2 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -44,6 +44,7 @@ CONFIG_ARCH_BCM_IPROC=y
 CONFIG_ARCH_BCMBCA=y
 CONFIG_ARCH_BRCMSTB=y
 CONFIG_ARCH_BERLIN=y
+CONFIG_ARCH_BLAIZE=y
 CONFIG_ARCH_EXYNOS=y
 CONFIG_ARCH_SPARX5=y
 CONFIG_ARCH_K3=y

-- 
2.43.0




From devnull+nikolaos.pasaloukos.blaize.com at kernel.org  Wed Dec  4 08:05:27 2024
From: devnull+nikolaos.pasaloukos.blaize.com at kernel.org (Nikolaos Pasaloukos via B4 Relay)
Date: Wed, 04 Dec 2024 16:05:27 +0000
Subject: [PATCH v5 4/6] arm64: dts: Add initial support for Blaize BLZP1600
 CB2
In-Reply-To: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
Message-ID: <20241204-blaize-blzp1600_init_board_support-v5-4-b642bcc49307@blaize.com>

From: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>

Add support for the Blaize CB2 development board based on
the BLZP1600 SoC. This consists of a Carrier-Board-2 and a
System-on-Module.

Both BLZP1600 SoM and CB2 are available as products.
CB2 (Pathfinder) has multiple peripherals like UART, I2C,
SPI, GPIO, CSI (camera), DSI (display), USB-3.0 and Ethernet.

Enable support for the Cryptocell, UART and I2C which are
already fully supported by the drivers.

The blaize-blzp1600.dtsi is the common part for the SoC,
blaize-blzp1600-som.dtsi is the common part for the SoM and
blaize-blzp1600-cb2.dts is the board specific file.

Co-developed-by: James Cowgill <james.cowgill at blaize.com>
Signed-off-by: James Cowgill <james.cowgill at blaize.com>
Co-developed-by: Matt Redfearn <matt.redfearn at blaize.com>
Signed-off-by: Matt Redfearn <matt.redfearn at blaize.com>
Co-developed-by: Neil Jones <neil.jones at blaize.com>
Signed-off-by: Neil Jones <neil.jones at blaize.com>
Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/boot/dts/Makefile                       |   1 +
 arch/arm64/boot/dts/blaize/Makefile                |   2 +
 arch/arm64/boot/dts/blaize/blaize-blzp1600-cb2.dts |  83 +++++++++
 .../arm64/boot/dts/blaize/blaize-blzp1600-som.dtsi |  23 +++
 arch/arm64/boot/dts/blaize/blaize-blzp1600.dtsi    | 205 +++++++++++++++++++++
 5 files changed, 314 insertions(+)

diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 21cd3a87f385309c3a655a67a3bee5f0abed7545..79b73a21ddc22b17308554e502f8207392935b45 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -10,6 +10,7 @@ subdir-y += apm
 subdir-y += apple
 subdir-y += arm
 subdir-y += bitmain
+subdir-y += blaize
 subdir-y += broadcom
 subdir-y += cavium
 subdir-y += exynos
diff --git a/arch/arm64/boot/dts/blaize/Makefile b/arch/arm64/boot/dts/blaize/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..7e10b3199e6c73b64c826fef1aa4058c7b3e898b
--- /dev/null
+++ b/arch/arm64/boot/dts/blaize/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0+
+dtb-$(CONFIG_ARCH_BLAIZE) += blaize-blzp1600-cb2.dtb
diff --git a/arch/arm64/boot/dts/blaize/blaize-blzp1600-cb2.dts b/arch/arm64/boot/dts/blaize/blaize-blzp1600-cb2.dts
new file mode 100644
index 0000000000000000000000000000000000000000..7e3cef2ed3522e202487e799b2021cd45398e006
--- /dev/null
+++ b/arch/arm64/boot/dts/blaize/blaize-blzp1600-cb2.dts
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024 Blaize, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "blaize-blzp1600-som.dtsi"
+
+/ {
+	model = "Blaize BLZP1600 SoM1600P CB2 Development Board";
+
+	compatible = "blaize,blzp1600-cb2", "blaize,blzp1600";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200";
+	};
+};
+
+&i2c0 {
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&i2c3 {
+	clock-frequency = <100000>;
+	status = "okay";
+
+	gpio_expander: gpio at 74 {
+		compatible = "ti,tca9539";
+		reg = <0x74>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "RSP_PIN_7",	/* GPIO_0 */
+				  "RSP_PIN_11",	/* GPIO_1 */
+				  "RSP_PIN_13",	/* GPIO_2 */
+				  "RSP_PIN_15",	/* GPIO_3 */
+				  "RSP_PIN_27",	/* GPIO_4 */
+				  "RSP_PIN_29",	/* GPIO_5 */
+				  "RSP_PIN_31",	/* GPIO_6 */
+				  "RSP_PIN_33",	/* GPIO_7 */
+				  "RSP_PIN_37",	/* GPIO_8 */
+				  "RSP_PIN_16",	/* GPIO_9 */
+				  "RSP_PIN_18",	/* GPIO_10 */
+				  "RSP_PIN_22",	/* GPIO_11 */
+				  "RSP_PIN_28",	/* GPIO_12 */
+				  "RSP_PIN_32",	/* GPIO_13 */
+				  "RSP_PIN_36",	/* GPIO_14 */
+				  "TP31";	/* GPIO_15 */
+	};
+
+	gpio_expander_m2: gpio at 75 {
+		compatible = "ti,tca9539";
+		reg = <0x75>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "M2_W_DIS1_N",	/* GPIO_0 */
+				  "M2_W_DIS2_N",	/* GPIO_1 */
+				  "M2_UART_WAKE_N",	/* GPIO_2 */
+				  "M2_COEX3",		/* GPIO_3 */
+				  "M2_COEX_RXD",	/* GPIO_4 */
+				  "M2_COEX_TXD",	/* GPIO_5 */
+				  "M2_VENDOR_PIN40",	/* GPIO_6 */
+				  "M2_VENDOR_PIN42",	/* GPIO_7 */
+				  "M2_VENDOR_PIN38",	/* GPIO_8 */
+				  "M2_SDIO_RST_N",	/* GPIO_9 */
+				  "M2_SDIO_WAKE_N",	/* GPIO_10 */
+				  "M2_PETN1",		/* GPIO_11 */
+				  "M2_PERP1",		/* GPIO_12 */
+				  "M2_PERN1",		/* GPIO_13 */
+				  "UIM_SWP",		/* GPIO_14 */
+				  "UART1_TO_RSP";	/* GPIO_15 */
+	};
+};
diff --git a/arch/arm64/boot/dts/blaize/blaize-blzp1600-som.dtsi b/arch/arm64/boot/dts/blaize/blaize-blzp1600-som.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..bfdff5953edd95341440aa98569a019adcc0425d
--- /dev/null
+++ b/arch/arm64/boot/dts/blaize/blaize-blzp1600-som.dtsi
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024 Blaize, Inc. All rights reserved.
+ */
+
+#include "blaize-blzp1600.dtsi"
+
+/ {
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x1 0x0>;
+	};
+};
+
+/* i2c4 bus is available only on the SoM, not on the board */
+&i2c4 {
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/blaize/blaize-blzp1600.dtsi b/arch/arm64/boot/dts/blaize/blaize-blzp1600.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..7d399e6a532f5b24385dd837be965be771c7d24c
--- /dev/null
+++ b/arch/arm64/boot/dts/blaize/blaize-blzp1600.dtsi
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024 Blaize, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			compatible = "arm,cortex-a53";
+			reg = <0x0 0x0>;
+			device_type = "cpu";
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+		};
+
+		cpu1: cpu at 1 {
+			compatible = "arm,cortex-a53";
+			reg = <0x0 0x1>;
+			device_type = "cpu";
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+		};
+
+		l2: l2-cache0 {
+			compatible = "cache";
+			cache-level = <2>;
+			cache-unified;
+		};
+	};
+
+	firmware {
+		scmi {
+			compatible = "arm,scmi-smc";
+			arm,smc-id = <0x82002000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			shmem = <&scmi0_shm>;
+
+			scmi_clk: protocol at 14 {
+				reg = <0x14>;
+				#clock-cells = <1>;
+			};
+
+			scmi_rst: protocol at 16 {
+				reg = <0x16>;
+				#reset-cells = <1>;
+			};
+		};
+	};
+
+	pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* SCMI reserved buffer space on DDR space */
+		scmi0_shm: scmi-shmem at 800 {
+			compatible = "arm,scmi-shmem";
+			reg = <0x0 0x800 0x0 0x80>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = /* Physical Secure PPI */
+			     <GIC_PPI 13 (GIC_CPU_MASK_RAW(0x3) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+			     /* Physical Non-Secure PPI */
+			     <GIC_PPI 14 (GIC_CPU_MASK_RAW(0x3) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+			     /* Hypervisor PPI */
+			     <GIC_PPI 10 (GIC_CPU_MASK_RAW(0x3) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+			     /* Virtual PPI */
+			     <GIC_PPI 11 (GIC_CPU_MASK_RAW(0x3) |
+					  IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	soc at 200000000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x2 0x0 0x850000>;
+
+		gic: interrupt-controller at 410000 {
+			compatible = "arm,gic-400";
+			reg = <0x410000 0x20000>,
+			      <0x420000 0x20000>,
+			      <0x440000 0x20000>,
+			      <0x460000 0x20000>;
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_RAW(0x3) |
+						 IRQ_TYPE_LEVEL_LOW)>;
+		};
+
+		uart0: serial at 4d0000 {
+			compatible = "ns16550a";
+			reg = <0x4d0000 0x1000>;
+			clocks = <&scmi_clk 59>;
+			resets = <&scmi_rst 59>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart1: serial at 4e0000 {
+			compatible = "ns16550a";
+			reg = <0x4e0000 0x1000>;
+			clocks = <&scmi_clk 60>;
+			resets = <&scmi_rst 60>;
+			reg-shift = <2>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		i2c0: i2c at 4f0000 {
+			compatible = "snps,designware-i2c";
+			reg = <0x4f0000 0x1000>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&scmi_clk 54>;
+			resets = <&scmi_rst 54>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c1: i2c at 500000 {
+			compatible = "snps,designware-i2c";
+			reg = <0x500000 0x1000>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&scmi_clk 55>;
+			resets = <&scmi_rst 55>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c2: i2c at 510000 {
+			compatible = "snps,designware-i2c";
+			reg = <0x510000 0x1000>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&scmi_clk 56>;
+			resets = <&scmi_rst 56>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c3: i2c at 520000 {
+			compatible = "snps,designware-i2c";
+			reg = <0x520000 0x1000>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&scmi_clk 57>;
+			resets = <&scmi_rst 57>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c4: i2c at 530000 {
+			compatible = "snps,designware-i2c";
+			reg = <0x530000 0x1000>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&scmi_clk 58>;
+			resets = <&scmi_rst 58>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		arm_cc712: crypto at 550000 {
+			compatible = "arm,cryptocell-712-ree";
+			reg = <0x550000 0x1000>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&scmi_clk 7>;
+		};
+	};
+};

-- 
2.43.0




From devnull+nikolaos.pasaloukos.blaize.com at kernel.org  Wed Dec  4 08:05:23 2024
From: devnull+nikolaos.pasaloukos.blaize.com at kernel.org (Nikolaos Pasaloukos via B4 Relay)
Date: Wed, 04 Dec 2024 16:05:23 +0000
Subject: [PATCH v5 0/6] Add support for Blaize BLZP1600 SoC
Message-ID: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>

Blaize, Inc. (www.blaize.com) is a SoC designer and manufacturer
with integrated programmable Graph-Streaming-Processors for AI
and ML. This series adds support for the Blaize BLZP1600 SoC.

The SoC can run as either a PCIe based accelerator in a host
system, or as a stand alone SoC running Linux on its integrated
dual core ARM Cortex A53 cluster.

The SoC includes a suite of peripherals, support for which will
be added later.

This first series is just the basics to get the upstream
kernel to boot with a UART console and ARM SCMI based
clocks and resets.

Resending V5 with tags applied and 'From' fixed.

V5 changes:
 * Add more information on patches and on files
 * Rename arch to ARCH_BLAIZE

V4 changes:
 * Add maintainer for blaize in arm64 dts
 * Fix Blaize schema & dts code style
 * Add range and reserved-memory as suggested

V3 changes:
 * Removed unnecessary dt-bindings
 * Update SoBs

V2 changes:
 * Update SoBs
 * `make dtbs_check` has no warnings
 * Fix dts names and removed dead code
 * DTS is separated from anything else

Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
---
Nikolaos Pasaloukos (6):
      dt-bindings: Add Blaize vendor prefix
      dt-bindings: arm: blaize: Add Blaize BLZP1600 SoC
      arm64: Add Blaize BLZP1600 SoC family
      arm64: dts: Add initial support for Blaize BLZP1600 CB2
      arm64: defconfig: Enable Blaize BLZP1600 platform
      MAINTAINER: Add entry for Blaize SoC

 Documentation/devicetree/bindings/arm/blaize.yaml  |  40 ++++
 .../devicetree/bindings/vendor-prefixes.yaml       |   2 +
 MAINTAINERS                                        |   9 +
 arch/arm64/Kconfig.platforms                       |   5 +
 arch/arm64/boot/dts/Makefile                       |   1 +
 arch/arm64/boot/dts/blaize/Makefile                |   2 +
 arch/arm64/boot/dts/blaize/blaize-blzp1600-cb2.dts |  83 +++++++++
 .../arm64/boot/dts/blaize/blaize-blzp1600-som.dtsi |  23 +++
 arch/arm64/boot/dts/blaize/blaize-blzp1600.dtsi    | 205 +++++++++++++++++++++
 arch/arm64/configs/defconfig                       |   1 +
 10 files changed, 371 insertions(+)
---
base-commit: 83d67c257f4d045ff477309b5617d931f9a7be66
change-id: 20241111-blaize-blzp1600_init_board_support-1128194ca976

Best regards,
-- 
Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>




From devnull+nikolaos.pasaloukos.blaize.com at kernel.org  Wed Dec  4 08:05:24 2024
From: devnull+nikolaos.pasaloukos.blaize.com at kernel.org (Nikolaos Pasaloukos via B4 Relay)
Date: Wed, 04 Dec 2024 16:05:24 +0000
Subject: [PATCH v5 1/6] dt-bindings: Add Blaize vendor prefix
In-Reply-To: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
Message-ID: <20241204-blaize-blzp1600_init_board_support-v5-1-b642bcc49307@blaize.com>

From: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>

Blaize, Inc. (www.blaize.com) is a SoC manufacturer with integrated
programmable Graph-Streaming-Processors for AI and ML.

Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index b320a39de7fe40ce4d97ed3ea264a5971a3428dd..809086061a1992567ca6c5d404fbcee8a33ee300 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -216,6 +216,8 @@ patternProperties:
     description: Shenzhen BigTree Tech Co., LTD
   "^bitmain,.*":
     description: Bitmain Technologies
+  "^blaize,.*":
+    description: Blaize, Inc.
   "^blutek,.*":
     description: BluTek Power
   "^boe,.*":

-- 
2.43.0




From devnull+nikolaos.pasaloukos.blaize.com at kernel.org  Wed Dec  4 08:05:25 2024
From: devnull+nikolaos.pasaloukos.blaize.com at kernel.org (Nikolaos Pasaloukos via B4 Relay)
Date: Wed, 04 Dec 2024 16:05:25 +0000
Subject: [PATCH v5 2/6] dt-bindings: arm: blaize: Add Blaize BLZP1600 SoC
In-Reply-To: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
Message-ID: <20241204-blaize-blzp1600_init_board_support-v5-2-b642bcc49307@blaize.com>

From: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>

Add device tree bindings for the Blaize BLZP1600 CB2 development
board (carrier board). This board integrates a Blaize BLZP1600
SoM (System on Module) which is based on the Blaize BLZP1600 SoC.

The Blaize BLZP1600 SoC integrates a dual core ARM Cortex A53
cluster and a Blaize Graph Streaming Processor for AI and ML
workloads, plus a suite of connectivity and other peripherals.

Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
Reviewed-by: Matt Redfearn <matt.redfearn at blaize.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/blaize.yaml | 40 +++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/blaize.yaml b/Documentation/devicetree/bindings/arm/blaize.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..af39e2756407baacee3030f6909cf2aa7dc5776c
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/blaize.yaml
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/blaize.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Blaize Platforms
+
+maintainers:
+  - James Cowgill <james.cowgill at blaize.com>
+  - Matt Redfearn <matt.redfearn at blaize.com>
+  - Neil Jones <neil.jones at blaize.com>
+  - Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
+
+description: |
+  Blaize Platforms using SoCs designed by Blaize Inc.
+
+  The products based on the BLZP1600 SoC:
+
+  - BLZP1600-SoM: SoM (System on Module)
+  - BLZP1600-CB2: Development board CB2 based on BLZP1600-SoM
+
+  BLZP1600 SoC integrates a dual core ARM Cortex A53 cluster
+  and a Blaize Graph Streaming Processor for AI and ML workloads,
+  plus a suite of connectivity and other peripherals.
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+      - description: Blaize BLZP1600 based boards
+        items:
+          - enum:
+              - blaize,blzp1600-cb2
+          - const: blaize,blzp1600
+
+additionalProperties: true
+
+...

-- 
2.43.0




From yang at os.amperecomputing.com  Wed Dec  4 08:00:16 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Wed, 4 Dec 2024 08:00:16 -0800
Subject: [GIT PULL] arm64 updates for 6.13-rc1
In-Reply-To: <Z1B6OMqEZitgBVEx@arm.com>
References: <20241118100623.2674026-1-catalin.marinas@arm.com>
 <Z0STR6VLt2MCalnY@sashalap> <Z0TLhc3uxa5RnK64@arm.com>
 <0c09425b-c8ba-4ed6-b429-0bce4e7d00e9@os.amperecomputing.com>
 <Z0dhc-DtVsvufv-E@arm.com>
 <dc5e8809-825f-4c38-b487-b16c7d516311@os.amperecomputing.com>
 <e6b3e6c7-193d-43c4-a8c6-6023458723dd@redhat.com>
 <6aec1d44-4a89-4acf-a16b-4493626b93bb@os.amperecomputing.com>
 <Z1B1VS8PayXsXDzl@arm.com> <4919faec-3e35-459f-a7d3-b5b3f188bd9c@redhat.com>
 <Z1B6OMqEZitgBVEx@arm.com>
Message-ID: <5f99ff7d-67dc-41da-8a90-a1a5e76b8daa@os.amperecomputing.com>



On 12/4/24 7:50 AM, Catalin Marinas wrote:
> On Wed, Dec 04, 2024 at 04:32:11PM +0100, David Hildenbrand wrote:
>> On 04.12.24 16:29, Catalin Marinas wrote:
>>> On Mon, Dec 02, 2024 at 08:22:57AM -0800, Yang Shi wrote:
>>>> On 11/28/24 1:56 AM, David Hildenbrand wrote:
>>>>> On 28.11.24 02:21, Yang Shi wrote:
>>>>>>>> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
>>>>>>>> index 87b3f1a25535..ef303a2262c5 100644
>>>>>>>> --- a/arch/arm64/mm/copypage.c
>>>>>>>> +++ b/arch/arm64/mm/copypage.c
>>>>>>>> @@ -30,9 +30,9 @@ void copy_highpage(struct page *to, struct
>>>>>>>> page *from)
>>>>>>>>   ??????? if (!system_supports_mte())
>>>>>>>>   ??????????? return;
>>>>>>>> -??? if (folio_test_hugetlb(src) &&
>>>>>>>> -??????? folio_test_hugetlb_mte_tagged(src)) {
>>>>>>>> -??????? if (!folio_try_hugetlb_mte_tagging(dst))
>>>>>>>> +??? if (folio_test_hugetlb(src)) {
>>>>>>>> +??????? if (!folio_test_hugetlb_mte_tagged(src) ||
>>>>>>>> +??????????? !folio_try_hugetlb_mte_tagging(dst))
>>>>>>>>   ??????????????? return;
>>>>>>>>   ??????????? /*
>>>>>>> I wonder why we had a 'return' here originally rather than a
>>>>>>> WARN_ON_ONCE() as we do further down for the page case. Do you seen any
>>>>>>> issue with the hunk below? Destination should be a new folio and not
>>>>>>> tagged yet:
>>>>>> Yes, I did see problem. Because we copy tags for all sub pages then set
>>>>>> folio mte tagged when copying the data for the first subpage. The
>>>>>> warning will be triggered when we copy the second subpage.
>>>>> It's rather weird, though. We're instructed to copy a single page, yet
>>>>> copy tags for all pages.
>>>>>
>>>>> This really only makes sense when called from folio_copy(), where we are
>>>>> guaranteed to copy all pages.
>>>>>
>>>>> I'm starting to wonder if we should be able to hook into / overload
>>>>> folio_copy() instead, to just handle the complete hugetlb copy ourselves
>>>>> in one shot, and assume that copy_highpage() will never be called for
>>>>> hugetlb pages (WARN and don't copy tags).
>>>> Actually folio_copy() is just called by migration. Copy huge page in CoW is
>>>> more complicated and uses copy_user_highpage()->copy_highpage() instead of
>>>> folio_copy(). It may start the page copy from any subpage. For example, if
>>>> the CoW is triggered by accessing to the address in the middle of 2M. Kernel
>>>> may copy the second half first then the first half to guarantee the accessed
>>>> data in cache.
>>> Still trying to understand the possible call paths here. If we get a
>>> write fault on a large folio, does the core code allocate a folio of the
>>> same size for CoW or it starts with smaller ones? wp_page_copy()
>>> allocates order 0 AFAICT, though if it was a pmd fault, it takes a
>>> different path in handle_mm_fault(). But we also have huge pages using
>>> contiguous ptes.
>>>
>>> Unless the source and destinations folios are exactly the same size, it
>>> will break many assumptions in the code above. Going the other way
>>> around is also wrong, dst larger than src, we are not initialising the
>>> whole dst folio.
>>>
>>> Maybe going back to per-page PG_mte_tagged flag rather than per-folio
>>> would keep things simple, less risk of wrong assumptions.
>> I think the magic bit here is that for hugetlb, we only get hugetlb folios
>> of the same size, and no mixtures.

Yes, hugetlb always allocates the same order folio for CoW. And hugetlb 
CoW path is:

handle_mm_fault() ->
 ? hugetlb_fault() ->
 ??? hugetlb_wp()

> Ah, ok, we do check for this and only do the advance copy for hugetlb
> folios. I'd add a check for folio size just in case, something like
> below (I'll add some description and post it properly):
>
> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
> index 87b3f1a25535..c3a83db46ec6 100644
> --- a/arch/arm64/mm/copypage.c
> +++ b/arch/arm64/mm/copypage.c
> @@ -30,11 +30,14 @@ void copy_highpage(struct page *to, struct page *from)
>   	if (!system_supports_mte())
>   		return;
>   
> -	if (folio_test_hugetlb(src) &&
> -	    folio_test_hugetlb_mte_tagged(src)) {
> -		if (!folio_try_hugetlb_mte_tagging(dst))
> +	if (folio_test_hugetlb(src)) {
> +		if (!folio_test_hugetlb_mte_tagged(src) ||
> +		    from != folio_page(src, 0) ||
> +		    WARN_ON_ONCE(folio_nr_pages(src) != folio_nr_pages(dst)))

The check is ok, but TBH I don't see too much benefit. The same order is 
guaranteed by hugetlb fault handler. And I don't think we will support 
mixed order for hugetlb in foreseeable future.

>   			return;
>   
> +		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
> +
>   		/*
>   		 * Populate tags for all subpages.
>   		 *
>



From andrew at lunn.ch  Wed Dec  4 08:04:25 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 4 Dec 2024 17:04:25 +0100
Subject: [PATCH 5/9] ARM: mvebu_v5_defconfig: rebuild default
 configuration
In-Reply-To: <20241204-defconfigs-v1-5-86587652d37a@gmail.com>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
 <20241204-defconfigs-v1-5-86587652d37a@gmail.com>
Message-ID: <303c44ca-879c-477c-a96c-9741bf3bf31a@lunn.ch>

On Wed, Dec 04, 2024 at 04:56:47PM +0100, Marcus Folkesson wrote:
> This configuration contains obsolete configuration options e.g.
> CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.
> 
> Rebuild this configuration by run:
> make ARCH=arm mvebu_v5_defconfig
> make ARCH=arm savedefconfig
> 
> Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>

You probably want to wait until Arnd big removal patchset lands,
because this is going to be immediately outdated.

     Andrew


From linux at armlinux.org.uk  Wed Dec  4 08:06:25 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Dec 2024 16:06:25 +0000
Subject: arm allmodconfig build issue with bpf
In-Reply-To: <9950a25d-1a79-42c9-ade7-dc51ef569ad2@oracle.com>
References: <9950a25d-1a79-42c9-ade7-dc51ef569ad2@oracle.com>
Message-ID: <Z1B-AVPdkMiSyY-H@shell.armlinux.org.uk>

On Wed, Dec 04, 2024 at 03:54:30PM +0000, John Garry wrote:
> Hi all,
> 
> For some time, the arm allmodconfig build has had this following build issue
> for me:
> 
> $ make net/bpf/test_run.o
>   CALL    scripts/checksyscalls.sh
>   CC      net/bpf/test_run.o
> net/bpf/test_run.c:522:1: error: ?retain? attribute ignored
> [-Werror=attributes]
>   522 | {
>       | ^
> net/bpf/test_run.c:568:1: error: ?retain? attribute ignored
> [-Werror=attributes]
>   568 | {
>       | ^
> net/bpf/test_run.c:577:1: error: ?retain? attribute ignored
> [-Werror=attributes]
>   577 | {
>       | ^
> net/bpf/test_run.c:584:1: error: ?retain? attribute ignored
> [-Werror=attributes]
>   584 | {
>       | ^
> net/bpf/test_run.c:590:1: error: ?retain? attribute ignored
> [-Werror=attributes]
>   590 | {
>       | ^
> net/bpf/test_run.c:619:1: error: ?retain? attribute ignored
> [-Werror=attributes]
>   619 | {
>       | ^
> net/bpf/test_run.c:624:1: error: ?retain? attribute ignored
> [-Werror=attributes]
>   624 | {
>       | ^
> net/bpf/test_run.c:630:1: error: ?retain? attribute ignored
> [-Werror=attributes]
>   630 | {
>       | ^
> net/bpf/test_run.c:634:1: error: ?retain? attribute ignored
> [-Werror=attributes]
>   634 | {
>       | ^
> cc1: all warnings being treated as errors
> make[4]: *** [scripts/Makefile.build:194: net/bpf/test_run.o] Error 1
> make[3]: *** [scripts/Makefile.build:440: net/bpf] Error 2
> make[2]: *** [scripts/Makefile.build:440: net] Error 2
> make[1]: *** [/home/ubuntu/mnt/linux2/Makefile:1989: .] Error 2
> make: *** [Makefile:251: __sub-make] Error 2
> ubuntu at jgarry-ubuntu-bm5-instance-20230215-1843:~/mnt/linux2$
> 
> The issue comes the definition of __bpf_kfunc from include/linux/btf.h

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99587

seems relevant. Jakub's reply in comment 3 suggests that:

#if __has_attribute(__retain__) && \
        (defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || \
         defined(CONFIG_LTO_CLANG))
# define __retain                       __attribute__((__retain__))
#else
# define __retain
#endif

is wrong - __has_attribute(__retain__) doesn't mean that GCC supports
__retain__, it only means that it "knows" about it but may still
reject it.

The nice thing about this bug is... it's remained "NEW" for three
years already, so likely means that it remains unfixed.

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


From devnull+nikolaos.pasaloukos.blaize.com at kernel.org  Wed Dec  4 08:05:29 2024
From: devnull+nikolaos.pasaloukos.blaize.com at kernel.org (Nikolaos Pasaloukos via B4 Relay)
Date: Wed, 04 Dec 2024 16:05:29 +0000
Subject: [PATCH v5 6/6] MAINTAINER: Add entry for Blaize SoC
In-Reply-To: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
Message-ID: <20241204-blaize-blzp1600_init_board_support-v5-6-b642bcc49307@blaize.com>

From: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>

Add MAINTAINERS entry for Blaize SoC platform with a list of
maintainers.

Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 273a84483b74543b510de7b08804bbd1f6514358..43846a23f9d990ae9fe066e65ed2bdd36376e327 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2238,6 +2238,15 @@ F:	arch/arm64/boot/dts/bitmain/
 F:	drivers/clk/clk-bm1880.c
 F:	drivers/pinctrl/pinctrl-bm1880.c
 
+ARM/BLAIZE ARCHITECTURE
+M:	James Cowgill <james.cowgill at blaize.com>
+M:	Matt Redfearn <matt.redfearn at blaize.com>
+M:	Neil Jones <neil.jones at blaize.com>
+M:	Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/arm/blaize.yaml
+F:	arch/arm64/boot/dts/blaize/
+
 ARM/CALXEDA HIGHBANK ARCHITECTURE
 M:	Andre Przywara <andre.przywara at arm.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)

-- 
2.43.0




From devnull+nikolaos.pasaloukos.blaize.com at kernel.org  Wed Dec  4 08:05:26 2024
From: devnull+nikolaos.pasaloukos.blaize.com at kernel.org (Nikolaos Pasaloukos via B4 Relay)
Date: Wed, 04 Dec 2024 16:05:26 +0000
Subject: [PATCH v5 3/6] arm64: Add Blaize BLZP1600 SoC family
In-Reply-To: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
Message-ID: <20241204-blaize-blzp1600_init_board_support-v5-3-b642bcc49307@blaize.com>

From: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>

Add ARCH_BLAIZE SoC family to the arm64 architecture to
support the BLZP1600 System-On-Module and the Carrier-Board-2
development board.

Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
Reviewed-by: Matt Redfearn <matt.redfearn at blaize.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/Kconfig.platforms | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 6c6d11536b42ec6e878db8d355c17994c2500d7b..08dd5b3b2d7381a01bd5c4347c29202edff3495f 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -101,6 +101,11 @@ config ARCH_BITMAIN
 	help
 	  This enables support for the Bitmain SoC Family.
 
+config ARCH_BLAIZE
+	bool "Blaize SoC Platforms"
+	help
+	  This enables support for the Blaize SoC family
+
 config ARCH_EXYNOS
 	bool "Samsung Exynos SoC family"
 	select COMMON_CLK_SAMSUNG

-- 
2.43.0




From david at redhat.com  Wed Dec  4 08:00:53 2024
From: david at redhat.com (David Hildenbrand)
Date: Wed, 4 Dec 2024 17:00:53 +0100
Subject: [GIT PULL] arm64 updates for 6.13-rc1
In-Reply-To: <Z1B6OMqEZitgBVEx@arm.com>
References: <20241118100623.2674026-1-catalin.marinas@arm.com>
 <Z0STR6VLt2MCalnY@sashalap> <Z0TLhc3uxa5RnK64@arm.com>
 <0c09425b-c8ba-4ed6-b429-0bce4e7d00e9@os.amperecomputing.com>
 <Z0dhc-DtVsvufv-E@arm.com>
 <dc5e8809-825f-4c38-b487-b16c7d516311@os.amperecomputing.com>
 <e6b3e6c7-193d-43c4-a8c6-6023458723dd@redhat.com>
 <6aec1d44-4a89-4acf-a16b-4493626b93bb@os.amperecomputing.com>
 <Z1B1VS8PayXsXDzl@arm.com> <4919faec-3e35-459f-a7d3-b5b3f188bd9c@redhat.com>
 <Z1B6OMqEZitgBVEx@arm.com>
Message-ID: <f7e0029e-f940-4f08-84f4-e89450d3e981@redhat.com>

On 04.12.24 16:50, Catalin Marinas wrote:
> On Wed, Dec 04, 2024 at 04:32:11PM +0100, David Hildenbrand wrote:
>> On 04.12.24 16:29, Catalin Marinas wrote:
>>> On Mon, Dec 02, 2024 at 08:22:57AM -0800, Yang Shi wrote:
>>>> On 11/28/24 1:56 AM, David Hildenbrand wrote:
>>>>> On 28.11.24 02:21, Yang Shi wrote:
>>>>>>>> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
>>>>>>>> index 87b3f1a25535..ef303a2262c5 100644
>>>>>>>> --- a/arch/arm64/mm/copypage.c
>>>>>>>> +++ b/arch/arm64/mm/copypage.c
>>>>>>>> @@ -30,9 +30,9 @@ void copy_highpage(struct page *to, struct
>>>>>>>> page *from)
>>>>>>>>   ??????? if (!system_supports_mte())
>>>>>>>>   ??????????? return;
>>>>>>>> -??? if (folio_test_hugetlb(src) &&
>>>>>>>> -??????? folio_test_hugetlb_mte_tagged(src)) {
>>>>>>>> -??????? if (!folio_try_hugetlb_mte_tagging(dst))
>>>>>>>> +??? if (folio_test_hugetlb(src)) {
>>>>>>>> +??????? if (!folio_test_hugetlb_mte_tagged(src) ||
>>>>>>>> +??????????? !folio_try_hugetlb_mte_tagging(dst))
>>>>>>>>   ??????????????? return;
>>>>>>>>   ??????????? /*
>>>>>>> I wonder why we had a 'return' here originally rather than a
>>>>>>> WARN_ON_ONCE() as we do further down for the page case. Do you seen any
>>>>>>> issue with the hunk below? Destination should be a new folio and not
>>>>>>> tagged yet:
>>>>>>
>>>>>> Yes, I did see problem. Because we copy tags for all sub pages then set
>>>>>> folio mte tagged when copying the data for the first subpage. The
>>>>>> warning will be triggered when we copy the second subpage.
>>>>>
>>>>> It's rather weird, though. We're instructed to copy a single page, yet
>>>>> copy tags for all pages.
>>>>>
>>>>> This really only makes sense when called from folio_copy(), where we are
>>>>> guaranteed to copy all pages.
>>>>>
>>>>> I'm starting to wonder if we should be able to hook into / overload
>>>>> folio_copy() instead, to just handle the complete hugetlb copy ourselves
>>>>> in one shot, and assume that copy_highpage() will never be called for
>>>>> hugetlb pages (WARN and don't copy tags).
>>>>
>>>> Actually folio_copy() is just called by migration. Copy huge page in CoW is
>>>> more complicated and uses copy_user_highpage()->copy_highpage() instead of
>>>> folio_copy(). It may start the page copy from any subpage. For example, if
>>>> the CoW is triggered by accessing to the address in the middle of 2M. Kernel
>>>> may copy the second half first then the first half to guarantee the accessed
>>>> data in cache.
>>>
>>> Still trying to understand the possible call paths here. If we get a
>>> write fault on a large folio, does the core code allocate a folio of the
>>> same size for CoW or it starts with smaller ones? wp_page_copy()
>>> allocates order 0 AFAICT, though if it was a pmd fault, it takes a
>>> different path in handle_mm_fault(). But we also have huge pages using
>>> contiguous ptes.
>>>
>>> Unless the source and destinations folios are exactly the same size, it
>>> will break many assumptions in the code above. Going the other way
>>> around is also wrong, dst larger than src, we are not initialising the
>>> whole dst folio.
>>>
>>> Maybe going back to per-page PG_mte_tagged flag rather than per-folio
>>> would keep things simple, less risk of wrong assumptions.
>>
>> I think the magic bit here is that for hugetlb, we only get hugetlb folios
>> of the same size, and no mixtures.
> 
> Ah, ok, we do check for this and only do the advance copy for hugetlb
> folios. I'd add a check for folio size just in case, something like
> below (I'll add some description and post it properly):
> 
> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
> index 87b3f1a25535..c3a83db46ec6 100644
> --- a/arch/arm64/mm/copypage.c
> +++ b/arch/arm64/mm/copypage.c
> @@ -30,11 +30,14 @@ void copy_highpage(struct page *to, struct page *from)
>   	if (!system_supports_mte())
>   		return;
>   
> -	if (folio_test_hugetlb(src) &&
> -	    folio_test_hugetlb_mte_tagged(src)) {
> -		if (!folio_try_hugetlb_mte_tagging(dst))
> +	if (folio_test_hugetlb(src)) {

To be safe, maybe also test that dst is a hugetlb folio? But maybe the 
implicit checks we added in folio_try_hugetlb_mte_tagging() will already 
check that.

> +		if (!folio_test_hugetlb_mte_tagged(src) ||
> +		    from != folio_page(src, 0) ||
> +		    WARN_ON_ONCE(folio_nr_pages(src) != folio_nr_pages(dst)))
>   			return;
>   
> +		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
> +
>   		/*
>   		 * Populate tags for all subpages.
>   		 *
> 


-- 
Cheers,

David / dhildenb



From yang at os.amperecomputing.com  Wed Dec  4 08:17:14 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Wed, 4 Dec 2024 08:17:14 -0800
Subject: [GIT PULL] arm64 updates for 6.13-rc1
In-Reply-To: <f7e0029e-f940-4f08-84f4-e89450d3e981@redhat.com>
References: <20241118100623.2674026-1-catalin.marinas@arm.com>
 <Z0STR6VLt2MCalnY@sashalap> <Z0TLhc3uxa5RnK64@arm.com>
 <0c09425b-c8ba-4ed6-b429-0bce4e7d00e9@os.amperecomputing.com>
 <Z0dhc-DtVsvufv-E@arm.com>
 <dc5e8809-825f-4c38-b487-b16c7d516311@os.amperecomputing.com>
 <e6b3e6c7-193d-43c4-a8c6-6023458723dd@redhat.com>
 <6aec1d44-4a89-4acf-a16b-4493626b93bb@os.amperecomputing.com>
 <Z1B1VS8PayXsXDzl@arm.com> <4919faec-3e35-459f-a7d3-b5b3f188bd9c@redhat.com>
 <Z1B6OMqEZitgBVEx@arm.com> <f7e0029e-f940-4f08-84f4-e89450d3e981@redhat.com>
Message-ID: <c7b897f3-cd63-4aba-8cac-1c5b40286a77@os.amperecomputing.com>



On 12/4/24 8:00 AM, David Hildenbrand wrote:
> On 04.12.24 16:50, Catalin Marinas wrote:
>> On Wed, Dec 04, 2024 at 04:32:11PM +0100, David Hildenbrand wrote:
>>> On 04.12.24 16:29, Catalin Marinas wrote:
>>>> On Mon, Dec 02, 2024 at 08:22:57AM -0800, Yang Shi wrote:
>>>>> On 11/28/24 1:56 AM, David Hildenbrand wrote:
>>>>>> On 28.11.24 02:21, Yang Shi wrote:
>>>>>>>>> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
>>>>>>>>> index 87b3f1a25535..ef303a2262c5 100644
>>>>>>>>> --- a/arch/arm64/mm/copypage.c
>>>>>>>>> +++ b/arch/arm64/mm/copypage.c
>>>>>>>>> @@ -30,9 +30,9 @@ void copy_highpage(struct page *to, struct
>>>>>>>>> page *from)
>>>>>>>>> ? ??????? if (!system_supports_mte())
>>>>>>>>> ? ??????????? return;
>>>>>>>>> -??? if (folio_test_hugetlb(src) &&
>>>>>>>>> -??????? folio_test_hugetlb_mte_tagged(src)) {
>>>>>>>>> -??????? if (!folio_try_hugetlb_mte_tagging(dst))
>>>>>>>>> +??? if (folio_test_hugetlb(src)) {
>>>>>>>>> +??????? if (!folio_test_hugetlb_mte_tagged(src) ||
>>>>>>>>> +??????????? !folio_try_hugetlb_mte_tagging(dst))
>>>>>>>>> ? ??????????????? return;
>>>>>>>>> ? ??????????? /*
>>>>>>>> I wonder why we had a 'return' here originally rather than a
>>>>>>>> WARN_ON_ONCE() as we do further down for the page case. Do you 
>>>>>>>> seen any
>>>>>>>> issue with the hunk below? Destination should be a new folio 
>>>>>>>> and not
>>>>>>>> tagged yet:
>>>>>>>
>>>>>>> Yes, I did see problem. Because we copy tags for all sub pages 
>>>>>>> then set
>>>>>>> folio mte tagged when copying the data for the first subpage. The
>>>>>>> warning will be triggered when we copy the second subpage.
>>>>>>
>>>>>> It's rather weird, though. We're instructed to copy a single 
>>>>>> page, yet
>>>>>> copy tags for all pages.
>>>>>>
>>>>>> This really only makes sense when called from folio_copy(), where 
>>>>>> we are
>>>>>> guaranteed to copy all pages.
>>>>>>
>>>>>> I'm starting to wonder if we should be able to hook into / overload
>>>>>> folio_copy() instead, to just handle the complete hugetlb copy 
>>>>>> ourselves
>>>>>> in one shot, and assume that copy_highpage() will never be called 
>>>>>> for
>>>>>> hugetlb pages (WARN and don't copy tags).
>>>>>
>>>>> Actually folio_copy() is just called by migration. Copy huge page 
>>>>> in CoW is
>>>>> more complicated and uses copy_user_highpage()->copy_highpage() 
>>>>> instead of
>>>>> folio_copy(). It may start the page copy from any subpage. For 
>>>>> example, if
>>>>> the CoW is triggered by accessing to the address in the middle of 
>>>>> 2M. Kernel
>>>>> may copy the second half first then the first half to guarantee 
>>>>> the accessed
>>>>> data in cache.
>>>>
>>>> Still trying to understand the possible call paths here. If we get a
>>>> write fault on a large folio, does the core code allocate a folio 
>>>> of the
>>>> same size for CoW or it starts with smaller ones? wp_page_copy()
>>>> allocates order 0 AFAICT, though if it was a pmd fault, it takes a
>>>> different path in handle_mm_fault(). But we also have huge pages using
>>>> contiguous ptes.
>>>>
>>>> Unless the source and destinations folios are exactly the same 
>>>> size, it
>>>> will break many assumptions in the code above. Going the other way
>>>> around is also wrong, dst larger than src, we are not initialising the
>>>> whole dst folio.
>>>>
>>>> Maybe going back to per-page PG_mte_tagged flag rather than per-folio
>>>> would keep things simple, less risk of wrong assumptions.
>>>
>>> I think the magic bit here is that for hugetlb, we only get hugetlb 
>>> folios
>>> of the same size, and no mixtures.
>>
>> Ah, ok, we do check for this and only do the advance copy for hugetlb
>> folios. I'd add a check for folio size just in case, something like
>> below (I'll add some description and post it properly):
>>
>> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
>> index 87b3f1a25535..c3a83db46ec6 100644
>> --- a/arch/arm64/mm/copypage.c
>> +++ b/arch/arm64/mm/copypage.c
>> @@ -30,11 +30,14 @@ void copy_highpage(struct page *to, struct page 
>> *from)
>> ????? if (!system_supports_mte())
>> ????????? return;
>> ? -??? if (folio_test_hugetlb(src) &&
>> -??????? folio_test_hugetlb_mte_tagged(src)) {
>> -??????? if (!folio_try_hugetlb_mte_tagging(dst))
>> +??? if (folio_test_hugetlb(src)) {
>
> To be safe, maybe also test that dst is a hugetlb folio? But maybe the 
> implicit checks we added in folio_try_hugetlb_mte_tagging() will 
> already check that.

Yes, we have "VM_WARN_ON_ONCE(!folio_test_hugetlb(folio))" in 
folio_try_hugetlb_mte_tagging(), it should be good enough.

>
>> +??????? if (!folio_test_hugetlb_mte_tagged(src) ||
>> +??????????? from != folio_page(src, 0) ||
>> +??????????? WARN_ON_ONCE(folio_nr_pages(src) != folio_nr_pages(dst)))
>> ????????????? return;
>> ? +??????? WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
>> +
>> ????????? /*
>> ?????????? * Populate tags for all subpages.
>> ?????????? *
>>
>
>



From thierry.reding at gmail.com  Wed Dec  4 08:23:53 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 4 Dec 2024 17:23:53 +0100
Subject: [PATCH v1 1/1] net: stmmac: dwmac-tegra: Read iommu stream id
 from device tree
In-Reply-To: <20241119144729.72e048a5.parker@finest.io>
References: <cover.1731685185.git.pnewman@connecttech.com>
 <f2a14edb5761d372ec939ccbea4fb8dfd1fdab91.1731685185.git.pnewman@connecttech.com>
 <ed2ec1c2-65c7-4768-99f1-987e5fa39a54@redhat.com>
 <20241115135940.5f898781.parker@finest.io>
 <bb52bdc1-df2e-493d-a58f-df3143715150@lunn.ch>
 <20241118084400.35f4697a.parker@finest.io>
 <984a8471-7e49-4549-9d8a-48e1a29950f6@lunn.ch>
 <20241119131336.371af397.parker@finest.io>
 <f00bccd3-62d5-46a9-b448-051894267c7a@lunn.ch>
 <20241119144729.72e048a5.parker@finest.io>
Message-ID: <mpgilwqb5zg5kb4n7r6zwbhy4uutdh6rq5s2yc6ndhcj6gqgri@qkfr4qwjj3ym>

On Tue, Nov 19, 2024 at 02:47:29PM -0500, Parker Newman wrote:
> On Tue, 19 Nov 2024 20:18:00 +0100
> Andrew Lunn <andrew at lunn.ch> wrote:
> 
> > > I think there is some confusion here. I will try to summarize:
> > > - Ihe iommu is supported by the Tegra SOC.
> > > - The way the mgbe driver is written the iommu DT property is REQUIRED.
> >
> > If it is required, please also include a patch to
> > nvidia,tegra234-mgbe.yaml and make iommus required.
> >
> 
> I will add this when I submit a v2 of the patch.
> 
> > > - "iommus" is a SOC DT property and is defined in tegra234.dtsi.
> > > - The mgbe device tree nodes in tegra234.dtsi DO have the iommus property.
> > > - There are no device tree changes required to to make this patch work.
> > > - This patch works fine with existing device trees.
> > >
> > > I will add the fallback however in case there is changes made to the iommu
> > > subsystem in the future.
> >
> > I would suggest you make iommus a required property and run the tests
> > over the existing .dts files.
> >
> > I looked at the history of tegra234.dtsi. The ethernet nodes were
> > added in:
> >
> > 610cdf3186bc604961bf04851e300deefd318038
> > Author: Thierry Reding <treding at nvidia.com>
> > Date:   Thu Jul 7 09:48:15 2022 +0200
> >
> >     arm64: tegra: Add MGBE nodes on Tegra234
> >
> > and the iommus property is present. So the requires is safe.
> >
> > Please expand the commit message. It is clear from all the questions
> > and backwards and forwards, it does not provide enough details.
> >
> 
> I will add more details when I submit V2.
> 
> > I just have one open issue. The code has been like this for over 2
> > years. Why has it only now started crashing?
> >
> 
> It is rare for Nvidia Jetson users to use the mainline kernel. Nvidia
> provides a custom kernel package with many out of tree drivers including a
> driver for the mgbe controllers.
> 
> Also, while the Orin AGX SOC (tegra234) has 4 instances of the mgbe controller,
> the Nvidia Orin AGX devkit only uses mgbe0. Connect Tech has carrier boards
> that use 2 or more of the mgbe controllers which is why we found the bug.

Correct. Also, this was a really stupid thing that I overlooked. I don't
recall the exact circumstances, but I vaguely recall there had been
discussions about adding the tegra_dev_iommu_get_stream_id() helper
(that this patch uses) around the time that this driver was created. In
the midst of all of this I likely forgot to update the driver after the
discussions had settled.

Anyway, I agree with the conclusion that we don't need a compatibility
fallback for this, both because it would be actively wrong to do it and
we've had the required IOMMU properties in device tree since the start,
so there can't be any regressions caused by this.

I don't think it's necessary to make the iommus property required,
though, because there's technically no requirement for these devices to
be attached to an IOMMU. They usually are, and it's better if they are,
but they should be able to work correctly without an IOMMU.

Thanks, and apologies for dropping the ball on this,
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/20241204/5758e442/attachment.sig>

From marcus.folkesson at gmail.com  Wed Dec  4 08:26:04 2024
From: marcus.folkesson at gmail.com (Marcus Folkesson)
Date: Wed, 4 Dec 2024 17:26:04 +0100
Subject: [PATCH 5/9] ARM: mvebu_v5_defconfig: rebuild default
 configuration
In-Reply-To: <303c44ca-879c-477c-a96c-9741bf3bf31a@lunn.ch>
References: <20241204-defconfigs-v1-0-86587652d37a@gmail.com>
 <20241204-defconfigs-v1-5-86587652d37a@gmail.com>
 <303c44ca-879c-477c-a96c-9741bf3bf31a@lunn.ch>
Message-ID: <Z1CCnGZvuBLZ2k2P@gmail.com>

On Wed, Dec 04, 2024 at 05:04:25PM +0100, Andrew Lunn wrote:
> On Wed, Dec 04, 2024 at 04:56:47PM +0100, Marcus Folkesson wrote:
> > This configuration contains obsolete configuration options e.g.
> > CONFIG_MTD_M25P80 which is integrated into MTD_SPI_NOR.
> > 
> > Rebuild this configuration by run:
> > make ARCH=arm mvebu_v5_defconfig
> > make ARCH=arm savedefconfig
> > 
> > Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>
> 
> You probably want to wait until Arnd big removal patchset lands,
> because this is going to be immediately outdated.

Thanks for the info, I wasn't aware of this.

I will give it another shot when his patchset has landed.

> 
>      Andrew

Best regards,
Marcus Folkesson
-------------- 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/20241204/0ea3e31a/attachment.sig>

From vishal.sagar at amd.com  Wed Dec  4 08:26:41 2024
From: vishal.sagar at amd.com (Sagar, Vishal)
Date: Wed, 4 Dec 2024 16:26:41 +0000
Subject: [PATCH 01/10] drm/fourcc: Add warning for bad bpp
In-Reply-To: <20241204-xilinx-formats-v1-1-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
 <20241204-xilinx-formats-v1-1-0bf2c5147db1@ideasonboard.com>
Message-ID: <BL1PR12MB596954886CC5E28EC8E735BA9C372@BL1PR12MB5969.namprd12.prod.outlook.com>

[AMD Official Use Only - AMD Internal Distribution Only]

Hi Tomi,

Thanks for the patch.

> -----Original Message-----
> From: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> Sent: Wednesday, December 4, 2024 10:31 AM
> To: Sagar, Vishal <vishal.sagar at amd.com>; Klymenko, Anatoliy
> <Anatoliy.Klymenko at amd.com>; Maarten Lankhorst
> <maarten.lankhorst at linux.intel.com>; Maxime Ripard <mripard at kernel.org>;
> Thomas Zimmermann <tzimmermann at suse.de>; David Airlie
> <airlied at gmail.com>; Simona Vetter <simona at ffwll.ch>; Laurent Pinchart
> <laurent.pinchart at ideasonboard.com>; Simek, Michal <michal.simek at amd.com>
> Cc: dri-devel at lists.freedesktop.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> Subject: [PATCH 01/10] drm/fourcc: Add warning for bad bpp
>
> drm_format_info_bpp() cannot be used for formats which do not have an
> integer bits-per-pixel. Handle wrong calls by printing a warning and
> returning 0.

It would be good to add an example of pixel format that may cause this issue.

>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
>  drivers/gpu/drm/drm_fourcc.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index 193cf8ed7912..e84c4ed6928c 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -429,6 +429,13 @@ unsigned int drm_format_info_bpp(const struct
> drm_format_info *info, int plane)
>       if (!info || plane < 0 || plane >= info->num_planes)
>               return 0;
>
> +     if (info->char_per_block[plane] * 8 %
> +         (drm_format_info_block_width(info, plane) *
> +          drm_format_info_block_height(info, plane))) {
> +             pr_warn("unable to return an integer bpp\n");
> +             return 0;
> +     }
> +
>       return info->char_per_block[plane] * 8 /
>              (drm_format_info_block_width(info, plane) *
>               drm_format_info_block_height(info, plane));
>
> --
> 2.43.0

Regards
Vishal Sagar

From broonie at kernel.org  Wed Dec  4 08:25:18 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 04 Dec 2024 16:25:18 +0000
Subject: [PATCH] spi: rockchip-sfc: Optimize the judgment mechanism
 completed by the controller
In-Reply-To: <20241203013513.2628810-1-jon.lin@rock-chips.com>
References: <20241203013513.2628810-1-jon.lin@rock-chips.com>
Message-ID: <173332951887.13421.11537303801053149682.b4-ty@kernel.org>

On Tue, 03 Dec 2024 09:35:13 +0800, Jon Lin wrote:
> There is very little data left in fifo, and the controller will
> complete the transmission in a short period of time, so
> use readl_poll_timeout() for busy wait 10us to accelerate response.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: rockchip-sfc: Optimize the judgment mechanism completed by the controller
      commit: 577f1cf76ceedb5fbdc9aca4f712b21864ac15ee

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 m.tretter at pengutronix.de  Wed Dec  4 08:27:40 2024
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 4 Dec 2024 17:27:40 +0100
Subject: [PATCH] media: allegro-dvt: Moving the current driver to
 subdirectory
In-Reply-To: <abshbp4blqxasxvf4ibumtfqcr7hytehmhzs2yag3nfpbcl47x@ndjg7al4iysk>
References: <20241202102654.40472-1-yassine.ouaissa@allegrodvt.com>
 <Z02SLI05JhNDtXFn@pengutronix.de>
 <abshbp4blqxasxvf4ibumtfqcr7hytehmhzs2yag3nfpbcl47x@ndjg7al4iysk>
Message-ID: <Z1CC_PQF8hCzmPoQ@pengutronix.de>

Hi Yassine,

On Wed, 04 Dec 2024 14:44:31 +0000, Yassine Ouaissa wrote:
> On 02.12.2024 11:55, Michael Tretter wrote:
> > On Mon, 02 Dec 2024 11:26:38 +0100, Yassine Ouaissa wrote:
> > What kind of conflicts do you encounter or expect? It's kind of
> > surprising that your driver would conflict with anything in the existing
> > driver.
> 
> The current "NOT allegro" driver support only the ZynqMP (ex : ZCU106/ZCU104 ).
> And the upcoming driver, has support for many platforms.

What are the supported platforms of the new driver? Does your driver
support ZynqMP, too?

If there are enough similarities between the encoders, I'd happily
replace parts of the current driver with functionality of the upcoming
driver or reuse the infrastructure of the new driver.

> 
> > I'd like to see how you plan to integrate your driver, what it looks
> > like and what conflicts with the existing driver actually occur. Without
> > that information I don't see the point in moving the driver to a
> > sub-directory.
> 
> The upcoming driver is not using the parsing, conversion inside of the
> driver. Actually the new Gen of ALLEGRO IP does that.

Sorry, I don't understand what you mean by parsing and conversion. Do
you mean the mailbox messages or the NAL units?

Can you point me to some repository with your upcoming driver? I'd
really like to know what's coming up to have an informed discussion how
to structure the directory.

Michael

> > > 
> > > Signed-off-by: Yassine Ouaissa <yassine.ouaissa at allegrodvt.com>
> > > ---
> > >  MAINTAINERS                                               | 2 +-
> > >  drivers/media/platform/allegro-dvt/Kconfig                | 4 ++--
> > >  drivers/media/platform/allegro-dvt/Makefile               | 8 ++------
> > >  drivers/media/platform/allegro-dvt/zynqmp/Makefile        | 6 ++++++
> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c    | 0
> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h    | 0
> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c    | 0
> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h    | 0
> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c    | 0
> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h    | 0
> > >  .../{allegro-core.c => zynqmp/zynqmp-allegro-core.c}      | 2 +-
> > >  .../{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c}      | 2 +-
> > >  .../{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h}      | 0
> > >  13 files changed, 13 insertions(+), 11 deletions(-)
> > >  create mode 100644 drivers/media/platform/allegro-dvt/zynqmp/Makefile
> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c (100%)
> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h (100%)
> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c (100%)
> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h (100%)
> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c (100%)
> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h (100%)
> > >  rename drivers/media/platform/allegro-dvt/{allegro-core.c => zynqmp/zynqmp-allegro-core.c} (99%)
> > >  rename drivers/media/platform/allegro-dvt/{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c} (99%)
> > >  rename drivers/media/platform/allegro-dvt/{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h} (100%)
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 7292e4a1ddb8..d79efe6f8992 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -795,7 +795,7 @@ R:	Pengutronix Kernel Team <kernel at pengutronix.de>
> > >  L:	linux-media at vger.kernel.org
> > >  S:	Maintained
> > >  F:	Documentation/devicetree/bindings/media/allegro,al5e.yaml
> > > -F:	drivers/media/platform/allegro-dvt/
> > > +F:	drivers/media/platform/allegro-dvt/zynqmp
> > > 
> > >  ALLIED VISION ALVIUM CAMERA DRIVER
> > >  M:	Tommaso Merciai <tomm.merciai at gmail.com>
> > > diff --git a/drivers/media/platform/allegro-dvt/Kconfig b/drivers/media/platform/allegro-dvt/Kconfig
> > > index 2182e1277568..9bc7e99788b8 100644
> > > --- a/drivers/media/platform/allegro-dvt/Kconfig
> > > +++ b/drivers/media/platform/allegro-dvt/Kconfig
> > > @@ -2,8 +2,8 @@
> > > 
> > >  comment "Allegro DVT media platform drivers"
> > > 
> > > -config VIDEO_ALLEGRO_DVT
> > > -	tristate "Allegro DVT Video IP Core"
> > > +config VIDEO_ZYNQMP_ALLEGRO_DVT
> > > +	tristate "Allegro DVT Video IP Core for ZynqMP"
> > >  	depends on V4L_MEM2MEM_DRIVERS
> > >  	depends on VIDEO_DEV
> > >  	depends on ARCH_ZYNQMP || COMPILE_TEST
> > > diff --git a/drivers/media/platform/allegro-dvt/Makefile b/drivers/media/platform/allegro-dvt/Makefile
> > > index 66108a303774..04727c5f7ef4 100644
> > > --- a/drivers/media/platform/allegro-dvt/Makefile
> > > +++ b/drivers/media/platform/allegro-dvt/Makefile
> > > @@ -1,6 +1,2 @@
> > > -# SPDX-License-Identifier: GPL-2.0
> > > -
> > > -allegro-objs := allegro-core.o allegro-mail.o
> > > -allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
> > > -
> > > -obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o
> > > +# SPDX-License-Identifier: GPL-2.0-only
> > > +obj-y += zynqmp/
> > > diff --git a/drivers/media/platform/allegro-dvt/zynqmp/Makefile b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
> > > new file mode 100644
> > > index 000000000000..a8ddb9cf93a8
> > > --- /dev/null
> > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
> > > @@ -0,0 +1,6 @@
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +
> > > +zynqmp-allegro-objs := zynqmp-allegro-core.o zynqmp-allegro-mail.o
> > > +zynqmp-allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
> > > +
> > > +obj-$(CONFIG_VIDEO_ZYNQMP_ALLEGRO_DVT) += zynqmp-allegro.o
> > > diff --git a/drivers/media/platform/allegro-dvt/nal-h264.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
> > > similarity index 100%
> > > rename from drivers/media/platform/allegro-dvt/nal-h264.c
> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
> > > diff --git a/drivers/media/platform/allegro-dvt/nal-h264.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
> > > similarity index 100%
> > > rename from drivers/media/platform/allegro-dvt/nal-h264.h
> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
> > > diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
> > > similarity index 100%
> > > rename from drivers/media/platform/allegro-dvt/nal-hevc.c
> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
> > > diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
> > > similarity index 100%
> > > rename from drivers/media/platform/allegro-dvt/nal-hevc.h
> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
> > > diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
> > > similarity index 100%
> > > rename from drivers/media/platform/allegro-dvt/nal-rbsp.c
> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
> > > diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
> > > similarity index 100%
> > > rename from drivers/media/platform/allegro-dvt/nal-rbsp.h
> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
> > > diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> > > similarity index 99%
> > > rename from drivers/media/platform/allegro-dvt/allegro-core.c
> > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> > > index e491399afcc9..8895d7755987 100644
> > > --- a/drivers/media/platform/allegro-dvt/allegro-core.c
> > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> > > @@ -31,7 +31,7 @@
> > >  #include <media/videobuf2-dma-contig.h>
> > >  #include <media/videobuf2-v4l2.h>
> > > 
> > > -#include "allegro-mail.h"
> > > +#include "zynqmp-allegro-mail.h"
> > >  #include "nal-h264.h"
> > >  #include "nal-hevc.h"
> > > 
> > > diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> > > similarity index 99%
> > > rename from drivers/media/platform/allegro-dvt/allegro-mail.c
> > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> > > index aadc947a77ae..88a98f9e5d00 100644
> > > --- a/drivers/media/platform/allegro-dvt/allegro-mail.c
> > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> > > @@ -12,7 +12,7 @@
> > >  #include <linux/string.h>
> > >  #include <linux/videodev2.h>
> > > 
> > > -#include "allegro-mail.h"
> > > +#include "zynqmp-allegro-mail.h"
> > > 
> > >  const char *msg_type_name(enum mcu_msg_type type)
> > >  {
> > > diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.h b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
> > > similarity index 100%
> > > rename from drivers/media/platform/allegro-dvt/allegro-mail.h
> > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
> > > --
> > > 2.30.2
> > > 
> > > 


From Frank.li at nxp.com  Wed Dec  4 08:35:20 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 4 Dec 2024 11:35:20 -0500
Subject: [PATCH 1/2] PCI: host-generic: Allow {en,dis}able_device() to be
 provided via pci_ecam_ops
In-Reply-To: <20241204150145.800408-2-maz@kernel.org>
References: <20241204150145.800408-1-maz@kernel.org>
 <20241204150145.800408-2-maz@kernel.org>
Message-ID: <Z1CEyAJn8OnxEHUO@lizhi-Precision-Tower-5810>

On Wed, Dec 04, 2024 at 03:01:44PM +0000, Marc Zyngier wrote:
> In order to let host controller drivers using the host-generic
> infrastructure use the {en,dis}able_device() callbacks that can
> be used to configure sideband RID mapping hardware, provide these
> two callbacks as part of the pci_ecap_ops structure.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>  drivers/pci/controller/pci-host-common.c | 2 ++
>  include/linux/pci-ecam.h                 | 4 ++++
>  2 files changed, 6 insertions(+)
>
> diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
> index cf5f59a745b37..f441bfd6f96a8 100644
> --- a/drivers/pci/controller/pci-host-common.c
> +++ b/drivers/pci/controller/pci-host-common.c
> @@ -75,6 +75,8 @@ int pci_host_common_probe(struct platform_device *pdev)
>
>  	bridge->sysdata = cfg;
>  	bridge->ops = (struct pci_ops *)&ops->pci_ops;
> +	bridge->enable_device = ops->enable_device;
> +	bridge->disable_device = ops->disable_device;
>  	bridge->msi_domain = true;
>
>  	return pci_host_probe(bridge);
> diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
> index 3a4860bd27586..3a10f8cfc3ad5 100644
> --- a/include/linux/pci-ecam.h
> +++ b/include/linux/pci-ecam.h
> @@ -45,6 +45,10 @@ struct pci_ecam_ops {
>  	unsigned int			bus_shift;
>  	struct pci_ops			pci_ops;
>  	int				(*init)(struct pci_config_window *);
> +	int				(*enable_device)(struct pci_host_bridge *,
> +							 struct pci_dev *);
> +	void				(*disable_device)(struct pci_host_bridge *,
> +							  struct pci_dev *);
>  };
>
>  /*
> --
> 2.39.2
>


From linux at armlinux.org.uk  Wed Dec  4 08:39:43 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Dec 2024 16:39:43 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <2g2lp3bkadc4wpeslmdoexpidoiqzt7vejar5xhjx5ayt3uox3@dqdyfzn6khn6>
References: <20241021061023.2162701-1-0x1207@gmail.com>
 <d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
 <20241128144501.0000619b@gmail.com>
 <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com>
 <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
 <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
 <df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>
 <2g2lp3bkadc4wpeslmdoexpidoiqzt7vejar5xhjx5ayt3uox3@dqdyfzn6khn6>
Message-ID: <Z1CFz7GpeIzkDro1@shell.armlinux.org.uk>

On Wed, Dec 04, 2024 at 04:58:34PM +0100, Thierry Reding wrote:
> This doesn't match the location from earlier, but at least there's
> something afoot here that needs fixing. I suppose this could simply be
> hiding any subsequent errors, so once this is fixed we might see other
> similar issues.

Well, having a quick look at this, the first thing which stands out is:

In stmmac_tx_clean(), we have:

                if (likely(tx_q->tx_skbuff_dma[entry].buf &&
                           tx_q->tx_skbuff_dma[entry].buf_type != STMMAC_TXBUF_T
_XDP_TX)) {
                        if (tx_q->tx_skbuff_dma[entry].map_as_page)
                                dma_unmap_page(priv->device,
                                               tx_q->tx_skbuff_dma[entry].buf,
                                               tx_q->tx_skbuff_dma[entry].len,
                                               DMA_TO_DEVICE);
                        else
                                dma_unmap_single(priv->device,
                                                 tx_q->tx_skbuff_dma[entry].buf,
                                                 tx_q->tx_skbuff_dma[entry].len,
                                                 DMA_TO_DEVICE);
                        tx_q->tx_skbuff_dma[entry].buf = 0;
                        tx_q->tx_skbuff_dma[entry].len = 0;
                        tx_q->tx_skbuff_dma[entry].map_as_page = false;
                }

So, tx_skbuff_dma[entry].buf is expected to point appropriately to the
DMA region.

Now if we look at stmmac_tso_xmit():

        des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
                             DMA_TO_DEVICE);
        if (dma_mapping_error(priv->device, des))
                goto dma_map_err;

        if (priv->dma_cap.addr64 <= 32) {
...
        } else {
...
                des += proto_hdr_len;
...
	}

        tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
        tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
        tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
        tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;

This will result in stmmac_tx_clean() calling dma_unmap_single() using
"des" and "skb_headlen(skb)" as the buffer start and length.

One of the requirements of the DMA mapping API is that the DMA handle
returned by the map operation will be passed into the unmap function.
Not something that was offset. The length will also be the same.

We can clearly see above that there is a case where the DMA handle has
been offset by proto_hdr_len, and when this is so, the value that is
passed into the unmap operation no longer matches this requirement.

So, a question to the reporter - what is the value of
priv->dma_cap.addr64 in your failing case? You should see the value
in the "Using %d/%d bits DMA host/device width" kernel message.

Thanks.

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


From Frank.li at nxp.com  Wed Dec  4 08:37:33 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 4 Dec 2024 11:37:33 -0500
Subject: [PATCH 2/2] PCI: apple: Convert to {en,dis}able_device()
 callbacks
In-Reply-To: <20241204150145.800408-3-maz@kernel.org>
References: <20241204150145.800408-1-maz@kernel.org>
 <20241204150145.800408-3-maz@kernel.org>
Message-ID: <Z1CFTb8d1SfAmP2w@lizhi-Precision-Tower-5810>

On Wed, Dec 04, 2024 at 03:01:45PM +0000, Marc Zyngier wrote:
> Now that the core host-bridge infrastructure is able to give
> us a callback on each device being added or removed, convert
> the bus-notifier hack to it.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Frank Li <Frank.Li at nxp.com>


> ---
>  drivers/pci/controller/pcie-apple.c | 75 ++++++-----------------------
>  1 file changed, 15 insertions(+), 60 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
> index fefab2758a064..a7e51bc1c2fe8 100644
> --- a/drivers/pci/controller/pcie-apple.c
> +++ b/drivers/pci/controller/pcie-apple.c
> @@ -26,7 +26,6 @@
>  #include <linux/list.h>
>  #include <linux/module.h>
>  #include <linux/msi.h>
> -#include <linux/notifier.h>
>  #include <linux/of_irq.h>
>  #include <linux/pci-ecam.h>
>
> @@ -667,12 +666,16 @@ static struct apple_pcie_port *apple_pcie_get_port(struct pci_dev *pdev)
>  	return NULL;
>  }
>
> -static int apple_pcie_add_device(struct apple_pcie_port *port,
> -				 struct pci_dev *pdev)
> +static int apple_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
>  {
>  	u32 sid, rid = pci_dev_id(pdev);
> +	struct apple_pcie_port *port;
>  	int idx, err;
>
> +	port = apple_pcie_get_port(pdev);
> +	if (!port)
> +		return 0;
> +
>  	dev_dbg(&pdev->dev, "added to bus %s, index %d\n",
>  		pci_name(pdev->bus->self), port->idx);
>
> @@ -698,12 +701,16 @@ static int apple_pcie_add_device(struct apple_pcie_port *port,
>  	return idx >= 0 ? 0 : -ENOSPC;
>  }
>
> -static void apple_pcie_release_device(struct apple_pcie_port *port,
> -				      struct pci_dev *pdev)
> +static void apple_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
>  {
> +	struct apple_pcie_port *port;
>  	u32 rid = pci_dev_id(pdev);
>  	int idx;
>
> +	port = apple_pcie_get_port(pdev);
> +	if (!port)
> +		return;
> +
>  	mutex_lock(&port->pcie->lock);
>
>  	for_each_set_bit(idx, port->sid_map, port->sid_map_sz) {
> @@ -721,45 +728,6 @@ static void apple_pcie_release_device(struct apple_pcie_port *port,
>  	mutex_unlock(&port->pcie->lock);
>  }
>
> -static int apple_pcie_bus_notifier(struct notifier_block *nb,
> -				   unsigned long action,
> -				   void *data)
> -{
> -	struct device *dev = data;
> -	struct pci_dev *pdev = to_pci_dev(dev);
> -	struct apple_pcie_port *port;
> -	int err;
> -
> -	/*
> -	 * This is a bit ugly. We assume that if we get notified for
> -	 * any PCI device, we must be in charge of it, and that there
> -	 * is no other PCI controller in the whole system. It probably
> -	 * holds for now, but who knows for how long?
> -	 */
> -	port = apple_pcie_get_port(pdev);
> -	if (!port)
> -		return NOTIFY_DONE;
> -
> -	switch (action) {
> -	case BUS_NOTIFY_ADD_DEVICE:
> -		err = apple_pcie_add_device(port, pdev);
> -		if (err)
> -			return notifier_from_errno(err);
> -		break;
> -	case BUS_NOTIFY_DEL_DEVICE:
> -		apple_pcie_release_device(port, pdev);
> -		break;
> -	default:
> -		return NOTIFY_DONE;
> -	}
> -
> -	return NOTIFY_OK;
> -}
> -
> -static struct notifier_block apple_pcie_nb = {
> -	.notifier_call = apple_pcie_bus_notifier,
> -};
> -
>  static int apple_pcie_init(struct pci_config_window *cfg)
>  {
>  	struct device *dev = cfg->parent;
> @@ -799,23 +767,10 @@ static int apple_pcie_init(struct pci_config_window *cfg)
>  	return 0;
>  }
>
> -static int apple_pcie_probe(struct platform_device *pdev)
> -{
> -	int ret;
> -
> -	ret = bus_register_notifier(&pci_bus_type, &apple_pcie_nb);
> -	if (ret)
> -		return ret;
> -
> -	ret = pci_host_common_probe(pdev);
> -	if (ret)
> -		bus_unregister_notifier(&pci_bus_type, &apple_pcie_nb);
> -
> -	return ret;
> -}
> -
>  static const struct pci_ecam_ops apple_pcie_cfg_ecam_ops = {
>  	.init		= apple_pcie_init,
> +	.enable_device	= apple_pcie_enable_device,
> +	.disable_device	= apple_pcie_disable_device,
>  	.pci_ops	= {
>  		.map_bus	= pci_ecam_map_bus,
>  		.read		= pci_generic_config_read,
> @@ -830,7 +785,7 @@ static const struct of_device_id apple_pcie_of_match[] = {
>  MODULE_DEVICE_TABLE(of, apple_pcie_of_match);
>
>  static struct platform_driver apple_pcie_driver = {
> -	.probe	= apple_pcie_probe,
> +	.probe	= pci_host_common_probe,
>  	.driver	= {
>  		.name			= "pcie-apple",
>  		.of_match_table		= apple_pcie_of_match,
> --
> 2.39.2
>


From parker at finest.io  Wed Dec  4 08:53:17 2024
From: parker at finest.io (Parker Newman)
Date: Wed, 4 Dec 2024 11:53:17 -0500
Subject: [PATCH v1 1/1] net: stmmac: dwmac-tegra: Read iommu stream id
 from device tree
In-Reply-To: <mpgilwqb5zg5kb4n7r6zwbhy4uutdh6rq5s2yc6ndhcj6gqgri@qkfr4qwjj3ym>
References: <cover.1731685185.git.pnewman@connecttech.com>
	<f2a14edb5761d372ec939ccbea4fb8dfd1fdab91.1731685185.git.pnewman@connecttech.com>
	<ed2ec1c2-65c7-4768-99f1-987e5fa39a54@redhat.com>
	<20241115135940.5f898781.parker@finest.io>
	<bb52bdc1-df2e-493d-a58f-df3143715150@lunn.ch>
	<20241118084400.35f4697a.parker@finest.io>
	<984a8471-7e49-4549-9d8a-48e1a29950f6@lunn.ch>
	<20241119131336.371af397.parker@finest.io>
	<f00bccd3-62d5-46a9-b448-051894267c7a@lunn.ch>
	<20241119144729.72e048a5.parker@finest.io>
	<mpgilwqb5zg5kb4n7r6zwbhy4uutdh6rq5s2yc6ndhcj6gqgri@qkfr4qwjj3ym>
Message-ID: <20241204115317.008f497c.parker@finest.io>

On Wed, 4 Dec 2024 17:23:53 +0100
Thierry Reding <thierry.reding at gmail.com> wrote:

> On Tue, Nov 19, 2024 at 02:47:29PM -0500, Parker Newman wrote:
> > On Tue, 19 Nov 2024 20:18:00 +0100
> > Andrew Lunn <andrew at lunn.ch> wrote:
> >
> > > > I think there is some confusion here. I will try to summarize:
> > > > - Ihe iommu is supported by the Tegra SOC.
> > > > - The way the mgbe driver is written the iommu DT property is REQUIRED.
> > >
> > > If it is required, please also include a patch to
> > > nvidia,tegra234-mgbe.yaml and make iommus required.
> > >
> >
> > I will add this when I submit a v2 of the patch.
> >
> > > > - "iommus" is a SOC DT property and is defined in tegra234.dtsi.
> > > > - The mgbe device tree nodes in tegra234.dtsi DO have the iommus property.
> > > > - There are no device tree changes required to to make this patch work.
> > > > - This patch works fine with existing device trees.
> > > >
> > > > I will add the fallback however in case there is changes made to the iommu
> > > > subsystem in the future.
> > >
> > > I would suggest you make iommus a required property and run the tests
> > > over the existing .dts files.
> > >
> > > I looked at the history of tegra234.dtsi. The ethernet nodes were
> > > added in:
> > >
> > > 610cdf3186bc604961bf04851e300deefd318038
> > > Author: Thierry Reding <treding at nvidia.com>
> > > Date:   Thu Jul 7 09:48:15 2022 +0200
> > >
> > >     arm64: tegra: Add MGBE nodes on Tegra234
> > >
> > > and the iommus property is present. So the requires is safe.
> > >
> > > Please expand the commit message. It is clear from all the questions
> > > and backwards and forwards, it does not provide enough details.
> > >
> >
> > I will add more details when I submit V2.
> >
> > > I just have one open issue. The code has been like this for over 2
> > > years. Why has it only now started crashing?
> > >
> >
> > It is rare for Nvidia Jetson users to use the mainline kernel. Nvidia
> > provides a custom kernel package with many out of tree drivers including a
> > driver for the mgbe controllers.
> >
> > Also, while the Orin AGX SOC (tegra234) has 4 instances of the mgbe controller,
> > the Nvidia Orin AGX devkit only uses mgbe0. Connect Tech has carrier boards
> > that use 2 or more of the mgbe controllers which is why we found the bug.
>
> Correct. Also, this was a really stupid thing that I overlooked. I don't
> recall the exact circumstances, but I vaguely recall there had been
> discussions about adding the tegra_dev_iommu_get_stream_id() helper
> (that this patch uses) around the time that this driver was created. In
> the midst of all of this I likely forgot to update the driver after the
> discussions had settled.
>
> Anyway, I agree with the conclusion that we don't need a compatibility
> fallback for this, both because it would be actively wrong to do it and
> we've had the required IOMMU properties in device tree since the start,
> so there can't be any regressions caused by this.
>
> I don't think it's necessary to make the iommus property required,
> though, because there's technically no requirement for these devices to
> be attached to an IOMMU. They usually are, and it's better if they are,
> but they should be able to work correctly without an IOMMU.
>
Thanks for confirming from the Nvidia side! I wasn't sure if they would
work without the iommu. That said, if you did NOT want to use the iommu
and removed the iommu DT property then the probe will fail after my patch.
Would we not need a guard around the writes to MGBE_WRAP_AXI_ASID0_CTRL as well?

Thanks,
Parker

> Thanks, and apologies for dropping the ball on this,
> Thierry



From wahrenst at gmx.net  Wed Dec  4 08:55:46 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Wed,  4 Dec 2024 17:55:46 +0100
Subject: [PATCH V7] dmaengine: bcm2835-dma: Prevent suspend if DMA channel is busy
Message-ID: <20241204165546.77941-1-wahrenst@gmx.net>

bcm2835-dma provides the service to others, so it should suspend
late and resume early. Suspend should be prevented in case a DMA
channel is still busy.

Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/dma/bcm2835-dma.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

Changes in V7:
- improve patch title and changelog
- add explaining comment and drop warning in suspend
- drop empty resume callback

Changes in V6:
- split out of series because there is no dependency

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 7ba52dee40a9..20b10c15c696 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -875,6 +875,27 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
 	return chan;
 }

+static int bcm2835_dma_suspend_late(struct device *dev)
+{
+	struct bcm2835_dmadev *od = dev_get_drvdata(dev);
+	struct bcm2835_chan *c, *next;
+
+	list_for_each_entry_safe(c, next, &od->ddev.channels,
+				 vc.chan.device_node) {
+		void __iomem *chan_base = c->chan_base;
+
+		/* Check if DMA channel is busy */
+		if (readl(chan_base + BCM2835_DMA_ADDR))
+			return -EBUSY;
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops bcm2835_dma_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late, NULL)
+};
+
 static int bcm2835_dma_probe(struct platform_device *pdev)
 {
 	struct bcm2835_dmadev *od;
@@ -1033,6 +1054,7 @@ static struct platform_driver bcm2835_dma_driver = {
 	.driver = {
 		.name = "bcm2835-dma",
 		.of_match_table = of_match_ptr(bcm2835_dma_of_match),
+		.pm = pm_ptr(&bcm2835_dma_pm_ops),
 	},
 };

--
2.34.1



From sashal at kernel.org  Wed Dec  4 07:45:29 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 10:45:29 -0500
Subject: [PATCH AUTOSEL 6.12 13/36] scsi: ufs: core: Make DMA mask configuration more flexible
In-Reply-To: <20241204154626.2211476-1-sashal@kernel.org>
References: <20241204154626.2211476-1-sashal@kernel.org>
Message-ID: <20241204154626.2211476-13-sashal@kernel.org>

From: Bart Van Assche <bvanassche at acm.org>

[ Upstream commit 78bc671bd1501e2f6c571e063301a4fdc5db53b2 ]

Replace UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS with
ufs_hba_variant_ops::set_dma_mask.  Update the Renesas driver
accordingly.  This patch enables supporting other configurations than
32-bit or 64-bit DMA addresses, e.g. 36-bit DMA addresses.

Signed-off-by: Bart Van Assche <bvanassche at acm.org>
Link: https://lore.kernel.org/r/20241018194753.775074-1-bvanassche at acm.org
Reviewed-by: Avri Altman <Avri.Altman at wdc.com>
Reviewed-by: Peter Wang <peter.wang at mediatek.com>
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 ++--
 drivers/ufs/host/ufs-renesas.c | 9 ++++++++-
 include/ufs/ufshcd.h           | 9 +++------
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index abbe7135a9778..2b445a8699dbc 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -2411,8 +2411,6 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)
 	int err;
 
 	hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES);
-	if (hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS)
-		hba->capabilities &= ~MASK_64_ADDRESSING_SUPPORT;
 
 	/* nutrs and nutmrs are 0 based values */
 	hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS_SDB) + 1;
@@ -10309,6 +10307,8 @@ EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
  */
 static int ufshcd_set_dma_mask(struct ufs_hba *hba)
 {
+	if (hba->vops && hba->vops->set_dma_mask)
+		return hba->vops->set_dma_mask(hba);
 	if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
 		if (!dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(64)))
 			return 0;
diff --git a/drivers/ufs/host/ufs-renesas.c b/drivers/ufs/host/ufs-renesas.c
index 8711e5cbc9680..3ff97112e1f6d 100644
--- a/drivers/ufs/host/ufs-renesas.c
+++ b/drivers/ufs/host/ufs-renesas.c
@@ -7,6 +7,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
@@ -364,14 +365,20 @@ static int ufs_renesas_init(struct ufs_hba *hba)
 		return -ENOMEM;
 	ufshcd_set_variant(hba, priv);
 
-	hba->quirks |= UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS | UFSHCD_QUIRK_HIBERN_FASTAUTO;
+	hba->quirks |= UFSHCD_QUIRK_HIBERN_FASTAUTO;
 
 	return 0;
 }
 
+static int ufs_renesas_set_dma_mask(struct ufs_hba *hba)
+{
+	return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32));
+}
+
 static const struct ufs_hba_variant_ops ufs_renesas_vops = {
 	.name		= "renesas",
 	.init		= ufs_renesas_init,
+	.set_dma_mask	= ufs_renesas_set_dma_mask,
 	.setup_clocks	= ufs_renesas_setup_clocks,
 	.hce_enable_notify = ufs_renesas_hce_enable_notify,
 	.dbg_register_dump = ufs_renesas_dbg_register_dump,
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index 3f68ae3e4330d..0b0fba9f1383c 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -299,6 +299,8 @@ struct ufs_pwr_mode_info {
  * @max_num_rtt: maximum RTT supported by the host
  * @init: called when the driver is initialized
  * @exit: called to cleanup everything done in init
+ * @set_dma_mask: For setting another DMA mask than indicated by the 64AS
+ *	capability bit.
  * @get_ufs_hci_version: called to get UFS HCI version
  * @clk_scale_notify: notifies that clks are scaled up/down
  * @setup_clocks: called before touching any of the controller registers
@@ -341,6 +343,7 @@ struct ufs_hba_variant_ops {
 	int	(*init)(struct ufs_hba *);
 	void    (*exit)(struct ufs_hba *);
 	u32	(*get_ufs_hci_version)(struct ufs_hba *);
+	int	(*set_dma_mask)(struct ufs_hba *);
 	int	(*clk_scale_notify)(struct ufs_hba *, bool,
 				    enum ufs_notify_change_status);
 	int	(*setup_clocks)(struct ufs_hba *, bool,
@@ -623,12 +626,6 @@ enum ufshcd_quirks {
 	 */
 	UFSHCD_QUIRK_SKIP_PH_CONFIGURATION		= 1 << 16,
 
-	/*
-	 * This quirk needs to be enabled if the host controller has
-	 * 64-bit addressing supported capability but it doesn't work.
-	 */
-	UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS		= 1 << 17,
-
 	/*
 	 * This quirk needs to be enabled if the host controller has
 	 * auto-hibernate capability but it's FASTAUTO only.
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 07:47:26 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 10:47:26 -0500
Subject: [PATCH AUTOSEL 6.11 13/33] scsi: ufs: core: Make DMA mask configuration more flexible
In-Reply-To: <20241204154817.2212455-1-sashal@kernel.org>
References: <20241204154817.2212455-1-sashal@kernel.org>
Message-ID: <20241204154817.2212455-13-sashal@kernel.org>

From: Bart Van Assche <bvanassche at acm.org>

[ Upstream commit 78bc671bd1501e2f6c571e063301a4fdc5db53b2 ]

Replace UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS with
ufs_hba_variant_ops::set_dma_mask.  Update the Renesas driver
accordingly.  This patch enables supporting other configurations than
32-bit or 64-bit DMA addresses, e.g. 36-bit DMA addresses.

Signed-off-by: Bart Van Assche <bvanassche at acm.org>
Link: https://lore.kernel.org/r/20241018194753.775074-1-bvanassche at acm.org
Reviewed-by: Avri Altman <Avri.Altman at wdc.com>
Reviewed-by: Peter Wang <peter.wang at mediatek.com>
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 ++--
 drivers/ufs/host/ufs-renesas.c | 9 ++++++++-
 include/ufs/ufshcd.h           | 9 +++------
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 03490f062d63a..5c64ef7334546 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -2398,8 +2398,6 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)
 	int err;
 
 	hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES);
-	if (hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS)
-		hba->capabilities &= ~MASK_64_ADDRESSING_SUPPORT;
 
 	/* nutrs and nutmrs are 0 based values */
 	hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS_SDB) + 1;
@@ -10314,6 +10312,8 @@ EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
  */
 static int ufshcd_set_dma_mask(struct ufs_hba *hba)
 {
+	if (hba->vops && hba->vops->set_dma_mask)
+		return hba->vops->set_dma_mask(hba);
 	if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
 		if (!dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(64)))
 			return 0;
diff --git a/drivers/ufs/host/ufs-renesas.c b/drivers/ufs/host/ufs-renesas.c
index 8711e5cbc9680..3ff97112e1f6d 100644
--- a/drivers/ufs/host/ufs-renesas.c
+++ b/drivers/ufs/host/ufs-renesas.c
@@ -7,6 +7,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
@@ -364,14 +365,20 @@ static int ufs_renesas_init(struct ufs_hba *hba)
 		return -ENOMEM;
 	ufshcd_set_variant(hba, priv);
 
-	hba->quirks |= UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS | UFSHCD_QUIRK_HIBERN_FASTAUTO;
+	hba->quirks |= UFSHCD_QUIRK_HIBERN_FASTAUTO;
 
 	return 0;
 }
 
+static int ufs_renesas_set_dma_mask(struct ufs_hba *hba)
+{
+	return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32));
+}
+
 static const struct ufs_hba_variant_ops ufs_renesas_vops = {
 	.name		= "renesas",
 	.init		= ufs_renesas_init,
+	.set_dma_mask	= ufs_renesas_set_dma_mask,
 	.setup_clocks	= ufs_renesas_setup_clocks,
 	.hce_enable_notify = ufs_renesas_hce_enable_notify,
 	.dbg_register_dump = ufs_renesas_dbg_register_dump,
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index 0fd2aebac7286..3fee38029bfee 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -298,6 +298,8 @@ struct ufs_pwr_mode_info {
  * @max_num_rtt: maximum RTT supported by the host
  * @init: called when the driver is initialized
  * @exit: called to cleanup everything done in init
+ * @set_dma_mask: For setting another DMA mask than indicated by the 64AS
+ *	capability bit.
  * @get_ufs_hci_version: called to get UFS HCI version
  * @clk_scale_notify: notifies that clks are scaled up/down
  * @setup_clocks: called before touching any of the controller registers
@@ -340,6 +342,7 @@ struct ufs_hba_variant_ops {
 	int	(*init)(struct ufs_hba *);
 	void    (*exit)(struct ufs_hba *);
 	u32	(*get_ufs_hci_version)(struct ufs_hba *);
+	int	(*set_dma_mask)(struct ufs_hba *);
 	int	(*clk_scale_notify)(struct ufs_hba *, bool,
 				    enum ufs_notify_change_status);
 	int	(*setup_clocks)(struct ufs_hba *, bool,
@@ -622,12 +625,6 @@ enum ufshcd_quirks {
 	 */
 	UFSHCD_QUIRK_SKIP_PH_CONFIGURATION		= 1 << 16,
 
-	/*
-	 * This quirk needs to be enabled if the host controller has
-	 * 64-bit addressing supported capability but it doesn't work.
-	 */
-	UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS		= 1 << 17,
-
 	/*
 	 * This quirk needs to be enabled if the host controller has
 	 * auto-hibernate capability but it's FASTAUTO only.
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 07:50:45 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 10:50:45 -0500
Subject: [PATCH AUTOSEL 6.1 06/15] scsi: ufs: core: Make DMA mask configuration more flexible
In-Reply-To: <20241204155105.2214350-1-sashal@kernel.org>
References: <20241204155105.2214350-1-sashal@kernel.org>
Message-ID: <20241204155105.2214350-6-sashal@kernel.org>

From: Bart Van Assche <bvanassche at acm.org>

[ Upstream commit 78bc671bd1501e2f6c571e063301a4fdc5db53b2 ]

Replace UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS with
ufs_hba_variant_ops::set_dma_mask.  Update the Renesas driver
accordingly.  This patch enables supporting other configurations than
32-bit or 64-bit DMA addresses, e.g. 36-bit DMA addresses.

Signed-off-by: Bart Van Assche <bvanassche at acm.org>
Link: https://lore.kernel.org/r/20241018194753.775074-1-bvanassche at acm.org
Reviewed-by: Avri Altman <Avri.Altman at wdc.com>
Reviewed-by: Peter Wang <peter.wang at mediatek.com>
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 ++--
 drivers/ufs/host/ufs-renesas.c | 9 ++++++++-
 include/ufs/ufshcd.h           | 9 +++------
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index a1809aa9a8892..df94c563b808a 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -2230,8 +2230,6 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)
 	int err;
 
 	hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES);
-	if (hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS)
-		hba->capabilities &= ~MASK_64_ADDRESSING_SUPPORT;
 
 	/* nutrs and nutmrs are 0 based values */
 	hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1;
@@ -9648,6 +9646,8 @@ EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
  */
 static int ufshcd_set_dma_mask(struct ufs_hba *hba)
 {
+	if (hba->vops && hba->vops->set_dma_mask)
+		return hba->vops->set_dma_mask(hba);
 	if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
 		if (!dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(64)))
 			return 0;
diff --git a/drivers/ufs/host/ufs-renesas.c b/drivers/ufs/host/ufs-renesas.c
index ab0652d8705ac..481ad0a3a6c7c 100644
--- a/drivers/ufs/host/ufs-renesas.c
+++ b/drivers/ufs/host/ufs-renesas.c
@@ -7,6 +7,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
@@ -364,14 +365,20 @@ static int ufs_renesas_init(struct ufs_hba *hba)
 		return -ENOMEM;
 	ufshcd_set_variant(hba, priv);
 
-	hba->quirks |= UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS | UFSHCD_QUIRK_HIBERN_FASTAUTO;
+	hba->quirks |= UFSHCD_QUIRK_HIBERN_FASTAUTO;
 
 	return 0;
 }
 
+static int ufs_renesas_set_dma_mask(struct ufs_hba *hba)
+{
+	return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32));
+}
+
 static const struct ufs_hba_variant_ops ufs_renesas_vops = {
 	.name		= "renesas",
 	.init		= ufs_renesas_init,
+	.set_dma_mask	= ufs_renesas_set_dma_mask,
 	.setup_clocks	= ufs_renesas_setup_clocks,
 	.hce_enable_notify = ufs_renesas_hce_enable_notify,
 	.dbg_register_dump = ufs_renesas_dbg_register_dump,
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index b54f22840dabf..c4b1e6dca2397 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -272,6 +272,8 @@ struct ufs_pwr_mode_info {
  * @name: variant name
  * @init: called when the driver is initialized
  * @exit: called to cleanup everything done in init
+ * @set_dma_mask: For setting another DMA mask than indicated by the 64AS
+ *	capability bit.
  * @get_ufs_hci_version: called to get UFS HCI version
  * @clk_scale_notify: notifies that clks are scaled up/down
  * @setup_clocks: called before touching any of the controller registers
@@ -303,6 +305,7 @@ struct ufs_hba_variant_ops {
 	int	(*init)(struct ufs_hba *);
 	void    (*exit)(struct ufs_hba *);
 	u32	(*get_ufs_hci_version)(struct ufs_hba *);
+	int	(*set_dma_mask)(struct ufs_hba *);
 	int	(*clk_scale_notify)(struct ufs_hba *, bool,
 				    enum ufs_notify_change_status);
 	int	(*setup_clocks)(struct ufs_hba *, bool,
@@ -582,12 +585,6 @@ enum ufshcd_quirks {
 	 */
 	UFSHCD_QUIRK_SKIP_PH_CONFIGURATION		= 1 << 16,
 
-	/*
-	 * This quirk needs to be enabled if the host controller has
-	 * 64-bit addressing supported capability but it doesn't work.
-	 */
-	UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS		= 1 << 17,
-
 	/*
 	 * This quirk needs to be enabled if the host controller has
 	 * auto-hibernate capability but it's FASTAUTO only.
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 07:49:29 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 10:49:29 -0500
Subject: [PATCH AUTOSEL 6.6 09/24] scsi: ufs: core: Make DMA mask configuration more flexible
In-Reply-To: <20241204155003.2213733-1-sashal@kernel.org>
References: <20241204155003.2213733-1-sashal@kernel.org>
Message-ID: <20241204155003.2213733-9-sashal@kernel.org>

From: Bart Van Assche <bvanassche at acm.org>

[ Upstream commit 78bc671bd1501e2f6c571e063301a4fdc5db53b2 ]

Replace UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS with
ufs_hba_variant_ops::set_dma_mask.  Update the Renesas driver
accordingly.  This patch enables supporting other configurations than
32-bit or 64-bit DMA addresses, e.g. 36-bit DMA addresses.

Signed-off-by: Bart Van Assche <bvanassche at acm.org>
Link: https://lore.kernel.org/r/20241018194753.775074-1-bvanassche at acm.org
Reviewed-by: Avri Altman <Avri.Altman at wdc.com>
Reviewed-by: Peter Wang <peter.wang at mediatek.com>
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 ++--
 drivers/ufs/host/ufs-renesas.c | 9 ++++++++-
 include/ufs/ufshcd.h           | 9 +++------
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index db4044358e22d..62fbbd56a86e8 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -2265,8 +2265,6 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)
 	int err;
 
 	hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES);
-	if (hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS)
-		hba->capabilities &= ~MASK_64_ADDRESSING_SUPPORT;
 
 	/* nutrs and nutmrs are 0 based values */
 	hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1;
@@ -10206,6 +10204,8 @@ EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
  */
 static int ufshcd_set_dma_mask(struct ufs_hba *hba)
 {
+	if (hba->vops && hba->vops->set_dma_mask)
+		return hba->vops->set_dma_mask(hba);
 	if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
 		if (!dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(64)))
 			return 0;
diff --git a/drivers/ufs/host/ufs-renesas.c b/drivers/ufs/host/ufs-renesas.c
index cc94970b86c93..ea3da773b1c14 100644
--- a/drivers/ufs/host/ufs-renesas.c
+++ b/drivers/ufs/host/ufs-renesas.c
@@ -7,6 +7,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
@@ -364,14 +365,20 @@ static int ufs_renesas_init(struct ufs_hba *hba)
 		return -ENOMEM;
 	ufshcd_set_variant(hba, priv);
 
-	hba->quirks |= UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS | UFSHCD_QUIRK_HIBERN_FASTAUTO;
+	hba->quirks |= UFSHCD_QUIRK_HIBERN_FASTAUTO;
 
 	return 0;
 }
 
+static int ufs_renesas_set_dma_mask(struct ufs_hba *hba)
+{
+	return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32));
+}
+
 static const struct ufs_hba_variant_ops ufs_renesas_vops = {
 	.name		= "renesas",
 	.init		= ufs_renesas_init,
+	.set_dma_mask	= ufs_renesas_set_dma_mask,
 	.setup_clocks	= ufs_renesas_setup_clocks,
 	.hce_enable_notify = ufs_renesas_hce_enable_notify,
 	.dbg_register_dump = ufs_renesas_dbg_register_dump,
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index 2a7d6f269d9e3..8b66228645d76 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -295,6 +295,8 @@ struct ufs_pwr_mode_info {
  * @name: variant name
  * @init: called when the driver is initialized
  * @exit: called to cleanup everything done in init
+ * @set_dma_mask: For setting another DMA mask than indicated by the 64AS
+ *	capability bit.
  * @get_ufs_hci_version: called to get UFS HCI version
  * @clk_scale_notify: notifies that clks are scaled up/down
  * @setup_clocks: called before touching any of the controller registers
@@ -332,6 +334,7 @@ struct ufs_hba_variant_ops {
 	int	(*init)(struct ufs_hba *);
 	void    (*exit)(struct ufs_hba *);
 	u32	(*get_ufs_hci_version)(struct ufs_hba *);
+	int	(*set_dma_mask)(struct ufs_hba *);
 	int	(*clk_scale_notify)(struct ufs_hba *, bool,
 				    enum ufs_notify_change_status);
 	int	(*setup_clocks)(struct ufs_hba *, bool,
@@ -613,12 +616,6 @@ enum ufshcd_quirks {
 	 */
 	UFSHCD_QUIRK_SKIP_PH_CONFIGURATION		= 1 << 16,
 
-	/*
-	 * This quirk needs to be enabled if the host controller has
-	 * 64-bit addressing supported capability but it doesn't work.
-	 */
-	UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS		= 1 << 17,
-
 	/*
 	 * This quirk needs to be enabled if the host controller has
 	 * auto-hibernate capability but it's FASTAUTO only.
-- 
2.43.0



From jonathanh at nvidia.com  Wed Dec  4 09:02:19 2024
From: jonathanh at nvidia.com (Jon Hunter)
Date: Wed, 4 Dec 2024 17:02:19 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap for
 non-paged SKB data
In-Reply-To: <Z1CFz7GpeIzkDro1@shell.armlinux.org.uk>
References: <20241021061023.2162701-1-0x1207@gmail.com>
 <d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
 <20241128144501.0000619b@gmail.com> <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com> <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
 <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
 <df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>
 <2g2lp3bkadc4wpeslmdoexpidoiqzt7vejar5xhjx5ayt3uox3@dqdyfzn6khn6>
 <Z1CFz7GpeIzkDro1@shell.armlinux.org.uk>
Message-ID: <9719982a-d40c-4110-9233-def2e6cb4d74@nvidia.com>

Hi Russell,

On 04/12/2024 16:39, Russell King (Oracle) wrote:
> On Wed, Dec 04, 2024 at 04:58:34PM +0100, Thierry Reding wrote:
>> This doesn't match the location from earlier, but at least there's
>> something afoot here that needs fixing. I suppose this could simply be
>> hiding any subsequent errors, so once this is fixed we might see other
>> similar issues.
> 
> Well, having a quick look at this, the first thing which stands out is:
> 
> In stmmac_tx_clean(), we have:
> 
>                  if (likely(tx_q->tx_skbuff_dma[entry].buf &&
>                             tx_q->tx_skbuff_dma[entry].buf_type != STMMAC_TXBUF_T
> _XDP_TX)) {
>                          if (tx_q->tx_skbuff_dma[entry].map_as_page)
>                                  dma_unmap_page(priv->device,
>                                                 tx_q->tx_skbuff_dma[entry].buf,
>                                                 tx_q->tx_skbuff_dma[entry].len,
>                                                 DMA_TO_DEVICE);
>                          else
>                                  dma_unmap_single(priv->device,
>                                                   tx_q->tx_skbuff_dma[entry].buf,
>                                                   tx_q->tx_skbuff_dma[entry].len,
>                                                   DMA_TO_DEVICE);
>                          tx_q->tx_skbuff_dma[entry].buf = 0;
>                          tx_q->tx_skbuff_dma[entry].len = 0;
>                          tx_q->tx_skbuff_dma[entry].map_as_page = false;
>                  }
> 
> So, tx_skbuff_dma[entry].buf is expected to point appropriately to the
> DMA region.
> 
> Now if we look at stmmac_tso_xmit():
> 
>          des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
>                               DMA_TO_DEVICE);
>          if (dma_mapping_error(priv->device, des))
>                  goto dma_map_err;
> 
>          if (priv->dma_cap.addr64 <= 32) {
> ...
>          } else {
> ...
>                  des += proto_hdr_len;
> ...
> 	}
> 
>          tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
>          tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
>          tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
>          tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
> 
> This will result in stmmac_tx_clean() calling dma_unmap_single() using
> "des" and "skb_headlen(skb)" as the buffer start and length.
> 
> One of the requirements of the DMA mapping API is that the DMA handle
> returned by the map operation will be passed into the unmap function.
> Not something that was offset. The length will also be the same.
> 
> We can clearly see above that there is a case where the DMA handle has
> been offset by proto_hdr_len, and when this is so, the value that is
> passed into the unmap operation no longer matches this requirement.
> 
> So, a question to the reporter - what is the value of
> priv->dma_cap.addr64 in your failing case? You should see the value
> in the "Using %d/%d bits DMA host/device width" kernel message.

It is ...

  dwc-eth-dwmac 2490000.ethernet: Using 40/40 bits DMA host/device width

Thanks
Jon

-- 
nvpublic



From jonathanh at nvidia.com  Wed Dec  4 09:03:14 2024
From: jonathanh at nvidia.com (Jon Hunter)
Date: Wed, 4 Dec 2024 17:03:14 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap for
 non-paged SKB data
In-Reply-To: <20241203111637.000023fe@gmail.com>
References: <20241021061023.2162701-1-0x1207@gmail.com>
 <d8112193-0386-4e14-b516-37c2d838171a@nvidia.com>
 <20241128144501.0000619b@gmail.com> <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com> <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
Message-ID: <44e7ae05-2eea-4602-b192-dbd01631169c@nvidia.com>


On 03/12/2024 03:16, Furong Xu wrote:
> On Mon, 2 Dec 2024 18:34:25 -0800, Jakub Kicinski <kuba at kernel.org> wrote:
> 
>> On Tue, 3 Dec 2024 10:03:31 +0800 Furong Xu wrote:
>>> I requested Jon to provide more info about "Tx DMA map failed" in previous
>>> reply, and he does not respond yet.
>>
>> What does it mean to provide "more info" about a print statement from
>> the driver? Is there a Kconfig which he needs to set to get more info?
>> Perhaps you should provide a debug patch he can apply on his tree, that
>> will print info about (1) which buffer mapping failed (head or frags);
>> (2) what the physical address was of the buffer that couldn't be mapped.
> 
> A debug patch to print info about buffer makes no sense here.
> Both Tegra186 Jetson TX2(tegra186-p2771-0000) and Tegra194 Jetson AGX Xavier
> (tegra194-p2972-0000) enable IOMMU/SMMU for stmmac in its device-tree node,
> buffer info should be investigated with detailed IOMMU/SMMU debug info from
> drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c together.
> 
> I am not an expert in IOMMU, so I cannot help more.
> 
> Without the help from Jon, our only choice is revert as you said.


Sorry Thierry and I were digging into this offline but yes I can provide 
any more info that is needed.

Jon

-- 
nvpublic



From laurent.pinchart at ideasonboard.com  Wed Dec  4 09:04:56 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 4 Dec 2024 19:04:56 +0200
Subject: [PATCH v4 media-next] media: rkisp1: Fix unused value issue
In-Reply-To: <20241119075944.GA31681@pendragon.ideasonboard.com>
References: <20241119072653.72260-1-dheeraj.linuxdev@gmail.com>
 <20241119075944.GA31681@pendragon.ideasonboard.com>
Message-ID: <20241204170456.GA16224@pendragon.ideasonboard.com>

On Tue, Nov 19, 2024 at 09:59:44AM +0200, Laurent Pinchart wrote:
> Hi Dheeraj,
> 
> Thank you for the patch.
> 
> On Tue, Nov 19, 2024 at 12:56:53PM +0530, Dheeraj Reddy Jonnalagadda wrote:
> > This commit fixes an unused value issue detected by Coverity (CID
> > 1519008). The error condition for the invalid MIPI CSI-2 is not
> > properly handled as the break statement would only exit the switch block
> > and not the entire loop. Fixed this by returning the error immediately
> > after the switch block.
> 
> The patch doesn't "return immediately". You can write "Fix this by
> breaking from the look immediately after the switch block when an error
> occurs." or something similar.
> 
> > 'Fixes: 8d4f126fde89 ("media: rkisp1: Make the internal CSI-2 receiver
> > optional")'
> 
> The Fixes tag should be formatted on a single line, without outer
> quotes, and without a blank line between it and the Signed-off-by line:
> 
> Fixes: 8d4f126fde89 ("media: rkisp1: Make the internal CSI-2 receiver optional")

That commit ID doesn't exist in the git history. The commit
corresponding to the message is 7d4f126fde89. I'll update the commit
message accordingly.

> > Signed-off-by: Dheeraj Reddy Jonnalagadda <dheeraj.linuxdev at gmail.com>
> 
> I can update the commit message when applying the patch, there's no need
> to submit a v5, unless if you want to. Please let me know if I should
> take this version and update the commit message, or if you will send a
> v5.
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> 
> > ---
> >  drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> > index dd114ab77800..9ad5026ab10a 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> > @@ -228,6 +228,9 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1)
> >  			break;
> >  		}
> >  
> > +		if (ret)
> > +			break;
> > +
> >  		/* Parse the endpoint and validate the bus type. */
> >  		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> >  		if (ret) {

-- 
Regards,

Laurent Pinchart


From sashal at kernel.org  Wed Dec  4 08:00:36 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 11:00:36 -0500
Subject: [PATCH AUTOSEL 6.11 11/13] i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock
In-Reply-To: <20241204160044.2216380-1-sashal@kernel.org>
References: <20241204160044.2216380-1-sashal@kernel.org>
Message-ID: <20241204160044.2216380-11-sashal@kernel.org>

From: Defa Li <defa.li at mediatek.com>

[ Upstream commit 6cf7b65f7029914dc0cd7db86fac9ee5159008c6 ]

A deadlock may happen since the i3c_master_register() acquires
&i3cbus->lock twice. See the log below.
Use i3cdev->desc->info instead of calling i3c_device_info() to
avoid acquiring the lock twice.

v2:
  - Modified the title and commit message

============================================
WARNING: possible recursive locking detected
6.11.0-mainline
--------------------------------------------
init/1 is trying to acquire lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_bus_normaluse_lock

but task is already holding lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&i3cbus->lock);
  lock(&i3cbus->lock);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

2 locks held by init/1:
 #0: fcffff809b6798f8 (&dev->mutex){....}-{3:3}, at: __driver_attach
 #1: f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

stack backtrace:
CPU: 6 UID: 0 PID: 1 Comm: init
Call trace:
 dump_backtrace+0xfc/0x17c
 show_stack+0x18/0x28
 dump_stack_lvl+0x40/0xc0
 dump_stack+0x18/0x24
 print_deadlock_bug+0x388/0x390
 __lock_acquire+0x18bc/0x32ec
 lock_acquire+0x134/0x2b0
 down_read+0x50/0x19c
 i3c_bus_normaluse_lock+0x14/0x24
 i3c_device_get_info+0x24/0x58
 i3c_device_uevent+0x34/0xa4
 dev_uevent+0x310/0x384
 kobject_uevent_env+0x244/0x414
 kobject_uevent+0x14/0x20
 device_add+0x278/0x460
 device_register+0x20/0x34
 i3c_master_register_new_i3c_devs+0x78/0x154
 i3c_master_register+0x6a0/0x6d4
 mtk_i3c_master_probe+0x3b8/0x4d8
 platform_probe+0xa0/0xe0
 really_probe+0x114/0x454
 __driver_probe_device+0xa0/0x15c
 driver_probe_device+0x3c/0x1ac
 __driver_attach+0xc4/0x1f0
 bus_for_each_dev+0x104/0x160
 driver_attach+0x24/0x34
 bus_add_driver+0x14c/0x294
 driver_register+0x68/0x104
 __platform_driver_register+0x20/0x30
 init_module+0x20/0xfe4
 do_one_initcall+0x184/0x464
 do_init_module+0x58/0x1ec
 load_module+0xefc/0x10c8
 __arm64_sys_finit_module+0x238/0x33c
 invoke_syscall+0x58/0x10c
 el0_svc_common+0xa8/0xdc
 do_el0_svc+0x1c/0x28
 el0_svc+0x50/0xac
 el0t_64_sync_handler+0x70/0xbc
 el0t_64_sync+0x1a8/0x1ac

Signed-off-by: Defa Li <defa.li at mediatek.com>
Link: https://lore.kernel.org/r/20241107132549.25439-1-defa.li at mediatek.com
Signed-off-by: Alexandre Belloni <alexandre.belloni at bootlin.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/i3c/master.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 7028f03c2c42e..5e3b63f78d2d2 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -282,7 +282,8 @@ static int i3c_device_uevent(const struct device *dev, struct kobj_uevent_env *e
 	struct i3c_device_info devinfo;
 	u16 manuf, part, ext;
 
-	i3c_device_get_info(i3cdev, &devinfo);
+	if (i3cdev->desc)
+		devinfo = i3cdev->desc->info;
 	manuf = I3C_PID_MANUF_ID(devinfo.pid);
 	part = I3C_PID_PART_ID(devinfo.pid);
 	ext = I3C_PID_EXTRA_INFO(devinfo.pid);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 08:01:07 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 11:01:07 -0500
Subject: [PATCH AUTOSEL 6.6 10/12] i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock
In-Reply-To: <20241204160115.2216718-1-sashal@kernel.org>
References: <20241204160115.2216718-1-sashal@kernel.org>
Message-ID: <20241204160115.2216718-10-sashal@kernel.org>

From: Defa Li <defa.li at mediatek.com>

[ Upstream commit 6cf7b65f7029914dc0cd7db86fac9ee5159008c6 ]

A deadlock may happen since the i3c_master_register() acquires
&i3cbus->lock twice. See the log below.
Use i3cdev->desc->info instead of calling i3c_device_info() to
avoid acquiring the lock twice.

v2:
  - Modified the title and commit message

============================================
WARNING: possible recursive locking detected
6.11.0-mainline
--------------------------------------------
init/1 is trying to acquire lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_bus_normaluse_lock

but task is already holding lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&i3cbus->lock);
  lock(&i3cbus->lock);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

2 locks held by init/1:
 #0: fcffff809b6798f8 (&dev->mutex){....}-{3:3}, at: __driver_attach
 #1: f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

stack backtrace:
CPU: 6 UID: 0 PID: 1 Comm: init
Call trace:
 dump_backtrace+0xfc/0x17c
 show_stack+0x18/0x28
 dump_stack_lvl+0x40/0xc0
 dump_stack+0x18/0x24
 print_deadlock_bug+0x388/0x390
 __lock_acquire+0x18bc/0x32ec
 lock_acquire+0x134/0x2b0
 down_read+0x50/0x19c
 i3c_bus_normaluse_lock+0x14/0x24
 i3c_device_get_info+0x24/0x58
 i3c_device_uevent+0x34/0xa4
 dev_uevent+0x310/0x384
 kobject_uevent_env+0x244/0x414
 kobject_uevent+0x14/0x20
 device_add+0x278/0x460
 device_register+0x20/0x34
 i3c_master_register_new_i3c_devs+0x78/0x154
 i3c_master_register+0x6a0/0x6d4
 mtk_i3c_master_probe+0x3b8/0x4d8
 platform_probe+0xa0/0xe0
 really_probe+0x114/0x454
 __driver_probe_device+0xa0/0x15c
 driver_probe_device+0x3c/0x1ac
 __driver_attach+0xc4/0x1f0
 bus_for_each_dev+0x104/0x160
 driver_attach+0x24/0x34
 bus_add_driver+0x14c/0x294
 driver_register+0x68/0x104
 __platform_driver_register+0x20/0x30
 init_module+0x20/0xfe4
 do_one_initcall+0x184/0x464
 do_init_module+0x58/0x1ec
 load_module+0xefc/0x10c8
 __arm64_sys_finit_module+0x238/0x33c
 invoke_syscall+0x58/0x10c
 el0_svc_common+0xa8/0xdc
 do_el0_svc+0x1c/0x28
 el0_svc+0x50/0xac
 el0t_64_sync_handler+0x70/0xbc
 el0t_64_sync+0x1a8/0x1ac

Signed-off-by: Defa Li <defa.li at mediatek.com>
Link: https://lore.kernel.org/r/20241107132549.25439-1-defa.li at mediatek.com
Signed-off-by: Alexandre Belloni <alexandre.belloni at bootlin.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/i3c/master.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 0e9ff5500a777..d66ff7a98c71d 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -280,7 +280,8 @@ static int i3c_device_uevent(const struct device *dev, struct kobj_uevent_env *e
 	struct i3c_device_info devinfo;
 	u16 manuf, part, ext;
 
-	i3c_device_get_info(i3cdev, &devinfo);
+	if (i3cdev->desc)
+		devinfo = i3cdev->desc->info;
 	manuf = I3C_PID_MANUF_ID(devinfo.pid);
 	part = I3C_PID_PART_ID(devinfo.pid);
 	ext = I3C_PID_EXTRA_INFO(devinfo.pid);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 08:00:00 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 11:00:00 -0500
Subject: [PATCH AUTOSEL 6.12 12/15] i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock
In-Reply-To: <20241204160010.2216008-1-sashal@kernel.org>
References: <20241204160010.2216008-1-sashal@kernel.org>
Message-ID: <20241204160010.2216008-12-sashal@kernel.org>

From: Defa Li <defa.li at mediatek.com>

[ Upstream commit 6cf7b65f7029914dc0cd7db86fac9ee5159008c6 ]

A deadlock may happen since the i3c_master_register() acquires
&i3cbus->lock twice. See the log below.
Use i3cdev->desc->info instead of calling i3c_device_info() to
avoid acquiring the lock twice.

v2:
  - Modified the title and commit message

============================================
WARNING: possible recursive locking detected
6.11.0-mainline
--------------------------------------------
init/1 is trying to acquire lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_bus_normaluse_lock

but task is already holding lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&i3cbus->lock);
  lock(&i3cbus->lock);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

2 locks held by init/1:
 #0: fcffff809b6798f8 (&dev->mutex){....}-{3:3}, at: __driver_attach
 #1: f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

stack backtrace:
CPU: 6 UID: 0 PID: 1 Comm: init
Call trace:
 dump_backtrace+0xfc/0x17c
 show_stack+0x18/0x28
 dump_stack_lvl+0x40/0xc0
 dump_stack+0x18/0x24
 print_deadlock_bug+0x388/0x390
 __lock_acquire+0x18bc/0x32ec
 lock_acquire+0x134/0x2b0
 down_read+0x50/0x19c
 i3c_bus_normaluse_lock+0x14/0x24
 i3c_device_get_info+0x24/0x58
 i3c_device_uevent+0x34/0xa4
 dev_uevent+0x310/0x384
 kobject_uevent_env+0x244/0x414
 kobject_uevent+0x14/0x20
 device_add+0x278/0x460
 device_register+0x20/0x34
 i3c_master_register_new_i3c_devs+0x78/0x154
 i3c_master_register+0x6a0/0x6d4
 mtk_i3c_master_probe+0x3b8/0x4d8
 platform_probe+0xa0/0xe0
 really_probe+0x114/0x454
 __driver_probe_device+0xa0/0x15c
 driver_probe_device+0x3c/0x1ac
 __driver_attach+0xc4/0x1f0
 bus_for_each_dev+0x104/0x160
 driver_attach+0x24/0x34
 bus_add_driver+0x14c/0x294
 driver_register+0x68/0x104
 __platform_driver_register+0x20/0x30
 init_module+0x20/0xfe4
 do_one_initcall+0x184/0x464
 do_init_module+0x58/0x1ec
 load_module+0xefc/0x10c8
 __arm64_sys_finit_module+0x238/0x33c
 invoke_syscall+0x58/0x10c
 el0_svc_common+0xa8/0xdc
 do_el0_svc+0x1c/0x28
 el0_svc+0x50/0xac
 el0t_64_sync_handler+0x70/0xbc
 el0t_64_sync+0x1a8/0x1ac

Signed-off-by: Defa Li <defa.li at mediatek.com>
Link: https://lore.kernel.org/r/20241107132549.25439-1-defa.li at mediatek.com
Signed-off-by: Alexandre Belloni <alexandre.belloni at bootlin.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/i3c/master.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 6f3eb710a75d6..bb8a8bf0c4c7c 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -282,7 +282,8 @@ static int i3c_device_uevent(const struct device *dev, struct kobj_uevent_env *e
 	struct i3c_device_info devinfo;
 	u16 manuf, part, ext;
 
-	i3c_device_get_info(i3cdev, &devinfo);
+	if (i3cdev->desc)
+		devinfo = i3cdev->desc->info;
 	manuf = I3C_PID_MANUF_ID(devinfo.pid);
 	part = I3C_PID_PART_ID(devinfo.pid);
 	ext = I3C_PID_EXTRA_INFO(devinfo.pid);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 08:01:38 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 11:01:38 -0500
Subject: [PATCH AUTOSEL 6.1 6/6] i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock
In-Reply-To: <20241204160142.2217017-1-sashal@kernel.org>
References: <20241204160142.2217017-1-sashal@kernel.org>
Message-ID: <20241204160142.2217017-6-sashal@kernel.org>

From: Defa Li <defa.li at mediatek.com>

[ Upstream commit 6cf7b65f7029914dc0cd7db86fac9ee5159008c6 ]

A deadlock may happen since the i3c_master_register() acquires
&i3cbus->lock twice. See the log below.
Use i3cdev->desc->info instead of calling i3c_device_info() to
avoid acquiring the lock twice.

v2:
  - Modified the title and commit message

============================================
WARNING: possible recursive locking detected
6.11.0-mainline
--------------------------------------------
init/1 is trying to acquire lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_bus_normaluse_lock

but task is already holding lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&i3cbus->lock);
  lock(&i3cbus->lock);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

2 locks held by init/1:
 #0: fcffff809b6798f8 (&dev->mutex){....}-{3:3}, at: __driver_attach
 #1: f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

stack backtrace:
CPU: 6 UID: 0 PID: 1 Comm: init
Call trace:
 dump_backtrace+0xfc/0x17c
 show_stack+0x18/0x28
 dump_stack_lvl+0x40/0xc0
 dump_stack+0x18/0x24
 print_deadlock_bug+0x388/0x390
 __lock_acquire+0x18bc/0x32ec
 lock_acquire+0x134/0x2b0
 down_read+0x50/0x19c
 i3c_bus_normaluse_lock+0x14/0x24
 i3c_device_get_info+0x24/0x58
 i3c_device_uevent+0x34/0xa4
 dev_uevent+0x310/0x384
 kobject_uevent_env+0x244/0x414
 kobject_uevent+0x14/0x20
 device_add+0x278/0x460
 device_register+0x20/0x34
 i3c_master_register_new_i3c_devs+0x78/0x154
 i3c_master_register+0x6a0/0x6d4
 mtk_i3c_master_probe+0x3b8/0x4d8
 platform_probe+0xa0/0xe0
 really_probe+0x114/0x454
 __driver_probe_device+0xa0/0x15c
 driver_probe_device+0x3c/0x1ac
 __driver_attach+0xc4/0x1f0
 bus_for_each_dev+0x104/0x160
 driver_attach+0x24/0x34
 bus_add_driver+0x14c/0x294
 driver_register+0x68/0x104
 __platform_driver_register+0x20/0x30
 init_module+0x20/0xfe4
 do_one_initcall+0x184/0x464
 do_init_module+0x58/0x1ec
 load_module+0xefc/0x10c8
 __arm64_sys_finit_module+0x238/0x33c
 invoke_syscall+0x58/0x10c
 el0_svc_common+0xa8/0xdc
 do_el0_svc+0x1c/0x28
 el0_svc+0x50/0xac
 el0t_64_sync_handler+0x70/0xbc
 el0t_64_sync+0x1a8/0x1ac

Signed-off-by: Defa Li <defa.li at mediatek.com>
Link: https://lore.kernel.org/r/20241107132549.25439-1-defa.li at mediatek.com
Signed-off-by: Alexandre Belloni <alexandre.belloni at bootlin.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/i3c/master.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index ab0b5691b03e0..ac97bf9c55c39 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -279,7 +279,8 @@ static int i3c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 	struct i3c_device_info devinfo;
 	u16 manuf, part, ext;
 
-	i3c_device_get_info(i3cdev, &devinfo);
+	if (i3cdev->desc)
+		devinfo = i3cdev->desc->info;
 	manuf = I3C_PID_MANUF_ID(devinfo.pid);
 	part = I3C_PID_PART_ID(devinfo.pid);
 	ext = I3C_PID_EXTRA_INFO(devinfo.pid);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 08:01:56 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 11:01:56 -0500
Subject: [PATCH AUTOSEL 5.15 6/6] i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock
In-Reply-To: <20241204160200.2217169-1-sashal@kernel.org>
References: <20241204160200.2217169-1-sashal@kernel.org>
Message-ID: <20241204160200.2217169-6-sashal@kernel.org>

From: Defa Li <defa.li at mediatek.com>

[ Upstream commit 6cf7b65f7029914dc0cd7db86fac9ee5159008c6 ]

A deadlock may happen since the i3c_master_register() acquires
&i3cbus->lock twice. See the log below.
Use i3cdev->desc->info instead of calling i3c_device_info() to
avoid acquiring the lock twice.

v2:
  - Modified the title and commit message

============================================
WARNING: possible recursive locking detected
6.11.0-mainline
--------------------------------------------
init/1 is trying to acquire lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_bus_normaluse_lock

but task is already holding lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&i3cbus->lock);
  lock(&i3cbus->lock);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

2 locks held by init/1:
 #0: fcffff809b6798f8 (&dev->mutex){....}-{3:3}, at: __driver_attach
 #1: f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

stack backtrace:
CPU: 6 UID: 0 PID: 1 Comm: init
Call trace:
 dump_backtrace+0xfc/0x17c
 show_stack+0x18/0x28
 dump_stack_lvl+0x40/0xc0
 dump_stack+0x18/0x24
 print_deadlock_bug+0x388/0x390
 __lock_acquire+0x18bc/0x32ec
 lock_acquire+0x134/0x2b0
 down_read+0x50/0x19c
 i3c_bus_normaluse_lock+0x14/0x24
 i3c_device_get_info+0x24/0x58
 i3c_device_uevent+0x34/0xa4
 dev_uevent+0x310/0x384
 kobject_uevent_env+0x244/0x414
 kobject_uevent+0x14/0x20
 device_add+0x278/0x460
 device_register+0x20/0x34
 i3c_master_register_new_i3c_devs+0x78/0x154
 i3c_master_register+0x6a0/0x6d4
 mtk_i3c_master_probe+0x3b8/0x4d8
 platform_probe+0xa0/0xe0
 really_probe+0x114/0x454
 __driver_probe_device+0xa0/0x15c
 driver_probe_device+0x3c/0x1ac
 __driver_attach+0xc4/0x1f0
 bus_for_each_dev+0x104/0x160
 driver_attach+0x24/0x34
 bus_add_driver+0x14c/0x294
 driver_register+0x68/0x104
 __platform_driver_register+0x20/0x30
 init_module+0x20/0xfe4
 do_one_initcall+0x184/0x464
 do_init_module+0x58/0x1ec
 load_module+0xefc/0x10c8
 __arm64_sys_finit_module+0x238/0x33c
 invoke_syscall+0x58/0x10c
 el0_svc_common+0xa8/0xdc
 do_el0_svc+0x1c/0x28
 el0_svc+0x50/0xac
 el0t_64_sync_handler+0x70/0xbc
 el0t_64_sync+0x1a8/0x1ac

Signed-off-by: Defa Li <defa.li at mediatek.com>
Link: https://lore.kernel.org/r/20241107132549.25439-1-defa.li at mediatek.com
Signed-off-by: Alexandre Belloni <alexandre.belloni at bootlin.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/i3c/master.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index b6abbb0acbbd3..c4663501a971c 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -279,7 +279,8 @@ static int i3c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 	struct i3c_device_info devinfo;
 	u16 manuf, part, ext;
 
-	i3c_device_get_info(i3cdev, &devinfo);
+	if (i3cdev->desc)
+		devinfo = i3cdev->desc->info;
 	manuf = I3C_PID_MANUF_ID(devinfo.pid);
 	part = I3C_PID_PART_ID(devinfo.pid);
 	ext = I3C_PID_EXTRA_INFO(devinfo.pid);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 08:02:14 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 11:02:14 -0500
Subject: [PATCH AUTOSEL 5.10 4/4] i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock
In-Reply-To: <20241204160216.2217323-1-sashal@kernel.org>
References: <20241204160216.2217323-1-sashal@kernel.org>
Message-ID: <20241204160216.2217323-4-sashal@kernel.org>

From: Defa Li <defa.li at mediatek.com>

[ Upstream commit 6cf7b65f7029914dc0cd7db86fac9ee5159008c6 ]

A deadlock may happen since the i3c_master_register() acquires
&i3cbus->lock twice. See the log below.
Use i3cdev->desc->info instead of calling i3c_device_info() to
avoid acquiring the lock twice.

v2:
  - Modified the title and commit message

============================================
WARNING: possible recursive locking detected
6.11.0-mainline
--------------------------------------------
init/1 is trying to acquire lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_bus_normaluse_lock

but task is already holding lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&i3cbus->lock);
  lock(&i3cbus->lock);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

2 locks held by init/1:
 #0: fcffff809b6798f8 (&dev->mutex){....}-{3:3}, at: __driver_attach
 #1: f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

stack backtrace:
CPU: 6 UID: 0 PID: 1 Comm: init
Call trace:
 dump_backtrace+0xfc/0x17c
 show_stack+0x18/0x28
 dump_stack_lvl+0x40/0xc0
 dump_stack+0x18/0x24
 print_deadlock_bug+0x388/0x390
 __lock_acquire+0x18bc/0x32ec
 lock_acquire+0x134/0x2b0
 down_read+0x50/0x19c
 i3c_bus_normaluse_lock+0x14/0x24
 i3c_device_get_info+0x24/0x58
 i3c_device_uevent+0x34/0xa4
 dev_uevent+0x310/0x384
 kobject_uevent_env+0x244/0x414
 kobject_uevent+0x14/0x20
 device_add+0x278/0x460
 device_register+0x20/0x34
 i3c_master_register_new_i3c_devs+0x78/0x154
 i3c_master_register+0x6a0/0x6d4
 mtk_i3c_master_probe+0x3b8/0x4d8
 platform_probe+0xa0/0xe0
 really_probe+0x114/0x454
 __driver_probe_device+0xa0/0x15c
 driver_probe_device+0x3c/0x1ac
 __driver_attach+0xc4/0x1f0
 bus_for_each_dev+0x104/0x160
 driver_attach+0x24/0x34
 bus_add_driver+0x14c/0x294
 driver_register+0x68/0x104
 __platform_driver_register+0x20/0x30
 init_module+0x20/0xfe4
 do_one_initcall+0x184/0x464
 do_init_module+0x58/0x1ec
 load_module+0xefc/0x10c8
 __arm64_sys_finit_module+0x238/0x33c
 invoke_syscall+0x58/0x10c
 el0_svc_common+0xa8/0xdc
 do_el0_svc+0x1c/0x28
 el0_svc+0x50/0xac
 el0t_64_sync_handler+0x70/0xbc
 el0t_64_sync+0x1a8/0x1ac

Signed-off-by: Defa Li <defa.li at mediatek.com>
Link: https://lore.kernel.org/r/20241107132549.25439-1-defa.li at mediatek.com
Signed-off-by: Alexandre Belloni <alexandre.belloni at bootlin.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/i3c/master.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 828fb236a63ae..525f789b0f86c 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -279,7 +279,8 @@ static int i3c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 	struct i3c_device_info devinfo;
 	u16 manuf, part, ext;
 
-	i3c_device_get_info(i3cdev, &devinfo);
+	if (i3cdev->desc)
+		devinfo = i3cdev->desc->info;
 	manuf = I3C_PID_MANUF_ID(devinfo.pid);
 	part = I3C_PID_PART_ID(devinfo.pid);
 	ext = I3C_PID_EXTRA_INFO(devinfo.pid);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 08:02:25 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 11:02:25 -0500
Subject: [PATCH AUTOSEL 5.4 4/4] i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock
In-Reply-To: <20241204160227.2217428-1-sashal@kernel.org>
References: <20241204160227.2217428-1-sashal@kernel.org>
Message-ID: <20241204160227.2217428-4-sashal@kernel.org>

From: Defa Li <defa.li at mediatek.com>

[ Upstream commit 6cf7b65f7029914dc0cd7db86fac9ee5159008c6 ]

A deadlock may happen since the i3c_master_register() acquires
&i3cbus->lock twice. See the log below.
Use i3cdev->desc->info instead of calling i3c_device_info() to
avoid acquiring the lock twice.

v2:
  - Modified the title and commit message

============================================
WARNING: possible recursive locking detected
6.11.0-mainline
--------------------------------------------
init/1 is trying to acquire lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_bus_normaluse_lock

but task is already holding lock:
f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&i3cbus->lock);
  lock(&i3cbus->lock);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

2 locks held by init/1:
 #0: fcffff809b6798f8 (&dev->mutex){....}-{3:3}, at: __driver_attach
 #1: f1ffff80a6a40dc0 (&i3cbus->lock){++++}-{3:3}, at: i3c_master_register

stack backtrace:
CPU: 6 UID: 0 PID: 1 Comm: init
Call trace:
 dump_backtrace+0xfc/0x17c
 show_stack+0x18/0x28
 dump_stack_lvl+0x40/0xc0
 dump_stack+0x18/0x24
 print_deadlock_bug+0x388/0x390
 __lock_acquire+0x18bc/0x32ec
 lock_acquire+0x134/0x2b0
 down_read+0x50/0x19c
 i3c_bus_normaluse_lock+0x14/0x24
 i3c_device_get_info+0x24/0x58
 i3c_device_uevent+0x34/0xa4
 dev_uevent+0x310/0x384
 kobject_uevent_env+0x244/0x414
 kobject_uevent+0x14/0x20
 device_add+0x278/0x460
 device_register+0x20/0x34
 i3c_master_register_new_i3c_devs+0x78/0x154
 i3c_master_register+0x6a0/0x6d4
 mtk_i3c_master_probe+0x3b8/0x4d8
 platform_probe+0xa0/0xe0
 really_probe+0x114/0x454
 __driver_probe_device+0xa0/0x15c
 driver_probe_device+0x3c/0x1ac
 __driver_attach+0xc4/0x1f0
 bus_for_each_dev+0x104/0x160
 driver_attach+0x24/0x34
 bus_add_driver+0x14c/0x294
 driver_register+0x68/0x104
 __platform_driver_register+0x20/0x30
 init_module+0x20/0xfe4
 do_one_initcall+0x184/0x464
 do_init_module+0x58/0x1ec
 load_module+0xefc/0x10c8
 __arm64_sys_finit_module+0x238/0x33c
 invoke_syscall+0x58/0x10c
 el0_svc_common+0xa8/0xdc
 do_el0_svc+0x1c/0x28
 el0_svc+0x50/0xac
 el0t_64_sync_handler+0x70/0xbc
 el0t_64_sync+0x1a8/0x1ac

Signed-off-by: Defa Li <defa.li at mediatek.com>
Link: https://lore.kernel.org/r/20241107132549.25439-1-defa.li at mediatek.com
Signed-off-by: Alexandre Belloni <alexandre.belloni at bootlin.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/i3c/master.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 02dc8e29c8280..0503f8398a86a 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -257,7 +257,8 @@ static int i3c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 	struct i3c_device_info devinfo;
 	u16 manuf, part, ext;
 
-	i3c_device_get_info(i3cdev, &devinfo);
+	if (i3cdev->desc)
+		devinfo = i3cdev->desc->info;
 	manuf = I3C_PID_MANUF_ID(devinfo.pid);
 	part = I3C_PID_PART_ID(devinfo.pid);
 	ext = I3C_PID_EXTRA_INFO(devinfo.pid);
-- 
2.43.0



From lkp at intel.com  Wed Dec  4 09:13:06 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 5 Dec 2024 01:13:06 +0800
Subject: [PATCH v4 1/2] input: keypad: add new keypad driver for MA35D1
In-Reply-To: <20241204021014.5083-2-mjchen0829@gmail.com>
References: <20241204021014.5083-2-mjchen0829@gmail.com>
Message-ID: <202412050142.nkbl6PnK-lkp@intel.com>

Hi Ming-Jen,

kernel test robot noticed the following build errors:

[auto build test ERROR on dtor-input/next]
[also build test ERROR on dtor-input/for-linus hid/for-next soc/for-next linus/master v6.13-rc1 next-20241203]
[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/Ming-Jen-Chen/input-keypad-add-new-keypad-driver-for-MA35D1/20241204-123001
base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
patch link:    https://lore.kernel.org/r/20241204021014.5083-2-mjchen0829%40gmail.com
patch subject: [PATCH v4 1/2] input: keypad: add new keypad driver for MA35D1
config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20241205/202412050142.nkbl6PnK-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241205/202412050142.nkbl6PnK-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/202412050142.nkbl6PnK-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/input/keyboard/ma35d1_keypad.c:9:
   In file included from include/linux/input.h:19:
   In file included from include/linux/device.h:32:
   In file included from include/linux/device/driver.h:21:
   In file included from include/linux/module.h:19:
   In file included from include/linux/elf.h:6:
   In file included from arch/s390/include/asm/elf.h:181:
   In file included from arch/s390/include/asm/mmu_context.h:11:
   In file included from arch/s390/include/asm/pgalloc.h:18:
   In file included from include/linux/mm.h:2228:
   include/linux/vmstat.h:503:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     503 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     504 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:510:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     510 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     511 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:517:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     517 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:523:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     523 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     524 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/input/keyboard/ma35d1_keypad.c:83:17: error: call to undeclared function 'readl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
      83 |         key_event[0] = readl(keypad->mmio_base + KPI_KPE0);
         |                        ^
   drivers/input/keyboard/ma35d1_keypad.c:89:2: error: call to undeclared function 'writel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
      89 |         writel(key_event[0], (keypad->mmio_base + KPI_KPE0));
         |         ^
   drivers/input/keyboard/ma35d1_keypad.c:123:12: error: call to undeclared function 'readl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     123 |         kstatus = readl(keypad->mmio_base + KPI_STATUS);
         |                   ^
   drivers/input/keyboard/ma35d1_keypad.c:129:4: error: call to undeclared function 'writel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     129 |                         writel(PDWAKE, (keypad->mmio_base + KPI_STATUS));
         |                         ^
   drivers/input/keyboard/ma35d1_keypad.c:148:2: error: call to undeclared function 'writel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     148 |         writel(val, keypad->mmio_base + KPI_CONF);
         |         ^
   drivers/input/keyboard/ma35d1_keypad.c:159:8: error: call to undeclared function 'readl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     159 |         val = readl(keypad->mmio_base + KPI_KPE0) & ~ENKP;
         |               ^
   drivers/input/keyboard/ma35d1_keypad.c:160:2: error: call to undeclared function 'writel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     160 |         writel(val, keypad->mmio_base + KPI_CONF);
         |         ^
   drivers/input/keyboard/ma35d1_keypad.c:166:17: warning: array index 12 is past the end of the array (that has type 'const unsigned int[12]') [-Warray-bounds]
     166 |         u32 min_diff = debounce_values[NUM_SETTINGS];
         |                        ^               ~~~~~~~~~~~~
   drivers/input/keyboard/ma35d1_keypad.c:53:1: note: array 'debounce_values' declared here
      53 | static const unsigned int debounce_values[NUM_SETTINGS] = {
         | ^
   drivers/input/keyboard/ma35d1_keypad.c:173:25: warning: array index 12 is past the end of the array (that has type 'const unsigned int[12]') [-Warray-bounds]
     173 |         keypad->debounce_val = debounce_register[NUM_SETTINGS];
         |                                ^                 ~~~~~~~~~~~~
   drivers/input/keyboard/ma35d1_keypad.c:57:1: note: array 'debounce_register' declared here
      57 | static const unsigned int debounce_register[NUM_SETTINGS] = {
         | ^
   drivers/input/keyboard/ma35d1_keypad.c:349:3: error: call to undeclared function 'writel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     349 |                 writel(readl(keypad->mmio_base + KPI_CONF) | WAKEUP, keypad->mmio_base + KPI_CONF);
         |                 ^
   drivers/input/keyboard/ma35d1_keypad.c:349:10: error: call to undeclared function 'readl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     349 |                 writel(readl(keypad->mmio_base + KPI_CONF) | WAKEUP, keypad->mmio_base + KPI_CONF);
         |                        ^
   drivers/input/keyboard/ma35d1_keypad.c:359:3: error: call to undeclared function 'writel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     359 |                 writel(readl(keypad->mmio_base + KPI_CONF) & ~(WAKEUP),
         |                 ^
   drivers/input/keyboard/ma35d1_keypad.c:359:10: error: call to undeclared function 'readl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     359 |                 writel(readl(keypad->mmio_base + KPI_CONF) & ~(WAKEUP),
         |                        ^
   6 warnings and 11 errors generated.


vim +/readl +83 drivers/input/keyboard/ma35d1_keypad.c

    72	
    73	static void ma35d1_keypad_scan_matrix(struct ma35d1_keypad *keypad, unsigned int status)
    74	{
    75		struct input_dev *input_dev = keypad->input_dev;
    76		u32 row_shift = get_count_order(keypad->kpi_col);
    77		u32 *keymap = input_dev->keycode;
    78		u32 code, key, index;
    79		u32 key_event[4];
    80		u64 pressed_keys = 0, released_keys = 0;
    81	
    82		/* Read key event status */
  > 83		key_event[0] = readl(keypad->mmio_base + KPI_KPE0);
    84		key_event[1] = readl(keypad->mmio_base + KPI_KPE1);
    85		key_event[2] = readl(keypad->mmio_base + KPI_KRE0);
    86		key_event[3] = readl(keypad->mmio_base + KPI_KRE1);
    87	
    88		/* Clear key event status */
    89		writel(key_event[0], (keypad->mmio_base + KPI_KPE0));
    90		writel(key_event[1], (keypad->mmio_base + KPI_KPE1));
    91		writel(key_event[2], (keypad->mmio_base + KPI_KRE0));
    92		writel(key_event[3], (keypad->mmio_base + KPI_KRE1));
    93	
    94		pressed_keys  = key_event[0] | ((u64)key_event[1] << 32);
    95		released_keys = key_event[2] | ((u64)key_event[3] << 32);
    96	
    97		/* Process pressed keys */
    98		for_each_set_bit(index, (const unsigned long *)&pressed_keys, KEY_EVENT_BITS) {
    99			code = MATRIX_SCAN_CODE(index / 8, (index % 8), row_shift);
   100			key = keymap[code];
   101	
   102			input_event(input_dev, EV_MSC, MSC_SCAN, code);
   103			input_report_key(input_dev, key, 1);
   104		}
   105	
   106		/* Process released keys */
   107		for_each_set_bit(index, (const unsigned long *)&released_keys, KEY_EVENT_BITS) {
   108			code = MATRIX_SCAN_CODE(index / 8, (index % 8), row_shift);
   109			key = keymap[code];
   110	
   111			input_event(input_dev, EV_MSC, MSC_SCAN, code);
   112			input_report_key(input_dev, key, 0);
   113		}
   114	
   115		input_sync(input_dev);
   116	}
   117	

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


From jbrunet at baylibre.com  Wed Dec  4 09:19:50 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Wed, 04 Dec 2024 18:19:50 +0100
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <37b656cc8272552ba07c93c5a9a59641.sboyd@kernel.org> (Stephen
	Boyd's message of "Tue, 03 Dec 2024 12:15:48 -0800")
References: <20241127-clk-audio-fix-rst-missing-v1-1-9f9d0ab98fce@baylibre.com>
	<f8de4a2a-776f-4c10-b75e-e845bcc38dde@app.fastmail.com>
	<1j4j3r32ld.fsf@starbuckisacylon.baylibre.com>
	<306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com>
	<1jy1131kxz.fsf@starbuckisacylon.baylibre.com>
	<c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com>
	<1jplmf1jqa.fsf@starbuckisacylon.baylibre.com>
	<ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com>
	<df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org>
	<1jr06pkof6.fsf@starbuckisacylon.baylibre.com>
	<37b656cc8272552ba07c93c5a9a59641.sboyd@kernel.org>
Message-ID: <1jfrn3l615.fsf@starbuckisacylon.baylibre.com>

On Tue 03 Dec 2024 at 12:15, Stephen Boyd <sboyd at kernel.org> wrote:

> Quoting Jerome Brunet (2024-12-03 03:15:41)
>> On Mon 02 Dec 2024 at 18:53, Stephen Boyd <sboyd at kernel.org> wrote:
>> >
>> > I think the best approach is to add the reset auxilary device with a
>> > function that creates the auxiliary device directly by string name and
>> > does nothing else. Maybe we can have some helper in the auxiliary
>> > layer that does that all for us, because it's quite a bit of boiler
>> > plate that we need to write over and over again. Something like:
>> >
>> >   int devm_auxiliary_device_create(struct device *parent, const char *name)
>> >
>> > that does the whole kzalloc() + ida dance that
>> > devm_meson_rst_aux_register() is doing today and wraps it all up so that
>> > the device is removed when the parent driver unbinds. Then this clk
>> > driver can register the reset device with a single call and not need to
>> > do anything besides select AUXILIARY_BUS.
>> 
>> I think this is fairly close to what I proposed in the inital RFC, but
>> generic instead of specific.
>
> Ok :-/ I've realized that we need this sort of approach in more places
> to logically split the device without making it SoC specific. It's only
> useful to have the registration API live in the driver when we need to
> call functions provided by that module from the driver registering the
> auxiliary device.
>
>> 
>> I suspect the the generic path is likely to trigger more discussion.
>> I'd like to be able to finish this migration, instead of leaving half
>> finished like it is now.
>
> Is the half finished migration a problem for this cycle? I was intending
> to send the revert later this week and try again next cycle.

Not really, with the fix you applied. There is just code present in
reset that should not be used in its current form. I'd prefer to
sanitise the situation sooner rather than later.

>
>> 
>> May I add back the boiler plate code in drivers/clk/meson, similar to
>> what was proposed in the RFC [1] and propose the generic implementation
>> in parallel ? It will just be a matter of switching when/if it is approved.
>
> Sure. You can make devm_meson_clk_rst_aux_register() use the same
> signature as I proposed above so that it's a one line patch later. And
> definitely drop the imply RESET_MESON and depends on REGMAP part. Maybe
> you can put it in the clkc-utils file?

Sure. Few things I'd like to clarify

* I tend think like Arnd, platform data will be needed eventually. Not
  sure having 2 functions, one with the param, one without is really
  worth it. We could just pass NULL when it is not needed. It is not
  uncommon. Would it be acceptable ? (for the generic helper, the
  temporary solution does not need that for sure)

* You mean (meson-)clkc-utils.c ? I could but that would add dependency on
  the auxiliary_bus for clock controllers that don't need it. It is a
  minor problem really that I could just ignore.
  I'd rather keep this helper separate if possible.

* Why drop 'imply RESET_MESON_AUX' ? I would still like the
  COMMON_CLK_AXG_AUDIO to 'strongly suggest' RESET_MESON_AUX, with
  dependency problem sorted out.
  
-- 
Jerome


From linux at leemhuis.info  Wed Dec  4 09:43:24 2024
From: linux at leemhuis.info (Thorsten Leemhuis)
Date: Wed, 4 Dec 2024 18:43:24 +0100
Subject: [PATCH 6.12 470/826] perf stat: Uniquify event name improvements
In-Reply-To: <f2ada8a7-165b-41fb-8b7b-3c0d16bb8216@leemhuis.info>
References: <20241203144743.428732212@linuxfoundation.org>
 <20241203144802.097952233@linuxfoundation.org>
 <f2ada8a7-165b-41fb-8b7b-3c0d16bb8216@leemhuis.info>
Message-ID: <563836eb-78da-4a89-b80a-52775107161d@leemhuis.info>

On 03.12.24 18:24, Thorsten Leemhuis wrote:
> On 03.12.24 15:43, Greg Kroah-Hartman wrote:
>> 6.12-stable review patch.  If anyone has any objections, please let me know.
>>
>> ------------------
>>
>> From: Ian Rogers <irogers at google.com>
>>
>> [ Upstream commit 057f8bfc6f7070577523d1e3081081bbf4229c1c ]
>>
>> Without aggregation on Intel:
> 
> My 6.11.y-rc and 6.12.y-rc builds for Fedora failed when building perf. 
> I did not bisect, but from a brief look at the error message (see
> below) I suspect it might be caused by this patch, which is the
> second of the patch-set "Event parsing fixes":
> https://lore.kernel.org/all/20240926144851.245903-1-james.clark at linaro.org/

TWIMC, Florian Fainelli and Naresh Kamboju (both now CCed) meanwhile
reported the same problem for the latest 6.11.y and 6.12.y rc releases:

https://lore.kernel.org/all/5eeb1f9c-2b9f-49f1-9861-051478a8630d at gmail.com/
https://lore.kernel.org/all/713b5871-c7a3-44fa-a5ac-5cf558be81c9 at gmail.com/
https://lore.kernel.org/all/CA+G9fYu21yqTvL428TFueMJ1uU1H_u8Vc470dER2CTrNK=Js0g at mail.gmail.com/
https://lore.kernel.org/all/CA+G9fYtNvEDcUEuv=QFC84y+pXY1UszoRYOitJztCApLV7-psg at mail.gmail.com/

Ciao, Thorsten

> To my untrained eyes and from a quick look I guess the first patch
> in the series needs to be backported as well:
> perf evsel: Add alternate_hw_config and use in evsel__match
> https://lore.kernel.org/all/20240926144851.245903-2-james.clark at linaro.org/
> 
> This is 22a4db3c36034e ("perf evsel: Add alternate_hw_config
> and use in evsel__match") in mainline. I tried to cherry-pick it
> on-top of 6.12.2-rc1, but there were a few small conflicts. 
> 
> Ciao, Thorsten
> 
> P.S.: The build error:
> 
>   gcc -Wp,-MD,util/.topdown.o.d -Wp,-MT,util/topdown.o -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wno-system-headers -Wold-style-definition -Wpacked -Wredundant-decls -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wundef -Wwrite-strings -Wformat -Wno-type-limits -Wstrict-aliasing=3 -Wshadow -DHAVE_SYSCALL_TABLE_SUPPORT -Iarch/x86/include/generated -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET -DNDEBUG=1 -O3 -fno-omit-frame-pointer -Wall -Wextra -std=gnu11 -fstack-protector-all -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/util/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/arch/x86/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/include/ -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/arch/x86/include/uapi -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/include/uapi -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/arch/x86/include/ -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/arch/x86/ -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/util -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf -DHAVE_PTHREAD_ATTR_SETAFFINITY_NP -DHAVE_PTHREAD_BARRIER -DHAVE_EVENTFD_SUPPORT -DHAVE_GET_CURRENT_DIR_NAME -DHAVE_GETTID -DHAVE_FILE_HANDLE -DHAVE_DWARF_GETLOCATIONS_SUPPORT -DHAVE_DWARF_CFI_SUPPORT -DHAVE_AIO_SUPPORT -DHAVE_SCANDIRAT_SUPPORT -DHAVE_SCHED_GETCPU_SUPPORT -DHAVE_SETNS_SUPPORT -DHAVE_ZLIB_SUPPORT -DHAVE_LIBELF_SUPPORT -DHAVE_ELF_GETPHDRNUM_SUPPORT -DHAVE_GELF_GETNOTE_SUPPORT -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT -DHAVE_DWARF_SUPPORT -DHAVE_LIBBPF_SUPPORT -DHAVE_SDT_EVENT -DHAVE_JITDUMP -DHAVE_BPF_SKEL -DHAVE_DWARF_UNWIND_SUPPORT -DHAVE_LIBCRYPTO_SUPPORT -DHAVE_SLANG_SUPPORT -DHAVE_LIBPERL_SUPPORT -DHAVE_TIMERFD_SUPPORT -DHAVE_LIBPYTHON_SUPPORT -fPIC -DHAVE_LIBLLVM_SUPPORT -I/usr/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DHAVE_CXA_DEMANGLE_SUPPORT -DHAVE_LZMA_SUPPORT -DHAVE_ZSTD_SUPPORT -DHAVE_BACKTRACE_SUPPORT -DHAVE_LIBNUMA_SUPPORT -DHAVE_KVM_STAT_SUPPORT -DDISASM_FOUR_ARGS_SIGNATURE -DDISASM_INIT_STYLED -DHAVE_LIBBABELTRACE_SUPPORT -DHAVE_AUXTRACE_SUPPORT -DHAVE_JVMTI_CMLR -DHAVE_LIBTRACEEVENT -I/usr/include/traceevent -DLIBTRACEEVENT_VERSION=67067 -I/usr/include/tracefs -I/usr/include/traceevent -DLIBTRACEFS_VERSION=67065 -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libapi/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libsubcmd/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libsymbol/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libperf/include -D"BUILD_STR(s)=#s" -c -o util/topdown.o util/topdown.c
> util/stat-display.c: In function ?uniquify_event_name?:
> util/stat-display.c:895:45: error: ?struct evsel? has no member named ?alternate_hw_config?
>   895 |         if (counter->pmu->is_core && counter->alternate_hw_config != PERF_COUNT_HW_MAX)
>       |                                             ^~
> make[4]: *** [/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/build/Makefile.build:106: util/stat-display.o] Error 1
> make[4]: *** Waiting for unfinished jobs....
> 
>> ```
>> $ perf stat -e instructions,cycles ...
>> ```
>> Will use "cycles" for the name of the legacy cycles event but as
>> "instructions" has a sysfs name it will and a "[cpu]" PMU suffix. This
>> often breaks things as the space between the event and the PMU name
>> look like an extra column. The existing uniquify logic was also
>> uniquifying in cases when all events are core and not with uncore
>> events, it was not correctly handling modifiers, etc.
>>
>> Change the logic so that an initial pass that can disable
>> uniquification is run. For individual counters, disable uniquification
>> in more cases such as for consistency with legacy events or for
>> libpfm4 events. Don't use the "[pmu]" style suffix in uniquification,
>> always use "pmu/.../". Change how modifiers/terms are handled in the
>> uniquification so that they look like parse-able events.
>>
>> This fixes "102: perf stat metrics (shadow stat) test:" that has been
>> failing due to "instructions [cpu]" breaking its column/awk logic when
>> values aren't aggregated. This started happening when instructions
>> could match a sysfs rather than a legacy event, so the fixes tag
>> reflects this.
>>
>> Fixes: 617824a7f0f7 ("perf parse-events: Prefer sysfs/JSON hardware events over legacy")
>> Acked-by: Namhyung Kim <namhyung at kernel.org>
>> Signed-off-by: Ian Rogers <irogers at google.com>
>> [ Fix Intel TPEBS counting mode test ]
>> Acked-by: Kan Liang <kan.liang at linux.intel.com>
>> Signed-off-by: James Clark <james.clark at linaro.org>
>> Cc: Yang Jihong <yangjihong at bytedance.com>
>> Cc: Dominique Martinet <asmadeus at codewreck.org>
>> Cc: Colin Ian King <colin.i.king at gmail.com>
>> Cc: Howard Chu <howardchu95 at gmail.com>
>> Cc: Ze Gao <zegao2021 at gmail.com>
>> Cc: Yicong Yang <yangyicong at hisilicon.com>
>> Cc: Weilin Wang <weilin.wang at intel.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mike Leach <mike.leach at linaro.org>
>> Cc: Jing Zhang <renyu.zj at linux.alibaba.com>
>> Cc: Yang Li <yang.lee at linux.alibaba.com>
>> Cc: Leo Yan <leo.yan at linux.dev>
>> Cc: ak at linux.intel.com
>> Cc: Athira Rajeev <atrajeev at linux.vnet.ibm.com>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: Sun Haiyong <sunhaiyong at loongson.cn>
>> Cc: John Garry <john.g.garry at oracle.com>
>> Link: https://lore.kernel.org/r/20240926144851.245903-3-james.clark at linaro.org
>> Signed-off-by: Namhyung Kim <namhyung at kernel.org>
>> Signed-off-by: Sasha Levin <sashal at kernel.org>
>> ---
>>  .../perf/tests/shell/test_stat_intel_tpebs.sh |  11 +-
>>  tools/perf/util/stat-display.c                | 101 ++++++++++++++----
>>  2 files changed, 85 insertions(+), 27 deletions(-)
>>
>> diff --git a/tools/perf/tests/shell/test_stat_intel_tpebs.sh b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
>> index c60b29add9801..9a11f42d153ca 100755
>> --- a/tools/perf/tests/shell/test_stat_intel_tpebs.sh
>> +++ b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
>> @@ -8,12 +8,15 @@ grep -q GenuineIntel /proc/cpuinfo || { echo Skipping non-Intel; exit 2; }
>>  # Use this event for testing because it should exist in all platforms
>>  event=cache-misses:R
>>  
>> +# Hybrid platforms output like "cpu_atom/cache-misses/R", rather than as above
>> +alt_name=/cache-misses/R
>> +
>>  # Without this cmd option, default value or zero is returned
>> -echo "Testing without --record-tpebs"
>> -result=$(perf stat -e "$event" true 2>&1)
>> -[[ "$result" =~ $event ]] || exit 1
>> +#echo "Testing without --record-tpebs"
>> +#result=$(perf stat -e "$event" true 2>&1)
>> +#[[ "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
>>  
>>  # In platforms that do not support TPEBS, it should execute without error.
>>  echo "Testing with --record-tpebs"
>>  result=$(perf stat -e "$event" --record-tpebs -a sleep 0.01 2>&1)
>> -[[ "$result" =~ "perf record" && "$result" =~ $event ]] || exit 1
>> +[[ "$result" =~ "perf record" && "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
>> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
>> index ea96e4ebad8c8..cbff43ff8d0fb 100644
>> --- a/tools/perf/util/stat-display.c
>> +++ b/tools/perf/util/stat-display.c
>> @@ -871,38 +871,66 @@ static void printout(struct perf_stat_config *config, struct outstate *os,
>>  
>>  static void uniquify_event_name(struct evsel *counter)
>>  {
>> -	char *new_name;
>> -	char *config;
>> -	int ret = 0;
>> +	const char *name, *pmu_name;
>> +	char *new_name, *config;
>> +	int ret;
>>  
>> -	if (counter->uniquified_name || counter->use_config_name ||
>> -	    !counter->pmu_name || !strncmp(evsel__name(counter), counter->pmu_name,
>> -					   strlen(counter->pmu_name)))
>> +	/* The evsel was already uniquified. */
>> +	if (counter->uniquified_name)
>>  		return;
>>  
>> -	config = strchr(counter->name, '/');
>> +	/* Avoid checking to uniquify twice. */
>> +	counter->uniquified_name = true;
>> +
>> +	/* The evsel has a "name=" config term or is from libpfm. */
>> +	if (counter->use_config_name || counter->is_libpfm_event)
>> +		return;
>> +
>> +	/* Legacy no PMU event, don't uniquify. */
>> +	if  (!counter->pmu ||
>> +	     (counter->pmu->type < PERF_TYPE_MAX && counter->pmu->type != PERF_TYPE_RAW))
>> +		return;
>> +
>> +	/* A sysfs or json event replacing a legacy event, don't uniquify. */
>> +	if (counter->pmu->is_core && counter->alternate_hw_config != PERF_COUNT_HW_MAX)
>> +		return;
>> +
>> +	name = evsel__name(counter);
>> +	pmu_name = counter->pmu->name;
>> +	/* Already prefixed by the PMU name. */
>> +	if (!strncmp(name, pmu_name, strlen(pmu_name)))
>> +		return;
>> +
>> +	config = strchr(name, '/');
>>  	if (config) {
>> -		if (asprintf(&new_name,
>> -			     "%s%s", counter->pmu_name, config) > 0) {
>> -			free(counter->name);
>> -			counter->name = new_name;
>> -		}
>> -	} else {
>> -		if (evsel__is_hybrid(counter)) {
>> -			ret = asprintf(&new_name, "%s/%s/",
>> -				       counter->pmu_name, counter->name);
>> +		int len = config - name;
>> +
>> +		if (config[1] == '/') {
>> +			/* case: event// */
>> +			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 2);
>>  		} else {
>> -			ret = asprintf(&new_name, "%s [%s]",
>> -				       counter->name, counter->pmu_name);
>> +			/* case: event/.../ */
>> +			ret = asprintf(&new_name, "%s/%.*s,%s", pmu_name, len, name, config + 1);
>>  		}
>> +	} else {
>> +		config = strchr(name, ':');
>> +		if (config) {
>> +			/* case: event:.. */
>> +			int len = config - name;
>>  
>> -		if (ret) {
>> -			free(counter->name);
>> -			counter->name = new_name;
>> +			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 1);
>> +		} else {
>> +			/* case: event */
>> +			ret = asprintf(&new_name, "%s/%s/", pmu_name, name);
>>  		}
>>  	}
>> -
>> -	counter->uniquified_name = true;
>> +	if (ret > 0) {
>> +		free(counter->name);
>> +		counter->name = new_name;
>> +	} else {
>> +		/* ENOMEM from asprintf. */
>> +		counter->uniquified_name = false;
>> +	}
>>  }
>>  
>>  static bool hybrid_uniquify(struct evsel *evsel, struct perf_stat_config *config)
>> @@ -1559,6 +1587,31 @@ static void print_cgroup_counter(struct perf_stat_config *config, struct evlist
>>  		print_metric_end(config, os);
>>  }
>>  
>> +static void disable_uniquify(struct evlist *evlist)
>> +{
>> +	struct evsel *counter;
>> +	struct perf_pmu *last_pmu = NULL;
>> +	bool first = true;
>> +
>> +	evlist__for_each_entry(evlist, counter) {
>> +		/* If PMUs vary then uniquify can be useful. */
>> +		if (!first && counter->pmu != last_pmu)
>> +			return;
>> +		first = false;
>> +		if (counter->pmu) {
>> +			/* Allow uniquify for uncore PMUs. */
>> +			if (!counter->pmu->is_core)
>> +				return;
>> +			/* Keep hybrid event names uniquified for clarity. */
>> +			if (perf_pmus__num_core_pmus() > 1)
>> +				return;
>> +		}
>> +	}
>> +	evlist__for_each_entry_continue(evlist, counter) {
>> +		counter->uniquified_name = true;
>> +	}
>> +}
>> +
>>  void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config,
>>  			    struct target *_target, struct timespec *ts,
>>  			    int argc, const char **argv)
>> @@ -1572,6 +1625,8 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
>>  		.first = true,
>>  	};
>>  
>> +	disable_uniquify(evlist);
>> +
>>  	if (config->iostat_run)
>>  		evlist->selected = evlist__first(evlist);
>>  
> 



From conor at kernel.org  Wed Dec  4 09:45:08 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 4 Dec 2024 17:45:08 +0000
Subject: [PATCH v2 1/2] dt-bindings: soc: samsung: exynos-pmu: Add
 exynos990-pmu compatible
In-Reply-To: <20241204145559.524932-2-igor.belwon@mentallysanemainliners.org>
References: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>
 <20241204145559.524932-2-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241204-flyover-freckles-241e17dc2262@spud>

On Wed, Dec 04, 2024 at 03:55:58PM +0100, Igor Belwon wrote:
> Add a dt-binding compatible for the Exynos990 PMU. It's compatible
> with the Exynos7 PMU design. It handles system reboot, as well as
> other system control registers (i.e registers for the USB PHY).
> 
> Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>

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/20241204/221ce2d5/attachment.sig>

From linux at armlinux.org.uk  Wed Dec  4 09:45:43 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Dec 2024 17:45:43 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <9719982a-d40c-4110-9233-def2e6cb4d74@nvidia.com>
References: <20241128144501.0000619b@gmail.com>
 <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com>
 <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
 <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
 <df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>
 <2g2lp3bkadc4wpeslmdoexpidoiqzt7vejar5xhjx5ayt3uox3@dqdyfzn6khn6>
 <Z1CFz7GpeIzkDro1@shell.armlinux.org.uk>
 <9719982a-d40c-4110-9233-def2e6cb4d74@nvidia.com>
Message-ID: <Z1CVRzWcSDuPyQZe@shell.armlinux.org.uk>

On Wed, Dec 04, 2024 at 05:02:19PM +0000, Jon Hunter wrote:
> Hi Russell,
> 
> On 04/12/2024 16:39, Russell King (Oracle) wrote:
> > On Wed, Dec 04, 2024 at 04:58:34PM +0100, Thierry Reding wrote:
> > > This doesn't match the location from earlier, but at least there's
> > > something afoot here that needs fixing. I suppose this could simply be
> > > hiding any subsequent errors, so once this is fixed we might see other
> > > similar issues.
> > 
> > Well, having a quick look at this, the first thing which stands out is:
> > 
> > In stmmac_tx_clean(), we have:
> > 
> >                  if (likely(tx_q->tx_skbuff_dma[entry].buf &&
> >                             tx_q->tx_skbuff_dma[entry].buf_type != STMMAC_TXBUF_T
> > _XDP_TX)) {
> >                          if (tx_q->tx_skbuff_dma[entry].map_as_page)
> >                                  dma_unmap_page(priv->device,
> >                                                 tx_q->tx_skbuff_dma[entry].buf,
> >                                                 tx_q->tx_skbuff_dma[entry].len,
> >                                                 DMA_TO_DEVICE);
> >                          else
> >                                  dma_unmap_single(priv->device,
> >                                                   tx_q->tx_skbuff_dma[entry].buf,
> >                                                   tx_q->tx_skbuff_dma[entry].len,
> >                                                   DMA_TO_DEVICE);
> >                          tx_q->tx_skbuff_dma[entry].buf = 0;
> >                          tx_q->tx_skbuff_dma[entry].len = 0;
> >                          tx_q->tx_skbuff_dma[entry].map_as_page = false;
> >                  }
> > 
> > So, tx_skbuff_dma[entry].buf is expected to point appropriately to the
> > DMA region.
> > 
> > Now if we look at stmmac_tso_xmit():
> > 
> >          des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
> >                               DMA_TO_DEVICE);
> >          if (dma_mapping_error(priv->device, des))
> >                  goto dma_map_err;
> > 
> >          if (priv->dma_cap.addr64 <= 32) {
> > ...
> >          } else {
> > ...
> >                  des += proto_hdr_len;
> > ...
> > 	}
> > 
> >          tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
> >          tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
> >          tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
> >          tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
> > 
> > This will result in stmmac_tx_clean() calling dma_unmap_single() using
> > "des" and "skb_headlen(skb)" as the buffer start and length.
> > 
> > One of the requirements of the DMA mapping API is that the DMA handle
> > returned by the map operation will be passed into the unmap function.
> > Not something that was offset. The length will also be the same.
> > 
> > We can clearly see above that there is a case where the DMA handle has
> > been offset by proto_hdr_len, and when this is so, the value that is
> > passed into the unmap operation no longer matches this requirement.
> > 
> > So, a question to the reporter - what is the value of
> > priv->dma_cap.addr64 in your failing case? You should see the value
> > in the "Using %d/%d bits DMA host/device width" kernel message.
> 
> It is ...
> 
>  dwc-eth-dwmac 2490000.ethernet: Using 40/40 bits DMA host/device width

So yes, "des" is being offset, which will upset the unmap operation.
Please try the following patch, thanks:

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9b262cdad60b..c81ea8cdfe6e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4192,8 +4192,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct stmmac_txq_stats *txq_stats;
 	struct stmmac_tx_queue *tx_q;
 	u32 pay_len, mss, queue;
+	dma_addr_t tso_des, des;
 	u8 proto_hdr_len, hdr;
-	dma_addr_t des;
 	bool set_ic;
 	int i;
 
@@ -4289,14 +4289,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		/* If needed take extra descriptors to fill the remaining payload */
 		tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
+		tso_des = des;
 	} else {
 		stmmac_set_desc_addr(priv, first, des);
 		tmp_pay_len = pay_len;
-		des += proto_hdr_len;
+		tso_des = des + proto_hdr_len;
 		pay_len = 0;
 	}
 
-	stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
+	stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
 
 	/* In case two or more DMA transmit descriptors are allocated for this
 	 * non-paged SKB data, the DMA buffer address should be saved to

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


From catalin.marinas at arm.com  Wed Dec  4 09:50:04 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed,  4 Dec 2024 17:50:04 +0000
Subject: [PATCH] arm64: mte: Fix copy_highpage() warning on hugetlb folios
Message-ID: <20241204175004.906754-1-catalin.marinas@arm.com>

Commit 25c17c4b55de ("hugetlb: arm64: add mte support") improved the
copy_highpage() function to update the tags in the destination hugetlb
folio. However, when the source folio isn't tagged, the code takes the
non-hugetlb path where try_page_mte_tagging() warns as the destination
is a hugetlb folio:

  WARNING: CPU: 0 PID: 363 at arch/arm64/include/asm/mte.h:58 copy_highpage+0x1d4/0x2d8
  [...]
  pc : copy_highpage+0x1d4/0x2d8
  lr : copy_highpage+0x78/0x2d8
  [...]
  Call trace:
   copy_highpage+0x1d4/0x2d8 (P)
   copy_highpage+0x78/0x2d8 (L)
   copy_user_highpage+0x20/0x48
   copy_user_large_folio+0x1bc/0x268
   hugetlb_wp+0x190/0x860
   hugetlb_fault+0xa28/0xc10
   handle_mm_fault+0x2a0/0x2c0
   do_page_fault+0x12c/0x578
   do_mem_abort+0x4c/0xa8
   el0_da+0x44/0xb0
   el0t_64_sync_handler+0xc4/0x138
   el0t_64_sync+0x198/0x1a0

Change the check for the tagged status of the source folio so that it
does not fall through the non-hugetlb case. In addition, only perform
the copy (for the full folio) if the source page is the folio head and
warn if the destination folio is already tagged, for symmetry with the
non-hugetlb case.

Fixes: 25c17c4b55de ("hugetlb: arm64: add mte support")
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Reported-by: Sasha Levin <sashal at kernel.org>
Cc: Yang Shi <yang at os.amperecomputing.com>
Cc: David Hildenbrand <david at redhat.com>
Cc: Will Deacon <will at kernel.org>
Link: https://lore.kernel.org/r/Z0STR6VLt2MCalnY at sashalap
---
 arch/arm64/mm/copypage.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
index 87b3f1a25535..a86c897017df 100644
--- a/arch/arm64/mm/copypage.c
+++ b/arch/arm64/mm/copypage.c
@@ -30,11 +30,13 @@ void copy_highpage(struct page *to, struct page *from)
 	if (!system_supports_mte())
 		return;
 
-	if (folio_test_hugetlb(src) &&
-	    folio_test_hugetlb_mte_tagged(src)) {
-		if (!folio_try_hugetlb_mte_tagging(dst))
+	if (folio_test_hugetlb(src)) {
+		if (!folio_test_hugetlb_mte_tagged(src) ||
+		    from != folio_page(src, 0))
 			return;
 
+		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
+
 		/*
 		 * Populate tags for all subpages.
 		 *


From lucas.demarchi at intel.com  Wed Dec  4 09:51:01 2024
From: lucas.demarchi at intel.com (Lucas De Marchi)
Date: Wed, 4 Dec 2024 11:51:01 -0600
Subject: [PATCH v2 3/3] drm: remove driver date from struct drm_driver
 and all drivers
In-Reply-To: <1f2bf2543aed270a06f6c707fd6ed1b78bf16712.1733322525.git.jani.nikula@intel.com>
References: <cover.1733322525.git.jani.nikula@intel.com>
 <1f2bf2543aed270a06f6c707fd6ed1b78bf16712.1733322525.git.jani.nikula@intel.com>
Message-ID: <lf2kh3f7wr7nd3tsuq4p2eppiizveqb3mm6z7bfw7a47hj4hsy@u6hybopsg6bl>

On Wed, Dec 04, 2024 at 04:31:12PM +0200, Jani Nikula wrote:
>We stopped using the driver initialized date in commit 7fb8af6798e8
>("drm: deprecate driver date") and (eventually) started returning "0"
>for drm_version ioctl instead.
>
>Finish the job, and remove the unused date member from struct
>drm_driver, its initialization from drivers, along with the common
>DRIVER_DATE macros.
>
>v2: Also update drivers/accel (kernel test robot)
>
>Reviewed-by: Javier Martinez Canillas <javierm at redhat.com>
>Acked-by: Alex Deucher <alexander.deucher at amd.com>
>Acked-by: Simon Ser <contact at emersion.fr>
>Acked-by: Jeffrey Hugo <quic_jhugo at quicinc.com>
>Signed-off-by: Jani Nikula <jani.nikula at intel.com>


Acked-by: Lucas De Marchi <lucas.demarchi at intel.com>

Lucas De Marchi


From mathieu.poirier at linaro.org  Wed Dec  4 10:02:38 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 4 Dec 2024 11:02:38 -0700
Subject: [PATCH v15 4/8] remoteproc: Rename load() operation to
 load_segments() in rproc_ops struct
In-Reply-To: <20241128084219.2159197-5-arnaud.pouliquen@foss.st.com>
References: <20241128084219.2159197-1-arnaud.pouliquen@foss.st.com>
 <20241128084219.2159197-5-arnaud.pouliquen@foss.st.com>
Message-ID: <Z1CZPhu1T2opd906@p14s>

On Thu, Nov 28, 2024 at 09:42:11AM +0100, Arnaud Pouliquen wrote:
> With the introduction of the load_fw() operation in the rproc_ops
> structure, we need to clarify the difference in the use of the load()
> and load_fw() ops.
> 
> The legacy load() is dedicated to loading the ELF segments into memory.
> Rename this to a more explicit name: load_segments().

This is introducing more code churn than is worth it.  Please enhance the usage
comment for ->load() as part of the previous patch and drop this one.

I am done reviewing this set.

Thanks,
Mathieu

> 
> Suggested-by: Mathieu Poirier <mathieu.poirier at linaro.org>
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
> ---
> Update vs version V14:
> Fix: Rename missing load() to load_segments() in drivers/remoteproc/pru_rproc.c.
> 
> Reported-by: kernel test robot <lkp at intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202411281332.Ra70nJAW-lkp at intel.com/
> 
> ---
>  drivers/remoteproc/imx_dsp_rproc.c       | 2 +-
>  drivers/remoteproc/imx_rproc.c           | 2 +-
>  drivers/remoteproc/meson_mx_ao_arc.c     | 2 +-
>  drivers/remoteproc/mtk_scp.c             | 2 +-
>  drivers/remoteproc/pru_rproc.c           | 2 +-
>  drivers/remoteproc/qcom_q6v5_adsp.c      | 2 +-
>  drivers/remoteproc/qcom_q6v5_mss.c       | 2 +-
>  drivers/remoteproc/qcom_q6v5_pas.c       | 4 ++--
>  drivers/remoteproc/qcom_q6v5_wcss.c      | 4 ++--
>  drivers/remoteproc/qcom_wcnss.c          | 2 +-
>  drivers/remoteproc/rcar_rproc.c          | 2 +-
>  drivers/remoteproc/remoteproc_core.c     | 4 ++--
>  drivers/remoteproc/remoteproc_internal.h | 4 ++--
>  drivers/remoteproc/st_remoteproc.c       | 2 +-
>  drivers/remoteproc/st_slim_rproc.c       | 2 +-
>  drivers/remoteproc/stm32_rproc.c         | 2 +-
>  drivers/remoteproc/xlnx_r5_remoteproc.c  | 2 +-
>  include/linux/remoteproc.h               | 4 ++--
>  18 files changed, 23 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
> index 376187ad5754..a4a85fbce907 100644
> --- a/drivers/remoteproc/imx_dsp_rproc.c
> +++ b/drivers/remoteproc/imx_dsp_rproc.c
> @@ -934,7 +934,7 @@ static const struct rproc_ops imx_dsp_rproc_ops = {
>  	.start		= imx_dsp_rproc_start,
>  	.stop		= imx_dsp_rproc_stop,
>  	.kick		= imx_dsp_rproc_kick,
> -	.load		= imx_dsp_rproc_elf_load_segments,
> +	.load_segments	= imx_dsp_rproc_elf_load_segments,
>  	.parse_fw	= imx_dsp_rproc_parse_fw,
>  	.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
>  	.sanity_check	= rproc_elf_sanity_check,
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 800015ff7ff9..f45b3207f7e9 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -681,7 +681,7 @@ static const struct rproc_ops imx_rproc_ops = {
>  	.stop		= imx_rproc_stop,
>  	.kick		= imx_rproc_kick,
>  	.da_to_va       = imx_rproc_da_to_va,
> -	.load		= rproc_elf_load_segments,
> +	.load_segments	= rproc_elf_load_segments,
>  	.parse_fw	= imx_rproc_parse_fw,
>  	.find_loaded_rsc_table = imx_rproc_elf_find_loaded_rsc_table,
>  	.get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table,
> diff --git a/drivers/remoteproc/meson_mx_ao_arc.c b/drivers/remoteproc/meson_mx_ao_arc.c
> index f6744b538323..a1c8c0929ce3 100644
> --- a/drivers/remoteproc/meson_mx_ao_arc.c
> +++ b/drivers/remoteproc/meson_mx_ao_arc.c
> @@ -137,7 +137,7 @@ static struct rproc_ops meson_mx_ao_arc_rproc_ops = {
>  	.stop		= meson_mx_ao_arc_rproc_stop,
>  	.da_to_va	= meson_mx_ao_arc_rproc_da_to_va,
>  	.get_boot_addr	= rproc_elf_get_boot_addr,
> -	.load		= rproc_elf_load_segments,
> +	.load_segments	= rproc_elf_load_segments,
>  	.sanity_check	= rproc_elf_sanity_check,
>  };
>  
> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> index e744c07507ee..4e9a8bf3bc6e 100644
> --- a/drivers/remoteproc/mtk_scp.c
> +++ b/drivers/remoteproc/mtk_scp.c
> @@ -924,7 +924,7 @@ static int scp_stop(struct rproc *rproc)
>  static const struct rproc_ops scp_ops = {
>  	.start		= scp_start,
>  	.stop		= scp_stop,
> -	.load		= scp_load,
> +	.load_segments	= scp_load,
>  	.da_to_va	= scp_da_to_va,
>  	.parse_fw	= scp_parse_fw,
>  	.sanity_check	= rproc_elf_sanity_check,
> diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
> index 327f0c7ee3d6..0b2bf2574f74 100644
> --- a/drivers/remoteproc/pru_rproc.c
> +++ b/drivers/remoteproc/pru_rproc.c
> @@ -1015,7 +1015,7 @@ static int pru_rproc_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  	}
>  	/* use a custom load function to deal with PRU-specific quirks */
> -	rproc->ops->load = pru_rproc_load_elf_segments;
> +	rproc->ops->load_segments = pru_rproc_load_elf_segments;
>  
>  	/* use a custom parse function to deal with PRU-specific resources */
>  	rproc->ops->parse_fw = pru_rproc_parse_fw;
> diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
> index 572dcb0f055b..aa9896930bcf 100644
> --- a/drivers/remoteproc/qcom_q6v5_adsp.c
> +++ b/drivers/remoteproc/qcom_q6v5_adsp.c
> @@ -527,7 +527,7 @@ static const struct rproc_ops adsp_ops = {
>  	.stop = adsp_stop,
>  	.da_to_va = adsp_da_to_va,
>  	.parse_fw = adsp_parse_firmware,
> -	.load = adsp_load,
> +	.load_segments = adsp_load,
>  	.panic = adsp_panic,
>  };
>  
> diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
> index 2a42215ce8e0..a8beac1deabe 100644
> --- a/drivers/remoteproc/qcom_q6v5_mss.c
> +++ b/drivers/remoteproc/qcom_q6v5_mss.c
> @@ -1687,7 +1687,7 @@ static const struct rproc_ops q6v5_ops = {
>  	.start = q6v5_start,
>  	.stop = q6v5_stop,
>  	.parse_fw = qcom_q6v5_register_dump_segments,
> -	.load = q6v5_load,
> +	.load_segments = q6v5_load,
>  	.panic = q6v5_panic,
>  };
>  
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index ef82835e98a4..9b269ce390c1 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> @@ -436,7 +436,7 @@ static const struct rproc_ops adsp_ops = {
>  	.stop = adsp_stop,
>  	.da_to_va = adsp_da_to_va,
>  	.parse_fw = qcom_register_dump_segments,
> -	.load = adsp_load,
> +	.load_segments = adsp_load,
>  	.panic = adsp_panic,
>  };
>  
> @@ -446,7 +446,7 @@ static const struct rproc_ops adsp_minidump_ops = {
>  	.stop = adsp_stop,
>  	.da_to_va = adsp_da_to_va,
>  	.parse_fw = qcom_register_dump_segments,
> -	.load = adsp_load,
> +	.load_segments = adsp_load,
>  	.panic = adsp_panic,
>  	.coredump = adsp_minidump,
>  };
> diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
> index e913dabae992..44b5736dc8b9 100644
> --- a/drivers/remoteproc/qcom_q6v5_wcss.c
> +++ b/drivers/remoteproc/qcom_q6v5_wcss.c
> @@ -771,7 +771,7 @@ static const struct rproc_ops q6v5_wcss_ipq8074_ops = {
>  	.start = q6v5_wcss_start,
>  	.stop = q6v5_wcss_stop,
>  	.da_to_va = q6v5_wcss_da_to_va,
> -	.load = q6v5_wcss_load,
> +	.load_segments = q6v5_wcss_load,
>  	.get_boot_addr = rproc_elf_get_boot_addr,
>  };
>  
> @@ -779,7 +779,7 @@ static const struct rproc_ops q6v5_wcss_qcs404_ops = {
>  	.start = q6v5_qcs404_wcss_start,
>  	.stop = q6v5_wcss_stop,
>  	.da_to_va = q6v5_wcss_da_to_va,
> -	.load = q6v5_wcss_load,
> +	.load_segments = q6v5_wcss_load,
>  	.get_boot_addr = rproc_elf_get_boot_addr,
>  	.parse_fw = qcom_register_dump_segments,
>  };
> diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c
> index a7bb9da27029..42102bc4c458 100644
> --- a/drivers/remoteproc/qcom_wcnss.c
> +++ b/drivers/remoteproc/qcom_wcnss.c
> @@ -335,7 +335,7 @@ static const struct rproc_ops wcnss_ops = {
>  	.stop = wcnss_stop,
>  	.da_to_va = wcnss_da_to_va,
>  	.parse_fw = qcom_register_dump_segments,
> -	.load = wcnss_load,
> +	.load_segments = wcnss_load,
>  };
>  
>  static irqreturn_t wcnss_wdog_interrupt(int irq, void *dev)
> diff --git a/drivers/remoteproc/rcar_rproc.c b/drivers/remoteproc/rcar_rproc.c
> index cc17e8421f65..e36778fec072 100644
> --- a/drivers/remoteproc/rcar_rproc.c
> +++ b/drivers/remoteproc/rcar_rproc.c
> @@ -142,7 +142,7 @@ static struct rproc_ops rcar_rproc_ops = {
>  	.prepare	= rcar_rproc_prepare,
>  	.start		= rcar_rproc_start,
>  	.stop		= rcar_rproc_stop,
> -	.load		= rproc_elf_load_segments,
> +	.load_segments	= rproc_elf_load_segments,
>  	.parse_fw	= rcar_rproc_parse_fw,
>  	.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
>  	.sanity_check	= rproc_elf_sanity_check,
> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> index 8df4b2c59bb6..e4ad024efcda 100644
> --- a/drivers/remoteproc/remoteproc_core.c
> +++ b/drivers/remoteproc/remoteproc_core.c
> @@ -2485,11 +2485,11 @@ static int rproc_alloc_ops(struct rproc *rproc, const struct rproc_ops *ops)
>  	if (!rproc->ops->coredump)
>  		rproc->ops->coredump = rproc_coredump;
>  
> -	if (rproc->ops->load || rproc->ops->load_fw)
> +	if (rproc->ops->load_segments || rproc->ops->load_fw)
>  		return 0;
>  
>  	/* Default to ELF loader if no load function is specified */
> -	rproc->ops->load = rproc_elf_load_segments;
> +	rproc->ops->load_segments = rproc_elf_load_segments;
>  	rproc->ops->parse_fw = rproc_elf_load_rsc_table;
>  	rproc->ops->find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table;
>  	rproc->ops->sanity_check = rproc_elf_sanity_check;
> diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
> index 2104ca449178..b898494600cf 100644
> --- a/drivers/remoteproc/remoteproc_internal.h
> +++ b/drivers/remoteproc/remoteproc_internal.h
> @@ -167,8 +167,8 @@ u64 rproc_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
>  static inline
>  int rproc_load_segments(struct rproc *rproc, const struct firmware *fw)
>  {
> -	if (rproc->ops->load)
> -		return rproc->ops->load(rproc, fw);
> +	if (rproc->ops->load_segments)
> +		return rproc->ops->load_segments(rproc, fw);
>  
>  	return -EINVAL;
>  }
> diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
> index 1340be9d0110..8d6b75e91531 100644
> --- a/drivers/remoteproc/st_remoteproc.c
> +++ b/drivers/remoteproc/st_remoteproc.c
> @@ -233,7 +233,7 @@ static const struct rproc_ops st_rproc_ops = {
>  	.start			= st_rproc_start,
>  	.stop			= st_rproc_stop,
>  	.parse_fw		= st_rproc_parse_fw,
> -	.load			= rproc_elf_load_segments,
> +	.load_segments		= rproc_elf_load_segments,
>  	.find_loaded_rsc_table	= rproc_elf_find_loaded_rsc_table,
>  	.sanity_check		= rproc_elf_sanity_check,
>  	.get_boot_addr		= rproc_elf_get_boot_addr,
> diff --git a/drivers/remoteproc/st_slim_rproc.c b/drivers/remoteproc/st_slim_rproc.c
> index 5412beb0a692..0f91d8f1e7c7 100644
> --- a/drivers/remoteproc/st_slim_rproc.c
> +++ b/drivers/remoteproc/st_slim_rproc.c
> @@ -201,7 +201,7 @@ static const struct rproc_ops slim_rproc_ops = {
>  	.stop		= slim_rproc_stop,
>  	.da_to_va       = slim_rproc_da_to_va,
>  	.get_boot_addr	= rproc_elf_get_boot_addr,
> -	.load		= rproc_elf_load_segments,
> +	.load_segments	= rproc_elf_load_segments,
>  	.sanity_check	= rproc_elf_sanity_check,
>  };
>  
> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
> index 8c7f7950b80e..7e8ffd9fcc57 100644
> --- a/drivers/remoteproc/stm32_rproc.c
> +++ b/drivers/remoteproc/stm32_rproc.c
> @@ -667,7 +667,7 @@ static const struct rproc_ops st_rproc_ops = {
>  	.attach		= stm32_rproc_attach,
>  	.detach		= stm32_rproc_detach,
>  	.kick		= stm32_rproc_kick,
> -	.load		= rproc_elf_load_segments,
> +	.load_segments	= rproc_elf_load_segments,
>  	.parse_fw	= stm32_rproc_parse_fw,
>  	.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
>  	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
> diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
> index 5aeedeaf3c41..59cfba0a02e7 100644
> --- a/drivers/remoteproc/xlnx_r5_remoteproc.c
> +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
> @@ -864,7 +864,7 @@ static const struct rproc_ops zynqmp_r5_rproc_ops = {
>  	.unprepare	= zynqmp_r5_rproc_unprepare,
>  	.start		= zynqmp_r5_rproc_start,
>  	.stop		= zynqmp_r5_rproc_stop,
> -	.load		= rproc_elf_load_segments,
> +	.load_segments	= rproc_elf_load_segments,
>  	.parse_fw	= zynqmp_r5_parse_fw,
>  	.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
>  	.sanity_check	= rproc_elf_sanity_check,
> diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> index ba6fd560f7ba..55c20424a99f 100644
> --- a/include/linux/remoteproc.h
> +++ b/include/linux/remoteproc.h
> @@ -374,7 +374,7 @@ enum rsc_handling_status {
>   * @find_loaded_rsc_table: find the loaded resource table from firmware image
>   * @get_loaded_rsc_table: get resource table installed in memory
>   *			  by external entity
> - * @load:		load firmware to memory, where the remote processor
> + * @load_segments:	load firmware ELF segment to memory, where the remote processor
>   *			expects to find it
>   * @sanity_check:	sanity check the fw image
>   * @get_boot_addr:	get boot address to entry point specified in firmware
> @@ -402,7 +402,7 @@ struct rproc_ops {
>  				struct rproc *rproc, const struct firmware *fw);
>  	struct resource_table *(*get_loaded_rsc_table)(
>  				struct rproc *rproc, size_t *size);
> -	int (*load)(struct rproc *rproc, const struct firmware *fw);
> +	int (*load_segments)(struct rproc *rproc, const struct firmware *fw);
>  	int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
>  	u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
>  	unsigned long (*panic)(struct rproc *rproc);
> -- 
> 2.25.1
> 


From thierry.reding at gmail.com  Wed Dec  4 10:06:30 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 4 Dec 2024 19:06:30 +0100
Subject: [PATCH v1 1/1] net: stmmac: dwmac-tegra: Read iommu stream id
 from device tree
In-Reply-To: <20241204115317.008f497c.parker@finest.io>
References: <ed2ec1c2-65c7-4768-99f1-987e5fa39a54@redhat.com>
 <20241115135940.5f898781.parker@finest.io>
 <bb52bdc1-df2e-493d-a58f-df3143715150@lunn.ch>
 <20241118084400.35f4697a.parker@finest.io>
 <984a8471-7e49-4549-9d8a-48e1a29950f6@lunn.ch>
 <20241119131336.371af397.parker@finest.io>
 <f00bccd3-62d5-46a9-b448-051894267c7a@lunn.ch>
 <20241119144729.72e048a5.parker@finest.io>
 <mpgilwqb5zg5kb4n7r6zwbhy4uutdh6rq5s2yc6ndhcj6gqgri@qkfr4qwjj3ym>
 <20241204115317.008f497c.parker@finest.io>
Message-ID: <uad6id6omswjm7e4eqwd75c52sy5pddtxru3bcuxlukhecvj4u@klzgrws24r2q>

On Wed, Dec 04, 2024 at 11:53:17AM -0500, Parker Newman wrote:
> On Wed, 4 Dec 2024 17:23:53 +0100
> Thierry Reding <thierry.reding at gmail.com> wrote:
> 
> > On Tue, Nov 19, 2024 at 02:47:29PM -0500, Parker Newman wrote:
> > > On Tue, 19 Nov 2024 20:18:00 +0100
> > > Andrew Lunn <andrew at lunn.ch> wrote:
> > >
> > > > > I think there is some confusion here. I will try to summarize:
> > > > > - Ihe iommu is supported by the Tegra SOC.
> > > > > - The way the mgbe driver is written the iommu DT property is REQUIRED.
> > > >
> > > > If it is required, please also include a patch to
> > > > nvidia,tegra234-mgbe.yaml and make iommus required.
> > > >
> > >
> > > I will add this when I submit a v2 of the patch.
> > >
> > > > > - "iommus" is a SOC DT property and is defined in tegra234.dtsi.
> > > > > - The mgbe device tree nodes in tegra234.dtsi DO have the iommus property.
> > > > > - There are no device tree changes required to to make this patch work.
> > > > > - This patch works fine with existing device trees.
> > > > >
> > > > > I will add the fallback however in case there is changes made to the iommu
> > > > > subsystem in the future.
> > > >
> > > > I would suggest you make iommus a required property and run the tests
> > > > over the existing .dts files.
> > > >
> > > > I looked at the history of tegra234.dtsi. The ethernet nodes were
> > > > added in:
> > > >
> > > > 610cdf3186bc604961bf04851e300deefd318038
> > > > Author: Thierry Reding <treding at nvidia.com>
> > > > Date:   Thu Jul 7 09:48:15 2022 +0200
> > > >
> > > >     arm64: tegra: Add MGBE nodes on Tegra234
> > > >
> > > > and the iommus property is present. So the requires is safe.
> > > >
> > > > Please expand the commit message. It is clear from all the questions
> > > > and backwards and forwards, it does not provide enough details.
> > > >
> > >
> > > I will add more details when I submit V2.
> > >
> > > > I just have one open issue. The code has been like this for over 2
> > > > years. Why has it only now started crashing?
> > > >
> > >
> > > It is rare for Nvidia Jetson users to use the mainline kernel. Nvidia
> > > provides a custom kernel package with many out of tree drivers including a
> > > driver for the mgbe controllers.
> > >
> > > Also, while the Orin AGX SOC (tegra234) has 4 instances of the mgbe controller,
> > > the Nvidia Orin AGX devkit only uses mgbe0. Connect Tech has carrier boards
> > > that use 2 or more of the mgbe controllers which is why we found the bug.
> >
> > Correct. Also, this was a really stupid thing that I overlooked. I don't
> > recall the exact circumstances, but I vaguely recall there had been
> > discussions about adding the tegra_dev_iommu_get_stream_id() helper
> > (that this patch uses) around the time that this driver was created. In
> > the midst of all of this I likely forgot to update the driver after the
> > discussions had settled.
> >
> > Anyway, I agree with the conclusion that we don't need a compatibility
> > fallback for this, both because it would be actively wrong to do it and
> > we've had the required IOMMU properties in device tree since the start,
> > so there can't be any regressions caused by this.
> >
> > I don't think it's necessary to make the iommus property required,
> > though, because there's technically no requirement for these devices to
> > be attached to an IOMMU. They usually are, and it's better if they are,
> > but they should be able to work correctly without an IOMMU.
> >
> Thanks for confirming from the Nvidia side! I wasn't sure if they would
> work without the iommu. That said, if you did NOT want to use the iommu
> and removed the iommu DT property then the probe will fail after my patch.
> Would we not need a guard around the writes to MGBE_WRAP_AXI_ASID0_CTRL as well?

Well... frankly, I don't know. There's an override in the memory
controller which we set when a device is attached to an IOMMU. That's
usually how the stream ID is programmed. If we don't do that it will
typically default to a special passthrough stream ID (technically the
firmware can lock down those register and force them to a specific
stream ID all the time). I'm not sure what exactly the impact is of
these ASID registers (there's a few other instances where those are
needed). They are required if you want to use the IOMMU, but I don't
know what their meaning is if the IOMMU is not enabled.

There's also different cases: the IOMMU can be disabled altogether, in
which case no page tables and such exist for any device and no
translation should happen whatsoever. But there's also the case where an
IOMMU is enabled, but certain devices shouldn't attach to them. I should
make it very clear that both of these are not recommended setups and I
don't know if they'll work. And they are mostly untested. I've been
meaning, but haven't found the time, to test some of these cases.

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/20241204/93ab2e2c/attachment.sig>

From thierry.reding at gmail.com  Wed Dec  4 10:18:46 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 4 Dec 2024 19:18:46 +0100
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <Z1CVRzWcSDuPyQZe@shell.armlinux.org.uk>
References: <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com>
 <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
 <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
 <df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>
 <2g2lp3bkadc4wpeslmdoexpidoiqzt7vejar5xhjx5ayt3uox3@dqdyfzn6khn6>
 <Z1CFz7GpeIzkDro1@shell.armlinux.org.uk>
 <9719982a-d40c-4110-9233-def2e6cb4d74@nvidia.com>
 <Z1CVRzWcSDuPyQZe@shell.armlinux.org.uk>
Message-ID: <pckuhqpx33woc7tgcv4mluhwg2clriokzb7r4vkzmr6jz3gy3p@hykwm4qtgv6f>

On Wed, Dec 04, 2024 at 05:45:43PM +0000, Russell King (Oracle) wrote:
> On Wed, Dec 04, 2024 at 05:02:19PM +0000, Jon Hunter wrote:
> > Hi Russell,
> > 
> > On 04/12/2024 16:39, Russell King (Oracle) wrote:
> > > On Wed, Dec 04, 2024 at 04:58:34PM +0100, Thierry Reding wrote:
> > > > This doesn't match the location from earlier, but at least there's
> > > > something afoot here that needs fixing. I suppose this could simply be
> > > > hiding any subsequent errors, so once this is fixed we might see other
> > > > similar issues.
> > > 
> > > Well, having a quick look at this, the first thing which stands out is:
> > > 
> > > In stmmac_tx_clean(), we have:
> > > 
> > >                  if (likely(tx_q->tx_skbuff_dma[entry].buf &&
> > >                             tx_q->tx_skbuff_dma[entry].buf_type != STMMAC_TXBUF_T
> > > _XDP_TX)) {
> > >                          if (tx_q->tx_skbuff_dma[entry].map_as_page)
> > >                                  dma_unmap_page(priv->device,
> > >                                                 tx_q->tx_skbuff_dma[entry].buf,
> > >                                                 tx_q->tx_skbuff_dma[entry].len,
> > >                                                 DMA_TO_DEVICE);
> > >                          else
> > >                                  dma_unmap_single(priv->device,
> > >                                                   tx_q->tx_skbuff_dma[entry].buf,
> > >                                                   tx_q->tx_skbuff_dma[entry].len,
> > >                                                   DMA_TO_DEVICE);
> > >                          tx_q->tx_skbuff_dma[entry].buf = 0;
> > >                          tx_q->tx_skbuff_dma[entry].len = 0;
> > >                          tx_q->tx_skbuff_dma[entry].map_as_page = false;
> > >                  }
> > > 
> > > So, tx_skbuff_dma[entry].buf is expected to point appropriately to the
> > > DMA region.
> > > 
> > > Now if we look at stmmac_tso_xmit():
> > > 
> > >          des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
> > >                               DMA_TO_DEVICE);
> > >          if (dma_mapping_error(priv->device, des))
> > >                  goto dma_map_err;
> > > 
> > >          if (priv->dma_cap.addr64 <= 32) {
> > > ...
> > >          } else {
> > > ...
> > >                  des += proto_hdr_len;
> > > ...
> > > 	}
> > > 
> > >          tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
> > >          tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
> > >          tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
> > >          tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
> > > 
> > > This will result in stmmac_tx_clean() calling dma_unmap_single() using
> > > "des" and "skb_headlen(skb)" as the buffer start and length.
> > > 
> > > One of the requirements of the DMA mapping API is that the DMA handle
> > > returned by the map operation will be passed into the unmap function.
> > > Not something that was offset. The length will also be the same.
> > > 
> > > We can clearly see above that there is a case where the DMA handle has
> > > been offset by proto_hdr_len, and when this is so, the value that is
> > > passed into the unmap operation no longer matches this requirement.
> > > 
> > > So, a question to the reporter - what is the value of
> > > priv->dma_cap.addr64 in your failing case? You should see the value
> > > in the "Using %d/%d bits DMA host/device width" kernel message.
> > 
> > It is ...
> > 
> >  dwc-eth-dwmac 2490000.ethernet: Using 40/40 bits DMA host/device width
> 
> So yes, "des" is being offset, which will upset the unmap operation.
> Please try the following patch, thanks:
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 9b262cdad60b..c81ea8cdfe6e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4192,8 +4192,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  	struct stmmac_txq_stats *txq_stats;
>  	struct stmmac_tx_queue *tx_q;
>  	u32 pay_len, mss, queue;
> +	dma_addr_t tso_des, des;
>  	u8 proto_hdr_len, hdr;
> -	dma_addr_t des;
>  	bool set_ic;
>  	int i;
>  
> @@ -4289,14 +4289,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  
>  		/* If needed take extra descriptors to fill the remaining payload */
>  		tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
> +		tso_des = des;
>  	} else {
>  		stmmac_set_desc_addr(priv, first, des);
>  		tmp_pay_len = pay_len;
> -		des += proto_hdr_len;
> +		tso_des = des + proto_hdr_len;
>  		pay_len = 0;
>  	}
>  
> -	stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
> +	stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
>  
>  	/* In case two or more DMA transmit descriptors are allocated for this
>  	 * non-paged SKB data, the DMA buffer address should be saved to

I see, that makes sense. Looks like this has been broken for a few years
(since commit 34c15202896d ("net: stmmac: Fix the problem of tso_xmit"))
and Furong's patch ended up exposing it.

Anyway, this seems to fix it for me. I can usually trigger the issue
within one or two iperf runs, with your patch I haven't seen it break
after a dozen or so runs.

It may be good to have Jon's test results as well, but looks good so
far.

Thanks!
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/20241204/75cbd8bc/attachment.sig>

From David.Laight at ACULAB.COM  Wed Dec  4 10:30:40 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Wed, 4 Dec 2024 18:30:40 +0000
Subject: [PATCH 01/10] compiler.h: add statically_false()
In-Reply-To: <20241203-is_constexpr-refactor-v1-1-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-1-4e4cbaecc216@wanadoo.fr>
Message-ID: <e115a4245e5342a994a7e596cc6357fa@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 02 December 2024 17:33
> 
> From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> 
> For completion, add statically_false() which is the equivalent of
> statically_true() except that it will return true only if the input is
> known to be false at compile time.

This is pretty much pointless.
It is just as easy to invert the condition at the call site.

	David

> 
> The == operator is used instead of the ! negation to prevent a
> -Wint-in-bool-context compiler warning when the argument is not a
> boolean. For example:
> 
>   statically_false(var * 0)
> 
> Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> ---
>  include/linux/compiler.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 469a64dd6495fefab2c85ffc279568a657b72660..a2a56a50dd85227a4fdc62236a2710ca37c5ba52 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -314,6 +314,7 @@ static inline void *offset_to_ptr(const int *off)
>   * values to determine that the condition is statically true.
>   */
>  #define statically_true(x) (__builtin_constant_p(x) && (x))
> +#define statically_false(x) (__builtin_constant_p(x) && (x) == 0)
> 
>  /*
>   * This is needed in functions which generate the stack canary, see
> 
> --
> 2.45.2
> 
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From vt at altlinux.org  Wed Dec  4 10:34:53 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Wed, 4 Dec 2024 21:34:53 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <87jzcfsuep.wl-maz@kernel.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
 <20241203092721.j473dthkbq6wzez7@altlinux.org>
 <1847e34fa7724d28aeb22d93752f64f2@huawei.com>
 <20241203221453.mwh6sozyczi4ec2k@altlinux.org>
 <87jzcfsuep.wl-maz@kernel.org>
Message-ID: <20241204182231.ovvj6rpvcs2f5gv7@altlinux.org>

Marc,

On Wed, Dec 04, 2024 at 08:51:26AM +0000, Marc Zyngier wrote:
> On Tue, 03 Dec 2024 22:14:53 +0000,
> Vitaly Chikunov <vt at altlinux.org> wrote:
> > 
> > Shameer, Marc, Oliver, Will,
> > 
> > On Tue, Dec 03, 2024 at 10:03:11AM +0000, Shameerali Kolothum Thodi wrote:
> > > > -----Original Message-----
> > > > From: linux-arm-kernel <linux-arm-kernel-bounces at lists.infradead.org> On
> > > > Behalf Of Vitaly Chikunov
> > > > Sent: Tuesday, December 3, 2024 9:27 AM
> > > > To: Marc Zyngier <maz at kernel.org>
> > > > Cc: Will Deacon <will at kernel.org>; james.morse at arm.com; linux-arm-
> > > > kernel at lists.infradead.org; Catalin Marinas <catalin.marinas at arm.com>;
> > > > linux-kernel at vger.kernel.org; oliver.upton at linux.dev;
> > > > mark.rutland at arm.com
> > > > Subject: Re: v6.13-rc1: Internal error: Oops - Undefined instruction:
> > > > 0000000002000000 [#1] SMP
> > > > 
> > > > Marc,
> > > > 
> > > > On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> > > > > On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > > > > > On Mon, 02 Dec 2024 15:59:40 +0000,
> > > > > > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > > > > >
> > > > > > > Marc,
> > > > > > >
> > > > > > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > > > > > >
> > > > > > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > > > > >
> > > > > > > No, host is 6.6.60.
> > > > > >
> > > > > > Right. I wouldn't be surprised if:
> > > > > >
> > > > > > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> > > > > >   that's proably something we should backport)
> > > > >
> > > > > How to confirm this? Currently I cannot find any (case-insensitive)
> > > > > "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM
> > > > > strings in `strace -v` (as it decodes some KVM ioctls) of qemu process.
> > > > >
> > > > > >
> > > > > > - you get a nastygram in the host log telling you that the guest has
> > > > > >   executed something it shouldn't (you'll get the encoding of the
> > > > > >   instruction)
> > > > >
> > > > > I requested admins of the box for dmesg output since I don't have root
> > > > > access myself and nowadays dmesg is not accessible for a user.
> > > > 
> > > > This is what they reported:
> > > > 
> > > >   kvm [2502822]: Unsupported guest sys_reg access at: ffff80008003e9f0
> > > > [000000c5]
> > > >                    { Op0( 3), Op1( 0), CRn(10), CRm( 4), Op2( 4), func_read },
> > > > 
> > > 
> > > As Will pointed out I think this is access to MPAMIDR_EL1 and is from this
> > > code here,
> > > 
> > > +++ b/arch/arm64/kernel/cpuinfo.c
> > > @@ -478,6 +478,9 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
> > >  	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
> > >  		__cpuinfo_store_cpu_32bit(&info->aarch32);
> > >  
> > > +	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
> > > +		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
> > > +
> > >  	cpuinfo_detect_icache_policy(info);
> > >  }
> > > 
> > > I did manage to boot my setup in 6.6 and this is what happens,
> > > 
> > > Host kernel 6.6
> > > Guest Kernel 6.13-rc1
> > > 
> > > [    0.195392] smp: Brought up 1 node, 8 CPUs
> > > [    0.219000] SMP: Total of 8 processors activated.
> > > [    0.219629] CPU: All CPU(s) started at EL1
> > > ...
> > > [    0.223212] CPU features: detected: RAS Extension Support
> > > [    0.223927] CPU features: detected: Memory Partitioning And Monitoring
> > > [    0.224796] CPU features: detected: Memory Partitioning And Monitoring Virtualisation
> > > [    0.225961] alternatives: applying system-wide alternatives
> > > ...
> > > 
> > > Guest detects MPAM and boots fine.
> > > 
> > > Host kernel 6.13-rc1
> > > Guest Kernel 6.13-rc1
> > > 
> > > [    0.196625] smp: Brought up 1 node, 8 CPUs
> > > [    0.222093] SMP: Total of 8 processors activated.
> > > [    0.222769] CPU: All CPU(s) started at EL1
> > > ...
> > > [    0.226620] CPU features: detected: RAS Extension Support
> > > [    0.227453] alternatives: applying system-wide alternatives
> > > 
> > > MPAM is not visible to Guest in this case.
> > > 
> > > So as I pointed out earlier could it be a case where the ID register reports MPAM support
> > > but the firmware has not enabled MPAM?
> > > 
> > > James seems to be mentioning that case here,
> > > 
> > > " (If you have a boot failure that bisects here its likely your CPUs
> > > advertise MPAM in the id registers, but firmware failed to either enable
> > > or MPAM, or emulate the trap as if it were disabled)"
> > 
> > I tried to verify that MPAM is advertised with qemu+gdb method, as
> > suggested by Oliver, but ID_AA64PFR0_EL1 register is not there.
> > 
> >   (gdb) i r ID_AA64PFR0_EL1
> >   Invalid register `ID_AA64PFR0_EL1'
> 
> Then there is a bug in either QEMU or the GDB stubs. This register
> exists, or you wouldn't be here.


In case this is useful:

  builder at aarch64:/.in$ qemu-system-aarch64 --version
  QEMU emulator version 9.1.1 (qemu-9.1.1-alt2)
  Copyright (c) 2003-2024 Fabrice Bellard and the QEMU Project developers
  builder at aarch64:/.in$ gdb --version
  GNU gdb (GDB) 14.1.0.56.d739d4fd457-alt1 (ALT Sisyphus)
  Copyright (C) 2023 Free Software Foundation, Inc.
  License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  This is free software: you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.

Is there way to get content of this register with these possible gdb/qemu bugs?
Perhaps, we can add some debugging print in guest kernel.

> > 
> > Are there other suggestions?
> 
> Mark has described what the problem is likely to be. 6.6-stable needs
> to have 6685f5d572c22e10 backported, and it probably should have been
> Cc: to stable. Can you please apply the following patch to your *host*
> machine and retest?

Unfortunately I cannot. But I can apply patches to the guest kernel. [I
will try to convince admins of the server to apply the patch, though, but
this can take time, and they can refuse since this is production build
server and it's update procedure is complicated.]

> > > https://lore.kernel.org/all/20241030160317.2528209-4-joey.gouly at arm.com/
> > > 
> > > Is there a way you can find out the BIOS version on that board?
> > 
> > Unfortunately, admins of the server do not provide me with this
> > info.
> 
> This doesn't really help, I'm afraid.

They provided me with this dmicedcode output:

  Handle 0x0000, DMI type 0, 26 bytes
  BIOS Information
	  Vendor: Huawei Corp.
	  Version: 1.25
	  Release Date: 01/17/2020
	  Address: 0x5F000
	  Runtime Size: 644 kB
	  ROM Size: 6 MB

  Handle 0x0001, DMI type 1, 27 bytes
  System Information
	  Manufacturer: Huawei
	  Product Name: TaiShan 200 (Model 2280)

Admins said they are in process of requesting firmware upgrade from
manufacturer.

> 
> > For such cases, when MPAM is incorrectly advertised, can we have kernel
> > command line parameter like mpam=0 to override it's detection?
> 
> We could, but only when we can confirm what the problem is.
> 
> > I think with "If you have a boot failure that bisects here" it's
> > acknowledged possibility and it's confirmed by our server.
> 
> Not really. This talks about firmware. We are debugging the hypervisor
> here. This might be closely related, but these are not the same
> things.

Understandable.
Thanks,

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


From David.Laight at ACULAB.COM  Wed Dec  4 10:39:53 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Wed, 4 Dec 2024 18:39:53 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
Message-ID: <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 02 December 2024 17:33
> 
> From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> 
> __is_constexpr(), while being one of the most glorious one liner hack
> ever witnessed by mankind, is overly complex. Following the adoption
> of C11 in the kernel, this macro can be simplified through the use of
> a _Generic() selection.

You should give credit to some of the earlier patches that do the same.
I'm sure there were some related ones from Linus - not applied yet.

> 
> First, split the macro in two:
> 
>   - __is_const_zero(x): an helper macro; tells whether x is the
>     integer constant expression 0 or something else.
> 
>   - is_const(x): replacement of __is_constexpr(); tells whether x is a
>     integer constant expression.
> 
> The split serves two purposes: first make it easier to understand;
> second, __is_const_zero() will be reused as a building block for other
> is_const_*() macros that will be introduced later on.
> 
> The core principle of __is_constexpr() to abuse the return type of the
> ternary operator remains, but all the surrounding sizeof() hack
> disappear.
> 
> On a side note, while not relevant to the kernel, __is_constexpr()
> relied on the GNU extension that sizeof(void) is 1. const_expr() does
> not use any GNU extensions, making it ISO C compliant.
> 
> __is_constexpr() is temporarily kept and will be removed once all its
> users get migrated to is_const() (or one of its friend).
> 
> Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> ---
>  include/linux/compiler.h | 41 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
> 
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index a2a56a50dd85227a4fdc62236a2710ca37c5ba52..30ce06df4153cfdc0fad9bc7bffab9097f8b0450 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -316,6 +316,47 @@ static inline void *offset_to_ptr(const int *off)
>  #define statically_true(x) (__builtin_constant_p(x) && (x))
>  #define statically_false(x) (__builtin_constant_p(x) && (x) == 0)
> 
> +/*
> + * Whether x is the integer constant expression 0 or something else.
> + *
> + * Details:
> + *   - The C11 standard defines in ?6.3.2.3.3
> + *       (void *)<integer constant expression with the value 0>
> + *     as a null pointer constant (c.f. the NULL macro).
> + *   - If x evaluates to the integer constant expression 0,
> + *       (void *)(x)
> + *     is a null pointer constant. Else, it is a void * expression.
> + *   - In a ternary expression:
> + *       condition ? operand1 : operand2
> + *     if one of the two operands is of type void * and the other one
> + *     some other pointer type, the C11 standard defines in ?6.5.15.6
> + *     the resulting type as below:
> + *       if one operand is a null pointer constant, the result has the
> + *       type of the other operand; otherwise [...] the result type is
> + *       a pointer to an appropriately qualified version of void.
> + *   - As such, in
> + *       0 ? (void *)(x) : (char *)0
> + *     if x is the integer constant expression 0, operand1 is a null
> + *     pointer constant and the resulting type is that of operand2:
> + *     char *. If x is anything else, the type is void *.
> + *   - The (long) cast silences a compiler warning for when x is not 0.
> + *   - Finally, the _Generic() dispatches the resulting type into a
> + *     Boolean.

The comment is absolutely excessive.
I'm sure I managed about 2 lines in one of the patches I did.

> + *
> + * Glory to Martin Uecker <Martin.Uecker at med.uni-goettingen.de>

IIRC Martin has agreed in the past that the accreditation can
be removed - especially since it refers to the 'sizeof (void)' trick.

> + */
> +#define __is_const_zero(x) \
> +	_Generic(0 ? (void *)(long)(x) : (char *)0, char *: 1, void *: 0)
> +
> +/*
> + * Returns a constant expression while determining if its argument is a
> + * constant expression, most importantly without evaluating the argument.

You need to differentiate between a 'constant integer expression'
and a 'compile time constant'.
 
> + *
> + * If getting a constant expression is not relevant to you, use the more
> + * powerful __builtin_constant_p() instead.

__builtin_constant_p() is not 'more powerful' it is testing for
something different.

	David

> + */
> +#define is_const(x) __is_const_zero(0 * (x))
> +
>  /*
>   * This is needed in functions which generate the stack canary, see
>   * arch/x86/kernel/smpboot.c::start_secondary() for an example.
> 
> --
> 2.45.2
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From David.Laight at ACULAB.COM  Wed Dec  4 10:48:38 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Wed, 4 Dec 2024 18:48:38 +0000
Subject: [PATCH 03/10] compiler.h: add is_const_true() and
 is_const_false()
In-Reply-To: <20241203-is_constexpr-refactor-v1-3-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-3-4e4cbaecc216@wanadoo.fr>
Message-ID: <c617483816b54096ba4b30bea595da49@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 02 December 2024 17:33
>
> __builtin_constant_p() is known for not always being able to produce
> constant expression [1] which led to the introduction of
> __is_constexpr() [2]. Because of its dependency on
> __builtin_constant_p(), statically_true() suffers from the same
> issues.

No, they are testing different things.


> 
> For example:
> 
>   void foo(int a)
>   {
>   	 /* fail on GCC */
>   	BUILD_BUG_ON_ZERO(statically_true(a));
> 
>   	 /* fail on both clang and GCC */
>   	static char arr[statically_true(a) ? 1 : 2];
>   }
> 
> Define a new is_const_true() and is_const_false() pair of macros
> which, by making use of __is_const_zero(), always produces a constant
> expression.
> 
> Note that is_const_false() can not be directly defined as an alias to
> __is_const_zero(). Otherwise, it could yield some false positives on
> huge numbers because of a lost of precision when doing the (long) cast
> in __is_const_zero(). Example:
> 
>   is_const_false((u128)ULONG_MAX << BITS_PER_LONG)
> 
> Furthermore, using the ! operator like this:
> 
>   #define is_const_true(x) __is_const_zero(!(x))
>   #define is_const_false(x) __is_const_zero(!!(x))
> 
> would yield a -Wint-in-bool-context compiler warning if the argument
> is not a boolean. Use the == and != operators instead.
> 
> It should be noted that statically_true/false() are the only ones
> capable of folding tautologic expressions in which at least one on the
> operands is not a constant expression. For example:
> 
>   statically_true(true || var)
>   statically_true(var == var)
>   statically_false(var * 0)
>   statically_false(var * 8 % 4)
> 
> always evaluate to true, whereas all of these would be false under
> is_const_true/false() if var is not a constant expression [3].
> 
> For this reason, usage of const_true/false() should be the exception.
> Reflect in the documentation that const_true() is less powerful and
> that statically_true() is the overall preferred solution.
> 
> [1] __builtin_constant_p cannot resolve to const when optimizing
> Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449
> 
> [2] commit 3c8ba0d61d04 ("kernel.h: Retain constant expression output for max()/min()")
> Link: https://git.kernel.org/torvalds/c/3c8ba0d61d04
> 
> [3] https://godbolt.org/z/E4r7EaxW9
> 
> Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> ---
>  include/linux/compiler.h | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 30ce06df4153cfdc0fad9bc7bffab9097f8b0450..165aa5b9bc484376087a130a1ac1f3edb50c983d 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -357,6 +357,29 @@ static inline void *offset_to_ptr(const int *off)
>   */
>  #define is_const(x) __is_const_zero(0 * (x))
> 
> +/*
> + * Similar to statically_true() but produces a constant expression

No.
It tests whether a value is a 'constant integer expression' and
the result is a 'constant integer expression'.
statically_true() checks for the value being a 'compile time constant'.

Most code really doesn't care, it all got added to min() so that
a very few places could do:
	char foo[min(16, sizeof (type))];
without triggering the 'variable length array' warning.
But that just bloated everywhere else and (IIRC) Linus replaced
them with a MIN() that was just an expression.

> + *
> + * To be used in conjunction with macros, such as BUILD_BUG_ON_ZERO(),
> + * which require their input to be a constant expression and for which
> + * statically_true() would otherwise fail.

Use a different BUILD_BUG macro instead.
Look at the current definition of min().

	David

> + *
> + * This is a trade-off: is_const_true() requires all its operands to
> + * be compile time constants. Else, it would always returns false even
> + * on the most trivial cases like:
> + *
> + *   true || non_const_expr
> + *
> + * On the opposite, statically_true() is able to fold more complex
> + * tautologies and will return true on expressions such as:
> + *
> + *   !(non_const_expr * 8 % 4)
> + *
> + * For the general case, statically_true() is better.
> + */
> +#define is_const_true(x) __is_const_zero((x) == 0)
> +#define is_const_false(x) __is_const_zero((x) != 0)
> +
>  /*
>   * This is needed in functions which generate the stack canary, see
>   * arch/x86/kernel/smpboot.c::start_secondary() for an example.
> 
> --
> 2.45.2
> 
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From yang at os.amperecomputing.com  Wed Dec  4 10:53:45 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Wed, 4 Dec 2024 10:53:45 -0800
Subject: [PATCH] arm64: mte: Fix copy_highpage() warning on hugetlb folios
In-Reply-To: <20241204175004.906754-1-catalin.marinas@arm.com>
References: <20241204175004.906754-1-catalin.marinas@arm.com>
Message-ID: <36a74021-6ae9-419c-9501-fe15146c9dd4@os.amperecomputing.com>



On 12/4/24 9:50 AM, Catalin Marinas wrote:
> Commit 25c17c4b55de ("hugetlb: arm64: add mte support") improved the
> copy_highpage() function to update the tags in the destination hugetlb
> folio. However, when the source folio isn't tagged, the code takes the
> non-hugetlb path where try_page_mte_tagging() warns as the destination
> is a hugetlb folio:
>
>    WARNING: CPU: 0 PID: 363 at arch/arm64/include/asm/mte.h:58 copy_highpage+0x1d4/0x2d8
>    [...]
>    pc : copy_highpage+0x1d4/0x2d8
>    lr : copy_highpage+0x78/0x2d8
>    [...]
>    Call trace:
>     copy_highpage+0x1d4/0x2d8 (P)
>     copy_highpage+0x78/0x2d8 (L)
>     copy_user_highpage+0x20/0x48
>     copy_user_large_folio+0x1bc/0x268
>     hugetlb_wp+0x190/0x860
>     hugetlb_fault+0xa28/0xc10
>     handle_mm_fault+0x2a0/0x2c0
>     do_page_fault+0x12c/0x578
>     do_mem_abort+0x4c/0xa8
>     el0_da+0x44/0xb0
>     el0t_64_sync_handler+0xc4/0x138
>     el0t_64_sync+0x198/0x1a0
>
> Change the check for the tagged status of the source folio so that it
> does not fall through the non-hugetlb case. In addition, only perform
> the copy (for the full folio) if the source page is the folio head and
> warn if the destination folio is already tagged, for symmetry with the
> non-hugetlb case.
>
> Fixes: 25c17c4b55de ("hugetlb: arm64: add mte support")
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> Reported-by: Sasha Levin <sashal at kernel.org>
> Cc: Yang Shi <yang at os.amperecomputing.com>
> Cc: David Hildenbrand <david at redhat.com>
> Cc: Will Deacon <will at kernel.org>
> Link: https://lore.kernel.org/r/Z0STR6VLt2MCalnY at sashalap

Thanks for fixing this. Reviewed-by: Yang Shi <yang at os.amperecomputing.com>

> ---
>   arch/arm64/mm/copypage.c | 8 +++++---
>   1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
> index 87b3f1a25535..a86c897017df 100644
> --- a/arch/arm64/mm/copypage.c
> +++ b/arch/arm64/mm/copypage.c
> @@ -30,11 +30,13 @@ void copy_highpage(struct page *to, struct page *from)
>   	if (!system_supports_mte())
>   		return;
>   
> -	if (folio_test_hugetlb(src) &&
> -	    folio_test_hugetlb_mte_tagged(src)) {
> -		if (!folio_try_hugetlb_mte_tagging(dst))
> +	if (folio_test_hugetlb(src)) {
> +		if (!folio_test_hugetlb_mte_tagged(src) ||
> +		    from != folio_page(src, 0))
>   			return;
>   
> +		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
> +
>   		/*
>   		 * Populate tags for all subpages.
>   		 *



From David.Laight at ACULAB.COM  Wed Dec  4 10:52:10 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Wed, 4 Dec 2024 18:52:10 +0000
Subject: [PATCH 04/10] linux/bits.h: simplify GENMASK_INPUT_CHECK() by
 using is_const_true()
In-Reply-To: <20241203-is_constexpr-refactor-v1-4-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-4-4e4cbaecc216@wanadoo.fr>
Message-ID: <dff4cdd543104e3792e4856375f310c1@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 02 December 2024 17:33
> 
>   __builtin_choose_expr(__is_constexpr((l) > (h)), (l) > (h), 0)
> 
> is equivalent to:
> 
>   is_const_true((l) > (h))

Change it to BUILD_BUG_ON_MSG(statically_true((l) < (h)), "error message")

and then fix all the fallout :-)

	David

> 
> Apply is_const_true() to simplify GENMASK_INPUT_CHECK().
> 
> Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> ---
> This change passes the unit tests from CONFIG_BITS_TEST, including the
> extra negative tests provided under #ifdef TEST_GENMASK_FAILURES [1].
> 
> [1] commit 6d511020e13d ("lib/test_bits.c: add tests of GENMASK")
> Link: https://git.kernel.org/torvalds/c/6d511020e13d
> ---
>  include/linux/bits.h | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/bits.h b/include/linux/bits.h
> index 60044b6088172b3f26aa3f17cdaede9786863dae..ef0119e6179e1ca95345a3d4d3327ba19633028e 100644
> --- a/include/linux/bits.h
> +++ b/include/linux/bits.h
> @@ -20,9 +20,8 @@
>   */
>  #if !defined(__ASSEMBLY__)
>  #include <linux/build_bug.h>
> -#define GENMASK_INPUT_CHECK(h, l) \
> -	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
> -		__is_constexpr((l) > (h)), (l) > (h), 0)))
> +#include <linux/compiler.h>
> +#define GENMASK_INPUT_CHECK(h, l) BUILD_BUG_ON_ZERO(is_const_true((l) > (h)))
>  #else
>  /*
>   * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
> 
> --
> 2.45.2
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From vt at altlinux.org  Wed Dec  4 10:53:09 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Wed, 4 Dec 2024 21:53:09 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <87jzcfsuep.wl-maz@kernel.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
 <20241203092721.j473dthkbq6wzez7@altlinux.org>
 <1847e34fa7724d28aeb22d93752f64f2@huawei.com>
 <20241203221453.mwh6sozyczi4ec2k@altlinux.org>
 <87jzcfsuep.wl-maz@kernel.org>
Message-ID: <20241204185309.v4yq6n7antt7m7jb@altlinux.org>

Marc,

On Wed, Dec 04, 2024 at 08:51:26AM +0000, Marc Zyngier wrote:
> On Tue, 03 Dec 2024 22:14:53 +0000,
> Vitaly Chikunov <vt at altlinux.org> wrote:
> > 
> > I tried to verify that MPAM is advertised with qemu+gdb method, as
> > suggested by Oliver, but ID_AA64PFR0_EL1 register is not there.
> > 
> >   (gdb) i r ID_AA64PFR0_EL1
> >   Invalid register `ID_AA64PFR0_EL1'
> 
> Then there is a bug in either QEMU or the GDB stubs. This register
> exists, or you wouldn't be here.
> 
> > 
> > Are there other suggestions?
> 
> Mark has described what the problem is likely to be. 6.6-stable needs
> to have 6685f5d572c22e10 backported, and it probably should have been
> Cc: to stable. Can you please apply the following patch to your *host*
> machine and retest?

Looks like I will be able to test this.

Thanks,

> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 370a1a7bd369..258a39bcd3c7 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1330,6 +1330,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
>  			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
>  
>  		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
> +		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MPAM_frac);
>  		break;
>  	case SYS_ID_AA64ISAR1_EL1:
>  		if (!vcpu_has_ptrauth(vcpu))
> @@ -1472,6 +1473,13 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
>  
>  	val &= ~ID_AA64PFR0_EL1_AMU_MASK;
>  
> +	/*
> +	 * MPAM is disabled by default as KVM also needs a set of PARTID to
> +	 * program the MPAMVPMx_EL2 PARTID remapping registers with. But some
> +	 * older kernels let the guest see the ID bit.
> +	 */
> +	val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
> +
>  	return val;
>  }
>  
> @@ -1560,6 +1568,29 @@ static int set_id_dfr0_el1(struct kvm_vcpu *vcpu,
>  	return set_id_reg(vcpu, rd, val);
>  }
>  
> +static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> +			       const struct sys_reg_desc *rd, u64 user_val)
> +{
> +	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> +	u64 mpam_mask = ID_AA64PFR0_EL1_MPAM_MASK;
> +
> +	/*
> +	 * Commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits
> +	 * in ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to
> +	 * guests, but didn't add trap handling. KVM doesn't support MPAM and
> +	 * always returns an UNDEF for these registers. The guest must see 0
> +	 * for this field.
> +	 *
> +	 * But KVM must also accept values from user-space that were provided
> +	 * by KVM. On CPUs that support MPAM, permit user-space to write
> +	 * the sanitizied value to ID_AA64PFR0_EL1.MPAM, but ignore this field.
> +	 */
> +	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
> +		user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
> +
> +	return set_id_reg(vcpu, rd, user_val);
> +}
> +
>  /*
>   * cpufeature ID register user accessors
>   *
> @@ -2018,7 +2049,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_ID_AA64PFR0_EL1),
>  	  .access = access_id_reg,
>  	  .get_user = get_id_reg,
> -	  .set_user = set_id_reg,
> +	  .set_user = set_id_aa64pfr0_el1,
>  	  .reset = read_sanitised_id_aa64pfr0_el1,
>  	  .val = ID_AA64PFR0_EL1_CSV2_MASK | ID_AA64PFR0_EL1_CSV3_MASK, },
>  	ID_SANITISED(ID_AA64PFR1_EL1),
> 


From David.Laight at ACULAB.COM  Wed Dec  4 10:54:16 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Wed, 4 Dec 2024 18:54:16 +0000
Subject: [PATCH 05/10] minmax: simplify __clamp_once() by using
 is_const_false()
In-Reply-To: <20241203-is_constexpr-refactor-v1-5-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-5-4e4cbaecc216@wanadoo.fr>
Message-ID: <8b8262389bd6484586007d749132346f@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 02 December 2024 17:33
> 
> In __clamp_once(),
> 
>   __builtin_choose_expr(__is_constexpr((lo) > (hi)), (lo) <= (hi), true)
> 
> is equivalent to:
> 
>   !is_const_false((lo) <= (hi))
> 
> Apply is_const_false() to simplify __clamp_once().

There is already a patch 'for next' that changes it use BUILD_BUG_ON_MSG()
and statically_true().

It has found some 'interesting' code.

	David

> 
> Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> ---
>  include/linux/minmax.h | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/include/linux/minmax.h b/include/linux/minmax.h
> index 98008dd92153db10c672155bca93201ffabee994..431bf76ac460a11a2e4af23acd90c0d26e99c862 100644
> --- a/include/linux/minmax.h
> +++ b/include/linux/minmax.h
> @@ -111,8 +111,7 @@
>  	__auto_type uval = (val);						\
>  	__auto_type ulo = (lo);							\
>  	__auto_type uhi = (hi);							\
> -	static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), 	\
> -			(lo) <= (hi), true),					\
> +	static_assert(!is_const_false((lo) <= (hi)),				\
>  		"clamp() low limit " #lo " greater than high limit " #hi);	\
>  	BUILD_BUG_ON_MSG(!__types_ok3(val,lo,hi,uval,ulo,uhi),			\
>  		"clamp("#val", "#lo", "#hi") signedness error");		\
> 
> --
> 2.45.2
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From David.Laight at ACULAB.COM  Wed Dec  4 10:58:35 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Wed, 4 Dec 2024 18:58:35 +0000
Subject: [PATCH 06/10] fortify: replace __is_constexpr() by is_const() in
 strlen()
In-Reply-To: <20241203-is_constexpr-refactor-v1-6-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-6-4e4cbaecc216@wanadoo.fr>
Message-ID: <ad4482cc835543578862051431f5174f@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 02 December 2024 17:33
> 
> From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> 
> is_const() is a one to one replacement of __is_constexpr(). Do the
> replacement so that __is_constexpr() can be removed.
> 
> Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> ---
>  include/linux/fortify-string.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
> index 0d99bf11d260a3482bbe46e35c7553c0ccfb8b94..e3f2f772c5439ef71eb4a904b4ce27956bc69743 100644
> --- a/include/linux/fortify-string.h
> +++ b/include/linux/fortify-string.h
> @@ -254,8 +254,8 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size
>   * Returns number of characters in @p (NOT including the final NUL).
>   *
>   */
> -#define strlen(p)							\
> -	__builtin_choose_expr(__is_constexpr(__builtin_strlen(p)),	\
> +#define strlen(p)						\
> +	__builtin_choose_expr(is_const(__builtin_strlen(p)),	\
>  		__builtin_strlen(p), __fortify_strlen(p))

I'm sure Linus suggested a way of doing that without replicating
the __builtin_strlen().

Indeed it may be valid to do:
	len = __builtin_strlen(p);
	__builtin_constant_p(len) ? len : __fortify_strlen(p);

	David

>  __FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1)
>  __kernel_size_t __fortify_strlen(const char * const POS p)
> 
> --
> 2.45.2
> 
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From David.Laight at ACULAB.COM  Wed Dec  4 11:00:30 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Wed, 4 Dec 2024 19:00:30 +0000
Subject: [PATCH 08/10] drm/i915/reg: replace __is_const_expr() by
 is_const_true() or is_const()
In-Reply-To: <20241203-is_constexpr-refactor-v1-8-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-8-4e4cbaecc216@wanadoo.fr>
Message-ID: <6597979088eb4ee7b98cfb99815a402e@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 02 December 2024 17:34
> 
> Most of the use of __is_const_expr() in i915_reg_defs.h are just to
> test whether an expression is known to be true. Because those checks
> are all done in a BUILD_BUG_ON_ZERO(), replace those with
> is_const_true().

Another place that could use statically_true() and BUILD_BUG_ON_MSG().

	David

> 
> Replace the few other occurrences of __is_const_expr() with is_const().
> 
> Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> ---
>  drivers/gpu/drm/i915/i915_reg_defs.h | 47 +++++++++++++++++-------------------
>  1 file changed, 22 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h b/drivers/gpu/drm/i915/i915_reg_defs.h
> index e251bcc0c89f5710125bc70f07851b2cb978c89c..6ed2fb9cf506a3bd6467ba30f9d0e863d62762f3 100644
> --- a/drivers/gpu/drm/i915/i915_reg_defs.h
> +++ b/drivers/gpu/drm/i915/i915_reg_defs.h
> @@ -19,8 +19,7 @@
>   */
>  #define REG_BIT(__n)							\
>  	((u32)(BIT(__n) +						\
> -	       BUILD_BUG_ON_ZERO(__is_constexpr(__n) &&		\
> -				 ((__n) < 0 || (__n) > 31))))
> +	       BUILD_BUG_ON_ZERO(is_const_true((__n) < 0 || (__n) > 31))))
> 
>  /**
>   * REG_BIT8() - Prepare a u8 bit value
> @@ -32,8 +31,7 @@
>   */
>  #define REG_BIT8(__n)                                                   \
>  	((u8)(BIT(__n) +                                                \
> -	       BUILD_BUG_ON_ZERO(__is_constexpr(__n) &&         \
> -				 ((__n) < 0 || (__n) > 7))))
> +	      BUILD_BUG_ON_ZERO(is_const_true((__n) < 0 || (__n) > 7))))
> 
>  /**
>   * REG_GENMASK() - Prepare a continuous u32 bitmask
> @@ -46,9 +44,9 @@
>   */
>  #define REG_GENMASK(__high, __low)					\
>  	((u32)(GENMASK(__high, __low) +					\
> -	       BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&	\
> -				 __is_constexpr(__low) &&		\
> -				 ((__low) < 0 || (__high) > 31 || (__low) > (__high)))))
> +	       BUILD_BUG_ON_ZERO(is_const_true((__low) < 0 ||		\
> +					       (__high) > 31 ||		\
> +					       (__low) > (__high)))))
> 
>  /**
>   * REG_GENMASK64() - Prepare a continuous u64 bitmask
> @@ -61,9 +59,9 @@
>   */
>  #define REG_GENMASK64(__high, __low)					\
>  	((u64)(GENMASK_ULL(__high, __low) +				\
> -	       BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&		\
> -				 __is_constexpr(__low) &&		\
> -				 ((__low) < 0 || (__high) > 63 || (__low) > (__high)))))
> +	       BUILD_BUG_ON_ZERO(is_const_true((__low) < 0 ||		\
> +					       (__high) > 63 ||		\
> +					       (__low) > (__high)))))
> 
>  /**
>   * REG_GENMASK8() - Prepare a continuous u8 bitmask
> @@ -76,9 +74,9 @@
>   */
>  #define REG_GENMASK8(__high, __low)                                     \
>  	((u8)(GENMASK(__high, __low) +                                  \
> -	       BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&      \
> -				 __is_constexpr(__low) &&               \
> -				 ((__low) < 0 || (__high) > 7 || (__low) > (__high)))))
> +	      BUILD_BUG_ON_ZERO(is_const_true((__low) < 0 ||            \
> +					      (__high) > 7 ||           \
> +					      (__low) > (__high)))))
> 
>  /*
>   * Local integer constant expression version of is_power_of_2().
> @@ -97,10 +95,10 @@
>   */
>  #define REG_FIELD_PREP(__mask, __val)						\
>  	((u32)((((typeof(__mask))(__val) << __bf_shf(__mask)) & (__mask)) +	\
> -	       BUILD_BUG_ON_ZERO(!__is_constexpr(__mask)) +		\
> +	       BUILD_BUG_ON_ZERO(!is_const(__mask)) +				\
>  	       BUILD_BUG_ON_ZERO((__mask) == 0 || (__mask) > U32_MAX) +		\
>  	       BUILD_BUG_ON_ZERO(!IS_POWER_OF_2((__mask) + (1ULL << __bf_shf(__mask)))) + \
> -	       BUILD_BUG_ON_ZERO(__builtin_choose_expr(__is_constexpr(__val), (~((__mask) >>
> __bf_shf(__mask)) & (__val)), 0))))
> +	       BUILD_BUG_ON_ZERO(is_const_true(~((__mask) >> __bf_shf(__mask)) & (__val)))))
> 
>  /**
>   * REG_FIELD_PREP8() - Prepare a u8 bitfield value
> @@ -114,10 +112,10 @@
>   */
>  #define REG_FIELD_PREP8(__mask, __val)                                          \
>  	((u8)((((typeof(__mask))(__val) << __bf_shf(__mask)) & (__mask)) +      \
> -	       BUILD_BUG_ON_ZERO(!__is_constexpr(__mask)) +             \
> +	       BUILD_BUG_ON_ZERO(!is_const(__mask)) +                           \
>  	       BUILD_BUG_ON_ZERO((__mask) == 0 || (__mask) > U8_MAX) +          \
>  	       BUILD_BUG_ON_ZERO(!IS_POWER_OF_2((__mask) + (1ULL << __bf_shf(__mask)))) + \
> -	       BUILD_BUG_ON_ZERO(__builtin_choose_expr(__is_constexpr(__val), (~((__mask) >>
> __bf_shf(__mask)) & (__val)), 0))))
> +	       BUILD_BUG_ON_ZERO(is_const_true(~((__mask) >> __bf_shf(__mask)) & (__val)))))
> 
>  /**
>   * REG_FIELD_GET() - Extract a u32 bitfield value
> @@ -154,8 +152,7 @@
>   */
>  #define REG_BIT16(__n)                                                   \
>  	((u16)(BIT(__n) +                                                \
> -	       BUILD_BUG_ON_ZERO(__is_constexpr(__n) &&         \
> -				 ((__n) < 0 || (__n) > 15))))
> +	       BUILD_BUG_ON_ZERO(is_const_true((__n) < 0 || (__n) > 15))))
> 
>  /**
>   * REG_GENMASK16() - Prepare a continuous u8 bitmask
> @@ -169,9 +166,9 @@
>   */
>  #define REG_GENMASK16(__high, __low)                                     \
>  	((u16)(GENMASK(__high, __low) +                                  \
> -	       BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&      \
> -				 __is_constexpr(__low) &&               \
> -				 ((__low) < 0 || (__high) > 15 || (__low) > (__high)))))
> +	       BUILD_BUG_ON_ZERO(is_const_true((__low) < 0 ||            \
> +					       (__high) > 15 ||          \
> +					       (__low) > (__high)))))
> 
>  /**
>   * REG_FIELD_PREP16() - Prepare a u16 bitfield value
> @@ -186,10 +183,10 @@
>   */
>  #define REG_FIELD_PREP16(__mask, __val)                                          \
>  	((u16)((((typeof(__mask))(__val) << __bf_shf(__mask)) & (__mask)) +      \
> -	       BUILD_BUG_ON_ZERO(!__is_constexpr(__mask)) +             \
> +	       BUILD_BUG_ON_ZERO(!is_const(__mask)) +                            \
>  	       BUILD_BUG_ON_ZERO((__mask) == 0 || (__mask) > U16_MAX) +          \
>  	       BUILD_BUG_ON_ZERO(!IS_POWER_OF_2((__mask) + (1ULL << __bf_shf(__mask)))) + \
> -	       BUILD_BUG_ON_ZERO(__builtin_choose_expr(__is_constexpr(__val), (~((__mask) >>
> __bf_shf(__mask)) & (__val)), 0))))
> +	       BUILD_BUG_ON_ZERO(is_const_true(~((__mask) >> __bf_shf(__mask)) & (__val)))))
> 
>  #define __MASKED_FIELD(mask, value) ((mask) << 16 | (value))
>  #define _MASKED_FIELD(mask, value) ({					   \
> @@ -237,7 +234,7 @@
>   *	...
>   */
>  #define _PICK_EVEN_2RANGES(__index, __c_index, __a, __b, __c, __d)		\
> -	(BUILD_BUG_ON_ZERO(!__is_constexpr(__c_index)) +			\
> +	(BUILD_BUG_ON_ZERO(!is_const(__c_index)) +				\
>  	 ((__index) < (__c_index) ? _PICK_EVEN(__index, __a, __b) :		\
>  				   _PICK_EVEN((__index) - (__c_index), __c, __d)))
> 
> 
> --
> 2.45.2
> 
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From florian.fainelli at broadcom.com  Wed Dec  4 11:08:46 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Wed, 4 Dec 2024 11:08:46 -0800
Subject: [PATCH 7/7] arm64: dts: broadcom: Fix device tree errors on
 BCM2712.
In-Reply-To: <44c233d7-87d7-4dbb-a0d0-9e93ea497622@kernel.org>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-7-fac67cc2f98a@raspberrypi.com>
 <44c233d7-87d7-4dbb-a0d0-9e93ea497622@kernel.org>
Message-ID: <4ab9673a-03a7-4358-b95d-eef514607bc2@broadcom.com>

On 12/2/24 07:24, Krzysztof Kozlowski wrote:
> On 02/12/2024 15:32, Dave Stevenson wrote:
>> Resolves the issues on clocks and power nodes
> 
> Which issues? Be specific. Such commit is unprecise and not really
> helpful. We see it from the diff that this is "some issue". What we do
> not see is WHY and WHAT the ISSUE is.

A link to the robot email would have probably been helpful in 
understanding which dt checker errors are being fixed here. Regardless, 
as indicated in patch #4, those commit messages will be discarded since 
I intend to fixup the original commits directly into my tree I would not 
put too much effort into addressing any comments there, unless there is 
some piece of information that should have been provided in the original 
commit, in which case I can squash, rather than fixup.
-- 
Florian


From maz at kernel.org  Wed Dec  4 11:13:09 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Dec 2024 19:13:09 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP
In-Reply-To: <20241204182231.ovvj6rpvcs2f5gv7@altlinux.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
	<20241202153618.GA6834@willie-the-truck>
	<86ttbmt71k.wl-maz@kernel.org>
	<20241202155940.p267a3tz5ypj4sog@altlinux.org>
	<86ser6t6fs.wl-maz@kernel.org>
	<20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
	<20241203092721.j473dthkbq6wzez7@altlinux.org>
	<1847e34fa7724d28aeb22d93752f64f2@huawei.com>
	<20241203221453.mwh6sozyczi4ec2k@altlinux.org>
	<87jzcfsuep.wl-maz@kernel.org>
	<20241204182231.ovvj6rpvcs2f5gv7@altlinux.org>
Message-ID: <87h67js1mi.wl-maz@kernel.org>

On Wed, 04 Dec 2024 18:34:53 +0000,
Vitaly Chikunov <vt at altlinux.org> wrote:
> 
> Marc,
> 
> On Wed, Dec 04, 2024 at 08:51:26AM +0000, Marc Zyngier wrote:
> > On Tue, 03 Dec 2024 22:14:53 +0000,
> > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > 
> > > Shameer, Marc, Oliver, Will,
> > > 
> > > On Tue, Dec 03, 2024 at 10:03:11AM +0000, Shameerali Kolothum Thodi wrote:
> > > > > -----Original Message-----
> > > > > From: linux-arm-kernel <linux-arm-kernel-bounces at lists.infradead.org> On
> > > > > Behalf Of Vitaly Chikunov
> > > > > Sent: Tuesday, December 3, 2024 9:27 AM
> > > > > To: Marc Zyngier <maz at kernel.org>
> > > > > Cc: Will Deacon <will at kernel.org>; james.morse at arm.com; linux-arm-
> > > > > kernel at lists.infradead.org; Catalin Marinas <catalin.marinas at arm.com>;
> > > > > linux-kernel at vger.kernel.org; oliver.upton at linux.dev;
> > > > > mark.rutland at arm.com
> > > > > Subject: Re: v6.13-rc1: Internal error: Oops - Undefined instruction:
> > > > > 0000000002000000 [#1] SMP
> > > > > 
> > > > > Marc,
> > > > > 
> > > > > On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> > > > > > On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > > > > > > On Mon, 02 Dec 2024 15:59:40 +0000,
> > > > > > > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > > > > > >
> > > > > > > > Marc,
> > > > > > > >
> > > > > > > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > > > > > > >
> > > > > > > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > > > > > >
> > > > > > > > No, host is 6.6.60.
> > > > > > >
> > > > > > > Right. I wouldn't be surprised if:
> > > > > > >
> > > > > > > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> > > > > > >   that's proably something we should backport)
> > > > > >
> > > > > > How to confirm this? Currently I cannot find any (case-insensitive)
> > > > > > "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM
> > > > > > strings in `strace -v` (as it decodes some KVM ioctls) of qemu process.
> > > > > >
> > > > > > >
> > > > > > > - you get a nastygram in the host log telling you that the guest has
> > > > > > >   executed something it shouldn't (you'll get the encoding of the
> > > > > > >   instruction)
> > > > > >
> > > > > > I requested admins of the box for dmesg output since I don't have root
> > > > > > access myself and nowadays dmesg is not accessible for a user.
> > > > > 
> > > > > This is what they reported:
> > > > > 
> > > > >   kvm [2502822]: Unsupported guest sys_reg access at: ffff80008003e9f0
> > > > > [000000c5]
> > > > >                    { Op0( 3), Op1( 0), CRn(10), CRm( 4), Op2( 4), func_read },
> > > > > 
> > > > 
> > > > As Will pointed out I think this is access to MPAMIDR_EL1 and is from this
> > > > code here,
> > > > 
> > > > +++ b/arch/arm64/kernel/cpuinfo.c
> > > > @@ -478,6 +478,9 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
> > > >  	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
> > > >  		__cpuinfo_store_cpu_32bit(&info->aarch32);
> > > >  
> > > > +	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
> > > > +		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
> > > > +
> > > >  	cpuinfo_detect_icache_policy(info);
> > > >  }
> > > > 
> > > > I did manage to boot my setup in 6.6 and this is what happens,
> > > > 
> > > > Host kernel 6.6
> > > > Guest Kernel 6.13-rc1
> > > > 
> > > > [    0.195392] smp: Brought up 1 node, 8 CPUs
> > > > [    0.219000] SMP: Total of 8 processors activated.
> > > > [    0.219629] CPU: All CPU(s) started at EL1
> > > > ...
> > > > [    0.223212] CPU features: detected: RAS Extension Support
> > > > [    0.223927] CPU features: detected: Memory Partitioning And Monitoring
> > > > [    0.224796] CPU features: detected: Memory Partitioning And Monitoring Virtualisation
> > > > [    0.225961] alternatives: applying system-wide alternatives
> > > > ...
> > > > 
> > > > Guest detects MPAM and boots fine.
> > > > 
> > > > Host kernel 6.13-rc1
> > > > Guest Kernel 6.13-rc1
> > > > 
> > > > [    0.196625] smp: Brought up 1 node, 8 CPUs
> > > > [    0.222093] SMP: Total of 8 processors activated.
> > > > [    0.222769] CPU: All CPU(s) started at EL1
> > > > ...
> > > > [    0.226620] CPU features: detected: RAS Extension Support
> > > > [    0.227453] alternatives: applying system-wide alternatives
> > > > 
> > > > MPAM is not visible to Guest in this case.
> > > > 
> > > > So as I pointed out earlier could it be a case where the ID register reports MPAM support
> > > > but the firmware has not enabled MPAM?
> > > > 
> > > > James seems to be mentioning that case here,
> > > > 
> > > > " (If you have a boot failure that bisects here its likely your CPUs
> > > > advertise MPAM in the id registers, but firmware failed to either enable
> > > > or MPAM, or emulate the trap as if it were disabled)"
> > > 
> > > I tried to verify that MPAM is advertised with qemu+gdb method, as
> > > suggested by Oliver, but ID_AA64PFR0_EL1 register is not there.
> > > 
> > >   (gdb) i r ID_AA64PFR0_EL1
> > >   Invalid register `ID_AA64PFR0_EL1'
> > 
> > Then there is a bug in either QEMU or the GDB stubs. This register
> > exists, or you wouldn't be here.
> 
> 
> In case this is useful:
> 
>   builder at aarch64:/.in$ qemu-system-aarch64 --version
>   QEMU emulator version 9.1.1 (qemu-9.1.1-alt2)
>   Copyright (c) 2003-2024 Fabrice Bellard and the QEMU Project developers
>   builder at aarch64:/.in$ gdb --version
>   GNU gdb (GDB) 14.1.0.56.d739d4fd457-alt1 (ALT Sisyphus)
>   Copyright (C) 2023 Free Software Foundation, Inc.
>   License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
>   This is free software: you are free to change and redistribute it.
>   There is NO WARRANTY, to the extent permitted by law.
> 
> Is there way to get content of this register with these possible
> gdb/qemu bugs?

I have no idea. And frankly, I don't think this matters.

> Perhaps, we can add some debugging print in guest kernel.
> 
> > > 
> > > Are there other suggestions?
> > 
> > Mark has described what the problem is likely to be. 6.6-stable needs
> > to have 6685f5d572c22e10 backported, and it probably should have been
> > Cc: to stable. Can you please apply the following patch to your *host*
> > machine and retest?
> 
> Unfortunately I cannot. But I can apply patches to the guest kernel. [I
> will try to convince admins of the server to apply the patch, though, but
> this can take time, and they can refuse since this is production build
> server and it's update procedure is complicated.]

Then I really cannot help you. I'm not going to paper over a
hypervisor bug in the guest kernel, and if you/they are happy to run
with critical bugs in your production machine, that's about it then.

	M.

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


From jthoughton at google.com  Wed Dec  4 11:13:35 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:35 +0000
Subject: [PATCH v1 00/13] KVM: Introduce KVM Userfault
Message-ID: <20241204191349.1730936-1-jthoughton@google.com>

This is a continuation of the original KVM Userfault RFC[1] from July.
It contains the simplifications we talked about at LPC[2].

Please see the RFC[1] for the problem description. In summary,
guest_memfd VMs have no mechanism for doing post-copy live migration.
KVM Userfault provides such a mechanism. Today there is no upstream
mechanism for installing memory into a guest_memfd, but there will
be one soon (e.g. [3]).

There is a second problem that KVM Userfault solves: userfaultfd-based
post-copy doesn't scale very well. KVM Userfault when used with
userfaultfd can scale much better in the common case that most post-copy
demand fetches are a result of vCPU access violations. This is a
continuation of the solution Anish was working on[4]. This aspect of
KVM Userfault is important for userfaultfd-based live migration when
scaling up to hundreds of vCPUs with ~30us network latency for a
PAGE_SIZE demand-fetch.

The implementation in this series is version than the RFC[1]. It adds...
 1. a new memslot flag is added: KVM_MEM_USERFAULT,
 2. a new parameter, userfault_bitmap, into struct kvm_memory_slot,
 3. a new KVM_RUN exit reason: KVM_MEMORY_EXIT_FLAG_USERFAULT,
 4. a new KVM capability KVM_CAP_USERFAULT.

KVM Userfault does not attempt to catch KVM's own accesses to guest
memory. That is left up to userfaultfd.

When enabling KVM_MEM_USERFAULT for a memslot, the second-stage mappings
are zapped, and new faults will check `userfault_bitmap` to see if the
fault should exit to userspace.

When KVM_MEM_USERFAULT is enabled, only PAGE_SIZE mappings are
permitted.

When disabling KVM_MEM_USERFAULT, huge mappings will be reconstructed
(either eagerly or on-demand; the architecture can decide).

KVM Userfault is not compatible with async page faults. Nikita has
proposed a new implementation of async page faults that is more
userspace-driven that *is* compatible with KVM Userfault[5].

Performance
===========

The takeaways I have are:

1. For cases where lock contention is not a concern, there is a
   discernable win because KVM Userfault saves the trip through the
   userfaultfd poll/read/WAKE cycle.

2. Using a single userfaultfd without KVM Userfault gets very slow as
   the number of vCPUs increases, and it gets even slower when you add
   more reader threads. This is due to contention on the userfaultfd
   wait_queue locks. This is the contention that KVM Userfault avoids.
   Compare this to the multiple-userfaultfd runs; they are much faster
   because the wait_queue locks are sharded perfectly (1 per vCPU).
   Perfect sharding is only possible because the vCPUs are configured to
   touch only their own chunk of memory.

Config:
 - 64M per vcpu
 - vcpus only touch their 64M (`-b 64M -a`)
 - THPs disabled
 - MGLRU disabled

Each run used the following command:

./demand_paging_test -b 64M -a -v <#vcpus>  \
	-s shmem		     \ # if using shmem
	-r <#readers> -u <uffd_mode> \ # if using userfaultfd
	-k \			     \ # if using KVM Userfault
	-m 3			       # when on arm64

note: I patched demand_paging_test so that, when using shmem, the page
      cache will always be preallocated, not only in the `-u MINOR`
      case. Otherwise the comparison would be unfair. I left this patch
      out in the selftest commits, but I am happy to add it if it would
      be useful.

== x86 (96 LPUs, 48 cores, TDP MMU enabled) ==

-- Anonymous memory, single userfaultfd

	userfault mode
vcpus				2	8	64
	no userfault		306845	220402	47720
	MISSING (single reader)	90724	26059	3029
	MISSING			86840	37912	1664
	MISSING + KVM UF	143021	104385	34910
	KVM UF			160326	128247	39913

-- shmem (preallocated), single userfaultfd

vcpus				2	8	64
	no userfault		375130	214635	54420
	MINOR (single reader)	102336	31704	3244
	MINOR 			97981	36982	1673
	MINOR + KVM UF		161835	113716	33577
	KVM UF			181972	131204	42914

-- shmem (preallocated), multiple userfaultfds

vcpus				2	8	64
	no userfault		374060	216108	54433
	MINOR			102661	56978	11300
	MINOR + KVM UF		167080	123461	48382
	KVM UF			180439	122310	42539

== arm64 (96 PEs, AmpereOne) ==

-- shmem (preallocated), single userfaultfd

vcpus:				2	8	64
	no userfault		419069	363081	34348
	MINOR (single reader)	87421	36147	3764
	MINOR			84953	43444	1323
	MINOR + KVM UF		164509	139986	12373
	KVM UF			185706	122153	12153

-- shmem (preallocated), multiple userfaultfds

vcpus:				2	8	64
	no userfault		401931	334142	36117
	MINOR			83696	75617	15996
	MINOR + KVM UF		176327	115784	12198
	KVM UF			190074	126966	12084

This series is based on the latest kvm/next.

[1]: https://lore.kernel.org/kvm/20240710234222.2333120-1-jthoughton at google.com/
[2]: https://lpc.events/event/18/contributions/1757/
[3]: https://lore.kernel.org/kvm/20241112073837.22284-1-yan.y.zhao at intel.com/
[4]: https://lore.kernel.org/all/20240215235405.368539-1-amoorthy at google.com/
[5]: https://lore.kernel.org/kvm/20241118123948.4796-1-kalyazin at amazon.com/#t

James Houghton (13):
  KVM: Add KVM_MEM_USERFAULT memslot flag and bitmap
  KVM: Add KVM_MEMORY_EXIT_FLAG_USERFAULT
  KVM: Allow late setting of KVM_MEM_USERFAULT on guest_memfd memslot
  KVM: Advertise KVM_CAP_USERFAULT in KVM_CHECK_EXTENSION
  KVM: x86/mmu: Add support for KVM_MEM_USERFAULT
  KVM: arm64: Add support for KVM_MEM_USERFAULT
  KVM: selftests: Fix vm_mem_region_set_flags docstring
  KVM: selftests: Fix prefault_mem logic
  KVM: selftests: Add va_start/end into uffd_desc
  KVM: selftests: Add KVM Userfault mode to demand_paging_test
  KVM: selftests: Inform set_memory_region_test of KVM_MEM_USERFAULT
  KVM: selftests: Add KVM_MEM_USERFAULT + guest_memfd toggle tests
  KVM: Documentation: Add KVM_CAP_USERFAULT and KVM_MEM_USERFAULT
    details

 Documentation/virt/kvm/api.rst                |  33 +++-
 arch/arm64/kvm/Kconfig                        |   1 +
 arch/arm64/kvm/mmu.c                          |  23 ++-
 arch/x86/kvm/Kconfig                          |   1 +
 arch/x86/kvm/mmu/mmu.c                        |  27 +++-
 arch/x86/kvm/mmu/mmu_internal.h               |  20 ++-
 arch/x86/kvm/x86.c                            |  36 +++--
 include/linux/kvm_host.h                      |  19 ++-
 include/uapi/linux/kvm.h                      |   6 +-
 .../selftests/kvm/demand_paging_test.c        | 145 ++++++++++++++++--
 .../testing/selftests/kvm/include/kvm_util.h  |   5 +
 .../selftests/kvm/include/userfaultfd_util.h  |   2 +
 tools/testing/selftests/kvm/lib/kvm_util.c    |  42 ++++-
 .../selftests/kvm/lib/userfaultfd_util.c      |   2 +
 .../selftests/kvm/set_memory_region_test.c    |  33 ++++
 virt/kvm/Kconfig                              |   3 +
 virt/kvm/kvm_main.c                           |  47 +++++-
 17 files changed, 409 insertions(+), 36 deletions(-)


base-commit: 4d911c7abee56771b0219a9fbf0120d06bdc9c14
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:36 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:36 +0000
Subject: [PATCH v1 01/13] KVM: Add KVM_MEM_USERFAULT memslot flag and bitmap
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-2-jthoughton@google.com>

Use one of the 14 reserved u64s in struct kvm_userspace_memory_region2
for the user to provide `userfault_bitmap`.

The memslot flag indicates if KVM should be reading from the
`userfault_bitmap` field from the memslot. The user is permitted to
provide a bogus pointer. If the pointer cannot be read from, we will
return -EFAULT (with no other information) back to the user.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 include/linux/kvm_host.h | 14 ++++++++++++++
 include/uapi/linux/kvm.h |  4 +++-
 virt/kvm/Kconfig         |  3 +++
 virt/kvm/kvm_main.c      | 28 ++++++++++++++++++++++++++++
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 401439bb21e3..f7a3dfd5e224 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -590,6 +590,7 @@ struct kvm_memory_slot {
 	unsigned long *dirty_bitmap;
 	struct kvm_arch_memory_slot arch;
 	unsigned long userspace_addr;
+	unsigned long __user *userfault_bitmap;
 	u32 flags;
 	short id;
 	u16 as_id;
@@ -724,6 +725,11 @@ static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm)
 }
 #endif
 
+static inline bool kvm_has_userfault(struct kvm *kvm)
+{
+	return IS_ENABLED(CONFIG_HAVE_KVM_USERFAULT);
+}
+
 struct kvm_memslots {
 	u64 generation;
 	atomic_long_t last_used_slot;
@@ -2553,4 +2559,12 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu,
 				    struct kvm_pre_fault_memory *range);
 #endif
 
+int kvm_gfn_userfault(struct kvm *kvm, struct kvm_memory_slot *memslot,
+		      gfn_t gfn);
+
+static inline bool kvm_memslot_userfault(struct kvm_memory_slot *memslot)
+{
+	return memslot->flags & KVM_MEM_USERFAULT;
+}
+
 #endif
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 502ea63b5d2e..94be7e8b46a4 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -40,7 +40,8 @@ struct kvm_userspace_memory_region2 {
 	__u64 guest_memfd_offset;
 	__u32 guest_memfd;
 	__u32 pad1;
-	__u64 pad2[14];
+	__u64 userfault_bitmap;
+	__u64 pad2[13];
 };
 
 /*
@@ -51,6 +52,7 @@ struct kvm_userspace_memory_region2 {
 #define KVM_MEM_LOG_DIRTY_PAGES	(1UL << 0)
 #define KVM_MEM_READONLY	(1UL << 1)
 #define KVM_MEM_GUEST_MEMFD	(1UL << 2)
+#define KVM_MEM_USERFAULT	(1UL << 3)
 
 /* for KVM_IRQ_LINE */
 struct kvm_irq_level {
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index 54e959e7d68f..9eb1fae238b1 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -124,3 +124,6 @@ config HAVE_KVM_ARCH_GMEM_PREPARE
 config HAVE_KVM_ARCH_GMEM_INVALIDATE
        bool
        depends on KVM_PRIVATE_MEM
+
+config HAVE_KVM_USERFAULT
+       bool
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index de2c11dae231..23fa3e911c4e 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1541,6 +1541,9 @@ static int check_memory_region_flags(struct kvm *kvm,
 	    !(mem->flags & KVM_MEM_GUEST_MEMFD))
 		valid_flags |= KVM_MEM_READONLY;
 
+	if (kvm_has_userfault(kvm))
+		valid_flags |= KVM_MEM_USERFAULT;
+
 	if (mem->flags & ~valid_flags)
 		return -EINVAL;
 
@@ -2042,6 +2045,8 @@ int __kvm_set_memory_region(struct kvm *kvm,
 		if (r)
 			goto out;
 	}
+	if (mem->flags & KVM_MEM_USERFAULT)
+		new->userfault_bitmap = (unsigned long *)mem->userfault_bitmap;
 
 	r = kvm_set_memslot(kvm, old, new, change);
 	if (r)
@@ -6426,3 +6431,26 @@ void kvm_exit(void)
 	kvm_irqfd_exit();
 }
 EXPORT_SYMBOL_GPL(kvm_exit);
+
+int kvm_gfn_userfault(struct kvm *kvm, struct kvm_memory_slot *memslot,
+		       gfn_t gfn)
+{
+	unsigned long bitmap_chunk = 0;
+	off_t offset;
+
+	if (!kvm_memslot_userfault(memslot))
+		return 0;
+
+	if (WARN_ON_ONCE(!memslot->userfault_bitmap))
+		return 0;
+
+	offset = gfn - memslot->base_gfn;
+
+	if (copy_from_user(&bitmap_chunk,
+			   memslot->userfault_bitmap + offset / BITS_PER_LONG,
+			   sizeof(bitmap_chunk)))
+		return -EFAULT;
+
+	/* Set in the bitmap means that the gfn is userfault */
+	return !!(bitmap_chunk & (1ul << (offset % BITS_PER_LONG)));
+}
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:37 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:37 +0000
Subject: [PATCH v1 02/13] KVM: Add KVM_MEMORY_EXIT_FLAG_USERFAULT
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-3-jthoughton@google.com>

This flag is used for vCPU memory faults caused by KVM Userfault; i.e.,
the bit in `userfault_bitmap` corresponding to the faulting gfn was set.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 include/uapi/linux/kvm.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 94be7e8b46a4..641a2e580441 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -444,6 +444,7 @@ struct kvm_run {
 		/* KVM_EXIT_MEMORY_FAULT */
 		struct {
 #define KVM_MEMORY_EXIT_FLAG_PRIVATE	(1ULL << 3)
+#define KVM_MEMORY_EXIT_FLAG_USERFAULT	(1ULL << 4)
 			__u64 flags;
 			__u64 gpa;
 			__u64 size;
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:38 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:38 +0000
Subject: [PATCH v1 03/13] KVM: Allow late setting of KVM_MEM_USERFAULT on
 guest_memfd memslot
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-4-jthoughton@google.com>

Currently guest_memfd memslots can only be deleted. Slightly change the
logic to allow KVM_MR_FLAGS_ONLY changes when the only flag being
changed is KVM_MEM_USERFAULT.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 virt/kvm/kvm_main.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 23fa3e911c4e..fa851704db94 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2009,9 +2009,6 @@ int __kvm_set_memory_region(struct kvm *kvm,
 		if ((kvm->nr_memslot_pages + npages) < kvm->nr_memslot_pages)
 			return -EINVAL;
 	} else { /* Modify an existing slot. */
-		/* Private memslots are immutable, they can only be deleted. */
-		if (mem->flags & KVM_MEM_GUEST_MEMFD)
-			return -EINVAL;
 		if ((mem->userspace_addr != old->userspace_addr) ||
 		    (npages != old->npages) ||
 		    ((mem->flags ^ old->flags) & KVM_MEM_READONLY))
@@ -2025,6 +2022,16 @@ int __kvm_set_memory_region(struct kvm *kvm,
 			return 0;
 	}
 
+	/*
+	 * Except for being able to set KVM_MEM_USERFAULT, private memslots are
+	 * immutable, they can only be deleted.
+	 */
+	if (mem->flags & KVM_MEM_GUEST_MEMFD &&
+	    !(change == KVM_MR_CREATE ||
+	      (change == KVM_MR_FLAGS_ONLY &&
+	       (mem->flags ^ old->flags) == KVM_MEM_USERFAULT)))
+		return -EINVAL;
+
 	if ((change == KVM_MR_CREATE || change == KVM_MR_MOVE) &&
 	    kvm_check_memslot_overlap(slots, id, base_gfn, base_gfn + npages))
 		return -EEXIST;
@@ -2040,7 +2047,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
 	new->npages = npages;
 	new->flags = mem->flags;
 	new->userspace_addr = mem->userspace_addr;
-	if (mem->flags & KVM_MEM_GUEST_MEMFD) {
+	if (mem->flags & KVM_MEM_GUEST_MEMFD && change == KVM_MR_CREATE) {
 		r = kvm_gmem_bind(kvm, new, mem->guest_memfd, mem->guest_memfd_offset);
 		if (r)
 			goto out;
-- 
2.47.0.338.g60cca15819-goog



From florian.fainelli at broadcom.com  Wed Dec  4 11:05:58 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Wed, 4 Dec 2024 11:05:58 -0800
Subject: [PATCH 4/7] arm64: dts: broadcom: Fix device tree warnings for
 BCM2712 display pipeline
In-Reply-To: <c8093283-f2c1-4a66-823a-50aeabb3c82b@kernel.org>
References: <20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a@raspberrypi.com>
 <20241202-dt-bcm2712-fixes-v1-4-fac67cc2f98a@raspberrypi.com>
 <c8093283-f2c1-4a66-823a-50aeabb3c82b@kernel.org>
Message-ID: <5b36a3c7-f691-49e5-a4c6-803ddccdd5ea@broadcom.com>

On 12/2/24 07:20, Krzysztof Kozlowski wrote:
> On 02/12/2024 15:31, Dave Stevenson wrote:
>> Fixes up errors on HDMI and interrupt controllers that weren't
> 
> What errors? I can't find anything in the commit. Describe the error.
> 
>> noticed before merging.
>>
>> Fixes: de9bc2dba3db ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
>> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
>> ---
>>   arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 8 ++++----
>>   1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
>> index 39305e0869ec..f42fad2d8b37 100644
>> --- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
>> +++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
>> @@ -336,7 +336,7 @@ ddc1: i2c at 7d508280 {
>>   			#size-cells = <0>;
>>   		};
>>   
>> -		bsc_irq: intc at 7d508380 {
>> +		bsc_irq: interrupt-controller at 7d508380 {
> 
> 
> Do not mix cleanups with bugfixes.
> 
> BTW, do not mix DTS to DRM. DRM has its own development style. DTS
> *cannot* be merged there, so combining these series is not welcomed and
> leads to issues (like DRM applying DTS!).

That is not what was done, I took the DTS patches via the Broadcom ARM 
SoC tree, as I usually do, unless someone tells me otherwise.

We got a number of DTS warnings after I took Dave's patches so I asked 
for those to be fixed, as it turns out there are binding and DTS fixes.

I intend to squash these fixes with their original commit, so all of 
those commit messages will be discarded, they are only meant to be 
transitional.
-- 
Florian


From val at packett.cool  Wed Dec  4 11:05:03 2024
From: val at packett.cool (Val Packett)
Date: Wed,  4 Dec 2024 16:05:03 -0300
Subject: [PATCH 0/5] MT8516/MT8167 dtsi fixes
Message-ID: <20241204190524.21862-1-val@packett.cool>

Hi everyone,

I've been working on mainline bringup on an MT8167 tablet I found at a
junkyard sale (lenovo,tb7304f) for postmarketOS :3

This first series consists of basic device tree fixes for the MT8516
dtsi that the MT8167 one inherits from.

The changes that follow add support for the MT6392 PMIC, and that's
mostly been implemented by Fabien Parent back in 2020 and not merged:

<https://patchwork.kernel.org/project/linux-arm-kernel/patch/20201027181157.862927-3-fparent at baylibre.com/>
<https://patchwork.kernel.org/project/linux-arm-kernel/patch/20201024200304.1427864-2-fparent at baylibre.com/>

but I have a couple changes on top of those patches (like adding the
missing mt6392_set_buck_vosel_reg). I'm wondering what the best way to
get this in would be, should I squash my changes and submit the "final"
patches with a Co-developed-by tag?

(Similar situation with DRM nodes, not merged due to "concerns about
the driver architecture" in 2021, now missing GCE/CMDQ mailbox props:
<https://lore.kernel.org/df4c57f9-115b-c4da-e656-e4bdec62c2d7 at gmail.com/>)

By the way, is anyone familiar with PSCI cpuidle/hot-unplug issues on
Mediatek Android devices from around this time? Specifically on this
tablet, I can't make the cores come back from suspend. I have
investigated local-timer-stop and arm,no-tick-in-suspend, Fabien pointed
me to the mediatek timer and its required clocks, but nothing helped.
Trying the psci_checker, I realized that it's not just suspend: they
do not come back from hot-unplug either. Initial CPU_ON on boot is fine,
but then after a CPU_OFF they do not actually come back when CPU_ON
supposedly turns them on. Now I can't help but notice that the only DTS
in mainline for a device that came with Android, mt6795-sony-xperia-m5,
does not have any cpuidle nodes in its SoC's dtsi either..

Val Packett (5):
  arm64: dts: mediatek: mt8516: fix GICv2 range
  arm64: dts: mediatek: mt8516: fix wdt irq type
  arm64: dts: mediatek: mt8516: add i2c clock-div property
  arm64: dts: mediatek: mt8516: reserve 192 KiB for TF-A
  arm64: dts: mediatek: mt8516: add keypad node

 arch/arm64/boot/dts/mediatek/mt8516.dtsi      | 21 +++++++++++++++----
 .../boot/dts/mediatek/pumpkin-common.dtsi     |  2 --
 2 files changed, 17 insertions(+), 6 deletions(-)

-- 
2.47.1



From val at packett.cool  Wed Dec  4 11:05:04 2024
From: val at packett.cool (Val Packett)
Date: Wed,  4 Dec 2024 16:05:04 -0300
Subject: [PATCH 1/5] arm64: dts: mediatek: mt8516: fix GICv2 range
In-Reply-To: <20241204190524.21862-1-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
Message-ID: <20241204190524.21862-2-val@packett.cool>

On the MT8167 which is based on the MT8516 DTS, the following error
was appearing on boot, breaking interrupt operation:

GICv2 detected, but range too small and irqchip.gicv2_force_probe not set

Similar to what's been proposed for MT7622 which has the same issue,
fix by using the range reported by force_probe.

Link: https://lore.kernel.org/all/YmhNSLgp%2Fyg8Vr1F at makrotopia.org/
Fixes: 5236347bde42 ("arm64: dts: mediatek: add dtsi for MT8516")
Signed-off-by: Val Packett <val at packett.cool>
---
 arch/arm64/boot/dts/mediatek/mt8516.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
index d0b03dc4d3f4..444429341302 100644
--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
@@ -268,7 +268,7 @@ gic: interrupt-controller at 10310000 {
 			interrupt-parent = <&gic>;
 			interrupt-controller;
 			reg = <0 0x10310000 0 0x1000>,
-			      <0 0x10320000 0 0x1000>,
+			      <0 0x1032f000 0 0x2000>,
 			      <0 0x10340000 0 0x2000>,
 			      <0 0x10360000 0 0x2000>;
 			interrupts = <GIC_PPI 9
-- 
2.47.1



From val at packett.cool  Wed Dec  4 11:05:05 2024
From: val at packett.cool (Val Packett)
Date: Wed,  4 Dec 2024 16:05:05 -0300
Subject: [PATCH 2/5] arm64: dts: mediatek: mt8516: fix wdt irq type
In-Reply-To: <20241204190524.21862-1-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
Message-ID: <20241204190524.21862-3-val@packett.cool>

The GICv2 does not support EDGE_FALLING interrupts, so the watchdog
would refuse to attach due to a failing check coming from the GIC driver.

Fixes: 5236347bde42 ("arm64: dts: mediatek: add dtsi for MT8516")
Signed-off-by: Val Packett <val at packett.cool>
---
 arch/arm64/boot/dts/mediatek/mt8516.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
index 444429341302..098c32ebf678 100644
--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
@@ -206,7 +206,7 @@ watchdog at 10007000 {
 			compatible = "mediatek,mt8516-wdt",
 				     "mediatek,mt6589-wdt";
 			reg = <0 0x10007000 0 0x1000>;
-			interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_FALLING>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
 			#reset-cells = <1>;
 		};
 
-- 
2.47.1



From val at packett.cool  Wed Dec  4 11:05:06 2024
From: val at packett.cool (Val Packett)
Date: Wed,  4 Dec 2024 16:05:06 -0300
Subject: [PATCH 3/5] arm64: dts: mediatek: mt8516: add i2c clock-div property
In-Reply-To: <20241204190524.21862-1-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
Message-ID: <20241204190524.21862-4-val@packett.cool>

Move the clock-div property from the pumpkin board dtsi to the SoC's
since it belongs to the SoC itself and is required on other devices.

Fixes: 5236347bde42 ("arm64: dts: mediatek: add dtsi for MT8516")
Signed-off-by: Val Packett <val at packett.cool>
---
 arch/arm64/boot/dts/mediatek/mt8516.dtsi         | 3 +++
 arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi | 2 --
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
index 098c32ebf678..dd17d8a88c19 100644
--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
@@ -344,6 +344,7 @@ i2c0: i2c at 11009000 {
 			reg = <0 0x11009000 0 0x90>,
 			      <0 0x11000180 0 0x80>;
 			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_LOW>;
+			clock-div = <2>;
 			clocks = <&topckgen CLK_TOP_I2C0>,
 				 <&topckgen CLK_TOP_APDMA>;
 			clock-names = "main", "dma";
@@ -358,6 +359,7 @@ i2c1: i2c at 1100a000 {
 			reg = <0 0x1100a000 0 0x90>,
 			      <0 0x11000200 0 0x80>;
 			interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_LOW>;
+			clock-div = <2>;
 			clocks = <&topckgen CLK_TOP_I2C1>,
 				 <&topckgen CLK_TOP_APDMA>;
 			clock-names = "main", "dma";
@@ -372,6 +374,7 @@ i2c2: i2c at 1100b000 {
 			reg = <0 0x1100b000 0 0x90>,
 			      <0 0x11000280 0 0x80>;
 			interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_LOW>;
+			clock-div = <2>;
 			clocks = <&topckgen CLK_TOP_I2C2>,
 				 <&topckgen CLK_TOP_APDMA>;
 			clock-names = "main", "dma";
diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
index ec8dfb3d1c6d..a356db5fcc5f 100644
--- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
+++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
@@ -47,7 +47,6 @@ key-volume-down {
 };
 
 &i2c0 {
-	clock-div = <2>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins_a>;
 	status = "okay";
@@ -156,7 +155,6 @@ cam-pwdn-hog {
 };
 
 &i2c2 {
-	clock-div = <2>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c2_pins_a>;
 	status = "okay";
-- 
2.47.1



From val at packett.cool  Wed Dec  4 11:05:07 2024
From: val at packett.cool (Val Packett)
Date: Wed,  4 Dec 2024 16:05:07 -0300
Subject: [PATCH 4/5] arm64: dts: mediatek: mt8516: reserve 192 KiB for TF-A
In-Reply-To: <20241204190524.21862-1-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
Message-ID: <20241204190524.21862-5-val@packett.cool>

The Android DTB for the related MT8167 reserves 0x30000. This is likely
correct for MT8516 Android devices as well, and there's never any harm
in reserving 64KiB more.

Fixes: 5236347bde42 ("arm64: dts: mediatek: add dtsi for MT8516")
Signed-off-by: Val Packett <val at packett.cool>
---
 arch/arm64/boot/dts/mediatek/mt8516.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
index dd17d8a88c19..e30623ebac0e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
@@ -144,10 +144,10 @@ reserved-memory {
 		#size-cells = <2>;
 		ranges;
 
-		/* 128 KiB reserved for ARM Trusted Firmware (BL31) */
+		/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
 		bl31_secmon_reserved: secmon at 43000000 {
 			no-map;
-			reg = <0 0x43000000 0 0x20000>;
+			reg = <0 0x43000000 0 0x30000>;
 		};
 	};
 
-- 
2.47.1



From val at packett.cool  Wed Dec  4 11:05:08 2024
From: val at packett.cool (Val Packett)
Date: Wed,  4 Dec 2024 16:05:08 -0300
Subject: [PATCH 5/5] arm64: dts: mediatek: mt8516: add keypad node
In-Reply-To: <20241204190524.21862-1-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
Message-ID: <20241204190524.21862-6-val@packett.cool>

Add a keypad matrix node for the MT8516/MT8167 SoC.

Signed-off-by: Val Packett <val at packett.cool>
---
 arch/arm64/boot/dts/mediatek/mt8516.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
index e30623ebac0e..3beb9f74ec79 100644
--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
@@ -220,6 +220,16 @@ timer: timer at 10008000 {
 			clock-names = "clk13m", "bus";
 		};
 
+		keypad: keypad at 10002000 {
+			compatible = "mediatek,mt6779-keypad";
+			reg = <0 0x10002000 0 0x1000>;
+			wakeup-source;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_EDGE_FALLING>;
+			clocks = <&clk26m>;
+			clock-names = "kpd";
+			status = "disabled";
+		};
+
 		syscfg_pctl: syscfg-pctl at 10005000 {
 			compatible = "syscon";
 			reg = <0 0x10005000 0 0x1000>;
-- 
2.47.1



From jthoughton at google.com  Wed Dec  4 11:13:39 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:39 +0000
Subject: [PATCH v1 04/13] KVM: Advertise KVM_CAP_USERFAULT in KVM_CHECK_EXTENSION
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-5-jthoughton@google.com>

Advertise support for KVM_CAP_USERFAULT when kvm_has_userfault() returns
true. Currently this is merely IS_ENABLED(CONFIG_HAVE_KVM_USERFAULT), so
it is somewhat redundant.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 include/uapi/linux/kvm.h | 1 +
 virt/kvm/kvm_main.c      | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 641a2e580441..d9a135c895d7 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -936,6 +936,7 @@ struct kvm_enable_cap {
 #define KVM_CAP_PRE_FAULT_MEMORY 236
 #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237
 #define KVM_CAP_X86_GUEST_MODE 238
+#define KVM_CAP_USERFAULT 239
 
 struct kvm_irq_routing_irqchip {
 	__u32 irqchip;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index fa851704db94..b552cdef2850 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -4804,6 +4804,10 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
 #ifdef CONFIG_KVM_PRIVATE_MEM
 	case KVM_CAP_GUEST_MEMFD:
 		return !kvm || kvm_arch_has_private_mem(kvm);
+#endif
+#ifdef CONFIG_HAVE_KVM_USERFAULT
+	case KVM_CAP_USERFAULT:
+		return kvm_has_userfault(kvm);
 #endif
 	default:
 		break;
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:40 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:40 +0000
Subject: [PATCH v1 05/13] KVM: x86/mmu: Add support for KVM_MEM_USERFAULT
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-6-jthoughton@google.com>

Adhering to the requirements of KVM Userfault:

1. Zap all sptes for the memslot when KVM_MEM_USERFAULT is toggled on
   with kvm_arch_flush_shadow_memslot().
2. Only all PAGE_SIZE sptes while KVM_MEM_USERFAULT is enabled (for both
   normal/GUP memory and guest_memfd memory).
3. Reconstruct huge mappings when KVM_MEM_USERFAULT is toggled off with
   kvm_mmu_recover_huge_pages().

With the new logic in kvm_mmu_slot_apply_flags(), I've simplified the
two dirty-logging-toggle checks into one, and I have dropped the
WARN_ON() that was there.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 arch/x86/kvm/Kconfig            |  1 +
 arch/x86/kvm/mmu/mmu.c          | 27 +++++++++++++++++++++----
 arch/x86/kvm/mmu/mmu_internal.h | 20 +++++++++++++++---
 arch/x86/kvm/x86.c              | 36 ++++++++++++++++++++++++---------
 include/linux/kvm_host.h        |  5 ++++-
 5 files changed, 71 insertions(+), 18 deletions(-)

diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index ea2c4f21c1ca..286c6825cd1c 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -47,6 +47,7 @@ config KVM_X86
 	select KVM_GENERIC_PRE_FAULT_MEMORY
 	select KVM_GENERIC_PRIVATE_MEM if KVM_SW_PROTECTED_VM
 	select KVM_WERROR if WERROR
+	select HAVE_KVM_USERFAULT
 
 config KVM
 	tristate "Kernel-based Virtual Machine (KVM) support"
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 22e7ad235123..2f7381255d11 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -4292,14 +4292,19 @@ static inline u8 kvm_max_level_for_order(int order)
 	return PG_LEVEL_4K;
 }
 
-static u8 kvm_max_private_mapping_level(struct kvm *kvm, kvm_pfn_t pfn,
-					u8 max_level, int gmem_order)
+static u8 kvm_max_private_mapping_level(struct kvm *kvm,
+					struct kvm_memory_slot *slot,
+					kvm_pfn_t pfn, u8 max_level,
+					int gmem_order)
 {
 	u8 req_max_level;
 
 	if (max_level == PG_LEVEL_4K)
 		return PG_LEVEL_4K;
 
+	if (kvm_memslot_userfault(slot))
+		return PG_LEVEL_4K;
+
 	max_level = min(kvm_max_level_for_order(gmem_order), max_level);
 	if (max_level == PG_LEVEL_4K)
 		return PG_LEVEL_4K;
@@ -4336,8 +4341,10 @@ static int kvm_mmu_faultin_pfn_private(struct kvm_vcpu *vcpu,
 	}
 
 	fault->map_writable = !(fault->slot->flags & KVM_MEM_READONLY);
-	fault->max_level = kvm_max_private_mapping_level(vcpu->kvm, fault->pfn,
-							 fault->max_level, max_order);
+	fault->max_level = kvm_max_private_mapping_level(vcpu->kvm, fault->slot,
+							 fault->pfn,
+							 fault->max_level,
+							 max_order);
 
 	return RET_PF_CONTINUE;
 }
@@ -4346,6 +4353,18 @@ static int __kvm_mmu_faultin_pfn(struct kvm_vcpu *vcpu,
 				 struct kvm_page_fault *fault)
 {
 	unsigned int foll = fault->write ? FOLL_WRITE : 0;
+	int userfault;
+
+	userfault = kvm_gfn_userfault(vcpu->kvm, fault->slot, fault->gfn);
+	if (userfault < 0)
+		return userfault;
+	if (userfault) {
+		kvm_mmu_prepare_userfault_exit(vcpu, fault);
+		return -EFAULT;
+	}
+
+	if (kvm_memslot_userfault(fault->slot))
+		fault->max_level = PG_LEVEL_4K;
 
 	if (fault->is_private)
 		return kvm_mmu_faultin_pfn_private(vcpu, fault);
diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h
index b00abbe3f6cf..15705faa3b67 100644
--- a/arch/x86/kvm/mmu/mmu_internal.h
+++ b/arch/x86/kvm/mmu/mmu_internal.h
@@ -282,12 +282,26 @@ enum {
 	RET_PF_SPURIOUS,
 };
 
-static inline void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
-						     struct kvm_page_fault *fault)
+static inline void __kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
+						       struct kvm_page_fault *fault,
+						       bool is_userfault)
 {
 	kvm_prepare_memory_fault_exit(vcpu, fault->gfn << PAGE_SHIFT,
 				      PAGE_SIZE, fault->write, fault->exec,
-				      fault->is_private);
+				      fault->is_private,
+				      is_userfault);
+}
+
+static inline void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
+						     struct kvm_page_fault *fault)
+{
+	__kvm_mmu_prepare_memory_fault_exit(vcpu, fault, false);
+}
+
+static inline void kvm_mmu_prepare_userfault_exit(struct kvm_vcpu *vcpu,
+						  struct kvm_page_fault *fault)
+{
+	__kvm_mmu_prepare_memory_fault_exit(vcpu, fault, true);
 }
 
 static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2e713480933a..2f7080fd6218 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -13053,12 +13053,36 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm,
 	u32 new_flags = new ? new->flags : 0;
 	bool log_dirty_pages = new_flags & KVM_MEM_LOG_DIRTY_PAGES;
 
+	/*
+	 * When toggling KVM Userfault on, zap all sptes so that userfault-ness
+	 * will be respected at refault time. All new faults will only install
+	 * small sptes. Therefore, when toggling it off, recover hugepages.
+	 *
+	 * For MOVE and DELETE, there will be nothing to do, as the old
+	 * mappings will have already been deleted by
+	 * kvm_arch_flush_shadow_memslot().
+	 *
+	 * For CREATE, no mappings will have been created yet.
+	 */
+	if ((old_flags ^ new_flags) & KVM_MEM_USERFAULT &&
+	    (change == KVM_MR_FLAGS_ONLY)) {
+		if (old_flags & KVM_MEM_USERFAULT)
+			kvm_mmu_recover_huge_pages(kvm, new);
+		else
+			kvm_arch_flush_shadow_memslot(kvm, old);
+	}
+
+	/*
+	 * Nothing more to do if dirty logging isn't being toggled.
+	 */
+	if (!((old_flags ^ new_flags) & KVM_MEM_LOG_DIRTY_PAGES))
+		return;
+
 	/*
 	 * Update CPU dirty logging if dirty logging is being toggled.  This
 	 * applies to all operations.
 	 */
-	if ((old_flags ^ new_flags) & KVM_MEM_LOG_DIRTY_PAGES)
-		kvm_mmu_update_cpu_dirty_logging(kvm, log_dirty_pages);
+	kvm_mmu_update_cpu_dirty_logging(kvm, log_dirty_pages);
 
 	/*
 	 * Nothing more to do for RO slots (which can't be dirtied and can't be
@@ -13078,14 +13102,6 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm,
 	if ((change != KVM_MR_FLAGS_ONLY) || (new_flags & KVM_MEM_READONLY))
 		return;
 
-	/*
-	 * READONLY and non-flags changes were filtered out above, and the only
-	 * other flag is LOG_DIRTY_PAGES, i.e. something is wrong if dirty
-	 * logging isn't being toggled on or off.
-	 */
-	if (WARN_ON_ONCE(!((old_flags ^ new_flags) & KVM_MEM_LOG_DIRTY_PAGES)))
-		return;
-
 	if (!log_dirty_pages) {
 		/*
 		 * Recover huge page mappings in the slot now that dirty logging
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index f7a3dfd5e224..9e8a8dcf2b73 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -2465,7 +2465,8 @@ static inline void kvm_account_pgtable_pages(void *virt, int nr)
 static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
 						 gpa_t gpa, gpa_t size,
 						 bool is_write, bool is_exec,
-						 bool is_private)
+						 bool is_private,
+						 bool is_userfault)
 {
 	vcpu->run->exit_reason = KVM_EXIT_MEMORY_FAULT;
 	vcpu->run->memory_fault.gpa = gpa;
@@ -2475,6 +2476,8 @@ static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
 	vcpu->run->memory_fault.flags = 0;
 	if (is_private)
 		vcpu->run->memory_fault.flags |= KVM_MEMORY_EXIT_FLAG_PRIVATE;
+	if (is_userfault)
+		vcpu->run->memory_fault.flags |= KVM_MEMORY_EXIT_FLAG_USERFAULT;
 }
 
 #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:44 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:44 +0000
Subject: [PATCH v1 09/13] KVM: selftests: Add va_start/end into uffd_desc
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-10-jthoughton@google.com>

This will be used for the self-test to look up which userfaultfd we
should be using when handling a KVM Userfault (in the event KVM
Userfault and userfaultfd are being used together).

Signed-off-by: James Houghton <jthoughton at google.com>
---
 tools/testing/selftests/kvm/include/userfaultfd_util.h | 2 ++
 tools/testing/selftests/kvm/lib/userfaultfd_util.c     | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/userfaultfd_util.h b/tools/testing/selftests/kvm/include/userfaultfd_util.h
index 60f7f9d435dc..b62fecdfe745 100644
--- a/tools/testing/selftests/kvm/include/userfaultfd_util.h
+++ b/tools/testing/selftests/kvm/include/userfaultfd_util.h
@@ -30,6 +30,8 @@ struct uffd_desc {
 	int *pipefds;
 	pthread_t *readers;
 	struct uffd_reader_args *reader_args;
+	void *va_start;
+	void *va_end;
 };
 
 struct uffd_desc *uffd_setup_demand_paging(int uffd_mode, useconds_t delay,
diff --git a/tools/testing/selftests/kvm/lib/userfaultfd_util.c b/tools/testing/selftests/kvm/lib/userfaultfd_util.c
index 7c9de8414462..93004c85bcdc 100644
--- a/tools/testing/selftests/kvm/lib/userfaultfd_util.c
+++ b/tools/testing/selftests/kvm/lib/userfaultfd_util.c
@@ -152,6 +152,8 @@ struct uffd_desc *uffd_setup_demand_paging(int uffd_mode, useconds_t delay,
 		    expected_ioctls, "missing userfaultfd ioctls");
 
 	uffd_desc->uffd = uffd;
+	uffd_desc->va_start = hva;
+	uffd_desc->va_end = (char *)hva + len;
 	for (i = 0; i < uffd_desc->num_readers; ++i) {
 		int pipes[2];
 
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:45 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:45 +0000
Subject: [PATCH v1 10/13] KVM: selftests: Add KVM Userfault mode to demand_paging_test
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-11-jthoughton@google.com>

Add a way for the KVM_RUN loop to handle -EFAULT exits when they are for
KVM_MEMORY_EXIT_FLAG_USERFAULT. In this case, preemptively handle the
UFFDIO_COPY or UFFDIO_CONTINUE if userfaultfd is also in use. This saves
the trip through the userfaultfd poll/read/WAKE loop.

When preemptively handling UFFDIO_COPY/CONTINUE, do so with
MODE_DONTWAKE, as there will not be a thread to wake. If a thread *does*
take the userfaultfd slow path, we will get a regular userfault, and we
will call handle_uffd_page_request() which will do a full wake-up. In
the EEXIST case, a wake-up will not occur. Make sure to call UFFDIO_WAKE
explicitly in this case.

When handling KVM userfaults, make sure to set the bitmap with
memory_order_release. Although it wouldn't affect the functionality of
the test (because memstress doesn't actually require any particular
guest memory contents), it is what userspace normally needs to do.

Add `-k` to set the test to use KVM Userfault.

Add the vm_mem_region_set_flags_userfault() helper for setting
`userfault_bitmap` and KVM_MEM_USERFAULT at the same time.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 .../selftests/kvm/demand_paging_test.c        | 139 +++++++++++++++++-
 .../testing/selftests/kvm/include/kvm_util.h  |   5 +
 tools/testing/selftests/kvm/lib/kvm_util.c    |  40 ++++-
 3 files changed, 176 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c
index 315f5c9037b4..e7ea1c57264d 100644
--- a/tools/testing/selftests/kvm/demand_paging_test.c
+++ b/tools/testing/selftests/kvm/demand_paging_test.c
@@ -12,7 +12,9 @@
 #include <time.h>
 #include <pthread.h>
 #include <linux/userfaultfd.h>
+#include <linux/bitmap.h>
 #include <sys/syscall.h>
+#include <stdatomic.h>
 
 #include "kvm_util.h"
 #include "test_util.h"
@@ -24,11 +26,21 @@
 #ifdef __NR_userfaultfd
 
 static int nr_vcpus = 1;
+static int num_uffds;
 static uint64_t guest_percpu_mem_size = DEFAULT_PER_VCPU_MEM_SIZE;
 
 static size_t demand_paging_size;
+static size_t host_page_size;
 static char *guest_data_prototype;
 
+static struct {
+	bool enabled;
+	int uffd_mode; /* set if userfaultfd is also in use */
+	struct uffd_desc **uffd_descs;
+} kvm_userfault_data;
+
+static void resolve_kvm_userfault(u64 gpa, u64 size);
+
 static void vcpu_worker(struct memstress_vcpu_args *vcpu_args)
 {
 	struct kvm_vcpu *vcpu = vcpu_args->vcpu;
@@ -41,8 +53,22 @@ static void vcpu_worker(struct memstress_vcpu_args *vcpu_args)
 	clock_gettime(CLOCK_MONOTONIC, &start);
 
 	/* Let the guest access its memory */
+restart:
 	ret = _vcpu_run(vcpu);
-	TEST_ASSERT(ret == 0, "vcpu_run failed: %d", ret);
+	if (ret < 0 && errno == EFAULT && kvm_userfault_data.enabled) {
+		/* Check for userfault. */
+		TEST_ASSERT(run->exit_reason == KVM_EXIT_MEMORY_FAULT,
+			    "Got invalid exit reason: %x", run->exit_reason);
+		TEST_ASSERT(run->memory_fault.flags ==
+			    KVM_MEMORY_EXIT_FLAG_USERFAULT,
+			    "Got invalid memory fault exit: %llx",
+			    run->memory_fault.flags);
+		resolve_kvm_userfault(run->memory_fault.gpa,
+				      run->memory_fault.size);
+		goto restart;
+	} else
+		TEST_ASSERT(ret == 0, "vcpu_run failed: %d", ret);
+
 	if (get_ucall(vcpu, NULL) != UCALL_SYNC) {
 		TEST_ASSERT(false,
 			    "Invalid guest sync status: exit_reason=%s",
@@ -54,11 +80,10 @@ static void vcpu_worker(struct memstress_vcpu_args *vcpu_args)
 		       ts_diff.tv_sec, ts_diff.tv_nsec);
 }
 
-static int handle_uffd_page_request(int uffd_mode, int uffd,
-		struct uffd_msg *msg)
+static int resolve_uffd_page_request(int uffd_mode, int uffd, uint64_t addr,
+				     bool wake)
 {
 	pid_t tid = syscall(__NR_gettid);
-	uint64_t addr = msg->arg.pagefault.address;
 	struct timespec start;
 	struct timespec ts_diff;
 	int r;
@@ -71,7 +96,7 @@ static int handle_uffd_page_request(int uffd_mode, int uffd,
 		copy.src = (uint64_t)guest_data_prototype;
 		copy.dst = addr;
 		copy.len = demand_paging_size;
-		copy.mode = 0;
+		copy.mode = wake ? 0 : UFFDIO_COPY_MODE_DONTWAKE;
 
 		r = ioctl(uffd, UFFDIO_COPY, &copy);
 		/*
@@ -96,6 +121,7 @@ static int handle_uffd_page_request(int uffd_mode, int uffd,
 
 		cont.range.start = addr;
 		cont.range.len = demand_paging_size;
+		cont.mode = wake ? 0 : UFFDIO_CONTINUE_MODE_DONTWAKE;
 
 		r = ioctl(uffd, UFFDIO_CONTINUE, &cont);
 		/*
@@ -119,6 +145,20 @@ static int handle_uffd_page_request(int uffd_mode, int uffd,
 		TEST_FAIL("Invalid uffd mode %d", uffd_mode);
 	}
 
+	if (r < 0 && wake) {
+		/*
+		 * No wake-up occurs when UFFDIO_COPY/CONTINUE fails, but we
+		 * have a thread waiting. Wake it up.
+		 */
+		struct uffdio_range range = {0};
+
+		range.start = addr;
+		range.len = demand_paging_size;
+
+		TEST_ASSERT(ioctl(uffd, UFFDIO_WAKE, &range) == 0,
+			    "UFFDIO_WAKE failed: 0x%lx", addr);
+	}
+
 	ts_diff = timespec_elapsed(start);
 
 	PER_PAGE_DEBUG("UFFD page-in %d \t%ld ns\n", tid,
@@ -129,6 +169,58 @@ static int handle_uffd_page_request(int uffd_mode, int uffd,
 	return 0;
 }
 
+static int handle_uffd_page_request(int uffd_mode, int uffd,
+				    struct uffd_msg *msg)
+{
+	uint64_t addr = msg->arg.pagefault.address;
+
+	return resolve_uffd_page_request(uffd_mode, uffd, addr, true);
+}
+
+static void resolve_kvm_userfault(u64 gpa, u64 size)
+{
+	struct kvm_vm *vm = memstress_args.vm;
+	struct userspace_mem_region *region;
+	unsigned long *bitmap_chunk;
+	u64 page, gpa_offset;
+
+	region = (struct userspace_mem_region *) userspace_mem_region_find(
+		vm, gpa, (gpa + size - 1));
+
+	if (kvm_userfault_data.uffd_mode) {
+		/*
+		 * Resolve userfaults early, without needing to read them
+		 * off the userfaultfd.
+		 */
+		uint64_t hva = (uint64_t)addr_gpa2hva(vm, gpa);
+		struct uffd_desc **descs = kvm_userfault_data.uffd_descs;
+		int i, fd;
+
+		for (i = 0; i < num_uffds; ++i)
+			if (hva >= (uint64_t)descs[i]->va_start &&
+			    hva < (uint64_t)descs[i]->va_end)
+				break;
+
+		TEST_ASSERT(i < num_uffds,
+			    "Did not find userfaultfd for hva: %lx", hva);
+
+		fd = kvm_userfault_data.uffd_descs[i]->uffd;
+		resolve_uffd_page_request(kvm_userfault_data.uffd_mode, fd,
+					  hva, false);
+	} else {
+		uint64_t hva = (uint64_t)addr_gpa2hva(vm, gpa);
+
+		memcpy((char *)hva, guest_data_prototype, demand_paging_size);
+	}
+
+	gpa_offset = gpa - region->region.guest_phys_addr;
+	page = gpa_offset / host_page_size;
+	bitmap_chunk = (unsigned long *)region->region.userfault_bitmap +
+		       page / BITS_PER_LONG;
+	atomic_fetch_and_explicit(bitmap_chunk,
+			~(1ul << (page % BITS_PER_LONG)), memory_order_release);
+}
+
 struct test_params {
 	int uffd_mode;
 	bool single_uffd;
@@ -136,6 +228,7 @@ struct test_params {
 	int readers_per_uffd;
 	enum vm_mem_backing_src_type src_type;
 	bool partition_vcpu_memory_access;
+	bool kvm_userfault;
 };
 
 static void prefault_mem(void *alias, uint64_t len)
@@ -149,6 +242,25 @@ static void prefault_mem(void *alias, uint64_t len)
 	}
 }
 
+static void enable_userfault(struct kvm_vm *vm, int slots)
+{
+	for (int i = 0; i < slots; ++i) {
+		int slot = MEMSTRESS_MEM_SLOT_INDEX + i;
+		struct userspace_mem_region *region;
+		unsigned long *userfault_bitmap;
+		int flags = KVM_MEM_USERFAULT;
+
+		region = memslot2region(vm, slot);
+		userfault_bitmap = bitmap_zalloc(region->mmap_size /
+						 host_page_size);
+		/* everything is userfault initially */
+		memset(userfault_bitmap, -1, region->mmap_size / host_page_size / CHAR_BIT);
+		printf("Setting bitmap: %p\n", userfault_bitmap);
+		vm_mem_region_set_flags_userfault(vm, slot, flags,
+						  userfault_bitmap);
+	}
+}
+
 static void run_test(enum vm_guest_mode mode, void *arg)
 {
 	struct memstress_vcpu_args *vcpu_args;
@@ -159,12 +271,13 @@ static void run_test(enum vm_guest_mode mode, void *arg)
 	struct timespec ts_diff;
 	double vcpu_paging_rate;
 	struct kvm_vm *vm;
-	int i, num_uffds = 0;
+	int i;
 
 	vm = memstress_create_vm(mode, nr_vcpus, guest_percpu_mem_size, 1,
 				 p->src_type, p->partition_vcpu_memory_access);
 
 	demand_paging_size = get_backing_src_pagesz(p->src_type);
+	host_page_size = getpagesize();
 
 	guest_data_prototype = malloc(demand_paging_size);
 	TEST_ASSERT(guest_data_prototype,
@@ -208,6 +321,14 @@ static void run_test(enum vm_guest_mode mode, void *arg)
 		}
 	}
 
+	if (p->kvm_userfault) {
+		TEST_REQUIRE(kvm_has_cap(KVM_CAP_USERFAULT));
+		kvm_userfault_data.enabled = true;
+		kvm_userfault_data.uffd_mode = p->uffd_mode;
+		kvm_userfault_data.uffd_descs = uffd_descs;
+		enable_userfault(vm, 1);
+	}
+
 	pr_info("Finished creating vCPUs and starting uffd threads\n");
 
 	clock_gettime(CLOCK_MONOTONIC, &start);
@@ -265,6 +386,7 @@ static void help(char *name)
 	printf(" -v: specify the number of vCPUs to run.\n");
 	printf(" -o: Overlap guest memory accesses instead of partitioning\n"
 	       "     them into a separate region of memory for each vCPU.\n");
+	printf(" -k: Use KVM Userfault\n");
 	puts("");
 	exit(0);
 }
@@ -283,7 +405,7 @@ int main(int argc, char *argv[])
 
 	guest_modes_append_default();
 
-	while ((opt = getopt(argc, argv, "ahom:u:d:b:s:v:c:r:")) != -1) {
+	while ((opt = getopt(argc, argv, "ahokm:u:d:b:s:v:c:r:")) != -1) {
 		switch (opt) {
 		case 'm':
 			guest_modes_cmdline(optarg);
@@ -326,6 +448,9 @@ int main(int argc, char *argv[])
 				    "Invalid number of readers per uffd %d: must be >=1",
 				    p.readers_per_uffd);
 			break;
+		case 'k':
+			p.kvm_userfault = true;
+			break;
 		case 'h':
 		default:
 			help(argv[0]);
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index bc7c242480d6..7fec3559aa64 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -582,6 +582,8 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm,
 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);
+struct userspace_mem_region *
+userspace_mem_region_find(struct kvm_vm *vm, uint64_t start, uint64_t end);
 
 #ifndef vm_arch_has_protected_memory
 static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm)
@@ -591,6 +593,9 @@ static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm)
 #endif
 
 void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags);
+void vm_mem_region_set_flags_userfault(struct kvm_vm *vm, uint32_t slot,
+				       uint32_t flags,
+				       unsigned long *userfault_bitmap);
 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);
 struct kvm_vcpu *__vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 9603f99d3247..7195dd3db5df 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -634,7 +634,7 @@ void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcpu[],
  * of the regions is returned.  Null is returned only when no overlapping
  * region exists.
  */
-static struct userspace_mem_region *
+struct userspace_mem_region *
 userspace_mem_region_find(struct kvm_vm *vm, uint64_t start, uint64_t end)
 {
 	struct rb_node *node;
@@ -1149,6 +1149,44 @@ void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags)
 		ret, errno, slot, flags);
 }
 
+/*
+ * VM Memory Region Flags Set with a userfault bitmap
+ *
+ * Input Args:
+ *   vm - Virtual Machine
+ *   flags - Flags for the memslot
+ *   userfault_bitmap - The bitmap to use for KVM_MEM_USERFAULT
+ *
+ * Output Args: None
+ *
+ * Return: None
+ *
+ * Sets the flags of the memory region specified by the value of slot,
+ * to the values given by flags. This helper adds a way to provide a
+ * userfault_bitmap.
+ */
+void vm_mem_region_set_flags_userfault(struct kvm_vm *vm, uint32_t slot,
+				       uint32_t flags,
+				       unsigned long *userfault_bitmap)
+{
+	int ret;
+	struct userspace_mem_region *region;
+
+	region = memslot2region(vm, slot);
+
+	TEST_ASSERT(!userfault_bitmap ^ (flags & KVM_MEM_USERFAULT),
+		    "KVM_MEM_USERFAULT must be specified with a bitmap");
+
+	region->region.flags = flags;
+	region->region.userfault_bitmap = (__u64)userfault_bitmap;
+
+	ret = __vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION2, &region->region);
+
+	TEST_ASSERT(ret == 0, "KVM_SET_USER_MEMORY_REGION2 IOCTL failed,\n"
+		"  rc: %i errno: %i slot: %u flags: 0x%x",
+		ret, errno, slot, flags);
+}
+
 /*
  * VM Memory Region Move
  *
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:46 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:46 +0000
Subject: [PATCH v1 11/13] KVM: selftests: Inform set_memory_region_test of KVM_MEM_USERFAULT
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-12-jthoughton@google.com>

The KVM_MEM_USERFAULT flag is supported iff KVM_CAP_USERFAULT is
available.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 tools/testing/selftests/kvm/set_memory_region_test.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c
index a8267628e9ed..d233cdfb0241 100644
--- a/tools/testing/selftests/kvm/set_memory_region_test.c
+++ b/tools/testing/selftests/kvm/set_memory_region_test.c
@@ -364,6 +364,9 @@ static void test_invalid_memory_region_flags(void)
 	if (kvm_check_cap(KVM_CAP_MEMORY_ATTRIBUTES) & KVM_MEMORY_ATTRIBUTE_PRIVATE)
 		supported_flags |= KVM_MEM_GUEST_MEMFD;
 
+	if (kvm_check_cap(KVM_CAP_USERFAULT))
+		supported_flags |= KVM_MEM_USERFAULT;
+
 	for (i = 0; i < 32; i++) {
 		if ((supported_flags & BIT(i)) && !(v2_only_flags & BIT(i)))
 			continue;
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:47 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:47 +0000
Subject: [PATCH v1 12/13] KVM: selftests: Add KVM_MEM_USERFAULT + guest_memfd
 toggle tests
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-13-jthoughton@google.com>

Make sure KVM_MEM_USERFAULT can be toggled on and off for
KVM_MEM_GUEST_MEMFD memslots.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 .../selftests/kvm/set_memory_region_test.c    | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c
index d233cdfb0241..57b7032d7cc3 100644
--- a/tools/testing/selftests/kvm/set_memory_region_test.c
+++ b/tools/testing/selftests/kvm/set_memory_region_test.c
@@ -556,6 +556,35 @@ static void test_add_overlapping_private_memory_regions(void)
 	close(memfd);
 	kvm_vm_free(vm);
 }
+
+static void test_private_memory_region_userfault(void)
+{
+	struct kvm_vm *vm;
+	int memfd;
+
+	pr_info("Testing toggling KVM_MEM_USERFAULT on KVM_MEM_GUEST_MEMFD memory regions\n");
+
+	vm = vm_create_barebones_type(KVM_X86_SW_PROTECTED_VM);
+
+	test_invalid_guest_memfd(vm, vm->kvm_fd, 0, "KVM fd should fail");
+	test_invalid_guest_memfd(vm, vm->fd, 0, "VM's fd should fail");
+
+	memfd = vm_create_guest_memfd(vm, MEM_REGION_SIZE, 0);
+
+	vm_set_user_memory_region2(vm, MEM_REGION_SLOT, KVM_MEM_GUEST_MEMFD,
+				   MEM_REGION_GPA, MEM_REGION_SIZE, 0, memfd, 0);
+
+	vm_set_user_memory_region2(vm, MEM_REGION_SLOT,
+				   KVM_MEM_GUEST_MEMFD | KVM_MEM_USERFAULT,
+				   MEM_REGION_GPA, MEM_REGION_SIZE, 0, memfd, 0);
+
+	vm_set_user_memory_region2(vm, MEM_REGION_SLOT, KVM_MEM_GUEST_MEMFD,
+				   MEM_REGION_GPA, MEM_REGION_SIZE, 0, memfd, 0);
+
+	close(memfd);
+
+	kvm_vm_free(vm);
+}
 #endif
 
 int main(int argc, char *argv[])
@@ -582,6 +611,7 @@ int main(int argc, char *argv[])
 	    (kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_VM))) {
 		test_add_private_memory_region();
 		test_add_overlapping_private_memory_regions();
+		test_private_memory_region_userfault();
 	} else {
 		pr_info("Skipping tests for KVM_MEM_GUEST_MEMFD memory regions\n");
 	}
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:48 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:48 +0000
Subject: [PATCH v1 13/13] KVM: Documentation: Add KVM_CAP_USERFAULT and
 KVM_MEM_USERFAULT details
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-14-jthoughton@google.com>

Include the note about memory ordering when clearing bits in
userfault_bitmap, as it may not be obvious for users.

Signed-off-by: James Houghton <jthoughton at google.com>
---
  I would like to include the new -EFAULT reason in the documentation for
  KVM_RUN (the case where userfault_bitmap could not be read), as -EFAULT
  usually means that GUP failed.
---
 Documentation/virt/kvm/api.rst | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 454c2aaa155e..eec485dcf0bc 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -6281,7 +6281,8 @@ bounds checks apply (use common sense).
 	__u64 guest_memfd_offset;
 	__u32 guest_memfd;
 	__u32 pad1;
-	__u64 pad2[14];
+	__u64 userfault_bitmap;
+	__u64 pad2[13];
   };
 
 A KVM_MEM_GUEST_MEMFD region _must_ have a valid guest_memfd (private memory) and
@@ -6297,6 +6298,25 @@ state.  At VM creation time, all memory is shared, i.e. the PRIVATE attribute
 is '0' for all gfns.  Userspace can control whether memory is shared/private by
 toggling KVM_MEMORY_ATTRIBUTE_PRIVATE via KVM_SET_MEMORY_ATTRIBUTES as needed.
 
+When the KVM_MEM_USERFAULT flag is set, userfault_bitmap points to the starting
+address for the bitmap that controls if vCPU memory faults should immediately
+exit to userspace. If an invalid pointer is provided, at fault time, KVM_RUN
+will return -EFAULT. KVM_MEM_USERFAULT is only supported when
+KVM_CAP_USERFAULT is supported.
+
+userfault_bitmap should point to an array of longs where each bit in the array
+linearly corresponds to a single gfn. Bit 0 in userfault_bitmap corresponds to
+guest_phys_addr, bit 1 corresponds to guest_phys_addr + PAGE_SIZE, etc. If the
+bit for a page is set, any vCPU access to that page will exit to userspace with
+KVM_MEMORY_EXIT_FLAG_USERFAULT.
+
+Setting bits in userfault_bitmap has no effect on pages that have already been
+mapped by KVM until KVM_MEM_USERFAULT is disabled and re-enabled again.
+
+Clearing bits in userfault_bitmap should usually be done with a store-release
+if changes to guest memory are being made available to the guest via
+userfault_bitmap.
+
 S390:
 ^^^^^
 
@@ -8251,6 +8271,17 @@ KVM exits with the register state of either the L1 or L2 guest
 depending on which executed at the time of an exit. Userspace must
 take care to differentiate between these cases.
 
+7.37 KVM_CAP_USERFAULT
+----------------------
+
+:Architectures: x86, arm64
+:Returns: Informational only, -EINVAL on direct KVM_ENABLE_CAP.
+
+The presence of this capability indicates that KVM_SET_USER_MEMORY_REGION2 will
+accept KVM_MEM_USERFAULT as a valid memslot flag.
+
+See KVM_SET_USER_MEMORY_REGION2 for more details.
+
 8. Other capabilities.
 ======================
 
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:41 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:41 +0000
Subject: [PATCH v1 06/13] KVM: arm64: Add support for KVM_MEM_USERFAULT
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-7-jthoughton@google.com>

Adhering to the requirements of KVM Userfault:

1. When it is toggled (either on or off), zap the second stage with
   kvm_arch_flush_shadow_memslot(). This is to (1) respect
   userfault-ness and (2) to reconstruct block mappings.
2. While KVM_MEM_USERFAULT is enabled, restrict new second-stage mappings
   to be PAGE_SIZE, just like when dirty logging is enabled.

Signed-off-by: James Houghton <jthoughton at google.com>
---
  I'm not 100% sure if kvm_arch_flush_shadow_memslot() is correct in
  this case (like if the host does not have S2FWB).
---
 arch/arm64/kvm/Kconfig |  1 +
 arch/arm64/kvm/mmu.c   | 23 ++++++++++++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index ead632ad01b4..d89b4088b580 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -38,6 +38,7 @@ menuconfig KVM
 	select HAVE_KVM_VCPU_RUN_PID_CHANGE
 	select SCHED_INFO
 	select GUEST_PERF_EVENTS if PERF_EVENTS
+	select HAVE_KVM_USERFAULT
 	help
 	  Support hosting virtualized guest machines.
 
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index a71fe6f6bd90..53cee0bacb75 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1482,7 +1482,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * logging_active is guaranteed to never be true for VM_PFNMAP
 	 * memslots.
 	 */
-	if (logging_active) {
+	if (logging_active || kvm_memslot_userfault(memslot)) {
 		force_pte = true;
 		vma_shift = PAGE_SHIFT;
 	} else {
@@ -1571,6 +1571,13 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	mmu_seq = vcpu->kvm->mmu_invalidate_seq;
 	mmap_read_unlock(current->mm);
 
+	if (kvm_gfn_userfault(kvm, memslot, gfn)) {
+		kvm_prepare_memory_fault_exit(vcpu, gfn << PAGE_SHIFT,
+					      PAGE_SIZE, write_fault,
+					      exec_fault, false, true);
+		return -EFAULT;
+	}
+
 	pfn = __kvm_faultin_pfn(memslot, gfn, write_fault ? FOLL_WRITE : 0,
 				&writable, &page);
 	if (pfn == KVM_PFN_ERR_HWPOISON) {
@@ -2062,6 +2069,20 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
 				   enum kvm_mr_change change)
 {
 	bool log_dirty_pages = new && new->flags & KVM_MEM_LOG_DIRTY_PAGES;
+	u32 changed_flags = (new ? new->flags : 0) ^ (old ? old->flags : 0);
+
+	/*
+	 * If KVM_MEM_USERFAULT changed, drop all the stage-2 mappings so that
+	 * we can (1) respect userfault-ness or (2) create block mappings.
+	 */
+	if ((changed_flags & KVM_MEM_USERFAULT) && change == KVM_MR_FLAGS_ONLY)
+		kvm_arch_flush_shadow_memslot(kvm, old);
+
+	/*
+	 * Nothing left to do if not toggling dirty logging.
+	 */
+	if (!(changed_flags & KVM_MEM_LOG_DIRTY_PAGES))
+		return;
 
 	/*
 	 * At this point memslot has been committed and there is an
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:42 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:42 +0000
Subject: [PATCH v1 07/13] KVM: selftests: Fix vm_mem_region_set_flags docstring
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-8-jthoughton@google.com>

`flags` is what region->region.flags gets set to.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 tools/testing/selftests/kvm/lib/kvm_util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 480e3a40d197..9603f99d3247 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1124,7 +1124,7 @@ memslot2region(struct kvm_vm *vm, uint32_t memslot)
  *
  * Input Args:
  *   vm - Virtual Machine
- *   flags - Starting guest physical address
+ *   flags - Flags for the memslot
  *
  * Output Args: None
  *
-- 
2.47.0.338.g60cca15819-goog



From jthoughton at google.com  Wed Dec  4 11:13:43 2024
From: jthoughton at google.com (James Houghton)
Date: Wed,  4 Dec 2024 19:13:43 +0000
Subject: [PATCH v1 08/13] KVM: selftests: Fix prefault_mem logic
In-Reply-To: <20241204191349.1730936-1-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
Message-ID: <20241204191349.1730936-9-jthoughton@google.com>

The previous logic didn't handle the case where memory was partitioned
AND we were using a single userfaultfd. It would only prefault the first
vCPU's memory and not the rest.

Signed-off-by: James Houghton <jthoughton at google.com>
---
 tools/testing/selftests/kvm/demand_paging_test.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c
index 0202b78f8680..315f5c9037b4 100644
--- a/tools/testing/selftests/kvm/demand_paging_test.c
+++ b/tools/testing/selftests/kvm/demand_paging_test.c
@@ -172,11 +172,13 @@ static void run_test(enum vm_guest_mode mode, void *arg)
 	memset(guest_data_prototype, 0xAB, demand_paging_size);
 
 	if (p->uffd_mode == UFFDIO_REGISTER_MODE_MINOR) {
-		num_uffds = p->single_uffd ? 1 : nr_vcpus;
-		for (i = 0; i < num_uffds; i++) {
+		for (i = 0; i < nr_vcpus; i++) {
 			vcpu_args = &memstress_args.vcpu_args[i];
 			prefault_mem(addr_gpa2alias(vm, vcpu_args->gpa),
 				     vcpu_args->pages * memstress_args.guest_page_size);
+			if (!p->partition_vcpu_memory_access)
+				/* We prefaulted everything */
+				break;
 		}
 	}
 
-- 
2.47.0.338.g60cca15819-goog



From sboyd at kernel.org  Wed Dec  4 12:05:14 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 04 Dec 2024 12:05:14 -0800
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <1jfrn3l615.fsf@starbuckisacylon.baylibre.com>
References: <20241127-clk-audio-fix-rst-missing-v1-1-9f9d0ab98fce@baylibre.com> <306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com> <1jy1131kxz.fsf@starbuckisacylon.baylibre.com> <c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com> <1jplmf1jqa.fsf@starbuckisacylon.baylibre.com> <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com> <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org> <1jr06pkof6.fsf@starbuckisacylon.baylibre.com> <37b656cc8272552ba07c93c5a9a59641.sboyd@kernel.org> <1jfrn3l615.fsf@starbuckisacylon.baylibre.com>
Message-ID: <4e87e30244204b4e71f9b0f630171a40.sboyd@kernel.org>

Quoting Jerome Brunet (2024-12-04 09:19:50)
> On Tue 03 Dec 2024 at 12:15, Stephen Boyd <sboyd at kernel.org> wrote:
> 
> > Quoting Jerome Brunet (2024-12-03 03:15:41)
> >> On Mon 02 Dec 2024 at 18:53, Stephen Boyd <sboyd at kernel.org> wrote:
> >
> > Is the half finished migration a problem for this cycle? I was intending
> > to send the revert later this week and try again next cycle.
> 
> Not really, with the fix you applied. There is just code present in
> reset that should not be used in its current form. I'd prefer to
> sanitise the situation sooner rather than later.

Alright. Let's just sort it out in the next few weeks for the next merge
window then. Maybe you can just do it once then and get auxiliary bus
maintainers to ack the patch so you can merge the helper locally and use
it in the amlogic clk tree.

> >
> > Sure. You can make devm_meson_clk_rst_aux_register() use the same
> > signature as I proposed above so that it's a one line patch later. And
> > definitely drop the imply RESET_MESON and depends on REGMAP part. Maybe
> > you can put it in the clkc-utils file?
> 
> Sure. Few things I'd like to clarify
> 
> * I tend think like Arnd, platform data will be needed eventually. Not
>   sure having 2 functions, one with the param, one without is really
>   worth it. We could just pass NULL when it is not needed. It is not
>   uncommon. Would it be acceptable ? (for the generic helper, the
>   temporary solution does not need that for sure)

I'll defer to the maintainers there. I don't feel strongly.

> 
> * You mean (meson-)clkc-utils.c ? I could but that would add dependency on
>   the auxiliary_bus for clock controllers that don't need it. It is a
>   minor problem really that I could just ignore.
>   I'd rather keep this helper separate if possible.

Ok, no worries.

> 
> * Why drop 'imply RESET_MESON_AUX' ? I would still like the
>   COMMON_CLK_AXG_AUDIO to 'strongly suggest' RESET_MESON_AUX, with
>   dependency problem sorted out.

Because eventually you'll lose this Kconfig. I guess you'll want to add
that to the driver Kconfig option to maintain "strongly suggested".


From SenthilNathan.Thangaraj at amd.com  Wed Dec  4 12:09:51 2024
From: SenthilNathan.Thangaraj at amd.com (Thangaraj, Senthil Nathan)
Date: Wed, 4 Dec 2024 20:09:51 +0000
Subject: [PATCH v2] arm64: zynqmp: add clock-output-names property in
 clock nodes
In-Reply-To: <20241122095712.1166883-1-naman.trivedimanojbhai@amd.com>
References: <20241122095712.1166883-1-naman.trivedimanojbhai@amd.com>
Message-ID: <LV3PR12MB92606EADDE78383521D359B9E2372@LV3PR12MB9260.namprd12.prod.outlook.com>

> -----Original Message-----
> From: Naman Trivedi <naman.trivedimanojbhai at amd.com>
> Sent: Friday, November 22, 2024 1:57 AM
> To: robh at kernel.org; Simek, Michal <michal.simek at amd.com>;
> krzk+dt at kernel.org; conor+dt at kernel.org; devicetree at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; Thangaraj, Senthil Nathan
> <SenthilNathan.Thangaraj at amd.com>
> Cc: linux-kernel at vger.kernel.org
> Subject: [PATCH v2] arm64: zynqmp: add clock-output-names property in clock
> nodes
> 
> Add clock-output-names property to clock nodes, so that the resulting clock name
> do not change when clock node name is changed.
> Also, replace underscores with hyphens in the clock node names as per dt-schema
> rule.
> 
> Signed-off-by: Naman Trivedi <naman.trivedimanojbhai at amd.com>
> ---
> v1: https://lore.kernel.org/all/c5d6effa-bdcf-49e3-a4bf-3713db889b70 at kernel.org
> Changes v1 -> v2:
> - Fix the clock node names by replacing underscore with hyphen.
> ---
>  arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> index 60d1b1acf9a0..385fed8a852a 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> @@ -10,39 +10,44 @@
> 
>  #include <dt-bindings/clock/xlnx-zynqmp-clk.h>
>  / {
> -	pss_ref_clk: pss_ref_clk {
> +	pss_ref_clk: pss-ref-clk {
>  		bootph-all;
>  		compatible = "fixed-clock";
>  		#clock-cells = <0>;
>  		clock-frequency = <33333333>;
> +		clock-output-names = "pss_ref_clk";
>  	};
> 
> -	video_clk: video_clk {
> +	video_clk: video-clk {
>  		bootph-all;
>  		compatible = "fixed-clock";
>  		#clock-cells = <0>;
>  		clock-frequency = <27000000>;
> +		clock-output-names = "video_clk";
>  	};
> 
> -	pss_alt_ref_clk: pss_alt_ref_clk {
> +	pss_alt_ref_clk: pss-alt-ref-clk {
>  		bootph-all;
>  		compatible = "fixed-clock";
>  		#clock-cells = <0>;
>  		clock-frequency = <0>;
> +		clock-output-names = "pss_alt_ref_clk";
>  	};
> 
> -	gt_crx_ref_clk: gt_crx_ref_clk {
> +	gt_crx_ref_clk: gt-crx-ref-clk {
>  		bootph-all;
>  		compatible = "fixed-clock";
>  		#clock-cells = <0>;
>  		clock-frequency = <108000000>;
> +		clock-output-names = "gt_crx_ref_clk";
>  	};
> 
> -	aux_ref_clk: aux_ref_clk {
> +	aux_ref_clk: aux-ref-clk {
>  		bootph-all;
>  		compatible = "fixed-clock";
>  		#clock-cells = <0>;
>  		clock-frequency = <27000000>;
> +		clock-output-names = "aux_ref_clk";
>  	};
>  };
> 
> --
> 2.25.1

Acked-by: Senthil Nathan Thangaraj <senthilnathan.thangaraj at amd.com>

Thanks,
Senthil



From arnd at arndb.de  Wed Dec  4 12:10:24 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 04 Dec 2024 21:10:24 +0100
Subject: [PATCH] clk: amlogic: axg-audio: select RESET_MESON_AUX
In-Reply-To: <1jfrn3l615.fsf@starbuckisacylon.baylibre.com>
References: <20241127-clk-audio-fix-rst-missing-v1-1-9f9d0ab98fce@baylibre.com>
 <f8de4a2a-776f-4c10-b75e-e845bcc38dde@app.fastmail.com>
 <1j4j3r32ld.fsf@starbuckisacylon.baylibre.com>
 <306b0b30-5a32-4c7c-86b4-57d50e2307e8@app.fastmail.com>
 <1jy1131kxz.fsf@starbuckisacylon.baylibre.com>
 <c06317c6-b2b2-4b6d-96e4-0c2cfc6846de@app.fastmail.com>
 <1jplmf1jqa.fsf@starbuckisacylon.baylibre.com>
 <ce67e512-a15b-4482-8194-b917096f4eeb@app.fastmail.com>
 <df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org>
 <1jr06pkof6.fsf@starbuckisacylon.baylibre.com>
 <37b656cc8272552ba07c93c5a9a59641.sboyd@kernel.org>
 <1jfrn3l615.fsf@starbuckisacylon.baylibre.com>
Message-ID: <0241900c-3533-42d1-8dc0-df64181e6aca@app.fastmail.com>

On Wed, Dec 4, 2024, at 18:19, Jerome Brunet wrote:
> On Tue 03 Dec 2024 at 12:15, Stephen Boyd <sboyd at kernel.org> wrote:
>>> 
>>> May I add back the boiler plate code in drivers/clk/meson, similar to
>>> what was proposed in the RFC [1] and propose the generic implementation
>>> in parallel ? It will just be a matter of switching when/if it is approved.
>>
>> Sure. You can make devm_meson_clk_rst_aux_register() use the same
>> signature as I proposed above so that it's a one line patch later. And
>> definitely drop the imply RESET_MESON and depends on REGMAP part. Maybe
>> you can put it in the clkc-utils file?

> * Why drop 'imply RESET_MESON_AUX' ? I would still like the
>   COMMON_CLK_AXG_AUDIO to 'strongly suggest' RESET_MESON_AUX, with
>   dependency problem sorted out.

You can do it the other way round and use 'default
COMMON_CLK_AXG_AUDIO' if you want to tie the two together
with the same effect but avoid the ugly "imply" statement.

I still think it's best to just leave it out. From a user
perspective, the dependency isn't really that the clk
driver needs the reset driver, but instead it's the audio
driver that needs both.

      Arnd


From arnd at arndb.de  Wed Dec  4 12:26:50 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 04 Dec 2024 21:26:50 +0100
Subject: [PATCH 03/15] ARM: rework ARM11 CPU selection logic
In-Reply-To: <CACRpkdYws_rfGPe--xj8d4Gu1pON=_T2sSAoTi3=sMz7wpSFHQ@mail.gmail.com>
References: <20241204102904.1863796-1-arnd@kernel.org>
 <20241204102904.1863796-4-arnd@kernel.org>
 <CACRpkdYws_rfGPe--xj8d4Gu1pON=_T2sSAoTi3=sMz7wpSFHQ@mail.gmail.com>
Message-ID: <7ff7afbe-938f-4eb3-b970-331a177c7348@app.fastmail.com>

On Wed, Dec 4, 2024, at 15:02, Linus Walleij wrote:
> On Wed, Dec 4, 2024 at 11:29?AM Arnd Bergmann <arnd at kernel.org> wrote:
>>
>>  - Eukrea CPUIMX35 reference platform
>>  - Freescale/NXP i.MX35 Product Development Kit
>>  - ARM Integrator/CP/IM-LT3 with ARM1136J Core Tile
>
> I can't test that, I doubt anyone can. I think this support can
> be simply deleted unless there is some QEMU support or
> so.
>
>>  - ARM Realview/EB with ARM1136J Core Tile
>
> I will check if I have this one, otherwise this can probably go
> as well.

To clarify, these two do not add any maintenance burden.
Yes, we can probably remove them, but we can also just
keep them around for as long as i.MX35 is supported. Once
we drop i.MX35 it makes sense to leave only the ARM1176
CPUs supported in ARMv6K and reduce the possible feature
set.

       Arnd


From dan.j.williams at intel.com  Wed Dec  4 13:16:05 2024
From: dan.j.williams at intel.com (Dan Williams)
Date: Wed, 4 Dec 2024 13:16:05 -0800
Subject: [PATCH v7 10/11] virt: arm-cca-guest: TSM_REPORT support for
 realms
In-Reply-To: <20241017131434.40935-11-steven.price@arm.com>
References: <20241017131434.40935-1-steven.price@arm.com>
 <20241017131434.40935-11-steven.price@arm.com>
Message-ID: <6750c695194cd_2508129427@dwillia2-xfh.jf.intel.com.notmuch>

Steven Price wrote:
> From: Sami Mujawar <sami.mujawar at arm.com>
> 
> Introduce an arm-cca-guest driver that registers with
> the configfs-tsm module to provide user interfaces for
> retrieving an attestation token.
> 
> When a new report is requested the arm-cca-guest driver
> invokes the appropriate RSI interfaces to query an
> attestation token.
> 
> The steps to retrieve an attestation token are as follows:
>   1. Mount the configfs filesystem if not already mounted
>      mount -t configfs none /sys/kernel/config
>   2. Generate an attestation token
>      report=/sys/kernel/config/tsm/report/report0
>      mkdir $report
>      dd if=/dev/urandom bs=64 count=1 > $report/inblob
>      hexdump -C $report/outblob
>      rmdir $report
> 
> Signed-off-by: Sami Mujawar <sami.mujawar at arm.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Steven Price <steven.price at arm.com>
> ---
> Changes since v6:
>  * Avoid get_cpu() and instead make the init attestation call using
>    smp_call_function_single(). Improve comments to explain the logic.
>  * Minor code reorgnisation and comment cleanup following Gavin's review
>    (thanks!)
> ---
>  drivers/virt/coco/Kconfig                     |   2 +
>  drivers/virt/coco/Makefile                    |   1 +
>  drivers/virt/coco/arm-cca-guest/Kconfig       |  11 +
>  drivers/virt/coco/arm-cca-guest/Makefile      |   2 +
>  .../virt/coco/arm-cca-guest/arm-cca-guest.c   | 224 ++++++++++++++++++
>  5 files changed, 240 insertions(+)
>  create mode 100644 drivers/virt/coco/arm-cca-guest/Kconfig
>  create mode 100644 drivers/virt/coco/arm-cca-guest/Makefile
>  create mode 100644 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
[..]
> diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/arm-cca-guest/Kconfig
> new file mode 100644
> index 000000000000..9dd27c3ee215
> --- /dev/null
> +++ b/drivers/virt/coco/arm-cca-guest/Kconfig
> @@ -0,0 +1,11 @@
> +config ARM_CCA_GUEST
> +	tristate "Arm CCA Guest driver"
> +	depends on ARM64
> +	default m

I am working on some updates to the TSM_REPORTS interface, rebased them
to test the changes with this driver, and discovered that this driver is
enabled by default.

Just a reminder to please do not mark new drivers as "default m" [1]. In
this case it is difficult to imagine that every arm64 kernel on the
planet needs this functionality enabled by default. In general, someone
should be able to run olddefconfig with a new kernel and not be exposed
to brand new drivers that they have not considered previously.

[1]: http://lore.kernel.org/CA+55aFzxL6-Xp=-mnBwMisZsuKhRZ6zRDJoAmH8W5LDHU2oJuw at mail.gmail.com/


From yury.norov at gmail.com  Wed Dec  4 13:20:39 2024
From: yury.norov at gmail.com (Yury Norov)
Date: Wed, 4 Dec 2024 13:20:39 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
Message-ID: <Z1DHp34fyyhtLEV0@yury-ThinkPad>

> > diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> > index a2a56a50dd85227a4fdc62236a2710ca37c5ba52..30ce06df4153cfdc0fad9bc7bffab9097f8b0450 100644
> > --- a/include/linux/compiler.h
> > +++ b/include/linux/compiler.h
> > @@ -316,6 +316,47 @@ static inline void *offset_to_ptr(const int *off)
> >  #define statically_true(x) (__builtin_constant_p(x) && (x))
> >  #define statically_false(x) (__builtin_constant_p(x) && (x) == 0)
> > 
> > +/*
> > + * Whether x is the integer constant expression 0 or something else.
> > + *
> > + * Details:
> > + *   - The C11 standard defines in ?6.3.2.3.3
> > + *       (void *)<integer constant expression with the value 0>
> > + *     as a null pointer constant (c.f. the NULL macro).
> > + *   - If x evaluates to the integer constant expression 0,
> > + *       (void *)(x)
> > + *     is a null pointer constant. Else, it is a void * expression.
> > + *   - In a ternary expression:
> > + *       condition ? operand1 : operand2
> > + *     if one of the two operands is of type void * and the other one
> > + *     some other pointer type, the C11 standard defines in ?6.5.15.6
> > + *     the resulting type as below:
> > + *       if one operand is a null pointer constant, the result has the
> > + *       type of the other operand; otherwise [...] the result type is
> > + *       a pointer to an appropriately qualified version of void.
> > + *   - As such, in
> > + *       0 ? (void *)(x) : (char *)0
> > + *     if x is the integer constant expression 0, operand1 is a null
> > + *     pointer constant and the resulting type is that of operand2:
> > + *     char *. If x is anything else, the type is void *.
> > + *   - The (long) cast silences a compiler warning for when x is not 0.
> > + *   - Finally, the _Generic() dispatches the resulting type into a
> > + *     Boolean.
> 
> The comment is absolutely excessive.

I like this comment. Particularly I like the references to the standard
followed by a step-by-step explanation of how the macro is built.

> I'm sure I managed about 2 lines in one of the patches I did.

Sorry, don't understand this.

Thanks,
Yury

> > + *
> > + * Glory to Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
> 
> IIRC Martin has agreed in the past that the accreditation can
> be removed - especially since it refers to the 'sizeof (void)' trick.
> 
> > + */
> > +#define __is_const_zero(x) \
> > +	_Generic(0 ? (void *)(long)(x) : (char *)0, char *: 1, void *: 0)
> > +
> > +/*
> > + * Returns a constant expression while determining if its argument is a
> > + * constant expression, most importantly without evaluating the argument.
> 
> You need to differentiate between a 'constant integer expression'
> and a 'compile time constant'.
>  
> > + *
> > + * If getting a constant expression is not relevant to you, use the more
> > + * powerful __builtin_constant_p() instead.
> 
> __builtin_constant_p() is not 'more powerful' it is testing for
> something different.
> 
> 	David
> 
> > + */
> > +#define is_const(x) __is_const_zero(0 * (x))
> > +
> >  /*
> >   * This is needed in functions which generate the stack canary, see
> >   * arch/x86/kernel/smpboot.c::start_secondary() for an example.
> > 
> > --
> > 2.45.2
> > 
> 
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)


From oliver.upton at linux.dev  Wed Dec  4 13:56:58 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 4 Dec 2024 13:56:58 -0800
Subject: [RFC PATCH 05/14] KVM: arm64: Always allow fixed cycle counter
In-Reply-To: <87ikrzstt1.wl-maz@kernel.org>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
 <20241203193220.1070811-6-oliver.upton@linux.dev>
 <87ldwwsbad.wl-maz@kernel.org>
 <Z0-HBsBgf6WB7x4R@linux.dev>
 <87ikrzstt1.wl-maz@kernel.org>
Message-ID: <Z1DQKg02tebLmGsO@linux.dev>

On Wed, Dec 04, 2024 at 09:04:26AM +0000, Marc Zyngier wrote:
> On Tue, 03 Dec 2024 22:32:38 +0000,
> Oliver Upton <oliver.upton at linux.dev> wrote:
> > > More importantly, the current filtering works in terms of events, and
> > > not in terms of counters.
> > > 
> > > Instead of changing the ABI, how about simply not supporting filtering
> > > on such non-compliant HW? Surely that would simplify a few things.
> > 
> > Yeah, that sounds reasonable. Especially if we allow programmable event
> > counters where the event ID space doesn't match the architecture.
> 
> Another thing I have been wondering is if a slightly better approach
> would be to move some of the handling to the PMU driver itself, and
> let it emulate PMUv3 if it can. This would allow conversion of event
> numbers in situ rather than polluting the PMUv3 code in KVM.

Sure, but I think the actual event fed into perf_event_create_kernel_counter()
should be the correct hardware event, not a PMUv3 event reinterpreted
behind the scenes. Otherwise, we'd need to devise an alternate config encoding
for PMUv3-like events since the event ID spaces overlap.

I'm thinking this could be a helper in the arm_pmu struct that takes a
PMUv3 event and spits out (in this case) an M1 event. The resulting KVM
code would be miniscule, like:

u64 kvm_map_pmu_event(struct kvm *kvm, u64 eventsel)
{
	struct arm_pmu *pmu = kvm->arch.arm_pmu;

	if (!pmu->map_pmuv3_event)
		return eventsel;

	return pmu->map_pmuv3_event(eventsel);
}

static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc)
{

	[...]

	attr.config = kvm_map_pmu_event(vcpu->kvm, eventsel);
	event = perf_event_create_kernel_counter(&attr, ...);
}

We could even have the M1 PMU driver populate arm_pmu->pmceid_bitmap
with the events it knows about and get PMCEID emulation for free.

-- 
Thanks,
Oliver


From quic_molvera at quicinc.com  Wed Dec  4 14:27:25 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 4 Dec 2024 14:27:25 -0800
Subject: [PATCH RESEND v2] dt-bindings: arm-smmu: Document SM8750 SMMU
Message-ID: <20241204-sm8750_master_smmu-v2-1-9e73e3fc15f2@quicinc.com>

Document the SM8750 SMMU block.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
---
Resending since I forgot to include linux-arm-msm.

Changes in V2:
- added additional documentation for gpu and clocks
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index c1e11bc6b7a054e6e839b4cff356231170d95093..e4e067a2b778e3b9ed30bbb973b50b2b86ddd2f1 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -61,6 +61,7 @@ properties:
               - qcom,sm8450-smmu-500
               - qcom,sm8550-smmu-500
               - qcom,sm8650-smmu-500
+              - qcom,sm8750-smmu-500
               - qcom,x1e80100-smmu-500
           - const: qcom,smmu-500
           - const: arm,mmu-500
@@ -102,6 +103,7 @@ properties:
               - qcom,sm8450-smmu-500
               - qcom,sm8550-smmu-500
               - qcom,sm8650-smmu-500
+              - qcom,sm8750-smmu-500
               - qcom,x1e80100-smmu-500
           - const: qcom,adreno-smmu
           - const: qcom,smmu-500
@@ -550,6 +552,23 @@ allOf:
             - description: GPU SNoC bus clock
             - description: GPU AHB clock
 
+  - if:
+      properties:
+        compatible:
+          items:
+            - const: qcom,sm8750-smmu-500
+            - const: qcom,adreno-smmu
+            - const: qcom,smmu-500
+            - const: arm,mmu-500
+    then:
+      properties:
+        clock-names:
+          items:
+            - const: hlos
+        clocks:
+          items:
+            - description: HLOS vote clock
+
   # Disallow clocks for all other platforms with specific compatibles
   - if:
       properties:

---
base-commit: bcf2acd8f64b0a5783deeeb5fd70c6163ec5acd7
change-id: 20241204-sm8750_master_smmu-0867ab939686

Best regards,
-- 
Melody Olvera <quic_molvera at quicinc.com>



From Frank.li at nxp.com  Wed Dec  4 14:58:28 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 4 Dec 2024 17:58:28 -0500
Subject: [PATCH 06/11] irqchip/imx-mu-msi: Convert to
 msi_create_parent_irq_domain() helper
In-Reply-To: <20241204124549.607054-7-maz@kernel.org>
References: <20241204124549.607054-1-maz@kernel.org>
 <20241204124549.607054-7-maz@kernel.org>
Message-ID: <Z1DelMq8m7eG9SA2@lizhi-Precision-Tower-5810>

On Wed, Dec 04, 2024 at 12:45:44PM +0000, Marc Zyngier wrote:
> Now that we have a concise helper to create an MSI parent domain,
> switch the IMX letter soup over to that.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>  drivers/irqchip/irq-imx-mu-msi.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c
> index b3f656c6e7708..b73968423bb9f 100644
> --- a/drivers/irqchip/irq-imx-mu-msi.c
> +++ b/drivers/irqchip/irq-imx-mu-msi.c
> @@ -226,17 +226,15 @@ static int imx_mu_msi_domains_init(struct imx_mu_msi *msi_data, struct device *d
>  	struct irq_domain *parent;
>
>  	/* Initialize MSI domain parent */
> -	parent = irq_domain_create_linear(fwnodes, IMX_MU_CHANS,
> -					  &imx_mu_msi_domain_ops, msi_data);
> +	parent = msi_create_parent_irq_domain(fwnodes, &imx_mu_msi_parent_ops,
> +					      &imx_mu_msi_domain_ops, 0,
> +					      IMX_MU_CHANS, msi_data, NULL);
>  	if (!parent) {
>  		dev_err(dev, "failed to create IRQ domain\n");
>  		return -ENOMEM;
>  	}
>
> -	irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS);
>  	parent->dev = parent->pm_dev = dev;
> -	parent->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
> -	parent->msi_parent_ops = &imx_mu_msi_parent_ops;
>  	return 0;
>  }
>
> --
> 2.39.2
>


From oliver.upton at linux.dev  Wed Dec  4 15:07:27 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 4 Dec 2024 15:07:27 -0800
Subject: [PATCH v1 06/13] KVM: arm64: Add support for KVM_MEM_USERFAULT
In-Reply-To: <20241204191349.1730936-7-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
 <20241204191349.1730936-7-jthoughton@google.com>
Message-ID: <Z1Dgr_TnaFQT04Pi@linux.dev>

Hi James,

On Wed, Dec 04, 2024 at 07:13:41PM +0000, James Houghton wrote:
> Adhering to the requirements of KVM Userfault:
> 
> 1. When it is toggled (either on or off), zap the second stage with
>    kvm_arch_flush_shadow_memslot(). This is to (1) respect
>    userfault-ness and (2) to reconstruct block mappings.
> 2. While KVM_MEM_USERFAULT is enabled, restrict new second-stage mappings
>    to be PAGE_SIZE, just like when dirty logging is enabled.
> 
> Signed-off-by: James Houghton <jthoughton at google.com>
> ---
>   I'm not 100% sure if kvm_arch_flush_shadow_memslot() is correct in
>   this case (like if the host does not have S2FWB).

Invalidating the stage-2 entries is of course necessary for correctness
on the !USERFAULT -> USERFAULT transition, and the MMU will do the right
thing regardless of whether hardware implements FEAT_S2FWB.

What I think you may be getting at is the *performance* implications are
quite worrying without FEAT_S2FWB due to the storm of CMOs, and I'd
definitely agree with that.

> @@ -2062,6 +2069,20 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
>  				   enum kvm_mr_change change)
>  {
>  	bool log_dirty_pages = new && new->flags & KVM_MEM_LOG_DIRTY_PAGES;
> +	u32 changed_flags = (new ? new->flags : 0) ^ (old ? old->flags : 0);
> +
> +	/*
> +	 * If KVM_MEM_USERFAULT changed, drop all the stage-2 mappings so that
> +	 * we can (1) respect userfault-ness or (2) create block mappings.
> +	 */
> +	if ((changed_flags & KVM_MEM_USERFAULT) && change == KVM_MR_FLAGS_ONLY)
> +		kvm_arch_flush_shadow_memslot(kvm, old);

I'd strongly prefer that we make (2) a userspace problem and don't
eagerly invalidate stage-2 mappings on the USERFAULT -> !USERFAULT
change.

Having implied user-visible behaviors on ioctls is never good, and for
systems without FEAT_S2FWB you might be better off avoiding the unmap in
the first place.

So, if userspace decides there's a benefit to invalidating the stage-2
MMU, it can just delete + recreate the memslot.

-- 
Thanks,
Oliver


From dmitry.baryshkov at linaro.org  Wed Dec  4 15:14:43 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Dec 2024 01:14:43 +0200
Subject: [PATCH v2 3/3] drm: remove driver date from struct drm_driver
 and all drivers
In-Reply-To: <1f2bf2543aed270a06f6c707fd6ed1b78bf16712.1733322525.git.jani.nikula@intel.com>
References: <cover.1733322525.git.jani.nikula@intel.com>
 <1f2bf2543aed270a06f6c707fd6ed1b78bf16712.1733322525.git.jani.nikula@intel.com>
Message-ID: <couqmlshll3v6vgziqnt6sq7caf4nart42ljo5fbim3rg7ec5o@3ym66tyaytd2>

On Wed, Dec 04, 2024 at 04:31:12PM +0200, Jani Nikula wrote:
> We stopped using the driver initialized date in commit 7fb8af6798e8
> ("drm: deprecate driver date") and (eventually) started returning "0"
> for drm_version ioctl instead.
> 
> Finish the job, and remove the unused date member from struct
> drm_driver, its initialization from drivers, along with the common
> DRIVER_DATE macros.
> 
> v2: Also update drivers/accel (kernel test robot)
> 
> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com>
> Acked-by: Alex Deucher <alexander.deucher at amd.com>
> Acked-by: Simon Ser <contact at emersion.fr>
> Acked-by: Jeffrey Hugo <quic_jhugo at quicinc.com>
> Signed-off-by: Jani Nikula <jani.nikula at intel.com>

Acked-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org> # msm

> 
> ---

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Wed Dec  4 15:17:39 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Dec 2024 01:17:39 +0200
Subject: [PATCH v5 7/9] drm/bridge_connector: hook
 drm_atomic_helper_connector_hdmi_update_edid()
In-Reply-To: <87v7vz3ne4.fsf@intel.com>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-7-b5316e82f61a@linaro.org>
 <87a5dc4zd5.fsf@intel.com>
 <txzri7x4pdeakx4juandk3hfhsbx3dhlulxfuehqlmrr7b3wpw@jaunqktsro6x>
 <87v7vz3ne4.fsf@intel.com>
Message-ID: <3oz2k3ywwdkxhi4t4setfqjl54yzxg3nxe7upxwl4syyyygf42@3ynkabu2bmvs>

On Wed, Dec 04, 2024 at 09:42:11AM +0200, Jani Nikula wrote:
> On Wed, 04 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> > On Tue, Dec 03, 2024 at 04:25:58PM +0200, Jani Nikula wrote:
> >> On Sun, 01 Dec 2024, Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> >> > +	drm_edid = drm_bridge_edid_read(bridge, connector);
> >> > +	if (!drm_edid_valid(drm_edid)) {
> >> 
> >> What's the case this check is for?
> >> 
> >> My preference would be that bridge->funcs->edid_read() uses
> >> drm_edid_read*() family of functions that do the checks and return the
> >> EDID.
> >> 
> >> There are some cases that just allocate a blob and return it. Would be
> >> nice if they could be converted, but in the mean time could use
> >> drm_edid_valid() right there. Additional validity checks are redundant.
> >
> > This was c&p from drm_bridge_connector_get_modes_edid(). If you think
> > that the check is redundant, could you please send a patch dropping the
> > check?
> 
> Mmmh. It's just scary to *remove* them, and that's the reason I didn't
> want you to add one in the first place! :)

Ack

-- 
With best wishes
Dmitry


From quic_molvera at quicinc.com  Wed Dec  4 15:18:02 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 4 Dec 2024 15:18:02 -0800
Subject: [PATCH v3 2/7] arm64: dts: qcom: Add PMD8028 PMIC
In-Reply-To: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
Message-ID: <20241204-sm8750_master_dt-v3-2-4d5a8269950b@quicinc.com>

Add descriptions of PMD8028 PMIC used on SM8750 platforms.

Signed-off-by: Jishnu Prakash <quic_jprakash at quicinc.com>
Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
---
 arch/arm64/boot/dts/qcom/pmd8028.dtsi | 62 +++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pmd8028.dtsi b/arch/arm64/boot/dts/qcom/pmd8028.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..a00913e28a4ca94d04d8a195ae8a868e9dd2fea4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pmd8028.dtsi
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+	thermal-zones {
+		pmd8028-thermal {
+			polling-delay-passive = <100>;
+			thermal-sensors = <&pmd8028_temp_alarm>;
+
+			trips {
+				pmd8028_trip0: trip0 {
+					temperature = <95000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				pmd8028_trip1: trip1 {
+					temperature = <115000>;
+					hysteresis = <0>;
+					type = "hot";
+				};
+
+				pmd8028_trip2: trip2 {
+					temperature = <145000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+	};
+};
+
+&spmi_bus {
+	pmd8028: pmic at 4 {
+		compatible = "qcom,pmd8028", "qcom,spmi-pmic";
+		reg = <0x4 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmd8028_temp_alarm: temp-alarm at a00 {
+			compatible = "qcom,spmi-temp-alarm";
+			reg = <0xa00>;
+			interrupts = <0x4 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		pmd8028_gpios: gpio at 8800 {
+			compatible = "qcom,pmd8028-gpio", "qcom,spmi-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pmd8028_gpios 0 0 4>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+};

-- 
2.46.1



From quic_molvera at quicinc.com  Wed Dec  4 15:18:03 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 4 Dec 2024 15:18:03 -0800
Subject: [PATCH v3 3/7] arm64: dts: qcom: Add PMIH0108 PMIC
In-Reply-To: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
Message-ID: <20241204-sm8750_master_dt-v3-3-4d5a8269950b@quicinc.com>

Add descriptions of PMIH0108 PMIC used on SM8750 platforms.

Signed-off-by: Jishnu Prakash <quic_jprakash at quicinc.com>
Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
---
 arch/arm64/boot/dts/qcom/pmih0108.dtsi | 68 ++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pmih0108.dtsi b/arch/arm64/boot/dts/qcom/pmih0108.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..1c875995d8813900795b6d68e5528a6f88850fd4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pmih0108.dtsi
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+	thermal-zones {
+		pmih0108-thermal {
+			polling-delay-passive = <100>;
+			thermal-sensors = <&pmih0108_temp_alarm>;
+
+			trips {
+				trip0 {
+					temperature = <95000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <115000>;
+					hysteresis = <0>;
+					type = "hot";
+				};
+
+				trip2 {
+					temperature = <145000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+	};
+};
+
+&spmi_bus {
+	pmih0108: pmic at 7 {
+		compatible = "qcom,pmih0108", "qcom,spmi-pmic";
+		reg = <0x7 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmih0108_temp_alarm: temp-alarm at a00 {
+			compatible = "qcom,spmi-temp-alarm";
+			reg = <0xa00>;
+			interrupts = <0x7 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		pmih0108_gpios: gpio at 8800 {
+			compatible = "qcom,pmih0108-gpio", "qcom,spmi-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pmih0108_gpios 0 0 18>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pmih0108_eusb2_repeater: phy at fd00 {
+			compatible = "qcom,pm8550b-eusb2-repeater";
+			reg = <0xfd00>;
+			#phy-cells = <0>;
+		};
+	};
+};

-- 
2.46.1



From quic_molvera at quicinc.com  Wed Dec  4 15:18:05 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 4 Dec 2024 15:18:05 -0800
Subject: [PATCH v3 5/7] arm64: dts: qcom: sm8750: Add pmic dtsi
In-Reply-To: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
Message-ID: <20241204-sm8750_master_dt-v3-5-4d5a8269950b@quicinc.com>

Add pmic dtsi file for SM8750 SoC describing the pmics and
their thermal zones.

Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sm8750-pmics.dtsi | 188 +++++++++++++++++++++++++++++
 1 file changed, 188 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8750-pmics.dtsi b/arch/arm64/boot/dts/qcom/sm8750-pmics.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..6eb8d78937c3f2907a352616ec3170a3c0973e5d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8750-pmics.dtsi
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/ {
+	thermal-zones {
+		pm8550ve-d-thermal {
+			polling-delay-passive = <100>;
+
+			thermal-sensors = <&pm8550ve_d_temp_alarm>;
+
+			trips {
+				trip0 {
+					temperature = <95000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <115000>;
+					hysteresis = <0>;
+					type = "hot";
+				};
+			};
+		};
+
+		pm8550ve-f-thermal {
+			polling-delay-passive = <100>;
+
+			thermal-sensors = <&pm8550ve_f_temp_alarm>;
+
+			trips {
+				trip0 {
+					temperature = <95000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <115000>;
+					hysteresis = <0>;
+					type = "hot";
+				};
+			};
+		};
+
+		pm8550ve-g-thermal {
+			polling-delay-passive = <100>;
+
+			thermal-sensors = <&pm8550ve_g_temp_alarm>;
+
+			trips {
+				trip0 {
+					temperature = <95000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <115000>;
+					hysteresis = <0>;
+					type = "hot";
+				};
+			};
+		};
+
+		pm8550vs-j-thermal {
+			polling-delay-passive = <100>;
+
+			thermal-sensors = <&pm8550vs_j_temp_alarm>;
+
+			trips {
+				trip0 {
+					temperature = <95000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <115000>;
+					hysteresis = <0>;
+					type = "hot";
+				};
+			};
+		};
+	};
+};
+
+&spmi_bus {
+	/* PM8550VE */
+	pm8550ve_d: pmic at 3 {
+		compatible = "qcom,pm8550ve", "qcom,spmi-pmic";
+		reg = <0x3 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pm8550ve_d_temp_alarm: temp-alarm at a00 {
+			compatible = "qcom,spmi-temp-alarm";
+			reg = <0xa00>;
+			interrupts = <0x3 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		pm8550ve_d_gpios: gpio at 8800 {
+			compatible = "qcom,pm8550ve-gpio", "qcom,spmi-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pm8550ve_d_gpios 0 0 8>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pm8550ve_f: pmic at 5 {
+		compatible = "qcom,pm8550ve", "qcom,spmi-pmic";
+		reg = <0x5 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pm8550ve_f_temp_alarm: temp-alarm at a00 {
+			compatible = "qcom,spmi-temp-alarm";
+			reg = <0xa00>;
+			interrupts = <0x5 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		pm8550ve_f_gpios: gpio at 8800 {
+			compatible = "qcom,pm8550ve-gpio", "qcom,spmi-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pm8550ve_f_gpios 0 0 6>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pm8550ve_g: pmic at 6 {
+		compatible = "qcom,pm8550ve", "qcom,spmi-pmic";
+		reg = <0x6 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pm8550ve_g_temp_alarm: temp-alarm at a00 {
+			compatible = "qcom,spmi-temp-alarm";
+			reg = <0xa00>;
+			interrupts = <0x6 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		pm8550ve_g_gpios: gpio at 8800 {
+			compatible = "qcom,pm8550ve-gpio", "qcom,spmi-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pm8550ve_g_gpios 0 0 8>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	/* PM8550VS */
+	pm8550vs_j: pmic at 9 {
+		compatible = "qcom,pm8550vs", "qcom,spmi-pmic";
+		reg = <0x9 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pm8550vs_j_temp_alarm: temp-alarm at a00 {
+			compatible = "qcom,spmi-temp-alarm";
+			reg = <0xa00>;
+			interrupts = <0x9 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		pm8550vs_j_gpios: gpio at 8800 {
+			compatible = "qcom,pm8550vs-gpio", "qcom,spmi-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pm8550vs_j_gpios 0 0 6>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+};

-- 
2.46.1



From quic_molvera at quicinc.com  Wed Dec  4 15:18:07 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 4 Dec 2024 15:18:07 -0800
Subject: [PATCH v3 7/7] arm64: defconfig: Enable SM8750 SoC base configs
In-Reply-To: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
Message-ID: <20241204-sm8750_master_dt-v3-7-4d5a8269950b@quicinc.com>

Enable GCC, TCSRCC, Pinctrl and Interconnect configs for Qualcomm's
SM8750 SoC which is required to boot SM8750 MTP/QRD boards to a
console shell. The configs are required to be marked as builtin
and not modules due to the console driver dependencies.

Co-developed-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
Signed-off-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski 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 6beb0b5efd2e693b826d4a3106d4c4b4582d1927..b7a039f3d763b5723cb21810a649281c24b0f2f1 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -630,6 +630,7 @@ CONFIG_PINCTRL_SM8350=y
 CONFIG_PINCTRL_SM8450=y
 CONFIG_PINCTRL_SM8550=y
 CONFIG_PINCTRL_SM8650=y
+CONFIG_PINCTRL_SM8750=y
 CONFIG_PINCTRL_X1E80100=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_PINCTRL_LPASS_LPI=m
@@ -1361,6 +1362,7 @@ CONFIG_SM_GCC_8350=y
 CONFIG_SM_GCC_8450=y
 CONFIG_SM_GCC_8550=y
 CONFIG_SM_GCC_8650=y
+CONFIG_SM_GCC_8750=y
 CONFIG_SM_GPUCC_6115=m
 CONFIG_SM_GPUCC_8150=y
 CONFIG_SM_GPUCC_8250=y
@@ -1370,6 +1372,7 @@ CONFIG_SM_GPUCC_8550=m
 CONFIG_SM_GPUCC_8650=m
 CONFIG_SM_TCSRCC_8550=y
 CONFIG_SM_TCSRCC_8650=y
+CONFIG_SM_TCSRCC_8750=y
 CONFIG_SM_VIDEOCC_8250=y
 CONFIG_QCOM_HFPLL=y
 CONFIG_CLK_GFM_LPASS_SM8250=m
@@ -1650,6 +1653,7 @@ CONFIG_INTERCONNECT_QCOM_SM8350=y
 CONFIG_INTERCONNECT_QCOM_SM8450=y
 CONFIG_INTERCONNECT_QCOM_SM8550=y
 CONFIG_INTERCONNECT_QCOM_SM8650=y
+CONFIG_INTERCONNECT_QCOM_SM8750=y
 CONFIG_INTERCONNECT_QCOM_X1E80100=y
 CONFIG_COUNTER=m
 CONFIG_RZ_MTU3_CNT=m

-- 
2.46.1



From quic_molvera at quicinc.com  Wed Dec  4 15:18:06 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 4 Dec 2024 15:18:06 -0800
Subject: [PATCH v3 6/7] arm64: dts: qcom: Add board dts files for SM8750
 MTP and QRD
In-Reply-To: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
Message-ID: <20241204-sm8750_master_dt-v3-6-4d5a8269950b@quicinc.com>

Add MTP and QRD dts files for SM8750 describing board clocks, regulators,
gpio keys, etc.

Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
---
 arch/arm64/boot/dts/qcom/Makefile       |   2 +
 arch/arm64/boot/dts/qcom/sm8750-mtp.dts | 794 ++++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/qcom/sm8750-qrd.dts | 792 +++++++++++++++++++++++++++++++
 3 files changed, 1588 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 4686f2a8ddd897227360b4de48a0618499ad463e..28a8ef1099997b071635ef229735beaf47ef979a 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -283,6 +283,8 @@ dtb-$(CONFIG_ARCH_QCOM)	+= sm8650-hdk-display-card.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8650-hdk.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8650-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8650-qrd.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sm8750-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sm8750-qrd.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= x1e001de-devkit.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= x1e78100-lenovo-thinkpad-t14s.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= x1e80100-asus-vivobook-s15.dtb
diff --git a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts
new file mode 100644
index 0000000000000000000000000000000000000000..9e3aacad7bdab6848e86f8e45e04907e1c752a07
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts
@@ -0,0 +1,794 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sm8750.dtsi"
+#include "pm8010.dtsi"
+#include "pm8550.dtsi"
+#define PMK8550VE_SID 8
+#include "pm8550ve.dtsi"
+#include "pmd8028.dtsi"
+#include "pmih0108.dtsi"
+#include "pmk8550.dtsi"
+#include "pmr735d_a.dtsi"
+#include "sm8750-pmics.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SM8750 MTP";
+	compatible = "qcom,sm8750-mtp", "qcom,sm8750";
+	chassis-type = "handset";
+
+
+	aliases {
+		serial0 = &uart7;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	clocks {
+		xo_board: xo-board {
+			compatible = "fixed-clock";
+			clock-frequency = <76800000>;
+			#clock-cells = <0>;
+		};
+
+		sleep_clk: sleep-clk {
+			compatible = "fixed-clock";
+			clock-frequency = <32000>;
+			#clock-cells = <0>;
+		};
+
+		bi_tcxo_div2: bi-tcxo-div2-clk {
+			compatible = "fixed-factor-clock";
+			#clock-cells = <0>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-mult = <1>;
+			clock-div = <2>;
+		};
+
+		bi_tcxo_ao_div2: bi-tcxo-ao-div2-clk {
+			compatible = "fixed-factor-clock";
+			#clock-cells = <0>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK_A>;
+			clock-mult = <1>;
+			clock-div = <2>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&volume_up_n>;
+		pinctrl-names = "default";
+
+		key-volume-up {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			wakeup-source;
+		};
+	};
+
+	vph_pwr: vph-pwr-regulator {
+		compatible = "regulator-fixed";
+
+		regulator-name = "vph_pwr";
+		regulator-min-microvolt = <3700000>;
+		regulator-max-microvolt = <3700000>;
+
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pm8550-rpmh-regulators";
+
+		vdd-bob1-supply = <&vph_pwr>;
+		vdd-bob2-supply = <&vph_pwr>;
+		vdd-l1-l4-l10-supply = <&vreg_s3g_1p8>;
+		vdd-l2-l13-l14-supply = <&vreg_bob1>;
+		vdd-l3-supply = <&vreg_s7i_1p2>;
+		vdd-l5-l16-supply = <&vreg_bob1>;
+		vdd-l6-l7-supply = <&vreg_bob1>;
+		vdd-l8-l9-supply = <&vreg_bob1>;
+		vdd-l11-supply = <&vreg_s7i_1p2>;
+		vdd-l12-supply = <&vreg_s3g_1p8>;
+		vdd-l15-supply = <&vreg_s3g_1p8>;
+		vdd-l17-supply = <&vreg_bob2>;
+
+		qcom,pmic-id = "b";
+
+		vreg_bob1: bob1 {
+			regulator-name = "vreg_bob1";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <4000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_bob2: bob2 {
+			regulator-name = "vreg_bob2";
+			regulator-min-microvolt = <2704000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1b_1p8: ldo1 {
+			regulator-name = "vreg_l1b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2b_3p0: ldo2 {
+			regulator-name = "vreg_l2b_3p0";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <3048000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4b_1p8: ldo4 {
+			regulator-name = "vreg_l4b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5b_3p1: ldo5 {
+			regulator-name = "vreg_l5b_3p1";
+			regulator-min-microvolt = <3100000>;
+			regulator-max-microvolt = <3148000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6b_1p8: ldo6 {
+			regulator-name = "vreg_l6b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7b_1p8: ldo7 {
+			regulator-name = "vreg_l7b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+
+		};
+
+		vreg_l8b_1p8: ldo8 {
+			regulator-name = "vreg_l8b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9b_2p9: ldo9 {
+			regulator-name = "vreg_l9b_2p9";
+			regulator-min-microvolt = <2960000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l10b_1p8: ldo10 {
+			regulator-name = "vreg_l10b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11b_1p0: ldo11 {
+			regulator-name = "vreg_l11b_1p0";
+			regulator-min-microvolt = <1064000>;
+			regulator-max-microvolt = <1292000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l12b_1p8: ldo12 {
+			regulator-name = "vreg_l12b_1p8";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l13b_3p0: ldo13 {
+			regulator-name = "vreg_l13b_3p0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l14b_3p2: ldo14 {
+			regulator-name = "vreg_l14b_3p2";
+			regulator-min-microvolt = <3200000>;
+			regulator-max-microvolt = <3200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l15b_1p8: ldo15 {
+			regulator-name = "vreg_l15b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l16b_2p8: ldo16 {
+			regulator-name = "vreg_l16b_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l17b_2p5: ldo17 {
+			regulator-name = "vreg_l17b_2p5";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2504000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s7i_1p2>;
+		vdd-l2-supply = <&vreg_s1d_0p97>;
+		vdd-l3-supply = <&vreg_s1d_0p97>;
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+		vdd-s4-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "d";
+
+		vreg_s1d_0p97: smps1 {
+			regulator-name = "vreg_s1d_0p97";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3d_1p2: smps3 {
+			regulator-name = "vreg_s3d_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4d_0p85: smps4 {
+			regulator-name = "vreg_s4d_0p85";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1036000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1d_1p2: ldo1 {
+			regulator-name = "vreg_l1d_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2d_0p88: ldo2 {
+			regulator-name = "vreg_l2d_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3d_0p88: ldo3 {
+			regulator-name = "vreg_l3d_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-2 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s1d_0p97>;
+		vdd-l2-supply = <&vreg_s7i_1p2>;
+		vdd-l3-supply = <&vreg_s3g_1p8>;
+		vdd-s5-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "f";
+
+		vreg_s5f_0p5: smps5 {
+			regulator-name = "vreg_s5f_0p5";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1f_0p88: ldo1 {
+			regulator-name = "vreg_l1f_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2f_1p2: ldo2 {
+			regulator-name = "vreg_l2f_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3f_1p8: ldo3 {
+			regulator-name = "vreg_l3f_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+	};
+
+	regulators-3 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s1d_0p97>;
+		vdd-l2-supply = <&vreg_s3g_1p8>;
+		vdd-l3-supply = <&vreg_s7i_1p2>;
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "g";
+
+		vreg_s1g_0p5: smps1 {
+			regulator-name = "vreg_s1g_0p5";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <700000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3g_1p8: smps3 {
+			regulator-name = "vreg_s3g_1p8";
+			regulator-min-microvolt = <1856000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4g_0p75: smps4 {
+			regulator-name = "vreg_s4g_0p75";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <900000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1g_0p91: ldo1 {
+			regulator-name = "vreg_l1g_0p91";
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <936000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2g_1p8: ldo2 {
+			regulator-name = "vreg_l2g_1p8";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1860000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3g_1p2: ldo3 {
+			regulator-name = "vreg_l3g_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1256000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-4 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s7i_1p2>;
+		vdd-l2-supply = <&vreg_s7i_1p2>;
+		vdd-l3-supply = <&vreg_s1d_0p97>;
+		vdd-s7-supply = <&vph_pwr>;
+		vdd-s8-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "i";
+
+		vreg_s7i_1p2: smps7 {
+			regulator-name = "vreg_s7i_1p2";
+			regulator-min-microvolt = <1224000>;
+			regulator-max-microvolt = <1340000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s8i_0p9: smps8 {
+			regulator-name = "vreg_s8i_0p9";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <972000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1i_1p2: ldo1 {
+			regulator-name = "vreg_l1i_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2i_1p2: ldo2 {
+			regulator-name = "vreg_l2i_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3i_0p88: ldo3 {
+			regulator-name = "vreg_l3i_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-5 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s1d_0p97>;
+		vdd-l2-supply = <&vreg_s7i_1p2>;
+		vdd-s2-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+		vdd-s4-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "j";
+
+		vreg_s2j_1p1: smps2 {
+			regulator-name = "vreg_s2j_1p1";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3j_1p1: smps3 {
+			regulator-name = "vreg_s3j_1p1";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1j_0p91: ldo1 {
+			regulator-name = "vreg_l1j_0p91";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2j_1p2: ldo2 {
+			regulator-name = "vreg_l2j_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-6 {
+		compatible = "qcom,pm8010-rpmh-regulators";
+		qcom,pmic-id = "m";
+
+		vdd-l1-l2-supply = <&vreg_s7i_1p2>;
+		vdd-l3-l4-supply = <&vreg_bob2>;
+		vdd-l5-supply = <&vreg_s3g_1p8>;
+		vdd-l6-supply = <&vreg_bob1>;
+		vdd-l7-supply = <&vreg_bob1>;
+
+		vreg_l1m_1p1: ldo1 {
+			regulator-name = "vreg_l1m_1p1";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2m_1p056: ldo2 {
+			regulator-name = "vreg_l2m_1p056";
+			regulator-min-microvolt = <1056000>;
+			regulator-max-microvolt = <1056000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3m_2p8: ldo3 {
+			regulator-name = "vreg_l3m_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4m_2p8: ldo4 {
+			regulator-name = "vreg_l4m_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5m_1p8: ldo5 {
+			regulator-name = "vreg_l5m_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6m_2p8: ldo6 {
+			regulator-name = "vreg_l6m_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7m_2p96: ldo7 {
+			regulator-name = "vreg_l7m_2p96";
+			regulator-min-microvolt = <2960000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-7 {
+		compatible = "qcom,pm8010-rpmh-regulators";
+		qcom,pmic-id = "n";
+
+		vdd-l1-l2-supply = <&vreg_s7i_1p2>;
+		vdd-l3-l4-supply = <&vreg_s3g_1p8>;
+		vdd-l5-supply = <&vreg_bob2>;
+		vdd-l6-supply = <&vreg_bob2>;
+		vdd-l7-supply = <&vreg_bob1>;
+
+		vreg_l1n_1p1: ldo1 {
+			regulator-name = "vreg_l1n_1p1";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2n_1p1: ldo2 {
+			regulator-name = "vreg_l2n_1p1";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3n_1p8: ldo3 {
+			regulator-name = "vreg_l3n_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4n_1p8: ldo4 {
+			regulator-name = "vreg_l4n_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5n_2p8: ldo5 {
+			regulator-name = "vreg_l5n_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6n_2p8: ldo6 {
+			regulator-name = "vreg_l6n_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7n_3p3: ldo7 {
+			regulator-name = "vreg_l7n_3p3";
+			regulator-min-microvolt = <3304000>;
+			regulator-max-microvolt = <3304000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&pm8550_flash {
+	status = "okay";
+
+	led-0 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_YELLOW>;
+		led-sources = <1>, <4>;
+		led-max-microamp = <500000>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <0>;
+	};
+
+	led-1 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_WHITE>;
+		led-sources = <2>, <3>;
+		led-max-microamp = <500000>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <1>;
+	};
+};
+
+&pm8550_gpios {
+	volume_up_n: volume-up-n-state {
+		pins = "gpio6";
+		function = "normal";
+		bias-pull-up;
+		input-enable;
+		power-source = <1>;
+	};
+};
+
+&pm8550_pwm {
+	status = "okay";
+
+	multi-led {
+		color = <LED_COLOR_ID_RGB>;
+		function = LED_FUNCTION_STATUS;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		led at 1 {
+			reg = <1>;
+			color = <LED_COLOR_ID_RED>;
+		};
+
+		led at 2 {
+			reg = <2>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led at 3 {
+			reg = <3>;
+			color = <LED_COLOR_ID_BLUE>;
+		};
+	};
+};
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+
+	status = "okay";
+};
+
+&pmih0108_eusb2_repeater {
+	status = "okay";
+
+	vdd18-supply = <&vreg_l15b_1p8>;
+	vdd3-supply = <&vreg_l5b_3p1>;
+};
+
+&qupv3_1 {
+	status = "okay";
+};
+
+&tlmm {
+	/* reserved for secure world */
+	gpio-reserved-ranges = <36 4>, <74 1>;
+};
+
+&uart7 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts
new file mode 100644
index 0000000000000000000000000000000000000000..f77efab0aef9bab751a947173bcdcc27df7295a8
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts
@@ -0,0 +1,792 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sm8750.dtsi"
+#include "pm8010.dtsi"
+#include "pm8550.dtsi"
+#define PMK8550VE_SID 8
+#include "pm8550ve.dtsi"
+#include "pmd8028.dtsi"
+#include "pmih0108.dtsi"
+#include "pmk8550.dtsi"
+#include "pmr735d_a.dtsi"
+#include "sm8750-pmics.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SM8750 QRD";
+	compatible = "qcom,sm8750-qrd", "qcom,sm8750";
+	chassis-type = "handset";
+
+	aliases {
+		serial0 = &uart7;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	clocks {
+		xo_board: xo-board {
+			compatible = "fixed-clock";
+			clock-frequency = <76800000>;
+			#clock-cells = <0>;
+		};
+
+		sleep_clk: sleep-clk {
+			compatible = "fixed-clock";
+			clock-frequency = <32000>;
+			#clock-cells = <0>;
+		};
+
+		bi_tcxo_div2: bi-tcxo-div2-clk {
+			compatible = "fixed-factor-clock";
+			#clock-cells = <0>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-mult = <1>;
+			clock-div = <2>;
+		};
+
+		bi_tcxo_ao_div2: bi-tcxo-ao-div2-clk {
+			compatible = "fixed-factor-clock";
+			#clock-cells = <0>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK_A>;
+			clock-mult = <1>;
+			clock-div = <2>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&volume_up_n>;
+		pinctrl-names = "default";
+
+		key-volume-up {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			wakeup-source;
+		};
+	};
+
+	vph_pwr: vph-pwr-regulator {
+		compatible = "regulator-fixed";
+
+		regulator-name = "vph_pwr";
+		regulator-min-microvolt = <3700000>;
+		regulator-max-microvolt = <3700000>;
+
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pm8550-rpmh-regulators";
+
+		vdd-bob1-supply = <&vph_pwr>;
+		vdd-bob2-supply = <&vph_pwr>;
+		vdd-l1-l4-l10-supply = <&vreg_s3g_1p8>;
+		vdd-l2-l13-l14-supply = <&vreg_bob1>;
+		vdd-l3-supply = <&vreg_s7i_1p2>;
+		vdd-l5-l16-supply = <&vreg_bob1>;
+		vdd-l6-l7-supply = <&vreg_bob1>;
+		vdd-l8-l9-supply = <&vreg_bob1>;
+		vdd-l11-supply = <&vreg_s7i_1p2>;
+		vdd-l12-supply = <&vreg_s3g_1p8>;
+		vdd-l15-supply = <&vreg_s3g_1p8>;
+		vdd-l17-supply = <&vreg_bob2>;
+
+		qcom,pmic-id = "b";
+
+		vreg_bob1: bob1 {
+			regulator-name = "vreg_bob1";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <4000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_bob2: bob2 {
+			regulator-name = "vreg_bob2";
+			regulator-min-microvolt = <2704000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1b_1p8: ldo1 {
+			regulator-name = "vreg_l1b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2b_3p0: ldo2 {
+			regulator-name = "vreg_l2b_3p0";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <3048000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4b_1p8: ldo4 {
+			regulator-name = "vreg_l4b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5b_3p1: ldo5 {
+			regulator-name = "vreg_l5b_3p1";
+			regulator-min-microvolt = <3100000>;
+			regulator-max-microvolt = <3148000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6b_1p8: ldo6 {
+			regulator-name = "vreg_l6b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7b_1p8: ldo7 {
+			regulator-name = "vreg_l7b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8b_1p8: ldo8 {
+			regulator-name = "vreg_l8b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9b_2p9: ldo9 {
+			regulator-name = "vreg_l9b_2p9";
+			regulator-min-microvolt = <2960000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l10b_1p8: ldo10 {
+			regulator-name = "vreg_l10b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11b_1p0: ldo11 {
+			regulator-name = "vreg_l11b_1p0";
+			regulator-min-microvolt = <1064000>;
+			regulator-max-microvolt = <1292000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l12b_1p8: ldo12 {
+			regulator-name = "vreg_l12b_1p8";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l13b_3p0: ldo13 {
+			regulator-name = "vreg_l13b_3p0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l14b_3p2: ldo14 {
+			regulator-name = "vreg_l14b_3p2";
+			regulator-min-microvolt = <3200000>;
+			regulator-max-microvolt = <3200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l15b_1p8: ldo15 {
+			regulator-name = "vreg_l15b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l16b_2p8: ldo16 {
+			regulator-name = "vreg_l16b_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l17b_2p5: ldo17 {
+			regulator-name = "vreg_l17b_2p5";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2504000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s7i_1p2>;
+		vdd-l2-supply = <&vreg_s1d_0p97>;
+		vdd-l3-supply = <&vreg_s1d_0p97>;
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+		vdd-s4-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "d";
+
+		vreg_s1d_0p97: smps1 {
+			regulator-name = "vreg_s1d_0p97";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3d_1p2: smps3 {
+			regulator-name = "vreg_s3d_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4d_0p85: smps4 {
+			regulator-name = "vreg_s4d_0p85";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1036000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1d_1p2: ldo1 {
+			regulator-name = "vreg_l1d_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2d_0p88: ldo2 {
+			regulator-name = "vreg_l2d_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3d_0p88: ldo3 {
+			regulator-name = "vreg_l3d_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-2 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s1d_0p97>;
+		vdd-l2-supply = <&vreg_s7i_1p2>;
+		vdd-l3-supply = <&vreg_s3g_1p8>;
+		vdd-s5-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "f";
+
+		vreg_s5f_0p5: smps5 {
+			regulator-name = "vreg_s5f_0p5";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1f_0p88: ldo1 {
+			regulator-name = "vreg_l1f_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2f_1p2: ldo2 {
+			regulator-name = "vreg_l2f_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3f_1p8: ldo3 {
+			regulator-name = "vreg_l3f_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+	};
+
+	regulators-3 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s1d_0p97>;
+		vdd-l2-supply = <&vreg_s3g_1p8>;
+		vdd-l3-supply = <&vreg_s7i_1p2>;
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "g";
+
+		vreg_s1g_0p5: smps1 {
+			regulator-name = "vreg_s1g_0p5";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <700000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3g_1p8: smps3 {
+			regulator-name = "vreg_s3g_1p8";
+			regulator-min-microvolt = <1856000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4g_0p75: smps4 {
+			regulator-name = "vreg_s4g_0p75";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <900000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1g_0p91: ldo1 {
+			regulator-name = "vreg_l1g_0p91";
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <936000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2g_1p8: ldo2 {
+			regulator-name = "vreg_l2g_1p8";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1860000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3g_1p2: ldo3 {
+			regulator-name = "vreg_l3g_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1256000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-4 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s7i_1p2>;
+		vdd-l2-supply = <&vreg_s7i_1p2>;
+		vdd-l3-supply = <&vreg_s1d_0p97>;
+		vdd-s7-supply = <&vph_pwr>;
+		vdd-s8-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "i";
+
+		vreg_s7i_1p2: smps7 {
+			regulator-name = "vreg_s7i_1p2";
+			regulator-min-microvolt = <1224000>;
+			regulator-max-microvolt = <1340000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s8i_0p9: smps8 {
+			regulator-name = "vreg_s8i_0p9";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <972000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1i_1p2: ldo1 {
+			regulator-name = "vreg_l1i_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2i_1p2: ldo2 {
+			regulator-name = "vreg_l2i_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3i_0p88: ldo3 {
+			regulator-name = "vreg_l3i_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-5 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s1d_0p97>;
+		vdd-l2-supply = <&vreg_s7i_1p2>;
+		vdd-s2-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "j";
+
+		vreg_s2j_1p1: smps2 {
+			regulator-name = "vreg_s2j_1p1";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3j_1p1: smps3 {
+			regulator-name = "vreg_s3j_1p1";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+
+		vreg_l1j_0p91: ldo1 {
+			regulator-name = "vreg_l1j_0p91";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2j_1p2: ldo2 {
+			regulator-name = "vreg_l2j_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-6 {
+		compatible = "qcom,pm8010-rpmh-regulators";
+		qcom,pmic-id = "m";
+
+		vdd-l1-l2-supply = <&vreg_s7i_1p2>;
+		vdd-l3-l4-supply = <&vreg_s3g_1p8>;
+		vdd-l5-supply = <&vreg_s3g_1p8>;
+		vdd-l6-supply = <&vreg_bob1>;
+		vdd-l7-supply = <&vreg_bob1>;
+
+		vreg_l1m_1p1: ldo1 {
+			regulator-name = "vreg_l1m_1p1";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2m_1p056: ldo2 {
+			regulator-name = "vreg_l2m_1p056";
+			regulator-min-microvolt = <1056000>;
+			regulator-max-microvolt = <1056000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3m_2p8: ldo3 {
+			regulator-name = "vreg_l3m_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4m_2p8: ldo4 {
+			regulator-name = "vreg_l4m_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5m_1p8: ldo5 {
+			regulator-name = "vreg_l5m_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6m_2p8: ldo6 {
+			regulator-name = "vreg_l6m_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7m_2p96: ldo7 {
+			regulator-name = "vreg_l7m_2p96";
+			regulator-min-microvolt = <2960000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-7 {
+		compatible = "qcom,pm8010-rpmh-regulators";
+		qcom,pmic-id = "n";
+
+		vdd-l1-l2-supply = <&vreg_s7i_1p2>;
+		vdd-l3-l4-supply = <&vreg_s7i_1p2>;
+		vdd-l5-supply = <&vreg_bob2>;
+		vdd-l6-supply = <&vreg_bob2>;
+		vdd-l7-supply = <&vreg_bob1>;
+
+		vreg_l1n_1p1: ldo1 {
+			regulator-name = "vreg_l1n_1p1";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2n_1p1: ldo2 {
+			regulator-name = "vreg_l2n_1p1";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3n_1p8: ldo3 {
+			regulator-name = "vreg_l3n_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4n_1p8: ldo4 {
+			regulator-name = "vreg_l4n_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5n_2p8: ldo5 {
+			regulator-name = "vreg_l5n_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6n_2p8: ldo6 {
+			regulator-name = "vreg_l6n_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7n_3p3: ldo7 {
+			regulator-name = "vreg_l7n_3p3";
+			regulator-min-microvolt = <3304000>;
+			regulator-max-microvolt = <3304000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&pm8550_flash {
+	status = "okay";
+
+	led-0 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_YELLOW>;
+		led-sources = <1>, <4>;
+		led-max-microamp = <500000>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <0>;
+	};
+
+	led-1 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_WHITE>;
+		led-sources = <2>, <3>;
+		led-max-microamp = <500000>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <1>;
+	};
+};
+
+&pm8550_gpios {
+	volume_up_n: volume-up-n-state {
+		pins = "gpio6";
+		function = "normal";
+		bias-pull-up;
+		input-enable;
+		power-source = <1>;
+	};
+};
+
+&pm8550_pwm {
+	status = "okay";
+
+	multi-led {
+		color = <LED_COLOR_ID_RGB>;
+		function = LED_FUNCTION_STATUS;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		led at 1 {
+			reg = <1>;
+			color = <LED_COLOR_ID_RED>;
+		};
+
+		led at 2 {
+			reg = <2>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led at 3 {
+			reg = <3>;
+			color = <LED_COLOR_ID_BLUE>;
+		};
+	};
+};
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+
+	status = "okay";
+};
+
+&pmih0108_eusb2_repeater {
+	status = "okay";
+
+	vdd18-supply = <&vreg_l15b_1p8>;
+	vdd3-supply = <&vreg_l5b_3p1>;
+};
+
+&qupv3_1 {
+	status = "okay";
+};
+
+&tlmm {
+	/* reserved for secure world */
+	gpio-reserved-ranges = <36 4>, <74 1>;
+};
+
+&uart7 {
+	status = "okay";
+};

-- 
2.46.1



From quic_molvera at quicinc.com  Wed Dec  4 15:18:04 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 4 Dec 2024 15:18:04 -0800
Subject: [PATCH v3 4/7] arm64: dts: qcom: Add base SM8750 dtsi
In-Reply-To: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
Message-ID: <20241204-sm8750_master_dt-v3-4-4d5a8269950b@quicinc.com>

Add the base dtsi for the SM8750 SoC describing the CPUs, GCC and
RPMHCC clock controllers, geni UART, interrupt controller, TLMM,
reserved memory, interconnects, and SMMU.

Co-developed-by: Taniya Das <quic_tdas at quicinc.com>
Signed-off-by: Taniya Das <quic_tdas at quicinc.com>
Co-developed-by: Jishnu Prakash <quic_jprakash at quicinc.com>
Signed-off-by: Jishnu Prakash <quic_jprakash at quicinc.com>
Co-developed-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
Signed-off-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sm8750.dtsi | 2907 ++++++++++++++++++++++++++++++++++
 1 file changed, 2907 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..3bbd7d18598ee0a3a0d5130c03a3166e1fc14d82
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
@@ -0,0 +1,2907 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/clock/qcom,sm8750-gcc.h>
+#include <dt-bindings/clock/qcom,sm8750-tcsr.h>
+#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/interconnect/qcom,sm8750-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom,rpmhpd.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+
+/ {
+	interrupt-parent = <&intc>;
+
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "qcom,oryon";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			next-level-cache = <&l2_0>;
+			power-domains = <&cpu_pd0>;
+			power-domain-names = "psci";
+
+			l2_0: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+			};
+		};
+
+		cpu1: cpu at 100 {
+			device_type = "cpu";
+			compatible = "qcom,oryon";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			next-level-cache = <&l2_0>;
+			power-domains = <&cpu_pd1>;
+			power-domain-names = "psci";
+		};
+
+		cpu2: cpu at 200 {
+			device_type = "cpu";
+			compatible = "qcom,oryon";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			next-level-cache = <&l2_0>;
+			power-domains = <&cpu_pd2>;
+			power-domain-names = "psci";
+		};
+
+		cpu3: cpu at 300 {
+			device_type = "cpu";
+			compatible = "qcom,oryon";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			next-level-cache = <&l2_0>;
+			power-domains = <&cpu_pd3>;
+			power-domain-names = "psci";
+		};
+
+		cpu4: cpu at 400 {
+			device_type = "cpu";
+			compatible = "qcom,oryon";
+			reg = <0x0 0x400>;
+			enable-method = "psci";
+			next-level-cache = <&l2_0>;
+			power-domains = <&cpu_pd4>;
+			power-domain-names = "psci";
+		};
+
+		cpu5: cpu at 500 {
+			device_type = "cpu";
+			compatible = "qcom,oryon";
+			reg = <0x0 0x500>;
+			enable-method = "psci";
+			next-level-cache = <&l2_0>;
+			power-domains = <&cpu_pd5>;
+			power-domain-names = "psci";
+		};
+
+		cpu6: cpu at 10000 {
+			device_type = "cpu";
+			compatible = "qcom,oryon";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			next-level-cache = <&L2_1>;
+			power-domains = <&cpu_pd6>;
+			power-domain-names = "psci";
+
+			L2_1: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+			};
+		};
+
+		cpu7: cpu at 10100 {
+			device_type = "cpu";
+			compatible = "qcom,oryon";
+			reg = <0x0 0x10100>;
+			enable-method = "psci";
+			next-level-cache = <&L2_1>;
+			power-domains = <&cpu_pd7>;
+			power-domain-names = "psci";
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+
+				core4 {
+					cpu = <&cpu4>;
+				};
+
+				core5 {
+					cpu = <&cpu5>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu6>;
+				};
+
+				core1 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			cluster0_c4: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "ret";
+				arm,psci-suspend-param = <0x00000004>;
+				entry-latency-us = <93>;
+				exit-latency-us = <129>;
+				min-residency-us = <560>;
+			};
+
+			cluster1_c4: cpu-sleep-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "ret";
+				arm,psci-suspend-param = <0x00000004>;
+				entry-latency-us = <172>;
+				exit-latency-us = <130>;
+				min-residency-us = <686>;
+			};
+
+		};
+
+		domain-idle-states {
+			cluster_cl5: cluster-sleep-0 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x01000054>;
+				entry-latency-us = <2150>;
+				exit-latency-us = <1983>;
+				min-residency-us = <9144>;
+			};
+
+			domain_ss3: domain-sleep-0 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x0200c354>;
+				entry-latency-us = <2800>;
+				exit-latency-us = <4400>;
+				min-residency-us = <10150>;
+			};
+		};
+	};
+
+	firmware {
+		scm: scm {
+			compatible = "qcom,scm-sm8750", "qcom,scm";
+			interconnects = <&aggre2_noc MASTER_CRYPTO QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+		};
+	};
+
+	clk_virt: interconnect-0 {
+		compatible = "qcom,sm8750-clk-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	mc_virt: interconnect-1 {
+		compatible = "qcom,sm8750-mc-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	memory at a0000000 {
+		device_type = "memory";
+		/* We expect the bootloader to fill in the size */
+		reg = <0x0 0xa0000000 0x0 0x0>;
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+
+		cpu_pd0: power-domain-cpu0 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&cluster0_c4>;
+		};
+
+		cpu_pd1: power-domain-cpu1 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&cluster0_c4>;
+		};
+
+		cpu_pd2: power-domain-cpu2 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&cluster0_c4>;
+		};
+
+		cpu_pd3: power-domain-cpu3 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&cluster0_c4>;
+		};
+
+		cpu_pd4: power-domain-cpu4 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&cluster0_c4>;
+		};
+
+		cpu_pd5: power-domain-cpu5 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&cluster0_c4>;
+		};
+
+		cpu_pd6: power-domain-cpu6 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&cluster1_c4>;
+		};
+
+		cpu_pd7: power-domain-cpu7 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&cluster1_c4>;
+		};
+
+		cluster_pd: power-domain-cluster {
+			#power-domain-cells = <0>;
+			domain-idle-states = <&cluster_cl5>;
+			power-domains = <&system_pd>;
+		};
+
+		system_pd: power-domain-system {
+			#power-domain-cells = <0>;
+			domain-idle-states = <&domain_ss3>;
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gunyah_hyp_mem: gunyah-hyp at 80000000 {
+			reg = <0x0 0x80000000 0x0 0xe00000>;
+			no-map;
+		};
+
+		cpusys_vm_mem: cpusys-vm-mem at 80e00000 {
+			reg = <0x0 0x80e00000 0x0 0x40000>;
+			no-map;
+		};
+
+		cpucp_mem: cpucp at 81200000 {
+			reg = <0x0 0x81200000 0x0 0x200000>;
+			no-map;
+		};
+
+		xbl_dtlog_mem: xbl-dtlog at 81a00000 {
+			reg = <0x0 0x81a00000 0x0 0x40000>;
+			no-map;
+		};
+
+		aop_image_mem: aop-image at 81c00000 {
+			reg = <0x0 0x81c00000 0x0 0x60000>;
+			no-map;
+		};
+
+		aop_cmd_db_mem: aop-cmd-db at 81c60000 {
+			compatible = "qcom,cmd-db";
+			reg = <0x0 0x81c60000 0x0 0x20000>;
+			no-map;
+		};
+
+		/* Merged aop_config, tme_crash_dump, tme_log and uefi_log regions */
+		aop_tme_uefi_merged_mem: aop-tme-uefi-merged at 81c80000 {
+			reg = <0x0 0x81c80000 0x0 0x74000>;
+			no-map;
+		};
+
+		/* Secdata region can be reused by apps */
+
+		smem_mem: smem at 81d00000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x81d00000 0x0 0x200000>;
+			hwlocks = <&tcsr_mutex 3>;
+			no-map;
+		};
+
+		pdp_ns_shared_mem: pdp-ns-shared at 81f00000 {
+			reg = <0x0 0x81f00000 0x0 0x100000>;
+			no-map;
+		};
+
+		cpucp_scandump_mem: cpucp-scandump at 82000000 {
+			reg = <0x0 0x82000000 0x0 0x380000>;
+			no-map;
+		};
+
+		adsp_mhi_mem: adsp-mhi at 82380000 {
+			reg = <0x0 0x82380000 0x0 0x20000>;
+			no-map;
+		};
+
+		soccp_sdi_mem: soccp-sdi at 823a0000 {
+			reg = <0x0 0x823a0000 0x0 0x40000>;
+			no-map;
+		};
+
+		pmic_minii_dump_mem: pmic-minii-dump at 823e0000 {
+			reg = <0x0 0x823e0000 0x0 0x80000>;
+			no-map;
+		};
+
+		pvmfw_mem: pvmfw at 824a0000 {
+			reg = <0x0 0x824a0000 0x0 0x100000>;
+			no-map;
+		};
+
+		global_sync_mem: global-sync at 82600000 {
+			reg = <0x0 0x82600000 0x0 0x100000>;
+			no-map;
+		};
+
+		tz_stat_mem: tz-stat at 82700000 {
+			reg = <0x0 0x82700000 0x0 0x100000>;
+			no-map;
+		};
+
+		qdss_mem: qdss at 82800000 {
+			reg = <0x0 0x82800000 0x0 0x2000000>;
+			no-map;
+		};
+
+		dsm_partition_1_mem: dsm-partition-1 at 84a00000 {
+			reg = <0x0 0x84a00000 0x0 0x4900000>;
+			no-map;
+		};
+
+		dsm_partition_2_mem: dsm-partition-2 at 89300000 {
+			reg = <0x0 0x89300000 0x0 0xa80000>;
+			no-map;
+		};
+
+		mpss_mem: mpss at 8ba00000 {
+			reg = <0x0 0x8ba00000 0x0 0xf600000>;
+			no-map;
+		};
+
+		q6_mpss_dtb_mem: q6-mpss-dtb at 9b000000 {
+			reg = <0x0 0x9b000000 0x0 0x80000>;
+			no-map;
+		};
+
+		ipa_fw_mem: ipa-fw at 9b080000 {
+			reg = <0x0 0x9b080000 0x0 0x10000>;
+			no-map;
+		};
+
+		ipa_gsi_mem: ipa-gsi at 9b090000 {
+			reg = <0x0 0x9b090000 0x0 0xa000>;
+			no-map;
+		};
+
+		gpu_micro_code_mem: gpu-micro-code at 9b09a000 {
+			reg = <0x0 0x9b09a000 0x0 0x2000>;
+			no-map;
+		};
+
+		spss_region_mem: spss at 9b0a0000  {
+			reg = <0x0 0x9b0a0000 0x0 0x1e0000>;
+			no-map;
+		};
+
+		/* First part of the "SPU secure shared memory" region */
+		spu_tz_shared_mem: spu-tz-shared at 9b280000 {
+			reg = <0x0 0x9b280000 0x0 0x40000>;
+			no-map;
+		};
+
+		/* Second part of the "SPU secure shared memory" region */
+		spu_modem_shared_mem: spu-modem-shared at 9b2c0000 {
+			reg = <0x0 0x9b2c0000 0x0 0x40000>;
+			no-map;
+		};
+
+		camera_mem: camera at 9b300000 {
+			reg = <0x0 0x9b300000 0x0 0x800000>;
+			no-map;
+		};
+
+		camera_2_mem: camera-2 at 9bb00000 {
+			reg = <0x0 0x9bb00000 0x0 0x800000>;
+			no-map;
+		};
+
+		video_mem: video at 9c300000 {
+			reg = <0x0 0x9c300000 0x0 0x800000>;
+			no-map;
+		};
+
+		cvp_mem: cvp at 9cb00000 {
+			reg = <0x0 0x9cb00000 0x0 0x700000>;
+			no-map;
+		};
+
+		cdsp_mem: cdsp at 9d200000 {
+			reg = <0x0 0x9d200000 0x0 0x1900000>;
+			no-map;
+		};
+
+		q6_cdsp_dtb_mem: q6-cdsp-dtb at 9eb00000 {
+			reg = <0x0 0x9eb00000 0x0 0x80000>;
+			no-map;
+		};
+
+		soccp_mem: soccp at 9ec00000 {
+			reg = <0x0 0x9ec00000 0x0 0x180000>;
+			no-map;
+		};
+
+		q6_adsp_dtb_mem: q6-adsp-dtb at 9ed80000 {
+			reg = <0x0 0x9ed80000 0x0 0x80000>;
+			no-map;
+		};
+
+		adspslpi_mem: adspslpi at 9ee00000 {
+			reg = <0x0 0x9ee00000 0x0 0x3a80000>;
+			no-map;
+		};
+
+		xbl_ramdump_mem: xbl-ramdump at b8000000 {
+			reg = <0x0 0xb8000000 0x0 0x1c0000>;
+			no-map;
+		};
+
+		hwfence_shbuf: hwfence-shbuf at d4e23000 {
+			no-map;
+			reg = <0x0 0xd4e23000 0x0 0x2dd000>;
+		};
+
+		/* Merged tz_reserved, xbl_sc, and qtee regions */
+		tz_merged_mem: tz-merged at d8000000 {
+			reg = <0x0 0xd8000000 0x0 0x600000>;
+			no-map;
+		};
+
+		trust_ui_vm_mem: trust-ui-vm at f3800000 {
+			reg = <0x0 0xf3800000 0x0 0x4400000>;
+			no-map;
+		};
+
+		oem_vm_mem: oem-vm at f7c00000 {
+			reg = <0x0 0xf7c00000 0x0 0x4c00000>;
+			no-map;
+		};
+
+		llcc_lpi_mem: llcc-lpi at ff800000 {
+			reg = <0x0 0xff800000 0x0 0x800000>;
+			no-map;
+		};
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dma-ranges = <0 0 0 0 0x10 0>;
+		ranges = <0 0 0 0 0x10 0>;
+
+		gcc: clock-controller at 100000 {
+			compatible = "qcom,sm8750-gcc";
+			reg = <0x0 0x00100000 0x0 0x1f4200>;
+
+			clocks = <&bi_tcxo_div2>,
+				 <0>,
+				 <&sleep_clk>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>;
+
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		gpi_dma2: dma-controller at 800000 {
+			compatible = "qcom,sm8750-gpi-dma", "qcom,sm6350-gpi-dma";
+			reg = <0x0 0x00800000 0x0 0x60000>;
+
+			interrupts = <GIC_SPI 588 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 589 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 590 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 591 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 592 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 594 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 595 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 596 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 597 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 598 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 599 IRQ_TYPE_LEVEL_HIGH>;
+
+			dma-channels = <12>;
+			dma-channel-mask = <0x1e>;
+			#dma-cells = <3>;
+
+			iommus = <&apps_smmu 0x436 0x0>;
+
+			status = "disabled";
+		};
+
+		qupv3_2: geniqup at 8c0000 {
+			compatible = "qcom,geni-se-qup";
+			reg = <0x0 0x008c0000 0x0 0x2000>;
+
+			clocks = <&gcc GCC_QUPV3_WRAP_2_M_AHB_CLK>,
+				 <&gcc GCC_QUPV3_WRAP_2_S_AHB_CLK>;
+			clock-names = "m-ahb",
+				      "s-ahb";
+
+			iommus = <&apps_smmu 0x423 0x0>;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			status = "disabled";
+
+			i2c8: i2c at 880000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00880000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c8_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi8: spi at 880000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00880000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi8_data_clk>, <&qup_spi8_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c9: i2c at 884000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00884000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 1 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c9_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi9: spi at 884000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00884000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 1 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi9_data_clk>, <&qup_spi9_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c10: i2c at 888000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00888000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 2 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c10_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi10: spi at 888000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00888000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 2 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi10_data_clk>, <&qup_spi10_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c11: i2c at 88c000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x0088c000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 3 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c11_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi11: spi at 88c000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x0088c000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 3 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi11_data_clk>, <&qup_spi11_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c12: i2c at 890000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00890000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 4 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c12_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi12: spi at 890000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00890000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 4 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 4 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi12_data_clk>, <&qup_spi12_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c13: i2c at 894000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00894000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 5 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 5 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c13_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi13: spi at 894000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00894000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 5 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi13_data_clk>, <&qup_spi13_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			uart14: serial at 898000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00898000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
+				clock-names = "se";
+
+				interconnects =	<&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&qup_uart14_default>;
+				pinctrl-names = "default";
+
+				status = "disabled";
+			};
+
+			i2c15: i2c at 89c000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x0089c000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S7_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 7 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 7 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c15_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi15: spi at 89c000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x0089c000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP2_S7_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma2 0 7 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 7 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi15_data_clk>, <&qup_spi15_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+		};
+
+		i2c_master_hub_0: geniqup at 9c0000 {
+			compatible = "qcom,geni-se-i2c-master-hub";
+			reg = <0x0 0x009c0000 0x0 0x2000>;
+
+			clocks = <&gcc GCC_QUPV3_I2C_S_AHB_CLK>;
+			clock-names = "s-ahb";
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			status = "disabled";
+
+			i2c_hub_0: i2c at 980000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x00980000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S0_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c0_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c_hub_1: i2c at 984000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x00984000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S1_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c1_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c_hub_2: i2c at 988000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x00988000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S2_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c2_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c_hub_3: i2c at 98c000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x0098c000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S3_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c3_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c_hub_4: i2c at 990000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x00990000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S4_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c4_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c_hub_5: i2c at 994000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x00994000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S5_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c5_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c_hub_6: i2c at 998000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x00998000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S6_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c6_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c_hub_7: i2c at 99c000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x0099c000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S7_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c7_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c_hub_8: i2c at 9a0000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x009a0000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S8_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c8_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c_hub_9: i2c at 9a4000 {
+				compatible = "qcom,geni-i2c-master-hub";
+				reg = <0x0 0x009a4000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_I2C_S9_CLK>,
+					 <&gcc GCC_QUPV3_I2C_CORE_CLK>;
+				clock-names = "se",
+					      "core";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+				pinctrl-0 = <&hub_i2c9_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+		};
+
+		gpi_dma1: dma-controller at a00000 {
+			compatible = "qcom,sm8750-gpi-dma", "qcom,sm6350-gpi-dma";
+			reg = <0x0 0x00a00000 0x0 0x60000>;
+
+			interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 294 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 295 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>;
+
+			dma-channels = <12>;
+			dma-channel-mask = <0x1e>;
+			#dma-cells = <3>;
+
+			iommus = <&apps_smmu 0xb6 0x0>;
+
+			status = "disabled";
+		};
+
+		qupv3_1: geniqup at ac0000 {
+			compatible = "qcom,geni-se-qup";
+			reg = <0x0 0x00ac0000 0x0 0x2000>;
+
+			clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>,
+				 <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>;
+			clock-names = "m-ahb",
+				      "s-ahb";
+
+			iommus = <&apps_smmu 0xa3 0x0>;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			status = "disabled";
+
+			i2c0: i2c at a80000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00a80000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c0_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi0: spi at a80000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00a80000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi0_data_clk>, <&qup_spi0_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c1: i2c at a84000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00a84000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 1 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c1_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi1: spi at a84000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00a84000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 1 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi1_data_clk>, <&qup_spi1_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c2: i2c at a88000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00a88000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 2 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c2_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi2: spi at a88000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00a88000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 2 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi2_data_clk>, <&qup_spi2_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c3: i2c at a8c000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00a8c000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 3 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c3_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi3: spi at a8c000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00a8c000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 3 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi3_data_clk>, <&qup_spi3_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c4: i2c at a90000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00a90000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 4 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c4_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi4: spi at a90000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00a90000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 4 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi4_data_clk>, <&qup_spi4_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c5: i2c at a94000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00a94000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 5 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c5_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi5: spi at a94000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00a94000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 5 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi5_data_clk>, <&qup_spi5_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			i2c6: i2c at a98000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x00a98000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 6 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_i2c6_data_clk>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			spi6: spi at a98000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00a98000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+
+				dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 6 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+
+				pinctrl-0 = <&qup_spi6_data_clk>, <&qup_spi6_cs>;
+				pinctrl-names = "default";
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+			};
+
+			uart7: serial at a9c000 {
+				compatible = "qcom,geni-debug-uart";
+				reg = <0x0 0x00a9c000 0x0 0x4000>;
+
+				interrupts = <GIC_SPI 579 IRQ_TYPE_LEVEL_HIGH>;
+
+				clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>;
+				clock-names = "se";
+
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+
+
+				pinctrl-0 = <&qup_uart7_default>;
+				pinctrl-names = "default";
+
+				status = "disabled";
+			};
+		};
+
+		cnoc_main: interconnect at 1500000 {
+			compatible = "qcom,sm8750-cnoc-main";
+			reg = <0x0 0x01500000 0x0 0x16080>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+		};
+
+		config_noc: interconnect at 1600000 {
+			compatible = "qcom,sm8750-config-noc";
+			reg = <0x0 0x01600000 0x0 0x6200>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+		};
+
+		system_noc: interconnect at 1680000 {
+			compatible = "qcom,sm8750-system-noc";
+			reg = <0x0 0x01680000 0x0 0x1d080>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+		};
+
+		pcie_noc: interconnect at 16c0000 {
+			compatible = "qcom,sm8750-pcie-anoc";
+			reg = <0x0 0x016c0000 0x0 0x11400>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+			clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>;
+
+		};
+
+		aggre1_noc: interconnect at 16e0000 {
+			compatible = "qcom,sm8750-aggre1-noc";
+			reg = <0x0 0x016e0000 0x0 0x16400>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+			clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>;
+
+		};
+
+		aggre2_noc: interconnect at 1700000 {
+			compatible = "qcom,sm8750-aggre2-noc";
+			reg = <0x0 0x01700000 0x0 0x1f400>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+			clocks = <&rpmhcc RPMH_IPA_CLK>;
+		};
+
+		mmss_noc: interconnect at 1780000 {
+			compatible = "qcom,sm8750-mmss-noc";
+			reg = <0x0 0x01780000 0x0 0x5b800>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+		};
+
+		tcsr_mutex: hwlock at 1f40000 {
+			compatible = "qcom,tcsr-mutex";
+			reg = <0x0 0x01f40000 0x0 0x20000>;
+			#hwlock-cells = <1>;
+		};
+
+		lpass_ag_noc: interconnect at 7e40000 {
+			compatible = "qcom,sm8750-lpass-ag-noc";
+			reg = <0x0 0x07e40000 0x0 0xe080>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+		};
+
+		lpass_lpiaon_noc: interconnect at 7400000 {
+			compatible = "qcom,sm8750-lpass-lpiaon-noc";
+			reg = <0x0 0x07400000 0x0 0x19080>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+		};
+
+		lpass_lpicx_noc: interconnect at 7420000 {
+			compatible = "qcom,sm8750-lpass-lpicx-noc";
+			reg = <0x0 0x07420000 0x0 0x44080>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+		};
+
+		pdc: interrupt-controller at b220000 {
+			compatible = "qcom,sm8750-pdc", "qcom,pdc";
+			reg = <0x0 0x0b220000 0x0 0x10000>, <0x0 0x164400f0 0x0 0x64>;
+
+			qcom,pdc-ranges = <0 745 51>, <51 527 47>,
+					  <98 609 32>, <130 717 12>,
+					  <142 251 5>, <147 796 16>;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&intc>;
+			interrupt-controller;
+		};
+
+		spmi_bus: spmi at c400000 {
+			compatible = "qcom,spmi-pmic-arb";
+			reg = <0x0 0x0c400000 0x0 0x3000>,
+			      <0x0 0x0c500000 0x0 0x400000>,
+			      <0x0 0x0c440000 0x0 0x80000>,
+			      <0x0 0x0c4c0000 0x0 0x10000>,
+			      <0x0 0x0c42d000 0x0 0x4000>;
+			reg-names = "core",
+				    "chnls",
+				    "obsrvr",
+				    "intr",
+				    "cnfg";
+
+			interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "periph_irq";
+
+			qcom,ee = <0>;
+			qcom,channel = <0>;
+			qcom,bus-id = <0>;
+
+			interrupt-controller;
+			#interrupt-cells = <4>;
+
+			#address-cells = <2>;
+			#size-cells = <0>;
+		};
+
+		tlmm: pinctrl at f100000 {
+			compatible = "qcom,sm8750-tlmm";
+			reg = <0x0 0x0f100000 0x0 0x102000>;
+
+			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			gpio-ranges = <&tlmm 0 0 216>;
+			wakeup-parent = <&pdc>;
+
+			hub_i2c0_data_clk: hub-i2c0-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio64", "gpio65";
+				function = "i2chub0_se0";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			hub_i2c1_data_clk: hub-i2c1-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio66", "gpio67";
+				function = "i2chub0_se1";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			hub_i2c2_data_clk: hub-i2c2-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio68", "gpio69";
+				function = "i2chub0_se2";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			hub_i2c3_data_clk: hub-i2c3-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio70", "gpio71";
+				function = "i2chub0_se3";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			hub_i2c4_data_clk: hub-i2c4-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio72", "gpio73";
+				function = "i2chub0_se4";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			hub_i2c5_data_clk: hub-i2c5-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio74", "gpio75";
+				function = "i2chub0_se5";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			hub_i2c6_data_clk: hub-i2c6-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio76", "gpio77";
+				function = "i2chub0_se6";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			hub_i2c7_data_clk: hub-i2c7-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio82", "gpio83";
+				function = "i2chub0_se7";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			hub_i2c8_data_clk: hub-i2c8-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio206", "gpio207";
+				function = "i2chub0_se8";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			hub_i2c9_data_clk: hub-i2c9-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio80", "gpio81";
+				function = "i2chub0_se9";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			pcie0_default_state: pcie0-default-state {
+				perst-pins {
+					pins = "gpio102";
+					function = "gpio";
+					drive-strength = <2>;
+					bias-pull-down;
+				};
+
+				clkreq-pins {
+					pins = "gpio103";
+					function = "pcie0_clk_req_n";
+					drive-strength = <2>;
+					bias-pull-up;
+				};
+
+				wake-pins {
+					pins = "gpio104";
+					function = "gpio";
+					drive-strength = <2>;
+					bias-pull-up;
+				};
+			};
+
+			qup_i2c0_data_clk: qup-i2c0-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio32", "gpio33";
+				function = "qup1_se0";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c1_data_clk: qup-i2c1-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio36", "gpio37";
+				function = "qup1_se1";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c2_data_clk: qup-i2c2-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio40", "gpio41";
+				function = "qup1_se2";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c3_data_clk: qup-i2c3-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio44", "gpio45";
+				function = "qup1_se3";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c4_data_clk: qup-i2c4-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio48", "gpio49";
+				function = "qup1_se4";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c5_data_clk: qup-i2c5-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio52", "gpio53";
+				function = "qup1_se5";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c6_data_clk: qup-i2c6-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio56", "gpio57";
+				function = "qup1_se6";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c8_data_clk: qup-i2c8-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio0", "gpio1";
+				function = "qup2_se0";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c9_data_clk: qup-i2c9-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio4", "gpio5";
+				function = "qup2_se1";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c10_data_clk: qup-i2c10-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio8", "gpio9";
+				function = "qup2_se2";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c11_data_clk: qup-i2c11-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio12", "gpio13";
+				function = "qup2_se3";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c12_data_clk: qup-i2c12-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio16", "gpio17";
+				function = "qup2_se4";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c13_data_clk: qup-i2c13-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio20", "gpio21";
+				function = "qup2_se5";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_i2c15_data_clk: qup-i2c15-data-clk-state {
+				/* SDA, SCL */
+				pins = "gpio28", "gpio29";
+				function = "qup2_se7";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_spi0_cs: qup-spi0-cs-state {
+				pins = "gpio35";
+				function = "qup1_se0";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi0_data_clk: qup-spi0-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio32", "gpio33", "gpio34";
+				function = "qup1_se0";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi1_cs: qup-spi1-cs-state {
+				pins = "gpio39";
+				function = "qup1_se1";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi1_data_clk: qup-spi1-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio36", "gpio37", "gpio38";
+				function = "qup1_se1";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi2_cs: qup-spi2-cs-state {
+				pins = "gpio43";
+				function = "qup1_se2";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi2_data_clk: qup-spi2-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio40", "gpio41", "gpio42";
+				function = "qup1_se2";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi3_cs: qup-spi3-cs-state {
+				pins = "gpio47";
+				function = "qup1_se3";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi3_data_clk: qup-spi3-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio44", "gpio45", "gpio46";
+				function = "qup1_se3";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi4_cs: qup-spi4-cs-state {
+				pins = "gpio51";
+				function = "qup1_se4";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi4_data_clk: qup-spi4-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio48", "gpio49", "gpio50";
+				function = "qup1_se4";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi5_cs: qup-spi5-cs-state {
+				pins = "gpio55";
+				function = "qup1_se5";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi5_data_clk: qup-spi5-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio52", "gpio53", "gpio54";
+				function = "qup1_se5";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi6_cs: qup-spi6-cs-state {
+				pins = "gpio59";
+				function = "qup1_se6";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi6_data_clk: qup-spi6-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio56", "gpio57", "gpio58";
+				function = "qup1_se6";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi8_cs: qup-spi8-cs-state {
+				pins = "gpio3";
+				function = "qup2_se0";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi8_data_clk: qup-spi8-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio0", "gpio1", "gpio2";
+				function = "qup2_se0";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi9_cs: qup-spi9-cs-state {
+				pins = "gpio7";
+				function = "qup2_se1";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi9_data_clk: qup-spi9-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio4", "gpio5", "gpio6";
+				function = "qup2_se1";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi10_cs: qup-spi10-cs-state {
+				pins = "gpio11";
+				function = "qup2_se2";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi10_data_clk: qup-spi10-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio8", "gpio9", "gpio10";
+				function = "qup2_se2";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi11_cs: qup-spi11-cs-state {
+				pins = "gpio15";
+				function = "qup2_se3";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi11_data_clk: qup-spi11-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio12", "gpio13", "gpio14";
+				function = "qup2_se3";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi12_cs: qup-spi12-cs-state {
+				pins = "gpio19";
+				function = "qup2_se4";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi12_data_clk: qup-spi12-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio16", "gpio17", "gpio18";
+				function = "qup2_se4";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi13_cs: qup-spi13-cs-state {
+				pins = "gpio23";
+				function = "qup2_se5";
+				drive-strength = <6>;
+				bias-pull-up;
+			};
+
+			qup_spi13_data_clk: qup-spi13-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio20", "gpio21", "gpio22";
+				function = "qup2_se5";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi15_cs: qup-spi15-cs-state {
+				pins = "gpio31";
+				function = "qup2_se7";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_spi15_data_clk: qup-spi15-data-clk-state {
+				/* MISO, MOSI, CLK */
+				pins = "gpio28", "gpio29", "gpio30";
+				function = "qup2_se7";
+				drive-strength = <6>;
+				bias-disable;
+			};
+
+			qup_uart7_default: qup-uart7-default-state {
+				/* TX, RX */
+				pins = "gpio62", "gpio63";
+				function = "qup1_se7";
+				drive-strength = <2>;
+				bias-disable;
+			};
+
+			qup_uart14_default: qup-uart14-default-state {
+				/* TX, RX */
+				pins = "gpio26", "gpio27";
+				function = "qup2_se6";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			qup_uart14_cts_rts: qup-uart14-cts-rts-state {
+				/* CTS, RTS */
+				pins = "gpio24", "gpio25";
+				function = "qup2_se6";
+				drive-strength = <2>;
+				bias-pull-down;
+			};
+
+			sdc2_sleep: sdc2-sleep-state {
+				clk-pins {
+					pins = "sdc2_clk";
+					drive-strength = <2>;
+					bias-disable;
+				};
+
+				cmd-pins {
+					pins = "sdc2_cmd";
+					drive-strength = <2>;
+					bias-pull-up;
+				};
+
+				data-pins {
+					pins = "sdc2_data";
+					drive-strength = <2>;
+					bias-pull-up;
+				};
+			};
+
+			sdc2_default: sdc2-default-state {
+				clk-pins {
+					pins = "sdc2_clk";
+					drive-strength = <16>;
+					bias-disable;
+				};
+
+				cmd-pins {
+					pins = "sdc2_cmd";
+					drive-strength = <10>;
+					bias-pull-up;
+				};
+
+				data-pins {
+					pins = "sdc2_data";
+					drive-strength = <10>;
+					bias-pull-up;
+				};
+			};
+		};
+
+		tcsrcc: clock-controller at f204008 {
+			compatible = "qcom,sm8750-tcsr", "syscon";
+			reg = <0x0 0x0f204008 0x0 0x3004>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		apps_smmu: iommu at 15000000 {
+			compatible = "qcom,sm8750-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x15000000 0x0 0x100000>;
+
+			interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 99 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>,
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+				     <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 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>,
+				     <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 691 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 692 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 693 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 697 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 492 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 493 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 496 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 497 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 498 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 499 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 500 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 501 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 502 IRQ_TYPE_LEVEL_HIGH>;
+
+			#iommu-cells = <2>;
+			#global-interrupts = <1>;
+
+			dma-coherent;
+		};
+
+		intc: interrupt-controller at 16000000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x16000000 0x0 0x10000>,
+			      <0x0 0x16080000 0x0 0x200000>;
+
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+			#interrupt-cells = <3>;
+			interrupt-controller;
+
+			#redistributor-regions = <1>;
+			redistributor-stride = <0x0 0x40000>;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			gic_its: msi-controller at 16040000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x16040000 0x0 0x20000>;
+
+				msi-controller;
+				#msi-cells = <1>;
+			};
+		};
+
+		apps_rsc: rsc at 16500000 {
+			compatible = "qcom,rpmh-rsc";
+			reg = <0x0 0x16500000 0x0 0x10000>,
+			      <0x0 0x16510000 0x0 0x10000>,
+			      <0x0 0x16520000 0x0 0x10000>;
+			reg-names = "drv-0",
+				    "drv-1",
+				    "drv-2";
+
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			qcom,tcs-offset = <0xd00>;
+			qcom,drv-id = <2>;
+			qcom,tcs-config = <ACTIVE_TCS    3>, <SLEEP_TCS     2>,
+					  <WAKE_TCS      2>, <CONTROL_TCS   0>;
+
+			label = "apps_rsc";
+
+			power-domains = <&system_pd>;
+
+			apps_bcm_voter: bcm-voter {
+				compatible = "qcom,bcm-voter";
+			};
+
+			rpmhcc: clock-controller {
+				compatible = "qcom,sm8750-rpmh-clk";
+
+				clocks = <&xo_board>;
+				clock-names = "xo";
+
+				#clock-cells = <1>;
+			};
+
+			rpmhpd: power-controller {
+				compatible = "qcom,sm8750-rpmhpd";
+
+				operating-points-v2 = <&rpmhpd_opp_table>;
+
+				#power-domain-cells = <1>;
+
+				rpmhpd_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					rpmhpd_opp_ret: opp-16 {
+						opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
+					};
+
+					rpmhpd_opp_min_svs: opp-48 {
+						opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+					};
+
+					rpmhpd_opp_low_svs_d3: opp-50 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D3>;
+					};
+
+					rpmhpd_opp_low_svs_d2: opp-52 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+					};
+
+					rpmhpd_opp_low_svs_d1: opp-56 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+					};
+
+					rpmhpd_opp_low_svs_d0: opp-60 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+					};
+
+					rpmhpd_opp_low_svs: opp-64 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+					};
+
+					rpmhpd_opp_low_svs_l1: opp-80 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+					};
+
+					rpmhpd_opp_svs: opp-128 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+					};
+
+					rpmhpd_opp_svs_l0: opp-144 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+					};
+
+					rpmhpd_opp_svs_l1: opp-192 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+					};
+
+					rpmhpd_opp_svs_l2: opp-224 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+					};
+
+					rpmhpd_opp_nom: opp-256 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+					};
+
+					rpmhpd_opp_nom_l1: opp-320 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+					};
+
+					rpmhpd_opp_nom_l2: opp-336 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
+					};
+
+					rpmhpd_opp_turbo: opp-384 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+					};
+
+					rpmhpd_opp_turbo_l1: opp-416 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+					};
+
+					rpmhpd_opp_turbo_l2: opp-432 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L2>;
+					};
+
+					rpmhpd_opp_turbo_l3: opp-448 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3>;
+					};
+
+					rpmhpd_opp_turbo_l4: opp-452 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L4>;
+					};
+
+					rpmhpd_opp_super_turbo_no_cpr: opp-480 {
+						opp-level =
+							<RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR>;
+					};
+				};
+			};
+		};
+
+		timer at 16800000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x16800000 0x0 0x1000>;
+
+			#address-cells = <2>;
+			#size-cells = <1>;
+			ranges = <0 0 0 0 0x20000000>;
+
+			frame at 16801000 {
+				reg = <0x0 0x16801000 0x1000>,
+				      <0x0 0x16802000 0x1000>;
+
+				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+
+				frame-number = <0>;
+			};
+
+			frame at 16803000 {
+				reg = <0x0 0x16803000 0x1000>;
+
+				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+				frame-number = <1>;
+
+				status = "disabled";
+			};
+
+			frame at 16805000 {
+				reg = <0x0 0x16805000 0x1000>;
+
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+
+				frame-number = <2>;
+
+				status = "disabled";
+			};
+
+			frame at 16807000 {
+				reg = <0x0 0x16807000 0x1000>;
+
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+
+				frame-number = <3>;
+
+				status = "disabled";
+			};
+
+			frame at 16809000 {
+				reg = <0x0 0x16809000 0x1000>;
+
+				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+
+				frame-number = <4>;
+
+				status = "disabled";
+			};
+
+			frame at 1680b000 {
+				reg = <0x0 0x1680b000 0x1000>;
+
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+
+				frame-number = <5>;
+
+				status = "disabled";
+			};
+
+			frame at 1680d000 {
+				reg = <0x0 0x1680d000 0x1000>;
+
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+
+				frame-number = <6>;
+
+				status = "disabled";
+			};
+		};
+
+		gem_noc: interconnect at 24100000 {
+			compatible = "qcom,sm8750-gem-noc";
+			reg = <0x0 0x24100000 0x0 0x14b080>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+		};
+
+		nsp_noc: interconnect at 320c0000 {
+			compatible = "qcom,sm8750-nsp-noc";
+			reg = <0x0 0x320c0000 0x0 0x13080>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			#interconnect-cells = <2>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+};

-- 
2.46.1



From sboyd at kernel.org  Wed Dec  4 15:24:40 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 04 Dec 2024 15:24:40 -0800
Subject: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
In-Reply-To: <OS8PR06MB75419637D55A022300E00850F2352@OS8PR06MB7541.apcprd06.prod.outlook.com>
References: <20241028053018.2579200-1-ryan_chen@aspeedtech.com> <20241028053018.2579200-4-ryan_chen@aspeedtech.com> <287924eed186e3b6b52cd13bcf939ab6.sboyd@kernel.org> <SI6PR06MB7535F5D22E3FCCF5C610B307F2552@SI6PR06MB7535.apcprd06.prod.outlook.com> <a68516df98c8b8fb80f094e6e55fcb8d.sboyd@kernel.org> <OS8PR06MB75419637D55A022300E00850F2352@OS8PR06MB7541.apcprd06.prod.outlook.com>
Message-ID: <9ccfb478d9a122db6c634e9559e211ff.sboyd@kernel.org>

Quoting Ryan Chen (2024-12-01 19:12:01)
> > > > Subject: Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> > > >
> > > > Quoting Ryan Chen (2024-10-27 22:30:18)
> > > > > diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c
> > > > > new file mode 100644 index 000000000000..db9ee5031b7c
> > > > > --- /dev/null
> > > > > +++ b/drivers/clk/clk-ast2700.c
> > > > > @@ -0,0 +1,1513 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0
> > [...]
> > > > > +struct ast2700_clk_info {
> > > > > +       const char *name;
> > > > > +       const char * const *parent_names;
> > > >
> > > > Please don't use strings for parent names.
> > > Sorry, do you mean use clk_parent_data struct for parent?
> > >         +const struct clk_parent_data   parent;         /* For gate */
> > >         +const struct clk_parent_data   *parents;               /*
> > For mux */
> > 
> > Yes.
> And I find a better way for parent_data. The following is my modification. 
> And parent_data will be union data structure. Like following.
> Is this good direction? 

Looks OK.

> 
> #define DIVIDER_CLK(_id, _name, _parent, _reg, _shift, _width, _div_table) \
>         [_id] = { \
>                 .type = CLK_DIVIDER, \
>                 .name = _name, \
>                 .data = { \
>                         .div = { \
>                                 .parent = _parent, \
>                                 .reg = _reg, \
>                                 .bit_shift = _shift, \
>                                 .bit_width = _width, \
>                                 .div_table = _div_table, \
>                         }, \
>                 }, \
>         }
> struct ast2700_clk_info {
>         const char *name;
>         u8 clk_idx;
>         u32 reg;
>         u32 type;
>         union {
>                 struct ast2700_clk_fixed_factor_data factor;
>                 struct ast2700_clk_fixed_rate_data rate;
>                 struct ast2700_clk_gate_data gate;
>                 struct ast2700_clk_div_data div;
>                 struct ast2700_clk_pll_data pll;
>                 struct ast2700_clk_mux_data mux;
>         } data;
> };
> 
> struct ast2700_clk_div_data {
>         const struct clk_div_table *div_table;
>         const struct clk_parent_data *parent;
>         u8 bit_shift;
>         u8 bit_width;
>         u32 reg;
> };
> 
> static const struct ast2700_clk_info ast2700_scu0_clk_info[] __initconst = {
> ...........................
>         DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,

Can you also show what soc0_ahbmux is?

>                     SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table),
> ......................
> > 
> > >
> > > >
> > > > > +       const struct clk_div_table *div_table;
> > > > > +       unsigned long fixed_rate;
> > > > > +       unsigned int mult;
> > > > > +       unsigned int div;
> > > > > +       u32 reg;
> > > > > +       u32 flags;
> > > > > +       u32 type;
> > > > > +       u8 clk_idx;
> > > > > +       u8 bit_shift;
> > > > > +       u8 bit_width;
> > > > > +       u8 num_parents;
> > > > > +};
> > > > > +
> > > > [...]
> > > > > +
> > > > > +static const struct clk_div_table ast2700_clk_div_table2[] = {
> > > > > +       { 0x0, 2 },
> > > > > +       { 0x1, 4 },
> > > > > +       { 0x2, 6 },
> > > > > +       { 0x3, 8 },
> > > > > +       { 0x4, 10 },
> > > > > +       { 0x5, 12 },
> > > > > +       { 0x6, 14 },
> > > > > +       { 0x7, 16 },
> > > >
> > > > Isn't this the default divider setting for struct clk_divider?
> > > Sorry, I don't catch your point.
> > > the SoC do have default divider setting. But it can be modified.
> > > And also have different divider table setting.
> > 
> > I mean that this is the way that struct clk_divider works already. So you don't
> > need to make the clk_div_table array for what is supported in code.
> 
> Sorry, I understand your point. But I trace the code didn't get any clue. "clk_divider work already".
> finally function call will be __clk_hw_register_divider
> https://github.com/torvalds/linux/blob/master/drivers/clk/clk-divider.c#L589
> It still need table point need to address. Can you give me more direction or example?
> 

The 'table' member is optional. When the table is NULL, we treat each
number that fits into the divider field width as a divider. It may be
CLK_DIVIDER_EVEN_INTEGERS that you have here though.


From Frank.Li at nxp.com  Wed Dec  4 15:25:50 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 04 Dec 2024 18:25:50 -0500
Subject: [PATCH v10 0/7] PCI: EP: Add RC-to-EP doorbell with platform MSI
 controller
Message-ID: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>

??????????????   ?????????????????????????????????????   ??????????????????
?            ?   ?                                   ?   ?                ?
?            ?   ? PCI Endpoint                      ?   ? PCI Host       ?
?            ?   ?                                   ?   ?                ?
?            ????? 1.platform_msi_domain_alloc_irqs()?   ?                ?
?            ?   ?                                   ?   ?                ?
? MSI        ????? 2.write_msi_msg()                 ??????BAR<n>         ?
? Controller ?   ?   update doorbell register address?   ?                ?
?            ?   ?   for BAR                         ?   ?                ?
?            ?   ?                                   ?   ? 3. Write BAR<n>?
?            ?????????????????????????????????????????????                ?
?            ?   ?                                   ?   ?                ?
?            ????? 4.Irq Handle                      ?   ?                ?
?            ?   ?                                   ?   ?                ?
?            ?   ?                                   ?   ?                ?
??????????????   ?????????????????????????????????????   ??????????????????

This patches based on old https://lore.kernel.org/imx/20221124055036.1630573-1-Frank.Li at nxp.com/

Original patch only target to vntb driver. But actually it is common
method.

This patches add new API to pci-epf-core, so any EP driver can use it.

Previous v2 discussion here.
https://lore.kernel.org/imx/20230911220920.1817033-1-Frank.Li at nxp.com/

Changes in v10:

Thomas Gleixner:
	There are big change in pci-ep-msi.c. I am sure if go on the
corrent path. The key improvement is remove only 1 function devices's
limitation.

	I use new patch for imutable check, which relative additional
feature compared to base enablement patch.

- Remove patch Add msi_remove_device_irq_domain() in platform_device_msi_free_irqs_all()
- Add new patch irqchip/gic-v3-its: Avoid overwriting msi_prepare callback if provided by msi_domain_info
- Remove only support 1 endpoint function limiation.
- Create one MSI domain for each endpoint function devices.
- Use "msi-map" in pci ep controler node, instead of of msi-parent. first
argument is
	(func_no << 8 | vfunc_no)

- Link to v9: https://lore.kernel.org/r/20241203-ep-msi-v9-0-a60dbc3f15dd at nxp.com

Changes in v9
- Add patch platform-msi: Add msi_remove_device_irq_domain() in platform_device_msi_free_irqs_all()
- Remove patch PCI: endpoint: Add pci_epc_get_fn() API for customizable filtering
- Remove API pci_epf_align_inbound_addr_lo_hi
- Move doorbell_alloc in to doorbell_enable function.
- Link to v8: https://lore.kernel.org/r/20241116-ep-msi-v8-0-6f1f68ffd1bb at nxp.com

Changes in v8:
- update helper function name to pci_epf_align_inbound_addr()
- Link to v7: https://lore.kernel.org/r/20241114-ep-msi-v7-0-d4ac7aafbd2c at nxp.com

Changes in v7:
- Add helper function pci_epf_align_addr();
- Link to v6: https://lore.kernel.org/r/20241112-ep-msi-v6-0-45f9722e3c2a at nxp.com

Changes in v6:
- change doorbell_addr to doorbell_offset
- use round_down()
- add Niklas's test by tag
- rebase to pci/endpoint
- Link to v5: https://lore.kernel.org/r/20241108-ep-msi-v5-0-a14951c0d007 at nxp.com

Changes in v5:
- Move request_irq to epf test function driver for more flexiable user case
- Add fixed size bar handler
- Some minor improvememtn to see each patches's changelog.
- Link to v4: https://lore.kernel.org/r/20241031-ep-msi-v4-0-717da2d99b28 at nxp.com

Changes in v4:
- Remove patch genirq/msi: Add cleanup guard define for msi_lock_descs()/msi_unlock_descs()
- Use new method to avoid compatible problem.
  Add new command DOORBELL_ENABLE and DOORBELL_DISABLE.
  pcitest -B send DOORBELL_ENABLE first, EP test function driver try to
remap one of BAR_N (except test register bar) to ITS MSI MMIO space. Old
driver don't support new command, so failure return, not side effect.
  After test, DOORBELL_DISABLE command send out to recover original map, so
pcitest bar test can pass as normal.
- Other detail change see each patches's change log
- Link to v3: https://lore.kernel.org/r/20241015-ep-msi-v3-0-cedc89a16c1a at nxp.com

Change from v2 to v3
- Fixed manivannan's comments
- Move common part to pci-ep-msi.c and pci-ep-msi.h
- rebase to 6.12-rc1
- use RevID to distingiush old version

mkdir /sys/kernel/config/pci_ep/functions/pci_epf_test/func1
echo 16 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/msi_interrupts
echo 0x080c > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/deviceid
echo 0x1957 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/vendorid
echo 1 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/revid
^^^^^^ to enable platform msi support.
ln -s /sys/kernel/config/pci_ep/functions/pci_epf_test/func1 /sys/kernel/config/pci_ep/controllers/4c380000.pcie-ep

- use new device ID, which identify support doorbell to avoid broken
compatility.

    Enable doorbell support only for PCI_DEVICE_ID_IMX8_DB, while other devices
    keep the same behavior as before.

           EP side             RC with old driver      RC with new driver
    PCI_DEVICE_ID_IMX8_DB          no probe              doorbell enabled
    Other device ID             doorbell disabled*       doorbell disabled*

    * Behavior remains unchanged.

Change from v1 to v2
- Add missed patch for endpont/pci-epf-test.c
- Move alloc and free to epc driver from epf.
- Provide general help function for EPC driver to alloc platform msi irq.
- Fixed manivannan's comments.

To: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
To: Krzysztof Wilczy?ski <kw at linux.com>
To: Kishon Vijay Abraham I <kishon at kernel.org>
To: Bjorn Helgaas <bhelgaas at google.com>
To: Arnd Bergmann <arnd at arndb.de>
To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: linux-kernel at vger.kernel.org
Cc: linux-pci at vger.kernel.org
Cc: imx at lists.linux.dev
Cc: Niklas Cassel <cassel at kernel.org>
Cc: dlemoal at kernel.org
Cc: jdmason at kudzu.us
To: Rafael J. Wysocki <rafael at kernel.org>
To: Thomas Gleixner <tglx at linutronix.de>
To: Anup Patel <apatel at ventanamicro.com>
To: Kishon Vijay Abraham I <kishon at kernel.org>
To: Marc Zyngier <maz at kernel.org>
To: Thomas Gleixner <tglx at linutronix.de>
Cc: linux-arm-kernel at lists.infradead.org

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Frank Li (7):
      irqchip/gic-v3-its: Avoid overwriting msi_prepare callback if provided by msi_domain_info
      PCI: endpoint: Add RC-to-EP doorbell support using platform MSI controller
      PCI: endpoint: pci-ep-msi: Add MSI address/data pair mutable check
      PCI: endpoint: Add pci_epf_align_inbound_addr() helper for address alignment
      PCI: endpoint: pci-epf-test: Add doorbell test support
      misc: pci_endpoint_test: Add doorbell test case
      tools: PCI: Add 'B' option for test doorbell

 drivers/irqchip/irq-gic-v3-its-msi-parent.c   |   3 +-
 drivers/misc/pci_endpoint_test.c              |  80 +++++++++++++
 drivers/pci/endpoint/Makefile                 |   2 +-
 drivers/pci/endpoint/functions/pci-epf-test.c | 132 ++++++++++++++++++++++
 drivers/pci/endpoint/pci-ep-msi.c             | 156 ++++++++++++++++++++++++++
 drivers/pci/endpoint/pci-epf-core.c           |  44 ++++++++
 include/linux/msi.h                           |   2 +
 include/linux/pci-ep-msi.h                    |  15 +++
 include/linux/pci-epf.h                       |  19 ++++
 include/uapi/linux/pcitest.h                  |   1 +
 tools/pci/pcitest.c                           |  16 ++-
 11 files changed, 467 insertions(+), 3 deletions(-)
---
base-commit: f134785ecf3bd881a10f83dccacdcea2ac45e673
change-id: 20241010-ep-msi-8b4cab33b1be

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Wed Dec  4 15:25:51 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 04 Dec 2024 18:25:51 -0500
Subject: [PATCH v10 1/7] irqchip/gic-v3-its: Avoid overwriting msi_prepare
 callback if provided by msi_domain_info
In-Reply-To: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
Message-ID: <20241204-ep-msi-v10-1-87c378dbcd6d@nxp.com>

  ?????????????????????????????????    ?????????
  ?                               ?    ?       ?
  ? PCI Endpoint Controller (1)   ?????? ITS   ?
  ?                               ?    ?       ?
  ?????????????????????????????????    ?????????
      ?        ?
      ?        ?
  ????????  ????????
  ?      ?  ?      ?
  ?Func1 ?  ?Func2 ?
  ? (2)  ?  ?      ?
  ????????  ????????
     ?         ?
     ?         ?
     ?????????????????????????? PCIe Bus

(1) is platform device, which is generally descripted by Device Tree(DT).
(2) Func1 and Func2 is created by configfs

The current platform MSI API supports only a single device. For instance,
a platform device (e.g., PCI Endpoint Controller) calls
platform_device_msi_init_and_alloc_irqs() to allocate MSI IRQs.

Child devices (e.g., function devices created by configfs) require
individual MSI domains, with the same MSI parent domain as the parent
device. These individual domains need specialized msi_prepare callbacks to
set  msi_alloc_info_t. However, the current ITS implementation overwrites
the msi_prepare callback with its_pmsi_prepare().

Modify the implementation to assign its_pmsi_prepare() only if
msi_domain_info::msi_prepare is NULL, allowing customized callbacks where
needed.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v10
- new patch
---
 drivers/irqchip/irq-gic-v3-its-msi-parent.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
index 75aa0d4bd1346..33e94cfc4d506 100644
--- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
@@ -195,7 +195,8 @@ static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 		 * FIXME: See the above PCI prepare comment. The domain
 		 * size is also known at domain creation time.
 		 */
-		info->ops->msi_prepare = its_pmsi_prepare;
+		if (!info->ops->msi_prepare)
+			info->ops->msi_prepare = its_pmsi_prepare;
 		break;
 	default:
 		/* Confused. How did the lib return true? */

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec  4 15:25:52 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 04 Dec 2024 18:25:52 -0500
Subject: [PATCH v10 2/7] PCI: endpoint: Add RC-to-EP doorbell support using
 platform MSI controller
In-Reply-To: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
Message-ID: <20241204-ep-msi-v10-2-87c378dbcd6d@nxp.com>

Doorbell feature is implemented by mapping the EP's MSI interrupt
controller message address to a dedicated BAR in the EPC core. It is the
responsibility of the EPF driver to pass the actual message data to be
written by the host to the doorbell BAR region through its own logic.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v10
- Create msi domain for each function device.
- Remove only function support limiation. My hardware only support one
function, so not test more than one case.
- use "msi-map" descript msi information

  msi-map = <func_no << 8  | vfunc_no, &its, start_stream_id,  size>;

Chagne from v8 to v9
- sort header file
- use pci_epc_get(dev_name(msi_desc_to_dev(desc)));
- check epf number at pci_epf_alloc_doorbell
- Add comments for miss msi-parent case

change from v5 to v8
-none

Change from v4 to v5
- Remove request_irq() in pci_epc_alloc_doorbell() and leave to EP function
driver, so ep function driver can register differece call back function for
difference doorbell events and set irq affinity to differece CPU core.
- Improve error message when MSI allocate failure.

Change from v3 to v4
- msi change to use msi_get_virq() avoid use msi_for_each_desc().
- add new struct for pci_epf_doorbell_msg to msi msg,virq and irq name.
- move mutex lock to epc function
- initialize variable at declear place.
- passdown epf to epc*() function to simplify code.
---
 drivers/pci/endpoint/Makefile     |   2 +-
 drivers/pci/endpoint/pci-ep-msi.c | 148 ++++++++++++++++++++++++++++++++++++++
 include/linux/pci-ep-msi.h        |  15 ++++
 include/linux/pci-epf.h           |  16 +++++
 4 files changed, 180 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/endpoint/Makefile b/drivers/pci/endpoint/Makefile
index 95b2fe47e3b06..a1ccce440c2c5 100644
--- a/drivers/pci/endpoint/Makefile
+++ b/drivers/pci/endpoint/Makefile
@@ -5,4 +5,4 @@
 
 obj-$(CONFIG_PCI_ENDPOINT_CONFIGFS)	+= pci-ep-cfs.o
 obj-$(CONFIG_PCI_ENDPOINT)		+= pci-epc-core.o pci-epf-core.o\
-					   pci-epc-mem.o functions/
+					   pci-epc-mem.o pci-ep-msi.o functions/
diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
new file mode 100644
index 0000000000000..b0a91fde202f3
--- /dev/null
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCI Endpoint *Controller* (EPC) MSI library
+ *
+ * Copyright (C) 2024 NXP
+ * Author: Frank Li <Frank.Li at nxp.com>
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/pci-epc.h>
+#include <linux/pci-epf.h>
+#include <linux/pci-ep-cfs.h>
+#include <linux/pci-ep-msi.h>
+#include <linux/slab.h>
+
+static void pci_epf_write_msi_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	struct msi_desc *desc = irq_data_get_msi_desc(d);
+	struct pci_epf *epf = to_pci_epf(desc->dev);
+
+	if (epf && epf->db_msg && desc->msi_index < epf->num_db)
+		memcpy(&epf->db_msg[desc->msi_index].msg, msg, sizeof(*msg));
+}
+
+static void pci_epf_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+	arg->desc = desc;
+	arg->hwirq = desc->msi_index;
+}
+
+static int pci_epf_msi_prepare(struct irq_domain *domain, struct device *dev,
+			       int nvec, msi_alloc_info_t *arg)
+{
+	struct pci_epf *epf = to_pci_epf(dev);
+	struct msi_domain_info *msi_info;
+	struct pci_epc *epc = epf->epc;
+
+	memset(arg, 0, sizeof(*arg));
+	arg->scratchpad[0].ul = of_msi_map_id(epc->dev.parent, NULL,
+					      (epf->func_no << 8) | epf->vfunc_no);
+
+	/*
+	 * @domain->msi_domain_info->hwsize contains the size of the device
+	 * domain, but vector allocation happens one by one.
+	 */
+	msi_info = msi_get_domain_info(domain);
+	if (msi_info->hwsize > nvec)
+		nvec = msi_info->hwsize;
+
+	/* Allocate at least 32 MSIs, and always as a power of 2 */
+	nvec = max_t(int, 32, roundup_pow_of_two(nvec));
+
+	msi_info = msi_get_domain_info(domain->parent);
+	return msi_info->ops->msi_prepare(domain->parent, dev, nvec, arg);
+}
+
+static const struct msi_domain_template pci_epf_msi_template = {
+	.chip = {
+		.name			= "EP-MSI",
+		.irq_mask		= irq_chip_mask_parent,
+		.irq_unmask		= irq_chip_unmask_parent,
+		.irq_write_msi_msg	= pci_epf_write_msi_msg,
+		/* The rest is filled in by the MSI parent */
+	},
+
+	.ops = {
+		.msi_prepare		= pci_epf_msi_prepare,
+		.set_desc		= pci_epf_msi_set_desc,
+	},
+
+	.info = {
+		.bus_token		= DOMAIN_BUS_DEVICE_MSI,
+	},
+};
+
+static int pci_epf_device_msi_init_and_alloc_irqs(struct device *dev, unsigned int nvec)
+{
+	struct irq_domain *domain = dev->msi.domain;
+
+	if (!domain)
+		return -EINVAL;
+
+	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN,
+					  &pci_epf_msi_template, nvec, NULL, NULL))
+		return -ENODEV;
+
+	return msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, nvec - 1);
+}
+
+int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
+{
+	struct pci_epc *epc = epf->epc;
+	struct device *dev = &epf->dev;
+	struct irq_domain *dom;
+	void *msg;
+	u32 rid;
+	int ret;
+	int i;
+
+	rid = (epf->func_no << 8) | epf->vfunc_no;
+	dom = of_msi_map_get_device_domain(epc->dev.parent, rid, DOMAIN_BUS_PLATFORM_MSI);
+	if (!dom) {
+		dev_err(dev, "Can't find msi domain\n");
+		return -EINVAL;
+	}
+
+	dev_set_msi_domain(dev, dom);
+
+	msg = kcalloc(num_db, sizeof(struct pci_epf_doorbell_msg), GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	epf->num_db = num_db;
+	epf->db_msg = msg;
+
+	ret = pci_epf_device_msi_init_and_alloc_irqs(dev, num_db);
+	if (ret) {
+		/*
+		 * The pcie_ep DT node has to specify 'msi-parent' for EP
+		 * doorbell support to work. Right now only GIC ITS is
+		 * supported. If you have GIC ITS and reached this print,
+		 * perhaps you are missing 'msi-map' in DT.
+		 */
+		dev_err(dev, "Failed to allocate MSI\n");
+		kfree(msg);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < num_db; i++)
+		epf->db_msg[i].virq = msi_get_virq(dev, i);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epf_alloc_doorbell);
+
+void pci_epf_free_doorbell(struct pci_epf *epf)
+{
+	msi_domain_free_irqs_all(&epf->dev, MSI_DEFAULT_DOMAIN);
+	msi_remove_device_irq_domain(&epf->dev, MSI_DEFAULT_DOMAIN);
+
+	kfree(epf->db_msg);
+	epf->db_msg = NULL;
+	epf->num_db = 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_free_doorbell);
diff --git a/include/linux/pci-ep-msi.h b/include/linux/pci-ep-msi.h
new file mode 100644
index 0000000000000..f0cfecf491199
--- /dev/null
+++ b/include/linux/pci-ep-msi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PCI Endpoint *Function* side MSI header file
+ *
+ * Copyright (C) 2024 NXP
+ * Author: Frank Li <Frank.Li at nxp.com>
+ */
+
+#ifndef __PCI_EP_MSI__
+#define __PCI_EP_MSI__
+
+int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 nums);
+void pci_epf_free_doorbell(struct pci_epf *epf);
+
+#endif /* __PCI_EP_MSI__ */
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 18a3aeb62ae4e..5374e6515ffa0 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -12,6 +12,7 @@
 #include <linux/configfs.h>
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <linux/msi.h>
 #include <linux/pci.h>
 
 struct pci_epf;
@@ -125,6 +126,17 @@ struct pci_epf_bar {
 	int		flags;
 };
 
+/**
+ * struct pci_epf_doorbell_msg - represents doorbell message
+ * @msi_msg: MSI message
+ * @virq: irq number of this doorbell MSI message
+ * @name: irq name for doorbell interrupt
+ */
+struct pci_epf_doorbell_msg {
+	struct msi_msg msg;
+	int virq;
+};
+
 /**
  * struct pci_epf - represents the PCI EPF device
  * @dev: the PCI EPF device
@@ -152,6 +164,8 @@ struct pci_epf_bar {
  * @vfunction_num_map: bitmap to manage virtual function number
  * @pci_vepf: list of virtual endpoint functions associated with this function
  * @event_ops: Callbacks for capturing the EPC events
+ * @db_msg: data for MSI from RC side
+ * @num_db: number of doorbells
  */
 struct pci_epf {
 	struct device		dev;
@@ -182,6 +196,8 @@ struct pci_epf {
 	unsigned long		vfunction_num_map;
 	struct list_head	pci_vepf;
 	const struct pci_epc_event_ops *event_ops;
+	struct pci_epf_doorbell_msg *db_msg;
+	u16 num_db;
 };
 
 /**

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec  4 15:25:53 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 04 Dec 2024 18:25:53 -0500
Subject: [PATCH v10 3/7] PCI: endpoint: pci-ep-msi: Add MSI address/data
 pair mutable check
In-Reply-To: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
Message-ID: <20241204-ep-msi-v10-3-87c378dbcd6d@nxp.com>

Some MSI controller change address/data pair when irq_set_affinity().
Current PCI endpoint can't support this type MSI controller. So add flag
MSI_FLAG_MUTABLE in include/linux/msi.h and check it when allocate
doorbell.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v10
- new patch
---
 drivers/pci/endpoint/pci-ep-msi.c | 8 ++++++++
 include/linux/msi.h               | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
index b0a91fde202f3..c4a4f211cb27d 100644
--- a/drivers/pci/endpoint/pci-ep-msi.c
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -107,6 +107,14 @@ int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
 		return -EINVAL;
 	}
 
+	if (!dom->msi_parent_ops)
+		return -EINVAL;
+
+	if (dom->msi_parent_ops->supported_flags & MSI_FLAG_MUTABLE) {
+		dev_err(dev, "Can't support mutable address/data pair MSI controller\n");
+		return -EINVAL;
+	}
+
 	dev_set_msi_domain(dev, dom);
 
 	msg = kcalloc(num_db, sizeof(struct pci_epf_doorbell_msg), GFP_KERNEL);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index b10093c4d00ea..e404e0a01692a 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -556,6 +556,8 @@ enum {
 	MSI_FLAG_PCI_MSIX_ALLOC_DYN	= (1 << 20),
 	/* PCI MSIs cannot be steered separately to CPU cores */
 	MSI_FLAG_NO_AFFINITY		= (1 << 21),
+	/* Address and data pair is mutable when irq_set_affinity() */
+	MSI_FLAG_MUTABLE		= (1 << 22),
 };
 
 /**

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec  4 15:25:54 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 04 Dec 2024 18:25:54 -0500
Subject: [PATCH v10 4/7] PCI: endpoint: Add pci_epf_align_inbound_addr()
 helper for address alignment
In-Reply-To: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
Message-ID: <20241204-ep-msi-v10-4-87c378dbcd6d@nxp.com>

Introduce the helper function pci_epf_align_inbound_addr() to adjust
addresses according to PCI BAR alignment requirements, converting addresses
into base and offset values.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change form v9 to v10
- none

change from v8 to v9
- pci_epf_align_inbound_addr(), base and off must be not NULL
- rm pci_epf_align_inbound_addr_lo_hi()

change from v7 to v8
- change name to pci_epf_align_inbound_addr()
- update comment said only need for memory, which not allocated by
pci_epf_alloc_space().

change from v6 to v7
- new patch
---
 drivers/pci/endpoint/pci-epf-core.c | 44 +++++++++++++++++++++++++++++++++++++
 include/linux/pci-epf.h             |  3 +++
 2 files changed, 47 insertions(+)

diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 8fa2797d4169a..d7a80f9c1e661 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -464,6 +464,50 @@ struct pci_epf *pci_epf_create(const char *name)
 }
 EXPORT_SYMBOL_GPL(pci_epf_create);
 
+/**
+ * pci_epf_align_inbound_addr() - Get base address and offset that match BAR's
+ *			  alignment requirement
+ * @epf: the EPF device
+ * @addr: the address of the memory
+ * @bar: the BAR number corresponding to map addr
+ * @base: return base address, which match BAR's alignment requirement.
+ * @off: return offset.
+ *
+ * Helper function to convert input 'addr' to base and offset, which match
+ * BAR's alignment requirement.
+ *
+ * The pci_epf_alloc_space() function already accounts for alignment. This is
+ * primarily intended for use with other memory regions not allocated by
+ * pci_epf_alloc_space(), such as peripheral register spaces or the trigger
+ * address for a platform MSI controller.
+ */
+int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
+			       u64 addr, u64 *base, size_t *off)
+{
+	const struct pci_epc_features *epc_features;
+	u64 align;
+
+	if (!base || !off)
+		return -EINVAL;
+
+	epc_features = pci_epc_get_features(epf->epc, epf->func_no, epf->vfunc_no);
+	if (!epc_features) {
+		dev_err(&epf->dev, "epc_features not implemented\n");
+		return -EOPNOTSUPP;
+	}
+
+	align = epc_features->align;
+	align = align ? align : 128;
+	if (epc_features->bar[bar].type == BAR_FIXED)
+		align = max(epc_features->bar[bar].fixed_size, align);
+
+	*base = round_down(addr, align);
+	*off = addr & (align - 1);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_align_inbound_addr);
+
 static void pci_epf_dev_release(struct device *dev)
 {
 	struct pci_epf *epf = to_pci_epf(dev);
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 5374e6515ffa0..2847d195433bf 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -238,6 +238,9 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
 			  enum pci_epc_interface_type type);
 void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
 			enum pci_epc_interface_type type);
+
+int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
+			       u64 addr, u64 *base, size_t *off);
 int pci_epf_bind(struct pci_epf *epf);
 void pci_epf_unbind(struct pci_epf *epf);
 int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec  4 15:25:55 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 04 Dec 2024 18:25:55 -0500
Subject: [PATCH v10 5/7] PCI: endpoint: pci-epf-test: Add doorbell test
 support
In-Reply-To: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
Message-ID: <20241204-ep-msi-v10-5-87c378dbcd6d@nxp.com>

Add three registers: doorbell_bar, doorbell_addr, and doorbell_data. Use
pci_epf_alloc_doorbell() to allocate a doorbell address space.

Enable the Root Complex (RC) side driver to trigger pci-epc-test's doorbell
callback handler by writing doorbell_data to the mapped doorbell_bar's
address space.

Set STATUS_DOORBELL_SUCCESS in the doorbell callback to indicate
completion.

Avoid breaking compatibility between host and endpoint, add new command
COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL. Host side need send
COMMAND_ENABLE_DOORBELL to map one bar's inbound address to MSI space.
the command COMMAND_DISABLE_DOORBELL to recovery original inbound address
mapping.

	 	Host side new driver	Host side old driver

EP: new driver      S				F
EP: old driver      F				F

S: If EP side support MSI, 'pcitest -B' return success.
   If EP side doesn't support MSI, the same to 'F'.

F: 'pcitest -B' return failure, other case as usual.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v10
- none

Change from v8 to v9
- move pci_epf_alloc_doorbell() into pci_epf_{enable/disable}_doorbell().
- remove doorbell_done in commit message.
- rename pci_epf_{enable/disable}_doorbell() to
pci_epf_test_{enable/disable}_doorbell() to align corrent code style.

Change from v7 to v8
- rename to pci_epf_align_inbound_addr_lo_hi()

Change from v6 to v7
- use help function pci_epf_align_addr_lo_hi()

Change from v5 to v6
- rename doorbell_addr to doorbell_offset

Chagne from v4 to v5
- Add doorbell free at unbind function.
- Move msi irq handler to here to more complex user case, such as differece
doorbell can use difference handler function.
- Add Niklas's code to handle fixed bar's case. If need add your signed-off
tag or co-developer tag, please let me know.

change from v3 to v4
- remove revid requirement
- Add command COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL.
- call pci_epc_set_bar() to map inbound address to MSI space only at
COMMAND_ENABLE_DOORBELL.
---
 drivers/pci/endpoint/functions/pci-epf-test.c | 132 ++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index ef6677f34116e..a0a0e86a081cb 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -11,12 +11,14 @@
 #include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/msi.h>
 #include <linux/slab.h>
 #include <linux/pci_ids.h>
 #include <linux/random.h>
 
 #include <linux/pci-epc.h>
 #include <linux/pci-epf.h>
+#include <linux/pci-ep-msi.h>
 #include <linux/pci_regs.h>
 
 #define IRQ_TYPE_INTX			0
@@ -29,6 +31,8 @@
 #define COMMAND_READ			BIT(3)
 #define COMMAND_WRITE			BIT(4)
 #define COMMAND_COPY			BIT(5)
+#define COMMAND_ENABLE_DOORBELL		BIT(6)
+#define COMMAND_DISABLE_DOORBELL	BIT(7)
 
 #define STATUS_READ_SUCCESS		BIT(0)
 #define STATUS_READ_FAIL		BIT(1)
@@ -39,6 +43,11 @@
 #define STATUS_IRQ_RAISED		BIT(6)
 #define STATUS_SRC_ADDR_INVALID		BIT(7)
 #define STATUS_DST_ADDR_INVALID		BIT(8)
+#define STATUS_DOORBELL_SUCCESS		BIT(9)
+#define STATUS_DOORBELL_ENABLE_SUCCESS	BIT(10)
+#define STATUS_DOORBELL_ENABLE_FAIL	BIT(11)
+#define STATUS_DOORBELL_DISABLE_SUCCESS BIT(12)
+#define STATUS_DOORBELL_DISABLE_FAIL	BIT(13)
 
 #define FLAG_USE_DMA			BIT(0)
 
@@ -74,6 +83,9 @@ struct pci_epf_test_reg {
 	u32	irq_type;
 	u32	irq_number;
 	u32	flags;
+	u32	doorbell_bar;
+	u32	doorbell_offset;
+	u32	doorbell_data;
 } __packed;
 
 static struct pci_epf_header test_header = {
@@ -642,6 +654,117 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test,
 	}
 }
 
+static irqreturn_t pci_epf_test_doorbell_handler(int irq, void *data)
+{
+	struct pci_epf_test *epf_test = data;
+	enum pci_barno test_reg_bar = epf_test->test_reg_bar;
+	struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
+
+	reg->status |= STATUS_DOORBELL_SUCCESS;
+	pci_epf_test_raise_irq(epf_test, reg);
+
+	return IRQ_HANDLED;
+}
+
+static void pci_epf_test_doorbell_cleanup(struct pci_epf_test *epf_test)
+{
+	struct pci_epf_test_reg *reg = epf_test->reg[epf_test->test_reg_bar];
+	struct pci_epf *epf = epf_test->epf;
+
+	if (reg->doorbell_bar > 0) {
+		free_irq(epf->db_msg[0].virq, epf_test);
+		reg->doorbell_bar = NO_BAR;
+	}
+
+	if (epf->db_msg)
+		pci_epf_free_doorbell(epf);
+}
+
+static void pci_epf_test_enable_doorbell(struct pci_epf_test *epf_test,
+					 struct pci_epf_test_reg *reg)
+{
+	struct pci_epf *epf = epf_test->epf;
+	struct pci_epf_bar db_bar = {};
+	struct pci_epc *epc = epf->epc;
+	struct msi_msg *msg;
+	enum pci_barno bar;
+	size_t offset;
+	int ret;
+
+	ret = pci_epf_alloc_doorbell(epf, 1);
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		return;
+	}
+
+	msg = &epf->db_msg[0].msg;
+	bar = pci_epc_get_next_free_bar(epf_test->epc_features, epf_test->test_reg_bar + 1);
+	if (bar < BAR_0 || bar == epf_test->test_reg_bar || !epf->db_msg) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		return;
+	}
+
+	ret = request_irq(epf->db_msg[0].virq, pci_epf_test_doorbell_handler, 0,
+			  "pci-test-doorbell", epf_test);
+	if (ret) {
+		dev_err(&epf->dev,
+			"Failed to request irq %d, doorbell feature is not supported\n",
+			epf->db_msg[0].virq);
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+		return;
+	}
+
+	reg->doorbell_data = msg->data;
+	reg->doorbell_bar = bar;
+
+	msg = &epf->db_msg[0].msg;
+	ret = pci_epf_align_inbound_addr(epf, bar, ((u64)msg->address_hi << 32) | msg->address_lo,
+					 &db_bar.phys_addr, &offset);
+
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+		return;
+	}
+
+	reg->doorbell_offset = offset;
+
+	db_bar.barno = bar;
+	db_bar.size = epf->bar[bar].size;
+	db_bar.flags = epf->bar[bar].flags;
+
+	ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &db_bar);
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+	} else {
+		reg->status |= STATUS_DOORBELL_ENABLE_SUCCESS;
+	}
+}
+
+static void pci_epf_test_disable_doorbell(struct pci_epf_test *epf_test,
+					  struct pci_epf_test_reg *reg)
+{
+	enum pci_barno bar = reg->doorbell_bar;
+	struct pci_epf *epf = epf_test->epf;
+	struct pci_epc *epc = epf->epc;
+	int ret;
+
+	if (bar < BAR_0 || bar == epf_test->test_reg_bar || !epf->db_msg) {
+		reg->status |= STATUS_DOORBELL_DISABLE_FAIL;
+		return;
+	}
+
+	ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &epf->bar[bar]);
+	if (ret)
+		reg->status |= STATUS_DOORBELL_DISABLE_FAIL;
+	else
+		reg->status |= STATUS_DOORBELL_DISABLE_SUCCESS;
+
+	pci_epf_test_doorbell_cleanup(epf_test);
+}
+
 static void pci_epf_test_cmd_handler(struct work_struct *work)
 {
 	u32 command;
@@ -688,6 +811,14 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 		pci_epf_test_copy(epf_test, reg);
 		pci_epf_test_raise_irq(epf_test, reg);
 		break;
+	case COMMAND_ENABLE_DOORBELL:
+		pci_epf_test_enable_doorbell(epf_test, reg);
+		pci_epf_test_raise_irq(epf_test, reg);
+		break;
+	case COMMAND_DISABLE_DOORBELL:
+		pci_epf_test_disable_doorbell(epf_test, reg);
+		pci_epf_test_raise_irq(epf_test, reg);
+		break;
 	default:
 		dev_err(dev, "Invalid command 0x%x\n", command);
 		break;
@@ -934,6 +1065,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
 		pci_epf_test_clean_dma_chan(epf_test);
 		pci_epf_test_clear_bar(epf);
 	}
+	pci_epf_test_doorbell_cleanup(epf_test);
 	pci_epf_test_free_space(epf);
 }
 

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec  4 15:25:56 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 04 Dec 2024 18:25:56 -0500
Subject: [PATCH v10 6/7] misc: pci_endpoint_test: Add doorbell test case
In-Reply-To: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
Message-ID: <20241204-ep-msi-v10-6-87c378dbcd6d@nxp.com>

Add three registers: PCIE_ENDPOINT_TEST_DB_BAR, PCIE_ENDPOINT_TEST_DB_ADDR,
and PCIE_ENDPOINT_TEST_DB_DATA.

Trigger the doorbell by writing data from PCI_ENDPOINT_TEST_DB_DATA to the
address provided by PCI_ENDPOINT_TEST_DB_OFFSET and wait for endpoint
feedback.

Add two command to COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL
to enable EP side's doorbell support and avoid compatible problem, which
host side driver miss-match with endpoint side function driver. See below
table:

		Host side new driver	Host side old driver
EP: new driver		S			F
EP: old driver		F			F

S: If EP side support MSI, 'pcitest -B' return success.
   If EP side doesn't support MSI, the same to 'F'.

F: 'pcitest -B' return failure, other case as usual.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v10
- none

Change from v8 to v9
- change PCITEST_DOORBELL to 0xa

Change form v6 to v8
- none

Change from v5 to v6
- %s/PCI_ENDPOINT_TEST_DB_ADDR/PCI_ENDPOINT_TEST_DB_OFFSET/g

Change from v4 to v5
- remove unused varible
- add irq_type at pci_endpoint_test_doorbell();

change from v3 to v4
- Add COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL.
- Remove new DID requirement.
---
 drivers/misc/pci_endpoint_test.c | 80 ++++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/pcitest.h     |  1 +
 2 files changed, 81 insertions(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 3aaaf47fa4ee2..b3f36b6ba8ba2 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -42,6 +42,8 @@
 #define COMMAND_READ				BIT(3)
 #define COMMAND_WRITE				BIT(4)
 #define COMMAND_COPY				BIT(5)
+#define COMMAND_ENABLE_DOORBELL			BIT(6)
+#define COMMAND_DISABLE_DOORBELL		BIT(7)
 
 #define PCI_ENDPOINT_TEST_STATUS		0x8
 #define STATUS_READ_SUCCESS			BIT(0)
@@ -53,6 +55,11 @@
 #define STATUS_IRQ_RAISED			BIT(6)
 #define STATUS_SRC_ADDR_INVALID			BIT(7)
 #define STATUS_DST_ADDR_INVALID			BIT(8)
+#define STATUS_DOORBELL_SUCCESS			BIT(9)
+#define STATUS_DOORBELL_ENABLE_SUCCESS		BIT(10)
+#define STATUS_DOORBELL_ENABLE_FAIL		BIT(11)
+#define STATUS_DOORBELL_DISABLE_SUCCESS		BIT(12)
+#define STATUS_DOORBELL_DISABLE_FAIL		BIT(13)
 
 #define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR	0x0c
 #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR	0x10
@@ -67,6 +74,10 @@
 #define PCI_ENDPOINT_TEST_IRQ_NUMBER		0x28
 
 #define PCI_ENDPOINT_TEST_FLAGS			0x2c
+#define PCI_ENDPOINT_TEST_DB_BAR		0x30
+#define PCI_ENDPOINT_TEST_DB_OFFSET		0x34
+#define PCI_ENDPOINT_TEST_DB_DATA		0x38
+
 #define FLAG_USE_DMA				BIT(0)
 
 #define PCI_DEVICE_ID_TI_AM654			0xb00c
@@ -108,6 +119,7 @@ enum pci_barno {
 	BAR_3,
 	BAR_4,
 	BAR_5,
+	NO_BAR = -1,
 };
 
 struct pci_endpoint_test {
@@ -746,6 +758,71 @@ static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
 	return false;
 }
 
+static bool pci_endpoint_test_doorbell(struct pci_endpoint_test *test)
+{
+	struct pci_dev *pdev = test->pdev;
+	struct device *dev = &pdev->dev;
+	int irq_type = test->irq_type;
+	enum pci_barno bar;
+	u32 data, status;
+	u32 addr;
+
+	if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
+		dev_err(dev, "Invalid IRQ type option\n");
+		return false;
+	}
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
+				 COMMAND_ENABLE_DOORBELL);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+	if (status & STATUS_DOORBELL_ENABLE_FAIL) {
+		dev_err(dev, "Failed to enable doorbell\n");
+		return false;
+	}
+
+	data = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_DATA);
+	addr = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_OFFSET);
+	bar = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_BAR);
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS, 0);
+
+	bar = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_BAR);
+
+	writel(data, test->bar[bar] + addr);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+
+	if (!(status & STATUS_DOORBELL_SUCCESS))
+		dev_err(dev, "Endpoint have not received Doorbell\n");
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
+				 COMMAND_DISABLE_DOORBELL);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status |= pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+
+	if (status & STATUS_DOORBELL_DISABLE_FAIL) {
+		dev_err(dev, "Failed to disable doorbell\n");
+		return false;
+	}
+
+	if (!(status & STATUS_DOORBELL_SUCCESS))
+		return false;
+
+	return true;
+}
+
 static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 				    unsigned long arg)
 {
@@ -793,6 +870,9 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 	case PCITEST_CLEAR_IRQ:
 		ret = pci_endpoint_test_clear_irq(test);
 		break;
+	case PCITEST_DOORBELL:
+		ret = pci_endpoint_test_doorbell(test);
+		break;
 	}
 
 ret:
diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h
index 94b46b043b536..b82e7f2ed937d 100644
--- a/include/uapi/linux/pcitest.h
+++ b/include/uapi/linux/pcitest.h
@@ -20,6 +20,7 @@
 #define PCITEST_MSIX		_IOW('P', 0x7, int)
 #define PCITEST_SET_IRQTYPE	_IOW('P', 0x8, int)
 #define PCITEST_GET_IRQTYPE	_IO('P', 0x9)
+#define PCITEST_DOORBELL	_IO('P', 0xa)
 #define PCITEST_CLEAR_IRQ	_IO('P', 0x10)
 
 #define PCITEST_FLAGS_USE_DMA	0x00000001

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec  4 15:25:57 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 04 Dec 2024 18:25:57 -0500
Subject: [PATCH v10 7/7] tools: PCI: Add 'B' option for test doorbell
In-Reply-To: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
Message-ID: <20241204-ep-msi-v10-7-87c378dbcd6d@nxp.com>

Add doorbell test support.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v3 to v10
- none
---
 tools/pci/pcitest.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 7b530d838d408..fcff0224a3381 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -34,6 +34,7 @@ struct pci_test {
 	bool		copy;
 	unsigned long	size;
 	bool		use_dma;
+	bool		doorbell;
 };
 
 static int run_test(struct pci_test *test)
@@ -147,6 +148,15 @@ static int run_test(struct pci_test *test)
 			fprintf(stdout, "%s\n", result[ret]);
 	}
 
+	if (test->doorbell) {
+		ret = ioctl(fd, PCITEST_DOORBELL, 0);
+		fprintf(stdout, "Ringing doorbell on the EP\t\t");
+		if (ret < 0)
+			fprintf(stdout, "TEST FAILED\n");
+		else
+			fprintf(stdout, "%s\n", result[ret]);
+	}
+
 	fflush(stdout);
 	close(fd);
 	return (ret < 0) ? ret : 1 - ret; /* return 0 if test succeeded */
@@ -172,7 +182,7 @@ int main(int argc, char **argv)
 	/* set default endpoint device */
 	test->device = "/dev/pci-endpoint-test.0";
 
-	while ((c = getopt(argc, argv, "D:b:m:x:i:deIlhrwcs:")) != EOF)
+	while ((c = getopt(argc, argv, "D:b:m:x:i:BdeIlhrwcs:")) != EOF)
 	switch (c) {
 	case 'D':
 		test->device = optarg;
@@ -222,6 +232,9 @@ int main(int argc, char **argv)
 	case 'd':
 		test->use_dma = true;
 		continue;
+	case 'B':
+		test->doorbell = true;
+		continue;
 	case 'h':
 	default:
 usage:
@@ -241,6 +254,7 @@ int main(int argc, char **argv)
 			"\t-w			Write buffer test\n"
 			"\t-c			Copy buffer test\n"
 			"\t-s <size>		Size of buffer {default: 100KB}\n"
+			"\t-B			Doorbell test\n"
 			"\t-h			Print this help message\n",
 			argv[0]);
 		return -EINVAL;

-- 
2.34.1



From quic_abhinavk at quicinc.com  Wed Dec  4 15:26:18 2024
From: quic_abhinavk at quicinc.com (Abhinav Kumar)
Date: Wed, 4 Dec 2024 15:26:18 -0800
Subject: [PATCH 07/10] drm/msm/dp: use eld_mutex to protect access to
 connector->eld
In-Reply-To: <n2zmw4wquxzht6gvlx6yjurpobgwlsryh75n5gw65j5vjclhgr@jqubqjispqsr>
References: <20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03@linaro.org>
 <20241201-drm-connector-eld-mutex-v1-7-ba56a6545c03@linaro.org>
 <ca906dc4-ac72-4a76-a670-36c011c853c9@quicinc.com>
 <n2zmw4wquxzht6gvlx6yjurpobgwlsryh75n5gw65j5vjclhgr@jqubqjispqsr>
Message-ID: <c4c3dd96-727b-4be1-9152-e384478a7508@quicinc.com>



On 12/3/2024 5:58 AM, Dmitry Baryshkov wrote:
> On Mon, Dec 02, 2024 at 07:27:45PM -0800, Abhinav Kumar wrote:
>>
>>
>> On 11/30/2024 3:55 PM, Dmitry Baryshkov wrote:
>>> Reading access to connector->eld can happen at the same time the
>>> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
>>> order to protect connector->eld from concurrent access.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>> ---
>>>    drivers/gpu/drm/msm/dp/dp_audio.c | 2 ++
>>>    1 file changed, 2 insertions(+)
>>>
>>
>> Reviewed-by: Abhinav Kumar <quic_abhinavk at quicinc.com>
> 
> Ack to merge through drm-misc?
> 

Yes,

Acked-by: Abhinav Kumar <quic_abhinavk at quicinc.com>


From sashal at kernel.org  Wed Dec  4 14:15:55 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 17:15:55 -0500
Subject: [PATCH AUTOSEL 6.12 01/15] usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag
Message-ID: <20241204221627.2247598-1-sashal@kernel.org>

From: Xu Yang <xu.yang_2 at nxp.com>

[ Upstream commit ec841b8d73cff37f8960e209017efe1eb2fb21f2 ]

Currently, the imx deivice controller has below limitations:

1. can't generate short packet interrupt if IOC not set in dTD. So if one
   request span more than one dTDs and only the last dTD set IOC, the usb
   request will pending there if no more data comes.
2. the controller can't accurately deliver data to differtent usb requests
   in some cases due to short packet. For example: one usb request span 3
   dTDs, then if the controller received a short packet the next packet
   will go to 2nd dTD of current request rather than the first dTD of next
   request.
3. can't build a bus packet use multiple dTDs. For example: controller
   needs to send one packet of 512 bytes use dTD1 (200 bytes) + dTD2
   (312 bytes), actually the host side will see 200 bytes short packet.

Based on these limits, add CI_HDRC_HAS_SHORT_PKT_LIMIT flag and use it on
imx platforms.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
Acked-by: Peter Chen <peter.chen at kernel.org>
Link: https://lore.kernel.org/r/20240923081203.2851768-1-xu.yang_2 at nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/chipidea/ci.h          | 1 +
 drivers/usb/chipidea/ci_hdrc_imx.c | 1 +
 drivers/usb/chipidea/core.c        | 2 ++
 include/linux/usb/chipidea.h       | 1 +
 4 files changed, 5 insertions(+)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 2a38e1eb65466..e4b003d060c26 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -260,6 +260,7 @@ struct ci_hdrc {
 	bool				b_sess_valid_event;
 	bool				imx28_write_fix;
 	bool				has_portsc_pec_bug;
+	bool				has_short_pkt_limit;
 	bool				supports_runtime_pm;
 	bool				in_lpm;
 	bool				wakeup_int;
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index c64ab0e07ea03..17b3ac2ac8a1e 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -342,6 +342,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 	struct ci_hdrc_platform_data pdata = {
 		.name		= dev_name(&pdev->dev),
 		.capoffset	= DEF_CAPOFFSET,
+		.flags		= CI_HDRC_HAS_SHORT_PKT_LIMIT,
 		.notify_event	= ci_hdrc_imx_notify_event,
 	};
 	int ret;
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 835bf2428dc6e..5aa16dbfc289c 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -1076,6 +1076,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		CI_HDRC_SUPPORTS_RUNTIME_PM);
 	ci->has_portsc_pec_bug = !!(ci->platdata->flags &
 		CI_HDRC_HAS_PORTSC_PEC_MISSED);
+	ci->has_short_pkt_limit = !!(ci->platdata->flags &
+		CI_HDRC_HAS_SHORT_PKT_LIMIT);
 	platform_set_drvdata(pdev, ci);
 
 	ret = hw_device_init(ci, base);
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 5a7f96684ea22..ebdfef124b2bc 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -65,6 +65,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_PHY_VBUS_CONTROL	BIT(16)
 #define CI_HDRC_HAS_PORTSC_PEC_MISSED	BIT(17)
 #define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS	BIT(18)
+#define	CI_HDRC_HAS_SHORT_PKT_LIMIT	BIT(19)
 	enum usb_dr_mode	dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT		0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 14:16:02 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 17:16:02 -0500
Subject: [PATCH AUTOSEL 6.12 08/15] drm: display: Set fwnode for aux bus devices
In-Reply-To: <20241204221627.2247598-1-sashal@kernel.org>
References: <20241204221627.2247598-1-sashal@kernel.org>
Message-ID: <20241204221627.2247598-8-sashal@kernel.org>

From: Saravana Kannan <saravanak at google.com>

[ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]

fwnode needs to be set for a device for fw_devlink to be able to
track/enforce its dependencies correctly. Without this, you'll see error
messages like this when the supplier has probed and tries to make sure
all its fwnode consumers are linked to it using device links:

mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0

Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
Signed-off-by: Saravana Kannan <saravanak at google.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reviewed-by: Thierry Reding <treding at nvidia.com>
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c
index d810529ebfb6e..ec7eac6b595f7 100644
--- a/drivers/gpu/drm/display/drm_dp_aux_bus.c
+++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c
@@ -292,7 +292,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux,
 	aux_ep->dev.parent = aux->dev;
 	aux_ep->dev.bus = &dp_aux_bus_type;
 	aux_ep->dev.type = &dp_aux_device_type_type;
-	aux_ep->dev.of_node = of_node_get(np);
+	device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np)));
 	dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev));
 
 	ret = device_register(&aux_ep->dev);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 14:16:55 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 17:16:55 -0500
Subject: [PATCH AUTOSEL 6.11 01/15] usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag
Message-ID: <20241204221726.2247988-1-sashal@kernel.org>

From: Xu Yang <xu.yang_2 at nxp.com>

[ Upstream commit ec841b8d73cff37f8960e209017efe1eb2fb21f2 ]

Currently, the imx deivice controller has below limitations:

1. can't generate short packet interrupt if IOC not set in dTD. So if one
   request span more than one dTDs and only the last dTD set IOC, the usb
   request will pending there if no more data comes.
2. the controller can't accurately deliver data to differtent usb requests
   in some cases due to short packet. For example: one usb request span 3
   dTDs, then if the controller received a short packet the next packet
   will go to 2nd dTD of current request rather than the first dTD of next
   request.
3. can't build a bus packet use multiple dTDs. For example: controller
   needs to send one packet of 512 bytes use dTD1 (200 bytes) + dTD2
   (312 bytes), actually the host side will see 200 bytes short packet.

Based on these limits, add CI_HDRC_HAS_SHORT_PKT_LIMIT flag and use it on
imx platforms.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
Acked-by: Peter Chen <peter.chen at kernel.org>
Link: https://lore.kernel.org/r/20240923081203.2851768-1-xu.yang_2 at nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/chipidea/ci.h          | 1 +
 drivers/usb/chipidea/ci_hdrc_imx.c | 1 +
 drivers/usb/chipidea/core.c        | 2 ++
 include/linux/usb/chipidea.h       | 1 +
 4 files changed, 5 insertions(+)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 2a38e1eb65466..e4b003d060c26 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -260,6 +260,7 @@ struct ci_hdrc {
 	bool				b_sess_valid_event;
 	bool				imx28_write_fix;
 	bool				has_portsc_pec_bug;
+	bool				has_short_pkt_limit;
 	bool				supports_runtime_pm;
 	bool				in_lpm;
 	bool				wakeup_int;
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index bdc04ce919f7a..b76e7c3fa2c6e 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -342,6 +342,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 	struct ci_hdrc_platform_data pdata = {
 		.name		= dev_name(&pdev->dev),
 		.capoffset	= DEF_CAPOFFSET,
+		.flags		= CI_HDRC_HAS_SHORT_PKT_LIMIT,
 		.notify_event	= ci_hdrc_imx_notify_event,
 	};
 	int ret;
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 835bf2428dc6e..5aa16dbfc289c 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -1076,6 +1076,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		CI_HDRC_SUPPORTS_RUNTIME_PM);
 	ci->has_portsc_pec_bug = !!(ci->platdata->flags &
 		CI_HDRC_HAS_PORTSC_PEC_MISSED);
+	ci->has_short_pkt_limit = !!(ci->platdata->flags &
+		CI_HDRC_HAS_SHORT_PKT_LIMIT);
 	platform_set_drvdata(pdev, ci);
 
 	ret = hw_device_init(ci, base);
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 5a7f96684ea22..ebdfef124b2bc 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -65,6 +65,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_PHY_VBUS_CONTROL	BIT(16)
 #define CI_HDRC_HAS_PORTSC_PEC_MISSED	BIT(17)
 #define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS	BIT(18)
+#define	CI_HDRC_HAS_SHORT_PKT_LIMIT	BIT(19)
 	enum usb_dr_mode	dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT		0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 14:17:02 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 17:17:02 -0500
Subject: [PATCH AUTOSEL 6.11 08/15] drm: display: Set fwnode for aux bus devices
In-Reply-To: <20241204221726.2247988-1-sashal@kernel.org>
References: <20241204221726.2247988-1-sashal@kernel.org>
Message-ID: <20241204221726.2247988-8-sashal@kernel.org>

From: Saravana Kannan <saravanak at google.com>

[ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]

fwnode needs to be set for a device for fw_devlink to be able to
track/enforce its dependencies correctly. Without this, you'll see error
messages like this when the supplier has probed and tries to make sure
all its fwnode consumers are linked to it using device links:

mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0

Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
Signed-off-by: Saravana Kannan <saravanak at google.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reviewed-by: Thierry Reding <treding at nvidia.com>
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c
index d810529ebfb6e..ec7eac6b595f7 100644
--- a/drivers/gpu/drm/display/drm_dp_aux_bus.c
+++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c
@@ -292,7 +292,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux,
 	aux_ep->dev.parent = aux->dev;
 	aux_ep->dev.bus = &dp_aux_bus_type;
 	aux_ep->dev.type = &dp_aux_device_type_type;
-	aux_ep->dev.of_node = of_node_get(np);
+	device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np)));
 	dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev));
 
 	ret = device_register(&aux_ep->dev);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 14:18:02 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 17:18:02 -0500
Subject: [PATCH AUTOSEL 6.6 04/10] drm: display: Set fwnode for aux bus devices
In-Reply-To: <20241204221820.2248367-1-sashal@kernel.org>
References: <20241204221820.2248367-1-sashal@kernel.org>
Message-ID: <20241204221820.2248367-4-sashal@kernel.org>

From: Saravana Kannan <saravanak at google.com>

[ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]

fwnode needs to be set for a device for fw_devlink to be able to
track/enforce its dependencies correctly. Without this, you'll see error
messages like this when the supplier has probed and tries to make sure
all its fwnode consumers are linked to it using device links:

mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0

Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
Signed-off-by: Saravana Kannan <saravanak at google.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reviewed-by: Thierry Reding <treding at nvidia.com>
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c
index 8a165be1a8214..d15c0f184983b 100644
--- a/drivers/gpu/drm/display/drm_dp_aux_bus.c
+++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c
@@ -292,7 +292,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux,
 	aux_ep->dev.parent = aux->dev;
 	aux_ep->dev.bus = &dp_aux_bus_type;
 	aux_ep->dev.type = &dp_aux_device_type_type;
-	aux_ep->dev.of_node = of_node_get(np);
+	device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np)));
 	dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev));
 
 	ret = device_register(&aux_ep->dev);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 14:18:46 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 17:18:46 -0500
Subject: [PATCH AUTOSEL 6.1 4/8] drm: display: Set fwnode for aux bus devices
In-Reply-To: <20241204221859.2248634-1-sashal@kernel.org>
References: <20241204221859.2248634-1-sashal@kernel.org>
Message-ID: <20241204221859.2248634-4-sashal@kernel.org>

From: Saravana Kannan <saravanak at google.com>

[ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]

fwnode needs to be set for a device for fw_devlink to be able to
track/enforce its dependencies correctly. Without this, you'll see error
messages like this when the supplier has probed and tries to make sure
all its fwnode consumers are linked to it using device links:

mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0

Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
Signed-off-by: Saravana Kannan <saravanak at google.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reviewed-by: Thierry Reding <treding at nvidia.com>
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c
index f5741b45ca077..951170e1d5d14 100644
--- a/drivers/gpu/drm/display/drm_dp_aux_bus.c
+++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c
@@ -287,7 +287,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux,
 	aux_ep->dev.parent = aux->dev;
 	aux_ep->dev.bus = &dp_aux_bus_type;
 	aux_ep->dev.type = &dp_aux_device_type_type;
-	aux_ep->dev.of_node = of_node_get(np);
+	device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np)));
 	dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev));
 
 	ret = device_register(&aux_ep->dev);
-- 
2.43.0



From sashal at kernel.org  Wed Dec  4 14:23:21 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 17:23:21 -0500
Subject: [PATCH AUTOSEL 6.12 5/8] irqchip/gicv3-its: Add workaround for hip09 ITS erratum 162100801
In-Reply-To: <20241204222334.2249307-1-sashal@kernel.org>
References: <20241204222334.2249307-1-sashal@kernel.org>
Message-ID: <20241204222334.2249307-5-sashal@kernel.org>

From: Zhou Wang <wangzhou1 at hisilicon.com>

[ Upstream commit f82e62d470cc990ebd9d691f931dd418e4e9cea9 ]

When enabling GICv4.1 in hip09, VMAPP fails to clear some caches during
the unmap operation, which can causes vSGIs to be lost.

To fix the issue, invalidate the related vPE cache through GICR_INVALLR
after VMOVP.

Suggested-by: Marc Zyngier <maz at kernel.org>
Co-developed-by: Nianyao Tang <tangnianyao at huawei.com>
Signed-off-by: Nianyao Tang <tangnianyao at huawei.com>
Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/arch/arm64/silicon-errata.rst |  2 +
 arch/arm64/Kconfig                          | 11 +++++
 drivers/irqchip/irq-gic-v3-its.c            | 50 ++++++++++++++++-----
 3 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index 65bfab1b18614..77db10e944f03 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -258,6 +258,8 @@ stable kernels.
 | Hisilicon      | Hip{08,09,10,10C| #162001900      | N/A                         |
 |                | ,11} SMMU PMCG  |                 |                             |
 +----------------+-----------------+-----------------+-----------------------------+
+| Hisilicon      | Hip09           | #162100801      | HISILICON_ERRATUM_162100801 |
++----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
 | Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
 +----------------+-----------------+-----------------+-----------------------------+
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 22f8a7bca6d21..a11a7a42edbfb 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1232,6 +1232,17 @@ config HISILICON_ERRATUM_161600802
 
 	  If unsure, say Y.
 
+config HISILICON_ERRATUM_162100801
+	bool "Hip09 162100801 erratum support"
+	default y
+	help
+	  When enabling GICv4.1 in hip09, VMAPP will fail to clear some caches
+	  during unmapping operation, which will cause some vSGIs lost.
+	  To fix the issue, invalidate related vPE cache through GICR_INVALLR
+	  after VMOVP.
+
+	  If unsure, say Y.
+
 config QCOM_FALKOR_ERRATUM_1003
 	bool "Falkor E1003: Incorrect translation due to ASID change"
 	default y
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 52f625e07658c..d9b6ec844cdda 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -44,6 +44,7 @@
 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375	(1ULL << 1)
 #define ITS_FLAGS_WORKAROUND_CAVIUM_23144	(1ULL << 2)
 #define ITS_FLAGS_FORCE_NON_SHAREABLE		(1ULL << 3)
+#define ITS_FLAGS_WORKAROUND_HISILICON_162100801	(1ULL << 4)
 
 #define RD_LOCAL_LPI_ENABLED                    BIT(0)
 #define RD_LOCAL_PENDTABLE_PREALLOCATED         BIT(1)
@@ -61,6 +62,7 @@ static u32 lpi_id_bits;
 #define LPI_PENDBASE_SZ		ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
 
 static u8 __ro_after_init lpi_prop_prio;
+static struct its_node *find_4_1_its(void);
 
 /*
  * Collection structure - just an ID, and a redistributor address to
@@ -3797,6 +3799,20 @@ static void its_vpe_db_proxy_move(struct its_vpe *vpe, int from, int to)
 	raw_spin_unlock_irqrestore(&vpe_proxy.lock, flags);
 }
 
+static void its_vpe_4_1_invall_locked(int cpu, struct its_vpe *vpe)
+{
+	void __iomem *rdbase;
+	u64 val;
+
+	val  = GICR_INVALLR_V;
+	val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id);
+
+	guard(raw_spinlock)(&gic_data_rdist_cpu(cpu)->rd_lock);
+	rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
+	gic_write_lpir(val, rdbase + GICR_INVALLR);
+	wait_for_syncr(rdbase);
+}
+
 static int its_vpe_set_affinity(struct irq_data *d,
 				const struct cpumask *mask_val,
 				bool force)
@@ -3804,6 +3820,7 @@ static int its_vpe_set_affinity(struct irq_data *d,
 	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
 	unsigned int from, cpu = nr_cpu_ids;
 	struct cpumask *table_mask;
+	struct its_node *its;
 	unsigned long flags;
 
 	/*
@@ -3866,6 +3883,11 @@ static int its_vpe_set_affinity(struct irq_data *d,
 	vpe->col_idx = cpu;
 
 	its_send_vmovp(vpe);
+
+	its = find_4_1_its();
+	if (its && its->flags & ITS_FLAGS_WORKAROUND_HISILICON_162100801)
+		its_vpe_4_1_invall_locked(cpu, vpe);
+
 	its_vpe_db_proxy_move(vpe, from, cpu);
 
 out:
@@ -4173,22 +4195,12 @@ static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
 
 static void its_vpe_4_1_invall(struct its_vpe *vpe)
 {
-	void __iomem *rdbase;
 	unsigned long flags;
-	u64 val;
 	int cpu;
 
-	val  = GICR_INVALLR_V;
-	val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id);
-
 	/* Target the redistributor this vPE is currently known on */
 	cpu = vpe_to_cpuid_lock(vpe, &flags);
-	raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock);
-	rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
-	gic_write_lpir(val, rdbase + GICR_INVALLR);
-
-	wait_for_syncr(rdbase);
-	raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock);
+	its_vpe_4_1_invall_locked(cpu, vpe);
 	vpe_to_cpuid_unlock(vpe, flags);
 }
 
@@ -4781,6 +4793,14 @@ static bool its_set_non_coherent(void *data)
 	return true;
 }
 
+static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data)
+{
+	struct its_node *its = data;
+
+	its->flags |= ITS_FLAGS_WORKAROUND_HISILICON_162100801;
+	return true;
+}
+
 static const struct gic_quirk its_quirks[] = {
 #ifdef CONFIG_CAVIUM_ERRATUM_22375
 	{
@@ -4827,6 +4847,14 @@ static const struct gic_quirk its_quirks[] = {
 		.init	= its_enable_quirk_hip07_161600802,
 	},
 #endif
+#ifdef CONFIG_HISILICON_ERRATUM_162100801
+	{
+		.desc	= "ITS: Hip09 erratum 162100801",
+		.iidr	= 0x00051736,
+		.mask	= 0xffffffff,
+		.init	= its_enable_quirk_hip09_162100801,
+	},
+#endif
 #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
 	{
 		.desc   = "ITS: Rockchip erratum RK3588001",
-- 
2.43.0



From quic_molvera at quicinc.com  Wed Dec  4 15:18:01 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 4 Dec 2024 15:18:01 -0800
Subject: [PATCH v3 1/7] dt-bindings: arm: qcom: Document SM8750 SoC and
 boards
In-Reply-To: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
Message-ID: <20241204-sm8750_master_dt-v3-1-4d5a8269950b@quicinc.com>

Document the SM8750 SoC binding and the boards which use it.

Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/qcom.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index d394dffe3fba5a396b85a6093f34e9ef62b6f9cc..f42442993045a648ce61e92a5b10c48ee37750e8 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -97,6 +97,7 @@ description: |
         sm8450
         sm8550
         sm8650
+        sm8750
         x1e78100
         x1e80100
 
@@ -1099,6 +1100,12 @@ properties:
               - qcom,sm8650-qrd
           - const: qcom,sm8650
 
+      - items:
+          - enum:
+              - qcom,sm8750-mtp
+              - qcom,sm8750-qrd
+          - const: qcom,sm8750
+
       - items:
           - enum:
               - qcom,x1e001de-devkit

-- 
2.46.1



From quic_molvera at quicinc.com  Wed Dec  4 15:18:00 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 4 Dec 2024 15:18:00 -0800
Subject: [PATCH v3 0/7] dts: qcom: Introduce SM8750 device trees
Message-ID: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>

This series adds the initial device tree support for the SM8750 SoCs
needed to boot to shell. This specifically adds support for clocks,
pinctrl, rpmhpd, regulators, interconnects, and SoC and board
compatibles.

The Qualcomm Technologies, Inc. SM8750 SoC is the latest in the line of
consumer mobile device SoCs. See more at:
https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/images/company/news-media/media-center/press-kits/snapdragon-summit-2024/day-1/documents/Snapdragon8EliteProductBrief.pdf

Dependencies:
clks: https://lore.kernel.org/all/20241204-sm8750_master_clks-v3-0-1a8f31a53a86 at quicinc.com/
interconnects: https://lore.kernel.org/all/20241204-sm8750_master_interconnects-v3-0-3d9aad4200e9 at quicinc.com/
pinctrl (applied): https://lore.kernel.org/all/20241112002843.2804490-1-quic_molvera at quicinc.com/
regulators (applied): https://lore.kernel.org/all/20241112002645.2803506-1-quic_molvera at quicinc.com/
power domains (applied): https://lore.kernel.org/all/20241112002444.2802092-1-quic_molvera at quicinc.com/
misc bindings:
- https://lore.kernel.org/all/20241204-sm8750_master_smmu-v2-1-9e73e3fc15f2 at quicinc.com/
- https://lore.kernel.org/all/20241204-sm8750_master_pdc-v1-1-3a06cb62a28f at quicinc.com/
applied bindings:
- https://lore.kernel.org/all/20241021230427.2632466-1-quic_molvera at quicinc.com/
- https://lore.kernel.org/all/20241112003544.2807368-1-quic_molvera at quicinc.com/
- https://lore.kernel.org/all/20241021230500.2632527-1-quic_molvera at quicinc.com/

Changes in V3:
- split PMD8028 PMIC and PMIH0108 PMIC into two patches
- added critical trips for PMD8028 and PMIH0108
- updated commit msgs to all use uppercase for names
- updated cpu idle states in dt to follow previous conventions
- enabled msi-controller at 16040000
- reordered gcc clocks to match bindings 

Changes in V2:
- split dts and dtsi patches into separate patches
- changed eusb-repeater to phy
- removed empty chosen node
- lowercased phandles in dtsi
- added system-wide domain idle state
- added leading zeroes to applicable regs
- corrected gpio ranges
- removed some unnecessary comments
- updated timer size cells
- separated pmics & thermal zones into their own file
- added chassis type to board files
- added reserved tlmm nodes to board files
- corrected regulator-0 supplies in board files

Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
---
Melody Olvera (7):
      dt-bindings: arm: qcom: Document SM8750 SoC and boards
      arm64: dts: qcom: Add PMD8028 PMIC
      arm64: dts: qcom: Add PMIH0108 PMIC
      arm64: dts: qcom: Add base SM8750 dtsi
      arm64: dts: qcom: sm8750: Add pmic dtsi
      arm64: dts: qcom: Add board dts files for SM8750 MTP and QRD
      arm64: defconfig: Enable SM8750 SoC base configs

 Documentation/devicetree/bindings/arm/qcom.yaml |    7 +
 arch/arm64/boot/dts/qcom/Makefile               |    2 +
 arch/arm64/boot/dts/qcom/pmd8028.dtsi           |   62 +
 arch/arm64/boot/dts/qcom/pmih0108.dtsi          |   68 +
 arch/arm64/boot/dts/qcom/sm8750-mtp.dts         |  794 +++++++
 arch/arm64/boot/dts/qcom/sm8750-pmics.dtsi      |  188 ++
 arch/arm64/boot/dts/qcom/sm8750-qrd.dts         |  792 ++++++
 arch/arm64/boot/dts/qcom/sm8750.dtsi            | 2907 +++++++++++++++++++++++
 arch/arm64/configs/defconfig                    |    4 +
 9 files changed, 4824 insertions(+)
---
base-commit: ed2e49e900fcf3ea198df034facb67bf8d99f44e
change-id: 20241204-sm8750_master_dt-16c23db0d836
prerequisite-change-id: 20241204-sm8750_master_interconnects-5089c590dfe5:v3
prerequisite-patch-id: 2129d2b0d43098012e7e63a728971870eda5a891
prerequisite-patch-id: a4c4f081f8e050b93f33730fa63af4e8413834bf
prerequisite-change-id: 20241204-sm8750_master_clks-e26e1b9416b6:v3
prerequisite-patch-id: 6746978c15f8c943df3ca44013b1692668d7c60a
prerequisite-patch-id: ac3e8d8cbeac3f1a77f8d54751063dba61642a01
prerequisite-patch-id: e0affb2c25d8c566c875994970503aa446983ea7
prerequisite-patch-id: 70df483173f5546f676427883505bd135663583b
prerequisite-patch-id: 8897202725dcee6119e018c8c3c11dcc2a5337ef
prerequisite-patch-id: 5e652ef99d655ab31e4c86cabb7fd58b03ad7437
prerequisite-patch-id: 551a78c20b5320c0d51b262f5de9772d8f554d0a
prerequisite-patch-id: a4db6036b69abd4f25ec8d44a9919e8a1b5fb7da
prerequisite-change-id: 20241204-sm8750_master_smmu-0867ab939686:v2
prerequisite-patch-id: 05669e3fd6558fd8a03082bb0c42347cc74e4b4c
prerequisite-change-id: 20241204-sm8750_master_pdc-275e5a003eec:v1
prerequisite-patch-id: e02a35925d37a2e61abbf240cc8963208f54e1c0

Best regards,
-- 
Melody Olvera <quic_molvera at quicinc.com>



From sashal at kernel.org  Wed Dec  4 14:23:46 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  4 Dec 2024 17:23:46 -0500
Subject: [PATCH AUTOSEL 6.11 4/7] irqchip/gicv3-its: Add workaround for hip09 ITS erratum 162100801
In-Reply-To: <20241204222402.2249702-1-sashal@kernel.org>
References: <20241204222402.2249702-1-sashal@kernel.org>
Message-ID: <20241204222402.2249702-4-sashal@kernel.org>

From: Zhou Wang <wangzhou1 at hisilicon.com>

[ Upstream commit f82e62d470cc990ebd9d691f931dd418e4e9cea9 ]

When enabling GICv4.1 in hip09, VMAPP fails to clear some caches during
the unmap operation, which can causes vSGIs to be lost.

To fix the issue, invalidate the related vPE cache through GICR_INVALLR
after VMOVP.

Suggested-by: Marc Zyngier <maz at kernel.org>
Co-developed-by: Nianyao Tang <tangnianyao at huawei.com>
Signed-off-by: Nianyao Tang <tangnianyao at huawei.com>
Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/arch/arm64/silicon-errata.rst |  2 +
 arch/arm64/Kconfig                          | 11 +++++
 drivers/irqchip/irq-gic-v3-its.c            | 50 ++++++++++++++++-----
 3 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index 8cd4f365044b6..8cf9187e435dd 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -258,6 +258,8 @@ stable kernels.
 | Hisilicon      | Hip08 SMMU PMCG | #162001900      | N/A                         |
 |                | Hip09 SMMU PMCG |                 |                             |
 +----------------+-----------------+-----------------+-----------------------------+
+| Hisilicon      | Hip09           | #162100801      | HISILICON_ERRATUM_162100801 |
++----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
 | Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
 +----------------+-----------------+-----------------+-----------------------------+
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7d92c0a9c43d4..c5b7835f567c3 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1215,6 +1215,17 @@ config HISILICON_ERRATUM_161600802
 
 	  If unsure, say Y.
 
+config HISILICON_ERRATUM_162100801
+	bool "Hip09 162100801 erratum support"
+	default y
+	help
+	  When enabling GICv4.1 in hip09, VMAPP will fail to clear some caches
+	  during unmapping operation, which will cause some vSGIs lost.
+	  To fix the issue, invalidate related vPE cache through GICR_INVALLR
+	  after VMOVP.
+
+	  If unsure, say Y.
+
 config QCOM_FALKOR_ERRATUM_1003
 	bool "Falkor E1003: Incorrect translation due to ASID change"
 	default y
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index ab597e74ba08e..80676aa1c6ab5 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -44,6 +44,7 @@
 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375	(1ULL << 1)
 #define ITS_FLAGS_WORKAROUND_CAVIUM_23144	(1ULL << 2)
 #define ITS_FLAGS_FORCE_NON_SHAREABLE		(1ULL << 3)
+#define ITS_FLAGS_WORKAROUND_HISILICON_162100801	(1ULL << 4)
 
 #define RD_LOCAL_LPI_ENABLED                    BIT(0)
 #define RD_LOCAL_PENDTABLE_PREALLOCATED         BIT(1)
@@ -61,6 +62,7 @@ static u32 lpi_id_bits;
 #define LPI_PENDBASE_SZ		ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
 
 static u8 __ro_after_init lpi_prop_prio;
+static struct its_node *find_4_1_its(void);
 
 /*
  * Collection structure - just an ID, and a redistributor address to
@@ -3797,6 +3799,20 @@ static void its_vpe_db_proxy_move(struct its_vpe *vpe, int from, int to)
 	raw_spin_unlock_irqrestore(&vpe_proxy.lock, flags);
 }
 
+static void its_vpe_4_1_invall_locked(int cpu, struct its_vpe *vpe)
+{
+	void __iomem *rdbase;
+	u64 val;
+
+	val  = GICR_INVALLR_V;
+	val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id);
+
+	guard(raw_spinlock)(&gic_data_rdist_cpu(cpu)->rd_lock);
+	rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
+	gic_write_lpir(val, rdbase + GICR_INVALLR);
+	wait_for_syncr(rdbase);
+}
+
 static int its_vpe_set_affinity(struct irq_data *d,
 				const struct cpumask *mask_val,
 				bool force)
@@ -3804,6 +3820,7 @@ static int its_vpe_set_affinity(struct irq_data *d,
 	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
 	unsigned int from, cpu = nr_cpu_ids;
 	struct cpumask *table_mask;
+	struct its_node *its;
 	unsigned long flags;
 
 	/*
@@ -3856,6 +3873,11 @@ static int its_vpe_set_affinity(struct irq_data *d,
 	vpe->col_idx = cpu;
 
 	its_send_vmovp(vpe);
+
+	its = find_4_1_its();
+	if (its && its->flags & ITS_FLAGS_WORKAROUND_HISILICON_162100801)
+		its_vpe_4_1_invall_locked(cpu, vpe);
+
 	its_vpe_db_proxy_move(vpe, from, cpu);
 
 out:
@@ -4163,22 +4185,12 @@ static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
 
 static void its_vpe_4_1_invall(struct its_vpe *vpe)
 {
-	void __iomem *rdbase;
 	unsigned long flags;
-	u64 val;
 	int cpu;
 
-	val  = GICR_INVALLR_V;
-	val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id);
-
 	/* Target the redistributor this vPE is currently known on */
 	cpu = vpe_to_cpuid_lock(vpe, &flags);
-	raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock);
-	rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
-	gic_write_lpir(val, rdbase + GICR_INVALLR);
-
-	wait_for_syncr(rdbase);
-	raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock);
+	its_vpe_4_1_invall_locked(cpu, vpe);
 	vpe_to_cpuid_unlock(vpe, flags);
 }
 
@@ -4771,6 +4783,14 @@ static bool its_set_non_coherent(void *data)
 	return true;
 }
 
+static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data)
+{
+	struct its_node *its = data;
+
+	its->flags |= ITS_FLAGS_WORKAROUND_HISILICON_162100801;
+	return true;
+}
+
 static const struct gic_quirk its_quirks[] = {
 #ifdef CONFIG_CAVIUM_ERRATUM_22375
 	{
@@ -4817,6 +4837,14 @@ static const struct gic_quirk its_quirks[] = {
 		.init	= its_enable_quirk_hip07_161600802,
 	},
 #endif
+#ifdef CONFIG_HISILICON_ERRATUM_162100801
+	{
+		.desc	= "ITS: Hip09 erratum 162100801",
+		.iidr	= 0x00051736,
+		.mask	= 0xffffffff,
+		.init	= its_enable_quirk_hip09_162100801,
+	},
+#endif
 #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
 	{
 		.desc   = "ITS: Rockchip erratum RK3588001",
-- 
2.43.0



From csokas.bence at prolan.hu  Wed Dec  4 15:55:02 2024
From: csokas.bence at prolan.hu (=?UTF-8?B?Q3PDs2vDoXMgQmVuY2U=?=)
Date: Thu, 5 Dec 2024 00:55:02 +0100
Subject: (subset) [PATCH v5 0/5] Add support for DMA of F1C100s
In-Reply-To: <173331833897.673424.223627111827356616.b4-ty@kernel.org>
References: <20241122161128.2619172-1-csokas.bence@prolan.hu>
 <173331833897.673424.223627111827356616.b4-ty@kernel.org>
Message-ID: <932d4f7a-c9cf-4e48-afd3-476b6c0fbc86@prolan.hu>

Hi,

On 2024. 12. 04. 14:18, Vinod Koul wrote:
> 
> On Fri, 22 Nov 2024 17:11:23 +0100, Cs?k?s, Bence wrote:
>> Support for Allwinner F1C100s/200s series audio was
>> submitted in 2018 as an RFC series, but was not merged,
>> despite having only minor errors. However, this is
>> essential for having audio on these SoCs.
>> This series was forward-ported/rebased to the best of
>> my abilities, on top of Linus' tree as of now:
>> commit 28eb75e178d3 ("Merge tag 'drm-next-2024-11-21' of https://gitlab.freedesktop.org/drm/kernel")
>>
>> [...]
> 
> Applied, thanks!
> 
> [1/5] dma-engine: sun4i: Add a quirk to support different chips
>        commit: eeca1b60138189ef1b9636709e578d0c9e0de517
> [2/5] dma-engine: sun4i: Add has_reset option to quirk
>        commit: 1f738d0c2f67ae3551e4543e8dddbfb44cdd9f53
> [3/5] dt-bindings: dmaengine: Add Allwinner suniv F1C100s DMA
>        commit: 1ad2ebf3be836e62792788f4cd105b30ca9178b6
> [4/5] dma-engine: sun4i: Add support for Allwinner suniv F1C100s
>        commit: 61785259d1eb4e4c4acef8551a2524441683dbf3

Thanks! Though unfortunately, b4 has once again mangled my sign-off, 
leaving it empty :/

Bence



From kees at kernel.org  Wed Dec  4 15:58:44 2024
From: kees at kernel.org (Kees Cook)
Date: Thu, 05 Dec 2024 09:58:44 +1000
Subject: =?US-ASCII?Q?Re=3A_=5BPATCH_00/10=5D_compiler=2Eh=3A_refactor_=5F=5Fis?=
 =?US-ASCII?Q?=5Fconstexpr=28=29_into_is=5F?=
 =?US-ASCII?Q?const=7B=2C=5Ftrue=2C=5Ffalse=7D=28=29?=
In-Reply-To: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
Message-ID: <FBEB24FF-5885-4938-8D1C-9B7BA9071FB9@kernel.org>



On December 3, 2024 3:33:22 AM GMT+10:00, Vincent Mailhol via B4 Relay <devnull+mailhol.vincent.wanadoo.fr at kernel.org> wrote:
>This series is the spiritual successor of [1] which introduced
>const_true(). In [1], following a comment from David Laight, Linus
>came with a suggestion to simplify __is_constexpr() and its derived
>macros using a _Generic() selection. Because of the total change of
>scope, I am starting a new series.
>
>The goal is to introduce a set of three macros:
>
>  - is_const(): a one to one replacement of __is_constexpr() in term
>    of features but written in a less hacky way thanks to _Generic().
>
>  - is_const_true(): tells whether or not the argument is a true
>    integer constant expression.
>
>  - is_const_false(): tells whether or not the argument is a false
>    integer constant expression.

But why make this change? Is something broken? Does it make builds faster?

> 7 files changed, 97 insertions(+), 84 deletions(-)

It makes the code larger too. I don't see what the benefit is, and given how much time has been spent making sure the existing stuff works correctly, I feel like we should have a clear benefit to replacing it all.

-Kees

-- 
Kees Cook


From csokas.bence at prolan.hu  Wed Dec  4 16:01:37 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?=)
Date: Thu, 5 Dec 2024 01:01:37 +0100
Subject: [PATCH 2/3] ARM: dts: suniv: f1c100s: Add support for Audio Codec
In-Reply-To: <20241205000137.187450-1-csokas.bence@prolan.hu>
References: <20241205000137.187450-1-csokas.bence@prolan.hu>
Message-ID: <20241205000137.187450-3-csokas.bence@prolan.hu>

From: Mesih Kilinc <mesihkilinc at gmail.com>

Allwinner suniv F1C100s now has basic audio codec support. Enable it
under device tree.

Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>
[ csokas.bence: Rebased on current master ]
Signed-off-by: Cs?k?s, Bence <csokas.bence at prolan.hu>
---
 arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
index 290efe026ceb..e4b41bc93852 100644
--- a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
+++ b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
@@ -336,5 +336,19 @@ uart2: serial at 1c25800 {
 			resets = <&ccu RST_BUS_UART2>;
 			status = "disabled";
 		};
+
+		codec: codec at 1c23c00 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,suniv-f1c100s-codec";
+			reg = <0x01c23c00 0x400>;
+			interrupts = <21>;
+			clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_CODEC>;
+			clock-names = "apb", "codec";
+			dmas = <&dma SUN4I_DMA_NORMAL 12>,
+			       <&dma SUN4I_DMA_NORMAL 12>;
+			dma-names = "rx", "tx";
+			resets = <&ccu RST_BUS_CODEC>;
+			status = "disabled";
+		};
 	};
 };
-- 
2.34.1




From csokas.bence at prolan.hu  Wed Dec  4 16:01:36 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?=)
Date: Thu, 5 Dec 2024 01:01:36 +0100
Subject: [PATCH 1/3] ARM: dts: suniv: f1c100s: Add support for DMA
In-Reply-To: <20241205000137.187450-1-csokas.bence@prolan.hu>
References: <20241205000137.187450-1-csokas.bence@prolan.hu>
Message-ID: <20241205000137.187450-2-csokas.bence@prolan.hu>

From: Mesih Kilinc <mesihkilinc at gmail.com>

Allwinner suniv F1C100s now has DMA support. Enable it under device
tree.

Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>
[ csokas.bence: Rebased on current master ]
Signed-off-by: Cs?k?s, Bence <csokas.bence at prolan.hu>
---
 arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
index 3c61d59ab5f8..290efe026ceb 100644
--- a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
+++ b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
@@ -6,6 +6,7 @@
 
 #include <dt-bindings/clock/suniv-ccu-f1c100s.h>
 #include <dt-bindings/reset/suniv-ccu-f1c100s.h>
+#include <dt-bindings/dma/sun4i-a10.h>
 
 / {
 	#address-cells = <1>;
@@ -159,6 +160,15 @@ usbphy: phy at 1c13400 {
 			status = "disabled";
 		};
 
+		dma: dma-controller at 1c02000 {
+			compatible = "allwinner,suniv-f1c100s-dma";
+			reg = <0x01c02000 0x1000>;
+			interrupts = <18>;
+			clocks = <&ccu CLK_BUS_DMA>;
+			resets = <&ccu RST_BUS_DMA>;
+			#dma-cells = <2>;
+		};
+
 		ccu: clock at 1c20000 {
 			compatible = "allwinner,suniv-f1c100s-ccu";
 			reg = <0x01c20000 0x400>;
-- 
2.34.1




From csokas.bence at prolan.hu  Wed Dec  4 16:01:35 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?=)
Date: Thu, 5 Dec 2024 01:01:35 +0100
Subject: [PATCH 0/3] Add F1C100s audio support
Message-ID: <20241205000137.187450-1-csokas.bence@prolan.hu>

Support for Allwinner F1C100s/200s series audio was
merged in the for-next branches of the DMA and ALSA
trees, the last step is to add the codec to DT.
This series was forward-ported/rebased to the best of
my abilities, on top of Linus' tree as of now:
commit feffde684ac2 ("Merge tag 'for-6.13-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux")

Mesih Kilinc (3):
  ARM: dts: suniv: f1c100s: Add support for DMA
  ARM: dts: suniv: f1c100s: Add support for Audio Codec
  ARM: dts: suniv: f1c100s: Activate Audio Codec for Lichee Pi Nano

 .../allwinner/suniv-f1c100s-licheepi-nano.dts |  8 +++++++
 .../arm/boot/dts/allwinner/suniv-f1c100s.dtsi | 24 +++++++++++++++++++
 2 files changed, 32 insertions(+)

-- 
2.34.1




From csokas.bence at prolan.hu  Wed Dec  4 16:01:38 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?=)
Date: Thu, 5 Dec 2024 01:01:38 +0100
Subject: [PATCH 3/3] ARM: dts: suniv: f1c100s: Activate Audio Codec for Lichee Pi Nano
In-Reply-To: <20241205000137.187450-1-csokas.bence@prolan.hu>
References: <20241205000137.187450-1-csokas.bence@prolan.hu>
Message-ID: <20241205000137.187450-4-csokas.bence@prolan.hu>

From: Mesih Kilinc <mesihkilinc at gmail.com>

Allwinner suniv F1C100s now has basic audio codec support. Activate it
for Lichee Pi Nano board.

Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>
[ csokas.bence: Moved and fixed conflict ]
Signed-off-by: Cs?k?s, Bence <csokas.bence at prolan.hu>
---
 .../boot/dts/allwinner/suniv-f1c100s-licheepi-nano.dts    | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/allwinner/suniv-f1c100s-licheepi-nano.dts b/arch/arm/boot/dts/allwinner/suniv-f1c100s-licheepi-nano.dts
index 43896723a994..472ded0aafcf 100644
--- a/arch/arm/boot/dts/allwinner/suniv-f1c100s-licheepi-nano.dts
+++ b/arch/arm/boot/dts/allwinner/suniv-f1c100s-licheepi-nano.dts
@@ -62,6 +62,14 @@ &uart0 {
 	status = "okay";
 };
 
+&codec {
+	allwinner,audio-routing =
+		"Headphone", "HP",
+		"Headphone", "HPCOM",
+		"MIC", "Mic";
+	status = "okay";
+};
+
 &usb_otg {
 	dr_mode = "otg";
 	status = "okay";
-- 
2.34.1




From oliver.upton at linux.dev  Wed Dec  4 16:26:11 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 4 Dec 2024 16:26:11 -0800
Subject: [PATCH 02/11] KVM: arm64: nv: Sync nested timer state with
 FEAT_NV2
In-Reply-To: <20241202172134.384923-3-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
 <20241202172134.384923-3-maz@kernel.org>
Message-ID: <Z1DzI75XOcJVHARq@linux.dev>

On Mon, Dec 02, 2024 at 05:21:25PM +0000, Marc Zyngier wrote:
> Emulating the timers with FEAT_NV2 is a bit odd, as the timers
> can be reconfigured behind our back without the hypervisor even
> noticing. In the VHE case, that's an actual regression in the
> architecture...
> 
> Co-developed-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/arch_timer.c  | 44 ++++++++++++++++++++++++++++++++++++
>  arch/arm64/kvm/arm.c         |  3 +++
>  include/kvm/arm_arch_timer.h |  1 +
>  3 files changed, 48 insertions(+)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 1215df5904185..81afafd62059f 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -905,6 +905,50 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
>  		kvm_timer_blocking(vcpu);
>  }
>  
> +void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
> +{
> +	/*
> +	 * When NV2 is on, guest hypervisors have their EL0 timer register
> +	 * accesses redirected to the VNCR page. Any guest action taken on
> +	 * the timer is postponed until the next exit, leading to a very
> +	 * poor quality of emulation.
> +	 */
> +	if (!is_hyp_ctxt(vcpu))
> +		return;
> +
> +	if (!vcpu_el2_e2h_is_set(vcpu)) {
> +		/*
> +		 * A non-VHE guest hypervisor doesn't have any direct access
> +		 * to its timers: the EL2 registers trap (and the HW is
> +		 * fully emulated), while the EL0 registers access memory
> +		 * despite the access being notionally direct. Boo.
> +		 *
> +		 * We update the hardware timer registers with the
> +		 * latest value written by the guest to the VNCR page
> +		 * and let the hardware take care of the rest.
> +		 */
> +		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CTL_EL0),  SYS_CNTV_CTL);
> +		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CVAL_EL0), SYS_CNTV_CVAL);
> +		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CTL_EL0),  SYS_CNTP_CTL);
> +		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CVAL_EL0), SYS_CNTP_CVAL);
> +	} else {
> +		/*
> +		 * For a VHE guest hypervisor, the EL2 state is directly
> +		 * stored in the host EL0 timers, while the emulated EL0
> +		 * state is stored in the VNCR page. The latter could have
> +		 * been updated behind our back, and we must reset the
> +		 * emulation of the timers.
> +		 */

nitpick: s/host EL0/EL1/

At least in the way the architecture terms it there's no such thing as
an EL0 timer, and "host EL0" might lead one to think of ELIsInHost(EL0)

-- 
Thanks,
Oliver


From trunixs.kim at samsung.com  Wed Dec  4 16:28:05 2024
From: trunixs.kim at samsung.com (=?utf-8?B?6rmA7YOc7JmE?=)
Date: Thu, 5 Dec 2024 09:28:05 +0900
Subject: [PATCH v3 3/3] arm64: dts: exynosautov920: add watchdog DT node
In-Reply-To: <c487babb-84a5-4e47-a58f-75fec55cbabb@kernel.org>
References: <20241021063903.793166-1-trunixs.kim@samsung.com>
	<CGME20241021063938epcas2p1c01c89badb532f08a46087a4907df7dc@epcas2p1.samsung.com>
	<20241021063903.793166-4-trunixs.kim@samsung.com>
	<961e1aca-cd90-4db1-87d7-afd2e542421e@kernel.org>
	<20241107103331.GA4818@www.linux-watchdog.org>
	<589c40e1-6a1c-4ef7-b0d8-b761b132578a@kernel.org>
	<20241107113325.GA5284@www.linux-watchdog.org>
	<c487babb-84a5-4e47-a58f-75fec55cbabb@kernel.org>
Message-ID: <000201db46ac$8d7cfee0$a876fca0$@samsung.com>

Hi Krzysztof,

> On 07/11/2024 12:33, Wim Van Sebroeck wrote:
> >>> Seems like you are having a hard day.
> >>> The 3 patches are dropped. I presume that you will take them all
> through your tree then?
> >>
> >> I meant only this one patch, not entire patchset. The bindings and
> >> watchdog driver are for you. I commented only about this patch here -
> DTS.
> >>
> >>
> >> Best regards,
> >> Krzysztof
> >>
> >
> > I added the first two patches again. Even when it sounds more logical to
> me to keep the 3 together.
> 
> Thank you.
> 
> > But that's a never ending discussion, so we won't go into that :-).
> 
> DTS is hardware description independent from Linux, therefore always goes
> separate way than Linux drivers.
> 
> Best regards,
> Krzysztof

I found that the first two patches have been added to the linux-next git, 
but the last patch has not yet been reviewed.

I would appreciate it if you could take a look at this patch.

Best regards,
Taewan Kim.



From oliver.upton at linux.dev  Wed Dec  4 16:37:34 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 4 Dec 2024 16:37:34 -0800
Subject: [PATCH 06/11] KVM: arm64: nv: Acceletate EL0 counter accesses
 from hypervisor context
In-Reply-To: <20241202172134.384923-7-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
 <20241202172134.384923-7-maz@kernel.org>
Message-ID: <Z1D1zus18KCpCqjD@linux.dev>

typo: accelerate

On Mon, Dec 02, 2024 at 05:21:29PM +0000, Marc Zyngier wrote:
> Similarly to handling the physical timer accesses early when FEAT_ECV
> causes a trap, we try to handle the physical counter without returning
> to the general sysreg handling.
> 
> More surprisingly, we introduce something similar for the virtual
> counter. Although this isn't necessary yet, it will prove useful on
> systems that have a broken CNTVOFF_EL2 implementation. Yes, they exist.
> 
> Special care is taken to offset reads of the counter with the host's
> CNTPOFF_EL2, as we perform this with TGE clear.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/hyp/include/hyp/switch.h |  5 +++++
>  arch/arm64/kvm/hyp/vhe/switch.c         | 13 +++++++++++++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 34f53707892df..30e572de28749 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -501,6 +501,11 @@ static inline bool handle_tx2_tvm(struct kvm_vcpu *vcpu)
>  	return true;
>  }
>  
> +static inline u64 compute_counter_value(struct arch_timer_context *ctxt)
> +{
> +	return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
> +}
> +
>  static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
>  {
>  	struct arch_timer_context *ctxt;
> diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> index b014b0b10bf5d..49815a8a4c9bc 100644
> --- a/arch/arm64/kvm/hyp/vhe/switch.c
> +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> @@ -296,6 +296,13 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
>  			val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
>  		}
>  		break;
> +	case SYS_CNTPCT_EL0:
> +	case SYS_CNTPCTSS_EL0:
> +		/* If !ELIsInHost(EL0), the guest's CNTPOFF_EL2 applies */
> +		val = compute_counter_value(!(vcpu_el2_e2h_is_set(vcpu) &&
> +					      vcpu_el2_tge_is_set(vcpu)) ?
> +					    vcpu_ptimer(vcpu) : vcpu_hptimer(vcpu));
> +		break;
>  	case SYS_CNTV_CTL_EL02:
>  		val = __vcpu_sys_reg(vcpu, CNTV_CTL_EL0);
>  		break;
> @@ -314,6 +321,12 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
>  		else
>  			val = __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
>  		break;
> +	case SYS_CNTVCT_EL0:
> +	case SYS_CNTVCTSS_EL0:
> +		/* If !ELIsInHost(EL2), the guest's CNTVOFF_EL2 applies */

!ELIsInHost(EL0)

> +		val = compute_counter_value(!vcpu_el2_e2h_is_set(vcpu) ?
> +					    vcpu_vtimer(vcpu) : vcpu_hvtimer(vcpu));
> +		break;
>  	default:
>  		return false;
>  	}
> -- 
> 2.39.2
> 


From oliver.upton at linux.dev  Wed Dec  4 16:40:27 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 4 Dec 2024 16:40:27 -0800
Subject: [PATCH 00/11] KVM: arm64: Add NV timer support
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <Z1D2ezLP7nL0TXaf@linux.dev>

On Mon, Dec 02, 2024 at 05:21:23PM +0000, Marc Zyngier wrote:
> Here's another batch of NV-related patches, this time bringing in most
> of the timer support for EL2 as well as nested guests.
> 
> The code is pretty convoluted for a bunch of reasons:
> 
> - FEAT_NV2 breaks the timer semantics by redirecting HW controls to
>   memory, meaning that a guest could setup a timer and never see it
>   firing until the next exit
> 
> - We go try hard to reflect the timer state in memory, but that's not
>   great.
> 
> - With FEAT_ECV, we can finally correctly emulate the virtual timer,
>   but this emulation is pretty costly
> 
> - As a way to make things suck less, we handle timer reads as early as
>   possible, and only defer writes to the normal trap handling
> 
> - Finally, some implementations are badly broken, and require some
>   hand-holding, irrespective of NV support. So we try and reuse the NV
>   infrastructure to make them usable. This could be further optimised,
>   but I'm running out of patience for this sort of HW.
> 
> What this is not implementing is support for CNTPOFF_EL2. It appears
> that the architecture doesn't let you correctly emulate it, so I guess
> this will be trap/emulate for the foreseeable future.
> 
> This series is on top of v6.13-rc1, and has been tested on my usual M2
> setup, but also on a Snapdragon X1 Elite devkit. I would like to thank
> Qualcomm for the free hardware with no strings (nor support) attached!

This series is looking pretty good to me, but I think it'd be good to
remap "EL0 timer" -> "EL1 timer" throughout this series to match the
architectural term.

-- 
Thanks,
Oliver


From ryan_chen at aspeedtech.com  Wed Dec  4 16:48:42 2024
From: ryan_chen at aspeedtech.com (Ryan Chen)
Date: Thu, 5 Dec 2024 00:48:42 +0000
Subject: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
In-Reply-To: <9ccfb478d9a122db6c634e9559e211ff.sboyd@kernel.org>
References: <20241028053018.2579200-1-ryan_chen@aspeedtech.com>
 <20241028053018.2579200-4-ryan_chen@aspeedtech.com>
 <287924eed186e3b6b52cd13bcf939ab6.sboyd@kernel.org>
 <SI6PR06MB7535F5D22E3FCCF5C610B307F2552@SI6PR06MB7535.apcprd06.prod.outlook.com>
 <a68516df98c8b8fb80f094e6e55fcb8d.sboyd@kernel.org>
 <OS8PR06MB75419637D55A022300E00850F2352@OS8PR06MB7541.apcprd06.prod.outlook.com>
 <9ccfb478d9a122db6c634e9559e211ff.sboyd@kernel.org>
Message-ID: <OS8PR06MB75418449B451224C5AB46FBFF2302@OS8PR06MB7541.apcprd06.prod.outlook.com>

> Subject: RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> 
> Quoting Ryan Chen (2024-12-01 19:12:01)
> > > > > Subject: Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> > > > >
> > > > > Quoting Ryan Chen (2024-10-27 22:30:18)
> > > > > > diff --git a/drivers/clk/clk-ast2700.c
> > > > > > b/drivers/clk/clk-ast2700.c new file mode 100644 index
> > > > > > 000000000000..db9ee5031b7c
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/clk/clk-ast2700.c
> > > > > > @@ -0,0 +1,1513 @@
> > > > > > +// SPDX-License-Identifier: GPL-2.0
> > > [...]
> > > > > > +struct ast2700_clk_info {
> > > > > > +       const char *name;
> > > > > > +       const char * const *parent_names;
> > > > >
> > > > > Please don't use strings for parent names.
> > > > Sorry, do you mean use clk_parent_data struct for parent?
> > > >         +const struct clk_parent_data   parent;         /* For
> gate */
> > > >         +const struct clk_parent_data   *parents;
> /*
> > > For mux */
> > >
> > > Yes.
> > And I find a better way for parent_data. The following is my modification.
> > And parent_data will be union data structure. Like following.
> > Is this good direction?
> 
> Looks OK.
> 
> >
> > #define DIVIDER_CLK(_id, _name, _parent, _reg, _shift, _width, _div_table) \
> >         [_id] = { \
> >                 .type = CLK_DIVIDER, \
> >                 .name = _name, \
> >                 .data = { \
> >                         .div = { \
> >                                 .parent = _parent, \
> >                                 .reg = _reg, \
> >                                 .bit_shift = _shift, \
> >                                 .bit_width = _width, \
> >                                 .div_table = _div_table, \
> >                         }, \
> >                 }, \
> >         }
> > struct ast2700_clk_info {
> >         const char *name;
> >         u8 clk_idx;
> >         u32 reg;
> >         u32 type;
> >         union {
> >                 struct ast2700_clk_fixed_factor_data factor;
> >                 struct ast2700_clk_fixed_rate_data rate;
> >                 struct ast2700_clk_gate_data gate;
> >                 struct ast2700_clk_div_data div;
> >                 struct ast2700_clk_pll_data pll;
> >                 struct ast2700_clk_mux_data mux;
> >         } data;
> > };
> >
> > struct ast2700_clk_div_data {
> >         const struct clk_div_table *div_table;
> >         const struct clk_parent_data *parent;
> >         u8 bit_shift;
> >         u8 bit_width;
> >         u32 reg;
> > };
> >
> > static const struct ast2700_clk_info ast2700_scu0_clk_info[]
> > __initconst = { ...........................
> >         DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,
> 
> Can you also show what soc0_ahbmux is?
It will be following. 

static const struct clk_parent_data soc0_ahbmux[] = {
	{ .fw_name = "soc0-ahbmux", .name = "soc0-ahbmux" },
};
> 
> >                     SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table),
> > ......................
> > >
> > > >
> > > > >
> > > > > > +       const struct clk_div_table *div_table;
> > > > > > +       unsigned long fixed_rate;
> > > > > > +       unsigned int mult;
> > > > > > +       unsigned int div;
> > > > > > +       u32 reg;
> > > > > > +       u32 flags;
> > > > > > +       u32 type;
> > > > > > +       u8 clk_idx;
> > > > > > +       u8 bit_shift;
> > > > > > +       u8 bit_width;
> > > > > > +       u8 num_parents;
> > > > > > +};
> > > > > > +
> > > > > [...]
> > > > > > +
> > > > > > +static const struct clk_div_table ast2700_clk_div_table2[] = {
> > > > > > +       { 0x0, 2 },
> > > > > > +       { 0x1, 4 },
> > > > > > +       { 0x2, 6 },
> > > > > > +       { 0x3, 8 },
> > > > > > +       { 0x4, 10 },
> > > > > > +       { 0x5, 12 },
> > > > > > +       { 0x6, 14 },
> > > > > > +       { 0x7, 16 },
> > > > >
> > > > > Isn't this the default divider setting for struct clk_divider?
> > > > Sorry, I don't catch your point.
> > > > the SoC do have default divider setting. But it can be modified.
> > > > And also have different divider table setting.
> > >
> > > I mean that this is the way that struct clk_divider works already.
> > > So you don't need to make the clk_div_table array for what is supported in
> code.
> >
> > Sorry, I understand your point. But I trace the code didn't get any clue.
> "clk_divider work already".
> > finally function call will be __clk_hw_register_divider
> > https://github.com/torvalds/linux/blob/master/drivers/clk/clk-divider.
> > c#L589 It still need table point need to address. Can you give me more
> > direction or example?
> >
> 
> The 'table' member is optional. When the table is NULL, we treat each
> number that fits into the divider field width as a divider. It may be
> CLK_DIVIDER_EVEN_INTEGERS that you have here though.

Got it, will use this flag.

From alim.akhtar at samsung.com  Wed Dec  4 17:07:41 2024
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 5 Dec 2024 06:37:41 +0530
Subject: [PATCH v2 2/2] arm64: dts: exynos990: Add pmu and syscon-reboot
 nodes
In-Reply-To: <20241204145559.524932-3-igor.belwon@mentallysanemainliners.org>
References: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>
	<CGME20241204145953epcas5p4d9d541ee5d585d9e882c3b4b202b96f5@epcas5p4.samsung.com>
	<20241204145559.524932-3-igor.belwon@mentallysanemainliners.org>
Message-ID: <0f2301db46b2$16b204d0$44160e70$@samsung.com>

Hi Igor

> -----Original Message-----
> From: Igor Belwon <igor.belwon at mentallysanemainliners.org>
> Sent: Wednesday, December 4, 2024 8:26 PM
> To: Rob Herring <robh at kernel.org>; Krzysztof Kozlowski
> <krzk+dt at kernel.org>; Conor Dooley <conor+dt at kernel.org>; Alim Akhtar
> <alim.akhtar at samsung.com>
> Cc: devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
linux-
> samsung-soc at vger.kernel.org; linux-kernel at vger.kernel.org
> Subject: [PATCH v2 2/2] arm64: dts: exynos990: Add pmu and syscon-reboot
> nodes
> 
> Add PMU syscon, and syscon-reboot nodes to the Exynos990 dtsi.
> 
> Reboot of the Exynos990 SoC is handled by setting bit(SWRESET_TRIGGER[1])
> of SWRESET register (PMU + 0x3a00).
> 
> Tested using the "reboot" command.
> 
> Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
> ---

Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  arch/arm64/boot/dts/exynos/exynos990.dtsi | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
[snip]
> 2.45.2




From alim.akhtar at samsung.com  Wed Dec  4 17:08:09 2024
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 5 Dec 2024 06:38:09 +0530
Subject: [PATCH v2 1/2] dt-bindings: soc: samsung: exynos-pmu: Add
 exynos990-pmu compatible
In-Reply-To: <20241204145559.524932-2-igor.belwon@mentallysanemainliners.org>
References: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>
	<CGME20241204145947epcas5p3f4fc2a6d35669293b339a31d85daef1c@epcas5p3.samsung.com>
	<20241204145559.524932-2-igor.belwon@mentallysanemainliners.org>
Message-ID: <0f2401db46b2$2753d4d0$75fb7e70$@samsung.com>

Hi Igor

> -----Original Message-----
> From: Igor Belwon <igor.belwon at mentallysanemainliners.org>
> Sent: Wednesday, December 4, 2024 8:26 PM
> To: Rob Herring <robh at kernel.org>; Krzysztof Kozlowski
> <krzk+dt at kernel.org>; Conor Dooley <conor+dt at kernel.org>; Alim Akhtar
> <alim.akhtar at samsung.com>
> Cc: devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
linux-
> samsung-soc at vger.kernel.org; linux-kernel at vger.kernel.org
> Subject: [PATCH v2 1/2] dt-bindings: soc: samsung: exynos-pmu: Add
> exynos990-pmu compatible
> 
> Add a dt-binding compatible for the Exynos990 PMU. It's compatible with
the
> Exynos7 PMU design. It handles system reboot, as well as other system
> control registers (i.e registers for the USB PHY).
> 
> Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
> ---

Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-
> pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-
> pmu.yaml
> index 6cdfe7e059a3..8e6d051d8c97 100644
> --- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
> +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
> @@ -55,6 +55,7 @@ properties:
>                - samsung,exynos7885-pmu
>                - samsung,exynos8895-pmu
>                - samsung,exynos9810-pmu
> +              - samsung,exynos990-pmu
>                - samsung,exynosautov9-pmu
>                - samsung,exynosautov920-pmu
>                - tesla,fsd-pmu
> --
> 2.45.2




From andy.yan at rock-chips.com  Wed Dec  4 17:11:06 2024
From: andy.yan at rock-chips.com (Andy Yan)
Date: Thu, 5 Dec 2024 09:11:06 +0800
Subject: [PATCH v3 2/3] dt-bindings: display: rockchip: Add schema for
 RK3588 DW DSI2 controller
In-Reply-To: <20241203165450.1501219-3-heiko@sntech.de>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241203165450.1501219-3-heiko@sntech.de>
Message-ID: <cd4fe5b9-20d3-4cb1-8125-5ffdcef5c428@rock-chips.com>

Hi Heiko,

On 12/4/24 00:54, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> The Display Serial Interface 2 (DSI-2) is part of a group of communication
> protocols defined by the MIPI Alliance. The RK3588 implements this
> specification in its two MIPI DSI-2 Host Controllers that are based on a
> new Synopsis IP.
> 
> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
> ---
>   .../rockchip/rockchip,rk3588-mipi-dsi2.yaml   | 119 ++++++++++++++++++
>   1 file changed, 119 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml
> new file mode 100644
> index 000000000000..7c017e927223
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.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/rockchip/rockchip,rk3588-mipi-dsi2.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip specific extensions to the Synopsys Designware MIPI DSI2
> +
> +maintainers:
> +  - Heiko Stuebner <heiko at sntech.de>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - rockchip,rk3588-mipi-dsi2
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 2
> +
> +  clock-names:
> +    items:
> +      - const: pclk
> +      - const: sys
> +
> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      This SoC uses GRF regs to switch between vopl/vopb.
> +
> +  phys:
> +    maxItems: 1
> +
> +  phy-names:
> +    const: dcphy
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 1
> +
> +  reset-names:
> +    const: apb
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Input node to receive pixel data.
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: DSI output node to panel.
> +
> +    required:
> +      - port at 0
> +      - port at 1
> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - rockchip,grf
> +  - phys
> +  - phy-names
> +  - ports
> +  - reg
> +
> +allOf:
> +  - $ref: /schemas/display/dsi-controller.yaml#
> +
> +unevaluatedProperties: 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>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      dsi at fde20000 {
> +        compatible = "rockchip,rk3588-mipi-dsi2";
> +        reg = <0x0 0xfde20000 0x0 0x10000>;
> +        interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>;
> +        clocks = <&cru PCLK_DSIHOST0>, <&cru CLK_DSIHOST0>;
> +        clock-names = "pclk", "sys";
> +        resets = <&cru SRST_P_DSIHOST0>;
> +        reset-names = "apb";
> +        power-domains = <&power RK3588_PD_VOP>;
> +        phys = <&mipidcphy0>;

Should it be phys = <&mipidcphy0 PHY_TYPE_DPHY>, as the #phy-cells = 1 on phy side ?

> +        phy-names = "dcphy";
> +        rockchip,grf = <&vop_grf>;
> +
> +        ports {
> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +          dsi0_in: port at 0 {
> +            reg = <0>;
> +          };
> +
> +          dsi0_out: port at 1 {
> +            reg = <1>;
> +          };
> +        };
> +      };
> +    };


From damon.ding at rock-chips.com  Wed Dec  4 17:13:33 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 5 Dec 2024 09:13:33 +0800
Subject: [PATCH v1 04/10] phy: phy-rockchip-samsung-hdptx: Add support for
 eDP mode
In-Reply-To: <abzu2chif2g3urxoqbm3gbe6cciexbmqvn44qezrx4hgllfkkn@7bzi5jl3stqe>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <2131853.KlZ2vcFHjT@diego>
 <6e1f35c0-5ea8-414f-b3ea-4e7222c605ef@rock-chips.com>
 <2886747.Y6S9NjorxK@diego>
 <h4giob7bcrh7qmtepti6huym2llw4ujfmeff76vrgpahb5zy6x@dz6zghsifww5>
 <2342f342-672c-447e-90d8-674b748af6a4@rock-chips.com>
 <abzu2chif2g3urxoqbm3gbe6cciexbmqvn44qezrx4hgllfkkn@7bzi5jl3stqe>
Message-ID: <42035ebe-09b7-4005-912a-8ec72d5dabcc@rock-chips.com>

Hi Sebastian,

On 2024/12/2 22:41, Sebastian Reichel wrote:
> Hi,
> 
> On Mon, Dec 02, 2024 at 11:28:13AM +0800, Damon Ding wrote:
>> Hi,
>>
>> On 2024/12/2 6:59, Sebastian Reichel wrote:
>>> Hi,
>>>
>>> On Sat, Nov 30, 2024 at 09:25:12PM +0100, Heiko St?bner wrote:
>>>> Am Freitag, 29. November 2024, 03:43:57 CET schrieb Damon Ding:
>>>>> On 2024/11/27 19:04, Heiko St?bner wrote:
>>>>>> Am Mittwoch, 27. November 2024, 12:00:10 CET schrieb Damon Ding:
>>>>>>> On 2024/11/27 17:29, Heiko St?bner wrote:
>>>>>>>> Am Mittwoch, 27. November 2024, 08:51:51 CET schrieb Damon Ding:
>>>>>>>>> +static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode,
>>>>>>>>> +				 int submode)
>>>>>>>>> +{
>>>>>>>>> +	return 0;
>>>>>>>>> +}
>>>>>>>> analogix_dp_phy_power_on
>>>>>>>> I think it might make sense to go the same way as the DCPHY and also
>>>>>>>> naneng combophy, to use #phy-cells = 1 to select the phy-mode via DT .
>>>>>>>>
>>>>>>>> See [0] for Sebastians initial suggestion regarding the DC-PHY.
>>>>>>>> The naneng combophy already uses that scheme of mode-selection too.
>>>>>>>>
>>>>>>>> There is of course the issue of backwards-compatibility, but that can be
>>>>>>>> worked around in the binding with something like:
>>>>>>>>
>>>>>>>>      '#phy-cells':
>>>>>>>>         enum: [0, 1]
>>>>>>>>         description: |
>>>>>>>>           If #phy-cells is 0, PHY mode is set to PHY_TYPE_HDMI
>>>>>>>>           If #phy-cells is 1 mode is set in the PHY cells. Supported modes are:
>>>>>>>>             - PHY_TYPE_HDMI
>>>>>>>>             - PHY_TYPE_DP
>>>>>>>>           See include/dt-bindings/phy/phy.h for constants.
>>>>>>>>
>>>>>>>> PHY_TYPE_HDMI needs to be added to include/dt-bindings/phy/phy.h
>>>>>>>> but PHY_TYPE_DP is already there.
>>>>>>>>
>>>>>>>> That way we would standardize on one form of accessing phy-types
>>>>>>>> on rk3588 :-) .
>>>>>>>>
>>>>>>>> Also see the Mediatek CSI rx phy doing this too already [1]
>>>>>>>>
>>>>>>>>
>>>>>>>> Heiko
>>>>>>>>
>>>>>>>> [0] https://lore.kernel.org/linux-rockchip/udad4qf3o7kt45nuz6gxsvsmprh4rnyfxfogopmih6ucznizih at 7oj2jrnlfonz/
>>>>>>>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/phy/mediatek,mt8365-csi-rx.yaml
>>>>>>>>
>>>>>>>
>>>>>>> It is really a nice way to separate HDMI and DP modes.
>>>>>
>>>>> I apologize for reopening the discussion about the phy-types setting.
>>>>
>>>> there is definitly no need to apologize. We're trying to find the best
>>>> solution afterall :-) .
>>>>
>>>>> With the .set_mode() of struct phy_ops, the HDMI and eDP dynamic
>>>>> switching can be achieved, which just depends on the right setting of
>>>>> enum phy_mode in include/linux/phy/phy.h. So the previous way of
>>>>> configuring phy mode may be also good.
>>>>
>>>> I think the deciding factor is, is there a use-case for needing to switch
>>>> modes at runtime.
>>>>
>>>> I do think the mode for the dc-phy and also the hdptx-phy is pretty much
>>>> decided by the board design.
>>>>
>>>> I.e. when you end up in a DP-connector (or eDP-panel) on your board you
>>>> need DP mode, and when you end up in a hdmi-connector you need the
>>>> HDMI phy mode.
>>>>
>>>> So I think the phy-mode for the hdptx-phy is largely dictated by the static
>>>> board definition (like devicetree), hence going with the dt-argument for
>>>> the mode.
>>>>
>>>> Like similar to the Naneng combophy, selecting its mode via argument
>>>> because deciding if it ends up in a sata port is a board-design thing.
>>>>
>>>> Is there a use-case where you need to switch at runtime between
>>>> HDMI and eDP? Like starting the phy in eDP mode but then needing
>>>> to switch to HDMI mode, while the device is running?
>>
>> Indeed, we have the board as you described, on which the DP-connector and
>> HDMI-connector both have been configured.
>>
>> And the dynamic switching is more useful for RK3576, which has the same
>> eDP/HDMI design as RK3588 but only one eDP controller/HDMI controller/HDPTX
>> phy. We can only enable both of eDP/HDMI by this way.
>>
>>>
>>> I believe the eDP controller can only use the PHY in eDP mode and
>>> the HDMI controller can only use it in HDMI mode. So in order to
>>> support runtime switching, the following options are possible:
>>>
>>> 1. Enable both controllers, the PHY decides which one is really
>>>      used, the other one is basically a non-functional dummy device
>>>      until the PHY is reconfigured. This requires the set_mode()
>>>      callback, since the HDMI and eDP drivers both expect their
>>>      PHY to be enabled.
>>>
>>> 2. Properly enable / disable the used controller, so that only one
>>>      controller is active at the same time. In this case the switching
>>>      is handled one layer above and the PHY has nothing to do with it.
>>>      The phy_enable call from each controller would just set it up in
>>>      the right mode.
>>>
>>> I guess option 1 is the hacked solution, which is easier to
>>> implement as DRM's hotplug abilities are quite limited at the moment
>>> as far as I know. I think the second solution looks much cleaner and
>>> should be prefered for upstream. That solution does not require
>>> calling set_mode() for runtime switching making this whole argument
>>> void :)
>>>
>>
>> Your friendly and detailed analysis has brought me some valuable insights.
>> :)
>>
>> The option 2 is really a better way to support the dynamic switching, and we
>> still need the .set_mode() to select the configurations for either eDP or
>> HDMI in HDPTX phy at the controller level. Would you mind
>> elaborating on the useful way to choose the phy mode for the second
>> solution?
> 
> The xlate function to handle the arguments is called when the PHY
> device is looked up. So the devm_phy_get(dp->dev, "dp") call in
> analogix_dp_probe() would setup the PHY in DP mode.
> 
> Similarily the call to devm_of_phy_get_by_index() in
> dw_hdmi_qp_rockchip_bind() would set the PHY in HDMI mode.
> 
> So the PHY mode is correct as long as only one controller driver
> is bound at the same time.
> 

Firstly, the term "the HDMI and eDP dynamic switching" can be somewhat 
misleading, because the eDP usually does not support hot plug. The 
RK3588 eDP is often used as DP, and it actually supports DP 1.2. 
Therefore, it is better to use the "the HDMI and DP dynamic switching" 
description.

Indeed, the devm_phy_get(dp->dev, "dp") and devm_of_phy_get_by_index() 
will help to get the phy reference in .probe() or .bind().

However, the phy_set_mode() may be still needed in the HDMI and DP 
dynamic switching application scenarios. We need the enum phy_mode 
PHY_MODE_DP/PHY_MODE_HDMI to differentiate the configuration processes 
in .power_on(), .power_off() and .configure() of struct phy_ops, which 
will be called in conjunction with plugging in and unplugging an HDMI or 
DP cable.

Therefore, I believe we should retain the .set_mode() function.

> Greetings,
> 
> -- Sebastian
> 
>>> FWIW I think the DT argument based mode setting and the runtime set_mode
>>> are not necessarily mutual exclusive. In theory one could support both
>>> and adding set_mode support later does not change any ABI as far as
>>> I can see. Basically handle it like pin mux/configuration settings,
>>> which are usually automatically handled by the device core based on
>>> DT information, except for some drivers which have special needs.
>>>
>>
>>>>> And other phys may want to support dynamic switching too, like the
>>>>> Rockchip USBDP combo phy.
>>>>
>>>> I guess USBDP is special in that in also does both modes dynamical
>>>> depending on its use (like type-c with option DP altmode)
>>>
>>> The USBDP PHY is indeed quite different from the PHYs in your list
>>> above, but for a different reason: All the combined PHYs you listed
>>> above only support one mode at the same time. E.g. you need to
>>> decide between PCIe, SATA and USB3 mode for the Naneng combophy.
>>>
>>> For the USBDP PHY the modes are not mutually exclusive. The USB
>>> controller can request the USBDP PHY in USB mode at the same time
>>> as the DP controller requests it in DP mode. Some additional
>>> registers configure how the lanes are being muxed. A typcial setup
>>> would be 2 lanes for USB3 and 2 lanes for DP.
>>>
>>> Greetings,
>>>
>>> -- Sebastian
>>
>> Best regards,
>> Damon
>>

Best regards,
Damon


From kever.yang at rock-chips.com  Wed Dec  4 17:17:12 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Thu, 5 Dec 2024 09:17:12 +0800
Subject: [RESEND PATCH v3 2/2] phy: rockchip-naneng-combo: add rk3576
 support
In-Reply-To: <20241106021357.19782-2-frawang.cn@gmail.com>
References: <20241106021357.19782-1-frawang.cn@gmail.com>
 <20241106021357.19782-2-frawang.cn@gmail.com>
Message-ID: <11439cc8-82e7-4054-b5f1-e932c8ab5a4f@rock-chips.com>

Hi Frank,

On 2024/11/6 10:13, Frank Wang wrote:
> From: Kever Yang <kever.yang at rock-chips.com>
>
> Rockchip RK3576 integrates two naneng-combo PHY, PHY0 is used for
> PCIE and SATA, PHY1 is used for PCIE, SATA and USB3.
>
> This adds device specific data support.
>
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
> Signed-off-by: William Wu <william.wu at rock-chips.com>
> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>

Test on rk3576 evb with pcie port.

Test-by: Kever Yang <kever.yang at rock-chips.com>


Thanks,

- Kever

> ---
> Changelog:
> v3:
>   - add detail commit contents.
>   - using FIELD_PREP() instead of bit shift.
>   - leave a blank line after each switch break case.
>
> v2:
>   - using constants macro instead of magic values.
>   - add more comments for PHY tuning operations.
>
> v1:
>   - https://patchwork.kernel.org/project/linux-phy/patch/20241015013351.4884-2-frawang.cn at gmail.com/
>
>   .../rockchip/phy-rockchip-naneng-combphy.c    | 279 ++++++++++++++++++
>   1 file changed, 279 insertions(+)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> index 0a9989e41237f..eceb798567859 100644
> --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> @@ -37,6 +37,10 @@
>   #define PHYREG8				0x1C
>   #define PHYREG8_SSC_EN			BIT(4)
>   
> +#define PHYREG10			0x24
> +#define PHYREG10_SSC_PCM_MASK		GENMASK(3, 0)
> +#define PHYREG10_SSC_PCM_3500PPM	7
> +
>   #define PHYREG11			0x28
>   #define PHYREG11_SU_TRIM_0_7		0xF0
>   
> @@ -61,17 +65,26 @@
>   #define PHYREG16			0x3C
>   #define PHYREG16_SSC_CNT_VALUE		0x5f
>   
> +#define PHYREG17			0x40
> +
>   #define PHYREG18			0x44
>   #define PHYREG18_PLL_LOOP		0x32
>   
> +#define PHYREG21			0x50
> +#define PHYREG21_RX_SQUELCH_VAL		0x0D
> +
>   #define PHYREG27			0x6C
>   #define PHYREG27_RX_TRIM_RK3588		0x4C
>   
> +#define PHYREG30			0x74
> +
>   #define PHYREG32			0x7C
>   #define PHYREG32_SSC_MASK		GENMASK(7, 4)
> +#define PHYREG32_SSC_DIR_MASK		GENMASK(5, 4)
>   #define PHYREG32_SSC_DIR_SHIFT		4
>   #define PHYREG32_SSC_UPWARD		0
>   #define PHYREG32_SSC_DOWNWARD		1
> +#define PHYREG32_SSC_OFFSET_MASK	GENMASK(7, 6)
>   #define PHYREG32_SSC_OFFSET_SHIFT	6
>   #define PHYREG32_SSC_OFFSET_500PPM	1
>   
> @@ -79,6 +92,7 @@
>   #define PHYREG33_PLL_KVCO_MASK		GENMASK(4, 2)
>   #define PHYREG33_PLL_KVCO_SHIFT		2
>   #define PHYREG33_PLL_KVCO_VALUE		2
> +#define PHYREG33_PLL_KVCO_VALUE_RK3576	4
>   
>   struct rockchip_combphy_priv;
>   
> @@ -98,6 +112,7 @@ struct rockchip_combphy_grfcfg {
>   	struct combphy_reg pipe_rxterm_set;
>   	struct combphy_reg pipe_txelec_set;
>   	struct combphy_reg pipe_txcomp_set;
> +	struct combphy_reg pipe_clk_24m;
>   	struct combphy_reg pipe_clk_25m;
>   	struct combphy_reg pipe_clk_100m;
>   	struct combphy_reg pipe_phymode_sel;
> @@ -584,6 +599,266 @@ static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
>   	.combphy_cfg	= rk3568_combphy_cfg,
>   };
>   
> +static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)
> +{
> +	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
> +	unsigned long rate;
> +	u32 val;
> +
> +	switch (priv->type) {
> +	case PHY_TYPE_PCIE:
> +		/* Set SSC downward spread spectrum */
> +		val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
> +		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
> +
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
> +		break;
> +
> +	case PHY_TYPE_USB3:
> +		/* Set SSC downward spread spectrum */
> +		val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
> +		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
> +
> +		/* Enable adaptive CTLE for USB3.0 Rx */
> +		val = readl(priv->mmio + PHYREG15);
> +		val |= PHYREG15_CTLE_EN;
> +		writel(val, priv->mmio + PHYREG15);
> +
> +		/* Set PLL KVCO fine tuning signals */
> +		rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33);
> +
> +		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
> +		writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
> +
> +		/* Set PLL input clock divider 1/2 */
> +		val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2);
> +		rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6);
> +
> +		/* Set PLL loop divider */
> +		writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
> +
> +		/* Set PLL KVCO to min and set PLL charge pump current to max */
> +		writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
> +
> +		/* Set Rx squelch input filler bandwidth */
> +		writel(PHYREG21_RX_SQUELCH_VAL, priv->mmio + PHYREG21);
> +
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
> +		break;
> +
> +	case PHY_TYPE_SATA:
> +		/* Enable adaptive CTLE for SATA Rx */
> +		val = readl(priv->mmio + PHYREG15);
> +		val |= PHYREG15_CTLE_EN;
> +		writel(val, priv->mmio + PHYREG15);
> +
> +		/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
> +		val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
> +		val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
> +		writel(val, priv->mmio + PHYREG7);
> +
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
> +		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
> +		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
> +		break;
> +
> +	default:
> +		dev_err(priv->dev, "incompatible PHY type\n");
> +		return -EINVAL;
> +	}
> +
> +	rate = clk_get_rate(priv->refclk);
> +
> +	switch (rate) {
> +	case REF_CLOCK_24MHz:
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true);
> +		if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
> +			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
> +			val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE);
> +			rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
> +						 val, PHYREG15);
> +
> +			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
> +		} else if (priv->type == PHY_TYPE_PCIE) {
> +			/* PLL KVCO tuning fine */
> +			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
> +			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> +						 val, PHYREG33);
> +
> +			/* Set up rx_pck invert and rx msb to disable */
> +			writel(0x00, priv->mmio + PHYREG27);
> +
> +			/*
> +			 * Set up SU adjust signal:
> +			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
> +			 * su_trim[15:8],  PLL LPF R1 adujst bits[9:7]=3'b011
> +			 * su_trim[31:24], CKDRV adjust
> +			 */
> +			writel(0x90, priv->mmio + PHYREG11);
> +			writel(0x02, priv->mmio + PHYREG12);
> +			writel(0x57, priv->mmio + PHYREG14);
> +
> +			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
> +		}
> +		break;
> +
> +	case REF_CLOCK_25MHz:
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
> +		break;
> +
> +	case REF_CLOCK_100MHz:
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
> +		if (priv->type == PHY_TYPE_PCIE) {
> +			/* gate_tx_pck_sel length select work for L1SS */
> +			writel(0xc0, priv->mmio + PHYREG30);
> +
> +			/* PLL KVCO tuning fine */
> +			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
> +			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> +						 val, PHYREG33);
> +
> +			/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
> +			writel(0x4c, priv->mmio + PHYREG27);
> +
> +			/*
> +			 * Set up SU adjust signal:
> +			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
> +			 * su_trim[15:8],  bypass PLL loop divider code, and
> +			 *                 PLL LPF R1 adujst bits[9:7]=3'b101
> +			 * su_trim[23:16], CKRCV adjust
> +			 * su_trim[31:24], CKDRV adjust
> +			 */
> +			writel(0x90, priv->mmio + PHYREG11);
> +			writel(0x43, priv->mmio + PHYREG12);
> +			writel(0x88, priv->mmio + PHYREG13);
> +			writel(0x56, priv->mmio + PHYREG14);
> +		} else if (priv->type == PHY_TYPE_SATA) {
> +			/* downward spread spectrum +500ppm */
> +			val = FIELD_PREP(PHYREG32_SSC_DIR_MASK, PHYREG32_SSC_DOWNWARD);
> +			val |= FIELD_PREP(PHYREG32_SSC_OFFSET_MASK, PHYREG32_SSC_OFFSET_500PPM);
> +			rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
> +
> +			/* ssc ppm adjust to 3500ppm */
> +			rockchip_combphy_updatel(priv, PHYREG10_SSC_PCM_MASK,
> +						 PHYREG10_SSC_PCM_3500PPM,
> +						 PHYREG10);
> +		}
> +		break;
> +
> +	default:
> +		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
> +		return -EINVAL;
> +	}
> +
> +	if (priv->ext_refclk) {
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
> +		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
> +			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
> +			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> +						 val, PHYREG33);
> +
> +			/* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */
> +			writel(0x0c, priv->mmio + PHYREG27);
> +
> +			/*
> +			 * Set up SU adjust signal:
> +			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
> +			 * su_trim[15:8],  bypass PLL loop divider code, and
> +			 *                 PLL LPF R1 adujst bits[9:7]=3'b101.
> +			 * su_trim[23:16], CKRCV adjust
> +			 * su_trim[31:24], CKDRV adjust
> +			 */
> +			writel(0x90, priv->mmio + PHYREG11);
> +			writel(0x43, priv->mmio + PHYREG12);
> +			writel(0x88, priv->mmio + PHYREG13);
> +			writel(0x56, priv->mmio + PHYREG14);
> +		}
> +	}
> +
> +	if (priv->enable_ssc) {
> +		val = readl(priv->mmio + PHYREG8);
> +		val |= PHYREG8_SSC_EN;
> +		writel(val, priv->mmio + PHYREG8);
> +
> +		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) {
> +			/* Set PLL loop divider */
> +			writel(0x00, priv->mmio + PHYREG17);
> +			writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
> +
> +			/* Set up rx_pck invert and rx msb to disable */
> +			writel(0x00, priv->mmio + PHYREG27);
> +
> +			/*
> +			 * Set up SU adjust signal:
> +			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
> +			 * su_trim[15:8],  PLL LPF R1 adujst bits[9:7]=3'b101
> +			 * su_trim[23:16], CKRCV adjust
> +			 * su_trim[31:24], CKDRV adjust
> +			 */
> +			writel(0x90, priv->mmio + PHYREG11);
> +			writel(0x02, priv->mmio + PHYREG12);
> +			writel(0x08, priv->mmio + PHYREG13);
> +			writel(0x57, priv->mmio + PHYREG14);
> +			writel(0x40, priv->mmio + PHYREG15);
> +
> +			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
> +
> +			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
> +			writel(val, priv->mmio + PHYREG33);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = {
> +	/* pipe-phy-grf */
> +	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
> +	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
> +	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
> +	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
> +	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
> +	.pipe_clk_24m		= { 0x0004, 14, 13, 0x00, 0x00 },
> +	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
> +	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
> +	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
> +	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
> +	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
> +	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
> +	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
> +	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
> +	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
> +	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
> +	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
> +	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
> +	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
> +	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
> +	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
> +	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
> +	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
> +	/* php-grf */
> +	.pipe_con0_for_sata	= { 0x001C, 2, 0, 0x00, 0x2 },
> +	.pipe_con1_for_sata	= { 0x0020, 2, 0, 0x00, 0x2 },
> +};
> +
> +static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = {
> +	.num_phys = 2,
> +	.phy_ids = {
> +		0x2b050000,
> +		0x2b060000
> +	},
> +	.grfcfg		= &rk3576_combphy_grfcfgs,
> +	.combphy_cfg	= rk3576_combphy_cfg,
> +};
> +
>   static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
>   {
>   	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
> @@ -775,6 +1050,10 @@ static const struct of_device_id rockchip_combphy_of_match[] = {
>   		.compatible = "rockchip,rk3568-naneng-combphy",
>   		.data = &rk3568_combphy_cfgs,
>   	},
> +	{
> +		.compatible = "rockchip,rk3576-naneng-combphy",
> +		.data = &rk3576_combphy_cfgs,
> +	},
>   	{
>   		.compatible = "rockchip,rk3588-naneng-combphy",
>   		.data = &rk3588_combphy_cfgs,


From pgwipeout at gmail.com  Wed Dec  4 17:33:17 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Wed, 4 Dec 2024 20:33:17 -0500
Subject: [PATCH] arm64: dts: rockchip: increase gmac rx_delay to 0x11 on rk3399-puma
In-Reply-To: <2578458.4XsnlVU6TS@diego>
References: <20241202090408.201662-1-jakob.unterwurzacher@cherry.de>
 <63b3be80-cb6c-49e5-858f-70fd826140c5@cherry.de> <2578458.4XsnlVU6TS@diego>
Message-ID: <CAMdYzYr9bULWou5gf43G-AywREWRCOhHmJ-fOQ1cEDWJSmGSdQ@mail.gmail.com>

On Mon, Dec 2, 2024 at 4:58?AM Heiko St?bner <heiko at sntech.de> wrote:
>
> Am Montag, 2. Dezember 2024, 10:52:06 CET schrieb Quentin Schulz:
> > Hi Jakob,
> >
> > On 12/2/24 10:04 AM, Jakob Unterwurzacher wrote:
> > > During mass manufacturing, we noticed the mmc_rx_crc_error counter,
> > > as reported by "ethtool -S eth0 | grep mmc_rx_crc_error" to increase
> > > above zero during nuttcp speedtests.
> > >
> > > Cycling through the rx_delay range on two boards shows that is a large
> > > "good" region from 0x11 to 0x35 (see below for details).
> > >
> >
> > Is this missing a "there" after that? "that there is a large good region"?

That large good region is actually an eye that you are aligning to the
clock signal. The board is on the tail end of the eye where it is
barely working. This value is supposed to be tuned to be in the middle
of that eye. You may want to test the old boards against the new
boards, because if the original board was tuned correctly something
may have changed in hardware that caused a significant shift in the
eye location. Examples of this would be changing to a new phy,
enabling phy delays, or changes in the trace length. If this is the
case, you'll probably want to make a new variant of the dts to cover
this.

> >
> > > This commit increases rx_delay to 0x11, which is the smallest
> > > possible change that fixes the issue we are seeing on the KSZ9031 PHY.
> > > This also matches what most other rk3399 boards do.
> > >
> > > Tests for Puma PCBA S/N TT0069903:
> > >
> > >     rx_delay mmc_rx_crc_error
> > >     -------- ----------------
> > >     0x09 (dhcp broken)
> > >     0x10 897
> > >     0x11 0
> > >     0x20 0
> > >     0x30 0
> > >     0x35 0
> > >     0x3a 745
> > >     0x3b 11375
> > >     0x3c 36680
> > >     0x40 (dhcp broken)
> > >     0x7f (dhcp broken)
> > >
> > > Tests for Puma PCBA S/N TT0157733:
> > >
> > >     rx_delay mmc_rx_crc_error
> > >     -------- ----------------
> > >     0x10 59
> > >     0x11 0
> > >     0x35 0
> > >
> > > Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at cherry.de>
> >
> > This would be a candidate for backporting I believe.
> >
> > Therefore, a
>
> also please include a
>
> Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")
>
> > Cc: <stable at vger.kernel.org>
> >
> > here would have been nice (in the commit log), c.f.
> > https://www.kernel.org/doc/html/latest/process/submitting-patches.html#select-the-recipients-for-your-patch
> >
> > > ---
> > >   arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 2 +-
> > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> > > index 9efcdce0f593..13d0c511046b 100644
> > > --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> > > +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> > > @@ -181,7 +181,7 @@ &gmac {
> > >     snps,reset-active-low;
> > >     snps,reset-delays-us = <0 10000 50000>;
> > >     tx_delay = <0x10>;
> > > -   rx_delay = <0x10>;
> > > +   rx_delay = <0x11>;
> >
> > While at it, we could reorder this alphabetically and move rx_delay
>
> I would disagree. This is a "fix", so should ideally only do the minimal
> changes to make life of the stable people easier.
>
> Doing this one-line change is way easier to understand than stuff also
> moving around.
>
> Heiko
>
> > between pinctrl-0 and snps,reset-gpio? c.f.
> > https://www.kernel.org/doc/html/latest/devicetree/bindings/dts-coding-style.html#order-of-properties-in-device-node
> > rx_delay and tx_delay seem to be vendor-specific but without the vendor
> > prefix, but so is snps,reset-gpio so that should be fine to reorder this
> > way.
> >
> > Considering we have an option for KSZ9031 on RK3588 Jaguar and RK3588
> > Tiger and the "same" MAC IP is used and that we use the same TXD and RXD
> > delay than on RK3399 Puma right now, I guess we would want to check
> > those don't need a change as well? (funnily enough, all RK3588-based
> > boards in 6.12 actually have 0x00 for rx_delay and 0x43/0x44 for
> > tx_delay, except ours which are at 0x10). Not a blocker for this patch
> > though, so:
> >
> > Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>
> >
> > Thanks!
> > Quentin
> >
>
>
>
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From xiaqinxin at huawei.com  Wed Dec  4 17:33:31 2024
From: xiaqinxin at huawei.com (Qinxin Xia)
Date: Thu, 5 Dec 2024 09:33:31 +0800
Subject: [PATCH v2] ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A
Message-ID: <20241205013331.1484017-1-xiaqinxin@huawei.com>

HiSilicon HIP09A platforms using the same SMMU PMCG with HIP09
and thus suffers the same erratum. List them in the PMCG platform
information list without introducing a new SMMU PMCG Model.

Update the silicon-errata.rst as well.

Reviewed-by: Yicong Yang <yangyicong at hisilicon.com>
Acked-by: Hanjun Guo <guohanjun at huawei.com>
Signed-off-by: Qinxin Xia <xiaqinxin at huawei.com>

---

Changes since V1:
- Change the description of PMCG HIP09x to HIP09A in silicon-errata.rst
- Link: https://lore.kernel.org/linux-arm-kernel/4ac9e057-725c-a0ae-e2db-612ea359bec1 at huawei.com/T/#mf90dd6937b2aee3895a1b2cc9d0ec8a6061e5c8a

Documentation/arch/arm64/silicon-errata.rst | 5 +++--
drivers/acpi/arm64/iort.c                   | 2 ++
2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index 77db10e944f0..b42fea07c5ce 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -255,8 +255,9 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | Hisilicon      | Hip08 SMMU PMCG | #162001800      | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
-| Hisilicon      | Hip{08,09,10,10C| #162001900      | N/A                         |
-|                | ,11} SMMU PMCG  |                 |                             |
+| Hisilicon      | Hip{08,09,09A,10| #162001900      | N/A                         |
+|                | ,10C,11}        |                 |                             |
+|                | SMMU PMCG       |                 |                             |
 +----------------+-----------------+-----------------+-----------------------------+
 | Hisilicon      | Hip09           | #162100801      | HISILICON_ERRATUM_162100801 |
 +----------------+-----------------+-----------------+-----------------------------+
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 1f7e4c691d9e..98759d6199d3 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1716,6 +1716,8 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = {
 	/* HiSilicon Hip09 Platform */
 	{"HISI  ", "HIP09   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
 	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+	{"HISI  ", "HIP09A  ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
 	/* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */
 	{"HISI  ", "HIP10   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
 	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
-- 
2.33.0



From gshan at redhat.com  Wed Dec  4 18:08:29 2024
From: gshan at redhat.com (Gavin Shan)
Date: Thu, 5 Dec 2024 12:08:29 +1000
Subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module
 loading
In-Reply-To: <a64a21cc-6d10-4e8f-9ab9-87aca44ca858@arm.com>
References: <20241203000156.72451-2-jeremy.linton@arm.com>
 <202412031348.bp5i3ws2-lkp@intel.com>
 <b1923d68-726a-4864-8661-54588a634d95@redhat.com>
 <a64a21cc-6d10-4e8f-9ab9-87aca44ca858@arm.com>
Message-ID: <60ab506d-5374-484d-906e-3561fc895a6d@redhat.com>


On 12/4/24 1:30 AM, Jeremy Linton wrote:
> On 12/3/24 2:56 AM, Gavin Shan wrote:
>> On 12/3/24 4:03 PM, kernel test robot wrote:
>>> Hi Jeremy,
>>>
>>> kernel test robot noticed the following build warnings:
>>>
>>> [auto build test WARNING on arm64/for-next/core]
>>> [also build test WARNING on linus/master v6.13-rc1 next-20241128]
>>> [cannot apply to kvmarm/next soc/for-next arm/for-next arm/fixes]
>>> [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/Jeremy-Linton/ arm64-rsi-Add-automatic-arm-cca-guest-module-loading/20241203-080347
>>> base:?? https://git.kernel.org/pub/scm/linux/kernel/git/arm64/ linux.git for-next/core
>>> patch link:??? https://lore.kernel.org/r/20241203000156.72451-2- jeremy.linton%40arm.com
>>> patch subject: [PATCH v2 1/1] arm64: rsi: Add automatic arm-cca-guest module loading
>>> config: arm64-randconfig-004-20241203 (https://download.01.org/0day- ci/archive/20241203/202412031348.bp5i3ws2-lkp at intel.com/config)
>>> compiler: clang version 20.0.0git (https://github.com/llvm/llvm- project 592c0fe55f6d9a811028b5f3507be91458ab2713)
>>> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/ archive/20241203/202412031348.bp5i3ws2-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/202412031348.bp5i3ws2- lkp at intel.com/
>>>
>>> All warnings (new ones prefixed by >>):
>>>
>>>>> drivers/virt/coco/arm-cca-guest/arm-cca-guest.c:224:21: warning: attribute declaration must precede definition [-Wignored-attributes]
>>> ????? 224 | static const struct __maybe_unused platform_device_id arm_cca_match[] = {
>>> ????????? |???????????????????? ^
>>> ??? include/linux/compiler_attributes.h:356:56: note: expanded from macro '__maybe_unused'
>>> ????? 356 | #define __maybe_unused __attribute__((__unused__))
>>> ????????? |??????????????????????????????????????????????????????? ^
>>> ??? include/linux/mod_devicetable.h:607:8: note: previous definition is here
>>> ????? 607 | struct platform_device_id {
>>> ????????? |??????? ^
>>>>> drivers/virt/coco/arm-cca-guest/arm-cca-guest.c:224:55: warning: unused variable 'arm_cca_match' [-Wunused-const-variable]
>>> ????? 224 | static const struct __maybe_unused platform_device_id arm_cca_match[] = {
>>> ????????? | ^~~~~~~~~~~~~
>>> ??? 2 warnings generated.
>>>
>>>
>>> vim +224 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
>>>
>>> ??? 222
>>> ??? 223??? /* modalias, so userspace can autoload this module when RSI is available */
>>> ? > 224??? static const struct __maybe_unused platform_device_id arm_cca_match[] = {
>>> ??? 225??????? { RSI_PDEV_NAME, 0},
>>> ??? 226??????? { }
>>> ??? 227??? };
>>> ??? 228
>>>
>>
>> The definition may have to be something like below, to avoid the compiling warning.
>>
>> static const struct platform_device_id __maybe_unused arm_cca_match[] = {
> 
> I should have tested this with clang rather than copy/pasting the utilization from somewhere else! It looks like a number of other kernel users are putting it before the '=', but its sorta annoying because it seems like the kind of warning that should be suppressed globally for this case (module device description in module that can be built in).
> 
> 

I think it also work by putting '__maybe_unused' before '='. It's also my personaly preferred style.
However, I don't see how the pattern 'struct __maybe_unused platform_device_id arm_cca_match[]' can
work because the affective scope of '__maybe_unused' is ambiguous to the compiler: 'struct platform_device_id'
or 'arm_cca_match[]'.

> 
>> ??????? ...
>> };
>>

Thanks,
Gavin




From vt at altlinux.org  Wed Dec  4 18:09:46 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Thu, 5 Dec 2024 05:09:46 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <20241203040350.4soyvaeqs75kjqoj@altlinux.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
 <Z05cuuMMurzp1jx5@linux.dev>
 <20241203040350.4soyvaeqs75kjqoj@altlinux.org>
Message-ID: <20241205020946.yf6xdieoswsrmvi5@altlinux.org>

Oliver,

On Tue, Dec 03, 2024 at 07:03:50AM +0300, Vitaly Chikunov wrote:
> On Mon, Dec 02, 2024 at 05:19:54PM -0800, Oliver Upton wrote:
> > On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> > > Marc,
> > > 
> > > On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > > > On Mon, 02 Dec 2024 15:59:40 +0000,
> > > > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > > > 
> > > > > Marc,
> > > > > 
> > > > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > > > >
> > > > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > > > 
> > > > > No, host is 6.6.60.
> > > > 
> > > > Right. I wouldn't be surprised if:
> > > > 
> > > > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> > > >   that's proably something we should backport)
> > > 
> > > How to confirm this? Currently I cannot find any (case-insensitive)
> > > "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM strings
> > > in `strace -v` (as it decodes some KVM ioctls) of qemu process.
> > 
> > If you can attach to the QEMU gdbstub of the VM, info registers will
> > dump ~everything.
> > 
> > If the value of ID_AA64PFR0_EL1.MPAM (bits 43:40) is nonzero then the
> > host KVM is erroneously advertising MPAM to the guest.
> 
> I don't find such register. There is what I get:

Thanks to ArmCpuInfo.efi I can confirm MPAM is advertised.

  Shell> ArmCpuInfo.efi
  ID_AA64PFR0_EL1  = 0x1100010011111111
  ...
  PFR0  | MPAM         | 43:40 |  0001 | FEAT_MPAM v1.0 implemented.

I prepared the kernel with Marc's patch (backport of 6685f5d572c22e10 to
6.6) and am waiting for the admins to boot it, hopefully today or tomorrow.

Thanks,



From ck.hu at mediatek.com  Wed Dec  4 18:42:01 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 5 Dec 2024 02:42:01 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <716b8630-66ef-4497-8cba-d5d20da2382a@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
	 <559ac08df6614e47c3e8d9d8160b35c9e683c503.camel@mediatek.com>
	 <716b8630-66ef-4497-8cba-d5d20da2382a@collabora.com>
Message-ID: <6bba26909f2fe0686c2584536f7a080451f768a1.camel@mediatek.com>

On Wed, 2024-12-04 at 15:44 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Il 02/12/24 08:27, CK Hu (???) ha scritto:
> > Hi, Angelo:
> > 
> > On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> > > External email : Please do not click links or open attachments until you have verified the sender or the content.
> > > 
> > > 
> > > Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> > > found in MediaTek's MT8195, MT8188 SoC and their variants, and
> > > including support for display modes up to 4k60 and for HDMI
> > > Audio, as per the HDMI 2.0 spec.
> > > 
> > > HDCP and CEC functionalities are also supported by this hardware,
> > > but are not included in this commit.
> > > 
> > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > > ---
> > 
> > [snip]
> > 
> > > +static int mtk_hdmi_v2_enable(struct mtk_hdmi *hdmi)
> > > +{
> > > +       int ret;
> > > +
> > > +       ret = pm_runtime_resume_and_get(hdmi->dev);
> > 
> > Why turn on power when attach?
> > Should hot-plug detection be always on so power on when attach?
> > If so, maybe we need to use CEC to detect hot-plug because CEC has lower power and HDMI power would not be always on.
> > As you describe previously, CEC just need some hack to support both HDMI Tx and HDMI Rx.
> > So there is a software solution to use CEC to detect hot-plug in a lower power mode.
> > And v1 use CEC to detect hot-plug, so it's worth to make v1 and v2 has the same behavior.
> > 
> 
> As I said, we can't use CEC to detect hotplug, because the same CEC controller
> can be used for both HDMI TX and RX at the same time.
> 
> If you use CEC to detect cable attach and you have both HDMI RX and HDMI TX drivers
> probed and ready, if you attach the cable to HDMI RX port, HDMI TX will try to get
> enabled and will error out.
> Same happens if you attach a cable to HDMI TX: HDMI RX will try to get enabled and
> will error out.
> 
> The only way to use CEC for hotplug detection is to detect twice: CEC for HDMI
> TX/RX controllers wakeup, then reset both, wait for autodetect in both controllers,
> suppress errors, and start signal transmit or receive.
> 
> While it is technically possible to do so, it's very complicated and hacky.
> 
> Please keep in mind that on the new SoCs (8188/8195) the CEC block is different
> from the one in the old SoCs (6795, 8173, etc) and requires an entirely new driver
> to get it working.
> 
> Using CEC for hotplug detection would mean that we need 3 full drivers:
> 1. HDMI TX
> 2. HDMI RX
> 3. CEC
> 
> This is because the CEC is shared, so we need to have all three to properly test
> the functionality - and this is not possible to do all at once.
> 
> To save some power (not much, though!), we can eventually go for your proposed
> CEC detection *in the future*, but really not right now - and we can do that only
> after upstreaming both HDMI TX and HDMI RX drivers.
> 
> The plan (time/effort pemitting!) would look like this:
> 
> Series 1 - Upstream HDMIv2 TX (HPD through HDMIv2 TX controller) - drivers/gpu/drm
> Series 2 - Upstream HDMIv2 RX (HPD through HDMIv2 RX controller) - drivers/media
> Series 3 - Upstream CEC driver (No HPD in CEC)                   - drivers/media
> Series 4 - Implement HPD in CEC and use it in HDMIv2 TX and HDMIv2 RX - media,drm
> 
> You can see how complicated this is - and I'm sure that you understand why that
> cannot be done all at once.
> 
> Adding up some: the HDMI driver is used only on IoT boards for now, which typically
> run off AC and not battery - so the (again) very little power consumption raise is
> not critical for now.

If you plan to upstream HDMI RX driver recently, it's OK not using CEC to detect hot-plug.
But for any behavior which is different with v1 and it's related to CEC, add comment about CEC.

Regards,
CK

> 
> Cheers,
> Angelo
> 
> > Regards,
> > CK
> > 
> > 
> > > +       if (ret) {
> > > +               dev_err(hdmi->dev, "Cannot resume HDMI\n");
> > > +               return ret;
> > > +       }
> > > +
> > > +       mtk_hdmi_v2_clk_enable(hdmi);
> > > +       mtk_hdmi_hw_reset(hdmi);
> > > +       mtk_hdmi_set_sw_hpd(hdmi, true);
> > > +
> > > +       return 0;
> > > +}
> > > +

From ck.hu at mediatek.com  Wed Dec  4 18:48:51 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 5 Dec 2024 02:48:51 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <6bba26909f2fe0686c2584536f7a080451f768a1.camel@mediatek.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
	 <559ac08df6614e47c3e8d9d8160b35c9e683c503.camel@mediatek.com>
	 <716b8630-66ef-4497-8cba-d5d20da2382a@collabora.com>
	 <6bba26909f2fe0686c2584536f7a080451f768a1.camel@mediatek.com>
Message-ID: <8c34c5a6cc2217ffc1a2d9881f20708e8427ffe6.camel@mediatek.com>

On Thu, 2024-12-05 at 10:42 +0800, CK Hu wrote:
> On Wed, 2024-12-04 at 15:44 +0100, AngeloGioacchino Del Regno wrote:
> > External email : Please do not click links or open attachments until you have verified the sender or the content.
> > 
> > 
> > Il 02/12/24 08:27, CK Hu (???) ha scritto:
> > > Hi, Angelo:
> > > 
> > > On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> > > > External email : Please do not click links or open attachments until you have verified the sender or the content.
> > > > 
> > > > 
> > > > Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> > > > found in MediaTek's MT8195, MT8188 SoC and their variants, and
> > > > including support for display modes up to 4k60 and for HDMI
> > > > Audio, as per the HDMI 2.0 spec.
> > > > 
> > > > HDCP and CEC functionalities are also supported by this hardware,
> > > > but are not included in this commit.
> > > > 
> > > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +static int mtk_hdmi_v2_enable(struct mtk_hdmi *hdmi)
> > > > +{
> > > > +       int ret;
> > > > +
> > > > +       ret = pm_runtime_resume_and_get(hdmi->dev);
> > > 
> > > Why turn on power when attach?
> > > Should hot-plug detection be always on so power on when attach?
> > > If so, maybe we need to use CEC to detect hot-plug because CEC has lower power and HDMI power would not be always on.
> > > As you describe previously, CEC just need some hack to support both HDMI Tx and HDMI Rx.
> > > So there is a software solution to use CEC to detect hot-plug in a lower power mode.
> > > And v1 use CEC to detect hot-plug, so it's worth to make v1 and v2 has the same behavior.
> > > 
> > 
> > As I said, we can't use CEC to detect hotplug, because the same CEC controller
> > can be used for both HDMI TX and RX at the same time.
> > 
> > If you use CEC to detect cable attach and you have both HDMI RX and HDMI TX drivers
> > probed and ready, if you attach the cable to HDMI RX port, HDMI TX will try to get
> > enabled and will error out.
> > Same happens if you attach a cable to HDMI TX: HDMI RX will try to get enabled and
> > will error out.
> > 
> > The only way to use CEC for hotplug detection is to detect twice: CEC for HDMI
> > TX/RX controllers wakeup, then reset both, wait for autodetect in both controllers,
> > suppress errors, and start signal transmit or receive.
> > 
> > While it is technically possible to do so, it's very complicated and hacky.
> > 
> > Please keep in mind that on the new SoCs (8188/8195) the CEC block is different
> > from the one in the old SoCs (6795, 8173, etc) and requires an entirely new driver
> > to get it working.
> > 
> > Using CEC for hotplug detection would mean that we need 3 full drivers:
> > 1. HDMI TX
> > 2. HDMI RX
> > 3. CEC
> > 
> > This is because the CEC is shared, so we need to have all three to properly test
> > the functionality - and this is not possible to do all at once.
> > 
> > To save some power (not much, though!), we can eventually go for your proposed
> > CEC detection *in the future*, but really not right now - and we can do that only
> > after upstreaming both HDMI TX and HDMI RX drivers.
> > 
> > The plan (time/effort pemitting!) would look like this:
> > 
> > Series 1 - Upstream HDMIv2 TX (HPD through HDMIv2 TX controller) - drivers/gpu/drm
> > Series 2 - Upstream HDMIv2 RX (HPD through HDMIv2 RX controller) - drivers/media
> > Series 3 - Upstream CEC driver (No HPD in CEC)                   - drivers/media
> > Series 4 - Implement HPD in CEC and use it in HDMIv2 TX and HDMIv2 RX - media,drm
> > 
> > You can see how complicated this is - and I'm sure that you understand why that
> > cannot be done all at once.
> > 
> > Adding up some: the HDMI driver is used only on IoT boards for now, which typically
> > run off AC and not battery - so the (again) very little power consumption raise is
> > not critical for now.
> 
> If you plan to upstream HDMI RX driver recently, it's OK not using CEC to detect hot-plug.
> But for any behavior which is different with v1 and it's related to CEC, add comment about CEC.

In here, describe more about the power.
Chromebook may need HDMI TX driver and its power is from battery.
Maybe Googler would be interested in low power behavior.

Regards,
CK

> 
> Regards,
> CK
> 
> > 
> > Cheers,
> > Angelo
> > 
> > > Regards,
> > > CK
> > > 
> > > 
> > > > +       if (ret) {
> > > > +               dev_err(hdmi->dev, "Cannot resume HDMI\n");
> > > > +               return ret;
> > > > +       }
> > > > +
> > > > +       mtk_hdmi_v2_clk_enable(hdmi);
> > > > +       mtk_hdmi_hw_reset(hdmi);
> > > > +       mtk_hdmi_set_sw_hpd(hdmi, true);
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +


From ck.hu at mediatek.com  Wed Dec  4 19:16:30 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 5 Dec 2024 03:16:30 +0000
Subject: [PATCH v1 6/7] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241120124512.134278-7-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-7-angelogioacchino.delregno@collabora.com>
Message-ID: <b032782b60db4c3cf86ab9a50c18e1c0a315f68b.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

>  /*
>   * HDMI audio codec callbacks
>   */
> @@ -1528,14 +1104,14 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
>         switch (daifmt->fmt) {
>         case HDMI_I2S:
>                 hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -               hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +               hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;

You change the name from aud_sampe_size to aud_sample_size.
So this is a refinement. Separate this to a refinement patch.

Regards,
CK

>                 hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
>                 hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
>                 hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
>                 break;
>         case HDMI_SPDIF:
>                 hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -               hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +               hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
>                 hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
>                 break;
>         default:
> @@ -1590,6 +1166,7 @@ static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
>                 memcpy(buf, hdmi->curr_conn->eld, min(sizeof(hdmi->curr_conn->eld), len));
>         else
>                 memset(buf, 0, len);
> +
>         return 0;
>  }
> 


From lkp at intel.com  Wed Dec  4 19:21:08 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 5 Dec 2024 11:21:08 +0800
Subject: [arm-platforms:pci/xgene-fixes-6.13 14/18]
 drivers/pci/controller/pci-xgene-msi.c:101:31: error: implicit declaration
 of function 'FIELD_PREP'
Message-ID: <202412051158.EfEkIVqu-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git pci/xgene-fixes-6.13
head:   32627e010975ae9817552c5e21d1860ce9c9bdfa
commit: 3d9c887e78e0ae9e97a531f2015c585b5c213a76 [14/18] PCI: xgene: Sanitise MSI allocation and affinity setting
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20241205/202412051158.EfEkIVqu-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241205/202412051158.EfEkIVqu-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/202412051158.EfEkIVqu-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from include/linux/swab.h:5,
                    from include/uapi/linux/byteorder/big_endian.h:14,
                    from include/linux/byteorder/big_endian.h:5,
                    from arch/arc/include/uapi/asm/byteorder.h:14,
                    from include/asm-generic/bitops/le.h:6,
                    from arch/arc/include/asm/bitops.h:192,
                    from include/linux/bitops.h:68,
                    from include/linux/thread_info.h:27,
                    from include/linux/sched.h:14,
                    from include/linux/ratelimit.h:6,
                    from include/linux/dev_printk.h:16,
                    from include/linux/device.h:15,
                    from include/linux/node.h:18,
                    from include/linux/cpu.h:17,
                    from drivers/pci/controller/pci-xgene-msi.c:9:
   drivers/pci/controller/pci-xgene-msi.c: In function 'xgene_msi_ir_read':
>> drivers/pci/controller/pci-xgene-msi.c:101:31: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
     101 |                              (FIELD_PREP(MSI_GROUP_MASK, msi_grp) |
         |                               ^~~~~~~~~~
   include/uapi/linux/swab.h:118:38: note: in definition of macro '__swab32'
     118 |         (__u32)(__builtin_constant_p(x) ?       \
         |                                      ^
   include/linux/byteorder/generic.h:89:21: note: in expansion of macro '__le32_to_cpu'
      89 | #define le32_to_cpu __le32_to_cpu
         |                     ^~~~~~~~~~~~~
   drivers/pci/controller/pci-xgene-msi.c:100:16: note: in expansion of macro 'readl_relaxed'
     100 |         return readl_relaxed(msi->msi_regs + MSI_IR0 +
         |                ^~~~~~~~~~~~~
   drivers/pci/controller/pci-xgene-msi.c: In function 'compute_hwirq':
>> drivers/pci/controller/pci-xgene-msi.c:114:18: error: implicit declaration of function 'FIELD_GET' [-Werror=implicit-function-declaration]
     114 |         return ((FIELD_GET(BIT(3), grp_idx) << 7)       |
         |                  ^~~~~~~~~
   cc1: some warnings being treated as errors


vim +/FIELD_PREP +101 drivers/pci/controller/pci-xgene-msi.c

    43	
    44	/*
    45	 * X-Gene v1 has 16 frames of MSI termination registers MSInIRx, where n is
    46	 * frame number (0..15), x is index of registers in each frame (0..7).  Each
    47	 * 32b register is at the beginning of a 64kB region, each frame occupying
    48	 * 512kB (and the whole thing 8MB of PA space).
    49	 *
    50	 * Each register supports 16 MSI vectors (0..15) to generate interrupts.
    51	 *
    52	 * Additionally, each MSI termination frame has 1 MSIINTn register (n is
    53	 * 0..15) to indicate the MSI pending status caused by 1 of its 8 index
    54	 * registers. Each 32b register is at the beginning of a 64kB region (and
    55	 * overall occupying an extra 1MB).
    56	 *
    57	 * There is one GIC IRQ assigned for each MSI termination frame, 16 in
    58	 * total.
    59	 *
    60	 * The register layout is as follows:
    61	 * MSI0IR0			base_addr
    62	 * MSI0IR1			base_addr +  0x10000
    63	 * ...				...
    64	 * MSI0IR6			base_addr +  0x60000
    65	 * MSI0IR7			base_addr +  0x70000
    66	 * MSI1IR0			base_addr +  0x80000
    67	 * MSI1IR1			base_addr +  0x90000
    68	 * ...				...
    69	 * MSI1IR7			base_addr +  0xF0000
    70	 * MSI2IR0			base_addr + 0x100000
    71	 * ...				...
    72	 * MSIFIR0			base_addr + 0x780000
    73	 * MSIFIR1			base_addr + 0x790000
    74	 * ...				...
    75	 * MSIFIR7			base_addr + 0x7F0000
    76	 * MSIINT0			base_addr + 0x800000
    77	 * MSIINT1			base_addr + 0x810000
    78	 * ...				...
    79	 * MSIINTF			base_addr + 0x8F0000
    80	 *
    81	 * In order to allow an MSI to be moved from one CPU to another without
    82	 * having to repaint both the address and the data (which cannot be done
    83	 * atomically), we statically partitions the MSI frames between CPUs. Given
    84	 * that XGene-1 has 8 CPUs, each CPU gets two frames assigned to it
    85	 *
    86	 * We adopt the convention that when an MSI is moved, it is configured to
    87	 * target the same register number in the new frame. This reserves a given
    88	 * MSI across all CPUs, and reduces the MSI capacity from 2048 to 256.
    89	 *
    90	 * Effectively, this amounts to:
    91	 * - hwirq[7]::cpu[2:0] is the target frame number
    92	 * - hwirq[6:4] is the register index in any given frame
    93	 * - hwirq[3:0] is the MSI data
    94	 */
    95	
    96	/* MSInIRx read helper */
    97	static u32 xgene_msi_ir_read(struct xgene_msi *msi,
    98					    u32 msi_grp, u32 msir_idx)
    99	{
   100		return readl_relaxed(msi->msi_regs + MSI_IR0 +
 > 101				     (FIELD_PREP(MSI_GROUP_MASK, msi_grp) |
   102				      FIELD_PREP(MSI_INDEX_MASK, msir_idx)));
   103	}
   104	
   105	/* MSIINTn read helper */
   106	static u32 xgene_msi_int_read(struct xgene_msi *msi, u32 msi_grp)
   107	{
   108		return readl_relaxed(msi->msi_regs + MSI_INT0 +
   109				     FIELD_PREP(MSI_INTR_MASK, msi_grp));
   110	}
   111	
   112	static irq_hw_number_t compute_hwirq(u32 grp_idx, u32 msir_idx, u32 intr_idx)
   113	{
 > 114		return ((FIELD_GET(BIT(3), grp_idx) << 7)	|
   115			(msir_idx << 4)				|
   116			intr_idx);
   117	}
   118	

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


From wens at csie.org  Wed Dec  4 19:22:48 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Thu, 5 Dec 2024 11:22:48 +0800
Subject: (subset) [PATCH v5 0/5] Add support for DMA of F1C100s
In-Reply-To: <932d4f7a-c9cf-4e48-afd3-476b6c0fbc86@prolan.hu>
References: <20241122161128.2619172-1-csokas.bence@prolan.hu>
 <173331833897.673424.223627111827356616.b4-ty@kernel.org> <932d4f7a-c9cf-4e48-afd3-476b6c0fbc86@prolan.hu>
Message-ID: <CAGb2v65M9g-3nLAe=7Q3sbJ2wtpvQXXVhb+h08m=2pWY6g7HzA@mail.gmail.com>

On Thu, Dec 5, 2024 at 7:55?AM Cs?k?s Bence <csokas.bence at prolan.hu> wrote:
>
> Hi,
>
> On 2024. 12. 04. 14:18, Vinod Koul wrote:
> >
> > On Fri, 22 Nov 2024 17:11:23 +0100, Cs?k?s, Bence wrote:
> >> Support for Allwinner F1C100s/200s series audio was
> >> submitted in 2018 as an RFC series, but was not merged,
> >> despite having only minor errors. However, this is
> >> essential for having audio on these SoCs.
> >> This series was forward-ported/rebased to the best of
> >> my abilities, on top of Linus' tree as of now:
> >> commit 28eb75e178d3 ("Merge tag 'drm-next-2024-11-21' of https://gitlab.freedesktop.org/drm/kernel")
> >>
> >> [...]
> >
> > Applied, thanks!
> >
> > [1/5] dma-engine: sun4i: Add a quirk to support different chips
> >        commit: eeca1b60138189ef1b9636709e578d0c9e0de517
> > [2/5] dma-engine: sun4i: Add has_reset option to quirk
> >        commit: 1f738d0c2f67ae3551e4543e8dddbfb44cdd9f53
> > [3/5] dt-bindings: dmaengine: Add Allwinner suniv F1C100s DMA
> >        commit: 1ad2ebf3be836e62792788f4cd105b30ca9178b6
> > [4/5] dma-engine: sun4i: Add support for Allwinner suniv F1C100s
> >        commit: 61785259d1eb4e4c4acef8551a2524441683dbf3
>
> Thanks! Though unfortunately, b4 has once again mangled my sign-off,
> leaving it empty :/

There's one or more issues filed for b4 regarding this. See
- https://github.com/mricon/b4/issues/50
- https://github.com/mricon/b4/issues/52  (filed by me)

ChenYu


From wens at csie.org  Wed Dec  4 19:29:20 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Thu, 5 Dec 2024 11:29:20 +0800
Subject: [PATCH 0/3] Add F1C100s audio support
In-Reply-To: <20241205000137.187450-1-csokas.bence@prolan.hu>
References: <20241205000137.187450-1-csokas.bence@prolan.hu>
Message-ID: <CAGb2v674BnpmyP6zC85zbCuKVN-gb3MQA=CiQoe7-eV8qqyM+Q@mail.gmail.com>

On Thu, Dec 5, 2024 at 8:03?AM Cs?k?s, Bence <csokas.bence at prolan.hu> wrote:
>
> Support for Allwinner F1C100s/200s series audio was
> merged in the for-next branches of the DMA and ALSA
> trees, the last step is to add the codec to DT.
> This series was forward-ported/rebased to the best of
> my abilities, on top of Linus' tree as of now:
> commit feffde684ac2 ("Merge tag 'for-6.13-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux")

There's no real need to resend just the DTS bits, though I appreciate
the effort of making it easier to pick. There should be no difference
due to rebasing, since we didn't have many F1C100s changes.

The DTS bits can only be merged after driver bits have been accepted,
otherwise we would get DT validation errors in -next. After the
notifications yesterday, I started to pick the patches, but it got
late so I hadn't pushed them out yet. Just want you to know that they
haven't been forgotten. :)

BTW, if you merge different patch series and resending, please keep
the highest version number, like you would when resending a single
patch series, and also provide reference links to the originals.
That way we know where it came from and which version it was from.
There have been cases where the latest version was rejected and
an older version was resent.


Thanks
ChenYu

> Mesih Kilinc (3):
>   ARM: dts: suniv: f1c100s: Add support for DMA
>   ARM: dts: suniv: f1c100s: Add support for Audio Codec
>   ARM: dts: suniv: f1c100s: Activate Audio Codec for Lichee Pi Nano
>
>  .../allwinner/suniv-f1c100s-licheepi-nano.dts |  8 +++++++
>  .../arm/boot/dts/allwinner/suniv-f1c100s.dtsi | 24 +++++++++++++++++++
>  2 files changed, 32 insertions(+)
>
> --
> 2.34.1
>
>


From ck.hu at mediatek.com  Wed Dec  4 19:40:01 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 5 Dec 2024 03:40:01 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
Message-ID: <d9ca3245c89813d78e7a25aa9d4a0868fb30d27e.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static int mtk_hdmi_v2_audio_hw_params(struct device *dev, void *data,
> +                                   struct hdmi_codec_daifmt *codec_daifmt,
> +                                   struct hdmi_codec_params *codec_params)
> +{

This function is almost the same as v1.
Try to make this function as common function.

Regards,
CK

> +       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +       struct hdmi_audio_param aud_params = { 0 };
> +
> +       if (!hdmi->bridge.encoder)
> +               return -ENODEV;
> +
> +       switch (codec_params->cea.channels) {
> +       case 2:
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> +               break;
> +       case 4:
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
> +               break;
> +       case 6:
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
> +               break;
> +       case 8:
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       switch (codec_params->sample_rate) {
> +       case 32000:
> +       case 44100:
> +       case 48000:
> +       case 88200:
> +       case 96000:
> +       case 176400:
> +       case 192000:
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       switch (codec_daifmt->fmt) {
> +       case HDMI_I2S:
> +               aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +               aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +               aud_params.aud_input_type = HDMI_AUD_INPUT_I2S;
> +               aud_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> +               aud_params.aud_mclk = HDMI_AUD_MCLK_128FS;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       memcpy(&aud_params.codec_params, codec_params, sizeof(aud_params.codec_params));
> +       mtk_hdmi_v2_audio_set_param(hdmi, &aud_params);
> +
> +       return 0;
> +}
> +

> 


From wenst at chromium.org  Wed Dec  4 19:41:01 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Thu, 5 Dec 2024 11:41:01 +0800
Subject: [PATCH 1/2] dt-bindings: mmc: mtk-sd: Document compatibles that
 need two register ranges
In-Reply-To: <4762E5F1-59F2-40D1-9D22-724107623AAB@public-files.de>
References: <20241204092855.1365638-1-wenst@chromium.org> <20241204092855.1365638-2-wenst@chromium.org>
 <4762E5F1-59F2-40D1-9D22-724107623AAB@public-files.de>
Message-ID: <CAGXv+5EYf9-r88nv7zDo8JFGhMFyzVPU1gBNwkETvGTp+27q0g@mail.gmail.com>

On Wed, Dec 4, 2024 at 6:38?PM Frank Wunderlich <frank-w at public-files.de> wrote:
>
> Am 4. Dezember 2024 10:28:52 MEZ schrieb Chen-Yu Tsai <wenst at chromium.org>:
> >Besides the MT8183's MMC controller and all its compatible derivatives,
> >the recently added MT7986 and MT8196 also require two register ranges.
> >This is based on the actual device trees.
>
> Hi
>
> Mt7988 is similar to mt7986 (only using different clock settings) and using 2 reg too.
>
> Currently there is no mmc node in mt7988 dts (i currently upstreaming it) so i guess this is why you have not yet noticed it.
>
> See this for more:
>
> https://patchwork.kernel.org/project/linux-mediatek/patch/20241202122602.30734-3-linux at fw-web.de/

I think I noticed it at the beginning, but it then slipped my mind. I
might have gotten it mixed up with mt7986.

> Maybe you can add mt7988 compatible here too in v2.

Will do.

Thanks
ChenYu

> Regards Frank
>
> >Properly enforce this in the binding.
> >
> >Fixes: 4a8bd2b07d88 ("dt-bindings: mmc: mtk-sd: Add mt7988 SoC")
> >Fixes: 58927c9dc4ab ("dt-bindings: mmc: mtk-sd: Add support for MT8196")
> >Cc: Frank Wunderlich <frank-w at public-files.de>
> >Cc: Andy-ld Lu <andy-ld.lu at mediatek.com>
> >Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> >---
> > Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 9 ++++++++-
> > 1 file changed, 8 insertions(+), 1 deletion(-)
> >
> >diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
> >index f86ebd81f5a5..9ea035928563 100644
> >--- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
> >+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
> >@@ -235,11 +235,18 @@ allOf:
> >       properties:
> >         compatible:
> >           contains:
> >-            const: mediatek,mt8183-mmc
> >+            enum:
> >+              - mediatek,mt7986-mmc
> >+              - mediatek,mt8183-mmc
> >+              - mediatek,mt8196-mmc
> >     then:
> >       properties:
> >         reg:
> >           minItems: 2
> >+    else:
> >+      properties:
> >+        reg:
> >+          maxItems: 1
> >
> >   - if:
> >       properties:
>
>
> regards Frank


From wens at csie.org  Wed Dec  4 20:16:00 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Thu, 5 Dec 2024 12:16:00 +0800
Subject: [PATCH] arm64: dts: allwinner: h616: rg35xx add missing regulator-ramp-delay
In-Reply-To: <20241203203824.23306-1-simons.philippe@gmail.com>
References: <20241203203824.23306-1-simons.philippe@gmail.com>
Message-ID: <CAGb2v67Uv3SVQSqox85qt_05aVvX0oCynNRoaN9BA1Nha3eo8w@mail.gmail.com>

On Wed, Dec 4, 2024 at 4:38?AM Philippe Simons
<simons.philippe at gmail.com> wrote:
>
> AXP datasheet says that ramp delay is 15.625 us/step,
> which is 10mV in our case.

(CC-ing Mark for knowledge on regulators)

If this is the property of the PMIC, it probably belongs in the driver,
in "regulator_desc.ramp_delay".

The "regulator-ramp-delay" in the DT can be used to override this
if the board has excessive ramp delay due to other design reasons.


ChenYu

> add missing regulator-ramp-delay to dcdc regulators accordingly
>
> Signed-off-by: Philippe Simons <simons.philippe at gmail.com>
> ---
>  .../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts    | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
> index 80ccab7b5..b6e76a804 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
> @@ -238,6 +238,7 @@ reg_dcdc1: dcdc1 {
>                                 regulator-always-on;
>                                 regulator-min-microvolt = <900000>;
>                                 regulator-max-microvolt = <1160000>;
> +                               regulator-ramp-delay = <640>;
>                                 regulator-name = "vdd-cpu";
>                         };
>
> @@ -245,6 +246,7 @@ reg_dcdc2: dcdc2 {
>                                 regulator-always-on;
>                                 regulator-min-microvolt = <940000>;
>                                 regulator-max-microvolt = <940000>;
> +                               regulator-ramp-delay = <640>;
>                                 regulator-name = "vdd-gpu-sys";
>                         };
>
> @@ -252,6 +254,7 @@ reg_dcdc3: dcdc3 {
>                                 regulator-always-on;
>                                 regulator-min-microvolt = <1100000>;
>                                 regulator-max-microvolt = <1100000>;
> +                               regulator-ramp-delay = <640>;
>                                 regulator-name = "vdd-dram";
>                         };
>
> --
> 2.47.1
>


From zmw12306 at gmail.com  Wed Dec  4 20:22:14 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Wed,  4 Dec 2024 23:22:14 -0500
Subject: [PATCH] pinctrl: nomadik: Add check for clk_enable()
Message-ID: <20241205042214.2410982-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error. Change return type of nmk_gpio_glitch_slpm_init casade.

Fixes: 3a19805920f1 ("pinctrl: nomadik: move all Nomadik drivers to subdir")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 29 +++++++++++++++++------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index f4f10c60c1d2..2207c9513afd 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -438,9 +438,9 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
  *  - Any spurious wake up event during switch sequence to be ignored and
  *    cleared
  */
-static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
+static int nmk_gpio_glitch_slpm_init(unsigned int *slpm)
 {
-	int i;
+	int i, ret;
 
 	for (i = 0; i < NMK_MAX_BANKS; i++) {
 		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
@@ -449,11 +449,15 @@ static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
 		if (!chip)
 			break;
 
-		clk_enable(chip->clk);
+		ret = clk_enable(chip->clk);
+		if (ret)
+			return ret;
 
 		slpm[i] = readl(chip->addr + NMK_GPIO_SLPC);
 		writel(temp, chip->addr + NMK_GPIO_SLPC);
 	}
+
+	return 0;
 }
 
 static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
@@ -923,7 +927,9 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 
 			slpm[nmk_chip->bank] &= ~BIT(bit);
 		}
-		nmk_gpio_glitch_slpm_init(slpm);
+		ret = nmk_gpio_glitch_slpm_init(slpm);
+		if (ret)
+			goto out_pre_slpm_init;
 	}
 
 	for (i = 0; i < g->grp.npins; i++) {
@@ -940,7 +946,10 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 		dev_dbg(npct->dev, "setting pin %d to altsetting %d\n",
 			g->grp.pins[i], g->altsetting);
 
-		clk_enable(nmk_chip->clk);
+		ret = clk_enable(nmk_chip->clk);
+		if (ret)
+			goto out_glitch;
+
 		/*
 		 * If the pin is switching to altfunc, and there was an
 		 * interrupt installed on it which has been lazy disabled,
@@ -988,6 +997,7 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 	struct nmk_gpio_chip *nmk_chip;
 	struct gpio_chip *chip;
 	unsigned int bit;
+	int ret;
 
 	if (!range) {
 		dev_err(npct->dev, "invalid range\n");
@@ -1004,7 +1014,9 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 
 	find_nmk_gpio_from_pin(pin, &bit);
 
-	clk_enable(nmk_chip->clk);
+	ret = clk_enable(nmk_chip->clk);
+	if (ret)
+		return ret;
 	/* 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);
@@ -1058,6 +1070,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
 	unsigned long cfg;
 	int pull, slpm, output, val, i;
 	bool lowemi, gpiomode, sleep;
+	int ret;
 
 	nmk_chip = find_nmk_gpio_from_pin(pin, &bit);
 	if (!nmk_chip) {
@@ -1116,7 +1129,9 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
 			output ? (val ? "high" : "low") : "",
 			lowemi ? "on" : "off");
 
-		clk_enable(nmk_chip->clk);
+		ret = clk_enable(nmk_chip->clk);
+		if (ret)
+			return ret;
 		if (gpiomode)
 			/* No glitch when going to GPIO mode */
 			__nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
-- 
2.34.1



From advaitdhamorikar at gmail.com  Wed Dec  4 20:26:57 2024
From: advaitdhamorikar at gmail.com (Advait Dhamorikar)
Date: Thu, 5 Dec 2024 09:56:57 +0530
Subject: [PATCH v2] drm/atmel_hlcdc: Fix uninitialized variable
In-Reply-To: <rr7pp6a77tmur62vu2xdpasokokta7g6kcgjcd4iydmzyqpd5e@z45genf4gsv3>
References: <20241007150904.9840-1-advaitdhamorikar@gmail.com> <rr7pp6a77tmur62vu2xdpasokokta7g6kcgjcd4iydmzyqpd5e@z45genf4gsv3>
Message-ID: <CAJ7bep+Hc4Uw1WUBANtR7UGfVrDVyFe_0iPJ=ja=EczO6kk9Nw@mail.gmail.com>

Hello,

Just a gentle ping, this patch was never applied.
Is there something more that needs to be done?

Thanks and regards,
Advait

On Mon, 14 Oct 2024 at 13:08, Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Mon, Oct 07, 2024 at 08:39:04PM +0530, Advait Dhamorikar wrote:
> > atmel_hlcdc_plane_update_buffers: may use an uninitialized
> > sr variable when the if condition remains unsatisfied.
> > The variable may contain an arbitrary value left from earlier computations.
> >
> > Reported-by: kernel test robot <lkp at intel.com>
> > Reported-by: Dan Carpenter <error27 at gmail.com>
> > Closes: https://lore.kernel.org/r/202409240320.MZPgi3Up-lkp at intel.com/
> > Signed-off-by: Advait Dhamorikar <advaitdhamorikar at gmail.com>
>
> Fixes: d498771b0b83 ("drm: atmel_hlcdc: Add support for XLCDC using IP specific driver ops")
>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>
> --
> With best wishes
> Dmitry


From vabhav.sharma at nxp.com  Wed Dec  4 20:56:31 2024
From: vabhav.sharma at nxp.com (Vabhav Sharma)
Date: Thu, 05 Dec 2024 05:56:31 +0100
Subject: [PATCH v4 0/4] firmware: imx: secvio: Add secvio support
Message-ID: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>

The tampers are security feature available on i.MX products and
managed by SNVS block.The tamper goal is to detect the variation
of hardware or physical parameters, which can indicate an attack.

The SNVS, which provides secure non-volatile storage, allows to
detect some hardware attacks against the SoC.They are connected
to the security-violation ports, which send an alert when an
out-of-range value is detected.

This detection is done by:
-Analog tampers: measure analogic values
	- External clock frequency.
	- Temperature.
	- Voltage.

- Digital tampers:
	- External tamper
	- Other detectors:
		- Secure real-time counter rollover tamper.
		- Monotonic counter rollover tamper.
		- Power supply glitch tamper.

The on-chip sensors for voltage, temperature, and clock frequency
indicate if tamper scenarios may be present. These sensors generate an
out-of-range signal that causes a security violation to clear the
authentication and storage keys and to block access to sensitive
information.

Add linux module secvio driver to handle security violation interrupt.

The "imx-secvio-sc" module is designed to report security violations
and tamper triggering to the user.

The functionalities of the module are accessible via the "debugfs"
kernel.The folder containing the interface files for the module is
"<kernel_debugfs>/secvio/".

Get status
Reading from the "info" file will return the status of security:
- Fuse related to security tampers.
- SNVS readable registers.
- DGO registers.

To: Rob Herring <robh at kernel.org>
To: Krzysztof Kozlowski <krzk+dt at kernel.org>
To: Conor Dooley <conor+dt at kernel.org>
To: Dong Aisheng <aisheng.dong at nxp.com>
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>
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: imx at lists.linux.dev
Cc: linux-arm-kernel at lists.infradead.org
Cc: frank.li at nxp.com
Cc: pankaj.gupta at nxp.com
Cc: daniel.baluta at nxp.com
Cc: silvano.dininno at nxp.com
Cc: V.Sethi at nxp.com
Cc: meenakshi.aggarwal at nxp.com
Signed-off-by: Vabhav Sharma <vabhav.sharma at nxp.com>

Changes in v4:
- Modify description of NVMEM controller handle to be used by snvs driver.
- Modify the type of argument1 in copy_to_user() in imx_secvio_sc_ioctl().
- Modified the type of argument 2 in copy_from_user() in imx_secvio_sc_ioctl().
- Modified the type of variable as static for structure device, platform_device.
- Export the API imx_scu_secvio_init() to be used in SCU probe imx_scu_probe().
- Link to v3: https://lore.kernel.org/r/20241107-secvio-v3-0-ea27f1e9ced4 at nxp.com

Changes in v3:
- Dropped [PATCH 1/4] dt-bindings: firmware: secvio: Add device tree bindings.
	- Reuse SCU node to prove secvio driver asynchronously.
- Dropped [PATCH 4/4] arm64: dts: imx8q: Add node for Security Violation.
	- Removed explicit secvio sub-node within SCU node.
- Create seperate secvio platform devices.
	- secvio driver probe asynchronously.
	- SCU driver keep going and finish the probe first.
	- added new function imx_scu_secvio_init() called within imx_scu_probe()
- Link to v2: https://lore.kernel.org/r/20240509-secvio-v1-0-90fbe2baeda2 at nxp.com

Changes in v2:
- used b4 to add the devicetree list.
	- Added all necessary to/cc list.
- Link to v1: https://lore.kernel.org/r/20240501053205.1737248-1-vabhav.sharma at nxp.com

---
Vabhav Sharma (4):
      dt-bindings: firmware: imx: add nvmem phandle
      arm64: dts: imx8qxp: add node for nvmem property
      firmware: imx: Add SC APIs required for secvio module
      firmware: imx: secvio: Add support for SNVS secvio and tamper via SCFW

 .../devicetree/bindings/firmware/fsl,scu.yaml      |   3 +
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi         |   1 +
 drivers/firmware/imx/Kconfig                       |  11 +
 drivers/firmware/imx/Makefile                      |   4 +-
 drivers/firmware/imx/imx-scu-secvio-debugfs.c      | 274 +++++++++
 drivers/firmware/imx/imx-scu-secvio.c              | 619 +++++++++++++++++++++
 drivers/firmware/imx/imx-scu.c                     |   8 +-
 drivers/firmware/imx/seco.c                        | 216 +++++++
 include/linux/firmware/imx/ipc.h                   |   1 +
 include/linux/firmware/imx/sci.h                   |   9 +
 include/linux/firmware/imx/svc/imx-secvio-sc.h     | 216 +++++++
 include/linux/firmware/imx/svc/seco.h              |  69 +++
 12 files changed, 1429 insertions(+), 2 deletions(-)
---
base-commit: 9852d85ec9d492ebef56dc5f229416c925758edc
change-id: 20240508-secvio-8acfa2838385

Best regards,
-- 
Vabhav Sharma <vabhav.sharma at nxp.com>



From vabhav.sharma at nxp.com  Wed Dec  4 20:56:33 2024
From: vabhav.sharma at nxp.com (Vabhav Sharma)
Date: Thu, 05 Dec 2024 05:56:33 +0100
Subject: [PATCH v4 2/4] arm64: dts: imx8qxp: add node for nvmem property
In-Reply-To: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
Message-ID: <20241205-secvio-v4-2-5c37cdc39573@nxp.com>

Add nvmem property to be used by secvio driver.

Signed-off-by: Vabhav Sharma <vabhav.sharma at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 0313f295de2e..2b1dd0addb50 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -210,6 +210,7 @@ system-controller {
 		mboxes = <&lsio_mu1 0 0
 			  &lsio_mu1 1 0
 			  &lsio_mu1 3 3>;
+		nvmem = <&ocotp>;
 
 		pd: power-controller {
 			compatible = "fsl,imx8qxp-scu-pd", "fsl,scu-pd";

-- 
2.25.1



From vabhav.sharma at nxp.com  Wed Dec  4 20:56:34 2024
From: vabhav.sharma at nxp.com (Vabhav Sharma)
Date: Thu, 05 Dec 2024 05:56:34 +0100
Subject: [PATCH v4 3/4] firmware: imx: Add SC APIs required for secvio
 module
In-Reply-To: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
Message-ID: <20241205-secvio-v4-3-5c37cdc39573@nxp.com>

The Security Violation module requires below System Controller
Security controller API to interact with SNVS block via SCFW
    - imx_sc_seco_build_info
    - imx_sc_seco_secvio_enable
    - imx_sc_seco_secvio_config
    - imx_sc_seco_secvio_dgo_config

Signed-off-by: Franck LENORMAND <franck.lenormand at nxp.com>
Reviewed-by: Iuliana Prodan <iuliana.prodan at nxp.com>
Reviewed-by: Horia Geanta<horia.geanta at nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
Signed-off-by: Vabhav Sharma <vabhav.sharma at nxp.com>
---
 drivers/firmware/imx/Makefile         |   2 +-
 drivers/firmware/imx/imx-scu.c        |   4 +-
 drivers/firmware/imx/seco.c           | 216 ++++++++++++++++++++++++++++++++++
 include/linux/firmware/imx/ipc.h      |   1 +
 include/linux/firmware/imx/sci.h      |   4 +
 include/linux/firmware/imx/svc/seco.h |  69 +++++++++++
 6 files changed, 294 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
index 8d046c341be8..7aaecf570c56 100644
--- a/drivers/firmware/imx/Makefile
+++ b/drivers/firmware/imx/Makefile
@@ -1,4 +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_SCU)		+= imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o seco.o
 obj-${CONFIG_IMX_SCMI_MISC_DRV}	+= sm-misc.o
diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
index 1dd4362ef9a3..c96dc73689a8 100644
--- a/drivers/firmware/imx/imx-scu.c
+++ b/drivers/firmware/imx/imx-scu.c
@@ -242,9 +242,11 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
 		 * APIs are defined as void function in SCU firmware, so they
 		 * should be treated as return success always.
 		 */
-		if ((saved_svc == IMX_SC_RPC_SVC_MISC) &&
+		if (((saved_svc == IMX_SC_RPC_SVC_MISC) &&
 			(saved_func == IMX_SC_MISC_FUNC_UNIQUE_ID ||
 			 saved_func == IMX_SC_MISC_FUNC_GET_BUTTON_STATUS))
+			 || (saved_svc == IMX_SC_RPC_SVC_SECO &&
+			 saved_func == IMX_SC_SECO_FUNC_BUILD_INFO))
 			ret = 0;
 	}
 
diff --git a/drivers/firmware/imx/seco.c b/drivers/firmware/imx/seco.c
new file mode 100644
index 000000000000..2d6bf301ac87
--- /dev/null
+++ b/drivers/firmware/imx/seco.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020, 2024 NXP
+ *
+ * File containing client-side RPC functions for the SECO service. These
+ * function are ported to clients that communicate to the SC.
+ */
+
+#include <linux/firmware/imx/sci.h>
+
+struct imx_sc_msg_seco_get_build_id {
+	struct imx_sc_rpc_msg hdr;
+	u32 version;
+	u32 commit;
+} __packed __aligned(4);
+
+int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
+			   uint32_t *commit)
+{
+	struct imx_sc_msg_seco_get_build_id msg;
+	struct imx_sc_rpc_msg *hdr = &msg.hdr;
+	int ret;
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = IMX_SC_RPC_SVC_SECO;
+	hdr->func = IMX_SC_SECO_FUNC_BUILD_INFO;
+	hdr->size = 1;
+
+	ret = imx_scu_call_rpc(ipc, &msg, true);
+	if (ret)
+		return ret;
+
+	if (version)
+		*version = msg.version;
+	if (commit)
+		*commit = msg.commit;
+
+	return 0;
+}
+EXPORT_SYMBOL(imx_sc_seco_build_info);
+
+int imx_sc_seco_secvio_enable(struct imx_sc_ipc *ipc)
+{
+	struct imx_sc_rpc_msg msg;
+	struct imx_sc_rpc_msg *hdr = &msg;
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = IMX_SC_RPC_SVC_SECO;
+	hdr->func = IMX_SC_SECO_FUNC_SECVIO_ENABLE;
+	hdr->size = 1;
+
+	return imx_scu_call_rpc(ipc, &msg, true);
+}
+EXPORT_SYMBOL(imx_sc_seco_secvio_enable);
+
+struct imx_sc_msg_req_seco_config {
+	struct imx_sc_rpc_msg hdr;
+	u32 data0;
+	u32 data1;
+	u32 data2;
+	u32 data3;
+	u32 data4;
+	u8 id;
+	u8 access;
+	u8 size;
+} __packed __aligned(4);
+
+struct imx_sc_msg_resp_seco_config {
+	struct imx_sc_rpc_msg hdr;
+	u32 data0;
+	u32 data1;
+	u32 data2;
+	u32 data3;
+	u32 data4;
+} __packed __aligned(4);
+
+int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+			      u32 *data0, u32 *data1, u32 *data2, u32 *data3,
+			      u32 *data4, u8 size)
+{
+	struct imx_sc_msg_req_seco_config msg;
+	struct imx_sc_msg_resp_seco_config *resp;
+	struct imx_sc_rpc_msg *hdr = &msg.hdr;
+	int ret;
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = IMX_SC_RPC_SVC_SECO;
+	hdr->func = IMX_SC_SECO_FUNC_SECVIO_CONFIG;
+	hdr->size = 7;
+
+	/* Check the pointers on data are valid and set it if doing a write */
+	switch (size) {
+	case 5:
+		if (data4) {
+			if (access)
+				msg.data4 = *data4;
+		} else {
+			return -EINVAL;
+		}
+		fallthrough;
+	case 4:
+		if (data3) {
+			if (access)
+				msg.data3 = *data3;
+		} else {
+			return -EINVAL;
+		}
+		fallthrough;
+	case 3:
+		if (data2) {
+			if (access)
+				msg.data2 = *data2;
+		} else {
+			return -EINVAL;
+		}
+		fallthrough;
+	case 2:
+		if (data1) {
+			if (access)
+				msg.data1 = *data1;
+		} else {
+			return -EINVAL;
+		}
+		fallthrough;
+	case 1:
+		if (data0) {
+			if (access)
+				msg.data0 = *data0;
+		} else {
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	msg.id = id;
+	msg.access = access;
+	msg.size = size;
+
+	ret = imx_scu_call_rpc(ipc, &msg, true);
+	if (ret)
+		return ret;
+
+	resp = (struct imx_sc_msg_resp_seco_config *)&msg;
+
+	/* Pointers already checked so we just copy the data if reading */
+	if (!access)
+		switch (size) {
+		case 5:
+			*data4 = resp->data4;
+		fallthrough;
+		case 4:
+			*data3 = resp->data3;
+		fallthrough;
+		case 3:
+			*data2 = resp->data2;
+		fallthrough;
+		case 2:
+			*data1 = resp->data1;
+		fallthrough;
+		case 1:
+			*data0 = resp->data0;
+		}
+
+	return 0;
+}
+EXPORT_SYMBOL(imx_sc_seco_secvio_config);
+
+struct imx_sc_msg_req_seco_dgo_config {
+	struct imx_sc_rpc_msg hdr;
+	u32 data;
+	u8 id;
+	u8 access;
+} __packed __aligned(4);
+
+struct imx_sc_msg_resp_seco_dgo_config {
+	struct imx_sc_rpc_msg hdr;
+	u32 data;
+} __packed __aligned(4);
+
+int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+				  u32 *data)
+{
+	struct imx_sc_msg_req_seco_dgo_config msg;
+	struct imx_sc_msg_resp_seco_dgo_config *resp;
+	struct imx_sc_rpc_msg *hdr = &msg.hdr;
+	int ret;
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = IMX_SC_RPC_SVC_SECO;
+	hdr->func = IMX_SC_SECO_FUNC_SECVIO_DGO_CONFIG;
+	hdr->size = 3;
+
+	if (access) {
+		if (data)
+			msg.data = *data;
+		else
+			return -EINVAL;
+	}
+
+	msg.access = access;
+	msg.id = id;
+
+	ret = imx_scu_call_rpc(ipc, &msg, true);
+	if (ret)
+		return ret;
+
+	resp = (struct imx_sc_msg_resp_seco_dgo_config *)&msg;
+
+	if (!access && data)
+		*data = resp->data;
+
+	return 0;
+}
+EXPORT_SYMBOL(imx_sc_seco_secvio_dgo_config);
diff --git a/include/linux/firmware/imx/ipc.h b/include/linux/firmware/imx/ipc.h
index 0b4643571625..df38ab8e7e2e 100644
--- a/include/linux/firmware/imx/ipc.h
+++ b/include/linux/firmware/imx/ipc.h
@@ -25,6 +25,7 @@ enum imx_sc_rpc_svc {
 	IMX_SC_RPC_SVC_PAD = 6,
 	IMX_SC_RPC_SVC_MISC = 7,
 	IMX_SC_RPC_SVC_IRQ = 8,
+	IMX_SC_RPC_SVC_SECO = 9,
 };
 
 struct imx_sc_rpc_msg {
diff --git a/include/linux/firmware/imx/sci.h b/include/linux/firmware/imx/sci.h
index df17196df5ff..947e49d8bebc 100644
--- a/include/linux/firmware/imx/sci.h
+++ b/include/linux/firmware/imx/sci.h
@@ -15,6 +15,10 @@
 #include <linux/firmware/imx/svc/misc.h>
 #include <linux/firmware/imx/svc/pm.h>
 #include <linux/firmware/imx/svc/rm.h>
+#include <linux/firmware/imx/svc/seco.h>
+
+#define IMX_SC_IRQ_SECVIO            BIT(6)    /* Security violation */
+#define IMX_SC_IRQ_GROUP_WAKE           3   /* Wakeup interrupts */
 
 #if IS_ENABLED(CONFIG_IMX_SCU)
 int imx_scu_enable_general_irq_channel(struct device *dev);
diff --git a/include/linux/firmware/imx/svc/seco.h b/include/linux/firmware/imx/svc/seco.h
new file mode 100644
index 000000000000..508444c02d39
--- /dev/null
+++ b/include/linux/firmware/imx/svc/seco.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2020, 2024 NXP
+ *
+ * Header file containing the public API for the System Controller (SC)
+ * Security Controller (SECO) function.
+ *
+ * SECO_SVC (SVC) Security Controller Service
+ *
+ * Module for the Security Controller (SECO) service.
+ */
+
+#ifndef _SC_SECO_API_H
+#define _SC_SECO_API_H
+
+#include <linux/errno.h>
+#include <linux/firmware/imx/sci.h>
+
+/*
+ * This type is used to indicate RPCs/RM/SECO function calls.
+ */
+enum imx_sc_seco_func {
+	IMX_SC_SECO_FUNC_UNKNOWN = 0,
+	IMX_SC_SECO_FUNC_BUILD_INFO = 16,
+	IMX_SC_SECO_FUNC_SECVIO_ENABLE = 25,
+	IMX_SC_SECO_FUNC_SECVIO_CONFIG = 26,
+	IMX_SC_SECO_FUNC_SECVIO_DGO_CONFIG = 27,
+};
+
+#if IS_ENABLED(CONFIG_IMX_SCU)
+int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
+			   uint32_t *commit);
+int imx_sc_seco_secvio_enable(struct imx_sc_ipc *ipc);
+int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+			      u32 *data0, u32 *data1, u32 *data2, u32 *data3,
+			      u32 *data4, u8 size);
+int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+				  u32 *data);
+#else /* IS_ENABLED(CONFIG_IMX_SCU) */
+static inline
+int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
+			   uint32_t *commit)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline
+int imx_sc_seco_secvio_enable(struct imx_sc_ipc *ipc)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline
+int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+			      u32 *data0, u32 *data1, u32 *data2, u32 *data3,
+			      u32 *data4, u8 size)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline
+int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+				  u32 *data)
+{
+	return -EOPNOTSUPP;
+}
+#endif /* IS_ENABLED(CONFIG_IMX_SCU) */
+
+#endif /* _SC_SECO_API_H */

-- 
2.25.1



From zmw12306 at gmail.com  Wed Dec  4 20:59:42 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Wed,  4 Dec 2024 23:59:42 -0500
Subject: [PATCH] pinctrl: stm32: Add check for clk_enable()
Message-ID: <20241205045942.2441430-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error. Add a cleanup loop to disable clocks already enabled in case
of an error during clock enabling for subsequent banks.

Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
 drivers/pinctrl/stm32/pinctrl-stm32.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index 5b7fa77c1184..eb7b2f864d88 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -1738,10 +1738,16 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
 	struct stm32_pinctrl_group *g = pctl->groups;
-	int i;
+	int i, j, ret;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_enable(pctl->banks[i].clk);
+	for (i = 0; i < pctl->nbanks; i++) {
+		ret = clk_enable(pctl->banks[i].clk);
+		if (ret) {
+			for (j = 0; j < i; j++)
+				clk_disable(pctl->banks[j].clk);
+			return ret;
+		}
+	}
 
 	for (i = 0; i < pctl->ngroups; i++, g++)
 		stm32_pinctrl_restore_gpio_regs(pctl, g->pin);
-- 
2.34.1



From vabhav.sharma at nxp.com  Wed Dec  4 20:56:32 2024
From: vabhav.sharma at nxp.com (Vabhav Sharma)
Date: Thu, 05 Dec 2024 05:56:32 +0100
Subject: [PATCH v4 1/4] dt-bindings: firmware: imx: add nvmem phandle
In-Reply-To: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
Message-ID: <20241205-secvio-v4-1-5c37cdc39573@nxp.com>

nvmem phandle is required by secvio driver to
read fuse.

Signed-off-by: Vabhav Sharma <vabhav.sharma at nxp.com>
---
 Documentation/devicetree/bindings/firmware/fsl,scu.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
index 557e524786c2..c88d9c2dac24 100644
--- a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
+++ b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
@@ -112,6 +112,9 @@ properties:
           - const: rx2
           - const: rx3
           - const: gip3
+  nvmem:
+    description:
+      phandle of NVMEM controller provided by the SCU
 
   pinctrl:
     description:

-- 
2.25.1



From vabhav.sharma at nxp.com  Wed Dec  4 20:56:35 2024
From: vabhav.sharma at nxp.com (Vabhav Sharma)
Date: Thu, 05 Dec 2024 05:56:35 +0100
Subject: [PATCH v4 4/4] firmware: imx: secvio: Add support for SNVS secvio
 and tamper via SCFW
In-Reply-To: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
Message-ID: <20241205-secvio-v4-4-5c37cdc39573@nxp.com>

The i.MX8QXP SoC contains the Secure Non-Volatile Storage (SNVS)
block. This block can detect specific hardware attacks.This block
can only be accessible using the SCFW API.

This module interact with the SCU which relay request to/from the
SNVS block to detect if security violation occurred.

The driver register an IRQ handle to SCU for security violation
interrupt.

When an interruption is fired, the driver inform the user.

Signed-off-by: Franck LENORMAND <franck.lenormand at nxp.com>
Signed-off-by: Vabhav Sharma <vabhav.sharma at nxp.com>
---
 drivers/firmware/imx/Kconfig                   |  11 +
 drivers/firmware/imx/Makefile                  |   2 +
 drivers/firmware/imx/imx-scu-secvio-debugfs.c  | 274 +++++++++++
 drivers/firmware/imx/imx-scu-secvio.c          | 619 +++++++++++++++++++++++++
 drivers/firmware/imx/imx-scu.c                 |   4 +
 include/linux/firmware/imx/sci.h               |   5 +
 include/linux/firmware/imx/svc/imx-secvio-sc.h | 216 +++++++++
 7 files changed, 1131 insertions(+)

diff --git a/drivers/firmware/imx/Kconfig b/drivers/firmware/imx/Kconfig
index 477d3f32d99a..14976bd9f5c6 100644
--- a/drivers/firmware/imx/Kconfig
+++ b/drivers/firmware/imx/Kconfig
@@ -33,3 +33,14 @@ config IMX_SCMI_MISC_DRV
 	  core that could provide misc functions such as board control.
 
 	  This driver can also be built as a module.
+
+config SECVIO_SC
+	tristate "NXP SC secvio support"
+	depends on IMX_SCU
+	default y
+	help
+	   If you say yes here you get support for the NXP SNVS security
+	   violation module. It includes the possibility to read information
+	   related to security violations and tampers. It also gives the
+	   possibility to register user callbacks when a security violation
+	   occurs.
diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
index 7aaecf570c56..80a2bd4bbc2d 100644
--- a/drivers/firmware/imx/Makefile
+++ b/drivers/firmware/imx/Makefile
@@ -2,3 +2,5 @@
 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 seco.o
 obj-${CONFIG_IMX_SCMI_MISC_DRV}	+= sm-misc.o
+obj-$(CONFIG_SECVIO_SC)		+= imx-scu-secvio.o
+obj-$(CONFIG_DEBUG_FS)		+= imx-scu-secvio-debugfs.o
diff --git a/drivers/firmware/imx/imx-scu-secvio-debugfs.c b/drivers/firmware/imx/imx-scu-secvio-debugfs.c
new file mode 100644
index 000000000000..55bce7d0b7b4
--- /dev/null
+++ b/drivers/firmware/imx/imx-scu-secvio-debugfs.c
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019, 2024 NXP
+ */
+
+/*
+ * The module exposes below files in debugfs:
+ *  - secvio/info:
+ *      * Read: It returns the value of the fuses and SNVS registers which are
+ *              readable and related to secvio and tampers.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/nvmem-consumer.h>
+
+#include <linux/firmware/imx/svc/misc.h>
+#include <linux/firmware/imx/svc/seco.h>
+
+#include <linux/firmware/imx/svc/imx-secvio-sc.h>
+
+static int fuse_reader(struct device *dev, u32 id, u32 *value, u8 mul)
+{
+	struct imx_secvio_sc_data *data = dev_get_drvdata(dev);
+	u32 size_to_read = mul * sizeof(u32);
+	int ret;
+
+	ret = nvmem_device_read(data->nvmem, id, size_to_read, value);
+	if (ret < 0) {
+		dev_err(data->dev, "Failed to read fuse %d: %d\n", id, ret);
+		return ret;
+	}
+
+	if (ret != size_to_read) {
+		dev_err(data->dev, "Read only %d instead of %d\n", ret,
+			size_to_read);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int snvs_reader(struct device *dev, u32 id, u32 *value, u8 mul)
+{
+	int ret;
+	u32 *v1, *v2, *v3, *v4, *v5;
+	struct imx_secvio_sc_data *data;
+
+	data = dev_get_drvdata(dev);
+	v1 = NULL;
+	v2 = NULL;
+	v3 = NULL;
+	v4 = NULL;
+	v5 = NULL;
+
+	switch (mul) {
+	case 5:
+		v5 = &value[4];
+		fallthrough;
+	case 4:
+		v4 = &value[3];
+		fallthrough;
+	case 3:
+		v3 = &value[2];
+		fallthrough;
+	case 2:
+		v2 = &value[1];
+		fallthrough;
+	case 1:
+		v1 = &value[0];
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = imx_sc_seco_secvio_config(data->ipc_handle, id, SECVIO_CONFIG_READ,
+					v1, v2, v3, v4, v5, mul);
+	if (ret < 0)
+		dev_err(dev, "Failed to read snvs reg %d: %d\n", id, ret);
+
+	return ret;
+}
+
+static int snvs_dgo_reader(struct device *dev, u32 id, u32 *value, u8 mul)
+{
+	struct imx_secvio_sc_data *data = dev_get_drvdata(dev);
+	int ret;
+
+	if (mul != 1)
+		return -EINVAL;
+
+	ret = imx_sc_seco_secvio_dgo_config(data->ipc_handle, id,
+					    SECVIO_CONFIG_READ, value);
+	if (ret)
+		dev_err(dev, "Failed to read snvs dgo reg %d: %d\n", id, ret);
+
+	return ret;
+}
+
+static const struct imx_secvio_info_entry {
+	int (*reader)(struct device *dev, u32 id, u32 *value, u8 mul);
+	const char *type;
+	const char *name;
+	u32 id;
+	u8 mul;
+} gs_imx_secvio_info_list[] = {
+	{fuse_reader, "fuse", "trim", 30, 1},
+	{fuse_reader, "fuse", "trim2", 31, 1},
+	{fuse_reader, "fuse", "ctrim1", 260, 1},
+	{fuse_reader, "fuse", "ctrim2", 261, 1},
+	{fuse_reader, "fuse", "ctrim3", 262, 1},
+	{fuse_reader, "fuse", "ctrim4", 263, 1},
+	{fuse_reader, "fuse", "OSC_CAP", 768, 1},
+
+	{snvs_reader, "snvs", "HPLR",    0x0, 1},
+	{snvs_reader, "snvs", "LPLR",    0x34, 1},
+	{snvs_reader, "snvs", "HPSICR",  0xc, 1},
+	{snvs_reader, "snvs", "HPSVCR",  0x10, 1},
+	{snvs_reader, "snvs", "HPSVS",   0x18, 1},
+	{snvs_reader, "snvs", "LPSVC",   0x40, 1},
+	{snvs_reader, "snvs", "LPTDC",   0x48, 2},
+	{snvs_reader, "snvs", "LPSR",    0x4c, 1},
+	{snvs_reader, "snvs", "LPTDS",   0xa4, 1},
+	{snvs_reader, "snvs", "LPTGFC",  0x44, 3},
+	{snvs_reader, "snvs", "LPATCTL", 0xe0, 1},
+	{snvs_reader, "snvs", "LPATCLK", 0xe4, 1},
+	{snvs_reader, "snvs", "LPATRC1", 0xe8, 2},
+	{snvs_reader, "snvs", "LPMKC",   0x3c, 1},
+	{snvs_reader, "snvs", "LPSMC",   0x5c, 2},
+	{snvs_reader, "snvs", "LPPGD",   0x64, 1},
+	{snvs_reader, "snvs", "HPVID",   0xf8, 2},
+
+	{snvs_dgo_reader, "dgo", "Offset",  0x0, 1},
+	{snvs_dgo_reader, "dgo", "PUP/PD",  0x10, 1},
+	{snvs_dgo_reader, "dgo", "Anatest", 0x20, 1},
+	{snvs_dgo_reader, "dgo", "T trim",  0x30, 1},
+	{snvs_dgo_reader, "dgo", "Misc",    0x40, 1},
+	{snvs_dgo_reader, "dgo", "Vmon",    0x50, 1},
+};
+
+struct imx_secvio_sc_info_seq_data {
+	struct device *dev;
+	const struct imx_secvio_info_entry *list;
+	int size;
+};
+
+static void *imx_secvio_sc_info_seq_start(struct seq_file *m, loff_t *pos)
+{
+	struct imx_secvio_sc_info_seq_data *data = m->private;
+
+	/* Check we are not out of bound */
+	if (*pos >= data->size)
+		return NULL;
+
+	return (void *)pos;
+}
+
+static void *imx_secvio_sc_info_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	/* Increment the counter */
+	++*pos;
+
+	/* call the start function which will check the index */
+	return imx_secvio_sc_info_seq_start(m, pos);
+}
+
+static void imx_secvio_sc_info_seq_stop(struct seq_file *m, void *v)
+{
+}
+
+static int imx_secvio_sc_info_seq_show(struct seq_file *m, void *v)
+{
+	struct imx_secvio_sc_info_seq_data *data = m->private;
+	const struct imx_secvio_info_entry *e;
+	int ret;
+	u32 vals[5];
+	int idx;
+
+	idx = *(loff_t *)v;
+	e = &data->list[idx];
+
+	/* Read the values */
+	ret = e->reader(data->dev, e->id, (u32 *)&vals, e->mul);
+	if (ret) {
+		dev_err(data->dev, "Fail to read %s %s (idx %d)\n", e->type,
+			e->name, e->id);
+		return 0;
+	}
+
+	seq_printf(m, "%5s/%-10s(%.3d):", e->type, e->name, e->id);
+
+	/* Loop over the values */
+	for (idx = 0; idx < e->mul; idx++)
+		seq_printf(m, " %.8x", vals[idx]);
+
+	seq_puts(m, "\n");
+
+	return 0;
+}
+
+static const struct seq_operations imx_secvio_sc_info_seq_ops = {
+	.start = imx_secvio_sc_info_seq_start,
+	.next  = imx_secvio_sc_info_seq_next,
+	.stop  = imx_secvio_sc_info_seq_stop,
+	.show  = imx_secvio_sc_info_seq_show,
+};
+
+static int imx_secvio_sc_info_open(struct inode *inode, struct file *file)
+{
+	struct imx_secvio_sc_info_seq_data *data;
+
+	data = __seq_open_private(file, &imx_secvio_sc_info_seq_ops, sizeof(*data));
+	if (!data)
+		return -ENOMEM;
+
+	data->dev = inode->i_private;
+	data->list = gs_imx_secvio_info_list;
+	data->size = ARRAY_SIZE(gs_imx_secvio_info_list);
+
+	return 0;
+}
+
+static const struct file_operations imx_secvio_sc_info_ops = {
+	.owner = THIS_MODULE,
+	.open = imx_secvio_sc_info_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release_private,
+};
+
+static void if_debugfs_remove_recursive(void *dentry)
+{
+	debugfs_remove_recursive(dentry);
+}
+
+int imx_secvio_sc_debugfs(struct device *dev)
+{
+	struct imx_secvio_sc_data *data = dev_get_drvdata(dev);
+	struct dentry *dir;
+	int ret = 0;
+
+	/* Create a folder */
+	dir = debugfs_create_dir(dev_name(dev), NULL);
+	if (IS_ERR(dir)) {
+		dev_err(dev, "Failed to create dfs dir\n");
+		ret = PTR_ERR(dir);
+		goto exit;
+	}
+	data->dfs = dir;
+
+	ret = devm_add_action(dev, if_debugfs_remove_recursive, data->dfs);
+	if (ret) {
+		dev_err(dev, "Failed to add managed action to disable IRQ\n");
+		goto remove_fs;
+	}
+
+	/* Create the file to read info and write to reg */
+	dir = debugfs_create_file("info", 0x666, data->dfs, dev,
+				  &imx_secvio_sc_info_ops);
+	if (IS_ERR(dir)) {
+		dev_err(dev, "Failed to add info to debugfs\n");
+		ret = PTR_ERR(dir);
+		goto exit;
+	}
+
+exit:
+	return ret;
+
+remove_fs:
+	debugfs_remove_recursive(data->dfs);
+	goto exit;
+}
diff --git a/drivers/firmware/imx/imx-scu-secvio.c b/drivers/firmware/imx/imx-scu-secvio.c
new file mode 100644
index 000000000000..30eb9e4bf7b8
--- /dev/null
+++ b/drivers/firmware/imx/imx-scu-secvio.c
@@ -0,0 +1,619 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019, 2024 NXP
+ *
+ */
+
+/*
+ * The i.MX8QXP SoC contains the Secure Non-Volatile Storage (SNVS) block. This
+ * block can detect specific hardware attacks.This block can only be accessible
+ * using the SCFW API.
+ *
+ * This module interact with the SCU which relay request to/from the SNVS block
+ * to detect if security violation occurred.
+ *
+ * The module exports an API to add processing when a SV is detected:
+ *  - register_imx_secvio_sc_notifier
+ *  - unregister_imx_secvio_sc_notifier
+ *  - imx_secvio_sc_check_state
+ *  - imx_secvio_sc_clear_state
+ *  - imx_secvio_sc_enable_irq
+ *  - imx_secvio_sc_disable_irq
+ */
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+
+#include <linux/uaccess.h>
+
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/sci.h>
+#include <linux/firmware/imx/svc/seco.h>
+#include <linux/firmware/imx/svc/rm.h>
+#include <linux/firmware/imx/svc/imx-secvio-sc.h>
+
+/* Reference on the driver_device */
+static struct device *imx_secvio_sc_dev;
+
+/* Register IDs for sc_seco_secvio_config API */
+#define HPSVS_ID 0x18
+#define LPS_ID 0x4c
+#define LPTDS_ID 0xa4
+#define HPVIDR_ID 0xf8
+
+#define SECO_MINOR_VERSION_SUPPORT_SECVIO_TAMPER 0x53
+#define SECO_VERSION_MINOR_MASK GENMASK(15, 0)
+
+static struct platform_driver imx_secvio_sc_driver;
+static struct platform_device *pdev;
+static struct device *scdev;
+
+/* Notifier list for new CB */
+static BLOCKING_NOTIFIER_HEAD(imx_secvio_sc_notifier_chain);
+
+int register_imx_secvio_sc_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&imx_secvio_sc_notifier_chain,
+						nb);
+}
+EXPORT_SYMBOL(register_imx_secvio_sc_notifier);
+
+int unregister_imx_secvio_sc_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&imx_secvio_sc_notifier_chain,
+						  nb);
+}
+EXPORT_SYMBOL(unregister_imx_secvio_sc_notifier);
+
+static void if_imx_scu_irq_register_notifier(void *nb)
+{
+	imx_scu_irq_register_notifier(nb);
+}
+
+static void if_unregister_imx_secvio_sc_notifier(void *nb)
+{
+	unregister_imx_secvio_sc_notifier(nb);
+}
+
+static
+int imx_secvio_sc_notifier_call_chain(struct secvio_sc_notifier_info *info)
+{
+	return blocking_notifier_call_chain(&imx_secvio_sc_notifier_chain, 0,
+					    (void *)info);
+}
+
+int imx_secvio_sc_get_state(struct device *dev,
+			    struct secvio_sc_notifier_info *info)
+{
+	int ret, err = 0;
+	struct imx_secvio_sc_data *data;
+
+	dev = imx_secvio_sc_dev;
+	if (!dev)
+		return -EINVAL;
+
+	data = dev_get_drvdata(dev);
+
+	/* Read secvio status */
+	ret = imx_sc_seco_secvio_config(data->ipc_handle, HPSVS_ID, SECVIO_CONFIG_READ,
+					&info->hpsvs, NULL, NULL, NULL, NULL, 1);
+	if (ret) {
+		err = ret;
+		dev_err(dev, "Fail read secvio config status %d\n", ret);
+	}
+	info->hpsvs &= HPSVS_ALL_SV_MASK;
+
+	/* Read tampers status */
+	ret = imx_sc_seco_secvio_config(data->ipc_handle, LPS_ID, SECVIO_CONFIG_READ,
+					&info->lps, NULL, NULL, NULL, NULL, 1);
+	if (ret) {
+		err = ret;
+		dev_err(dev, "Fail read tamper 1 status: %d\n", ret);
+	}
+	info->lps &= LPS_ALL_TP_MASK;
+
+	ret = imx_sc_seco_secvio_config(data->ipc_handle, LPTDS_ID, SECVIO_CONFIG_READ,
+					&info->lptds, NULL, NULL, NULL, NULL, 1);
+	if (ret) {
+		err = ret;
+		dev_err(dev, "Fail read  tamper 2 status: %d\n", ret);
+	}
+	info->lptds &= LPTDS_ALL_TP_MASK;
+
+	dev_dbg(dev, "Status: %.8x, %.8x, %.8x\n", info->hpsvs,
+		info->lps, info->lptds);
+
+	return err;
+}
+EXPORT_SYMBOL(imx_secvio_sc_get_state);
+
+int imx_secvio_sc_check_state(struct device *dev)
+{
+	struct secvio_sc_notifier_info info;
+	int ret;
+
+	dev = imx_secvio_sc_dev;
+
+	ret = imx_secvio_sc_get_state(dev, &info);
+	if (ret) {
+		dev_err(dev, "Failed to get secvio state\n");
+		return ret;
+	}
+
+	/* Call chain of CB registered to this module if status detected */
+	if (info.hpsvs || info.lps || info.lptds)
+		if (imx_secvio_sc_notifier_call_chain(&info))
+			dev_warn(dev,
+				 "Issues when calling the notifier chain\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(imx_secvio_sc_check_state);
+
+static int imx_secvio_sc_disable_irq(struct device *dev)
+{
+	int ret;
+
+	if (!dev)
+		return -EINVAL;
+
+	/* Disable the IRQ */
+	ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_SECVIO,
+				       false);
+	if (ret) {
+		dev_err(dev, "Cannot disable SCU IRQ: %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int imx_secvio_sc_enable_irq(struct device *dev)
+{
+	int ret = 0, err;
+	u32 irq_status;
+	struct imx_secvio_sc_data *data;
+
+	if (!dev)
+		return -EINVAL;
+
+	data = dev_get_drvdata(dev);
+
+	/* Enable the IRQ */
+	ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_SECVIO,
+				       true);
+	if (ret) {
+		dev_err(dev, "Cannot enable SCU IRQ: %d\n", ret);
+		goto exit;
+	}
+
+	/* Enable interrupt */
+	ret = imx_sc_seco_secvio_enable(data->ipc_handle);
+	if (ret) {
+		dev_err(dev, "Cannot enable SNVS irq: %d\n", ret);
+		goto exit;
+	}
+
+	/* Unmask interrupt */
+	ret = imx_scu_irq_get_status(IMX_SC_IRQ_GROUP_WAKE, &irq_status);
+	if (ret) {
+		dev_err(dev, "Cannot unmask irq: %d\n", ret);
+		goto exit;
+	}
+
+exit:
+	if (ret) {
+		err = imx_secvio_sc_disable_irq(dev);
+		if (err)
+			dev_warn(dev, "Failed to disable the IRQ\n");
+	}
+
+	return ret;
+}
+
+static int imx_secvio_sc_notify(struct notifier_block *nb,
+				unsigned long event, void *group)
+{
+	struct imx_secvio_sc_data *data =
+				container_of(nb, struct imx_secvio_sc_data,
+					     irq_nb);
+	struct device *dev = data->dev;
+	int ret;
+
+	/* Filter event for us */
+	if (!((event & IMX_SC_IRQ_SECVIO) &&
+	      (*(u8 *)group == IMX_SC_IRQ_GROUP_WAKE)))
+		return 0;
+
+	dev_warn(dev, "secvio security violation detected\n");
+
+	ret = imx_secvio_sc_check_state(dev);
+
+	/* Re-enable interrupt */
+	ret = imx_secvio_sc_enable_irq(dev);
+	if (ret)
+		dev_err(dev, "Failed to enable IRQ\n");
+
+	return ret;
+}
+
+int imx_secvio_sc_clear_state(struct device *dev, u32 hpsvs, u32 lps, u32 lptds)
+{
+	int ret;
+	struct imx_secvio_sc_data *data;
+
+	dev = imx_secvio_sc_dev;
+	if (!dev)
+		return -EINVAL;
+
+	data = dev_get_drvdata(dev);
+
+	ret = imx_sc_seco_secvio_config(data->ipc_handle, HPSVS_ID, SECVIO_CONFIG_WRITE,
+					&hpsvs, NULL, NULL, NULL, NULL, 1);
+	if (ret) {
+		dev_err(dev, "Fail to clear secvio status: %d\n", ret);
+		return ret;
+	}
+
+	ret = imx_sc_seco_secvio_config(data->ipc_handle, LPS_ID, SECVIO_CONFIG_WRITE,
+					&lps, NULL, NULL, NULL, NULL, 1);
+	if (ret) {
+		dev_err(dev, "Fail to clear tamper 1 status: %d\n", ret);
+		return ret;
+	}
+
+	ret = imx_sc_seco_secvio_config(data->ipc_handle, LPTDS_ID, SECVIO_CONFIG_WRITE,
+					&lptds, NULL, NULL, NULL, NULL, 1);
+	if (ret) {
+		dev_err(dev, "Fail to clear tamper 2 status: %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(imx_secvio_sc_clear_state);
+
+static int report_to_user_notify(struct notifier_block *nb,
+				 unsigned long status, void *notif_info)
+{
+	struct secvio_sc_notifier_info *info = notif_info;
+	struct imx_secvio_sc_data *data =
+				container_of(nb, struct imx_secvio_sc_data,
+					     report_nb);
+	struct device *dev = data->dev;
+
+	/* Information about the security violation */
+	if (info->hpsvs & HPSVS_LP_SEC_VIO_MASK)
+		dev_info(dev, "SNVS secvio: LPSV\n");
+	if (info->hpsvs & HPSVS_SW_LPSV_MASK)
+		dev_info(dev, "SNVS secvio: SW LPSV\n");
+	if (info->hpsvs & HPSVS_SW_FSV_MASK)
+		dev_info(dev, "SNVS secvio: SW FSV\n");
+	if (info->hpsvs & HPSVS_SW_SV_MASK)
+		dev_info(dev, "SNVS secvio: SW SV\n");
+	if (info->hpsvs & HPSVS_SV5_MASK)
+		dev_info(dev, "SNVS secvio: SV 5\n");
+	if (info->hpsvs & HPSVS_SV4_MASK)
+		dev_info(dev, "SNVS secvio: SV 4\n");
+	if (info->hpsvs & HPSVS_SV3_MASK)
+		dev_info(dev, "SNVS secvio: SV 3\n");
+	if (info->hpsvs & HPSVS_SV2_MASK)
+		dev_info(dev, "SNVS secvio: SV 2\n");
+	if (info->hpsvs & HPSVS_SV1_MASK)
+		dev_info(dev, "SNVS secvio: SV 1\n");
+	if (info->hpsvs & HPSVS_SV0_MASK)
+		dev_info(dev, "SNVS secvio: SV 0\n");
+
+	/* Information about the tampers */
+	if (info->lps & LPS_ESVD_MASK)
+		dev_info(dev, "SNVS tamper: External SV\n");
+	if (info->lps & LPS_ET2D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 2\n");
+	if (info->lps & LPS_ET1D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 1\n");
+	if (info->lps & LPS_WMT2D_MASK)
+		dev_info(dev, "SNVS tamper: Wire Mesh 2\n");
+	if (info->lps & LPS_WMT1D_MASK)
+		dev_info(dev, "SNVS tamper: Wire Mesh 1\n");
+	if (info->lps & LPS_VTD_MASK)
+		dev_info(dev, "SNVS tamper: Voltage\n");
+	if (info->lps & LPS_TTD_MASK)
+		dev_info(dev, "SNVS tamper: Temperature\n");
+	if (info->lps & LPS_CTD_MASK)
+		dev_info(dev, "SNVS tamper: Clock\n");
+	if (info->lps & LPS_PGD_MASK)
+		dev_info(dev, "SNVS tamper: Power Glitch\n");
+	if (info->lps & LPS_MCR_MASK)
+		dev_info(dev, "SNVS tamper: Monotonic Counter rollover\n");
+	if (info->lps & LPS_SRTCR_MASK)
+		dev_info(dev, "SNVS tamper: Secure RTC rollover\n");
+	if (info->lps & LPS_LPTA_MASK)
+		dev_info(dev, "SNVS tamper: Time alarm\n");
+
+	if (info->lptds & LPTDS_ET10D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 10\n");
+	if (info->lptds & LPTDS_ET9D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 9\n");
+	if (info->lptds & LPTDS_ET8D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 8\n");
+	if (info->lptds & LPTDS_ET7D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 7\n");
+	if (info->lptds & LPTDS_ET6D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 6\n");
+	if (info->lptds & LPTDS_ET5D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 5\n");
+	if (info->lptds & LPTDS_ET4D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 4\n");
+	if (info->lptds & LPTDS_ET3D_MASK)
+		dev_info(dev, "SNVS tamper: Tamper 3\n");
+
+	return 0;
+}
+
+static void if_imx_secvio_sc_disable_irq(void *dev)
+{
+	imx_secvio_sc_disable_irq(dev);
+}
+
+static int imx_secvio_sc_open(struct inode *node, struct file *filp)
+{
+	filp->private_data = node->i_private;
+
+	return 0;
+}
+
+static long imx_secvio_sc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct device *dev = file->private_data;
+	struct secvio_sc_notifier_info info;
+	int ret;
+
+	switch (cmd) {
+	case IMX_SECVIO_SC_GET_STATE:
+		ret = imx_secvio_sc_get_state(dev, &info);
+		if (ret)
+			return ret;
+
+		ret = copy_to_user((void __user *)arg, &info, sizeof(info));
+		if (ret) {
+			dev_err(dev, "Fail to copy info to user\n");
+			return -EFAULT;
+		}
+		break;
+	case IMX_SECVIO_SC_CHECK_STATE:
+		ret = imx_secvio_sc_check_state(dev);
+		if (ret)
+			return ret;
+		break;
+	case IMX_SECVIO_SC_CLEAR_STATE:
+		ret = copy_from_user(&info, (void __user *)arg, sizeof(info));
+		if (ret) {
+			dev_err(dev, "Fail to copy info from user\n");
+			return -EFAULT;
+		}
+
+		ret = imx_secvio_sc_clear_state(dev, info.hpsvs, info.lps,
+						    info.lptds);
+		if (ret)
+			return ret;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+	}
+
+	return ret;
+}
+
+static const struct file_operations imx_secvio_sc_fops = {
+	.owner = THIS_MODULE,
+	.open = imx_secvio_sc_open,
+	.unlocked_ioctl = imx_secvio_sc_ioctl,
+};
+
+static void if_misc_deregister(void *miscdevice)
+{
+	misc_deregister(miscdevice);
+}
+
+int imx_scu_secvio_init(struct device *np)
+{
+	int ret;
+
+	scdev = np;
+
+	pdev = platform_device_alloc("imx-secvio-sc", -1);
+	if (!pdev) {
+		pr_err("%s: secvio: Failed to allocate secvio device\n", __func__);
+		return -ENOMEM;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret != 0) {
+		pr_err("%s: secvio: Failed to add secvio device\n", __func__);
+		platform_device_put(pdev);
+		return ret;
+	}
+
+	ret = platform_driver_register(&imx_secvio_sc_driver);
+	if (ret != 0) {
+		pr_err("%s: secvio: Failed to register secvio driver\n", __func__);
+		platform_device_unregister(pdev);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(imx_scu_secvio_init);
+
+static int imx_secvio_sc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct imx_secvio_sc_data *data;
+	u32 seco_version = 0;
+	bool own_secvio;
+	u32 irq_status;
+	int ret;
+
+	/* Allocate private data */
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	if (!devres_open_group(dev, NULL, GFP_KERNEL))
+		return -ENOMEM;
+
+	data->dev = dev;
+
+	dev_set_drvdata(dev, data);
+
+	data->nvmem = devm_nvmem_device_get(scdev, NULL);
+	if (IS_ERR(data->nvmem)) {
+		ret = PTR_ERR(data->nvmem);
+
+		if (ret != -EPROBE_DEFER)
+			dev_err_probe(dev, ret, "Failed to retrieve nvmem\n");
+
+		goto clean;
+	}
+
+	/* Get a handle */
+	ret = imx_scu_get_handle(&data->ipc_handle);
+	if (ret) {
+		dev_err(dev, "cannot get handle to scu: %d\n", ret);
+		goto clean;
+	}
+
+	/* Check the version of the SECO */
+	ret = imx_sc_seco_build_info(data->ipc_handle, &seco_version, NULL);
+	if (ret) {
+		dev_err(dev, "Failed to get seco version\n");
+		goto clean;
+	}
+
+	if ((seco_version & SECO_VERSION_MINOR_MASK) <
+	     SECO_MINOR_VERSION_SUPPORT_SECVIO_TAMPER) {
+		dev_err(dev, "SECO version %.8x doesn't support all secvio\n",
+			seco_version);
+		ret = -EOPNOTSUPP;
+		goto clean;
+	}
+
+	/* Init debug FS */
+	ret = imx_secvio_sc_debugfs(dev);
+	if (ret) {
+		dev_err(dev, "Failed to set debugfs\n");
+		goto clean;
+	}
+
+	/* Check we own the SECVIO */
+	ret = imx_sc_rm_is_resource_owned(data->ipc_handle, IMX_SC_R_SECVIO);
+	if (ret < 0) {
+		dev_err(dev, "Failed to retrieve secvio ownership\n");
+		goto clean;
+	}
+
+	own_secvio = ret > 0;
+	if (!own_secvio) {
+		dev_err(dev, "Secvio resource is not owned\n");
+		ret = -EPERM;
+		goto clean;
+	}
+
+	/* Check IRQ exists and enable it */
+	ret = imx_scu_irq_get_status(IMX_SC_IRQ_GROUP_WAKE, &irq_status);
+	if (ret) {
+		dev_err(dev, "Cannot get IRQ state: %d\n", ret);
+		goto clean;
+	}
+
+	ret = imx_secvio_sc_enable_irq(dev);
+	if (ret) {
+		dev_err(dev, "Failed to enable IRQ\n");
+		goto clean;
+	}
+
+	ret = devm_add_action_or_reset(dev, if_imx_secvio_sc_disable_irq, dev);
+	if (ret) {
+		dev_err(dev, "Failed to add managed action to disable IRQ\n");
+		goto clean;
+	}
+
+	/* Register the notifier for IRQ from SNVS */
+	data->irq_nb.notifier_call = imx_secvio_sc_notify;
+	ret = imx_scu_irq_register_notifier(&data->irq_nb);
+	if (ret) {
+		dev_err(dev, "Failed to register IRQ notification handler\n");
+		goto clean;
+	}
+
+	ret = devm_add_action_or_reset(dev, if_imx_scu_irq_register_notifier,
+				       &data->irq_nb);
+	if (ret) {
+		dev_err(dev, "Failed to add action to remove irq notif\n");
+		goto clean;
+	}
+
+	/* Register the notification for reporting to user */
+	data->report_nb.notifier_call = report_to_user_notify;
+	ret = register_imx_secvio_sc_notifier(&data->report_nb);
+	if (ret) {
+		dev_err(dev, "Failed to register report notif handler\n");
+		goto clean;
+	}
+
+	ret = devm_add_action_or_reset(dev, if_unregister_imx_secvio_sc_notifier,
+				       &data->report_nb);
+	if (ret) {
+		dev_err(dev, "Failed to add action to remove report notif\n");
+		goto clean;
+	}
+
+	/* Register misc device for IOCTL */
+	data->miscdev.name = devm_kstrdup(dev, "secvio-sc", GFP_KERNEL);
+	data->miscdev.minor = MISC_DYNAMIC_MINOR;
+	data->miscdev.fops = &imx_secvio_sc_fops;
+	data->miscdev.parent = dev;
+	ret = misc_register(&data->miscdev);
+	if (ret) {
+		dev_err(dev, "failed to register misc device\n");
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(dev, if_misc_deregister, &data->miscdev);
+	if (ret) {
+		dev_err(dev, "Failed to add action to unregister miscdev\n");
+		goto clean;
+	}
+
+	imx_secvio_sc_dev = dev;
+
+	/* Process current state of the secvio and tampers */
+	imx_secvio_sc_check_state(dev);
+
+	devres_remove_group(dev, NULL);
+
+	return ret;
+
+clean:
+	devres_release_group(dev, NULL);
+
+	return ret;
+}
+
+static struct platform_driver imx_secvio_sc_driver = {
+	.driver = {
+		.name	= "imx-secvio-sc",
+		.probe_type     = PROBE_PREFER_ASYNCHRONOUS,
+	},
+	.probe		= imx_secvio_sc_probe,
+};
diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
index c96dc73689a8..5c27a767fe2f 100644
--- a/drivers/firmware/imx/imx-scu.c
+++ b/drivers/firmware/imx/imx-scu.c
@@ -339,6 +339,10 @@ static int imx_scu_probe(struct platform_device *pdev)
 		dev_warn(dev,
 			"failed to enable general irq channel: %d\n", ret);
 
+	ret = imx_scu_secvio_init(dev);
+	if (ret)
+		dev_warn(dev, "failed to initialize secvio: %d\n", ret);
+
 	dev_info(dev, "NXP i.MX SCU Initialized\n");
 
 	return devm_of_platform_populate(dev);
diff --git a/include/linux/firmware/imx/sci.h b/include/linux/firmware/imx/sci.h
index 947e49d8bebc..08237fa47c3d 100644
--- a/include/linux/firmware/imx/sci.h
+++ b/include/linux/firmware/imx/sci.h
@@ -27,7 +27,12 @@ int imx_scu_irq_unregister_notifier(struct notifier_block *nb);
 int imx_scu_irq_group_enable(u8 group, u32 mask, u8 enable);
 int imx_scu_irq_get_status(u8 group, u32 *irq_status);
 int imx_scu_soc_init(struct device *dev);
+int imx_scu_secvio_init(struct device *dev);
 #else
+static inline int imx_scu_secvio_init(struct device *dev)
+{
+	return -EOPNOTSUPP;
+}
 static inline int imx_scu_soc_init(struct device *dev)
 {
 	return -EOPNOTSUPP;
diff --git a/include/linux/firmware/imx/svc/imx-secvio-sc.h b/include/linux/firmware/imx/svc/imx-secvio-sc.h
new file mode 100644
index 000000000000..d8c9208217fe
--- /dev/null
+++ b/include/linux/firmware/imx/svc/imx-secvio-sc.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019, 2024 NXP
+ */
+
+#ifndef _MISC_IMX_SECVIO_SC_H_
+#define _MISC_IMX_SECVIO_SC_H_
+
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/notifier.h>
+
+/* Bitmask of the security violation status bit in the HPSVS register */
+#define HPSVS_LP_SEC_VIO_MASK BIT(31)
+#define HPSVS_SW_LPSV_MASK    BIT(15)
+#define HPSVS_SW_FSV_MASK     BIT(14)
+#define HPSVS_SW_SV_MASK      BIT(13)
+#define HPSVS_SV5_MASK        BIT(5)
+#define HPSVS_SV4_MASK        BIT(4)
+#define HPSVS_SV3_MASK        BIT(3)
+#define HPSVS_SV2_MASK        BIT(2)
+#define HPSVS_SV1_MASK        BIT(1)
+#define HPSVS_SV0_MASK        BIT(0)
+
+/* Bitmask of all security violation status bit in the HPSVS register */
+#define HPSVS_ALL_SV_MASK (HPSVS_LP_SEC_VIO_MASK | \
+			     HPSVS_SW_LPSV_MASK | \
+			     HPSVS_SW_FSV_MASK | \
+			     HPSVS_SW_SV_MASK | \
+			     HPSVS_SV5_MASK | \
+			     HPSVS_SV4_MASK | \
+			     HPSVS_SV3_MASK | \
+			     HPSVS_SV2_MASK | \
+			     HPSVS_SV1_MASK | \
+			     HPSVS_SV0_MASK)
+
+/*
+ * Bitmask of the security violation and tampers status bit in the LPS register
+ */
+#define LPS_ESVD_MASK  BIT(16)
+#define LPS_ET2D_MASK  BIT(10)
+#define LPS_ET1D_MASK  BIT(9)
+#define LPS_WMT2D_MASK BIT(8)
+#define LPS_WMT1D_MASK BIT(7)
+#define LPS_VTD_MASK   BIT(6)
+#define LPS_TTD_MASK   BIT(5)
+#define LPS_CTD_MASK   BIT(4)
+#define LPS_PGD_MASK   BIT(3)
+#define LPS_MCR_MASK   BIT(2)
+#define LPS_SRTCR_MASK BIT(1)
+#define LPS_LPTA_MASK  BIT(0)
+
+/*
+ * Bitmask of all security violation and tampers status bit in the LPS register
+ */
+#define LPS_ALL_TP_MASK (LPS_ESVD_MASK | \
+			   LPS_ET2D_MASK | \
+			   LPS_ET1D_MASK | \
+			   LPS_WMT2D_MASK | \
+			   LPS_WMT1D_MASK | \
+			   LPS_VTD_MASK | \
+			   LPS_TTD_MASK | \
+			   LPS_CTD_MASK | \
+			   LPS_PGD_MASK | \
+			   LPS_MCR_MASK | \
+			   LPS_SRTCR_MASK | \
+			   LPS_LPTA_MASK)
+
+/*
+ * Bitmask of the security violation and tampers status bit in the LPTDS
+ * register
+ */
+#define LPTDS_ET10D_MASK  BIT(7)
+#define LPTDS_ET9D_MASK   BIT(6)
+#define LPTDS_ET8D_MASK   BIT(5)
+#define LPTDS_ET7D_MASK   BIT(4)
+#define LPTDS_ET6D_MASK   BIT(3)
+#define LPTDS_ET5D_MASK   BIT(2)
+#define LPTDS_ET4D_MASK   BIT(1)
+#define LPTDS_ET3D_MASK   BIT(0)
+
+/*
+ * Bitmask of all security violation and tampers status bit in the LPTDS
+ * register
+ */
+#define LPTDS_ALL_TP_MASK (LPTDS_ET10D_MASK | \
+			     LPTDS_ET9D_MASK | \
+			     LPTDS_ET8D_MASK | \
+			     LPTDS_ET7D_MASK | \
+			     LPTDS_ET6D_MASK | \
+			     LPTDS_ET5D_MASK | \
+			     LPTDS_ET4D_MASK | \
+			     LPTDS_ET3D_MASK)
+
+/* Access for sc_seco_secvio_config API */
+#define SECVIO_CONFIG_READ  0
+#define SECVIO_CONFIG_WRITE 1
+
+/* Internal Structure */
+struct imx_secvio_sc_data {
+	struct device *dev;
+
+	struct imx_sc_ipc *ipc_handle;
+
+	struct notifier_block irq_nb;
+	struct notifier_block report_nb;
+
+	struct nvmem_device *nvmem;
+
+	struct miscdevice miscdev;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *dfs;
+#endif
+
+	u32 version;
+};
+
+/* Struct for notification */
+/**
+ * struct secvio_sc_notifier_info - Information about the status of the SNVS
+ * @hpsvs: status from register HPSVS
+ * @lps:   status from register LPS
+ * @lptds: status from register LPTDS
+ */
+struct secvio_sc_notifier_info {
+	u32 hpsvs;
+	u32 lps;
+	u32 lptds;
+};
+
+/**
+ * register_imx_secvio_sc_notifier() - Register a notifier
+ *
+ * @nb: The notifier block structure
+ *
+ * Register a function to notify to the imx-secvio-sc module. The function
+ * will be notified when a check of the state of the SNVS happens: called by
+ * a user or triggered by an interruption form the SNVS.
+ *
+ * The struct secvio_sc_notifier_info is passed as data to the notifier.
+ *
+ * Return: 0 in case of success
+ */
+int register_imx_secvio_sc_notifier(struct notifier_block *nb);
+
+/**
+ * unregister_imx_secvio_sc_notifier() - Unregister a notifier
+ *
+ * @nb: The notifier block structure
+ *
+ * Return: 0 in case of success
+ */
+int unregister_imx_secvio_sc_notifier(struct notifier_block *nb);
+
+/**
+ * imx_secvio_sc_get_state() - Get the state of the SNVS
+ *
+ * @dev:  Pointer to the struct device of secvio
+ * @info: The structure containing the state of the SNVS
+ *
+ * Return: 0 in case of success
+ */
+int imx_secvio_sc_get_state(struct device *dev, struct secvio_sc_notifier_info *info);
+
+/**
+ * imx_secvio_sc_check_state() - Check the state of the SNVS
+ *
+ * If a security violation or a tamper is detected, the list of notifier
+ * (registered using register_imx_secvio_sc_notifier() ) will be called
+ *
+ * @dev: Pointer to the struct device of secvio
+ *
+ * Return: 0 in case of success
+ */
+int imx_secvio_sc_check_state(struct device *dev);
+
+/**
+ * imx_secvio_sc_clear_state() - Clear the state of the SNVS
+ *
+ * @dev:   Pointer to the struct device of secvio
+ * @hpsvs: Value to write to HPSVS register
+ * @lps:   Value to write to LPS register
+ * @lptds: Value to write to LPTDSregister
+ *
+ * The function will write the value provided to the corresponding register
+ * which will clear the status of the bits set.
+ *
+ * Return: 0 in case of success
+ */
+int imx_secvio_sc_clear_state(struct device *dev, u32 hpsvs, u32 lps, u32 lptds);
+
+/* Commands of the ioctl interface */
+enum ioctl_cmd_t {
+	GET_STATE,
+	CHECK_STATE,
+	CLEAR_STATE,
+};
+
+/* Definition for the ioctl interface */
+#define IMX_SECVIO_SC_GET_STATE   _IOR('S', GET_STATE, \
+				struct secvio_sc_notifier_info)
+#define IMX_SECVIO_SC_CHECK_STATE _IO('S', CHECK_STATE)
+#define IMX_SECVIO_SC_CLEAR_STATE _IOW('S', CLEAR_STATE, \
+				struct secvio_sc_notifier_info)
+
+#ifdef CONFIG_DEBUG_FS
+int imx_secvio_sc_debugfs(struct device *dev);
+#else
+static inline
+int imx_secvio_sc_debugfs(struct device *dev)
+{
+	return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+#endif /* _MISC_IMX_SECVIO_SC_H_ */

-- 
2.25.1



From marex at denx.de  Wed Dec  4 21:07:51 2024
From: marex at denx.de (Marek Vasut)
Date: Thu, 5 Dec 2024 06:07:51 +0100
Subject: [PATCH] pinctrl: stm32: Add check for clk_enable()
In-Reply-To: <20241205045942.2441430-1-zmw12306@gmail.com>
References: <20241205045942.2441430-1-zmw12306@gmail.com>
Message-ID: <3c809cae-991b-4b13-8d8b-bd6cbcc9a9b9@denx.de>

On 12/5/24 5:59 AM, Mingwei Zheng wrote:
> Add check for the return value of clk_enable() to catch the potential
> error. Add a cleanup loop to disable clocks already enabled in case
> of an error during clock enabling for subsequent banks.
> 
> Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
> ---
>   drivers/pinctrl/stm32/pinctrl-stm32.c | 12 +++++++++---
>   1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
> index 5b7fa77c1184..eb7b2f864d88 100644
> --- a/drivers/pinctrl/stm32/pinctrl-stm32.c
> +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
> @@ -1738,10 +1738,16 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
>   {
>   	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
>   	struct stm32_pinctrl_group *g = pctl->groups;
> -	int i;
> +	int i, j, ret;
>   
> -	for (i = 0; i < pctl->nbanks; i++)
> -		clk_enable(pctl->banks[i].clk);
> +	for (i = 0; i < pctl->nbanks; i++) {
> +		ret = clk_enable(pctl->banks[i].clk);
> +		if (ret) {
> +			for (j = 0; j < i; j++)

Instead of this open-coded loop, can you please convert the driver to 
clk_bulk*() API and then do simple clk_bulk_enable()/clk_bulk_disable() 
here and everywhere ?

Thank you


From zmw12306 at gmail.com  Wed Dec  4 21:17:46 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Thu,  5 Dec 2024 00:17:46 -0500
Subject: [PATCH] pwm: stm32-lp: Add check for clk_enable()
Message-ID: <20241205051746.2465490-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error.

Fixes: e70a540b4e02 ("pwm: Add STM32 LPTimer PWM driver")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
 drivers/pwm/pwm-stm32-lp.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
index 989731256f50..4abef304417d 100644
--- a/drivers/pwm/pwm-stm32-lp.c
+++ b/drivers/pwm/pwm-stm32-lp.c
@@ -163,12 +163,16 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
 	unsigned long rate = clk_get_rate(priv->clk);
 	u32 val, presc, prd;
 	u64 tmp;
+	int ret;
 
 	regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
 	state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
 	/* Keep PWM counter clock refcount in sync with PWM initial state */
-	if (state->enabled)
-		clk_enable(priv->clk);
+	if (state->enabled) {
+		ret = clk_enable(priv->clk);
+		if (ret)
+			return ret;
+	}
 
 	regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
 	presc = FIELD_GET(STM32_LPTIM_PRESC, val);
-- 
2.34.1



From val at packett.cool  Wed Dec  4 21:50:46 2024
From: val at packett.cool (Val Packett)
Date: Thu,  5 Dec 2024 02:50:46 -0300
Subject: [PATCH] clk: rockchip: add clock ID for CIF0/1 on RK3066
Message-ID: <20241205055122.11613-1-val@packett.cool>

RK3066 does have two "CIF" video capture interface blocks, add their
corresponding clock IDs so that they could be used.

Signed-off-by: Val Packett <val at packett.cool>
---
 drivers/clk/rockchip/clk-rk3188.c             | 4 ++--
 include/dt-bindings/clock/rk3188-cru-common.h | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 684233e72105..81e94b338d0f 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -344,7 +344,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 
 	GATE(0, "pclkin_cif0", "ext_cif0", 0,
 			RK2928_CLKGATE_CON(3), 3, GFLAGS),
-	INVERTER(0, "pclk_cif0", "pclkin_cif0",
+	INVERTER(PCLK_CIF0, "pclk_cif0", "pclkin_cif0",
 			RK2928_CLKSEL_CON(30), 8, IFLAGS),
 
 	FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
@@ -602,7 +602,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 
 	GATE(0, "pclkin_cif1", "ext_cif1", 0,
 			RK2928_CLKGATE_CON(3), 4, GFLAGS),
-	INVERTER(0, "pclk_cif1", "pclkin_cif1",
+	INVERTER(PCLK_CIF1, "pclk_cif1", "pclkin_cif1",
 			RK2928_CLKSEL_CON(30), 12, IFLAGS),
 
 	COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0,
diff --git a/include/dt-bindings/clock/rk3188-cru-common.h b/include/dt-bindings/clock/rk3188-cru-common.h
index 01e14ab252a7..dd988cc9d582 100644
--- a/include/dt-bindings/clock/rk3188-cru-common.h
+++ b/include/dt-bindings/clock/rk3188-cru-common.h
@@ -103,6 +103,8 @@
 #define PCLK_PERI		351
 #define PCLK_DDRUPCTL		352
 #define PCLK_PUBL		353
+#define PCLK_CIF0		354
+#define PCLK_CIF1		355
 
 /* hclk gates */
 #define HCLK_SDMMC		448
-- 
2.47.1



From ilkka at os.amperecomputing.com  Wed Dec  4 22:19:13 2024
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Thu,  5 Dec 2024 06:19:13 +0000
Subject: [PATCH 1/2] perf/dwc_pcie: Fix the event numbers
In-Reply-To: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
References: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
Message-ID: <20241205061914.5568-2-ilkka@os.amperecomputing.com>

According to Databook, L1 aux is event number 0x08 and
TX L0s and RX L0S is 0x09. Fix the event numbers for the
two events.

Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
---
 drivers/perf/dwc_pcie_pmu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
index 9cbea9675e21..890cf3bb43a2 100644
--- a/drivers/perf/dwc_pcie_pmu.c
+++ b/drivers/perf/dwc_pcie_pmu.c
@@ -199,8 +199,8 @@ static struct attribute *dwc_pcie_pmu_time_event_attrs[] = {
 	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(L1_1, 0x05),
 	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(L1_2, 0x06),
 	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(CFG_RCVRY, 0x07),
-	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(TX_RX_L0S, 0x08),
-	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(L1_AUX, 0x09),
+	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(L1_AUX, 0x08),
+	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(TX_RX_L0S, 0x09),
 
 	/* Group #1 */
 	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(tx_pcie_tlp_data_payload, 0x20),
-- 
2.47.0



From ilkka at os.amperecomputing.com  Wed Dec  4 22:19:12 2024
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Thu,  5 Dec 2024 06:19:12 +0000
Subject: [PATCH 0/2] perf/dwc_pcie: Fix the swapped event numbers as well as the documentation
Message-ID: <20241205061914.5568-1-ilkka@os.amperecomputing.com>

According to the versions of Designware Cores PCI Express Controller Databook
I found, the eventid for "L1 aux" is 0x08 and "TX L0s and RX L0S" is 0x09.

Shuai and Jing, could you verify that your document matches ours and the events
are indeed swapped in the driver at the moment?

Cheers, Ilkka



Ilkka Koskinen (2):
  perf/dwc_pcie: Fix the event numbers
  Documentation: dwc_pcie_pmu: Fix the mnemonics and eventid

 Documentation/admin-guide/perf/dwc_pcie_pmu.rst | 6 +++---
 drivers/perf/dwc_pcie_pmu.c                     | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

-- 
2.47.0



From ilkka at os.amperecomputing.com  Wed Dec  4 22:19:14 2024
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Thu,  5 Dec 2024 06:19:14 +0000
Subject: [PATCH 2/2] Documentation: dwc_pcie_pmu: Fix the mnemonics and eventid
In-Reply-To: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
References: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
Message-ID: <20241205061914.5568-3-ilkka@os.amperecomputing.com>

Fix the event id and type in the example. In addition, the recent fix,
which addressed the mnemonics with mixed case, didn't fix the document.
Match the names with the driver.

Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
---
 Documentation/admin-guide/perf/dwc_pcie_pmu.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/perf/dwc_pcie_pmu.rst b/Documentation/admin-guide/perf/dwc_pcie_pmu.rst
index 39b8e1fdd0cd..cb376f335f40 100644
--- a/Documentation/admin-guide/perf/dwc_pcie_pmu.rst
+++ b/Documentation/admin-guide/perf/dwc_pcie_pmu.rst
@@ -60,7 +60,7 @@ description of available events and configuration options in sysfs, see
 The "format" directory describes format of the config fields of the
 perf_event_attr structure. The "events" directory provides configuration
 templates for all documented events.  For example,
-"Rx_PCIe_TLP_Data_Payload" is an equivalent of "eventid=0x22,type=0x1".
+"rx_pcie_tlp_data_payload" is an equivalent of "eventid=0x21,type=0x0".
 
 The "perf list" command shall list the available events from sysfs, e.g.::
 
@@ -79,8 +79,8 @@ Example usage of counting PCIe RX TLP data payload (Units of bytes)::
 
 The average RX/TX bandwidth can be calculated using the following formula:
 
-    PCIe RX Bandwidth = Rx_PCIe_TLP_Data_Payload / Measure_Time_Window
-    PCIe TX Bandwidth = Tx_PCIe_TLP_Data_Payload / Measure_Time_Window
+    PCIe RX Bandwidth = rx_pcie_tlp_data_payload / Measure_Time_Window
+    PCIe TX Bandwidth = tx_pcie_tlp_data_payload / Measure_Time_Window
 
 Lane Event Usage
 -------------------------------
-- 
2.47.0



From andre.draszik at linaro.org  Wed Dec  4 22:22:18 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Thu, 05 Dec 2024 06:22:18 +0000
Subject: [PATCH 2/4] dt-bindings: power: supply: add max77759-fg flavor
 and don't require nvme address
In-Reply-To: <5281f86d-6917-4f4e-b85d-70502a24c5bd@uclouvain.be>
References: <20241202-b4-gs101_max77759_fg-v1-0-98d2fa7bfe30@uclouvain.be>
	 <20241202-b4-gs101_max77759_fg-v1-2-98d2fa7bfe30@uclouvain.be>
	 <e23721ebd766f410103ddfb8705f3d7d6e5ae3e9.camel@linaro.org>
	 <575b3275-b2fa-4e5c-bb6b-759394b02e18@uclouvain.be>
	 <30b0995903fb7db3f866d1304783d878f563fe2f.camel@linaro.org>
	 <5281f86d-6917-4f4e-b85d-70502a24c5bd@uclouvain.be>
Message-ID: <2a20b243ade39fa240f75baf22a13f02239e3411.camel@linaro.org>

On Wed, 2024-12-04 at 14:13 +0100, Thomas Antoine wrote:
> On 12/3/24 11:40, Andr? Draszik wrote:
> > On Tue, 2024-12-03 at 11:23 +0100, Thomas Antoine wrote:
> > > On 12/3/24 08:12, Andr? Draszik wrote:
> > > > On Mon, 2024-12-02 at 14:07 +0100, Thomas Antoine via B4 Relay wrote:
> > > > > From: Thomas Antoine <t.antoine at uclouvain.be>
> > > > > 
> > > > > As the Maxim max77759 fuel gauge has no non-volatile memory slave address,
> > > > > make it non-obligatory. Except for this, the max77759 seems to behave the
> > > > > same as the max1720x.
> > > > 
> > > > What about the battery characterization tables? Aren't they needed for
> > > > correct reporting?

[...]

> > 
> I looked into it. The probe function launches a delay work
> max1720x_model_work which will try multiple times to run
> max1720x_model_load which leads to
> max_m5_load_gauge_model -> max_m5_update_custom_model
> 
> This last function writes 0x0059 to 0x62 and 0x00c4 to 0x63 which unlocks
> the addresses from 0x80 to 0xaf.

OK. The regmap I had proposed was excluding those based on the
datasheet I have, but you probably noticed.

[...]

> If it is indeed the case and that all of those are equivalent to their
> max1720x counterpart, I think the management of those values should be
> added in another patch which implements it for both the max1720x (and possibly the
> max77759) as the mainline driver does not do anything with those values
> currently.

Thanks for the analysis! And yes, I agree.

Adding new required properties to a DT binding is an ABI break,
therefore I was trying to ensure the binding is complete from
the start.

Cheers,
Andre'



From Karl.Li at mediatek.com  Wed Dec  4 22:49:54 2024
From: Karl.Li at mediatek.com (=?utf-8?B?S2FybCBMaSAo5p2O5pm65ZiJKQ==?=)
Date: Thu, 5 Dec 2024 06:49:54 +0000
Subject: [PATCH v2 1/1] soc: mediatek: Add command for APU SMC call
In-Reply-To: <20241030013533.855696-2-karl.li@mediatek.com>
References: <20241030013533.855696-1-karl.li@mediatek.com>
	 <20241030013533.855696-2-karl.li@mediatek.com>
Message-ID: <b8de718de8d5b5357f67183c1d283180aff33f62.camel@mediatek.com>

Dead maintainers,

I hope you're doing well. Just a warm reminder that we're following up
on this patch and really appreciate any feedback you might have.

Thanks you in advance for your review.

Regards,
Karl

On Wed, 2024-10-30 at 09:35 +0800, Karl.Li wrote:
> From: Karl Li <karl.li at mediatek.com>
> 
> Add command for APU SMC call.
> The APU microprocess's start and stop sequence will process in ATF.
> 
> Signed-off-by: Karl Li <karl.li at mediatek.com>
> ---
> ?include/linux/firmware/mediatek/mtk-apu.h | 32
> +++++++++++++++++++++++
> ?1 file changed, 32 insertions(+)
> ?create mode 100644 include/linux/firmware/mediatek/mtk-apu.h
> 
> diff --git a/include/linux/firmware/mediatek/mtk-apu.h
> b/include/linux/firmware/mediatek/mtk-apu.h
> new file mode 100644
> index 000000000000..a327e31d40fa
> --- /dev/null
> +++ b/include/linux/firmware/mediatek/mtk-apu.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2024 MediaTek Inc.
> + */
> +
> +#ifndef __MEDIATEK_APU_H__
> +#define __MEDIATEK_APU_H__
> +
> +enum mtk_apusys_kernel_op {
> +	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON,		
> 	/*? 0 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF,		/*?
> 1 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER,		/*?
> 2 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP,		/*?
> 3 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT,		/*?
> 4 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP,		/*?
> 5 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP,		
> 	/*? 6 */
> +	MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX,			/*?
> 7 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM,		/*?
> 8 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR,	
> 	/*? 9 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR,		/*
> 10 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING,		/*
> 11 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING,		/*
> 12 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU,		/*
> 13 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP,		/*
> 14 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE,		/*
> 15 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C,		/*
> 16 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY,	/*
> 17 */
> +	MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN,		/*
> 18 */
> +	MTK_APUSYS_KERNEL_OP_NUM,
> +};
> +
> +#endif


From Karl.Li at mediatek.com  Wed Dec  4 23:05:30 2024
From: Karl.Li at mediatek.com (=?utf-8?B?S2FybCBMaSAo5p2O5pm65ZiJKQ==?=)
Date: Thu, 5 Dec 2024 07:05:30 +0000
Subject: [PATCH 3/3] mailbox: mediatek: Add mtk-apu-mailbox driver
In-Reply-To: <a3c3280478bf86eb97a422782ce60ec4eaa35224.camel@mediatek.com>
References: <20241024092608.431581-1-karl.li@mediatek.com>
	 <20241024092608.431581-4-karl.li@mediatek.com>
	 <083c8f7b-0969-4ca3-8a91-35f5767c5f32@collabora.com>
	 <CAGXv+5Fw+qZhTTgJq0QdiQHgiQP2ByR1tgae2+k4erx+0fp61g@mail.gmail.com>
	 <a3c3280478bf86eb97a422782ce60ec4eaa35224.camel@mediatek.com>
Message-ID: <0f98405c40530d81c342af06dea593e7babedeac.camel@mediatek.com>

Dead maintainers,

I hope you're doing well. Just a warm reminder that we're following up
on these patch and really appreciate any feedback you might have.

Thanks you in advance for your review.

Regards,
Karl

On Tue, 2024-10-29 at 16:27 +0800, Karl Li wrote:
> On Mon, 2024-10-28 at 14:16 +0800, Chen-Yu Tsai wrote:
> > 
> > External email : Please do not click links or open attachments
> > until
> > you have verified the sender or the content.
> > 
> > 
> > On Thu, Oct 24, 2024 at 7:13?PM AngeloGioacchino Del Regno
> > <angelogioacchino.delregno at collabora.com> wrote:
> > > 
> > > Il 24/10/24 11:25, Karl.Li ha scritto:
> > > > From: Karl Li <karl.li at mediatek.com>
> > > > 
> > > > Add mtk-apu-mailbox driver to support the communication with
> > > > APU remote microprocessor.
> > > > 
> > > > Also, the mailbox hardware contains extra spare (scratch)
> > > > registers
> > > > that other hardware blocks use to communicate through.
> > > > Expose these with custom mtk_apu_mbox_(read|write)() functions.
> > > > 
> > > > Signed-off-by: Karl Li <karl.li at mediatek.com>
> > > > ---
> > > > ? drivers/mailbox/Kconfig???????????????? |?? 9 +
> > > > ? drivers/mailbox/Makefile??????????????? |?? 2 +
> > > > ? drivers/mailbox/mtk-apu-mailbox.c?????? | 222
> > > > ++++++++++++++++++++++++
> > > > ? include/linux/mailbox/mtk-apu-mailbox.h |? 20 +++
> > > > ? 4 files changed, 253 insertions(+)
> > > > ? create mode 100644 drivers/mailbox/mtk-apu-mailbox.c
> > > > ? create mode 100644 include/linux/mailbox/mtk-apu-mailbox.h
> > > > 
> > > > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> > > > index 6fb995778636..2338e08a110a 100644
> > > > --- a/drivers/mailbox/Kconfig
> > > > +++ b/drivers/mailbox/Kconfig
> > > > @@ -240,6 +240,15 @@ config MTK_ADSP_MBOX
> > > > ??????????? between processors with ADSP. It will place the
> > > > message to share
> > > > ??????? buffer and will access the ipc control.
> > > > 
> > > > +config MTK_APU_MBOX
> > > > +???? tristate "MediaTek APU Mailbox Support"
> > > > +???? depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > +???? help
> > > > +?????? Say yes here to add support for the MediaTek APU
> > > > Mailbox
> > > > +?????? driver. The mailbox implementation provides access from
> > > > the
> > > > +?????? application processor to the MediaTek AI Processing
> > > > Unit.
> > > > +?????? If unsure say N.
> > > > +
> > > > ? config MTK_CMDQ_MBOX
> > > > ????? tristate "MediaTek CMDQ Mailbox Support"
> > > > ????? depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > diff --git a/drivers/mailbox/Makefile
> > > > b/drivers/mailbox/Makefile
> > > > index 3c3c27d54c13..6b6dcc78d644 100644
> > > > --- a/drivers/mailbox/Makefile
> > > > +++ b/drivers/mailbox/Makefile
> > > > @@ -53,6 +53,8 @@ obj-$(CONFIG_STM32_IPCC)??? += stm32-ipcc.o
> > > > 
> > > > ? obj-$(CONFIG_MTK_ADSP_MBOX) += mtk-adsp-mailbox.o
> > > > 
> > > > +obj-$(CONFIG_MTK_APU_MBOX)?? += mtk-apu-mailbox.o
> > > > +
> > > > ? obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o
> > > > 
> > > > ? obj-$(CONFIG_ZYNQMP_IPI_MBOX)?????? += zynqmp-ipi-mailbox.o
> > > > diff --git a/drivers/mailbox/mtk-apu-mailbox.c
> > > > b/drivers/mailbox/mtk-apu-mailbox.c
> > > > new file mode 100644
> > > > index 000000000000..b347ebd34ef7
> > > > --- /dev/null
> > > > +++ b/drivers/mailbox/mtk-apu-mailbox.c
> > > > @@ -0,0 +1,222 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +/*
> > > > + * Copyright (c) 2024 MediaTek Inc.
> > > > + */
> > > > +
> > > > +#include <asm/io.h>
> > > > +#include <linux/bits.h>
> > > > +#include <linux/interrupt.h>
> > > > +#include <linux/mailbox_controller.h>
> > > > +#include <linux/mailbox/mtk-apu-mailbox.h>
> > > > +#include <linux/platform_device.h>
> > > > +
> > > > +#define INBOX??????????????? (0x0)
> > > > +#define OUTBOX?????????????? (0x20)
> > > > +#define INBOX_IRQ??? (0xc0)
> > > > +#define OUTBOX_IRQ?? (0xc4)
> > > > +#define INBOX_IRQ_MASK?????? (0xd0)
> > > > +
> > > > +#define SPARE_OFF_START????? (0x40)
> > > > +#define SPARE_OFF_END??????? (0xB0)
> > > > +
> > > > +struct mtk_apu_mailbox {
> > > > +???? struct device *dev;
> > > > +???? void __iomem *regs;
> > > > +???? struct mbox_controller controller;
> > > 
> > > struct mbox_controller mbox;
> > > 
> > > ...it's shorter and consistent with at least other MTK mailbox
> > > drivers.
> > > 
> > > > +???? u32 msgs[MSG_MBOX_SLOTS];
> > > 
> > > Just reuse struct mtk_apu_mailbox_msg instead.....
> > > 
> > > > +};
> > > > +
> > > > +struct mtk_apu_mailbox *g_mbox;
> > > 
> > > That global struct must disappear - and if you use the mailbox
> > > API
> > > correctly
> > > it's even simple.
> > > 
> > > Also, you want something like....
> > > 
> > > static inline struct mtk_apu_mailbox *get_mtk_apu_mailbox(struct
> > > mbox_controller *mbox)
> > > {
> > > ??????? return container_of(mbox, struct mtk_apu_mailbox, mbox);
> > > }
> > > 
> > > > +
> > > > +static irqreturn_t mtk_apu_mailbox_irq_top_half(int irq, void
> > > > *dev_id)
> > > > +{
> > > static irqreturn_t mtk_apu_mailbox_irq(int irq, void *data)
> > > {
> > > ??????? struct mbox_chan *chan = data;
> > > ??????? struct mtk_apu_mailbox = get_mtk_apu_mailbox(chan->mbox);
> > > 
> > > > +???? struct mtk_apu_mailbox *mbox = dev_id;
> > > > +???? struct mbox_chan *link = &mbox->controller.chans[0];
> > > > +???? int i;
> > > > +
> > > > +???? for (i = 0; i < MSG_MBOX_SLOTS; i++)
> > > > +???????????? mbox->msgs[i] = readl(mbox->regs + OUTBOX + i *
> > > > sizeof(u32));
> > > > +
> > > > +???? mbox_chan_received_data(link, &mbox->msgs);
> > > > +
> > > > +???? return IRQ_WAKE_THREAD;
> > > > +}
> > > > +
> > > > +static irqreturn_t mtk_apu_mailbox_irq_btm_half(int irq, void
> > > > *dev_id)
> > > 
> > > ....mtk_apu_mailbox_irq_thread(...)
> > > 
> > > > +{
> > > > +???? struct mtk_apu_mailbox *mbox = dev_id;
> > > > +???? struct mbox_chan *link = &mbox->controller.chans[0];
> > > > +
> > > > +???? mbox_chan_received_data_bh(link, &mbox->msgs);
> > > 
> > > I don't think that you really need this _bh variant, looks more
> > > like you wanted
> > > to have two callbacks instead of one.
> > > 
> > > You can instead have one callback and vary functionality based
> > > based on reading
> > > a variable to decide what to actually do inside. Not a big deal.
> > 
> > The problem is that they need something with different semantics.
> > mbox_chan_received_data() is atomic only.
> 
> Yes, as Chen-Yu said, we want to have another callback which can run
> under non-atomic semantic.
> Even though we change the function based in the callback function of
> mbox_chan_received_data(), it is still non-atomic for the bottom-half
> handler.
> 
> > 
> > > > +???? writel(readl(mbox->regs + OUTBOX_IRQ), mbox->regs +
> > > > OUTBOX_IRQ);
> > > > +
> > > > +???? return IRQ_HANDLED;
> > > > +}
> > > > +
> > > > +static int mtk_apu_mailbox_send_data(struct mbox_chan *chan,
> > > > void *data)
> > > > +{
> > > > +???? struct mtk_apu_mailbox *mbox = container_of(chan->mbox,
> > > > +???????????????????????????????????????????????? struct
> > > > mtk_apu_mailbox,
> > > > +???????????????????????????????????????????????? controller);
> > > > +???? struct mtk_apu_mailbox_msg *msg = data;
> > > > +???? int i;
> > > > +
> > > > +???? if (msg->send_cnt <= 0 || msg->send_cnt > MSG_MBOX_SLOTS)
> > > > {
> > > > +???????????? dev_err(mbox->dev, "%s: invalid send_cnt %d\n",
> > > > __func__, msg->send_cnt);
> > > > +???????????? return -EINVAL;
> > > > +???? }
> > > > +
> > > > +???? /*
> > > > +????? *????? Mask lowest "send_cnt-1" interrupts bits, so the
> > > > interrupt on the other side
> > > > +????? *????? triggers only after the last data slot is written
> > > > (sent).
> > > > +????? */
> > > > +???? writel(GENMASK(msg->send_cnt - 2, 0), mbox->regs +
> > > > INBOX_IRQ_MASK);
> > > > +???? for (i = 0; i < msg->send_cnt; i++)
> > > > +???????????? writel(msg->data[i], mbox->regs + INBOX + i *
> > > > sizeof(u32));
> > > > +
> > > > +???? return 0;
> > > > +}
> > > > +
> > > > +static bool mtk_apu_mailbox_last_tx_done(struct mbox_chan
> > > > *chan)
> > > > +{
> > > > +???? struct mtk_apu_mailbox *mbox = container_of(chan->mbox,
> > > > +???????????????????????????????????????????????? struct
> > > > mtk_apu_mailbox,
> > > > +???????????????????????????????????????????????? controller);
> > > > +
> > > > +???? return readl(mbox->regs + INBOX_IRQ) == 0;
> > > > +}
> > > > +
> > > > +static const struct mbox_chan_ops mtk_apu_mailbox_ops = {
> > > > +???? .send_data = mtk_apu_mailbox_send_data,
> > > > +???? .last_tx_done = mtk_apu_mailbox_last_tx_done,
> > > > +};
> > > > +
> > > > +/**
> > > > + * mtk_apu_mbox_write - Write value to specifice mtk_apu_mbox
> > > > spare register.
> > > > + * @val: Value to be written.
> > > > + * @offset: Offset of the spare register.
> > > > + *
> > > > + * Return: 0 if successful
> > > > + *????? negative value if error happened
> > > > + */
> > > > +int mtk_apu_mbox_write(u32 val, u32 offset)
> > > > +{
> > > > +???? if (!g_mbox) {
> > > > +???????????? pr_err("mtk apu mbox was not initialized, stop
> > > > writing register\n");
> > > > +???????????? return -ENODEV;
> > > > +???? }
> > > > +
> > > > +???? if (offset < SPARE_OFF_START || offset >= SPARE_OFF_END)
> > > > {
> > > > +???????????? dev_err(g_mbox->dev, "Invalid offset %d for mtk
> > > > apu
> > > > mbox spare register\n", offset);
> > > > +???????????? return -EINVAL;
> > > > +???? }
> > > > +
> > > > +???? writel(val, g_mbox->regs + offset);
> > > 
> > > There's something odd in what you're doing here, why would you
> > > ever
> > > need
> > > a function that performs a writel just like that? What's the
> > > purpose?
> > > 
> > > What are you writing to the spare registers?
> > > For which reason?
> > 
> > I'll leave the explaining to Karl, but based on internal reviews
> > for
> > the
> > previous generation, it looked like passing values to/from the MCU.
> > 
> 
> The main reason we want to access the APU mailbox spare registers is
> to
> ensure that we can configure the necessary settings before the APU
> firmware becomes fully operational.
> 
> At the early stage, the communication pathways between the APU and
> the
> Linux Kernel aren't yet available, so these spare registers are
> needed
> for passing the initial configuration data.
> 
> > > I think you can avoid (read this as: you *have to* avoid) having
> > > such a
> > > function around.
> > 
> > Again, during the previous round of internal reviews, I had thought
> > about modeling these as extra mbox channels. I may have even asked
> > about this on IRC.
> > 
> > The problem is that it doesn't really have mbox semantics. They are
> > just shared registers with no send/receive notification. So at the
> > very least, there's nothing that will trigger a reception. I
> > suppose
> > we could make the .peek_data op trigger RX, but that's a really
> > convoluted way to read just a register.
> > 
> > The other option would be to have a syscon / custom exported
> > regmap?
> > 
> > > > +???? return 0;
> > > > +}
> > > > +EXPORT_SYMBOL_NS(mtk_apu_mbox_write, MTK_APU_MAILBOX);
> > > > +
> > > > +/**
> > > > + * mtk_apu_mbox_read - Read value to specifice mtk_apu_mbox
> > > > spare register.
> > > > + * @offset: Offset of the spare register.
> > > > + * @val: Pointer to store read value.
> > > > + *
> > > > + * Return: 0 if successful
> > > > + *????? negative value if error happened
> > > > + */
> > > > +int mtk_apu_mbox_read(u32 offset, u32 *val)
> > > > +{
> > > > +???? if (!g_mbox) {
> > > > +???????????? pr_err("mtk apu mbox was not initialized, stop
> > > > reading register\n");
> > > > +???????????? return -ENODEV;
> > > > +???? }
> > > > +
> > > > +???? if (offset < SPARE_OFF_START || offset >= SPARE_OFF_END)
> > > > {
> > > > +???????????? dev_err(g_mbox->dev, "Invalid offset %d for mtk
> > > > apu
> > > > mbox spare register\n", offset);
> > > > +???????????? return -EINVAL;
> > > > +???? }
> > > > +
> > > > +???? *val = readl(g_mbox->regs + offset);
> > > > +
> > > 
> > > Same goes for this one.
> > > 
> > > > +???? return 0;
> > > > +}
> > > > +EXPORT_SYMBOL_NS(mtk_apu_mbox_read, MTK_APU_MAILBOX);
> > > > +
> > > > +static int mtk_apu_mailbox_probe(struct platform_device *pdev)
> > > > +{
> > > > +???? struct device *dev = &pdev->dev;
> > > > +???? struct mtk_apu_mailbox *mbox;
> > > > +???? int irq = -1, ret = 0;
> > > > +
> > > > +???? mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
> > > > +???? if (!mbox)
> > > > +???????????? return -ENOMEM;
> > > > +
> > > > +???? mbox->dev = dev;
> > > > +???? platform_set_drvdata(pdev, mbox);
> > > > +
> > > 
> > > Please move the platform_get_irq call here or anyway before
> > > registering the
> > > mbox controller: in case anything goes wrong, devm won't have to
> > > unregister
> > > the mbox afterwards because it never got registered in the first
> > > place.
> > 
> > To clarify, you mean _just_ platform_get_irq() and not request_irq
> > as
> > well.
> > 
> > > > +???? mbox->regs = devm_platform_ioremap_resource(pdev, 0);
> > > > +???? if (IS_ERR(mbox->regs))
> > > > +???????????? return PTR_ERR(mbox->regs);
> > > > +
> > > > +???? mbox->controller.txdone_irq = false;
> > > > +???? mbox->controller.txdone_poll = true;
> > > > +???? mbox->controller.txpoll_period = 1;
> > > > +???? mbox->controller.ops = &mtk_apu_mailbox_ops;
> > > > +???? mbox->controller.dev = dev;
> > > > +???? /*
> > > > +????? * Here we only register 1 mbox channel.
> > > > +????? * The remaining channels are used by other modules.
> > > 
> > > What other modules? I don't really see any - so please at least
> > > explain that in the
> > > commit description.
> 
> Sorry for any confusion caused by the above comment. To clarify, the
> comment was specific to the MT8188 platform, which is the legacy
> platform compared to MT8196.
> In the context of MT8188, the APU mailbox has multiple in/out boxes,
> and Linux only utilizes in/out box 0, while the others are reserved
> for
> different VMs.
> 
> However, the APU mailbox hardware design in MT8196 differs from that
> of
> MT8188, and in MT8196, Linux has full access to the APU mailbox.
> 
> Given that this patch is primarily for the MT8196 platform, we will
> remove the above comment in the next version of the patch.
> 
> Thanks for your asking.
> 
> Karl
> 
> > > 
> > > > +????? */
> > > > +???? mbox->controller.num_chans = 1;
> > > > +???? mbox->controller.chans = devm_kcalloc(dev, mbox-
> > > > > controller.num_chans,
> > > > +?????????????????????????????????????????? sizeof(*mbox-
> > > > > controller.chans),
> > > > +?????????????????????????????????????????? GFP_KERNEL);
> > > > +???? if (!mbox->controller.chans)
> > > > +???????????? return -ENOMEM;
> > > > +
> > > > +???? ret = devm_mbox_controller_register(dev, &mbox-
> > > > > controller);
> > > > +???? if (ret)
> > > > +???????????? return ret;
> > > > +
> > > > +???? irq = platform_get_irq(pdev, 0);
> > > > +???? if (irq < 0)
> > > > +???????????? return irq;
> > > > +
> > > > +???? ret = devm_request_threaded_irq(dev, irq,
> > > > mtk_apu_mailbox_irq_top_half,
> > > > +????????????????????????????????????
> > > > mtk_apu_mailbox_irq_btm_half, IRQF_ONESHOT,
> > > > +???????????????????????????????????? dev_name(dev), mbox);
> > > 
> > > pass mbox->chans to the isr
> > > 
> > > > +???? if (ret)
> > > > +???????????? return dev_err_probe(dev, ret, "Failed to request
> > > > IRQ\n");
> > > > +
> > > > +???? g_mbox = mbox;
> > > > +
> > > > +???? dev_dbg(dev, "registered mtk apu mailbox\n");
> > > > +
> > > > +???? return 0;
> > > > +}
> > > > +
> > > > +static void mtk_apu_mailbox_remove(struct platform_device
> > > > *pdev)
> > > > +{
> > > > +???? g_mbox = NULL;
> > > > +}
> > > > +
> > > > +static const struct of_device_id mtk_apu_mailbox_of_match[] =
> > > > {
> > > > +???? { .compatible = "mediatek,mt8188-apu-mailbox" },
> > > > +???? { .compatible = "mediatek,mt8196-apu-mailbox" },
> > > 
> > > Just mediatek,mt8188-apu-mailbox is fine; you can allow
> > > mt8196==mt8188 in the
> > > binding instead.
> > > 
> > > > +???? {}
> > > > +};
> > > > +MODULE_DEVICE_TABLE(of, mtk_apu_mailbox_of_match);
> > > > +
> > > > +static struct platform_driver mtk_apu_mailbox_driver = {
> > > > +???? .probe = mtk_apu_mailbox_probe,
> > > > +???? .remove = mtk_apu_mailbox_remove,
> > > 
> > > You don't need this remove callback, since g_mbox has to
> > > disappear
> > > :-)
> > > 
> > > > +???? .driver = {
> > > > +???????????? .name = "mtk-apu-mailbox",
> > > > +???????????? .of_match_table = mtk_apu_mailbox_of_match,
> > > > +???? },
> > > > +};
> > > > +
> > > > +module_platform_driver(mtk_apu_mailbox_driver);
> > > > +MODULE_LICENSE("GPL");
> > > > +MODULE_DESCRIPTION("MediaTek APU Mailbox Driver");
> > > > diff --git a/include/linux/mailbox/mtk-apu-mailbox.h
> > > > b/include/linux/mailbox/mtk-apu-mailbox.h
> > > > new file mode 100644
> > > > index 000000000000..d1457d16ce9b
> > > > --- /dev/null
> > > > +++ b/include/linux/mailbox/mtk-apu-mailbox.h
> > > > @@ -0,0 +1,20 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > +/*
> > > > + * Copyright (c) 2024 MediaTek Inc.
> > > > + *
> > > > + */
> > > > +
> > > > +#ifndef __MTK_APU_MAILBOX_H__
> > > > +#define __MTK_APU_MAILBOX_H__
> > > > +
> > > > +#define MSG_MBOX_SLOTS?????? (8)
> > > > +
> > > > +struct mtk_apu_mailbox_msg {
> > > > +???? int send_cnt;
> > > 
> > > u8 data_cnt;
> > > 
> > > > +???? u32 data[MSG_MBOX_SLOTS];
> > > 
> > > With hardcoded slots, what happens when we get a new chip in the
> > > future that
> > > supports more slots?
> > 
> > Seems like we can make it a flexible array member? But the problem
> > then
> > becomes how does the client know what the maximum length is. Or
> > maybe
> > it should already know given it's tied to a particular platform.
> > 
> > In any case it becomes:
> > 
> > ??? struct mtk_apu_mailbox_msg {
> > ??????? u8 data_size;
> > ??????? u8 data[] __counted_by(data_size);
> > ??? };
> > 
> > This can't be allocated on the stack if `data_size` isn't a compile
> > time constant though; but again it shouldn't be a problem given the
> > message size is tied to the client & its platform and should be
> > constant anyway.
> > 
> > The controller should just error out if the message is larger than
> > what it can atomically send.
> > 
> > 
> > ChenYu
> > 
> > > Please think about this now and make the implementation flexible
> > > before that
> > > happens because, at a later time, it'll be harder.
> > > 
> > > Regards,
> > > Angelo
> > > 
> > > > +};
> > > > +
> > > > +int mtk_apu_mbox_write(u32 val, u32 offset);
> > > > +int mtk_apu_mbox_read(u32 offset, u32 *val);
> > > > +
> > > > +#endif /* __MTK_APU_MAILBOX_H__ */
> > > 
> > > 
> 


From krzk at kernel.org  Wed Dec  4 23:19:12 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 08:19:12 +0100
Subject: [PATCH v3 3/3] arm64: dts: exynosautov920: add watchdog DT node
In-Reply-To: <000201db46ac$8d7cfee0$a876fca0$@samsung.com>
References: <20241021063903.793166-1-trunixs.kim@samsung.com>
 <CGME20241021063938epcas2p1c01c89badb532f08a46087a4907df7dc@epcas2p1.samsung.com>
 <20241021063903.793166-4-trunixs.kim@samsung.com>
 <961e1aca-cd90-4db1-87d7-afd2e542421e@kernel.org>
 <20241107103331.GA4818@www.linux-watchdog.org>
 <589c40e1-6a1c-4ef7-b0d8-b761b132578a@kernel.org>
 <20241107113325.GA5284@www.linux-watchdog.org>
 <c487babb-84a5-4e47-a58f-75fec55cbabb@kernel.org>
 <000201db46ac$8d7cfee0$a876fca0$@samsung.com>
Message-ID: <88950a3a-c3de-4ff5-9ff8-9b85e1b0ad14@kernel.org>

On 05/12/2024 01:28, ??? wrote:
> Hi Krzysztof,
> 
>> On 07/11/2024 12:33, Wim Van Sebroeck wrote:
>>>>> Seems like you are having a hard day.
>>>>> The 3 patches are dropped. I presume that you will take them all
>> through your tree then?
>>>>
>>>> I meant only this one patch, not entire patchset. The bindings and
>>>> watchdog driver are for you. I commented only about this patch here -
>> DTS.
>>>>
>>>>
>>>> Best regards,
>>>> Krzysztof
>>>>
>>>
>>> I added the first two patches again. Even when it sounds more logical to
>> me to keep the 3 together.
>>
>> Thank you.
>>
>>> But that's a never ending discussion, so we won't go into that :-).
>>
>> DTS is hardware description independent from Linux, therefore always goes
>> separate way than Linux drivers.
>>
>> Best regards,
>> Krzysztof
> 
> I found that the first two patches have been added to the linux-next git, 
> but the last patch has not yet been reviewed.
> 
> I would appreciate it if you could take a look at this patch.

Since this patch was applied, I dropped from my queue. I don't have it
in my inbox anymore. Please rebase, resolve any comments and resend.
Best regards,
Krzysztof


From xueshuai at linux.alibaba.com  Wed Dec  4 23:24:04 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Thu, 5 Dec 2024 15:24:04 +0800
Subject: [PATCH 0/2] perf/dwc_pcie: Fix the swapped event numbers as well
 as the documentation
In-Reply-To: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
References: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
Message-ID: <412549fa-ca7a-42a1-9fad-85d3dcd14b79@linux.alibaba.com>



? 2024/12/5 14:19, Ilkka Koskinen ??:
> According to the versions of Designware Cores PCI Express Controller Databook
> I found, the eventid for "L1 aux" is 0x08 and "TX L0s and RX L0S" is 0x09.
> 
> Shuai and Jing, could you verify that your document matches ours and the events
> are indeed swapped in the driver at the moment?

Yep, it is a typo.

> 
> Cheers, Ilkka

Thanks for the fixes :)

Best Regards,
Shuai

> 
> 
> 
> Ilkka Koskinen (2):
>    perf/dwc_pcie: Fix the event numbers
>    Documentation: dwc_pcie_pmu: Fix the mnemonics and eventid
> 
>   Documentation/admin-guide/perf/dwc_pcie_pmu.rst | 6 +++---
>   drivers/perf/dwc_pcie_pmu.c                     | 4 ++--
>   2 files changed, 5 insertions(+), 5 deletions(-)
> 



From simons.philippe at gmail.com  Wed Dec  4 23:26:00 2024
From: simons.philippe at gmail.com (Philippe Simons)
Date: Thu, 5 Dec 2024 08:26:00 +0100
Subject: [PATCH] arm64: dts: allwinner: h616: rg35xx add missing regulator-ramp-delay
In-Reply-To: <CAGb2v67Uv3SVQSqox85qt_05aVvX0oCynNRoaN9BA1Nha3eo8w@mail.gmail.com>
References: <20241203203824.23306-1-simons.philippe@gmail.com> <CAGb2v67Uv3SVQSqox85qt_05aVvX0oCynNRoaN9BA1Nha3eo8w@mail.gmail.com>
Message-ID: <CADomA482XLFNySkjujoPmPCnCrKn+RcppW=SqRqcA2WLMe-mNw@mail.gmail.com>

Ok I can do that, but the driver (axp20x-regulator.c) is using macros
 to generate these regulator_desc structs.

So I have two options, create a new macro with the ramp_delay, or
modify the existing macro, using 0 for the regulators I don't know about.

Philippe

On Thu, Dec 5, 2024 at 5:16?AM Chen-Yu Tsai <wens at csie.org> wrote:
>
> On Wed, Dec 4, 2024 at 4:38?AM Philippe Simons
> <simons.philippe at gmail.com> wrote:
> >
> > AXP datasheet says that ramp delay is 15.625 us/step,
> > which is 10mV in our case.
>
> (CC-ing Mark for knowledge on regulators)
>
> If this is the property of the PMIC, it probably belongs in the driver,
> in "regulator_desc.ramp_delay".
>
> The "regulator-ramp-delay" in the DT can be used to override this
> if the board has excessive ramp delay due to other design reasons.
>
>
> ChenYu
>
> > add missing regulator-ramp-delay to dcdc regulators accordingly
> >
> > Signed-off-by: Philippe Simons <simons.philippe at gmail.com>
> > ---
> >  .../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts    | 3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
> > index 80ccab7b5..b6e76a804 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
> > @@ -238,6 +238,7 @@ reg_dcdc1: dcdc1 {
> >                                 regulator-always-on;
> >                                 regulator-min-microvolt = <900000>;
> >                                 regulator-max-microvolt = <1160000>;
> > +                               regulator-ramp-delay = <640>;
> >                                 regulator-name = "vdd-cpu";
> >                         };
> >
> > @@ -245,6 +246,7 @@ reg_dcdc2: dcdc2 {
> >                                 regulator-always-on;
> >                                 regulator-min-microvolt = <940000>;
> >                                 regulator-max-microvolt = <940000>;
> > +                               regulator-ramp-delay = <640>;
> >                                 regulator-name = "vdd-gpu-sys";
> >                         };
> >
> > @@ -252,6 +254,7 @@ reg_dcdc3: dcdc3 {
> >                                 regulator-always-on;
> >                                 regulator-min-microvolt = <1100000>;
> >                                 regulator-max-microvolt = <1100000>;
> > +                               regulator-ramp-delay = <640>;
> >                                 regulator-name = "vdd-dram";
> >                         };
> >
> > --
> > 2.47.1
> >


From xueshuai at linux.alibaba.com  Wed Dec  4 23:25:10 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Thu, 5 Dec 2024 15:25:10 +0800
Subject: [PATCH 1/2] perf/dwc_pcie: Fix the event numbers
In-Reply-To: <20241205061914.5568-2-ilkka@os.amperecomputing.com>
References: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
 <20241205061914.5568-2-ilkka@os.amperecomputing.com>
Message-ID: <9fa8c4b3-1585-4f2c-84df-d61d8c5c8329@linux.alibaba.com>



? 2024/12/5 14:19, Ilkka Koskinen ??:
> According to Databook, L1 aux is event number 0x08 and
> TX L0s and RX L0S is 0x09. Fix the event numbers for the
> two events.
> 
> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> ---
>   drivers/perf/dwc_pcie_pmu.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
> index 9cbea9675e21..890cf3bb43a2 100644
> --- a/drivers/perf/dwc_pcie_pmu.c
> +++ b/drivers/perf/dwc_pcie_pmu.c
> @@ -199,8 +199,8 @@ static struct attribute *dwc_pcie_pmu_time_event_attrs[] = {
>   	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(L1_1, 0x05),
>   	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(L1_2, 0x06),
>   	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(CFG_RCVRY, 0x07),
> -	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(TX_RX_L0S, 0x08),
> -	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(L1_AUX, 0x09),
> +	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(L1_AUX, 0x08),
> +	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(TX_RX_L0S, 0x09),
>   
>   	/* Group #1 */
>   	DWC_PCIE_PMU_TIME_BASE_EVENT_ATTR(tx_pcie_tlp_data_payload, 0x20),

LGTM.

Reviewed-by: Shuai Xue <xueshuai at linux.alibaba.com>

Thanks.

Best Regards,
Shuai


From xueshuai at linux.alibaba.com  Wed Dec  4 23:26:14 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Thu, 5 Dec 2024 15:26:14 +0800
Subject: [PATCH 2/2] Documentation: dwc_pcie_pmu: Fix the mnemonics and
 eventid
In-Reply-To: <20241205061914.5568-3-ilkka@os.amperecomputing.com>
References: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
 <20241205061914.5568-3-ilkka@os.amperecomputing.com>
Message-ID: <ac669a87-7517-4a37-8026-67b70e99884c@linux.alibaba.com>



? 2024/12/5 14:19, Ilkka Koskinen ??:
> Fix the event id and type in the example. In addition, the recent fix,
> which addressed the mnemonics with mixed case, didn't fix the document.
> Match the names with the driver.
> 
> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> ---
>   Documentation/admin-guide/perf/dwc_pcie_pmu.rst | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/admin-guide/perf/dwc_pcie_pmu.rst b/Documentation/admin-guide/perf/dwc_pcie_pmu.rst
> index 39b8e1fdd0cd..cb376f335f40 100644
> --- a/Documentation/admin-guide/perf/dwc_pcie_pmu.rst
> +++ b/Documentation/admin-guide/perf/dwc_pcie_pmu.rst
> @@ -60,7 +60,7 @@ description of available events and configuration options in sysfs, see
>   The "format" directory describes format of the config fields of the
>   perf_event_attr structure. The "events" directory provides configuration
>   templates for all documented events.  For example,
> -"Rx_PCIe_TLP_Data_Payload" is an equivalent of "eventid=0x22,type=0x1".
> +"rx_pcie_tlp_data_payload" is an equivalent of "eventid=0x21,type=0x0".
>   
>   The "perf list" command shall list the available events from sysfs, e.g.::
>   
> @@ -79,8 +79,8 @@ Example usage of counting PCIe RX TLP data payload (Units of bytes)::
>   
>   The average RX/TX bandwidth can be calculated using the following formula:
>   
> -    PCIe RX Bandwidth = Rx_PCIe_TLP_Data_Payload / Measure_Time_Window
> -    PCIe TX Bandwidth = Tx_PCIe_TLP_Data_Payload / Measure_Time_Window
> +    PCIe RX Bandwidth = rx_pcie_tlp_data_payload / Measure_Time_Window
> +    PCIe TX Bandwidth = tx_pcie_tlp_data_payload / Measure_Time_Window
>   
>   Lane Event Usage
>   -------------------------------


LGTM.

Reviewed-by: Shuai Xue <xueshuai at linux.alibaba.com>

Thanks.

Best Regards,
Shuai


From tzimmermann at suse.de  Wed Dec  4 23:29:16 2024
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Thu, 5 Dec 2024 08:29:16 +0100
Subject: [PATCH v2 3/3] drm: remove driver date from struct drm_driver and
 all drivers
In-Reply-To: <1f2bf2543aed270a06f6c707fd6ed1b78bf16712.1733322525.git.jani.nikula@intel.com>
References: <cover.1733322525.git.jani.nikula@intel.com>
 <1f2bf2543aed270a06f6c707fd6ed1b78bf16712.1733322525.git.jani.nikula@intel.com>
Message-ID: <340a179e-04fb-49cc-8ed9-227a34c32bc6@suse.de>




Am 04.12.24 um 15:31 schrieb Jani Nikula:
> We stopped using the driver initialized date in commit 7fb8af6798e8
> ("drm: deprecate driver date") and (eventually) started returning "0"
> for drm_version ioctl instead.
>
> Finish the job, and remove the unused date member from struct
> drm_driver, its initialization from drivers, along with the common
> DRIVER_DATE macros.
>
> v2: Also update drivers/accel (kernel test robot)
>
> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com>
> Acked-by: Alex Deucher <alexander.deucher at amd.com>
> Acked-by: Simon Ser <contact at emersion.fr>
> Acked-by: Jeffrey Hugo <quic_jhugo at quicinc.com>
> Signed-off-by: Jani Nikula <jani.nikula at intel.com>

Reviewed-by: Thomas Zimmermann <tzimmermann at suse.de>

>
> ---
>
> Cc: David Airlie <airlied at gmail.com>
> Cc: Hamza Mahfooz <hamza.mahfooz at amd.com>
> Cc: Javier Martinez Canillas <javierm at redhat.com>
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko at epam.com>
> Cc: Simon Ser <contact at emersion.fr>
> Cc: Simona Vetter <simona at ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann at suse.de>
> Cc: Ville Syrj?l? <ville.syrjala at linux.intel.com>
> Cc: amd-gfx at lists.freedesktop.org
> Cc: dri-devel at lists.freedesktop.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: nouveau at lists.freedesktop.org
> Cc: xen-devel at lists.xenproject.org
> ---
>   drivers/accel/habanalabs/common/habanalabs_drv.c | 1 -
>   drivers/accel/ivpu/ivpu_drv.c                    | 1 -
>   drivers/accel/qaic/qaic_drv.c                    | 1 -
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c          | 2 --
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h          | 1 -
>   drivers/gpu/drm/arm/display/komeda/komeda_kms.c  | 1 -
>   drivers/gpu/drm/arm/hdlcd_drv.c                  | 1 -
>   drivers/gpu/drm/arm/malidp_drv.c                 | 1 -
>   drivers/gpu/drm/armada/armada_drv.c              | 1 -
>   drivers/gpu/drm/aspeed/aspeed_gfx_drv.c          | 1 -
>   drivers/gpu/drm/ast/ast_drv.c                    | 1 -
>   drivers/gpu/drm/ast/ast_drv.h                    | 1 -
>   drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c     | 1 -
>   drivers/gpu/drm/etnaviv/etnaviv_drv.c            | 1 -
>   drivers/gpu/drm/exynos/exynos_drm_drv.c          | 2 --
>   drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c        | 1 -
>   drivers/gpu/drm/gma500/psb_drv.c                 | 1 -
>   drivers/gpu/drm/gma500/psb_drv.h                 | 1 -
>   drivers/gpu/drm/gud/gud_drv.c                    | 1 -
>   drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c  | 1 -
>   drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c  | 1 -
>   drivers/gpu/drm/hyperv/hyperv_drm_drv.c          | 2 --
>   drivers/gpu/drm/i915/i915_driver.c               | 1 -
>   drivers/gpu/drm/i915/i915_driver.h               | 1 -
>   drivers/gpu/drm/i915/i915_gpu_error.c            | 1 -
>   drivers/gpu/drm/imagination/pvr_drv.c            | 1 -
>   drivers/gpu/drm/imagination/pvr_drv.h            | 1 -
>   drivers/gpu/drm/imx/dcss/dcss-kms.c              | 1 -
>   drivers/gpu/drm/imx/ipuv3/imx-drm-core.c         | 1 -
>   drivers/gpu/drm/imx/lcdc/imx-lcdc.c              | 1 -
>   drivers/gpu/drm/ingenic/ingenic-drm-drv.c        | 1 -
>   drivers/gpu/drm/kmb/kmb_drv.c                    | 1 -
>   drivers/gpu/drm/kmb/kmb_drv.h                    | 1 -
>   drivers/gpu/drm/lima/lima_drv.c                  | 1 -
>   drivers/gpu/drm/logicvc/logicvc_drm.c            | 1 -
>   drivers/gpu/drm/loongson/lsdc_drv.c              | 2 --
>   drivers/gpu/drm/mcde/mcde_drv.c                  | 1 -
>   drivers/gpu/drm/mediatek/mtk_drm_drv.c           | 2 --
>   drivers/gpu/drm/meson/meson_drv.c                | 1 -
>   drivers/gpu/drm/mgag200/mgag200_drv.c            | 1 -
>   drivers/gpu/drm/mgag200/mgag200_drv.h            | 1 -
>   drivers/gpu/drm/msm/msm_drv.c                    | 1 -
>   drivers/gpu/drm/mxsfb/lcdif_drv.c                | 1 -
>   drivers/gpu/drm/mxsfb/mxsfb_drv.c                | 1 -
>   drivers/gpu/drm/nouveau/nouveau_drm.c            | 5 -----
>   drivers/gpu/drm/nouveau/nouveau_drv.h            | 1 -
>   drivers/gpu/drm/omapdrm/omap_drv.c               | 2 --
>   drivers/gpu/drm/panfrost/panfrost_drv.c          | 1 -
>   drivers/gpu/drm/panthor/panthor_drv.c            | 1 -
>   drivers/gpu/drm/pl111/pl111_drv.c                | 1 -
>   drivers/gpu/drm/qxl/qxl_drv.c                    | 1 -
>   drivers/gpu/drm/qxl/qxl_drv.h                    | 1 -
>   drivers/gpu/drm/radeon/radeon_drv.c              | 1 -
>   drivers/gpu/drm/radeon/radeon_drv.h              | 1 -
>   drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c    | 1 -
>   drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c     | 1 -
>   drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 1 -
>   drivers/gpu/drm/rockchip/rockchip_drm_drv.c      | 2 --
>   drivers/gpu/drm/solomon/ssd130x.c                | 2 --
>   drivers/gpu/drm/sprd/sprd_drm.c                  | 2 --
>   drivers/gpu/drm/sti/sti_drv.c                    | 2 --
>   drivers/gpu/drm/stm/drv.c                        | 1 -
>   drivers/gpu/drm/sun4i/sun4i_drv.c                | 1 -
>   drivers/gpu/drm/tegra/drm.c                      | 2 --
>   drivers/gpu/drm/tidss/tidss_drv.c                | 1 -
>   drivers/gpu/drm/tilcdc/tilcdc_drv.c              | 1 -
>   drivers/gpu/drm/tiny/arcpgu.c                    | 1 -
>   drivers/gpu/drm/tiny/bochs.c                     | 1 -
>   drivers/gpu/drm/tiny/cirrus-qemu.c               | 2 --
>   drivers/gpu/drm/tiny/gm12u320.c                  | 2 --
>   drivers/gpu/drm/tiny/hx8357d.c                   | 1 -
>   drivers/gpu/drm/tiny/ili9163.c                   | 1 -
>   drivers/gpu/drm/tiny/ili9225.c                   | 1 -
>   drivers/gpu/drm/tiny/ili9341.c                   | 1 -
>   drivers/gpu/drm/tiny/ili9486.c                   | 1 -
>   drivers/gpu/drm/tiny/mi0283qt.c                  | 1 -
>   drivers/gpu/drm/tiny/ofdrm.c                     | 2 --
>   drivers/gpu/drm/tiny/panel-mipi-dbi.c            | 1 -
>   drivers/gpu/drm/tiny/repaper.c                   | 1 -
>   drivers/gpu/drm/tiny/sharp-memory.c              | 1 -
>   drivers/gpu/drm/tiny/simpledrm.c                 | 2 --
>   drivers/gpu/drm/tiny/st7586.c                    | 1 -
>   drivers/gpu/drm/tiny/st7735r.c                   | 1 -
>   drivers/gpu/drm/tve200/tve200_drv.c              | 1 -
>   drivers/gpu/drm/udl/udl_drv.c                    | 1 -
>   drivers/gpu/drm/udl/udl_drv.h                    | 1 -
>   drivers/gpu/drm/v3d/v3d_drv.c                    | 2 --
>   drivers/gpu/drm/vboxvideo/vbox_drv.c             | 1 -
>   drivers/gpu/drm/vboxvideo/vbox_drv.h             | 1 -
>   drivers/gpu/drm/vc4/vc4_drv.c                    | 3 ---
>   drivers/gpu/drm/vgem/vgem_drv.c                  | 2 --
>   drivers/gpu/drm/virtio/virtgpu_drv.c             | 1 -
>   drivers/gpu/drm/virtio/virtgpu_drv.h             | 1 -
>   drivers/gpu/drm/vkms/vkms_drv.c                  | 2 --
>   drivers/gpu/drm/vmwgfx/vmwgfx_drv.c              | 1 -
>   drivers/gpu/drm/vmwgfx/vmwgfx_drv.h              | 1 -
>   drivers/gpu/drm/xe/xe_device.c                   | 1 -
>   drivers/gpu/drm/xe/xe_drv.h                      | 1 -
>   drivers/gpu/drm/xen/xen_drm_front.c              | 1 -
>   drivers/gpu/drm/xlnx/zynqmp_kms.c                | 1 -
>   include/drm/drm_drv.h                            | 2 --
>   101 files changed, 126 deletions(-)
>
> diff --git a/drivers/accel/habanalabs/common/habanalabs_drv.c b/drivers/accel/habanalabs/common/habanalabs_drv.c
> index 708dfd10f39c..5409b2c656c8 100644
> --- a/drivers/accel/habanalabs/common/habanalabs_drv.c
> +++ b/drivers/accel/habanalabs/common/habanalabs_drv.c
> @@ -101,7 +101,6 @@ static const struct drm_driver hl_driver = {
>   	.major = LINUX_VERSION_MAJOR,
>   	.minor = LINUX_VERSION_PATCHLEVEL,
>   	.patchlevel = LINUX_VERSION_SUBLEVEL,
> -	.date = "20190505",
>   
>   	.fops = &hl_fops,
>   	.open = hl_device_open,
> diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
> index 1f359dbe5150..1e8ffbe25eee 100644
> --- a/drivers/accel/ivpu/ivpu_drv.c
> +++ b/drivers/accel/ivpu/ivpu_drv.c
> @@ -458,7 +458,6 @@ static const struct drm_driver driver = {
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
>   
> -	.date = UTS_RELEASE,
>   	.major = 1,
>   };
>   
> diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c
> index 3575e0c984d6..542c5d24e499 100644
> --- a/drivers/accel/qaic/qaic_drv.c
> +++ b/drivers/accel/qaic/qaic_drv.c
> @@ -208,7 +208,6 @@ static const struct drm_driver qaic_accel_driver = {
>   
>   	.name			= QAIC_NAME,
>   	.desc			= QAIC_DESC,
> -	.date			= "20190618",
>   
>   	.fops			= &qaic_accel_fops,
>   	.open			= qaic_open,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 346746d6c233..eaeaaddb32cd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -2916,7 +2916,6 @@ static const struct drm_driver amdgpu_kms_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = KMS_DRIVER_MAJOR,
>   	.minor = KMS_DRIVER_MINOR,
>   	.patchlevel = KMS_DRIVER_PATCHLEVEL,
> @@ -2940,7 +2939,6 @@ const struct drm_driver amdgpu_partition_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = KMS_DRIVER_MAJOR,
>   	.minor = KMS_DRIVER_MINOR,
>   	.patchlevel = KMS_DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h
> index 5bc2cb661af7..2d86cc6f7f4d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h
> @@ -40,7 +40,6 @@
>   
>   #define DRIVER_NAME		"amdgpu"
>   #define DRIVER_DESC		"AMD GPU"
> -#define DRIVER_DATE		"20150101"
>   
>   extern const struct drm_driver amdgpu_partition_driver;
>   
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> index 1e7b1fcb2848..6ed504099188 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> @@ -63,7 +63,6 @@ static const struct drm_driver komeda_kms_driver = {
>   	.fops = &komeda_cma_fops,
>   	.name = "komeda",
>   	.desc = "Arm Komeda Display Processor driver",
> -	.date = "20181101",
>   	.major = 0,
>   	.minor = 1,
>   };
> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> index 4af8fce7dab7..8617d10940d8 100644
> --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> @@ -233,7 +233,6 @@ static const struct drm_driver hdlcd_driver = {
>   	.fops = &fops,
>   	.name = "hdlcd",
>   	.desc = "ARM HDLCD Controller DRM",
> -	.date = "20151021",
>   	.major = 1,
>   	.minor = 0,
>   };
> diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
> index 38b1b5b6bf69..3abc9339464b 100644
> --- a/drivers/gpu/drm/arm/malidp_drv.c
> +++ b/drivers/gpu/drm/arm/malidp_drv.c
> @@ -570,7 +570,6 @@ static const struct drm_driver malidp_driver = {
>   	.fops = &fops,
>   	.name = "mali-dp",
>   	.desc = "ARM Mali Display Processor driver",
> -	.date = "20160106",
>   	.major = 1,
>   	.minor = 0,
>   };
> diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
> index ddf0eaf546a6..5d5b7435970a 100644
> --- a/drivers/gpu/drm/armada/armada_drv.c
> +++ b/drivers/gpu/drm/armada/armada_drv.c
> @@ -45,7 +45,6 @@ static const struct drm_driver armada_drm_driver = {
>   	.minor			= 0,
>   	.name			= "armada-drm",
>   	.desc			= "Armada SoC DRM",
> -	.date			= "20120730",
>   	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
>   	.ioctls			= armada_ioctls,
>   	.num_ioctls = ARRAY_SIZE(armada_ioctls),
> diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
> index 55e90ab9b231..90189a3cf886 100644
> --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
> +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
> @@ -252,7 +252,6 @@ static const struct drm_driver aspeed_gfx_driver = {
>   	.fops = &fops,
>   	.name = "aspeed-gfx-drm",
>   	.desc = "ASPEED GFX DRM",
> -	.date = "20180319",
>   	.major = 1,
>   	.minor = 0,
>   };
> diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
> index 8e9c9cb89a50..ff3bcdd1cff2 100644
> --- a/drivers/gpu/drm/ast/ast_drv.c
> +++ b/drivers/gpu/drm/ast/ast_drv.c
> @@ -60,7 +60,6 @@ static const struct drm_driver ast_driver = {
>   	.fops = &ast_fops,
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
> index 21ce3769bf0d..6b4305ac07d4 100644
> --- a/drivers/gpu/drm/ast/ast_drv.h
> +++ b/drivers/gpu/drm/ast/ast_drv.h
> @@ -43,7 +43,6 @@
>   
>   #define DRIVER_NAME		"ast"
>   #define DRIVER_DESC		"AST"
> -#define DRIVER_DATE		"20120228"
>   
>   #define DRIVER_MAJOR		0
>   #define DRIVER_MINOR		1
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index 506289a937e2..b51528b2166c 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -846,7 +846,6 @@ static const struct drm_driver atmel_hlcdc_dc_driver = {
>   	.fops = &fops,
>   	.name = "atmel-hlcdc",
>   	.desc = "Atmel HLCD Controller DRM",
> -	.date = "20141504",
>   	.major = 1,
>   	.minor = 0,
>   };
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> index 9b4e2f4b1bc7..c4ddabe3cabd 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> @@ -503,7 +503,6 @@ static const struct drm_driver etnaviv_drm_driver = {
>   	.fops               = &fops,
>   	.name               = "etnaviv",
>   	.desc               = "etnaviv DRM",
> -	.date               = "20151214",
>   	.major              = 1,
>   	.minor              = 4,
>   };
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 7e517a2ec681..91ab42b56716 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -35,7 +35,6 @@
>   
>   #define DRIVER_NAME	"exynos"
>   #define DRIVER_DESC	"Samsung SoC DRM"
> -#define DRIVER_DATE	"20180330"
>   
>   /*
>    * Interface history:
> @@ -118,7 +117,6 @@ static const struct drm_driver exynos_drm_driver = {
>   	.fops			= &exynos_drm_driver_fops,
>   	.name	= DRIVER_NAME,
>   	.desc	= DRIVER_DESC,
> -	.date	= DRIVER_DATE,
>   	.major	= DRIVER_MAJOR,
>   	.minor	= DRIVER_MINOR,
>   };
> diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
> index 12b2096b6c9d..e1183644ec39 100644
> --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
> +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
> @@ -174,7 +174,6 @@ static const struct drm_driver fsl_dcu_drm_driver = {
>   	.fops			= &fsl_dcu_drm_fops,
>   	.name			= "fsl-dcu-drm",
>   	.desc			= "Freescale DCU DRM",
> -	.date			= "20160425",
>   	.major			= 1,
>   	.minor			= 1,
>   };
> diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
> index 2c56ece17d71..85d3557c2eb9 100644
> --- a/drivers/gpu/drm/gma500/psb_drv.c
> +++ b/drivers/gpu/drm/gma500/psb_drv.c
> @@ -513,7 +513,6 @@ static const struct drm_driver driver = {
>   	.fops = &psb_gem_fops,
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL
> diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
> index de62cbfcdc72..7f77cb2b2751 100644
> --- a/drivers/gpu/drm/gma500/psb_drv.h
> +++ b/drivers/gpu/drm/gma500/psb_drv.h
> @@ -26,7 +26,6 @@
>   
>   #define DRIVER_NAME "gma500"
>   #define DRIVER_DESC "DRM driver for the Intel GMA500, GMA600, GMA3600, GMA3650"
> -#define DRIVER_DATE "20140314"
>   
>   #define DRIVER_MAJOR 1
>   #define DRIVER_MINOR 0
> diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
> index 65a16f009ea6..cb405771d6e2 100644
> --- a/drivers/gpu/drm/gud/gud_drv.c
> +++ b/drivers/gpu/drm/gud/gud_drv.c
> @@ -381,7 +381,6 @@ static const struct drm_driver gud_drm_driver = {
>   
>   	.name			= "gud",
>   	.desc			= "Generic USB Display",
> -	.date			= "20200422",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> index 69bdae604982..7f814c32ed34 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> @@ -57,7 +57,6 @@ static const struct drm_driver hibmc_driver = {
>   	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
>   	.fops			= &hibmc_fops,
>   	.name			= "hibmc",
> -	.date			= "20160828",
>   	.desc			= "hibmc drm driver",
>   	.major			= 1,
>   	.minor			= 0,
> diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> index 5616c3917c03..2eb49177ac42 100644
> --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> @@ -929,7 +929,6 @@ static const struct drm_driver ade_driver = {
>   	DRM_FBDEV_DMA_DRIVER_OPS,
>   	.name = "kirin",
>   	.desc = "Hisilicon Kirin620 SoC DRM Driver",
> -	.date = "20150718",
>   	.major = 1,
>   	.minor = 0,
>   };
> diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> index c5ac240f7a7a..f59abfa7622a 100644
> --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> @@ -20,7 +20,6 @@
>   
>   #define DRIVER_NAME "hyperv_drm"
>   #define DRIVER_DESC "DRM driver for Hyper-V synthetic video device"
> -#define DRIVER_DATE "2020"
>   #define DRIVER_MAJOR 1
>   #define DRIVER_MINOR 0
>   
> @@ -31,7 +30,6 @@ static struct drm_driver hyperv_driver = {
>   
>   	.name		 = DRIVER_NAME,
>   	.desc		 = DRIVER_DESC,
> -	.date		 = DRIVER_DATE,
>   	.major		 = DRIVER_MAJOR,
>   	.minor		 = DRIVER_MINOR,
>   
> diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
> index c1edf5e1f61e..e35aa0274d76 100644
> --- a/drivers/gpu/drm/i915/i915_driver.c
> +++ b/drivers/gpu/drm/i915/i915_driver.c
> @@ -1797,7 +1797,6 @@ static const struct drm_driver i915_drm_driver = {
>   	.fops = &i915_driver_fops,
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/i915/i915_driver.h b/drivers/gpu/drm/i915/i915_driver.h
> index 94a70d8ec5d5..4b67ad9a61cd 100644
> --- a/drivers/gpu/drm/i915/i915_driver.h
> +++ b/drivers/gpu/drm/i915/i915_driver.h
> @@ -15,7 +15,6 @@ struct drm_printer;
>   
>   #define DRIVER_NAME		"i915"
>   #define DRIVER_DESC		"Intel Graphics"
> -#define DRIVER_DATE		"20230929"
>   #define DRIVER_TIMESTAMP	1695980603
>   
>   extern const struct dev_pm_ops i915_pm_ops;
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 4eb58887819a..eb975b3815df 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -841,7 +841,6 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
>   	err_printf(m, "Kernel: %s %s\n",
>   		   init_utsname()->release,
>   		   init_utsname()->machine);
> -	err_printf(m, "Driver: %s\n", DRIVER_DATE);
>   	ts = ktime_to_timespec64(error->time);
>   	err_printf(m, "Time: %lld s %ld us\n",
>   		   (s64)ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC);
> diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c
> index 36c0e768698e..6ab023593476 100644
> --- a/drivers/gpu/drm/imagination/pvr_drv.c
> +++ b/drivers/gpu/drm/imagination/pvr_drv.c
> @@ -1387,7 +1387,6 @@ static struct drm_driver pvr_drm_driver = {
>   
>   	.name = PVR_DRIVER_NAME,
>   	.desc = PVR_DRIVER_DESC,
> -	.date = PVR_DRIVER_DATE,
>   	.major = PVR_DRIVER_MAJOR,
>   	.minor = PVR_DRIVER_MINOR,
>   	.patchlevel = PVR_DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/imagination/pvr_drv.h b/drivers/gpu/drm/imagination/pvr_drv.h
> index 378fe477b759..7fa147312dd1 100644
> --- a/drivers/gpu/drm/imagination/pvr_drv.h
> +++ b/drivers/gpu/drm/imagination/pvr_drv.h
> @@ -9,7 +9,6 @@
>   
>   #define PVR_DRIVER_NAME "powervr"
>   #define PVR_DRIVER_DESC "Imagination PowerVR (Series 6 and later) & IMG Graphics"
> -#define PVR_DRIVER_DATE "20230904"
>   
>   /*
>    * Driver interface version:
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c
> index 490b5c269f39..3633e8f3aff6 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-kms.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c
> @@ -34,7 +34,6 @@ static const struct drm_driver dcss_kms_driver = {
>   	.fops			= &dcss_cma_fops,
>   	.name			= "imx-dcss",
>   	.desc			= "i.MX8MQ Display Subsystem",
> -	.date			= "20190917",
>   	.major			= 1,
>   	.minor			= 0,
>   	.patchlevel		= 0,
> diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> index 6b84429735d6..bcb35ba670fc 100644
> --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> @@ -163,7 +163,6 @@ static const struct drm_driver imx_drm_driver = {
>   	.fops			= &imx_drm_driver_fops,
>   	.name			= "imx-drm",
>   	.desc			= "i.MX DRM graphics",
> -	.date			= "20120507",
>   	.major			= 1,
>   	.minor			= 0,
>   	.patchlevel		= 0,
> diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
> index c5121fed80fd..d70981295f88 100644
> --- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
> +++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
> @@ -352,7 +352,6 @@ static struct drm_driver imx_lcdc_drm_driver = {
>   	DRM_FBDEV_DMA_DRIVER_OPS,
>   	.name = "imx-lcdc",
>   	.desc = "i.MX LCDC driver",
> -	.date = "20200716",
>   };
>   
>   static const struct of_device_id imx_lcdc_of_dev_id[] = {
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> index 0a4eb3994cd6..6546d9ec410a 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> @@ -953,7 +953,6 @@ static const struct drm_driver ingenic_drm_driver_data = {
>   	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
>   	.name			= "ingenic-drm",
>   	.desc			= "DRM module for Ingenic SoCs",
> -	.date			= "20200716",
>   	.major			= 1,
>   	.minor			= 1,
>   	.patchlevel		= 0,
> diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c
> index 4173344ba32c..c340b4c6a74b 100644
> --- a/drivers/gpu/drm/kmb/kmb_drv.c
> +++ b/drivers/gpu/drm/kmb/kmb_drv.c
> @@ -445,7 +445,6 @@ static const struct drm_driver kmb_driver = {
>   	DRM_FBDEV_DMA_DRIVER_OPS,
>   	.name = "kmb-drm",
>   	.desc = "KEEMBAY DISPLAY DRIVER",
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   };
> diff --git a/drivers/gpu/drm/kmb/kmb_drv.h b/drivers/gpu/drm/kmb/kmb_drv.h
> index bf085e95b28f..1f0c10d317fe 100644
> --- a/drivers/gpu/drm/kmb/kmb_drv.h
> +++ b/drivers/gpu/drm/kmb/kmb_drv.h
> @@ -16,7 +16,6 @@
>   #define KMB_MIN_WIDTH                   1920 /*Max width in pixels */
>   #define KMB_MIN_HEIGHT                  1080 /*Max height in pixels */
>   
> -#define DRIVER_DATE			"20210223"
>   #define DRIVER_MAJOR			1
>   #define DRIVER_MINOR			1
>   
> diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
> index 10bce18b7c31..4b70c5189f7c 100644
> --- a/drivers/gpu/drm/lima/lima_drv.c
> +++ b/drivers/gpu/drm/lima/lima_drv.c
> @@ -271,7 +271,6 @@ static const struct drm_driver lima_drm_driver = {
>   	.fops               = &lima_drm_driver_fops,
>   	.name               = "lima",
>   	.desc               = "lima DRM",
> -	.date               = "20191231",
>   	.major              = 1,
>   	.minor              = 1,
>   	.patchlevel         = 0,
> diff --git a/drivers/gpu/drm/logicvc/logicvc_drm.c b/drivers/gpu/drm/logicvc/logicvc_drm.c
> index 9152034e54a3..bda2a689d928 100644
> --- a/drivers/gpu/drm/logicvc/logicvc_drm.c
> +++ b/drivers/gpu/drm/logicvc/logicvc_drm.c
> @@ -52,7 +52,6 @@ static struct drm_driver logicvc_drm_driver = {
>   	.fops				= &logicvc_drm_fops,
>   	.name				= "logicvc-drm",
>   	.desc				= "Xylon LogiCVC DRM driver",
> -	.date				= "20200403",
>   	.major				= 1,
>   	.minor				= 0,
>   
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
> index a55aa1fe2c21..12193d2a301a 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.c
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.c
> @@ -26,7 +26,6 @@
>   #define DRIVER_AUTHOR               "Sui Jingfeng <suijingfeng at loongson.cn>"
>   #define DRIVER_NAME                 "loongson"
>   #define DRIVER_DESC                 "drm driver for loongson graphics"
> -#define DRIVER_DATE                 "20220701"
>   #define DRIVER_MAJOR                1
>   #define DRIVER_MINOR                0
>   #define DRIVER_PATCHLEVEL           0
> @@ -39,7 +38,6 @@ static const struct drm_driver lsdc_drm_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
> index f8c7aa9d7f33..324a95d7f15b 100644
> --- a/drivers/gpu/drm/mcde/mcde_drv.c
> +++ b/drivers/gpu/drm/mcde/mcde_drv.c
> @@ -208,7 +208,6 @@ static const struct drm_driver mcde_drm_driver = {
>   	.fops = &drm_fops,
>   	.name = "mcde",
>   	.desc = DRIVER_DESC,
> -	.date = "20180529",
>   	.major = 1,
>   	.minor = 0,
>   	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 38297d705df6..723782e75c55 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -33,7 +33,6 @@
>   
>   #define DRIVER_NAME "mediatek"
>   #define DRIVER_DESC "Mediatek SoC DRM"
> -#define DRIVER_DATE "20150513"
>   #define DRIVER_MAJOR 1
>   #define DRIVER_MINOR 0
>   
> @@ -615,7 +614,6 @@ static const struct drm_driver mtk_drm_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   };
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index 83ee18024682..64c8c4bb60f1 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -105,7 +105,6 @@ static const struct drm_driver meson_driver = {
>   	.fops			= &fops,
>   	.name			= DRIVER_NAME,
>   	.desc			= DRIVER_DESC,
> -	.date			= "20161109",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
> index b7ed763addfa..069fdd2dc8f6 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_drv.c
> +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
> @@ -97,7 +97,6 @@ static const struct drm_driver mgag200_driver = {
>   	.fops = &mgag200_driver_fops,
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
> index 988967eafbf2..0608fc63e588 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_drv.h
> +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
> @@ -25,7 +25,6 @@
>   
>   #define DRIVER_NAME		"mgag200"
>   #define DRIVER_DESC		"MGA G200 SE"
> -#define DRIVER_DATE		"20110418"
>   
>   #define DRIVER_MAJOR		1
>   #define DRIVER_MINOR		0
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index b5fa715cbfb0..73e72aee6ec5 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -910,7 +910,6 @@ static const struct drm_driver msm_driver = {
>   	.fops               = &fops,
>   	.name               = "msm",
>   	.desc               = "MSM Snapdragon DRM",
> -	.date               = "20130625",
>   	.major              = MSM_VERSION_MAJOR,
>   	.minor              = MSM_VERSION_MINOR,
>   	.patchlevel         = MSM_VERSION_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> index 81ec91cef66c..02fe6b89f3aa 100644
> --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> @@ -248,7 +248,6 @@ static const struct drm_driver lcdif_driver = {
>   	.fops	= &fops,
>   	.name	= "imx-lcdif",
>   	.desc	= "i.MX LCDIF Controller DRM",
> -	.date	= "20220417",
>   	.major	= 1,
>   	.minor	= 0,
>   };
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> index 1c27a97dce03..129cc3fb4448 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> @@ -336,7 +336,6 @@ static const struct drm_driver mxsfb_driver = {
>   	.fops	= &fops,
>   	.name	= "mxsfb-drm",
>   	.desc	= "MXSFB Controller DRM",
> -	.date	= "20160824",
>   	.major	= 1,
>   	.minor	= 0,
>   };
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
> index a99c1d9855c9..744ae9d3305d 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> @@ -1326,11 +1326,6 @@ driver_stub = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -#ifdef GIT_REVISION
> -	.date = GIT_REVISION,
> -#else
> -	.date = DRIVER_DATE,
> -#endif
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
> index 685d6ca3d8aa..55abc510067b 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drv.h
> +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
> @@ -7,7 +7,6 @@
>   
>   #define DRIVER_NAME		"nouveau"
>   #define DRIVER_DESC		"nVidia Riva/TNT/GeForce/Quadro/Tesla/Tegra K1+"
> -#define DRIVER_DATE		"20120801"
>   
>   #define DRIVER_MAJOR		1
>   #define DRIVER_MINOR		4
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> index 1796cd20a877..a80e0f375a0e 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -28,7 +28,6 @@
>   
>   #define DRIVER_NAME		MODULE_NAME
>   #define DRIVER_DESC		"OMAP DRM"
> -#define DRIVER_DATE		"20110917"
>   #define DRIVER_MAJOR		1
>   #define DRIVER_MINOR		0
>   #define DRIVER_PATCHLEVEL	0
> @@ -653,7 +652,6 @@ static const struct drm_driver omap_drm_driver = {
>   	.fops = &omapdriver_fops,
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
> index 04d615df5259..fbaef3afcd66 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> @@ -636,7 +636,6 @@ static const struct drm_driver panfrost_drm_driver = {
>   	.fops			= &panfrost_drm_driver_fops,
>   	.name			= "panfrost",
>   	.desc			= "panfrost DRM",
> -	.date			= "20180908",
>   	.major			= 1,
>   	.minor			= 3,
>   
> diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
> index ac7e53f6e3f0..ad46a40ed9e1 100644
> --- a/drivers/gpu/drm/panthor/panthor_drv.c
> +++ b/drivers/gpu/drm/panthor/panthor_drv.c
> @@ -1505,7 +1505,6 @@ static const struct drm_driver panthor_drm_driver = {
>   	.fops = &panthor_drm_driver_fops,
>   	.name = "panthor",
>   	.desc = "Panthor DRM driver",
> -	.date = "20230801",
>   	.major = 1,
>   	.minor = 2,
>   
> diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
> index 4b96f48cf630..56ff6a3fb483 100644
> --- a/drivers/gpu/drm/pl111/pl111_drv.c
> +++ b/drivers/gpu/drm/pl111/pl111_drv.c
> @@ -220,7 +220,6 @@ static const struct drm_driver pl111_drm_driver = {
>   	.fops = &drm_fops,
>   	.name = "pl111",
>   	.desc = DRIVER_DESC,
> -	.date = "20170317",
>   	.major = 1,
>   	.minor = 0,
>   	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
> index f15e9583b098..417061ae59eb 100644
> --- a/drivers/gpu/drm/qxl/qxl_drv.c
> +++ b/drivers/gpu/drm/qxl/qxl_drv.c
> @@ -300,7 +300,6 @@ static struct drm_driver qxl_driver = {
>   	.num_ioctls = ARRAY_SIZE(qxl_ioctls),
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = 0,
>   	.minor = 1,
>   	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
> index b5fc14c9525d..cc02b5f10ad9 100644
> --- a/drivers/gpu/drm/qxl/qxl_drv.h
> +++ b/drivers/gpu/drm/qxl/qxl_drv.h
> @@ -54,7 +54,6 @@ struct iosys_map;
>   
>   #define DRIVER_NAME		"qxl"
>   #define DRIVER_DESC		"RH QXL"
> -#define DRIVER_DATE		"20120117"
>   
>   #define DRIVER_MAJOR 0
>   #define DRIVER_MINOR 1
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
> index 5ce7e91bedad..267f082bc430 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -603,7 +603,6 @@ static const struct drm_driver kms_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = KMS_DRIVER_MAJOR,
>   	.minor = KMS_DRIVER_MINOR,
>   	.patchlevel = KMS_DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
> index 02a65971d140..0f3dbffc492d 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.h
> +++ b/drivers/gpu/drm/radeon/radeon_drv.h
> @@ -43,7 +43,6 @@
>   
>   #define DRIVER_NAME		"radeon"
>   #define DRIVER_DESC		"ATI Radeon"
> -#define DRIVER_DATE		"20080528"
>   
>   /* Interface history:
>    *
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
> index 0f5204ef996e..be39b107b98c 100644
> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
> @@ -611,7 +611,6 @@ static const struct drm_driver rcar_du_driver = {
>   	.fops			= &rcar_du_fops,
>   	.name			= "rcar-du",
>   	.desc			= "Renesas R-Car Display Unit",
> -	.date			= "20130110",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
> index 0a03a20f663b..9bbdc4d63d88 100644
> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
> @@ -84,7 +84,6 @@ static const struct drm_driver rzg2l_du_driver = {
>   	.fops			= &rzg2l_du_fops,
>   	.name			= "rzg2l-du",
>   	.desc			= "Renesas RZ/G2L Display Unit",
> -	.date			= "20230410",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 40b582ee178e..387eb602dadf 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -107,7 +107,6 @@ static const struct drm_driver shmob_drm_driver = {
>   	.fops			= &shmob_drm_fops,
>   	.name			= "shmob-drm",
>   	.desc			= "Renesas SH Mobile DRM",
> -	.date			= "20120424",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index 0393b48ad65b..1fe4399d6901 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -39,7 +39,6 @@
>   
>   #define DRIVER_NAME	"rockchip"
>   #define DRIVER_DESC	"RockChip Soc DRM"
> -#define DRIVER_DATE	"20140818"
>   #define DRIVER_MAJOR	1
>   #define DRIVER_MINOR	0
>   
> @@ -235,7 +234,6 @@ static const struct drm_driver rockchip_drm_driver = {
>   	.fops			= &rockchip_drm_driver_fops,
>   	.name	= DRIVER_NAME,
>   	.desc	= DRIVER_DESC,
> -	.date	= DRIVER_DATE,
>   	.major	= DRIVER_MAJOR,
>   	.minor	= DRIVER_MINOR,
>   };
> diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
> index a737f650c2bc..7b9f8fc193ac 100644
> --- a/drivers/gpu/drm/solomon/ssd130x.c
> +++ b/drivers/gpu/drm/solomon/ssd130x.c
> @@ -39,7 +39,6 @@
>   
>   #define DRIVER_NAME	"ssd130x"
>   #define DRIVER_DESC	"DRM driver for Solomon SSD13xx OLED displays"
> -#define DRIVER_DATE	"20220131"
>   #define DRIVER_MAJOR	1
>   #define DRIVER_MINOR	0
>   
> @@ -1784,7 +1783,6 @@ static const struct drm_driver ssd130x_drm_driver = {
>   	DRM_FBDEV_SHMEM_DRIVER_OPS,
>   	.name			= DRIVER_NAME,
>   	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>   	.major			= DRIVER_MAJOR,
>   	.minor			= DRIVER_MINOR,
>   	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> diff --git a/drivers/gpu/drm/sprd/sprd_drm.c b/drivers/gpu/drm/sprd/sprd_drm.c
> index a74cd0caf645..867ee2d8997f 100644
> --- a/drivers/gpu/drm/sprd/sprd_drm.c
> +++ b/drivers/gpu/drm/sprd/sprd_drm.c
> @@ -23,7 +23,6 @@
>   
>   #define DRIVER_NAME	"sprd"
>   #define DRIVER_DESC	"Spreadtrum SoCs' DRM Driver"
> -#define DRIVER_DATE	"20200201"
>   #define DRIVER_MAJOR	1
>   #define DRIVER_MINOR	0
>   
> @@ -59,7 +58,6 @@ static struct drm_driver sprd_drm_drv = {
>   
>   	.name			= DRIVER_NAME,
>   	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>   	.major			= DRIVER_MAJOR,
>   	.minor			= DRIVER_MINOR,
>   };
> diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
> index a6c13318aa0b..46e6b674fa54 100644
> --- a/drivers/gpu/drm/sti/sti_drv.c
> +++ b/drivers/gpu/drm/sti/sti_drv.c
> @@ -29,7 +29,6 @@
>   
>   #define DRIVER_NAME	"sti"
>   #define DRIVER_DESC	"STMicroelectronics SoC DRM"
> -#define DRIVER_DATE	"20140601"
>   #define DRIVER_MAJOR	1
>   #define DRIVER_MINOR	0
>   
> @@ -143,7 +142,6 @@ static const struct drm_driver sti_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   };
> diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
> index d181d11b277b..40a62c57e04c 100644
> --- a/drivers/gpu/drm/stm/drv.c
> +++ b/drivers/gpu/drm/stm/drv.c
> @@ -62,7 +62,6 @@ static const struct drm_driver drv_driver = {
>   	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
>   	.name = "stm",
>   	.desc = "STMicroelectronics SoC DRM",
> -	.date = "20170330",
>   	.major = 1,
>   	.minor = 0,
>   	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
> index a7c11b795e98..025b0bdcbfd9 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -50,7 +50,6 @@ static const struct drm_driver sun4i_drv_driver = {
>   	.fops			= &sun4i_drv_fops,
>   	.name			= "sun4i-drm",
>   	.desc			= "Allwinner sun4i Display Engine",
> -	.date			= "20150629",
>   	.major			= 1,
>   	.minor			= 0,
>   
> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
> index 34878f5d2918..4596073fe28f 100644
> --- a/drivers/gpu/drm/tegra/drm.c
> +++ b/drivers/gpu/drm/tegra/drm.c
> @@ -35,7 +35,6 @@
>   
>   #define DRIVER_NAME "tegra"
>   #define DRIVER_DESC "NVIDIA Tegra graphics"
> -#define DRIVER_DATE "20120330"
>   #define DRIVER_MAJOR 1
>   #define DRIVER_MINOR 0
>   #define DRIVER_PATCHLEVEL 0
> @@ -901,7 +900,6 @@ static const struct drm_driver tegra_drm_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
> index 53bc219c097f..ee1132d581f5 100644
> --- a/drivers/gpu/drm/tidss/tidss_drv.c
> +++ b/drivers/gpu/drm/tidss/tidss_drv.c
> @@ -113,7 +113,6 @@ static const struct drm_driver tidss_driver = {
>   	DRM_FBDEV_DMA_DRIVER_OPS,
>   	.name			= "tidss",
>   	.desc			= "TI Keystone DSS",
> -	.date			= "20180215",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> index 821d0ba26287..8013f01dbdf0 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> @@ -481,7 +481,6 @@ static const struct drm_driver tilcdc_driver = {
>   	.fops               = &fops,
>   	.name               = "tilcdc",
>   	.desc               = "TI LCD Controller DRM",
> -	.date               = "20121205",
>   	.major              = 1,
>   	.minor              = 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c
> index 5a0c8a874421..1e570f6f639f 100644
> --- a/drivers/gpu/drm/tiny/arcpgu.c
> +++ b/drivers/gpu/drm/tiny/arcpgu.c
> @@ -367,7 +367,6 @@ static const struct drm_driver arcpgu_drm_driver = {
>   	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
>   	.name = "arcpgu",
>   	.desc = "ARC PGU Controller",
> -	.date = "20160219",
>   	.major = 1,
>   	.minor = 0,
>   	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
> index 71a1f15d6ac9..89a699370a59 100644
> --- a/drivers/gpu/drm/tiny/bochs.c
> +++ b/drivers/gpu/drm/tiny/bochs.c
> @@ -680,7 +680,6 @@ static const struct drm_driver bochs_driver = {
>   	.fops			= &bochs_fops,
>   	.name			= "bochs-drm",
>   	.desc			= "bochs dispi vga interface (qemu stdvga)",
> -	.date			= "20130925",
>   	.major			= 1,
>   	.minor			= 0,
>   	DRM_GEM_SHMEM_DRIVER_OPS,
> diff --git a/drivers/gpu/drm/tiny/cirrus-qemu.c b/drivers/gpu/drm/tiny/cirrus-qemu.c
> index c0ae316888e2..52ec1e4ea9e5 100644
> --- a/drivers/gpu/drm/tiny/cirrus-qemu.c
> +++ b/drivers/gpu/drm/tiny/cirrus-qemu.c
> @@ -48,7 +48,6 @@
>   
>   #define DRIVER_NAME "cirrus-qemu"
>   #define DRIVER_DESC "qemu cirrus vga"
> -#define DRIVER_DATE "2019"
>   #define DRIVER_MAJOR 2
>   #define DRIVER_MINOR 0
>   
> @@ -659,7 +658,6 @@ static const struct drm_driver cirrus_driver = {
>   
>   	.name		 = DRIVER_NAME,
>   	.desc		 = DRIVER_DESC,
> -	.date		 = DRIVER_DATE,
>   	.major		 = DRIVER_MAJOR,
>   	.minor		 = DRIVER_MINOR,
>   
> diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
> index 47dbee84d58b..41e9bfb2e2ff 100644
> --- a/drivers/gpu/drm/tiny/gm12u320.c
> +++ b/drivers/gpu/drm/tiny/gm12u320.c
> @@ -34,7 +34,6 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
>   
>   #define DRIVER_NAME		"gm12u320"
>   #define DRIVER_DESC		"Grain Media GM12U320 USB projector display"
> -#define DRIVER_DATE		"2019"
>   #define DRIVER_MAJOR		1
>   #define DRIVER_MINOR		0
>   
> @@ -626,7 +625,6 @@ static const struct drm_driver gm12u320_drm_driver = {
>   
>   	.name		 = DRIVER_NAME,
>   	.desc		 = DRIVER_DESC,
> -	.date		 = DRIVER_DATE,
>   	.major		 = DRIVER_MAJOR,
>   	.minor		 = DRIVER_MINOR,
>   
> diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c
> index 910279ebbbaa..df263818f45f 100644
> --- a/drivers/gpu/drm/tiny/hx8357d.c
> +++ b/drivers/gpu/drm/tiny/hx8357d.c
> @@ -199,7 +199,6 @@ static const struct drm_driver hx8357d_driver = {
>   	.debugfs_init		= mipi_dbi_debugfs_init,
>   	.name			= "hx8357d",
>   	.desc			= "HX8357D",
> -	.date			= "20181023",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c
> index e54ce120692f..62cadf5e033d 100644
> --- a/drivers/gpu/drm/tiny/ili9163.c
> +++ b/drivers/gpu/drm/tiny/ili9163.c
> @@ -118,7 +118,6 @@ static struct drm_driver ili9163_driver = {
>   	.debugfs_init		= mipi_dbi_debugfs_init,
>   	.name			= "ili9163",
>   	.desc			= "Ilitek ILI9163",
> -	.date			= "20210208",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
> index f322e67f473a..6de44ff69b51 100644
> --- a/drivers/gpu/drm/tiny/ili9225.c
> +++ b/drivers/gpu/drm/tiny/ili9225.c
> @@ -364,7 +364,6 @@ static const struct drm_driver ili9225_driver = {
>   	DRM_FBDEV_DMA_DRIVER_OPS,
>   	.name			= "ili9225",
>   	.desc			= "Ilitek ILI9225",
> -	.date			= "20171106",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c
> index 356c7f107c3e..e55029433509 100644
> --- a/drivers/gpu/drm/tiny/ili9341.c
> +++ b/drivers/gpu/drm/tiny/ili9341.c
> @@ -155,7 +155,6 @@ static const struct drm_driver ili9341_driver = {
>   	.debugfs_init		= mipi_dbi_debugfs_init,
>   	.name			= "ili9341",
>   	.desc			= "Ilitek ILI9341",
> -	.date			= "20180514",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
> index f5b1d21f7109..093661c771a0 100644
> --- a/drivers/gpu/drm/tiny/ili9486.c
> +++ b/drivers/gpu/drm/tiny/ili9486.c
> @@ -177,7 +177,6 @@ static const struct drm_driver ili9486_driver = {
>   	.debugfs_init		= mipi_dbi_debugfs_init,
>   	.name			= "ili9486",
>   	.desc			= "Ilitek ILI9486",
> -	.date			= "20200118",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
> index 61e33376fbc9..b6b4664908ae 100644
> --- a/drivers/gpu/drm/tiny/mi0283qt.c
> +++ b/drivers/gpu/drm/tiny/mi0283qt.c
> @@ -159,7 +159,6 @@ static const struct drm_driver mi0283qt_driver = {
>   	.debugfs_init		= mipi_dbi_debugfs_init,
>   	.name			= "mi0283qt",
>   	.desc			= "Multi-Inno MI0283QT",
> -	.date			= "20160614",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c
> index b27ed3677bfd..cd5916752507 100644
> --- a/drivers/gpu/drm/tiny/ofdrm.c
> +++ b/drivers/gpu/drm/tiny/ofdrm.c
> @@ -25,7 +25,6 @@
>   
>   #define DRIVER_NAME	"ofdrm"
>   #define DRIVER_DESC	"DRM driver for OF platform devices"
> -#define DRIVER_DATE	"20220501"
>   #define DRIVER_MAJOR	1
>   #define DRIVER_MINOR	0
>   
> @@ -1348,7 +1347,6 @@ static struct drm_driver ofdrm_driver = {
>   	DRM_FBDEV_SHMEM_DRIVER_OPS,
>   	.name			= DRIVER_NAME,
>   	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>   	.major			= DRIVER_MAJOR,
>   	.minor			= DRIVER_MINOR,
>   	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
> index 79d5818cbbe6..4786b8144a9f 100644
> --- a/drivers/gpu/drm/tiny/panel-mipi-dbi.c
> +++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
> @@ -269,7 +269,6 @@ static const struct drm_driver panel_mipi_dbi_driver = {
>   	.debugfs_init		= mipi_dbi_debugfs_init,
>   	.name			= "panel-mipi-dbi",
>   	.desc			= "MIPI DBI compatible display panel",
> -	.date			= "20220103",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
> index 9373063a13fc..52ba6c699bc8 100644
> --- a/drivers/gpu/drm/tiny/repaper.c
> +++ b/drivers/gpu/drm/tiny/repaper.c
> @@ -917,7 +917,6 @@ static const struct drm_driver repaper_driver = {
>   	DRM_FBDEV_DMA_DRIVER_OPS,
>   	.name			= "repaper",
>   	.desc			= "Pervasive Displays RePaper e-ink panels",
> -	.date			= "20170405",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/sharp-memory.c b/drivers/gpu/drm/tiny/sharp-memory.c
> index d87068126f9b..03d2850310c4 100644
> --- a/drivers/gpu/drm/tiny/sharp-memory.c
> +++ b/drivers/gpu/drm/tiny/sharp-memory.c
> @@ -107,7 +107,6 @@ static const struct drm_driver sharp_memory_drm_driver = {
>   	DRM_FBDEV_DMA_DRIVER_OPS,
>   	.name			= "sharp_memory_display",
>   	.desc			= "Sharp Display Memory LCD",
> -	.date			= "20231129",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
> index b3a2fc11dcf0..b47ca2d902d9 100644
> --- a/drivers/gpu/drm/tiny/simpledrm.c
> +++ b/drivers/gpu/drm/tiny/simpledrm.c
> @@ -31,7 +31,6 @@
>   
>   #define DRIVER_NAME	"simpledrm"
>   #define DRIVER_DESC	"DRM driver for simple-framebuffer platform devices"
> -#define DRIVER_DATE	"20200625"
>   #define DRIVER_MAJOR	1
>   #define DRIVER_MINOR	0
>   
> @@ -1015,7 +1014,6 @@ static struct drm_driver simpledrm_driver = {
>   	DRM_FBDEV_SHMEM_DRIVER_OPS,
>   	.name			= DRIVER_NAME,
>   	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>   	.major			= DRIVER_MAJOR,
>   	.minor			= DRIVER_MINOR,
>   	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
> index 7bfd4296c1c9..a29672d84ede 100644
> --- a/drivers/gpu/drm/tiny/st7586.c
> +++ b/drivers/gpu/drm/tiny/st7586.c
> @@ -295,7 +295,6 @@ static const struct drm_driver st7586_driver = {
>   	.debugfs_init		= mipi_dbi_debugfs_init,
>   	.name			= "st7586",
>   	.desc			= "Sitronix ST7586",
> -	.date			= "20170801",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
> index 6832ca590127..1d60f6e5b3bc 100644
> --- a/drivers/gpu/drm/tiny/st7735r.c
> +++ b/drivers/gpu/drm/tiny/st7735r.c
> @@ -160,7 +160,6 @@ static const struct drm_driver st7735r_driver = {
>   	.debugfs_init		= mipi_dbi_debugfs_init,
>   	.name			= "st7735r",
>   	.desc			= "Sitronix ST7735R",
> -	.date			= "20171128",
>   	.major			= 1,
>   	.minor			= 0,
>   };
> diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c
> index cb66dbbe2801..65a0d4301160 100644
> --- a/drivers/gpu/drm/tve200/tve200_drv.c
> +++ b/drivers/gpu/drm/tve200/tve200_drv.c
> @@ -146,7 +146,6 @@ static const struct drm_driver tve200_drm_driver = {
>   	.fops = &drm_fops,
>   	.name = "tve200",
>   	.desc = DRIVER_DESC,
> -	.date = "20170703",
>   	.major = 1,
>   	.minor = 0,
>   	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index 6c182b21028e..05b3a152cc33 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -78,7 +78,6 @@ static const struct drm_driver driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
> index 1eb716d9dad5..be00dc1d87a1 100644
> --- a/drivers/gpu/drm/udl/udl_drv.h
> +++ b/drivers/gpu/drm/udl/udl_drv.h
> @@ -26,7 +26,6 @@ struct drm_mode_create_dumb;
>   
>   #define DRIVER_NAME		"udl"
>   #define DRIVER_DESC		"DisplayLink"
> -#define DRIVER_DATE		"20120220"
>   
>   #define DRIVER_MAJOR		0
>   #define DRIVER_MINOR		0
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
> index fb35c5c3f1a7..9d8de9146cb0 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.c
> +++ b/drivers/gpu/drm/v3d/v3d_drv.c
> @@ -31,7 +31,6 @@
>   
>   #define DRIVER_NAME "v3d"
>   #define DRIVER_DESC "Broadcom V3D graphics"
> -#define DRIVER_DATE "20180419"
>   #define DRIVER_MAJOR 1
>   #define DRIVER_MINOR 0
>   #define DRIVER_PATCHLEVEL 0
> @@ -248,7 +247,6 @@ static const struct drm_driver v3d_drm_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> index d9d884aad97f..bb861f0a0a31 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> @@ -189,7 +189,6 @@ static const struct drm_driver driver = {
>   	.fops = &vbox_fops,
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> index e77bd6512eb1..dfa935f381a6 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> @@ -25,7 +25,6 @@
>   
>   #define DRIVER_NAME         "vboxvideo"
>   #define DRIVER_DESC         "Oracle VM VirtualBox Graphics Card"
> -#define DRIVER_DATE         "20130823"
>   
>   #define DRIVER_MAJOR        1
>   #define DRIVER_MINOR        0
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> index ee5df153c2a6..e88a7ee486c6 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.c
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -47,7 +47,6 @@
>   
>   #define DRIVER_NAME "vc4"
>   #define DRIVER_DESC "Broadcom VC4 graphics"
> -#define DRIVER_DATE "20140616"
>   #define DRIVER_MAJOR 0
>   #define DRIVER_MINOR 0
>   #define DRIVER_PATCHLEVEL 0
> @@ -222,7 +221,6 @@ const struct drm_driver vc4_drm_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> @@ -244,7 +242,6 @@ const struct drm_driver vc5_drm_driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
> index c5e3e5457737..2752ab4f1c97 100644
> --- a/drivers/gpu/drm/vgem/vgem_drv.c
> +++ b/drivers/gpu/drm/vgem/vgem_drv.c
> @@ -47,7 +47,6 @@
>   
>   #define DRIVER_NAME	"vgem"
>   #define DRIVER_DESC	"Virtual GEM provider"
> -#define DRIVER_DATE	"20120112"
>   #define DRIVER_MAJOR	1
>   #define DRIVER_MINOR	0
>   
> @@ -121,7 +120,6 @@ static const struct drm_driver vgem_driver = {
>   
>   	.name	= DRIVER_NAME,
>   	.desc	= DRIVER_DESC,
> -	.date	= DRIVER_DATE,
>   	.major	= DRIVER_MAJOR,
>   	.minor	= DRIVER_MINOR,
>   };
> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
> index e216123ce6a5..6a67c6297d58 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_drv.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
> @@ -201,7 +201,6 @@ static const struct drm_driver driver = {
>   
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
> index 8328107edf78..f42ca9d8ed10 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
> @@ -45,7 +45,6 @@
>   
>   #define DRIVER_NAME "virtio_gpu"
>   #define DRIVER_DESC "virtio GPU"
> -#define DRIVER_DATE "0"
>   
>   #define DRIVER_MAJOR 0
>   #define DRIVER_MINOR 1
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
> index fa3331f612e3..e0409aba9349 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.c
> +++ b/drivers/gpu/drm/vkms/vkms_drv.c
> @@ -34,7 +34,6 @@
>   
>   #define DRIVER_NAME	"vkms"
>   #define DRIVER_DESC	"Virtual Kernel Mode Setting"
> -#define DRIVER_DATE	"20180514"
>   #define DRIVER_MAJOR	1
>   #define DRIVER_MINOR	0
>   
> @@ -116,7 +115,6 @@ static const struct drm_driver vkms_driver = {
>   
>   	.name			= DRIVER_NAME,
>   	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>   	.major			= DRIVER_MAJOR,
>   	.minor			= DRIVER_MINOR,
>   };
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> index ded48554568a..1699236fca5a 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> @@ -1634,7 +1634,6 @@ static const struct drm_driver driver = {
>   	.fops = &vmwgfx_driver_fops,
>   	.name = VMWGFX_DRIVER_NAME,
>   	.desc = VMWGFX_DRIVER_DESC,
> -	.date = VMWGFX_DRIVER_DATE,
>   	.major = VMWGFX_DRIVER_MAJOR,
>   	.minor = VMWGFX_DRIVER_MINOR,
>   	.patchlevel = VMWGFX_DRIVER_PATCHLEVEL
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> index b21831ef214a..5275ef632d4b 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> @@ -57,7 +57,6 @@
>   
>   
>   #define VMWGFX_DRIVER_NAME "vmwgfx"
> -#define VMWGFX_DRIVER_DATE "20211206"
>   #define VMWGFX_DRIVER_MAJOR 2
>   #define VMWGFX_DRIVER_MINOR 20
>   #define VMWGFX_DRIVER_PATCHLEVEL 0
> diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
> index d6fccea1e083..56d4ffb650da 100644
> --- a/drivers/gpu/drm/xe/xe_device.c
> +++ b/drivers/gpu/drm/xe/xe_device.c
> @@ -271,7 +271,6 @@ static struct drm_driver driver = {
>   	.fops = &xe_driver_fops,
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>   	.major = DRIVER_MAJOR,
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/xe/xe_drv.h b/drivers/gpu/drm/xe/xe_drv.h
> index d45b71426cc8..d61650d4aa0b 100644
> --- a/drivers/gpu/drm/xe/xe_drv.h
> +++ b/drivers/gpu/drm/xe/xe_drv.h
> @@ -10,7 +10,6 @@
>   
>   #define DRIVER_NAME		"xe"
>   #define DRIVER_DESC		"Intel Xe Graphics"
> -#define DRIVER_DATE		"20201103"
>   
>   /* Interface history:
>    *
> diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
> index 931d855bfbe8..1bda7ef606cc 100644
> --- a/drivers/gpu/drm/xen/xen_drm_front.c
> +++ b/drivers/gpu/drm/xen/xen_drm_front.c
> @@ -478,7 +478,6 @@ static const struct drm_driver xen_drm_driver = {
>   	.fops                      = &xen_drm_dev_fops,
>   	.name                      = "xendrm-du",
>   	.desc                      = "Xen PV DRM Display Unit",
> -	.date                      = "20180221",
>   	.major                     = 1,
>   	.minor                     = 0,
>   
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c
> index e272ecbce78d..b47463473472 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_kms.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c
> @@ -409,7 +409,6 @@ static const struct drm_driver zynqmp_dpsub_drm_driver = {
>   
>   	.name				= "zynqmp-dpsub",
>   	.desc				= "Xilinx DisplayPort Subsystem Driver",
> -	.date				= "20130509",
>   	.major				= 1,
>   	.minor				= 0,
>   };
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index 1bbbcb8e2d23..1b6e59139e6c 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -401,8 +401,6 @@ struct drm_driver {
>   	char *name;
>   	/** @desc: driver description */
>   	char *desc;
> -	/** @date: driver date, unused, to be removed */
> -	char *date;
>   
>   	/**
>   	 * @driver_features:

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



From andre.draszik at linaro.org  Wed Dec  4 23:33:16 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 07:33:16 +0000
Subject: [PATCH v3 5/8] phy: exynos5-usbdrd: gs101: ensure power is gated
 to SS phy in phy_exit()
In-Reply-To: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
Message-ID: <20241205-gs101-phy-lanes-orientation-phy-v3-5-32f721bed219@linaro.org>

We currently don't gate the power to the SS phy in phy_exit().

Shuffle the code slightly to ensure the power is gated to the SS phy as
well.

Fixes: 32267c29bc7d ("phy: exynos5-usbdrd: support Exynos USBDRD 3.1 combo phy (HS & SS)")
CC: stable at vger.kernel.org # 6.11+
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* add cc-stable and fixes tags (Krzysztof)
* collect tags
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 2a724d362c2d..c1ce6fdeef31 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1296,14 +1296,17 @@ static int exynos5_usbdrd_gs101_phy_exit(struct phy *phy)
 	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
 	int ret;
 
+	if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) {
+		ret = exynos850_usbdrd_phy_exit(phy);
+		if (ret)
+			return ret;
+	}
+
+	exynos5_usbdrd_phy_isol(inst, true);
+
 	if (inst->phy_cfg->id != EXYNOS5_DRDPHY_UTMI)
 		return 0;
 
-	ret = exynos850_usbdrd_phy_exit(phy);
-	if (ret)
-		return ret;
-
-	exynos5_usbdrd_phy_isol(inst, true);
 	return regulator_bulk_disable(phy_drd->drv_data->n_regulators,
 				      phy_drd->regulators);
 }

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Wed Dec  4 23:33:18 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 07:33:18 +0000
Subject: [PATCH v3 7/8] phy: exynos5-usbdrd: subscribe to orientation
 notifier if required
In-Reply-To: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
Message-ID: <20241205-gs101-phy-lanes-orientation-phy-v3-7-32f721bed219@linaro.org>

gs101's SS phy needs to be configured differently based on the
connector orientation, as the SS link can only be established if the
mux is configured correctly.

The code to handle programming of the mux is in place already, this commit
now adds the missing pieces to subscribe to the Type-C orientation
switch event.

Note that for this all to work we rely on the USB controller
re-initialising us. It should invoke our .exit() upon cable unplug, and
during cable plug we'll receive the orientation event after which we
expect our .init() to be called.

Above reinitialisation happens if the DWC3 controller can enter runtime
suspend automatically. For the DWC3 driver, this is an opt-in:
    echo auto > /sys/devices/.../11110000.usb/power/control
Once done, things work as long as the UDC is not bound as otherwise it
stays busy because it doesn't cancel / stop outstanding TRBs. For now
we have to manually unbind the UDC in that case:
     echo "" > sys/kernel/config/usb_gadget/.../UDC

Note that if the orientation-switch property is missing from the DT,
the code will behave as before this commit (meaning for gs101 it will
work in SS mode in one orientation only). Other platforms are not
affected either way.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v3:
* drop init to -1 of phy_drd->orientation (Vinod)
* avoid #ifdef and switch to normal conditional IS_ENABLED() for
  CONFIG_TYPEC

v2:
* move #include typec_mux.h from parent patch into this one (Peter)

IS_ENABLED(CONFIG_TYPEC)
---
 drivers/phy/samsung/Kconfig              |  1 +
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 56 ++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig
index f10afa3d7ff5..fc7bd1088576 100644
--- a/drivers/phy/samsung/Kconfig
+++ b/drivers/phy/samsung/Kconfig
@@ -80,6 +80,7 @@ config PHY_EXYNOS5_USBDRD
 	tristate "Exynos5 SoC series USB DRD PHY driver"
 	depends on (ARCH_EXYNOS && OF) || COMPILE_TEST
 	depends on HAS_IOMEM
+	depends on TYPEC || (TYPEC=n && COMPILE_TEST)
 	depends on USB_DWC3_EXYNOS
 	select GENERIC_PHY
 	select MFD_SYSCON
diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 206483c7ca55..6dcc3c80c1d2 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -24,6 +24,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/usb/typec.h>
+#include <linux/usb/typec_mux.h>
 
 /* Exynos USB PHY registers */
 #define EXYNOS5_FSEL_9MHZ6		0x0
@@ -394,6 +395,7 @@ struct exynos5_usbdrd_phy_drvdata {
  * @extrefclk: frequency select settings when using 'separate
  *	       reference clocks' for SS and HS operations
  * @regulators: regulators for phy
+ * @sw: TypeC orientation switch handle
  * @orientation: TypeC connector orientation - normal or flipped
  */
 struct exynos5_usbdrd_phy {
@@ -415,6 +417,7 @@ struct exynos5_usbdrd_phy {
 	u32 extrefclk;
 	struct regulator_bulk_data *regulators;
 
+	struct typec_switch_dev *sw;
 	enum typec_orientation orientation;
 };
 
@@ -1400,6 +1403,55 @@ static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd)
 	return 0;
 }
 
+static int exynos5_usbdrd_orien_sw_set(struct typec_switch_dev *sw,
+				       enum typec_orientation orientation)
+{
+	struct exynos5_usbdrd_phy *phy_drd = typec_switch_get_drvdata(sw);
+
+	scoped_guard(mutex, &phy_drd->phy_mutex)
+		phy_drd->orientation = orientation;
+
+	return 0;
+}
+
+static void exynos5_usbdrd_orien_switch_unregister(void *data)
+{
+	struct exynos5_usbdrd_phy *phy_drd = data;
+
+	typec_switch_unregister(phy_drd->sw);
+}
+
+static int exynos5_usbdrd_setup_notifiers(struct exynos5_usbdrd_phy *phy_drd)
+{
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_TYPEC))
+		return 0;
+
+	if (device_property_present(phy_drd->dev, "orientation-switch")) {
+		struct typec_switch_desc sw_desc = { };
+
+		sw_desc.drvdata = phy_drd;
+		sw_desc.fwnode = dev_fwnode(phy_drd->dev);
+		sw_desc.set = exynos5_usbdrd_orien_sw_set;
+
+		phy_drd->sw = typec_switch_register(phy_drd->dev, &sw_desc);
+		if (IS_ERR(phy_drd->sw))
+			return dev_err_probe(phy_drd->dev,
+					     PTR_ERR(phy_drd->sw),
+					     "Failed to register TypeC orientation switch\n");
+
+		ret = devm_add_action_or_reset(phy_drd->dev,
+					       exynos5_usbdrd_orien_switch_unregister,
+					       phy_drd);
+		if (ret)
+			return dev_err_probe(phy_drd->dev, ret,
+					     "Failed to register TypeC orientation devm action\n");
+	}
+
+	return 0;
+}
+
 static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
 	{
 		.id		= EXYNOS5_DRDPHY_UTMI,
@@ -1789,6 +1841,10 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to get regulators\n");
 
+	ret = exynos5_usbdrd_setup_notifiers(phy_drd);
+	if (ret)
+		return ret;
+
 	dev_vdbg(dev, "Creating usbdrd_phy phy\n");
 
 	for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Wed Dec  4 23:33:15 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 07:33:15 +0000
Subject: [PATCH v3 4/8] phy: exynos5-usbdrd: fix EDS distribution tuning
 (gs101)
In-Reply-To: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
Message-ID: <20241205-gs101-phy-lanes-orientation-phy-v3-4-32f721bed219@linaro.org>

This code's intention is to configure lane0 and lane2 tunings, but for
lane2 there is a typo and it ends up tuning something else.

Fix the typo, as it doesn't appear to make sense to apply different
tunings for lane0 vs lane2.

The same typo appears to exist in the bootloader, hence we restore the
original value in the typo'd registers as well. This can be removed
once / if the bootloader is updated.

Note that this is incorrect in the downstream driver as well - the
values had been copied from there.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index ceae4b47cece..2a724d362c2d 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1510,8 +1510,11 @@ static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_preinit[] = {
 	PHY_TUNING_ENTRY_PMA(0x09e0, -1, 0x00),
 	PHY_TUNING_ENTRY_PMA(0x09e4, -1, 0x36),
 	PHY_TUNING_ENTRY_PMA(0x1e7c, -1, 0x06),
-	PHY_TUNING_ENTRY_PMA(0x1e90, -1, 0x00),
-	PHY_TUNING_ENTRY_PMA(0x1e94, -1, 0x36),
+	PHY_TUNING_ENTRY_PMA(0x19e0, -1, 0x00),
+	PHY_TUNING_ENTRY_PMA(0x19e4, -1, 0x36),
+	/* fix bootloader bug */
+	PHY_TUNING_ENTRY_PMA(0x1e90, -1, 0x02),
+	PHY_TUNING_ENTRY_PMA(0x1e94, -1, 0x0b),
 	/* improve LVCC */
 	PHY_TUNING_ENTRY_PMA(0x08f0, -1, 0x30),
 	PHY_TUNING_ENTRY_PMA(0x18f0, -1, 0x30),

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Wed Dec  4 23:33:17 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 07:33:17 +0000
Subject: [PATCH v3 6/8] phy: exynos5-usbdrd: gs101: configure SS lanes
 based on orientation
In-Reply-To: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
Message-ID: <20241205-gs101-phy-lanes-orientation-phy-v3-6-32f721bed219@linaro.org>

USB SS lanes need to be configured based on the connector orientation -
at most two lanes will be in use for USB (and the remaining two for
alternate modes like DP).

For the USB link to come up in SS, the lane configuration registers
have to be programmed accordingly.

While we still need a way to be notified of the actual connector
orientation and then reprogram the registers accordingly (at the moment
the configuration happens just once during phy_init() and never again),
we can prepare the code doing the configuration to take the orientation
into account.

Do so.

Note: the mutex is needed to synchronize this with the upcoming
connector orientation callback.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
* replace #include typec_mux.h with typec.h, and move the former into
  next patch (Peter)
* commit message typo (Peter)
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 72 ++++++++++++++++++++++----------
 1 file changed, 51 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index c1ce6fdeef31..206483c7ca55 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -23,6 +23,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
+#include <linux/usb/typec.h>
 
 /* Exynos USB PHY registers */
 #define EXYNOS5_FSEL_9MHZ6		0x0
@@ -209,6 +210,10 @@
 
 #define EXYNOS9_PMA_USBDP_CMN_REG00B8		0x02e0
 #define CMN_REG00B8_LANE_MUX_SEL_DP		GENMASK(3, 0)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE3	BIT(3)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE2	BIT(2)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE1	BIT(1)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE0	BIT(0)
 
 #define EXYNOS9_PMA_USBDP_CMN_REG01C0		0x0700
 #define CMN_REG01C0_ANA_LCPLL_LOCK_DONE		BIT(7)
@@ -383,11 +388,13 @@ struct exynos5_usbdrd_phy_drvdata {
  * @clks: clocks for register access
  * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required)
  * @drv_data: pointer to SoC level driver data structure
+ * @phy_mutex: mutex protecting phy_init/exit & TCPC callbacks
  * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY
  *	    instances each with its 'phy' and 'phy_cfg'.
  * @extrefclk: frequency select settings when using 'separate
  *	       reference clocks' for SS and HS operations
  * @regulators: regulators for phy
+ * @orientation: TypeC connector orientation - normal or flipped
  */
 struct exynos5_usbdrd_phy {
 	struct device *dev;
@@ -397,6 +404,7 @@ struct exynos5_usbdrd_phy {
 	struct clk_bulk_data *clks;
 	struct clk_bulk_data *core_clks;
 	const struct exynos5_usbdrd_phy_drvdata *drv_data;
+	struct mutex phy_mutex;
 	struct phy_usb_instance {
 		struct phy *phy;
 		u32 index;
@@ -406,6 +414,8 @@ struct exynos5_usbdrd_phy {
 	} phys[EXYNOS5_DRDPHYS_NUM];
 	u32 extrefclk;
 	struct regulator_bulk_data *regulators;
+
+	enum typec_orientation orientation;
 };
 
 static inline
@@ -647,22 +657,38 @@ exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(struct exynos5_usbdrd_phy *phy_drd)
 	/* lane configuration: USB on all lanes */
 	reg = readl(regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8);
 	reg &= ~CMN_REG00B8_LANE_MUX_SEL_DP;
-	writel(reg, regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8);
-
 	/*
-	 * FIXME: below code supports one connector orientation only. It needs
-	 * updating once we can receive connector events.
+	 * USB on lanes 0 & 1 in normal mode, or 2 & 3 if reversed, DP on the
+	 * other ones.
 	 */
+	reg |= FIELD_PREP(CMN_REG00B8_LANE_MUX_SEL_DP,
+			  ((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL)
+			   ? (CMN_REG00B8_LANE_MUX_SEL_DP_LANE3
+			      | CMN_REG00B8_LANE_MUX_SEL_DP_LANE2)
+			   : (CMN_REG00B8_LANE_MUX_SEL_DP_LANE1
+			      | CMN_REG00B8_LANE_MUX_SEL_DP_LANE0)));
+	writel(reg, regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8);
+
 	/* override of TX receiver detector and comparator: lane 1 */
 	reg = readl(regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0413);
-	reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN;
-	reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_EN;
+	if (phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) {
+		reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN;
+		reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_EN;
+	} else {
+		reg |= TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN;
+		reg |= TRSV_REG0413_OVRD_LN1_TX_RXD_EN;
+	}
 	writel(reg, regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0413);
 
 	/* lane 3 */
 	reg = readl(regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0813);
-	reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN;
-	reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_EN;
+	if (phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) {
+		reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN;
+		reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_EN;
+	} else {
+		reg &= ~TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN;
+		reg &= ~TRSV_REG0813_OVRD_LN3_TX_RXD_EN;
+	}
 	writel(reg, regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0813);
 }
 
@@ -700,21 +726,18 @@ exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock(struct exynos5_usbdrd_phy *phy_drd
 	int err;
 
 	err = readl_poll_timeout(
-			phy_drd->reg_pma + EXYNOS9_PMA_USBDP_TRSV_REG03C3,
-			reg, (reg & locked) == locked, sleep_us, timeout_us);
-	if (!err)
-		return;
-
-	dev_err(phy_drd->dev,
-		"timed out waiting for CDR lock (l0): %#.8x, retrying\n", reg);
-
-	/* based on cable orientation, this might be on the other phy port */
-	err = readl_poll_timeout(
-			phy_drd->reg_pma + EXYNOS9_PMA_USBDP_TRSV_REG07C3,
+			/* lane depends on cable orientation */
+			(phy_drd->reg_pma
+			 + ((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL)
+			    ? EXYNOS9_PMA_USBDP_TRSV_REG03C3
+			    : EXYNOS9_PMA_USBDP_TRSV_REG07C3)),
 			reg, (reg & locked) == locked, sleep_us, timeout_us);
 	if (err)
 		dev_err(phy_drd->dev,
-			"timed out waiting for CDR lock (l2): %#.8x\n", reg);
+			"timed out waiting for CDR(l%d) lock: %#.8x\n",
+			((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL)
+			 ? 0
+			 : 2), reg);
 }
 
 static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
@@ -1184,7 +1207,8 @@ static int exynos850_usbdrd_phy_init(struct phy *phy)
 		return ret;
 
 	/* UTMI or PIPE3 specific init */
-	inst->phy_cfg->phy_init(phy_drd);
+	scoped_guard(mutex, &phy_drd->phy_mutex)
+		inst->phy_cfg->phy_init(phy_drd);
 
 	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
 
@@ -1203,6 +1227,8 @@ static int exynos850_usbdrd_phy_exit(struct phy *phy)
 	if (ret)
 		return ret;
 
+	guard(mutex)(&phy_drd->phy_mutex);
+
 	/* Set PHY clock and control HS PHY */
 	reg = readl(regs_base + EXYNOS850_DRD_UTMI);
 	reg &= ~(UTMI_DP_PULLDOWN | UTMI_DM_PULLDOWN);
@@ -1701,6 +1727,10 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 		return -EINVAL;
 	phy_drd->drv_data = drv_data;
 
+	ret = devm_mutex_init(dev, &phy_drd->phy_mutex);
+	if (ret)
+		return ret;
+
 	if (of_property_present(dev->of_node, "reg-names")) {
 		void __iomem *reg;
 

-- 
2.47.0.338.g60cca15819-goog



From Karl.Li at mediatek.com  Wed Dec  4 23:34:08 2024
From: Karl.Li at mediatek.com (=?utf-8?B?S2FybCBMaSAo5p2O5pm65ZiJKQ==?=)
Date: Thu, 5 Dec 2024 07:34:08 +0000
Subject: [PATCH v2 1/1] soc: mediatek: Add command for APU SMC call
In-Reply-To: <b8de718de8d5b5357f67183c1d283180aff33f62.camel@mediatek.com>
References: <20241030013533.855696-1-karl.li@mediatek.com>
	 <20241030013533.855696-2-karl.li@mediatek.com>
	 <b8de718de8d5b5357f67183c1d283180aff33f62.camel@mediatek.com>
Message-ID: <94480dcb145fba89c41045cde374e1dd71a1e6af.camel@mediatek.com>

On Thu, 2024-12-05 at 14:49 +0800, Karl Li wrote:
> Dead maintainers,
"Dear" maintainers. Really sorry for the typo...
> 
> I hope you're doing well. Just a warm reminder that we're following
> up
> on this patch and really appreciate any feedback you might have.
> 
> Thanks you in advance for your review.
> 
> Regards,
> Karl
> 
> On Wed, 2024-10-30 at 09:35 +0800, Karl.Li wrote:
> > From: Karl Li <karl.li at mediatek.com>
> > 
> > Add command for APU SMC call.
> > The APU microprocess's start and stop sequence will process in ATF.
> > 
> > Signed-off-by: Karl Li <karl.li at mediatek.com>
> > ---
> > ?include/linux/firmware/mediatek/mtk-apu.h | 32
> > +++++++++++++++++++++++
> > ?1 file changed, 32 insertions(+)
> > ?create mode 100644 include/linux/firmware/mediatek/mtk-apu.h
> > 
> > diff --git a/include/linux/firmware/mediatek/mtk-apu.h
> > b/include/linux/firmware/mediatek/mtk-apu.h
> > new file mode 100644
> > index 000000000000..a327e31d40fa
> > --- /dev/null
> > +++ b/include/linux/firmware/mediatek/mtk-apu.h
> > @@ -0,0 +1,32 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2024 MediaTek Inc.
> > + */
> > +
> > +#ifndef __MEDIATEK_APU_H__
> > +#define __MEDIATEK_APU_H__
> > +
> > +enum mtk_apusys_kernel_op {
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON,		
> > 	/*? 0 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF,		/*
> > ?
> > 1 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER,		/*
> > ?
> > 2 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP,		/*
> > ?
> > 3 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT,		/*
> > ?
> > 4 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP,		/*
> > ?
> > 5 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP,		
> > 	/*? 6 */
> > +	MTK_APUSYS_KERNEL_OP_DEVAPC_INIT_RCX,			/*
> > ?
> > 7 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_SEC_MEM,		/*
> > ?
> > 8 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_DISABLE_WDT_ISR,	
> > 	/*? 9 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CLEAR_WDT_ISR,		/*
> > 10 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_GATING,		/*
> > 11 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_CG_UNGATING,		/*
> > 12 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_APUMMU,		/*
> > 13 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_DUMP,		/*
> > 14 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_WRITE,		/*
> > 15 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_LOGTOP_REG_W1C,		/*
> > 16 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_COLD_BOOT_CLR_MBOX_DUMMY,	/*
> > 17 */
> > +	MTK_APUSYS_KERNEL_OP_APUSYS_SETUP_CE_BIN,		/*
> > 18 */
> > +	MTK_APUSYS_KERNEL_OP_NUM,
> > +};
> > +
> > +#endif
> 


From Karl.Li at mediatek.com  Wed Dec  4 23:32:25 2024
From: Karl.Li at mediatek.com (=?utf-8?B?S2FybCBMaSAo5p2O5pm65ZiJKQ==?=)
Date: Thu, 5 Dec 2024 07:32:25 +0000
Subject: [PATCH 3/3] mailbox: mediatek: Add mtk-apu-mailbox driver
In-Reply-To: <0f98405c40530d81c342af06dea593e7babedeac.camel@mediatek.com>
References: <20241024092608.431581-1-karl.li@mediatek.com>
	 <20241024092608.431581-4-karl.li@mediatek.com>
	 <083c8f7b-0969-4ca3-8a91-35f5767c5f32@collabora.com>
	 <CAGXv+5Fw+qZhTTgJq0QdiQHgiQP2ByR1tgae2+k4erx+0fp61g@mail.gmail.com>
	 <a3c3280478bf86eb97a422782ce60ec4eaa35224.camel@mediatek.com>
	 <0f98405c40530d81c342af06dea593e7babedeac.camel@mediatek.com>
Message-ID: <cf75f3c3932ddc50f5697bc4f394bd77fc16cd39.camel@mediatek.com>

On Thu, 2024-12-05 at 07:05 +0000, Karl Li (???) wrote:
> Dead maintainers,
"Dear" maintainers. Really sorry for the typo...
> 
> I hope you're doing well. Just a warm reminder that we're following
> up
> on these patch and really appreciate any feedback you might have.
> 
> Thanks you in advance for your review.
> 
> Regards,
> Karl
> 
> On Tue, 2024-10-29 at 16:27 +0800, Karl Li wrote:
> > On Mon, 2024-10-28 at 14:16 +0800, Chen-Yu Tsai wrote:
> > > 
> > > External email : Please do not click links or open attachments
> > > until
> > > you have verified the sender or the content.
> > > 
> > > 
> > > On Thu, Oct 24, 2024 at 7:13?PM AngeloGioacchino Del Regno
> > > <angelogioacchino.delregno at collabora.com> wrote:
> > > > 
> > > > Il 24/10/24 11:25, Karl.Li ha scritto:
> > > > > From: Karl Li <karl.li at mediatek.com>
> > > > > 
> > > > > Add mtk-apu-mailbox driver to support the communication with
> > > > > APU remote microprocessor.
> > > > > 
> > > > > Also, the mailbox hardware contains extra spare (scratch)
> > > > > registers
> > > > > that other hardware blocks use to communicate through.
> > > > > Expose these with custom mtk_apu_mbox_(read|write)()
> > > > > functions.
> > > > > 
> > > > > Signed-off-by: Karl Li <karl.li at mediatek.com>
> > > > > ---
> > > > > ? drivers/mailbox/Kconfig???????????????? |?? 9 +
> > > > > ? drivers/mailbox/Makefile??????????????? |?? 2 +
> > > > > ? drivers/mailbox/mtk-apu-mailbox.c?????? | 222
> > > > > ++++++++++++++++++++++++
> > > > > ? include/linux/mailbox/mtk-apu-mailbox.h |? 20 +++
> > > > > ? 4 files changed, 253 insertions(+)
> > > > > ? create mode 100644 drivers/mailbox/mtk-apu-mailbox.c
> > > > > ? create mode 100644 include/linux/mailbox/mtk-apu-mailbox.h
> > > > > 
> > > > > diff --git a/drivers/mailbox/Kconfig
> > > > > b/drivers/mailbox/Kconfig
> > > > > index 6fb995778636..2338e08a110a 100644
> > > > > --- a/drivers/mailbox/Kconfig
> > > > > +++ b/drivers/mailbox/Kconfig
> > > > > @@ -240,6 +240,15 @@ config MTK_ADSP_MBOX
> > > > > ??????????? between processors with ADSP. It will place the
> > > > > message to share
> > > > > ??????? buffer and will access the ipc control.
> > > > > 
> > > > > +config MTK_APU_MBOX
> > > > > +???? tristate "MediaTek APU Mailbox Support"
> > > > > +???? depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > > +???? help
> > > > > +?????? Say yes here to add support for the MediaTek APU
> > > > > Mailbox
> > > > > +?????? driver. The mailbox implementation provides access
> > > > > from
> > > > > the
> > > > > +?????? application processor to the MediaTek AI Processing
> > > > > Unit.
> > > > > +?????? If unsure say N.
> > > > > +
> > > > > ? config MTK_CMDQ_MBOX
> > > > > ????? tristate "MediaTek CMDQ Mailbox Support"
> > > > > ????? depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > > diff --git a/drivers/mailbox/Makefile
> > > > > b/drivers/mailbox/Makefile
> > > > > index 3c3c27d54c13..6b6dcc78d644 100644
> > > > > --- a/drivers/mailbox/Makefile
> > > > > +++ b/drivers/mailbox/Makefile
> > > > > @@ -53,6 +53,8 @@ obj-$(CONFIG_STM32_IPCC)??? += stm32-ipcc.o
> > > > > 
> > > > > ? obj-$(CONFIG_MTK_ADSP_MBOX) += mtk-adsp-mailbox.o
> > > > > 
> > > > > +obj-$(CONFIG_MTK_APU_MBOX)?? += mtk-apu-mailbox.o
> > > > > +
> > > > > ? obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o
> > > > > 
> > > > > ? obj-$(CONFIG_ZYNQMP_IPI_MBOX)?????? += zynqmp-ipi-mailbox.o
> > > > > diff --git a/drivers/mailbox/mtk-apu-mailbox.c
> > > > > b/drivers/mailbox/mtk-apu-mailbox.c
> > > > > new file mode 100644
> > > > > index 000000000000..b347ebd34ef7
> > > > > --- /dev/null
> > > > > +++ b/drivers/mailbox/mtk-apu-mailbox.c
> > > > > @@ -0,0 +1,222 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0
> > > > > +/*
> > > > > + * Copyright (c) 2024 MediaTek Inc.
> > > > > + */
> > > > > +
> > > > > +#include <asm/io.h>
> > > > > +#include <linux/bits.h>
> > > > > +#include <linux/interrupt.h>
> > > > > +#include <linux/mailbox_controller.h>
> > > > > +#include <linux/mailbox/mtk-apu-mailbox.h>
> > > > > +#include <linux/platform_device.h>
> > > > > +
> > > > > +#define INBOX??????????????? (0x0)
> > > > > +#define OUTBOX?????????????? (0x20)
> > > > > +#define INBOX_IRQ??? (0xc0)
> > > > > +#define OUTBOX_IRQ?? (0xc4)
> > > > > +#define INBOX_IRQ_MASK?????? (0xd0)
> > > > > +
> > > > > +#define SPARE_OFF_START????? (0x40)
> > > > > +#define SPARE_OFF_END??????? (0xB0)
> > > > > +
> > > > > +struct mtk_apu_mailbox {
> > > > > +???? struct device *dev;
> > > > > +???? void __iomem *regs;
> > > > > +???? struct mbox_controller controller;
> > > > 
> > > > struct mbox_controller mbox;
> > > > 
> > > > ...it's shorter and consistent with at least other MTK mailbox
> > > > drivers.
> > > > 
> > > > > +???? u32 msgs[MSG_MBOX_SLOTS];
> > > > 
> > > > Just reuse struct mtk_apu_mailbox_msg instead.....
> > > > 
> > > > > +};
> > > > > +
> > > > > +struct mtk_apu_mailbox *g_mbox;
> > > > 
> > > > That global struct must disappear - and if you use the mailbox
> > > > API
> > > > correctly
> > > > it's even simple.
> > > > 
> > > > Also, you want something like....
> > > > 
> > > > static inline struct mtk_apu_mailbox
> > > > *get_mtk_apu_mailbox(struct
> > > > mbox_controller *mbox)
> > > > {
> > > > ??????? return container_of(mbox, struct mtk_apu_mailbox,
> > > > mbox);
> > > > }
> > > > 
> > > > > +
> > > > > +static irqreturn_t mtk_apu_mailbox_irq_top_half(int irq,
> > > > > void
> > > > > *dev_id)
> > > > > +{
> > > > static irqreturn_t mtk_apu_mailbox_irq(int irq, void *data)
> > > > {
> > > > ??????? struct mbox_chan *chan = data;
> > > > ??????? struct mtk_apu_mailbox = get_mtk_apu_mailbox(chan-
> > > > >mbox);
> > > > 
> > > > > +???? struct mtk_apu_mailbox *mbox = dev_id;
> > > > > +???? struct mbox_chan *link = &mbox->controller.chans[0];
> > > > > +???? int i;
> > > > > +
> > > > > +???? for (i = 0; i < MSG_MBOX_SLOTS; i++)
> > > > > +???????????? mbox->msgs[i] = readl(mbox->regs + OUTBOX + i *
> > > > > sizeof(u32));
> > > > > +
> > > > > +???? mbox_chan_received_data(link, &mbox->msgs);
> > > > > +
> > > > > +???? return IRQ_WAKE_THREAD;
> > > > > +}
> > > > > +
> > > > > +static irqreturn_t mtk_apu_mailbox_irq_btm_half(int irq,
> > > > > void
> > > > > *dev_id)
> > > > 
> > > > ....mtk_apu_mailbox_irq_thread(...)
> > > > 
> > > > > +{
> > > > > +???? struct mtk_apu_mailbox *mbox = dev_id;
> > > > > +???? struct mbox_chan *link = &mbox->controller.chans[0];
> > > > > +
> > > > > +???? mbox_chan_received_data_bh(link, &mbox->msgs);
> > > > 
> > > > I don't think that you really need this _bh variant, looks more
> > > > like you wanted
> > > > to have two callbacks instead of one.
> > > > 
> > > > You can instead have one callback and vary functionality based
> > > > based on reading
> > > > a variable to decide what to actually do inside. Not a big
> > > > deal.
> > > 
> > > The problem is that they need something with different semantics.
> > > mbox_chan_received_data() is atomic only.
> > 
> > Yes, as Chen-Yu said, we want to have another callback which can
> > run
> > under non-atomic semantic.
> > Even though we change the function based in the callback function
> > of
> > mbox_chan_received_data(), it is still non-atomic for the bottom-
> > half
> > handler.
> > 
> > > 
> > > > > +???? writel(readl(mbox->regs + OUTBOX_IRQ), mbox->regs +
> > > > > OUTBOX_IRQ);
> > > > > +
> > > > > +???? return IRQ_HANDLED;
> > > > > +}
> > > > > +
> > > > > +static int mtk_apu_mailbox_send_data(struct mbox_chan *chan,
> > > > > void *data)
> > > > > +{
> > > > > +???? struct mtk_apu_mailbox *mbox = container_of(chan->mbox,
> > > > > +???????????????????????????????????????????????? struct
> > > > > mtk_apu_mailbox,
> > > > > +????????????????????????????????????????????????
> > > > > controller);
> > > > > +???? struct mtk_apu_mailbox_msg *msg = data;
> > > > > +???? int i;
> > > > > +
> > > > > +???? if (msg->send_cnt <= 0 || msg->send_cnt >
> > > > > MSG_MBOX_SLOTS)
> > > > > {
> > > > > +???????????? dev_err(mbox->dev, "%s: invalid send_cnt %d\n",
> > > > > __func__, msg->send_cnt);
> > > > > +???????????? return -EINVAL;
> > > > > +???? }
> > > > > +
> > > > > +???? /*
> > > > > +????? *????? Mask lowest "send_cnt-1" interrupts bits, so
> > > > > the
> > > > > interrupt on the other side
> > > > > +????? *????? triggers only after the last data slot is
> > > > > written
> > > > > (sent).
> > > > > +????? */
> > > > > +???? writel(GENMASK(msg->send_cnt - 2, 0), mbox->regs +
> > > > > INBOX_IRQ_MASK);
> > > > > +???? for (i = 0; i < msg->send_cnt; i++)
> > > > > +???????????? writel(msg->data[i], mbox->regs + INBOX + i *
> > > > > sizeof(u32));
> > > > > +
> > > > > +???? return 0;
> > > > > +}
> > > > > +
> > > > > +static bool mtk_apu_mailbox_last_tx_done(struct mbox_chan
> > > > > *chan)
> > > > > +{
> > > > > +???? struct mtk_apu_mailbox *mbox = container_of(chan->mbox,
> > > > > +???????????????????????????????????????????????? struct
> > > > > mtk_apu_mailbox,
> > > > > +????????????????????????????????????????????????
> > > > > controller);
> > > > > +
> > > > > +???? return readl(mbox->regs + INBOX_IRQ) == 0;
> > > > > +}
> > > > > +
> > > > > +static const struct mbox_chan_ops mtk_apu_mailbox_ops = {
> > > > > +???? .send_data = mtk_apu_mailbox_send_data,
> > > > > +???? .last_tx_done = mtk_apu_mailbox_last_tx_done,
> > > > > +};
> > > > > +
> > > > > +/**
> > > > > + * mtk_apu_mbox_write - Write value to specifice
> > > > > mtk_apu_mbox
> > > > > spare register.
> > > > > + * @val: Value to be written.
> > > > > + * @offset: Offset of the spare register.
> > > > > + *
> > > > > + * Return: 0 if successful
> > > > > + *????? negative value if error happened
> > > > > + */
> > > > > +int mtk_apu_mbox_write(u32 val, u32 offset)
> > > > > +{
> > > > > +???? if (!g_mbox) {
> > > > > +???????????? pr_err("mtk apu mbox was not initialized, stop
> > > > > writing register\n");
> > > > > +???????????? return -ENODEV;
> > > > > +???? }
> > > > > +
> > > > > +???? if (offset < SPARE_OFF_START || offset >=
> > > > > SPARE_OFF_END)
> > > > > {
> > > > > +???????????? dev_err(g_mbox->dev, "Invalid offset %d for mtk
> > > > > apu
> > > > > mbox spare register\n", offset);
> > > > > +???????????? return -EINVAL;
> > > > > +???? }
> > > > > +
> > > > > +???? writel(val, g_mbox->regs + offset);
> > > > 
> > > > There's something odd in what you're doing here, why would you
> > > > ever
> > > > need
> > > > a function that performs a writel just like that? What's the
> > > > purpose?
> > > > 
> > > > What are you writing to the spare registers?
> > > > For which reason?
> > > 
> > > I'll leave the explaining to Karl, but based on internal reviews
> > > for
> > > the
> > > previous generation, it looked like passing values to/from the
> > > MCU.
> > > 
> > 
> > The main reason we want to access the APU mailbox spare registers
> > is
> > to
> > ensure that we can configure the necessary settings before the APU
> > firmware becomes fully operational.
> > 
> > At the early stage, the communication pathways between the APU and
> > the
> > Linux Kernel aren't yet available, so these spare registers are
> > needed
> > for passing the initial configuration data.
> > 
> > > > I think you can avoid (read this as: you *have to* avoid)
> > > > having
> > > > such a
> > > > function around.
> > > 
> > > Again, during the previous round of internal reviews, I had
> > > thought
> > > about modeling these as extra mbox channels. I may have even
> > > asked
> > > about this on IRC.
> > > 
> > > The problem is that it doesn't really have mbox semantics. They
> > > are
> > > just shared registers with no send/receive notification. So at
> > > the
> > > very least, there's nothing that will trigger a reception. I
> > > suppose
> > > we could make the .peek_data op trigger RX, but that's a really
> > > convoluted way to read just a register.
> > > 
> > > The other option would be to have a syscon / custom exported
> > > regmap?
> > > 
> > > > > +???? return 0;
> > > > > +}
> > > > > +EXPORT_SYMBOL_NS(mtk_apu_mbox_write, MTK_APU_MAILBOX);
> > > > > +
> > > > > +/**
> > > > > + * mtk_apu_mbox_read - Read value to specifice mtk_apu_mbox
> > > > > spare register.
> > > > > + * @offset: Offset of the spare register.
> > > > > + * @val: Pointer to store read value.
> > > > > + *
> > > > > + * Return: 0 if successful
> > > > > + *????? negative value if error happened
> > > > > + */
> > > > > +int mtk_apu_mbox_read(u32 offset, u32 *val)
> > > > > +{
> > > > > +???? if (!g_mbox) {
> > > > > +???????????? pr_err("mtk apu mbox was not initialized, stop
> > > > > reading register\n");
> > > > > +???????????? return -ENODEV;
> > > > > +???? }
> > > > > +
> > > > > +???? if (offset < SPARE_OFF_START || offset >=
> > > > > SPARE_OFF_END)
> > > > > {
> > > > > +???????????? dev_err(g_mbox->dev, "Invalid offset %d for mtk
> > > > > apu
> > > > > mbox spare register\n", offset);
> > > > > +???????????? return -EINVAL;
> > > > > +???? }
> > > > > +
> > > > > +???? *val = readl(g_mbox->regs + offset);
> > > > > +
> > > > 
> > > > Same goes for this one.
> > > > 
> > > > > +???? return 0;
> > > > > +}
> > > > > +EXPORT_SYMBOL_NS(mtk_apu_mbox_read, MTK_APU_MAILBOX);
> > > > > +
> > > > > +static int mtk_apu_mailbox_probe(struct platform_device
> > > > > *pdev)
> > > > > +{
> > > > > +???? struct device *dev = &pdev->dev;
> > > > > +???? struct mtk_apu_mailbox *mbox;
> > > > > +???? int irq = -1, ret = 0;
> > > > > +
> > > > > +???? mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
> > > > > +???? if (!mbox)
> > > > > +???????????? return -ENOMEM;
> > > > > +
> > > > > +???? mbox->dev = dev;
> > > > > +???? platform_set_drvdata(pdev, mbox);
> > > > > +
> > > > 
> > > > Please move the platform_get_irq call here or anyway before
> > > > registering the
> > > > mbox controller: in case anything goes wrong, devm won't have
> > > > to
> > > > unregister
> > > > the mbox afterwards because it never got registered in the
> > > > first
> > > > place.
> > > 
> > > To clarify, you mean _just_ platform_get_irq() and not
> > > request_irq
> > > as
> > > well.
> > > 
> > > > > +???? mbox->regs = devm_platform_ioremap_resource(pdev, 0);
> > > > > +???? if (IS_ERR(mbox->regs))
> > > > > +???????????? return PTR_ERR(mbox->regs);
> > > > > +
> > > > > +???? mbox->controller.txdone_irq = false;
> > > > > +???? mbox->controller.txdone_poll = true;
> > > > > +???? mbox->controller.txpoll_period = 1;
> > > > > +???? mbox->controller.ops = &mtk_apu_mailbox_ops;
> > > > > +???? mbox->controller.dev = dev;
> > > > > +???? /*
> > > > > +????? * Here we only register 1 mbox channel.
> > > > > +????? * The remaining channels are used by other modules.
> > > > 
> > > > What other modules? I don't really see any - so please at least
> > > > explain that in the
> > > > commit description.
> > 
> > Sorry for any confusion caused by the above comment. To clarify,
> > the
> > comment was specific to the MT8188 platform, which is the legacy
> > platform compared to MT8196.
> > In the context of MT8188, the APU mailbox has multiple in/out
> > boxes,
> > and Linux only utilizes in/out box 0, while the others are reserved
> > for
> > different VMs.
> > 
> > However, the APU mailbox hardware design in MT8196 differs from
> > that
> > of
> > MT8188, and in MT8196, Linux has full access to the APU mailbox.
> > 
> > Given that this patch is primarily for the MT8196 platform, we will
> > remove the above comment in the next version of the patch.
> > 
> > Thanks for your asking.
> > 
> > Karl
> > 
> > > > 
> > > > > +????? */
> > > > > +???? mbox->controller.num_chans = 1;
> > > > > +???? mbox->controller.chans = devm_kcalloc(dev, mbox-
> > > > > > controller.num_chans,
> > > > > +?????????????????????????????????????????? sizeof(*mbox-
> > > > > > controller.chans),
> > > > > +?????????????????????????????????????????? GFP_KERNEL);
> > > > > +???? if (!mbox->controller.chans)
> > > > > +???????????? return -ENOMEM;
> > > > > +
> > > > > +???? ret = devm_mbox_controller_register(dev, &mbox-
> > > > > > controller);
> > > > > +???? if (ret)
> > > > > +???????????? return ret;
> > > > > +
> > > > > +???? irq = platform_get_irq(pdev, 0);
> > > > > +???? if (irq < 0)
> > > > > +???????????? return irq;
> > > > > +
> > > > > +???? ret = devm_request_threaded_irq(dev, irq,
> > > > > mtk_apu_mailbox_irq_top_half,
> > > > > +????????????????????????????????????
> > > > > mtk_apu_mailbox_irq_btm_half, IRQF_ONESHOT,
> > > > > +???????????????????????????????????? dev_name(dev), mbox);
> > > > 
> > > > pass mbox->chans to the isr
> > > > 
> > > > > +???? if (ret)
> > > > > +???????????? return dev_err_probe(dev, ret, "Failed to
> > > > > request
> > > > > IRQ\n");
> > > > > +
> > > > > +???? g_mbox = mbox;
> > > > > +
> > > > > +???? dev_dbg(dev, "registered mtk apu mailbox\n");
> > > > > +
> > > > > +???? return 0;
> > > > > +}
> > > > > +
> > > > > +static void mtk_apu_mailbox_remove(struct platform_device
> > > > > *pdev)
> > > > > +{
> > > > > +???? g_mbox = NULL;
> > > > > +}
> > > > > +
> > > > > +static const struct of_device_id mtk_apu_mailbox_of_match[]
> > > > > =
> > > > > {
> > > > > +???? { .compatible = "mediatek,mt8188-apu-mailbox" },
> > > > > +???? { .compatible = "mediatek,mt8196-apu-mailbox" },
> > > > 
> > > > Just mediatek,mt8188-apu-mailbox is fine; you can allow
> > > > mt8196==mt8188 in the
> > > > binding instead.
> > > > 
> > > > > +???? {}
> > > > > +};
> > > > > +MODULE_DEVICE_TABLE(of, mtk_apu_mailbox_of_match);
> > > > > +
> > > > > +static struct platform_driver mtk_apu_mailbox_driver = {
> > > > > +???? .probe = mtk_apu_mailbox_probe,
> > > > > +???? .remove = mtk_apu_mailbox_remove,
> > > > 
> > > > You don't need this remove callback, since g_mbox has to
> > > > disappear
> > > > :-)
> > > > 
> > > > > +???? .driver = {
> > > > > +???????????? .name = "mtk-apu-mailbox",
> > > > > +???????????? .of_match_table = mtk_apu_mailbox_of_match,
> > > > > +???? },
> > > > > +};
> > > > > +
> > > > > +module_platform_driver(mtk_apu_mailbox_driver);
> > > > > +MODULE_LICENSE("GPL");
> > > > > +MODULE_DESCRIPTION("MediaTek APU Mailbox Driver");
> > > > > diff --git a/include/linux/mailbox/mtk-apu-mailbox.h
> > > > > b/include/linux/mailbox/mtk-apu-mailbox.h
> > > > > new file mode 100644
> > > > > index 000000000000..d1457d16ce9b
> > > > > --- /dev/null
> > > > > +++ b/include/linux/mailbox/mtk-apu-mailbox.h
> > > > > @@ -0,0 +1,20 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > +/*
> > > > > + * Copyright (c) 2024 MediaTek Inc.
> > > > > + *
> > > > > + */
> > > > > +
> > > > > +#ifndef __MTK_APU_MAILBOX_H__
> > > > > +#define __MTK_APU_MAILBOX_H__
> > > > > +
> > > > > +#define MSG_MBOX_SLOTS?????? (8)
> > > > > +
> > > > > +struct mtk_apu_mailbox_msg {
> > > > > +???? int send_cnt;
> > > > 
> > > > u8 data_cnt;
> > > > 
> > > > > +???? u32 data[MSG_MBOX_SLOTS];
> > > > 
> > > > With hardcoded slots, what happens when we get a new chip in
> > > > the
> > > > future that
> > > > supports more slots?
> > > 
> > > Seems like we can make it a flexible array member? But the
> > > problem
> > > then
> > > becomes how does the client know what the maximum length is. Or
> > > maybe
> > > it should already know given it's tied to a particular platform.
> > > 
> > > In any case it becomes:
> > > 
> > > ??? struct mtk_apu_mailbox_msg {
> > > ??????? u8 data_size;
> > > ??????? u8 data[] __counted_by(data_size);
> > > ??? };
> > > 
> > > This can't be allocated on the stack if `data_size` isn't a
> > > compile
> > > time constant though; but again it shouldn't be a problem given
> > > the
> > > message size is tied to the client & its platform and should be
> > > constant anyway.
> > > 
> > > The controller should just error out if the message is larger
> > > than
> > > what it can atomically send.
> > > 
> > > 
> > > ChenYu
> > > 
> > > > Please think about this now and make the implementation
> > > > flexible
> > > > before that
> > > > happens because, at a later time, it'll be harder.
> > > > 
> > > > Regards,
> > > > Angelo
> > > > 
> > > > > +};
> > > > > +
> > > > > +int mtk_apu_mbox_write(u32 val, u32 offset);
> > > > > +int mtk_apu_mbox_read(u32 offset, u32 *val);
> > > > > +
> > > > > +#endif /* __MTK_APU_MAILBOX_H__ */
> > > > 
> > > > 
> > 
> 


From andre.draszik at linaro.org  Wed Dec  4 23:33:11 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 07:33:11 +0000
Subject: [PATCH v3 0/8] USB31DRD phy updates for Google Tensor gs101
 (orientation & DWC3 rpm)
Message-ID: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>

Hi,

This series enables USB3 Type-C lane orientation detection and
configuration on platforms that support this (Google gs101), and it
also allows the DWC3 core to enter runtime suspend even when UDC is
active.

For lane orientation, this driver now optionally (based on DT)
subscribes to the TCPC's lane orientation notifier and remembers the
orientation to later be used during phy_init().

To enable DWC3 runtime suspend, the gadget needs to inform the core via
dwc3_gadget_interrupt() with event type == DWC3_DEVICE_EVENT_DISCONNECT
of a cable disconnect. For that to allow to happen, this driver
therefore needs to stop forcing the Vbus and bvalid signals to active
and instead change their state based on actual conditions. The same
TCPC notifier is used to detect this, and program the hardware
accordingly.

That signal state is based on advice given by Thinh in
https://lore.kernel.org/all/20240813230625.jgkatqstyhcmpezv at synopsys.com/

Both changes together now allow cable orientation detection to work, as
the DWC3 will now call phy_exit() on cable disconnect, and we can
reprogram the lane mux in phy_init().

On top of that, there are some small related cleanup patches.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
Changes in v3:
- patches 1 & 2: update as per Rob's suggestions
- patch 7 & 8: drop init to -1 of phy_drd->orientation (Vinod)
- patch 7: avoid an #ifdef 
- Link to v2: https://lore.kernel.org/r/20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d at linaro.org

Changes in v2:
- squash patches #2 and #3 from v1 to actually disallow
  orientation-switch on !gs101 (not just optional) (Conor)
- update bindings commit message to clarify that the intention for the
  driver is to work with old and new DTS (Conor)
- add cc-stable and fixes tags to power gating patch (Krzysztof)
- fix an #include and typo (Peter)
- Link to v1: https://lore.kernel.org/r/20241127-gs101-phy-lanes-orientation-phy-v1-0-1b7fce24960b at linaro.org

---
Andr? Draszik (8):
      dt-bindings: phy: samsung,usb3-drd-phy: add blank lines between DT properties
      dt-bindings: phy: samsung,usb3-drd-phy: gs101: require Type-C properties
      phy: exynos5-usbdrd: convert to dev_err_probe
      phy: exynos5-usbdrd: fix EDS distribution tuning (gs101)
      phy: exynos5-usbdrd: gs101: ensure power is gated to SS phy in phy_exit()
      phy: exynos5-usbdrd: gs101: configure SS lanes based on orientation
      phy: exynos5-usbdrd: subscribe to orientation notifier if required
      phy: exynos5-usbdrd: allow DWC3 runtime suspend with UDC bound (E850+)

 .../bindings/phy/samsung,usb3-drd-phy.yaml         |  21 +-
 drivers/phy/samsung/Kconfig                        |   1 +
 drivers/phy/samsung/phy-exynos5-usbdrd.c           | 215 ++++++++++++++++-----
 3 files changed, 190 insertions(+), 47 deletions(-)
---
base-commit: c245a7a79602ccbee780c004c1e4abcda66aec32
change-id: 20241127-gs101-phy-lanes-orientation-phy-29d20c6d84d2

Best regards,
-- 
Andr? Draszik <andre.draszik at linaro.org>



From andre.draszik at linaro.org  Wed Dec  4 23:33:13 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 07:33:13 +0000
Subject: [PATCH v3 2/8] dt-bindings: phy: samsung,usb3-drd-phy: gs101:
 require Type-C properties
In-Reply-To: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
Message-ID: <20241205-gs101-phy-lanes-orientation-phy-v3-2-32f721bed219@linaro.org>

orientation-switch is the standard declaration to inform the Type-C mux
layer that a remote-endpoint is capable of processing orientation
change messages.

The USB PHY on gs101 needs to be configured based on the orientation of
the connector. For that the DTS needs a link between the phy's port and
a TCPCi, and we'll need to inform the phy driver that it should handle
the orientation (register a handler).

Update the schema to enforce that by requiring the orientation-switch
and port properties on gs101 (only). We disallow orientation-switch on
all other supported platforms, since other versions of this phy (or its
system integration) don't currently support or even need it.

Even though this new required gs101 property is an ABI break, the
intention for the driver is to behave as before if it's missing
(meaning for gs101 it will work in SS mode in one orientation only).
Other platforms are not affected.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v3:
* update as per Rob's suggestion (I hope :-)

v2:
* squash original patches #2 and #3
* actually disallow orientation-switch on !gs101 (not just optional) (Conor)
* update commit message to clarify that the intention for the driver is
  to work with old and new DTS (Conor)
* collect tags

foo
---
 Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index 1f8b35917b11..27295acbba76 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -114,6 +114,8 @@ allOf:
           contains:
             const: google,gs101-usb31drd-phy
     then:
+      $ref: /schemas/usb/usb-switch.yaml#
+
       properties:
         clocks:
           items:
@@ -139,6 +141,8 @@ allOf:
 
       required:
         - reg-names
+        - orientation-switch
+        - port
         - pll-supply
         - dvdd-usb20-supply
         - vddh-usb20-supply
@@ -198,7 +202,7 @@ allOf:
         reg-names:
           maxItems: 1
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Wed Dec  4 23:33:12 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 07:33:12 +0000
Subject: [PATCH v3 1/8] dt-bindings: phy: samsung,usb3-drd-phy: add blank
 lines between DT properties
In-Reply-To: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
Message-ID: <20241205-gs101-phy-lanes-orientation-phy-v3-1-32f721bed219@linaro.org>

In [1], Rob pointed out that we should really be separating properties
with blank lines in between, which is universal style. Only where
properties are booleans, empty lines are not required.

Do so.

Link: https://lore.kernel.org/all/20240711212359.GA3023490-robh at kernel.org/ [1]
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v3:
* update subject line (Rob)
* collect tags

v2:
* collect tags
---
 .../devicetree/bindings/phy/samsung,usb3-drd-phy.yaml     | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index 16321cdd4919..1f8b35917b11 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -83,14 +83,19 @@ properties:
 
   pll-supply:
     description: Power supply for the USB PLL.
+
   dvdd-usb20-supply:
     description: DVDD power supply for the USB 2.0 phy.
+
   vddh-usb20-supply:
     description: VDDh power supply for the USB 2.0 phy.
+
   vdd33-usb20-supply:
     description: 3.3V power supply for the USB 2.0 phy.
+
   vdda-usbdp-supply:
     description: VDDa power supply for the USB DP phy.
+
   vddh-usbdp-supply:
     description: VDDh power supply for the USB DP phy.
 
@@ -117,6 +122,7 @@ allOf:
             - description: Gate of control interface AXI clock
             - description: Gate of control interface APB clock
             - description: Gate of SCL APB clock
+
         clock-names:
           items:
             - const: phy
@@ -124,10 +130,13 @@ allOf:
             - const: ctrl_aclk
             - const: ctrl_pclk
             - const: scl_pclk
+
         reg:
           minItems: 3
+
         reg-names:
           minItems: 3
+
       required:
         - reg-names
         - pll-supply
@@ -149,6 +158,7 @@ allOf:
         clocks:
           minItems: 5
           maxItems: 5
+
         clock-names:
           items:
             - const: phy
@@ -156,8 +166,10 @@ allOf:
             - const: phy_utmi
             - const: phy_pipe
             - const: itp
+
         reg:
           maxItems: 1
+
         reg-names:
           maxItems: 1
 
@@ -174,12 +186,15 @@ allOf:
         clocks:
           minItems: 2
           maxItems: 2
+
         clock-names:
           items:
             - const: phy
             - const: ref
+
         reg:
           maxItems: 1
+
         reg-names:
           maxItems: 1
 

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Wed Dec  4 23:33:14 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 07:33:14 +0000
Subject: [PATCH v3 3/8] phy: exynos5-usbdrd: convert to dev_err_probe
In-Reply-To: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
Message-ID: <20241205-gs101-phy-lanes-orientation-phy-v3-3-32f721bed219@linaro.org>

dev_err_probe() exists to simplify code.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index c421b495eb0f..ceae4b47cece 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1725,10 +1725,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 
 	reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node,
 						   "samsung,pmu-syscon");
-	if (IS_ERR(reg_pmu)) {
-		dev_err(dev, "Failed to lookup PMU regmap\n");
-		return PTR_ERR(reg_pmu);
-	}
+	if (IS_ERR(reg_pmu))
+		return dev_err_probe(dev, PTR_ERR(reg_pmu),
+				     "Failed to lookup PMU regmap\n");
 
 	/*
 	 * Exynos5420 SoC has multiple channels for USB 3.0 PHY, with
@@ -1759,10 +1758,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 	for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {
 		struct phy *phy = devm_phy_create(dev, NULL, drv_data->phy_ops);
 
-		if (IS_ERR(phy)) {
-			dev_err(dev, "Failed to create usbdrd_phy phy\n");
-			return PTR_ERR(phy);
-		}
+		if (IS_ERR(phy))
+			return dev_err_probe(dev, PTR_ERR(phy),
+					     "Failed to create usbdrd_phy phy\n");
 
 		phy_drd->phys[i].phy = phy;
 		phy_drd->phys[i].index = i;
@@ -1786,10 +1784,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 
 	phy_provider = devm_of_phy_provider_register(dev,
 						     exynos5_usbdrd_phy_xlate);
-	if (IS_ERR(phy_provider)) {
-		dev_err(phy_drd->dev, "Failed to register phy provider\n");
-		return PTR_ERR(phy_provider);
-	}
+	if (IS_ERR(phy_provider))
+		return dev_err_probe(phy_drd->dev, PTR_ERR(phy_provider),
+				     "Failed to register phy provider\n");
 
 	return 0;
 }

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Wed Dec  4 23:33:19 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 07:33:19 +0000
Subject: [PATCH v3 8/8] phy: exynos5-usbdrd: allow DWC3 runtime suspend
 with UDC bound (E850+)
In-Reply-To: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
Message-ID: <20241205-gs101-phy-lanes-orientation-phy-v3-8-32f721bed219@linaro.org>

To make USB runtime suspend work when a UDC has been bound, the phy
needs to inform the USBDRD controller (DWC3) that Vbus and bvalid are
gone, so that it can in turn raise the respective gadget interrupt with
event == DWC3_DEVICE_EVENT_DISCONNECT, which will cause the USB stack
to clean up, allowing DWC3 to enter runtime suspend.

On e850 and gs101 this isn't working, as the respective signals are not
directly connected, and instead this driver uses override bits in the
PHY IP to set those signals. It currently forcefully sets them to 'on',
so the above mentioned interrupt will not be raised, preventing runtime
suspend.

To detect that state, update this driver to act on the TCPC's
orientation signal - when orientation == NONE, Vbus is gone and we can
clear the respective bits. Similarly, for other orientation values we
re-enable them.

This makes runtime suspend work on platforms with a TCPC (like Pixel6),
while keeping compatibility with platforms without (e850-96).

With runtime suspend working, USB-C cable orientation detection now
also fully works on such platforms, and the link comes up as Superspeed
as expected irrespective of the cable orientation and whether UDC /
gadget are configured and active.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v3:
* update exynos5_usbdrd_orien_sw_set() to not test against previous
  orientation
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 50 +++++++++++++++++++++++++++-----
 1 file changed, 42 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 6dcc3c80c1d2..ae42e299ba42 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1137,13 +1137,15 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
 	reg |= LINKCTRL_BUS_FILTER_BYPASS(0xf);
 	writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL);
 
-	reg = readl(regs_base + EXYNOS850_DRD_UTMI);
-	reg |= UTMI_FORCE_BVALID | UTMI_FORCE_VBUSVALID;
-	writel(reg, regs_base + EXYNOS850_DRD_UTMI);
-
-	reg = readl(regs_base + EXYNOS850_DRD_HSP);
-	reg |= HSP_VBUSVLDEXT | HSP_VBUSVLDEXTSEL;
-	writel(reg, regs_base + EXYNOS850_DRD_HSP);
+	if (!phy_drd->sw) {
+		reg = readl(regs_base + EXYNOS850_DRD_UTMI);
+		reg |= UTMI_FORCE_BVALID | UTMI_FORCE_VBUSVALID;
+		writel(reg, regs_base + EXYNOS850_DRD_UTMI);
+
+		reg = readl(regs_base + EXYNOS850_DRD_HSP);
+		reg |= HSP_VBUSVLDEXT | HSP_VBUSVLDEXTSEL;
+		writel(reg, regs_base + EXYNOS850_DRD_HSP);
+	}
 
 	reg = readl(regs_base + EXYNOS850_DRD_SSPPLLCTL);
 	reg &= ~SSPPLLCTL_FSEL;
@@ -1407,9 +1409,41 @@ static int exynos5_usbdrd_orien_sw_set(struct typec_switch_dev *sw,
 				       enum typec_orientation orientation)
 {
 	struct exynos5_usbdrd_phy *phy_drd = typec_switch_get_drvdata(sw);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret) {
+		dev_err(phy_drd->dev, "Failed to enable PHY clocks(s)\n");
+		return ret;
+	}
+
+	scoped_guard(mutex, &phy_drd->phy_mutex) {
+		void __iomem * const regs_base = phy_drd->reg_phy;
+		unsigned int reg;
+
+		if (orientation == TYPEC_ORIENTATION_NONE) {
+			reg = readl(regs_base + EXYNOS850_DRD_UTMI);
+			reg &= ~(UTMI_FORCE_VBUSVALID | UTMI_FORCE_BVALID);
+			writel(reg, regs_base +  EXYNOS850_DRD_UTMI);
+
+			reg = readl(regs_base + EXYNOS850_DRD_HSP);
+			reg |= HSP_VBUSVLDEXTSEL;
+			reg &= ~HSP_VBUSVLDEXT;
+			writel(reg, regs_base + EXYNOS850_DRD_HSP);
+		} else {
+			reg = readl(regs_base + EXYNOS850_DRD_UTMI);
+			reg |= UTMI_FORCE_VBUSVALID | UTMI_FORCE_BVALID;
+			writel(reg, regs_base +  EXYNOS850_DRD_UTMI);
+
+			reg = readl(regs_base + EXYNOS850_DRD_HSP);
+			reg |= HSP_VBUSVLDEXTSEL | HSP_VBUSVLDEXT;
+			writel(reg, regs_base + EXYNOS850_DRD_HSP);
+		}
 
-	scoped_guard(mutex, &phy_drd->phy_mutex)
 		phy_drd->orientation = orientation;
+	}
+
+	clk_bulk_disable(phy_drd->drv_data->n_clks, phy_drd->clks);
 
 	return 0;
 }

-- 
2.47.0.338.g60cca15819-goog



From krzk at kernel.org  Wed Dec  4 23:35:08 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 08:35:08 +0100
Subject: [PATCH v5 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <1DBA844B-4DB2-4AA2-BF04-B3CC39B3C3F8@public-files.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-4-linux@fw-web.de>
 <iwmnxlqpaijvr4kmzwk3elacqj5ukqlchfs67ca6c6gxrycpbb@pc6a6scqkdi5>
 <1DBA844B-4DB2-4AA2-BF04-B3CC39B3C3F8@public-files.de>
Message-ID: <6ebd58fd-8461-476c-9266-a21455d5e819@kernel.org>

On 04/12/2024 08:41, Frank Wunderlich wrote:
> Am 4. Dezember 2024 08:35:37 MEZ schrieb Krzysztof Kozlowski <krzk at kernel.org>:
>> On Mon, Dec 02, 2024 at 12:00:37PM +0100, Frank Wunderlich wrote:
>>> From: Frank Wunderlich <frank-w at public-files.de>
>>>
>>> This adds bindings for MT7988 pinctrl driver.
>>>
>>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>>> ---
>>> changes in v5 (so not adding RB from Rob given in v4):
>>> - do not use MTK_DRIVE_8mA in example
>>> - add _0 functions for pwm
>>>
>>
>> <form letter>
>> 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.
>> </form letter>
> 
> Is this an automatic message? I guess yes...
> 
> I have not added it (robs reviewed-by) from v4 due to changes and explained why in changelog. If i'm wrong please let me know.

Where did you explain the reason of dropping review tag? This has to be
*EXPLICIT* but I only see:

- rebased to 6.13-rc1
- moved dt nodes with mutliple options to BPI-R4 board
- changes suggested by angelo in v4
- changed example in binding and dt node to not using const MTK_DRIVE_8mA


Nothing here suggests even remotely that review tag was dropped. Nothing
suggests that it should be dropped!

Best regards,
Krzysztof


From wens at csie.org  Wed Dec  4 23:39:24 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Thu, 5 Dec 2024 15:39:24 +0800
Subject: [PATCH] arm64: dts: allwinner: h616: rg35xx add missing regulator-ramp-delay
In-Reply-To: <CADomA482XLFNySkjujoPmPCnCrKn+RcppW=SqRqcA2WLMe-mNw@mail.gmail.com>
References: <20241203203824.23306-1-simons.philippe@gmail.com>
 <CAGb2v67Uv3SVQSqox85qt_05aVvX0oCynNRoaN9BA1Nha3eo8w@mail.gmail.com> <CADomA482XLFNySkjujoPmPCnCrKn+RcppW=SqRqcA2WLMe-mNw@mail.gmail.com>
Message-ID: <CAGb2v64YFcEhTYVzTJWTvw7CZ3XF08e7+1jiTg25HN6C1Ny+Jg@mail.gmail.com>

On Thu, Dec 5, 2024 at 3:26?PM Philippe Simons
<simons.philippe at gmail.com> wrote:

Please reply inline.

> Ok I can do that, but the driver (axp20x-regulator.c) is using macros
>  to generate these regulator_desc structs.
>
> So I have two options, create a new macro with the ramp_delay, or
> modify the existing macro, using 0 for the regulators I don't know about.

You can add a new macro with the extra ramp_delay argument, and modify
the existing macro to expand to that with ramp_delay = 0.

ChenYu

> Philippe
>
> On Thu, Dec 5, 2024 at 5:16?AM Chen-Yu Tsai <wens at csie.org> wrote:
> >
> > On Wed, Dec 4, 2024 at 4:38?AM Philippe Simons
> > <simons.philippe at gmail.com> wrote:
> > >
> > > AXP datasheet says that ramp delay is 15.625 us/step,
> > > which is 10mV in our case.
> >
> > (CC-ing Mark for knowledge on regulators)
> >
> > If this is the property of the PMIC, it probably belongs in the driver,
> > in "regulator_desc.ramp_delay".
> >
> > The "regulator-ramp-delay" in the DT can be used to override this
> > if the board has excessive ramp delay due to other design reasons.
> >
> >
> > ChenYu
> >
> > > add missing regulator-ramp-delay to dcdc regulators accordingly
> > >
> > > Signed-off-by: Philippe Simons <simons.philippe at gmail.com>
> > > ---
> > >  .../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts    | 3 +++
> > >  1 file changed, 3 insertions(+)
> > >
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
> > > index 80ccab7b5..b6e76a804 100644
> > > --- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
> > > @@ -238,6 +238,7 @@ reg_dcdc1: dcdc1 {
> > >                                 regulator-always-on;
> > >                                 regulator-min-microvolt = <900000>;
> > >                                 regulator-max-microvolt = <1160000>;
> > > +                               regulator-ramp-delay = <640>;
> > >                                 regulator-name = "vdd-cpu";
> > >                         };
> > >
> > > @@ -245,6 +246,7 @@ reg_dcdc2: dcdc2 {
> > >                                 regulator-always-on;
> > >                                 regulator-min-microvolt = <940000>;
> > >                                 regulator-max-microvolt = <940000>;
> > > +                               regulator-ramp-delay = <640>;
> > >                                 regulator-name = "vdd-gpu-sys";
> > >                         };
> > >
> > > @@ -252,6 +254,7 @@ reg_dcdc3: dcdc3 {
> > >                                 regulator-always-on;
> > >                                 regulator-min-microvolt = <1100000>;
> > >                                 regulator-max-microvolt = <1100000>;
> > > +                               regulator-ramp-delay = <640>;
> > >                                 regulator-name = "vdd-dram";
> > >                         };
> > >
> > > --
> > > 2.47.1
> > >


From krishna.kurapati at oss.qualcomm.com  Thu Dec  5 00:02:29 2024
From: krishna.kurapati at oss.qualcomm.com (Krishna Kurapati)
Date: Thu, 5 Dec 2024 13:32:29 +0530
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint reader
In-Reply-To: <d095ae2a-3f9d-464c-9dc8-a3e73eac6598@oss.qualcomm.com>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com>
 <d095ae2a-3f9d-464c-9dc8-a3e73eac6598@oss.qualcomm.com>
Message-ID: <98b2b88b-9690-44a7-9b22-2f23e6606e82@oss.qualcomm.com>



On 12/3/2024 6:45 PM, Krishna Kurapati wrote:
> 
> 
> On 12/3/2024 3:50 PM, Johan Hovold wrote:
>> [ +CC: Krishna, Thinh and the USB list ]
>>
>> On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
>>> The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
>>> multiport controller on eUSB6. All other ports (including USB 
>>> super-speed
>>> pins) are unused.
>>>
>>> Set it up in the device tree together with the NXP PTN3222 repeater.
>>>
>>> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
>>> ---
>>> ? arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 48 
>>> +++++++++++++++++++++++++++++++
>>> ? 1 file changed, 48 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts 
>>> b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>>> index 39f9d9cdc10d..44942931c18f 100644
>>> --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>>> +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>>> @@ -735,6 +735,26 @@ keyboard at 3a {
>>> ????? };
>>> ? };
>>> +&i2c5 {
>>> +??? clock-frequency = <400000>;
>>> +
>>> +??? status = "okay";
>>> +
>>> +??? eusb6_repeater: redriver at 4f {
>>> +??????? compatible = "nxp,ptn3222";
>>> +??????? reg = <0x4f>;
>>
>> The driver does not currently check that there's actually anything at
>> this address. Did you verify that this is the correct address?
>>
>> (Abel is adding a check to the driver as we speak to catch any such
>> mistakes going forward).
>>
>>> +??????? #phy-cells = <0>;
>>
>> nit: I'd put provider properties like this one last.
>>
>>> +??????? vdd3v3-supply = <&vreg_l13b_3p0>;
>>> +??????? vdd1v8-supply = <&vreg_l4b_1p8>;
>>
>> Sort by supply name?
>>
>>> +??????? reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>;
>>> +
>>> +??????? pinctrl-0 = <&eusb6_reset_n>;
>>> +??????? pinctrl-names = "default";
>>> +??? };
>>> +};
>>> +
>>> ? &i2c8 {
>>> ????? clock-frequency = <400000>;
>>> @@ -1047,6 +1067,14 @@ edp_reg_en: edp-reg-en-state {
>>> ????????? bias-disable;
>>> ????? };
>>> +??? eusb6_reset_n: eusb6-reset-n-state {
>>> +??????? pins = "gpio184";
>>> +??????? function = "gpio";
>>> +??????? drive-strength = <2>;
>>> +??????? bias-disable;
>>> +??????? output-low;
>>
>> I don't think the pin config should assert reset, that should be up to
>> the driver to control.
>>
>>> +??? };
>>> +
>>> ????? hall_int_n_default: hall-int-n-state {
>>> ????????? pins = "gpio92";
>>> ????????? function = "gpio";
>>> @@ -1260,3 +1288,23 @@ &usb_1_ss2_dwc3_hs {
>>> ? &usb_1_ss2_qmpphy_out {
>>> ????? remote-endpoint = <&pmic_glink_ss2_ss_in>;
>>> ? };
>>> +
>>> +&usb_mp {
>>> +??? status = "okay";
>>> +};
>>> +
>>> +&usb_mp_dwc3 {
>>> +??? /* Limit to USB 2.0 and single port */
>>> +??? maximum-speed = "high-speed";
>>> +??? phys = <&usb_mp_hsphy1>;
>>> +??? phy-names = "usb2-1";
>>> +};
>>
>> The dwc3 driver determines (and acts on) the number of ports based on
>> the port interrupts in DT and controller capabilities.
>>
>> I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
>> that would still be there in the SoC (possibly initialised by the boot
>> firmware).
>>
> 
> The DWC3 core driver identifies number of ports based on xHCI registers. 
> The QC Wrapper reads this number via interrupts. But these two values 
> are independent of each other. The core driver uses these values to 
> identify and manipulate phys. Even if only one HS is given in multiport 
> it would be sufficient if the name is "usb2-1". If the others are 
> missing, those phys would be read by driver as NULL and any ops to phys 
> would be NOP.
> 

However do we need to reduce the number of interrupts used in DTS ?
We don't need to give all interrupts as there is only one port present.
We don't want to enable all interrupts when ports are not exposed.

Regards,
Krishna,


From gregkh at linuxfoundation.org  Thu Dec  5 00:04:02 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Thu, 5 Dec 2024 09:04:02 +0100
Subject: [PATCH v3 5/8] phy: exynos5-usbdrd: gs101: ensure power is gated
 to SS phy in phy_exit()
In-Reply-To: <20241205-gs101-phy-lanes-orientation-phy-v3-5-32f721bed219@linaro.org>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
 <20241205-gs101-phy-lanes-orientation-phy-v3-5-32f721bed219@linaro.org>
Message-ID: <2024120528-poker-thinness-6cfb@gregkh>

On Thu, Dec 05, 2024 at 07:33:16AM +0000, Andr? Draszik wrote:
> We currently don't gate the power to the SS phy in phy_exit().
> 
> Shuffle the code slightly to ensure the power is gated to the SS phy as
> well.
> 
> Fixes: 32267c29bc7d ("phy: exynos5-usbdrd: support Exynos USBDRD 3.1 combo phy (HS & SS)")
> CC: stable at vger.kernel.org # 6.11+

Why is a patch 5/8 a stable thing?  If this is such an important bugfix,
it should be sent separately as a 1/1 patch, right?

thanks,

greg k-h


From yassine.ouaissa at allegrodvt.com  Thu Dec  5 00:11:48 2024
From: yassine.ouaissa at allegrodvt.com (Yassine Ouaissa)
Date: Thu, 5 Dec 2024 08:11:48 +0000
Subject: [PATCH] media: allegro-dvt: Moving the current driver to
 subdirectory
In-Reply-To: <Z1CC_PQF8hCzmPoQ@pengutronix.de>
References: <20241202102654.40472-1-yassine.ouaissa@allegrodvt.com>
 <Z02SLI05JhNDtXFn@pengutronix.de>
 <abshbp4blqxasxvf4ibumtfqcr7hytehmhzs2yag3nfpbcl47x@ndjg7al4iysk>
 <Z1CC_PQF8hCzmPoQ@pengutronix.de>
Message-ID: <46tabetrggwplddtssags6eyjcd6x7znaquerjg3z5a63ykle4@z5fqzikwv2o4>

Hi Michael, 

On 04.12.2024 17:27, Michael Tretter wrote:
>Hi Yassine,
>
>On Wed, 04 Dec 2024 14:44:31 +0000, Yassine Ouaissa wrote:
>> On 02.12.2024 11:55, Michael Tretter wrote:
>> > On Mon, 02 Dec 2024 11:26:38 +0100, Yassine Ouaissa wrote:
>> > What kind of conflicts do you encounter or expect? It's kind of
>> > surprising that your driver would conflict with anything in the existing
>> > driver.
>>
>> The current "NOT allegro" driver support only the ZynqMP (ex : ZCU106/ZCU104 ).
>> And the upcoming driver, has support for many platforms.
>
>What are the supported platforms of the new driver? Does your driver
>support ZynqMP, too?
>
The upcoming driver is not using the ZynqMP, it can be used by other
clients including Xilinx. 
>If there are enough similarities between the encoders, I'd happily
>replace parts of the current driver with functionality of the upcoming
>driver or reuse the infrastructure of the new driver.
>

For now, we do have only the decoder (stateful). the encoder is "in
progress". 
We prefer to have a separate driver core for each platform. 
>>
>> > I'd like to see how you plan to integrate your driver, what it looks
>> > like and what conflicts with the existing driver actually occur. Without
>> > that information I don't see the point in moving the driver to a
>> > sub-directory.
>>
>> The upcoming driver is not using the parsing, conversion inside of the
>> driver. Actually the new Gen of ALLEGRO IP does that.
>
>Sorry, I don't understand what you mean by parsing and conversion. Do
>you mean the mailbox messages or the NAL units?
>
>Can you point me to some repository with your upcoming driver? I'd
>really like to know what's coming up to have an informed discussion how
>to structure the directory.
>
>Michael
>

Yassine
>> > >
>> > > Signed-off-by: Yassine Ouaissa <yassine.ouaissa at allegrodvt.com>
>> > > ---
>> > >  MAINTAINERS                                               | 2 +-
>> > >  drivers/media/platform/allegro-dvt/Kconfig                | 4 ++--
>> > >  drivers/media/platform/allegro-dvt/Makefile               | 8 ++------
>> > >  drivers/media/platform/allegro-dvt/zynqmp/Makefile        | 6 ++++++
>> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c    | 0
>> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h    | 0
>> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c    | 0
>> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h    | 0
>> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c    | 0
>> > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h    | 0
>> > >  .../{allegro-core.c => zynqmp/zynqmp-allegro-core.c}      | 2 +-
>> > >  .../{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c}      | 2 +-
>> > >  .../{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h}      | 0
>> > >  13 files changed, 13 insertions(+), 11 deletions(-)
>> > >  create mode 100644 drivers/media/platform/allegro-dvt/zynqmp/Makefile
>> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c (100%)
>> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h (100%)
>> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c (100%)
>> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h (100%)
>> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c (100%)
>> > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h (100%)
>> > >  rename drivers/media/platform/allegro-dvt/{allegro-core.c => zynqmp/zynqmp-allegro-core.c} (99%)
>> > >  rename drivers/media/platform/allegro-dvt/{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c} (99%)
>> > >  rename drivers/media/platform/allegro-dvt/{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h} (100%)
>> > >
>> > > diff --git a/MAINTAINERS b/MAINTAINERS
>> > > index 7292e4a1ddb8..d79efe6f8992 100644
>> > > --- a/MAINTAINERS
>> > > +++ b/MAINTAINERS
>> > > @@ -795,7 +795,7 @@ R:	Pengutronix Kernel Team <kernel at pengutronix.de>
>> > >  L:	linux-media at vger.kernel.org
>> > >  S:	Maintained
>> > >  F:	Documentation/devicetree/bindings/media/allegro,al5e.yaml
>> > > -F:	drivers/media/platform/allegro-dvt/
>> > > +F:	drivers/media/platform/allegro-dvt/zynqmp
>> > >
>> > >  ALLIED VISION ALVIUM CAMERA DRIVER
>> > >  M:	Tommaso Merciai <tomm.merciai at gmail.com>
>> > > diff --git a/drivers/media/platform/allegro-dvt/Kconfig b/drivers/media/platform/allegro-dvt/Kconfig
>> > > index 2182e1277568..9bc7e99788b8 100644
>> > > --- a/drivers/media/platform/allegro-dvt/Kconfig
>> > > +++ b/drivers/media/platform/allegro-dvt/Kconfig
>> > > @@ -2,8 +2,8 @@
>> > >
>> > >  comment "Allegro DVT media platform drivers"
>> > >
>> > > -config VIDEO_ALLEGRO_DVT
>> > > -	tristate "Allegro DVT Video IP Core"
>> > > +config VIDEO_ZYNQMP_ALLEGRO_DVT
>> > > +	tristate "Allegro DVT Video IP Core for ZynqMP"
>> > >  	depends on V4L_MEM2MEM_DRIVERS
>> > >  	depends on VIDEO_DEV
>> > >  	depends on ARCH_ZYNQMP || COMPILE_TEST
>> > > diff --git a/drivers/media/platform/allegro-dvt/Makefile b/drivers/media/platform/allegro-dvt/Makefile
>> > > index 66108a303774..04727c5f7ef4 100644
>> > > --- a/drivers/media/platform/allegro-dvt/Makefile
>> > > +++ b/drivers/media/platform/allegro-dvt/Makefile
>> > > @@ -1,6 +1,2 @@
>> > > -# SPDX-License-Identifier: GPL-2.0
>> > > -
>> > > -allegro-objs := allegro-core.o allegro-mail.o
>> > > -allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
>> > > -
>> > > -obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o
>> > > +# SPDX-License-Identifier: GPL-2.0-only
>> > > +obj-y += zynqmp/
>> > > diff --git a/drivers/media/platform/allegro-dvt/zynqmp/Makefile b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
>> > > new file mode 100644
>> > > index 000000000000..a8ddb9cf93a8
>> > > --- /dev/null
>> > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
>> > > @@ -0,0 +1,6 @@
>> > > +# SPDX-License-Identifier: GPL-2.0
>> > > +
>> > > +zynqmp-allegro-objs := zynqmp-allegro-core.o zynqmp-allegro-mail.o
>> > > +zynqmp-allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
>> > > +
>> > > +obj-$(CONFIG_VIDEO_ZYNQMP_ALLEGRO_DVT) += zynqmp-allegro.o
>> > > diff --git a/drivers/media/platform/allegro-dvt/nal-h264.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
>> > > similarity index 100%
>> > > rename from drivers/media/platform/allegro-dvt/nal-h264.c
>> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
>> > > diff --git a/drivers/media/platform/allegro-dvt/nal-h264.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
>> > > similarity index 100%
>> > > rename from drivers/media/platform/allegro-dvt/nal-h264.h
>> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
>> > > diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
>> > > similarity index 100%
>> > > rename from drivers/media/platform/allegro-dvt/nal-hevc.c
>> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
>> > > diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
>> > > similarity index 100%
>> > > rename from drivers/media/platform/allegro-dvt/nal-hevc.h
>> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
>> > > diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
>> > > similarity index 100%
>> > > rename from drivers/media/platform/allegro-dvt/nal-rbsp.c
>> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
>> > > diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
>> > > similarity index 100%
>> > > rename from drivers/media/platform/allegro-dvt/nal-rbsp.h
>> > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
>> > > diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
>> > > similarity index 99%
>> > > rename from drivers/media/platform/allegro-dvt/allegro-core.c
>> > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
>> > > index e491399afcc9..8895d7755987 100644
>> > > --- a/drivers/media/platform/allegro-dvt/allegro-core.c
>> > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
>> > > @@ -31,7 +31,7 @@
>> > >  #include <media/videobuf2-dma-contig.h>
>> > >  #include <media/videobuf2-v4l2.h>
>> > >
>> > > -#include "allegro-mail.h"
>> > > +#include "zynqmp-allegro-mail.h"
>> > >  #include "nal-h264.h"
>> > >  #include "nal-hevc.h"
>> > >
>> > > diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
>> > > similarity index 99%
>> > > rename from drivers/media/platform/allegro-dvt/allegro-mail.c
>> > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
>> > > index aadc947a77ae..88a98f9e5d00 100644
>> > > --- a/drivers/media/platform/allegro-dvt/allegro-mail.c
>> > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
>> > > @@ -12,7 +12,7 @@
>> > >  #include <linux/string.h>
>> > >  #include <linux/videodev2.h>
>> > >
>> > > -#include "allegro-mail.h"
>> > > +#include "zynqmp-allegro-mail.h"
>> > >
>> > >  const char *msg_type_name(enum mcu_msg_type type)
>> > >  {
>> > > diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.h b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
>> > > similarity index 100%
>> > > rename from drivers/media/platform/allegro-dvt/allegro-mail.h
>> > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
>> > > --
>> > > 2.30.2
>> > >
>> > >


From johan at kernel.org  Thu Dec  5 00:16:03 2024
From: johan at kernel.org (Johan Hovold)
Date: Thu, 5 Dec 2024 09:16:03 +0100
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint reader
In-Reply-To: <98b2b88b-9690-44a7-9b22-2f23e6606e82@oss.qualcomm.com>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com>
 <d095ae2a-3f9d-464c-9dc8-a3e73eac6598@oss.qualcomm.com>
 <98b2b88b-9690-44a7-9b22-2f23e6606e82@oss.qualcomm.com>
Message-ID: <Z1FhQ3OUI0t3k1_q@hovoldconsulting.com>

On Thu, Dec 05, 2024 at 01:32:29PM +0530, Krishna Kurapati wrote:
> On 12/3/2024 6:45 PM, Krishna Kurapati wrote:
> > On 12/3/2024 3:50 PM, Johan Hovold wrote:
> >> On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:

> >>> +&usb_mp_dwc3 {
> >>> +??? /* Limit to USB 2.0 and single port */
> >>> +??? maximum-speed = "high-speed";
> >>> +??? phys = <&usb_mp_hsphy1>;
> >>> +??? phy-names = "usb2-1";
> >>> +};
> >>
> >> The dwc3 driver determines (and acts on) the number of ports based on
> >> the port interrupts in DT and controller capabilities.
> >>
> >> I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
> >> that would still be there in the SoC (possibly initialised by the boot
> >> firmware).
> > 
> > The DWC3 core driver identifies number of ports based on xHCI registers. 
> > The QC Wrapper reads this number via interrupts. But these two values 
> > are independent of each other. The core driver uses these values to 
> > identify and manipulate phys. Even if only one HS is given in multiport 
> > it would be sufficient if the name is "usb2-1". If the others are 
> > missing, those phys would be read by driver as NULL and any ops to phys 
> > would be NOP.

No, the core driver still acts on these ports (to some extent) even if
there is no PHY specified (e.g. updates DWC3_GUSB2PHYCFG on suspend).

And IIRC I even had to specify more than just the fingerprint reader PHY
on the X13s to get it to enumerate. I never had time to fully determine
why this was the case though.

> However do we need to reduce the number of interrupts used in DTS ?
> We don't need to give all interrupts as there is only one port present.
> We don't want to enable all interrupts when ports are not exposed.

No, the interrupts are still there, wired up in the SoC, so we should
not change that.

With runtime PM eventually enabled and working as it should, the OS
should be able to power down any unused ports. And we could also
consider marking some ports as not physically accessible and not
connected as a further hint to the OS that they can be disabled even
sooner.

Johan


From krzk at kernel.org  Thu Dec  5 00:16:49 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 09:16:49 +0100
Subject: [PATCH v5 6/6] MAINTAINER: Add entry for Blaize SoC
In-Reply-To: <20241204-blaize-blzp1600_init_board_support-v5-6-b642bcc49307@blaize.com>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
 <20241204-blaize-blzp1600_init_board_support-v5-6-b642bcc49307@blaize.com>
Message-ID: <h5awakp52e6pxnnfrclhtlhhs3i66twvmqwlf5vmnfwk2xhbwr@marp6wti72ti>

On Wed, Dec 04, 2024 at 04:05:29PM +0000, Nikolaos Pasaloukos wrote:
> Add MAINTAINERS entry for Blaize SoC platform with a list of
> maintainers.
> 
> Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
> ---
>  MAINTAINERS | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 273a84483b74543b510de7b08804bbd1f6514358..43846a23f9d990ae9fe066e65ed2bdd36376e327 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2238,6 +2238,15 @@ F:	arch/arm64/boot/dts/bitmain/
>  F:	drivers/clk/clk-bm1880.c
>  F:	drivers/pinctrl/pinctrl-bm1880.c
>  
> +ARM/BLAIZE ARCHITECTURE
> +M:	James Cowgill <james.cowgill at blaize.com>
> +M:	Matt Redfearn <matt.redfearn at blaize.com>
> +M:	Neil Jones <neil.jones at blaize.com>
> +M:	Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>

Just to be clear: this is list of active maintainers, so all above are
supposed to perform reviews or maintainer duties. This is not
credits/managers/I-need-to-please-someone list.

With the assumption these are active maintainers:

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

They should also ack it to confirm they understand the burden.

Best regards,
Krzysztof



From kever.yang at rock-chips.com  Thu Dec  5 00:21:07 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Thu, 5 Dec 2024 16:21:07 +0800
Subject: [RESEND PATCH v3 2/2] phy: rockchip-naneng-combo: add rk3576
 support
In-Reply-To: <20241106021357.19782-2-frawang.cn@gmail.com>
References: <20241106021357.19782-1-frawang.cn@gmail.com>
 <20241106021357.19782-2-frawang.cn@gmail.com>
Message-ID: <e853b62f-2ebd-4520-8dea-15d8102f25d8@rock-chips.com>

Hi Frank,

On 2024/11/6 10:13, Frank Wang wrote:
> From: Kever Yang <kever.yang at rock-chips.com>
>
> Rockchip RK3576 integrates two naneng-combo PHY, PHY0 is used for
> PCIE and SATA, PHY1 is used for PCIE, SATA and USB3.
>
> This adds device specific data support.
>
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
> Signed-off-by: William Wu <william.wu at rock-chips.com>
> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
Test on rk3576 evb with pcie port.
Test-by: Kever Yang <kever.yang at rock-chips.com>


Thanks,
- Kever
> ---
> Changelog:
> v3:
>   - add detail commit contents.
>   - using FIELD_PREP() instead of bit shift.
>   - leave a blank line after each switch break case.
>
> v2:
>   - using constants macro instead of magic values.
>   - add more comments for PHY tuning operations.
>
> v1:
>   - https://patchwork.kernel.org/project/linux-phy/patch/20241015013351.4884-2-frawang.cn at gmail.com/
>
>   .../rockchip/phy-rockchip-naneng-combphy.c    | 279 ++++++++++++++++++
>   1 file changed, 279 insertions(+)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> index 0a9989e41237f..eceb798567859 100644
> --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> @@ -37,6 +37,10 @@
>   #define PHYREG8				0x1C
>   #define PHYREG8_SSC_EN			BIT(4)
>   
> +#define PHYREG10			0x24
> +#define PHYREG10_SSC_PCM_MASK		GENMASK(3, 0)
> +#define PHYREG10_SSC_PCM_3500PPM	7
> +
>   #define PHYREG11			0x28
>   #define PHYREG11_SU_TRIM_0_7		0xF0
>   
> @@ -61,17 +65,26 @@
>   #define PHYREG16			0x3C
>   #define PHYREG16_SSC_CNT_VALUE		0x5f
>   
> +#define PHYREG17			0x40
> +
>   #define PHYREG18			0x44
>   #define PHYREG18_PLL_LOOP		0x32
>   
> +#define PHYREG21			0x50
> +#define PHYREG21_RX_SQUELCH_VAL		0x0D
> +
>   #define PHYREG27			0x6C
>   #define PHYREG27_RX_TRIM_RK3588		0x4C
>   
> +#define PHYREG30			0x74
> +
>   #define PHYREG32			0x7C
>   #define PHYREG32_SSC_MASK		GENMASK(7, 4)
> +#define PHYREG32_SSC_DIR_MASK		GENMASK(5, 4)
>   #define PHYREG32_SSC_DIR_SHIFT		4
>   #define PHYREG32_SSC_UPWARD		0
>   #define PHYREG32_SSC_DOWNWARD		1
> +#define PHYREG32_SSC_OFFSET_MASK	GENMASK(7, 6)
>   #define PHYREG32_SSC_OFFSET_SHIFT	6
>   #define PHYREG32_SSC_OFFSET_500PPM	1
>   
> @@ -79,6 +92,7 @@
>   #define PHYREG33_PLL_KVCO_MASK		GENMASK(4, 2)
>   #define PHYREG33_PLL_KVCO_SHIFT		2
>   #define PHYREG33_PLL_KVCO_VALUE		2
> +#define PHYREG33_PLL_KVCO_VALUE_RK3576	4
>   
>   struct rockchip_combphy_priv;
>   
> @@ -98,6 +112,7 @@ struct rockchip_combphy_grfcfg {
>   	struct combphy_reg pipe_rxterm_set;
>   	struct combphy_reg pipe_txelec_set;
>   	struct combphy_reg pipe_txcomp_set;
> +	struct combphy_reg pipe_clk_24m;
>   	struct combphy_reg pipe_clk_25m;
>   	struct combphy_reg pipe_clk_100m;
>   	struct combphy_reg pipe_phymode_sel;
> @@ -584,6 +599,266 @@ static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
>   	.combphy_cfg	= rk3568_combphy_cfg,
>   };
>   
> +static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)
> +{
> +	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
> +	unsigned long rate;
> +	u32 val;
> +
> +	switch (priv->type) {
> +	case PHY_TYPE_PCIE:
> +		/* Set SSC downward spread spectrum */
> +		val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
> +		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
> +
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
> +		break;
> +
> +	case PHY_TYPE_USB3:
> +		/* Set SSC downward spread spectrum */
> +		val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
> +		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
> +
> +		/* Enable adaptive CTLE for USB3.0 Rx */
> +		val = readl(priv->mmio + PHYREG15);
> +		val |= PHYREG15_CTLE_EN;
> +		writel(val, priv->mmio + PHYREG15);
> +
> +		/* Set PLL KVCO fine tuning signals */
> +		rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33);
> +
> +		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
> +		writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
> +
> +		/* Set PLL input clock divider 1/2 */
> +		val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2);
> +		rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6);
> +
> +		/* Set PLL loop divider */
> +		writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
> +
> +		/* Set PLL KVCO to min and set PLL charge pump current to max */
> +		writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
> +
> +		/* Set Rx squelch input filler bandwidth */
> +		writel(PHYREG21_RX_SQUELCH_VAL, priv->mmio + PHYREG21);
> +
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
> +		break;
> +
> +	case PHY_TYPE_SATA:
> +		/* Enable adaptive CTLE for SATA Rx */
> +		val = readl(priv->mmio + PHYREG15);
> +		val |= PHYREG15_CTLE_EN;
> +		writel(val, priv->mmio + PHYREG15);
> +
> +		/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
> +		val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
> +		val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
> +		writel(val, priv->mmio + PHYREG7);
> +
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
> +		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
> +		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
> +		break;
> +
> +	default:
> +		dev_err(priv->dev, "incompatible PHY type\n");
> +		return -EINVAL;
> +	}
> +
> +	rate = clk_get_rate(priv->refclk);
> +
> +	switch (rate) {
> +	case REF_CLOCK_24MHz:
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true);
> +		if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
> +			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
> +			val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE);
> +			rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
> +						 val, PHYREG15);
> +
> +			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
> +		} else if (priv->type == PHY_TYPE_PCIE) {
> +			/* PLL KVCO tuning fine */
> +			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
> +			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> +						 val, PHYREG33);
> +
> +			/* Set up rx_pck invert and rx msb to disable */
> +			writel(0x00, priv->mmio + PHYREG27);
> +
> +			/*
> +			 * Set up SU adjust signal:
> +			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
> +			 * su_trim[15:8],  PLL LPF R1 adujst bits[9:7]=3'b011
> +			 * su_trim[31:24], CKDRV adjust
> +			 */
> +			writel(0x90, priv->mmio + PHYREG11);
> +			writel(0x02, priv->mmio + PHYREG12);
> +			writel(0x57, priv->mmio + PHYREG14);
> +
> +			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
> +		}
> +		break;
> +
> +	case REF_CLOCK_25MHz:
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
> +		break;
> +
> +	case REF_CLOCK_100MHz:
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
> +		if (priv->type == PHY_TYPE_PCIE) {
> +			/* gate_tx_pck_sel length select work for L1SS */
> +			writel(0xc0, priv->mmio + PHYREG30);
> +
> +			/* PLL KVCO tuning fine */
> +			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
> +			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> +						 val, PHYREG33);
> +
> +			/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
> +			writel(0x4c, priv->mmio + PHYREG27);
> +
> +			/*
> +			 * Set up SU adjust signal:
> +			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
> +			 * su_trim[15:8],  bypass PLL loop divider code, and
> +			 *                 PLL LPF R1 adujst bits[9:7]=3'b101
> +			 * su_trim[23:16], CKRCV adjust
> +			 * su_trim[31:24], CKDRV adjust
> +			 */
> +			writel(0x90, priv->mmio + PHYREG11);
> +			writel(0x43, priv->mmio + PHYREG12);
> +			writel(0x88, priv->mmio + PHYREG13);
> +			writel(0x56, priv->mmio + PHYREG14);
> +		} else if (priv->type == PHY_TYPE_SATA) {
> +			/* downward spread spectrum +500ppm */
> +			val = FIELD_PREP(PHYREG32_SSC_DIR_MASK, PHYREG32_SSC_DOWNWARD);
> +			val |= FIELD_PREP(PHYREG32_SSC_OFFSET_MASK, PHYREG32_SSC_OFFSET_500PPM);
> +			rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
> +
> +			/* ssc ppm adjust to 3500ppm */
> +			rockchip_combphy_updatel(priv, PHYREG10_SSC_PCM_MASK,
> +						 PHYREG10_SSC_PCM_3500PPM,
> +						 PHYREG10);
> +		}
> +		break;
> +
> +	default:
> +		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
> +		return -EINVAL;
> +	}
> +
> +	if (priv->ext_refclk) {
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
> +		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
> +			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
> +			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> +						 val, PHYREG33);
> +
> +			/* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */
> +			writel(0x0c, priv->mmio + PHYREG27);
> +
> +			/*
> +			 * Set up SU adjust signal:
> +			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
> +			 * su_trim[15:8],  bypass PLL loop divider code, and
> +			 *                 PLL LPF R1 adujst bits[9:7]=3'b101.
> +			 * su_trim[23:16], CKRCV adjust
> +			 * su_trim[31:24], CKDRV adjust
> +			 */
> +			writel(0x90, priv->mmio + PHYREG11);
> +			writel(0x43, priv->mmio + PHYREG12);
> +			writel(0x88, priv->mmio + PHYREG13);
> +			writel(0x56, priv->mmio + PHYREG14);
> +		}
> +	}
> +
> +	if (priv->enable_ssc) {
> +		val = readl(priv->mmio + PHYREG8);
> +		val |= PHYREG8_SSC_EN;
> +		writel(val, priv->mmio + PHYREG8);
> +
> +		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) {
> +			/* Set PLL loop divider */
> +			writel(0x00, priv->mmio + PHYREG17);
> +			writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
> +
> +			/* Set up rx_pck invert and rx msb to disable */
> +			writel(0x00, priv->mmio + PHYREG27);
> +
> +			/*
> +			 * Set up SU adjust signal:
> +			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
> +			 * su_trim[15:8],  PLL LPF R1 adujst bits[9:7]=3'b101
> +			 * su_trim[23:16], CKRCV adjust
> +			 * su_trim[31:24], CKDRV adjust
> +			 */
> +			writel(0x90, priv->mmio + PHYREG11);
> +			writel(0x02, priv->mmio + PHYREG12);
> +			writel(0x08, priv->mmio + PHYREG13);
> +			writel(0x57, priv->mmio + PHYREG14);
> +			writel(0x40, priv->mmio + PHYREG15);
> +
> +			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
> +
> +			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
> +			writel(val, priv->mmio + PHYREG33);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = {
> +	/* pipe-phy-grf */
> +	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
> +	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
> +	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
> +	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
> +	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
> +	.pipe_clk_24m		= { 0x0004, 14, 13, 0x00, 0x00 },
> +	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
> +	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
> +	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
> +	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
> +	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
> +	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
> +	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
> +	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
> +	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
> +	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
> +	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
> +	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
> +	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
> +	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
> +	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
> +	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
> +	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
> +	/* php-grf */
> +	.pipe_con0_for_sata	= { 0x001C, 2, 0, 0x00, 0x2 },
> +	.pipe_con1_for_sata	= { 0x0020, 2, 0, 0x00, 0x2 },
> +};
> +
> +static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = {
> +	.num_phys = 2,
> +	.phy_ids = {
> +		0x2b050000,
> +		0x2b060000
> +	},
> +	.grfcfg		= &rk3576_combphy_grfcfgs,
> +	.combphy_cfg	= rk3576_combphy_cfg,
> +};
> +
>   static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
>   {
>   	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
> @@ -775,6 +1050,10 @@ static const struct of_device_id rockchip_combphy_of_match[] = {
>   		.compatible = "rockchip,rk3568-naneng-combphy",
>   		.data = &rk3568_combphy_cfgs,
>   	},
> +	{
> +		.compatible = "rockchip,rk3576-naneng-combphy",
> +		.data = &rk3576_combphy_cfgs,
> +	},
>   	{
>   		.compatible = "rockchip,rk3588-naneng-combphy",
>   		.data = &rk3588_combphy_cfgs,


From krishna.kurapati at oss.qualcomm.com  Thu Dec  5 00:22:08 2024
From: krishna.kurapati at oss.qualcomm.com (Krishna Kurapati)
Date: Thu, 5 Dec 2024 13:52:08 +0530
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint reader
In-Reply-To: <Z1FhQ3OUI0t3k1_q@hovoldconsulting.com>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com>
 <d095ae2a-3f9d-464c-9dc8-a3e73eac6598@oss.qualcomm.com>
 <98b2b88b-9690-44a7-9b22-2f23e6606e82@oss.qualcomm.com>
 <Z1FhQ3OUI0t3k1_q@hovoldconsulting.com>
Message-ID: <e6f60ca6-a4d2-4539-ab9b-dabe95dd2d21@oss.qualcomm.com>



On 12/5/2024 1:46 PM, Johan Hovold wrote:
> On Thu, Dec 05, 2024 at 01:32:29PM +0530, Krishna Kurapati wrote:
>> On 12/3/2024 6:45 PM, Krishna Kurapati wrote:
>>> On 12/3/2024 3:50 PM, Johan Hovold wrote:
>>>> On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
> 
>>>>> +&usb_mp_dwc3 {
>>>>> +??? /* Limit to USB 2.0 and single port */
>>>>> +??? maximum-speed = "high-speed";
>>>>> +??? phys = <&usb_mp_hsphy1>;
>>>>> +??? phy-names = "usb2-1";
>>>>> +};
>>>>
>>>> The dwc3 driver determines (and acts on) the number of ports based on
>>>> the port interrupts in DT and controller capabilities.
>>>>
>>>> I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
>>>> that would still be there in the SoC (possibly initialised by the boot
>>>> firmware).
>>>
>>> The DWC3 core driver identifies number of ports based on xHCI registers.
>>> The QC Wrapper reads this number via interrupts. But these two values
>>> are independent of each other. The core driver uses these values to
>>> identify and manipulate phys. Even if only one HS is given in multiport
>>> it would be sufficient if the name is "usb2-1". If the others are
>>> missing, those phys would be read by driver as NULL and any ops to phys
>>> would be NOP.
> 
> No, the core driver still acts on these ports (to some extent) even if
> there is no PHY specified (e.g. updates DWC3_GUSB2PHYCFG on suspend).
> 

Yes, since the port count is obtained from xHCI registers, the 
GUSB2PHYCFG/ GUSB3PIPECTL regs are modified regardless we use the PHYs 
or not but this is still fine. It can be considered a NOP AFAIK.

> And IIRC I even had to specify more than just the fingerprint reader PHY
> on the X13s to get it to enumerate. I never had time to fully determine
> why this was the case though.
> 

This might need to be checked. Did you attempt adding each phy 
individually ? Just incase the first PHY is not the one corresponding to 
the fingerprint reader.

Regards,
Krishna,

>> However do we need to reduce the number of interrupts used in DTS ?
>> We don't need to give all interrupts as there is only one port present.
>> We don't want to enable all interrupts when ports are not exposed.
> 
> No, the interrupts are still there, wired up in the SoC, so we should
> not change that.
> 
> With runtime PM eventually enabled and working as it should, the OS
> should be able to power down any unused ports. And we could also
> consider marking some ports as not physically accessible and not
> connected as a further hint to the OS that they can be disabled even
> sooner.
> 
> Johan


From m-malladi at ti.com  Thu Dec  5 00:24:46 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Thu, 5 Dec 2024 13:54:46 +0530
Subject: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix firmware load sequence.
Message-ID: <20241205082447.777463-1-m-malladi@ti.com>

From: MD Danish Anwar <danishanwar at ti.com>

Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
and SLICE1. Currently whenever any ICSSG interface comes up we load the
respective firmwares to PRU cores and whenever interface goes down, we
stop the resective cores. Due to this, when SLICE0 goes down while
SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
stopped. This results in clock jump for SLICE1 interface as the timesync
related operations are no longer running.

As there are interdependencies between SLICE0 and SLICE1 firmwares,
fix this by running both PRU0 and PRU1 firmwares as long as at least 1
ICSSG interface is up. Add new flag in prueth struct to check if all
firmwares are running.

Use emacs_initialized as reference count to load the firmwares for the
first and last interface up/down. Moving init_emac_mode and fw_offload_mode
API outside of icssg_config to icssg_common_start API as they need
to be called only once per firmware boot.

Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Signed-off-by: Meghana Malladi <m-malladi at ti.com>
---

Hi all,

This patch is based on net-next tagged next-20241128.
v2:https://lore.kernel.org/all/20241128122931.2494446-2-m-malladi at ti.com/

* Changes since v2 (v3-v2):
- error handling in caller function of prueth_emac_common_start()
- Use prus_running flag check before stopping the firmwares
Both suggested by Roger Quadros <rogerq at kernel.org>

 drivers/net/ethernet/ti/icssg/icssg_config.c |  45 ++++--
 drivers/net/ethernet/ti/icssg/icssg_config.h |   1 +
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
 drivers/net/ethernet/ti/icssg/icssg_prueth.h |   5 +
 4 files changed, 140 insertions(+), 68 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
index 5d2491c2943a..342150756cf7 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
@@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
 	return 0;
 }
 
-static void icssg_init_emac_mode(struct prueth *prueth)
+void icssg_init_emac_mode(struct prueth *prueth)
 {
 	/* When the device is configured as a bridge and it is being brought
 	 * back to the emac mode, the host mac address has to be set as 0.
@@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth)
 	int i;
 	u8 mac[ETH_ALEN] = { 0 };
 
-	if (prueth->emacs_initialized)
-		return;
-
 	/* Set VLAN TABLE address base */
 	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
 			   addr <<  SMEM_VLAN_OFFSET);
@@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth)
 	/* Clear host MAC address */
 	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
 }
+EXPORT_SYMBOL_GPL(icssg_init_emac_mode);
 
-static void icssg_init_fw_offload_mode(struct prueth *prueth)
+void icssg_init_fw_offload_mode(struct prueth *prueth)
 {
 	u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET;
 	int i;
 
-	if (prueth->emacs_initialized)
-		return;
-
 	/* Set VLAN TABLE address base */
 	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
 			   addr <<  SMEM_VLAN_OFFSET);
@@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth)
 		icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr);
 	icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST);
 }
+EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode);
 
 int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
 {
@@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
 	struct icssg_flow_cfg __iomem *flow_cfg;
 	int ret;
 
-	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
-		icssg_init_fw_offload_mode(prueth);
-	else
-		icssg_init_emac_mode(prueth);
-
 	memset_io(config, 0, TAS_GATE_MASK_LIST0);
 	icssg_miig_queues_init(prueth, slice);
 
@@ -786,3 +777,31 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port)
 		writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET);
 }
 EXPORT_SYMBOL_GPL(icssg_set_pvid);
+
+int emac_fdb_flow_id_updated(struct prueth_emac *emac)
+{
+	struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
+	int slice = prueth_emac_slice(emac);
+	struct mgmt_cmd fdb_cmd = { 0 };
+	int ret = 0;
+
+	fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
+	fdb_cmd.type   = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
+	fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq);
+	fdb_cmd.param  = 0;
+
+	fdb_cmd.param |= (slice << 4);
+	fdb_cmd.cmd_args[0] = 0;
+
+	ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp);
+
+	if (ret)
+		return ret;
+
+	WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum);
+	if (fdb_cmd_rsp.status == 1)
+		return 0;
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
index 92c2deaa3068..c884e9fa099e 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
@@ -55,6 +55,7 @@ struct icssg_rxq_ctx {
 #define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
 #define ICSSG_FW_MGMT_CMD_TYPE		0x04
 #define ICSSG_FW_MGMT_PKT		0x80000000
+#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW	0x05
 
 struct icssg_r30_cmd {
 	u32 cmd[4];
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index c568c84a032b..2e22e793b01a 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -164,11 +164,11 @@ static struct icssg_firmwares icssg_emac_firmwares[] = {
 	}
 };
 
-static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
+static int prueth_emac_start(struct prueth *prueth, int slice)
 {
 	struct icssg_firmwares *firmwares;
 	struct device *dev = prueth->dev;
-	int slice, ret;
+	int ret;
 
 	if (prueth->is_switch_mode)
 		firmwares = icssg_switch_firmwares;
@@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 	else
 		firmwares = icssg_emac_firmwares;
 
-	slice = prueth_emac_slice(emac);
-	if (slice < 0) {
-		netdev_err(emac->ndev, "invalid port\n");
-		return -EINVAL;
-	}
-
-	ret = icssg_config(prueth, emac, slice);
-	if (ret)
-		return ret;
-
 	ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
 	ret = rproc_boot(prueth->pru[slice]);
 	if (ret) {
@@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 		goto halt_rtu;
 	}
 
-	emac->fw_running = 1;
 	return 0;
 
 halt_rtu:
@@ -220,6 +209,80 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 	return ret;
 }
 
+static int prueth_emac_common_start(struct prueth *prueth)
+{
+	struct prueth_emac *emac;
+	int ret = 0;
+	int slice;
+
+	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
+		return -EINVAL;
+
+	/* clear SMEM and MSMC settings for all slices */
+	memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
+	memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
+
+	icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
+	icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
+
+	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
+		icssg_init_fw_offload_mode(prueth);
+	else
+		icssg_init_emac_mode(prueth);
+
+	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
+		emac = prueth->emac[slice];
+		if (emac) {
+			ret |= icssg_config(prueth, emac, slice);
+			if (ret)
+				return ret;
+		}
+		ret |= prueth_emac_start(prueth, slice);
+	}
+	if (!ret)
+		prueth->prus_running = 1;
+	else
+		return ret;
+
+	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
+	       prueth->emac[ICSS_SLICE1];
+	ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
+			    emac, IEP_DEFAULT_CYCLE_TIME_NS);
+	if (ret) {
+		dev_err(prueth->dev, "Failed to initialize IEP module\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int prueth_emac_common_stop(struct prueth *prueth)
+{
+	struct prueth_emac *emac;
+	int slice;
+
+	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
+		return -EINVAL;
+
+	icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
+	icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
+
+	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
+		if (prueth->prus_running) {
+			rproc_shutdown(prueth->txpru[slice]);
+			rproc_shutdown(prueth->rtu[slice]);
+			rproc_shutdown(prueth->pru[slice]);
+		}
+	}
+	prueth->prus_running = 0;
+
+	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
+	       prueth->emac[ICSS_SLICE1];
+	icss_iep_exit(emac->iep);
+
+	return 0;
+}
+
 /* called back by PHY layer if there is change in link state of hw port*/
 static void emac_adjust_link(struct net_device *ndev)
 {
@@ -369,12 +432,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
 {
 	struct icssg_setclock_desc __iomem *sc_descp;
 	struct prueth_emac *emac = clockops_data;
+	struct prueth *prueth = emac->prueth;
 	struct icssg_setclock_desc sc_desc;
 	u64 cyclecount;
 	u32 cycletime;
 	int timeout;
 
-	if (!emac->fw_running)
+	if (!prueth->prus_running)
 		return;
 
 	sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
@@ -543,23 +607,17 @@ 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;
+	struct icssg_flow_cfg __iomem *flow_cfg;
 	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, false);
 	icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
 
 	/* Notify the stack of the actual queue counts. */
@@ -597,18 +655,23 @@ static int emac_ndo_open(struct net_device *ndev)
 		goto cleanup_napi;
 	}
 
-	/* reset and start PRU firmware */
-	ret = prueth_emac_start(prueth, emac);
-	if (ret)
-		goto free_rx_irq;
+	if (!prueth->emacs_initialized) {
+		ret = prueth_emac_common_start(prueth);
+		if (ret)
+			goto stop;
+	}
 
-	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
+	flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
+	writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
+	ret = emac_fdb_flow_id_updated(emac);
 
-	if (!prueth->emacs_initialized) {
-		ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
-				    emac, IEP_DEFAULT_CYCLE_TIME_NS);
+	if (ret) {
+		netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
+		goto stop;
 	}
 
+	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
+
 	ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
 				   IRQF_ONESHOT, dev_name(dev), emac);
 	if (ret)
@@ -653,8 +716,7 @@ static int emac_ndo_open(struct net_device *ndev)
 free_tx_ts_irq:
 	free_irq(emac->tx_ts_irq, emac);
 stop:
-	prueth_emac_stop(emac);
-free_rx_irq:
+	prueth_emac_common_stop(prueth);
 	free_irq(emac->rx_chns.irq[rx_flow], emac);
 cleanup_napi:
 	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
@@ -689,8 +751,6 @@ static int emac_ndo_stop(struct net_device *ndev)
 	if (ndev->phydev)
 		phy_stop(ndev->phydev);
 
-	icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
-
 	if (emac->prueth->is_hsr_offload_mode)
 		__dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
 	else
@@ -728,11 +788,9 @@ static int emac_ndo_stop(struct net_device *ndev)
 	/* Destroying the queued work in ndo_stop() */
 	cancel_delayed_work_sync(&emac->stats_work);
 
-	if (prueth->emacs_initialized == 1)
-		icss_iep_exit(emac->iep);
-
 	/* stop PRUs */
-	prueth_emac_stop(emac);
+	if (prueth->emacs_initialized == 1)
+		prueth_emac_common_stop(prueth);
 
 	free_irq(emac->tx_ts_irq, emac);
 
@@ -1069,16 +1127,10 @@ static void prueth_emac_restart(struct prueth *prueth)
 	icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
 
 	/* Stop both pru cores for both PRUeth ports*/
-	prueth_emac_stop(emac0);
-	prueth->emacs_initialized--;
-	prueth_emac_stop(emac1);
-	prueth->emacs_initialized--;
+	prueth_emac_common_stop(prueth);
 
 	/* Start both pru cores for both PRUeth ports */
-	prueth_emac_start(prueth, emac0);
-	prueth->emacs_initialized++;
-	prueth_emac_start(prueth, emac1);
-	prueth->emacs_initialized++;
+	prueth_emac_common_start(prueth);
 
 	/* Enable forwarding for both PRUeth ports */
 	icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
@@ -1413,13 +1465,10 @@ static int prueth_probe(struct platform_device *pdev)
 		prueth->pa_stats = NULL;
 	}
 
-	if (eth0_node) {
+	if (eth0_node || eth1_node) {
 		ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
 		if (ret)
 			goto put_cores;
-	}
-
-	if (eth1_node) {
 		ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
 		if (ret)
 			goto put_cores;
@@ -1618,14 +1667,12 @@ static int prueth_probe(struct platform_device *pdev)
 	pruss_put(prueth->pruss);
 
 put_cores:
-	if (eth1_node) {
-		prueth_put_cores(prueth, ICSS_SLICE1);
-		of_node_put(eth1_node);
-	}
-
-	if (eth0_node) {
+	if (eth0_node || eth1_node) {
 		prueth_put_cores(prueth, ICSS_SLICE0);
 		of_node_put(eth0_node);
+
+		prueth_put_cores(prueth, ICSS_SLICE1);
+		of_node_put(eth1_node);
 	}
 
 	return ret;
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index f5c1d473e9f9..b30f2e9a73d8 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -257,6 +257,7 @@ struct icssg_firmwares {
  * @is_switchmode_supported: indicates platform support for switch mode
  * @switch_id: ID for mapping switch ports to bridge
  * @default_vlan: Default VLAN for host
+ * @prus_running: flag to indicate if all pru cores are running
  */
 struct prueth {
 	struct device *dev;
@@ -298,6 +299,7 @@ struct prueth {
 	int default_vlan;
 	/** @vtbl_lock: Lock for vtbl in shared memory */
 	spinlock_t vtbl_lock;
+	bool prus_running;
 };
 
 struct emac_tx_ts_response {
@@ -361,6 +363,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
 			 enum icssg_port_state_cmd state);
 void icssg_config_set_speed(struct prueth_emac *emac);
 void icssg_config_half_duplex(struct prueth_emac *emac);
+void icssg_init_emac_mode(struct prueth *prueth);
+void icssg_init_fw_offload_mode(struct prueth *prueth);
 
 /* Buffer queue helpers */
 int icssg_queue_pop(struct prueth *prueth, u8 queue);
@@ -377,6 +381,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
 		       u8 untag_mask, bool add);
 u16 icssg_get_pvid(struct prueth_emac *emac);
 void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
+int emac_fdb_flow_id_updated(struct prueth_emac *emac);
 #define prueth_napi_to_tx_chn(pnapi) \
 	container_of(pnapi, struct prueth_tx_chn, napi_tx)
 
-- 
2.25.1



From krzk at kernel.org  Thu Dec  5 00:26:16 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 09:26:16 +0100
Subject: [PATCH v7 1/5] media: dt-bindings: Add qcom,sc7280-camss
In-Reply-To: <20241204100003.300123-2-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-2-quic_vikramsa@quicinc.com>
Message-ID: <oko5qqysmxhicqzkwhkz54wvsmt64ba3cd37zkcy55ee77owbk@5z3zetfr2ejx>

On Wed, Dec 04, 2024 at 03:29:59PM +0530, Vikram Sharma wrote:
> Add bindings for qcom,sc7280-camss to support the camera subsystem
> on the SC7280 platform.
> 
> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> ---
>  .../bindings/media/qcom,sc7280-camss.yaml     | 418 ++++++++++++++++++
>  1 file changed, 418 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
> 

...

> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/qcom,camcc-sc7280.h>
> +    #include <dt-bindings/clock/qcom,gcc-sc7280.h>
> +    #include <dt-bindings/interconnect/qcom,sc7280.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/qcom-rpmpd.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        camss at acb3000 {

If there is going to be resend, then node name: isp

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


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

Best regards,
Krzysztof



From m-malladi at ti.com  Thu Dec  5 00:28:31 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Thu, 5 Dec 2024 13:58:31 +0530
Subject: [PATCH net v3 2/2] net: ti: icssg-prueth: Fix clearing of IEP_CMP_CFG registers during iep_init
In-Reply-To: <20241205082831.777868-1-m-malladi@ti.com>
References: <20241205082831.777868-1-m-malladi@ti.com>
Message-ID: <20241205082831.777868-3-m-malladi@ti.com>

When ICSSG interfaces are brought down and brought up again, the
pru cores are shut down and booted again, flushing out all the memories
and start again in a clean state. Hence it is expected that the
IEP_CMP_CFG register needs to be flushed during iep_init() to ensure
that the existing residual configuration doesn't cause any unusual
behavior. If the register is not cleared, existing IEP_CMP_CFG set for
CMP1 will result in SYNC0_OUT signal based on the SYNC_OUT register values.

After bringing the interface up, calling PPS enable doesn't work as
the driver believes PPS is already enabled, (iep->pps_enabled is not
cleared during interface bring down) and driver will just return true
even though there is no signal. Fix this by disabling pps and perout.

Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
Signed-off-by: Meghana Malladi <m-malladi at ti.com>
Reviewed-by: Roger Quadros <rogerq at kernel.org>
---

Hi all,

This patch is based on net-next tagged next-20241128
v2: https://lore.kernel.org/all/20241128122931.2494446-3-m-malladi at ti.com/

* Changes since v2 (v3-v2):
- Collected Reviewed-by tag from Roger Quadros <rogerq at kernel.org>

 drivers/net/ethernet/ti/icssg/icss_iep.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c
index 5d6d1cf78e93..a96861debbe3 100644
--- a/drivers/net/ethernet/ti/icssg/icss_iep.c
+++ b/drivers/net/ethernet/ti/icssg/icss_iep.c
@@ -215,6 +215,10 @@ static void icss_iep_enable_shadow_mode(struct icss_iep *iep)
 	for (cmp = IEP_MIN_CMP; cmp < IEP_MAX_CMP; cmp++) {
 		regmap_update_bits(iep->map, ICSS_IEP_CMP_STAT_REG,
 				   IEP_CMP_STATUS(cmp), IEP_CMP_STATUS(cmp));
+
+		regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
+				   IEP_CMP_CFG_CMP_EN(cmp), 0);
+
 	}
 
 	/* enable reset counter on CMP0 event */
@@ -780,6 +784,11 @@ int icss_iep_exit(struct icss_iep *iep)
 	}
 	icss_iep_disable(iep);
 
+	if (iep->pps_enabled)
+		icss_iep_pps_enable(iep, false);
+	else if (iep->perout_enabled)
+		icss_iep_perout_enable(iep, NULL, false);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(icss_iep_exit);
-- 
2.25.1



From m-malladi at ti.com  Thu Dec  5 00:28:29 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Thu, 5 Dec 2024 13:58:29 +0530
Subject: [PATCH net v3 0/2] IEP clock module bug fixes
Message-ID: <20241205082831.777868-1-m-malladi@ti.com>

Hi All,
This series has some bug fixes for IEP module needed by PPS and
timesync operations.

Patch 1/2 fixes firmware load sequence to run all the firmwares
when either of the ethernet interfaces is up. Move all the code
common for firmware bringup under common functions.

Patch 2/2 fixes distorted PPS signal when the ethernet interfaces
are brough down and up. This patch also fixes enabling PPS signal
after bringing the interface up, without disabling PPS.

MD Danish Anwar (1):
  net: ti: icssg-prueth: Fix firmware load sequence.

Meghana Malladi (1):
  net: ti: icssg-prueth: Fix clearing of IEP_CMP_CFG registers during
    iep_init

 drivers/net/ethernet/ti/icssg/icss_iep.c     |   9 ++
 drivers/net/ethernet/ti/icssg/icssg_config.c |  45 ++++--
 drivers/net/ethernet/ti/icssg/icssg_config.h |   1 +
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
 drivers/net/ethernet/ti/icssg/icssg_prueth.h |   5 +
 5 files changed, 149 insertions(+), 68 deletions(-)


base-commit: dfc14664794a4706e0c2186a0c082386e6b14c4d
-- 
2.25.1



From m-malladi at ti.com  Thu Dec  5 00:28:30 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Thu, 5 Dec 2024 13:58:30 +0530
Subject: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix firmware load sequence.
In-Reply-To: <20241205082831.777868-1-m-malladi@ti.com>
References: <20241205082831.777868-1-m-malladi@ti.com>
Message-ID: <20241205082831.777868-2-m-malladi@ti.com>

From: MD Danish Anwar <danishanwar at ti.com>

Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
and SLICE1. Currently whenever any ICSSG interface comes up we load the
respective firmwares to PRU cores and whenever interface goes down, we
stop the resective cores. Due to this, when SLICE0 goes down while
SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
stopped. This results in clock jump for SLICE1 interface as the timesync
related operations are no longer running.

As there are interdependencies between SLICE0 and SLICE1 firmwares,
fix this by running both PRU0 and PRU1 firmwares as long as at least 1
ICSSG interface is up. Add new flag in prueth struct to check if all
firmwares are running.

Use emacs_initialized as reference count to load the firmwares for the
first and last interface up/down. Moving init_emac_mode and fw_offload_mode
API outside of icssg_config to icssg_common_start API as they need
to be called only once per firmware boot.

Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Signed-off-by: Meghana Malladi <m-malladi at ti.com>
---

Hi all,

This patch is based on net-next tagged next-20241128.
v2:https://lore.kernel.org/all/20241128122931.2494446-2-m-malladi at ti.com/

* Changes since v2 (v3-v2):
- error handling in caller function of prueth_emac_common_start()
- Use prus_running flag check before stopping the firmwares
Both suggested by Roger Quadros <rogerq at kernel.org>

 drivers/net/ethernet/ti/icssg/icssg_config.c |  45 ++++--
 drivers/net/ethernet/ti/icssg/icssg_config.h |   1 +
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
 drivers/net/ethernet/ti/icssg/icssg_prueth.h |   5 +
 4 files changed, 140 insertions(+), 68 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
index 5d2491c2943a..342150756cf7 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
@@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
 	return 0;
 }
 
-static void icssg_init_emac_mode(struct prueth *prueth)
+void icssg_init_emac_mode(struct prueth *prueth)
 {
 	/* When the device is configured as a bridge and it is being brought
 	 * back to the emac mode, the host mac address has to be set as 0.
@@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth)
 	int i;
 	u8 mac[ETH_ALEN] = { 0 };
 
-	if (prueth->emacs_initialized)
-		return;
-
 	/* Set VLAN TABLE address base */
 	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
 			   addr <<  SMEM_VLAN_OFFSET);
@@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth)
 	/* Clear host MAC address */
 	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
 }
+EXPORT_SYMBOL_GPL(icssg_init_emac_mode);
 
-static void icssg_init_fw_offload_mode(struct prueth *prueth)
+void icssg_init_fw_offload_mode(struct prueth *prueth)
 {
 	u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET;
 	int i;
 
-	if (prueth->emacs_initialized)
-		return;
-
 	/* Set VLAN TABLE address base */
 	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
 			   addr <<  SMEM_VLAN_OFFSET);
@@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth)
 		icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr);
 	icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST);
 }
+EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode);
 
 int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
 {
@@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
 	struct icssg_flow_cfg __iomem *flow_cfg;
 	int ret;
 
-	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
-		icssg_init_fw_offload_mode(prueth);
-	else
-		icssg_init_emac_mode(prueth);
-
 	memset_io(config, 0, TAS_GATE_MASK_LIST0);
 	icssg_miig_queues_init(prueth, slice);
 
@@ -786,3 +777,31 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port)
 		writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET);
 }
 EXPORT_SYMBOL_GPL(icssg_set_pvid);
+
+int emac_fdb_flow_id_updated(struct prueth_emac *emac)
+{
+	struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
+	int slice = prueth_emac_slice(emac);
+	struct mgmt_cmd fdb_cmd = { 0 };
+	int ret = 0;
+
+	fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
+	fdb_cmd.type   = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
+	fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq);
+	fdb_cmd.param  = 0;
+
+	fdb_cmd.param |= (slice << 4);
+	fdb_cmd.cmd_args[0] = 0;
+
+	ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp);
+
+	if (ret)
+		return ret;
+
+	WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum);
+	if (fdb_cmd_rsp.status == 1)
+		return 0;
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
index 92c2deaa3068..c884e9fa099e 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
@@ -55,6 +55,7 @@ struct icssg_rxq_ctx {
 #define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
 #define ICSSG_FW_MGMT_CMD_TYPE		0x04
 #define ICSSG_FW_MGMT_PKT		0x80000000
+#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW	0x05
 
 struct icssg_r30_cmd {
 	u32 cmd[4];
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index c568c84a032b..2e22e793b01a 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -164,11 +164,11 @@ static struct icssg_firmwares icssg_emac_firmwares[] = {
 	}
 };
 
-static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
+static int prueth_emac_start(struct prueth *prueth, int slice)
 {
 	struct icssg_firmwares *firmwares;
 	struct device *dev = prueth->dev;
-	int slice, ret;
+	int ret;
 
 	if (prueth->is_switch_mode)
 		firmwares = icssg_switch_firmwares;
@@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 	else
 		firmwares = icssg_emac_firmwares;
 
-	slice = prueth_emac_slice(emac);
-	if (slice < 0) {
-		netdev_err(emac->ndev, "invalid port\n");
-		return -EINVAL;
-	}
-
-	ret = icssg_config(prueth, emac, slice);
-	if (ret)
-		return ret;
-
 	ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
 	ret = rproc_boot(prueth->pru[slice]);
 	if (ret) {
@@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 		goto halt_rtu;
 	}
 
-	emac->fw_running = 1;
 	return 0;
 
 halt_rtu:
@@ -220,6 +209,80 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 	return ret;
 }
 
+static int prueth_emac_common_start(struct prueth *prueth)
+{
+	struct prueth_emac *emac;
+	int ret = 0;
+	int slice;
+
+	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
+		return -EINVAL;
+
+	/* clear SMEM and MSMC settings for all slices */
+	memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
+	memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
+
+	icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
+	icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
+
+	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
+		icssg_init_fw_offload_mode(prueth);
+	else
+		icssg_init_emac_mode(prueth);
+
+	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
+		emac = prueth->emac[slice];
+		if (emac) {
+			ret |= icssg_config(prueth, emac, slice);
+			if (ret)
+				return ret;
+		}
+		ret |= prueth_emac_start(prueth, slice);
+	}
+	if (!ret)
+		prueth->prus_running = 1;
+	else
+		return ret;
+
+	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
+	       prueth->emac[ICSS_SLICE1];
+	ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
+			    emac, IEP_DEFAULT_CYCLE_TIME_NS);
+	if (ret) {
+		dev_err(prueth->dev, "Failed to initialize IEP module\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int prueth_emac_common_stop(struct prueth *prueth)
+{
+	struct prueth_emac *emac;
+	int slice;
+
+	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
+		return -EINVAL;
+
+	icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
+	icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
+
+	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
+		if (prueth->prus_running) {
+			rproc_shutdown(prueth->txpru[slice]);
+			rproc_shutdown(prueth->rtu[slice]);
+			rproc_shutdown(prueth->pru[slice]);
+		}
+	}
+	prueth->prus_running = 0;
+
+	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
+	       prueth->emac[ICSS_SLICE1];
+	icss_iep_exit(emac->iep);
+
+	return 0;
+}
+
 /* called back by PHY layer if there is change in link state of hw port*/
 static void emac_adjust_link(struct net_device *ndev)
 {
@@ -369,12 +432,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
 {
 	struct icssg_setclock_desc __iomem *sc_descp;
 	struct prueth_emac *emac = clockops_data;
+	struct prueth *prueth = emac->prueth;
 	struct icssg_setclock_desc sc_desc;
 	u64 cyclecount;
 	u32 cycletime;
 	int timeout;
 
-	if (!emac->fw_running)
+	if (!prueth->prus_running)
 		return;
 
 	sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
@@ -543,23 +607,17 @@ 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;
+	struct icssg_flow_cfg __iomem *flow_cfg;
 	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, false);
 	icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
 
 	/* Notify the stack of the actual queue counts. */
@@ -597,18 +655,23 @@ static int emac_ndo_open(struct net_device *ndev)
 		goto cleanup_napi;
 	}
 
-	/* reset and start PRU firmware */
-	ret = prueth_emac_start(prueth, emac);
-	if (ret)
-		goto free_rx_irq;
+	if (!prueth->emacs_initialized) {
+		ret = prueth_emac_common_start(prueth);
+		if (ret)
+			goto stop;
+	}
 
-	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
+	flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
+	writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
+	ret = emac_fdb_flow_id_updated(emac);
 
-	if (!prueth->emacs_initialized) {
-		ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
-				    emac, IEP_DEFAULT_CYCLE_TIME_NS);
+	if (ret) {
+		netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
+		goto stop;
 	}
 
+	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
+
 	ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
 				   IRQF_ONESHOT, dev_name(dev), emac);
 	if (ret)
@@ -653,8 +716,7 @@ static int emac_ndo_open(struct net_device *ndev)
 free_tx_ts_irq:
 	free_irq(emac->tx_ts_irq, emac);
 stop:
-	prueth_emac_stop(emac);
-free_rx_irq:
+	prueth_emac_common_stop(prueth);
 	free_irq(emac->rx_chns.irq[rx_flow], emac);
 cleanup_napi:
 	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
@@ -689,8 +751,6 @@ static int emac_ndo_stop(struct net_device *ndev)
 	if (ndev->phydev)
 		phy_stop(ndev->phydev);
 
-	icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
-
 	if (emac->prueth->is_hsr_offload_mode)
 		__dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
 	else
@@ -728,11 +788,9 @@ static int emac_ndo_stop(struct net_device *ndev)
 	/* Destroying the queued work in ndo_stop() */
 	cancel_delayed_work_sync(&emac->stats_work);
 
-	if (prueth->emacs_initialized == 1)
-		icss_iep_exit(emac->iep);
-
 	/* stop PRUs */
-	prueth_emac_stop(emac);
+	if (prueth->emacs_initialized == 1)
+		prueth_emac_common_stop(prueth);
 
 	free_irq(emac->tx_ts_irq, emac);
 
@@ -1069,16 +1127,10 @@ static void prueth_emac_restart(struct prueth *prueth)
 	icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
 
 	/* Stop both pru cores for both PRUeth ports*/
-	prueth_emac_stop(emac0);
-	prueth->emacs_initialized--;
-	prueth_emac_stop(emac1);
-	prueth->emacs_initialized--;
+	prueth_emac_common_stop(prueth);
 
 	/* Start both pru cores for both PRUeth ports */
-	prueth_emac_start(prueth, emac0);
-	prueth->emacs_initialized++;
-	prueth_emac_start(prueth, emac1);
-	prueth->emacs_initialized++;
+	prueth_emac_common_start(prueth);
 
 	/* Enable forwarding for both PRUeth ports */
 	icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
@@ -1413,13 +1465,10 @@ static int prueth_probe(struct platform_device *pdev)
 		prueth->pa_stats = NULL;
 	}
 
-	if (eth0_node) {
+	if (eth0_node || eth1_node) {
 		ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
 		if (ret)
 			goto put_cores;
-	}
-
-	if (eth1_node) {
 		ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
 		if (ret)
 			goto put_cores;
@@ -1618,14 +1667,12 @@ static int prueth_probe(struct platform_device *pdev)
 	pruss_put(prueth->pruss);
 
 put_cores:
-	if (eth1_node) {
-		prueth_put_cores(prueth, ICSS_SLICE1);
-		of_node_put(eth1_node);
-	}
-
-	if (eth0_node) {
+	if (eth0_node || eth1_node) {
 		prueth_put_cores(prueth, ICSS_SLICE0);
 		of_node_put(eth0_node);
+
+		prueth_put_cores(prueth, ICSS_SLICE1);
+		of_node_put(eth1_node);
 	}
 
 	return ret;
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index f5c1d473e9f9..b30f2e9a73d8 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -257,6 +257,7 @@ struct icssg_firmwares {
  * @is_switchmode_supported: indicates platform support for switch mode
  * @switch_id: ID for mapping switch ports to bridge
  * @default_vlan: Default VLAN for host
+ * @prus_running: flag to indicate if all pru cores are running
  */
 struct prueth {
 	struct device *dev;
@@ -298,6 +299,7 @@ struct prueth {
 	int default_vlan;
 	/** @vtbl_lock: Lock for vtbl in shared memory */
 	spinlock_t vtbl_lock;
+	bool prus_running;
 };
 
 struct emac_tx_ts_response {
@@ -361,6 +363,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
 			 enum icssg_port_state_cmd state);
 void icssg_config_set_speed(struct prueth_emac *emac);
 void icssg_config_half_duplex(struct prueth_emac *emac);
+void icssg_init_emac_mode(struct prueth *prueth);
+void icssg_init_fw_offload_mode(struct prueth *prueth);
 
 /* Buffer queue helpers */
 int icssg_queue_pop(struct prueth *prueth, u8 queue);
@@ -377,6 +381,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
 		       u8 untag_mask, bool add);
 u16 icssg_get_pvid(struct prueth_emac *emac);
 void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
+int emac_fdb_flow_id_updated(struct prueth_emac *emac);
 #define prueth_napi_to_tx_chn(pnapi) \
 	container_of(pnapi, struct prueth_tx_chn, napi_tx)
 
-- 
2.25.1



From m-malladi at ti.com  Thu Dec  5 00:30:24 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Thu, 5 Dec 2024 14:00:24 +0530
Subject: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix firmware load
 sequence.
In-Reply-To: <20241205082447.777463-1-m-malladi@ti.com>
References: <20241205082447.777463-1-m-malladi@ti.com>
Message-ID: <d0457446-2b45-44ed-91d4-8839e1626180@ti.com>

Hi All,

Apologies for this mishap (incorrect patch series). Please ignore this 
patch.

On 05/12/24 13:54, Meghana Malladi wrote:
> From: MD Danish Anwar <danishanwar at ti.com>
> 
> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
> and SLICE1. Currently whenever any ICSSG interface comes up we load the
> respective firmwares to PRU cores and whenever interface goes down, we
> stop the resective cores. Due to this, when SLICE0 goes down while
> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
> stopped. This results in clock jump for SLICE1 interface as the timesync
> related operations are no longer running.
> 
> As there are interdependencies between SLICE0 and SLICE1 firmwares,
> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
> ICSSG interface is up. Add new flag in prueth struct to check if all
> firmwares are running.
> 
> Use emacs_initialized as reference count to load the firmwares for the
> first and last interface up/down. Moving init_emac_mode and fw_offload_mode
> API outside of icssg_config to icssg_common_start API as they need
> to be called only once per firmware boot.
> 
> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
> ---
> 
> Hi all,
> 
> This patch is based on net-next tagged next-20241128.
> v2:https://lore.kernel.org/all/20241128122931.2494446-2-m-malladi at ti.com/
> 
> * Changes since v2 (v3-v2):
> - error handling in caller function of prueth_emac_common_start()
> - Use prus_running flag check before stopping the firmwares
> Both suggested by Roger Quadros <rogerq at kernel.org>
> 
>   drivers/net/ethernet/ti/icssg/icssg_config.c |  45 ++++--
>   drivers/net/ethernet/ti/icssg/icssg_config.h |   1 +
>   drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
>   drivers/net/ethernet/ti/icssg/icssg_prueth.h |   5 +
>   4 files changed, 140 insertions(+), 68 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
> index 5d2491c2943a..342150756cf7 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_config.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
> @@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>   	return 0;
>   }
>   
> -static void icssg_init_emac_mode(struct prueth *prueth)
> +void icssg_init_emac_mode(struct prueth *prueth)
>   {
>   	/* When the device is configured as a bridge and it is being brought
>   	 * back to the emac mode, the host mac address has to be set as 0.
> @@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>   	int i;
>   	u8 mac[ETH_ALEN] = { 0 };
>   
> -	if (prueth->emacs_initialized)
> -		return;
> -
>   	/* Set VLAN TABLE address base */
>   	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>   			   addr <<  SMEM_VLAN_OFFSET);
> @@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>   	/* Clear host MAC address */
>   	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
>   }
> +EXPORT_SYMBOL_GPL(icssg_init_emac_mode);
>   
> -static void icssg_init_fw_offload_mode(struct prueth *prueth)
> +void icssg_init_fw_offload_mode(struct prueth *prueth)
>   {
>   	u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET;
>   	int i;
>   
> -	if (prueth->emacs_initialized)
> -		return;
> -
>   	/* Set VLAN TABLE address base */
>   	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>   			   addr <<  SMEM_VLAN_OFFSET);
> @@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth)
>   		icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr);
>   	icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST);
>   }
> +EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode);
>   
>   int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>   {
> @@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>   	struct icssg_flow_cfg __iomem *flow_cfg;
>   	int ret;
>   
> -	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
> -		icssg_init_fw_offload_mode(prueth);
> -	else
> -		icssg_init_emac_mode(prueth);
> -
>   	memset_io(config, 0, TAS_GATE_MASK_LIST0);
>   	icssg_miig_queues_init(prueth, slice);
>   
> @@ -786,3 +777,31 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port)
>   		writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET);
>   }
>   EXPORT_SYMBOL_GPL(icssg_set_pvid);
> +
> +int emac_fdb_flow_id_updated(struct prueth_emac *emac)
> +{
> +	struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
> +	int slice = prueth_emac_slice(emac);
> +	struct mgmt_cmd fdb_cmd = { 0 };
> +	int ret = 0;
> +
> +	fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
> +	fdb_cmd.type   = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
> +	fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq);
> +	fdb_cmd.param  = 0;
> +
> +	fdb_cmd.param |= (slice << 4);
> +	fdb_cmd.cmd_args[0] = 0;
> +
> +	ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp);
> +
> +	if (ret)
> +		return ret;
> +
> +	WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum);
> +	if (fdb_cmd_rsp.status == 1)
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated);
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
> index 92c2deaa3068..c884e9fa099e 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_config.h
> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
> @@ -55,6 +55,7 @@ struct icssg_rxq_ctx {
>   #define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
>   #define ICSSG_FW_MGMT_CMD_TYPE		0x04
>   #define ICSSG_FW_MGMT_PKT		0x80000000
> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW	0x05
>   
>   struct icssg_r30_cmd {
>   	u32 cmd[4];
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> index c568c84a032b..2e22e793b01a 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> @@ -164,11 +164,11 @@ static struct icssg_firmwares icssg_emac_firmwares[] = {
>   	}
>   };
>   
> -static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
> +static int prueth_emac_start(struct prueth *prueth, int slice)
>   {
>   	struct icssg_firmwares *firmwares;
>   	struct device *dev = prueth->dev;
> -	int slice, ret;
> +	int ret;
>   
>   	if (prueth->is_switch_mode)
>   		firmwares = icssg_switch_firmwares;
> @@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>   	else
>   		firmwares = icssg_emac_firmwares;
>   
> -	slice = prueth_emac_slice(emac);
> -	if (slice < 0) {
> -		netdev_err(emac->ndev, "invalid port\n");
> -		return -EINVAL;
> -	}
> -
> -	ret = icssg_config(prueth, emac, slice);
> -	if (ret)
> -		return ret;
> -
>   	ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
>   	ret = rproc_boot(prueth->pru[slice]);
>   	if (ret) {
> @@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>   		goto halt_rtu;
>   	}
>   
> -	emac->fw_running = 1;
>   	return 0;
>   
>   halt_rtu:
> @@ -220,6 +209,80 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>   	return ret;
>   }
>   
> +static int prueth_emac_common_start(struct prueth *prueth)
> +{
> +	struct prueth_emac *emac;
> +	int ret = 0;
> +	int slice;
> +
> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
> +		return -EINVAL;
> +
> +	/* clear SMEM and MSMC settings for all slices */
> +	memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
> +	memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
> +
> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
> +
> +	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
> +		icssg_init_fw_offload_mode(prueth);
> +	else
> +		icssg_init_emac_mode(prueth);
> +
> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
> +		emac = prueth->emac[slice];
> +		if (emac) {
> +			ret |= icssg_config(prueth, emac, slice);
> +			if (ret)
> +				return ret;
> +		}
> +		ret |= prueth_emac_start(prueth, slice);
> +	}
> +	if (!ret)
> +		prueth->prus_running = 1;
> +	else
> +		return ret;
> +
> +	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
> +	       prueth->emac[ICSS_SLICE1];
> +	ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
> +			    emac, IEP_DEFAULT_CYCLE_TIME_NS);
> +	if (ret) {
> +		dev_err(prueth->dev, "Failed to initialize IEP module\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int prueth_emac_common_stop(struct prueth *prueth)
> +{
> +	struct prueth_emac *emac;
> +	int slice;
> +
> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
> +		return -EINVAL;
> +
> +	icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
> +	icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
> +
> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
> +		if (prueth->prus_running) {
> +			rproc_shutdown(prueth->txpru[slice]);
> +			rproc_shutdown(prueth->rtu[slice]);
> +			rproc_shutdown(prueth->pru[slice]);
> +		}
> +	}
> +	prueth->prus_running = 0;
> +
> +	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
> +	       prueth->emac[ICSS_SLICE1];
> +	icss_iep_exit(emac->iep);
> +
> +	return 0;
> +}
> +
>   /* called back by PHY layer if there is change in link state of hw port*/
>   static void emac_adjust_link(struct net_device *ndev)
>   {
> @@ -369,12 +432,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
>   {
>   	struct icssg_setclock_desc __iomem *sc_descp;
>   	struct prueth_emac *emac = clockops_data;
> +	struct prueth *prueth = emac->prueth;
>   	struct icssg_setclock_desc sc_desc;
>   	u64 cyclecount;
>   	u32 cycletime;
>   	int timeout;
>   
> -	if (!emac->fw_running)
> +	if (!prueth->prus_running)
>   		return;
>   
>   	sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
> @@ -543,23 +607,17 @@ 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;
> +	struct icssg_flow_cfg __iomem *flow_cfg;
>   	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, false);
>   	icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
>   
>   	/* Notify the stack of the actual queue counts. */
> @@ -597,18 +655,23 @@ static int emac_ndo_open(struct net_device *ndev)
>   		goto cleanup_napi;
>   	}
>   
> -	/* reset and start PRU firmware */
> -	ret = prueth_emac_start(prueth, emac);
> -	if (ret)
> -		goto free_rx_irq;
> +	if (!prueth->emacs_initialized) {
> +		ret = prueth_emac_common_start(prueth);
> +		if (ret)
> +			goto stop;
> +	}
>   
> -	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
> +	flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
> +	writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
> +	ret = emac_fdb_flow_id_updated(emac);
>   
> -	if (!prueth->emacs_initialized) {
> -		ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
> -				    emac, IEP_DEFAULT_CYCLE_TIME_NS);
> +	if (ret) {
> +		netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
> +		goto stop;
>   	}
>   
> +	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
> +
>   	ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
>   				   IRQF_ONESHOT, dev_name(dev), emac);
>   	if (ret)
> @@ -653,8 +716,7 @@ static int emac_ndo_open(struct net_device *ndev)
>   free_tx_ts_irq:
>   	free_irq(emac->tx_ts_irq, emac);
>   stop:
> -	prueth_emac_stop(emac);
> -free_rx_irq:
> +	prueth_emac_common_stop(prueth);
>   	free_irq(emac->rx_chns.irq[rx_flow], emac);
>   cleanup_napi:
>   	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
> @@ -689,8 +751,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>   	if (ndev->phydev)
>   		phy_stop(ndev->phydev);
>   
> -	icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
> -
>   	if (emac->prueth->is_hsr_offload_mode)
>   		__dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
>   	else
> @@ -728,11 +788,9 @@ static int emac_ndo_stop(struct net_device *ndev)
>   	/* Destroying the queued work in ndo_stop() */
>   	cancel_delayed_work_sync(&emac->stats_work);
>   
> -	if (prueth->emacs_initialized == 1)
> -		icss_iep_exit(emac->iep);
> -
>   	/* stop PRUs */
> -	prueth_emac_stop(emac);
> +	if (prueth->emacs_initialized == 1)
> +		prueth_emac_common_stop(prueth);
>   
>   	free_irq(emac->tx_ts_irq, emac);
>   
> @@ -1069,16 +1127,10 @@ static void prueth_emac_restart(struct prueth *prueth)
>   	icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
>   
>   	/* Stop both pru cores for both PRUeth ports*/
> -	prueth_emac_stop(emac0);
> -	prueth->emacs_initialized--;
> -	prueth_emac_stop(emac1);
> -	prueth->emacs_initialized--;
> +	prueth_emac_common_stop(prueth);
>   
>   	/* Start both pru cores for both PRUeth ports */
> -	prueth_emac_start(prueth, emac0);
> -	prueth->emacs_initialized++;
> -	prueth_emac_start(prueth, emac1);
> -	prueth->emacs_initialized++;
> +	prueth_emac_common_start(prueth);
>   
>   	/* Enable forwarding for both PRUeth ports */
>   	icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
> @@ -1413,13 +1465,10 @@ static int prueth_probe(struct platform_device *pdev)
>   		prueth->pa_stats = NULL;
>   	}
>   
> -	if (eth0_node) {
> +	if (eth0_node || eth1_node) {
>   		ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
>   		if (ret)
>   			goto put_cores;
> -	}
> -
> -	if (eth1_node) {
>   		ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
>   		if (ret)
>   			goto put_cores;
> @@ -1618,14 +1667,12 @@ static int prueth_probe(struct platform_device *pdev)
>   	pruss_put(prueth->pruss);
>   
>   put_cores:
> -	if (eth1_node) {
> -		prueth_put_cores(prueth, ICSS_SLICE1);
> -		of_node_put(eth1_node);
> -	}
> -
> -	if (eth0_node) {
> +	if (eth0_node || eth1_node) {
>   		prueth_put_cores(prueth, ICSS_SLICE0);
>   		of_node_put(eth0_node);
> +
> +		prueth_put_cores(prueth, ICSS_SLICE1);
> +		of_node_put(eth1_node);
>   	}
>   
>   	return ret;
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> index f5c1d473e9f9..b30f2e9a73d8 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> @@ -257,6 +257,7 @@ struct icssg_firmwares {
>    * @is_switchmode_supported: indicates platform support for switch mode
>    * @switch_id: ID for mapping switch ports to bridge
>    * @default_vlan: Default VLAN for host
> + * @prus_running: flag to indicate if all pru cores are running
>    */
>   struct prueth {
>   	struct device *dev;
> @@ -298,6 +299,7 @@ struct prueth {
>   	int default_vlan;
>   	/** @vtbl_lock: Lock for vtbl in shared memory */
>   	spinlock_t vtbl_lock;
> +	bool prus_running;
>   };
>   
>   struct emac_tx_ts_response {
> @@ -361,6 +363,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
>   			 enum icssg_port_state_cmd state);
>   void icssg_config_set_speed(struct prueth_emac *emac);
>   void icssg_config_half_duplex(struct prueth_emac *emac);
> +void icssg_init_emac_mode(struct prueth *prueth);
> +void icssg_init_fw_offload_mode(struct prueth *prueth);
>   
>   /* Buffer queue helpers */
>   int icssg_queue_pop(struct prueth *prueth, u8 queue);
> @@ -377,6 +381,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
>   		       u8 untag_mask, bool add);
>   u16 icssg_get_pvid(struct prueth_emac *emac);
>   void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
> +int emac_fdb_flow_id_updated(struct prueth_emac *emac);
>   #define prueth_napi_to_tx_chn(pnapi) \
>   	container_of(pnapi, struct prueth_tx_chn, napi_tx)
>   


From ukleinek at kernel.org  Thu Dec  5 00:34:32 2024
From: ukleinek at kernel.org (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 5 Dec 2024 09:34:32 +0100
Subject: [PATCH] pwm: stm32-lp: Add check for clk_enable()
In-Reply-To: <20241205051746.2465490-1-zmw12306@gmail.com>
References: <20241205051746.2465490-1-zmw12306@gmail.com>
Message-ID: <geyicxufezkbu7cdvnbgnr2qeuwrn5ubz5ent3spk5biuozxrs@gsqx2chgiiot>

On Thu, Dec 05, 2024 at 12:17:46AM -0500, Mingwei Zheng wrote:
> Add check for the return value of clk_enable() to catch the potential
> error.

Is this something that you actually hit, or just a janitoral fix you
noticed while browsing the code (or reading some checker output)?

> Fixes: e70a540b4e02 ("pwm: Add STM32 LPTimer PWM driver")
> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
> ---
>  drivers/pwm/pwm-stm32-lp.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
> index 989731256f50..4abef304417d 100644
> --- a/drivers/pwm/pwm-stm32-lp.c
> +++ b/drivers/pwm/pwm-stm32-lp.c
> @@ -163,12 +163,16 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
>  	unsigned long rate = clk_get_rate(priv->clk);
>  	u32 val, presc, prd;
>  	u64 tmp;
> +	int ret;

Please move this variable to the block where it's used. No need for such
a big scope.

Otherwise looks fine.

Best regards
Uwe
-------------- 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/20241205/3297cc26/attachment.sig>

From ck.hu at mediatek.com  Thu Dec  5 00:35:53 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 5 Dec 2024 08:35:53 +0000
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
	 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
Message-ID: <ac1c75e310331483235183daff66c849e4ad4ba3.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static u8 mtk_hdmi_get_i2s_ch_mapping(struct mtk_hdmi *hdmi, u8 channel_type)

Parameter hdmi is redundant, so drop it.

Regards,
CK

> +{
> +       switch (channel_type) {
> +       case HDMI_AUD_CHAN_TYPE_1_1:
> +       case HDMI_AUD_CHAN_TYPE_2_1:
> +               return 0x01;
> +       case HDMI_AUD_CHAN_TYPE_3_0:
> +               return 0x02;
> +       case HDMI_AUD_CHAN_TYPE_3_1:
> +               return 0x03;
> +       case HDMI_AUD_CHAN_TYPE_3_0_LRS:
> +       case HDMI_AUD_CHAN_TYPE_4_0:
> +               return 0x08;
> +       case HDMI_AUD_CHAN_TYPE_5_1:
> +               return 0x0b;
> +       case HDMI_AUD_CHAN_TYPE_4_1_CLRS:
> +       case HDMI_AUD_CHAN_TYPE_6_0:
> +       case HDMI_AUD_CHAN_TYPE_6_0_CS:
> +       case HDMI_AUD_CHAN_TYPE_6_0_CH:
> +       case HDMI_AUD_CHAN_TYPE_6_0_OH:
> +       case HDMI_AUD_CHAN_TYPE_6_0_CHR:
> +               return 0x0e;
> +       case HDMI_AUD_CHAN_TYPE_1_0:
> +       case HDMI_AUD_CHAN_TYPE_2_0:
> +       case HDMI_AUD_CHAN_TYPE_3_1_LRS:
> +       case HDMI_AUD_CHAN_TYPE_4_1:
> +       case HDMI_AUD_CHAN_TYPE_5_0:
> +       case HDMI_AUD_CHAN_TYPE_4_0_CLRS:
> +       case HDMI_AUD_CHAN_TYPE_6_1:
> +       case HDMI_AUD_CHAN_TYPE_6_1_CS:
> +       case HDMI_AUD_CHAN_TYPE_6_1_CH:
> +       case HDMI_AUD_CHAN_TYPE_6_1_OH:
> +       case HDMI_AUD_CHAN_TYPE_6_1_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_0:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LH_RH:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LC_RC:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LW_RW:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CS_CH:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CS_OH:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CS_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CH_OH:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CH_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_0_OH_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR:
> +       case HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS:
> +       case HDMI_AUD_CHAN_TYPE_7_1:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LH_RH:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LC_RC:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LW_RW:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CS_CH:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CS_OH:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CS_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CH_OH:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CH_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_1_OH_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR:
> +       default:
> +               return 0;
> +       }
> +
> +       return 0;
> +}
> +



From heiko at sntech.de  Thu Dec  5 00:47:10 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 05 Dec 2024 09:47:10 +0100
Subject: [RESEND PATCH v3 2/2] phy: rockchip-naneng-combo: add rk3576 support
In-Reply-To: <e853b62f-2ebd-4520-8dea-15d8102f25d8@rock-chips.com>
References: <20241106021357.19782-1-frawang.cn@gmail.com>
 <20241106021357.19782-2-frawang.cn@gmail.com>
 <e853b62f-2ebd-4520-8dea-15d8102f25d8@rock-chips.com>
Message-ID: <5541205.29KlJPOoH8@diego>

Hi Kever,

Am Donnerstag, 5. Dezember 2024, 09:21:07 CET schrieb Kever Yang:
> On 2024/11/6 10:13, Frank Wang wrote:
> > From: Kever Yang <kever.yang at rock-chips.com>
> >
> > Rockchip RK3576 integrates two naneng-combo PHY, PHY0 is used for
> > PCIE and SATA, PHY1 is used for PCIE, SATA and USB3.
> >
> > This adds device specific data support.
> >
> > Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
> > Signed-off-by: William Wu <william.wu at rock-chips.com>
> > Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
> Test on rk3576 evb with pcie port.
> Test-by: Kever Yang <kever.yang at rock-chips.com>

nitpick: the tag should be named

Tested-by: Kever Yang <kever.yang at rock-chips.com>






From heiko at sntech.de  Thu Dec  5 00:48:17 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 05 Dec 2024 09:48:17 +0100
Subject: [PATCH] clk: rockchip: add clock ID for CIF0/1 on RK3066
In-Reply-To: <20241205055122.11613-1-val@packett.cool>
References: <20241205055122.11613-1-val@packett.cool>
Message-ID: <5336726.6fTUFtlzNn@diego>

Hi Val,

Am Donnerstag, 5. Dezember 2024, 06:50:46 CET schrieb Val Packett:
> RK3066 does have two "CIF" video capture interface blocks, add their
> corresponding clock IDs so that they could be used.
> 
> Signed-off-by: Val Packett <val at packett.cool>

please split this into two patches
- addition of the clock-ids to the dt-binding header
- setting the clock-ids in the clock driver

Thanks
Heiko

> ---
>  drivers/clk/rockchip/clk-rk3188.c             | 4 ++--
>  include/dt-bindings/clock/rk3188-cru-common.h | 2 ++
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
> index 684233e72105..81e94b338d0f 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -344,7 +344,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
>  
>  	GATE(0, "pclkin_cif0", "ext_cif0", 0,
>  			RK2928_CLKGATE_CON(3), 3, GFLAGS),
> -	INVERTER(0, "pclk_cif0", "pclkin_cif0",
> +	INVERTER(PCLK_CIF0, "pclk_cif0", "pclkin_cif0",
>  			RK2928_CLKSEL_CON(30), 8, IFLAGS),
>  
>  	FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
> @@ -602,7 +602,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
>  
>  	GATE(0, "pclkin_cif1", "ext_cif1", 0,
>  			RK2928_CLKGATE_CON(3), 4, GFLAGS),
> -	INVERTER(0, "pclk_cif1", "pclkin_cif1",
> +	INVERTER(PCLK_CIF1, "pclk_cif1", "pclkin_cif1",
>  			RK2928_CLKSEL_CON(30), 12, IFLAGS),
>  
>  	COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0,
> diff --git a/include/dt-bindings/clock/rk3188-cru-common.h b/include/dt-bindings/clock/rk3188-cru-common.h
> index 01e14ab252a7..dd988cc9d582 100644
> --- a/include/dt-bindings/clock/rk3188-cru-common.h
> +++ b/include/dt-bindings/clock/rk3188-cru-common.h
> @@ -103,6 +103,8 @@
>  #define PCLK_PERI		351
>  #define PCLK_DDRUPCTL		352
>  #define PCLK_PUBL		353
> +#define PCLK_CIF0		354
> +#define PCLK_CIF1		355
>  
>  /* hclk gates */
>  #define HCLK_SDMMC		448
> 






From heiko at sntech.de  Thu Dec  5 00:54:09 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 05 Dec 2024 09:54:09 +0100
Subject: [PATCH v7] rockchip/drm: vop2: add support for gamma LUT
In-Reply-To: <9Rp0NJW2QG5qDduowVaialZWN6xTe9KJFciu7Q2LERJZQXsUgFvMGXfcFaNznIEJEBpZeOdZPuL4fxOEFduaSJLuQJ3cIvN-fx2lEzYSBKE=@proton.me>
References: <20241101185545.559090-3-pZ010001011111@proton.me>
 <9Rp0NJW2QG5qDduowVaialZWN6xTe9KJFciu7Q2LERJZQXsUgFvMGXfcFaNznIEJEBpZeOdZPuL4fxOEFduaSJLuQJ3cIvN-fx2lEzYSBKE=@proton.me>
Message-ID: <12938960.VsHLxoZxqI@diego>

Hi Piotr,

Am Mittwoch, 4. Dezember 2024, 16:45:21 CET schrieb Piotr Zalewski:
> I just noticed that after coming out of suspend gamma LUT is lost and must
> be rewritten by userspace.
> 
> So I guess it will be needed to save LUT to a buffer and rewrite it after
> going out of suspend during modeset?

Most likely ... the old vop does this already too, so I guess you can
get inspiration from there. (gamma_set call in vop_crtc_atomic_enable())

> I checked the patch isn't yet in the "official" linux-next.

The patch is in drm-misc-next:
https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/4f537776340dab2b680a4d8554567f6884240d0b

so should turn up in linux-next at some point. This also means, please
provide a follow-up patch for the suspend handling.

Thanks a lot
Heiko




From shameerali.kolothum.thodi at huawei.com  Thu Dec  5 00:53:52 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Thu, 5 Dec 2024 08:53:52 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <20241204182231.ovvj6rpvcs2f5gv7@altlinux.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck> <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org> <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
 <20241203092721.j473dthkbq6wzez7@altlinux.org>
 <1847e34fa7724d28aeb22d93752f64f2@huawei.com>
 <20241203221453.mwh6sozyczi4ec2k@altlinux.org> <87jzcfsuep.wl-maz@kernel.org>
 <20241204182231.ovvj6rpvcs2f5gv7@altlinux.org>
Message-ID: <156521fbdabb428a805e38c99f8f57c2@huawei.com>



> -----Original Message-----
> From: Vitaly Chikunov <vt at altlinux.org>
> Sent: Wednesday, December 4, 2024 6:35 PM
> To: Marc Zyngier <maz at kernel.org>
> Cc: Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi at huawei.com>; Will Deacon
> <will at kernel.org>; james.morse at arm.com; linux-arm-
> kernel at lists.infradead.org; Catalin Marinas <catalin.marinas at arm.com>;
> linux-kernel at vger.kernel.org; oliver.upton at linux.dev;
> mark.rutland at arm.com; Wangzhou (B) <wangzhou1 at hisilicon.com>; Gleb
> Fotengauer-Malinovskiy <glebfm at altlinux.org>
> Subject: Re: v6.13-rc1: Internal error: Oops - Undefined instruction:
> 0000000002000000 [#1] SMP
> 


> > > > Is there a way you can find out the BIOS version on that board?
> > >
> > > Unfortunately, admins of the server do not provide me with this
> > > info.
> >
> > This doesn't really help, I'm afraid.
> 
> They provided me with this dmicedcode output:
> 
>   Handle 0x0000, DMI type 0, 26 bytes
>   BIOS Information
> 	  Vendor: Huawei Corp.
> 	  Version: 1.25

The information I have from our BIOS team is that you need version 1.70 or above to
support MPAM. 

Thanks,
Shameer


From james.clark at linaro.org  Thu Dec  5 00:54:15 2024
From: james.clark at linaro.org (James Clark)
Date: Thu, 5 Dec 2024 08:54:15 +0000
Subject: [PATCH 6.12 470/826] perf stat: Uniquify event name improvements
In-Reply-To: <f2ada8a7-165b-41fb-8b7b-3c0d16bb8216@leemhuis.info>
References: <20241203144743.428732212@linuxfoundation.org>
 <20241203144802.097952233@linuxfoundation.org>
 <f2ada8a7-165b-41fb-8b7b-3c0d16bb8216@leemhuis.info>
Message-ID: <deb83bf5-2342-479c-b1bd-7f8c49f5b1d4@linaro.org>



On 03/12/2024 5:24 pm, Thorsten Leemhuis wrote:
> On 03.12.24 15:43, Greg Kroah-Hartman wrote:
>> 6.12-stable review patch.  If anyone has any objections, please let me know.
>>
>> ------------------
>>
>> From: Ian Rogers <irogers at google.com>
>>
>> [ Upstream commit 057f8bfc6f7070577523d1e3081081bbf4229c1c ]
>>
>> Without aggregation on Intel:
> 
> My 6.11.y-rc and 6.12.y-rc builds for Fedora failed when building perf.
> I did not bisect, but from a brief look at the error message (see
> below) I suspect it might be caused by this patch, which is the
> second of the patch-set "Event parsing fixes":
> https://lore.kernel.org/all/20240926144851.245903-1-james.clark at linaro.org/
> 
> To my untrained eyes and from a quick look I guess the first patch
> in the series needs to be backported as well:
> perf evsel: Add alternate_hw_config and use in evsel__match
> https://lore.kernel.org/all/20240926144851.245903-2-james.clark at linaro.org/
> 
> This is 22a4db3c36034e ("perf evsel: Add alternate_hw_config
> and use in evsel__match") in mainline. I tried to cherry-pick it
> on-top of 6.12.2-rc1, but there were a few small conflicts.
> 
> Ciao, Thorsten
> 

Yes I imagine both commits are required. Another option is to not 
backport this one. It looks like it's mainly to fix a test, nothing is 
missing or wrong from the output, just the formatting is off.

James

> P.S.: The build error:
> 
>    gcc -Wp,-MD,util/.topdown.o.d -Wp,-MT,util/topdown.o -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wno-system-headers -Wold-style-definition -Wpacked -Wredundant-decls -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wundef -Wwrite-strings -Wformat -Wno-type-limits -Wstrict-aliasing=3 -Wshadow -DHAVE_SYSCALL_TABLE_SUPPORT -Iarch/x86/include/generated -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET -DNDEBUG=1 -O3 -fno-omit-frame-pointer -Wall -Wextra -std=gnu11 -fstack-protector-all -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/util/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/arch/x86/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/include/ -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/arch/x86/include/uapi -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/include/uapi -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/arch/x86/include/ -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/arch/x86/ -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/util -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf -DHAVE_PTHREAD_ATTR_SETAFFINITY_NP -DHAVE_PTHREAD_BARRIER -DHAVE_EVENTFD_SUPPORT -DHAVE_GET_CURRENT_DIR_NAME -DHAVE_GETTID -DHAVE_FILE_HANDLE -DHAVE_DWARF_GETLOCATIONS_SUPPORT -DHAVE_DWARF_CFI_SUPPORT -DHAVE_AIO_SUPPORT -DHAVE_SCANDIRAT_SUPPORT -DHAVE_SCHED_GETCPU_SUPPORT -DHAVE_SETNS_SUPPORT -DHAVE_ZLIB_SUPPORT -DHAVE_LIBELF_SUPPORT -DHAVE_ELF_GETPHDRNUM_SUPPORT -DHAVE_GELF_GETNOTE_SUPPORT -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT -DHAVE_DWARF_SUPPORT -DHAVE_LIBBPF_SUPPORT -DHAVE_SDT_EVENT -DHAVE_JITDUMP -DHAVE_BPF_SKEL -DHAVE_DWARF_UNWIND_SUPPORT -DHAVE_LIBCRYPTO_SUPPORT -DHAVE_SLANG_SUPPORT -DHAVE_LIBPERL_SUPPORT -DHAVE_TIMERFD_SUPPORT -DHAVE_LIBPYTHON_SUPPORT -fPIC -DHAVE_LIBLLVM_SUPPORT -I/usr/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DHAVE_CXA_DEMANGLE_SUPPORT -DHAVE_LZMA_SUPPORT -DHAVE_ZSTD_SUPPORT -DHAVE_BACKTRACE_SUPPORT -DHAVE_LIBNUMA_SUPPORT -DHAVE_KVM_STAT_SUPPORT -DDISASM_FOUR_ARGS_SIGNATURE -DDISASM_INIT_STYLED -DHAVE_LIBBABELTRACE_SUPPORT -DHAVE_AUXTRACE_SUPPORT -DHAVE_JVMTI_CMLR -DHAVE_LIBTRACEEVENT -I/usr/include/traceevent -DLIBTRACEEVENT_VERSION=67067 -I/usr/include/tracefs -I/usr/include/traceevent -DLIBTRACEFS_VERSION=67065 -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libapi/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libsubcmd/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libsymbol/include -I/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/perf/libperf/include -D"BUILD_STR(s)=#s" -c -o util/topdown.o util/topdown.c
> util/stat-display.c: In function ?uniquify_event_name?:
> util/stat-display.c:895:45: error: ?struct evsel? has no member named ?alternate_hw_config?
>    895 |         if (counter->pmu->is_core && counter->alternate_hw_config != PERF_COUNT_HW_MAX)
>        |                                             ^~
> make[4]: *** [/builddir/build/BUILD/kernel-6.12.2-build/kernel-6.12.2-rc1/linux-6.12.2-0.rc1.400.vanilla.fc41.x86_64/tools/build/Makefile.build:106: util/stat-display.o] Error 1
> make[4]: *** Waiting for unfinished jobs....
> 
>> ```
>> $ perf stat -e instructions,cycles ...
>> ```
>> Will use "cycles" for the name of the legacy cycles event but as
>> "instructions" has a sysfs name it will and a "[cpu]" PMU suffix. This
>> often breaks things as the space between the event and the PMU name
>> look like an extra column. The existing uniquify logic was also
>> uniquifying in cases when all events are core and not with uncore
>> events, it was not correctly handling modifiers, etc.
>>
>> Change the logic so that an initial pass that can disable
>> uniquification is run. For individual counters, disable uniquification
>> in more cases such as for consistency with legacy events or for
>> libpfm4 events. Don't use the "[pmu]" style suffix in uniquification,
>> always use "pmu/.../". Change how modifiers/terms are handled in the
>> uniquification so that they look like parse-able events.
>>
>> This fixes "102: perf stat metrics (shadow stat) test:" that has been
>> failing due to "instructions [cpu]" breaking its column/awk logic when
>> values aren't aggregated. This started happening when instructions
>> could match a sysfs rather than a legacy event, so the fixes tag
>> reflects this.
>>
>> Fixes: 617824a7f0f7 ("perf parse-events: Prefer sysfs/JSON hardware events over legacy")
>> Acked-by: Namhyung Kim <namhyung at kernel.org>
>> Signed-off-by: Ian Rogers <irogers at google.com>
>> [ Fix Intel TPEBS counting mode test ]
>> Acked-by: Kan Liang <kan.liang at linux.intel.com>
>> Signed-off-by: James Clark <james.clark at linaro.org>
>> Cc: Yang Jihong <yangjihong at bytedance.com>
>> Cc: Dominique Martinet <asmadeus at codewreck.org>
>> Cc: Colin Ian King <colin.i.king at gmail.com>
>> Cc: Howard Chu <howardchu95 at gmail.com>
>> Cc: Ze Gao <zegao2021 at gmail.com>
>> Cc: Yicong Yang <yangyicong at hisilicon.com>
>> Cc: Weilin Wang <weilin.wang at intel.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mike Leach <mike.leach at linaro.org>
>> Cc: Jing Zhang <renyu.zj at linux.alibaba.com>
>> Cc: Yang Li <yang.lee at linux.alibaba.com>
>> Cc: Leo Yan <leo.yan at linux.dev>
>> Cc: ak at linux.intel.com
>> Cc: Athira Rajeev <atrajeev at linux.vnet.ibm.com>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: Sun Haiyong <sunhaiyong at loongson.cn>
>> Cc: John Garry <john.g.garry at oracle.com>
>> Link: https://lore.kernel.org/r/20240926144851.245903-3-james.clark at linaro.org
>> Signed-off-by: Namhyung Kim <namhyung at kernel.org>
>> Signed-off-by: Sasha Levin <sashal at kernel.org>
>> ---
>>   .../perf/tests/shell/test_stat_intel_tpebs.sh |  11 +-
>>   tools/perf/util/stat-display.c                | 101 ++++++++++++++----
>>   2 files changed, 85 insertions(+), 27 deletions(-)
>>
>> diff --git a/tools/perf/tests/shell/test_stat_intel_tpebs.sh b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
>> index c60b29add9801..9a11f42d153ca 100755
>> --- a/tools/perf/tests/shell/test_stat_intel_tpebs.sh
>> +++ b/tools/perf/tests/shell/test_stat_intel_tpebs.sh
>> @@ -8,12 +8,15 @@ grep -q GenuineIntel /proc/cpuinfo || { echo Skipping non-Intel; exit 2; }
>>   # Use this event for testing because it should exist in all platforms
>>   event=cache-misses:R
>>   
>> +# Hybrid platforms output like "cpu_atom/cache-misses/R", rather than as above
>> +alt_name=/cache-misses/R
>> +
>>   # Without this cmd option, default value or zero is returned
>> -echo "Testing without --record-tpebs"
>> -result=$(perf stat -e "$event" true 2>&1)
>> -[[ "$result" =~ $event ]] || exit 1
>> +#echo "Testing without --record-tpebs"
>> +#result=$(perf stat -e "$event" true 2>&1)
>> +#[[ "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
>>   
>>   # In platforms that do not support TPEBS, it should execute without error.
>>   echo "Testing with --record-tpebs"
>>   result=$(perf stat -e "$event" --record-tpebs -a sleep 0.01 2>&1)
>> -[[ "$result" =~ "perf record" && "$result" =~ $event ]] || exit 1
>> +[[ "$result" =~ "perf record" && "$result" =~ $event || "$result" =~ $alt_name ]] || exit 1
>> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
>> index ea96e4ebad8c8..cbff43ff8d0fb 100644
>> --- a/tools/perf/util/stat-display.c
>> +++ b/tools/perf/util/stat-display.c
>> @@ -871,38 +871,66 @@ static void printout(struct perf_stat_config *config, struct outstate *os,
>>   
>>   static void uniquify_event_name(struct evsel *counter)
>>   {
>> -	char *new_name;
>> -	char *config;
>> -	int ret = 0;
>> +	const char *name, *pmu_name;
>> +	char *new_name, *config;
>> +	int ret;
>>   
>> -	if (counter->uniquified_name || counter->use_config_name ||
>> -	    !counter->pmu_name || !strncmp(evsel__name(counter), counter->pmu_name,
>> -					   strlen(counter->pmu_name)))
>> +	/* The evsel was already uniquified. */
>> +	if (counter->uniquified_name)
>>   		return;
>>   
>> -	config = strchr(counter->name, '/');
>> +	/* Avoid checking to uniquify twice. */
>> +	counter->uniquified_name = true;
>> +
>> +	/* The evsel has a "name=" config term or is from libpfm. */
>> +	if (counter->use_config_name || counter->is_libpfm_event)
>> +		return;
>> +
>> +	/* Legacy no PMU event, don't uniquify. */
>> +	if  (!counter->pmu ||
>> +	     (counter->pmu->type < PERF_TYPE_MAX && counter->pmu->type != PERF_TYPE_RAW))
>> +		return;
>> +
>> +	/* A sysfs or json event replacing a legacy event, don't uniquify. */
>> +	if (counter->pmu->is_core && counter->alternate_hw_config != PERF_COUNT_HW_MAX)
>> +		return;
>> +
>> +	name = evsel__name(counter);
>> +	pmu_name = counter->pmu->name;
>> +	/* Already prefixed by the PMU name. */
>> +	if (!strncmp(name, pmu_name, strlen(pmu_name)))
>> +		return;
>> +
>> +	config = strchr(name, '/');
>>   	if (config) {
>> -		if (asprintf(&new_name,
>> -			     "%s%s", counter->pmu_name, config) > 0) {
>> -			free(counter->name);
>> -			counter->name = new_name;
>> -		}
>> -	} else {
>> -		if (evsel__is_hybrid(counter)) {
>> -			ret = asprintf(&new_name, "%s/%s/",
>> -				       counter->pmu_name, counter->name);
>> +		int len = config - name;
>> +
>> +		if (config[1] == '/') {
>> +			/* case: event// */
>> +			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 2);
>>   		} else {
>> -			ret = asprintf(&new_name, "%s [%s]",
>> -				       counter->name, counter->pmu_name);
>> +			/* case: event/.../ */
>> +			ret = asprintf(&new_name, "%s/%.*s,%s", pmu_name, len, name, config + 1);
>>   		}
>> +	} else {
>> +		config = strchr(name, ':');
>> +		if (config) {
>> +			/* case: event:.. */
>> +			int len = config - name;
>>   
>> -		if (ret) {
>> -			free(counter->name);
>> -			counter->name = new_name;
>> +			ret = asprintf(&new_name, "%s/%.*s/%s", pmu_name, len, name, config + 1);
>> +		} else {
>> +			/* case: event */
>> +			ret = asprintf(&new_name, "%s/%s/", pmu_name, name);
>>   		}
>>   	}
>> -
>> -	counter->uniquified_name = true;
>> +	if (ret > 0) {
>> +		free(counter->name);
>> +		counter->name = new_name;
>> +	} else {
>> +		/* ENOMEM from asprintf. */
>> +		counter->uniquified_name = false;
>> +	}
>>   }
>>   
>>   static bool hybrid_uniquify(struct evsel *evsel, struct perf_stat_config *config)
>> @@ -1559,6 +1587,31 @@ static void print_cgroup_counter(struct perf_stat_config *config, struct evlist
>>   		print_metric_end(config, os);
>>   }
>>   
>> +static void disable_uniquify(struct evlist *evlist)
>> +{
>> +	struct evsel *counter;
>> +	struct perf_pmu *last_pmu = NULL;
>> +	bool first = true;
>> +
>> +	evlist__for_each_entry(evlist, counter) {
>> +		/* If PMUs vary then uniquify can be useful. */
>> +		if (!first && counter->pmu != last_pmu)
>> +			return;
>> +		first = false;
>> +		if (counter->pmu) {
>> +			/* Allow uniquify for uncore PMUs. */
>> +			if (!counter->pmu->is_core)
>> +				return;
>> +			/* Keep hybrid event names uniquified for clarity. */
>> +			if (perf_pmus__num_core_pmus() > 1)
>> +				return;
>> +		}
>> +	}
>> +	evlist__for_each_entry_continue(evlist, counter) {
>> +		counter->uniquified_name = true;
>> +	}
>> +}
>> +
>>   void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config,
>>   			    struct target *_target, struct timespec *ts,
>>   			    int argc, const char **argv)
>> @@ -1572,6 +1625,8 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
>>   		.first = true,
>>   	};
>>   
>> +	disable_uniquify(evlist);
>> +
>>   	if (config->iostat_run)
>>   		evlist->selected = evlist__first(evlist);
>>   
> 


From johan at kernel.org  Thu Dec  5 00:56:07 2024
From: johan at kernel.org (Johan Hovold)
Date: Thu, 5 Dec 2024 09:56:07 +0100
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint reader
In-Reply-To: <e6f60ca6-a4d2-4539-ab9b-dabe95dd2d21@oss.qualcomm.com>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com>
 <d095ae2a-3f9d-464c-9dc8-a3e73eac6598@oss.qualcomm.com>
 <98b2b88b-9690-44a7-9b22-2f23e6606e82@oss.qualcomm.com>
 <Z1FhQ3OUI0t3k1_q@hovoldconsulting.com>
 <e6f60ca6-a4d2-4539-ab9b-dabe95dd2d21@oss.qualcomm.com>
Message-ID: <Z1Fqp4EXxDbLOM4e@hovoldconsulting.com>

On Thu, Dec 05, 2024 at 01:52:08PM +0530, Krishna Kurapati wrote:
> On 12/5/2024 1:46 PM, Johan Hovold wrote:

> > And IIRC I even had to specify more than just the fingerprint reader PHY
> > on the X13s to get it to enumerate. I never had time to fully determine
> > why this was the case though.
> 
> This might need to be checked. Did you attempt adding each phy 
> individually ? Just incase the first PHY is not the one corresponding to 
> the fingerprint reader.

Yes, I tried each PHY in turn, and only enabling the HS and SS PHY for
the fingerprint reader port, but that was not enough.

Johan


From m.tretter at pengutronix.de  Thu Dec  5 00:58:55 2024
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Thu, 5 Dec 2024 09:58:55 +0100
Subject: [PATCH] media: allegro-dvt: Moving the current driver to
 subdirectory
In-Reply-To: <46tabetrggwplddtssags6eyjcd6x7znaquerjg3z5a63ykle4@z5fqzikwv2o4>
References: <20241202102654.40472-1-yassine.ouaissa@allegrodvt.com>
 <Z02SLI05JhNDtXFn@pengutronix.de>
 <abshbp4blqxasxvf4ibumtfqcr7hytehmhzs2yag3nfpbcl47x@ndjg7al4iysk>
 <Z1CC_PQF8hCzmPoQ@pengutronix.de>
 <46tabetrggwplddtssags6eyjcd6x7znaquerjg3z5a63ykle4@z5fqzikwv2o4>
Message-ID: <Z1FrT3gBWE5VgMOS@pengutronix.de>

Hi Yassine,

On Thu, 05 Dec 2024 08:11:48 +0000, Yassine Ouaissa wrote:
> On 04.12.2024 17:27, Michael Tretter wrote:
> > On Wed, 04 Dec 2024 14:44:31 +0000, Yassine Ouaissa wrote:
> > > On 02.12.2024 11:55, Michael Tretter wrote:
> > > > On Mon, 02 Dec 2024 11:26:38 +0100, Yassine Ouaissa wrote:
> > > > What kind of conflicts do you encounter or expect? It's kind of
> > > > surprising that your driver would conflict with anything in the existing
> > > > driver.
> > > 
> > > The current "NOT allegro" driver support only the ZynqMP (ex : ZCU106/ZCU104 ).
> > > And the upcoming driver, has support for many platforms.
> > 
> > What are the supported platforms of the new driver? Does your driver
> > support ZynqMP, too?
> > 
> The upcoming driver is not using the ZynqMP, it can be used by other
> clients including Xilinx.
> > If there are enough similarities between the encoders, I'd happily
> > replace parts of the current driver with functionality of the upcoming
> > driver or reuse the infrastructure of the new driver.
> > 
> 
> For now, we do have only the decoder (stateful). the encoder is "in
> progress". We prefer to have a separate driver core for each platform.

Thanks! I'd like to wait until I've seen your patches before agreeing to
move the driver to a subdirectory. Maybe even include this patch as the
first patch in your series to give a full picture of the new structure.

Michael

> > > 
> > > > I'd like to see how you plan to integrate your driver, what it looks
> > > > like and what conflicts with the existing driver actually occur. Without
> > > > that information I don't see the point in moving the driver to a
> > > > sub-directory.
> > > 
> > > The upcoming driver is not using the parsing, conversion inside of the
> > > driver. Actually the new Gen of ALLEGRO IP does that.
> > 
> > Sorry, I don't understand what you mean by parsing and conversion. Do
> > you mean the mailbox messages or the NAL units?
> > 
> > Can you point me to some repository with your upcoming driver? I'd
> > really like to know what's coming up to have an informed discussion how
> > to structure the directory.
> > 
> > Michael
> > 
> 
> Yassine
> > > > >
> > > > > Signed-off-by: Yassine Ouaissa <yassine.ouaissa at allegrodvt.com>
> > > > > ---
> > > > >  MAINTAINERS                                               | 2 +-
> > > > >  drivers/media/platform/allegro-dvt/Kconfig                | 4 ++--
> > > > >  drivers/media/platform/allegro-dvt/Makefile               | 8 ++------
> > > > >  drivers/media/platform/allegro-dvt/zynqmp/Makefile        | 6 ++++++
> > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c    | 0
> > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h    | 0
> > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c    | 0
> > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h    | 0
> > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c    | 0
> > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h    | 0
> > > > >  .../{allegro-core.c => zynqmp/zynqmp-allegro-core.c}      | 2 +-
> > > > >  .../{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c}      | 2 +-
> > > > >  .../{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h}      | 0
> > > > >  13 files changed, 13 insertions(+), 11 deletions(-)
> > > > >  create mode 100644 drivers/media/platform/allegro-dvt/zynqmp/Makefile
> > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c (100%)
> > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h (100%)
> > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c (100%)
> > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h (100%)
> > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c (100%)
> > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h (100%)
> > > > >  rename drivers/media/platform/allegro-dvt/{allegro-core.c => zynqmp/zynqmp-allegro-core.c} (99%)
> > > > >  rename drivers/media/platform/allegro-dvt/{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c} (99%)
> > > > >  rename drivers/media/platform/allegro-dvt/{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h} (100%)
> > > > >
> > > > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > > > index 7292e4a1ddb8..d79efe6f8992 100644
> > > > > --- a/MAINTAINERS
> > > > > +++ b/MAINTAINERS
> > > > > @@ -795,7 +795,7 @@ R:	Pengutronix Kernel Team <kernel at pengutronix.de>
> > > > >  L:	linux-media at vger.kernel.org
> > > > >  S:	Maintained
> > > > >  F:	Documentation/devicetree/bindings/media/allegro,al5e.yaml
> > > > > -F:	drivers/media/platform/allegro-dvt/
> > > > > +F:	drivers/media/platform/allegro-dvt/zynqmp
> > > > >
> > > > >  ALLIED VISION ALVIUM CAMERA DRIVER
> > > > >  M:	Tommaso Merciai <tomm.merciai at gmail.com>
> > > > > diff --git a/drivers/media/platform/allegro-dvt/Kconfig b/drivers/media/platform/allegro-dvt/Kconfig
> > > > > index 2182e1277568..9bc7e99788b8 100644
> > > > > --- a/drivers/media/platform/allegro-dvt/Kconfig
> > > > > +++ b/drivers/media/platform/allegro-dvt/Kconfig
> > > > > @@ -2,8 +2,8 @@
> > > > >
> > > > >  comment "Allegro DVT media platform drivers"
> > > > >
> > > > > -config VIDEO_ALLEGRO_DVT
> > > > > -	tristate "Allegro DVT Video IP Core"
> > > > > +config VIDEO_ZYNQMP_ALLEGRO_DVT
> > > > > +	tristate "Allegro DVT Video IP Core for ZynqMP"
> > > > >  	depends on V4L_MEM2MEM_DRIVERS
> > > > >  	depends on VIDEO_DEV
> > > > >  	depends on ARCH_ZYNQMP || COMPILE_TEST
> > > > > diff --git a/drivers/media/platform/allegro-dvt/Makefile b/drivers/media/platform/allegro-dvt/Makefile
> > > > > index 66108a303774..04727c5f7ef4 100644
> > > > > --- a/drivers/media/platform/allegro-dvt/Makefile
> > > > > +++ b/drivers/media/platform/allegro-dvt/Makefile
> > > > > @@ -1,6 +1,2 @@
> > > > > -# SPDX-License-Identifier: GPL-2.0
> > > > > -
> > > > > -allegro-objs := allegro-core.o allegro-mail.o
> > > > > -allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
> > > > > -
> > > > > -obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o
> > > > > +# SPDX-License-Identifier: GPL-2.0-only
> > > > > +obj-y += zynqmp/
> > > > > diff --git a/drivers/media/platform/allegro-dvt/zynqmp/Makefile b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
> > > > > new file mode 100644
> > > > > index 000000000000..a8ddb9cf93a8
> > > > > --- /dev/null
> > > > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
> > > > > @@ -0,0 +1,6 @@
> > > > > +# SPDX-License-Identifier: GPL-2.0
> > > > > +
> > > > > +zynqmp-allegro-objs := zynqmp-allegro-core.o zynqmp-allegro-mail.o
> > > > > +zynqmp-allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
> > > > > +
> > > > > +obj-$(CONFIG_VIDEO_ZYNQMP_ALLEGRO_DVT) += zynqmp-allegro.o
> > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-h264.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
> > > > > similarity index 100%
> > > > > rename from drivers/media/platform/allegro-dvt/nal-h264.c
> > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
> > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-h264.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
> > > > > similarity index 100%
> > > > > rename from drivers/media/platform/allegro-dvt/nal-h264.h
> > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
> > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
> > > > > similarity index 100%
> > > > > rename from drivers/media/platform/allegro-dvt/nal-hevc.c
> > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
> > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
> > > > > similarity index 100%
> > > > > rename from drivers/media/platform/allegro-dvt/nal-hevc.h
> > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
> > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
> > > > > similarity index 100%
> > > > > rename from drivers/media/platform/allegro-dvt/nal-rbsp.c
> > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
> > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
> > > > > similarity index 100%
> > > > > rename from drivers/media/platform/allegro-dvt/nal-rbsp.h
> > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
> > > > > diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> > > > > similarity index 99%
> > > > > rename from drivers/media/platform/allegro-dvt/allegro-core.c
> > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> > > > > index e491399afcc9..8895d7755987 100644
> > > > > --- a/drivers/media/platform/allegro-dvt/allegro-core.c
> > > > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> > > > > @@ -31,7 +31,7 @@
> > > > >  #include <media/videobuf2-dma-contig.h>
> > > > >  #include <media/videobuf2-v4l2.h>
> > > > >
> > > > > -#include "allegro-mail.h"
> > > > > +#include "zynqmp-allegro-mail.h"
> > > > >  #include "nal-h264.h"
> > > > >  #include "nal-hevc.h"
> > > > >
> > > > > diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> > > > > similarity index 99%
> > > > > rename from drivers/media/platform/allegro-dvt/allegro-mail.c
> > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> > > > > index aadc947a77ae..88a98f9e5d00 100644
> > > > > --- a/drivers/media/platform/allegro-dvt/allegro-mail.c
> > > > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> > > > > @@ -12,7 +12,7 @@
> > > > >  #include <linux/string.h>
> > > > >  #include <linux/videodev2.h>
> > > > >
> > > > > -#include "allegro-mail.h"
> > > > > +#include "zynqmp-allegro-mail.h"
> > > > >
> > > > >  const char *msg_type_name(enum mcu_msg_type type)
> > > > >  {
> > > > > diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.h b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
> > > > > similarity index 100%
> > > > > rename from drivers/media/platform/allegro-dvt/allegro-mail.h
> > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
> > > > > --
> > > > > 2.30.2
> > > > >
> > > > >


From krzk at kernel.org  Thu Dec  5 00:59:29 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 09:59:29 +0100
Subject: [PATCH v4 1/4] dt-bindings: firmware: imx: add nvmem phandle
In-Reply-To: <20241205-secvio-v4-1-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
 <20241205-secvio-v4-1-5c37cdc39573@nxp.com>
Message-ID: <vxe5ml2zwg2kg5ui2mz4ws2mc3fj6whvnvvft3x6ezr7fhkdrd@ipghbtncp3en>

On Thu, Dec 05, 2024 at 05:56:32AM +0100, Vabhav Sharma wrote:
> nvmem phandle is required by secvio driver to
> read fuse.

Please wrap commit message according to Linux coding style / submission
process (neither too early nor over the limit):
https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597

> 
> Signed-off-by: Vabhav Sharma <vabhav.sharma at nxp.com>
> ---
>  Documentation/devicetree/bindings/firmware/fsl,scu.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> index 557e524786c2..c88d9c2dac24 100644
> --- a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> +++ b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> @@ -112,6 +112,9 @@ properties:
>            - const: rx2
>            - const: rx3
>            - const: gip3

Unresolved comment. I would normally add conditional ack, but this is
second time you ignore comments, so I don't trust you on that. Sad that
such trivial things will require respin.

> +  nvmem:
> +    description:
> +      phandle of NVMEM controller provided by the SCU

Best regards,
Krzysztof



From geert at linux-m68k.org  Thu Dec  5 01:07:37 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 5 Dec 2024 10:07:37 +0100
Subject: [PATCH 0/5] arm64: renesas: Add R8A779G3 White Hawk Single support
In-Reply-To: <87jzcg1d2f.wl-kuninori.morimoto.gx@renesas.com>
References: <cover.1733156661.git.geert+renesas@glider.be> <87jzcg1d2f.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <CAMuHMdWF7NcmKYzvF4Dfjh3S5MccbJrpSphK5BhxXNnhxgtmYQ@mail.gmail.com>

Hi Morimoto-san,

On Wed, Dec 4, 2024 at 1:56?AM Kuninori Morimoto
<kuninori.morimoto.gx at renesas.com> wrote:
> > This patch series adds support for the Renesas R-Car V4H ES3.0 (R8A779G3)
> > SoC on the Renesas White Hawk Single board.  R-Car V4H ES3.0 (R8A779G3)
> > is an updated version of R-Car V4H (R8A779G0).
> >
> > I intend to queue these in renesas-devel for v6.14.
> > Thanks for your comments!
>
> Thank you for the patch-set. For all patches
>
> Reviewed-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
>
> But small nitpick is that R8A779G2 is not only for ES2.0 but for ES2.x

I didn't add any occurrences of "ES2.0" in this series ;-)

I did consider adding comments to the SoC-specific compatible values
in Documentation/devicetree/bindings/soc/renesas/renesas.yaml

-              - renesas,r8a779g2
-              - renesas,r8a779g3
+              - renesas,r8a779g2 # ES2.x
+              - renesas,r8a779g3 # ES3.0

but decided against doing so, as "ES3.0" would become stale as soon
as Renesas releases "ES3.1". Alternatively, I could use "ES3.x"
immediately.

What do you think?
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 syzbot+list5853008af9f104a9355f at syzkaller.appspotmail.com  Thu Dec  5 01:08:27 2024
From: syzbot+list5853008af9f104a9355f at syzkaller.appspotmail.com (syzbot)
Date: Thu, 05 Dec 2024 01:08:27 -0800
Subject: [syzbot] Monthly arm report (Dec 2024)
Message-ID: <67516d8b.050a0220.17bd51.0092.GAE@google.com>

Hello arm maintainers/developers,

This is a 31-day syzbot report for the arm subsystem.
All related reports/information can be found at:
https://syzkaller.appspot.com/upstream/s/arm

During the period, 0 new issues were detected and 0 were fixed.
In total, 5 issues are still open and 5 have already been fixed.

Some of the still happening issues:

Ref Crashes Repro Title
<1> 3448    Yes   BUG: bad usercopy in fpa_set
                  https://syzkaller.appspot.com/bug?extid=cb76c2983557a07cdb14
<2> 817     Yes   BUG: unable to handle kernel paging request in trans_pgd_create_copy
                  https://syzkaller.appspot.com/bug?extid=2d1f5a94167d430a3bd7
<3> 123     No    WARNING in delayed_work_timer_fn
                  https://syzkaller.appspot.com/bug?extid=e13e654d315d4da1277c

---
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.

To disable reminders for individual bugs, reply with the following command:
#syz set <Ref> no-reminders

To change bug's subsystems, reply with:
#syz set <Ref> subsystems: new-subsystem

You may send multiple commands in a single email message.


From kalesh-anakkur.purayil at broadcom.com  Thu Dec  5 01:10:28 2024
From: kalesh-anakkur.purayil at broadcom.com (Kalesh Anakkur Purayil)
Date: Thu, 5 Dec 2024 14:40:28 +0530
Subject: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix firmware load sequence.
In-Reply-To: <20241205082831.777868-2-m-malladi@ti.com>
References: <20241205082831.777868-1-m-malladi@ti.com> <20241205082831.777868-2-m-malladi@ti.com>
Message-ID: <CAH-L+nMBYWVwbLoeMpe+PYw27KPKaKAH+hNFRaNTtYrBJ6yRHw@mail.gmail.com>

On Thu, Dec 5, 2024 at 1:59?PM Meghana Malladi <m-malladi at ti.com> wrote:
>
> From: MD Danish Anwar <danishanwar at ti.com>
>
> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
> and SLICE1. Currently whenever any ICSSG interface comes up we load the
> respective firmwares to PRU cores and whenever interface goes down, we
> stop the resective cores. Due to this, when SLICE0 goes down while
> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
> stopped. This results in clock jump for SLICE1 interface as the timesync
> related operations are no longer running.
>
> As there are interdependencies between SLICE0 and SLICE1 firmwares,
> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
> ICSSG interface is up. Add new flag in prueth struct to check if all
> firmwares are running.
>
> Use emacs_initialized as reference count to load the firmwares for the
> first and last interface up/down. Moving init_emac_mode and fw_offload_mode
> API outside of icssg_config to icssg_common_start API as they need
> to be called only once per firmware boot.
>
> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
> ---
>
> Hi all,
>
> This patch is based on net-next tagged next-20241128.
> v2:https://lore.kernel.org/all/20241128122931.2494446-2-m-malladi at ti.com/
>
> * Changes since v2 (v3-v2):
> - error handling in caller function of prueth_emac_common_start()
> - Use prus_running flag check before stopping the firmwares
> Both suggested by Roger Quadros <rogerq at kernel.org>
>
>  drivers/net/ethernet/ti/icssg/icssg_config.c |  45 ++++--
>  drivers/net/ethernet/ti/icssg/icssg_config.h |   1 +
>  drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
>  drivers/net/ethernet/ti/icssg/icssg_prueth.h |   5 +
>  4 files changed, 140 insertions(+), 68 deletions(-)
>
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
> index 5d2491c2943a..342150756cf7 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_config.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
> @@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>         return 0;
>  }
>
> -static void icssg_init_emac_mode(struct prueth *prueth)
> +void icssg_init_emac_mode(struct prueth *prueth)
>  {
>         /* When the device is configured as a bridge and it is being brought
>          * back to the emac mode, the host mac address has to be set as 0.
> @@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>         int i;
>         u8 mac[ETH_ALEN] = { 0 };
>
> -       if (prueth->emacs_initialized)
> -               return;
> -
>         /* Set VLAN TABLE address base */
>         regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>                            addr <<  SMEM_VLAN_OFFSET);
> @@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>         /* Clear host MAC address */
>         icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
>  }
> +EXPORT_SYMBOL_GPL(icssg_init_emac_mode);
>
> -static void icssg_init_fw_offload_mode(struct prueth *prueth)
> +void icssg_init_fw_offload_mode(struct prueth *prueth)
>  {
>         u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET;
>         int i;
>
> -       if (prueth->emacs_initialized)
> -               return;
> -
>         /* Set VLAN TABLE address base */
>         regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>                            addr <<  SMEM_VLAN_OFFSET);
> @@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth)
>                 icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr);
>         icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST);
>  }
> +EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode);
>
>  int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>  {
> @@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>         struct icssg_flow_cfg __iomem *flow_cfg;
>         int ret;
>
> -       if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
> -               icssg_init_fw_offload_mode(prueth);
> -       else
> -               icssg_init_emac_mode(prueth);
> -
>         memset_io(config, 0, TAS_GATE_MASK_LIST0);
>         icssg_miig_queues_init(prueth, slice);
>
> @@ -786,3 +777,31 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port)
>                 writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET);
>  }
>  EXPORT_SYMBOL_GPL(icssg_set_pvid);
> +
> +int emac_fdb_flow_id_updated(struct prueth_emac *emac)
> +{
> +       struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
> +       int slice = prueth_emac_slice(emac);
> +       struct mgmt_cmd fdb_cmd = { 0 };
> +       int ret = 0;
[Kalesh] There is no need to initialize "ret" here
> +
> +       fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
> +       fdb_cmd.type   = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
> +       fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq);
> +       fdb_cmd.param  = 0;
> +
> +       fdb_cmd.param |= (slice << 4);
> +       fdb_cmd.cmd_args[0] = 0;
> +
> +       ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp);
> +
[Kalesh] There is no need of an new line here
> +       if (ret)
> +               return ret;
> +
> +       WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum);
> +       if (fdb_cmd_rsp.status == 1)
> +               return 0;
> +
> +       return -EINVAL;
[Kalesh] Maybe you can simplify this as:
return fdb_cmd_rsp.status == 1 ? 0 : -EINVAL;
> +}
> +EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated);
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
> index 92c2deaa3068..c884e9fa099e 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_config.h
> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
> @@ -55,6 +55,7 @@ struct icssg_rxq_ctx {
>  #define ICSSG_FW_MGMT_FDB_CMD_TYPE     0x03
>  #define ICSSG_FW_MGMT_CMD_TYPE         0x04
>  #define ICSSG_FW_MGMT_PKT              0x80000000
> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW     0x05
>
>  struct icssg_r30_cmd {
>         u32 cmd[4];
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> index c568c84a032b..2e22e793b01a 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> @@ -164,11 +164,11 @@ static struct icssg_firmwares icssg_emac_firmwares[] = {
>         }
>  };
>
> -static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
> +static int prueth_emac_start(struct prueth *prueth, int slice)
>  {
>         struct icssg_firmwares *firmwares;
>         struct device *dev = prueth->dev;
> -       int slice, ret;
> +       int ret;
>
>         if (prueth->is_switch_mode)
>                 firmwares = icssg_switch_firmwares;
> @@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>         else
>                 firmwares = icssg_emac_firmwares;
>
> -       slice = prueth_emac_slice(emac);
> -       if (slice < 0) {
> -               netdev_err(emac->ndev, "invalid port\n");
> -               return -EINVAL;
> -       }
> -
> -       ret = icssg_config(prueth, emac, slice);
> -       if (ret)
> -               return ret;
> -
>         ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
>         ret = rproc_boot(prueth->pru[slice]);
>         if (ret) {
> @@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>                 goto halt_rtu;
>         }
>
> -       emac->fw_running = 1;
>         return 0;
>
>  halt_rtu:
> @@ -220,6 +209,80 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>         return ret;
>  }
>
> +static int prueth_emac_common_start(struct prueth *prueth)
> +{
> +       struct prueth_emac *emac;
> +       int ret = 0;
> +       int slice;
> +
> +       if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
> +               return -EINVAL;
> +
> +       /* clear SMEM and MSMC settings for all slices */
> +       memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
> +       memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
> +
> +       icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
> +       icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
> +
> +       if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
> +               icssg_init_fw_offload_mode(prueth);
> +       else
> +               icssg_init_emac_mode(prueth);
> +
> +       for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
> +               emac = prueth->emac[slice];
> +               if (emac) {
> +                       ret |= icssg_config(prueth, emac, slice);
> +                       if (ret)
> +                               return ret;
> +               }
> +               ret |= prueth_emac_start(prueth, slice);
> +       }
> +       if (!ret)
> +               prueth->prus_running = 1;
> +       else
> +               return ret;
[Kalesh] This will read better if you change the condition check like:
if (ret)
    return ret;
prueth->prus_running = 1;
> +
> +       emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
> +              prueth->emac[ICSS_SLICE1];
> +       ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
> +                           emac, IEP_DEFAULT_CYCLE_TIME_NS);
> +       if (ret) {
> +               dev_err(prueth->dev, "Failed to initialize IEP module\n");
> +               return ret;
> +       }
> +
> +       return 0;
[Kalesh] You can "return ret" here and remove the return from above if
condition.
> +}
> +
> +static int prueth_emac_common_stop(struct prueth *prueth)
> +{
> +       struct prueth_emac *emac;
> +       int slice;
> +
> +       if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
> +               return -EINVAL;
> +
> +       icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
> +       icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
> +
> +       for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
> +               if (prueth->prus_running) {
> +                       rproc_shutdown(prueth->txpru[slice]);
> +                       rproc_shutdown(prueth->rtu[slice]);
> +                       rproc_shutdown(prueth->pru[slice]);
> +               }
> +       }
> +       prueth->prus_running = 0;
> +
> +       emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
> +              prueth->emac[ICSS_SLICE1];
> +       icss_iep_exit(emac->iep);
> +
> +       return 0;
> +}
> +
>  /* called back by PHY layer if there is change in link state of hw port*/
>  static void emac_adjust_link(struct net_device *ndev)
>  {
> @@ -369,12 +432,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
>  {
>         struct icssg_setclock_desc __iomem *sc_descp;
>         struct prueth_emac *emac = clockops_data;
> +       struct prueth *prueth = emac->prueth;
>         struct icssg_setclock_desc sc_desc;
>         u64 cyclecount;
>         u32 cycletime;
>         int timeout;
>
> -       if (!emac->fw_running)
> +       if (!prueth->prus_running)
>                 return;
>
>         sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
> @@ -543,23 +607,17 @@ 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;
> +       struct icssg_flow_cfg __iomem *flow_cfg;
>         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, false);
>         icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
>
>         /* Notify the stack of the actual queue counts. */
> @@ -597,18 +655,23 @@ static int emac_ndo_open(struct net_device *ndev)
>                 goto cleanup_napi;
>         }
>
> -       /* reset and start PRU firmware */
> -       ret = prueth_emac_start(prueth, emac);
> -       if (ret)
> -               goto free_rx_irq;
> +       if (!prueth->emacs_initialized) {
> +               ret = prueth_emac_common_start(prueth);
> +               if (ret)
> +                       goto stop;
> +       }
>
> -       icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
> +       flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
> +       writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
> +       ret = emac_fdb_flow_id_updated(emac);
>
> -       if (!prueth->emacs_initialized) {
> -               ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
> -                                   emac, IEP_DEFAULT_CYCLE_TIME_NS);
> +       if (ret) {
> +               netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
> +               goto stop;
>         }
>
> +       icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
> +
>         ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
>                                    IRQF_ONESHOT, dev_name(dev), emac);
>         if (ret)
> @@ -653,8 +716,7 @@ static int emac_ndo_open(struct net_device *ndev)
>  free_tx_ts_irq:
>         free_irq(emac->tx_ts_irq, emac);
>  stop:
> -       prueth_emac_stop(emac);
> -free_rx_irq:
> +       prueth_emac_common_stop(prueth);
>         free_irq(emac->rx_chns.irq[rx_flow], emac);
>  cleanup_napi:
>         prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
> @@ -689,8 +751,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>         if (ndev->phydev)
>                 phy_stop(ndev->phydev);
>
> -       icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
> -
>         if (emac->prueth->is_hsr_offload_mode)
>                 __dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
>         else
> @@ -728,11 +788,9 @@ static int emac_ndo_stop(struct net_device *ndev)
>         /* Destroying the queued work in ndo_stop() */
>         cancel_delayed_work_sync(&emac->stats_work);
>
> -       if (prueth->emacs_initialized == 1)
> -               icss_iep_exit(emac->iep);
> -
>         /* stop PRUs */
> -       prueth_emac_stop(emac);
> +       if (prueth->emacs_initialized == 1)
> +               prueth_emac_common_stop(prueth);
>
>         free_irq(emac->tx_ts_irq, emac);
>
> @@ -1069,16 +1127,10 @@ static void prueth_emac_restart(struct prueth *prueth)
>         icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
>
>         /* Stop both pru cores for both PRUeth ports*/
> -       prueth_emac_stop(emac0);
> -       prueth->emacs_initialized--;
> -       prueth_emac_stop(emac1);
> -       prueth->emacs_initialized--;
> +       prueth_emac_common_stop(prueth);
>
>         /* Start both pru cores for both PRUeth ports */
> -       prueth_emac_start(prueth, emac0);
> -       prueth->emacs_initialized++;
> -       prueth_emac_start(prueth, emac1);
> -       prueth->emacs_initialized++;
> +       prueth_emac_common_start(prueth);
>
>         /* Enable forwarding for both PRUeth ports */
>         icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
> @@ -1413,13 +1465,10 @@ static int prueth_probe(struct platform_device *pdev)
>                 prueth->pa_stats = NULL;
>         }
>
> -       if (eth0_node) {
> +       if (eth0_node || eth1_node) {
>                 ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
>                 if (ret)
>                         goto put_cores;
> -       }
> -
> -       if (eth1_node) {
>                 ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
>                 if (ret)
>                         goto put_cores;
> @@ -1618,14 +1667,12 @@ static int prueth_probe(struct platform_device *pdev)
>         pruss_put(prueth->pruss);
>
>  put_cores:
> -       if (eth1_node) {
> -               prueth_put_cores(prueth, ICSS_SLICE1);
> -               of_node_put(eth1_node);
> -       }
> -
> -       if (eth0_node) {
> +       if (eth0_node || eth1_node) {
>                 prueth_put_cores(prueth, ICSS_SLICE0);
>                 of_node_put(eth0_node);
> +
> +               prueth_put_cores(prueth, ICSS_SLICE1);
> +               of_node_put(eth1_node);
>         }
>
>         return ret;
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> index f5c1d473e9f9..b30f2e9a73d8 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> @@ -257,6 +257,7 @@ struct icssg_firmwares {
>   * @is_switchmode_supported: indicates platform support for switch mode
>   * @switch_id: ID for mapping switch ports to bridge
>   * @default_vlan: Default VLAN for host
> + * @prus_running: flag to indicate if all pru cores are running
>   */
>  struct prueth {
>         struct device *dev;
> @@ -298,6 +299,7 @@ struct prueth {
>         int default_vlan;
>         /** @vtbl_lock: Lock for vtbl in shared memory */
>         spinlock_t vtbl_lock;
> +       bool prus_running;
>  };
>
>  struct emac_tx_ts_response {
> @@ -361,6 +363,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
>                          enum icssg_port_state_cmd state);
>  void icssg_config_set_speed(struct prueth_emac *emac);
>  void icssg_config_half_duplex(struct prueth_emac *emac);
> +void icssg_init_emac_mode(struct prueth *prueth);
> +void icssg_init_fw_offload_mode(struct prueth *prueth);
>
>  /* Buffer queue helpers */
>  int icssg_queue_pop(struct prueth *prueth, u8 queue);
> @@ -377,6 +381,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
>                        u8 untag_mask, bool add);
>  u16 icssg_get_pvid(struct prueth_emac *emac);
>  void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
> +int emac_fdb_flow_id_updated(struct prueth_emac *emac);
>  #define prueth_napi_to_tx_chn(pnapi) \
>         container_of(pnapi, struct prueth_tx_chn, napi_tx)
>
> --
> 2.25.1
>
>


-- 
Regards,
Kalesh A P
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4239 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241205/23d231b5/attachment.p7s>

From dmt.yashin at gmail.com  Thu Dec  5 01:06:27 2024
From: dmt.yashin at gmail.com (Dmitry Yashin)
Date: Thu, 5 Dec 2024 14:06:27 +0500
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2
 controller
In-Reply-To: <20241203165450.1501219-1-heiko@sntech.de>
References: <20241203165450.1501219-1-heiko@sntech.de>
Message-ID: <6c8e60a1-820b-4818-ad68-9b042533f4f9@gmail.com>

Hello Heiko,

On 03.12.24 21:54, Heiko Stuebner wrote:
> This series adds a bridge and glue driver for the DSI2 controller found
> in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
>
> As the manual states:
> The Display Serial Interface 2 (DSI-2) is part of a group of communication
> protocols defined by the MIPI Alliance. The MIPI DSI-2 Host Controller is
> a digital core that implements all protocol functions defined in the
> MIPI DSI-2 Specification.
>
>
> While the driver structure is very similar to the previous DSI controller,
> the programming model of the core is quite different, with a completely
> new register set.
>
> Another notable difference is that the phy interface is variable now too
> in its width and some other settings.

Thanks for the series. I was able to get output on my Radxa's Rock 5B
(dsi1) + Radxa's 10FHD Display setup. Works smoothly with multiple DE's,
rotation and display on/off.

Tested-by: Dmitry Yashin <dmt.yashin at gmail.com>

-- 
Thanks,
Dmitry



From krzk at kernel.org  Thu Dec  5 01:13:21 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 10:13:21 +0100
Subject: [PATCH v4 4/4] firmware: imx: secvio: Add support for SNVS
 secvio and tamper via SCFW
In-Reply-To: <20241205-secvio-v4-4-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
 <20241205-secvio-v4-4-5c37cdc39573@nxp.com>
Message-ID: <fihqc5qtocjauc52e6ri34v5nqzaz3vbk4usafpwkoaslc32qn@kjkpwsm6fqur>

On Thu, Dec 05, 2024 at 05:56:35AM +0100, Vabhav Sharma wrote:
> +
> +int imx_secvio_sc_debugfs(struct device *dev)
> +{
> +	struct imx_secvio_sc_data *data = dev_get_drvdata(dev);
> +	struct dentry *dir;
> +	int ret = 0;
> +
> +	/* Create a folder */
> +	dir = debugfs_create_dir(dev_name(dev), NULL);
> +	if (IS_ERR(dir)) {
> +		dev_err(dev, "Failed to create dfs dir\n");

Drop

> +		ret = PTR_ERR(dir);
> +		goto exit;

Drop all this.

> +	}
> +	data->dfs = dir;
> +
> +	ret = devm_add_action(dev, if_debugfs_remove_recursive, data->dfs);
> +	if (ret) {
> +		dev_err(dev, "Failed to add managed action to disable IRQ\n");

Drop

> +		goto remove_fs;
> +	}
> +
> +	/* Create the file to read info and write to reg */
> +	dir = debugfs_create_file("info", 0x666, data->dfs, dev,
> +				  &imx_secvio_sc_info_ops);
> +	if (IS_ERR(dir)) {
> +		dev_err(dev, "Failed to add info to debugfs\n");

There is *never such code*. You never print error messages and fail the
probe on debugfs. Drop.


> +		ret = PTR_ERR(dir);
> +		goto exit;

Drop

This has several trivial issues. I suggest doing extensive
internal review before asking the community to look at this.

> +	}
> +
> +exit:
> +	return ret;
> +
> +remove_fs:
> +	debugfs_remove_recursive(data->dfs);
> +	goto exit;
> +}
> diff --git a/drivers/firmware/imx/imx-scu-secvio.c b/drivers/firmware/imx/imx-scu-secvio.c
> new file mode 100644
> index 000000000000..30eb9e4bf7b8
> --- /dev/null
> +++ b/drivers/firmware/imx/imx-scu-secvio.c
> @@ -0,0 +1,619 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2019, 2024 NXP
> + *
> + */
> +
> +/*
> + * The i.MX8QXP SoC contains the Secure Non-Volatile Storage (SNVS) block. This
> + * block can detect specific hardware attacks.This block can only be accessible
> + * using the SCFW API.
> + *
> + * This module interact with the SCU which relay request to/from the SNVS block
> + * to detect if security violation occurred.
> + *
> + * The module exports an API to add processing when a SV is detected:
> + *  - register_imx_secvio_sc_notifier
> + *  - unregister_imx_secvio_sc_notifier
> + *  - imx_secvio_sc_check_state
> + *  - imx_secvio_sc_clear_state
> + *  - imx_secvio_sc_enable_irq
> + *  - imx_secvio_sc_disable_irq
> + */
> +
> +#include <dt-bindings/firmware/imx/rsrc.h>
> +#include <linux/device.h>
> +#include <linux/fs.h>
> +#include <linux/kernel.h>
> +#include <linux/miscdevice.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/notifier.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_platform.h>
> +
> +#include <linux/uaccess.h>
> +
> +#include <linux/firmware/imx/ipc.h>
> +#include <linux/firmware/imx/sci.h>
> +#include <linux/firmware/imx/svc/seco.h>
> +#include <linux/firmware/imx/svc/rm.h>
> +#include <linux/firmware/imx/svc/imx-secvio-sc.h>
> +
> +/* Reference on the driver_device */
> +static struct device *imx_secvio_sc_dev;
> +
> +/* Register IDs for sc_seco_secvio_config API */
> +#define HPSVS_ID 0x18
> +#define LPS_ID 0x4c
> +#define LPTDS_ID 0xa4
> +#define HPVIDR_ID 0xf8
> +
> +#define SECO_MINOR_VERSION_SUPPORT_SECVIO_TAMPER 0x53
> +#define SECO_VERSION_MINOR_MASK GENMASK(15, 0)
> +
> +static struct platform_driver imx_secvio_sc_driver;

Drop, not used... or you messed up cleaning processes.

> +static struct platform_device *pdev;

Singletons are really poor coding approach. Fix your driver architecture
so this will be properly instantiated only once, not multiple times.

> +static struct device *scdev;

Drop, not needed. Fix your driver.

> +
> +/* Notifier list for new CB */
> +static BLOCKING_NOTIFIER_HEAD(imx_secvio_sc_notifier_chain);
> +
> +int register_imx_secvio_sc_notifier(struct notifier_block *nb)
> +{
> +	return blocking_notifier_chain_register(&imx_secvio_sc_notifier_chain,
> +						nb);
> +}
> +EXPORT_SYMBOL(register_imx_secvio_sc_notifier);

NAK

> +
> +int unregister_imx_secvio_sc_notifier(struct notifier_block *nb)
> +{
> +	return blocking_notifier_chain_unregister(&imx_secvio_sc_notifier_chain,
> +						  nb);
> +}
> +EXPORT_SYMBOL(unregister_imx_secvio_sc_notifier);

1. You mix up exports with statics. This driver is poorly organized.
Really it is a mess here.
2. Why do you need to export these? These are not used, so you cannot
have them.

That's a strong NAK. Stop bringing here some stuff for yourodownstream.


> +
> +static void if_imx_scu_irq_register_notifier(void *nb)
> +{
> +	imx_scu_irq_register_notifier(nb);
> +}
> +
> +static void if_unregister_imx_secvio_sc_notifier(void *nb)
> +{
> +	unregister_imx_secvio_sc_notifier(nb);
> +}
> +
> +static
> +int imx_secvio_sc_notifier_call_chain(struct secvio_sc_notifier_info *info)
> +{
> +	return blocking_notifier_call_chain(&imx_secvio_sc_notifier_chain, 0,
> +					    (void *)info);
> +}
> +
> +int imx_secvio_sc_get_state(struct device *dev,
> +			    struct secvio_sc_notifier_info *info)
> +{
> +	int ret, err = 0;
> +	struct imx_secvio_sc_data *data;
> +
> +	dev = imx_secvio_sc_dev;
> +	if (!dev)
> +		return -EINVAL;
> +
> +	data = dev_get_drvdata(dev);
> +
> +	/* Read secvio status */
> +	ret = imx_sc_seco_secvio_config(data->ipc_handle, HPSVS_ID, SECVIO_CONFIG_READ,
> +					&info->hpsvs, NULL, NULL, NULL, NULL, 1);
> +	if (ret) {
> +		err = ret;
> +		dev_err(dev, "Fail read secvio config status %d\n", ret);
> +	}
> +	info->hpsvs &= HPSVS_ALL_SV_MASK;
> +
> +	/* Read tampers status */
> +	ret = imx_sc_seco_secvio_config(data->ipc_handle, LPS_ID, SECVIO_CONFIG_READ,
> +					&info->lps, NULL, NULL, NULL, NULL, 1);
> +	if (ret) {
> +		err = ret;
> +		dev_err(dev, "Fail read tamper 1 status: %d\n", ret);
> +	}
> +	info->lps &= LPS_ALL_TP_MASK;
> +
> +	ret = imx_sc_seco_secvio_config(data->ipc_handle, LPTDS_ID, SECVIO_CONFIG_READ,
> +					&info->lptds, NULL, NULL, NULL, NULL, 1);
> +	if (ret) {
> +		err = ret;
> +		dev_err(dev, "Fail read  tamper 2 status: %d\n", ret);
> +	}
> +	info->lptds &= LPTDS_ALL_TP_MASK;
> +
> +	dev_dbg(dev, "Status: %.8x, %.8x, %.8x\n", info->hpsvs,
> +		info->lps, info->lptds);

No, don't print internal values.

> +
> +	return err;
> +}
> +EXPORT_SYMBOL(imx_secvio_sc_get_state);

NAK, no users.

> +
> +int imx_secvio_sc_check_state(struct device *dev)
> +{
> +	struct secvio_sc_notifier_info info;
> +	int ret;
> +
> +	dev = imx_secvio_sc_dev;
> +
> +	ret = imx_secvio_sc_get_state(dev, &info);
> +	if (ret) {
> +		dev_err(dev, "Failed to get secvio state\n");
> +		return ret;
> +	}
> +
> +	/* Call chain of CB registered to this module if status detected */
> +	if (info.hpsvs || info.lps || info.lptds)
> +		if (imx_secvio_sc_notifier_call_chain(&info))
> +			dev_warn(dev,
> +				 "Issues when calling the notifier chain\n");
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(imx_secvio_sc_check_state);
> +

NAK, no users.

> +static int imx_secvio_sc_disable_irq(struct device *dev)
> +{
> +	int ret;
> +
> +	if (!dev)
> +		return -EINVAL;
> +
> +	/* Disable the IRQ */
> +	ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_SECVIO,
> +				       false);
> +	if (ret) {
> +		dev_err(dev, "Cannot disable SCU IRQ: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +static int imx_secvio_sc_enable_irq(struct device *dev)
> +{
> +	int ret = 0, err;
> +	u32 irq_status;
> +	struct imx_secvio_sc_data *data;
> +
> +	if (!dev)
> +		return -EINVAL;
> +
> +	data = dev_get_drvdata(dev);
> +
> +	/* Enable the IRQ */
> +	ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_SECVIO,
> +				       true);
> +	if (ret) {
> +		dev_err(dev, "Cannot enable SCU IRQ: %d\n", ret);
> +		goto exit;
> +	}
> +
> +	/* Enable interrupt */
> +	ret = imx_sc_seco_secvio_enable(data->ipc_handle);
> +	if (ret) {
> +		dev_err(dev, "Cannot enable SNVS irq: %d\n", ret);
> +		goto exit;
> +	}
> +
> +	/* Unmask interrupt */
> +	ret = imx_scu_irq_get_status(IMX_SC_IRQ_GROUP_WAKE, &irq_status);
> +	if (ret) {
> +		dev_err(dev, "Cannot unmask irq: %d\n", ret);
> +		goto exit;
> +	}
> +
> +exit:
> +	if (ret) {
> +		err = imx_secvio_sc_disable_irq(dev);
> +		if (err)
> +			dev_warn(dev, "Failed to disable the IRQ\n");
> +	}
> +
> +	return ret;
> +}
> +
> +static int imx_secvio_sc_notify(struct notifier_block *nb,
> +				unsigned long event, void *group)
> +{
> +	struct imx_secvio_sc_data *data =
> +				container_of(nb, struct imx_secvio_sc_data,
> +					     irq_nb);
> +	struct device *dev = data->dev;
> +	int ret;
> +
> +	/* Filter event for us */
> +	if (!((event & IMX_SC_IRQ_SECVIO) &&
> +	      (*(u8 *)group == IMX_SC_IRQ_GROUP_WAKE)))
> +		return 0;
> +
> +	dev_warn(dev, "secvio security violation detected\n");
> +
> +	ret = imx_secvio_sc_check_state(dev);
> +
> +	/* Re-enable interrupt */
> +	ret = imx_secvio_sc_enable_irq(dev);
> +	if (ret)
> +		dev_err(dev, "Failed to enable IRQ\n");
> +
> +	return ret;
> +}
> +
> +int imx_secvio_sc_clear_state(struct device *dev, u32 hpsvs, u32 lps, u32 lptds)
> +{
> +	int ret;
> +	struct imx_secvio_sc_data *data;
> +
> +	dev = imx_secvio_sc_dev;
> +	if (!dev)
> +		return -EINVAL;
> +
> +	data = dev_get_drvdata(dev);
> +
> +	ret = imx_sc_seco_secvio_config(data->ipc_handle, HPSVS_ID, SECVIO_CONFIG_WRITE,
> +					&hpsvs, NULL, NULL, NULL, NULL, 1);
> +	if (ret) {
> +		dev_err(dev, "Fail to clear secvio status: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = imx_sc_seco_secvio_config(data->ipc_handle, LPS_ID, SECVIO_CONFIG_WRITE,
> +					&lps, NULL, NULL, NULL, NULL, 1);
> +	if (ret) {
> +		dev_err(dev, "Fail to clear tamper 1 status: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = imx_sc_seco_secvio_config(data->ipc_handle, LPTDS_ID, SECVIO_CONFIG_WRITE,
> +					&lptds, NULL, NULL, NULL, NULL, 1);
> +	if (ret) {
> +		dev_err(dev, "Fail to clear tamper 2 status: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(imx_secvio_sc_clear_state);

So again export appears after several static functions? Organize your
driver in readable style.

However that's anyway a NAK, no users.

> +
> +static int report_to_user_notify(struct notifier_block *nb,
> +				 unsigned long status, void *notif_info)
> +{
> +	struct secvio_sc_notifier_info *info = notif_info;
> +	struct imx_secvio_sc_data *data =
> +				container_of(nb, struct imx_secvio_sc_data,
> +					     report_nb);
> +	struct device *dev = data->dev;
> +
> +	/* Information about the security violation */
> +	if (info->hpsvs & HPSVS_LP_SEC_VIO_MASK)
> +		dev_info(dev, "SNVS secvio: LPSV\n");
> +	if (info->hpsvs & HPSVS_SW_LPSV_MASK)
> +		dev_info(dev, "SNVS secvio: SW LPSV\n");
> +	if (info->hpsvs & HPSVS_SW_FSV_MASK)
> +		dev_info(dev, "SNVS secvio: SW FSV\n");
> +	if (info->hpsvs & HPSVS_SW_SV_MASK)
> +		dev_info(dev, "SNVS secvio: SW SV\n");
> +	if (info->hpsvs & HPSVS_SV5_MASK)
> +		dev_info(dev, "SNVS secvio: SV 5\n");
> +	if (info->hpsvs & HPSVS_SV4_MASK)
> +		dev_info(dev, "SNVS secvio: SV 4\n");
> +	if (info->hpsvs & HPSVS_SV3_MASK)
> +		dev_info(dev, "SNVS secvio: SV 3\n");
> +	if (info->hpsvs & HPSVS_SV2_MASK)
> +		dev_info(dev, "SNVS secvio: SV 2\n");
> +	if (info->hpsvs & HPSVS_SV1_MASK)
> +		dev_info(dev, "SNVS secvio: SV 1\n");
> +	if (info->hpsvs & HPSVS_SV0_MASK)
> +		dev_info(dev, "SNVS secvio: SV 0\n");
> +
> +	/* Information about the tampers */
> +	if (info->lps & LPS_ESVD_MASK)
> +		dev_info(dev, "SNVS tamper: External SV\n");
> +	if (info->lps & LPS_ET2D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 2\n");
> +	if (info->lps & LPS_ET1D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 1\n");
> +	if (info->lps & LPS_WMT2D_MASK)
> +		dev_info(dev, "SNVS tamper: Wire Mesh 2\n");
> +	if (info->lps & LPS_WMT1D_MASK)
> +		dev_info(dev, "SNVS tamper: Wire Mesh 1\n");
> +	if (info->lps & LPS_VTD_MASK)
> +		dev_info(dev, "SNVS tamper: Voltage\n");
> +	if (info->lps & LPS_TTD_MASK)
> +		dev_info(dev, "SNVS tamper: Temperature\n");
> +	if (info->lps & LPS_CTD_MASK)
> +		dev_info(dev, "SNVS tamper: Clock\n");
> +	if (info->lps & LPS_PGD_MASK)
> +		dev_info(dev, "SNVS tamper: Power Glitch\n");
> +	if (info->lps & LPS_MCR_MASK)
> +		dev_info(dev, "SNVS tamper: Monotonic Counter rollover\n");
> +	if (info->lps & LPS_SRTCR_MASK)
> +		dev_info(dev, "SNVS tamper: Secure RTC rollover\n");
> +	if (info->lps & LPS_LPTA_MASK)
> +		dev_info(dev, "SNVS tamper: Time alarm\n");
> +
> +	if (info->lptds & LPTDS_ET10D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 10\n");
> +	if (info->lptds & LPTDS_ET9D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 9\n");
> +	if (info->lptds & LPTDS_ET8D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 8\n");
> +	if (info->lptds & LPTDS_ET7D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 7\n");
> +	if (info->lptds & LPTDS_ET6D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 6\n");
> +	if (info->lptds & LPTDS_ET5D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 5\n");
> +	if (info->lptds & LPTDS_ET4D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 4\n");
> +	if (info->lptds & LPTDS_ET3D_MASK)
> +		dev_info(dev, "SNVS tamper: Tamper 3\n");
> +
> +	return 0;
> +}
> +
> +static void if_imx_secvio_sc_disable_irq(void *dev)
> +{
> +	imx_secvio_sc_disable_irq(dev);
> +}
> +
> +static int imx_secvio_sc_open(struct inode *node, struct file *filp)
> +{
> +	filp->private_data = node->i_private;
> +
> +	return 0;
> +}
> +
> +static long imx_secvio_sc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> +	struct device *dev = file->private_data;
> +	struct secvio_sc_notifier_info info;
> +	int ret;
> +
> +	switch (cmd) {
> +	case IMX_SECVIO_SC_GET_STATE:
> +		ret = imx_secvio_sc_get_state(dev, &info);
> +		if (ret)
> +			return ret;
> +
> +		ret = copy_to_user((void __user *)arg, &info, sizeof(info));
> +		if (ret) {
> +			dev_err(dev, "Fail to copy info to user\n");
> +			return -EFAULT;
> +		}
> +		break;
> +	case IMX_SECVIO_SC_CHECK_STATE:
> +		ret = imx_secvio_sc_check_state(dev);
> +		if (ret)
> +			return ret;
> +		break;
> +	case IMX_SECVIO_SC_CLEAR_STATE:
> +		ret = copy_from_user(&info, (void __user *)arg, sizeof(info));
> +		if (ret) {
> +			dev_err(dev, "Fail to copy info from user\n");
> +			return -EFAULT;
> +		}
> +
> +		ret = imx_secvio_sc_clear_state(dev, info.hpsvs, info.lps,
> +						    info.lptds);
> +		if (ret)
> +			return ret;
> +		break;
> +	default:
> +		ret = -ENOIOCTLCMD;
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct file_operations imx_secvio_sc_fops = {
> +	.owner = THIS_MODULE,
> +	.open = imx_secvio_sc_open,
> +	.unlocked_ioctl = imx_secvio_sc_ioctl,
> +};
> +
> +static void if_misc_deregister(void *miscdevice)
> +{
> +	misc_deregister(miscdevice);
> +}
> +
> +int imx_scu_secvio_init(struct device *np)
> +{
> +	int ret;
> +
> +	scdev = np;
> +
> +	pdev = platform_device_alloc("imx-secvio-sc", -1);
> +	if (!pdev) {
> +		pr_err("%s: secvio: Failed to allocate secvio device\n", __func__);
> +		return -ENOMEM;
> +	}
> +
> +	ret = platform_device_add(pdev);
> +	if (ret != 0) {
> +		pr_err("%s: secvio: Failed to add secvio device\n", __func__);
> +		platform_device_put(pdev);
> +		return ret;
> +	}
> +
> +	ret = platform_driver_register(&imx_secvio_sc_driver);
> +	if (ret != 0) {
> +		pr_err("%s: secvio: Failed to register secvio driver\n", __func__);
> +		platform_device_unregister(pdev);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(imx_scu_secvio_init);

1. GPL
2. Init is always at the end which avoids your forward declarations

> +
> +static int imx_secvio_sc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct imx_secvio_sc_data *data;
> +	u32 seco_version = 0;
> +	bool own_secvio;
> +	u32 irq_status;
> +	int ret;
> +
> +	/* Allocate private data */
> +	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	if (!devres_open_group(dev, NULL, GFP_KERNEL))
> +		return -ENOMEM;
> +
> +	data->dev = dev;
> +
> +	dev_set_drvdata(dev, data);
> +
> +	data->nvmem = devm_nvmem_device_get(scdev, NULL);
> +	if (IS_ERR(data->nvmem)) {
> +		ret = PTR_ERR(data->nvmem);
> +
> +		if (ret != -EPROBE_DEFER)
> +			dev_err_probe(dev, ret, "Failed to retrieve nvmem\n");

Do not open-code dev_err_probe. Syntax is:
ret = dev_err_probe()


> +
> +		goto clean;
> +	}
> +
> +	/* Get a handle */
> +	ret = imx_scu_get_handle(&data->ipc_handle);
> +	if (ret) {
> +		dev_err(dev, "cannot get handle to scu: %d\n", ret);

dev_err_probe. Open the function and analyze whether it can defer
(although one would argue that even if it cannot defer you are supposed
to use dev_err_probe()).

> +		goto clean;
> +	}
> +
> +	/* Check the version of the SECO */
> +	ret = imx_sc_seco_build_info(data->ipc_handle, &seco_version, NULL);
> +	if (ret) {
> +		dev_err(dev, "Failed to get seco version\n");
> +		goto clean;
> +	}
> +
> +	if ((seco_version & SECO_VERSION_MINOR_MASK) <
> +	     SECO_MINOR_VERSION_SUPPORT_SECVIO_TAMPER) {
> +		dev_err(dev, "SECO version %.8x doesn't support all secvio\n",
> +			seco_version);
> +		ret = -EOPNOTSUPP;
> +		goto clean;
> +	}
> +
> +	/* Init debug FS */
> +	ret = imx_secvio_sc_debugfs(dev);
> +	if (ret) {
> +		dev_err(dev, "Failed to set debugfs\n");

debugfs errors are never a probe failure.

> +		goto clean;
> +	}
> +
> +	/* Check we own the SECVIO */
> +	ret = imx_sc_rm_is_resource_owned(data->ipc_handle, IMX_SC_R_SECVIO);
> +	if (ret < 0) {

This is not posible. Read the doc: 0 or 1.

> +		dev_err(dev, "Failed to retrieve secvio ownership\n");
> +		goto clean;
> +	}
> +
> +	own_secvio = ret > 0;
> +	if (!own_secvio) {
> +		dev_err(dev, "Secvio resource is not owned\n");
> +		ret = -EPERM;
> +		goto clean;
> +	}

Best regards,
Krzysztof



From krzk at kernel.org  Thu Dec  5 01:15:51 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 10:15:51 +0100
Subject: [PATCH v4 3/4] firmware: imx: Add SC APIs required for secvio
 module
In-Reply-To: <20241205-secvio-v4-3-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
 <20241205-secvio-v4-3-5c37cdc39573@nxp.com>
Message-ID: <bdwn6slol2pnpf25xmcyx6rro5jaiadpob5fvl45ngtru3bea3@pucfhsmsxrct>

On Thu, Dec 05, 2024 at 05:56:34AM +0100, Vabhav Sharma wrote:
> The Security Violation module requires below System Controller
> Security controller API to interact with SNVS block via SCFW
>     - imx_sc_seco_build_info
>     - imx_sc_seco_secvio_enable
>     - imx_sc_seco_secvio_config
>     - imx_sc_seco_secvio_dgo_config
> 
> Signed-off-by: Franck LENORMAND <franck.lenormand at nxp.com>
> Reviewed-by: Iuliana Prodan <iuliana.prodan at nxp.com>
> Reviewed-by: Horia Geanta<horia.geanta at nxp.com>
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> Signed-off-by: Vabhav Sharma <vabhav.sharma at nxp.com>
> ---
>  drivers/firmware/imx/Makefile         |   2 +-
>  drivers/firmware/imx/imx-scu.c        |   4 +-
>  drivers/firmware/imx/seco.c           | 216 ++++++++++++++++++++++++++++++++++
>  include/linux/firmware/imx/ipc.h      |   1 +
>  include/linux/firmware/imx/sci.h      |   4 +
>  include/linux/firmware/imx/svc/seco.h |  69 +++++++++++
>  6 files changed, 294 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
> index 8d046c341be8..7aaecf570c56 100644
> --- a/drivers/firmware/imx/Makefile
> +++ b/drivers/firmware/imx/Makefile
> @@ -1,4 +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_SCU)		+= imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o seco.o
>  obj-${CONFIG_IMX_SCMI_MISC_DRV}	+= sm-misc.o
> diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
> index 1dd4362ef9a3..c96dc73689a8 100644
> --- a/drivers/firmware/imx/imx-scu.c
> +++ b/drivers/firmware/imx/imx-scu.c
> @@ -242,9 +242,11 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
>  		 * APIs are defined as void function in SCU firmware, so they
>  		 * should be treated as return success always.
>  		 */
> -		if ((saved_svc == IMX_SC_RPC_SVC_MISC) &&
> +		if (((saved_svc == IMX_SC_RPC_SVC_MISC) &&
>  			(saved_func == IMX_SC_MISC_FUNC_UNIQUE_ID ||
>  			 saved_func == IMX_SC_MISC_FUNC_GET_BUTTON_STATUS))
> +			 || (saved_svc == IMX_SC_RPC_SVC_SECO &&
> +			 saved_func == IMX_SC_SECO_FUNC_BUILD_INFO))
>  			ret = 0;
>  	}
>  
> diff --git a/drivers/firmware/imx/seco.c b/drivers/firmware/imx/seco.c
> new file mode 100644
> index 000000000000..2d6bf301ac87
> --- /dev/null
> +++ b/drivers/firmware/imx/seco.c
> @@ -0,0 +1,216 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2020, 2024 NXP
> + *
> + * File containing client-side RPC functions for the SECO service. These
> + * function are ported to clients that communicate to the SC.
> + */
> +
> +#include <linux/firmware/imx/sci.h>
> +
> +struct imx_sc_msg_seco_get_build_id {
> +	struct imx_sc_rpc_msg hdr;
> +	u32 version;
> +	u32 commit;
> +} __packed __aligned(4);
> +
> +int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
> +			   uint32_t *commit)
> +{
> +	struct imx_sc_msg_seco_get_build_id msg;
> +	struct imx_sc_rpc_msg *hdr = &msg.hdr;
> +	int ret;
> +
> +	hdr->ver = IMX_SC_RPC_VERSION;
> +	hdr->svc = IMX_SC_RPC_SVC_SECO;
> +	hdr->func = IMX_SC_SECO_FUNC_BUILD_INFO;
> +	hdr->size = 1;
> +
> +	ret = imx_scu_call_rpc(ipc, &msg, true);
> +	if (ret)
> +		return ret;
> +
> +	if (version)
> +		*version = msg.version;
> +	if (commit)
> +		*commit = msg.commit;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(imx_sc_seco_build_info);


NAK for all your exports: no users. Stop adding exports for your
downstream drivers.

Best regards,
Krzysztof



From stanislawa.laskowska at agreementdeal.pl  Thu Dec  5 01:15:57 2024
From: stanislawa.laskowska at agreementdeal.pl (=?UTF-8?Q? Stanis=C5=82awa_Laskowska ?=)
Date: Thu,  5 Dec 2024 09:15:57 GMT
Subject: Kandydat do pracy
Message-ID: <20241205084500-0.1.4u.19amr.0.q2sotq2092@agreementdeal.pl>

Dzie? dobry,

delegujemy sprawdzone osoby ze Wschodu do pracy w firmach produkcyjnych do prostych prac przy produkcji, na magazynie, przy pakowaniu towaru czy kontroli jako?ci. 

Nasza firma organizuje wszelkie formalno?ci oraz zakwaterowanie, co pozwala zmniejszy? koszty po Pa?stwa stronie.

Czy mog? przedstawi? szczeg??y?


Pozdrawiam
Stanis?awa Laskowska


From krzk at kernel.org  Thu Dec  5 01:17:13 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 10:17:13 +0100
Subject: [PATCH v4 0/4] firmware: imx: secvio: Add secvio support
In-Reply-To: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-0-5c37cdc39573@nxp.com>
Message-ID: <qgh5pzcjlke55eszovjfa3xs4icepcwz7dpfalgo2p6xyv4yei@xmgofqph4yph>

On Thu, Dec 05, 2024 at 05:56:31AM +0100, Vabhav Sharma wrote:
> The tampers are security feature available on i.MX products and
> managed by SNVS block.The tamper goal is to detect the variation
> of hardware or physical parameters, which can indicate an attack.
> 
> The SNVS, which provides secure non-volatile storage, allows to
> detect some hardware attacks against the SoC.They are connected
> to the security-violation ports, which send an alert when an
> out-of-range value is detected.
> 
> This detection is done by:
> -Analog tampers: measure analogic values
> 	- External clock frequency.
> 	- Temperature.
> 	- Voltage.
> 
> - Digital tampers:
> 	- External tamper
> 	- Other detectors:
> 		- Secure real-time counter rollover tamper.
> 		- Monotonic counter rollover tamper.
> 		- Power supply glitch tamper.
> 
> The on-chip sensors for voltage, temperature, and clock frequency
> indicate if tamper scenarios may be present. These sensors generate an
> out-of-range signal that causes a security violation to clear the
> authentication and storage keys and to block access to sensitive
> information.
> 
> Add linux module secvio driver to handle security violation interrupt.
> 
> The "imx-secvio-sc" module is designed to report security violations
> and tamper triggering to the user.
> 
> The functionalities of the module are accessible via the "debugfs"
> kernel.The folder containing the interface files for the module is
> "<kernel_debugfs>/secvio/".


Debugfs is for debugging, not accessing functions. Come with proper
sysfs or other control interface and its ABI, not debugging one to avoid
any review.

Best regards,
Krzysztof



From linux at fw-web.de  Thu Dec  5 01:18:34 2024
From: linux at fw-web.de (Frank Wunderlich (linux))
Date: Thu, 05 Dec 2024 10:18:34 +0100
Subject: [PATCH v5 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <6ebd58fd-8461-476c-9266-a21455d5e819@kernel.org>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-4-linux@fw-web.de>
 <iwmnxlqpaijvr4kmzwk3elacqj5ukqlchfs67ca6c6gxrycpbb@pc6a6scqkdi5>
 <1DBA844B-4DB2-4AA2-BF04-B3CC39B3C3F8@public-files.de>
 <6ebd58fd-8461-476c-9266-a21455d5e819@kernel.org>
Message-ID: <6926509bd56cbb32125a978c939b28ab@fw-web.de>

Am 2024-12-05 08:35, schrieb Krzysztof Kozlowski:
> On 04/12/2024 08:41, Frank Wunderlich wrote:
>> Am 4. Dezember 2024 08:35:37 MEZ schrieb Krzysztof Kozlowski 
>> <krzk at kernel.org>:
>>> On Mon, Dec 02, 2024 at 12:00:37PM +0100, Frank Wunderlich wrote:
>>>> From: Frank Wunderlich <frank-w at public-files.de>
>>>> 
>>>> This adds bindings for MT7988 pinctrl driver.
>>>> 
>>>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>>>> ---
>>>> changes in v5 (so not adding RB from Rob given in v4):
>>>> - do not use MTK_DRIVE_8mA in example
>>>> - add _0 functions for pwm
>>>> 
>>> 
>>> <form letter>
>>> 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.
>>> </form letter>
>> 
>> Is this an automatic message? I guess yes...
>> 
>> I have not added it (robs reviewed-by) from v4 due to changes and 
>> explained why in changelog. If i'm wrong please let me know.
> 
> Where did you explain the reason of dropping review tag? This has to be
> *EXPLICIT* but I only see:
> 
> - rebased to 6.13-rc1
> - moved dt nodes with mutliple options to BPI-R4 board
> - changes suggested by angelo in v4
> - changed example in binding and dt node to not using const 
> MTK_DRIVE_8mA
> 
> 
> Nothing here suggests even remotely that review tag was dropped. 
> Nothing
> suggests that it should be dropped!

here:
>>>> changes in v5 (so not adding RB from Rob given in v4):


> Best regards,
> Krzysztof


From 0x1207 at gmail.com  Thu Dec  5 01:18:30 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Thu,  5 Dec 2024 17:18:30 +0800
Subject: [PATCH net v1] net: stmmac: TSO: Fix unaligned DMA unmap for non-paged SKB data
Message-ID: <20241205091830.3719609-1-0x1207@gmail.com>

Commit 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap for
non-paged SKB data") assigns a wrong DMA buffer address that is added an
offset of proto_hdr_len to tx_q->tx_skbuff_dma[entry].buf on a certain
platform that the DMA AXI address width is configured to 40-bit/48-bit,
stmmac_tx_clean() will try to unmap this illegal DMA buffer address
and many crashes are reported: [1] [2].

This patch guarantees that DMA address is passed to stmmac_tx_clean()
unmodified and without offset.

[1] https://lore.kernel.org/all/d8112193-0386-4e14-b516-37c2d838171a at nvidia.com/
[2] https://lore.kernel.org/all/klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc at bwwhelz2l4dw/

Reported-by: Jon Hunter <jonathanh at nvidia.com>
Reported-by: Thierry Reding <thierry.reding at gmail.com>
Suggested-by: Russell King (Oracle) <linux at armlinux.org.uk>
Fixes: 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data")
Signed-off-by: Furong Xu <0x1207 at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9b262cdad60b..7227f8428b5e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4192,8 +4192,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct stmmac_txq_stats *txq_stats;
 	struct stmmac_tx_queue *tx_q;
 	u32 pay_len, mss, queue;
+	dma_addr_t tso_hdr, des;
 	u8 proto_hdr_len, hdr;
-	dma_addr_t des;
 	bool set_ic;
 	int i;
 
@@ -4279,6 +4279,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 			     DMA_TO_DEVICE);
 	if (dma_mapping_error(priv->device, des))
 		goto dma_map_err;
+	tso_hdr = des;
 
 	if (priv->dma_cap.addr64 <= 32) {
 		first->des0 = cpu_to_le32(des);
@@ -4310,7 +4311,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	 * this DMA buffer right after the DMA engine completely finishes the
 	 * full buffer transmission.
 	 */
-	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
+	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = tso_hdr;
 	tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
 	tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
 	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
-- 
2.34.1



From gregkh at linuxfoundation.org  Thu Dec  5 01:27:33 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 5 Dec 2024 10:27:33 +0100
Subject: [PATCH 6.12 470/826] perf stat: Uniquify event name improvements
In-Reply-To: <deb83bf5-2342-479c-b1bd-7f8c49f5b1d4@linaro.org>
References: <20241203144743.428732212@linuxfoundation.org>
 <20241203144802.097952233@linuxfoundation.org>
 <f2ada8a7-165b-41fb-8b7b-3c0d16bb8216@leemhuis.info>
 <deb83bf5-2342-479c-b1bd-7f8c49f5b1d4@linaro.org>
Message-ID: <2024120517-reason-icing-8e77@gregkh>

On Thu, Dec 05, 2024 at 08:54:15AM +0000, James Clark wrote:
> 
> 
> On 03/12/2024 5:24 pm, Thorsten Leemhuis wrote:
> > On 03.12.24 15:43, Greg Kroah-Hartman wrote:
> > > 6.12-stable review patch.  If anyone has any objections, please let me know.
> > > 
> > > ------------------
> > > 
> > > From: Ian Rogers <irogers at google.com>
> > > 
> > > [ Upstream commit 057f8bfc6f7070577523d1e3081081bbf4229c1c ]
> > > 
> > > Without aggregation on Intel:
> > 
> > My 6.11.y-rc and 6.12.y-rc builds for Fedora failed when building perf.
> > I did not bisect, but from a brief look at the error message (see
> > below) I suspect it might be caused by this patch, which is the
> > second of the patch-set "Event parsing fixes":
> > https://lore.kernel.org/all/20240926144851.245903-1-james.clark at linaro.org/
> > 
> > To my untrained eyes and from a quick look I guess the first patch
> > in the series needs to be backported as well:
> > perf evsel: Add alternate_hw_config and use in evsel__match
> > https://lore.kernel.org/all/20240926144851.245903-2-james.clark at linaro.org/
> > 
> > This is 22a4db3c36034e ("perf evsel: Add alternate_hw_config
> > and use in evsel__match") in mainline. I tried to cherry-pick it
> > on-top of 6.12.2-rc1, but there were a few small conflicts.
> > 
> > Ciao, Thorsten
> > 
> 
> Yes I imagine both commits are required. Another option is to not backport
> this one. It looks like it's mainly to fix a test, nothing is missing or
> wrong from the output, just the formatting is off.


Thanks, I'll just drop this patch from the stable queue for now.

greg k-h


From angelogioacchino.delregno at collabora.com  Thu Dec  5 01:28:43 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 10:28:43 +0100
Subject: [PATCH v1 7/7] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <8c34c5a6cc2217ffc1a2d9881f20708e8427ffe6.camel@mediatek.com>
References: <20241120124512.134278-1-angelogioacchino.delregno@collabora.com>
 <20241120124512.134278-8-angelogioacchino.delregno@collabora.com>
 <559ac08df6614e47c3e8d9d8160b35c9e683c503.camel@mediatek.com>
 <716b8630-66ef-4497-8cba-d5d20da2382a@collabora.com>
 <6bba26909f2fe0686c2584536f7a080451f768a1.camel@mediatek.com>
 <8c34c5a6cc2217ffc1a2d9881f20708e8427ffe6.camel@mediatek.com>
Message-ID: <5cbf569c-7288-48bd-8958-dcdd29b0aa20@collabora.com>

Il 05/12/24 03:48, CK Hu (???) ha scritto:
> On Thu, 2024-12-05 at 10:42 +0800, CK Hu wrote:
>> On Wed, 2024-12-04 at 15:44 +0100, AngeloGioacchino Del Regno wrote:
>>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>>
>>>
>>> Il 02/12/24 08:27, CK Hu (???) ha scritto:
>>>> Hi, Angelo:
>>>>
>>>> On Wed, 2024-11-20 at 13:45 +0100, AngeloGioacchino Del Regno wrote:
>>>>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>>>>
>>>>>
>>>>> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
>>>>> found in MediaTek's MT8195, MT8188 SoC and their variants, and
>>>>> including support for display modes up to 4k60 and for HDMI
>>>>> Audio, as per the HDMI 2.0 spec.
>>>>>
>>>>> HDCP and CEC functionalities are also supported by this hardware,
>>>>> but are not included in this commit.
>>>>>
>>>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>>>> ---
>>>>
>>>> [snip]
>>>>
>>>>> +static int mtk_hdmi_v2_enable(struct mtk_hdmi *hdmi)
>>>>> +{
>>>>> +       int ret;
>>>>> +
>>>>> +       ret = pm_runtime_resume_and_get(hdmi->dev);
>>>>
>>>> Why turn on power when attach?
>>>> Should hot-plug detection be always on so power on when attach?
>>>> If so, maybe we need to use CEC to detect hot-plug because CEC has lower power and HDMI power would not be always on.
>>>> As you describe previously, CEC just need some hack to support both HDMI Tx and HDMI Rx.
>>>> So there is a software solution to use CEC to detect hot-plug in a lower power mode.
>>>> And v1 use CEC to detect hot-plug, so it's worth to make v1 and v2 has the same behavior.
>>>>
>>>
>>> As I said, we can't use CEC to detect hotplug, because the same CEC controller
>>> can be used for both HDMI TX and RX at the same time.
>>>
>>> If you use CEC to detect cable attach and you have both HDMI RX and HDMI TX drivers
>>> probed and ready, if you attach the cable to HDMI RX port, HDMI TX will try to get
>>> enabled and will error out.
>>> Same happens if you attach a cable to HDMI TX: HDMI RX will try to get enabled and
>>> will error out.
>>>
>>> The only way to use CEC for hotplug detection is to detect twice: CEC for HDMI
>>> TX/RX controllers wakeup, then reset both, wait for autodetect in both controllers,
>>> suppress errors, and start signal transmit or receive.
>>>
>>> While it is technically possible to do so, it's very complicated and hacky.
>>>
>>> Please keep in mind that on the new SoCs (8188/8195) the CEC block is different
>>> from the one in the old SoCs (6795, 8173, etc) and requires an entirely new driver
>>> to get it working.
>>>
>>> Using CEC for hotplug detection would mean that we need 3 full drivers:
>>> 1. HDMI TX
>>> 2. HDMI RX
>>> 3. CEC
>>>
>>> This is because the CEC is shared, so we need to have all three to properly test
>>> the functionality - and this is not possible to do all at once.
>>>
>>> To save some power (not much, though!), we can eventually go for your proposed
>>> CEC detection *in the future*, but really not right now - and we can do that only
>>> after upstreaming both HDMI TX and HDMI RX drivers.
>>>
>>> The plan (time/effort pemitting!) would look like this:
>>>
>>> Series 1 - Upstream HDMIv2 TX (HPD through HDMIv2 TX controller) - drivers/gpu/drm
>>> Series 2 - Upstream HDMIv2 RX (HPD through HDMIv2 RX controller) - drivers/media
>>> Series 3 - Upstream CEC driver (No HPD in CEC)                   - drivers/media
>>> Series 4 - Implement HPD in CEC and use it in HDMIv2 TX and HDMIv2 RX - media,drm
>>>
>>> You can see how complicated this is - and I'm sure that you understand why that
>>> cannot be done all at once.
>>>
>>> Adding up some: the HDMI driver is used only on IoT boards for now, which typically
>>> run off AC and not battery - so the (again) very little power consumption raise is
>>> not critical for now.
>>
>> If you plan to upstream HDMI RX driver recently, it's OK not using CEC to detect hot-plug.
>> But for any behavior which is different with v1 and it's related to CEC, add comment about CEC.
> 
> In here, describe more about the power.
> Chromebook may need HDMI TX driver and its power is from battery.
> Maybe Googler would be interested in low power behavior.
> 

There's no Chromebook with HDMI TX, only DP.

The only boards exposing the HDMI connector routed through the HDMI TX Controller
are:
  - Radxa NIO 12L  (MT8195)
  - Genio 1200 EVK (MT8195)
  - Genio 700 EVK  (MT8188)

Should a Chromebook featuring HDMI TX appear, we can go with heavy power related
optimization later, there's no problem (besides, again, it's about some microamps
and nothing more).

The power consumption was measured with a Joulescope JS110 on the Genio 700 EVK.
I didn't save the current measurement values, and I peformed those 3 weeks ago
so I don't remember the exact values - what I remember is that there was a
difference of microamps (18650 battery 4.2V -> JS110 -> board), but nothing more.

Cheers,
Angelo

> Regards,
> CK
> 
>>
>> Regards,
>> CK
>>
>>>
>>> Cheers,
>>> Angelo
>>>
>>>> Regards,
>>>> CK
>>>>
>>>>
>>>>> +       if (ret) {
>>>>> +               dev_err(hdmi->dev, "Cannot resume HDMI\n");
>>>>> +               return ret;
>>>>> +       }
>>>>> +
>>>>> +       mtk_hdmi_v2_clk_enable(hdmi);
>>>>> +       mtk_hdmi_hw_reset(hdmi);
>>>>> +       mtk_hdmi_set_sw_hpd(hdmi, true);
>>>>> +
>>>>> +       return 0;
>>>>> +}
>>>>> +
> 



From 0x1207 at gmail.com  Thu Dec  5 01:34:31 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Thu, 5 Dec 2024 17:34:31 +0800
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap
 for non-paged SKB data
In-Reply-To: <Z1CVRzWcSDuPyQZe@shell.armlinux.org.uk>
References: <20241128144501.0000619b@gmail.com>
	<20241202163309.05603e96@kernel.org>
	<20241203100331.00007580@gmail.com>
	<20241202183425.4021d14c@kernel.org>
	<20241203111637.000023fe@gmail.com>
	<klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
	<df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>
	<2g2lp3bkadc4wpeslmdoexpidoiqzt7vejar5xhjx5ayt3uox3@dqdyfzn6khn6>
	<Z1CFz7GpeIzkDro1@shell.armlinux.org.uk>
	<9719982a-d40c-4110-9233-def2e6cb4d74@nvidia.com>
	<Z1CVRzWcSDuPyQZe@shell.armlinux.org.uk>
Message-ID: <20241205173431.0000779e@gmail.com>

Hi Russell,

On Wed, 4 Dec 2024 17:45:43 +0000, "Russell King (Oracle)" <linux at armlinux.org.uk> wrote:
> So yes, "des" is being offset, which will upset the unmap operation.
> Please try the following patch, thanks:
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 9b262cdad60b..c81ea8cdfe6e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4192,8 +4192,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  	struct stmmac_txq_stats *txq_stats;
>  	struct stmmac_tx_queue *tx_q;
>  	u32 pay_len, mss, queue;
> +	dma_addr_t tso_des, des;
>  	u8 proto_hdr_len, hdr;
> -	dma_addr_t des;
>  	bool set_ic;
>  	int i;
>  
> @@ -4289,14 +4289,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  
>  		/* If needed take extra descriptors to fill the remaining payload */
>  		tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
> +		tso_des = des;
>  	} else {
>  		stmmac_set_desc_addr(priv, first, des);
>  		tmp_pay_len = pay_len;
> -		des += proto_hdr_len;
> +		tso_des = des + proto_hdr_len;
>  		pay_len = 0;
>  	}
>  
> -	stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
> +	stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
>  
>  	/* In case two or more DMA transmit descriptors are allocated for this
>  	 * non-paged SKB data, the DMA buffer address should be saved to
> 

Much appreciated for your comments and suggestions, I sent a new patch to fix
this issue. Please let me know if you have any new advice.
https://lore.kernel.org/netdev/20241205091830.3719609-1-0x1207 at gmail.com/

Thanks,
Furong


From bryan.odonoghue at linaro.org  Thu Dec  5 01:35:33 2024
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Thu, 5 Dec 2024 09:35:33 +0000
Subject: [PATCH v7 4/5] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <20241204100003.300123-5-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-5-quic_vikramsa@quicinc.com>
Message-ID: <51d340e1-a62a-4851-a2be-545580bf4088@linaro.org>

On 04/12/2024 10:00, Vikram Sharma wrote:
> Add changes to support the camera subsystem on the SC7280.
> 
> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> ---
>   arch/arm64/boot/dts/qcom/sc7280.dtsi | 172 +++++++++++++++++++++++++++
>   1 file changed, 172 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> index 55db1c83ef55..e363996602d6 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>


From linux at armlinux.org.uk  Thu Dec  5 01:42:07 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 5 Dec 2024 09:42:07 +0000
Subject: [PATCH net-next 0/3] net: net: add negotiation of in-band
 capabilities (remainder)
Message-ID: <Z1F1b8eh8s8T627j@shell.armlinux.org.uk>

Hi,

Here are the last three patches which were not included in the non-RFC
posting, but were in the RFC posting. These add the .pcs_inband()
method to the Lynx, MTK Lynx and XPCS drivers.

 drivers/net/pcs/pcs-lynx.c      | 22 ++++++++++++++++++++++
 drivers/net/pcs/pcs-mtk-lynxi.c | 16 ++++++++++++++++
 drivers/net/pcs/pcs-xpcs.c      | 28 ++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+)

-- 
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  Thu Dec  5 01:42:29 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 05 Dec 2024 09:42:29 +0000
Subject: [PATCH net-next 2/3] net: pcs: pcs-mtk-lynxi: implement
 pcs_inband_caps() method
In-Reply-To: <Z1F1b8eh8s8T627j@shell.armlinux.org.uk>
References: <Z1F1b8eh8s8T627j@shell.armlinux.org.uk>
Message-ID: <E1tJ8NR-006L5P-E3@rmk-PC.armlinux.org.uk>

Report the PCS in-band capabilities to phylink for the LynxI PCS.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/pcs/pcs-mtk-lynxi.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 4f63abe638c4..7de804535229 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -88,6 +88,21 @@ static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
 	return container_of(pcs, struct mtk_pcs_lynxi, pcs);
 }
 
+static unsigned int mtk_pcs_lynxi_inband_caps(struct phylink_pcs *pcs,
+					      phy_interface_t interface)
+{
+	switch (interface) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_QSGMII:
+		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+
+	default:
+		return 0;
+	}
+}
+
 static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
 				    struct phylink_link_state *state)
 {
@@ -241,6 +256,7 @@ static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs)
 }
 
 static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
+	.pcs_inband_caps = mtk_pcs_lynxi_inband_caps,
 	.pcs_get_state = mtk_pcs_lynxi_get_state,
 	.pcs_config = mtk_pcs_lynxi_config,
 	.pcs_an_restart = mtk_pcs_lynxi_restart_an,
-- 
2.30.2



From andrej.picej at norik.com  Thu Dec  5 01:45:47 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu, 5 Dec 2024 10:45:47 +0100
Subject: [PATCH v3 1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add
 properties for ti,lvds-vod-swing
In-Reply-To: <vgg3bygtmj6sotatddkqfapset5bofsqvkzuj7ejuvomn6hs3n@mscq2jbhtaux>
References: <20241203110054.2506123-1-andrej.picej@norik.com>
 <20241203110054.2506123-2-andrej.picej@norik.com>
 <vgg3bygtmj6sotatddkqfapset5bofsqvkzuj7ejuvomn6hs3n@mscq2jbhtaux>
Message-ID: <be973fe9-ac7a-4904-923e-93f87c9ff615@norik.com>

Hi Krzysztof,

On 4. 12. 24 08:54, Krzysztof Kozlowski wrote:
> On Tue, Dec 03, 2024 at 12:00:52PM +0100, Andrej Picej wrote:
>> Add properties which can be used to specify LVDS differential output
>> voltage. Since this also depends on near-end signal termination also
>> include property which sets this. LVDS differential output voltage is
>> specified with an array (min, max), which should match the one from
>> connected device.
>>
>> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
>> ---
>> Changes in v3:
>> - no change
> 
> 
> One version of patchset per 24h.

understood.

> 
>> Changes in v2:
>> - move LVDS port schema to a $defs and reference it from there
>> - properties are now defined in microvolts/ohms
>> - use 1 property for data-lane and 1 for clock-lane LVDS voltage swing
>> - add 1 property which sets LVDS near-end termination
>> - since major change was done change the authorship to myself
>> ---
>>   .../bindings/display/bridge/ti,sn65dsi83.yaml | 36 +++++++++++++++++--
>>   1 file changed, 33 insertions(+), 3 deletions(-)
> 
> ...
> 
>>   allOf:
>>     - if:
>>         properties:
>> @@ -120,7 +150,7 @@ allOf:
>>             properties:
>>               port at 1: false
>>   
>> -additionalProperties: false
>> +additionalProperties: true
> 
> This cannot be true. Not explained in commit msg and this is not shared
> schema.

You are right. Will remove it in next iteration.

Best regards,
Andrej

> 
>>   
>>   examples:
>>     - |
>> -- 
>> 2.34.1
>>


From bryan.odonoghue at linaro.org  Thu Dec  5 01:53:15 2024
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Thu, 5 Dec 2024 09:53:15 +0000
Subject: [PATCH v7 1/5] media: dt-bindings: Add qcom,sc7280-camss
In-Reply-To: <20241204100003.300123-2-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-2-quic_vikramsa@quicinc.com>
Message-ID: <02a2660f-b577-42b5-9c3d-4fb0429d8c67@linaro.org>

On 04/12/2024 09:59, Vikram Sharma wrote:
> Add bindings for qcom,sc7280-camss to support the camera subsystem
> on the SC7280 platform.
> 
> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>


From matthias.fend at emfend.at  Thu Dec  5 01:52:55 2024
From: matthias.fend at emfend.at (Matthias Fend)
Date: Thu, 5 Dec 2024 10:52:55 +0100
Subject: [PATCH] media: dt-bindings: sony,imx415: add required clock-names
 property
In-Reply-To: <bh3obpt6bcklejdvrk4r6ienraz5zmhrdyotijhvlwexussqgj@hicmx34vi27w>
References: <20241130141716.1007115-1-matthias.fend@emfend.at>
 <bh3obpt6bcklejdvrk4r6ienraz5zmhrdyotijhvlwexussqgj@hicmx34vi27w>
Message-ID: <90ec4241-c8d2-452a-a7c3-e983e5df1872@emfend.at>

Hi Krzysztof,

Am 02.12.2024 um 08:56 schrieb Krzysztof Kozlowski:
> On Sat, Nov 30, 2024 at 03:17:15PM +0100, Matthias Fend wrote:
>> The imx415 driver expects a clock with the name "inck".
>> Document this in the bindings.
> 
> No, fix the driver instead of bypassing review. It was decided to drop
> it during review, so you cannot reintroduce it 2 years later claiming
> that's now ABI. Of course original submission was buggy and never
> tested, but that does not allow review bypass.

Sorry. I discovered this by accident when I was using a copy of the DT 
snippet and realized it doesn't work that way.
I wasn't aware that this was intentionally removed (at least partially) 
during the review discussion...

Best regards
  ~Matthias

> 
> Best regards,
> Krzysztof
> 



From andrej.picej at norik.com  Thu Dec  5 01:55:18 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu, 5 Dec 2024 10:55:18 +0100
Subject: [PATCH v3 2/3] drm/bridge: ti-sn65dsi83: Add ti, lvds-vod-swing
 optional properties
In-Reply-To: <sjcspny5lmynm4q2dnkhktvwte5e3gigtujynaiqp5gr5rkqfn@j2h5f6xiwz34>
References: <20241203110054.2506123-1-andrej.picej@norik.com>
 <20241203110054.2506123-3-andrej.picej@norik.com>
 <sjcspny5lmynm4q2dnkhktvwte5e3gigtujynaiqp5gr5rkqfn@j2h5f6xiwz34>
Message-ID: <6fd4d9e6-b457-4e7a-acb8-4dbcd270a7f9@norik.com>

Hi Dmitry,

On 3. 12. 24 18:26, Dmitry Baryshkov wrote:
> On Tue, Dec 03, 2024 at 12:00:53PM +0100, Andrej Picej wrote:
>> Add a optional properties to change LVDS output voltage. This should not
>> be static as this depends mainly on the connected display voltage
>> requirement. We have three properties:
>> - "ti,lvds-termination-ohms", which sets near end termination,
>> - "ti,lvds-vod-swing-data-microvolt" and
>> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
>> output voltage for data and clock lanes. They are defined as an array
>> with min and max values. The appropriate bitfiled will be set if
>> selected constraints can be met.
>>
>> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
>> end termination will be used. Selecting only one:
>> "ti,lvds-vod-swing-data-microvolt" or
>> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
>> constraint for only data/clock lanes will be met. Setting both is
>> recommended.
>>
>> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
>> ---
>> Changes in v3:
>> - use microvolts for default array values 1000 mV -> 1000000 uV.
>> Changes in v2:
>> - use datasheet tables to get the proper configuration
>> - since major change was done change the authorship to myself
>> ---
>>   drivers/gpu/drm/bridge/ti-sn65dsi83.c | 144 +++++++++++++++++++++++++-
>>   1 file changed, 141 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>> index 57a7ed13f996..1a070df5ea12 100644
>> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>> @@ -132,6 +132,16 @@
>>   #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>>   #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>>   
>> +enum sn65dsi83_channel {
>> +	CHANNEL_A,
>> +	CHANNEL_B
>> +};
>> +
>> +enum sn65dsi83_lvds_term {
>> +	OHM_100,
>> +	OHM_200
>> +};
>> +
>>   enum sn65dsi83_model {
>>   	MODEL_SN65DSI83,
>>   	MODEL_SN65DSI84,
>> @@ -147,6 +157,10 @@ struct sn65dsi83 {
>>   	struct regulator		*vcc;
>>   	bool				lvds_dual_link;
>>   	bool				lvds_dual_link_even_odd_swap;
>> +	int				lvdsA_vod_swing_conf;
>> +	int				lvdsB_vod_swing_conf;
>> +	int				lvdsA_term_conf;
>> +	int				lvdsB_term_conf;
>>   };
>>   
>>   static const struct regmap_range sn65dsi83_readable_ranges[] = {
>> @@ -237,6 +251,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>>   	.max_register = REG_IRQ_STAT,
>>   };
>>   
>> +static const int lvds_vod_swing_data_table[2][4][2] = {
>> +	{	/* 100 Ohm */
>> +		{ 180000, 313000 },
>> +		{ 215000, 372000 },
>> +		{ 250000, 430000 },
>> +		{ 290000, 488000 },
>> +	},
>> +	{	/* 200 Ohm */
>> +		{ 150000, 261000 },
>> +		{ 200000, 346000 },
>> +		{ 250000, 428000 },
>> +		{ 300000, 511000 },
>> +	},
>> +};
>> +
>> +static const int lvds_vod_swing_clock_table[2][4][2] = {
>> +	{	/* 100 Ohm */
>> +		{ 140000, 244000 },
>> +		{ 168000, 290000 },
>> +		{ 195000, 335000 },
>> +		{ 226000, 381000 },
>> +	},
>> +	{	/* 200 Ohm */
>> +		{ 117000, 204000 },
>> +		{ 156000, 270000 },
>> +		{ 195000, 334000 },
>> +		{ 234000, 399000 },
>> +	},
>> +};
>> +
>>   static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>>   {
>>   	return container_of(bridge, struct sn65dsi83, bridge);
>> @@ -435,12 +479,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>>   		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>>   
>>   	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
>> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
>> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
>> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvdsA_vod_swing_conf) |
>> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvdsB_vod_swing_conf));
>>   	regmap_write(ctx->regmap, REG_LVDS_LANE,
>>   		     (ctx->lvds_dual_link_even_odd_swap ?
>>   		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
>> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
>> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
>> +		     (ctx->lvdsA_term_conf ?
>> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
>> +		     (ctx->lvdsB_term_conf ?
>> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>>   	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>>   
>>   	le16val = cpu_to_le16(mode->hdisplay);
>> @@ -576,10 +624,96 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>>   	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>>   };
>>   
>> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
>> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i <= 3; i++) {
>> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
>> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
>> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
>> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
>> +			return i;
>> +	}
>> +
>> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
>> +	return -EINVAL;
>> +}
>> +
>> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
>> +{
>> +	struct device *dev = ctx->dev;
>> +	struct device_node *endpoint;
>> +	/* Set so the property can be freely selected if not defined */
>> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
>> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
>> +	u32 lvds_term = 200;
>> +	u8 lvds_term_conf;
>> +	int endpoint_reg;
>> +	int lvds_vod_swing_conf;
>> +	int ret = 0;
>> +	int ret_data;
>> +	int ret_clock;
>> +
>> +	if (channel == CHANNEL_A)
>> +		endpoint_reg = 2;
>> +	else
>> +		endpoint_reg = 3;
>> +
>> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
>> +	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
>> +
>> +	if (lvds_term == 200)
>> +		lvds_term_conf = OHM_200;
>> +	else
>> +		lvds_term_conf = OHM_100;
>> +
>> +	if (channel == CHANNEL_A)
>> +		ctx->lvdsA_term_conf = lvds_term_conf;
>> +	else
>> +		ctx->lvdsB_term_conf = lvds_term_conf;
> 
> This sounds like ctx->lvds_term_conf[channel] = ...;
> 
> And so on for other properties.

correct, this might simplify the code. Will include it in next patch 
iteration.

> 
>> +
>> +	ret_data = of_property_read_u32_array(endpoint,
>> +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
>> +			ARRAY_SIZE(lvds_vod_swing_data));
>> +	ret_clock = of_property_read_u32_array(endpoint,
>> +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
>> +			ARRAY_SIZE(lvds_vod_swing_clk));
>> +	/* If any of the two properties is defined. */
>> +	if (!ret_data || !ret_clock) {
> 
> I think it's not that easy. We were usually ignoring errors for a
> single-value properties, but for the arrays I think we should make a
> diffence between the property being not present in DT and the property
> being erroneous or not being parsed correctly.

Ok, no problem. I'll add additional checks on return values and err out 
if return value is anything else then 0 or -EINVAL.

Best regards,
Andrej

> 
>> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
>> +			lvds_vod_swing_data, lvds_vod_swing_clk,
>> +			lvds_term_conf);
>> +		if (lvds_vod_swing_conf < 0) {
>> +			ret = lvds_vod_swing_conf;
>> +			goto exit;
>> +		}
>> +		if (channel == CHANNEL_A)
>> +			ctx->lvdsA_vod_swing_conf = lvds_vod_swing_conf;
>> +		else
>> +			ctx->lvdsB_vod_swing_conf = lvds_vod_swing_conf;
>> +	}
>> +	ret = 0;
>> +exit:
>> +	of_node_put(endpoint);
>> +	return ret;
>> +}
>> +
>>   static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>>   {
>>   	struct drm_bridge *panel_bridge;
>>   	struct device *dev = ctx->dev;
>> +	int ret;
>> +
>> +	ctx->lvdsA_vod_swing_conf = 0x1;
>> +	ctx->lvdsB_vod_swing_conf = 0x1;
>> +	ctx->lvdsA_term_conf = 0x1;
>> +	ctx->lvdsB_term_conf = 0x1;
>> +
>> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
>> +	if (ret < 0)
>> +		return ret;
>>   
>>   	ctx->lvds_dual_link = false;
>>   	ctx->lvds_dual_link_even_odd_swap = false;
>> @@ -587,6 +721,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>>   		struct device_node *port2, *port3;
>>   		int dual_link;
>>   
>> +		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
>> +		if (ret < 0)
>> +			return ret;
>> +
>>   		port2 = of_graph_get_port_by_id(dev->of_node, 2);
>>   		port3 = of_graph_get_port_by_id(dev->of_node, 3);
>>   		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
>> -- 
>> 2.34.1
>>
> 


From dharma.b at microchip.com  Thu Dec  5 01:57:02 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Thu, 5 Dec 2024 15:27:02 +0530
Subject: [PATCH] dt-bindings: mmc: atmel,hsmci: Convert to json schema
Message-ID: <20241205-hsmci-v1-1-5a25e622dfed@microchip.com>

Convert atmel,hsmci documentation to yaml format. The new file will inherit
from mmc-controller.yaml.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
 .../devicetree/bindings/mmc/atmel,hsmci.yaml       | 124 +++++++++++++++++++++
 .../devicetree/bindings/mmc/atmel-hsmci.txt        |  73 ------------
 2 files changed, 124 insertions(+), 73 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml b/Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml
new file mode 100644
index 000000000000..3870d464faa8
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mmc/atmel,hsmci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel High-Speed MultiMedia Card Interface (HSMCI)
+
+description:
+  The Atmel HSMCI controller provides an interface for MMC, SD, and SDIO memory
+  cards.
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Aubin Constans <aubin.constans at microchip.com>
+
+allOf:
+  - $ref: mmc-controller.yaml
+
+properties:
+  compatible:
+    const: atmel,hsmci
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  dmas:
+    maxItems: 1
+
+  dma-names:
+    const: rxtx
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: mci_clk
+
+  "#address-cells":
+    const: 1
+    description: Used for slot IDs.
+
+  "#size-cells":
+    const: 0
+
+patternProperties:
+  "^slot@[0-9]+$":
+    type: object
+    description: A slot node representing an MMC, SD, or SDIO slot.
+
+    allOf:
+      - $ref: mmc-controller.yaml
+
+    properties:
+      reg:
+        description: Slot ID.
+        minimum: 0
+
+      bus-width:
+        description: Number of data lines connected to the controller.
+        enum: [1, 4, 8]
+
+      cd-gpios:
+        description: GPIO used for card detection.
+
+      cd-inverted:
+        type: boolean
+        description: Inverts the value of the card detection GPIO.
+
+      wp-gpios:
+        description: GPIO used for write protection.
+
+    required:
+      - reg
+      - bus-width
+
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - "#address-cells"
+  - "#size-cells"
+
+anyOf:
+  - required:
+      - slot at 0
+  - required:
+      - slot at 1
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/at91.h>
+    mmc at f0008000 {
+      compatible = "atmel,hsmci";
+      reg = <0xf0008000 0x600>;
+      interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&mci0_clk>;
+      clock-names = "mci_clk";
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      slot at 0 {
+        reg = <0>;
+        bus-width = <4>;
+        cd-gpios = <&pioD 15 0>;
+        cd-inverted;
+      };
+
+      slot at 1 {
+        reg = <1>;
+        bus-width = <4>;
+      };
+    };
+...
diff --git a/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt b/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt
deleted file mode 100644
index 07ad02075a93..000000000000
--- a/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-* Atmel High Speed MultiMedia Card Interface
-
-This controller on atmel products provides an interface for MMC, SD and SDIO
-types of memory cards.
-
-This file documents differences between the core properties described
-by mmc.txt and the properties used by the atmel-mci driver.
-
-1) MCI node
-
-Required properties:
-- compatible: should be "atmel,hsmci"
-- #address-cells: should be one. The cell is the slot id.
-- #size-cells: should be zero.
-- at least one slot node
-- clock-names: tuple listing input clock names.
-	Required elements: "mci_clk"
-- clocks: phandles to input clocks.
-
-The node contains child nodes for each slot that the platform uses
-
-Example MCI node:
-
-mmc0: mmc at f0008000 {
-	compatible = "atmel,hsmci";
-	reg = <0xf0008000 0x600>;
-	interrupts = <12 4>;
-	#address-cells = <1>;
-	#size-cells = <0>;
-	clock-names = "mci_clk";
-	clocks = <&mci0_clk>;
-
-	[ child node definitions...]
-};
-
-2) slot nodes
-
-Required properties:
-- reg: should contain the slot id.
-- bus-width: number of data lines connected to the controller
-
-Optional properties:
-- cd-gpios: specify GPIOs for card detection
-- cd-inverted: invert the value of external card detect gpio line
-- wp-gpios: specify GPIOs for write protection
-
-Example slot node:
-
-slot at 0 {
-	reg = <0>;
-	bus-width = <4>;
-	cd-gpios = <&pioD 15 0>
-	cd-inverted;
-};
-
-Example full MCI node:
-mmc0: mmc at f0008000 {
-	compatible = "atmel,hsmci";
-	reg = <0xf0008000 0x600>;
-	interrupts = <12 4>;
-	#address-cells = <1>;
-	#size-cells = <0>;
-	slot at 0 {
-		reg = <0>;
-		bus-width = <4>;
-		cd-gpios = <&pioD 15 0>
-		cd-inverted;
-	};
-	slot at 1 {
-		reg = <1>;
-		bus-width = <4>;
-	};
-};

---
base-commit: feffde684ac29a3b7aec82d2df850fbdbdee55e4
change-id: 20241205-hsmci-7ac3ea915777

Best regards,
-- 
Dharma Balasubiramani <dharma.b at microchip.com>



From charan.pedumuru at microchip.com  Thu Dec  5 01:56:18 2024
From: charan.pedumuru at microchip.com (Charan Pedumuru)
Date: Thu, 5 Dec 2024 15:26:18 +0530
Subject: [PATCH] dt-bindings: dma: atmel: Convert to json schema
Message-ID: <20241205-xdma-v1-1-76a4a44670b5@microchip.com>

Convert old text based binding to json schema.
Changes during conversion:
- Add the required properties `clock` and `clock-names`, which were
  missing in the original binding.
- Add a fallback for `microchip,sam9x7-dma` and `microchip,sam9x60-dma`
  as they are compatible with the dma IP core on `atmel,sama5d4-dma`.
- Update examples and include appropriate file directives to resolve
  errors identified by `dt_binding_check` and `dtbs_check`.

Signed-off-by: Charan Pedumuru <charan.pedumuru at microchip.com>
---
 .../devicetree/bindings/dma/atmel,sama5d4-dma.yaml | 79 ++++++++++++++++++++++
 .../devicetree/bindings/dma/atmel-xdma.txt         | 54 ---------------
 2 files changed, 79 insertions(+), 54 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/atmel,sama5d4-dma.yaml b/Documentation/devicetree/bindings/dma/atmel,sama5d4-dma.yaml
new file mode 100644
index 000000000000..9ca1c5d1f00f
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/atmel,sama5d4-dma.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/atmel,sama5d4-dma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip AT91 Extensible Direct Memory Access Controller
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Charan Pedumuru <charan.pedumuru at microchip.com>
+
+description:
+  The DMA Controller (XDMAC) is a AHB-protocol central direct memory access
+  controller. It 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. The channel features are configurable at
+  implementation.
+
+allOf:
+  - $ref: dma-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - atmel,sama5d4-dma
+          - microchip,sama7g5-dma
+      - items:
+          - enum:
+              - microchip,sam9x60-dma
+              - microchip,sam9x7-dma
+          - const: atmel,sama5d4-dma
+
+  "#dma-cells":
+    description: |
+      Represents the number of integer cells in the `dmas` property of client
+      devices. The single cell specifies the channel configuration register:
+        - bit 13: SIF (Source Interface Identifier) for memory interface.
+        - bit 14: DIF (Destination Interface Identifier) for peripheral interface.
+        - bit 30-24: PERID (Peripheral Identifier).
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: dma_clk
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - "#dma-cells"
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/at91.h>
+    #include <dt-bindings/dma/at91.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    dma-controller at f0008000 {
+        compatible = "atmel,sama5d4-dma";
+        reg = <0xf0008000 0x1000>;
+        interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
+        #dma-cells = <1>;
+        clocks = <&pmc PMC_TYPE_PERIPHERAL 20>;
+        clock-names = "dma_clk";
+    };
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";
-};

---
base-commit: 85a2dd7d7c8152cb125712a1ecae1d0a6ccac250
change-id: 20241125-xdma-985c6c48ebd5

Best regards,
-- 
Charan Pedumuru <charan.pedumuru at microchip.com>



From sudeep.holla at arm.com  Thu Dec  5 01:59:05 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 5 Dec 2024 09:59:05 +0000
Subject: [PATCH] arm64: dts: fvp: Update bus-range property
In-Reply-To: <Z1CwGaAh714XfILz@e110455-lin.cambridge.arm.com>
References: <20241128152543.1821878-1-aneesh.kumar@kernel.org>
 <Z1CwGaAh714XfILz@e110455-lin.cambridge.arm.com>
Message-ID: <Z1F5aeNT-0KFOVHf@bogus>

On Wed, Dec 04, 2024 at 07:40:09PM +0000, Liviu Dudau wrote:
> On Thu, Nov 28, 2024 at 08:55:43PM +0530, Aneesh Kumar K.V (Arm) wrote:
> > These days, the Fixed Virtual Platforms(FVP) Base RevC model supports
> > more PCI devices. Update the max bus number so that Linux can enumerate
> > them correctly. Without this, the kernel throws the below error while
> > booting with the default hierarchy
> > 
> > pci_bus 0000:01: busn_res: [bus 01] end is updated to 01
> > pci_bus 0000:02: busn_res: can not insert [bus 02-01] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > pci_bus 0000:02: busn_res: [bus 02-01] end is updated to 02
> > pci_bus 0000:02: busn_res: can not insert [bus 02] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > pci_bus 0000:03: busn_res: can not insert [bus 03-01] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > pci_bus 0000:03: busn_res: [bus 03-01] end is updated to 03
> > pci_bus 0000:03: busn_res: can not insert [bus 03] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > pci_bus 0000:04: busn_res: can not insert [bus 04-01] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > pci_bus 0000:04: busn_res: [bus 04-01] end is updated to 04
> > pci_bus 0000:04: busn_res: can not insert [bus 04] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > pci 0000:00:01.0: BAR 14: assigned [mem 0x50000000-0x500fffff]
> > 
> > The change is using 0xff as max bus nr because the ECAM window is 256MB in size.
> > 
> > pci-host-generic 40000000.pci: ECAM at [mem 0x40000000-0x4fffffff] for [bus 00-01]
> > 
> > lspci output with and without the change
> > without fix:
> > 00:00.0 Host bridge: ARM Device 00ba (rev 01)
> > 00:01.0 PCI bridge: ARM Device 0def
> > 00:02.0 PCI bridge: ARM Device 0def
> > 00:03.0 PCI bridge: ARM Device 0def
> > 00:04.0 PCI bridge: ARM Device 0def
> > 00:1e.0 Unassigned class [ff00]: ARM Device ff80
> > 00:1e.1 Unassigned class [ff00]: ARM Device ff80
> > 00:1f.0 SATA controller: Device 0abc:aced (rev 01)
> > 01:00.0 SATA controller: Device 0abc:aced (rev 01)
> > 
> > with fix:
> > 00:00.0 Host bridge: ARM Device 00ba (rev 01)
> > 00:01.0 PCI bridge: ARM Device 0def
> > 00:02.0 PCI bridge: ARM Device 0def
> > 00:03.0 PCI bridge: ARM Device 0def
> > 00:04.0 PCI bridge: ARM Device 0def
> > 00:1e.0 Unassigned class [ff00]: ARM Device ff80
> > 00:1e.1 Unassigned class [ff00]: ARM Device ff80
> > 00:1f.0 SATA controller: Device 0abc:aced (rev 01)
> > 01:00.0 SATA controller: Device 0abc:aced (rev 01)
> > 02:00.0 Unassigned class [ff00]: ARM Device ff80
> > 02:00.4 Unassigned class [ff00]: ARM Device ff80
> > 03:00.0 PCI bridge: ARM Device 0def
> > 04:00.0 PCI bridge: ARM Device 0def
> > 04:01.0 PCI bridge: ARM Device 0def
> > 04:02.0 PCI bridge: ARM Device 0def
> > 05:00.0 SATA controller: Device 0abc:aced (rev 01)
> > 06:00.0 Unassigned class [ff00]: ARM Device ff80
> > 06:00.7 Unassigned class [ff00]: ARM Device ff80
> > 07:00.0 Unassigned class [ff00]: ARM Device ff80
> > 07:00.3 Unassigned class [ff00]: ARM Device ff80
> > 08:00.0 Unassigned class [ff00]: ARM Device ff80
> > 08:00.1 Unassigned class [ff00]: ARM Device ff80
> > 
> > Cc: Liviu Dudau <liviu.dudau at arm.com>
> > Cc: Sudeep Holla <sudeep.holla at arm.com>
> > Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
> > Cc: Rob Herring <robh at kernel.org>
> > Cc: Krzysztof Kozlowski <krzk+dt at kernel.org>
> > Cc: Conor Dooley <conor+dt at kernel.org>
> > Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar at kernel.org>
> 
> Reviewed-by: Liviu Dudau <liviu.dudau at arm.com>
> 
> Sudeep, can you please take this patch through your tree?
>

I have already queued and must be in -next, just didn't get to a point to
respond as applied yet. I will update with your tags. Thanks!

-- 
Regards,
Sudeep


From qperret at google.com  Thu Dec  5 02:02:50 2024
From: qperret at google.com (Quentin Perret)
Date: Thu, 5 Dec 2024 10:02:50 +0000
Subject: [PATCH] KVM: arm64: Always check the state from hyp_ack_unshare()
In-Reply-To: <20241128154406.602875-1-qperret@google.com>
References: <20241128154406.602875-1-qperret@google.com>
Message-ID: <Z1F6SpUQVPdjllUG@google.com>

On Thursday 28 Nov 2024 at 15:44:06 (+0000), Quentin Perret wrote:
> There are multiple pKVM memory transitions where the state of a page is
> not cross-checked from the completer's PoV for performance reasons.
> For example, if a page is PKVM_PAGE_OWNED from the initiator's PoV,
> we should be guaranteed by construction that it is PKVM_NOPAGE for
> everybody else, hence allowing us to save a page-table lookup.
> 
> When it was introduced, hyp_ack_unshare() followed that logic and bailed
> out without checking the PKVM_PAGE_SHARED_BORROWED state in the
> hypervisor's stage-1. This was correct as we could safely assume that
> all host-initiated shares were directed at the hypervisor at the time.
> But with the introduction of other types of shares (e.g. for FF-A or
> non-protected guests), it is now very much required to cross check this
> state to prevent the host from running __pkvm_host_unshare_hyp() on a
> page shared with TZ or a non-protected guest.
> 
> Thankfully, if an attacker were to try this, the hyp_unmap() call from
> hyp_complete_unshare() would fail, hence causing to WARN() from
> __do_unshare() with the host lock held, which is fatal. But this is
> fragile at best, and can hardly be considered a security measure.
> 
> Let's just do the right thing and always check the state from
> hyp_ack_unshare().
> 
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index caba3e4bd09e..e75374d682f4 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -783,9 +783,6 @@ static int hyp_ack_unshare(u64 addr, const struct pkvm_mem_transition *tx)
>  	if (tx->initiator.id == PKVM_ID_HOST && hyp_page_count((void *)addr))
>  		return -EBUSY;
>  
> -	if (__hyp_ack_skip_pgtable_check(tx))
> -		return 0;
> -
>  	return __hyp_check_page_state_range(addr, size,
>  					    PKVM_PAGE_SHARED_BORROWED);
>  }
> -- 
> 2.47.0.338.g60cca15819-goog

Shameless inbox bump for this one :-)

It should hopefully be a fairly straightforward fix.

Thanks,
Quentin


From yeoreum.yun at arm.com  Thu Dec  5 02:10:38 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Thu, 5 Dec 2024 10:10:38 +0000
Subject: [PATCH] coresight: Drop atomics in connection refcounts
In-Reply-To: <20241128121414.2425119-1-james.clark@linaro.org>
References: <20241128121414.2425119-1-james.clark@linaro.org>
Message-ID: <Z1F8HvLY/04jukUH@e129823.arm.com>

This patch looks good to me.

Reviewed-by: Yeoreum Yun <yeoreum.yun at arm.com>

On Thu, Nov 28, 2024 at 12:14:14PM +0000, James Clark wrote:
> These belong to the device being enabled or disabled and are only ever
> used inside the device's spinlock. Remove the atomics to not imply that
> there are any other concurrent accesses.
>
> If atomics were necessary I don't think they would have been enough
> anyway. There would be nothing to prevent an enable or disable running
> concurrently if not for the spinlock.
>
> Signed-off-by: James Clark <james.clark at linaro.org>
> ---
>  drivers/hwtracing/coresight/coresight-funnel.c     | 6 +++---
>  drivers/hwtracing/coresight/coresight-replicator.c | 6 +++---
>  drivers/hwtracing/coresight/coresight-tpda.c       | 6 +++---
>  include/linux/coresight.h                          | 4 ++--
>  4 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
> index 5a819c8970fb..bd32f74cbdae 100644
> --- a/drivers/hwtracing/coresight/coresight-funnel.c
> +++ b/drivers/hwtracing/coresight/coresight-funnel.c
> @@ -86,14 +86,14 @@ static int funnel_enable(struct coresight_device *csdev,
>  	bool first_enable = false;
>
>  	spin_lock_irqsave(&drvdata->spinlock, flags);
> -	if (atomic_read(&in->dest_refcnt) == 0) {
> +	if (in->dest_refcnt == 0) {
>  		if (drvdata->base)
>  			rc = dynamic_funnel_enable_hw(drvdata, in->dest_port);
>  		if (!rc)
>  			first_enable = true;
>  	}
>  	if (!rc)
> -		atomic_inc(&in->dest_refcnt);
> +		in->dest_refcnt++;
>  	spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>  	if (first_enable)
> @@ -130,7 +130,7 @@ static void funnel_disable(struct coresight_device *csdev,
>  	bool last_disable = false;
>
>  	spin_lock_irqsave(&drvdata->spinlock, flags);
> -	if (atomic_dec_return(&in->dest_refcnt) == 0) {
> +	if (--in->dest_refcnt == 0) {
>  		if (drvdata->base)
>  			dynamic_funnel_disable_hw(drvdata, in->dest_port);
>  		last_disable = true;
> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
> index 3e55be9c8418..31322aea19f2 100644
> --- a/drivers/hwtracing/coresight/coresight-replicator.c
> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
> @@ -126,7 +126,7 @@ static int replicator_enable(struct coresight_device *csdev,
>  	bool first_enable = false;
>
>  	spin_lock_irqsave(&drvdata->spinlock, flags);
> -	if (atomic_read(&out->src_refcnt) == 0) {
> +	if (out->src_refcnt == 0) {
>  		if (drvdata->base)
>  			rc = dynamic_replicator_enable(drvdata, in->dest_port,
>  						       out->src_port);
> @@ -134,7 +134,7 @@ static int replicator_enable(struct coresight_device *csdev,
>  			first_enable = true;
>  	}
>  	if (!rc)
> -		atomic_inc(&out->src_refcnt);
> +		out->src_refcnt++;
>  	spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>  	if (first_enable)
> @@ -180,7 +180,7 @@ static void replicator_disable(struct coresight_device *csdev,
>  	bool last_disable = false;
>
>  	spin_lock_irqsave(&drvdata->spinlock, flags);
> -	if (atomic_dec_return(&out->src_refcnt) == 0) {
> +	if (--out->src_refcnt == 0) {
>  		if (drvdata->base)
>  			dynamic_replicator_disable(drvdata, in->dest_port,
>  						   out->src_port);
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
> index bfca103f9f84..4ec676bea1ce 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.c
> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
> @@ -190,10 +190,10 @@ static int tpda_enable(struct coresight_device *csdev,
>  	int ret = 0;
>
>  	spin_lock(&drvdata->spinlock);
> -	if (atomic_read(&in->dest_refcnt) == 0) {
> +	if (in->dest_refcnt == 0) {
>  		ret = __tpda_enable(drvdata, in->dest_port);
>  		if (!ret) {
> -			atomic_inc(&in->dest_refcnt);
> +			in->dest_refcnt++;
>  			csdev->refcnt++;
>  			dev_dbg(drvdata->dev, "TPDA inport %d enabled.\n", in->dest_port);
>  		}
> @@ -223,7 +223,7 @@ static void tpda_disable(struct coresight_device *csdev,
>  	struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>
>  	spin_lock(&drvdata->spinlock);
> -	if (atomic_dec_return(&in->dest_refcnt) == 0) {
> +	if (--in->dest_refcnt == 0) {
>  		__tpda_disable(drvdata, in->dest_port);
>  		csdev->refcnt--;
>  	}
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index c13342594278..834029cb9ba2 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -200,8 +200,8 @@ struct coresight_connection {
>  	struct coresight_device *dest_dev;
>  	struct coresight_sysfs_link *link;
>  	struct coresight_device *src_dev;
> -	atomic_t src_refcnt;
> -	atomic_t dest_refcnt;
> +	int src_refcnt;
> +	int dest_refcnt;
>  };
>
>  /**
> --
> 2.34.1
>


From quic_sibis at quicinc.com  Thu Dec  5 02:16:03 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Thu, 5 Dec 2024 15:46:03 +0530
Subject: [PATCH V5 2/2] firmware: arm_scmi: vendors: Add QCOM SCMI Generic
 Extensions
In-Reply-To: <Z1BSjM5heBoRFCYk@pluto>
References: <20241115011515.1313447-1-quic_sibis@quicinc.com>
 <20241115011515.1313447-3-quic_sibis@quicinc.com> <Z1BSjM5heBoRFCYk@pluto>
Message-ID: <d666a553-05fa-b571-a497-bf59a6c15ad9@quicinc.com>



On 12/4/24 18:31, Cristian Marussi wrote:
> On Fri, Nov 15, 2024 at 06:45:15AM +0530, Sibi Sankar wrote:
>> The QCOM SCMI Generic Extensions Protocol provides a generic way of
>> exposing a number of Qualcomm SoC specific features (like memory bus
>> scaling) through a mixture of pre-determined algorithm strings and
>> param_id pairs hosted on the SCMI controller.
>>
> 
> Hi,

Hey Cristian,
Thanks for taking time to review the series!

>   
>> Co-developed-by: Shivnandan Kumar <quic_kshivnan at quicinc.com>
>> Signed-off-by: Shivnandan Kumar <quic_kshivnan at quicinc.com>
>> Co-developed-by: Ramakrishna Gottimukkula <quic_rgottimu at quicinc.com>
>> Signed-off-by: Ramakrishna Gottimukkula <quic_rgottimu at quicinc.com>
>> Co-developed-by: Amir Vajid <avajid at quicinc.com>
>> Signed-off-by: Amir Vajid <avajid at quicinc.com>
>> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
>> Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>
> 
> You reworked/refactored quite a lot the internals since V4, you should
> have dropped the Reviewed-by tag.

Yup, ack!

> 
>> ---
>>
>> v4:
>> * Splitting the series into vendor protocol and memlat client.
>>    Also the move the memlat client implementation back to RFC
>>    due to multiple opens.
>> * Use common xfer helper to avoid code duplication [Dmitry]
>> * Update enum documentation without duplicate enum info [Dmitry]
>>
>>   drivers/firmware/arm_scmi/Kconfig             |   1 +
>>   drivers/firmware/arm_scmi/Makefile            |   1 +
>>   .../firmware/arm_scmi/vendors/qcom/Kconfig    |  15 ++
>>   .../firmware/arm_scmi/vendors/qcom/Makefile   |   2 +
>>   .../arm_scmi/vendors/qcom/qcom-generic-ext.c  | 139 ++++++++++++++++++
>>   include/linux/scmi_qcom_protocol.h            |  37 +++++
>>   6 files changed, 195 insertions(+)
>>   create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/Kconfig
>>   create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/Makefile
>>   create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/qcom-generic-ext.c
>>   create mode 100644 include/linux/scmi_qcom_protocol.h
>>
>> diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
>> index dabd874641d0..73128442d97b 100644
>> --- a/drivers/firmware/arm_scmi/Kconfig
>> +++ b/drivers/firmware/arm_scmi/Kconfig
>> @@ -71,6 +71,7 @@ config ARM_SCMI_DEBUG_COUNTERS
>>   
>>   source "drivers/firmware/arm_scmi/transports/Kconfig"
>>   source "drivers/firmware/arm_scmi/vendors/imx/Kconfig"
>> +source "drivers/firmware/arm_scmi/vendors/qcom/Kconfig"
>>   
>>   endif #ARM_SCMI_PROTOCOL
>>   
>> diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
>> index 9ac81adff567..58cf4d656cbb 100644
>> --- a/drivers/firmware/arm_scmi/Makefile
>> +++ b/drivers/firmware/arm_scmi/Makefile
>> @@ -12,6 +12,7 @@ scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
>>   
>>   obj-$(CONFIG_ARM_SCMI_PROTOCOL) += transports/
>>   obj-$(CONFIG_ARM_SCMI_PROTOCOL) += vendors/imx/
>> +obj-$(CONFIG_ARM_SCMI_PROTOCOL) += vendors/qcom/
>>   
>>   obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
>>   obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o
>> diff --git a/drivers/firmware/arm_scmi/vendors/qcom/Kconfig b/drivers/firmware/arm_scmi/vendors/qcom/Kconfig
>> new file mode 100644
>> index 000000000000..5dd9e8a6b75f
>> --- /dev/null
>> +++ b/drivers/firmware/arm_scmi/vendors/qcom/Kconfig
>> @@ -0,0 +1,15 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +menu "ARM SCMI QCOM Vendor Protocols"
>> +
>> +config QCOM_SCMI_GENERIC_EXT
>> +	tristate "Qualcomm Technologies, Inc. Qcom SCMI vendor Protocol"
>> +	depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
>> +	help
>> +	  The QCOM SCMI vendor protocol provides a generic way of exposing
>> +	  a number of Qualcomm SoC specific features (like memory bus scaling)
>> +	  through a mixture of pre-determined algorithm strings and param_id
>> +	  pairs hosted on the SCMI controller.
>> +
>> +	  This driver defines/documents the message ID's used for this
>> +	  communication and also exposes the operations used by the clients.
>> +endmenu
>> diff --git a/drivers/firmware/arm_scmi/vendors/qcom/Makefile b/drivers/firmware/arm_scmi/vendors/qcom/Makefile
>> new file mode 100644
>> index 000000000000..6b98fabbebb8
>> --- /dev/null
>> +++ b/drivers/firmware/arm_scmi/vendors/qcom/Makefile
>> @@ -0,0 +1,2 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +obj-$(CONFIG_QCOM_SCMI_GENERIC_EXT) += qcom-generic-ext.o
>> diff --git a/drivers/firmware/arm_scmi/vendors/qcom/qcom-generic-ext.c b/drivers/firmware/arm_scmi/vendors/qcom/qcom-generic-ext.c
>> new file mode 100644
>> index 000000000000..1b209093d275
>> --- /dev/null
>> +++ b/drivers/firmware/arm_scmi/vendors/qcom/qcom-generic-ext.c
>> @@ -0,0 +1,139 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#include <linux/scmi_qcom_protocol.h>
>> +
>> +#include "../../common.h"
>> +
>> +/**
>> + * enum qcom_generic_ext_protocol_cmd - vendor specific commands supported by SCMI Qualcomm
>> + *                                      generic vendor protocol.
>> + *
>> + * This protocol is intended as a generic way of exposing a number of Qualcomm SoC
>> + * specific features through a mixture of pre-determined algorithm string and param_id
>> + * pairs hosted on the SCMI controller.
>> + *
>> + * The QCOM SCMI Vendor Protocol has the protocol id as 0x80 and vendor id set to
>> + * Qualcomm and the implementation version set to 0x20000. The PROTOCOL_VERSION command
>> + * returns version 1.0.
> 
> The chosen protocol ID is already defined in the protocol doc in the
> series, and the note about the implementation version seems redundant,
> it is indeed specified as needed in scmi_protocol.

sure will have this removed.

> 
>> + *
>> + * @QCOM_SCMI_SET_PARAM: is used to set the parameter of a specific algo_str hosted on
>> + *			 QCOM SCMI Vendor Protocol. The tx len depends on the algo_str used.
>> + * @QCOM_SCMI_GET_PARAM: is used to get parameter information of a specific algo_str
>> + *			 hosted on QCOM SCMI Vendor Protocol. The tx and rx len depends
>> + *			 on the algo_str used.
>> + * @QCOM_SCMI_START_ACTIVITY: is used to start the activity performed by the algo_str.
>> + * @QCOM_SCMI_STOP_ACTIVITY: is used to stop a pre-existing activity performed by the algo_str.
>> + */
>> +enum qcom_generic_ext_protocol_cmd {
>> +	QCOM_SCMI_SET_PARAM = 0x10,
>> +	QCOM_SCMI_GET_PARAM = 0x11,
>> +	QCOM_SCMI_START_ACTIVITY = 0x12,
>> +	QCOM_SCMI_STOP_ACTIVITY = 0x13,
>> +};
>> +
>> +/**
>> + * struct qcom_scmi_msg - represents the various parameters to be populated
>> + *                        for using the QCOM SCMI Vendor Protocol
>> + *
>> + * @ext_id: reserved, must be zero
>> + * @algo_low: lower 32 bits of the algo_str
>> + * @algo_high: upper 32 bits of the algo_str
>> + * @param_id: serves as token message id to the specific algo_str
>> + * @buf: serves as the payload to the specified param_id and algo_str pair
>> + */
>> +struct qcom_scmi_msg {
>> +	__le32 ext_id;
>> +	__le32 algo_low;
>> +	__le32 algo_high;
>> +	__le32 param_id;
>> +	__le32 buf[];
>> +};
>> +
>> +static int qcom_scmi_common_xfer(const struct scmi_protocol_handle *ph,
>> +				 enum qcom_generic_ext_protocol_cmd cmd_id, void *buf,
>> +				 size_t buf_len, u64 algo_str, u32 param_id, size_t rx_size)
>> +{
>> +	struct scmi_xfer *t;
>> +	struct qcom_scmi_msg *msg;
>> +	int ret;
>> +
>> +	ret = ph->xops->xfer_get_init(ph, cmd_id, buf_len + sizeof(*msg), rx_size, &t);
>> +	if (ret)
>> +		return ret;
>> +
>> +	msg = t->tx.buf;
>> +	msg->algo_low = cpu_to_le32(lower_32_bits(algo_str));
>> +	msg->algo_high = cpu_to_le32(upper_32_bits(algo_str));
>> +	msg->param_id = cpu_to_le32(param_id);
>> +	memcpy(msg->buf, buf, buf_len);
>> +
>> +	ret = ph->xops->do_xfer(ph, t);
>> +	if (rx_size)
> 
> You should check ret == 0 also here before considering to pick up the reply
> if a non-zero rx_size was specified.

ack

> 
>> +		memcpy(buf, t->rx.buf, t->rx.len);
> 
> ...you are using the same buf/buf_len to hold the TX request and get back
> the reply content if a non-zero rx_size was provided but while you can
> be sure that the reply payload rx.len <= rx_size by construction
> (via xfer_get_init) you cannot be equally sure that rx_size <= buf_len
> ...it depends on te caller how this operation is invoked...so you could
> end up oveflowing buf depending on the caller-provided params...
> 
> ...please add some additional check at the start of this function like:
> 
> 	if (rx_size > buf_len)
> 		return -EINVAL;
> 
> ...to catch such bad invcations...

ack

> 
>> +	ph->xops->xfer_put(ph, t);
>> +
>> +	return ret;
>> +}
>> +
>> +static int qcom_scmi_set_param(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
>> +			       u64 algo_str, u32 param_id)
>> +{
>> +	return qcom_scmi_common_xfer(ph, QCOM_SCMI_SET_PARAM, buf, buf_len, algo_str,
>> +				     param_id, 0);
>> +}
>> +
>> +static int qcom_scmi_get_param(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
>> +			       u64 algo_str, u32 param_id, size_t rx_size)
>> +{
>> +	return qcom_scmi_common_xfer(ph, QCOM_SCMI_GET_PARAM, buf, buf_len, algo_str,
>> +				     param_id, rx_size);
>> +}
>> +
>> +static int qcom_scmi_start_activity(const struct scmi_protocol_handle *ph, void *buf,
>> +				    size_t buf_len, u64 algo_str, u32 param_id)
>> +{
>> +	return qcom_scmi_common_xfer(ph, QCOM_SCMI_START_ACTIVITY, buf, buf_len, algo_str,
>> +				     param_id, 0);
>> +}
>> +
>> +static int qcom_scmi_stop_activity(const struct scmi_protocol_handle *ph, void *buf,
>> +				   size_t buf_len, u64 algo_str, u32 param_id)
>> +{
>> +	return qcom_scmi_common_xfer(ph, QCOM_SCMI_STOP_ACTIVITY, buf, buf_len, algo_str,
>> +				     param_id, 0);
>> +}
>> +
>> +static struct qcom_generic_ext_ops qcom_proto_ops = {
>> +	.set_param = qcom_scmi_set_param,
>> +	.get_param = qcom_scmi_get_param,
>> +	.start_activity = qcom_scmi_start_activity,
>> +	.stop_activity = qcom_scmi_stop_activity,
>> +};
>> +
>> +static int qcom_generic_ext_protocol_init(const struct scmi_protocol_handle *ph)
>> +{
>> +	u32 version;
>> +
>> +	ph->xops->version_get(ph, &version);
> 
> ... please check retval and bailout on error when not even a basic version_get
> succedeed...

ack

> 
>> +
>> +	dev_dbg(ph->dev, "QCOM Generic Vendor Version %d.%d\n",
>> +		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct scmi_protocol qcom_generic_ext = {
>> +	.id = SCMI_PROTOCOL_QCOM_GENERIC,
>> +	.owner = THIS_MODULE,
>> +	.instance_init = &qcom_generic_ext_protocol_init,
>> +	.ops = &qcom_proto_ops,
>> +	.vendor_id = "Qualcomm",
>> +	.impl_ver = 0x20000,
>> +};
>> +module_scmi_protocol(qcom_generic_ext);
>> +
> 
> You may have to add a proper MODULE_ALIAS, if the series on autoload
> goes through
> 
> https://lore.kernel.org/linux-arm-kernel/20241203200038.3961090-1-cristian.marussi at arm.com/
> 

Thanks for sending out ^^ series. Will re-spin with those added.

-Sibi

>> +MODULE_DESCRIPTION("QCOM SCMI Generic Vendor protocol");
>> +MODULE_LICENSE("GPL");
>> diff --git a/include/linux/scmi_qcom_protocol.h b/include/linux/scmi_qcom_protocol.h
>> new file mode 100644
>> index 000000000000..465b2522ca29
>> --- /dev/null
>> +++ b/include/linux/scmi_qcom_protocol.h
>> @@ -0,0 +1,37 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * SCMI Message Protocol driver QCOM extension header
>> + *
>> + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#ifndef _LINUX_SCMI_QCOM_PROTOCOL_H
>> +#define _LINUX_SCMI_QCOM_PROTOCOL_H
>> +
>> +#include <linux/types.h>
>> +
>> +#define SCMI_PROTOCOL_QCOM_GENERIC    0x80
>> +
>> +struct scmi_protocol_handle;
>> +
>> +/**
>> + * struct qcom_generic_ext_ops - represents the various operations provided
>> + *				 by QCOM Generic Vendor Protocol
>> + *
>> + * @set_param: set parameter specified by param_id and algo_str pair.
>> + * @get_param: retrieve parameter specified by param_id and algo_str pair.
>> + * @start_activity: initiate a specific activity defined by algo_str.
>> + * @stop_activity: halt previously initiated activity defined by algo_str.
>> + */
>> +struct qcom_generic_ext_ops {
>> +	int (*set_param)(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
>> +			 u64 algo_str, u32 param_id);
>> +	int (*get_param)(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
>> +			 u64 algo_str, u32 param_id, size_t rx_size);
>> +	int (*start_activity)(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
>> +			      u64 algo_str, u32 param_id);
>> +	int (*stop_activity)(const struct scmi_protocol_handle *ph, void *buf, size_t buf_len,
>> +			     u64 algo_str, u32 param_id);
>> +};
>> +
>> +#endif /* _LINUX_SCMI_QCOM_PROTOCOL_H */
>> -- 
> 
> Thanks,
> Cristian


From quic_sibis at quicinc.com  Thu Dec  5 02:17:14 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Thu, 5 Dec 2024 15:47:14 +0530
Subject: [PATCH V4 4/5] soc: qcom: Introduce SCMI based Memlat (Memory
 Latency) governor
In-Reply-To: <20241115003809epcms1p518df149458f3023d33ec6d87a315e8f6@epcms1p5>
References: <ac655bdc-5ccf-c6c6-3203-659f1916c53c@quicinc.com>
 <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-5-quic_sibis@quicinc.com>
 <2aycrvnvivcrqctqmweadcgenwugafdr6ub3bzkscterpenz32@bzabln2hkral>
 <29eef87e-96f6-5105-6f7a-a8e01efcb4a3@quicinc.com>
 <k4lpzxtrq3x6riyv6etxiobn7nbpczf2bp3m4oc752nhjknlit@uo53kbppzim7>
 <CGME20241114041419epcas1p3b52bb9795ffd9efa568bb106ba268e02@epcms1p5>
 <20241115003809epcms1p518df149458f3023d33ec6d87a315e8f6@epcms1p5>
Message-ID: <6356241e-6bfc-c4dc-1fbd-cd92f1b236ba@quicinc.com>



On 11/15/24 06:08, MyungJoo Ham wrote:
>>
>> Hey Dmitry,
>>
>> Thanks for taking time to review the series.
>>
>> + Devfreq maintainers to comment (I thought you already added
>> them by name)
>>
>>
>> Hey MyungJoo/Kyungmin/Chanwoo,
>>
>> Can you weigh in here? Does it make sense to add a new
>> class of devfreq devices that don't have governors
>> associated with them just for them to export a few
>> essential data to userspace? In this scenario the
>> scaling algorithm is in a SCP and we just start
>> them from the kernel. We do have ways to get the
>> current frequency of various buses but does this
>> warrant adding a new class of governor less devices?
>>
>> -Sibi
> 
> If voltage/frequency is controlled by SCP
> (it's an SoC's internal hardware IP, right?),
> it's good to have a userspace governer
> with the driver not accepting updates from userspace.
> 
> E.g., Let "target" callback not update the frequency value,
>   or let "target" callback always return an error with
>   a dev_err message that you don't accept frequency changes
>   from userspace.

Thanks for the input. Will implement something similar to
what you suggested for the next re-spin.

-Sibi

> 
> Cheers,
> MyungJoo.


From andre.draszik at linaro.org  Thu Dec  5 02:22:00 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Thu, 05 Dec 2024 10:22:00 +0000
Subject: [PATCH v4] phy: exynos5-usbdrd: gs101: ensure power is gated to SS
 phy in phy_exit()
Message-ID: <20241205-gs101-usb-phy-fix-v4-1-0278809fb810@linaro.org>

We currently don't gate the power to the SS phy in phy_exit().

Shuffle the code slightly to ensure the power is gated to the SS phy as
well.

Fixes: 32267c29bc7d ("phy: exynos5-usbdrd: support Exynos USBDRD 3.1 combo phy (HS & SS)")
CC: stable at vger.kernel.org # 6.11+
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
Changes in v4:
- separate this patch out from original series
- Link to v3: https://lore.kernel.org/all/20241205-gs101-phy-lanes-orientation-phy-v3-5-32f721bed219 at linaro.org/

Changes in v3:
- none
- Link to v2: https://lore.kernel.org/all/20241203-gs101-phy-lanes-orientation-phy-v2-5-40dcf1b7670d at linaro.org/

Changes in v2:
- add cc-stable and fixes tags to power gating patch (Krzysztof)
- Link to v1: https://lore.kernel.org/all/20241127-gs101-phy-lanes-orientation-phy-v1-6-1b7fce24960b at linaro.org/
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index c421b495eb0f..e4699d4e8075 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1296,14 +1296,17 @@ static int exynos5_usbdrd_gs101_phy_exit(struct phy *phy)
 	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
 	int ret;
 
+	if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) {
+		ret = exynos850_usbdrd_phy_exit(phy);
+		if (ret)
+			return ret;
+	}
+
+	exynos5_usbdrd_phy_isol(inst, true);
+
 	if (inst->phy_cfg->id != EXYNOS5_DRDPHY_UTMI)
 		return 0;
 
-	ret = exynos850_usbdrd_phy_exit(phy);
-	if (ret)
-		return ret;
-
-	exynos5_usbdrd_phy_isol(inst, true);
 	return regulator_bulk_disable(phy_drd->drv_data->n_regulators,
 				      phy_drd->regulators);
 }

---
base-commit: c245a7a79602ccbee780c004c1e4abcda66aec32
change-id: 20241205-gs101-usb-phy-fix-2c558aa0392a

Best regards,
-- 
Andr? Draszik <andre.draszik at linaro.org>



From krzk at kernel.org  Thu Dec  5 02:25:28 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 11:25:28 +0100
Subject: [PATCH] clk: rockchip: add clock ID for CIF0/1 on RK3066
In-Reply-To: <20241205055122.11613-1-val@packett.cool>
References: <20241205055122.11613-1-val@packett.cool>
Message-ID: <5kesytgbhfununu5li4ychaw4newkctx4wuhlshks2ertfkd2t@jauqcntehv2z>

On Thu, Dec 05, 2024 at 02:50:46AM -0300, Val Packett wrote:
> RK3066 does have two "CIF" video capture interface blocks, add their
> corresponding clock IDs so that they could be used.
> 
> Signed-off-by: Val Packett <val at packett.cool>
> ---
>  drivers/clk/rockchip/clk-rk3188.c             | 4 ++--
>  include/dt-bindings/clock/rk3188-cru-common.h | 2 ++
>  2 files changed, 4 insertions(+), 2 deletions(-)

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

Best regards,
Krzysztof



From lpieralisi at kernel.org  Thu Dec  5 02:25:07 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Thu, 5 Dec 2024 11:25:07 +0100
Subject: [PATCH v7 2/2] PCI: imx6: Add IOMMU and ITS MSI support for
 i.MX95
In-Reply-To: <20241203-imx95_lut-v7-2-d0cd6293225e@nxp.com>
References: <20241203-imx95_lut-v7-0-d0cd6293225e@nxp.com>
 <20241203-imx95_lut-v7-2-d0cd6293225e@nxp.com>
Message-ID: <Z1F/g/clUxAIGFZ1@lpieralisi>

On Tue, Dec 03, 2024 at 06:27:16PM -0500, Frank Li wrote:
> For the i.MX95, configuration of a LUT is necessary to convert Bus Device
> Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
> This involves examining the msi-map and smmu-map to ensure consistent

This involves checking msi-map and iommu-map device tree properties
to...

> mapping of PCI BDF to the same stream IDs. Subsequently, LUT-related
> registers are configured. In the absence of an msi-map, the built-in MSI
> controller is utilized as a fallback.
> 
> Register a PCI bus callback function to handle enable_device() and
> disable_device() operations, setting up the LUT whenever a new PCI device
> is enabled.
> 
> Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> Change from v5 to v6
> - change comment rid to RID
> - some mini change according to mani's feedback
> 
> Change from v4 to v5
> - rework commt message
> - add comment for mutex
> - s/reqid/rid/
> - keep only one loop when enable lut
> - add warning when try to add duplicate rid
> - Replace hardcode 0xffff with IMX95_PE0_LUT_MASK
> - Fix some error message
> 
> Change from v3 to v4
> - Check target value at of_map_id().
> - of_node_put() for target.
> - add case for msi-map exist, but rid entry is not exist.
> 
> Change from v2 to v3
> - Use the "target" argument of of_map_id()
> - Check if rid already in lut table when enable device
> 
> change from v1 to v2
> - set callback to pci_host_bridge instead pci->ops.
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 183 +++++++++++++++++++++++++++++++++-
>  1 file changed, 182 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index c8d5c90aa4d45..ac5caa7b05075 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -55,6 +55,22 @@
>  #define IMX95_PE0_GEN_CTRL_3			0x1058
>  #define IMX95_PCIE_LTSSM_EN			BIT(0)
>  
> +#define IMX95_PE0_LUT_ACSCTRL			0x1008
> +#define IMX95_PEO_LUT_RWA			BIT(16)
> +#define IMX95_PE0_LUT_ENLOC			GENMASK(4, 0)
> +
> +#define IMX95_PE0_LUT_DATA1			0x100c
> +#define IMX95_PE0_LUT_VLD			BIT(31)
> +#define IMX95_PE0_LUT_DAC_ID			GENMASK(10, 8)
> +#define IMX95_PE0_LUT_STREAM_ID			GENMASK(5, 0)
> +
> +#define IMX95_PE0_LUT_DATA2			0x1010
> +#define IMX95_PE0_LUT_REQID			GENMASK(31, 16)
> +#define IMX95_PE0_LUT_MASK			GENMASK(15, 0)
> +
> +#define IMX95_SID_MASK				GENMASK(5, 0)
> +#define IMX95_MAX_LUT				32
> +
>  #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
>  
>  enum imx_pcie_variants {
> @@ -87,6 +103,7 @@ enum imx_pcie_variants {
>   * workaround suspend resume on some devices which are affected by this errata.
>   */
>  #define IMX_PCIE_FLAG_BROKEN_SUSPEND		BIT(9)
> +#define IMX_PCIE_FLAG_HAS_LUT			BIT(10)
>  
>  #define imx_check_flag(pci, val)	(pci->drvdata->flags & val)
>  
> @@ -139,6 +156,9 @@ struct imx_pcie {
>  	struct device		*pd_pcie_phy;
>  	struct phy		*phy;
>  	const struct imx_pcie_drvdata *drvdata;
> +
> +	/* Ensure that only one device's LUT is configured at any given time */
> +	struct mutex		lock;
>  };
>  
>  /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
> @@ -930,6 +950,159 @@ static void imx_pcie_stop_link(struct dw_pcie *pci)
>  	imx_pcie_ltssm_disable(dev);
>  }
>  
> +static int imx_pcie_add_lut(struct imx_pcie *imx_pcie, u16 rid, u8 sid)
> +{
> +	struct dw_pcie *pci = imx_pcie->pci;
> +	struct device *dev = pci->dev;
> +	u32 data1, data2;
> +	int free = -1;
> +	int i;
> +
> +	if (sid >= 64) {
> +		dev_err(dev, "Invalid SID for index %d\n", sid);
> +		return -EINVAL;
> +	}
> +
> +	guard(mutex)(&imx_pcie->lock);
> +
> +	/*
> +	 * Iterate through all LUT entries to check for duplicate RID and
> +	 * identify the first available entry. Configure this available entry
> +	 * immediately after verification to avoid rescanning it.
> +	 */
> +	for (i = 0; i < IMX95_MAX_LUT; i++) {
> +		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
> +		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, &data1);
> +
> +		if (!(data1 & IMX95_PE0_LUT_VLD)) {
> +			if (free < 0)
> +				free = i;
> +			continue;
> +		}
> +
> +		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
> +
> +		/* Do not add duplicate RID */
> +		if (rid == FIELD_GET(IMX95_PE0_LUT_REQID, data2)) {
> +			dev_warn(dev, "Existing LUT entry available for RID (%d)", rid);
> +			return 0;
> +		}
> +	}
> +
> +	if (free < 0) {
> +		dev_err(dev, "LUT entry is not available\n");
> +		return -ENOSPC;
> +	}
> +
> +	data1 = FIELD_PREP(IMX95_PE0_LUT_DAC_ID, 0);
> +	data1 |= FIELD_PREP(IMX95_PE0_LUT_STREAM_ID, sid);
> +	data1 |= IMX95_PE0_LUT_VLD;
> +	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, data1);
> +
> +	data2 = IMX95_PE0_LUT_MASK; /* Match all bits of RID */
> +	data2 |= FIELD_PREP(IMX95_PE0_LUT_REQID, rid);
> +	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, data2);
> +
> +	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, free);
> +
> +	return 0;
> +}
> +
> +static void imx_pcie_remove_lut(struct imx_pcie *imx_pcie, u16 rid)
> +{
> +	u32 data2;
> +	int i;
> +
> +	guard(mutex)(&imx_pcie->lock);
> +
> +	for (i = 0; i < IMX95_MAX_LUT; i++) {
> +		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
> +		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
> +		if (FIELD_GET(IMX95_PE0_LUT_REQID, data2) == rid) {
> +			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, 0);
> +			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, 0);
> +			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i);
> +
> +			break;
> +		}
> +	}
> +}
> +
> +static int imx_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> +{
> +	struct imx_pcie *imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> +	u32 sid_i, sid_m, rid = pci_dev_id(pdev);
> +	struct device_node *target;
> +	struct device *dev;
> +	int err_i, err_m;
> +
> +	dev = imx_pcie->pci->dev;
> +
> +	target = NULL;
> +	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
> +	if (target)
> +		of_node_put(target);
> +	else
> +		err_i = -EINVAL;

Why ? If target == NULL err_i is already set to a negative value ?

> +
> +	target = NULL;
> +	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
> +
> +	/*
> +	 * Return failure if msi-map exist and no entry for RID because dwc common
> +	 * driver will skip setting up built-in MSI controller if msi-map existed.

This is not ideal - to depend on the DWC common driver behaviour.

> +	 *
> +	 *   err_m      target
> +	 *	0	NULL		Return failure, function not work.
> +	 *      !0      NULL		msi-map not exist, use built-in MSI.
					^^^^
"function not work" does not mean anything, sorry. What is it meant to
say ?

!=0

> +	 *	0	!NULL		Find one entry.
> +	 *	!0	!NULL		Invalidate case.

"Find one entry", "Invalidate case", I don't understand what they mean.

!=0 !=NULL

> +	 */
> +	if (!err_m && !target)
> +		return -EINVAL;
> +	else if (target)
> +		of_node_put(target); /* Find entry for RID in msi-map */
> +
> +	/*
> +	 * msi-map        iommu-map
> +	 *   Y                Y            ITS + SMMU, require the same sid
> +	 *   Y                N            ITS
> +	 *   N                Y            DWC MSI Ctrl + SMMU
> +	 *   N                N            DWC MSI Ctrl
> +	 */
> +	if (!err_i && !err_m)
> +		if ((sid_i & IMX95_SID_MASK) != (sid_m & IMX95_SID_MASK)) {

Here you mask sid_i

> +			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
> +			return -EINVAL;
> +		}
> +
> +	/*
> +	 * Both iommu-map and msi-map not exist, use dwc built-in MSI
> +	 * controller, do nothing here.
> +	 */
> +	if (err_i && err_m)
> +		return 0;
> +
> +	if (!err_i)
> +		return imx_pcie_add_lut(imx_pcie, rid, sid_i);

Here you don't ?

Moreover - this would also cater for the case where (!err_i && !err_m) is
true ?

Probably cleaner to do:
	u32 sid;

	if (err_i && err_m)
		return 0;

	if (!err_i && !err_m) {
		if ((sid_i & IMX95_SID_MASK) != (sid_m & IMX95_SID_MASK)) {
			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
			return -EINVAL;
		}
	}

	if (!err_i)
		sid = sid_i & IMX95_SID_MASK;
	else if (!err_m)
		sid = sid_m & IMX95_SID_MASK;

	return imx_pcie_add_lut(imx_pcie, rid, sid);
> +	else if (!err_m)
> +		/*
> +		 * Hardware auto add 2 bits controller id ahead of stream ID,
> +		 * so mask this 2bits to get stream ID.
> +		 */
> +		return imx_pcie_add_lut(imx_pcie, rid, sid_m & IMX95_SID_MASK);
> +
> +	return 0;

return 0; is dead code AFAICS.

> +}
> +
> +static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> +{
> +	struct imx_pcie *imx_pcie;
> +
> +	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> +	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
> +}
> +
>  static int imx_pcie_host_init(struct dw_pcie_rp *pp)
>  {
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -946,6 +1119,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
>  		}
>  	}
>  
> +	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
> +		pp->bridge->enable_device = imx_pcie_enable_device;
> +		pp->bridge->disable_device = imx_pcie_disable_device;
> +	}
> +
>  	imx_pcie_assert_core_reset(imx_pcie);
>  
>  	if (imx_pcie->drvdata->init_phy)
> @@ -1330,6 +1508,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
>  	imx_pcie->pci = pci;
>  	imx_pcie->drvdata = of_device_get_match_data(dev);
>  
> +	mutex_init(&imx_pcie->lock);
> +
>  	/* Find the PHY if one is defined, only imx7d uses it */
>  	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
>  	if (np) {
> @@ -1627,7 +1807,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
>  	},
>  	[IMX95] = {
>  		.variant = IMX95,
> -		.flags = IMX_PCIE_FLAG_HAS_SERDES,
> +		.flags = IMX_PCIE_FLAG_HAS_SERDES |
> +			 IMX_PCIE_FLAG_HAS_LUT,
>  		.clk_names = imx8mq_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
>  		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> 
> -- 
> 2.34.1
> 


From miquel.raynal at bootlin.com  Thu Dec  5 02:26:30 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 05 Dec 2024 11:26:30 +0100
Subject: [PATCH v10 0/2] Add support for nuvoton ma35 nand controller
In-Reply-To: <20241204025129.150525-1-hpchen0nvt@gmail.com> (Hui-Ping Chen's
	message of "Wed, 4 Dec 2024 02:51:27 +0000")
References: <20241204025129.150525-1-hpchen0nvt@gmail.com>
Message-ID: <878qsuwhm1.fsf@bootlin.com>

Hi,

On 04/12/2024 at 02:51:27 GMT, Hui-Ping Chen <hpchen0nvt at gmail.com> wrote:

> This patch series adds the mtd nand driver for the nuvoton ma35 ARMv8 SoC.
> It includes DT binding documentation and the ma35 mtd nand driver.
>
> v10:
>   - Update ma35d1 mtd nand driver
>     - Add unsupported write page handling.

I was about to apply it but...

    [31m?[0m checkpatch.pl: 117: WARNING: please write a help paragraph that fully describes the config symbol
    [31m?[0m checkpatch.pl: 141: WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
    [31m?[0m checkpatch.pl: 348: CHECK: spaces preferred around that '+' (ctx:VxV)
    [31m?[0m checkpatch.pl: 352: CHECK: spaces preferred around that '+' (ctx:VxV)
    [31m?[0m checkpatch.pl: 352: CHECK: spaces preferred around that '+' (ctx:VxV)
    [31m?[0m checkpatch.pl: 429: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 465: CHECK: spaces preferred around that '*' (ctx:VxV)
    [31m?[0m checkpatch.pl: 465: CHECK: spaces preferred around that '+' (ctx:VxV)
    [31m?[0m checkpatch.pl: 466: CHECK: spaces preferred around that '*' (ctx:VxV)
    [31m?[0m checkpatch.pl: 466: CHECK: spaces preferred around that '+' (ctx:VxV)
    [31m?[0m checkpatch.pl: 467: CHECK: spaces preferred around that '*' (ctx:VxV)
    [31m?[0m checkpatch.pl: 467: CHECK: spaces preferred around that '+' (ctx:VxV)
    [31m?[0m checkpatch.pl: 468: CHECK: spaces preferred around that '*' (ctx:VxV)
    [31m?[0m checkpatch.pl: 468: CHECK: spaces preferred around that '+' (ctx:VxV)
    [31m?[0m checkpatch.pl: 479: CHECK: spaces preferred around that '*' (ctx:VxV)
    [31m?[0m checkpatch.pl: 479: CHECK: spaces preferred around that '+' (ctx:VxV)
    [31m?[0m checkpatch.pl: 481: CHECK: spaces preferred around that '*' (ctx:VxV)
    [31m?[0m checkpatch.pl: 481: CHECK: spaces preferred around that '+' (ctx:VxV)
    [31m?[0m checkpatch.pl: 514: CHECK: Unbalanced braces around else statement
    [31m?[0m checkpatch.pl: 611: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 650: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 665: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 675: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 689: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 699: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 715: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 756: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 805: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 935: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 950: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 953: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 975: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 1001: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 1018: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 1131: CHECK: Alignment should match open parenthesis
    [31m?[0m checkpatch.pl: 1159: WARNING: DT compatible string "nuvoton,ma35d1-nand" appears un-documented -- check ./Documentation/devicetree/bindings/

Please fix these warnings and checks.

You might want to use --strict by default.

Thanks,
Miqu?l


From sudeep.holla at arm.com  Thu Dec  5 02:31:03 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu,  5 Dec 2024 10:31:03 +0000
Subject: [PATCH] arm64: dts: fvp: Update bus-range property
In-Reply-To: <20241128152543.1821878-1-aneesh.kumar@kernel.org>
References: <20241128152543.1821878-1-aneesh.kumar@kernel.org>
Message-ID: <173339457335.691023.1334271427632194234.b4-ty@arm.com>

On Thu, 28 Nov 2024 20:55:43 +0530, Aneesh Kumar K.V (Arm) wrote:
> These days, the Fixed Virtual Platforms(FVP) Base RevC model supports
> more PCI devices. Update the max bus number so that Linux can enumerate
> them correctly. Without this, the kernel throws the below error while
> booting with the default hierarchy
>
> pci_bus 0000:01: busn_res: [bus 01] end is updated to 01
> pci_bus 0000:02: busn_res: can not insert [bus 02-01] under [bus 00-01] (conflicts with (null) [bus 00-01])
> pci_bus 0000:02: busn_res: [bus 02-01] end is updated to 02
> pci_bus 0000:02: busn_res: can not insert [bus 02] under [bus 00-01] (conflicts with (null) [bus 00-01])
> pci_bus 0000:03: busn_res: can not insert [bus 03-01] under [bus 00-01] (conflicts with (null) [bus 00-01])
> pci_bus 0000:03: busn_res: [bus 03-01] end is updated to 03
> pci_bus 0000:03: busn_res: can not insert [bus 03] under [bus 00-01] (conflicts with (null) [bus 00-01])
> pci_bus 0000:04: busn_res: can not insert [bus 04-01] under [bus 00-01] (conflicts with (null) [bus 00-01])
> pci_bus 0000:04: busn_res: [bus 04-01] end is updated to 04
> pci_bus 0000:04: busn_res: can not insert [bus 04] under [bus 00-01] (conflicts with (null) [bus 00-01])
> pci 0000:00:01.0: BAR 14: assigned [mem 0x50000000-0x500fffff]
>
> [...]

Applied to sudeep.holla/linux (for-next/juno/fixes), thanks!

[1/1] arm64: dts: fvp: Update bus-range property
      https://git.kernel.org/sudeep.holla/c/4f776d81bf92
--
Regards,
Sudeep



From lpieralisi at kernel.org  Thu Dec  5 02:30:36 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Thu, 5 Dec 2024 11:30:36 +0100
Subject: [PATCH v7 1/2] PCI: Add enable_device() and disable_device()
 callbacks for bridges
In-Reply-To: <20241203-imx95_lut-v7-1-d0cd6293225e@nxp.com>
References: <20241203-imx95_lut-v7-0-d0cd6293225e@nxp.com>
 <20241203-imx95_lut-v7-1-d0cd6293225e@nxp.com>
Message-ID: <Z1GAzI+tNqVv5Fbg@lpieralisi>

On Tue, Dec 03, 2024 at 06:27:15PM -0500, Frank Li wrote:
> Some PCIe host bridges require special handling when enabling or disabling
> PCIe Endpoints. For example, the i.MX95 platform has a lookup table to map
> Requester IDs to StreamIDs, which are used by the SMMU and MSI controller
> to identify the source of DMA accesses.
> 
> Without this mapping, DMA accesses may target unintended memory, which
> would corrupt memory or read the wrong data.
> 
> Add a host bridge .enable_device() hook the imx6 driver can use to
> configure the Requester ID to StreamID mapping. The hardware table isn't
> big enough to map all possible Requester IDs, so this hook may fail if no
> table space is available. In that case, return failure from
> pci_enable_device().
> 
> It might make more sense to make pci_set_master() decline to enable bus
> mastering and return failure, but it currently doesn't have a way to return
> failure.
> 
> Reviewed-by: Marc Zyngier <maz at kernel.org>
> Tested-by: Marc Zyngier <maz at kernel.org>
> Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> Change from v5 to v6
> - Add Marc testedby and Reviewed-by tag
> - Add Mani's acked tag
> 
> Change from v4 to v5
> - Add two static help functions
> int pci_host_bridge_enable_device(dev);
> void pci_host_bridge_disable_device(dev);
> - remove tags because big change
> Acked-by: Bjorn Helgaas <bhelgaas at google.com>

I can pick it up when Bjorn acks it.

> Reviewed-by: Marc Zyngier <maz at kernel.org>
> Tested-by: Marc Zyngier <maz at kernel.org>
> 
> Change from v3 to v4
> - Add Bjorn's ack tag
> 
> Change from v2 to v3
> - use Bjorn suggest's commit message.
> - call disable_device() when error happen.
> 
> Change from v1 to v2
> - move enable(disable)device ops to pci_host_bridge
> ---
>  drivers/pci/pci.c   | 36 +++++++++++++++++++++++++++++++++++-
>  include/linux/pci.h |  2 ++
>  2 files changed, 37 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 0b29ec6e8e5e2..773ca3cbd3221 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -2059,6 +2059,28 @@ int __weak pcibios_enable_device(struct pci_dev *dev, int bars)
>  	return pci_enable_resources(dev, bars);
>  }
>  
> +static int pci_host_bridge_enable_device(struct pci_dev *dev)
> +{
> +	struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus);
> +	int err;
> +
> +	if (host_bridge && host_bridge->enable_device) {
> +		err = host_bridge->enable_device(host_bridge, dev);
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static void pci_host_bridge_disable_device(struct pci_dev *dev)
> +{
> +	struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus);
> +
> +	if (host_bridge && host_bridge->disable_device)
> +		host_bridge->disable_device(host_bridge, dev);
> +}
> +
>  static int do_pci_enable_device(struct pci_dev *dev, int bars)
>  {
>  	int err;
> @@ -2074,9 +2096,13 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
>  	if (bridge)
>  		pcie_aspm_powersave_config_link(bridge);
>  
> +	err = pci_host_bridge_enable_device(dev);
> +	if (err)
> +		return err;
> +
>  	err = pcibios_enable_device(dev, bars);

Next in line is removing pcibios_enable_device() arch callbacks and move
that code into bridge callbacks to do the same, we can do it later.

Lorenzo

>  	if (err < 0)
> -		return err;
> +		goto err_enable;
>  	pci_fixup_device(pci_fixup_enable, dev);
>  
>  	if (dev->msi_enabled || dev->msix_enabled)
> @@ -2091,6 +2117,12 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
>  	}
>  
>  	return 0;
> +
> +err_enable:
> +	pci_host_bridge_disable_device(dev);
> +
> +	return err;
> +
>  }
>  
>  /**
> @@ -2274,6 +2306,8 @@ void pci_disable_device(struct pci_dev *dev)
>  	if (atomic_dec_return(&dev->enable_cnt) != 0)
>  		return;
>  
> +	pci_host_bridge_disable_device(dev);
> +
>  	do_pci_disable_device(dev);
>  
>  	dev->is_busmaster = 0;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index db9b47ce3eefd..bcbef004dd561 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -595,6 +595,8 @@ struct pci_host_bridge {
>  	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
>  	int (*map_irq)(const struct pci_dev *, u8, u8);
>  	void (*release_fn)(struct pci_host_bridge *);
> +	int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
> +	void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
>  	void		*release_data;
>  	unsigned int	ignore_reset_delay:1;	/* For entire hierarchy */
>  	unsigned int	no_ext_tags:1;		/* No Extended Tags */
> 
> -- 
> 2.34.1
> 


From sudeep.holla at arm.com  Thu Dec  5 02:32:25 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu,  5 Dec 2024 10:32:25 +0000
Subject: [PATCH] firmware: arm_scmi: fix i.MX build dependency
In-Reply-To: <20241115230555.2435004-1-arnd@kernel.org>
References: <20241115230555.2435004-1-arnd@kernel.org>
Message-ID: <173339471403.691669.17537976195919564595.b4-ty@arm.com>

On Sat, 16 Nov 2024 00:05:18 +0100, Arnd Bergmann wrote:
> The newly added SCMI vendor driver references functions in the
> protocol driver but needs a Kconfig dependency to ensure it can link,
> essentially the Kconfig dependency needs to be reversed to match the
> link time dependency:
> 
> arm-linux-gnueabi-ld: sound/soc/fsl/fsl_mqs.o: in function `fsl_mqs_sm_write':
> fsl_mqs.c:(.text+0x1aa): undefined reference to `scmi_imx_misc_ctrl_set'
> arm-linux-gnueabi-ld: sound/soc/fsl/fsl_mqs.o: in function `fsl_mqs_sm_read':
> fsl_mqs.c:(.text+0x1ee): undefined reference to `scmi_imx_misc_ctrl_get'
> 
> [...]

Applied to sudeep.holla/linux (for-next/scmi/fixes), thanks!

[1/1] firmware: arm_scmi: fix i.MX build dependency
      https://git.kernel.org/sudeep.holla/c/514b2262ade4
--
Regards,
Sudeep



From kever.yang at rock-chips.com  Thu Dec  5 02:36:18 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Thu,  5 Dec 2024 18:36:18 +0800
Subject: [PATCH 1/6] dt-bindings: PCI: dwc: rockchip: Add rk3576 support
In-Reply-To: <20241205103623.878181-1-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
Message-ID: <20241205103623.878181-2-kever.yang@rock-chips.com>

rk3576 is using the same controller as rk3568.

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

 Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml
index 550d8a684af3..5328ccad7130 100644
--- a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml
@@ -26,6 +26,7 @@ properties:
       - const: rockchip,rk3568-pcie
       - items:
           - enum:
+              - rockchip,rk3576-pcie
               - rockchip,rk3588-pcie
           - const: rockchip,rk3568-pcie
 
-- 
2.25.1



From kever.yang at rock-chips.com  Thu Dec  5 02:36:17 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Thu,  5 Dec 2024 18:36:17 +0800
Subject: [PATCH 0/6] Rockchip: add Rockchip rk3576 EVB1 board
Message-ID: <20241205103623.878181-1-kever.yang@rock-chips.com>

This patch set is for rockchip rk3576 evb1.
Based on the naneng combphy patch from Frank Wang.


Kever Yang (6):
  dt-bindings: PCI: dwc: rockchip: Add rk3576 support
  dts: arm64: rockchip: Add rk3576 naneng combphy nodes
  dts: arm64: rockchip: Add rk3576 pcie nodes
  dt-bindings: arm: rockchip: Sort for rk3568 evb
  dt-bindings: arm: rockchip: Add rk3576 evb1 board
  arm64: dts: rockchip: Add rk3576 evb1 board

 .../devicetree/bindings/arm/rockchip.yaml     |  25 +-
 .../bindings/pci/rockchip-dw-pcie.yaml        |   1 +
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3576-evb1-v10.dts     | 699 ++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3576.dtsi      | 147 ++++
 5 files changed, 863 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts

-- 
2.25.1



From kever.yang at rock-chips.com  Thu Dec  5 02:36:19 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Thu,  5 Dec 2024 18:36:19 +0800
Subject: [PATCH 2/6] dts: arm64: rockchip: Add rk3576 naneng combphy nodes
In-Reply-To: <20241205103623.878181-1-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
Message-ID: <20241205103623.878181-3-kever.yang@rock-chips.com>

rk3576 has two naneng combo phy,
- combophy0 is used for one of pcie and sata;
- combophy is used for one of pcie, sata and usb3;

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 36 ++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index 436232ffe4d1..8938ec7c3bb4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1587,6 +1587,42 @@ uart11: serial at 2afd0000 {
 			status = "disabled";
 		};
 
+		combphy0_ps: phy at 2b050000 {
+			compatible = "rockchip,rk3576-naneng-combphy";
+			reg = <0x0 0x2b050000 0x0 0x100>;
+			#phy-cells = <1>;
+			clocks = <&cru CLK_REF_PCIE0_PHY>,
+				 <&cru PCLK_PCIE2_COMBOPHY0>,
+				 <&cru PCLK_PCIE0>;
+			clock-names = "refclk", "apbclk", "pipe_clk";
+			assigned-clocks = <&cru CLK_REF_PCIE0_PHY>;
+			assigned-clock-rates = <100000000>;
+			resets = <&cru SRST_P_PCIE2_COMBOPHY0>,
+				 <&cru SRST_PCIE0_PIPE_PHY>;
+			reset-names = "combphy-apb", "combphy";
+			rockchip,pipe-grf = <&php_grf>;
+			rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
+			status = "disabled";
+		};
+
+		combphy1_psu: phy at 2b060000 {
+			compatible = "rockchip,rk3576-naneng-combphy";
+			reg = <0x0 0x2b060000 0x0 0x100>;
+			#phy-cells = <1>;
+			clocks = <&cru CLK_REF_PCIE1_PHY>,
+				 <&cru PCLK_PCIE2_COMBOPHY1>,
+				 <&cru PCLK_PCIE1>;
+			clock-names = "refclk", "apbclk", "pipe_clk";
+			assigned-clocks = <&cru CLK_REF_PCIE1_PHY>;
+			assigned-clock-rates = <100000000>;
+			resets = <&cru SRST_P_PCIE2_COMBOPHY1>,
+				 <&cru SRST_PCIE1_PIPE_PHY>;
+			reset-names = "combphy-apb", "combphy";
+			rockchip,pipe-grf = <&php_grf>;
+			rockchip,pipe-phy-grf = <&pipe_phy1_grf>;
+			status = "disabled";
+		};
+
 		sram: sram at 3ff88000 {
 			compatible = "mmio-sram";
 			reg = <0x0 0x3ff88000 0x0 0x78000>;
-- 
2.25.1



From kever.yang at rock-chips.com  Thu Dec  5 02:36:20 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Thu,  5 Dec 2024 18:36:20 +0800
Subject: [PATCH 3/6] dts: arm64: rockchip: Add rk3576 pcie nodes
In-Reply-To: <20241205103623.878181-1-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
Message-ID: <20241205103623.878181-4-kever.yang@rock-chips.com>

rk3576 has two pcie controller, both are pcie2x1 used with
naneng-combphy.

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 111 +++++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index 8938ec7c3bb4..888af56530e8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1016,6 +1016,117 @@ qos_npu_m1ro: qos at 27f22100 {
 			reg = <0x0 0x27f22100 0x0 0x20>;
 		};
 
+		pcie0: pcie at 2a200000 {
+			compatible = "rockchip,rk3576-pcie", "rockchip,rk3568-pcie";
+			bus-range = <0x0 0xf>;
+			clocks = <&cru ACLK_PCIE0_MST>, <&cru ACLK_PCIE0_SLV>,
+				 <&cru ACLK_PCIE0_DBI>, <&cru PCLK_PCIE0>,
+				 <&cru CLK_PCIE0_AUX>;
+
+			clock-names = "aclk_mst", "aclk_slv",
+				      "aclk_dbi", "pclk",
+				      "aux";
+			device_type = "pci";
+			interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH 0>;
+			interrupt-names = "msi", "sys", "pmc", "msg", "legacy", "err";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie0_intc 0>,
+					<0 0 0 2 &pcie0_intc 1>,
+					<0 0 0 3 &pcie0_intc 2>,
+					<0 0 0 4 &pcie0_intc 3>;
+			linux,pci-domain = <0>;
+			num-ib-windows = <8>;
+			num-viewport = <8>;
+			num-ob-windows = <2>;
+			max-link-speed = <2>;
+			num-lanes = <1>;
+			phys = <&combphy0_ps PHY_TYPE_PCIE>;
+			phy-names = "pcie-phy";
+			power-domains = <&power RK3576_PD_PHP>;
+			ranges = <0x00000800 0x0 0x20000000 0x0 0x20000000 0x0 0x00100000
+				  0x81000000 0x0 0x20100000 0x0 0x20100000 0x0 0x00100000
+				  0x82000000 0x0 0x20200000 0x0 0x20200000 0x0 0x00e00000
+				  0x83000000 0x9 0x00000000 0x9 0x00000000 0x0 0x80000000>;
+			reg = <0x0 0x2a200000 0x0 0x00010000>,
+			      <0x0 0x22000000 0x0 0x00400000>,
+			      <0x0 0x20000000 0x0 0x00100000>;
+			reg-names = "apb", "dbi", "config";
+			resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
+			reset-names = "pipe", "p_pcie0";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			status = "disabled";
+
+			pcie0_intc: legacy-interrupt-controller {
+				interrupt-controller;
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 280 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
+
+		pcie1: pcie at 2a210000 {
+			compatible = "rockchip,rk3576-pcie", "rockchip,rk3568-pcie";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x20 0x2f>;
+			clocks = <&cru ACLK_PCIE1_MST>, <&cru ACLK_PCIE1_SLV>,
+				 <&cru ACLK_PCIE1_DBI>, <&cru PCLK_PCIE1>,
+				 <&cru CLK_PCIE1_AUX>;
+			clock-names = "aclk_mst", "aclk_slv",
+				      "aclk_dbi", "pclk",
+				      "aux";
+			device_type = "pci";
+			interrupts = <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH 0>,
+				     <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH 0>;
+			interrupt-names = "msi", "sys", "pmc", "msg", "legacy", "err";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie1_intc 0>,
+					<0 0 0 2 &pcie1_intc 1>,
+					<0 0 0 3 &pcie1_intc 2>,
+					<0 0 0 4 &pcie1_intc 3>;
+			linux,pci-domain = <0>;
+			num-ib-windows = <8>;
+			num-viewport = <8>;
+			num-ob-windows = <2>;
+			max-link-speed = <2>;
+			num-lanes = <1>;
+			phys = <&combphy1_psu PHY_TYPE_PCIE>;
+			phy-names = "pcie-phy";
+			power-domains = <&power RK3576_PD_SUBPHP>;
+			ranges = <0x00000800 0x0 0x21000000 0x0 0x21000000 0x0 0x00100000
+				  0x81000000 0x0 0x21100000 0x0 0x21100000 0x0 0x00100000
+				  0x82000000 0x0 0x21200000 0x0 0x21200000 0x0 0x00e00000
+				  0x83000000 0x9 0x80000000 0x9 0x80000000 0x0 0x80000000>;
+			reg = <0x0 0x2a210000 0x0 0x00010000>,
+			      <0x0 0x22400000 0x0 0x00400000>,
+			      <0x0 0x21000000 0x0 0x00100000>;
+			reg-names = "apb", "dbi", "config";
+			resets = <&cru SRST_PCIE1_POWER_UP>, <&cru SRST_P_PCIE1>;
+			reset-names = "pipe", "p_pcie1";
+			status = "disabled";
+
+			pcie1_intc: legacy-interrupt-controller {
+				interrupt-controller;
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 266 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
+
 		gmac0: ethernet at 2a220000 {
 			compatible = "rockchip,rk3576-gmac", "snps,dwmac-4.20a";
 			reg = <0x0 0x2a220000 0x0 0x10000>;
-- 
2.25.1



From kever.yang at rock-chips.com  Thu Dec  5 02:36:21 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Thu,  5 Dec 2024 18:36:21 +0800
Subject: [PATCH 4/6] dt-bindings: arm: rockchip: Sort for rk3568 evb
In-Reply-To: <20241205103623.878181-1-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
Message-ID: <20241205103623.878181-5-kever.yang@rock-chips.com>

The info for rk3568 should before rk3588.

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

 .../devicetree/bindings/arm/rockchip.yaml     | 20 +++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 753199a12923..45ee4bf7c80c 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -1006,6 +1006,16 @@ properties:
           - const: rockchip,rk3399-sapphire-excavator
           - const: rockchip,rk3399
 
+      - description: Rockchip RK3566 BOX Evaluation Demo board
+        items:
+          - const: rockchip,rk3566-box-demo
+          - const: rockchip,rk3566
+
+      - description: Rockchip RK3568 Evaluation board
+        items:
+          - const: rockchip,rk3568-evb1-v10
+          - const: rockchip,rk3568
+
       - description: Rockchip RK3588 Evaluation board
         items:
           - const: rockchip,rk3588-evb1-v10
@@ -1099,16 +1109,6 @@ properties:
           - const: zkmagic,a95x-z2
           - const: rockchip,rk3318
 
-      - description: Rockchip RK3566 BOX Evaluation Demo board
-        items:
-          - const: rockchip,rk3566-box-demo
-          - const: rockchip,rk3566
-
-      - description: Rockchip RK3568 Evaluation board
-        items:
-          - const: rockchip,rk3568-evb1-v10
-          - const: rockchip,rk3568
-
       - description: Sinovoip RK3308 Banana Pi P2 Pro
         items:
           - const: sinovoip,rk3308-bpi-p2pro
-- 
2.25.1



From kever.yang at rock-chips.com  Thu Dec  5 02:36:22 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Thu,  5 Dec 2024 18:36:22 +0800
Subject: [PATCH 5/6] dt-bindings: arm: rockchip: Add rk3576 evb1 board
In-Reply-To: <20241205103623.878181-1-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
Message-ID: <20241205103623.878181-6-kever.yang@rock-chips.com>

Add device tree documentation for rk3576-evb1-v10.

Signed-off-by: Kever Yang <kever.yang 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 45ee4bf7c80c..b2681a45867b 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -1016,6 +1016,11 @@ properties:
           - const: rockchip,rk3568-evb1-v10
           - const: rockchip,rk3568
 
+      - description: Rockchip RK3576 Evaluation board
+        items:
+          - const: rockchip,rk3576-evb1-v10
+          - const: rockchip,rk3576
+
       - description: Rockchip RK3588 Evaluation board
         items:
           - const: rockchip,rk3588-evb1-v10
-- 
2.25.1



From sudeep.holla at arm.com  Thu Dec  5 02:35:03 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu,  5 Dec 2024 10:35:03 +0000
Subject: [PATCH v2 0/2] small fixes for arm_ffa driver
In-Reply-To: <20241203143109.1030514-1-yeoreum.yun@arm.com>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
Message-ID: <173339480142.692288.1444653013736952859.b4-ty@arm.com>

On Tue, 03 Dec 2024 14:31:07 +0000, Yeoreum Yun wrote:
> This patchset small fixes for arm_ffa driver:
>     - change ffa_device_register()'s declaration and its return value.
>     - fix direct message request version 2 uuid setup.
>
>
> v1 -> v2:
>     - Restore error return in ffa_device_register().
>     - change type __be64 to unsigned long to suppress warning.
>
> [...]

Applied with some reformating/reworking of the commit messages including
$subject change to sudeep.holla/linux (for-next/ffa/fixes), thanks!

[1/2] firmware/arm_ffa: change ffa_device_register()'s parameters and return
      https://git.kernel.org/sudeep.holla/c/6fe437cfe2cd
[2/2] firmware/arm_ffa: remove __le64_to_cpu() when set uuid for direct msg v2
      https://git.kernel.org/sudeep.holla/c/81c8b1c2ef7a
--
Regards,
Sudeep



From krzk at kernel.org  Thu Dec  5 02:35:43 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 11:35:43 +0100
Subject: [PATCH v3 3/3] arm64: dts: exynosautov920: add watchdog DT node
In-Reply-To: <88950a3a-c3de-4ff5-9ff8-9b85e1b0ad14@kernel.org>
References: <20241021063903.793166-1-trunixs.kim@samsung.com>
 <CGME20241021063938epcas2p1c01c89badb532f08a46087a4907df7dc@epcas2p1.samsung.com>
 <20241021063903.793166-4-trunixs.kim@samsung.com>
 <961e1aca-cd90-4db1-87d7-afd2e542421e@kernel.org>
 <20241107103331.GA4818@www.linux-watchdog.org>
 <589c40e1-6a1c-4ef7-b0d8-b761b132578a@kernel.org>
 <20241107113325.GA5284@www.linux-watchdog.org>
 <c487babb-84a5-4e47-a58f-75fec55cbabb@kernel.org>
 <000201db46ac$8d7cfee0$a876fca0$@samsung.com>
 <88950a3a-c3de-4ff5-9ff8-9b85e1b0ad14@kernel.org>
Message-ID: <171072ed-c35f-430e-a8c0-5cf718efed0c@kernel.org>

On 05/12/2024 08:19, Krzysztof Kozlowski wrote:
>>>> But that's a never ending discussion, so we won't go into that :-).
>>>
>>> DTS is hardware description independent from Linux, therefore always goes
>>> separate way than Linux drivers.
>>>
>>> Best regards,
>>> Krzysztof
>>
>> I found that the first two patches have been added to the linux-next git, 
>> but the last patch has not yet been reviewed.
>>
>> I would appreciate it if you could take a look at this patch.
> 
> Since this patch was applied, I dropped from my queue. I don't have it
> in my inbox anymore. Please rebase, resolve any comments and resend.

I found it in my inbox and tried to apply but it fails:
error: patch failed: arch/arm64/boot/dts/exynos/exynosautov920.dtsi:172


please rebase and resend.

Best regards,
Krzysztof


From kever.yang at rock-chips.com  Thu Dec  5 02:36:23 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Thu,  5 Dec 2024 18:36:23 +0800
Subject: [PATCH 6/6] arm64: dts: rockchip: Add rk3576 evb1 board
In-Reply-To: <20241205103623.878181-1-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
Message-ID: <20241205103623.878181-7-kever.yang@rock-chips.com>

RK3576 EVB1 board features:
- Rockchip RK3576
- PMIC: RK806-2x2pcs+DiscretePower
- RAM: LPDDR4/4x 2pcsx 32bit
- ROM: eMMC5.1 + UFS
- LAN x 2
- HDMI TX
- SD card slot
- PCIe2 slot

Add support for pmic, eMMC, SD-card, ADC-KEY, PCIE and GMAC.

NOTE: The board has a mux design for PCIe slot and USB3 host, and
default state is switch to USB3, need to switch to PCIe side to enable
the PCIe slot.

Signed-off-by: Liang Chen <cl at rock-chips.com>
Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3576-evb1-v10.dts     | 699 ++++++++++++++++++
 2 files changed, 700 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 86cc418a2255..2e683d7eab58 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -129,6 +129,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-display-vz.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-io-expander.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-sige7.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-w3.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-coolpi-cm5-evb.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts
new file mode 100644
index 000000000000..2b18bc1a4b72
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts
@@ -0,0 +1,699 @@
+// 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/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3576.dtsi"
+
+/ {
+	model = "Rockchip RK3576 EVB V10 Board";
+	compatible = "rockchip,rk3576-evb1-v10", "rockchip,rk3576";
+
+	aliases {
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
+	};
+
+	chosen: chosen {
+		stdout-path = "serial0:1500000n8";
+	};
+
+	adc_keys: adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		vol-up-key {
+			label = "volume up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <17000>;
+		};
+
+		vol-down-key {
+			label = "volume down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <417000>;
+		};
+
+		menu-key {
+			label = "menu";
+			linux,code = <KEY_MENU>;
+			press-threshold-microvolt = <890000>;
+		};
+
+		back-key {
+			label = "back";
+			linux,code = <KEY_BACK>;
+			press-threshold-microvolt = <1235000>;
+		};
+	};
+
+	leds: leds {
+		compatible = "gpio-leds";
+		work_led: work {
+			gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	vcc12v_dcin: regulator-vcc12v-dcin {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc_sys: regulator-vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_device: regulator-vcc5v0-device {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_device";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc_2v0_pldo_s3: regulator-vcc-2v0-pldo-s3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_2v0_pldo_s3";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <2000000>;
+		regulator-max-microvolt = <2000000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v1_nldo_s3";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc3v3_rtc_s5: regulator-vcc3v3-rtc-s5 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_rtc_s5";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc_1v8_s0: regulator-vcc-1v8-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_1v8_s3>;
+	};
+
+	vcc_3v3_s0: regulator-vcc-3v3-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	vcc_ufs_s0: regulator-vcc-ufs-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_ufs_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc1v8_ufs_vccq2_s0: regulator-vcc1v8-ufs-vccq2-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc1v8_ufs_vccq2_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_1v8_s3>;
+	};
+
+	vcc1v2_ufs_vccq_s0: regulator-vcc1v2-ufs-vccq-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc1v2_ufs_vccq_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc3v3_lcd_n: regulator-vcc3v3-lcd0-n {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_lcd0_n";
+		regulator-boot-on;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc_3v3_s0>;
+	};
+
+	vcc3v3_pcie0: regulator-vcc3v3-pcie0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_pcie1";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <5000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_host: regulator-vcc5v0-host {
+		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 = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc5v0_device>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_host_pwren>;
+	};
+
+	vbus5v0_typec: regulator-vbus5v0-typec {
+		compatible = "regulator-fixed";
+		regulator-name = "vbus5v0_typec";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc5v0_device>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_otg0_pwren>;
+	};
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu_big_s0>;
+};
+
+&combphy1_psu {
+	status = "okay";
+};
+
+&gmac0 {
+	phy-mode = "rgmii-rxid";
+	clock_in_out = "output";
+
+	snps,reset-gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 20000 100000>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&eth0m0_miim
+		     &eth0m0_tx_bus2
+		     &eth0m0_rx_bus2
+		     &eth0m0_rgmii_clk
+		     &eth0m0_rgmii_bus
+		     &ethm0_clk0_25m_out>;
+
+	tx_delay = <0x21>;
+
+	phy-handle = <&rgmii_phy0>;
+	status = "okay";
+};
+
+&gmac1 {
+	phy-mode = "rgmii-rxid";
+	clock_in_out = "output";
+
+	snps,reset-gpio = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 20000 100000>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&eth1m0_miim
+		     &eth1m0_tx_bus2
+		     &eth1m0_rx_bus2
+		     &eth1m0_rgmii_clk
+		     &eth1m0_rgmii_bus
+		     &ethm0_clk1_25m_out>;
+
+	tx_delay = <0x20>;
+
+	phy-handle = <&rgmii_phy1>;
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+
+	rk806: pmic at 23 {
+		compatible = "rockchip,rk806";
+		reg = <0x23>;
+
+		interrupt-parent = <&gpio0>;
+		interrupts = <6 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 = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc5-supply = <&vcc_sys>;
+		vcc6-supply = <&vcc_sys>;
+		vcc7-supply = <&vcc_sys>;
+		vcc8-supply = <&vcc_sys>;
+		vcc9-supply = <&vcc_sys>;
+		vcc10-supply = <&vcc_sys>;
+		vcc11-supply = <&vcc_2v0_pldo_s3>;
+		vcc12-supply = <&vcc_sys>;
+		vcc13-supply = <&vcc_1v1_nldo_s3>;
+		vcc14-supply = <&vcc_1v1_nldo_s3>;
+		vcca-supply = <&vcc_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";
+		};
+
+		rk806_dvs1_slp: dvs1-slp-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun1";
+		};
+
+		rk806_dvs1_pwrdn: dvs1-pwrdn-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun2";
+		};
+
+		rk806_dvs1_rst: dvs1-rst-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun3";
+		};
+
+		rk806_dvs2_slp: dvs2-slp-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun1";
+		};
+
+		rk806_dvs2_pwrdn: dvs2-pwrdn-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun2";
+		};
+
+		rk806_dvs2_rst: dvs2-rst-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun3";
+		};
+
+		rk806_dvs2_dvs: dvs2-dvs-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun4";
+		};
+
+		rk806_dvs2_gpio: dvs2-gpio-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun5";
+		};
+
+		rk806_dvs3_slp: dvs3-slp-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun1";
+		};
+
+		rk806_dvs3_pwrdn: dvs3-pwrdn-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun2";
+		};
+
+		rk806_dvs3_rst: dvs3-rst-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun3";
+		};
+
+		rk806_dvs3_dvs: dvs3-dvs-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun4";
+		};
+
+		rk806_dvs3_gpio: dvs3-gpio-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun5";
+		};
+
+		regulators {
+			vdd_cpu_big_s0: dcdc-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-init-microvolt = <850000>;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_cpu_big_s0";
+				regulator-enable-ramp-delay = <400>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_npu_s0: dcdc-reg2 {
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_npu_s0";
+				regulator-enable-ramp-delay = <400>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_lit_s0: dcdc-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-init-microvolt = <850000>;
+				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;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vcc_3v3_s3: dcdc-reg4 {
+				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>;
+				};
+			};
+
+			vdd_gpu_s0: dcdc-reg5 {
+				regulator-boot-on;
+				regulator-init-microvolt = <750000>;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <900000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_gpu_s0";
+				regulator-enable-ramp-delay = <400>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vddq_ddr_s0: dcdc-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vddq_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_logic_s0: dcdc-reg7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-init-microvolt = <750000>;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <800000>;
+				regulator-name = "vdd_logic_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s3: dcdc-reg8 {
+				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>;
+				};
+			};
+
+			vdd2_ddr_s3: dcdc-reg9 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vdd2_ddr_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_ddr_s0: dcdc-reg10 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-name = "vdd_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca_1v8_s0: pldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca_1v8_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pldo2_s0: pldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca1v8_pldo2_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_1v2_s0: pldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-name = "vdda_1v2_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca_3v3_s0: pldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcca_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;
+				};
+			};
+
+			vcca1v8_pldo6_s3: pldo-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca1v8_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 = <550000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdda_ddr_pll_s0: nldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdda_ddr_pll_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v75_hdmi_s0: nldo-reg3 {
+				regulator-boot-on;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
+				regulator-name = "vdda0v75_hdmi_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v85_s0: nldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdda_0v85_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v75_s0: nldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdda_0v75_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&mdio0 {
+	rgmii_phy0: phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+		clocks = <&cru REFCLKO25M_GMAC0_OUT>;
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+		clocks = <&cru REFCLKO25M_GMAC1_OUT>;
+	};
+};
+
+&pinctrl {
+	usb {
+		usb_host_pwren: usb-host-pwren {
+			rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usb_otg0_pwren: usb-otg0-pwren {
+			rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usbc0_int: usbc0-int {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&sdmmc {
+	max-frequency = <200000000>;
+	no-sdio;
+	no-mmc;
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	disable-wp;
+	sd-uhs-sdr104;
+	vqmmc-supply = <&vccio_sd_s0>;
+	status = "okay";
+};
+
+&pcie1 {
+	reset-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_pcie0>;
+	status = "okay";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vcca_1v8_s0>;
+};
+
+&uart0 {
+	status = "okay";
+};
-- 
2.25.1



From krzk at kernel.org  Thu Dec  5 02:39:54 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 11:39:54 +0100
Subject: [PATCH v5 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <6926509bd56cbb32125a978c939b28ab@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-4-linux@fw-web.de>
 <iwmnxlqpaijvr4kmzwk3elacqj5ukqlchfs67ca6c6gxrycpbb@pc6a6scqkdi5>
 <1DBA844B-4DB2-4AA2-BF04-B3CC39B3C3F8@public-files.de>
 <6ebd58fd-8461-476c-9266-a21455d5e819@kernel.org>
 <6926509bd56cbb32125a978c939b28ab@fw-web.de>
Message-ID: <8583b946-9ea9-4b06-88b6-683c64bf604c@kernel.org>

On 05/12/2024 10:18, Frank Wunderlich (linux) wrote:
>>> Is this an automatic message? I guess yes...
>>>
>>> I have not added it (robs reviewed-by) from v4 due to changes and 
>>> explained why in changelog. If i'm wrong please let me know.
>>
>> Where did you explain the reason of dropping review tag? This has to be
>> *EXPLICIT* but I only see:
>>
>> - rebased to 6.13-rc1
>> - moved dt nodes with mutliple options to BPI-R4 board
>> - changes suggested by angelo in v4
>> - changed example in binding and dt node to not using const 
>> MTK_DRIVE_8mA
>>
>>
>> Nothing here suggests even remotely that review tag was dropped. 
>> Nothing
>> suggests that it should be dropped!
> 
> here:
>>>>> changes in v5 (so not adding RB from Rob given in v4):
> 
Ah, indeed, I totally missed that. Sorry.

Best regards,
Krzysztof


From krzysztof.kozlowski at linaro.org  Thu Dec  5 02:42:06 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 05 Dec 2024 11:42:06 +0100
Subject: [PATCH v2 0/5] Cleanup Spreadtrum/Unisoc ARM64 DT (part 2)
In-Reply-To: <cover.1730918663.git.stano.jakubek@gmail.com>
References: <cover.1730918663.git.stano.jakubek@gmail.com>
Message-ID: <173339532634.70936.15343238064427564768.b4-ty@linaro.org>


On Wed, 06 Nov 2024 20:05:19 +0100, Stanislav Jakubek wrote:
> This series continues cleaning up various issues with the Spreadtrum/Unisoc
> ARM64 DeviceTrees.
> 
> Changes in V2:
> - dropped original patch 2, as it was split off into its own series [1]
> - new patches 2, 4 and 5 which fix some issues found by Rob's bot
>   and/or CHECK_DTBS=y
> - rebase on next-20241106
> 
> [...]

Applied, thanks!

[1/5] arm64: dts: sprd: sp9860g-1h10: fix constant-charge-voltage-max-microvolt property
      https://git.kernel.org/krzk/linux-dt/c/367d31471c3272b87a7e842355b2aa4bc688add8
[2/5] arm64: dts: sprd: sp9860g-1h10: fix factory-internal-resistance-micro-ohms property
      https://git.kernel.org/krzk/linux-dt/c/e864e215ce2197cd5d5c0e9229b4bb83379a5186
[3/5] arm64: dts: sprd: sc2731: move fuel-gauge monitored-battery to device DTS
      https://git.kernel.org/krzk/linux-dt/c/ec87fd9f66bb8196ce4c80b6f9a02a8fdb452821
[4/5] arm64: dts: sprd: sc9863a: fix in-ports property
      https://git.kernel.org/krzk/linux-dt/c/a34907f484949e3a550a54a19d71e8616d812d7e
[5/5] arm64: dts: sprd: sc9863a: reorder clocks, clock-names per bindings
      https://git.kernel.org/krzk/linux-dt/c/49f4ad82f031ac390ea4571a5bf7d58ee27ce4f2

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



From krzysztof.kozlowski at linaro.org  Thu Dec  5 02:42:07 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 05 Dec 2024 11:42:07 +0100
Subject: (subset) [PATCH treewide 00/11] ASoC: Clean up
 {hp,mic}-det-gpio handling
In-Reply-To: <cover.1727438777.git.geert+renesas@glider.be>
References: <cover.1727438777.git.geert+renesas@glider.be>
Message-ID: <173339532775.70936.4554643874403091214.b4-ty@linaro.org>


On Fri, 27 Sep 2024 14:42:15 +0200, Geert Uytterhoeven wrote:
> 	Hi all,
> 
> The "gpio" suffix for GPIO consumers was deprecated a while ago, in
> favor of the "gpios" suffix.  However, there are still several users of
> the "hp-det-gpio" and "mic-det-gpio" properties, in DT bindings,
> drivers, and DT source files.
> 
> [...]

Applied, thanks!

[03/11] ARM: dts: marvell: mmp2-olpc-xo-1-75: Switch to {hp,mic}-det-gpios
        https://git.kernel.org/krzk/linux-dt/c/62f95d8a4920706e94759a8f5e34677528530cf1
[08/11] arm64: dts: uniphier: Switch to hp-det-gpios
        https://git.kernel.org/krzk/linux-dt/c/751df73d825b3f7e6cad42ed333c28096635784d

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



From miquel.raynal at bootlin.com  Thu Dec  5 02:43:25 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu,  5 Dec 2024 11:43:25 +0100
Subject: [PATCH next] mtd: rawnand: fix double free in atmel_pmecc_create_user()
In-Reply-To: <7d809e5f-32e1-4438-9cc6-3167f27dd239@stanley.mountain>
References: <7d809e5f-32e1-4438-9cc6-3167f27dd239@stanley.mountain>
Message-ID: <173339519112.766262.17129619892556491178.b4-ty@bootlin.com>

On Wed, 23 Oct 2024 11:40:56 +0300, Dan Carpenter wrote:
> The "user" pointer was converted from being allocated with kzalloc() to
> being allocated by devm_kzalloc().  Calling kfree(user) will lead to a
> double free.
> 
> 

Applied to mtd/fixes, thanks!

[1/1] mtd: rawnand: fix double free in atmel_pmecc_create_user()

Patche(s) will be available within hours on:
mtd/linux.git

Kind regards,
Miqu?l


From jens.wiklander at linaro.org  Thu Dec  5 02:43:57 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 5 Dec 2024 11:43:57 +0100
Subject: [PATCH v3 1/4] tee: add restricted memory allocation
In-Reply-To: <CAFA6WYPVEzNLRL3sFUBgGGF_9m7tqGmg+h4TY5LDCAN5=qgBTg@mail.gmail.com>
References: <20241128150927.1377981-1-jens.wiklander@linaro.org>
 <20241128150927.1377981-2-jens.wiklander@linaro.org> <CAFA6WYPVEzNLRL3sFUBgGGF_9m7tqGmg+h4TY5LDCAN5=qgBTg@mail.gmail.com>
Message-ID: <CAHUa44EL-8OH4a9ZvW5v7s3eW14_eYaDJV1HR17exWH5roeUFA@mail.gmail.com>

Hi Sumit,

On Tue, Dec 3, 2024 at 8:58?AM Sumit Garg <sumit.garg at linaro.org> wrote:
>
> Hi Jens,
>
> On Thu, 28 Nov 2024 at 20:39, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> >
> > Add restricted memory allocation to the TEE subsystem. Restricted memory
> > is not be accessible by kernel during normal circumstances. A new ioctl
>
> s/not be accessible/not accessible/
>
> How about if we reword it as follows?
>
>     Restricted memory refers to memory buffers behind a hardware enforced
>     firewall. It is not accessible to the kernel during normal circumstances but
>     rather only accessible to certain hardware IPs or CPUs executing in higher
>     privileged mode than the kernel itself. This interface allows to
> allocate and
>     manage such restricted memory buffers via interaction with a TEE
>     implementation.

Sure, thanks.

>
> > TEE_IOC_RSTMEM_ALLOC is added to allocate these restricted memory
> > buffers.
> >
> > The restricted memory is allocated for a specific use-case, like Secure
> > Video Playback, Trusted UI, or Secure Video Recording where certain
> > hardware devices can access the memory.
> >
> > More use-cases can be added in userspace ABI, but it's up to the backend
> > drivers to provide the implementation.
> >
> > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > ---
> >  drivers/tee/Makefile       |   1 +
> >  drivers/tee/tee_core.c     |  37 ++++++-
> >  drivers/tee/tee_private.h  |   2 +
> >  drivers/tee/tee_rstmem.c   | 201 +++++++++++++++++++++++++++++++++++++
> >  drivers/tee/tee_shm.c      |   2 +
> >  drivers/tee/tee_shm_pool.c |  69 ++++++++++++-
> >  include/linux/tee_core.h   |  15 +++
> >  include/linux/tee_drv.h    |   4 +-
> >  include/uapi/linux/tee.h   |  37 ++++++-
> >  9 files changed, 363 insertions(+), 5 deletions(-)
> >  create mode 100644 drivers/tee/tee_rstmem.c
> >
> > diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
> > index 5488cba30bd2..a4c6b55444b9 100644
> > --- a/drivers/tee/Makefile
> > +++ b/drivers/tee/Makefile
> > @@ -3,6 +3,7 @@ obj-$(CONFIG_TEE) += tee.o
> >  tee-objs += tee_core.o
> >  tee-objs += tee_shm.o
> >  tee-objs += tee_shm_pool.o
> > +tee-objs += tee_rstmem.o
> >  obj-$(CONFIG_OPTEE) += optee/
> >  obj-$(CONFIG_AMDTEE) += amdtee/
> >  obj-$(CONFIG_ARM_TSTEE) += tstee/
> > diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
> > index d113679b1e2d..e81167826002 100644
> > --- a/drivers/tee/tee_core.c
> > +++ b/drivers/tee/tee_core.c
> > @@ -1,12 +1,13 @@
> >  // SPDX-License-Identifier: GPL-2.0-only
> >  /*
> > - * Copyright (c) 2015-2016, Linaro Limited
> > + * Copyright (c) 2015-2022, 2024, Linaro Limited
> >   */
> >
> >  #define pr_fmt(fmt) "%s: " fmt, __func__
> >
> >  #include <linux/cdev.h>
> >  #include <linux/cred.h>
> > +#include <linux/dma-buf.h>
> >  #include <linux/fs.h>
> >  #include <linux/idr.h>
> >  #include <linux/module.h>
> > @@ -815,6 +816,38 @@ static int tee_ioctl_supp_send(struct tee_context *ctx,
> >         return rc;
> >  }
> >
> > +static int
> > +tee_ioctl_rstmem_alloc(struct tee_context *ctx,
> > +                      struct tee_ioctl_rstmem_alloc_data __user *udata)
> > +{
> > +       struct tee_ioctl_rstmem_alloc_data data;
> > +       struct dma_buf *dmabuf;
> > +       int id;
> > +       int fd;
> > +
> > +       if (copy_from_user(&data, udata, sizeof(data)))
> > +               return -EFAULT;
> > +
> > +       if (data.use_case == TEE_IOC_UC_RESERVED)
> > +               return -EINVAL;
> > +
> > +       dmabuf = tee_rstmem_alloc(ctx, data.flags, data.use_case, data.size,
> > +                                 &id);
> > +       if (IS_ERR(dmabuf))
> > +               return PTR_ERR(dmabuf);
> > +       if (put_user(id, &udata->id)) {
> > +               fd = -EFAULT;
> > +               goto err;
> > +       }
> > +       fd = dma_buf_fd(dmabuf, O_CLOEXEC);
> > +       if (fd < 0)
> > +               goto err;
> > +       return fd;
> > +err:
> > +       dma_buf_put(dmabuf);
> > +       return fd;
> > +}
> > +
> >  static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> >  {
> >         struct tee_context *ctx = filp->private_data;
> > @@ -839,6 +872,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> >                 return tee_ioctl_supp_recv(ctx, uarg);
> >         case TEE_IOC_SUPPL_SEND:
> >                 return tee_ioctl_supp_send(ctx, uarg);
> > +       case TEE_IOC_RSTMEM_ALLOC:
> > +               return tee_ioctl_rstmem_alloc(ctx, uarg);
> >         default:
> >                 return -EINVAL;
> >         }
> > diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h
> > index 9bc50605227c..bf97796909c0 100644
> > --- a/drivers/tee/tee_private.h
> > +++ b/drivers/tee/tee_private.h
> > @@ -23,5 +23,7 @@ void teedev_ctx_put(struct tee_context *ctx);
> >  struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size);
> >  struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx,
> >                                           unsigned long addr, size_t length);
> > +struct dma_buf *tee_rstmem_alloc(struct tee_context *ctx, u32 flags,
> > +                                u32 use_case, size_t size, int *shm_id);
> >
> >  #endif /*TEE_PRIVATE_H*/
> > diff --git a/drivers/tee/tee_rstmem.c b/drivers/tee/tee_rstmem.c
> > new file mode 100644
> > index 000000000000..536bca2901e2
> > --- /dev/null
> > +++ b/drivers/tee/tee_rstmem.c
> > @@ -0,0 +1,201 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (c) 2024 Linaro Limited
> > + */
> > +#include <linux/device.h>
> > +#include <linux/dma-buf.h>
> > +#include <linux/genalloc.h>
> > +#include <linux/scatterlist.h>
> > +#include <linux/slab.h>
> > +#include <linux/tee_core.h>
> > +#include "tee_private.h"
> > +
> > +struct tee_rstmem_attachment {
> > +       struct sg_table table;
> > +       struct device *dev;
> > +};
> > +
> > +static int rstmem_dma_attach(struct dma_buf *dmabuf,
> > +                            struct dma_buf_attachment *attachment)
> > +{
> > +       struct tee_shm *shm = dmabuf->priv;
> > +       struct tee_rstmem_attachment *a;
> > +       int rc;
> > +
> > +       a = kzalloc(sizeof(*a), GFP_KERNEL);
> > +       if (!a)
> > +               return -ENOMEM;
> > +
> > +       if (shm->pages) {
> > +               rc = sg_alloc_table_from_pages(&a->table, shm->pages,
> > +                                              shm->num_pages, 0,
> > +                                              shm->num_pages * PAGE_SIZE,
> > +                                              GFP_KERNEL);
> > +               if (rc)
> > +                       goto err;
> > +       } else {
> > +               rc = sg_alloc_table(&a->table, 1, GFP_KERNEL);
> > +               if (rc)
> > +                       goto err;
> > +               sg_set_page(a->table.sgl, phys_to_page(shm->paddr), shm->size,
> > +                           0);
> > +       }
> > +
> > +       a->dev = attachment->dev;
> > +       attachment->priv = a;
> > +
> > +       return 0;
> > +err:
> > +       kfree(a);
> > +       return rc;
> > +}
> > +
> > +static void rstmem_dma_detach(struct dma_buf *dmabuf,
> > +                             struct dma_buf_attachment *attachment)
> > +{
> > +       struct tee_rstmem_attachment *a = attachment->priv;
> > +
> > +       sg_free_table(&a->table);
> > +       kfree(a);
> > +}
> > +
> > +static struct sg_table *
> > +rstmem_dma_map_dma_buf(struct dma_buf_attachment *attachment,
> > +                      enum dma_data_direction direction)
> > +{
> > +       struct tee_rstmem_attachment *a = attachment->priv;
> > +       int ret;
> > +
> > +       ret = dma_map_sgtable(attachment->dev, &a->table, direction,
> > +                             DMA_ATTR_SKIP_CPU_SYNC);
> > +       if (ret)
> > +               return ERR_PTR(ret);
> > +
> > +       return &a->table;
> > +}
> > +
> > +static void rstmem_dma_unmap_dma_buf(struct dma_buf_attachment *attachment,
> > +                                    struct sg_table *table,
> > +                                    enum dma_data_direction direction)
> > +{
> > +       struct tee_rstmem_attachment *a = attachment->priv;
> > +
> > +       WARN_ON(&a->table != table);
> > +
> > +       dma_unmap_sgtable(attachment->dev, table, direction,
> > +                         DMA_ATTR_SKIP_CPU_SYNC);
> > +}
> > +
> > +static int rstmem_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
> > +                                          enum dma_data_direction direction)
> > +{
> > +       return -EPERM;
> > +}
> > +
> > +static int rstmem_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
> > +                                        enum dma_data_direction direction)
> > +{
> > +       return -EPERM;
> > +}
> > +
> > +static int rstmem_dma_buf_mmap(struct dma_buf *dmabuf,
> > +                              struct vm_area_struct *vma)
> > +{
> > +       return -EPERM;
> > +}
> > +
> > +static void rstmem_dma_buf_free(struct dma_buf *dmabuf)
> > +{
> > +       struct tee_shm *shm = dmabuf->priv;
> > +
> > +       tee_shm_put(shm);
> > +}
> > +
> > +static const struct dma_buf_ops rstmem_generic_buf_ops = {
> > +       .attach = rstmem_dma_attach,
> > +       .detach = rstmem_dma_detach,
> > +       .map_dma_buf = rstmem_dma_map_dma_buf,
> > +       .unmap_dma_buf = rstmem_dma_unmap_dma_buf,
> > +       .begin_cpu_access = rstmem_dma_buf_begin_cpu_access,
> > +       .end_cpu_access = rstmem_dma_buf_end_cpu_access,
> > +       .mmap = rstmem_dma_buf_mmap,
> > +       .release = rstmem_dma_buf_free,
> > +};
> > +
> > +struct dma_buf *tee_rstmem_alloc(struct tee_context *ctx, u32 flags,
> > +                                u32 use_case, size_t size, int *shm_id)
> > +{
> > +       struct tee_device *teedev = ctx->teedev;
> > +       DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
> > +       struct dma_buf *dmabuf;
> > +       struct tee_shm *shm;
> > +       void *ret;
> > +       int rc;
> > +
> > +       if (!tee_device_get(teedev))
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       if (!teedev->desc->ops->rstmem_alloc ||
> > +           !teedev->desc->ops->rstmem_free) {
> > +               dmabuf = ERR_PTR(-EINVAL);
> > +               goto err;
> > +       }
> > +
> > +       shm = kzalloc(sizeof(*shm), GFP_KERNEL);
> > +       if (!shm) {
> > +               dmabuf = ERR_PTR(-ENOMEM);
> > +               goto err;
> > +       }
> > +
> > +       refcount_set(&shm->refcount, 1);
> > +       shm->flags = TEE_SHM_RESTRICTED;
> > +       shm->use_case = use_case;
> > +       shm->ctx = ctx;
> > +
> > +       mutex_lock(&teedev->mutex);
> > +       shm->id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL);
> > +       mutex_unlock(&teedev->mutex);
> > +       if (shm->id < 0) {
> > +               dmabuf = ERR_PTR(shm->id);
> > +               goto err_kfree;
> > +       }
> > +
> > +       rc = teedev->desc->ops->rstmem_alloc(ctx, shm, flags, use_case, size);
> > +       if (rc) {
> > +               dmabuf = ERR_PTR(rc);
> > +               goto err_idr_remove;
> > +       }
> > +
> > +       mutex_lock(&teedev->mutex);
> > +       ret = idr_replace(&teedev->idr, shm, shm->id);
> > +       mutex_unlock(&teedev->mutex);
> > +       if (IS_ERR(ret)) {
> > +               dmabuf = ret;
> > +               goto err_rstmem_free;
> > +       }
> > +       teedev_ctx_get(ctx);
> > +
> > +       exp_info.ops = &rstmem_generic_buf_ops;
> > +       exp_info.size = shm->size;
> > +       exp_info.priv = shm;
> > +       dmabuf = dma_buf_export(&exp_info);
> > +       if (IS_ERR(dmabuf)) {
> > +               tee_shm_put(shm);
> > +               return dmabuf;
> > +       }
> > +
> > +       *shm_id = shm->id;
> > +       return dmabuf;
> > +
> > +err_rstmem_free:
> > +       teedev->desc->ops->rstmem_free(ctx, shm);
> > +err_idr_remove:
> > +       mutex_lock(&teedev->mutex);
> > +       idr_remove(&teedev->idr, shm->id);
> > +       mutex_unlock(&teedev->mutex);
> > +err_kfree:
> > +       kfree(shm);
> > +err:
> > +       tee_device_put(teedev);
> > +       return dmabuf;
> > +}
> > diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
> > index daf6e5cfd59a..416f7f25d885 100644
> > --- a/drivers/tee/tee_shm.c
> > +++ b/drivers/tee/tee_shm.c
> > @@ -55,6 +55,8 @@ static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm)
> >                                 "unregister shm %p failed: %d", shm, rc);
> >
> >                 release_registered_pages(shm);
> > +       } else if (shm->flags & TEE_SHM_RESTRICTED) {
> > +               teedev->desc->ops->rstmem_free(shm->ctx, shm);
> >         }
> >
> >         teedev_ctx_put(shm->ctx);
> > diff --git a/drivers/tee/tee_shm_pool.c b/drivers/tee/tee_shm_pool.c
> > index 80004b55628d..ee57ef157a77 100644
> > --- a/drivers/tee/tee_shm_pool.c
> > +++ b/drivers/tee/tee_shm_pool.c
> > @@ -1,9 +1,8 @@
> >  // SPDX-License-Identifier: GPL-2.0-only
> >  /*
> > - * Copyright (c) 2015, 2017, 2022 Linaro Limited
> > + * Copyright (c) 2015, 2017, 2022, 2024 Linaro Limited
> >   */
> >  #include <linux/device.h>
> > -#include <linux/dma-buf.h>
> >  #include <linux/genalloc.h>
> >  #include <linux/slab.h>
> >  #include <linux/tee_core.h>
> > @@ -90,3 +89,69 @@ struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
> >         return ERR_PTR(rc);
> >  }
> >  EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem);
> > +
> > +static int rstmem_pool_op_gen_alloc(struct tee_shm_pool *pool,
> > +                                   struct tee_shm *shm, size_t size,
> > +                                   size_t align)
> > +{
> > +       size_t sz = ALIGN(size, PAGE_SIZE);
> > +       phys_addr_t pa;
> > +
> > +       pa = gen_pool_alloc(pool->private_data, sz);
> > +       if (!pa)
> > +               return -ENOMEM;
> > +
> > +       shm->size = sz;
> > +       shm->paddr = pa;
> > +
> > +       return 0;
> > +}
> > +
> > +static void rstmem_pool_op_gen_free(struct tee_shm_pool *pool,
> > +                                   struct tee_shm *shm)
> > +{
> > +       gen_pool_free(pool->private_data, shm->paddr, shm->size);
> > +       shm->paddr = 0;
> > +}
> > +
> > +static struct tee_shm_pool_ops rstmem_pool_ops_generic = {
> > +       .alloc = rstmem_pool_op_gen_alloc,
> > +       .free = rstmem_pool_op_gen_free,
> > +       .destroy_pool = pool_op_gen_destroy_pool,
> > +};
> > +
> > +struct tee_shm_pool *tee_rstmem_gen_pool_alloc(phys_addr_t paddr, size_t size)
> > +{
> > +       const size_t page_mask = PAGE_SIZE - 1;
> > +       struct tee_shm_pool *pool;
> > +       int rc;
> > +
> > +       /* Check it's page aligned */
> > +       if ((paddr | size) & page_mask)
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       pool = kzalloc(sizeof(*pool), GFP_KERNEL);
> > +       if (!pool)
> > +               return ERR_PTR(-ENOMEM);
> > +
> > +       pool->private_data = gen_pool_create(PAGE_SHIFT, -1);
> > +       if (!pool->private_data) {
> > +               rc = -ENOMEM;
> > +               goto err_free;
> > +       }
> > +
> > +       rc = gen_pool_add(pool->private_data, paddr, size, -1);
> > +       if (rc)
> > +               goto err_free_pool;
> > +
> > +       pool->ops = &rstmem_pool_ops_generic;
> > +       return pool;
> > +
> > +err_free_pool:
> > +       gen_pool_destroy(pool->private_data);
> > +err_free:
> > +       kfree(pool);
> > +
> > +       return ERR_PTR(rc);
> > +}
> > +EXPORT_SYMBOL_GPL(tee_rstmem_gen_pool_alloc);
> > diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h
> > index a38494d6b5f4..608302f494fe 100644
> > --- a/include/linux/tee_core.h
> > +++ b/include/linux/tee_core.h
> > @@ -26,6 +26,7 @@
> >  #define TEE_SHM_USER_MAPPED    BIT(1)  /* Memory mapped in user space */
> >  #define TEE_SHM_POOL           BIT(2)  /* Memory allocated from pool */
> >  #define TEE_SHM_PRIV           BIT(3)  /* Memory private to TEE driver */
> > +#define TEE_SHM_RESTRICTED     BIT(4)  /* Restricted memory */
> >
> >  #define TEE_DEVICE_FLAG_REGISTERED     0x1
> >  #define TEE_MAX_DEV_NAME_LEN           32
> > @@ -76,6 +77,8 @@ struct tee_device {
> >   * @supp_send:         called for supplicant to send a response
> >   * @shm_register:      register shared memory buffer in TEE
> >   * @shm_unregister:    unregister shared memory buffer in TEE
> > + * @rstmem_alloc:      allocate restricted memory
> > + * @rstmem_free:       free restricted memory
> >   */
> >  struct tee_driver_ops {
> >         void (*get_version)(struct tee_device *teedev,
> > @@ -99,6 +102,9 @@ struct tee_driver_ops {
> >                             struct page **pages, size_t num_pages,
> >                             unsigned long start);
> >         int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm);
> > +       int (*rstmem_alloc)(struct tee_context *ctx, struct tee_shm *shm,
> > +                           u32 flags, u32 use_case, size_t size);
> > +       void (*rstmem_free)(struct tee_context *ctx, struct tee_shm *shm);
> >  };
> >
> >  /**
> > @@ -229,6 +235,15 @@ static inline void tee_shm_pool_free(struct tee_shm_pool *pool)
> >         pool->ops->destroy_pool(pool);
> >  }
> >
> > +/**
> > + * tee_rstmem_gen_pool_alloc() - Create a restricted memory manager
> > + * @paddr:     Physical address of start of pool
> > + * @size:      Size in bytes of the pool
> > + *
> > + * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
> > + */
> > +struct tee_shm_pool *tee_rstmem_gen_pool_alloc(phys_addr_t paddr, size_t size);
> > +
> >  /**
> >   * tee_get_drvdata() - Return driver_data pointer
> >   * @returns the driver_data pointer supplied to tee_register().
> > diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
> > index a54c203000ed..b7ee346e5e44 100644
> > --- a/include/linux/tee_drv.h
> > +++ b/include/linux/tee_drv.h
> > @@ -55,6 +55,7 @@ struct tee_context {
> >   * @pages:     locked pages from userspace
> >   * @num_pages: number of locked pages
> >   * @refcount:  reference counter
> > + * @use_case:  defined by TEE_IOC_UC_* in tee.h
> >   * @flags:     defined by TEE_SHM_* in tee_core.h
> >   * @id:                unique id of a shared memory object on this device, shared
> >   *             with user space
> > @@ -71,7 +72,8 @@ struct tee_shm {
> >         struct page **pages;
> >         size_t num_pages;
> >         refcount_t refcount;
> > -       u32 flags;
> > +       u16 use_case;
> > +       u16 flags;
>
> Shouldn't we keep them u32 instead to be aligned with user-space inputs?

Sure, that makes sense.

>
> >         int id;
> >         u64 sec_world_id;
> >  };
> > diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
> > index d0430bee8292..cdc8c82c9a38 100644
> > --- a/include/uapi/linux/tee.h
> > +++ b/include/uapi/linux/tee.h
> > @@ -1,5 +1,5 @@
> >  /*
> > - * Copyright (c) 2015-2016, Linaro Limited
> > + * Copyright (c) 2015-2017, 2020, 2024, Linaro Limited
> >   * All rights reserved.
> >   *
> >   * Redistribution and use in source and binary forms, with or without
> > @@ -48,6 +48,7 @@
> >  #define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */
> >  #define TEE_GEN_CAP_REG_MEM    (1 << 2)/* Supports registering shared memory */
> >  #define TEE_GEN_CAP_MEMREF_NULL        (1 << 3)/* NULL MemRef support */
> > +#define TEE_GEN_CAP_RSTMEM     (1 << 4)/* Supports restricted memory */
> >
> >  #define TEE_MEMREF_NULL                (__u64)(-1) /* NULL MemRef Buffer */
> >
> > @@ -389,6 +390,40 @@ struct tee_ioctl_shm_register_data {
> >   */
> >  #define TEE_IOC_SHM_REGISTER   _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \
> >                                      struct tee_ioctl_shm_register_data)
> > +
> > +#define TEE_IOC_UC_RESERVED            0
> > +#define TEE_IOC_UC_SECURE_VIDEO_PLAY   1
> > +#define TEE_IOC_UC_TRUSTED_UI          2
> > +#define TEE_IOC_UC_SECURE_VIDEO_RECORD 3
> > +
> > +/**
> > + * struct tee_ioctl_rstmem_alloc_data - Restricted memory allocate argument
> > + * @size:      [in/out] Size of restricted memory to allocate
> > + * @flags:     [in/out] Flags to/from allocate
> > + * @use_case   [in] Restricted memory use case, TEE_IOC_UC_*
> > + * @id:                [out] Identifier of the restricted memory
> > + */
> > +struct tee_ioctl_rstmem_alloc_data {
> > +       __u64 size;
> > +       __u32 flags;
> > +       __u32 use_case;
> > +       __s32 id;
> > +};
> > +
> > +/**
> > + * TEE_IOC_RSTMEM_ALLOC - allocate restricted memory
> > + *
> > + * Allocates restricted physically memory normally not accessible by the
> > + * kernel.
>
> Can we elaborate here as well on similar lines as per commit message?

OK, I'll add something.

Thanks,
Jens

>
> -Sumit
>
> > + *
> > + * Returns a file descriptor on success or < 0 on failure
> > + *
> > + * The returned file descriptor is a dma-buf that can be attached and
> > + * mapped for device with permission to access the physical memory.
> > + */
> > +#define TEE_IOC_RSTMEM_ALLOC     _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 10, \
> > +                                      struct tee_ioctl_rstmem_alloc_data)
> > +
> >  /*
> >   * Five syscalls are used when communicating with the TEE driver.
> >   * open(): opens the device associated with the driver
> > --
> > 2.43.0
> >


From quic_sibis at quicinc.com  Thu Dec  5 02:56:55 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Thu, 5 Dec 2024 16:26:55 +0530
Subject: [PATCH V4 0/5] arm_scmi: vendors: Qualcomm Generic Vendor
 Extensions
In-Reply-To: <Z0BC203BhGEmXcJi@hovoldconsulting.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <ZytnRc94iKUfMYH0@hovoldconsulting.com> <ZyvLktLUZOGP-LH5@pluto>
 <Zy4qvedrmkRdPR3x@hovoldconsulting.com>
 <8d42682b-0fa7-3962-da12-728cfe64903b@quicinc.com>
 <Z0BC203BhGEmXcJi@hovoldconsulting.com>
Message-ID: <d61bb7bc-d824-883a-4edd-109ae74076c1@quicinc.com>



On 11/22/24 14:07, Johan Hovold wrote:
> On Thu, Nov 14, 2024 at 09:52:12AM +0530, Sibi Sankar wrote:
>> On 11/8/24 20:44, Johan Hovold wrote:
> 
>>>> On Wed, Nov 06, 2024 at 01:55:33PM +0100, Johan Hovold wrote:
> 
>>>>> Second, after loading the protocol and client drivers manually (in that
>>>>> order, shouldn't the client driver pull in the protocol?), I got:
>>>>>
>>>>> 	scmi_module: Loaded SCMI Vendor Protocol 0x80 - Qualcomm  20000
>>>>> 	arm-scmi arm-scmi.0.auto: QCOM Generic Vendor Version 1.0
>>>>> 	scmi-qcom-generic-ext-memlat scmi_dev.5: error -EOPNOTSUPP: failed to configure common events
>>>>> 	scmi-qcom-generic-ext-memlat scmi_dev.5: probe with driver scmi-qcom-generic-ext-memlat failed with error -95
>>>>>
>>>>> which seems to suggest that the firmware on my CRD does not support this
>>>>> feature. Is that the way this should be interpreted? And does that mean
>>>>> that non of the commercial laptops supports this either?
> 
>>> Yeah, hopefully Sibi can shed some light on this. I'm using the DT
>>> patch (5/5) from this series, which according to the commit message is
>>> supposed to enable bus scaling on the x1e80100 platform. So I guess
>>> something is missing in my firmware.
>>
>> Nah, it's probably just because of the algo string used.
>> The past few series used caps MEMLAT string instead of
>> memlat to pass the tuneables, looks like all the laptops
>> havn't really switched to it yet. Will revert back to
>> using to lower case memlat so that all devices are
>> supported. Thanks for trying the series out!
> 
> I have a Lenovo ThinkPad T14s set up now so I gave this series a spin
> there too, and there I do *not* see the above mentioned -EOPNOSUPP error
> and the memlat driver probes successfully.
> 
> On the other hand, this series seems to have no effect on a kernel
> compilation benchmark. Is that expected?

I can have a look at your tree. But memlat in general
depends on the cpu frequency when your benchmarks max
the cpu's the ddr/llcc are scaled accordingly by it.

> 
> And does this mean that you should stick with the uppercase "MEMLAT"
> string after all? The firmware on my CRD is not the latest one, but I am
> using the latest available firmware for the T14s.

We should stick with "memlat" if we run into a device in the
wild that doesn't support "MEMLAT"

-Sibi

> 
> Johan
> 


From s-vadapalli at ti.com  Thu Dec  5 02:50:32 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 5 Dec 2024 16:20:32 +0530
Subject: [PATCH v4 0/4] Add PCIe Overlays for J721E, AM68 and AM69
Message-ID: <20241205105041.749576-1-s-vadapalli@ti.com>

Hello,

This series adds device-tree overlays for enabling Endpoint mode of
operation of the PCIe Controllers on TI's J721E, AM68 and AM69 SoCs.

Only the second patch of this series has a v3 while the rest of the
patches have been newly introduced in this series. The reason for
grouping patches is the dependency on the Makefile w.r.t. the changes
made in the patches when enabling overlays.

v3:
https://lore.kernel.org/r/20241010100933.2492806-1-s-vadapalli at ti.com/
Changes since v3:
- Rebased on next-20241204.

v2:
https://lore.kernel.org/r/20240222065733.1213434-1-s-vadapalli at ti.com/
Changes since v2:
- Rebased patch on next-20241010.
- Moved vendor specific property "ti,syscon-pcie-ctrl" to the end of the
  node.

v1:
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"

Series is based on linux-next tagged next-20241204.

Logs validating series:
1. J721E Overlay test logs:
https://gist.github.com/Siddharth-Vadapalli-at-TI/682d2469884d74ad73c3e6ab4b829067
2. AM68 Overlay test logs:
https://gist.github.com/Siddharth-Vadapalli-at-TI/b302475ee8ff257dab358a7ccfaaa734
3. AM69 Overlay test logs:
https://gist.github.com/Siddharth-Vadapalli-at-TI/c50e5a09b5af962cba722619974add2b

Regards,
Siddharth.

Siddharth Vadapalli (4):
  arm64: dts: ti: Makefile: Fix typo "k3-j7200-evm-pcie1-ep.dtbo"
  arm64: dts: ti: k3-j721e-evm: Add overlay for PCIE1 Endpoint Mode
  arm64: dts: ti: k3-am68-sk-base-board: Add overlay for PCIE1 Endpoint
    Mode
  arm64: dts: ti: k3-am69-sk: Add overlay for PCIE0 Endpoint Mode

 arch/arm64/boot/dts/ti/Makefile               | 15 +++++-
 .../ti/k3-am68-sk-base-board-pcie1-ep.dtso    | 53 +++++++++++++++++++
 .../boot/dts/ti/k3-am69-sk-pcie0-ep.dtso      | 53 +++++++++++++++++++
 .../boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso    | 53 +++++++++++++++++++
 4 files changed, 173 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am68-sk-base-board-pcie1-ep.dtso
 create mode 100644 arch/arm64/boot/dts/ti/k3-am69-sk-pcie0-ep.dtso
 create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso

-- 
2.43.0



From s-vadapalli at ti.com  Thu Dec  5 02:50:33 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 5 Dec 2024 16:20:33 +0530
Subject: [PATCH v4 1/4] arm64: dts: ti: Makefile: Fix typo "k3-j7200-evm-pcie1-ep.dtbo"
In-Reply-To: <20241205105041.749576-1-s-vadapalli@ti.com>
References: <20241205105041.749576-1-s-vadapalli@ti.com>
Message-ID: <20241205105041.749576-2-s-vadapalli@ti.com>

The list of "dtbs" should contain the resultant "dtb" formed by applying
the "dtbo" overlay on the base "dtb", rather than the "dtbo" itself.

Hence, change "k3-j7200-evm-pcie1-ep.dtbo" to "k3-j7200-evm-pcie1-ep.dtb"
in the list of "dtbs".

Fixes: f43ec89bbc83 ("arm64: dts: ti: k3-j7200-evm: Add overlay for PCIE1 Endpoint Mode")
Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

This patch has been newly introduced in this series.

 arch/arm64/boot/dts/ti/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index f71360f14f23..379bfa4425d4 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -230,7 +230,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
 	k3-am68-sk-base-board-csi2-dual-imx219.dtb \
 	k3-am69-sk-csi2-dual-imx219.dtb \
-	k3-j7200-evm-pcie1-ep.dtbo \
+	k3-j7200-evm-pcie1-ep.dtb \
 	k3-j721e-common-proc-board-infotainment.dtb \
 	k3-j721e-evm-pcie0-ep.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtb \
-- 
2.43.0



From s-vadapalli at ti.com  Thu Dec  5 02:50:34 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 5 Dec 2024 16:20:34 +0530
Subject: [PATCH v4 2/4] arm64: dts: ti: k3-j721e-evm: Add overlay for PCIE1 Endpoint Mode
In-Reply-To: <20241205105041.749576-1-s-vadapalli@ti.com>
References: <20241205105041.749576-1-s-vadapalli@ti.com>
Message-ID: <20241205105041.749576-3-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>
---
v3:
https://lore.kernel.org/r/20241010100933.2492806-1-s-vadapalli at ti.com/
Changes since v3:
- Rebased on next-20241204.

v2:
https://lore.kernel.org/r/20240222065733.1213434-1-s-vadapalli at ti.com/
Changes since v2:
- Rebased patch on next-20241010.
- Moved vendor specific property "ti,syscon-pcie-ctrl" to the end of the
  node.

v1:
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"

 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 379bfa4425d4..03bacbc589ee 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -107,6 +107,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721e-common-proc-board-infotainment.dtbo
 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
 
@@ -200,6 +201,8 @@ k3-j721e-common-proc-board-infotainment-dtbs := k3-j721e-common-proc-board.dtb \
 	k3-j721e-common-proc-board-infotainment.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 \
@@ -233,6 +236,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-j7200-evm-pcie1-ep.dtb \
 	k3-j721e-common-proc-board-infotainment.dtb \
 	k3-j721e-evm-pcie0-ep.dtb \
+	k3-j721e-evm-pcie1-ep.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtb \
 	k3-j721s2-evm-pcie1-ep.dtb \
 	k3-j784s4-evm-pcie0-pcie1-ep.dtb \
@@ -255,6 +259,7 @@ DTC_FLAGS_k3-am68-sk-base-board += -@
 DTC_FLAGS_k3-am69-sk += -@
 DTC_FLAGS_k3-j7200-common-proc-board += -@
 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 += -@
 DTC_FLAGS_k3-j784s4-evm += -@
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..a8cccdcf3e3b
--- /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>;
+		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";
+		ti,syscon-pcie-ctrl = <&scm_conf 0x4074>;
+	};
+};
-- 
2.43.0



From s-vadapalli at ti.com  Thu Dec  5 02:50:35 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 5 Dec 2024 16:20:35 +0530
Subject: [PATCH v4 3/4] arm64: dts: ti: k3-am68-sk-base-board: Add overlay for PCIE1 Endpoint Mode
In-Reply-To: <20241205105041.749576-1-s-vadapalli@ti.com>
References: <20241205105041.749576-1-s-vadapalli@ti.com>
Message-ID: <20241205105041.749576-4-s-vadapalli@ti.com>

Add overlay to enable the PCIE1 instance of PCIe on AM68-SK-Base-Board in
Endpoint mode of operation. PCIE1 on AM68-SK-Base-Board supports x2 Lane
operation unlike its counterpart on J721S2-EVM which supports x1 Lane.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

This patch has been newly introduced in this series.

 arch/arm64/boot/dts/ti/Makefile               |  4 ++
 .../ti/k3-am68-sk-base-board-pcie1-ep.dtso    | 53 +++++++++++++++++++
 2 files changed, 57 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am68-sk-base-board-pcie1-ep.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 03bacbc589ee..04438f7136b8 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -113,6 +113,7 @@ 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
+dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board-pcie1-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721s2-common-proc-board.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-gesi-exp-board.dtbo
 k3-j721s2-evm-dtbs := k3-j721s2-common-proc-board.dtb k3-j721s2-evm-gesi-exp-board.dtbo
@@ -193,6 +194,8 @@ 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-am68-sk-base-board-pcie1-ep-dtbs := k3-am68-sk-base-board.dtb \
+	k3-am68-sk-base-board-pcie1-ep.dtbo
 k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j7200-evm-pcie1-ep-dtbs := k3-j7200-common-proc-board.dtb \
@@ -232,6 +235,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
 	k3-am68-sk-base-board-csi2-dual-imx219.dtb \
+	k3-am68-sk-base-board-pcie1-ep.dtb \
 	k3-am69-sk-csi2-dual-imx219.dtb \
 	k3-j7200-evm-pcie1-ep.dtb \
 	k3-j721e-common-proc-board-infotainment.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board-pcie1-ep.dtso b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board-pcie1-ep.dtso
new file mode 100644
index 000000000000..455736e378cc
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board-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
+ * AM68-SK board.
+ *
+ * AM68-SK Board Product Link: https://www.ti.com/tool/SK-AM68
+ *
+ * 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,j7200-pcie-ep", "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>;
+		max-link-speed = <3>;
+		num-lanes = <2>;
+		power-domains = <&k3_pds 276 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 276 41>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes0_pcie_link>;
+		phy-names = "pcie-phy";
+		ti,syscon-pcie-ctrl = <&scm_conf 0x074>;
+	};
+};
-- 
2.43.0



From s-vadapalli at ti.com  Thu Dec  5 02:50:36 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 5 Dec 2024 16:20:36 +0530
Subject: [PATCH v4 4/4] arm64: dts: ti: k3-am69-sk: Add overlay for PCIE0 Endpoint Mode
In-Reply-To: <20241205105041.749576-1-s-vadapalli@ti.com>
References: <20241205105041.749576-1-s-vadapalli@ti.com>
Message-ID: <20241205105041.749576-5-s-vadapalli@ti.com>

Add overlay to enable the PCIE0 instance of PCIe on AM69-SK in Endpoint
mode of operation.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

This patch has been newly introduced in this series.

 arch/arm64/boot/dts/ti/Makefile               |  4 ++
 .../boot/dts/ti/k3-am69-sk-pcie0-ep.dtso      | 53 +++++++++++++++++++
 2 files changed, 57 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am69-sk-pcie0-ep.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 04438f7136b8..db5ae27467e7 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -126,6 +126,7 @@ 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-am69-sk-pcie0-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-pcie0-pcie1-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-quad-port-eth-exp1.dtbo
@@ -198,6 +199,8 @@ k3-am68-sk-base-board-pcie1-ep-dtbs := k3-am68-sk-base-board.dtb \
 	k3-am68-sk-base-board-pcie1-ep.dtbo
 k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-am69-sk-pcie0-ep-dtbs := k3-am69-sk.dtb \
+	k3-am69-sk-pcie0-ep.dtbo
 k3-j7200-evm-pcie1-ep-dtbs := k3-j7200-common-proc-board.dtb \
 	k3-j7200-evm-pcie1-ep.dtbo
 k3-j721e-common-proc-board-infotainment-dtbs := k3-j721e-common-proc-board.dtb \
@@ -237,6 +240,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am68-sk-base-board-csi2-dual-imx219.dtb \
 	k3-am68-sk-base-board-pcie1-ep.dtb \
 	k3-am69-sk-csi2-dual-imx219.dtb \
+	k3-am69-sk-pcie0-ep.dtb \
 	k3-j7200-evm-pcie1-ep.dtb \
 	k3-j721e-common-proc-board-infotainment.dtb \
 	k3-j721e-evm-pcie0-ep.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk-pcie0-ep.dtso b/arch/arm64/boot/dts/ti/k3-am69-sk-pcie0-ep.dtso
new file mode 100644
index 000000000000..9a5bcf282a9e
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk-pcie0-ep.dtso
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling PCIE0 instances of PCIe in Endpoint Configuration
+ * on AM69-SK.
+ *
+ * AM69-SK Product Link: https://www.ti.com/tool/SK-AM69
+ *
+ * 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.
+ */
+&pcie0_rc {
+	status = "disabled";
+};
+
+&cbass_main {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic500>;
+
+	pcie0_ep: pcie-ep at 2900000 {
+		compatible = "ti,j784s4-pcie-ep";
+		reg = <0x00 0x02900000 0x00 0x1000>,
+		      <0x00 0x02907000 0x00 0x400>,
+		      <0x00 0x0d000000 0x00 0x00800000>,
+		      <0x00 0x10000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>;
+		max-link-speed = <3>;
+		num-lanes = <4>;
+		power-domains = <&k3_pds 332 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 332 0>;
+		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";
+		ti,syscon-pcie-ctrl = <&pcie0_ctrl 0x0>;
+	};
+};
-- 
2.43.0



From quic_sibis at quicinc.com  Thu Dec  5 02:52:53 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Thu, 5 Dec 2024 16:22:53 +0530
Subject: [PATCH V4 4/5] soc: qcom: Introduce SCMI based Memlat (Memory
 Latency) governor
In-Reply-To: <34p27za5hcpubaxjuddsir2vqnqrvwyesnclu2cocvm3yhbv3r@ak7rcnp67gyd>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-5-quic_sibis@quicinc.com>
 <2aycrvnvivcrqctqmweadcgenwugafdr6ub3bzkscterpenz32@bzabln2hkral>
 <29eef87e-96f6-5105-6f7a-a8e01efcb4a3@quicinc.com>
 <k4lpzxtrq3x6riyv6etxiobn7nbpczf2bp3m4oc752nhjknlit@uo53kbppzim7>
 <ac655bdc-5ccf-c6c6-3203-659f1916c53c@quicinc.com>
 <34p27za5hcpubaxjuddsir2vqnqrvwyesnclu2cocvm3yhbv3r@ak7rcnp67gyd>
Message-ID: <1f5258f4-7c20-5343-dec6-0847449c821b@quicinc.com>



On 11/14/24 18:02, Dmitry Baryshkov wrote:
> On Thu, Nov 14, 2024 at 09:43:53AM +0530, Sibi Sankar wrote:
>>
>>
>> On 10/26/24 23:46, Dmitry Baryshkov wrote:
>>> On Tue, Oct 22, 2024 at 01:48:25PM +0530, Sibi Sankar wrote:
>>>>
>>>>
>>>> On 10/7/24 23:27, Dmitry Baryshkov wrote:
>>>>> On Mon, Oct 07, 2024 at 11:40:22AM GMT, Sibi Sankar wrote:
> 
>>>>>
>>>>>> +};
>>>>>> +
>>>>>> +struct map_param_msg {
>>>>>> +	u32 hw_type;
>>>>>> +	u32 mon_idx;
>>>>>> +	u32 nr_rows;
>>>>>> +	struct map_table tbl[MAX_MAP_ENTRIES];
>>>>>> +} __packed;
>>>>>> +
>>>>>> +struct node_msg {
>>>>>> +	u32 cpumask;
>>>>>> +	u32 hw_type;
>>>>>> +	u32 mon_type;
>>>>>> +	u32 mon_idx;
>>>>>> +	char mon_name[MAX_NAME_LEN];
>>>>>> +};
>>>>>> +
>>>>>> +struct scalar_param_msg {
>>>>>> +	u32 hw_type;
>>>>>> +	u32 mon_idx;
>>>>>> +	u32 val;
>>>>>> +};
>>>>>> +
>>>>>> +enum common_ev_idx {
>>>>>> +	INST_IDX,
>>>>>> +	CYC_IDX,
>>>>>> +	CONST_CYC_IDX,
>>>>>> +	FE_STALL_IDX,
>>>>>> +	BE_STALL_IDX,
>>>>>> +	NUM_COMMON_EVS
>>>>>> +};
>>>>>> +
>>>>>> +enum grp_ev_idx {
>>>>>> +	MISS_IDX,
>>>>>> +	WB_IDX,
>>>>>> +	ACC_IDX,
>>>>>> +	NUM_GRP_EVS
>>>>>> +};
>>>>>> +
>>>>>> +#define EV_CPU_CYCLES		0
>>>>>> +#define EV_INST_RETIRED		2
>>>>>> +#define EV_L2_D_RFILL		5
>>>>>> +
>>>>>> +struct ev_map_msg {
>>>>>> +	u32 num_evs;
>>>>>> +	u32 hw_type;
>>>>>> +	u32 cid[NUM_COMMON_EVS];
>>>>>> +};
>>>>>> +
>>>>>> +struct cpufreq_memfreq_map {
>>>>>> +	unsigned int cpufreq_mhz;
>>>>>> +	unsigned int memfreq_khz;
>>>>>> +};
>>>>>> +
>>>>>> +struct scmi_monitor_info {
>>>>>> +	struct cpufreq_memfreq_map *freq_map;
>>>>>> +	char mon_name[MAX_NAME_LEN];
>>>>>> +	u32 mon_idx;
>>>>>> +	u32 mon_type;
>>>>>> +	u32 ipm_ceil;
>>>>>> +	u32 mask;
>>>>>> +	u32 freq_map_len;
>>>>>> +};
>>>>>> +
>>>>>> +struct scmi_memory_info {
>>>>>> +	struct scmi_monitor_info *monitor[MAX_MONITOR_CNT];
>>>>>> +	u32 hw_type;
>>>>>> +	int monitor_cnt;
>>>>>> +	u32 min_freq;
>>>>>> +	u32 max_freq;
>>>>>> +};
>>>>>> +
>>>>>> +struct scmi_memlat_info {
>>>>>> +	struct scmi_protocol_handle *ph;
>>>>>> +	const struct qcom_generic_ext_ops *ops;
>>>>>> +	struct scmi_memory_info *memory[MAX_MEMORY_TYPES];
>>>>>> +	u32 cluster_info[NR_CPUS];
>>>>>> +	int memory_cnt;
>>>>>> +};
>>>>>> +
>>>>>> +static int populate_cluster_info(u32 *cluster_info)
>>>>>> +{
>>>>>> +	char name[MAX_NAME_LEN];
>>>>>> +	int i = 0;
>>>>>> +
>>>>>> +	struct device_node *cn __free(device_node) = of_find_node_by_path("/cpus");
>>>>>> +	if (!cn)
>>>>>> +		return -ENODEV;
>>>>>> +
>>>>>> +	struct device_node *map __free(device_node) = of_get_child_by_name(cn, "cpu-map");
>>>>>> +	if (!map)
>>>>>> +		return -ENODEV;
>>>>>> +
>>>>>> +	do {
>>>>>> +		snprintf(name, sizeof(name), "cluster%d", i);
>>>>>> +		struct device_node *c __free(device_node) = of_get_child_by_name(map, name);
>>>>>> +		if (!c)
>>>>>> +			break;
>>>>>> +
>>>>>> +		*(cluster_info + i) = of_get_child_count(c);
>>>>>> +		i++;
>>>>>> +	} while (1);
>>>>>
>>>>> Can you use existing API from drivers/base/arch_topology.c? If not, can
>>>>> it be extended to support your usecase?
>>>>
>>>> ack. But I'm pretty sure it's going to take a while for reaching such
>>>> an agreement so I'll drop this feature during the next re-spin.
>>>
>>> Why? What kind of API do you actually need? The arch_topology.c simply
>>> exports a table of struct cpu_topology. Is it somehow different from
>>> what you are parsing manually?
>>
>> yup, we had to figure out the physical id of the cpu
>> since cpus can be disabled by the bootloader using
>> status = "failed" property and we have to pass this
>> onto the cpucp memlat algorithm.
> 
> Isn't it equal to the index in the cpu_topology table?

from what I see cpu_topology indexes remain unpopulated
for cpus that are disabled since get_cpu_for_node
ignores those?

> 
>>
>>>
>>>>
>>>>>
>>>>>> +
>>>>>> +	return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static void populate_physical_mask(struct device_node *np, u32 *mask, u32 *cluster_info)
>>>>>> +{
>>>>>> +	struct device_node *dev_phandle __free(device_node);
>>>>>> +	int cpu, i = 0, physical_id;
>>>>>> +
>>>>>> +	do {
>>>>>> +		dev_phandle = of_parse_phandle(np, "cpus", i++);
>>>>>> +		cpu = of_cpu_node_to_id(dev_phandle);
>>>>>> +		if (cpu != -ENODEV) {
>>>>>> +			physical_id = topology_core_id(cpu);
>>>>>> +			for (int j = 0; j < topology_cluster_id(cpu); j++)
>>>>>> +				physical_id += *(cluster_info + j);
>>>>>> +			*mask |= BIT(physical_id);
>>>>>> +		}
>>>>>> +	} while (dev_phandle);
>>>>>> +}
>>>>>> +
>>>>>> +static struct cpufreq_memfreq_map *init_cpufreq_memfreq_map(struct device *dev,
>>>>>> +							    struct scmi_memory_info *memory,
>>>>>> +							    struct device_node *of_node,
>>>>>> +							    u32 *cnt)
>>>>>> +{
>>>>>> +	struct device_node *tbl_np __free(device_node), *opp_np __free(device_node);
>>>>>> +	struct cpufreq_memfreq_map *tbl;
>>>>>> +	int ret, i = 0;
>>>>>> +	u32 level, len;
>>>>>> +	u64 rate;
>>>>>> +
>>>>>> +	tbl_np = of_parse_phandle(of_node, "operating-points-v2", 0);
>>>>>
>>>>> Please use existing API to parse OPP tables or document a reason why it
>>>>> can't be used.
>>>>
>>>> Thanks, I had them documented as opens in the coverletter. Dropped them
>>>> since no one had any comments on it during V3. Will add them as comments
>>>> to this driver instead.
>>>>
>>>> https://lore.kernel.org/lkml/20240702191440.2161623-1-quic_sibis at quicinc.com/
>>>>
>>>> re-copying things again:
>>>> opp-tables are used but they don't get to be added to the scmi device
>>>> (thus we rely on a lot of manual parsing) because the memlat client driver
>>>> doesn't vote on these resources clocks/interconnects/power-domain
>>>> from the kernel and some of the resources aren't modeled in the first
>>>> place like DDR_QOS.
>>>
>>> As discussed offline, please consider extending the OPP to be able to
>>> get the struct opp_table for the particular phandle. Another option
>>> might be to change the memlat driver by having a separate device for
>>> each monitor. This way you can use existing API to parse OPP tables and
>>> to get necessary data from those tables.
>>
>> + Viresh
>>
>> Spoke with Viresh offline and he had stricter requirements
>> than what you proposed. He definitely wanted the opp-tables
>> to be assoiciated with devices at the very least and have
>> all opp parsing logic within the opp-framework. Given that
>> we have to model all these dummy devices just to add the
>> tables I'll re-check the feasibility of movign the tables
>> into the driver itself. Will move the patch series back
>> into RFC and re-post just the vendor protocol since that's
>> close to merge
> 
> I don't think it's sensible to move the tables to the driver. Instead
> adding a device per monitor sounds like a better idea.

yeah, I would like to keep this in dt as well. But in order
to be able to do that through the opp core we would need
to put in a clock and interconnect paths so that the framework
is able to add the table to the device. I should be able
to list the scmi perf domain as the clock phandle but inorder
to be able to convert the kbps values for the interconnect I
would need to store the bus width and so on which is currently
abstracted by the interconnect framework. Also in the future
we may have to model dummy devices just to get the table parsed
if the devices aren't modelled and controlled in the kernel.
All of these seems to indicate that having the tables in the
driver is a better alternative, lol.

-Sibi

> 
>>>>>> +	if (!tbl_np)
>>>>>> +		return ERR_PTR(-ENODEV);
>>>>>> +
>>>>>> +	len = min(of_get_available_child_count(tbl_np), MAX_MAP_ENTRIES);
>>>>>> +	if (len == 0)
>>>>>> +		return ERR_PTR(-ENODEV);
>>>>>> +
>>>>>> +	tbl = devm_kzalloc(dev, (len + 1) * sizeof(struct cpufreq_memfreq_map),
>>>>>> +			   GFP_KERNEL);
>>>>>> +	if (!tbl)
>>>>>> +		return ERR_PTR(-ENOMEM);
>>>>>> +
>>>>>> +	for_each_available_child_of_node(tbl_np, opp_np) {
>>>>>> +		ret = of_property_read_u64_index(opp_np, "opp-hz", 0, &rate);
>>>>>> +		if (ret < 0)
>>>>>> +			return ERR_PTR(ret);
>>>>>> +
>>>>>> +		tbl[i].cpufreq_mhz = rate / HZ_PER_MHZ;
>>>>>> +
>>>>>> +		if (memory->hw_type != QCOM_MEM_TYPE_DDR_QOS) {
>>>>>> +			ret = of_property_read_u64_index(opp_np, "opp-hz", 1, &rate);
>>>>>> +			if (ret < 0)
>>>>>> +				return ERR_PTR(ret);
>>>>>> +
>>>>>> +			tbl[i].memfreq_khz = rate / HZ_PER_KHZ;
>>>>>> +		} else {
>>>>>> +			ret = of_property_read_u32(opp_np, "opp-level", &level);
>>>>>> +			if (ret < 0)
>>>>>> +				return ERR_PTR(ret);
>>>>>> +
>>>>>> +			tbl[i].memfreq_khz = level;
>>>>>> +		}
>>>>>> +
>>>>>> +		dev_dbg(dev, "Entry%d CPU:%u, Mem:%u\n", i, tbl[i].cpufreq_mhz, tbl[i].memfreq_khz);
>>>>>> +		i++;
>>>>>> +	}
>>>>>> +	*cnt = len;
>>>>>> +
>>>>>> +	return tbl;
>>>>>> +}
>>>>>> +
>>>>>> +static int process_scmi_memlat_of_node(struct scmi_device *sdev, struct scmi_memlat_info *info)
>>>>>> +{
>>>>>> +	struct scmi_monitor_info *monitor;
>>>>>> +	struct scmi_memory_info *memory;
>>>>>> +	char name[MAX_NAME_LEN];
>>>>>> +	u64 memfreq[2];
>>>>>> +	int ret;
>>>>>> +
>>>>>> +	ret = populate_cluster_info(info->cluster_info);
>>>>>> +	if (ret < 0) {
>>>>>> +		dev_err_probe(&sdev->dev, ret, "failed to populate cluster info\n");
>>>>>> +		goto err;
>>>>>> +	}
>>>>>> +
>>>>>> +	of_node_get(sdev->dev.of_node);
>>>>>> +	do {
>>>>>> +		snprintf(name, sizeof(name), "memory-%d", info->memory_cnt);
>>>>>> +		struct device_node *memory_np __free(device_node) =
>>>>>> +			of_find_node_by_name(sdev->dev.of_node, name);
>>>>>> +
>>>>>> +		if (!memory_np)
>>>>>> +			break;
>>>>>> +
>>>>>> +		if (info->memory_cnt >= MAX_MEMORY_TYPES)
>>>>>> +			return dev_err_probe(&sdev->dev, -EINVAL,
>>>>>> +					     "failed to parse unsupported memory type\n");
>>>>>> +
>>>>>> +		memory = devm_kzalloc(&sdev->dev, sizeof(*memory), GFP_KERNEL);
>>>>>> +		if (!memory) {
>>>>>> +			ret = -ENOMEM;
>>>>>> +			goto err;
>>>>>> +		}
>>>>>> +
>>>>>> +		ret = of_property_read_u32(memory_np, "qcom,memory-type", &memory->hw_type);
>>>>>> +		if (ret) {
>>>>>> +			dev_err_probe(&sdev->dev, ret, "failed to read memory type\n");
>>>>>> +			goto err;
>>>>>> +		}
>>>>>> +
>>>>>> +		ret = of_property_read_u64_array(memory_np, "freq-table-hz", memfreq, 2);
>>>>>> +		if (ret && (ret != -EINVAL)) {
>>>>>> +			dev_err_probe(&sdev->dev, ret, "failed to read min/max freq\n");
>>>>>> +			goto err;
>>>>>> +		}
>>>>>
>>>>> Can we get this information from the OPP table instead?
>>>>
>>>> we don't list all the available ddr/llcc freqs in the opp-table
>>>> so that we can keep the table constant across platforms.
>>>
>>> NO. Use opp-supported-hw to limit data to a particular platform. There
>>> is no reason to keep min/max out of the OPP table.
>>
>> if we are movign the opp-tables into driver data for the reasons
>> described above, this can probably stay?
> 
> No. They duplicate the information that can be a part of the tables. It
> doesn't matter if the tables are in the driver or in DT.
> 
> 


From jens.wiklander at linaro.org  Thu Dec  5 02:55:14 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 5 Dec 2024 11:55:14 +0100
Subject: [PATCH v3 2/4] optee: account for direction while converting parameters
In-Reply-To: <CAFA6WYNJQEjs29AniqC7mdmo7Fe+fCmW1kFcJ1Z2HSjQQ36LBw@mail.gmail.com>
References: <20241128150927.1377981-1-jens.wiklander@linaro.org>
 <20241128150927.1377981-3-jens.wiklander@linaro.org> <CAFA6WYPEqCWyvD=pCj6DEkZWN9SCfXMnq4tKbSx1-e8UmgXb=Q@mail.gmail.com>
 <CAHUa44H0go3fSMt_jreWz4EQgYvo8GOZ5woc-x5Cyi680oWZWw@mail.gmail.com> <CAFA6WYNJQEjs29AniqC7mdmo7Fe+fCmW1kFcJ1Z2HSjQQ36LBw@mail.gmail.com>
Message-ID: <CAHUa44G2=6tCvnJN2xkkg+UHJ58-0sK+BJSJyCU27aXWqPJy9g@mail.gmail.com>

On Tue, Dec 3, 2024 at 11:35?AM Sumit Garg <sumit.garg at linaro.org> wrote:
>
> On Tue, 3 Dec 2024 at 15:58, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> >
> > Hi Sumit,
> >
> > On Tue, Dec 3, 2024 at 9:27?AM Sumit Garg <sumit.garg at linaro.org> wrote:
> > >
> > > Hi Jens,
> > >
> > > On Thu, 28 Nov 2024 at 20:39, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> > > >
> > > > The OP-TEE backend driver has two internal function pointers to convert
> > > > between the subsystem type struct tee_param and the OP-TEE type struct
> > > > optee_msg_param.
> > > >
> > > > The conversion is done from one of the types to the other, which is then
> > > > involved in some operation and finally converted back to the original
> > > > type. When converting to prepare the parameters for the operation, all
> > > > fields must be taken into account, but then converting back, it's enough
> > > > to update only out-values and out-sizes. So, an update_out parameter is
> > > > added to the conversion functions to tell if all or only some fields
> > > > must be copied.
> > >
> > > Is this patch just a refactoring of TEE params handling? Or are we
> > > fixing a real ABI issue here? Also, is this required for restricted
> > > shared memory support to work? Just asking if we want to consider it
> > > as a fix for backporting or if we can handle this refactoring patch
> > > independently of this series?
> >
> > This is needed in this series. Without this patch, it might get
> > confusing when converting back in from_msg_param() callback since an
> > allocated restricted SHM can be using the sec_world_id of the pool and
> > that doesn't translate back well. params_to_user() in
> > drivers/tee/tee_core.c already takes the direction into account so it
> > wouldn't spread to user-space.
>
> Thanks Jens for the clarification, if you can update the commit text
> accordingly will help clarify the motivation for the change.

Sure, I'll update.

Thanks,
Jens

>
> -Sumit
>
> >
> > Cheers,
> > Jens
> >
> > >
> > > -Sumit
> > >
> > > >
> > > > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > > > ---
> > > >  drivers/tee/optee/call.c          | 10 ++--
> > > >  drivers/tee/optee/ffa_abi.c       | 43 +++++++++++++----
> > > >  drivers/tee/optee/optee_private.h | 42 +++++++++++------
> > > >  drivers/tee/optee/rpc.c           | 31 +++++++++----
> > > >  drivers/tee/optee/smc_abi.c       | 76 +++++++++++++++++++++++--------
> > > >  5 files changed, 144 insertions(+), 58 deletions(-)
> > > >
> > > > diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
> > > > index 16eb953e14bb..f1533b894726 100644
> > > > --- a/drivers/tee/optee/call.c
> > > > +++ b/drivers/tee/optee/call.c
> > > > @@ -400,7 +400,8 @@ int optee_open_session(struct tee_context *ctx,
> > > >         export_uuid(msg_arg->params[1].u.octets, &client_uuid);
> > > >
> > > >         rc = optee->ops->to_msg_param(optee, msg_arg->params + 2,
> > > > -                                     arg->num_params, param);
> > > > +                                     arg->num_params, param,
> > > > +                                     false /*!update_out*/);
> > > >         if (rc)
> > > >                 goto out;
> > > >
> > > > @@ -427,7 +428,8 @@ int optee_open_session(struct tee_context *ctx,
> > > >         }
> > > >
> > > >         if (optee->ops->from_msg_param(optee, param, arg->num_params,
> > > > -                                      msg_arg->params + 2)) {
> > > > +                                      msg_arg->params + 2,
> > > > +                                      true /*update_out*/)) {
> > > >                 arg->ret = TEEC_ERROR_COMMUNICATION;
> > > >                 arg->ret_origin = TEEC_ORIGIN_COMMS;
> > > >                 /* Close session again to avoid leakage */
> > > > @@ -541,7 +543,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
> > > >         msg_arg->cancel_id = arg->cancel_id;
> > > >
> > > >         rc = optee->ops->to_msg_param(optee, msg_arg->params, arg->num_params,
> > > > -                                     param);
> > > > +                                     param, false /*!update_out*/);
> > > >         if (rc)
> > > >                 goto out;
> > > >
> > > > @@ -551,7 +553,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
> > > >         }
> > > >
> > > >         if (optee->ops->from_msg_param(optee, param, arg->num_params,
> > > > -                                      msg_arg->params)) {
> > > > +                                      msg_arg->params, true /*update_out*/)) {
> > > >                 msg_arg->ret = TEEC_ERROR_COMMUNICATION;
> > > >                 msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
> > > >         }
> > > > diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
> > > > index f3af5666bb11..02e6175ac5f0 100644
> > > > --- a/drivers/tee/optee/ffa_abi.c
> > > > +++ b/drivers/tee/optee/ffa_abi.c
> > > > @@ -122,15 +122,21 @@ static int optee_shm_rem_ffa_handle(struct optee *optee, u64 global_id)
> > > >   */
> > > >
> > > >  static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> > > > -                                  u32 attr, const struct optee_msg_param *mp)
> > > > +                                  u32 attr, const struct optee_msg_param *mp,
> > > > +                                  bool update_out)
> > > >  {
> > > >         struct tee_shm *shm = NULL;
> > > >         u64 offs_high = 0;
> > > >         u64 offs_low = 0;
> > > >
> > > > +       if (update_out) {
> > > > +               if (attr == OPTEE_MSG_ATTR_TYPE_FMEM_INPUT)
> > > > +                       return;
> > > > +               goto out;
> > > > +       }
> > > > +
> > > >         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> > > >                   attr - OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
> > > > -       p->u.memref.size = mp->u.fmem.size;
> > > >
> > > >         if (mp->u.fmem.global_id != OPTEE_MSG_FMEM_INVALID_GLOBAL_ID)
> > > >                 shm = optee_shm_from_ffa_handle(optee, mp->u.fmem.global_id);
> > > > @@ -141,6 +147,8 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> > > >                 offs_high = mp->u.fmem.offs_high;
> > > >         }
> > > >         p->u.memref.shm_offs = offs_low | offs_high << 32;
> > > > +out:
> > > > +       p->u.memref.size = mp->u.fmem.size;
> > > >  }
> > > >
> > > >  /**
> > > > @@ -150,12 +158,14 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> > > >   * @params:    subsystem internal parameter representation
> > > >   * @num_params:        number of elements in the parameter arrays
> > > >   * @msg_params:        OPTEE_MSG parameters
> > > > + * @update_out: update parameter for output only
> > > >   *
> > > >   * Returns 0 on success or <0 on failure
> > > >   */
> > > >  static int optee_ffa_from_msg_param(struct optee *optee,
> > > >                                     struct tee_param *params, size_t num_params,
> > > > -                                   const struct optee_msg_param *msg_params)
> > > > +                                   const struct optee_msg_param *msg_params,
> > > > +                                   bool update_out)
> > > >  {
> > > >         size_t n;
> > > >
> > > > @@ -166,18 +176,20 @@ static int optee_ffa_from_msg_param(struct optee *optee,
> > > >
> > > >                 switch (attr) {
> > > >                 case OPTEE_MSG_ATTR_TYPE_NONE:
> > > > +                       if (update_out)
> > > > +                               break;
> > > >                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> > > >                         memset(&p->u, 0, sizeof(p->u));
> > > >                         break;
> > > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
> > > > -                       optee_from_msg_param_value(p, attr, mp);
> > > > +                       optee_from_msg_param_value(p, attr, mp, update_out);
> > > >                         break;
> > > >                 case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
> > > > -                       from_msg_param_ffa_mem(optee, p, attr, mp);
> > > > +                       from_msg_param_ffa_mem(optee, p, attr, mp, update_out);
> > > >                         break;
> > > >                 default:
> > > >                         return -EINVAL;
> > > > @@ -188,10 +200,16 @@ static int optee_ffa_from_msg_param(struct optee *optee,
> > > >  }
> > > >
> > > >  static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> > > > -                               const struct tee_param *p)
> > > > +                               const struct tee_param *p, bool update_out)
> > > >  {
> > > >         struct tee_shm *shm = p->u.memref.shm;
> > > >
> > > > +       if (update_out) {
> > > > +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> > > > +                       return 0;
> > > > +               goto out;
> > > > +       }
> > > > +
> > > >         mp->attr = OPTEE_MSG_ATTR_TYPE_FMEM_INPUT + p->attr -
> > > >                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> > > >
> > > > @@ -211,6 +229,7 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> > > >                 memset(&mp->u, 0, sizeof(mp->u));
> > > >                 mp->u.fmem.global_id = OPTEE_MSG_FMEM_INVALID_GLOBAL_ID;
> > > >         }
> > > > +out:
> > > >         mp->u.fmem.size = p->u.memref.size;
> > > >
> > > >         return 0;
> > > > @@ -222,13 +241,15 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> > > >   * @optee:     main service struct
> > > >   * @msg_params:        OPTEE_MSG parameters
> > > >   * @num_params:        number of elements in the parameter arrays
> > > > - * @params:    subsystem itnernal parameter representation
> > > > + * @params:    subsystem internal parameter representation
> > > > + * @update_out: update parameter for output only
> > > >   * Returns 0 on success or <0 on failure
> > > >   */
> > > >  static int optee_ffa_to_msg_param(struct optee *optee,
> > > >                                   struct optee_msg_param *msg_params,
> > > >                                   size_t num_params,
> > > > -                                 const struct tee_param *params)
> > > > +                                 const struct tee_param *params,
> > > > +                                 bool update_out)
> > > >  {
> > > >         size_t n;
> > > >
> > > > @@ -238,18 +259,20 @@ static int optee_ffa_to_msg_param(struct optee *optee,
> > > >
> > > >                 switch (p->attr) {
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
> > > > +                       if (update_out)
> > > > +                               break;
> > > >                         mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> > > >                         memset(&mp->u, 0, sizeof(mp->u));
> > > >                         break;
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
> > > > -                       optee_to_msg_param_value(mp, p);
> > > > +                       optee_to_msg_param_value(mp, p, update_out);
> > > >                         break;
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
> > > > -                       if (to_msg_param_ffa_mem(mp, p))
> > > > +                       if (to_msg_param_ffa_mem(mp, p, update_out))
> > > >                                 return -EINVAL;
> > > >                         break;
> > > >                 default:
> > > > diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
> > > > index dc0f355ef72a..20eda508dbac 100644
> > > > --- a/drivers/tee/optee/optee_private.h
> > > > +++ b/drivers/tee/optee/optee_private.h
> > > > @@ -185,10 +185,12 @@ struct optee_ops {
> > > >                                 bool system_thread);
> > > >         int (*to_msg_param)(struct optee *optee,
> > > >                             struct optee_msg_param *msg_params,
> > > > -                           size_t num_params, const struct tee_param *params);
> > > > +                           size_t num_params, const struct tee_param *params,
> > > > +                           bool update_out);
> > > >         int (*from_msg_param)(struct optee *optee, struct tee_param *params,
> > > >                               size_t num_params,
> > > > -                             const struct optee_msg_param *msg_params);
> > > > +                             const struct optee_msg_param *msg_params,
> > > > +                             bool update_out);
> > > >  };
> > > >
> > > >  /**
> > > > @@ -316,23 +318,35 @@ void optee_release(struct tee_context *ctx);
> > > >  void optee_release_supp(struct tee_context *ctx);
> > > >
> > > >  static inline void optee_from_msg_param_value(struct tee_param *p, u32 attr,
> > > > -                                             const struct optee_msg_param *mp)
> > > > +                                             const struct optee_msg_param *mp,
> > > > +                                             bool update_out)
> > > >  {
> > > > -       p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
> > > > -                 attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> > > > -       p->u.value.a = mp->u.value.a;
> > > > -       p->u.value.b = mp->u.value.b;
> > > > -       p->u.value.c = mp->u.value.c;
> > > > +       if (!update_out)
> > > > +               p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
> > > > +                         attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> > > > +
> > > > +       if (attr == OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT ||
> > > > +           attr == OPTEE_MSG_ATTR_TYPE_VALUE_INOUT || !update_out) {
> > > > +               p->u.value.a = mp->u.value.a;
> > > > +               p->u.value.b = mp->u.value.b;
> > > > +               p->u.value.c = mp->u.value.c;
> > > > +       }
> > > >  }
> > > >
> > > >  static inline void optee_to_msg_param_value(struct optee_msg_param *mp,
> > > > -                                           const struct tee_param *p)
> > > > +                                           const struct tee_param *p,
> > > > +                                           bool update_out)
> > > >  {
> > > > -       mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
> > > > -                  TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> > > > -       mp->u.value.a = p->u.value.a;
> > > > -       mp->u.value.b = p->u.value.b;
> > > > -       mp->u.value.c = p->u.value.c;
> > > > +       if (!update_out)
> > > > +               mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
> > > > +                          TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
> > > > +
> > > > +       if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
> > > > +           p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT || !update_out) {
> > > > +               mp->u.value.a = p->u.value.a;
> > > > +               mp->u.value.b = p->u.value.b;
> > > > +               mp->u.value.c = p->u.value.c;
> > > > +       }
> > > >  }
> > > >
> > > >  void optee_cq_init(struct optee_call_queue *cq, int thread_count);
> > > > diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
> > > > index ebbbd42b0e3e..580e6b9b0606 100644
> > > > --- a/drivers/tee/optee/rpc.c
> > > > +++ b/drivers/tee/optee/rpc.c
> > > > @@ -63,7 +63,7 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
> > > >         }
> > > >
> > > >         if (optee->ops->from_msg_param(optee, params, arg->num_params,
> > > > -                                      arg->params))
> > > > +                                      arg->params, false /*!update_out*/))
> > > >                 goto bad;
> > > >
> > > >         for (i = 0; i < arg->num_params; i++) {
> > > > @@ -107,7 +107,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
> > > >         } else {
> > > >                 params[3].u.value.a = msg.len;
> > > >                 if (optee->ops->to_msg_param(optee, arg->params,
> > > > -                                            arg->num_params, params))
> > > > +                                            arg->num_params, params,
> > > > +                                            true /*update_out*/))
> > > >                         arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > >                 else
> > > >                         arg->ret = TEEC_SUCCESS;
> > > > @@ -188,6 +189,7 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
> > > >  static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
> > > >                                 struct optee_msg_arg *arg)
> > > >  {
> > > > +       bool update_out = false;
> > > >         struct tee_param *params;
> > > >
> > > >         arg->ret_origin = TEEC_ORIGIN_COMMS;
> > > > @@ -200,15 +202,21 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
> > > >         }
> > > >
> > > >         if (optee->ops->from_msg_param(optee, params, arg->num_params,
> > > > -                                      arg->params)) {
> > > > +                                      arg->params, update_out)) {
> > > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > >                 goto out;
> > > >         }
> > > >
> > > >         arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
> > > >
> > > > +       /*
> > > > +        * Special treatment for OPTEE_RPC_CMD_SHM_ALLOC since input is a
> > > > +        * value type, but the output is a memref type.
> > > > +        */
> > > > +       if (arg->cmd != OPTEE_RPC_CMD_SHM_ALLOC)
> > > > +               update_out = true;
> > > >         if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
> > > > -                                    params))
> > > > +                                    params, update_out))
> > > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > >  out:
> > > >         kfree(params);
> > > > @@ -270,7 +278,7 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
> > > >
> > > >         if (arg->num_params != ARRAY_SIZE(params) ||
> > > >             optee->ops->from_msg_param(optee, params, arg->num_params,
> > > > -                                      arg->params) ||
> > > > +                                      arg->params, false /*!update_out*/) ||
> > > >             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT) {
> > > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > >                 return;
> > > > @@ -280,7 +288,8 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
> > > >         params[0].u.value.b = 0;
> > > >         params[0].u.value.c = 0;
> > > >         if (optee->ops->to_msg_param(optee, arg->params,
> > > > -                                    arg->num_params, params)) {
> > > > +                                    arg->num_params, params,
> > > > +                                    true /*update_out*/)) {
> > > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > >                 return;
> > > >         }
> > > > @@ -324,7 +333,7 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
> > > >
> > > >         if (arg->num_params != ARRAY_SIZE(params) ||
> > > >             optee->ops->from_msg_param(optee, params, arg->num_params,
> > > > -                                      arg->params) ||
> > > > +                                      arg->params, false /*!update_out*/) ||
> > > >             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
> > > >             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
> > > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > > @@ -358,7 +367,8 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
> > > >         params[0].u.value.b = rdev->descr.capacity;
> > > >         params[0].u.value.c = rdev->descr.reliable_wr_count;
> > > >         if (optee->ops->to_msg_param(optee, arg->params,
> > > > -                                    arg->num_params, params)) {
> > > > +                                    arg->num_params, params,
> > > > +                                    true /*update_out*/)) {
> > > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > >                 return;
> > > >         }
> > > > @@ -384,7 +394,7 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
> > > >
> > > >         if (arg->num_params != ARRAY_SIZE(params) ||
> > > >             optee->ops->from_msg_param(optee, params, arg->num_params,
> > > > -                                      arg->params) ||
> > > > +                                      arg->params, false /*!update_out*/) ||
> > > >             params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT ||
> > > >             params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
> > > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > > @@ -401,7 +411,8 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
> > > >                 goto out;
> > > >         }
> > > >         if (optee->ops->to_msg_param(optee, arg->params,
> > > > -                                    arg->num_params, params)) {
> > > > +                                    arg->num_params, params,
> > > > +                                    true /*update_out*/)) {
> > > >                 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> > > >                 goto out;
> > > >         }
> > > > diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
> > > > index e9456e3e74cc..d1f79947f58a 100644
> > > > --- a/drivers/tee/optee/smc_abi.c
> > > > +++ b/drivers/tee/optee/smc_abi.c
> > > > @@ -81,20 +81,26 @@ static int optee_cpuhp_disable_pcpu_irq(unsigned int cpu)
> > > >   */
> > > >
> > > >  static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
> > > > -                                 const struct optee_msg_param *mp)
> > > > +                                 const struct optee_msg_param *mp,
> > > > +                                 bool update_out)
> > > >  {
> > > >         struct tee_shm *shm;
> > > >         phys_addr_t pa;
> > > >         int rc;
> > > >
> > > > +       if (update_out) {
> > > > +               if (attr == OPTEE_MSG_ATTR_TYPE_TMEM_INPUT)
> > > > +                       return 0;
> > > > +               goto out;
> > > > +       }
> > > > +
> > > >         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> > > >                   attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
> > > > -       p->u.memref.size = mp->u.tmem.size;
> > > >         shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
> > > >         if (!shm) {
> > > >                 p->u.memref.shm_offs = 0;
> > > >                 p->u.memref.shm = NULL;
> > > > -               return 0;
> > > > +               goto out;
> > > >         }
> > > >
> > > >         rc = tee_shm_get_pa(shm, 0, &pa);
> > > > @@ -103,18 +109,25 @@ static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
> > > >
> > > >         p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
> > > >         p->u.memref.shm = shm;
> > > > -
> > > > +out:
> > > > +       p->u.memref.size = mp->u.tmem.size;
> > > >         return 0;
> > > >  }
> > > >
> > > >  static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> > > > -                                  const struct optee_msg_param *mp)
> > > > +                                  const struct optee_msg_param *mp,
> > > > +                                  bool update_out)
> > > >  {
> > > >         struct tee_shm *shm;
> > > >
> > > > +       if (update_out) {
> > > > +               if (attr == OPTEE_MSG_ATTR_TYPE_RMEM_INPUT)
> > > > +                       return;
> > > > +               goto out;
> > > > +       }
> > > > +
> > > >         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> > > >                   attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
> > > > -       p->u.memref.size = mp->u.rmem.size;
> > > >         shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
> > > >
> > > >         if (shm) {
> > > > @@ -124,6 +137,8 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> > > >                 p->u.memref.shm_offs = 0;
> > > >                 p->u.memref.shm = NULL;
> > > >         }
> > > > +out:
> > > > +       p->u.memref.size = mp->u.rmem.size;
> > > >  }
> > > >
> > > >  /**
> > > > @@ -133,11 +148,13 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
> > > >   * @params:    subsystem internal parameter representation
> > > >   * @num_params:        number of elements in the parameter arrays
> > > >   * @msg_params:        OPTEE_MSG parameters
> > > > + * @update_out:        update parameter for output only
> > > >   * Returns 0 on success or <0 on failure
> > > >   */
> > > >  static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
> > > >                                 size_t num_params,
> > > > -                               const struct optee_msg_param *msg_params)
> > > > +                               const struct optee_msg_param *msg_params,
> > > > +                               bool update_out)
> > > >  {
> > > >         int rc;
> > > >         size_t n;
> > > > @@ -149,25 +166,27 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
> > > >
> > > >                 switch (attr) {
> > > >                 case OPTEE_MSG_ATTR_TYPE_NONE:
> > > > +                       if (update_out)
> > > > +                               break;
> > > >                         p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> > > >                         memset(&p->u, 0, sizeof(p->u));
> > > >                         break;
> > > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
> > > > -                       optee_from_msg_param_value(p, attr, mp);
> > > > +                       optee_from_msg_param_value(p, attr, mp, update_out);
> > > >                         break;
> > > >                 case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
> > > > -                       rc = from_msg_param_tmp_mem(p, attr, mp);
> > > > +                       rc = from_msg_param_tmp_mem(p, attr, mp, update_out);
> > > >                         if (rc)
> > > >                                 return rc;
> > > >                         break;
> > > >                 case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
> > > >                 case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
> > > > -                       from_msg_param_reg_mem(p, attr, mp);
> > > > +                       from_msg_param_reg_mem(p, attr, mp, update_out);
> > > >                         break;
> > > >
> > > >                 default:
> > > > @@ -178,20 +197,25 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
> > > >  }
> > > >
> > > >  static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
> > > > -                               const struct tee_param *p)
> > > > +                               const struct tee_param *p, bool update_out)
> > > >  {
> > > >         int rc;
> > > >         phys_addr_t pa;
> > > >
> > > > +       if (update_out) {
> > > > +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> > > > +                       return 0;
> > > > +               goto out;
> > > > +       }
> > > > +
> > > >         mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
> > > >                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> > > >
> > > >         mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
> > > > -       mp->u.tmem.size = p->u.memref.size;
> > > >
> > > >         if (!p->u.memref.shm) {
> > > >                 mp->u.tmem.buf_ptr = 0;
> > > > -               return 0;
> > > > +               goto out;
> > > >         }
> > > >
> > > >         rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa);
> > > > @@ -201,19 +225,27 @@ static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
> > > >         mp->u.tmem.buf_ptr = pa;
> > > >         mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
> > > >                     OPTEE_MSG_ATTR_CACHE_SHIFT;
> > > > -
> > > > +out:
> > > > +       mp->u.tmem.size = p->u.memref.size;
> > > >         return 0;
> > > >  }
> > > >
> > > >  static int to_msg_param_reg_mem(struct optee_msg_param *mp,
> > > > -                               const struct tee_param *p)
> > > > +                               const struct tee_param *p, bool update_out)
> > > >  {
> > > > +       if (update_out) {
> > > > +               if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
> > > > +                       return 0;
> > > > +               goto out;
> > > > +       }
> > > > +
> > > >         mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
> > > >                    TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> > > >
> > > >         mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm;
> > > > -       mp->u.rmem.size = p->u.memref.size;
> > > >         mp->u.rmem.offs = p->u.memref.shm_offs;
> > > > +out:
> > > > +       mp->u.rmem.size = p->u.memref.size;
> > > >         return 0;
> > > >  }
> > > >
> > > > @@ -223,11 +255,13 @@ static int to_msg_param_reg_mem(struct optee_msg_param *mp,
> > > >   * @msg_params:        OPTEE_MSG parameters
> > > >   * @num_params:        number of elements in the parameter arrays
> > > >   * @params:    subsystem itnernal parameter representation
> > > > + * @update_out:        update parameter for output only
> > > >   * Returns 0 on success or <0 on failure
> > > >   */
> > > >  static int optee_to_msg_param(struct optee *optee,
> > > >                               struct optee_msg_param *msg_params,
> > > > -                             size_t num_params, const struct tee_param *params)
> > > > +                             size_t num_params, const struct tee_param *params,
> > > > +                             bool update_out)
> > > >  {
> > > >         int rc;
> > > >         size_t n;
> > > > @@ -238,21 +272,23 @@ static int optee_to_msg_param(struct optee *optee,
> > > >
> > > >                 switch (p->attr) {
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
> > > > +                       if (update_out)
> > > > +                               break;
> > > >                         mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> > > >                         memset(&mp->u, 0, sizeof(mp->u));
> > > >                         break;
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
> > > > -                       optee_to_msg_param_value(mp, p);
> > > > +                       optee_to_msg_param_value(mp, p, update_out);
> > > >                         break;
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
> > > >                 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
> > > >                         if (tee_shm_is_dynamic(p->u.memref.shm))
> > > > -                               rc = to_msg_param_reg_mem(mp, p);
> > > > +                               rc = to_msg_param_reg_mem(mp, p, update_out);
> > > >                         else
> > > > -                               rc = to_msg_param_tmp_mem(mp, p);
> > > > +                               rc = to_msg_param_tmp_mem(mp, p, update_out);
> > > >                         if (rc)
> > > >                                 return rc;
> > > >                         break;
> > > > --
> > > > 2.43.0
> > > >


From jens.wiklander at linaro.org  Thu Dec  5 02:57:33 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 5 Dec 2024 11:57:33 +0100
Subject: [PATCH v3 4/4] optee: support restricted memory allocation
In-Reply-To: <CAFA6WYMi6X37=nKx4v52xYWU2wkW1dmcPMeXn6=6k4nv2igpPA@mail.gmail.com>
References: <20241128150927.1377981-1-jens.wiklander@linaro.org>
 <20241128150927.1377981-5-jens.wiklander@linaro.org> <CAFA6WYMi6X37=nKx4v52xYWU2wkW1dmcPMeXn6=6k4nv2igpPA@mail.gmail.com>
Message-ID: <CAHUa44E=LvL305qWUAUKmGkJreEYepnSQjBkY7u7_priXTDeEg@mail.gmail.com>

Hi Sumit,

On Tue, Dec 3, 2024 at 9:19?AM Sumit Garg <sumit.garg at linaro.org> wrote:
>
> Hi Jens,
>
> On Thu, 28 Nov 2024 at 20:39, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> >
> > Add support in the OP-TEE backend driver for restricted memory
> > allocation.
> >
> > The restricted memory can be allocated from a static carveout, but also
> > be dynamically allocated from CMA and turned into restricted memory by
> > OP-TEE, inaccessible by the kernel. The restricted memory configuration
> > is depends on the platform and is probed by driver.
> >
> > A restricted memory pool is allocated during probe if a static carveout
> > is available. The restricted memory pools for dynamically allocated
> > restrict memory are instantiated when requested by user-space. This
> > instantiation can fail if OP-TEE doesn't support the requested use-case
> > of restricted memory.
>
> Can we split this patch into smaller reviewable pieces as follows?
>
> - Patch 1: Adds support for static carveout using SMC ABI
> - Patch 2: Adds support for dynamic CMA pool using SMC ABI
> - Patch 3: Adds support for both using FF-A ABI

OK, I'll split it.

Thanks,
Jens

>
> -Sumit
>
> >
> > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > ---
> >  drivers/tee/optee/Makefile        |   1 +
> >  drivers/tee/optee/core.c          |   1 +
> >  drivers/tee/optee/ffa_abi.c       | 135 ++++++++++-
> >  drivers/tee/optee/optee_private.h |  33 ++-
> >  drivers/tee/optee/rstmem.c        | 380 ++++++++++++++++++++++++++++++
> >  drivers/tee/optee/smc_abi.c       | 138 ++++++++++-
> >  6 files changed, 683 insertions(+), 5 deletions(-)
> >  create mode 100644 drivers/tee/optee/rstmem.c
> >
> > diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
> > index a6eff388d300..498969fb8e40 100644
> > --- a/drivers/tee/optee/Makefile
> > +++ b/drivers/tee/optee/Makefile
> > @@ -4,6 +4,7 @@ optee-objs += core.o
> >  optee-objs += call.o
> >  optee-objs += notif.o
> >  optee-objs += rpc.o
> > +optee-objs += rstmem.o
> >  optee-objs += supp.o
> >  optee-objs += device.o
> >  optee-objs += smc_abi.o
> > diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
> > index c75fddc83576..f4fa494789a4 100644
> > --- a/drivers/tee/optee/core.c
> > +++ b/drivers/tee/optee/core.c
> > @@ -182,6 +182,7 @@ void optee_remove_common(struct optee *optee)
> >         tee_device_unregister(optee->teedev);
> >
> >         tee_shm_pool_free(optee->pool);
> > +       optee_rstmem_pools_uninit(optee);
> >         optee_supp_uninit(&optee->supp);
> >         mutex_destroy(&optee->call_queue.mutex);
> >         rpmb_dev_put(optee->rpmb_dev);
> > diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
> > index 02e6175ac5f0..f500cf101c8d 100644
> > --- a/drivers/tee/optee/ffa_abi.c
> > +++ b/drivers/tee/optee/ffa_abi.c
> > @@ -672,6 +672,122 @@ static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
> >         return optee_ffa_yielding_call(ctx, &data, rpc_arg, system_thread);
> >  }
> >
> > +static int do_call_lend_rstmem(struct optee *optee, u64 cookie, u32 use_case)
> > +{
> > +       struct optee_shm_arg_entry *entry;
> > +       struct optee_msg_arg *msg_arg;
> > +       struct tee_shm *shm;
> > +       u_int offs;
> > +       int rc;
> > +
> > +       msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs);
> > +       if (IS_ERR(msg_arg))
> > +               return PTR_ERR(msg_arg);
> > +
> > +       msg_arg->cmd = OPTEE_MSG_CMD_ASSIGN_RSTMEM;
> > +       msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> > +       msg_arg->params[0].u.value.a = cookie;
> > +       msg_arg->params[0].u.value.b = use_case;
> > +
> > +       rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
> > +       if (rc)
> > +               goto out;
> > +       if (msg_arg->ret != TEEC_SUCCESS) {
> > +               rc = -EINVAL;
> > +               goto out;
> > +       }
> > +
> > +out:
> > +       optee_free_msg_arg(optee->ctx, entry, offs);
> > +       return rc;
> > +}
> > +
> > +static int optee_ffa_lend_rstmem(struct optee *optee, struct tee_shm *rstmem,
> > +                                u16 *end_points, unsigned int ep_count)
> > +{
> > +       struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
> > +       const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops;
> > +       const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops;
> > +       struct ffa_send_direct_data data;
> > +       struct ffa_mem_region_attributes *mem_attr;
> > +       struct ffa_mem_ops_args args = {
> > +               .use_txbuf = true,
> > +               .tag = rstmem->use_case,
> > +       };
> > +       struct page *page;
> > +       struct scatterlist sgl;
> > +       unsigned int n;
> > +       int rc;
> > +
> > +       mem_attr = kcalloc(ep_count, sizeof(*mem_attr), GFP_KERNEL);
> > +       for (n = 0; n < ep_count; n++) {
> > +               mem_attr[n].receiver = end_points[n];
> > +               mem_attr[n].attrs = FFA_MEM_RW;
> > +       }
> > +       args.attrs = mem_attr;
> > +       args.nattrs = ep_count;
> > +
> > +       page = phys_to_page(rstmem->paddr);
> > +       sg_init_table(&sgl, 1);
> > +       sg_set_page(&sgl, page, rstmem->size, 0);
> > +
> > +       args.sg = &sgl;
> > +       rc = mem_ops->memory_lend(&args);
> > +       kfree(mem_attr);
> > +       if (rc)
> > +               return rc;
> > +
> > +       rc = do_call_lend_rstmem(optee, args.g_handle, rstmem->use_case);
> > +       if (rc)
> > +               goto err_reclaim;
> > +
> > +       rc = optee_shm_add_ffa_handle(optee, rstmem, args.g_handle);
> > +       if (rc)
> > +               goto err_unreg;
> > +
> > +       rstmem->sec_world_id = args.g_handle;
> > +
> > +       return 0;
> > +
> > +err_unreg:
> > +       data = (struct ffa_send_direct_data){
> > +               .data0 = OPTEE_FFA_RELEASE_RSTMEM,
> > +               .data1 = (u32)args.g_handle,
> > +               .data2 = (u32)(args.g_handle >> 32),
> > +       };
> > +       msg_ops->sync_send_receive(ffa_dev, &data);
> > +err_reclaim:
> > +       mem_ops->memory_reclaim(args.g_handle, 0);
> > +       return rc;
> > +}
> > +
> > +static int optee_ffa_reclaim_rstmem(struct optee *optee, struct tee_shm *rstmem)
> > +{
> > +       struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
> > +       const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops;
> > +       const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops;
> > +       u64 global_handle = rstmem->sec_world_id;
> > +       struct ffa_send_direct_data data = {
> > +               .data0 = OPTEE_FFA_RELEASE_RSTMEM,
> > +               .data1 = (u32)global_handle,
> > +               .data2 = (u32)(global_handle >> 32)
> > +       };
> > +       int rc;
> > +
> > +       optee_shm_rem_ffa_handle(optee, global_handle);
> > +       rstmem->sec_world_id = 0;
> > +
> > +       rc = msg_ops->sync_send_receive(ffa_dev, &data);
> > +       if (rc)
> > +               pr_err("Release SHM id 0x%llx rc %d\n", global_handle, rc);
> > +
> > +       rc = mem_ops->memory_reclaim(global_handle, 0);
> > +       if (rc)
> > +               pr_err("mem_reclaim: 0x%llx %d", global_handle, rc);
> > +
> > +       return rc;
> > +}
> > +
> >  /*
> >   * 6. Driver initialization
> >   *
> > @@ -785,7 +901,10 @@ static void optee_ffa_get_version(struct tee_device *teedev,
> >                 .gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM |
> >                             TEE_GEN_CAP_MEMREF_NULL,
> >         };
> > +       struct optee *optee = tee_get_drvdata(teedev);
> >
> > +       if (optee->rstmem_pools)
> > +               v.gen_caps |= TEE_GEN_CAP_RSTMEM;
> >         *vers = v;
> >  }
> >
> > @@ -804,6 +923,8 @@ static const struct tee_driver_ops optee_ffa_clnt_ops = {
> >         .cancel_req = optee_cancel_req,
> >         .shm_register = optee_ffa_shm_register,
> >         .shm_unregister = optee_ffa_shm_unregister,
> > +       .rstmem_alloc = optee_rstmem_alloc,
> > +       .rstmem_free = optee_rstmem_free,
> >  };
> >
> >  static const struct tee_desc optee_ffa_clnt_desc = {
> > @@ -820,6 +941,8 @@ static const struct tee_driver_ops optee_ffa_supp_ops = {
> >         .supp_send = optee_supp_send,
> >         .shm_register = optee_ffa_shm_register, /* same as for clnt ops */
> >         .shm_unregister = optee_ffa_shm_unregister_supp,
> > +       .rstmem_alloc = optee_rstmem_alloc,
> > +       .rstmem_free = optee_rstmem_free,
> >  };
> >
> >  static const struct tee_desc optee_ffa_supp_desc = {
> > @@ -833,6 +956,8 @@ static const struct optee_ops optee_ffa_ops = {
> >         .do_call_with_arg = optee_ffa_do_call_with_arg,
> >         .to_msg_param = optee_ffa_to_msg_param,
> >         .from_msg_param = optee_ffa_from_msg_param,
> > +       .lend_rstmem = optee_ffa_lend_rstmem,
> > +       .reclaim_rstmem = optee_ffa_reclaim_rstmem,
> >  };
> >
> >  static void optee_ffa_remove(struct ffa_device *ffa_dev)
> > @@ -937,11 +1062,17 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
> >             (sec_caps & OPTEE_FFA_SEC_CAP_RPMB_PROBE))
> >                 optee->in_kernel_rpmb_routing = true;
> >
> > +       if (sec_caps & OPTEE_FFA_SEC_CAP_RSTMEM) {
> > +               rc = optee_rstmem_pools_init(optee);
> > +               if (rc)
> > +                       goto err_free_pool;
> > +       }
> > +
> >         teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool,
> >                                   optee);
> >         if (IS_ERR(teedev)) {
> >                 rc = PTR_ERR(teedev);
> > -               goto err_free_pool;
> > +               goto err_free_rstmem_pools;
> >         }
> >         optee->teedev = teedev;
> >
> > @@ -1020,6 +1151,8 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
> >         tee_device_unregister(optee->teedev);
> >  err_free_pool:
> >         tee_shm_pool_free(pool);
> > +err_free_rstmem_pools:
> > +       optee_rstmem_pools_uninit(optee);
> >  err_free_optee:
> >         kfree(optee);
> >         return rc;
> > diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
> > index 20eda508dbac..dd2a3a2224bc 100644
> > --- a/drivers/tee/optee/optee_private.h
> > +++ b/drivers/tee/optee/optee_private.h
> > @@ -174,9 +174,14 @@ struct optee;
> >   * @do_call_with_arg:  enters OP-TEE in secure world
> >   * @to_msg_param:      converts from struct tee_param to OPTEE_MSG parameters
> >   * @from_msg_param:    converts from OPTEE_MSG parameters to struct tee_param
> > + * @lend_rstmem:       lends physically contiguous memory as restricted
> > + *                     memory, inaccessible by the kernel
> > + * @reclaim_rstmem:    reclaims restricted memory previously lent with
> > + *                     @lend_rstmem() and makes it accessible by the
> > + *                     kernel again
> >   *
> >   * These OPs are only supposed to be used internally in the OP-TEE driver
> > - * as a way of abstracting the different methogs of entering OP-TEE in
> > + * as a way of abstracting the different methods of entering OP-TEE in
> >   * secure world.
> >   */
> >  struct optee_ops {
> > @@ -191,6 +196,23 @@ struct optee_ops {
> >                               size_t num_params,
> >                               const struct optee_msg_param *msg_params,
> >                               bool update_out);
> > +       int (*lend_rstmem)(struct optee *optee, struct tee_shm *rstmem,
> > +                          u16 *end_points, unsigned int ep_count);
> > +       int (*reclaim_rstmem)(struct optee *optee, struct tee_shm *rstmem);
> > +};
> > +
> > +/**
> > + * struct optee_rstmem_pools - restricted memory pools
> > + * @mutex:     serializes write access to @xa when adding a new pool.
> > + * @xa:                XArray of struct tee_shm_pool where the index is the
> > + *             use case ID TEE_IOC_UC_* supplied for TEE_IOC_RSTMEM_ALLOC.
> > + */
> > +struct optee_rstmem_pools {
> > +       /*
> > +        * Serializes write access to @xa when adding a new pool.
> > +        */
> > +       struct mutex mutex;
> > +       struct xarray xa;
> >  };
> >
> >  /**
> > @@ -206,6 +228,7 @@ struct optee_ops {
> >   * @notif:             notification synchronization struct
> >   * @supp:              supplicant synchronization struct for RPC to supplicant
> >   * @pool:              shared memory pool
> > + * @rstmem_pool:       restricted memory pool for secure data path
> >   * @mutex:             mutex protecting @rpmb_dev
> >   * @rpmb_dev:          current RPMB device or NULL
> >   * @rpmb_scan_bus_done flag if device registation of RPMB dependent devices
> > @@ -230,6 +253,7 @@ struct optee {
> >         struct optee_notif notif;
> >         struct optee_supp supp;
> >         struct tee_shm_pool *pool;
> > +       struct optee_rstmem_pools *rstmem_pools;
> >         /* Protects rpmb_dev pointer */
> >         struct mutex rpmb_dev_mutex;
> >         struct rpmb_dev *rpmb_dev;
> > @@ -286,6 +310,9 @@ void optee_supp_init(struct optee_supp *supp);
> >  void optee_supp_uninit(struct optee_supp *supp);
> >  void optee_supp_release(struct optee_supp *supp);
> >
> > +int optee_rstmem_pools_init(struct optee *optee);
> > +void optee_rstmem_pools_uninit(struct optee *optee);
> > +
> >  int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
> >                     struct tee_param *param);
> >  int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
> > @@ -378,6 +405,10 @@ void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
> >  int optee_do_bottom_half(struct tee_context *ctx);
> >  int optee_stop_async_notif(struct tee_context *ctx);
> >
> > +int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
> > +                      u32 flags, u32 use_case, size_t size);
> > +void optee_rstmem_free(struct tee_context *ctx, struct tee_shm *shm);
> > +
> >  /*
> >   * Small helpers
> >   */
> > diff --git a/drivers/tee/optee/rstmem.c b/drivers/tee/optee/rstmem.c
> > new file mode 100644
> > index 000000000000..cf300929171f
> > --- /dev/null
> > +++ b/drivers/tee/optee/rstmem.c
> > @@ -0,0 +1,380 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (c) 2024, Linaro Limited
> > + */
> > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > +
> > +#include <linux/cma.h>
> > +#include <linux/dma-map-ops.h>
> > +#include <linux/errno.h>
> > +#include <linux/genalloc.h>
> > +#include <linux/slab.h>
> > +#include <linux/string.h>
> > +#include <linux/tee_core.h>
> > +#include <linux/types.h>
> > +#include "optee_private.h"
> > +
> > +struct optee_rstmem_cma_pool {
> > +       struct tee_shm_pool pool;
> > +       struct page *page;
> > +       struct optee *optee;
> > +       size_t page_count;
> > +       u16 *end_points;
> > +       u_int end_point_count;
> > +       u_int align;
> > +       refcount_t refcount;
> > +       struct tee_shm rstmem;
> > +       /* Protects when initializing and tearing down this struct */
> > +       struct mutex mutex;
> > +};
> > +
> > +static struct optee_rstmem_cma_pool *
> > +to_rstmem_cma_pool(struct tee_shm_pool *pool)
> > +{
> > +       return container_of(pool, struct optee_rstmem_cma_pool, pool);
> > +}
> > +
> > +static int init_cma_rstmem(struct optee_rstmem_cma_pool *rp)
> > +{
> > +       struct cma *cma = dev_get_cma_area(&rp->optee->teedev->dev);
> > +       int rc;
> > +
> > +       rp->page = cma_alloc(cma, rp->page_count, rp->align, true/*no_warn*/);
> > +       if (!rp->page)
> > +               return -ENOMEM;
> > +
> > +       /*
> > +        * TODO unmap the memory range since the physical memory will
> > +        * become inaccesible after the lend_rstmem() call.
> > +        */
> > +
> > +       rp->rstmem.paddr = page_to_phys(rp->page);
> > +       rp->rstmem.size = rp->page_count * PAGE_SIZE;
> > +       rc = rp->optee->ops->lend_rstmem(rp->optee, &rp->rstmem,
> > +                                        rp->end_points, rp->end_point_count);
> > +       if (rc)
> > +               goto err_release;
> > +
> > +       rp->pool.private_data = gen_pool_create(PAGE_SHIFT, -1);
> > +       if (!rp->pool.private_data) {
> > +               rc = -ENOMEM;
> > +               goto err_reclaim;
> > +       }
> > +
> > +       rc = gen_pool_add(rp->pool.private_data, rp->rstmem.paddr,
> > +                         rp->rstmem.size, -1);
> > +       if (rc)
> > +               goto err_free_pool;
> > +
> > +       refcount_set(&rp->refcount, 1);
> > +       return 0;
> > +
> > +err_free_pool:
> > +       gen_pool_destroy(rp->pool.private_data);
> > +err_reclaim:
> > +       rp->optee->ops->reclaim_rstmem(rp->optee, &rp->rstmem);
> > +err_release:
> > +       cma_release(cma, rp->page, rp->page_count);
> > +       rp->rstmem.paddr = 0;
> > +       rp->rstmem.size = 0;
> > +       rp->rstmem.sec_world_id = 0;
> > +       return rc;
> > +}
> > +
> > +static int get_cma_rstmem(struct optee_rstmem_cma_pool *rp)
> > +{
> > +       int rc = 0;
> > +
> > +       if (!refcount_inc_not_zero(&rp->refcount)) {
> > +               mutex_lock(&rp->mutex);
> > +               if (rp->pool.private_data) {
> > +                       /*
> > +                        * Another thread has already initialized the pool
> > +                        * before us, or the pool was just about to be torn
> > +                        * down. Either way we only need to increase the
> > +                        * refcount and we're done.
> > +                        */
> > +                       refcount_inc(&rp->refcount);
> > +               } else {
> > +                       rc = init_cma_rstmem(rp);
> > +               }
> > +               mutex_unlock(&rp->mutex);
> > +       }
> > +
> > +       return rc;
> > +}
> > +
> > +static void release_cma_rstmem(struct optee_rstmem_cma_pool *rp)
> > +{
> > +       gen_pool_destroy(rp->pool.private_data);
> > +       rp->optee->ops->reclaim_rstmem(rp->optee, &rp->rstmem);
> > +       cma_release(dev_get_cma_area(&rp->optee->teedev->dev), rp->page,
> > +                   rp->page_count);
> > +
> > +       rp->pool.private_data = NULL;
> > +       rp->page = NULL;
> > +       rp->rstmem.paddr = 0;
> > +       rp->rstmem.size = 0;
> > +       rp->rstmem.sec_world_id = 0;
> > +}
> > +
> > +static void put_cma_rstmem(struct optee_rstmem_cma_pool *rp)
> > +{
> > +       if (refcount_dec_and_test(&rp->refcount)) {
> > +               mutex_lock(&rp->mutex);
> > +               if (rp->pool.private_data)
> > +                       release_cma_rstmem(rp);
> > +               mutex_unlock(&rp->mutex);
> > +       }
> > +}
> > +
> > +static int rstmem_pool_op_cma_alloc(struct tee_shm_pool *pool,
> > +                                   struct tee_shm *shm, size_t size,
> > +                                   size_t align)
> > +{
> > +       struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool);
> > +       size_t sz = ALIGN(size, PAGE_SIZE);
> > +       phys_addr_t pa;
> > +       int rc;
> > +
> > +       rc = get_cma_rstmem(rp);
> > +       if (rc)
> > +               return rc;
> > +
> > +       pa = gen_pool_alloc(rp->pool.private_data, sz);
> > +       if (!pa) {
> > +               put_cma_rstmem(rp);
> > +               return -ENOMEM;
> > +       }
> > +
> > +       shm->size = sz;
> > +       shm->paddr = pa;
> > +       shm->offset = pa - page_to_phys(rp->page);
> > +       shm->sec_world_id = rp->rstmem.sec_world_id;
> > +
> > +       return 0;
> > +}
> > +
> > +static void rstmem_pool_op_cma_free(struct tee_shm_pool *pool,
> > +                                   struct tee_shm *shm)
> > +{
> > +       struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool);
> > +
> > +       gen_pool_free(rp->pool.private_data, shm->paddr, shm->size);
> > +       shm->size = 0;
> > +       shm->paddr = 0;
> > +       shm->offset = 0;
> > +       shm->sec_world_id = 0;
> > +       put_cma_rstmem(rp);
> > +}
> > +
> > +static void pool_op_cma_destroy_pool(struct tee_shm_pool *pool)
> > +{
> > +       struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool);
> > +
> > +       mutex_destroy(&rp->mutex);
> > +       kfree(rp);
> > +}
> > +
> > +static struct tee_shm_pool_ops rstmem_pool_ops_cma = {
> > +       .alloc = rstmem_pool_op_cma_alloc,
> > +       .free = rstmem_pool_op_cma_free,
> > +       .destroy_pool = pool_op_cma_destroy_pool,
> > +};
> > +
> > +static int get_rstmem_config(struct optee *optee, u32 use_case,
> > +                            size_t *min_size, u_int *min_align,
> > +                            u16 *end_points, u_int *ep_count)
> > +{
> > +       struct tee_param params[2] = {
> > +               [0] = {
> > +                       .attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT,
> > +                       .u.value.a = use_case,
> > +               },
> > +               [1] = {
> > +                       .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT,
> > +               },
> > +       };
> > +       struct optee_shm_arg_entry *entry;
> > +       struct tee_shm *shm_param = NULL;
> > +       struct optee_msg_arg *msg_arg;
> > +       struct tee_shm *shm;
> > +       u_int offs;
> > +       int rc;
> > +
> > +       if (end_points && *ep_count) {
> > +               params[1].u.memref.size = *ep_count * sizeof(*end_points);
> > +               shm_param = tee_shm_alloc_priv_buf(optee->ctx,
> > +                                                  params[1].u.memref.size);
> > +               if (IS_ERR(shm_param))
> > +                       return PTR_ERR(shm_param);
> > +               params[1].u.memref.shm = shm_param;
> > +       }
> > +
> > +       msg_arg = optee_get_msg_arg(optee->ctx, ARRAY_SIZE(params), &entry,
> > +                                   &shm, &offs);
> > +       if (IS_ERR(msg_arg)) {
> > +               rc = PTR_ERR(msg_arg);
> > +               goto out_free_shm;
> > +       }
> > +       msg_arg->cmd = OPTEE_MSG_CMD_GET_RSTMEM_CONFIG;
> > +
> > +       rc = optee->ops->to_msg_param(optee, msg_arg->params,
> > +                                     ARRAY_SIZE(params), params,
> > +                                     false /*!update_out*/);
> > +       if (rc)
> > +               goto out_free_msg;
> > +
> > +       rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
> > +       if (rc)
> > +               goto out_free_msg;
> > +       if (msg_arg->ret && msg_arg->ret != TEEC_ERROR_SHORT_BUFFER) {
> > +               rc = -EINVAL;
> > +               goto out_free_msg;
> > +       }
> > +
> > +       rc = optee->ops->from_msg_param(optee, params, ARRAY_SIZE(params),
> > +                                       msg_arg->params, true /*update_out*/);
> > +       if (rc)
> > +               goto out_free_msg;
> > +
> > +       if (!msg_arg->ret && end_points &&
> > +           *ep_count < params[1].u.memref.size / sizeof(u16)) {
> > +               rc = -EINVAL;
> > +               goto out_free_msg;
> > +       }
> > +
> > +       *min_size = params[0].u.value.a;
> > +       *min_align = params[0].u.value.b;
> > +       *ep_count = params[1].u.memref.size / sizeof(u16);
> > +
> > +       if (msg_arg->ret == TEEC_ERROR_SHORT_BUFFER) {
> > +               rc = -ENOSPC;
> > +               goto out_free_msg;
> > +       }
> > +
> > +       if (end_points)
> > +               memcpy(end_points, tee_shm_get_va(shm_param, 0),
> > +                      params[1].u.memref.size);
> > +
> > +out_free_msg:
> > +       optee_free_msg_arg(optee->ctx, entry, offs);
> > +out_free_shm:
> > +       if (shm_param)
> > +               tee_shm_free(shm_param);
> > +       return rc;
> > +}
> > +
> > +static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee, u32 use_case)
> > +{
> > +       struct optee_rstmem_cma_pool *rp;
> > +       size_t min_size;
> > +       int rc;
> > +
> > +       rp = kzalloc(sizeof(*rp), GFP_KERNEL);
> > +       if (!rp)
> > +               return ERR_PTR(-ENOMEM);
> > +       rp->rstmem.use_case = use_case;
> > +
> > +       rc = get_rstmem_config(optee, use_case, &min_size, &rp->align, NULL,
> > +                              &rp->end_point_count);
> > +       if (rc) {
> > +               if (rc != -ENOSPC)
> > +                       goto err;
> > +               rp->end_points = kcalloc(rp->end_point_count,
> > +                                        sizeof(*rp->end_points), GFP_KERNEL);
> > +               if (!rp->end_points) {
> > +                       rc = -ENOMEM;
> > +                       goto err;
> > +               }
> > +               rc = get_rstmem_config(optee, use_case, &min_size, &rp->align,
> > +                                      rp->end_points, &rp->end_point_count);
> > +               if (rc)
> > +                       goto err_kfree_eps;
> > +       }
> > +
> > +       rp->pool.ops = &rstmem_pool_ops_cma;
> > +       rp->optee = optee;
> > +       rp->page_count = min_size / PAGE_SIZE;
> > +       mutex_init(&rp->mutex);
> > +
> > +       return &rp->pool;
> > +
> > +err_kfree_eps:
> > +       kfree(rp->end_points);
> > +err:
> > +       kfree(rp);
> > +       return ERR_PTR(rc);
> > +}
> > +
> > +int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
> > +                      u32 flags, u32 use_case, size_t size)
> > +{
> > +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> > +       struct tee_shm_pool *pool;
> > +       int rc;
> > +
> > +       if (!optee->rstmem_pools)
> > +               return -EINVAL;
> > +       if (flags)
> > +               return -EINVAL;
> > +
> > +       pool = xa_load(&optee->rstmem_pools->xa, use_case);
> > +       if (!pool) {
> > +               pool = alloc_rstmem_pool(optee, use_case);
> > +               if (IS_ERR(pool))
> > +                       return PTR_ERR(pool);
> > +               rc = xa_insert(&optee->rstmem_pools->xa, use_case, pool,
> > +                              GFP_KERNEL);
> > +               if (rc) {
> > +                       pool->ops->destroy_pool(pool);
> > +                       return rc;
> > +               }
> > +       }
> > +
> > +       return pool->ops->alloc(pool, shm, size, 0);
> > +}
> > +
> > +void optee_rstmem_free(struct tee_context *ctx, struct tee_shm *shm)
> > +{
> > +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> > +       struct tee_shm_pool *pool;
> > +
> > +       pool = xa_load(&optee->rstmem_pools->xa, shm->use_case);
> > +       if (pool)
> > +               pool->ops->free(pool, shm);
> > +       else
> > +               pr_err("Can't find pool for use_case %u\n", shm->use_case);
> > +}
> > +
> > +int optee_rstmem_pools_init(struct optee *optee)
> > +{
> > +       struct optee_rstmem_pools *pools;
> > +
> > +       pools = kmalloc(sizeof(*pools), GFP_KERNEL);
> > +       if (!pools)
> > +               return -ENOMEM;
> > +
> > +       mutex_init(&pools->mutex);
> > +       xa_init(&pools->xa);
> > +       optee->rstmem_pools = pools;
> > +       return 0;
> > +}
> > +
> > +void optee_rstmem_pools_uninit(struct optee *optee)
> > +{
> > +       if (optee->rstmem_pools) {
> > +               struct tee_shm_pool *pool;
> > +               u_long idx;
> > +
> > +               xa_for_each(&optee->rstmem_pools->xa, idx, pool) {
> > +                       xa_erase(&optee->rstmem_pools->xa, idx);
> > +                       pool->ops->destroy_pool(pool);
> > +               }
> > +
> > +               xa_destroy(&optee->rstmem_pools->xa);
> > +               mutex_destroy(&optee->rstmem_pools->mutex);
> > +               kfree(optee->rstmem_pools);
> > +               optee->rstmem_pools = NULL;
> > +       }
> > +}
> > diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
> > index d1f79947f58a..7fa7d9d14c94 100644
> > --- a/drivers/tee/optee/smc_abi.c
> > +++ b/drivers/tee/optee/smc_abi.c
> > @@ -1001,6 +1001,67 @@ static int optee_smc_do_call_with_arg(struct tee_context *ctx,
> >         return rc;
> >  }
> >
> > +static int optee_smc_lend_rstmem(struct optee *optee, struct tee_shm *rstmem,
> > +                                u16 *end_points, unsigned int ep_count)
> > +{
> > +       struct optee_shm_arg_entry *entry;
> > +       struct optee_msg_arg *msg_arg;
> > +       struct tee_shm *shm;
> > +       u_int offs;
> > +       int rc;
> > +
> > +       msg_arg = optee_get_msg_arg(optee->ctx, 2, &entry, &shm, &offs);
> > +       if (IS_ERR(msg_arg))
> > +               return PTR_ERR(msg_arg);
> > +
> > +       msg_arg->cmd = OPTEE_MSG_CMD_LEND_RSTMEM;
> > +       msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
> > +       msg_arg->params[0].u.value.a = OPTEE_MSG_RSTMEM_SECURE_VIDEO_PLAY;
> > +       msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
> > +       msg_arg->params[1].u.tmem.buf_ptr = rstmem->paddr;
> > +       msg_arg->params[1].u.tmem.size = rstmem->size;
> > +       msg_arg->params[1].u.tmem.shm_ref = (u_long)rstmem;
> > +
> > +       rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
> > +       if (rc)
> > +               goto out;
> > +       if (msg_arg->ret != TEEC_SUCCESS) {
> > +               rc = -EINVAL;
> > +               goto out;
> > +       }
> > +
> > +out:
> > +       optee_free_msg_arg(optee->ctx, entry, offs);
> > +       return rc;
> > +}
> > +
> > +static int optee_smc_reclaim_rstmem(struct optee *optee, struct tee_shm *rstmem)
> > +{
> > +       struct optee_shm_arg_entry *entry;
> > +       struct optee_msg_arg *msg_arg;
> > +       struct tee_shm *shm;
> > +       u_int offs;
> > +       int rc;
> > +
> > +       msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs);
> > +       if (IS_ERR(msg_arg))
> > +               return PTR_ERR(msg_arg);
> > +
> > +       msg_arg->cmd = OPTEE_MSG_CMD_RECLAIM_RSTMEM;
> > +       msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
> > +       msg_arg->params[0].u.rmem.shm_ref = (u_long)rstmem;
> > +
> > +       rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
> > +       if (rc)
> > +               goto out;
> > +       if (msg_arg->ret != TEEC_SUCCESS)
> > +               rc = -EINVAL;
> > +
> > +out:
> > +       optee_free_msg_arg(optee->ctx, entry, offs);
> > +       return rc;
> > +}
> > +
> >  /*
> >   * 5. Asynchronous notification
> >   */
> > @@ -1201,6 +1262,8 @@ static void optee_get_version(struct tee_device *teedev,
> >                 v.gen_caps |= TEE_GEN_CAP_REG_MEM;
> >         if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
> >                 v.gen_caps |= TEE_GEN_CAP_MEMREF_NULL;
> > +       if (optee->rstmem_pools)
> > +               v.gen_caps |= TEE_GEN_CAP_RSTMEM;
> >         *vers = v;
> >  }
> >
> > @@ -1223,6 +1286,8 @@ static const struct tee_driver_ops optee_clnt_ops = {
> >         .cancel_req = optee_cancel_req,
> >         .shm_register = optee_shm_register,
> >         .shm_unregister = optee_shm_unregister,
> > +       .rstmem_alloc = optee_rstmem_alloc,
> > +       .rstmem_free = optee_rstmem_free,
> >  };
> >
> >  static const struct tee_desc optee_clnt_desc = {
> > @@ -1239,6 +1304,8 @@ static const struct tee_driver_ops optee_supp_ops = {
> >         .supp_send = optee_supp_send,
> >         .shm_register = optee_shm_register_supp,
> >         .shm_unregister = optee_shm_unregister_supp,
> > +       .rstmem_alloc = optee_rstmem_alloc,
> > +       .rstmem_free = optee_rstmem_free,
> >  };
> >
> >  static const struct tee_desc optee_supp_desc = {
> > @@ -1252,6 +1319,9 @@ static const struct optee_ops optee_ops = {
> >         .do_call_with_arg = optee_smc_do_call_with_arg,
> >         .to_msg_param = optee_to_msg_param,
> >         .from_msg_param = optee_from_msg_param,
> > +       .lend_rstmem = optee_smc_lend_rstmem,
> > +       .reclaim_rstmem = optee_smc_reclaim_rstmem,
> > +       //.alloc_rstmem_pool = optee_smc_alloc_rstmem_pool,
> >  };
> >
> >  static int enable_async_notif(optee_invoke_fn *invoke_fn)
> > @@ -1619,6 +1689,62 @@ static inline int optee_load_fw(struct platform_device *pdev,
> >  }
> >  #endif
> >
> > +static int optee_sdp_pool_init(struct optee *optee)
> > +{
> > +       bool dyn_sdp = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_RSTMEM;
> > +       bool sdp = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP;
> > +       struct tee_shm_pool *pool;
> > +       int rc;
> > +
> > +       /*
> > +        * optee_sdp_pools_init() must be called if secure world has any
> > +        * SDP capability. If the static carvout is available initialize
> > +        * and add a pool for that. If there's an error from secure world
> > +        * we complain but don't call optee_sdp_pools_uninit() unless we
> > +        * know that there is no SDP capability left.
> > +        */
> > +       if (!dyn_sdp && !sdp)
> > +               return 0;
> > +
> > +       rc = optee_rstmem_pools_init(optee);
> > +       if (rc)
> > +               return rc;
> > +
> > +       if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP) {
> > +               union {
> > +                       struct arm_smccc_res smccc;
> > +                       struct optee_smc_get_sdp_config_result result;
> > +               } res;
> > +
> > +               optee->smc.invoke_fn(OPTEE_SMC_GET_SDP_CONFIG, 0, 0, 0, 0, 0, 0,
> > +                                    0, &res.smccc);
> > +               if (res.result.status != OPTEE_SMC_RETURN_OK) {
> > +                       pr_err("Secure Data Path service not available\n");
> > +                       if (!dyn_sdp)
> > +                               goto err;
> > +                       return 0;
> > +               }
> > +
> > +               pool = tee_rstmem_gen_pool_alloc(res.result.start,
> > +                                                res.result.size);
> > +               if (IS_ERR(pool)) {
> > +                       rc = PTR_ERR(pool);
> > +                       goto err;
> > +               }
> > +               rc = xa_insert(&optee->rstmem_pools->xa,
> > +                              TEE_IOC_UC_SECURE_VIDEO_PLAY, pool, GFP_KERNEL);
> > +               if (rc) {
> > +                       pool->ops->destroy_pool(pool);
> > +                       goto err;
> > +               }
> > +       }
> > +
> > +       return 0;
> > +err:
> > +       optee_rstmem_pools_uninit(optee);
> > +       return rc;
> > +}
> > +
> >  static int optee_probe(struct platform_device *pdev)
> >  {
> >         optee_invoke_fn *invoke_fn;
> > @@ -1714,7 +1840,7 @@ static int optee_probe(struct platform_device *pdev)
> >         optee = kzalloc(sizeof(*optee), GFP_KERNEL);
> >         if (!optee) {
> >                 rc = -ENOMEM;
> > -               goto err_free_pool;
> > +               goto err_free_shm_pool;
> >         }
> >
> >         optee->ops = &optee_ops;
> > @@ -1726,10 +1852,14 @@ static int optee_probe(struct platform_device *pdev)
> >             (sec_caps & OPTEE_SMC_SEC_CAP_RPMB_PROBE))
> >                 optee->in_kernel_rpmb_routing = true;
> >
> > +       rc = optee_sdp_pool_init(optee);
> > +       if (rc)
> > +               goto err_free_optee;
> > +
> >         teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
> >         if (IS_ERR(teedev)) {
> >                 rc = PTR_ERR(teedev);
> > -               goto err_free_optee;
> > +               goto err_rstmem_pools_uninit;
> >         }
> >         optee->teedev = teedev;
> >
> > @@ -1836,9 +1966,11 @@ static int optee_probe(struct platform_device *pdev)
> >         tee_device_unregister(optee->supp_teedev);
> >  err_unreg_teedev:
> >         tee_device_unregister(optee->teedev);
> > +err_rstmem_pools_uninit:
> > +       optee_rstmem_pools_uninit(optee);
> >  err_free_optee:
> >         kfree(optee);
> > -err_free_pool:
> > +err_free_shm_pool:
> >         tee_shm_pool_free(pool);
> >         if (memremaped_shm)
> >                 memunmap(memremaped_shm);
> > --
> > 2.43.0
> >


From jonathanh at nvidia.com  Thu Dec  5 02:57:59 2024
From: jonathanh at nvidia.com (Jon Hunter)
Date: Thu, 5 Dec 2024 10:57:59 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap for
 non-paged SKB data
In-Reply-To: <pckuhqpx33woc7tgcv4mluhwg2clriokzb7r4vkzmr6jz3gy3p@hykwm4qtgv6f>
References: <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com> <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
 <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
 <df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>
 <2g2lp3bkadc4wpeslmdoexpidoiqzt7vejar5xhjx5ayt3uox3@dqdyfzn6khn6>
 <Z1CFz7GpeIzkDro1@shell.armlinux.org.uk>
 <9719982a-d40c-4110-9233-def2e6cb4d74@nvidia.com>
 <Z1CVRzWcSDuPyQZe@shell.armlinux.org.uk>
 <pckuhqpx33woc7tgcv4mluhwg2clriokzb7r4vkzmr6jz3gy3p@hykwm4qtgv6f>
Message-ID: <0ac66b26-9a1b-4bff-94b9-86f5597a106d@nvidia.com>


On 04/12/2024 18:18, Thierry Reding wrote:
> On Wed, Dec 04, 2024 at 05:45:43PM +0000, Russell King (Oracle) wrote:
>> On Wed, Dec 04, 2024 at 05:02:19PM +0000, Jon Hunter wrote:
>>> Hi Russell,
>>>
>>> On 04/12/2024 16:39, Russell King (Oracle) wrote:
>>>> On Wed, Dec 04, 2024 at 04:58:34PM +0100, Thierry Reding wrote:
>>>>> This doesn't match the location from earlier, but at least there's
>>>>> something afoot here that needs fixing. I suppose this could simply be
>>>>> hiding any subsequent errors, so once this is fixed we might see other
>>>>> similar issues.
>>>>
>>>> Well, having a quick look at this, the first thing which stands out is:
>>>>
>>>> In stmmac_tx_clean(), we have:
>>>>
>>>>                   if (likely(tx_q->tx_skbuff_dma[entry].buf &&
>>>>                              tx_q->tx_skbuff_dma[entry].buf_type != STMMAC_TXBUF_T
>>>> _XDP_TX)) {
>>>>                           if (tx_q->tx_skbuff_dma[entry].map_as_page)
>>>>                                   dma_unmap_page(priv->device,
>>>>                                                  tx_q->tx_skbuff_dma[entry].buf,
>>>>                                                  tx_q->tx_skbuff_dma[entry].len,
>>>>                                                  DMA_TO_DEVICE);
>>>>                           else
>>>>                                   dma_unmap_single(priv->device,
>>>>                                                    tx_q->tx_skbuff_dma[entry].buf,
>>>>                                                    tx_q->tx_skbuff_dma[entry].len,
>>>>                                                    DMA_TO_DEVICE);
>>>>                           tx_q->tx_skbuff_dma[entry].buf = 0;
>>>>                           tx_q->tx_skbuff_dma[entry].len = 0;
>>>>                           tx_q->tx_skbuff_dma[entry].map_as_page = false;
>>>>                   }
>>>>
>>>> So, tx_skbuff_dma[entry].buf is expected to point appropriately to the
>>>> DMA region.
>>>>
>>>> Now if we look at stmmac_tso_xmit():
>>>>
>>>>           des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
>>>>                                DMA_TO_DEVICE);
>>>>           if (dma_mapping_error(priv->device, des))
>>>>                   goto dma_map_err;
>>>>
>>>>           if (priv->dma_cap.addr64 <= 32) {
>>>> ...
>>>>           } else {
>>>> ...
>>>>                   des += proto_hdr_len;
>>>> ...
>>>> 	}
>>>>
>>>>           tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
>>>>           tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
>>>>           tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
>>>>           tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
>>>>
>>>> This will result in stmmac_tx_clean() calling dma_unmap_single() using
>>>> "des" and "skb_headlen(skb)" as the buffer start and length.
>>>>
>>>> One of the requirements of the DMA mapping API is that the DMA handle
>>>> returned by the map operation will be passed into the unmap function.
>>>> Not something that was offset. The length will also be the same.
>>>>
>>>> We can clearly see above that there is a case where the DMA handle has
>>>> been offset by proto_hdr_len, and when this is so, the value that is
>>>> passed into the unmap operation no longer matches this requirement.
>>>>
>>>> So, a question to the reporter - what is the value of
>>>> priv->dma_cap.addr64 in your failing case? You should see the value
>>>> in the "Using %d/%d bits DMA host/device width" kernel message.
>>>
>>> It is ...
>>>
>>>   dwc-eth-dwmac 2490000.ethernet: Using 40/40 bits DMA host/device width
>>
>> So yes, "des" is being offset, which will upset the unmap operation.
>> Please try the following patch, thanks:
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> index 9b262cdad60b..c81ea8cdfe6e 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -4192,8 +4192,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>>   	struct stmmac_txq_stats *txq_stats;
>>   	struct stmmac_tx_queue *tx_q;
>>   	u32 pay_len, mss, queue;
>> +	dma_addr_t tso_des, des;
>>   	u8 proto_hdr_len, hdr;
>> -	dma_addr_t des;
>>   	bool set_ic;
>>   	int i;
>>   
>> @@ -4289,14 +4289,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>>   
>>   		/* If needed take extra descriptors to fill the remaining payload */
>>   		tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
>> +		tso_des = des;
>>   	} else {
>>   		stmmac_set_desc_addr(priv, first, des);
>>   		tmp_pay_len = pay_len;
>> -		des += proto_hdr_len;
>> +		tso_des = des + proto_hdr_len;
>>   		pay_len = 0;
>>   	}
>>   
>> -	stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
>> +	stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
>>   
>>   	/* In case two or more DMA transmit descriptors are allocated for this
>>   	 * non-paged SKB data, the DMA buffer address should be saved to
> 
> I see, that makes sense. Looks like this has been broken for a few years
> (since commit 34c15202896d ("net: stmmac: Fix the problem of tso_xmit"))
> and Furong's patch ended up exposing it.
> 
> Anyway, this seems to fix it for me. I can usually trigger the issue
> within one or two iperf runs, with your patch I haven't seen it break
> after a dozen or so runs.
> 
> It may be good to have Jon's test results as well, but looks good so
> far.


I have been running tests on my side and so far so good too. I have not 
seen any more mapping failure cases.

Russell, if you are planning to send a fix for this, please add my ...

Tested-by: Jon Hunter <jonathanh at nvidia.com>

Thanks!
Jon

-- 
nvpublic



From jonathanh at nvidia.com  Thu Dec  5 03:02:00 2024
From: jonathanh at nvidia.com (Jon Hunter)
Date: Thu, 5 Dec 2024 11:02:00 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unbalanced DMA map/unmap for
 non-paged SKB data
In-Reply-To: <0ac66b26-9a1b-4bff-94b9-86f5597a106d@nvidia.com>
References: <20241202163309.05603e96@kernel.org>
 <20241203100331.00007580@gmail.com> <20241202183425.4021d14c@kernel.org>
 <20241203111637.000023fe@gmail.com>
 <klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc@bwwhelz2l4dw>
 <df3a6a9d-4b53-4338-9bc5-c4eea48b8a40@arm.com>
 <2g2lp3bkadc4wpeslmdoexpidoiqzt7vejar5xhjx5ayt3uox3@dqdyfzn6khn6>
 <Z1CFz7GpeIzkDro1@shell.armlinux.org.uk>
 <9719982a-d40c-4110-9233-def2e6cb4d74@nvidia.com>
 <Z1CVRzWcSDuPyQZe@shell.armlinux.org.uk>
 <pckuhqpx33woc7tgcv4mluhwg2clriokzb7r4vkzmr6jz3gy3p@hykwm4qtgv6f>
 <0ac66b26-9a1b-4bff-94b9-86f5597a106d@nvidia.com>
Message-ID: <ddfe8dbf-a2ae-4aa0-ad09-fa5efcb62c12@nvidia.com>



On 05/12/2024 10:57, Jon Hunter wrote:
> 
> On 04/12/2024 18:18, Thierry Reding wrote:
>> On Wed, Dec 04, 2024 at 05:45:43PM +0000, Russell King (Oracle) wrote:
>>> On Wed, Dec 04, 2024 at 05:02:19PM +0000, Jon Hunter wrote:
>>>> Hi Russell,
>>>>
>>>> On 04/12/2024 16:39, Russell King (Oracle) wrote:
>>>>> On Wed, Dec 04, 2024 at 04:58:34PM +0100, Thierry Reding wrote:
>>>>>> This doesn't match the location from earlier, but at least there's
>>>>>> something afoot here that needs fixing. I suppose this could 
>>>>>> simply be
>>>>>> hiding any subsequent errors, so once this is fixed we might see 
>>>>>> other
>>>>>> similar issues.
>>>>>
>>>>> Well, having a quick look at this, the first thing which stands out 
>>>>> is:
>>>>>
>>>>> In stmmac_tx_clean(), we have:
>>>>>
>>>>> ????????????????? if (likely(tx_q->tx_skbuff_dma[entry].buf &&
>>>>> ???????????????????????????? tx_q->tx_skbuff_dma[entry].buf_type != 
>>>>> STMMAC_TXBUF_T
>>>>> _XDP_TX)) {
>>>>> ????????????????????????? if (tx_q->tx_skbuff_dma[entry].map_as_page)
>>>>> ????????????????????????????????? dma_unmap_page(priv->device,
>>>>> ???????????????????????????????????????????????? tx_q- 
>>>>> >tx_skbuff_dma[entry].buf,
>>>>> ???????????????????????????????????????????????? tx_q- 
>>>>> >tx_skbuff_dma[entry].len,
>>>>> ???????????????????????????????????????????????? DMA_TO_DEVICE);
>>>>> ????????????????????????? else
>>>>> ????????????????????????????????? dma_unmap_single(priv->device,
>>>>> ?????????????????????????????????????????????????? tx_q- 
>>>>> >tx_skbuff_dma[entry].buf,
>>>>> ?????????????????????????????????????????????????? tx_q- 
>>>>> >tx_skbuff_dma[entry].len,
>>>>> ?????????????????????????????????????????????????? DMA_TO_DEVICE);
>>>>> ????????????????????????? tx_q->tx_skbuff_dma[entry].buf = 0;
>>>>> ????????????????????????? tx_q->tx_skbuff_dma[entry].len = 0;
>>>>> ????????????????????????? tx_q->tx_skbuff_dma[entry].map_as_page = 
>>>>> false;
>>>>> ????????????????? }
>>>>>
>>>>> So, tx_skbuff_dma[entry].buf is expected to point appropriately to the
>>>>> DMA region.
>>>>>
>>>>> Now if we look at stmmac_tso_xmit():
>>>>>
>>>>> ????????? des = dma_map_single(priv->device, skb->data, 
>>>>> skb_headlen(skb),
>>>>> ?????????????????????????????? DMA_TO_DEVICE);
>>>>> ????????? if (dma_mapping_error(priv->device, des))
>>>>> ????????????????? goto dma_map_err;
>>>>>
>>>>> ????????? if (priv->dma_cap.addr64 <= 32) {
>>>>> ...
>>>>> ????????? } else {
>>>>> ...
>>>>> ????????????????? des += proto_hdr_len;
>>>>> ...
>>>>> ????}
>>>>>
>>>>> ????????? tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
>>>>> ????????? tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
>>>>> ????????? tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
>>>>> ????????? tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = 
>>>>> STMMAC_TXBUF_T_SKB;
>>>>>
>>>>> This will result in stmmac_tx_clean() calling dma_unmap_single() using
>>>>> "des" and "skb_headlen(skb)" as the buffer start and length.
>>>>>
>>>>> One of the requirements of the DMA mapping API is that the DMA handle
>>>>> returned by the map operation will be passed into the unmap function.
>>>>> Not something that was offset. The length will also be the same.
>>>>>
>>>>> We can clearly see above that there is a case where the DMA handle has
>>>>> been offset by proto_hdr_len, and when this is so, the value that is
>>>>> passed into the unmap operation no longer matches this requirement.
>>>>>
>>>>> So, a question to the reporter - what is the value of
>>>>> priv->dma_cap.addr64 in your failing case? You should see the value
>>>>> in the "Using %d/%d bits DMA host/device width" kernel message.
>>>>
>>>> It is ...
>>>>
>>>> ? dwc-eth-dwmac 2490000.ethernet: Using 40/40 bits DMA host/device 
>>>> width
>>>
>>> So yes, "des" is being offset, which will upset the unmap operation.
>>> Please try the following patch, thanks:
>>>
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/ 
>>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> index 9b262cdad60b..c81ea8cdfe6e 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> @@ -4192,8 +4192,8 @@ static netdev_tx_t stmmac_tso_xmit(struct 
>>> sk_buff *skb, struct net_device *dev)
>>> ????? struct stmmac_txq_stats *txq_stats;
>>> ????? struct stmmac_tx_queue *tx_q;
>>> ????? u32 pay_len, mss, queue;
>>> +??? dma_addr_t tso_des, des;
>>> ????? u8 proto_hdr_len, hdr;
>>> -??? dma_addr_t des;
>>> ????? bool set_ic;
>>> ????? int i;
>>> @@ -4289,14 +4289,15 @@ static netdev_tx_t stmmac_tso_xmit(struct 
>>> sk_buff *skb, struct net_device *dev)
>>> ????????? /* If needed take extra descriptors to fill the remaining 
>>> payload */
>>> ????????? tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
>>> +??????? tso_des = des;
>>> ????? } else {
>>> ????????? stmmac_set_desc_addr(priv, first, des);
>>> ????????? tmp_pay_len = pay_len;
>>> -??????? des += proto_hdr_len;
>>> +??????? tso_des = des + proto_hdr_len;
>>> ????????? pay_len = 0;
>>> ????? }
>>> -??? stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
>>> +??? stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), 
>>> queue);
>>> ????? /* In case two or more DMA transmit descriptors are allocated 
>>> for this
>>> ?????? * non-paged SKB data, the DMA buffer address should be saved to
>>
>> I see, that makes sense. Looks like this has been broken for a few years
>> (since commit 34c15202896d ("net: stmmac: Fix the problem of tso_xmit"))
>> and Furong's patch ended up exposing it.
>>
>> Anyway, this seems to fix it for me. I can usually trigger the issue
>> within one or two iperf runs, with your patch I haven't seen it break
>> after a dozen or so runs.
>>
>> It may be good to have Jon's test results as well, but looks good so
>> far.
> 
> 
> I have been running tests on my side and so far so good too. I have not 
> seen any more mapping failure cases.
> 
> Russell, if you are planning to send a fix for this, please add my ...
> 
> Tested-by: Jon Hunter <jonathanh at nvidia.com>

Nevermind I see Furong already sent a fix.

Jon

-- 
nvpublic



From quic_sibis at quicinc.com  Thu Dec  5 03:03:05 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Thu, 5 Dec 2024 16:33:05 +0530
Subject: [PATCH V4 4/5] soc: qcom: Introduce SCMI based Memlat (Memory
 Latency) governor
In-Reply-To: <2e9614de-1a93-4e17-a10c-945c50fb3f1a@quicinc.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-5-quic_sibis@quicinc.com>
 <2e9614de-1a93-4e17-a10c-945c50fb3f1a@quicinc.com>
Message-ID: <61ce8618-cb08-06bc-9159-4ca26d703b14@quicinc.com>



On 11/29/24 15:27, Shivnandan Kumar wrote:
> 
> 
> On 10/7/2024 11:40 AM, Sibi Sankar wrote:
>> Introduce a client driver that uses the memlat algorithm string
>> hosted on QCOM SCMI Generic Extension Protocol to detect memory
>> latency workloads and control frequency/level of the various
>> memory buses (DDR/LLCC/DDR_QOS).
>>
>> Co-developed-by: Shivnandan Kumar <quic_kshivnan at quicinc.com>
>> Signed-off-by: Shivnandan Kumar <quic_kshivnan at quicinc.com>
>> Co-developed-by: Ramakrishna Gottimukkula <quic_rgottimu at quicinc.com>
>> Signed-off-by: Ramakrishna Gottimukkula <quic_rgottimu at quicinc.com>
>> Co-developed-by: Amir Vajid <avajid at quicinc.com>
>> Signed-off-by: Amir Vajid <avajid at quicinc.com>
>> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
>> ---
>>
>> v3:
>> * Add missing enum in the scmi memlat driver and fix documentation 
>> [Konrad]
>> * Add checks for max memory and monitor [Shivnandan]
>> * Fix typo from START_TIMER -> STOP_TIMER [Shivnandan]
>> * Make populate_physical_mask func to void [Shivnandan]
>> * Remove unecessary zero set [Shivnandan]
>> * Use __free(device node) in init_cpufreq-memfreqmap [Christian/Konrad]
>> * Use sdev->dev.of_node directly [Christian]
>> * use return dev_err_probe in multiple places [Christian]
>>
>> ? drivers/soc/qcom/Kconfig?????????????????? |? 12 +
>> ? drivers/soc/qcom/Makefile????????????????? |?? 1 +
>> ? drivers/soc/qcom/qcom_scmi_memlat_client.c | 569 +++++++++++++++++++++
>> ? 3 files changed, 582 insertions(+)
>> ? create mode 100644 drivers/soc/qcom/qcom_scmi_memlat_client.c
>>
>> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
>> index 74b9121240f8..1b6dd40d69ea 100644
>> --- a/drivers/soc/qcom/Kconfig
>> +++ b/drivers/soc/qcom/Kconfig
>> @@ -295,4 +295,16 @@ config QCOM_PBS
>> ??????? This module provides the APIs to the client drivers that wants 
>> to send the
>> ??????? PBS trigger event to the PBS RAM.
>> +config QCOM_SCMI_MEMLAT_CLIENT
>> +??? tristate "Qualcomm Technologies Inc. SCMI client driver"
>> +??? depends on QCOM_SCMI_GENERIC_EXT || COMPILE_TEST
>> +??? help
>> +????? This driver uses the MEMLAT (memory latency) algorithm string
>> +????? hosted on QCOM SCMI Vendor Protocol to detect memory latency
>> +????? workloads and control frequency/level of the various memory
>> +????? buses (DDR/LLCC/DDR_QOS).
>> +
>> +????? This driver defines/documents the parameter IDs used while 
>> configuring
>> +????? the memory buses.
>> +
>> ? endmenu
>> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
>> index acbca2ab5cc2..28549bb141bc 100644
>> --- a/drivers/soc/qcom/Makefile
>> +++ b/drivers/soc/qcom/Makefile
>> @@ -36,6 +36,7 @@ obj-$(CONFIG_QCOM_APR) += apr.o
>> ? obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o
>> ? obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) +=??? kryo-l2-accessors.o
>> ? obj-$(CONFIG_QCOM_ICC_BWMON)??? += icc-bwmon.o
>> +obj-$(CONFIG_QCOM_SCMI_MEMLAT_CLIENT)??? += qcom_scmi_memlat_client.o
>> ? qcom_ice-objs??????????? += ice.o
>> ? obj-$(CONFIG_QCOM_INLINE_CRYPTO_ENGINE)??? += qcom_ice.o
>> ? obj-$(CONFIG_QCOM_PBS) +=??? qcom-pbs.o
>> diff --git a/drivers/soc/qcom/qcom_scmi_memlat_client.c 
>> b/drivers/soc/qcom/qcom_scmi_memlat_client.c
>> new file mode 100644
>> index 000000000000..05198bf1f7ec
>> --- /dev/null
>> +++ b/drivers/soc/qcom/qcom_scmi_memlat_client.c
>> @@ -0,0 +1,569 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights 
>> reserved.
>> + */
>> +
>> +#include <linux/cpu.h>
>> +#include <linux/err.h>
>> +#include <linux/errno.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/scmi_protocol.h>
>> +#include <linux/scmi_qcom_protocol.h>
>> +#include <linux/units.h>
>> +#include <dt-bindings/firmware/qcom,scmi-memlat.h>
>> +
>> +#define MEMLAT_ALGO_STR??????????????? 0x4D454D4C4154 /* MEMLAT */
>> +#define INVALID_IDX??????????????? 0xff
>> +#define MAX_MEMORY_TYPES??????????? 3
>> +#define MAX_MONITOR_CNT??????????????? 4
>> +#define MAX_NAME_LEN??????????????? 20
>> +#define MAX_MAP_ENTRIES??????????????? 7
>> +#define CPUCP_DEFAULT_SAMPLING_PERIOD_MS??? 4
>> +#define CPUCP_DEFAULT_FREQ_METHOD??????? 1
>> +
>> +/**
>> + * enum scmi_memlat_protocol_cmd - parameter_ids supported by the 
>> "MEMLAT" algo_str hosted
>> + *???????????????????????????????? by the Qualcomm Generic Vendor 
>> Protocol on the SCMI controller.
>> + *
>> + * MEMLAT (Memory Latency) monitors the counters to detect memory 
>> latency bound workloads
>> + * and scales the frequency/levels of the memory buses accordingly.
>> + *
>> + * @MEMLAT_SET_MEM_GROUP: initializes the frequency/level scaling 
>> functions for the memory bus.
>> + * @MEMLAT_SET_MONITOR: configures the monitor to work on a specific 
>> memory bus.
>> + * @MEMLAT_SET_COMMON_EV_MAP: set up common counters used to monitor 
>> the cpu frequency.
>> + * @MEMLAT_SET_GRP_EV_MAP: set up any specific counters used to 
>> monitor the memory bus.
>> + * @MEMLAT_IPM_CEIL: set the IPM (Instruction Per Misses) ceiling per 
>> monitor.
>> + * @MEMLAT_SAMPLE_MS: set the sampling period for all the monitors.
>> + * @MEMLAT_MON_FREQ_MAP: setup the cpufreq to memfreq map.
>> + * @MEMLAT_SET_MIN_FREQ: set the max frequency of the memory bus.
>> + * @MEMLAT_SET_MAX_FREQ: set the min frequency of the memory bus.
>> + * @MEMLAT_START_TIMER: start all the monitors with the requested 
>> sampling period.
>> + * @MEMLAT_STOP_TIMER: stop all the running monitors.
>> + * @MEMLAT_SET_EFFECTIVE_FREQ_METHOD: set the method used to 
>> determine cpu frequency.
>> + */
>> +enum scmi_memlat_protocol_cmd {
>> +??? MEMLAT_SET_MEM_GROUP = 16,
>> +??? MEMLAT_SET_MONITOR,
>> +??? MEMLAT_SET_COMMON_EV_MAP,
>> +??? MEMLAT_SET_GRP_EV_MAP,
>> +??? MEMLAT_IPM_CEIL = 23,
>> +??? MEMLAT_SAMPLE_MS = 31,
>> +??? MEMLAT_MON_FREQ_MAP,
>> +??? MEMLAT_SET_MIN_FREQ,
>> +??? MEMLAT_SET_MAX_FREQ,
>> +??? MEMLAT_START_TIMER = 36,
>> +??? MEMLAT_STOP_TIMER,
>> +??? MEMLAT_SET_EFFECTIVE_FREQ_METHOD = 39,
>> +};
>> +
>> +struct map_table {
>> +??? u16 v1;
>> +??? u16 v2;
>> +};
>> +
>> +struct map_param_msg {
>> +??? u32 hw_type;
>> +??? u32 mon_idx;
>> +??? u32 nr_rows;
>> +??? struct map_table tbl[MAX_MAP_ENTRIES];
>> +} __packed;
>> +
>> +struct node_msg {
>> +??? u32 cpumask;
>> +??? u32 hw_type;
>> +??? u32 mon_type;
>> +??? u32 mon_idx;
>> +??? char mon_name[MAX_NAME_LEN];
>> +};
>> +
>> +struct scalar_param_msg {
>> +??? u32 hw_type;
>> +??? u32 mon_idx;
>> +??? u32 val;
>> +};
>> +
>> +enum common_ev_idx {
>> +??? INST_IDX,
>> +??? CYC_IDX,
>> +??? CONST_CYC_IDX,
>> +??? FE_STALL_IDX,
>> +??? BE_STALL_IDX,
>> +??? NUM_COMMON_EVS
>> +};
>> +
>> +enum grp_ev_idx {
>> +??? MISS_IDX,
>> +??? WB_IDX,
>> +??? ACC_IDX,
>> +??? NUM_GRP_EVS
>> +};
>> +
>> +#define EV_CPU_CYCLES??????? 0
>> +#define EV_INST_RETIRED??????? 2
>> +#define EV_L2_D_RFILL??????? 5
>> +
>> +struct ev_map_msg {
>> +??? u32 num_evs;
>> +??? u32 hw_type;
>> +??? u32 cid[NUM_COMMON_EVS];
>> +};
>> +
>> +struct cpufreq_memfreq_map {
>> +??? unsigned int cpufreq_mhz;
>> +??? unsigned int memfreq_khz;
>> +};
>> +
>> +struct scmi_monitor_info {
>> +??? struct cpufreq_memfreq_map *freq_map;
>> +??? char mon_name[MAX_NAME_LEN];
>> +??? u32 mon_idx;
>> +??? u32 mon_type;
>> +??? u32 ipm_ceil;
>> +??? u32 mask;
>> +??? u32 freq_map_len;
>> +};
>> +
>> +struct scmi_memory_info {
>> +??? struct scmi_monitor_info *monitor[MAX_MONITOR_CNT];
>> +??? u32 hw_type;
>> +??? int monitor_cnt;
>> +??? u32 min_freq;
>> +??? u32 max_freq;
>> +};
>> +
>> +struct scmi_memlat_info {
>> +??? struct scmi_protocol_handle *ph;
>> +??? const struct qcom_generic_ext_ops *ops;
>> +??? struct scmi_memory_info *memory[MAX_MEMORY_TYPES];
>> +??? u32 cluster_info[NR_CPUS];
>> +??? int memory_cnt;
>> +};
>> +
>> +static int populate_cluster_info(u32 *cluster_info)
>> +{
>> +??? char name[MAX_NAME_LEN];
>> +??? int i = 0;
>> +
>> +??? struct device_node *cn __free(device_node) = 
>> of_find_node_by_path("/cpus");
>> +??? if (!cn)
>> +??????? return -ENODEV;
>> +
>> +??? struct device_node *map __free(device_node) = 
>> of_get_child_by_name(cn, "cpu-map");
>> +??? if (!map)
>> +??????? return -ENODEV;
>> +
>> +??? do {
>> +??????? snprintf(name, sizeof(name), "cluster%d", i);
>> +??????? struct device_node *c __free(device_node) = 
>> of_get_child_by_name(map, name);
>> +??????? if (!c)
>> +??????????? break;
>> +
>> +??????? *(cluster_info + i) = of_get_child_count(c);
>> +??????? i++;
>> +??? } while (1);
>> +
>> +??? return 0;
>> +}
>> +
>> +static void populate_physical_mask(struct device_node *np, u32 *mask, 
>> u32 *cluster_info)
>> +{
>> +??? struct device_node *dev_phandle __free(device_node);
>> +??? int cpu, i = 0, physical_id;
>> +
>> +??? do {
>> +??????? dev_phandle = of_parse_phandle(np, "cpus", i++);
>> +??????? cpu = of_cpu_node_to_id(dev_phandle);
>> +??????? if (cpu != -ENODEV) {
>> +??????????? physical_id = topology_core_id(cpu);
>> +??????????? for (int j = 0; j < topology_cluster_id(cpu); j++)
>> +??????????????? physical_id += *(cluster_info + j);
>> +??????????? *mask |= BIT(physical_id);
>> +??????? }
>> +??? } while (dev_phandle);
>> +}
>> +
>> +static struct cpufreq_memfreq_map *init_cpufreq_memfreq_map(struct 
>> device *dev,
>> +??????????????????????????????? struct scmi_memory_info *memory,
>> +??????????????????????????????? struct device_node *of_node,
>> +??????????????????????????????? u32 *cnt)
>> +{
>> +??? struct device_node *tbl_np __free(device_node), *opp_np 
>> __free(device_node);
>> +??? struct cpufreq_memfreq_map *tbl;
>> +??? int ret, i = 0;
>> +??? u32 level, len;
>> +??? u64 rate;
>> +
>> +??? tbl_np = of_parse_phandle(of_node, "operating-points-v2", 0);
>> +??? if (!tbl_np)
>> +??????? return ERR_PTR(-ENODEV);
>> +
>> +??? len = min(of_get_available_child_count(tbl_np), MAX_MAP_ENTRIES);
>> +??? if (len == 0)
>> +??????? return ERR_PTR(-ENODEV);
>> +
>> +??? tbl = devm_kzalloc(dev, (len + 1) * sizeof(struct 
>> cpufreq_memfreq_map),
>> +?????????????? GFP_KERNEL);
>> +??? if (!tbl)
>> +??????? return ERR_PTR(-ENOMEM);
>> +
>> +??? for_each_available_child_of_node(tbl_np, opp_np) {
>> +??????? ret = of_property_read_u64_index(opp_np, "opp-hz", 0, &rate);
>> +??????? if (ret < 0)
>> +??????????? return ERR_PTR(ret);
>> +
>> +??????? tbl[i].cpufreq_mhz = rate / HZ_PER_MHZ;
>> +
>> +??????? if (memory->hw_type != QCOM_MEM_TYPE_DDR_QOS) {
>> +??????????? ret = of_property_read_u64_index(opp_np, "opp-hz", 1, 
>> &rate);
>> +??????????? if (ret < 0)
>> +??????????????? return ERR_PTR(ret);
>> +
>> +??????????? tbl[i].memfreq_khz = rate / HZ_PER_KHZ;
>> +??????? } else {
>> +??????????? ret = of_property_read_u32(opp_np, "opp-level", &level);
>> +??????????? if (ret < 0)
>> +??????????????? return ERR_PTR(ret);
>> +
>> +??????????? tbl[i].memfreq_khz = level;
>> +??????? }
>> +
>> +??????? dev_dbg(dev, "Entry%d CPU:%u, Mem:%u\n", i, 
>> tbl[i].cpufreq_mhz, tbl[i].memfreq_khz);
>> +??????? i++;
>> +??? }
>> +??? *cnt = len;
>> +
>> +??? return tbl;
>> +}
>> +
>> +static int process_scmi_memlat_of_node(struct scmi_device *sdev, 
>> struct scmi_memlat_info *info)
>> +{
>> +??? struct scmi_monitor_info *monitor;
>> +??? struct scmi_memory_info *memory;
>> +??? char name[MAX_NAME_LEN];
>> +??? u64 memfreq[2];
>> +??? int ret;
>> +
>> +??? ret = populate_cluster_info(info->cluster_info);
>> +??? if (ret < 0) {
>> +??????? dev_err_probe(&sdev->dev, ret, "failed to populate cluster 
>> info\n");
>> +??????? goto err;
>> +??? }
>> +
>> +??? of_node_get(sdev->dev.of_node);
>> +??? do {
>> +??????? snprintf(name, sizeof(name), "memory-%d", info->memory_cnt);
>> +??????? struct device_node *memory_np __free(device_node) =
>> +??????????? of_find_node_by_name(sdev->dev.of_node, name);
>> +
>> +??????? if (!memory_np)
>> +??????????? break;
>> +
>> +??????? if (info->memory_cnt >= MAX_MEMORY_TYPES)
>> +??????????? return dev_err_probe(&sdev->dev, -EINVAL,
>> +???????????????????????? "failed to parse unsupported memory type\n");
>> +
>> +??????? memory = devm_kzalloc(&sdev->dev, sizeof(*memory), GFP_KERNEL);
>> +??????? if (!memory) {
>> +??????????? ret = -ENOMEM;
>> +??????????? goto err;
>> +??????? }
>> +
>> +??????? ret = of_property_read_u32(memory_np, "qcom,memory-type", 
>> &memory->hw_type);
>> +??????? if (ret) {
>> +??????????? dev_err_probe(&sdev->dev, ret, "failed to read memory 
>> type\n");
>> +??????????? goto err;
>> +??????? }
>> +
>> +??????? ret = of_property_read_u64_array(memory_np, "freq-table-hz", 
>> memfreq, 2);
>> +??????? if (ret && (ret != -EINVAL)) {
>> +??????????? dev_err_probe(&sdev->dev, ret, "failed to read min/max 
>> freq\n");
>> +??????????? goto err;
>> +??????? }
>> +
>> +??????? if (memory->hw_type != QCOM_MEM_TYPE_DDR_QOS) {
>> +??????????? memory->min_freq = memfreq[0] / HZ_PER_KHZ;
>> +??????????? memory->max_freq = memfreq[1] / HZ_PER_KHZ;
>> +??????? } else {
>> +??????????? memory->min_freq = memfreq[0];
>> +??????????? memory->max_freq = memfreq[1];
>> +??????? }
>> +??????? info->memory[info->memory_cnt++] = memory;
>> +
>> +??????? do {
>> +??????????? snprintf(name, sizeof(name), "monitor-%d", 
>> memory->monitor_cnt);
>> +??????????? struct device_node *monitor_np __free(device_node) =
>> +??????????????? of_get_child_by_name(memory_np, name);
>> +
>> +??????????? if (!monitor_np)
>> +??????????????? break;
>> +
>> +??????????? if (memory->monitor_cnt >= MAX_MONITOR_CNT)
>> +??????????????? return dev_err_probe(&sdev->dev, -EINVAL,
>> +???????????????????????????? "failed to parse unsupported monitor\n");
>> +
>> +??????????? monitor = devm_kzalloc(&sdev->dev, sizeof(*monitor), 
>> GFP_KERNEL);
>> +??????????? if (!monitor) {
>> +??????????????? ret = -ENOMEM;
>> +??????????????? goto err;
>> +??????????? }
>> +
>> +??????????? monitor->mon_type = of_property_read_bool(monitor_np, 
>> "qcom,compute-type");
>> +??????????? if (!monitor->mon_type) {
>> +??????????????? ret = of_property_read_u32(monitor_np, "qcom,ipm-ceil",
>> +?????????????????????????????? &monitor->ipm_ceil);
>> +??????????????? if (ret) {
>> +??????????????????? dev_err_probe(&sdev->dev, ret,
>> +????????????????????????????? "failed to read IPM ceiling\n");
>> +??????????????????? goto err;
>> +??????????????? }
>> +??????????? }
>> +
>> +??????????? /*
>> +???????????? * Variants of the SoC having reduced number of cpus operate
>> +???????????? * with the same number of logical cpus but the physical
>> +???????????? * cpu disabled will differ between parts. Calculate the
>> +???????????? * physical cpu number using cluster information instead.
>> +???????????? */
>> +??????????? populate_physical_mask(monitor_np, &monitor->mask, 
>> info->cluster_info);
>> +
>> +??????????? monitor->freq_map = init_cpufreq_memfreq_map(&sdev->dev, 
>> memory, monitor_np,
>> +???????????????????????????????????? &monitor->freq_map_len);
>> +??????????? if (IS_ERR(monitor->freq_map)) {
>> +??????????????? dev_err_probe(&sdev->dev, PTR_ERR(monitor->freq_map),
>> +????????????????????????? "failed to populate cpufreq-memfreq map\n");
>> +??????????????? goto err;
>> +??????????? }
>> +
>> +??????????? strscpy(monitor->mon_name, name, sizeof(monitor->mon_name));
>> +??????????? monitor->mon_idx = memory->monitor_cnt;
>> +
>> +??????????? memory->monitor[memory->monitor_cnt++] = monitor;
>> +??????? } while (1);
>> +
>> +??????? if (!memory->monitor_cnt) {
>> +??????????? ret = -EINVAL;
>> +??????????? dev_err_probe(&sdev->dev, ret, "failed to find monitor 
>> nodes\n");
>> +??????????? goto err;
>> +??????? }
>> +??? } while (1);
>> +
>> +??? if (!info->memory_cnt) {
>> +??????? ret = -EINVAL;
>> +??????? dev_err_probe(&sdev->dev, ret, "failed to find memory nodes\n");
>> +??? }
>> +
>> +err:
>> +??? of_node_put(sdev->dev.of_node);
>> +
>> +??? return ret;
>> +}
>> +
>> +static int configure_cpucp_common_events(struct scmi_memlat_info *info)
>> +{
>> +??? const struct qcom_generic_ext_ops *ops = info->ops;
>> +??? u8 ev_map[NUM_COMMON_EVS];
>> +??? struct ev_map_msg msg;
>> +
>> +??? memset(ev_map, 0xFF, NUM_COMMON_EVS);
>> +
>> +??? msg.num_evs = NUM_COMMON_EVS;
>> +??? msg.hw_type = INVALID_IDX;
>> +??? msg.cid[INST_IDX] = EV_INST_RETIRED;
>> +??? msg.cid[CYC_IDX] = EV_CPU_CYCLES;
>> +??? msg.cid[CONST_CYC_IDX] = INVALID_IDX;
>> +??? msg.cid[FE_STALL_IDX] = INVALID_IDX;
>> +??? msg.cid[BE_STALL_IDX] = INVALID_IDX;
>> +
>> +??? return ops->set_param(info->ph, &msg, sizeof(msg), MEMLAT_ALGO_STR,
>> +????????????????? MEMLAT_SET_COMMON_EV_MAP);
>> +}
>> +
>> +static int configure_cpucp_grp(struct device *dev, struct 
>> scmi_memlat_info *info, int memory_index)
>> +{
>> +??? const struct qcom_generic_ext_ops *ops = info->ops;
>> +??? struct scmi_memory_info *memory = info->memory[memory_index];
>> +??? struct ev_map_msg ev_msg;
>> +??? u8 ev_map[NUM_GRP_EVS];
>> +??? struct node_msg msg;
>> +??? int ret;
>> +
>> +??? msg.cpumask = 0;
>> +??? msg.hw_type = memory->hw_type;
>> +??? msg.mon_type = 0;
>> +??? msg.mon_idx = 0;
>> +??? ret = ops->set_param(info->ph, &msg, sizeof(msg), 
>> MEMLAT_ALGO_STR, MEMLAT_SET_MEM_GROUP);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(dev, ret, "failed to configure mem type 
>> %d\n",
>> +???????????????????? memory->hw_type);
>> +
>> +??? memset(ev_map, 0xFF, NUM_GRP_EVS);
>> +??? ev_msg.num_evs = NUM_GRP_EVS;
>> +??? ev_msg.hw_type = memory->hw_type;
>> +??? ev_msg.cid[MISS_IDX] = EV_L2_D_RFILL;
>> +??? ev_msg.cid[WB_IDX] = INVALID_IDX;
>> +??? ev_msg.cid[ACC_IDX] = INVALID_IDX;
>> +??? ret = ops->set_param(info->ph, &ev_msg, sizeof(ev_msg), 
>> MEMLAT_ALGO_STR,
>> +???????????????? MEMLAT_SET_GRP_EV_MAP);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(dev, ret, "failed to configure event map 
>> for mem type %d\n",
>> +???????????????????? memory->hw_type);
>> +
>> +??? return ret;
>> +}
>> +
>> +static int configure_cpucp_mon(struct device *dev, struct 
>> scmi_memlat_info *info,
>> +?????????????????? int memory_index, int monitor_index)
>> +{
>> +??? const struct qcom_generic_ext_ops *ops = info->ops;
>> +??? struct scmi_memory_info *memory = info->memory[memory_index];
>> +??? struct scmi_monitor_info *monitor = memory->monitor[monitor_index];
>> +??? struct scalar_param_msg scalar_msg;
>> +??? struct map_param_msg map_msg;
>> +??? struct node_msg msg;
>> +??? int ret;
>> +??? int i;
>> +
>> +??? msg.cpumask = monitor->mask;
>> +??? msg.hw_type = memory->hw_type;
>> +??? msg.mon_type = monitor->mon_type;
>> +??? msg.mon_idx = monitor->mon_idx;
>> +??? strscpy(msg.mon_name, monitor->mon_name, sizeof(msg.mon_name));
>> +??? ret = ops->set_param(info->ph, &msg, sizeof(msg), 
>> MEMLAT_ALGO_STR, MEMLAT_SET_MONITOR);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(dev, ret, "failed to configure monitor 
>> %s\n",
>> +???????????????????? monitor->mon_name);
>> +
>> +??? scalar_msg.hw_type = memory->hw_type;
>> +??? scalar_msg.mon_idx = monitor->mon_idx;
>> +??? scalar_msg.val = monitor->ipm_ceil;
>> +??? ret = ops->set_param(info->ph, &scalar_msg, sizeof(scalar_msg), 
>> MEMLAT_ALGO_STR,
>> +???????????????? MEMLAT_IPM_CEIL);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(dev, ret, "failed to set ipm ceil for 
>> %s\n",
>> +???????????????????? monitor->mon_name);
>> +
>> +??? map_msg.hw_type = memory->hw_type;
>> +??? map_msg.mon_idx = monitor->mon_idx;
>> +??? map_msg.nr_rows = monitor->freq_map_len;
>> +??? for (i = 0; i < monitor->freq_map_len; i++) {
>> +??????? map_msg.tbl[i].v1 = monitor->freq_map[i].cpufreq_mhz;
>> +??????? map_msg.tbl[i].v2 = monitor->freq_map[i].memfreq_khz;
>> +??? }
>> +??? ret = ops->set_param(info->ph, &map_msg, sizeof(map_msg), 
>> MEMLAT_ALGO_STR,
>> +???????????????? MEMLAT_MON_FREQ_MAP);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(dev, ret, "failed to configure freq_map 
>> for %s\n",
>> +???????????????????? monitor->mon_name);
>> +
>> +??? scalar_msg.hw_type = memory->hw_type;
>> +??? scalar_msg.mon_idx = monitor->mon_idx;
>> +??? scalar_msg.val = memory->min_freq;
>> +??? ret = ops->set_param(info->ph, &scalar_msg, sizeof(scalar_msg), 
>> MEMLAT_ALGO_STR,
>> +???????????????? MEMLAT_SET_MIN_FREQ);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(dev, ret, "failed to set min_freq for 
>> %s\n",
>> +???????????????????? monitor->mon_name);
>> +
>> +??? scalar_msg.hw_type = memory->hw_type;
>> +??? scalar_msg.mon_idx = monitor->mon_idx;
>> +??? scalar_msg.val = memory->max_freq;
>> +??? ret = ops->set_param(info->ph, &scalar_msg, sizeof(scalar_msg), 
>> MEMLAT_ALGO_STR,
>> +???????????????? MEMLAT_SET_MAX_FREQ);
>> +??? if (ret < 0)
>> +??????? dev_err_probe(dev, ret, "failed to set max_freq for %s\n", 
>> monitor->mon_name);
>> +
>> +??? return ret;
>> +}
>> +
>> +static int cpucp_memlat_init(struct scmi_device *sdev)
>> +{
>> +??? const struct scmi_handle *handle = sdev->handle;
>> +??? const struct qcom_generic_ext_ops *ops;
>> +??? struct scmi_protocol_handle *ph;
>> +??? struct scmi_memlat_info *info;
>> +??? u32 cpucp_freq_method = CPUCP_DEFAULT_FREQ_METHOD;
>> +??? u32 cpucp_sample_ms = CPUCP_DEFAULT_SAMPLING_PERIOD_MS;
>> +??? int ret, i, j;
>> +
>> +??? if (!handle)
>> +??????? return -ENODEV;
>> +
>> +??? ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_QCOM_GENERIC, 
>> &ph);
>> +??? if (IS_ERR(ops))
>> +??????? return PTR_ERR(ops);
>> +
>> +??? info = devm_kzalloc(&sdev->dev, sizeof(*info), GFP_KERNEL);
>> +??? if (!info)
>> +??????? return -ENOMEM;
>> +
>> +??? ret = process_scmi_memlat_of_node(sdev, info);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? info->ph = ph;
>> +??? info->ops = ops;
>> +
>> +??? /* Configure common events ids */
>> +??? ret = configure_cpucp_common_events(info);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(&sdev->dev, ret, "failed to configure 
>> common events\n");
>> +
>> +??? for (i = 0; i < info->memory_cnt; i++) {
>> +??????? /* Configure per group parameters */
>> +??????? ret = configure_cpucp_grp(&sdev->dev, info, i);
>> +??????? if (ret < 0)
>> +??????????? return ret;
>> +
>> +??????? for (j = 0; j < info->memory[i]->monitor_cnt; j++) {
>> +??????????? /* Configure per monitor parameters */
>> +??????????? ret = configure_cpucp_mon(&sdev->dev, info, i, j);
>> +??????????? if (ret < 0)
>> +??????????????? return ret;
>> +??????? }
>> +??? }
>> +
>> +??? /* Set loop sampling time */
>> +??? ret = ops->set_param(ph, &cpucp_sample_ms, 
>> sizeof(cpucp_sample_ms), MEMLAT_ALGO_STR,
>> +???????????????? MEMLAT_SAMPLE_MS);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(&sdev->dev, ret, "failed to set 
>> sample_ms\n");
>> +
>> +??? /* Set the effective cpu frequency calculation method */
>> +??? ret = ops->set_param(ph, &cpucp_freq_method, 
>> sizeof(cpucp_freq_method), MEMLAT_ALGO_STR,
>> +???????????????? MEMLAT_SET_EFFECTIVE_FREQ_METHOD);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(&sdev->dev, ret,
>> +???????????????????? "failed to set effective frequency calc method\n");
>> +
> 
> Hi Sibi,

Hey Shiv,

Thanks for taking time to review the series!

> Since the MEMLAT_SET_EFFECTIVE_FREQ_METHOD command is not supported in 
> the legacy CPUCP firmware, it should be kept optional. This way, if the 
> legacy firmware is used, the driver will not return an error when the 
> CPUCP firmware returns -EOPNOTSUPP.

The vendor protocol with the current major/minor version is
expected to work as is on x1e platforms. What legacy firmware
are you referring to? All future SoCs that plan to adhere to
it are expected to maintain this abi and can decide to make
use of alternate mechanisms to calculating frequency based
on additional dt properties set.

-Sibi

> 
> Thanks,
> Shivnandan
> 
>> +??? /* Start sampling and voting timer */
>> +??? ret = ops->start_activity(ph, NULL, 0, MEMLAT_ALGO_STR, 
>> MEMLAT_START_TIMER);
>> +??? if (ret < 0)
>> +??????? dev_err_probe(&sdev->dev, ret, "failed to start memory group 
>> timer\n");
>> +
>> +??? return ret;
>> +}
>> +
>> +static int scmi_client_probe(struct scmi_device *sdev)
>> +{
>> +??? return cpucp_memlat_init(sdev);
>> +}
>> +
>> +static const struct scmi_device_id scmi_id_table[] = {
>> +??? { SCMI_PROTOCOL_QCOM_GENERIC, "qcom-generic-ext" },
>> +??? { },
>> +};
>> +MODULE_DEVICE_TABLE(scmi, scmi_id_table);
>> +
>> +static struct scmi_driver qcom_scmi_client_drv = {
>> +??? .name??????? = "scmi-qcom-generic-ext-memlat",
>> +??? .probe??????? = scmi_client_probe,
>> +??? .id_table??? = scmi_id_table,
>> +};
>> +module_scmi_driver(qcom_scmi_client_drv);
>> +
>> +MODULE_DESCRIPTION("QTI SCMI client driver");
>> +MODULE_LICENSE("GPL");


From maz at kernel.org  Thu Dec  5 03:03:41 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 05 Dec 2024 11:03:41 +0000
Subject: [PATCH 06/11] KVM: arm64: nv: Acceletate EL0 counter accesses from hypervisor context
In-Reply-To: <Z1D1zus18KCpCqjD@linux.dev>
References: <20241202172134.384923-1-maz@kernel.org>
	<20241202172134.384923-7-maz@kernel.org>
	<Z1D1zus18KCpCqjD@linux.dev>
Message-ID: <86ikrytmr6.wl-maz@kernel.org>

On Thu, 05 Dec 2024 00:37:34 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> typo: accelerate

Huh, thanks!

> 
> On Mon, Dec 02, 2024 at 05:21:29PM +0000, Marc Zyngier wrote:

[...]

> > +	case SYS_CNTVCT_EL0:
> > +	case SYS_CNTVCTSS_EL0:
> > +		/* If !ELIsInHost(EL2), the guest's CNTVOFF_EL2 applies */
> 
> !ELIsInHost(EL0)

No, and that's the whole point. CNTVOFF_EL2 applies at all times when
HCR_EL2==0 and that we're at EL2. From the pseudocode for CNTVCT_EL0:

<quote>
[...]
elsif PSTATE.EL == EL2 then
	if !ELIsInHost(EL2) then
		X[t, 64] = PhysicalCountInt() - CNTVOFF_EL2;
	else
		X[t, 64] = PhysicalCountInt();
[...]
</quote>

Which is why we only check E2H, and not E2H+TGE.

It is CNTPOFF_EL2 that applies when !ELIsInHost(EL0), and this is why
it cannot be reliably emulated as we don't (and cannot) track changes
to HCR_EL2.TGE.  Yes, this is nonsense.

	M.

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


From quic_sibis at quicinc.com  Thu Dec  5 03:07:28 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Thu, 5 Dec 2024 16:37:28 +0530
Subject: [PATCH V5 1/2] firmware: arm_scmi: Add QCOM Generic Vendor
 Protocol documentation
In-Reply-To: <Z1BBirNWH1eaSKtr@pluto>
References: <20241115011515.1313447-1-quic_sibis@quicinc.com>
 <20241115011515.1313447-2-quic_sibis@quicinc.com> <Z1BBirNWH1eaSKtr@pluto>
Message-ID: <73a16eb4-e590-92db-ee24-cc4f42a9de01@quicinc.com>



On 12/4/24 17:18, Cristian Marussi wrote:
> On Fri, Nov 15, 2024 at 06:45:14AM +0530, Sibi Sankar wrote:
>> Add QCOM System Control Management Interface (SCMI) Generic Vendor
>> Extensions Protocol documentation.
>>
>> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
>> ---
>>
>> v4:
>> * Update the protol attributes doc with more information. [Cristian]
>>
>>   .../arm_scmi/vendors/qcom/qcom_generic.rst    | 211 ++++++++++++++++++
>>   1 file changed, 211 insertions(+)
>>   create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
>>
>> diff --git a/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
>> new file mode 100644
>> index 000000000000..141bc932e30f
>> --- /dev/null
>> +++ b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
>> @@ -0,0 +1,211 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +.. include:: <isonum.txt>
>> +
>> +===============================================================================
>> +QCOM System Control and Management Interface(SCMI) Vendor Protocols Extension
>> +===============================================================================
>> +
>> +:Copyright: |copy| 2024, Qualcomm Innovation Center, Inc. All rights reserved.
>> +
>> +:Author: Sibi Sankar <quic_sibis at quicinc.com>
>> +
>> +SCMI_GENERIC: System Control and Management Interface QCOM Generic Vendor Protocol
>> +==================================================================================
>> +
>> +This protocol is intended as a generic way of exposing a number of Qualcomm
>> +SoC specific features through a mixture of pre-determined algorithm string and
>> +param_id pairs hosted on the SCMI controller. It implements an interface compliant
>> +with the Arm SCMI Specification with additional vendor specific commands as
>> +detailed below.
>> +
>> +Commands:
>> +_________
>> +
>> +PROTOCOL_VERSION
>> +~~~~~~~~~~~~~~~~
>> +
>> +message_id: 0x0
>> +protocol_id: 0x80
>> +
>> ++---------------+--------------------------------------------------------------+
>> +|Return values                                                                 |
>> ++---------------+--------------------------------------------------------------+
>> +|Name           |Description                                                   |
>> ++---------------+--------------------------------------------------------------+
>> +|int32 status   |See ARM SCMI Specification for status code definitions.       |
>> ++---------------+--------------------------------------------------------------+
>> +|uint32 version |For this revision of the specification, this value must be    |
>> +|               |0x10000.                                                      |
>> ++---------------+--------------------------------------------------------------+
>> +
>> +PROTOCOL_ATTRIBUTES
>> +~~~~~~~~~~~~~~~~~~~
>> +
>> +message_id: 0x1
>> +protocol_id: 0x80
>> +
>> ++---------------+--------------------------------------------------------------+
>> +|Return values                                                                 |
>> ++------------------+-----------------------------------------------------------+
>> +|Name              |Description                                                |
>> ++------------------+-----------------------------------------------------------+
>> +|int32 status      |See ARM SCMI Specification for status code definitions.    |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 attributes |Bits[31:16] Reserved, must be to 0.                        |
>> +|                  |Bits[15:8] Number of agents in the system                  |
>> +|                  |Bits[7:0] Number of vendor protocols in the system         |
>> ++------------------+-----------------------------------------------------------+
> 
> Thanks of clarifing this....may I ask why number of agents is reported
> here too given that it is already exposed by Base protocol ?
> 
> Not really arguing about this so much, but you will end up having to maintain this
> on 2 different protocols fw side...or are they not 'agents' in the SCMI meaning ?
> 
> Anyway, I'm fine with it, even though you dont seem to use this
> anywhere.

We don't use it anywhere and it looks like it was just put together
so that this protocol is compliant to the spec :|

> 
>> +
>> +PROTOCOL_MESSAGE_ATTRIBUTES
>> +~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> +
>> +message_id: 0x2
>> +protocol_id: 0x80
>> +
>> ++---------------+--------------------------------------------------------------+
>> +|Return values                                                                 |
>> ++------------------+-----------------------------------------------------------+
>> +|Name              |Description                                                |
>> ++------------------+-----------------------------------------------------------+
>> +|int32 status      |See ARM SCMI Specification for status code definitions.    |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 attributes |For all message id's the parameter has a value of 0.       |
>> ++------------------+-----------------------------------------------------------+
>> +
>> +QCOM_SCMI_SET_PARAM
>> +~~~~~~~~~~~~~~~~~~~
>> +
>> +message_id: 0x10
>> +protocol_id: 0x80
>> +
>> ++------------------+-----------------------------------------------------------+
>> +|Parameters                                                                    |
>> ++------------------+-----------------------------------------------------------+
>> +|Name              |Description                                                |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 ext_id     |Reserved, must be zero.                                    |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 algo_low   |Lower 32-bit value of the algorithm string.                |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 algo_high  |Upper 32-bit value of the algorithm string.                |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 param_id   |Serves as the token message id for the algorithm string    |
>> +|                  |and is used to set various parameters supported by it.     |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 buf[]      |Serves as the payload for the specified param_id and       |
>> +|                  |algorithm string pair.                                     |
>> ++------------------+-----------------------------------------------------------+
>> +|Return values                                                                 |
>> ++------------------+-----------------------------------------------------------+
>> +|Name              |Description                                                |
>> ++------------------+-----------------------------------------------------------+
>> +|int32 status      |SUCCESS: if the param_id and buf[] is parsed successfully  |
>> +|                  |by the chosen algorithm string.                            |
>> +|                  |NOT_SUPPORTED: if the algorithm string does not have any   |
>> +|                  |matches.                                                   |
>> +|                  |INVALID_PARAMETERS: if the param_id and the buf[] passed   |
>> +|                  |is rejected by the algorithm string.                       |
>> ++------------------+-----------------------------------------------------------+
>> +
>> +QCOM_SCMI_GET_PARAM
>> +~~~~~~~~~~~~~~~~~~~
>> +
>> +message_id: 0x11
>> +protocol_id: 0x80
>> +
>> ++------------------+-----------------------------------------------------------+
>> +|Parameters                                                                    |
>> ++------------------+-----------------------------------------------------------+
>> +|Name              |Description                                                |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 ext_id     |Reserved, must be zero.                                    |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 algo_low   |Lower 32-bit value of the algorithm string.                |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 algo_high  |Upper 32-bit value of the algorithm string.                |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 param_id   |Serves as the token message id for the algorithm string.   |
>> ++------------------+-----------------------------------------------------------+
>> +|uint32 buf[]      |Serves as the payload and store of value for the specified |
>> +|                  |param_id and algorithm string pair.                        |
>> ++------------------+-----------------------------------------------------------+
>> +|Return values                                                                 |
>> ++------------------+-----------------------------------------------------------+
>> +|Name              |Description                                                |
>> ++------------------+-----------------------------------------------------------+
>> +|int32 status      |SUCCESS: if the param_id and buf[] is parsed successfully  |
>> +|                  |by the chosen algorithm string and the result is copied    |
>> +|                  |into buf[].                                                |
>> +|                  |NOT_SUPPORTED: if the algorithm string does not have any   |
>> +|                  |matches.                                                   |
>> +|                  |INVALID_PARAMETERS: if the param_id and the buf[] passed   |
>> +|                  |is rejected by the algorithm string.                       |
>> ++------------------+-----------------------------------------------------------+
> 
> ..missed this last time...so you should add here also a field describing
> the reply buf right ? (as it happenns really in your code) something
> like:
> 
>   ++------------------+-----------------------------------------------------------+
>   +|uint32 buf[]      |Holds the payload of the result of the query.	 	 |
>   +|                  |					                         |
>   ++------------------+-----------------------------------------------------------+

Thanks will get this added in the next re-spin.

-Sibi

> 
> Thanks,
> Cristian


From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:11 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:11 +0100
Subject: [PATCH v2 09/15] drm/mediatek: mtk_hdmi_ddc: Switch to register as module_platform_driver
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-10-angelogioacchino.delregno@collabora.com>

In preparation for splitting out the common bits from the HDMI
driver, change the mtk_cec driver from being registered from the
HDMI driver itself to be a module_platform_driver of its own.

With this change, there are no more users of the mtk_hdmi.h header
so, while at it, also remove it.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c     |  2 --
 drivers/gpu/drm/mediatek/mtk_hdmi.h     | 13 -------------
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c |  4 ++--
 3 files changed, 2 insertions(+), 17 deletions(-)
 delete mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi.h

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 73ab88015d7f..bacb1a5289cb 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -31,7 +31,6 @@
 #include <drm/drm_probe_helper.h>
 
 #include "mtk_cec.h"
-#include "mtk_hdmi.h"
 #include "mtk_hdmi_regs.h"
 
 #define NCTS_BYTES	7
@@ -1804,7 +1803,6 @@ static struct platform_driver mtk_hdmi_driver = {
 };
 
 static struct platform_driver * const mtk_hdmi_drivers[] = {
-	&mtk_hdmi_ddc_driver,
 	&mtk_hdmi_driver,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.h b/drivers/gpu/drm/mediatek/mtk_hdmi.h
deleted file mode 100644
index e40bc4651995..000000000000
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2014 MediaTek Inc.
- * Author: Jie Qiu <jie.qiu at mediatek.com>
- */
-#ifndef _MTK_HDMI_CTRL_H
-#define _MTK_HDMI_CTRL_H
-
-struct platform_driver;
-
-extern struct platform_driver mtk_hdmi_ddc_driver;
-
-#endif /* _MTK_HDMI_CTRL_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c
index 8e60631d4cd2..6358e1af69b4 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c
@@ -20,7 +20,6 @@
 #include <linux/of_platform.h>
 
 #include "mtk_drm_drv.h"
-#include "mtk_hdmi.h"
 
 #define SIF1_CLOK		(288)
 #define DDC_DDCMCTL0		(0x0)
@@ -331,12 +330,13 @@ MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_match);
 
 struct platform_driver mtk_hdmi_ddc_driver = {
 	.probe = mtk_hdmi_ddc_probe,
-	.remove_new = mtk_hdmi_ddc_remove,
+	.remove = mtk_hdmi_ddc_remove,
 	.driver = {
 		.name = "mediatek-hdmi-ddc",
 		.of_match_table = mtk_hdmi_ddc_match,
 	},
 };
+module_platform_driver(mtk_hdmi_ddc_driver);
 
 MODULE_AUTHOR("Jie Qiu <jie.qiu at mediatek.com>");
 MODULE_DESCRIPTION("MediaTek HDMI DDC Driver");
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:12 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:12 +0100
Subject: [PATCH v2 10/15] drm/mediatek: hdmi: Use regmap instead of iomem for main registers
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-11-angelogioacchino.delregno@collabora.com>

From: Guillaume Ranquet <granquet at baylibre.com>

In preparation for the addition of a new version of the HDMI IP
which will need to share its iospace between multiple subdrivers,
and in preparation for moving out the common bits between the two,
migrate this driver to fully use regmap.

Signed-off-by: Guillaume Ranquet <granquet at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 173 +++++++++++-----------------
 1 file changed, 65 insertions(+), 108 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index bacb1a5289cb..9e8d9144cf86 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -170,7 +170,7 @@ struct mtk_hdmi {
 	u32 ibias_up;
 	struct regmap *sys_regmap;
 	unsigned int sys_offset;
-	void __iomem *regs;
+	struct regmap *regs;
 	enum hdmi_colorspace csp;
 	struct hdmi_audio_param aud_param;
 	bool audio_enable;
@@ -186,50 +186,10 @@ static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
 	return container_of(b, struct mtk_hdmi, bridge);
 }
 
-static u32 mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset)
-{
-	return readl(hdmi->regs + offset);
-}
-
-static void mtk_hdmi_write(struct mtk_hdmi *hdmi, u32 offset, u32 val)
-{
-	writel(val, hdmi->regs + offset);
-}
-
-static void mtk_hdmi_clear_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits)
-{
-	void __iomem *reg = hdmi->regs + offset;
-	u32 tmp;
-
-	tmp = readl(reg);
-	tmp &= ~bits;
-	writel(tmp, reg);
-}
-
-static void mtk_hdmi_set_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits)
-{
-	void __iomem *reg = hdmi->regs + offset;
-	u32 tmp;
-
-	tmp = readl(reg);
-	tmp |= bits;
-	writel(tmp, reg);
-}
-
-static void mtk_hdmi_mask(struct mtk_hdmi *hdmi, u32 offset, u32 val, u32 mask)
-{
-	void __iomem *reg = hdmi->regs + offset;
-	u32 tmp;
-
-	tmp = readl(reg);
-	tmp = (tmp & ~mask) | (val & mask);
-	writel(tmp, reg);
-}
-
 static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)
 {
-	mtk_hdmi_mask(hdmi, VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH,
-		      VIDEO_SOURCE_SEL);
+	regmap_update_bits(hdmi->regs, VIDEO_SOURCE_SEL,
+			   VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH);
 }
 
 static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable)
@@ -264,12 +224,12 @@ static void mtk_hdmi_hw_1p4_version_enable(struct mtk_hdmi *hdmi, bool enable)
 
 static void mtk_hdmi_hw_aud_mute(struct mtk_hdmi *hdmi)
 {
-	mtk_hdmi_set_bits(hdmi, GRL_AUDIO_CFG, AUDIO_ZERO);
+	regmap_set_bits(hdmi->regs, GRL_AUDIO_CFG, AUDIO_ZERO);
 }
 
 static void mtk_hdmi_hw_aud_unmute(struct mtk_hdmi *hdmi)
 {
-	mtk_hdmi_clear_bits(hdmi, GRL_AUDIO_CFG, AUDIO_ZERO);
+	regmap_clear_bits(hdmi->regs, GRL_AUDIO_CFG, AUDIO_ZERO);
 }
 
 static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi)
@@ -278,25 +238,25 @@ static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi)
 			   HDMI_RST, HDMI_RST);
 	regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C,
 			   HDMI_RST, 0);
-	mtk_hdmi_clear_bits(hdmi, GRL_CFG3, CFG3_CONTROL_PACKET_DELAY);
+	regmap_clear_bits(hdmi->regs, GRL_CFG3, CFG3_CONTROL_PACKET_DELAY);
 	regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C,
 			   ANLG_ON, ANLG_ON);
 }
 
 static void mtk_hdmi_hw_enable_notice(struct mtk_hdmi *hdmi, bool enable_notice)
 {
-	mtk_hdmi_mask(hdmi, GRL_CFG2, enable_notice ? CFG2_NOTICE_EN : 0,
-		      CFG2_NOTICE_EN);
+	regmap_update_bits(hdmi->regs, GRL_CFG2, CFG2_NOTICE_EN,
+			   enable_notice ? CFG2_NOTICE_EN : 0);
 }
 
 static void mtk_hdmi_hw_write_int_mask(struct mtk_hdmi *hdmi, u32 int_mask)
 {
-	mtk_hdmi_write(hdmi, GRL_INT_MASK, int_mask);
+	regmap_write(hdmi->regs, GRL_INT_MASK, int_mask);
 }
 
 static void mtk_hdmi_hw_enable_dvi_mode(struct mtk_hdmi *hdmi, bool enable)
 {
-	mtk_hdmi_mask(hdmi, GRL_CFG1, enable ? CFG1_DVI : 0, CFG1_DVI);
+	regmap_update_bits(hdmi->regs, GRL_CFG1, CFG1_DVI, enable ? CFG1_DVI : 0);
 }
 
 static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer,
@@ -342,22 +302,22 @@ static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer,
 		dev_err(hdmi->dev, "Unknown infoframe type %d\n", frame_type);
 		return;
 	}
-	mtk_hdmi_clear_bits(hdmi, ctrl_reg, ctrl_frame_en);
-	mtk_hdmi_write(hdmi, GRL_INFOFRM_TYPE, frame_type);
-	mtk_hdmi_write(hdmi, GRL_INFOFRM_VER, frame_ver);
-	mtk_hdmi_write(hdmi, GRL_INFOFRM_LNG, frame_len);
+	regmap_clear_bits(hdmi->regs, ctrl_reg, ctrl_frame_en);
+	regmap_write(hdmi->regs, GRL_INFOFRM_TYPE, frame_type);
+	regmap_write(hdmi->regs, GRL_INFOFRM_VER, frame_ver);
+	regmap_write(hdmi->regs, GRL_INFOFRM_LNG, frame_len);
 
-	mtk_hdmi_write(hdmi, GRL_IFM_PORT, checksum);
+	regmap_write(hdmi->regs, GRL_IFM_PORT, checksum);
 	for (i = 0; i < frame_len; i++)
-		mtk_hdmi_write(hdmi, GRL_IFM_PORT, frame_data[i]);
+		regmap_write(hdmi->regs, GRL_IFM_PORT, frame_data[i]);
 
-	mtk_hdmi_set_bits(hdmi, ctrl_reg, ctrl_frame_en);
+	regmap_set_bits(hdmi->regs, ctrl_reg, ctrl_frame_en);
 }
 
 static void mtk_hdmi_hw_send_aud_packet(struct mtk_hdmi *hdmi, bool enable)
 {
-	mtk_hdmi_mask(hdmi, GRL_SHIFT_R2, enable ? 0 : AUDIO_PACKET_OFF,
-		      AUDIO_PACKET_OFF);
+	regmap_update_bits(hdmi->regs, AUDIO_PACKET_OFF,
+			   GRL_SHIFT_R2, enable ? 0 : AUDIO_PACKET_OFF);
 }
 
 static void mtk_hdmi_hw_config_sys(struct mtk_hdmi *hdmi)
@@ -378,44 +338,44 @@ static void mtk_hdmi_hw_set_deep_color_mode(struct mtk_hdmi *hdmi)
 
 static void mtk_hdmi_hw_send_av_mute(struct mtk_hdmi *hdmi)
 {
-	mtk_hdmi_clear_bits(hdmi, GRL_CFG4, CTRL_AVMUTE);
+	regmap_clear_bits(hdmi->regs, GRL_CFG4, CTRL_AVMUTE);
 	usleep_range(2000, 4000);
-	mtk_hdmi_set_bits(hdmi, GRL_CFG4, CTRL_AVMUTE);
+	regmap_set_bits(hdmi->regs, GRL_CFG4, CTRL_AVMUTE);
 }
 
 static void mtk_hdmi_hw_send_av_unmute(struct mtk_hdmi *hdmi)
 {
-	mtk_hdmi_mask(hdmi, GRL_CFG4, CFG4_AV_UNMUTE_EN,
-		      CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET);
+	regmap_update_bits(hdmi->regs, GRL_CFG4, CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET,
+			   CFG4_AV_UNMUTE_EN);
 	usleep_range(2000, 4000);
-	mtk_hdmi_mask(hdmi, GRL_CFG4, CFG4_AV_UNMUTE_SET,
-		      CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET);
+	regmap_update_bits(hdmi->regs, GRL_CFG4, CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET,
+			   CFG4_AV_UNMUTE_SET);
 }
 
 static void mtk_hdmi_hw_ncts_enable(struct mtk_hdmi *hdmi, bool on)
 {
-	mtk_hdmi_mask(hdmi, GRL_CTS_CTRL, on ? 0 : CTS_CTRL_SOFT,
-		      CTS_CTRL_SOFT);
+	regmap_update_bits(hdmi->regs, GRL_CTS_CTRL, CTS_CTRL_SOFT,
+			   on ? 0 : CTS_CTRL_SOFT);
 }
 
 static void mtk_hdmi_hw_ncts_auto_write_enable(struct mtk_hdmi *hdmi,
 					       bool enable)
 {
-	mtk_hdmi_mask(hdmi, GRL_CTS_CTRL, enable ? NCTS_WRI_ANYTIME : 0,
-		      NCTS_WRI_ANYTIME);
+	regmap_update_bits(hdmi->regs, GRL_CTS_CTRL, NCTS_WRI_ANYTIME,
+			   enable ? NCTS_WRI_ANYTIME : 0);
 }
 
 static void mtk_hdmi_hw_msic_setting(struct mtk_hdmi *hdmi,
 				     struct drm_display_mode *mode)
 {
-	mtk_hdmi_clear_bits(hdmi, GRL_CFG4, CFG4_MHL_MODE);
+	regmap_clear_bits(hdmi->regs, GRL_CFG4, CFG4_MHL_MODE);
 
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE &&
 	    mode->clock == 74250 &&
 	    mode->vdisplay == 1080)
-		mtk_hdmi_clear_bits(hdmi, GRL_CFG2, CFG2_MHL_DE_SEL);
+		regmap_clear_bits(hdmi->regs, GRL_CFG2, CFG2_MHL_DE_SEL);
 	else
-		mtk_hdmi_set_bits(hdmi, GRL_CFG2, CFG2_MHL_DE_SEL);
+		regmap_set_bits(hdmi->regs, GRL_CFG2, CFG2_MHL_DE_SEL);
 }
 
 static void mtk_hdmi_hw_aud_set_channel_swap(struct mtk_hdmi *hdmi,
@@ -443,7 +403,7 @@ static void mtk_hdmi_hw_aud_set_channel_swap(struct mtk_hdmi *hdmi,
 		swap_bit = LFE_CC_SWAP;
 		break;
 	}
-	mtk_hdmi_mask(hdmi, GRL_CH_SWAP, swap_bit, 0xff);
+	regmap_update_bits(hdmi->regs, GRL_CH_SWAP, 0xff, swap_bit);
 }
 
 static void mtk_hdmi_hw_aud_set_bit_num(struct mtk_hdmi *hdmi,
@@ -464,7 +424,7 @@ static void mtk_hdmi_hw_aud_set_bit_num(struct mtk_hdmi *hdmi,
 		break;
 	}
 
-	mtk_hdmi_mask(hdmi, GRL_AOUT_CFG, val, AOUT_BNUM_SEL_MASK);
+	regmap_update_bits(hdmi->regs, GRL_AOUT_CFG, AOUT_BNUM_SEL_MASK, val);
 }
 
 static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi,
@@ -472,7 +432,7 @@ static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi,
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_CFG0);
+	regmap_read(hdmi->regs, GRL_CFG0, &val);
 	val &= ~(CFG0_W_LENGTH_MASK | CFG0_I2S_MODE_MASK);
 
 	switch (i2s_fmt) {
@@ -496,7 +456,7 @@ static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi,
 		val |= CFG0_I2S_MODE_I2S | CFG0_W_LENGTH_16BIT;
 		break;
 	}
-	mtk_hdmi_write(hdmi, GRL_CFG0, val);
+	regmap_write(hdmi->regs, GRL_CFG0, val);
 }
 
 static void mtk_hdmi_hw_audio_config(struct mtk_hdmi *hdmi, bool dst)
@@ -505,14 +465,14 @@ static void mtk_hdmi_hw_audio_config(struct mtk_hdmi *hdmi, bool dst)
 	u8 val;
 
 	/* Disable high bitrate, set DST packet normal/double */
-	mtk_hdmi_clear_bits(hdmi, GRL_AOUT_CFG, HIGH_BIT_RATE_PACKET_ALIGN);
+	regmap_clear_bits(hdmi->regs, GRL_AOUT_CFG, HIGH_BIT_RATE_PACKET_ALIGN);
 
 	if (dst)
 		val = DST_NORMAL_DOUBLE | SACD_DST;
 	else
 		val = 0;
 
-	mtk_hdmi_mask(hdmi, GRL_AUDIO_CFG, val, mask);
+	regmap_update_bits(hdmi->regs, GRL_AUDIO_CFG, mask, val);
 }
 
 static void mtk_hdmi_hw_aud_set_i2s_chan_num(struct mtk_hdmi *hdmi,
@@ -553,10 +513,10 @@ static void mtk_hdmi_hw_aud_set_i2s_chan_num(struct mtk_hdmi *hdmi,
 		i2s_uv = I2S_UV_CH_EN(0);
 	}
 
-	mtk_hdmi_write(hdmi, GRL_CH_SW0, ch_switch & 0xff);
-	mtk_hdmi_write(hdmi, GRL_CH_SW1, (ch_switch >> 8) & 0xff);
-	mtk_hdmi_write(hdmi, GRL_CH_SW2, (ch_switch >> 16) & 0xff);
-	mtk_hdmi_write(hdmi, GRL_I2S_UV, i2s_uv);
+	regmap_write(hdmi->regs, GRL_CH_SW0, ch_switch & 0xff);
+	regmap_write(hdmi->regs, GRL_CH_SW1, (ch_switch >> 8) & 0xff);
+	regmap_write(hdmi->regs, GRL_CH_SW2, (ch_switch >> 16) & 0xff);
+	regmap_write(hdmi->regs, GRL_I2S_UV, i2s_uv);
 }
 
 static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi,
@@ -564,7 +524,7 @@ static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi,
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_CFG1);
+	regmap_read(hdmi->regs, GRL_CFG1, &val);
 	if (input_type == HDMI_AUD_INPUT_I2S &&
 	    (val & CFG1_SPDIF) == CFG1_SPDIF) {
 		val &= ~CFG1_SPDIF;
@@ -572,7 +532,7 @@ static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi,
 		(val & CFG1_SPDIF) == 0) {
 		val |= CFG1_SPDIF;
 	}
-	mtk_hdmi_write(hdmi, GRL_CFG1, val);
+	regmap_write(hdmi->regs, GRL_CFG1, val);
 }
 
 static void mtk_hdmi_hw_aud_set_channel_status(struct mtk_hdmi *hdmi,
@@ -581,13 +541,13 @@ static void mtk_hdmi_hw_aud_set_channel_status(struct mtk_hdmi *hdmi,
 	int i;
 
 	for (i = 0; i < 5; i++) {
-		mtk_hdmi_write(hdmi, GRL_I2S_C_STA0 + i * 4, channel_status[i]);
-		mtk_hdmi_write(hdmi, GRL_L_STATUS_0 + i * 4, channel_status[i]);
-		mtk_hdmi_write(hdmi, GRL_R_STATUS_0 + i * 4, channel_status[i]);
+		regmap_write(hdmi->regs, GRL_I2S_C_STA0 + i * 4, channel_status[i]);
+		regmap_write(hdmi->regs, GRL_L_STATUS_0 + i * 4, channel_status[i]);
+		regmap_write(hdmi->regs, GRL_R_STATUS_0 + i * 4, channel_status[i]);
 	}
 	for (; i < 24; i++) {
-		mtk_hdmi_write(hdmi, GRL_L_STATUS_0 + i * 4, 0);
-		mtk_hdmi_write(hdmi, GRL_R_STATUS_0 + i * 4, 0);
+		regmap_write(hdmi->regs, GRL_L_STATUS_0 + i * 4, 0);
+		regmap_write(hdmi->regs, GRL_R_STATUS_0 + i * 4, 0);
 	}
 }
 
@@ -595,13 +555,13 @@ static void mtk_hdmi_hw_aud_src_reenable(struct mtk_hdmi *hdmi)
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL);
+	regmap_read(hdmi->regs, GRL_MIX_CTRL, &val);
 	if (val & MIX_CTRL_SRC_EN) {
 		val &= ~MIX_CTRL_SRC_EN;
-		mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);
+		regmap_write(hdmi->regs, GRL_MIX_CTRL, val);
 		usleep_range(255, 512);
 		val |= MIX_CTRL_SRC_EN;
-		mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);
+		regmap_write(hdmi->regs, GRL_MIX_CTRL, val);
 	}
 }
 
@@ -609,10 +569,10 @@ static void mtk_hdmi_hw_aud_src_disable(struct mtk_hdmi *hdmi)
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL);
+	regmap_read(hdmi->regs, GRL_MIX_CTRL, &val);
 	val &= ~MIX_CTRL_SRC_EN;
-	mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);
-	mtk_hdmi_write(hdmi, GRL_SHIFT_L1, 0x00);
+	regmap_write(hdmi->regs, GRL_MIX_CTRL, val);
+	regmap_write(hdmi->regs, GRL_SHIFT_L1, 0x00);
 }
 
 static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
@@ -620,7 +580,7 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_CFG5);
+	regmap_read(hdmi->regs, GRL_CFG5, &val);
 	val &= CFG5_CD_RATIO_MASK;
 
 	switch (mclk) {
@@ -643,7 +603,7 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
 		val |= CFG5_FS256;
 		break;
 	}
-	mtk_hdmi_write(hdmi, GRL_CFG5, val);
+	regmap_write(hdmi->regs, GRL_CFG5, val);
 }
 
 struct hdmi_acr_n {
@@ -727,9 +687,9 @@ static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,
 	unsigned char val[NCTS_BYTES];
 	int i;
 
-	mtk_hdmi_write(hdmi, GRL_NCTS, 0);
-	mtk_hdmi_write(hdmi, GRL_NCTS, 0);
-	mtk_hdmi_write(hdmi, GRL_NCTS, 0);
+	regmap_write(hdmi->regs, GRL_NCTS, 0);
+	regmap_write(hdmi->regs, GRL_NCTS, 0);
+	regmap_write(hdmi->regs, GRL_NCTS, 0);
 	memset(val, 0, sizeof(val));
 
 	val[0] = (cts >> 24) & 0xff;
@@ -742,7 +702,7 @@ static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,
 	val[6] = n & 0xff;
 
 	for (i = 0; i < NCTS_BYTES; i++)
-		mtk_hdmi_write(hdmi, GRL_NCTS, val[i]);
+		regmap_write(hdmi->regs, GRL_NCTS, val[i]);
 }
 
 static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
@@ -757,8 +717,7 @@ static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
 	dev_dbg(hdmi->dev, "%s: sample_rate=%u, clock=%d, cts=%u, n=%u\n",
 		__func__, sample_rate, clock, n, cts);
 
-	mtk_hdmi_mask(hdmi, DUMMY_304, AUDIO_I2S_NCTS_SEL_64,
-		      AUDIO_I2S_NCTS_SEL);
+	regmap_update_bits(hdmi->regs, DUMMY_304, AUDIO_I2S_NCTS_SEL, AUDIO_I2S_NCTS_SEL_64);
 	do_hdmi_hw_aud_set_ncts(hdmi, n, cts);
 }
 
@@ -878,7 +837,7 @@ static void mtk_hdmi_aud_set_input(struct mtk_hdmi *hdmi)
 	bool dst;
 
 	mtk_hdmi_hw_aud_set_channel_swap(hdmi, HDMI_AUD_SWAP_LFE_CC);
-	mtk_hdmi_set_bits(hdmi, GRL_MIX_CTRL, MIX_CTRL_FLAT);
+	regmap_set_bits(hdmi->regs, GRL_MIX_CTRL, MIX_CTRL_FLAT);
 
 	if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_SPDIF &&
 	    hdmi->aud_param.aud_codec == HDMI_AUDIO_CODING_TYPE_DST) {
@@ -910,7 +869,7 @@ static int mtk_hdmi_aud_set_src(struct mtk_hdmi *hdmi,
 
 	mtk_hdmi_hw_ncts_enable(hdmi, false);
 	mtk_hdmi_hw_aud_src_disable(hdmi);
-	mtk_hdmi_clear_bits(hdmi, GRL_CFG2, CFG2_ACLK_INV);
+	regmap_clear_bits(hdmi->regs, GRL_CFG2, CFG2_ACLK_INV);
 
 	if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_I2S) {
 		switch (sample_rate) {
@@ -1424,7 +1383,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 	struct device_node *cec_np, *remote, *i2c_np;
 	struct platform_device *cec_pdev;
 	struct regmap *regmap;
-	struct resource *mem;
 	int ret;
 
 	ret = mtk_hdmi_get_all_clk(hdmi, np);
@@ -1470,8 +1428,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 	}
 	hdmi->sys_regmap = regmap;
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdmi->regs = devm_ioremap_resource(dev, mem);
+	hdmi->regs = device_node_to_regmap(dev->of_node);
 	if (IS_ERR(hdmi->regs)) {
 		ret = PTR_ERR(hdmi->regs);
 		goto put_device;
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:13 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:13 +0100
Subject: [PATCH v2 11/15] drm/mediatek: mtk_hdmi: Fix typo for aud_sampe_size member
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-12-angelogioacchino.delregno@collabora.com>

Rename member aud_sampe_size of struct hdmi_audio_param to
aud_sample_size to fix a typo and enhance readability.

This commit brings no functional changes.

Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 9e8d9144cf86..7808141526fa 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -136,7 +136,7 @@ enum hdmi_aud_channel_swap_type {
 
 struct hdmi_audio_param {
 	enum hdmi_audio_coding_type aud_codec;
-	enum hdmi_audio_sample_size aud_sampe_size;
+	enum hdmi_audio_sample_size aud_sample_size;
 	enum hdmi_aud_input_type aud_input_type;
 	enum hdmi_aud_i2s_fmt aud_i2s_fmt;
 	enum hdmi_aud_mclk aud_mclk;
@@ -1032,7 +1032,7 @@ static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
 
 	hdmi->csp = HDMI_COLORSPACE_RGB;
 	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-	aud_param->aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
 	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
 	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
 	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
@@ -1528,14 +1528,14 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
 	switch (daifmt->fmt) {
 	case HDMI_I2S:
 		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
 		hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
 		hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
 		hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
 		break;
 	case HDMI_SPDIF:
 		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
 		hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
 		break;
 	default:
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:15 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:15 +0100
Subject: [PATCH v2 13/15] drm/mediatek: mtk_hdmi_common: Assign DDC adapter pointer to bridge
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-14-angelogioacchino.delregno@collabora.com>

In preparation for adding the new HDMI TX v2 IP driver, assign the
pointer to the DDC adapter to struct drm_bridge during probe.

This commit brings no functional changes.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index 1b23ab6969ec..4f708b04f5e8 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -410,6 +410,7 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
 	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	hdmi->bridge.of_node = pdev->dev.of_node;
+	hdmi->bridge.ddc = hdmi->ddc_adpt;
 
 	ret = devm_drm_bridge_add(dev, &hdmi->bridge);
 	if (ret)
-- 
2.47.0



From mark.rutland at arm.com  Thu Dec  5 04:16:52 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu,  5 Dec 2024 12:16:52 +0000
Subject: [PATCH 1/4] arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL
In-Reply-To: <20241205121655.1824269-1-mark.rutland@arm.com>
References: <20241205121655.1824269-1-mark.rutland@arm.com>
Message-ID: <20241205121655.1824269-2-mark.rutland@arm.com>

Currently tagged_addr_ctrl_set() doesn't initialize the temporary 'ctrl'
variable, and a SETREGSET call with a length of zero will leave this
uninitialized. Consequently tagged_addr_ctrl_set() will consume an
arbitrary value, potentially leaking up to 64 bits of memory from the
kernel stack. The read is limited to a specific slot on the stack, and
the issue does not provide a write mechanism.

As set_tagged_addr_ctrl() only accepts values where bits [63:4] zero and
rejects other values, a partial SETREGSET attempt will randomly succeed
or fail depending on the value of the uninitialized value, and the
exposure is significantly limited.

Fix this by initializing the temporary value before copying the regset
from userspace, as for other regsets (e.g. NT_PRSTATUS, NT_PRFPREG,
NT_ARM_SYSTEM_CALL). In the case of a zero-length write, the existing
value of the tagged address ctrl will be retained.

The NT_ARM_TAGGED_ADDR_CTRL regset is only visible in the
user_aarch64_view used by a native AArch64 task to manipulate another
native AArch64 task. As get_tagged_addr_ctrl() only returns an error
value when called for a compat task, tagged_addr_ctrl_get() and
tagged_addr_ctrl_set() should never observe an error value from
get_tagged_addr_ctrl(). Add a WARN_ON_ONCE() to both to indicate that
such an error would be unexpected, and error handlnig is not missing in
either case.

Fixes: 2200aa7154cb7ef7 ("arm64: mte: ptrace: Add NT_ARM_TAGGED_ADDR_CTRL regset")
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>
---
 arch/arm64/kernel/ptrace.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index e4437f62a2cda..8525d03f0fb40 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1427,7 +1427,7 @@ static int tagged_addr_ctrl_get(struct task_struct *target,
 {
 	long ctrl = get_tagged_addr_ctrl(target);
 
-	if (IS_ERR_VALUE(ctrl))
+	if (WARN_ON_ONCE(IS_ERR_VALUE(ctrl)))
 		return ctrl;
 
 	return membuf_write(&to, &ctrl, sizeof(ctrl));
@@ -1441,6 +1441,10 @@ static int tagged_addr_ctrl_set(struct task_struct *target, const struct
 	int ret;
 	long ctrl;
 
+	ctrl = get_tagged_addr_ctrl(target);
+	if (WARN_ON_ONCE(IS_ERR_VALUE(ctrl)))
+		return ctrl;
+
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1);
 	if (ret)
 		return ret;
-- 
2.30.2



From mark.rutland at arm.com  Thu Dec  5 04:16:53 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu,  5 Dec 2024 12:16:53 +0000
Subject: [PATCH 2/4] arm64: ptrace: fix partial SETREGSET for NT_ARM_FPMR
In-Reply-To: <20241205121655.1824269-1-mark.rutland@arm.com>
References: <20241205121655.1824269-1-mark.rutland@arm.com>
Message-ID: <20241205121655.1824269-3-mark.rutland@arm.com>

Currently fpmr_set() doesn't initialize the temporary 'fpmr' variable,
and a SETREGSET call with a length of zero will leave this
uninitialized. Consequently an arbitrary value will be written back to
target->thread.uw.fpmr, potentially leaking up to 64 bits of memory from
the kernel stack. The read is limited to a specific slot on the stack,
and the issue does not provide a write mechanism.

Fix this by initializing the temporary value before copying the regset
from userspace, as for other regsets (e.g. NT_PRSTATUS, NT_PRFPREG,
NT_ARM_SYSTEM_CALL). In the case of a zero-length write, the existing
contents of FPMR will be retained.

Before this patch:

| # ./fpmr-test
| Attempting to write NT_ARM_FPMR::fpmr = 0x900d900d900d900d
| SETREGSET(nt=0x40e, len=8) wrote 8 bytes
|
| Attempting to read NT_ARM_FPMR::fpmr
| GETREGSET(nt=0x40e, len=8) read 8 bytes
| Read NT_ARM_FPMR::fpmr = 0x900d900d900d900d
|
| Attempting to write NT_ARM_FPMR (zero length)
| SETREGSET(nt=0x40e, len=0) wrote 0 bytes
|
| Attempting to read NT_ARM_FPMR::fpmr
| GETREGSET(nt=0x40e, len=8) read 8 bytes
| Read NT_ARM_FPMR::fpmr = 0xffff800083963d50

After this patch:

| # ./fpmr-test
| Attempting to write NT_ARM_FPMR::fpmr = 0x900d900d900d900d
| SETREGSET(nt=0x40e, len=8) wrote 8 bytes
|
| Attempting to read NT_ARM_FPMR::fpmr
| GETREGSET(nt=0x40e, len=8) read 8 bytes
| Read NT_ARM_FPMR::fpmr = 0x900d900d900d900d
|
| Attempting to write NT_ARM_FPMR (zero length)
| SETREGSET(nt=0x40e, len=0) wrote 0 bytes
|
| Attempting to read NT_ARM_FPMR::fpmr
| GETREGSET(nt=0x40e, len=8) read 8 bytes
| Read NT_ARM_FPMR::fpmr = 0x900d900d900d900d

Fixes: 4035c22ef7d43a6c ("arm64/ptrace: Expose FPMR via ptrace")
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Mark Brown <broonie at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/ptrace.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 8525d03f0fb40..85c862dc845b3 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -720,6 +720,8 @@ static int fpmr_set(struct task_struct *target, const struct user_regset *regset
 	if (!system_supports_fpmr())
 		return -EINVAL;
 
+	fpmr = target->thread.uw.fpmr;
+
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fpmr, 0, count);
 	if (ret)
 		return ret;
-- 
2.30.2



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:35 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:35 +0100
Subject: [PATCH v5 00/20] Support spread spectrum clocking for i.MX8N PLLs
Message-ID: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>

The series adds support for spread spectrum clocking for i.MX8MN
PLLs (audio, video and DRAM). It has been tested for the video PLL on
a board using i.MX8MN.

The patches added in version 4, such as the dt-bindings and the driver
for anatop, were inspired by the extensive email exchange from version 3:
https://lore.kernel.org/imx/20241106090549.3684963-1-dario.binacchi at amarulasolutions.com/

Version 5 adds only a few fixes to some patches, merely addressing
compilation errors and warnings raised by checkpatch, but otherwise
does not alter the structure of version 4.

The series added spectrum spread support for the imx8mn platform only,
but in case it was merged, confirming that the directives and suggestions
made by the maintainers were correctly understood and implemented, I will
extend this support to the imx8mm and imx8mp platforms as well.

Changes in v5:
- Fix compilation errors.
- Separate driver code from dt-bindings

Changes in v4:
- Add dt-bindings for anatop
- Add anatop driver
- Drop fsl,ssc-clocks from spread spectrum dt-bindings

Changes in v3:
- Patches 1/8 has been added in version 3. The dt-bindings have
  been moved from fsl,imx8m-anatop.yaml to imx8m-clock.yaml. The
  anatop device (fsl,imx8m-anatop.yaml) is indeed more or less a
  syscon, so it represents a memory area accessible by ccm
  (imx8m-clock.yaml) to setup the PLLs.
- Patches {3,5}/8 have been added in version 3.
- Patches {4,6,8}/8 use ccm device node instead of the anatop one.

Changes in v2:
- Add "allOf:" and place it after "required:" block, like in the
  example schema.
- Move the properties definition to the top-level.
- Drop unit types as requested by the "make dt_binding_check" command.

Dario Binacchi (20):
  dt-bindings: clock: imx8mm: add VIDEO_PLL clocks
  clk: imx8mm: rename video_pll1 to video_pll
  dt-bindings: clock: imx8mp: add VIDEO_PLL clocks
  clk: imx8mp: rename video_pll1 to video_pll
  dt-bindings: clock: imx8m-anatop: define clocks/clock-names
  arm64: dts: imx8mm: add anatop clocks
  arm64: dts: imx8mn: add anatop clocks
  arm64: dts: imx8mp: add anatop clocks
  arm64: dts: imx8mq: add anatop clocks
  dt-bindings: clock: imx8mm: add binding definitions for anatop
  dt-bindings: clock: imx8mn: add binding definitions for anatop
  dt-bindings: clock: imx8mp: add binding definitions for anatop
  clk: imx: add hw API imx8m_anatop_get_clk_hw
  clk: imx: add support for i.MX8MN anatop clock driver
  dt-bindings: clock: imx8m-clock: support spread spectrum clocking
  arm64: dts: imx8mm: add PLLs to clock controller module (ccm)
  arm64: dts: imx8mn: add PLLs to clock controller module (ccm)
  arm64: dts: imx8mp: add PLLs to clock controller module (ccm)
  clk: imx: pll14xx: support spread spectrum clock generation
  clk: imx8mn: support spread spectrum clock generation

 .../bindings/clock/fsl,imx8m-anatop.yaml      |  53 +++-
 .../bindings/clock/imx8m-clock.yaml           |  77 ++++-
 arch/arm64/boot/dts/freescale/imx8mm.dtsi     |  11 +-
 arch/arm64/boot/dts/freescale/imx8mn.dtsi     |  11 +-
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     |  11 +-
 arch/arm64/boot/dts/freescale/imx8mq.dtsi     |   2 +
 drivers/clk/imx/Makefile                      |   2 +-
 drivers/clk/imx/clk-imx8mm.c                  | 102 +++----
 drivers/clk/imx/clk-imx8mn-anatop.c           | 281 ++++++++++++++++++
 drivers/clk/imx/clk-imx8mn.c                  | 188 ++++++------
 drivers/clk/imx/clk-imx8mp.c                  | 118 ++++----
 drivers/clk/imx/clk-pll14xx.c                 | 126 ++++++++
 drivers/clk/imx/clk.c                         |  28 ++
 drivers/clk/imx/clk.h                         |  23 ++
 include/dt-bindings/clock/imx8mm-clock.h      |  78 ++++-
 include/dt-bindings/clock/imx8mn-clock.h      |  67 +++++
 include/dt-bindings/clock/imx8mp-clock.h      |  82 ++++-
 17 files changed, 1026 insertions(+), 234 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx8mn-anatop.c

-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:36 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:36 +0100
Subject: [PATCH v5 01/20] dt-bindings: clock: imx8mm: add VIDEO_PLL clocks
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-2-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's add the IMX8MM_VIDEO_PLL[_*]
definitions to be consistent with the RM and avoid misunderstandings.

The IMX8MM_VIDEO_PLL1* constants have not been removed to ensure
backward compatibility of the patch.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v5:
- New

 include/dt-bindings/clock/imx8mm-clock.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
index 1f768b2eeb1a..102d8a6cdb55 100644
--- a/include/dt-bindings/clock/imx8mm-clock.h
+++ b/include/dt-bindings/clock/imx8mm-clock.h
@@ -16,7 +16,8 @@
 #define IMX8MM_CLK_EXT4				7
 #define IMX8MM_AUDIO_PLL1_REF_SEL		8
 #define IMX8MM_AUDIO_PLL2_REF_SEL		9
-#define IMX8MM_VIDEO_PLL1_REF_SEL		10
+#define IMX8MM_VIDEO_PLL_REF_SEL		10
+#define IMX8MM_VIDEO_PLL1_REF_SEL		IMX8MM_VIDEO_PLL_REF_SEL
 #define IMX8MM_DRAM_PLL_REF_SEL			11
 #define IMX8MM_GPU_PLL_REF_SEL			12
 #define IMX8MM_VPU_PLL_REF_SEL			13
@@ -26,7 +27,8 @@
 #define IMX8MM_SYS_PLL3_REF_SEL			17
 #define IMX8MM_AUDIO_PLL1			18
 #define IMX8MM_AUDIO_PLL2			19
-#define IMX8MM_VIDEO_PLL1			20
+#define IMX8MM_VIDEO_PLL			20
+#define IMX8MM_VIDEO_PLL1			IMX8MM_VIDEO_PLL
 #define IMX8MM_DRAM_PLL				21
 #define IMX8MM_GPU_PLL				22
 #define IMX8MM_VPU_PLL				23
@@ -36,7 +38,8 @@
 #define IMX8MM_SYS_PLL3				27
 #define IMX8MM_AUDIO_PLL1_BYPASS		28
 #define IMX8MM_AUDIO_PLL2_BYPASS		29
-#define IMX8MM_VIDEO_PLL1_BYPASS		30
+#define IMX8MM_VIDEO_PLL_BYPASS			30
+#define IMX8MM_VIDEO_PLL1_BYPASS		IMX8MM_VIDEO_PLL_BYPASS
 #define IMX8MM_DRAM_PLL_BYPASS			31
 #define IMX8MM_GPU_PLL_BYPASS			32
 #define IMX8MM_VPU_PLL_BYPASS			33
@@ -46,7 +49,8 @@
 #define IMX8MM_SYS_PLL3_BYPASS			37
 #define IMX8MM_AUDIO_PLL1_OUT			38
 #define IMX8MM_AUDIO_PLL2_OUT			39
-#define IMX8MM_VIDEO_PLL1_OUT			40
+#define IMX8MM_VIDEO_PLL_OUT			40
+#define IMX8MM_VIDEO_PLL1_OUT			IMX8MM_VIDEO_PLL_OUT
 #define IMX8MM_DRAM_PLL_OUT			41
 #define IMX8MM_GPU_PLL_OUT			42
 #define IMX8MM_VPU_PLL_OUT			43
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:37 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:37 +0100
Subject: [PATCH v5 02/20] clk: imx8mm: rename video_pll1 to video_pll
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-3-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's rename "video_pll1" to
"video_pll" to be consistent with the RM and avoid misunderstandings.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---
The patch, which simply replaces video_pll1 with video_pll, highlights
many warnings raised by checkpatch.pl. These are not generated by the
changes made but are inherited from how the module was originally
written. Fixing them would have meant "obscuring" the actual changes
introduced.

Changes in v5:
- Split the patch dropping the dt-bindings changes.

Changes in v4:
- New

 drivers/clk/imx/clk-imx8mm.c | 102 +++++++++++++++++------------------
 1 file changed, 51 insertions(+), 51 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index 342049b847b9..8a1fc7e17ba2 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -28,7 +28,7 @@ static u32 share_count_nand;
 static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
 static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
 static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
-static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char *video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
 static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
 static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
 static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
@@ -42,22 +42,22 @@ static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m
 static const char * const imx8mm_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
 
 static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m",
-				       "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+				       "sys_pll1_800m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", };
 
 static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
 					"sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", };
 
 static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
-					  "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					  "sys_pll2_1000m", "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
-					  "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					  "sys_pll2_1000m", "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m",
-					     "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",};
+					     "sys_pll2_1000m", "audio_pll1_out", "video_pll_out", "sys_pll1_100m",};
 
 static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
-					     "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+					     "sys_pll2_200m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", };
 
 static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
 					       "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
@@ -72,28 +72,28 @@ static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pl
 					     "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
 
 static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m",
-					      "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
+					      "audio_pll1_out", "video_pll_out", "clk_ext2", "clk_ext3", };
 
 static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
 					    "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
 
 static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
-					    "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					    "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
-					    "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					    "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m",
-					"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					"audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m",
-					    "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", };
+					    "sys_pll1_800m", "audio_pll1_out", "video_pll_out", };
 
 static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
-					"sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+					"sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll_out", };
 
 static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m",
-					      "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+					      "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll_out", };
 
 static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m",
 					     "sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", };
@@ -108,10 +108,10 @@ static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_8
 					   "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
 
 static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "dummy", "sys_pll1_800m", "sys_pll2_1000m",
-					      "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+					      "sys_pll1_160m", "video_pll_out", "sys_pll3_out", "audio_pll2_out", };
 
 static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "dummy", "sys_pll1_800m", "sys_pll2_1000m",
-						"sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+						"sys_pll1_160m", "video_pll_out", "sys_pll3_out", "audio_pll2_out", };
 
 static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
 					       "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
@@ -122,47 +122,47 @@ static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_p
 static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
 					      "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
 
-static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out", "audio_pll1_out",
 					     "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
-static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out", "audio_pll1_out",
 						"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
-static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
 
-static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
 
-static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
 
-static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
 
-static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
 
-static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
 
-static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					   "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
 
-static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					   "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
 
 static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
-					     "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
+					     "sys_pll1_160m", "audio_pll1_out", "video_pll_out", "clk_ext4", };
 
 static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
-					       "clk_ext3", "clk_ext4", "video_pll1_out", };
+					       "clk_ext3", "clk_ext4", "video_pll_out", };
 
 static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
-					     "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
+					     "sys_pll2_500m", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
-					 "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
+					 "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll_out", };
 
 static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m",
 					 "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
@@ -174,16 +174,16 @@ static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1
 					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
 
 static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
 					  "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
@@ -213,19 +213,19 @@ static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1
 					   "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
 
 static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
-					 "video_pll1_out", "sys_pll1_80m", "audio_pll1_out", "clk_ext1" };
+					 "video_pll_out", "sys_pll1_80m", "audio_pll1_out", "clk_ext1" };
 
 static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
 					 "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
@@ -234,31 +234,31 @@ static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_ou
 					  "sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", };
 
 static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
-					     "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					     "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m",
-					    "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+					    "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m",
-					    "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					    "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
 					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
 
 static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
-					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
-					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
 					     "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
 
 static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
-					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
-					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
 					     "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
@@ -286,9 +286,9 @@ static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }
 static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "dummy", "sys_pll1_200m",
 					  "audio_pll2_out", "sys_pll2_500m", "vpu_pll", "sys_pll1_80m", };
 static const char *imx8mm_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", "sys_pll2_166m",
-					  "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "osc_32k", };
+					  "sys_pll3_out", "audio_pll1_out", "video_pll_out", "osc_32k", };
 
-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					   "dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
 					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
 					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
@@ -327,7 +327,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MM_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
@@ -336,7 +336,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MM_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
 	hws[IMX8MM_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
-	hws[IMX8MM_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
+	hws[IMX8MM_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll);
 	hws[IMX8MM_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
 	hws[IMX8MM_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
 	hws[IMX8MM_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
@@ -348,7 +348,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 	/* PLL bypass out */
 	hws[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MM_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
@@ -358,7 +358,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 	/* PLL out gate */
 	hws[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
 	hws[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
-	hws[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+	hws[IMX8MM_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13);
 	hws[IMX8MM_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
 	hws[IMX8MM_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
 	hws[IMX8MM_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:38 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:38 +0100
Subject: [PATCH v5 03/20] dt-bindings: clock: imx8mp: add VIDEO_PLL clocks
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-4-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's add the IMX8MP_VIDEO_PLL[_*]
definitions to be consistent with the RM and avoid misunderstandings.

The IMX8MP_VIDEO_PLL1* constants have not been removed to ensure
backward compatibility of the patch.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v5:
- New

 include/dt-bindings/clock/imx8mp-clock.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
index 7da4243984b2..3235d7de3b62 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -16,7 +16,8 @@
 #define IMX8MP_CLK_EXT4				7
 #define IMX8MP_AUDIO_PLL1_REF_SEL		8
 #define IMX8MP_AUDIO_PLL2_REF_SEL		9
-#define IMX8MP_VIDEO_PLL1_REF_SEL		10
+#define IMX8MP_VIDEO_PLL_REF_SEL		10
+#define IMX8MP_VIDEO_PLL1_REF_SEL		IMX8MP_VIDEO_PLL_REF_SEL
 #define IMX8MP_DRAM_PLL_REF_SEL			11
 #define IMX8MP_GPU_PLL_REF_SEL			12
 #define IMX8MP_VPU_PLL_REF_SEL			13
@@ -26,7 +27,8 @@
 #define IMX8MP_SYS_PLL3_REF_SEL			17
 #define IMX8MP_AUDIO_PLL1			18
 #define IMX8MP_AUDIO_PLL2			19
-#define IMX8MP_VIDEO_PLL1			20
+#define IMX8MP_VIDEO_PLL			20
+#define IMX8MP_VIDEO_PLL1			IMX8MP_VIDEO_PLL
 #define IMX8MP_DRAM_PLL				21
 #define IMX8MP_GPU_PLL				22
 #define IMX8MP_VPU_PLL				23
@@ -36,7 +38,8 @@
 #define IMX8MP_SYS_PLL3				27
 #define IMX8MP_AUDIO_PLL1_BYPASS		28
 #define IMX8MP_AUDIO_PLL2_BYPASS		29
-#define IMX8MP_VIDEO_PLL1_BYPASS		30
+#define IMX8MP_VIDEO_PLL_BYPASS			30
+#define IMX8MP_VIDEO_PLL1_BYPASS		IMX8MP_VIDEO_PLL_BYPASS
 #define IMX8MP_DRAM_PLL_BYPASS			31
 #define IMX8MP_GPU_PLL_BYPASS			32
 #define IMX8MP_VPU_PLL_BYPASS			33
@@ -46,7 +49,8 @@
 #define IMX8MP_SYS_PLL3_BYPASS			37
 #define IMX8MP_AUDIO_PLL1_OUT			38
 #define IMX8MP_AUDIO_PLL2_OUT			39
-#define IMX8MP_VIDEO_PLL1_OUT			40
+#define IMX8MP_VIDEO_PLL_OUT			40
+#define IMX8MP_VIDEO_PLL1_OUT			IMX8MP_VIDEO_PLL_OUT
 #define IMX8MP_DRAM_PLL_OUT			41
 #define IMX8MP_GPU_PLL_OUT			42
 #define IMX8MP_VPU_PLL_OUT			43
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:39 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:39 +0100
Subject: [PATCH v5 04/20] clk: imx8mp: rename video_pll1 to video_pll
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-5-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's rename "video_pll1" to
"video_pll" to be consistent with the RM and avoid misunderstandings.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---
The patch, which simply replaces video_pll1 with video_pll, highlights
many warnings raised by checkpatch.pl. These are not generated by the
changes made but are inherited from how the module was originally
written. Fixing them would have meant "obscuring" the actual changes
introduced.

Changes in v5:
- Split the patch dropping the dt-bindings changes.

Changes in v4:
- New

 drivers/clk/imx/clk-imx8mp.c | 118 +++++++++++++++++------------------
 1 file changed, 59 insertions(+), 59 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 516dbd170c8a..e96460534e7d 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -23,7 +23,7 @@ static u32 share_count_audio;
 static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
 static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
 static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
-static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
 static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
 static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
 static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
@@ -40,27 +40,27 @@ static const char * const imx8mp_a53_core_sels[] = {"arm_a53_div", "arm_pll_out"
 
 static const char * const imx8mp_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m",
 					      "vpu_pll_out", "sys_pll1_800m", "audio_pll1_out",
-					      "video_pll1_out", "sys_pll3_out", };
+					      "video_pll_out", "sys_pll3_out", };
 
 static const char * const imx8mp_ml_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 					      "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-					      "video_pll1_out", "audio_pll2_out", };
+					      "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu3d_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						      "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						      "video_pll1_out", "audio_pll2_out", };
+						      "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu3d_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 							"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-							"video_pll1_out", "audio_pll2_out", };
+							"video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						 "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						 "video_pll1_out", "audio_pll2_out", };
+						 "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_audio_axi_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						     "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						     "video_pll1_out", "audio_pll2_out", };
+						     "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_hsio_axi_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
 						    "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
@@ -72,11 +72,11 @@ static const char * const imx8mp_media_isp_sels[] = {"osc_24m", "sys_pll2_1000m"
 
 static const char * const imx8mp_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m",
 						    "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
-						    "video_pll1_out", "sys_pll1_100m",};
+						    "video_pll_out", "sys_pll1_100m",};
 
 static const char * const imx8mp_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
 						    "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
-						    "video_pll1_out", "sys_pll3_out", };
+						    "video_pll_out", "sys_pll3_out", };
 
 static const char * const imx8mp_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
 						      "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
@@ -96,35 +96,35 @@ static const char * const imx8mp_media_apb_sels[] = {"osc_24m", "sys_pll2_125m",
 
 static const char * const imx8mp_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						   "video_pll1_out", "audio_pll2_out", };
+						   "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						   "video_pll1_out", "audio_pll2_out", };
+						   "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
 					       "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
-					       "video_pll1_out", "audio_pll2_out", };
+					       "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_noc_io_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
 						  "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
-						  "video_pll1_out", "audio_pll2_out", };
+						  "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_ml_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						  "video_pll1_out", "audio_pll2_out", };
+						  "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_ml_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						  "video_pll1_out", "audio_pll2_out", };
+						  "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m",
 					       "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
-					       "audio_pll1_out", "video_pll1_out", };
+					       "audio_pll1_out", "video_pll_out", };
 
 static const char * const imx8mp_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
 						     "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out",
-						     "audio_pll1_out", "video_pll1_out", };
+						     "audio_pll1_out", "video_pll_out", };
 
 static const char * const imx8mp_mipi_dsi_esc_rx_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
 							   "sys_pll1_800m", "sys_pll2_1000m",
@@ -159,56 +159,56 @@ static const char * const imx8mp_pcie_aux_sels[] = {"osc_24m", "sys_pll2_200m",
 						    "sys_pll1_160m", "sys_pll1_200m", };
 
 static const char * const imx8mp_i2c5_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c6_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext1", "clk_ext2", };
 
 static const char * const imx8mp_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext2", "clk_ext3", };
 
 static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
 
 static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext2", "clk_ext3", };
 
 static const char * const imx8mp_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
 
 static const char * const imx8mp_enet_qos_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
 						    "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
-						    "video_pll1_out", "clk_ext4", };
+						    "video_pll_out", "clk_ext4", };
 
 static const char * const imx8mp_enet_qos_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
 							  "clk_ext1", "clk_ext2", "clk_ext3",
-							  "clk_ext4", "video_pll1_out", };
+							  "clk_ext4", "video_pll_out", };
 
 static const char * const imx8mp_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
 						    "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
-						    "video_pll1_out", "clk_ext4", };
+						    "video_pll_out", "clk_ext4", };
 
 static const char * const imx8mp_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
 						      "clk_ext1", "clk_ext2", "clk_ext3",
-						      "clk_ext4", "video_pll1_out", };
+						      "clk_ext4", "video_pll_out", };
 
 static const char * const imx8mp_enet_phy_ref_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m",
 							"sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out",
-							"video_pll1_out", "audio_pll2_out", };
+							"video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
 						"sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
-						"sys_pll2_250m", "video_pll1_out", };
+						"sys_pll2_250m", "video_pll_out", };
 
 static const char * const imx8mp_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m",
 						"sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
@@ -223,19 +223,19 @@ static const char * const imx8mp_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "s
 						  "audio_pll2_out", "sys_pll1_100m", };
 
 static const char * const imx8mp_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
@@ -276,42 +276,42 @@ static const char * const imx8mp_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "s
 
 static const char * const imx8mp_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext1" };
 
 static const char * const imx8mp_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext2" };
 
 static const char * const imx8mp_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext3" };
 
 static const char * const imx8mp_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext1" };
 
 static const char * const imx8mp_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext2" };
 
 static const char * const imx8mp_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext3" };
 
 static const char * const imx8mp_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
@@ -328,19 +328,19 @@ static const char * const imx8mp_ipp_do_clko1_sels[] = {"osc_24m", "sys_pll1_800
 
 static const char * const imx8mp_ipp_do_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m",
 							"sys_pll1_166m", "sys_pll3_out", "audio_pll1_out",
-							"video_pll1_out", "osc_32k" };
+							"video_pll_out", "osc_32k" };
 
 static const char * const imx8mp_hdmi_fdcc_tst_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
 							 "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
-							 "audio_pll2_out", "video_pll1_out", };
+							 "audio_pll2_out", "video_pll_out", };
 
 static const char * const imx8mp_hdmi_24m_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						    "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						    "sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						    "audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_hdmi_ref_266m_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out",
 							 "sys_pll2_333m", "sys_pll1_266m", "sys_pll2_200m",
-							 "audio_pll1_out", "video_pll1_out", };
+							 "audio_pll1_out", "video_pll_out", };
 
 static const char * const imx8mp_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
 						  "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
@@ -349,26 +349,26 @@ static const char * const imx8mp_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "s
 static const char * const imx8mp_media_cam1_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
 							  "sys_pll1_800m", "sys_pll2_1000m",
 							  "sys_pll3_out", "audio_pll2_out",
-							  "video_pll1_out", };
+							  "video_pll_out", };
 
 static const char * const imx8mp_media_mipi_phy1_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
 							       "sys_pll1_800m", "sys_pll2_1000m",
 							       "clk_ext2", "audio_pll2_out",
-							       "video_pll1_out", };
+							       "video_pll_out", };
 
-static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
+static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out",
 							   "audio_pll1_out", "sys_pll1_800m",
 							   "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
 static const char * const imx8mp_media_cam2_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
 							  "sys_pll1_800m", "sys_pll2_1000m",
 							  "sys_pll3_out", "audio_pll2_out",
-							  "video_pll1_out", };
+							  "video_pll_out", };
 
 static const char * const imx8mp_media_ldb_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
 						     "sys_pll1_800m", "sys_pll2_1000m",
 						     "clk_ext2", "audio_pll2_out",
-						     "video_pll1_out", };
+						     "video_pll_out", };
 
 static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
 							"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
@@ -392,12 +392,12 @@ static const char * const imx8mp_vpu_vc8000e_sels[] = {"osc_24m", "vpu_pll_out",
 						       "sys_pll3_out", "audio_pll1_out", };
 
 static const char * const imx8mp_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
 
 static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
 
-static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
 						  "dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
 						  "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
 						  "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
@@ -440,7 +440,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", anatop_base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", anatop_base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MP_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MP_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", anatop_base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", anatop_base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", anatop_base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
@@ -451,7 +451,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", anatop_base, &imx_1443x_pll);
 	hws[IMX8MP_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", anatop_base + 0x14, &imx_1443x_pll);
-	hws[IMX8MP_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
+	hws[IMX8MP_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
 	hws[IMX8MP_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", anatop_base + 0x50, &imx_1443x_dram_pll);
 	hws[IMX8MP_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", anatop_base + 0x64, &imx_1416x_pll);
 	hws[IMX8MP_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", anatop_base + 0x74, &imx_1416x_pll);
@@ -462,7 +462,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MP_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", anatop_base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
@@ -473,7 +473,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
 	hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
-	hws[IMX8MP_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", anatop_base + 0x28, 13);
+	hws[IMX8MP_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", anatop_base + 0x28, 13);
 	hws[IMX8MP_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", anatop_base + 0x50, 13);
 	hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
 	hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:40 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:40 +0100
Subject: [PATCH v5 05/20] dt-bindings: clock: imx8m-anatop: define clocks/clock-names
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-6-dario.binacchi@amarulasolutions.com>

Define clocks and clock-names properties of the anatop device node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 .../bindings/clock/fsl,imx8m-anatop.yaml      | 53 ++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml b/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
index bbd22e95b319..f439b0a94ce2 100644
--- a/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
+++ b/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
@@ -30,22 +30,73 @@ properties:
   interrupts:
     maxItems: 1
 
+  clocks:
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    minItems: 2
+    maxItems: 3
+
   '#clock-cells':
     const: 1
 
 required:
   - compatible
   - reg
+  - clocks
+  - clock-names
   - '#clock-cells'
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx8mq-anatop
+    then:
+      properties:
+        clocks:
+          items:
+            - description: 32k osc
+            - description: 25m osc
+            - description: 27m osc
+        clock-names:
+          items:
+            - const: ckil
+            - const: osc_25m
+            - const: osc_27m
+    else:
+      properties:
+        clocks:
+          items:
+            - description: 32k osc
+            - description: 24m osc
+
+        clock-names:
+          items:
+            - const: osc_32k
+            - const: osc_24m
+
 additionalProperties: false
 
 examples:
   - |
-    anatop: clock-controller at 30360000 {
+    clock-controller at 30360000 {
         compatible = "fsl,imx8mn-anatop", "fsl,imx8mm-anatop";
         reg = <0x30360000 0x10000>;
         #clock-cells = <1>;
+        clocks = <&osc_32k>, <&osc_24m>;
+        clock-names = "osc_32k", "osc_24m";
+    };
+
+  - |
+    clock-controller at 30360000 {
+        compatible = "fsl,imx8mq-anatop";
+        reg = <0x30360000 0x10000>;
+        #clock-cells = <1>;
+        clocks = <&ckil>, <&osc_25m>, <&osc_27m>;
+        clock-names = "ckil", "osc_25m", "osc_27m";
     };
 
 ...
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:41 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:41 +0100
Subject: [PATCH v5 06/20] arm64: dts: imx8mm: add anatop clocks
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-7-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Add the bindings definitions for the anatop node. The patch is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 4de3bf22902b..597041a05073 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -600,6 +600,8 @@ anatop: clock-controller at 30360000 {
 				compatible = "fsl,imx8mm-anatop";
 				reg = <0x30360000 0x10000>;
 				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>;
+				clock-names = "osc_32k", "osc_24m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:42 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:42 +0100
Subject: [PATCH v5 07/20] arm64: dts: imx8mn: add anatop clocks
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-8-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index a5f9cfb46e5d..49be492b5687 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -606,6 +606,8 @@ anatop: clock-controller at 30360000 {
 				compatible = "fsl,imx8mn-anatop", "fsl,imx8mm-anatop";
 				reg = <0x30360000 0x10000>;
 				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>;
+				clock-names = "osc_32k", "osc_24m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:43 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:43 +0100
Subject: [PATCH v5 08/20] arm64: dts: imx8mp: add anatop clocks
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-9-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index e0d3b8cba221..0b928e173f29 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -709,6 +709,8 @@ anatop: clock-controller at 30360000 {
 				compatible = "fsl,imx8mp-anatop", "fsl,imx8mm-anatop";
 				reg = <0x30360000 0x10000>;
 				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>;
+				clock-names = "osc_32k", "osc_24m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:44 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:44 +0100
Subject: [PATCH v5 09/20] arm64: dts: imx8mq: add anatop clocks
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-10-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index d51de8d899b2..1d1424a136f0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -817,6 +817,8 @@ anatop: clock-controller at 30360000 {
 				reg = <0x30360000 0x10000>;
 				interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
+				clocks = <&ckil>, <&osc_25m>, <&osc_27m>;
+				clock-names = "ckil", "osc_25m", "osc_27m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:45 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:45 +0100
Subject: [PATCH v5 10/20] dt-bindings: clock: imx8mm: add binding definitions for anatop
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-11-dario.binacchi@amarulasolutions.com>

Add the bindings definitions for the anatop node. The patch is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 include/dt-bindings/clock/imx8mm-clock.h | 66 ++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
index 102d8a6cdb55..1962b0a1e732 100644
--- a/include/dt-bindings/clock/imx8mm-clock.h
+++ b/include/dt-bindings/clock/imx8mm-clock.h
@@ -287,4 +287,70 @@
 
 #define IMX8MM_CLK_END				258
 
+#define IMX8MM_ANATOP_CLK_DUMMY			0
+#define IMX8MM_ANATOP_CLK_32K			1
+#define IMX8MM_ANATOP_CLK_24M			2
+#define IMX8MM_ANATOP_AUDIO_PLL1_REF_SEL	3
+#define IMX8MM_ANATOP_AUDIO_PLL2_REF_SEL	4
+#define IMX8MM_ANATOP_VIDEO_PLL_REF_SEL		5
+#define IMX8MM_ANATOP_DRAM_PLL_REF_SEL		6
+#define IMX8MM_ANATOP_GPU_PLL_REF_SEL		7
+#define IMX8MM_ANATOP_VPU_PLL_REF_SEL		8
+#define IMX8MM_ANATOP_ARM_PLL_REF_SEL		9
+#define IMX8MM_ANATOP_SYS_PLL3_REF_SEL		10
+#define IMX8MM_ANATOP_AUDIO_PLL1		11
+#define IMX8MM_ANATOP_AUDIO_PLL2		12
+#define IMX8MM_ANATOP_VIDEO_PLL			13
+#define IMX8MM_ANATOP_DRAM_PLL			14
+#define IMX8MM_ANATOP_GPU_PLL			15
+#define IMX8MM_ANATOP_VPU_PLL			16
+#define IMX8MM_ANATOP_ARM_PLL			17
+#define IMX8MM_ANATOP_SYS_PLL1			18
+#define IMX8MM_ANATOP_SYS_PLL2			19
+#define IMX8MM_ANATOP_SYS_PLL3			20
+#define IMX8MM_ANATOP_AUDIO_PLL1_BYPASS		21
+#define IMX8MM_ANATOP_AUDIO_PLL2_BYPASS		22
+#define IMX8MM_ANATOP_VIDEO_PLL_BYPASS		23
+#define IMX8MM_ANATOP_DRAM_PLL_BYPASS		24
+#define IMX8MM_ANATOP_GPU_PLL_BYPASS		25
+#define IMX8MM_ANATOP_VPU_PLL_BYPASS		26
+#define IMX8MM_ANATOP_ARM_PLL_BYPASS		27
+#define IMX8MM_ANATOP_SYS_PLL3_BYPASS		28
+#define IMX8MM_ANATOP_AUDIO_PLL1_OUT		29
+#define IMX8MM_ANATOP_AUDIO_PLL2_OUT		30
+#define IMX8MM_ANATOP_VIDEO_PLL_OUT		31
+#define IMX8MM_ANATOP_DRAM_PLL_OUT		32
+#define IMX8MM_ANATOP_GPU_PLL_OUT		33
+#define IMX8MM_ANATOP_VPU_PLL_OUT		34
+#define IMX8MM_ANATOP_ARM_PLL_OUT		35
+#define IMX8MM_ANATOP_SYS_PLL3_OUT		36
+#define IMX8MM_ANATOP_SYS_PLL1_OUT		37
+#define IMX8MM_ANATOP_SYS_PLL1_40M		38
+#define IMX8MM_ANATOP_SYS_PLL1_80M		39
+#define IMX8MM_ANATOP_SYS_PLL1_100M		40
+#define IMX8MM_ANATOP_SYS_PLL1_133M		41
+#define IMX8MM_ANATOP_SYS_PLL1_160M		42
+#define IMX8MM_ANATOP_SYS_PLL1_200M		43
+#define IMX8MM_ANATOP_SYS_PLL1_266M		44
+#define IMX8MM_ANATOP_SYS_PLL1_400M		45
+#define IMX8MM_ANATOP_SYS_PLL1_800M		46
+#define IMX8MM_ANATOP_SYS_PLL2_OUT		47
+#define IMX8MM_ANATOP_SYS_PLL2_50M		48
+#define IMX8MM_ANATOP_SYS_PLL2_100M		49
+#define IMX8MM_ANATOP_SYS_PLL2_125M		50
+#define IMX8MM_ANATOP_SYS_PLL2_166M		51
+#define IMX8MM_ANATOP_SYS_PLL2_200M		52
+#define IMX8MM_ANATOP_SYS_PLL2_250M		53
+#define IMX8MM_ANATOP_SYS_PLL2_333M		54
+#define IMX8MM_ANATOP_SYS_PLL2_500M		55
+#define IMX8MM_ANATOP_SYS_PLL2_1000M		56
+#define IMX8MM_ANATOP_CLK_CLKOUT1_SEL		57
+#define IMX8MM_ANATOP_CLK_CLKOUT1_DIV		58
+#define IMX8MM_ANATOP_CLK_CLKOUT1		59
+#define IMX8MM_ANATOP_CLK_CLKOUT2_SEL		60
+#define IMX8MM_ANATOP_CLK_CLKOUT2_DIV		61
+#define IMX8MM_ANATOP_CLK_CLKOUT2		62
+
+#define IMX8MM_ANATOP_CLK_END			63
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:46 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:46 +0100
Subject: [PATCH v5 11/20] dt-bindings: clock: imx8mn: add binding definitions for anatop
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-12-dario.binacchi@amarulasolutions.com>

Add the bindings definitions for the anatop node. The patch is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 include/dt-bindings/clock/imx8mn-clock.h | 67 ++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
index 04809edab33c..732ff87a16c2 100644
--- a/include/dt-bindings/clock/imx8mn-clock.h
+++ b/include/dt-bindings/clock/imx8mn-clock.h
@@ -267,4 +267,71 @@
 
 #define IMX8MN_CLK_END				235
 
+#define IMX8MN_ANATOP_CLK_DUMMY			0
+#define IMX8MN_ANATOP_CLK_32K			1
+#define IMX8MN_ANATOP_CLK_24M			2
+#define IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL	3
+#define IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL	4
+#define IMX8MN_ANATOP_VIDEO_PLL_REF_SEL		5
+#define IMX8MN_ANATOP_DRAM_PLL_REF_SEL		6
+#define IMX8MN_ANATOP_GPU_PLL_REF_SEL		7
+#define IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL	8
+#define IMX8MN_ANATOP_ARM_PLL_REF_SEL		9
+#define IMX8MN_ANATOP_SYS_PLL3_REF_SEL		10
+#define IMX8MN_ANATOP_AUDIO_PLL1		11
+#define IMX8MN_ANATOP_AUDIO_PLL2		12
+#define IMX8MN_ANATOP_VIDEO_PLL			13
+#define IMX8MN_ANATOP_DRAM_PLL			14
+#define IMX8MN_ANATOP_GPU_PLL			15
+#define IMX8MN_ANATOP_M7_ALT_PLL		16
+#define IMX8MN_ANATOP_ARM_PLL			17
+#define IMX8MN_ANATOP_SYS_PLL1			18
+#define IMX8MN_ANATOP_SYS_PLL2			19
+#define IMX8MN_ANATOP_SYS_PLL3			20
+#define IMX8MN_ANATOP_AUDIO_PLL1_BYPASS		21
+#define IMX8MN_ANATOP_AUDIO_PLL2_BYPASS		22
+#define IMX8MN_ANATOP_VIDEO_PLL_BYPASS		23
+#define IMX8MN_ANATOP_DRAM_PLL_BYPASS		24
+#define IMX8MN_ANATOP_GPU_PLL_BYPASS		25
+#define IMX8MN_ANATOP_M7_ALT_PLL_BYPASS		26
+#define IMX8MN_ANATOP_ARM_PLL_BYPASS		27
+#define IMX8MN_ANATOP_SYS_PLL3_BYPASS		28
+#define IMX8MN_ANATOP_AUDIO_PLL1_OUT		29
+#define IMX8MN_ANATOP_AUDIO_PLL2_OUT		30
+#define IMX8MN_ANATOP_VIDEO_PLL_OUT		31
+#define IMX8MN_ANATOP_DRAM_PLL_OUT		32
+#define IMX8MN_ANATOP_GPU_PLL_OUT		33
+#define IMX8MN_ANATOP_M7_ALT_PLL_OUT		34
+#define IMX8MN_ANATOP_ARM_PLL_OUT		35
+#define IMX8MN_ANATOP_SYS_PLL3_OUT		36
+#define IMX8MN_ANATOP_SYS_PLL1_OUT		37
+#define IMX8MN_ANATOP_SYS_PLL1_40M		38
+#define IMX8MN_ANATOP_SYS_PLL1_80M		39
+#define IMX8MN_ANATOP_SYS_PLL1_100M		40
+#define IMX8MN_ANATOP_SYS_PLL1_133M		41
+#define IMX8MN_ANATOP_SYS_PLL1_160M		42
+#define IMX8MN_ANATOP_SYS_PLL1_200M		43
+#define IMX8MN_ANATOP_SYS_PLL1_266M		44
+#define IMX8MN_ANATOP_SYS_PLL1_400M		45
+#define IMX8MN_ANATOP_SYS_PLL1_800M		46
+#define IMX8MN_ANATOP_SYS_PLL2_OUT		47
+#define IMX8MN_ANATOP_SYS_PLL2_50M		48
+#define IMX8MN_ANATOP_SYS_PLL2_100M		49
+#define IMX8MN_ANATOP_SYS_PLL2_125M		50
+#define IMX8MN_ANATOP_SYS_PLL2_166M		51
+#define IMX8MN_ANATOP_SYS_PLL2_200M		52
+#define IMX8MN_ANATOP_SYS_PLL2_250M		53
+#define IMX8MN_ANATOP_SYS_PLL2_333M		54
+#define IMX8MN_ANATOP_SYS_PLL2_500M		55
+#define IMX8MN_ANATOP_SYS_PLL2_1000M		56
+
+#define IMX8MN_ANATOP_CLK_CLKOUT1_SEL		57
+#define IMX8MN_ANATOP_CLK_CLKOUT1_DIV		58
+#define IMX8MN_ANATOP_CLK_CLKOUT1		59
+#define IMX8MN_ANATOP_CLK_CLKOUT2_SEL		60
+#define IMX8MN_ANATOP_CLK_CLKOUT2_DIV		61
+#define IMX8MN_ANATOP_CLK_CLKOUT2		62
+
+#define IMX8MN_ANATOP_CLK_END			63
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:47 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:47 +0100
Subject: [PATCH v5 12/20] dt-bindings: clock: imx8mp: add binding definitions for anatop
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-13-dario.binacchi@amarulasolutions.com>

Add the bindings definitions for the anatop node. The patch is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 include/dt-bindings/clock/imx8mp-clock.h | 70 ++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
index 3235d7de3b62..c2acba5d4555 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -402,4 +402,74 @@
 
 #define IMX8MP_CLK_AUDIOMIX_END			59
 
+#define IMX8MP_ANATOP_CLK_DUMMY			0
+#define IMX8MP_ANATOP_CLK_24M			1
+#define IMX8MP_ANATOP_CLK_32K			2
+#define IMX8MP_ANATOP_AUDIO_PLL1_REF_SEL	3
+#define IMX8MP_ANATOP_AUDIO_PLL2_REF_SEL	4
+#define IMX8MP_ANATOP_VIDEO_PLL_REF_SEL		5
+#define IMX8MP_ANATOP_DRAM_PLL_REF_SEL		6
+#define IMX8MP_ANATOP_GPU_PLL_REF_SEL		7
+#define IMX8MP_ANATOP_VPU_PLL_REF_SEL		8
+#define IMX8MP_ANATOP_ARM_PLL_REF_SEL		9
+#define IMX8MP_ANATOP_SYS_PLL1_REF_SEL		10
+#define IMX8MP_ANATOP_SYS_PLL2_REF_SEL		11
+#define IMX8MP_ANATOP_SYS_PLL3_REF_SEL		12
+#define IMX8MP_ANATOP_AUDIO_PLL1		13
+#define IMX8MP_ANATOP_AUDIO_PLL2		14
+#define IMX8MP_ANATOP_VIDEO_PLL			15
+#define IMX8MP_ANATOP_DRAM_PLL			16
+#define IMX8MP_ANATOP_GPU_PLL			17
+#define IMX8MP_ANATOP_VPU_PLL			18
+#define IMX8MP_ANATOP_ARM_PLL			19
+#define IMX8MP_ANATOP_SYS_PLL1			20
+#define IMX8MP_ANATOP_SYS_PLL2			21
+#define IMX8MP_ANATOP_SYS_PLL3			22
+#define IMX8MP_ANATOP_AUDIO_PLL1_BYPASS		23
+#define IMX8MP_ANATOP_AUDIO_PLL2_BYPASS		24
+#define IMX8MP_ANATOP_VIDEO_PLL_BYPASS		25
+#define IMX8MP_ANATOP_DRAM_PLL_BYPASS		26
+#define IMX8MP_ANATOP_GPU_PLL_BYPASS		27
+#define IMX8MP_ANATOP_VPU_PLL_BYPASS		28
+#define IMX8MP_ANATOP_ARM_PLL_BYPASS		29
+#define IMX8MP_ANATOP_SYS_PLL1_BYPASS		30
+#define IMX8MP_ANATOP_SYS_PLL2_BYPASS		31
+#define IMX8MP_ANATOP_SYS_PLL3_BYPASS		32
+#define IMX8MP_ANATOP_AUDIO_PLL1_OUT		33
+#define IMX8MP_ANATOP_AUDIO_PLL2_OUT		34
+#define IMX8MP_ANATOP_VIDEO_PLL_OUT		35
+#define IMX8MP_ANATOP_DRAM_PLL_OUT		36
+#define IMX8MP_ANATOP_GPU_PLL_OUT		37
+#define IMX8MP_ANATOP_VPU_PLL_OUT		38
+#define IMX8MP_ANATOP_ARM_PLL_OUT		39
+#define IMX8MP_ANATOP_SYS_PLL3_OUT		40
+#define IMX8MP_ANATOP_SYS_PLL1_OUT		41
+#define IMX8MP_ANATOP_SYS_PLL1_40M		42
+#define IMX8MP_ANATOP_SYS_PLL1_80M		43
+#define IMX8MP_ANATOP_SYS_PLL1_100M		44
+#define IMX8MP_ANATOP_SYS_PLL1_133M		45
+#define IMX8MP_ANATOP_SYS_PLL1_160M		46
+#define IMX8MP_ANATOP_SYS_PLL1_200M		47
+#define IMX8MP_ANATOP_SYS_PLL1_266M		48
+#define IMX8MP_ANATOP_SYS_PLL1_400M		49
+#define IMX8MP_ANATOP_SYS_PLL1_800M		50
+#define IMX8MP_ANATOP_SYS_PLL2_OUT		51
+#define IMX8MP_ANATOP_SYS_PLL2_50M		52
+#define IMX8MP_ANATOP_SYS_PLL2_100M		53
+#define IMX8MP_ANATOP_SYS_PLL2_125M		54
+#define IMX8MP_ANATOP_SYS_PLL2_166M		55
+#define IMX8MP_ANATOP_SYS_PLL2_200M		56
+#define IMX8MP_ANATOP_SYS_PLL2_250M		57
+#define IMX8MP_ANATOP_SYS_PLL2_333M		58
+#define IMX8MP_ANATOP_SYS_PLL2_500M		59
+#define IMX8MP_ANATOP_SYS_PLL2_1000M		60
+#define IMX8MP_ANATOP_CLK_CLKOUT1_SEL		61
+#define IMX8MP_ANATOP_CLK_CLKOUT1_DIV		62
+#define IMX8MP_ANATOP_CLK_CLKOUT1		63
+#define IMX8MP_ANATOP_CLK_CLKOUT2_SEL		64
+#define IMX8MP_ANATOP_CLK_CLKOUT2_DIV		65
+#define IMX8MP_ANATOP_CLK_CLKOUT2		66
+
+#define IMX8MP_ANATOP_CLK_END			67
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:48 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:48 +0100
Subject: [PATCH v5 13/20] clk: imx: add hw API imx8m_anatop_get_clk_hw
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-14-dario.binacchi@amarulasolutions.com>

Get the hw of a clock registered by the anatop module. This function is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v5:
- Consider CONFIG_CLK_IMX8M{M,N,P,Q}_MODULE to fix compilation errors

Changes in v4:
- New

 drivers/clk/imx/clk.c | 28 ++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h |  7 +++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
index df83bd939492..9a21f233e105 100644
--- a/drivers/clk/imx/clk.c
+++ b/drivers/clk/imx/clk.c
@@ -128,6 +128,34 @@ struct clk_hw *imx_get_clk_hw_by_name(struct device_node *np, const char *name)
 }
 EXPORT_SYMBOL_GPL(imx_get_clk_hw_by_name);
 
+#if defined(CONFIG_CLK_IMX8MM) || defined(CONFIG_CLK_IMX8MM_MODULE) || \
+	defined(CONFIG_CLK_IMX8MN) || defined(CONFIG_CLK_IMX8MN_MODULE) || \
+	defined(CONFIG_CLK_IMX8MP) || defined(CONFIG_CLK_IMX8MP_MODULE) || \
+	defined(CONFIG_CLK_IMX8MQ) || defined(CONFIG_CLK_IMX8MQ_MODULE)
+struct clk_hw *imx8m_anatop_get_clk_hw(int id)
+{
+#if defined(CONFIG_CLK_IMX8MQ) || defined(CONFIG_CLK_IMX8MQ_MODULE)
+	const char *compatible = "fsl,imx8mq-anatop";
+#else
+	const char *compatible = "fsl,imx8mm-anatop";
+#endif
+	struct device_node *np;
+	struct of_phandle_args args;
+	struct clk_hw *hw;
+
+	np = of_find_compatible_node(NULL, NULL, compatible);
+	args.np = np;
+	args.args_count = 1;
+	args.args[0] = id;
+	of_node_put(np);
+
+	hw = __clk_get_hw(of_clk_get_from_provider(&args));
+	pr_debug("%s: got clk: %s\n", __func__, clk_hw_get_name(hw));
+	return hw;
+}
+EXPORT_SYMBOL_GPL(imx8m_anatop_get_clk_hw);
+#endif
+
 /*
  * This fixups the register CCM_CSCMR1 write value.
  * The write/read/divider values of the aclk_podf field
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index aa5202f284f3..52055fda3058 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -487,4 +487,11 @@ struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible,
 			       u32 reg, const char **parent_names,
 			       u8 num_parents, const u32 *mux_table, u32 mask);
 
+#if defined(CONFIG_CLK_IMX8MM) || defined(CONFIG_CLK_IMX8MM_MODULE) || \
+	defined(CONFIG_CLK_IMX8MN) || defined(CONFIG_CLK_IMX8MN_MODULE) || \
+	defined(CONFIG_CLK_IMX8MP) || defined(CONFIG_CLK_IMX8MP_MODULE) || \
+	defined(CONFIG_CLK_IMX8MQ) || defined(CONFIG_CLK_IMX8MQ_MODULE)
+struct clk_hw *imx8m_anatop_get_clk_hw(int id);
+#endif
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:49 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:49 +0100
Subject: [PATCH v5 14/20] clk: imx: add support for i.MX8MN anatop clock driver
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-15-dario.binacchi@amarulasolutions.com>

Support NXP i.MX8M anatop PLL module which generates PLLs to CCM root.
By doing so, we also simplify the CCM driver code. The changes are
backward compatible.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 drivers/clk/imx/Makefile            |   2 +-
 drivers/clk/imx/clk-imx8mn-anatop.c | 281 ++++++++++++++++++++++++++++
 drivers/clk/imx/clk-imx8mn.c        | 175 ++++++++---------
 3 files changed, 355 insertions(+), 103 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx8mn-anatop.c

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 03f2b2a1ab63..f0f1d01c68f8 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -26,7 +26,7 @@ mxc-clk-objs += clk-gpr-mux.o
 obj-$(CONFIG_MXC_CLK) += mxc-clk.o
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
-obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
+obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn-anatop.o clk-imx8mn.o
 obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-imx8mp-audiomix.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 
diff --git a/drivers/clk/imx/clk-imx8mn-anatop.c b/drivers/clk/imx/clk-imx8mn-anatop.c
new file mode 100644
index 000000000000..9b1dcb904575
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mn-anatop.c
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * clk-imx8mn-anatop.c - NXP i.MX8MN anatop clock driver
+ *
+ * Copyright (c) 2022 Dario Binacchi <dario.binacchi at amarulasolutions.com>
+ */
+
+#include <dt-bindings/clock/imx8mn-clock.h>
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+
+#include "clk.h"
+
+static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
+static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", };
+static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
+					   "dummy", "dummy", "gpu_pll_out", "dummy",
+					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
+					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
+
+static struct clk_hw_onecell_data *clk_hw_data;
+static struct clk_hw **hws;
+
+static int imx8mn_anatop_clocks_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	void __iomem *base;
+	int ret;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base)) {
+		dev_err(dev, "failed to get base address\n");
+		return PTR_ERR(base);
+	}
+
+	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
+						    IMX8MN_ANATOP_CLK_END),
+				   GFP_KERNEL);
+	if (WARN_ON(!clk_hw_data))
+		return -ENOMEM;
+
+	clk_hw_data->num = IMX8MN_ANATOP_CLK_END;
+	hws = clk_hw_data->hws;
+
+	hws[IMX8MN_ANATOP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
+	hws[IMX8MN_ANATOP_CLK_32K] = imx_get_clk_hw_by_name(np, "osc_32k");
+	hws[IMX8MN_ANATOP_CLK_24M] = imx_get_clk_hw_by_name(np, "osc_24m");
+
+	hws[IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL] =
+		imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL] =
+		imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_VIDEO_PLL_REF_SEL] =
+		imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_DRAM_PLL_REF_SEL] =
+		imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_GPU_PLL_REF_SEL] =
+		imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL] =
+		imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_ARM_PLL_REF_SEL] =
+		imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_SYS_PLL3_REF_SEL] =
+		imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+	hws[IMX8MN_ANATOP_AUDIO_PLL1] =
+		imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel",
+				   base, &imx_1443x_pll);
+	hws[IMX8MN_ANATOP_AUDIO_PLL2] =
+		imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel",
+				   base + 0x14, &imx_1443x_pll);
+	hws[IMX8MN_ANATOP_VIDEO_PLL] =
+		imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel",
+				   base + 0x28, &imx_1443x_pll);
+	hws[IMX8MN_ANATOP_DRAM_PLL] =
+		imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50,
+				   &imx_1443x_dram_pll);
+	hws[IMX8MN_ANATOP_GPU_PLL] =
+		imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64,
+				   &imx_1416x_pll);
+	hws[IMX8MN_ANATOP_M7_ALT_PLL] =
+		imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel",
+				   base + 0x74, &imx_1416x_pll);
+	hws[IMX8MN_ANATOP_ARM_PLL] =
+		imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84,
+				   &imx_1416x_pll);
+	hws[IMX8MN_ANATOP_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
+	hws[IMX8MN_ANATOP_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
+	hws[IMX8MN_ANATOP_SYS_PLL3] =
+		imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114,
+				   &imx_1416x_pll);
+
+	/* PLL bypass out */
+	hws[IMX8MN_ANATOP_AUDIO_PLL1_BYPASS] =
+		imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1,
+				     audio_pll1_bypass_sels,
+				     ARRAY_SIZE(audio_pll1_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_AUDIO_PLL2_BYPASS] =
+		imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1,
+				     audio_pll2_bypass_sels,
+				     ARRAY_SIZE(audio_pll2_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_VIDEO_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1,
+				     video_pll_bypass_sels,
+				     ARRAY_SIZE(video_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_DRAM_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1,
+				     dram_pll_bypass_sels,
+				     ARRAY_SIZE(dram_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_GPU_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1,
+				     gpu_pll_bypass_sels,
+				     ARRAY_SIZE(gpu_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_M7_ALT_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1,
+				     m7_alt_pll_bypass_sels,
+				     ARRAY_SIZE(m7_alt_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_ARM_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1,
+				     arm_pll_bypass_sels,
+				     ARRAY_SIZE(arm_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_SYS_PLL3_BYPASS] =
+		imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1,
+				     sys_pll3_bypass_sels,
+				     ARRAY_SIZE(sys_pll3_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+
+	/* PLL out gate */
+	hws[IMX8MN_ANATOP_AUDIO_PLL1_OUT] =
+		imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass",
+				base, 13);
+	hws[IMX8MN_ANATOP_AUDIO_PLL2_OUT] =
+		imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass",
+				base + 0x14, 13);
+	hws[IMX8MN_ANATOP_VIDEO_PLL_OUT] =
+		imx_clk_hw_gate("video_pll_out", "video_pll_bypass",
+				base + 0x28, 13);
+	hws[IMX8MN_ANATOP_DRAM_PLL_OUT] =
+		imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass",
+				base + 0x50, 13);
+	hws[IMX8MN_ANATOP_GPU_PLL_OUT] =
+		imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass",
+				base + 0x64, 11);
+	hws[IMX8MN_ANATOP_M7_ALT_PLL_OUT] =
+		imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass",
+				base + 0x74, 11);
+	hws[IMX8MN_ANATOP_ARM_PLL_OUT] =
+		imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass",
+				base + 0x84, 11);
+	hws[IMX8MN_ANATOP_SYS_PLL3_OUT] =
+		imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass",
+				base + 0x114, 11);
+
+	/* SYS PLL1 fixed output */
+	hws[IMX8MN_ANATOP_SYS_PLL1_OUT] =
+		imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
+	hws[IMX8MN_ANATOP_SYS_PLL1_40M] =
+		imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
+	hws[IMX8MN_ANATOP_SYS_PLL1_80M] =
+		imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
+	hws[IMX8MN_ANATOP_SYS_PLL1_100M] =
+		imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
+	hws[IMX8MN_ANATOP_SYS_PLL1_133M] =
+		imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
+	hws[IMX8MN_ANATOP_SYS_PLL1_160M] =
+		imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
+	hws[IMX8MN_ANATOP_SYS_PLL1_200M] =
+		imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
+	hws[IMX8MN_ANATOP_SYS_PLL1_266M] =
+		imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
+	hws[IMX8MN_ANATOP_SYS_PLL1_400M] =
+		imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+	hws[IMX8MN_ANATOP_SYS_PLL1_800M] =
+		imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+
+	/* SYS PLL2 fixed output */
+	hws[IMX8MN_ANATOP_SYS_PLL2_OUT] =
+		imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
+	hws[IMX8MN_ANATOP_SYS_PLL2_50M] =
+		imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
+	hws[IMX8MN_ANATOP_SYS_PLL2_100M] =
+		imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
+	hws[IMX8MN_ANATOP_SYS_PLL2_125M] =
+		imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
+	hws[IMX8MN_ANATOP_SYS_PLL2_166M] =
+		imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
+	hws[IMX8MN_ANATOP_SYS_PLL2_200M] =
+		imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
+	hws[IMX8MN_ANATOP_SYS_PLL2_250M] =
+		imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
+	hws[IMX8MN_ANATOP_SYS_PLL2_333M] =
+		imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
+	hws[IMX8MN_ANATOP_SYS_PLL2_500M] =
+		imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+	hws[IMX8MN_ANATOP_SYS_PLL2_1000M] =
+		imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+
+	hws[IMX8MN_ANATOP_CLK_CLKOUT1_SEL] =
+		imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4,
+				clkout_sels, ARRAY_SIZE(clkout_sels));
+	hws[IMX8MN_ANATOP_CLK_CLKOUT1_DIV] =
+		imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128,
+				   0, 4);
+	hws[IMX8MN_ANATOP_CLK_CLKOUT1] =
+		imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8);
+	hws[IMX8MN_ANATOP_CLK_CLKOUT2_SEL] =
+		imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4,
+				clkout_sels, ARRAY_SIZE(clkout_sels));
+	hws[IMX8MN_ANATOP_CLK_CLKOUT2_DIV] =
+		imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128,
+				   16, 4);
+	hws[IMX8MN_ANATOP_CLK_CLKOUT2] =
+		imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24);
+
+	imx_check_clk_hws(hws, IMX8MN_ANATOP_CLK_END);
+
+	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+	if (ret < 0) {
+		imx_unregister_hw_clocks(hws, IMX8MN_ANATOP_CLK_END);
+		return dev_err_probe(dev, ret,
+				     "failed to register anatop clock provider\n");
+	}
+
+	dev_info(dev, "NXP i.MX8MN anatop clock driver probed\n");
+	return 0;
+}
+
+static const struct of_device_id imx8mn_anatop_clk_of_match[] = {
+	{ .compatible = "fsl,imx8mn-anatop" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx8mn_anatop_clk_of_match);
+
+static struct platform_driver imx8mn_anatop_clk_driver = {
+	.probe = imx8mn_anatop_clocks_probe,
+	.driver = {
+		.name = "imx8mn-anatop",
+		/*
+		 * Disable bind attributes: clocks are not removed and
+		 * reloading the driver will crash or break devices.
+		 */
+		.suppress_bind_attrs = true,
+		.of_match_table = imx8mn_anatop_clk_of_match,
+	},
+};
+
+module_platform_driver(imx8mn_anatop_clk_driver);
+
+MODULE_AUTHOR("Dario Binacchi <dario.binacchi at amarulasolutions.com>");
+MODULE_DESCRIPTION("NXP i.MX8MN anatop clock driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index ab77e148e70c..588cebce6c9d 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -24,16 +24,6 @@ static u32 share_count_disp;
 static u32 share_count_pdm;
 static u32 share_count_nand;
 
-static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
-static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
-static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
-static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
-static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
-static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
-static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", };
-static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
-static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
-
 static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m",
 					       "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
 					       "audio_pll1_out", "sys_pll3_out", };
@@ -308,11 +298,6 @@ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sy
 						 "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out",
 						 "video_pll_out", "osc_32k", };
 
-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
-					   "dummy", "dummy", "gpu_pll_out", "dummy",
-					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
-					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
-
 static struct clk_hw_onecell_data *clk_hw_data;
 static struct clk_hw **hws;
 
@@ -323,6 +308,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	void __iomem *base;
 	int ret;
 
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (WARN_ON(IS_ERR(base)))
+		return PTR_ERR(base);
+
 	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
 					  IMX8MN_CLK_END), GFP_KERNEL);
 	if (WARN_ON(!clk_hw_data))
@@ -331,99 +320,84 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	clk_hw_data->num = IMX8MN_CLK_END;
 	hws = clk_hw_data->hws;
 
-	hws[IMX8MN_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
-	hws[IMX8MN_CLK_24M] = imx_get_clk_hw_by_name(np, "osc_24m");
-	hws[IMX8MN_CLK_32K] = imx_get_clk_hw_by_name(np, "osc_32k");
+	hws[IMX8MN_CLK_DUMMY] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_DUMMY);
+	hws[IMX8MN_CLK_24M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_24M);
+	hws[IMX8MN_CLK_32K] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_32K);
 	hws[IMX8MN_CLK_EXT1] = imx_get_clk_hw_by_name(np, "clk_ext1");
 	hws[IMX8MN_CLK_EXT2] = imx_get_clk_hw_by_name(np, "clk_ext2");
 	hws[IMX8MN_CLK_EXT3] = imx_get_clk_hw_by_name(np, "clk_ext3");
 	hws[IMX8MN_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
-	base = devm_of_iomap(dev, np, 0, NULL);
-	of_node_put(np);
-	if (WARN_ON(IS_ERR(base))) {
-		ret = PTR_ERR(base);
-		goto unregister_hws;
-	}
-
-	hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-
-	hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
-	hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
-	hws[IMX8MN_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll);
-	hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
-	hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
-	hws[IMX8MN_M7_ALT_PLL] = imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel", base + 0x74, &imx_1416x_pll);
-	hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
-	hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
-	hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
-	hws[IMX8MN_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
+	hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL);
+	hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL);
+	hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_REF_SEL);
+	hws[IMX8MN_DRAM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_REF_SEL);
+	hws[IMX8MN_GPU_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_REF_SEL);
+	hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL);
+	hws[IMX8MN_ARM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_REF_SEL);
+	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_REF_SEL);
+
+	hws[IMX8MN_AUDIO_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1);
+	hws[IMX8MN_AUDIO_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2);
+	hws[IMX8MN_VIDEO_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL);
+	hws[IMX8MN_DRAM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL);
+	hws[IMX8MN_GPU_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL);
+	hws[IMX8MN_M7_ALT_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL);
+	hws[IMX8MN_ARM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL);
+	hws[IMX8MN_SYS_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1);
+	hws[IMX8MN_SYS_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2);
+	hws[IMX8MN_SYS_PLL3] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3);
 
 	/* PLL bypass out */
-	hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1, m7_alt_pll_bypass_sels, ARRAY_SIZE(m7_alt_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_BYPASS);
+	hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_BYPASS);
+	hws[IMX8MN_VIDEO_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_BYPASS);
+	hws[IMX8MN_DRAM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_BYPASS);
+	hws[IMX8MN_GPU_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_BYPASS);
+	hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_BYPASS);
+	hws[IMX8MN_ARM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_BYPASS);
+	hws[IMX8MN_SYS_PLL3_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_BYPASS);
 
 	/* PLL out gate */
-	hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
-	hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
-	hws[IMX8MN_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13);
-	hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
-	hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
-	hws[IMX8MN_M7_ALT_PLL_OUT] = imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass", base + 0x74, 11);
-	hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
-	hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
+	hws[IMX8MN_AUDIO_PLL1_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_OUT);
+	hws[IMX8MN_AUDIO_PLL2_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_OUT);
+	hws[IMX8MN_VIDEO_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_OUT);
+	hws[IMX8MN_DRAM_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_OUT);
+	hws[IMX8MN_GPU_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_OUT);
+	hws[IMX8MN_M7_ALT_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_OUT);
+	hws[IMX8MN_ARM_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_OUT);
+	hws[IMX8MN_SYS_PLL3_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_OUT);
 
 	/* SYS PLL1 fixed output */
-	hws[IMX8MN_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
-	hws[IMX8MN_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
-	hws[IMX8MN_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
-	hws[IMX8MN_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
-	hws[IMX8MN_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
-	hws[IMX8MN_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
-	hws[IMX8MN_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
-	hws[IMX8MN_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
-	hws[IMX8MN_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
-	hws[IMX8MN_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+	hws[IMX8MN_SYS_PLL1_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_OUT);
+	hws[IMX8MN_SYS_PLL1_40M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_40M);
+	hws[IMX8MN_SYS_PLL1_80M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_80M);
+	hws[IMX8MN_SYS_PLL1_100M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_100M);
+	hws[IMX8MN_SYS_PLL1_133M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_133M);
+	hws[IMX8MN_SYS_PLL1_160M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_160M);
+	hws[IMX8MN_SYS_PLL1_200M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_200M);
+	hws[IMX8MN_SYS_PLL1_266M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_266M);
+	hws[IMX8MN_SYS_PLL1_400M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_400M);
+	hws[IMX8MN_SYS_PLL1_800M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_800M);
 
 	/* SYS PLL2 fixed output */
-	hws[IMX8MN_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
-	hws[IMX8MN_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
-	hws[IMX8MN_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
-	hws[IMX8MN_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
-	hws[IMX8MN_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
-	hws[IMX8MN_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
-	hws[IMX8MN_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
-	hws[IMX8MN_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
-	hws[IMX8MN_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
-	hws[IMX8MN_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
-
-	hws[IMX8MN_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
-	hws[IMX8MN_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128, 0, 4);
-	hws[IMX8MN_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8);
-	hws[IMX8MN_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
-	hws[IMX8MN_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128, 16, 4);
-	hws[IMX8MN_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24);
-
-	np = dev->of_node;
-	base = devm_platform_ioremap_resource(pdev, 0);
-	if (WARN_ON(IS_ERR(base))) {
-		ret = PTR_ERR(base);
-		goto unregister_hws;
-	}
+	hws[IMX8MN_SYS_PLL2_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_OUT);
+	hws[IMX8MN_SYS_PLL2_50M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_50M);
+	hws[IMX8MN_SYS_PLL2_100M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_100M);
+	hws[IMX8MN_SYS_PLL2_125M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_125M);
+	hws[IMX8MN_SYS_PLL2_166M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_166M);
+	hws[IMX8MN_SYS_PLL2_200M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_200M);
+	hws[IMX8MN_SYS_PLL2_250M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_250M);
+	hws[IMX8MN_SYS_PLL2_333M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_333M);
+	hws[IMX8MN_SYS_PLL2_500M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_500M);
+	hws[IMX8MN_SYS_PLL2_1000M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_1000M);
+
+	hws[IMX8MN_CLK_CLKOUT1_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1_SEL);
+	hws[IMX8MN_CLK_CLKOUT1_DIV] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1_DIV);
+	hws[IMX8MN_CLK_CLKOUT1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1);
+	hws[IMX8MN_CLK_CLKOUT2_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2_SEL);
+	hws[IMX8MN_CLK_CLKOUT2_DIV] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2_DIV);
+	hws[IMX8MN_CLK_CLKOUT2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2);
 
 	/* CORE */
 	hws[IMX8MN_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mn_a53_sels, base + 0x8000);
@@ -599,18 +573,15 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 
 	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
 	if (ret < 0) {
-		dev_err(dev, "failed to register hws for i.MX8MN\n");
-		goto unregister_hws;
+		imx_unregister_hw_clocks(hws, IMX8MN_CLK_END);
+		return dev_err_probe(dev, ret,
+				     "failed to register hws for i.MX8MN\n");
 	}
 
 	imx_register_uart_clocks();
 
+	dev_info(dev, "NXP i.MX8MN ccm clock driver probed\n");
 	return 0;
-
-unregister_hws:
-	imx_unregister_hw_clocks(hws, IMX8MN_CLK_END);
-
-	return ret;
 }
 
 static const struct of_device_id imx8mn_clk_of_match[] = {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:50 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:50 +0100
Subject: [PATCH v5 15/20] dt-bindings: clock: imx8m-clock: support spread spectrum clocking
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-16-dario.binacchi@amarulasolutions.com>

The patch adds the DT bindings for enabling and tuning spread spectrum
clocking generation.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- Drop "fsl,ssc-clocks" property. The other added properties now refer
  to the clock list.
- Updated minItems and maxItems of
  - clocks
  - clock-names
  - fsl,ssc-modfreq-hz
  - fsl,ssc-modrate-percent
  - fsl,ssc-modmethod
- Updated the dts examples

Changes in v3:
- Added in v3
- The dt-bindings have been moved from fsl,imx8m-anatop.yaml to
  imx8m-clock.yaml. The anatop device (fsl,imx8m-anatop.yaml) is
  indeed more or less a syscon, so it represents a memory area
  accessible by ccm (imx8m-clock.yaml) to setup the PLLs.

Changes in v2:
- Add "allOf:" and place it after "required:" block, like in the
  example schema.
- Move the properties definition to the top-level.
- Drop unit types as requested by the "make dt_binding_check" command.

 .../bindings/clock/imx8m-clock.yaml           | 77 +++++++++++++++++--
 1 file changed, 71 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
index c643d4a81478..83036f6d2274 100644
--- a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
@@ -29,12 +29,12 @@ properties:
     maxItems: 2
 
   clocks:
-    minItems: 6
-    maxItems: 7
+    minItems: 7
+    maxItems: 10
 
   clock-names:
-    minItems: 6
-    maxItems: 7
+    minItems: 7
+    maxItems: 10
 
   '#clock-cells':
     const: 1
@@ -43,6 +43,34 @@ properties:
       ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8m-clock.h
       for the full list of i.MX8M clock IDs.
 
+  fsl,ssc-modfreq-hz:
+    description:
+      The values of modulation frequency (Hz unit) for each clock
+      supporting spread spectrum.
+    minItems: 7
+    maxItems: 10
+
+  fsl,ssc-modrate-percent:
+    description:
+      The percentage values of modulation rate for each clock
+      supporting spread spectrum.
+    minItems: 7
+    maxItems: 10
+
+  fsl,ssc-modmethod:
+    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+    description:
+      The modulation techniques for each clock supporting spread
+      spectrum.
+    minItems: 7
+    maxItems: 10
+    items:
+      enum:
+        - ""
+        - down-spread
+        - up-spread
+        - center-spread
+
 required:
   - compatible
   - reg
@@ -76,6 +104,10 @@ allOf:
             - const: clk_ext2
             - const: clk_ext3
             - const: clk_ext4
+        fsl,ssc-modfreq-hz: false
+        fsl,ssc-modrate-percent: false
+        fsl,ssc-modmethod: false
+
     else:
       properties:
         clocks:
@@ -86,6 +118,10 @@ allOf:
             - description: ext2 clock input
             - description: ext3 clock input
             - description: ext4 clock input
+            - description: audio1 PLL input
+            - description: audio2 PLL input
+            - description: dram PLL input
+            - description: video PLL input
 
         clock-names:
           items:
@@ -95,20 +131,49 @@ allOf:
             - const: clk_ext2
             - const: clk_ext3
             - const: clk_ext4
+            - const: audio_pll1
+            - const: audio_pll2
+            - const: dram_pll
+            - const: video_pll
 
 additionalProperties: false
 
 examples:
   # Clock Control Module node:
   - |
+    #include <dt-bindings/clock/imx8mm-clock.h>
+
     clock-controller at 30380000 {
         compatible = "fsl,imx8mm-ccm";
         reg = <0x30380000 0x10000>;
         #clock-cells = <1>;
         clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-                 <&clk_ext3>, <&clk_ext4>;
+                 <&clk_ext3>, <&clk_ext4>,
+                 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+                 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+                 <&anatop IMX8MM_ANATOP_DRAM_PLL>,
+                 <&anatop IMX8MM_ANATOP_VIDEO_PLL>;
         clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-                      "clk_ext3", "clk_ext4";
+                      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+                      "dram_pll", "video_pll";
+        fsl,ssc-modfreq-hz = <0>, <0>, <0>, <0>,
+                             <0>, <0>,
+                             <6818>,
+                             <0>,
+                             <0>,
+                             <2419>;
+        fsl,ssc-modrate-percent = <0>, <0>, <0>, <0>,
+                             <0>, <0>,
+                             <3>,
+                             <0>,
+                             <0>,
+                             <7>;
+        fsl,ssc-modmethod = "", "", "", "",
+                            "", "",
+                            "down-spread",
+                            "",
+                            "",
+                            "center-spread";
     };
 
   - |
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:51 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:51 +0100
Subject: [PATCH v5 16/20] arm64: dts: imx8mm: add PLLs to clock controller module (ccm)
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-17-dario.binacchi@amarulasolutions.com>

Add the PLLs generated by anatop to the clock list of the Clock
Controller Module (CCM) node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 597041a05073..0b35aecb6755 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -642,9 +642,14 @@ clk: clock-controller at 30380000 {
 					     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
 				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-					 <&clk_ext3>, <&clk_ext4>;
+					 <&clk_ext3>, <&clk_ext4>,
+					 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MM_ANATOP_DRAM_PLL>,
+					 <&anatop IMX8MM_ANATOP_VIDEO_PLL>;
 				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-					      "clk_ext3", "clk_ext4";
+					      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+					      "dram_pll", "video_pll";
 				assigned-clocks = <&clk IMX8MM_CLK_A53_SRC>,
 						<&clk IMX8MM_CLK_A53_CORE>,
 						<&clk IMX8MM_CLK_NOC>,
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:52 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:52 +0100
Subject: [PATCH v5 17/20] arm64: dts: imx8mn: add PLLs to clock controller module (ccm)
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-18-dario.binacchi@amarulasolutions.com>

Add the PLLs generated by anatop to the clock list of the Clock
Controller Module (CCM) node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index 49be492b5687..aaa179784717 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -643,9 +643,14 @@ clk: clock-controller at 30380000 {
 					     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
 				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-					 <&clk_ext3>, <&clk_ext4>;
+					 <&clk_ext3>, <&clk_ext4>,
+					 <&anatop IMX8MN_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MN_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MN_ANATOP_DRAM_PLL>,
+					 <&anatop IMX8MN_ANATOP_VIDEO_PLL>;
 				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-					      "clk_ext3", "clk_ext4";
+					      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+					      "dram_pll", "video_pll";
 				assigned-clocks = <&clk IMX8MN_CLK_A53_SRC>,
 						<&clk IMX8MN_CLK_A53_CORE>,
 						<&clk IMX8MN_CLK_NOC>,
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:53 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:53 +0100
Subject: [PATCH v5 18/20] arm64: dts: imx8mp: add PLLs to clock controller module (ccm)
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-19-dario.binacchi@amarulasolutions.com>

Add the PLLs generated by anatop to the clock list of the Clock
Controller Module (CCM) node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 0b928e173f29..861bd4f4dced 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -751,9 +751,14 @@ clk: clock-controller at 30380000 {
 					     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
 				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-					 <&clk_ext3>, <&clk_ext4>;
+					 <&clk_ext3>, <&clk_ext4>,
+					 <&anatop IMX8MP_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MP_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MP_ANATOP_DRAM_PLL>,
+					 <&anatop IMX8MP_ANATOP_VIDEO_PLL>;
 				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-					      "clk_ext3", "clk_ext4";
+					      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+					      "dram_pll", "video_pll";
 				assigned-clocks = <&clk IMX8MP_CLK_A53_SRC>,
 						  <&clk IMX8MP_CLK_A53_CORE>,
 						  <&clk IMX8MP_CLK_NOC>,
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:54 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:54 +0100
Subject: [PATCH v5 19/20] clk: imx: pll14xx: support spread spectrum clock generation
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-20-dario.binacchi@amarulasolutions.com>

Add support for spread spectrum clock (SSC) generation to the pll14xxx
driver.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
---

(no changes since v1)

 drivers/clk/imx/clk-pll14xx.c | 126 ++++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h         |  16 +++++
 2 files changed, 142 insertions(+)

diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index d63564dbb12c..1e66c3bb230d 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -20,6 +20,8 @@
 #define GNRL_CTL	0x0
 #define DIV_CTL0	0x4
 #define DIV_CTL1	0x8
+#define SSCG_CTRL	0xc
+
 #define LOCK_STATUS	BIT(31)
 #define LOCK_SEL_MASK	BIT(29)
 #define CLKE_MASK	BIT(11)
@@ -31,6 +33,10 @@
 #define KDIV_MASK	GENMASK(15, 0)
 #define KDIV_MIN	SHRT_MIN
 #define KDIV_MAX	SHRT_MAX
+#define SSCG_ENABLE	BIT(31)
+#define MFREQ_CTL_MASK	GENMASK(19, 12)
+#define MRAT_CTL_MASK	GENMASK(9, 4)
+#define SEL_PF_MASK	GENMASK(1, 0)
 
 #define LOCK_TIMEOUT_US		10000
 
@@ -40,6 +46,8 @@ struct clk_pll14xx {
 	enum imx_pll14xx_type		type;
 	const struct imx_pll14xx_rate_table *rate_table;
 	int rate_count;
+	bool                            ssc_enable;
+	struct imx_pll14xx_ssc		ssc_conf;
 };
 
 #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
@@ -347,6 +355,27 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
 	return 0;
 }
 
+static void clk_pll1443x_enable_ssc(struct clk_hw *hw, unsigned long parent_rate,
+				    unsigned int pdiv, unsigned int mdiv)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+	struct imx_pll14xx_ssc *conf = &pll->ssc_conf;
+	u32 sscg_ctrl, mfr, mrr;
+
+	sscg_ctrl = readl_relaxed(pll->base + SSCG_CTRL);
+	sscg_ctrl &=
+		~(SSCG_ENABLE | MFREQ_CTL_MASK | MRAT_CTL_MASK | SEL_PF_MASK);
+
+	mfr = parent_rate / (conf->mod_freq * pdiv * (1 << 5));
+	mrr = (conf->mod_rate * mdiv * (1 << 6)) / (100 * mfr);
+
+	sscg_ctrl |= SSCG_ENABLE | FIELD_PREP(MFREQ_CTL_MASK, mfr) |
+		FIELD_PREP(MRAT_CTL_MASK, mrr) |
+		FIELD_PREP(SEL_PF_MASK, conf->mod_type);
+
+	writel_relaxed(sscg_ctrl, pll->base + SSCG_CTRL);
+}
+
 static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 				 unsigned long prate)
 {
@@ -368,6 +397,9 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 		writel_relaxed(FIELD_PREP(KDIV_MASK, rate.kdiv),
 			       pll->base + DIV_CTL1);
 
+		if (pll->ssc_enable)
+			clk_pll1443x_enable_ssc(hw, prate, rate.pdiv, rate.mdiv);
+
 		return 0;
 	}
 
@@ -408,6 +440,9 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 	gnrl_ctl &= ~BYPASS_MASK;
 	writel_relaxed(gnrl_ctl, pll->base + GNRL_CTL);
 
+	if (pll->ssc_enable)
+		clk_pll1443x_enable_ssc(hw, prate, rate.pdiv, rate.mdiv);
+
 	return 0;
 }
 
@@ -542,3 +577,94 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
 	return hw;
 }
 EXPORT_SYMBOL_GPL(imx_dev_clk_hw_pll14xx);
+
+void imx_clk_pll14xx_enable_ssc(struct clk_hw *hw, struct imx_pll14xx_ssc *conf)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+
+	pll->ssc_enable = true;
+	memcpy(&pll->ssc_conf, conf, sizeof(pll->ssc_conf));
+}
+EXPORT_SYMBOL_GPL(imx_clk_pll14xx_enable_ssc);
+
+static int clk_pll14xx_ssc_mod_type(const char *name,
+				    enum imx_pll14xx_ssc_mod_type *mod_type)
+{
+	int i;
+	struct {
+		const char *name;
+		enum imx_pll14xx_ssc_mod_type id;
+	} mod_types[] = {
+		{ .name = "down-spread", .id = IMX_PLL14XX_SSC_DOWN_SPREAD },
+		{ .name = "up-spread", .id = IMX_PLL14XX_SSC_UP_SPREAD },
+		{ .name = "center-spread", .id = IMX_PLL14XX_SSC_CENTER_SPREAD }
+	};
+
+	pr_info("%s, name: %s\n", __func__, name);
+	for (i = 0; i < ARRAY_SIZE(mod_types); i++) {
+		if (!strcmp(name, mod_types[i].name)) {
+			*mod_type = mod_types[i].id;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+int imx_clk_pll14xx_ssc_parse_dt(struct device_node *np, const char *pll_name,
+				 struct imx_pll14xx_ssc *conf)
+{
+	int i, ret, num_clks;
+	const char *s;
+
+	if (!conf)
+		return -EINVAL;
+
+	ret = of_property_count_strings(np, "clock-names");
+	if (ret < 0)
+		return ret;
+
+	num_clks = ret;
+	for (i = 0; i < num_clks; i++) {
+		ret = of_property_read_string_index(np, "clock-names", i, &s);
+		if (strcmp(pll_name, s))
+			continue;
+
+		ret = of_property_read_u32_index(np, "fsl,ssc-modfreq-hz", i,
+						 &conf->mod_freq);
+		if (ret)
+			return ret;
+
+		ret = of_property_read_u32_index(np, "fsl,ssc-modrate-percent", i,
+						 &conf->mod_rate);
+		if (ret) {
+			pr_err("missing fsl,ssc-modrate-percent property for %pOFn\n",
+			       np);
+			return ret;
+		}
+
+		ret = of_property_read_string_index(np, "fsl,ssc-modmethod", i, &s);
+		if (ret) {
+			pr_err("failed to get fsl,ssc-modmethod property for %pOFn\n",
+			       np);
+			return ret;
+		}
+
+		if (strlen(s) == 0)
+			return -ENODEV;
+
+		ret = clk_pll14xx_ssc_mod_type(s, &conf->mod_type);
+		if (ret) {
+			pr_err("wrong fsl,ssc-modmethod property for %pOFn\n", np);
+			return ret;
+		}
+
+		pr_debug("%s: mod_freq: %d, mod_rate: %d: mod_method: %s [%d]\n",
+			 __func__, conf->mod_freq, conf->mod_rate, s, conf->mod_type);
+
+		return 0;
+	}
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(imx_clk_pll14xx_ssc_parse_dt);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 52055fda3058..edd28b78b115 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -69,6 +69,18 @@ struct imx_pll14xx_clk {
 	int flags;
 };
 
+enum imx_pll14xx_ssc_mod_type {
+	IMX_PLL14XX_SSC_DOWN_SPREAD,
+	IMX_PLL14XX_SSC_UP_SPREAD,
+	IMX_PLL14XX_SSC_CENTER_SPREAD,
+};
+
+struct imx_pll14xx_ssc {
+	unsigned int mod_freq;
+	unsigned int mod_rate;
+	enum imx_pll14xx_ssc_mod_type mod_type;
+};
+
 extern struct imx_pll14xx_clk imx_1416x_pll;
 extern struct imx_pll14xx_clk imx_1443x_pll;
 extern struct imx_pll14xx_clk imx_1443x_dram_pll;
@@ -494,4 +506,8 @@ struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible,
 struct clk_hw *imx8m_anatop_get_clk_hw(int id);
 #endif
 
+void imx_clk_pll14xx_enable_ssc(struct clk_hw *hw, struct imx_pll14xx_ssc *conf);
+int imx_clk_pll14xx_ssc_parse_dt(struct device_node *np, const char *pll_name,
+				 struct imx_pll14xx_ssc *conf);
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 03:17:55 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 12:17:55 +0100
Subject: [PATCH v5 20/20] clk: imx8mn: support spread spectrum clock generation
In-Reply-To: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241205111939.1796244-21-dario.binacchi@amarulasolutions.com>

Add support for spread spectrum clock generation for the audio, video,
and DRAM PLLs.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v1)

 drivers/clk/imx/clk-imx8mn.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 588cebce6c9d..c61368e724f7 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -306,6 +306,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	void __iomem *base;
+	struct imx_pll14xx_ssc ssc_conf;
 	int ret;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
@@ -338,9 +339,21 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_REF_SEL);
 
 	hws[IMX8MN_AUDIO_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "audio_pll1", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_AUDIO_PLL1], &ssc_conf);
+
 	hws[IMX8MN_AUDIO_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "audio_pll2", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_AUDIO_PLL2], &ssc_conf);
+
 	hws[IMX8MN_VIDEO_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "video_pll", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_VIDEO_PLL], &ssc_conf);
+
 	hws[IMX8MN_DRAM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "dram_pll", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_DRAM_PLL], &ssc_conf);
+
 	hws[IMX8MN_GPU_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL);
 	hws[IMX8MN_M7_ALT_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL);
 	hws[IMX8MN_ARM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL);
-- 
2.43.0



From matt.redfearn at blaize.com  Thu Dec  5 03:22:15 2024
From: matt.redfearn at blaize.com (Matt Redfearn)
Date: Thu, 5 Dec 2024 11:22:15 +0000
Subject: [PATCH v5 6/6] MAINTAINER: Add entry for Blaize SoC
In-Reply-To: <h5awakp52e6pxnnfrclhtlhhs3i66twvmqwlf5vmnfwk2xhbwr@marp6wti72ti>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
 <20241204-blaize-blzp1600_init_board_support-v5-6-b642bcc49307@blaize.com>
 <h5awakp52e6pxnnfrclhtlhhs3i66twvmqwlf5vmnfwk2xhbwr@marp6wti72ti>
Message-ID: <ac96f306-e5ea-4514-b25d-18b44777d3e6@blaize.com>


On 05/12/2024 08:16, Krzysztof Kozlowski wrote:
> On Wed, Dec 04, 2024 at 04:05:29PM +0000, Nikolaos Pasaloukos wrote:
>> Add MAINTAINERS entry for Blaize SoC platform with a list of
>> maintainers.
>>
>> Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
>> ---
>>   MAINTAINERS | 9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 273a84483b74543b510de7b08804bbd1f6514358..43846a23f9d990ae9fe066e65ed2bdd36376e327 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -2238,6 +2238,15 @@ F:	arch/arm64/boot/dts/bitmain/
>>   F:	drivers/clk/clk-bm1880.c
>>   F:	drivers/pinctrl/pinctrl-bm1880.c
>>   
>> +ARM/BLAIZE ARCHITECTURE
>> +M:	James Cowgill <james.cowgill at blaize.com>
>> +M:	Matt Redfearn <matt.redfearn at blaize.com>
>> +M:	Neil Jones <neil.jones at blaize.com>
>> +M:	Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
> Just to be clear: this is list of active maintainers, so all above are
> supposed to perform reviews or maintainer duties. This is not
> credits/managers/I-need-to-please-someone list.

Hi Krzysztof,

Yes, I will be an active maintainer of the board upstream.

>
> With the assumption these are active maintainers:
>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>
> They should also ack it to confirm they understand the burden.

Acked-by: Matt Redfearn <matt.redfearn at blaize.com>


A question about process: should Niko resend V5 with all of the acks?

Thanks,

Matt


>
> Best regards,
> Krzysztof
>


From dmitry.baryshkov at linaro.org  Thu Dec  5 03:30:02 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Dec 2024 13:30:02 +0200
Subject: [PATCH V4 4/5] soc: qcom: Introduce SCMI based Memlat (Memory
 Latency) governor
In-Reply-To: <1f5258f4-7c20-5343-dec6-0847449c821b@quicinc.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-5-quic_sibis@quicinc.com> <2aycrvnvivcrqctqmweadcgenwugafdr6ub3bzkscterpenz32@bzabln2hkral>
 <29eef87e-96f6-5105-6f7a-a8e01efcb4a3@quicinc.com> <k4lpzxtrq3x6riyv6etxiobn7nbpczf2bp3m4oc752nhjknlit@uo53kbppzim7>
 <ac655bdc-5ccf-c6c6-3203-659f1916c53c@quicinc.com> <34p27za5hcpubaxjuddsir2vqnqrvwyesnclu2cocvm3yhbv3r@ak7rcnp67gyd>
 <1f5258f4-7c20-5343-dec6-0847449c821b@quicinc.com>
Message-ID: <CAA8EJpoN3QSi72UUDV+=YkqySgXkiODUFJvwpBYfSmnkSotuZA@mail.gmail.com>

On Thu, 5 Dec 2024 at 12:53, Sibi Sankar <quic_sibis at quicinc.com> wrote:
>
>
>
> On 11/14/24 18:02, Dmitry Baryshkov wrote:
> > On Thu, Nov 14, 2024 at 09:43:53AM +0530, Sibi Sankar wrote:
> >>
> >>
> >> On 10/26/24 23:46, Dmitry Baryshkov wrote:
> >>> On Tue, Oct 22, 2024 at 01:48:25PM +0530, Sibi Sankar wrote:
> >>>>
> >>>>
> >>>> On 10/7/24 23:27, Dmitry Baryshkov wrote:
> >>>>> On Mon, Oct 07, 2024 at 11:40:22AM GMT, Sibi Sankar wrote:
> >
> >>>>>
> >>>>>> +};
> >>>>>> +
> >>>>>> +struct map_param_msg {
> >>>>>> +        u32 hw_type;
> >>>>>> +        u32 mon_idx;
> >>>>>> +        u32 nr_rows;
> >>>>>> +        struct map_table tbl[MAX_MAP_ENTRIES];
> >>>>>> +} __packed;
> >>>>>> +
> >>>>>> +struct node_msg {
> >>>>>> +        u32 cpumask;
> >>>>>> +        u32 hw_type;
> >>>>>> +        u32 mon_type;
> >>>>>> +        u32 mon_idx;
> >>>>>> +        char mon_name[MAX_NAME_LEN];
> >>>>>> +};
> >>>>>> +
> >>>>>> +struct scalar_param_msg {
> >>>>>> +        u32 hw_type;
> >>>>>> +        u32 mon_idx;
> >>>>>> +        u32 val;
> >>>>>> +};
> >>>>>> +
> >>>>>> +enum common_ev_idx {
> >>>>>> +        INST_IDX,
> >>>>>> +        CYC_IDX,
> >>>>>> +        CONST_CYC_IDX,
> >>>>>> +        FE_STALL_IDX,
> >>>>>> +        BE_STALL_IDX,
> >>>>>> +        NUM_COMMON_EVS
> >>>>>> +};
> >>>>>> +
> >>>>>> +enum grp_ev_idx {
> >>>>>> +        MISS_IDX,
> >>>>>> +        WB_IDX,
> >>>>>> +        ACC_IDX,
> >>>>>> +        NUM_GRP_EVS
> >>>>>> +};
> >>>>>> +
> >>>>>> +#define EV_CPU_CYCLES           0
> >>>>>> +#define EV_INST_RETIRED         2
> >>>>>> +#define EV_L2_D_RFILL           5
> >>>>>> +
> >>>>>> +struct ev_map_msg {
> >>>>>> +        u32 num_evs;
> >>>>>> +        u32 hw_type;
> >>>>>> +        u32 cid[NUM_COMMON_EVS];
> >>>>>> +};
> >>>>>> +
> >>>>>> +struct cpufreq_memfreq_map {
> >>>>>> +        unsigned int cpufreq_mhz;
> >>>>>> +        unsigned int memfreq_khz;
> >>>>>> +};
> >>>>>> +
> >>>>>> +struct scmi_monitor_info {
> >>>>>> +        struct cpufreq_memfreq_map *freq_map;
> >>>>>> +        char mon_name[MAX_NAME_LEN];
> >>>>>> +        u32 mon_idx;
> >>>>>> +        u32 mon_type;
> >>>>>> +        u32 ipm_ceil;
> >>>>>> +        u32 mask;
> >>>>>> +        u32 freq_map_len;
> >>>>>> +};
> >>>>>> +
> >>>>>> +struct scmi_memory_info {
> >>>>>> +        struct scmi_monitor_info *monitor[MAX_MONITOR_CNT];
> >>>>>> +        u32 hw_type;
> >>>>>> +        int monitor_cnt;
> >>>>>> +        u32 min_freq;
> >>>>>> +        u32 max_freq;
> >>>>>> +};
> >>>>>> +
> >>>>>> +struct scmi_memlat_info {
> >>>>>> +        struct scmi_protocol_handle *ph;
> >>>>>> +        const struct qcom_generic_ext_ops *ops;
> >>>>>> +        struct scmi_memory_info *memory[MAX_MEMORY_TYPES];
> >>>>>> +        u32 cluster_info[NR_CPUS];
> >>>>>> +        int memory_cnt;
> >>>>>> +};
> >>>>>> +
> >>>>>> +static int populate_cluster_info(u32 *cluster_info)
> >>>>>> +{
> >>>>>> +        char name[MAX_NAME_LEN];
> >>>>>> +        int i = 0;
> >>>>>> +
> >>>>>> +        struct device_node *cn __free(device_node) = of_find_node_by_path("/cpus");
> >>>>>> +        if (!cn)
> >>>>>> +                return -ENODEV;
> >>>>>> +
> >>>>>> +        struct device_node *map __free(device_node) = of_get_child_by_name(cn, "cpu-map");
> >>>>>> +        if (!map)
> >>>>>> +                return -ENODEV;
> >>>>>> +
> >>>>>> +        do {
> >>>>>> +                snprintf(name, sizeof(name), "cluster%d", i);
> >>>>>> +                struct device_node *c __free(device_node) = of_get_child_by_name(map, name);
> >>>>>> +                if (!c)
> >>>>>> +                        break;
> >>>>>> +
> >>>>>> +                *(cluster_info + i) = of_get_child_count(c);
> >>>>>> +                i++;
> >>>>>> +        } while (1);
> >>>>>
> >>>>> Can you use existing API from drivers/base/arch_topology.c? If not, can
> >>>>> it be extended to support your usecase?
> >>>>
> >>>> ack. But I'm pretty sure it's going to take a while for reaching such
> >>>> an agreement so I'll drop this feature during the next re-spin.
> >>>
> >>> Why? What kind of API do you actually need? The arch_topology.c simply
> >>> exports a table of struct cpu_topology. Is it somehow different from
> >>> what you are parsing manually?
> >>
> >> yup, we had to figure out the physical id of the cpu
> >> since cpus can be disabled by the bootloader using
> >> status = "failed" property and we have to pass this
> >> onto the cpucp memlat algorithm.
> >
> > Isn't it equal to the index in the cpu_topology table?
>
> from what I see cpu_topology indexes remain unpopulated
> for cpus that are disabled since get_cpu_for_node
> ignores those?

Why do you need cpu_topology for disabled aka non-existing CPU devices?

>
> >
> >>
> >>>
> >>>>
> >>>>>
> >>>>>> +
> >>>>>> +        return 0;
> >>>>>> +}
> >>>>>> +
> >>>>>> +static void populate_physical_mask(struct device_node *np, u32 *mask, u32 *cluster_info)
> >>>>>> +{
> >>>>>> +        struct device_node *dev_phandle __free(device_node);
> >>>>>> +        int cpu, i = 0, physical_id;
> >>>>>> +
> >>>>>> +        do {
> >>>>>> +                dev_phandle = of_parse_phandle(np, "cpus", i++);
> >>>>>> +                cpu = of_cpu_node_to_id(dev_phandle);
> >>>>>> +                if (cpu != -ENODEV) {
> >>>>>> +                        physical_id = topology_core_id(cpu);
> >>>>>> +                        for (int j = 0; j < topology_cluster_id(cpu); j++)
> >>>>>> +                                physical_id += *(cluster_info + j);
> >>>>>> +                        *mask |= BIT(physical_id);
> >>>>>> +                }
> >>>>>> +        } while (dev_phandle);
> >>>>>> +}
> >>>>>> +
> >>>>>> +static struct cpufreq_memfreq_map *init_cpufreq_memfreq_map(struct device *dev,
> >>>>>> +                                                            struct scmi_memory_info *memory,
> >>>>>> +                                                            struct device_node *of_node,
> >>>>>> +                                                            u32 *cnt)
> >>>>>> +{
> >>>>>> +        struct device_node *tbl_np __free(device_node), *opp_np __free(device_node);
> >>>>>> +        struct cpufreq_memfreq_map *tbl;
> >>>>>> +        int ret, i = 0;
> >>>>>> +        u32 level, len;
> >>>>>> +        u64 rate;
> >>>>>> +
> >>>>>> +        tbl_np = of_parse_phandle(of_node, "operating-points-v2", 0);
> >>>>>
> >>>>> Please use existing API to parse OPP tables or document a reason why it
> >>>>> can't be used.
> >>>>
> >>>> Thanks, I had them documented as opens in the coverletter. Dropped them
> >>>> since no one had any comments on it during V3. Will add them as comments
> >>>> to this driver instead.
> >>>>
> >>>> https://lore.kernel.org/lkml/20240702191440.2161623-1-quic_sibis at quicinc.com/
> >>>>
> >>>> re-copying things again:
> >>>> opp-tables are used but they don't get to be added to the scmi device
> >>>> (thus we rely on a lot of manual parsing) because the memlat client driver
> >>>> doesn't vote on these resources clocks/interconnects/power-domain
> >>>> from the kernel and some of the resources aren't modeled in the first
> >>>> place like DDR_QOS.
> >>>
> >>> As discussed offline, please consider extending the OPP to be able to
> >>> get the struct opp_table for the particular phandle. Another option
> >>> might be to change the memlat driver by having a separate device for
> >>> each monitor. This way you can use existing API to parse OPP tables and
> >>> to get necessary data from those tables.
> >>
> >> + Viresh
> >>
> >> Spoke with Viresh offline and he had stricter requirements
> >> than what you proposed. He definitely wanted the opp-tables
> >> to be assoiciated with devices at the very least and have
> >> all opp parsing logic within the opp-framework. Given that
> >> we have to model all these dummy devices just to add the
> >> tables I'll re-check the feasibility of movign the tables
> >> into the driver itself. Will move the patch series back
> >> into RFC and re-post just the vendor protocol since that's
> >> close to merge
> >
> > I don't think it's sensible to move the tables to the driver. Instead
> > adding a device per monitor sounds like a better idea.
>
> yeah, I would like to keep this in dt as well. But in order
> to be able to do that through the opp core we would need
> to put in a clock and interconnect paths so that the framework
> is able to add the table to the device.
> I should be able
> to list the scmi perf domain as the clock phandle but inorder
> to be able to convert the kbps values for the interconnect I
> would need to store the bus width and so on which is currently
> abstracted by the interconnect framework. Also in the future
> we may have to model dummy devices just to get the table parsed
> if the devices aren't modelled and controlled in the kernel.
> All of these seems to indicate that having the tables in the
> driver is a better alternative, lol.

Or fix the OPP API. I don't think that having monitor tables for the
SCMI-based platforms in the driver code is going to scale.

>
> -Sibi
>
> >
> >>>>>> +        if (!tbl_np)
> >>>>>> +                return ERR_PTR(-ENODEV);
> >>>>>> +
> >>>>>> +        len = min(of_get_available_child_count(tbl_np), MAX_MAP_ENTRIES);
> >>>>>> +        if (len == 0)
> >>>>>> +                return ERR_PTR(-ENODEV);
> >>>>>> +
> >>>>>> +        tbl = devm_kzalloc(dev, (len + 1) * sizeof(struct cpufreq_memfreq_map),
> >>>>>> +                           GFP_KERNEL);
> >>>>>> +        if (!tbl)
> >>>>>> +                return ERR_PTR(-ENOMEM);
> >>>>>> +
> >>>>>> +        for_each_available_child_of_node(tbl_np, opp_np) {
> >>>>>> +                ret = of_property_read_u64_index(opp_np, "opp-hz", 0, &rate);
> >>>>>> +                if (ret < 0)
> >>>>>> +                        return ERR_PTR(ret);
> >>>>>> +
> >>>>>> +                tbl[i].cpufreq_mhz = rate / HZ_PER_MHZ;
> >>>>>> +
> >>>>>> +                if (memory->hw_type != QCOM_MEM_TYPE_DDR_QOS) {
> >>>>>> +                        ret = of_property_read_u64_index(opp_np, "opp-hz", 1, &rate);
> >>>>>> +                        if (ret < 0)
> >>>>>> +                                return ERR_PTR(ret);
> >>>>>> +
> >>>>>> +                        tbl[i].memfreq_khz = rate / HZ_PER_KHZ;
> >>>>>> +                } else {
> >>>>>> +                        ret = of_property_read_u32(opp_np, "opp-level", &level);
> >>>>>> +                        if (ret < 0)
> >>>>>> +                                return ERR_PTR(ret);
> >>>>>> +
> >>>>>> +                        tbl[i].memfreq_khz = level;
> >>>>>> +                }
> >>>>>> +
> >>>>>> +                dev_dbg(dev, "Entry%d CPU:%u, Mem:%u\n", i, tbl[i].cpufreq_mhz, tbl[i].memfreq_khz);
> >>>>>> +                i++;
> >>>>>> +        }
> >>>>>> +        *cnt = len;
> >>>>>> +
> >>>>>> +        return tbl;
> >>>>>> +}
> >>>>>> +
> >>>>>> +static int process_scmi_memlat_of_node(struct scmi_device *sdev, struct scmi_memlat_info *info)
> >>>>>> +{
> >>>>>> +        struct scmi_monitor_info *monitor;
> >>>>>> +        struct scmi_memory_info *memory;
> >>>>>> +        char name[MAX_NAME_LEN];
> >>>>>> +        u64 memfreq[2];
> >>>>>> +        int ret;
> >>>>>> +
> >>>>>> +        ret = populate_cluster_info(info->cluster_info);
> >>>>>> +        if (ret < 0) {
> >>>>>> +                dev_err_probe(&sdev->dev, ret, "failed to populate cluster info\n");
> >>>>>> +                goto err;
> >>>>>> +        }
> >>>>>> +
> >>>>>> +        of_node_get(sdev->dev.of_node);
> >>>>>> +        do {
> >>>>>> +                snprintf(name, sizeof(name), "memory-%d", info->memory_cnt);
> >>>>>> +                struct device_node *memory_np __free(device_node) =
> >>>>>> +                        of_find_node_by_name(sdev->dev.of_node, name);
> >>>>>> +
> >>>>>> +                if (!memory_np)
> >>>>>> +                        break;
> >>>>>> +
> >>>>>> +                if (info->memory_cnt >= MAX_MEMORY_TYPES)
> >>>>>> +                        return dev_err_probe(&sdev->dev, -EINVAL,
> >>>>>> +                                             "failed to parse unsupported memory type\n");
> >>>>>> +
> >>>>>> +                memory = devm_kzalloc(&sdev->dev, sizeof(*memory), GFP_KERNEL);
> >>>>>> +                if (!memory) {
> >>>>>> +                        ret = -ENOMEM;
> >>>>>> +                        goto err;
> >>>>>> +                }
> >>>>>> +
> >>>>>> +                ret = of_property_read_u32(memory_np, "qcom,memory-type", &memory->hw_type);
> >>>>>> +                if (ret) {
> >>>>>> +                        dev_err_probe(&sdev->dev, ret, "failed to read memory type\n");
> >>>>>> +                        goto err;
> >>>>>> +                }
> >>>>>> +
> >>>>>> +                ret = of_property_read_u64_array(memory_np, "freq-table-hz", memfreq, 2);
> >>>>>> +                if (ret && (ret != -EINVAL)) {
> >>>>>> +                        dev_err_probe(&sdev->dev, ret, "failed to read min/max freq\n");
> >>>>>> +                        goto err;
> >>>>>> +                }
> >>>>>
> >>>>> Can we get this information from the OPP table instead?
> >>>>
> >>>> we don't list all the available ddr/llcc freqs in the opp-table
> >>>> so that we can keep the table constant across platforms.
> >>>
> >>> NO. Use opp-supported-hw to limit data to a particular platform. There
> >>> is no reason to keep min/max out of the OPP table.
> >>
> >> if we are movign the opp-tables into driver data for the reasons
> >> described above, this can probably stay?
> >
> > No. They duplicate the information that can be a part of the tables. It
> > doesn't matter if the tables are in the driver or in DT.
> >
> >



-- 
With best wishes
Dmitry


From heiko at sntech.de  Thu Dec  5 03:30:35 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 05 Dec 2024 12:30:35 +0100
Subject: [PATCH 1/6] dt-bindings: PCI: dwc: rockchip: Add rk3576 support
In-Reply-To: <20241205103623.878181-2-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
 <20241205103623.878181-2-kever.yang@rock-chips.com>
Message-ID: <49528886.MN2xkq1pzW@diego>

Am Donnerstag, 5. Dezember 2024, 11:36:18 CET schrieb Kever Yang:
> rk3576 is using the same controller as rk3568.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>

> ---
> 
>  Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml
> index 550d8a684af3..5328ccad7130 100644
> --- a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml
> +++ b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml
> @@ -26,6 +26,7 @@ properties:
>        - const: rockchip,rk3568-pcie
>        - items:
>            - enum:
> +              - rockchip,rk3576-pcie
>                - rockchip,rk3588-pcie
>            - const: rockchip,rk3568-pcie
>  
> 






From cristian.marussi at arm.com  Thu Dec  5 03:37:20 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Thu, 5 Dec 2024 11:37:20 +0000
Subject: [PATCH V5 1/2] firmware: arm_scmi: Add QCOM Generic Vendor
 Protocol documentation
In-Reply-To: <73a16eb4-e590-92db-ee24-cc4f42a9de01@quicinc.com>
References: <20241115011515.1313447-1-quic_sibis@quicinc.com>
 <20241115011515.1313447-2-quic_sibis@quicinc.com>
 <Z1BBirNWH1eaSKtr@pluto>
 <73a16eb4-e590-92db-ee24-cc4f42a9de01@quicinc.com>
Message-ID: <Z1GQcAHsmax4RtLb@pluto>

On Thu, Dec 05, 2024 at 04:37:28PM +0530, Sibi Sankar wrote:
> 
> 
> On 12/4/24 17:18, Cristian Marussi wrote:
> > On Fri, Nov 15, 2024 at 06:45:14AM +0530, Sibi Sankar wrote:
> > > Add QCOM System Control Management Interface (SCMI) Generic Vendor
> > > Extensions Protocol documentation.
> > > 
> > > Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
> > > ---
> > > 
> > > v4:
> > > * Update the protol attributes doc with more information. [Cristian]
> > > 
> > >   .../arm_scmi/vendors/qcom/qcom_generic.rst    | 211 ++++++++++++++++++
> > >   1 file changed, 211 insertions(+)
> > >   create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> > > 
> > > diff --git a/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> > > new file mode 100644
> > > index 000000000000..141bc932e30f
> > > --- /dev/null
> > > +++ b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> > > @@ -0,0 +1,211 @@
> > > +.. SPDX-License-Identifier: GPL-2.0
> > > +.. include:: <isonum.txt>
> > > +
> > > +===============================================================================
> > > +QCOM System Control and Management Interface(SCMI) Vendor Protocols Extension
> > > +===============================================================================
> > > +
> > > +:Copyright: |copy| 2024, Qualcomm Innovation Center, Inc. All rights reserved.
> > > +
> > > +:Author: Sibi Sankar <quic_sibis at quicinc.com>
> > > +
> > > +SCMI_GENERIC: System Control and Management Interface QCOM Generic Vendor Protocol
> > > +==================================================================================
> > > +
> > > +This protocol is intended as a generic way of exposing a number of Qualcomm
> > > +SoC specific features through a mixture of pre-determined algorithm string and
> > > +param_id pairs hosted on the SCMI controller. It implements an interface compliant
> > > +with the Arm SCMI Specification with additional vendor specific commands as
> > > +detailed below.
> > > +
> > > +Commands:
> > > +_________
> > > +
> > > +PROTOCOL_VERSION
> > > +~~~~~~~~~~~~~~~~
> > > +
> > > +message_id: 0x0
> > > +protocol_id: 0x80
> > > +
> > > ++---------------+--------------------------------------------------------------+
> > > +|Return values                                                                 |
> > > ++---------------+--------------------------------------------------------------+
> > > +|Name           |Description                                                   |
> > > ++---------------+--------------------------------------------------------------+
> > > +|int32 status   |See ARM SCMI Specification for status code definitions.       |
> > > ++---------------+--------------------------------------------------------------+
> > > +|uint32 version |For this revision of the specification, this value must be    |
> > > +|               |0x10000.                                                      |
> > > ++---------------+--------------------------------------------------------------+
> > > +
> > > +PROTOCOL_ATTRIBUTES
> > > +~~~~~~~~~~~~~~~~~~~
> > > +
> > > +message_id: 0x1
> > > +protocol_id: 0x80
> > > +
> > > ++---------------+--------------------------------------------------------------+
> > > +|Return values                                                                 |
> > > ++------------------+-----------------------------------------------------------+
> > > +|Name              |Description                                                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|int32 status      |See ARM SCMI Specification for status code definitions.    |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 attributes |Bits[31:16] Reserved, must be to 0.                        |
> > > +|                  |Bits[15:8] Number of agents in the system                  |
> > > +|                  |Bits[7:0] Number of vendor protocols in the system         |
> > > ++------------------+-----------------------------------------------------------+
> > 
> > Thanks of clarifing this....may I ask why number of agents is reported
> > here too given that it is already exposed by Base protocol ?
> > 
> > Not really arguing about this so much, but you will end up having to maintain this
> > on 2 different protocols fw side...or are they not 'agents' in the SCMI meaning ?
> > 
> > Anyway, I'm fine with it, even though you dont seem to use this
> > anywhere.
> 
> We don't use it anywhere and it looks like it was just put together
> so that this protocol is compliant to the spec :|
> 

mmm...you mean the vendor protocol is compliant with this vendor doc ?

...because while PROTOCOL_ATTRIBUTES(0x1) is a mandatory command for
each protocols (including vendors) there isn't any expectation from the spec to
expose such info like agents and vendors protos....it is expected to
expose attributes specific to the protocol itself...or nothing if you
dont need anything.
 
> > 
> > > +
> > > +PROTOCOL_MESSAGE_ATTRIBUTES
> > > +~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > +
> > > +message_id: 0x2
> > > +protocol_id: 0x80
> > > +
> > > ++---------------+--------------------------------------------------------------+
> > > +|Return values                                                                 |
> > > ++------------------+-----------------------------------------------------------+
> > > +|Name              |Description                                                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|int32 status      |See ARM SCMI Specification for status code definitions.    |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 attributes |For all message id's the parameter has a value of 0.       |
> > > ++------------------+-----------------------------------------------------------+
> > > +
> > > +QCOM_SCMI_SET_PARAM
> > > +~~~~~~~~~~~~~~~~~~~
> > > +
> > > +message_id: 0x10
> > > +protocol_id: 0x80
> > > +
> > > ++------------------+-----------------------------------------------------------+
> > > +|Parameters                                                                    |
> > > ++------------------+-----------------------------------------------------------+
> > > +|Name              |Description                                                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 ext_id     |Reserved, must be zero.                                    |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 algo_low   |Lower 32-bit value of the algorithm string.                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 algo_high  |Upper 32-bit value of the algorithm string.                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 param_id   |Serves as the token message id for the algorithm string    |
> > > +|                  |and is used to set various parameters supported by it.     |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 buf[]      |Serves as the payload for the specified param_id and       |
> > > +|                  |algorithm string pair.                                     |
> > > ++------------------+-----------------------------------------------------------+
> > > +|Return values                                                                 |
> > > ++------------------+-----------------------------------------------------------+
> > > +|Name              |Description                                                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|int32 status      |SUCCESS: if the param_id and buf[] is parsed successfully  |
> > > +|                  |by the chosen algorithm string.                            |
> > > +|                  |NOT_SUPPORTED: if the algorithm string does not have any   |
> > > +|                  |matches.                                                   |
> > > +|                  |INVALID_PARAMETERS: if the param_id and the buf[] passed   |
> > > +|                  |is rejected by the algorithm string.                       |
> > > ++------------------+-----------------------------------------------------------+
> > > +
> > > +QCOM_SCMI_GET_PARAM
> > > +~~~~~~~~~~~~~~~~~~~
> > > +
> > > +message_id: 0x11
> > > +protocol_id: 0x80
> > > +
> > > ++------------------+-----------------------------------------------------------+
> > > +|Parameters                                                                    |
> > > ++------------------+-----------------------------------------------------------+
> > > +|Name              |Description                                                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 ext_id     |Reserved, must be zero.                                    |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 algo_low   |Lower 32-bit value of the algorithm string.                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 algo_high  |Upper 32-bit value of the algorithm string.                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 param_id   |Serves as the token message id for the algorithm string.   |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 buf[]      |Serves as the payload and store of value for the specified |
> > > +|                  |param_id and algorithm string pair.                        |
> > > ++------------------+-----------------------------------------------------------+
> > > +|Return values                                                                 |
> > > ++------------------+-----------------------------------------------------------+
> > > +|Name              |Description                                                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|int32 status      |SUCCESS: if the param_id and buf[] is parsed successfully  |
> > > +|                  |by the chosen algorithm string and the result is copied    |
> > > +|                  |into buf[].                                                |
> > > +|                  |NOT_SUPPORTED: if the algorithm string does not have any   |
> > > +|                  |matches.                                                   |
> > > +|                  |INVALID_PARAMETERS: if the param_id and the buf[] passed   |
> > > +|                  |is rejected by the algorithm string.                       |
> > > ++------------------+-----------------------------------------------------------+
> > 
> > ..missed this last time...so you should add here also a field describing
> > the reply buf right ? (as it happenns really in your code) something
> > like:
> > 
> >   ++------------------+-----------------------------------------------------------+
> >   +|uint32 buf[]      |Holds the payload of the result of the query.	 	 |
> >   +|                  |					                         |
> >   ++------------------+-----------------------------------------------------------+
> 
> Thanks will get this added in the next re-spin.
>

Ok.

Thanks,
Cristian


From sudeep.holla at arm.com  Thu Dec  5 03:43:02 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu,  5 Dec 2024 11:43:02 +0000
Subject: [GIT PULL] arm64: dts: juno: Fixes for v6.13
Message-ID: <20241205114302.708433-1-sudeep.holla@arm.com>

Hi ARM SoC Team,

Please pull !

Regards,
Sudeep

-->8

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/juno-fix-6.13

for you to fetch changes up to 4f776d81bf927a4f25d5e32a4d0df08ee509dd6c:

  arm64: dts: fvp: Update PCIe bus-range property (2024-12-05 10:28:26 +0000)

----------------------------------------------------------------
Armv8 Juno fix for v6.13

Just a single fix updating the PCIe bus address range to accommodate
the full ECAM window of 256MB available on most of the recent versions
of RevC FVP models.

----------------------------------------------------------------
Aneesh Kumar K.V (Arm) (1):
      arm64: dts: fvp: Update PCIe bus-range property

 arch/arm64/boot/dts/arm/fvp-base-revc.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


From sudeep.holla at arm.com  Thu Dec  5 03:43:48 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu,  5 Dec 2024 11:43:48 +0000
Subject: [GIT PULL] firmware: arm_scmi: Fix for v6.13
Message-ID: <20241205114348.708618-1-sudeep.holla@arm.com>

Hi ARM SoC Team,

Please pull !

Regards,
Sudeep

-->8

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/scmi-fix-6.13

for you to fetch changes up to 514b2262ade48a0503ac6aa03c3bfb8c5be69b21:

  firmware: arm_scmi: Fix i.MX build dependency (2024-12-03 15:47:11 +0000)

----------------------------------------------------------------
Arm SCMI fix for v6.13

Fix for the build issue in the ASoC driver with the SCMI support by
enforcing the link-time dependency if IMX_SCMI_MISC_DRV is a loadable
module but not if that is disabled.

----------------------------------------------------------------
Arnd Bergmann (1):
      firmware: arm_scmi: Fix i.MX build dependency

 drivers/firmware/arm_scmi/vendors/imx/Kconfig | 1 +
 drivers/firmware/imx/Kconfig                  | 1 -
 sound/soc/fsl/Kconfig                         | 2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)


From sudeep.holla at arm.com  Thu Dec  5 03:44:06 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu,  5 Dec 2024 11:44:06 +0000
Subject: [GIT PULL] firmware: arm_ffa: Fixes for v6.13
Message-ID: <20241205114406.708710-1-sudeep.holla@arm.com>

Hi ARM SoC Team,

Please pull !

Regards,
Sudeep

-->8

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/ffa-fixes-6.13

for you to fetch changes up to 81c8b1c2ef7a75fa5f7f805fdb7f681bbbed07e5:

  firmware: arm_ffa: Drop le64_to_cpu() on UUID in ffa_msg_send_direct_req2() (2024-12-04 09:59:54 +0000)

----------------------------------------------------------------
Arm FF-A fixes for v6.13

Couple of fixes to address:

1. A possible race around setting ffa_dev->properties in ffa_device_register()
   by updating ffa_device_register() to take all the partition information
   received from the firmware and updating the struct ffa_device accordingly
   before registering the device to the bus/driver model in the kernel.

2. Incorrect endian conversion or byte swapping of the UUID by dropping
   le64_to_cpu() for uuid in ffa_msg_send_direct_req2(). This was added
   to fix the compiler warning but missed to get proper end-to-end testing
   as it was relatively new API.

----------------------------------------------------------------
Levi Yun (2):
      firmware: arm_ffa: Fix the race around setting ffa_dev->properties
      firmware: arm_ffa: Drop le64_to_cpu() on UUID in ffa_msg_send_direct_req2()

 drivers/firmware/arm_ffa/bus.c    | 15 +++++++++++----
 drivers/firmware/arm_ffa/driver.c | 13 ++++---------
 include/linux/arm_ffa.h           | 13 ++++++++-----
 3 files changed, 23 insertions(+), 18 deletions(-)


From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:02 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:02 +0100
Subject: [PATCH v2 00/15] Add support for MT8195/88 DPI, HDMIv2 and DDCv2
Message-ID: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>

Changes in v2:
 - Merged series "Add support for MT8195/8188 and Pattern Generator"
   and "drm/mediatek: Add support for HDMIv2 and DDCv2 IPs" in one
   as they are directly related, as requested by CK Hu
 - More commonization: moved some audio functions to mtk_hdmi_common
 - Fixed a bug in DDCv2 driver to allow sending a message with len=1
 - Renamed some functions in HDMIv2 to consistently use the prefix
   mtk_hdmi_v2_ across the driver
 - Added .mode_valid() callback to HDMIv2
 - Added .atomic_check() callback to HDMIv2
 - Reordered drm_bridge_funcs in HDMIv2 driver
 - Rewritten .edid_read() callback in HDMIv2 to move checking audio
   availability to bridge_pre_enable() stage, and to stop using the
   drm_edid_read_ddc() in favor of drm_edid_read()
 - Added support for API provided HDMI Helpers
 - Added .tmds_char_rate_valid() callback to HDMIv2 for HDMI helpers
 - Added .hdmi_{read,write}_infoframe() callback to HDMIv2 for helpers
 - Added support for Vendor infoframes in HDMIv2
 - Added missing audio-dai-cells to HDMIv2 binding to fix check error
 - Added more information to the HDMIv2 binding for clocks and PHY
 - Added some comments to the HDMIv2 code to clarify why the controller
   is preconfigured in bridge_pre_enable() instead of bridge_enable()
 - Added a mention of the differences in HPD between v1 and v2 to the
   commit introducing the v2 driver (v2 is not using CEC for HPD)
 - ...and tested again on HW! :-)


This series adds support for the HDMI-TX v2 Encoder and DDCv2, and for
the direct connection DPI as found in MT8195, MT8188 and their variants.

Tested on Genio 700 EVK:
 - ABIST ON: ok, pattern generated internally from HDMI is shown on
   HDMI screen at the correct resolution;
 - ABIST OFF + DPI Pattern Generator ON: ok, pattern coming from DPI is
   shown on HDMI screen at the correct resolution;
 - Can negotiate up to 4k60

and on MT8395 Radxa NIO 12L:
 - ABIST ON: ok, pattern generated internally from HDMI is shown on
   HDMI screen at the correct resolution;
 - ABIST OFF + DPI Pattern Generator ON: ok, pattern coming from DPI is
   shown on HDMI screen at the correct resolution;
 - Dual screen usecase validated (DSI + HDMI 3840x2160p 60Hz)
 - Can negotiate up to 4k60

Please note that this submission does *not* include support for HDCP
nor for CECv2, as I want this to be upstream before implementing
additional features which are not strictly required for simple
HDMI output.

Bonus in this series is the addition of support for the Pattern Generator
found in the DPI HW: since I needed this for debugging during development,
I had to code in the actual support bits and it looked like a waste of
time to just remove it.
I instead decided to clean it up and upstream it, as this will anyway come
handy for multiple things, of which the most important (imo) are:
 - Adding support for new SoCs in the future will be less time consuming
   as this driver already has the pattern generator in;
 - CI Testing might be able to make use of this to validate that the
   data that comes out is not garbled (so, to help testing display
   support in an automated manner).

AngeloGioacchino Del Regno (14):
  dt-bindings: display: mediatek: dpi: Add MT8195 and MT8188 compat
  drm/mediatek: mtk_dpi: Add support for Pattern Generator in debugfs
  drm/mediatek: mtk_dpi: Use an array for pixclk factor calculation
  drm/mediatek: mtk_dpi: Move pixel clock setting flow to function
  drm/mediatek: mtk_dpi: Add checks for reg_h_fre_con existence
  drm/mediatek: Add support for MT8195 Digital Parallel Interface
  dt-bindings: display: mediatek: Add binding for MT8195 HDMI-TX v2
  drm/mediatek: mtk_cec: Switch to register as module_platform_driver
  drm/mediatek: mtk_hdmi_ddc: Switch to register as
    module_platform_driver
  drm/mediatek: mtk_hdmi: Fix typo for aud_sampe_size member
  drm/mediatek: mtk_hdmi: Split driver and add common probe function
  drm/mediatek: mtk_hdmi_common: Assign DDC adapter pointer to bridge
  drm/mediatek: mtk_hdmi_common: Add OP_HDMI, vendor and product strings
  drm/mediatek: Introduce HDMI/DDC v2 for MT8195/MT8188

Guillaume Ranquet (1):
  drm/mediatek: hdmi: Use regmap instead of iomem for main registers

 .../display/mediatek/mediatek,dpi.yaml        |    5 +
 .../mediatek/mediatek,mt8195-hdmi.yaml        |  154 ++
 drivers/gpu/drm/mediatek/Kconfig              |   19 +-
 drivers/gpu/drm/mediatek/Makefile             |    5 +
 drivers/gpu/drm/mediatek/mtk_cec.c            |    5 +-
 drivers/gpu/drm/mediatek/mtk_dpi.c            |  311 +++-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   10 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    2 +
 drivers/gpu/drm/mediatek/mtk_hdmi.c           |  896 ++--------
 drivers/gpu/drm/mediatek/mtk_hdmi.h           |   14 -
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c    |  438 +++++
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h    |  204 +++
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c       |    4 +-
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c    |  403 +++++
 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h   |  263 +++
 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c        | 1488 +++++++++++++++++
 16 files changed, 3384 insertions(+), 837 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
 delete mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c

-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:03 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:03 +0100
Subject: [PATCH v2 01/15] dt-bindings: display: mediatek: dpi: Add MT8195 and MT8188 compat
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-2-angelogioacchino.delregno@collabora.com>

Add compatibles for the Digital Parallel Interface (DPI) block
found in the MT8195 and MT8188 SoCs: inside of the chip, this one
is directly connected to the HDMI block.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../devicetree/bindings/display/mediatek/mediatek,dpi.yaml   | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
index 0f1e556dc8ef..5670715efa5c 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
@@ -27,6 +27,7 @@ properties:
           - mediatek,mt8188-dp-intf
           - mediatek,mt8192-dpi
           - mediatek,mt8195-dp-intf
+          - mediatek,mt8195-dpi
       - items:
           - enum:
               - mediatek,mt6795-dpi
@@ -35,6 +36,10 @@ properties:
           - enum:
               - mediatek,mt8365-dpi
           - const: mediatek,mt8192-dpi
+      - items:
+          - enum:
+              - mediatek,mt8188-dpi
+          - const: mediatek,mt8195-dpi
 
   reg:
     maxItems: 1
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:04 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:04 +0100
Subject: [PATCH v2 02/15] drm/mediatek: mtk_dpi: Add support for Pattern Generator in debugfs
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-3-angelogioacchino.delregno@collabora.com>

This IP includes a Pattern Generator which is useful for debugging
and testing purposes: add the relevant register and bits to the
mtk_dpi_regs.h header, and implement support for it in mtk_dpi.

Adding this required to introduce a .debugfs_init() callback for
the DPI bridge, which creates a "dpi_test_pattern" file in the
directory of the appropriate connector.

The pattern generator can generate various internal patterns and
this submission includes support for:
 - 256 or 1024 shades of gray in a Vertical or Horizontal Pattern
 - Vertical Color Bars
 - Frame border
 - Dot Moire

This generator also supports filling the entire screen with one
custom color, but support for that is not included in this commit.

Enabling and disabling this generator can be done by sending a
string to the dpi_test_pattern debugfs file; the pattern is
expected to be formatted as follows:

         <enable (1) or disable (0)> <pattern number>

where the pattern number can be a number from 0 to 7, excluding 5.

Of course 5 is excluded because that activates custom color fill
which, again, is not supported in this commit.

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_dpi.c      | 107 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |   4 +
 2 files changed, 111 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 20a9d589fd75..c7143184e5de 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -6,6 +6,7 @@
 
 #include <linux/clk.h>
 #include <linux/component.h>
+#include <linux/debugfs.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/media-bus-format.h>
@@ -166,6 +167,18 @@ static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
 	writel(tmp, dpi->regs + offset);
 }
 
+static void mtk_dpi_test_pattern_en(struct mtk_dpi *dpi, u8 type, bool enable)
+{
+	u32 val;
+
+	if (enable)
+		val = FIELD_PREP(DPI_PAT_SEL, type) | DPI_PAT_EN;
+	else
+		val = 0;
+
+	mtk_dpi_mask(dpi, DPI_PATTERN0, val, DPI_PAT_SEL | DPI_PAT_EN);
+}
+
 static void mtk_dpi_sw_reset(struct mtk_dpi *dpi, bool reset)
 {
 	mtk_dpi_mask(dpi, DPI_RET, reset ? RST : 0, RST);
@@ -767,6 +780,99 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
 	return MODE_OK;
 }
 
+static int mtk_dpi_debug_tp_show(struct seq_file *m, void *arg)
+{
+	struct mtk_dpi *dpi = m->private;
+	bool en;
+	u32 val;
+
+	if (!dpi)
+		return -EINVAL;
+
+	val = readl(dpi->regs + DPI_PATTERN0);
+	en = val & DPI_PAT_EN;
+	val = FIELD_GET(DPI_PAT_SEL, val);
+
+	seq_printf(m, "DPI Test Pattern: %s\n", en ? "Enabled" : "Disabled");
+
+	if (en) {
+		seq_printf(m, "Internal pattern %d: ", val);
+		switch (val) {
+		case 0:
+			seq_puts(m, "256 Vertical Gray\n");
+			break;
+		case 1:
+			seq_puts(m, "1024 Vertical Gray\n");
+			break;
+		case 2:
+			seq_puts(m, "256 Horizontal Gray\n");
+			break;
+		case 3:
+			seq_puts(m, "1024 Horizontal Gray\n");
+			break;
+		case 4:
+			seq_puts(m, "Vertical Color bars\n");
+			break;
+		case 6:
+			seq_puts(m, "Frame border\n");
+			break;
+		case 7:
+			seq_puts(m, "Dot moire\n");
+			break;
+		default:
+			seq_puts(m, "Invalid selection\n");
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static ssize_t mtk_dpi_debug_tp_write(struct file *file, const char __user *ubuf,
+				      size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	u32 en, type;
+	char buf[6];
+
+	if (!m || !m->private || *offp || len > sizeof(buf) - 1)
+		return -EINVAL;
+
+	memset(buf, 0, sizeof(buf));
+	if (copy_from_user(buf, ubuf, len))
+		return -EFAULT;
+
+	if (sscanf(buf, "%u %u", &en, &type) != 2)
+		return -EINVAL;
+
+	if (en < 0 || en > 1 || type < 0 || type > 7)
+		return -EINVAL;
+
+	mtk_dpi_test_pattern_en((struct mtk_dpi *)m->private, type, en);
+	return len;
+}
+
+static int mtk_dpi_debug_tp_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mtk_dpi_debug_tp_show, inode->i_private);
+}
+
+static const struct file_operations mtk_dpi_debug_tp_fops = {
+	.owner = THIS_MODULE,
+	.open = mtk_dpi_debug_tp_open,
+	.read = seq_read,
+	.write = mtk_dpi_debug_tp_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static void mtk_dpi_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
+{
+	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
+
+	debugfs_create_file("dpi_test_pattern", 0640, root, dpi, &mtk_dpi_debug_tp_fops);
+}
+
 static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
 	.attach = mtk_dpi_bridge_attach,
 	.mode_set = mtk_dpi_bridge_mode_set,
@@ -779,6 +885,7 @@ static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
 	.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,
+	.debugfs_init = mtk_dpi_debugfs_init,
 };
 
 void mtk_dpi_start(struct device *dev)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 62bd4931b344..a0b1d18bbbf7 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -235,4 +235,8 @@
 #define MATRIX_SEL_RGB_TO_JPEG		0
 #define MATRIX_SEL_RGB_TO_BT601		2
 
+#define DPI_PATTERN0		0xf00
+#define DPI_PAT_EN			BIT(0)
+#define DPI_PAT_SEL			GENMASK(6, 4)
+
 #endif /* __MTK_DPI_REGS_H */
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:05 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:05 +0100
Subject: [PATCH v2 03/15] drm/mediatek: mtk_dpi: Use an array for pixclk factor calculation
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-4-angelogioacchino.delregno@collabora.com>

Setting the TVD PLL clock requires to multiply the target pixel
clock by a specific constant factor to achieve the target PLL
frequency, and this is done to reduce jitter to acceptable levels.

On all MediaTek SoCs, the factor is not retrieved by any real kind
of calculation but rather by checking if the target pixel clock
is less than a specified frequency, hence assigning a function
pointer for just a bunch of if branches does enlarge the code
size for little reason.

Remove all SoC-specific functions, add a structure `mtk_dpi_factor`
that holds a clock frequency and corresponding PLL factor, and
declare the constraints for each SoC in form of an array of said
structure.
Instead of function pointers, this structure (and its size) is then
assigned to each SoC's platform data.

The "calculation" is then performed with a new static function
mtk_dpi_calculate_factor(dpi, mode_clk) that iterates through all
of the entries of the aforementioned array and returns the right
factor.

If no factor is found, the lowest possible factor is returned,
mimicking the same flow as all of the old per-SoC calculation
functions.

This commit brings no functional change.

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_dpi.c | 103 +++++++++++++++--------------
 1 file changed, 52 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index c7143184e5de..9f59ee679ce1 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -117,9 +117,15 @@ struct mtk_dpi_yc_limit {
 	u16 c_bottom;
 };
 
+struct mtk_dpi_factor {
+	u32 clock;
+	u8 factor;
+};
+
 /**
  * struct mtk_dpi_conf - Configuration of mediatek dpi.
- * @cal_factor: Callback function to calculate factor value.
+ * @dpi_factor: SoC-specific pixel clock PLL factor values.
+ * @num_dpi_factor: Number of pixel clock PLL factor values.
  * @reg_h_fre_con: Register address of frequency control.
  * @max_clock_khz: Max clock frequency supported for this SoCs in khz units.
  * @edge_sel_en: Enable of edge selection.
@@ -140,7 +146,8 @@ struct mtk_dpi_yc_limit {
  * @edge_cfg_in_mmsys: If the edge configuration for DPI's output needs to be set in MMSYS.
  */
 struct mtk_dpi_conf {
-	unsigned int (*cal_factor)(int clock);
+	const struct mtk_dpi_factor *dpi_factor;
+	const u8 num_dpi_factor;
 	u32 reg_h_fre_con;
 	u32 max_clock_khz;
 	bool edge_sel_en;
@@ -515,6 +522,20 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return ret;
 }
 
+static unsigned int mtk_dpi_calculate_factor(struct mtk_dpi *dpi, int mode_clk)
+{
+	const struct mtk_dpi_factor *dpi_factor = dpi->conf->dpi_factor;
+	int i;
+
+	for (i = 0; i < dpi->conf->num_dpi_factor; i++) {
+		if (mode_clk <= dpi_factor[i].clock)
+			return dpi_factor[i].factor;
+	}
+
+	/* If no match try the lowest possible factor */
+	return dpi_factor[dpi->conf->num_dpi_factor - 1].factor;
+}
+
 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 				    struct drm_display_mode *mode)
 {
@@ -529,7 +550,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	unsigned int factor;
 
 	/* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
-	factor = dpi->conf->cal_factor(mode->clock);
+	factor = mtk_dpi_calculate_factor(dpi, mode_clk);
 	drm_display_mode_to_videomode(mode, &vm);
 	pll_rate = vm.pixelclock * factor;
 
@@ -964,48 +985,6 @@ static const struct component_ops mtk_dpi_component_ops = {
 	.unbind = mtk_dpi_unbind,
 };
 
-static unsigned int mt8173_calculate_factor(int clock)
-{
-	if (clock <= 27000)
-		return 3 << 4;
-	else if (clock <= 84000)
-		return 3 << 3;
-	else if (clock <= 167000)
-		return 3 << 2;
-	else
-		return 3 << 1;
-}
-
-static unsigned int mt2701_calculate_factor(int clock)
-{
-	if (clock <= 64000)
-		return 4;
-	else if (clock <= 128000)
-		return 2;
-	else
-		return 1;
-}
-
-static unsigned int mt8183_calculate_factor(int clock)
-{
-	if (clock <= 27000)
-		return 8;
-	else if (clock <= 167000)
-		return 4;
-	else
-		return 2;
-}
-
-static unsigned int mt8195_dpintf_calculate_factor(int clock)
-{
-	if (clock < 70000)
-		return 4;
-	else if (clock < 200000)
-		return 2;
-	else
-		return 1;
-}
-
 static const u32 mt8173_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -1020,8 +999,25 @@ static const u32 mt8195_output_fmts[] = {
 	MEDIA_BUS_FMT_YUYV8_1X16,
 };
 
+static const struct mtk_dpi_factor dpi_factor_mt2701[] = {
+	{ 64000, 4 }, { 128000, 2 }, { U32_MAX, 1 }
+};
+
+static const struct mtk_dpi_factor dpi_factor_mt8173[] = {
+	{ 27000, 48 }, { 84000, 24 }, { 167000, 12 }, { U32_MAX, 6 }
+};
+
+static const struct mtk_dpi_factor dpi_factor_mt8183[] = {
+	{ 27000, 8 }, { 167000, 4 }, { U32_MAX, 2 }
+};
+
+static const struct mtk_dpi_factor dpi_factor_mt8195_dp_intf[] = {
+	{ 70000 - 1, 4 }, { 200000 - 1, 2 }, { U32_MAX, 1 }
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
-	.cal_factor = mt8173_calculate_factor,
+	.dpi_factor = dpi_factor_mt8173,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8173),
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
@@ -1038,7 +1034,8 @@ static const struct mtk_dpi_conf mt8173_conf = {
 };
 
 static const struct mtk_dpi_conf mt2701_conf = {
-	.cal_factor = mt2701_calculate_factor,
+	.dpi_factor = dpi_factor_mt2701,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt2701),
 	.reg_h_fre_con = 0xb0,
 	.edge_sel_en = true,
 	.max_clock_khz = 150000,
@@ -1056,7 +1053,8 @@ static const struct mtk_dpi_conf mt2701_conf = {
 };
 
 static const struct mtk_dpi_conf mt8183_conf = {
-	.cal_factor = mt8183_calculate_factor,
+	.dpi_factor = dpi_factor_mt8183,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8183),
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
@@ -1073,7 +1071,8 @@ static const struct mtk_dpi_conf mt8183_conf = {
 };
 
 static const struct mtk_dpi_conf mt8186_conf = {
-	.cal_factor = mt8183_calculate_factor,
+	.dpi_factor = dpi_factor_mt8183,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8183),
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 150000,
 	.output_fmts = mt8183_output_fmts,
@@ -1091,7 +1090,8 @@ static const struct mtk_dpi_conf mt8186_conf = {
 };
 
 static const struct mtk_dpi_conf mt8192_conf = {
-	.cal_factor = mt8183_calculate_factor,
+	.dpi_factor = dpi_factor_mt8183,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8183),
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 150000,
 	.output_fmts = mt8183_output_fmts,
@@ -1108,7 +1108,8 @@ static const struct mtk_dpi_conf mt8192_conf = {
 };
 
 static const struct mtk_dpi_conf mt8195_dpintf_conf = {
-	.cal_factor = mt8195_dpintf_calculate_factor,
+	.dpi_factor = dpi_factor_mt8195_dp_intf,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8195_dp_intf),
 	.max_clock_khz = 600000,
 	.output_fmts = mt8195_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:06 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:06 +0100
Subject: [PATCH v2 04/15] drm/mediatek: mtk_dpi: Move pixel clock setting flow to function
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-5-angelogioacchino.delregno@collabora.com>

In preparation for adding support for the DPI IP found in MT8195
and in MT8188 used for HDMI, move the code flow for calculation
and setting of the DPI pixel clock to a separate function called
mtk_dpi_set_pixel_clk().

This was done because, on those platforms, the DPI instance that
is used for HDMI will get its pixel clock from the HDMI clock,
hence it is not necessary, nor desirable, to calculate or set
the pixel clock in DPI.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 9f59ee679ce1..378b49b6bdfb 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -536,26 +536,17 @@ static unsigned int mtk_dpi_calculate_factor(struct mtk_dpi *dpi, int mode_clk)
 	return dpi_factor[dpi->conf->num_dpi_factor - 1].factor;
 }
 
-static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
-				    struct drm_display_mode *mode)
+static void mtk_dpi_set_pixel_clk(struct mtk_dpi *dpi, struct videomode *vm, int mode_clk)
 {
-	struct mtk_dpi_polarities dpi_pol;
-	struct mtk_dpi_sync_param hsync;
-	struct mtk_dpi_sync_param vsync_lodd = { 0 };
-	struct mtk_dpi_sync_param vsync_leven = { 0 };
-	struct mtk_dpi_sync_param vsync_rodd = { 0 };
-	struct mtk_dpi_sync_param vsync_reven = { 0 };
-	struct videomode vm = { 0 };
 	unsigned long pll_rate;
 	unsigned int factor;
 
 	/* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
 	factor = mtk_dpi_calculate_factor(dpi, mode_clk);
-	drm_display_mode_to_videomode(mode, &vm);
-	pll_rate = vm.pixelclock * factor;
+	pll_rate = vm->pixelclock * factor;
 
 	dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
-		pll_rate, vm.pixelclock);
+		pll_rate, vm->pixelclock);
 
 	clk_set_rate(dpi->tvd_clk, pll_rate);
 	pll_rate = clk_get_rate(dpi->tvd_clk);
@@ -565,20 +556,34 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	 * pixels for each iteration: divide the clock by this number and
 	 * adjust the display porches accordingly.
 	 */
-	vm.pixelclock = pll_rate / factor;
-	vm.pixelclock /= dpi->conf->pixels_per_iter;
+	vm->pixelclock = pll_rate / factor;
+	vm->pixelclock /= dpi->conf->pixels_per_iter;
 
 	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
 	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
-		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
+		clk_set_rate(dpi->pixel_clk, vm->pixelclock * 2);
 	else
-		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
+		clk_set_rate(dpi->pixel_clk, vm->pixelclock);
 
-
-	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
+	vm->pixelclock = clk_get_rate(dpi->pixel_clk);
 
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
-		pll_rate, vm.pixelclock);
+		pll_rate, vm->pixelclock);
+}
+
+static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
+				    struct drm_display_mode *mode)
+{
+	struct mtk_dpi_polarities dpi_pol;
+	struct mtk_dpi_sync_param hsync;
+	struct mtk_dpi_sync_param vsync_lodd = { 0 };
+	struct mtk_dpi_sync_param vsync_leven = { 0 };
+	struct mtk_dpi_sync_param vsync_rodd = { 0 };
+	struct mtk_dpi_sync_param vsync_reven = { 0 };
+	struct videomode vm = { 0 };
+
+	drm_display_mode_to_videomode(mode, &vm);
+	mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
 
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:07 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:07 +0100
Subject: [PATCH v2 05/15] drm/mediatek: mtk_dpi: Add checks for reg_h_fre_con existence
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-6-angelogioacchino.delregno@collabora.com>

In preparation for adding support for newer DPI instances which
do support direct-pin but do not have any H_FRE_CON register,
like the one found in MT8195 and MT8188, add a branch to check
if the reg_h_fre_con variable was declared in the mtk_dpi_conf
structure for the probed SoC DPI version.

As a note, this is useful specifically only for cases in which
the support_direct_pin variable is true, so mt8195-dpintf is
not affected by any issue.

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_dpi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 378b49b6bdfb..79923d1bfbc9 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -430,12 +430,13 @@ static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
 
 static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi)
 {
-	mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N);
+	if (dpi->conf->reg_h_fre_con)
+		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N);
 }
 
 static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
 {
-	if (dpi->conf->edge_sel_en)
+	if (dpi->conf->edge_sel_en && dpi->conf->reg_h_fre_con)
 		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
 }
 
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:08 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:08 +0100
Subject: [PATCH v2 06/15] drm/mediatek: Add support for MT8195 Digital Parallel Interface
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-7-angelogioacchino.delregno@collabora.com>

Add support for the DPI block found in the MT8195 and MT8188 SoCs.
Inside of the SoC, this block is directly connected to the HDMI IP.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 55 ++++++++++++++++++++++---
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  6 +++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  2 +
 3 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 79923d1bfbc9..f76d1c5b68bd 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -144,6 +144,7 @@ struct mtk_dpi_factor {
  * @csc_enable_bit: Enable bit of CSC.
  * @pixels_per_iter: Quantity of transferred pixels per iteration.
  * @edge_cfg_in_mmsys: If the edge configuration for DPI's output needs to be set in MMSYS.
+ * @is_internal_hdmi: Specifies whether the DPI is internally connected to the HDMI block
  */
 struct mtk_dpi_conf {
 	const struct mtk_dpi_factor *dpi_factor;
@@ -164,6 +165,7 @@ struct mtk_dpi_conf {
 	u32 csc_enable_bit;
 	u32 pixels_per_iter;
 	bool edge_cfg_in_mmsys;
+	bool is_internal_hdmi;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -492,6 +494,7 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 
 	mtk_dpi_disable(dpi);
 	clk_disable_unprepare(dpi->pixel_clk);
+	clk_disable_unprepare(dpi->tvd_clk);
 	clk_disable_unprepare(dpi->engine_clk);
 }
 
@@ -508,6 +511,12 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 		goto err_refcount;
 	}
 
+	ret = clk_prepare_enable(dpi->tvd_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
+		goto err_engine;
+	}
+
 	ret = clk_prepare_enable(dpi->pixel_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
@@ -517,6 +526,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return 0;
 
 err_pixel:
+	clk_disable_unprepare(dpi->tvd_clk);
+err_engine:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
 	dpi->refcount--;
@@ -584,7 +595,9 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	struct videomode vm = { 0 };
 
 	drm_display_mode_to_videomode(mode, &vm);
-	mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
+
+	if (!dpi->conf->is_internal_hdmi)
+		mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
 
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
@@ -647,10 +660,18 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	if (dpi->conf->support_direct_pin) {
 		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 		mtk_dpi_config_2n_h_fre(dpi);
-		mtk_dpi_dual_edge(dpi);
+		/* DPI can connect to either an external bridge or the internal HDMI encoder */
+		if (dpi->conf->is_internal_hdmi) {
+			mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN, DPI_OUTPUT_1T1P_EN);
+			mtk_dpi_mask(dpi, DPI_CON,
+				     dpi->conf->input_2pixel ? DPI_INPUT_2P_EN : 0,
+				     DPI_INPUT_2P_EN);
+		} else {
+			mtk_dpi_dual_edge(dpi);
+		}
 		mtk_dpi_config_disable_edge(dpi);
 	}
-	if (dpi->conf->input_2pixel) {
+	if (dpi->conf->input_2pixel && !dpi->conf->is_internal_hdmi) {
 		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
 			     DPINTF_INPUT_2P_EN);
 	}
@@ -919,14 +940,16 @@ void mtk_dpi_start(struct device *dev)
 {
 	struct mtk_dpi *dpi = dev_get_drvdata(dev);
 
-	mtk_dpi_power_on(dpi);
+	if (!dpi->conf->is_internal_hdmi)
+		mtk_dpi_power_on(dpi);
 }
 
 void mtk_dpi_stop(struct device *dev)
 {
 	struct mtk_dpi *dpi = dev_get_drvdata(dev);
 
-	mtk_dpi_power_off(dpi);
+	if (!dpi->conf->is_internal_hdmi)
+		mtk_dpi_power_off(dpi);
 }
 
 unsigned int mtk_dpi_encoder_index(struct device *dev)
@@ -1021,6 +1044,8 @@ static const struct mtk_dpi_factor dpi_factor_mt8195_dp_intf[] = {
 	{ 70000 - 1, 4 }, { 200000 - 1, 2 }, { U32_MAX, 1 }
 };
 
+static const struct mtk_dpi_factor dpi_factor_mt8195_dpi = { U32_MAX, 1 };
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.dpi_factor = dpi_factor_mt8173,
 	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8173),
@@ -1113,6 +1138,25 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.csc_enable_bit = CSC_ENABLE,
 };
 
+static const struct mtk_dpi_conf mt8195_conf = {
+	.dpi_factor = &dpi_factor_mt8195_dpi,
+	.num_dpi_factor = 1,
+	.max_clock_khz = 594000,
+	.output_fmts = mt8183_output_fmts,
+	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.pixels_per_iter = 1,
+	.is_ck_de_pol = true,
+	.swap_input_support = true,
+	.support_direct_pin = true,
+	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
+	.is_internal_hdmi = true,
+	.input_2pixel = true,
+};
+
 static const struct mtk_dpi_conf mt8195_dpintf_conf = {
 	.dpi_factor = dpi_factor_mt8195_dp_intf,
 	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8195_dp_intf),
@@ -1216,6 +1260,7 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8188-dp-intf", .data = &mt8195_dpintf_conf },
 	{ .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf },
 	{ .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf },
+	{ .compatible = "mediatek,mt8195-dpi", .data = &mt8195_conf },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index a0b1d18bbbf7..3c24d9e9f241 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -40,6 +40,12 @@
 #define FAKE_DE_LEVEN			BIT(21)
 #define FAKE_DE_RODD			BIT(22)
 #define FAKE_DE_REVEN			BIT(23)
+
+/* DPI_CON: DPI instances */
+#define DPI_OUTPUT_1T1P_EN		BIT(24)
+#define DPI_INPUT_2P_EN			BIT(25)
+
+/* DPI_CON: DPINTF instances */
 #define DPINTF_YUV422_EN		BIT(24)
 #define DPINTF_CSC_ENABLE		BIT(26)
 #define DPINTF_INPUT_2P_EN		BIT(29)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 9a8ef8558da9..ba4539150f52 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -807,6 +807,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt8195-dp-intf",
 	  .data = (void *)MTK_DP_INTF },
+	{ .compatible = "mediatek,mt8195-dpi",
+	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt2701-dsi",
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8173-dsi",
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:09 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:09 +0100
Subject: [PATCH v2 07/15] dt-bindings: display: mediatek: Add binding for MT8195 HDMI-TX v2
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-8-angelogioacchino.delregno@collabora.com>

Add a binding for the HDMI TX v2 Encoder found in MediaTek MT8195
and MT8188 SoCs.

This fully supports the HDMI Specification 2.0b, hence it provides
support for 3D-HDMI, Polarity inversion, up to 16 bits Deep Color,
color spaces including RGB444, YCBCR420/422/444 (ITU601/ITU709) and
xvYCC, with output resolutions up to 3840x2160p at 60Hz.

Moreover, it also supports HDCP 1.4 and 2.3, Variable Refresh Rate
(VRR) and Consumer Electronics Control (CEC).

This IP also includes support for HDMI Audio, including IEC60958
and IEC61937 SPDIF, 8-channel PCM, DSD, and other lossless audio
according to HDMI 2.0.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../mediatek/mediatek,mt8195-hdmi.yaml        | 154 ++++++++++++++++++
 1 file changed, 154 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
new file mode 100644
index 000000000000..73b1dfaa1adb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
@@ -0,0 +1,154 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek HDMI-TX v2 Encoder
+
+maintainers:
+  - AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+  - CK Hu <ck.hu at mediatek.com>
+
+description:
+  The MediaTek HDMI-TX v2 encoder can generate HDMI format data based on
+  the HDMI Specification 2.0b.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8188-hdmi-tx
+      - mediatek,mt8195-hdmi-tx
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: HDMI Peripheral Bus (APB) clock
+      - description: HDCP and HDMI_TOP clock
+      - description: HDCP and HDMI_TOP reference clock
+      - description: VPP HDMI Split clock
+
+  clock-names:
+    items:
+      - const: bus
+      - const: hdcp
+      - const: hdcp24m
+      - const: hdmi-split
+
+  i2c:
+    type: object
+    $ref: /schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
+    unevaluatedProperties: false
+    description: HDMI DDC I2C controller
+
+  phys:
+    maxItems: 1
+    description: PHY providing clocking TMDS and pixel to controller
+
+  phy-names:
+    items:
+      - const: hdmi
+
+  pinctrl-0: true
+
+  pinctrl-names:
+    items:
+      - const: default
+
+  power-domains:
+    maxItems: 1
+
+  '#sound-dai-cells':
+    const: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Input port, usually connected to the output port of a DPI
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port that must be connected either to the input port of
+          a HDMI connector node containing a ddc-i2c-bus, or to the input
+          port of an attached bridge chip, such as a SlimPort transmitter.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - power-domains
+  - phys
+  - phy-names
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/mt8195-power.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        hdmi-tx at 1c300000 {
+            compatible = "mediatek,mt8195-hdmi-tx";
+            reg = <0 0x1c300000 0 0x1000>;
+            clocks = <&topckgen CLK_TOP_HDMI_APB>,
+                     <&topckgen CLK_TOP_HDCP>,
+                     <&topckgen CLK_TOP_HDCP_24M>,
+                     <&vppsys1 CLK_VPP1_VPP_SPLIT_HDMI>;
+            clock-names = "bus", "hdcp", "hdcp24m", "hdmi-split";
+            interrupts = <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH 0>;
+            phys = <&hdmi_phy>;
+            phy-names = "hdmi";
+            power-domains = <&spm MT8195_POWER_DOMAIN_HDMI_TX>;
+            pinctrl-names = "default";
+            pinctrl-0 = <&hdmi_pins>;
+            #sound-dai-cells = <1>;
+
+            hdmitx_ddc: i2c {
+                compatible = "mediatek,mt8195-hdmi-ddc";
+                clocks = <&clk26m>;
+            };
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port at 0 {
+                    reg = <0>;
+
+                    hdmi_in: endpoint {
+                        remote-endpoint = <&dpi1_out>;
+                    };
+                };
+
+                port at 1 {
+                    reg = <1>;
+
+                    hdmi_out: endpoint {
+                        remote-endpoint = <&hdmi_connector_in>;
+                    };
+                };
+            };
+        };
+    };
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:10 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:10 +0100
Subject: [PATCH v2 08/15] drm/mediatek: mtk_cec: Switch to register as module_platform_driver
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-9-angelogioacchino.delregno@collabora.com>

In preparation for splitting out the common bits from the HDMI
driver, change the mtk_cec driver from being registered from the
HDMI driver itself to be a module_platform_driver of its own.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_cec.c  | 5 ++++-
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 1 -
 drivers/gpu/drm/mediatek/mtk_hdmi.h | 1 -
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c
index 2de248443147..263ae3b4c4df 100644
--- a/drivers/gpu/drm/mediatek/mtk_cec.c
+++ b/drivers/gpu/drm/mediatek/mtk_cec.c
@@ -12,7 +12,6 @@
 #include <linux/platform_device.h>
 
 #include "mtk_cec.h"
-#include "mtk_hdmi.h"
 #include "mtk_drm_drv.h"
 
 #define TR_CONFIG		0x00
@@ -247,3 +246,7 @@ struct platform_driver mtk_cec_driver = {
 		.of_match_table = mtk_cec_of_ids,
 	},
 };
+module_platform_driver(mtk_cec_driver);
+
+MODULE_DESCRIPTION("MediaTek HDMI CEC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 7687f673964e..73ab88015d7f 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1805,7 +1805,6 @@ static struct platform_driver mtk_hdmi_driver = {
 
 static struct platform_driver * const mtk_hdmi_drivers[] = {
 	&mtk_hdmi_ddc_driver,
-	&mtk_cec_driver,
 	&mtk_hdmi_driver,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.h b/drivers/gpu/drm/mediatek/mtk_hdmi.h
index 472bf141c92b..e40bc4651995 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.h
@@ -8,7 +8,6 @@
 
 struct platform_driver;
 
-extern struct platform_driver mtk_cec_driver;
 extern struct platform_driver mtk_hdmi_ddc_driver;
 
 #endif /* _MTK_HDMI_CTRL_H */
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:14 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:14 +0100
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add common probe function
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>

In preparation for adding a new driver for the HDMI TX v2 IP,
split out the functions that will be common between the already
present mtk_hdmi (v1) driver and the new one.

Since the probe flow for both drivers is 90% similar, add a common
probe function that will be called from each driver's .probe()
callback, avoiding lots of code duplication.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/Kconfig           |  11 +-
 drivers/gpu/drm/mediatek/Makefile          |   1 +
 drivers/gpu/drm/mediatek/mtk_hdmi.c        | 724 +++------------------
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 425 ++++++++++++
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h | 203 ++++++
 5 files changed, 729 insertions(+), 635 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.h

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index f496e6cfdfe0..73459f07dae3 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -34,10 +34,19 @@ config DRM_MEDIATEK_DP
 	help
 	  DRM/KMS Display Port driver for MediaTek SoCs.
 
+config DRM_MEDIATEK_HDMI_COMMON
+	tristate
+	depends on DRM_MEDIATEK
+	select DRM_DISPLAY_HDMI_HELPER
+	select DRM_DISPLAY_HELPER
+	select SND_SOC_HDMI_CODEC if SND_SOC
+	help
+	  MediaTek SoC HDMI common library
+
 config DRM_MEDIATEK_HDMI
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
-	select SND_SOC_HDMI_CODEC if SND_SOC
+	select DRM_MEDIATEK_HDMI_COMMON
 	select PHY_MTK_HDMI
 	help
 	  DRM/KMS HDMI driver for Mediatek SoCs
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 32a2ed6c0cfe..8973d7ba37d3 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -25,6 +25,7 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
 			  mtk_hdmi.o \
 			  mtk_hdmi_ddc.o
 
+obj-$(CONFIG_DRM_MEDIATEK_HDMI_COMMON) += mtk_hdmi_common.o
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
 
 obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 7808141526fa..44b2bc55afa3 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -31,6 +31,7 @@
 #include <drm/drm_probe_helper.h>
 
 #include "mtk_cec.h"
+#include "mtk_hdmi_common.h"
 #include "mtk_hdmi_regs.h"
 
 #define NCTS_BYTES	7
@@ -43,149 +44,13 @@ enum mtk_hdmi_clk_id {
 	MTK_HDMI_CLK_COUNT
 };
 
-enum hdmi_aud_input_type {
-	HDMI_AUD_INPUT_I2S = 0,
-	HDMI_AUD_INPUT_SPDIF,
-};
-
-enum hdmi_aud_i2s_fmt {
-	HDMI_I2S_MODE_RJT_24BIT = 0,
-	HDMI_I2S_MODE_RJT_16BIT,
-	HDMI_I2S_MODE_LJT_24BIT,
-	HDMI_I2S_MODE_LJT_16BIT,
-	HDMI_I2S_MODE_I2S_24BIT,
-	HDMI_I2S_MODE_I2S_16BIT
-};
-
-enum hdmi_aud_mclk {
-	HDMI_AUD_MCLK_128FS,
-	HDMI_AUD_MCLK_192FS,
-	HDMI_AUD_MCLK_256FS,
-	HDMI_AUD_MCLK_384FS,
-	HDMI_AUD_MCLK_512FS,
-	HDMI_AUD_MCLK_768FS,
-	HDMI_AUD_MCLK_1152FS,
-};
-
-enum hdmi_aud_channel_type {
-	HDMI_AUD_CHAN_TYPE_1_0 = 0,
-	HDMI_AUD_CHAN_TYPE_1_1,
-	HDMI_AUD_CHAN_TYPE_2_0,
-	HDMI_AUD_CHAN_TYPE_2_1,
-	HDMI_AUD_CHAN_TYPE_3_0,
-	HDMI_AUD_CHAN_TYPE_3_1,
-	HDMI_AUD_CHAN_TYPE_4_0,
-	HDMI_AUD_CHAN_TYPE_4_1,
-	HDMI_AUD_CHAN_TYPE_5_0,
-	HDMI_AUD_CHAN_TYPE_5_1,
-	HDMI_AUD_CHAN_TYPE_6_0,
-	HDMI_AUD_CHAN_TYPE_6_1,
-	HDMI_AUD_CHAN_TYPE_7_0,
-	HDMI_AUD_CHAN_TYPE_7_1,
-	HDMI_AUD_CHAN_TYPE_3_0_LRS,
-	HDMI_AUD_CHAN_TYPE_3_1_LRS,
-	HDMI_AUD_CHAN_TYPE_4_0_CLRS,
-	HDMI_AUD_CHAN_TYPE_4_1_CLRS,
-	HDMI_AUD_CHAN_TYPE_6_1_CS,
-	HDMI_AUD_CHAN_TYPE_6_1_CH,
-	HDMI_AUD_CHAN_TYPE_6_1_OH,
-	HDMI_AUD_CHAN_TYPE_6_1_CHR,
-	HDMI_AUD_CHAN_TYPE_7_1_LH_RH,
-	HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR,
-	HDMI_AUD_CHAN_TYPE_7_1_LC_RC,
-	HDMI_AUD_CHAN_TYPE_7_1_LW_RW,
-	HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD,
-	HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS,
-	HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS,
-	HDMI_AUD_CHAN_TYPE_7_1_CS_CH,
-	HDMI_AUD_CHAN_TYPE_7_1_CS_OH,
-	HDMI_AUD_CHAN_TYPE_7_1_CS_CHR,
-	HDMI_AUD_CHAN_TYPE_7_1_CH_OH,
-	HDMI_AUD_CHAN_TYPE_7_1_CH_CHR,
-	HDMI_AUD_CHAN_TYPE_7_1_OH_CHR,
-	HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR,
-	HDMI_AUD_CHAN_TYPE_6_0_CS,
-	HDMI_AUD_CHAN_TYPE_6_0_CH,
-	HDMI_AUD_CHAN_TYPE_6_0_OH,
-	HDMI_AUD_CHAN_TYPE_6_0_CHR,
-	HDMI_AUD_CHAN_TYPE_7_0_LH_RH,
-	HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR,
-	HDMI_AUD_CHAN_TYPE_7_0_LC_RC,
-	HDMI_AUD_CHAN_TYPE_7_0_LW_RW,
-	HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD,
-	HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS,
-	HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS,
-	HDMI_AUD_CHAN_TYPE_7_0_CS_CH,
-	HDMI_AUD_CHAN_TYPE_7_0_CS_OH,
-	HDMI_AUD_CHAN_TYPE_7_0_CS_CHR,
-	HDMI_AUD_CHAN_TYPE_7_0_CH_OH,
-	HDMI_AUD_CHAN_TYPE_7_0_CH_CHR,
-	HDMI_AUD_CHAN_TYPE_7_0_OH_CHR,
-	HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR,
-	HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS,
-	HDMI_AUD_CHAN_TYPE_UNKNOWN = 0xFF
-};
-
-enum hdmi_aud_channel_swap_type {
-	HDMI_AUD_SWAP_LR,
-	HDMI_AUD_SWAP_LFE_CC,
-	HDMI_AUD_SWAP_LSRS,
-	HDMI_AUD_SWAP_RLS_RRS,
-	HDMI_AUD_SWAP_LR_STATUS,
-};
-
-struct hdmi_audio_param {
-	enum hdmi_audio_coding_type aud_codec;
-	enum hdmi_audio_sample_size aud_sample_size;
-	enum hdmi_aud_input_type aud_input_type;
-	enum hdmi_aud_i2s_fmt aud_i2s_fmt;
-	enum hdmi_aud_mclk aud_mclk;
-	enum hdmi_aud_channel_type aud_input_chan_type;
-	struct hdmi_codec_params codec_params;
-};
-
-struct mtk_hdmi_conf {
-	bool tz_disabled;
-	bool cea_modes_only;
-	unsigned long max_mode_clock;
-};
-
-struct mtk_hdmi {
-	struct drm_bridge bridge;
-	struct drm_bridge *next_bridge;
-	struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */
-	struct device *dev;
-	const struct mtk_hdmi_conf *conf;
-	struct phy *phy;
-	struct device *cec_dev;
-	struct i2c_adapter *ddc_adpt;
-	struct clk *clk[MTK_HDMI_CLK_COUNT];
-	struct drm_display_mode mode;
-	bool dvi_mode;
-	u32 min_clock;
-	u32 max_clock;
-	u32 max_hdisplay;
-	u32 max_vdisplay;
-	u32 ibias;
-	u32 ibias_up;
-	struct regmap *sys_regmap;
-	unsigned int sys_offset;
-	struct regmap *regs;
-	enum hdmi_colorspace csp;
-	struct hdmi_audio_param aud_param;
-	bool audio_enable;
-	bool powered;
-	bool enabled;
-	hdmi_codec_plugged_cb plugged_cb;
-	struct device *codec_dev;
-	struct mutex update_plugged_status_lock;
+const char * const mtk_hdmi_clk_names_v1[MTK_HDMI_CLK_COUNT] = {
+	[MTK_HDMI_CLK_HDMI_PIXEL] = "pixel",
+	[MTK_HDMI_CLK_HDMI_PLL] = "pll",
+	[MTK_HDMI_CLK_AUD_BCLK] = "bclk",
+	[MTK_HDMI_CLK_AUD_SPDIF] = "spdif",
 };
 
-static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
-{
-	return container_of(b, struct mtk_hdmi, bridge);
-}
-
 static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)
 {
 	regmap_update_bits(hdmi->regs, VIDEO_SOURCE_SEL,
@@ -606,81 +471,6 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
 	regmap_write(hdmi->regs, GRL_CFG5, val);
 }
 
-struct hdmi_acr_n {
-	unsigned int clock;
-	unsigned int n[3];
-};
-
-/* Recommended N values from HDMI specification, tables 7-1 to 7-3 */
-static const struct hdmi_acr_n hdmi_rec_n_table[] = {
-	/* Clock, N: 32kHz 44.1kHz 48kHz */
-	{  25175, {  4576,  7007,  6864 } },
-	{  74176, { 11648, 17836, 11648 } },
-	{ 148352, { 11648,  8918,  5824 } },
-	{ 296703, {  5824,  4459,  5824 } },
-	{ 297000, {  3072,  4704,  5120 } },
-	{      0, {  4096,  6272,  6144 } }, /* all other TMDS clocks */
-};
-
-/**
- * hdmi_recommended_n() - Return N value recommended by HDMI specification
- * @freq: audio sample rate in Hz
- * @clock: rounded TMDS clock in kHz
- */
-static unsigned int hdmi_recommended_n(unsigned int freq, unsigned int clock)
-{
-	const struct hdmi_acr_n *recommended;
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(hdmi_rec_n_table) - 1; i++) {
-		if (clock == hdmi_rec_n_table[i].clock)
-			break;
-	}
-	recommended = hdmi_rec_n_table + i;
-
-	switch (freq) {
-	case 32000:
-		return recommended->n[0];
-	case 44100:
-		return recommended->n[1];
-	case 48000:
-		return recommended->n[2];
-	case 88200:
-		return recommended->n[1] * 2;
-	case 96000:
-		return recommended->n[2] * 2;
-	case 176400:
-		return recommended->n[1] * 4;
-	case 192000:
-		return recommended->n[2] * 4;
-	default:
-		return (128 * freq) / 1000;
-	}
-}
-
-static unsigned int hdmi_mode_clock_to_hz(unsigned int clock)
-{
-	switch (clock) {
-	case 25175:
-		return 25174825;	/* 25.2/1.001 MHz */
-	case 74176:
-		return 74175824;	/* 74.25/1.001 MHz */
-	case 148352:
-		return 148351648;	/* 148.5/1.001 MHz */
-	case 296703:
-		return 296703297;	/* 297/1.001 MHz */
-	default:
-		return clock * 1000;
-	}
-}
-
-static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate,
-				      unsigned int tmds_clock, unsigned int n)
-{
-	return DIV_ROUND_CLOSEST_ULL((u64)hdmi_mode_clock_to_hz(tmds_clock) * n,
-				     128 * audio_sample_rate);
-}
-
 static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,
 				    unsigned int cts)
 {
@@ -710,9 +500,13 @@ static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
 				     unsigned int clock)
 {
 	unsigned int n, cts;
+	int ret;
 
-	n = hdmi_recommended_n(sample_rate, clock);
-	cts = hdmi_expected_cts(sample_rate, clock, n);
+	ret = mtk_hdmi_get_ncts(sample_rate, clock, &n, &cts);
+	if (ret) {
+		dev_err(hdmi->dev, "Invalid sample rate: %u\n", sample_rate);
+		return;
+	}
 
 	dev_dbg(hdmi->dev, "%s: sample_rate=%u, clock=%d, cts=%u, n=%u\n",
 		__func__, sample_rate, clock, n, cts);
@@ -829,7 +623,6 @@ static void mtk_hdmi_video_set_display_mode(struct mtk_hdmi *hdmi,
 	mtk_hdmi_hw_msic_setting(hdmi, mode);
 }
 
-
 static void mtk_hdmi_aud_set_input(struct mtk_hdmi *hdmi)
 {
 	enum hdmi_aud_channel_type chan_type;
@@ -920,53 +713,46 @@ static int mtk_hdmi_aud_output_config(struct mtk_hdmi *hdmi,
 	return 0;
 }
 
-static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi,
+static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, size_t bufsz,
 					struct drm_display_mode *mode)
 {
 	struct hdmi_avi_infoframe frame;
-	u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
 	ssize_t err;
 
-	err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
-						       hdmi->curr_conn, mode);
+	err = drm_hdmi_avi_infoframe_from_display_mode(&frame, hdmi->curr_conn, mode);
 	if (err < 0) {
 		dev_err(hdmi->dev,
 			"Failed to get AVI infoframe from mode: %zd\n", err);
 		return err;
 	}
 
-	err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
+	err = hdmi_avi_infoframe_pack(&frame, buffer, bufsz);
 	if (err < 0) {
 		dev_err(hdmi->dev, "Failed to pack AVI infoframe: %zd\n", err);
 		return err;
 	}
 
-	mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer));
 	return 0;
 }
 
-static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi,
-					const char *vendor,
-					const char *product)
+static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, size_t bufsz,
+					const char *vendor, const char *product)
 {
 	struct hdmi_spd_infoframe frame;
-	u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE];
 	ssize_t err;
 
 	err = hdmi_spd_infoframe_init(&frame, vendor, product);
 	if (err < 0) {
-		dev_err(hdmi->dev, "Failed to initialize SPD infoframe: %zd\n",
-			err);
+		dev_err(hdmi->dev, "Failed to initialize SPD infoframe: %zd\n", err);
 		return err;
 	}
 
-	err = hdmi_spd_infoframe_pack(&frame, buffer, sizeof(buffer));
+	err = hdmi_spd_infoframe_pack(&frame, buffer, bufsz);
 	if (err < 0) {
 		dev_err(hdmi->dev, "Failed to pack SDP infoframe: %zd\n", err);
 		return err;
 	}
 
-	mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer));
 	return 0;
 }
 
@@ -1026,19 +812,12 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi,
 	return 0;
 }
 
-static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
+static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, u8 *buffer_spd, size_t bufsz_spd,
+				    u8 *buffer_avi, size_t bufsz_avi,
+				    struct drm_display_mode *mode)
 {
-	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
-
-	hdmi->csp = HDMI_COLORSPACE_RGB;
-	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
-	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
-	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
-	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
-	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
-
-	return 0;
+	mtk_hdmi_setup_avi_infoframe(hdmi, buffer_avi, bufsz_avi, mode);
+	mtk_hdmi_setup_spd_infoframe(hdmi, buffer_spd, bufsz_spd, "mediatek", "On-chip HDMI");
 }
 
 static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)
@@ -1053,20 +832,6 @@ static void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi)
 	hdmi->audio_enable = false;
 }
 
-static int mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi,
-				    struct hdmi_audio_param *param)
-{
-	if (!hdmi->audio_enable) {
-		dev_err(hdmi->dev, "hdmi audio is in disable state!\n");
-		return -EINVAL;
-	}
-	dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",
-		param->aud_codec, param->aud_input_type,
-		param->aud_input_chan_type, param->codec_params.sample_rate);
-	memcpy(&hdmi->aud_param, param, sizeof(*param));
-	return mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);
-}
-
 static int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi,
 					    struct drm_display_mode *mode)
 {
@@ -1095,27 +860,6 @@ static int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi,
 	return 0;
 }
 
-static const char * const mtk_hdmi_clk_names[MTK_HDMI_CLK_COUNT] = {
-	[MTK_HDMI_CLK_HDMI_PIXEL] = "pixel",
-	[MTK_HDMI_CLK_HDMI_PLL] = "pll",
-	[MTK_HDMI_CLK_AUD_BCLK] = "bclk",
-	[MTK_HDMI_CLK_AUD_SPDIF] = "spdif",
-};
-
-static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi,
-				struct device_node *np)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(mtk_hdmi_clk_names); i++) {
-		hdmi->clk[i] = of_clk_get_by_name(np,
-						  mtk_hdmi_clk_names[i]);
-		if (IS_ERR(hdmi->clk[i]))
-			return PTR_ERR(hdmi->clk[i]);
-	}
-	return 0;
-}
-
 static int mtk_hdmi_clk_enable_audio(struct mtk_hdmi *hdmi)
 {
 	int ret;
@@ -1125,13 +869,12 @@ static int mtk_hdmi_clk_enable_audio(struct mtk_hdmi *hdmi)
 		return ret;
 
 	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]);
-	if (ret)
-		goto err;
+	if (ret) {
+		clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);
+		return ret;
+	}
 
 	return 0;
-err:
-	clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);
-	return ret;
 }
 
 static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi)
@@ -1143,10 +886,11 @@ static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi)
 static enum drm_connector_status
 mtk_hdmi_update_plugged_status(struct mtk_hdmi *hdmi)
 {
-	bool connected;
+	bool connected = true;
 
 	mutex_lock(&hdmi->update_plugged_status_lock);
-	connected = mtk_cec_hpd_high(hdmi->cec_dev);
+	if (hdmi->cec_dev)
+		connected = mtk_cec_hpd_high(hdmi->cec_dev);
 	if (hdmi->plugged_cb && hdmi->codec_dev)
 		hdmi->plugged_cb(hdmi->codec_dev, connected);
 	mutex_unlock(&hdmi->update_plugged_status_lock);
@@ -1254,18 +998,12 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge,
 			return ret;
 	}
 
-	mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, hdmi->dev);
+	if (hdmi->cec_dev)
+		mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, hdmi->dev);
 
 	return 0;
 }
 
-static bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
-				       const struct drm_display_mode *mode,
-				       struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
 static void mtk_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
 					   struct drm_bridge_state *old_bridge_state)
 {
@@ -1297,28 +1035,6 @@ static void mtk_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
 	hdmi->powered = false;
 }
 
-static void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode)
-{
-	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
-
-	dev_dbg(hdmi->dev, "cur info: name:%s, hdisplay:%d\n",
-		adjusted_mode->name, adjusted_mode->hdisplay);
-	dev_dbg(hdmi->dev, "hsync_start:%d,hsync_end:%d, htotal:%d",
-		adjusted_mode->hsync_start, adjusted_mode->hsync_end,
-		adjusted_mode->htotal);
-	dev_dbg(hdmi->dev, "hskew:%d, vdisplay:%d\n",
-		adjusted_mode->hskew, adjusted_mode->vdisplay);
-	dev_dbg(hdmi->dev, "vsync_start:%d, vsync_end:%d, vtotal:%d",
-		adjusted_mode->vsync_start, adjusted_mode->vsync_end,
-		adjusted_mode->vtotal);
-	dev_dbg(hdmi->dev, "vscan:%d, flag:%d\n",
-		adjusted_mode->vscan, adjusted_mode->flags);
-
-	drm_mode_copy(&hdmi->mode, adjusted_mode);
-}
-
 static void mtk_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
 					      struct drm_bridge_state *old_state)
 {
@@ -1330,21 +1046,13 @@ static void mtk_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
 	hdmi->powered = true;
 }
 
-static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi,
-				    struct drm_display_mode *mode)
-{
-	mtk_hdmi_setup_audio_infoframe(hdmi);
-	mtk_hdmi_setup_avi_infoframe(hdmi, mode);
-	mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI");
-	if (mode->flags & DRM_MODE_FLAG_3D_MASK)
-		mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode);
-}
-
 static void mtk_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
 					  struct drm_bridge_state *old_state)
 {
 	struct drm_atomic_state *state = old_state->base.state;
 	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+	u8 buffer_spd[HDMI_INFOFRAME_SIZE(SPD)];
+	u8 buffer_avi[HDMI_INFOFRAME_SIZE(AVI)];
 
 	/* Retrieve the connector through the atomic state. */
 	hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state,
@@ -1354,12 +1062,16 @@ static void mtk_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
 	clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]);
 	clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]);
 	phy_power_on(hdmi->phy);
-	mtk_hdmi_send_infoframe(hdmi, &hdmi->mode);
+	mtk_hdmi_setup_audio_infoframe(hdmi);
+	mtk_hdmi_send_infoframe(hdmi, buffer_spd, sizeof(buffer_spd),
+				buffer_avi, sizeof(buffer_avi), &hdmi->mode);
+	if (hdmi->mode.flags & DRM_MODE_FLAG_3D_MASK)
+		mtk_hdmi_setup_vendor_specific_infoframe(hdmi, &hdmi->mode);
 
 	hdmi->enabled = true;
 }
 
-static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = {
+const struct drm_bridge_funcs mtk_mt8183_hdmi_bridge_funcs = {
 	.mode_valid = mtk_hdmi_bridge_mode_valid,
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -1375,180 +1087,19 @@ static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = {
 	.edid_read = mtk_hdmi_bridge_edid_read,
 };
 
-static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
-				   struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
-	struct device_node *cec_np, *remote, *i2c_np;
-	struct platform_device *cec_pdev;
-	struct regmap *regmap;
-	int ret;
-
-	ret = mtk_hdmi_get_all_clk(hdmi, np);
-	if (ret) {
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get clocks: %d\n", ret);
-
-		return ret;
-	}
-
-	/* The CEC module handles HDMI hotplug detection */
-	cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
-	if (!cec_np) {
-		dev_err(dev, "Failed to find CEC node\n");
-		return -EINVAL;
-	}
-
-	cec_pdev = of_find_device_by_node(cec_np);
-	if (!cec_pdev) {
-		dev_err(hdmi->dev, "Waiting for CEC device %pOF\n",
-			cec_np);
-		of_node_put(cec_np);
-		return -EPROBE_DEFER;
-	}
-	of_node_put(cec_np);
-	hdmi->cec_dev = &cec_pdev->dev;
-
-	/*
-	 * The mediatek,syscon-hdmi property contains a phandle link to the
-	 * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG
-	 * registers it contains.
-	 */
-	regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");
-	ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1,
-					 &hdmi->sys_offset);
-	if (IS_ERR(regmap))
-		ret = PTR_ERR(regmap);
-	if (ret) {
-		dev_err(dev,
-			"Failed to get system configuration registers: %d\n",
-			ret);
-		goto put_device;
-	}
-	hdmi->sys_regmap = regmap;
-
-	hdmi->regs = device_node_to_regmap(dev->of_node);
-	if (IS_ERR(hdmi->regs)) {
-		ret = PTR_ERR(hdmi->regs);
-		goto put_device;
-	}
-
-	remote = of_graph_get_remote_node(np, 1, 0);
-	if (!remote) {
-		ret = -EINVAL;
-		goto put_device;
-	}
-
-	if (!of_device_is_compatible(remote, "hdmi-connector")) {
-		hdmi->next_bridge = of_drm_find_bridge(remote);
-		if (!hdmi->next_bridge) {
-			dev_err(dev, "Waiting for external bridge\n");
-			of_node_put(remote);
-			ret = -EPROBE_DEFER;
-			goto put_device;
-		}
-	}
-
-	i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
-	if (!i2c_np) {
-		dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n",
-			remote);
-		of_node_put(remote);
-		ret = -EINVAL;
-		goto put_device;
-	}
-	of_node_put(remote);
-
-	hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
-	of_node_put(i2c_np);
-	if (!hdmi->ddc_adpt) {
-		dev_err(dev, "Failed to get ddc i2c adapter by node\n");
-		ret = -EINVAL;
-		goto put_device;
-	}
-
-	return 0;
-put_device:
-	put_device(hdmi->cec_dev);
-	return ret;
-}
-
 /*
  * HDMI audio codec callbacks
  */
-
 static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
 				    struct hdmi_codec_daifmt *daifmt,
 				    struct hdmi_codec_params *params)
 {
 	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-	struct hdmi_audio_param hdmi_params;
-	unsigned int chan = params->cea.channels;
-
-	dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
-		params->sample_rate, params->sample_width, chan);
-
-	if (!hdmi->bridge.encoder)
-		return -ENODEV;
-
-	switch (chan) {
-	case 2:
-		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
-		break;
-	case 4:
-		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
-		break;
-	case 6:
-		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
-		break;
-	case 8:
-		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
-		break;
-	default:
-		dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
-		return -EINVAL;
-	}
-
-	switch (params->sample_rate) {
-	case 32000:
-	case 44100:
-	case 48000:
-	case 88200:
-	case 96000:
-	case 176400:
-	case 192000:
-		break;
-	default:
-		dev_err(hdmi->dev, "rate[%d] not supported!\n",
-			params->sample_rate);
-		return -EINVAL;
-	}
 
-	switch (daifmt->fmt) {
-	case HDMI_I2S:
-		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
-		hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
-		hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
-		hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
-		break;
-	case HDMI_SPDIF:
-		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
-		hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
-		break;
-	default:
-		dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,
-			daifmt->fmt);
-		return -EINVAL;
+	if (hdmi->audio_enable) {
+		mtk_hdmi_audio_params(hdmi, daifmt, params);
+		mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);
 	}
-
-	memcpy(&hdmi_params.codec_params, params,
-	       sizeof(hdmi_params.codec_params));
-
-	mtk_hdmi_audio_set_param(hdmi, &hdmi_params);
-
 	return 0;
 }
 
@@ -1582,28 +1133,13 @@ mtk_hdmi_audio_mute(struct device *dev, void *data,
 	return 0;
 }
 
-static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len)
-{
-	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-
-	if (hdmi->enabled)
-		memcpy(buf, hdmi->curr_conn->eld, min(sizeof(hdmi->curr_conn->eld), len));
-	else
-		memset(buf, 0, len);
-	return 0;
-}
-
 static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,
 					  hdmi_codec_plugged_cb fn,
 					  struct device *codec_dev)
 {
 	struct mtk_hdmi *hdmi = data;
 
-	mutex_lock(&hdmi->update_plugged_status_lock);
-	hdmi->plugged_cb = fn;
-	hdmi->codec_dev = codec_dev;
-	mutex_unlock(&hdmi->update_plugged_status_lock);
-
+	mtk_hdmi_audio_set_plugged_cb(hdmi, fn, codec_dev);
 	mtk_hdmi_update_plugged_status(hdmi);
 
 	return 0;
@@ -1619,165 +1155,85 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
 	.no_capture_mute = 1,
 };
 
-static int mtk_hdmi_register_audio_driver(struct device *dev)
+static __maybe_unused int mtk_hdmi_suspend(struct device *dev)
 {
 	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-	struct hdmi_codec_pdata codec_data = {
-		.ops = &mtk_hdmi_audio_codec_ops,
-		.max_i2s_channels = 2,
-		.i2s = 1,
-		.data = hdmi,
-	};
-	struct platform_device *pdev;
-
-	pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-					     PLATFORM_DEVID_AUTO, &codec_data,
-					     sizeof(codec_data));
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
+
+	mtk_hdmi_clk_disable_audio(hdmi);
+
 	return 0;
 }
 
-static int mtk_hdmi_probe(struct platform_device *pdev)
+static __maybe_unused int mtk_hdmi_resume(struct device *dev)
 {
-	struct mtk_hdmi *hdmi;
-	struct device *dev = &pdev->dev;
-	int ret;
-
-	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
-	if (!hdmi)
-		return -ENOMEM;
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
 
-	hdmi->dev = dev;
-	hdmi->conf = of_device_get_match_data(dev);
+	return mtk_hdmi_clk_enable_audio(hdmi);
+}
 
-	ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev);
-	if (ret)
-		return ret;
+static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops, mtk_hdmi_suspend, mtk_hdmi_resume);
 
-	hdmi->phy = devm_phy_get(dev, "hdmi");
-	if (IS_ERR(hdmi->phy))
-		return dev_err_probe(dev, PTR_ERR(hdmi->phy),
-				     "Failed to get HDMI PHY\n");
+static const struct mtk_hdmi_ver_conf mtk_hdmi_v1_ver_conf = {
+	.bridge_funcs = &mtk_mt8183_hdmi_bridge_funcs,
+	.codec_ops = &mtk_hdmi_audio_codec_ops,
+	.mtk_hdmi_clock_names = mtk_hdmi_clk_names_v1,
+	.num_clocks = ARRAY_SIZE(mtk_hdmi_clk_names_v1)
+};
 
-	mutex_init(&hdmi->update_plugged_status_lock);
-	platform_set_drvdata(pdev, hdmi);
+static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = {
+	.tz_disabled = true,
+	.ver_conf = &mtk_hdmi_v1_ver_conf
+};
 
-	ret = mtk_hdmi_output_init(hdmi);
-	if (ret)
-		return dev_err_probe(dev, ret,
-				     "Failed to initialize hdmi output\n");
+static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 = {
+	.max_mode_clock = 148500,
+	.cea_modes_only = true,
+	.ver_conf = &mtk_hdmi_v1_ver_conf
+};
 
-	ret = mtk_hdmi_register_audio_driver(dev);
-	if (ret)
-		return dev_err_probe(dev, ret,
-				     "Failed to register audio driver\n");
+static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8173 = {
+	.ver_conf = &mtk_hdmi_v1_ver_conf
+};
 
-	hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs;
-	hdmi->bridge.of_node = pdev->dev.of_node;
-	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
-			 | DRM_BRIDGE_OP_HPD;
-	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
-	drm_bridge_add(&hdmi->bridge);
+static int mtk_hdmi_probe(struct platform_device *pdev)
+{
+	struct mtk_hdmi *hdmi;
 
-	ret = mtk_hdmi_clk_enable_audio(hdmi);
-	if (ret) {
-		drm_bridge_remove(&hdmi->bridge);
-		return dev_err_probe(dev, ret,
-				     "Failed to enable audio clocks\n");
-	}
+	hdmi = mtk_hdmi_common_probe(pdev);
+	if (IS_ERR(hdmi))
+		return PTR_ERR(hdmi);
 
-	return 0;
+	return mtk_hdmi_clk_enable_audio(hdmi);
 }
 
 static void mtk_hdmi_remove(struct platform_device *pdev)
 {
 	struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
 
-	drm_bridge_remove(&hdmi->bridge);
-	mtk_hdmi_clk_disable_audio(hdmi);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int mtk_hdmi_suspend(struct device *dev)
-{
-	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-
 	mtk_hdmi_clk_disable_audio(hdmi);
-
-	return 0;
-}
-
-static int mtk_hdmi_resume(struct device *dev)
-{
-	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-	int ret = 0;
-
-	ret = mtk_hdmi_clk_enable_audio(hdmi);
-	if (ret) {
-		dev_err(dev, "hdmi resume failed!\n");
-		return ret;
-	}
-
-	return 0;
+	i2c_put_adapter(hdmi->ddc_adpt);
 }
-#endif
-static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops,
-			 mtk_hdmi_suspend, mtk_hdmi_resume);
-
-static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = {
-	.tz_disabled = true,
-};
-
-static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 = {
-	.max_mode_clock = 148500,
-	.cea_modes_only = true,
-};
 
-static const struct of_device_id mtk_hdmi_of_ids[] = {
-	{ .compatible = "mediatek,mt2701-hdmi",
-	  .data = &mtk_hdmi_conf_mt2701,
-	},
-	{ .compatible = "mediatek,mt8167-hdmi",
-	  .data = &mtk_hdmi_conf_mt8167,
-	},
-	{ .compatible = "mediatek,mt8173-hdmi",
-	},
-	{}
+static const struct of_device_id mtk_drm_hdmi_of_ids[] = {
+	{ .compatible = "mediatek,mt2701-hdmi", .data = &mtk_hdmi_conf_mt2701 },
+	{ .compatible = "mediatek,mt8167-hdmi", .data = &mtk_hdmi_conf_mt8167 },
+	{ .compatible = "mediatek,mt8173-hdmi", .data = &mtk_hdmi_conf_mt8173 },
+	{ /* sentinel */ }
 };
-MODULE_DEVICE_TABLE(of, mtk_hdmi_of_ids);
+MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids);
 
 static struct platform_driver mtk_hdmi_driver = {
 	.probe = mtk_hdmi_probe,
-	.remove_new = mtk_hdmi_remove,
+	.remove = mtk_hdmi_remove,
 	.driver = {
 		.name = "mediatek-drm-hdmi",
-		.of_match_table = mtk_hdmi_of_ids,
+		.of_match_table = mtk_drm_hdmi_of_ids,
 		.pm = &mtk_hdmi_pm_ops,
 	},
 };
-
-static struct platform_driver * const mtk_hdmi_drivers[] = {
-	&mtk_hdmi_driver,
-};
-
-static int __init mtk_hdmitx_init(void)
-{
-	return platform_register_drivers(mtk_hdmi_drivers,
-					 ARRAY_SIZE(mtk_hdmi_drivers));
-}
-
-static void __exit mtk_hdmitx_exit(void)
-{
-	platform_unregister_drivers(mtk_hdmi_drivers,
-				    ARRAY_SIZE(mtk_hdmi_drivers));
-}
-
-module_init(mtk_hdmitx_init);
-module_exit(mtk_hdmitx_exit);
+module_platform_driver(mtk_hdmi_driver);
 
 MODULE_AUTHOR("Jie Qiu <jie.qiu at mediatek.com>");
+MODULE_AUTHOR("Can Zeng <can.zeng at mediatek.com>");
 MODULE_DESCRIPTION("MediaTek HDMI Driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
new file mode 100644
index 000000000000..1b23ab6969ec
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -0,0 +1,425 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre, SAS
+ * Copyright (c) 2024 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+ */
+
+#include <drm/drm_modes.h>
+#include <linux/device.h>
+#include <linux/hdmi.h>
+#include <linux/i2c.h>
+#include <linux/math.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+#include <sound/hdmi-codec.h>
+
+#include "mtk_hdmi_common.h"
+
+struct hdmi_acr_n {
+	unsigned int clock;
+	unsigned int n[3];
+};
+
+/* Recommended N values from HDMI specification, tables 7-1 to 7-3 */
+static const struct hdmi_acr_n hdmi_rec_n_table[] = {
+	/* Clock, N: 32kHz 44.1kHz 48kHz */
+	{ 25175,  {  4576,  7007,  6864 } },
+	{ 74176,  { 11648, 17836, 11648 } },
+	{ 148352, { 11648,  8918,  5824 } },
+	{ 296703, {  5824,  4459,  5824 } },
+	{ 297000, {  3072,  4704,  5120 } },
+	{ 0,      {  4096,  6272,  6144 } }, /* all other TMDS clocks */
+};
+
+/**
+ * hdmi_recommended_n() - Return N value recommended by HDMI specification
+ * @freq: audio sample rate in Hz
+ * @clock: rounded TMDS clock in kHz
+ */
+static int hdmi_recommended_n(unsigned int freq, unsigned int clock)
+{
+	const struct hdmi_acr_n *recommended;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_rec_n_table) - 1; i++) {
+		if (clock == hdmi_rec_n_table[i].clock)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(hdmi_rec_n_table))
+		return -EINVAL;
+
+	recommended = hdmi_rec_n_table + i;
+
+	switch (freq) {
+	case 32000:
+		return recommended->n[0];
+	case 44100:
+		return recommended->n[1];
+	case 48000:
+		return recommended->n[2];
+	case 88200:
+		return recommended->n[1] * 2;
+	case 96000:
+		return recommended->n[2] * 2;
+	case 176400:
+		return recommended->n[1] * 4;
+	case 192000:
+		return recommended->n[2] * 4;
+	default:
+		return (128 * freq) / 1000;
+	}
+}
+
+static unsigned int hdmi_mode_clock_to_hz(unsigned int clock)
+{
+	switch (clock) {
+	case 25175:
+		return 25174825; /* 25.2/1.001 MHz */
+	case 74176:
+		return 74175824; /* 74.25/1.001 MHz */
+	case 148352:
+		return 148351648; /* 148.5/1.001 MHz */
+	case 296703:
+		return 296703297; /* 297/1.001 MHz */
+	default:
+		return clock * 1000;
+	}
+}
+
+static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate,
+				      unsigned int tmds_clock, unsigned int n)
+{
+	return DIV_ROUND_CLOSEST_ULL((u64)hdmi_mode_clock_to_hz(tmds_clock) * n,
+				     128 * audio_sample_rate);
+}
+
+int mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock,
+		      unsigned int *n, unsigned int *cts)
+{
+	int rec_n = hdmi_recommended_n(sample_rate, clock);
+
+	if (rec_n < 0)
+		return rec_n;
+
+	*cts = hdmi_expected_cts(sample_rate, clock, rec_n);
+	*n = rec_n;
+
+	return 0;
+}
+
+int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi,
+			  struct hdmi_codec_daifmt *daifmt,
+			  struct hdmi_codec_params *params)
+{
+	struct hdmi_audio_param aud_params = { 0 };
+	unsigned int chan = params->cea.channels;
+
+	dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
+		params->sample_rate, params->sample_width, chan);
+
+	if (!hdmi->bridge.encoder)
+		return -ENODEV;
+
+	switch (chan) {
+	case 2:
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
+		break;
+	case 4:
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
+		break;
+	case 6:
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
+		break;
+	case 8:
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
+		break;
+	default:
+		dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
+		return -EINVAL;
+	}
+
+	switch (params->sample_rate) {
+	case 32000:
+	case 44100:
+	case 48000:
+	case 88200:
+	case 96000:
+	case 176400:
+	case 192000:
+		break;
+	default:
+		dev_err(hdmi->dev, "rate[%d] not supported!\n",
+			params->sample_rate);
+		return -EINVAL;
+	}
+
+	switch (daifmt->fmt) {
+	case HDMI_I2S:
+		aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+		aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		aud_params.aud_input_type = HDMI_AUD_INPUT_I2S;
+		aud_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
+		aud_params.aud_mclk = HDMI_AUD_MCLK_128FS;
+		break;
+	case HDMI_SPDIF:
+		aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+		aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		aud_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
+		break;
+	default:
+		dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,
+			daifmt->fmt);
+		return -EINVAL;
+	}
+	memcpy(&aud_params.codec_params, params, sizeof(aud_params.codec_params));
+	memcpy(&hdmi->aud_param, &aud_params, sizeof(aud_params));
+
+	dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",
+		aud_params.aud_codec, aud_params.aud_input_type,
+		aud_params.aud_input_chan_type, aud_params.codec_params.sample_rate);
+
+	return 0;
+}
+
+int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	if (hdmi->enabled)
+		memcpy(buf, hdmi->curr_conn->eld, min(sizeof(hdmi->curr_conn->eld), len));
+	else
+		memset(buf, 0, len);
+
+	return 0;
+}
+
+void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn,
+				   struct device *codec_dev)
+{
+	mutex_lock(&hdmi->update_plugged_status_lock);
+	hdmi->plugged_cb = fn;
+	hdmi->codec_dev = codec_dev;
+	mutex_unlock(&hdmi->update_plugged_status_lock);
+}
+
+static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi, struct device_node *np,
+				const char * const *mtk_hdmi_clk_names, size_t num_clocks)
+{
+	int i;
+
+	for (i = 0; i < num_clocks; i++) {
+		hdmi->clk[i] = of_clk_get_by_name(np, mtk_hdmi_clk_names[i]);
+
+		if (IS_ERR(hdmi->clk[i]))
+			return PTR_ERR(hdmi->clk[i]);
+	}
+
+	return 0;
+}
+
+bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+				const struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+			      const struct drm_display_mode *mode,
+			      const struct drm_display_mode *adjusted_mode)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	drm_mode_copy(&hdmi->mode, adjusted_mode);
+}
+
+static int mtk_hdmi_get_cec_dev(struct mtk_hdmi *hdmi, struct device *dev, struct device_node *np)
+{
+	struct platform_device *cec_pdev;
+	struct device_node *cec_np;
+	int ret;
+
+	/* The CEC module handles HDMI hotplug detection */
+	cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
+	if (!cec_np)
+		return dev_err_probe(dev, -ENOTSUPP, "Failed to find CEC node\n");
+
+	cec_pdev = of_find_device_by_node(cec_np);
+	if (!cec_pdev) {
+		dev_err(hdmi->dev, "Waiting for CEC device %pOF\n", cec_np);
+		of_node_put(cec_np);
+		return -EPROBE_DEFER;
+	}
+	of_node_put(cec_np);
+
+	/*
+	 * The mediatek,syscon-hdmi property contains a phandle link to the
+	 * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG
+	 * registers it contains.
+	 */
+	hdmi->sys_regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");
+	if (IS_ERR(hdmi->sys_regmap))
+		return PTR_ERR(hdmi->sys_regmap);
+
+	ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, &hdmi->sys_offset);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get system configuration registers\n");
+
+	hdmi->cec_dev = &cec_pdev->dev;
+	return 0;
+}
+
+static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device *pdev,
+				   const char * const *clk_names, size_t num_clocks)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *remote, *i2c_np;
+	int ret;
+
+	ret = mtk_hdmi_get_all_clk(hdmi, np, clk_names, num_clocks);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get clocks\n");
+
+	hdmi->irq = platform_get_irq(pdev, 0);
+	if (!hdmi->irq)
+		return hdmi->irq;
+
+	hdmi->regs = device_node_to_regmap(dev->of_node);
+	if (IS_ERR(hdmi->regs))
+		return PTR_ERR(hdmi->regs);
+
+	remote = of_graph_get_remote_node(np, 1, 0);
+	if (!remote)
+		return dev_err_probe(dev, -EINVAL, "Cannot find HDMI input port\n");
+
+	if (!of_device_is_compatible(remote, "hdmi-connector")) {
+		hdmi->next_bridge = of_drm_find_bridge(remote);
+		if (!hdmi->next_bridge) {
+			dev_err(dev, "Waiting for external bridge\n");
+			of_node_put(remote);
+			return -EPROBE_DEFER;
+		}
+	}
+
+	i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
+	if (!i2c_np) {
+		of_node_put(pdev->dev.of_node);
+		return dev_err_probe(dev, -EINVAL, "No ddc-i2c-bus in connector\n");
+	}
+
+	hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
+	of_node_put(i2c_np);
+	if (!hdmi->ddc_adpt) {
+		dev_err(dev, "Failed to get ddc i2c adapter by node");
+		return -EPROBE_DEFER;
+	}
+
+	ret = mtk_hdmi_get_cec_dev(hdmi, dev, np);
+	if (ret == -ENOTSUPP)
+		dev_info(dev, "CEC support unavailable: node not found\n");
+	else if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void mtk_hdmi_unregister_audio_driver(void *data)
+{
+	platform_device_unregister(data);
+}
+
+static int mtk_hdmi_register_audio_driver(struct device *dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
+	struct hdmi_codec_pdata codec_data = {
+		.i2s = 1,
+		.max_i2s_channels = 2,
+		.data = hdmi,
+		.ops = hdmi->conf->ver_conf->codec_ops
+	};
+	int ret;
+
+	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
+	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
+	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
+	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
+
+	hdmi->audio_pdev = platform_device_register_data(dev,
+							 HDMI_CODEC_DRV_NAME,
+							 PLATFORM_DEVID_AUTO,
+							 &codec_data,
+							 sizeof(codec_data));
+	if (IS_ERR(hdmi->audio_pdev))
+		return PTR_ERR(hdmi->audio_pdev);
+
+	ret = devm_add_action_or_reset(dev, mtk_hdmi_unregister_audio_driver,
+				       hdmi->audio_pdev);
+	if (ret) {
+		platform_device_unregister(hdmi->audio_pdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
+{
+	const struct mtk_hdmi_ver_conf *ver_conf;
+	struct device *dev = &pdev->dev;
+	struct mtk_hdmi *hdmi;
+	int ret;
+
+	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return ERR_PTR(-ENOMEM);
+
+	hdmi->dev = dev;
+	hdmi->conf = of_device_get_match_data(dev);
+	ver_conf = hdmi->conf->ver_conf;
+
+	hdmi->clk = devm_kcalloc(dev, ver_conf->num_clocks, sizeof(*hdmi->clk), GFP_KERNEL);
+	if (!hdmi->clk)
+		return ERR_PTR(-ENOMEM);
+
+	hdmi->phy = devm_phy_get(dev, "hdmi");
+	if (IS_ERR(hdmi->phy))
+		return dev_err_cast_probe(dev, hdmi->phy, "Failed to get HDMI PHY\n");
+
+	ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, ver_conf->mtk_hdmi_clock_names,
+				      ver_conf->num_clocks);
+	if (ret)
+		return ERR_PTR(ret);
+
+	platform_set_drvdata(pdev, hdmi);
+
+	ret = mtk_hdmi_register_audio_driver(dev);
+	if (ret)
+		return dev_err_ptr_probe(dev, ret, "Cannot register HDMI Audio driver\n");
+
+	hdmi->bridge.funcs = ver_conf->bridge_funcs;
+	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
+	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+	hdmi->bridge.of_node = pdev->dev.of_node;
+
+	ret = devm_drm_bridge_add(dev, &hdmi->bridge);
+	if (ret)
+		return dev_err_ptr_probe(dev, ret, "Failed to add bridge\n");
+
+	return hdmi;
+}
+
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>");
+MODULE_AUTHOR("Can Zeng <can.zeng at mediatek.com>");
+MODULE_AUTHOR("Jie Qiu <jie.qiu at mediatek.com>");
+MODULE_DESCRIPTION("MediaTek HDMI Common Library");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
new file mode 100644
index 000000000000..15121e8548f3
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre, SAS
+ */
+
+#ifndef _MTK_HDMI_COMMON_H
+#define _MTK_HDMI_COMMON_H
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/hdmi.h>
+#include <linux/i2c.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mutex.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+#include <sound/hdmi-codec.h>
+
+enum hdmi_aud_input_type {
+	HDMI_AUD_INPUT_I2S = 0,
+	HDMI_AUD_INPUT_SPDIF,
+};
+
+enum hdmi_aud_i2s_fmt {
+	HDMI_I2S_MODE_RJT_24BIT = 0,
+	HDMI_I2S_MODE_RJT_16BIT,
+	HDMI_I2S_MODE_LJT_24BIT,
+	HDMI_I2S_MODE_LJT_16BIT,
+	HDMI_I2S_MODE_I2S_24BIT,
+	HDMI_I2S_MODE_I2S_16BIT
+};
+
+enum hdmi_aud_mclk {
+	HDMI_AUD_MCLK_128FS,
+	HDMI_AUD_MCLK_192FS,
+	HDMI_AUD_MCLK_256FS,
+	HDMI_AUD_MCLK_384FS,
+	HDMI_AUD_MCLK_512FS,
+	HDMI_AUD_MCLK_768FS,
+	HDMI_AUD_MCLK_1152FS,
+};
+
+enum hdmi_aud_channel_type {
+	HDMI_AUD_CHAN_TYPE_1_0 = 0,
+	HDMI_AUD_CHAN_TYPE_1_1,
+	HDMI_AUD_CHAN_TYPE_2_0,
+	HDMI_AUD_CHAN_TYPE_2_1,
+	HDMI_AUD_CHAN_TYPE_3_0,
+	HDMI_AUD_CHAN_TYPE_3_1,
+	HDMI_AUD_CHAN_TYPE_4_0,
+	HDMI_AUD_CHAN_TYPE_4_1,
+	HDMI_AUD_CHAN_TYPE_5_0,
+	HDMI_AUD_CHAN_TYPE_5_1,
+	HDMI_AUD_CHAN_TYPE_6_0,
+	HDMI_AUD_CHAN_TYPE_6_1,
+	HDMI_AUD_CHAN_TYPE_7_0,
+	HDMI_AUD_CHAN_TYPE_7_1,
+	HDMI_AUD_CHAN_TYPE_3_0_LRS,
+	HDMI_AUD_CHAN_TYPE_3_1_LRS,
+	HDMI_AUD_CHAN_TYPE_4_0_CLRS,
+	HDMI_AUD_CHAN_TYPE_4_1_CLRS,
+	HDMI_AUD_CHAN_TYPE_6_1_CS,
+	HDMI_AUD_CHAN_TYPE_6_1_CH,
+	HDMI_AUD_CHAN_TYPE_6_1_OH,
+	HDMI_AUD_CHAN_TYPE_6_1_CHR,
+	HDMI_AUD_CHAN_TYPE_7_1_LH_RH,
+	HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR,
+	HDMI_AUD_CHAN_TYPE_7_1_LC_RC,
+	HDMI_AUD_CHAN_TYPE_7_1_LW_RW,
+	HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD,
+	HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS,
+	HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS,
+	HDMI_AUD_CHAN_TYPE_7_1_CS_CH,
+	HDMI_AUD_CHAN_TYPE_7_1_CS_OH,
+	HDMI_AUD_CHAN_TYPE_7_1_CS_CHR,
+	HDMI_AUD_CHAN_TYPE_7_1_CH_OH,
+	HDMI_AUD_CHAN_TYPE_7_1_CH_CHR,
+	HDMI_AUD_CHAN_TYPE_7_1_OH_CHR,
+	HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR,
+	HDMI_AUD_CHAN_TYPE_6_0_CS,
+	HDMI_AUD_CHAN_TYPE_6_0_CH,
+	HDMI_AUD_CHAN_TYPE_6_0_OH,
+	HDMI_AUD_CHAN_TYPE_6_0_CHR,
+	HDMI_AUD_CHAN_TYPE_7_0_LH_RH,
+	HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR,
+	HDMI_AUD_CHAN_TYPE_7_0_LC_RC,
+	HDMI_AUD_CHAN_TYPE_7_0_LW_RW,
+	HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD,
+	HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS,
+	HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS,
+	HDMI_AUD_CHAN_TYPE_7_0_CS_CH,
+	HDMI_AUD_CHAN_TYPE_7_0_CS_OH,
+	HDMI_AUD_CHAN_TYPE_7_0_CS_CHR,
+	HDMI_AUD_CHAN_TYPE_7_0_CH_OH,
+	HDMI_AUD_CHAN_TYPE_7_0_CH_CHR,
+	HDMI_AUD_CHAN_TYPE_7_0_OH_CHR,
+	HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR,
+	HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS,
+	HDMI_AUD_CHAN_TYPE_UNKNOWN = 0xFF
+};
+
+enum hdmi_aud_channel_swap_type {
+	HDMI_AUD_SWAP_LR,
+	HDMI_AUD_SWAP_LFE_CC,
+	HDMI_AUD_SWAP_LSRS,
+	HDMI_AUD_SWAP_RLS_RRS,
+	HDMI_AUD_SWAP_LR_STATUS,
+};
+
+enum hdmi_hpd_state {
+	HDMI_PLUG_OUT = 0,
+	HDMI_PLUG_IN_AND_SINK_POWER_ON,
+	HDMI_PLUG_IN_ONLY,
+};
+
+struct hdmi_audio_param {
+	enum hdmi_audio_coding_type aud_codec;
+	enum hdmi_audio_sample_size aud_sample_size;
+	enum hdmi_aud_input_type aud_input_type;
+	enum hdmi_aud_i2s_fmt aud_i2s_fmt;
+	enum hdmi_aud_mclk aud_mclk;
+	enum hdmi_aud_channel_type aud_input_chan_type;
+	struct hdmi_codec_params codec_params;
+};
+
+struct mtk_hdmi {
+	struct drm_bridge bridge;
+	struct device *dev;
+	const struct mtk_hdmi_conf *conf;
+	struct phy *phy;
+	struct i2c_adapter *ddc_adpt;
+	struct clk **clk;
+	struct drm_display_mode mode;
+	bool dvi_mode;
+	struct regmap *sys_regmap;
+	unsigned int sys_offset;
+	struct regmap *regs;
+
+	bool powered;
+	bool enabled;
+	unsigned int irq;
+	enum hdmi_hpd_state hpd;
+
+	/* Audio */
+	struct platform_device *audio_pdev;
+	struct hdmi_audio_param aud_param;
+	bool audio_enable;
+
+	struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */
+	struct mutex update_plugged_status_lock;
+	struct device *cec_dev;
+	struct device *codec_dev;
+	hdmi_codec_plugged_cb plugged_cb;
+	struct drm_bridge *next_bridge;
+};
+
+struct mtk_hdmi_ver_conf {
+	const struct drm_bridge_funcs *bridge_funcs;
+	const struct hdmi_codec_ops *codec_ops;
+	const char * const *mtk_hdmi_clock_names;
+	int num_clocks;
+	bool hdr_support;
+};
+
+struct mtk_hdmi_conf {
+	const struct mtk_hdmi_ver_conf *ver_conf;
+	bool tz_disabled;
+	bool cea_modes_only;
+	unsigned long max_mode_clock;
+};
+
+static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
+{
+	return container_of(b, struct mtk_hdmi, bridge);
+}
+
+int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len);
+void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn,
+				   struct device *codec_dev);
+int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi, struct hdmi_codec_daifmt *daifmt,
+			  struct hdmi_codec_params *params);
+int mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock,
+		      unsigned int *n, unsigned int *cts);
+bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+				const struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode);
+void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+			      const struct drm_display_mode *mode,
+			      const struct drm_display_mode *adjusted_mode);
+struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev);
+int mtk_drm_hdmi_probe(struct platform_device *pdev);
+int mtk_drm_hdmi_remove(struct platform_device *pdev);
+
+#endif /* _MTK_HDMI_COMMON_H */
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:16 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:16 +0100
Subject: [PATCH v2 14/15] drm/mediatek: mtk_hdmi_common: Add OP_HDMI, vendor and product strings
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-15-angelogioacchino.delregno@collabora.com>

In preparation for adding the HDMI TX v2 driver, and to allow
a future modernization of the HDMI v1 one, perform changes
that enable the usage of the HDMI Helpers provided by DRM.

Check if the HDMI driver provides the function pointers to
hdmi_{clear,write}_infoframe used by the HDMI Helper API and,
if present, add DRM_BRIDGE_OP_HDMI to the drm_bridge ops,
enabling the drm API to register the bridge as HDMI and to use
the HDMI Helper functions.

Moreover, as part of data exclusively used (in the context of
HDMI bridges) by the helpers, assign the vendor "MediaTek" and
product "On-Chip HDMI" strings to the drm_bridge struct.

If the hdmi_{write,clear}_infoframe pointers are not assigned,
vendor and product strings and HDMI helpers will not be used,
hence this commit brings no functional changes to drivers that
have not been refactored to use the new helpers.

This also means that, in the current state, there is effectively
no functional change to mtk_hdmi and its other components.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index 4f708b04f5e8..0f60842462b0 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -408,9 +408,16 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
 
 	hdmi->bridge.funcs = ver_conf->bridge_funcs;
 	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
+
+	if (ver_conf->bridge_funcs->hdmi_write_infoframe &&
+	    ver_conf->bridge_funcs->hdmi_clear_infoframe)
+		hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI;
+
 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	hdmi->bridge.of_node = pdev->dev.of_node;
 	hdmi->bridge.ddc = hdmi->ddc_adpt;
+	hdmi->bridge.vendor = "MediaTek";
+	hdmi->bridge.product = "On-Chip HDMI";
 
 	ret = devm_drm_bridge_add(dev, &hdmi->bridge);
 	if (ret)
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Thu Dec  5 03:45:17 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  5 Dec 2024 12:45:17 +0100
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for MT8195/MT8188
In-Reply-To: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>

Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
found in MediaTek's MT8195, MT8188 SoC and their variants, and
including support for display modes up to 4k60 and for HDMI
Audio, as per the HDMI 2.0 spec.

HDCP and CEC functionalities are also supported by this hardware,
but are not included in this commit and that also poses a slight
difference between the V2 and V1 controllers in how they handle
Hotplug Detection (HPD).

While the v1 controller was using the CEC controller to check
HDMI cable connection and disconnection, in this driver the v2
one does not.

This is due to the fact that on parts with v2 designs, like the
MT8195 SoC, there is one CEC controller shared between the HDMI
Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
adding support to use the CEC HW to wake up the HDMI controllers
it is necessary to have support for one TX, one RX *and* for both
at the same time.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/Kconfig            |    8 +
 drivers/gpu/drm/mediatek/Makefile           |    4 +
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c  |    5 +
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h  |    1 +
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c  |  403 +++++
 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h |  263 ++++
 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c      | 1488 +++++++++++++++++++
 7 files changed, 2172 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index 73459f07dae3..8127576be1eb 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -50,3 +50,11 @@ config DRM_MEDIATEK_HDMI
 	select PHY_MTK_HDMI
 	help
 	  DRM/KMS HDMI driver for Mediatek SoCs
+
+config DRM_MEDIATEK_HDMI_V2
+	tristate "DRM HDMI v2 IP support for MediaTek SoCs"
+	depends on DRM_MEDIATEK
+	select DRM_MEDIATEK_HDMI_COMMON
+	select PHY_MTK_HDMI
+	help
+	  DRM/KMS HDMI driver for MediaTek SoCs with HDMIv2 IP
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 8973d7ba37d3..928a850f707f 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -25,7 +25,11 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
 			  mtk_hdmi.o \
 			  mtk_hdmi_ddc.o
 
+mediatek-drm-hdmi-v2-objs := mtk_hdmi_ddc_v2.o \
+			     mtk_hdmi_v2.o
+
 obj-$(CONFIG_DRM_MEDIATEK_HDMI_COMMON) += mtk_hdmi_common.o
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
+obj-$(CONFIG_DRM_MEDIATEK_HDMI_V2) += mediatek-drm-hdmi-v2.o
 
 obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index 0f60842462b0..90f603f34cde 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -295,6 +295,11 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device
 	if (IS_ERR(hdmi->regs))
 		return PTR_ERR(hdmi->regs);
 
+	/* Populate HDMI sub-devices if present */
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret)
+		return ret;
+
 	remote = of_graph_get_remote_node(np, 1, 0);
 	if (!remote)
 		return dev_err_probe(dev, -EINVAL, "Cannot find HDMI input port\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
index 15121e8548f3..8cfff39b0d90 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
@@ -176,6 +176,7 @@ struct mtk_hdmi_conf {
 	bool tz_disabled;
 	bool cea_modes_only;
 	unsigned long max_mode_clock;
+	u32 reg_hdmi_tx_cfg;
 };
 
 static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
new file mode 100644
index 000000000000..297b8b6f668c
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek HDMI v2 Display Data Channel Driver
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre, SAS
+ * Copyright (c) 2024 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#include <drm/drm_edid.h>
+
+#include "mtk_hdmi_common.h"
+#include "mtk_hdmi_regs_v2.h"
+
+#define DDC2_DLY_CNT 572 /* BIM=208M/(v*4) = 90Khz */
+#define DDC2_DLY_CNT_EDID 832 /* BIM=208M/(v*4) = 62.5Khz */
+#define SI2C_ADDR_READ 0xf4
+#define SCDC_I2C_SLAVE_ADDRESS 0x54
+
+struct mtk_hdmi_ddc {
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *clk;
+	struct i2c_adapter adap;
+	/* Serialize read/write operations */
+	struct mutex mtx;
+};
+
+static int mtk_ddc_check_and_rise_low_bus(struct mtk_hdmi_ddc *ddc)
+{
+	u32 val;
+
+	regmap_read(ddc->regs, HDCP2X_DDCM_STATUS, &val);
+	if (val & DDC_I2C_BUS_LOW) {
+		regmap_update_bits(ddc->regs, DDC_CTRL, DDC_CTRL_CMD,
+				   FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_CLOCK_SCL));
+		usleep_range(250, 300);
+	}
+
+	if (val & DDC_I2C_NO_ACK) {
+		u32 ddc_ctrl, hpd_ddc_ctrl, hpd_ddc_status;
+
+		regmap_read(ddc->regs, DDC_CTRL, &ddc_ctrl);
+		regmap_read(ddc->regs, HPD_DDC_CTRL, &hpd_ddc_ctrl);
+		regmap_read(ddc->regs, HPD_DDC_STATUS, &hpd_ddc_status);
+	}
+
+	if (val & DDC_I2C_NO_ACK)
+		return -EIO;
+
+	return 0;
+}
+
+static int mtk_ddc_wr_one(struct mtk_hdmi_ddc *ddc, u16 addr_id,
+			  u16 offset_id, u8 wr_data)
+{
+	u32 val;
+	int ret;
+
+	/* If down, rise bus for write operation */
+	mtk_ddc_check_and_rise_low_bus(ddc);
+
+	regmap_update_bits(ddc->regs, HPD_DDC_CTRL, HPD_DDC_DELAY_CNT,
+			   FIELD_PREP(HPD_DDC_DELAY_CNT, DDC2_DLY_CNT));
+
+	regmap_write(ddc->regs, SI2C_CTRL,
+		     FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
+		     FIELD_PREP(SI2C_WDATA, wr_data) |
+		     SI2C_WR);
+
+	regmap_write(ddc->regs, DDC_CTRL,
+		     FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_SEQ_WRITE) |
+		     FIELD_PREP(DDC_CTRL_DIN_CNT, 1) |
+		     FIELD_PREP(DDC_CTRL_OFFSET, offset_id) |
+		     FIELD_PREP(DDC_CTRL_ADDR, addr_id));
+	usleep_range(1000, 1250);
+
+	ret = regmap_read_poll_timeout(ddc->regs, HPD_DDC_STATUS, val,
+				       !(val & DDC_I2C_IN_PROG), 500, 1000);
+	if (ret) {
+		dev_err(ddc->dev, "DDC I2C write timeout\n");
+		return ret;
+	}
+
+	/* The I2C bus might be down after WR operation: rise it again */
+	ret = mtk_ddc_check_and_rise_low_bus(ddc);
+	if (ret) {
+		dev_err(ddc->dev, "Error during write operation: No ACK\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mtk_ddcm_read_hdmi(struct mtk_hdmi_ddc *ddc, u16 dly_cnt, u16 uc_dev,
+			      u8 addr, u8 *puc_value, u16 data_cnt)
+{
+	u16 i, loop_counter, temp_length, uc_idx;
+	u32 rem, uc_read_count, val;
+	int ret;
+
+	if (!puc_value || !data_cnt || !dly_cnt) {
+		dev_err(ddc->dev, "Bad DDCM read request\n");
+		return 0;
+	}
+
+	mtk_ddc_check_and_rise_low_bus(ddc);
+
+	regmap_update_bits(ddc->regs, DDC_CTRL, DDC_CTRL_CMD,
+			   FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_CLEAR_FIFO));
+
+	if (data_cnt >= 16) {
+		temp_length = 16;
+		loop_counter = data_cnt;
+
+		rem = do_div(loop_counter, temp_length);
+		if (rem)
+			loop_counter++;
+	} else {
+		temp_length = data_cnt;
+		loop_counter = 1;
+	}
+
+	if (uc_dev >= DDC_ADDR && dly_cnt < DDC2_DLY_CNT_EDID)
+		dly_cnt = DDC2_DLY_CNT_EDID;
+
+	regmap_update_bits(ddc->regs, HPD_DDC_CTRL, HPD_DDC_DELAY_CNT,
+			   FIELD_PREP(HPD_DDC_DELAY_CNT, dly_cnt));
+
+	for (i = 0; i < loop_counter; i++) {
+		rem = data_cnt % 16;
+
+		if (i > 0 && i == (loop_counter - 1) && rem)
+			temp_length = rem;
+
+		/* 0x51 - 0x53: Flow control */
+		if (uc_dev > DDC_ADDR && uc_dev <= 0x53) {
+			regmap_update_bits(ddc->regs, SCDC_CTRL, SCDC_DDC_SEGMENT,
+					   FIELD_PREP(SCDC_DDC_SEGMENT, uc_dev - DDC_ADDR));
+
+			regmap_write(ddc->regs, DDC_CTRL,
+				     FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_ENH_READ_NOACK) |
+				     FIELD_PREP(DDC_CTRL_DIN_CNT, temp_length) |
+				     FIELD_PREP(DDC_CTRL_OFFSET, addr + i * temp_length) |
+				     FIELD_PREP(DDC_CTRL_ADDR, DDC_ADDR));
+		} else {
+			u16 offset;
+
+			if (addr != 0x43)
+				offset = i * 16;
+			else
+				offset = 0;
+
+			regmap_write(ddc->regs, DDC_CTRL,
+				     FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_SEQ_READ_NOACK) |
+				     FIELD_PREP(DDC_CTRL_DIN_CNT, temp_length) |
+				     FIELD_PREP(DDC_CTRL_OFFSET, addr + offset) |
+				     FIELD_PREP(DDC_CTRL_ADDR, uc_dev));
+		}
+		usleep_range(5000, 5500);
+
+		ret = regmap_read_poll_timeout(ddc->regs, HPD_DDC_STATUS, val,
+					       !(val & DDC_I2C_IN_PROG), 1000,
+					       500 * (temp_length + 5));
+		if (ret) {
+			dev_err(ddc->dev, "Timeout waiting for DDC I2C\n");
+			return ret;
+		}
+
+		ret = mtk_ddc_check_and_rise_low_bus(ddc);
+		if (ret) {
+			dev_err(ddc->dev, "Error during read operation: No ACK\n");
+			return ret;
+		}
+
+		for (uc_idx = 0; uc_idx < temp_length; uc_idx++) {
+			unsigned int read_idx = i * 16 + uc_idx;
+
+			regmap_write(ddc->regs, SI2C_CTRL,
+				     FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
+				     SI2C_RD);
+
+			regmap_read(ddc->regs, HPD_DDC_STATUS, &val);
+			puc_value[read_idx] = FIELD_GET(DDC_DATA_OUT, val);
+
+			regmap_write(ddc->regs, SI2C_CTRL,
+				     FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
+				     SI2C_CONFIRM_READ);
+
+			/*
+			 * If HDMI IP gets reset during EDID read, DDC read
+			 * operation will fail and its delay counter will be
+			 * reset to 400.
+			 */
+			regmap_read(ddc->regs, HPD_DDC_CTRL, &val);
+			if (FIELD_GET(HPD_DDC_DELAY_CNT, val) < DDC2_DLY_CNT)
+				return 0;
+
+			uc_read_count = read_idx + 1;
+		}
+	}
+	if (uc_read_count > U8_MAX)
+		dev_warn(ddc->dev, "Invalid read data count %u\n", uc_read_count);
+
+	return uc_read_count;
+}
+
+static int mtk_hdmi_fg_ddc_data_read(struct mtk_hdmi_ddc *ddc, u16 b_dev,
+				     u8 data_addr, u16 data_cnt, u8 *pr_data)
+{
+	int read_data_cnt;
+	u16 req_data_cnt;
+
+	if (!pr_data || !data_cnt)
+		return -EINVAL;
+
+	req_data_cnt = U8_MAX - data_addr + 1;
+	if (req_data_cnt > data_cnt)
+		req_data_cnt = data_cnt;
+
+	mutex_lock(&ddc->mtx);
+
+	regmap_set_bits(ddc->regs, HDCP2X_POL_CTRL, HDCP2X_DIS_POLL_EN);
+
+	read_data_cnt = mtk_ddcm_read_hdmi(ddc, DDC2_DLY_CNT, b_dev, data_addr,
+					   pr_data, req_data_cnt);
+
+	mutex_unlock(&ddc->mtx);
+
+	if (read_data_cnt < 0)
+		return read_data_cnt;
+	else if (read_data_cnt != req_data_cnt)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int mtk_hdmi_ddc_fg_data_write(struct mtk_hdmi_ddc *ddc, u16 b_dev,
+				      u8 data_addr, u16 data_cnt, u8 *pr_data)
+{
+	int i = 0, ret;
+
+	mutex_lock(&ddc->mtx);
+
+	regmap_set_bits(ddc->regs, HDCP2X_POL_CTRL, HDCP2X_DIS_POLL_EN);
+	do {
+		ret = mtk_ddc_wr_one(ddc, b_dev, data_addr + i, pr_data[i]);
+		if (ret)
+			break;
+	} while (++i < data_cnt);
+
+	mutex_unlock(&ddc->mtx);
+
+	return ret;
+}
+
+static int mtk_hdmi_ddc_v2_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+	struct mtk_hdmi_ddc *ddc;
+	u8 offset = 0;
+	int i, ret;
+
+	if (!adapter || !adapter->algo_data || !msgs)
+		return -EINVAL;
+
+	ddc = adapter->algo_data;
+
+	for (i = 0; i < num; i++) {
+		struct i2c_msg *msg = &msgs[i];
+
+		if (!msg->buf) {
+			pr_err("XFER: No message buffer\n");
+			return -EINVAL;
+		}
+
+		if (msg->flags & I2C_M_RD) {
+			/*
+			 * The underlying DDC hardware always issues a write request
+			 * that assigns the read offset as part of the read operation,
+			 * therefore, use the `offset` value assigned in the previous
+			 * write request from drm_edid
+			 */
+			ret = mtk_hdmi_fg_ddc_data_read(ddc, msg->addr, offset,
+							msg->len, &msg->buf[0]);
+			if (ret)
+				return ret;
+		} else {
+			ret = mtk_hdmi_ddc_fg_data_write(ddc, msg->addr, msg->buf[0],
+							 msg->len - 1, &msg->buf[1]);
+			if (ret)
+				return ret;
+
+			/*
+			 * Store the offset value requested by drm_edid or by
+			 * scdc to use in subsequent read requests.
+			 */
+			if ((msg->addr == DDC_ADDR || msg->addr == SCDC_I2C_SLAVE_ADDRESS) &&
+			    msg->len == 1) {
+				offset = msg->buf[0];
+			}
+		}
+	}
+
+	return i;
+}
+
+static u32 mtk_hdmi_ddc_v2_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm mtk_hdmi_ddc_v2_algorithm = {
+	.master_xfer = mtk_hdmi_ddc_v2_xfer,
+	.functionality = mtk_hdmi_ddc_v2_func,
+};
+
+static int mtk_hdmi_ddc_v2_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_hdmi_ddc *ddc;
+	int ret;
+
+	ddc = devm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL);
+	if (!ddc)
+		return -ENOMEM;
+
+	ddc->dev = dev;
+	ddc->regs = device_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR_OR_NULL(ddc->regs))
+		return dev_err_probe(dev,
+				     IS_ERR(ddc->regs) ? PTR_ERR(ddc->regs) : -EINVAL,
+				     "Cannot get regmap\n");
+
+	ddc->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(ddc->clk))
+		return dev_err_probe(dev, PTR_ERR(ddc->clk), "Cannot get DDC clock\n");
+
+	mutex_init(&ddc->mtx);
+
+	strscpy(ddc->adap.name, "mediatek-hdmi-ddc-v2", sizeof(ddc->adap.name));
+	ddc->adap.owner = THIS_MODULE;
+	ddc->adap.algo = &mtk_hdmi_ddc_v2_algorithm;
+	ddc->adap.retries = 3;
+	ddc->adap.dev.of_node = dev->of_node;
+	ddc->adap.algo_data = ddc;
+	ddc->adap.dev.parent = &pdev->dev;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Cannot enable Runtime PM\n");
+
+	pm_runtime_get_sync(dev);
+
+	ret = devm_i2c_add_adapter(dev, &ddc->adap);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Cannot add DDC I2C adapter\n");
+
+	platform_set_drvdata(pdev, ddc);
+	return 0;
+}
+
+static const struct of_device_id mtk_hdmi_ddc_v2_match[] = {
+	{ .compatible = "mediatek,mt8195-hdmi-ddc" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_v2_match)
+
+struct platform_driver mtk_hdmi_ddc_v2_driver = {
+	.probe = mtk_hdmi_ddc_v2_probe,
+	.driver = {
+		.name = "mediatek-hdmi-ddc-v2",
+		.of_match_table = mtk_hdmi_ddc_v2_match,
+	},
+};
+module_platform_driver(mtk_hdmi_ddc_v2_driver);
+
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>");
+MODULE_AUTHOR("Can Zeng <can.zeng at mediatek.com>");
+MODULE_DESCRIPTION("MediaTek HDMIv2 DDC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h b/drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
new file mode 100644
index 000000000000..521b35c7e14d
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
@@ -0,0 +1,263 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre, SAS
+ * Copyright (c) 2024 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+ */
+
+#ifndef _MTK_HDMI_REGS_H
+#define _MTK_HDMI_REGS_H
+
+/* HDMI_TOP Config */
+#define TOP_CFG00			0x000
+#define  HDMI2_ON			BIT(2)
+#define  HDMI_MODE_HDMI			BIT(3)
+#define  SCR_ON				BIT(4)
+#define  TMDS_PACK_MODE			GENMASK(9, 8)
+#define   TMDS_PACK_MODE_8BPP		0
+#define   TMDS_PACK_MODE_10BPP		1
+#define   TMDS_PACK_MODE_12BPP		2
+#define   TMDS_PACK_MODE_16BPP		3
+#define  DEEPCOLOR_PKT_EN		BIT(12)
+#define  HDMI_ABIST_VIDEO_FORMAT	GENMASK(21, 16)
+#define  HDMI_ABIST_ENABLE		BIT(31)
+#define TOP_CFG01 0x004
+#define  CP_SET_MUTE_EN			BIT(0)
+#define  CP_CLR_MUTE_EN			BIT(1)
+#define  NULL_PKT_EN			BIT(2)
+#define  NULL_PKT_VSYNC_HIGH_EN		BIT(3)
+
+/* HDMI_TOP Audio: Channel Mapping */
+#define TOP_AUD_MAP			0x00c
+#define  SD0_MAP			GENMASK(2, 0)
+#define  SD1_MAP			GENMASK(6, 4)
+#define  SD2_MAP			GENMASK(10, 8)
+#define  SD3_MAP			GENMASK(14, 12)
+#define  SD4_MAP			GENMASK(18, 16)
+#define  SD5_MAP			GENMASK(22, 20)
+#define  SD6_MAP			GENMASK(26, 24)
+#define  SD7_MAP			GENMASK(30, 28)
+
+/* Auxiliary Video Information (AVI) Infoframe */
+#define TOP_AVI_HEADER			0x024
+#define TOP_AVI_PKT00			0x028
+#define TOP_AVI_PKT01			0x02C
+#define TOP_AVI_PKT02			0x030
+#define TOP_AVI_PKT03			0x034
+#define TOP_AVI_PKT04			0x038
+#define TOP_AVI_PKT05			0x03C
+
+/* Audio Interface Infoframe */
+#define TOP_AIF_HEADER			0x040
+#define TOP_AIF_PKT00			0x044
+#define TOP_AIF_PKT01			0x048
+#define TOP_AIF_PKT02			0x04c
+#define TOP_AIF_PKT03			0x050
+
+/* Audio SPDIF Infoframe */
+#define TOP_SPDIF_HEADER		0x054
+#define TOP_SPDIF_PKT00			0x058
+#define TOP_SPDIF_PKT01			0x05c
+#define TOP_SPDIF_PKT02			0x060
+#define TOP_SPDIF_PKT03			0x064
+#define TOP_SPDIF_PKT04			0x068
+#define TOP_SPDIF_PKT05			0x06c
+#define TOP_SPDIF_PKT06			0x070
+#define TOP_SPDIF_PKT07			0x074
+
+/* Infoframes Configuration */
+#define TOP_INFO_EN			0x01c
+#define  AVI_EN				BIT(0)
+#define  SPD_EN				BIT(1)
+#define  AUD_EN				BIT(2)
+#define  CP_EN				BIT(5)
+#define  VSIF_EN			BIT(11)
+#define  AVI_EN_WR			BIT(16)
+#define  SPD_EN_WR			BIT(17)
+#define  AUD_EN_WR			BIT(18)
+#define  CP_EN_WR			BIT(21)
+#define  VSIF_EN_WR			BIT(27)
+#define TOP_INFO_RPT			0x020
+#define  AVI_RPT_EN			BIT(0)
+#define  SPD_RPT_EN			BIT(1)
+#define  AUD_RPT_EN			BIT(2)
+#define  CP_RPT_EN			BIT(5)
+#define  VSIF_RPT_EN			BIT(11)
+
+/* Vendor Specific Infoframe */
+#define TOP_VSIF_HEADER			0x174
+#define TOP_VSIF_PKT00			0x178
+#define TOP_VSIF_PKT01			0x17c
+#define TOP_VSIF_PKT02			0x180
+#define TOP_VSIF_PKT03			0x184
+#define TOP_VSIF_PKT04			0x188
+#define TOP_VSIF_PKT05			0x18c
+#define TOP_VSIF_PKT06			0x190
+#define TOP_VSIF_PKT07			0x194
+
+/* HDMI_TOP Misc */
+#define TOP_MISC_CTLR			0x1a4
+#define  DEEP_COLOR_ADD			BIT(4)
+
+/* Hardware interrupts */
+#define TOP_INT_STA00			0x1a8
+#define TOP_INT_ENABLE00		0x1b0
+#define  HTPLG_R_INT			BIT(0)
+#define  HTPLG_F_INT			BIT(1)
+#define  PORD_R_INT			BIT(2)
+#define  PORD_F_INT			BIT(3)
+#define  HDMI_VSYNC_INT			BIT(4)
+#define  HDMI_AUDIO_INT			BIT(5)
+#define  HDCP2X_RX_REAUTH_REQ_DDCM_INT	BIT(25)
+#define TOP_INT_ENABLE01		0x1b4
+#define TOP_INT_CLR00			0x1b8
+#define TOP_INT_CLR01			0x1bc
+
+
+/* Video Mute */
+#define TOP_VMUTE_CFG1			0x1c8
+#define  REG_VMUTE_EN			BIT(16)
+
+/* HDMI Audio IP */
+#define AIP_CTRL			0x400
+#define  CTS_SW_SEL			BIT(0)
+#define  CTS_REQ_EN			BIT(1)
+#define  MCLK_EN			BIT(2)
+#define  NO_MCLK_CTSGEN_SEL		BIT(3)
+#define  AUD_IN_EN			BIT(8)
+#define  AUD_SEL_OWRT			BIT(9)
+#define  SPDIF_EN			BIT(13)
+#define  HBRA_ON			BIT(14)
+#define  DSD_EN				BIT(15)
+#define  I2S_EN				GENMASK(19, 16)
+#define  HBR_FROM_SPDIF			BIT(20)
+#define  CTS_CAL_N4			BIT(23)
+#define  SPDIF_INTERNAL_MODULE		BIT(24)
+#define AIP_N_VAL			0x404
+#define AIP_CTS_SVAL			0x408
+#define AIP_SPDIF_CTRL			0x40c
+#define  WR_1UI_LOCK			BIT(0)
+#define  FS_OVERRIDE_WRITE		BIT(1)
+#define  WR_2UI_LOCK			BIT(2)
+#define  MAX_1UI_WRITE			GENMASK(15, 8)
+#define  MAX_2UI_SPDIF_WRITE		GENMASK(23, 16)
+#define  MAX_2UI_I2S_HI_WRITE		GENMASK(23, 20)
+#define   MAX_2UI_I2S_LFE_CC_SWAP	BIT(1)
+#define  MAX_2UI_I2S_LO_WRITE		GENMASK(19, 16)
+#define  AUD_ERR_THRESH			GENMASK(29, 24)
+#define  I2S2DSD_EN			BIT(30)
+#define AIP_I2S_CTRL			0x410
+#define  FIFO0_MAP			GENMASK(1, 0)
+#define  FIFO1_MAP			GENMASK(3, 2)
+#define  FIFO2_MAP			GENMASK(5, 4)
+#define  FIFO3_MAP			GENMASK(7, 6)
+#define  I2S_1ST_BIT_NOSHIFT		BIT(8)
+#define  I2S_DATA_DIR_LSB		BIT(9)
+#define  JUSTIFY_RIGHT			BIT(10)
+#define  WS_HIGH			BIT(11)
+#define  VBIT_COMPRESSED		BIT(12)
+#define  CBIT_ORDER_SAME		BIT(13)
+#define  SCK_EDGE_RISE			BIT(14)
+#define AIP_I2S_CHST0			0x414
+#define AIP_I2S_CHST1			0x418
+#define AIP_TXCTRL			0x424
+#define  RST4AUDIO			BIT(0)
+#define  RST4AUDIO_FIFO			BIT(1)
+#define  RST4AUDIO_ACR			BIT(2)
+#define  AUD_LAYOUT_1			BIT(4)
+#define  AUD_MUTE_FIFO_EN		BIT(5)
+#define  AUD_PACKET_DROP		BIT(6)
+#define  DSD_MUTE_EN			BIT(7)
+#define AIP_TPI_CTRL			0x428
+#define  TPI_AUDIO_LOOKUP_EN		BIT(2)
+
+/* Video downsampling configuration */
+#define VID_DOWNSAMPLE_CONFIG		0x8d0
+#define  C444_C422_CONFIG_ENABLE	BIT(0)
+#define  C422_C420_CONFIG_ENABLE	BIT(4)
+#define  C422_C420_CONFIG_BYPASS	BIT(5)
+#define  C422_C420_CONFIG_OUT_CB_OR_CR	BIT(6)
+#define VID_OUT_FORMAT			0x8fc
+#define  OUTPUT_FORMAT_DEMUX_420_ENABLE	BIT(10)
+
+/* HDCP registers */
+#define HDCP_TOP_CTRL			0xc00
+#define HDCP2X_CTRL_0			0xc20
+#define  HDCP2X_EN			BIT(0)
+#define  HDCP2X_ENCRYPT_EN		BIT(7)
+#define  HDCP2X_HPD_OVR			BIT(10)
+#define  HDCP2X_HPD_SW			BIT(11)
+#define HDCP2X_POL_CTRL			0xc54
+#define  HDCP2X_DIS_POLL_EN		BIT(16)
+#define HDCP1X_CTRL			0xcd0
+#define  HDCP1X_ENC_EN			BIT(6)
+
+/* HDMI DDC registers */
+#define HPD_DDC_CTRL			0xc08
+#define  HPD_DDC_DELAY_CNT		GENMASK(31, 16)
+#define  HPD_DDC_HPD_DBNC_EN		BIT(2)
+#define  HPD_DDC_PORD_DBNC_EN		BIT(3)
+#define DDC_CTRL			0xc10
+#define  DDC_CTRL_ADDR			GENMASK(7, 1)
+#define  DDC_CTRL_OFFSET		GENMASK(15, 8)
+#define  DDC_CTRL_DIN_CNT		GENMASK(25, 16)
+#define  DDC_CTRL_CMD			GENMASK(31, 28)
+#define SCDC_CTRL			0xc18
+#define  SCDC_DDC_SEGMENT		GENMASK(15, 8)
+#define HPD_DDC_STATUS			0xc60
+#define  HPD_STATE			GENMASK(1, 0)
+#define   HPD_STATE_CONNECTED		2
+#define  HPD_PIN_STA			BIT(4)
+#define  PORD_PIN_STA			BIT(5)
+#define  DDC_I2C_IN_PROG		BIT(13)
+#define  DDC_DATA_OUT			GENMASK(23, 16)
+#define SI2C_CTRL			0xcac
+#define  SI2C_WR			BIT(0)
+#define  SI2C_RD			BIT(1)
+#define  SI2C_CONFIRM_READ		BIT(2)
+#define  SI2C_WDATA			GENMASK(15, 8)
+#define  SI2C_ADDR			GENMASK(23, 16)
+
+/* HDCP DDC registers */
+#define HDCP2X_DDCM_STATUS		0xc68
+#define  DDC_I2C_NO_ACK			BIT(10)
+#define  DDC_I2C_BUS_LOW		BIT(11)
+
+/* HDMI TX registers */
+#define HDMITX_CONFIG_MT8188		0xea0
+#define HDMITX_CONFIG_MT8195		0x900
+#define  HDMI_YUV420_MODE		BIT(10)
+#define  HDMITX_SW_HPD			BIT(29)
+#define  HDMITX_SW_RSTB			BIT(31)
+
+/**
+ * enum mtk_hdmi_ddc_v2_cmds - DDC_CMD register commands
+ * @DDC_CMD_READ_NOACK:      Current address read with no ACK on last byte
+ * @DDC_CMD_READ:            Current address read with ACK on last byte
+ * @DDC_CMD_SEQ_READ_NOACK:  Sequential read with no ACK on last byte
+ * @DDC_CMD_SEQ_READ:        Sequential read with ACK on last byte
+ * @DDC_CMD_ENH_READ_NOACK:  Enhanced read with no ACK on last byte
+ * @DDC_CMD_ENH_READ:        Enhanced read with ACK on last byte
+ * @DDC_CMD_SEQ_WRITE_NOACK: Sequential write ignoring ACK on last byte
+ * @DDC_CMD_SEQ_WRITE:       Sequential write requiring ACK on last byte
+ * @DDC_CMD_RSVD:            Reserved for future use
+ * @DDC_CMD_CLEAR_FIFO:      Clear DDC I2C FIFO
+ * @DDC_CMD_CLOCK_SCL:       Start clocking DDC I2C SCL
+ * @DDC_CMD_ABORT_XFER:      Abort DDC I2C transaction
+ */
+enum mtk_hdmi_ddc_v2_cmds {
+	DDC_CMD_READ_NOACK = 0x0,
+	DDC_CMD_READ,
+	DDC_CMD_SEQ_READ_NOACK,
+	DDC_CMD_SEQ_READ,
+	DDC_CMD_ENH_READ_NOACK,
+	DDC_CMD_ENH_READ,
+	DDC_CMD_SEQ_WRITE_NOACK,
+	DDC_CMD_SEQ_WRITE = 0x07,
+	DDC_CMD_CLEAR_FIFO = 0x09,
+	DDC_CMD_CLOCK_SCL = 0x0a,
+	DDC_CMD_ABORT_XFER = 0x0f
+};
+
+#endif /* _MTK_HDMI_REGS_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
new file mode 100644
index 000000000000..05cbfc45be54
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
@@ -0,0 +1,1488 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek HDMI v2 IP driver
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre, SAS
+ * Copyright (c) 2024 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/suspend.h>
+#include <linux/timer.h>
+#include <linux/units.h>
+
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_hdmi_state_helper.h>
+#include <drm/display/drm_scdc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+
+#include "mtk_hdmi_common.h"
+#include "mtk_hdmi_regs_v2.h"
+
+#define MTK_HDMI_V2_CLOCK_MIN	27000
+#define MTK_HDMI_V2_CLOCK_MAX	594000
+
+#define HPD_PORD_HWIRQS		(HTPLG_R_INT | HTPLG_F_INT | PORD_F_INT | PORD_R_INT)
+
+enum mtk_hdmi_v2_clk_id {
+	MTK_HDMI_V2_CLK_HDCP_SEL,
+	MTK_HDMI_V2_CLK_HDCP_24M_SEL,
+	MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI,
+	MTK_HDMI_V2_CLK_HDMI_APB_SEL,
+	MTK_HDMI_V2_CLK_COUNT,
+};
+
+const char *const mtk_hdmi_v2_clk_names[MTK_HDMI_V2_CLK_COUNT] = {
+	[MTK_HDMI_V2_CLK_HDMI_APB_SEL] = "bus",
+	[MTK_HDMI_V2_CLK_HDCP_SEL] = "hdcp",
+	[MTK_HDMI_V2_CLK_HDCP_24M_SEL] = "hdcp24m",
+	[MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI] = "hdmi-split",
+};
+
+static inline void mtk_hdmi_v2_hwirq_disable(struct mtk_hdmi *hdmi)
+{
+	regmap_write(hdmi->regs, TOP_INT_ENABLE00, 0);
+	regmap_write(hdmi->regs, TOP_INT_ENABLE01, 0);
+}
+
+static inline void mtk_hdmi_v2_enable_hpd_pord_irq(struct mtk_hdmi *hdmi, bool enable)
+{
+	if (enable)
+		regmap_set_bits(hdmi->regs, TOP_INT_ENABLE00, HPD_PORD_HWIRQS);
+	else
+		regmap_clear_bits(hdmi->regs, TOP_INT_ENABLE00, HPD_PORD_HWIRQS);
+}
+
+static inline void mtk_hdmi_v2_clear_hpd_pord_irq(struct mtk_hdmi *hdmi)
+{
+	regmap_set_bits(hdmi->regs, TOP_INT_CLR00, HPD_PORD_HWIRQS);
+	regmap_clear_bits(hdmi->regs, TOP_INT_CLR00, HPD_PORD_HWIRQS);
+}
+
+static inline void mtk_hdmi_v2_set_sw_hpd(struct mtk_hdmi *hdmi, bool enable)
+{
+	if (enable) {
+		regmap_set_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_HPD);
+		regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_OVR);
+		regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_SW);
+	} else {
+		regmap_clear_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_OVR);
+		regmap_clear_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_SW);
+		regmap_clear_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_HPD);
+	}
+}
+
+static void mtk_hdmi_v2_disable_hdcp_encrypt(struct mtk_hdmi *hdmi)
+{
+	regmap_clear_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_ENCRYPT_EN);
+	regmap_clear_bits(hdmi->regs, HDCP1X_CTRL, HDCP1X_ENC_EN);
+}
+
+static inline void mtk_hdmi_v2_enable_scrambling(struct mtk_hdmi *hdmi, bool enable)
+{
+	struct drm_scdc *scdc = &hdmi->curr_conn->display_info.hdmi.scdc;
+
+	if (enable)
+		regmap_set_bits(hdmi->regs, TOP_CFG00, SCR_ON | HDMI2_ON);
+	else
+		regmap_clear_bits(hdmi->regs, TOP_CFG00, SCR_ON | HDMI2_ON);
+
+	if (scdc->supported) {
+		if (scdc->scrambling.supported)
+			drm_scdc_set_scrambling(hdmi->curr_conn, enable);
+		drm_scdc_set_high_tmds_clock_ratio(hdmi->curr_conn, enable);
+	}
+}
+
+static void mtk_hdmi_v2_hw_vid_mute(struct mtk_hdmi *hdmi, bool enable)
+{
+	/* If enabled, sends a black image */
+	if (enable)
+		regmap_set_bits(hdmi->regs, TOP_VMUTE_CFG1, REG_VMUTE_EN);
+	else
+		regmap_clear_bits(hdmi->regs, TOP_VMUTE_CFG1, REG_VMUTE_EN);
+}
+
+static void mtk_hdmi_v2_hw_aud_mute(struct mtk_hdmi *hdmi, bool enable)
+{
+	u32 aip, val;
+
+	if (!enable) {
+		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, AUD_MUTE_FIFO_EN);
+		return;
+	}
+
+	regmap_read(hdmi->regs, AIP_CTRL, &aip);
+
+	val = AUD_MUTE_FIFO_EN;
+	if (aip & DSD_EN)
+		val |= DSD_MUTE_EN;
+
+	regmap_update_bits(hdmi->regs, AIP_TXCTRL, val, val);
+}
+
+static void mtk_hdmi_v2_hw_reset(struct mtk_hdmi *hdmi)
+{
+	regmap_clear_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_RSTB);
+	udelay(5);
+	regmap_set_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_RSTB);
+}
+
+static inline u32 mtk_hdmi_v2_format_hw_packet(const u8 *buffer, u8 len)
+{
+	unsigned short i;
+	u32 val = 0;
+
+	for (i = 0; i < len; i++)
+		val |= buffer[i] << (i * 8);
+
+	return val;
+}
+
+static void mtk_hdmi_v2_hw_write_audio_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
+{
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
+
+	regmap_write(hdmi->regs, TOP_AIF_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
+	regmap_write(hdmi->regs, TOP_AIF_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 3));
+	regmap_write(hdmi->regs, TOP_AIF_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 2));
+	regmap_write(hdmi->regs, TOP_AIF_PKT02, 0);
+	regmap_write(hdmi->regs, TOP_AIF_PKT03, 0);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
+}
+
+static void mtk_hdmi_v2_hw_write_avi_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
+{
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
+
+	regmap_write(hdmi->regs, TOP_AVI_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
+	regmap_write(hdmi->regs, TOP_AVI_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 4));
+	regmap_write(hdmi->regs, TOP_AVI_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 3));
+	regmap_write(hdmi->regs, TOP_AVI_PKT02, mtk_hdmi_v2_format_hw_packet(&buffer[10], 4));
+	regmap_write(hdmi->regs, TOP_AVI_PKT03, mtk_hdmi_v2_format_hw_packet(&buffer[14], 3));
+	regmap_write(hdmi->regs, TOP_AVI_PKT04, 0);
+	regmap_write(hdmi->regs, TOP_AVI_PKT05, 0);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
+}
+
+static void mtk_hdmi_v2_hw_write_spd_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
+{
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
+
+	regmap_write(hdmi->regs, TOP_SPDIF_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 4));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 3));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT02, mtk_hdmi_v2_format_hw_packet(&buffer[10], 4));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT03, mtk_hdmi_v2_format_hw_packet(&buffer[14], 3));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT04, mtk_hdmi_v2_format_hw_packet(&buffer[17], 4));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT05, mtk_hdmi_v2_format_hw_packet(&buffer[21], 3));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT06, mtk_hdmi_v2_format_hw_packet(&buffer[24], 4));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT07, buffer[28]);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
+}
+
+static void mtk_hdmi_v2_hw_write_vendor_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
+{
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
+
+	regmap_write(hdmi->regs, TOP_VSIF_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
+	regmap_write(hdmi->regs, TOP_VSIF_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 4));
+	regmap_write(hdmi->regs, TOP_VSIF_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 2));
+	regmap_write(hdmi->regs, TOP_VSIF_PKT02, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT03, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT04, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT05, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT06, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT07, 0);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
+}
+
+static void mtk_hdmi_yuv420_downsampling(struct mtk_hdmi *hdmi, bool enable)
+{
+	u32 val;
+
+	regmap_read(hdmi->regs, VID_DOWNSAMPLE_CONFIG, &val);
+
+	if (enable) {
+		regmap_set_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg,
+				HDMI_YUV420_MODE | HDMITX_SW_HPD);
+
+		val |= C444_C422_CONFIG_ENABLE | C422_C420_CONFIG_ENABLE;
+		val |= C422_C420_CONFIG_OUT_CB_OR_CR;
+		val &= ~C422_C420_CONFIG_BYPASS;
+		regmap_write(hdmi->regs, VID_DOWNSAMPLE_CONFIG, val);
+
+		regmap_set_bits(hdmi->regs, VID_OUT_FORMAT, OUTPUT_FORMAT_DEMUX_420_ENABLE);
+	} else {
+		regmap_update_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg,
+				   HDMI_YUV420_MODE | HDMITX_SW_HPD, HDMITX_SW_HPD);
+
+		val &= ~(C444_C422_CONFIG_ENABLE | C422_C420_CONFIG_ENABLE);
+		val &= ~C422_C420_CONFIG_OUT_CB_OR_CR;
+		val |= C422_C420_CONFIG_BYPASS;
+		regmap_write(hdmi->regs, VID_DOWNSAMPLE_CONFIG, val);
+
+		regmap_clear_bits(hdmi->regs, VID_OUT_FORMAT, OUTPUT_FORMAT_DEMUX_420_ENABLE);
+	}
+}
+
+static int mtk_hdmi_v2_setup_audio_infoframe(struct mtk_hdmi *hdmi)
+{
+	struct hdmi_codec_params *params = &hdmi->aud_param.codec_params;
+	struct hdmi_audio_infoframe frame;
+	u8 buffer[14];
+	ssize_t ret;
+
+	memcpy(&frame, &params->cea, sizeof(frame));
+
+	ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
+	if (ret < 0)
+		return ret;
+
+	mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
+
+	return 0;
+}
+
+static inline void mtk_hdmi_v2_hw_reset_av_mute_regs(struct mtk_hdmi *hdmi)
+{
+	/* GCP packet */
+	regmap_clear_bits(hdmi->regs, TOP_CFG01, CP_CLR_MUTE_EN | CP_SET_MUTE_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, CP_RPT_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, CP_EN | CP_EN_WR);
+}
+
+static inline void mtk_hdmi_v2_hw_av_mute(struct mtk_hdmi *hdmi, bool mute)
+{
+	mtk_hdmi_v2_hw_reset_av_mute_regs(hdmi);
+
+	if (mute)
+		regmap_set_bits(hdmi->regs, TOP_CFG01, CP_SET_MUTE_EN);
+	else
+		regmap_set_bits(hdmi->regs, TOP_CFG01, CP_CLR_MUTE_EN);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, CP_RPT_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, CP_EN | CP_EN_WR);
+}
+
+static void mtk_hdmi_v2_hw_ncts_enable(struct mtk_hdmi *hdmi, bool enable)
+{
+	if (enable)
+		regmap_set_bits(hdmi->regs, AIP_CTRL, CTS_SW_SEL);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_CTRL, CTS_SW_SEL);
+}
+
+static void mtk_hdmi_v2_hw_aud_set_channel_status(struct mtk_hdmi *hdmi, u8 *ch_status)
+{
+	/* Only the first 5 to 7 bytes of Channel Status contain useful information */
+	regmap_write(hdmi->regs, AIP_I2S_CHST0, mtk_hdmi_v2_format_hw_packet(&ch_status[0], 4));
+	regmap_write(hdmi->regs, AIP_I2S_CHST1, mtk_hdmi_v2_format_hw_packet(&ch_status[4], 3));
+}
+
+static void mtk_hdmi_v2_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
+				     unsigned int sample_rate,
+				     unsigned int clock)
+{
+	unsigned int n, cts;
+	int ret;
+
+	ret = mtk_hdmi_get_ncts(sample_rate, clock, &n, &cts);
+	if (ret) {
+		dev_err(hdmi->dev, "Invalid sample rate: %u\n", sample_rate);
+		return;
+	}
+
+	regmap_write(hdmi->regs, AIP_N_VAL, n);
+	regmap_write(hdmi->regs, AIP_CTS_SVAL, cts);
+}
+
+static void mtk_hdmi_v2_hw_aud_enable(struct mtk_hdmi *hdmi, bool enable)
+{
+	if (enable)
+		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, AUD_PACKET_DROP);
+	else
+		regmap_set_bits(hdmi->regs, AIP_TXCTRL, AUD_PACKET_DROP);
+}
+
+static u32 mtk_hdmi_v2_aud_output_channel_map(u8 sd0, u8 sd1, u8 sd2, u8 sd3,
+					   u8 sd4, u8 sd5, u8 sd6, u8 sd7)
+{
+	u32 val;
+
+	/*
+	 * Each of the Output Channels (0-7) can be mapped to get their input
+	 * from any of the available Input Channels (0-7): this function
+	 * takes input channel numbers and formats a value that must then
+	 * be written to the TOP_AUD_MAP hardware register by the caller.
+	 */
+	val = FIELD_PREP(SD0_MAP, sd0) | FIELD_PREP(SD1_MAP, sd1);
+	val |= FIELD_PREP(SD2_MAP, sd2) | FIELD_PREP(SD3_MAP, sd3);
+	val |= FIELD_PREP(SD4_MAP, sd4) | FIELD_PREP(SD5_MAP, sd5);
+	val |= FIELD_PREP(SD6_MAP, sd6) | FIELD_PREP(SD7_MAP, sd7);
+
+	return val;
+}
+
+static void mtk_hdmi_audio_dsd_config(struct mtk_hdmi *hdmi,
+				      unsigned char chnum, bool dsd_bypass)
+{
+	u32 channel_map;
+
+	regmap_update_bits(hdmi->regs, AIP_CTRL, SPDIF_EN | DSD_EN | HBRA_ON, DSD_EN);
+	regmap_set_bits(hdmi->regs, AIP_TXCTRL, DSD_MUTE_EN);
+
+	if (dsd_bypass)
+		channel_map = mtk_hdmi_v2_aud_output_channel_map(0, 2, 4, 6, 1, 3, 5, 7);
+	else
+		channel_map = mtk_hdmi_v2_aud_output_channel_map(0, 5, 1, 0, 3, 2, 4, 0);
+
+	regmap_write(hdmi->regs, TOP_AUD_MAP, channel_map);
+	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, I2S2DSD_EN);
+}
+
+static inline void mtk_hdmi_v2_hw_i2s_fifo_map(struct mtk_hdmi *hdmi, u32 fifo_mapping)
+{
+	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL,
+			   FIFO0_MAP | FIFO1_MAP | FIFO2_MAP | FIFO3_MAP, fifo_mapping);
+}
+
+static inline void mtk_hdmi_v2_hw_i2s_ch_number(struct mtk_hdmi *hdmi, u8 chnum)
+{
+	regmap_update_bits(hdmi->regs, AIP_CTRL, I2S_EN, FIELD_PREP(I2S_EN, chnum));
+}
+
+static void mtk_hdmi_v2_hw_i2s_ch_mapping(struct mtk_hdmi *hdmi, u8 chnum, u8 mapping)
+{
+	u32 fifo_map;
+	u8 bdata;
+
+	switch (chnum) {
+	default:
+	case 2:
+		bdata = 0x1;
+		break;
+	case 3:
+		bdata = 0x3;
+		break;
+	case 6:
+		if (mapping == 0x0e) {
+			bdata = 0xf;
+			break;
+		}
+		fallthrough;
+	case 5:
+		bdata = 0x7;
+		break;
+	case 7:
+	case 8:
+		bdata = 0xf;
+		break;
+	}
+
+	/* Assign default FIFO mapping: SD0 to FIFO0, SD1 to FIFO1, etc. */
+	fifo_map = FIELD_PREP(FIFO0_MAP, 0) | FIELD_PREP(FIFO1_MAP, 1);
+	fifo_map |= FIELD_PREP(FIFO2_MAP, 2) | FIELD_PREP(FIFO3_MAP, 3);
+	mtk_hdmi_v2_hw_i2s_fifo_map(hdmi, fifo_map);
+	mtk_hdmi_v2_hw_i2s_ch_number(hdmi, bdata);
+
+	/*
+	 * Set HDMI Audio packet layout indicator:
+	 * Layout 0 is for two channels
+	 * Layout 1 is for up to eight channels
+	 */
+	if (chnum == 2)
+		regmap_set_bits(hdmi->regs, AIP_TXCTRL, AUD_LAYOUT_1);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, AUD_LAYOUT_1);
+}
+
+static void mtk_hdmi_i2s_data_fmt(struct mtk_hdmi *hdmi, unsigned char fmt)
+{
+	u32 val;
+
+	regmap_read(hdmi->regs, AIP_I2S_CTRL, &val);
+	val &= ~(WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT);
+
+	switch (fmt) {
+	case HDMI_I2S_MODE_RJT_24BIT:
+	case HDMI_I2S_MODE_RJT_16BIT:
+		val |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT);
+		break;
+	case HDMI_I2S_MODE_LJT_24BIT:
+	case HDMI_I2S_MODE_LJT_16BIT:
+		val |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT);
+		break;
+	case HDMI_I2S_MODE_I2S_24BIT:
+	case HDMI_I2S_MODE_I2S_16BIT:
+	default:
+		break;
+	}
+
+	regmap_write(hdmi->regs, AIP_I2S_CTRL, val);
+}
+
+static inline void mtk_hdmi_i2s_sck_edge_rise(struct mtk_hdmi *hdmi, bool rise)
+{
+	if (rise)
+		regmap_set_bits(hdmi->regs, AIP_I2S_CTRL, SCK_EDGE_RISE);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_I2S_CTRL, SCK_EDGE_RISE);
+}
+
+static inline void mtk_hdmi_i2s_cbit_order(struct mtk_hdmi *hdmi, unsigned int cbit)
+{
+	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL, CBIT_ORDER_SAME, cbit);
+}
+
+static inline void mtk_hdmi_i2s_vbit(struct mtk_hdmi *hdmi, unsigned int vbit)
+{
+	/* V bit: 0 for PCM, 1 for Compressed data */
+	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL, VBIT_COMPRESSED, vbit);
+}
+
+static inline void mtk_hdmi_i2s_data_direction(struct mtk_hdmi *hdmi, unsigned int is_lsb)
+{
+	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL, I2S_DATA_DIR_LSB, is_lsb);
+}
+
+static inline void mtk_hdmi_v2_hw_audio_type(struct mtk_hdmi *hdmi, unsigned int spdif_i2s)
+{
+	regmap_update_bits(hdmi->regs, AIP_CTRL, SPDIF_EN, FIELD_PREP(SPDIF_EN, spdif_i2s));
+}
+
+static u8 mtk_hdmi_v2_get_i2s_ch_mapping(struct mtk_hdmi *hdmi, u8 channel_type)
+{
+	switch (channel_type) {
+	case HDMI_AUD_CHAN_TYPE_1_1:
+	case HDMI_AUD_CHAN_TYPE_2_1:
+		return 0x01;
+	case HDMI_AUD_CHAN_TYPE_3_0:
+		return 0x02;
+	case HDMI_AUD_CHAN_TYPE_3_1:
+		return 0x03;
+	case HDMI_AUD_CHAN_TYPE_3_0_LRS:
+	case HDMI_AUD_CHAN_TYPE_4_0:
+		return 0x08;
+	case HDMI_AUD_CHAN_TYPE_5_1:
+		return 0x0b;
+	case HDMI_AUD_CHAN_TYPE_4_1_CLRS:
+	case HDMI_AUD_CHAN_TYPE_6_0:
+	case HDMI_AUD_CHAN_TYPE_6_0_CS:
+	case HDMI_AUD_CHAN_TYPE_6_0_CH:
+	case HDMI_AUD_CHAN_TYPE_6_0_OH:
+	case HDMI_AUD_CHAN_TYPE_6_0_CHR:
+		return 0x0e;
+	case HDMI_AUD_CHAN_TYPE_1_0:
+	case HDMI_AUD_CHAN_TYPE_2_0:
+	case HDMI_AUD_CHAN_TYPE_3_1_LRS:
+	case HDMI_AUD_CHAN_TYPE_4_1:
+	case HDMI_AUD_CHAN_TYPE_5_0:
+	case HDMI_AUD_CHAN_TYPE_4_0_CLRS:
+	case HDMI_AUD_CHAN_TYPE_6_1:
+	case HDMI_AUD_CHAN_TYPE_6_1_CS:
+	case HDMI_AUD_CHAN_TYPE_6_1_CH:
+	case HDMI_AUD_CHAN_TYPE_6_1_OH:
+	case HDMI_AUD_CHAN_TYPE_6_1_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_0:
+	case HDMI_AUD_CHAN_TYPE_7_0_LH_RH:
+	case HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR:
+	case HDMI_AUD_CHAN_TYPE_7_0_LC_RC:
+	case HDMI_AUD_CHAN_TYPE_7_0_LW_RW:
+	case HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD:
+	case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS:
+	case HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS:
+	case HDMI_AUD_CHAN_TYPE_7_0_CS_CH:
+	case HDMI_AUD_CHAN_TYPE_7_0_CS_OH:
+	case HDMI_AUD_CHAN_TYPE_7_0_CS_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_0_CH_OH:
+	case HDMI_AUD_CHAN_TYPE_7_0_CH_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_0_OH_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR:
+	case HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS:
+	case HDMI_AUD_CHAN_TYPE_7_1:
+	case HDMI_AUD_CHAN_TYPE_7_1_LH_RH:
+	case HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR:
+	case HDMI_AUD_CHAN_TYPE_7_1_LC_RC:
+	case HDMI_AUD_CHAN_TYPE_7_1_LW_RW:
+	case HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD:
+	case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS:
+	case HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS:
+	case HDMI_AUD_CHAN_TYPE_7_1_CS_CH:
+	case HDMI_AUD_CHAN_TYPE_7_1_CS_OH:
+	case HDMI_AUD_CHAN_TYPE_7_1_CS_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_1_CH_OH:
+	case HDMI_AUD_CHAN_TYPE_7_1_CH_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_1_OH_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR:
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
+static inline void mtk_hdmi_v2_hw_i2s_ch_swap(struct mtk_hdmi *hdmi, unsigned char swapbit)
+{
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_2UI_I2S_HI_WRITE,
+			   FIELD_PREP(MAX_2UI_I2S_HI_WRITE, swapbit));
+}
+
+static void mtk_hdmi_hbr_config(struct mtk_hdmi *hdmi, bool dsd_bypass)
+{
+	const u32 hbr_mask = SPDIF_EN | DSD_EN | HBRA_ON;
+
+	if (dsd_bypass) {
+		regmap_update_bits(hdmi->regs, AIP_CTRL, hbr_mask, HBRA_ON);
+		regmap_set_bits(hdmi->regs, AIP_CTRL, I2S_EN);
+	} else {
+		regmap_update_bits(hdmi->regs, AIP_CTRL, hbr_mask, SPDIF_EN);
+		regmap_set_bits(hdmi->regs, AIP_CTRL, SPDIF_INTERNAL_MODULE);
+		regmap_set_bits(hdmi->regs, AIP_CTRL, HBR_FROM_SPDIF);
+		regmap_set_bits(hdmi->regs, AIP_CTRL, CTS_CAL_N4);
+	}
+}
+
+static inline void mtk_hdmi_v2_hw_spdif_config(struct mtk_hdmi *hdmi)
+{
+	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, WR_1UI_LOCK);
+	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, FS_OVERRIDE_WRITE);
+	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, WR_2UI_LOCK);
+
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_1UI_WRITE,
+			   FIELD_PREP(MAX_1UI_WRITE, 4));
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_2UI_SPDIF_WRITE,
+			   FIELD_PREP(MAX_2UI_SPDIF_WRITE, 9));
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, AUD_ERR_THRESH,
+			   FIELD_PREP(AUD_ERR_THRESH, 4));
+
+	regmap_set_bits(hdmi->regs, AIP_SPDIF_CTRL, I2S2DSD_EN);
+}
+
+static void mtk_hdmi_v2_aud_set_input(struct mtk_hdmi *hdmi)
+{
+	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
+	u8 i2s_ch_map;
+	u32 out_ch_map;
+
+	/* Write the default output channel map. CH0 maps to SD0, CH1 maps to SD1, etc */
+	out_ch_map = mtk_hdmi_v2_aud_output_channel_map(0, 1, 2, 3, 4, 5, 6, 7);
+	regmap_write(hdmi->regs, TOP_AUD_MAP, out_ch_map);
+
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_2UI_I2S_HI_WRITE, 0);
+	regmap_clear_bits(hdmi->regs, AIP_CTRL,
+			  SPDIF_EN | DSD_EN | HBRA_ON | CTS_CAL_N4 |
+			  HBR_FROM_SPDIF | SPDIF_INTERNAL_MODULE);
+	regmap_clear_bits(hdmi->regs, AIP_TXCTRL, DSD_MUTE_EN | AUD_LAYOUT_1);
+
+	if (aud_param->aud_input_type == HDMI_AUD_INPUT_I2S) {
+		switch (aud_param->aud_codec) {
+		case HDMI_AUDIO_CODING_TYPE_DTS_HD:
+		case HDMI_AUDIO_CODING_TYPE_MLP:
+			mtk_hdmi_i2s_data_fmt(hdmi, aud_param->aud_i2s_fmt);
+			mtk_hdmi_hbr_config(hdmi, true);
+			break;
+		case HDMI_AUDIO_CODING_TYPE_DSD:
+			mtk_hdmi_audio_dsd_config(hdmi, aud_param->codec_params.channels, 0);
+			mtk_hdmi_v2_hw_i2s_ch_mapping(hdmi, aud_param->codec_params.channels, 1);
+			break;
+		default:
+			mtk_hdmi_i2s_data_fmt(hdmi, aud_param->aud_i2s_fmt);
+			mtk_hdmi_i2s_sck_edge_rise(hdmi, true);
+			mtk_hdmi_i2s_cbit_order(hdmi, CBIT_ORDER_SAME);
+			mtk_hdmi_i2s_vbit(hdmi, 0); /* PCM data */
+			mtk_hdmi_i2s_data_direction(hdmi, 0); /* MSB first */
+			mtk_hdmi_v2_hw_audio_type(hdmi, HDMI_AUD_INPUT_I2S);
+			i2s_ch_map = mtk_hdmi_v2_get_i2s_ch_mapping(hdmi,
+						aud_param->aud_input_chan_type);
+			mtk_hdmi_v2_hw_i2s_ch_mapping(hdmi,
+						aud_param->codec_params.channels, i2s_ch_map);
+			mtk_hdmi_v2_hw_i2s_ch_swap(hdmi, MAX_2UI_I2S_LFE_CC_SWAP);
+		}
+	} else {
+		if (aud_param->codec_params.sample_rate == 768000 &&
+		    (aud_param->aud_codec == HDMI_AUDIO_CODING_TYPE_DTS_HD ||
+		     aud_param->aud_codec == HDMI_AUDIO_CODING_TYPE_MLP)) {
+			mtk_hdmi_hbr_config(hdmi, false);
+		} else {
+			mtk_hdmi_v2_hw_spdif_config(hdmi);
+			mtk_hdmi_v2_hw_i2s_ch_mapping(hdmi, 2, 0);
+		}
+	}
+}
+
+static void mtk_hdmi_v2_aud_set_sw_ncts(struct mtk_hdmi *hdmi,
+				     struct drm_display_mode *display_mode)
+{
+	mtk_hdmi_v2_hw_ncts_enable(hdmi, false);
+	mtk_hdmi_v2_hw_aud_set_ncts(hdmi, hdmi->aud_param.codec_params.sample_rate,
+				 display_mode->clock);
+}
+
+static inline void mtk_hdmi_v2_hw_audio_input_enable(struct mtk_hdmi *hdmi,
+						  unsigned int enable)
+{
+	if (enable)
+		regmap_set_bits(hdmi->regs, AIP_CTRL, AUD_IN_EN);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_CTRL, AUD_IN_EN);
+}
+
+static void mtk_hdmi_v2_aip_ctrl_init(struct mtk_hdmi *hdmi)
+{
+	regmap_set_bits(hdmi->regs, AIP_CTRL,
+			AUD_SEL_OWRT | NO_MCLK_CTSGEN_SEL | MCLK_EN | CTS_REQ_EN);
+	regmap_clear_bits(hdmi->regs, AIP_TPI_CTRL, TPI_AUDIO_LOOKUP_EN);
+}
+
+static void mtk_hdmi_v2_audio_reset(struct mtk_hdmi *hdmi, bool reset)
+{
+	const u32 arst_bits = RST4AUDIO | RST4AUDIO_FIFO | RST4AUDIO_ACR;
+
+	if (reset)
+		regmap_set_bits(hdmi->regs, AIP_TXCTRL, arst_bits);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, arst_bits);
+}
+
+static void mtk_hdmi_v2_aud_output_config(struct mtk_hdmi *hdmi,
+				       struct drm_display_mode *display_mode)
+{
+	mtk_hdmi_v2_hw_aud_mute(hdmi, true);
+	mtk_hdmi_v2_hw_aud_enable(hdmi, false);
+	mtk_hdmi_v2_audio_reset(hdmi, true);
+	mtk_hdmi_v2_aip_ctrl_init(hdmi);
+	mtk_hdmi_v2_aud_set_input(hdmi);
+	mtk_hdmi_v2_hw_aud_set_channel_status(hdmi, hdmi->aud_param.codec_params.iec.status);
+	mtk_hdmi_v2_setup_audio_infoframe(hdmi);
+	mtk_hdmi_v2_hw_audio_input_enable(hdmi, true);
+	mtk_hdmi_v2_audio_reset(hdmi, false);
+	mtk_hdmi_v2_aud_set_sw_ncts(hdmi, display_mode);
+
+	/* Wait for the HW to apply settings */
+	usleep_range(25, 50);
+
+	mtk_hdmi_v2_hw_ncts_enable(hdmi, true);
+	mtk_hdmi_v2_hw_aud_enable(hdmi, true);
+	mtk_hdmi_v2_hw_aud_mute(hdmi, false);
+}
+
+static void mtk_hdmi_v2_change_video_resolution(struct mtk_hdmi *hdmi)
+{
+	mtk_hdmi_v2_hw_reset(hdmi);
+	mtk_hdmi_v2_set_sw_hpd(hdmi, true);
+	udelay(2);
+
+	regmap_write(hdmi->regs, HDCP_TOP_CTRL, 0);
+
+	/* Enable HDCP reauthentication interrupt */
+	regmap_set_bits(hdmi->regs, TOP_INT_ENABLE00, HDCP2X_RX_REAUTH_REQ_DDCM_INT);
+
+	/* Enable hotplug and pord interrupts */
+	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
+
+	/* Force enabling HDCP HPD */
+	regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_OVR);
+	regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_SW);
+
+	/* Set 8 bits per pixel */
+	regmap_update_bits(hdmi->regs, TOP_CFG00, TMDS_PACK_MODE,
+			   FIELD_PREP(TMDS_PACK_MODE, TMDS_PACK_MODE_8BPP));
+	/* Disable generating deepcolor packets */
+	regmap_clear_bits(hdmi->regs, TOP_CFG00, DEEPCOLOR_PKT_EN);
+	/* Disable adding deepcolor information to the general packet */
+	regmap_clear_bits(hdmi->regs, TOP_MISC_CTLR, DEEP_COLOR_ADD);
+
+	if (hdmi->dvi_mode)
+		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_MODE_HDMI);
+	else
+		regmap_set_bits(hdmi->regs, TOP_CFG00, HDMI_MODE_HDMI);
+
+	udelay(5);
+	mtk_hdmi_v2_hw_vid_mute(hdmi, true);
+	mtk_hdmi_v2_hw_aud_mute(hdmi, true);
+	mtk_hdmi_v2_hw_av_mute(hdmi, false);
+
+	regmap_update_bits(hdmi->regs, TOP_CFG01,
+			   NULL_PKT_VSYNC_HIGH_EN | NULL_PKT_EN, NULL_PKT_VSYNC_HIGH_EN);
+	usleep_range(100, 150);
+
+	/* Enable scrambling if tmds clock is 340MHz or more */
+	mtk_hdmi_v2_enable_scrambling(hdmi, hdmi->mode.clock >= 340 * KILO);
+
+	/* Disable YUV420 downsampling */
+	mtk_hdmi_yuv420_downsampling(hdmi, false);
+}
+
+static void mtk_hdmi_v2_output_set_display_mode(struct mtk_hdmi *hdmi,
+						struct drm_display_mode *mode)
+{
+	union phy_configure_opts opts = {
+		.dp = { .link_rate = hdmi->mode.clock * KILO }
+	};
+	int ret;
+
+	ret = phy_configure(hdmi->phy, &opts);
+	if (ret)
+		dev_err(hdmi->dev, "Setting clock=%d failed: %d", mode->clock, ret);
+
+	mtk_hdmi_v2_change_video_resolution(hdmi);
+	mtk_hdmi_v2_aud_output_config(hdmi, mode);
+}
+
+static int mtk_hdmi_v2_clk_enable(struct mtk_hdmi *hdmi)
+{
+	int ret;
+
+	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_24M_SEL]);
+	if (ret)
+		goto disable_hdcp_clk;
+
+	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_HDMI_APB_SEL]);
+	if (ret)
+		goto disable_hdcp_24m_clk;
+
+	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI]);
+	if (ret)
+		goto disable_bus_clk;
+
+	return 0;
+
+disable_bus_clk:
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDMI_APB_SEL]);
+disable_hdcp_24m_clk:
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_24M_SEL]);
+disable_hdcp_clk:
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
+
+	return ret;
+}
+
+static void mtk_hdmi_v2_clk_disable(struct mtk_hdmi *hdmi)
+{
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI]);
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDMI_APB_SEL]);
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_24M_SEL]);
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
+}
+
+static void mtk_hdmi_hpd_event(enum hdmi_hpd_state hpd, struct device *dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	if (hdmi && hdmi->bridge.encoder && hdmi->bridge.encoder->dev)
+		drm_helper_hpd_irq_event(hdmi->bridge.encoder->dev);
+}
+
+static enum hdmi_hpd_state mtk_hdmi_v2_hpd_pord_status(struct mtk_hdmi *hdmi)
+{
+	u8 hpd_pin_sta, pord_pin_sta;
+	u32 hpd_status;
+
+	regmap_read(hdmi->regs, HPD_DDC_STATUS, &hpd_status);
+	hpd_pin_sta = FIELD_GET(HPD_PIN_STA, hpd_status);
+	pord_pin_sta = FIELD_GET(PORD_PIN_STA, hpd_status);
+
+	if (hpd_pin_sta && pord_pin_sta)
+		return HDMI_PLUG_IN_AND_SINK_POWER_ON;
+	else if (hpd_pin_sta)
+		return HDMI_PLUG_IN_ONLY;
+	else
+		return HDMI_PLUG_OUT;
+}
+
+static irqreturn_t mtk_hdmi_v2_isr(int irq, void *arg)
+{
+	struct mtk_hdmi *hdmi = arg;
+	unsigned int irq_sta;
+	int ret = IRQ_HANDLED;
+
+	regmap_read(hdmi->regs, TOP_INT_STA00, &irq_sta);
+
+	/* Handle Hotplug Detection interrupt */
+	if (irq_sta & (HTPLG_R_INT | HTPLG_F_INT | PORD_F_INT | PORD_R_INT)) {
+		mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, false);
+		ret = IRQ_WAKE_THREAD;
+	}
+
+	/*
+	 * Clear all 32 + 19 interrupts in CLR00 and CLR01: this is important
+	 * to avoid unwanted retriggering of any interrupts
+	 */
+	regmap_write(hdmi->regs, TOP_INT_CLR00, GENMASK(31, 0));
+	regmap_write(hdmi->regs, TOP_INT_CLR01, GENMASK(18, 0));
+
+	/* Restore interrupt clearing registers to zero */
+	regmap_write(hdmi->regs, TOP_INT_CLR00, 0);
+	regmap_write(hdmi->regs, TOP_INT_CLR01, 0);
+
+	return ret;
+}
+
+static irqreturn_t __mtk_hdmi_v2_isr_thread(struct mtk_hdmi *hdmi)
+{
+	enum hdmi_hpd_state hpd;
+
+	hpd = mtk_hdmi_v2_hpd_pord_status(hdmi);
+	if (hpd != hdmi->hpd) {
+		hdmi->hpd = hpd;
+		mtk_hdmi_hpd_event(hpd, hdmi->dev);
+	}
+
+	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_hdmi_v2_isr_thread(int irq, void *arg)
+{
+	struct mtk_hdmi *hdmi = arg;
+
+	/*
+	 * Debounce HDMI monitor HPD status.
+	 * Empirical testing shows that 30ms is enough wait
+	 */
+	msleep(30);
+
+	return __mtk_hdmi_v2_isr_thread(hdmi);
+}
+
+static int mtk_hdmi_v2_enable(struct mtk_hdmi *hdmi)
+{
+	int ret;
+
+	ret = pm_runtime_resume_and_get(hdmi->dev);
+	if (ret) {
+		dev_err(hdmi->dev, "Cannot resume HDMI\n");
+		return ret;
+	}
+
+	mtk_hdmi_v2_clk_enable(hdmi);
+	mtk_hdmi_v2_hw_reset(hdmi);
+	mtk_hdmi_v2_set_sw_hpd(hdmi, true);
+
+	return 0;
+}
+
+/*
+ * Bridge callbacks
+ */
+
+static int mtk_hdmi_v2_bridge_attach(struct drm_bridge *bridge,
+				     enum drm_bridge_attach_flags flags)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+	int ret;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		DRM_ERROR("The flag DRM_BRIDGE_ATTACH_NO_CONNECTOR must be supplied\n");
+		return -EINVAL;
+	}
+	if (hdmi->next_bridge) {
+		ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge, bridge, flags);
+		if (ret)
+			return ret;
+	}
+
+	/* Enable the controller at attach time for HPD/Pord feedback */
+	ret = mtk_hdmi_v2_enable(hdmi);
+	if (ret)
+		return ret;
+
+	/* Enable Hotplug and Pord pins internal debouncing */
+	regmap_set_bits(hdmi->regs, HPD_DDC_CTRL,
+			HPD_DDC_HPD_DBNC_EN | HPD_DDC_PORD_DBNC_EN);
+
+	irq_clear_status_flags(hdmi->irq, IRQ_NOAUTOEN);
+	enable_irq(hdmi->irq);
+
+	/*
+	 * Check if any HDMI monitor was connected before probing this driver
+	 * and/or attaching the bridge, without debouncing: if so, we want to
+	 * notify the DRM so that we start outputting an image ASAP.
+	 * Note that calling the ISR thread function will also perform a HW
+	 * registers write that enables both the HPD and Pord interrupts.
+	 */
+	__mtk_hdmi_v2_isr_thread(hdmi);
+
+	return 0;
+}
+
+static void mtk_hdmi_v2_bridge_detach(struct drm_bridge *bridge)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	/* Disable interrupts */
+	mtk_hdmi_v2_hwirq_disable(hdmi);
+	disable_irq(hdmi->irq);
+	pm_runtime_put_sync(hdmi->dev);
+}
+
+static void mtk_hdmi_v2_handle_plugged_change(struct mtk_hdmi *hdmi, bool plugged)
+{
+	mutex_lock(&hdmi->update_plugged_status_lock);
+	if (hdmi->plugged_cb && hdmi->codec_dev)
+		hdmi->plugged_cb(hdmi->codec_dev, plugged);
+	mutex_unlock(&hdmi->update_plugged_status_lock);
+}
+
+static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
+					  struct drm_bridge_state *old_state)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector_state *conn_state;
+	union phy_configure_opts opts = {
+		.dp = { .link_rate = hdmi->mode.clock * KILO }
+	};
+
+	/* Retrieve the connector through the atomic state */
+	hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
+
+	conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
+	if (WARN_ON(!conn_state))
+		return;
+
+	/*
+	 * Preconfigure the HDMI controller and the HDMI PHY at pre_enable
+	 * stage to make sure that this IP is ready and clocked before the
+	 * mtk_dpi gets powered on and before it enables the output.
+	 */
+	hdmi->dvi_mode = !hdmi->curr_conn->display_info.is_hdmi;
+	mtk_hdmi_v2_output_set_display_mode(hdmi, &hdmi->mode);
+
+	/* Reconfigure phy clock link with appropriate rate */
+	phy_configure(hdmi->phy, &opts);
+
+	/* Power on the PHY here to make sure that DPI_HDMI is clocked */
+	phy_power_on(hdmi->phy);
+
+	hdmi->powered = true;
+}
+
+static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
+				      struct drm_bridge_state *old_state)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+	struct drm_atomic_state *state = old_state->base.state;
+	int ret;
+
+	ret = drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
+	if (ret)
+		dev_err(hdmi->dev, "Could not update infoframes: %d\n", ret);
+
+	mtk_hdmi_v2_hw_vid_mute(hdmi, false);
+	mtk_hdmi_v2_hw_aud_mute(hdmi, false);
+
+	/* signal the connect event to audio codec */
+	mtk_hdmi_v2_handle_plugged_change(hdmi, true);
+
+	hdmi->enabled = true;
+}
+
+static void mtk_hdmi_v2_bridge_disable(struct drm_bridge *bridge,
+				       struct drm_bridge_state *old_bridge_state)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	if (!hdmi->enabled)
+		return;
+
+	mtk_hdmi_v2_hw_av_mute(hdmi, true);
+	msleep(50);
+	mtk_hdmi_v2_hw_vid_mute(hdmi, true);
+	mtk_hdmi_v2_hw_aud_mute(hdmi, true);
+	mtk_hdmi_v2_disable_hdcp_encrypt(hdmi);
+	msleep(50);
+
+	hdmi->enabled = false;
+}
+
+static void mtk_hdmi_v2_bridge_post_disable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *old_state)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	if (!hdmi->powered)
+		return;
+
+	/* Disable VSync interrupt */
+	regmap_clear_bits(hdmi->regs, TOP_INT_ENABLE00, HDMI_VSYNC_INT);
+
+	phy_power_off(hdmi->phy);
+	hdmi->powered = false;
+
+	/* signal the disconnect event to audio codec */
+	mtk_hdmi_v2_handle_plugged_change(hdmi, false);
+}
+
+static enum drm_connector_status mtk_hdmi_v2_bridge_detect(struct drm_bridge *bridge)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	return hdmi->hpd != HDMI_PLUG_OUT ?
+	       connector_status_connected : connector_status_disconnected;
+}
+
+static const struct drm_edid *mtk_hdmi_v2_bridge_edid_read(struct drm_bridge *bridge,
+							   struct drm_connector *connector)
+{
+	return drm_edid_read(connector);
+}
+
+static int mtk_hdmi_v2_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
+						 const struct drm_display_mode *mode,
+						 unsigned long long tmds_rate)
+{
+	if (mode->clock < MTK_HDMI_V2_CLOCK_MIN)
+		return MODE_CLOCK_LOW;
+	else if (mode->clock > MTK_HDMI_V2_CLOCK_MAX)
+		return MODE_CLOCK_HIGH;
+	else
+		return MODE_OK;
+}
+
+static enum drm_mode_status
+mtk_hdmi_v2_bridge_mode_valid(struct drm_bridge *bridge,
+			      const struct drm_display_info *info,
+			      const struct drm_display_mode *mode)
+{
+	unsigned long long rate;
+
+	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+	return mtk_hdmi_v2_hdmi_tmds_char_rate_valid(bridge, mode, rate);
+}
+
+static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+	u32 reg_start, reg_end;
+
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
+		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
+		reg_start = TOP_AIF_HEADER;
+		reg_end = TOP_AIF_PKT03;
+		break;
+	case HDMI_INFOFRAME_TYPE_AVI:
+		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
+		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
+		reg_start = TOP_AVI_HEADER;
+		reg_end = TOP_AVI_PKT05;
+		break;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
+		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
+		reg_start = TOP_SPDIF_HEADER;
+		reg_end = TOP_SPDIF_PKT07;
+		break;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
+		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
+		reg_start = TOP_VSIF_HEADER;
+		reg_end = TOP_VSIF_PKT07;
+		break;
+	case HDMI_INFOFRAME_TYPE_DRM:
+	default:
+		return 0;
+	};
+
+	for (; reg_start <= reg_end; reg_start += 4)
+		regmap_write(hdmi->regs, reg_start, 0);
+
+	return 0;
+}
+
+static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type,
+					    const u8 *buffer, size_t len)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
+		break;
+	case HDMI_INFOFRAME_TYPE_AVI:
+		mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer);
+		break;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer);
+		break;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer);
+		break;
+	case HDMI_INFOFRAME_TYPE_DRM:
+	default:
+		dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type);
+		break;
+	};
+
+	return 0;
+}
+
+static int mtk_hdmi_v2_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)
+{
+	return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
+						      conn_state->state);
+}
+
+static int mtk_hdmi_v2_set_abist(struct mtk_hdmi *hdmi, bool enable)
+{
+	struct drm_display_mode *mode = &hdmi->mode;
+	int abist_format = -EINVAL;
+	bool interlaced;
+
+	if (!enable) {
+		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
+		return 0;
+	}
+
+	if (!mode->hdisplay || !mode->vdisplay)
+		return -EINVAL;
+
+	interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
+
+	switch (mode->hdisplay) {
+	case 720:
+		if (mode->vdisplay == 480)
+			abist_format = 2;
+		else if (mode->vdisplay == 576)
+			abist_format = 11;
+		break;
+	case 1280:
+		if (mode->vdisplay == 720)
+			abist_format = 3;
+		break;
+	case 1440:
+		if (mode->vdisplay == 480)
+			abist_format = interlaced ? 5 : 9;
+		else if (mode->vdisplay == 576)
+			abist_format = interlaced ? 14 : 18;
+		break;
+	case 1920:
+		if (mode->vdisplay == 1080)
+			abist_format = interlaced ? 4 : 10;
+		break;
+	case 3840:
+		if (mode->vdisplay == 2160)
+			abist_format = 25;
+		break;
+	case 4096:
+		if (mode->vdisplay == 2160)
+			abist_format = 26;
+		break;
+	default:
+		break;
+	}
+	if (!abist_format)
+		return -EINVAL;
+
+	regmap_update_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_VIDEO_FORMAT,
+			   FIELD_PREP(HDMI_ABIST_VIDEO_FORMAT, abist_format));
+	regmap_set_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
+	return 0;
+}
+
+static int mtk_hdmi_v2_debug_abist_show(struct seq_file *m, void *arg)
+{
+	struct mtk_hdmi *hdmi = m->private;
+	bool en;
+	u32 val;
+	int ret;
+
+	if (!hdmi)
+		return -EINVAL;
+
+	ret = regmap_read(hdmi->regs, TOP_CFG00, &val);
+	if (ret)
+		return ret;
+
+	en = FIELD_GET(HDMI_ABIST_ENABLE, val);
+
+	seq_printf(m, "HDMI Automated Built-In Self Test: %s\n",
+		   en ? "Enabled" : "Disabled");
+
+	return 0;
+}
+
+static ssize_t mtk_hdmi_v2_debug_abist_write(struct file *file,
+					     const char __user *ubuf,
+					     size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	int ret;
+	u32 en;
+
+	if (!m || !m->private || *offp)
+		return -EINVAL;
+
+	ret = kstrtouint_from_user(ubuf, len, 0, &en);
+	if (ret)
+		return ret;
+
+	if (en < 0 || en > 1)
+		return -EINVAL;
+
+	mtk_hdmi_v2_set_abist((struct mtk_hdmi *)m->private, en);
+	return len;
+}
+
+static int mtk_hdmi_v2_debug_abist_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mtk_hdmi_v2_debug_abist_show, inode->i_private);
+}
+
+static const struct file_operations mtk_hdmi_debug_abist_fops = {
+	.owner = THIS_MODULE,
+	.open = mtk_hdmi_v2_debug_abist_open,
+	.read = seq_read,
+	.write = mtk_hdmi_v2_debug_abist_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static void mtk_hdmi_v2_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
+{
+	struct mtk_hdmi *dpi = hdmi_ctx_from_bridge(bridge);
+
+	debugfs_create_file("hdmi_abist", 0640, root, dpi, &mtk_hdmi_debug_abist_fops);
+}
+
+static const struct drm_bridge_funcs mtk_v2_hdmi_bridge_funcs = {
+	.attach = mtk_hdmi_v2_bridge_attach,
+	.detach = mtk_hdmi_v2_bridge_detach,
+	.mode_fixup = mtk_hdmi_bridge_mode_fixup,
+	.mode_set = mtk_hdmi_bridge_mode_set,
+	.mode_valid = mtk_hdmi_v2_bridge_mode_valid,
+	.atomic_pre_enable = mtk_hdmi_v2_bridge_pre_enable,
+	.atomic_enable = mtk_hdmi_v2_bridge_enable,
+	.atomic_disable = mtk_hdmi_v2_bridge_disable,
+	.atomic_post_disable = mtk_hdmi_v2_bridge_post_disable,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_check = mtk_hdmi_v2_bridge_atomic_check,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.detect = mtk_hdmi_v2_bridge_detect,
+	.edid_read = mtk_hdmi_v2_bridge_edid_read,
+	.hdmi_tmds_char_rate_valid = mtk_hdmi_v2_hdmi_tmds_char_rate_valid,
+	.hdmi_clear_infoframe = mtk_hdmi_v2_hdmi_clear_infoframe,
+	.hdmi_write_infoframe = mtk_hdmi_v2_hdmi_write_infoframe,
+	.debugfs_init = mtk_hdmi_v2_debugfs_init,
+};
+
+/*
+ * HDMI audio codec callbacks
+ */
+static int mtk_hdmi_v2_audio_hook_plugged_cb(struct device *dev, void *data,
+					     hdmi_codec_plugged_cb fn,
+					     struct device *codec_dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	bool plugged;
+
+	if (!hdmi)
+		return -ENODEV;
+
+	mtk_hdmi_audio_set_plugged_cb(hdmi, fn, codec_dev);
+	plugged = (hdmi->hpd == HDMI_PLUG_IN_AND_SINK_POWER_ON);
+	mtk_hdmi_v2_handle_plugged_change(hdmi, plugged);
+
+	return 0;
+}
+
+static int mtk_hdmi_v2_audio_hw_params(struct device *dev, void *data,
+				       struct hdmi_codec_daifmt *daifmt,
+				       struct hdmi_codec_params *params)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	if (hdmi->audio_enable) {
+		mtk_hdmi_audio_params(hdmi, daifmt, params);
+		mtk_hdmi_v2_aud_output_config(hdmi, &hdmi->mode);
+	}
+	return 0;
+}
+
+static int mtk_hdmi_v2_audio_startup(struct device *dev, void *data)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	mtk_hdmi_v2_hw_aud_enable(hdmi, true);
+	hdmi->audio_enable = true;
+
+	return 0;
+}
+
+static void mtk_hdmi_v2_audio_shutdown(struct device *dev, void *data)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	hdmi->audio_enable = false;
+	mtk_hdmi_v2_hw_aud_enable(hdmi, false);
+}
+
+static int mtk_hdmi_v2_audio_mute(struct device *dev, void *data, bool enable, int dir)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	mtk_hdmi_v2_hw_aud_mute(hdmi, enable);
+
+	return 0;
+}
+
+static const struct hdmi_codec_ops mtk_hdmi_v2_audio_codec_ops = {
+	.hw_params = mtk_hdmi_v2_audio_hw_params,
+	.audio_startup = mtk_hdmi_v2_audio_startup,
+	.audio_shutdown = mtk_hdmi_v2_audio_shutdown,
+	.mute_stream = mtk_hdmi_v2_audio_mute,
+	.get_eld = mtk_hdmi_audio_get_eld,
+	.hook_plugged_cb = mtk_hdmi_v2_audio_hook_plugged_cb,
+};
+
+static __maybe_unused int mtk_hdmi_v2_suspend(struct device *dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	mtk_hdmi_v2_hwirq_disable(hdmi);
+	mtk_hdmi_v2_clk_disable(hdmi);
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+static __maybe_unused int mtk_hdmi_v2_resume(struct device *dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	int ret;
+
+	pm_runtime_get_sync(dev);
+
+	ret = mtk_hdmi_v2_clk_enable(hdmi);
+	if (ret)
+		return ret;
+
+	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mtk_hdmi_v2_pm_ops, mtk_hdmi_v2_suspend, mtk_hdmi_v2_resume);
+
+static const struct mtk_hdmi_ver_conf mtk_hdmi_conf_v2 = {
+	.bridge_funcs = &mtk_v2_hdmi_bridge_funcs,
+	.codec_ops = &mtk_hdmi_v2_audio_codec_ops,
+	.mtk_hdmi_clock_names = mtk_hdmi_v2_clk_names,
+	.num_clocks = MTK_HDMI_V2_CLK_COUNT
+};
+
+static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8188 = {
+	.ver_conf = &mtk_hdmi_conf_v2,
+	.reg_hdmi_tx_cfg = HDMITX_CONFIG_MT8188
+};
+
+static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8195 = {
+	.ver_conf = &mtk_hdmi_conf_v2,
+	.reg_hdmi_tx_cfg = HDMITX_CONFIG_MT8195,
+};
+
+static int mtk_hdmi_v2_probe(struct platform_device *pdev)
+{
+	struct mtk_hdmi *hdmi;
+	int ret;
+
+	hdmi = mtk_hdmi_common_probe(pdev);
+	if (IS_ERR(hdmi))
+		return PTR_ERR(hdmi);
+
+	hdmi->hpd = HDMI_PLUG_OUT;
+
+	/*
+	 * Disable all HW interrupts at probe stage and install the ISR
+	 * but keep it disabled, as the rest of the interrupts setup is
+	 * done in the .bridge_attach() callback, which will enable both
+	 * the right HW IRQs and the ISR.
+	 */
+	mtk_hdmi_v2_hwirq_disable(hdmi);
+	irq_set_status_flags(hdmi->irq, IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(&pdev->dev, hdmi->irq, mtk_hdmi_v2_isr,
+					mtk_hdmi_v2_isr_thread,
+					IRQ_TYPE_LEVEL_HIGH,
+					dev_name(&pdev->dev), hdmi);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Cannot request IRQ\n");
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Cannot enable Runtime PM\n");
+
+	return 0;
+}
+
+static void mtk_hdmi_v2_remove(struct platform_device *pdev)
+{
+	struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
+
+	pm_runtime_disable(&pdev->dev);
+	i2c_put_adapter(hdmi->ddc_adpt);
+}
+
+static const struct of_device_id mtk_drm_hdmi_v2_of_ids[] = {
+	{ .compatible = "mediatek,mt8188-hdmi-tx", .data = &mtk_hdmi_conf_mt8188 },
+	{ .compatible = "mediatek,mt8195-hdmi-tx", .data = &mtk_hdmi_conf_mt8195 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_v2_of_ids);
+
+static struct platform_driver mtk_hdmi_v2_driver = {
+	.probe = mtk_hdmi_v2_probe,
+	.remove = mtk_hdmi_v2_remove,
+	.driver = {
+		.name = "mediatek-drm-hdmi-v2",
+		.of_match_table = mtk_drm_hdmi_v2_of_ids,
+		.pm = &mtk_hdmi_v2_pm_ops,
+	},
+};
+module_platform_driver(mtk_hdmi_v2_driver);
+
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>>");
+MODULE_AUTHOR("Guillaume Ranquet <granquet at baylibre.com>");
+MODULE_DESCRIPTION("MediaTek HDMIv2 Driver");
+MODULE_LICENSE("GPL");
-- 
2.47.0



From christian.bruel at foss.st.com  Thu Dec  5 03:46:29 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Thu, 5 Dec 2024 12:46:29 +0100
Subject: [PATCH v2 2/5] PCI: stm32: Add PCIe host support for STM32MP25
In-Reply-To: <9ca967aea19d6c28327f3a9bb77e23f6245603e9.camel@pengutronix.de>
References: <20241129205822.GA2772018@bhelgaas>
 <9ca967aea19d6c28327f3a9bb77e23f6245603e9.camel@pengutronix.de>
Message-ID: <9340979e-8f0e-465b-a524-4ff315a9941d@foss.st.com>

Hello Bjorn and Lucas,

On 11/29/24 22:18, Lucas Stach wrote:
> Am Freitag, dem 29.11.2024 um 14:58 -0600 schrieb Bjorn Helgaas:
>> [+to Rob, DMA mask question]
>>
>> On Tue, Nov 26, 2024 at 04:51:16PM +0100, Christian Bruel wrote:
>>> Add driver for the STM32MP25 SoC PCIe Gen2 controller based on the
>>> DesignWare PCIe core.
>>
>> Can you include the numeric rate, not just "gen2", so we don't have to
>> search for it?
>>
>>> +static int stm32_pcie_resume_noirq(struct device *dev)
>>> +{
>>> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
>>> +	struct dw_pcie *pci = stm32_pcie->pci;
>>> +	struct dw_pcie_rp *pp = &pci->pp;
>>> +	int ret;
>>> +
>>> +	/* init_state must be called first to force clk_req# gpio when no
>>> +	 * device is plugged.
>>> +	 */
>>
>> Use drivers/pci/ conventional comment style:
>>
>>    /*
>>     * text ...
>>     */
>>
>>> +static bool is_stm32_pcie_driver(struct device *dev)
>>> +{
>>> +	/* PCI bridge */
>>> +	dev = get_device(dev);
>>> +
>>> +	/* Platform driver */
>>> +	dev = get_device(dev->parent);
>>> +
>>> +	return (dev->driver == &stm32_pcie_driver.driver);
>>> +}
>>> +
>>> +/*
>>> + * DMA masters can only access the first 4GB of memory space,
>>> + * so we setup the bus DMA limit accordingly.
>>> + */
>>> +static int stm32_dma_limit(struct pci_dev *pdev, void *data)
>>> +{
>>> +	dev_dbg(&pdev->dev, "disabling DMA DAC for device");
>>> +
>>> +	pdev->dev.bus_dma_limit = DMA_BIT_MASK(32);
>>
>> I don't think this is the right way to do this.  Surely there's a way
>> to describe the DMA capability of the bridge once instead of iterating
>> over all the downstream devices?  This quirk can't work for hot-added
>> devices anyway.
>>

agree,

> This should simply be a dma-ranges property in the PCIe host controller
> DT node, which should describe the DMA address range limits for
> transactions passing through the host.

far better indeed, dma-ranges works like a charm

thanks,

> 
> Regards,
> Lucas
> 
>>> +	return 0;
>>> +}
>>> +
>>> +static void quirk_stm32_dma_mask(struct pci_dev *pci)
>>> +{
>>> +	struct pci_dev *root_port;
>>> +
>>> +	root_port = pcie_find_root_port(pci);
>>> +
>>> +	if (root_port && is_stm32_pcie_driver(root_port->dev.parent))
>>> +		pci_walk_bus(pci->bus, stm32_dma_limit, NULL);
>>> +}
>>> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SYNOPSYS, 0x0550, quirk_stm32_dma_mask);
>>
> 


From catalin.marinas at arm.com  Thu Dec  5 03:51:23 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 5 Dec 2024 11:51:23 +0000
Subject: [PATCH v7 10/11] virt: arm-cca-guest: TSM_REPORT support for
 realms
In-Reply-To: <6750c695194cd_2508129427@dwillia2-xfh.jf.intel.com.notmuch>
References: <20241017131434.40935-1-steven.price@arm.com>
 <20241017131434.40935-11-steven.price@arm.com>
 <6750c695194cd_2508129427@dwillia2-xfh.jf.intel.com.notmuch>
Message-ID: <Z1GTu1kAV3J1cnJc@arm.com>

On Wed, Dec 04, 2024 at 01:16:05PM -0800, Dan Williams wrote:
> Steven Price wrote:
> > diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/arm-cca-guest/Kconfig
> > new file mode 100644
> > index 000000000000..9dd27c3ee215
> > --- /dev/null
> > +++ b/drivers/virt/coco/arm-cca-guest/Kconfig
> > @@ -0,0 +1,11 @@
> > +config ARM_CCA_GUEST
> > +	tristate "Arm CCA Guest driver"
> > +	depends on ARM64
> > +	default m
> 
> I am working on some updates to the TSM_REPORTS interface, rebased them
> to test the changes with this driver, and discovered that this driver is
> enabled by default.
> 
> Just a reminder to please do not mark new drivers as "default m" [1]. In
> this case it is difficult to imagine that every arm64 kernel on the
> planet needs this functionality enabled by default. In general, someone
> should be able to run olddefconfig with a new kernel and not be exposed
> to brand new drivers that they have not considered previously.
> 
> [1]: http://lore.kernel.org/CA+55aFzxL6-Xp=-mnBwMisZsuKhRZ6zRDJoAmH8W5LDHU2oJuw at mail.gmail.com/

Fair point, the pKVM driver is also default off. At least with the arm64
defconfig, VIRT_DRIVERS is default off, so this wouldn't be built. But
an olddefconfig will indeed enable it (this reminds me to add the coco
drivers to my test configs).

-- 
Catalin


From andi.shyti at kernel.org  Thu Dec  5 03:53:42 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Thu, 5 Dec 2024 12:53:42 +0100
Subject: [PATCH] i2c: imx: make controller available until system
 suspend_noirq() and from resume_noirq()
In-Reply-To: <20241125142108.1613016-1-carlos.song@nxp.com>
References: <20241125142108.1613016-1-carlos.song@nxp.com>
Message-ID: <6d6xgvuvu74hm5466xeovgr4qqkwxaxaoeemvfdty3dqnl4gjp@axlzm6mxnzkv>

Hi Carlos,

...

> +static int i2c_imx_suspend(struct device *dev)
> +{
> +	/*
> +	 * Some I2C devices may need I2C controller up during resume_noirq()
> +	 * or suspend_noirq(), if the controller is autosuspended, there is
> +	 * no way to wakeup it once runtime pm is disabled (in suspend_late()).
> +	 * When system resume, I2C controller will be available until runtime pm
> +	 * is enabled(in_resume_early()). But it is too late for some devices.
> +	 * Wakeup the controller in suspend() callback while runtime pm is enabled,
> +	 * I2C controller will be available until suspend_noirq() callback
> +	 * (pm_runtime_force_suspend()) is called. During the resume, I2C controller
> +	 * can be restored by resume_noirq() callback (pm_runtime_force_resume()).
> +	 * Then resume() callback enables autosuspend. It will make I2C controller
> +	 * available until system suspend_noirq() and from resume_noirq().
> +	 */

Just made some little adjustments to the comment above, please
let me know if they are fine:

	/*
	 * Some I2C devices may need the I2C controller to remain active
	 * during resume_noirq() or suspend_noirq(). If the controller is
	 * autosuspended, there is no way to wake it up once runtime PM is
	 * disabled (in suspend_late()).
	 *
	 * During system resume, the I2C controller will be available only
	 * after runtime PM is re-enabled (in resume_early()). However, this
	 * may be too late for some devices.
	 *
	 * Wake up the controller in the suspend() callback while runtime PM
	 * is still enabled. The I2C controller will remain available until
	 * the suspend_noirq() callback (pm_runtime_force_suspend()) is
	 * called. During resume, the I2C controller can be restored by the
	 * resume_noirq() callback (pm_runtime_force_resume()).
	 *
	 * Finally, the resume() callback re-enables autosuspend, ensuring
	 * the I2C controller remains available until the system enters
	 * suspend_noirq() and from resume_noirq().
	 */

If so, I will take it in.

Andi

> +	return pm_runtime_resume_and_get(dev);
> +}


From lkp at intel.com  Thu Dec  5 03:52:43 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 5 Dec 2024 19:52:43 +0800
Subject: [PATCH v1 01/13] KVM: Add KVM_MEM_USERFAULT memslot flag and
 bitmap
In-Reply-To: <20241204191349.1730936-2-jthoughton@google.com>
References: <20241204191349.1730936-2-jthoughton@google.com>
Message-ID: <202412051904.GNL7BE1X-lkp@intel.com>

Hi James,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 4d911c7abee56771b0219a9fbf0120d06bdc9c14]

url:    https://github.com/intel-lab-lkp/linux/commits/James-Houghton/KVM-Add-KVM_MEM_USERFAULT-memslot-flag-and-bitmap/20241205-032516
base:   4d911c7abee56771b0219a9fbf0120d06bdc9c14
patch link:    https://lore.kernel.org/r/20241204191349.1730936-2-jthoughton%40google.com
patch subject: [PATCH v1 01/13] KVM: Add KVM_MEM_USERFAULT memslot flag and bitmap
config: x86_64-randconfig-121 (https://download.01.org/0day-ci/archive/20241205/202412051904.GNL7BE1X-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/20241205/202412051904.GNL7BE1X-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/202412051904.GNL7BE1X-lkp at intel.com/

sparse warnings: (new ones prefixed by >>)
   arch/x86/kvm/../../../virt/kvm/kvm_main.c: note: in included file:
   include/linux/kvm_host.h:2080:54: sparse: sparse: array of flexible structures
   include/linux/kvm_host.h:2082:56: sparse: sparse: array of flexible structures
>> arch/x86/kvm/../../../virt/kvm/kvm_main.c:2049:39: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected unsigned long [noderef] __user *userfault_bitmap @@     got unsigned long * @@
   arch/x86/kvm/../../../virt/kvm/kvm_main.c:2049:39: sparse:     expected unsigned long [noderef] __user *userfault_bitmap
   arch/x86/kvm/../../../virt/kvm/kvm_main.c:2049:39: sparse:     got unsigned long *
   arch/x86/kvm/../../../virt/kvm/kvm_main.c:626:25: sparse: sparse: context imbalance in 'kvm_mmu_notifier_invalidate_range_start' - different lock contexts for basic block
   arch/x86/kvm/../../../virt/kvm/kvm_main.c:626:25: sparse: sparse: context imbalance in 'kvm_mmu_notifier_invalidate_range_end' - different lock contexts for basic block
   arch/x86/kvm/../../../virt/kvm/kvm_main.c:626:25: sparse: sparse: context imbalance in 'kvm_mmu_notifier_clear_flush_young' - different lock contexts for basic block
   arch/x86/kvm/../../../virt/kvm/kvm_main.c:626:25: sparse: sparse: context imbalance in 'kvm_mmu_notifier_clear_young' - different lock contexts for basic block
   arch/x86/kvm/../../../virt/kvm/kvm_main.c:626:25: sparse: sparse: context imbalance in 'kvm_mmu_notifier_test_young' - different lock contexts for basic block
   arch/x86/kvm/../../../virt/kvm/kvm_main.c: note: in included file (through include/linux/mutex.h, include/linux/kvm_types.h, include/kvm/iodev.h):
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true
   arch/x86/kvm/../../../virt/kvm/kvm_main.c:1960:49: sparse: sparse: self-comparison always evaluates to false
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true

vim +2049 arch/x86/kvm/../../../virt/kvm/kvm_main.c

  1931	
  1932	/*
  1933	 * Allocate some memory and give it an address in the guest physical address
  1934	 * space.
  1935	 *
  1936	 * Discontiguous memory is allowed, mostly for framebuffers.
  1937	 *
  1938	 * Must be called holding kvm->slots_lock for write.
  1939	 */
  1940	int __kvm_set_memory_region(struct kvm *kvm,
  1941				    const struct kvm_userspace_memory_region2 *mem)
  1942	{
  1943		struct kvm_memory_slot *old, *new;
  1944		struct kvm_memslots *slots;
  1945		enum kvm_mr_change change;
  1946		unsigned long npages;
  1947		gfn_t base_gfn;
  1948		int as_id, id;
  1949		int r;
  1950	
  1951		r = check_memory_region_flags(kvm, mem);
  1952		if (r)
  1953			return r;
  1954	
  1955		as_id = mem->slot >> 16;
  1956		id = (u16)mem->slot;
  1957	
  1958		/* General sanity checks */
  1959		if ((mem->memory_size & (PAGE_SIZE - 1)) ||
  1960		    (mem->memory_size != (unsigned long)mem->memory_size))
  1961			return -EINVAL;
  1962		if (mem->guest_phys_addr & (PAGE_SIZE - 1))
  1963			return -EINVAL;
  1964		/* We can read the guest memory with __xxx_user() later on. */
  1965		if ((mem->userspace_addr & (PAGE_SIZE - 1)) ||
  1966		    (mem->userspace_addr != untagged_addr(mem->userspace_addr)) ||
  1967		     !access_ok((void __user *)(unsigned long)mem->userspace_addr,
  1968				mem->memory_size))
  1969			return -EINVAL;
  1970		if (mem->flags & KVM_MEM_GUEST_MEMFD &&
  1971		    (mem->guest_memfd_offset & (PAGE_SIZE - 1) ||
  1972		     mem->guest_memfd_offset + mem->memory_size < mem->guest_memfd_offset))
  1973			return -EINVAL;
  1974		if (as_id >= kvm_arch_nr_memslot_as_ids(kvm) || id >= KVM_MEM_SLOTS_NUM)
  1975			return -EINVAL;
  1976		if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr)
  1977			return -EINVAL;
  1978		if ((mem->memory_size >> PAGE_SHIFT) > KVM_MEM_MAX_NR_PAGES)
  1979			return -EINVAL;
  1980	
  1981		slots = __kvm_memslots(kvm, as_id);
  1982	
  1983		/*
  1984		 * Note, the old memslot (and the pointer itself!) may be invalidated
  1985		 * and/or destroyed by kvm_set_memslot().
  1986		 */
  1987		old = id_to_memslot(slots, id);
  1988	
  1989		if (!mem->memory_size) {
  1990			if (!old || !old->npages)
  1991				return -EINVAL;
  1992	
  1993			if (WARN_ON_ONCE(kvm->nr_memslot_pages < old->npages))
  1994				return -EIO;
  1995	
  1996			return kvm_set_memslot(kvm, old, NULL, KVM_MR_DELETE);
  1997		}
  1998	
  1999		base_gfn = (mem->guest_phys_addr >> PAGE_SHIFT);
  2000		npages = (mem->memory_size >> PAGE_SHIFT);
  2001	
  2002		if (!old || !old->npages) {
  2003			change = KVM_MR_CREATE;
  2004	
  2005			/*
  2006			 * To simplify KVM internals, the total number of pages across
  2007			 * all memslots must fit in an unsigned long.
  2008			 */
  2009			if ((kvm->nr_memslot_pages + npages) < kvm->nr_memslot_pages)
  2010				return -EINVAL;
  2011		} else { /* Modify an existing slot. */
  2012			/* Private memslots are immutable, they can only be deleted. */
  2013			if (mem->flags & KVM_MEM_GUEST_MEMFD)
  2014				return -EINVAL;
  2015			if ((mem->userspace_addr != old->userspace_addr) ||
  2016			    (npages != old->npages) ||
  2017			    ((mem->flags ^ old->flags) & KVM_MEM_READONLY))
  2018				return -EINVAL;
  2019	
  2020			if (base_gfn != old->base_gfn)
  2021				change = KVM_MR_MOVE;
  2022			else if (mem->flags != old->flags)
  2023				change = KVM_MR_FLAGS_ONLY;
  2024			else /* Nothing to change. */
  2025				return 0;
  2026		}
  2027	
  2028		if ((change == KVM_MR_CREATE || change == KVM_MR_MOVE) &&
  2029		    kvm_check_memslot_overlap(slots, id, base_gfn, base_gfn + npages))
  2030			return -EEXIST;
  2031	
  2032		/* Allocate a slot that will persist in the memslot. */
  2033		new = kzalloc(sizeof(*new), GFP_KERNEL_ACCOUNT);
  2034		if (!new)
  2035			return -ENOMEM;
  2036	
  2037		new->as_id = as_id;
  2038		new->id = id;
  2039		new->base_gfn = base_gfn;
  2040		new->npages = npages;
  2041		new->flags = mem->flags;
  2042		new->userspace_addr = mem->userspace_addr;
  2043		if (mem->flags & KVM_MEM_GUEST_MEMFD) {
  2044			r = kvm_gmem_bind(kvm, new, mem->guest_memfd, mem->guest_memfd_offset);
  2045			if (r)
  2046				goto out;
  2047		}
  2048		if (mem->flags & KVM_MEM_USERFAULT)
> 2049			new->userfault_bitmap = (unsigned long *)mem->userfault_bitmap;
  2050	
  2051		r = kvm_set_memslot(kvm, old, new, change);
  2052		if (r)
  2053			goto out_unbind;
  2054	
  2055		return 0;
  2056	
  2057	out_unbind:
  2058		if (mem->flags & KVM_MEM_GUEST_MEMFD)
  2059			kvm_gmem_unbind(new);
  2060	out:
  2061		kfree(new);
  2062		return r;
  2063	}
  2064	EXPORT_SYMBOL_GPL(__kvm_set_memory_region);
  2065	

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


From bryan.odonoghue at linaro.org  Thu Dec  5 03:56:33 2024
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Thu, 5 Dec 2024 11:56:33 +0000
Subject: [PATCH v7 1/5] media: dt-bindings: Add qcom,sc7280-camss
In-Reply-To: <eaffa633-c3a4-4924-8ba7-694b18bf92ee@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-2-quic_vikramsa@quicinc.com>
 <oko5qqysmxhicqzkwhkz54wvsmt64ba3cd37zkcy55ee77owbk@5z3zetfr2ejx>
 <eaffa633-c3a4-4924-8ba7-694b18bf92ee@quicinc.com>
Message-ID: <2cb5940b-3779-4450-a213-fa766df7f406@linaro.org>

On 05/12/2024 10:59, Vikram Sharma wrote:
> Hi Krzysztof,
> 
> Thanks for your "Reviewed-by"
> 
> +        camss at acb3000 {
> 
> If there is going to be resend, then node name: isp
> 
> Sure, we will change node-name from camss to isp or camera (As its a 
> part of generic names recommendation as per the shared link.)
> If there is a resend. or we will address this as a followup.
> 
> So
> 
> - camss at acb3000 {
> + camera at acb3000 {
> 
> Best Regards,
> Vikram

Please no top-posting.
https://subspace.kernel.org/etiquette.html

Shouldn't that be isp at 0xaddress ?

If you are making this change, please remember to do it in both the 
example and the dts.

---
bod


From s-vadapalli at ti.com  Thu Dec  5 04:01:27 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 5 Dec 2024 17:31:27 +0530
Subject: [PATCH v2 0/2] Add Deep Sleep pinmux macros for TI's K3 SoCs
Message-ID: <20241205120134.754664-1-s-vadapalli@ti.com>

Hello,

This series introduces deep sleep macros which are common to TI's K3
SoCs and can be used to configure the behavior of SoC pins during Deep
Sleep mode. Additionally, support for SoC wakeup with USB1 on AM62x
based SoCs is added with the help of the newly introduced deep sleep
macros.

v1:
https://lore.kernel.org/r/20241112115650.988943-1-s-vadapalli at ti.com
Changes since v1:
- Rebased on next-20241204.

Series is based on linux-next tagged next-20241204.

Regards,
Siddharth.

Siddharth Vadapalli (2):
  arm64: dts: ti: k3-pinctrl: Introduce deep sleep macros
  arm64: dts: ti: k3-am62x-sk-common: Support SoC wakeup using USB1
    wakeup

 .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi |  2 +-
 arch/arm64/boot/dts/ti/k3-pinctrl.h           | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

-- 
2.43.0



From s-vadapalli at ti.com  Thu Dec  5 04:01:28 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 5 Dec 2024 17:31:28 +0530
Subject: [PATCH v2 1/2] arm64: dts: ti: k3-pinctrl: Introduce deep sleep macros
In-Reply-To: <20241205120134.754664-1-s-vadapalli@ti.com>
References: <20241205120134.754664-1-s-vadapalli@ti.com>
Message-ID: <20241205120134.754664-2-s-vadapalli@ti.com>

The behavior of pins in deep sleep mode can be configured by programming
the corresponding bits in the respective Pad Configuration register. Add
macros to support this.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

v1:
https://lore.kernel.org/r/20241112115650.988943-2-s-vadapalli at ti.com
Changes since v1:
- Rebased on next-20241204.

While Rob had suggested dropping the zero defines at:
https://lore.kernel.org/r/20241115154822.GA2954187-robh at kernel.org/
I had pointed out the inconsistency with existing convention at:
https://lore.kernel.org/r/5b35c736-74d6-4fe9-ae82-272dc2e98b82 at ti.com/
asking for Rob's opinion. Since I didn't receive a reply, I assumed that
the patch is fine in terms of being consistent and hence haven't dropped
the zero defines in the current version.

Regards,
Siddharth.

 arch/arm64/boot/dts/ti/k3-pinctrl.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-pinctrl.h b/arch/arm64/boot/dts/ti/k3-pinctrl.h
index 22b8d73cfd32..cac7cccc1112 100644
--- a/arch/arm64/boot/dts/ti/k3-pinctrl.h
+++ b/arch/arm64/boot/dts/ti/k3-pinctrl.h
@@ -12,6 +12,12 @@
 #define PULLTYPESEL_SHIFT	(17)
 #define RXACTIVE_SHIFT		(18)
 #define DEBOUNCE_SHIFT		(11)
+#define FORCE_DS_EN_SHIFT	(15)
+#define DS_EN_SHIFT		(24)
+#define DS_OUT_DIS_SHIFT	(25)
+#define DS_OUT_VAL_SHIFT	(26)
+#define DS_PULLUD_EN_SHIFT	(27)
+#define DS_PULLTYPE_SEL_SHIFT	(28)
 
 #define PULL_DISABLE		(1 << PULLUDEN_SHIFT)
 #define PULL_ENABLE		(0 << PULLUDEN_SHIFT)
@@ -38,6 +44,19 @@
 #define PIN_DEBOUNCE_CONF5	(5 << DEBOUNCE_SHIFT)
 #define PIN_DEBOUNCE_CONF6	(6 << DEBOUNCE_SHIFT)
 
+#define PIN_DS_FORCE_DISABLE		(0 << FORCE_DS_EN_SHIFT)
+#define PIN_DS_FORCE_ENABLE		(1 << FORCE_DS_EN_SHIFT)
+#define PIN_DS_IO_OVERRIDE_DISABLE	(0 << DS_IO_OVERRIDE_EN_SHIFT)
+#define PIN_DS_IO_OVERRIDE_ENABLE	(1 << DS_IO_OVERRIDE_EN_SHIFT)
+#define PIN_DS_OUT_ENABLE		(0 << DS_OUT_DIS_SHIFT)
+#define PIN_DS_OUT_DISABLE		(1 << DS_OUT_DIS_SHIFT)
+#define PIN_DS_OUT_VALUE_ZERO		(0 << DS_OUT_VAL_SHIFT)
+#define PIN_DS_OUT_VALUE_ONE		(1 << DS_OUT_VAL_SHIFT)
+#define PIN_DS_PULLUD_ENABLE		(0 << DS_PULLUD_EN_SHIFT)
+#define PIN_DS_PULLUD_DISABLE		(1 << DS_PULLUD_EN_SHIFT)
+#define PIN_DS_PULL_DOWN		(0 << DS_PULLTYPE_SEL_SHIFT)
+#define PIN_DS_PULL_UP			(1 << DS_PULLTYPE_SEL_SHIFT)
+
 /* Default mux configuration for gpio-ranges to use with pinctrl */
 #define PIN_GPIO_RANGE_IOPAD	(PIN_INPUT | 7)
 
-- 
2.43.0



From s-vadapalli at ti.com  Thu Dec  5 04:01:29 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 5 Dec 2024 17:31:29 +0530
Subject: [PATCH v2 2/2] arm64: dts: ti: k3-am62x-sk-common: Support SoC wakeup using USB1 wakeup
In-Reply-To: <20241205120134.754664-1-s-vadapalli@ti.com>
References: <20241205120134.754664-1-s-vadapalli@ti.com>
Message-ID: <20241205120134.754664-3-s-vadapalli@ti.com>

After the SoC has entered the Deep Sleep mode, USB1 can be used to wakeup
the SoC based on USB events triggered by USB devices. This requires that
the pin corresponding to the Type-A connector remains pulled up even after
the SoC has entered the Deep Sleep mode. Hence, enable Deep Sleep pullup /
pulldown selection for the USB1_DRVVBUS pin and set its Deep Sleep state to
PULL_UP.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---
v1:
https://lore.kernel.org/r/20241112115650.988943-3-s-vadapalli at ti.com
Changes since v1:
- Rebased on next-20241204.

 arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 6957b3e44c82..8b6316454639 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -256,7 +256,7 @@ AM62X_IOPAD(0x12c, PIN_OUTPUT, 0) /* (AD19/V15) RGMII1_TX_CTL */
 
 	main_usb1_pins_default: main-usb1-default-pins {
 		pinctrl-single,pins = <
-			AM62X_IOPAD(0x0258, PIN_OUTPUT, 0) /* (F18/E16) USB1_DRVVBUS */
+			AM62X_IOPAD(0x0258, PIN_OUTPUT | PIN_DS_PULLUD_ENABLE | PIN_DS_PULL_UP, 0) /* (F18/E16) USB1_DRVVBUS */
 		>;
 	};
 
-- 
2.43.0



From joey.gouly at arm.com  Thu Dec  5 04:07:07 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Thu, 5 Dec 2024 12:07:07 +0000
Subject: [PATCH 06/11] KVM: arm64: nv: Acceletate EL0 counter accesses
 from hypervisor context
In-Reply-To: <20241202172134.384923-7-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
 <20241202172134.384923-7-maz@kernel.org>
Message-ID: <20241205120707.GA102570@e124191.cambridge.arm.com>

On Mon, Dec 02, 2024 at 05:21:29PM +0000, Marc Zyngier wrote:
> Similarly to handling the physical timer accesses early when FEAT_ECV
> causes a trap, we try to handle the physical counter without returning
> to the general sysreg handling.
> 
> More surprisingly, we introduce something similar for the virtual
> counter. Although this isn't necessary yet, it will prove useful on
> systems that have a broken CNTVOFF_EL2 implementation. Yes, they exist.
> 

> Special care is taken to offset reads of the counter with the host's
> CNTPOFF_EL2, as we perform this with TGE clear.

Can you explain this part a bit more? I'm assuming it's somehow related to the
arch_timer_read_cntpct_el0() call.

However I think we're at EL2 inside kvm_hyp_handle_timer(), so reading
CNTPCT_EL0 won't involve CNTPOFF_EL2.

What am I missing/misunderstanding?

> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/hyp/include/hyp/switch.h |  5 +++++
>  arch/arm64/kvm/hyp/vhe/switch.c         | 13 +++++++++++++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 34f53707892df..30e572de28749 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -501,6 +501,11 @@ static inline bool handle_tx2_tvm(struct kvm_vcpu *vcpu)
>  	return true;
>  }
>  
> +static inline u64 compute_counter_value(struct arch_timer_context *ctxt)
> +{
> +	return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
> +}
> +
>  static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
>  {
>  	struct arch_timer_context *ctxt;
> diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> index b014b0b10bf5d..49815a8a4c9bc 100644
> --- a/arch/arm64/kvm/hyp/vhe/switch.c
> +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> @@ -296,6 +296,13 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
>  			val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
>  		}
>  		break;
> +	case SYS_CNTPCT_EL0:
> +	case SYS_CNTPCTSS_EL0:
> +		/* If !ELIsInHost(EL0), the guest's CNTPOFF_EL2 applies */
> +		val = compute_counter_value(!(vcpu_el2_e2h_is_set(vcpu) &&
> +					      vcpu_el2_tge_is_set(vcpu)) ?
> +					    vcpu_ptimer(vcpu) : vcpu_hptimer(vcpu));
> +		break;
>  	case SYS_CNTV_CTL_EL02:
>  		val = __vcpu_sys_reg(vcpu, CNTV_CTL_EL0);
>  		break;
> @@ -314,6 +321,12 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
>  		else
>  			val = __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
>  		break;
> +	case SYS_CNTVCT_EL0:
> +	case SYS_CNTVCTSS_EL0:
> +		/* If !ELIsInHost(EL2), the guest's CNTVOFF_EL2 applies */
> +		val = compute_counter_value(!vcpu_el2_e2h_is_set(vcpu) ?
> +					    vcpu_vtimer(vcpu) : vcpu_hvtimer(vcpu));
> +		break;
>  	default:
>  		return false;
>  	}

Thanks,
Joey


From krzk at kernel.org  Thu Dec  5 04:12:46 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 13:12:46 +0100
Subject: [PATCH v5 6/6] MAINTAINER: Add entry for Blaize SoC
In-Reply-To: <ac96f306-e5ea-4514-b25d-18b44777d3e6@blaize.com>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
 <20241204-blaize-blzp1600_init_board_support-v5-6-b642bcc49307@blaize.com>
 <h5awakp52e6pxnnfrclhtlhhs3i66twvmqwlf5vmnfwk2xhbwr@marp6wti72ti>
 <ac96f306-e5ea-4514-b25d-18b44777d3e6@blaize.com>
Message-ID: <6999aff2-5889-4786-9395-28d9ce40f6c0@kernel.org>

On 05/12/2024 12:22, Matt Redfearn wrote:
>>
>> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>
>> They should also ack it to confirm they understand the burden.
> 
> Acked-by: Matt Redfearn <matt.redfearn at blaize.com>
> 
> 
> A question about process: should Niko resend V5 with all of the acks?

Normally not, here however after finished review expectation was to send
it to soc tree (I think Arnd described the process).

Best regards,
Krzysztof


From nfraprado at collabora.com  Thu Dec  5 04:13:53 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Thu, 05 Dec 2024 09:13:53 -0300
Subject: [PATCH 0/5] Enable audio output for Genio 700 EVK board
Message-ID: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>

This series enables audio output support for the Genio 700 EVK board.
Patches 1-4 do the required binding and DT changes, and patch 5
describes the audio DT nodes to get audio output working on the two
audio jacks, Earphone and Speaker, present on the board.

The standalone fix in [1] is required in addition to this series in
order to get the sound card probing.

[1] https://lore.kernel.org/all/20241203-mt8188-6359-unhardcode-dmic-v1-1-346e3e5cbe6d at collabora.com

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
N?colas F. R. A. Prado (5):
      arm64: dts: mt6359: Add #sound-dai-cells property
      ASoC: dt-bindings: mediatek,mt8188-mt6359: Add compatible for mt8390 evk
      ASoC: dt-bindings: mediatek,mt8188-mt6359: Add DSP properties
      ASoC: dt-bindings: mediatek,mt8188-mt6359: Allow DL_SRC/UL_SRC dai-links
      arm64: dts: mediatek: mt8390-genio-700-evk: Add sound output support

 .../bindings/sound/mediatek,mt8188-mt6359.yaml     | 26 ++++++++---
 arch/arm64/boot/dts/mediatek/mt6359.dtsi           |  1 +
 .../boot/dts/mediatek/mt8390-genio-700-evk.dts     | 50 ++++++++++++++++++++++
 3 files changed, 72 insertions(+), 5 deletions(-)
---
base-commit: b852e1e7a0389ed6168ef1d38eb0bad71a6b11e8
change-id: 20241204-genio700-audio-output-fba8f2ebad10

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From nfraprado at collabora.com  Thu Dec  5 04:13:54 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Thu, 05 Dec 2024 09:13:54 -0300
Subject: [PATCH 1/5] arm64: dts: mt6359: Add #sound-dai-cells property
In-Reply-To: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
Message-ID: <20241205-genio700-audio-output-v1-1-0e955c78c29e@collabora.com>

MT6359 provides digital audio interfaces. Add a #sound-dai-cells
property for it to allow pointing to it from dai-link nodes.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt6359.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
index 8e1b8c85c6ede94a7beaefcdfc74ce47b3ab50fe..150ad84d5d2b30ab6064c71e1375ce5df5ae4b36 100644
--- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
@@ -8,6 +8,7 @@ pmic: pmic {
 		compatible = "mediatek,mt6359";
 		interrupt-controller;
 		#interrupt-cells = <2>;
+		#sound-dai-cells = <1>;
 
 		pmic_adc: adc {
 			compatible = "mediatek,mt6359-auxadc";

-- 
2.47.0



From nfraprado at collabora.com  Thu Dec  5 04:13:55 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Thu, 05 Dec 2024 09:13:55 -0300
Subject: [PATCH 2/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Add
 compatible for mt8390 evk
In-Reply-To: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
Message-ID: <20241205-genio700-audio-output-v1-2-0e955c78c29e@collabora.com>

Add a compatible for the MT8390 EVK. It is compatible with
mediatek,mt8188-mt6359-evb so make that the fallback compatible.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 .../devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml  | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
index f94ad0715e3239653c74553e27231f1395babefa..ffe9347b543f5c687433862a21ad534b8aace27e 100644
--- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
+++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
@@ -14,11 +14,15 @@ allOf:
 
 properties:
   compatible:
-    enum:
-      - mediatek,mt8188-es8326
-      - mediatek,mt8188-mt6359-evb
-      - mediatek,mt8188-nau8825
-      - mediatek,mt8188-rt5682s
+    oneOf:
+      - enum:
+          - mediatek,mt8188-es8326
+          - mediatek,mt8188-mt6359-evb
+          - mediatek,mt8188-nau8825
+          - mediatek,mt8188-rt5682s
+      - items:
+          - const: mediatek,mt8390-mt6359-evk
+          - const: mediatek,mt8188-mt6359-evb
 
   audio-routing:
     description:

-- 
2.47.0



From nfraprado at collabora.com  Thu Dec  5 04:13:56 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Thu, 05 Dec 2024 09:13:56 -0300
Subject: [PATCH 3/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Add DSP
 properties
In-Reply-To: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
Message-ID: <20241205-genio700-audio-output-v1-3-0e955c78c29e@collabora.com>

Add the mediatek,adsp and mediatek,dai-link properties to allow
describing the DSP configuration in the sound card node, as is already
the case for other MediaTek SoCs.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 .../devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml      | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
index ffe9347b543f5c687433862a21ad534b8aace27e..1e282c34dbd99851d3959b641096968c0b2e71be 100644
--- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
+++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
@@ -33,6 +33,16 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle
     description: The phandle of MT8188 ASoC platform.
 
+  mediatek,adsp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of MT8195 ADSP platform.
+
+  mediatek,dai-link:
+    $ref: /schemas/types.yaml#/definitions/string-array
+    description:
+      A list of the desired dai-links in the sound card. Each entry is a
+      name defined in the machine driver.
+
 patternProperties:
   "^dai-link-[0-9]+$":
     type: object

-- 
2.47.0



From nfraprado at collabora.com  Thu Dec  5 04:13:57 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Thu, 05 Dec 2024 09:13:57 -0300
Subject: [PATCH 4/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Allow
 DL_SRC/UL_SRC dai-links
In-Reply-To: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
Message-ID: <20241205-genio700-audio-output-v1-4-0e955c78c29e@collabora.com>

Add DL_SRC_BE and UL_SRC_BE as possible link-names for dai-links. These
DAI back-ends are currently hardcoded in the driver to the
MT6359 codec, but they may still be overridden with dai-links in the
Devicetree to assign them additional codecs or even to make the
dependency to the MT6359 codec explicit and allow device links to probe
the components in the right order and avoid unnecessary probe deferrals.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
index 1e282c34dbd99851d3959b641096968c0b2e71be..8993dff01244db9fc2fbf7bdefe7ea863be7c362 100644
--- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
+++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
@@ -63,6 +63,8 @@ patternProperties:
             - ETDM2_OUT_BE
             - ETDM3_OUT_BE
             - PCM1_BE
+            - DL_SRC_BE
+            - UL_SRC_BE
 
       codec:
         description: Holds subnode which indicates codec dai.

-- 
2.47.0



From nfraprado at collabora.com  Thu Dec  5 04:13:58 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Thu, 05 Dec 2024 09:13:58 -0300
Subject: [PATCH 5/5] arm64: dts: mediatek: mt8390-genio-700-evk: Add sound
 output support
In-Reply-To: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
Message-ID: <20241205-genio700-audio-output-v1-5-0e955c78c29e@collabora.com>

Describe all the components to get sound output working on the two audio
jacks, Earphone and Speaker, present on the Genio 700 EVK board with the
audio DSP enabled.

Co-developed-by: Aary Patil <aary.patil at mediatek.com>
Signed-off-by: Aary Patil <aary.patil at mediatek.com>
Co-developed-by: Suhrid Subramaniam <suhrid.subramaniam at mediatek.com>
Signed-off-by: Suhrid Subramaniam <suhrid.subramaniam at mediatek.com>
Co-developed-by: parkeryang <Parker.Yang at mediatek.com>
Signed-off-by: parkeryang <Parker.Yang at mediatek.com>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 .../boot/dts/mediatek/mt8390-genio-700-evk.dts     | 50 ++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
index bb68665f0b2da80397b833db0241a06648a322a0..2fded39078773e81d8e0313d6b118b3064be308d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
@@ -92,6 +92,24 @@ vpu_mem: memory at 57000000 {
 			compatible = "shared-dma-pool";
 			reg = <0 0x57000000 0 0x1400000>; /* 20 MB */
 		};
+
+		adsp_mem: memory at 60000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x60000000 0 0xf00000>;
+			no-map;
+		};
+
+		afe_dma_mem: memory at 60f00000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x60f00000 0 0x100000>;
+			no-map;
+		};
+
+		adsp_dma_mem: memory at 61000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x61000000 0 0x100000>;
+			no-map;
+		};
 	};
 
 	common_fixed_5v: regulator-0 {
@@ -209,6 +227,16 @@ usb_p2_vbus: regulator-9 {
 	};
 };
 
+&adsp {
+	memory-region = <&adsp_dma_mem>, <&adsp_mem>;
+	status = "okay";
+};
+
+&afe {
+	memory-region = <&afe_dma_mem>;
+	status = "okay";
+};
+
 &gpu {
 	mali-supply = <&mt6359_vproc2_buck_reg>;
 	status = "okay";
@@ -912,6 +940,28 @@ &scp {
 	status = "okay";
 };
 
+&sound {
+	compatible = "mediatek,mt8390-mt6359-evk", "mediatek,mt8188-mt6359-evb";
+	model = "mt8390-evk";
+	pinctrl-names = "default";
+	pinctrl-0 = <&audio_default_pins>;
+	audio-routing =
+		"Headphone", "Headphone L",
+		"Headphone", "Headphone R";
+	mediatek,adsp = <&adsp>;
+	mediatek,dai-link = "DL_SRC_BE", "UL_SRC_BE", "AFE_SOF_DL2",
+		"AFE_SOF_DL3", "AFE_SOF_UL4", "AFE_SOF_UL5";
+	status = "okay";
+
+	dai-link-0 {
+		link-name = "DL_SRC_BE";
+
+		codec {
+			sound-dai = <&pmic 0>;
+		};
+	};
+};
+
 &spi2 {
 	pinctrl-0 = <&spi2_pins>;
 	pinctrl-names = "default";

-- 
2.47.0



From mark.rutland at arm.com  Thu Dec  5 04:16:51 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu,  5 Dec 2024 12:16:51 +0000
Subject: [PATCH 0/4] arm64: ptrace: fix handling of partial SETREGSET calls
Message-ID: <20241205121655.1824269-1-mark.rutland@arm.com>

A few of arm64's regsets forget to handle partial-length SETREGSET
calls, and copy a small portion of uninitialized kernel stack memory to
the backing storage of the relevant registers. In all cases the read is
limited to a specific slot on the stack, and the issue does not provide
a write mechanism.

For example, a zero-length SETREGSET to NT_ARM_FPMR will reset FPMR to
an arbitrary uninitialized value from the kernel stack:

| # ./fpmr-test
| Attempting to write NT_ARM_FPMR::fpmr = 0x900d900d900d900d
| SETREGSET(nt=0x40e, len=8) wrote 8 bytes
|
| Attempting to read NT_ARM_FPMR::fpmr
| GETREGSET(nt=0x40e, len=8) read 8 bytes
| Read NT_ARM_FPMR::fpmr = 0x900d900d900d900d
|
| Attempting to write NT_ARM_FPMR (zero length)
| SETREGSET(nt=0x40e, len=0) wrote 0 bytes
|
| Attempting to read NT_ARM_FPMR::fpmr
| GETREGSET(nt=0x40e, len=8) read 8 bytes
| Read NT_ARM_FPMR::fpmr = 0xffff800083963d50

This series (based on v6.13-rc1) fixes affected regsets. To fix each
case there are three approaches we could follow:

(a) Preserve the registers which are not explicitly written to. Most
    other regsets (e.g. NT_PRSTATUS, NT_PRFPREG, NT_ARM_SYSTEM_CALL)
    follow this approach.

(b) Reset registers to a fixed value (e.g. zero) if not explicitly
    written to.

(c) Forbid writes that are smaller than the entire regset. For example,
    x86 does this in xfpregs_set().

For most regsets, partial-length SETREGSET calls follow option (a)
today, so I've taken that approach for all the affected arm64 regsets.

I've checked all of arm64's regsets (native, native view of compat, and
compat view of compat), and as far as I can tell, the only affected
regsets are NT_ARM_TAGGED_ADDR_CTRL, NT_ARM_FPMR, NT_ARM_POE, and
NT_ARM_GCS. All other regsets either either initialize a temporary
buffer prior to copying in, or copy directly to the backing storage, and
so don't copy uninitialized data.

There are some other cleanups which could be made here in future;
ideally we'd have a compiler warning for these cases, or a mechanism
that avoids the problem entirely.

Mark.

Mark Rutland (4):
  arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL
  arm64: ptrace: fix partial SETREGSET for NT_ARM_FPMR
  arm64: ptrace: fix partial SETREGSET for NT_ARM_POE
  arm64: ptrace: fix partial SETREGSET for NT_ARM_GCS

 arch/arm64/kernel/ptrace.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

-- 
2.30.2



From mark.rutland at arm.com  Thu Dec  5 04:16:54 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu,  5 Dec 2024 12:16:54 +0000
Subject: [PATCH 3/4] arm64: ptrace: fix partial SETREGSET for NT_ARM_POE
In-Reply-To: <20241205121655.1824269-1-mark.rutland@arm.com>
References: <20241205121655.1824269-1-mark.rutland@arm.com>
Message-ID: <20241205121655.1824269-4-mark.rutland@arm.com>

Currently poe_set() doesn't initialize the temporary 'ctrl' variable,
and a SETREGSET call with a length of zero will leave this
uninitialized. Consequently an arbitrary value will be written back to
target->thread.por_el0, potentially leaking up to 64 bits of memory from
the kernel stack. The read is limited to a specific slot on the stack,
and the issue does not provide a write mechanism.

Fix this by initializing the temporary value before copying the regset
from userspace, as for other regsets (e.g. NT_PRSTATUS, NT_PRFPREG,
NT_ARM_SYSTEM_CALL). In the case of a zero-length write, the existing
contents of POR_EL1 will be retained.

Before this patch:

| # ./poe-test
| Attempting to write NT_ARM_POE::por_el0 = 0x900d900d900d900d
| SETREGSET(nt=0x40f, len=8) wrote 8 bytes
|
| Attempting to read NT_ARM_POE::por_el0
| GETREGSET(nt=0x40f, len=8) read 8 bytes
| Read NT_ARM_POE::por_el0 = 0x900d900d900d900d
|
| Attempting to write NT_ARM_POE (zero length)
| SETREGSET(nt=0x40f, len=0) wrote 0 bytes
|
| Attempting to read NT_ARM_POE::por_el0
| GETREGSET(nt=0x40f, len=8) read 8 bytes
| Read NT_ARM_POE::por_el0 = 0xffff8000839c3d50

After this patch:

| # ./poe-test
| Attempting to write NT_ARM_POE::por_el0 = 0x900d900d900d900d
| SETREGSET(nt=0x40f, len=8) wrote 8 bytes
|
| Attempting to read NT_ARM_POE::por_el0
| GETREGSET(nt=0x40f, len=8) read 8 bytes
| Read NT_ARM_POE::por_el0 = 0x900d900d900d900d
|
| Attempting to write NT_ARM_POE (zero length)
| SETREGSET(nt=0x40f, len=0) wrote 0 bytes
|
| Attempting to read NT_ARM_POE::por_el0
| GETREGSET(nt=0x40f, len=8) read 8 bytes
| Read NT_ARM_POE::por_el0 = 0x900d900d900d900d

Fixes: 17519819926211e6 ("arm64/ptrace: add support for FEAT_POE")
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Joey Gouly <joey.gouly at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/ptrace.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 85c862dc845b3..f17810030fa05 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1478,6 +1478,8 @@ static int poe_set(struct task_struct *target, const struct
 	if (!system_supports_poe())
 		return -EINVAL;
 
+	ctrl = target->thread.por_el0;
+
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1);
 	if (ret)
 		return ret;
-- 
2.30.2



From mark.rutland at arm.com  Thu Dec  5 04:16:55 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu,  5 Dec 2024 12:16:55 +0000
Subject: [PATCH 4/4] arm64: ptrace: fix partial SETREGSET for NT_ARM_GCS
In-Reply-To: <20241205121655.1824269-1-mark.rutland@arm.com>
References: <20241205121655.1824269-1-mark.rutland@arm.com>
Message-ID: <20241205121655.1824269-5-mark.rutland@arm.com>

Currently gcs_set() doesn't initialize the temporary 'user_gcs'
variable, and a SETREGSET call with a length of 0, 8, or 16 will leave
some portion of this uninitialized. Consequently some arbitrary
uninitialized values may be written back to the relevant fields in task
struct, potentially leaking up to 192 bits of memory from the kernel
stack. The read is limited to a specific slot on the stack, and the
issue does not provide a write mechanism.

As gcs_set() rejects cases where user_gcs::features_enabled has bits set
other than PR_SHADOW_STACK_SUPPORTED_STATUS_MASK, a SETREGSET call with
a length of zero will randomly succeed or fail depending on the value of
the uninitialized value, it isn't possible to leak the full 192 bits.
With a length of 8 or 16, user_gcs::features_enabled can be initialized
to an accepted value, making it practical to leak 128 or 64 bits.

Fix this by initializing the temporary value before copying the regset
from userspace, as for other regsets (e.g. NT_PRSTATUS, NT_PRFPREG,
NT_ARM_SYSTEM_CALL). In the case of a zero-length or partial write, the
existing contents of the fields which are not written to will be
retained.

To ensure that the extraction and insertion of fields is consistent
across the GETREGSET and SETREGSET calls, new task_gcs_to_user() and
task_gcs_from_user() helpers are added, matching the style of
pac_address_keys_to_user() and pac_address_keys_from_user().

Before this patch:

| # ./gcs-test
| Attempting to write NT_ARM_GCS::user_gcs = {
|     .features_enabled = 0x0000000000000000,
|     .features_locked  = 0x0000000000000000,
|     .gcspr_el0        = 0x900d900d900d900d,
| }
| SETREGSET(nt=0x410, len=24) wrote 24 bytes
|
| Attempting to read NT_ARM_GCS::user_gcs
| GETREGSET(nt=0x410, len=24) read 24 bytes
| Read NT_ARM_GCS::user_gcs = {
|     .features_enabled = 0x0000000000000000,
|     .features_locked  = 0x0000000000000000,
|     .gcspr_el0        = 0x900d900d900d900d,
| }
|
| Attempting partial write NT_ARM_GCS::user_gcs = {
|     .features_enabled = 0x0000000000000000,
|     .features_locked  = 0x1de7ec7edbadc0de,
|     .gcspr_el0        = 0x1de7ec7edbadc0de,
| }
| SETREGSET(nt=0x410, len=8) wrote 8 bytes
|
| Attempting to read NT_ARM_GCS::user_gcs
| GETREGSET(nt=0x410, len=24) read 24 bytes
| Read NT_ARM_GCS::user_gcs = {
|     .features_enabled = 0x0000000000000000,
|     .features_locked  = 0x000000000093e780,
|     .gcspr_el0        = 0xffff800083a63d50,
| }

After this patch:

| # ./gcs-test
| Attempting to write NT_ARM_GCS::user_gcs = {
|     .features_enabled = 0x0000000000000000,
|     .features_locked  = 0x0000000000000000,
|     .gcspr_el0        = 0x900d900d900d900d,
| }
| SETREGSET(nt=0x410, len=24) wrote 24 bytes
|
| Attempting to read NT_ARM_GCS::user_gcs
| GETREGSET(nt=0x410, len=24) read 24 bytes
| Read NT_ARM_GCS::user_gcs = {
|     .features_enabled = 0x0000000000000000,
|     .features_locked  = 0x0000000000000000,
|     .gcspr_el0        = 0x900d900d900d900d,
| }
|
| Attempting partial write NT_ARM_GCS::user_gcs = {
|     .features_enabled = 0x0000000000000000,
|     .features_locked  = 0x1de7ec7edbadc0de,
|     .gcspr_el0        = 0x1de7ec7edbadc0de,
| }
| SETREGSET(nt=0x410, len=8) wrote 8 bytes
|
| Attempting to read NT_ARM_GCS::user_gcs
| GETREGSET(nt=0x410, len=24) read 24 bytes
| Read NT_ARM_GCS::user_gcs = {
|     .features_enabled = 0x0000000000000000,
|     .features_locked  = 0x0000000000000000,
|     .gcspr_el0        = 0x900d900d900d900d,
| }

Fixes: 7ec3b57cb29f8371 ("arm64/ptrace: Expose GCS via ptrace and core files")
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Mark Brown <broonie at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/ptrace.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index f17810030fa05..f79b0d5f71ac9 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1491,6 +1491,22 @@ static int poe_set(struct task_struct *target, const struct
 #endif
 
 #ifdef CONFIG_ARM64_GCS
+static void task_gcs_to_user(struct user_gcs *user_gcs,
+			     const struct task_struct *target)
+{
+	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;
+}
+
+static void task_gcs_from_user(struct task_struct *target,
+			       const struct user_gcs *user_gcs)
+{
+	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;
+}
+
 static int gcs_get(struct task_struct *target,
 		   const struct user_regset *regset,
 		   struct membuf to)
@@ -1503,9 +1519,7 @@ static int gcs_get(struct task_struct *target,
 	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;
+	task_gcs_to_user(&user_gcs, target);
 
 	return membuf_write(&to, &user_gcs, sizeof(user_gcs));
 }
@@ -1521,6 +1535,8 @@ static int gcs_set(struct task_struct *target, const struct
 	if (!system_supports_gcs())
 		return -EINVAL;
 
+	task_gcs_to_user(&user_gcs, target);
+
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_gcs, 0, -1);
 	if (ret)
 		return ret;
@@ -1528,9 +1544,7 @@ static int gcs_set(struct task_struct *target, const struct
 	if (user_gcs.features_enabled & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK)
 		return -EINVAL;
 
-	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;
+	task_gcs_from_user(target, &user_gcs);
 
 	return 0;
 }
-- 
2.30.2



From trunixs.kim at samsung.com  Thu Dec  5 04:25:16 2024
From: trunixs.kim at samsung.com (=?UTF-8?B?6rmA7YOc7JmE?=)
Date: Thu, 5 Dec 2024 21:25:16 +0900
Subject: [PATCH v3 3/3] arm64: dts: exynosautov920: add watchdog DT node
In-Reply-To: <171072ed-c35f-430e-a8c0-5cf718efed0c@kernel.org>
References: <20241021063903.793166-1-trunixs.kim@samsung.com>
	<CGME20241021063938epcas2p1c01c89badb532f08a46087a4907df7dc@epcas2p1.samsung.com>
	<20241021063903.793166-4-trunixs.kim@samsung.com>
	<961e1aca-cd90-4db1-87d7-afd2e542421e@kernel.org>
	<20241107103331.GA4818@www.linux-watchdog.org>
	<589c40e1-6a1c-4ef7-b0d8-b761b132578a@kernel.org>
	<20241107113325.GA5284@www.linux-watchdog.org>
	<c487babb-84a5-4e47-a58f-75fec55cbabb@kernel.org>
	<000201db46ac$8d7cfee0$a876fca0$@samsung.com>
	<88950a3a-c3de-4ff5-9ff8-9b85e1b0ad14@kernel.org>
	<171072ed-c35f-430e-a8c0-5cf718efed0c@kernel.org>
Message-ID: <000101db4710$bdac8310$39058930$@samsung.com>

on 05/12/2024 12:25 UTC+09:00, Taewan Kim wrote:
>>>>> But that's a never ending discussion, so we won't go into that :-).
>>>>
>>>> DTS is hardware description independent from Linux, therefore always
>>>> goes separate way than Linux drivers.
>>>>
>>>> Best regards,
>>>> Krzysztof
>>>
>>> I found that the first two patches have been added to the linux-next
>>> git, but the last patch has not yet been reviewed.
>>>
>>> I would appreciate it if you could take a look at this patch.
>>
>> Since this patch was applied, I dropped from my queue. I don't have it
>> in my inbox anymore. Please rebase, resolve any comments and resend.
>
>I found it in my inbox and tried to apply but it fails:
>error: patch failed: arch/arm64/boot/dts/exynos/exynosautov920.dtsi:172
>
>
>please rebase and resend.

Thanks to your hard work, I will resend it after rebase.

Best regards,
Taewan Kim



From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:26:38 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:26:38 +0100
Subject: [PATCH 5/5] arm64: dts: mediatek: mt8516: add keypad node
In-Reply-To: <20241204190524.21862-6-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
 <20241204190524.21862-6-val@packett.cool>
Message-ID: <6792791b-035c-4b50-809a-c561bfe21c1d@collabora.com>

Il 04/12/24 20:05, Val Packett ha scritto:
> Add a keypad matrix node for the MT8516/MT8167 SoC.
> 
> Signed-off-by: Val Packett <val at packett.cool>
> ---
>   arch/arm64/boot/dts/mediatek/mt8516.dtsi | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> index e30623ebac0e..3beb9f74ec79 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> @@ -220,6 +220,16 @@ timer: timer at 10008000 {
>   			clock-names = "clk13m", "bus";
>   		};
>   
> +		keypad: keypad at 10002000 {
> +			compatible = "mediatek,mt6779-keypad";

Noupe, you have to add your SoC to the compatible list... both here and in the
binding for mediatek.mt6779-keypad.yaml

compatible = "mediatek,mt8516-keypad", "mediatek,mt6779-keypad"

for the binding, it's just a simple addition to an enum, nothing else.

Cheers,
Angelo

> +			reg = <0 0x10002000 0 0x1000>;
> +			wakeup-source;
> +			interrupts = <GIC_SPI 149 IRQ_TYPE_EDGE_FALLING>;
> +			clocks = <&clk26m>;
> +			clock-names = "kpd";
> +			status = "disabled";
> +		};
> +
>   		syscfg_pctl: syscfg-pctl at 10005000 {
>   			compatible = "syscon";
>   			reg = <0 0x10005000 0 0x1000>;





From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:26:40 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:26:40 +0100
Subject: [PATCH 4/5] arm64: dts: mediatek: mt8516: reserve 192 KiB for
 TF-A
In-Reply-To: <20241204190524.21862-5-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
 <20241204190524.21862-5-val@packett.cool>
Message-ID: <1f2ce323-92ef-4386-a678-07e641f9a20c@collabora.com>

Il 04/12/24 20:05, Val Packett ha scritto:
> The Android DTB for the related MT8167 reserves 0x30000. This is likely
> correct for MT8516 Android devices as well, and there's never any harm
> in reserving 64KiB more.
> 
> Fixes: 5236347bde42 ("arm64: dts: mediatek: add dtsi for MT8516")
> Signed-off-by: Val Packett <val at packett.cool>

That has changed over time with new bootloaders, yes, so there's no harm
and it's actually a necessary change.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:26:41 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:26:41 +0100
Subject: [PATCH 3/5] arm64: dts: mediatek: mt8516: add i2c clock-div
 property
In-Reply-To: <20241204190524.21862-4-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
 <20241204190524.21862-4-val@packett.cool>
Message-ID: <8192b0b5-31ff-45d9-9013-949483425791@collabora.com>

Il 04/12/24 20:05, Val Packett ha scritto:
> Move the clock-div property from the pumpkin board dtsi to the SoC's
> since it belongs to the SoC itself and is required on other devices.
> 
> Fixes: 5236347bde42 ("arm64: dts: mediatek: add dtsi for MT8516")
> Signed-off-by: Val Packett <val at packett.cool>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:26:48 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:26:48 +0100
Subject: [PATCH 2/5] arm64: dts: mediatek: mt8516: fix wdt irq type
In-Reply-To: <20241204190524.21862-3-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
 <20241204190524.21862-3-val@packett.cool>
Message-ID: <ece47aeb-e9e2-4690-8103-a05a01ec7be5@collabora.com>

Il 04/12/24 20:05, Val Packett ha scritto:
> The GICv2 does not support EDGE_FALLING interrupts, so the watchdog
> would refuse to attach due to a failing check coming from the GIC driver.
> 
> Fixes: 5236347bde42 ("arm64: dts: mediatek: add dtsi for MT8516")
> Signed-off-by: Val Packett <val at packett.cool>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   arch/arm64/boot/dts/mediatek/mt8516.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> index 444429341302..098c32ebf678 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> @@ -206,7 +206,7 @@ watchdog at 10007000 {
>   			compatible = "mediatek,mt8516-wdt",
>   				     "mediatek,mt6589-wdt";
>   			reg = <0 0x10007000 0 0x1000>;
> -			interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_FALLING>;
> +			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
>   			#reset-cells = <1>;
>   		};
>   




From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:26:54 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:26:54 +0100
Subject: [PATCH 1/5] arm64: dts: mediatek: mt8516: fix GICv2 range
In-Reply-To: <20241204190524.21862-2-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
 <20241204190524.21862-2-val@packett.cool>
Message-ID: <9e19d117-ad78-43d0-990e-e3b881428601@collabora.com>

Il 04/12/24 20:05, Val Packett ha scritto:
> On the MT8167 which is based on the MT8516 DTS, the following error
> was appearing on boot, breaking interrupt operation:
> 
> GICv2 detected, but range too small and irqchip.gicv2_force_probe not set
> 
> Similar to what's been proposed for MT7622 which has the same issue,
> fix by using the range reported by force_probe.
> 
> Link: https://lore.kernel.org/all/YmhNSLgp%2Fyg8Vr1F at makrotopia.org/
> Fixes: 5236347bde42 ("arm64: dts: mediatek: add dtsi for MT8516")
> Signed-off-by: Val Packett <val at packett.cool>

Yeah, that's fine, I agree.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   arch/arm64/boot/dts/mediatek/mt8516.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> index d0b03dc4d3f4..444429341302 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> @@ -268,7 +268,7 @@ gic: interrupt-controller at 10310000 {
>   			interrupt-parent = <&gic>;
>   			interrupt-controller;
>   			reg = <0 0x10310000 0 0x1000>,
> -			      <0 0x10320000 0 0x1000>,
> +			      <0 0x1032f000 0 0x2000>,
>   			      <0 0x10340000 0 0x2000>,
>   			      <0 0x10360000 0 0x2000>;
>   			interrupts = <GIC_PPI 9



From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:27:01 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:27:01 +0100
Subject: [PATCH 0/5] MT8516/MT8167 dtsi fixes
In-Reply-To: <20241204190524.21862-1-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
Message-ID: <7bf536a5-30c1-43d8-9ea3-3aaea65c6b0a@collabora.com>

Il 04/12/24 20:05, Val Packett ha scritto:
> Hi everyone,
> 
> I've been working on mainline bringup on an MT8167 tablet I found at a
> junkyard sale (lenovo,tb7304f) for postmarketOS :3
> 
> This first series consists of basic device tree fixes for the MT8516
> dtsi that the MT8167 one inherits from.
> 

...Yes, but I don't see any patch that is introducing your TB7304F device here.

I strongly suggest you to also send one that achieves basic boot with UART console
as a first step for upstreaming your board, and then go for incremental changes
everytime you get a new feature working.

> The changes that follow add support for the MT6392 PMIC, and that's
> mostly been implemented by Fabien Parent back in 2020 and not merged:
> 
> <https://patchwork.kernel.org/project/linux-arm-kernel/patch/20201027181157.862927-3-fparent at baylibre.com/>
> <https://patchwork.kernel.org/project/linux-arm-kernel/patch/20201024200304.1427864-2-fparent at baylibre.com/>
> 
> but I have a couple changes on top of those patches (like adding the
> missing mt6392_set_buck_vosel_reg). I'm wondering what the best way to
> get this in would be, should I squash my changes and submit the "final"
> patches with a Co-developed-by tag?
> 

Generally, if the patches are only simple additions, you could send the original
patches without any author variation (and fixing that MT6392_IRQ_numbers enum
in the original ones because lower case please!) and then your patches on top
with your additions.

Otherwise, if you're "changing a lot of stuff" it makes sense to grab authorship
and add the Co-Developed-by... but I don't think you're changing much, honestly.

Of course, you'll have to drop the TXT additions, as now they are YAML (where the
YAML additions go to a separated dt-bindings patch!).

In the end, it's your choice - that's more or less a gist of how to do it.

> (Similar situation with DRM nodes, not merged due to "concerns about
> the driver architecture" in 2021, now missing GCE/CMDQ mailbox props:
> <https://lore.kernel.org/df4c57f9-115b-c4da-e656-e4bdec62c2d7 at gmail.com/>)
> 

The upstream driver just gained support for configuring the display paths
entirely in the devicetree as those are obviously device specific.

You can make use of that for upstreaming your tablet after adding the display
nodes (and bindings, if required) as if you go for the default configuration
that's probably not going to work because it's for the pumpkin boards which
will most probably have a different display pipeline compared to your board.

> By the way, is anyone familiar with PSCI cpuidle/hot-unplug issues on
> Mediatek Android devices from around this time? Specifically on this
> tablet, I can't make the cores come back from suspend. I have
> investigated local-timer-stop and arm,no-tick-in-suspend, Fabien pointed
> me to the mediatek timer and its required clocks, but nothing helped.
> Trying the psci_checker, I realized that it's not just suspend: they
> do not come back from hot-unplug either. Initial CPU_ON on boot is fine,
> but then after a CPU_OFF they do not actually come back when CPU_ON
> supposedly turns them on. Now I can't help but notice that the only DTS
> in mainline for a device that came with Android, mt6795-sony-xperia-m5,
> does not have any cpuidle nodes in its SoC's dtsi either..
> 

I did have some issues with an older bootloader on the Xperia M5 smartphone
and would even lock up at boot, because on the old firmwares the power
domains for the CPUs are not managed automatically by FW.

Before discovering that there was new FW (and this stuff is signed so you
cannot cross-flash...) I did engineer a solution, but never upstreamed it
because I did effectively lack time to clean it up and make it proper.

This solution is not upstreamable, as it makes the mtk-pm-domains driver
to be usable only as built-in and not as module anymore... so that would
probably need a separated driver or something like that.

Here's the (rather dirty, but working) code: 
https://gitlab.collabora.com/google/chromeos-kernel/-/commit/ae8f7048aadac03037391a64d9d79ca5af7b7a77

Cheers!
Angelo

> Val Packett (5):
>    arm64: dts: mediatek: mt8516: fix GICv2 range
>    arm64: dts: mediatek: mt8516: fix wdt irq type
>    arm64: dts: mediatek: mt8516: add i2c clock-div property
>    arm64: dts: mediatek: mt8516: reserve 192 KiB for TF-A
>    arm64: dts: mediatek: mt8516: add keypad node
> 
>   arch/arm64/boot/dts/mediatek/mt8516.dtsi      | 21 +++++++++++++++----
>   .../boot/dts/mediatek/pumpkin-common.dtsi     |  2 --
>   2 files changed, 17 insertions(+), 6 deletions(-)
> 





From dmitry.baryshkov at linaro.org  Thu Dec  5 04:29:03 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Dec 2024 14:29:03 +0200
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
Message-ID: <olxtqto5mbgofxg4iqjvsmpxxzz6zoj7pbwmoeklhfjiavqfvv@dyveek7hgtki>

On Thu, Dec 05, 2024 at 12:45:14PM +0100, AngeloGioacchino Del Regno wrote:
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/Kconfig           |  11 +-
>  drivers/gpu/drm/mediatek/Makefile          |   1 +
>  drivers/gpu/drm/mediatek/mtk_hdmi.c        | 724 +++------------------
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 425 ++++++++++++
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.h | 203 ++++++
>  5 files changed, 729 insertions(+), 635 deletions(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> 
> @@ -1026,19 +812,12 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi,
>  	return 0;
>  }
>  
> -static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
> +static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, u8 *buffer_spd, size_t bufsz_spd,
> +				    u8 *buffer_avi, size_t bufsz_avi,
> +				    struct drm_display_mode *mode)
>  {
> -	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> -
> -	hdmi->csp = HDMI_COLORSPACE_RGB;
> -	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> -	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> -	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> -	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> -	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> -
> -	return 0;
> +	mtk_hdmi_setup_avi_infoframe(hdmi, buffer_avi, bufsz_avi, mode);
> +	mtk_hdmi_setup_spd_infoframe(hdmi, buffer_spd, bufsz_spd, "mediatek", "On-chip HDMI");

Please use the HDMI Connector framework instead of handling everything
on your own.

>  }
>  
>  static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)

-- 
With best wishes
Dmitry


From heiko at sntech.de  Thu Dec  5 04:29:55 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 05 Dec 2024 13:29:55 +0100
Subject: [PATCH] clk: rockchip: add clock ID for CIF0/1 on RK3066
In-Reply-To: <5kesytgbhfununu5li4ychaw4newkctx4wuhlshks2ertfkd2t@jauqcntehv2z>
References: <20241205055122.11613-1-val@packett.cool>
 <5kesytgbhfununu5li4ychaw4newkctx4wuhlshks2ertfkd2t@jauqcntehv2z>
Message-ID: <1944322.g5d078U9FE@diego>

Hi Krzysztof,

Am Donnerstag, 5. Dezember 2024, 11:25:28 CET schrieb Krzysztof Kozlowski:
> On Thu, Dec 05, 2024 at 02:50:46AM -0300, Val Packett wrote:
> > RK3066 does have two "CIF" video capture interface blocks, add their
> > corresponding clock IDs so that they could be used.
> > 
> > Signed-off-by: Val Packett <val at packett.cool>
> > ---
> >  drivers/clk/rockchip/clk-rk3188.c             | 4 ++--
> >  include/dt-bindings/clock/rk3188-cru-common.h | 2 ++
> >  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> Please run scripts/checkpatch.pl and fix reported warnings. Then please
> run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
> Some warnings can be ignored, especially from --strict run, but the code
> here looks like it needs a fix. Feel free to get in touch if the warning
> is not clear.

I guess you're taking a shot of the indentation?

Though that is an intentional deviation, for the long lists of
clock-declarations, that is more a spreadsheet than actual code.

To give this some context, an excerpt from the rk3188 clock driver:

        COMPOSITE(0, "aclk_lcdc1_pre", mux_pll_src_cpll_gpll_p, 0,
                        RK2928_CLKSEL_CON(31), 15, 1, MFLAGS, 8, 5, DFLAGS,
                        RK2928_CLKGATE_CON(1), 4, GFLAGS),
        GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", 0,
                        RK2928_CLKGATE_CON(2), 1, GFLAGS),
        COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_pre", 0,
                        RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
                        RK2928_CLKGATE_CON(2), 2, GFLAGS),
        MUX(0, "cif_src", mux_pll_src_cpll_gpll_p, 0,
                        RK2928_CLKSEL_CON(29), 0, 1, MFLAGS),

Rockchip clocks most of the time consist of a mux+divider in one register
and a gate-bit in another. Most clocks are of the COMPOSITE-type above.
Surprisingly this is true since before 2013 - and even today :-) .

So the notation is
      TYPE(id, name, parent-name(s), main-clk-flags,
	MUXDIV-reg, muxoffset, muxwidth, muxflags, divoffset, divwidth, divflags,
	GATE-reg, gatebit, gateflags)

Having all these elements keep their relative position makes it way easier
on the eyes, compared to if they followed that opening parenthesis of each
individual line or maybe reflowing of the elements.

The only real change the clock definitions will see are fixes to wrong
register numbers or wrong bits (or missing clock-ids), so being able to
see check those easily is just nice to have.


Heiko




From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:36:18 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:36:18 +0100
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <olxtqto5mbgofxg4iqjvsmpxxzz6zoj7pbwmoeklhfjiavqfvv@dyveek7hgtki>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
 <olxtqto5mbgofxg4iqjvsmpxxzz6zoj7pbwmoeklhfjiavqfvv@dyveek7hgtki>
Message-ID: <f2862790-f613-4583-bec5-302e06c77d8d@collabora.com>

Il 05/12/24 13:29, Dmitry Baryshkov ha scritto:
> On Thu, Dec 05, 2024 at 12:45:14PM +0100, AngeloGioacchino Del Regno wrote:
>> In preparation for adding a new driver for the HDMI TX v2 IP,
>> split out the functions that will be common between the already
>> present mtk_hdmi (v1) driver and the new one.
>>
>> Since the probe flow for both drivers is 90% similar, add a common
>> probe function that will be called from each driver's .probe()
>> callback, avoiding lots of code duplication.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
>>   drivers/gpu/drm/mediatek/Kconfig           |  11 +-
>>   drivers/gpu/drm/mediatek/Makefile          |   1 +
>>   drivers/gpu/drm/mediatek/mtk_hdmi.c        | 724 +++------------------
>>   drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 425 ++++++++++++
>>   drivers/gpu/drm/mediatek/mtk_hdmi_common.h | 203 ++++++
>>   5 files changed, 729 insertions(+), 635 deletions(-)
>>   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.c
>>   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.h
>>
>> @@ -1026,19 +812,12 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi,
>>   	return 0;
>>   }
>>   
>> -static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
>> +static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, u8 *buffer_spd, size_t bufsz_spd,
>> +				    u8 *buffer_avi, size_t bufsz_avi,
>> +				    struct drm_display_mode *mode)
>>   {
>> -	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
>> -
>> -	hdmi->csp = HDMI_COLORSPACE_RGB;
>> -	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
>> -	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
>> -	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
>> -	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
>> -	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
>> -	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
>> -
>> -	return 0;
>> +	mtk_hdmi_setup_avi_infoframe(hdmi, buffer_avi, bufsz_avi, mode);
>> +	mtk_hdmi_setup_spd_infoframe(hdmi, buffer_spd, bufsz_spd, "mediatek", "On-chip HDMI");
> 
> Please use the HDMI Connector framework instead of handling everything
> on your own.
> 

Dmitry, my plan is to get the MediaTek HDMIv2 driver upstreamed *with* using
the HDMI helpers - this commit is only splitting the old HDMI v1 driver in
common parts and v1 handling.

This "handling everything on my own" is something that was already present
into the old v1 driver, I am *not adding* this code, but *moving it around*.

I cannot migrate the v1 driver to the HDMI helpers right now because in this
moment I have no way to test that and I don't want to break any functionality.

If you check patch 15, you'll see that I am indeed using all of the helper
goodies - but for now only on the new driver, and not on the old one.

I do plan to migrate the v1 driver to the new helpers as well, but I would
(please) really prefer to do that only after the v2 driver is upstreamed.

Is that okay for you?

Cheers,
Angelo

>>   }
>>   
>>   static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)
> 





From cristian.marussi at arm.com  Thu Dec  5 04:39:54 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Thu, 5 Dec 2024 12:39:54 +0000
Subject: [PATCH V4 4/5] soc: qcom: Introduce SCMI based Memlat (Memory
 Latency) governor
In-Reply-To: <61ce8618-cb08-06bc-9159-4ca26d703b14@quicinc.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-5-quic_sibis@quicinc.com>
 <2e9614de-1a93-4e17-a10c-945c50fb3f1a@quicinc.com>
 <61ce8618-cb08-06bc-9159-4ca26d703b14@quicinc.com>
Message-ID: <Z1GfGk0yQAVQKEVL@pluto>

On Thu, Dec 05, 2024 at 04:33:05PM +0530, Sibi Sankar wrote:
> 
> 
> On 11/29/24 15:27, Shivnandan Kumar wrote:
> > 
> >

Hi Sibi,

some rants down below :P
 
> > On 10/7/2024 11:40 AM, Sibi Sankar wrote:
> > > Introduce a client driver that uses the memlat algorithm string
> > > hosted on QCOM SCMI Generic Extension Protocol to detect memory
> > > latency workloads and control frequency/level of the various
> > > memory buses (DDR/LLCC/DDR_QOS).
> > > 

[snip]

> > > +??? /* Set the effective cpu frequency calculation method */
> > > +??? ret = ops->set_param(ph, &cpucp_freq_method,
> > > sizeof(cpucp_freq_method), MEMLAT_ALGO_STR,
> > > +???????????????? MEMLAT_SET_EFFECTIVE_FREQ_METHOD);
> > > +??? if (ret < 0)
> > > +??????? return dev_err_probe(&sdev->dev, ret,
> > > +???????????????????? "failed to set effective frequency calc method\n");
> > > +
> > 
> > Hi Sibi,
> 
> Hey Shiv,
> 
> Thanks for taking time to review the series!
> 
> > Since the MEMLAT_SET_EFFECTIVE_FREQ_METHOD command is not supported in
> > the legacy CPUCP firmware, it should be kept optional. This way, if the
> > legacy firmware is used, the driver will not return an error when the
> > CPUCP firmware returns -EOPNOTSUPP.
> 
> The vendor protocol with the current major/minor version is
> expected to work as is on x1e platforms. What legacy firmware
> are you referring to? All future SoCs that plan to adhere to
> it are expected to maintain this abi and can decide to make
> use of alternate mechanisms to calculating frequency based
> on additional dt properties set.
> 

Normally in the SCMI world you could leverage protocol versioning and
the standard PROTOCOL_MESSAGE_ATTRIBUTES(0x2) command to let the agent
investigate if the SCMI server it is speaking to implements or NOT a
specific command and which specific version of that command is understood
(with possibly varying size and fields)...

...BUT since your vendor protocol is 'Generic' and, as it stands, it
basically piggybacks any kind of binary payload (i.e. subcommands of
some kind of subprotocols of yours) into the same 4 get/set/start/stop
'Generic' ops, without even specifying the transmitted/received payload
sizes into the message itself....all of the possible SCMI versioning
autodiscovery and backward-compatibility capabilities happily go out of
the window because:

- your versioning refers to the generic protocol and you cannot possibly
  describe all the possible future subcommands (opaque payloads) variations
  and/or subcommands addition/removals purely on the major/minor version, AND
  even if you did that, NONE of such future variations will be documented
  anywhere since you are hiding all of this inside a bunch of binary blobs

- you dont even specify the payload sizes of the tx/rx 'Generic' payload
  subcommands so it becomes even difficult for both the server and the
  client to safely handle your 'Generic' subcommand message payloads

- you cannot issue a PROTOCOL_MESSAGE_ATTRIBUTE() to see if a specific
  subcommand is supported, because your subcommand is NOT really a protocol
  command but it is just one of the payloads of one of the 'Generic' protocol:
  you commmands are only set/get/start/stop (maybe some sort of hack
  could be doen around these...bit all will be even more flaky...)

- you dont implement NEGOTIATE_PROTOCOL_VERSION and so you cannot even
  check if the SCMI server that you are speaking to will agree to
  downgrade and 'speak' your Kernel SCMI agent (possibly older) 'Generic'
  protocol version

All of this basically defeats all of the SCMI general capabilities
around versioning and auto-discovery when it comes to your 'Generic' vendor
protocol, with the end result that you will have to be EXTREMELY confident
to perfectly match and keep in sync at all times your SCMI Server(FW) and
Client(Kernel) sides, without any possibility of coping with a such a mismatch
on the field by using some of the fallback/downgrade mechanism that you
threw out of the window...
(...and sorry but looking at the above xchange about 'legacy firmware' I am
 a bit skeptic about this as of now :D)

...as I said initially when reviewing this series, you can do whatever
you want within your Vendor protocol, but abusing the SCMI Vendor extensions
capabilities in such a way could end up bringing to the table more cons
(the above) than pros (some supposed 'simplification')

Thanks,
Cristian


From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:41:22 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:41:22 +0100
Subject: [PATCH 1/5] arm64: dts: mt6359: Add #sound-dai-cells property
In-Reply-To: <20241205-genio700-audio-output-v1-1-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
 <20241205-genio700-audio-output-v1-1-0e955c78c29e@collabora.com>
Message-ID: <787b0b53-547f-42eb-921f-a2635b462df5@collabora.com>

Il 05/12/24 13:13, N?colas F. R. A. Prado ha scritto:
> MT6359 provides digital audio interfaces. Add a #sound-dai-cells
> property for it to allow pointing to it from dai-link 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  Thu Dec  5 04:41:23 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:41:23 +0100
Subject: [PATCH 3/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Add DSP
 properties
In-Reply-To: <20241205-genio700-audio-output-v1-3-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
 <20241205-genio700-audio-output-v1-3-0e955c78c29e@collabora.com>
Message-ID: <ef8db876-bd06-4d5d-96ff-c570beefaa9a@collabora.com>

Il 05/12/24 13:13, N?colas F. R. A. Prado ha scritto:
> Add the mediatek,adsp and mediatek,dai-link properties to allow
> describing the DSP configuration in the sound card node, as is already
> the case for other MediaTek SoCs.
> 
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> ---
>   .../devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml      | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
> index ffe9347b543f5c687433862a21ad534b8aace27e..1e282c34dbd99851d3959b641096968c0b2e71be 100644
> --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
> +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
> @@ -33,6 +33,16 @@ properties:
>       $ref: /schemas/types.yaml#/definitions/phandle
>       description: The phandle of MT8188 ASoC platform.
>   
> +  mediatek,adsp:

This is already upstream

https://lore.kernel.org/r/20241105091246.3944946-1-fshao at chromium.org

> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: The phandle of MT8195 ADSP platform.
> +
> +  mediatek,dai-link:

That shouldn't be needed.

...so this patch can be dropped :-)

Cheers,
Angelo

> +    $ref: /schemas/types.yaml#/definitions/string-array
> +    description:
> +      A list of the desired dai-links in the sound card. Each entry is a
> +      name defined in the machine driver.
> +
>   patternProperties:
>     "^dai-link-[0-9]+$":
>       type: object
> 



From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:42:06 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:42:06 +0100
Subject: [PATCH 5/5] arm64: dts: mediatek: mt8390-genio-700-evk: Add sound
 output support
In-Reply-To: <20241205-genio700-audio-output-v1-5-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
 <20241205-genio700-audio-output-v1-5-0e955c78c29e@collabora.com>
Message-ID: <ce2f6f07-0276-4a8b-ae3f-4188c707c6e7@collabora.com>

Il 05/12/24 13:13, N?colas F. R. A. Prado ha scritto:
> Describe all the components to get sound output working on the two audio
> jacks, Earphone and Speaker, present on the Genio 700 EVK board with the
> audio DSP enabled.
> 
> Co-developed-by: Aary Patil <aary.patil at mediatek.com>
> Signed-off-by: Aary Patil <aary.patil at mediatek.com>
> Co-developed-by: Suhrid Subramaniam <suhrid.subramaniam at mediatek.com>
> Signed-off-by: Suhrid Subramaniam <suhrid.subramaniam at mediatek.com>
> Co-developed-by: parkeryang <Parker.Yang at mediatek.com>
> Signed-off-by: parkeryang <Parker.Yang at mediatek.com>
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> ---
>   .../boot/dts/mediatek/mt8390-genio-700-evk.dts     | 50 ++++++++++++++++++++++
>   1 file changed, 50 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
> index bb68665f0b2da80397b833db0241a06648a322a0..2fded39078773e81d8e0313d6b118b3064be308d 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
> @@ -92,6 +92,24 @@ vpu_mem: memory at 57000000 {
>   			compatible = "shared-dma-pool";
>   			reg = <0 0x57000000 0 0x1400000>; /* 20 MB */
>   		};
> +
> +		adsp_mem: memory at 60000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0 0x60000000 0 0xf00000>;
> +			no-map;
> +		};
> +
> +		afe_dma_mem: memory at 60f00000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0 0x60f00000 0 0x100000>;
> +			no-map;
> +		};
> +
> +		adsp_dma_mem: memory at 61000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0 0x61000000 0 0x100000>;
> +			no-map;
> +		};
>   	};
>   
>   	common_fixed_5v: regulator-0 {
> @@ -209,6 +227,16 @@ usb_p2_vbus: regulator-9 {
>   	};
>   };
>   
> +&adsp {
> +	memory-region = <&adsp_dma_mem>, <&adsp_mem>;
> +	status = "okay";
> +};
> +
> +&afe {
> +	memory-region = <&afe_dma_mem>;
> +	status = "okay";
> +};
> +
>   &gpu {
>   	mali-supply = <&mt6359_vproc2_buck_reg>;
>   	status = "okay";
> @@ -912,6 +940,28 @@ &scp {
>   	status = "okay";
>   };
>   
> +&sound {
> +	compatible = "mediatek,mt8390-mt6359-evk", "mediatek,mt8188-mt6359-evb";
> +	model = "mt8390-evk";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&audio_default_pins>;
> +	audio-routing =
> +		"Headphone", "Headphone L",
> +		"Headphone", "Headphone R";
> +	mediatek,adsp = <&adsp>;
> +	mediatek,dai-link = "DL_SRC_BE", "UL_SRC_BE", "AFE_SOF_DL2",
> +		"AFE_SOF_DL3", "AFE_SOF_UL4", "AFE_SOF_UL5";

Are you really, really, really, extremely sure that you need mediatek,dai-link?

I say you don't... :-)

Cheers,
Angelo



From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:41:11 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:41:11 +0100
Subject: [PATCH 4/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Allow
 DL_SRC/UL_SRC dai-links
In-Reply-To: <20241205-genio700-audio-output-v1-4-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
 <20241205-genio700-audio-output-v1-4-0e955c78c29e@collabora.com>
Message-ID: <f6e4b7c7-f67c-4d78-8875-39e640ebfede@collabora.com>

Il 05/12/24 13:13, N?colas F. R. A. Prado ha scritto:
> Add DL_SRC_BE and UL_SRC_BE as possible link-names for dai-links. These
> DAI back-ends are currently hardcoded in the driver to the
> MT6359 codec, but they may still be overridden with dai-links in the
> Devicetree to assign them additional codecs or even to make the
> dependency to the MT6359 codec explicit and allow device links to probe
> the components in the right order and avoid unnecessary probe deferrals.
> 
> 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  Thu Dec  5 04:41:15 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:41:15 +0100
Subject: [PATCH 2/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Add
 compatible for mt8390 evk
In-Reply-To: <20241205-genio700-audio-output-v1-2-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
 <20241205-genio700-audio-output-v1-2-0e955c78c29e@collabora.com>
Message-ID: <8290aaee-4ee6-43ec-9555-9a746e0db3a9@collabora.com>

Il 05/12/24 13:13, N?colas F. R. A. Prado ha scritto:
> Add a compatible for the MT8390 EVK. It is compatible with
> mediatek,mt8188-mt6359-evb so make that the fallback compatible.
> 
> 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  Thu Dec  5 04:43:59 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:43:59 +0100
Subject: [PATCH] ASoC: mediatek: mt8188-mt6359: Remove hardcoded dmic
 codec
In-Reply-To: <20241203-mt8188-6359-unhardcode-dmic-v1-1-346e3e5cbe6d@collabora.com>
References: <20241203-mt8188-6359-unhardcode-dmic-v1-1-346e3e5cbe6d@collabora.com>
Message-ID: <d95fcdb2-6519-4950-803b-20a60051cf3c@collabora.com>

Il 03/12/24 20:20, N?colas F. R. A. Prado ha scritto:
> Remove hardcoded dmic codec from the UL_SRC dai link to avoid requiring
> a dmic codec to be present for the driver to probe, as not every
> MT8188-based platform might need a dmic codec. The codec can be assigned
> to the dai link through the dai-link property in Devicetree on the
> platforms where it is needed.
> 
> No Devicetree currently relies on it so it is safe to remove without
> worrying about backward compatibility.
> 
> Fixes: 9f08dcbddeb3 ("ASoC: mediatek: mt8188-mt6359: support new board with nau88255")
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From andi.shyti at kernel.org  Thu Dec  5 04:49:09 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Thu, 5 Dec 2024 13:49:09 +0100
Subject: [PATCH] i2c: imx: fix divide by zero warning
In-Reply-To: <20241125141521.1612947-1-carlos.song@nxp.com>
References: <20241125141521.1612947-1-carlos.song@nxp.com>
Message-ID: <buy4r64ugalvyfqcctrq5l7ylnryjulf26yohgbzbnsy3asrbg@3ikvipa4keny>

Hi Carlos,

On Mon, Nov 25, 2024 at 10:15:21PM +0800, carlos.song at nxp.com wrote:
> From: Carlos Song <carlos.song at nxp.com>
> 
> Add "i2c_clk_rate / 2" check to avoid "divide by zero warning".
> i2c_clk_rate may be zero if i2c clock is disabled.
> 
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Signed-off-by: Clark Wang <xiaoning.wang at nxp.com>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>

merged to i2c/i2c-host,

thanks,
Andi


From jakobunt at gmail.com  Thu Dec  5 04:51:28 2024
From: jakobunt at gmail.com (Jakob Unterwurzacher)
Date: Thu, 5 Dec 2024 13:51:28 +0100
Subject: [PATCH] arm64: dts: rockchip: increase gmac rx_delay to 0x11 on rk3399-puma
In-Reply-To: <CAMdYzYr9bULWou5gf43G-AywREWRCOhHmJ-fOQ1cEDWJSmGSdQ@mail.gmail.com>
References: <20241202090408.201662-1-jakob.unterwurzacher@cherry.de>
 <63b3be80-cb6c-49e5-858f-70fd826140c5@cherry.de> <2578458.4XsnlVU6TS@diego> <CAMdYzYr9bULWou5gf43G-AywREWRCOhHmJ-fOQ1cEDWJSmGSdQ@mail.gmail.com>
Message-ID: <CAPv9Zmmz2W6aU16n1NYZvCrMcsXL8QK3d-mtfWy6d0vsTaNYQw@mail.gmail.com>

On Thu, Dec 5, 2024 at 2:33?AM Peter Geis <pgwipeout at gmail.com> wrote:
> > > > Cycling through the rx_delay range on two boards shows that is a large
> > > > "good" region from 0x11 to 0x35 (see below for details).
> > > >
> > >
> > > Is this missing a "there" after that? "that there is a large good region"?
>
> That large good region is actually an eye that you are aligning to the
> clock signal. The board is on the tail end of the eye where it is
> barely working. This value is supposed to be tuned to be in the middle
> of that eye. You may want to test the old boards against the new
> boards, because if the original board was tuned correctly something
> may have changed in hardware that caused a significant shift in the
> eye location. Examples of this would be changing to a new phy,
> enabling phy delays, or changes in the trace length. If this is the
> case, you'll probably want to make a new variant of the dts to cover
> this.

Thanks for the comment.

Nothing should have changed on the board, and I dug out a really old
one to verify. It behaves the same.
0x10 seems to be the lower edge of things still working.

I will put rx_delay in the center of the eye with the v3 patch.

I also checked tx_delay, and we already seem to be in the middle of
the eye, so I won't touch it.

Best regards,
Jakob


From angelogioacchino.delregno at collabora.com  Thu Dec  5 04:51:57 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 13:51:57 +0100
Subject: [PATCH] ASoC: mediatek: mt8188: Enable apll1 clock during reg rw
 to prevent hang
In-Reply-To: <a10dbdf265194e77a69b6e40afa3df9636b3ab14.camel@mediatek.com>
References: <20241203-mt8188-afe-fix-hang-disabled-apll1-clk-v1-1-07cdd7760834@collabora.com>
 <a10dbdf265194e77a69b6e40afa3df9636b3ab14.camel@mediatek.com>
Message-ID: <a70a0521-985d-43a4-a1fa-36eb733d5ca9@collabora.com>

Il 04/12/24 13:17, Trevor Wu (???) ha scritto:
> On Tue, 2024-12-03 at 17:07 -0300, N?colas F. R. A. Prado wrote:
> 
>>
>> Currently, booting the Genio 700 EVK board with the MT8188 sound
>> platform driver configured as a module (CONFIG_SND_SOC_MT8188=m)
>> results
>> in a system hang right when the HW registers for the audio controller
>> are read:
>>
>>    mt8188-audio 10b10000.audio-controller: No cache defaults, reading
>> back from HW
>>
>> The hang doesn't occur with the driver configured as builtin as then
>> the
>> unused clocks are still enabled.
>>
>> Enable the apll1 clock during register read/write to prevent the
>> hang.
>>
>> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
>> ---
>>   sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
>> b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
>> index
>> e69c1bb2cb239596dee50b166c20192d5408be10..fb8cf286df3f02ac076528b898f
>> d0d7a708ec1ea 100644
>> --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
>> +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
>> @@ -587,6 +587,8 @@ int mt8188_afe_enable_reg_rw_clk(struct
>> mtk_base_afe *afe)
>>          mt8188_afe_enable_clk(afe, afe_priv-
>>> clk[MT8188_CLK_AUD_A1SYS_HP]);
>>          mt8188_afe_enable_clk(afe, afe_priv-
>>> clk[MT8188_CLK_AUD_A1SYS]);
>>
>> +       mt8188_afe_enable_clk(afe, afe_priv-
>>> clk[MT8188_CLK_APMIXED_APLL1]);
>> +
>>          return 0;
>>   }
> Hi Nicolas,
> 
> If I understand correctly, APLL1 should be the parent clock of
> AUD_A1SYS_HP and AUD_A1SYS, so it should be enabled automatically by
> CCF.
> 
> I'm not sure why you resolved the hang issue after enabling APLL1.
> Could you share more details about the solution?
> 

Hmm. Now I see what's happening here...

Nicolas, Trevor,

Possible parents for top_a1sys_hp are:
  - clk26m
  - apll1_d4

...what's happening here most probably is that after the clock gets disabled as
unused, it gets parented to clk26m by default as that is parent index 0... and
something else in AFE needs APLL1 to feed a clock to .. something .. to allow
register access.

Trevor, do you know why is this IP unaccessible when A1SYS is parented to clk26m?

That might give Nicolas a definitive hint about how to resolve this issue.

Cheers,
Angelo

> Thanks,
> Trevor
> 
>>
>> @@ -594,6 +596,8 @@ int mt8188_afe_disable_reg_rw_clk(struct
>> mtk_base_afe *afe)
>>   {
>>          struct mt8188_afe_private *afe_priv = afe->platform_priv;
>>
>> +       mt8188_afe_disable_clk(afe, afe_priv-
>>> clk[MT8188_CLK_APMIXED_APLL1]);
>> +
>>          mt8188_afe_disable_clk(afe, afe_priv-
>>> clk[MT8188_CLK_AUD_A1SYS]);
>>          mt8188_afe_disable_clk(afe, afe_priv-
>>> clk[MT8188_CLK_AUD_A1SYS_HP]);
>>          mt8188_afe_disable_clk(afe, afe_priv-
>>> clk[MT8188_CLK_AUD_AFE]);
>>
>> ---
>> base-commit: b852e1e7a0389ed6168ef1d38eb0bad71a6b11e8
>> change-id: 20241203-mt8188-afe-fix-hang-disabled-apll1-clk-
>> b3c11782cbaf
>>
>> Best regards,
>> --
>> N?colas F. R. A. Prado <nfraprado at collabora.com>
>>
>>



From andyshrk at 163.com  Thu Dec  5 04:53:25 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 5 Dec 2024 20:53:25 +0800 (CST)
Subject: [PATCH v7] rockchip/drm: vop2: add support for gamma LUT
In-Reply-To: <12938960.VsHLxoZxqI@diego>
References: <20241101185545.559090-3-pZ010001011111@proton.me>
 <9Rp0NJW2QG5qDduowVaialZWN6xTe9KJFciu7Q2LERJZQXsUgFvMGXfcFaNznIEJEBpZeOdZPuL4fxOEFduaSJLuQJ3cIvN-fx2lEzYSBKE=@proton.me>
 <12938960.VsHLxoZxqI@diego>
Message-ID: <7877dddf.b3b8.19396e1df66.Coremail.andyshrk@163.com>


Hi Piotr,

At 2024-12-05 16:54:09, "Heiko St?bner" <heiko at sntech.de> wrote:
>Hi Piotr,
>
>Am Mittwoch, 4. Dezember 2024, 16:45:21 CET schrieb Piotr Zalewski:
>> I just noticed that after coming out of suspend gamma LUT is lost and must
>> be rewritten by userspace.
>> 
>> So I guess it will be needed to save LUT to a buffer and rewrite it after
>> going out of suspend during modeset?
>
>Most likely ... the old vop does this already too, so I guess you can
>get inspiration from there. (gamma_set call in vop_crtc_atomic_enable())

I guess it returned because crtc_state->color_mgmt_changed is false when called from 
vop2_crtc_atomic_enable from s2r.


static void vop2_crtc_atomic_try_set_gamma(struct vop2 *vop2,
                                           struct vop2_video_port *vp,
                                           struct drm_crtc *crtc,
                                           struct drm_crtc_state *crtc_state)
{
        if (!vop2->lut_regs || !crtc_state->color_mgmt_changed)
                return;

        if (!crtc_state->gamma_lut) {
                vop2_vp_dsp_lut_disable(vp);
                return;
        }

        if (vop2_supports_seamless_gamma_lut_update(vop2))
                vop2_crtc_atomic_set_gamma_seamless(vop2, vp, crtc);
        else
                vop2_crtc_atomic_set_gamma_rk356x(vop2, vp, crtc);
}
>
>> I checked the patch isn't yet in the "official" linux-next.
>
>The patch is in drm-misc-next:
>https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/4f537776340dab2b680a4d8554567f6884240d0b
>
>so should turn up in linux-next at some point. This also means, please
>provide a follow-up patch for the suspend handling.
>
>Thanks a lot
>Heiko
>

From dmitry.baryshkov at linaro.org  Thu Dec  5 04:56:18 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Dec 2024 14:56:18 +0200
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
Message-ID: <4lvsvo6vsc7bipcgftsq3mzunwxoka3wjqad42ptr37oz77zub@5uarhvjmcxnc>

On Thu, Dec 05, 2024 at 12:45:17PM +0100, AngeloGioacchino Del Regno wrote:
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit and that also poses a slight
> difference between the V2 and V1 controllers in how they handle
> Hotplug Detection (HPD).
> 
> While the v1 controller was using the CEC controller to check
> HDMI cable connection and disconnection, in this driver the v2
> one does not.
> 
> This is due to the fact that on parts with v2 designs, like the
> MT8195 SoC, there is one CEC controller shared between the HDMI
> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> adding support to use the CEC HW to wake up the HDMI controllers
> it is necessary to have support for one TX, one RX *and* for both
> at the same time.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/Kconfig            |    8 +
>  drivers/gpu/drm/mediatek/Makefile           |    4 +
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.c  |    5 +
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.h  |    1 +
>  drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c  |  403 +++++
>  drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h |  263 ++++
>  drivers/gpu/drm/mediatek/mtk_hdmi_v2.c      | 1488 +++++++++++++++++++
>  7 files changed, 2172 insertions(+)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
> 
> diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
> index 73459f07dae3..8127576be1eb 100644
> --- a/drivers/gpu/drm/mediatek/Kconfig
> +++ b/drivers/gpu/drm/mediatek/Kconfig
> @@ -50,3 +50,11 @@ config DRM_MEDIATEK_HDMI
>  	select PHY_MTK_HDMI
>  	help
>  	  DRM/KMS HDMI driver for Mediatek SoCs
> +
> +config DRM_MEDIATEK_HDMI_V2
> +	tristate "DRM HDMI v2 IP support for MediaTek SoCs"
> +	depends on DRM_MEDIATEK
> +	select DRM_MEDIATEK_HDMI_COMMON
> +	select PHY_MTK_HDMI
> +	help
> +	  DRM/KMS HDMI driver for MediaTek SoCs with HDMIv2 IP
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index 8973d7ba37d3..928a850f707f 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -25,7 +25,11 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
>  			  mtk_hdmi.o \
>  			  mtk_hdmi_ddc.o
>  
> +mediatek-drm-hdmi-v2-objs := mtk_hdmi_ddc_v2.o \
> +			     mtk_hdmi_v2.o
> +
>  obj-$(CONFIG_DRM_MEDIATEK_HDMI_COMMON) += mtk_hdmi_common.o
>  obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
> +obj-$(CONFIG_DRM_MEDIATEK_HDMI_V2) += mediatek-drm-hdmi-v2.o
>  
>  obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> index 0f60842462b0..90f603f34cde 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> @@ -295,6 +295,11 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device
>  	if (IS_ERR(hdmi->regs))
>  		return PTR_ERR(hdmi->regs);
>  
> +	/* Populate HDMI sub-devices if present */
> +	ret = devm_of_platform_populate(&pdev->dev);
> +	if (ret)
> +		return ret;
> +
>  	remote = of_graph_get_remote_node(np, 1, 0);
>  	if (!remote)
>  		return dev_err_probe(dev, -EINVAL, "Cannot find HDMI input port\n");
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> index 15121e8548f3..8cfff39b0d90 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> @@ -176,6 +176,7 @@ struct mtk_hdmi_conf {
>  	bool tz_disabled;
>  	bool cea_modes_only;
>  	unsigned long max_mode_clock;
> +	u32 reg_hdmi_tx_cfg;
>  };
>  
>  static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
> new file mode 100644
> index 000000000000..297b8b6f668c
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
> @@ -0,0 +1,403 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek HDMI v2 Display Data Channel Driver
> + *
> + * Copyright (c) 2021 MediaTek Inc.
> + * Copyright (c) 2021 BayLibre, SAS
> + * Copyright (c) 2024 Collabora Ltd.
> + *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/i2c.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/semaphore.h>
> +#include <linux/slab.h>
> +#include <linux/time.h>
> +#include <linux/types.h>
> +
> +#include <drm/drm_edid.h>
> +
> +#include "mtk_hdmi_common.h"
> +#include "mtk_hdmi_regs_v2.h"
> +
> +#define DDC2_DLY_CNT 572 /* BIM=208M/(v*4) = 90Khz */
> +#define DDC2_DLY_CNT_EDID 832 /* BIM=208M/(v*4) = 62.5Khz */
> +#define SI2C_ADDR_READ 0xf4
> +#define SCDC_I2C_SLAVE_ADDRESS 0x54
> +
> +struct mtk_hdmi_ddc {
> +	struct device *dev;
> +	void __iomem *regs;
> +	struct clk *clk;
> +	struct i2c_adapter adap;
> +	/* Serialize read/write operations */
> +	struct mutex mtx;
> +};
> +
> +static int mtk_ddc_check_and_rise_low_bus(struct mtk_hdmi_ddc *ddc)
> +{
> +	u32 val;
> +
> +	regmap_read(ddc->regs, HDCP2X_DDCM_STATUS, &val);
> +	if (val & DDC_I2C_BUS_LOW) {
> +		regmap_update_bits(ddc->regs, DDC_CTRL, DDC_CTRL_CMD,
> +				   FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_CLOCK_SCL));
> +		usleep_range(250, 300);
> +	}
> +
> +	if (val & DDC_I2C_NO_ACK) {
> +		u32 ddc_ctrl, hpd_ddc_ctrl, hpd_ddc_status;
> +
> +		regmap_read(ddc->regs, DDC_CTRL, &ddc_ctrl);
> +		regmap_read(ddc->regs, HPD_DDC_CTRL, &hpd_ddc_ctrl);
> +		regmap_read(ddc->regs, HPD_DDC_STATUS, &hpd_ddc_status);
> +	}
> +
> +	if (val & DDC_I2C_NO_ACK)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int mtk_ddc_wr_one(struct mtk_hdmi_ddc *ddc, u16 addr_id,
> +			  u16 offset_id, u8 wr_data)
> +{
> +	u32 val;
> +	int ret;
> +
> +	/* If down, rise bus for write operation */
> +	mtk_ddc_check_and_rise_low_bus(ddc);
> +
> +	regmap_update_bits(ddc->regs, HPD_DDC_CTRL, HPD_DDC_DELAY_CNT,
> +			   FIELD_PREP(HPD_DDC_DELAY_CNT, DDC2_DLY_CNT));
> +
> +	regmap_write(ddc->regs, SI2C_CTRL,
> +		     FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
> +		     FIELD_PREP(SI2C_WDATA, wr_data) |
> +		     SI2C_WR);
> +
> +	regmap_write(ddc->regs, DDC_CTRL,
> +		     FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_SEQ_WRITE) |
> +		     FIELD_PREP(DDC_CTRL_DIN_CNT, 1) |
> +		     FIELD_PREP(DDC_CTRL_OFFSET, offset_id) |
> +		     FIELD_PREP(DDC_CTRL_ADDR, addr_id));
> +	usleep_range(1000, 1250);
> +
> +	ret = regmap_read_poll_timeout(ddc->regs, HPD_DDC_STATUS, val,
> +				       !(val & DDC_I2C_IN_PROG), 500, 1000);
> +	if (ret) {
> +		dev_err(ddc->dev, "DDC I2C write timeout\n");
> +		return ret;
> +	}
> +
> +	/* The I2C bus might be down after WR operation: rise it again */
> +	ret = mtk_ddc_check_and_rise_low_bus(ddc);
> +	if (ret) {
> +		dev_err(ddc->dev, "Error during write operation: No ACK\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_ddcm_read_hdmi(struct mtk_hdmi_ddc *ddc, u16 dly_cnt, u16 uc_dev,
> +			      u8 addr, u8 *puc_value, u16 data_cnt)
> +{
> +	u16 i, loop_counter, temp_length, uc_idx;
> +	u32 rem, uc_read_count, val;
> +	int ret;
> +
> +	if (!puc_value || !data_cnt || !dly_cnt) {
> +		dev_err(ddc->dev, "Bad DDCM read request\n");
> +		return 0;
> +	}
> +
> +	mtk_ddc_check_and_rise_low_bus(ddc);
> +
> +	regmap_update_bits(ddc->regs, DDC_CTRL, DDC_CTRL_CMD,
> +			   FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_CLEAR_FIFO));
> +
> +	if (data_cnt >= 16) {
> +		temp_length = 16;
> +		loop_counter = data_cnt;
> +
> +		rem = do_div(loop_counter, temp_length);
> +		if (rem)
> +			loop_counter++;
> +	} else {
> +		temp_length = data_cnt;
> +		loop_counter = 1;
> +	}
> +
> +	if (uc_dev >= DDC_ADDR && dly_cnt < DDC2_DLY_CNT_EDID)
> +		dly_cnt = DDC2_DLY_CNT_EDID;
> +
> +	regmap_update_bits(ddc->regs, HPD_DDC_CTRL, HPD_DDC_DELAY_CNT,
> +			   FIELD_PREP(HPD_DDC_DELAY_CNT, dly_cnt));
> +
> +	for (i = 0; i < loop_counter; i++) {
> +		rem = data_cnt % 16;
> +
> +		if (i > 0 && i == (loop_counter - 1) && rem)
> +			temp_length = rem;
> +
> +		/* 0x51 - 0x53: Flow control */
> +		if (uc_dev > DDC_ADDR && uc_dev <= 0x53) {
> +			regmap_update_bits(ddc->regs, SCDC_CTRL, SCDC_DDC_SEGMENT,
> +					   FIELD_PREP(SCDC_DDC_SEGMENT, uc_dev - DDC_ADDR));
> +
> +			regmap_write(ddc->regs, DDC_CTRL,
> +				     FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_ENH_READ_NOACK) |
> +				     FIELD_PREP(DDC_CTRL_DIN_CNT, temp_length) |
> +				     FIELD_PREP(DDC_CTRL_OFFSET, addr + i * temp_length) |
> +				     FIELD_PREP(DDC_CTRL_ADDR, DDC_ADDR));
> +		} else {
> +			u16 offset;
> +
> +			if (addr != 0x43)
> +				offset = i * 16;
> +			else
> +				offset = 0;
> +
> +			regmap_write(ddc->regs, DDC_CTRL,
> +				     FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_SEQ_READ_NOACK) |
> +				     FIELD_PREP(DDC_CTRL_DIN_CNT, temp_length) |
> +				     FIELD_PREP(DDC_CTRL_OFFSET, addr + offset) |
> +				     FIELD_PREP(DDC_CTRL_ADDR, uc_dev));
> +		}
> +		usleep_range(5000, 5500);
> +
> +		ret = regmap_read_poll_timeout(ddc->regs, HPD_DDC_STATUS, val,
> +					       !(val & DDC_I2C_IN_PROG), 1000,
> +					       500 * (temp_length + 5));
> +		if (ret) {
> +			dev_err(ddc->dev, "Timeout waiting for DDC I2C\n");
> +			return ret;
> +		}
> +
> +		ret = mtk_ddc_check_and_rise_low_bus(ddc);
> +		if (ret) {
> +			dev_err(ddc->dev, "Error during read operation: No ACK\n");
> +			return ret;
> +		}
> +
> +		for (uc_idx = 0; uc_idx < temp_length; uc_idx++) {
> +			unsigned int read_idx = i * 16 + uc_idx;
> +
> +			regmap_write(ddc->regs, SI2C_CTRL,
> +				     FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
> +				     SI2C_RD);
> +
> +			regmap_read(ddc->regs, HPD_DDC_STATUS, &val);
> +			puc_value[read_idx] = FIELD_GET(DDC_DATA_OUT, val);
> +
> +			regmap_write(ddc->regs, SI2C_CTRL,
> +				     FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
> +				     SI2C_CONFIRM_READ);
> +
> +			/*
> +			 * If HDMI IP gets reset during EDID read, DDC read
> +			 * operation will fail and its delay counter will be
> +			 * reset to 400.
> +			 */
> +			regmap_read(ddc->regs, HPD_DDC_CTRL, &val);
> +			if (FIELD_GET(HPD_DDC_DELAY_CNT, val) < DDC2_DLY_CNT)
> +				return 0;
> +
> +			uc_read_count = read_idx + 1;
> +		}
> +	}
> +	if (uc_read_count > U8_MAX)
> +		dev_warn(ddc->dev, "Invalid read data count %u\n", uc_read_count);
> +
> +	return uc_read_count;
> +}
> +
> +static int mtk_hdmi_fg_ddc_data_read(struct mtk_hdmi_ddc *ddc, u16 b_dev,
> +				     u8 data_addr, u16 data_cnt, u8 *pr_data)
> +{
> +	int read_data_cnt;
> +	u16 req_data_cnt;
> +
> +	if (!pr_data || !data_cnt)
> +		return -EINVAL;
> +
> +	req_data_cnt = U8_MAX - data_addr + 1;
> +	if (req_data_cnt > data_cnt)
> +		req_data_cnt = data_cnt;
> +
> +	mutex_lock(&ddc->mtx);
> +
> +	regmap_set_bits(ddc->regs, HDCP2X_POL_CTRL, HDCP2X_DIS_POLL_EN);
> +
> +	read_data_cnt = mtk_ddcm_read_hdmi(ddc, DDC2_DLY_CNT, b_dev, data_addr,
> +					   pr_data, req_data_cnt);
> +
> +	mutex_unlock(&ddc->mtx);
> +
> +	if (read_data_cnt < 0)
> +		return read_data_cnt;
> +	else if (read_data_cnt != req_data_cnt)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int mtk_hdmi_ddc_fg_data_write(struct mtk_hdmi_ddc *ddc, u16 b_dev,
> +				      u8 data_addr, u16 data_cnt, u8 *pr_data)
> +{
> +	int i = 0, ret;
> +
> +	mutex_lock(&ddc->mtx);
> +
> +	regmap_set_bits(ddc->regs, HDCP2X_POL_CTRL, HDCP2X_DIS_POLL_EN);
> +	do {
> +		ret = mtk_ddc_wr_one(ddc, b_dev, data_addr + i, pr_data[i]);
> +		if (ret)
> +			break;
> +	} while (++i < data_cnt);
> +
> +	mutex_unlock(&ddc->mtx);
> +
> +	return ret;
> +}
> +
> +static int mtk_hdmi_ddc_v2_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
> +{
> +	struct mtk_hdmi_ddc *ddc;
> +	u8 offset = 0;
> +	int i, ret;
> +
> +	if (!adapter || !adapter->algo_data || !msgs)
> +		return -EINVAL;
> +
> +	ddc = adapter->algo_data;
> +
> +	for (i = 0; i < num; i++) {
> +		struct i2c_msg *msg = &msgs[i];
> +
> +		if (!msg->buf) {
> +			pr_err("XFER: No message buffer\n");
> +			return -EINVAL;
> +		}
> +
> +		if (msg->flags & I2C_M_RD) {
> +			/*
> +			 * The underlying DDC hardware always issues a write request
> +			 * that assigns the read offset as part of the read operation,
> +			 * therefore, use the `offset` value assigned in the previous
> +			 * write request from drm_edid
> +			 */
> +			ret = mtk_hdmi_fg_ddc_data_read(ddc, msg->addr, offset,
> +							msg->len, &msg->buf[0]);
> +			if (ret)
> +				return ret;
> +		} else {
> +			ret = mtk_hdmi_ddc_fg_data_write(ddc, msg->addr, msg->buf[0],
> +							 msg->len - 1, &msg->buf[1]);
> +			if (ret)
> +				return ret;
> +
> +			/*
> +			 * Store the offset value requested by drm_edid or by
> +			 * scdc to use in subsequent read requests.
> +			 */
> +			if ((msg->addr == DDC_ADDR || msg->addr == SCDC_I2C_SLAVE_ADDRESS) &&
> +			    msg->len == 1) {
> +				offset = msg->buf[0];
> +			}
> +		}
> +	}
> +
> +	return i;
> +}
> +
> +static u32 mtk_hdmi_ddc_v2_func(struct i2c_adapter *adapter)
> +{
> +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
> +}
> +
> +static const struct i2c_algorithm mtk_hdmi_ddc_v2_algorithm = {
> +	.master_xfer = mtk_hdmi_ddc_v2_xfer,
> +	.functionality = mtk_hdmi_ddc_v2_func,
> +};
> +
> +static int mtk_hdmi_ddc_v2_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_hdmi_ddc *ddc;
> +	int ret;
> +
> +	ddc = devm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL);
> +	if (!ddc)
> +		return -ENOMEM;
> +
> +	ddc->dev = dev;
> +	ddc->regs = device_node_to_regmap(dev->parent->of_node);
> +	if (IS_ERR_OR_NULL(ddc->regs))
> +		return dev_err_probe(dev,
> +				     IS_ERR(ddc->regs) ? PTR_ERR(ddc->regs) : -EINVAL,
> +				     "Cannot get regmap\n");
> +
> +	ddc->clk = devm_clk_get_enabled(dev, NULL);
> +	if (IS_ERR(ddc->clk))
> +		return dev_err_probe(dev, PTR_ERR(ddc->clk), "Cannot get DDC clock\n");
> +
> +	mutex_init(&ddc->mtx);
> +
> +	strscpy(ddc->adap.name, "mediatek-hdmi-ddc-v2", sizeof(ddc->adap.name));
> +	ddc->adap.owner = THIS_MODULE;
> +	ddc->adap.algo = &mtk_hdmi_ddc_v2_algorithm;
> +	ddc->adap.retries = 3;
> +	ddc->adap.dev.of_node = dev->of_node;
> +	ddc->adap.algo_data = ddc;
> +	ddc->adap.dev.parent = &pdev->dev;
> +
> +	ret = devm_pm_runtime_enable(&pdev->dev);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret, "Cannot enable Runtime PM\n");
> +
> +	pm_runtime_get_sync(dev);
> +
> +	ret = devm_i2c_add_adapter(dev, &ddc->adap);
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "Cannot add DDC I2C adapter\n");
> +
> +	platform_set_drvdata(pdev, ddc);
> +	return 0;
> +}
> +
> +static const struct of_device_id mtk_hdmi_ddc_v2_match[] = {
> +	{ .compatible = "mediatek,mt8195-hdmi-ddc" },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_v2_match)
> +
> +struct platform_driver mtk_hdmi_ddc_v2_driver = {
> +	.probe = mtk_hdmi_ddc_v2_probe,
> +	.driver = {
> +		.name = "mediatek-hdmi-ddc-v2",
> +		.of_match_table = mtk_hdmi_ddc_v2_match,
> +	},
> +};
> +module_platform_driver(mtk_hdmi_ddc_v2_driver);
> +
> +MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>");
> +MODULE_AUTHOR("Can Zeng <can.zeng at mediatek.com>");
> +MODULE_DESCRIPTION("MediaTek HDMIv2 DDC Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h b/drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
> new file mode 100644
> index 000000000000..521b35c7e14d
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
> @@ -0,0 +1,263 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Copyright (c) 2021 BayLibre, SAS
> + * Copyright (c) 2024 Collabora Ltd.
> + *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> + */
> +
> +#ifndef _MTK_HDMI_REGS_H
> +#define _MTK_HDMI_REGS_H
> +
> +/* HDMI_TOP Config */
> +#define TOP_CFG00			0x000
> +#define  HDMI2_ON			BIT(2)
> +#define  HDMI_MODE_HDMI			BIT(3)
> +#define  SCR_ON				BIT(4)
> +#define  TMDS_PACK_MODE			GENMASK(9, 8)
> +#define   TMDS_PACK_MODE_8BPP		0
> +#define   TMDS_PACK_MODE_10BPP		1
> +#define   TMDS_PACK_MODE_12BPP		2
> +#define   TMDS_PACK_MODE_16BPP		3
> +#define  DEEPCOLOR_PKT_EN		BIT(12)
> +#define  HDMI_ABIST_VIDEO_FORMAT	GENMASK(21, 16)
> +#define  HDMI_ABIST_ENABLE		BIT(31)
> +#define TOP_CFG01 0x004
> +#define  CP_SET_MUTE_EN			BIT(0)
> +#define  CP_CLR_MUTE_EN			BIT(1)
> +#define  NULL_PKT_EN			BIT(2)
> +#define  NULL_PKT_VSYNC_HIGH_EN		BIT(3)
> +
> +/* HDMI_TOP Audio: Channel Mapping */
> +#define TOP_AUD_MAP			0x00c
> +#define  SD0_MAP			GENMASK(2, 0)
> +#define  SD1_MAP			GENMASK(6, 4)
> +#define  SD2_MAP			GENMASK(10, 8)
> +#define  SD3_MAP			GENMASK(14, 12)
> +#define  SD4_MAP			GENMASK(18, 16)
> +#define  SD5_MAP			GENMASK(22, 20)
> +#define  SD6_MAP			GENMASK(26, 24)
> +#define  SD7_MAP			GENMASK(30, 28)
> +
> +/* Auxiliary Video Information (AVI) Infoframe */
> +#define TOP_AVI_HEADER			0x024
> +#define TOP_AVI_PKT00			0x028
> +#define TOP_AVI_PKT01			0x02C
> +#define TOP_AVI_PKT02			0x030
> +#define TOP_AVI_PKT03			0x034
> +#define TOP_AVI_PKT04			0x038
> +#define TOP_AVI_PKT05			0x03C
> +
> +/* Audio Interface Infoframe */
> +#define TOP_AIF_HEADER			0x040
> +#define TOP_AIF_PKT00			0x044
> +#define TOP_AIF_PKT01			0x048
> +#define TOP_AIF_PKT02			0x04c
> +#define TOP_AIF_PKT03			0x050
> +
> +/* Audio SPDIF Infoframe */
> +#define TOP_SPDIF_HEADER		0x054
> +#define TOP_SPDIF_PKT00			0x058
> +#define TOP_SPDIF_PKT01			0x05c
> +#define TOP_SPDIF_PKT02			0x060
> +#define TOP_SPDIF_PKT03			0x064
> +#define TOP_SPDIF_PKT04			0x068
> +#define TOP_SPDIF_PKT05			0x06c
> +#define TOP_SPDIF_PKT06			0x070
> +#define TOP_SPDIF_PKT07			0x074
> +
> +/* Infoframes Configuration */
> +#define TOP_INFO_EN			0x01c
> +#define  AVI_EN				BIT(0)
> +#define  SPD_EN				BIT(1)
> +#define  AUD_EN				BIT(2)
> +#define  CP_EN				BIT(5)
> +#define  VSIF_EN			BIT(11)
> +#define  AVI_EN_WR			BIT(16)
> +#define  SPD_EN_WR			BIT(17)
> +#define  AUD_EN_WR			BIT(18)
> +#define  CP_EN_WR			BIT(21)
> +#define  VSIF_EN_WR			BIT(27)
> +#define TOP_INFO_RPT			0x020
> +#define  AVI_RPT_EN			BIT(0)
> +#define  SPD_RPT_EN			BIT(1)
> +#define  AUD_RPT_EN			BIT(2)
> +#define  CP_RPT_EN			BIT(5)
> +#define  VSIF_RPT_EN			BIT(11)
> +
> +/* Vendor Specific Infoframe */
> +#define TOP_VSIF_HEADER			0x174
> +#define TOP_VSIF_PKT00			0x178
> +#define TOP_VSIF_PKT01			0x17c
> +#define TOP_VSIF_PKT02			0x180
> +#define TOP_VSIF_PKT03			0x184
> +#define TOP_VSIF_PKT04			0x188
> +#define TOP_VSIF_PKT05			0x18c
> +#define TOP_VSIF_PKT06			0x190
> +#define TOP_VSIF_PKT07			0x194
> +
> +/* HDMI_TOP Misc */
> +#define TOP_MISC_CTLR			0x1a4
> +#define  DEEP_COLOR_ADD			BIT(4)
> +
> +/* Hardware interrupts */
> +#define TOP_INT_STA00			0x1a8
> +#define TOP_INT_ENABLE00		0x1b0
> +#define  HTPLG_R_INT			BIT(0)
> +#define  HTPLG_F_INT			BIT(1)
> +#define  PORD_R_INT			BIT(2)
> +#define  PORD_F_INT			BIT(3)
> +#define  HDMI_VSYNC_INT			BIT(4)
> +#define  HDMI_AUDIO_INT			BIT(5)
> +#define  HDCP2X_RX_REAUTH_REQ_DDCM_INT	BIT(25)
> +#define TOP_INT_ENABLE01		0x1b4
> +#define TOP_INT_CLR00			0x1b8
> +#define TOP_INT_CLR01			0x1bc
> +
> +
> +/* Video Mute */
> +#define TOP_VMUTE_CFG1			0x1c8
> +#define  REG_VMUTE_EN			BIT(16)
> +
> +/* HDMI Audio IP */
> +#define AIP_CTRL			0x400
> +#define  CTS_SW_SEL			BIT(0)
> +#define  CTS_REQ_EN			BIT(1)
> +#define  MCLK_EN			BIT(2)
> +#define  NO_MCLK_CTSGEN_SEL		BIT(3)
> +#define  AUD_IN_EN			BIT(8)
> +#define  AUD_SEL_OWRT			BIT(9)
> +#define  SPDIF_EN			BIT(13)
> +#define  HBRA_ON			BIT(14)
> +#define  DSD_EN				BIT(15)
> +#define  I2S_EN				GENMASK(19, 16)
> +#define  HBR_FROM_SPDIF			BIT(20)
> +#define  CTS_CAL_N4			BIT(23)
> +#define  SPDIF_INTERNAL_MODULE		BIT(24)
> +#define AIP_N_VAL			0x404
> +#define AIP_CTS_SVAL			0x408
> +#define AIP_SPDIF_CTRL			0x40c
> +#define  WR_1UI_LOCK			BIT(0)
> +#define  FS_OVERRIDE_WRITE		BIT(1)
> +#define  WR_2UI_LOCK			BIT(2)
> +#define  MAX_1UI_WRITE			GENMASK(15, 8)
> +#define  MAX_2UI_SPDIF_WRITE		GENMASK(23, 16)
> +#define  MAX_2UI_I2S_HI_WRITE		GENMASK(23, 20)
> +#define   MAX_2UI_I2S_LFE_CC_SWAP	BIT(1)
> +#define  MAX_2UI_I2S_LO_WRITE		GENMASK(19, 16)
> +#define  AUD_ERR_THRESH			GENMASK(29, 24)
> +#define  I2S2DSD_EN			BIT(30)
> +#define AIP_I2S_CTRL			0x410
> +#define  FIFO0_MAP			GENMASK(1, 0)
> +#define  FIFO1_MAP			GENMASK(3, 2)
> +#define  FIFO2_MAP			GENMASK(5, 4)
> +#define  FIFO3_MAP			GENMASK(7, 6)
> +#define  I2S_1ST_BIT_NOSHIFT		BIT(8)
> +#define  I2S_DATA_DIR_LSB		BIT(9)
> +#define  JUSTIFY_RIGHT			BIT(10)
> +#define  WS_HIGH			BIT(11)
> +#define  VBIT_COMPRESSED		BIT(12)
> +#define  CBIT_ORDER_SAME		BIT(13)
> +#define  SCK_EDGE_RISE			BIT(14)
> +#define AIP_I2S_CHST0			0x414
> +#define AIP_I2S_CHST1			0x418
> +#define AIP_TXCTRL			0x424
> +#define  RST4AUDIO			BIT(0)
> +#define  RST4AUDIO_FIFO			BIT(1)
> +#define  RST4AUDIO_ACR			BIT(2)
> +#define  AUD_LAYOUT_1			BIT(4)
> +#define  AUD_MUTE_FIFO_EN		BIT(5)
> +#define  AUD_PACKET_DROP		BIT(6)
> +#define  DSD_MUTE_EN			BIT(7)
> +#define AIP_TPI_CTRL			0x428
> +#define  TPI_AUDIO_LOOKUP_EN		BIT(2)
> +
> +/* Video downsampling configuration */
> +#define VID_DOWNSAMPLE_CONFIG		0x8d0
> +#define  C444_C422_CONFIG_ENABLE	BIT(0)
> +#define  C422_C420_CONFIG_ENABLE	BIT(4)
> +#define  C422_C420_CONFIG_BYPASS	BIT(5)
> +#define  C422_C420_CONFIG_OUT_CB_OR_CR	BIT(6)
> +#define VID_OUT_FORMAT			0x8fc
> +#define  OUTPUT_FORMAT_DEMUX_420_ENABLE	BIT(10)
> +
> +/* HDCP registers */
> +#define HDCP_TOP_CTRL			0xc00
> +#define HDCP2X_CTRL_0			0xc20
> +#define  HDCP2X_EN			BIT(0)
> +#define  HDCP2X_ENCRYPT_EN		BIT(7)
> +#define  HDCP2X_HPD_OVR			BIT(10)
> +#define  HDCP2X_HPD_SW			BIT(11)
> +#define HDCP2X_POL_CTRL			0xc54
> +#define  HDCP2X_DIS_POLL_EN		BIT(16)
> +#define HDCP1X_CTRL			0xcd0
> +#define  HDCP1X_ENC_EN			BIT(6)
> +
> +/* HDMI DDC registers */
> +#define HPD_DDC_CTRL			0xc08
> +#define  HPD_DDC_DELAY_CNT		GENMASK(31, 16)
> +#define  HPD_DDC_HPD_DBNC_EN		BIT(2)
> +#define  HPD_DDC_PORD_DBNC_EN		BIT(3)
> +#define DDC_CTRL			0xc10
> +#define  DDC_CTRL_ADDR			GENMASK(7, 1)
> +#define  DDC_CTRL_OFFSET		GENMASK(15, 8)
> +#define  DDC_CTRL_DIN_CNT		GENMASK(25, 16)
> +#define  DDC_CTRL_CMD			GENMASK(31, 28)
> +#define SCDC_CTRL			0xc18
> +#define  SCDC_DDC_SEGMENT		GENMASK(15, 8)
> +#define HPD_DDC_STATUS			0xc60
> +#define  HPD_STATE			GENMASK(1, 0)
> +#define   HPD_STATE_CONNECTED		2
> +#define  HPD_PIN_STA			BIT(4)
> +#define  PORD_PIN_STA			BIT(5)
> +#define  DDC_I2C_IN_PROG		BIT(13)
> +#define  DDC_DATA_OUT			GENMASK(23, 16)
> +#define SI2C_CTRL			0xcac
> +#define  SI2C_WR			BIT(0)
> +#define  SI2C_RD			BIT(1)
> +#define  SI2C_CONFIRM_READ		BIT(2)
> +#define  SI2C_WDATA			GENMASK(15, 8)
> +#define  SI2C_ADDR			GENMASK(23, 16)
> +
> +/* HDCP DDC registers */
> +#define HDCP2X_DDCM_STATUS		0xc68
> +#define  DDC_I2C_NO_ACK			BIT(10)
> +#define  DDC_I2C_BUS_LOW		BIT(11)
> +
> +/* HDMI TX registers */
> +#define HDMITX_CONFIG_MT8188		0xea0
> +#define HDMITX_CONFIG_MT8195		0x900
> +#define  HDMI_YUV420_MODE		BIT(10)
> +#define  HDMITX_SW_HPD			BIT(29)
> +#define  HDMITX_SW_RSTB			BIT(31)
> +
> +/**
> + * enum mtk_hdmi_ddc_v2_cmds - DDC_CMD register commands
> + * @DDC_CMD_READ_NOACK:      Current address read with no ACK on last byte
> + * @DDC_CMD_READ:            Current address read with ACK on last byte
> + * @DDC_CMD_SEQ_READ_NOACK:  Sequential read with no ACK on last byte
> + * @DDC_CMD_SEQ_READ:        Sequential read with ACK on last byte
> + * @DDC_CMD_ENH_READ_NOACK:  Enhanced read with no ACK on last byte
> + * @DDC_CMD_ENH_READ:        Enhanced read with ACK on last byte
> + * @DDC_CMD_SEQ_WRITE_NOACK: Sequential write ignoring ACK on last byte
> + * @DDC_CMD_SEQ_WRITE:       Sequential write requiring ACK on last byte
> + * @DDC_CMD_RSVD:            Reserved for future use
> + * @DDC_CMD_CLEAR_FIFO:      Clear DDC I2C FIFO
> + * @DDC_CMD_CLOCK_SCL:       Start clocking DDC I2C SCL
> + * @DDC_CMD_ABORT_XFER:      Abort DDC I2C transaction
> + */
> +enum mtk_hdmi_ddc_v2_cmds {
> +	DDC_CMD_READ_NOACK = 0x0,
> +	DDC_CMD_READ,
> +	DDC_CMD_SEQ_READ_NOACK,
> +	DDC_CMD_SEQ_READ,
> +	DDC_CMD_ENH_READ_NOACK,
> +	DDC_CMD_ENH_READ,
> +	DDC_CMD_SEQ_WRITE_NOACK,
> +	DDC_CMD_SEQ_WRITE = 0x07,
> +	DDC_CMD_CLEAR_FIFO = 0x09,
> +	DDC_CMD_CLOCK_SCL = 0x0a,
> +	DDC_CMD_ABORT_XFER = 0x0f
> +};
> +
> +#endif /* _MTK_HDMI_REGS_H */
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
> new file mode 100644
> index 000000000000..05cbfc45be54
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
> @@ -0,0 +1,1488 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek HDMI v2 IP driver
> + *
> + * Copyright (c) 2022 MediaTek Inc.
> + * Copyright (c) 2022 BayLibre, SAS
> + * Copyright (c) 2024 Collabora Ltd.
> + *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clk.h>
> +#include <linux/debugfs.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_graph.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/suspend.h>
> +#include <linux/timer.h>
> +#include <linux/units.h>
> +
> +#include <drm/display/drm_hdmi_helper.h>
> +#include <drm/display/drm_hdmi_state_helper.h>
> +#include <drm/display/drm_scdc_helper.h>
> +#include <drm/drm_edid.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_probe_helper.h>
> +
> +#include "mtk_hdmi_common.h"
> +#include "mtk_hdmi_regs_v2.h"
> +
> +#define MTK_HDMI_V2_CLOCK_MIN	27000
> +#define MTK_HDMI_V2_CLOCK_MAX	594000
> +
> +#define HPD_PORD_HWIRQS		(HTPLG_R_INT | HTPLG_F_INT | PORD_F_INT | PORD_R_INT)
> +
> +enum mtk_hdmi_v2_clk_id {
> +	MTK_HDMI_V2_CLK_HDCP_SEL,
> +	MTK_HDMI_V2_CLK_HDCP_24M_SEL,
> +	MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI,
> +	MTK_HDMI_V2_CLK_HDMI_APB_SEL,
> +	MTK_HDMI_V2_CLK_COUNT,
> +};
> +
> +const char *const mtk_hdmi_v2_clk_names[MTK_HDMI_V2_CLK_COUNT] = {
> +	[MTK_HDMI_V2_CLK_HDMI_APB_SEL] = "bus",
> +	[MTK_HDMI_V2_CLK_HDCP_SEL] = "hdcp",
> +	[MTK_HDMI_V2_CLK_HDCP_24M_SEL] = "hdcp24m",
> +	[MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI] = "hdmi-split",
> +};
> +
> +static inline void mtk_hdmi_v2_hwirq_disable(struct mtk_hdmi *hdmi)
> +{
> +	regmap_write(hdmi->regs, TOP_INT_ENABLE00, 0);
> +	regmap_write(hdmi->regs, TOP_INT_ENABLE01, 0);
> +}
> +
> +static inline void mtk_hdmi_v2_enable_hpd_pord_irq(struct mtk_hdmi *hdmi, bool enable)
> +{
> +	if (enable)
> +		regmap_set_bits(hdmi->regs, TOP_INT_ENABLE00, HPD_PORD_HWIRQS);
> +	else
> +		regmap_clear_bits(hdmi->regs, TOP_INT_ENABLE00, HPD_PORD_HWIRQS);
> +}
> +
> +static inline void mtk_hdmi_v2_clear_hpd_pord_irq(struct mtk_hdmi *hdmi)
> +{
> +	regmap_set_bits(hdmi->regs, TOP_INT_CLR00, HPD_PORD_HWIRQS);
> +	regmap_clear_bits(hdmi->regs, TOP_INT_CLR00, HPD_PORD_HWIRQS);
> +}
> +
> +static inline void mtk_hdmi_v2_set_sw_hpd(struct mtk_hdmi *hdmi, bool enable)
> +{
> +	if (enable) {
> +		regmap_set_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_HPD);
> +		regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_OVR);
> +		regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_SW);
> +	} else {
> +		regmap_clear_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_OVR);
> +		regmap_clear_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_SW);
> +		regmap_clear_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_HPD);
> +	}
> +}
> +
> +static void mtk_hdmi_v2_disable_hdcp_encrypt(struct mtk_hdmi *hdmi)
> +{
> +	regmap_clear_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_ENCRYPT_EN);
> +	regmap_clear_bits(hdmi->regs, HDCP1X_CTRL, HDCP1X_ENC_EN);
> +}
> +
> +static inline void mtk_hdmi_v2_enable_scrambling(struct mtk_hdmi *hdmi, bool enable)
> +{
> +	struct drm_scdc *scdc = &hdmi->curr_conn->display_info.hdmi.scdc;
> +
> +	if (enable)
> +		regmap_set_bits(hdmi->regs, TOP_CFG00, SCR_ON | HDMI2_ON);
> +	else
> +		regmap_clear_bits(hdmi->regs, TOP_CFG00, SCR_ON | HDMI2_ON);
> +
> +	if (scdc->supported) {
> +		if (scdc->scrambling.supported)
> +			drm_scdc_set_scrambling(hdmi->curr_conn, enable);
> +		drm_scdc_set_high_tmds_clock_ratio(hdmi->curr_conn, enable);
> +	}
> +}
> +
> +static void mtk_hdmi_v2_hw_vid_mute(struct mtk_hdmi *hdmi, bool enable)
> +{
> +	/* If enabled, sends a black image */
> +	if (enable)
> +		regmap_set_bits(hdmi->regs, TOP_VMUTE_CFG1, REG_VMUTE_EN);
> +	else
> +		regmap_clear_bits(hdmi->regs, TOP_VMUTE_CFG1, REG_VMUTE_EN);
> +}
> +
> +static void mtk_hdmi_v2_hw_aud_mute(struct mtk_hdmi *hdmi, bool enable)
> +{
> +	u32 aip, val;
> +
> +	if (!enable) {
> +		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, AUD_MUTE_FIFO_EN);
> +		return;
> +	}
> +
> +	regmap_read(hdmi->regs, AIP_CTRL, &aip);
> +
> +	val = AUD_MUTE_FIFO_EN;
> +	if (aip & DSD_EN)
> +		val |= DSD_MUTE_EN;
> +
> +	regmap_update_bits(hdmi->regs, AIP_TXCTRL, val, val);
> +}
> +
> +static void mtk_hdmi_v2_hw_reset(struct mtk_hdmi *hdmi)
> +{
> +	regmap_clear_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_RSTB);
> +	udelay(5);
> +	regmap_set_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_RSTB);
> +}
> +
> +static inline u32 mtk_hdmi_v2_format_hw_packet(const u8 *buffer, u8 len)
> +{
> +	unsigned short i;
> +	u32 val = 0;
> +
> +	for (i = 0; i < len; i++)
> +		val |= buffer[i] << (i * 8);
> +
> +	return val;
> +}
> +
> +static void mtk_hdmi_v2_hw_write_audio_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
> +{
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
> +
> +	regmap_write(hdmi->regs, TOP_AIF_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
> +	regmap_write(hdmi->regs, TOP_AIF_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 3));
> +	regmap_write(hdmi->regs, TOP_AIF_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 2));
> +	regmap_write(hdmi->regs, TOP_AIF_PKT02, 0);
> +	regmap_write(hdmi->regs, TOP_AIF_PKT03, 0);
> +
> +	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
> +	regmap_set_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
> +}
> +
> +static void mtk_hdmi_v2_hw_write_avi_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
> +{
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
> +
> +	regmap_write(hdmi->regs, TOP_AVI_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
> +	regmap_write(hdmi->regs, TOP_AVI_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 4));
> +	regmap_write(hdmi->regs, TOP_AVI_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 3));
> +	regmap_write(hdmi->regs, TOP_AVI_PKT02, mtk_hdmi_v2_format_hw_packet(&buffer[10], 4));
> +	regmap_write(hdmi->regs, TOP_AVI_PKT03, mtk_hdmi_v2_format_hw_packet(&buffer[14], 3));
> +	regmap_write(hdmi->regs, TOP_AVI_PKT04, 0);
> +	regmap_write(hdmi->regs, TOP_AVI_PKT05, 0);
> +
> +	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
> +	regmap_set_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
> +}
> +
> +static void mtk_hdmi_v2_hw_write_spd_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
> +{
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
> +
> +	regmap_write(hdmi->regs, TOP_SPDIF_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
> +	regmap_write(hdmi->regs, TOP_SPDIF_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 4));
> +	regmap_write(hdmi->regs, TOP_SPDIF_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 3));
> +	regmap_write(hdmi->regs, TOP_SPDIF_PKT02, mtk_hdmi_v2_format_hw_packet(&buffer[10], 4));
> +	regmap_write(hdmi->regs, TOP_SPDIF_PKT03, mtk_hdmi_v2_format_hw_packet(&buffer[14], 3));
> +	regmap_write(hdmi->regs, TOP_SPDIF_PKT04, mtk_hdmi_v2_format_hw_packet(&buffer[17], 4));
> +	regmap_write(hdmi->regs, TOP_SPDIF_PKT05, mtk_hdmi_v2_format_hw_packet(&buffer[21], 3));
> +	regmap_write(hdmi->regs, TOP_SPDIF_PKT06, mtk_hdmi_v2_format_hw_packet(&buffer[24], 4));
> +	regmap_write(hdmi->regs, TOP_SPDIF_PKT07, buffer[28]);
> +
> +	regmap_set_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
> +	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
> +}
> +
> +static void mtk_hdmi_v2_hw_write_vendor_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
> +{
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
> +
> +	regmap_write(hdmi->regs, TOP_VSIF_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
> +	regmap_write(hdmi->regs, TOP_VSIF_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 4));
> +	regmap_write(hdmi->regs, TOP_VSIF_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 2));
> +	regmap_write(hdmi->regs, TOP_VSIF_PKT02, 0);
> +	regmap_write(hdmi->regs, TOP_VSIF_PKT03, 0);
> +	regmap_write(hdmi->regs, TOP_VSIF_PKT04, 0);
> +	regmap_write(hdmi->regs, TOP_VSIF_PKT05, 0);
> +	regmap_write(hdmi->regs, TOP_VSIF_PKT06, 0);
> +	regmap_write(hdmi->regs, TOP_VSIF_PKT07, 0);
> +
> +	regmap_set_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
> +	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
> +}
> +
> +static void mtk_hdmi_yuv420_downsampling(struct mtk_hdmi *hdmi, bool enable)
> +{
> +	u32 val;
> +
> +	regmap_read(hdmi->regs, VID_DOWNSAMPLE_CONFIG, &val);
> +
> +	if (enable) {
> +		regmap_set_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg,
> +				HDMI_YUV420_MODE | HDMITX_SW_HPD);
> +
> +		val |= C444_C422_CONFIG_ENABLE | C422_C420_CONFIG_ENABLE;
> +		val |= C422_C420_CONFIG_OUT_CB_OR_CR;
> +		val &= ~C422_C420_CONFIG_BYPASS;
> +		regmap_write(hdmi->regs, VID_DOWNSAMPLE_CONFIG, val);
> +
> +		regmap_set_bits(hdmi->regs, VID_OUT_FORMAT, OUTPUT_FORMAT_DEMUX_420_ENABLE);
> +	} else {
> +		regmap_update_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg,
> +				   HDMI_YUV420_MODE | HDMITX_SW_HPD, HDMITX_SW_HPD);
> +
> +		val &= ~(C444_C422_CONFIG_ENABLE | C422_C420_CONFIG_ENABLE);
> +		val &= ~C422_C420_CONFIG_OUT_CB_OR_CR;
> +		val |= C422_C420_CONFIG_BYPASS;
> +		regmap_write(hdmi->regs, VID_DOWNSAMPLE_CONFIG, val);
> +
> +		regmap_clear_bits(hdmi->regs, VID_OUT_FORMAT, OUTPUT_FORMAT_DEMUX_420_ENABLE);
> +	}
> +}
> +
> +static int mtk_hdmi_v2_setup_audio_infoframe(struct mtk_hdmi *hdmi)
> +{
> +	struct hdmi_codec_params *params = &hdmi->aud_param.codec_params;
> +	struct hdmi_audio_infoframe frame;
> +	u8 buffer[14];
> +	ssize_t ret;
> +
> +	memcpy(&frame, &params->cea, sizeof(frame));
> +
> +	ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
> +	if (ret < 0)
> +		return ret;
> +
> +	mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);

This should be handled via HDMI Connector framework too. There is
already an interface to set / clear audio infoframes.
als I have been working on an interface to make HDMI codec
implementation more generic, see [1]. Your comments are appreciated.

[1] https://patchwork.freedesktop.org/series/134927/

> +
> +	return 0;
> +}
> +
> +static inline void mtk_hdmi_v2_hw_reset_av_mute_regs(struct mtk_hdmi *hdmi)
> +{
> +	/* GCP packet */
> +	regmap_clear_bits(hdmi->regs, TOP_CFG01, CP_CLR_MUTE_EN | CP_SET_MUTE_EN);
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, CP_RPT_EN);
> +	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, CP_EN | CP_EN_WR);
> +}
> +
> +static inline void mtk_hdmi_v2_hw_av_mute(struct mtk_hdmi *hdmi, bool mute)
> +{
> +	mtk_hdmi_v2_hw_reset_av_mute_regs(hdmi);
> +
> +	if (mute)
> +		regmap_set_bits(hdmi->regs, TOP_CFG01, CP_SET_MUTE_EN);
> +	else
> +		regmap_set_bits(hdmi->regs, TOP_CFG01, CP_CLR_MUTE_EN);
> +
> +	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, CP_RPT_EN);
> +	regmap_set_bits(hdmi->regs, TOP_INFO_EN, CP_EN | CP_EN_WR);
> +}
> +
> +static void mtk_hdmi_v2_hw_ncts_enable(struct mtk_hdmi *hdmi, bool enable)
> +{
> +	if (enable)
> +		regmap_set_bits(hdmi->regs, AIP_CTRL, CTS_SW_SEL);
> +	else
> +		regmap_clear_bits(hdmi->regs, AIP_CTRL, CTS_SW_SEL);
> +}
> +
> +static void mtk_hdmi_v2_hw_aud_set_channel_status(struct mtk_hdmi *hdmi, u8 *ch_status)
> +{
> +	/* Only the first 5 to 7 bytes of Channel Status contain useful information */
> +	regmap_write(hdmi->regs, AIP_I2S_CHST0, mtk_hdmi_v2_format_hw_packet(&ch_status[0], 4));
> +	regmap_write(hdmi->regs, AIP_I2S_CHST1, mtk_hdmi_v2_format_hw_packet(&ch_status[4], 3));
> +}
> +
> +static void mtk_hdmi_v2_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
> +				     unsigned int sample_rate,
> +				     unsigned int clock)
> +{
> +	unsigned int n, cts;
> +	int ret;
> +
> +	ret = mtk_hdmi_get_ncts(sample_rate, clock, &n, &cts);
> +	if (ret) {
> +		dev_err(hdmi->dev, "Invalid sample rate: %u\n", sample_rate);
> +		return;
> +	}
> +
> +	regmap_write(hdmi->regs, AIP_N_VAL, n);
> +	regmap_write(hdmi->regs, AIP_CTS_SVAL, cts);
> +}
> +
> +static void mtk_hdmi_v2_hw_aud_enable(struct mtk_hdmi *hdmi, bool enable)
> +{
> +	if (enable)
> +		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, AUD_PACKET_DROP);
> +	else
> +		regmap_set_bits(hdmi->regs, AIP_TXCTRL, AUD_PACKET_DROP);
> +}
> +
> +static u32 mtk_hdmi_v2_aud_output_channel_map(u8 sd0, u8 sd1, u8 sd2, u8 sd3,
> +					   u8 sd4, u8 sd5, u8 sd6, u8 sd7)
> +{
> +	u32 val;
> +
> +	/*
> +	 * Each of the Output Channels (0-7) can be mapped to get their input
> +	 * from any of the available Input Channels (0-7): this function
> +	 * takes input channel numbers and formats a value that must then
> +	 * be written to the TOP_AUD_MAP hardware register by the caller.
> +	 */
> +	val = FIELD_PREP(SD0_MAP, sd0) | FIELD_PREP(SD1_MAP, sd1);
> +	val |= FIELD_PREP(SD2_MAP, sd2) | FIELD_PREP(SD3_MAP, sd3);
> +	val |= FIELD_PREP(SD4_MAP, sd4) | FIELD_PREP(SD5_MAP, sd5);
> +	val |= FIELD_PREP(SD6_MAP, sd6) | FIELD_PREP(SD7_MAP, sd7);
> +
> +	return val;
> +}
> +
> +static void mtk_hdmi_audio_dsd_config(struct mtk_hdmi *hdmi,
> +				      unsigned char chnum, bool dsd_bypass)
> +{
> +	u32 channel_map;
> +
> +	regmap_update_bits(hdmi->regs, AIP_CTRL, SPDIF_EN | DSD_EN | HBRA_ON, DSD_EN);
> +	regmap_set_bits(hdmi->regs, AIP_TXCTRL, DSD_MUTE_EN);
> +
> +	if (dsd_bypass)
> +		channel_map = mtk_hdmi_v2_aud_output_channel_map(0, 2, 4, 6, 1, 3, 5, 7);
> +	else
> +		channel_map = mtk_hdmi_v2_aud_output_channel_map(0, 5, 1, 0, 3, 2, 4, 0);
> +
> +	regmap_write(hdmi->regs, TOP_AUD_MAP, channel_map);
> +	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, I2S2DSD_EN);
> +}
> +
> +static inline void mtk_hdmi_v2_hw_i2s_fifo_map(struct mtk_hdmi *hdmi, u32 fifo_mapping)
> +{
> +	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL,
> +			   FIFO0_MAP | FIFO1_MAP | FIFO2_MAP | FIFO3_MAP, fifo_mapping);
> +}
> +
> +static inline void mtk_hdmi_v2_hw_i2s_ch_number(struct mtk_hdmi *hdmi, u8 chnum)
> +{
> +	regmap_update_bits(hdmi->regs, AIP_CTRL, I2S_EN, FIELD_PREP(I2S_EN, chnum));
> +}
> +
> +static void mtk_hdmi_v2_hw_i2s_ch_mapping(struct mtk_hdmi *hdmi, u8 chnum, u8 mapping)
> +{
> +	u32 fifo_map;
> +	u8 bdata;
> +
> +	switch (chnum) {
> +	default:
> +	case 2:
> +		bdata = 0x1;
> +		break;
> +	case 3:
> +		bdata = 0x3;
> +		break;
> +	case 6:
> +		if (mapping == 0x0e) {
> +			bdata = 0xf;
> +			break;
> +		}
> +		fallthrough;
> +	case 5:
> +		bdata = 0x7;
> +		break;
> +	case 7:
> +	case 8:
> +		bdata = 0xf;
> +		break;
> +	}
> +
> +	/* Assign default FIFO mapping: SD0 to FIFO0, SD1 to FIFO1, etc. */
> +	fifo_map = FIELD_PREP(FIFO0_MAP, 0) | FIELD_PREP(FIFO1_MAP, 1);
> +	fifo_map |= FIELD_PREP(FIFO2_MAP, 2) | FIELD_PREP(FIFO3_MAP, 3);
> +	mtk_hdmi_v2_hw_i2s_fifo_map(hdmi, fifo_map);
> +	mtk_hdmi_v2_hw_i2s_ch_number(hdmi, bdata);
> +
> +	/*
> +	 * Set HDMI Audio packet layout indicator:
> +	 * Layout 0 is for two channels
> +	 * Layout 1 is for up to eight channels
> +	 */
> +	if (chnum == 2)
> +		regmap_set_bits(hdmi->regs, AIP_TXCTRL, AUD_LAYOUT_1);
> +	else
> +		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, AUD_LAYOUT_1);
> +}
> +
> +static void mtk_hdmi_i2s_data_fmt(struct mtk_hdmi *hdmi, unsigned char fmt)
> +{
> +	u32 val;
> +
> +	regmap_read(hdmi->regs, AIP_I2S_CTRL, &val);
> +	val &= ~(WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT);
> +
> +	switch (fmt) {
> +	case HDMI_I2S_MODE_RJT_24BIT:
> +	case HDMI_I2S_MODE_RJT_16BIT:
> +		val |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT);
> +		break;
> +	case HDMI_I2S_MODE_LJT_24BIT:
> +	case HDMI_I2S_MODE_LJT_16BIT:
> +		val |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT);
> +		break;
> +	case HDMI_I2S_MODE_I2S_24BIT:
> +	case HDMI_I2S_MODE_I2S_16BIT:
> +	default:
> +		break;
> +	}
> +
> +	regmap_write(hdmi->regs, AIP_I2S_CTRL, val);
> +}
> +
> +static inline void mtk_hdmi_i2s_sck_edge_rise(struct mtk_hdmi *hdmi, bool rise)
> +{
> +	if (rise)
> +		regmap_set_bits(hdmi->regs, AIP_I2S_CTRL, SCK_EDGE_RISE);
> +	else
> +		regmap_clear_bits(hdmi->regs, AIP_I2S_CTRL, SCK_EDGE_RISE);
> +}
> +
> +static inline void mtk_hdmi_i2s_cbit_order(struct mtk_hdmi *hdmi, unsigned int cbit)
> +{
> +	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL, CBIT_ORDER_SAME, cbit);
> +}
> +
> +static inline void mtk_hdmi_i2s_vbit(struct mtk_hdmi *hdmi, unsigned int vbit)
> +{
> +	/* V bit: 0 for PCM, 1 for Compressed data */
> +	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL, VBIT_COMPRESSED, vbit);
> +}
> +
> +static inline void mtk_hdmi_i2s_data_direction(struct mtk_hdmi *hdmi, unsigned int is_lsb)
> +{
> +	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL, I2S_DATA_DIR_LSB, is_lsb);
> +}
> +
> +static inline void mtk_hdmi_v2_hw_audio_type(struct mtk_hdmi *hdmi, unsigned int spdif_i2s)
> +{
> +	regmap_update_bits(hdmi->regs, AIP_CTRL, SPDIF_EN, FIELD_PREP(SPDIF_EN, spdif_i2s));
> +}
> +
> +static u8 mtk_hdmi_v2_get_i2s_ch_mapping(struct mtk_hdmi *hdmi, u8 channel_type)
> +{
> +	switch (channel_type) {
> +	case HDMI_AUD_CHAN_TYPE_1_1:
> +	case HDMI_AUD_CHAN_TYPE_2_1:
> +		return 0x01;
> +	case HDMI_AUD_CHAN_TYPE_3_0:
> +		return 0x02;
> +	case HDMI_AUD_CHAN_TYPE_3_1:
> +		return 0x03;
> +	case HDMI_AUD_CHAN_TYPE_3_0_LRS:
> +	case HDMI_AUD_CHAN_TYPE_4_0:
> +		return 0x08;
> +	case HDMI_AUD_CHAN_TYPE_5_1:
> +		return 0x0b;
> +	case HDMI_AUD_CHAN_TYPE_4_1_CLRS:
> +	case HDMI_AUD_CHAN_TYPE_6_0:
> +	case HDMI_AUD_CHAN_TYPE_6_0_CS:
> +	case HDMI_AUD_CHAN_TYPE_6_0_CH:
> +	case HDMI_AUD_CHAN_TYPE_6_0_OH:
> +	case HDMI_AUD_CHAN_TYPE_6_0_CHR:
> +		return 0x0e;
> +	case HDMI_AUD_CHAN_TYPE_1_0:
> +	case HDMI_AUD_CHAN_TYPE_2_0:
> +	case HDMI_AUD_CHAN_TYPE_3_1_LRS:
> +	case HDMI_AUD_CHAN_TYPE_4_1:
> +	case HDMI_AUD_CHAN_TYPE_5_0:
> +	case HDMI_AUD_CHAN_TYPE_4_0_CLRS:
> +	case HDMI_AUD_CHAN_TYPE_6_1:
> +	case HDMI_AUD_CHAN_TYPE_6_1_CS:
> +	case HDMI_AUD_CHAN_TYPE_6_1_CH:
> +	case HDMI_AUD_CHAN_TYPE_6_1_OH:
> +	case HDMI_AUD_CHAN_TYPE_6_1_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_0:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LH_RH:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LC_RC:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LW_RW:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CS_CH:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CS_OH:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CS_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CH_OH:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CH_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_0_OH_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR:
> +	case HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS:
> +	case HDMI_AUD_CHAN_TYPE_7_1:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LH_RH:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LC_RC:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LW_RW:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CS_CH:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CS_OH:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CS_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CH_OH:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CH_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_1_OH_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR:
> +	default:
> +		return 0;
> +	}
> +
> +	return 0;
> +}
> +
> +static inline void mtk_hdmi_v2_hw_i2s_ch_swap(struct mtk_hdmi *hdmi, unsigned char swapbit)
> +{
> +	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_2UI_I2S_HI_WRITE,
> +			   FIELD_PREP(MAX_2UI_I2S_HI_WRITE, swapbit));
> +}
> +
> +static void mtk_hdmi_hbr_config(struct mtk_hdmi *hdmi, bool dsd_bypass)
> +{
> +	const u32 hbr_mask = SPDIF_EN | DSD_EN | HBRA_ON;
> +
> +	if (dsd_bypass) {
> +		regmap_update_bits(hdmi->regs, AIP_CTRL, hbr_mask, HBRA_ON);
> +		regmap_set_bits(hdmi->regs, AIP_CTRL, I2S_EN);
> +	} else {
> +		regmap_update_bits(hdmi->regs, AIP_CTRL, hbr_mask, SPDIF_EN);
> +		regmap_set_bits(hdmi->regs, AIP_CTRL, SPDIF_INTERNAL_MODULE);
> +		regmap_set_bits(hdmi->regs, AIP_CTRL, HBR_FROM_SPDIF);
> +		regmap_set_bits(hdmi->regs, AIP_CTRL, CTS_CAL_N4);
> +	}
> +}
> +
> +static inline void mtk_hdmi_v2_hw_spdif_config(struct mtk_hdmi *hdmi)
> +{
> +	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, WR_1UI_LOCK);
> +	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, FS_OVERRIDE_WRITE);
> +	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, WR_2UI_LOCK);
> +
> +	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_1UI_WRITE,
> +			   FIELD_PREP(MAX_1UI_WRITE, 4));
> +	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_2UI_SPDIF_WRITE,
> +			   FIELD_PREP(MAX_2UI_SPDIF_WRITE, 9));
> +	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, AUD_ERR_THRESH,
> +			   FIELD_PREP(AUD_ERR_THRESH, 4));
> +
> +	regmap_set_bits(hdmi->regs, AIP_SPDIF_CTRL, I2S2DSD_EN);
> +}
> +
> +static void mtk_hdmi_v2_aud_set_input(struct mtk_hdmi *hdmi)
> +{
> +	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> +	u8 i2s_ch_map;
> +	u32 out_ch_map;
> +
> +	/* Write the default output channel map. CH0 maps to SD0, CH1 maps to SD1, etc */
> +	out_ch_map = mtk_hdmi_v2_aud_output_channel_map(0, 1, 2, 3, 4, 5, 6, 7);
> +	regmap_write(hdmi->regs, TOP_AUD_MAP, out_ch_map);
> +
> +	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_2UI_I2S_HI_WRITE, 0);
> +	regmap_clear_bits(hdmi->regs, AIP_CTRL,
> +			  SPDIF_EN | DSD_EN | HBRA_ON | CTS_CAL_N4 |
> +			  HBR_FROM_SPDIF | SPDIF_INTERNAL_MODULE);
> +	regmap_clear_bits(hdmi->regs, AIP_TXCTRL, DSD_MUTE_EN | AUD_LAYOUT_1);
> +
> +	if (aud_param->aud_input_type == HDMI_AUD_INPUT_I2S) {
> +		switch (aud_param->aud_codec) {
> +		case HDMI_AUDIO_CODING_TYPE_DTS_HD:
> +		case HDMI_AUDIO_CODING_TYPE_MLP:
> +			mtk_hdmi_i2s_data_fmt(hdmi, aud_param->aud_i2s_fmt);
> +			mtk_hdmi_hbr_config(hdmi, true);
> +			break;
> +		case HDMI_AUDIO_CODING_TYPE_DSD:
> +			mtk_hdmi_audio_dsd_config(hdmi, aud_param->codec_params.channels, 0);
> +			mtk_hdmi_v2_hw_i2s_ch_mapping(hdmi, aud_param->codec_params.channels, 1);
> +			break;
> +		default:
> +			mtk_hdmi_i2s_data_fmt(hdmi, aud_param->aud_i2s_fmt);
> +			mtk_hdmi_i2s_sck_edge_rise(hdmi, true);
> +			mtk_hdmi_i2s_cbit_order(hdmi, CBIT_ORDER_SAME);
> +			mtk_hdmi_i2s_vbit(hdmi, 0); /* PCM data */
> +			mtk_hdmi_i2s_data_direction(hdmi, 0); /* MSB first */
> +			mtk_hdmi_v2_hw_audio_type(hdmi, HDMI_AUD_INPUT_I2S);
> +			i2s_ch_map = mtk_hdmi_v2_get_i2s_ch_mapping(hdmi,
> +						aud_param->aud_input_chan_type);
> +			mtk_hdmi_v2_hw_i2s_ch_mapping(hdmi,
> +						aud_param->codec_params.channels, i2s_ch_map);
> +			mtk_hdmi_v2_hw_i2s_ch_swap(hdmi, MAX_2UI_I2S_LFE_CC_SWAP);
> +		}
> +	} else {
> +		if (aud_param->codec_params.sample_rate == 768000 &&
> +		    (aud_param->aud_codec == HDMI_AUDIO_CODING_TYPE_DTS_HD ||
> +		     aud_param->aud_codec == HDMI_AUDIO_CODING_TYPE_MLP)) {
> +			mtk_hdmi_hbr_config(hdmi, false);
> +		} else {
> +			mtk_hdmi_v2_hw_spdif_config(hdmi);
> +			mtk_hdmi_v2_hw_i2s_ch_mapping(hdmi, 2, 0);
> +		}
> +	}
> +}
> +
> +static void mtk_hdmi_v2_aud_set_sw_ncts(struct mtk_hdmi *hdmi,
> +				     struct drm_display_mode *display_mode)
> +{
> +	mtk_hdmi_v2_hw_ncts_enable(hdmi, false);
> +	mtk_hdmi_v2_hw_aud_set_ncts(hdmi, hdmi->aud_param.codec_params.sample_rate,
> +				 display_mode->clock);
> +}
> +
> +static inline void mtk_hdmi_v2_hw_audio_input_enable(struct mtk_hdmi *hdmi,
> +						  unsigned int enable)
> +{
> +	if (enable)
> +		regmap_set_bits(hdmi->regs, AIP_CTRL, AUD_IN_EN);
> +	else
> +		regmap_clear_bits(hdmi->regs, AIP_CTRL, AUD_IN_EN);
> +}
> +
> +static void mtk_hdmi_v2_aip_ctrl_init(struct mtk_hdmi *hdmi)
> +{
> +	regmap_set_bits(hdmi->regs, AIP_CTRL,
> +			AUD_SEL_OWRT | NO_MCLK_CTSGEN_SEL | MCLK_EN | CTS_REQ_EN);
> +	regmap_clear_bits(hdmi->regs, AIP_TPI_CTRL, TPI_AUDIO_LOOKUP_EN);
> +}
> +
> +static void mtk_hdmi_v2_audio_reset(struct mtk_hdmi *hdmi, bool reset)
> +{
> +	const u32 arst_bits = RST4AUDIO | RST4AUDIO_FIFO | RST4AUDIO_ACR;
> +
> +	if (reset)
> +		regmap_set_bits(hdmi->regs, AIP_TXCTRL, arst_bits);
> +	else
> +		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, arst_bits);
> +}
> +
> +static void mtk_hdmi_v2_aud_output_config(struct mtk_hdmi *hdmi,
> +				       struct drm_display_mode *display_mode)
> +{
> +	mtk_hdmi_v2_hw_aud_mute(hdmi, true);
> +	mtk_hdmi_v2_hw_aud_enable(hdmi, false);
> +	mtk_hdmi_v2_audio_reset(hdmi, true);
> +	mtk_hdmi_v2_aip_ctrl_init(hdmi);
> +	mtk_hdmi_v2_aud_set_input(hdmi);
> +	mtk_hdmi_v2_hw_aud_set_channel_status(hdmi, hdmi->aud_param.codec_params.iec.status);
> +	mtk_hdmi_v2_setup_audio_infoframe(hdmi);
> +	mtk_hdmi_v2_hw_audio_input_enable(hdmi, true);
> +	mtk_hdmi_v2_audio_reset(hdmi, false);
> +	mtk_hdmi_v2_aud_set_sw_ncts(hdmi, display_mode);
> +
> +	/* Wait for the HW to apply settings */
> +	usleep_range(25, 50);
> +
> +	mtk_hdmi_v2_hw_ncts_enable(hdmi, true);
> +	mtk_hdmi_v2_hw_aud_enable(hdmi, true);
> +	mtk_hdmi_v2_hw_aud_mute(hdmi, false);
> +}
> +
> +static void mtk_hdmi_v2_change_video_resolution(struct mtk_hdmi *hdmi)
> +{
> +	mtk_hdmi_v2_hw_reset(hdmi);
> +	mtk_hdmi_v2_set_sw_hpd(hdmi, true);
> +	udelay(2);
> +
> +	regmap_write(hdmi->regs, HDCP_TOP_CTRL, 0);
> +
> +	/* Enable HDCP reauthentication interrupt */
> +	regmap_set_bits(hdmi->regs, TOP_INT_ENABLE00, HDCP2X_RX_REAUTH_REQ_DDCM_INT);
> +
> +	/* Enable hotplug and pord interrupts */
> +	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
> +
> +	/* Force enabling HDCP HPD */
> +	regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_OVR);
> +	regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_SW);
> +
> +	/* Set 8 bits per pixel */
> +	regmap_update_bits(hdmi->regs, TOP_CFG00, TMDS_PACK_MODE,
> +			   FIELD_PREP(TMDS_PACK_MODE, TMDS_PACK_MODE_8BPP));
> +	/* Disable generating deepcolor packets */
> +	regmap_clear_bits(hdmi->regs, TOP_CFG00, DEEPCOLOR_PKT_EN);
> +	/* Disable adding deepcolor information to the general packet */
> +	regmap_clear_bits(hdmi->regs, TOP_MISC_CTLR, DEEP_COLOR_ADD);
> +
> +	if (hdmi->dvi_mode)
> +		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_MODE_HDMI);
> +	else
> +		regmap_set_bits(hdmi->regs, TOP_CFG00, HDMI_MODE_HDMI);
> +
> +	udelay(5);
> +	mtk_hdmi_v2_hw_vid_mute(hdmi, true);
> +	mtk_hdmi_v2_hw_aud_mute(hdmi, true);
> +	mtk_hdmi_v2_hw_av_mute(hdmi, false);
> +
> +	regmap_update_bits(hdmi->regs, TOP_CFG01,
> +			   NULL_PKT_VSYNC_HIGH_EN | NULL_PKT_EN, NULL_PKT_VSYNC_HIGH_EN);
> +	usleep_range(100, 150);
> +
> +	/* Enable scrambling if tmds clock is 340MHz or more */
> +	mtk_hdmi_v2_enable_scrambling(hdmi, hdmi->mode.clock >= 340 * KILO);
> +
> +	/* Disable YUV420 downsampling */
> +	mtk_hdmi_yuv420_downsampling(hdmi, false);
> +}
> +
> +static void mtk_hdmi_v2_output_set_display_mode(struct mtk_hdmi *hdmi,
> +						struct drm_display_mode *mode)
> +{
> +	union phy_configure_opts opts = {
> +		.dp = { .link_rate = hdmi->mode.clock * KILO }
> +	};
> +	int ret;
> +
> +	ret = phy_configure(hdmi->phy, &opts);
> +	if (ret)
> +		dev_err(hdmi->dev, "Setting clock=%d failed: %d", mode->clock, ret);
> +
> +	mtk_hdmi_v2_change_video_resolution(hdmi);
> +	mtk_hdmi_v2_aud_output_config(hdmi, mode);
> +}
> +
> +static int mtk_hdmi_v2_clk_enable(struct mtk_hdmi *hdmi)
> +{
> +	int ret;
> +
> +	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_24M_SEL]);
> +	if (ret)
> +		goto disable_hdcp_clk;
> +
> +	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_HDMI_APB_SEL]);
> +	if (ret)
> +		goto disable_hdcp_24m_clk;
> +
> +	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI]);
> +	if (ret)
> +		goto disable_bus_clk;
> +
> +	return 0;
> +
> +disable_bus_clk:
> +	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDMI_APB_SEL]);
> +disable_hdcp_24m_clk:
> +	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_24M_SEL]);
> +disable_hdcp_clk:
> +	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
> +
> +	return ret;
> +}
> +
> +static void mtk_hdmi_v2_clk_disable(struct mtk_hdmi *hdmi)
> +{
> +	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI]);
> +	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDMI_APB_SEL]);
> +	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_24M_SEL]);
> +	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
> +}
> +
> +static void mtk_hdmi_hpd_event(enum hdmi_hpd_state hpd, struct device *dev)
> +{
> +	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +
> +	if (hdmi && hdmi->bridge.encoder && hdmi->bridge.encoder->dev)
> +		drm_helper_hpd_irq_event(hdmi->bridge.encoder->dev);
> +}
> +
> +static enum hdmi_hpd_state mtk_hdmi_v2_hpd_pord_status(struct mtk_hdmi *hdmi)
> +{
> +	u8 hpd_pin_sta, pord_pin_sta;
> +	u32 hpd_status;
> +
> +	regmap_read(hdmi->regs, HPD_DDC_STATUS, &hpd_status);
> +	hpd_pin_sta = FIELD_GET(HPD_PIN_STA, hpd_status);
> +	pord_pin_sta = FIELD_GET(PORD_PIN_STA, hpd_status);
> +
> +	if (hpd_pin_sta && pord_pin_sta)
> +		return HDMI_PLUG_IN_AND_SINK_POWER_ON;
> +	else if (hpd_pin_sta)
> +		return HDMI_PLUG_IN_ONLY;
> +	else
> +		return HDMI_PLUG_OUT;
> +}
> +
> +static irqreturn_t mtk_hdmi_v2_isr(int irq, void *arg)
> +{
> +	struct mtk_hdmi *hdmi = arg;
> +	unsigned int irq_sta;
> +	int ret = IRQ_HANDLED;
> +
> +	regmap_read(hdmi->regs, TOP_INT_STA00, &irq_sta);
> +
> +	/* Handle Hotplug Detection interrupt */
> +	if (irq_sta & (HTPLG_R_INT | HTPLG_F_INT | PORD_F_INT | PORD_R_INT)) {
> +		mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, false);
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	/*
> +	 * Clear all 32 + 19 interrupts in CLR00 and CLR01: this is important
> +	 * to avoid unwanted retriggering of any interrupts
> +	 */
> +	regmap_write(hdmi->regs, TOP_INT_CLR00, GENMASK(31, 0));
> +	regmap_write(hdmi->regs, TOP_INT_CLR01, GENMASK(18, 0));
> +
> +	/* Restore interrupt clearing registers to zero */
> +	regmap_write(hdmi->regs, TOP_INT_CLR00, 0);
> +	regmap_write(hdmi->regs, TOP_INT_CLR01, 0);
> +
> +	return ret;
> +}
> +
> +static irqreturn_t __mtk_hdmi_v2_isr_thread(struct mtk_hdmi *hdmi)
> +{
> +	enum hdmi_hpd_state hpd;
> +
> +	hpd = mtk_hdmi_v2_hpd_pord_status(hdmi);
> +	if (hpd != hdmi->hpd) {
> +		hdmi->hpd = hpd;
> +		mtk_hdmi_hpd_event(hpd, hdmi->dev);
> +	}
> +
> +	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t mtk_hdmi_v2_isr_thread(int irq, void *arg)
> +{
> +	struct mtk_hdmi *hdmi = arg;
> +
> +	/*
> +	 * Debounce HDMI monitor HPD status.
> +	 * Empirical testing shows that 30ms is enough wait
> +	 */
> +	msleep(30);
> +
> +	return __mtk_hdmi_v2_isr_thread(hdmi);
> +}
> +
> +static int mtk_hdmi_v2_enable(struct mtk_hdmi *hdmi)
> +{
> +	int ret;
> +
> +	ret = pm_runtime_resume_and_get(hdmi->dev);
> +	if (ret) {
> +		dev_err(hdmi->dev, "Cannot resume HDMI\n");
> +		return ret;
> +	}
> +
> +	mtk_hdmi_v2_clk_enable(hdmi);
> +	mtk_hdmi_v2_hw_reset(hdmi);
> +	mtk_hdmi_v2_set_sw_hpd(hdmi, true);
> +
> +	return 0;
> +}
> +
> +/*
> + * Bridge callbacks
> + */
> +
> +static int mtk_hdmi_v2_bridge_attach(struct drm_bridge *bridge,
> +				     enum drm_bridge_attach_flags flags)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +	int ret;
> +
> +	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
> +		DRM_ERROR("The flag DRM_BRIDGE_ATTACH_NO_CONNECTOR must be supplied\n");
> +		return -EINVAL;
> +	}
> +	if (hdmi->next_bridge) {
> +		ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge, bridge, flags);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	/* Enable the controller at attach time for HPD/Pord feedback */
> +	ret = mtk_hdmi_v2_enable(hdmi);
> +	if (ret)
> +		return ret;

This looks like a hack. Please use .hpd_enable() / .hpd_disable()
callbacks.

> +
> +	/* Enable Hotplug and Pord pins internal debouncing */
> +	regmap_set_bits(hdmi->regs, HPD_DDC_CTRL,
> +			HPD_DDC_HPD_DBNC_EN | HPD_DDC_PORD_DBNC_EN);
> +
> +	irq_clear_status_flags(hdmi->irq, IRQ_NOAUTOEN);
> +	enable_irq(hdmi->irq);
> +
> +	/*
> +	 * Check if any HDMI monitor was connected before probing this driver
> +	 * and/or attaching the bridge, without debouncing: if so, we want to
> +	 * notify the DRM so that we start outputting an image ASAP.
> +	 * Note that calling the ISR thread function will also perform a HW
> +	 * registers write that enables both the HPD and Pord interrupts.
> +	 */
> +	__mtk_hdmi_v2_isr_thread(hdmi);
> +
> +	return 0;
> +}
> +
> +static void mtk_hdmi_v2_bridge_detach(struct drm_bridge *bridge)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +
> +	/* Disable interrupts */
> +	mtk_hdmi_v2_hwirq_disable(hdmi);
> +	disable_irq(hdmi->irq);
> +	pm_runtime_put_sync(hdmi->dev);
> +}
> +
> +static void mtk_hdmi_v2_handle_plugged_change(struct mtk_hdmi *hdmi, bool plugged)
> +{
> +	mutex_lock(&hdmi->update_plugged_status_lock);
> +	if (hdmi->plugged_cb && hdmi->codec_dev)
> +		hdmi->plugged_cb(hdmi->codec_dev, plugged);
> +	mutex_unlock(&hdmi->update_plugged_status_lock);
> +}
> +
> +static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
> +					  struct drm_bridge_state *old_state)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +	struct drm_atomic_state *state = old_state->base.state;
> +	struct drm_connector_state *conn_state;
> +	union phy_configure_opts opts = {
> +		.dp = { .link_rate = hdmi->mode.clock * KILO }
> +	};
> +
> +	/* Retrieve the connector through the atomic state */
> +	hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
> +
> +	conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
> +	if (WARN_ON(!conn_state))
> +		return;
> +
> +	/*
> +	 * Preconfigure the HDMI controller and the HDMI PHY at pre_enable
> +	 * stage to make sure that this IP is ready and clocked before the
> +	 * mtk_dpi gets powered on and before it enables the output.
> +	 */
> +	hdmi->dvi_mode = !hdmi->curr_conn->display_info.is_hdmi;

Can you access display_info directly instead?

> +	mtk_hdmi_v2_output_set_display_mode(hdmi, &hdmi->mode);
> +
> +	/* Reconfigure phy clock link with appropriate rate */
> +	phy_configure(hdmi->phy, &opts);
> +
> +	/* Power on the PHY here to make sure that DPI_HDMI is clocked */
> +	phy_power_on(hdmi->phy);
> +
> +	hdmi->powered = true;
> +}
> +
> +static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
> +				      struct drm_bridge_state *old_state)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +	struct drm_atomic_state *state = old_state->base.state;
> +	int ret;
> +
> +	ret = drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
> +	if (ret)
> +		dev_err(hdmi->dev, "Could not update infoframes: %d\n", ret);
> +
> +	mtk_hdmi_v2_hw_vid_mute(hdmi, false);
> +	mtk_hdmi_v2_hw_aud_mute(hdmi, false);
> +
> +	/* signal the connect event to audio codec */
> +	mtk_hdmi_v2_handle_plugged_change(hdmi, true);

I think it was agreed that this should be called from the hotplug path,
see the (linked) HDMI codec infrastructure patchset and dicussions for
the previous revisions.

> +
> +	hdmi->enabled = true;
> +}
> +
> +static void mtk_hdmi_v2_bridge_disable(struct drm_bridge *bridge,
> +				       struct drm_bridge_state *old_bridge_state)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +
> +	if (!hdmi->enabled)
> +		return;
> +
> +	mtk_hdmi_v2_hw_av_mute(hdmi, true);
> +	msleep(50);
> +	mtk_hdmi_v2_hw_vid_mute(hdmi, true);
> +	mtk_hdmi_v2_hw_aud_mute(hdmi, true);
> +	mtk_hdmi_v2_disable_hdcp_encrypt(hdmi);
> +	msleep(50);
> +
> +	hdmi->enabled = false;
> +}
> +
> +static void mtk_hdmi_v2_bridge_post_disable(struct drm_bridge *bridge,
> +					    struct drm_bridge_state *old_state)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +
> +	if (!hdmi->powered)
> +		return;
> +
> +	/* Disable VSync interrupt */
> +	regmap_clear_bits(hdmi->regs, TOP_INT_ENABLE00, HDMI_VSYNC_INT);
> +
> +	phy_power_off(hdmi->phy);
> +	hdmi->powered = false;
> +
> +	/* signal the disconnect event to audio codec */
> +	mtk_hdmi_v2_handle_plugged_change(hdmi, false);
> +}
> +
> +static enum drm_connector_status mtk_hdmi_v2_bridge_detect(struct drm_bridge *bridge)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +
> +	return hdmi->hpd != HDMI_PLUG_OUT ?
> +	       connector_status_connected : connector_status_disconnected;
> +}
> +
> +static const struct drm_edid *mtk_hdmi_v2_bridge_edid_read(struct drm_bridge *bridge,
> +							   struct drm_connector *connector)
> +{
> +	return drm_edid_read(connector);
> +}
> +
> +static int mtk_hdmi_v2_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> +						 const struct drm_display_mode *mode,
> +						 unsigned long long tmds_rate)
> +{
> +	if (mode->clock < MTK_HDMI_V2_CLOCK_MIN)
> +		return MODE_CLOCK_LOW;
> +	else if (mode->clock > MTK_HDMI_V2_CLOCK_MAX)
> +		return MODE_CLOCK_HIGH;
> +	else
> +		return MODE_OK;
> +}
> +
> +static enum drm_mode_status
> +mtk_hdmi_v2_bridge_mode_valid(struct drm_bridge *bridge,
> +			      const struct drm_display_info *info,
> +			      const struct drm_display_mode *mode)
> +{
> +	unsigned long long rate;
> +
> +	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
> +	return mtk_hdmi_v2_hdmi_tmds_char_rate_valid(bridge, mode, rate);
> +}

Please rebase on top of https://patchwork.freedesktop.org/series/140193/
There should be no need to do this manually.

> +
> +static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge,
> +					    enum hdmi_infoframe_type type)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +	u32 reg_start, reg_end;
> +
> +	switch (type) {
> +	case HDMI_INFOFRAME_TYPE_AUDIO:
> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
> +		reg_start = TOP_AIF_HEADER;
> +		reg_end = TOP_AIF_PKT03;
> +		break;
> +	case HDMI_INFOFRAME_TYPE_AVI:
> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
> +		reg_start = TOP_AVI_HEADER;
> +		reg_end = TOP_AVI_PKT05;
> +		break;
> +	case HDMI_INFOFRAME_TYPE_SPD:
> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
> +		reg_start = TOP_SPDIF_HEADER;
> +		reg_end = TOP_SPDIF_PKT07;
> +		break;
> +	case HDMI_INFOFRAME_TYPE_VENDOR:
> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
> +		reg_start = TOP_VSIF_HEADER;
> +		reg_end = TOP_VSIF_PKT07;
> +		break;
> +	case HDMI_INFOFRAME_TYPE_DRM:
> +	default:
> +		return 0;
> +	};
> +
> +	for (; reg_start <= reg_end; reg_start += 4)
> +		regmap_write(hdmi->regs, reg_start, 0);

Interesting. Usually sending of the infoframe is controlled by a
register of a kind.

> +
> +	return 0;
> +}
> +
> +static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge,
> +					    enum hdmi_infoframe_type type,
> +					    const u8 *buffer, size_t len)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +
> +	switch (type) {
> +	case HDMI_INFOFRAME_TYPE_AUDIO:
> +		mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_AVI:
> +		mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_SPD:
> +		mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_VENDOR:
> +		mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_DRM:
> +	default:
> +		dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type);
> +		break;
> +	};
> +
> +	return 0;
> +}
> +
> +static int mtk_hdmi_v2_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)
> +{
> +	return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
> +						      conn_state->state);
> +}

Note to myself, probably we can move this to drm_bridge_connector too.

> +
> +static int mtk_hdmi_v2_set_abist(struct mtk_hdmi *hdmi, bool enable)
> +{
> +	struct drm_display_mode *mode = &hdmi->mode;
> +	int abist_format = -EINVAL;
> +	bool interlaced;
> +
> +	if (!enable) {
> +		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
> +		return 0;
> +	}
> +
> +	if (!mode->hdisplay || !mode->vdisplay)
> +		return -EINVAL;
> +
> +	interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;

The interlaced modes should be filtered, unless you also set
bridge->interlace_allowed to true.

> +
> +	switch (mode->hdisplay) {
> +	case 720:
> +		if (mode->vdisplay == 480)
> +			abist_format = 2;
> +		else if (mode->vdisplay == 576)
> +			abist_format = 11;
> +		break;
> +	case 1280:
> +		if (mode->vdisplay == 720)
> +			abist_format = 3;
> +		break;
> +	case 1440:
> +		if (mode->vdisplay == 480)
> +			abist_format = interlaced ? 5 : 9;
> +		else if (mode->vdisplay == 576)
> +			abist_format = interlaced ? 14 : 18;
> +		break;
> +	case 1920:
> +		if (mode->vdisplay == 1080)
> +			abist_format = interlaced ? 4 : 10;
> +		break;
> +	case 3840:
> +		if (mode->vdisplay == 2160)
> +			abist_format = 25;
> +		break;
> +	case 4096:
> +		if (mode->vdisplay == 2160)
> +			abist_format = 26;
> +		break;
> +	default:
> +		break;
> +	}
> +	if (!abist_format)
> +		return -EINVAL;
> +
> +	regmap_update_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_VIDEO_FORMAT,
> +			   FIELD_PREP(HDMI_ABIST_VIDEO_FORMAT, abist_format));
> +	regmap_set_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
> +	return 0;
> +}
> +
> +static int mtk_hdmi_v2_debug_abist_show(struct seq_file *m, void *arg)
> +{
> +	struct mtk_hdmi *hdmi = m->private;
> +	bool en;
> +	u32 val;
> +	int ret;
> +
> +	if (!hdmi)
> +		return -EINVAL;
> +
> +	ret = regmap_read(hdmi->regs, TOP_CFG00, &val);
> +	if (ret)
> +		return ret;
> +
> +	en = FIELD_GET(HDMI_ABIST_ENABLE, val);
> +
> +	seq_printf(m, "HDMI Automated Built-In Self Test: %s\n",
> +		   en ? "Enabled" : "Disabled");
> +
> +	return 0;
> +}
> +
> +static ssize_t mtk_hdmi_v2_debug_abist_write(struct file *file,
> +					     const char __user *ubuf,
> +					     size_t len, loff_t *offp)
> +{
> +	struct seq_file *m = file->private_data;
> +	int ret;
> +	u32 en;
> +
> +	if (!m || !m->private || *offp)
> +		return -EINVAL;
> +
> +	ret = kstrtouint_from_user(ubuf, len, 0, &en);
> +	if (ret)
> +		return ret;
> +
> +	if (en < 0 || en > 1)
> +		return -EINVAL;
> +
> +	mtk_hdmi_v2_set_abist((struct mtk_hdmi *)m->private, en);
> +	return len;
> +}
> +
> +static int mtk_hdmi_v2_debug_abist_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, mtk_hdmi_v2_debug_abist_show, inode->i_private);
> +}
> +
> +static const struct file_operations mtk_hdmi_debug_abist_fops = {
> +	.owner = THIS_MODULE,
> +	.open = mtk_hdmi_v2_debug_abist_open,
> +	.read = seq_read,
> +	.write = mtk_hdmi_v2_debug_abist_write,
> +	.llseek = seq_lseek,
> +	.release = single_release,
> +};
> +
> +static void mtk_hdmi_v2_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
> +{
> +	struct mtk_hdmi *dpi = hdmi_ctx_from_bridge(bridge);
> +
> +	debugfs_create_file("hdmi_abist", 0640, root, dpi, &mtk_hdmi_debug_abist_fops);
> +}
> +
> +static const struct drm_bridge_funcs mtk_v2_hdmi_bridge_funcs = {
> +	.attach = mtk_hdmi_v2_bridge_attach,
> +	.detach = mtk_hdmi_v2_bridge_detach,
> +	.mode_fixup = mtk_hdmi_bridge_mode_fixup,
> +	.mode_set = mtk_hdmi_bridge_mode_set,
> +	.mode_valid = mtk_hdmi_v2_bridge_mode_valid,
> +	.atomic_pre_enable = mtk_hdmi_v2_bridge_pre_enable,
> +	.atomic_enable = mtk_hdmi_v2_bridge_enable,
> +	.atomic_disable = mtk_hdmi_v2_bridge_disable,
> +	.atomic_post_disable = mtk_hdmi_v2_bridge_post_disable,
> +	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> +	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> +	.atomic_check = mtk_hdmi_v2_bridge_atomic_check,
> +	.atomic_reset = drm_atomic_helper_bridge_reset,
> +	.detect = mtk_hdmi_v2_bridge_detect,
> +	.edid_read = mtk_hdmi_v2_bridge_edid_read,
> +	.hdmi_tmds_char_rate_valid = mtk_hdmi_v2_hdmi_tmds_char_rate_valid,
> +	.hdmi_clear_infoframe = mtk_hdmi_v2_hdmi_clear_infoframe,
> +	.hdmi_write_infoframe = mtk_hdmi_v2_hdmi_write_infoframe,
> +	.debugfs_init = mtk_hdmi_v2_debugfs_init,
> +};
> +
> +/*
> + * HDMI audio codec callbacks
> + */
> +static int mtk_hdmi_v2_audio_hook_plugged_cb(struct device *dev, void *data,
> +					     hdmi_codec_plugged_cb fn,
> +					     struct device *codec_dev)
> +{
> +	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +	bool plugged;
> +
> +	if (!hdmi)
> +		return -ENODEV;
> +
> +	mtk_hdmi_audio_set_plugged_cb(hdmi, fn, codec_dev);
> +	plugged = (hdmi->hpd == HDMI_PLUG_IN_AND_SINK_POWER_ON);
> +	mtk_hdmi_v2_handle_plugged_change(hdmi, plugged);
> +
> +	return 0;
> +}
> +
> +static int mtk_hdmi_v2_audio_hw_params(struct device *dev, void *data,
> +				       struct hdmi_codec_daifmt *daifmt,
> +				       struct hdmi_codec_params *params)
> +{
> +	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +
> +	if (hdmi->audio_enable) {
> +		mtk_hdmi_audio_params(hdmi, daifmt, params);
> +		mtk_hdmi_v2_aud_output_config(hdmi, &hdmi->mode);
> +	}
> +	return 0;
> +}
> +
> +static int mtk_hdmi_v2_audio_startup(struct device *dev, void *data)
> +{
> +	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +
> +	mtk_hdmi_v2_hw_aud_enable(hdmi, true);
> +	hdmi->audio_enable = true;
> +
> +	return 0;
> +}
> +
> +static void mtk_hdmi_v2_audio_shutdown(struct device *dev, void *data)
> +{
> +	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +
> +	hdmi->audio_enable = false;
> +	mtk_hdmi_v2_hw_aud_enable(hdmi, false);
> +}
> +
> +static int mtk_hdmi_v2_audio_mute(struct device *dev, void *data, bool enable, int dir)
> +{
> +	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +
> +	mtk_hdmi_v2_hw_aud_mute(hdmi, enable);
> +
> +	return 0;
> +}
> +
> +static const struct hdmi_codec_ops mtk_hdmi_v2_audio_codec_ops = {
> +	.hw_params = mtk_hdmi_v2_audio_hw_params,
> +	.audio_startup = mtk_hdmi_v2_audio_startup,
> +	.audio_shutdown = mtk_hdmi_v2_audio_shutdown,
> +	.mute_stream = mtk_hdmi_v2_audio_mute,
> +	.get_eld = mtk_hdmi_audio_get_eld,
> +	.hook_plugged_cb = mtk_hdmi_v2_audio_hook_plugged_cb,
> +};
> +
> +static __maybe_unused int mtk_hdmi_v2_suspend(struct device *dev)
> +{
> +	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +
> +	mtk_hdmi_v2_hwirq_disable(hdmi);
> +	mtk_hdmi_v2_clk_disable(hdmi);
> +	pm_runtime_put_sync(dev);
> +
> +	return 0;
> +}
> +
> +static __maybe_unused int mtk_hdmi_v2_resume(struct device *dev)
> +{
> +	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +	int ret;
> +
> +	pm_runtime_get_sync(dev);
> +
> +	ret = mtk_hdmi_v2_clk_enable(hdmi);
> +	if (ret)
> +		return ret;
> +
> +	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(mtk_hdmi_v2_pm_ops, mtk_hdmi_v2_suspend, mtk_hdmi_v2_resume);
> +
> +static const struct mtk_hdmi_ver_conf mtk_hdmi_conf_v2 = {
> +	.bridge_funcs = &mtk_v2_hdmi_bridge_funcs,
> +	.codec_ops = &mtk_hdmi_v2_audio_codec_ops,
> +	.mtk_hdmi_clock_names = mtk_hdmi_v2_clk_names,
> +	.num_clocks = MTK_HDMI_V2_CLK_COUNT
> +};
> +
> +static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8188 = {
> +	.ver_conf = &mtk_hdmi_conf_v2,
> +	.reg_hdmi_tx_cfg = HDMITX_CONFIG_MT8188
> +};
> +
> +static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8195 = {
> +	.ver_conf = &mtk_hdmi_conf_v2,
> +	.reg_hdmi_tx_cfg = HDMITX_CONFIG_MT8195,
> +};
> +
> +static int mtk_hdmi_v2_probe(struct platform_device *pdev)
> +{
> +	struct mtk_hdmi *hdmi;
> +	int ret;
> +
> +	hdmi = mtk_hdmi_common_probe(pdev);
> +	if (IS_ERR(hdmi))
> +		return PTR_ERR(hdmi);
> +
> +	hdmi->hpd = HDMI_PLUG_OUT;
> +
> +	/*
> +	 * Disable all HW interrupts at probe stage and install the ISR
> +	 * but keep it disabled, as the rest of the interrupts setup is
> +	 * done in the .bridge_attach() callback, which will enable both
> +	 * the right HW IRQs and the ISR.
> +	 */
> +	mtk_hdmi_v2_hwirq_disable(hdmi);
> +	irq_set_status_flags(hdmi->irq, IRQ_NOAUTOEN);
> +	ret = devm_request_threaded_irq(&pdev->dev, hdmi->irq, mtk_hdmi_v2_isr,
> +					mtk_hdmi_v2_isr_thread,
> +					IRQ_TYPE_LEVEL_HIGH,
> +					dev_name(&pdev->dev), hdmi);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret, "Cannot request IRQ\n");
> +
> +	ret = devm_pm_runtime_enable(&pdev->dev);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret, "Cannot enable Runtime PM\n");
> +
> +	return 0;
> +}
> +
> +static void mtk_hdmi_v2_remove(struct platform_device *pdev)
> +{
> +	struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
> +
> +	pm_runtime_disable(&pdev->dev);
> +	i2c_put_adapter(hdmi->ddc_adpt);
> +}
> +
> +static const struct of_device_id mtk_drm_hdmi_v2_of_ids[] = {
> +	{ .compatible = "mediatek,mt8188-hdmi-tx", .data = &mtk_hdmi_conf_mt8188 },
> +	{ .compatible = "mediatek,mt8195-hdmi-tx", .data = &mtk_hdmi_conf_mt8195 },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_v2_of_ids);
> +
> +static struct platform_driver mtk_hdmi_v2_driver = {
> +	.probe = mtk_hdmi_v2_probe,
> +	.remove = mtk_hdmi_v2_remove,
> +	.driver = {
> +		.name = "mediatek-drm-hdmi-v2",
> +		.of_match_table = mtk_drm_hdmi_v2_of_ids,
> +		.pm = &mtk_hdmi_v2_pm_ops,
> +	},
> +};
> +module_platform_driver(mtk_hdmi_v2_driver);
> +
> +MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>>");
> +MODULE_AUTHOR("Guillaume Ranquet <granquet at baylibre.com>");
> +MODULE_DESCRIPTION("MediaTek HDMIv2 Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.47.0
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Thu Dec  5 04:56:57 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Dec 2024 14:56:57 +0200
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <f2862790-f613-4583-bec5-302e06c77d8d@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
 <olxtqto5mbgofxg4iqjvsmpxxzz6zoj7pbwmoeklhfjiavqfvv@dyveek7hgtki>
 <f2862790-f613-4583-bec5-302e06c77d8d@collabora.com>
Message-ID: <uhcl2ypz3xmari73xl3l4klu2ucfkfkuj7bt3dz35hfmuzvvkj@5odvmmhivl54>

On Thu, Dec 05, 2024 at 01:36:18PM +0100, AngeloGioacchino Del Regno wrote:
> Il 05/12/24 13:29, Dmitry Baryshkov ha scritto:
> > On Thu, Dec 05, 2024 at 12:45:14PM +0100, AngeloGioacchino Del Regno wrote:
> > > In preparation for adding a new driver for the HDMI TX v2 IP,
> > > split out the functions that will be common between the already
> > > present mtk_hdmi (v1) driver and the new one.
> > > 
> > > Since the probe flow for both drivers is 90% similar, add a common
> > > probe function that will be called from each driver's .probe()
> > > callback, avoiding lots of code duplication.
> > > 
> > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > > ---
> > >   drivers/gpu/drm/mediatek/Kconfig           |  11 +-
> > >   drivers/gpu/drm/mediatek/Makefile          |   1 +
> > >   drivers/gpu/drm/mediatek/mtk_hdmi.c        | 724 +++------------------
> > >   drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 425 ++++++++++++
> > >   drivers/gpu/drm/mediatek/mtk_hdmi_common.h | 203 ++++++
> > >   5 files changed, 729 insertions(+), 635 deletions(-)
> > >   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> > >   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> > > 
> > > @@ -1026,19 +812,12 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi,
> > >   	return 0;
> > >   }
> > > -static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
> > > +static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, u8 *buffer_spd, size_t bufsz_spd,
> > > +				    u8 *buffer_avi, size_t bufsz_avi,
> > > +				    struct drm_display_mode *mode)
> > >   {
> > > -	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> > > -
> > > -	hdmi->csp = HDMI_COLORSPACE_RGB;
> > > -	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> > > -	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> > > -	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> > > -	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> > > -	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> > > -	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> > > -
> > > -	return 0;
> > > +	mtk_hdmi_setup_avi_infoframe(hdmi, buffer_avi, bufsz_avi, mode);
> > > +	mtk_hdmi_setup_spd_infoframe(hdmi, buffer_spd, bufsz_spd, "mediatek", "On-chip HDMI");
> > 
> > Please use the HDMI Connector framework instead of handling everything
> > on your own.
> > 
> 
> Dmitry, my plan is to get the MediaTek HDMIv2 driver upstreamed *with* using
> the HDMI helpers - this commit is only splitting the old HDMI v1 driver in
> common parts and v1 handling.
> 
> This "handling everything on my own" is something that was already present
> into the old v1 driver, I am *not adding* this code, but *moving it around*.
> 
> I cannot migrate the v1 driver to the HDMI helpers right now because in this
> moment I have no way to test that and I don't want to break any functionality.
> 
> If you check patch 15, you'll see that I am indeed using all of the helper
> goodies - but for now only on the new driver, and not on the old one.
> 
> I do plan to migrate the v1 driver to the new helpers as well, but I would
> (please) really prefer to do that only after the v2 driver is upstreamed.
> 
> Is that okay for you?

Yes, I've sent this comment before seeing the last patches.

> 
> Cheers,
> Angelo
> 
> > >   }
> > >   static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)
> > 
> 
> 
> 

-- 
With best wishes
Dmitry


From geert+renesas at glider.be  Thu Dec  5 04:53:48 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  5 Dec 2024 13:53:48 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: white-hawk-ard-audio: Drop SoC part
In-Reply-To: <cover.1733402907.git.geert+renesas@glider.be>
References: <cover.1733402907.git.geert+renesas@glider.be>
Message-ID: <0a72c67991828784066f76b61605d2f7913a353c.1733402907.git.geert+renesas@glider.be>

The White Hawk with ARD-AUDIO-DA7212 external audio board stack is not
specific to R8A779G0.  Hence rename its DTS file name to drop the
"r8a779g0-" prefix.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/Makefile                          | 4 ++--
 ...ard-audio-da7212.dtso => white-hawk-ard-audio-da7212.dtso} | 0
 2 files changed, 2 insertions(+), 2 deletions(-)
 rename arch/arm64/boot/dts/renesas/{r8a779g0-white-hawk-ard-audio-da7212.dtso => white-hawk-ard-audio-da7212.dtso} (100%)

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index df9ea5b2e20818f4..dea812ba55f3132e 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -86,8 +86,8 @@ dtb-$(CONFIG_ARCH_R8A779F0) += r8a779f4-s4sk.dtb
 
 dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk.dtb
 dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-cpu.dtb
-dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-ard-audio-da7212.dtbo
-r8a779g0-white-hawk-ard-audio-da7212-dtbs := r8a779g0-white-hawk.dtb r8a779g0-white-hawk-ard-audio-da7212.dtbo
+dtb-$(CONFIG_ARCH_R8A779G0) += white-hawk-ard-audio-da7212.dtbo
+r8a779g0-white-hawk-ard-audio-da7212-dtbs := r8a779g0-white-hawk.dtb white-hawk-ard-audio-da7212.dtbo
 dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-ard-audio-da7212.dtb
 
 dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g2-white-hawk-single.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso b/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
similarity index 100%
rename from arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso
rename to arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
-- 
2.34.1



From geert+renesas at glider.be  Thu Dec  5 04:53:49 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  5 Dec 2024 13:53:49 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: white-hawk-single: Add R-Car Sound support
In-Reply-To: <cover.1733402907.git.geert+renesas@glider.be>
References: <cover.1733402907.git.geert+renesas@glider.be>
Message-ID: <7c840b6e08e0af8a6b9bd5516969eb585f16e10a.1733402907.git.geert+renesas@glider.be>

White Hawk Single boards can use the same ARD-AUDIO-DA7212 external
audio board as the White Hawk board stack.  Add support for building
DTBs for them, and document the small differences in connector labels.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/Makefile                       | 4 ++++
 .../boot/dts/renesas/white-hawk-ard-audio-da7212.dtso      | 7 ++++---
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index dea812ba55f3132e..68031d0f28fb2a54 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -91,8 +91,12 @@ r8a779g0-white-hawk-ard-audio-da7212-dtbs := r8a779g0-white-hawk.dtb white-hawk-
 dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-ard-audio-da7212.dtb
 
 dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g2-white-hawk-single.dtb
+r8a779g2-white-hawk-single-ard-audio-da7212-dtbs := r8a779g2-white-hawk-single.dtb white-hawk-ard-audio-da7212.dtbo
+dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g2-white-hawk-single-ard-audio-da7212.dtb
 
 dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-white-hawk-single.dtb
+r8a779g3-white-hawk-single-ard-audio-da7212-dtbs := r8a779g3-white-hawk-single.dtb white-hawk-ard-audio-da7212.dtbo
+dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-white-hawk-single-ard-audio-da7212.dtb
 
 dtb-$(CONFIG_ARCH_R8A779H0) += r8a779h0-gray-hawk-single.dtb
 
diff --git a/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso b/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
index e6cf304c77ee9225..1308a35561365f51 100644
--- a/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
+++ b/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the White Hawk board with ARD-AUDIO-DA7212 Board
+ * Device Tree Source for the White Hawk (Single) board with ARD-AUDIO-DA7212
+ * Board
  *
  * You can find and buy "ARD-AUDIO-DA7212" at Digi-Key
  *
@@ -27,12 +28,12 @@
  * +----------------------------+
  * |Breakout board		|
  * |				|	+---------------+
- * |CN34 (I2C CN)		|	|J1		|
+ * |CN(30)34 (I2C CN)		|	|J1		|
  * |	I2C0_SCL	   pin3 |<----->| pin20 SCL	|
  * |	I2C0_SDA	   pin5 |<----->| pin18 SDA	|
  * |				|	+---------------+
  * |				|	+-----------------------+
- * |CN4 (Power)		        |	|J7			|
+ * |CN(300)4 (Power)	        |	|J7			|
  * |	3v3 (v)		   pin9 |<----->| pin4  / pin8  3.3v	|
  * |	GND (v)	    pin3 / pin4 |<----->| pin12 / pin14 GND	|
  * +----------------------------+	+-----------------------+
-- 
2.34.1



From geert+renesas at glider.be  Thu Dec  5 04:53:47 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  5 Dec 2024 13:53:47 +0100
Subject: [PATCH 0/2] arm64: dts: renesas: white-hawk-single: Add R-Car Sound support
Message-ID: <cover.1733402907.git.geert+renesas@glider.be>

	Hi all,

This patch series add R-Car Sound support for the various variants of
the White Hawk Single development board, using the ARD-AUDIO-DA7212
external audio board.

The second hunk in the second patch depends on "[PATCH 0/5] arm64:
renesas: Add R8A779G3 White Hawk Single support"[1]..
This was compile-tested only, due to lack of hardware.

To be queued in renesas-devel for v6.14.
Thanks for your comments!

[1] https://lore.kernel.org/all/cover.1733156661.git.geert+renesas at glider.be

Geert Uytterhoeven (2):
  arm64: dts: renesas: white-hawk-ard-audio: Drop SoC part
  arm64: dts: renesas: white-hawk-single: Add R-Car Sound support

 arch/arm64/boot/dts/renesas/Makefile                      | 8 ++++++--
 ...audio-da7212.dtso => white-hawk-ard-audio-da7212.dtso} | 7 ++++---
 2 files changed, 10 insertions(+), 5 deletions(-)
 rename arch/arm64/boot/dts/renesas/{r8a779g0-white-hawk-ard-audio-da7212.dtso => white-hawk-ard-audio-da7212.dtso} (96%)

-- 
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 quic_vikramsa at quicinc.com  Thu Dec  5 04:58:25 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Thu, 5 Dec 2024 18:28:25 +0530
Subject: [PATCH v7 1/5] media: dt-bindings: Add qcom,sc7280-camss
In-Reply-To: <2cb5940b-3779-4450-a213-fa766df7f406@linaro.org>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-2-quic_vikramsa@quicinc.com>
 <oko5qqysmxhicqzkwhkz54wvsmt64ba3cd37zkcy55ee77owbk@5z3zetfr2ejx>
 <eaffa633-c3a4-4924-8ba7-694b18bf92ee@quicinc.com>
 <2cb5940b-3779-4450-a213-fa766df7f406@linaro.org>
Message-ID: <dbc5e54e-97ef-4d88-a2bd-a6493527c0dc@quicinc.com>


On 12/5/2024 5:26 PM, Bryan O'Donoghue wrote:
> On 05/12/2024 10:59, Vikram Sharma wrote:
>> Hi Krzysztof,
>>
>> Thanks for your "Reviewed-by"
>>
>> +??????? camss at acb3000 {
>>
>> If there is going to be resend, then node name: isp
>>
>> Sure, we will change node-name from camss to isp or camera (As its a 
>> part of generic names recommendation as per the shared link.)
>> If there is a resend. or we will address this as a followup.
>>
>> So
>>
>> - camss at acb3000 {
>> + camera at acb3000 {
>>
>> Best Regards,
>> Vikram
>
> Please no top-posting.
> https://subspace.kernel.org/etiquette.html
>
> Shouldn't that be isp at 0xaddress ?

ACK.

- camss at acb3000 {
+ isp at acb3000 {

In both YAML and DTS. If we post V8.

>
> If you are making this change, please remember to do it in both the 
> example and the dts.
Understood. Will avoid this.
>
> ---
> bod


Best Regards,
Vikram



From rogerq at kernel.org  Thu Dec  5 05:08:39 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 5 Dec 2024 15:08:39 +0200
Subject: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix firmware load
 sequence.
In-Reply-To: <20241205082831.777868-2-m-malladi@ti.com>
References: <20241205082831.777868-1-m-malladi@ti.com>
 <20241205082831.777868-2-m-malladi@ti.com>
Message-ID: <a86bc0b1-8bb4-477e-b7e1-13921bf47b53@kernel.org>

Hi,

On 05/12/2024 10:28, Meghana Malladi wrote:
> From: MD Danish Anwar <danishanwar at ti.com>
> 
> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
> and SLICE1. Currently whenever any ICSSG interface comes up we load the
> respective firmwares to PRU cores and whenever interface goes down, we
> stop the resective cores. Due to this, when SLICE0 goes down while
> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
> stopped. This results in clock jump for SLICE1 interface as the timesync
> related operations are no longer running.
> 
> As there are interdependencies between SLICE0 and SLICE1 firmwares,
> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
> ICSSG interface is up. Add new flag in prueth struct to check if all
> firmwares are running.
> 
> Use emacs_initialized as reference count to load the firmwares for the
> first and last interface up/down. Moving init_emac_mode and fw_offload_mode
> API outside of icssg_config to icssg_common_start API as they need
> to be called only once per firmware boot.
> 
> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
> ---
> 
> Hi all,
> 
> This patch is based on net-next tagged next-20241128.
> v2:https://lore.kernel.org/all/20241128122931.2494446-2-m-malladi at ti.com/
> 
> * Changes since v2 (v3-v2):
> - error handling in caller function of prueth_emac_common_start()
> - Use prus_running flag check before stopping the firmwares
> Both suggested by Roger Quadros <rogerq at kernel.org>
> 
>  drivers/net/ethernet/ti/icssg/icssg_config.c |  45 ++++--
>  drivers/net/ethernet/ti/icssg/icssg_config.h |   1 +
>  drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
>  drivers/net/ethernet/ti/icssg/icssg_prueth.h |   5 +
>  4 files changed, 140 insertions(+), 68 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
> index 5d2491c2943a..342150756cf7 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_config.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
> @@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>  	return 0;
>  }
>  
> -static void icssg_init_emac_mode(struct prueth *prueth)
> +void icssg_init_emac_mode(struct prueth *prueth)
>  {
>  	/* When the device is configured as a bridge and it is being brought
>  	 * back to the emac mode, the host mac address has to be set as 0.
> @@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>  	int i;
>  	u8 mac[ETH_ALEN] = { 0 };
>  
> -	if (prueth->emacs_initialized)
> -		return;
> -
>  	/* Set VLAN TABLE address base */
>  	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>  			   addr <<  SMEM_VLAN_OFFSET);
> @@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>  	/* Clear host MAC address */
>  	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
>  }
> +EXPORT_SYMBOL_GPL(icssg_init_emac_mode);
>  
> -static void icssg_init_fw_offload_mode(struct prueth *prueth)
> +void icssg_init_fw_offload_mode(struct prueth *prueth)
>  {
>  	u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET;
>  	int i;
>  
> -	if (prueth->emacs_initialized)
> -		return;
> -
>  	/* Set VLAN TABLE address base */
>  	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>  			   addr <<  SMEM_VLAN_OFFSET);
> @@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth)
>  		icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr);
>  	icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST);
>  }
> +EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode);
>  
>  int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>  {
> @@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>  	struct icssg_flow_cfg __iomem *flow_cfg;
>  	int ret;
>  
> -	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
> -		icssg_init_fw_offload_mode(prueth);
> -	else
> -		icssg_init_emac_mode(prueth);
> -
>  	memset_io(config, 0, TAS_GATE_MASK_LIST0);
>  	icssg_miig_queues_init(prueth, slice);
>  
> @@ -786,3 +777,31 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port)
>  		writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET);
>  }
>  EXPORT_SYMBOL_GPL(icssg_set_pvid);
> +
> +int emac_fdb_flow_id_updated(struct prueth_emac *emac)
> +{
> +	struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
> +	int slice = prueth_emac_slice(emac);
> +	struct mgmt_cmd fdb_cmd = { 0 };
> +	int ret = 0;
> +
> +	fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
> +	fdb_cmd.type   = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
> +	fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq);
> +	fdb_cmd.param  = 0;
> +
> +	fdb_cmd.param |= (slice << 4);
> +	fdb_cmd.cmd_args[0] = 0;
> +
> +	ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp);
> +
> +	if (ret)
> +		return ret;
> +
> +	WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum);
> +	if (fdb_cmd_rsp.status == 1)
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated);
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
> index 92c2deaa3068..c884e9fa099e 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_config.h
> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
> @@ -55,6 +55,7 @@ struct icssg_rxq_ctx {
>  #define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
>  #define ICSSG_FW_MGMT_CMD_TYPE		0x04
>  #define ICSSG_FW_MGMT_PKT		0x80000000
> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW	0x05
>  
>  struct icssg_r30_cmd {
>  	u32 cmd[4];
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> index c568c84a032b..2e22e793b01a 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> @@ -164,11 +164,11 @@ static struct icssg_firmwares icssg_emac_firmwares[] = {
>  	}
>  };
>  
> -static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
> +static int prueth_emac_start(struct prueth *prueth, int slice)
>  {
>  	struct icssg_firmwares *firmwares;
>  	struct device *dev = prueth->dev;
> -	int slice, ret;
> +	int ret;
>  
>  	if (prueth->is_switch_mode)
>  		firmwares = icssg_switch_firmwares;
> @@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>  	else
>  		firmwares = icssg_emac_firmwares;
>  
> -	slice = prueth_emac_slice(emac);
> -	if (slice < 0) {
> -		netdev_err(emac->ndev, "invalid port\n");
> -		return -EINVAL;
> -	}
> -
> -	ret = icssg_config(prueth, emac, slice);
> -	if (ret)
> -		return ret;
> -
>  	ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
>  	ret = rproc_boot(prueth->pru[slice]);
>  	if (ret) {
> @@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>  		goto halt_rtu;
>  	}
>  
> -	emac->fw_running = 1;
>  	return 0;
>  
>  halt_rtu:
> @@ -220,6 +209,80 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>  	return ret;
>  }
>  
> +static int prueth_emac_common_start(struct prueth *prueth)
> +{
> +	struct prueth_emac *emac;
> +	int ret = 0;
> +	int slice;
> +
> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
> +		return -EINVAL;
> +
> +	/* clear SMEM and MSMC settings for all slices */
> +	memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
> +	memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
> +
> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
> +
> +	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
> +		icssg_init_fw_offload_mode(prueth);
> +	else
> +		icssg_init_emac_mode(prueth);
> +
> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
> +		emac = prueth->emac[slice];
> +		if (emac) {
> +			ret |= icssg_config(prueth, emac, slice);
> +			if (ret)
> +				return ret;
> +		}
> +		ret |= prueth_emac_start(prueth, slice);
> +	}

need newline?

> +	if (!ret)
> +		prueth->prus_running = 1;
> +	else
> +		return ret;
> +
> +	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
> +	       prueth->emac[ICSS_SLICE1];
> +	ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
> +			    emac, IEP_DEFAULT_CYCLE_TIME_NS);
> +	if (ret) {
> +		dev_err(prueth->dev, "Failed to initialize IEP module\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int prueth_emac_common_stop(struct prueth *prueth)
> +{
> +	struct prueth_emac *emac;
> +	int slice;
> +
> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
> +		return -EINVAL;
> +
> +	icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
> +	icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
> +
> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
> +		if (prueth->prus_running) {
> +			rproc_shutdown(prueth->txpru[slice]);
> +			rproc_shutdown(prueth->rtu[slice]);
> +			rproc_shutdown(prueth->pru[slice]);
> +		}
> +	}
> +	prueth->prus_running = 0;
> +
> +	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
> +	       prueth->emac[ICSS_SLICE1];
> +	icss_iep_exit(emac->iep);

if icss_iep_init() failed at prueth_emac_common_start(), we should not be
calling icss_iep_exit(). Maybe you need another flag for iep_init status?

Is it better to call icss_iep_exit() at the top before icssg_class_disable()?

> +
> +	return 0;
> +}
> +
>  /* called back by PHY layer if there is change in link state of hw port*/
>  static void emac_adjust_link(struct net_device *ndev)
>  {
> @@ -369,12 +432,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
>  {
>  	struct icssg_setclock_desc __iomem *sc_descp;
>  	struct prueth_emac *emac = clockops_data;
> +	struct prueth *prueth = emac->prueth;
>  	struct icssg_setclock_desc sc_desc;
>  	u64 cyclecount;
>  	u32 cycletime;
>  	int timeout;
>  
> -	if (!emac->fw_running)
> +	if (!prueth->prus_running)
>  		return;
>  
>  	sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
> @@ -543,23 +607,17 @@ 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;
> +	struct icssg_flow_cfg __iomem *flow_cfg;
>  	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, false);
>  	icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
>  
>  	/* Notify the stack of the actual queue counts. */
> @@ -597,18 +655,23 @@ static int emac_ndo_open(struct net_device *ndev)
>  		goto cleanup_napi;
>  	}
>  
> -	/* reset and start PRU firmware */
> -	ret = prueth_emac_start(prueth, emac);
> -	if (ret)
> -		goto free_rx_irq;
> +	if (!prueth->emacs_initialized) {
> +		ret = prueth_emac_common_start(prueth);
> +		if (ret)
> +			goto stop;
> +	}
>  
> -	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
> +	flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
> +	writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
> +	ret = emac_fdb_flow_id_updated(emac);
>  
> -	if (!prueth->emacs_initialized) {
> -		ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
> -				    emac, IEP_DEFAULT_CYCLE_TIME_NS);
> +	if (ret) {
> +		netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
> +		goto stop;
>  	}
>  
> +	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
> +
>  	ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
>  				   IRQF_ONESHOT, dev_name(dev), emac);
>  	if (ret)
> @@ -653,8 +716,7 @@ static int emac_ndo_open(struct net_device *ndev)
>  free_tx_ts_irq:
>  	free_irq(emac->tx_ts_irq, emac);
>  stop:
> -	prueth_emac_stop(emac);
> -free_rx_irq:
> +	prueth_emac_common_stop(prueth);
>  	free_irq(emac->rx_chns.irq[rx_flow], emac);
>  cleanup_napi:
>  	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
> @@ -689,8 +751,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>  	if (ndev->phydev)
>  		phy_stop(ndev->phydev);
>  
> -	icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
> -
>  	if (emac->prueth->is_hsr_offload_mode)
>  		__dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
>  	else
> @@ -728,11 +788,9 @@ static int emac_ndo_stop(struct net_device *ndev)
>  	/* Destroying the queued work in ndo_stop() */
>  	cancel_delayed_work_sync(&emac->stats_work);
>  
> -	if (prueth->emacs_initialized == 1)
> -		icss_iep_exit(emac->iep);
> -
>  	/* stop PRUs */
> -	prueth_emac_stop(emac);
> +	if (prueth->emacs_initialized == 1)
> +		prueth_emac_common_stop(prueth);
>  
>  	free_irq(emac->tx_ts_irq, emac);
>  
> @@ -1069,16 +1127,10 @@ static void prueth_emac_restart(struct prueth *prueth)
>  	icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
>  
>  	/* Stop both pru cores for both PRUeth ports*/
> -	prueth_emac_stop(emac0);
> -	prueth->emacs_initialized--;
> -	prueth_emac_stop(emac1);
> -	prueth->emacs_initialized--;
> +	prueth_emac_common_stop(prueth);
>  
>  	/* Start both pru cores for both PRUeth ports */
> -	prueth_emac_start(prueth, emac0);
> -	prueth->emacs_initialized++;
> -	prueth_emac_start(prueth, emac1);
> -	prueth->emacs_initialized++;
> +	prueth_emac_common_start(prueth);

But this can fail? You need to deal with failure condition appropriately.

>  
>  	/* Enable forwarding for both PRUeth ports */
>  	icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
> @@ -1413,13 +1465,10 @@ static int prueth_probe(struct platform_device *pdev)
>  		prueth->pa_stats = NULL;
>  	}
>  
> -	if (eth0_node) {
> +	if (eth0_node || eth1_node) {
>  		ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
>  		if (ret)
>  			goto put_cores;
> -	}
> -
> -	if (eth1_node) {
>  		ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
>  		if (ret)
>  			goto put_cores;
> @@ -1618,14 +1667,12 @@ static int prueth_probe(struct platform_device *pdev)
>  	pruss_put(prueth->pruss);
>  
>  put_cores:
> -	if (eth1_node) {
> -		prueth_put_cores(prueth, ICSS_SLICE1);
> -		of_node_put(eth1_node);
> -	}
> -
> -	if (eth0_node) {
> +	if (eth0_node || eth1_node) {
>  		prueth_put_cores(prueth, ICSS_SLICE0);
>  		of_node_put(eth0_node);
> +
> +		prueth_put_cores(prueth, ICSS_SLICE1);
> +		of_node_put(eth1_node);
>  	}
>  
>  	return ret;
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> index f5c1d473e9f9..b30f2e9a73d8 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> @@ -257,6 +257,7 @@ struct icssg_firmwares {
>   * @is_switchmode_supported: indicates platform support for switch mode
>   * @switch_id: ID for mapping switch ports to bridge
>   * @default_vlan: Default VLAN for host
> + * @prus_running: flag to indicate if all pru cores are running
>   */
>  struct prueth {
>  	struct device *dev;
> @@ -298,6 +299,7 @@ struct prueth {
>  	int default_vlan;
>  	/** @vtbl_lock: Lock for vtbl in shared memory */
>  	spinlock_t vtbl_lock;
> +	bool prus_running;

I think you don't need fw_running flag anymore. Could you please remove it
from struct prueth_emac?

>  };
>  
>  struct emac_tx_ts_response {
> @@ -361,6 +363,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
>  			 enum icssg_port_state_cmd state);
>  void icssg_config_set_speed(struct prueth_emac *emac);
>  void icssg_config_half_duplex(struct prueth_emac *emac);
> +void icssg_init_emac_mode(struct prueth *prueth);
> +void icssg_init_fw_offload_mode(struct prueth *prueth);
>  
>  /* Buffer queue helpers */
>  int icssg_queue_pop(struct prueth *prueth, u8 queue);
> @@ -377,6 +381,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
>  		       u8 untag_mask, bool add);
>  u16 icssg_get_pvid(struct prueth_emac *emac);
>  void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
> +int emac_fdb_flow_id_updated(struct prueth_emac *emac);
>  #define prueth_napi_to_tx_chn(pnapi) \
>  	container_of(pnapi, struct prueth_tx_chn, napi_tx)
>  

-- 
cheers,
-roger



From tglx at linutronix.de  Thu Dec  5 05:10:55 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Thu, 05 Dec 2024 14:10:55 +0100
Subject: [PATCH v10 3/7] PCI: endpoint: pci-ep-msi: Add MSI address/data
 pair mutable check
In-Reply-To: <20241204-ep-msi-v10-3-87c378dbcd6d@nxp.com>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
 <20241204-ep-msi-v10-3-87c378dbcd6d@nxp.com>
Message-ID: <87ttbiqnq8.ffs@tglx>

On Wed, Dec 04 2024 at 18:25, Frank Li wrote:
> Some MSI controller change address/data pair when irq_set_affinity().
> Current PCI endpoint can't support this type MSI controller. So add flag
> MSI_FLAG_MUTABLE in include/linux/msi.h and check it when allocate
> doorbell.

Q: Who is going to annotate the affected domains with that flag?

A: Nobody.

Q: What's the value of the flag?

A: Zero, as as it prevents exactly nothing.

You want a MSI_FLAG_MSG_IMMUTABLE and set that on the domains which
provide it. That way you ensure that someone looked at the domain to
validate it.

Thanks,

        tglx


From broonie at kernel.org  Thu Dec  5 05:21:23 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 5 Dec 2024 13:21:23 +0000
Subject: [PATCH 0/4] arm64: ptrace: fix handling of partial SETREGSET
 calls
In-Reply-To: <20241205121655.1824269-1-mark.rutland@arm.com>
References: <20241205121655.1824269-1-mark.rutland@arm.com>
Message-ID: <a2f806dc-c959-454c-bedb-7b76a7416da0@sirena.org.uk>

On Thu, Dec 05, 2024 at 12:16:51PM +0000, Mark Rutland wrote:
> A few of arm64's regsets forget to handle partial-length SETREGSET
> calls, and copy a small portion of uninitialized kernel stack memory to
> the backing storage of the relevant registers. In all cases the read is
> limited to a specific slot on the stack, and the issue does not provide
> a write mechanism.

It feels like we might want a helpers specifically for the case where
we're mapping a value directly into a data structure, it all feels a bit
open coding.  The shape is a bit awkward though since things aren't
usually stored in the same layout as we expose via ptrace when there's
more than one value.

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/20241205/1876c48a/attachment.sig>

From defa.li at mediatek.com  Thu Dec  5 05:29:02 2024
From: defa.li at mediatek.com (Defa Li)
Date: Thu, 5 Dec 2024 21:29:02 +0800
Subject: [PATCH] i3c: master: Improve initialization of numbered I2C adapters
Message-ID: <20241205132934.12110-1-defa.li@mediatek.com>

Add logic to initialize I2C adapters with a specific ID if available,
improving device identification and configuration.

Signed-off-by: Defa Li <defa.li at mediatek.com>
---
 drivers/i3c/master.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 42310c9a00c2..a838cdbb897b 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -2486,7 +2486,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
 	struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master);
 	struct i2c_dev_desc *i2cdev;
 	struct i2c_dev_boardinfo *i2cboardinfo;
-	int ret;
+	int ret, id = -ENODEV;
 
 	adap->dev.parent = master->dev.parent;
 	adap->owner = master->dev.parent->driver->owner;
@@ -2497,7 +2497,14 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
 	adap->timeout = 1000;
 	adap->retries = 3;
 
-	ret = i2c_add_adapter(adap);
+	if (master->dev.of_node)
+		id = of_alias_get_id(master->dev.of_node, "i2c");
+
+	if (id >= 0) {
+		adap->nr = id;
+		ret = i2c_add_numbered_adapter(adap);
+	} else
+		ret = i2c_add_adapter(adap);
 	if (ret)
 		return ret;
 
-- 
2.45.2



From angelogioacchino.delregno at collabora.com  Thu Dec  5 05:30:51 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 5 Dec 2024 14:30:51 +0100
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <4lvsvo6vsc7bipcgftsq3mzunwxoka3wjqad42ptr37oz77zub@5uarhvjmcxnc>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
 <4lvsvo6vsc7bipcgftsq3mzunwxoka3wjqad42ptr37oz77zub@5uarhvjmcxnc>
Message-ID: <a4a74f96-29cc-4007-9b03-f634b84d9cc2@collabora.com>

Il 05/12/24 13:56, Dmitry Baryshkov ha scritto:
> On Thu, Dec 05, 2024 at 12:45:17PM +0100, AngeloGioacchino Del Regno wrote:
>> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
>> found in MediaTek's MT8195, MT8188 SoC and their variants, and
>> including support for display modes up to 4k60 and for HDMI
>> Audio, as per the HDMI 2.0 spec.
>>
>> HDCP and CEC functionalities are also supported by this hardware,
>> but are not included in this commit and that also poses a slight
>> difference between the V2 and V1 controllers in how they handle
>> Hotplug Detection (HPD).
>>
>> While the v1 controller was using the CEC controller to check
>> HDMI cable connection and disconnection, in this driver the v2
>> one does not.
>>
>> This is due to the fact that on parts with v2 designs, like the
>> MT8195 SoC, there is one CEC controller shared between the HDMI
>> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
>> adding support to use the CEC HW to wake up the HDMI controllers
>> it is necessary to have support for one TX, one RX *and* for both
>> at the same time.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
>>   drivers/gpu/drm/mediatek/Kconfig            |    8 +
>>   drivers/gpu/drm/mediatek/Makefile           |    4 +
>>   drivers/gpu/drm/mediatek/mtk_hdmi_common.c  |    5 +
>>   drivers/gpu/drm/mediatek/mtk_hdmi_common.h  |    1 +
>>   drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c  |  403 +++++
>>   drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h |  263 ++++
>>   drivers/gpu/drm/mediatek/mtk_hdmi_v2.c      | 1488 +++++++++++++++++++
>>   7 files changed, 2172 insertions(+)
>>   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
>>   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
>>   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
>>

..snip..

>> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
>> new file mode 100644
>> index 000000000000..05cbfc45be54
>> --- /dev/null
>> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
>> @@ -0,0 +1,1488 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*

..snip..

>> +static int mtk_hdmi_v2_setup_audio_infoframe(struct mtk_hdmi *hdmi)
>> +{
>> +	struct hdmi_codec_params *params = &hdmi->aud_param.codec_params;
>> +	struct hdmi_audio_infoframe frame;
>> +	u8 buffer[14];
>> +	ssize_t ret;
>> +
>> +	memcpy(&frame, &params->cea, sizeof(frame));
>> +
>> +	ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
> 
> This should be handled via HDMI Connector framework too. There is
> already an interface to set / clear audio infoframes.
> als I have been working on an interface to make HDMI codec
> implementation more generic, see [1]. Your comments are appreciated.
> 
> [1] https://patchwork.freedesktop.org/series/134927/
> 

I didn't go for that because I was afraid that your series wouldn't actually
land in the same window as this driver.

I am at this point puzzled to whether I should add a commit on top of this
submission that switches this driver to using the generic HDMI Codec infra
(which could also be helpful as guidance to others trying to do the same on
other drivers, I guess), or if I should just rebase on top of that.

I'd rather add a commit on top to mainly avoid risking to delay this driver,
but if you're absolutely certain that you can get your series merged in the
same window as this driver I have *zero* problems in just rebasing on top.

Besides...

I'll find the time to review your series - I'm sad it didn't land earlier as
I would've written a bit less code otherwise :-)

>> +
>> +	return 0;
>> +}
>> +

..snip..

>> +
>> +	/* Enable the controller at attach time for HPD/Pord feedback */
>> +	ret = mtk_hdmi_v2_enable(hdmi);
>> +	if (ret)
>> +		return ret;
> 
> This looks like a hack. Please use .hpd_enable() / .hpd_disable()
> callbacks.
> 

...but there's no way to power on only the HPD - you can either power on
the entire controller, or nothing.

I can't call mtk_hdmi_v2_enable/disable() from the HPD callbacks.

Perhaps the comment should have been

"Enable the controller attach time also allows HPD/Pord feedback"?

>> +
>> +	/* Enable Hotplug and Pord pins internal debouncing */
>> +	regmap_set_bits(hdmi->regs, HPD_DDC_CTRL,
>> +			HPD_DDC_HPD_DBNC_EN | HPD_DDC_PORD_DBNC_EN);
>> +
>> +	irq_clear_status_flags(hdmi->irq, IRQ_NOAUTOEN);
>> +	enable_irq(hdmi->irq);
>> +
>> +	/*
>> +	 * Check if any HDMI monitor was connected before probing this driver
>> +	 * and/or attaching the bridge, without debouncing: if so, we want to
>> +	 * notify the DRM so that we start outputting an image ASAP.
>> +	 * Note that calling the ISR thread function will also perform a HW
>> +	 * registers write that enables both the HPD and Pord interrupts.
>> +	 */
>> +	__mtk_hdmi_v2_isr_thread(hdmi);
>> +
>> +	return 0;
>> +}
>> +

..snip..

>> +static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
>> +					  struct drm_bridge_state *old_state)
>> +{
>> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>> +	struct drm_atomic_state *state = old_state->base.state;
>> +	struct drm_connector_state *conn_state;
>> +	union phy_configure_opts opts = {
>> +		.dp = { .link_rate = hdmi->mode.clock * KILO }
>> +	};
>> +
>> +	/* Retrieve the connector through the atomic state */
>> +	hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
>> +
>> +	conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
>> +	if (WARN_ON(!conn_state))
>> +		return;
>> +
>> +	/*
>> +	 * Preconfigure the HDMI controller and the HDMI PHY at pre_enable
>> +	 * stage to make sure that this IP is ready and clocked before the
>> +	 * mtk_dpi gets powered on and before it enables the output.
>> +	 */
>> +	hdmi->dvi_mode = !hdmi->curr_conn->display_info.is_hdmi;
> 
> Can you access display_info directly instead?
> 

Nice catch. Yeah, I should've done that from the beginning. Fixed for v3.

>> +	mtk_hdmi_v2_output_set_display_mode(hdmi, &hdmi->mode);
>> +
>> +	/* Reconfigure phy clock link with appropriate rate */
>> +	phy_configure(hdmi->phy, &opts);
>> +
>> +	/* Power on the PHY here to make sure that DPI_HDMI is clocked */
>> +	phy_power_on(hdmi->phy);
>> +
>> +	hdmi->powered = true;
>> +}
>> +
>> +static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
>> +				      struct drm_bridge_state *old_state)
>> +{
>> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>> +	struct drm_atomic_state *state = old_state->base.state;
>> +	int ret;
>> +
>> +	ret = drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
>> +	if (ret)
>> +		dev_err(hdmi->dev, "Could not update infoframes: %d\n", ret);
>> +
>> +	mtk_hdmi_v2_hw_vid_mute(hdmi, false);
>> +	mtk_hdmi_v2_hw_aud_mute(hdmi, false);
>> +
>> +	/* signal the connect event to audio codec */
>> +	mtk_hdmi_v2_handle_plugged_change(hdmi, true);
> 
> I think it was agreed that this should be called from the hotplug path,
> see the (linked) HDMI codec infrastructure patchset and dicussions for
> the previous revisions.
> 

Okay, I'll check that out.

>> +
>> +	hdmi->enabled = true;
>> +}
>> +

..snip..

>> +
>> +static int mtk_hdmi_v2_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
>> +						 const struct drm_display_mode *mode,
>> +						 unsigned long long tmds_rate)
>> +{
>> +	if (mode->clock < MTK_HDMI_V2_CLOCK_MIN)
>> +		return MODE_CLOCK_LOW;
>> +	else if (mode->clock > MTK_HDMI_V2_CLOCK_MAX)
>> +		return MODE_CLOCK_HIGH;
>> +	else
>> +		return MODE_OK;
>> +}
>> +
>> +static enum drm_mode_status
>> +mtk_hdmi_v2_bridge_mode_valid(struct drm_bridge *bridge,
>> +			      const struct drm_display_info *info,
>> +			      const struct drm_display_mode *mode)
>> +{
>> +	unsigned long long rate;
>> +
>> +	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
>> +	return mtk_hdmi_v2_hdmi_tmds_char_rate_valid(bridge, mode, rate);
>> +}
> 
> Please rebase on top of https://patchwork.freedesktop.org/series/140193/
> There should be no need to do this manually.
> 

Oh finally there's a helper for this. Cool, will rebase! Thanks!

>> +
>> +static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge,
>> +					    enum hdmi_infoframe_type type)
>> +{
>> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>> +	u32 reg_start, reg_end;
>> +
>> +	switch (type) {
>> +	case HDMI_INFOFRAME_TYPE_AUDIO:
>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
>> +		reg_start = TOP_AIF_HEADER;
>> +		reg_end = TOP_AIF_PKT03;
>> +		break;
>> +	case HDMI_INFOFRAME_TYPE_AVI:
>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
>> +		reg_start = TOP_AVI_HEADER;
>> +		reg_end = TOP_AVI_PKT05;
>> +		break;
>> +	case HDMI_INFOFRAME_TYPE_SPD:
>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
>> +		reg_start = TOP_SPDIF_HEADER;
>> +		reg_end = TOP_SPDIF_PKT07;
>> +		break;
>> +	case HDMI_INFOFRAME_TYPE_VENDOR:
>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
>> +		reg_start = TOP_VSIF_HEADER;
>> +		reg_end = TOP_VSIF_PKT07;
>> +		break;
>> +	case HDMI_INFOFRAME_TYPE_DRM:
>> +	default:
>> +		return 0;
>> +	};
>> +
>> +	for (; reg_start <= reg_end; reg_start += 4)
>> +		regmap_write(hdmi->regs, reg_start, 0);
> 
> Interesting. Usually sending of the infoframe is controlled by a
> register of a kind.
> 

"This callback clears the infoframes in the hardware during commit"

...and that's exactly what this function does: clears the infoframes
in the HW and stops the RPT, making the HW ready for the "next round".

Did I get the documentation wrong?
Should this function *send* an all-zero infoframe to the external display?

>> +
>> +	return 0;
>> +}
>> +
>> +static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge,
>> +					    enum hdmi_infoframe_type type,
>> +					    const u8 *buffer, size_t len)
>> +{
>> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>> +
>> +	switch (type) {
>> +	case HDMI_INFOFRAME_TYPE_AUDIO:
>> +		mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
>> +		break;
>> +	case HDMI_INFOFRAME_TYPE_AVI:
>> +		mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer);
>> +		break;
>> +	case HDMI_INFOFRAME_TYPE_SPD:
>> +		mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer);
>> +		break;
>> +	case HDMI_INFOFRAME_TYPE_VENDOR:
>> +		mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer);
>> +		break;
>> +	case HDMI_INFOFRAME_TYPE_DRM:
>> +	default:
>> +		dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type);
>> +		break;
>> +	};
>> +
>> +	return 0;
>> +}
>> +
>> +static int mtk_hdmi_v2_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)
>> +{
>> +	return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
>> +						      conn_state->state);
>> +}
> 
> Note to myself, probably we can move this to drm_bridge_connector too.
> 
>> +
>> +static int mtk_hdmi_v2_set_abist(struct mtk_hdmi *hdmi, bool enable)
>> +{
>> +	struct drm_display_mode *mode = &hdmi->mode;
>> +	int abist_format = -EINVAL;
>> +	bool interlaced;
>> +
>> +	if (!enable) {
>> +		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
>> +		return 0;
>> +	}
>> +
>> +	if (!mode->hdisplay || !mode->vdisplay)
>> +		return -EINVAL;
>> +
>> +	interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
> 
> The interlaced modes should be filtered, unless you also set
> bridge->interlace_allowed to true.
> 

Noted. Many Thanks for the review!

I'll wait until next week for more feedback before sending a v3.

Cheers,
Angelo



From maz at kernel.org  Thu Dec  5 05:31:16 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 05 Dec 2024 13:31:16 +0000
Subject: [PATCH 06/11] KVM: arm64: nv: Acceletate EL0 counter accesses from hypervisor context
In-Reply-To: <20241205120707.GA102570@e124191.cambridge.arm.com>
References: <20241202172134.384923-1-maz@kernel.org>
	<20241202172134.384923-7-maz@kernel.org>
	<20241205120707.GA102570@e124191.cambridge.arm.com>
Message-ID: <86h67itfx7.wl-maz@kernel.org>

On Thu, 05 Dec 2024 12:07:07 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> On Mon, Dec 02, 2024 at 05:21:29PM +0000, Marc Zyngier wrote:
> > Similarly to handling the physical timer accesses early when FEAT_ECV
> > causes a trap, we try to handle the physical counter without returning
> > to the general sysreg handling.
> > 
> > More surprisingly, we introduce something similar for the virtual
> > counter. Although this isn't necessary yet, it will prove useful on
> > systems that have a broken CNTVOFF_EL2 implementation. Yes, they exist.
> > 
> 
> > Special care is taken to offset reads of the counter with the host's
> > CNTPOFF_EL2, as we perform this with TGE clear.
> 
> Can you explain this part a bit more? I'm assuming it's somehow related to the
> arch_timer_read_cntpct_el0() call.
> 
> However I think we're at EL2 inside kvm_hyp_handle_timer(), so reading
> CNTPCT_EL0 won't involve CNTPOFF_EL2.
> 
> What am I missing/misunderstanding?

I think the wording above is particularly misleading, and leads to
some bad confusion.

Let's go back to basics: we're at host EL2, and handling a trap from
guest EL2.  Although you are right that CNTPOFF_EL2 doesn't affect a
direct read of CNTPCT_EL0 from EL2, we are emulating it as if it was
executed from EL1 (guest EL2 being EL1).

So any offsetting that would be applied if we were not trapping
CNTPCT_EL0 must still be applied. In the case of a read from
hypervisor context, this is the VM-wide offset.

But this makes me realise that...

> 
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/kvm/hyp/include/hyp/switch.h |  5 +++++
> >  arch/arm64/kvm/hyp/vhe/switch.c         | 13 +++++++++++++
> >  2 files changed, 18 insertions(+)
> > 
> > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > index 34f53707892df..30e572de28749 100644
> > --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> > +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > @@ -501,6 +501,11 @@ static inline bool handle_tx2_tvm(struct kvm_vcpu *vcpu)
> >  	return true;
> >  }
> >  
> > +static inline u64 compute_counter_value(struct arch_timer_context *ctxt)
> > +{
> > +	return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
> > +}
> > +
> >  static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
> >  {
> >  	struct arch_timer_context *ctxt;
> > diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> > index b014b0b10bf5d..49815a8a4c9bc 100644
> > --- a/arch/arm64/kvm/hyp/vhe/switch.c
> > +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> > @@ -296,6 +296,13 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
> >  			val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
> >  		}
> >  		break;
> > +	case SYS_CNTPCT_EL0:
> > +	case SYS_CNTPCTSS_EL0:
> > +		/* If !ELIsInHost(EL0), the guest's CNTPOFF_EL2 applies */
> > +		val = compute_counter_value(!(vcpu_el2_e2h_is_set(vcpu) &&
> > +					      vcpu_el2_tge_is_set(vcpu)) ?
> > +					    vcpu_ptimer(vcpu) : vcpu_hptimer(vcpu));

... this should be simplified, because there is no case where we can
be in HYP context *and* not be using the hptimer() context (everything
else would be handled by kvm_handle_cntxct()).

I'm minded to change this to:

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index a8b1a23712329..5a79ed0aac613 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -305,10 +305,7 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
 		break;
 	case SYS_CNTPCT_EL0:
 	case SYS_CNTPCTSS_EL0:
-		/* If !ELIsInHost(EL0), the guest's CNTPOFF_EL2 applies */
-		val = compute_counter_value(!(vcpu_el2_e2h_is_set(vcpu) &&
-					      vcpu_el2_tge_is_set(vcpu)) ?
-					    vcpu_ptimer(vcpu) : vcpu_hptimer(vcpu));
+		val = compute_counter_value(vcpu_hptimer(vcpu));
 		break;
 	case SYS_CNTV_CTL_EL02:
 		val = __vcpu_sys_reg(vcpu, CNTV_CTL_EL0);

Thanks,

	M.

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


From robh at kernel.org  Thu Dec  5 05:33:52 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 05 Dec 2024 07:33:52 -0600
Subject: [PATCH v2 07/15] dt-bindings: display: mediatek: Add binding
 for MT8195 HDMI-TX v2
In-Reply-To: <20241205114518.53527-8-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-8-angelogioacchino.delregno@collabora.com>
Message-ID: <173340563286.3304541.16351309995499835638.robh@kernel.org>


On Thu, 05 Dec 2024 12:45:09 +0100, AngeloGioacchino Del Regno wrote:
> Add a binding for the HDMI TX v2 Encoder found in MediaTek MT8195
> and MT8188 SoCs.
> 
> This fully supports the HDMI Specification 2.0b, hence it provides
> support for 3D-HDMI, Polarity inversion, up to 16 bits Deep Color,
> color spaces including RGB444, YCBCR420/422/444 (ITU601/ITU709) and
> xvYCC, with output resolutions up to 3840x2160p at 60Hz.
> 
> Moreover, it also supports HDCP 1.4 and 2.3, Variable Refresh Rate
> (VRR) and Consumer Electronics Control (CEC).
> 
> This IP also includes support for HDMI Audio, including IEC60958
> and IEC61937 SPDIF, 8-channel PCM, DSD, and other lossless audio
> according to HDMI 2.0.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  .../mediatek/mediatek,mt8195-hdmi.yaml        | 154 ++++++++++++++++++
>  1 file changed, 154 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml:
Error in referenced schema matching $id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.example.dtb: hdmi-tx at 1c300000: i2c: False schema does not allow {'compatible': ['mediatek,mt8195-hdmi-ddc'], 'clocks': [[4294967295]]}
	from schema $id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.example.dtb: hdmi-tx at 1c300000: i2c: Unevaluated properties are not allowed ('clocks', 'compatible' were unexpected)
	from schema $id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml#
Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.example.dtb: /example-0/soc/hdmi-tx at 1c300000/i2c: failed to match any schema with compatible: ['mediatek,mt8195-hdmi-ddc']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241205114518.53527-8-angelogioacchino.delregno 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 andrej.picej at norik.com  Thu Dec  5 05:40:20 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu,  5 Dec 2024 14:40:20 +0100
Subject: [PATCH v4 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
In-Reply-To: <20241205134021.2592013-1-andrej.picej@norik.com>
References: <20241205134021.2592013-1-andrej.picej@norik.com>
Message-ID: <20241205134021.2592013-3-andrej.picej@norik.com>

Add a optional properties to change LVDS output voltage. This should not
be static as this depends mainly on the connected display voltage
requirement. We have three properties:
- "ti,lvds-termination-ohms", which sets near end termination,
- "ti,lvds-vod-swing-data-microvolt" and
- "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
output voltage for data and clock lanes. They are defined as an array
with min and max values. The appropriate bitfield will be set if
selected constraints can be met.

If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
end termination will be used. Selecting only one:
"ti,lvds-vod-swing-data-microvolt" or
"ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
constraint for only data/clock lanes will be met. Setting both is
recommended.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v4:
- fix typo in commit message bitfiled -> bitfield
- use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
of separate variables for channel A/B
- add more checks on return value of "of_property_read_u32_array"
Changes in v3:
- use microvolts for default array values 1000 mV -> 1000000 uV.
Changes in v2:
- use datasheet tables to get the proper configuration
- since major change was done change the authorship to myself
---
 drivers/gpu/drm/bridge/ti-sn65dsi83.c | 147 +++++++++++++++++++++++++-
 1 file changed, 144 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 57a7ed13f996..f724d2a6777b 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -132,6 +132,16 @@
 #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
 #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
 
+enum sn65dsi83_channel {
+	CHANNEL_A,
+	CHANNEL_B
+};
+
+enum sn65dsi83_lvds_term {
+	OHM_100,
+	OHM_200
+};
+
 enum sn65dsi83_model {
 	MODEL_SN65DSI83,
 	MODEL_SN65DSI84,
@@ -147,6 +157,8 @@ struct sn65dsi83 {
 	struct regulator		*vcc;
 	bool				lvds_dual_link;
 	bool				lvds_dual_link_even_odd_swap;
+	int				lvds_vod_swing_conf[2];
+	int				lvds_term_conf[2];
 };
 
 static const struct regmap_range sn65dsi83_readable_ranges[] = {
@@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
 	.max_register = REG_IRQ_STAT,
 };
 
+static const int lvds_vod_swing_data_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 180000, 313000 },
+		{ 215000, 372000 },
+		{ 250000, 430000 },
+		{ 290000, 488000 },
+	},
+	{	/* 200 Ohm */
+		{ 150000, 261000 },
+		{ 200000, 346000 },
+		{ 250000, 428000 },
+		{ 300000, 511000 },
+	},
+};
+
+static const int lvds_vod_swing_clock_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 140000, 244000 },
+		{ 168000, 290000 },
+		{ 195000, 335000 },
+		{ 226000, 381000 },
+	},
+	{	/* 200 Ohm */
+		{ 117000, 204000 },
+		{ 156000, 270000 },
+		{ 195000, 334000 },
+		{ 234000, 399000 },
+	},
+};
+
 static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
 {
 	return container_of(bridge, struct sn65dsi83, bridge);
@@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
 		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
 
 	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
-	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
+	regmap_write(ctx->regmap, REG_LVDS_VCOM,
+			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
+			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
 	regmap_write(ctx->regmap, REG_LVDS_LANE,
 		     (ctx->lvds_dual_link_even_odd_swap ?
 		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
-		     REG_LVDS_LANE_CHA_LVDS_TERM |
-		     REG_LVDS_LANE_CHB_LVDS_TERM);
+		     (ctx->lvds_term_conf[CHANNEL_A] ?
+			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
+		     (ctx->lvds_term_conf[CHANNEL_B] ?
+			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
 	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
 
 	le16val = cpu_to_le16(mode->hdisplay);
@@ -576,10 +622,101 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
 	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
 };
 
+static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
+	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
+{
+	int i;
+
+	for (i = 0; i <= 3; i++) {
+		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
+		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
+		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
+		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
+			return i;
+	}
+
+	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
+	return -EINVAL;
+}
+
+static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *endpoint;
+	/* Set so the property can be freely selected if not defined */
+	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
+	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
+	u32 lvds_term = 200;
+	u8 lvds_term_conf;
+	int endpoint_reg;
+	int lvds_vod_swing_conf;
+	int ret = 0;
+	int ret_data;
+	int ret_clock;
+
+	if (channel == CHANNEL_A)
+		endpoint_reg = 2;
+	else
+		endpoint_reg = 3;
+
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
+	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
+
+	if (lvds_term == 200)
+		lvds_term_conf = OHM_200;
+	else
+		lvds_term_conf = OHM_100;
+
+	ctx->lvds_term_conf[channel] = lvds_term_conf;
+
+	ret_data = of_property_read_u32_array(endpoint,
+			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
+			ARRAY_SIZE(lvds_vod_swing_data));
+	if (ret_data != 0 && ret_data != -EINVAL) {
+		ret = ret_data;
+		goto exit;
+	}
+
+	ret_clock = of_property_read_u32_array(endpoint,
+			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
+			ARRAY_SIZE(lvds_vod_swing_clk));
+	if (ret_clock != 0 && ret_clock != -EINVAL) {
+		ret = ret_clock;
+		goto exit;
+	}
+
+	/* If any of the two properties is defined. */
+	if (!ret_data || !ret_clock) {
+		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
+			lvds_vod_swing_data, lvds_vod_swing_clk,
+			lvds_term_conf);
+		if (lvds_vod_swing_conf < 0) {
+			ret = lvds_vod_swing_conf;
+			goto exit;
+		}
+
+		ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
+	}
+	ret = 0;
+exit:
+	of_node_put(endpoint);
+	return ret;
+}
+
 static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
 {
 	struct drm_bridge *panel_bridge;
 	struct device *dev = ctx->dev;
+	int ret;
+
+	ctx->lvds_vod_swing_conf[CHANNEL_A] = 0x1;
+	ctx->lvds_vod_swing_conf[CHANNEL_B] = 0x1;
+	ctx->lvds_term_conf[CHANNEL_A] = 0x1;
+	ctx->lvds_term_conf[CHANNEL_B] = 0x1;
+
+	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
+	if (ret < 0)
+		return ret;
 
 	ctx->lvds_dual_link = false;
 	ctx->lvds_dual_link_even_odd_swap = false;
@@ -587,6 +724,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
 		struct device_node *port2, *port3;
 		int dual_link;
 
+		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
+		if (ret < 0)
+			return ret;
+
 		port2 = of_graph_get_port_by_id(dev->of_node, 2);
 		port3 = of_graph_get_port_by_id(dev->of_node, 3);
 		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
-- 
2.34.1



From andrej.picej at norik.com  Thu Dec  5 05:40:19 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu,  5 Dec 2024 14:40:19 +0100
Subject: [PATCH v4 1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for ti,lvds-vod-swing
In-Reply-To: <20241205134021.2592013-1-andrej.picej@norik.com>
References: <20241205134021.2592013-1-andrej.picej@norik.com>
Message-ID: <20241205134021.2592013-2-andrej.picej@norik.com>

Add properties which can be used to specify LVDS differential output
voltage. Since this also depends on near-end signal termination also
include property which sets this. LVDS differential output voltage is
specified with an array (min, max), which should match the one from
connected device.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v4:
- removed "additionalProperties: true" from the patch as it is not needed
Changes in v3:
- no change
Changes in v2:
- move LVDS port schema to a $defs and reference it from there
- properties are now defined in microvolts/ohms
- use 1 property for data-lane and 1 for clock-lane LVDS voltage swing
- add 1 property which sets LVDS near-end termination
- since major change was done change the authorship to myself
---
 .../bindings/display/bridge/ti,sn65dsi83.yaml | 34 +++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
index 48a97bb3e2e0..bad6f5c81b06 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
@@ -80,12 +80,12 @@ properties:
                   - const: 4
 
       port at 2:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-A output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
       port at 3:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-B output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
     required:
       - port at 0
@@ -96,6 +96,36 @@ required:
   - reg
   - ports
 
+$defs:
+  lvds-port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    unevaluatedProperties: false
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          ti,lvds-termination-ohms:
+            description: The value of near end differential termination in ohms.
+            enum: [100, 200]
+            default: 200
+
+          ti,lvds-vod-swing-clock-microvolt:
+            description: LVDS diferential output voltage <min max> for clock
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
+          ti,lvds-vod-swing-data-microvolt:
+            description: LVDS diferential output voltage <min max> for data
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
 allOf:
   - if:
       properties:
-- 
2.34.1



From andrej.picej at norik.com  Thu Dec  5 05:40:18 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu,  5 Dec 2024 14:40:18 +0100
Subject: [PATCH v4 0/3] SN65DSI83/4 lvds_vod_swing properties
Message-ID: <20241205134021.2592013-1-andrej.picej@norik.com>

Hi all,

The LVDS differential voltage swing can be specified as arrays of min, max
in microvolts. Two arrays, one for data-lanes and one for clock-lane can
be specified. Additionally, because LVDS voltage swing depends on near-end
termination this can now also be specified with separate property.

Driver goes through the tables, taken from datasheet [1] and selects the
appropriate configuration. If appropriate configuration can not be found
the probe fails. If these properties are not defined default values are
used as before.

This patch series depends on the patch
"[PATCH v2 11/15] arm64: dts: imx8mm-phyboard-polis: Add support for PEB-AV-10"
(https://lore.kernel.org/all/20241202072052.2195283-12-andrej.picej at norik.com/)
which is currently under review. Please apply the dependent series first before
applying this one.

v1 is at: https://lore.kernel.org/all/20241127103031.1007893-1-andrej.picej at norik.com/
v2 is at: https://lore.kernel.org/all/20241203085822.2475138-1-andrej.picej at norik.com/
v3 is at: https://lore.kernel.org/all/20241203110054.2506123-1-andrej.picej at norik.com/

[1] https://www.ti.com/lit/ds/symlink/sn65dsi83.pdf?ts=1732738773429&ref_url=https%253A%252F%252Fwww.mouser.co.uk%252F

Best regards,
Andrej

Andrej Picej (3):
  dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for
    ti,lvds-vod-swing
  drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
  arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing

 .../bindings/display/bridge/ti,sn65dsi83.yaml |  34 +++-
 .../imx8mm-phyboard-polis-peb-av-10.dtso      |   2 +
 drivers/gpu/drm/bridge/ti-sn65dsi83.c         | 147 +++++++++++++++++-
 3 files changed, 178 insertions(+), 5 deletions(-)

-- 
2.34.1



From andrej.picej at norik.com  Thu Dec  5 05:40:21 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu,  5 Dec 2024 14:40:21 +0100
Subject: [PATCH v4 3/3] arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing
In-Reply-To: <20241205134021.2592013-1-andrej.picej@norik.com>
References: <20241205134021.2592013-1-andrej.picej@norik.com>
Message-ID: <20241205134021.2592013-4-andrej.picej@norik.com>

Set custom differential output voltage for LVDS, to fulfill requirements
of the connected display. LVDS differential voltage for data-lanes and
clock output has to be between 200 mV and 600 mV.
Driver sets 200 Ohm near-end termination by default.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v4:
- no change
Changes in v3:
- no change
Changes in v2:
- use new properties from previous patches
---
 .../boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso     | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
index a9de42cf14be..8bf9cc553bea 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
@@ -186,6 +186,8 @@ port at 2 {
 			reg = <2>;
 			bridge_out: endpoint {
 				remote-endpoint = <&panel_in>;
+				ti,lvds-vod-swing-clock-microvolt = <200000 600000>;
+				ti,lvds-vod-swing-data-microvolt = <200000 600000>;
 			};
 		};
 	};
-- 
2.34.1



From krzk at kernel.org  Thu Dec  5 05:45:33 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 14:45:33 +0100
Subject: [PATCH] clk: rockchip: add clock ID for CIF0/1 on RK3066
In-Reply-To: <1944322.g5d078U9FE@diego>
References: <20241205055122.11613-1-val@packett.cool>
 <5kesytgbhfununu5li4ychaw4newkctx4wuhlshks2ertfkd2t@jauqcntehv2z>
 <1944322.g5d078U9FE@diego>
Message-ID: <bc43fd83-326e-4fe2-9f53-efaef7581a5f@kernel.org>

On 05/12/2024 13:29, Heiko St?bner wrote:
> Hi Krzysztof,
> 
> Am Donnerstag, 5. Dezember 2024, 11:25:28 CET schrieb Krzysztof Kozlowski:
>> On Thu, Dec 05, 2024 at 02:50:46AM -0300, Val Packett wrote:
>>> RK3066 does have two "CIF" video capture interface blocks, add their
>>> corresponding clock IDs so that they could be used.
>>>
>>> Signed-off-by: Val Packett <val at packett.cool>
>>> ---
>>>  drivers/clk/rockchip/clk-rk3188.c             | 4 ++--
>>>  include/dt-bindings/clock/rk3188-cru-common.h | 2 ++
>>>  2 files changed, 4 insertions(+), 2 deletions(-)
>>
>> Please run scripts/checkpatch.pl and fix reported warnings. Then please
>> run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
>> Some warnings can be ignored, especially from --strict run, but the code
>> here looks like it needs a fix. Feel free to get in touch if the warning
>> is not clear.
> 
> I guess you're taking a shot of the indentation?

No, there is a big, fat warning about bindings.

Best regards,
Krzysztof


From christian.bruel at foss.st.com  Thu Dec  5 05:41:26 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Thu, 5 Dec 2024 14:41:26 +0100
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <20241203222515.GA2967814@bhelgaas>
References: <20241203222515.GA2967814@bhelgaas>
Message-ID: <569904ad-2b70-4a58-98fe-4f24e1089e17@foss.st.com>



On 12/3/24 23:25, Bjorn Helgaas wrote:
> On Tue, Nov 26, 2024 at 04:51:15PM +0100, Christian Bruel wrote:
>> Document the bindings for STM32MP25 PCIe Controller configured in
>> root complex mode.
>>
>> Supports 4 legacy interrupts and MSI interrupts from the ARM
>> GICv2m controller.
> 
> s/legacy/INTx/
> 
>> STM32 PCIe may be in a power domain which is the case for the STM32MP25
>> based boards.
>>
>> Supports wake# from wake-gpios
> 
> s/wake#/WAKE#/
> 
>> +  wake-gpios:
>> +    description: GPIO controlled connection to WAKE# input signal
> 
> I'm not a hardware guy, but this sounds like a GPIO that *reads*
> WAKE#, not controls it.

Rephrasing as
"GPIO used as WAKE# input signal" (output for the endpoint bindings)

> 
>> +    pcie at 48400000 {
>> +        compatible = "st,stm32mp25-pcie-rc";
>> +        device_type = "pci";
>> +        num-lanes = <1>;
> 
> num-lanes applies to a Root Port, not to a Root Complex.  I know most
> bindings conflate Root Ports with the Root Complex, maybe because many
> of these controllers only support a single Root Port?
> 
> But are we ever going to separate these out?  I assume someday
> controllers will support multiple Root Ports and/or additional devices
> on the root bus, like RCiEPs, RCECs, etc., and we'll need per-RP phys,
> max-link-speed, num-lanes, reset-gpios, etc.
> 
> Seems like it would be to our benefit to split out the Root Ports when
> we can, even if the current hardware only supports one, so we can
> start untangling the code and data structures.

OK. and we support only 1 lane anyway, so drop it.

thanks,

> 
> Bjorn


From robin.murphy at arm.com  Thu Dec  5 05:48:09 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu,  5 Dec 2024 13:48:09 +0000
Subject: [PATCH 1/2] iommu/arm-smmu-v3: Document SVA interaction with new pagetable features
Message-ID: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>

Process pagetables may now be using new permission-indirection-based
features which an SMMU may not understand when given such a table for
SVA. Although SMMUv3.4 does add its own S1PIE feature, realistically
we're still going to have to cope with feature mismatches between CPUs
and SMMUs, so let's start simple and essentially just document the
expectations for what falls out as-is. Although it seems unlikely for
SVA applications to also depend on memory-hardening features, or
vice-versa, the relative lifecycles make it tricky to enforce mutual
exclusivity. Thankfully our PIE index allocation makes it relatively
benign for an SMMU to keep interpreting them as direct permissions, the
only real implication is that an SVA application cannot harden itself
against its own devices with these features. Thus, inform the user about
that just in case they have other expectations.

Also we don't (yet) support LPA2, so deny SVA entirely if we're going to
misunderstand the pagetable format altogether.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 15 ++++++++++++++-
 1 file changed, 14 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 1d3e71569775..9ba596430e7c 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
@@ -112,6 +112,15 @@ void arm_smmu_make_sva_cd(struct arm_smmu_cd *target,
 	 * from the current CPU register
 	 */
 	target->data[3] = cpu_to_le64(read_sysreg(mair_el1));
+
+	/*
+	 * Note that we don't bother with S1PIE on the SMMU, we just rely on
+	 * our default encoding scheme matching direct permissions anyway.
+	 * SMMU has no notion of S1POE nor GCS, so make sure that is clear if
+	 * either is enabled for CPUs, just in case anyone imagines otherwise.
+	 */
+	if (system_supports_poe() || system_supports_gcs())
+		dev_warn_once(master->smmu->dev, "SVA devices ignore permission overlays and GCS\n");
 }
 EXPORT_SYMBOL_IF_KUNIT(arm_smmu_make_sva_cd);
 
@@ -206,8 +215,12 @@ bool arm_smmu_sva_supported(struct arm_smmu_device *smmu)
 	unsigned long asid_bits;
 	u32 feat_mask = ARM_SMMU_FEAT_COHERENCY;
 
-	if (vabits_actual == 52)
+	if (vabits_actual == 52) {
+		/* We don't support LPA2 */
+		if (PAGE_SIZE != SZ_64K)
+			return false;
 		feat_mask |= ARM_SMMU_FEAT_VAX;
+	}
 
 	if ((smmu->features & feat_mask) != feat_mask)
 		return false;
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Thu Dec  5 05:48:10 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu,  5 Dec 2024 13:48:10 +0000
Subject: [PATCH 2/2] arm64: cpufeature: Add GCS to cpucap_is_possible()
In-Reply-To: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
Message-ID: <416c7369fcdce4ebb2a8f12daae234507be27e38.1733406275.git.robin.murphy@arm.com>

Since system_supports_gcs() ends up referring to cpucap_is_possible(),
teach the latter about GCS for consistency with similar features.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 arch/arm64/include/asm/cpucaps.h    | 2 ++
 arch/arm64/include/asm/cpufeature.h | 3 +--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 201a46efd918..cbbf70e0f204 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -44,6 +44,8 @@ cpucap_is_possible(const unsigned int cap)
 		return IS_ENABLED(CONFIG_ARM64_TLB_RANGE);
 	case ARM64_HAS_S1POE:
 		return IS_ENABLED(CONFIG_ARM64_POE);
+	case ARM64_HAS_GCS:
+		return IS_ENABLED(CONFIG_ARM64_GCS);
 	case ARM64_UNMAP_KERNEL_AT_EL0:
 		return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0);
 	case ARM64_WORKAROUND_843419:
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index b64e49bd9d10..8b4e5a3cd24c 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -847,8 +847,7 @@ static inline bool system_supports_poe(void)
 
 static inline bool system_supports_gcs(void)
 {
-	return IS_ENABLED(CONFIG_ARM64_GCS) &&
-		alternative_has_cap_unlikely(ARM64_HAS_GCS);
+	return alternative_has_cap_unlikely(ARM64_HAS_GCS);
 }
 
 static inline bool system_supports_haft(void)
-- 
2.39.2.101.g768bb238c484.dirty



From daniel.machon at microchip.com  Thu Dec  5 05:54:27 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Thu, 5 Dec 2024 14:54:27 +0100
Subject: [PATCH net 4/5] net: sparx5: fix default value of monitor ports
In-Reply-To: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
References: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
Message-ID: <20241205-sparx5-lan969x-misc-fixes-v1-4-575ff3d0b022@microchip.com>

When doing port mirroring, the physical port to send the frame to, is
written to the FRMC_PORT_VAL field of the QFWD_FRAME_COPY_CFG register.
This field is 7 bits wide on sparx5 and 6 bits wide on lan969x, and has
a default value of 65 and 30, respectively (the number of front ports).

On mirror deletion, we set the default value of the monitor port to
65 for this field, in case no more ports exists for the mirror. Needless
to say, this will not fit the 6 bits on lan969x.

Fix this by correctly using the n_ports constant instead.

Fixes: 3f9e46347a46 ("net: sparx5: use SPX5_CONST for constants which already have a symbol")
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c b/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c
index 9806729e9c62..76097761fa97 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c
@@ -12,7 +12,6 @@
 #define SPX5_MIRROR_DISABLED 0
 #define SPX5_MIRROR_EGRESS 1
 #define SPX5_MIRROR_INGRESS 2
-#define SPX5_MIRROR_MONITOR_PORT_DEFAULT 65
 #define SPX5_QFWD_MP_OFFSET 9 /* Mirror port offset in the QFWD register */
 
 /* Convert from bool ingress/egress to mirror direction */
@@ -200,7 +199,7 @@ void sparx5_mirror_del(struct sparx5_mall_entry *entry)
 
 	sparx5_mirror_monitor_set(sparx5,
 				  mirror_idx,
-				  SPX5_MIRROR_MONITOR_PORT_DEFAULT);
+				  sparx5->data->consts->n_ports);
 }
 
 void sparx5_mirror_stats(struct sparx5_mall_entry *entry,

-- 
2.34.1



From daniel.machon at microchip.com  Thu Dec  5 05:54:23 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Thu, 5 Dec 2024 14:54:23 +0100
Subject: [PATCH net 0/5] net: sparx5: misc fixes for sparx5 and lan969x
Message-ID: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>

This series fixes various issues in the Sparx5 and lan969x drivers. Most
of the fixes are for new issues introduced by the recent series adding
lan969x switch support in the Sparx5 driver.

Most notable is patch 1/5 that moves the lan969x dir into the sparx5
dir, in order to address a cyclic dependency issue reported by depmod,
when installing modules. Details are in the commit descriptions.

To: Andrew Lunn <andrew+netdev at lunn.ch>
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>
To: Lars Povlsen <lars.povlsen at microchip.com>
To: Steen Hegelund <Steen.Hegelund at microchip.com>
To: UNGLinuxDriver at microchip.com
To: Richard Cochran <richardcochran at gmail.com>
To: Bjarni Jonasson <bjarni.jonasson at microchip.com>
To: jensemil.schulzostergaard at microchip.com
To: horatiu.vultur at microchip.com
To: arnd at arndb.de
To: jacob.e.keller at intel.com
To: Parthiban.Veerasooran at microchip.com
Cc: Calvin Owens <calvin at wbinvd.org>
Cc: Muhammad Usama Anjum <Usama.Anjum at collabora.com>
Cc: linux-kernel at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
Daniel Machon (5):
      net: lan969x: fix cyclic dependency reported by depmod
      net: lan969x: fix the use of spin_lock in PTP handler
      net: sparx5: fix FDMA performance issue
      net: sparx5: fix default value of monitor ports
      net: sparx5: fix the maximum frame length register

 MAINTAINERS                                               |  2 +-
 drivers/net/ethernet/microchip/Kconfig                    |  1 -
 drivers/net/ethernet/microchip/Makefile                   |  1 -
 drivers/net/ethernet/microchip/lan969x/Kconfig            |  5 -----
 drivers/net/ethernet/microchip/lan969x/Makefile           | 13 -------------
 drivers/net/ethernet/microchip/sparx5/Kconfig             |  6 ++++++
 drivers/net/ethernet/microchip/sparx5/Makefile            |  6 ++++++
 .../net/ethernet/microchip/{ => sparx5}/lan969x/lan969x.c |  9 ++-------
 .../net/ethernet/microchip/{ => sparx5}/lan969x/lan969x.h |  0
 .../microchip/{ => sparx5}/lan969x/lan969x_calendar.c     |  0
 .../microchip/{ => sparx5}/lan969x/lan969x_regs.c         |  0
 .../microchip/{ => sparx5}/lan969x/lan969x_vcap_ag_api.c  |  0
 .../microchip/{ => sparx5}/lan969x/lan969x_vcap_impl.c    |  0
 drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c   |  2 --
 drivers/net/ethernet/microchip/sparx5/sparx5_main.c       | 15 +++++++--------
 drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c     |  3 +--
 drivers/net/ethernet/microchip/sparx5/sparx5_port.c       |  2 +-
 drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c        |  1 -
 18 files changed, 24 insertions(+), 42 deletions(-)
---
base-commit: da4fa00abe5674d3d165cfd8032c740e8aab4d3b
change-id: 20241203-sparx5-lan969x-misc-fixes-869bff8b55a1

Best regards,
-- 
Daniel Machon <daniel.machon at microchip.com>



From daniel.machon at microchip.com  Thu Dec  5 05:54:24 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Thu, 5 Dec 2024 14:54:24 +0100
Subject: [PATCH net 1/5] net: lan969x: fix cyclic dependency reported by
 depmod
In-Reply-To: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
References: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
Message-ID: <20241205-sparx5-lan969x-misc-fixes-v1-1-575ff3d0b022@microchip.com>

Depmod reports a cyclic dependency between modules sparx5-switch.ko and
lan969x-switch.ko:

depmod: ERROR: Cycle detected: lan969x_switch -> sparx5_switch -> lan969x_switch
depmod: ERROR: Found 2 modules in dependency cycles!
make[2]: *** [scripts/Makefile.modinst:132: depmod] Error 1
make: *** [Makefile:224: __sub-make] Error 2

This makes sense, as they both require symbols from each other.

Fix this by compiling lan969x support into the sparx5-switch.ko module.
In order to do this, in a sensible way, we move the lan969x/ dir into
the sparx5/ dir and do some code cleanup of code that is no longer
required.

After this patch, depmod will no longer complain, as lan969x support is
compiled into the sparx5-swicth.ko module, and can no longer be compiled
as a standalone module.

Fixes: 98a01119608d ("net: sparx5: add compatible string for lan969x")
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 MAINTAINERS                                                 |  2 +-
 drivers/net/ethernet/microchip/Kconfig                      |  1 -
 drivers/net/ethernet/microchip/Makefile                     |  1 -
 drivers/net/ethernet/microchip/lan969x/Kconfig              |  5 -----
 drivers/net/ethernet/microchip/lan969x/Makefile             | 13 -------------
 drivers/net/ethernet/microchip/sparx5/Kconfig               |  6 ++++++
 drivers/net/ethernet/microchip/sparx5/Makefile              |  6 ++++++
 .../net/ethernet/microchip/{ => sparx5}/lan969x/lan969x.c   |  5 -----
 .../net/ethernet/microchip/{ => sparx5}/lan969x/lan969x.h   |  0
 .../microchip/{ => sparx5}/lan969x/lan969x_calendar.c       |  0
 .../ethernet/microchip/{ => sparx5}/lan969x/lan969x_regs.c  |  0
 .../microchip/{ => sparx5}/lan969x/lan969x_vcap_ag_api.c    |  0
 .../microchip/{ => sparx5}/lan969x/lan969x_vcap_impl.c      |  0
 drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c     |  2 --
 drivers/net/ethernet/microchip/sparx5/sparx5_main.c         |  4 ++--
 drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c          |  1 -
 16 files changed, 15 insertions(+), 31 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0456a33ef657..991a3c8f2e77 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15270,7 +15270,7 @@ M:	Daniel Machon <daniel.machon at microchip.com>
 M:	UNGLinuxDriver at microchip.com
 L:	netdev at vger.kernel.org
 S:	Maintained
-F:	drivers/net/ethernet/microchip/lan969x/*
+F:	drivers/net/ethernet/microchip/sparx5/lan969x/*
 
 MICROCHIP LCDFB DRIVER
 M:	Nicolas Ferre <nicolas.ferre at microchip.com>
diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/microchip/Kconfig
index 73832fb2bc32..ee046468652c 100644
--- a/drivers/net/ethernet/microchip/Kconfig
+++ b/drivers/net/ethernet/microchip/Kconfig
@@ -59,7 +59,6 @@ config LAN743X
 
 source "drivers/net/ethernet/microchip/lan865x/Kconfig"
 source "drivers/net/ethernet/microchip/lan966x/Kconfig"
-source "drivers/net/ethernet/microchip/lan969x/Kconfig"
 source "drivers/net/ethernet/microchip/sparx5/Kconfig"
 source "drivers/net/ethernet/microchip/vcap/Kconfig"
 source "drivers/net/ethernet/microchip/fdma/Kconfig"
diff --git a/drivers/net/ethernet/microchip/Makefile b/drivers/net/ethernet/microchip/Makefile
index 7770df82200f..3c65baed9fd8 100644
--- a/drivers/net/ethernet/microchip/Makefile
+++ b/drivers/net/ethernet/microchip/Makefile
@@ -11,7 +11,6 @@ lan743x-objs := lan743x_main.o lan743x_ethtool.o lan743x_ptp.o
 
 obj-$(CONFIG_LAN865X) += lan865x/
 obj-$(CONFIG_LAN966X_SWITCH) += lan966x/
-obj-$(CONFIG_LAN969X_SWITCH) += lan969x/
 obj-$(CONFIG_SPARX5_SWITCH) += sparx5/
 obj-$(CONFIG_VCAP) += vcap/
 obj-$(CONFIG_FDMA) += fdma/
diff --git a/drivers/net/ethernet/microchip/lan969x/Kconfig b/drivers/net/ethernet/microchip/lan969x/Kconfig
deleted file mode 100644
index c5c6122ae2ec..000000000000
--- a/drivers/net/ethernet/microchip/lan969x/Kconfig
+++ /dev/null
@@ -1,5 +0,0 @@
-config LAN969X_SWITCH
-	bool "Lan969x switch driver"
-	depends on SPARX5_SWITCH
-	help
-	  This driver supports the lan969x family of network switch devices.
diff --git a/drivers/net/ethernet/microchip/lan969x/Makefile b/drivers/net/ethernet/microchip/lan969x/Makefile
deleted file mode 100644
index 316405cbbc71..000000000000
--- a/drivers/net/ethernet/microchip/lan969x/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the Microchip lan969x network device drivers.
-#
-
-obj-$(CONFIG_SPARX5_SWITCH) += lan969x-switch.o
-
-lan969x-switch-y := lan969x_regs.o lan969x.o lan969x_calendar.o \
- lan969x_vcap_ag_api.o lan969x_vcap_impl.o
-
-# Provide include files
-ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/fdma
-ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
diff --git a/drivers/net/ethernet/microchip/sparx5/Kconfig b/drivers/net/ethernet/microchip/sparx5/Kconfig
index 3f04992eace6..35b057c9d0cb 100644
--- a/drivers/net/ethernet/microchip/sparx5/Kconfig
+++ b/drivers/net/ethernet/microchip/sparx5/Kconfig
@@ -24,3 +24,9 @@ config SPARX5_DCB
 	  DSCP and PCP.
 
 	  If unsure, set to Y.
+
+config LAN969X_SWITCH
+	bool "Lan969x switch driver"
+	depends on SPARX5_SWITCH
+	help
+	  This driver supports the lan969x family of network switch devices.
diff --git a/drivers/net/ethernet/microchip/sparx5/Makefile b/drivers/net/ethernet/microchip/sparx5/Makefile
index 3435ca86dd70..4bf2a885a9da 100644
--- a/drivers/net/ethernet/microchip/sparx5/Makefile
+++ b/drivers/net/ethernet/microchip/sparx5/Makefile
@@ -16,6 +16,12 @@ sparx5-switch-y  := sparx5_main.o sparx5_packet.o \
 sparx5-switch-$(CONFIG_SPARX5_DCB) += sparx5_dcb.o
 sparx5-switch-$(CONFIG_DEBUG_FS) += sparx5_vcap_debugfs.o
 
+sparx5-switch-$(CONFIG_LAN969X_SWITCH) += lan969x/lan969x_regs.o \
+					  lan969x/lan969x.o \
+					  lan969x/lan969x_calendar.o \
+					  lan969x/lan969x_vcap_ag_api.o \
+					  lan969x/lan969x_vcap_impl.o
+
 # Provide include files
 ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
 ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/fdma
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
similarity index 98%
rename from drivers/net/ethernet/microchip/lan969x/lan969x.c
rename to drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
index ac37d0f74ee3..67463d41d10e 100644
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
@@ -346,8 +346,3 @@ const struct sparx5_match_data lan969x_desc = {
 	.consts     = &lan969x_consts,
 	.ops        = &lan969x_ops,
 };
-EXPORT_SYMBOL_GPL(lan969x_desc);
-
-MODULE_DESCRIPTION("Microchip lan969x switch driver");
-MODULE_AUTHOR("Daniel Machon <daniel.machon at microchip.com>");
-MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x.h b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
similarity index 100%
rename from drivers/net/ethernet/microchip/lan969x/lan969x.h
rename to drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x_calendar.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_calendar.c
similarity index 100%
rename from drivers/net/ethernet/microchip/lan969x/lan969x_calendar.c
rename to drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_calendar.c
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x_regs.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_regs.c
similarity index 100%
rename from drivers/net/ethernet/microchip/lan969x/lan969x_regs.c
rename to drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_regs.c
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x_vcap_ag_api.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_vcap_ag_api.c
similarity index 100%
rename from drivers/net/ethernet/microchip/lan969x/lan969x_vcap_ag_api.c
rename to drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_vcap_ag_api.c
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x_vcap_impl.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_vcap_impl.c
similarity index 100%
rename from drivers/net/ethernet/microchip/lan969x/lan969x_vcap_impl.c
rename to drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_vcap_impl.c
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
index 5fe941c66c17..5c46d81de530 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
@@ -98,7 +98,6 @@ u32 sparx5_cal_speed_to_value(enum sparx5_cal_bw speed)
 	default: return 0;
 	}
 }
-EXPORT_SYMBOL_GPL(sparx5_cal_speed_to_value);
 
 static u32 sparx5_bandwidth_to_calendar(u32 bw)
 {
@@ -150,7 +149,6 @@ enum sparx5_cal_bw sparx5_get_port_cal_speed(struct sparx5 *sparx5, u32 portno)
 		return SPX5_CAL_SPEED_NONE;
 	return sparx5_bandwidth_to_calendar(port->conf.bandwidth);
 }
-EXPORT_SYMBOL_GPL(sparx5_get_port_cal_speed);
 
 /* Auto configure the QSYS calendar based on port configuration */
 int sparx5_config_auto_calendar(struct sparx5 *sparx5)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 2f1013f870fb..2b58fcb9422e 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -24,7 +24,7 @@
 #include <linux/types.h>
 #include <linux/reset.h>
 
-#include "../lan969x/lan969x.h" /* for lan969x match data */
+#include "lan969x/lan969x.h" /* for lan969x match data */
 
 #include "sparx5_main_regs.h"
 #include "sparx5_main.h"
@@ -1093,7 +1093,7 @@ static const struct sparx5_match_data sparx5_desc = {
 
 static const struct of_device_id mchp_sparx5_match[] = {
 	{ .compatible = "microchip,sparx5-switch", .data = &sparx5_desc },
-#if IS_ENABLED(CONFIG_LAN969X_SWITCH)
+#ifdef CONFIG_LAN969X_SWITCH
 	{ .compatible = "microchip,lan9691-switch", .data = &lan969x_desc },
 #endif
 	{ }
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
index 1c2903700a9c..2f168700f63c 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
@@ -303,7 +303,6 @@ void sparx5_get_hwtimestamp(struct sparx5 *sparx5,
 
 	spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags);
 }
-EXPORT_SYMBOL_GPL(sparx5_get_hwtimestamp);
 
 irqreturn_t sparx5_ptp_irq_handler(int irq, void *args)
 {

-- 
2.34.1



From daniel.machon at microchip.com  Thu Dec  5 05:54:28 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Thu, 5 Dec 2024 14:54:28 +0100
Subject: [PATCH net 5/5] net: sparx5: fix the maximum frame length register
In-Reply-To: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
References: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
Message-ID: <20241205-sparx5-lan969x-misc-fixes-v1-5-575ff3d0b022@microchip.com>

On port initialization, we configure the maximum frame length accepted
by the receive module associated with the port. This value is currently
written to the MAX_LEN field of the DEV10G_MAC_ENA_CFG register, when in
fact, it should be written to the DEV10G_MAC_MAXLEN_CFG register. Fix
this.

Fixes: 946e7fd5053a ("net: sparx5: add port module support")
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 1401761c6251..f9d1a6bb9bff 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1151,7 +1151,7 @@ int sparx5_port_init(struct sparx5 *sparx5,
 	spx5_inst_rmw(DEV10G_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
 		      DEV10G_MAC_MAXLEN_CFG_MAX_LEN,
 		      devinst,
-		      DEV10G_MAC_ENA_CFG(0));
+		      DEV10G_MAC_MAXLEN_CFG(0));
 
 	/* Handle Signal Detect in 10G PCS */
 	spx5_inst_wr(PCS10G_BR_PCS_SD_CFG_SD_POL_SET(sd_pol) |

-- 
2.34.1



From daniel.machon at microchip.com  Thu Dec  5 05:54:25 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Thu, 5 Dec 2024 14:54:25 +0100
Subject: [PATCH net 2/5] net: lan969x: fix the use of spin_lock in PTP
 handler
In-Reply-To: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
References: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
Message-ID: <20241205-sparx5-lan969x-misc-fixes-v1-2-575ff3d0b022@microchip.com>

We are mixing the use of spin_lock() and spin_lock_irqsave() functions
in the PTP handler of lan969x. Fix this by correctly using the _irqsave
variants.

Fixes: 24fe83541755 ("net: lan969x: add PTP handler function")
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>

[1]: https://lore.kernel.org/netdev/20241024-sparx5-lan969x-switch-driver-2-v2-10-a0b5fae88a0f at microchip.com/
---
 drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
index 67463d41d10e..c2afa2176b08 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
@@ -273,9 +273,9 @@ static irqreturn_t lan969x_ptp_irq_handler(int irq, void *args)
 		if (WARN_ON(!skb_match))
 			continue;
 
-		spin_lock(&sparx5->ptp_ts_id_lock);
+		spin_lock_irqsave(&sparx5->ptp_ts_id_lock, flags);
 		sparx5->ptp_skbs--;
-		spin_unlock(&sparx5->ptp_ts_id_lock);
+		spin_unlock_irqrestore(&sparx5->ptp_ts_id_lock, flags);
 
 		/* Get the h/w timestamp */
 		sparx5_get_hwtimestamp(sparx5, &ts, delay);

-- 
2.34.1



From daniel.machon at microchip.com  Thu Dec  5 05:54:26 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Thu, 5 Dec 2024 14:54:26 +0100
Subject: [PATCH net 3/5] net: sparx5: fix FDMA performance issue
In-Reply-To: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
References: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
Message-ID: <20241205-sparx5-lan969x-misc-fixes-v1-3-575ff3d0b022@microchip.com>

The FDMA handler is responsible for scheduling a NAPI poll, which will
eventually fetch RX packets from the FDMA queue. Currently, the FDMA
handler is run in a threaded context. For some reason, this kills
performance.  Admittedly, I did not do a thorough investigation to see
exactly what causes the issue, however, I noticed that in the other
driver utilizing the same FDMA engine, we run the FDMA handler in hard
IRQ context.

Fix this performance issue, by  running the FDMA handler in hard IRQ
context, not deferring any work to a thread.

Prior to this change, the RX UDP performance was:

Interval           Transfer     Bitrate         Jitter
0.00-10.20  sec    44.6 MBytes  36.7 Mbits/sec  0.027 ms

After this change, the rx UDP performance is:

Interval           Transfer     Bitrate         Jitter
0.00-9.12   sec    1.01 GBytes  953 Mbits/sec   0.020 ms

Fixes: 10615907e9b5 ("net: sparx5: switchdev: adding frame DMA functionality")
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 2b58fcb9422e..f61aa15beab7 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -780,12 +780,11 @@ static int sparx5_start(struct sparx5 *sparx5)
 	err = -ENXIO;
 	if (sparx5->fdma_irq >= 0 && is_sparx5(sparx5)) {
 		if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0)
-			err = devm_request_threaded_irq(sparx5->dev,
-							sparx5->fdma_irq,
-							NULL,
-							sparx5_fdma_handler,
-							IRQF_ONESHOT,
-							"sparx5-fdma", sparx5);
+			err = devm_request_irq(sparx5->dev,
+					       sparx5->fdma_irq,
+					       sparx5_fdma_handler,
+					       0,
+					       "sparx5-fdma", sparx5);
 		if (!err)
 			err = sparx5_fdma_start(sparx5);
 		if (err)

-- 
2.34.1



From jonathanh at nvidia.com  Thu Dec  5 05:55:24 2024
From: jonathanh at nvidia.com (Jon Hunter)
Date: Thu, 5 Dec 2024 13:55:24 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unaligned DMA unmap for
 non-paged SKB data
In-Reply-To: <20241205091830.3719609-1-0x1207@gmail.com>
References: <20241205091830.3719609-1-0x1207@gmail.com>
Message-ID: <566fb566-4806-41bc-ae6f-7f4ef5762a7b@nvidia.com>


On 05/12/2024 09:18, Furong Xu wrote:
> Commit 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap for
> non-paged SKB data") assigns a wrong DMA buffer address that is added an
> offset of proto_hdr_len to tx_q->tx_skbuff_dma[entry].buf on a certain
> platform that the DMA AXI address width is configured to 40-bit/48-bit,

In our case it is 40/40 ...

  dwc-eth-dwmac 2490000.ethernet: Using 40/40 bits DMA host/device width

> stmmac_tx_clean() will try to unmap this illegal DMA buffer address
> and many crashes are reported: [1] [2].
> 
> This patch guarantees that DMA address is passed to stmmac_tx_clean()
> unmodified and without offset.
> 
> [1] https://lore.kernel.org/all/d8112193-0386-4e14-b516-37c2d838171a at nvidia.com/
> [2] https://lore.kernel.org/all/klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc at bwwhelz2l4dw/
> 
> Reported-by: Jon Hunter <jonathanh at nvidia.com>
> Reported-by: Thierry Reding <thierry.reding at gmail.com>
> Suggested-by: Russell King (Oracle) <linux at armlinux.org.uk>
> Fixes: 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data")
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
>   drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 9b262cdad60b..7227f8428b5e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4192,8 +4192,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>   	struct stmmac_txq_stats *txq_stats;
>   	struct stmmac_tx_queue *tx_q;
>   	u32 pay_len, mss, queue;
> +	dma_addr_t tso_hdr, des;
>   	u8 proto_hdr_len, hdr;
> -	dma_addr_t des;
>   	bool set_ic;
>   	int i;
>   
> @@ -4279,6 +4279,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>   			     DMA_TO_DEVICE);
>   	if (dma_mapping_error(priv->device, des))
>   		goto dma_map_err;
> +	tso_hdr = des;
>   
>   	if (priv->dma_cap.addr64 <= 32) {
>   		first->des0 = cpu_to_le32(des);
> @@ -4310,7 +4311,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>   	 * this DMA buffer right after the DMA engine completely finishes the
>   	 * full buffer transmission.
>   	 */
> -	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
> +	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = tso_hdr;
>   	tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
>   	tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
>   	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;

Otherwise ...

Tested-by: Jon Hunter <jonathanh at nvidia.com>

Jon

-- 
nvpublic



From a.fatoum at pengutronix.de  Thu Dec  5 05:57:59 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 5 Dec 2024 14:57:59 +0100
Subject: [PATCH v1] arm: dts: st: stm32mp151a-prtt1l: Fix QSPI
 configuration
In-Reply-To: <a483fb50-f978-4e48-b38e-6d79632540f1@foss.st.com>
References: <20240806120517.406714-1-o.rempel@pengutronix.de>
 <20dc2cd4-7684-4894-9db3-23c3f4abd661@pengutronix.de>
 <a483fb50-f978-4e48-b38e-6d79632540f1@foss.st.com>
Message-ID: <361b3a14-db86-4c3c-9f07-4ebc1dd40d0e@pengutronix.de>

Hello Alex,

On 29.10.24 16:39, Alexandre TORGUE wrote:
> On 8/7/24 11:38, Ahmad Fatoum wrote:
>> Hello Oleksij,
>>
>> On 06.08.24 14:05, Oleksij Rempel wrote:
>> There's bias-disable in stm32mp15-pinctrl.dtsi. You may want to add
>> a /delete-property/ for that to make sure, it's not up to the driver
>> which one has priority.
>>
>>> ????????? drive-push-pull;
>>> ????????? slew-rate = <1>;
>>
>> These are already in qspi_bk1_pins_a. If repeating those is ok, why
>> not go a step further and just duplicate the pinmux property and stay
>> clear of this issue altogether, provided Alex is amenable to changing
>> his mind regarding pinctrl groups in board device trees.
> 
> I still prefer to have pin configuration defined in pinctrl dtsi file and I'll continue like this for ST board. The reason is that we try to reuse as much as possible pins when we create a new board and so it is easier to maintain if we declare them only one time.

I can see the point for ST evaluation kits as ST customer hardware
will often copy the reference designs.

> But, I'm not blocked for "other" boards based on STM32 SoC. I mean, if it is simpler for you and above all if it avoid issues/complexities then, you can declare some pin groups in your board dts file. In this case we need to take care of the IO groups label name.

That's good to hear and what I wanted to clarify. Especially for things like
ADCs, there are so many possible permutations that there is no point for
boards to add their pinctrl group to the main DTSI instead of just listing
their specific pin configuration in the board DTS.

Thanks,
Ahmad

> 
> regards
> alex
> 
>>
>>
>> Cheers,
>> Ahmad
>>
> 


-- 
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 mark.rutland at arm.com  Thu Dec  5 06:23:35 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 5 Dec 2024 14:23:35 +0000
Subject: [PATCH 2/2] arm64: cpufeature: Add GCS to cpucap_is_possible()
In-Reply-To: <416c7369fcdce4ebb2a8f12daae234507be27e38.1733406275.git.robin.murphy@arm.com>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
 <416c7369fcdce4ebb2a8f12daae234507be27e38.1733406275.git.robin.murphy@arm.com>
Message-ID: <Z1G3Z9C9efBkVKjR@J2N7QTR9R3>

On Thu, Dec 05, 2024 at 01:48:10PM +0000, Robin Murphy wrote:
> Since system_supports_gcs() ends up referring to cpucap_is_possible(),
> teach the latter about GCS for consistency with similar features.
> 
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Looking around, we should probably do the same for HAFT.

Mark.

> ---
>  arch/arm64/include/asm/cpucaps.h    | 2 ++
>  arch/arm64/include/asm/cpufeature.h | 3 +--
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
> index 201a46efd918..cbbf70e0f204 100644
> --- a/arch/arm64/include/asm/cpucaps.h
> +++ b/arch/arm64/include/asm/cpucaps.h
> @@ -44,6 +44,8 @@ cpucap_is_possible(const unsigned int cap)
>  		return IS_ENABLED(CONFIG_ARM64_TLB_RANGE);
>  	case ARM64_HAS_S1POE:
>  		return IS_ENABLED(CONFIG_ARM64_POE);
> +	case ARM64_HAS_GCS:
> +		return IS_ENABLED(CONFIG_ARM64_GCS);
>  	case ARM64_UNMAP_KERNEL_AT_EL0:
>  		return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0);
>  	case ARM64_WORKAROUND_843419:
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index b64e49bd9d10..8b4e5a3cd24c 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -847,8 +847,7 @@ static inline bool system_supports_poe(void)
>  
>  static inline bool system_supports_gcs(void)
>  {
> -	return IS_ENABLED(CONFIG_ARM64_GCS) &&
> -		alternative_has_cap_unlikely(ARM64_HAS_GCS);
> +	return alternative_has_cap_unlikely(ARM64_HAS_GCS);
>  }
>  
>  static inline bool system_supports_haft(void)
> -- 
> 2.39.2.101.g768bb238c484.dirty
> 


From lkp at intel.com  Thu Dec  5 06:22:50 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 5 Dec 2024 22:22:50 +0800
Subject: [PATCH v1 01/13] KVM: Add KVM_MEM_USERFAULT memslot flag and
 bitmap
In-Reply-To: <20241204191349.1730936-2-jthoughton@google.com>
References: <20241204191349.1730936-2-jthoughton@google.com>
Message-ID: <202412052133.pTg3UAQm-lkp@intel.com>

Hi James,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 4d911c7abee56771b0219a9fbf0120d06bdc9c14]

url:    https://github.com/intel-lab-lkp/linux/commits/James-Houghton/KVM-Add-KVM_MEM_USERFAULT-memslot-flag-and-bitmap/20241205-032516
base:   4d911c7abee56771b0219a9fbf0120d06bdc9c14
patch link:    https://lore.kernel.org/r/20241204191349.1730936-2-jthoughton%40google.com
patch subject: [PATCH v1 01/13] KVM: Add KVM_MEM_USERFAULT memslot flag and bitmap
config: i386-buildonly-randconfig-006 (https://download.01.org/0day-ci/archive/20241205/202412052133.pTg3UAQm-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/20241205/202412052133.pTg3UAQm-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/202412052133.pTg3UAQm-lkp at intel.com/

All warnings (new ones prefixed by >>):

   arch/x86/kvm/../../../virt/kvm/kvm_main.c: In function '__kvm_set_memory_region':
>> arch/x86/kvm/../../../virt/kvm/kvm_main.c:2049:41: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
    2049 |                 new->userfault_bitmap = (unsigned long *)mem->userfault_bitmap;
         |                                         ^


vim +2049 arch/x86/kvm/../../../virt/kvm/kvm_main.c

  1931	
  1932	/*
  1933	 * Allocate some memory and give it an address in the guest physical address
  1934	 * space.
  1935	 *
  1936	 * Discontiguous memory is allowed, mostly for framebuffers.
  1937	 *
  1938	 * Must be called holding kvm->slots_lock for write.
  1939	 */
  1940	int __kvm_set_memory_region(struct kvm *kvm,
  1941				    const struct kvm_userspace_memory_region2 *mem)
  1942	{
  1943		struct kvm_memory_slot *old, *new;
  1944		struct kvm_memslots *slots;
  1945		enum kvm_mr_change change;
  1946		unsigned long npages;
  1947		gfn_t base_gfn;
  1948		int as_id, id;
  1949		int r;
  1950	
  1951		r = check_memory_region_flags(kvm, mem);
  1952		if (r)
  1953			return r;
  1954	
  1955		as_id = mem->slot >> 16;
  1956		id = (u16)mem->slot;
  1957	
  1958		/* General sanity checks */
  1959		if ((mem->memory_size & (PAGE_SIZE - 1)) ||
  1960		    (mem->memory_size != (unsigned long)mem->memory_size))
  1961			return -EINVAL;
  1962		if (mem->guest_phys_addr & (PAGE_SIZE - 1))
  1963			return -EINVAL;
  1964		/* We can read the guest memory with __xxx_user() later on. */
  1965		if ((mem->userspace_addr & (PAGE_SIZE - 1)) ||
  1966		    (mem->userspace_addr != untagged_addr(mem->userspace_addr)) ||
  1967		     !access_ok((void __user *)(unsigned long)mem->userspace_addr,
  1968				mem->memory_size))
  1969			return -EINVAL;
  1970		if (mem->flags & KVM_MEM_GUEST_MEMFD &&
  1971		    (mem->guest_memfd_offset & (PAGE_SIZE - 1) ||
  1972		     mem->guest_memfd_offset + mem->memory_size < mem->guest_memfd_offset))
  1973			return -EINVAL;
  1974		if (as_id >= kvm_arch_nr_memslot_as_ids(kvm) || id >= KVM_MEM_SLOTS_NUM)
  1975			return -EINVAL;
  1976		if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr)
  1977			return -EINVAL;
  1978		if ((mem->memory_size >> PAGE_SHIFT) > KVM_MEM_MAX_NR_PAGES)
  1979			return -EINVAL;
  1980	
  1981		slots = __kvm_memslots(kvm, as_id);
  1982	
  1983		/*
  1984		 * Note, the old memslot (and the pointer itself!) may be invalidated
  1985		 * and/or destroyed by kvm_set_memslot().
  1986		 */
  1987		old = id_to_memslot(slots, id);
  1988	
  1989		if (!mem->memory_size) {
  1990			if (!old || !old->npages)
  1991				return -EINVAL;
  1992	
  1993			if (WARN_ON_ONCE(kvm->nr_memslot_pages < old->npages))
  1994				return -EIO;
  1995	
  1996			return kvm_set_memslot(kvm, old, NULL, KVM_MR_DELETE);
  1997		}
  1998	
  1999		base_gfn = (mem->guest_phys_addr >> PAGE_SHIFT);
  2000		npages = (mem->memory_size >> PAGE_SHIFT);
  2001	
  2002		if (!old || !old->npages) {
  2003			change = KVM_MR_CREATE;
  2004	
  2005			/*
  2006			 * To simplify KVM internals, the total number of pages across
  2007			 * all memslots must fit in an unsigned long.
  2008			 */
  2009			if ((kvm->nr_memslot_pages + npages) < kvm->nr_memslot_pages)
  2010				return -EINVAL;
  2011		} else { /* Modify an existing slot. */
  2012			/* Private memslots are immutable, they can only be deleted. */
  2013			if (mem->flags & KVM_MEM_GUEST_MEMFD)
  2014				return -EINVAL;
  2015			if ((mem->userspace_addr != old->userspace_addr) ||
  2016			    (npages != old->npages) ||
  2017			    ((mem->flags ^ old->flags) & KVM_MEM_READONLY))
  2018				return -EINVAL;
  2019	
  2020			if (base_gfn != old->base_gfn)
  2021				change = KVM_MR_MOVE;
  2022			else if (mem->flags != old->flags)
  2023				change = KVM_MR_FLAGS_ONLY;
  2024			else /* Nothing to change. */
  2025				return 0;
  2026		}
  2027	
  2028		if ((change == KVM_MR_CREATE || change == KVM_MR_MOVE) &&
  2029		    kvm_check_memslot_overlap(slots, id, base_gfn, base_gfn + npages))
  2030			return -EEXIST;
  2031	
  2032		/* Allocate a slot that will persist in the memslot. */
  2033		new = kzalloc(sizeof(*new), GFP_KERNEL_ACCOUNT);
  2034		if (!new)
  2035			return -ENOMEM;
  2036	
  2037		new->as_id = as_id;
  2038		new->id = id;
  2039		new->base_gfn = base_gfn;
  2040		new->npages = npages;
  2041		new->flags = mem->flags;
  2042		new->userspace_addr = mem->userspace_addr;
  2043		if (mem->flags & KVM_MEM_GUEST_MEMFD) {
  2044			r = kvm_gmem_bind(kvm, new, mem->guest_memfd, mem->guest_memfd_offset);
  2045			if (r)
  2046				goto out;
  2047		}
  2048		if (mem->flags & KVM_MEM_USERFAULT)
> 2049			new->userfault_bitmap = (unsigned long *)mem->userfault_bitmap;
  2050	
  2051		r = kvm_set_memslot(kvm, old, new, change);
  2052		if (r)
  2053			goto out_unbind;
  2054	
  2055		return 0;
  2056	
  2057	out_unbind:
  2058		if (mem->flags & KVM_MEM_GUEST_MEMFD)
  2059			kvm_gmem_unbind(new);
  2060	out:
  2061		kfree(new);
  2062		return r;
  2063	}
  2064	EXPORT_SYMBOL_GPL(__kvm_set_memory_region);
  2065	

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


From wens at csie.org  Thu Dec  5 06:25:38 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Thu, 05 Dec 2024 22:25:38 +0800
Subject: [PATCH v6 0/3] Add support for codec of F1C100s
In-Reply-To: <20241123123900.2656837-1-csokas.bence@prolan.hu>
References: <20241123123900.2656837-1-csokas.bence@prolan.hu>
Message-ID: <173340873895.1777403.9265230616081178067.b4-ty@csie.org>

On Sat, 23 Nov 2024 13:38:55 +0100, Cs?k?s, Bence wrote:
> Support for Allwinner F1C100s/200s series audio was
> submitted in 2018 as an RFC series, but was not merged,
> despite having only minor errors. However, this is
> essential for having audio on these SoCs.
> This series was forward-ported/rebased to the best of
> my abilities, on top of Linus' tree as of now:
> commit 28eb75e178d3 ("Merge tag 'drm-next-2024-11-21' of https://gitlab.freedesktop.org/drm/kernel")
> 
> [...]

Applied to dt-for-6.14 in git at github.com:linux-sunxi/linux-sunxi.git, thanks!

[1/5] ASoC: sun4i-codec: Add DMA Max Burst field
      (no commit info)
[2/5] dt-bindings: sound: Add Allwinner suniv F1C100s Audio Codec
      (no commit info)
[3/5] ASoC: sun4i-codec: Add support for Allwinner suniv F1C100s
      (no commit info)
[4/5] ARM: dts: suniv: f1c100s: Add support for Audio Codec
      commit: 95b570f7ded1e921eb3fd256d0a70b294f31bd0c
[5/5] ARM: dts: suniv: f1c100s: Activate Audio Codec for Lichee Pi Nano
      commit: 20296f8baa25839585b9060079946f7333a5c5aa

Best regards,
-- 
Chen-Yu Tsai <wens at csie.org>



From wens at csie.org  Thu Dec  5 06:25:38 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Thu, 05 Dec 2024 22:25:38 +0800
Subject: [PATCH v5 0/5] Add support for DMA of F1C100s
In-Reply-To: <20241122161128.2619172-1-csokas.bence@prolan.hu>
References: <20241122161128.2619172-1-csokas.bence@prolan.hu>
Message-ID: <173340873878.1777403.11710031355609971039.b4-ty@csie.org>

On Fri, 22 Nov 2024 17:11:23 +0100, Cs?k?s, Bence wrote:
> Support for Allwinner F1C100s/200s series audio was
> submitted in 2018 as an RFC series, but was not merged,
> despite having only minor errors. However, this is
> essential for having audio on these SoCs.
> This series was forward-ported/rebased to the best of
> my abilities, on top of Linus' tree as of now:
> commit 28eb75e178d3 ("Merge tag 'drm-next-2024-11-21' of https://gitlab.freedesktop.org/drm/kernel")
> 
> [...]

Applied to dt-for-6.14 in git at github.com:linux-sunxi/linux-sunxi.git, thanks!

[1/5] dma-engine: sun4i: Add a quirk to support different chips
      (no commit info)
[2/5] dma-engine: sun4i: Add has_reset option to quirk
      (no commit info)
[3/5] dt-bindings: dmaengine: Add Allwinner suniv F1C100s DMA
      (no commit info)
[4/5] dma-engine: sun4i: Add support for Allwinner suniv F1C100s
      (no commit info)
[5/5] ARM: dts: suniv: f1c100s: Add support for DMA
      commit: 7336701f6467381af87a462008793178925a03bf

Best regards,
-- 
Chen-Yu Tsai <wens at csie.org>



From sudeep.holla at arm.com  Thu Dec  5 06:27:24 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 5 Dec 2024 14:27:24 +0000
Subject: [PATCH] arm64: dts: fvp: Update bus-range property
In-Reply-To: <Z1GxQHY1XkQcPFc0@e110455-lin.cambridge.arm.com>
References: <20241128152543.1821878-1-aneesh.kumar@kernel.org>
 <173339457335.691023.1334271427632194234.b4-ty@arm.com>
 <Z1GxQHY1XkQcPFc0@e110455-lin.cambridge.arm.com>
Message-ID: <Z1G4TCY9ekezAc8Y@bogus>

On Thu, Dec 05, 2024 at 01:57:20PM +0000, Liviu Dudau wrote:
> On Thu, Dec 05, 2024 at 10:31:03AM +0000, Sudeep Holla wrote:
> > On Thu, 28 Nov 2024 20:55:43 +0530, Aneesh Kumar K.V (Arm) wrote:
> > > These days, the Fixed Virtual Platforms(FVP) Base RevC model supports
> > > more PCI devices. Update the max bus number so that Linux can enumerate
> > > them correctly. Without this, the kernel throws the below error while
> > > booting with the default hierarchy
> > >
> > > pci_bus 0000:01: busn_res: [bus 01] end is updated to 01
> > > pci_bus 0000:02: busn_res: can not insert [bus 02-01] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > > pci_bus 0000:02: busn_res: [bus 02-01] end is updated to 02
> > > pci_bus 0000:02: busn_res: can not insert [bus 02] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > > pci_bus 0000:03: busn_res: can not insert [bus 03-01] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > > pci_bus 0000:03: busn_res: [bus 03-01] end is updated to 03
> > > pci_bus 0000:03: busn_res: can not insert [bus 03] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > > pci_bus 0000:04: busn_res: can not insert [bus 04-01] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > > pci_bus 0000:04: busn_res: [bus 04-01] end is updated to 04
> > > pci_bus 0000:04: busn_res: can not insert [bus 04] under [bus 00-01] (conflicts with (null) [bus 00-01])
> > > pci 0000:00:01.0: BAR 14: assigned [mem 0x50000000-0x500fffff]
> > >
> > > [...]
> > 
> > Applied to sudeep.holla/linux (for-next/juno/fixes), thanks!
> > 
> > [1/1] arm64: dts: fvp: Update bus-range property
> >       https://git.kernel.org/sudeep.holla/c/4f776d81bf92
> 
> Thanks for the quick response. TBH, I did not receive your initial review
> email, that's why I've messaged thinking it got lost.

No I hadn't responded on the list yet. I queue and wait for a day for the
kbuild bot or any other bots to report no failures before I officially respond
as applied as I wouldn't have tried all build configs in general but it
doesn't apply for DT files though ?.

--
Regards,
Sudeep


From james.cowgill at blaize.com  Thu Dec  5 06:35:07 2024
From: james.cowgill at blaize.com (James Cowgill)
Date: Thu, 5 Dec 2024 14:35:07 +0000
Subject: [PATCH v5 6/6] MAINTAINER: Add entry for Blaize SoC
In-Reply-To: <h5awakp52e6pxnnfrclhtlhhs3i66twvmqwlf5vmnfwk2xhbwr@marp6wti72ti>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
 <20241204-blaize-blzp1600_init_board_support-v5-6-b642bcc49307@blaize.com>
 <h5awakp52e6pxnnfrclhtlhhs3i66twvmqwlf5vmnfwk2xhbwr@marp6wti72ti>
Message-ID: <3229b92c-0e0c-4661-8524-3f0f6e1ad87f@blaize.com>

On 05/12/2024 08:16, Krzysztof Kozlowski wrote:
> On Wed, Dec 04, 2024 at 04:05:29PM +0000, Nikolaos Pasaloukos wrote:
>> Add MAINTAINERS entry for Blaize SoC platform with a list of
>> maintainers.
>>
>> Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
>> ---
>>  MAINTAINERS | 9 +++++++++
>>  1 file changed, 9 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 273a84483b74543b510de7b08804bbd1f6514358..43846a23f9d990ae9fe066e65ed2bdd36376e327 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -2238,6 +2238,15 @@ F:	arch/arm64/boot/dts/bitmain/
>>  F:	drivers/clk/clk-bm1880.c
>>  F:	drivers/pinctrl/pinctrl-bm1880.c
>>  
>> +ARM/BLAIZE ARCHITECTURE
>> +M:	James Cowgill <james.cowgill at blaize.com>
>> +M:	Matt Redfearn <matt.redfearn at blaize.com>
>> +M:	Neil Jones <neil.jones at blaize.com>
>> +M:	Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
> 
> Just to be clear: this is list of active maintainers, so all above are
> supposed to perform reviews or maintainer duties. This is not
> credits/managers/I-need-to-please-someone list.
> 
> With the assumption these are active maintainers:
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> They should also ack it to confirm they understand the burden.

Acked-by: James Cowgill <james.cowgill at blaize.com>

James


From suzuki.poulose at arm.com  Thu Dec  5 06:36:34 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu,  5 Dec 2024 14:36:34 +0000
Subject: [PATCH] coco: virt: arm64: Do not enable cca guest driver by default
Message-ID: <20241205143634.306114-1-suzuki.poulose@arm.com>

As per the guidelines, new drivers may not be set to default on.
An expert user can always select it.

Reported-by: Dan Williams <dan.j.williams at intel.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Steven Price <steven.price at arm.com>
Cc: Sami Mujawar <sami.mujawar at arm.com>
Link: https://lkml.kernel.org/r/6750c695194cd_2508129427 at dwillia2-xfh.jf.intel.com.notmuch
Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
---
 drivers/virt/coco/arm-cca-guest/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/arm-cca-guest/Kconfig
index 9dd27c3ee215..3f0f013f03f1 100644
--- a/drivers/virt/coco/arm-cca-guest/Kconfig
+++ b/drivers/virt/coco/arm-cca-guest/Kconfig
@@ -1,7 +1,6 @@
 config ARM_CCA_GUEST
 	tristate "Arm CCA Guest driver"
 	depends on ARM64
-	default m
 	select TSM_REPORTS
 	help
 	  The driver provides userspace interface to request and
-- 
2.34.1



From steven.price at arm.com  Thu Dec  5 06:39:19 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 5 Dec 2024 14:39:19 +0000
Subject: [PATCH] coco: virt: arm64: Do not enable cca guest driver by
 default
In-Reply-To: <20241205143634.306114-1-suzuki.poulose@arm.com>
References: <20241205143634.306114-1-suzuki.poulose@arm.com>
Message-ID: <7dc06874-faba-45c8-b200-929d508bf39e@arm.com>

On 05/12/2024 14:36, Suzuki K Poulose wrote:
> As per the guidelines, new drivers may not be set to default on.
> An expert user can always select it.
> 
> Reported-by: Dan Williams <dan.j.williams at intel.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Steven Price <steven.price at arm.com>
> Cc: Sami Mujawar <sami.mujawar at arm.com>
> Link: https://lkml.kernel.org/r/6750c695194cd_2508129427 at dwillia2-xfh.jf.intel.com.notmuch
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>

Sorry about that oversight on my part.

Reviewed-by: Steven Price <steven.price at arm.com>

> ---
>  drivers/virt/coco/arm-cca-guest/Kconfig | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/arm-cca-guest/Kconfig
> index 9dd27c3ee215..3f0f013f03f1 100644
> --- a/drivers/virt/coco/arm-cca-guest/Kconfig
> +++ b/drivers/virt/coco/arm-cca-guest/Kconfig
> @@ -1,7 +1,6 @@
>  config ARM_CCA_GUEST
>  	tristate "Arm CCA Guest driver"
>  	depends on ARM64
> -	default m
>  	select TSM_REPORTS
>  	help
>  	  The driver provides userspace interface to request and



From neil.jones at blaize.com  Thu Dec  5 06:39:42 2024
From: neil.jones at blaize.com (Neil Jones)
Date: Thu, 5 Dec 2024 14:39:42 +0000
Subject: [PATCH v5 6/6] MAINTAINER: Add entry for Blaize SoC
In-Reply-To: <h5awakp52e6pxnnfrclhtlhhs3i66twvmqwlf5vmnfwk2xhbwr@marp6wti72ti>
References: <20241204-blaize-blzp1600_init_board_support-v5-0-b642bcc49307@blaize.com>
 <20241204-blaize-blzp1600_init_board_support-v5-6-b642bcc49307@blaize.com>
 <h5awakp52e6pxnnfrclhtlhhs3i66twvmqwlf5vmnfwk2xhbwr@marp6wti72ti>
Message-ID: <5ea81796-b871-4a4b-8984-6095d3e06d4c@blaize.com>

On 05/12/2024 08:16, Krzysztof Kozlowski wrote:

> On Wed, Dec 04, 2024 at 04:05:29PM +0000, Nikolaos Pasaloukos wrote:
>> Add MAINTAINERS entry for Blaize SoC platform with a list of
>> maintainers.
>>
>> Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
>> ---
>>   MAINTAINERS | 9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 273a84483b74543b510de7b08804bbd1f6514358..43846a23f9d990ae9fe066e65ed2bdd36376e327 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -2238,6 +2238,15 @@ F:	arch/arm64/boot/dts/bitmain/
>>   F:	drivers/clk/clk-bm1880.c
>>   F:	drivers/pinctrl/pinctrl-bm1880.c
>>   
>> +ARM/BLAIZE ARCHITECTURE
>> +M:	James Cowgill <james.cowgill at blaize.com>
>> +M:	Matt Redfearn <matt.redfearn at blaize.com>
>> +M:	Neil Jones <neil.jones at blaize.com>
>> +M:	Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
> Just to be clear: this is list of active maintainers, so all above are
> supposed to perform reviews or maintainer duties. This is not
> credits/managers/I-need-to-please-someone list.
>
> With the assumption these are active maintainers:
>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>
> They should also ack it to confirm they understand the burden.
>
> Best regards,
> Krzysztof
>
Acked-by: Neil Jones <neil.jones at blaize.com>

Cheers,

Neil

On 05/12/2024 08:16, Krzysztof Kozlowski wrote:
> On Wed, Dec 04, 2024 at 04:05:29PM +0000, Nikolaos Pasaloukos wrote:
>> Add MAINTAINERS entry for Blaize SoC platform with a list of
>> maintainers.
>>
>> Signed-off-by: Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
>> ---
>>   MAINTAINERS | 9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 273a84483b74543b510de7b08804bbd1f6514358..43846a23f9d990ae9fe066e65ed2bdd36376e327 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -2238,6 +2238,15 @@ F:	arch/arm64/boot/dts/bitmain/
>>   F:	drivers/clk/clk-bm1880.c
>>   F:	drivers/pinctrl/pinctrl-bm1880.c
>>   
>> +ARM/BLAIZE ARCHITECTURE
>> +M:	James Cowgill <james.cowgill at blaize.com>
>> +M:	Matt Redfearn <matt.redfearn at blaize.com>
>> +M:	Neil Jones <neil.jones at blaize.com>
>> +M:	Nikolaos Pasaloukos <nikolaos.pasaloukos at blaize.com>
> Just to be clear: this is list of active maintainers, so all above are
> supposed to perform reviews or maintainer duties. This is not
> credits/managers/I-need-to-please-someone list.
>
> With the assumption these are active maintainers:
>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>
> They should also ack it to confirm they understand the burden.
>
> Best regards,
> Krzysztof
>


From naresh.kamboju at linaro.org  Thu Dec  5 06:45:13 2024
From: naresh.kamboju at linaro.org (Naresh Kamboju)
Date: Thu, 5 Dec 2024 20:15:13 +0530
Subject: arm64: include/linux/compiler_types.h:542:38: error: call to
 '__compiletime_assert_1050' declared with attribute error: clamp() low limit
 min greater than high limit max_avail
Message-ID: <CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g@mail.gmail.com>

The arm64 build started failing from Linux next-20241203 tag with gcc-8
due to following build warnings / errors.

First seen on Linux next-20241203 tag
GOOD: Linux next-20241128 tag
BAD: Linux next-20241203 tag and next-20241205 tag

* arm64, build
  - gcc-8-defconfig
  - gcc-8-defconfig-40bc7ee5

Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>

Build log:
===========
net/netfilter/ipvs/ip_vs_conn.c: In function 'ip_vs_conn_init':
include/linux/compiler_types.h:542:38: error: call to
'__compiletime_assert_1050' declared with attribute error: clamp() low
limit min greater than high limit max_avail
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                                      ^
include/linux/compiler_types.h:523:4: note: in definition of macro
'__compiletime_assert'
    prefix ## suffix();    \
    ^~~~~~
include/linux/compiler_types.h:542:2: note: in expansion of macro
'_compiletime_assert'
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
  ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro
'compiletime_assert'
 #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
                                     ^~~~~~~~~~~~~~~~~~
include/linux/minmax.h:188:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
  BUILD_BUG_ON_MSG(statically_true(ulo > uhi),    \
  ^~~~~~~~~~~~~~~~
include/linux/minmax.h:195:2: note: in expansion of macro '__clamp_once'
  __clamp_once(type, val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_),
__UNIQUE_ID(h_))
  ^~~~~~~~~~~~
include/linux/minmax.h:206:28: note: in expansion of macro '__careful_clamp'
 #define clamp(val, lo, hi) __careful_clamp(__auto_type, val, lo, hi)
                            ^~~~~~~~~~~~~~~
net/netfilter/ipvs/ip_vs_conn.c:1498:8: note: in expansion of macro 'clamp'
  max = clamp(max, min, max_avail);
        ^~~~~

Links:
---
- https://storage.tuxsuite.com/public/linaro/lkft/builds/2pjAOE9K3Dz9gRywrldKTyaXQoT/
- https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20241203/testrun/26189105/suite/build/test/gcc-8-defconfig/log
- https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20241203/testrun/26189105/suite/build/test/gcc-8-defconfig/details/
- https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20241203/testrun/26189105/suite/build/test/gcc-8-defconfig/history/

Steps to reproduce:
------------
# tuxmake --runtime podman --target-arch arm64 --toolchain gcc-8
--kconfig defconfig

metadata:
----
  git describe: next-20241203
  git repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
  git sha: c245a7a79602ccbee780c004c1e4abcda66aec32
  kernel config:
https://storage.tuxsuite.com/public/linaro/lkft/builds/2pjAOE9K3Dz9gRywrldKTyaXQoT/config
  build url: https://storage.tuxsuite.com/public/linaro/lkft/builds/2pjAOE9K3Dz9gRywrldKTyaXQoT/
  toolchain: gcc-8
  config: gcc-8-defconfig
  arch: arm64

--
Linaro LKFT
https://lkft.linaro.org


From ansuelsmth at gmail.com  Thu Dec  5 06:51:31 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu,  5 Dec 2024 15:51:31 +0100
Subject: [net-next PATCH v9 1/4] net: dsa: add devm_dsa_register_switch()
In-Reply-To: <20241205145142.29278-1-ansuelsmth@gmail.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
Message-ID: <20241205145142.29278-2-ansuelsmth@gmail.com>

Some DSA driver can be simplified if devres takes care of unregistering
the DSA switch. This permits to effectively drop the remove OP from
driver that just execute the dsa_unregister_switch() and nothing else.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 include/net/dsa.h |  1 +
 net/dsa/dsa.c     | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 72ae65e7246a..c703d5dc3fb0 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -1355,6 +1355,7 @@ static inline void dsa_tag_generic_flow_dissect(const struct sk_buff *skb,
 
 void dsa_unregister_switch(struct dsa_switch *ds);
 int dsa_register_switch(struct dsa_switch *ds);
+int devm_dsa_register_switch(struct device *dev, struct dsa_switch *ds);
 void dsa_switch_shutdown(struct dsa_switch *ds);
 struct dsa_switch *dsa_switch_find(int tree_index, int sw_index);
 void dsa_flush_workqueue(void);
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 5a7c0e565a89..aca6aee68248 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -1544,6 +1544,25 @@ int dsa_register_switch(struct dsa_switch *ds)
 }
 EXPORT_SYMBOL_GPL(dsa_register_switch);
 
+static void devm_dsa_unregister_switch(void *data)
+{
+	struct dsa_switch *ds = data;
+
+	dsa_unregister_switch(ds);
+}
+
+int devm_dsa_register_switch(struct device *dev, struct dsa_switch *ds)
+{
+	int err;
+
+	err = dsa_register_switch(ds);
+	if (err)
+		return err;
+
+	return devm_add_action_or_reset(dev, devm_dsa_unregister_switch, ds);
+}
+EXPORT_SYMBOL_GPL(devm_dsa_register_switch);
+
 static void dsa_switch_remove(struct dsa_switch *ds)
 {
 	struct dsa_switch_tree *dst = ds->dst;
-- 
2.45.2



From ansuelsmth at gmail.com  Thu Dec  5 06:51:32 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu,  5 Dec 2024 15:51:32 +0100
Subject: [net-next PATCH v9 2/4] dt-bindings: net: dsa: Add Airoha AN8855 Gigabit Switch documentation
In-Reply-To: <20241205145142.29278-1-ansuelsmth@gmail.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
Message-ID: <20241205145142.29278-3-ansuelsmth@gmail.com>

Add Airoha AN8855 5 port Gigabit Switch documentation.

The switch node requires an additional mdio node to describe each internal
PHY absolute address on the bus.

Calibration values might be stored in switch EFUSE and internal PHY
might need to be calibrated, in such case, airoha,ext-surge needs to be
enabled and relative NVMEM cells needs to be defined in nvmem-layout
node.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
 .../bindings/net/dsa/airoha,an8855.yaml       | 242 ++++++++++++++++++
 1 file changed, 242 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml

diff --git a/Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml b/Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml
new file mode 100644
index 000000000000..8ea2fadbab85
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml
@@ -0,0 +1,242 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/dsa/airoha,an8855.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 Gigabit switch
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description: >
+  Airoha AN8855 is a 5-port Gigabit Switch.
+
+  The switch node requires an additional mdio node to describe each internal
+  PHY relative offset as the PHY address for the switch match the one for
+  the PHY ports. On top of internal PHY address, the switch base PHY address
+  is added.
+
+  Also the switch base PHY address can be configured and changed after the
+  first initialization. On reset, the switch PHY address is ALWAYS 1.
+
+properties:
+  compatible:
+    const: airoha,an8855
+
+  reg:
+    maxItems: 1
+
+  reset-gpios:
+    description:
+      GPIO to be used to reset the whole device
+    maxItems: 1
+
+  airoha,ext-surge:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Calibrate the internal PHY with the calibration values stored in EFUSE
+      for the r50Ohm values.
+
+  '#nvmem-cell-cells':
+    const: 0
+
+  nvmem-layout:
+    $ref: /schemas/nvmem/layouts/nvmem-layout.yaml
+    description:
+      NVMEM Layout for exposed EFUSE. (for example to propagate calibration
+      value for r50Ohm for internal PHYs)
+
+  mdio:
+    $ref: /schemas/net/mdio.yaml#
+    unevaluatedProperties: false
+    description:
+      Define the absolute address of the internal PHY for each port.
+
+$ref: dsa.yaml#
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    mdio {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        switch at 1 {
+            compatible = "airoha,an8855";
+            reg = <1>;
+            reset-gpios = <&pio 39 0>;
+
+            airoha,ext-surge;
+
+            #nvmem-cell-cells = <0>;
+
+            nvmem-layout {
+                compatible = "fixed-layout";
+                #address-cells = <1>;
+                #size-cells = <1>;
+
+                shift_sel_port0_tx_a: shift-sel-port0-tx-a at c {
+                    reg = <0xc 0x4>;
+                };
+
+                shift_sel_port0_tx_b: shift-sel-port0-tx-b at 10 {
+                    reg = <0x10 0x4>;
+                };
+
+                shift_sel_port0_tx_c: shift-sel-port0-tx-c at 14 {
+                    reg = <0x14 0x4>;
+                };
+
+                shift_sel_port0_tx_d: shift-sel-port0-tx-d at 18 {
+                    reg = <0x18 0x4>;
+                };
+
+                shift_sel_port1_tx_a: shift-sel-port1-tx-a at 1c {
+                    reg = <0x1c 0x4>;
+                };
+
+                shift_sel_port1_tx_b: shift-sel-port1-tx-b at 20 {
+                    reg = <0x20 0x4>;
+                };
+
+                shift_sel_port1_tx_c: shift-sel-port1-tx-c at 24 {
+                    reg = <0x24 0x4>;
+                };
+
+                shift_sel_port1_tx_d: shift-sel-port1-tx-d at 28 {
+                    reg = <0x28 0x4>;
+                };
+
+                shift_sel_port2_tx_a: shift-sel-port2-tx-a at 2c {
+                    reg = <0x2c 0x4>;
+                };
+
+                shift_sel_port2_tx_b: shift-sel-port2-tx-b at 30 {
+                    reg = <0x30 0x4>;
+                };
+
+                shift_sel_port2_tx_c: shift-sel-port2-tx-c at 34 {
+                    reg = <0x34 0x4>;
+                };
+
+                shift_sel_port2_tx_d: shift-sel-port2-tx-d at 38 {
+                    reg = <0x38 0x4>;
+                };
+
+                shift_sel_port3_tx_a: shift-sel-port3-tx-a at 4c {
+                    reg = <0x4c 0x4>;
+                };
+
+                shift_sel_port3_tx_b: shift-sel-port3-tx-b at 50 {
+                    reg = <0x50 0x4>;
+                };
+
+                shift_sel_port3_tx_c: shift-sel-port3-tx-c at 54 {
+                    reg = <0x54 0x4>;
+                };
+
+                shift_sel_port3_tx_d: shift-sel-port3-tx-d at 58 {
+                    reg = <0x58 0x4>;
+                };
+            };
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port at 0 {
+                    reg = <0>;
+                    label = "lan1";
+                    phy-mode = "internal";
+                    phy-handle = <&internal_phy1>;
+                };
+
+                port at 1 {
+                    reg = <1>;
+                    label = "lan2";
+                    phy-mode = "internal";
+                    phy-handle = <&internal_phy2>;
+                };
+
+                port at 2 {
+                    reg = <2>;
+                    label = "lan3";
+                    phy-mode = "internal";
+                    phy-handle = <&internal_phy3>;
+                };
+
+                port at 3 {
+                    reg = <3>;
+                    label = "lan4";
+                    phy-mode = "internal";
+                    phy-handle = <&internal_phy4>;
+                };
+
+                port at 5 {
+                    reg = <5>;
+                    label = "cpu";
+                    ethernet = <&gmac0>;
+                    phy-mode = "2500base-x";
+
+                    fixed-link {
+                        speed = <2500>;
+                        full-duplex;
+                        pause;
+                    };
+                };
+            };
+
+            mdio {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                internal_phy1: phy at 1 {
+                    reg = <1>;
+
+                    nvmem-cells = <&shift_sel_port0_tx_a>,
+                                  <&shift_sel_port0_tx_b>,
+                                  <&shift_sel_port0_tx_c>,
+                                  <&shift_sel_port0_tx_d>;
+                    nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+
+                internal_phy2: phy at 2 {
+                    reg = <2>;
+
+                    nvmem-cells = <&shift_sel_port1_tx_a>,
+                                  <&shift_sel_port1_tx_b>,
+                                  <&shift_sel_port1_tx_c>,
+                                  <&shift_sel_port1_tx_d>;
+                    nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+
+                internal_phy3: phy at 3 {
+                    reg = <3>;
+
+                    nvmem-cells = <&shift_sel_port2_tx_a>,
+                                  <&shift_sel_port2_tx_b>,
+                                  <&shift_sel_port2_tx_c>,
+                                  <&shift_sel_port2_tx_d>;
+                    nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+
+                internal_phy4: phy at 4 {
+                    reg = <4>;
+
+                    nvmem-cells = <&shift_sel_port3_tx_a>,
+                                  <&shift_sel_port3_tx_b>,
+                                  <&shift_sel_port3_tx_c>,
+                                  <&shift_sel_port3_tx_d>;
+                    nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+            };
+        };
+    };
-- 
2.45.2



From ansuelsmth at gmail.com  Thu Dec  5 06:51:34 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu,  5 Dec 2024 15:51:34 +0100
Subject: [net-next PATCH v9 4/4] net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY
In-Reply-To: <20241205145142.29278-1-ansuelsmth@gmail.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
Message-ID: <20241205145142.29278-5-ansuelsmth@gmail.com>

Add support for Airoha AN8855 Internal Switch Gigabit PHY.

This is a simple PHY driver to configure and calibrate the PHY for the
AN8855 Switch with the use of NVMEM cells.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                  |   1 +
 drivers/net/phy/Kconfig      |   5 +
 drivers/net/phy/Makefile     |   1 +
 drivers/net/phy/air_an8855.c | 267 +++++++++++++++++++++++++++++++++++
 4 files changed, 274 insertions(+)
 create mode 100644 drivers/net/phy/air_an8855.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e3077d9feee2..cf34add2a0bb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -726,6 +726,7 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml
 F:	drivers/net/dsa/an8855.c
 F:	drivers/net/dsa/an8855.h
+F:	drivers/net/phy/air_an8855.c
 
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index ee3ea0b56d48..1d474038ea7f 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -79,6 +79,11 @@ config SFP
 
 comment "MII PHY device drivers"
 
+config AIR_AN8855_PHY
+	tristate "Airoha AN8855 Internal Gigabit PHY"
+	help
+	  Currently supports the internal Airoha AN8855 Switch PHY.
+
 config AIR_EN8811H_PHY
 	tristate "Airoha EN8811H 2.5 Gigabit PHY"
 	help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 90f886844381..baba7894785b 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -35,6 +35,7 @@ obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
 
 obj-$(CONFIG_ADIN_PHY)		+= adin.o
 obj-$(CONFIG_ADIN1100_PHY)	+= adin1100.o
+obj-$(CONFIG_AIR_AN8855_PHY)   += air_an8855.o
 obj-$(CONFIG_AIR_EN8811H_PHY)   += air_en8811h.o
 obj-$(CONFIG_AMD_PHY)		+= amd.o
 obj-$(CONFIG_AMCC_QT2025_PHY)	+= qt2025.o
diff --git a/drivers/net/phy/air_an8855.c b/drivers/net/phy/air_an8855.c
new file mode 100644
index 000000000000..7ede6674994f
--- /dev/null
+++ b/drivers/net/phy/air_an8855.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth at gmail.com>
+ */
+
+#include <linux/phy.h>
+#include <linux/module.h>
+#include <linux/bitfield.h>
+#include <linux/nvmem-consumer.h>
+
+#define AN8855_PHY_SELECT_PAGE			0x1f
+#define   AN8855_PHY_PAGE			GENMASK(2, 0)
+#define   AN8855_PHY_PAGE_STANDARD		FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
+#define   AN8855_PHY_PAGE_EXTENDED_1		FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
+
+/* MII Registers Page 1 */
+#define AN8855_PHY_EXT_REG_14			0x14
+#define   AN8855_PHY_EN_DOWN_SHIFT		BIT(4)
+
+/* R50 Calibration regs in MDIO_MMD_VEND1 */
+#define AN8855_PHY_R500HM_RSEL_TX_AB		0x174
+#define AN8855_PHY_R50OHM_RSEL_TX_A_EN		BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_A		GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_B_EN		BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_B		GENMASK(6, 0)
+#define AN8855_PHY_R500HM_RSEL_TX_CD		0x175
+#define AN8855_PHY_R50OHM_RSEL_TX_C_EN		BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_C		GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_D_EN		BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_D		GENMASK(6, 0)
+
+#define AN8855_SWITCH_EFUSE_R50O		GENMASK(30, 24)
+
+/* PHY TX PAIR DELAY SELECT Register */
+#define AN8855_PHY_TX_PAIR_DLY_SEL_GBE		0x013
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE GENMASK(14, 12)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_B_GBE GENMASK(10, 8)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE GENMASK(6, 4)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_D_GBE GENMASK(2, 0)
+/* PHY ADC Register */
+#define AN8855_PHY_RXADC_CTRL			0x0d8
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A	BIT(12)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_B	BIT(8)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C	BIT(4)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_D	BIT(0)
+#define AN8855_PHY_RXADC_REV_0			0x0d9
+#define   AN8855_PHY_RG_AD_RESERVE0_A		GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_B		GENMASK(7, 0)
+#define AN8855_PHY_RXADC_REV_1			0x0da
+#define   AN8855_PHY_RG_AD_RESERVE0_C		GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_D		GENMASK(7, 0)
+
+#define AN8855_PHY_ID				0xc0ff0410
+
+#define AN8855_PHY_FLAGS_EN_CALIBRATION		BIT(0)
+
+struct air_an8855_priv {
+	u8 calibration_data[4];
+};
+
+static const u8 dsa_r50ohm_table[] = {
+	127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+	127, 127, 127, 127, 127, 127, 127, 126, 122, 117,
+	112, 109, 104, 101,  97,  94,  90,  88,  84,  80,
+	78,  74,  72,  68,  66,  64,  61,  58,  56,  53,
+	51,  48,  47,  44,  42,  40,  38,  36,  34,  32,
+	31,  28,  27,  24,  24,  22,  20,  18,  16,  16,
+	14,  12,  11,   9
+};
+
+static int en8855_get_r50ohm_val(struct device *dev, const char *calib_name,
+				 u8 *dest)
+{
+	u32 shift_sel, val;
+	int ret;
+	int i;
+
+	ret = nvmem_cell_read_u32(dev, calib_name, &val);
+	if (ret)
+		return ret;
+
+	shift_sel = FIELD_GET(AN8855_SWITCH_EFUSE_R50O, val);
+	for (i = 0; i < ARRAY_SIZE(dsa_r50ohm_table); i++)
+		if (dsa_r50ohm_table[i] == shift_sel)
+			break;
+
+	if (i < 8 || i >= ARRAY_SIZE(dsa_r50ohm_table))
+		*dest = dsa_r50ohm_table[25];
+	else
+		*dest = dsa_r50ohm_table[i - 8];
+
+	return 0;
+}
+
+static int an8855_probe(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	struct device_node *node = dev->of_node;
+	struct air_an8855_priv *priv;
+	int ret;
+
+	/* If we don't have a node, skip get calib */
+	if (!node)
+		return 0;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	ret = en8855_get_r50ohm_val(dev, "tx_a", &priv->calibration_data[0]);
+	if (ret)
+		return ret;
+
+	ret = en8855_get_r50ohm_val(dev, "tx_b", &priv->calibration_data[1]);
+	if (ret)
+		return ret;
+
+	ret = en8855_get_r50ohm_val(dev, "tx_c", &priv->calibration_data[2]);
+	if (ret)
+		return ret;
+
+	ret = en8855_get_r50ohm_val(dev, "tx_d", &priv->calibration_data[3]);
+	if (ret)
+		return ret;
+
+	phydev->priv = priv;
+
+	return 0;
+}
+
+static int an8855_get_downshift(struct phy_device *phydev, u8 *data)
+{
+	int val;
+
+	val = phy_read_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1, AN8855_PHY_EXT_REG_14);
+	if (val < 0)
+		return val;
+
+	*data = val & AN8855_PHY_EN_DOWN_SHIFT ? DOWNSHIFT_DEV_DEFAULT_COUNT :
+						 DOWNSHIFT_DEV_DISABLE;
+
+	return 0;
+}
+
+static int an8855_set_downshift(struct phy_device *phydev, u8 cnt)
+{
+	u16 ds = cnt != DOWNSHIFT_DEV_DISABLE ? AN8855_PHY_EN_DOWN_SHIFT : 0;
+
+	return phy_modify_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1,
+				AN8855_PHY_EXT_REG_14, AN8855_PHY_EN_DOWN_SHIFT,
+				ds);
+}
+
+static int an8855_config_init(struct phy_device *phydev)
+{
+	struct air_an8855_priv *priv = phydev->priv;
+	int ret;
+
+	/* Enable HW auto downshift */
+	ret = an8855_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT);
+	if (ret)
+		return ret;
+
+	/* Apply calibration values, if needed.
+	 * AN8855_PHY_FLAGS_EN_CALIBRATION signal this.
+	 */
+	if (priv && phydev->dev_flags & AN8855_PHY_FLAGS_EN_CALIBRATION) {
+		u8 *calibration_data = priv->calibration_data;
+
+		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_AB,
+				     AN8855_PHY_R50OHM_RSEL_TX_A | AN8855_PHY_R50OHM_RSEL_TX_B,
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_A, calibration_data[0]) |
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_B, calibration_data[1]));
+		if (ret)
+			return ret;
+		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_CD,
+				     AN8855_PHY_R50OHM_RSEL_TX_C | AN8855_PHY_R50OHM_RSEL_TX_D,
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_C, calibration_data[2]) |
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_D, calibration_data[3]));
+		if (ret)
+			return ret;
+	}
+
+	/* Apply values to reduce signal noise */
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_TX_PAIR_DLY_SEL_GBE,
+			    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE, 0x4) |
+			    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE, 0x4));
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_CTRL,
+			    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A |
+			    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C);
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_0,
+			    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_A, 0x1));
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_1,
+			    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_C, 0x1));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int an8855_get_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, void *data)
+{
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT:
+		return an8855_get_downshift(phydev, data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int an8855_set_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, const void *data)
+{
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT:
+		return an8855_set_downshift(phydev, *(const u8 *)data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int an8855_read_page(struct phy_device *phydev)
+{
+	return __phy_read(phydev, AN8855_PHY_SELECT_PAGE);
+}
+
+static int an8855_write_page(struct phy_device *phydev, int page)
+{
+	return __phy_write(phydev, AN8855_PHY_SELECT_PAGE, page);
+}
+
+static struct phy_driver an8855_driver[] = {
+{
+	PHY_ID_MATCH_EXACT(AN8855_PHY_ID),
+	.name			= "Airoha AN8855 internal PHY",
+	/* PHY_GBIT_FEATURES */
+	.flags			= PHY_IS_INTERNAL,
+	.probe			= an8855_probe,
+	.config_init		= an8855_config_init,
+	.soft_reset		= genphy_soft_reset,
+	.get_tunable		= an8855_get_tunable,
+	.set_tunable		= an8855_set_tunable,
+	.suspend		= genphy_suspend,
+	.resume			= genphy_resume,
+	.read_page		= an8855_read_page,
+	.write_page		= an8855_write_page,
+}, };
+
+module_phy_driver(an8855_driver);
+
+static struct mdio_device_id __maybe_unused an8855_tbl[] = {
+	{ PHY_ID_MATCH_EXACT(AN8855_PHY_ID) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(mdio, an8855_tbl);
+
+MODULE_DESCRIPTION("Airoha AN8855 PHY driver");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From ansuelsmth at gmail.com  Thu Dec  5 06:51:30 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu,  5 Dec 2024 15:51:30 +0100
Subject: [net-next PATCH v9 0/4] net: dsa: Add Airoha AN8855 support
Message-ID: <20241205145142.29278-1-ansuelsmth@gmail.com>

This small series add the initial support for the Airoha AN8855 Switch.

It's a 5 port Gigabit Switch with SGMII/HSGMII upstream port.

This is starting to get in the wild and there are already some router
having this switch chip.

It's conceptually similar to mediatek switch but register and bits
are different. And there is that massive Hell that is the PCS
configuration.
Saddly for that part we have absolutely NO documentation currently.

There is this special thing where PHY needs to be calibrated with values
from the switch efuse. (the thing have a whole cpu timer and MCU)

>From v8 Driver is now evaluated with Kernel selftest scripts for DSA:

Output local_termination.sh
TEST: lan2: Unicast IPv4 to primary MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to macvlan MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address, promisc            [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address, allmulti           [ OK ]
TEST: lan2: Multicast IPv4 to joined group                          [ OK ]
TEST: lan2: Multicast IPv4 to unknown group                         [XFAIL]
        reception succeeded, but should have failed
TEST: lan2: Multicast IPv4 to unknown group, promisc                [ OK ]
TEST: lan2: Multicast IPv4 to unknown group, allmulti               [ OK ]
TEST: lan2: Multicast IPv6 to joined group                          [ OK ]
TEST: lan2: Multicast IPv6 to unknown group                         [XFAIL]
        reception succeeded, but should have failed
TEST: lan2: Multicast IPv6 to unknown group, promisc                [ OK ]
TEST: lan2: Multicast IPv6 to unknown group, allmulti               [ OK ]
TEST: lan2: 1588v2 over L2 transport, Sync                          [ OK ]
TEST: lan2: 1588v2 over L2 transport, Follow-Up                     [ OK ]
TEST: lan2: 1588v2 over L2 transport, Peer Delay Request            [ OK ]
TEST: lan2: 1588v2 over IPv4, Sync                                  [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv4, Follow-Up                             [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv4, Peer Delay Request                    [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Sync                                  [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Follow-Up                             [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Peer Delay Request                    [FAIL]
        reception failed
TEST: vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to joined group       [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to joined group       [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to joined group       [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to joined group       [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN upper: Unicast IPv4 to primary MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to macvlan MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address, promisc      [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address, allmulti     [ OK ]
TEST: VLAN upper: Multicast IPv4 to joined group                    [ OK ]
TEST: VLAN upper: Multicast IPv4 to unknown group                   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN upper: Multicast IPv4 to unknown group, promisc          [ OK ]
TEST: VLAN upper: Multicast IPv4 to unknown group, allmulti         [ OK ]
TEST: VLAN upper: Multicast IPv6 to joined group                    [ OK ]
TEST: VLAN upper: Multicast IPv6 to unknown group                   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN upper: Multicast IPv6 to unknown group, promisc          [ OK ]
TEST: VLAN upper: Multicast IPv6 to unknown group, allmulti         [ OK ]
TEST: VLAN upper: 1588v2 over L2 transport, Sync                    [ OK ]
TEST: VLAN upper: 1588v2 over L2 transport, Follow-Up               [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over L2 transport, Peer Delay Request      [ OK ]
TEST: VLAN upper: 1588v2 over IPv4, Sync                            [FAIL]
        reception failed
;TEST: VLAN upper: 1588v2 over IPv4, Follow-Up                       [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv4, Peer Delay Request              [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Sync                            [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Follow-Up                       [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Peer Delay Request              [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Sync   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Follow-Up   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Peer Delay Request   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address   [FAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, allmulti   [FAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Sync   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Follow-Up   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Peer Delay Request   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]

Output bridge_vlan_unaware.sh
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: FDB learning                                                  [ OK ]
TEST: Unknown unicast flood                                         [ OK ]
TEST: Unregistered multicast flood                                  [ OK ]

Output bridge_vlan_aware.sh
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: FDB learning                                                  [ OK ]
TEST: Unknown unicast flood                                         [ OK ]
TEST: Unregistered multicast flood                                  [ OK ]
INFO: Add and delete a VLAN on bridge port lan2
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: Externally learned FDB entry - ageing & roaming               [ OK ]
TEST: FDB entry in PVID for VLAN-tagged with other TPID             [FAIL]
        FDB entry was not learned when it should
TEST: Reception of VLAN with other TPID as untagged                 [FAIL]
        Packet was not forwarded when it should
TEST: Reception of VLAN with other TPID as untagged (no PVID)       [FAIL]
        Packet was forwarded when should not

Changes v9:
- Error out on using 5G speed as currently not supported
- Add missing MAC_2500FD in phylink mac_capabilities
- Add comment and improve if condition for an8855_phylink_mac_config
Changes v8:
- Add port Fast Age support
- Add support for Port Isolation
- Use correct register for Learning Disable
- Add support for Ageing Time OP
- Set default PVID to 0 by default
- Add mdb OPs
- Add port change MTU
- Fix support for Upper VLAN
Changes v7:
- Fix devm_dsa_register_switch wrong export symbol
Changes v6:
- Drop standard MIB and handle with ethtool OPs (as requested by Jakub)
- Cosmetic: use bool instead of 0 or 1
Changes v5:
- Add devm_dsa_register_switch() patch
- Add Reviewed-by tag for DT patch
Changes v4:
- Set regmap readable_table static (mute compilation warning)
- Add support for port_bridge flags (LEARNING, FLOOD)
- Reset fdb struct in fdb_dump
- Drop support_asym_pause in port_enable
- Add define for get_phy_flags
- Fix bug for port not inititially part of a bridge
  (in an8855_setup the port matrix was always cleared but
   the CPU port was never initially added)
- Disable learning and flood for user port by default
- Set CPU port to flood and learning by default
- Correctly AND force duplex and flow control in an8855_phylink_mac_link_up
- Drop RGMII from pcs_config
- Check ret in "Disable AN if not in autoneg"
- Use devm_mutex_init
- Fix typo for AN8855_PORT_CHECK_MODE
- Better define AN8855_STP_LISTENING = AN8855_STP_BLOCKING
- Fix typo in AN8855_PHY_EN_DOWN_SHIFT
- Use paged helper for PHY
- Skip calibration in config_init if priv not defined
Changes v3:
- Out of RFC
- Switch PHY code to select_page API
- Better describe masks and bits in PHY driver for ADC register
- Drop raw values and use define for mii read/write
- Switch to absolute PHY address
- Replace raw values with mask and bits for pcs_config
- Fix typo for ext-surge property name
- Drop support for relocating Switch base PHY address on the bus
Changes v2:
- Drop mutex guard patch
- Drop guard usage in DSA driver
- Use __mdiobus_write/read
- Check return condition and return errors for mii read/write
- Fix wrong logic for EEE
- Fix link_down (don't force link down with autoneg)
- Fix forcing speed on sgmii autoneg
- Better document link speed for sgmii reg
- Use standard define for sgmii reg
- Imlement nvmem support to expose switch EFUSE
- Rework PHY calibration with the use of NVMEM producer/consumer
- Update DT with new NVMEM property
- Move aneg validation for 2500-basex in pcs_config
- Move r50Ohm table and function to PHY driver

Christian Marangi (4):
  net: dsa: add devm_dsa_register_switch()
  dt-bindings: net: dsa: Add Airoha AN8855 Gigabit Switch documentation
  net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
  net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY

 .../bindings/net/dsa/airoha,an8855.yaml       |  242 ++
 MAINTAINERS                                   |   11 +
 drivers/net/dsa/Kconfig                       |    9 +
 drivers/net/dsa/Makefile                      |    1 +
 drivers/net/dsa/an8855.c                      | 2671 +++++++++++++++++
 drivers/net/dsa/an8855.h                      |  810 +++++
 drivers/net/phy/Kconfig                       |    5 +
 drivers/net/phy/Makefile                      |    1 +
 drivers/net/phy/air_an8855.c                  |  267 ++
 include/net/dsa.h                             |    1 +
 net/dsa/dsa.c                                 |   19 +
 11 files changed, 4037 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855.yaml
 create mode 100644 drivers/net/dsa/an8855.c
 create mode 100644 drivers/net/dsa/an8855.h
 create mode 100644 drivers/net/phy/air_an8855.c

-- 
2.45.2



From Frank.li at nxp.com  Thu Dec  5 06:56:11 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 5 Dec 2024 09:56:11 -0500
Subject: [PATCH v10 3/7] PCI: endpoint: pci-ep-msi: Add MSI address/data
 pair mutable check
In-Reply-To: <87ttbiqnq8.ffs@tglx>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
 <20241204-ep-msi-v10-3-87c378dbcd6d@nxp.com>
 <87ttbiqnq8.ffs@tglx>
Message-ID: <Z1G/CwFvO/aBLBe8@lizhi-Precision-Tower-5810>

On Thu, Dec 05, 2024 at 02:10:55PM +0100, Thomas Gleixner wrote:
> On Wed, Dec 04 2024 at 18:25, Frank Li wrote:
> > Some MSI controller change address/data pair when irq_set_affinity().
> > Current PCI endpoint can't support this type MSI controller. So add flag
> > MSI_FLAG_MUTABLE in include/linux/msi.h and check it when allocate
> > doorbell.
>
> Q: Who is going to annotate the affected domains with that flag?
>
> A: Nobody.
>
> Q: What's the value of the flag?
>
> A: Zero, as as it prevents exactly nothing.
>
> You want a MSI_FLAG_MSG_IMMUTABLE and set that on the domains which
> provide it. That way you ensure that someone looked at the domain to
> validate it.

Okay, at beginning I think most MSI controller is immutable. So I use
MSI_FLAG_MSG_MUTABLE.

It is fine change to MSI_FLAG_MSG_IMMUTABLE.

Frank

>
> Thanks,
>
>         tglx


From broonie at kernel.org  Thu Dec  5 07:04:11 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 5 Dec 2024 15:04:11 +0000
Subject: [PATCH 2/2] arm64: cpufeature: Add GCS to cpucap_is_possible()
In-Reply-To: <416c7369fcdce4ebb2a8f12daae234507be27e38.1733406275.git.robin.murphy@arm.com>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
 <416c7369fcdce4ebb2a8f12daae234507be27e38.1733406275.git.robin.murphy@arm.com>
Message-ID: <051c017c-a60f-48a7-b09f-07f0f32e48e3@sirena.org.uk>

On Thu, Dec 05, 2024 at 01:48:10PM +0000, Robin Murphy wrote:
> Since system_supports_gcs() ends up referring to cpucap_is_possible(),
> teach the latter about GCS for consistency with similar features.

Not clear why this is part of a series, there's no obvious relationship
with patch 1?

>  static inline bool system_supports_gcs(void)
>  {
> -	return IS_ENABLED(CONFIG_ARM64_GCS) &&
> -		alternative_has_cap_unlikely(ARM64_HAS_GCS);
> +	return alternative_has_cap_unlikely(ARM64_HAS_GCS);
>  }

Ah, this is bitrot since the series was on the list for so long.  As
well as HAFT which Rutland mentioned it looks like _bti_kernel(),
_irq_prio_masking() and possibly others have the same thing.  Ideally
we'd have no uses of IS_ENABLED() in these functions so it's a bit more
obvious.  In any case

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/20241205/dc23b591/attachment.sig>

From ardb+git at google.com  Thu Dec  5 07:02:30 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu,  5 Dec 2024 16:02:30 +0100
Subject: [PATCH v2 0/6] arm64: Clean up and simplify PA space size handling
Message-ID: <20241205150229.3510177-8-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

This series addresses a number of buglets related to how we handle the
size of the physical address space when building LPA2 capable kernels:

- reject 52-bit physical addressess in the mapping routines when LPA2 is
  configured but not available at runtime
- ensure that TCR.IPS is not set to 52-bits if LPA2 is not supported
- ensure that TCR_EL2.PS and DS match the host, regardless of whether
  LPA2 is available at stage 2
- don't rely on kvm_get_parange() and invalid physical addresses as
  control flags in the pKVM page donation APIs

Finally, the configurable 48-bit physical address space limit is dropped
entirely, as it doesn't buy us a lot now that all the PARange and {I}PS
handling is done at runtime.

Changes since v1:
- rebase onto v6.13-rc1
- add Anshuman's ack to patch #1
- incorporate Anshuman's feedback on patches #1 and #2
- tweak owner_update logic in patch #4

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>
Cc: Quentin Perret <qperret at google.com>

Ard Biesheuvel (6):
  arm64/mm: Reduce PA space to 48 bits when LPA2 is not enabled
  arm64/mm: Override PARange for !LPA2 and use it consistently
  arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
  arm64/kvm: Avoid invalid physical addresses to signal owner updates
  arm64: Kconfig: force ARM64_PAN=y when enabling TTBR0 sw PAN
  arm64/mm: Drop configurable 48-bit physical address space limit

 arch/arm64/Kconfig                     | 37 ++------------------
 arch/arm64/include/asm/assembler.h     | 14 +++-----
 arch/arm64/include/asm/cpufeature.h    |  3 +-
 arch/arm64/include/asm/kvm_pgtable.h   |  3 +-
 arch/arm64/include/asm/pgtable-hwdef.h | 12 +------
 arch/arm64/include/asm/pgtable-prot.h  |  7 ++++
 arch/arm64/include/asm/pgtable.h       | 11 +-----
 arch/arm64/include/asm/sparsemem.h     |  4 ++-
 arch/arm64/include/asm/sysreg.h        |  6 ----
 arch/arm64/kernel/cpufeature.c         |  2 +-
 arch/arm64/kernel/pi/idreg-override.c  |  9 +++++
 arch/arm64/kernel/pi/map_kernel.c      |  6 ++++
 arch/arm64/kvm/arm.c                   |  8 ++---
 arch/arm64/kvm/hyp/pgtable.c           | 33 ++++++-----------
 arch/arm64/mm/init.c                   |  7 +++-
 arch/arm64/mm/pgd.c                    |  9 ++---
 arch/arm64/mm/proc.S                   |  2 --
 scripts/gdb/linux/constants.py.in      |  1 -
 tools/arch/arm64/include/asm/sysreg.h  |  6 ----
 19 files changed, 63 insertions(+), 117 deletions(-)

-- 
2.47.0.338.g60cca15819-goog



From ardb+git at google.com  Thu Dec  5 07:02:31 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu,  5 Dec 2024 16:02:31 +0100
Subject: [PATCH v2 1/6] arm64/mm: Reduce PA space to 48 bits when LPA2 is not enabled
In-Reply-To: <20241205150229.3510177-8-ardb+git@google.com>
References: <20241205150229.3510177-8-ardb+git@google.com>
Message-ID: <20241205150229.3510177-9-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Currently, LPA2 kernel support implies support for up to 52 bits of
physical addressing, and this is reflected in global definitions such as
PHYS_MASK_SHIFT and MAX_PHYSMEM_BITS.

This is potentially problematic, given that LPA2 hardware support is
modeled as a CPU feature which can be overridden, and with LPA2 hardware
support turned off, attempting to map physical regions with address bits
[51:48] set (which may exist on LPA2 capable systems booting with
arm64.nolva) will result in corrupted mappings with a truncated output
address and bogus shareability attributes.

This means that the accepted physical address range in the mapping
routines should be at most 48 bits wide when LPA2 support is configured
but not enabled at runtime.

Fixes: 352b0395b505 ("arm64: Enable 52-bit virtual addressing for 4k and 16k granule configs")
Cc: <stable at vger.kernel.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgtable-hwdef.h | 6 ------
 arch/arm64/include/asm/pgtable-prot.h  | 7 +++++++
 arch/arm64/include/asm/sparsemem.h     | 4 +++-
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index c78a988cca93..a9136cc551cc 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -222,12 +222,6 @@
  */
 #define S1_TABLE_AP		(_AT(pmdval_t, 3) << 61)
 
-/*
- * Highest possible physical address supported.
- */
-#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
-#define PHYS_MASK		((UL(1) << PHYS_MASK_SHIFT) - 1)
-
 #define TTBR_CNP_BIT		(UL(1) << 0)
 
 /*
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 9f9cf13bbd95..a95f1f77bb39 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -81,6 +81,7 @@ extern unsigned long prot_ns_shared;
 #define lpa2_is_enabled()	false
 #define PTE_MAYBE_SHARED	PTE_SHARED
 #define PMD_MAYBE_SHARED	PMD_SECT_S
+#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
 #else
 static inline bool __pure lpa2_is_enabled(void)
 {
@@ -89,8 +90,14 @@ static inline bool __pure lpa2_is_enabled(void)
 
 #define PTE_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PTE_SHARED)
 #define PMD_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PMD_SECT_S)
+#define PHYS_MASK_SHIFT		(lpa2_is_enabled() ? CONFIG_ARM64_PA_BITS : 48)
 #endif
 
+/*
+ * Highest possible physical address supported.
+ */
+#define PHYS_MASK		((UL(1) << PHYS_MASK_SHIFT) - 1)
+
 /*
  * If we have userspace only BTI we don't want to mark kernel pages
  * guarded even if the system does support BTI.
diff --git a/arch/arm64/include/asm/sparsemem.h b/arch/arm64/include/asm/sparsemem.h
index 8a8acc220371..035e0ca74e88 100644
--- a/arch/arm64/include/asm/sparsemem.h
+++ b/arch/arm64/include/asm/sparsemem.h
@@ -5,7 +5,9 @@
 #ifndef __ASM_SPARSEMEM_H
 #define __ASM_SPARSEMEM_H
 
-#define MAX_PHYSMEM_BITS	CONFIG_ARM64_PA_BITS
+#include <asm/pgtable-prot.h>
+
+#define MAX_PHYSMEM_BITS	PHYS_MASK_SHIFT
 
 /*
  * Section size must be at least 512MB for 64K base
-- 
2.47.0.338.g60cca15819-goog



From ardb+git at google.com  Thu Dec  5 07:02:32 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu,  5 Dec 2024 16:02:32 +0100
Subject: [PATCH v2 2/6] arm64/mm: Override PARange for !LPA2 and use it consistently
In-Reply-To: <20241205150229.3510177-8-ardb+git@google.com>
References: <20241205150229.3510177-8-ardb+git@google.com>
Message-ID: <20241205150229.3510177-10-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

When FEAT_LPA{,2} are not implemented, the ID_AA64MMFR0_EL1.PARange and
TCR.IPS values corresponding with 52-bit physical addressing are
reserved.

Setting the TCR.IPS field to 0b110 (52-bit physical addressing) has side
effects, such as how the TTBRn_ELx.BADDR fields are interpreted, and so
it is important that disabling FEAT_LPA2 (by overriding the
ID_AA64MMFR0.TGran fields) also presents a PARange field consistent with
that.

So limit the field to 48 bits unless LPA2 is enabled, and update
existing references to use the override consistently.

Fixes: 352b0395b505 ("arm64: Enable 52-bit virtual addressing for 4k and 16k granule configs")
Cc: <stable at vger.kernel.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/assembler.h    | 5 +++++
 arch/arm64/kernel/cpufeature.c        | 2 +-
 arch/arm64/kernel/pi/idreg-override.c | 9 +++++++++
 arch/arm64/kernel/pi/map_kernel.c     | 6 ++++++
 arch/arm64/mm/init.c                  | 7 ++++++-
 5 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 3d8d534a7a77..ad63457a05c5 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -343,6 +343,11 @@ alternative_cb_end
 	// Narrow PARange to fit the PS field in TCR_ELx
 	ubfx	\tmp0, \tmp0, #ID_AA64MMFR0_EL1_PARANGE_SHIFT, #3
 	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_MAX
+#ifdef CONFIG_ARM64_LPA2
+alternative_if_not ARM64_HAS_VA52
+	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_48
+alternative_else_nop_endif
+#endif
 	cmp	\tmp0, \tmp1
 	csel	\tmp0, \tmp1, \tmp0, hi
 	bfi	\tcr, \tmp0, \pos, #3
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed8..f8cb8a6ab98a 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -3478,7 +3478,7 @@ static void verify_hyp_capabilities(void)
 		return;
 
 	safe_mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
-	mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
+	mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 	mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
 
 	/* Verify VMID bits */
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index 22159251eb3a..c6b185b885f7 100644
--- a/arch/arm64/kernel/pi/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -83,6 +83,15 @@ static bool __init mmfr2_varange_filter(u64 val)
 		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;
+
+		/*
+		 * Override PARange to 48 bits - the override will just be
+		 * ignored if the actual PARange is smaller, but this is
+		 * unlikely to be the case for LPA2 capable silicon.
+		 */
+		id_aa64mmfr0_override.val |=
+			ID_AA64MMFR0_EL1_PARANGE_48 << ID_AA64MMFR0_EL1_PARANGE_SHIFT;
+		id_aa64mmfr0_override.mask |= 0xfU << ID_AA64MMFR0_EL1_PARANGE_SHIFT;
 	}
 #endif
 	return true;
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
index f374a3e5a5fe..e57b043f324b 100644
--- a/arch/arm64/kernel/pi/map_kernel.c
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -136,6 +136,12 @@ 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;
+	u64 mmfr0 = read_sysreg(id_aa64mmfr0_el1);
+	u64 parange = cpuid_feature_extract_unsigned_field(mmfr0,
+							   ID_AA64MMFR0_EL1_PARANGE_SHIFT);
+
+	tcr &= ~TCR_IPS_MASK;
+	tcr |= parange << TCR_IPS_SHIFT;
 
 	asm("	msr	sctlr_el1, %0		;"
 	    "	isb				;"
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d21f67d67cf5..2b2289d55eaa 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -280,7 +280,12 @@ void __init arm64_memblock_init(void)
 
 	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
 		extern u16 memstart_offset_seed;
-		u64 mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
+
+		/*
+		 * Use the sanitised version of id_aa64mmfr0_el1 so that linear
+		 * map randomization can be enabled by shrinking the IPA space.
+		 */
+		u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 		int parange = cpuid_feature_extract_unsigned_field(
 					mmfr0, ID_AA64MMFR0_EL1_PARANGE_SHIFT);
 		s64 range = linear_region_size -
-- 
2.47.0.338.g60cca15819-goog



From ardb+git at google.com  Thu Dec  5 07:02:33 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu,  5 Dec 2024 16:02:33 +0100
Subject: [PATCH v2 3/6] arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
In-Reply-To: <20241205150229.3510177-8-ardb+git@google.com>
References: <20241205150229.3510177-8-ardb+git@google.com>
Message-ID: <20241205150229.3510177-11-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

When the host stage1 is configured for LPA2, the value currently being
programmed into TCR_EL2.T0SZ may be invalid unless LPA2 is configured
at HYP as well.  This means kvm_lpa2_is_enabled() is not the right
condition to test when setting TCR_EL2.DS, as it will return false if
LPA2 is only available for stage 1 but not for stage 2.

Similary, programming TCR_EL2.PS based on a limited IPA range due to
lack of stage2 LPA2 support could potentially result in problems.

So use lpa2_is_enabled() instead, and set the PS field according to the
host's IPS, which is capped at 48 bits if LPA2 support is absent or
disabled. Whether or not we can make meaningful use of such a
configuration is a different question.

Cc: <stable at vger.kernel.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kvm/arm.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..7b2735ad32e9 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1990,8 +1990,7 @@ static int kvm_init_vector_slots(void)
 static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
 {
 	struct kvm_nvhe_init_params *params = per_cpu_ptr_nvhe_sym(kvm_init_params, cpu);
-	u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
-	unsigned long tcr;
+	unsigned long tcr, ips;
 
 	/*
 	 * Calculate the raw per-cpu offset without a translation from the
@@ -2005,6 +2004,7 @@ static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
 	params->mair_el2 = read_sysreg(mair_el1);
 
 	tcr = read_sysreg(tcr_el1);
+	ips = FIELD_GET(TCR_IPS_MASK, tcr);
 	if (cpus_have_final_cap(ARM64_KVM_HVHE)) {
 		tcr |= TCR_EPD1_MASK;
 	} else {
@@ -2014,8 +2014,8 @@ static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
 	tcr &= ~TCR_T0SZ_MASK;
 	tcr |= TCR_T0SZ(hyp_va_bits);
 	tcr &= ~TCR_EL2_PS_MASK;
-	tcr |= FIELD_PREP(TCR_EL2_PS_MASK, kvm_get_parange(mmfr0));
-	if (kvm_lpa2_is_enabled())
+	tcr |= FIELD_PREP(TCR_EL2_PS_MASK, ips);
+	if (lpa2_is_enabled())
 		tcr |= TCR_EL2_DS;
 	params->tcr_el2 = tcr;
 
-- 
2.47.0.338.g60cca15819-goog



From ardb+git at google.com  Thu Dec  5 07:02:34 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu,  5 Dec 2024 16:02:34 +0100
Subject: [PATCH v2 4/6] arm64/kvm: Avoid invalid physical addresses to signal
 owner updates
In-Reply-To: <20241205150229.3510177-8-ardb+git@google.com>
References: <20241205150229.3510177-8-ardb+git@google.com>
Message-ID: <20241205150229.3510177-12-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The pKVM stage2 mapping code relies on an invalid physical address to
signal to the internal API that only the owner_id fields of descriptors
should be updated, and these are stored in the high bits of invalid
descriptors covering memory that has been donated to protected guests,
and is therefore unmapped from the host stage-2 page tables.

Given that these invalid PAs are never stored into the descriptors, it
is better to rely on an explicit flag, to clarify the API and to avoid
confusion regarding whether or not the output address of a descriptor
can ever be invalid to begin with (which is not the case with LPA2).

That removes a dependency on the logic that reasons about the maximum PA
range, which differs on LPA2 capable CPUs based on whether LPA2 is
enabled or not, and will be further clarified in subsequent patches.

Cc: Quentin Perret <qperret at google.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kvm/hyp/pgtable.c | 33 ++++++--------------
 1 file changed, 10 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 40bd55966540..0569e1d97c38 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -35,14 +35,6 @@ static bool kvm_pgtable_walk_skip_cmo(const struct kvm_pgtable_visit_ctx *ctx)
 	return unlikely(ctx->flags & KVM_PGTABLE_WALK_SKIP_CMO);
 }
 
-static bool kvm_phys_is_valid(u64 phys)
-{
-	u64 parange_max = kvm_get_parange_max();
-	u8 shift = id_aa64mmfr0_parange_to_phys_shift(parange_max);
-
-	return phys < BIT(shift);
-}
-
 static bool kvm_block_mapping_supported(const struct kvm_pgtable_visit_ctx *ctx, u64 phys)
 {
 	u64 granule = kvm_granule_size(ctx->level);
@@ -53,7 +45,7 @@ static bool kvm_block_mapping_supported(const struct kvm_pgtable_visit_ctx *ctx,
 	if (granule > (ctx->end - ctx->addr))
 		return false;
 
-	if (kvm_phys_is_valid(phys) && !IS_ALIGNED(phys, granule))
+	if (!IS_ALIGNED(phys, granule))
 		return false;
 
 	return IS_ALIGNED(ctx->addr, granule);
@@ -587,6 +579,9 @@ struct stage2_map_data {
 
 	/* Force mappings to page granularity */
 	bool				force_pte;
+
+	/* Walk should update owner_id only */
+	bool				owner_update;
 };
 
 u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
@@ -885,18 +880,7 @@ static u64 stage2_map_walker_phys_addr(const struct kvm_pgtable_visit_ctx *ctx,
 {
 	u64 phys = data->phys;
 
-	/*
-	 * Stage-2 walks to update ownership data are communicated to the map
-	 * walker using an invalid PA. Avoid offsetting an already invalid PA,
-	 * which could overflow and make the address valid again.
-	 */
-	if (!kvm_phys_is_valid(phys))
-		return phys;
-
-	/*
-	 * Otherwise, work out the correct PA based on how far the walk has
-	 * gotten.
-	 */
+	/* Work out the correct PA based on how far the walk has gotten */
 	return phys + (ctx->addr - ctx->start);
 }
 
@@ -908,6 +892,9 @@ static bool stage2_leaf_mapping_allowed(const struct kvm_pgtable_visit_ctx *ctx,
 	if (data->force_pte && ctx->level < KVM_PGTABLE_LAST_LEVEL)
 		return false;
 
+	if (data->owner_update && ctx->level == KVM_PGTABLE_LAST_LEVEL)
+		return true;
+
 	return kvm_block_mapping_supported(ctx, phys);
 }
 
@@ -923,7 +910,7 @@ static int stage2_map_walker_try_leaf(const struct kvm_pgtable_visit_ctx *ctx,
 	if (!stage2_leaf_mapping_allowed(ctx, data))
 		return -E2BIG;
 
-	if (kvm_phys_is_valid(phys))
+	if (!data->owner_update)
 		new = kvm_init_valid_leaf_pte(phys, data->attr, ctx->level);
 	else
 		new = kvm_init_invalid_leaf_owner(data->owner_id);
@@ -1085,11 +1072,11 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size,
 {
 	int ret;
 	struct stage2_map_data map_data = {
-		.phys		= KVM_PHYS_INVALID,
 		.mmu		= pgt->mmu,
 		.memcache	= mc,
 		.owner_id	= owner_id,
 		.force_pte	= true,
+		.owner_update	= true,
 	};
 	struct kvm_pgtable_walker walker = {
 		.cb		= stage2_map_walker,
-- 
2.47.0.338.g60cca15819-goog



From ardb+git at google.com  Thu Dec  5 07:02:35 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu,  5 Dec 2024 16:02:35 +0100
Subject: [PATCH v2 5/6] arm64: Kconfig: force ARM64_PAN=y when enabling TTBR0
 sw PAN
In-Reply-To: <20241205150229.3510177-8-ardb+git@google.com>
References: <20241205150229.3510177-8-ardb+git@google.com>
Message-ID: <20241205150229.3510177-13-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

There are a couple of instances of Kconfig constraints where PAN must be
enabled too if TTBR0 sw PAN is enabled, primarily to avoid dealing with
the modified TTBR0_EL1 sysreg format that is used when 52-bit physical
addressing and/or CnP are enabled (support for either implies support
for hardware PAN as well, which will supersede PAN emulation if both are
available)

Let's simplify this, and always enable ARM64_PAN when enabling TTBR0 sw
PAN. This decouples the PAN configuration from the VA size selection,
permitting us to simplify the latter in subsequent patches. (Note that
PAN and TTBR0 sw PAN can still be disabled after this patch, but not
independently)

To avoid a convoluted circular Kconfig dependency involving KCSAN, make
ARM64_MTE select ARM64_PAN too, instead of depending on it.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/Kconfig | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..c1ca21adddc1 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1379,7 +1379,6 @@ config ARM64_VA_BITS_48
 
 config ARM64_VA_BITS_52
 	bool "52-bit"
-	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
@@ -1431,7 +1430,6 @@ config ARM64_PA_BITS_48
 config ARM64_PA_BITS_52
 	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
 	  part of the ARMv8.2-LPA extension.
@@ -1681,6 +1679,7 @@ config RODATA_FULL_DEFAULT_ENABLED
 config ARM64_SW_TTBR0_PAN
 	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
 	depends on !KCSAN
+	select ARM64_PAN
 	help
 	  Enabling this option prevents the kernel from accessing
 	  user-space memory directly by pointing TTBR0_EL1 to a reserved
@@ -1937,7 +1936,6 @@ config ARM64_RAS_EXTN
 config ARM64_CNP
 	bool "Enable support for Common Not Private (CNP) translations"
 	default y
-	depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
 	help
 	  Common Not Private (CNP) allows translation table entries to
 	  be shared between different PEs in the same inner shareable
@@ -2132,7 +2130,7 @@ config ARM64_MTE
 	depends on AS_HAS_ARMV8_5
 	depends on AS_HAS_LSE_ATOMICS
 	# Required for tag checking in the uaccess routines
-	depends on ARM64_PAN
+	select ARM64_PAN
 	select ARCH_HAS_SUBPAGE_FAULTS
 	select ARCH_USES_HIGH_VMA_FLAGS
 	select ARCH_USES_PG_ARCH_2
-- 
2.47.0.338.g60cca15819-goog



From ardb+git at google.com  Thu Dec  5 07:02:36 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu,  5 Dec 2024 16:02:36 +0100
Subject: [PATCH v2 6/6] arm64/mm: Drop configurable 48-bit physical address
 space limit
In-Reply-To: <20241205150229.3510177-8-ardb+git@google.com>
References: <20241205150229.3510177-8-ardb+git@google.com>
Message-ID: <20241205150229.3510177-14-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Currently, the maximum supported physical address space can be
configured as either 48 bits or 52 bits. The only remaining difference
between these in practice is that the former omits the masking and
shifting required to construct TTBR and PTE values, which carry bits #48
and higher disjoint from the rest of the physical address.

The overhead of performing these additional calculations is negligible,
and so there is little reason to retain support for two different
configurations, and we can simply support whatever the hardware
supports.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/Kconfig                     | 31 +-------------------
 arch/arm64/include/asm/assembler.h     | 13 ++------
 arch/arm64/include/asm/cpufeature.h    |  3 +-
 arch/arm64/include/asm/kvm_pgtable.h   |  3 +-
 arch/arm64/include/asm/pgtable-hwdef.h |  6 +---
 arch/arm64/include/asm/pgtable-prot.h  |  4 +--
 arch/arm64/include/asm/pgtable.h       | 11 +------
 arch/arm64/include/asm/sysreg.h        |  6 ----
 arch/arm64/mm/pgd.c                    |  9 +++---
 arch/arm64/mm/proc.S                   |  2 --
 scripts/gdb/linux/constants.py.in      |  1 -
 tools/arch/arm64/include/asm/sysreg.h  |  6 ----
 12 files changed, 14 insertions(+), 81 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c1ca21adddc1..7ebd0ba32a32 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1416,38 +1416,9 @@ config ARM64_VA_BITS
 	default 48 if ARM64_VA_BITS_48
 	default 52 if ARM64_VA_BITS_52
 
-choice
-	prompt "Physical address space size"
-	default ARM64_PA_BITS_48
-	help
-	  Choose the maximum physical address range that the kernel will
-	  support.
-
-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"
-	depends on ARM64_64K_PAGES || ARM64_VA_BITS_52
-	help
-	  Enable support for a 52-bit physical address space, introduced as
-	  part of the ARMv8.2-LPA extension.
-
-	  With this enabled, the kernel will also continue to work on CPUs that
-	  do not support ARMv8.2-LPA, but with some added memory overhead (and
-	  minor performance overhead).
-
-endchoice
-
-config ARM64_PA_BITS
-	int
-	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
+	depends on !ARM64_64K_PAGES
 
 choice
 	prompt "Endianness"
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index ad63457a05c5..01a1e3c16283 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -342,14 +342,13 @@ alternative_cb_end
 	mrs	\tmp0, ID_AA64MMFR0_EL1
 	// Narrow PARange to fit the PS field in TCR_ELx
 	ubfx	\tmp0, \tmp0, #ID_AA64MMFR0_EL1_PARANGE_SHIFT, #3
-	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_MAX
 #ifdef CONFIG_ARM64_LPA2
 alternative_if_not ARM64_HAS_VA52
 	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_48
-alternative_else_nop_endif
-#endif
 	cmp	\tmp0, \tmp1
 	csel	\tmp0, \tmp1, \tmp0, hi
+alternative_else_nop_endif
+#endif
 	bfi	\tcr, \tmp0, \pos, #3
 	.endm
 
@@ -599,21 +598,13 @@ alternative_endif
  * 	ttbr:	returns the TTBR value
  */
 	.macro	phys_to_ttbr, ttbr, phys
-#ifdef CONFIG_ARM64_PA_BITS_52
 	orr	\ttbr, \phys, \phys, lsr #46
 	and	\ttbr, \ttbr, #TTBR_BADDR_MASK_52
-#else
-	mov	\ttbr, \phys
-#endif
 	.endm
 
 	.macro	phys_to_pte, pte, phys
-#ifdef CONFIG_ARM64_PA_BITS_52
 	orr	\pte, \phys, \phys, lsr #PTE_ADDR_HIGH_SHIFT
 	and	\pte, \pte, #PHYS_TO_PTE_ADDR_MASK
-#else
-	mov	\pte, \phys
-#endif
 	.endm
 
 /*
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index b64e49bd9d10..ed327358e734 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -885,9 +885,8 @@ static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
 	 * However, by the "D10.1.4 Principles of the ID scheme
 	 * for fields in ID registers", ARM DDI 0487C.a, any new
 	 * value is guaranteed to be higher than what we know already.
-	 * As a safe limit, we return the limit supported by the kernel.
 	 */
-	default: return CONFIG_ARM64_PA_BITS;
+	default: return 52;
 	}
 }
 
diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index aab04097b505..525aef178cb4 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -30,8 +30,7 @@
 
 static inline u64 kvm_get_parange_max(void)
 {
-	if (kvm_lpa2_is_enabled() ||
-	   (IS_ENABLED(CONFIG_ARM64_PA_BITS_52) && PAGE_SHIFT == 16))
+	if (kvm_lpa2_is_enabled() || PAGE_SHIFT == 16)
 		return ID_AA64MMFR0_EL1_PARANGE_52;
 	else
 		return ID_AA64MMFR0_EL1_PARANGE_48;
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index a9136cc551cc..9b34180042b2 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -176,7 +176,6 @@
 #define PTE_SWBITS_MASK		_AT(pteval_t, (BIT(63) | GENMASK(58, 55)))
 
 #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_HIGH_SHIFT	36
@@ -186,7 +185,6 @@
 #define PTE_ADDR_HIGH_SHIFT	42
 #define PHYS_TO_PTE_ADDR_MASK	GENMASK_ULL(49, 8)
 #endif
-#endif
 
 /*
  * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
@@ -327,12 +325,10 @@
 /*
  * TTBR.
  */
-#ifdef CONFIG_ARM64_PA_BITS_52
 /*
- * TTBR_ELx[1] is RES0 in this configuration.
+ * TTBR_ELx[1] is RES0 when using 52-bit physical addressing
  */
 #define TTBR_BADDR_MASK_52	GENMASK_ULL(47, 2)
-#endif
 
 #ifdef CONFIG_ARM64_VA_BITS_52
 /* Must be at least 64-byte aligned to prevent corruption of the TTBR */
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index a95f1f77bb39..b73acf25341f 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -81,7 +81,7 @@ extern unsigned long prot_ns_shared;
 #define lpa2_is_enabled()	false
 #define PTE_MAYBE_SHARED	PTE_SHARED
 #define PMD_MAYBE_SHARED	PMD_SECT_S
-#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
+#define PHYS_MASK_SHIFT		(52)
 #else
 static inline bool __pure lpa2_is_enabled(void)
 {
@@ -90,7 +90,7 @@ static inline bool __pure lpa2_is_enabled(void)
 
 #define PTE_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PTE_SHARED)
 #define PMD_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PMD_SECT_S)
-#define PHYS_MASK_SHIFT		(lpa2_is_enabled() ? CONFIG_ARM64_PA_BITS : 48)
+#define PHYS_MASK_SHIFT		(lpa2_is_enabled() ? 52 : 48)
 #endif
 
 /*
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6986345b537a..ec8124d66b9c 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -69,10 +69,9 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 	pr_err("%s:%d: bad pte %016llx.\n", __FILE__, __LINE__, pte_val(e))
 
 /*
- * Macros to convert between a physical address and its placement in a
+ * Helpers to convert between a physical address and its placement in a
  * page table entry, taking care of 52-bit addresses.
  */
-#ifdef CONFIG_ARM64_PA_BITS_52
 static inline phys_addr_t __pte_to_phys(pte_t pte)
 {
 	pte_val(pte) &= ~PTE_MAYBE_SHARED;
@@ -83,10 +82,6 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
 {
 	return (phys | (phys >> PTE_ADDR_HIGH_SHIFT)) & PHYS_TO_PTE_ADDR_MASK;
 }
-#else
-#define __pte_to_phys(pte)	(pte_val(pte) & PTE_ADDR_LOW)
-#define __phys_to_pte_val(phys)	(phys)
-#endif
 
 #define pte_pfn(pte)		(__pte_to_phys(pte) >> PAGE_SHIFT)
 #define pfn_pte(pfn,prot)	\
@@ -1495,11 +1490,7 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
 	update_mmu_cache_range(NULL, vma, addr, ptep, 1)
 #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
 
-#ifdef CONFIG_ARM64_PA_BITS_52
 #define phys_to_ttbr(addr)	(((addr) | ((addr) >> 46)) & TTBR_BADDR_MASK_52)
-#else
-#define phys_to_ttbr(addr)	(addr)
-#endif
 
 /*
  * On arm64 without hardware Access Flag, copying from user will fail because
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index b8303a83c0bf..f902893ec903 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -916,12 +916,6 @@
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2		0x3
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX		0x7
 
-#ifdef CONFIG_ARM64_PA_BITS_52
-#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_52
-#else
-#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_48
-#endif
-
 #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
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 0c501cabc238..8722ab6d4b1c 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -48,20 +48,21 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 
 void __init pgtable_cache_init(void)
 {
+	unsigned int pgd_size = PGD_SIZE;
+
 	if (pgdir_is_page_size())
 		return;
 
-#ifdef CONFIG_ARM64_PA_BITS_52
 	/*
 	 * With 52-bit physical addresses, the architecture requires the
 	 * top-level table to be aligned to at least 64 bytes.
 	 */
-	BUILD_BUG_ON(PGD_SIZE < 64);
-#endif
+	if (PHYS_MASK_SHIFT >= 52)
+		pgd_size = max(pgd_size, 64);
 
 	/*
 	 * Naturally aligned pgds required by the architecture.
 	 */
-	pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
+	pgd_cache = kmem_cache_create("pgd_cache", pgd_size, pgd_size,
 				      SLAB_PANIC, NULL);
 }
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index b8edc5765441..51ed0e9d0a0d 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -197,10 +197,8 @@ SYM_FUNC_ALIAS(__pi_idmap_cpu_replace_ttbr1, idmap_cpu_replace_ttbr1)
 
 	.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
diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
index fd6bd69c5096..05034c0b8fd7 100644
--- a/scripts/gdb/linux/constants.py.in
+++ b/scripts/gdb/linux/constants.py.in
@@ -141,7 +141,6 @@ LX_CONFIG(CONFIG_ARM64_4K_PAGES)
 LX_CONFIG(CONFIG_ARM64_16K_PAGES)
 LX_CONFIG(CONFIG_ARM64_64K_PAGES)
 if IS_BUILTIN(CONFIG_ARM64):
-    LX_VALUE(CONFIG_ARM64_PA_BITS)
     LX_VALUE(CONFIG_ARM64_VA_BITS)
     LX_VALUE(CONFIG_PAGE_SHIFT)
     LX_VALUE(CONFIG_ARCH_FORCE_MAX_ORDER)
diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index cd8420e8c3ad..daeecb1a5366 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -574,12 +574,6 @@
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MIN		0x2
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX		0x7
 
-#ifdef CONFIG_ARM64_PA_BITS_52
-#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_52
-#else
-#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_48
-#endif
-
 #if defined(CONFIG_ARM64_4K_PAGES)
 #define ID_AA64MMFR0_EL1_TGRAN_SHIFT		ID_AA64MMFR0_EL1_TGRAN4_SHIFT
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN
-- 
2.47.0.338.g60cca15819-goog



From alexander.stein at ew.tq-group.com  Thu Dec  5 07:07:28 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Thu,  5 Dec 2024 16:07:28 +0100
Subject: [PATCH v2 1/2] arm64: dt: imx93-tqma9352-mba93xxca: enable Open Drain for MDIO
Message-ID: <20241205150730.3132807-1-alexander.stein@ew.tq-group.com>

From: Markus Niebel <Markus.Niebel at ew.tq-group.com>

The board has a pull-up resistor for MDIO pin per PHY design guide.
When MDIO is idle, it needs to be high and open drain is better
to be used here for power saving.

Signed-off-by: Markus Niebel <Markus.Niebel at ew.tq-group.com>
Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
Changes in v2:
* Update commit message

 .../arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts
index 599df32976e24..8e939d716aac8 100644
--- a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxca.dts
@@ -627,8 +627,8 @@ pinctrl_eqos: eqosgrp {
 		fsl,pins = <
 			/* PD | FSEL_2 | DSE X4 */
 			MX93_PAD_ENET1_MDC__ENET_QOS_MDC			0x51e
-			/* SION | HYS | FSEL_2 | DSE X4 */
-			MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO			0x4000111e
+			/* SION | HYS | ODE | FSEL_2 | DSE X4 */
+			MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO			0x4000191e
 			/* HYS | FSEL_0 | DSE no drive */
 			MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0			0x1000
 			MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1			0x1000
@@ -659,8 +659,8 @@ pinctrl_fec: fecgrp {
 		fsl,pins = <
 			/* PD | FSEL_2 | DSE X4 */
 			MX93_PAD_ENET2_MDC__ENET1_MDC			0x51e
-			/* SION | HYS | FSEL_2 | DSE X4 */
-			MX93_PAD_ENET2_MDIO__ENET1_MDIO			0x4000111e
+			/* SION | HYS | ODE | FSEL_2 | DSE X4 */
+			MX93_PAD_ENET2_MDIO__ENET1_MDIO			0x4000191e
 			/* HYS | FSEL_0 | DSE no drive */
 			MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0		0x1000
 			MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1		0x1000
-- 
2.34.1



From alexander.stein at ew.tq-group.com  Thu Dec  5 07:07:29 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Thu,  5 Dec 2024 16:07:29 +0100
Subject: [PATCH v2 2/2] arm64: dt: imx93-tqma9352-mba93xxla: enable Open Drain for MDIO
In-Reply-To: <20241205150730.3132807-1-alexander.stein@ew.tq-group.com>
References: <20241205150730.3132807-1-alexander.stein@ew.tq-group.com>
Message-ID: <20241205150730.3132807-2-alexander.stein@ew.tq-group.com>

From: Markus Niebel <Markus.Niebel at ew.tq-group.com>

The board has a pull-up resistor for MDIO pin per PHY design guide.
When MDIO is idle, it needs to be high and open drain is better
to be used here for power saving.

Signed-off-by: Markus Niebel <Markus.Niebel at ew.tq-group.com>
Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
Changes in v2:
* Update commit message

 .../arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts
index 0b4b3bb866d06..2e953a05c590e 100644
--- a/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts
@@ -597,8 +597,8 @@ pinctrl_eqos: eqosgrp {
 		fsl,pins = <
 			/* PD | FSEL_2 | DSE X4 */
 			MX93_PAD_ENET1_MDC__ENET_QOS_MDC			0x51e
-			/* SION | HYS | FSEL_2 | DSE X4 */
-			MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO			0x4000111e
+			/* SION | HYS | ODE | FSEL_2 | DSE X4 */
+			MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO			0x4000191e
 			/* HYS | FSEL_0 | DSE no drive */
 			MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0			0x1000
 			MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1			0x1000
@@ -629,8 +629,8 @@ pinctrl_fec: fecgrp {
 		fsl,pins = <
 			/* PD | FSEL_2 | DSE X4 */
 			MX93_PAD_ENET2_MDC__ENET1_MDC			0x51e
-			/* SION | HYS | FSEL_2 | DSE X4 */
-			MX93_PAD_ENET2_MDIO__ENET1_MDIO			0x4000111e
+			/* SION | HYS | ODE | FSEL_2 | DSE X4 */
+			MX93_PAD_ENET2_MDIO__ENET1_MDIO			0x4000191e
 			/* HYS | FSEL_0 | DSE no drive */
 			MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0		0x1000
 			MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1		0x1000
-- 
2.34.1



From dan.carpenter at linaro.org  Thu Dec  5 07:16:20 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Thu, 5 Dec 2024 18:16:20 +0300
Subject: arm64: include/linux/compiler_types.h:542:38: error: call to
 '__compiletime_assert_1050' declared with attribute error: clamp() low limit
 min greater than high limit max_avail
In-Reply-To: <CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g@mail.gmail.com>
References: <CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g@mail.gmail.com>
Message-ID: <8dde5a62-4ce6-4954-86c9-54d961aed6df@stanley.mountain>

Add David to the CC list.

regards,
dan carpenter

On Thu, Dec 05, 2024 at 08:15:13PM +0530, Naresh Kamboju wrote:
> The arm64 build started failing from Linux next-20241203 tag with gcc-8
> due to following build warnings / errors.
> 
> First seen on Linux next-20241203 tag
> GOOD: Linux next-20241128 tag
> BAD: Linux next-20241203 tag and next-20241205 tag
> 
> * arm64, build
>   - gcc-8-defconfig
>   - gcc-8-defconfig-40bc7ee5
> 
> Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>
> 
> Build log:
> ===========
> net/netfilter/ipvs/ip_vs_conn.c: In function 'ip_vs_conn_init':
> include/linux/compiler_types.h:542:38: error: call to
> '__compiletime_assert_1050' declared with attribute error: clamp() low
> limit min greater than high limit max_avail
>   _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>                                       ^
> include/linux/compiler_types.h:523:4: note: in definition of macro
> '__compiletime_assert'
>     prefix ## suffix();    \
>     ^~~~~~
> include/linux/compiler_types.h:542:2: note: in expansion of macro
> '_compiletime_assert'
>   _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>   ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro
> 'compiletime_assert'
>  #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
>                                      ^~~~~~~~~~~~~~~~~~
> include/linux/minmax.h:188:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
>   BUILD_BUG_ON_MSG(statically_true(ulo > uhi),    \
>   ^~~~~~~~~~~~~~~~
> include/linux/minmax.h:195:2: note: in expansion of macro '__clamp_once'
>   __clamp_once(type, val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_),
> __UNIQUE_ID(h_))
>   ^~~~~~~~~~~~
> include/linux/minmax.h:206:28: note: in expansion of macro '__careful_clamp'
>  #define clamp(val, lo, hi) __careful_clamp(__auto_type, val, lo, hi)
>                             ^~~~~~~~~~~~~~~
> net/netfilter/ipvs/ip_vs_conn.c:1498:8: note: in expansion of macro 'clamp'
>   max = clamp(max, min, max_avail);
>         ^~~~~
> 
> Links:
> ---
> - https://storage.tuxsuite.com/public/linaro/lkft/builds/2pjAOE9K3Dz9gRywrldKTyaXQoT/
> - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20241203/testrun/26189105/suite/build/test/gcc-8-defconfig/log
> - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20241203/testrun/26189105/suite/build/test/gcc-8-defconfig/details/
> - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20241203/testrun/26189105/suite/build/test/gcc-8-defconfig/history/
> 
> Steps to reproduce:
> ------------
> # tuxmake --runtime podman --target-arch arm64 --toolchain gcc-8
> --kconfig defconfig
> 
> metadata:
> ----
>   git describe: next-20241203
>   git repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
>   git sha: c245a7a79602ccbee780c004c1e4abcda66aec32
>   kernel config:
> https://storage.tuxsuite.com/public/linaro/lkft/builds/2pjAOE9K3Dz9gRywrldKTyaXQoT/config
>   build url: https://storage.tuxsuite.com/public/linaro/lkft/builds/2pjAOE9K3Dz9gRywrldKTyaXQoT/
>   toolchain: gcc-8
>   config: gcc-8-defconfig
>   arch: arm64
> 
> --
> Linaro LKFT
> https://lkft.linaro.org


From lkp at intel.com  Thu Dec  5 07:15:38 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 5 Dec 2024 23:15:38 +0800
Subject: [PATCH v4 4/4] firmware: imx: secvio: Add support for SNVS
 secvio and tamper via SCFW
In-Reply-To: <20241205-secvio-v4-4-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-4-5c37cdc39573@nxp.com>
Message-ID: <202412052340.ub9tlWcC-lkp@intel.com>

Hi Vabhav,

kernel test robot noticed the following build errors:

[auto build test ERROR on 9852d85ec9d492ebef56dc5f229416c925758edc]

url:    https://github.com/intel-lab-lkp/linux/commits/Vabhav-Sharma/dt-bindings-firmware-imx-add-nvmem-phandle/20241205-125909
base:   9852d85ec9d492ebef56dc5f229416c925758edc
patch link:    https://lore.kernel.org/r/20241205-secvio-v4-4-5c37cdc39573%40nxp.com
patch subject: [PATCH v4 4/4] firmware: imx: secvio: Add support for SNVS secvio and tamper via SCFW
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20241205/202412052340.ub9tlWcC-lkp at intel.com/config)
compiler: sh4-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241205/202412052340.ub9tlWcC-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/202412052340.ub9tlWcC-lkp at intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

ERROR: modpost: missing MODULE_LICENSE() in drivers/firmware/imx/imx-scu-secvio.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/firmware/imx/imx-scu-secvio.o
ERROR: modpost: "__delay" [drivers/net/mdio/mdio-cavium.ko] undefined!
ERROR: modpost: "devm_of_clk_add_hw_provider" [drivers/media/i2c/tc358746.ko] undefined!
ERROR: modpost: "devm_clk_hw_register" [drivers/media/i2c/tc358746.ko] undefined!
ERROR: modpost: "of_clk_hw_simple_get" [drivers/media/i2c/tc358746.ko] undefined!
>> ERROR: modpost: "imx_secvio_sc_debugfs" [drivers/firmware/imx/imx-scu-secvio.ko] undefined!

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


From jakobunt at gmail.com  Thu Dec  5 07:18:27 2024
From: jakobunt at gmail.com (Jakob Unterwurzacher)
Date: Thu,  5 Dec 2024 16:18:27 +0100
Subject: [PATCH v3] arm64: dts: rockchip: increase gmac rx_delay on rk3399-puma
Message-ID: <20241205151827.282130-1-jakob.unterwurzacher@cherry.de>

During mass manufacturing, we noticed the mmc_rx_crc_error counter,
as reported by "ethtool -S eth0 | grep mmc_rx_crc_error", to increase
above zero during nuttcp speedtests. Most of the time, this did not
affect the achieved speed, but it prompted this investigation.

Cycling through the rx_delay range on six boards (see table below) of
various ages shows that there is a large good region from 0x12 to 0x35
where we see zero crc errors on all tested boards.

The old rx_delay value (0x10) seems to have always been on the edge for
the KSZ9031RNX that is usually placed on Puma.

Choose "rx_delay = 0x23" to put us smack in the middle of the good
region. This works fine as well with the KSZ9131RNX PHY that was used
for a small number of boards during the COVID chip shortages.

	Board S/N        PHY        rx_delay good region
	---------        ---        --------------------
	Puma TT0069903   KSZ9031RNX 0x11 0x35
	Puma TT0157733   KSZ9031RNX 0x11 0x35
	Puma TT0681551   KSZ9031RNX 0x12 0x37
	Puma TT0681156   KSZ9031RNX 0x10 0x38
	Puma 17496030079 KSZ9031RNX 0x10 0x37 (Puma v1.2 from 2017)
	Puma TT0681720   KSZ9131RNX 0x02 0x39 (alternative PHY used in very few boards)

	Intersection of good regions = 0x12 0x35
	Middle of good region = 0x23

Relates-to: PUMA-111
Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")
Cc: <stable at vger.kernel.org>
Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>
Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at cherry.de>
---
v3: use rx_delay = 0x23 instead of 0x11, which was not enough.
v2: cc stable, add "Fixes:", add omitted "there" to commit msg,
    add Reviewed-by.

 arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
index 9efcdce0f593..f9b4cd2d7daa 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
@@ -181,7 +181,7 @@ &gmac {
 	snps,reset-active-low;
 	snps,reset-delays-us = <0 10000 50000>;
 	tx_delay = <0x10>;
-	rx_delay = <0x10>;
+	rx_delay = <0x23>;
 	status = "okay";
 };
 
-- 
2.39.5



From alexander.stein at ew.tq-group.com  Thu Dec  5 07:22:22 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Thu, 05 Dec 2024 16:22:22 +0100
Subject: [PATCH v2 1/4] media: i2c: imx290: Limit analogue gain according to module
In-Reply-To: <20241120-media-imx290-imx462-v2-1-7e562cf191d8@raspberrypi.com>
References: <20241120-media-imx290-imx462-v2-0-7e562cf191d8@raspberrypi.com> <20241120-media-imx290-imx462-v2-1-7e562cf191d8@raspberrypi.com>
Message-ID: <4950196.GXAFRqVoOG@steina-w>

Hi Dave,

Am Mittwoch, 20. November 2024, 20:17:03 CET schrieb Dave Stevenson:
> The imx327 only supports up to 29.4dB of analogue gain, vs
> the imx290 going up to 30dB. Both are in 0.3dB steps.

While I agree for 30dB on imx290, my (maybe outdated) Rev0.2 datasheet says
up to 27dB in 0.3dB steps.

Despite that this change looks good.

Best regards,
Alexander

> As we now have model specific config, fix this mismatch,
> and delete the comment referencing it.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
>  drivers/media/i2c/imx290.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
> index ee698c99001d..da654deb444a 100644
> --- a/drivers/media/i2c/imx290.c
> +++ b/drivers/media/i2c/imx290.c
> @@ -176,6 +176,7 @@ struct imx290_model_info {
>  	enum imx290_colour_variant colour_variant;
>  	const struct cci_reg_sequence *init_regs;
>  	size_t init_regs_num;
> +	unsigned int max_analog_gain;
>  	const char *name;
>  };
>  
> @@ -876,14 +877,10 @@ static int imx290_ctrl_init(struct imx290 *imx290)
>  	 * up to 72.0dB (240) add further digital gain. Limit the range to
>  	 * analog gain only, support for digital gain can be added separately
>  	 * if needed.
> -	 *
> -	 * The IMX327 and IMX462 are largely compatible with the IMX290, but
> -	 * have an analog gain range of 0.0dB to 29.4dB and 42dB of digital
> -	 * gain. When support for those sensors gets added to the driver, the
> -	 * gain control should be adjusted accordingly.
>  	 */
>  	v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
> -			  V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0);
> +			  V4L2_CID_ANALOGUE_GAIN, 0,
> +			  imx290->model->max_analog_gain, 1, 0);
>  
>  	/*
>  	 * Correct range will be determined through imx290_ctrl_update setting
> @@ -1441,18 +1438,21 @@ static const struct imx290_model_info imx290_models[] = {
>  		.colour_variant = IMX290_VARIANT_COLOUR,
>  		.init_regs = imx290_global_init_settings_290,
>  		.init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290),
> +		.max_analog_gain = 100,
>  		.name = "imx290",
>  	},
>  	[IMX290_MODEL_IMX290LLR] = {
>  		.colour_variant = IMX290_VARIANT_MONO,
>  		.init_regs = imx290_global_init_settings_290,
>  		.init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290),
> +		.max_analog_gain = 100,
>  		.name = "imx290",
>  	},
>  	[IMX290_MODEL_IMX327LQR] = {
>  		.colour_variant = IMX290_VARIANT_COLOUR,
>  		.init_regs = imx290_global_init_settings_327,
>  		.init_regs_num = ARRAY_SIZE(imx290_global_init_settings_327),
> +		.max_analog_gain = 98,
>  		.name = "imx327",
>  	},
>  };
> 
> 


-- 
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 Dec  5 07:24:01 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 16:24:01 +0100
Subject: [PATCH v3] arm64: dts: rockchip: increase gmac rx_delay on
 rk3399-puma
In-Reply-To: <20241205151827.282130-1-jakob.unterwurzacher@cherry.de>
References: <20241205151827.282130-1-jakob.unterwurzacher@cherry.de>
Message-ID: <97d7b661-8b9b-4c56-aa85-3833718f4e01@linaro.org>

On 05/12/2024 16:18, Jakob Unterwurzacher wrote:
> During mass manufacturing, we noticed the mmc_rx_crc_error counter,
> as reported by "ethtool -S eth0 | grep mmc_rx_crc_error", to increase
> above zero during nuttcp speedtests. Most of the time, this did not
> affect the achieved speed, but it prompted this investigation.
> 
> Cycling through the rx_delay range on six boards (see table below) of
> various ages shows that there is a large good region from 0x12 to 0x35
> where we see zero crc errors on all tested boards.
> 
> The old rx_delay value (0x10) seems to have always been on the edge for
> the KSZ9031RNX that is usually placed on Puma.
> 
> Choose "rx_delay = 0x23" to put us smack in the middle of the good
> region. This works fine as well with the KSZ9131RNX PHY that was used
> for a small number of boards during the COVID chip shortages.
> 
> 	Board S/N        PHY        rx_delay good region
> 	---------        ---        --------------------
> 	Puma TT0069903   KSZ9031RNX 0x11 0x35
> 	Puma TT0157733   KSZ9031RNX 0x11 0x35
> 	Puma TT0681551   KSZ9031RNX 0x12 0x37
> 	Puma TT0681156   KSZ9031RNX 0x10 0x38
> 	Puma 17496030079 KSZ9031RNX 0x10 0x37 (Puma v1.2 from 2017)
> 	Puma TT0681720   KSZ9131RNX 0x02 0x39 (alternative PHY used in very few boards)
> 
> 	Intersection of good regions = 0x12 0x35
> 	Middle of good region = 0x23
> 
> Relates-to: PUMA-111

Drop 3rd party tags.

Also you you CC-ed an address, which suggests you do not work on
mainline kernel or you do not use get_maintainers.pl/b4/patman.
Regardless of the reason, process needs improvement: please rebase and
always work on mainline or start using mentioned tools tools, so correct
addresses will be used.


Best regards,
Krzysztof


From catalin.marinas at arm.com  Thu Dec  5 07:25:18 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 5 Dec 2024 15:25:18 +0000
Subject: [PATCH 2/2] arm64: cpufeature: Add GCS to cpucap_is_possible()
In-Reply-To: <051c017c-a60f-48a7-b09f-07f0f32e48e3@sirena.org.uk>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
 <416c7369fcdce4ebb2a8f12daae234507be27e38.1733406275.git.robin.murphy@arm.com>
 <051c017c-a60f-48a7-b09f-07f0f32e48e3@sirena.org.uk>
Message-ID: <Z1HF3i-mAAXDHKUP@arm.com>

On Thu, Dec 05, 2024 at 03:04:11PM +0000, Mark Brown wrote:
> On Thu, Dec 05, 2024 at 01:48:10PM +0000, Robin Murphy wrote:
> > Since system_supports_gcs() ends up referring to cpucap_is_possible(),
> > teach the latter about GCS for consistency with similar features.
> 
> Not clear why this is part of a series, there's no obvious relationship
> with patch 1?

No, probably Robing forgot to pass --no-thread to git.

> >  static inline bool system_supports_gcs(void)
> >  {
> > -	return IS_ENABLED(CONFIG_ARM64_GCS) &&
> > -		alternative_has_cap_unlikely(ARM64_HAS_GCS);
> > +	return alternative_has_cap_unlikely(ARM64_HAS_GCS);
> >  }
> 
> Ah, this is bitrot since the series was on the list for so long.  As
> well as HAFT which Rutland mentioned it looks like _bti_kernel(),
> _irq_prio_masking() and possibly others have the same thing.  Ideally
> we'd have no uses of IS_ENABLED() in these functions so it's a bit more
> obvious.  In any case
> 
> Reviewed-by: Mark Brown <broonie at kernel.org>

Thanks. This patch will go in via the arm64 tree. I'll leave the other
for the smmu tree.

-- 
Catalin


From sudeep.holla at arm.com  Thu Dec  5 07:27:18 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 5 Dec 2024 15:27:18 +0000
Subject: [PATCH V4 1/5] dt-bindings: firmware: Document bindings for QCOM
 SCMI Generic Extension
In-Reply-To: <20241007061023.1978380-2-quic_sibis@quicinc.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-2-quic_sibis@quicinc.com>
Message-ID: <Z1HGVhi5xebqc4d4@bogus>

On Mon, Oct 07, 2024 at 11:40:19AM +0530, Sibi Sankar wrote:
> Document the various memory buses that can be monitored and scaled by
> the memory latency governor hosted by the QCOM SCMI Generic Extension
> Protocol v1.0.
> 
> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
> ---
> 
> v3:
> * Restructure the bindings to mimic IMX [Christian]
> 
>  .../bindings/firmware/arm,scmi.yaml           |   1 +
>  .../bindings/firmware/qcom,scmi-memlat.yaml   | 246 ++++++++++++++++++
>  .../dt-bindings/firmware/qcom,scmi-memlat.h   |  22 ++
>  3 files changed, 269 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/firmware/qcom,scmi-memlat.yaml
>  create mode 100644 include/dt-bindings/firmware/qcom,scmi-memlat.h
> 
> diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
> index 54d7d11bfed4..1d405f429168 100644
> --- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
> +++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
> @@ -24,6 +24,7 @@ description: |
>  
>  anyOf:
>    - $ref: /schemas/firmware/nxp,imx95-scmi.yaml
> +  - $ref: /schemas/firmware/qcom,scmi-memlat.yaml
>  
>  properties:
>    $nodename:
> diff --git a/Documentation/devicetree/bindings/firmware/qcom,scmi-memlat.yaml b/Documentation/devicetree/bindings/firmware/qcom,scmi-memlat.yaml
> new file mode 100644
> index 000000000000..0e8ea6dacd6a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/firmware/qcom,scmi-memlat.yaml
> @@ -0,0 +1,246 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/firmware/qcom,scmi-memlat.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm SCMI Memory Bus nodes
> +
> +maintainers:
> +  - Sibi Sankar <quic_sibis at quicinc.com>
> +
> +description:
> +  This binding describes the various memory buses that can be monitored and scaled
> +  by memory latency governor running on the CPU Control Processor (SCMI controller).
> +
> +properties:
> +  protocol at 80:
> +    $ref: '/schemas/firmware/arm,scmi.yaml#/$defs/protocol-node'
> +    unevaluatedProperties: false
> +
> +    properties:
> +      reg:
> +        const: 0x80
> +
> +    patternProperties:
> +      '^memory-[0-9]$':
> +        type: object
> +        unevaluatedProperties: false
> +        description:
> +          The list of all memory buses that can be monitored and scaled by the
> +          memory latency governor running on the SCMI controller.
> +
> +        properties:
> +          qcom,memory-type:
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            enum: [0, 1, 2]
> +            description: |
> +              Memory Bus Identifier
> +              0 = QCOM_MEM_TYPE_DDR
> +              1 = QCOM_MEM_TYPE_LLCC
> +              2 = QCOM_MEM_TYPE_DDR_QOS
> +
> +          freq-table-hz:
> +            items:
> +              items:
> +                - description: Minimum frequency of the memory bus in Hz
> +                - description: Maximum frequency of the memory bus in Hz
> +
> +        patternProperties:
> +          '^monitor-[0-9]$':
> +            type: object
> +            unevaluatedProperties: false
> +            description:
> +              The list of all monitors detecting the memory latency bound workloads using
> +              various counters.
> +
> +            properties:
> +              qcom,compute-type:
> +                description:
> +                  Monitors of type compute perform bus dvfs based on a rudimentary CPU
> +                  frequency to memory frequency map.
> +                type: boolean
> +
> +              qcom,ipm-ceil:
> +                $ref: /schemas/types.yaml#/definitions/uint32
> +                description:
> +                  Monitors having this property perform bus dvfs based on the same
> +                  rudimentary table but the scaling is performed only if the calculated
> +                  IPM (Instruction Per Misses) exceeds the given ceiling.
> +
> +              cpus:
> +                $ref: /schemas/types.yaml#/definitions/phandle-array
> +                description:
> +                  Should be a list of phandles to CPU nodes (as described in
> +                  Documentation/devicetree/bindings/arm/cpus.yaml).

And what exactly this list of cpu phandles represent here ?

> +
> +              operating-points-v2: true

Can you elaborate why the protocol can't add a command to fetch this from
the firmware to avoid any possible mismatch between the DT and firmware.

> +              opp-table:
> +                type: object
> +
> +            required:
> +              - cpus
> +              - operating-points-v2
> +
> +            oneOf:
> +              - required: [ 'qcom,compute-type' ]
> +              - required: [ 'qcom,ipm-ceil' ]
> +
> +        required:
> +          - qcom,memory-type
> +          - freq-table-hz
> +
> +additionalProperties: true
> +
> +examples:
> +  - |
> +    #include <dt-bindings/firmware/qcom,scmi-memlat.h>
> +
> +    firmware {
> +        scmi {
> +            compatible = "arm,scmi";
> +            mboxes = <&cpucp_mbox 0>, <&cpucp_mbox 2>;
> +            mbox-names = "tx", "rx";
> +            shmem = <&cpu_scp_lpri0>, <&cpu_scp_lpri1>;
> +
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            protocol at 80 {
> +                reg = <0x80>;
> +
> +                memory-0 {

I am not sure if it is just me, but I find this binding hard to understand.
Hence I thought I will look and the example and get better understanding
instead.

So these monitors are numbered ? If there were any meaningful name it would
have been slightly better but irrespective of that I find it hard as why
the communication with firmware is not based on index and why they are not
part of the bindings though I see indices used in the driver.

> +                    qcom,memory-type = <QCOM_MEM_TYPE_DDR>;

Also I see that the type can be easily derived from the index, care to
elaborate why the firmware expects it to be sent, if not why is that
information needed here in the DT ?

-- 
Regards,
Sudeep


From ksloat at cornersoftsolutions.com  Thu Dec  5 07:32:17 2024
From: ksloat at cornersoftsolutions.com (Ken Sloat)
Date: Thu, 5 Dec 2024 10:32:17 -0500
Subject: [PATCH v1] dt-bindings: dma: st-stm32-dmamux: Add description for
 dma-cell values
Message-ID: <CADRqkYAaCYvo3ybGdKO1F_y9jFEcwTBxZzRN-Av-adq_4fVu6g@mail.gmail.com>

The dma-cell values for the stm32-dmamux are used to craft the DMA spec
for the actual controller. These values are currently undocumented
leaving the user to reverse engineer the driver in order to determine
their meaning. Add a basic description, while avoiding duplicating
information by pointing the user to the associated DMA docs that
describe the fields in depth.

Signed-off-by: Ken Sloat <ksloat at cornersoftsolutions.com>
---
.../bindings/dma/stm32/st,stm32-dmamux.yaml | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
index f26c914a3a9a..aa2e52027ee6 100644
--- a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
+++ b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
@@ -15,6 +15,17 @@ allOf:
properties:
"#dma-cells":
const: 3
+ description: |
+ Should be set to <3> with each cell representing the following:
+ 1. The mux input number/line for the request
+ 2. Bitfield representing DMA channel configuration that is passed
+ to the real DMA controller
+ 3. Bitfield representing device dependent DMA features passed to
+ the real DMA controller
+
+ For bitfield definitions of cells 2 and 3, see the associated
+ bindings doc for the actual DMA controller the mux is connected
+ to.
compatible:
const: st,stm32h7-dmamux
-- 
2.34.1


From sudeep.holla at arm.com  Thu Dec  5 07:32:02 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 5 Dec 2024 15:32:02 +0000
Subject: [PATCH V5 1/2] firmware: arm_scmi: Add QCOM Generic Vendor
 Protocol documentation
In-Reply-To: <73a16eb4-e590-92db-ee24-cc4f42a9de01@quicinc.com>
References: <20241115011515.1313447-1-quic_sibis@quicinc.com>
 <20241115011515.1313447-2-quic_sibis@quicinc.com>
 <Z1BBirNWH1eaSKtr@pluto>
 <73a16eb4-e590-92db-ee24-cc4f42a9de01@quicinc.com>
Message-ID: <Z1HHciQfWL-l79YR@bogus>

On Thu, Dec 05, 2024 at 04:37:28PM +0530, Sibi Sankar wrote:
> 
> 
> On 12/4/24 17:18, Cristian Marussi wrote:
> > On Fri, Nov 15, 2024 at 06:45:14AM +0530, Sibi Sankar wrote:
> > > Add QCOM System Control Management Interface (SCMI) Generic Vendor
> > > Extensions Protocol documentation.
> > > 
> > > Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
> > > ---
> > > 
> > > v4:
> > > * Update the protol attributes doc with more information. [Cristian]
> > > 
> > >   .../arm_scmi/vendors/qcom/qcom_generic.rst    | 211 ++++++++++++++++++
> > >   1 file changed, 211 insertions(+)
> > >   create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> > > 
> > > diff --git a/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> > > new file mode 100644
> > > index 000000000000..141bc932e30f
> > > --- /dev/null
> > > +++ b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> > > @@ -0,0 +1,211 @@
> > > +.. SPDX-License-Identifier: GPL-2.0
> > > +.. include:: <isonum.txt>
> > > +
> > > +===============================================================================
> > > +QCOM System Control and Management Interface(SCMI) Vendor Protocols Extension
> > > +===============================================================================
> > > +
> > > +:Copyright: |copy| 2024, Qualcomm Innovation Center, Inc. All rights reserved.
> > > +
> > > +:Author: Sibi Sankar <quic_sibis at quicinc.com>
> > > +
> > > +SCMI_GENERIC: System Control and Management Interface QCOM Generic Vendor Protocol
> > > +==================================================================================
> > > +
> > > +This protocol is intended as a generic way of exposing a number of Qualcomm
> > > +SoC specific features through a mixture of pre-determined algorithm string and
> > > +param_id pairs hosted on the SCMI controller. It implements an interface compliant
> > > +with the Arm SCMI Specification with additional vendor specific commands as
> > > +detailed below.
> > > +
> > > +Commands:
> > > +_________
> > > +
> > > +PROTOCOL_VERSION
> > > +~~~~~~~~~~~~~~~~
> > > +
> > > +message_id: 0x0
> > > +protocol_id: 0x80
> > > +
> > > ++---------------+--------------------------------------------------------------+
> > > +|Return values                                                                 |
> > > ++---------------+--------------------------------------------------------------+
> > > +|Name           |Description                                                   |
> > > ++---------------+--------------------------------------------------------------+
> > > +|int32 status   |See ARM SCMI Specification for status code definitions.       |
> > > ++---------------+--------------------------------------------------------------+
> > > +|uint32 version |For this revision of the specification, this value must be    |
> > > +|               |0x10000.                                                      |
> > > ++---------------+--------------------------------------------------------------+
> > > +
> > > +PROTOCOL_ATTRIBUTES
> > > +~~~~~~~~~~~~~~~~~~~
> > > +
> > > +message_id: 0x1
> > > +protocol_id: 0x80
> > > +
> > > ++---------------+--------------------------------------------------------------+
> > > +|Return values                                                                 |
> > > ++------------------+-----------------------------------------------------------+
> > > +|Name              |Description                                                |
> > > ++------------------+-----------------------------------------------------------+
> > > +|int32 status      |See ARM SCMI Specification for status code definitions.    |
> > > ++------------------+-----------------------------------------------------------+
> > > +|uint32 attributes |Bits[31:16] Reserved, must be to 0.                        |
> > > +|                  |Bits[15:8] Number of agents in the system                  |
> > > +|                  |Bits[7:0] Number of vendor protocols in the system         |
> > > ++------------------+-----------------------------------------------------------+
> > 
> > Thanks of clarifing this....may I ask why number of agents is reported
> > here too given that it is already exposed by Base protocol ?
> > 
> > Not really arguing about this so much, but you will end up having to maintain this
> > on 2 different protocols fw side...or are they not 'agents' in the SCMI meaning ?
> > 
> > Anyway, I'm fine with it, even though you dont seem to use this
> > anywhere.
> 
> We don't use it anywhere and it looks like it was just put together
> so that this protocol is compliant to the spec :|

Interesting, I need to dig and check if that is needed to be compliant.
Even if it is required, please add a text to say it must match what std.
BASE protocol response(IOW it just can't be random here as you don't use
it anymore). We may decide to match and warn if required at all.

-- 
Regards,
Sudeep


From miquel.raynal at bootlin.com  Thu Dec  5 07:32:32 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 05 Dec 2024 16:32:32 +0100
Subject: [PATCH nand/next] mtd: nand: spi: Use write_cache first and
 then update_cache in write operation
In-Reply-To: <20241119093949.3014-1-SkyLake.Huang@mediatek.com> (Sky Huang's
	message of "Tue, 19 Nov 2024 17:39:49 +0800")
References: <20241119093949.3014-1-SkyLake.Huang@mediatek.com>
Message-ID: <871pymtab3.fsf@bootlin.com>

Hello,

On 19/11/2024 at 17:39:49 +08, Sky Huang <SkyLake.Huang at mediatek.com> wrote:

> From: Sky Huang <skylake.huang at mediatek.com>
>
> According to discussion with Miquel Raynal <miquel.raynal at bootlin.com>
> and Chuanhong Guo <gch981213 at gmail.com> on FORESEE F35SQA002G patch,
> Chuanhong recommmends that we can use the following sequence in
> spinand_write_to_cache_op():
>
> x1 mode:
> 02H(program data load) -> 84H(random program data load) -> 84H ...
>
> x4 mode:
> 32H(program data load x4) -> 34H(random program data load x4) -> 34H ...
>
> 02H or 32H commands will clear cache buffer on SPI-NAND and load
> data to it. For those SPI controllers which can't finish transmission
> in single step, 84H or 34H will be triggered for the rest data.
>
> We observe that some current SPI-NANDs, including FORESEE F35SQA001G and
> F35SQA002G, must use 02H or 32H to reset cache buffer in flash before
> using 84H or 34H. Or users may encounter program failure issue. This issue
> is not always reproducible, but it may occur and cause system instability.
>
> This sequence should work on all SPI-NANDs nowadays. I also check with
> Foresee that the sequence can solve the above program failure issue.
>
> On my test platform (MT7988), SPI driver is drivers/spi/spi-mt65xx.c.
> And I limit MTK_SPI_IPM_PACKET_SIZE to SZ_1K to simulate lightweight SPI
> controller which can only transmit 1024 bytes.
>
> The test step is the following:
> - mtd erase /dev/mtd2
> - dd if=/dev/zero bs=2048 count=1 | tr '\0' '\xA5' > output.bin
> - mtd write output.bin /dev/mtd2
>
> Before applying this patch, write operation uses only 34H(update_cache):
> [78.937720] OP code: 0x34, addr val: 0x0, data nbytes: 1020, data 1st byte: 0xa5
> [78.945297] OP code: 0x34, addr val: 0x3fc, data nbytes: 1020, data 1st byte: 0xa5
> [78.954251] OP code: 0x34, addr val: 0x7f8, data nbytes: 72, data 1st byte: 0xa5
> [78.962966] OP code: 0x10, addr val: 0x300
> [78.968816] OP code: 0x34, addr val: 0x0, data nbytes: 1020, data 1st byte: 0xff
> [78.977233] OP code: 0x34, addr val: 0x3fc, data nbytes: 1020, data 1st byte: 0xff
> [78.985124] OP code: 0x34, addr val: 0x7f8, data nbytes: 72, data 1st byte: 0xff
> [78.992527] OP code: 0x10, addr val: 0x301
> [78.996981] OP code: 0x34, addr val: 0x0, data nbytes: 1020, data 1st byte: 0xff
> [79.004416] OP code: 0x34, addr val: 0x3fc, data nbytes: 1020, data 1st byte: 0xff
> [79.012031] OP code: 0x34, addr val: 0x7f8, data nbytes: 72, data 1st byte: 0xff
> [79.019435] OP code: 0x10, addr val: 0x302

I am sorry but above you said that we should not perform:

    0x32, 0x32, 0x32...

because the second time it would clear the cache again. And here
you tell us that actually the core already handles that by performing
instead:

    0x34, 0x34, 0x34...

So what is the problem?

Or maybe I misunderstood the issue, but I think Chuanhong raised an
issue that is already solved? Isn't it?

Thanks,
Miqu?l


From dave.stevenson at raspberrypi.com  Thu Dec  5 07:37:01 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 5 Dec 2024 15:37:01 +0000
Subject: [PATCH v2 1/4] media: i2c: imx290: Limit analogue gain according
 to module
In-Reply-To: <4950196.GXAFRqVoOG@steina-w>
References: <20241120-media-imx290-imx462-v2-0-7e562cf191d8@raspberrypi.com>
 <20241120-media-imx290-imx462-v2-1-7e562cf191d8@raspberrypi.com> <4950196.GXAFRqVoOG@steina-w>
Message-ID: <CAPY8ntCeYOtBhEKCcygsT-aAHJ8rxo5qP0NdjE9DMJmHCxZzsA@mail.gmail.com>

Hi Alexander

On Thu, 5 Dec 2024 at 15:22, Alexander Stein
<alexander.stein at ew.tq-group.com> wrote:
>
> Hi Dave,
>
> Am Mittwoch, 20. November 2024, 20:17:03 CET schrieb Dave Stevenson:
> > The imx327 only supports up to 29.4dB of analogue gain, vs
> > the imx290 going up to 30dB. Both are in 0.3dB steps.
>
> While I agree for 30dB on imx290, my (maybe outdated) Rev0.2 datasheet says
> up to 27dB in 0.3dB steps.

For IMX327, I have revision E17Z06B93 2019/03/25.

The revision control section for Rev0.3 lists
Page 1: "Correction: Max analog gain 27dB - 29.4dB"
Page 74: "Correction: Max Gain 69dB -> 71.4dB"

The graph in "Gain Adjustment Function" (page 74) also shows values
above 27dB as being purely analogue gain. Certainly 0x62 is red for
analogue, which would be a gain of 29.4dB. The next dot is 0x64 (30dB)
and blue, so we have to trust the text for 0x63 being 29.4dB analogue
and 0.3dB digital gain.

So I'm happy that the limit is 29.4dB.

  Dave

> Despite that this change looks good.
>
> Best regards,
> Alexander
>
> > As we now have model specific config, fix this mismatch,
> > and delete the comment referencing it.
> >
> > Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > ---
> >  drivers/media/i2c/imx290.c | 12 ++++++------
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
> > index ee698c99001d..da654deb444a 100644
> > --- a/drivers/media/i2c/imx290.c
> > +++ b/drivers/media/i2c/imx290.c
> > @@ -176,6 +176,7 @@ struct imx290_model_info {
> >       enum imx290_colour_variant colour_variant;
> >       const struct cci_reg_sequence *init_regs;
> >       size_t init_regs_num;
> > +     unsigned int max_analog_gain;
> >       const char *name;
> >  };
> >
> > @@ -876,14 +877,10 @@ static int imx290_ctrl_init(struct imx290 *imx290)
> >        * up to 72.0dB (240) add further digital gain. Limit the range to
> >        * analog gain only, support for digital gain can be added separately
> >        * if needed.
> > -      *
> > -      * The IMX327 and IMX462 are largely compatible with the IMX290, but
> > -      * have an analog gain range of 0.0dB to 29.4dB and 42dB of digital
> > -      * gain. When support for those sensors gets added to the driver, the
> > -      * gain control should be adjusted accordingly.
> >        */
> >       v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
> > -                       V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0);
> > +                       V4L2_CID_ANALOGUE_GAIN, 0,
> > +                       imx290->model->max_analog_gain, 1, 0);
> >
> >       /*
> >        * Correct range will be determined through imx290_ctrl_update setting
> > @@ -1441,18 +1438,21 @@ static const struct imx290_model_info imx290_models[] = {
> >               .colour_variant = IMX290_VARIANT_COLOUR,
> >               .init_regs = imx290_global_init_settings_290,
> >               .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290),
> > +             .max_analog_gain = 100,
> >               .name = "imx290",
> >       },
> >       [IMX290_MODEL_IMX290LLR] = {
> >               .colour_variant = IMX290_VARIANT_MONO,
> >               .init_regs = imx290_global_init_settings_290,
> >               .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290),
> > +             .max_analog_gain = 100,
> >               .name = "imx290",
> >       },
> >       [IMX290_MODEL_IMX327LQR] = {
> >               .colour_variant = IMX290_VARIANT_COLOUR,
> >               .init_regs = imx290_global_init_settings_327,
> >               .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_327),
> > +             .max_analog_gain = 98,
> >               .name = "imx327",
> >       },
> >  };
> >
> >
>
>
> --
> 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 jgg at nvidia.com  Thu Dec  5 07:40:15 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu,  5 Dec 2024 11:40:15 -0400
Subject: [PATCH] iommu/arm-smmuv3: Update comments about ATS and bypass
Message-ID: <0-v1-f27174f44f39+27a33-smmuv3_ats_note_jgg@nvidia.com>

The SMMUv3 spec has a note that BYPASS and ATS don't work together under
the STE EATS field definition. However there is another section "13.6.4
Full ATS skipping stage 1" that explains under certain conditions BYPASS
and ATS do work together if the STE is using S1DSS to select BYPASS and
the CD table has the possibility for a substream.

When these comments were written the understanding was that all forms of
BYPASS just didn't work and this was to be a future problem to solve.

It turns out that ATS and IDENTITY will always work just fine:

 - If STE.Config = BYPASS then the PCI ATS is disabled

 - If a PASID domain is attached then S1DSS = BYPASS and ATS will be
   enabled. This meets the requirements of 13.6.4 to automatically
   generate 1:1 ATS replies on the RID.

Update the comments to reflect this.

Fixes: 7497f4211f4f ("iommu/arm-smmu-v3: Make changing domains be hitless for ATS")
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 17 ++++++++++++-----
 1 file changed, 12 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 e4ebd9e12ad468..7605b264fbf983 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2745,9 +2745,14 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
 		 * 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). Thus ATS can only be
-		 * enabled if we have arm_smmu_domain, those always have page
-		 * tables.
+		 * (IHI0070Ea 5.2 Stream Table Entry).
+		 *
+		 * However, if we have installed a CD table and are using S1DSS
+		 * then ATS will work in S1DSS bypass. See "13.6.4 Full ATS
+		 * skipping stage 1".
+		 *
+		 * Disable ATS if we are going to create a normal 0b100 bypass
+		 * STE.
 		 */
 		state->ats_enabled = !state->disable_ats &&
 				     arm_smmu_ats_supported(master);
@@ -3070,8 +3075,10 @@ static void arm_smmu_attach_dev_ste(struct iommu_domain *domain,
 	if (arm_smmu_ssids_in_use(&master->cd_table)) {
 		/*
 		 * If a CD table has to be present then we need to run with ATS
-		 * on even though the RID will fail ATS queries with UR. This is
-		 * because we have no idea what the PASID's need.
+		 * on because we have to assume a PASID is using ATS. For
+		 * IDENTITY this will setup things so that S1DSS=bypass which
+		 * follows the explanation in "13.6.4 Full ATS skipping stage 1"
+		 * and allows for ATS on the RID to work.
 		 */
 		state.cd_needs_ats = true;
 		arm_smmu_attach_prepare(&state, domain);

base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
-- 
2.43.0



From alexander.stein at ew.tq-group.com  Thu Dec  5 07:39:30 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Thu, 05 Dec 2024 16:39:30 +0100
Subject: [PATCH v2 1/4] media: i2c: imx290: Limit analogue gain according to module
In-Reply-To: <CAPY8ntCeYOtBhEKCcygsT-aAHJ8rxo5qP0NdjE9DMJmHCxZzsA@mail.gmail.com>
References: <20241120-media-imx290-imx462-v2-0-7e562cf191d8@raspberrypi.com> <4950196.GXAFRqVoOG@steina-w> <CAPY8ntCeYOtBhEKCcygsT-aAHJ8rxo5qP0NdjE9DMJmHCxZzsA@mail.gmail.com>
Message-ID: <2214258.irdbgypaU6@steina-w>

Hi Dave,

Am Donnerstag, 5. Dezember 2024, 16:37:01 CET schrieb Dave Stevenson:
> Hi Alexander
> 
> On Thu, 5 Dec 2024 at 15:22, Alexander Stein
> <alexander.stein at ew.tq-group.com> wrote:
> >
> > Hi Dave,
> >
> > Am Mittwoch, 20. November 2024, 20:17:03 CET schrieb Dave Stevenson:
> > > The imx327 only supports up to 29.4dB of analogue gain, vs
> > > the imx290 going up to 30dB. Both are in 0.3dB steps.
> >
> > While I agree for 30dB on imx290, my (maybe outdated) Rev0.2 datasheet says
> > up to 27dB in 0.3dB steps.
> 
> For IMX327, I have revision E17Z06B93 2019/03/25.
> 
> The revision control section for Rev0.3 lists
> Page 1: "Correction: Max analog gain 27dB - 29.4dB"
> Page 74: "Correction: Max Gain 69dB -> 71.4dB"
> 
> The graph in "Gain Adjustment Function" (page 74) also shows values
> above 27dB as being purely analogue gain. Certainly 0x62 is red for
> analogue, which would be a gain of 29.4dB. The next dot is 0x64 (30dB)
> and blue, so we have to trust the text for 0x63 being 29.4dB analogue
> and 0.3dB digital gain.
> 
> So I'm happy that the limit is 29.4dB.

Okay, this is a newer datasheet. So assume this is correct.

Thanks for clarification.
Reviewed-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Best regards,
Alexander


>   Dave
> 
> > Despite that this change looks good.
> >
> > Best regards,
> > Alexander
> >
> > > As we now have model specific config, fix this mismatch,
> > > and delete the comment referencing it.
> > >
> > > Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> > > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > > ---
> > >  drivers/media/i2c/imx290.c | 12 ++++++------
> > >  1 file changed, 6 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
> > > index ee698c99001d..da654deb444a 100644
> > > --- a/drivers/media/i2c/imx290.c
> > > +++ b/drivers/media/i2c/imx290.c
> > > @@ -176,6 +176,7 @@ struct imx290_model_info {
> > >       enum imx290_colour_variant colour_variant;
> > >       const struct cci_reg_sequence *init_regs;
> > >       size_t init_regs_num;
> > > +     unsigned int max_analog_gain;
> > >       const char *name;
> > >  };
> > >
> > > @@ -876,14 +877,10 @@ static int imx290_ctrl_init(struct imx290 *imx290)
> > >        * up to 72.0dB (240) add further digital gain. Limit the range to
> > >        * analog gain only, support for digital gain can be added separately
> > >        * if needed.
> > > -      *
> > > -      * The IMX327 and IMX462 are largely compatible with the IMX290, but
> > > -      * have an analog gain range of 0.0dB to 29.4dB and 42dB of digital
> > > -      * gain. When support for those sensors gets added to the driver, the
> > > -      * gain control should be adjusted accordingly.
> > >        */
> > >       v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
> > > -                       V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0);
> > > +                       V4L2_CID_ANALOGUE_GAIN, 0,
> > > +                       imx290->model->max_analog_gain, 1, 0);
> > >
> > >       /*
> > >        * Correct range will be determined through imx290_ctrl_update setting
> > > @@ -1441,18 +1438,21 @@ static const struct imx290_model_info imx290_models[] = {
> > >               .colour_variant = IMX290_VARIANT_COLOUR,
> > >               .init_regs = imx290_global_init_settings_290,
> > >               .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290),
> > > +             .max_analog_gain = 100,
> > >               .name = "imx290",
> > >       },
> > >       [IMX290_MODEL_IMX290LLR] = {
> > >               .colour_variant = IMX290_VARIANT_MONO,
> > >               .init_regs = imx290_global_init_settings_290,
> > >               .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290),
> > > +             .max_analog_gain = 100,
> > >               .name = "imx290",
> > >       },
> > >       [IMX290_MODEL_IMX327LQR] = {
> > >               .colour_variant = IMX290_VARIANT_COLOUR,
> > >               .init_regs = imx290_global_init_settings_327,
> > >               .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_327),
> > > +             .max_analog_gain = 98,
> > >               .name = "imx327",
> > >       },
> > >  };
> > >
> > >
> >
> >
> > --
> > 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 mark.rutland at arm.com  Thu Dec  5 07:40:57 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 5 Dec 2024 15:40:57 +0000
Subject: [PATCH 2/2] arm64: cpufeature: Add GCS to cpucap_is_possible()
In-Reply-To: <051c017c-a60f-48a7-b09f-07f0f32e48e3@sirena.org.uk>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
 <416c7369fcdce4ebb2a8f12daae234507be27e38.1733406275.git.robin.murphy@arm.com>
 <051c017c-a60f-48a7-b09f-07f0f32e48e3@sirena.org.uk>
Message-ID: <Z1HJiUg60kZP4zPb@J2N7QTR9R3>

On Thu, Dec 05, 2024 at 03:04:11PM +0000, Mark Brown wrote:
> On Thu, Dec 05, 2024 at 01:48:10PM +0000, Robin Murphy wrote:
> >  static inline bool system_supports_gcs(void)
> >  {
> > -	return IS_ENABLED(CONFIG_ARM64_GCS) &&
> > -		alternative_has_cap_unlikely(ARM64_HAS_GCS);
> > +	return alternative_has_cap_unlikely(ARM64_HAS_GCS);
> >  }
> 
> Ah, this is bitrot since the series was on the list for so long.  As
> well as HAFT which Rutland mentioned it looks like _bti_kernel(),
> _irq_prio_masking() and possibly others have the same thing.

In <asm/cpufeature.h>, only system_supports_gcs() and
system_supports_haft() don't use cpucap_is_possible(); all the other
IS_ENABLED() checks are for additional dependent properties, and rely on
the base case being handled in cpucap_is_possible().

In <asm/cpucaps.h> we have:

	static __always_inline bool
	cpucap_is_possible(const unsigned int cap)
	{
		...
		switch (cap) {
		...
		case ARM64_HAS_PAN:
			return IS_ENABLED(CONFIG_ARM64_PAN);
		...
		case ARM64_BTI:
			return IS_ENABLED(CONFIG_ARM64_BTI);
		...
		case ARM64_HAS_GIC_PRIO_MASKING:
			return IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI);
		...
		}
	}

In <asm/cpufeature.h> we have:

	// base case
	static inline bool system_uses_hw_pan(void)
	{
		return alternative_has_cap_unlikely(ARM64_HAS_PAN);
	}

	// additional dependent property
	static inline bool system_uses_ttbr0_pan(void)
	{
		return IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN) &&
		       !system_uses_hw_pan();
	}

	...

	// base case
	static __always_inline bool system_uses_irq_prio_masking(void)
	{
		return alternative_has_cap_unlikely(ARM64_HAS_GIC_PRIO_MASKING);
	}

	// additional dependent property
	static inline bool system_has_prio_mask_debugging(void)
	{
		return IS_ENABLED(CONFIG_ARM64_DEBUG_PRIORITY_MASKING) &&
		       system_uses_irq_prio_masking();
	}

	...

	// base case
	static inline bool system_supports_bti(void)
	{
		return cpus_have_final_cap(ARM64_BTI);
	}

	// additional dependent property
	static inline bool system_supports_bti_kernel(void)
	{
		return IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) &&
			cpus_have_final_boot_cap(ARM64_BTI);
	}

> Ideally we'd have no uses of IS_ENABLED() in these functions so it's a
> bit more obvious.

For the three cases above we can't do that without additional cpucaps,
and I think that'd be worse. I don't see anything we can practically do
other than add comments, and I suspect that's not going to help either.

Mark.


From jgg at nvidia.com  Thu Dec  5 07:43:29 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu,  5 Dec 2024 11:43:29 -0400
Subject: [PATCH 3/3] iommu/arm-smmu-v3: Remove domain_alloc_paging()
In-Reply-To: <0-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
Message-ID: <3-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>

arm_smmu_domain_alloc_paging_flags() with a flags = 0 now does the same
thing as arm_smmu_domain_alloc_paging(), remove
arm_smmu_domain_alloc_paging().

Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 31 ---------------------
 1 file changed, 31 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 00105ccadc8b2b..f285b98f982c14 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -83,8 +83,6 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
 	{ 0, NULL},
 };
 
-static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
-				    struct arm_smmu_device *smmu, u32 flags);
 static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
 
 static void parse_driver_options(struct arm_smmu_device *smmu)
@@ -2359,34 +2357,6 @@ struct arm_smmu_domain *arm_smmu_domain_alloc(void)
 	return smmu_domain;
 }
 
-static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
-{
-	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
-	struct arm_smmu_domain *smmu_domain;
-	int ret;
-
-	/*
-	 * Allocate the domain and initialise some of its data structures.
-	 * We can't really do anything meaningful until we've added a
-	 * master.
-	 */
-	smmu_domain = arm_smmu_domain_alloc();
-	if (IS_ERR(smmu_domain))
-		return ERR_CAST(smmu_domain);
-
-	if (master->smmu->features & ARM_SMMU_FEAT_TRANS_S1)
-		smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
-	else
-		smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
-
-	ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, 0);
-	if (ret) {
-		kfree(smmu_domain);
-		return ERR_PTR(ret);
-	}
-	return &smmu_domain->domain;
-}
-
 static void arm_smmu_domain_free_paging(struct iommu_domain *domain)
 {
 	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
@@ -3549,7 +3519,6 @@ static struct iommu_ops arm_smmu_ops = {
 	.blocked_domain		= &arm_smmu_blocked_domain,
 	.capable		= arm_smmu_capable,
 	.hw_info		= arm_smmu_hw_info,
-	.domain_alloc_paging    = arm_smmu_domain_alloc_paging,
 	.domain_alloc_sva       = arm_smmu_sva_domain_alloc,
 	.domain_alloc_paging_flags = arm_smmu_domain_alloc_paging_flags,
 	.probe_device		= arm_smmu_probe_device,
-- 
2.43.0



From jgg at nvidia.com  Thu Dec  5 07:43:26 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu,  5 Dec 2024 11:43:26 -0400
Subject: [PATCH 0/3] iommu/arm-smmuv3: Update domain_alloc_paging_flags()
Message-ID: <0-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>

The last cycle saw the removal of the NULL device during domain allocation
and the introduction of domain_alloc_paging_flags(). Update smmuv3 to this
new design.

Jason Gunthorpe (3):
  iommu/arm-smmu-v3: Remove arm_smmu_domain_finalise() during attach
  iommu/arm-smmu-v3: Make domain_alloc_paging_flags() directly determine
    the S1/S2
  iommu/arm-smmu-v3: Remove domain_alloc_paging()

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 88 +++++++--------------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  1 -
 2 files changed, 28 insertions(+), 61 deletions(-)


base-commit: 121ea6330bec79ce3376959196360ca7114c7ee7
-- 
2.43.0



From jgg at nvidia.com  Thu Dec  5 07:43:28 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu,  5 Dec 2024 11:43:28 -0400
Subject: [PATCH 2/3] iommu/arm-smmu-v3: Make domain_alloc_paging_flags() directly determine the S1/S2
In-Reply-To: <0-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
Message-ID: <2-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>

The selection of S1/S2 is a bit indirect today, make
domain_alloc_paging_flags() directly decode the flags and select the
correct S1/S2 type.

Directly reject flag combinations the HW doesn't support when processing
the flags.

Fix missing rejection of some flag combinations that are not supported
today (ie NEST_PARENT | DIRTY_TRACKING) by using a switch statement to
list out exactly the combinations that are currently supported.

Move the determination of the stage out of arm_smmu_domain_finalise() and
into both callers. As today the default stage is S1 if supported in HW.

This makes arm_smmu_domain_alloc_paging_flags() self contained and no
longer calling arm_smmu_domain_alloc_paging().

Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 42 +++++++++++++++------
 1 file changed, 30 insertions(+), 12 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 e62c8d0f47a903..00105ccadc8b2b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2374,6 +2374,11 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
 	if (IS_ERR(smmu_domain))
 		return ERR_CAST(smmu_domain);
 
+	if (master->smmu->features & ARM_SMMU_FEAT_TRANS_S1)
+		smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
+	else
+		smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
+
 	ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, 0);
 	if (ret) {
 		kfree(smmu_domain);
@@ -2447,12 +2452,6 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
 				 struct arm_smmu_domain *smmu_domain);
 	bool enable_dirty = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
 
-	/* Restrict the stage to what we can actually support */
-	if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
-		smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
-	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,
@@ -3124,6 +3123,7 @@ arm_smmu_domain_alloc_paging_flags(struct device *dev, u32 flags,
 				   const struct iommu_user_data *user_data)
 {
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct arm_smmu_device *smmu = master->smmu;
 	const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
 				 IOMMU_HWPT_ALLOC_PASID |
 				 IOMMU_HWPT_ALLOC_NEST_PARENT;
@@ -3135,25 +3135,43 @@ arm_smmu_domain_alloc_paging_flags(struct device *dev, u32 flags,
 	if (user_data)
 		return ERR_PTR(-EOPNOTSUPP);
 
-	if (flags & IOMMU_HWPT_ALLOC_PASID)
-		return arm_smmu_domain_alloc_paging(dev);
-
 	smmu_domain = arm_smmu_domain_alloc();
 	if (IS_ERR(smmu_domain))
 		return ERR_CAST(smmu_domain);
 
-	if (flags & IOMMU_HWPT_ALLOC_NEST_PARENT) {
-		if (!(master->smmu->features & ARM_SMMU_FEAT_NESTING)) {
+	switch (flags) {
+	case 0:
+		/* Prefer S1 if available */
+		if (smmu->features & ARM_SMMU_FEAT_TRANS_S1)
+			smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
+		else
+			smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
+		break;
+	case IOMMU_HWPT_ALLOC_NEST_PARENT:
+		if (!(smmu->features & ARM_SMMU_FEAT_NESTING)) {
 			ret = -EOPNOTSUPP;
 			goto err_free;
 		}
 		smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
 		smmu_domain->nest_parent = true;
+		break;
+	case IOMMU_HWPT_ALLOC_DIRTY_TRACKING:
+	case IOMMU_HWPT_ALLOC_DIRTY_TRACKING | IOMMU_HWPT_ALLOC_PASID:
+	case IOMMU_HWPT_ALLOC_PASID:
+		if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1)) {
+			ret = -EOPNOTSUPP;
+			goto err_free;
+		}
+		smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		goto err_free;
 	}
 
 	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, flags);
+	ret = arm_smmu_domain_finalise(smmu_domain, smmu, flags);
 	if (ret)
 		goto err_free;
 	return &smmu_domain->domain;
-- 
2.43.0



From jgg at nvidia.com  Thu Dec  5 07:43:27 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu,  5 Dec 2024 11:43:27 -0400
Subject: [PATCH 1/3] iommu/arm-smmu-v3: Remove arm_smmu_domain_finalise() during attach
In-Reply-To: <0-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
Message-ID: <1-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>

Domains are now always finalized during allocation because the core code
no longer permits a NULL dev argument to domain_alloc_paging/_flags().

Remove the late finalize during attach that supported domains that were
not fully initialized.

Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 37 +++++----------------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  1 -
 2 files changed, 9 insertions(+), 29 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 7605b264fbf983..e62c8d0f47a903 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2353,7 +2353,6 @@ struct arm_smmu_domain *arm_smmu_domain_alloc(void)
 	if (!smmu_domain)
 		return ERR_PTR(-ENOMEM);
 
-	mutex_init(&smmu_domain->init_mutex);
 	INIT_LIST_HEAD(&smmu_domain->devices);
 	spin_lock_init(&smmu_domain->devices_lock);
 
@@ -2362,7 +2361,9 @@ struct arm_smmu_domain *arm_smmu_domain_alloc(void)
 
 static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
 {
+	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
 	struct arm_smmu_domain *smmu_domain;
+	int ret;
 
 	/*
 	 * Allocate the domain and initialise some of its data structures.
@@ -2373,15 +2374,10 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
 	if (IS_ERR(smmu_domain))
 		return ERR_CAST(smmu_domain);
 
-	if (dev) {
-		struct arm_smmu_master *master = dev_iommu_priv_get(dev);
-		int ret;
-
-		ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, 0);
-		if (ret) {
-			kfree(smmu_domain);
-			return ERR_PTR(ret);
-		}
+	ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, 0);
+	if (ret) {
+		kfree(smmu_domain);
+		return ERR_PTR(ret);
 	}
 	return &smmu_domain->domain;
 }
@@ -2858,15 +2854,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	state.master = master = dev_iommu_priv_get(dev);
 	smmu = master->smmu;
 
-	mutex_lock(&smmu_domain->init_mutex);
-
-	if (!smmu_domain->smmu) {
-		ret = arm_smmu_domain_finalise(smmu_domain, smmu, 0);
-	} else if (smmu_domain->smmu != smmu)
-		ret = -EINVAL;
-
-	mutex_unlock(&smmu_domain->init_mutex);
-	if (ret)
+	if (smmu_domain->smmu != smmu)
 		return ret;
 
 	if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
@@ -2923,16 +2911,9 @@ static int arm_smmu_s1_set_dev_pasid(struct iommu_domain *domain,
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
 	struct arm_smmu_device *smmu = master->smmu;
 	struct arm_smmu_cd target_cd;
-	int ret = 0;
 
-	mutex_lock(&smmu_domain->init_mutex);
-	if (!smmu_domain->smmu)
-		ret = arm_smmu_domain_finalise(smmu_domain, smmu, 0);
-	else if (smmu_domain->smmu != smmu)
-		ret = -EINVAL;
-	mutex_unlock(&smmu_domain->init_mutex);
-	if (ret)
-		return ret;
+	if (smmu_domain->smmu != smmu)
+		return -EINVAL;
 
 	if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1)
 		return -EINVAL;
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 0107d3f333a1cc..e121b30e612f64 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -813,7 +813,6 @@ enum arm_smmu_domain_stage {
 
 struct arm_smmu_domain {
 	struct arm_smmu_device		*smmu;
-	struct mutex			init_mutex; /* Protects smmu pointer */
 
 	struct io_pgtable_ops		*pgtbl_ops;
 	atomic_t			nr_ats_masters;
-- 
2.43.0



From sudeep.holla at arm.com  Thu Dec  5 07:53:06 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 5 Dec 2024 15:53:06 +0000
Subject: [PATCH V5 1/2] firmware: arm_scmi: Add QCOM Generic Vendor
 Protocol documentation
In-Reply-To: <20241115011515.1313447-2-quic_sibis@quicinc.com>
References: <20241115011515.1313447-1-quic_sibis@quicinc.com>
 <20241115011515.1313447-2-quic_sibis@quicinc.com>
Message-ID: <Z1HMYt8kQ72rRMZ0@bogus>

On Fri, Nov 15, 2024 at 06:45:14AM +0530, Sibi Sankar wrote:
> Add QCOM System Control Management Interface (SCMI) Generic Vendor
> Extensions Protocol documentation.
> 
> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
> ---
> 
> v4:
> * Update the protol attributes doc with more information. [Cristian]
> 
>  .../arm_scmi/vendors/qcom/qcom_generic.rst    | 211 ++++++++++++++++++
>  1 file changed, 211 insertions(+)
>  create mode 100644 drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> 
> diff --git a/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> new file mode 100644
> index 000000000000..141bc932e30f
> --- /dev/null
> +++ b/drivers/firmware/arm_scmi/vendors/qcom/qcom_generic.rst
> @@ -0,0 +1,211 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +.. include:: <isonum.txt>
> +
> +===============================================================================
> +QCOM System Control and Management Interface(SCMI) Vendor Protocols Extension
> +===============================================================================
> +
> +:Copyright: |copy| 2024, Qualcomm Innovation Center, Inc. All rights reserved.
> +
> +:Author: Sibi Sankar <quic_sibis at quicinc.com>
> +
> +SCMI_GENERIC: System Control and Management Interface QCOM Generic Vendor Protocol
> +==================================================================================
> +
> +This protocol is intended as a generic way of exposing a number of Qualcomm
> +SoC specific features through a mixture of pre-determined algorithm string and
> +param_id pairs hosted on the SCMI controller. It implements an interface compliant
> +with the Arm SCMI Specification with additional vendor specific commands as
> +detailed below.
> +
> +Commands:
> +_________
> +
> +PROTOCOL_VERSION
> +~~~~~~~~~~~~~~~~
> +
> +message_id: 0x0
> +protocol_id: 0x80
> +
> ++---------------+--------------------------------------------------------------+
> +|Return values                                                                 |
> ++---------------+--------------------------------------------------------------+
> +|Name           |Description                                                   |
> ++---------------+--------------------------------------------------------------+
> +|int32 status   |See ARM SCMI Specification for status code definitions.       |
> ++---------------+--------------------------------------------------------------+
> +|uint32 version |For this revision of the specification, this value must be    |
> +|               |0x10000.                                                      |
> ++---------------+--------------------------------------------------------------+
> +
> +PROTOCOL_ATTRIBUTES
> +~~~~~~~~~~~~~~~~~~~
> +
> +message_id: 0x1
> +protocol_id: 0x80
> +
> ++---------------+--------------------------------------------------------------+
> +|Return values                                                                 |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|int32 status      |See ARM SCMI Specification for status code definitions.    |
> ++------------------+-----------------------------------------------------------+
> +|uint32 attributes |Bits[31:16] Reserved, must be to 0.                        |
> +|                  |Bits[15:8] Number of agents in the system                  |
> +|                  |Bits[7:0] Number of vendor protocols in the system         |
> ++------------------+-----------------------------------------------------------+
> +
> +PROTOCOL_MESSAGE_ATTRIBUTES
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +message_id: 0x2
> +protocol_id: 0x80
> +
> ++---------------+--------------------------------------------------------------+
> +|Return values                                                                 |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|int32 status      |See ARM SCMI Specification for status code definitions.    |
> ++------------------+-----------------------------------------------------------+
> +|uint32 attributes |For all message id's the parameter has a value of 0.       |
> ++------------------+-----------------------------------------------------------+
> +
> +QCOM_SCMI_SET_PARAM
> +~~~~~~~~~~~~~~~~~~~
>

I can understand the missing description for the above commands, but for the
list below, no. What does QCOM_SCMI_SET_PARAM do exactly ? All I can
understand is the syntax of the interface with below details. What is the
algorithm string ? Is it fixed or choice of the caller ? If fixed, can we
have that list here ?

> +message_id: 0x10
> +protocol_id: 0x80
> +
> ++------------------+-----------------------------------------------------------+
> +|Parameters                                                                    |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|uint32 ext_id     |Reserved, must be zero.                                    |
> ++------------------+-----------------------------------------------------------+
> +|uint32 algo_low   |Lower 32-bit value of the algorithm string.                |
> ++------------------+-----------------------------------------------------------+
> +|uint32 algo_high  |Upper 32-bit value of the algorithm string.                |
> ++------------------+-----------------------------------------------------------+
> +|uint32 param_id   |Serves as the token message id for the algorithm string    |
> +|                  |and is used to set various parameters supported by it.     |

And how is it related to the algorithm string ? Sorry details please. Based on
the quality firmware we have seen so far, I will be more pedantic, you need to
be patient to make any progress and I don't want to deal with the Qcom
firmware mess with all these. I will make you specify every single detail and
the code will just be compliant with that. Anything else will be firmware bug
that needs to be fixed in the firmware. Sorry, I don't see any other approach
will make anyone's life easier here.

> ++------------------+-----------------------------------------------------------+
> +|uint32 buf[]      |Serves as the payload for the specified param_id and       |
> +|                  |algorithm string pair.                                     |
> ++------------------+-----------------------------------------------------------+
> +|Return values                                                                 |
> ++------------------+-----------------------------------------------------------+
> +|Name              |Description                                                |
> ++------------------+-----------------------------------------------------------+
> +|int32 status      |SUCCESS: if the param_id and buf[] is parsed successfully  |
> +|                  |by the chosen algorithm string.                            |
> +|                  |NOT_SUPPORTED: if the algorithm string does not have any   |
> +|                  |matches.

So there is a fixed list from the above statement IIUC. So kindly list them
here in this document. I may need to follow the last version but I would
prefer you to explicitly mention how is the MEMLAT protocol in the previous
version gets used here ? I just can't understand that from these description.

> +
> +QCOM_SCMI_START_ACTIVITY
> +~~~~~~~~~~~~~~~~~~~~~~~~
> 

What is this activity ? How will the firmware know what is that ? All possible
details please if there are all hidden in the buffer too.

-- 
Regards,
Sudeep


From broonie at kernel.org  Thu Dec  5 07:52:34 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 5 Dec 2024 15:52:34 +0000
Subject: [PATCH 2/2] arm64: cpufeature: Add GCS to cpucap_is_possible()
In-Reply-To: <Z1HJiUg60kZP4zPb@J2N7QTR9R3>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
 <416c7369fcdce4ebb2a8f12daae234507be27e38.1733406275.git.robin.murphy@arm.com>
 <051c017c-a60f-48a7-b09f-07f0f32e48e3@sirena.org.uk>
 <Z1HJiUg60kZP4zPb@J2N7QTR9R3>
Message-ID: <1e967066-c89d-4b0d-b055-356cd688f72a@sirena.org.uk>

On Thu, Dec 05, 2024 at 03:40:57PM +0000, Mark Rutland wrote:

> In <asm/cpufeature.h>, only system_supports_gcs() and
> system_supports_haft() don't use cpucap_is_possible(); all the other
> IS_ENABLED() checks are for additional dependent properties, and rely on
> the base case being handled in cpucap_is_possible().

Ah, yes - I got lost in indirections while checking.  
-------------- 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/20241205/5357b5d6/attachment.sig>

From johan at kernel.org  Thu Dec  5 07:52:57 2024
From: johan at kernel.org (Johan Hovold)
Date: Thu, 5 Dec 2024 16:52:57 +0100
Subject: [PATCH V4 0/5] arm_scmi: vendors: Qualcomm Generic Vendor
 Extensions
In-Reply-To: <d61bb7bc-d824-883a-4edd-109ae74076c1@quicinc.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <ZytnRc94iKUfMYH0@hovoldconsulting.com>
 <ZyvLktLUZOGP-LH5@pluto>
 <Zy4qvedrmkRdPR3x@hovoldconsulting.com>
 <8d42682b-0fa7-3962-da12-728cfe64903b@quicinc.com>
 <Z0BC203BhGEmXcJi@hovoldconsulting.com>
 <d61bb7bc-d824-883a-4edd-109ae74076c1@quicinc.com>
Message-ID: <Z1HMWUa_QCsNA1-Q@hovoldconsulting.com>

On Thu, Dec 05, 2024 at 04:26:55PM +0530, Sibi Sankar wrote:
> On 11/22/24 14:07, Johan Hovold wrote:

> > I have a Lenovo ThinkPad T14s set up now so I gave this series a spin
> > there too, and there I do *not* see the above mentioned -EOPNOSUPP error
> > and the memlat driver probes successfully.
> > 
> > On the other hand, this series seems to have no effect on a kernel
> > compilation benchmark. Is that expected?
> 
> I can have a look at your tree. But memlat in general
> depends on the cpu frequency when your benchmarks max
> the cpu's the ddr/llcc are scaled accordingly by it.

A kernel compilation should max out the CPU frequency on all cores.

> > And does this mean that you should stick with the uppercase "MEMLAT"
> > string after all? The firmware on my CRD is not the latest one, but I am
> > using the latest available firmware for the T14s.
> 
> We should stick with "memlat" if we run into a device in the
> wild that doesn't support "MEMLAT"

Ok. So the updated firmware supports both strings?

Johan


From robin.murphy at arm.com  Thu Dec  5 07:55:11 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 5 Dec 2024 15:55:11 +0000
Subject: [PATCH 2/2] arm64: cpufeature: Add GCS to cpucap_is_possible()
In-Reply-To: <Z1HF3i-mAAXDHKUP@arm.com>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
 <416c7369fcdce4ebb2a8f12daae234507be27e38.1733406275.git.robin.murphy@arm.com>
 <051c017c-a60f-48a7-b09f-07f0f32e48e3@sirena.org.uk>
 <Z1HF3i-mAAXDHKUP@arm.com>
Message-ID: <6129a590-6b1b-4368-8bcc-a09a8754bbe5@arm.com>

On 05/12/2024 3:25 pm, Catalin Marinas wrote:
> On Thu, Dec 05, 2024 at 03:04:11PM +0000, Mark Brown wrote:
>> On Thu, Dec 05, 2024 at 01:48:10PM +0000, Robin Murphy wrote:
>>> Since system_supports_gcs() ends up referring to cpucap_is_possible(),
>>> teach the latter about GCS for consistency with similar features.
>>
>> Not clear why this is part of a series, there's no obvious relationship
>> with patch 1?
> 
> No, probably Robing forgot to pass --no-thread to git.

Yeah, this was just a tangent from poking around figuring out how to 
detect GCS being enabled for the main patch.

>>>   static inline bool system_supports_gcs(void)
>>>   {
>>> -	return IS_ENABLED(CONFIG_ARM64_GCS) &&
>>> -		alternative_has_cap_unlikely(ARM64_HAS_GCS);
>>> +	return alternative_has_cap_unlikely(ARM64_HAS_GCS);
>>>   }
>>
>> Ah, this is bitrot since the series was on the list for so long.  As
>> well as HAFT which Rutland mentioned it looks like _bti_kernel(),
>> _irq_prio_masking() and possibly others have the same thing.  Ideally
>> we'd have no uses of IS_ENABLED() in these functions so it's a bit more
>> obvious.  In any case
>>
>> Reviewed-by: Mark Brown <broonie at kernel.org>
> 
> Thanks. This patch will go in via the arm64 tree. I'll leave the other
> for the smmu tree.

Thanks!

Robin.


From krzk at kernel.org  Thu Dec  5 07:59:09 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 16:59:09 +0100
Subject: [PATCH v1] dt-bindings: dma: st-stm32-dmamux: Add description for
 dma-cell values
In-Reply-To: <CADRqkYAaCYvo3ybGdKO1F_y9jFEcwTBxZzRN-Av-adq_4fVu6g@mail.gmail.com>
References: <CADRqkYAaCYvo3ybGdKO1F_y9jFEcwTBxZzRN-Av-adq_4fVu6g@mail.gmail.com>
Message-ID: <d53538ea-f846-4a6a-bc14-22ec7ee57e53@kernel.org>

On 05/12/2024 16:32, Ken Sloat wrote:
> The dma-cell values for the stm32-dmamux are used to craft the DMA spec
> for the actual controller. These values are currently undocumented
> leaving the user to reverse engineer the driver in order to determine
> their meaning. Add a basic description, while avoiding duplicating
> information by pointing the user to the associated DMA docs that
> describe the fields in depth.
> 
> Signed-off-by: Ken Sloat <ksloat at cornersoftsolutions.com>
> ---
> .../bindings/dma/stm32/st,stm32-dmamux.yaml | 11 +++++++++++
> 1 file changed, 11 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
> b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
> index f26c914a3a9a..aa2e52027ee6 100644
> --- a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
> +++ b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
> @@ -15,6 +15,17 @@ allOf:
> properties:
> "#dma-cells":
> const: 3

Your patch is corrupted. Please use git send-email or b4 or b4+relay.

> + description: |
> + Should be set to <3> with each cell representing the following:

Drop this part, const says this.

> + 1. The mux input number/line for the request
> + 2. Bitfield representing DMA channel configuration that is passed
> + to the real DMA controller
> + 3. Bitfield representing device dependent DMA features passed to
> + the real DMA controller
> +
> + For bitfield definitions of cells 2 and 3, see the associated
> + bindings doc for the actual DMA controller the mux is connected

This does not sound right. This is the binding for DMA controller, so
you are saying "please look at itself". I suggest to drop this as well.


Best regards,
Krzysztof


From David.Laight at ACULAB.COM  Thu Dec  5 07:59:36 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Thu, 5 Dec 2024 15:59:36 +0000
Subject: arm64: include/linux/compiler_types.h:542:38: error: call to
 '__compiletime_assert_1050' declared with attribute error: clamp() low limit
 min greater than high limit max_avail
In-Reply-To: <8dde5a62-4ce6-4954-86c9-54d961aed6df@stanley.mountain>
References: <CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g@mail.gmail.com>
 <8dde5a62-4ce6-4954-86c9-54d961aed6df@stanley.mountain>
Message-ID: <68a3ca49c2644af5b2995038ca88a51b@AcuMS.aculab.com>

From: Dan Carpenter <dan.carpenter at linaro.org>
> Sent: 05 December 2024 15:16
> 
> Add David to the CC list.

I've been forwarded this one before.
It is not unreasonable really.

Is all stems from order_base_2(totalram_pages()).
order_base_2(n) is 'n > 1 ? ilog2(n - 1) + 1 : 0'.
And the compiler is generating two copies of the code.
(Basically optimising for the zero case.)
And the one for totalram_pages() being zero hits the check in clamp().

Flipping to clamp(max_avail, min, max) will stop it bleating.

More interesting would be 'launder' the 0 in order_base_2().
By adding something like:
#define optimiser_hide_val(x) ({ \
	__auto_type(_x) = (x); \
	optimiser_hide_var(_x); \
	_x; \
})
and change order_base_2() to be:
	n > 1 ? ilog2(n - 1) + 1 : optimiser_hide_val(0);
(ISTR there is a split for constant v non-constant before then.)

	David

> 
> regards,
> dan carpenter
> 
> On Thu, Dec 05, 2024 at 08:15:13PM +0530, Naresh Kamboju wrote:
> > The arm64 build started failing from Linux next-20241203 tag with gcc-8
> > due to following build warnings / errors.
> >
> > First seen on Linux next-20241203 tag
> > GOOD: Linux next-20241128 tag
> > BAD: Linux next-20241203 tag and next-20241205 tag
> >
> > * arm64, build
> >   - gcc-8-defconfig
> >   - gcc-8-defconfig-40bc7ee5
> >
> > Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>
> >
> > Build log:
> > ===========
> > net/netfilter/ipvs/ip_vs_conn.c: In function 'ip_vs_conn_init':
> > include/linux/compiler_types.h:542:38: error: call to
> > '__compiletime_assert_1050' declared with attribute error: clamp() low
> > limit min greater than high limit max_avail
> >   _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
> >                                       ^
> > include/linux/compiler_types.h:523:4: note: in definition of macro
> > '__compiletime_assert'
> >     prefix ## suffix();    \
> >     ^~~~~~
> > include/linux/compiler_types.h:542:2: note: in expansion of macro
> > '_compiletime_assert'
> >   _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
> >   ^~~~~~~~~~~~~~~~~~~
> > include/linux/build_bug.h:39:37: note: in expansion of macro
> > 'compiletime_assert'
> >  #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> >                                      ^~~~~~~~~~~~~~~~~~
> > include/linux/minmax.h:188:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> >   BUILD_BUG_ON_MSG(statically_true(ulo > uhi),    \
> >   ^~~~~~~~~~~~~~~~
> > include/linux/minmax.h:195:2: note: in expansion of macro '__clamp_once'
> >   __clamp_once(type, val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_),
> > __UNIQUE_ID(h_))
> >   ^~~~~~~~~~~~
> > include/linux/minmax.h:206:28: note: in expansion of macro '__careful_clamp'
> >  #define clamp(val, lo, hi) __careful_clamp(__auto_type, val, lo, hi)
> >                             ^~~~~~~~~~~~~~~
> > net/netfilter/ipvs/ip_vs_conn.c:1498:8: note: in expansion of macro 'clamp'
> >   max = clamp(max, min, max_avail);
> >         ^~~~~
> >
> > Links:
> > ---
> > - https://storage.tuxsuite.com/public/linaro/lkft/builds/2pjAOE9K3Dz9gRywrldKTyaXQoT/
> > - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-
> 20241203/testrun/26189105/suite/build/test/gcc-8-defconfig/log
> > - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-
> 20241203/testrun/26189105/suite/build/test/gcc-8-defconfig/details/
> > - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-
> 20241203/testrun/26189105/suite/build/test/gcc-8-defconfig/history/
> >
> > Steps to reproduce:
> > ------------
> > # tuxmake --runtime podman --target-arch arm64 --toolchain gcc-8
> > --kconfig defconfig
> >
> > metadata:
> > ----
> >   git describe: next-20241203
> >   git repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
> >   git sha: c245a7a79602ccbee780c004c1e4abcda66aec32
> >   kernel config:
> > https://storage.tuxsuite.com/public/linaro/lkft/builds/2pjAOE9K3Dz9gRywrldKTyaXQoT/config
> >   build url: https://storage.tuxsuite.com/public/linaro/lkft/builds/2pjAOE9K3Dz9gRywrldKTyaXQoT/
> >   toolchain: gcc-8
> >   config: gcc-8-defconfig
> >   arch: arm64
> >
> > --
> > Linaro LKFT
> > https://lkft.linaro.org

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From olteanv at gmail.com  Thu Dec  5 08:03:44 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 5 Dec 2024 18:03:44 +0200
Subject: [net-next PATCH v9 1/4] net: dsa: add devm_dsa_register_switch()
In-Reply-To: <20241205145142.29278-2-ansuelsmth@gmail.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-2-ansuelsmth@gmail.com>
Message-ID: <20241205160344.hnshthreouyjecxq@skbuf>

On Thu, Dec 05, 2024 at 03:51:31PM +0100, Christian Marangi wrote:
> Some DSA driver can be simplified if devres takes care of unregistering
> the DSA switch. This permits to effectively drop the remove OP from
> driver that just execute the dsa_unregister_switch() and nothing else.
> 
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> ---

The premise is false. *No* DSA drivers can safely be simplified if
devres is let to take care of calling dsa_unregister_switch().

See, no remove() method of a DSA driver calls dsa_unregister_switch()
directly, but instead they all test dev_get_drvdata() against NULL first.
See this patch set for a full explanation:
https://lore.kernel.org/netdev/20210917133436.553995-1-vladimir.oltean at nxp.com/
but the short explanation is that the parent bus can implement its own
.shutdown() as .remove(), which for the DSA switch device means that
during shutdown/reboot, both .shutdown() *and* .remove() will be called.
The DSA framework is only prepared for either dsa_unregister_switch()
*or* dsa_switch_shutdown() to be called. It doesn't work if *both* are
called, so we have this mechanism where .shutdown() will set the device
drvdata to NULL, so that .remove() will become a no-op. But that mechanism
will become void if we start to drop the driver's remove() and rely on
devres to call dsa_unregister_switch().

Demo for sja1105 driver with the spi-fsl-dspi.c controller driver as parent.

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index f8454f3b6f9c..b9c92a5e5f5f 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -3404,17 +3404,7 @@ static int sja1105_probe(struct spi_device *spi)
 			return -ENOMEM;
 	}
 
-	return dsa_register_switch(priv->ds);
-}
-
-static void sja1105_remove(struct spi_device *spi)
-{
-	struct sja1105_private *priv = spi_get_drvdata(spi);
-
-	if (!priv)
-		return;
-
-	dsa_unregister_switch(priv->ds);
+	return devm_dsa_register_switch(dev, priv->ds);
 }
 
 static void sja1105_shutdown(struct spi_device *spi)
@@ -3466,7 +3456,6 @@ static struct spi_driver sja1105_driver = {
 	},
 	.id_table = sja1105_spi_ids,
 	.probe  = sja1105_probe,
-	.remove = sja1105_remove,
 	.shutdown = sja1105_shutdown,
 };
 

root at debian:~# reboot
[   52.421866] watchdog: watchdog0: watchdog did not stop!
[   52.515700] systemd-shutdown[1]: Using hardware watchdog 'sp805-wdt', version 0, device /dev/watchdog0
[   52.525256] systemd-shutdown[1]: Watchdog running with a timeout of 5min 44s.
[   52.977392] systemd-shutdown[1]: Syncing filesystems and block devices.
[   53.041107] systemd-shutdown[1]: Sending SIGTERM to remaining processes...
[   53.070259] systemd-journald[277]: Received SIGTERM from PID 1 (systemd-shutdow).
[   53.123590] systemd-shutdown[1]: Sending SIGKILL to remaining processes...
[   53.156518] systemd-shutdown[1]: Unmounting file systems.
[   53.170735] (sd-remount)[632]: Remounting '/' read-only with options ''.
[   53.229253] EXT4-fs (mmcblk0p2): re-mounted e092e674-ed6c-4216-b216-58d8390ae85d ro. Quota mode: none.
[   53.313634] systemd-shutdown[1]: All filesystems unmounted.
[   53.319334] systemd-shutdown[1]: Deactivating swaps.
[   53.324625] systemd-shutdown[1]: All swaps deactivated.
[   53.329943] systemd-shutdown[1]: Detaching loop devices.
[   53.342596] systemd-shutdown[1]: All loop devices detached.
[   53.348263] systemd-shutdown[1]: Stopping MD devices.
[   53.354180] systemd-shutdown[1]: All MD devices stopped.
[   53.359633] systemd-shutdown[1]: Detaching DM devices.
[   53.365699] systemd-shutdown[1]: All DM devices detached.
[   53.371178] systemd-shutdown[1]: All filesystems, swaps, loop devices, MD devices and DM devices detached.
[   53.381033] watchdog: watchdog0: watchdog did not stop!
[   53.424144] systemd-shutdown[1]: Syncing filesystems and block devices.
[   53.431313] systemd-shutdown[1]: Rebooting.
[   53.458710] sja1105 spi2.0 sw0p0: Link is Down
[   53.477004] mscc_felix 0000:00:00.5 swp0: Link is Down
[   53.486054] fsl_enetc 0000:00:00.2 eno2: Link is Down
[   53.518865] Unable to handle kernel NULL pointer dereference at virtual address 000000000000002c
[   53.527921] Mem abort info:
[   53.530776]   ESR = 0x0000000096000004
[   53.534612]   EC = 0x25: DABT (current EL), IL = 32 bits
[   53.539988]   SET = 0, FnV = 0
[   53.543124]   EA = 0, S1PTW = 0
[   53.546315]   FSC = 0x04: level 0 translation fault
[   53.551282] Data abort info:
[   53.554211]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[   53.559792]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[   53.564904]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[   53.570476] user pgtable: 4k pages, 48-bit VAs, pgdp=0000002083f73000
[   53.577029] [000000000000002c] pgd=0000000000000000, p4d=0000000000000000
[   53.584079] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[   53.590374] Modules linked in:
[   53.593442] CPU: 0 UID: 0 PID: 1 Comm: systemd-shutdow Tainted: G                 N 6.12.0-10714-gc118f6e3b41e-dirty #2585
[   53.604532] Tainted: [N]=TEST
[   53.613010] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   53.619999] pc : dsa_tree_conduit_admin_state_change+0x44/0xf8
[   53.625864] lr : dsa_unregister_switch+0x194/0x2a8
[   53.630674] sp : ffff80008002b940
[   53.633997] x29: ffff80008002b960 x28: ffff330a40938000 x27: ffff330a40cff818
[   53.641168] x26: ffffba4f5bb05000 x25: 0000000000000001 x24: ffff330a42e19400
[   53.648338] x23: ffff330a42e13668 x22: ffff330a435a5890 x21: ffff330a42dc7000
[   53.655507] x20: ffff330a42e5e080 x19: ffff330a435a5880 x18: 0000000000000000
[   53.662676] x17: ffffba4f5be23118 x16: ffffba4f5bb0d088 x15: 0000000000000108
[   53.669845] x14: ffffba4f5c02b550 x13: 0000000000000004 x12: ffff330a40938908
[   53.677014] x11: ffffba4f5b2ae418 x10: 0000000000000000 x9 : 0000000000000000
[   53.684183] x8 : 0000000000000000 x7 : ffffba4f5917fbe0 x6 : 0000000000000000
[   53.691352] x5 : 0000000000000020 x4 : ffff80008002b620 x3 : 0000000000000000
[   53.698521] x2 : 0000000000000000 x1 : ffff330a42dc7000 x0 : ffff330a435a5880
[   53.705691] Call trace:
[   53.708142]  dsa_tree_conduit_admin_state_change+0x44/0xf8 (P)
[   53.714001]  dsa_unregister_switch+0x194/0x2a8 (L)
[   53.718811]  dsa_unregister_switch+0x194/0x2a8
[   53.723272]  devm_dsa_unregister_switch+0x1c/0x30
[   53.727994]  devm_action_release+0x20/0x38
[   53.732107]  devres_release_all+0xc4/0x130
[   53.736217]  device_release_driver_internal+0x1d0/0x280
[   53.741464]  device_release_driver+0x24/0x38
[   53.745751]  bus_remove_device+0x154/0x170
[   53.749862]  device_del+0x1f8/0x3e8
[   53.753361]  spi_unregister_device+0x90/0xe8
[   53.757646]  __unregister+0x1c/0x38
[   53.761147]  device_for_each_child+0x6c/0xc8
[   53.765432]  spi_unregister_controller+0x50/0x158
[   53.770153]  dspi_remove+0x28/0x98
[   53.773567]  dspi_shutdown+0x1c/0x30
[   53.777154]  platform_shutdown+0x30/0x48
[   53.781089]  device_shutdown+0x174/0x238
[   53.785025]  kernel_restart+0x4c/0x128
[   53.788788]  __arm64_sys_reboot+0x200/0x2e8
[   53.792987]  invoke_syscall+0x4c/0x110
[   53.796752]  el0_svc_common+0xb8/0xf0
[   53.800429]  do_el0_svc+0x28/0x40
[   53.803757]  el0_svc+0x4c/0xc0
[   53.806823]  el0t_64_sync_handler+0x84/0x108
[   53.811109]  el0t_64_sync+0x198/0x1a0
[   53.814786] Code: 0a490949 37000489 37b00468 f9421828 (b9402d09)
[   53.820901] ---[ end trace 0000000000000000 ]---
[   53.825600] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[   53.833306] Kernel Offset: 0x3a4ed7800000 from 0xffff800080000000
[   53.839420] PHYS_OFFSET: 0xfff0cd1640000000
[   53.843615] CPU features: 0x080,0002012c,00800000,8200421b
[   53.849120] Memory Limit: none
[   53.852184] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---

This will need a lot more thought before it makes its appearance as a
tool in the DSA toolbox. Otherwise it is just an avoidable source of
problems.


From broonie at kernel.org  Thu Dec  5 08:05:21 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 05 Dec 2024 16:05:21 +0000
Subject: (subset) [PATCH 0/5] Enable audio output for Genio 700 EVK
 board
In-Reply-To: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
Message-ID: <173341472111.145991.1986411780939561969.b4-ty@kernel.org>

On Thu, 05 Dec 2024 09:13:53 -0300, N?colas F. R. A. Prado wrote:
> This series enables audio output support for the Genio 700 EVK board.
> Patches 1-4 do the required binding and DT changes, and patch 5
> describes the audio DT nodes to get audio output working on the two
> audio jacks, Earphone and Speaker, present on the board.
> 
> The standalone fix in [1] is required in addition to this series in
> order to get the sound card probing.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[2/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Add compatible for mt8390 evk
      commit: 8e22ea5fb8498c52fcc20bbe2070c3aef1a3dff2
[4/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Allow DL_SRC/UL_SRC dai-links
      commit: 5a56323a54b7febcfe82cc5eda840a176647b7cd

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 konrad.dybcio at oss.qualcomm.com  Thu Dec  5 08:05:58 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 5 Dec 2024 17:05:58 +0100
Subject: [PATCH v3 4/7] arm64: dts: qcom: Add base SM8750 dtsi
In-Reply-To: <20241204-sm8750_master_dt-v3-4-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
 <20241204-sm8750_master_dt-v3-4-4d5a8269950b@quicinc.com>
Message-ID: <54e9582b-8570-4272-9d08-6a89a1548bd9@oss.qualcomm.com>

On 5.12.2024 12:18 AM, Melody Olvera wrote:
> Add the base dtsi for the SM8750 SoC describing the CPUs, GCC and
> RPMHCC clock controllers, geni UART, interrupt controller, TLMM,
> reserved memory, interconnects, and SMMU.
> 
> Co-developed-by: Taniya Das <quic_tdas at quicinc.com>
> Signed-off-by: Taniya Das <quic_tdas at quicinc.com>
> Co-developed-by: Jishnu Prakash <quic_jprakash at quicinc.com>
> Signed-off-by: Jishnu Prakash <quic_jprakash at quicinc.com>
> Co-developed-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
> Signed-off-by: Raviteja Laggyshetty <quic_rlaggysh at quicinc.com>
> Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

Konrad


From ksloat at cornersoftsolutions.com  Thu Dec  5 08:07:20 2024
From: ksloat at cornersoftsolutions.com (Ken Sloat)
Date: Thu, 5 Dec 2024 11:07:20 -0500
Subject: [PATCH v1] dt-bindings: dma: st-stm32-dmamux: Add description for
 dma-cell values
In-Reply-To: <d53538ea-f846-4a6a-bc14-22ec7ee57e53@kernel.org>
References: <CADRqkYAaCYvo3ybGdKO1F_y9jFEcwTBxZzRN-Av-adq_4fVu6g@mail.gmail.com>
 <d53538ea-f846-4a6a-bc14-22ec7ee57e53@kernel.org>
Message-ID: <CADRqkYDnDNL_H2CzxjsPOdM++iYp-9Ak3PVFBw2qcjR_M=GeBA@mail.gmail.com>

Hi Krzysztof,

Thanks for reviewing

On Thu, Dec 5, 2024 at 10:59?AM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On 05/12/2024 16:32, Ken Sloat wrote:
> > The dma-cell values for the stm32-dmamux are used to craft the DMA spec
> > for the actual controller. These values are currently undocumented
> > leaving the user to reverse engineer the driver in order to determine
> > their meaning. Add a basic description, while avoiding duplicating
> > information by pointing the user to the associated DMA docs that
> > describe the fields in depth.
> >
> > Signed-off-by: Ken Sloat <ksloat at cornersoftsolutions.com>
> > ---
> > .../bindings/dma/stm32/st,stm32-dmamux.yaml | 11 +++++++++++
> > 1 file changed, 11 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
> > b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
> > index f26c914a3a9a..aa2e52027ee6 100644
> > --- a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
> > +++ b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
> > @@ -15,6 +15,17 @@ allOf:
> > properties:
> > "#dma-cells":
> > const: 3
>
> Your patch is corrupted. Please use git send-email or b4 or b4+relay.

Sorry about that, I will do that. I will wait for any additional
comments and then re-submit.

>
> > + description: |
> > + Should be set to <3> with each cell representing the following:
>
> Drop this part, const says this.

Ok

>
> > + 1. The mux input number/line for the request
> > + 2. Bitfield representing DMA channel configuration that is passed
> > + to the real DMA controller
> > + 3. Bitfield representing device dependent DMA features passed to
> > + the real DMA controller
> > +
> > + For bitfield definitions of cells 2 and 3, see the associated
> > + bindings doc for the actual DMA controller the mux is connected
>
> This does not sound right. This is the binding for DMA controller, so
> you are saying "please look at itself". I suggest to drop this as well.
>

While logically it is the DMA controller, this doc is specifically for
the mux - the DMA controller has its own driver and binding docs in
Documentation/devicetree/bindings/dma/stm32/st,stm32-dma.yaml

I can reference st,stm32-dma.yaml directly, but I was unsure if this
mux IP was used with another DMA controller from ST on a different
SoC.

What do you suggest here?

>
> Best regards,
> Krzysztof

-- 
Sincerely,
Ken Sloat


From Frank.li at nxp.com  Thu Dec  5 08:07:15 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 5 Dec 2024 11:07:15 -0500
Subject: [PATCH v7 2/2] PCI: imx6: Add IOMMU and ITS MSI support for
 i.MX95
In-Reply-To: <Z1F/g/clUxAIGFZ1@lpieralisi>
References: <20241203-imx95_lut-v7-0-d0cd6293225e@nxp.com>
 <20241203-imx95_lut-v7-2-d0cd6293225e@nxp.com>
 <Z1F/g/clUxAIGFZ1@lpieralisi>
Message-ID: <Z1HPs2/PBZY4iq/1@lizhi-Precision-Tower-5810>

On Thu, Dec 05, 2024 at 11:25:07AM +0100, Lorenzo Pieralisi wrote:
> On Tue, Dec 03, 2024 at 06:27:16PM -0500, Frank Li wrote:
> > For the i.MX95, configuration of a LUT is necessary to convert Bus Device
> > Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
> > This involves examining the msi-map and smmu-map to ensure consistent
>
> This involves checking msi-map and iommu-map device tree properties
> to...
>
> > mapping of PCI BDF to the same stream IDs. Subsequently, LUT-related
> > registers are configured. In the absence of an msi-map, the built-in MSI
> > controller is utilized as a fallback.
> >
> > Register a PCI bus callback function to handle enable_device() and
> > disable_device() operations, setting up the LUT whenever a new PCI device
> > is enabled.
> >
> > Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > Change from v5 to v6
> > - change comment rid to RID
> > - some mini change according to mani's feedback
> >
> > Change from v4 to v5
> > - rework commt message
> > - add comment for mutex
> > - s/reqid/rid/
> > - keep only one loop when enable lut
> > - add warning when try to add duplicate rid
> > - Replace hardcode 0xffff with IMX95_PE0_LUT_MASK
> > - Fix some error message
> >
> > Change from v3 to v4
> > - Check target value at of_map_id().
> > - of_node_put() for target.
> > - add case for msi-map exist, but rid entry is not exist.
> >
> > Change from v2 to v3
> > - Use the "target" argument of of_map_id()
> > - Check if rid already in lut table when enable device
> >
> > change from v1 to v2
> > - set callback to pci_host_bridge instead pci->ops.
> > ---
> >  drivers/pci/controller/dwc/pci-imx6.c | 183 +++++++++++++++++++++++++++++++++-
> >  1 file changed, 182 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > index c8d5c90aa4d45..ac5caa7b05075 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -55,6 +55,22 @@
> >  #define IMX95_PE0_GEN_CTRL_3			0x1058
> >  #define IMX95_PCIE_LTSSM_EN			BIT(0)
> >
> > +#define IMX95_PE0_LUT_ACSCTRL			0x1008
> > +#define IMX95_PEO_LUT_RWA			BIT(16)
> > +#define IMX95_PE0_LUT_ENLOC			GENMASK(4, 0)
> > +
> > +#define IMX95_PE0_LUT_DATA1			0x100c
> > +#define IMX95_PE0_LUT_VLD			BIT(31)
> > +#define IMX95_PE0_LUT_DAC_ID			GENMASK(10, 8)
> > +#define IMX95_PE0_LUT_STREAM_ID			GENMASK(5, 0)
> > +
> > +#define IMX95_PE0_LUT_DATA2			0x1010
> > +#define IMX95_PE0_LUT_REQID			GENMASK(31, 16)
> > +#define IMX95_PE0_LUT_MASK			GENMASK(15, 0)
> > +
> > +#define IMX95_SID_MASK				GENMASK(5, 0)
> > +#define IMX95_MAX_LUT				32
> > +
> >  #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
> >
> >  enum imx_pcie_variants {
> > @@ -87,6 +103,7 @@ enum imx_pcie_variants {
> >   * workaround suspend resume on some devices which are affected by this errata.
> >   */
> >  #define IMX_PCIE_FLAG_BROKEN_SUSPEND		BIT(9)
> > +#define IMX_PCIE_FLAG_HAS_LUT			BIT(10)
> >
> >  #define imx_check_flag(pci, val)	(pci->drvdata->flags & val)
> >
> > @@ -139,6 +156,9 @@ struct imx_pcie {
> >  	struct device		*pd_pcie_phy;
> >  	struct phy		*phy;
> >  	const struct imx_pcie_drvdata *drvdata;
> > +
> > +	/* Ensure that only one device's LUT is configured at any given time */
> > +	struct mutex		lock;
> >  };
> >
> >  /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
> > @@ -930,6 +950,159 @@ static void imx_pcie_stop_link(struct dw_pcie *pci)
> >  	imx_pcie_ltssm_disable(dev);
> >  }
> >
> > +static int imx_pcie_add_lut(struct imx_pcie *imx_pcie, u16 rid, u8 sid)
> > +{
> > +	struct dw_pcie *pci = imx_pcie->pci;
> > +	struct device *dev = pci->dev;
> > +	u32 data1, data2;
> > +	int free = -1;
> > +	int i;
> > +
> > +	if (sid >= 64) {
> > +		dev_err(dev, "Invalid SID for index %d\n", sid);
> > +		return -EINVAL;
> > +	}
> > +
> > +	guard(mutex)(&imx_pcie->lock);
> > +
> > +	/*
> > +	 * Iterate through all LUT entries to check for duplicate RID and
> > +	 * identify the first available entry. Configure this available entry
> > +	 * immediately after verification to avoid rescanning it.
> > +	 */
> > +	for (i = 0; i < IMX95_MAX_LUT; i++) {
> > +		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
> > +		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, &data1);
> > +
> > +		if (!(data1 & IMX95_PE0_LUT_VLD)) {
> > +			if (free < 0)
> > +				free = i;
> > +			continue;
> > +		}
> > +
> > +		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
> > +
> > +		/* Do not add duplicate RID */
> > +		if (rid == FIELD_GET(IMX95_PE0_LUT_REQID, data2)) {
> > +			dev_warn(dev, "Existing LUT entry available for RID (%d)", rid);
> > +			return 0;
> > +		}
> > +	}
> > +
> > +	if (free < 0) {
> > +		dev_err(dev, "LUT entry is not available\n");
> > +		return -ENOSPC;
> > +	}
> > +
> > +	data1 = FIELD_PREP(IMX95_PE0_LUT_DAC_ID, 0);
> > +	data1 |= FIELD_PREP(IMX95_PE0_LUT_STREAM_ID, sid);
> > +	data1 |= IMX95_PE0_LUT_VLD;
> > +	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, data1);
> > +
> > +	data2 = IMX95_PE0_LUT_MASK; /* Match all bits of RID */
> > +	data2 |= FIELD_PREP(IMX95_PE0_LUT_REQID, rid);
> > +	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, data2);
> > +
> > +	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, free);
> > +
> > +	return 0;
> > +}
> > +
> > +static void imx_pcie_remove_lut(struct imx_pcie *imx_pcie, u16 rid)
> > +{
> > +	u32 data2;
> > +	int i;
> > +
> > +	guard(mutex)(&imx_pcie->lock);
> > +
> > +	for (i = 0; i < IMX95_MAX_LUT; i++) {
> > +		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
> > +		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
> > +		if (FIELD_GET(IMX95_PE0_LUT_REQID, data2) == rid) {
> > +			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, 0);
> > +			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, 0);
> > +			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i);
> > +
> > +			break;
> > +		}
> > +	}
> > +}
> > +
> > +static int imx_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> > +{
> > +	struct imx_pcie *imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> > +	u32 sid_i, sid_m, rid = pci_dev_id(pdev);
> > +	struct device_node *target;
> > +	struct device *dev;
> > +	int err_i, err_m;
> > +
> > +	dev = imx_pcie->pci->dev;
> > +
> > +	target = NULL;
> > +	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
> > +	if (target)
> > +		of_node_put(target);
> > +	else
> > +		err_i = -EINVAL;
>
> Why ? If target == NULL err_i is already set to a negative value ?

When no "iommu-map" exist, target == NULL, but err_i is 0.
See below err_m table.

>
> > +
> > +	target = NULL;
> > +	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
> > +
> > +	/*
> > +	 * Return failure if msi-map exist and no entry for RID because dwc common
> > +	 * driver will skip setting up built-in MSI controller if msi-map existed.
>
> This is not ideal - to depend on the DWC common driver behaviour.



>
> > +	 *
> > +	 *   err_m      target
> > +	 *	0	NULL		Return failure, function not work.
> > +	 *      !0      NULL		msi-map not exist, use built-in MSI.
> 					^^^^
> "function not work" does not mean anything, sorry. What is it meant to
> say ?

RID is exeed what msi-map'r ranges for example

 RID	MSI   stream ID size
<0x100, &its, 0x8, 	0x1>

If RID is 0x101,  err_m is 0, target is NULL. sid_m will be 0x101, it is
wrong, because max streamID width is 5bits.

So it should return failure for this case.

>
> !=0
>
> > +	 *	0	!NULL		Find one entry.
> > +	 *	!0	!NULL		Invalidate case.
>
> "Find one entry", "Invalidate case", I don't understand what they mean.

Find one entry means get one streamID, as above example, RID = 0x100,
sid will be 0x8.

Invalidate case means never happen, this case doesn't exist.

>
> !=0 !=NULL
>
> > +	 */
> > +	if (!err_m && !target)
> > +		return -EINVAL;
> > +	else if (target)
> > +		of_node_put(target); /* Find entry for RID in msi-map */
> > +
> > +	/*
> > +	 * msi-map        iommu-map
> > +	 *   Y                Y            ITS + SMMU, require the same sid
> > +	 *   Y                N            ITS
> > +	 *   N                Y            DWC MSI Ctrl + SMMU
> > +	 *   N                N            DWC MSI Ctrl
> > +	 */
> > +	if (!err_i && !err_m)
> > +		if ((sid_i & IMX95_SID_MASK) != (sid_m & IMX95_SID_MASK)) {
>
> Here you mask sid_i
>
> > +			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
> > +			return -EINVAL;
> > +		}
> > +
> > +	/*
> > +	 * Both iommu-map and msi-map not exist, use dwc built-in MSI
> > +	 * controller, do nothing here.
> > +	 */
> > +	if (err_i && err_m)
> > +		return 0;
> > +
> > +	if (!err_i)
> > +		return imx_pcie_add_lut(imx_pcie, rid, sid_i);
>
> Here you don't ?

Okay, only need mask sid_m.

>
> Moreover - this would also cater for the case where (!err_i && !err_m) is
> true ?
>
> Probably cleaner to do:
> 	u32 sid;
>
> 	if (err_i && err_m)
> 		return 0;
>
> 	if (!err_i && !err_m) {
> 		if ((sid_i & IMX95_SID_MASK) != (sid_m & IMX95_SID_MASK)) {
> 			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
> 			return -EINVAL;
> 		}
> 	}
>
> 	if (!err_i)
> 		sid = sid_i & IMX95_SID_MASK;
> 	else if (!err_m)
> 		sid = sid_m & IMX95_SID_MASK;
>
> 	return imx_pcie_add_lut(imx_pcie, rid, sid);

Okay.

> > +	else if (!err_m)
> > +		/*
> > +		 * Hardware auto add 2 bits controller id ahead of stream ID,
> > +		 * so mask this 2bits to get stream ID.
> > +		 */
> > +		return imx_pcie_add_lut(imx_pcie, rid, sid_m & IMX95_SID_MASK);
> > +
> > +	return 0;
>
> return 0; is dead code AFAICS.
>
> > +}
> > +
> > +static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> > +{
> > +	struct imx_pcie *imx_pcie;
> > +
> > +	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> > +	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
> > +}
> > +
> >  static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> >  {
> >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > @@ -946,6 +1119,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> >  		}
> >  	}
> >
> > +	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
> > +		pp->bridge->enable_device = imx_pcie_enable_device;
> > +		pp->bridge->disable_device = imx_pcie_disable_device;
> > +	}
> > +
> >  	imx_pcie_assert_core_reset(imx_pcie);
> >
> >  	if (imx_pcie->drvdata->init_phy)
> > @@ -1330,6 +1508,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
> >  	imx_pcie->pci = pci;
> >  	imx_pcie->drvdata = of_device_get_match_data(dev);
> >
> > +	mutex_init(&imx_pcie->lock);
> > +
> >  	/* Find the PHY if one is defined, only imx7d uses it */
> >  	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
> >  	if (np) {
> > @@ -1627,7 +1807,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
> >  	},
> >  	[IMX95] = {
> >  		.variant = IMX95,
> > -		.flags = IMX_PCIE_FLAG_HAS_SERDES,
> > +		.flags = IMX_PCIE_FLAG_HAS_SERDES |
> > +			 IMX_PCIE_FLAG_HAS_LUT,
> >  		.clk_names = imx8mq_clks,
> >  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> >  		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> >
> > --
> > 2.34.1
> >


From krzk at kernel.org  Thu Dec  5 08:09:35 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Dec 2024 17:09:35 +0100
Subject: [PATCH v1] dt-bindings: dma: st-stm32-dmamux: Add description for
 dma-cell values
In-Reply-To: <CADRqkYDnDNL_H2CzxjsPOdM++iYp-9Ak3PVFBw2qcjR_M=GeBA@mail.gmail.com>
References: <CADRqkYAaCYvo3ybGdKO1F_y9jFEcwTBxZzRN-Av-adq_4fVu6g@mail.gmail.com>
 <d53538ea-f846-4a6a-bc14-22ec7ee57e53@kernel.org>
 <CADRqkYDnDNL_H2CzxjsPOdM++iYp-9Ak3PVFBw2qcjR_M=GeBA@mail.gmail.com>
Message-ID: <28d1bb46-ab18-42da-9ca2-ff498c888d66@kernel.org>

On 05/12/2024 17:07, Ken Sloat wrote:
>>> + 1. The mux input number/line for the request
>>> + 2. Bitfield representing DMA channel configuration that is passed
>>> + to the real DMA controller
>>> + 3. Bitfield representing device dependent DMA features passed to
>>> + the real DMA controller
>>> +
>>> + For bitfield definitions of cells 2 and 3, see the associated
>>> + bindings doc for the actual DMA controller the mux is connected
>>
>> This does not sound right. This is the binding for DMA controller, so
>> you are saying "please look at itself". I suggest to drop this as well.
>>
> 
> While logically it is the DMA controller, this doc is specifically for
> the mux - the DMA controller has its own driver and binding docs in
> Documentation/devicetree/bindings/dma/stm32/st,stm32-dma.yaml
> 
> I can reference st,stm32-dma.yaml directly, but I was unsure if this
> mux IP was used with another DMA controller from ST on a different
> SoC.
> 
> What do you suggest here?

Thanks for explanation, I think it is fine.

Best regards,
Krzysztof


From linux at armlinux.org.uk  Thu Dec  5 08:12:03 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 5 Dec 2024 16:12:03 +0000
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241205145142.29278-4-ansuelsmth@gmail.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
Message-ID: <Z1HQ0zYV4aPpW48X@shell.armlinux.org.uk>

hi Christian,

On Thu, Dec 05, 2024 at 03:51:33PM +0100, Christian Marangi wrote:
> diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
> index 2d10b4d6cfbb..6b6d0b7bae72 100644
> --- a/drivers/net/dsa/Kconfig
> +++ b/drivers/net/dsa/Kconfig
> @@ -24,6 +24,15 @@ config NET_DSA_LOOP
>  	  This enables support for a fake mock-up switch chip which
>  	  exercises the DSA APIs.
>  
> +

Niggle - no need for the extra blank line.

> +static int an8855_set_mac_eee(struct dsa_switch *ds, int port,
> +			      struct ethtool_keee *eee)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	u32 reg;
> +	int ret;
> +
> +	if (eee->eee_enabled) {
> +		ret = regmap_read(priv->regmap, AN8855_PMCR_P(port), &reg);
> +		if (ret)
> +			return ret;
> +		/* Force enable EEE if force mode and LINK */
> +		if (reg & AN8855_PMCR_FORCE_MODE &&
> +		    reg & AN8855_PMCR_FORCE_LNK) {
> +			switch (reg & AN8855_PMCR_FORCE_SPEED) {
> +			case AN8855_PMCR_FORCE_SPEED_1000:
> +				reg |= AN8855_PMCR_FORCE_EEE1G;
> +				break;
> +			case AN8855_PMCR_FORCE_SPEED_100:
> +				reg |= AN8855_PMCR_FORCE_EEE100;
> +				break;
> +			default:
> +				break;
> +			}

Does this forcing force EEE to be enabled for the port, irrespective
of the negotiation?

> +			ret = regmap_write(priv->regmap, AN8855_PMCR_P(port), reg);
> +			if (ret)
> +				return ret;
> +		}
> +		ret = regmap_update_bits(priv->regmap, AN8855_PMEEECR_P(port),
> +					 AN8855_LPI_MODE_EN,
> +					 eee->tx_lpi_enabled ? AN8855_LPI_MODE_EN : 0);
> +		if (ret)
> +			return ret;
> +	} else {
> +		ret = regmap_clear_bits(priv->regmap, AN8855_PMCR_P(port),
> +					AN8855_PMCR_FORCE_EEE1G |
> +					AN8855_PMCR_FORCE_EEE100);
> +		if (ret)
> +			return ret;
> +
> +		ret = regmap_clear_bits(priv->regmap, AN8855_PMEEECR_P(port),
> +					AN8855_LPI_MODE_EN);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int an8855_get_mac_eee(struct dsa_switch *ds, int port,
> +			      struct ethtool_keee *eee)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	u32 reg;
> +	int ret;
> +
> +	ret = regmap_read(priv->regmap, AN8855_PMEEECR_P(port), &reg);
> +	if (ret)
> +		return ret;
> +	eee->tx_lpi_enabled = reg & AN8855_LPI_MODE_EN;
> +
> +	ret = regmap_read(priv->regmap, AN8855_CKGCR, &reg);
> +	if (ret)
> +		return ret;
> +	/* Global LPI TXIDLE Threshold, default 60ms (unit 2us) */
> +	eee->tx_lpi_timer = FIELD_GET(AN8855_LPI_TXIDLE_THD_MASK, reg) / 500;

There is no point setting tx_lpi_enabled and tx_lpi_timer, as phylib
will immediately overwrite then in its phy_ethtool_get_eee() method.
In fact, there's no point to the DSA get_mac_eee() method.

> +
> +	ret = regmap_read(priv->regmap, AN8855_PMSR_P(port), &reg);
> +	if (ret)
> +		return ret;

What's the purpose of this read?

> +
> +	return 0;
> +}

Overall, I would suggest not implementing EEE just yet - I sent out a
22 patch RFC patch set last week which implements EEE support in
phylink, and I have another bunch of patches that clean up DSA that
I didn't send, which includes getting rid of the DSA get_mac_eee()
method.

Now that the bulk of the phylink in-band changes have been merged, my
plan is to work through getting the RFC patch set merged - I've sent
out the first four patches today for final review and merging.

I stated some questions in the RFC cover message that everyone ignored,
maybe you could look at that and give your views on the points I raised
there?

> +static struct phylink_pcs *
> +an8855_phylink_mac_select_pcs(struct phylink_config *config,
> +			      phy_interface_t interface)
> +{
> +	struct dsa_port *dp = dsa_phylink_to_port(config);
> +	struct an8855_priv *priv = dp->ds->priv;
> +
> +	switch (interface) {
> +	case PHY_INTERFACE_MODE_SGMII:
> +	case PHY_INTERFACE_MODE_2500BASEX:
> +		return &priv->pcs;
> +	default:
> +		return NULL;
> +	}

Great, exactly what I like to see in mac_select_pcs()!

> +}
> +
> +static void
> +an8855_phylink_mac_config(struct phylink_config *config, unsigned int mode,
> +			  const struct phylink_link_state *state)
> +{
> +	struct dsa_port *dp = dsa_phylink_to_port(config);
> +	struct dsa_switch *ds = dp->ds;
> +	struct an8855_priv *priv;
> +	int port = dp->index;
> +
> +	priv = ds->priv;
> +
> +	/* Nothing to configure for internal ports */
> +	if (port != 5)
> +		return;
> +
> +	regmap_update_bits(priv->regmap, AN8855_PMCR_P(port),
> +			   AN8855_PMCR_IFG_XMIT | AN8855_PMCR_MAC_MODE |
> +			   AN8855_PMCR_BACKOFF_EN | AN8855_PMCR_BACKPR_EN,
> +			   FIELD_PREP(AN8855_PMCR_IFG_XMIT, 0x1) |
> +			   AN8855_PMCR_MAC_MODE | AN8855_PMCR_BACKOFF_EN |
> +			   AN8855_PMCR_BACKPR_EN);
> +}

This looks much better, thanks.

> +
> +static void an8855_phylink_get_caps(struct dsa_switch *ds, int port,
> +				    struct phylink_config *config)
> +{
> +	switch (port) {
> +	case 0:
> +	case 1:
> +	case 2:
> +	case 3:
> +	case 4:
> +		__set_bit(PHY_INTERFACE_MODE_GMII,
> +			  config->supported_interfaces);
> +		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
> +			  config->supported_interfaces);
> +		break;
> +	case 5:
> +		phy_interface_set_rgmii(config->supported_interfaces);
> +		__set_bit(PHY_INTERFACE_MODE_SGMII,
> +			  config->supported_interfaces);
> +		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
> +			  config->supported_interfaces);
> +		break;
> +	}
> +
> +	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
> +				   MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
> +}
> +
> +static void
> +an8855_phylink_mac_link_down(struct phylink_config *config, unsigned int mode,
> +			     phy_interface_t interface)
> +{
> +	struct dsa_port *dp = dsa_phylink_to_port(config);
> +	struct an8855_priv *priv = dp->ds->priv;
> +
> +	/* With autoneg just disable TX/RX else also force link down */
> +	if (phylink_autoneg_inband(mode)) {
> +		regmap_clear_bits(priv->regmap, AN8855_PMCR_P(dp->index),
> +				  AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
> +	} else {
> +		regmap_update_bits(priv->regmap, AN8855_PMCR_P(dp->index),
> +				   AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN |
> +				   AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK,
> +				   AN8855_PMCR_FORCE_MODE);
> +	}
> +}
> +
> +static void
> +an8855_phylink_mac_link_up(struct phylink_config *config,
> +			   struct phy_device *phydev, unsigned int mode,
> +			   phy_interface_t interface, int speed, int duplex,
> +			   bool tx_pause, bool rx_pause)
> +{
> +	struct dsa_port *dp = dsa_phylink_to_port(config);
> +	struct an8855_priv *priv = dp->ds->priv;
> +	int port = dp->index;
> +	u32 reg;
> +
> +	reg = regmap_read(priv->regmap, AN8855_PMCR_P(port), &reg);
> +	if (phylink_autoneg_inband(mode)) {
> +		reg &= ~AN8855_PMCR_FORCE_MODE;
> +	} else {
> +		reg |= AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK;
> +
> +		reg &= ~AN8855_PMCR_FORCE_SPEED;
> +		switch (speed) {
> +		case SPEED_10:
> +			reg |= AN8855_PMCR_FORCE_SPEED_10;
> +			break;
> +		case SPEED_100:
> +			reg |= AN8855_PMCR_FORCE_SPEED_100;
> +			break;
> +		case SPEED_1000:
> +			reg |= AN8855_PMCR_FORCE_SPEED_1000;
> +			break;
> +		case SPEED_2500:
> +			reg |= AN8855_PMCR_FORCE_SPEED_2500;
> +			break;
> +		case SPEED_5000:
> +			dev_err(priv->dev, "Missing support for 5G speed. Aborting...\n");
> +			return;
> +		}
> +
> +		reg &= ~AN8855_PMCR_FORCE_FDX;
> +		if (duplex == DUPLEX_FULL)
> +			reg |= AN8855_PMCR_FORCE_FDX;
> +
> +		reg &= ~AN8855_PMCR_RX_FC_EN;
> +		if (rx_pause || dsa_port_is_cpu(dp))
> +			reg |= AN8855_PMCR_RX_FC_EN;
> +
> +		reg &= ~AN8855_PMCR_TX_FC_EN;
> +		if (rx_pause || dsa_port_is_cpu(dp))
> +			reg |= AN8855_PMCR_TX_FC_EN;
> +
> +		/* Disable any EEE options */
> +		reg &= ~(AN8855_PMCR_FORCE_EEE5G | AN8855_PMCR_FORCE_EEE2P5G |
> +			 AN8855_PMCR_FORCE_EEE1G | AN8855_PMCR_FORCE_EEE100);
> +	}
> +
> +	reg |= AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN;
> +
> +	regmap_write(priv->regmap, AN8855_PMCR_P(port), reg);
> +}

All the above looks fine to me.

> +
> +static void an8855_pcs_get_state(struct phylink_pcs *pcs,
> +				 struct phylink_link_state *state)
> +{
> +	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
> +	u32 val;
> +	int ret;
> +
> +	ret = regmap_read(priv->regmap, AN8855_PMSR_P(AN8855_CPU_PORT), &val);
> +	if (ret < 0) {
> +		state->link = false;
> +		return;
> +	}
> +
> +	state->link = !!(val & AN8855_PMSR_LNK);
> +	state->an_complete = state->link;
> +	state->duplex = (val & AN8855_PMSR_DPX) ? DUPLEX_FULL :
> +						  DUPLEX_HALF;
> +
> +	switch (val & AN8855_PMSR_SPEED) {
> +	case AN8855_PMSR_SPEED_10:
> +		state->speed = SPEED_10;
> +		break;
> +	case AN8855_PMSR_SPEED_100:
> +		state->speed = SPEED_100;
> +		break;
> +	case AN8855_PMSR_SPEED_1000:
> +		state->speed = SPEED_1000;
> +		break;
> +	case AN8855_PMSR_SPEED_2500:
> +		state->speed = SPEED_2500;
> +		break;
> +	case AN8855_PMSR_SPEED_5000:
> +		dev_err(priv->dev, "Missing support for 5G speed. Setting Unknown.\n");
> +		fallthrough;
> +	default:
> +		state->speed = SPEED_UNKNOWN;
> +		break;
> +	}
> +
> +	if (val & AN8855_PMSR_RX_FC)
> +		state->pause |= MLO_PAUSE_RX;
> +	if (val & AN8855_PMSR_TX_FC)
> +		state->pause |= MLO_PAUSE_TX;
> +}
> +
> +static int an8855_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
> +			     phy_interface_t interface,
> +			     const unsigned long *advertising,
> +			     bool permit_pause_to_mac)
> +{
> +	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
> +	u32 val;
> +	int ret;
> +
> +	switch (interface) {
> +	case PHY_INTERFACE_MODE_SGMII:
> +		break;
> +	case PHY_INTERFACE_MODE_2500BASEX:
> +		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> +			dev_err(priv->dev, "in-band negotiation unsupported");
> +			return -EINVAL;
> +		}
> +		break;

Now that we have the phylink in-band changes merged, along with a new
PCS .pcs_inband_caps() method, please implement this method to indicate
that in-band is not supported in 2500BASE-X mode. Phylink will issue a
warning if it attempts to go against that (particularly when e.g. the
PHY demands in-band but the PCS doesn't support it - a case that likely
will never work in practice.)

> +	default:
> +		return -EINVAL;
> +	}
> +
> +	/*                   !!! WELCOME TO HELL !!!                   */
> +
> +	/* TX FIR - improve TX EYE */
> +	ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_10,
> +				 AN8855_RG_DA_QP_TX_FIR_C2_SEL |
> +				 AN8855_RG_DA_QP_TX_FIR_C2_FORCE |
> +				 AN8855_RG_DA_QP_TX_FIR_C1_SEL |
> +				 AN8855_RG_DA_QP_TX_FIR_C1_FORCE,
> +				 AN8855_RG_DA_QP_TX_FIR_C2_SEL |
> +				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C2_FORCE, 0x4) |
> +				 AN8855_RG_DA_QP_TX_FIR_C1_SEL |
> +				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C1_FORCE, 0x0));
> +	if (ret)
> +		return ret;
> +
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +		val = 0x0;
> +	else
> +		val = 0xd;
> +	ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_11,
> +				 AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
> +				 AN8855_RG_DA_QP_TX_FIR_C0B_FORCE,
> +				 AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
> +				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C0B_FORCE, val));
> +	if (ret)
> +		return ret;
> +
> +	/* RX CDR - improve RX Jitter Tolerance */
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +		val = 0x5;
> +	else
> +		val = 0x6;
> +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_BOT_LIM,
> +				 AN8855_RG_QP_CDR_LPF_KP_GAIN |
> +				 AN8855_RG_QP_CDR_LPF_KI_GAIN,
> +				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_KP_GAIN, val) |
> +				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_KI_GAIN, val));
> +	if (ret)
> +		return ret;
> +
> +	/* PLL */
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +		val = 0x1;
> +	else
> +		val = 0x0;
> +	ret = regmap_update_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_1,
> +				 AN8855_RG_TPHY_SPEED,
> +				 FIELD_PREP(AN8855_RG_TPHY_SPEED, val));
> +	if (ret)
> +		return ret;
> +
> +	/* PLL - LPF */
> +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> +				 AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
> +				 AN8855_RG_DA_QP_PLL_FBKSEL_INTF |
> +				 AN8855_RG_DA_QP_PLL_BR_INTF |
> +				 AN8855_RG_DA_QP_PLL_BPD_INTF |
> +				 AN8855_RG_DA_QP_PLL_BPA_INTF |
> +				 AN8855_RG_DA_QP_PLL_BC_INTF,
> +				 AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_FBKSEL_INTF, 0x0) |
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BR_INTF, 0x3) |
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BPD_INTF, 0x0) |
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BPA_INTF, 0x5) |
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BC_INTF, 0x1));
> +	if (ret)
> +		return ret;
> +
> +	/* PLL - ICO */
> +	ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_4,
> +			      AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF);
> +	if (ret)
> +		return ret;
> +	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
> +				AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF);
> +	if (ret)
> +		return ret;
> +
> +	/* PLL - CHP */
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +		val = 0x6;
> +	else
> +		val = 0x4;
> +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> +				 AN8855_RG_DA_QP_PLL_IR_INTF,
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_IR_INTF, val));
> +	if (ret)
> +		return ret;
> +
> +	/* PLL - PFD */
> +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> +				 AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF |
> +				 AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF |
> +				 AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF,
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF, 0x1) |
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF, 0x1));
> +	if (ret)
> +		return ret;
> +
> +	/* PLL - POSTDIV */
> +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> +				 AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF |
> +				 AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF |
> +				 AN8855_RG_DA_QP_PLL_PCK_SEL_INTF,
> +				 AN8855_RG_DA_QP_PLL_PCK_SEL_INTF);
> +	if (ret)
> +		return ret;
> +
> +	/* PLL - SDM */
> +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> +				 AN8855_RG_DA_QP_PLL_SDM_HREN_INTF,
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SDM_HREN_INTF, 0x0));
> +	if (ret)
> +		return ret;
> +	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
> +				AN8855_RG_DA_QP_PLL_SDM_IFM_INTF);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_SS_LCPLL_PWCTL_SETTING_2,
> +				 AN8855_RG_NCPO_ANA_MSB,
> +				 FIELD_PREP(AN8855_RG_NCPO_ANA_MSB, 0x1));
> +	if (ret)
> +		return ret;
> +
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +		val = 0x7a000000;
> +	else
> +		val = 0x48000000;
> +	ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_2,
> +			   FIELD_PREP(AN8855_RG_LCPLL_NCPO_VALUE, val));
> +	if (ret)
> +		return ret;
> +	ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_PCW_1,
> +			   FIELD_PREP(AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON, val));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_clear_bits(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_5,
> +				AN8855_RG_LCPLL_NCPO_CHG);
> +	if (ret)
> +		return ret;
> +	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
> +				AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF);
> +	if (ret)
> +		return ret;
> +
> +	/* PLL - SS */
> +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
> +				 AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF,
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF, 0x0));
> +	if (ret)
> +		return ret;
> +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_4,
> +				 AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF,
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF, 0x0));
> +	if (ret)
> +		return ret;
> +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
> +				 AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF,
> +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF, 0x0));
> +	if (ret)
> +		return ret;
> +
> +	/* PLL - TDC */
> +	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
> +				AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
> +			      AN8855_RG_QP_PLL_SSC_TRI_EN);
> +	if (ret)
> +		return ret;
> +	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
> +			      AN8855_RG_QP_PLL_SSC_PHASE_INI);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_RX_DAC_EN,
> +				 AN8855_RG_QP_SIGDET_HF,
> +				 FIELD_PREP(AN8855_RG_QP_SIGDET_HF, 0x2));
> +	if (ret)
> +		return ret;
> +
> +	/* TCL Disable (only for Co-SIM) */
> +	ret = regmap_clear_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_0,
> +				AN8855_RG_QP_EQ_RX500M_CK_SEL);
> +	if (ret)
> +		return ret;
> +
> +	/* TX Init */
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +		val = 0x4;
> +	else
> +		val = 0x0;
> +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_TX_MODE,
> +				 AN8855_RG_QP_TX_RESERVE |
> +				 AN8855_RG_QP_TX_MODE_16B_EN,
> +				 FIELD_PREP(AN8855_RG_QP_TX_RESERVE, val));
> +	if (ret)
> +		return ret;
> +
> +	/* RX Control/Init */
> +	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_RXAFE_RESERVE,
> +			      AN8855_RG_QP_CDR_PD_10B_EN);
> +	if (ret)
> +		return ret;
> +
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +		val = 0x1;
> +	else
> +		val = 0x2;
> +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_MJV_LIM,
> +				 AN8855_RG_QP_CDR_LPF_RATIO,
> +				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_RATIO, val));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_SETVALUE,
> +				 AN8855_RG_QP_CDR_PR_BUF_IN_SR |
> +				 AN8855_RG_QP_CDR_PR_BETA_SEL,
> +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_BUF_IN_SR, 0x6) |
> +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_BETA_SEL, 0x1));
> +	if (ret)
> +		return ret;
> +
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +		val = 0xf;
> +	else
> +		val = 0xc;
> +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
> +				 AN8855_RG_QP_CDR_PR_DAC_BAND,
> +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_DAC_BAND, val));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
> +				 AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE |
> +				 AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK,
> +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK, 0x19));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF,
> +				 AN8855_RG_QP_CDR_PHYCK_SEL |
> +				 AN8855_RG_QP_CDR_PHYCK_RSTB |
> +				 AN8855_RG_QP_CDR_PHYCK_DIV,
> +				 FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_SEL, 0x2) |
> +				 FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_DIV, 0x21));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_clear_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
> +				AN8855_RG_QP_CDR_PR_XFICK_EN);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
> +				 AN8855_RG_QP_CDR_PR_KBAND_DIV,
> +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV, 0x4));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_26,
> +				 AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
> +				 AN8855_RG_LINK_NE_EN |
> +				 AN8855_RG_LINK_ERRO_EN,
> +				 AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
> +				 AN8855_RG_LINK_ERRO_EN);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RX_DLY_0,
> +				 AN8855_RG_QP_RX_SAOSC_EN_H_DLY |
> +				 AN8855_RG_QP_RX_PI_CAL_EN_H_DLY,
> +				 FIELD_PREP(AN8855_RG_QP_RX_SAOSC_EN_H_DLY, 0x3f) |
> +				 FIELD_PREP(AN8855_RG_QP_RX_PI_CAL_EN_H_DLY, 0x6f));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_42,
> +				 AN8855_RG_QP_EQ_EN_DLY,
> +				 FIELD_PREP(AN8855_RG_QP_EQ_EN_DLY, 0x150));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_2,
> +				 AN8855_RG_QP_RX_EQ_EN_H_DLY,
> +				 FIELD_PREP(AN8855_RG_QP_RX_EQ_EN_H_DLY, 0x150));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_9,
> +				 AN8855_RG_QP_EQ_LEQOSC_DLYCNT,
> +				 FIELD_PREP(AN8855_RG_QP_EQ_LEQOSC_DLYCNT, 0x1));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_8,
> +				 AN8855_RG_DA_QP_SAOSC_DONE_TIME |
> +				 AN8855_RG_DA_QP_LEQOS_EN_TIME,
> +				 FIELD_PREP(AN8855_RG_DA_QP_SAOSC_DONE_TIME, 0x200) |
> +				 FIELD_PREP(AN8855_RG_DA_QP_LEQOS_EN_TIME, 0xfff));
> +	if (ret)
> +		return ret;
> +
> +	/* Frequency meter */
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +		val = 0x10;
> +	else
> +		val = 0x28;
> +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_5,
> +				 AN8855_RG_FREDET_CHK_CYCLE,
> +				 FIELD_PREP(AN8855_RG_FREDET_CHK_CYCLE, val));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_6,
> +				 AN8855_RG_FREDET_GOLDEN_CYCLE,
> +				 FIELD_PREP(AN8855_RG_FREDET_GOLDEN_CYCLE, 0x64));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_7,
> +				 AN8855_RG_FREDET_TOLERATE_CYCLE,
> +				 FIELD_PREP(AN8855_RG_FREDET_TOLERATE_CYCLE, 0x2710));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_0,
> +			      AN8855_RG_PHYA_AUTO_INIT);
> +	if (ret)
> +		return ret;
> +
> +	/* PCS Init */
> +	if (interface == PHY_INTERFACE_MODE_SGMII &&
> +	    neg_mode == PHYLINK_PCS_NEG_INBAND_DISABLED) {
> +		ret = regmap_clear_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_0,
> +					AN8855_RG_SGMII_MODE | AN8855_RG_SGMII_AN_EN);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	ret = regmap_clear_bits(priv->regmap, AN8855_RG_HSGMII_PCS_CTROL_1,
> +				AN8855_RG_TBI_10B_MODE);
> +	if (ret)
> +		return ret;
> +
> +	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> +		/* Set AN Ability - Interrupt */
> +		ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN_FORCE_CL37,
> +				      AN8855_RG_FORCE_AN_DONE);
> +		if (ret)
> +			return ret;
> +
> +		ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN_13,
> +					 AN8855_SGMII_REMOTE_FAULT_DIS |
> +					 AN8855_SGMII_IF_MODE,
> +					 AN8855_SGMII_REMOTE_FAULT_DIS |
> +					 FIELD_PREP(AN8855_SGMII_IF_MODE, 0xb));
> +		if (ret)
> +			return ret;
> +	}
> +
> +	/* Rate Adaption - GMII path config. */
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX) {
> +		ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
> +					AN8855_RG_P0_DIS_MII_MODE);
> +		if (ret)
> +			return ret;
> +	} else {
> +		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> +			ret = regmap_set_bits(priv->regmap, AN8855_MII_RA_AN_ENABLE,
> +					      AN8855_RG_P0_RA_AN_EN);
> +			if (ret)
> +				return ret;
> +		} else {
> +			ret = regmap_update_bits(priv->regmap, AN8855_RG_AN_SGMII_MODE_FORCE,
> +						 AN8855_RG_FORCE_CUR_SGMII_MODE |
> +						 AN8855_RG_FORCE_CUR_SGMII_SEL,
> +						 AN8855_RG_FORCE_CUR_SGMII_SEL);
> +			if (ret)
> +				return ret;
> +
> +			ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
> +						AN8855_RG_P0_MII_RA_RX_EN |
> +						AN8855_RG_P0_MII_RA_TX_EN |
> +						AN8855_RG_P0_MII_RA_RX_MODE |
> +						AN8855_RG_P0_MII_RA_TX_MODE);
> +			if (ret)
> +				return ret;
> +		}
> +
> +		ret = regmap_set_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
> +				      AN8855_RG_P0_MII_MODE);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	ret = regmap_set_bits(priv->regmap, AN8855_RG_RATE_ADAPT_CTRL_0,
> +			      AN8855_RG_RATE_ADAPT_RX_BYPASS |
> +			      AN8855_RG_RATE_ADAPT_TX_BYPASS |
> +			      AN8855_RG_RATE_ADAPT_RX_EN |
> +			      AN8855_RG_RATE_ADAPT_TX_EN);
> +	if (ret)
> +		return ret;
> +
> +	/* Disable AN if not in autoneg */
> +	ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN0, BMCR_ANENABLE,
> +				 neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE :
> +									      0);
> +	if (ret)
> +		return ret;
> +
> +	if (interface == PHY_INTERFACE_MODE_SGMII &&
> +	    neg_mode == PHYLINK_PCS_NEG_INBAND_DISABLED) {
> +		ret = regmap_set_bits(priv->regmap, AN8855_PHY_RX_FORCE_CTRL_0,
> +				      AN8855_RG_FORCE_TXC_SEL);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	/* Force Speed with fixed-link or 2500base-x as doesn't support aneg */
> +	if (interface == PHY_INTERFACE_MODE_2500BASEX ||
> +	    neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
> +		if (interface == PHY_INTERFACE_MODE_2500BASEX)
> +			val = AN8855_RG_LINK_MODE_P0_SPEED_2500;
> +		else
> +			val = AN8855_RG_LINK_MODE_P0_SPEED_1000;
> +		ret = regmap_update_bits(priv->regmap, AN8855_SGMII_STS_CTRL_0,
> +					 AN8855_RG_LINK_MODE_P0 |
> +					 AN8855_RG_FORCE_SPD_MODE_P0,
> +					 val | AN8855_RG_FORCE_SPD_MODE_P0);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	/* bypass flow control to MAC */
> +	ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_0,
> +			   AN8855_RG_DPX_STS_P3 | AN8855_RG_DPX_STS_P2 |
> +			   AN8855_RG_DPX_STS_P1 | AN8855_RG_TXFC_STS_P0 |
> +			   AN8855_RG_RXFC_STS_P0 | AN8855_RG_DPX_STS_P0);
> +	if (ret)
> +		return ret;
> +	ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_2,
> +			   AN8855_RG_RXFC_AN_BYPASS_P3 |
> +			   AN8855_RG_RXFC_AN_BYPASS_P2 |
> +			   AN8855_RG_RXFC_AN_BYPASS_P1 |
> +			   AN8855_RG_TXFC_AN_BYPASS_P3 |
> +			   AN8855_RG_TXFC_AN_BYPASS_P2 |
> +			   AN8855_RG_TXFC_AN_BYPASS_P1 |
> +			   AN8855_RG_DPX_AN_BYPASS_P3 |
> +			   AN8855_RG_DPX_AN_BYPASS_P2 |
> +			   AN8855_RG_DPX_AN_BYPASS_P1 |
> +			   AN8855_RG_DPX_AN_BYPASS_P0);
> +	if (ret)
> +		return ret;

Is the above disruptive to the link if it is executed when the link is
already up? Do you need to re-execute it even when "interface" hasn't
changed?

This gets called to possibly change the PCS advertisement in response
to ethtool -s, so ought not have any link disrupting effects if
nothing has changed.

> +
> +	return 0;
> +}
> +
> +static void an8855_pcs_an_restart(struct phylink_pcs *pcs)
> +{
> +	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
> +
> +	regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN0, BMCR_ANRESTART);

This won't get called for SGMII - Cisco SGMII is merely the PHY telling
the PCS/MAC what was negotiated at the media and how it's going to be
operating the SGMII link. AN restart is a media side thing, so that
would happen at the PHY in that case. I suggest this becomes an empty
no-op function.

Thanks!

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


From konrad.dybcio at oss.qualcomm.com  Thu Dec  5 08:14:10 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 5 Dec 2024 17:14:10 +0100
Subject: [PATCH v3 5/7] arm64: dts: qcom: sm8750: Add pmic dtsi
In-Reply-To: <20241204-sm8750_master_dt-v3-5-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
 <20241204-sm8750_master_dt-v3-5-4d5a8269950b@quicinc.com>
Message-ID: <6d7204a5-a007-4637-8d42-0fad6ede6d4d@oss.qualcomm.com>

On 5.12.2024 12:18 AM, Melody Olvera wrote:
> Add pmic dtsi file for SM8750 SoC describing the pmics and
> their thermal zones.
> 
> Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

Konrad


From lkp at intel.com  Thu Dec  5 08:17:54 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 6 Dec 2024 00:17:54 +0800
Subject: [PATCH v4 4/4] firmware: imx: secvio: Add support for SNVS
 secvio and tamper via SCFW
In-Reply-To: <20241205-secvio-v4-4-5c37cdc39573@nxp.com>
References: <20241205-secvio-v4-4-5c37cdc39573@nxp.com>
Message-ID: <202412060014.woL5otGn-lkp@intel.com>

Hi Vabhav,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 9852d85ec9d492ebef56dc5f229416c925758edc]

url:    https://github.com/intel-lab-lkp/linux/commits/Vabhav-Sharma/dt-bindings-firmware-imx-add-nvmem-phandle/20241205-125909
base:   9852d85ec9d492ebef56dc5f229416c925758edc
patch link:    https://lore.kernel.org/r/20241205-secvio-v4-4-5c37cdc39573%40nxp.com
patch subject: [PATCH v4 4/4] firmware: imx: secvio: Add support for SNVS secvio and tamper via SCFW
config: nios2-randconfig-r063-20241205 (https://download.01.org/0day-ci/archive/20241206/202412060014.woL5otGn-lkp at intel.com/config)
compiler: nios2-linux-gcc (GCC) 14.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>
| Closes: https://lore.kernel.org/oe-kbuild-all/202412060014.woL5otGn-lkp at intel.com/

cocci warnings: (new ones prefixed by >>)
>> drivers/firmware/imx/imx-scu-secvio.c:368:11-29: WARNING opportunity for simple_open, see also structure on line 419

vim +368 drivers/firmware/imx/imx-scu-secvio.c

   367	
 > 368	static int imx_secvio_sc_open(struct inode *node, struct file *filp)
   369	{
   370		filp->private_data = node->i_private;
   371	
   372		return 0;
   373	}
   374	
   375	static long imx_secvio_sc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
   376	{
   377		struct device *dev = file->private_data;
   378		struct secvio_sc_notifier_info info;
   379		int ret;
   380	
   381		switch (cmd) {
   382		case IMX_SECVIO_SC_GET_STATE:
   383			ret = imx_secvio_sc_get_state(dev, &info);
   384			if (ret)
   385				return ret;
   386	
   387			ret = copy_to_user((void __user *)arg, &info, sizeof(info));
   388			if (ret) {
   389				dev_err(dev, "Fail to copy info to user\n");
   390				return -EFAULT;
   391			}
   392			break;
   393		case IMX_SECVIO_SC_CHECK_STATE:
   394			ret = imx_secvio_sc_check_state(dev);
   395			if (ret)
   396				return ret;
   397			break;
   398		case IMX_SECVIO_SC_CLEAR_STATE:
   399			ret = copy_from_user(&info, (void __user *)arg, sizeof(info));
   400			if (ret) {
   401				dev_err(dev, "Fail to copy info from user\n");
   402				return -EFAULT;
   403			}
   404	
   405			ret = imx_secvio_sc_clear_state(dev, info.hpsvs, info.lps,
   406							    info.lptds);
   407			if (ret)
   408				return ret;
   409			break;
   410		default:
   411			ret = -ENOIOCTLCMD;
   412		}
   413	
   414		return ret;
   415	}
   416	
   417	static const struct file_operations imx_secvio_sc_fops = {
   418		.owner = THIS_MODULE,
 > 419		.open = imx_secvio_sc_open,
   420		.unlocked_ioctl = imx_secvio_sc_ioctl,
   421	};
   422	

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


From dario.binacchi at amarulasolutions.com  Thu Dec  5 08:24:23 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 17:24:23 +0100
Subject: [RESEND PATCH v2] drm/mxsfb: Remove generic DRM drivers in probe function
Message-ID: <20241205162432.1803869-1-dario.binacchi@amarulasolutions.com>

Use aperture helpers to remove all generic graphics drivers before
loading mxsfb. Makes mxsfb compatible with simpledrm.

Co-developed-by: Michael Trimarchi <michael at amarulasolutions.com>
Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v2:
- Use aperture_remove_all_conflicting_devices() instead of
  drm_aperture_remove_framebuffers().

 drivers/gpu/drm/mxsfb/mxsfb_drv.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 6b95e4eb3e4e..10da8b54f4c6 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -8,6 +8,7 @@
  * Copyright (C) 2008 Embedded Alley Solutions, Inc All Rights Reserved.
  */
 
+#include <linux/aperture.h>
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
@@ -362,6 +363,15 @@ static int mxsfb_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_free;
 
+	/*
+	 * Remove early framebuffers (ie. simplefb). The framebuffer can be
+	 * located anywhere in RAM
+	 */
+	ret = aperture_remove_all_conflicting_devices(mxsfb_driver.name);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "can't kick out existing framebuffers\n");
+
 	ret = drm_dev_register(drm, 0);
 	if (ret)
 		goto err_unload;
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Thu Dec  5 08:26:04 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Thu,  5 Dec 2024 17:26:04 +0100
Subject: [RESEND PATCH v2] arm64: dts: imx8mn-bsh-smm-s2/pro: add simple-framebuffer
Message-ID: <20241205162612.1804274-1-dario.binacchi@amarulasolutions.com>

Add a simple-framebuffer node for U-Boot to further fill and activate.

Co-developed-by: Michael Trimarchi <michael at amarulasolutions.com>
Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v2:
- Fix the warnings:
  (ranges_format): /chosen:ranges: empty "ranges" property but its #address-cells (1) differs from / (2)
  (ranges_format): /chosen:ranges: empty "ranges" property but its #size-cells (1) differs from / (2)
  by setting both #address-cells and #size-cells to 2.

 .../freescale/imx8mn-bsh-smm-s2-display.dtsi  | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2-display.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2-display.dtsi
index 7675583a6b67..98dec3c42060 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2-display.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2-display.dtsi
@@ -4,6 +4,34 @@
  */
 
 / {
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		framebuffer-panel0 {
+			compatible = "simple-framebuffer";
+			clocks = <&clk IMX8MN_CLK_DISP_PIXEL_ROOT>, /* lcdif */
+				 <&clk IMX8MN_CLK_DISP_APB_ROOT>,
+				 <&clk IMX8MN_CLK_DISP_AXI_ROOT>,
+				 <&clk IMX8MN_VIDEO_PLL1>,
+				 <&clk IMX8MN_CLK_DISP_AXI_ROOT>, /* pgc_dispmix */
+				 <&clk IMX8MN_CLK_DISP_APB_ROOT>,
+				 <&clk IMX8MN_CLK_DISP_AXI>,
+				 <&clk IMX8MN_CLK_DISP_APB>,
+				 <&clk IMX8MN_SYS_PLL2_1000M>,
+				 <&clk IMX8MN_SYS_PLL1_800M>,
+				 <&clk IMX8MN_CLK_DSI_CORE>, /* mipi_disi */
+				 <&clk IMX8MN_CLK_DSI_PHY_REF>;
+
+			power-domains = <&disp_blk_ctrl IMX8MN_DISPBLK_PD_LCDIF>,
+					<&disp_blk_ctrl IMX8MN_DISPBLK_PD_MIPI_DSI>;
+			dvdd-supply = <&reg_3v3_dvdd>;
+			avdd-supply = <&reg_v3v3_avdd>;
+			status = "disabled";
+		};
+	};
+
 	backlight: backlight {
 		compatible = "pwm-backlight";
 		pwms = <&pwm1 0 700000 0>;	/* 700000 ns = 1337Hz */
-- 
2.43.0



From olteanv at gmail.com  Thu Dec  5 08:27:59 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 5 Dec 2024 18:27:59 +0200
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241205145142.29278-4-ansuelsmth@gmail.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
Message-ID: <20241205162759.pm3iz42bhdsvukfm@skbuf>

On Thu, Dec 05, 2024 at 03:51:33PM +0100, Christian Marangi wrote:
> +static int an8855_efuse_read(void *context, unsigned int offset,
> +			     void *val, size_t bytes)
> +{
> +	struct an8855_priv *priv = context;
> +
> +	return regmap_bulk_read(priv->regmap, AN8855_EFUSE_DATA0 + offset,
> +				val, bytes / sizeof(u32));
> +}
> +
> +static struct nvmem_config an8855_nvmem_config = {
> +	.name = "an8855-efuse",
> +	.size = AN8855_EFUSE_CELL * sizeof(u32),
> +	.stride = sizeof(u32),
> +	.word_size = sizeof(u32),
> +	.reg_read = an8855_efuse_read,
> +};
> +
> +static int an8855_sw_register_nvmem(struct an8855_priv *priv)
> +{
> +	struct nvmem_device *nvmem;
> +
> +	an8855_nvmem_config.priv = priv;
> +	an8855_nvmem_config.dev = priv->dev;
> +	nvmem = devm_nvmem_register(priv->dev, &an8855_nvmem_config);
> +	if (IS_ERR(nvmem))
> +		return PTR_ERR(nvmem);
> +
> +	return 0;
> +}

At some point we should enforce the rule that new drivers for switch
SoCs with complex peripherals should use MFD and move all non-networking
peripherals to drivers handled by their respective subsystems.

I don't have the expertise to review a nvmem driver, and the majority of
them are in drivers/nvmem, with a dedicated subsystem and maintainer.
In general I want to make sure it is clear that I don't encourage the
model where DSA owns the entire mdio_device.

What other peripherals are there on this SoC other than an MDIO bus and
an EFUSE? IRQCHIP, GPIOs, LED controller, sensors?

You can take a look at drivers/mfd/ocelot* and
Documentation/devicetree/bindings/mfd/mscc,ocelot.yaml for an example on
how to use mfd for the top-level MDIO device, and DSA as just the driver
for the Ethernet switch component (which will be represented as a
platform_device).


From konrad.dybcio at oss.qualcomm.com  Thu Dec  5 08:28:33 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 5 Dec 2024 17:28:33 +0100
Subject: [PATCH v7 4/5] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <20241204100003.300123-5-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-5-quic_vikramsa@quicinc.com>
Message-ID: <e586b76f-50a7-47cc-9ce6-a37f9b53262f@oss.qualcomm.com>

On 4.12.2024 11:00 AM, Vikram Sharma wrote:
> Add changes to support the camera subsystem on the SC7280.
> 
> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> ---

[...]

(isp@ as mentioned)

> +			interconnects = <&gem_noc  MASTER_APPSS_PROC 0 &cnoc2 SLAVE_CAMERA_CFG 0>,

QCOM_ICC_TAG_ACTIVE_ONLY

> +					<&mmss_noc MASTER_CAMNOC_HF  0 &mc_virt SLAVE_EBI1     0>;

QCOM_ICC_TAG_ALWAYS

> +			interconnect-names = "ahb", "hf_0";
> +
> +			iommus = <&apps_smmu 0x800 0x4e0>;
> +
> +			power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
> +					<&camcc CAM_CC_IFE_1_GDSC>,
> +					<&camcc CAM_CC_IFE_2_GDSC>,
> +					<&camcc CAM_CC_TITAN_TOP_GDSC>;
> +			power-domain-names = "ife0", "ife1", "ife2", "top";

vertical list, please

Konrad


From konrad.dybcio at oss.qualcomm.com  Thu Dec  5 08:30:29 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 5 Dec 2024 17:30:29 +0100
Subject: [PATCH v7 5/5] arm64: dts: qcom:
 qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <20241204100003.300123-6-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-6-quic_vikramsa@quicinc.com>
Message-ID: <cf90f570-57ea-4ce2-9592-82a009f198af@oss.qualcomm.com>

On 4.12.2024 11:00 AM, Vikram Sharma wrote:
> The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
> Enable the IMX577 on the vision mezzanine.
> 
> An example media-ctl pipeline for the imx577 is:
> 
> media-ctl --reset
> media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
> media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
> media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
> media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
> media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
> media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
> 
> yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0
> 
> Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> ---

[...]

> +&camcc {
> +	status = "okay";
> +};

It's already enabled

> +
> +&camss {
> +	vdda-phy-supply = <&vreg_l10c_0p88>;
> +	vdda-pll-supply = <&vreg_l6b_1p2>;
> +	status = "okay";

A newline before status is expected
> +
> +	ports {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		/* The port index denotes CSIPHY id i.e. csiphy3 */
> +		port at 3 {
> +			reg = <3>;
> +			csiphy3_ep: endpoint {

Also between last property and subnode

[...]

> +
> +&tlmm {
> +	cam2_default: cam2-default-state {
> +		rst-pins {
> +			pins = "gpio78";
> +			function = "gpio";
> +			drive-strength = <2>;
> +			bias-disable;
> +		};
> +
> +		mclk-pins {
> +			pins = "gpio67";
> +			function = "cam_mclk";
> +			drive-strength = <2>;
> +			bias-disable;
> +		};

Please sort these by gpio idx

Konrad


From tzimmermann at suse.de  Thu Dec  5 08:32:29 2024
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Thu, 5 Dec 2024 17:32:29 +0100
Subject: [RESEND PATCH v2] drm/mxsfb: Remove generic DRM drivers in probe
 function
In-Reply-To: <20241205162432.1803869-1-dario.binacchi@amarulasolutions.com>
References: <20241205162432.1803869-1-dario.binacchi@amarulasolutions.com>
Message-ID: <1ea567f4-33c2-40a6-9bca-117e4daee8ef@suse.de>




Am 05.12.24 um 17:24 schrieb Dario Binacchi:
> Use aperture helpers to remove all generic graphics drivers before
> loading mxsfb. Makes mxsfb compatible with simpledrm.
>
> Co-developed-by: Michael Trimarchi <michael at amarulasolutions.com>
> Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

Reviewed-by: Thomas Zimmermann <tzimmermann at suse.de>

>
> ---
>
> Changes in v2:
> - Use aperture_remove_all_conflicting_devices() instead of
>    drm_aperture_remove_framebuffers().
>
>   drivers/gpu/drm/mxsfb/mxsfb_drv.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
>
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> index 6b95e4eb3e4e..10da8b54f4c6 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> @@ -8,6 +8,7 @@
>    * Copyright (C) 2008 Embedded Alley Solutions, Inc All Rights Reserved.
>    */
>   
> +#include <linux/aperture.h>
>   #include <linux/clk.h>
>   #include <linux/dma-mapping.h>
>   #include <linux/io.h>
> @@ -362,6 +363,15 @@ static int mxsfb_probe(struct platform_device *pdev)
>   	if (ret)
>   		goto err_free;
>   
> +	/*
> +	 * Remove early framebuffers (ie. simplefb). The framebuffer can be
> +	 * located anywhere in RAM
> +	 */
> +	ret = aperture_remove_all_conflicting_devices(mxsfb_driver.name);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret,
> +				     "can't kick out existing framebuffers\n");
> +
>   	ret = drm_dev_register(drm, 0);
>   	if (ret)
>   		goto err_unload;

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



From robin.murphy at arm.com  Thu Dec  5 08:33:57 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu,  5 Dec 2024 16:33:57 +0000
Subject: [PATCH v2 3/4] iommu/arm-smmu-v3: Clean up more on probe failure
In-Reply-To: <cover.1733406914.git.robin.murphy@arm.com>
References: <cover.1733406914.git.robin.murphy@arm.com>
Message-ID: <5137901958471cf67f2fad5c2229f8a8f1ae901a.1733406914.git.robin.murphy@arm.com>

kmemleak noticed that the iopf queue allocated deep down within
arm_smmu_init_structures() can be leaked by a subsequent error return
from arm_smmu_device_probe(). Furthermore, after arm_smmu_device_reset()
we will also leave the SMMU enabled with an empty Stream Table, silently
blocking all DMA. This proves rather annoying for debugging said probe
failure, so let's handle it a bit better by putting the SMMU back into
(more or less) the same state as if it hadn't probed at all.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---

v2: Squash disable fix, get labels right

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 17 ++++++++++++-----
 1 file changed, 12 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 e1eae4ecfa02..264a686d30cb 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4663,7 +4663,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Initialise in-memory data structures */
 	ret = arm_smmu_init_structures(smmu);
 	if (ret)
-		return ret;
+		goto err_free_iopf;
 
 	/* Record our private device structure */
 	platform_set_drvdata(pdev, smmu);
@@ -4674,22 +4674,29 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Reset the device */
 	ret = arm_smmu_device_reset(smmu);
 	if (ret)
-		return ret;
+		goto err_disable;
 
 	/* And we're up. Go go go! */
 	ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
 				     "smmu3.%pa", &ioaddr);
 	if (ret)
-		return ret;
+		goto err_disable;
 
 	ret = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev);
 	if (ret) {
 		dev_err(dev, "Failed to register iommu\n");
-		iommu_device_sysfs_remove(&smmu->iommu);
-		return ret;
+		goto err_free_sysfs;
 	}
 
 	return 0;
+
+err_free_sysfs:
+	iommu_device_sysfs_remove(&smmu->iommu);
+err_disable:
+	arm_smmu_device_disable(smmu);
+err_free_iopf:
+	iopf_queue_free(smmu->evtq.iopf);
+	return ret;
 }
 
 static void arm_smmu_device_remove(struct platform_device *pdev)
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Thu Dec  5 08:33:58 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu,  5 Dec 2024 16:33:58 +0000
Subject: [PATCH v2 4/4] iommu: Manage driver probe deferral better
In-Reply-To: <cover.1733406914.git.robin.murphy@arm.com>
References: <cover.1733406914.git.robin.murphy@arm.com>
Message-ID: <41fa59f156ef8d196d08fa75c4901e6d4b12e6c4.1733406914.git.robin.murphy@arm.com>

Since iommu_fwspec_init() absorbed the basic driver probe deferral
check to wait for an IOMMU to register, we may as well handle the probe
deferral timeout there as well. The current inconsistency of callers
results in client devices deferring forever on an arm64 ACPI system
where an SMMU has failed its own driver probe.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---

v2: No change

 drivers/iommu/iommu.c    | 2 +-
 drivers/iommu/of_iommu.c | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9bc0c74cca3c..7cd433803bd6 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2819,7 +2819,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode)
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 
 	if (!ops)
-		return -EPROBE_DEFER;
+		return driver_deferred_probe_check_state(dev);
 
 	if (fwspec)
 		return ops == iommu_fwspec_ops(fwspec) ? 0 : -EINVAL;
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index e7a6a1611d19..97987cd78da9 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -29,8 +29,6 @@ static int of_iommu_xlate(struct device *dev,
 		return -ENODEV;
 
 	ret = iommu_fwspec_init(dev, of_fwnode_handle(iommu_spec->np));
-	if (ret == -EPROBE_DEFER)
-		return driver_deferred_probe_check_state(dev);
 	if (ret)
 		return ret;
 
-- 
2.39.2.101.g768bb238c484.dirty



From sudeep.holla at arm.com  Thu Dec  5 08:35:33 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 5 Dec 2024 16:35:33 +0000
Subject: [PATCH V5 0/2] arm_scmi: vendors: Qualcomm Generic Vendor
 Extensions
In-Reply-To: <20241115011515.1313447-1-quic_sibis@quicinc.com>
References: <20241115011515.1313447-1-quic_sibis@quicinc.com>
Message-ID: <Z1HWVfIS-w0OXQHl@bogus>

On Fri, Nov 15, 2024 at 06:45:13AM +0530, Sibi Sankar wrote:
> The QCOM SCMI vendor protocol provides a generic way of exposing a
> number of Qualcomm SoC specific features (like memory bus scaling)
> through a mixture of pre-determined algorithm strings and param_id
> pairs hosted on the SCMI controller. Introduce a client driver that
> uses the memlat algorithm string hosted on QCOM SCMI Vendor Protocol
> to detect memory latency workloads and control frequency/level of
> the various memory buses (DDR/LLCC/DDR_QOS).
> 
> QCOM SCMI Generic Vendor protocol background:
> It was found that a lot of the vendor protocol used internally was
> for debug/internal development purposes that would either be super
> SoC specific or had to be disabled because of some features being
> fused out during production. This lead to a large number of vendor
> protocol numbers being quickly consumed and were never released
> either. Using a generic vendor protocol with functionality abstracted
> behind algorithm strings gave us the flexibility of allowing such
> functionality exist during initial development/debugging while
> still being able to expose functionality like memlat once they have
> matured enough. The param-ids are certainly expected to act as ABI
> for algorithms strings like MEMLAT.
> 
> Thanks in advance for taking time to review the series.
> 
> V4:
> * Splitting the series into vendor protocol and memlat client.
>   Also the move the memlat client implementation back to RFC
>   due to multiple opens.

Sorry if I missed the rationale for the split here from the previous
discussions, but I would like to see the DT bindings if any for all the
users first before I can merge this. I am happy to get this series reviewed
independently but my views might change looking at how it will be used as
I might get better idea looking at the users. I really don't like the
interface as well as the DT bindings that might be enforcing us to define.
I have given my initial comments there.

No need to respin it together immediately or even in future as along as
there is a reference for me to look at.

--
Regards,
Sudeep


From robin.murphy at arm.com  Thu Dec  5 08:33:54 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu,  5 Dec 2024 16:33:54 +0000
Subject: [PATCH v2 0/4] iommu/arm-smmu: Minor probe_device related improvements
Message-ID: <cover.1733406914.git.robin.murphy@arm.com>

v1: https://lore.kernel.org/linux-iommu/cover.1731088789.git.robin.murphy at arm.com

Hi all,

Here's what I probably should have sent instead of rushing v1 out
earlier, now rebased and polished :)

Cheers,
Robin.


Robin Murphy (4):
  iommu/arm-smmu: Make instance lookup robust
  iommu/arm-smmu: Retire probe deferral workaround
  iommu/arm-smmu-v3: Clean up more on probe failure
  iommu: Manage driver probe deferral better

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 21 +++++++----
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 42 +++++++--------------
 drivers/iommu/iommu.c                       |  2 +-
 drivers/iommu/of_iommu.c                    |  2 -
 4 files changed, 29 insertions(+), 38 deletions(-)

-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Thu Dec  5 08:33:55 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu,  5 Dec 2024 16:33:55 +0000
Subject: [PATCH v2 1/4] iommu/arm-smmu: Make instance lookup robust
In-Reply-To: <cover.1733406914.git.robin.murphy@arm.com>
References: <cover.1733406914.git.robin.murphy@arm.com>
Message-ID: <6d7ce1dc31873abdb75c895fb8bd2097cce098b4.1733406914.git.robin.murphy@arm.com>

Relying on the driver list was a cute idea for minimising the scope of
our SMMU device lookups, however it turns out to have a subtle flaw. The
SMMU device only gets added to that list after arm_smmu_device_probe()
returns success, so there's actually no way the iommu_device_register()
call from there could ever work as intended, even if it wasn't already
hampered by the fwspec setup not happening early enough.

Switch both arm_smmu_get_by_fwnode() implementations to use a platform
bus lookup instead, which *will* reliably work. Also make sure that we
don't register SMMUv2 instances until we've fully initialised them, to
avoid similar consequences of the lookup now finding a device with no
drvdata. Moving the error returns is also a perfect excuse to streamline
them with dev_err_probe() in the process.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---

v2: Tweak commit message

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  4 +--
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 31 ++++++++++-----------
 2 files changed, 16 insertions(+), 19 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 a5c7002ff75b..e1eae4ecfa02 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3237,8 +3237,8 @@ static struct platform_driver arm_smmu_driver;
 static
 struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
 {
-	struct device *dev = driver_find_device_by_fwnode(&arm_smmu_driver.driver,
-							  fwnode);
+	struct device *dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
+
 	put_device(dev);
 	return dev ? dev_get_drvdata(dev) : NULL;
 }
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 650664e0f6e3..0949f2734e5d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1411,8 +1411,8 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
 static
 struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
 {
-	struct device *dev = driver_find_device_by_fwnode(&arm_smmu_driver.driver,
-							  fwnode);
+	struct device *dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
+
 	put_device(dev);
 	return dev ? dev_get_drvdata(dev) : NULL;
 }
@@ -2227,21 +2227,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 					i, irq);
 	}
 
-	err = iommu_device_sysfs_add(&smmu->iommu, smmu->dev, NULL,
-				     "smmu.%pa", &smmu->ioaddr);
-	if (err) {
-		dev_err(dev, "Failed to register iommu in sysfs\n");
-		return err;
-	}
-
-	err = iommu_device_register(&smmu->iommu, &arm_smmu_ops,
-				    using_legacy_binding ? NULL : dev);
-	if (err) {
-		dev_err(dev, "Failed to register iommu\n");
-		iommu_device_sysfs_remove(&smmu->iommu);
-		return err;
-	}
-
 	platform_set_drvdata(pdev, smmu);
 
 	/* Check for RMRs and install bypass SMRs if any */
@@ -2250,6 +2235,18 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	arm_smmu_device_reset(smmu);
 	arm_smmu_test_smr_masks(smmu);
 
+	err = iommu_device_sysfs_add(&smmu->iommu, smmu->dev, NULL,
+				     "smmu.%pa", &smmu->ioaddr);
+	if (err)
+		return dev_err_probe(dev, err, "Failed to register iommu in sysfs\n");
+
+	err = iommu_device_register(&smmu->iommu, &arm_smmu_ops,
+				    using_legacy_binding ? NULL : dev);
+	if (err) {
+		iommu_device_sysfs_remove(&smmu->iommu);
+		return dev_err_probe(dev, err, "Failed to register iommu\n");
+	}
+
 	/*
 	 * We want to avoid touching dev->power.lock in fastpaths unless
 	 * it's really going to do something useful - pm_runtime_enabled()
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Thu Dec  5 08:33:56 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu,  5 Dec 2024 16:33:56 +0000
Subject: [PATCH v2 2/4] iommu/arm-smmu: Retire probe deferral workaround
In-Reply-To: <cover.1733406914.git.robin.murphy@arm.com>
References: <cover.1733406914.git.robin.murphy@arm.com>
Message-ID: <4167c5dfa052d4c8bb780f0a30af63dcfc4ce6c1.1733406914.git.robin.murphy@arm.com>

This reverts commit 229e6ee43d2a160a1592b83aad620d6027084aad.

Now that the fundamental ordering issue between arm_smmu_get_by_fwnode()
and iommu_device_register() is resolved, the race condition for client
probe no longer exists either, so retire the specific workaround.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---

v2: New

 drivers/iommu/arm/arm-smmu/arm-smmu.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 0949f2734e5d..79afc92e1d8b 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1437,17 +1437,6 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 			goto out_free;
 	} else {
 		smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
-
-		/*
-		 * Defer probe if the relevant SMMU instance hasn't finished
-		 * probing yet. This is a fragile hack and we'd ideally
-		 * avoid this race in the core code. Until that's ironed
-		 * out, however, this is the most pragmatic option on the
-		 * table.
-		 */
-		if (!smmu)
-			return ERR_PTR(dev_err_probe(dev, -EPROBE_DEFER,
-						"smmu dev has not bound yet\n"));
 	}
 
 	ret = -EINVAL;
-- 
2.39.2.101.g768bb238c484.dirty



From broonie at kernel.org  Thu Dec  5 08:36:49 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 05 Dec 2024 16:36:49 +0000
Subject: [PATCH] ASoC: mediatek: mt8188-mt6359: Remove hardcoded dmic
 codec
In-Reply-To: <20241203-mt8188-6359-unhardcode-dmic-v1-1-346e3e5cbe6d@collabora.com>
References: <20241203-mt8188-6359-unhardcode-dmic-v1-1-346e3e5cbe6d@collabora.com>
Message-ID: <173341660960.157362.16366009839095486342.b4-ty@kernel.org>

On Tue, 03 Dec 2024 16:20:58 -0300, N?colas F. R. A. Prado wrote:
> Remove hardcoded dmic codec from the UL_SRC dai link to avoid requiring
> a dmic codec to be present for the driver to probe, as not every
> MT8188-based platform might need a dmic codec. The codec can be assigned
> to the dai link through the dai-link property in Devicetree on the
> platforms where it is needed.
> 
> No Devicetree currently relies on it so it is safe to remove without
> worrying about backward compatibility.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: mediatek: mt8188-mt6359: Remove hardcoded dmic codec
      commit: ec16a3cdf37e507013062f9c4a2067eacdd12b62

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 devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:42:57 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:42:57 +0100
Subject: [PATCH net-next v8 00/15] Add support for Synopsis DWMAC IP on NXP
 Automotive SoCs S32G2xx/S32G3xx/S32R45
Message-ID: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>

The SoC series S32G2xx and S32G3xx feature one DWMAC instance,
the SoC S32R45 has two instances. The devices can use RGMII/RMII/MII
interface over Pinctrl device or the output can be routed
to the embedded SerDes for SGMII connectivity.

The provided stmmac glue code implements only basic functionality,
interface support is restricted to RGMII only. More, including
SGMII/SerDes support will come later.

This patchset adds stmmac glue driver based on downstream NXP git [0].

[0] https://github.com/nxp-auto-linux/linux

v8:
- dropped 'driver' in patch subject
- fixed interface rx/tx clock init
- Link to v7: https://lore.kernel.org/r/20241202-upstream_s32cc_gmac-v7-0-bc3e1f9f656e at oss.nxp.com

v7:
- rebased on v6.13-rc1 and removed RFC prefix
- Link to v6: https://lore.kernel.org/r/20241124-upstream_s32cc_gmac-v6-0-dc5718ccf001 at oss.nxp.com

v6:
- removed dead code in dwmac-intel-plat.c
- yaml: fix indention
- validate interface mode in probe
- dropped patch#16 to fit in max 15 patches in series
- Link to v5: https://lore.kernel.org/r/20241119-upstream_s32cc_gmac-v5-0-7dcc90fcffef at oss.nxp.com

v5:
- yaml: refactored compatible string to use fallback
- yaml: fix indention in example
- fix xmas tree formating in local variable declarations
- removed lazy rx clk setup
- drop PTP clock reading patch and replace it with stmmac_platform fix
- Link to v4: https://lore.kernel.org/r/20241028-upstream_s32cc_gmac-v4-0-03618f10e3e2 at oss.nxp.com

v4:
- fixed empty commit messages for rgmi_clock() helper patches
- fixed yaml path in MAINTAINERS
- switched to platform_driver::remove() as suggested Uwe
- yaml: returned back all compatibility sting values
- added better commit description for rgmii_clock() helper
- Link to v3: https://lore.kernel.org/r/20241013-upstream_s32cc_gmac-v3-0-d84b5a67b930 at oss.nxp.com

v3:
- switched to b4 WoW to overcome threading issue with b4
- extracted the hunk with the typo fix from v2 patch#1 to separate patch
  as Jacob suggested
- removed dead code for RMII/MII support, which will be added alter
- used new rgmii_clock() helper in other stmmac:dwmac glue drivers
- yaml: compatible strings compressed to simple one "nxp,s32-dwmac",
  removed duplicated required properties, already defined in snps,dwmac,
  fixed example

v2:
- send to wider audience as first version missed many maintainers
- created rgmi_clk() helper as Russell suggested (see patch#4)
- address Andrew's, Russell's, Serge's and Simon's comments

Message-ID: <AM9PR04MB85066576AD6848E2402DA354E2832 at AM9PR04MB8506.eurprd04.prod.outlook.com>

Cc: 

Cc:

---
To: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
To: Alexandre Torgue <alexandre.torgue at foss.st.com>
To: Jose Abreu <joabreu at synopsys.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>
To: Vinod Koul <vkoul at kernel.org>
To: Richard Cochran <richardcochran at gmail.com>
To: Andrew Lunn <andrew at lunn.ch>
To: Heiner Kallweit <hkallweit1 at gmail.com>
To: Russell King <linux at armlinux.org.uk>
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: Emil Renner Berthing <kernel at esmil.dk>
To: Minda Chen <minda.chen at starfivetech.com>
To: Nicolas Ferre <nicolas.ferre at microchip.com>
To: Claudiu Beznea <claudiu.beznea at tuxon.dev>
To: Iyappan Subramanian <iyappan at os.amperecomputing.com>
To: Keyur Chudgar <keyur at os.amperecomputing.com>
To: Quan Nguyen <quan at os.amperecomputing.com>
To: Rob Herring <robh at kernel.org>
To: Krzysztof Kozlowski <krzk+dt at kernel.org>
To: Conor Dooley <conor+dt at kernel.org>
To: Giuseppe Cavallaro <peppe.cavallaro at st.com>
To: Andrew Lunn <andrew+netdev at lunn.ch>
Cc: linux-stm32 at st-md-mailman.stormreply.com
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: linux-arm-msm at vger.kernel.org
Cc: imx at lists.linux.dev
Cc: devicetree at vger.kernel.org
Cc: NXP S32 Linux Team <s32 at nxp.com>
Cc: 0x1207 at gmail.com
Cc: fancer.lancer at gmail.com
Cc: 
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>

---
Jan Petrous (OSS) (15):
      net: stmmac: Fix CSR divider comment
      net: stmmac: Extend CSR calc support
      net: stmmac: Fix clock rate variables size
      net: phy: Add helper for mapping RGMII link speed to clock rate
      net: dwmac-dwc-qos-eth: Use helper rgmii_clock
      net: dwmac-imx: Use helper rgmii_clock
      net: dwmac-intel-plat: Use helper rgmii_clock
      net: dwmac-rk: Use helper rgmii_clock
      net: dwmac-starfive: Use helper rgmii_clock
      net: macb: Use helper rgmii_clock
      net: xgene_enet: Use helper rgmii_clock
      net: dwmac-sti: Use helper rgmii_clock
      dt-bindings: net: Add DT bindings for DWMAC on NXP S32G/R SoCs
      net: stmmac: dwmac-s32: add basic NXP S32G/S32R glue driver
      MAINTAINERS: Add Jan Petrous as the NXP S32G/R DWMAC driver maintainer

 .../devicetree/bindings/net/nxp,s32-dwmac.yaml     | 105 +++++++++++
 .../devicetree/bindings/net/snps,dwmac.yaml        |   1 +
 MAINTAINERS                                        |   7 +
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.c     |  16 +-
 drivers/net/ethernet/cadence/macb_main.c           |  14 +-
 drivers/net/ethernet/stmicro/stmmac/Kconfig        |  12 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile       |   1 +
 drivers/net/ethernet/stmicro/stmmac/common.h       |   2 +
 .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  11 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  15 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  22 +--
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  30 +--
 drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c    | 202 +++++++++++++++++++++
 .../net/ethernet/stmicro/stmmac/dwmac-starfive.c   |  19 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  18 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c  |   2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   6 +-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   2 +-
 include/linux/phy.h                                |  23 +++
 include/linux/stmmac.h                             |  10 +-
 21 files changed, 399 insertions(+), 121 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20240923-upstream_s32cc_gmac-6891eb75b126

Best regards,
-- 
Jan Petrous (OSS) <jan.petrous at oss.nxp.com>




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:42:58 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:42:58 +0100
Subject: [PATCH net-next v8 01/15] net: stmmac: Fix CSR divider comment
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-1-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

The comment in declaration of STMMAC_CSR_250_300M
incorrectly describes the constant as '/* MDC = clk_scr_i/122 */'
but the DWC Ether QOS Handbook version 5.20a says it is
CSR clock/124.

Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
---
 include/linux/stmmac.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index d79ff252cfdc..75cbfb576358 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -33,7 +33,7 @@
 #define	STMMAC_CSR_20_35M	0x2	/* MDC = clk_scr_i/16 */
 #define	STMMAC_CSR_35_60M	0x3	/* MDC = clk_scr_i/26 */
 #define	STMMAC_CSR_150_250M	0x4	/* MDC = clk_scr_i/102 */
-#define	STMMAC_CSR_250_300M	0x5	/* MDC = clk_scr_i/122 */
+#define	STMMAC_CSR_250_300M	0x5	/* MDC = clk_scr_i/124 */
 
 /* MTL algorithms identifiers */
 #define MTL_TX_ALGORITHM_WRR	0x0

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:00 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:00 +0100
Subject: [PATCH net-next v8 03/15] net: stmmac: Fix clock rate variables
 size
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-3-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

The clock API clk_get_rate() returns unsigned long value.
Expand affected members of stmmac platform data and
convert the stmmac_clk_csr_set() and dwmac4_core_init() methods
to defining the unsigned long clk_rate local variables.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c       | 2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c       | 2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c   | 2 +-
 include/linux/stmmac.h                                  | 6 +++---
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 901a3c1959fa..2a5b38723635 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -777,7 +777,7 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 		netdev_err(priv->dev, "Failed to max out clk_ptp_ref: %d\n", err);
 	plat_dat->clk_ptp_rate = clk_get_rate(plat_dat->clk_ptp_ref);
 
-	netdev_dbg(priv->dev, "PTP rate %d\n", plat_dat->clk_ptp_rate);
+	netdev_dbg(priv->dev, "PTP rate %lu\n", plat_dat->clk_ptp_rate);
 }
 
 static int qcom_ethqos_probe(struct platform_device *pdev)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index c25781874aa7..c36f90a782c5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -27,7 +27,7 @@ static void dwmac4_core_init(struct mac_device_info *hw,
 	struct stmmac_priv *priv = netdev_priv(dev);
 	void __iomem *ioaddr = hw->pcsr;
 	u32 value = readl(ioaddr + GMAC_CONFIG);
-	u32 clk_rate;
+	unsigned long clk_rate;
 
 	value |= GMAC_CORE_INIT;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3cb7ad6ccc4e..d45fd7a3acd5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -301,7 +301,7 @@ static void stmmac_global_err(struct stmmac_priv *priv)
  */
 static void stmmac_clk_csr_set(struct stmmac_priv *priv)
 {
-	u32 clk_rate;
+	unsigned long clk_rate;
 
 	clk_rate = clk_get_rate(priv->plat->stmmac_clk);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 3ac32444e492..06e07e6e180b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -640,7 +640,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 		dev_info(&pdev->dev, "PTP uses main clock\n");
 	} else {
 		plat->clk_ptp_rate = clk_get_rate(plat->clk_ptp_ref);
-		dev_dbg(&pdev->dev, "PTP rate %d\n", plat->clk_ptp_rate);
+		dev_dbg(&pdev->dev, "PTP rate %lu\n", plat->clk_ptp_rate);
 	}
 
 	plat->stmmac_rst = devm_reset_control_get_optional(&pdev->dev,
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 865d0fe26f98..c9878a612e53 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -252,8 +252,8 @@ struct plat_stmmacenet_data {
 	struct clk *stmmac_clk;
 	struct clk *pclk;
 	struct clk *clk_ptp_ref;
-	unsigned int clk_ptp_rate;
-	unsigned int clk_ref_rate;
+	unsigned long clk_ptp_rate;
+	unsigned long clk_ref_rate;
 	unsigned int mult_fact_100ns;
 	s32 ptp_max_adj;
 	u32 cdc_error_adj;
@@ -265,7 +265,7 @@ struct plat_stmmacenet_data {
 	int mac_port_sel_speed;
 	int has_xgmac;
 	u8 vlan_fail_q;
-	unsigned int eee_usecs_rate;
+	unsigned long eee_usecs_rate;
 	struct pci_dev *pdev;
 	int int_snapshot_num;
 	int msi_mac_vec;

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:02 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:02 +0100
Subject: [PATCH net-next v8 05/15] net: dwmac-dwc-qos-eth: Use helper
 rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-5-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

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 83290e707df5..bd4eb187f8c6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
@@ -181,24 +181,19 @@ static void dwc_qos_remove(struct platform_device *pdev)
 static void tegra_eqos_fix_speed(void *priv, unsigned int speed, unsigned int mode)
 {
 	struct tegra_eqos *eqos = priv;
-	unsigned long rate = 125000000;
 	bool needs_calibration = false;
+	long rate = 125000000;
 	u32 value;
 	int err;
 
 	switch (speed) {
 	case SPEED_1000:
-		needs_calibration = true;
-		rate = 125000000;
-		break;
-
 	case SPEED_100:
 		needs_calibration = true;
-		rate = 25000000;
-		break;
+		fallthrough;
 
 	case SPEED_10:
-		rate = 2500000;
+		rate = rgmii_clock(speed);
 		break;
 
 	default:

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:03 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:03 +0100
Subject: [PATCH net-next v8 06/15] net: dwmac-imx: Use helper rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-6-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c | 15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
index 641f3cd019a3..43e0fbba4f77 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
@@ -186,7 +186,7 @@ static void imx_dwmac_fix_speed(void *priv, unsigned int speed, unsigned int mod
 {
 	struct plat_stmmacenet_data *plat_dat;
 	struct imx_priv_data *dwmac = priv;
-	unsigned long rate;
+	long rate;
 	int err;
 
 	plat_dat = dwmac->plat_dat;
@@ -196,17 +196,8 @@ static void imx_dwmac_fix_speed(void *priv, unsigned int speed, unsigned int mod
 	    (plat_dat->mac_interface == PHY_INTERFACE_MODE_MII))
 		return;
 
-	switch (speed) {
-	case SPEED_1000:
-		rate = 125000000;
-		break;
-	case SPEED_100:
-		rate = 25000000;
-		break;
-	case SPEED_10:
-		rate = 2500000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dwmac->dev, "invalid speed %u\n", speed);
 		return;
 	}

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:42:59 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:42:59 +0100
Subject: [PATCH net-next v8 02/15] net: stmmac: Extend CSR calc support
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-2-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Add support for CSR clock range up to 800 MHz.

Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h      | 2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++++
 include/linux/stmmac.h                            | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1367fa5c9b8e..70d601f45481 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -257,6 +257,8 @@ struct stmmac_safety_stats {
 #define CSR_F_150M	150000000
 #define CSR_F_250M	250000000
 #define CSR_F_300M	300000000
+#define CSR_F_500M	500000000
+#define CSR_F_800M	800000000
 
 #define	MAC_CSR_H_FRQ_MASK	0x20
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9b262cdad60b..3cb7ad6ccc4e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -325,6 +325,10 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
 			priv->clk_csr = STMMAC_CSR_150_250M;
 		else if ((clk_rate >= CSR_F_250M) && (clk_rate <= CSR_F_300M))
 			priv->clk_csr = STMMAC_CSR_250_300M;
+		else if ((clk_rate >= CSR_F_300M) && (clk_rate < CSR_F_500M))
+			priv->clk_csr = STMMAC_CSR_300_500M;
+		else if ((clk_rate >= CSR_F_500M) && (clk_rate < CSR_F_800M))
+			priv->clk_csr = STMMAC_CSR_500_800M;
 	}
 
 	if (priv->plat->flags & STMMAC_FLAG_HAS_SUN8I) {
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 75cbfb576358..865d0fe26f98 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -34,6 +34,8 @@
 #define	STMMAC_CSR_35_60M	0x3	/* MDC = clk_scr_i/26 */
 #define	STMMAC_CSR_150_250M	0x4	/* MDC = clk_scr_i/102 */
 #define	STMMAC_CSR_250_300M	0x5	/* MDC = clk_scr_i/124 */
+#define	STMMAC_CSR_300_500M	0x6	/* MDC = clk_scr_i/204 */
+#define	STMMAC_CSR_500_800M	0x7	/* MDC = clk_scr_i/324 */
 
 /* MTL algorithms identifiers */
 #define MTL_TX_ALGORITHM_WRR	0x0

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:05 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:05 +0100
Subject: [PATCH net-next v8 08/15] net: dwmac-rk: Use helper rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-8-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 30 ++++++--------------------
 1 file changed, 6 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 8cb374668b74..a4dc89e23a68 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1079,20 +1079,11 @@ static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
 {
 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
 	struct device *dev = &bsp_priv->pdev->dev;
-	unsigned long rate;
+	long rate;
 	int ret;
 
-	switch (speed) {
-	case 10:
-		rate = 2500000;
-		break;
-	case 100:
-		rate = 25000000;
-		break;
-	case 1000:
-		rate = 125000000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
 		return;
 	}
@@ -1540,20 +1531,11 @@ static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
 {
 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
 	struct device *dev = &bsp_priv->pdev->dev;
-	unsigned long rate;
+	long rate;
 	int ret;
 
-	switch (speed) {
-	case 10:
-		rate = 2500000;
-		break;
-	case 100:
-		rate = 25000000;
-		break;
-	case 1000:
-		rate = 125000000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
 		return;
 	}

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:01 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:01 +0100
Subject: [PATCH net-next v8 04/15] net: phy: Add helper for mapping RGMII
 link speed to clock rate
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-4-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

The RGMII interface supports three data rates: 10/100 Mbps
and 1 Gbps. These speeds correspond to clock frequencies
of 2.5/25 MHz and 125 MHz, respectively.

Many Ethernet drivers, including glues in stmmac, follow
a similar pattern of converting RGMII speed to clock frequency.

To simplify code, define the helper rgmii_clock(speed)
to convert connection speed to clock frequency.

Suggested-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 include/linux/phy.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/include/linux/phy.h b/include/linux/phy.h
index 563c46205685..a746f056ed57 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -298,6 +298,29 @@ static inline const char *phy_modes(phy_interface_t interface)
 	}
 }
 
+/**
+ * rgmii_clock - map link speed to the clock rate
+ * @speed: link speed value
+ *
+ * Description: maps RGMII supported link speeds
+ * into the clock rates.
+ *
+ * Returns: clock rate or negative errno
+ */
+static inline long rgmii_clock(int speed)
+{
+	switch (speed) {
+	case SPEED_10:
+		return 2500000;
+	case SPEED_100:
+		return 25000000;
+	case SPEED_1000:
+		return 125000000;
+	default:
+		return -EINVAL;
+	}
+}
+
 #define PHY_INIT_TIMEOUT	100000
 #define PHY_FORCE_TIMEOUT	10
 

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:04 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:04 +0100
Subject: [PATCH net-next v8 07/15] net: dwmac-intel-plat: Use helper
 rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-7-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

When in, remove dead code in kmb_eth_fix_mac_speed().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
index d94f0a150e93..ddee6154d40b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
@@ -31,27 +31,13 @@ struct intel_dwmac_data {
 static void kmb_eth_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
 {
 	struct intel_dwmac *dwmac = priv;
-	unsigned long rate;
+	long rate;
 	int ret;
 
-	rate = clk_get_rate(dwmac->tx_clk);
-
-	switch (speed) {
-	case SPEED_1000:
-		rate = 125000000;
-		break;
-
-	case SPEED_100:
-		rate = 25000000;
-		break;
-
-	case SPEED_10:
-		rate = 2500000;
-		break;
-
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dwmac->dev, "Invalid speed\n");
-		break;
+		return;
 	}
 
 	ret = clk_set_rate(dwmac->tx_clk, rate);

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:07 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:07 +0100
Subject: [PATCH net-next v8 10/15] net: macb: Use helper rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-10-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/cadence/macb_main.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index daa416fb1724..640f500f989d 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -530,19 +530,9 @@ static void macb_set_tx_clk(struct macb *bp, int speed)
 	if (bp->phy_interface == PHY_INTERFACE_MODE_MII)
 		return;
 
-	switch (speed) {
-	case SPEED_10:
-		rate = 2500000;
-		break;
-	case SPEED_100:
-		rate = 25000000;
-		break;
-	case SPEED_1000:
-		rate = 125000000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0)
 		return;
-	}
 
 	rate_rounded = clk_round_rate(bp->tx_clk, rate);
 	if (rate_rounded < 0)

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:06 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:06 +0100
Subject: [PATCH net-next v8 09/15] net: dwmac-starfive: Use helper
 rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-9-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Emil Renner Berthing <emil.renner.berthing at canonical.com>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
index 421666279dd3..0a0a363d3730 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
@@ -34,24 +34,13 @@ struct starfive_dwmac {
 static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
 {
 	struct starfive_dwmac *dwmac = priv;
-	unsigned long rate;
+	long rate;
 	int err;
 
-	rate = clk_get_rate(dwmac->clk_tx);
-
-	switch (speed) {
-	case SPEED_1000:
-		rate = 125000000;
-		break;
-	case SPEED_100:
-		rate = 25000000;
-		break;
-	case SPEED_10:
-		rate = 2500000;
-		break;
-	default:
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
 		dev_err(dwmac->dev, "invalid speed %u\n", speed);
-		break;
+		return;
 	}
 
 	err = clk_set_rate(dwmac->clk_tx, rate);

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:08 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:08 +0100
Subject: [PATCH net-next v8 11/15] net: xgene_enet: Use helper rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-11-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index e641dbbea1e2..b854b6b42d77 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -421,18 +421,12 @@ static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata)
 
 	if (dev->of_node) {
 		struct clk *parent = clk_get_parent(pdata->clk);
+		long rate = rgmii_clock(pdata->phy_speed);
 
-		switch (pdata->phy_speed) {
-		case SPEED_10:
-			clk_set_rate(parent, 2500000);
-			break;
-		case SPEED_100:
-			clk_set_rate(parent, 25000000);
-			break;
-		default:
-			clk_set_rate(parent, 125000000);
-			break;
-		}
+		if (rate < 0)
+			rate = 125000000;
+
+		clk_set_rate(parent, rate);
 	}
 #ifdef CONFIG_ACPI
 	else {

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:11 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:11 +0100
Subject: [PATCH net-next v8 14/15] net: stmmac: dwmac-s32: add basic NXP
 S32G/S32R glue driver
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-14-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

NXP S32G2xx/S32G3xx and S32R45 are automotive grade SoCs
that integrate one or two Synopsys DWMAC 5.10/5.20 IPs.

The basic driver supports only RGMII interface.

Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig     |  12 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile    |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c | 202 ++++++++++++++++++++++++
 3 files changed, 215 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 6658536a4e17..4cc85a36a1ab 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -154,6 +154,18 @@ config DWMAC_RZN1
 	  the stmmac device driver. This support can make use of a custom MII
 	  converter PCS device.
 
+config DWMAC_S32
+	tristate "NXP S32G/S32R GMAC support"
+	default ARCH_S32
+	depends on OF && (ARCH_S32 || COMPILE_TEST)
+	help
+	  Support for ethernet controller on NXP S32CC SOCs.
+
+	  This selects NXP SoC glue layer support for the stmmac
+	  device driver. This driver is used for the S32CC series
+	  SOCs GMAC ethernet controller, ie. S32G2xx, S32G3xx and
+	  S32R45.
+
 config DWMAC_SOCFPGA
 	tristate "SOCFPGA dwmac support"
 	default ARCH_INTEL_SOCFPGA
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 2389fd261344..b26f0e79c2b3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_DWMAC_MESON)	+= dwmac-meson.o dwmac-meson8b.o
 obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-ethqos.o
 obj-$(CONFIG_DWMAC_ROCKCHIP)	+= dwmac-rk.o
 obj-$(CONFIG_DWMAC_RZN1)	+= dwmac-rzn1.o
+obj-$(CONFIG_DWMAC_S32)		+= dwmac-s32.o
 obj-$(CONFIG_DWMAC_SOCFPGA)	+= dwmac-altr-socfpga.o
 obj-$(CONFIG_DWMAC_STARFIVE)	+= dwmac-starfive.o
 obj-$(CONFIG_DWMAC_STI)		+= dwmac-sti.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
new file mode 100644
index 000000000000..9cc0e5817416
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP S32G/R GMAC glue layer
+ *
+ * Copyright 2019-2024 NXP
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/ethtool.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_mdio.h>
+#include <linux/of_address.h>
+#include <linux/phy.h>
+#include <linux/phylink.h>
+#include <linux/platform_device.h>
+#include <linux/stmmac.h>
+
+#include "stmmac_platform.h"
+
+#define GMAC_INTF_RATE_125M	125000000	/* 125MHz */
+
+/* SoC PHY interface control register */
+#define PHY_INTF_SEL_MII	0x00
+#define PHY_INTF_SEL_SGMII	0x01
+#define PHY_INTF_SEL_RGMII	0x02
+#define PHY_INTF_SEL_RMII	0x08
+
+struct s32_priv_data {
+	void __iomem *ioaddr;
+	void __iomem *ctrl_sts;
+	struct device *dev;
+	phy_interface_t *intf_mode;
+	struct clk *tx_clk;
+	struct clk *rx_clk;
+};
+
+static int s32_gmac_write_phy_intf_select(struct s32_priv_data *gmac)
+{
+	writel(PHY_INTF_SEL_RGMII, gmac->ctrl_sts);
+
+	dev_dbg(gmac->dev, "PHY mode set to %s\n", phy_modes(*gmac->intf_mode));
+
+	return 0;
+}
+
+static int s32_gmac_init(struct platform_device *pdev, void *priv)
+{
+	struct s32_priv_data *gmac = priv;
+	int ret;
+
+	/* Set initial TX interface clock */
+	ret = clk_prepare_enable(gmac->tx_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't enable tx clock\n");
+		return ret;
+	}
+	ret = clk_set_rate(gmac->tx_clk, GMAC_INTF_RATE_125M);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't set tx clock\n");
+		goto err_tx_disable;
+	}
+
+	/* Set initial RX interface clock */
+	ret = clk_prepare_enable(gmac->rx_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't enable rx clock\n");
+		goto err_tx_disable;
+	}
+	ret = clk_set_rate(gmac->rx_clk, GMAC_INTF_RATE_125M);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't set rx clock\n");
+		goto err_txrx_disable;
+	}
+
+	/* Set interface mode */
+	ret = s32_gmac_write_phy_intf_select(gmac);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't set PHY interface mode\n");
+		goto err_txrx_disable;
+	}
+
+	return 0;
+
+err_txrx_disable:
+	clk_disable_unprepare(gmac->rx_clk);
+err_tx_disable:
+	clk_disable_unprepare(gmac->tx_clk);
+	return ret;
+}
+
+static void s32_gmac_exit(struct platform_device *pdev, void *priv)
+{
+	struct s32_priv_data *gmac = priv;
+
+	clk_disable_unprepare(gmac->tx_clk);
+	clk_disable_unprepare(gmac->rx_clk);
+}
+
+static void s32_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
+{
+	struct s32_priv_data *gmac = priv;
+	long tx_clk_rate;
+	int ret;
+
+	tx_clk_rate = rgmii_clock(speed);
+	if (tx_clk_rate < 0) {
+		dev_err(gmac->dev, "Unsupported/Invalid speed: %d\n", speed);
+		return;
+	}
+
+	dev_dbg(gmac->dev, "Set tx clock to %ld Hz\n", tx_clk_rate);
+	ret = clk_set_rate(gmac->tx_clk, tx_clk_rate);
+	if (ret)
+		dev_err(gmac->dev, "Can't set tx clock\n");
+}
+
+static int s32_dwmac_probe(struct platform_device *pdev)
+{
+	struct plat_stmmacenet_data *plat;
+	struct device *dev = &pdev->dev;
+	struct stmmac_resources res;
+	struct s32_priv_data *gmac;
+	int ret;
+
+	gmac = devm_kzalloc(&pdev->dev, sizeof(*gmac), GFP_KERNEL);
+	if (!gmac)
+		return -ENOMEM;
+
+	gmac->dev = &pdev->dev;
+
+	ret = stmmac_get_platform_resources(pdev, &res);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get platform resources\n");
+
+	plat = devm_stmmac_probe_config_dt(pdev, res.mac);
+	if (IS_ERR(plat))
+		return dev_err_probe(dev, PTR_ERR(plat),
+				     "dt configuration failed\n");
+
+	/* PHY interface mode control reg */
+	gmac->ctrl_sts = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
+	if (IS_ERR(gmac->ctrl_sts))
+		return dev_err_probe(dev, PTR_ERR(gmac->ctrl_sts),
+				     "S32CC config region is missing\n");
+
+	/* tx clock */
+	gmac->tx_clk = devm_clk_get(&pdev->dev, "tx");
+	if (IS_ERR(gmac->tx_clk))
+		return dev_err_probe(dev, PTR_ERR(gmac->tx_clk),
+				     "tx clock not found\n");
+
+	/* rx clock */
+	gmac->rx_clk = devm_clk_get(&pdev->dev, "rx");
+	if (IS_ERR(gmac->rx_clk))
+		return dev_err_probe(dev, PTR_ERR(gmac->rx_clk),
+				     "rx clock not found\n");
+
+	gmac->intf_mode = &plat->phy_interface;
+	gmac->ioaddr = res.addr;
+
+	/* S32CC core feature set */
+	plat->has_gmac4 = true;
+	plat->pmt = 1;
+	plat->flags |= STMMAC_FLAG_SPH_DISABLE;
+	plat->rx_fifo_size = 20480;
+	plat->tx_fifo_size = 20480;
+
+	plat->init = s32_gmac_init;
+	plat->exit = s32_gmac_exit;
+	plat->fix_mac_speed = s32_fix_mac_speed;
+
+	plat->bsp_priv = gmac;
+
+	return stmmac_pltfr_probe(pdev, plat, &res);
+}
+
+static const struct of_device_id s32_dwmac_match[] = {
+	{ .compatible = "nxp,s32g2-dwmac" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, s32_dwmac_match);
+
+static struct platform_driver s32_dwmac_driver = {
+	.probe = s32_dwmac_probe,
+	.remove = stmmac_pltfr_remove,
+	.driver = {
+		.name = "s32-dwmac",
+		.pm = &stmmac_pltfr_pm_ops,
+		.of_match_table = s32_dwmac_match,
+	},
+};
+module_platform_driver(s32_dwmac_driver);
+
+MODULE_AUTHOR("Jan Petrous (OSS) <jan.petrous at oss.nxp.com>");
+MODULE_DESCRIPTION("NXP S32G/R common chassis GMAC driver");
+MODULE_LICENSE("GPL");
+

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:09 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:09 +0100
Subject: [PATCH net-next v8 12/15] net: dwmac-sti: Use helper rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-12-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Utilize a new helper function rgmii_clock().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index a6ff02d905a9..eabc4da9e1a9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -21,10 +21,7 @@
 
 #include "stmmac_platform.h"
 
-#define DWMAC_125MHZ	125000000
 #define DWMAC_50MHZ	50000000
-#define DWMAC_25MHZ	25000000
-#define DWMAC_2_5MHZ	2500000
 
 #define IS_PHY_IF_MODE_RGMII(iface)	(iface == PHY_INTERFACE_MODE_RGMII || \
 			iface == PHY_INTERFACE_MODE_RGMII_ID || \
@@ -140,7 +137,7 @@ static void stih4xx_fix_retime_src(void *priv, u32 spd, unsigned int mode)
 	struct sti_dwmac *dwmac = priv;
 	u32 src = dwmac->tx_retime_src;
 	u32 reg = dwmac->ctrl_reg;
-	u32 freq = 0;
+	long freq = 0;
 
 	if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
 		src = TX_RETIME_SRC_TXCLK;
@@ -153,19 +150,14 @@ static void stih4xx_fix_retime_src(void *priv, u32 spd, unsigned int mode)
 		}
 	} else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
 		/* On GiGa clk source can be either ext or from clkgen */
-		if (spd == SPEED_1000) {
-			freq = DWMAC_125MHZ;
-		} else {
+		freq = rgmii_clock(spd);
+
+		if (spd != SPEED_1000 && freq > 0)
 			/* Switch to clkgen for these speeds */
 			src = TX_RETIME_SRC_CLKGEN;
-			if (spd == SPEED_100)
-				freq = DWMAC_25MHZ;
-			else if (spd == SPEED_10)
-				freq = DWMAC_2_5MHZ;
-		}
 	}
 
-	if (src == TX_RETIME_SRC_CLKGEN && freq)
+	if (src == TX_RETIME_SRC_CLKGEN && freq > 0)
 		clk_set_rate(dwmac->clk, freq);
 
 	regmap_update_bits(dwmac->regmap, reg, STIH4XX_RETIME_SRC_MASK,

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:12 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:12 +0100
Subject: [PATCH net-next v8 15/15] MAINTAINERS: Add Jan Petrous as the NXP
 S32G/R DWMAC driver maintainer
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-15-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Add myself as NXP S32G/R DWMAC Ethernet driver maintainer.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..baf41d73d14e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2836,6 +2836,13 @@ S:	Maintained
 F:	arch/arm64/boot/dts/freescale/s32g*.dts*
 F:	drivers/pinctrl/nxp/
 
+ARM/NXP S32G/S32R DWMAC ETHERNET DRIVER
+M:	Jan Petrous <jan.petrous at oss.nxp.com>
+L:	NXP S32 Linux Team <s32 at nxp.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
+F:	drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
+
 ARM/Orion SoC/Technologic Systems TS-78xx platform support
 M:	Alexander Clouter <alex at digriz.org.uk>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)

-- 
2.47.0




From devnull+jan.petrous.oss.nxp.com at kernel.org  Thu Dec  5 08:43:10 2024
From: devnull+jan.petrous.oss.nxp.com at kernel.org (Jan Petrous via B4 Relay)
Date: Thu, 05 Dec 2024 17:43:10 +0100
Subject: [PATCH net-next v8 13/15] dt-bindings: net: Add DT bindings for
 DWMAC on NXP S32G/R SoCs
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <20241205-upstream_s32cc_gmac-v8-13-ec1d180df815@oss.nxp.com>

From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>

Add basic description for DWMAC ethernet IP on NXP S32G2xx, S32G3xx
and S32R45 automotive series SoCs.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
---
 .../devicetree/bindings/net/nxp,s32-dwmac.yaml     | 105 +++++++++++++++++++++
 .../devicetree/bindings/net/snps,dwmac.yaml        |   1 +
 2 files changed, 106 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml b/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
new file mode 100644
index 000000000000..2b8b74c5feec
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright 2021-2024 NXP
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/nxp,s32-dwmac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP S32G2xx/S32G3xx/S32R45 GMAC ethernet controller
+
+maintainers:
+  - Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
+
+description:
+  This device is a Synopsys DWC IP, integrated on NXP S32G/R SoCs.
+  The SoC series S32G2xx and S32G3xx feature one DWMAC instance,
+  the SoC S32R45 has two instances. The devices can use RGMII/RMII/MII
+  interface over Pinctrl device or the output can be routed
+  to the embedded SerDes for SGMII connectivity.
+
+properties:
+  compatible:
+    oneOf:
+      - const: nxp,s32g2-dwmac
+      - items:
+          - enum:
+              - nxp,s32g3-dwmac
+              - nxp,s32r45-dwmac
+          - const: nxp,s32g2-dwmac
+
+  reg:
+    items:
+      - description: Main GMAC registers
+      - description: GMAC PHY mode control register
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-names:
+    const: macirq
+
+  clocks:
+    items:
+      - description: Main GMAC clock
+      - description: Transmit clock
+      - description: Receive clock
+      - description: PTP reference clock
+
+  clock-names:
+    items:
+      - const: stmmaceth
+      - const: tx
+      - const: rx
+      - const: ptp_ref
+
+required:
+  - clocks
+  - clock-names
+
+allOf:
+  - $ref: snps,dwmac.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/phy/phy.h>
+    bus {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      ethernet at 4033c000 {
+        compatible = "nxp,s32g2-dwmac";
+        reg = <0x0 0x4033c000 0x0 0x2000>, /* gmac IP */
+              <0x0 0x4007c004 0x0 0x4>;    /* GMAC_0_CTRL_STS */
+        interrupt-parent = <&gic>;
+        interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "macirq";
+        snps,mtl-rx-config = <&mtl_rx_setup>;
+        snps,mtl-tx-config = <&mtl_tx_setup>;
+        clocks = <&clks 24>, <&clks 17>, <&clks 16>, <&clks 15>;
+        clock-names = "stmmaceth", "tx", "rx", "ptp_ref";
+        phy-mode = "rgmii-id";
+        phy-handle = <&phy0>;
+
+        mtl_rx_setup: rx-queues-config {
+          snps,rx-queues-to-use = <5>;
+        };
+
+        mtl_tx_setup: tx-queues-config {
+          snps,tx-queues-to-use = <5>;
+        };
+
+        mdio {
+          #address-cells = <1>;
+          #size-cells = <0>;
+          compatible = "snps,dwmac-mdio";
+
+          phy0: ethernet-phy at 0 {
+            reg = <0>;
+          };
+        };
+      };
+    };
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index eb1f3ae41ab9..91e75eb3f329 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -67,6 +67,7 @@ properties:
         - ingenic,x2000-mac
         - loongson,ls2k-dwmac
         - loongson,ls7a-dwmac
+        - nxp,s32g2-dwmac
         - qcom,qcs404-ethqos
         - qcom,sa8775p-ethqos
         - qcom,sc8280xp-ethqos

-- 
2.47.0




From konrad.dybcio at oss.qualcomm.com  Thu Dec  5 08:45:13 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 5 Dec 2024 17:45:13 +0100
Subject: [PATCH v3 6/7] arm64: dts: qcom: Add board dts files for SM8750
 MTP and QRD
In-Reply-To: <20241204-sm8750_master_dt-v3-6-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
 <20241204-sm8750_master_dt-v3-6-4d5a8269950b@quicinc.com>
Message-ID: <b9225284-7830-4aa4-aed2-7f58fb7320e8@oss.qualcomm.com>

On 5.12.2024 12:18 AM, Melody Olvera wrote:
> Add MTP and QRD dts files for SM8750 describing board clocks, regulators,
> gpio keys, etc.
> 
> Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
> ---

[...]

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

> +&tlmm {
> +	/* reserved for secure world */
> +	gpio-reserved-ranges = <36 4>, <74 1>;
> +};

Any chance you could describe what those specifically are?

Konrad


From mathieu.poirier at linaro.org  Thu Dec  5 08:47:42 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 5 Dec 2024 09:47:42 -0700
Subject: [PATCH] remoteproc: mtk_scp: Only populate devices SCP cores
In-Reply-To: <20241202062826.66619-1-wenst@chromium.org>
References: <20241202062826.66619-1-wenst@chromium.org>
Message-ID: <Z1HZLq4iJQGmKDgM@p14s>

Good day,

On Mon, Dec 02, 2024 at 02:28:25PM +0800, Chen-Yu Tsai wrote:
> When multi-core SCP support was added, the driver was made to populate
> platform devices for all the sub-nodes. This ended up adding platform
> devices for the rpmsg sub-nodes as well, which never actually get used,
> since rpmsg devices are registered through the rpmsg interface.
> 
> Limit of_platform_populate() to just populating the SCP cores with a
> compatible string match list.
> 
> Fixes: 1fdbf0cdde98 ("remoteproc: mediatek: Probe SCP cluster on multi-core SCP")
> Cc: Tinghan Shen <tinghan.shen at mediatek.com>
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/remoteproc/mtk_scp.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> index 0f4a7065d0bd..8206a1766481 100644
> --- a/drivers/remoteproc/mtk_scp.c
> +++ b/drivers/remoteproc/mtk_scp.c
> @@ -1326,6 +1326,11 @@ static int scp_cluster_init(struct platform_device *pdev, struct mtk_scp_of_clus
>  	return ret;
>  }
>  
> +static const struct of_device_id scp_core_match[] = {
> +	{ .compatible = "mediatek,scp-core" },
> +	{}
> +};
> +
>  static int scp_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -1357,13 +1362,15 @@ static int scp_probe(struct platform_device *pdev)
>  	INIT_LIST_HEAD(&scp_cluster->mtk_scp_list);
>  	mutex_init(&scp_cluster->cluster_lock);
>  
> -	ret = devm_of_platform_populate(dev);
> +	ret = of_platform_populate(dev_of_node(dev), scp_core_match, NULL, dev);
>  	if (ret)
>  		return dev_err_probe(dev, ret, "Failed to populate platform devices\n");
>  
>  	ret = scp_cluster_init(pdev, scp_cluster);
> -	if (ret)
> +	if (ret) {
> +		of_platform_depopulate(dev);
>  		return ret;
> +	}
>  
>  	return 0;
>  }
> @@ -1379,6 +1386,7 @@ static void scp_remove(struct platform_device *pdev)
>  		rproc_del(scp->rproc);
>  		scp_free(scp);
>  	}
> +	of_platform_depopulate(&pdev->dev);

This looks like a sensible addition to me but I'll give Angelo some time to
chime in.

Regards,
Mathieu

>  	mutex_destroy(&scp_cluster->cluster_lock);
>  }
>  
> -- 
> 2.47.0.338.g60cca15819-goog
> 


From Frank.Li at nxp.com  Thu Dec  5 08:51:08 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 05 Dec 2024 11:51:08 -0500
Subject: [PATCH 0/5] regulator: pca9450: collect some improvement patches
Message-ID: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>

Add pca9452 support
Use dev_err_probe() to simple code
add pca9452 support in imx93-14x14 dts

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Frank Li (1):
      regulator: pca9450: Use dev_err_probe() to simplify code

Joy Zou (3):
      regulator: dt-bindings: pca9450: Add pca9452 support
      regulator: pca9450: Add PMIC pca9452 support
      arm64: dts: imx93: add pca9452 support

Robin Gong (1):
      regulator: pca9450: add enable_value for all bucks

 .../bindings/regulator/nxp,pca9450-regulator.yaml  |   1 +
 arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts  |  83 +++++++++++++++
 drivers/regulator/pca9450-regulator.c              | 111 ++++++++++++---------
 include/linux/regulator/pca9450.h                  |   1 +
 4 files changed, 150 insertions(+), 46 deletions(-)
---
base-commit: af2ea8ab7a546b430726183458da0a173d331272
change-id: 20241121-pca9450-72c3f757a0b0

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Thu Dec  5 08:51:09 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 05 Dec 2024 11:51:09 -0500
Subject: [PATCH 1/5] regulator: pca9450: add enable_value for all bucks
In-Reply-To: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
References: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
Message-ID: <20241205-pca9450-v1-1-aab448b74e78@nxp.com>

From: Robin Gong <yibin.gong at nxp.com>

Set 'enable_value' in the regulator descriptor for different bucks to
manage their enable modes:

- 00b: OFF
- 01b: ON when PMIC_ON_REQ = H
- 10b: ON when PMIC_ON_REQ = H && PMIC_STBY_REQ = L
- 11b: Always ON

Ensure appropriate behavior based on the intended design. For example:
- Buck2, designed for vddarm, should be set to '10b' (ON when
PMIC_STBY_REQ = L) since it can be off when `PMIC_STBY_REQ = H` after the
kernel enters suspend.
- Other bucks remain '01b' (ON when PMIC_ON_REQ = H), matching the default
setting. This avoids the need to re-enable them during kernel boot as they
are already enabled after PMIC initialization.

Signed-off-by: Robin Gong <yibin.gong at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/regulator/pca9450-regulator.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index 9714afe347dcc..caeeed433165c 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -247,6 +247,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
 			.ramp_mask = BUCK1_RAMP_MASK,
 			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
 			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
+			.enable_val = BUCK_ENMODE_ONREQ,
 			.owner = THIS_MODULE,
 			.of_parse_cb = pca9450_set_dvs_levels,
 		},
@@ -272,6 +273,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
 			.vsel_mask = BUCK2OUT_DVS0_MASK,
 			.enable_reg = PCA9450_REG_BUCK2CTRL,
 			.enable_mask = BUCK2_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ_STBYREQ,
 			.ramp_reg = PCA9450_REG_BUCK2CTRL,
 			.ramp_mask = BUCK2_RAMP_MASK,
 			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
@@ -301,6 +303,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
 			.vsel_mask = BUCK3OUT_DVS0_MASK,
 			.enable_reg = PCA9450_REG_BUCK3CTRL,
 			.enable_mask = BUCK3_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ,
 			.ramp_reg = PCA9450_REG_BUCK3CTRL,
 			.ramp_mask = BUCK3_RAMP_MASK,
 			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
@@ -330,6 +333,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
 			.vsel_mask = BUCK4OUT_MASK,
 			.enable_reg = PCA9450_REG_BUCK4CTRL,
 			.enable_mask = BUCK4_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ,
 			.owner = THIS_MODULE,
 		},
 	},
@@ -348,6 +352,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
 			.vsel_mask = BUCK5OUT_MASK,
 			.enable_reg = PCA9450_REG_BUCK5CTRL,
 			.enable_mask = BUCK5_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ,
 			.owner = THIS_MODULE,
 		},
 	},
@@ -366,6 +371,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
 			.vsel_mask = BUCK6OUT_MASK,
 			.enable_reg = PCA9450_REG_BUCK6CTRL,
 			.enable_mask = BUCK6_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ,
 			.owner = THIS_MODULE,
 		},
 	},
@@ -481,6 +487,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
 			.vsel_mask = BUCK1OUT_DVS0_MASK,
 			.enable_reg = PCA9450_REG_BUCK1CTRL,
 			.enable_mask = BUCK1_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ,
 			.ramp_reg = PCA9450_REG_BUCK1CTRL,
 			.ramp_mask = BUCK1_RAMP_MASK,
 			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
@@ -510,6 +517,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
 			.vsel_mask = BUCK2OUT_DVS0_MASK,
 			.enable_reg = PCA9450_REG_BUCK2CTRL,
 			.enable_mask = BUCK2_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ_STBYREQ,
 			.ramp_reg = PCA9450_REG_BUCK2CTRL,
 			.ramp_mask = BUCK2_RAMP_MASK,
 			.ramp_delay_table = pca9450_dvs_buck_ramp_table,
@@ -539,6 +547,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
 			.vsel_mask = BUCK4OUT_MASK,
 			.enable_reg = PCA9450_REG_BUCK4CTRL,
 			.enable_mask = BUCK4_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ,
 			.owner = THIS_MODULE,
 		},
 	},
@@ -557,6 +566,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
 			.vsel_mask = BUCK5OUT_MASK,
 			.enable_reg = PCA9450_REG_BUCK5CTRL,
 			.enable_mask = BUCK5_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ,
 			.owner = THIS_MODULE,
 		},
 	},
@@ -575,6 +585,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
 			.vsel_mask = BUCK6OUT_MASK,
 			.enable_reg = PCA9450_REG_BUCK6CTRL,
 			.enable_mask = BUCK6_ENMODE_MASK,
+			.enable_val = BUCK_ENMODE_ONREQ,
 			.owner = THIS_MODULE,
 		},
 	},

-- 
2.34.1



From Frank.Li at nxp.com  Thu Dec  5 08:51:10 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 05 Dec 2024 11:51:10 -0500
Subject: [PATCH 2/5] regulator: pca9450: Use dev_err_probe() to simplify
 code
In-Reply-To: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
References: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
Message-ID: <20241205-pca9450-v1-2-aab448b74e78@nxp.com>

Use dev_err_probe() to simplify code.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/regulator/pca9450-regulator.c | 73 +++++++++++++----------------------
 1 file changed, 27 insertions(+), 46 deletions(-)

diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index caeeed433165c..0b1f099fdd5ee 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -932,25 +932,20 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 
 	pca9450->regmap = devm_regmap_init_i2c(i2c,
 					       &pca9450_regmap_config);
-	if (IS_ERR(pca9450->regmap)) {
-		dev_err(&i2c->dev, "regmap initialization failed\n");
-		return PTR_ERR(pca9450->regmap);
-	}
+	if (IS_ERR(pca9450->regmap))
+		return dev_err_probe(&i2c->dev, PTR_ERR(pca9450->regmap),
+				     "regmap initialization failed\n");
 
 	ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);
-	if (ret) {
-		dev_err(&i2c->dev, "Read device id error\n");
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(&i2c->dev, ret, "Read device id error\n");
 
 	/* Check your board and dts for match the right pmic */
 	if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
 	    ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC) ||
-	    ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A)) {
-		dev_err(&i2c->dev, "Device id(%x) mismatched\n",
-			device_id >> 4);
-		return -EINVAL;
-	}
+	    ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A))
+		return dev_err_probe(&i2c->dev, -EINVAL,
+				     "Device id(%x) mismatched\n", device_id >> 4);
 
 	for (i = 0; i < pca9450->rcnt; i++) {
 		const struct regulator_desc *desc;
@@ -964,13 +959,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 		config.dev = pca9450->dev;
 
 		rdev = devm_regulator_register(pca9450->dev, desc, &config);
-		if (IS_ERR(rdev)) {
-			ret = PTR_ERR(rdev);
-			dev_err(pca9450->dev,
-				"Failed to register regulator(%s): %d\n",
-				desc->name, ret);
-			return ret;
-		}
+		if (IS_ERR(rdev))
+			return dev_err_probe(pca9450->dev, PTR_ERR(rdev),
+					     "Failed to register regulator(%s)\n", desc->name);
 	}
 
 	if (pca9450->irq) {
@@ -978,29 +969,24 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 						pca9450_irq_handler,
 						(IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
 						"pca9450-irq", pca9450);
-		if (ret != 0) {
-			dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
-				pca9450->irq);
-			return ret;
-		}
+		if (ret != 0)
+			return dev_err_probe(pca9450->dev, ret, "Failed to request IRQ: %d\n",
+					     pca9450->irq);
+
 		/* Unmask all interrupt except PWRON/WDOG/RSVD */
 		ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,
 					IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |
 					IRQ_THERM_105 | IRQ_THERM_125,
 					IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);
-		if (ret) {
-			dev_err(&i2c->dev, "Unmask irq error\n");
-			return ret;
-		}
+		if (ret)
+			return dev_err_probe(&i2c->dev, ret, "Unmask irq error\n");
 	}
 
 	/* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */
 	ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS,
 				BUCK123_PRESET_EN);
-	if (ret) {
-		dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret);
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(&i2c->dev, ret,  "Failed to clear PRESET_EN bit\n");
 
 	if (of_property_read_bool(i2c->dev.of_node, "nxp,wdog_b-warm-reset"))
 		reset_ctrl = WDOG_B_CFG_WARM;
@@ -1010,20 +996,16 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 	/* Set reset behavior on assertion of WDOG_B signal */
 	ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
 				 WDOG_B_CFG_MASK, reset_ctrl);
-	if (ret) {
-		dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(&i2c->dev, ret, "Failed to set WDOG_B reset behavior\n");
 
 	if (of_property_read_bool(i2c->dev.of_node, "nxp,i2c-lt-enable")) {
 		/* Enable I2C Level Translator */
 		ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_CONFIG2,
 					 I2C_LT_MASK, I2C_LT_ON_STANDBY_RUN);
-		if (ret) {
-			dev_err(&i2c->dev,
-				"Failed to enable I2C level translator\n");
-			return ret;
-		}
+		if (ret)
+			return dev_err_probe(&i2c->dev, ret,
+					     "Failed to enable I2C level translator\n");
 	}
 
 	/*
@@ -1033,10 +1015,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 	 */
 	pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH);
 
-	if (IS_ERR(pca9450->sd_vsel_gpio)) {
-		dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
-		return PTR_ERR(pca9450->sd_vsel_gpio);
-	}
+	if (IS_ERR(pca9450->sd_vsel_gpio))
+		return dev_err_probe(&i2c->dev, PTR_ERR(pca9450->sd_vsel_gpio),
+				     "Failed to get SD_VSEL GPIO\n");
 
 	dev_info(&i2c->dev, "%s probed.\n",
 		type == PCA9450_TYPE_PCA9450A ? "pca9450a" :

-- 
2.34.1



From Frank.Li at nxp.com  Thu Dec  5 08:51:11 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 05 Dec 2024 11:51:11 -0500
Subject: [PATCH 3/5] regulator: dt-bindings: pca9450: Add pca9452 support
In-Reply-To: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
References: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
Message-ID: <20241205-pca9450-v1-3-aab448b74e78@nxp.com>

From: Joy Zou <joy.zou at nxp.com>

Add compatible string 'nxp,pca9452'. pca9452 add 'ldo3' compared with
pca9451a.

Signed-off-by: Joy Zou <joy.zou at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
index f8057bba747a5..68709a7dc43f1 100644
--- a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
@@ -29,6 +29,7 @@ properties:
       - nxp,pca9450b
       - nxp,pca9450c
       - nxp,pca9451a
+      - nxp,pca9452
 
   reg:
     maxItems: 1

-- 
2.34.1



From Frank.Li at nxp.com  Thu Dec  5 08:51:12 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 05 Dec 2024 11:51:12 -0500
Subject: [PATCH 4/5] regulator: pca9450: Add PMIC pca9452 support
In-Reply-To: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
References: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
Message-ID: <20241205-pca9450-v1-4-aab448b74e78@nxp.com>

From: Joy Zou <joy.zou at nxp.com>

Add the PMIC pca9452 support, which add ldo3 compared with pca9451a.

Signed-off-by: Joy Zou <joy.zou at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/regulator/pca9450-regulator.c | 29 ++++++++++++++++++++++++++++-
 include/linux/regulator/pca9450.h     |  1 +
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index 0b1f099fdd5ee..faa6b79c27d75 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -815,6 +815,24 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = {
 			.owner = THIS_MODULE,
 		},
 	},
+	{
+		.desc = {
+			.name = "ldo3",
+			.of_match = of_match_ptr("LDO3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO3,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo34_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
+			.vsel_reg = PCA9450_REG_LDO3CTRL,
+			.vsel_mask = LDO3OUT_MASK,
+			.enable_reg = PCA9450_REG_LDO3CTRL,
+			.enable_mask = LDO3_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
 	{
 		.desc = {
 			.name = "ldo4",
@@ -916,6 +934,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 		pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
 		break;
 	case PCA9450_TYPE_PCA9451A:
+	case PCA9450_TYPE_PCA9452:
 		regulator_desc = pca9451a_regulators;
 		pca9450->rcnt = ARRAY_SIZE(pca9451a_regulators);
 		break;
@@ -943,7 +962,8 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 	/* Check your board and dts for match the right pmic */
 	if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
 	    ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC) ||
-	    ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A))
+	    ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A) ||
+	    ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9452))
 		return dev_err_probe(&i2c->dev, -EINVAL,
 				     "Device id(%x) mismatched\n", device_id >> 4);
 
@@ -955,6 +975,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 		r = &regulator_desc[i];
 		desc = &r->desc;
 
+		if (type == PCA9450_TYPE_PCA9451A && !strcmp(desc->name, "ldo3"))
+			continue;
+
 		config.regmap = pca9450->regmap;
 		config.dev = pca9450->dev;
 
@@ -1043,6 +1066,10 @@ static const struct of_device_id pca9450_of_match[] = {
 		.compatible = "nxp,pca9451a",
 		.data = (void *)PCA9450_TYPE_PCA9451A,
 	},
+	{
+		.compatible = "nxp,pca9452",
+		.data = (void *)PCA9450_TYPE_PCA9452,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, pca9450_of_match);
diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h
index 243633c8dceb3..b427b5873de1a 100644
--- a/include/linux/regulator/pca9450.h
+++ b/include/linux/regulator/pca9450.h
@@ -10,6 +10,7 @@ enum pca9450_chip_type {
 	PCA9450_TYPE_PCA9450A = 0,
 	PCA9450_TYPE_PCA9450BC,
 	PCA9450_TYPE_PCA9451A,
+	PCA9450_TYPE_PCA9452,
 	PCA9450_TYPE_AMOUNT,
 };
 

-- 
2.34.1



From Frank.Li at nxp.com  Thu Dec  5 08:51:13 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 05 Dec 2024 11:51:13 -0500
Subject: [PATCH 5/5] arm64: dts: imx93: add pca9452 support
In-Reply-To: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
References: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
Message-ID: <20241205-pca9450-v1-5-aab448b74e78@nxp.com>

From: Joy Zou <joy.zou at nxp.com>

Support pca9452 on imx93-14x14-evk.

Signed-off-by: Joy Zou <joy.zou at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts | 83 +++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts b/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts
index 236a44c1782ae..348abb9ceae19 100644
--- a/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts
@@ -219,6 +219,89 @@ pcal6524: gpio at 22 {
 		interrupt-parent = <&gpio3>;
 		interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
 	};
+
+	pmic at 25 {
+		compatible = "nxp,pca9452";
+		reg = <0x25>;
+		interrupt-parent = <&pcal6524>;
+		interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+
+		regulators {
+			buck1: BUCK1 {
+				regulator-name = "BUCK1";
+				regulator-min-microvolt = <610000>;
+				regulator-max-microvolt = <950000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <3125>;
+			};
+
+			buck2: BUCK2 {
+				regulator-name = "BUCK2";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <670000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <3125>;
+			};
+
+			buck4: BUCK4{
+				regulator-name = "BUCK4";
+				regulator-min-microvolt = <1620000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck5: BUCK5{
+				regulator-name = "BUCK5";
+				regulator-min-microvolt = <1620000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck6: BUCK6 {
+				regulator-name = "BUCK6";
+				regulator-min-microvolt = <1060000>;
+				regulator-max-microvolt = <1140000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo1: LDO1 {
+				regulator-name = "LDO1";
+				regulator-min-microvolt = <1620000>;
+				regulator-max-microvolt = <1980000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo3: LDO3 {
+				regulator-name = "LDO3";
+				regulator-min-microvolt = <1710000>;
+				regulator-max-microvolt = <1890000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo4: LDO4 {
+				regulator-name = "LDO4";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <840000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo5: LDO5 {
+				regulator-name = "LDO5";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
 };
 
 &lpi2c3 {

-- 
2.34.1



From linux at armlinux.org.uk  Thu Dec  5 08:51:19 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 5 Dec 2024 16:51:19 +0000
Subject: [PATCH net-next v8 01/15] net: stmmac: Fix CSR divider comment
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-1-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
 <20241205-upstream_s32cc_gmac-v8-1-ec1d180df815@oss.nxp.com>
Message-ID: <Z1HaB6hT0QX4Jlyx@shell.armlinux.org.uk>

On Thu, Dec 05, 2024 at 05:42:58PM +0100, Jan Petrous via B4 Relay wrote:
> From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>
> 
> The comment in declaration of STMMAC_CSR_250_300M
> incorrectly describes the constant as '/* MDC = clk_scr_i/122 */'
> but the DWC Ether QOS Handbook version 5.20a says it is
> CSR clock/124.
> 
> Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
> Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>

I gave my reviewed-by for this patch in the previous posting, but you
haven't included it.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

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


From jan.petrous at oss.nxp.com  Thu Dec  5 08:55:22 2024
From: jan.petrous at oss.nxp.com (Jan Petrous)
Date: Thu, 5 Dec 2024 17:55:22 +0100
Subject: [PATCH net-next v8 01/15] net: stmmac: Fix CSR divider comment
In-Reply-To: <Z1HaB6hT0QX4Jlyx@shell.armlinux.org.uk>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
 <20241205-upstream_s32cc_gmac-v8-1-ec1d180df815@oss.nxp.com>
 <Z1HaB6hT0QX4Jlyx@shell.armlinux.org.uk>
Message-ID: <Z1Ha+me4+hbOj9JO@lsv051416.swis.nl-cdc01.nxp.com>

On Thu, Dec 05, 2024 at 04:51:19PM +0000, Russell King (Oracle) wrote:
> On Thu, Dec 05, 2024 at 05:42:58PM +0100, Jan Petrous via B4 Relay wrote:
> > From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>
> > 
> > The comment in declaration of STMMAC_CSR_250_300M
> > incorrectly describes the constant as '/* MDC = clk_scr_i/122 */'
> > but the DWC Ether QOS Handbook version 5.20a says it is
> > CSR clock/124.
> > 
> > Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
> > Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
> 
> I gave my reviewed-by for this patch in the previous posting, but you
> haven't included it.
> 
> Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Hi Russell,
sorry for that, I missed it. Should I resend the v8 series?

BR.
/Jan


From oliver.upton at linux.dev  Thu Dec  5 09:07:57 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 5 Dec 2024 09:07:57 -0800
Subject: [PATCH 06/11] KVM: arm64: nv: Acceletate EL0 counter accesses
 from hypervisor context
In-Reply-To: <86ikrytmr6.wl-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
 <20241202172134.384923-7-maz@kernel.org>
 <Z1D1zus18KCpCqjD@linux.dev>
 <86ikrytmr6.wl-maz@kernel.org>
Message-ID: <Z1Hd7U5gZS1RDxop@linux.dev>

On Thu, Dec 05, 2024 at 11:03:41AM +0000, Marc Zyngier wrote:
> On Thu, 05 Dec 2024 00:37:34 +0000,
> Oliver Upton <oliver.upton at linux.dev> wrote:
> > 
> > typo: accelerate
> 
> Huh, thanks!
> 
> > 
> > On Mon, Dec 02, 2024 at 05:21:29PM +0000, Marc Zyngier wrote:
> 
> [...]
> 
> > > +	case SYS_CNTVCT_EL0:
> > > +	case SYS_CNTVCTSS_EL0:
> > > +		/* If !ELIsInHost(EL2), the guest's CNTVOFF_EL2 applies */
> > 
> > !ELIsInHost(EL0)
> 
> No, and that's the whole point. CNTVOFF_EL2 applies at all times when
> HCR_EL2==0 and that we're at EL2. From the pseudocode for CNTVCT_EL0:

Dammit, I don't know how many times I misread "CNTPCT" here rather than
CNTVCT. Sorry for the noise.

-- 
Thanks,
Oliver


From suzuki.poulose at arm.com  Thu Dec  5 09:10:49 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 5 Dec 2024 17:10:49 +0000
Subject: [PATCH v12 0/8] Coresight for Kernel panic and watchdog reset
In-Reply-To: <20241129091255.GA1150491@hyd1403.caveonetworks.com>
References: <20241129084714.3057080-1-lcherian@marvell.com>
 <20241129091255.GA1150491@hyd1403.caveonetworks.com>
Message-ID: <5b232cf4-b8b5-44cd-977d-4a799f364e20@arm.com>

Hi Linu


On 29/11/2024 09:12, Linu Cherian wrote:
> Hi,
> 
> On 2024-11-29 at 14:17:06, Linu Cherian (lcherian at marvell.com) wrote:
>> This patch series is rebased on coresight-next-v6.12.rc4
>>
>> * Patches 1 & 2 adds support for allocation of trace buffer pages from reserved RAM
>> * Patches 3 & 4 adds support for saving metadata at the time of kernel panic
>> * Patch 5 adds support for reading trace data captured at the time of panic
>> * Patches 6 & 7 adds support for disabling coresight blocks at the time of panic
>> * Patch 8: Gives the full description about this feature as part of documentation
>>
>> V11 is posted here,
>> https://lore.kernel.org/linux-arm-kernel/20241111124746.2210378-1-lcherian at marvell.com/
>>
>> Changelog from v11:
>> Convert all commands to literal code blocks, that was missed out in v11.
>> No other code changes.
> 
> To make it clear, this is just some missed out fixes in Patch 8,
> Documentation.
> 

I have completed the review of this series. If you could address 
comments on Path 5, I am happy to queue this


Suzuki


>>
>> Changelog from v10:
>> * Converted all csdev_access_* to readl functions in tmc_panic_sync_*
>> * Added "tmc" prefix for register snapshots in struct tmc_crash_metadata
>> * Converted dev_info to dev_dbg in panic handlers
>> * Converted dsb to dmb in panic handlers
>> * Fixed marking metadata as invalid when a user is trying to use the
>>    reserved buffer. Earlier this was wrongly set at the time of reading
>>    reserved trace buffer.
>> * Moved common validation checks to is_tmc_crashdata_valid and minor
>>    code rearrangements for efficiency
>> * Got rid of sink specific prepare/unprepare invocations
>> * Got rid of full from struct tmc_resrv_buf
>> * While reading crashdata, size is now calculated from metdata instead
>>    of relying on reserved buffer size populated by dtb
>> * Minor documenation fixes
>>
>> Changelog from v9:
>> * Add common helper function of_tmc_get_reserved_resource_by_name
>>    for better code reuse
>> * Reserved buffer validity and crashdata validity has been separated to
>>    avoid interdependence
>> * New fields added to crash metadata: version, ffcr, ffsr, mode
>> * Version checks added for metadata validation
>> * Special file /dev/crash_tmc_xxx would be available only when
>>    crash metadata is valid
>> * Removed READ_CRASHDATA mode meant for special casing crashdata reads.
>>    Instead, dedicated read function added for crashdata reads from reserved
>>    buffer which is common for both ETR and ETF sinks as well.
>> * Documentation added to Documentation/tracing/coresight/panic.rst
>>
>> Changelog from v8:
>> * Added missing exit path on error in __tmc_probe.
>> * Few whitespace fixes, checkpatch fixes.
>> * With perf sessions honouring stop_on_flush sysfs attribute,
>>    removed redundant variable stop_on_flush_en.
>>
>> Changelog from v7:
>> * Fixed breakage on perf test -vvvv  "arm coresight".
>>    No issues seen with and without "resrv" buffer mode
>> * Moved the crashdev registration into a separate function.
>> * Removed redundant variable in tmc_etr_setup_crashdata_buf
>> * Avoided a redundant memcpy in tmc_panic_sync_etf.
>> * Tested kernel panic with trace session started uisng perf.
>>    Please see the title "Perf based testing" below for details.
>>    For this, stop_on_flush sysfs attribute is taken into
>>    consideration while starting perf sessions as well.
>>
>> Changelog from v6:
>> * Added special device files for reading crashdata, so that
>>    read_prevboot mode flag is removed.
>> * Added new sysfs TMC device attribute, stop_on_flush.
>>    Stop on flush trigger event is disabled by default.
>>    User need to explicitly enable this from sysfs for panic stop
>>    to work.
>> * Address parameter for panicstop ETM configuration is
>>    chosen as kernel "panic" address by default.
>> * Added missing tmc_wait_for_tmcready during panic handling
>> * Few other misc code rearrangements.
>>
>> Changelog from v5:
>> * Fixed issues reported by CONFIG_DEBUG_ATOMIC_SLEEP
>> * Fixed a memory leak while reading data from /dev/tmc_etrx in
>>    READ_PREVBOOT mode
>> * Tested reading trace data from crashdump kernel
>>
>> Changelog from v4:
>> * Device tree binding
>>    - Description is made more explicit on the usage of reserved memory
>>      region
>>    - Mismatch in memory region names in dts binding and driver fixed
>>    - Removed "mem" suffix from the memory region names
>> * Rename "struct tmc_register_snapshot" ->  "struct tmc_crash_metadata",
>>    since it contains more than register snapshot.
>>    Related variables are named accordingly.
>> * Rename struct tmc_drvdata members
>>     resrv_buf -> crash_tbuf
>>     metadata  -> crash_mdata
>> * Size field in metadata refers to RSZ register and hence indicates the
>>    size in 32 bit words. ETR metadata follows this convention, the same
>>    has been extended to ETF metadata as well.
>> * Added crc32 for more robust metadata and tracedata validation.
>> * Added/modified dev_dbg messages during metadata validation
>> * Fixed a typo in patch 5 commit description
>>
>> Changelog from v3:
>> * Converted the Coresight ETM driver change to a named configuration.
>>    RFC tag has been removed with this change.
>> * Fixed yaml issues reported by "make dt_binding_check"
>> * Added names for reserved memory regions 0 and 1
>> * Added prevalidation checks for metadata processing
>> * Fixed a regression introduced in RFC v3
>>    - TMC Status register was getting saved wrongly
>> * Reverted memremap attribute changes from _WB to _WC to match
>>    with the dma map attributes
>> * Introduced reserved buffer mode specific .sync op.
>>    This fixes a possible crash when reserved buffer mode was used in
>>    normal trace capture, due to unwanted dma maintenance operations.
>>
>>
>>
>>   
>> Linu Cherian (8):
>>    dt-bindings: arm: coresight-tmc: Add "memory-region" property
>>    coresight: tmc-etr: Add support to use reserved trace memory
>>    coresight: core: Add provision for panic callbacks
>>    coresight: tmc: Enable panic sync handling
>>    coresight: tmc: Add support for reading crash data
>>    coresight: tmc: Stop trace capture on FlIn
>>    coresight: config: Add preloaded configuration
>>    Documentation: coresight: Panic support
>>
>>   .../bindings/arm/arm,coresight-tmc.yaml       |  26 ++
>>   Documentation/trace/coresight/panic.rst       | 362 ++++++++++++++++++
>>   drivers/hwtracing/coresight/Makefile          |   2 +-
>>   .../coresight/coresight-cfg-preload.c         |   2 +
>>   .../coresight/coresight-cfg-preload.h         |   2 +
>>   .../hwtracing/coresight/coresight-cfg-pstop.c |  83 ++++
>>   drivers/hwtracing/coresight/coresight-core.c  |  42 ++
>>   .../hwtracing/coresight/coresight-tmc-core.c  | 326 +++++++++++++++-
>>   .../hwtracing/coresight/coresight-tmc-etf.c   |  92 ++++-
>>   .../hwtracing/coresight/coresight-tmc-etr.c   | 181 ++++++++-
>>   drivers/hwtracing/coresight/coresight-tmc.h   | 104 +++++
>>   include/linux/coresight.h                     |  12 +
>>   12 files changed, 1222 insertions(+), 12 deletions(-)
>>   create mode 100644 Documentation/trace/coresight/panic.rst
>>   create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pstop.c
>>
>> -- 
>> 2.34.1
>>
>>



From conor at kernel.org  Thu Dec  5 09:14:19 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 5 Dec 2024 17:14:19 +0000
Subject: [PATCH 4/6] dt-bindings: arm: rockchip: Sort for rk3568 evb
In-Reply-To: <20241205103623.878181-5-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
 <20241205103623.878181-5-kever.yang@rock-chips.com>
Message-ID: <20241205-twisted-vintage-c4db864b6049@spud>

On Thu, Dec 05, 2024 at 06:36:21PM +0800, Kever Yang wrote:
> The info for rk3568 should before rk3588.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>

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/20241205/974a41bf/attachment.sig>

From conor at kernel.org  Thu Dec  5 09:14:48 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 5 Dec 2024 17:14:48 +0000
Subject: [PATCH 5/6] dt-bindings: arm: rockchip: Add rk3576 evb1 board
In-Reply-To: <20241205103623.878181-6-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
 <20241205103623.878181-6-kever.yang@rock-chips.com>
Message-ID: <20241205-judicial-drainpipe-645f3abe07fd@spud>

On Thu, Dec 05, 2024 at 06:36:22PM +0800, Kever Yang wrote:
> Add device tree documentation for rk3576-evb1-v10.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
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/20241205/0cefe479/attachment.sig>

From dmitry.baryshkov at linaro.org  Thu Dec  5 09:15:18 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Dec 2024 19:15:18 +0200
Subject: [PATCH v3 3/7] arm64: dts: qcom: Add PMIH0108 PMIC
In-Reply-To: <20241204-sm8750_master_dt-v3-3-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
 <20241204-sm8750_master_dt-v3-3-4d5a8269950b@quicinc.com>
Message-ID: <4i4y5sajd7dmqjm7snjxmj2v64hadj52reo6utztvk4lsulwax@p5yq7swn3z2q>

On Wed, Dec 04, 2024 at 03:18:03PM -0800, Melody Olvera wrote:
> Add descriptions of PMIH0108 PMIC used on SM8750 platforms.
> 
> Signed-off-by: Jishnu Prakash <quic_jprakash at quicinc.com>
> Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
> ---
>  arch/arm64/boot/dts/qcom/pmih0108.dtsi | 68 ++++++++++++++++++++++++++++++++++
>  1 file changed, 68 insertions(+)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Thu Dec  5 09:15:44 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Dec 2024 19:15:44 +0200
Subject: [PATCH v3 2/7] arm64: dts: qcom: Add PMD8028 PMIC
In-Reply-To: <20241204-sm8750_master_dt-v3-2-4d5a8269950b@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
 <20241204-sm8750_master_dt-v3-2-4d5a8269950b@quicinc.com>
Message-ID: <jnqgccc6penjqmkhursdlbc46xctikvovfa26vlsvttxwqo5zv@uwh7fhixrmrz>

On Wed, Dec 04, 2024 at 03:18:02PM -0800, Melody Olvera wrote:
> Add descriptions of PMD8028 PMIC used on SM8750 platforms.
> 
> Signed-off-by: Jishnu Prakash <quic_jprakash at quicinc.com>
> Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
> ---
>  arch/arm64/boot/dts/qcom/pmd8028.dtsi | 62 +++++++++++++++++++++++++++++++++++
>  1 file changed, 62 insertions(+)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> 

-- 
With best wishes
Dmitry


From ansuelsmth at gmail.com  Thu Dec  5 09:17:18 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu, 5 Dec 2024 18:17:18 +0100
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241205162759.pm3iz42bhdsvukfm@skbuf>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
Message-ID: <6751e023.5d0a0220.394b90.7bc9@mx.google.com>

On Thu, Dec 05, 2024 at 06:27:59PM +0200, Vladimir Oltean wrote:
> On Thu, Dec 05, 2024 at 03:51:33PM +0100, Christian Marangi wrote:
> > +static int an8855_efuse_read(void *context, unsigned int offset,
> > +			     void *val, size_t bytes)
> > +{
> > +	struct an8855_priv *priv = context;
> > +
> > +	return regmap_bulk_read(priv->regmap, AN8855_EFUSE_DATA0 + offset,
> > +				val, bytes / sizeof(u32));
> > +}
> > +
> > +static struct nvmem_config an8855_nvmem_config = {
> > +	.name = "an8855-efuse",
> > +	.size = AN8855_EFUSE_CELL * sizeof(u32),
> > +	.stride = sizeof(u32),
> > +	.word_size = sizeof(u32),
> > +	.reg_read = an8855_efuse_read,
> > +};
> > +
> > +static int an8855_sw_register_nvmem(struct an8855_priv *priv)
> > +{
> > +	struct nvmem_device *nvmem;
> > +
> > +	an8855_nvmem_config.priv = priv;
> > +	an8855_nvmem_config.dev = priv->dev;
> > +	nvmem = devm_nvmem_register(priv->dev, &an8855_nvmem_config);
> > +	if (IS_ERR(nvmem))
> > +		return PTR_ERR(nvmem);
> > +
> > +	return 0;
> > +}
> 
> At some point we should enforce the rule that new drivers for switch
> SoCs with complex peripherals should use MFD and move all non-networking
> peripherals to drivers handled by their respective subsystems.
> 
> I don't have the expertise to review a nvmem driver, and the majority of
> them are in drivers/nvmem, with a dedicated subsystem and maintainer.
> In general I want to make sure it is clear that I don't encourage the
> model where DSA owns the entire mdio_device.
> 
> What other peripherals are there on this SoC other than an MDIO bus and
> an EFUSE? IRQCHIP, GPIOs, LED controller, sensors?
> 
> You can take a look at drivers/mfd/ocelot* and
> Documentation/devicetree/bindings/mfd/mscc,ocelot.yaml for an example on
> how to use mfd for the top-level MDIO device, and DSA as just the driver
> for the Ethernet switch component (which will be represented as a
> platform_device).

Hi Vladimir,

I checked the examples and one problems that comes to me is how to model
this if only MDIO is used as a comunication method. Ocelot have PCIE or
SPI but this switch only comunicate with MDIO on his address. So where
should I place the SoC or MFD node? In the switch root node?

Also the big problem is how to model accessing the register with MDIO
with an MFD implementation.

Anyway just to make sure the Switch SoC doesn't expose an actualy MDIO
bus, that is just to solve the problem with the Switch Address shared
with one of the port. (Switch Address can be accessed by every switch
port with a specific page set)

But yes the problem is there... Function is not implemented but the
switch have i2c interface, minimal CPU, GPIO and Timer in it.

Happy to make the required changes, just very confused on how the final
DT node structure.

-- 
	Ansuel


From ptesarik at suse.com  Thu Dec  5 09:20:08 2024
From: ptesarik at suse.com (Petr Tesarik)
Date: Thu, 5 Dec 2024 18:20:08 +0100
Subject: [RFC PATCH v1 00/57] Boot-time page size selection for arm64
In-Reply-To: <aa9a7118-3067-448e-aa34-bbc148c921a2@arm.com>
References: <20241014105514.3206191-1-ryan.roberts@arm.com>
	<20241017142752.17f2c816@mordecai.tesarici.cz>
	<aa9a7118-3067-448e-aa34-bbc148c921a2@arm.com>
Message-ID: <20241205182008.2b36476a@mordecai.tesarici.cz>

Hi Ryan,

On Thu, 17 Oct 2024 13:32:43 +0100
Ryan Roberts <ryan.roberts at arm.com> wrote:

> On 17/10/2024 13:27, Petr Tesarik wrote:
> > On Mon, 14 Oct 2024 11:55:11 +0100
> > Ryan Roberts <ryan.roberts at arm.com> wrote:
> >   
> >> [...]
> >> The series is arranged as follows:
> >>
> >>   - patch 1:	   Add macros required for converting non-arch code to support
> >>   		   boot-time page size selection
> >>   - patches 2-36:  Remove PAGE_SIZE compile-time constant assumption from all
> >>   		   non-arch code  
> > 
> > I have just tried to recompile the openSUSE kernel with these patches
> > applied, and I'm running into this:
> > 
> >   CC      arch/arm64/hyperv/hv_core.o
> > In file included from ../arch/arm64/hyperv/hv_core.c:14:0:
> > ../include/linux/hyperv.h:158:5: error: variably modified ?reserved2? at file scope
> >   u8 reserved2[PAGE_SIZE - 68];
> >      ^~~~~~~~~
> > 
> > It looks like one more place which needs a patch, right?  
> 
> As mentioned in the cover letter, so far I've only converted enough to get the
> defconfig *image* building (i.e. no modules). If you are compiling a different
> config or compiling the modules for defconfig, you will likely run into these
> types of issues.
> 
> That said, I do have some patches to fix Hyper-V, which Michael Kelley was kind
> enough to send me.
> 
> I understand that Suse might be able to help with wider performance testing - if
> that's the reason you are trying to compile, you could send me your config and
> I'll start working on fixing up other drivers?

This project was de-prioritised for some time, but I have just returned
to it, and one of our test systems uses a Mellanox 5 NIC, which did not build.

If you still have time to work on your patch series, please, can you
look into enabling MLX5_CORE_EN?

Oh, and have you rebased the series to 6.12 yet?

Petr T


From helgaas at kernel.org  Thu Dec  5 09:20:22 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 5 Dec 2024 11:20:22 -0600
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <569904ad-2b70-4a58-98fe-4f24e1089e17@foss.st.com>
Message-ID: <20241205172022.GA3053765@bhelgaas>

[cc->to: Rob for RC/RP separation conversation]

On Thu, Dec 05, 2024 at 02:41:26PM +0100, Christian Bruel wrote:
> On 12/3/24 23:25, Bjorn Helgaas wrote:
> > On Tue, Nov 26, 2024 at 04:51:15PM +0100, Christian Bruel wrote:
> > > Document the bindings for STM32MP25 PCIe Controller configured in
> > > root complex mode.
> > > 
> > > Supports 4 legacy interrupts and MSI interrupts from the ARM
> > > GICv2m controller.

> > > +  wake-gpios:
> > > +    description: GPIO controlled connection to WAKE# input signal
> > 
> > I'm not a hardware guy, but this sounds like a GPIO that *reads*
> > WAKE#, not controls it.
> 
> Rephrasing as
> "GPIO used as WAKE# input signal" (output for the endpoint bindings)

Perfect, that makes a lot of sense.

> > > +    pcie at 48400000 {
> > > +        compatible = "st,stm32mp25-pcie-rc";
> > > +        device_type = "pci";
> > > +        num-lanes = <1>;
> > 
> > num-lanes applies to a Root Port, not to a Root Complex.  I know most
> > bindings conflate Root Ports with the Root Complex, maybe because many
> > of these controllers only support a single Root Port?
> > 
> > But are we ever going to separate these out?  I assume someday
> > controllers will support multiple Root Ports and/or additional devices
> > on the root bus, like RCiEPs, RCECs, etc., and we'll need per-RP phys,
> > max-link-speed, num-lanes, reset-gpios, etc.
> > 
> > Seems like it would be to our benefit to split out the Root Ports when
> > we can, even if the current hardware only supports one, so we can
> > start untangling the code and data structures.
> 
> OK. and we support only 1 lane anyway, so drop it.

Makes sense.  What about phys, resets, etc?  I'm pretty sure a PHY
would be a per-Root Port thing, and some resets and wakeup signals
also.

For new drivers, I think we should start adding Root Port stanzas to
specifically associate those things with the Root Port, e.g.,
something like this?

  pcie at 48400000 {
    compatible = "st,stm32mp25-pcie-rc";

    pcie at 0,0 {
      reg = <0x0000 0 0 0 0>;
      phys = <&combophy PHY_TYPE_PCIE>;
      phy-names = "pcie-phy";
    };
  };

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pci/mediatek,mt7621-pcie.yaml?id=v6.12#n111
is one binding that does this, others include apple,pcie.yaml,
brcm,stb-pcie.yaml, hisilicon,kirin-pcie.yaml.

Bjorn


From helgaas at kernel.org  Thu Dec  5 09:23:10 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 5 Dec 2024 11:23:10 -0600
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <20241126155119.1574564-2-christian.bruel@foss.st.com>
Message-ID: <20241205172310.GA3055111@bhelgaas>

On Tue, Nov 26, 2024 at 04:51:15PM +0100, Christian Bruel wrote:
> Document the bindings for STM32MP25 PCIe Controller configured in
> root complex mode.
> ...

> +        power-domains = <&CLUSTER_PD>;
> +    };
> +

Nit:

  Applying: dt-bindings: PCI: Add STM32MP25 PCIe root complex bindings
  .git/rebase-apply/patch:163: new blank line at EOF.
  +
  warning: 1 line adds whitespace errors.



From linux at armlinux.org.uk  Thu Dec  5 08:43:22 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 5 Dec 2024 16:43:22 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unaligned DMA unmap for
 non-paged SKB data
In-Reply-To: <20241205091830.3719609-1-0x1207@gmail.com>
References: <20241205091830.3719609-1-0x1207@gmail.com>
Message-ID: <Z1HYKh9eCwkYGlrA@shell.armlinux.org.uk>

I'm slightly disappointed to have my patch turned into a commit under
someone else's authorship before I've had a chance to do that myself.
Next time I won't send a patch out until I've done that.

On Thu, Dec 05, 2024 at 05:18:30PM +0800, Furong Xu wrote:
> Commit 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap for
> non-paged SKB data") assigns a wrong DMA buffer address that is added an
> offset of proto_hdr_len to tx_q->tx_skbuff_dma[entry].buf on a certain
> platform that the DMA AXI address width is configured to 40-bit/48-bit,
> stmmac_tx_clean() will try to unmap this illegal DMA buffer address
> and many crashes are reported: [1] [2].

This should mention that the DMA mapping API requires the cookie that is
returned from dma_map_single() be passed in unaltered to
dma_unmap_single(), and this driver does not do that when the DMA
address width is greater than 32-bit.

> 
> This patch guarantees that DMA address is passed to stmmac_tx_clean()
> unmodified and without offset.
> 
> [1] https://lore.kernel.org/all/d8112193-0386-4e14-b516-37c2d838171a at nvidia.com/
> [2] https://lore.kernel.org/all/klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc at bwwhelz2l4dw/
> 
> Reported-by: Jon Hunter <jonathanh at nvidia.com>
> Reported-by: Thierry Reding <thierry.reding at gmail.com>
> Suggested-by: Russell King (Oracle) <linux at armlinux.org.uk>

Please use rmk+kernel at armlinux.org.uk there.

> Fixes: 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data")
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 9b262cdad60b..7227f8428b5e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4192,8 +4192,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  	struct stmmac_txq_stats *txq_stats;
>  	struct stmmac_tx_queue *tx_q;
>  	u32 pay_len, mss, queue;
> +	dma_addr_t tso_hdr, des;
>  	u8 proto_hdr_len, hdr;
> -	dma_addr_t des;
>  	bool set_ic;
>  	int i;
>  
> @@ -4279,6 +4279,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  			     DMA_TO_DEVICE);
>  	if (dma_mapping_error(priv->device, des))
>  		goto dma_map_err;
> +	tso_hdr = des;
>  
>  	if (priv->dma_cap.addr64 <= 32) {
>  		first->des0 = cpu_to_le32(des);
> @@ -4310,7 +4311,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  	 * this DMA buffer right after the DMA engine completely finishes the
>  	 * full buffer transmission.
>  	 */
> -	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
> +	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = tso_hdr;
>  	tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
>  	tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
>  	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
> -- 
> 2.34.1
> 
> 

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


From kuba at kernel.org  Thu Dec  5 08:55:39 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Thu, 5 Dec 2024 08:55:39 -0800
Subject: [PATCH net v1] net: stmmac: TSO: Fix unaligned DMA unmap for
 non-paged SKB data
In-Reply-To: <Z1HYKh9eCwkYGlrA@shell.armlinux.org.uk>
References: <20241205091830.3719609-1-0x1207@gmail.com>
	<Z1HYKh9eCwkYGlrA@shell.armlinux.org.uk>
Message-ID: <20241205085539.0258e5fb@kernel.org>

On Thu, 5 Dec 2024 16:43:22 +0000 Russell King (Oracle) wrote:
> I'm slightly disappointed to have my patch turned into a commit under
> someone else's authorship before I've had a chance to do that myself.
> Next time I won't send a patch out until I've done that.

Yes, this is definitely not okay. LMK if you dropped this from your
TODO already, otherwise I'm tossing this patch and expecting the fix
from the real author.

Side rant - the Suggested-by tag is completely meaningless, maybe we
should stop using it. The usage ranges from crediting people pointing
out issues in basic code review, to crediting authors when stealing
their code. What is the point.


From linux at armlinux.org.uk  Thu Dec  5 08:58:02 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 5 Dec 2024 16:58:02 +0000
Subject: [PATCH net-next v8 07/15] net: dwmac-intel-plat: Use helper
 rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-7-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
 <20241205-upstream_s32cc_gmac-v8-7-ec1d180df815@oss.nxp.com>
Message-ID: <Z1Hbml22IgrTyzeN@shell.armlinux.org.uk>

On Thu, Dec 05, 2024 at 05:43:04PM +0100, Jan Petrous via B4 Relay wrote:
> From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>
> 
> Utilize a new helper function rgmii_clock().
> 
> When in, remove dead code in kmb_eth_fix_mac_speed().
> 
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.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 broonie at kernel.org  Thu Dec  5 08:58:31 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 5 Dec 2024 16:58:31 +0000
Subject: [PATCH 5/5] arm64: dts: imx93: add pca9452 support
In-Reply-To: <20241205-pca9450-v1-5-aab448b74e78@nxp.com>
References: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
 <20241205-pca9450-v1-5-aab448b74e78@nxp.com>
Message-ID: <b5b07f6f-a5c5-4b29-ada3-962dbbba42d4@sirena.org.uk>

On Thu, Dec 05, 2024 at 11:51:13AM -0500, Frank Li wrote:

> +				regulator-name = "BUCK1";
> +				regulator-min-microvolt = <610000>;
> +				regulator-max-microvolt = <950000>;

> +				regulator-name = "BUCK4";
> +				regulator-min-microvolt = <1620000>;
> +				regulator-max-microvolt = <3400000>;

The regulators all have really wide ranges, especially with no obvious
consumers specified.  Are these actually valid for the board?
-------------- 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/20241205/2cdb302d/attachment.sig>

From sudeep.holla at arm.com  Thu Dec  5 09:01:45 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 5 Dec 2024 17:01:45 +0000
Subject: [PATCH V4 0/5] arm_scmi: vendors: Qualcomm Generic Vendor
 Extensions
In-Reply-To: <Z0BC203BhGEmXcJi@hovoldconsulting.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <ZytnRc94iKUfMYH0@hovoldconsulting.com>
 <ZyvLktLUZOGP-LH5@pluto>
 <Zy4qvedrmkRdPR3x@hovoldconsulting.com>
 <8d42682b-0fa7-3962-da12-728cfe64903b@quicinc.com>
 <Z0BC203BhGEmXcJi@hovoldconsulting.com>
Message-ID: <Z1HceQegfMl07qj_@bogus>

On Fri, Nov 22, 2024 at 09:37:47AM +0100, Johan Hovold wrote:
> On Thu, Nov 14, 2024 at 09:52:12AM +0530, Sibi Sankar wrote:
> > On 11/8/24 20:44, Johan Hovold wrote:
>
> > >> On Wed, Nov 06, 2024 at 01:55:33PM +0100, Johan Hovold wrote:
>
> > >>> Second, after loading the protocol and client drivers manually (in that
> > >>> order, shouldn't the client driver pull in the protocol?), I got:
> > >>>
> > >>> 	scmi_module: Loaded SCMI Vendor Protocol 0x80 - Qualcomm  20000
> > >>> 	arm-scmi arm-scmi.0.auto: QCOM Generic Vendor Version 1.0
> > >>> 	scmi-qcom-generic-ext-memlat scmi_dev.5: error -EOPNOTSUPP: failed to configure common events
> > >>> 	scmi-qcom-generic-ext-memlat scmi_dev.5: probe with driver scmi-qcom-generic-ext-memlat failed with error -95
> > >>>
> > >>> which seems to suggest that the firmware on my CRD does not support this
> > >>> feature. Is that the way this should be interpreted? And does that mean
> > >>> that non of the commercial laptops supports this either?
>
> > > Yeah, hopefully Sibi can shed some light on this. I'm using the DT
> > > patch (5/5) from this series, which according to the commit message is
> > > supposed to enable bus scaling on the x1e80100 platform. So I guess
> > > something is missing in my firmware.
> >
> > Nah, it's probably just because of the algo string used.
> > The past few series used caps MEMLAT string instead of
> > memlat to pass the tuneables, looks like all the laptops
> > havn't really switched to it yet. Will revert back to
> > using to lower case memlat so that all devices are
> > supported. Thanks for trying the series out!
>
> I have a Lenovo ThinkPad T14s set up now so I gave this series a spin
> there too, and there I do *not* see the above mentioned -EOPNOSUPP error
> and the memlat driver probes successfully.
>
> On the other hand, this series seems to have no effect on a kernel
> compilation benchmark. Is that expected?
>

Hijacking this thread to rant about state of firmware implementation on
this platform that gives me zero confidence in merging any of these without
examining each of the interface details in depth and at lengths.

Also I see the standard protocol like PERF seem to have so many issues which
adds to my no confidence. I can't comment on that thread for specific reasons.

I will briefly mention my suspicion here. This Lenovo ThinkPad T14s being
primarily targeting other OS using ACPI might have just implemented what is
required for ACPI CPPC which conveniently doesn't have to discover lot of
fastchannel details since they are supplied in the tables straight away.
But that also would mean it could be not fully compliant to SCMI spec.

Either we need to run some compliance test suite(which again may need more
work as it is unfortunately make platform specific - referring to [1])
or use the raw interface in the kernel and throw /dev/random at it and see
how well it can cope up.

--
Regards,
Sudeep

[1] https://gitlab.arm.com/tests/scmi-tests (Not so great and needs platform
     specific vectors to check compliance)


From linux at armlinux.org.uk  Thu Dec  5 09:01:23 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 5 Dec 2024 17:01:23 +0000
Subject: [PATCH net-next v8 01/15] net: stmmac: Fix CSR divider comment
In-Reply-To: <Z1Ha+me4+hbOj9JO@lsv051416.swis.nl-cdc01.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
 <20241205-upstream_s32cc_gmac-v8-1-ec1d180df815@oss.nxp.com>
 <Z1HaB6hT0QX4Jlyx@shell.armlinux.org.uk>
 <Z1Ha+me4+hbOj9JO@lsv051416.swis.nl-cdc01.nxp.com>
Message-ID: <Z1HcYyNG4FfnN84s@shell.armlinux.org.uk>

On Thu, Dec 05, 2024 at 05:55:22PM +0100, Jan Petrous wrote:
> On Thu, Dec 05, 2024 at 04:51:19PM +0000, Russell King (Oracle) wrote:
> > On Thu, Dec 05, 2024 at 05:42:58PM +0100, Jan Petrous via B4 Relay wrote:
> > > From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>
> > > 
> > > The comment in declaration of STMMAC_CSR_250_300M
> > > incorrectly describes the constant as '/* MDC = clk_scr_i/122 */'
> > > but the DWC Ether QOS Handbook version 5.20a says it is
> > > CSR clock/124.
> > > 
> > > Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
> > > Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
> > 
> > I gave my reviewed-by for this patch in the previous posting, but you
> > haven't included it.
> > 
> > Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> 
> Hi Russell,
> sorry for that, I missed it. Should I resend the v8 series?

Patchwork will add it if this series is merged, so there's no immediate
need to resend. However, please update your series with it in case there
is another reason to send another version.

Thanks.

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


From suzuki.poulose at arm.com  Thu Dec  5 09:01:51 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 5 Dec 2024 17:01:51 +0000
Subject: [PATCH v12 5/8] coresight: tmc: Add support for reading crash
 data
In-Reply-To: <20241129084714.3057080-6-lcherian@marvell.com>
References: <20241129084714.3057080-1-lcherian@marvell.com>
 <20241129084714.3057080-6-lcherian@marvell.com>
Message-ID: <b56cbd79-61a4-49c3-82ce-12ca55a40991@arm.com>

Hi Linu,

On 29/11/2024 08:47, Linu Cherian wrote:
> * Add support for reading crashdata using special device files.
>    The special device files /dev/crash_tmc_xxx would be available
>    for read file operation only when the crash data is valid.
> 
> * User can read the crash data as below
> 
>    For example, for reading crash data from tmc_etf sink
> 
>    #dd if=/dev/crash_tmc_etfXX of=~/cstrace.bin
> 

Unfortunately there is still a bug that I picked up, see below for the 
barrier_packet insertion.

> Signed-off-by: Anil Kumar Reddy <areddy3 at marvell.com>
> Signed-off-by: Tanmay Jagdale <tanmay at marvell.com>
> Signed-off-by: Linu Cherian <lcherian at marvell.com>
> ---
>   .../hwtracing/coresight/coresight-tmc-core.c  | 231 +++++++++++++++++-
>   .../hwtracing/coresight/coresight-tmc-etr.c   |  19 +-
>   drivers/hwtracing/coresight/coresight-tmc.h   |  13 +-
>   3 files changed, 260 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index 1e3938ec12cb..5f3789314c4d 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -105,6 +105,151 @@ u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata)
>   	return mask;
>   }
>   
> +bool is_tmc_crashdata_valid(struct tmc_drvdata *drvdata)
> +{
> +	struct tmc_crash_metadata *mdata;
> +
> +	if (!tmc_has_reserved_buffer(drvdata) ||
> +	    !tmc_has_crash_mdata_buffer(drvdata))
> +		return false;
> +
> +	mdata = drvdata->crash_mdata.vaddr;
> +
> +	/* Check version match */
> +	if (mdata->version != CS_CRASHDATA_VERSION)
> +		return false;
> +
> +	/* Check for valid metadata */
> +	if (!mdata->valid) {
> +		dev_dbg(&drvdata->csdev->dev,
> +			"Data invalid in tmc crash metadata\n");
> +		return false;
> +	}
> +
> +	/*
> +	 * Buffer address given by metadata for retrieval of trace data
> +	 * from previous boot is expected to be same as the reserved
> +	 * trace buffer memory region provided through DTS
> +	 */
> +	if (drvdata->resrv_buf.paddr != mdata->trace_paddr) {
> +		dev_dbg(&drvdata->csdev->dev,
> +			"Trace buffer address of previous boot invalid\n");
> +		return false;
> +	}
> +
> +	/* Check data integrity of metadata */
> +	if (mdata->crc32_mdata != find_crash_metadata_crc(mdata)) {
> +		dev_dbg(&drvdata->csdev->dev,
> +			"CRC mismatch in tmc crash metadata\n");
> +		return false;
> +	}
> +	/* Check data integrity of tracedata */
> +	if (mdata->crc32_tdata != find_crash_tracedata_crc(drvdata, mdata)) {
> +		dev_dbg(&drvdata->csdev->dev,
> +			"CRC mismatch in tmc crash tracedata\n");
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
> +int tmc_read_prepare_crashdata(struct tmc_drvdata *drvdata)
> +{
> +	int ret = 0;
> +	u32 status, size;
> +	u64 rrp, rwp, dba;
> +	unsigned long flags;
> +	struct tmc_resrv_buf *rbuf;
> +	struct tmc_crash_metadata *mdata;
> +
> +	spin_lock_irqsave(&drvdata->spinlock, flags);
> +
> +	if (drvdata->reading) {
> +		ret = -EBUSY;
> +		goto out;
> +	}
> +
> +	if (!is_tmc_crashdata_valid(drvdata)) {
> +		ret = -ENXIO;
> +		goto out;
> +	}
> +
> +	mdata = drvdata->crash_mdata.vaddr;
> +	rbuf = &drvdata->resrv_buf;
> +
> +	rrp = mdata->tmc_rrp;
> +	rwp = mdata->tmc_rwp;
> +	dba = mdata->tmc_dba;
> +	status = mdata->tmc_sts;
> +	size = mdata->tmc_ram_size << 2;
> +
> +	/* Sync the buffer pointers */
> +	rbuf->offset = rrp - dba;
> +	if (status & TMC_STS_FULL)
> +		rbuf->len = size;
> +	else
> +		rbuf->len = rwp - rrp;
> +

I believe all of the above can be done one time probe and don't need to
be repeated every time we do a read_prepare() ?


> +	/* Additional sanity checks for validating metadata */
> +	if ((rbuf->offset > size) ||
> +	    (rbuf->len > size)) {
> +		dev_dbg(&drvdata->csdev->dev,
> +			"Offset and length invalid in tmc crash metadata\n");
> +		return -EINVAL;
> +	}

Ideally this should also be done once and "don't expose" crash_tmc
device if the above is invalid in metada.


> +
> +	if (status & 0x1)

minor nit: s/0x1/TMC_STS_FULL ?

> +		coresight_insert_barrier_packet(drvdata->buf);

And this looks completely out of nowhere and corrupting the drvdata->buf 
? drvdata->buf is for active sessions, which we haven't set here ?


> +
> +	drvdata->reading = true;

Also, we agreed to not overload "drvdata->reading" ?

See 
https://lkml.kernel.org/r/20241017114054.GC896339 at hyd1403.caveonetworks.com

We are allowed to the ETR (which drvdata->reading prevents from btw) 
while crash data is being read. You could instead move it to
drvdata->resrv_buf->reading ?



Suzuki


> +out:
> +	spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +	return ret;
> +}
> +
> +int tmc_read_unprepare_crashdata(struct tmc_drvdata *drvdata)
> +{
> +	unsigned long flags;
> +	struct tmc_resrv_buf *rbuf;
> +
> +	spin_lock_irqsave(&drvdata->spinlock, flags);
> +
> +	rbuf = &drvdata->resrv_buf;
> +	/* Reset valid length */
> +	rbuf->len = 0;
> +
> +	drvdata->reading = false;
> +	spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +
> +	return 0;
> +}
> +
> +static inline ssize_t tmc_get_resvbuf_trace(struct tmc_drvdata *drvdata,
> +					  loff_t pos, size_t len, char **bufpp)
> +{
> +	s64 offset;
> +	ssize_t actual = len;
> +	struct tmc_resrv_buf *rbuf = &drvdata->resrv_buf;
> +
> +	if (pos + actual > rbuf->len)
> +		actual = rbuf->len - pos;
> +	if (actual <= 0)
> +		return 0;
> +
> +	/* Compute the offset from which we read the data */
> +	offset = rbuf->offset + pos;
> +	if (offset >= rbuf->size)
> +		offset -= rbuf->size;
> +
> +	/* Adjust the length to limit this transaction to end of buffer */
> +	actual = (actual < (rbuf->size - offset)) ?
> +		actual : rbuf->size - offset;
> +
> +	*bufpp = (char *)rbuf->vaddr + offset;
> +
> +	return actual;
> +}
> +
>   static int tmc_read_prepare(struct tmc_drvdata *drvdata)
>   {
>   	int ret = 0;
> @@ -223,6 +368,69 @@ static const struct file_operations tmc_fops = {
>   	.release	= tmc_release,
>   };
>   
> +static int tmc_crashdata_open(struct inode *inode, struct file *file)
> +{
> +	int ret;
> +	struct tmc_drvdata *drvdata = container_of(file->private_data,
> +						   struct tmc_drvdata,
> +						   crashdev);
> +
> +	ret = tmc_read_prepare_crashdata(drvdata);
> +	if (ret)
> +		return ret;
> +
> +	nonseekable_open(inode, file);
> +
> +	dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__);
> +	return 0;
> +}
> +
> +static ssize_t tmc_crashdata_read(struct file *file, char __user *data,
> +				  size_t len, loff_t *ppos)
> +{
> +	char *bufp;
> +	ssize_t actual;
> +	struct tmc_drvdata *drvdata = container_of(file->private_data,
> +						   struct tmc_drvdata,
> +						   crashdev);
> +
> +	actual = tmc_get_resvbuf_trace(drvdata, *ppos, len, &bufp);
> +	if (actual <= 0)
> +		return 0;
> +
> +	if (copy_to_user(data, bufp, actual)) {
> +		dev_dbg(&drvdata->csdev->dev,
> +			"%s: copy_to_user failed\n", __func__);
> +		return -EFAULT;
> +	}
> +
> +	*ppos += actual;
> +	dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
> +
> +	return actual;
> +
> +}
> +
> +static int tmc_crashdata_release(struct inode *inode, struct file *file)
> +{
> +	int ret = 0;
> +	struct tmc_drvdata *drvdata = container_of(file->private_data,
> +						   struct tmc_drvdata,
> +						   crashdev);
> +
> +	ret = tmc_read_unprepare_crashdata(drvdata);
> +
> +	dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__);
> +	return ret;
> +}
> +
> +static const struct file_operations tmc_crashdata_fops = {
> +	.owner		= THIS_MODULE,
> +	.open		= tmc_crashdata_open,
> +	.read		= tmc_crashdata_read,
> +	.release	= tmc_crashdata_release,
> +};
> +
>   static enum tmc_mem_intf_width tmc_get_memwidth(u32 devid)
>   {
>   	enum tmc_mem_intf_width memwidth;
> @@ -532,6 +740,20 @@ static u32 tmc_etr_get_max_burst_size(struct device *dev)
>   	return burst_size;
>   }
>   
> +static void register_crash_dev_interface(struct tmc_drvdata *drvdata,
> +					 const char *name)
> +{
> +	drvdata->crashdev.name =
> +		devm_kasprintf(&drvdata->csdev->dev, GFP_KERNEL, "%s_%s", "crash", name);
> +	drvdata->crashdev.minor = MISC_DYNAMIC_MINOR;
> +	drvdata->crashdev.fops = &tmc_crashdata_fops;
> +	if (misc_register(&drvdata->crashdev)) {
> +		dev_dbg(&drvdata->csdev->dev,
> +			"Failed to setup user interface for crashdata\n");
> +		drvdata->crashdev.fops = NULL;
> +	}
> +}
> +
>   static int __tmc_probe(struct device *dev, struct resource *res)
>   {
>   	int ret = 0;
> @@ -632,8 +854,13 @@ static int __tmc_probe(struct device *dev, struct resource *res)
>   	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
>   	drvdata->miscdev.fops = &tmc_fops;
>   	ret = misc_register(&drvdata->miscdev);
> -	if (ret)
> +	if (ret) {
>   		coresight_unregister(drvdata->csdev);
> +		goto out;
> +	}
> +
> +	if (is_tmc_crashdata_valid(drvdata))
> +		register_crash_dev_interface(drvdata, desc.name);
>   out:
>   	return ret;
>   }
> @@ -687,6 +914,8 @@ static void __tmc_remove(struct device *dev)
>   	 * handler to this device is closed.
>   	 */
>   	misc_deregister(&drvdata->miscdev);
> +	if (drvdata->crashdev.fops)
> +		misc_deregister(&drvdata->crashdev);
>   	coresight_unregister(drvdata->csdev);
>   }
>   
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index fb944a68a11c..18752f58dfa6 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -2012,6 +2012,23 @@ static ssize_t buf_mode_preferred_show(struct device *dev,
>   	return sysfs_emit(buf, "%s\n", buf_modes_str[drvdata->etr_mode]);
>   }
>   
> +static int buf_mode_set_resrv(struct tmc_drvdata *drvdata)
> +{
> +	unsigned long flags;
> +	int err = 0;
> +
> +	/* Ensure there are no active crashdata read sessions */
> +	spin_lock_irqsave(&drvdata->spinlock, flags);
> +	if (!drvdata->reading) {
> +		tmc_crashdata_set_invalid(drvdata);
> +		drvdata->etr_mode = ETR_MODE_RESRV;
> +
> +	} else
> +		err = -1;
> +	spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +	return err;
> +}
> +
>   static ssize_t buf_mode_preferred_store(struct device *dev,
>   					  struct device_attribute *attr,
>   					  const char *buf, size_t size)
> @@ -2027,7 +2044,7 @@ static ssize_t buf_mode_preferred_store(struct device *dev,
>   	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_CATU]) && buf_hw.has_catu)
>   		drvdata->etr_mode = ETR_MODE_CATU;
>   	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_RESRV]) && buf_hw.has_resrv)
> -		drvdata->etr_mode = ETR_MODE_RESRV;
> +		return buf_mode_set_resrv(drvdata) ? -EBUSY : size;
>   	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_AUTO]))
>   		drvdata->etr_mode = ETR_MODE_AUTO;
>   	else
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index d76e83fc840b..2ece44e09911 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -195,11 +195,15 @@ struct etr_buf {
>    * @paddr	: Start address of reserved memory region.
>    * @vaddr	: Corresponding CPU virtual address.
>    * @size	: Size of reserved memory region.
> + * @offset	: Offset of the trace data in the buffer for consumption.
> + * @len	: Available trace data @buf (may round up to the beginning).
>    */
>   struct tmc_resrv_buf {
>   	phys_addr_t     paddr;
>   	void		*vaddr;
>   	size_t		size;
> +	unsigned long	offset;
> +	s64		len;
>   };
>   
>   /**
> @@ -208,6 +212,8 @@ struct tmc_resrv_buf {
>    * @base:	memory mapped base address for this component.
>    * @csdev:	component vitals needed by the framework.
>    * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
> + * @crashdev:	specifics to handle "/dev/crash_tmc_xyz" entry for reading
> + *		crash tracedata.
>    * @spinlock:	only one at a time pls.
>    * @pid:	Process ID of the process that owns the session that is using
>    *		this component. For example this would be the pid of the Perf
> @@ -227,7 +233,7 @@ struct tmc_resrv_buf {
>    * @idr_mutex:	Access serialisation for idr.
>    * @sysfs_buf:	SYSFS buffer for ETR.
>    * @perf_buf:	PERF buffer for ETR.
> - * @resrv_buf:	Used by ETR as hardware trace buffer and for trace data
> + * @resrv_buf:  Used by ETR as hardware trace buffer and for trace data
>    *		retention (after crash) only when ETR_MODE_RESRV buffer
>    *		mode is enabled. Used by ETF for trace data retention
>    *		(after crash) by default.
> @@ -239,6 +245,7 @@ struct tmc_drvdata {
>   	void __iomem		*base;
>   	struct coresight_device	*csdev;
>   	struct miscdevice	miscdev;
> +	struct miscdevice	crashdev;
>   	spinlock_t		spinlock;
>   	pid_t			pid;
>   	bool			reading;
> @@ -309,6 +316,8 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata);
>   void tmc_enable_hw(struct tmc_drvdata *drvdata);
>   void tmc_disable_hw(struct tmc_drvdata *drvdata);
>   u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata);
> +int tmc_read_prepare_crashdata(struct tmc_drvdata *drvdata);
> +int tmc_read_unprepare_crashdata(struct tmc_drvdata *drvdata);
>   
>   /* ETB/ETF functions */
>   int tmc_read_prepare_etb(struct tmc_drvdata *drvdata);
> @@ -371,6 +380,8 @@ void tmc_sg_table_sync_data_range(struct tmc_sg_table *table,
>   				  u64 offset, u64 size);
>   ssize_t tmc_sg_table_get_data(struct tmc_sg_table *sg_table,
>   			      u64 offset, size_t len, char **bufpp);
> +
> +bool is_tmc_crashdata_valid(struct tmc_drvdata *drvdata);
>   static inline unsigned long
>   tmc_sg_table_buf_size(struct tmc_sg_table *sg_table)
>   {



From conor at kernel.org  Thu Dec  5 09:05:43 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 5 Dec 2024 17:05:43 +0000
Subject: [PATCH 1/6] dt-bindings: PCI: dwc: rockchip: Add rk3576 support
In-Reply-To: <20241205103623.878181-2-kever.yang@rock-chips.com>
References: <20241205103623.878181-1-kever.yang@rock-chips.com>
 <20241205103623.878181-2-kever.yang@rock-chips.com>
Message-ID: <20241205-backfire-support-68a48f6dcb80@spud>

On Thu, Dec 05, 2024 at 06:36:18PM +0800, Kever Yang wrote:
> rk3576 is using the same controller as rk3568.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>

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/20241205/e6b73fe5/attachment.sig>

From olteanv at gmail.com  Thu Dec  5 09:06:29 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 5 Dec 2024 19:06:29 +0200
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241205145142.29278-4-ansuelsmth@gmail.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
Message-ID: <20241205170629.ww7qcvgbqdf5ipcj@skbuf>

On Thu, Dec 05, 2024 at 03:51:33PM +0100, Christian Marangi wrote:
> +	.port_fdb_add = an8855_port_fdb_add,
> +	.port_fdb_del = an8855_port_fdb_del,
> +	.port_fdb_dump = an8855_port_fdb_dump,
> +	.port_mdb_add = an8855_port_mdb_add,
> +	.port_mdb_del = an8855_port_mdb_del,

Please handle the "struct dsa_db" argument of these functions, so that
you can turn on ds->fdb_isolation. It is likely that instead of a single
AN8855_FID_BRIDGED, there needs to be a unique FID allocated for each
VLAN-unaware bridge in order for their FDBs to be isolated from each
other, and so that the same MAC address could live under both bridges.


From ansuelsmth at gmail.com  Thu Dec  5 09:26:01 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu, 5 Dec 2024 18:26:01 +0100
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241205170629.ww7qcvgbqdf5ipcj@skbuf>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205170629.ww7qcvgbqdf5ipcj@skbuf>
Message-ID: <6751e22d.050a0220.3435c6.57de@mx.google.com>

On Thu, Dec 05, 2024 at 07:06:29PM +0200, Vladimir Oltean wrote:
> On Thu, Dec 05, 2024 at 03:51:33PM +0100, Christian Marangi wrote:
> > +	.port_fdb_add = an8855_port_fdb_add,
> > +	.port_fdb_del = an8855_port_fdb_del,
> > +	.port_fdb_dump = an8855_port_fdb_dump,
> > +	.port_mdb_add = an8855_port_mdb_add,
> > +	.port_mdb_del = an8855_port_mdb_del,
> 
> Please handle the "struct dsa_db" argument of these functions, so that
> you can turn on ds->fdb_isolation. It is likely that instead of a single
> AN8855_FID_BRIDGED, there needs to be a unique FID allocated for each
> VLAN-unaware bridge in order for their FDBs to be isolated from each
> other, and so that the same MAC address could live under both bridges.

Mh ok, I hoped we could first have the base DSA driver merged before
starting to applying these kind of feature.

Concept looks handy, ideally I can just assign one ID for each port
like:
port 1 -> FIB 1
port 2 -> FIB 1
port 3 -> FIB 2

Question:
Ports of the same bridge should have the same FIB?

What I need to check is how the switch handle this for learning. Does
the switch correctly create FDB entry with the right FIB? If that's not
the case then I think assisted_learning is needed and HW Learn can't be
used?

(I still need to check if I can assign a default FIB for a port...
Currently the STP register are 2 bit for each FIB id, so 16 different
FIB are possible)

Also do we have a script for selft tests? I remember there was one back
in the days for fdb isolation?

-- 
	Ansuel


From helgaas at kernel.org  Thu Dec  5 09:27:38 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 5 Dec 2024 11:27:38 -0600
Subject: [PATCH v2 4/5] PCI: stm32: Add PCIe endpoint support for
 STM32MP25
In-Reply-To: <20241126155119.1574564-5-christian.bruel@foss.st.com>
Message-ID: <20241205172738.GA3054352@bhelgaas>

On Tue, Nov 26, 2024 at 04:51:18PM +0100, Christian Bruel wrote:
> Add driver to configure the STM32MP25 SoC PCIe Gen2 controller based on the
> DesignWare PCIe core in endpoint mode.

> +config PCIE_STM32_EP
> +	tristate "STMicroelectronics STM32MP25 PCIe Controller (endpoint mode)"
> +	depends on ARCH_STM32 || COMPILE_TEST
> +	depends on PCI_ENDPOINT
> +	select PCIE_DW_EP
> +	help
> +	  Enables endpoint support for DesignWare core based PCIe controller in found
> +	  in STM32MP25 SoC.

s/in found in/in/ (or "found in" if you prefer)

Wrap so help text fits in 80 columns when for "make menuconfig".

> +static void stm32_pcie_ep_init(struct dw_pcie_ep *ep)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
> +	enum pci_barno bar;
> +
> +	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
> +		dw_pcie_ep_reset_bar(pci, bar);
> +
> +	/* Defer Completion Requests until link started */

I asked about this before [1] but didn't finish the conversation.  My
main point is that I think "Completion Request" is a misnomer.
There's a "Configuration Request" and a "Completion," but no such
thing as a "Completion Request."

Based on your previous response, I think this should say something
like "respond to config requests with Request Retry Status (RRS) until
we're prepared to handle them."

> +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
> +			   STM32MP25_PCIECR_REQ_RETRY_EN,
> +			   STM32MP25_PCIECR_REQ_RETRY_EN);
> +}
> +
> +static int stm32_pcie_enable_link(struct dw_pcie *pci)
> +{
> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
> +	int ret;
> +
> +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
> +			   STM32MP25_PCIECR_LTSSM_EN,
> +			   STM32MP25_PCIECR_LTSSM_EN);
> +
> +	ret = dw_pcie_wait_for_link(pci);
> +	if (ret)
> +		return ret;
> +
> +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
> +			   STM32MP25_PCIECR_REQ_RETRY_EN,
> +			   0);

And I assume this means the endpoint will accept config requests and
handle them normally instead of responding with RRS.

Strictly speaking this is a different condition than "the link is up"
because the link must be up in order to even receive a config request.
The purpose of RRS is for devices that need more initialization time
after the link is up before they can respond to config requests.

The fact that the hardware provides this bit makes me think the
designer anticipated that the link might come up before the rest of
the device is fully initialized.

Bjorn

[1] https://lore.kernel.org/r/20241112203846.GA1856246 at bhelgaas



From conor at kernel.org  Thu Dec  5 09:32:55 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 5 Dec 2024 17:32:55 +0000
Subject: [PATCH] dt-bindings: dma: atmel: Convert to json schema
In-Reply-To: <20241205-xdma-v1-1-76a4a44670b5@microchip.com>
References: <20241205-xdma-v1-1-76a4a44670b5@microchip.com>
Message-ID: <20241205-silt-legwork-8cfe9a41bb2e@spud>

On Thu, Dec 05, 2024 at 03:26:18PM +0530, Charan Pedumuru wrote:
> Convert old text based binding to json schema.
> Changes during conversion:
> - Add the required properties `clock` and `clock-names`, which were
>   missing in the original binding.
> - Add a fallback for `microchip,sam9x7-dma` and `microchip,sam9x60-dma`
>   as they are compatible with the dma IP core on `atmel,sama5d4-dma`.
> - Update examples and include appropriate file directives to resolve
>   errors identified by `dt_binding_check` and `dtbs_check`.
> 
> Signed-off-by: Charan Pedumuru <charan.pedumuru at microchip.com>

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/20241205/b5183985/attachment.sig>

From tudor.ambarus at linaro.org  Thu Dec  5 09:41:37 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 17:41:37 +0000
Subject: [PATCH v3 3/3] MAINTAINERS: add entry for samsung exynos mailbox driver
In-Reply-To: <20241205174137.190545-1-tudor.ambarus@linaro.org>
References: <20241205174137.190545-1-tudor.ambarus@linaro.org>
Message-ID: <20241205174137.190545-4-tudor.ambarus@linaro.org>

Add entry for the samsung exynos mailbox driver.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..41a29d1d6e4d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3023,6 +3023,7 @@ F:	drivers/*/*s3c24*
 F:	drivers/*/*s3c64xx*
 F:	drivers/*/*s5pv210*
 F:	drivers/clocksource/samsung_pwm_timer.c
+F:	drivers/mailbox/exynos-mailbox.c
 F:	drivers/memory/samsung/
 F:	drivers/pwm/pwm-samsung.c
 F:	drivers/soc/samsung/
@@ -20712,6 +20713,14 @@ F:	arch/arm64/boot/dts/exynos/exynos850*
 F:	drivers/clk/samsung/clk-exynos850.c
 F:	include/dt-bindings/clock/exynos850.h
 
+SAMSUNG EXYNOS MAILBOX DRIVER
+M:	Tudor Ambarus <tudor.ambarus at linaro.org>
+L:	linux-kernel at vger.kernel.org
+L:	linux-samsung-soc at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/mailbox/samsung,exynos.yaml
+F:	drivers/mailbox/exynos-mailbox.c
+
 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 M:	Krzysztof Kozlowski <krzk at kernel.org>
 L:	linux-crypto at vger.kernel.org
-- 
2.47.0.338.g60cca15819-goog



From ansuelsmth at gmail.com  Thu Dec  5 09:44:12 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu, 5 Dec 2024 18:44:12 +0100
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <Z1HQ0zYV4aPpW48X@shell.armlinux.org.uk>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <Z1HQ0zYV4aPpW48X@shell.armlinux.org.uk>
Message-ID: <6751e671.050a0220.3b1956.9c7d@mx.google.com>

On Thu, Dec 05, 2024 at 04:12:03PM +0000, Russell King (Oracle) wrote:
> hi Christian,
> 
> On Thu, Dec 05, 2024 at 03:51:33PM +0100, Christian Marangi wrote:
> > diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
> > index 2d10b4d6cfbb..6b6d0b7bae72 100644
> > --- a/drivers/net/dsa/Kconfig
> > +++ b/drivers/net/dsa/Kconfig
> > @@ -24,6 +24,15 @@ config NET_DSA_LOOP
> >  	  This enables support for a fake mock-up switch chip which
> >  	  exercises the DSA APIs.
> >  
> > +
> 
> Niggle - no need for the extra blank line.
>

Will drop!

> > +static int an8855_set_mac_eee(struct dsa_switch *ds, int port,
> > +			      struct ethtool_keee *eee)
> > +{
> > +	struct an8855_priv *priv = ds->priv;
> > +	u32 reg;
> > +	int ret;
> > +
> > +	if (eee->eee_enabled) {
> > +		ret = regmap_read(priv->regmap, AN8855_PMCR_P(port), &reg);
> > +		if (ret)
> > +			return ret;
> > +		/* Force enable EEE if force mode and LINK */
> > +		if (reg & AN8855_PMCR_FORCE_MODE &&
> > +		    reg & AN8855_PMCR_FORCE_LNK) {
> > +			switch (reg & AN8855_PMCR_FORCE_SPEED) {
> > +			case AN8855_PMCR_FORCE_SPEED_1000:
> > +				reg |= AN8855_PMCR_FORCE_EEE1G;
> > +				break;
> > +			case AN8855_PMCR_FORCE_SPEED_100:
> > +				reg |= AN8855_PMCR_FORCE_EEE100;
> > +				break;
> > +			default:
> > +				break;
> > +			}
> 
> Does this forcing force EEE to be enabled for the port, irrespective
> of the negotiation?
> 

This apply only if autoneg is off. In that case EEE is forced. I think
you already had this comment at times for this exact question. If
autoneg is on, EEE is not forced if EEE is turned on.

> > +			ret = regmap_write(priv->regmap, AN8855_PMCR_P(port), reg);
> > +			if (ret)
> > +				return ret;
> > +		}
> > +		ret = regmap_update_bits(priv->regmap, AN8855_PMEEECR_P(port),
> > +					 AN8855_LPI_MODE_EN,
> > +					 eee->tx_lpi_enabled ? AN8855_LPI_MODE_EN : 0);
> > +		if (ret)
> > +			return ret;
> > +	} else {
> > +		ret = regmap_clear_bits(priv->regmap, AN8855_PMCR_P(port),
> > +					AN8855_PMCR_FORCE_EEE1G |
> > +					AN8855_PMCR_FORCE_EEE100);
> > +		if (ret)
> > +			return ret;
> > +
> > +		ret = regmap_clear_bits(priv->regmap, AN8855_PMEEECR_P(port),
> > +					AN8855_LPI_MODE_EN);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int an8855_get_mac_eee(struct dsa_switch *ds, int port,
> > +			      struct ethtool_keee *eee)
> > +{
> > +	struct an8855_priv *priv = ds->priv;
> > +	u32 reg;
> > +	int ret;
> > +
> > +	ret = regmap_read(priv->regmap, AN8855_PMEEECR_P(port), &reg);
> > +	if (ret)
> > +		return ret;
> > +	eee->tx_lpi_enabled = reg & AN8855_LPI_MODE_EN;
> > +
> > +	ret = regmap_read(priv->regmap, AN8855_CKGCR, &reg);
> > +	if (ret)
> > +		return ret;
> > +	/* Global LPI TXIDLE Threshold, default 60ms (unit 2us) */
> > +	eee->tx_lpi_timer = FIELD_GET(AN8855_LPI_TXIDLE_THD_MASK, reg) / 500;
> 
> There is no point setting tx_lpi_enabled and tx_lpi_timer, as phylib
> will immediately overwrite then in its phy_ethtool_get_eee() method.
> In fact, there's no point to the DSA get_mac_eee() method.
> 
> > +
> > +	ret = regmap_read(priv->regmap, AN8855_PMSR_P(port), &reg);
> > +	if (ret)
> > +		return ret;
> 
> What's the purpose of this read?
> 
> > +
> > +	return 0;
> > +}
> 
> Overall, I would suggest not implementing EEE just yet - I sent out a
> 22 patch RFC patch set last week which implements EEE support in
> phylink, and I have another bunch of patches that clean up DSA that
> I didn't send, which includes getting rid of the DSA get_mac_eee()
> method.
> 
> Now that the bulk of the phylink in-band changes have been merged, my
> plan is to work through getting the RFC patch set merged - I've sent
> out the first four patches today for final review and merging.
> 
> I stated some questions in the RFC cover message that everyone ignored,
> maybe you could look at that and give your views on the points I raised
> there?
> 

Ok to drop these OPs and reimplement later once we have a better
implementation? (really wants the base driver merged so I don't have to
send big patch every time, hope you understand the problem)

> > +static struct phylink_pcs *
> > +an8855_phylink_mac_select_pcs(struct phylink_config *config,
> > +			      phy_interface_t interface)
> > +{
> > +	struct dsa_port *dp = dsa_phylink_to_port(config);
> > +	struct an8855_priv *priv = dp->ds->priv;
> > +
> > +	switch (interface) {
> > +	case PHY_INTERFACE_MODE_SGMII:
> > +	case PHY_INTERFACE_MODE_2500BASEX:
> > +		return &priv->pcs;
> > +	default:
> > +		return NULL;
> > +	}
> 
> Great, exactly what I like to see in mac_select_pcs()!
> 
> > +}
> > +
> > +static void
> > +an8855_phylink_mac_config(struct phylink_config *config, unsigned int mode,
> > +			  const struct phylink_link_state *state)
> > +{
> > +	struct dsa_port *dp = dsa_phylink_to_port(config);
> > +	struct dsa_switch *ds = dp->ds;
> > +	struct an8855_priv *priv;
> > +	int port = dp->index;
> > +
> > +	priv = ds->priv;
> > +
> > +	/* Nothing to configure for internal ports */
> > +	if (port != 5)
> > +		return;
> > +
> > +	regmap_update_bits(priv->regmap, AN8855_PMCR_P(port),
> > +			   AN8855_PMCR_IFG_XMIT | AN8855_PMCR_MAC_MODE |
> > +			   AN8855_PMCR_BACKOFF_EN | AN8855_PMCR_BACKPR_EN,
> > +			   FIELD_PREP(AN8855_PMCR_IFG_XMIT, 0x1) |
> > +			   AN8855_PMCR_MAC_MODE | AN8855_PMCR_BACKOFF_EN |
> > +			   AN8855_PMCR_BACKPR_EN);
> > +}
> 
> This looks much better, thanks.
> 
> > +
> > +static void an8855_phylink_get_caps(struct dsa_switch *ds, int port,
> > +				    struct phylink_config *config)
> > +{
> > +	switch (port) {
> > +	case 0:
> > +	case 1:
> > +	case 2:
> > +	case 3:
> > +	case 4:
> > +		__set_bit(PHY_INTERFACE_MODE_GMII,
> > +			  config->supported_interfaces);
> > +		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
> > +			  config->supported_interfaces);
> > +		break;
> > +	case 5:
> > +		phy_interface_set_rgmii(config->supported_interfaces);
> > +		__set_bit(PHY_INTERFACE_MODE_SGMII,
> > +			  config->supported_interfaces);
> > +		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
> > +			  config->supported_interfaces);
> > +		break;
> > +	}
> > +
> > +	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
> > +				   MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
> > +}
> > +
> > +static void
> > +an8855_phylink_mac_link_down(struct phylink_config *config, unsigned int mode,
> > +			     phy_interface_t interface)
> > +{
> > +	struct dsa_port *dp = dsa_phylink_to_port(config);
> > +	struct an8855_priv *priv = dp->ds->priv;
> > +
> > +	/* With autoneg just disable TX/RX else also force link down */
> > +	if (phylink_autoneg_inband(mode)) {
> > +		regmap_clear_bits(priv->regmap, AN8855_PMCR_P(dp->index),
> > +				  AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
> > +	} else {
> > +		regmap_update_bits(priv->regmap, AN8855_PMCR_P(dp->index),
> > +				   AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN |
> > +				   AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK,
> > +				   AN8855_PMCR_FORCE_MODE);
> > +	}
> > +}
> > +
> > +static void
> > +an8855_phylink_mac_link_up(struct phylink_config *config,
> > +			   struct phy_device *phydev, unsigned int mode,
> > +			   phy_interface_t interface, int speed, int duplex,
> > +			   bool tx_pause, bool rx_pause)
> > +{
> > +	struct dsa_port *dp = dsa_phylink_to_port(config);
> > +	struct an8855_priv *priv = dp->ds->priv;
> > +	int port = dp->index;
> > +	u32 reg;
> > +
> > +	reg = regmap_read(priv->regmap, AN8855_PMCR_P(port), &reg);
> > +	if (phylink_autoneg_inband(mode)) {
> > +		reg &= ~AN8855_PMCR_FORCE_MODE;
> > +	} else {
> > +		reg |= AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK;
> > +
> > +		reg &= ~AN8855_PMCR_FORCE_SPEED;
> > +		switch (speed) {
> > +		case SPEED_10:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_10;
> > +			break;
> > +		case SPEED_100:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_100;
> > +			break;
> > +		case SPEED_1000:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_1000;
> > +			break;
> > +		case SPEED_2500:
> > +			reg |= AN8855_PMCR_FORCE_SPEED_2500;
> > +			break;
> > +		case SPEED_5000:
> > +			dev_err(priv->dev, "Missing support for 5G speed. Aborting...\n");
> > +			return;
> > +		}
> > +
> > +		reg &= ~AN8855_PMCR_FORCE_FDX;
> > +		if (duplex == DUPLEX_FULL)
> > +			reg |= AN8855_PMCR_FORCE_FDX;
> > +
> > +		reg &= ~AN8855_PMCR_RX_FC_EN;
> > +		if (rx_pause || dsa_port_is_cpu(dp))
> > +			reg |= AN8855_PMCR_RX_FC_EN;
> > +
> > +		reg &= ~AN8855_PMCR_TX_FC_EN;
> > +		if (rx_pause || dsa_port_is_cpu(dp))
> > +			reg |= AN8855_PMCR_TX_FC_EN;
> > +
> > +		/* Disable any EEE options */
> > +		reg &= ~(AN8855_PMCR_FORCE_EEE5G | AN8855_PMCR_FORCE_EEE2P5G |
> > +			 AN8855_PMCR_FORCE_EEE1G | AN8855_PMCR_FORCE_EEE100);
> > +	}
> > +
> > +	reg |= AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN;
> > +
> > +	regmap_write(priv->regmap, AN8855_PMCR_P(port), reg);
> > +}
> 
> All the above looks fine to me.
> 
> > +
> > +static void an8855_pcs_get_state(struct phylink_pcs *pcs,
> > +				 struct phylink_link_state *state)
> > +{
> > +	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
> > +	u32 val;
> > +	int ret;
> > +
> > +	ret = regmap_read(priv->regmap, AN8855_PMSR_P(AN8855_CPU_PORT), &val);
> > +	if (ret < 0) {
> > +		state->link = false;
> > +		return;
> > +	}
> > +
> > +	state->link = !!(val & AN8855_PMSR_LNK);
> > +	state->an_complete = state->link;
> > +	state->duplex = (val & AN8855_PMSR_DPX) ? DUPLEX_FULL :
> > +						  DUPLEX_HALF;
> > +
> > +	switch (val & AN8855_PMSR_SPEED) {
> > +	case AN8855_PMSR_SPEED_10:
> > +		state->speed = SPEED_10;
> > +		break;
> > +	case AN8855_PMSR_SPEED_100:
> > +		state->speed = SPEED_100;
> > +		break;
> > +	case AN8855_PMSR_SPEED_1000:
> > +		state->speed = SPEED_1000;
> > +		break;
> > +	case AN8855_PMSR_SPEED_2500:
> > +		state->speed = SPEED_2500;
> > +		break;
> > +	case AN8855_PMSR_SPEED_5000:
> > +		dev_err(priv->dev, "Missing support for 5G speed. Setting Unknown.\n");
> > +		fallthrough;
> > +	default:
> > +		state->speed = SPEED_UNKNOWN;
> > +		break;
> > +	}
> > +
> > +	if (val & AN8855_PMSR_RX_FC)
> > +		state->pause |= MLO_PAUSE_RX;
> > +	if (val & AN8855_PMSR_TX_FC)
> > +		state->pause |= MLO_PAUSE_TX;
> > +}
> > +
> > +static int an8855_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
> > +			     phy_interface_t interface,
> > +			     const unsigned long *advertising,
> > +			     bool permit_pause_to_mac)
> > +{
> > +	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
> > +	u32 val;
> > +	int ret;
> > +
> > +	switch (interface) {
> > +	case PHY_INTERFACE_MODE_SGMII:
> > +		break;
> > +	case PHY_INTERFACE_MODE_2500BASEX:
> > +		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> > +			dev_err(priv->dev, "in-band negotiation unsupported");
> > +			return -EINVAL;
> > +		}
> > +		break;
> 
> Now that we have the phylink in-band changes merged, along with a new
> PCS .pcs_inband_caps() method, please implement this method to indicate
> that in-band is not supported in 2500BASE-X mode. Phylink will issue a
> warning if it attempts to go against that (particularly when e.g. the
> PHY demands in-band but the PCS doesn't support it - a case that likely
> will never work in practice.)
> 

Thanks for the hint of the new OPs, yes will reimplement this.

> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	/*                   !!! WELCOME TO HELL !!!                   */
> > +
> > +	/* TX FIR - improve TX EYE */
> > +	ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_10,
> > +				 AN8855_RG_DA_QP_TX_FIR_C2_SEL |
> > +				 AN8855_RG_DA_QP_TX_FIR_C2_FORCE |
> > +				 AN8855_RG_DA_QP_TX_FIR_C1_SEL |
> > +				 AN8855_RG_DA_QP_TX_FIR_C1_FORCE,
> > +				 AN8855_RG_DA_QP_TX_FIR_C2_SEL |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C2_FORCE, 0x4) |
> > +				 AN8855_RG_DA_QP_TX_FIR_C1_SEL |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C1_FORCE, 0x0));
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +		val = 0x0;
> > +	else
> > +		val = 0xd;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_11,
> > +				 AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
> > +				 AN8855_RG_DA_QP_TX_FIR_C0B_FORCE,
> > +				 AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C0B_FORCE, val));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* RX CDR - improve RX Jitter Tolerance */
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +		val = 0x5;
> > +	else
> > +		val = 0x6;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_BOT_LIM,
> > +				 AN8855_RG_QP_CDR_LPF_KP_GAIN |
> > +				 AN8855_RG_QP_CDR_LPF_KI_GAIN,
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_KP_GAIN, val) |
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_KI_GAIN, val));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PLL */
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +		val = 0x1;
> > +	else
> > +		val = 0x0;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_1,
> > +				 AN8855_RG_TPHY_SPEED,
> > +				 FIELD_PREP(AN8855_RG_TPHY_SPEED, val));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PLL - LPF */
> > +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> > +				 AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
> > +				 AN8855_RG_DA_QP_PLL_FBKSEL_INTF |
> > +				 AN8855_RG_DA_QP_PLL_BR_INTF |
> > +				 AN8855_RG_DA_QP_PLL_BPD_INTF |
> > +				 AN8855_RG_DA_QP_PLL_BPA_INTF |
> > +				 AN8855_RG_DA_QP_PLL_BC_INTF,
> > +				 AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_FBKSEL_INTF, 0x0) |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BR_INTF, 0x3) |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BPD_INTF, 0x0) |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BPA_INTF, 0x5) |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BC_INTF, 0x1));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PLL - ICO */
> > +	ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_4,
> > +			      AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF);
> > +	if (ret)
> > +		return ret;
> > +	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
> > +				AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PLL - CHP */
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +		val = 0x6;
> > +	else
> > +		val = 0x4;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> > +				 AN8855_RG_DA_QP_PLL_IR_INTF,
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_IR_INTF, val));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PLL - PFD */
> > +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> > +				 AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF |
> > +				 AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF |
> > +				 AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF,
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF, 0x1) |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF, 0x1));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PLL - POSTDIV */
> > +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> > +				 AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF |
> > +				 AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF |
> > +				 AN8855_RG_DA_QP_PLL_PCK_SEL_INTF,
> > +				 AN8855_RG_DA_QP_PLL_PCK_SEL_INTF);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PLL - SDM */
> > +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
> > +				 AN8855_RG_DA_QP_PLL_SDM_HREN_INTF,
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SDM_HREN_INTF, 0x0));
> > +	if (ret)
> > +		return ret;
> > +	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
> > +				AN8855_RG_DA_QP_PLL_SDM_IFM_INTF);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_SS_LCPLL_PWCTL_SETTING_2,
> > +				 AN8855_RG_NCPO_ANA_MSB,
> > +				 FIELD_PREP(AN8855_RG_NCPO_ANA_MSB, 0x1));
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +		val = 0x7a000000;
> > +	else
> > +		val = 0x48000000;
> > +	ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_2,
> > +			   FIELD_PREP(AN8855_RG_LCPLL_NCPO_VALUE, val));
> > +	if (ret)
> > +		return ret;
> > +	ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_PCW_1,
> > +			   FIELD_PREP(AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON, val));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_clear_bits(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_5,
> > +				AN8855_RG_LCPLL_NCPO_CHG);
> > +	if (ret)
> > +		return ret;
> > +	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
> > +				AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PLL - SS */
> > +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
> > +				 AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF,
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF, 0x0));
> > +	if (ret)
> > +		return ret;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_4,
> > +				 AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF,
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF, 0x0));
> > +	if (ret)
> > +		return ret;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
> > +				 AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF,
> > +				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF, 0x0));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PLL - TDC */
> > +	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
> > +				AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
> > +			      AN8855_RG_QP_PLL_SSC_TRI_EN);
> > +	if (ret)
> > +		return ret;
> > +	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
> > +			      AN8855_RG_QP_PLL_SSC_PHASE_INI);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_RX_DAC_EN,
> > +				 AN8855_RG_QP_SIGDET_HF,
> > +				 FIELD_PREP(AN8855_RG_QP_SIGDET_HF, 0x2));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* TCL Disable (only for Co-SIM) */
> > +	ret = regmap_clear_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_0,
> > +				AN8855_RG_QP_EQ_RX500M_CK_SEL);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* TX Init */
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +		val = 0x4;
> > +	else
> > +		val = 0x0;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_TX_MODE,
> > +				 AN8855_RG_QP_TX_RESERVE |
> > +				 AN8855_RG_QP_TX_MODE_16B_EN,
> > +				 FIELD_PREP(AN8855_RG_QP_TX_RESERVE, val));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* RX Control/Init */
> > +	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_RXAFE_RESERVE,
> > +			      AN8855_RG_QP_CDR_PD_10B_EN);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +		val = 0x1;
> > +	else
> > +		val = 0x2;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_MJV_LIM,
> > +				 AN8855_RG_QP_CDR_LPF_RATIO,
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_RATIO, val));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_SETVALUE,
> > +				 AN8855_RG_QP_CDR_PR_BUF_IN_SR |
> > +				 AN8855_RG_QP_CDR_PR_BETA_SEL,
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_BUF_IN_SR, 0x6) |
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_BETA_SEL, 0x1));
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +		val = 0xf;
> > +	else
> > +		val = 0xc;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
> > +				 AN8855_RG_QP_CDR_PR_DAC_BAND,
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_DAC_BAND, val));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
> > +				 AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE |
> > +				 AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK,
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK, 0x19));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF,
> > +				 AN8855_RG_QP_CDR_PHYCK_SEL |
> > +				 AN8855_RG_QP_CDR_PHYCK_RSTB |
> > +				 AN8855_RG_QP_CDR_PHYCK_DIV,
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_SEL, 0x2) |
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_DIV, 0x21));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_clear_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
> > +				AN8855_RG_QP_CDR_PR_XFICK_EN);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
> > +				 AN8855_RG_QP_CDR_PR_KBAND_DIV,
> > +				 FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV, 0x4));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_26,
> > +				 AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
> > +				 AN8855_RG_LINK_NE_EN |
> > +				 AN8855_RG_LINK_ERRO_EN,
> > +				 AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
> > +				 AN8855_RG_LINK_ERRO_EN);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RX_DLY_0,
> > +				 AN8855_RG_QP_RX_SAOSC_EN_H_DLY |
> > +				 AN8855_RG_QP_RX_PI_CAL_EN_H_DLY,
> > +				 FIELD_PREP(AN8855_RG_QP_RX_SAOSC_EN_H_DLY, 0x3f) |
> > +				 FIELD_PREP(AN8855_RG_QP_RX_PI_CAL_EN_H_DLY, 0x6f));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_42,
> > +				 AN8855_RG_QP_EQ_EN_DLY,
> > +				 FIELD_PREP(AN8855_RG_QP_EQ_EN_DLY, 0x150));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_2,
> > +				 AN8855_RG_QP_RX_EQ_EN_H_DLY,
> > +				 FIELD_PREP(AN8855_RG_QP_RX_EQ_EN_H_DLY, 0x150));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_9,
> > +				 AN8855_RG_QP_EQ_LEQOSC_DLYCNT,
> > +				 FIELD_PREP(AN8855_RG_QP_EQ_LEQOSC_DLYCNT, 0x1));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_8,
> > +				 AN8855_RG_DA_QP_SAOSC_DONE_TIME |
> > +				 AN8855_RG_DA_QP_LEQOS_EN_TIME,
> > +				 FIELD_PREP(AN8855_RG_DA_QP_SAOSC_DONE_TIME, 0x200) |
> > +				 FIELD_PREP(AN8855_RG_DA_QP_LEQOS_EN_TIME, 0xfff));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Frequency meter */
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +		val = 0x10;
> > +	else
> > +		val = 0x28;
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_5,
> > +				 AN8855_RG_FREDET_CHK_CYCLE,
> > +				 FIELD_PREP(AN8855_RG_FREDET_CHK_CYCLE, val));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_6,
> > +				 AN8855_RG_FREDET_GOLDEN_CYCLE,
> > +				 FIELD_PREP(AN8855_RG_FREDET_GOLDEN_CYCLE, 0x64));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_7,
> > +				 AN8855_RG_FREDET_TOLERATE_CYCLE,
> > +				 FIELD_PREP(AN8855_RG_FREDET_TOLERATE_CYCLE, 0x2710));
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_0,
> > +			      AN8855_RG_PHYA_AUTO_INIT);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* PCS Init */
> > +	if (interface == PHY_INTERFACE_MODE_SGMII &&
> > +	    neg_mode == PHYLINK_PCS_NEG_INBAND_DISABLED) {
> > +		ret = regmap_clear_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_0,
> > +					AN8855_RG_SGMII_MODE | AN8855_RG_SGMII_AN_EN);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	ret = regmap_clear_bits(priv->regmap, AN8855_RG_HSGMII_PCS_CTROL_1,
> > +				AN8855_RG_TBI_10B_MODE);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> > +		/* Set AN Ability - Interrupt */
> > +		ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN_FORCE_CL37,
> > +				      AN8855_RG_FORCE_AN_DONE);
> > +		if (ret)
> > +			return ret;
> > +
> > +		ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN_13,
> > +					 AN8855_SGMII_REMOTE_FAULT_DIS |
> > +					 AN8855_SGMII_IF_MODE,
> > +					 AN8855_SGMII_REMOTE_FAULT_DIS |
> > +					 FIELD_PREP(AN8855_SGMII_IF_MODE, 0xb));
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	/* Rate Adaption - GMII path config. */
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX) {
> > +		ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
> > +					AN8855_RG_P0_DIS_MII_MODE);
> > +		if (ret)
> > +			return ret;
> > +	} else {
> > +		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> > +			ret = regmap_set_bits(priv->regmap, AN8855_MII_RA_AN_ENABLE,
> > +					      AN8855_RG_P0_RA_AN_EN);
> > +			if (ret)
> > +				return ret;
> > +		} else {
> > +			ret = regmap_update_bits(priv->regmap, AN8855_RG_AN_SGMII_MODE_FORCE,
> > +						 AN8855_RG_FORCE_CUR_SGMII_MODE |
> > +						 AN8855_RG_FORCE_CUR_SGMII_SEL,
> > +						 AN8855_RG_FORCE_CUR_SGMII_SEL);
> > +			if (ret)
> > +				return ret;
> > +
> > +			ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
> > +						AN8855_RG_P0_MII_RA_RX_EN |
> > +						AN8855_RG_P0_MII_RA_TX_EN |
> > +						AN8855_RG_P0_MII_RA_RX_MODE |
> > +						AN8855_RG_P0_MII_RA_TX_MODE);
> > +			if (ret)
> > +				return ret;
> > +		}
> > +
> > +		ret = regmap_set_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
> > +				      AN8855_RG_P0_MII_MODE);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	ret = regmap_set_bits(priv->regmap, AN8855_RG_RATE_ADAPT_CTRL_0,
> > +			      AN8855_RG_RATE_ADAPT_RX_BYPASS |
> > +			      AN8855_RG_RATE_ADAPT_TX_BYPASS |
> > +			      AN8855_RG_RATE_ADAPT_RX_EN |
> > +			      AN8855_RG_RATE_ADAPT_TX_EN);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Disable AN if not in autoneg */
> > +	ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN0, BMCR_ANENABLE,
> > +				 neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE :
> > +									      0);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (interface == PHY_INTERFACE_MODE_SGMII &&
> > +	    neg_mode == PHYLINK_PCS_NEG_INBAND_DISABLED) {
> > +		ret = regmap_set_bits(priv->regmap, AN8855_PHY_RX_FORCE_CTRL_0,
> > +				      AN8855_RG_FORCE_TXC_SEL);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	/* Force Speed with fixed-link or 2500base-x as doesn't support aneg */
> > +	if (interface == PHY_INTERFACE_MODE_2500BASEX ||
> > +	    neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
> > +		if (interface == PHY_INTERFACE_MODE_2500BASEX)
> > +			val = AN8855_RG_LINK_MODE_P0_SPEED_2500;
> > +		else
> > +			val = AN8855_RG_LINK_MODE_P0_SPEED_1000;
> > +		ret = regmap_update_bits(priv->regmap, AN8855_SGMII_STS_CTRL_0,
> > +					 AN8855_RG_LINK_MODE_P0 |
> > +					 AN8855_RG_FORCE_SPD_MODE_P0,
> > +					 val | AN8855_RG_FORCE_SPD_MODE_P0);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	/* bypass flow control to MAC */
> > +	ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_0,
> > +			   AN8855_RG_DPX_STS_P3 | AN8855_RG_DPX_STS_P2 |
> > +			   AN8855_RG_DPX_STS_P1 | AN8855_RG_TXFC_STS_P0 |
> > +			   AN8855_RG_RXFC_STS_P0 | AN8855_RG_DPX_STS_P0);
> > +	if (ret)
> > +		return ret;
> > +	ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_2,
> > +			   AN8855_RG_RXFC_AN_BYPASS_P3 |
> > +			   AN8855_RG_RXFC_AN_BYPASS_P2 |
> > +			   AN8855_RG_RXFC_AN_BYPASS_P1 |
> > +			   AN8855_RG_TXFC_AN_BYPASS_P3 |
> > +			   AN8855_RG_TXFC_AN_BYPASS_P2 |
> > +			   AN8855_RG_TXFC_AN_BYPASS_P1 |
> > +			   AN8855_RG_DPX_AN_BYPASS_P3 |
> > +			   AN8855_RG_DPX_AN_BYPASS_P2 |
> > +			   AN8855_RG_DPX_AN_BYPASS_P1 |
> > +			   AN8855_RG_DPX_AN_BYPASS_P0);
> > +	if (ret)
> > +		return ret;
> 
> Is the above disruptive to the link if it is executed when the link is
> already up? Do you need to re-execute it even when "interface" hasn't
> changed?
> 
> This gets called to possibly change the PCS advertisement in response
> to ethtool -s, so ought not have any link disrupting effects if
> nothing has changed.
> 

No these change only after a switch reset, so they don't need to be
re-executed and doesn't interrupt the link.

> > +
> > +	return 0;
> > +}
> > +
> > +static void an8855_pcs_an_restart(struct phylink_pcs *pcs)
> > +{
> > +	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
> > +
> > +	regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN0, BMCR_ANRESTART);
> 
> This won't get called for SGMII - Cisco SGMII is merely the PHY telling
> the PCS/MAC what was negotiated at the media and how it's going to be
> operating the SGMII link. AN restart is a media side thing, so that
> would happen at the PHY in that case. I suggest this becomes an empty
> no-op function.
> 

Soo this function won't ever be called in the current implementation?

I would like to keep the same PCS config of the original driver (just to
be sure). This is called for SGMII configuration in autoneg right after
BMCR_ANENABLE, ok for you to move this call in pcs_config or do you
think I should drop it entirely?

-- 
	Ansuel


From tudor.ambarus at linaro.org  Thu Dec  5 09:41:34 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 17:41:34 +0000
Subject: [PATCH v3 0/3] mailbox: add samsung exynos driver
Message-ID: <20241205174137.190545-1-tudor.ambarus@linaro.org>

Hi,

The samsung exynos mailbox controller has 16 flag bits for hardware
interrupt generation and a shared register for passing mailbox messages.
When the controller is used by the ACPM protocol the shared register is
ignored and the mailbox controller acts as a doorbell. The controller
just raises the interrupt to APM after the ACPM protocol has written
the message to SRAM.

I mark this as v3 because it is a continuation of:
https://lore.kernel.org/linux-arm-kernel/20241017163649.3007062-1-tudor.ambarus at linaro.org/

Changes in v3:
- decouple the mailbox controller driver from the ACPM protocol driver
- address Krzysztof's eview comments 

Thanks,
ta

Tudor Ambarus (3):
  dt-bindings: mailbox: add bindings for samsung,exynos
  mailbox: add samsung exynos driver
  MAINTAINERS: add entry for samsung exynos mailbox driver

 .../bindings/mailbox/samsung,exynos.yaml      |  70 +++++++++
 MAINTAINERS                                   |   9 ++
 drivers/mailbox/Kconfig                       |  11 ++
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/exynos-mailbox.c              | 143 ++++++++++++++++++
 5 files changed, 235 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/samsung,exynos.yaml
 create mode 100644 drivers/mailbox/exynos-mailbox.c

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec  5 09:41:35 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 17:41:35 +0000
Subject: [PATCH v3 1/3] dt-bindings: mailbox: add bindings for samsung,exynos
In-Reply-To: <20241205174137.190545-1-tudor.ambarus@linaro.org>
References: <20241205174137.190545-1-tudor.ambarus@linaro.org>
Message-ID: <20241205174137.190545-2-tudor.ambarus@linaro.org>

Add bindings for the Samsung Exynos Mailbox Controller.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 .../bindings/mailbox/samsung,exynos.yaml      | 70 +++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/samsung,exynos.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/samsung,exynos.yaml b/Documentation/devicetree/bindings/mailbox/samsung,exynos.yaml
new file mode 100644
index 000000000000..1fddec1fc64c
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/samsung,exynos.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright 2024 Linaro Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/samsung,exynos.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos Mailbox Controller
+
+maintainers:
+  - Tudor Ambarus <tudor.ambarus at linaro.org>
+
+description: |
+  The samsung exynos mailbox controller has 16 flag bits for hardware interrupt
+  generation and a shared register for passing mailbox messages. When the
+  controller is used by the ACPM protocol the shared register is ignored and
+  the mailbox controller acts as a doorbell. The controller just raises the
+  interrupt to the firmware after the ACPM protocol has written the message to
+  SRAM.
+
+properties:
+  compatible:
+    const: google,gs101-acpm-mbox
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: pclk
+
+  interrupts:
+    description: IRQ line for the RX mailbox.
+    maxItems: 1
+
+  '#mbox-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - '#mbox-cells'
+
+additionalProperties: false
+
+examples:
+  # Doorbell mode.
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/google,gs101.h>
+
+    soc {
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        ap2apm_mailbox: mailbox at 17610000 {
+            compatible = "google,gs101-acpm-mbox";
+            reg = <0x17610000 0x1000>;
+            clocks = <&cmu_apm CLK_GOUT_APM_MAILBOX_APM_AP_PCLK>;
+            clock-names = "pclk";
+            interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 0>;
+            #mbox-cells = <1>;
+        };
+    };
-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec  5 09:41:36 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 17:41:36 +0000
Subject: [PATCH v3 2/3] mailbox: add samsung exynos driver
In-Reply-To: <20241205174137.190545-1-tudor.ambarus@linaro.org>
References: <20241205174137.190545-1-tudor.ambarus@linaro.org>
Message-ID: <20241205174137.190545-3-tudor.ambarus@linaro.org>

The samsung exynos mailbox controller has 16 flag bits for hardware
interrupt generation and a shared register for passing mailbox messages.
When the controller is used by the ACPM protocol the shared register is
ignored and the mailbox controller acts as a doorbell. The controller
just raises the interrupt to APM after the ACPM protocol has written
the message to SRAM.

Add support for the samsung exynos mailbox controller.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/mailbox/Kconfig          |  11 +++
 drivers/mailbox/Makefile         |   2 +
 drivers/mailbox/exynos-mailbox.c | 143 +++++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 drivers/mailbox/exynos-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 8ecba7fb999e..44b808c4d97f 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -36,6 +36,17 @@ config ARM_MHU_V3
 	  that provides different means of transports: supported extensions
 	  will be discovered and possibly managed at probe-time.
 
+config EXYNOS_MBOX
+	tristate "Exynos Mailbox"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	help
+	  Say Y here if you want to build the Samsung Exynos Mailbox controller
+	  driver. The controller has 16 flag bits for hardware interrupt
+	  generation and a shared register for passing mailbox messages.
+	  When the controller is used by the ACPM protocol the shared register
+	  is ignored and the mailbox controller acts as a doorbell that raises
+	  the interrupt to the ACPM firmware.
+
 config IMX_MBOX
 	tristate "i.MX Mailbox"
 	depends on ARCH_MXC || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 5f4f5b0ce2cc..86192b5c7c32 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -11,6 +11,8 @@ obj-$(CONFIG_ARM_MHU_V2)	+= arm_mhuv2.o
 
 obj-$(CONFIG_ARM_MHU_V3)	+= arm_mhuv3.o
 
+obj-$(CONFIG_EXYNOS_MBOX)	+= exynos-mailbox.o
+
 obj-$(CONFIG_IMX_MBOX)	+= imx-mailbox.o
 
 obj-$(CONFIG_ARMADA_37XX_RWTM_MBOX)	+= armada-37xx-rwtm-mailbox.o
diff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c
new file mode 100644
index 000000000000..6d4e9b3106b2
--- /dev/null
+++ b/drivers/mailbox/exynos-mailbox.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define EXYNOS_MBOX_MCUCTRL		0x0	/* Mailbox Control Register */
+#define EXYNOS_MBOX_INTCR0		0x24	/* Interrupt Clear Register 0 */
+#define EXYNOS_MBOX_INTMR0		0x28	/* Interrupt Mask Register 0 */
+#define EXYNOS_MBOX_INTSR0		0x2c	/* Interrupt Status Register 0 */
+#define EXYNOS_MBOX_INTMSR0		0x30	/* Interrupt Mask Status Register 0 */
+#define EXYNOS_MBOX_INTGR1		0x40	/* Interrupt Generation Register 1 */
+#define EXYNOS_MBOX_INTMR1		0x48	/* Interrupt Mask Register 1 */
+#define EXYNOS_MBOX_INTSR1		0x4c	/* Interrupt Status Register 1 */
+#define EXYNOS_MBOX_INTMSR1		0x50	/* Interrupt Mask Status Register 1 */
+
+#define EXYNOS_MBOX_INTMR0_MASK		GENMASK(15, 0)
+#define EXYNOS_MBOX_INTGR1_MASK		GENMASK(15, 0)
+
+#define EXYNOS_MBOX_CHAN_COUNT		HWEIGHT32(EXYNOS_MBOX_INTGR1_MASK)
+
+/**
+ * struct exynos_mbox - driver's private data.
+ * @regs:	mailbox registers base address.
+ * @mbox:	pointer to the mailbox controller.
+ * @dev:	pointer to the mailbox device.
+ * @pclk:	pointer to the mailbox peripheral clock.
+ */
+struct exynos_mbox {
+	void __iomem *regs;
+	struct mbox_controller *mbox;
+	struct device *dev;
+	struct clk *pclk;
+};
+
+static int exynos_mbox_chan_index(struct mbox_chan *chan)
+{
+	struct mbox_controller *mbox = chan->mbox;
+	int i;
+
+	for (i = 0; i < mbox->num_chans; i++)
+		if (chan == &mbox->chans[i])
+			return i;
+	return -EINVAL;
+}
+
+static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct exynos_mbox *exynos_mbox = dev_get_drvdata(chan->mbox->dev);
+	int index;
+
+	index = exynos_mbox_chan_index(chan);
+	if (index < 0)
+		return index;
+
+	writel_relaxed(BIT(index), exynos_mbox->regs + EXYNOS_MBOX_INTGR1);
+
+	return 0;
+}
+
+static const struct mbox_chan_ops exynos_mbox_chan_ops = {
+	.send_data = exynos_mbox_send_data,
+};
+
+static const struct of_device_id exynos_mbox_match[] = {
+	{ .compatible = "google,gs101-acpm-mbox" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos_mbox_match);
+
+static int exynos_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct exynos_mbox *exynos_mbox;
+	struct mbox_controller *mbox;
+	struct mbox_chan *chans;
+	int i;
+
+	exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL);
+	if (!exynos_mbox)
+		return -ENOMEM;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	chans = devm_kcalloc(dev, EXYNOS_MBOX_CHAN_COUNT, sizeof(*chans),
+			     GFP_KERNEL);
+	if (!chans)
+		return -ENOMEM;
+
+	exynos_mbox->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(exynos_mbox->regs))
+		return PTR_ERR(exynos_mbox->regs);
+
+	exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk");
+	if (IS_ERR(exynos_mbox->pclk))
+		return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk),
+				     "Failed to enable clock.\n");
+
+	mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT;
+	mbox->chans = chans;
+	mbox->dev = dev;
+	mbox->ops = &exynos_mbox_chan_ops;
+
+	for (i = 0; i < EXYNOS_MBOX_CHAN_COUNT; i++)
+		chans[i].mbox = mbox;
+
+	exynos_mbox->dev = dev;
+	exynos_mbox->mbox = mbox;
+
+	platform_set_drvdata(pdev, exynos_mbox);
+
+	/* Mask out all interrupts. We support just polling channels for now. */
+	writel_relaxed(EXYNOS_MBOX_INTMR0_MASK,
+		       exynos_mbox->regs + EXYNOS_MBOX_INTMR0);
+
+	return devm_mbox_controller_register(dev, mbox);
+}
+
+static struct platform_driver exynos_mbox_driver = {
+	.probe	= exynos_mbox_probe,
+	.driver	= {
+		.name = "exynos-acpm-mbox",
+		.of_match_table	= of_match_ptr(exynos_mbox_match),
+	},
+};
+module_platform_driver(exynos_mbox_driver);
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Exynos mailbox driver");
+MODULE_LICENSE("GPL");
-- 
2.47.0.338.g60cca15819-goog



From conor at kernel.org  Thu Dec  5 09:45:52 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 5 Dec 2024 17:45:52 +0000
Subject: [PATCH] dt-bindings: mmc: atmel,hsmci: Convert to json schema
In-Reply-To: <20241205-hsmci-v1-1-5a25e622dfed@microchip.com>
References: <20241205-hsmci-v1-1-5a25e622dfed@microchip.com>
Message-ID: <20241205-trickster-rebate-d5e64bc29992@spud>

On Thu, Dec 05, 2024 at 03:27:02PM +0530, Dharma Balasubiramani wrote:

> +patternProperties:
> +  "^slot@[0-9]+$":
> +    type: object
> +    description: A slot node representing an MMC, SD, or SDIO slot.
> +
> +    allOf:
> +      - $ref: mmc-controller.yaml
> +
> +    properties:
> +      reg:
> +        description: Slot ID.
> +        minimum: 0
> +
> +      bus-width:
> +        description: Number of data lines connected to the controller.
> +        enum: [1, 4, 8]
> +
> +      cd-gpios:
> +        description: GPIO used for card detection.
> +
> +      cd-inverted:
> +        type: boolean

This type conflicts with mmc-controller.yaml, it's a flag there.

> +        description: Inverts the value of the card detection GPIO.
> +
> +      wp-gpios:
> +        description: GPIO used for write protection.
> +
> +    required:
> +      - reg
> +      - bus-width
> +
> +    unevaluatedProperties: false

Do you mean additionalProperties: false here? You listed properties
contained in mmc-controller.yaml which makes it seem like you're
restricting to this subset rather than allowing all properties - but you
need additionalProperties: false to do that.
-------------- 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/20241205/f8887e5d/attachment.sig>

From tudor.ambarus at linaro.org  Thu Dec  5 09:53:44 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 17:53:44 +0000
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <20241205175345.201595-1-tudor.ambarus@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
Message-ID: <20241205175345.201595-3-tudor.ambarus@linaro.org>

Alive Clock and Power Manager (ACPM) Message Protocol is defined for
the purpose of communication between the ACPM firmware and masters
(AP, AOC, ...). ACPM firmware operates on the Active Power Management
(APM) module that handles overall power activities.

ACPM and masters regard each other as independent hardware component and
communicate with each other using mailbox messages and shared memory.

This protocol library provides the interface for all the client drivers
making use of the features offered by the APM. Add ACPM protocol support.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/samsung/Kconfig              |  14 +
 drivers/firmware/samsung/Makefile             |   4 +
 drivers/firmware/samsung/exynos-acpm-pmic.c   | 226 +++++
 drivers/firmware/samsung/exynos-acpm-pmic.h   |  24 +
 drivers/firmware/samsung/exynos-acpm.c        | 772 ++++++++++++++++++
 drivers/firmware/samsung/exynos-acpm.h        |  15 +
 .../linux/soc/samsung/exynos-acpm-protocol.h  |  57 ++
 9 files changed, 1114 insertions(+)
 create mode 100644 drivers/firmware/samsung/Kconfig
 create mode 100644 drivers/firmware/samsung/Makefile
 create mode 100644 drivers/firmware/samsung/exynos-acpm-pmic.c
 create mode 100644 drivers/firmware/samsung/exynos-acpm-pmic.h
 create mode 100644 drivers/firmware/samsung/exynos-acpm.c
 create mode 100644 drivers/firmware/samsung/exynos-acpm.h
 create mode 100644 include/linux/soc/samsung/exynos-acpm-protocol.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 71d8b26c4103..24edb956831b 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -267,6 +267,7 @@ source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/microchip/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/qcom/Kconfig"
+source "drivers/firmware/samsung/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
 source "drivers/firmware/tegra/Kconfig"
 source "drivers/firmware/xilinx/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 7a8d486e718f..91efcc868a05 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -33,6 +33,7 @@ obj-y				+= efi/
 obj-y				+= imx/
 obj-y				+= psci/
 obj-y				+= qcom/
+obj-y				+= samsung/
 obj-y				+= smccc/
 obj-y				+= tegra/
 obj-y				+= xilinx/
diff --git a/drivers/firmware/samsung/Kconfig b/drivers/firmware/samsung/Kconfig
new file mode 100644
index 000000000000..eed8cd8a677b
--- /dev/null
+++ b/drivers/firmware/samsung/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config EXYNOS_ACPM_PROTOCOL
+	tristate "Exynos Alive Clock and Power Manager (ACPM) Message Protocol"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	depends on EXYNOS_MBOX
+	help
+	  Alive Clock and Power Manager (ACPM) Message Protocol is defined for
+	  the purpose of communication between the ACPM firmware and masters
+	  (AP, AOC, ...). ACPM firmware operates on the Active Power Management
+	  (APM) module that handles overall power activities.
+
+	  This protocol library provides interface for all the client drivers
+	  making use of the features offered by the APM.
diff --git a/drivers/firmware/samsung/Makefile b/drivers/firmware/samsung/Makefile
new file mode 100644
index 000000000000..7b4c9f6f34f5
--- /dev/null
+++ b/drivers/firmware/samsung/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+acpm-protocol-objs			:= exynos-acpm.o exynos-acpm-pmic.o
+obj-$(CONFIG_EXYNOS_ACPM_PROTOCOL)	+= acpm-protocol.o
diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.c b/drivers/firmware/samsung/exynos-acpm-pmic.c
new file mode 100644
index 000000000000..371fd67cd56d
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm-pmic.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/sched/clock.h>
+#include <linux/soc/samsung/exynos-acpm-protocol.h>
+#include <linux/types.h>
+
+#include "exynos-acpm.h"
+#include "exynos-acpm-pmic.h"
+
+#define ACPM_PMIC_CHANNEL		GENMASK(15, 12)
+#define ACPM_PMIC_TYPE			GENMASK(11, 8)
+#define ACPM_PMIC_REG			GENMASK(7, 0)
+
+#define ACPM_PMIC_RETURN		GENMASK(31, 24)
+#define ACPM_PMIC_MASK			GENMASK(23, 16)
+#define ACPM_PMIC_VALUE			GENMASK(15, 8)
+#define ACPM_PMIC_FUNC			GENMASK(7, 0)
+
+#define ACPM_BULK_SHIFT			8
+#define ACPM_BULK_MASK			GENMASK(7, 0)
+#define exynos_acpm_set_bulk(data, i)					\
+	(((data) & ACPM_BULK_MASK) << (ACPM_BULK_SHIFT * (i)))
+#define exynos_acpm_read_bulk(data, i)					\
+	(((data) >> (ACPM_BULK_SHIFT * (i))) & ACPM_BULK_MASK)
+
+enum exynos_acpm_pmic_func {
+	ACPM_PMIC_READ,
+	ACPM_PMIC_WRITE,
+	ACPM_PMIC_UPDATE,
+	ACPM_PMIC_BULK_READ,
+	ACPM_PMIC_BULK_WRITE,
+};
+
+static void acpm_pmic_init_read_cmd(u32 *cmd, u8 type, u8 reg, u8 chan)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_READ);
+	cmd[3] = (u32)(sched_clock() / 1000000); /*record ktime ms*/
+}
+
+int acpm_pmic_read_reg(const struct acpm_handle *handle, int acpm_chan_id,
+		       u8 type, u8 reg, u8 chan, u8 *dest)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_read_cmd(cmd, type, reg, chan);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	*dest = FIELD_GET(ACPM_PMIC_VALUE, xfer.rx.cmd[1]);
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+static void acpm_pmic_init_bulk_read_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+					 u8 count)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_BULK_READ) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, count);
+}
+
+int acpm_pmic_bulk_read(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 count, u8 *buf)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int i, ret;
+
+	acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	ret = FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < count; i++) {
+		if (i < 4)
+			buf[i] = exynos_acpm_read_bulk(xfer.rx.cmd[2], i);
+		else
+			buf[i] = exynos_acpm_read_bulk(xfer.rx.cmd[3], i - 4);
+	}
+
+	return 0;
+}
+
+static void acpm_pmic_init_write_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+				     u8 value)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_WRITE) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, value);
+	cmd[3] = (u32)(sched_clock() / 1000000); /*record ktime ms*/
+}
+
+int acpm_pmic_write_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 value)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_write_cmd(cmd, type, reg, chan, value);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+static void acpm_pmic_init_bulk_write_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+					  u8 count, u8 *buf)
+{
+	int i;
+
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_BULK_WRITE) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, count);
+
+	for (i = 0; i < count; i++) {
+		if (i < 4)
+			cmd[2] |= exynos_acpm_set_bulk(buf[i], i);
+		else
+			cmd[3] |= exynos_acpm_set_bulk(buf[i], i - 4);
+	}
+}
+
+int acpm_pmic_bulk_write(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 count, u8 *buf)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+static void acpm_pmic_init_update_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+				      u8 value, u8 mask)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_UPDATE) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, value) |
+		 FIELD_PREP(ACPM_PMIC_MASK, mask);
+	cmd[3] = (u32)(sched_clock() / 1000000); /*record ktime ms*/
+}
+
+int acpm_pmic_update_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 value, u8 mask)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos ACPM mailbox PMIC protocol driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.h b/drivers/firmware/samsung/exynos-acpm-pmic.h
new file mode 100644
index 000000000000..c7ff5fdde25a
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm-pmic.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+#ifndef __EXYNOS_ACPM_MFD_H__
+#define __EXYNOS_ACPM_MFD_H__
+
+#include <linux/types.h>
+
+struct acpm_handle;
+
+int acpm_pmic_read_reg(const struct acpm_handle *handle, int acpm_chan_id,
+		       u8 type, u8 reg, u8 chan, u8 *dest);
+int acpm_pmic_bulk_read(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+int acpm_pmic_write_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 value);
+int acpm_pmic_bulk_write(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+int acpm_pmic_update_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 value, u8 mask);
+#endif /* __EXYNOS_ACPM_MFD_H__ */
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
new file mode 100644
index 000000000000..1b04230942a4
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -0,0 +1,772 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitmap.h>
+#include <linux/bits.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/math.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/soc/samsung/exynos-acpm-protocol.h>
+#include <linux/types.h>
+
+#include "exynos-acpm.h"
+#include "exynos-acpm-pmic.h"
+
+#define ACPM_PROTOCOL_SEQNUM	GENMASK(21, 16)
+
+/* The unit of counter is 20 us. 5000 * 20 = 100 ms */
+#define ACPM_POLL_TIMEOUT	5000
+#define ACPM_TX_TIMEOUT_US	500000
+
+/**
+ * struct acpm_shmem - shared memory configuration information.
+ * @reserved:	unused fields.
+ * @chans:	offset to array of struct acpm_chan_shmem.
+ * @reserved1:	unused fields.
+ * @num_chans:	number of channels.
+ */
+struct acpm_shmem {
+	u32 reserved[2];
+	u32 chans;
+	u32 reserved1[3];
+	u32 num_chans;
+};
+
+/**
+ * struct acpm_chan_shmem - descriptor of a shared memory channel.
+ *
+ * @id:			channel ID.
+ * @reserved:		unused fields.
+ * @rx_rear:		rear pointer of APM RX queue (TX for AP).
+ * @rx_front:		front pointer of APM RX queue (TX for AP).
+ * @rx_base:		base address of APM RX queue (TX for AP).
+ * @reserved1:		unused fields.
+ * @tx_rear:		rear pointer of APM TX queue (RX for AP).
+ * @tx_front:		front pointer of APM TX queue (RX for AP).
+ * @tx_base:		base address of APM TX queue (RX for AP).
+ * @qlen:		queue length. Applies to both TX/RX queues.
+ * @mlen:		message length. Applies to both TX/RX queues.
+ * @reserved2:		unused fields.
+ * @poll_completion:	true when the channel works on polling.
+ */
+struct acpm_chan_shmem {
+	u32 id;
+	u32 reserved[3];
+	u32 rx_rear;
+	u32 rx_front;
+	u32 rx_base;
+	u32 reserved1[3];
+	u32 tx_rear;
+	u32 tx_front;
+	u32 tx_base;
+	u32 qlen;
+	u32 mlen;
+	u32 reserved2[2];
+	u32 poll_completion;
+};
+
+/**
+ * struct acpm_queue - exynos acpm queue.
+ *
+ * @rear:	rear address of the queue.
+ * @front:	front address of the queue.
+ * @base:	base address of the queue.
+ */
+struct acpm_queue {
+	void __iomem *rear;
+	void __iomem *front;
+	void __iomem *base;
+};
+
+/**
+ * struct acpm_rx_data - RX queue data.
+ *
+ * @cmd:	pointer to where the data shall be saved.
+ * @n_cmd:	number of 32-bit commands.
+ * @response:	true if the client expects the RX data.
+ */
+struct acpm_rx_data {
+	u32 *cmd;
+	size_t n_cmd;
+	bool response;
+};
+
+#define ACPM_SEQNUM_MAX    64
+
+/**
+ * struct acpm_chan - driver internal representation of a channel.
+ * @cl:		mailbox client.
+ * @chan:	mailbox channel.
+ * @acpm:	pointer to driver private data.
+ * @tx:		TX queue. The enqueue is done by the host.
+ *			- front index is written by the host.
+ *			- rear index is written by the firmware.
+ *
+ * @rx:		RX queue. The enqueue is done by the firmware.
+ *			- front index is written by the firmware.
+ *			- rear index is written by the host.
+ * @tx_lock:	protects TX queue.
+ * @rx_lock:	protects RX queue.
+ * @qlen:	queue length. Applies to both TX/RX queues.
+ * @mlen:	message length. Applies to both TX/RX queues.
+ * @seqnum:	sequence number of the last message enqueued on TX queue.
+ * @id:		channel ID.
+ * @poll_completion:	indicates if the transfer needs to be polled for
+ *			completion or interrupt mode is used.
+ * @bitmap_seqnum: bitmap that tracks the messages on the TX/RX queues.
+ * @rx_data:	internal buffer used to drain the RX queue.
+ */
+struct acpm_chan {
+	struct mbox_client cl;
+	struct mbox_chan *chan;
+	struct acpm_info *acpm;
+	struct acpm_queue tx;
+	struct acpm_queue rx;
+	spinlock_t tx_lock;
+	spinlock_t rx_lock;
+
+	unsigned int qlen;
+	unsigned int mlen;
+	u8 seqnum;
+	u8 id;
+	bool poll_completion;
+
+	DECLARE_BITMAP(bitmap_seqnum, ACPM_SEQNUM_MAX - 1);
+	struct acpm_rx_data rx_data[ACPM_SEQNUM_MAX];
+};
+
+/**
+ * struct acpm_info - driver's private data.
+ * @shmem:	pointer to the SRAM configuration data.
+ * @sram_base:	base address of SRAM.
+ * @chans:	pointer to the ACPM channel parameters retrieved from SRAM.
+ * @dev:	pointer to the exynos-acpm device.
+ * @handle:	instance of acpm_handle to send to clients.
+ * @node:	list head
+ * @num_chans:	number of channels available for this controller.
+ * @users:	number of users of this instance.
+ */
+struct acpm_info {
+	struct acpm_shmem __iomem *shmem;
+	void __iomem *sram_base;
+	struct acpm_chan *chans;
+	struct device *dev;
+	struct acpm_handle handle;
+	struct list_head node;
+	u32 num_chans;
+	/* protected by acpm_list_mutex */
+	int users;
+};
+
+#define client_to_acpm_chan(c) container_of(c, struct acpm_chan, cl)
+#define handle_to_acpm_info(h) container_of(h, struct acpm_info, handle)
+
+/* List of all ACPM devices active in system */
+static LIST_HEAD(acpm_list);
+/* Protection for the entire list */
+static DEFINE_MUTEX(acpm_list_mutex);
+
+/**
+ * acpm_get_rx() - get response from RX queue.
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer to get response for.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_get_rx(struct acpm_chan *achan, struct acpm_xfer *xfer)
+{
+	struct acpm_msg *tx = &xfer->tx;
+	struct acpm_msg *rx = &xfer->rx;
+	struct acpm_rx_data *rx_data;
+	const void __iomem *base, *addr;
+	u32 rx_front, rx_seqnum, tx_seqnum, seqnum;
+	u32 i, val, mlen;
+	bool rx_set = false;
+
+	rx_front = readl_relaxed(achan->rx.front);
+	i = readl_relaxed(achan->rx.rear);
+
+	/* Bail out if RX is empty. */
+	if (i == rx_front)
+		return 0;
+
+	base = achan->rx.base;
+	mlen = achan->mlen;
+
+	tx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, tx->cmd[0]);
+
+	/* Drain RX queue. */
+	do {
+		/* Read RX seqnum. */
+		addr = base + mlen * i;
+		val = readl_relaxed(addr);
+
+		rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, val);
+		if (!rx_seqnum)
+			return -EIO;
+		/*
+		 * mssg seqnum starts with value 1, whereas the driver considers
+		 * the first mssg at index 0.
+		 */
+		seqnum = rx_seqnum - 1;
+		rx_data = &achan->rx_data[seqnum];
+
+		if (rx_data->response) {
+			if (rx_seqnum == tx_seqnum) {
+				__ioread32_copy(rx->cmd, addr, rx->len / 4);
+				rx_set = true;
+				clear_bit(seqnum, achan->bitmap_seqnum);
+			} else {
+				/*
+				 * The RX data corresponds to another request.
+				 * Save the data to drain the queue, but don't
+				 * clear yet the bitmap. It will be cleared
+				 * after the response is copied to the request.
+				 */
+				__ioread32_copy(rx_data->cmd, addr,
+						rx->len / 4);
+			}
+		} else {
+			clear_bit(seqnum, achan->bitmap_seqnum);
+		}
+
+		i = (i + 1) % achan->qlen;
+	} while (i != rx_front);
+
+	/* We saved all responses, mark RX empty. */
+	writel_relaxed(rx_front, achan->rx.rear);
+
+	/* Flush SRAM posted writes. */
+	readl_relaxed(achan->rx.front);
+
+	/*
+	 * If the response was not in this iteration of the queue, check if the
+	 * RX data was previously saved.
+	 */
+	rx_data = &achan->rx_data[tx_seqnum - 1];
+	if (!rx_set && rx_data->response) {
+		rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM,
+				      rx_data->cmd[0]);
+
+		if (rx_seqnum == tx_seqnum) {
+			memcpy(rx->cmd, rx_data->cmd, rx->len);
+			clear_bit(rx_seqnum - 1, achan->bitmap_seqnum);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * acpm_dequeue_by_polling() - RX dequeue by polling.
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer being waited for.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_dequeue_by_polling(struct acpm_chan *achan,
+				   struct acpm_xfer *xfer)
+{
+	bool may_sleep = xfer->flags & ACPM_XFER_MAY_SLEEP;
+	struct device *dev = achan->acpm->dev;
+	struct acpm_msg *tx = &xfer->tx;
+	unsigned long flags;
+	unsigned int cnt_20us = 0;
+	u32 seqnum;
+	int ret;
+
+	seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, tx->cmd[0]);
+
+	do {
+		spin_lock_irqsave(&achan->rx_lock, flags);
+		ret = acpm_get_rx(achan, xfer);
+		spin_unlock_irqrestore(&achan->rx_lock, flags);
+		if (ret)
+			return ret;
+
+		if (!test_bit(seqnum - 1, achan->bitmap_seqnum))
+			return 0;
+
+		/* Determined experimentally. */
+		may_sleep ? usleep_range(20, 30) : udelay(20);
+		cnt_20us++;
+	} while (cnt_20us < ACPM_POLL_TIMEOUT);
+
+	dev_err(dev, "Timeout! ch:%u s:%u bitmap:%lx, cnt_20us = %d.\n",
+		achan->id, seqnum, achan->bitmap_seqnum[0], cnt_20us);
+
+	return -ETIME;
+}
+
+/**
+ * acpm_wait_for_queue_slots() - wait for queue slots.
+ *
+ * @achan:		ACPM channel info.
+ * @next_tx_front:	next front index of the TX queue.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_wait_for_queue_slots(struct acpm_chan *achan, u32 next_tx_front)
+{
+	u32 val, ret;
+
+	/*
+	 * Wait for RX front to keep up with TX front. Make sure there's at
+	 * least one element between them.
+	 */
+	ret = readl_relaxed_poll_timeout_atomic(achan->rx.front, val,
+						next_tx_front != val, 0,
+						ACPM_TX_TIMEOUT_US);
+	if (ret) {
+		dev_err(achan->acpm->dev, "RX front can not keep up with TX front.\n");
+		return ret;
+	}
+
+	ret = readl_relaxed_poll_timeout_atomic(achan->tx.rear, val,
+						next_tx_front != val, 0,
+						ACPM_TX_TIMEOUT_US);
+	if (ret)
+		dev_err(achan->acpm->dev, "TX queue is full.\n");
+
+	return ret;
+}
+
+/**
+ * acpm_prepare_xfer() - prepare a transfer before writing the message to the
+ * TX queue.
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer being prepared.
+ */
+static void acpm_prepare_xfer(struct acpm_chan *achan, struct acpm_xfer *xfer)
+{
+	struct acpm_msg *tx = &xfer->tx;
+	struct acpm_rx_data *rx_data;
+
+	/* Prevent chan->seqnum from being re-used */
+	do {
+		if (++achan->seqnum == ACPM_SEQNUM_MAX)
+			achan->seqnum = 1;
+	} while (test_bit(achan->seqnum - 1, achan->bitmap_seqnum));
+
+	tx->cmd[0] |= FIELD_PREP(ACPM_PROTOCOL_SEQNUM, achan->seqnum);
+
+	/* Clear data for upcoming responses */
+	rx_data = &achan->rx_data[achan->seqnum - 1];
+	memset(rx_data->cmd, 0, sizeof(*rx_data->cmd) * rx_data->n_cmd);
+	if (xfer->rx.cmd)
+		rx_data->response = true;
+
+	/* Flag the index based on seqnum. (seqnum: 1~63, bitmap: 0~62) */
+	set_bit(achan->seqnum - 1, achan->bitmap_seqnum);
+}
+
+/**
+ * acpm_wait_for_message_response - an helper to group all possible ways of
+ * waiting for a synchronous message response.
+ *
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer being waited for.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_wait_for_message_response(struct acpm_chan *achan,
+					  struct acpm_xfer *xfer)
+{
+	if (achan->poll_completion)
+		return acpm_dequeue_by_polling(achan, xfer);
+
+	dev_err(achan->acpm->dev, "Interrupt mode not supported\n");
+	return -EOPNOTSUPP;
+}
+
+/**
+ * acpm_do_xfer() - do one transfer.
+ * @handle:	pointer to the acpm handle.
+ * @xfer:	transfer to initiate and wait for response.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int acpm_do_xfer(const struct acpm_handle *handle, struct acpm_xfer *xfer)
+{
+	struct acpm_info *acpm = handle_to_acpm_info(handle);
+	struct acpm_chan *achan = &acpm->chans[xfer->acpm_chan_id];
+	struct acpm_msg *tx = &xfer->tx;
+	u32 idx, tx_front;
+	unsigned long flags;
+	int ret;
+
+	if (!tx->cmd || tx->len > achan->mlen || xfer->rx.len > achan->mlen)
+		return -EINVAL;
+
+	spin_lock_irqsave(&achan->tx_lock, flags);
+
+	tx_front = readl_relaxed(achan->tx.front);
+	idx = (tx_front + 1) % achan->qlen;
+
+	ret = acpm_wait_for_queue_slots(achan, idx);
+	if (ret) {
+		spin_unlock_irqrestore(&achan->tx_lock, flags);
+		return ret;
+	}
+
+	acpm_prepare_xfer(achan, xfer);
+
+	/* Write TX command. */
+	__iowrite32_copy(achan->tx.base + achan->mlen * tx_front, tx->cmd,
+			 tx->len / 4);
+
+	/* Advance TX front. */
+	writel_relaxed(idx, achan->tx.front);
+
+	/* Flush SRAM posted writes. */
+	readl_relaxed(achan->tx.front);
+
+	spin_unlock_irqrestore(&achan->tx_lock, flags);
+
+	ret = mbox_send_message(achan->chan, xfer);
+	if (ret < 0)
+		return ret;
+
+	ret = acpm_wait_for_message_response(achan, xfer);
+
+	/*
+	 * NOTE: we might prefer not to need the mailbox ticker to manage the
+	 * transfer queueing since the protocol layer queues things by itself.
+	 * Unfortunately, we have to kick the mailbox framework after we have
+	 * received our message.
+	 */
+	mbox_client_txdone(achan->chan, ret);
+
+	return ret;
+}
+
+/**
+ * acpm_put_handle() - release the handle acquired by acpm_get_by_phandle.
+ * @handle:	Handle acquired by acpm_get_by_phandle.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_put_handle(const struct acpm_handle *handle)
+{
+	struct acpm_info *acpm;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	acpm = handle_to_acpm_info(handle);
+	mutex_lock(&acpm_list_mutex);
+	if (!WARN_ON(!acpm->users))
+		acpm->users--;
+	mutex_unlock(&acpm_list_mutex);
+
+	return 0;
+}
+
+/**
+ * devm_acpm_release() - devres release method.
+ * @dev: pointer to device.
+ * @res: pointer to resource.
+ */
+static void devm_acpm_release(struct device *dev, void *res)
+{
+	const struct acpm_handle **ptr = res;
+	const struct acpm_handle *handle = *ptr;
+	int ret;
+
+	ret = acpm_put_handle(handle);
+	if (ret)
+		dev_err(dev, "failed to put handle %d\n", ret);
+}
+
+/**
+ * acpm_get_by_phandle() - get the ACPM handle using DT phandle.
+ * @np:		device node.
+ * @property:	property name containing phandle on ACPM node.
+ *
+ * Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
+ */
+static const struct acpm_handle *acpm_get_by_phandle(struct device_node *np,
+						     const char *property)
+{
+	struct acpm_handle *handle = NULL;
+	struct device_node *acpm_np;
+	struct acpm_info *info;
+
+	if (!np) {
+		pr_err("I need a device pointer\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	acpm_np = of_parse_phandle(np, property, 0);
+	if (!acpm_np)
+		return ERR_PTR(-ENODEV);
+
+	mutex_lock(&acpm_list_mutex);
+	list_for_each_entry(info, &acpm_list, node) {
+		if (acpm_np == info->dev->of_node) {
+			handle = &info->handle;
+			info->users++;
+			break;
+		}
+	}
+	mutex_unlock(&acpm_list_mutex);
+	of_node_put(acpm_np);
+
+	if (!handle)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return handle;
+}
+
+/**
+ * devm_acpm_get_by_phandle() - managed get handle using phandle.
+ * @dev:	device pointer requesting ACPM handle.
+ * @property:	property name containing phandle on ACPM node.
+ *
+ * Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
+ */
+const struct acpm_handle *devm_acpm_get_by_phandle(struct device *dev,
+						   const char *property)
+{
+	const struct acpm_handle *handle;
+	const struct acpm_handle **ptr;
+
+	ptr = devres_alloc(devm_acpm_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+	handle = acpm_get_by_phandle(dev_of_node(dev), property);
+
+	if (!IS_ERR(handle)) {
+		*ptr = handle;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return handle;
+}
+EXPORT_SYMBOL_GPL(devm_acpm_get_by_phandle);
+
+/**
+ * acpm_chan_shmem_get_params() - get channel parameters and addresses of the
+ * TX/RX queues.
+ * @achan:	ACPM channel info.
+ * @chan_shmem:	__iomem pointer to a channel described in shared memory.
+ */
+static void acpm_chan_shmem_get_params(struct acpm_chan *achan,
+				struct acpm_chan_shmem __iomem *chan_shmem)
+{
+	void __iomem *base = achan->acpm->sram_base;
+	struct acpm_queue *rx = &achan->rx;
+	struct acpm_queue *tx = &achan->tx;
+
+	achan->mlen = readl_relaxed(&chan_shmem->mlen);
+	achan->poll_completion = readl_relaxed(&chan_shmem->poll_completion);
+	achan->id = readl_relaxed(&chan_shmem->id);
+	achan->qlen = readl_relaxed(&chan_shmem->qlen);
+
+	tx->base = base + readl_relaxed(&chan_shmem->rx_base);
+	tx->rear = base + readl_relaxed(&chan_shmem->rx_rear);
+	tx->front = base + readl_relaxed(&chan_shmem->rx_front);
+
+	rx->base = base + readl_relaxed(&chan_shmem->tx_base);
+	rx->rear = base + readl_relaxed(&chan_shmem->tx_rear);
+	rx->front = base + readl_relaxed(&chan_shmem->tx_front);
+
+	dev_vdbg(achan->acpm->dev, "ID = %d poll = %d, mlen = %d, qlen = %d\n",
+		 achan->id, achan->poll_completion, achan->mlen, achan->qlen);
+}
+
+/**
+ * acpm_achan_alloc_cmds() - allocate buffers for retrieving data from the ACPM
+ * firmware.
+ * @achan:	ACPM channel info.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_achan_alloc_cmds(struct acpm_chan *achan)
+{
+	struct device *dev = achan->acpm->dev;
+	struct acpm_rx_data *rx_data;
+	size_t cmd_size, n_cmd;
+	int i;
+
+	if (achan->mlen == 0)
+		return 0;
+
+	cmd_size = sizeof(*(achan->rx_data[0].cmd));
+	n_cmd = DIV_ROUND_UP_ULL(achan->mlen, cmd_size);
+
+	for (i = 0; i < ACPM_SEQNUM_MAX; i++) {
+		rx_data = &achan->rx_data[i];
+		rx_data->n_cmd = n_cmd;
+		rx_data->cmd = devm_kcalloc(dev, n_cmd, cmd_size, GFP_KERNEL);
+		if (!rx_data->cmd)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * acpm_free_mbox_chans() - free mailbox channels.
+ * @acpm:	pointer to driver data.
+ */
+static void acpm_free_mbox_chans(struct acpm_info *acpm)
+{
+	int i;
+
+	for (i = 0; i < acpm->num_chans; i++)
+		mbox_free_channel(acpm->chans[i].chan);
+}
+
+/**
+ * acpm_channels_init() - initialize channels based on the configuration data in
+ * the shared memory.
+ * @acpm:	pointer to driver data.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_channels_init(struct acpm_info *acpm)
+{
+	struct acpm_shmem __iomem *shmem = acpm->shmem;
+	struct acpm_chan_shmem __iomem *chans_shmem;
+	struct device *dev = acpm->dev;
+	int i, ret;
+
+	acpm->num_chans = readl_relaxed(&shmem->num_chans);
+	acpm->chans = devm_kcalloc(dev, acpm->num_chans, sizeof(*acpm->chans),
+				   GFP_KERNEL);
+	if (!acpm->chans)
+		return -ENOMEM;
+
+	chans_shmem = acpm->sram_base + readl_relaxed(&shmem->chans);
+
+	for (i = 0; i < acpm->num_chans; i++) {
+		struct acpm_chan_shmem __iomem *chan_shmem = &chans_shmem[i];
+		struct acpm_chan *achan = &acpm->chans[i];
+		struct mbox_client *cl = &achan->cl;
+
+		achan->acpm = acpm;
+
+		acpm_chan_shmem_get_params(achan, chan_shmem);
+
+		ret = acpm_achan_alloc_cmds(achan);
+		if (ret)
+			return ret;
+
+		spin_lock_init(&achan->rx_lock);
+		spin_lock_init(&achan->tx_lock);
+
+		cl->dev = dev;
+
+		achan->chan = mbox_request_channel(cl, achan->id);
+		if (IS_ERR(achan->chan)) {
+			acpm_free_mbox_chans(acpm);
+			return PTR_ERR(achan->chan);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * acpm_setup_ops() - setup the operations structures.
+ * @acpm:	pointer to the driver data.
+ */
+static void acpm_setup_ops(struct acpm_info *acpm)
+{
+	struct acpm_pmic_ops *pmic_ops = &acpm->handle.ops.pmic_ops;
+
+	pmic_ops->read_reg = acpm_pmic_read_reg;
+	pmic_ops->bulk_read = acpm_pmic_bulk_read;
+	pmic_ops->write_reg = acpm_pmic_write_reg;
+	pmic_ops->bulk_write = acpm_pmic_bulk_write;
+	pmic_ops->update_reg = acpm_pmic_update_reg;
+}
+
+static int acpm_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *shmem;
+	struct acpm_info *acpm;
+	resource_size_t size;
+	struct resource res;
+	const __be32 *prop;
+	int ret;
+
+	acpm = devm_kzalloc(dev, sizeof(*acpm), GFP_KERNEL);
+	if (!acpm)
+		return -ENOMEM;
+
+	shmem = of_parse_phandle(node, "shmem", 0);
+	ret = of_address_to_resource(shmem, 0, &res);
+	of_node_put(shmem);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get shared memory.\n");
+
+	size = resource_size(&res);
+	acpm->sram_base = devm_ioremap(dev, res.start, size);
+	if (!acpm->sram_base)
+		return dev_err_probe(dev, -ENOMEM,
+				     "Failed to ioremap shared memory.\n");
+
+	prop = of_get_property(node, "initdata-base", NULL);
+	if (!prop)
+		return dev_err_probe(dev, -EINVAL,
+				     "Parsing initdata_base failed.\n");
+
+	acpm->dev = dev;
+	acpm->shmem = acpm->sram_base + be32_to_cpup(prop);
+
+	ret = acpm_channels_init(acpm);
+	if (ret)
+		return ret;
+
+	acpm_setup_ops(acpm);
+
+	INIT_LIST_HEAD(&acpm->node);
+	mutex_lock(&acpm_list_mutex);
+	list_add_tail(&acpm->node, &acpm_list);
+	mutex_unlock(&acpm_list_mutex);
+
+	platform_set_drvdata(pdev, acpm);
+
+	return 0;
+}
+
+static const struct of_device_id acpm_match[] = {
+	{ .compatible = "google,gs101-acpm-ipc" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, acpm_match);
+
+static struct platform_driver acpm_driver = {
+	.probe	= acpm_probe,
+	.driver	= {
+		.name = "exynos-acpm-protocol",
+		.of_match_table	= of_match_ptr(acpm_match),
+	},
+};
+module_platform_driver(acpm_driver);
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos ACPM mailbox protocol driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h
new file mode 100644
index 000000000000..a03adcd260f5
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+#ifndef __EXYNOS_ACPM_H__
+#define __EXYNOS_ACPM_H__
+
+struct acpm_handle;
+struct acpm_xfer;
+
+int acpm_do_xfer(const struct acpm_handle *handle, struct acpm_xfer *xfer);
+
+#endif /* __EXYNOS_ACPM_H__ */
diff --git a/include/linux/soc/samsung/exynos-acpm-protocol.h b/include/linux/soc/samsung/exynos-acpm-protocol.h
new file mode 100644
index 000000000000..762783af7617
--- /dev/null
+++ b/include/linux/soc/samsung/exynos-acpm-protocol.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#ifndef __EXYNOS_ACPM_PROTOCOL_H
+#define __EXYNOS_ACPM_PROTOCOL_H
+
+#include <linux/types.h>
+
+struct acpm_msg {
+	u32 *cmd;
+	size_t len;
+};
+
+struct acpm_xfer {
+	struct acpm_msg tx;
+	struct acpm_msg rx;
+	int acpm_chan_id;
+#define ACPM_XFER_MAY_SLEEP     BIT(0)
+	u32 flags;
+};
+
+struct acpm_handle;
+
+struct acpm_pmic_ops {
+	int (*read_reg)(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 *dest);
+	int (*bulk_read)(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+	int (*write_reg)(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 value);
+	int (*bulk_write)(const struct acpm_handle *handle, int acpm_chan_id,
+			  u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+	int (*update_reg)(const struct acpm_handle *handle, int acpm_chan_id,
+			  u8 type, u8 reg, u8 chan, u8 value, u8 mask);
+};
+
+struct acpm_ops {
+	struct acpm_pmic_ops pmic_ops;
+};
+
+/**
+ * struct acpm_handle - Reference to an initialized protocol instance
+ * @ops:
+ */
+struct acpm_handle {
+	struct acpm_ops ops;
+};
+
+struct device_node;
+
+const struct acpm_handle *devm_acpm_get_by_phandle(struct device *dev,
+						   const char *property);
+#endif /* __EXYNOS_ACPM_PROTOCOL_H */
-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec  5 09:53:42 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 17:53:42 +0000
Subject: [PATCH v3 0/3] firmware: add exynos ACPM protocol driver
Message-ID: <20241205175345.201595-1-tudor.ambarus@linaro.org>

Alive Clock and Power Manager (ACPM) Message Protocol is defined for
the purpose of communication between the ACPM firmware and masters
(AP, AOC, ...). ACPM firmware operates on the Active Power Management
(APM) module that handles overall power activities.

This protocol library provides the interface for all the client drivers
making use of the features offered by the APM. Add ACPM protocol support.

I mark this as v3 because it is a continuation of:
https://lore.kernel.org/linux-arm-kernel/20241017163649.3007062-1-tudor.ambarus at linaro.org/

The samsung exynos mailbox controller driver, the transport layer for
ACPM, can be found at:
https://lore.kernel.org/linux-arm-kernel/20241205174137.190545-1-tudor.ambarus at linaro.org/

Changes in v3:
- decouple the mailbox controller driver from the ACPM protocol driver
- address Krzysztof's eview comments 
- add ACPM PMIC protocol helpers

Cheers,
ta

Tudor Ambarus (3):
  dt-bindings: firmware: add samsung,exynos-acpm-ipc bindings
  firmware: add exynos ACPM protocol driver
  MAINTAINERS: add entry for the samsung exynos ACPM mailbox protocol

 .../firmware/samsung,exynos-acpm-ipc.yaml     |  64 ++
 MAINTAINERS                                   |  10 +
 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/samsung/Kconfig              |  14 +
 drivers/firmware/samsung/Makefile             |   4 +
 drivers/firmware/samsung/exynos-acpm-pmic.c   | 226 +++++
 drivers/firmware/samsung/exynos-acpm-pmic.h   |  24 +
 drivers/firmware/samsung/exynos-acpm.c        | 772 ++++++++++++++++++
 drivers/firmware/samsung/exynos-acpm.h        |  15 +
 .../linux/soc/samsung/exynos-acpm-protocol.h  |  57 ++
 11 files changed, 1188 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml
 create mode 100644 drivers/firmware/samsung/Kconfig
 create mode 100644 drivers/firmware/samsung/Makefile
 create mode 100644 drivers/firmware/samsung/exynos-acpm-pmic.c
 create mode 100644 drivers/firmware/samsung/exynos-acpm-pmic.h
 create mode 100644 drivers/firmware/samsung/exynos-acpm.c
 create mode 100644 drivers/firmware/samsung/exynos-acpm.h
 create mode 100644 include/linux/soc/samsung/exynos-acpm-protocol.h

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec  5 09:53:43 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 17:53:43 +0000
Subject: [PATCH v3 1/3] dt-bindings: firmware: add samsung,exynos-acpm-ipc bindings
In-Reply-To: <20241205175345.201595-1-tudor.ambarus@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
Message-ID: <20241205175345.201595-2-tudor.ambarus@linaro.org>

Add bindings for the samsung exynos ACPM mailbox protocol.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 .../firmware/samsung,exynos-acpm-ipc.yaml     | 64 +++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml

diff --git a/Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml b/Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml
new file mode 100644
index 000000000000..bfc9b4af9ea1
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2024 Linaro Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/samsung,exynos-acpm-ipc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung exynos ACPM mailbox protocol
+
+maintainers:
+  - Tudor Ambarus <tudor.ambarus at linaro.org>
+
+description: |
+  ACPM (Alive Clock and Power Manager) is a firmware that operates on the
+  APM (Active Power Management) module that handles overall power management
+  activities. ACPM and masters regard each other as independent hardware
+  component and communicate with each other using mailbox messages and
+  shared memory.
+
+  This binding is intended to define the interface the firmware implementing
+  ACPM provides for OSPM in the device tree.
+
+properties:
+  $nodename:
+    const: acpm_ipc
+
+  compatible:
+    const: google,gs101-acpm-ipc
+
+  mboxes:
+    description:
+      List of phandle and mailbox channel specifiers.
+    maxItems: 1
+
+  shmem:
+    description:
+      List of phandle pointing to the shared memory (SHM) area. The memory
+      contains channels configuration data and the TX/RX ring buffers that
+      are used for passing messages to/from the ACPM firmware.
+    maxItems: 1
+
+  initdata-base:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Base address of the configuration data in the shared memory.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - mboxes
+  - shmem
+  - initdata-base
+
+examples:
+  - |
+    firmware {
+        acpm_ipc: acpm_ipc {
+            compatible = "google,gs101-acpm-ipc";
+            mboxes = <&ap2apm_mailbox 0>;
+            shmem = <&apm_sram>;
+            initdata-base = <0xa000>;
+        };
+    };
-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec  5 09:53:45 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 17:53:45 +0000
Subject: [PATCH v3 3/3] MAINTAINERS: add entry for the samsung exynos ACPM mailbox protocol
In-Reply-To: <20241205175345.201595-1-tudor.ambarus@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
Message-ID: <20241205175345.201595-4-tudor.ambarus@linaro.org>

Add entry for the samsung exynos ACPM mailbox protocol.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..5cff01641f23 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3023,6 +3023,7 @@ F:	drivers/*/*s3c24*
 F:	drivers/*/*s3c64xx*
 F:	drivers/*/*s5pv210*
 F:	drivers/clocksource/samsung_pwm_timer.c
+F:	drivers/firmware/samsung/
 F:	drivers/memory/samsung/
 F:	drivers/pwm/pwm-samsung.c
 F:	drivers/soc/samsung/
@@ -20712,6 +20713,15 @@ F:	arch/arm64/boot/dts/exynos/exynos850*
 F:	drivers/clk/samsung/clk-exynos850.c
 F:	include/dt-bindings/clock/exynos850.h
 
+SAMSUNG EXYNOS ACPM MAILBOX PROTOCOL
+M:	Tudor Ambarus <tudor.ambarus at linaro.org>
+L:	linux-kernel at vger.kernel.org
+L:	linux-samsung-soc at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml
+F:	drivers/firmware/samsung/exynos-acpm*
+F:	include/linux/soc/samsung/exynos-acpm-protocol.h
+
 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 M:	Krzysztof Kozlowski <krzk at kernel.org>
 L:	linux-crypto at vger.kernel.org
-- 
2.47.0.338.g60cca15819-goog



From conor at kernel.org  Thu Dec  5 09:58:25 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 5 Dec 2024 17:58:25 +0000
Subject: [PATCH 3/5] regulator: dt-bindings: pca9450: Add pca9452 support
In-Reply-To: <20241205-pca9450-v1-3-aab448b74e78@nxp.com>
References: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
 <20241205-pca9450-v1-3-aab448b74e78@nxp.com>
Message-ID: <20241205-cornfield-stoplight-664ad32353de@spud>

On Thu, Dec 05, 2024 at 11:51:11AM -0500, Frank Li wrote:
> From: Joy Zou <joy.zou at nxp.com>
> 
> Add compatible string 'nxp,pca9452'. pca9452 add 'ldo3' compared with
> pca9451a.
> 
> Signed-off-by: Joy Zou <joy.zou at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

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/20241205/2ce685e5/attachment.sig>

From kent.overstreet at linux.dev  Thu Dec  5 10:03:11 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Thu, 5 Dec 2024 13:03:11 -0500
Subject: No subject
Message-ID: <36kx57aw46vwykgckr5cm4fafhw54tjuj4cqljrdnpfwvjl7if@a7znuhpfu54o>

linux-kernel at vger.kernel.org
Cc:
Bcc:
Subject: Re: arm64: stacktrace: unwind exception boundaries
Message-ID: <cqmiqyusbdua2x4kh6eefndnneg6ever6doztccko4taky3b6k at ezqikwh2ooe7>
Reply-To:

On 6.13-rc1, I'm now seeing a ton of test failures due to this warning -
what gives?

00104 ========= TEST   generic/017
00104        run fstests generic/017 at 2024-12-05 11:47:43
00104 spectre-v4 mitigation disabled by command-line option
00106 bcachefs (vdc): starting version 1.13: inode_has_child_snapshots
00106 bcachefs (vdc): initializing new filesystem
00106 bcachefs (vdc): going read-write
00106 bcachefs (vdc): marking superblocks
00106 bcachefs (vdc): initializing freespace
00106 bcachefs (vdc): done initializing freespace
00106 bcachefs (vdc): reading snapshots table
00106 bcachefs (vdc): reading snapshots done
00106 bcachefs (vdc): done starting filesystem
00200 ------------[ cut here ]------------
00200 WARNING: CPU: 8 PID: 12571 at arch/arm64/kernel/stacktrace.c:223 arch_stack_walk+0x2c0/0x388
00200 Modules linked in:
00200 CPU: 8 UID: 0 PID: 12571 Comm: cat Not tainted 6.13.0-rc1-ktest-gdf1fce23d033 #10877
00200 Hardware name: linux,dummy-virt (DT)
00200 pstate: 80001005 (Nzcv daif -PAN -UAO -TCO -DIT +SSBS BTYPE=--)
00200 pc : arch_stack_walk+0x2c0/0x388
00200 lr : arch_stack_walk+0x1f4/0x388
00200 sp : ffffff80ca757b00
00200 x29: ffffff80ca757b00 x28: ffffff80d6783758 x27: 000000000000036f
00200 x26: ffffff80d6783780 x25: ffffff80c19de180 x24: ffffff80c273ee40
00200 x23: ffffffc080022708 x22: ffffffc080025828 x21: ffffff80ca757be8
00200 x20: ffffffc0800c98c8 x19: ffffff80d8533d10 x18: ffffffffffffffff
00200 x17: 0000000000000000 x16: 0000000000000000 x15: ffffffffffffffff
00200 x14: 0000000000000000 x13: ffffff80d6c92000 x12: 0000000000000000
00200 x11: 0000000000000000 x10: 000000000000000a x9 : ffffffc08086beec
00200 x8 : ffffff80ca757bc0 x7 : 0000000000000000 x6 : ffffff80d8533d28
00200 x5 : ffffff80ca757b60 x4 : ffffff80d8534000 x3 : ffffff80ca757b40
00200 x2 : 0000000000000018 x1 : ffffff80d8533d10 x0 : 0000000000000000
00200 Call trace:
00200  arch_stack_walk+0x2c0/0x388 (P)
00200  arch_stack_walk+0x1f4/0x388 (L)
00200  stack_trace_save_tsk+0x90/0xd8
00200  bch2_save_backtrace+0x68/0x160
00200  bch2_prt_task_backtrace+0x30/0xb8
00200  bch2_btree_transactions_read+0xe0/0x1f0
00200  full_proxy_read+0x60/0xd0
00200  vfs_read+0x80/0x2d8
00200  ksys_read+0x5c/0xf0
00200  __arm64_sys_read+0x20/0x30
00200  invoke_syscall.constprop.0+0x54/0xe8
00200  do_el0_svc+0x44/0xc8
00200  el0_svc+0x18/0x58
00200  el0t_64_sync_handler+0x104/0x130
00200  el0t_64_sync+0x154/0x158
00200 ---[ end trace 0000000000000000 ]---
00233 hrtimer: interrupt took 49506640 ns
00493 bcachefs (vdb): shutting down
00493 bcachefs (vdb): going read-only
00493 bcachefs (vdb): finished waiting for writes to stop
00493 bcachefs (vdb): flushing journal and stopping allocators, journal seq 18
00493 bcachefs (vdb): flushing journal and stopping allocators complete, journal seq 18
00493 bcachefs (vdb): clean shutdown complete, journal seq 19
00493 bcachefs (vdb): marking filesystem clean
00493 bcachefs (vdb): shutdown complete
00493 bcachefs (vdc): shutting down
00493 bcachefs (vdc): going read-only
00493 bcachefs (vdc): finished waiting for writes to stop
00493 bcachefs (vdc): flushing journal and stopping allocators, journal seq 41457
00493 bcachefs (vdc): flushing journal and stopping allocators complete, journal seq 41459
00493 bcachefs (vdc): clean shutdown complete, journal seq 41460
00493 bcachefs (vdc): marking filesystem clean
00493 bcachefs (vdc): shutdown complete
00495 bcachefs (vdc): starting version 1.13: inode_has_child_snapshots
00495 bcachefs (vdc): recovering from clean shutdown, journal seq 41460
00495 bcachefs (vdc): accounting_read... done
00495 bcachefs (vdc): alloc_read... done
00495 bcachefs (vdc): stripes_read... done
00495 bcachefs (vdc): snapshots_read... done
00495 bcachefs (vdc): going read-write
00495 bcachefs (vdc): journal_replay... done
00495 bcachefs (vdc): resume_logged_ops... done
00495 bcachefs (vdc): delete_dead_inodes... done
00495 bcachefs (vdc): done starting filesystem
00495 bcachefs (vdc): shutting down
00495 bcachefs (vdc): going read-only
00495 bcachefs (vdc): finished waiting for writes to stop
00495 bcachefs (vdc): flushing journal and stopping allocators, journal seq 41460
00495 bcachefs (vdc): flushing journal and stopping allocators complete, journal seq 41460
00495 bcachefs (vdc): clean shutdown complete, journal seq 41461
00495 bcachefs (vdc): marking filesystem clean
00495 bcachefs (vdc): shutdown complete
00495 _check_dmesg: something found in dmesg (see /ktest-out/xfstests/generic/017.dmesg)
00496 
00496 /ktest-out/xfstests/generic/017.full:
00496 cat: /ktest-out/xfstests/generic/017.full: No such file or directory
00496 ========= FAILED generic/017 in 391s, exit status 0



From sebastian.reichel at collabora.com  Thu Dec  5 10:04:32 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Thu, 5 Dec 2024 19:04:32 +0100
Subject: [PATCH v1 04/10] phy: phy-rockchip-samsung-hdptx: Add support
 for eDP mode
In-Reply-To: <42035ebe-09b7-4005-912a-8ec72d5dabcc@rock-chips.com>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <2131853.KlZ2vcFHjT@diego>
 <6e1f35c0-5ea8-414f-b3ea-4e7222c605ef@rock-chips.com>
 <2886747.Y6S9NjorxK@diego>
 <h4giob7bcrh7qmtepti6huym2llw4ujfmeff76vrgpahb5zy6x@dz6zghsifww5>
 <2342f342-672c-447e-90d8-674b748af6a4@rock-chips.com>
 <abzu2chif2g3urxoqbm3gbe6cciexbmqvn44qezrx4hgllfkkn@7bzi5jl3stqe>
 <42035ebe-09b7-4005-912a-8ec72d5dabcc@rock-chips.com>
Message-ID: <5ncdog66jtc4s7vxk2yt4jkknf2es3whvweuqmrxbot3azi5ge@t6s3xadkiasp>

Hello Damon,

On Thu, Dec 05, 2024 at 09:13:33AM +0800, Damon Ding wrote:
> Firstly, the term "the HDMI and eDP dynamic switching" can be somewhat
> misleading, because the eDP usually does not support hot plug. The RK3588
> eDP is often used as DP, and it actually supports DP 1.2. Therefore, it is
> better to use the "the HDMI and DP dynamic switching" description.

The part unclear to me is how the dynamic switching is supposed to
happen. Looking at the TRM the hotplug detect signals also seem to be
shared between HDMI and eDP. Can the RK3588S EVB distinguish if HDMI
or eDP has been plugged, or does this require some user interaction
to set the right mode?

> Indeed, the devm_phy_get(dp->dev, "dp") and devm_of_phy_get_by_index() will
> help to get the phy reference in .probe() or .bind().
> 
> However, the phy_set_mode() may be still needed in the HDMI and DP dynamic
> switching application scenarios. We need the enum phy_mode
> PHY_MODE_DP/PHY_MODE_HDMI to differentiate the configuration processes in
> .power_on(), .power_off() and .configure() of struct phy_ops, which will be
> called in conjunction with plugging in and unplugging an HDMI or DP cable.

I suppose you could fetch the PHY in power_on() and release it in
power_off(). But using phy_set_mode() might indeed be better here.

-- 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/20241205/35661371/attachment.sig>

From kent.overstreet at linux.dev  Thu Dec  5 10:04:59 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Thu, 5 Dec 2024 13:04:59 -0500
Subject: arm64: stacktrace: unwind exception boundaries
In-Reply-To: <36kx57aw46vwykgckr5cm4fafhw54tjuj4cqljrdnpfwvjl7if@a7znuhpfu54o>
References: <36kx57aw46vwykgckr5cm4fafhw54tjuj4cqljrdnpfwvjl7if@a7znuhpfu54o>
Message-ID: <zbwbgkuvvciezpmigcp6gaahfxwm7cwhpzus7gtbfnbzsjb2n3@kfbdppbd74o4>

On 6.13-rc1, I'm now seeing a ton of test failures due to this warning -
what gives?

00104 ========= TEST   generic/017
00104        run fstests generic/017 at 2024-12-05 11:47:43
00104 spectre-v4 mitigation disabled by command-line option
00106 bcachefs (vdc): starting version 1.13: inode_has_child_snapshots
00106 bcachefs (vdc): initializing new filesystem
00106 bcachefs (vdc): going read-write
00106 bcachefs (vdc): marking superblocks
00106 bcachefs (vdc): initializing freespace
00106 bcachefs (vdc): done initializing freespace
00106 bcachefs (vdc): reading snapshots table
00106 bcachefs (vdc): reading snapshots done
00106 bcachefs (vdc): done starting filesystem
00200 ------------[ cut here ]------------
00200 WARNING: CPU: 8 PID: 12571 at arch/arm64/kernel/stacktrace.c:223 arch_stack_walk+0x2c0/0x388
00200 Modules linked in:
00200 CPU: 8 UID: 0 PID: 12571 Comm: cat Not tainted 6.13.0-rc1-ktest-gdf1fce23d033 #10877
00200 Hardware name: linux,dummy-virt (DT)
00200 pstate: 80001005 (Nzcv daif -PAN -UAO -TCO -DIT +SSBS BTYPE=--)
00200 pc : arch_stack_walk+0x2c0/0x388
00200 lr : arch_stack_walk+0x1f4/0x388
00200 sp : ffffff80ca757b00
00200 x29: ffffff80ca757b00 x28: ffffff80d6783758 x27: 000000000000036f
00200 x26: ffffff80d6783780 x25: ffffff80c19de180 x24: ffffff80c273ee40
00200 x23: ffffffc080022708 x22: ffffffc080025828 x21: ffffff80ca757be8
00200 x20: ffffffc0800c98c8 x19: ffffff80d8533d10 x18: ffffffffffffffff
00200 x17: 0000000000000000 x16: 0000000000000000 x15: ffffffffffffffff
00200 x14: 0000000000000000 x13: ffffff80d6c92000 x12: 0000000000000000
00200 x11: 0000000000000000 x10: 000000000000000a x9 : ffffffc08086beec
00200 x8 : ffffff80ca757bc0 x7 : 0000000000000000 x6 : ffffff80d8533d28
00200 x5 : ffffff80ca757b60 x4 : ffffff80d8534000 x3 : ffffff80ca757b40
00200 x2 : 0000000000000018 x1 : ffffff80d8533d10 x0 : 0000000000000000
00200 Call trace:
00200  arch_stack_walk+0x2c0/0x388 (P)
00200  arch_stack_walk+0x1f4/0x388 (L)
00200  stack_trace_save_tsk+0x90/0xd8
00200  bch2_save_backtrace+0x68/0x160
00200  bch2_prt_task_backtrace+0x30/0xb8
00200  bch2_btree_transactions_read+0xe0/0x1f0
00200  full_proxy_read+0x60/0xd0
00200  vfs_read+0x80/0x2d8
00200  ksys_read+0x5c/0xf0
00200  __arm64_sys_read+0x20/0x30
00200  invoke_syscall.constprop.0+0x54/0xe8
00200  do_el0_svc+0x44/0xc8
00200  el0_svc+0x18/0x58
00200  el0t_64_sync_handler+0x104/0x130
00200  el0t_64_sync+0x154/0x158
00200 ---[ end trace 0000000000000000 ]---
00233 hrtimer: interrupt took 49506640 ns
00493 bcachefs (vdb): shutting down
00493 bcachefs (vdb): going read-only
00493 bcachefs (vdb): finished waiting for writes to stop
00493 bcachefs (vdb): flushing journal and stopping allocators, journal seq 18
00493 bcachefs (vdb): flushing journal and stopping allocators complete, journal seq 18
00493 bcachefs (vdb): clean shutdown complete, journal seq 19
00493 bcachefs (vdb): marking filesystem clean
00493 bcachefs (vdb): shutdown complete
00493 bcachefs (vdc): shutting down
00493 bcachefs (vdc): going read-only
00493 bcachefs (vdc): finished waiting for writes to stop
00493 bcachefs (vdc): flushing journal and stopping allocators, journal seq 41457
00493 bcachefs (vdc): flushing journal and stopping allocators complete, journal seq 41459
00493 bcachefs (vdc): clean shutdown complete, journal seq 41460
00493 bcachefs (vdc): marking filesystem clean
00493 bcachefs (vdc): shutdown complete
00495 bcachefs (vdc): starting version 1.13: inode_has_child_snapshots
00495 bcachefs (vdc): recovering from clean shutdown, journal seq 41460
00495 bcachefs (vdc): accounting_read... done
00495 bcachefs (vdc): alloc_read... done
00495 bcachefs (vdc): stripes_read... done
00495 bcachefs (vdc): snapshots_read... done
00495 bcachefs (vdc): going read-write
00495 bcachefs (vdc): journal_replay... done
00495 bcachefs (vdc): resume_logged_ops... done
00495 bcachefs (vdc): delete_dead_inodes... done
00495 bcachefs (vdc): done starting filesystem
00495 bcachefs (vdc): shutting down
00495 bcachefs (vdc): going read-only
00495 bcachefs (vdc): finished waiting for writes to stop
00495 bcachefs (vdc): flushing journal and stopping allocators, journal seq 41460
00495 bcachefs (vdc): flushing journal and stopping allocators complete, journal seq 41460
00495 bcachefs (vdc): clean shutdown complete, journal seq 41461
00495 bcachefs (vdc): marking filesystem clean
00495 bcachefs (vdc): shutdown complete
00495 _check_dmesg: something found in dmesg (see /ktest-out/xfstests/generic/017.dmesg)
00496 
00496 /ktest-out/xfstests/generic/017.full:
00496 cat: /ktest-out/xfstests/generic/017.full: No such file or directory
00496 ========= FAILED generic/017 in 391s, exit status 0



From tglx at linutronix.de  Thu Dec  5 10:05:13 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Thu, 05 Dec 2024 19:05:13 +0100
Subject: [PATCH v10 3/7] PCI: endpoint: pci-ep-msi: Add MSI address/data
 pair mutable check
In-Reply-To: <Z1G/CwFvO/aBLBe8@lizhi-Precision-Tower-5810>
References: <20241204-ep-msi-v10-0-87c378dbcd6d@nxp.com>
 <20241204-ep-msi-v10-3-87c378dbcd6d@nxp.com> <87ttbiqnq8.ffs@tglx>
 <Z1G/CwFvO/aBLBe8@lizhi-Precision-Tower-5810>
Message-ID: <87ldwuqa3q.ffs@tglx>

On Thu, Dec 05 2024 at 09:56, Frank Li wrote:
> On Thu, Dec 05, 2024 at 02:10:55PM +0100, Thomas Gleixner wrote:
>> You want a MSI_FLAG_MSG_IMMUTABLE and set that on the domains which
>> provide it. That way you ensure that someone looked at the domain to
>> validate it.
>
> Okay, at beginning I think most MSI controller is immutable. So I use
> MSI_FLAG_MSG_MUTABLE.

If you want to do that then _you_ have to go through every single
interrupt controllers, validate and opt-out in case it does change the
message. Otherwise that flag is completely pointless.

Instead of adding the IMMUTABLE flag for one controller you know and
then let others who want to utilize this amend their controllers.

Opt-in is less work and more safe than opt-out. See?

Thanks,

        tglx


From tudor.ambarus at linaro.org  Thu Dec  5 10:01:56 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 18:01:56 +0000
Subject: [PATCH 0/4] arm64: exynos: gs101: add ACPM related nodes 
Message-ID: <20241205180200.203146-1-tudor.ambarus@linaro.org>

Define SRAM, mailbox and ACPM protocol in device tree.
Enable the mailbox and ACPM protocol in defconfig.

Tudor Ambarus (4):
  arm64: dts: exynos: gs101: add SRAM node
  arm64: dts: exynos: gs101: add AP to APM mailbox node
  arm64: dts: exynos: gs101: add ACPM protocol node
  arm64: defconfig: enable ACPM protocol and exynos mailbox

 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 40 ++++++++++++++++++++
 arch/arm64/configs/defconfig                 |  2 +
 2 files changed, 42 insertions(+)

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec  5 10:01:57 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 18:01:57 +0000
Subject: [PATCH 1/4] arm64: dts: exynos: gs101: add SRAM node
In-Reply-To: <20241205180200.203146-1-tudor.ambarus@linaro.org>
References: <20241205180200.203146-1-tudor.ambarus@linaro.org>
Message-ID: <20241205180200.203146-2-tudor.ambarus@linaro.org>

SRAM is used by the ACPM protocol to retrieve the ACPM channels
information, which includes the TX/RX rings among other channel
configuration data. Add the SRAM node.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 302c5beb224a..1441e9a252c2 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -269,6 +269,14 @@ bldr_log_hist_reserved: bldr-log-hist-reserved at fd900000 {
 		};
 	};
 
+	apm_sram: sram at 2039000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0x2039000 0x40000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x2039000 0x40000>;
+	};
+
 	soc: soc at 0 {
 		compatible = "simple-bus";
 		#address-cells = <1>;
-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec  5 10:01:58 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 18:01:58 +0000
Subject: [PATCH 2/4] arm64: dts: exynos: gs101: add AP to APM mailbox node
In-Reply-To: <20241205180200.203146-1-tudor.ambarus@linaro.org>
References: <20241205180200.203146-1-tudor.ambarus@linaro.org>
Message-ID: <20241205180200.203146-3-tudor.ambarus@linaro.org>

GS101 has 14 mailbox controllers. Add the AP to APM mailbox node.

Mailbox controllers have a shared register that can be used for passing
the mailbox messages. The AP to APM mailbox controller is used just as a
doorbell mechanism. It raises interrupt to the firmware after the mailbox
message has been written to SRAM where the TX/RX rings are defined.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 1441e9a252c2..0970f6fc1ef5 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -1445,6 +1445,15 @@ wakeup-interrupt-controller {
 			};
 		};
 
+		ap2apm_mailbox: mailbox at 17610000 {
+			compatible = "google,gs101-acpm-mbox";
+			reg = <0x17610000 0x1000>;
+			clocks = <&cmu_apm CLK_GOUT_APM_MAILBOX_APM_AP_PCLK>;
+			clock-names = "pclk";
+			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <1>;
+		};
+
 		pinctrl_gsactrl: pinctrl at 17940000 {
 			compatible = "google,gs101-pinctrl";
 			reg = <0x17940000 0x00001000>;
-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec  5 10:01:59 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 18:01:59 +0000
Subject: [PATCH 3/4] arm64: dts: exynos: gs101: add ACPM protocol node
In-Reply-To: <20241205180200.203146-1-tudor.ambarus@linaro.org>
References: <20241205180200.203146-1-tudor.ambarus@linaro.org>
Message-ID: <20241205180200.203146-4-tudor.ambarus@linaro.org>

Add the ACPM protocol node. ACPM protocol provides interface for all
the client drivers making use of the features offered by the
Active Power Management (APM) module.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 23 ++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 0970f6fc1ef5..ed9815194f65 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -277,6 +277,29 @@ apm_sram: sram at 2039000 {
 		ranges = <0x0 0x0 0x2039000 0x40000>;
 	};
 
+	firmware {
+		acpm_ipc: acpm_ipc {
+			compatible = "google,gs101-acpm-ipc";
+			mboxes = <&ap2apm_mailbox 0
+				  &ap2apm_mailbox 1
+				  &ap2apm_mailbox 2
+				  &ap2apm_mailbox 3
+				  &ap2apm_mailbox 4
+				  &ap2apm_mailbox 5
+				  &ap2apm_mailbox 6
+				  &ap2apm_mailbox 7
+				  &ap2apm_mailbox 8
+				  &ap2apm_mailbox 9
+				  &ap2apm_mailbox 10
+				  &ap2apm_mailbox 11
+				  &ap2apm_mailbox 12
+				  &ap2apm_mailbox 13
+				  &ap2apm_mailbox 14>;
+			shmem = <&apm_sram>;
+			initdata-base = <0xa000>;
+		};
+	};
+
 	soc: soc at 0 {
 		compatible = "simple-bus";
 		#address-cells = <1>;
-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec  5 10:02:00 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  5 Dec 2024 18:02:00 +0000
Subject: [PATCH 4/4] arm64: defconfig: enable ACPM protocol and exynos mailbox
In-Reply-To: <20241205180200.203146-1-tudor.ambarus@linaro.org>
References: <20241205180200.203146-1-tudor.ambarus@linaro.org>
Message-ID: <20241205180200.203146-5-tudor.ambarus@linaro.org>

Enable the Samsung Exynos ACPM protocol and its transport layer, the
exynos mailbox driver. Samsung exynos platforms implement ACPM to
provide support for PMIC, clock frequency scaling, clock configuration
and temperature sensors.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..91139b1cf813 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -262,6 +262,7 @@ CONFIG_IMX_SCU=y
 CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
 CONFIG_QCOM_QSEECOM=y
 CONFIG_QCOM_QSEECOM_UEFISECAPP=y
+CONFIG_EXYNOS_ACPM_PROTOCOL=m
 CONFIG_GNSS=m
 CONFIG_GNSS_MTK_SERIAL=m
 CONFIG_MTD=y
@@ -1378,6 +1379,7 @@ CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_TEGRA186_TIMER=y
 CONFIG_RENESAS_OSTM=y
 CONFIG_ARM_MHU=y
+CONFIG_EXYNOS_MBOX=m
 CONFIG_IMX_MBOX=y
 CONFIG_OMAP2PLUS_MBOX=m
 CONFIG_PLATFORM_MHU=y
-- 
2.47.0.338.g60cca15819-goog



From olteanv at gmail.com  Thu Dec  5 10:05:39 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 5 Dec 2024 20:05:39 +0200
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
Message-ID: <20241205180539.6t5iz2m3wjjwyxp3@skbuf>

On Thu, Dec 05, 2024 at 06:17:18PM +0100, Christian Marangi wrote:
> I checked the examples and one problems that comes to me is how to model
> this if only MDIO is used as a comunication method. Ocelot have PCIE or
> SPI but this switch only comunicate with MDIO on his address.

I don't see why this matters. There will be a top-level device driver,
which in this case will be an mdio_driver and will use mdiobus_{read,write}
to physically access registers. This driver will create regmaps and add
them to devres using devm_regmap_init(). From devres, DSA and other child
drivers can use dev_get_regmap(dev->parent) and perform their I/O through
regmap.

This driver is already written for regmap, so part of the work can
already be reused.

> So where should I place the SoC or MFD node? In the switch root node?

The SoC should be placed on the host MDIO bus. And the Ethernet switch
component should be a child of the SoC. Ideally, so should be all other
switch peripherals: on the same level as the Ethernet switch.

> Also the big problem is how to model accessing the register with MDIO
> with an MFD implementation.
> 
> Anyway just to make sure the Switch SoC doesn't expose an actualy MDIO
> bus, that is just to solve the problem with the Switch Address shared
> with one of the port. (Switch Address can be accessed by every switch
> port with a specific page set)

Sorry, I don't understand this, can you explain more? "Switch Address
can be accessed by every switch port with a specific page set"

In the code, I see that the priv->bus and priv->phy_base are used to
perform MDIO accesses for anything related to the switch. That's perfect,
it means that all switch registers are concentrated on a single MDIO
address, behind a single mdio_device. If that weren't the case, things
would get messy, because the Linux device model associates an MDIO device
with a single address on its bus.

And then we have an8855_phy_read() and an8855_phy_write(), which in my
understanding are the ops of a fake MDIO controller, one which has no
registers or MDIO address space of its own, but is just a passthrough
towards the host MDIO bus's address space. I have no idea why you don't
just put a phy-handle from the switch user ports to PHYs located on the
host MDIO bus directly, and why you go through this middle entity, but I
expect you will clarify. Creating an MDIO bus from DSA for internal PHYs
is completely optional if no special handling is required.

To explain again: In the MFD proposal, there is only one driver who has
access to the mdio_device from the host bus: the MFD driver. Depending
on how it implements the regmaps it presents to the children, it can
control page switching, etc etc. The child devices only operate with
regmaps, and have no idea of the underlying hardware access method.

> But yes the problem is there... Function is not implemented but the
> switch have i2c interface, minimal CPU, GPIO and Timer in it.
> 
> Happy to make the required changes, just very confused on how the final
> DT node structure.
> 
> -- 
> 	Ansuel



From amelie.delaunay at foss.st.com  Thu Dec  5 10:04:39 2024
From: amelie.delaunay at foss.st.com (Amelie Delaunay)
Date: Thu, 5 Dec 2024 19:04:39 +0100
Subject: [PATCH v1] dt-bindings: dma: st-stm32-dmamux: Add description for
 dma-cell values
In-Reply-To: <28d1bb46-ab18-42da-9ca2-ff498c888d66@kernel.org>
References: <CADRqkYAaCYvo3ybGdKO1F_y9jFEcwTBxZzRN-Av-adq_4fVu6g@mail.gmail.com>
 <d53538ea-f846-4a6a-bc14-22ec7ee57e53@kernel.org>
 <CADRqkYDnDNL_H2CzxjsPOdM++iYp-9Ak3PVFBw2qcjR_M=GeBA@mail.gmail.com>
 <28d1bb46-ab18-42da-9ca2-ff498c888d66@kernel.org>
Message-ID: <bdfeceb6-962a-4f20-b76c-4fe5e5ff80c3@foss.st.com>


On 12/5/24 17:09, Krzysztof Kozlowski wrote:
> On 05/12/2024 17:07, Ken Sloat wrote:
>>>> + 1. The mux input number/line for the request
>>>> + 2. Bitfield representing DMA channel configuration that is passed
>>>> + to the real DMA controller
>>>> + 3. Bitfield representing device dependent DMA features passed to
>>>> + the real DMA controller
>>>> +
>>>> + For bitfield definitions of cells 2 and 3, see the associated
>>>> + bindings doc for the actual DMA controller the mux is connected
>>>
>>> This does not sound right. This is the binding for DMA controller, so
>>> you are saying "please look at itself". I suggest to drop this as well.
>>>
>>
>> While logically it is the DMA controller, this doc is specifically for
>> the mux - the DMA controller has its own driver and binding docs in
>> Documentation/devicetree/bindings/dma/stm32/st,stm32-dma.yaml
>>
>> I can reference st,stm32-dma.yaml directly, but I was unsure if this
>> mux IP was used with another DMA controller from ST on a different
>> SoC.
>>
>> What do you suggest here?
> 
> Thanks for explanation, I think it is fine.
> 
> Best regards,
> Krzysztof

This description was lost when STM32 DMAMUX binding txt file was 
converted to yaml:
0b7c446fa9f7 ("dt-bindings: dma: Convert stm32 DMAMUX bindings to 
json-schema")

-- #dma-cells:	Should be set to <3>.
-		First parameter is request line number.
-		Second is DMA channel configuration
-		Third is Fifo threshold
-		For more details about the three cells, please see
-		stm32-dma.txt documentation binding file


stm32-dmamux exclusively muxes stm32-dma channels. It is not used with 
other ST DMA controllers (STM32 MDMA, STM32 DMA3).

So it is fine to refer to st,stm32-dma.yaml.

Regards,
Amelie


From jean-philippe at linaro.org  Thu Dec  5 10:14:04 2024
From: jean-philippe at linaro.org (Jean-Philippe Brucker)
Date: Thu, 5 Dec 2024 18:14:04 +0000
Subject: [PATCH 1/2] iommu/arm-smmu-v3: Document SVA interaction with new
 pagetable features
In-Reply-To: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
Message-ID: <20241205181404.GB664340@myrica>

On Thu, Dec 05, 2024 at 01:48:09PM +0000, Robin Murphy wrote:
> Process pagetables may now be using new permission-indirection-based
> features which an SMMU may not understand when given such a table for
> SVA. Although SMMUv3.4 does add its own S1PIE feature, realistically
> we're still going to have to cope with feature mismatches between CPUs
> and SMMUs, so let's start simple and essentially just document the
> expectations for what falls out as-is. Although it seems unlikely for
> SVA applications to also depend on memory-hardening features, or
> vice-versa,

Hard to predict, but SVA could be indirectly enabled by some common
library: for example a libcrypto plugin that shares the address space with
an accelerator when one is available (see uadk_engine). I'm not familiar
with the POE use-cases, but I guess a common library could also enable
those memory-hardening features, such that unsuspecting applications have
everything enabled.

> the relative lifecycles make it tricky to enforce mutual
> exclusivity. Thankfully our PIE index allocation makes it relatively
> benign for an SMMU to keep interpreting them as direct permissions, the
> only real implication is that an SVA application cannot harden itself
> against its own devices with these features. Thus, inform the user about
> that just in case they have other expectations.
> 
> Also we don't (yet) support LPA2, so deny SVA entirely if we're going to
> misunderstand the pagetable format altogether.
> 
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 15 ++++++++++++++-
>  1 file changed, 14 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 1d3e71569775..9ba596430e7c 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
> @@ -112,6 +112,15 @@ void arm_smmu_make_sva_cd(struct arm_smmu_cd *target,
>  	 * from the current CPU register
>  	 */
>  	target->data[3] = cpu_to_le64(read_sysreg(mair_el1));
> +
> +	/*
> +	 * Note that we don't bother with S1PIE on the SMMU, we just rely on
> +	 * our default encoding scheme matching direct permissions anyway.
> +	 * SMMU has no notion of S1POE nor GCS, so make sure that is clear if
> +	 * either is enabled for CPUs, just in case anyone imagines otherwise.
> +	 */
> +	if (system_supports_poe() || system_supports_gcs())
> +		dev_warn_once(master->smmu->dev, "SVA devices ignore permission overlays and GCS\n");

If POE tightens the page permissions, enabling SVA on top lets the
application easily bypass the POE protection. Could we actually return
false in arm_smmu_sva_supported() instead of displaying a warning that
likely no one will notice?

I guess enforcing !(SVA & POE) on an address space would be too much work?

Thanks,
Jean

>  }
>  EXPORT_SYMBOL_IF_KUNIT(arm_smmu_make_sva_cd);
>  
> @@ -206,8 +215,12 @@ bool arm_smmu_sva_supported(struct arm_smmu_device *smmu)
>  	unsigned long asid_bits;
>  	u32 feat_mask = ARM_SMMU_FEAT_COHERENCY;
>  
> -	if (vabits_actual == 52)
> +	if (vabits_actual == 52) {
> +		/* We don't support LPA2 */
> +		if (PAGE_SIZE != SZ_64K)
> +			return false;
>  		feat_mask |= ARM_SMMU_FEAT_VAX;
> +	}
>  
>  	if ((smmu->features & feat_mask) != feat_mask)
>  		return false;
> -- 
> 2.39.2.101.g768bb238c484.dirty
> 


From darren at os.amperecomputing.com  Thu Dec  5 03:50:36 2024
From: darren at os.amperecomputing.com (Darren Hart)
Date: Thu, 5 Dec 2024 03:50:36 -0800
Subject: [PATCH v3 00/16] KVM: arm64: nv: Shadow stage-2 page table
 handling
In-Reply-To: <871pz2th4b.wl-maz@kernel.org>
References: <20240614144552.2773592-1-maz@kernel.org>
 <171878647493.242213.9111337124987897859.b4-ty@linux.dev>
 <46bea470-3a3b-4dcc-b4a8-a74830c66774@os.amperecomputing.com>
 <86plmov8n3.wl-maz@kernel.org>
 <38339ef8-6e69-43b5-8d16-b7fd66775c93@os.amperecomputing.com>
 <86o727um28.wl-maz@kernel.org>
 <871pz2th4b.wl-maz@kernel.org>
Message-ID: <Z1GTjN3Ba0x1iKj9@Fedora>

On Sat, Nov 23, 2024 at 09:49:08AM +0000, Marc Zyngier wrote:
> On Fri, 22 Nov 2024 19:04:47 +0000,
> Marc Zyngier <maz at kernel.org> wrote:
> > 
> > On Fri, 22 Nov 2024 16:54:16 +0000,
> > Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> > > 
> > > 
> > > 
> > > On 21-11-2024 10:14 pm, Marc Zyngier wrote:
> > > > On Thu, 21 Nov 2024 08:11:00 +0000,
> > > > Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> > > > 
> > > > Hi Ganapatrao,
> > > > 
> > > >> IIRC, Most of the patches that are specific to NV have been merged
> > > >> upstream. However I do see that, some of the vGIC and Timer related
> > > >> patches are still in your private NV repository. Can these patches be
> > > >> prioritized to upstream, so that we can have have the first working
> > > >> version of NV on mainline.
> > > > 
> > > > Who is *we*?
> > > > 
> > > > Things get upstreamed when we (people doing the actual work) decide
> > > > they are ready. At the moment, they are not.
> > > > 
> > > > Also, while I enjoy working on NV, this isn't *my* priority.
> > > 
> > > Sure, I understand that it's not your priority right now.  I'm happy
> > > to spend some time on it, please do let us know in what areas/patches
> > > needs attention before the code would be ready to merge?
> > 
> > Please understand that NV isn't special, and while there is still a
> > bunch of things that need to be merged, it is the whole of KVM/arm64
> > that needs attention.
> > 
> > For example, there is the debug series from Oliver, the feature
> > handling from Fuad. They may not have NV written all over them, but
> > they do have an impact on the NV behaviour one way or another.
> > 
> > By paying attention to these series, you would help with the
> > groundwork that is required before we can actually enable NV. This is
> > what matters now, not the next 50 or so NV-specific patches.
> 
> And one last thing, while I think of it: NV is very unlikely to get
> merged without a testing infrastructure. Which means that the current
> selftests must run at EL2, and that *new* selftests must be created to
> test the NV implementation (all the trap behaviours, for example).
> 
> So if you (and I assume your employer, as you keep using the plural)
> want to help moving NV support upstream, this is an area where you
> could help and make a massive difference.

Appreciate the specific examples Marc, thank you. I'll work with my team
at Ampere in this direction - specifically the testing infrastructure
work and engaging in the NV-adjacent kvm patche series.

-- 
Darren Hart
Ampere Computing / Linux Enabling


From quic_molvera at quicinc.com  Thu Dec  5 10:21:31 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Thu, 5 Dec 2024 10:21:31 -0800
Subject: [PATCH v3 6/7] arm64: dts: qcom: Add board dts files for SM8750
 MTP and QRD
In-Reply-To: <b9225284-7830-4aa4-aed2-7f58fb7320e8@oss.qualcomm.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
 <20241204-sm8750_master_dt-v3-6-4d5a8269950b@quicinc.com>
 <b9225284-7830-4aa4-aed2-7f58fb7320e8@oss.qualcomm.com>
Message-ID: <79e55e6e-e560-4f43-8d6e-bbaf7fcf157a@quicinc.com>



On 12/5/2024 8:45 AM, Konrad Dybcio wrote:
> On 5.12.2024 12:18 AM, Melody Olvera wrote:
>> Add MTP and QRD dts files for SM8750 describing board clocks, regulators,
>> gpio keys, etc.
>>
>> Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
>> ---
> [...]
>
> Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>
>> +&tlmm {
>> +	/* reserved for secure world */
>> +	gpio-reserved-ranges = <36 4>, <74 1>;
>> +};
> Any chance you could describe what those specifically are?
>

I'm not too certain, and even if I was, I'm not certain I'd be at 
liberty to say.

Thanks,
Melody


From catalin.marinas at arm.com  Thu Dec  5 10:22:17 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu,  5 Dec 2024 18:22:17 +0000
Subject: [PATCH] arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs
In-Reply-To: <20241203151941.353796-1-catalin.marinas@arm.com>
References: <20241203151941.353796-1-catalin.marinas@arm.com>
Message-ID: <173342292873.1735998.10553787213604000003.b4-ty@arm.com>

On Tue, 03 Dec 2024 15:19:41 +0000, Catalin Marinas wrote:
> Linux currently sets the TCR_EL1.AS bit unconditionally during CPU
> bring-up. On an 8-bit ASID CPU, this is RES0 and ignored, otherwise
> 16-bit ASIDs are enabled. However, if running in a VM and the hypervisor
> reports 8-bit ASIDs (ID_AA64MMFR0_EL1.ASIDBits == 0) on a 16-bit ASIDs
> CPU, Linux uses bits 8 to 63 as a generation number for tracking old
> process ASIDs. The bottom 8 bits of this generation end up being written
> to TTBR1_EL1 and also used for the ASID-based TLBI operations as the
> upper 8 bits of the ASID. Following an ASID roll-over event we can have
> threads of the same application with the same 8-bit ASID but different
> generation numbers running on separate CPUs. Both TLB caching and the
> TLBI operations will end up using different actual 16-bit ASIDs for the
> same process.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs
      https://git.kernel.org/arm64/c/c0900d15d31c

-- 
Catalin



From catalin.marinas at arm.com  Thu Dec  5 10:23:36 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu,  5 Dec 2024 18:23:36 +0000
Subject: (subset) [PATCH 1/2] iommu/arm-smmu-v3: Document SVA interaction with new pagetable features
In-Reply-To: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
Message-ID: <173342292875.1735998.11342538299837592943.b4-ty@arm.com>

On Thu, 05 Dec 2024 13:48:09 +0000, Robin Murphy wrote:
> Process pagetables may now be using new permission-indirection-based
> features which an SMMU may not understand when given such a table for
> SVA. Although SMMUv3.4 does add its own S1PIE feature, realistically
> we're still going to have to cope with feature mismatches between CPUs
> and SMMUs, so let's start simple and essentially just document the
> expectations for what falls out as-is. Although it seems unlikely for
> SVA applications to also depend on memory-hardening features, or
> vice-versa, the relative lifecycles make it tricky to enforce mutual
> exclusivity. Thankfully our PIE index allocation makes it relatively
> benign for an SMMU to keep interpreting them as direct permissions, the
> only real implication is that an SVA application cannot harden itself
> against its own devices with these features. Thus, inform the user about
> that just in case they have other expectations.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[2/2] arm64: cpufeature: Add GCS to cpucap_is_possible()
      https://git.kernel.org/arm64/c/f00b53f1614f

-- 
Catalin



From catalin.marinas at arm.com  Thu Dec  5 10:23:54 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu,  5 Dec 2024 18:23:54 +0000
Subject: [PATCH] coco: virt: arm64: Do not enable cca guest driver by default
In-Reply-To: <20241205143634.306114-1-suzuki.poulose@arm.com>
References: <20241205143634.306114-1-suzuki.poulose@arm.com>
Message-ID: <173342292874.1735998.14336440611825426443.b4-ty@arm.com>

On Thu, 05 Dec 2024 14:36:34 +0000, Suzuki K Poulose wrote:
> As per the guidelines, new drivers may not be set to default on.
> An expert user can always select it.
> 
> 

Applied to arm64 (for-next/fixes), thanks!

[1/1] coco: virt: arm64: Do not enable cca guest driver by default
      https://git.kernel.org/arm64/c/16d5306629c0

-- 
Catalin



From catalin.marinas at arm.com  Thu Dec  5 10:24:10 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu,  5 Dec 2024 18:24:10 +0000
Subject: [PATCH v2] ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A
In-Reply-To: <20241205013331.1484017-1-xiaqinxin@huawei.com>
References: <20241205013331.1484017-1-xiaqinxin@huawei.com>
Message-ID: <173342292873.1735998.12216158136590332848.b4-ty@arm.com>

On Thu, 05 Dec 2024 09:33:31 +0800, Qinxin Xia wrote:
> HiSilicon HIP09A platforms using the same SMMU PMCG with HIP09
> and thus suffers the same erratum. List them in the PMCG platform
> information list without introducing a new SMMU PMCG Model.
> 
> Update the silicon-errata.rst as well.
> 
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A
      https://git.kernel.org/arm64/c/c2b46ae02270

-- 
Catalin



From catalin.marinas at arm.com  Thu Dec  5 10:23:00 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu,  5 Dec 2024 18:23:00 +0000
Subject: [PATCH] arm64: mte: Fix copy_highpage() warning on hugetlb folios
In-Reply-To: <20241204175004.906754-1-catalin.marinas@arm.com>
References: <20241204175004.906754-1-catalin.marinas@arm.com>
Message-ID: <173342292874.1735998.297921244309986411.b4-ty@arm.com>

On Wed, 04 Dec 2024 17:50:04 +0000, Catalin Marinas wrote:
> Commit 25c17c4b55de ("hugetlb: arm64: add mte support") improved the
> copy_highpage() function to update the tags in the destination hugetlb
> folio. However, when the source folio isn't tagged, the code takes the
> non-hugetlb path where try_page_mte_tagging() warns as the destination
> is a hugetlb folio:
> 
>   WARNING: CPU: 0 PID: 363 at arch/arm64/include/asm/mte.h:58 copy_highpage+0x1d4/0x2d8
>   [...]
>   pc : copy_highpage+0x1d4/0x2d8
>   lr : copy_highpage+0x78/0x2d8
>   [...]
>   Call trace:
>    copy_highpage+0x1d4/0x2d8 (P)
>    copy_highpage+0x78/0x2d8 (L)
>    copy_user_highpage+0x20/0x48
>    copy_user_large_folio+0x1bc/0x268
>    hugetlb_wp+0x190/0x860
>    hugetlb_fault+0xa28/0xc10
>    handle_mm_fault+0x2a0/0x2c0
>    do_page_fault+0x12c/0x578
>    do_mem_abort+0x4c/0xa8
>    el0_da+0x44/0xb0
>    el0t_64_sync_handler+0xc4/0x138
>    el0t_64_sync+0x198/0x1a0
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: mte: Fix copy_highpage() warning on hugetlb folios
      https://git.kernel.org/arm64/c/cf3b16dae4ca

-- 
Catalin



From catalin.marinas at arm.com  Thu Dec  5 10:23:09 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu,  5 Dec 2024 18:23:09 +0000
Subject: [PATCH 0/4] arm64: ptrace: fix handling of partial SETREGSET calls
In-Reply-To: <20241205121655.1824269-1-mark.rutland@arm.com>
References: <20241205121655.1824269-1-mark.rutland@arm.com>
Message-ID: <173342292875.1735998.10087174638613515208.b4-ty@arm.com>

On Thu, 05 Dec 2024 12:16:51 +0000, Mark Rutland wrote:
> A few of arm64's regsets forget to handle partial-length SETREGSET
> calls, and copy a small portion of uninitialized kernel stack memory to
> the backing storage of the relevant registers. In all cases the read is
> limited to a specific slot on the stack, and the issue does not provide
> a write mechanism.
> 
> For example, a zero-length SETREGSET to NT_ARM_FPMR will reset FPMR to
> an arbitrary uninitialized value from the kernel stack:
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/4] arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL
      https://git.kernel.org/arm64/c/ca62d90085f4
[2/4] arm64: ptrace: fix partial SETREGSET for NT_ARM_FPMR
      https://git.kernel.org/arm64/c/f5d71291841a
[3/4] arm64: ptrace: fix partial SETREGSET for NT_ARM_POE
      https://git.kernel.org/arm64/c/594bfc4947c4
[4/4] arm64: ptrace: fix partial SETREGSET for NT_ARM_GCS
      https://git.kernel.org/arm64/c/d60624f72d15

-- 
Catalin



From nicolas at ndufresne.ca  Thu Dec  5 10:26:22 2024
From: nicolas at ndufresne.ca (Nicolas Dufresne)
Date: Thu, 05 Dec 2024 13:26:22 -0500
Subject: [PATCH] media: allegro-dvt: Moving the current driver to
 subdirectory
In-Reply-To: <Z1FrT3gBWE5VgMOS@pengutronix.de>
References: <20241202102654.40472-1-yassine.ouaissa@allegrodvt.com>
	 <Z02SLI05JhNDtXFn@pengutronix.de>
	 <abshbp4blqxasxvf4ibumtfqcr7hytehmhzs2yag3nfpbcl47x@ndjg7al4iysk>
	 <Z1CC_PQF8hCzmPoQ@pengutronix.de>
	 <46tabetrggwplddtssags6eyjcd6x7znaquerjg3z5a63ykle4@z5fqzikwv2o4>
	 <Z1FrT3gBWE5VgMOS@pengutronix.de>
Message-ID: <cf7b66d0671e223263a7d33b6e519850a5ff2fb5.camel@ndufresne.ca>

Hi Yassine,

Le jeudi 05 d?cembre 2024 ? 09:58 +0100, Michael Tretter a ?crit?:
> Hi Yassine,
> 
> On Thu, 05 Dec 2024 08:11:48 +0000, Yassine Ouaissa wrote:
> > On 04.12.2024 17:27, Michael Tretter wrote:
> > > On Wed, 04 Dec 2024 14:44:31 +0000, Yassine Ouaissa wrote:
> > > > On 02.12.2024 11:55, Michael Tretter wrote:
> > > > > On Mon, 02 Dec 2024 11:26:38 +0100, Yassine Ouaissa wrote:
> > > > > What kind of conflicts do you encounter or expect? It's kind of
> > > > > surprising that your driver would conflict with anything in the existing
> > > > > driver.
> > > > 
> > > > The current "NOT allegro" driver support only the ZynqMP (ex : ZCU106/ZCU104 ).
> > > > And the upcoming driver, has support for many platforms.
> > > 
> > > What are the supported platforms of the new driver? Does your driver
> > > support ZynqMP, too?
> > > 
> > The upcoming driver is not using the ZynqMP, it can be used by other
> > clients including Xilinx.
> > > If there are enough similarities between the encoders, I'd happily
> > > replace parts of the current driver with functionality of the upcoming
> > > driver or reuse the infrastructure of the new driver.
> > > 
> > 
> > For now, we do have only the decoder (stateful). the encoder is "in
> > progress". We prefer to have a separate driver core for each platform.
> 
> Thanks! I'd like to wait until I've seen your patches before agreeing to
> move the driver to a subdirectory. Maybe even include this patch as the
> first patch in your series to give a full picture of the new structure.

I wonder if both you have the same definition of "platform". For me it sounded
like "a driver per SoC" and that is a big no no.

For stateful codec, what differentiate them is the interface with the firmware
and state machine used to driver them. If these are incompatible with the
generation of design on ZynqMP 104/106, then splitting the driver is the way to
go, even if the new interface could endup on older SoC through a firmware
update.

This is pretty much the direction taken by Qualcomm while moving from Venus
interface to Iris interface, and on some SoC (platform), this is just a firmware
swap and different compatible in the DT.

Nicolas

p.s. Yassine, its fine to state that your driver will be "pre-sillicon" tested,
that helps remove the confusion. Looking forward seeing some code of course,
that will also help, from there, Michael will better judge if there is an
overlap or not. Mid-ground solution exist, like creating allegro-common.ko.

> 
> Michael
> 
> > > > 
> > > > > I'd like to see how you plan to integrate your driver, what it looks
> > > > > like and what conflicts with the existing driver actually occur. Without
> > > > > that information I don't see the point in moving the driver to a
> > > > > sub-directory.
> > > > 
> > > > The upcoming driver is not using the parsing, conversion inside of the
> > > > driver. Actually the new Gen of ALLEGRO IP does that.
> > > 
> > > Sorry, I don't understand what you mean by parsing and conversion. Do
> > > you mean the mailbox messages or the NAL units?
> > > 
> > > Can you point me to some repository with your upcoming driver? I'd
> > > really like to know what's coming up to have an informed discussion how
> > > to structure the directory.
> > > 
> > > Michael
> > > 
> > 
> > Yassine
> > > > > > 
> > > > > > Signed-off-by: Yassine Ouaissa <yassine.ouaissa at allegrodvt.com>
> > > > > > ---
> > > > > >  MAINTAINERS                                               | 2 +-
> > > > > >  drivers/media/platform/allegro-dvt/Kconfig                | 4 ++--
> > > > > >  drivers/media/platform/allegro-dvt/Makefile               | 8 ++------
> > > > > >  drivers/media/platform/allegro-dvt/zynqmp/Makefile        | 6 ++++++
> > > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c    | 0
> > > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h    | 0
> > > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c    | 0
> > > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h    | 0
> > > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c    | 0
> > > > > >  .../media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h    | 0
> > > > > >  .../{allegro-core.c => zynqmp/zynqmp-allegro-core.c}      | 2 +-
> > > > > >  .../{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c}      | 2 +-
> > > > > >  .../{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h}      | 0
> > > > > >  13 files changed, 13 insertions(+), 11 deletions(-)
> > > > > >  create mode 100644 drivers/media/platform/allegro-dvt/zynqmp/Makefile
> > > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.c (100%)
> > > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-h264.h (100%)
> > > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.c (100%)
> > > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-hevc.h (100%)
> > > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.c (100%)
> > > > > >  rename drivers/media/platform/allegro-dvt/{ => zynqmp}/nal-rbsp.h (100%)
> > > > > >  rename drivers/media/platform/allegro-dvt/{allegro-core.c => zynqmp/zynqmp-allegro-core.c} (99%)
> > > > > >  rename drivers/media/platform/allegro-dvt/{allegro-mail.c => zynqmp/zynqmp-allegro-mail.c} (99%)
> > > > > >  rename drivers/media/platform/allegro-dvt/{allegro-mail.h => zynqmp/zynqmp-allegro-mail.h} (100%)
> > > > > > 
> > > > > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > > > > index 7292e4a1ddb8..d79efe6f8992 100644
> > > > > > --- a/MAINTAINERS
> > > > > > +++ b/MAINTAINERS
> > > > > > @@ -795,7 +795,7 @@ R:	Pengutronix Kernel Team <kernel at pengutronix.de>
> > > > > >  L:	linux-media at vger.kernel.org
> > > > > >  S:	Maintained
> > > > > >  F:	Documentation/devicetree/bindings/media/allegro,al5e.yaml
> > > > > > -F:	drivers/media/platform/allegro-dvt/
> > > > > > +F:	drivers/media/platform/allegro-dvt/zynqmp
> > > > > > 
> > > > > >  ALLIED VISION ALVIUM CAMERA DRIVER
> > > > > >  M:	Tommaso Merciai <tomm.merciai at gmail.com>
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/Kconfig b/drivers/media/platform/allegro-dvt/Kconfig
> > > > > > index 2182e1277568..9bc7e99788b8 100644
> > > > > > --- a/drivers/media/platform/allegro-dvt/Kconfig
> > > > > > +++ b/drivers/media/platform/allegro-dvt/Kconfig
> > > > > > @@ -2,8 +2,8 @@
> > > > > > 
> > > > > >  comment "Allegro DVT media platform drivers"
> > > > > > 
> > > > > > -config VIDEO_ALLEGRO_DVT
> > > > > > -	tristate "Allegro DVT Video IP Core"
> > > > > > +config VIDEO_ZYNQMP_ALLEGRO_DVT
> > > > > > +	tristate "Allegro DVT Video IP Core for ZynqMP"
> > > > > >  	depends on V4L_MEM2MEM_DRIVERS
> > > > > >  	depends on VIDEO_DEV
> > > > > >  	depends on ARCH_ZYNQMP || COMPILE_TEST
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/Makefile b/drivers/media/platform/allegro-dvt/Makefile
> > > > > > index 66108a303774..04727c5f7ef4 100644
> > > > > > --- a/drivers/media/platform/allegro-dvt/Makefile
> > > > > > +++ b/drivers/media/platform/allegro-dvt/Makefile
> > > > > > @@ -1,6 +1,2 @@
> > > > > > -# SPDX-License-Identifier: GPL-2.0
> > > > > > -
> > > > > > -allegro-objs := allegro-core.o allegro-mail.o
> > > > > > -allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
> > > > > > -
> > > > > > -obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o
> > > > > > +# SPDX-License-Identifier: GPL-2.0-only
> > > > > > +obj-y += zynqmp/
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/zynqmp/Makefile b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
> > > > > > new file mode 100644
> > > > > > index 000000000000..a8ddb9cf93a8
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/Makefile
> > > > > > @@ -0,0 +1,6 @@
> > > > > > +# SPDX-License-Identifier: GPL-2.0
> > > > > > +
> > > > > > +zynqmp-allegro-objs := zynqmp-allegro-core.o zynqmp-allegro-mail.o
> > > > > > +zynqmp-allegro-objs += nal-rbsp.o nal-h264.o nal-hevc.o
> > > > > > +
> > > > > > +obj-$(CONFIG_VIDEO_ZYNQMP_ALLEGRO_DVT) += zynqmp-allegro.o
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-h264.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
> > > > > > similarity index 100%
> > > > > > rename from drivers/media/platform/allegro-dvt/nal-h264.c
> > > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.c
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-h264.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
> > > > > > similarity index 100%
> > > > > > rename from drivers/media/platform/allegro-dvt/nal-h264.h
> > > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-h264.h
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
> > > > > > similarity index 100%
> > > > > > rename from drivers/media/platform/allegro-dvt/nal-hevc.c
> > > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.c
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
> > > > > > similarity index 100%
> > > > > > rename from drivers/media/platform/allegro-dvt/nal-hevc.h
> > > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-hevc.h
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.c b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
> > > > > > similarity index 100%
> > > > > > rename from drivers/media/platform/allegro-dvt/nal-rbsp.c
> > > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.c
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/nal-rbsp.h b/drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
> > > > > > similarity index 100%
> > > > > > rename from drivers/media/platform/allegro-dvt/nal-rbsp.h
> > > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/nal-rbsp.h
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> > > > > > similarity index 99%
> > > > > > rename from drivers/media/platform/allegro-dvt/allegro-core.c
> > > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> > > > > > index e491399afcc9..8895d7755987 100644
> > > > > > --- a/drivers/media/platform/allegro-dvt/allegro-core.c
> > > > > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-core.c
> > > > > > @@ -31,7 +31,7 @@
> > > > > >  #include <media/videobuf2-dma-contig.h>
> > > > > >  #include <media/videobuf2-v4l2.h>
> > > > > > 
> > > > > > -#include "allegro-mail.h"
> > > > > > +#include "zynqmp-allegro-mail.h"
> > > > > >  #include "nal-h264.h"
> > > > > >  #include "nal-hevc.h"
> > > > > > 
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.c b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> > > > > > similarity index 99%
> > > > > > rename from drivers/media/platform/allegro-dvt/allegro-mail.c
> > > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> > > > > > index aadc947a77ae..88a98f9e5d00 100644
> > > > > > --- a/drivers/media/platform/allegro-dvt/allegro-mail.c
> > > > > > +++ b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.c
> > > > > > @@ -12,7 +12,7 @@
> > > > > >  #include <linux/string.h>
> > > > > >  #include <linux/videodev2.h>
> > > > > > 
> > > > > > -#include "allegro-mail.h"
> > > > > > +#include "zynqmp-allegro-mail.h"
> > > > > > 
> > > > > >  const char *msg_type_name(enum mcu_msg_type type)
> > > > > >  {
> > > > > > diff --git a/drivers/media/platform/allegro-dvt/allegro-mail.h b/drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
> > > > > > similarity index 100%
> > > > > > rename from drivers/media/platform/allegro-dvt/allegro-mail.h
> > > > > > rename to drivers/media/platform/allegro-dvt/zynqmp/zynqmp-allegro-mail.h
> > > > > > --
> > > > > > 2.30.2
> > > > > > 
> > > > > > 
> 



From val at packett.cool  Thu Dec  5 10:29:35 2024
From: val at packett.cool (Val Packett)
Date: Thu,  5 Dec 2024 15:29:35 -0300
Subject: [PATCH v2 1/2] dt-bindings: clock: rk3188-common: add PCLK_CIF0/PCLK_CIF1
Message-ID: <20241205182954.5346-1-val@packett.cool>

Add missing clock IDs for the CIF (Camera InterFace) blocks
on the RK3188/RK3066.

Signed-off-by: Val Packett <val at packett.cool>
---

v2: split dt-bindings into separate patch
    (oops, thought that only applies to actual yaml and not headers)

 include/dt-bindings/clock/rk3188-cru-common.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/dt-bindings/clock/rk3188-cru-common.h b/include/dt-bindings/clock/rk3188-cru-common.h
index 01e14ab252a7..dd988cc9d582 100644
--- a/include/dt-bindings/clock/rk3188-cru-common.h
+++ b/include/dt-bindings/clock/rk3188-cru-common.h
@@ -103,6 +103,8 @@
 #define PCLK_PERI		351
 #define PCLK_DDRUPCTL		352
 #define PCLK_PUBL		353
+#define PCLK_CIF0		354
+#define PCLK_CIF1		355
 
 /* hclk gates */
 #define HCLK_SDMMC		448
-- 
2.47.1



From ansuelsmth at gmail.com  Thu Dec  5 10:29:53 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu, 5 Dec 2024 19:29:53 +0100
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241205180539.6t5iz2m3wjjwyxp3@skbuf>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <20241205180539.6t5iz2m3wjjwyxp3@skbuf>
Message-ID: <6751f125.5d0a0220.255b79.7be0@mx.google.com>

On Thu, Dec 05, 2024 at 08:05:39PM +0200, Vladimir Oltean wrote:
> On Thu, Dec 05, 2024 at 06:17:18PM +0100, Christian Marangi wrote:
> > I checked the examples and one problems that comes to me is how to model
> > this if only MDIO is used as a comunication method. Ocelot have PCIE or
> > SPI but this switch only comunicate with MDIO on his address.
> 
> I don't see why this matters. There will be a top-level device driver,
> which in this case will be an mdio_driver and will use mdiobus_{read,write}
> to physically access registers. This driver will create regmaps and add
> them to devres using devm_regmap_init(). From devres, DSA and other child
> drivers can use dev_get_regmap(dev->parent) and perform their I/O through
> regmap.
> 
> This driver is already written for regmap, so part of the work can
> already be reused.
> 
> > So where should I place the SoC or MFD node? In the switch root node?
> 
> The SoC should be placed on the host MDIO bus. And the Ethernet switch
> component should be a child of the SoC. Ideally, so should be all other
> switch peripherals: on the same level as the Ethernet switch.
>

Ohhhh ok, wasn't clear to me the MFD driver had to be placed in the mdio
node.

To make it clear this would be an implementation.

mdio_bus: mdio-bus {
	#address-cells = <1>;
	#size-cells = <0>;

	...

	mfd at 1 {
		compatible = "airoha,an8855-mfd";
		reg = <1>;

		nvmem_node {
			...
		};

		switch_node {
			...
		};
	};
};

Consider tho that recently I faced some problem with such structure with
DT mainatiners asking to keep everything in the MFD node. But lets see
how it goes.

Well aware of the MFD API, (had to have some fun recently) so the only
confusing part was the node placement.

> > Also the big problem is how to model accessing the register with MDIO
> > with an MFD implementation.
> > 
> > Anyway just to make sure the Switch SoC doesn't expose an actualy MDIO
> > bus, that is just to solve the problem with the Switch Address shared
> > with one of the port. (Switch Address can be accessed by every switch
> > port with a specific page set)
> 
> Sorry, I don't understand this, can you explain more? "Switch Address
> can be accessed by every switch port with a specific page set"
> 
> In the code, I see that the priv->bus and priv->phy_base are used to
> perform MDIO accesses for anything related to the switch. That's perfect,
> it means that all switch registers are concentrated on a single MDIO
> address, behind a single mdio_device. If that weren't the case, things
> would get messy, because the Linux device model associates an MDIO device
> with a single address on its bus.
> 
> And then we have an8855_phy_read() and an8855_phy_write(), which in my
> understanding are the ops of a fake MDIO controller, one which has no
> registers or MDIO address space of its own, but is just a passthrough
> towards the host MDIO bus's address space. I have no idea why you don't
> just put a phy-handle from the switch user ports to PHYs located on the
> host MDIO bus directly, and why you go through this middle entity, but I
> expect you will clarify. Creating an MDIO bus from DSA for internal PHYs
> is completely optional if no special handling is required.

The difficulties I found (and maybe is very easy to solve and I'm
missing something here) is that switch and internal PHY port have the
same address and conflicts.

Switch will be at address 1 (or 2 3 4 5... every port can access switch
register with page 0x4)

DSA port 0 will be at address 1, that is already occupied by the switch.

Defining the DSA port node on the host MDIO bus works correctly for
every port but for port 0 (the one at address 1), the kernel complains
and is not init. (as it does conflict with the switch that is at the
same address) (can't remember the exact warning)

> 
> To explain again: In the MFD proposal, there is only one driver who has
> access to the mdio_device from the host bus: the MFD driver. Depending
> on how it implements the regmaps it presents to the children, it can
> control page switching, etc etc. The child devices only operate with
> regmaps, and have no idea of the underlying hardware access method.
> 
> > But yes the problem is there... Function is not implemented but the
> > switch have i2c interface, minimal CPU, GPIO and Timer in it.
> > 
> > Happy to make the required changes, just very confused on how the final
> > DT node structure.
> > 
> > -- 
> > 	Ansuel
> 

-- 
	Ansuel


From val at packett.cool  Thu Dec  5 10:29:36 2024
From: val at packett.cool (Val Packett)
Date: Thu,  5 Dec 2024 15:29:36 -0300
Subject: [PATCH v2 2/2] clk: rockchip: use PCLK_CIF0/1 clock IDs on RK3066
In-Reply-To: <20241205182954.5346-1-val@packett.cool>
References: <20241205182954.5346-1-val@packett.cool>
Message-ID: <20241205182954.5346-2-val@packett.cool>

RK3066 has two "CIF" video capture interface blocks, reference the
newly added IDs for their PCLK clocks.

Signed-off-by: Val Packett <val at packett.cool>
---
 drivers/clk/rockchip/clk-rk3188.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 684233e72105..81e94b338d0f 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -344,7 +344,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 
 	GATE(0, "pclkin_cif0", "ext_cif0", 0,
 			RK2928_CLKGATE_CON(3), 3, GFLAGS),
-	INVERTER(0, "pclk_cif0", "pclkin_cif0",
+	INVERTER(PCLK_CIF0, "pclk_cif0", "pclkin_cif0",
 			RK2928_CLKSEL_CON(30), 8, IFLAGS),
 
 	FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
@@ -602,7 +602,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 
 	GATE(0, "pclkin_cif1", "ext_cif1", 0,
 			RK2928_CLKGATE_CON(3), 4, GFLAGS),
-	INVERTER(0, "pclk_cif1", "pclkin_cif1",
+	INVERTER(PCLK_CIF1, "pclk_cif1", "pclkin_cif1",
 			RK2928_CLKSEL_CON(30), 12, IFLAGS),
 
 	COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0,
-- 
2.47.1



From olteanv at gmail.com  Thu Dec  5 10:34:03 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 5 Dec 2024 20:34:03 +0200
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <6751e22d.050a0220.3435c6.57de@mx.google.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205170629.ww7qcvgbqdf5ipcj@skbuf>
 <6751e22d.050a0220.3435c6.57de@mx.google.com>
Message-ID: <20241205183403.zla5syfzj3yrinwj@skbuf>

On Thu, Dec 05, 2024 at 06:26:01PM +0100, Christian Marangi wrote:
> Concept looks handy, ideally I can just assign one ID for each port
> like:
> port 1 -> FIB 1
> port 2 -> FIB 1
> port 3 -> FIB 2
> 
> Question:
> Ports of the same bridge should have the same FIB?

The answer, as well as many other explanations, is under the "Address
databases" section of Documentation/networking/dsa/dsa.rst. Please read
it through before starting to implement anything.

> What I need to check is how the switch handle this for learning. Does
> the switch correctly create FDB entry with the right FIB?

You're asking me how an8855 behaves? I have no idea, I never interacted
with it :-|

The idea as far as the DSA API is concerned would be to learn addresses
in the bridge database (DSA_DB_BRIDGE) that the user port is configured
for, and not learn any addresses in the port-private database (DSA_DB_PORT).

> If that's not the case then I think assisted_learning is needed and HW
> Learn can't be used?

ds->assisted_learning_on_cpu_port applies, as suggested by its name,
only on the CPU port. On user ports, address learning should work normally.

As you will find in the documentation, the CPU port is not like a user
port, in the sense that it is not configured to service a single address
database, but all of them. So, source learning on the CPU port will not
work unless the switch knows which address database should each packet
be associated with.

In principle, one way could be to pass, during tagger xmit, the database ID,
so that the switch knows that it must learn the MAC SA of this packet in
this FID. I don't have the full image of the Mediatek DSA tag format,
but if an8855 is anything like mt7530, this option isn't available.
Thus, like mt7530, it needs to set ds->assisted_learning_on_cpu_port, so
that software will call port_fdb_add() on the CPU port with the correct
dsa_db (for the right bridge) as argument. But I don't think that is
going to pose any sort of issue.

> (I still need to check if I can assign a default FIB for a port...
> Currently the STP register are 2 bit for each FIB id, so 16 different
> FIB are possible)
> 
> Also do we have a script for selft tests? I remember there was one back
> in the days for fdb isolation?

I don't remember right now, I don't think we do. I'll try to come up
with something in the following days.


From naresh.kamboju at linaro.org  Thu Dec  5 10:42:03 2024
From: naresh.kamboju at linaro.org (Naresh Kamboju)
Date: Fri, 6 Dec 2024 00:12:03 +0530
Subject: arm64: include/linux/compiler_types.h:542:38: error: call to
 '__compiletime_assert_1050' declared with attribute error: clamp() low limit
 min greater than high limit max_avail
In-Reply-To: <8dde5a62-4ce6-4954-86c9-54d961aed6df@stanley.mountain>
References: <CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g@mail.gmail.com>
 <8dde5a62-4ce6-4954-86c9-54d961aed6df@stanley.mountain>
Message-ID: <CA+G9fYv5gW1gByakU1yyQ__BoAKWkCcg=vGGyNep7+5p9_2uJA@mail.gmail.com>

On Thu, 5 Dec 2024 at 20:46, Dan Carpenter <dan.carpenter at linaro.org> wrote:
>
> Add David to the CC list.

Anders bisected this reported issue and found the first bad commit as,

# first bad commit:
  [ef32b92ac605ba1b7692827330b9c60259f0af49]
  minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()


 - Naresh


From a.fatoum at pengutronix.de  Thu Dec  5 10:49:47 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 5 Dec 2024 19:49:47 +0100
Subject: [PATCH v4] i2c: imx: support DMA defer probing
In-Reply-To: <AM0PR0402MB39370E69BC4B71C761EE8377E8282@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <20241127083818.2108201-1-carlos.song@nxp.com>
 <153e8e36-7b0e-4379-9cc3-6dacb5d705be@pengutronix.de>
 <AM0PR0402MB39370E69BC4B71C761EE8377E8282@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <6b39268b-7487-427d-aff5-f3ca3b2afd42@pengutronix.de>

Hello Carlos,

On 27.11.24 11:43, Carlos Song wrote:
>> -----Original Message-----
>> From: Ahmad Fatoum <a.fatoum at pengutronix.de>
>> Sent: Wednesday, November 27, 2024 4:38 PM
>> To: Carlos Song <carlos.song at nxp.com>; mkl at pengutronix.de; Frank Li
>> <frank.li at nxp.com>; o.rempel at pengutronix.de; kernel at pengutronix.de;
>> andi.shyti at kernel.org; shawnguo at kernel.org; s.hauer at pengutronix.de;
>> festevam at gmail.com
>> Cc: imx at lists.linux.dev; linux-i2c at vger.kernel.org;
>> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>> Subject: [EXT] Re: [PATCH v4] i2c: imx: support DMA defer probing

>> Please try to address open questions before sending new versions of the patch
>> set. Otherwise, it's difficult to follow the conversation.
>>
>> Did you see my question[1] on your v2:
>>
> 
> Hi, thank you so much! So sorry about it... I missed it yesterday. I will answer your question[1] in this mail.
> 
> 
>> | Wouldn't this break probe for all i2c-imx users who have
>> | CONFIG_IMX_SDMA disabled?
>> |
> 
> I have tested i2c probe at IMX and LS platform when DMA disabled,

What does DMA disabled mean? Did you leave the dmas property in the device
tree unchanged, but just disabled the config option?

> it won't break i2c-imx probe.
> When require DMA channel in i2c_imx_dma_request, find no devices and return
> -ENODEV, as you see at V4 patch, it will continue to probe and work in PIO mode.
> I2C adapter should keep available whatever DMA mode is or isn't enabled.

If that's the case, then all is good. I thought the situation described
above would return -EPROBE_DEFER instead. I haven't dug into the code
to understand what the difference between when dma_request_chan().

>> | Also I am wondering on what kernel version and what configuration
>> | (CONFIG_I2C_IMX=?, CONFIG_IMX_SDMA=?) you have that made you run into
>> | this situation.
>> |
> 
> I want to correct something, these code about DMA in i2c-imx.c is for eDMA not for SDMA.
> For eDMA mode, I have tested this patch at layerscape-1043 platform. My patch is based on
> cfba9f07a1d6 (tag: next-20241122, origin/master, origin/HEAD).

The driver also handles i.MX variants like i.MX6, i.MX8 and so on, which
have SDMA. So eDMA is not the only DMA driver it is used with.

> 
> Test log is :
> No apply this patch:
> CONFIG_I2C_IMX=y
> CONFIG_FSL_EDMA=y
> root at ls1043ardb:~# dmesg | grep i2c
> [    1.162053] i2c i2c-0: IMX I2C adapter registered
> [    1.166826] i2c i2c-0: using dma0chan16 (tx) and dma0chan17 (rx) for DMA transfers
> [    4.722057] i2c_dev: i2c /dev entries driver
> 
> Not apply the patch:
> CONFIG_I2C_IMX=y
> CONFIG_FSL_EDMA=m
> root at ls1043ardb:~# dmesg | grep i2c
> [    1.166381] i2c i2c-0: IMX I2C adapter registered
> [    4.719226] i2c_dev: i2c /dev entries driver
> (result shows i2c not enabled the eDMA mode)
> root at ls1043ardb:~# i2cdetect -y -l
> i2c-0   i2c             2180000.i2c                             I2C adapter
> root at ls1043ardb:~# i2cdetect -y 0
>      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
> 00:                         08 -- -- -- -- -- -- --
> 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 40: UU -- -- -- -- -- -- -- -- -- -- -- UU -- -- --
> 50: -- UU UU UU -- -- -- -- -- -- -- -- -- -- -- --
> 60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- --
> 70: -- -- -- -- -- -- -- --
> 
> After apply the patch:
> CONFIG_I2C_IMX=y
> CONFIG_FSL_EDMA=m
> root at ls1043ardb:~#
> root at ls1043ardb:~# dmesg | grep i2c
> [    4.697046] i2c_dev: i2c /dev entries driver
> [    7.304142] imx-i2c 2180000.i2c: using dma0chan16 (tx) and dma0chan17 (rx) for DMA transfers
> [    7.313532] i2c i2c-0: IMX I2C adapter registered
> (result shows i2c probed after eDMA module installed)

My concern is this configuration:

  - A user has eDMA/SDMA module or disabled, but enabled in DT
  - The I2C has a PMIC, which is needed for eMMC VCC
  - System startup is stuck or considerably delayed

> root at ls1043ardb:~#
> root at ls1043ardb:~# i2cdetect -y -l
> i2c-0   i2c             2180000.i2c                             I2C adapter
> root at ls1043ardb:~# i2cdetect -y 0
>      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
> 00:                         08 -- -- -- -- -- -- --
> 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> 40: UU -- -- -- -- -- -- -- -- -- -- -- UU -- -- --
> 50: -- UU UU UU -- -- -- -- -- -- -- -- -- -- -- --
> 60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- --
> 70: -- -- -- -- -- -- -- --
> 
> 
>> | I'd have expected that with fw_devlink enabled, the I2C controller
>> | wouldn't be probed before the DMA provider is available.
>>
> 
> This is a legacy patch, it has been in our local tree for a long time. The related history is relatively vague.
> I reproduced the problem and found this patch is effective, so I referred the community patch and
> legacy patch to rewrite the commit log(I am not sure if this would happened in some cases so I kept this information).
> Now it seems that these descriptions are redundant. I should completely removed this in the commit log:
>     Move i2c_imx_dma_request() before registering I2C adapter to avoid
>     infinite loop of .probe() calls to the same driver, see "e8c220fac415
>     Revert "i2c: imx: improve the error handling in i2c_imx_dma_request()""
>     and "Documentation/driver-api/driver-model/driver.rst".

Cheers,
Ahmad

> 
> [1]: https://lore.kernel.org/all/19a43db4-db5c-4638-9778-d94fb571a206 at pengutronix.de/
> [2]:https://lore.kernel.org/all/153e8e36-7b0e-4379-9cc3-6dacb5d705be at pengutronix.de/
> 
>>>
>>> Signed-off-by: Carlos Song <carlos.song at nxp.com>
>>> Signed-off-by: Clark Wang <xiaoning.wang at nxp.com>
>>> ---
>>> Change for V4:
>>> - Output "Only use PIO mode" log in debug level when no DMA configure.
>>> Change for V3:
>>> - According to Marc's comment, remove error print when defer probe.
>>>   Add info log when DMA has not been enabled and add error log when
>>>   DMA error, both won't stuck the i2c adapter register, just for reminding,
>>>   i2c adapter is working only in PIO mode.
>>> Change for V2:
>>> - According to Frank's comments, wrap at 75 char and Simplify fix code
>>>   at i2c_imx_dma_request().
>>> - Use strict patch check, fix alignment warning at
>>> i2c_imx_dma_request()
>>> ---
>>>  drivers/i2c/busses/i2c-imx.c | 31 +++++++++++++++++++++++--------
>>>  1 file changed, 23 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/i2c/busses/i2c-imx.c
>>> b/drivers/i2c/busses/i2c-imx.c index 5ed4cb61e262..b11d66d56c55 100644
>>> --- a/drivers/i2c/busses/i2c-imx.c
>>> +++ b/drivers/i2c/busses/i2c-imx.c
>>> @@ -397,17 +397,16 @@ static void i2c_imx_reset_regs(struct
>>> imx_i2c_struct *i2c_imx)  }
>>>
>>>  /* Functions for DMA support */
>>> -static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
>>> -                                             dma_addr_t
>> phy_addr)
>>> +static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
>>> +dma_addr_t phy_addr)
>>>  {
>>>       struct imx_i2c_dma *dma;
>>>       struct dma_slave_config dma_sconfig;
>>> -     struct device *dev = &i2c_imx->adapter.dev;
>>> +     struct device *dev = i2c_imx->adapter.dev.parent;
>>>       int ret;
>>>
>>>       dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
>>>       if (!dma)
>>> -             return;
>>> +             return -ENOMEM;
>>>
>>>       dma->chan_tx = dma_request_chan(dev, "tx");
>>>       if (IS_ERR(dma->chan_tx)) {
>>> @@ -452,7 +451,7 @@ static void i2c_imx_dma_request(struct
>> imx_i2c_struct *i2c_imx,
>>>       dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n",
>>>               dma_chan_name(dma->chan_tx),
>>> dma_chan_name(dma->chan_rx));
>>>
>>> -     return;
>>> +     return 0;
>>>
>>>  fail_rx:
>>>       dma_release_channel(dma->chan_rx);
>>> @@ -460,6 +459,8 @@ static void i2c_imx_dma_request(struct
>> imx_i2c_struct *i2c_imx,
>>>       dma_release_channel(dma->chan_tx);
>>>  fail_al:
>>>       devm_kfree(dev, dma);
>>> +
>>> +     return ret;
>>>  }
>>>
>>>  static void i2c_imx_dma_callback(void *arg) @@ -1803,6 +1804,23 @@
>>> static int i2c_imx_probe(struct platform_device *pdev)
>>>       if (ret == -EPROBE_DEFER)
>>>               goto clk_notifier_unregister;
>>>
>>> +     /*
>>> +      * Init DMA config if supported, -ENODEV means DMA not enabled at
>>> +      * this platform, that is not a real error, so just remind "only
>>> +      * PIO mode is used". If DMA is enabled, but meet error when request
>>> +      * DMA channel, error should be showed in probe error log. PIO mode
>>> +      * should be available regardless of DMA.
>>> +      */
>>> +     ret = i2c_imx_dma_request(i2c_imx, phy_addr);
>>> +     if (ret) {
>>> +             if (ret == -EPROBE_DEFER)
>>> +                     goto clk_notifier_unregister;
>>> +             else if (ret == -ENODEV)
>>> +                     dev_dbg(&pdev->dev, "Only use PIO mode\n");
>>> +             else
>>> +                     dev_err_probe(&pdev->dev, ret, "Failed to setup
>> DMA, only use PIO mode\n");
>>> +     }
>>> +
>>>       /* Add I2C adapter */
>>>       ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
>>>       if (ret < 0)
>>> @@ -1817,9 +1835,6 @@ static int i2c_imx_probe(struct platform_device
>> *pdev)
>>>               i2c_imx->adapter.name);
>>>       dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
>>>
>>> -     /* Init DMA config if supported */
>>> -     i2c_imx_dma_request(i2c_imx, phy_addr);
>>> -
>>>       return 0;   /* Return OK */
>>>
>>>  clk_notifier_unregister:
>>
>>
>> --
>> Pengutronix e.K.                           |
>> |
>> Steuerwalder Str. 21                       |
>> http://www.pen/
>> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C1acf840d499f
>> 49a7872408dd0ebedc39%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
>> %7C638682935131084746%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAw
>> MDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&s
>> data=Y9Qn9XEk15yu4CespwsNu6hl3%2FqfNTvEeOn4ZvnGxbo%3D&reserved=0
>> |
>> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
>> |
>> Amtsgericht Hildesheim, HRA 2686           | Fax:
>> +49-5121-206917-5555 |
> 


-- 
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 olteanv at gmail.com  Thu Dec  5 10:50:37 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 5 Dec 2024 20:50:37 +0200
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <6751f125.5d0a0220.255b79.7be0@mx.google.com>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <20241205180539.6t5iz2m3wjjwyxp3@skbuf>
 <6751f125.5d0a0220.255b79.7be0@mx.google.com>
Message-ID: <20241205185037.g6cqejgad5jamj7r@skbuf>

On Thu, Dec 05, 2024 at 07:29:53PM +0100, Christian Marangi wrote:
> Ohhhh ok, wasn't clear to me the MFD driver had to be placed in the mdio
> node.
> 
> To make it clear this would be an implementation.
> 
> mdio_bus: mdio-bus {
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> 	...
> 
> 	mfd at 1 {
> 		compatible = "airoha,an8855-mfd";
> 		reg = <1>;
> 
> 		nvmem_node {
> 			...
> 		};
> 
> 		switch_node {
> 			...
> 		};
> 	};
> };

I mean, I did mention Documentation/devicetree/bindings/mfd/mscc,ocelot.yaml
in my initial reply, which has an example with exactly this layout...

> The difficulties I found (and maybe is very easy to solve and I'm
> missing something here) is that switch and internal PHY port have the
> same address and conflicts.
> 
> Switch will be at address 1 (or 2 3 4 5... every port can access switch
> register with page 0x4)
> 
> DSA port 0 will be at address 1, that is already occupied by the switch.
> 
> Defining the DSA port node on the host MDIO bus works correctly for
> every port but for port 0 (the one at address 1), the kernel complains
> and is not init. (as it does conflict with the switch that is at the
> same address) (can't remember the exact warning)

Can any of these MDIO addresses (switch or ports) be changed through registers?

I guess the non-hack solution would be to permit MDIO buses to have
#size-cells = 1, and MDIO devices to acquire a range of the address
space, rather than just one address. Though take this with a grain of
salt, I have a lot more to learn.

If neither of those are options, in principle the hack with just
selecting, randomly, one of the N internal PHY addresses as the central
MDIO address should work equally fine regardless of whether we are
talking about the DSA switch's MDIO address here, or the MFD device's
MDIO address.

With MFD you still have the option of creating a fake MDIO controller
child device, which has mdio-parent-bus = <&host_bus>, and redirecting
all user port phy-handles to children of this bus. Since all regmap I/O
of this fake MDIO bus goes to the MFD driver, you can implement there
your hacks with page switching etc etc, and it should be equally safe.


From mhklinux at outlook.com  Thu Dec  5 10:52:35 2024
From: mhklinux at outlook.com (Michael Kelley)
Date: Thu, 5 Dec 2024 18:52:35 +0000
Subject: [RFC PATCH v1 00/57] Boot-time page size selection for arm64
In-Reply-To: <20241205182008.2b36476a@mordecai.tesarici.cz>
References: <20241014105514.3206191-1-ryan.roberts@arm.com>
	<20241017142752.17f2c816@mordecai.tesarici.cz>
	<aa9a7118-3067-448e-aa34-bbc148c921a2@arm.com>
 <20241205182008.2b36476a@mordecai.tesarici.cz>
Message-ID: <SN6PR02MB41571E0BD384C44C46127B49D4302@SN6PR02MB4157.namprd02.prod.outlook.com>

From: Petr Tesarik <ptesarik at suse.com> Sent: Thursday, December 5, 2024 9:20 AM
> 
> Hi Ryan,
> 
> On Thu, 17 Oct 2024 13:32:43 +0100
> Ryan Roberts <ryan.roberts at arm.com> wrote:
> 
> > On 17/10/2024 13:27, Petr Tesarik wrote:
> > > On Mon, 14 Oct 2024 11:55:11 +0100
> > > Ryan Roberts <ryan.roberts at arm.com> wrote:
> > >
> > >> [...]
> > >> The series is arranged as follows:
> > >>
> > >>   - patch 1:	   Add macros required for converting non-arch code to support
> > >>   		   boot-time page size selection
> > >>   - patches 2-36:  Remove PAGE_SIZE compile-time constant assumption from all
> > >>   		   non-arch code
> > >
> > > I have just tried to recompile the openSUSE kernel with these patches
> > > applied, and I'm running into this:
> > >
> > >   CC      arch/arm64/hyperv/hv_core.o
> > > In file included from ../arch/arm64/hyperv/hv_core.c:14:0:
> > > ../include/linux/hyperv.h:158:5: error: variably modified ?reserved2? at file scope
> > >   u8 reserved2[PAGE_SIZE - 68];
> > >      ^~~~~~~~~
> > >
> > > It looks like one more place which needs a patch, right?
> >
> > As mentioned in the cover letter, so far I've only converted enough to get the
> > defconfig *image* building (i.e. no modules). If you are compiling a different
> > config or compiling the modules for defconfig, you will likely run into these
> > types of issues.
> >
> > That said, I do have some patches to fix Hyper-V, which Michael Kelley was kind
> > enough to send me.
> >
> > I understand that Suse might be able to help with wider performance testing - if
> > that's the reason you are trying to compile, you could send me your config and
> > I'll start working on fixing up other drivers?
> 
> This project was de-prioritised for some time, but I have just returned
> to it, and one of our test systems uses a Mellanox 5 NIC, which did not build.
> 
> If you still have time to work on your patch series, please, can you
> look into enabling MLX5_CORE_EN?
> 
> Oh, and have you rebased the series to 6.12 yet?
> 

FWIW, here's what I hacked together to compile and run the mlx5 driver in
a Hyper-V VM.  This was against a 6.11 kernel code base.

Michael

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
index d894a88fa9f2..d0b381df074c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -66,9 +66,10 @@ struct fw_page {
 
 enum {
 	MLX5_MAX_RECLAIM_TIME_MILI	= 5000,
-	MLX5_NUM_4K_IN_PAGE		= PAGE_SIZE / MLX5_ADAPTER_PAGE_SIZE,
 };
 
+#define MLX5_NUM_4K_IN_PAGE	((int)(PAGE_SIZE / MLX5_ADAPTER_PAGE_SIZE))
+
 static u32 get_function(u16 func_id, bool ec_function)
 {
 	return (u32)func_id | (ec_function << 16);
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index ba875a619b97..2d39ba77b591 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -255,12 +255,14 @@ enum {
 					  MLX5_NON_FP_BFREGS_PER_UAR,
 	MLX5_MAX_BFREGS			= MLX5_MAX_UARS *
 					  MLX5_NON_FP_BFREGS_PER_UAR,
-	MLX5_UARS_IN_PAGE		= PAGE_SIZE / MLX5_ADAPTER_PAGE_SIZE,
-	MLX5_NON_FP_BFREGS_IN_PAGE	= MLX5_NON_FP_BFREGS_PER_UAR * MLX5_UARS_IN_PAGE,
 	MLX5_MIN_DYN_BFREGS		= 512,
 	MLX5_MAX_DYN_BFREGS		= 1024,
 };
 
+
+#define	MLX5_UARS_IN_PAGE		((int)(PAGE_SIZE / MLX5_ADAPTER_PAGE_SIZE))
+#define	MLX5_NON_FP_BFREGS_IN_PAGE	((int)(MLX5_NON_FP_BFREGS_PER_UAR * MLX5_UARS_IN_PAGE))
+
 enum {
 	MLX5_MKEY_MASK_LEN		= 1ull << 0,
 	MLX5_MKEY_MASK_PAGE_SIZE	= 1ull << 1,

From quic_bibekkum at quicinc.com  Thu Dec  5 10:53:16 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Fri, 6 Dec 2024 00:23:16 +0530
Subject: [PATCH RESEND v17 3/5] iommu/arm-smmu: add support for PRR bit
 setup
In-Reply-To: <CAF6AEGtBva41Fz0tS4gRwK21ZqzDH5yGrWLY6TMeS6u7OFfS0Q@mail.gmail.com>
References: <20241114160721.1527934-1-quic_bibekkum@quicinc.com>
 <20241114160721.1527934-4-quic_bibekkum@quicinc.com>
 <CAF6AEGuwWsAkRyF-h5Aj3KzM7iksb12HsfJ5Ks+-P8hv60MWFg@mail.gmail.com>
 <9beca099-5cf3-42b5-b1f9-fb1551219b18@quicinc.com>
 <CAF6AEGvAOswFTpS5PHrgCsG_2-QN_Bi4YjZbPpV+r3x=9D2aUQ@mail.gmail.com>
 <d2d8d9e9-74b1-4b05-84a2-dcfa204e6e00@quicinc.com>
 <CAF6AEGtBva41Fz0tS4gRwK21ZqzDH5yGrWLY6TMeS6u7OFfS0Q@mail.gmail.com>
Message-ID: <4c1df383-6a0a-4bed-8ece-b582712ca4cf@quicinc.com>



On 12/4/2024 8:51 PM, Rob Clark wrote:
> On Wed, Dec 4, 2024 at 3:27?AM Bibek Kumar Patro
> <quic_bibekkum at quicinc.com> wrote:
>>
>>
>>
>> On 11/22/2024 10:33 PM, Rob Clark wrote:
>>> On Fri, Nov 22, 2024 at 8:19?AM Bibek Kumar Patro
>>> <quic_bibekkum at quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 11/20/2024 10:47 PM, Rob Clark wrote:
>>>>> On Thu, Nov 14, 2024 at 8:10?AM Bibek Kumar Patro
>>>>> <quic_bibekkum at quicinc.com> wrote:
>>>>>>
>>>>>> Add an adreno-smmu-priv interface for drm/msm to call
>>>>>> into arm-smmu-qcom and initiate the PRR bit setup or reset
>>>>>> sequence as per request.
>>>>>>
>>>>>> This will be used by GPU to setup the PRR bit and related
>>>>>> configuration registers through adreno-smmu private
>>>>>> interface instead of directly poking the smmu hardware.
>>>>>>
>>>>>> Suggested-by: Rob Clark <robdclark at gmail.com>
>>>>>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
>>>>>> ---
>>>>>>     drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 37 ++++++++++++++++++++++
>>>>>>     drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 ++
>>>>>>     include/linux/adreno-smmu-priv.h           | 14 ++++++++
>>>>>>     3 files changed, 53 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>>> index d26f5aea248e..0e4f3fbda961 100644
>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>>> @@ -16,6 +16,8 @@
>>>>>>
>>>>>>     #define QCOM_DUMMY_VAL -1
>>>>>>
>>>>>> +#define GFX_ACTLR_PRR          (1 << 5)
>>>>>> +
>>>>>>     static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
>>>>>>     {
>>>>>>            return container_of(smmu, struct qcom_smmu, smmu);
>>>>>> @@ -99,6 +101,32 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
>>>>>>            arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
>>>>>>     }
>>>>>>
>>>>>> +static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
>>>>>> +{
>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>>>> +       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>>>>>> +       u32 reg = 0;
>>>>>> +
>>>>>> +       reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
>>>>>> +       reg &= ~GFX_ACTLR_PRR;
>>>>>> +       if (set)
>>>>>> +               reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
>>>>>> +       arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
>>>>>> +}
>>>>>> +
>>>>>> +static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
>>>>>> +{
>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>>>> +
>>>>>> +       writel_relaxed(lower_32_bits(page_addr),
>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
>>>>>> +
>>>>>> +       writel_relaxed(upper_32_bits(page_addr),
>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
>>>>>> +}
>>>>>> +
>>>>>>     #define QCOM_ADRENO_SMMU_GPU_SID 0
>>>>>>
>>>>>>     static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
>>>>>> @@ -210,6 +238,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>>>>>>     static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>>>                    struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>>>>>>     {
>>>>>> +       const struct device_node *np = smmu_domain->smmu->dev->of_node;
>>>>>>            struct adreno_smmu_priv *priv;
>>>>>>
>>>>>>            smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>>>>> @@ -239,6 +268,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>>>            priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
>>>>>>            priv->set_stall = qcom_adreno_smmu_set_stall;
>>>>>>            priv->resume_translation = qcom_adreno_smmu_resume_translation;
>>>>>> +       priv->set_prr_bit = NULL;
>>>>>> +       priv->set_prr_addr = NULL;
>>>>>> +
>>>>>> +       if (of_device_is_compatible(np, "qcom,smmu-500") &&
>>>>>> +                       of_device_is_compatible(np, "qcom,adreno-smmu")) {
>>>>>
>>>>> fwiw, it seems like PRR actually works on sc7180, which is _not_
>>>>> mmu-500, so I guess the support actually goes back further.
>>>>>
>>>>
>>>> As I checked sc7180 was on previous variant of SMMU,
>>>> so targets on this variant have different steps to set PRR bit.
>>>> <Do not have both prr bit and PRR page registers>.
>>>
>>> Experimentally, I have to set both the PRR LADDR/UADDR regs and
>>> ACTLR.PRR bit on sc7180 to get the sparse-residency tests passing.  So
>>> the underlying hw seems to work in the same way as mmu-500.  _But_
>>> this is on a sc7180 chromebook, the situation might be different
>>> depending on fw on things that have QC hyp.
>>>
>>
>> I checked on sc7180 chipset which is based on the smmu-v2,
>> this time by looking for these offsets specifically. I can see the
>> nomenclature of the PRR related registers are a bit different
>> compared to MMU-500 variant.
>> Also the implementation register is 64 bit instead of
>> dual 32 bit as in case of MMU-500. and PRR bit is not marked in
>> ACTLR register offset.
> 
> Interesting.. in my experiments it needed both the ACTLR.PRR bit set
> and the LADDR/UADDR.  Maybe it was just happy coincidence that two 32b
> writes worked?
> 

I think it's similar to case we discussed [1] in v11
on why not good idea to use writeq on 32bit regs.
So some corner cases for unaligned 32b addresses might get truncated.

[1]: 
https://lore.kernel.org/all/ae35bf9b-4401-4a99-abd7-c0d9d399a46b at quicinc.com/#:~:text=So%20I%20think-,writeq,-for%2064bit%20write


>> So turns out PRR is supported but with some modification and
>> can be carried out with same compatible based approach only - as per
>> my understanding.
>>
>> In current patch plan was to provide support for MMU-500 based targets
>> and won't break any legacy targets, so we can take the PRR support
>> for legacy targets in different series once our evaluation is done on
>> smmu-v2 ?
> 
> I guess it wouldn't be the end of the world, but it would mean that
> drm would need to expose PRR support to userspace separately from
> sparse binding support.  Maybe we need to do that anyways.  (I'm not
> really sure how many different a6xx+smmu-v2 devices are out there, but
> I guess they are all based on the same generation of snapdragon?)
> 

We would need to audit on all the smmu-v2 based devices using a6xx
version before I can comment on this, but mostly it should be in the 
same generation of snapdragon (scxx/smxx).

Thanks & regards,
bibek

> BR,
> -R
> 
>> We would explore more on this PRR feature for smmu-v2 based targets,
>> before supporting it.
>>
>> Thanks & regards,
>> Bibek
>>
>>>> It's MMU-500 targets only where PRR support is with both PRR bit
>>>> and PRR page addr registers. As I was re-visiting our discussions on v13
>>>> regarding this - I remember that's why we started using the SMMU-
>>>> compatible string based PRR procedure selection instead of the reserved-
>>>> memory node. [1] i.e Based on SMMU variant (as selected by compatible
>>>> string), specific sequence will be selected.
>>>>
>>>> So for now only MMU-500 based selection has been supported as part of
>>>> this series and will add subsequent support for other SMMU-variants
>>>> thereafter.
>>>>
>>>>> I'm curious if we can just rely on this being supported by any hw that
>>>>> has a6xx or newer?
>>>>>
>>>>
>>>> I'd need to check on targets which will be based on a6xx onwards, on
>>>> what will be the procedure planned to support PRR feature. I'll update
>>>> the information over this space.
>>>
>>> One of the open questions about the drm/msm sparse-memory patchset is
>>> whether we need to expose to userspace whether PRR is supported, or if
>>> we can just rely on sparse-binding support implying sparse residency
>>> (ie, PRR) support. All a6xx devices support per-process pgtables,
>>> which is the only requirement for basic sparseBinding support.  But
>>> PRR is required to additionally expose
>>> sparseResidencyBuffer/sparseResidencyImage2D.
>>>
>>> I think, long term, turnip probably will want to drop support for
>>> older kernels and remove support for legacy buffer mapping.  But if we
>>> have some a6xx devices without PRR, then to do that we'd need to
>>> decouple sparse binding and sparse residency.  (Vulkan allows a driver
>>> to expose the former without the latter.)
>>>
>>> BR,
>>> -R
>>>
>>>> [1]:
>>>> https://lore.kernel.org/all/5790afa3-f9c0-4720-9804-8a7ff3d91854 at quicinc.com/#:~:text=%3E%20I%20guess%20if,part%20as%20well.
>>>>
>>>> Thanks & regards,
>>>> Bibek
>>>>
>>>>> BR,
>>>>> -R
>>>>>
>>>>>> +               priv->set_prr_bit = qcom_adreno_smmu_set_prr_bit;
>>>>>> +               priv->set_prr_addr = qcom_adreno_smmu_set_prr_addr;
>>>>>> +       }
>>>>>>
>>>>>>            return 0;
>>>>>>     }
>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>>> index e2aeb511ae90..2dbf3243b5ad 100644
>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>>> @@ -154,6 +154,8 @@ enum arm_smmu_cbar_type {
>>>>>>     #define ARM_SMMU_SCTLR_M               BIT(0)
>>>>>>
>>>>>>     #define ARM_SMMU_CB_ACTLR              0x4
>>>>>> +#define ARM_SMMU_GFX_PRR_CFG_LADDR     0x6008
>>>>>> +#define ARM_SMMU_GFX_PRR_CFG_UADDR     0x600C
>>>>>>
>>>>>>     #define ARM_SMMU_CB_RESUME             0x8
>>>>>>     #define ARM_SMMU_RESUME_TERMINATE      BIT(0)
>>>>>> diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
>>>>>> index c637e0997f6d..614665153b3e 100644
>>>>>> --- a/include/linux/adreno-smmu-priv.h
>>>>>> +++ b/include/linux/adreno-smmu-priv.h
>>>>>> @@ -50,6 +50,18 @@ struct adreno_smmu_fault_info {
>>>>>>      *                 the GPU driver must call resume_translation()
>>>>>>      * @resume_translation: Resume translation after a fault
>>>>>>      *
>>>>>> + * *CAUTION* : PRR callbacks (set_prr_bit/set_prr_addr) are NULL terminated for
>>>>>> + *             targets without PRR support. Exercise caution and verify target
>>>>>> + *             capabilities before invoking these callbacks to prevent potential
>>>>>> + *             runtime errors or unexpected behavior.
>>>>>> + *
>>>>>> + * @set_prr_bit:   Extendible interface to be used by GPU to modify the
>>>>>> + *                ACTLR register bits, currently used to configure
>>>>>> + *                Partially-Resident-Region (PRR) bit for feature's
>>>>>> + *                setup and reset sequence as requested.
>>>>>> + * @set_prr_addr:  Configure the PRR_CFG_*ADDR register with the
>>>>>> + *                physical address of PRR page passed from
>>>>>> + *                GPU driver.
>>>>>>      *
>>>>>>      * The GPU driver (drm/msm) and adreno-smmu work together for controlling
>>>>>>      * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
>>>>>> @@ -67,6 +79,8 @@ struct adreno_smmu_priv {
>>>>>>         void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
>>>>>>         void (*set_stall)(const void *cookie, bool enabled);
>>>>>>         void (*resume_translation)(const void *cookie, bool terminate);
>>>>>> +    void (*set_prr_bit)(const void *cookie, bool set);
>>>>>> +    void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
>>>>>>     };
>>>>>>
>>>>>>     #endif /* __ADRENO_SMMU_PRIV_H */
>>>>>> --
>>>>>> 2.34.1
>>>>>>
>>>>
>>



From pZ010001011111 at proton.me  Thu Dec  5 10:58:30 2024
From: pZ010001011111 at proton.me (Piotr Zalewski)
Date: Thu, 05 Dec 2024 18:58:30 +0000
Subject: [PATCH v7] rockchip/drm: vop2: add support for gamma LUT
In-Reply-To: <7877dddf.b3b8.19396e1df66.Coremail.andyshrk@163.com>
References: <20241101185545.559090-3-pZ010001011111@proton.me> <9Rp0NJW2QG5qDduowVaialZWN6xTe9KJFciu7Q2LERJZQXsUgFvMGXfcFaNznIEJEBpZeOdZPuL4fxOEFduaSJLuQJ3cIvN-fx2lEzYSBKE=@proton.me> <12938960.VsHLxoZxqI@diego> <7877dddf.b3b8.19396e1df66.Coremail.andyshrk@163.com>
Message-ID: <Kmf2VXiWF77w-brVyLRrswUV3O_7INOquqIpG31ctJB_c9wVFqCY8DeR8rot4jq6Cpz7VeHX7xDl7SXA2JBwXDggAsjKqn__sP9i-be8NI0=@proton.me>

On Thursday, December 5th, 2024 at 1:53 PM, Andy Yan <andyshrk at 163.com> wrote:


> I guess it returned because crtc_state->color_mgmt_changed is false when called from
> 
> vop2_crtc_atomic_enable from s2r.
> 

Hi Heiko and Andy,

Yes that was it. Moving the check out of *try_set_gamma
and checking it only in the atomic_flush fixed the issue.

Thanks Andy for pointing that out.

Regards, Piotr Zalewski


From dmitry.baryshkov at linaro.org  Thu Dec  5 11:10:31 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu,  5 Dec 2024 21:10:31 +0200
Subject: [PATCH v5 00/10] drm/display: hdmi: add drm_hdmi_connector_mode_valid()
In-Reply-To: <20241130-hdmi-mode-valid-v5-0-742644ec3b1f@linaro.org>
References: <20241130-hdmi-mode-valid-v5-0-742644ec3b1f@linaro.org>
Message-ID: <173342582161.2533869.11795486713615996638.b4-ty@linaro.org>

On Sat, 30 Nov 2024 03:52:25 +0200, Dmitry Baryshkov wrote:
> Several HDMI drivers have common code pice in the .mode_valid function
> that validates RGB / 8bpc rate using the TMDS char rate callbacks.
> 
> Move this code piece to the common helper and remove the need to perform
> this check manually. In case of DRM_BRIDGE_OP_HDMI bridges, they can
> skip the check in favour of performing it in drm_bridge_connector.
> 
> [...]

Applied to drm-misc-next, thanks!

[01/10] drm/tests: hdmi: handle empty modes in find_preferred_mode()
        commit: d3314efd6ebf335a3682b1d6b1b81cdab3d8254a
[02/10] drm/tests: hdmi: rename connector creation function
        commit: 67d31cd02c8dfb3d006dba62a854e6758cf7a0e4
[03/10] drm/tests: hdmi: return meaningful value from set_connector_edid()
        commit: a8403be6eea91e4f5d8ad5dbc463dd08339eaece
[04/10] drm/display: hdmi: add generic mode_valid helper
        commit: 47368ab437fdd1b5118644659a97a6e5dab45248
[05/10] drm/sun4i: use drm_hdmi_connector_mode_valid()
        commit: ae048fc4f96d716a2ef326bd6e894694057c078c
[06/10] drm/vc4: use drm_hdmi_connector_mode_valid()
        commit: d4581ae8695863b21f9b739dddce8159f3068ca3
[07/10] drm/display: bridge_connector: use drm_bridge_connector_mode_valid()
        commit: 54d7b7f9d637a53ba19d117eb9b01619bb1704ed
[08/10] drm/bridge: lontium-lt9611: drop TMDS char rate check in mode_valid
        commit: efda6551aa866b80dcb5a94158d805c560fc4f1c
[09/10] drm/bridge: dw-hdmi-qp: replace mode_valid with tmds_char_rate
        commit: 2d7202c6f38d14260a3998a2aa249a53415a24f5
[10/10] drm/sun4i: use drm_atomic_helper_connector_hdmi_check()
        commit: 84e541b1e58e04d808e1bb13ef566ffbe87aa89b

Best regards,
-- 
With best wishes
Dmitry



From ansuelsmth at gmail.com  Thu Dec  5 11:16:13 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu, 5 Dec 2024 20:16:13 +0100
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241205183403.zla5syfzj3yrinwj@skbuf>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205170629.ww7qcvgbqdf5ipcj@skbuf>
 <6751e22d.050a0220.3435c6.57de@mx.google.com>
 <20241205183403.zla5syfzj3yrinwj@skbuf>
Message-ID: <6751fc01.7b0a0220.1f425b.5416@mx.google.com>

On Thu, Dec 05, 2024 at 08:34:03PM +0200, Vladimir Oltean wrote:
> On Thu, Dec 05, 2024 at 06:26:01PM +0100, Christian Marangi wrote:
> > Concept looks handy, ideally I can just assign one ID for each port
> > like:
> > port 1 -> FIB 1
> > port 2 -> FIB 1
> > port 3 -> FIB 2
> > 
> > Question:
> > Ports of the same bridge should have the same FIB?
> 
> The answer, as well as many other explanations, is under the "Address
> databases" section of Documentation/networking/dsa/dsa.rst. Please read
> it through before starting to implement anything.
>

Ok sorry, will read.

> > What I need to check is how the switch handle this for learning. Does
> > the switch correctly create FDB entry with the right FIB?
> 
> You're asking me how an8855 behaves? I have no idea, I never interacted
> with it :-|
> 

Noo it wasn't a question for you, it was really to describe a problem
that might be present if the switch doesn't account for that and that I
need to check.

> The idea as far as the DSA API is concerned would be to learn addresses
> in the bridge database (DSA_DB_BRIDGE) that the user port is configured
> for, and not learn any addresses in the port-private database (DSA_DB_PORT).
> 
> > If that's not the case then I think assisted_learning is needed and HW
> > Learn can't be used?
> 
> ds->assisted_learning_on_cpu_port applies, as suggested by its name,
> only on the CPU port. On user ports, address learning should work normally.
> 
> As you will find in the documentation, the CPU port is not like a user
> port, in the sense that it is not configured to service a single address
> database, but all of them. So, source learning on the CPU port will not
> work unless the switch knows which address database should each packet
> be associated with.

Ok so in such case, learning on CPU needs to be disabled and assisted
learning enabled.

> 
> In principle, one way could be to pass, during tagger xmit, the database ID,
> so that the switch knows that it must learn the MAC SA of this packet in
> this FID. I don't have the full image of the Mediatek DSA tag format,
> but if an8855 is anything like mt7530, this option isn't available.
> Thus, like mt7530, it needs to set ds->assisted_learning_on_cpu_port, so
> that software will call port_fdb_add() on the CPU port with the correct
> dsa_db (for the right bridge) as argument. But I don't think that is
> going to pose any sort of issue.
> 

In theory I might have found just this option. Tagger documentation is
totally missing but there are some c and header API that define some
interesting option of the tagger.

It seems the tagger can work in 3 way:
- portmap (what we currently use)
- portid 
- lookup result

Now the last 2 mode seems very interesting.
The naming is very confusing but maybe with portid they refer to the
FIB. I need to check this. If that's the case then it's exactly what we
need. They set an int so it's definetly an ID.

I assume lookup result is to only use FDB to decide where the packet
should go. In this mode no ID or port are defined.

So in short lots of tests to do, maybe this can be handled in the
tagger.

> > (I still need to check if I can assign a default FIB for a port...
> > Currently the STP register are 2 bit for each FIB id, so 16 different
> > FIB are possible)
> > 
> > Also do we have a script for selft tests? I remember there was one back
> > in the days for fdb isolation?
> 
> I don't remember right now, I don't think we do. I'll try to come up
> with something in the following days.

Yes that would be handy.

-- 
	Ansuel


From ansuelsmth at gmail.com  Thu Dec  5 11:36:30 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Thu, 5 Dec 2024 20:36:30 +0100
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241205185037.g6cqejgad5jamj7r@skbuf>
References: <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <20241205180539.6t5iz2m3wjjwyxp3@skbuf>
 <6751f125.5d0a0220.255b79.7be0@mx.google.com>
 <20241205185037.g6cqejgad5jamj7r@skbuf>
Message-ID: <675200c3.7b0a0220.236ac3.9edf@mx.google.com>

On Thu, Dec 05, 2024 at 08:50:37PM +0200, Vladimir Oltean wrote:
> On Thu, Dec 05, 2024 at 07:29:53PM +0100, Christian Marangi wrote:
> > Ohhhh ok, wasn't clear to me the MFD driver had to be placed in the mdio
> > node.
> > 
> > To make it clear this would be an implementation.
> > 
> > mdio_bus: mdio-bus {
> > 	#address-cells = <1>;
> > 	#size-cells = <0>;
> > 
> > 	...
> > 
> > 	mfd at 1 {
> > 		compatible = "airoha,an8855-mfd";
> > 		reg = <1>;
> > 
> > 		nvmem_node {
> > 			...
> > 		};
> > 
> > 		switch_node {
> > 			...
> > 		};
> > 	};
> > };
> 
> I mean, I did mention Documentation/devicetree/bindings/mfd/mscc,ocelot.yaml
> in my initial reply, which has an example with exactly this layout...
> 
> > The difficulties I found (and maybe is very easy to solve and I'm
> > missing something here) is that switch and internal PHY port have the
> > same address and conflicts.
> > 
> > Switch will be at address 1 (or 2 3 4 5... every port can access switch
> > register with page 0x4)
> > 
> > DSA port 0 will be at address 1, that is already occupied by the switch.
> > 
> > Defining the DSA port node on the host MDIO bus works correctly for
> > every port but for port 0 (the one at address 1), the kernel complains
> > and is not init. (as it does conflict with the switch that is at the
> > same address) (can't remember the exact warning)
> 
> Can any of these MDIO addresses (switch or ports) be changed through registers?

No, it can only be changed the BASE address that change the address of
each port.

port 0 is base address
port 1 is base address + 1
port 2 is base address + 2...

> 
> I guess the non-hack solution would be to permit MDIO buses to have
> #size-cells = 1, and MDIO devices to acquire a range of the address
> space, rather than just one address. Though take this with a grain of
> salt, I have a lot more to learn.

I remember this was an idea when PHY Package API were proposed and was
rejected as we wanted PHY to be single reg.

> 
> If neither of those are options, in principle the hack with just
> selecting, randomly, one of the N internal PHY addresses as the central
> MDIO address should work equally fine regardless of whether we are
> talking about the DSA switch's MDIO address here, or the MFD device's
> MDIO address.
> 
> With MFD you still have the option of creating a fake MDIO controller
> child device, which has mdio-parent-bus = <&host_bus>, and redirecting
> all user port phy-handles to children of this bus. Since all regmap I/O
> of this fake MDIO bus goes to the MFD driver, you can implement there
> your hacks with page switching etc etc, and it should be equally
> safe.

I wonder if a node like this would be more consistent and descriptive?

mdio_bus: mdio-bus {
    #address-cells = <1>;
    #size-cells = <0>;

    ...

    mfd at 1 {
            compatible = "airoha,an8855-mfd";
            reg = <1>;

            nvmem_node {
                    ...
            };

            switch_node {
                ports {
                        port at 0 {
                                phy-handle = <&phy>;
                        };

                        port at 1 {
                                phy-handle = <&phy_2>;
                        }
                };
            };

            phy: phy_node {

            };
    };

    phy_2: phy at 2 {
        reg = <2>;
    }

    phy at 3 {
        reg = <3>;
    }

    ..
};

No idea how to register that single phy in mfd... I guess a fake mdio is
needed anyway... What do you think of this node example? Or not worth it
and better have the fake MDIO with all the switch PHY in it?

-- 
	Ansuel


From mailhol.vincent at wanadoo.fr  Thu Dec  5 07:31:29 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 00:31:29 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr> <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
Message-ID: <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>

-CC: Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
+CC: Martin Uecker <muecker at gwdg.de>
(seems that Martin changed his address)

On Thu. 5 Dec. 2024 at 03:39, David Laight <David.Laight at aculab.com> wrote:
> > Sent: 02 December 2024 17:33
> >
> > From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> >
> > __is_constexpr(), while being one of the most glorious one liner hack
> > ever witnessed by mankind, is overly complex. Following the adoption
> > of C11 in the kernel, this macro can be simplified through the use of
> > a _Generic() selection.
>
> You should give credit to some of the earlier patches that do the same.
> I'm sure there were some related ones from Linus - not applied yet.

ACK. Would adding a suggested--by Linus tag solve your concern?

> > First, split the macro in two:
> >
> >   - __is_const_zero(x): an helper macro; tells whether x is the
> >     integer constant expression 0 or something else.
> >
> >   - is_const(x): replacement of __is_constexpr(); tells whether x is a
> >     integer constant expression.
> >
> > The split serves two purposes: first make it easier to understand;
> > second, __is_const_zero() will be reused as a building block for other
> > is_const_*() macros that will be introduced later on.
> >
> > The core principle of __is_constexpr() to abuse the return type of the
> > ternary operator remains, but all the surrounding sizeof() hack
> > disappear.
> >
> > On a side note, while not relevant to the kernel, __is_constexpr()
> > relied on the GNU extension that sizeof(void) is 1. const_expr() does
> > not use any GNU extensions, making it ISO C compliant.
> >
> > __is_constexpr() is temporarily kept and will be removed once all its
> > users get migrated to is_const() (or one of its friend).
> >
> > Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> > ---
> >  include/linux/compiler.h | 41 +++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 41 insertions(+)
> >
> > diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> > index a2a56a50dd85227a4fdc62236a2710ca37c5ba52..30ce06df4153cfdc0fad9bc7bffab9097f8b0450 100644
> > --- a/include/linux/compiler.h
> > +++ b/include/linux/compiler.h
> > @@ -316,6 +316,47 @@ static inline void *offset_to_ptr(const int *off)
> >  #define statically_true(x) (__builtin_constant_p(x) && (x))
> >  #define statically_false(x) (__builtin_constant_p(x) && (x) == 0)
> >
> > +/*
> > + * Whether x is the integer constant expression 0 or something else.
> > + *
> > + * Details:
> > + *   - The C11 standard defines in ?6.3.2.3.3
> > + *       (void *)<integer constant expression with the value 0>
> > + *     as a null pointer constant (c.f. the NULL macro).
> > + *   - If x evaluates to the integer constant expression 0,
> > + *       (void *)(x)
> > + *     is a null pointer constant. Else, it is a void * expression.
> > + *   - In a ternary expression:
> > + *       condition ? operand1 : operand2
> > + *     if one of the two operands is of type void * and the other one
> > + *     some other pointer type, the C11 standard defines in ?6.5.15.6
> > + *     the resulting type as below:
> > + *       if one operand is a null pointer constant, the result has the
> > + *       type of the other operand; otherwise [...] the result type is
> > + *       a pointer to an appropriately qualified version of void.
> > + *   - As such, in
> > + *       0 ? (void *)(x) : (char *)0
> > + *     if x is the integer constant expression 0, operand1 is a null
> > + *     pointer constant and the resulting type is that of operand2:
> > + *     char *. If x is anything else, the type is void *.
> > + *   - The (long) cast silences a compiler warning for when x is not 0.
> > + *   - Finally, the _Generic() dispatches the resulting type into a
> > + *     Boolean.
>
> The comment is absolutely excessive.
> I'm sure I managed about 2 lines in one of the patches I did.

I think that Linus made it  clear in:

  https://lore.kernel.org/all/CAHk-=wgfpLdt7SFFGcByTfHdkvv7AEa3MDu_s_W1kfOxQs49pw at mail.gmail.com/

that this deserves a detailed comment.

The details block in the current __is_constexpr() is 37 lines long,
the details block in __is_const_zero() takes 22 lines. So I would
argue that I made things better.

Unless more people share your concern, I am planning to keep this comment as-is.

> > + *
> > + * Glory to Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
>
> IIRC Martin has agreed in the past that the accreditation can
> be removed - especially since it refers to the 'sizeof (void)' trick.

I tried to look for such message:

  https://lore.kernel.org/all/?q=f%3A%22martin+uecker%22+__is_constexpr

but couldn't find it. Do you have the link?

@Martin, do you agree that I remove the accreditation?

> > + */
> > +#define __is_const_zero(x) \
> > +     _Generic(0 ? (void *)(long)(x) : (char *)0, char *: 1, void *: 0)
> > +
> > +/*
> > + * Returns a constant expression while determining if its argument is a
> > + * constant expression, most importantly without evaluating the argument.
>
> You need to differentiate between a 'constant integer expression'
> and a 'compile time constant'.

OK. This one was just copied from the previous __is_constexpr(). I will apply
"s/constant expression/constant integer expression/g" in v2.

> > + *
> > + * If getting a constant expression is not relevant to you, use the more
> > + * powerful __builtin_constant_p() instead.
>
> __builtin_constant_p() is not 'more powerful' it is testing for
> something different.

I meant to say that __builtin_constant_p() is more powerful at
constant folding. But I agree that the comment is not clear.

What about this?

  If getting a constant integer expression is not relevant to you, use
  __builtin_constant_p() which not only returns true if the argument
  is an integer constant expression, but also if it is a compile time
  constant.


Yours sincerely,
Vincent Mailhol


From mailhol.vincent at wanadoo.fr  Thu Dec  5 07:56:35 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 00:56:35 +0900
Subject: [PATCH 08/10] drm/i915/reg: replace __is_const_expr() by
 is_const_true() or is_const()
In-Reply-To: <6597979088eb4ee7b98cfb99815a402e@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-8-4e4cbaecc216@wanadoo.fr> <6597979088eb4ee7b98cfb99815a402e@AcuMS.aculab.com>
Message-ID: <CAMZ6Rq+XhOb+yn5A1dHD=qkbB1_FQXMA7_ydBB4nPTSnys3jkA@mail.gmail.com>

On Thu. 5 Dec 2024 at 04:00, David Laight <David.Laight at aculab.com> wrote:
> From: Vincent Mailhol
> > Sent: 02 December 2024 17:34
> >
> > Most of the use of __is_const_expr() in i915_reg_defs.h are just to
> > test whether an expression is known to be true. Because those checks
> > are all done in a BUILD_BUG_ON_ZERO(), replace those with
> > is_const_true().
>
> Another place that could use statically_true() and BUILD_BUG_ON_MSG().

Here also, BUILD_BUG_ON_MSG() is not suitable because it does not
return a value.

__BUILD_BUG_ON_ZERO_MSG() could be used; but there is less benefit to
do this at a driver scope. In this i915_reg_defs.h,
BUILD_BUG_ON_ZERO() is used 20 times. Adding an error message each
time will just make things ugly.

If we want more readable error messages here, the solution for me is
just to redefine BUILD_BUG_ON_ZERO() to print a more meaningful error
message by default. But this is not the scope of this series. I sent a
separate patch for this:

  https://lore.kernel.org/all/20241205151316.1480255-2-mailhol.vincent at wanadoo.fr/

Concerning statically_true() instead of is_const_true(), let me test,
and if this works, then I will replace these in v2.


Yours sincerely,
Vincent Mailhol


From dmitry.baryshkov at linaro.org  Thu Dec  5 11:35:23 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Dec 2024 21:35:23 +0200
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <a4a74f96-29cc-4007-9b03-f634b84d9cc2@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
 <4lvsvo6vsc7bipcgftsq3mzunwxoka3wjqad42ptr37oz77zub@5uarhvjmcxnc>
 <a4a74f96-29cc-4007-9b03-f634b84d9cc2@collabora.com>
Message-ID: <m7u6xzm2o4dmcjot4xfk6do4slikpsp6gi3uyiuw4d35kunbc5@jyzgkrp4xjwc>

On Thu, Dec 05, 2024 at 02:30:51PM +0100, AngeloGioacchino Del Regno wrote:
> Il 05/12/24 13:56, Dmitry Baryshkov ha scritto:
> > On Thu, Dec 05, 2024 at 12:45:17PM +0100, AngeloGioacchino Del Regno wrote:
> > > Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> > > found in MediaTek's MT8195, MT8188 SoC and their variants, and
> > > including support for display modes up to 4k60 and for HDMI
> > > Audio, as per the HDMI 2.0 spec.
> > > 
> > > HDCP and CEC functionalities are also supported by this hardware,
> > > but are not included in this commit and that also poses a slight
> > > difference between the V2 and V1 controllers in how they handle
> > > Hotplug Detection (HPD).
> > > 
> > > While the v1 controller was using the CEC controller to check
> > > HDMI cable connection and disconnection, in this driver the v2
> > > one does not.
> > > 
> > > This is due to the fact that on parts with v2 designs, like the
> > > MT8195 SoC, there is one CEC controller shared between the HDMI
> > > Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> > > adding support to use the CEC HW to wake up the HDMI controllers
> > > it is necessary to have support for one TX, one RX *and* for both
> > > at the same time.
> > > 
> > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > > ---
> > >   drivers/gpu/drm/mediatek/Kconfig            |    8 +
> > >   drivers/gpu/drm/mediatek/Makefile           |    4 +
> > >   drivers/gpu/drm/mediatek/mtk_hdmi_common.c  |    5 +
> > >   drivers/gpu/drm/mediatek/mtk_hdmi_common.h  |    1 +
> > >   drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c  |  403 +++++
> > >   drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h |  263 ++++
> > >   drivers/gpu/drm/mediatek/mtk_hdmi_v2.c      | 1488 +++++++++++++++++++
> > >   7 files changed, 2172 insertions(+)
> > >   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
> > >   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
> > >   create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
> > > 
> 
> ..snip..
> 
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
> > > new file mode 100644
> > > index 000000000000..05cbfc45be54
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
> > > @@ -0,0 +1,1488 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> 
> ..snip..
> 
> > > +static int mtk_hdmi_v2_setup_audio_infoframe(struct mtk_hdmi *hdmi)
> > > +{
> > > +	struct hdmi_codec_params *params = &hdmi->aud_param.codec_params;
> > > +	struct hdmi_audio_infoframe frame;
> > > +	u8 buffer[14];
> > > +	ssize_t ret;
> > > +
> > > +	memcpy(&frame, &params->cea, sizeof(frame));
> > > +
> > > +	ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
> > 
> > This should be handled via HDMI Connector framework too. There is
> > already an interface to set / clear audio infoframes.
> > als I have been working on an interface to make HDMI codec
> > implementation more generic, see [1]. Your comments are appreciated.
> > 
> > [1] https://patchwork.freedesktop.org/series/134927/
> > 
> 
> I didn't go for that because I was afraid that your series wouldn't actually
> land in the same window as this driver.

There were two points in my comment (sorry for being not explicit
enough). One is to point to the HDMI codec infra (and you are right,
it's not yet in the mergeable state). Second one is to use
drm_atomic_helper_connector_hdmi_update_audio_infoframe() and
drm_atomic_helper_connector_hdmi_clear_audio_infoframe() if possible (it
might be hard to do it - in fact it being hard kind of forced me to
work on the HDMI codec infra).

> I am at this point puzzled to whether I should add a commit on top of this
> submission that switches this driver to using the generic HDMI Codec infra
> (which could also be helpful as guidance to others trying to do the same on
> other drivers, I guess), or if I should just rebase on top of that.

I'd say, a completely separate patch might be even better, I can then
integrate it into the HDMI codec patchset, adding a soft dependency on
your series. If for some reason the codec lands earlier than your
patchset, the patch can be dropped and reintegrated into your series. Or
just committed separately.

> I'd rather add a commit on top to mainly avoid risking to delay this driver,
> but if you're absolutely certain that you can get your series merged in the
> same window as this driver I have *zero* problems in just rebasing on top.
> 
> Besides...
> 
> I'll find the time to review your series - I'm sad it didn't land earlier as
> I would've written a bit less code otherwise :-)
> 
> > > +
> > > +	return 0;
> > > +}
> > > +
> 
> ..snip..
> 
> > > +
> > > +	/* Enable the controller at attach time for HPD/Pord feedback */
> > > +	ret = mtk_hdmi_v2_enable(hdmi);
> > > +	if (ret)
> > > +		return ret;
> > 
> > This looks like a hack. Please use .hpd_enable() / .hpd_disable()
> > callbacks.
> > 
> 
> ...but there's no way to power on only the HPD - you can either power on
> the entire controller, or nothing.
> 
> I can't call mtk_hdmi_v2_enable/disable() from the HPD callbacks.

Why? Add a powerup refcount if necessary.

> 
> Perhaps the comment should have been
> 
> "Enable the controller attach time also allows HPD/Pord feedback"?

I think it should still be explicit call from those callbacks. Consider
a platform using external GPIO to implement HPD. Then the HDMI
controller can stay disabled if it is not necessary.

> 
> > > +
> > > +	/* Enable Hotplug and Pord pins internal debouncing */
> > > +	regmap_set_bits(hdmi->regs, HPD_DDC_CTRL,
> > > +			HPD_DDC_HPD_DBNC_EN | HPD_DDC_PORD_DBNC_EN);
> > > +
> > > +	irq_clear_status_flags(hdmi->irq, IRQ_NOAUTOEN);
> > > +	enable_irq(hdmi->irq);
> > > +
> > > +	/*
> > > +	 * Check if any HDMI monitor was connected before probing this driver
> > > +	 * and/or attaching the bridge, without debouncing: if so, we want to
> > > +	 * notify the DRM so that we start outputting an image ASAP.
> > > +	 * Note that calling the ISR thread function will also perform a HW
> > > +	 * registers write that enables both the HPD and Pord interrupts.
> > > +	 */
> > > +	__mtk_hdmi_v2_isr_thread(hdmi);
> > > +
> > > +	return 0;
> > > +}
> > > +
> 
> ..snip..
> 
> > > +static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
> > > +					  struct drm_bridge_state *old_state)
> > > +{
> > > +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> > > +	struct drm_atomic_state *state = old_state->base.state;
> > > +	struct drm_connector_state *conn_state;
> > > +	union phy_configure_opts opts = {
> > > +		.dp = { .link_rate = hdmi->mode.clock * KILO }
> > > +	};
> > > +
> > > +	/* Retrieve the connector through the atomic state */
> > > +	hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
> > > +
> > > +	conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
> > > +	if (WARN_ON(!conn_state))
> > > +		return;
> > > +
> > > +	/*
> > > +	 * Preconfigure the HDMI controller and the HDMI PHY at pre_enable
> > > +	 * stage to make sure that this IP is ready and clocked before the
> > > +	 * mtk_dpi gets powered on and before it enables the output.
> > > +	 */
> > > +	hdmi->dvi_mode = !hdmi->curr_conn->display_info.is_hdmi;
> > 
> > Can you access display_info directly instead?
> > 
> 
> Nice catch. Yeah, I should've done that from the beginning. Fixed for v3.
> 
> > > +	mtk_hdmi_v2_output_set_display_mode(hdmi, &hdmi->mode);
> > > +
> > > +	/* Reconfigure phy clock link with appropriate rate */
> > > +	phy_configure(hdmi->phy, &opts);
> > > +
> > > +	/* Power on the PHY here to make sure that DPI_HDMI is clocked */
> > > +	phy_power_on(hdmi->phy);
> > > +
> > > +	hdmi->powered = true;
> > > +}
> > > +
> > > +static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
> > > +				      struct drm_bridge_state *old_state)
> > > +{
> > > +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> > > +	struct drm_atomic_state *state = old_state->base.state;
> > > +	int ret;
> > > +
> > > +	ret = drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
> > > +	if (ret)
> > > +		dev_err(hdmi->dev, "Could not update infoframes: %d\n", ret);
> > > +
> > > +	mtk_hdmi_v2_hw_vid_mute(hdmi, false);
> > > +	mtk_hdmi_v2_hw_aud_mute(hdmi, false);
> > > +
> > > +	/* signal the connect event to audio codec */
> > > +	mtk_hdmi_v2_handle_plugged_change(hdmi, true);
> > 
> > I think it was agreed that this should be called from the hotplug path,
> > see the (linked) HDMI codec infrastructure patchset and dicussions for
> > the previous revisions.
> > 
> 
> Okay, I'll check that out.
> 
> > > +
> > > +	hdmi->enabled = true;
> > > +}
> > > +
> 
> ..snip..
> 
> > > +
> > > +static int mtk_hdmi_v2_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > > +						 const struct drm_display_mode *mode,
> > > +						 unsigned long long tmds_rate)
> > > +{
> > > +	if (mode->clock < MTK_HDMI_V2_CLOCK_MIN)
> > > +		return MODE_CLOCK_LOW;
> > > +	else if (mode->clock > MTK_HDMI_V2_CLOCK_MAX)
> > > +		return MODE_CLOCK_HIGH;
> > > +	else
> > > +		return MODE_OK;
> > > +}
> > > +
> > > +static enum drm_mode_status
> > > +mtk_hdmi_v2_bridge_mode_valid(struct drm_bridge *bridge,
> > > +			      const struct drm_display_info *info,
> > > +			      const struct drm_display_mode *mode)
> > > +{
> > > +	unsigned long long rate;
> > > +
> > > +	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
> > > +	return mtk_hdmi_v2_hdmi_tmds_char_rate_valid(bridge, mode, rate);
> > > +}
> > 
> > Please rebase on top of https://patchwork.freedesktop.org/series/140193/
> > There should be no need to do this manually.
> > 
> 
> Oh finally there's a helper for this. Cool, will rebase! Thanks!

And it doesn't even add an extra dependency for you.

> 
> > > +
> > > +static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge,
> > > +					    enum hdmi_infoframe_type type)
> > > +{
> > > +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> > > +	u32 reg_start, reg_end;
> > > +
> > > +	switch (type) {
> > > +	case HDMI_INFOFRAME_TYPE_AUDIO:
> > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
> > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
> > > +		reg_start = TOP_AIF_HEADER;
> > > +		reg_end = TOP_AIF_PKT03;
> > > +		break;
> > > +	case HDMI_INFOFRAME_TYPE_AVI:
> > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
> > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
> > > +		reg_start = TOP_AVI_HEADER;
> > > +		reg_end = TOP_AVI_PKT05;
> > > +		break;
> > > +	case HDMI_INFOFRAME_TYPE_SPD:
> > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
> > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
> > > +		reg_start = TOP_SPDIF_HEADER;
> > > +		reg_end = TOP_SPDIF_PKT07;
> > > +		break;
> > > +	case HDMI_INFOFRAME_TYPE_VENDOR:
> > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
> > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
> > > +		reg_start = TOP_VSIF_HEADER;
> > > +		reg_end = TOP_VSIF_PKT07;
> > > +		break;
> > > +	case HDMI_INFOFRAME_TYPE_DRM:
> > > +	default:
> > > +		return 0;
> > > +	};
> > > +
> > > +	for (; reg_start <= reg_end; reg_start += 4)
> > > +		regmap_write(hdmi->regs, reg_start, 0);
> > 
> > Interesting. Usually sending of the infoframe is controlled by a
> > register of a kind.
> > 
> 
> "This callback clears the infoframes in the hardware during commit"
> 
> ...and that's exactly what this function does: clears the infoframes
> in the HW and stops the RPT, making the HW ready for the "next round".
> 
> Did I get the documentation wrong?
> Should this function *send* an all-zero infoframe to the external display?

No, it should stop sending the callback. My point was that usually there
is a separate register which controls the infoframes. You code just
clears the header (which probably is handled as disabling in the IP
core).

> 
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge,
> > > +					    enum hdmi_infoframe_type type,
> > > +					    const u8 *buffer, size_t len)
> > > +{
> > > +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> > > +
> > > +	switch (type) {
> > > +	case HDMI_INFOFRAME_TYPE_AUDIO:
> > > +		mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
> > > +		break;
> > > +	case HDMI_INFOFRAME_TYPE_AVI:
> > > +		mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer);
> > > +		break;
> > > +	case HDMI_INFOFRAME_TYPE_SPD:
> > > +		mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer);
> > > +		break;
> > > +	case HDMI_INFOFRAME_TYPE_VENDOR:
> > > +		mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer);
> > > +		break;
> > > +	case HDMI_INFOFRAME_TYPE_DRM:
> > > +	default:
> > > +		dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type);
> > > +		break;
> > > +	};
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int mtk_hdmi_v2_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)
> > > +{
> > > +	return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
> > > +						      conn_state->state);
> > > +}
> > 
> > Note to myself, probably we can move this to drm_bridge_connector too.
> > 
> > > +
> > > +static int mtk_hdmi_v2_set_abist(struct mtk_hdmi *hdmi, bool enable)
> > > +{
> > > +	struct drm_display_mode *mode = &hdmi->mode;
> > > +	int abist_format = -EINVAL;
> > > +	bool interlaced;
> > > +
> > > +	if (!enable) {
> > > +		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
> > > +		return 0;
> > > +	}
> > > +
> > > +	if (!mode->hdisplay || !mode->vdisplay)
> > > +		return -EINVAL;
> > > +
> > > +	interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
> > 
> > The interlaced modes should be filtered, unless you also set
> > bridge->interlace_allowed to true.
> > 
> 
> Noted. Many Thanks for the review!
> 
> I'll wait until next week for more feedback before sending a v3.

-- 
With best wishes
Dmitry


From igor.belwon at mentallysanemainliners.org  Thu Dec  5 11:34:20 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Thu,  5 Dec 2024 20:34:20 +0100
Subject: v1-0000-cover-letter.patchFrom 10d9a244391bcf592fd3e5fd902bae7f01cb4d4b Mon
Message-ID: <20241205193423.783815-1-igor.belwon@mentallysanemainliners.org>

Hi all,

This patchset adds support for the Clock Management Unit found in the
Exynos990 SoC. This CMU allows for clocking peripherals such as USB, UFS,
MCT, et cetera.

Currently there are two blocks implemented, CMU_TOP which
generates clocks for other blocks, and CMU_HSI0, which generates clocks
for USB. More blocks will be added (hopefully soon), like HSI1 for UFS.

Best regards

Igor

Igor Belwon (3):
  dt-bindings: clock: Add Exynos990 SoC CMU bindings
  clk: samsung: clk-pll: Add support for pll_{0717x, 0718x, 0732x}
  clk: samsung: Introduce Exynos990 clock controller driver

 .../clock/samsung,exynos990-clock.yaml        |  120 ++
 drivers/clk/samsung/Makefile                  |    1 +
 drivers/clk/samsung/clk-exynos990.c           | 1343 +++++++++++++++++
 drivers/clk/samsung/clk-pll.c                 |   14 +-
 drivers/clk/samsung/clk-pll.h                 |    3 +
 include/dt-bindings/clock/exynos990.h         |  236 +++
 6 files changed, 1715 insertions(+), 2 deletions(-)
 create mode 100644
Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
 create mode 100644 drivers/clk/samsung/clk-exynos990.c
 create mode 100644 include/dt-bindings/clock/exynos990.h

--
2.45.2


From igor.belwon at mentallysanemainliners.org  Thu Dec  5 11:34:21 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Thu,  5 Dec 2024 20:34:21 +0100
Subject: [PATCH v1 1/3] dt-bindings: clock: Add Exynos990 SoC CMU bindings
In-Reply-To: <20241205193423.783815-1-igor.belwon@mentallysanemainliners.org>
References: <20241205193423.783815-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241205193423.783815-2-igor.belwon@mentallysanemainliners.org>

Add dt-schema documentation for the Exynos990 SoC CMU.

This clock management unit has a topmost block (CMU_TOP)
that generates top clocks for other blocks. Currently the
only other block implemented is CMU_HSI0, which provides
clocks for the USB part of the SoC.

Also, device-tree binding definitions added for these blocks:
- CMU_TOP
- CMU_HSI0

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 .../clock/samsung,exynos990-clock.yaml        | 120 +++++++++
 include/dt-bindings/clock/samsung,exynos990.h | 236 ++++++++++++++++++
 2 files changed, 356 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
 create mode 100644 include/dt-bindings/clock/samsung,exynos990.h

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
new file mode 100644
index 000000000000..36d70d6d1b30
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos990-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos990 SoC clock controller
+
+maintainers:
+  - Igor Belwon <igor.belwon at mentallysanemainliners.org>
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzk at kernel.org>
+
+description: |
+  Exynos990 clock controller is comprised of several CMU units, generating
+  clocks for different domains. Those CMU units are modeled as separate device
+  tree nodes, and might depend on each other. The root clock in that root tree
+  is an external clock: OSCCLK (26 MHz). This external clock must be defined
+  as a fixed-rate clock in dts.
+
+  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
+  dividers; all other clocks of function blocks (other CMUs) are usually
+  derived from CMU_TOP.
+
+  Each clock is assigned an identifier and client nodes can use this identifier
+  to specify the clock which they consume. All clocks available for usage
+  in clock consumer nodes are defined as preprocessor macros in
+  'include/dt-bindings/clock/samsung,exynos990.h' header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos990-cmu-hsi0
+      - samsung,exynos990-cmu-top
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - reg
+  - "#clock-cells"
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos990-cmu-hsi0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_HSI0 BUS clock (from CMU_TOP)
+            - description: CMU_HSI0 USB31DRD clock (from CMU_TOP)
+            - description: CMU_HSI0 USBDP_DEBUG clock (from CMU_TOP)
+            - description: CMU_HSI0 DPGTC clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_cmu_hsi0_bus
+            - const: dout_cmu_hsi0_usb31drd
+            - const: dout_cmu_hsi0_usbdp_debug
+            - const: dout_cmu_hsi0_dpgtc
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos990-cmu-top
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+
+        clock-names:
+          items:
+            - const: oscclk
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/samsung,exynos990.h>
+
+    cmu_hsi0: clock-controller at 10a00000 {
+        compatible = "samsung,exynos990-cmu-hsi0";
+        reg = <0x10a00000 0x8000>;
+        #clock-cells = <1>;
+
+        clocks = <&oscclk>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
+        clock-names = "oscclk", "dout_cmu_hsi0_bus",
+                                "dout_cmu_hsi0_usb31drd",
+                                "dout_cmu_hsi0_usbdp_debug",
+                                "dout_cmu_hsi0_dpgtc";
+    };
+
+...
diff --git a/include/dt-bindings/clock/samsung,exynos990.h b/include/dt-bindings/clock/samsung,exynos990.h
new file mode 100644
index 000000000000..307215a3f3ed
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,exynos990.h
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2024 Igor Belwon <igor.belwon at mentallysanemainliners.org>
+ *
+ * Device Tree binding constants for Exynos990 clock controller.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_EXYNOS_990_H
+#define _DT_BINDINGS_CLOCK_EXYNOS_990_H
+
+/* CMU_TOP */
+#define CLK_FOUT_SHARED0_PLL		1
+#define CLK_FOUT_SHARED1_PLL		2
+#define CLK_FOUT_SHARED2_PLL		3
+#define CLK_FOUT_SHARED3_PLL		4
+#define CLK_FOUT_SHARED4_PLL		5
+#define CLK_FOUT_G3D_PLL		6
+#define CLK_FOUT_MMC_PLL		7
+#define CLK_MOUT_PLL_SHARED0		8
+#define CLK_MOUT_PLL_SHARED1		9
+#define CLK_MOUT_PLL_SHARED2		10
+#define CLK_MOUT_PLL_SHARED3		11
+#define CLK_MOUT_PLL_SHARED4		12
+#define CLK_MOUT_PLL_MMC		13
+#define CLK_MOUT_PLL_G3D		14
+#define CLK_MOUT_CMU_APM_BUS		15
+#define CLK_MOUT_CMU_AUD_CPU		16
+#define CLK_MOUT_CMU_BUS0_BUS		17
+#define CLK_MOUT_CMU_BUS1_BUS		18
+#define CLK_MOUT_CMU_BUS1_SSS		19
+#define CLK_MOUT_CMU_CIS_CLK0		20
+#define CLK_MOUT_CMU_CIS_CLK1		21
+#define CLK_MOUT_CMU_CIS_CLK2		22
+#define CLK_MOUT_CMU_CIS_CLK3		23
+#define CLK_MOUT_CMU_CIS_CLK4		24
+#define CLK_MOUT_CMU_CIS_CLK5		25
+#define CLK_MOUT_CMU_CMU_BOOST		26
+#define CLK_MOUT_CMU_CORE_BUS		27
+#define CLK_MOUT_CMU_CPUCL0_DBG_BUS	28
+#define CLK_MOUT_CMU_CPUCL0_SWITCH	29
+#define CLK_MOUT_CMU_CPUCL1_SWITCH	30
+#define CLK_MOUT_CMU_CPUCL2_BUSP	31
+#define CLK_MOUT_CMU_CPUCL2_SWITCH	32
+#define CLK_MOUT_CMU_CSIS_BUS		33
+#define CLK_MOUT_CMU_CSIS_OIS_MCU	34
+#define CLK_MOUT_CMU_DNC_BUS		35
+#define CLK_MOUT_CMU_DNC_BUSM		36
+#define CLK_MOUT_CMU_DNS_BUS		37
+#define CLK_MOUT_CMU_DPU		38
+#define CLK_MOUT_CMU_DPU_ALT		39
+#define CLK_MOUT_CMU_DSP_BUS		40
+#define CLK_MOUT_CMU_G2D_G2D		41
+#define CLK_MOUT_CMU_G2D_MSCL		42
+#define CLK_MOUT_CMU_HPM		43
+#define CLK_MOUT_CMU_HSI0_BUS		44
+#define CLK_MOUT_CMU_HSI0_DPGTC		45
+#define CLK_MOUT_CMU_HSI0_USB31DRD	46
+#define CLK_MOUT_CMU_HSI0_USBDP_DEBUG	47
+#define CLK_MOUT_CMU_HSI1_BUS		48
+#define CLK_MOUT_CMU_HSI1_MMC_CARD	49
+#define CLK_MOUT_CMU_HSI1_PCIE		50
+#define CLK_MOUT_CMU_HSI1_UFS_CARD	51
+#define CLK_MOUT_CMU_HSI1_UFS_EMBD	52
+#define CLK_MOUT_CMU_HSI2_BUS		53
+#define CLK_MOUT_CMU_HSI2_PCIE		54
+#define CLK_MOUT_CMU_IPP_BUS		55
+#define CLK_MOUT_CMU_ITP_BUS		56
+#define CLK_MOUT_CMU_MCSC_BUS		57
+#define CLK_MOUT_CMU_MCSC_GDC		58
+#define CLK_MOUT_CMU_CMU_BOOST_CPU	59
+#define CLK_MOUT_CMU_MFC0_MFC0		60
+#define CLK_MOUT_CMU_MFC0_WFD		61
+#define CLK_MOUT_CMU_MIF_BUSP		62
+#define CLK_MOUT_CMU_MIF_SWITCH		63
+#define CLK_MOUT_CMU_NPU_BUS		64
+#define CLK_MOUT_CMU_PERIC0_BUS		65
+#define CLK_MOUT_CMU_PERIC0_IP		66
+#define CLK_MOUT_CMU_PERIC1_BUS		67
+#define CLK_MOUT_CMU_PERIC1_IP		68
+#define CLK_MOUT_CMU_PERIS_BUS		69
+#define CLK_MOUT_CMU_SSP_BUS		70
+#define CLK_MOUT_CMU_TNR_BUS		71
+#define CLK_MOUT_CMU_VRA_BUS		72
+#define CLK_DOUT_CMU_APM_BUS		73
+#define CLK_DOUT_CMU_AUD_CPU		74
+#define CLK_DOUT_CMU_BUS0_BUS		75
+#define CLK_DOUT_CMU_BUS1_BUS		76
+#define CLK_DOUT_CMU_BUS1_SSS		77
+#define CLK_DOUT_CMU_CIS_CLK0		78
+#define CLK_DOUT_CMU_CIS_CLK1		79
+#define CLK_DOUT_CMU_CIS_CLK2		80
+#define CLK_DOUT_CMU_CIS_CLK3		81
+#define CLK_DOUT_CMU_CIS_CLK4		82
+#define CLK_DOUT_CMU_CIS_CLK5		83
+#define CLK_DOUT_CMU_CMU_BOOST		84
+#define CLK_DOUT_CMU_CORE_BUS		85
+#define CLK_DOUT_CMU_CPUCL0_DBG_BUS	86
+#define CLK_DOUT_CMU_CPUCL0_SWITCH	87
+#define CLK_DOUT_CMU_CPUCL1_SWITCH	88
+#define CLK_DOUT_CMU_CPUCL2_BUSP	89
+#define CLK_DOUT_CMU_CPUCL2_SWITCH	90
+#define CLK_DOUT_CMU_CSIS_BUS		91
+#define CLK_DOUT_CMU_CSIS_OIS_MCU	92
+#define CLK_DOUT_CMU_DNC_BUS		93
+#define CLK_DOUT_CMU_DNC_BUSM		94
+#define CLK_DOUT_CMU_DNS_BUS		95
+#define CLK_DOUT_CMU_DSP_BUS		96
+#define CLK_DOUT_CMU_G2D_G2D		97
+#define CLK_DOUT_CMU_G2D_MSCL		98
+#define CLK_DOUT_CMU_G3D_SWITCH		99
+#define CLK_DOUT_CMU_HPM		100
+#define CLK_DOUT_CMU_HSI0_BUS		101
+#define CLK_DOUT_CMU_HSI0_DPGTC		102
+#define CLK_DOUT_CMU_HSI0_USB31DRD	103
+#define CLK_DOUT_CMU_HSI0_USBDP_DEBUG	104
+#define CLK_DOUT_CMU_HSI1_BUS		105
+#define CLK_DOUT_CMU_HSI1_MMC_CARD	106
+#define CLK_DOUT_CMU_HSI1_PCIE		107
+#define CLK_DOUT_CMU_HSI1_UFS_CARD	108
+#define CLK_DOUT_CMU_HSI1_UFS_EMBD	109
+#define CLK_DOUT_CMU_HSI2_BUS		110
+#define CLK_DOUT_CMU_HSI2_PCIE		111
+#define CLK_DOUT_CMU_IPP_BUS		112
+#define CLK_DOUT_CMU_ITP_BUS		113
+#define CLK_DOUT_CMU_MCSC_BUS		114
+#define CLK_DOUT_CMU_MCSC_GDC		115
+#define CLK_DOUT_CMU_CMU_BOOST_CPU	116
+#define CLK_DOUT_CMU_MFC0_MFC0		117
+#define CLK_DOUT_CMU_MFC0_WFD		118
+#define CLK_DOUT_CMU_MIF_BUSP		119
+#define CLK_DOUT_CMU_NPU_BUS		120
+#define CLK_DOUT_CMU_OTP		121
+#define CLK_DOUT_CMU_PERIC0_BUS		122
+#define CLK_DOUT_CMU_PERIC0_IP		123
+#define CLK_DOUT_CMU_PERIC1_BUS		124
+#define CLK_DOUT_CMU_PERIC1_IP		125
+#define CLK_DOUT_CMU_PERIS_BUS		126
+#define CLK_DOUT_CMU_SSP_BUS		127
+#define CLK_DOUT_CMU_TNR_BUS		128
+#define CLK_DOUT_CMU_VRA_BUS		129
+#define CLK_DOUT_CMU_DPU		130
+#define CLK_DOUT_CMU_DPU_ALT		131
+#define CLK_DOUT_CMU_SHARED0_DIV2	132
+#define CLK_DOUT_CMU_SHARED0_DIV3	133
+#define CLK_DOUT_CMU_SHARED0_DIV4	134
+#define CLK_DOUT_CMU_SHARED1_DIV2	135
+#define CLK_DOUT_CMU_SHARED1_DIV3	136
+#define CLK_DOUT_CMU_SHARED1_DIV4	137
+#define CLK_DOUT_CMU_SHARED2_DIV2	138
+#define CLK_DOUT_CMU_SHARED4_DIV2	139
+#define CLK_DOUT_CMU_SHARED4_DIV3	140
+#define CLK_DOUT_CMU_SHARED4_DIV4	141
+#define CLK_GOUT_CMU_G3D_BUS		142
+#define CLK_GOUT_CMU_MIF_SWITCH		143
+#define CLK_GOUT_CMU_APM_BUS		144
+#define CLK_GOUT_CMU_AUD_CPU		145
+#define CLK_GOUT_CMU_BUS0_BUS		146
+#define CLK_GOUT_CMU_BUS1_BUS		147
+#define CLK_GOUT_CMU_BUS1_SSS		148
+#define CLK_GOUT_CMU_CIS_CLK0		149
+#define CLK_GOUT_CMU_CIS_CLK1		150
+#define CLK_GOUT_CMU_CIS_CLK2		151
+#define CLK_GOUT_CMU_CIS_CLK3		152
+#define CLK_GOUT_CMU_CIS_CLK4		153
+#define CLK_GOUT_CMU_CIS_CLK5		154
+#define CLK_GOUT_CMU_CORE_BUS		155
+#define CLK_GOUT_CMU_CPUCL0_DBG_BUS	156
+#define CLK_GOUT_CMU_CPUCL0_SWITCH	157
+#define CLK_GOUT_CMU_CPUCL1_SWITCH	158
+#define CLK_GOUT_CMU_CPUCL2_BUSP	159
+#define CLK_GOUT_CMU_CPUCL2_SWITCH	160
+#define CLK_GOUT_CMU_CSIS_BUS		161
+#define CLK_GOUT_CMU_CSIS_OIS_MCU	162
+#define CLK_GOUT_CMU_DNC_BUS		163
+#define CLK_GOUT_CMU_DNC_BUSM		164
+#define CLK_GOUT_CMU_DNS_BUS		165
+#define CLK_GOUT_CMU_DPU		166
+#define CLK_GOUT_CMU_DPU_BUS		167
+#define CLK_GOUT_CMU_DSP_BUS		168
+#define CLK_GOUT_CMU_G2D_G2D		169
+#define CLK_GOUT_CMU_G2D_MSCL		170
+#define CLK_GOUT_CMU_G3D_SWITCH		171
+#define CLK_GOUT_CMU_HPM		172
+#define CLK_GOUT_CMU_HSI0_BUS		173
+#define CLK_GOUT_CMU_HSI0_DPGTC		174
+#define CLK_GOUT_CMU_HSI0_USB31DRD	175
+#define CLK_GOUT_CMU_HSI0_USBDP_DEBUG	176
+#define CLK_GOUT_CMU_HSI1_BUS		177
+#define CLK_GOUT_CMU_HSI1_MMC_CARD	178
+#define CLK_GOUT_CMU_HSI1_PCIE		179
+#define CLK_GOUT_CMU_HSI1_UFS_CARD	180
+#define CLK_GOUT_CMU_HSI1_UFS_EMBD	181
+#define CLK_GOUT_CMU_HSI2_BUS		182
+#define CLK_GOUT_CMU_HSI2_PCIE		183
+#define CLK_GOUT_CMU_IPP_BUS		184
+#define CLK_GOUT_CMU_ITP_BUS		185
+#define CLK_GOUT_CMU_MCSC_BUS		186
+#define CLK_GOUT_CMU_MCSC_GDC		187
+#define CLK_GOUT_CMU_MFC0_MFC0		188
+#define CLK_GOUT_CMU_MFC0_WFD		189
+#define CLK_GOUT_CMU_MIF_BUSP		190
+#define CLK_GOUT_CMU_NPU_BUS		191
+#define CLK_GOUT_CMU_PERIC0_BUS		192
+#define CLK_GOUT_CMU_PERIC0_IP		193
+#define CLK_GOUT_CMU_PERIC1_BUS		194
+#define CLK_GOUT_CMU_PERIC1_IP		195
+#define CLK_GOUT_CMU_PERIS_BUS		196
+#define CLK_GOUT_CMU_SSP_BUS		197
+#define CLK_GOUT_CMU_TNR_BUS		198
+#define CLK_GOUT_CMU_VRA_BUS		199
+
+/* CMU_HSI0 */
+#define CLK_MOUT_HSI0_BUS_USER				1
+#define CLK_MOUT_HSI0_USB31DRD_USER			2
+#define CLK_MOUT_HSI0_USBDP_DEBUG_USER			3
+#define CLK_MOUT_HSI0_DPGTC_USER			4
+#define CLK_GOUT_HSI0_DP_LINK_DP_GTC_CLK		5
+#define CLK_GOUT_HSI0_DP_LINK_PCLK			6
+#define CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK			7
+#define CLK_GOUT_HSI0_LHM_AXI_P_HSI0_CLK		8
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_ACLK		9
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_PCLK		10
+#define CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK			11
+#define CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2			12
+#define CLK_GOUT_HSI0_SYSREG_HSI0_PCLK			13
+#define CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL		14
+#define CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY		15
+#define CLK_GOUT_HSI0_USB31DRD_USB31DRD_REF_CLK_40	16
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_REF_SOC_PLL	17
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_SCL_APB		18
+#define CLK_GOUT_HSI0_USB31DRD_USBPCS_APB_CLK		19
+#define CLK_GOUT_HSI0_VGEN_LITE_HSI0_CLK		20
+#define CLK_GOUT_HSI0_CMU_HSI0_PCLK			21
+#define CLK_GOUT_HSI0_XIU_D_HSI0_ACLK			22
+
+#endif
-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Thu Dec  5 11:34:22 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Thu,  5 Dec 2024 20:34:22 +0100
Subject: [PATCH v1 2/3] clk: samsung: clk-pll: Add support for pll_{0717x, 0718x, 0732x}
In-Reply-To: <20241205193423.783815-1-igor.belwon@mentallysanemainliners.org>
References: <20241205193423.783815-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241205193423.783815-3-igor.belwon@mentallysanemainliners.org>

These PLLs are found in the Exynos990 SoC. The PLLs are similar
to pll0822x.

pll0717x and pll0718x are an exception, and they use the mdiv
mask from 1718X (that is, one bit smaller).

Apart from that, the masks/shifts are identical to those of 0822x.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 drivers/clk/samsung/clk-pll.c | 14 ++++++++++++--
 drivers/clk/samsung/clk-pll.h |  3 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index be6b51694919..2e94bba6c396 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -430,7 +430,10 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {
 #define PLL0822X_LOCK_STAT_SHIFT	(29)
 #define PLL0822X_ENABLE_SHIFT		(31)
 
-/* PLL1418x is similar to PLL0822x, except that MDIV is one bit smaller */
+/*
+ * PLL1418x, PLL0717x and PLL0718x are similar
+ * to PLL0822x, except that MDIV is one bit smaller
+ */
 #define PLL1418X_MDIV_MASK		(0x1FF)
 
 static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
@@ -441,10 +444,14 @@ static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
 	u64 fvco = parent_rate;
 
 	pll_con3 = readl_relaxed(pll->con_reg);
-	if (pll->type != pll_1418x)
+
+	if (pll->type != pll_1418x &&
+	    pll->type != pll_0717x &&
+	    pll->type != pll_0718x)
 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
 	else
 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL1418X_MDIV_MASK;
+
 	pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
 	sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
 
@@ -1377,6 +1384,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_0516x:
 	case pll_0517x:
 	case pll_0518x:
+	case pll_0717x:
+	case pll_0718x:
+	case pll_0732x:
 		pll->enable_offs = PLL0822X_ENABLE_SHIFT;
 		pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
 		if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 858ab367eb65..6ddc54d173a0 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -45,6 +45,9 @@ enum samsung_pll_type {
 	pll_531x,
 	pll_1051x,
 	pll_1052x,
+	pll_0717x,
+	pll_0718x,
+	pll_0732x,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Thu Dec  5 11:34:23 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Thu,  5 Dec 2024 20:34:23 +0100
Subject: [PATCH v1 3/3] clk: samsung: Introduce Exynos990 clock controller driver
In-Reply-To: <20241205193423.783815-1-igor.belwon@mentallysanemainliners.org>
References: <20241205193423.783815-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241205193423.783815-4-igor.belwon@mentallysanemainliners.org>

The current implementation contains support for:
- CMU_TOP - which generates clocks for other blocks
- CMU_HSI0 - which generates clocks for USB31.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 drivers/clk/samsung/Makefile        |    1 +
 drivers/clk/samsung/clk-exynos990.c | 1343 +++++++++++++++++++++++++++
 2 files changed, 1344 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-exynos990.c

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 7a88331a658d..90e5b114872c 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7885.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos8895.o
+obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos990.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov9.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov920.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-gs101.o
diff --git a/drivers/clk/samsung/clk-exynos990.c b/drivers/clk/samsung/clk-exynos990.c
new file mode 100644
index 000000000000..b4c7c406c24d
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos990.c
@@ -0,0 +1,1343 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Igor Belwon <igor.belwon at mentallysanemainliners.org>
+ *
+ * Common Clock Framework support for Exynos990.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/exynos990.h>
+
+#include "clk.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_GOUT_CMU_VRA_BUS + 1)
+#define CLKS_NR_HSI0 (CLK_GOUT_HSI0_XIU_D_HSI0_ACLK + 1)
+
+/* ---- CMU_TOP ------------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_TOP (0x1a330000) */
+#define PLL_LOCKTIME_PLL_G3D				0x0000
+#define PLL_LOCKTIME_PLL_MMC				0x0004
+#define PLL_LOCKTIME_PLL_SHARED0			0x0008
+#define PLL_LOCKTIME_PLL_SHARED1			0x000c
+#define PLL_LOCKTIME_PLL_SHARED2			0x0010
+#define PLL_LOCKTIME_PLL_SHARED3			0x0014
+#define PLL_LOCKTIME_PLL_SHARED4			0x0018
+#define PLL_CON0_PLL_G3D				0x0100
+#define PLL_CON3_PLL_G3D				0x010c
+#define PLL_CON0_PLL_MMC				0x0140
+#define PLL_CON3_PLL_MMC				0x014c
+#define PLL_CON0_PLL_SHARED0				0x0180
+#define PLL_CON3_PLL_SHARED0				0x018c
+#define PLL_CON0_PLL_SHARED1				0x01c0
+#define PLL_CON3_PLL_SHARED1				0x01cc
+#define PLL_CON0_PLL_SHARED2				0x0200
+#define PLL_CON3_PLL_SHARED2				0x020c
+#define PLL_CON0_PLL_SHARED3				0x0240
+#define PLL_CON3_PLL_SHARED3				0x024c
+#define PLL_CON0_PLL_SHARED4				0x0280
+#define PLL_CON3_PLL_SHARED4				0x028c
+#define CLK_CON_MUX_MUX_CLKCMU_APM_BUS			0x1004
+#define CLK_CON_MUX_MUX_CLKCMU_AUD_CPU			0x1008
+#define CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS			0x100c
+#define CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS			0x1010
+#define CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS			0x1014
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0			0x1018
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1			0x101c
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2			0x1020
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3			0x1024
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4			0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5			0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST		0x1030
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS			0x1034
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS		0x1038
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH		0x103c
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH		0x1040
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP		0x1044
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH		0x1048
+#define CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS			0x104c
+#define CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU		0x1050
+#define CLK_CON_MUX_MUX_CLKCMU_DNC_BUS			0x1054
+#define CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM			0x1058
+#define CLK_CON_MUX_MUX_CLKCMU_DNS_BUS			0x105c
+#define CLK_CON_MUX_MUX_CLKCMU_DPU			0x1060
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_ALT			0x1064
+#define CLK_CON_MUX_MUX_CLKCMU_DSP_BUS			0x1068
+#define CLK_CON_MUX_MUX_CLKCMU_G2D_G2D			0x106c
+#define CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL			0x1070
+#define CLK_CON_MUX_MUX_CLKCMU_HPM			0x1074
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS			0x1078
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC		0x107c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD		0x1080
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG		0x1084
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS			0x1088
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD		0x108c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE		0x1090
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD		0x1094
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD		0x1098
+#define CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS			0x109c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE		0x10a0
+#define CLK_CON_MUX_MUX_CLKCMU_IPP_BUS			0x10a4
+#define CLK_CON_MUX_MUX_CLKCMU_ITP_BUS			0x10a8
+#define CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS			0x10ac
+#define CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC			0x10b0
+#define CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU		0x10b4
+#define CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0		0x10b8
+#define CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD			0x10bc
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP			0x10c0
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH		0x10c4
+#define CLK_CON_MUX_MUX_CLKCMU_NPU_BUS			0x10c8
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS		0x10cc
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP		0x10d0
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS		0x10d4
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP		0x10d8
+#define CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS		0x10dc
+#define CLK_CON_MUX_MUX_CLKCMU_SSP_BUS			0x10e0
+#define CLK_CON_MUX_MUX_CLKCMU_TNR_BUS			0x10e4
+#define CLK_CON_MUX_MUX_CLKCMU_VRA_BUS			0x10e8
+#define CLK_CON_DIV_CLKCMU_APM_BUS			0x1800
+#define CLK_CON_DIV_CLKCMU_AUD_CPU			0x1804
+#define CLK_CON_DIV_CLKCMU_BUS0_BUS			0x1808
+#define CLK_CON_DIV_CLKCMU_BUS1_BUS			0x180c
+#define CLK_CON_DIV_CLKCMU_BUS1_SSS			0x1810
+#define CLK_CON_DIV_CLKCMU_CIS_CLK0			0x1814
+#define CLK_CON_DIV_CLKCMU_CIS_CLK1			0x1818
+#define CLK_CON_DIV_CLKCMU_CIS_CLK2			0x181c
+#define CLK_CON_DIV_CLKCMU_CIS_CLK3			0x1820
+#define CLK_CON_DIV_CLKCMU_CIS_CLK4			0x1824
+#define CLK_CON_DIV_CLKCMU_CIS_CLK5			0x1828
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST			0x182c
+#define CLK_CON_DIV_CLKCMU_CORE_BUS			0x1830
+#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS		0x1834
+#define CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH		0x1838
+#define CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH		0x183c
+#define CLK_CON_DIV_CLKCMU_CPUCL2_BUSP			0x1840
+#define CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH		0x1844
+#define CLK_CON_DIV_CLKCMU_CSIS_BUS			0x1848
+#define CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU			0x184c
+#define CLK_CON_DIV_CLKCMU_DNC_BUS			0x1850
+#define CLK_CON_DIV_CLKCMU_DNC_BUSM			0x1854
+#define CLK_CON_DIV_CLKCMU_DNS_BUS			0x1858
+#define CLK_CON_DIV_CLKCMU_DSP_BUS			0x185c
+#define CLK_CON_DIV_CLKCMU_G2D_G2D			0x1860
+#define CLK_CON_DIV_CLKCMU_G2D_MSCL			0x1864
+#define CLK_CON_DIV_CLKCMU_G3D_SWITCH			0x1868
+#define CLK_CON_DIV_CLKCMU_HPM				0x186c
+#define CLK_CON_DIV_CLKCMU_HSI0_BUS			0x1870
+#define CLK_CON_DIV_CLKCMU_HSI0_DPGTC			0x1874
+#define CLK_CON_DIV_CLKCMU_HSI0_USB31DRD		0x1878
+#define CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG		0x187c
+#define CLK_CON_DIV_CLKCMU_HSI1_BUS			0x1880
+#define CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD		0x1884
+#define CLK_CON_DIV_CLKCMU_HSI1_PCIE			0x1888
+#define CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD		0x188c
+#define CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD		0x1890
+#define CLK_CON_DIV_CLKCMU_HSI2_BUS			0x1894
+#define CLK_CON_DIV_CLKCMU_HSI2_PCIE			0x1898
+#define CLK_CON_DIV_CLKCMU_IPP_BUS			0x189c
+#define CLK_CON_DIV_CLKCMU_ITP_BUS			0x18a0
+#define CLK_CON_DIV_CLKCMU_MCSC_BUS			0x18a4
+#define CLK_CON_DIV_CLKCMU_MCSC_GDC			0x18a8
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU		0x18ac
+#define CLK_CON_DIV_CLKCMU_MFC0_MFC0			0x18b0
+#define CLK_CON_DIV_CLKCMU_MFC0_WFD			0x18b4
+#define CLK_CON_DIV_CLKCMU_MIF_BUSP			0x18b8
+#define CLK_CON_DIV_CLKCMU_NPU_BUS			0x18bc
+#define CLK_CON_DIV_CLKCMU_OTP				0x18c0
+#define CLK_CON_DIV_CLKCMU_PERIC0_BUS			0x18c4
+#define CLK_CON_DIV_CLKCMU_PERIC0_IP			0x18c8
+#define CLK_CON_DIV_CLKCMU_PERIC1_BUS			0x18cc
+#define CLK_CON_DIV_CLKCMU_PERIC1_IP			0x18d0
+#define CLK_CON_DIV_CLKCMU_PERIS_BUS			0x18d4
+#define CLK_CON_DIV_CLKCMU_SSP_BUS			0x18d8
+#define CLK_CON_DIV_CLKCMU_TNR_BUS			0x18dc
+#define CLK_CON_DIV_CLKCMU_VRA_BUS			0x18e0
+#define CLK_CON_DIV_DIV_CLKCMU_DPU			0x18e8
+#define CLK_CON_DIV_DIV_CLKCMU_DPU_ALT			0x18ec
+#define CLK_CON_DIV_PLL_SHARED0_DIV2			0x18f4
+#define CLK_CON_DIV_PLL_SHARED0_DIV3			0x18f8
+#define CLK_CON_DIV_PLL_SHARED0_DIV4			0x18fc
+#define CLK_CON_DIV_PLL_SHARED1_DIV2			0x1900
+#define CLK_CON_DIV_PLL_SHARED1_DIV3			0x1904
+#define CLK_CON_DIV_PLL_SHARED1_DIV4			0x1908
+#define CLK_CON_DIV_PLL_SHARED2_DIV2			0x190c
+#define CLK_CON_DIV_PLL_SHARED4_DIV2			0x1910
+#define CLK_CON_DIV_PLL_SHARED4_DIV3			0x1914
+#define CLK_CON_DIV_PLL_SHARED4_DIV4			0x1918
+#define CLK_CON_GAT_CLKCMU_G3D_BUS			0x2000
+#define CLK_CON_GAT_CLKCMU_MIF_SWITCH			0x2004
+#define CLK_CON_GAT_GATE_CLKCMU_APM_BUS			0x2008
+#define CLK_CON_GAT_GATE_CLKCMU_AUD_CPU			0x200c
+#define CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS		0x2010
+#define CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS		0x2014
+#define CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS		0x2018
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0		0x201c
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1		0x2020
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2		0x2024
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3		0x2028
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4		0x202c
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5		0x2030
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS		0x2034
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS		0x2038
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH		0x203c
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH		0x2040
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP		0x2044
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH		0x2048
+#define CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS		0x204c
+#define CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU		0x2050
+#define CLK_CON_GAT_GATE_CLKCMU_DNC_BUS			0x2054
+#define CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM		0x2058
+#define CLK_CON_GAT_GATE_CLKCMU_DNS_BUS			0x205c
+#define CLK_CON_GAT_GATE_CLKCMU_DPU			0x2060
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_BUS			0x2064
+#define CLK_CON_GAT_GATE_CLKCMU_DSP_BUS			0x2068
+#define CLK_CON_GAT_GATE_CLKCMU_G2D_G2D			0x206c
+#define CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL		0x2070
+#define CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH		0x2074
+#define CLK_CON_GAT_GATE_CLKCMU_HPM			0x2078
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS		0x207c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC		0x2080
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD		0x2084
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG	0x2088
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS		0x208c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD		0x2090
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE		0x2094
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD		0x2098
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD		0x209c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS		0x20a0
+#define CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE		0x20a4
+#define CLK_CON_GAT_GATE_CLKCMU_IPP_BUS			0x20a8
+#define CLK_CON_GAT_GATE_CLKCMU_ITP_BUS			0x20ac
+#define CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS		0x20b0
+#define CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC		0x20b4
+#define CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0		0x20bc
+#define CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD		0x20c0
+#define CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP		0x20c4
+#define CLK_CON_GAT_GATE_CLKCMU_NPU_BUS			0x20c8
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS		0x20cc
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP		0x20d0
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS		0x20d4
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP		0x20d8
+#define CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS		0x20dc
+#define CLK_CON_GAT_GATE_CLKCMU_SSP_BUS			0x20e0
+#define CLK_CON_GAT_GATE_CLKCMU_TNR_BUS			0x20e4
+#define CLK_CON_GAT_GATE_CLKCMU_VRA_BUS			0x20e8
+
+static const unsigned long top_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_G3D,
+	PLL_LOCKTIME_PLL_MMC,
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_LOCKTIME_PLL_SHARED2,
+	PLL_LOCKTIME_PLL_SHARED3,
+	PLL_LOCKTIME_PLL_SHARED4,
+	PLL_CON3_PLL_G3D,
+	PLL_CON3_PLL_MMC,
+	PLL_CON3_PLL_SHARED0,
+	PLL_CON3_PLL_SHARED1,
+	PLL_CON3_PLL_SHARED2,
+	PLL_CON3_PLL_SHARED3,
+	PLL_CON3_PLL_SHARED4,
+	CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_AUD_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5,
+	CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST,
+	CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_MUX_MUX_CLKCMU_DNC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM,
+	CLK_CON_MUX_MUX_CLKCMU_DNS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DPU,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_ALT,
+	CLK_CON_MUX_MUX_CLKCMU_DSP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_G2D_G2D,
+	CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL,
+	CLK_CON_MUX_MUX_CLKCMU_HPM,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE,
+	CLK_CON_MUX_MUX_CLKCMU_IPP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_ITP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC,
+	CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0,
+	CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_NPU_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_SSP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_TNR_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_VRA_BUS,
+	CLK_CON_DIV_CLKCMU_APM_BUS,
+	CLK_CON_DIV_CLKCMU_AUD_CPU,
+	CLK_CON_DIV_CLKCMU_BUS0_BUS,
+	CLK_CON_DIV_CLKCMU_BUS1_BUS,
+	CLK_CON_DIV_CLKCMU_BUS1_SSS,
+	CLK_CON_DIV_CLKCMU_CIS_CLK0,
+	CLK_CON_DIV_CLKCMU_CIS_CLK1,
+	CLK_CON_DIV_CLKCMU_CIS_CLK2,
+	CLK_CON_DIV_CLKCMU_CIS_CLK3,
+	CLK_CON_DIV_CLKCMU_CIS_CLK4,
+	CLK_CON_DIV_CLKCMU_CIS_CLK5,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST,
+	CLK_CON_DIV_CLKCMU_CORE_BUS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_DIV_CLKCMU_CSIS_BUS,
+	CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_DIV_CLKCMU_DNC_BUS,
+	CLK_CON_DIV_CLKCMU_DNC_BUSM,
+	CLK_CON_DIV_CLKCMU_DNS_BUS,
+	CLK_CON_DIV_CLKCMU_DSP_BUS,
+	CLK_CON_DIV_CLKCMU_G2D_G2D,
+	CLK_CON_DIV_CLKCMU_G2D_MSCL,
+	CLK_CON_DIV_CLKCMU_G3D_SWITCH,
+	CLK_CON_DIV_CLKCMU_HPM,
+	CLK_CON_DIV_CLKCMU_HSI0_BUS,
+	CLK_CON_DIV_CLKCMU_HSI0_DPGTC,
+	CLK_CON_DIV_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_DIV_CLKCMU_HSI1_BUS,
+	CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_DIV_CLKCMU_HSI1_PCIE,
+	CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_DIV_CLKCMU_HSI2_BUS,
+	CLK_CON_DIV_CLKCMU_HSI2_PCIE,
+	CLK_CON_DIV_CLKCMU_IPP_BUS,
+	CLK_CON_DIV_CLKCMU_ITP_BUS,
+	CLK_CON_DIV_CLKCMU_MCSC_BUS,
+	CLK_CON_DIV_CLKCMU_MCSC_GDC,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU,
+	CLK_CON_DIV_CLKCMU_MFC0_MFC0,
+	CLK_CON_DIV_CLKCMU_MFC0_WFD,
+	CLK_CON_DIV_CLKCMU_MIF_BUSP,
+	CLK_CON_DIV_CLKCMU_NPU_BUS,
+	CLK_CON_DIV_CLKCMU_OTP,
+	CLK_CON_DIV_CLKCMU_PERIC0_BUS,
+	CLK_CON_DIV_CLKCMU_PERIC0_IP,
+	CLK_CON_DIV_CLKCMU_PERIC1_BUS,
+	CLK_CON_DIV_CLKCMU_PERIC1_IP,
+	CLK_CON_DIV_CLKCMU_PERIS_BUS,
+	CLK_CON_DIV_CLKCMU_SSP_BUS,
+	CLK_CON_DIV_CLKCMU_TNR_BUS,
+	CLK_CON_DIV_CLKCMU_VRA_BUS,
+	CLK_CON_DIV_DIV_CLKCMU_DPU,
+	CLK_CON_DIV_DIV_CLKCMU_DPU_ALT,
+	CLK_CON_DIV_PLL_SHARED0_DIV2,
+	CLK_CON_DIV_PLL_SHARED0_DIV3,
+	CLK_CON_DIV_PLL_SHARED0_DIV4,
+	CLK_CON_DIV_PLL_SHARED1_DIV2,
+	CLK_CON_DIV_PLL_SHARED1_DIV3,
+	CLK_CON_DIV_PLL_SHARED1_DIV4,
+	CLK_CON_DIV_PLL_SHARED2_DIV2,
+	CLK_CON_DIV_PLL_SHARED4_DIV2,
+	CLK_CON_DIV_PLL_SHARED4_DIV3,
+	CLK_CON_DIV_PLL_SHARED4_DIV4,
+	CLK_CON_GAT_CLKCMU_G3D_BUS,
+	CLK_CON_GAT_CLKCMU_MIF_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_AUD_CPU,
+	CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5,
+	CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_GAT_GATE_CLKCMU_DNC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM,
+	CLK_CON_GAT_GATE_CLKCMU_DNS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DPU,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DSP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_G2D_G2D,
+	CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL,
+	CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_HPM,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE,
+	CLK_CON_GAT_GATE_CLKCMU_IPP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_ITP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC,
+	CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0,
+	CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD,
+	CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_NPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_SSP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_TNR_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_VRA_BUS,
+};
+
+static const struct samsung_pll_clock top_pll_clks[] __initconst = {
+	PLL(pll_0717x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, NULL),
+	PLL(pll_0717x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, NULL),
+	PLL(pll_0718x, CLK_FOUT_SHARED2_PLL, "fout_shared2_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED2, PLL_CON3_PLL_SHARED2, NULL),
+	PLL(pll_0718x, CLK_FOUT_SHARED3_PLL, "fout_shared3_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED3, PLL_CON3_PLL_SHARED3, NULL),
+	PLL(pll_0717x, CLK_FOUT_SHARED4_PLL, "fout_shared4_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED4, PLL_CON3_PLL_SHARED4, NULL),
+	PLL(pll_0732x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL),
+	PLL(pll_0718x, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_G3D, PLL_CON3_PLL_G3D, NULL),
+};
+
+/* Parent clock list for CMU_TOP muxes*/
+PNAME(mout_pll_shared0_p)		= { "oscclk", "fout_shared0_pll" };
+PNAME(mout_pll_shared1_p)		= { "oscclk", "fout_shared1_pll" };
+PNAME(mout_pll_shared2_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_pll_shared3_p)		= { "oscclk", "fout_shared3_pll" };
+PNAME(mout_pll_shared4_p)		= { "oscclk", "fout_shared4_pll" };
+PNAME(mout_pll_mmc_p)			= { "oscclk", "fout_mmc_pll" };
+PNAME(mout_pll_g3d_p)			= { "oscclk", "fout_g3d_pll" };
+PNAME(mout_cmu_apm_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_aud_cpu_p)		= { "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_bus0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_bus1_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_bus1_sss_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_cis_clk0_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk1_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk2_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk3_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk4_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk5_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cmu_boost_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_core_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div3",
+					    "dout_cmu_shared1_div3",
+					    "dout_cmu_shared0_div4",
+					    "fout_shared3_pll", "oscclk" };
+PNAME(mout_cmu_cpucl0_dbg_bus_p)	= { "fout_shared2_pll",
+					    "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4",
+					    "oscclk" };
+PNAME(mout_cmu_cpucl0_switch_p)		= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_cpucl1_switch_p)	= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_cpucl2_busp_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cpucl2_switch_p)		= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_csis_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3" };
+PNAME(mout_cmu_csis_ois_mcu_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_dnc_bus_p)		= { "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_dnc_busm_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "dout_cmu_shared4_div4" };
+PNAME(mout_cmu_dns_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_dpu_p)			= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_dpu_alt_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_dsp_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "fout_shared3_pll", "oscclk",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_g2d_g2d_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_g2d_mscl_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "dout_cmu_shared4_div4",
+					    "oscclk" };
+PNAME(mout_cmu_hpm_p)			= { "oscclk",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_hsi0_dpgtc_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_usb31drd_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_usbdp_debug_p)	= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_hsi1_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "fout_mmc_pll", "oscclk", "oscclk" };
+PNAME(mout_cmu_hsi1_mmc_card_p)	= { "oscclk", "fout_shared2_pll",
+					    "fout_mmc_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_hsi1_pcie_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_hsi1_ufs_card_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi1_ufs_embd_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi2_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_hsi2_pcie_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_ipp_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "oscclk", "oscclk", "oscclk" };
+PNAME(mout_cmu_itp_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_mcsc_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_mcsc_gdc_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_cmu_boost_cpu_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_mfc0_mfc0_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_mfc0_wfd_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_mif_busp_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_mif_switch_p)		= { "fout_shared0_pll",
+					    "fout_shared1_pll",
+					    "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_npu_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "fout_shared3_pll", "oscclk",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_peric0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric0_ip_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric1_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric1_ip_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peris_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_ssp_bus_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_tnr_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_vra_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3" };
+
+/*
+ * Register name to clock name mangling strategy used in this file
+ *
+ * Replace PLL_CON{0,3}_PLL	   with CLK_MOUT_PLL and mout_pll
+ * Replace CLK_CON_MUX_MUX_CLKCMU  with CLK_MOUT_CMU and mout_cmu
+ * Replace CLK_CON_DIV_CLKCMU      with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_DIV_DIV_CLKCMU  with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_DIV_PLL_CLKCMU  with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_GAT_CLKCMU      with CLK_GOUT_CMU and gout_cmu
+ * Replace CLK_CON_GAT_GATE_CLKCMU with CLK_GOUT_CMU and gout_cmu
+ *
+ * For gates remove _UID _BLK _IPCLKPORT, _I and _RSTNSYNC
+ */
+
+static const struct samsung_mux_clock top_mux_clks[] __initconst = {
+	MUX(CLK_MOUT_PLL_SHARED0, "mout_pll_shared0", mout_pll_shared0_p,
+	    PLL_CON3_PLL_SHARED0, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED1, "mout_pll_shared1", mout_pll_shared1_p,
+	    PLL_CON3_PLL_SHARED1, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED2, "mout_pll_shared2", mout_pll_shared2_p,
+	    PLL_CON3_PLL_SHARED2, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED3, "mout_pll_shared3", mout_pll_shared3_p,
+	    PLL_CON3_PLL_SHARED3, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED4, "mout_pll_shared4", mout_pll_shared4_p,
+	    PLL_CON0_PLL_SHARED4, 4, 1),
+	MUX(CLK_MOUT_PLL_MMC, "mout_pll_mmc", mout_pll_mmc_p,
+	    PLL_CON0_PLL_MMC, 4, 1),
+	MUX(CLK_MOUT_PLL_G3D, "mout_pll_g3d", mout_pll_g3d_p,
+	    PLL_CON0_PLL_G3D, 4, 1),
+	MUX(CLK_MOUT_CMU_APM_BUS, "mout_cmu_apm_bus",
+	    mout_cmu_apm_bus_p, CLK_CON_MUX_MUX_CLKCMU_APM_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_AUD_CPU, "mout_cmu_aud_cpu",
+	    mout_cmu_aud_cpu_p, CLK_CON_MUX_MUX_CLKCMU_AUD_CPU, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS0_BUS, "mout_cmu_bus0_bus",
+	    mout_cmu_bus0_bus_p, CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS1_BUS, "mout_cmu_bus1_bus",
+	    mout_cmu_bus1_bus_p, CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS1_SSS, "mout_cmu_bus1_sss",
+	    mout_cmu_bus1_sss_p, CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS, 0, 2),
+	MUX(CLK_MOUT_CMU_CIS_CLK0, "mout_cmu_cis_clk0",
+	    mout_cmu_cis_clk0_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK1, "mout_cmu_cis_clk1",
+	    mout_cmu_cis_clk1_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK2, "mout_cmu_cis_clk2",
+	    mout_cmu_cis_clk2_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK3, "mout_cmu_cis_clk3",
+	    mout_cmu_cis_clk3_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK4, "mout_cmu_cis_clk4",
+	    mout_cmu_cis_clk4_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK5, "mout_cmu_cis_clk5",
+	    mout_cmu_cis_clk5_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5, 0, 1),
+	MUX(CLK_MOUT_CMU_CMU_BOOST, "mout_cmu_cmu_boost",
+	    mout_cmu_cmu_boost_p, CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST, 0, 2),
+	MUX(CLK_MOUT_CMU_CORE_BUS, "mout_cmu_core_bus",
+	    mout_cmu_core_bus_p, CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_CPUCL0_DBG_BUS, "mout_cmu_cpucl0_dbg_bus",
+	    mout_cmu_cpucl0_dbg_bus_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL0_SWITCH, "mout_cmu_cpucl0_switch",
+	    mout_cmu_cpucl0_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL1_SWITCH, "mout_cmu_cpucl1_switch",
+	    mout_cmu_cpucl1_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL2_BUSP, "mout_cmu_cpucl2_busp",
+	    mout_cmu_cpucl2_busp_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_CPUCL2_SWITCH, "mout_cmu_cpucl2_switch",
+	    mout_cmu_cpucl2_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CSIS_BUS, "mout_cmu_csis_bus",
+	    mout_cmu_csis_bus_p, CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_CSIS_OIS_MCU, "mout_cmu_csis_ois_mcu",
+	    mout_cmu_csis_ois_mcu_p, CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_DNC_BUS, "mout_cmu_dnc_bus",
+	    mout_cmu_dnc_bus_p, CLK_CON_MUX_MUX_CLKCMU_DNC_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_DNC_BUSM, "mout_cmu_dnc_busm",
+	    mout_cmu_dnc_busm_p, CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM, 0, 2),
+	MUX(CLK_MOUT_CMU_DNS_BUS, "mout_cmu_dns_bus",
+	    mout_cmu_dns_bus_p, CLK_CON_MUX_MUX_CLKCMU_DNS_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_DPU, "mout_cmu_dpu",
+	    mout_cmu_dpu_p, CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 1),
+	MUX(CLK_MOUT_CMU_DPU_ALT, "mout_cmu_dpu_alt",
+	    mout_cmu_dpu_alt_p, CLK_CON_MUX_MUX_CLKCMU_DPU_ALT, 0, 2),
+	MUX(CLK_MOUT_CMU_DSP_BUS, "mout_cmu_dsp_bus",
+	    mout_cmu_dsp_bus_p, CLK_CON_MUX_MUX_CLKCMU_DSP_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_G2D_G2D, "mout_cmu_g2d_g2d",
+	    mout_cmu_g2d_g2d_p, CLK_CON_MUX_MUX_CLKCMU_G2D_G2D, 0, 2),
+	MUX(CLK_MOUT_CMU_G2D_MSCL, "mout_cmu_g2d_mscl",
+	    mout_cmu_g2d_mscl_p, CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL, 0, 1),
+	MUX(CLK_MOUT_CMU_HPM, "mout_cmu_hpm",
+	    mout_cmu_hpm_p, CLK_CON_MUX_MUX_CLKCMU_HPM, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_BUS, "mout_cmu_hsi0_bus",
+	    mout_cmu_hsi0_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI0_DPGTC, "mout_cmu_hsi0_dpgtc",
+	    mout_cmu_hsi0_dpgtc_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_USB31DRD, "mout_cmu_hsi0_usb31drd",
+	    mout_cmu_hsi0_usb31drd_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_USBDP_DEBUG, "mout_cmu_hsi0_usbdp_debug",
+	    mout_cmu_hsi0_usbdp_debug_p,
+	    CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_BUS, "mout_cmu_hsi1_bus",
+	    mout_cmu_hsi1_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_HSI1_MMC_CARD, "mout_cmu_hsi1_mmc_card",
+	    mout_cmu_hsi1_mmc_card_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_PCIE, "mout_cmu_hsi1_pcie",
+	    mout_cmu_hsi1_pcie_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI1_UFS_CARD, "mout_cmu_hsi1_ufs_card",
+	    mout_cmu_hsi1_ufs_card_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_UFS_EMBD, "mout_cmu_hsi1_ufs_embd",
+	    mout_cmu_hsi1_ufs_embd_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_HSI2_BUS, "mout_cmu_hsi2_bus",
+	    mout_cmu_hsi2_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI2_PCIE, "mout_cmu_hsi2_pcie",
+	    mout_cmu_hsi2_pcie_p, CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE, 0, 1),
+	MUX(CLK_MOUT_CMU_IPP_BUS, "mout_cmu_ipp_bus",
+	    mout_cmu_ipp_bus_p, CLK_CON_MUX_MUX_CLKCMU_IPP_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_ITP_BUS, "mout_cmu_itp_bus",
+	    mout_cmu_itp_bus_p, CLK_CON_MUX_MUX_CLKCMU_ITP_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_MCSC_BUS, "mout_cmu_mcsc_bus",
+	    mout_cmu_mcsc_bus_p, CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_MCSC_GDC, "mout_cmu_mcsc_gdc",
+	    mout_cmu_mcsc_gdc_p, CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC, 0, 3),
+	MUX(CLK_MOUT_CMU_CMU_BOOST_CPU, "mout_cmu_cmu_boost_cpu",
+	    mout_cmu_cmu_boost_cpu_p, CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_MFC0_MFC0, "mout_cmu_mfc0_mfc0",
+	    mout_cmu_mfc0_mfc0_p, CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0, 0, 2),
+	MUX(CLK_MOUT_CMU_MFC0_WFD, "mout_cmu_mfc0_wfd",
+	    mout_cmu_mfc0_wfd_p, CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD, 0, 2),
+	MUX(CLK_MOUT_CMU_MIF_BUSP, "mout_cmu_mif_busp",
+	    mout_cmu_mif_busp_p, CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP, 0, 2),
+	MUX(CLK_MOUT_CMU_MIF_SWITCH, "mout_cmu_mif_switch",
+	    mout_cmu_mif_switch_p, CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH, 0, 3),
+	MUX(CLK_MOUT_CMU_NPU_BUS, "mout_cmu_npu_bus",
+	    mout_cmu_npu_bus_p, CLK_CON_MUX_MUX_CLKCMU_NPU_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_PERIC0_BUS, "mout_cmu_peric0_bus",
+	    mout_cmu_peric0_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC0_IP, "mout_cmu_peric0_ip",
+	    mout_cmu_peric0_ip_p, CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC1_BUS, "mout_cmu_peric1_bus",
+	    mout_cmu_peric1_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC1_IP, "mout_cmu_peric1_ip",
+	    mout_cmu_peric1_ip_p, CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIS_BUS, "mout_cmu_peris_bus",
+	    mout_cmu_peris_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_SSP_BUS, "mout_cmu_ssp_bus",
+	    mout_cmu_ssp_bus_p, CLK_CON_MUX_MUX_CLKCMU_SSP_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_TNR_BUS, "mout_cmu_tnr_bus",
+	    mout_cmu_tnr_bus_p, CLK_CON_MUX_MUX_CLKCMU_TNR_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_VRA_BUS, "mout_cmu_vra_bus",
+	    mout_cmu_vra_bus_p, CLK_CON_MUX_MUX_CLKCMU_VRA_BUS, 0, 2),
+};
+
+static const struct samsung_div_clock top_div_clks[] __initconst = {
+	/* SHARED0 region*/
+	DIV(CLK_DOUT_CMU_SHARED0_DIV2, "dout_cmu_shared0_div2", "mout_pll_shared0",
+	    CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED0_DIV3, "dout_cmu_shared0_div3", "mout_pll_shared0",
+	    CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED0_DIV4, "dout_cmu_shared0_div4", "dout_cmu_shared0_div2",
+	    CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
+
+	/* SHARED1 region*/
+	DIV(CLK_DOUT_CMU_SHARED1_DIV2, "dout_cmu_shared1_div2", "mout_pll_shared1",
+	    CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED1_DIV3, "dout_cmu_shared1_div3", "mout_pll_shared1",
+	    CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED1_DIV4, "dout_cmu_shared1_div4", "dout_cmu_shared1_div2",
+	    CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
+
+	/* SHARED2 region */
+	DIV(CLK_DOUT_CMU_SHARED2_DIV2, "dout_cmu_shared2_div2", "mout_pll_shared2",
+	    CLK_CON_DIV_PLL_SHARED2_DIV2, 0, 1),
+
+	/* SHARED4 region*/
+	DIV(CLK_DOUT_CMU_SHARED4_DIV2, "dout_cmu_shared4_div2", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED4_DIV3, "dout_cmu_shared4_div3", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED4_DIV4, "dout_cmu_shared4_div4", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV4, 0, 1),
+
+	DIV(CLK_DOUT_CMU_APM_BUS, "dout_cmu_apm_bus", "gout_cmu_apm_bus",
+	    CLK_CON_DIV_CLKCMU_APM_BUS, 0, 3),
+	DIV(CLK_DOUT_CMU_AUD_CPU, "dout_cmu_aud_cpu", "gout_cmu_aud_cpu",
+	    CLK_CON_DIV_CLKCMU_AUD_CPU, 0, 3),
+	DIV(CLK_DOUT_CMU_BUS0_BUS, "dout_cmu_bus0_bus", "gout_cmu_bus0_bus",
+	    CLK_CON_DIV_CLKCMU_BUS0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_BUS1_BUS, "dout_cmu_bus1_bus", "gout_cmu_bus1_bus",
+	    CLK_CON_DIV_CLKCMU_BUS1_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_BUS1_SSS, "dout_cmu_bus1_sss", "gout_cmu_bus1_sss",
+	    CLK_CON_DIV_CLKCMU_BUS1_SSS, 0, 4),
+	DIV(CLK_DOUT_CMU_CIS_CLK0, "dout_cmu_cis_clk0", "gout_cmu_cis_clk0",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK0, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK1, "dout_cmu_cis_clk1", "gout_cmu_cis_clk1",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK1, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK2, "dout_cmu_cis_clk2", "gout_cmu_cis_clk2",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK2, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK3, "dout_cmu_cis_clk3", "gout_cmu_cis_clk3",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK3, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK4, "dout_cmu_cis_clk4", "gout_cmu_cis_clk4",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK4, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK5, "dout_cmu_cis_clk5", "gout_cmu_cis_clk5",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK5, 0, 5),
+	DIV(CLK_DOUT_CMU_CMU_BOOST, "dout_cmu_cmu_boost", "mout_cmu_cmu_boost",
+	    CLK_CON_DIV_CLKCMU_CMU_BOOST, 0, 2),
+	DIV(CLK_DOUT_CMU_CORE_BUS, "dout_cmu_core_bus", "gout_cmu_core_bus",
+	    CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_CPUCL0_DBG_BUS, "dout_cmu_cpucl0_debug",
+	    "gout_cmu_cpucl0_dbg_bus", CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL0_SWITCH, "dout_cmu_cpucl0_switch",
+	    "gout_cmu_cpucl0_switch", CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL1_SWITCH, "dout_cmu_cpucl1_switch",
+	    "gout_cmu_cpucl1_switch", CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL2_BUSP, "dout_cmu_cpucl2_busp",
+	    "gout_cmu_cpucl2_busp", CLK_CON_DIV_CLKCMU_CPUCL2_BUSP, 0, 4),
+	DIV(CLK_DOUT_CMU_CPUCL2_SWITCH, "dout_cmu_cpucl2_switch",
+	    "gout_cmu_cpucl2_switch", CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CSIS_BUS, "dout_cmu_csis_bus", "gout_cmu_csis_bus",
+	    CLK_CON_DIV_CLKCMU_CSIS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_CSIS_OIS_MCU, "dout_cmu_csis_ois_mcu",
+	    "gout_cmu_csis_ois_mcu", CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU, 0, 4),
+	DIV(CLK_DOUT_CMU_DNC_BUS, "dout_cmu_dnc_bus", "gout_cmu_dnc_bus",
+	    CLK_CON_DIV_CLKCMU_DNC_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DNC_BUSM, "dout_cmu_dnc_busm", "gout_cmu_dnc_busm",
+	    CLK_CON_DIV_CLKCMU_DNC_BUSM, 0, 4),
+	DIV(CLK_DOUT_CMU_DNS_BUS, "dout_cmu_dns_bus", "gout_cmu_dns_bus",
+	    CLK_CON_DIV_CLKCMU_DNS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DSP_BUS, "dout_cmu_dsp_bus", "gout_cmu_dsp_bus",
+	    CLK_CON_DIV_CLKCMU_DSP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_G2D_G2D, "dout_cmu_g2d_g2d", "gout_cmu_g2d_g2d",
+	    CLK_CON_DIV_CLKCMU_G2D_G2D, 0, 4),
+	DIV(CLK_DOUT_CMU_G2D_MSCL, "dout_cmu_g2d_mscl", "gout_cmu_g2d_mscl",
+	    CLK_CON_DIV_CLKCMU_G2D_MSCL, 0, 4),
+	DIV(CLK_DOUT_CMU_G3D_SWITCH, "dout_cmu_g3d_switch",
+	    "gout_cmu_g3d_switch", CLK_CON_DIV_CLKCMU_G3D_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_HPM, "dout_cmu_hpm", "gout_cmu_hpm",
+	    CLK_CON_DIV_CLKCMU_HPM, 0, 2),
+	DIV(CLK_DOUT_CMU_HSI0_BUS, "dout_cmu_hsi0_bus", "gout_cmu_hsi0_bus",
+	    CLK_CON_DIV_CLKCMU_HSI0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI0_DPGTC, "dout_cmu_hsi0_dpgtc", "gout_cmu_hsi0_dpgtc",
+	    CLK_CON_DIV_CLKCMU_HSI0_DPGTC, 0, 3),
+	DIV(CLK_DOUT_CMU_HSI0_USB31DRD, "dout_cmu_hsi0_usb31drd",
+	    "gout_cmu_hsi0_usb31drd", CLK_CON_DIV_CLKCMU_HSI0_USB31DRD, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI0_USBDP_DEBUG, "dout_cmu_hsi0_usbdp_debug",
+	    "gout_cmu_hsi0_usbdp_debug", CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_HSI1_BUS, "dout_cmu_hsi1_bus", "gout_cmu_hsi1_bus",
+	    CLK_CON_DIV_CLKCMU_HSI1_BUS, 0, 3),
+	DIV(CLK_DOUT_CMU_HSI1_MMC_CARD, "dout_cmu_hsi1_mmc_card",
+	    "gout_cmu_hsi1_mmc_card", CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_HSI1_PCIE, "dout_cmu_hsi1_pcie", "gout_cmu_hsi1_pcie",
+	    CLK_CON_DIV_CLKCMU_HSI1_PCIE, 0, 7),
+	DIV(CLK_DOUT_CMU_HSI1_UFS_CARD, "dout_cmu_hsi1_ufs_card",
+	    "gout_cmu_hsi1_ufs_card", CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_HSI1_UFS_EMBD, "dout_cmu_hsi1_ufs_embd",
+	    "gout_cmu_hsi1_ufs_embd", CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_HSI2_BUS, "dout_cmu_hsi2_bus", "gout_cmu_hsi2_bus",
+	    CLK_CON_DIV_CLKCMU_HSI2_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI2_PCIE, "dout_cmu_hsi2_pcie", "gout_cmu_hsi2_pcie",
+	    CLK_CON_DIV_CLKCMU_HSI2_PCIE, 0, 7),
+	DIV(CLK_DOUT_CMU_IPP_BUS, "dout_cmu_ipp_bus", "gout_cmu_ipp_bus",
+	    CLK_CON_DIV_CLKCMU_IPP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_ITP_BUS, "dout_cmu_itp_bus", "gout_cmu_itp_bus",
+	    CLK_CON_DIV_CLKCMU_ITP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_MCSC_BUS, "dout_cmu_mcsc_bus", "gout_cmu_mcsc_bus",
+	    CLK_CON_DIV_CLKCMU_MCSC_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_MCSC_GDC, "dout_cmu_mcsc_gdc", "gout_cmu_mcsc_gdc",
+	    CLK_CON_DIV_CLKCMU_MCSC_GDC, 0, 4),
+	DIV(CLK_DOUT_CMU_CMU_BOOST_CPU, "dout_cmu_cmu_boost_cpu",
+	    "mout_cmu_cmu_boost_cpu", CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU,
+	    0, 2),
+	DIV(CLK_DOUT_CMU_MFC0_MFC0, "dout_cmu_mfc0_mfc0", "gout_cmu_mfc0_mfc0",
+	    CLK_CON_DIV_CLKCMU_MFC0_MFC0, 0, 4),
+	DIV(CLK_DOUT_CMU_MFC0_WFD, "dout_cmu_mfc0_wfd", "gout_cmu_mfc0_wfd",
+	    CLK_CON_DIV_CLKCMU_MFC0_WFD, 0, 4),
+	DIV(CLK_DOUT_CMU_MIF_BUSP, "dout_cmu_mif_busp", "gout_cmu_mif_busp",
+	    CLK_CON_DIV_CLKCMU_MIF_BUSP, 0, 4),
+	DIV(CLK_DOUT_CMU_NPU_BUS, "dout_cmu_npu_bus", "gout_cmu_npu_bus",
+	    CLK_CON_DIV_CLKCMU_NPU_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC0_BUS, "dout_cmu_peric0_bus", "gout_cmu_peric0_bus",
+	    CLK_CON_DIV_CLKCMU_PERIC0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC0_IP, "dout_cmu_peric0_ip", "gout_cmu_peric0_ip",
+	    CLK_CON_DIV_CLKCMU_PERIC0_IP, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC1_BUS, "dout_cmu_peric1_bus", "gout_cmu_peric1_bus",
+	    CLK_CON_DIV_CLKCMU_PERIC1_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC1_IP, "dout_cmu_peric1_ip", "gout_cmu_peric1_ip",
+	    CLK_CON_DIV_CLKCMU_PERIC1_IP, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIS_BUS, "dout_cmu_peris_bus", "gout_cmu_peris_bus",
+	    CLK_CON_DIV_CLKCMU_PERIS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_SSP_BUS, "dout_cmu_ssp_bus", "gout_cmu_ssp_bus",
+	    CLK_CON_DIV_CLKCMU_SSP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_TNR_BUS, "dout_cmu_tnr_bus", "gout_cmu_tnr_bus",
+	    CLK_CON_DIV_CLKCMU_TNR_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_VRA_BUS, "dout_cmu_vra_bus", "gout_cmu_vra_bus",
+	    CLK_CON_DIV_CLKCMU_VRA_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DPU, "dout_cmu_clkcmu_dpu", "gout_cmu_dpu",
+	    CLK_CON_DIV_DIV_CLKCMU_DPU, 0, 4),
+};
+
+static const struct samsung_gate_clock top_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CMU_APM_BUS, "gout_cmu_apm_bus", "mout_cmu_apm_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_APM_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_AUD_CPU, "gout_cmu_aud_cpu", "mout_cmu_aud_cpu",
+	     CLK_CON_GAT_GATE_CLKCMU_AUD_CPU, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_BUS0_BUS, "gout_cmu_bus0_bus", "mout_cmu_bus0_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_BUS1_BUS, "gout_cmu_bus1_bus", "mout_cmu_bus1_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_BUS1_SSS, "gout_cmu_bus1_sss", "mout_cmu_bus1_sss",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK0, "gout_cmu_cis_clk0", "mout_cmu_cis_clk0",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK1, "gout_cmu_cis_clk1", "mout_cmu_cis_clk1",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK2, "gout_cmu_cis_clk2", "mout_cmu_cis_clk2",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK3, "gout_cmu_cis_clk3", "mout_cmu_cis_clk3",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK4, "gout_cmu_cis_clk4", "mout_cmu_cis_clk4",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK5, "gout_cmu_cis_clk5", "mout_cmu_cis_clk5",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CORE_BUS, "gout_cmu_core_bus", "mout_cmu_core_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_DBG_BUS, "gout_cmu_cpucl0_dbg_bus",
+	     "mout_cmu_cpucl0_dbg_bus", CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_SWITCH, "gout_cmu_cpucl0_switch",
+	     "mout_cmu_cpucl0_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL1_SWITCH, "gout_cmu_cpucl1_switch",
+	     "mout_cmu_cpucl1_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL2_BUSP, "gout_cmu_cpucl2_busp",
+	     "mout_cmu_cpucl2_busp", CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL2_SWITCH, "gout_cmu_cpucl2_switch",
+	     "mout_cmu_cpucl2_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CSIS_BUS, "gout_cmu_csis_bus", "mout_cmu_csis_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CSIS_OIS_MCU, "gout_cmu_csis_ois_mcu",
+	     "mout_cmu_csis_ois_mcu", CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNC_BUS, "gout_cmu_dnc_bus", "mout_cmu_dnc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DNC_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNC_BUSM, "gout_cmu_dnc_busm", "mout_cmu_dnc_busm",
+	     CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNS_BUS, "gout_cmu_dns_bus", "mout_cmu_dns_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DNS_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU, "gout_cmu_dpu", "mout_cmu_dpu",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_BUS, "gout_cmu_dpu_bus", "mout_cmu_dpu_alt",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_DSP_BUS, "gout_cmu_dsp_bus", "mout_cmu_dsp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DSP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G2D_G2D, "gout_cmu_g2d_g2d", "mout_cmu_g2d_g2d",
+	     CLK_CON_GAT_GATE_CLKCMU_G2D_G2D, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G2D_MSCL, "gout_cmu_g2d_mscl", "mout_cmu_g2d_mscl",
+	     CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G3D_SWITCH, "gout_cmu_g3d_switch",
+	     "fout_shared2_pll", CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HPM, "gout_cmu_hpm", "mout_cmu_hpm",
+	     CLK_CON_GAT_GATE_CLKCMU_HPM, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_BUS, "gout_cmu_hsi0_bus",
+	     "mout_cmu_hsi0_bus", CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_DPGTC, "gout_cmu_hsi0_dpgtc",
+	     "mout_cmu_hsi0_dpgtc", CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_USB31DRD, "gout_cmu_hsi0_usb31drd",
+	     "mout_cmu_hsi0_usb31drd", CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_USBDP_DEBUG, "gout_cmu_hsi0_usbdp_debug",
+	     "mout_cmu_hsi0_usbdp_debug", CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_BUS, "gout_cmu_hsi1_bus", "mout_cmu_hsi1_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_MMC_CARD, "gout_cmu_hsi1_mmc_card",
+	     "mout_cmu_hsi1_mmc_card", CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_PCIE, "gout_cmu_hsi1_pcie",
+	     "mout_cmu_hsi1_pcie", CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_UFS_CARD, "gout_cmu_hsi1_ufs_card",
+	     "mout_cmu_hsi1_ufs_card", CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_UFS_EMBD, "gout_cmu_hsi1_ufs_embd",
+	     "mout_cmu_hsi1_ufs_embd", CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI2_BUS, "gout_cmu_hsi2_bus", "mout_cmu_hsi2_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI2_PCIE, "gout_cmu_hsi2_pcie",
+	     "mout_cmu_hsi2_pcie", CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_IPP_BUS, "gout_cmu_ipp_bus", "mout_cmu_ipp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_IPP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_ITP_BUS, "gout_cmu_itp_bus", "mout_cmu_itp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_ITP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MCSC_BUS, "gout_cmu_mcsc_bus", "mout_cmu_mcsc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MCSC_GDC, "gout_cmu_mcsc_gdc", "mout_cmu_mcsc_gdc",
+	     CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MFC0_MFC0, "gout_cmu_mfc0_mfc0",
+	     "mout_cmu_mfc0_mfc0", CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MFC0_WFD, "gout_cmu_mfc0_wfd", "mout_cmu_mfc0_wfd",
+	     CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MIF_BUSP, "gout_cmu_mif_busp", "mout_cmu_mif_busp",
+	     CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_NPU_BUS, "gout_cmu_npu_bus", "mout_cmu_npu_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_NPU_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC0_BUS, "gout_cmu_peric0_bus",
+	     "mout_cmu_peric0_bus", CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC0_IP, "gout_cmu_peric0_ip",
+	     "mout_cmu_peric0_ip", CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC1_BUS, "gout_cmu_peric1_bus",
+	     "mout_cmu_peric1_bus", CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC1_IP, "gout_cmu_peric1_ip",
+	     "mout_cmu_peric1_ip", CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIS_BUS, "gout_cmu_peris_bus",
+	     "mout_cmu_peris_bus", CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_SSP_BUS, "gout_cmu_ssp_bus", "mout_cmu_ssp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_SSP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_TNR_BUS, "gout_cmu_tnr_bus", "mout_cmu_tnr_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_TNR_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_VRA_BUS, "gout_cmu_vra_bus", "mout_cmu_vra_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_VRA_BUS, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info top_cmu_info __initconst = {
+	.pll_clks = top_pll_clks,
+	.nr_pll_clks = ARRAY_SIZE(top_pll_clks),
+	.mux_clks = top_mux_clks,
+	.nr_mux_clks = ARRAY_SIZE(top_mux_clks),
+	.div_clks = top_div_clks,
+	.nr_div_clks = ARRAY_SIZE(top_div_clks),
+	.gate_clks = top_gate_clks,
+	.nr_gate_clks = ARRAY_SIZE(top_gate_clks),
+	.nr_clk_ids = CLKS_NR_TOP,
+	.clk_regs = top_clk_regs,
+	.nr_clk_regs = ARRAY_SIZE(top_clk_regs),
+};
+
+static void __init exynos990_cmu_top_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
+}
+
+/* Register CMU_TOP early, as it's a dependency for other early domains */
+CLK_OF_DECLARE(exynos990_cmu_top, "samsung,exynos990-cmu-top",
+	       exynos990_cmu_top_init);
+
+/* ---- CMU_HSI0 ------------------------------------------------------------ */
+
+/* Register Offset definitions for CMU_HSI0 (0x10a00000) */
+#define PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER						0x0600
+#define PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER						0x0620
+#define PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER					0x0630
+#define PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER						0x0610
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK			0x2004
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK			0x2018
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHS_ACEL_D_HSI0_IPCLKPORT_I_CLK			0x2014
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK		0x2020
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK			0x2044
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK				0x2008
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK			0x200c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK			0x2010
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK			0x201c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2			0x2024
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK			0x2028
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL			0x202c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40		0x2034
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK	0x203c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK		0x2040
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY			0x2030
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK			0x2000
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK				0x2048
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL		0x2038
+
+static const unsigned long hsi0_clk_regs[] __initconst = {
+	PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHS_ACEL_D_HSI0_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK,
+};
+
+PNAME(mout_hsi0_bus_user_p)		= { "oscclk", "dout_cmu_hsi0_bus" };
+PNAME(mout_hsi0_usb31drd_user_p)	= { "oscclk", "dout_cmu_hsi0_usb31drd" };
+PNAME(mout_hsi0_usbdp_debug_user_p)	= { "oscclk",
+					    "dout_cmu_hsi0_usbdp_debug" };
+PNAME(mout_hsi0_dpgtc_user_p)		= { "oscclk", "dout_cmu_hsi0_dpgtc" };
+
+static const struct samsung_mux_clock hsi0_mux_clks[] __initconst = {
+	MUX(CLK_MOUT_HSI0_BUS_USER, "mout_hsi0_bus_user",
+	    mout_hsi0_bus_user_p, PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_USB31DRD_USER, "mout_hsi0_usb31drd_user",
+	    mout_hsi0_usb31drd_user_p, PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_USBDP_DEBUG_USER, "mout_hsi0_usbdp_debug_user",
+	    mout_hsi0_usbdp_debug_user_p,
+	    PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_DPGTC_USER, "mout_hsi0_dpgtc_user",
+	    mout_hsi0_dpgtc_user_p, PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER,
+	    4, 1),
+};
+
+static const struct samsung_gate_clock hsi0_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_HSI0_DP_LINK_DP_GTC_CLK,
+	     "gout_hsi0_dp_link_dp_gtc_clk", "mout_hsi0_dpgtc_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_DP_LINK_PCLK,
+	     "gout_hsi0_dp_link_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK,
+	     "gout_hsi0_d_tzpc_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_LHM_AXI_P_HSI0_CLK,
+	     "gout_hsi0_lhm_axi_p_hsi0_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK,
+	     21, CLK_IS_CRITICAL, 0),
+	GATE(CLK_GOUT_HSI0_PPMU_HSI0_BUS1_ACLK,
+	     "gout_hsi0_ppmu_hsi0_bus1_aclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_PPMU_HSI0_BUS1_PCLK,
+	     "gout_hsi0_ppmu_hsi0_bus1_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK,
+	     "gout_hsi0_clk_hsi0_bus_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2,
+	     "gout_hsi0_sysmmu_usb_clk_s2", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_HSI0_SYSREG_HSI0_PCLK,
+	     "gout_hsi0_sysreg_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL,
+	     "gout_hsi0_usb31drd_aclk_phyctrl", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY,
+	     "gout_hsi0_usb31drd_bus_clk_early",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USB31DRD_REF_CLK_40,
+	     "gout_hsi0_usb31drd_usb31drd_ref_clk_40",
+	     "mout_hsi0_usb31drd_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBDPPHY_REF_SOC_PLL,
+	     "gout_hsi0_usb31drd_usbdpphy_ref_soc_pll",
+	     "mout_hsi0_usbdp_debug_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBDPPHY_SCL_APB,
+	     "gout_hsi0_usb31drd_ipclkport_i_usbdpphy_scl_apb_pclk",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBPCS_APB_CLK,
+	     "gout_hsi0_usb31drd_usbpcs_apb_clk",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_VGEN_LITE_HSI0_CLK,
+	     "gout_hsi0_vgen_lite_ipclkport_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_CMU_HSI0_PCLK,
+	     "gout_hsi0_cmu_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_HSI0_XIU_D_HSI0_ACLK,
+	     "gout_hsi0_xiu_d_hsi0_aclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info hsi0_cmu_info __initconst = {
+	.mux_clks = hsi0_mux_clks,
+	.nr_mux_clks = ARRAY_SIZE(hsi0_mux_clks),
+	.gate_clks = hsi0_gate_clks,
+	.nr_gate_clks = ARRAY_SIZE(hsi0_gate_clks),
+	.nr_clk_ids = CLKS_NR_HSI0,
+	.clk_regs = hsi0_clk_regs,
+	.nr_clk_regs = ARRAY_SIZE(hsi0_clk_regs),
+	.clk_name		= "dout_cmu_hsi0_bus",
+};
+
+/* ----- platform_driver ----- */
+
+static int __init exynos990_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+static const struct of_device_id exynos990_cmu_of_match[] = {
+	{
+		.compatible = "samsung,exynos990-cmu-hsi0",
+		.data = &hsi0_cmu_info,
+	},
+	{ },
+};
+
+static struct platform_driver exynos990_cmu_driver __refdata = {
+	.driver	= {
+		.name = "exynos990-cmu",
+		.of_match_table = exynos990_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = exynos990_cmu_probe,
+};
+
+static int __init exynos990_cmu_init(void)
+{
+	return platform_driver_register(&exynos990_cmu_driver);
+}
+
+core_initcall(exynos990_cmu_init);
-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Thu Dec  5 11:40:19 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Thu,  5 Dec 2024 20:40:19 +0100
Subject: [PATCH v1 0/1] arm64: dts: exynos990: Add cmu nodes
Message-ID: <20241205194020.785846-1-igor.belwon@mentallysanemainliners.org>

Hi all,

This patchset adds device tree nodes for Exynos990 CMUs (TOP and HSI0).

This patchset is compile-time and runtime dependent on [1], which adds
driver support for CMU.

[1] https://lore.kernel.org/linux-samsung-soc/20241205193423.783815-1-igor.
belwon at mentallysanemainliners.org/T/#t

Igor Belwon (1):
  arm64: dts: exynos990: Add clock management unit nodes

 arch/arm64/boot/dts/exynos/exynos990.dtsi | 27 +++++++++++++++++++++++
 1 file changed, 27 insertions(+)

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Thu Dec  5 11:40:20 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Thu,  5 Dec 2024 20:40:20 +0100
Subject: [PATCH v1 1/1] arm64: dts: exynos990: Add clock management unit nodes
In-Reply-To: <20241205194020.785846-1-igor.belwon@mentallysanemainliners.org>
References: <20241205194020.785846-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241205194020.785846-2-igor.belwon@mentallysanemainliners.org>

Add CMU nodes for:
- cmu_top: provides clocks for other blocks
- cmu_hsi0: provides clocks for usb31

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/exynos990.dtsi | 27 +++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos990.dtsi b/arch/arm64/boot/dts/exynos/exynos990.dtsi
index c1986f00e443..49bb1e156843 100644
--- a/arch/arm64/boot/dts/exynos/exynos990.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos990.dtsi
@@ -5,6 +5,7 @@
  * Copyright (c) 2024, Igor Belwon <igor.belwon at mentallysanemainliners.org>
  */
 
+#include <dt-bindings/clock/samsung,exynos990.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
@@ -199,6 +200,23 @@ pinctrl_peric1: pinctrl at 10730000 {
 			interrupts = <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		cmu_hsi0: clock-controller at 10a00000 {
+			compatible = "samsung,exynos990-cmu-hsi0";
+			reg = <0x10a00000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>,
+				 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
+				 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
+				 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
+				 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
+			clock-names = "oscclk", "dout_cmu_hsi0_bus",
+						"dout_cmu_hsi0_usb31drd",
+						"dout_cmu_hsi0_usbdp_debug",
+						"dout_cmu_hsi0_dpgtc";
+
+		};
+
 		pinctrl_hsi1: pinctrl at 13040000 {
 			compatible = "samsung,exynos990-pinctrl";
 			reg = <0x13040000 0x1000>;
@@ -231,6 +249,15 @@ pinctrl_cmgp: pinctrl at 15c30000 {
 			compatible = "samsung,exynos990-pinctrl";
 			reg = <0x15c30000 0x1000>;
 		};
+
+		cmu_top: clock-controller at 1a330000 {
+			compatible = "samsung,exynos990-cmu-top";
+			reg = <0x1a330000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>;
+			clock-names = "oscclk";
+		};
 	};
 
 	timer {
-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Thu Dec  5 11:45:10 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Thu,  5 Dec 2024 20:45:10 +0100
Subject: Add Exynos990 CMU support
In-Reply-To: <20241205193423.783815-1-igor.belwon@mentallysanemainliners.org>
References: <20241205193423.783815-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241205194510.786973-1-igor.belwon@mentallysanemainliners.org>

I'm terribly sorry for the garbage as the subject. It was my editor adding in
some cached metadata(?). Will resend this patch if deemed necessary.


From konrad.dybcio at oss.qualcomm.com  Thu Dec  5 12:08:18 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 5 Dec 2024 21:08:18 +0100
Subject: [PATCH 1/3] dt-bindings: arm,psci: Allow S2RAM power_state
 parameter description
In-Reply-To: <ZzSe4UAyil8KUm85@lpieralisi>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
 <ZzSe4UAyil8KUm85@lpieralisi>
Message-ID: <3270d558-df65-431d-a347-e40bf3f3923d@oss.qualcomm.com>

On 13.11.2024 1:43 PM, Lorenzo Pieralisi wrote:
> On Mon, Oct 28, 2024 at 03:22:57PM +0100, Konrad Dybcio wrote:
>> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>
>> Certain firmware implementations (such as the ones found on Qualcomm
>> SoCs between roughly 2015 and 2023) expose an S3-like S2RAM state
>> through the CPU_SUSPEND call, as opposed to exposing PSCIv1.0's
>> optional PSCI_SYSTEM_SUSPEND.
>>
>> This really doesn't work well with the model where we associate all
>> calls to CPU_SUSPEND with cpuidle. Allow specifying a single special
>> CPU_SUSPEND suspend parameter value that is to be treated just like
>> SYSTEM_SUSPEND from the OS's point of view.
> 
> For the records, the info above is not relevant.
> 
> These are generic firmware bindings for PSCI specifications - how CPUidle
> is implemented in Linux must play no role here.

[...]

>> +  arm,psci-s2ram-param:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description:
>> +      power_state parameter denoting the S2RAM/S3-like system suspend state
>> +    maxItems: 1
> 
> NACK
> 
> This is nothing that has ever been specified in the PSCI specifications,
> see above.

Thankfully, neither do dt-bindings have to be limited by any software
specifications, nor is this a Linux specific problem.

This is simply non-discoverable firmware interface description, and
DT is the expected information provider here.

The TZ exposes a way for the platform to enter S3, through a call
that is usually not used to do this nowadays, but well allowed by
the specification, even after PSCI1.x.
This property lets the OS know what to pass to said firmware to
request S2RAM entry.

Section 6.5. of the PSCI design document recommends that within the
StateID magic value, a section is dedicated to system-wide (not cluster
or core) power states of "retention" or "powerdown". It also makes an
appearance in Section 4.2. in a more general fashion.

Konrad


From Frank.Li at nxp.com  Thu Dec  5 12:14:22 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu,  5 Dec 2024 15:14:22 -0500
Subject: [PATCH 1/1] dt-bindings: PCI: mobiveil: convert mobiveil-pcie.txt to yaml format
Message-ID: <20241205201423.3430862-1-Frank.Li@nxp.com>

Convert device tree binding doc mobiveil-pcie.txt to yaml format. Merge
layerscape-pcie-gen4.txt into this file.

Additional change:
- interrupt-names: "aer", "pme", "intr", which align order in examples.
- reg-names: csr_axi_slave, config_axi_slave, which align existed dts file.

Fix below CHECK_DTBS warning:
arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dtb: /soc/pcie at 3400000: failed to match any schema with compatible: ['fsl,lx2160a-pcie']

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
lx2160a r2 already don't use this IP. But someone still complain when I
try to remove old r1 support.

So convert to yaml file to avoid annoised CHECK_DTBS warnings.
---
 .../bindings/pci/layerscape-pcie-gen4.txt     |  52 ------
 .../bindings/pci/mbvl,gpex40-pcie.yaml        | 167 ++++++++++++++++++
 .../devicetree/bindings/pci/mobiveil-pcie.txt |  72 --------
 3 files changed, 167 insertions(+), 124 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
 create mode 100644 Documentation/devicetree/bindings/pci/mbvl,gpex40-pcie.yaml
 delete mode 100644 Documentation/devicetree/bindings/pci/mobiveil-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt b/Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
deleted file mode 100644
index b40fb5d15d3d9..0000000000000
--- a/Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-NXP Layerscape PCIe Gen4 controller
-
-This PCIe controller is based on the Mobiveil PCIe IP and thus inherits all
-the common properties defined in mobiveil-pcie.txt.
-
-Required properties:
-- compatible: should contain the platform identifier such as:
-  "fsl,lx2160a-pcie"
-- reg: base addresses and lengths of the PCIe controller register blocks.
-  "csr_axi_slave": Bridge config registers
-  "config_axi_slave": PCIe controller registers
-- interrupts: A list of interrupt outputs of the controller. Must contain an
-  entry for each entry in the interrupt-names property.
-- interrupt-names: It could include the following entries:
-  "intr": The interrupt that is asserted for controller interrupts
-  "aer": Asserted for aer interrupt when chip support the aer interrupt with
-	 none MSI/MSI-X/INTx mode,but there is interrupt line for aer.
-  "pme": Asserted for pme interrupt when chip support the pme interrupt with
-	 none MSI/MSI-X/INTx mode,but there is interrupt line for pme.
-- dma-coherent: Indicates that the hardware IP block can ensure the coherency
-  of the data transferred from/to the IP block. This can avoid the software
-  cache flush/invalid actions, and improve the performance significantly.
-- msi-parent : See the generic MSI binding described in
-  Documentation/devicetree/bindings/interrupt-controller/msi.txt.
-
-Example:
-
-	pcie at 3400000 {
-		compatible = "fsl,lx2160a-pcie";
-		reg = <0x00 0x03400000 0x0 0x00100000   /* controller registers */
-		       0x80 0x00000000 0x0 0x00001000>; /* configuration space */
-		reg-names = "csr_axi_slave", "config_axi_slave";
-		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */
-			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
-			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
-		interrupt-names = "aer", "pme", "intr";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		apio-wins = <8>;
-		ppio-wins = <8>;
-		dma-coherent;
-		bus-range = <0x0 0xff>;
-		msi-parent = <&its>;
-		ranges = <0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>;
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 7>;
-		interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
-				<0000 0 0 2 &gic 0 0 GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
-				<0000 0 0 3 &gic 0 0 GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
-				<0000 0 0 4 &gic 0 0 GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-	};
diff --git a/Documentation/devicetree/bindings/pci/mbvl,gpex40-pcie.yaml b/Documentation/devicetree/bindings/pci/mbvl,gpex40-pcie.yaml
new file mode 100644
index 0000000000000..160ddc4bc45bf
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/mbvl,gpex40-pcie.yaml
@@ -0,0 +1,167 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/mbvl,gpex40-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mobiveil AXI PCIe Root Port Bridge
+
+maintainers:
+  - Frank Li <Frank Li at nxp.com>
+
+description:
+  Mobiveil's GPEX 4.0 is a PCIe Gen4 root port bridge IP. This configurable IP
+  has up to 8 outbound and inbound windows for the address translation.
+
+  NXP Layerscape PCIe Gen4 controller (Deprecated) base on Mobiveil's GPEX 4.0.
+
+properties:
+  compatible:
+    enum:
+      - mbvl,gpex40-pcie
+      - fsl,lx2160a-pcie
+
+  reg:
+    items:
+      - description: PCIe controller registers
+      - description: Bridge config registers
+      - description: GPIO registers to control slot power
+      - description: MSI registers
+    minItems: 2
+
+  reg-names:
+    items:
+      - const: csr_axi_slave
+      - const: config_axi_slave
+      - const: gpio_slave
+      - const: apb_csr
+    minItems: 2
+
+  apio-wins:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      numbers of requested apio outbound windows
+        1. Config window
+        2. Memory window
+    default: 2
+    maximum: 256
+
+  ppio-wins:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: number of requested ppio inbound windows
+    default: 1
+    maximum: 256
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 3
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 3
+
+  dma-coherent: true
+
+  msi-parent: true
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+allOf:
+  - $ref: /schemas/pci/pci-host-bridge.yaml#
+  - if:
+      properties:
+        compatible:
+          enum:
+            - fsl,lx2160a-pcie
+    then:
+      properties:
+        reg:
+          maxItems: 2
+
+        reg-names:
+          maxItems: 2
+
+        interrupt-names:
+          items:
+            - const: aer
+            - const: pme
+            - const: intr
+    else:
+      properties:
+        dma-coherent: false
+        msi-parent: false
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    pcie at b0000000 {
+        compatible = "mbvl,gpex40-pcie";
+        reg = <0xb0000000 0x00010000>,
+              <0xa0000000 0x00001000>,
+              <0xff000000 0x00200000>,
+              <0xb0010000 0x00001000>;
+        reg-names = "csr_axi_slave",
+                    "config_axi_slave",
+                    "gpio_slave",
+                    "apb_csr";
+        #address-cells = <3>;
+        #size-cells = <2>;
+        device_type = "pci";
+        apio-wins = <2>;
+        ppio-wins = <1>;
+        bus-range = <0x00000000 0x000000ff>;
+        interrupt-controller;
+        #interrupt-cells = <1>;
+        interrupt-parent = <&gic>;
+        interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-map-mask = <0 0 0 7>;
+        interrupt-map = <0 0 0 0 &pci_express 0>,
+                        <0 0 0 1 &pci_express 1>,
+                        <0 0 0 2 &pci_express 2>,
+                        <0 0 0 3 &pci_express 3>;
+        ranges = <0x83000000 0 0x00000000 0xa8000000 0 0x8000000>;
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+        pcie at 3400000 {
+            compatible = "fsl,lx2160a-pcie";
+            reg = <0x00 0x03400000 0x0 0x00100000   /* controller registers */
+                   0x80 0x00000000 0x0 0x00001000>; /* configuration space */
+            reg-names = "csr_axi_slave", "config_axi_slave";
+            interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* AER interrupt */
+                         <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, /* PME interrupt */
+                        <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
+            interrupt-names = "aer", "pme", "intr";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            device_type = "pci";
+            apio-wins = <8>;
+            ppio-wins = <8>;
+            dma-coherent;
+            bus-range = <0x0 0xff>;
+            msi-parent = <&its>;
+            ranges = <0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>;
+            #interrupt-cells = <1>;
+            interrupt-map-mask = <0 0 0 7>;
+            interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+                            <0000 0 0 2 &gic 0 0 GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+                            <0000 0 0 3 &gic 0 0 GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+                            <0000 0 0 4 &gic 0 0 GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt b/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
deleted file mode 100644
index 64156993e052d..0000000000000
--- a/Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-* Mobiveil AXI PCIe Root Port Bridge DT description
-
-Mobiveil's GPEX 4.0 is a PCIe Gen4 root port bridge IP. This configurable IP
-has up to 8 outbound and inbound windows for the address translation.
-
-Required properties:
-- #address-cells: Address representation for root ports, set to <3>
-- #size-cells: Size representation for root ports, set to <2>
-- #interrupt-cells: specifies the number of cells needed to encode an
-	interrupt source. The value must be 1.
-- compatible: Should contain "mbvl,gpex40-pcie"
-- reg: Should contain PCIe registers location and length
-	Mandatory:
-	"config_axi_slave": PCIe controller registers
-	"csr_axi_slave"	  : Bridge config registers
-	Optional:
-	"gpio_slave"	  : GPIO registers to control slot power
-	"apb_csr"	  : MSI registers
-
-- device_type: must be "pci"
-- apio-wins : number of requested apio outbound windows
-		default 2 outbound windows are configured -
-		1. Config window
-		2. Memory window
-- ppio-wins : number of requested ppio inbound windows
-		default 1 inbound memory window is configured.
-- bus-range: PCI bus numbers covered
-- interrupt-controller: identifies the node as an interrupt controller
-- #interrupt-cells: specifies the number of cells needed to encode an
-	interrupt source. The value must be 1.
-- interrupts: The interrupt line of the PCIe controller
-		last cell of this field is set to 4 to
-		denote it as IRQ_TYPE_LEVEL_HIGH type interrupt.
-- interrupt-map-mask,
-	interrupt-map: standard PCI properties to define the mapping of the
-	PCI interface to interrupt numbers.
-- ranges: ranges for the PCI memory regions (I/O space region is not
-	supported by hardware)
-	Please refer to the standard PCI bus binding document for a more
-	detailed explanation
-
-
-Example:
-++++++++
-	pcie0: pcie at a0000000 {
-		#address-cells = <3>;
-		#size-cells = <2>;
-		compatible = "mbvl,gpex40-pcie";
-		reg =	<0xa0000000 0x00001000>,
-			<0xb0000000 0x00010000>,
-			<0xff000000 0x00200000>,
-			<0xb0010000 0x00001000>;
-		reg-names =	"config_axi_slave",
-				"csr_axi_slave",
-				"gpio_slave",
-				"apb_csr";
-		device_type = "pci";
-		apio-wins = <2>;
-		ppio-wins = <1>;
-		bus-range = <0x00000000 0x000000ff>;
-		interrupt-controller;
-		interrupt-parent = <&gic>;
-		#interrupt-cells = <1>;
-		interrupts = < 0 89 4 >;
-		interrupt-map-mask = <0 0 0 7>;
-		interrupt-map = <0 0 0 0 &pci_express 0>,
-				<0 0 0 1 &pci_express 1>,
-				<0 0 0 2 &pci_express 2>,
-				<0 0 0 3 &pci_express 3>;
-		ranges = < 0x83000000 0 0x00000000 0xa8000000 0 0x8000000>;
-
-	};
-- 
2.34.1



From konrad.dybcio at oss.qualcomm.com  Thu Dec  5 12:34:38 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 5 Dec 2024 21:34:38 +0100
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on pre-SYSTEM_SUSPEND
 PSCI impls
In-Reply-To: <CAPDyKFpGrw+vOs=-TxfChBeORjzkpaL_iVB08MtmaC4sFNKzcg@mail.gmail.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <CAPDyKFpGrw+vOs=-TxfChBeORjzkpaL_iVB08MtmaC4sFNKzcg@mail.gmail.com>
Message-ID: <72add0ff-db2a-44f8-b4af-0b5fe5f65f20@oss.qualcomm.com>

On 14.11.2024 4:30 PM, Ulf Hansson wrote:
> On Mon, 28 Oct 2024 at 15:24, Konrad Dybcio <konradybcio at kernel.org> wrote:
>>
>> Certain firmwares expose exactly what PSCI_SYSTEM_SUSPEND does through
>> CPU_SUSPEND instead. Inform Linux about that.
>> Please see the commit messages for a more detailed explanation.
>>
>> This is effectively a more educated follow-up to [1].
>>
>> The ultimate goal is to stop making Linux think that certain states
>> only concern cores/clusters, and consequently setting
>> pm_set_suspend/resume_via_firmware(), so that client drivers (such as
>> NVMe, see related discussion over at [2]) can make informed decisions
>> about assuming the power state of the device they govern.
> 
> In my opinion, this is not really the correct way to do it. Using
> pm_set_suspend/resume_via_firmware() works fine for x86/ACPI, but not
> for PSCI like this. Let me elaborate. If the NVMe storage device is
> sharing the same power-rail as the CPU cluster, then yes we should use
> PSCI to control it. But is that really the case? If so, there are in
> principle two ways forward to deal with this correctly.
> 
> 1) If PSCI OSI mode is being used, the corresponding NVMe storage
> device should be hooked up to the CPU PM cluster domain via genpd and
> controlled as any other devices sharing the cluster-rail. In this way,
> genpd together with the cpuidle-psci-domain can decide whether it's
> okay to turn off the cluster. I believe this is the preferred way, but
> 2) would work fine too.
> 
> 2) If PSCI PC mode is being used, a separate channel/interface to the
> FW (like SCMI or rpmh in the QC case), should inform the FW whether
> NVMe needs the power to it. This information should then be taken into
> account by the PSCI FW when it decides what low-power-state to enter,
> which ultimately means whether the cluster-rail can be turned off or
> not.

This assumes PSCI only governs the CPU power rail. But what I'd
guesstimate is that in most implementations if system-level suspend is
there at all (no matter through which call), as per the spec, it at
least also projects onto the DDR power state (like in this i.mx
impl here [1]), or some uncore peripherals (like in Tegra's case with
some secure element being toggled at [2])

> Assuming PSCI OSI mode is used here. Then if 1) doesn't work for you,
> please elaborate on why, so we can help to make it work, as it should.

On Qualcomm platforms, RPMh is the central authority when it comes
to power governance, but by design, the CPUs must be off (and with a
specific magic cookie) for the RPMh hardware to consider powering off
very power hungry parts of the system, such as general i/o rails.

So again, PSCI must be fed a specific value for the rest of the hw
to react. The "S2RAM state" isn't really a cpuidle state, because
it doesn't differ from many shallower states as far as the cpu/cluster
are concerned. If that all isn't in place, the platform never actually
enters any "real" sleep state, other than "CPU and some controllable
IP blocks are runtime-suspended".

This effectively is very close to what ACPI+x86 do - there's a
co-processor/firmware that does a lot of things behind your back and
all you can do is *ask* it to change some handwavily-defined P/Cstate
that affects a huge chunk of silicon.

Konrad

[1] https://github.com/nxp-imx/imx-atf/blob/lf_v2.6/plat/imx/imx8m/imx8mp/imx8mp_lpa_psci.c#L474
[2] https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c#L214



From mailhol.vincent at wanadoo.fr  Thu Dec  5 07:53:56 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 00:53:56 +0900
Subject: [PATCH 06/10] fortify: replace __is_constexpr() by is_const() in strlen()
In-Reply-To: <ad4482cc835543578862051431f5174f@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-6-4e4cbaecc216@wanadoo.fr> <ad4482cc835543578862051431f5174f@AcuMS.aculab.com>
Message-ID: <CAMZ6RqJMXKaa_xDcyweGwb+FqvANrpvrkRvnjh6_s-J1ApVmaA@mail.gmail.com>

On Thu. 5 Dec. 2024 at 03:58, David Laight <David.Laight at aculab.com> wrote:
> From: Vincent Mailhol
> > Sent: 02 December 2024 17:33
> >
> > From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> >
> > is_const() is a one to one replacement of __is_constexpr(). Do the
> > replacement so that __is_constexpr() can be removed.
> >
> > Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> > ---
> >  include/linux/fortify-string.h | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
> > index 0d99bf11d260a3482bbe46e35c7553c0ccfb8b94..e3f2f772c5439ef71eb4a904b4ce27956bc69743 100644
> > --- a/include/linux/fortify-string.h
> > +++ b/include/linux/fortify-string.h
> > @@ -254,8 +254,8 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size
> >   * Returns number of characters in @p (NOT including the final NUL).
> >   *
> >   */
> > -#define strlen(p)                                                    \
> > -     __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)),      \
> > +#define strlen(p)                                            \
> > +     __builtin_choose_expr(is_const(__builtin_strlen(p)),    \
> >               __builtin_strlen(p), __fortify_strlen(p))
>
> I'm sure Linus suggested a way of doing that without replicating
> the __builtin_strlen().
>
> Indeed it may be valid to do:
>         len = __builtin_strlen(p);
>         __builtin_constant_p(len) ? len : __fortify_strlen(p);

Then, wouldn't it be better for strlen() to be an inline function
instead of a macro?

  __FORTIFY_INLINE __kernel_size_t strlen(const char *p)
  {
          __kernel_size_t ret = __builtin_strlen(p);

          if (__builtin_constant_p(ret))
                  return ret;
          return __fortify_strlen(p);
  }

I tested it and it worked on an allyesconfig. So if I receive no
objections, strlen() will become an inline function in v2.


Yours sincerely,
Vincent Mailhol


From mailhol.vincent at wanadoo.fr  Thu Dec  5 07:49:43 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 00:49:43 +0900
Subject: [PATCH 04/10] linux/bits.h: simplify GENMASK_INPUT_CHECK() by
 using is_const_true()
In-Reply-To: <dff4cdd543104e3792e4856375f310c1@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-4-4e4cbaecc216@wanadoo.fr> <dff4cdd543104e3792e4856375f310c1@AcuMS.aculab.com>
Message-ID: <CAMZ6RqLsiOF=5FZ=U2MtZ01iBYKZHtfZ5Zi4t3m=L5Oc4EPHGg@mail.gmail.com>

On Thu. 5 Dec 2024 at 03:52, David Laight <David.Laight at aculab.com> wrote:
> From: Vincent Mailhol
> > Sent: 02 December 2024 17:33
> >
> >   __builtin_choose_expr(__is_constexpr((l) > (h)), (l) > (h), 0)
> >
> > is equivalent to:
> >
> >   is_const_true((l) > (h))
>
> Change it to BUILD_BUG_ON_MSG(statically_true((l) < (h)), "error message")
>
> and then fix all the fallout :-)

BUILD_BUG_ON_MSG() is not suitable for GENMASK_INPUT_CHECK. We need
one of the variants that returns zero here.

But I agree that it is good to have a more meaningful error message
here. I will use __BUILD_BUG_ON_ZERO_MSG() in v2.


Yours sincerely,
Vincent Mailhol


From karprzy7 at gmail.com  Thu Dec  5 14:22:21 2024
From: karprzy7 at gmail.com (Karol Przybylski)
Date: Thu,  5 Dec 2024 23:22:21 +0100
Subject: [PATCHv2] HID: hid-thrustmaster: Fix warning in thrustmaster_probe by adding endpoint check
Message-ID: <20241205222221.3094702-1-karprzy7@gmail.com>

syzbot has found a type mismatch between a USB pipe and the transfer
endpoint, which is triggered by the hid-thrustmaster driver[1].
There is a number of similar, already fixed issues [2].
In this case as in others, implementing check for endpoint type fixes the issue.

[1] https://syzkaller.appspot.com/bug?extid=040e8b3db6a96908d470
[2] https://syzkaller.appspot.com/bug?extid=348331f63b034f89b622

Fixes: c49c33637802 ("HID: support for initialization of some Thrustmaster wheels")
Reported-by: syzbot+040e8b3db6a96908d470 at syzkaller.appspotmail.com
Tested-by: syzbot+040e8b3db6a96908d470 at syzkaller.appspotmail.com
Signed-off-by: Karol Przybylski <karprzy7 at gmail.com>
---
 drivers/hid/hid-thrustmaster.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/hid/hid-thrustmaster.c b/drivers/hid/hid-thrustmaster.c
index cf1679b0d..6c3e758bb 100644
--- a/drivers/hid/hid-thrustmaster.c
+++ b/drivers/hid/hid-thrustmaster.c
@@ -170,6 +170,14 @@ static void thrustmaster_interrupts(struct hid_device *hdev)
 	ep = &usbif->cur_altsetting->endpoint[1];
 	b_ep = ep->desc.bEndpointAddress;
 
+	/* Are the expected endpoints present? */
+	u8 ep_addr[1] = {b_ep};
+
+	if (!usb_check_int_endpoints(usbif, ep_addr)) {
+		hid_err(hdev, "Unexpected non-int endpoint\n");
+		return;
+	}
+
 	for (i = 0; i < ARRAY_SIZE(setup_arr); ++i) {
 		memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]);
 
-- 
2.34.1



From dmitry.baryshkov at linaro.org  Thu Dec  5 14:48:23 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 6 Dec 2024 00:48:23 +0200
Subject: [PATCH v4 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <20241205134021.2592013-3-andrej.picej@norik.com>
References: <20241205134021.2592013-1-andrej.picej@norik.com>
 <20241205134021.2592013-3-andrej.picej@norik.com>
Message-ID: <nbumcptoi5hwehjbrynf6dh2wrz7a4ugqblrjxyswvj7udkf3u@6qikclizqfjr>

On Thu, Dec 05, 2024 at 02:40:20PM +0100, Andrej Picej wrote:
> Add a optional properties to change LVDS output voltage. This should not
> be static as this depends mainly on the connected display voltage
> requirement. We have three properties:
> - "ti,lvds-termination-ohms", which sets near end termination,
> - "ti,lvds-vod-swing-data-microvolt" and
> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> output voltage for data and clock lanes. They are defined as an array
> with min and max values. The appropriate bitfield will be set if
> selected constraints can be met.
> 
> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> end termination will be used. Selecting only one:
> "ti,lvds-vod-swing-data-microvolt" or
> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> constraint for only data/clock lanes will be met. Setting both is
> recommended.
> 
> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> ---
> Changes in v4:
> - fix typo in commit message bitfiled -> bitfield
> - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
> of separate variables for channel A/B
> - add more checks on return value of "of_property_read_u32_array"
> Changes in v3:
> - use microvolts for default array values 1000 mV -> 1000000 uV.
> Changes in v2:
> - use datasheet tables to get the proper configuration
> - since major change was done change the authorship to myself
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi83.c | 147 +++++++++++++++++++++++++-
>  1 file changed, 144 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> index 57a7ed13f996..f724d2a6777b 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> @@ -132,6 +132,16 @@
>  #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>  #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>  
> +enum sn65dsi83_channel {
> +	CHANNEL_A,
> +	CHANNEL_B
> +};
> +
> +enum sn65dsi83_lvds_term {
> +	OHM_100,
> +	OHM_200
> +};
> +
>  enum sn65dsi83_model {
>  	MODEL_SN65DSI83,
>  	MODEL_SN65DSI84,
> @@ -147,6 +157,8 @@ struct sn65dsi83 {
>  	struct regulator		*vcc;
>  	bool				lvds_dual_link;
>  	bool				lvds_dual_link_even_odd_swap;
> +	int				lvds_vod_swing_conf[2];
> +	int				lvds_term_conf[2];
>  };
>  
>  static const struct regmap_range sn65dsi83_readable_ranges[] = {
> @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>  	.max_register = REG_IRQ_STAT,
>  };
>  
> +static const int lvds_vod_swing_data_table[2][4][2] = {
> +	{	/* 100 Ohm */
> +		{ 180000, 313000 },
> +		{ 215000, 372000 },
> +		{ 250000, 430000 },
> +		{ 290000, 488000 },
> +	},
> +	{	/* 200 Ohm */
> +		{ 150000, 261000 },
> +		{ 200000, 346000 },
> +		{ 250000, 428000 },
> +		{ 300000, 511000 },
> +	},
> +};
> +
> +static const int lvds_vod_swing_clock_table[2][4][2] = {
> +	{	/* 100 Ohm */
> +		{ 140000, 244000 },
> +		{ 168000, 290000 },
> +		{ 195000, 335000 },
> +		{ 226000, 381000 },
> +	},
> +	{	/* 200 Ohm */
> +		{ 117000, 204000 },
> +		{ 156000, 270000 },
> +		{ 195000, 334000 },
> +		{ 234000, 399000 },
> +	},
> +};
> +
>  static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>  {
>  	return container_of(bridge, struct sn65dsi83, bridge);
> @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>  		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>  
>  	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
>  	regmap_write(ctx->regmap, REG_LVDS_LANE,
>  		     (ctx->lvds_dual_link_even_odd_swap ?
>  		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
> +		     (ctx->lvds_term_conf[CHANNEL_A] ?
> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
> +		     (ctx->lvds_term_conf[CHANNEL_B] ?
> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>  	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>  
>  	le16val = cpu_to_le16(mode->hdisplay);
> @@ -576,10 +622,101 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>  	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>  };
>  
> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
> +{
> +	int i;
> +
> +	for (i = 0; i <= 3; i++) {
> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
> +			return i;
> +	}
> +
> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
> +	return -EINVAL;
> +}
> +
> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> +{
> +	struct device *dev = ctx->dev;
> +	struct device_node *endpoint;
> +	/* Set so the property can be freely selected if not defined */
> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
> +	u32 lvds_term = 200;
> +	u8 lvds_term_conf;
> +	int endpoint_reg;
> +	int lvds_vod_swing_conf;
> +	int ret = 0;
> +	int ret_data;
> +	int ret_clock;
> +
> +	if (channel == CHANNEL_A)
> +		endpoint_reg = 2;
> +	else
> +		endpoint_reg = 3;
> +
> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
> +	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
> +
> +	if (lvds_term == 200)
> +		lvds_term_conf = OHM_200;
> +	else
> +		lvds_term_conf = OHM_100;
> +
> +	ctx->lvds_term_conf[channel] = lvds_term_conf;
> +
> +	ret_data = of_property_read_u32_array(endpoint,
> +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
> +			ARRAY_SIZE(lvds_vod_swing_data));
> +	if (ret_data != 0 && ret_data != -EINVAL) {
> +		ret = ret_data;
> +		goto exit;
> +	}
> +
> +	ret_clock = of_property_read_u32_array(endpoint,
> +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
> +			ARRAY_SIZE(lvds_vod_swing_clk));
> +	if (ret_clock != 0 && ret_clock != -EINVAL) {
> +		ret = ret_clock;
> +		goto exit;
> +	}
> +
> +	/* If any of the two properties is defined. */
> +	if (!ret_data || !ret_clock) {
> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
> +			lvds_vod_swing_data, lvds_vod_swing_clk,
> +			lvds_term_conf);
> +		if (lvds_vod_swing_conf < 0) {
> +			ret = lvds_vod_swing_conf;
> +			goto exit;
> +		}
> +
> +		ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
> +	}
> +	ret = 0;
> +exit:
> +	of_node_put(endpoint);
> +	return ret;
> +}
> +
>  static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>  {
>  	struct drm_bridge *panel_bridge;
>  	struct device *dev = ctx->dev;
> +	int ret;
> +
> +	ctx->lvds_vod_swing_conf[CHANNEL_A] = 0x1;
> +	ctx->lvds_vod_swing_conf[CHANNEL_B] = 0x1;
> +	ctx->lvds_term_conf[CHANNEL_A] = 0x1;
> +	ctx->lvds_term_conf[CHANNEL_B] = 0x1;

These match the defaults in sn65dsi83_parse_lvds_endpoint(). Do we
really need those?

> +
> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
> +	if (ret < 0)
> +		return ret;
>  
>  	ctx->lvds_dual_link = false;
>  	ctx->lvds_dual_link_even_odd_swap = false;
> @@ -587,6 +724,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>  		struct device_node *port2, *port3;
>  		int dual_link;
>  
> +		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
> +		if (ret < 0)
> +			return ret;
> +
>  		port2 = of_graph_get_port_by_id(dev->of_node, 2);
>  		port3 = of_graph_get_port_by_id(dev->of_node, 3);
>  		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From lkp at intel.com  Thu Dec  5 14:48:57 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 6 Dec 2024 06:48:57 +0800
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
Message-ID: <202412060636.00bzNpm9-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 pza/reset/next linus/master drm-misc/drm-misc-next v6.13-rc1 next-20241205]
[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/AngeloGioacchino-Del-Regno/dt-bindings-display-mediatek-dpi-Add-MT8195-and-MT8188-compat/20241205-194853
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20241205114518.53527-16-angelogioacchino.delregno%40collabora.com
patch subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for MT8195/MT8188
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20241206/202412060636.00bzNpm9-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241206/202412060636.00bzNpm9-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/202412060636.00bzNpm9-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c:15:
   In file included from include/linux/i2c.h:13:
   In file included from include/linux/acpi.h:39:
   In file included from include/acpi/acpi_io.h:7:
   In file included from arch/arm64/include/asm/acpi.h:14:
   In file included from include/linux/memblock.h:12:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c:389:47: error: expected ';' after top level declarator
     389 | MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_v2_match)
         |                                               ^
         |                                               ;
   4 warnings and 1 error generated.


vim +389 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c

   384	
   385	static const struct of_device_id mtk_hdmi_ddc_v2_match[] = {
   386		{ .compatible = "mediatek,mt8195-hdmi-ddc" },
   387		{ /* sentinel */ }
   388	};
 > 389	MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_v2_match)
   390	

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


From khilman at baylibre.com  Thu Dec  5 15:07:00 2024
From: khilman at baylibre.com (Kevin Hilman)
Date: Thu, 05 Dec 2024 15:07:00 -0800
Subject: [PATCH] ARM: OMAP2+: Fix a typo
In-Reply-To: <ec20fd5c347bf74963532e95282f850d209d84d5.1730539664.git.christophe.jaillet@wanadoo.fr>
References: <ec20fd5c347bf74963532e95282f850d209d84d5.1730539664.git.christophe.jaillet@wanadoo.fr>
Message-ID: <173344002056.407600.10771943462992727832.b4-ty@baylibre.com>


On Sat, 02 Nov 2024 10:27:51 +0100, Christophe JAILLET wrote:
> A 'a' is missing in "powerdomin".
> Add it.
> 
> 

Applied, thanks!

[1/1] ARM: OMAP2+: Fix a typo
      (no commit info)

Best regards,
-- 
Kevin Hilman <khilman at baylibre.com>



From khilman at baylibre.com  Thu Dec  5 15:07:02 2024
From: khilman at baylibre.com (Kevin Hilman)
Date: Thu, 05 Dec 2024 15:07:02 -0800
Subject: [PATCHv3 1/2] dt-bindings: mfd: syscon: Add
 ti,j721e-acspcie-proxy-ctrl compatible
In-Reply-To: <20241202143331.126800-1-romain.naour@smile.fr>
References: <20241202143331.126800-1-romain.naour@smile.fr>
Message-ID: <173344002250.407600.8303166891165540615.b4-ty@baylibre.com>


On Mon, 02 Dec 2024 15:33:30 +0100, Romain Naour wrote:
> The ACSPCIE_PROXY_CTRL registers within the CTRL_MMR space of TI's J721e
> SoC are used to drive the reference clock to the PCIe Endpoint device via
> the PAD IO Buffers. Add the compatible for allowing the PCIe driver to
> obtain the regmap for the ACSPCIE_CTRL register within the System
> Controller device-tree node in order to enable the PAD IO Buffers.
> 
> The Technical Reference Manual for J721e SoC with details of the
> ASCPCIE_CTRL registers is available at:
> https://www.ti.com/lit/zip/spruil1
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: mfd: syscon: Add ti,j721e-acspcie-proxy-ctrl compatible
      commit: d8efc0b428856137608ffcbb6994da6041c9fe2a
[2/2] arm64: dts: ti: k3-j721e-beagleboneai64: Enable ACSPCIE output for PCIe1
      commit: 1d5e14a20dc60b440c60bec8489acfd45cdf7508

Best regards,
-- 
Kevin Hilman <khilman at baylibre.com>



From kuninori.morimoto.gx at renesas.com  Thu Dec  5 15:18:14 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Thu, 5 Dec 2024 23:18:14 +0000
Subject: [PATCH 0/5] arm64: renesas: Add R8A779G3 White Hawk Single support
In-Reply-To: <CAMuHMdWF7NcmKYzvF4Dfjh3S5MccbJrpSphK5BhxXNnhxgtmYQ@mail.gmail.com>
References: <cover.1733156661.git.geert+renesas@glider.be>
	<87jzcg1d2f.wl-kuninori.morimoto.gx@renesas.com>
	<CAMuHMdWF7NcmKYzvF4Dfjh3S5MccbJrpSphK5BhxXNnhxgtmYQ@mail.gmail.com>
Message-ID: <87y10tvhw1.wl-kuninori.morimoto.gx@renesas.com>


Hi Geert

> > But small nitpick is that R8A779G2 is not only for ES2.0 but for ES2.x
> 
> I didn't add any occurrences of "ES2.0" in this series ;-)

Almost, but we can see ;P

	[PATCH 5/5] arm64: dts: renesas: r8a779g3: Add White Hawk Single support
	...
	For now, there are no visible differences compared to the variant
=>	equipped with an R-Car V4H ES2.0 (R8A779G2) SoC.

> -              - renesas,r8a779g2
> -              - renesas,r8a779g3
> +              - renesas,r8a779g2 # ES2.x
> +              - renesas,r8a779g3 # ES3.0
> 
> but decided against doing so, as "ES3.0" would become stale as soon
> as Renesas releases "ES3.1". Alternatively, I could use "ES3.x"
> immediately.

Yeah, maybe, but will check.
Please wait.
Thank you for your help !!

Best regards
---
Kuninori Morimoto


From jthoughton at google.com  Thu Dec  5 15:31:05 2024
From: jthoughton at google.com (James Houghton)
Date: Thu, 5 Dec 2024 15:31:05 -0800
Subject: [PATCH v1 06/13] KVM: arm64: Add support for KVM_MEM_USERFAULT
In-Reply-To: <Z1Dgr_TnaFQT04Pi@linux.dev>
References: <20241204191349.1730936-1-jthoughton@google.com>
 <20241204191349.1730936-7-jthoughton@google.com> <Z1Dgr_TnaFQT04Pi@linux.dev>
Message-ID: <CADrL8HWC7HhYmEBWa+5KeWmyD+iT1zPBJUAUtNyrhH7ZpLXJNQ@mail.gmail.com>

On Wed, Dec 4, 2024 at 3:07?PM Oliver Upton <oliver.upton at linux.dev> wrote:
>
> Hi James,

Hi Oliver!

>
> On Wed, Dec 04, 2024 at 07:13:41PM +0000, James Houghton wrote:
> > Adhering to the requirements of KVM Userfault:
> >
> > 1. When it is toggled (either on or off), zap the second stage with
> >    kvm_arch_flush_shadow_memslot(). This is to (1) respect
> >    userfault-ness and (2) to reconstruct block mappings.
> > 2. While KVM_MEM_USERFAULT is enabled, restrict new second-stage mappings
> >    to be PAGE_SIZE, just like when dirty logging is enabled.
> >
> > Signed-off-by: James Houghton <jthoughton at google.com>
> > ---
> >   I'm not 100% sure if kvm_arch_flush_shadow_memslot() is correct in
> >   this case (like if the host does not have S2FWB).
>
> Invalidating the stage-2 entries is of course necessary for correctness
> on the !USERFAULT -> USERFAULT transition, and the MMU will do the right
> thing regardless of whether hardware implements FEAT_S2FWB.
>
> What I think you may be getting at is the *performance* implications are
> quite worrying without FEAT_S2FWB due to the storm of CMOs, and I'd
> definitely agree with that.

Thanks for clarifying that for me.

> > @@ -2062,6 +2069,20 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
> >                                  enum kvm_mr_change change)
> >  {
> >       bool log_dirty_pages = new && new->flags & KVM_MEM_LOG_DIRTY_PAGES;
> > +     u32 changed_flags = (new ? new->flags : 0) ^ (old ? old->flags : 0);
> > +
> > +     /*
> > +      * If KVM_MEM_USERFAULT changed, drop all the stage-2 mappings so that
> > +      * we can (1) respect userfault-ness or (2) create block mappings.
> > +      */
> > +     if ((changed_flags & KVM_MEM_USERFAULT) && change == KVM_MR_FLAGS_ONLY)
> > +             kvm_arch_flush_shadow_memslot(kvm, old);
>
> I'd strongly prefer that we make (2) a userspace problem and don't
> eagerly invalidate stage-2 mappings on the USERFAULT -> !USERFAULT
> change.
>
> Having implied user-visible behaviors on ioctls is never good, and for
> systems without FEAT_S2FWB you might be better off avoiding the unmap in
> the first place.
>
> So, if userspace decides there's a benefit to invalidating the stage-2
> MMU, it can just delete + recreate the memslot.

Ok I think that's reasonable. So for USERFAULT -> !USERFAULT, I'll
just follow the precedent set by dirty logging. For x86 today, we
collapse the mappings, and for arm64 we do not.

Is arm64 ever going to support collapsing back to huge mappings after
dirty logging is disabled?


From kuninori.morimoto.gx at renesas.com  Thu Dec  5 15:37:43 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Thu, 5 Dec 2024 23:37:43 +0000
Subject: [PATCH 0/2] arm64: dts: renesas: white-hawk-single: Add R-Car Sound support
In-Reply-To: <cover.1733402907.git.geert+renesas@glider.be>
References: <cover.1733402907.git.geert+renesas@glider.be>
Message-ID: <87v7vxvgzc.wl-kuninori.morimoto.gx@renesas.com>


Hi Geert

> This patch series add R-Car Sound support for the various variants of
> the White Hawk Single development board, using the ARD-AUDIO-DA7212
> external audio board.
> 
> The second hunk in the second patch depends on "[PATCH 0/5] arm64:
> renesas: Add R8A779G3 White Hawk Single support"[1]..
> This was compile-tested only, due to lack of hardware.

For all patches

Reviewed-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>


Thank you for your help !!

Best regards
---
Kuninori Morimoto


From daniel.lezcano at linaro.org  Thu Dec  5 15:39:56 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 6 Dec 2024 00:39:56 +0100
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <20241205175345.201595-3-tudor.ambarus@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-3-tudor.ambarus@linaro.org>
Message-ID: <ce757b8e-4e6c-4ba9-9483-b57e6e230fdf@linaro.org>

On 12/5/24 18:53, Tudor Ambarus wrote:
> Alive Clock and Power Manager (ACPM) Message Protocol is defined for
> the purpose of communication between the ACPM firmware and masters
> (AP, AOC, ...). ACPM firmware operates on the Active Power Management
> (APM) module that handles overall power activities.
> 
> ACPM and masters regard each other as independent hardware component and
> communicate with each other using mailbox messages and shared memory.
> 
> This protocol library provides the interface for all the client drivers
> making use of the features offered by the APM. Add ACPM protocol support.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>   drivers/firmware/Kconfig                      |   1 +
>   drivers/firmware/Makefile                     |   1 +
>   drivers/firmware/samsung/Kconfig              |  14 +
>   drivers/firmware/samsung/Makefile             |   4 +
>   drivers/firmware/samsung/exynos-acpm-pmic.c   | 226 +++++
>   drivers/firmware/samsung/exynos-acpm-pmic.h   |  24 +
>   drivers/firmware/samsung/exynos-acpm.c        | 772 ++++++++++++++++++
>   drivers/firmware/samsung/exynos-acpm.h        |  15 +
>   .../linux/soc/samsung/exynos-acpm-protocol.h  |  57 ++
>   9 files changed, 1114 insertions(+)
>   create mode 100644 drivers/firmware/samsung/Kconfig
>   create mode 100644 drivers/firmware/samsung/Makefile
>   create mode 100644 drivers/firmware/samsung/exynos-acpm-pmic.c
>   create mode 100644 drivers/firmware/samsung/exynos-acpm-pmic.h
>   create mode 100644 drivers/firmware/samsung/exynos-acpm.c
>   create mode 100644 drivers/firmware/samsung/exynos-acpm.h
>   create mode 100644 include/linux/soc/samsung/exynos-acpm-protocol.h
> 
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> index 71d8b26c4103..24edb956831b 100644
> --- a/drivers/firmware/Kconfig
> +++ b/drivers/firmware/Kconfig
> @@ -267,6 +267,7 @@ source "drivers/firmware/meson/Kconfig"
>   source "drivers/firmware/microchip/Kconfig"
>   source "drivers/firmware/psci/Kconfig"
>   source "drivers/firmware/qcom/Kconfig"
> +source "drivers/firmware/samsung/Kconfig"
>   source "drivers/firmware/smccc/Kconfig"
>   source "drivers/firmware/tegra/Kconfig"
>   source "drivers/firmware/xilinx/Kconfig"
> diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
> index 7a8d486e718f..91efcc868a05 100644
> --- a/drivers/firmware/Makefile
> +++ b/drivers/firmware/Makefile
> @@ -33,6 +33,7 @@ obj-y				+= efi/
>   obj-y				+= imx/
>   obj-y				+= psci/
>   obj-y				+= qcom/
> +obj-y				+= samsung/
>   obj-y				+= smccc/
>   obj-y				+= tegra/
>   obj-y				+= xilinx/
> diff --git a/drivers/firmware/samsung/Kconfig b/drivers/firmware/samsung/Kconfig
> new file mode 100644
> index 000000000000..eed8cd8a677b
> --- /dev/null
> +++ b/drivers/firmware/samsung/Kconfig
> @@ -0,0 +1,14 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +config EXYNOS_ACPM_PROTOCOL
> +	tristate "Exynos Alive Clock and Power Manager (ACPM) Message Protocol"

Given the importance of this driver where a lot of PM services rely on, 
does it really make sense to allow it as a module ?

Some PM services may be needed very early in the boot process

-- 
<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 andrew at lunn.ch  Thu Dec  5 15:45:25 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 6 Dec 2024 00:45:25 +0100
Subject: [PATCH net-next v8 01/15] net: stmmac: Fix CSR divider comment
In-Reply-To: <Z1Ha+me4+hbOj9JO@lsv051416.swis.nl-cdc01.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
 <20241205-upstream_s32cc_gmac-v8-1-ec1d180df815@oss.nxp.com>
 <Z1HaB6hT0QX4Jlyx@shell.armlinux.org.uk>
 <Z1Ha+me4+hbOj9JO@lsv051416.swis.nl-cdc01.nxp.com>
Message-ID: <2706b154-737e-467c-8ea4-c9356bdc0720@lunn.ch>

On Thu, Dec 05, 2024 at 05:55:22PM +0100, Jan Petrous wrote:
> On Thu, Dec 05, 2024 at 04:51:19PM +0000, Russell King (Oracle) wrote:
> > On Thu, Dec 05, 2024 at 05:42:58PM +0100, Jan Petrous via B4 Relay wrote:
> > > From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>
> > > 
> > > The comment in declaration of STMMAC_CSR_250_300M
> > > incorrectly describes the constant as '/* MDC = clk_scr_i/122 */'
> > > but the DWC Ether QOS Handbook version 5.20a says it is
> > > CSR clock/124.
> > > 
> > > Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>
> > > Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
> > 
> > I gave my reviewed-by for this patch in the previous posting, but you
> > haven't included it.
> > 
> > Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> 
> Hi Russell,
> sorry for that, I missed it. Should I resend the v8 series?

b4 is pretty good at handling this, it will find such tags and add
them to your patchset if you are using b4 to manage it.

	Andrew


From olteanv at gmail.com  Thu Dec  5 15:57:09 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Fri, 6 Dec 2024 01:57:09 +0200
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <675200c3.7b0a0220.236ac3.9edf@mx.google.com>
References: <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <20241205180539.6t5iz2m3wjjwyxp3@skbuf>
 <6751f125.5d0a0220.255b79.7be0@mx.google.com>
 <20241205185037.g6cqejgad5jamj7r@skbuf>
 <675200c3.7b0a0220.236ac3.9edf@mx.google.com>
Message-ID: <20241205235709.pa5shi7mh26cnjhn@skbuf>

On Thu, Dec 05, 2024 at 08:36:30PM +0100, Christian Marangi wrote:
> > I guess the non-hack solution would be to permit MDIO buses to have
> > #size-cells = 1, and MDIO devices to acquire a range of the address
> > space, rather than just one address. Though take this with a grain of
> > salt, I have a lot more to learn.
> 
> I remember this was an idea when PHY Package API were proposed and was
> rejected as we wanted PHY to be single reg.

Would that effort have helped with MDIO devices, in the way it was proposed?
Why did it die out?

> > If neither of those are options, in principle the hack with just
> > selecting, randomly, one of the N internal PHY addresses as the central
> > MDIO address should work equally fine regardless of whether we are
> > talking about the DSA switch's MDIO address here, or the MFD device's
> > MDIO address.
> > 
> > With MFD you still have the option of creating a fake MDIO controller
> > child device, which has mdio-parent-bus = <&host_bus>, and redirecting
> > all user port phy-handles to children of this bus. Since all regmap I/O
> > of this fake MDIO bus goes to the MFD driver, you can implement there
> > your hacks with page switching etc etc, and it should be equally
> > safe.
> 
> I wonder if a node like this would be more consistent and descriptive?
> 
> mdio_bus: mdio-bus {
>     #address-cells = <1>;
>     #size-cells = <0>;
> 
>     ...
> 
>     mfd at 1 {
>             compatible = "airoha,an8855-mfd";
>             reg = <1>;
> 
>             nvmem_node {
>                     ...
>             };
> 
>             switch_node {
>                 ports {
>                         port at 0 {
>                                 phy-handle = <&phy>;
>                         };
> 
>                         port at 1 {
>                                 phy-handle = <&phy_2>;
>                         }
>                 };
>             };
> 
>             phy: phy_node {
> 
>             };
>     };
> 
>     phy_2: phy at 2 {
>         reg = <2>;
>     }
> 
>     phy at 3 {
>         reg = <3>;
>     }
> 
>     ..
> };
> 
> No idea how to register that single phy in mfd... I guess a fake mdio is
> needed anyway... What do you think of this node example? Or not worth it
> and better have the fake MDIO with all the switch PHY in it?

Could you work with something like this? dtc seems to swallow it without
any warnings...

mdio_bus: mdio {
        #address-cells = <1>;
        #size-cells = <0>;

        soc at 1 {
                compatible = "airoha,an8855";
                reg = <1>, <2>, <3>, <4>;
                reg-names = "phy0", "phy1", "phy2", "phy3";

                nvmem {
                        compatible = "airoha,an8855-nvmem";
                };

                ethernet-switch {
                        compatible = "airoha,an8855-switch";

                        ethernet-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;

                                ethernet-port at 0 {
                                        reg = <0>;
                                        phy-handle = <&phy0>;
                                        phy-mode = "internal";
                                };

                                ethernet-port at 1 {
                                        reg = <1>;
                                        phy-handle = <&phy1>;
                                        phy-mode = "internal";
                                };

                                ethernet-port at 2 {
                                        reg = <2>;
                                        phy-handle = <&phy2>;
                                        phy-mode = "internal";
                                };

                                ethernet-port at 3 {
                                        reg = <3>;
                                        phy-handle = <&phy3>;
                                        phy-mode = "internal";
                                };
                        };
                };

                mdio {
                        compatible = "airoha,an8855-mdio";
                        mdio-parent-bus = <&host_mdio>;
                        #address-cells = <1>;
                        #size-cells = <0>;

                        phy0: ethernet-phy at 1 {
                                reg = <1>;
                        };

                        phy1: ethernet-phy at 2 {
                                reg = <2>;
                        };

                        phy2: ethernet-phy at 3 {
                                reg = <3>;
                        };

                        phy3: ethernet-phy at 4 {
                                reg = <4>;
                        };
                };
        };
};


From saravanak at google.com  Thu Dec  5 16:04:55 2024
From: saravanak at google.com (Saravana Kannan)
Date: Thu, 5 Dec 2024 16:04:55 -0800
Subject: [PATCH AUTOSEL 6.1 4/8] drm: display: Set fwnode for aux bus devices
In-Reply-To: <20241204221859.2248634-4-sashal@kernel.org>
References: <20241204221859.2248634-1-sashal@kernel.org> <20241204221859.2248634-4-sashal@kernel.org>
Message-ID: <CAGETcx-u9BuPLiJ+Hn_29xmR_W3d7jC=uPFsw70eC65CZ_9UtQ@mail.gmail.com>

On Wed, Dec 4, 2024 at 3:30?PM Sasha Levin <sashal at kernel.org> wrote:
>
> From: Saravana Kannan <saravanak at google.com>
>
> [ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]
>
> fwnode needs to be set for a device for fw_devlink to be able to
> track/enforce its dependencies correctly. Without this, you'll see error
> messages like this when the supplier has probed and tries to make sure
> all its fwnode consumers are linked to it using device links:
>
> mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0
>
> Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
> Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> Signed-off-by: Saravana Kannan <saravanak at google.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Reviewed-by: Thierry Reding <treding at nvidia.com>
> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
> Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Sasha Levin <sashal at kernel.org>

As mentioned in the original cover letter:

PSA: Do not pull any of these patches into stable kernels. fw_devlink
had a lot of changes that landed in the last year. It's hard to ensure
cherry-picks have picked up all the dependencies correctly. If any of
these really need to get cherry-picked into stable kernels, cc me and
wait for my explicit Ack.

Is there a pressing need for this in 4.19?

-Saravana

> ---
>  drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> index f5741b45ca077..951170e1d5d14 100644
> --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c
> +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> @@ -287,7 +287,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux,
>         aux_ep->dev.parent = aux->dev;
>         aux_ep->dev.bus = &dp_aux_bus_type;
>         aux_ep->dev.type = &dp_aux_device_type_type;
> -       aux_ep->dev.of_node = of_node_get(np);
> +       device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np)));
>         dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev));
>
>         ret = device_register(&aux_ep->dev);
> --
> 2.43.0
>


From saravanak at google.com  Thu Dec  5 16:06:58 2024
From: saravanak at google.com (Saravana Kannan)
Date: Thu, 5 Dec 2024 16:06:58 -0800
Subject: [PATCH AUTOSEL 6.12 08/15] drm: display: Set fwnode for aux bus devices
In-Reply-To: <20241204221627.2247598-8-sashal@kernel.org>
References: <20241204221627.2247598-1-sashal@kernel.org> <20241204221627.2247598-8-sashal@kernel.org>
Message-ID: <CAGETcx-8nwfbCHN7zG7XuOM+CRevEU6M8fqaw1H4h+yz-H2BoQ@mail.gmail.com>

On Wed, Dec 4, 2024 at 3:28?PM Sasha Levin <sashal at kernel.org> wrote:
>
> From: Saravana Kannan <saravanak at google.com>
>
> [ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]
>
> fwnode needs to be set for a device for fw_devlink to be able to
> track/enforce its dependencies correctly. Without this, you'll see error
> messages like this when the supplier has probed and tries to make sure
> all its fwnode consumers are linked to it using device links:
>
> mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0
>
> Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
> Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> Signed-off-by: Saravana Kannan <saravanak at google.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Reviewed-by: Thierry Reding <treding at nvidia.com>
> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
> Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Sasha Levin <sashal at kernel.org>

I'm okay pulling this into 6.12 as it's recent enough.

-Saravana

> ---
>  drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> index d810529ebfb6e..ec7eac6b595f7 100644
> --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c
> +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> @@ -292,7 +292,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux,
>         aux_ep->dev.parent = aux->dev;
>         aux_ep->dev.bus = &dp_aux_bus_type;
>         aux_ep->dev.type = &dp_aux_device_type_type;
> -       aux_ep->dev.of_node = of_node_get(np);
> +       device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np)));
>         dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev));
>
>         ret = device_register(&aux_ep->dev);
> --
> 2.43.0
>


From saravanak at google.com  Thu Dec  5 16:05:35 2024
From: saravanak at google.com (Saravana Kannan)
Date: Thu, 5 Dec 2024 16:05:35 -0800
Subject: [PATCH AUTOSEL 6.6 04/10] drm: display: Set fwnode for aux bus devices
In-Reply-To: <20241204221820.2248367-4-sashal@kernel.org>
References: <20241204221820.2248367-1-sashal@kernel.org> <20241204221820.2248367-4-sashal@kernel.org>
Message-ID: <CAGETcx9RpUz0hR-X+rO6yKRxOmrMLveU7EMSACF49kMTMqdaRg@mail.gmail.com>

On Wed, Dec 4, 2024 at 3:29?PM Sasha Levin <sashal at kernel.org> wrote:
>
> From: Saravana Kannan <saravanak at google.com>
>
> [ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]
>
> fwnode needs to be set for a device for fw_devlink to be able to
> track/enforce its dependencies correctly. Without this, you'll see error
> messages like this when the supplier has probed and tries to make sure
> all its fwnode consumers are linked to it using device links:
>
> mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0
>
> Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
> Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> Signed-off-by: Saravana Kannan <saravanak at google.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Reviewed-by: Thierry Reding <treding at nvidia.com>
> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
> Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Sasha Levin <sashal at kernel.org>

As mentioned in the original cover letter:

PSA: Do not pull any of these patches into stable kernels. fw_devlink
had a lot of changes that landed in the last year. It's hard to ensure
cherry-picks have picked up all the dependencies correctly. If any of
these really need to get cherry-picked into stable kernels, cc me and
wait for my explicit Ack.

Is there a pressing need for this in 4.19?

-Saravana

> ---
>  drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> index 8a165be1a8214..d15c0f184983b 100644
> --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c
> +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> @@ -292,7 +292,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux,
>         aux_ep->dev.parent = aux->dev;
>         aux_ep->dev.bus = &dp_aux_bus_type;
>         aux_ep->dev.type = &dp_aux_device_type_type;
> -       aux_ep->dev.of_node = of_node_get(np);
> +       device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np)));
>         dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev));
>
>         ret = device_register(&aux_ep->dev);
> --
> 2.43.0
>


From saravanak at google.com  Thu Dec  5 16:06:02 2024
From: saravanak at google.com (Saravana Kannan)
Date: Thu, 5 Dec 2024 16:06:02 -0800
Subject: [PATCH AUTOSEL 6.11 08/15] drm: display: Set fwnode for aux bus devices
In-Reply-To: <20241204221726.2247988-8-sashal@kernel.org>
References: <20241204221726.2247988-1-sashal@kernel.org> <20241204221726.2247988-8-sashal@kernel.org>
Message-ID: <CAGETcx8bhzGZKge4qfpNR8FaTWqbo0-5J9c7whc3pn-RECJs3Q@mail.gmail.com>

On Wed, Dec 4, 2024 at 3:29?PM Sasha Levin <sashal at kernel.org> wrote:
>
> From: Saravana Kannan <saravanak at google.com>
>
> [ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]
>
> fwnode needs to be set for a device for fw_devlink to be able to
> track/enforce its dependencies correctly. Without this, you'll see error
> messages like this when the supplier has probed and tries to make sure
> all its fwnode consumers are linked to it using device links:
>
> mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0
>
> Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
> Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> Signed-off-by: Saravana Kannan <saravanak at google.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Reviewed-by: Thierry Reding <treding at nvidia.com>
> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
> Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Sasha Levin <sashal at kernel.org>

As mentioned in the original cover letter:

PSA: Do not pull any of these patches into stable kernels. fw_devlink
had a lot of changes that landed in the last year. It's hard to ensure
cherry-picks have picked up all the dependencies correctly. If any of
these really need to get cherry-picked into stable kernels, cc me and
wait for my explicit Ack.

Is there a pressing need for this in 4.19?

-Saravana

> ---
>  drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> index d810529ebfb6e..ec7eac6b595f7 100644
> --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c
> +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> @@ -292,7 +292,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux,
>         aux_ep->dev.parent = aux->dev;
>         aux_ep->dev.bus = &dp_aux_bus_type;
>         aux_ep->dev.type = &dp_aux_device_type_type;
> -       aux_ep->dev.of_node = of_node_get(np);
> +       device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np)));
>         dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev));
>
>         ret = device_register(&aux_ep->dev);
> --
> 2.43.0
>


From saravanak at google.com  Thu Dec  5 16:07:45 2024
From: saravanak at google.com (Saravana Kannan)
Date: Thu, 5 Dec 2024 16:07:45 -0800
Subject: [PATCH AUTOSEL 6.11 08/15] drm: display: Set fwnode for aux bus devices
In-Reply-To: <CAGETcx8bhzGZKge4qfpNR8FaTWqbo0-5J9c7whc3pn-RECJs3Q@mail.gmail.com>
References: <20241204221726.2247988-1-sashal@kernel.org> <20241204221726.2247988-8-sashal@kernel.org>
 <CAGETcx8bhzGZKge4qfpNR8FaTWqbo0-5J9c7whc3pn-RECJs3Q@mail.gmail.com>
Message-ID: <CAGETcx-6yHV5xr1j7krY8LShCF5JATX0NSwjeRUL9+3TLCMq9w@mail.gmail.com>

On Thu, Dec 5, 2024 at 4:06?PM Saravana Kannan <saravanak at google.com> wrote:
>
> On Wed, Dec 4, 2024 at 3:29?PM Sasha Levin <sashal at kernel.org> wrote:
> >
> > From: Saravana Kannan <saravanak at google.com>
> >
> > [ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]
> >
> > fwnode needs to be set for a device for fw_devlink to be able to
> > track/enforce its dependencies correctly. Without this, you'll see error
> > messages like this when the supplier has probed and tries to make sure
> > all its fwnode consumers are linked to it using device links:
> >
> > mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0
> >
> > Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> > Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
> > Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> > Signed-off-by: Saravana Kannan <saravanak at google.com>
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > Reviewed-by: Thierry Reding <treding at nvidia.com>
> > Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
> > Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> > Signed-off-by: Sasha Levin <sashal at kernel.org>
>
> As mentioned in the original cover letter:
>
> PSA: Do not pull any of these patches into stable kernels. fw_devlink
> had a lot of changes that landed in the last year. It's hard to ensure
> cherry-picks have picked up all the dependencies correctly. If any of
> these really need to get cherry-picked into stable kernels, cc me and
> wait for my explicit Ack.
>
> Is there a pressing need for this in 4.19?

I copy pasted this into several replies. In all those cases I meant
the kernel version mentioned in the subject.

-Saravana

>
> -Saravana
>
> > ---
> >  drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> > index d810529ebfb6e..ec7eac6b595f7 100644
> > --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c
> > +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c
> > @@ -292,7 +292,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux,
> >         aux_ep->dev.parent = aux->dev;
> >         aux_ep->dev.bus = &dp_aux_bus_type;
> >         aux_ep->dev.type = &dp_aux_device_type_type;
> > -       aux_ep->dev.of_node = of_node_get(np);
> > +       device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np)));
> >         dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev));
> >
> >         ret = device_register(&aux_ep->dev);
> > --
> > 2.43.0
> >


From oliver.upton at linux.dev  Thu Dec  5 16:45:45 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 5 Dec 2024 16:45:45 -0800
Subject: [PATCH v1 06/13] KVM: arm64: Add support for KVM_MEM_USERFAULT
In-Reply-To: <CADrL8HWC7HhYmEBWa+5KeWmyD+iT1zPBJUAUtNyrhH7ZpLXJNQ@mail.gmail.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
 <20241204191349.1730936-7-jthoughton@google.com>
 <Z1Dgr_TnaFQT04Pi@linux.dev>
 <CADrL8HWC7HhYmEBWa+5KeWmyD+iT1zPBJUAUtNyrhH7ZpLXJNQ@mail.gmail.com>
Message-ID: <Z1JJOfnuKQ9LCHq-@linux.dev>

On Thu, Dec 05, 2024 at 03:31:05PM -0800, James Houghton wrote:
> > > @@ -2062,6 +2069,20 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
> > >                                  enum kvm_mr_change change)
> > >  {
> > >       bool log_dirty_pages = new && new->flags & KVM_MEM_LOG_DIRTY_PAGES;
> > > +     u32 changed_flags = (new ? new->flags : 0) ^ (old ? old->flags : 0);
> > > +
> > > +     /*
> > > +      * If KVM_MEM_USERFAULT changed, drop all the stage-2 mappings so that
> > > +      * we can (1) respect userfault-ness or (2) create block mappings.
> > > +      */
> > > +     if ((changed_flags & KVM_MEM_USERFAULT) && change == KVM_MR_FLAGS_ONLY)
> > > +             kvm_arch_flush_shadow_memslot(kvm, old);
> >
> > I'd strongly prefer that we make (2) a userspace problem and don't
> > eagerly invalidate stage-2 mappings on the USERFAULT -> !USERFAULT
> > change.
> >
> > Having implied user-visible behaviors on ioctls is never good, and for
> > systems without FEAT_S2FWB you might be better off avoiding the unmap in
> > the first place.
> >
> > So, if userspace decides there's a benefit to invalidating the stage-2
> > MMU, it can just delete + recreate the memslot.
> 
> Ok I think that's reasonable. So for USERFAULT -> !USERFAULT, I'll
> just follow the precedent set by dirty logging. For x86 today, we
> collapse the mappings, and for arm64 we do not.
> 
> Is arm64 ever going to support collapsing back to huge mappings after
> dirty logging is disabled?

Patches on list is always a good place to start :)

What I'd expect on FEAT_S2FWB hardware is that invalidating the whole
stage-2 and faulting back in block entries would give the best
experience.

Only in the case of !FWB would a literal table -> block collapse be
beneficial, as the MMU could potentially elide CMOs when remapping. But
that assumes you're starting with a fully-mapped table and there are no
holes that are "out of sync" with the guest.

-- 
Thanks,
Oliver


From zmw12306 at gmail.com  Thu Dec  5 16:51:00 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Thu, 5 Dec 2024 19:51:00 -0500
Subject: [PATCH] pwm: stm32-lp: Add check for clk_enable()
In-Reply-To: <geyicxufezkbu7cdvnbgnr2qeuwrn5ubz5ent3spk5biuozxrs@gsqx2chgiiot>
References: <20241205051746.2465490-1-zmw12306@gmail.com>
 <geyicxufezkbu7cdvnbgnr2qeuwrn5ubz5ent3spk5biuozxrs@gsqx2chgiiot>
Message-ID: <5778D1D6-9C2B-4456-9765-213120076C62@gmail.com>



> On Dec 5, 2024, at 3:34 AM, Uwe Kleine-K?nig <ukleinek at kernel.org> wrote:
> 
> On Thu, Dec 05, 2024 at 12:17:46AM -0500, Mingwei Zheng wrote:
>> Add check for the return value of clk_enable() to catch the potential
>> error.
> 
> Is this something that you actually hit, or just a janitoral fix you
> noticed while browsing the code (or reading some checker output)?

We detected this through static analysis, instead of actually hit.

> 
>> Fixes: e70a540b4e02 ("pwm: Add STM32 LPTimer PWM driver")
>> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
>> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
>> ---
>> drivers/pwm/pwm-stm32-lp.c | 8 ++++++--
>> 1 file changed, 6 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
>> index 989731256f50..4abef304417d 100644
>> --- a/drivers/pwm/pwm-stm32-lp.c
>> +++ b/drivers/pwm/pwm-stm32-lp.c
>> @@ -163,12 +163,16 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
>> unsigned long rate = clk_get_rate(priv->clk);
>> u32 val, presc, prd;
>> u64 tmp;
>> + int ret;
> 
> Please move this variable to the block where it's used. No need for such
> a big scope.
> 
> Otherwise looks fine.
> 
> Best regards
> Uwe

Thank you! We will submit a v2 patch for you to review!

Best,
Mingwei



From oliver.upton at linux.dev  Thu Dec  5 17:02:18 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 5 Dec 2024 17:02:18 -0800
Subject: [PATCH v4 05/14] KVM: arm64: Initialize feature id registers for
 protected VMs
In-Reply-To: <20241202154742.3611749-6-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-6-tabba@google.com>
Message-ID: <Z1JNGmcZka1hl2ha@linux.dev>

Hi Fuad,

On Mon, Dec 02, 2024 at 03:47:32PM +0000, Fuad Tabba wrote:
> +/*
> + * Initializes feature registers for protected vms.
> + */
> +void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	struct kvm_arch *ka = &kvm->arch;
> +	u32 r;
> +

Can you add an assertion that this is called while holding the
vm_table_lock? Otherwise it isn't clear why its safe to initialize
per-VM state.

> +	if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags))
> +		return;
> +
> +	/*
> +	 * Initialize only AArch64 id registers since AArch32 isn't supported
> +	 * for protected VMs.
> +	 */
> +	for (r = sys_reg(3, 0, 0, 4, 0); r <= sys_reg(3, 0, 0, 7, 7); r += sys_reg(0, 0, 0, 0, 1))
> +		ka->id_regs[IDREG_IDX(r)] = pvm_calc_id_reg(vcpu, r);
> +
> +	set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
> +}
> +
>  /*
>   * Checks that the sysreg table is unique and in-order.
>   *
> -- 
> 2.47.0.338.g60cca15819-goog
> 

-- 
Thanks,
Oliver


From jiaqiyan at google.com  Thu Dec  5 17:02:44 2024
From: jiaqiyan at google.com (Jiaqi Yan)
Date: Fri,  6 Dec 2024 01:02:44 +0000
Subject: [RFC PATCH v2 1/3] KVM: arm64: SIGBUS VMM for SEA guest abort
Message-ID: <20241206010246.40282-1-jiaqiyan@google.com>

When APEI is unable claim or handles synchronous external abort (SEA)
today KVM handles SEA for guest by injecting an async SError into the
guest directly, bypassing VMM, usually results in guest kernel panic.

One major situation of guest SEA is when vCPU consumes uncorrectable
memory error on the physical memory. Although SError and guest kernel
panic effectively stops the propagation of corrupted memory, it is not
easy for VMM and guest to recover from memory error in a more graceful
manner.

This patch teach KVM to send a SIGBUS BUS_OBJERR to VMM/vCPU, just like
how core kernel signals SIGBUS BUS_OBJERR to a gernal poison consuming
userspace thread when APEI is unable to claim the SEA. In addition to
the benifit that KVM's handling for SEA becomes aligned with core
kernel's behavior
- VMM can inject SEA to guest. Compared to SError, the blast radius in
  VM is possible to be limited to only the consuming thread in guest,
  instead of the entire guest kernel (unless the poison consumption is
  from guest kernel).
- VMM usually tracks the poisoned guest pages. Together with [1], if
  guest consumes again the already poisoned guest pages, VMM can protect
  itself and the host by stopping the consumption at software level, by
  intercepting guest's access to poisoned pages, and again injecting
  SEA to guest.

KVM now handles SEA as follows:
1. Delegate to APEI/GHES driver to see if SEA can be claimed by them.
2. If APEI failed to claim the SEA, send current thread (i.e. VMM in EL0)
   a si_code=BUS_OBJERR SIGBUS signal. If the DIMM error's physical
   address is available from FAR_EL2, si_addr will be the DIMM error's
   host virtual address in VMM/vCPU's memory space.
3. Otherwise bypass VMM and inject async SError to guest.

Tested on a machine running Siryn AmpereOne processor. A dummy application
in VM allocated some memory buffer. The test used EINJ to inject an
uncorrectable recoverable memory error at a page in the allocated memory
buffer. The dummy application then consumed the memory error. Some hack
was done to make core kernel's memory_failure triggered by poison
generation to fail, so KVM had to deal with the SEA guest abort due to
poison consumption. vCPU thread in VMM received SIGBUS BUS_OBJERR with
valid host virtual address of the poisoned page. VMM then injected a SEA
into guest using KVM_SET_VCPU_EVENTS with ext_dabt_pending=1. At last
the dummy application in guest was killed by SIGBUS BUS_OBJERR, while the
guest survived and continued to run.

[1] https://lpc.events/event/18/contributions/1757/attachments/1442/3073/LPC_%20KVM%20Userfault.pdf

Changelog

RFC v2 -> RFC v1
- reword commit msg
- drop unused parameters from kvm_delegate_guest_sea
- remove KVM_CAP_ARM_SIGBUS_ON_SEA and its opt in code
- set FnV bit in vcpu's ESR_ELx if host ESR_EL2's FnV is set
- add documentation for this new SIGBUS feature

Signed-off-by: Jiaqi Yan <jiaqiyan at google.com>
---
 arch/arm64/include/asm/kvm_ras.h | 24 ++++++----
 arch/arm64/kvm/Makefile          |  2 +-
 arch/arm64/kvm/kvm_ras.c         | 81 ++++++++++++++++++++++++++++++++
 arch/arm64/kvm/mmu.c             |  8 +---
 4 files changed, 98 insertions(+), 17 deletions(-)
 create mode 100644 arch/arm64/kvm/kvm_ras.c

diff --git a/arch/arm64/include/asm/kvm_ras.h b/arch/arm64/include/asm/kvm_ras.h
index 87e10d9a635b5..5b4bec6f4f32b 100644
--- a/arch/arm64/include/asm/kvm_ras.h
+++ b/arch/arm64/include/asm/kvm_ras.h
@@ -1,5 +1,4 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2018 - Arm Ltd */
 
 #ifndef __ARM64_KVM_RAS_H__
 #define __ARM64_KVM_RAS_H__
@@ -11,15 +10,22 @@
 #include <asm/acpi.h>
 
 /*
- * Was this synchronous external abort a RAS notification?
- * Returns '0' for errors handled by some RAS subsystem, or -ENOENT.
+ * For synchrnous external abort taken to KVM at EL2, not on translation
+ * table walk or hardware update of translation table, is FAR_EL2 valid?
  */
-static inline int kvm_handle_guest_sea(phys_addr_t addr, u64 esr)
-{
-	/* apei_claim_sea(NULL) expects to mask interrupts itself */
-	lockdep_assert_irqs_enabled();
+bool kvm_vcpu_sea_far_valid(const struct kvm_vcpu *vcpu);
 
-	return apei_claim_sea(NULL);
-}
+/*
+ * Handle synchronous external abort (SEA) in the following order:
+ * 1. Delegate to APEI/GHES to see if they can claim SEA. If so, all done.
+ * 2. If the SEA is NOT about S2 translation table, send SIGBUS to current
+ *    with BUS_OBJERR and si_addr set to faulting/poisoned host virtual
+ *    address. When accurate HVA is unavailable, si_addr will be 0.
+ * 3. Otherwise, directly inject an async SError to guest.
+ *
+ * Note this applies to both instruction and data abort (ESR_ELx_EC_IABT_*
+ * and ESR_ELx_EC_DABT_*).
+ */
+void kvm_handle_guest_sea(struct kvm_vcpu *vcpu);
 
 #endif /* __ARM64_KVM_RAS_H__ */
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 3cf7adb2b5038..c4a3a6d4870e6 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -23,7 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-v3.o vgic/vgic-v4.o \
 	 vgic/vgic-mmio.o vgic/vgic-mmio-v2.o \
 	 vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
-	 vgic/vgic-its.o vgic/vgic-debug.o
+	 vgic/vgic-its.o vgic/vgic-debug.o kvm_ras.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
 kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
diff --git a/arch/arm64/kvm/kvm_ras.c b/arch/arm64/kvm/kvm_ras.c
new file mode 100644
index 0000000000000..88d5c57f14bc7
--- /dev/null
+++ b/arch/arm64/kvm/kvm_ras.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bitops.h>
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_ras.h>
+#include <asm/system_misc.h>
+
+bool kvm_vcpu_sea_far_valid(const struct kvm_vcpu *vcpu)
+{
+	/*
+	 * FnV is valid only for Data/Instruction aborts and if DFSC/IFSC
+	 * is ESR_ELx_FSC_EXTABT(0b010000).
+	 */
+	if (kvm_vcpu_trap_get_fault(vcpu) == ESR_ELx_FSC_EXTABT)
+		return !(vcpu->arch.fault.esr_el2 & ESR_ELx_FnV);
+
+	/* Other exception classes or aborts don't care about FnV field. */
+	return true;
+}
+
+/*
+ * Was this synchronous external abort a RAS notification?
+ * Returns '0' for errors handled by some RAS subsystem, or -ENOENT.
+ */
+static int kvm_delegate_guest_sea(void)
+{
+	/* apei_claim_sea(NULL) expects to mask interrupts itself */
+	lockdep_assert_irqs_enabled();
+	return apei_claim_sea(NULL);
+}
+
+void kvm_handle_guest_sea(struct kvm_vcpu *vcpu)
+{
+	bool sigbus_on_sea;
+	int idx;
+	u64 vcpu_esr = kvm_vcpu_get_esr(vcpu);
+	u8 fsc = kvm_vcpu_trap_get_fault(vcpu);
+	phys_addr_t fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
+	gfn_t gfn = fault_ipa >> PAGE_SHIFT;
+	/* When FnV is set, send 0 as si_addr like what do_sea() does. */
+	unsigned long hva = 0UL;
+
+	/*
+	 * For RAS the host kernel may handle this abort.
+	 * There is no need to SIGBUS VMM, or pass the error into the guest.
+	 */
+	if (kvm_delegate_guest_sea() == 0)
+		return;
+
+	/*
+	 * In addition to userspace opt-in, SIGBUS only makes sense if the
+	 * abort is NOT about stage 2 translation table walk and NOT about
+	 * hardware update of stage 2 translation table.
+	 */
+	sigbus_on_sea = (fsc == ESR_ELx_FSC_EXTABT ||
+			 fsc == ESR_ELx_FSC_SECC ||
+			 fsc == ESR_ELx_FSC_SEA_TTW(1) ||
+			 fsc == ESR_ELx_FSC_SECC_TTW(1));
+
+	/* Pass the error directly into the guest. */
+	if (!sigbus_on_sea) {
+		kvm_inject_vabt(vcpu);
+		return;
+	}
+
+	if (kvm_vcpu_sea_far_valid(vcpu)) {
+		idx = srcu_read_lock(&vcpu->kvm->srcu);
+		hva = gfn_to_hva(vcpu->kvm, gfn);
+		srcu_read_unlock(&vcpu->kvm->srcu, idx);
+	}
+
+	/*
+	 * Send a SIGBUS BUS_OBJERR to vCPU thread (the userspace thread that
+	 * runs KVM_RUN) or VMM, which aligns with what host kernel do_sea()
+	 * does if apei_claim_sea() fails.
+	 */
+	arm64_notify_die("synchronous external abort",
+			 current_pt_regs(), SIGBUS, BUS_OBJERR, hva, vcpu_esr);
+}
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index a71fe6f6bd90f..f5335953827ec 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1766,13 +1766,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 
 	/* Synchronous External Abort? */
 	if (kvm_vcpu_abt_issea(vcpu)) {
-		/*
-		 * For RAS the host kernel may handle this abort.
-		 * There is no need to pass the error into the guest.
-		 */
-		if (kvm_handle_guest_sea(fault_ipa, kvm_vcpu_get_esr(vcpu)))
-			kvm_inject_vabt(vcpu);
-
+		kvm_handle_guest_sea(vcpu);
 		return 1;
 	}
 
-- 
2.47.0.338.g60cca15819-goog



From jiaqiyan at google.com  Thu Dec  5 17:02:45 2024
From: jiaqiyan at google.com (Jiaqi Yan)
Date: Fri,  6 Dec 2024 01:02:45 +0000
Subject: [RFC PATCH v2 2/3] KVM: arm64: set FnV in vcpu's ESR_ELx when host
 FAR_EL2 is invalid
In-Reply-To: <20241206010246.40282-1-jiaqiyan@google.com>
References: <20241206010246.40282-1-jiaqiyan@google.com>
Message-ID: <20241206010246.40282-2-jiaqiyan@google.com>

Certain microarchitectures (e.g. Neoverse V2) do not keep track of
the faulting address for a memory load that consumes poisoned data
and results in a synchronous external abort (SEA). This means the
poisoned guest physical address is unavailable when KVM handles such
SEA in EL2, and FAR_EL2 just holds a garbage value. KVM sends SIGBUS
to interrupt VMM/vCPU but the si_addr will be zero.

In case VMM later asks KVM to synchronously inject a SEA into the
guest, KVM should set FnV bit
- in vcpu's ESR_EL1 to let guest kernel know that FAR_EL1
- in vcpu's ESR_EL2 to let nested virtualization know that FAR_EL2
is also invalid and holds garbage value.

Signed-off-by: Jiaqi Yan <jiaqiyan at google.com>
---
 arch/arm64/kvm/inject_fault.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index a640e839848e6..2b01b331a4879 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -13,6 +13,7 @@
 #include <linux/kvm_host.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_nested.h>
+#include <asm/kvm_ras.h>
 #include <asm/esr.h>
 
 static void pend_sync_exception(struct kvm_vcpu *vcpu)
@@ -81,6 +82,9 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr
 	if (!is_iabt)
 		esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
 
+	if (!kvm_vcpu_sea_far_valid(vcpu))
+		esr |= ESR_ELx_FnV;
+
 	esr |= ESR_ELx_FSC_EXTABT;
 
 	if (match_target_el(vcpu, unpack_vcpu_flag(EXCEPT_AA64_EL1_SYNC))) {
-- 
2.47.0.338.g60cca15819-goog



From jiaqiyan at google.com  Thu Dec  5 17:02:06 2024
From: jiaqiyan at google.com (Jiaqi Yan)
Date: Thu, 5 Dec 2024 17:02:06 -0800
Subject: [RFC PATCH v1] KVM: arm64: Introduce KVM_CAP_ARM_SIGBUS_ON_SEA
In-Reply-To: <Zz2TyC9-zNQ3D-KB@linux.dev>
References: <20241031212104.1429609-1-jiaqiyan@google.com> <86r07v1g2z.wl-maz@kernel.org>
 <CACw3F51FbzkkX_DcCVCieZ=408oP_Fy3sXYk5AjWRX3RJO2Fzg@mail.gmail.com>
 <878qtou96b.wl-maz@kernel.org> <CACw3F50gB40dqQ4CZ7f4X4aRkxHQhjiYunAhqbmVtcGnd5g3bA@mail.gmail.com>
 <Zz2TyC9-zNQ3D-KB@linux.dev>
Message-ID: <CACw3F50ACSOsP9+qJr2g=dL9p3-6AcZ2VWP2bbWvBMasu796pw@mail.gmail.com>

On Tue, Nov 19, 2024 at 11:46?PM Oliver Upton <oliver.upton at linux.dev> wrote:
>
> On Tue, Nov 19, 2024 at 03:57:46PM -0800, Jiaqi Yan wrote:
> >
> > While continuing the discussion here, I think it may make sense I sent
> > out a V2 with 2 major updates:
> >   - add documentation for new SIGBUS feature
> >   - remove KVM_CAP_ARM_SIGBUS_ON_SEA
>
> Just wanted to add that QEMU already has a functioning "MCE" injection
> implemenation based on signals that deals with the sloppy mess of
> coordinating w/ vCPU threads [*].
>
> I completely agree with Marc that the UAPI around using signals for this
> sort of thing is a giant pile of crap, but it seems to be a semi-understood
> pile of crap. And from that perspective, wiring unclaimed SEAs into the
> existing infrastructure at least makes the UAPI consistent.
>
> [*]: https://elixir.bootlin.com/qemu/v9.1.1/C/ident/kvm_on_sigbus_vcpu
>
> > On Tue, Nov 12, 2024 at 12:51?AM Marc Zyngier <maz at kernel.org> wrote:
> > > > Do you mean a CAP that VMM can tell KVM the VM guest has RAS ability?
> > > > I don't know if there is one for arm64. On x86 there is
> > > > KVM_X86_SETUP_MCE. KVM_CAP_ARM_INJECT_EXT_DABT maybe a revelant one
> > > > but I don't think it is exactly the one for "RAS ability".
> > >
> > > Having though about this a bit more, I now think this is independent
> > > of the guest supporting RAS. This really is about the VMM asking to be
> > > made aware of RAS errors affecting the guest, and it is the signalling
> > > back to the guest that needs to be gated by ID_AA64PFR0_EL1.RAS.
> >
> > Just to make sure I fully catch you. I think ID_AA64PFR0_EL1.RAS
> > translates to ARM64_HAS_RAS_EXTN in the kernel. If VMM signals RAS
> > error back to the guest with SEA, are you suggesting
> > __kvm_arm_vcpu_set_events should check
> > cpus_have_final_cap(ARM64_HAS_RAS_EXTN) before it
> > kvm_inject_dabt(vcpu)?
> >
> > If so, how could __kvm_arm_vcpu_set_events know if the error is about
> > RAS (e.g. memory error) vs about accessing memory not in a memslot
> > (i.e. KVM_EXIT_ARM_NISV)? I guess KVM needs to look at ESR_EL2 again
> > (e.g. kvm_vcpu_abt_issea vs kvm_vcpu_dabt_isvalid)?
>
> Good point. I don't think we can lock down this UAPI after the fact
> given the existing use cases. It is ultimately up to the VMM what to do.
>
> I don't see anything that would stop an implementation without FEAT_RAS
> from generating an SEA in this situation. The lack of FEAT_RAS (to me at
> least) implies:
>
>  - No ESR injection for vSErrors (already enforced in UAPI)
>  - No deferral of SErrors / ESBs
>  - No error record registers in the PE

Thanks Oliver, if I read you correctly, __kvm_arm_vcpu_set_events
doesn't need to assert ARM64_HAS_RAS_EXTN, and it also doesn't need to
differentiate RAS and KVM_EXIT_ARM_NISV.

>
> Of course, it is very likely you've thought about this more than I have,
> Marc.

I will send out RFC V2 in a second. Please take another look and
comment there, Marc and Oliver, thanks!

>
> --
> Thanks,
> Oliver


From jiaqiyan at google.com  Thu Dec  5 17:02:46 2024
From: jiaqiyan at google.com (Jiaqi Yan)
Date: Fri,  6 Dec 2024 01:02:46 +0000
Subject: [RFC PATCH v2 3/3] Documentation: kvm: new UAPI when arm64 guest
 consumes UER
In-Reply-To: <20241206010246.40282-1-jiaqiyan@google.com>
References: <20241206010246.40282-1-jiaqiyan@google.com>
Message-ID: <20241206010246.40282-3-jiaqiyan@google.com>

Add the documentation for new UAPI when guest consumes uncorrectable
but recoverable memory error (UER). This new UAPI enables userspace
to inject SEA into the guest.

Tested:
make htmldocs and proofreading

Signed-off-by: Jiaqi Yan <jiaqiyan at google.com>
---
 Documentation/virt/kvm/api.rst | 46 ++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 454c2aaa155e5..67645bdb66fe5 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -1288,16 +1288,48 @@ ARM64:
 
 User space may need to inject several types of events to the guest.
 
+Inject SError
+~~~~~~~~~~~~~
+
 Set the pending SError exception state for this VCPU. It is not possible to
 'cancel' an Serror that has been made pending.
 
-If the guest performed an access to I/O memory which could not be handled by
-userspace, for example because of missing instruction syndrome decode
-information or because there is no device mapped at the accessed IPA, then
-userspace can ask the kernel to inject an external abort using the address
-from the exiting fault on the VCPU. It is a programming error to set
-ext_dabt_pending after an exit which was not either KVM_EXIT_MMIO or
-KVM_EXIT_ARM_NISV. This feature is only available if the system supports
+Inject SEA
+~~~~~~~~~~
+
+- If the guest performed an access to I/O memory which could not be handled by
+  userspace, for example because of missing instruction syndrome decode
+  information or because there is no device mapped at the accessed IPA, then
+  userspace can ask the kernel to inject an external abort using the address
+  from the exiting fault on the VCPU.
+
+- If the guest consumed an uncorrectable memory error, and RAS extension in
+  Trusted Firmware choosed to notify PE with SEA, KVM and core kernel may have
+  to handle the memory poison consumption when host APEI was unable to claim
+  the SEA. For the following type of faults, KVM sends SIGBUS to current thread
+  (i.e. VMM in EL0) with si_code=BUS_OBJERR:
+
+  - Synchronous External abort, not on translation table walk or hardware
+    update of translation table.
+
+  - Synchronous External abort on translation table walk or hardware update of
+    translation table, level 1.
+
+  - Synchronous parity or ECC error on memory access, not on translation table
+    walk.
+
+  - Synchronous parity or ECC error on memory access on translation table walk
+    or hardware update of translation table, level 1.
+
+  If the memory error's physical address is available, si_addr will be the
+  error's host virtual address in VM's memory space; otherwise si_addr is zero.
+  When userspace VMM is interrupted by such SIGBUS, it can ask KVM to replay
+  an external abort into guest.
+
+It is a programming error to set ext_dabt_pending after an exit which was not
+KVM_EXIT_MMIO, not KVM_EXIT_ARM_NISV, and not interrupted by BUS_OBJERR SIGBUS.
+
+This feature is only available if the system supports
 KVM_CAP_ARM_INJECT_EXT_DABT. This is a helper which provides commonality in
 how userspace reports accesses for the above cases to guests, across different
 userspace implementations. Nevertheless, userspace can still emulate all Arm
-- 
2.47.0.338.g60cca15819-goog



From zmw12306 at gmail.com  Thu Dec  5 17:26:05 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Thu,  5 Dec 2024 20:26:05 -0500
Subject: [PATCH V2] pwm: stm32-lp: Add check for clk_enable()
Message-ID: <20241206012605.2877412-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error.

Fixes: e70a540b4e02 ("pwm: Add STM32 LPTimer PWM driver")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
Changelog:

v1 -> v2

1. Move int ret declaration into if block.
---
 drivers/pwm/pwm-stm32-lp.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
index 989731256f50..f09d097d6284 100644
--- a/drivers/pwm/pwm-stm32-lp.c
+++ b/drivers/pwm/pwm-stm32-lp.c
@@ -167,8 +167,12 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
 	regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
 	state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
 	/* Keep PWM counter clock refcount in sync with PWM initial state */
-	if (state->enabled)
-		clk_enable(priv->clk);
+	if (state->enabled) {
+		int ret = clk_enable(priv->clk);
+
+		if (ret)
+			return ret;
+	}
 
 	regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
 	presc = FIELD_GET(STM32_LPTIM_PRESC, val);
-- 
2.34.1



From hpchen0nvt at gmail.com  Thu Dec  5 17:43:45 2024
From: hpchen0nvt at gmail.com (Hui-Ping Chen)
Date: Fri, 6 Dec 2024 09:43:45 +0800
Subject: [PATCH v10 0/2] Add support for nuvoton ma35 nand controller
In-Reply-To: <878qsuwhm1.fsf@bootlin.com>
References: <20241204025129.150525-1-hpchen0nvt@gmail.com>
 <878qsuwhm1.fsf@bootlin.com>
Message-ID: <d41c9484-6192-462d-92e8-c200192d37f8@gmail.com>

Dear Miquel,

Thank you for your reply.


On 2024/12/5 ?? 06:26, Miquel Raynal wrote:
> Hi,
>
> On 04/12/2024 at 02:51:27 GMT, Hui-Ping Chen <hpchen0nvt at gmail.com> wrote:
>
>> This patch series adds the mtd nand driver for the nuvoton ma35 ARMv8 SoC.
>> It includes DT binding documentation and the ma35 mtd nand driver.
>>
>> v10:
>>    - Update ma35d1 mtd nand driver
>>      - Add unsupported write page handling.
> I was about to apply it but...
>
>      [31m?[0m checkpatch.pl: 117: WARNING: please write a help paragraph that fully describes the config symbol
>      [31m?[0m checkpatch.pl: 141: WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
>      [31m?[0m checkpatch.pl: 348: CHECK: spaces preferred around that '+' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 352: CHECK: spaces preferred around that '+' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 352: CHECK: spaces preferred around that '+' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 429: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 465: CHECK: spaces preferred around that '*' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 465: CHECK: spaces preferred around that '+' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 466: CHECK: spaces preferred around that '*' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 466: CHECK: spaces preferred around that '+' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 467: CHECK: spaces preferred around that '*' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 467: CHECK: spaces preferred around that '+' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 468: CHECK: spaces preferred around that '*' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 468: CHECK: spaces preferred around that '+' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 479: CHECK: spaces preferred around that '*' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 479: CHECK: spaces preferred around that '+' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 481: CHECK: spaces preferred around that '*' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 481: CHECK: spaces preferred around that '+' (ctx:VxV)
>      [31m?[0m checkpatch.pl: 514: CHECK: Unbalanced braces around else statement
>      [31m?[0m checkpatch.pl: 611: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 650: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 665: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 675: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 689: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 699: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 715: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 756: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 805: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 935: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 950: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 953: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 975: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 1001: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 1018: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 1131: CHECK: Alignment should match open parenthesis
>      [31m?[0m checkpatch.pl: 1159: WARNING: DT compatible string "nuvoton,ma35d1-nand" appears un-documented -- check ./Documentation/devicetree/bindings/
>
> Please fix these warnings and checks.
>
> You might want to use --strict by default.

I will fix it.


>
> Thanks,
> Miqu?l


Best regards,

Hui-Ping Chen



From 0x1207 at gmail.com  Thu Dec  5 17:45:02 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Fri, 6 Dec 2024 09:45:02 +0800
Subject: [PATCH net v1] net: stmmac: TSO: Fix unaligned DMA unmap for
 non-paged SKB data
In-Reply-To: <Z1HYKh9eCwkYGlrA@shell.armlinux.org.uk>
References: <20241205091830.3719609-1-0x1207@gmail.com>
	<Z1HYKh9eCwkYGlrA@shell.armlinux.org.uk>
Message-ID: <20241206094502.000062e8@gmail.com>

Hi Russell,

On Thu, 5 Dec 2024 16:43:22 +0000, "Russell King (Oracle)" <linux at armlinux.org.uk> wrote:
> I'm slightly disappointed to have my patch turned into a commit under
> someone else's authorship before I've had a chance to do that myself.
> Next time I won't send a patch out until I've done that.
> 
I am really sorry for this, I should have requested your permission first.

> 
> Please use rmk+kernel at armlinux.org.uk there.
> 
So another iteration is required here.
Would you mind me send the v2 of this fix?
I will not send v2 without your permission.

Thanks.


From David.Laight at ACULAB.COM  Thu Dec  5 18:18:59 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 02:18:59 +0000
Subject: arm64: include/linux/compiler_types.h:542:38: error: call to
 '__compiletime_assert_1050' declared with attribute error: clamp() low limit
 min greater than high limit max_avail
In-Reply-To: <CA+G9fYv5gW1gByakU1yyQ__BoAKWkCcg=vGGyNep7+5p9_2uJA@mail.gmail.com>
References: <CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g@mail.gmail.com>
 <8dde5a62-4ce6-4954-86c9-54d961aed6df@stanley.mountain>
 <CA+G9fYv5gW1gByakU1yyQ__BoAKWkCcg=vGGyNep7+5p9_2uJA@mail.gmail.com>
Message-ID: <bd95d7249ff94e31beb11b3f71a64e87@AcuMS.aculab.com>

From: Naresh Kamboju
> Sent: 05 December 2024 18:42
> 
> On Thu, 5 Dec 2024 at 20:46, Dan Carpenter <dan.carpenter at linaro.org> wrote:
> >
> > Add David to the CC list.
> 
> Anders bisected this reported issue and found the first bad commit as,
> 
> # first bad commit:
>   [ef32b92ac605ba1b7692827330b9c60259f0af49]
>   minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()

That 'just' changed the test to use __builtin_constant_p() and
thus gets checked after the optimiser has run.

I can paraphrase the code as:
unsigned int fn(unsigned int x)
{
	return clamp(10, 5, x == 0 ? 0 : x - 1);
}
which is never actually called with x <= 5.
The compiler converts it to:
	return x < 0 ? clamp(10, 5, 0) : clamp(10, 5, x);
(Probably because it can see that clamp(10, 5, 0) is constant.)
And then the compile-time sanity check in clamp() fires.

The order of the arguments to clamp is just wrong!

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From David.Laight at ACULAB.COM  Thu Dec  5 18:25:50 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 02:25:50 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
Message-ID: <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 05 December 2024 15:31
> 
> -CC: Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
> +CC: Martin Uecker <muecker at gwdg.de>
> (seems that Martin changed his address)
> 
> On Thu. 5 Dec. 2024 at 03:39, David Laight <David.Laight at aculab.com> wrote:
> > > Sent: 02 December 2024 17:33
> > >
> > > From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> > >
> > > __is_constexpr(), while being one of the most glorious one liner hack
> > > ever witnessed by mankind, is overly complex. Following the adoption
> > > of C11 in the kernel, this macro can be simplified through the use of
> > > a _Generic() selection.
> >
> > You should give credit to some of the earlier patches that do the same.
> > I'm sure there were some related ones from Linus - not applied yet.
> 
> ACK. Would adding a suggested--by Linus tag solve your concern?

I actually suspect the first patches to change __is_constexpr() to
use _Generic were from myself.
I've found a patch I send in November 2023.

> 
> > > First, split the macro in two:
> > >
> > >   - __is_const_zero(x): an helper macro; tells whether x is the
> > >     integer constant expression 0 or something else.
> > >
> > >   - is_const(x): replacement of __is_constexpr(); tells whether x is a
> > >     integer constant expression.
> > >
> > > The split serves two purposes: first make it easier to understand;
> > > second, __is_const_zero() will be reused as a building block for other
> > > is_const_*() macros that will be introduced later on.
> > >
> > > The core principle of __is_constexpr() to abuse the return type of the
> > > ternary operator remains, but all the surrounding sizeof() hack
> > > disappear.
> > >
> > > On a side note, while not relevant to the kernel, __is_constexpr()
> > > relied on the GNU extension that sizeof(void) is 1. const_expr() does
> > > not use any GNU extensions, making it ISO C compliant.
> > >
> > > __is_constexpr() is temporarily kept and will be removed once all its
> > > users get migrated to is_const() (or one of its friend).
> > >
> > > Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> > > ---
> > >  include/linux/compiler.h | 41 +++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 41 insertions(+)
> > >
> > > diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> > > index a2a56a50dd85227a4fdc62236a2710ca37c5ba52..30ce06df4153cfdc0fad9bc7bffab9097f8b0450 100644
> > > --- a/include/linux/compiler.h
> > > +++ b/include/linux/compiler.h
> > > @@ -316,6 +316,47 @@ static inline void *offset_to_ptr(const int *off)
> > >  #define statically_true(x) (__builtin_constant_p(x) && (x))
> > >  #define statically_false(x) (__builtin_constant_p(x) && (x) == 0)
> > >
> > > +/*
> > > + * Whether x is the integer constant expression 0 or something else.
> > > + *
> > > + * Details:
> > > + *   - The C11 standard defines in ?6.3.2.3.3
> > > + *       (void *)<integer constant expression with the value 0>
> > > + *     as a null pointer constant (c.f. the NULL macro).
> > > + *   - If x evaluates to the integer constant expression 0,
> > > + *       (void *)(x)
> > > + *     is a null pointer constant. Else, it is a void * expression.
> > > + *   - In a ternary expression:
> > > + *       condition ? operand1 : operand2
> > > + *     if one of the two operands is of type void * and the other one
> > > + *     some other pointer type, the C11 standard defines in ?6.5.15.6
> > > + *     the resulting type as below:
> > > + *       if one operand is a null pointer constant, the result has the
> > > + *       type of the other operand; otherwise [...] the result type is
> > > + *       a pointer to an appropriately qualified version of void.
> > > + *   - As such, in
> > > + *       0 ? (void *)(x) : (char *)0
> > > + *     if x is the integer constant expression 0, operand1 is a null
> > > + *     pointer constant and the resulting type is that of operand2:
> > > + *     char *. If x is anything else, the type is void *.
> > > + *   - The (long) cast silences a compiler warning for when x is not 0.
> > > + *   - Finally, the _Generic() dispatches the resulting type into a
> > > + *     Boolean.
> >
> > The comment is absolutely excessive.
> > I'm sure I managed about 2 lines in one of the patches I did.
> 
> I think that Linus made it  clear in:
> 
>   https://lore.kernel.org/all/CAHk-=wgfpLdt7SFFGcByTfHdkvv7AEa3MDu_s_W1kfOxQs49pw at mail.gmail.com/
> 
> that this deserves a detailed comment.

And he wrote one in https://lore.kernel.org/all/CAHk-=wiq=GUNWJwWh1CRAYchW73UmOaSkaCovLatfDKeveZctA at mail.gmail.com/

   /*
    * iff 'x' is a non-zero constant integer expression,
    * then '!(x)' will be a zero constant integer expression,
    * and casting that to 'void *' will result in a NULL pointer.
    * Otherwise casting it to 'void *' will be just a regular 'void *'.
    *
    * The type of '0 ? NULL : (char *)' is 'char *'
    * The type of '0 ? (void *) : (char *) is 'void *'
    */
    #define const_true(x) \
        _Generic(0 ? (void *)((long)!(x)) : (char *)0, char *: 1, void *: 0)



> 
> The details block in the current __is_constexpr() is 37 lines long,
> the details block in __is_const_zero() takes 22 lines. So I would
> argue that I made things better.

The old block was too long :-)

> 
> Unless more people share your concern, I am planning to keep this comment as-is.
> 
> > > + *
> > > + * Glory to Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
> >
> > IIRC Martin has agreed in the past that the accreditation can
> > be removed - especially since it refers to the 'sizeof (void)' trick.
> 
> I tried to look for such message:
> 
>   https://lore.kernel.org/all/?q=f%3A%22martin+uecker%22+__is_constexpr
> 
> but couldn't find it. Do you have the link?
> 
> @Martin, do you agree that I remove the accreditation?
> 
> > > + */
> > > +#define __is_const_zero(x) \
> > > +     _Generic(0 ? (void *)(long)(x) : (char *)0, char *: 1, void *: 0)
> > > +
> > > +/*
> > > + * Returns a constant expression while determining if its argument is a
> > > + * constant expression, most importantly without evaluating the argument.
> >
> > You need to differentiate between a 'constant integer expression'
> > and a 'compile time constant'.
> 
> OK. This one was just copied from the previous __is_constexpr(). I will apply
> "s/constant expression/constant integer expression/g" in v2.
> 
> > > + *
> > > + * If getting a constant expression is not relevant to you, use the more
> > > + * powerful __builtin_constant_p() instead.
> >
> > __builtin_constant_p() is not 'more powerful' it is testing for
> > something different.
> 
> I meant to say that __builtin_constant_p() is more powerful at
> constant folding. But I agree that the comment is not clear.
> 
> What about this?
> 
>   If getting a constant integer expression is not relevant to you, use
>   __builtin_constant_p() which not only returns true if the argument
>   is an integer constant expression, but also if it is a compile time
>   constant.

Complete f***ed tense.

It's not about 'constant folding' and 'powerful' isn't the correct word.
They are checking for two different things.

A 'constant integer expression' is defined by the C language, and is
basically something that is constant when first parsed by the compiler
(my definition) so it can pretty much only contain constants, sizeof()
and offsetof().

__builtin_constant_p() is true if the compiler decides that an expression is
constant. This can track values through inlined function calls and can
change from 'unknown' to 'true' late in the compilation.

	David

> 
> 
> Yours sincerely,
> Vincent Mailhol

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From lkp at intel.com  Thu Dec  5 18:28:44 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 6 Dec 2024 10:28:44 +0800
Subject: [PATCH v1 3/3] clk: samsung: Introduce Exynos990 clock
 controller driver
In-Reply-To: <20241205193423.783815-4-igor.belwon@mentallysanemainliners.org>
References: <20241205193423.783815-4-igor.belwon@mentallysanemainliners.org>
Message-ID: <202412061048.3gu75pLi-lkp@intel.com>

Hi Igor,

kernel test robot noticed the following build errors:

[auto build test ERROR on krzk/for-next]
[also build test ERROR on krzk-dt/for-next clk/clk-next linus/master v6.13-rc1 next-20241205]
[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/Igor-Belwon/clk-samsung-clk-pll-Add-support-for-pll_-0717x-0718x-0732x/20241206-043559
base:   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git for-next
patch link:    https://lore.kernel.org/r/20241205193423.783815-4-igor.belwon%40mentallysanemainliners.org
patch subject: [PATCH v1 3/3] clk: samsung: Introduce Exynos990 clock controller driver
config: arc-randconfig-001-20241206 (https://download.01.org/0day-ci/archive/20241206/202412061048.3gu75pLi-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241206/202412061048.3gu75pLi-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/202412061048.3gu75pLi-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/clk/samsung/clk-exynos990.c:13:10: fatal error: dt-bindings/clock/exynos990.h: No such file or directory
      13 | #include <dt-bindings/clock/exynos990.h>
         |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   compilation terminated.


vim +13 drivers/clk/samsung/clk-exynos990.c

    12	
  > 13	#include <dt-bindings/clock/exynos990.h>
    14	

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


From trunixs.kim at samsung.com  Thu Dec  5 18:51:38 2024
From: trunixs.kim at samsung.com (Taewan Kim)
Date: Fri,  6 Dec 2024 11:51:38 +0900
Subject: [PATCH v4 1/1] arm64: dts: exynosautov920: add watchdog DT node
In-Reply-To: <20241206025139.2148833-1-trunixs.kim@samsung.com>
References: <20241206025139.2148833-1-trunixs.kim@samsung.com>
	<CGME20241206025156epcas2p4c55f230accc4354e6f4bf324ab9a5833@epcas2p4.samsung.com>
Message-ID: <20241206025139.2148833-2-trunixs.kim@samsung.com>

From: Byoungtae Cho <bt.cho at samsung.com>

Adds two watchdog devices for ExynosAutoV920 SoC.

Signed-off-by: Byoungtae Cho <bt.cho at samsung.com>
Signed-off-by: Taewan Kim <trunixs.kim at samsung.com>
---
 .../arm64/boot/dts/exynos/exynosautov920.dtsi | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
index c759134c909e..7b9591255e91 100644
--- a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
@@ -183,6 +183,26 @@ cmu_misc: clock-controller at 10020000 {
 				      "noc";
 		};
 
+		watchdog_cl0: watchdog at 10060000 {
+			compatible = "samsung,exynosautov920-wdt";
+			reg = <0x10060000 0x100>;
+			interrupts = <GIC_SPI 953 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xtcxo>, <&xtcxo>;
+			clock-names = "watchdog", "watchdog_src";
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			samsung,cluster-index = <0>;
+		};
+
+		watchdog_cl1: watchdog at 10070000 {
+			compatible = "samsung,exynosautov920-wdt";
+			reg = <0x10070000 0x100>;
+			interrupts = <GIC_SPI 952 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xtcxo>, <&xtcxo>;
+			clock-names = "watchdog", "watchdog_src";
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			samsung,cluster-index = <1>;
+		};
+
 		gic: interrupt-controller at 10400000 {
 			compatible = "arm,gic-v3";
 			#interrupt-cells = <3>;
-- 
2.47.1



From trunixs.kim at samsung.com  Thu Dec  5 18:51:37 2024
From: trunixs.kim at samsung.com (Taewan Kim)
Date: Fri,  6 Dec 2024 11:51:37 +0900
Subject: [PATCH v4 0/1] support watchdog for exynosautov920 
References: <CGME20241206025156epcas2p3e1ce9ff35589d821735a7c038b9ac9da@epcas2p3.samsung.com>
Message-ID: <20241206025139.2148833-1-trunixs.kim@samsung.com>

Add support for the ExynosAutoV920 SoC. Basically this is almost
similar to ExynosAuto V9 or Exynos850 such as two watchdog instance for
each cluster but some CPU configuration are quite different.
Therefore device tree, compatibles and drvdata should be added.

In v3, the first and second patches were approved by watchdog maintainer and added as next-git.
- Link: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/log/?qt=grep&q=bt.cho

For the last third dts patch review, the patch was rebased and made v4.

---
Changes in v4:
- The first two patches were approved in v3.(1/3, 2/3)
- v4 contains only one patch that needs to be reviewed. (3/3)
- Rebase to the lastest master branch
- Link to v3: https://lore.kernel.org/all/20241021063903.793166-1-trunixs.kim at samsung.com/
---
Changes in v3:
- Add Acked-by/Reviewed-by tags 
- Link to v2: https://lore.kernel.org/all/20241010111807.3635504-1-trunixs.kim at samsung.com/
---
Changes in v2:
- Add a space before }
- Fix worng variant condition (cl1 -> cl0)
- Move the location declaring watchdog node
  to the correct location that fits the DTS coding rules
- Link to v1: https://lore.kernel.org/all/20240913080325.3676181-1-trunixs.kim at samsung.com/
---

Byoungtae Cho (1):
  arm64: dts: exynosautov920: add watchdog DT node

 .../arm64/boot/dts/exynos/exynosautov920.dtsi | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

-- 
2.47.1



From hpchen0nvt at gmail.com  Thu Dec  5 19:13:17 2024
From: hpchen0nvt at gmail.com (Hui-Ping Chen)
Date: Fri,  6 Dec 2024 03:13:17 +0000
Subject: [PATCH v11 1/2] dt-bindings: mtd: nuvoton,ma35d1-nand: add new bindings
In-Reply-To: <20241206031318.156152-1-hpchen0nvt@gmail.com>
References: <20241206031318.156152-1-hpchen0nvt@gmail.com>
Message-ID: <20241206031318.156152-2-hpchen0nvt@gmail.com>

Add dt-bindings for the Nuvoton MA35 SoC NAND Controller.

Signed-off-by: Hui-Ping Chen <hpchen0nvt at gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../bindings/mtd/nuvoton,ma35d1-nand.yaml     | 95 +++++++++++++++++++
 1 file changed, 95 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml b/Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml
new file mode 100644
index 000000000000..0b651450a8f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/nuvoton,ma35d1-nand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton MA35D1 NAND Flash Interface (NFI) Controller
+
+maintainers:
+  - Hui-Ping Chen <hpchen0nvt at gmail.com>
+
+allOf:
+  - $ref: nand-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - nuvoton,ma35d1-nand-controller
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+patternProperties:
+  "^nand@[a-f0-9]$":
+    type: object
+    $ref: raw-nand-chip.yaml
+    properties:
+      reg:
+        minimum: 0
+        maximum: 1
+
+      nand-ecc-step-size:
+        enum: [512, 1024]
+
+      nand-ecc-strength:
+        enum: [8, 12, 24]
+
+    required:
+      - reg
+
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        nand-controller at 401A0000 {
+            compatible = "nuvoton,ma35d1-nand-controller";
+            reg = <0x0 0x401A0000 0x0 0x1000>;
+            interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&clk NAND_GATE>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            nand at 0 {
+                reg = <0>;
+                nand-on-flash-bbt;
+                nand-ecc-step-size = <512>;
+                nand-ecc-strength = <8>;
+
+                partitions {
+                    compatible = "fixed-partitions";
+                    #address-cells = <1>;
+                    #size-cells = <1>;
+
+                    uboot at 0 {
+                        label = "nand-uboot";
+                        read-only;
+                        reg = <0x0 0x300000>;
+                    };
+                };
+            };
+        };
+    };
+
+...
-- 
2.25.1



From hpchen0nvt at gmail.com  Thu Dec  5 19:13:16 2024
From: hpchen0nvt at gmail.com (Hui-Ping Chen)
Date: Fri,  6 Dec 2024 03:13:16 +0000
Subject: [PATCH v11 0/2] Add support for nuvoton ma35 nand controller
Message-ID: <20241206031318.156152-1-hpchen0nvt@gmail.com>

This patch series adds the mtd nand driver for the nuvoton ma35 ARMv8 SoC.
It includes DT binding documentation and the ma35 mtd nand driver.

v11:
  - Update ma35d1 mtd nand driver
    - Fix warnings and checks use --strict.

v10:
  - Update ma35d1 mtd nand driver
    - Add unsupported write page handling.

v9:
  - Update ma35d1 mtd nand driver
    - Remove NAND_NO_SUBPAGE_WRITE flag.
    - Remove of_get_property().
    - Add ecc.write_subpage and ecc.read_subpage.

v8:
  - Update ma35d1 mtd nand driver
    - Rename to nuvoton-ma35d1-nand-controller.c.
    - Use switch case instead of if else.
    - Move some parameters to be set during initialization.
    - Fix the ecc.read_page return value issue.
    - Add enable/disable ECC engine before and after reading/writing the page.
    - Return IRQ_NONE if (isr & INT_DMA) == 0.
    - Move the HW ECC related settings to ON_HOST.
    - Move hw_init() to probe.

v7:
  - Update nuvoton,ma35d1-nand.yaml
    - Remove required 'nand-ecc-step-size' and 'nand-ecc-strength'.
    - Add 'reg' for chip select.
  - Update ma35d1 mtd nand driver
    - Update space and comments style.
    - Add chip select setting from DT.
    - Add switch case which supports various ECC configurations.
    - Set reset before NAND controller enable.

v6:
  - Update ma35d1 mtd nand driver
    - Remove extra blank lines and add comments.

v5:
  - Update ma35d1 mtd nand driver
    - Remove unnecessary definitions and comments.
    - Modified DMA API call sequence.
    - Move the ECC check out of the interrupt handler.
      Check it after reading a page.

v4:
  - Update nuvoton,ma35d1-nand.yaml
    - rename 'nuvoton,ma35d1-nand' to 'nuvoton,ma35d1-nand-controller'.
  - Update ma35d1 mtd nand driver
    - Rewrite the NAND driver using the exec_op API.

v3:
  - Update ma35d1 mtd nand driver
    - Release IRQ handler.
    - Remove unused functions.
    - Remove '.owner'.

v2:
  - Update nuvoton,ma35d1-nand.yaml
    - Adjust the order and remove any unnecessary items.
    - Add 'nand-ecc-step-size' and 'nand-ecc-strength' to the required list.
  - Update ma35d1 mtd nand driver
    - Fix coding style.
    - Use 'devm_clk_get' instead of 'of_clk_get'.
    - Use 'dev_err_probe' instead of 'dev_err'.
    - Remove 'pr_info' and 'of_match_ptr'.
    - Remove 'module_init' and 'module_exit'.


Hui-Ping Chen (2):
  dt-bindings: mtd: nuvoton,ma35d1-nand: add new bindings
  mtd: rawnand: nuvoton: add new driver for the Nuvoton MA35 SoC

 .../bindings/mtd/nuvoton,ma35d1-nand.yaml     |   95 ++
 drivers/mtd/nand/raw/Kconfig                  |    8 +
 drivers/mtd/nand/raw/Makefile                 |    1 +
 .../nand/raw/nuvoton-ma35d1-nand-controller.c | 1029 +++++++++++++++++
 4 files changed, 1133 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/nuvoton,ma35d1-nand.yaml
 create mode 100644 drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c

-- 
2.25.1



From hpchen0nvt at gmail.com  Thu Dec  5 19:13:18 2024
From: hpchen0nvt at gmail.com (Hui-Ping Chen)
Date: Fri,  6 Dec 2024 03:13:18 +0000
Subject: [PATCH v11 2/2] mtd: rawnand: nuvoton: add new driver for the Nuvoton MA35 SoC
In-Reply-To: <20241206031318.156152-1-hpchen0nvt@gmail.com>
References: <20241206031318.156152-1-hpchen0nvt@gmail.com>
Message-ID: <20241206031318.156152-3-hpchen0nvt@gmail.com>

Nuvoton MA35 SoCs NAND Flash Interface Controller
supports 2kiB, 4kiB and 8kiB page size, and up to
8-bit, 12-bit, and 24-bit hardware ECC calculation
circuit to protect data.

Signed-off-by: Hui-Ping Chen <hpchen0nvt at gmail.com>
---
 drivers/mtd/nand/raw/Kconfig                  |    8 +
 drivers/mtd/nand/raw/Makefile                 |    1 +
 .../nand/raw/nuvoton-ma35d1-nand-controller.c | 1029 +++++++++++++++++
 3 files changed, 1038 insertions(+)
 create mode 100644 drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index d0aaccf72d78..e3677bcaf035 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -454,6 +454,14 @@ config MTD_NAND_TS72XX
 	help
 	  Enables support for NAND controller on ts72xx SBCs.
 
+config MTD_NAND_NUVOTON_MA35
+	tristate "Nuvoton MA35 SoC NAND controller"
+	depends on ARCH_MA35 || COMPILE_TEST
+	depends on OF
+	help
+	  Enables support for the NAND controller found on
+	  the Nuvoton MA35 series SoCs.
+
 comment "Misc"
 
 config MTD_SM_COMMON
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index d0b0e6b83568..99e79c448847 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_INTEL_LGM)	+= intel-nand-controller.o
 obj-$(CONFIG_MTD_NAND_ROCKCHIP)		+= rockchip-nand-controller.o
 obj-$(CONFIG_MTD_NAND_PL35X)		+= pl35x-nand-controller.o
 obj-$(CONFIG_MTD_NAND_RENESAS)		+= renesas-nand-controller.o
+obj-$(CONFIG_MTD_NAND_NUVOTON_MA35)	+= nuvoton-ma35d1-nand-controller.o
 
 nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
 nand-objs += nand_onfi.o
diff --git a/drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c b/drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c
new file mode 100644
index 000000000000..3102fc4c0ca5
--- /dev/null
+++ b/drivers/mtd/nand/raw/nuvoton-ma35d1-nand-controller.c
@@ -0,0 +1,1029 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 Nuvoton Technology Corp.
+ */
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* NFI Registers */
+#define MA35_NFI_REG_DMACTL		0x400
+#define   DMA_EN				BIT(0)
+#define   DMA_RST				BIT(1)
+#define   DMA_BUSY				BIT(9)
+
+#define MA35_NFI_REG_DMASA		0x408
+#define MA35_NFI_REG_GCTL		0x800
+#define   GRST					BIT(0)
+#define   NAND_EN				BIT(3)
+
+#define MA35_NFI_REG_NANDCTL		0x8A0
+#define   SWRST				BIT(0)
+#define   DMA_R_EN				BIT(1)
+#define   DMA_W_EN				BIT(2)
+#define   ECC_CHK				BIT(7)
+#define   PROT3BEN				BIT(8)
+#define   PSIZE_2K				BIT(16)
+#define   PSIZE_4K				BIT(17)
+#define   PSIZE_8K				GENMASK(17, 16)
+#define   PSIZE_MASK				GENMASK(17, 16)
+#define   BCH_T24				BIT(18)
+#define   BCH_T8				BIT(20)
+#define   BCH_T12				BIT(21)
+#define   BCH_NONE				(0x0)
+#define   BCH_MASK				GENMASK(22, 18)
+#define   ECC_EN				BIT(23)
+#define   DISABLE_CS0				BIT(25)
+
+#define MA35_NFI_REG_NANDINTEN	0x8A8
+#define MA35_NFI_REG_NANDINTSTS	0x8AC
+#define   INT_DMA				BIT(0)
+#define   INT_ECC				BIT(2)
+#define   INT_RB0				BIT(10)
+
+#define MA35_NFI_REG_NANDCMD		0x8B0
+#define MA35_NFI_REG_NANDADDR		0x8B4
+#define   ENDADDR				BIT(31)
+
+#define MA35_NFI_REG_NANDDATA		0x8B8
+#define MA35_NFI_REG_NANDRACTL	0x8BC
+#define MA35_NFI_REG_NANDECTL		0x8C0
+#define   ENABLE_WP				0x0
+#define   DISABLE_WP				BIT(0)
+
+#define MA35_NFI_REG_NANDECCES0	0x8D0
+#define   ECC_STATUS_MASK			GENMASK(1, 0)
+#define   ECC_ERR_CNT_MASK			GENMASK(4, 0)
+
+#define MA35_NFI_REG_NANDECCEA0	0x900
+#define MA35_NFI_REG_NANDECCED0	0x960
+#define MA35_NFI_REG_NANDRA0		0xA00
+
+/* Define for the BCH hardware ECC engine */
+/* define the total padding bytes for 512/1024 data segment */
+#define MA35_BCH_PADDING_512	32
+#define MA35_BCH_PADDING_1024	64
+/* define the BCH parity code length for 512 bytes data pattern */
+#define MA35_PARITY_BCH8	15
+#define MA35_PARITY_BCH12	23
+/* define the BCH parity code length for 1024 bytes data pattern */
+#define MA35_PARITY_BCH24	45
+
+#define MA35_MAX_NSELS		(2)
+#define PREFIX_RA_IS_EMPTY(reg)	FIELD_GET(GENMASK(31, 16), (reg))
+
+struct ma35_nand_chip {
+	struct list_head node;
+	struct nand_chip chip;
+
+	u32 eccstatus;
+	u8 nsels;
+	u8 sels[] __counted_by(nsels);
+};
+
+struct ma35_nand_info {
+	struct nand_controller controller;
+	struct device *dev;
+	void __iomem *regs;
+	int irq;
+	struct clk *clk;
+	struct completion complete;
+	struct list_head chips;
+
+	u8 *buffer;
+	unsigned long assigned_cs;
+};
+
+static inline struct ma35_nand_chip *to_ma35_nand(struct nand_chip *chip)
+{
+	return container_of(chip, struct ma35_nand_chip, chip);
+}
+
+static int ma35_ooblayout_ecc(struct mtd_info *mtd, int section,
+			      struct mtd_oob_region *oob_region)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+
+	if (section)
+		return -ERANGE;
+
+	oob_region->length = chip->ecc.total;
+	oob_region->offset = mtd->oobsize - oob_region->length;
+
+	return 0;
+}
+
+static int ma35_ooblayout_free(struct mtd_info *mtd, int section,
+			       struct mtd_oob_region *oob_region)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+
+	if (section)
+		return -ERANGE;
+
+	oob_region->length = mtd->oobsize - chip->ecc.total - 2;
+	oob_region->offset = 2;
+
+	return 0;
+}
+
+static const struct mtd_ooblayout_ops ma35_ooblayout_ops = {
+	.free = ma35_ooblayout_free,
+	.ecc = ma35_ooblayout_ecc,
+};
+
+static inline void ma35_clear_spare(struct nand_chip *chip, int size)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	int i;
+
+	for (i = 0; i < size / 4; i++)
+		writel(0xff, nand->regs + MA35_NFI_REG_NANDRA0);
+}
+
+static inline void read_remaining_bytes(struct ma35_nand_info *nand, u32 *buf,
+					u32 offset, int size, int swap)
+{
+	u32 value = readl(nand->regs + MA35_NFI_REG_NANDRA0 + offset);
+	u8 *ptr = (u8 *)buf;
+	int i, shift;
+
+	for (i = 0; i < size; i++) {
+		shift = (swap ? 3 - i : i) * 8;
+		ptr[i] = (value >> shift) & 0xff;
+	}
+}
+
+static inline void ma35_read_spare(struct nand_chip *chip, int size, u32 *buf, u32 offset)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	u32 off = round_down(offset, 4);
+	int len = offset % 4;
+	int i;
+
+	if (len) {
+		read_remaining_bytes(nand, buf, off, 4 - len, 1);
+		off += 4;
+		size -= (4 - len);
+	}
+
+	for (i = 0; i < size / 4; i++)
+		*buf++ = readl(nand->regs + MA35_NFI_REG_NANDRA0 + off + (i * 4));
+
+	read_remaining_bytes(nand, buf, off + (size & ~3), size % 4, 0);
+}
+
+static inline void ma35_write_spare(struct nand_chip *chip, int size, u32 *buf)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	u32 value;
+	int i, j;
+	u8 *ptr;
+
+	for (i = 0, j = 0; i < size / 4; i++, j += 4)
+		writel(*buf++, nand->regs + MA35_NFI_REG_NANDRA0 + j);
+
+	ptr = (u8 *)buf;
+	switch (size % 4) {
+	case 1:
+		writel(*ptr, nand->regs + MA35_NFI_REG_NANDRA0 + j);
+		break;
+	case 2:
+		value = *ptr | (*(ptr + 1) << 8);
+		writel(value, nand->regs + MA35_NFI_REG_NANDRA0 + j);
+		break;
+	case 3:
+		value = *ptr | (*(ptr + 1) << 8) | (*(ptr + 2) << 16);
+		writel(value, nand->regs + MA35_NFI_REG_NANDRA0 + j);
+		break;
+	default:
+		break;
+	}
+}
+
+static void ma35_nand_target_enable(struct nand_chip *chip, unsigned int cs)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	u32 reg;
+
+	switch (cs) {
+	case 0:
+		reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+		writel(reg & ~DISABLE_CS0, nand->regs + MA35_NFI_REG_NANDCTL);
+
+		reg = readl(nand->regs + MA35_NFI_REG_NANDINTSTS);
+		reg |= INT_RB0;
+		writel(reg, nand->regs + MA35_NFI_REG_NANDINTSTS);
+		break;
+	default:
+		break;
+	}
+}
+
+static int ma35_nand_hwecc_init(struct nand_chip *chip, struct ma35_nand_info *nand)
+{
+	struct ma35_nand_chip *nvtnand = to_ma35_nand(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct device *dev = mtd->dev.parent;
+	u32 reg;
+
+	nand->buffer = devm_kzalloc(dev, mtd->writesize, GFP_KERNEL);
+	if (!nand->buffer)
+		return -ENOMEM;
+
+	/* Redundant area size */
+	writel(mtd->oobsize, nand->regs + MA35_NFI_REG_NANDRACTL);
+
+	/* Protect redundant 3 bytes and disable ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	reg |= (PROT3BEN | ECC_CHK);
+	reg &= ~ECC_EN;
+
+	if (chip->ecc.strength != 0) {
+		chip->ecc.steps = mtd->writesize / chip->ecc.size;
+		nvtnand->eccstatus = (chip->ecc.steps < 4) ? 1 : chip->ecc.steps / 4;
+		/* Set BCH algorithm */
+		reg &= ~BCH_MASK;
+		switch (chip->ecc.strength) {
+		case 8:
+			chip->ecc.total = chip->ecc.steps * MA35_PARITY_BCH8;
+			reg |= BCH_T8;
+			break;
+		case 12:
+			chip->ecc.total = chip->ecc.steps * MA35_PARITY_BCH12;
+			reg |= BCH_T12;
+			break;
+		case 24:
+			chip->ecc.total = chip->ecc.steps * MA35_PARITY_BCH24;
+			reg |= BCH_T24;
+			break;
+		default:
+			dev_err(nand->dev, "ECC strength unsupported\n");
+			return -EINVAL;
+		}
+
+		chip->ecc.bytes = chip->ecc.total / chip->ecc.steps;
+	}
+	writel(reg, nand->regs + MA35_NFI_REG_NANDCTL);
+	return 0;
+}
+
+/* Correct data by BCH alrogithm */
+static void ma35_nfi_correct(struct nand_chip *chip, u8 index,
+			     u8 err_cnt, u8 *addr)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	u32 temp_data[24], temp_addr[24];
+	u32 padding_len, parity_len;
+	u32 value, offset, remain;
+	u32 err_data[6];
+	u8  i, j;
+
+	/* Configurations */
+	if (chip->ecc.strength <= 8) {
+		parity_len = MA35_PARITY_BCH8;
+		padding_len = MA35_BCH_PADDING_512;
+	} else if (chip->ecc.strength <= 12) {
+		parity_len = MA35_PARITY_BCH12;
+		padding_len = MA35_BCH_PADDING_512;
+	} else if (chip->ecc.strength <= 24) {
+		parity_len = MA35_PARITY_BCH24;
+		padding_len = MA35_BCH_PADDING_1024;
+	} else {
+		dev_err(nand->dev, "Invalid BCH_TSEL = 0x%lx\n",
+			readl(nand->regs + MA35_NFI_REG_NANDCTL) & BCH_MASK);
+		return;
+	}
+
+	/*
+	 * got valid BCH_ECC_DATAx and parse them to temp_data[]
+	 * got the valid register number of BCH_ECC_DATAx since
+	 * one register include 4 error bytes
+	 */
+	j = (err_cnt + 3) / 4;
+	j = (j > 6) ? 6 : j;
+	for (i = 0; i < j; i++)
+		err_data[i] = readl(nand->regs + MA35_NFI_REG_NANDECCED0 + i * 4);
+
+	for (i = 0; i < j; i++) {
+		temp_data[i * 4 + 0] = err_data[i] & 0xff;
+		temp_data[i * 4 + 1] = (err_data[i] >> 8) & 0xff;
+		temp_data[i * 4 + 2] = (err_data[i] >> 16) & 0xff;
+		temp_data[i * 4 + 3] = (err_data[i] >> 24) & 0xff;
+	}
+
+	/*
+	 * got valid REG_BCH_ECC_ADDRx and parse them to temp_addr[]
+	 * got the valid register number of REG_BCH_ECC_ADDRx since
+	 * one register include 2 error addresses
+	 */
+	j = (err_cnt + 1) / 2;
+	j = (j > 12) ? 12 : j;
+	for (i = 0; i < j; i++) {
+		temp_addr[i * 2 + 0] = readl(nand->regs + MA35_NFI_REG_NANDECCEA0 + i * 4)
+					& 0x07ff;
+		temp_addr[i * 2 + 1] = (readl(nand->regs + MA35_NFI_REG_NANDECCEA0 + i * 4)
+					>> 16) & 0x07ff;
+	}
+
+	/* pointer to begin address of field that with data error */
+	addr += index * chip->ecc.size;
+
+	/* correct each error bytes */
+	for (i = 0; i < err_cnt; i++) {
+		u32 corrected_index = temp_addr[i];
+
+		if (corrected_index < chip->ecc.size) {
+			/* for wrong data in field */
+			*(addr + corrected_index) ^= temp_data[i];
+		} else if (corrected_index < (chip->ecc.size + 3)) {
+			/* for wrong first-3-bytes in redundancy area */
+			corrected_index -= chip->ecc.size;
+			temp_addr[i] += (parity_len * index);	/* field offset */
+
+			value = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+			value ^= temp_data[i] << (8 * corrected_index);
+			writel(value, nand->regs + MA35_NFI_REG_NANDRA0);
+		} else {
+			/*
+			 * for wrong parity code in redundancy area
+			 * ERR_ADDRx = [data in field] + [3 bytes] + [xx] + [parity code]
+			 *                               |<--     padding bytes      -->|
+			 * The ERR_ADDRx for last parity code always = field size + padding size.
+			 * The first parity code = field size + padding size - parity code length.
+			 * For example, for BCH T12, the first parity code = 512 + 32 - 23 = 521.
+			 * That is, error byte address offset within field is
+			 */
+			corrected_index -= (chip->ecc.size + padding_len - parity_len);
+
+			/*
+			 * final address = first parity code of first field +
+			 *                 offset of fields +
+			 *                 offset within field
+			 */
+			offset = (readl(nand->regs + MA35_NFI_REG_NANDRACTL) & 0x1ff) -
+				(parity_len * chip->ecc.steps) +
+				(parity_len * index) + corrected_index;
+
+			remain = offset % 4;
+			value = readl(nand->regs + MA35_NFI_REG_NANDRA0 + offset - remain);
+			value ^= temp_data[i] << (8 * remain);
+			writel(value, nand->regs + MA35_NFI_REG_NANDRA0 + offset - remain);
+		}
+	}
+}
+
+static int ma35_nfi_ecc_check(struct nand_chip *chip, u8 *addr)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct ma35_nand_chip *nvtnand = to_ma35_nand(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int maxbitflips = 0;
+	int cnt = 0;
+	u32 status;
+	int i, j;
+
+	for (j = 0; j < nvtnand->eccstatus; j++) {
+		status = readl(nand->regs + MA35_NFI_REG_NANDECCES0 + j * 4);
+		if (!status)
+			continue;
+
+		for (i = 0; i < 4; i++) {
+			if ((status & ECC_STATUS_MASK) == 0x01) {
+				/* Correctable error */
+				cnt = (status >> 2) & ECC_ERR_CNT_MASK;
+				ma35_nfi_correct(chip, j * 4 + i, cnt, addr);
+				maxbitflips = max_t(u32, maxbitflips, cnt);
+				mtd->ecc_stats.corrected += cnt;
+			} else {
+				/* Uncorrectable error */
+				mtd->ecc_stats.failed++;
+				dev_err(nand->dev, "uncorrectable error! 0x%4x\n", status);
+				return -EBADMSG;
+			}
+			status >>= 8;
+		}
+	}
+	return maxbitflips;
+}
+
+static void ma35_nand_dmac_init(struct ma35_nand_info *nand)
+{
+	/* DMAC reset and enable */
+	writel(DMA_RST | DMA_EN, nand->regs + MA35_NFI_REG_DMACTL);
+	writel(DMA_EN, nand->regs + MA35_NFI_REG_DMACTL);
+
+	/* Clear DMA finished flag and enable */
+	writel(INT_DMA | INT_ECC, nand->regs + MA35_NFI_REG_NANDINTSTS);
+	writel(INT_DMA, nand->regs + MA35_NFI_REG_NANDINTEN);
+}
+
+static int ma35_nand_do_write(struct nand_chip *chip, const u8 *addr, u32 len)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	dma_addr_t dma_addr;
+	int ret = 0, i;
+	u32 reg;
+
+	if (len != mtd->writesize) {
+		for (i = 0; i < len; i++)
+			writel(addr[i], nand->regs + MA35_NFI_REG_NANDDATA);
+		return 0;
+	}
+
+	ma35_nand_dmac_init(nand);
+
+	/* To mark this page as dirty. */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+	if (reg & 0xffff0000)
+		writel(reg & 0xffff, nand->regs + MA35_NFI_REG_NANDRA0);
+
+	dma_addr = dma_map_single(nand->dev, (void *)addr, len, DMA_TO_DEVICE);
+	ret = dma_mapping_error(nand->dev, dma_addr);
+	if (ret) {
+		dev_err(nand->dev, "dma mapping error\n");
+		return -EINVAL;
+	}
+	dma_sync_single_for_device(nand->dev, dma_addr, len, DMA_TO_DEVICE);
+
+	reinit_completion(&nand->complete);
+	writel(dma_addr, nand->regs + MA35_NFI_REG_DMASA);
+	writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DMA_W_EN,
+	       nand->regs + MA35_NFI_REG_NANDCTL);
+	ret = wait_for_completion_timeout(&nand->complete, msecs_to_jiffies(1000));
+	if (!ret) {
+		dev_err(nand->dev, "write timeout\n");
+		ret = -ETIMEDOUT;
+	}
+
+	dma_unmap_single(nand->dev, dma_addr, len, DMA_TO_DEVICE);
+
+	return ret;
+}
+
+static int ma35_nand_do_read(struct nand_chip *chip, u8 *addr, u32 len)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int ret = 0, cnt = 0, i;
+	dma_addr_t dma_addr;
+	u32 reg;
+
+	if (len != mtd->writesize) {
+		for (i = 0; i < len; i++)
+			addr[i] = readb(nand->regs + MA35_NFI_REG_NANDDATA);
+		return 0;
+	}
+
+	ma35_nand_dmac_init(nand);
+
+	/* Setup and start DMA using dma_addr */
+	dma_addr = dma_map_single(nand->dev, (void *)addr, len, DMA_FROM_DEVICE);
+	ret = dma_mapping_error(nand->dev, dma_addr);
+	if (ret) {
+		dev_err(nand->dev, "dma mapping error\n");
+		return -EINVAL;
+	}
+
+	reinit_completion(&nand->complete);
+	writel(dma_addr, nand->regs + MA35_NFI_REG_DMASA);
+	writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | DMA_R_EN,
+	       nand->regs + MA35_NFI_REG_NANDCTL);
+	ret = wait_for_completion_timeout(&nand->complete, msecs_to_jiffies(1000));
+	if (!ret) {
+		dev_err(nand->dev, "read timeout\n");
+		ret = -ETIMEDOUT;
+	}
+
+	dma_unmap_single(nand->dev, dma_addr, len, DMA_FROM_DEVICE);
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDINTSTS);
+	if (reg & INT_ECC) {
+		cnt = ma35_nfi_ecc_check(chip, addr);
+		if (cnt < 0) {
+			writel(DMA_RST | DMA_EN, nand->regs + MA35_NFI_REG_DMACTL);
+			writel(readl(nand->regs + MA35_NFI_REG_NANDCTL) | SWRST,
+			       nand->regs + MA35_NFI_REG_NANDCTL);
+		}
+		writel(INT_ECC, nand->regs + MA35_NFI_REG_NANDINTSTS);
+	}
+
+	ret = ret < 0 ? ret : cnt;
+	return ret;
+}
+
+static int ma35_nand_format_subpage(struct nand_chip *chip, u32 offset,
+				    u32 len, const u8 *buf)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	u32 page_off = round_down(offset, chip->ecc.size);
+	u32 end = DIV_ROUND_UP(page_off + len, chip->ecc.size);
+	u32 start = page_off / chip->ecc.size;
+	u32 reg;
+	int i;
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRACTL) | 0xffff0000;
+	memset(nand->buffer, 0xff, mtd->writesize);
+	for (i = start; i < end; i++) {
+		memcpy(nand->buffer + i * chip->ecc.size,
+		       buf + i * chip->ecc.size, chip->ecc.size);
+		reg &= ~(1 << (i + 16));
+	}
+	writel(reg, nand->regs + MA35_NFI_REG_NANDRACTL);
+
+	return 0;
+}
+
+static int ma35_nand_write_subpage_hwecc(struct nand_chip *chip, u32 offset,
+					 u32 data_len, const u8 *buf,
+					 int oob_required, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	u32 reg, oobpoi, index;
+	int i;
+
+	/* Enable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg | ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+
+	ma35_clear_spare(chip, mtd->oobsize);
+	ma35_write_spare(chip, mtd->oobsize - chip->ecc.total,
+			 (u32 *)chip->oob_poi);
+
+	ma35_nand_format_subpage(chip, offset, data_len, buf);
+	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+	ma35_nand_do_write(chip, nand->buffer, mtd->writesize);
+	nand_prog_page_end_op(chip);
+
+	oobpoi = mtd->oobsize - chip->ecc.total;
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRACTL);
+	for (i = 0; i < chip->ecc.steps; i++) {
+		index = i * chip->ecc.bytes;
+		if (!(reg & (1 << (i + 16)))) {
+			ma35_read_spare(chip, chip->ecc.bytes,
+					(u32 *)(chip->oob_poi + oobpoi + index),
+					oobpoi + index);
+		}
+	}
+
+	writel(mtd->oobsize, nand->regs + MA35_NFI_REG_NANDRACTL);
+	/* Disable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg & ~ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	return 0;
+}
+
+static int ma35_nand_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
+				      int oob_required, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	u32 reg;
+
+	/* Enable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg | ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+
+	ma35_clear_spare(chip, mtd->oobsize);
+	ma35_write_spare(chip, mtd->oobsize - chip->ecc.total,
+			 (u32 *)chip->oob_poi);
+
+	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+	ma35_nand_do_write(chip, buf, mtd->writesize);
+	nand_prog_page_end_op(chip);
+
+	ma35_read_spare(chip, chip->ecc.total,
+			(u32 *)(chip->oob_poi + (mtd->oobsize - chip->ecc.total)),
+			mtd->oobsize - chip->ecc.total);
+
+	/* Disable HW ECC engine */
+	writel(reg & ~ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	return 0;
+}
+
+static int ma35_nand_read_subpage_hwecc(struct nand_chip *chip, u32 offset,
+					u32 data_len, u8 *buf, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int bitflips = 0;
+	u32 reg;
+
+	/* Enable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg | ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+	nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
+	ma35_write_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi);
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+	if (PREFIX_RA_IS_EMPTY(reg)) {
+		memset((void *)buf, 0xff, mtd->writesize);
+	} else {
+		nand_read_page_op(chip, page, offset, NULL, 0);
+		bitflips = ma35_nand_do_read(chip, buf + offset, data_len);
+		ma35_read_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi, 0);
+	}
+
+	/* Disable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg & ~ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	return bitflips;
+}
+
+static int ma35_nand_read_page_hwecc(struct nand_chip *chip, u8 *buf,
+				     int oob_required, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	int bitflips = 0;
+	u32 reg;
+
+	/* Enable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg | ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+	nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
+	ma35_write_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi);
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+	if (PREFIX_RA_IS_EMPTY(reg)) {
+		memset((void *)buf, 0xff, mtd->writesize);
+	} else {
+		nand_read_page_op(chip, page, 0, NULL, 0);
+		bitflips = ma35_nand_do_read(chip, buf, mtd->writesize);
+		ma35_read_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi, 0);
+	}
+
+	/* Disable HW ECC engine */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	writel(reg & ~ECC_EN, nand->regs + MA35_NFI_REG_NANDCTL);
+
+	return bitflips;
+}
+
+static int ma35_nand_read_oob_hwecc(struct nand_chip *chip, int page)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	u32 reg;
+
+	ma35_nand_target_enable(chip, chip->cur_cs);
+	nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
+
+	/* copy OOB data to controller redundant area for page read */
+	ma35_write_spare(chip, mtd->oobsize, (u32 *)chip->oob_poi);
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDRA0);
+	if (PREFIX_RA_IS_EMPTY(reg))
+		memset((void *)chip->oob_poi, 0xff, mtd->oobsize);
+
+	return 0;
+}
+
+static inline void ma35_hw_init(struct ma35_nand_info *nand)
+{
+	u32 reg;
+
+	/* Disable flash wp. */
+	writel(DISABLE_WP, nand->regs + MA35_NFI_REG_NANDECTL);
+
+	/* resets the internal state machine and counters */
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL);
+	reg |= SWRST;
+	writel(reg, nand->regs + MA35_NFI_REG_NANDCTL);
+}
+
+static irqreturn_t ma35_nand_irq(int irq, void *id)
+{
+	struct ma35_nand_info *nand = (struct ma35_nand_info *)id;
+	u32 isr;
+
+	isr = readl(nand->regs + MA35_NFI_REG_NANDINTSTS);
+	if (isr & INT_DMA) {
+		writel(INT_DMA, nand->regs + MA35_NFI_REG_NANDINTSTS);
+		complete(&nand->complete);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int ma35_nand_attach_chip(struct nand_chip *chip)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct device *dev = mtd->dev.parent;
+	u32 reg;
+
+	if (chip->options & NAND_BUSWIDTH_16) {
+		dev_err(dev, "16 bits bus width not supported");
+		return -EINVAL;
+	}
+
+	reg = readl(nand->regs + MA35_NFI_REG_NANDCTL) & (~PSIZE_MASK);
+	switch (mtd->writesize) {
+	case SZ_2K:
+		writel(reg | PSIZE_2K, nand->regs + MA35_NFI_REG_NANDCTL);
+		break;
+	case SZ_4K:
+		writel(reg | PSIZE_4K, nand->regs + MA35_NFI_REG_NANDCTL);
+		break;
+	case SZ_8K:
+		writel(reg | PSIZE_8K, nand->regs + MA35_NFI_REG_NANDCTL);
+		break;
+	default:
+		dev_err(dev, "Unsupported page size");
+		return -EINVAL;
+	}
+
+	switch (chip->ecc.engine_type) {
+	case NAND_ECC_ENGINE_TYPE_ON_HOST:
+		/* Do not store BBT bits in the OOB section as it is not protected */
+		if (chip->bbt_options & NAND_BBT_USE_FLASH)
+			chip->bbt_options |= NAND_BBT_NO_OOB;
+		chip->options |= NAND_USES_DMA | NAND_SUBPAGE_READ;
+		chip->ecc.write_subpage = ma35_nand_write_subpage_hwecc;
+		chip->ecc.write_page = ma35_nand_write_page_hwecc;
+		chip->ecc.read_subpage = ma35_nand_read_subpage_hwecc;
+		chip->ecc.read_page  = ma35_nand_read_page_hwecc;
+		chip->ecc.read_oob   = ma35_nand_read_oob_hwecc;
+		return ma35_nand_hwecc_init(chip, nand);
+	case NAND_ECC_ENGINE_TYPE_NONE:
+	case NAND_ECC_ENGINE_TYPE_SOFT:
+	case NAND_ECC_ENGINE_TYPE_ON_DIE:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ma35_nfc_exec_instr(struct nand_chip *chip,
+			       const struct nand_op_instr *instr)
+{
+	struct ma35_nand_info *nand = nand_get_controller_data(chip);
+	unsigned int i;
+	int ret = 0;
+	u32 status;
+
+	switch (instr->type) {
+	case NAND_OP_CMD_INSTR:
+		writel(instr->ctx.cmd.opcode, nand->regs + MA35_NFI_REG_NANDCMD);
+		break;
+	case NAND_OP_ADDR_INSTR:
+		for (i = 0; i < instr->ctx.addr.naddrs; i++) {
+			if (i == (instr->ctx.addr.naddrs - 1))
+				writel(instr->ctx.addr.addrs[i] | ENDADDR,
+				       nand->regs + MA35_NFI_REG_NANDADDR);
+			else
+				writel(instr->ctx.addr.addrs[i],
+				       nand->regs + MA35_NFI_REG_NANDADDR);
+		}
+		break;
+	case NAND_OP_DATA_IN_INSTR:
+		ret = ma35_nand_do_read(chip, instr->ctx.data.buf.in, instr->ctx.data.len);
+		break;
+	case NAND_OP_DATA_OUT_INSTR:
+		ret = ma35_nand_do_write(chip, instr->ctx.data.buf.out, instr->ctx.data.len);
+		break;
+	case NAND_OP_WAITRDY_INSTR:
+		return readl_poll_timeout(nand->regs + MA35_NFI_REG_NANDINTSTS, status,
+					  status & INT_RB0, 20,
+					  instr->ctx.waitrdy.timeout_ms * MSEC_PER_SEC);
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int ma35_nfc_exec_op(struct nand_chip *chip,
+			    const struct nand_operation *op,
+			    bool check_only)
+{
+	int ret = 0;
+	u32 i;
+
+	if (check_only)
+		return 0;
+
+	ma35_nand_target_enable(chip, op->cs);
+
+	for (i = 0; i < op->ninstrs; i++) {
+		ret = ma35_nfc_exec_instr(chip, &op->instrs[i]);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static const struct nand_controller_ops ma35_nfc_ops = {
+	.attach_chip = ma35_nand_attach_chip,
+	.exec_op = ma35_nfc_exec_op,
+};
+
+static int ma35_nand_chip_init(struct device *dev, struct ma35_nand_info *nand,
+			       struct device_node *np)
+{
+	struct ma35_nand_chip *nvtnand;
+	struct nand_chip *chip;
+	struct mtd_info *mtd;
+	int nsels;
+	int ret;
+	u32 cs;
+	int i;
+
+	nsels = of_property_count_elems_of_size(np, "reg", sizeof(u32));
+	if (!nsels || nsels > MA35_MAX_NSELS) {
+		dev_err(dev, "invalid reg property size %d\n", nsels);
+		return -EINVAL;
+	}
+
+	nvtnand = devm_kzalloc(dev, struct_size(nvtnand, sels, nsels),
+			       GFP_KERNEL);
+	if (!nvtnand)
+		return -ENOMEM;
+
+	nvtnand->nsels = nsels;
+	for (i = 0; i < nsels; i++) {
+		ret = of_property_read_u32_index(np, "reg", i, &cs);
+		if (ret) {
+			dev_err(dev, "reg property failure : %d\n", ret);
+			return ret;
+		}
+
+		if (cs >= MA35_MAX_NSELS) {
+			dev_err(dev, "invalid CS: %u\n", cs);
+			return -EINVAL;
+		}
+
+		if (test_and_set_bit(cs, &nand->assigned_cs)) {
+			dev_err(dev, "CS %u already assigned\n", cs);
+			return -EINVAL;
+		}
+
+		nvtnand->sels[i] = cs;
+	}
+
+	chip = &nvtnand->chip;
+	chip->controller = &nand->controller;
+
+	nand_set_flash_node(chip, np);
+	nand_set_controller_data(chip, nand);
+
+	mtd = nand_to_mtd(chip);
+	mtd->owner = THIS_MODULE;
+	mtd->dev.parent = dev;
+
+	mtd_set_ooblayout(mtd, &ma35_ooblayout_ops);
+	ret = nand_scan(chip, nsels);
+	if (ret)
+		return ret;
+
+	ret = mtd_device_register(mtd, NULL, 0);
+	if (ret) {
+		nand_cleanup(chip);
+		return ret;
+	}
+
+	list_add_tail(&nvtnand->node, &nand->chips);
+
+	return 0;
+}
+
+static void ma35_chips_cleanup(struct ma35_nand_info *nand)
+{
+	struct ma35_nand_chip *nvtnand, *tmp;
+	struct nand_chip *chip;
+	int ret;
+
+	list_for_each_entry_safe(nvtnand, tmp, &nand->chips, node) {
+		chip = &nvtnand->chip;
+		ret = mtd_device_unregister(nand_to_mtd(chip));
+		WARN_ON(ret);
+		nand_cleanup(chip);
+		list_del(&nvtnand->node);
+	}
+}
+
+static int ma35_nand_chips_init(struct device *dev, struct ma35_nand_info *nand)
+{
+	struct device_node *np = dev->of_node, *nand_np;
+	int ret;
+
+	for_each_child_of_node(np, nand_np) {
+		ret = ma35_nand_chip_init(dev, nand, nand_np);
+		if (ret) {
+			ma35_chips_cleanup(nand);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int ma35_nand_probe(struct platform_device *pdev)
+{
+	struct ma35_nand_info *nand;
+	int ret = 0;
+
+	nand = devm_kzalloc(&pdev->dev, sizeof(*nand), GFP_KERNEL);
+	if (!nand)
+		return -ENOMEM;
+
+	nand_controller_init(&nand->controller);
+	INIT_LIST_HEAD(&nand->chips);
+	nand->controller.ops = &ma35_nfc_ops;
+
+	init_completion(&nand->complete);
+
+	nand->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(nand->regs))
+		return PTR_ERR(nand->regs);
+
+	nand->dev = &pdev->dev;
+
+	nand->clk = devm_clk_get_enabled(&pdev->dev, "nand_gate");
+	if (IS_ERR(nand->clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(nand->clk),
+				     "failed to find NAND clock\n");
+
+	nand->irq = platform_get_irq(pdev, 0);
+	if (nand->irq < 0)
+		return dev_err_probe(&pdev->dev, nand->irq,
+				     "failed to get platform irq\n");
+
+	ret = devm_request_irq(&pdev->dev, nand->irq, ma35_nand_irq,
+			       IRQF_TRIGGER_HIGH, "ma35d1-nand", nand);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request NAND irq\n");
+		return -ENXIO;
+	}
+
+	platform_set_drvdata(pdev, nand);
+
+	writel(GRST | NAND_EN, nand->regs + MA35_NFI_REG_GCTL);
+	ma35_hw_init(nand);
+	ret = ma35_nand_chips_init(&pdev->dev, nand);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to init NAND chips\n");
+		clk_disable(nand->clk);
+		return ret;
+	}
+
+	return ret;
+}
+
+static void ma35_nand_remove(struct platform_device *pdev)
+{
+	struct ma35_nand_info *nand = platform_get_drvdata(pdev);
+
+	ma35_chips_cleanup(nand);
+}
+
+static const struct of_device_id ma35_nand_of_match[] = {
+	{ .compatible = "nuvoton,ma35d1-nand" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ma35_nand_of_match);
+
+static struct platform_driver ma35_nand_driver = {
+	.driver = {
+		.name = "ma35d1-nand",
+		.of_match_table = ma35_nand_of_match,
+	},
+	.probe = ma35_nand_probe,
+	.remove = ma35_nand_remove,
+};
+
+module_platform_driver(ma35_nand_driver);
+
+MODULE_DESCRIPTION("Nuvoton ma35 NAND driver");
+MODULE_AUTHOR("Hui-Ping Chen <hpchen0nvt at gmail.com>");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From a0987203069 at gmail.com  Thu Dec  5 19:19:43 2024
From: a0987203069 at gmail.com (Joey Lu)
Date: Fri, 6 Dec 2024 11:19:43 +0800
Subject: [PATCH v4 1/3] dt-bindings: net: nuvoton: Add schema for Nuvoton
 MA35 family GMAC
In-Reply-To: <20241204142722.GA177756-robh@kernel.org>
References: <20241202023643.75010-1-a0987203069@gmail.com>
 <20241202023643.75010-2-a0987203069@gmail.com>
 <20241204142722.GA177756-robh@kernel.org>
Message-ID: <a04cd927-63cb-4271-bfc7-3ec97c5a978d@gmail.com>

Dear Rob,

Thank you for your reply.

Rob Herring ? 12/4/2024 10:27 PM ??:
> On Mon, Dec 02, 2024 at 10:36:41AM +0800, Joey Lu wrote:
>> Create initial schema for Nuvoton MA35 family Gigabit MAC.
>>
>> Signed-off-by: Joey Lu <a0987203069 at gmail.com>
>> ---
>>   .../bindings/net/nuvoton,ma35d1-dwmac.yaml    | 134 ++++++++++++++++++
>>   .../devicetree/bindings/net/snps,dwmac.yaml   |   1 +
>>   2 files changed, 135 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml b/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
>> new file mode 100644
>> index 000000000000..e44abaf4da3e
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
>> @@ -0,0 +1,134 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/net/nuvoton,ma35d1-dwmac.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Nuvoton DWMAC glue layer controller
>> +
>> +maintainers:
>> +  - Joey Lu <yclu4 at nuvoton.com>
>> +
>> +description:
>> +  Nuvoton 10/100/1000Mbps Gigabit Ethernet MAC Controller is based on
>> +  Synopsys DesignWare MAC (version 3.73a).
>> +
>> +allOf:
>> +  - $ref: snps,dwmac.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    items:
>> +      - enum:
>> +          - nuvoton,ma35d1-dwmac
>> +
>> +  reg:
>> +    maxItems: 1
>> +    description:
>> +      Register range should be one of the GMAC interface.
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    items:
>> +      - description: MAC clock
>> +      - description: PTP clock
>> +
>> +  clock-names:
>> +    items:
>> +      - const: stmmaceth
>> +      - const: ptp_ref
>> +
>> +  nuvoton,sys:
>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>> +    items:
>> +      - items:
>> +          - description: phandle to access syscon registers.
>> +          - description: GMAC interface ID.
>> +            enum:
>> +              - 0
>> +              - 1
>> +    description:
>> +      A phandle to the syscon with one argument that configures system registers
>> +      for MA35D1's two GMACs. The argument specifies the GMAC interface ID.
>> +
>> +  resets:
>> +    maxItems: 1
>> +
>> +  reset-names:
>> +    items:
>> +      - const: stmmaceth
>> +
>> +  phy-mode:
>> +    enum:
>> +      - rmii
>> +      - rgmii
>> +      - rgmii-id
>> +      - rgmii-txid
>> +      - rgmii-rxid
>> +
>> +  tx-internal-delay-ps:
>> +    default: 0
>> +    minimum: 0
>> +    maximum: 2000
>> +    description:
>> +      RGMII TX path delay used only when PHY operates in RGMII mode with
>> +      internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds.
>> +      Allowed values are from 0 to 2000.
>> +
>> +  rx-internal-delay-ps:
>> +    default: 0
>> +    minimum: 0
>> +    maximum: 2000
>> +    description:
>> +      RGMII RX path delay used only when PHY operates in RGMII mode with
>> +      internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds.
>> +      Allowed values are from 0 to 2000.
>> +
>> +  mdio:
>> +    $ref: /schemas/net/mdio.yaml#
> Drop. snps,dwmac.yaml already has this.
Got it.
>
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - interrupts
>> +  - interrupt-names
> Drop all 4. Already required by snps,dwmac.yaml.
Got it.
>
>> +  - clocks
>> +  - clock-names
>> +  - nuvoton,sys
>> +  - resets
>> +  - reset-names
>> +  - phy-mode
> Drop this one too.
Got it.
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
>> +    #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
>> +    ethernet at 40120000 {
>> +        compatible = "nuvoton,ma35d1-dwmac";
>> +        reg = <0x40120000 0x10000>;
>> +        interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
>> +        interrupt-names = "macirq";
>> +        clocks = <&clk EMAC0_GATE>, <&clk EPLL_DIV8>;
>> +        clock-names = "stmmaceth", "ptp_ref";
>> +
>> +        nuvoton,sys = <&sys 0>;
>> +        resets = <&sys MA35D1_RESET_GMAC0>;
>> +        reset-names = "stmmaceth";
>> +
>> +        phy-mode = "rgmii-id";
>> +        phy-handle = <&eth_phy0>;
>> +        mdio {
>> +            compatible = "snps,dwmac-mdio";
>> +            #address-cells = <1>;
>> +            #size-cells = <0>;
>> +
>> +            ethernet-phy at 0 {
>> +                reg = <0>;
>> +            };
>> +        };
>> +    };
>> diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
>> index eb1f3ae41ab9..4bf59ab910cc 100644
>> --- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
>> +++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
>> @@ -67,6 +67,7 @@ properties:
>>           - ingenic,x2000-mac
>>           - loongson,ls2k-dwmac
>>           - loongson,ls7a-dwmac
>> +        - nuvoton,ma35d1-dwmac
>>           - qcom,qcs404-ethqos
>>           - qcom,sa8775p-ethqos
>>           - qcom,sc8280xp-ethqos
>> -- 
>> 2.34.1

Thanks!

BR,

Joey



From shijie at os.amperecomputing.com  Thu Dec  5 19:23:43 2024
From: shijie at os.amperecomputing.com (Huang Shijie)
Date: Fri,  6 Dec 2024 11:23:43 +0800
Subject: [PATCH v2 4/4 fix] arm64: add a new document for the fine-tuning tips
In-Reply-To: <20241126085647.4993-5-shijie@os.amperecomputing.com>
References: <20241126085647.4993-5-shijie@os.amperecomputing.com>
Message-ID: <20241206032343.6357-1-shijie@os.amperecomputing.com>

Put some fine-tuning tips in this file:
	1.) rodata=noalias
	2.) slab_strict_numa
	3.) CONFIG_SCHED_CLUSTER

We can add more tips in future.

Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
---
Add the comment from Christoph.
---
 Documentation/arch/arm64/fine-tuning-tips.rst | 25 +++++++++++++++++++
 Documentation/arch/arm64/index.rst            |  1 +
 2 files changed, 26 insertions(+)
 create mode 100644 Documentation/arch/arm64/fine-tuning-tips.rst

diff --git a/Documentation/arch/arm64/fine-tuning-tips.rst b/Documentation/arch/arm64/fine-tuning-tips.rst
new file mode 100644
index 000000000000..df67a5ac87b9
--- /dev/null
+++ b/Documentation/arch/arm64/fine-tuning-tips.rst
@@ -0,0 +1,25 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+================
+fine-tuning tips
+================
+
+This file contains some fine-tuning tips for arm64 machines.
+These tips do not gurantee that you can get better performance,
+but you can try them with your workload.
+
+rodata=noalias
+----------------
+It can provide us more block mappings and contiguous hits
+to map the linear region which minimizes the TLB footprint.
+
+slab_strict_numa
+----------------
+In NUMA, it will provide the local memory allocation by SLUB.
+Slab objects will be placed individually according to memory policies.
+Increases object locality which is useful for NUMA systems using SLC caches.
+
+CONFIG_SCHED_CLUSTER
+----------------
+Some arm64 machines have cpu core clusters, enable it may
+helps you get better performance.
diff --git a/Documentation/arch/arm64/index.rst b/Documentation/arch/arm64/index.rst
index 6a012c98bdcd..36d1ef09bd71 100644
--- a/Documentation/arch/arm64/index.rst
+++ b/Documentation/arch/arm64/index.rst
@@ -16,6 +16,7 @@ ARM64 Architecture
     cpu-feature-registers
     cpu-hotplug
     elf_hwcaps
+    fine-tuning-tips
     gcs
     hugetlbpage
     kdump
-- 
2.40.1



From damon.ding at rock-chips.com  Thu Dec  5 19:28:21 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Fri, 6 Dec 2024 11:28:21 +0800
Subject: [PATCH v1 04/10] phy: phy-rockchip-samsung-hdptx: Add support for
 eDP mode
In-Reply-To: <5ncdog66jtc4s7vxk2yt4jkknf2es3whvweuqmrxbot3azi5ge@t6s3xadkiasp>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <2131853.KlZ2vcFHjT@diego>
 <6e1f35c0-5ea8-414f-b3ea-4e7222c605ef@rock-chips.com>
 <2886747.Y6S9NjorxK@diego>
 <h4giob7bcrh7qmtepti6huym2llw4ujfmeff76vrgpahb5zy6x@dz6zghsifww5>
 <2342f342-672c-447e-90d8-674b748af6a4@rock-chips.com>
 <abzu2chif2g3urxoqbm3gbe6cciexbmqvn44qezrx4hgllfkkn@7bzi5jl3stqe>
 <42035ebe-09b7-4005-912a-8ec72d5dabcc@rock-chips.com>
 <5ncdog66jtc4s7vxk2yt4jkknf2es3whvweuqmrxbot3azi5ge@t6s3xadkiasp>
Message-ID: <c0bc25b7-6e41-4ed8-ae8d-692a908607df@rock-chips.com>

Hi Sebastian,

On 2024/12/6 2:04, Sebastian Reichel wrote:
> Hello Damon,
> 
> On Thu, Dec 05, 2024 at 09:13:33AM +0800, Damon Ding wrote:
>> Firstly, the term "the HDMI and eDP dynamic switching" can be somewhat
>> misleading, because the eDP usually does not support hot plug. The RK3588
>> eDP is often used as DP, and it actually supports DP 1.2. Therefore, it is
>> better to use the "the HDMI and DP dynamic switching" description.
> 
> The part unclear to me is how the dynamic switching is supposed to
> happen. Looking at the TRM the hotplug detect signals also seem to be
> shared between HDMI and eDP. Can the RK3588S EVB distinguish if HDMI
> or eDP has been plugged, or does this require some user interaction
> to set the right mode?

Indeed, HDMI and eDP share the same pin for hotplug detect. However, 
some users may connect the hotplug detection pin of DP-connector with an 
unexpected pin that can not support the iomux of hotplug detect function 
on RK3588 SoC. This could be due to a flaw in the hardware design, a 
conflict in pin multiplexing, or other factors. Therefore, we support 
the GPIO HDP function for the eDP, as DP also supports this for the same 
reasons.

If the dynamic switching is enabled, HDMI detects the HPD signal through 
  the hotplug detect function pin, while eDP uses one of the available 
GPIO pins to do this.

What's more, if the user connects an HDMI cable first and than connects 
a DP cable as well, despite our clear instruction against using HDMI and 
eDP simultaneously, the status register of GRF will indicate that HDMI 
has been connected. Meanwhile, during the HPD detection process for eDP, 
it will return "connector_status_disconnected". The reverse scenario 
also applies.

> 
>> Indeed, the devm_phy_get(dp->dev, "dp") and devm_of_phy_get_by_index() will
>> help to get the phy reference in .probe() or .bind().
>>
>> However, the phy_set_mode() may be still needed in the HDMI and DP dynamic
>> switching application scenarios. We need the enum phy_mode
>> PHY_MODE_DP/PHY_MODE_HDMI to differentiate the configuration processes in
>> .power_on(), .power_off() and .configure() of struct phy_ops, which will be
>> called in conjunction with plugging in and unplugging an HDMI or DP cable.
> 
> I suppose you could fetch the PHY in power_on() and release it in
> power_off(). But using phy_set_mode() might indeed be better here.
> 

As a future expansion, the .set_mode() can also be helpful in the txffe 
level adjustment for HDMI 2.1. :)

> -- Sebastian

Best regards,
Damon


From mjchen0829 at gmail.com  Thu Dec  5 19:32:34 2024
From: mjchen0829 at gmail.com (Ming-Jen Chen)
Date: Fri, 6 Dec 2024 11:32:34 +0800
Subject: [PATCH 1/2] dt-bindings: input: Add Nuvoton MA35D1 keypad
In-Reply-To: <ql6m6qrdokwfu4iizn6wmvovawuc7kgg6jfzxebkmac5muz66e@myrjvq5jm7gg>
References: <20241119025954.4161-1-mjchen0829@gmail.com>
 <20241119025954.4161-2-mjchen0829@gmail.com>
 <ql6m6qrdokwfu4iizn6wmvovawuc7kgg6jfzxebkmac5muz66e@myrjvq5jm7gg>
Message-ID: <1c0f9efb-61a0-42b9-abe5-87cabe2d783e@gmail.com>


Hi, Krzysztof:

Thank you for your feedback on the v4 submission. I understand that some
of your previous comments were not fully addressed. I want to make sure
I completely understand your feedback and resolve the issues correctly.

Could you kindly let me know if the following approach is acceptable?


On 2024/11/20 ?? 04:41, Krzysztof Kozlowski wrote:
> On Tue, Nov 19, 2024 at 02:59:53AM +0000, Ming-Jen Chen wrote:
>> Add YAML bindings for MA35D1 SoC keypad.
>>
>> Signed-off-by: Ming-Jen Chen <mjchen0829 at gmail.com>
>> ---
>>  .../bindings/input/nuvoton,ma35d1-keypad.yaml | 69 +++++++++++++++++++
>>  1 file changed, 69 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/input/nuvoton,ma35d1-keypad.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/input/nuvoton,ma35d1-keypad.yaml b/Documentation/devicetree/bindings/input/nuvoton,ma35d1-keypad.yaml
>> new file mode 100644
>> index 000000000000..9ccd81a2574d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/input/nuvoton,ma35d1-keypad.yaml
> 
> Filename matching compatible. You got this comment already.
> 
> 
>> @@ -0,0 +1,69 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/input/nuvoton,ma35d1-keypad.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Nuvoton MA35D1 Keypad
>> +
>> +maintainers:
>> +  - Ming-jen Chen <mjchen0829 at gmail.com>
>> +
>> +allOf:
>> +  - $ref: /schemas/input/matrix-keymap.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    const: nuvoton,ma35d1-kpi
>> +
>> +  debounce-delay-ms:
>> +    description: Debounce delay time in milliseconds.
>> +    maxItems: 1
>> +
>> +  scan-interval-ms:
>> +    description: Scan interval time in milliseconds.
>> +    maxItems: 1
>> +
>> +  reg:
>> +    maxItems: 1
> 
> Keep the same order of properties as in required: block.

I will modify to:

properties:
  compatible:
    const: nuvoton,ma35d1-kpi

  reg:
    maxItems: 1

  interrupts:
    maxItems: 1

  clocks:
    maxItems: 1

  linux,keymap:
    description: Keymap for the keypad.

  keypad,num-rows:
    description: Number of rows in the keypad.

  keypad,num-columns:
    description: Number of columns in the keypad.

  debounce-delay-ms:
    description: Debounce delay time in milliseconds.
    maxItems: 1

  scan-interval-ms:
    description: Scan interval time in milliseconds.
    maxItems: 1

required:
  - compatible
  - reg
  - interrupts
  - clocks
  - linux,keymap
  - keypad,num-rows
  - keypad,num-columns
  - debounce-delay-ms
  - scan-interval-ms

> 
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    maxItems: 1
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - interrupts
>> +  - clocks
>> +  - linux,keymap
>> +  - keypad,num-rows
>> +  - keypad,num-columns
>> +  - debounce-delay-ms
>> +  - scan-interval-ms
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/input/input.h>
>> +    keypad at 404A0000 {
> 
> Lowercase hex

I will modify to:
keypad at 404a0000 {

> 
>> +      compatible = "nuvoton,ma35d1-kpi";
>> +      reg = <0x404A0000 0x10000>;
> 
> Lowercase hex

I will modify to:
reg = <0x404a0000 0x10000>;


Your guidance will be greatly appreciated, and I will incorporate the
necessary changes in the next submission to fully address your concerns.

Thank you for your time and patience.

> 
> Best regards,
> Krzysztof
> 



From David.Laight at ACULAB.COM  Thu Dec  5 19:39:59 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 03:39:59 +0000
Subject: [PATCH 01/10] compiler.h: add statically_false()
In-Reply-To: <CAMZ6Rq+n0vG9zObF-kY-Xo+iP_Y3P8A6_nEfB8F=UhqeQBepRw@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-1-4e4cbaecc216@wanadoo.fr>
 <e115a4245e5342a994a7e596cc6357fa@AcuMS.aculab.com>
 <CAMZ6Rq+n0vG9zObF-kY-Xo+iP_Y3P8A6_nEfB8F=UhqeQBepRw@mail.gmail.com>
Message-ID: <b48e2f5dd8d64cbab471629ae03c7511@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 05 December 2024 15:26
> 
> On Thu. 5 Dec 2024 at 03:30, David Laight <David.Laight at aculab.com> wrote:
> > From: Vincent Mailhol
> > > Sent: 02 December 2024 17:33
> > >
> > > From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> > >
> > > For completion, add statically_false() which is the equivalent of
> > > statically_true() except that it will return true only if the input is
> > > known to be false at compile time.
> >
> > This is pretty much pointless.
> > It is just as easy to invert the condition at the call site.
> 
> To start with, I will argue that:
> 
>   statically_false(foo)
> 
> is more pretty than
> 
>   statically_true(!(foo))

Except that the test is more likely to be:
	statically_false(x > y)
and the invert is then
	statically_true(x <= y)

No different from C itself, there is no 'ifnot (condition) {...}'
(don't talk to me about perl...)

I suspect you need to pretty much remove all the comments that
cross-refer to statically_true() from the other patches.

So is_const_true() is just 'return true if the expression
is a 'non-zero constant integer expression'.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From anshuman.khandual at arm.com  Thu Dec  5 19:56:32 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 6 Dec 2024 09:26:32 +0530
Subject: [PATCH v2 4/4] arm64: add a new document for the fine-tuning tips
In-Reply-To: <20241126085647.4993-5-shijie@os.amperecomputing.com>
References: <20241126085647.4993-1-shijie@os.amperecomputing.com>
 <20241126085647.4993-5-shijie@os.amperecomputing.com>
Message-ID: <e48df345-0946-4b34-a463-e89aa89680f9@arm.com>

On 11/26/24 14:26, Huang Shijie wrote:
> Put some fine-tuning tips in this file:
> 	1.) rodata=noalias
> 	2.) slab_strict_numa
> 	3.) CONFIG_SCHED_CLUSTER
> 
> We can add more tips in future.
> 
> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
> ---
>  Documentation/arch/arm64/fine-tuning-tips.rst | 23 +++++++++++++++++++
>  Documentation/arch/arm64/index.rst            |  1 +
>  2 files changed, 24 insertions(+)
>  create mode 100644 Documentation/arch/arm64/fine-tuning-tips.rst
> 
> diff --git a/Documentation/arch/arm64/fine-tuning-tips.rst b/Documentation/arch/arm64/fine-tuning-tips.rst
> new file mode 100644
> index 000000000000..70ef1cef92fb
> --- /dev/null
> +++ b/Documentation/arch/arm64/fine-tuning-tips.rst
> @@ -0,0 +1,23 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +================
> +fine-tuning tips
> +================
> +
> +This file contains some fine-tuning tips for arm64 machines.
> +These tips do not gurantee that you can get better performance,
> +but you can try them with your workload.
> +
> +rodata=noalias
> +----------------
> +It can provide us more block mappings and contiguous hits
> +to map the linear region which minimizes the TLB footprint.
> +
> +slab_strict_numa
> +----------------
> +In NUMA, it will provide the local memory allocation by SLUB.
> +
> +CONFIG_SCHED_CLUSTER
> +----------------
> +Some arm64 machines have cpu core cluster, enable it may
> +helps you get better performance.
> diff --git a/Documentation/arch/arm64/index.rst b/Documentation/arch/arm64/index.rst
> index 6a012c98bdcd..36d1ef09bd71 100644
> --- a/Documentation/arch/arm64/index.rst
> +++ b/Documentation/arch/arm64/index.rst
> @@ -16,6 +16,7 @@ ARM64 Architecture
>      cpu-feature-registers
>      cpu-hotplug
>      elf_hwcaps
> +    fine-tuning-tips
>      gcs
>      hugetlbpage
>      kdump
Although the idea for such a file makes sense, to help system admins
tune the kernel command line for required behaviour, I am concerned
about the overall structure and scope for such a document. Should it
contain tips regarding all the subsystems on the platform, till what
extent these details should be described in there and then there are
so many aspects for a required behaviour etc ?

Besides maintaining such a document might also be very difficult as
well given how implementations will change over time thus requiring
different tuning etc. Hence kernel source might not be a place for
such a document.


From anshuman.khandual at arm.com  Thu Dec  5 20:21:09 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 6 Dec 2024 09:51:09 +0530
Subject: [PATCH v2 1/4] arm64: make rodata=on behaviour be the original
 rodata=full
In-Reply-To: <20241126085647.4993-2-shijie@os.amperecomputing.com>
References: <20241126085647.4993-1-shijie@os.amperecomputing.com>
 <20241126085647.4993-2-shijie@os.amperecomputing.com>
Message-ID: <f625af22-cb60-47d2-a775-e9fd273a8e7c@arm.com>



On 11/26/24 14:26, Huang Shijie wrote:
> Make rodata=on behaviour be the original rodata=full.
> After this patch, the rodata=on will be the default,
> and the arm64 kernel behaviour will follow the
> Documentation/admin-guide/kernel-parameters.txt:
> 	rodata=		[KNL,EARLY]
> 		on	Mark read-only kernel memory as read-only (default).
> 
> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
> ---
>  arch/arm64/include/asm/setup.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
> index ba269a7a3201..5ded3bd11476 100644
> --- a/arch/arm64/include/asm/setup.h
> +++ b/arch/arm64/include/asm/setup.h
> @@ -21,7 +21,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
>  	if (!arg)
>  		return false;
>  
> -	if (!strcmp(arg, "full")) {
> +	if (!strcmp(arg, "on")) {
>  		rodata_enabled = rodata_full = true;
>  		return true;
>  	}
> @@ -31,7 +31,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
>  		return true;
>  	}
>  
> -	if (!strcmp(arg, "on")) {
> +	if (!strcmp(arg, "full")) {
>  		rodata_enabled = true;
>  		rodata_full = false;
>  		return true;

After this patch we have the following and seems like 'rodata=full'
is temporarily broken until the subsequent patches come in ?

static inline bool arch_parse_debug_rodata(char *arg)
{
        extern bool rodata_enabled;
        extern bool rodata_full;

        if (!arg)
                return false;

        if (!strcmp(arg, "on")) {
                rodata_enabled = rodata_full = true;
                return true;
        }

        if (!strcmp(arg, "off")) {
                rodata_enabled = rodata_full = false;
                return true;
        }

        if (!strcmp(arg, "full")) {
                rodata_enabled = true;
                rodata_full = false;     <---------------- here
                return true;
        }

        return false;
}


From anshuman.khandual at arm.com  Thu Dec  5 20:29:27 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 6 Dec 2024 09:59:27 +0530
Subject: [PATCH v2 3/4] arm64: introduce rodata=noalias
In-Reply-To: <20241126085647.4993-4-shijie@os.amperecomputing.com>
References: <20241126085647.4993-1-shijie@os.amperecomputing.com>
 <20241126085647.4993-4-shijie@os.amperecomputing.com>
Message-ID: <03245d82-ad68-4ac2-a6f1-d8e4cc5397c3@arm.com>



On 11/26/24 14:26, Huang Shijie wrote:
> The rodata=noalias is the original rodata=on.
> 
> The rodata=noalias can provide us more block mappings and contiguous hits
> to map the linear region which minimize the TLB footprint. And the
> linear aliases of pages belonging to read-only mappings in vmalloc
> region are also marked as read-only.
> 
> Also update kernel-parameters.txt for it:
>    change "full" to "noalias"
> 
> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
> ---
>  Documentation/admin-guide/kernel-parameters.txt | 2 +-
>  arch/arm64/include/asm/setup.h                  | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index dc663c0ca670..54b4df42e631 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -5894,7 +5894,7 @@
>  	rodata=		[KNL,EARLY]
>  		on	Mark read-only kernel memory as read-only (default).
>  		off	Leave read-only kernel memory writable for debugging.
> -		full	Mark read-only kernel memory and aliases as read-only
> +		noalias	Use more block mappings,may have better performance.
>  		        [arm64]
>  
>  	rockchip.usb_uart
> diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
> index 5ded3bd11476..3d96dde4d214 100644
> --- a/arch/arm64/include/asm/setup.h
> +++ b/arch/arm64/include/asm/setup.h
> @@ -31,7 +31,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
>  		return true;
>  	}
>  
> -	if (!strcmp(arg, "full")) {
> +	if (!strcmp(arg, "noalias")) {
>  		rodata_enabled = true;
>  		rodata_full = false;
>  		return true;

This patch should be folded back into [PATCH 1/4] ensuring that

- "rodata=" processing gets updated completely i.e dropping 'full',
  adding new 'noalias' and also updating the documentation at once

- Avoids temporary the "full" option breakage as mentioned earlier

Also please do add in code comment above arch_parse_debug_rodata()
function explaining all the options after these update.


From anshuman.khandual at arm.com  Thu Dec  5 20:40:43 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 6 Dec 2024 10:10:43 +0530
Subject: [PATCH v2 2/4] arm64: remove CONFIG_RODATA_FULL_DEFAULT_ENABLED
In-Reply-To: <20241126085647.4993-3-shijie@os.amperecomputing.com>
References: <20241126085647.4993-1-shijie@os.amperecomputing.com>
 <20241126085647.4993-3-shijie@os.amperecomputing.com>
Message-ID: <c1f2ba9e-6f2d-4c7e-9956-6d3b183d3e05@arm.com>

On 11/26/24 14:26, Huang Shijie wrote:
> The default kernel is rodata=on which means

Right but this is true only after the update in the series.

        if (!strcmp(arg, "on")) {
                rodata_enabled = rodata_full = true;
                return true;
        }

rodata_full is always "true" via 'rodata=on' and does not depend
on the config RODATA_FULL_DEFAULT_ENABLED anymore, so it can be
dropped. Please update this commit message with these context as
well.

> CONFIG_RODATA_FULL_DEFAULT_ENABLED is always enabled by default.
> So we can remove CONFIG_RODATA_FULL_DEFAULT_ENABLED now.
> 
> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
> ---
>  arch/arm64/Kconfig       | 14 --------------
>  arch/arm64/mm/pageattr.c |  2 +-
>  2 files changed, 1 insertion(+), 15 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 4316b1fe8bf8..a9ca305a31d8 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1653,20 +1653,6 @@ config MITIGATE_SPECTRE_BRANCH_HISTORY
>  	  When taking an exception from user-space, a sequence of branches
>  	  or a firmware call overwrites the branch history.
>  
> -config RODATA_FULL_DEFAULT_ENABLED
> -	bool "Apply r/o permissions of VM areas also to their linear aliases"
> -	default y
> -	help
> -	  Apply read-only attributes of VM areas to the linear alias of
> -	  the backing pages as well. This prevents code or read-only data
> -	  from being modified (inadvertently or intentionally) via another
> -	  mapping of the same memory page. This additional enhancement can
> -	  be turned off at runtime by passing rodata=[off|on] (and turned on
> -	  with rodata=full if this option is set to 'n')
> -
> -	  This requires the linear region to be mapped down to pages,
> -	  which may adversely affect performance in some cases.
> -
>  config ARM64_SW_TTBR0_PAN
>  	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
>  	depends on !KCSAN
> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> index 39fd1f7ff02a..6eef08d8451e 100644
> --- a/arch/arm64/mm/pageattr.c
> +++ b/arch/arm64/mm/pageattr.c
> @@ -20,7 +20,7 @@ struct page_change_data {
>  	pgprot_t clear_mask;
>  };
>  
> -bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED);
> +bool rodata_full __ro_after_init = true;
>  
>  bool can_set_direct_map(void)
>  {

This patch can still follow the first one but after folding in the
third patch.


From eahariha at linux.microsoft.com  Thu Dec  5 21:13:32 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Thu, 5 Dec 2024 21:13:32 -0800
Subject: [PATCH v3 4/5] hyperv: Switch from hyperv-tlfs.h to
 hyperv/hvhdk.h
In-Reply-To: <1732577084-2122-5-git-send-email-nunodasneves@linux.microsoft.com>
References: <1732577084-2122-1-git-send-email-nunodasneves@linux.microsoft.com>
 <1732577084-2122-5-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <34cd1209-f9d3-4cdf-b7c1-7028a9abe46c@linux.microsoft.com>

On 11/25/2024 3:24 PM, Nuno Das Neves wrote:
> Switch to using hvhdk.h everywhere in the kernel. This header
> includes all the new Hyper-V headers in include/hyperv, which form a
> superset of the definitions found in hyperv-tlfs.h.
> 
> This makes it easier to add new Hyper-V interfaces without being
> restricted to those in the TLFS doc (reflected in hyperv-tlfs.h).
> 
> To be more consistent with the original Hyper-V code, the names of
> some definitions are changed slightly. Update those where needed.
> 
> Update comments in mshyperv.h files to point to include/hyperv for
> adding new definitions.
> 
> Signed-off-by: Nuno Das Neves <nunodasneves at linux.microsoft.com>
> ---
>  arch/arm64/hyperv/hv_core.c        |  2 +-
>  arch/arm64/hyperv/mshyperv.c       |  4 ++--
>  arch/arm64/include/asm/mshyperv.h  |  7 +++----
>  arch/x86/hyperv/hv_init.c          | 20 ++++++++++----------
>  arch/x86/hyperv/hv_proc.c          |  2 +-
>  arch/x86/hyperv/nested.c           |  2 +-
>  arch/x86/include/asm/kvm_host.h    |  2 +-
>  arch/x86/include/asm/mshyperv.h    |  2 +-
>  arch/x86/include/asm/svm.h         |  2 +-
>  arch/x86/kernel/cpu/mshyperv.c     |  2 +-
>  arch/x86/kvm/vmx/hyperv_evmcs.h    |  2 +-
>  arch/x86/kvm/vmx/vmx_onhyperv.h    |  2 +-
>  drivers/clocksource/hyperv_timer.c |  2 +-
>  drivers/hv/hv_balloon.c            |  4 ++--
>  drivers/hv/hv_common.c             |  2 +-
>  drivers/hv/hv_kvp.c                |  2 +-
>  drivers/hv/hv_snapshot.c           |  2 +-
>  drivers/hv/hyperv_vmbus.h          |  2 +-
>  include/asm-generic/mshyperv.h     |  7 +++----
>  include/clocksource/hyperv_timer.h |  2 +-
>  include/linux/hyperv.h             |  2 +-
>  net/vmw_vsock/hyperv_transport.c   |  6 +++---
>  22 files changed, 39 insertions(+), 41 deletions(-)

Reviewed-by: Easwar Hariharan <eahariha at linux.microsoft.com>


From eahariha at linux.microsoft.com  Thu Dec  5 21:12:56 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Thu, 5 Dec 2024 21:12:56 -0800
Subject: [PATCH v3 3/5] hyperv: Add new Hyper-V headers in include/hyperv
In-Reply-To: <1732577084-2122-4-git-send-email-nunodasneves@linux.microsoft.com>
References: <1732577084-2122-1-git-send-email-nunodasneves@linux.microsoft.com>
 <1732577084-2122-4-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <3c5ec65e-93a9-48a2-a18f-f5b89e83e999@linux.microsoft.com>

On 11/25/2024 3:24 PM, Nuno Das Neves wrote:
> These headers contain definitions for regular Hyper-V guests (as in
> hyperv-tlfs.h), as well as interfaces for more privileged guests like
> the root partition (aka Dom0).
> 
> These files are derived from headers exported from Hyper-V, rather than
> being derived from the TLFS document. (Although, to preserve
> compatibility with existing Linux code, some definitions are copied
> directly from hyperv-tlfs.h too).
> 
> The new files follow a naming convention according to their original
> use:
> - hdk "host development kit"
> - gdk "guest development kit"
> With postfix "_mini" implying userspace-only headers, and "_ext" for
> extended hypercalls.
> 
> The use of multiple files and their original names is primarily to
> keep the provenance of exactly where they came from in Hyper-V
> code, which is helpful for manual maintenance and extension
> of these definitions. Microsoft maintainers importing new definitions
> should take care to put them in the right file. However, Linux kernel
> code that uses any of the definitions need not be aware of the multiple
> files or assign any meaning to the new names. Linux kernel code should
> always just include hvhdk.h
> 
> Note the new headers contain both arm64 and x86_64 definitions. Some are
> guarded by #ifdefs, and some are instead prefixed with the architecture,
> e.g. hv_x64_*. These conventions are kept from Hyper-V code as another
> tactic to simplify the process of importing and maintaining the
> definitions, rather than splitting them up into their own files in
> arch/x86/ and arch/arm64/.
> 
> These headers are a step toward importing headers directly from Hyper-V
> in the future, similar to Xen public files in include/xen/interface/.
> 
> Signed-off-by: Nuno Das Neves <nunodasneves at linux.microsoft.com>
> ---
>  MAINTAINERS                 |    5 +
>  include/hyperv/hvgdk.h      |  308 +++++++++
>  include/hyperv/hvgdk_ext.h  |   46 ++
>  include/hyperv/hvgdk_mini.h | 1306 +++++++++++++++++++++++++++++++++++
>  include/hyperv/hvhdk.h      |  733 ++++++++++++++++++++
>  include/hyperv/hvhdk_mini.h |  311 +++++++++
>  6 files changed, 2709 insertions(+)
>  create mode 100644 include/hyperv/hvgdk.h
>  create mode 100644 include/hyperv/hvgdk_ext.h
>  create mode 100644 include/hyperv/hvgdk_mini.h
>  create mode 100644 include/hyperv/hvhdk.h
>  create mode 100644 include/hyperv/hvhdk_mini.h

Reviewed-by: Easwar Hariharan <eahariha at linux.microsoft.com>


From eahariha at linux.microsoft.com  Thu Dec  5 21:14:40 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Thu, 5 Dec 2024 21:14:40 -0800
Subject: [PATCH v3 5/5] hyperv: Remove the now unused hyperv-tlfs.h files
In-Reply-To: <1732577084-2122-6-git-send-email-nunodasneves@linux.microsoft.com>
References: <1732577084-2122-1-git-send-email-nunodasneves@linux.microsoft.com>
 <1732577084-2122-6-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <92399e62-e07b-48eb-9a96-9747ad5b6eb7@linux.microsoft.com>

On 11/25/2024 3:24 PM, Nuno Das Neves wrote:
> Remove all hyperv-tlfs.h files. These are no longer included
> anywhere. hyperv/hvhdk.h serves the same role, but with an easier
> path for adding new definitions.
> 
> Remove the relevant lines in MAINTAINERS.
> 
> Signed-off-by: Nuno Das Neves <nunodasneves at linux.microsoft.com>
> ---
>  MAINTAINERS                          |   3 -
>  arch/arm64/include/asm/hyperv-tlfs.h |  71 ---
>  arch/x86/include/asm/hyperv-tlfs.h   | 811 ------------------------
>  include/asm-generic/hyperv-tlfs.h    | 883 ---------------------------
>  4 files changed, 1768 deletions(-)
>  delete mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
>  delete mode 100644 arch/x86/include/asm/hyperv-tlfs.h
>  delete mode 100644 include/asm-generic/hyperv-tlfs.h
> 

Reviewed-by: Easwar Hariharan <eahariha at linux.microsoft.com>


From shijie at amperemail.onmicrosoft.com  Thu Dec  5 21:50:55 2024
From: shijie at amperemail.onmicrosoft.com (Shijie Huang)
Date: Fri, 6 Dec 2024 13:50:55 +0800
Subject: [PATCH v2 3/4] arm64: introduce rodata=noalias
In-Reply-To: <03245d82-ad68-4ac2-a6f1-d8e4cc5397c3@arm.com>
References: <20241126085647.4993-1-shijie@os.amperecomputing.com>
 <20241126085647.4993-4-shijie@os.amperecomputing.com>
 <03245d82-ad68-4ac2-a6f1-d8e4cc5397c3@arm.com>
Message-ID: <31d523f8-9160-44ba-86d9-e7dade2fa622@amperemail.onmicrosoft.com>


On 2024/12/6 12:29, Anshuman Khandual wrote:
>
> On 11/26/24 14:26, Huang Shijie wrote:
>> The rodata=noalias is the original rodata=on.
>>
>> The rodata=noalias can provide us more block mappings and contiguous hits
>> to map the linear region which minimize the TLB footprint. And the
>> linear aliases of pages belonging to read-only mappings in vmalloc
>> region are also marked as read-only.
>>
>> Also update kernel-parameters.txt for it:
>>     change "full" to "noalias"
>>
>> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
>> ---
>>   Documentation/admin-guide/kernel-parameters.txt | 2 +-
>>   arch/arm64/include/asm/setup.h                  | 2 +-
>>   2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
>> index dc663c0ca670..54b4df42e631 100644
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -5894,7 +5894,7 @@
>>   	rodata=		[KNL,EARLY]
>>   		on	Mark read-only kernel memory as read-only (default).
>>   		off	Leave read-only kernel memory writable for debugging.
>> -		full	Mark read-only kernel memory and aliases as read-only
>> +		noalias	Use more block mappings,may have better performance.
>>   		        [arm64]
>>   
>>   	rockchip.usb_uart
>> diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
>> index 5ded3bd11476..3d96dde4d214 100644
>> --- a/arch/arm64/include/asm/setup.h
>> +++ b/arch/arm64/include/asm/setup.h
>> @@ -31,7 +31,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
>>   		return true;
>>   	}
>>   
>> -	if (!strcmp(arg, "full")) {
>> +	if (!strcmp(arg, "noalias")) {
>>   		rodata_enabled = true;
>>   		rodata_full = false;
>>   		return true;
> This patch should be folded back into [PATCH 1/4] ensuring that
Thanks, I will do it in next version.
>
> - "rodata=" processing gets updated completely i.e dropping 'full',
>    adding new 'noalias' and also updating the documentation at once
>
> - Avoids temporary the "full" option breakage as mentioned earlier
>
> Also please do add in code comment above arch_parse_debug_rodata()
> function explaining all the options after these update.

No problem.


Thanks

Huang Shijie



From cwweng.linux at gmail.com  Thu Dec  5 21:56:11 2024
From: cwweng.linux at gmail.com (Chi-Wen Weng)
Date: Fri, 6 Dec 2024 13:56:11 +0800
Subject: [PATCH RESEND v2 2/2] pwm: Add Nuvoton MA35D1 PWM controller
 support
In-Reply-To: <5a6ad0dc-f777-4129-962f-e10a0f7d6ee1@baylibre.com>
References: <20241024104309.169510-1-cwweng.linux@gmail.com>
 <20241024104309.169510-3-cwweng.linux@gmail.com>
 <5a6ad0dc-f777-4129-962f-e10a0f7d6ee1@baylibre.com>
Message-ID: <6f1d42d7-1554-4545-b09d-8432e033a96e@gmail.com>

Hi Trevor,

Thanks for your suggestions.


On 2024/11/21 ?? 12:49, Trevor Gamblin wrote:
> Hello,
>
> On 2024-10-24 06:43, Chi-Wen Weng wrote:
>> This commit adds a generic PWM framework driver for Nuvoton MA35D1
>> PWM controller.
>>
>> Signed-off-by: Chi-Wen Weng <cwweng.linux at gmail.com>
>> ---
>> ? drivers/pwm/Kconfig????? |?? 9 +++
>> ? drivers/pwm/Makefile???? |?? 1 +
>> ? drivers/pwm/pwm-ma35d1.c | 169 +++++++++++++++++++++++++++++++++++++++
>> ? 3 files changed, 179 insertions(+)
>> ? create mode 100644 drivers/pwm/pwm-ma35d1.c
> I don't see a MAINTAINERS entry? That needs to be added in the 
> bindings patch first, and then it should be updated to list this 
> driver file.
>>
>> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
>> index 0915c1e7df16..97b9e83af020 100644
>> --- a/drivers/pwm/Kconfig
>> +++ b/drivers/pwm/Kconfig
>> @@ -411,6 +411,15 @@ config PWM_LPSS_PLATFORM
>> ??????? To compile this driver as a module, choose M here: the module
>> ??????? will be called pwm-lpss-platform.
>> ? +config PWM_MA35D1
>> +??? tristate "Nuvoton MA35D1 PWM support"
>> +??? depends on ARCH_MA35 || COMPILE_TEST
>> +??? help
>> +????? Generic PWM framework driver for Nuvoton MA35D1.
>> +
>> +????? To compile this driver as a module, choose M here: the module
>> +????? will be called pwm-ma35d1.
>> +
>> ? config PWM_MESON
>> ????? tristate "Amlogic Meson PWM driver"
>> ????? depends on ARCH_MESON || COMPILE_TEST
>> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
>> index 9081e0c0e9e0..c1d3a1d8add0 100644
>> --- a/drivers/pwm/Makefile
>> +++ b/drivers/pwm/Makefile
>> @@ -36,6 +36,7 @@ obj-$(CONFIG_PWM_LPC32XX)??? += pwm-lpc32xx.o
>> ? obj-$(CONFIG_PWM_LPSS)??????? += pwm-lpss.o
>> ? obj-$(CONFIG_PWM_LPSS_PCI)??? += pwm-lpss-pci.o
>> ? obj-$(CONFIG_PWM_LPSS_PLATFORM)??? += pwm-lpss-platform.o
>> +obj-$(CONFIG_PWM_MA35D1)??? += pwm-ma35d1.o
>> ? obj-$(CONFIG_PWM_MESON)??????? += pwm-meson.o
>> ? obj-$(CONFIG_PWM_MEDIATEK)??? += pwm-mediatek.o
>> ? obj-$(CONFIG_PWM_MICROCHIP_CORE)??? += pwm-microchip-core.o
>> diff --git a/drivers/pwm/pwm-ma35d1.c b/drivers/pwm/pwm-ma35d1.c
>> new file mode 100644
>> index 000000000000..0c4eec4a0b07
>> --- /dev/null
>> +++ b/drivers/pwm/pwm-ma35d1.c
>> @@ -0,0 +1,169 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Driver for the Nuvoton MA35D1 PWM controller
>> + *
>> + * Copyright (C) 2024 Nuvoton Corporation
>> + *?????????????? Chi-Wen Weng <cwweng at nuvoton.com>
>> + */
>> +
>> +#include <linux/mod_devicetable.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pwm.h>
>> +#include <linux/io.h>
>> +#include <linux/clk.h>
>> +#include <linux/math64.h>
> These should be organized alphabetically.
>> +
>> +/* The following are registers for PWM controller */
>> +#define REG_PWM_CTL0??????????? (0x00)
>> +#define REG_PWM_CNTEN?????????? (0x20)
>> +#define REG_PWM_PERIOD0???????? (0x30)
>> +#define REG_PWM_CMPDAT0???????? (0x50)
>> +#define REG_PWM_WGCTL0????????? (0xB0)
>> +#define REG_PWM_POLCTL????????? (0xD4)
>> +#define REG_PWM_POEN??????????? (0xD8)
>
> These too, I think - it will make it more readable for others.
>
> You should also prefix all of your macros to be more explicit about 
> their use, e.g. MA35D1_REG_PWM_CTL0. That way it's clearer that 
> they're specific to this driver and not from elsewhere.
>
>> +
>> +#define PWM_TOTAL_CHANNELS????? 6
>> +#define PWM_CH_REG_SIZE???????? 4
> And these.
>> +
>> +struct nuvoton_pwm {
>> +??? void __iomem *base;
>> +??? u64 clkrate;
>> +};
>> +
>> +static inline struct nuvoton_pwm *to_nuvoton_pwm(struct pwm_chip *chip)
>> +{
>> +??? return pwmchip_get_drvdata(chip);
>> +}
>> +
>> +static int nuvoton_pwm_apply(struct pwm_chip *chip, struct 
>> pwm_device *pwm,
>> +???????????????? const struct pwm_state *state)
>> +{
>> +??? struct nuvoton_pwm *nvtpwm;
>> +??? unsigned int ch = pwm->hwpwm;
>> +
>> +??? nvtpwm = to_nuvoton_pwm(chip);
>> +??? if (state->enabled) {
>> +??????? u64 duty_cycles, period_cycles;
>> +
>> +??????? /* Calculate the duty and period cycles */
>> +??????? duty_cycles = mul_u64_u64_div_u64(nvtpwm->clkrate,
>> +????????????????????????? state->duty_cycle, NSEC_PER_SEC);
>> +??????? if (duty_cycles > 0xFFFF)
>> +??????????? duty_cycles = 0xFFFF;
> It would be good to create a macro for this value 0xFFFF, e.g. 
> MA35D1_MAX_PWM_RATE.
>> +
>> +??????? period_cycles = mul_u64_u64_div_u64(nvtpwm->clkrate,
>> +??????????????????????????? state->period, NSEC_PER_SEC);
>> +??????? if (period_cycles > 0xFFFF)
>> +??????????? period_cycles = 0xFFFF;
>> +
>> +??????? /* Write the duty and period cycles to registers */
>> +??????? writel(duty_cycles, nvtpwm->base + REG_PWM_CMPDAT0 + (ch * 
>> PWM_CH_REG_SIZE));
>> +??????? writel(period_cycles, nvtpwm->base + REG_PWM_PERIOD0 + (ch * 
>> PWM_CH_REG_SIZE));
>
> Since you are using things like
>
> nvtpwm->base + REG_PWM_CMPDAT0 + (ch * PWM_CH_REG_SIZE)
>
> and similar so frequently, I suggest creating more macros for these 
> sorts of accesses to improve readability, e.g.
>
> #define MA35D1_PWM_CMPDAT0_ADDR(base, ch)???? base + REG_PWM_CMPDAT0 + 
> (ch * PWM_CH_REG_SIZE));
>
> or even
>
> #define MA35D1_PWM_CMPDAT0_ADDR(nvtpwm, ch)???? nvtpwm->base + 
> REG_PWM_CMPDAT0 + (ch * PWM_CH_REG_SIZE));
>
> and then use those instead.
>
>> +??????? /* Enable counter */
>> +??????? writel(readl(nvtpwm->base + REG_PWM_CNTEN) | BIT(ch),
>> +?????????????? nvtpwm->base + REG_PWM_CNTEN);
> Same for cases like this.
>> +??????? /* Enable output */
>> +??????? writel(readl(nvtpwm->base + REG_PWM_POEN) | BIT(ch),
>> +?????????????? nvtpwm->base + REG_PWM_POEN);
>> +??? } else {
>> +??????? /* Disable counter */
>> +??????? writel(readl(nvtpwm->base + REG_PWM_CNTEN) & ~BIT(ch),
>> +?????????????? nvtpwm->base + REG_PWM_CNTEN);
>> +??????? /* Disable output */
>> +??????? writel(readl(nvtpwm->base + REG_PWM_POEN) & ~BIT(ch),
>> +?????????????? nvtpwm->base + REG_PWM_POEN);
>> +??? }
>> +
>> +??? /* Set polarity state to register */
>> +??? if (state->polarity == PWM_POLARITY_NORMAL)
>> +??????? writel(readl(nvtpwm->base + REG_PWM_POLCTL) & ~BIT(ch),
>> +?????????????? nvtpwm->base + REG_PWM_POLCTL);
>> +??? else
>> +??????? writel(readl(nvtpwm->base + REG_PWM_POLCTL) | BIT(ch),
>> +?????????????? nvtpwm->base + REG_PWM_POLCTL);
>> +
>> +??? return 0;
>> +}
>> +
>> +static int nuvoton_pwm_get_state(struct pwm_chip *chip, struct 
>> pwm_device *pwm,
>> +???????????????? struct pwm_state *state)
>> +{
>> +??? struct nuvoton_pwm *nvtpwm;
>> +??? unsigned int duty_cycles, period_cycles, cnten, outen, polarity;
>> +??? unsigned int ch = pwm->hwpwm;
>> +
>> +??? nvtpwm = to_nuvoton_pwm(chip);
>> +
>> +??? cnten = readl(nvtpwm->base + REG_PWM_CNTEN);
>> +??? outen = readl(nvtpwm->base + REG_PWM_POEN);
>> +??? duty_cycles = readl(nvtpwm->base + REG_PWM_CMPDAT0 + (ch * 
>> PWM_CH_REG_SIZE));
>> +??? period_cycles = readl(nvtpwm->base + REG_PWM_PERIOD0 + (ch * 
>> PWM_CH_REG_SIZE));
>> +??? polarity = readl(nvtpwm->base + REG_PWM_POLCTL) & BIT(ch);
>> +
>> +??? state->enabled = (cnten & BIT(ch)) && (outen & BIT(ch));
>> +??? state->polarity = polarity ? PWM_POLARITY_INVERSED : 
>> PWM_POLARITY_NORMAL;
>> +??? state->duty_cycle = DIV64_U64_ROUND_UP((u64)duty_cycles * 
>> NSEC_PER_SEC, nvtpwm->clkrate);
>> +??? state->period = DIV64_U64_ROUND_UP((u64)period_cycles * 
>> NSEC_PER_SEC, nvtpwm->clkrate);
>> +
>> +??? return 0;
>> +}
>> +
>> +static const struct pwm_ops nuvoton_pwm_ops = {
>> +??? .apply = nuvoton_pwm_apply,
>> +??? .get_state = nuvoton_pwm_get_state,
>> +};
>> +
>> +static int nuvoton_pwm_probe(struct platform_device *pdev)
>> +{
>> +??? struct pwm_chip *chip;
>> +??? struct nuvoton_pwm *nvtpwm;
>> +??? struct clk *clk;
>> +??? int ret;
>> +
>> +??? chip = devm_pwmchip_alloc(&pdev->dev, PWM_TOTAL_CHANNELS, 
>> sizeof(*nvtpwm));
>> +??? if (IS_ERR(chip))
>> +??????? return PTR_ERR(chip);
>> +
>> +??? nvtpwm = to_nuvoton_pwm(chip);
>> +
>> +??? nvtpwm->base = devm_platform_ioremap_resource(pdev, 0);
>> +??? if (IS_ERR(nvtpwm->base))
>> +??????? return PTR_ERR(nvtpwm->base);
>> +
>> +??? clk = devm_clk_get_enabled(&pdev->dev, NULL);
>> +??? if (IS_ERR(clk))
>> +??????? return dev_err_probe(&pdev->dev, PTR_ERR(clk), "unable to 
>> get the clock");
>> +
>> +??? nvtpwm->clkrate = clk_get_rate(clk);
>> +??? if (nvtpwm->clkrate > NSEC_PER_SEC)
>> +??????? return dev_err_probe(&pdev->dev, -EINVAL, "pwm clock out of 
>> range");
>> +
>> +??? chip->ops = &nuvoton_pwm_ops;
>> +??? chip->atomic = true;
>> +
>> +??? ret = devm_pwmchip_add(&pdev->dev, chip);
>> +??? if (ret < 0)
>> +??????? return dev_err_probe(&pdev->dev, ret, "unable to add pwm 
>> chip");
>> +
>> +??? return 0;
>> +}
>
> As a final note, please be aware that there is a change to the PWM 
> subsystem coming in 6.13. You don't need to do anything now, but it's 
> worth considering how the driver might change once that hits mainline.
>
> You can find the changes here: 
> https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git/log/?h=pwm/duty_offset 
> .
>
>> +
>> +static const struct of_device_id nuvoton_pwm_of_match[] = {
>> +??? { .compatible = "nuvoton,ma35d1-pwm" },
>> +??? {}
>> +};
>> +MODULE_DEVICE_TABLE(of, nuvoton_pwm_of_match);
>> +
>> +static struct platform_driver nuvoton_pwm_driver = {
>> +??? .probe = nuvoton_pwm_probe,
>> +??? .driver = {
>> +??????? .name = "nuvoton-pwm",
>> +??????? .of_match_table = nuvoton_pwm_of_match,
>> +??? },
>> +};
>> +module_platform_driver(nuvoton_pwm_driver);
>> +
>> +MODULE_AUTHOR("Chi-Wen Weng <cwweng at nuvoton.com>");
>> +MODULE_DESCRIPTION("Nuvoton MA35D1 PWM driver");
>> +MODULE_LICENSE("GPL");

Per Uwe's commet, I will keep the registers in address order.

Otherwise I will modify in next version.


Thanks.

Chi-Wen Weng




From cwweng.linux at gmail.com  Thu Dec  5 21:58:45 2024
From: cwweng.linux at gmail.com (Chi-Wen Weng)
Date: Fri, 6 Dec 2024 13:58:45 +0800
Subject: [PATCH RESEND v2 2/2] pwm: Add Nuvoton MA35D1 PWM controller
 support
In-Reply-To: <fllw3dv6juj2vepsnrb4lajh2j7b42jl6rzncmvt57gfaalgiv@sypw55h54oag>
References: <20241024104309.169510-1-cwweng.linux@gmail.com>
 <20241024104309.169510-3-cwweng.linux@gmail.com>
 <5a6ad0dc-f777-4129-962f-e10a0f7d6ee1@baylibre.com>
 <fllw3dv6juj2vepsnrb4lajh2j7b42jl6rzncmvt57gfaalgiv@sypw55h54oag>
Message-ID: <57648ce7-7c43-4ac5-81d9-35e8a624df22@gmail.com>

Hi Uwe,

Thanks for your comments.


On 2024/11/21 ?? 06:03, Uwe Kleine-K?nig wrote:
> hello,
>
> On Wed, Nov 20, 2024 at 11:49:48AM -0500, Trevor Gamblin wrote:
>> On 2024-10-24 06:43, Chi-Wen Weng wrote:
>>> +#include <linux/mod_devicetable.h>
>>> +#include <linux/module.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/pwm.h>
>>> +#include <linux/io.h>
>>> +#include <linux/clk.h>
>>> +#include <linux/math64.h>
>> These should be organized alphabetically.
>>> +
>>> +/* The following are registers for PWM controller */
>>> +#define REG_PWM_CTL0            (0x00)
>>> +#define REG_PWM_CNTEN           (0x20)
>>> +#define REG_PWM_PERIOD0         (0x30)
>>> +#define REG_PWM_CMPDAT0         (0x50)
>>> +#define REG_PWM_WGCTL0          (0xB0)
>>> +#define REG_PWM_POLCTL          (0xD4)
>>> +#define REG_PWM_POEN            (0xD8)
>> These too, I think - it will make it more readable for others.
> Keeping the registers in address order is the usual thing to do, so
> please keep the order of these.
>
> Otherwise I agree to Trevor's comments. Thanks for taking the time to
> look at this patch.
>
> Best regards
> Uwe


I will keep the registers in address order.

Otherwise I will modify per Trevor's suggestions .


Thanks.

Chi-Wen Weng



From shijie at amperemail.onmicrosoft.com  Thu Dec  5 22:14:26 2024
From: shijie at amperemail.onmicrosoft.com (Shijie Huang)
Date: Fri, 6 Dec 2024 14:14:26 +0800
Subject: [PATCH v2 4/4] arm64: add a new document for the fine-tuning tips
In-Reply-To: <e48df345-0946-4b34-a463-e89aa89680f9@arm.com>
References: <20241126085647.4993-1-shijie@os.amperecomputing.com>
 <20241126085647.4993-5-shijie@os.amperecomputing.com>
 <e48df345-0946-4b34-a463-e89aa89680f9@arm.com>
Message-ID: <e7cbafd4-506b-4e26-ad88-e1afba06e972@amperemail.onmicrosoft.com>


On 2024/12/6 11:56, Anshuman Khandual wrote:
> On 11/26/24 14:26, Huang Shijie wrote:
>> Put some fine-tuning tips in this file:
>> 	1.) rodata=noalias
>> 	2.) slab_strict_numa
>> 	3.) CONFIG_SCHED_CLUSTER
>>
>> We can add more tips in future.
>>
>> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
>> ---
>>   Documentation/arch/arm64/fine-tuning-tips.rst | 23 +++++++++++++++++++
>>   Documentation/arch/arm64/index.rst            |  1 +
>>   2 files changed, 24 insertions(+)
>>   create mode 100644 Documentation/arch/arm64/fine-tuning-tips.rst
>>
>> diff --git a/Documentation/arch/arm64/fine-tuning-tips.rst b/Documentation/arch/arm64/fine-tuning-tips.rst
>> new file mode 100644
>> index 000000000000..70ef1cef92fb
>> --- /dev/null
>> +++ b/Documentation/arch/arm64/fine-tuning-tips.rst
>> @@ -0,0 +1,23 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +
>> +================
>> +fine-tuning tips
>> +================
>> +
>> +This file contains some fine-tuning tips for arm64 machines.
>> +These tips do not gurantee that you can get better performance,
>> +but you can try them with your workload.
>> +
>> +rodata=noalias
>> +----------------
>> +It can provide us more block mappings and contiguous hits
>> +to map the linear region which minimizes the TLB footprint.
>> +
>> +slab_strict_numa
>> +----------------
>> +In NUMA, it will provide the local memory allocation by SLUB.
>> +
>> +CONFIG_SCHED_CLUSTER
>> +----------------
>> +Some arm64 machines have cpu core cluster, enable it may
>> +helps you get better performance.
>> diff --git a/Documentation/arch/arm64/index.rst b/Documentation/arch/arm64/index.rst
>> index 6a012c98bdcd..36d1ef09bd71 100644
>> --- a/Documentation/arch/arm64/index.rst
>> +++ b/Documentation/arch/arm64/index.rst
>> @@ -16,6 +16,7 @@ ARM64 Architecture
>>       cpu-feature-registers
>>       cpu-hotplug
>>       elf_hwcaps
>> +    fine-tuning-tips
>>       gcs
>>       hugetlbpage
>>       kdump
> Although the idea for such a file makes sense, to help system admins
> tune the kernel command line for required behaviour, I am concerned
This file also contains the CONFIG_SCHED_CLUSTER which is not a kernel 
command line.
> about the overall structure and scope for such a document. Should it
> contain tips regarding all the subsystems on the platform, till what
> extent these details should be described in there and then there are
> so many aspects for a required behaviour etc ?

My original thought is to let this file contains the tips only works in 
arm64.

All the tips which _may_ make the arm64 machines get better performance 
can be

recorded here.

Then the arm64 kernel engineers(the newbies) can follow this file, and 
ramp up

quickly.


>
> Besides maintaining such a document might also be very difficult as
> well given how implementations will change over time thus requiring
> different tuning etc. Hence kernel source might not be a place for
> such a document.

okay. If the kernel source is not the right place, I can remove this 
patch in next version.


Thanks

Huang Shijie



From torvalds at linux-foundation.org  Thu Dec  5 22:14:36 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Thu, 5 Dec 2024 22:14:36 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
Message-ID: <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>

On Thu, 5 Dec 2024 at 18:26, David Laight <David.Laight at aculab.com> wrote:
>
> From: Vincent Mailhol
> > ACK. Would adding a suggested--by Linus tag solve your concern?

I'm genberally the one person who doesn't need any more credit ;)

> I actually suspect the first patches to change __is_constexpr() to
> use _Generic were from myself.

Yes. And David was also I think the one who suggested something else
than "!!" originally too.

I may have liked "!!" for being very idiomatic and traditional C, but
there were those pesky compilers that warn about "integer in bool
context" or whatever the annoying warning was when then doing the
"multiply by zero" to turn a constant expression into a constant zero
expression.

So that

  #define is_const(x) __is_const_zero(0 * (x))

causes issues when 'x' is not an integer expression (think
"is_const(NULL)" or "is_const(1 == 2)".

Side note: I think "(x) == 0" will make sparse unhappy when 'x' is a
pointer, because it results that horrid "use integer zero as NULL
without a cast" thing when the plain zero gets implicitly cast to a
pointer. Which is a really nasty and broken C pattern and should never
have been silent.

I think David suggested using ((x)?0:0) at some point. Silly
nonsensical and complex expression, but maybe that finally gets rid of
all the warnings:

     #define is_const(x) __is_const_zero((x)?0:0)

might work regardless of the type of 'x'.

Or does that trigger some odd case too?

            Linus


From muecker at gwdg.de  Thu Dec  5 22:40:17 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Fri, 6 Dec 2024 07:40:17 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
Message-ID: <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>

Am Freitag, dem 06.12.2024 um 02:25 +0000 schrieb David Laight:
> From: Vincent Mailhol
> > Sent: 05 December 2024 15:31
> > 
> > -CC: Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
> > +CC: Martin Uecker <muecker at gwdg.de>
> > (seems that Martin changed his address)

My current one is this: uecker at tugraz.at

Martin

> > 
> > On Thu. 5 Dec. 2024 at 03:39, David Laight <David.Laight at aculab.com> wrote:
> > > > Sent: 02 December 2024 17:33
> > > > 
> > > > From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> > > > 
> > > > __is_constexpr(), while being one of the most glorious one liner hack
> > > > ever witnessed by mankind, is overly complex. Following the adoption
> > > > of C11 in the kernel, this macro can be simplified through the use of
> > > > a _Generic() selection.
> > > 
> > > You should give credit to some of the earlier patches that do the same.
> > > I'm sure there were some related ones from Linus - not applied yet.
> > 
> > ACK. Would adding a suggested--by Linus tag solve your concern?
> 
> I actually suspect the first patches to change __is_constexpr() to
> use _Generic were from myself.
> I've found a patch I send in November 2023.
> 
> > 
> > > > First, split the macro in two:
> > > > 
> > > >   - __is_const_zero(x): an helper macro; tells whether x is the
> > > >     integer constant expression 0 or something else.
> > > > 
> > > >   - is_const(x): replacement of __is_constexpr(); tells whether x is a
> > > >     integer constant expression.
> > > > 
> > > > The split serves two purposes: first make it easier to understand;
> > > > second, __is_const_zero() will be reused as a building block for other
> > > > is_const_*() macros that will be introduced later on.
> > > > 
> > > > The core principle of __is_constexpr() to abuse the return type of the
> > > > ternary operator remains, but all the surrounding sizeof() hack
> > > > disappear.
> > > > 
> > > > On a side note, while not relevant to the kernel, __is_constexpr()
> > > > relied on the GNU extension that sizeof(void) is 1. const_expr() does
> > > > not use any GNU extensions, making it ISO C compliant.
> > > > 
> > > > __is_constexpr() is temporarily kept and will be removed once all its
> > > > users get migrated to is_const() (or one of its friend).
> > > > 
> > > > Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> > > > ---
> > > >  include/linux/compiler.h | 41 +++++++++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 41 insertions(+)
> > > > 
> > > > diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> > > > index a2a56a50dd85227a4fdc62236a2710ca37c5ba52..30ce06df4153cfdc0fad9bc7bffab9097f8b0450 100644
> > > > --- a/include/linux/compiler.h
> > > > +++ b/include/linux/compiler.h
> > > > @@ -316,6 +316,47 @@ static inline void *offset_to_ptr(const int *off)
> > > >  #define statically_true(x) (__builtin_constant_p(x) && (x))
> > > >  #define statically_false(x) (__builtin_constant_p(x) && (x) == 0)
> > > > 
> > > > +/*
> > > > + * Whether x is the integer constant expression 0 or something else.
> > > > + *
> > > > + * Details:
> > > > + *   - The C11 standard defines in ?6.3.2.3.3
> > > > + *       (void *)<integer constant expression with the value 0>
> > > > + *     as a null pointer constant (c.f. the NULL macro).
> > > > + *   - If x evaluates to the integer constant expression 0,
> > > > + *       (void *)(x)
> > > > + *     is a null pointer constant. Else, it is a void * expression.
> > > > + *   - In a ternary expression:
> > > > + *       condition ? operand1 : operand2
> > > > + *     if one of the two operands is of type void * and the other one
> > > > + *     some other pointer type, the C11 standard defines in ?6.5.15.6
> > > > + *     the resulting type as below:
> > > > + *       if one operand is a null pointer constant, the result has the
> > > > + *       type of the other operand; otherwise [...] the result type is
> > > > + *       a pointer to an appropriately qualified version of void.
> > > > + *   - As such, in
> > > > + *       0 ? (void *)(x) : (char *)0
> > > > + *     if x is the integer constant expression 0, operand1 is a null
> > > > + *     pointer constant and the resulting type is that of operand2:
> > > > + *     char *. If x is anything else, the type is void *.
> > > > + *   - The (long) cast silences a compiler warning for when x is not 0.
> > > > + *   - Finally, the _Generic() dispatches the resulting type into a
> > > > + *     Boolean.
> > > 
> > > The comment is absolutely excessive.
> > > I'm sure I managed about 2 lines in one of the patches I did.
> > 
> > I think that Linus made it  clear in:
> > 
> >   https://lore.kernel.org/all/CAHk-=wgfpLdt7SFFGcByTfHdkvv7AEa3MDu_s_W1kfOxQs49pw at mail.gmail.com/
> > 
> > that this deserves a detailed comment.
> 
> And he wrote one in https://lore.kernel.org/all/CAHk-=wiq=GUNWJwWh1CRAYchW73UmOaSkaCovLatfDKeveZctA at mail.gmail.com/
> 
>    /*
>     * iff 'x' is a non-zero constant integer expression,
>     * then '!(x)' will be a zero constant integer expression,
>     * and casting that to 'void *' will result in a NULL pointer.
>     * Otherwise casting it to 'void *' will be just a regular 'void *'.
>     *
>     * The type of '0 ? NULL : (char *)' is 'char *'
>     * The type of '0 ? (void *) : (char *) is 'void *'
>     */
>     #define const_true(x) \
>         _Generic(0 ? (void *)((long)!(x)) : (char *)0, char *: 1, void *: 0)
> 
> 
> 
> > 
> > The details block in the current __is_constexpr() is 37 lines long,
> > the details block in __is_const_zero() takes 22 lines. So I would
> > argue that I made things better.
> 
> The old block was too long :-)
> 
> > 
> > Unless more people share your concern, I am planning to keep this comment as-is.
> > 
> > > > + *
> > > > + * Glory to Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
> > > 
> > > IIRC Martin has agreed in the past that the accreditation can
> > > be removed - especially since it refers to the 'sizeof (void)' trick.
> > 
> > I tried to look for such message:
> > 
> >   https://lore.kernel.org/all/?q=f%3A%22martin+uecker%22+__is_constexpr
> > 
> > but couldn't find it. Do you have the link?
> > 
> > @Martin, do you agree that I remove the accreditation?
> > 
> > > > + */
> > > > +#define __is_const_zero(x) \
> > > > +     _Generic(0 ? (void *)(long)(x) : (char *)0, char *: 1, void *: 0)
> > > > +
> > > > +/*
> > > > + * Returns a constant expression while determining if its argument is a
> > > > + * constant expression, most importantly without evaluating the argument.
> > > 
> > > You need to differentiate between a 'constant integer expression'
> > > and a 'compile time constant'.
> > 
> > OK. This one was just copied from the previous __is_constexpr(). I will apply
> > "s/constant expression/constant integer expression/g" in v2.
> > 
> > > > + *
> > > > + * If getting a constant expression is not relevant to you, use the more
> > > > + * powerful __builtin_constant_p() instead.
> > > 
> > > __builtin_constant_p() is not 'more powerful' it is testing for
> > > something different.
> > 
> > I meant to say that __builtin_constant_p() is more powerful at
> > constant folding. But I agree that the comment is not clear.
> > 
> > What about this?
> > 
> >   If getting a constant integer expression is not relevant to you, use
> >   __builtin_constant_p() which not only returns true if the argument
> >   is an integer constant expression, but also if it is a compile time
> >   constant.
> 
> Complete f***ed tense.
> 
> It's not about 'constant folding' and 'powerful' isn't the correct word.
> They are checking for two different things.
> 
> A 'constant integer expression' is defined by the C language, and is
> basically something that is constant when first parsed by the compiler
> (my definition) so it can pretty much only contain constants, sizeof()
> and offsetof().
> 
> __builtin_constant_p() is true if the compiler decides that an expression is
> constant. This can track values through inlined function calls and can
> change from 'unknown' to 'true' late in the compilation.
> 
> 	David
> 
> > 
> > 
> > Yours sincerely,
> > Vincent Mailhol
> 
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)



From arnd at arndb.de  Thu Dec  5 22:47:40 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 06 Dec 2024 07:47:40 +0100
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <20241205175345.201595-3-tudor.ambarus@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-3-tudor.ambarus@linaro.org>
Message-ID: <427caa87-b9ba-4797-88bd-a18a96eefdcf@app.fastmail.com>

On Thu, Dec 5, 2024, at 18:53, Tudor Ambarus wrote:

> +#define exynos_acpm_set_bulk(data, i)					\
> +	(((data) & ACPM_BULK_MASK) << (ACPM_BULK_SHIFT * (i)))
> +#define exynos_acpm_read_bulk(data, i)					\
> +	(((data) >> (ACPM_BULK_SHIFT * (i))) & ACPM_BULK_MASK)

Could these be inline functions for readability?

> +	cmd[3] = (u32)(sched_clock() / 1000000); /*record ktime ms*/

The comment does not match the implementation, sched_clock()
is probably not what you want here because of its limitiations.

Maybe ktime_to_ms(ktime_get())?

> +/**
> + * acpm_get_rx() - get response from RX queue.
> + * @achan:	ACPM channel info.
> + * @xfer:	reference to the transfer to get response for.
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +static int acpm_get_rx(struct acpm_chan *achan, struct acpm_xfer *xfer)
> +{
> +	struct acpm_msg *tx = &xfer->tx;
> +	struct acpm_msg *rx = &xfer->rx;
> +	struct acpm_rx_data *rx_data;
> +	const void __iomem *base, *addr;
> +	u32 rx_front, rx_seqnum, tx_seqnum, seqnum;
> +	u32 i, val, mlen;
> +	bool rx_set = false;
> +
> +	rx_front = readl_relaxed(achan->rx.front);
> +	i = readl_relaxed(achan->rx.rear);

If you have to use readl_relaxed(), please annotate why,
otherwise just use the normal readl().  Is this access to
the SRAM?

> +	spin_lock_irqsave(&achan->tx_lock, flags);
> +
> +	tx_front = readl_relaxed(achan->tx.front);
> +	idx = (tx_front + 1) % achan->qlen;
> +
> +	ret = acpm_wait_for_queue_slots(achan, idx);
> +	if (ret) {
> +		spin_unlock_irqrestore(&achan->tx_lock, flags);
> +		return ret;
> +	}

It looks like you are calling a busy loop function inside
of a hardirq handler here, with a 500ms timeout. This is
not ok.

If you may need to wait for a long timeout, I would suggest
changing the interface so that this function is not allowed
to be called from irq-disabled context, change the spinlock
to a mutex and polling read to a sleeping version.

> +	/* Advance TX front. */
> +	writel_relaxed(idx, achan->tx.front);
> +
> +	/* Flush SRAM posted writes. */
> +	readl_relaxed(achan->tx.front);
> +
> +	spin_unlock_irqrestore(&achan->tx_lock, flags);

I don't think this sequence guarantees the serialization
you want. By making the access _relaxed() you explicitly
say you don't want serialization, so the store does
not have to complete before the unlock.

> +static const struct of_device_id acpm_match[] = {
> +	{ .compatible = "google,gs101-acpm-ipc" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, acpm_match);
> +
> +static struct platform_driver acpm_driver = {
> +	.probe	= acpm_probe,
> +	.driver	= {
> +		.name = "exynos-acpm-protocol",
> +		.of_match_table	= of_match_ptr(acpm_match),

Remove the stray of_match_ptr() here.

> diff --git a/drivers/firmware/samsung/exynos-acpm.h 
> b/drivers/firmware/samsung/exynos-acpm.h
> new file mode 100644
> index 000000000000..a03adcd260f5
> --- /dev/null
> +++ b/drivers/firmware/samsung/exynos-acpm.h
> @@ -0,0 +1,15 @@
> +#ifndef __EXYNOS_ACPM_H__
> +#define __EXYNOS_ACPM_H__
> +
> +struct acpm_handle;
> +struct acpm_xfer;
> +
> +int acpm_do_xfer(const struct acpm_handle *handle, struct acpm_xfer 
> *xfer);
> +
> +#endif /* __EXYNOS_ACPM_H__ */
> diff --git a/include/linux/soc/samsung/exynos-acpm-protocol.h 
> b/include/linux/soc/samsung/exynos-acpm-protocol.h
> new file mode 100644
> index 000000000000..762783af7617
> --- /dev/null
> +++ b/include/linux/soc/samsung/exynos-acpm-protocol.h

Why is this in include/linux/soc, and not in the firmware
header?

      Arnd


From Trevor.Wu at mediatek.com  Thu Dec  5 22:57:00 2024
From: Trevor.Wu at mediatek.com (=?utf-8?B?VHJldm9yIFd1ICjlkLPmlofoia8p?=)
Date: Fri, 6 Dec 2024 06:57:00 +0000
Subject: [PATCH] ASoC: mediatek: mt8188: Enable apll1 clock during reg rw
 to prevent hang
In-Reply-To: <a70a0521-985d-43a4-a1fa-36eb733d5ca9@collabora.com>
References: <20241203-mt8188-afe-fix-hang-disabled-apll1-clk-v1-1-07cdd7760834@collabora.com>
	 <a10dbdf265194e77a69b6e40afa3df9636b3ab14.camel@mediatek.com>
	 <a70a0521-985d-43a4-a1fa-36eb733d5ca9@collabora.com>
Message-ID: <1d2ee55dde84bcab6f777525042c6789b9f2c1fc.camel@mediatek.com>

On Thu, 2024-12-05 at 13:51 +0100, AngeloGioacchino Del Regno wrote:
> 
> 
> Il 04/12/24 13:17, Trevor Wu (???) ha scritto:
> > On Tue, 2024-12-03 at 17:07 -0300, N?colas F. R. A. Prado wrote:
> > 
> > > 
> > > Currently, booting the Genio 700 EVK board with the MT8188 sound
> > > platform driver configured as a module (CONFIG_SND_SOC_MT8188=m)
> > > results
> > > in a system hang right when the HW registers for the audio
> > > controller
> > > are read:
> > > 
> > >    mt8188-audio 10b10000.audio-controller: No cache defaults,
> > > reading
> > > back from HW
> > > 
> > > The hang doesn't occur with the driver configured as builtin as
> > > then
> > > the
> > > unused clocks are still enabled.
> > > 
> > > Enable the apll1 clock during register read/write to prevent the
> > > hang.
> > > 
> > > Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> > > ---
> > >   sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 4 ++++
> > >   1 file changed, 4 insertions(+)
> > > 
> > > diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > index
> > > e69c1bb2cb239596dee50b166c20192d5408be10..fb8cf286df3f02ac076528b
> > > 898f
> > > d0d7a708ec1ea 100644
> > > --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > @@ -587,6 +587,8 @@ int mt8188_afe_enable_reg_rw_clk(struct
> > > mtk_base_afe *afe)
> > >          mt8188_afe_enable_clk(afe, afe_priv-
> > > > clk[MT8188_CLK_AUD_A1SYS_HP]);
> > > 
> > >          mt8188_afe_enable_clk(afe, afe_priv-
> > > > clk[MT8188_CLK_AUD_A1SYS]);
> > > 
> > > +       mt8188_afe_enable_clk(afe, afe_priv-
> > > > clk[MT8188_CLK_APMIXED_APLL1]);
> > > 
> > > +
> > >          return 0;
> > >   }
> > 
> > Hi Nicolas,
> > 
> > If I understand correctly, APLL1 should be the parent clock of
> > AUD_A1SYS_HP and AUD_A1SYS, so it should be enabled automatically
> > by
> > CCF.
> > 
> > I'm not sure why you resolved the hang issue after enabling APLL1.
> > Could you share more details about the solution?
> > 
> 
> Hmm. Now I see what's happening here...
> 
> Nicolas, Trevor,
> 
> Possible parents for top_a1sys_hp are:
>   - clk26m
>   - apll1_d4
> 
> ...what's happening here most probably is that after the clock gets
> disabled as
> unused, it gets parented to clk26m by default as that is parent index
> 0... and
> something else in AFE needs APLL1 to feed a clock to .. something ..
> to allow
> register access.
> 
> Trevor, do you know why is this IP unaccessible when A1SYS is
> parented to clk26m?

Hi Angelo,

As far as I know, it should work even though the clock is parented to
clk26m.

Unfortunately, I have no idea about why APLL1 enabling can resolve the
hang issue. I'm also curious about how Nicolas found the solution to
resolve the problem.

From the description, it seems that the problem is related to register
r/w hang. If I remembered correctly, when the mtcmos of ADSP_INFRA is
ON, register r/w won't cause the cpu to hang. However, ADSP_INFRA has
been configured as ALWAYS_ON in the driver. I'm not sure if it doesn't
work correctly when the driver is configured as a module. Maybe Nicolas
can also check this.

Thanks,
Trevor

> 
> That might give Nicolas a definitive hint about how to resolve this
> issue.
> 
> Cheers,
> Angelo
> 
> > Thanks,
> > Trevor
> > 
> > > 
> > > @@ -594,6 +596,8 @@ int mt8188_afe_disable_reg_rw_clk(struct
> > > mtk_base_afe *afe)
> > >   {
> > >          struct mt8188_afe_private *afe_priv = afe-
> > > >platform_priv;
> > > 
> > > +       mt8188_afe_disable_clk(afe, afe_priv-
> > > > clk[MT8188_CLK_APMIXED_APLL1]);
> > > 
> > > +
> > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > clk[MT8188_CLK_AUD_A1SYS]);
> > > 
> > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > clk[MT8188_CLK_AUD_A1SYS_HP]);
> > > 
> > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > clk[MT8188_CLK_AUD_AFE]);
> > > 
> > > ---
> > > base-commit: b852e1e7a0389ed6168ef1d38eb0bad71a6b11e8
> > > change-id: 20241203-mt8188-afe-fix-hang-disabled-apll1-clk-
> > > b3c11782cbaf
> > > 
> > > Best regards,
> > > --
> > > N?colas F. R. A. Prado <nfraprado at collabora.com>
> > > 
> > > 
> 
> 

From ciprianmarian.costea at oss.nxp.com  Thu Dec  5 23:09:53 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri,  6 Dec 2024 09:09:53 +0200
Subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

Add a RTC driver for NXP S32G2/S32G3 SoCs.

RTC tracks clock time during system suspend. It can be a wakeup source
for the S32G2/S32G3 SoC based boards.

The RTC module from S32G2/S32G3 is not battery-powered and it is not kept
alive during system reset.

Co-developed-by: Bogdan Hamciuc <bogdan.hamciuc at nxp.com>
Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc at nxp.com>
Co-developed-by: Ghennadi Procopciuc <Ghennadi.Procopciuc at nxp.com>
Signed-off-by: Ghennadi Procopciuc <Ghennadi.Procopciuc at nxp.com>
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 drivers/rtc/Kconfig    |  11 +
 drivers/rtc/Makefile   |   1 +
 drivers/rtc/rtc-s32g.c | 529 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 541 insertions(+)
 create mode 100644 drivers/rtc/rtc-s32g.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index a60bcc791a48..25ee7c6d8748 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -2103,4 +2103,15 @@ config RTC_DRV_AMLOGIC_A4
 	  This driver can also be built as a module. If so, the module
 	  will be called "rtc-amlogic-a4".
 
+config RTC_DRV_S32G
+	tristate "RTC driver for S32G2/S32G3 SoCs"
+	depends on ARCH_S32 || COMPILE_TEST
+	depends on COMMON_CLK
+	help
+	  Say yes to enable RTC driver for platforms based on the
+	  S32G2/S32G3 SoC family.
+
+	  This RTC module can be used as a wakeup source.
+	  Please note that it is not battery-powered.
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 489b4ab07068..e4b616ecd5ce 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -161,6 +161,7 @@ obj-$(CONFIG_RTC_DRV_RX8111)	+= rtc-rx8111.o
 obj-$(CONFIG_RTC_DRV_RX8581)	+= rtc-rx8581.o
 obj-$(CONFIG_RTC_DRV_RZN1)	+= rtc-rzn1.o
 obj-$(CONFIG_RTC_DRV_RENESAS_RTCA3)	+= rtc-renesas-rtca3.o
+obj-$(CONFIG_RTC_DRV_S32G)	+= rtc-s32g.o
 obj-$(CONFIG_RTC_DRV_S35390A)	+= rtc-s35390a.o
 obj-$(CONFIG_RTC_DRV_S3C)	+= rtc-s3c.o
 obj-$(CONFIG_RTC_DRV_S5M)	+= rtc-s5m.o
diff --git a/drivers/rtc/rtc-s32g.c b/drivers/rtc/rtc-s32g.c
new file mode 100644
index 000000000000..0989b6f2a613
--- /dev/null
+++ b/drivers/rtc/rtc-s32g.c
@@ -0,0 +1,529 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/math64.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#define RTCC_OFFSET	0x4ul
+#define RTCS_OFFSET	0x8ul
+#define RTCCNT_OFFSET	0xCul
+#define APIVAL_OFFSET	0x10ul
+#define RTCVAL_OFFSET	0x14ul
+
+/* RTCC fields */
+#define RTCC_CNTEN				BIT(31)
+#define RTCC_RTCIE				BIT(30)
+#define RTCC_APIEN				BIT(15)
+#define RTCC_APIIE				BIT(14)
+#define RTCC_CLKSEL_MASK		GENMASK(13, 12)
+#define RTCC_DIV512EN			BIT(11)
+#define RTCC_DIV32EN			BIT(10)
+
+/* RTCS fields */
+#define RTCS_RTCF		BIT(29)
+#define RTCS_INV_RTC		BIT(18)
+#define RTCS_APIF		BIT(13)
+
+#define RTCCNT_MAX_VAL		GENMASK(31, 0)
+#define RTC_SYNCH_TIMEOUT	(100 * USEC_PER_MSEC)
+
+#define RTC_CLK_MUX_SIZE	4
+
+/*
+ * S32G2 and S32G3 SoCs have RTC clock source1 reserved and
+ * should not be used.
+ */
+#define RTC_CLK_SRC1_RESERVED		BIT(1)
+
+enum {
+	DIV1 = 1,
+	DIV32 = 32,
+	DIV512 = 512,
+	DIV512_32 = 16384
+};
+
+static const char *rtc_clk_src[RTC_CLK_MUX_SIZE] = {
+	"source0",
+	"source1",
+	"source2",
+	"source3"
+};
+
+struct rtc_time_base {
+	s64 sec;
+	u64 cycles;
+	struct rtc_time tm;
+};
+
+struct rtc_priv {
+	struct rtc_device *rdev;
+	void __iomem *rtc_base;
+	struct clk *ipg;
+	struct clk *clk_src;
+	const struct rtc_soc_data *rtc_data;
+	struct rtc_time_base base;
+	u64 rtc_hz;
+	int irq;
+	int clk_src_idx;
+};
+
+struct rtc_soc_data {
+	u32 clk_div;
+	u32 reserved_clk_mask;
+};
+
+static const struct rtc_soc_data rtc_s32g2_data = {
+	.clk_div = DIV512,
+	.reserved_clk_mask = RTC_CLK_SRC1_RESERVED,
+};
+
+static u64 cycles_to_sec(u64 hz, u64 cycles)
+{
+	return div_u64(cycles, hz);
+}
+
+/**
+ * sec_to_rtcval - Convert a number of seconds to a value suitable for
+ * RTCVAL in our clock's
+ * current configuration.
+ * @priv: Pointer to the 'rtc_priv' structure
+ * @seconds: Number of seconds to convert
+ * @rtcval: The value to go into RTCVAL[RTCVAL]
+ *
+ * Return: 0 for success, -EINVAL if @seconds push the counter past the
+ *          32bit register range
+ */
+static int sec_to_rtcval(const struct rtc_priv *priv,
+			 unsigned long seconds, u32 *rtcval)
+{
+	u32 delta_cnt;
+
+	if (!seconds || seconds > cycles_to_sec(priv->rtc_hz, RTCCNT_MAX_VAL))
+		return -EINVAL;
+
+	/*
+	 * RTCCNT is read-only; we must return a value relative to the
+	 * current value of the counter (and hope we don't linger around
+	 * too much before we get to enable the interrupt)
+	 */
+	delta_cnt = seconds * priv->rtc_hz;
+	*rtcval = delta_cnt + ioread32(priv->rtc_base + RTCCNT_OFFSET);
+
+	return 0;
+}
+
+static irqreturn_t s32g_rtc_handler(int irq, void *dev)
+{
+	struct rtc_priv *priv = platform_get_drvdata(dev);
+	u32 status;
+
+	status = ioread32(priv->rtc_base + RTCS_OFFSET);
+
+	if (status & RTCS_RTCF) {
+		iowrite32(0x0, priv->rtc_base + RTCVAL_OFFSET);
+		iowrite32(status | RTCS_RTCF, priv->rtc_base + RTCS_OFFSET);
+		rtc_update_irq(priv->rdev, 1, RTC_AF);
+	}
+
+	if (status & RTCS_APIF) {
+		iowrite32(status | RTCS_APIF, priv->rtc_base + RTCS_OFFSET);
+		rtc_update_irq(priv->rdev, 1, RTC_PF);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static s64 s32g_rtc_get_time_or_alrm(struct rtc_priv *priv,
+				     u32 offset)
+{
+	u32 counter;
+
+	counter = ioread32(priv->rtc_base + offset);
+
+	if (counter < priv->base.cycles)
+		return -EINVAL;
+
+	counter -= priv->base.cycles;
+
+	return priv->base.sec + cycles_to_sec(priv->rtc_hz, counter);
+}
+
+static int s32g_rtc_read_time(struct device *dev,
+			      struct rtc_time *tm)
+{
+	struct rtc_priv *priv = dev_get_drvdata(dev);
+	s64 sec;
+
+	sec = s32g_rtc_get_time_or_alrm(priv, RTCCNT_OFFSET);
+	if (sec < 0)
+		return -EINVAL;
+
+	rtc_time64_to_tm(sec, tm);
+
+	return 0;
+}
+
+static int s32g_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_priv *priv = dev_get_drvdata(dev);
+	u32 rtcc, rtccnt, rtcval;
+	s64 sec;
+
+	sec = s32g_rtc_get_time_or_alrm(priv, RTCVAL_OFFSET);
+	if (sec < 0)
+		return -EINVAL;
+
+	rtc_time64_to_tm(sec, &alrm->time);
+
+	rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
+	alrm->enabled = sec && (rtcc & RTCC_RTCIE);
+
+	alrm->pending = 0;
+	if (alrm->enabled) {
+		rtccnt = ioread32(priv->rtc_base + RTCCNT_OFFSET);
+		rtcval = ioread32(priv->rtc_base + RTCVAL_OFFSET);
+
+		if (rtccnt < rtcval)
+			alrm->pending = 1;
+	}
+
+	return 0;
+}
+
+static int s32g_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct rtc_priv *priv = dev_get_drvdata(dev);
+	u32 rtcc;
+
+	if (!priv->irq)
+		return -EIO;
+
+	rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
+	if (enabled)
+		rtcc |= RTCC_RTCIE;
+
+	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
+
+	return 0;
+}
+
+static int s32g_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_priv *priv = dev_get_drvdata(dev);
+	struct rtc_time time_crt;
+	long long t_crt, t_alrm;
+	u32 rtcval, rtcs;
+	int ret = 0;
+
+	iowrite32(0x0, priv->rtc_base + RTCVAL_OFFSET);
+
+	t_alrm = rtc_tm_to_time64(&alrm->time);
+
+	/*
+	 * Assuming the alarm is being set relative to the same time
+	 * returned by our s32g_rtc_read_time callback
+	 */
+	ret = s32g_rtc_read_time(dev, &time_crt);
+	if (ret)
+		return ret;
+
+	t_crt = rtc_tm_to_time64(&time_crt);
+	ret = sec_to_rtcval(priv, t_alrm - t_crt, &rtcval);
+	if (ret) {
+		dev_warn(dev, "Alarm is set too far in the future\n");
+		return -ERANGE;
+	}
+
+	ret = read_poll_timeout(ioread32, rtcs, !(rtcs & RTCS_INV_RTC),
+				0, RTC_SYNCH_TIMEOUT, false, priv->rtc_base + RTCS_OFFSET);
+	if (ret)
+		return ret;
+
+	iowrite32(rtcval, priv->rtc_base + RTCVAL_OFFSET);
+
+	return 0;
+}
+
+static int s32g_rtc_set_time(struct device *dev,
+			     struct rtc_time *time)
+{
+	struct rtc_priv *priv = dev_get_drvdata(dev);
+
+	priv->base.cycles = ioread32(priv->rtc_base + RTCCNT_OFFSET);
+	priv->base.sec = rtc_tm_to_time64(time);
+
+	return 0;
+}
+
+/*
+ * Disable the 32-bit free running counter.
+ * This allows Clock Source and Divisors selection
+ * to be performed without causing synchronization issues.
+ */
+static void s32g_rtc_disable(struct rtc_priv *priv)
+{
+	u32 rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
+
+	rtcc &= ~RTCC_CNTEN;
+	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
+}
+
+static void s32g_rtc_enable(struct rtc_priv *priv)
+{
+	u32 rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
+
+	rtcc |= RTCC_CNTEN;
+	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
+}
+
+static int rtc_clk_src_setup(struct rtc_priv *priv)
+{
+	u32 rtcc = 0;
+
+	if (priv->rtc_data->reserved_clk_mask & (1 << priv->clk_src_idx))
+		return -EOPNOTSUPP;
+
+	rtcc = FIELD_PREP(RTCC_CLKSEL_MASK, priv->clk_src_idx);
+
+	switch (priv->rtc_data->clk_div) {
+	case DIV512_32:
+		rtcc |= RTCC_DIV512EN;
+		rtcc |= RTCC_DIV32EN;
+		break;
+	case DIV512:
+		rtcc |= RTCC_DIV512EN;
+		break;
+	case DIV32:
+		rtcc |= RTCC_DIV32EN;
+		break;
+	case DIV1:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	rtcc |= RTCC_RTCIE;
+	/*
+	 * Make sure the CNTEN is 0 before we configure
+	 * the clock source and dividers.
+	 */
+	s32g_rtc_disable(priv);
+	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
+	s32g_rtc_enable(priv);
+
+	return 0;
+}
+
+static const struct rtc_class_ops rtc_ops = {
+	.read_time = s32g_rtc_read_time,
+	.set_time = s32g_rtc_set_time,
+	.read_alarm = s32g_rtc_read_alarm,
+	.set_alarm = s32g_rtc_set_alarm,
+	.alarm_irq_enable = s32g_rtc_alarm_irq_enable,
+};
+
+static int rtc_clk_dts_setup(struct rtc_priv *priv,
+			     struct device *dev)
+{
+	int i;
+
+	priv->ipg = devm_clk_get_enabled(dev, "ipg");
+	if (IS_ERR(priv->ipg))
+		return dev_err_probe(dev, PTR_ERR(priv->ipg),
+				"Failed to get 'ipg' clock\n");
+
+	for (i = 0; i < RTC_CLK_MUX_SIZE; i++) {
+		priv->clk_src = devm_clk_get_enabled(dev, rtc_clk_src[i]);
+		if (!IS_ERR(priv->clk_src)) {
+			priv->clk_src_idx = i;
+			break;
+		}
+	}
+
+	if (IS_ERR(priv->clk_src))
+		return dev_err_probe(dev, PTR_ERR(priv->clk_src),
+				"Failed to get rtc module clock source\n");
+
+	return 0;
+}
+
+static int s32g_rtc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rtc_priv *priv;
+	int ret = 0;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->rtc_data = of_device_get_match_data(dev);
+	if (!priv->rtc_data)
+		return -ENODEV;
+
+	priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->rtc_base))
+		return PTR_ERR(priv->rtc_base);
+
+	device_init_wakeup(dev, true);
+
+	ret = rtc_clk_dts_setup(priv, dev);
+	if (ret)
+		return ret;
+
+	priv->rdev = devm_rtc_allocate_device(dev);
+	if (IS_ERR(priv->rdev))
+		return PTR_ERR(priv->rdev);
+
+	ret = rtc_clk_src_setup(priv);
+	if (ret)
+		return ret;
+
+	priv->rtc_hz = clk_get_rate(priv->clk_src);
+	if (!priv->rtc_hz) {
+		dev_err(dev, "Failed to get RTC frequency\n");
+		ret = -EINVAL;
+		goto disable_rtc;
+	}
+
+	priv->rtc_hz /= priv->rtc_data->clk_div;
+
+	platform_set_drvdata(pdev, priv);
+	priv->rdev->ops = &rtc_ops;
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (priv->irq < 0) {
+		ret = priv->irq;
+		goto disable_rtc;
+	}
+
+	ret = devm_request_irq(dev, priv->irq,
+			       s32g_rtc_handler, 0, dev_name(dev), pdev);
+	if (ret) {
+		dev_err(dev, "Request interrupt %d failed, error: %d\n",
+			priv->irq, ret);
+		goto disable_rtc;
+	}
+
+	ret = devm_rtc_register_device(priv->rdev);
+	if (ret)
+		goto disable_rtc;
+
+	return 0;
+
+disable_rtc:
+	s32g_rtc_disable(priv);
+	return ret;
+}
+
+static void s32g_enable_api_irq(struct device *dev, unsigned int enabled)
+{
+	struct rtc_priv *priv = dev_get_drvdata(dev);
+	u32 api_irq = RTCC_APIEN | RTCC_APIIE;
+	u32 rtcc;
+
+	rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
+	if (enabled)
+		rtcc |= api_irq;
+	else
+		rtcc &= ~api_irq;
+	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
+}
+
+static int s32g_rtc_suspend(struct device *dev)
+{
+	struct rtc_priv *init_priv = dev_get_drvdata(dev);
+	struct rtc_priv priv;
+	long long base_sec;
+	u32 rtcval, rtccnt, offset;
+	int ret = 0;
+	u32 sec;
+
+	if (!device_may_wakeup(dev))
+		return 0;
+
+	/* Save last known timestamp */
+	ret = s32g_rtc_read_time(dev, &init_priv->base.tm);
+	if (ret)
+		return ret;
+
+	/*
+	 * Use a local copy of the RTC control block to
+	 * avoid restoring it on resume path.
+	 */
+	memcpy(&priv, init_priv, sizeof(priv));
+
+	rtccnt = ioread32(init_priv->rtc_base + RTCCNT_OFFSET);
+	rtcval = ioread32(init_priv->rtc_base + RTCVAL_OFFSET);
+	offset = rtcval - rtccnt;
+	sec = cycles_to_sec(init_priv->rtc_hz, offset);
+
+	/* Adjust for the number of seconds we'll be asleep */
+	base_sec = rtc_tm_to_time64(&init_priv->base.tm);
+	base_sec += sec;
+	rtc_time64_to_tm(base_sec, &init_priv->base.tm);
+
+	ret = sec_to_rtcval(&priv, sec, &rtcval);
+	if (ret) {
+		dev_warn(dev, "Alarm is too far in the future\n");
+		return -ERANGE;
+	}
+
+	s32g_enable_api_irq(dev, 1);
+	iowrite32(offset, priv.rtc_base + APIVAL_OFFSET);
+
+	return ret;
+}
+
+static int s32g_rtc_resume(struct device *dev)
+{
+	struct rtc_priv *priv = dev_get_drvdata(dev);
+	int ret;
+
+	if (!device_may_wakeup(dev))
+		return 0;
+
+	/* Disable wake-up interrupts */
+	s32g_enable_api_irq(dev, 0);
+
+	ret = rtc_clk_src_setup(priv);
+	if (ret)
+		return ret;
+
+	/*
+	 * Now RTCCNT has just been reset, and is out of sync with priv->base;
+	 * reapply the saved time settings.
+	 */
+	return s32g_rtc_set_time(dev, &priv->base.tm);
+}
+
+static const struct of_device_id rtc_dt_ids[] = {
+	{ .compatible = "nxp,s32g2-rtc", .data = &rtc_s32g2_data},
+	{ /* sentinel */ },
+};
+
+static DEFINE_SIMPLE_DEV_PM_OPS(s32g_rtc_pm_ops,
+			 s32g_rtc_suspend, s32g_rtc_resume);
+
+static struct platform_driver s32g_rtc_driver = {
+	.driver		= {
+		.name			= "s32g-rtc",
+		.pm				= pm_sleep_ptr(&s32g_rtc_pm_ops),
+		.of_match_table = rtc_dt_ids,
+	},
+	.probe		= s32g_rtc_probe,
+};
+module_platform_driver(s32g_rtc_driver);
+
+MODULE_AUTHOR("NXP");
+MODULE_DESCRIPTION("NXP RTC driver for S32G2/S32G3");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Thu Dec  5 23:09:54 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri,  6 Dec 2024 09:09:54 +0200
Subject: [PATCH v6 3/4] arm64: defconfig: add S32G RTC module support
In-Reply-To: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241206070955.1503412-4-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

The RTC hardware module present on S32G based SoCs tracks clock time
during system suspend and it is used as a wakeup source on S32G2/S32G3
architecture.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..d9d0ddd0d31e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1210,6 +1210,7 @@ CONFIG_RTC_DRV_DA9063=m
 CONFIG_RTC_DRV_EFI=y
 CONFIG_RTC_DRV_CROS_EC=y
 CONFIG_RTC_DRV_FSL_FTM_ALARM=m
+CONFIG_RTC_DRV_S32G=m
 CONFIG_RTC_DRV_S3C=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_RTC_DRV_SUN6I=y
-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Thu Dec  5 23:09:55 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri,  6 Dec 2024 09:09:55 +0200
Subject: [PATCH v6 4/4] MAINTAINERS: add NXP S32G RTC driver
In-Reply-To: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241206070955.1503412-5-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

Add the NXP S32G RTC driver as maintained so further patches on this
driver can be reviewed under this architecture.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..cf1f5b0a31f9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2833,8 +2833,10 @@ R:	Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
 L:	NXP S32 Linux Team <s32 at nxp.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
+F:	Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml
 F:	arch/arm64/boot/dts/freescale/s32g*.dts*
 F:	drivers/pinctrl/nxp/
+F:	drivers/rtc/rtc-s32g.c
 
 ARM/Orion SoC/Technologic Systems TS-78xx platform support
 M:	Alexander Clouter <alex at digriz.org.uk>
-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Thu Dec  5 23:09:51 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri,  6 Dec 2024 09:09:51 +0200
Subject: [PATCH v6 0/4] add NXP RTC driver support for S32G2/S32G3 SoCs
Message-ID: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

This patch series add support for the NXP RTC hardware module present on
S32G2/S32G3 SoCs.

RTC tracks clock time during system suspend. It is used as a time-based
wakeup source for the S32G2/S32G3 SoCs.

RTC is not battery-powered and it is not kept alive during system reset.

Following is an example of Suspend to RAM trigger on S32G2/S32G3 SoCs,
using userspace tools such as rtcwake:
# rtcwake -s 2 -m mem
# rtcwake: assuming RTC uses UTC ...
# rtcwake: wakeup from "mem" using /dev/rtc0 at Wed Feb  6 06:28:36 2036
#

Changes in V6:
- Fixed a coding style issue regarding kernel doc reported by kernel test robot
- Refactored small sections from the S32G RTC driver without impacting
  functionality
- Fixed an error probe path issue on S32G RTC driver.
- Added 'rtc' schema in S32G-RTC bindings

Changes in V5:
- Removed rollover support.
- Removed clock switching support between Runtime and Suspend. A clock source
  which is always available has been used instead.
- Enabled 512 value RTC hardware frequency divisor to achieve higher rollover
  time
- Removed unneeded 'remove' callback.
- Decreased driver print verbosity on error paths.
- Provided 'clock-names' actual names in bindings documentation
- Remove __maybe_unused notations. Used the DEFINE_SIMPLE_DEV_PM_OPS() and
  pm_sleep_ptr() macros to handle the .suspend/.resume callbacks.
- Fixed some alignment issues.

Changes in V4:
- Dropped 'assigned-*' clock management approach. Simplified RTC Runtime
  and Suspend/Standby clock configuration.
- Simplified error paths on probe function
- Removed node label from bindings example
- Several cosmetic coding style fixes

Changes in V3:
- Removed 'nxp,s32g3-rtc' compatible string
- Change to 'remove' callback from 'remove_new'
- Used 'dev.parent' from 'struct rtc_device' instead of defining a
  specific 'struct device' in driver data
- Fixed several errors reported by kernel test robot
- Removed 'assigned-clocks', 'assigned-clock-parents' and
  'assigned-clock-rates' from required properties in the binding
  documentation.
- Refactored S32G RTC driver such that a default clock source and
  divisors configuration will be applied in case 'assigned-clocks' and
  'assigned-clock-parents' properties are missing.

Changes in V2:
- Removed 'clksel' support from dts bindings. Used clock parents support
  from CCF to better illustrate the RTC hardware IP from S32G2/S32G3.
- Removed frequency dividers support from dts bindings. Used assigned
  clock frequencies support from CCF instead.
- Reduced the interval while RTC is voluntarily disabled to a simple
  register write in order to avoid any race condition between a possbile
  rollover and 'suspend' callback execution flow.
- Updated bindings documentation with respect to clocking support.
- Fixed a potential unused variable warning reported by kernel test robot.
- Updated to usage of 'devm_rtc_allocate_device' and 'devm_rtc_register_device'
  instead of deprecated 'devm_rtc_device_register'.

Ciprian Marian Costea (4):
  dt-bindings: rtc: add schema for NXP S32G2/S32G3 SoCs
  rtc: s32g: add NXP S32G2/S32G3 SoC support
  arm64: defconfig: add S32G RTC module support
  MAINTAINERS: add NXP S32G RTC driver

 .../devicetree/bindings/rtc/nxp,s32g-rtc.yaml |  72 +++
 MAINTAINERS                                   |   2 +
 arch/arm64/configs/defconfig                  |   1 +
 drivers/rtc/Kconfig                           |  11 +
 drivers/rtc/Makefile                          |   1 +
 drivers/rtc/rtc-s32g.c                        | 529 ++++++++++++++++++
 6 files changed, 616 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml
 create mode 100644 drivers/rtc/rtc-s32g.c

-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Thu Dec  5 23:09:52 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri,  6 Dec 2024 09:09:52 +0200
Subject: [PATCH v6 1/4] dt-bindings: rtc: add schema for NXP S32G2/S32G3 SoCs
In-Reply-To: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241206070955.1503412-2-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

RTC tracks clock time during system suspend and it is used as a wakeup
source on S32G2/S32G3 architecture.

RTC from S32G2/S32G3 is not battery-powered and it is not kept alive
during system reset.

Co-developed-by: Bogdan-Gabriel Roman <bogdan-gabriel.roman at nxp.com>
Signed-off-by: Bogdan-Gabriel Roman <bogdan-gabriel.roman at nxp.com>
Co-developed-by: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 .../devicetree/bindings/rtc/nxp,s32g-rtc.yaml | 72 +++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml

diff --git a/Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml b/Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml
new file mode 100644
index 000000000000..40fd2fa298fe
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/nxp,s32g-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP S32G2/S32G3 Real Time Clock (RTC)
+
+maintainers:
+  - Bogdan Hamciuc <bogdan.hamciuc at nxp.com>
+  - Ciprian Marian Costea <ciprianmarian.costea at nxp.com>
+
+description:
+  RTC hardware module present on S32G2/S32G3 SoCs is used as a wakeup source.
+  It is not kept alive during system reset and it is not battery-powered.
+
+allOf:
+  - $ref: rtc.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - nxp,s32g2-rtc
+      - items:
+          - const: nxp,s32g3-rtc
+          - const: nxp,s32g2-rtc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: ipg clock drives the access to the RTC iomapped registers
+      - description: Clock source for the RTC module. Can be selected between
+          4 different clock sources using an integrated hardware mux.
+          On S32G2/S32G3 SoCs, 'source0' is the SIRC clock (~32KHz) and it is
+          available during standby and runtime. 'source1' is reserved and cannot
+          be used. 'source2' is the FIRC clock and it is only available during
+          runtime providing a better resolution (~48MHz). 'source3' is an external
+          RTC clock source which can be additionally added in hardware.
+
+  clock-names:
+    items:
+      - const: ipg
+      - enum: [ source0, source1, source2, source3 ]
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    rtc at 40060000 {
+        compatible = "nxp,s32g3-rtc",
+                     "nxp,s32g2-rtc";
+        reg = <0x40060000 0x1000>;
+        interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks 54>, <&clks 55>;
+        clock-names = "ipg", "source0";
+    };
-- 
2.45.2



From ukleinek at kernel.org  Thu Dec  5 23:12:57 2024
From: ukleinek at kernel.org (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Fri, 6 Dec 2024 08:12:57 +0100
Subject: [PATCH V2] pwm: stm32-lp: Add check for clk_enable()
In-Reply-To: <20241206012605.2877412-1-zmw12306@gmail.com>
References: <20241206012605.2877412-1-zmw12306@gmail.com>
Message-ID: <cim6rnzdvhik4kdibfmglf6jiky7xccynqwazmxmnr2f5fvu3f@lvoo3drlgaua>

On Thu, Dec 05, 2024 at 08:26:05PM -0500, Mingwei Zheng wrote:
> Add check for the return value of clk_enable() to catch the potential
> error.
> 
> Fixes: e70a540b4e02 ("pwm: Add STM32 LPTimer PWM driver")
> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>

In reply to (implicit) v1 you wrote:
> We detected this through static analysis, instead of actually hit.

Would be nice to mention the tool that actually found it in the commit
log.

Otherwise I'm happy with that change now.

Given the issue is old (the offending commit is in v4.14-rc1), I'd note
send it as a fix before v4.14. I'd send it along however if something
more urgent pops up.

Best regards
Uwe
-------------- 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/20241206/fab0c549/attachment.sig>

From joy.zou at nxp.com  Thu Dec  5 23:32:16 2024
From: joy.zou at nxp.com (Joy Zou)
Date: Fri, 6 Dec 2024 07:32:16 +0000
Subject: [EXT] Re: [PATCH 5/5] arm64: dts: imx93: add pca9452 support
In-Reply-To: <b5b07f6f-a5c5-4b29-ada3-962dbbba42d4@sirena.org.uk>
References: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
 <20241205-pca9450-v1-5-aab448b74e78@nxp.com>
 <b5b07f6f-a5c5-4b29-ada3-962dbbba42d4@sirena.org.uk>
Message-ID: <AS4PR04MB938640EE746307F991183C87E1312@AS4PR04MB9386.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Mark Brown <broonie at kernel.org>
> Sent: 2024?12?6? 0:59
> To: Frank Li <frank.li at nxp.com>
> Cc: Liam Girdwood <lgirdwood at gmail.com>; Rob Herring <robh at kernel.org>;
> Krzysztof Kozlowski <krzk+dt at kernel.org>; Conor Dooley
> <conor+dt at kernel.org>; Robin Gong <yibin.gong at nxp.com>; Shawn Guo
> <shawnguo at kernel.org>; Sascha Hauer <s.hauer at pengutronix.de>;
> Pengutronix Kernel Team <kernel at pengutronix.de>; Fabio Estevam
> <festevam at gmail.com>; linux-kernel at vger.kernel.org;
> devicetree at vger.kernel.org; imx at lists.linux.dev; Joy Zou <joy.zou at nxp.com>;
> linux-arm-kernel at lists.infradead.org
> Subject: [EXT] Re: [PATCH 5/5] arm64: dts: imx93: add pca9452 support
> 
> On Thu, Dec 05, 2024 at 11:51:13AM -0500, Frank Li wrote:
> 
> > +				regulator-name = "BUCK1";
> > +				regulator-min-microvolt = <610000>;
> > +				regulator-max-microvolt = <950000>;
> 
> > +				regulator-name = "BUCK4";
> > +				regulator-min-microvolt = <1620000>;
> > +				regulator-max-microvolt = <3400000>;
> 
> The regulators all have really wide ranges, especially with no obvious
> consumers specified.  Are these actually valid for the board?
Please ignore the last mail because of including html.
Thanks for your comments!
Yes, the regulators all have really wide ranges from the pca9452 datasheet as follow:
BUCK1, BUCK2, BUCK3 : 0.6V to 2.1875V, 12.5mV step, 3000mA
BUCK4 : 0.6V to 3.4V, 25mV step, 3000mA
Refer to PMIC pca9452 datasheet 7.1 Features:
https://www.mouser.com/catalog/specsheets/Nxp_03-02-2024_PCA9452.pdf?srsltid=AfmBOooTrgZ1FrPfHYfztxGm5r7YYsBEFRLkx59dIZKMRlk2rsR6nBV6
The BUCK1 is used for VDD_SOC and the BUCK4 is used for NVCC_GPIO/VDD_USB_3P3 on imx93 14x14 board.
Refer to IMX93AEC datasheet 4.1.4 Operating ranges:
https://www.nxp.com/docs/en/data-sheet/IMX93AEC.pdf
BR
Joy Zou
   

From luca.weiss at fairphone.com  Thu Dec  5 23:51:21 2024
From: luca.weiss at fairphone.com (Luca Weiss)
Date: Fri, 06 Dec 2024 08:51:21 +0100
Subject: [PATCH v7 3/5] media: qcom: camss: Add support for camss driver
 on sc7280
In-Reply-To: <20241204100003.300123-4-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-4-quic_vikramsa@quicinc.com>
Message-ID: <D64GCT2CXFLC.33Y61JJ8XFCHO@fairphone.com>

On Wed Dec 4, 2024 at 11:00 AM CET, Vikram Sharma wrote:
> From: Suresh Vankadara <quic_svankada at quicinc.com>
>
> Add support for the camss driver on the sc7280 soc.
>
> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>

Hi Vikram,

This is working on QCM6490 Fairphone 5 smartphone with WIP drivers for
IMX858 and S5KJN1, thanks!

Tested-by: Luca Weiss <luca.weiss at fairphone.com> # qcm6490-fairphone-fp5

Regards
Luca

> ---
>  .../qcom/camss/camss-csiphy-3ph-1-0.c         |   5 +
>  .../media/platform/qcom/camss/camss-csiphy.c  |   5 +
>  .../media/platform/qcom/camss/camss-csiphy.h  |   1 +
>  drivers/media/platform/qcom/camss/camss-vfe.c |   2 +
>  drivers/media/platform/qcom/camss/camss.c     | 319 ++++++++++++++++++
>  drivers/media/platform/qcom/camss/camss.h     |   1 +
>  6 files changed, 333 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
> index 7d2490c9de01..f341f7b7fd8a 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
> @@ -505,6 +505,10 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
>  	u32 val;
>  
>  	switch (csiphy->camss->res->version) {
> +	case CAMSS_7280:
> +		r = &lane_regs_sm8250[0][0];
> +		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
> +		break;
>  	case CAMSS_8250:
>  		r = &lane_regs_sm8250[0][0];
>  		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
> @@ -557,6 +561,7 @@ static bool csiphy_is_gen2(u32 version)
>  	bool ret = false;
>  
>  	switch (version) {
> +	case CAMSS_7280:
>  	case CAMSS_8250:
>  	case CAMSS_8280XP:
>  	case CAMSS_845:
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
> index 5af2b382a843..3791c2d8a6cf 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
> @@ -103,6 +103,11 @@ const struct csiphy_formats csiphy_formats_8x96 = {
>  	.formats = formats_8x96
>  };
>  
> +const struct csiphy_formats csiphy_formats_sc7280 = {
> +	.nformats = ARRAY_SIZE(formats_sdm845),
> +	.formats = formats_sdm845
> +};
> +
>  const struct csiphy_formats csiphy_formats_sdm845 = {
>  	.nformats = ARRAY_SIZE(formats_sdm845),
>  	.formats = formats_sdm845
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
> index eebc1ff1cfab..b6209bddfb61 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.h
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
> @@ -111,6 +111,7 @@ void msm_csiphy_unregister_entity(struct csiphy_device *csiphy);
>  
>  extern const struct csiphy_formats csiphy_formats_8x16;
>  extern const struct csiphy_formats csiphy_formats_8x96;
> +extern const struct csiphy_formats csiphy_formats_sc7280;
>  extern const struct csiphy_formats csiphy_formats_sdm845;
>  
>  extern const struct csiphy_hw_ops csiphy_ops_2ph_1_0;
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index fb3234c65403..95f6a1ac7eaf 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -335,6 +335,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
>  		}
>  		break;
>  	case CAMSS_660:
> +	case CAMSS_7280:
>  	case CAMSS_8x96:
>  	case CAMSS_8250:
>  	case CAMSS_8280XP:
> @@ -1693,6 +1694,7 @@ static int vfe_bpl_align(struct vfe_device *vfe)
>  	int ret = 8;
>  
>  	switch (vfe->camss->res->version) {
> +	case CAMSS_7280:
>  	case CAMSS_8250:
>  	case CAMSS_8280XP:
>  	case CAMSS_845:
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index f5704c23766a..4fa16ff6e614 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -1266,6 +1266,310 @@ static const struct resources_icc icc_res_sm8250[] = {
>  	},
>  };
>  
> +static const struct camss_subdev_resources csiphy_res_7280[] = {
> +	/* CSIPHY0 */
> +	{
> +		.regulators = { "vdda-phy", "vdda-pll" },
> +
> +		.clock = { "csiphy0", "csiphy0_timer" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 300000000 } },
> +		.reg = { "csiphy0" },
> +		.interrupt = { "csiphy0" },
> +		.csiphy = {
> +			.hw_ops = &csiphy_ops_3ph_1_0,
> +			.formats = &csiphy_formats_sc7280
> +		}
> +	},
> +	/* CSIPHY1 */
> +	{
> +		.regulators = { "vdda-phy", "vdda-pll" },
> +
> +		.clock = { "csiphy1", "csiphy1_timer" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 300000000 } },
> +		.reg = { "csiphy1" },
> +		.interrupt = { "csiphy1" },
> +		.csiphy = {
> +			.hw_ops = &csiphy_ops_3ph_1_0,
> +			.formats = &csiphy_formats_sc7280
> +		}
> +	},
> +	/* CSIPHY2 */
> +	{
> +		.regulators = { "vdda-phy", "vdda-pll" },
> +
> +		.clock = { "csiphy2", "csiphy2_timer" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 300000000 } },
> +		.reg = { "csiphy2" },
> +		.interrupt = { "csiphy2" },
> +		.csiphy = {
> +			.hw_ops = &csiphy_ops_3ph_1_0,
> +			.formats = &csiphy_formats_sc7280
> +		}
> +	},
> +	/* CSIPHY3 */
> +	{
> +		.regulators = { "vdda-phy", "vdda-pll" },
> +
> +		.clock = { "csiphy3", "csiphy3_timer" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 300000000 } },
> +		.reg = { "csiphy3" },
> +		.interrupt = { "csiphy3" },
> +		.csiphy = {
> +			.hw_ops = &csiphy_ops_3ph_1_0,
> +			.formats = &csiphy_formats_sc7280
> +		}
> +	},
> +	/* CSIPHY4 */
> +	{
> +		.regulators = { "vdda-phy", "vdda-pll" },
> +
> +		.clock = { "csiphy4", "csiphy4_timer" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 300000000 } },
> +		.reg = { "csiphy4" },
> +		.interrupt = { "csiphy4" },
> +		.csiphy = {
> +			.hw_ops = &csiphy_ops_3ph_1_0,
> +			.formats = &csiphy_formats_sc7280
> +		}
> +	},
> +};
> +
> +static const struct camss_subdev_resources csid_res_7280[] = {
> +	/* CSID0 */
> +	{
> +		.regulators = {},
> +
> +		.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 0 },
> +				{ 380000000, 510000000, 637000000, 760000000 }
> +		},
> +
> +		.reg = { "csid0" },
> +		.interrupt = { "csid0" },
> +		.csid = {
> +			.is_lite = false,
> +			.hw_ops = &csid_ops_gen2,
> +			.parent_dev_ops = &vfe_parent_dev_ops,
> +			.formats = &csid_formats_gen2
> +		}
> +	},
> +	/* CSID1 */
> +	{
> +		.regulators = {},
> +
> +		.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 0 },
> +				{ 380000000, 510000000, 637000000, 760000000 }
> +		},
> +
> +		.reg = { "csid1" },
> +		.interrupt = { "csid1" },
> +		.csid = {
> +			.is_lite = false,
> +			.hw_ops = &csid_ops_gen2,
> +			.parent_dev_ops = &vfe_parent_dev_ops,
> +			.formats = &csid_formats_gen2
> +		}
> +	},
> +	/* CSID2 */
> +	{
> +		.regulators = {},
> +
> +		.clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 0 },
> +				{ 380000000, 510000000, 637000000, 760000000 }
> +		},
> +
> +		.reg = { "csid2" },
> +		.interrupt = { "csid2" },
> +		.csid = {
> +			.is_lite = false,
> +			.hw_ops = &csid_ops_gen2,
> +			.parent_dev_ops = &vfe_parent_dev_ops,
> +			.formats = &csid_formats_gen2
> +		}
> +	},
> +	/* CSID3 */
> +	{
> +		.regulators = {},
> +
> +		.clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 0 },
> +				{ 320000000, 400000000, 480000000, 600000000 }
> +		},
> +
> +		.reg = { "csid_lite0" },
> +		.interrupt = { "csid_lite0" },
> +		.csid = {
> +			.is_lite = true,
> +			.hw_ops = &csid_ops_gen2,
> +			.parent_dev_ops = &vfe_parent_dev_ops,
> +			.formats = &csid_formats_gen2
> +		}
> +	},
> +	/* CSID4 */
> +	{
> +		.regulators = {},
> +
> +		.clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
> +		.clock_rate = { { 300000000, 400000000 },
> +				{ 0 },
> +				{ 320000000, 400000000, 480000000, 600000000 }
> +		},
> +
> +		.reg = { "csid_lite1" },
> +		.interrupt = { "csid_lite1" },
> +		.csid = {
> +			.is_lite = true,
> +			.hw_ops = &csid_ops_gen2,
> +			.parent_dev_ops = &vfe_parent_dev_ops,
> +			.formats = &csid_formats_gen2
> +		}
> +	},
> +};
> +
> +static const struct camss_subdev_resources vfe_res_7280[] = {
> +	/* VFE0 */
> +	{
> +		.regulators = {},
> +
> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0",
> +			   "vfe0_axi", "gcc_cam_hf_axi" },
> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
> +				{ 80000000 },
> +				{ 0 },
> +				{ 380000000, 510000000, 637000000, 760000000 },
> +				{ 0 },
> +				{ 0 } },
> +
> +		.reg = { "vfe0" },
> +		.interrupt = { "vfe0" },
> +		.vfe = {
> +			.line_num = 3,
> +			.is_lite = false,
> +			.has_pd = true,
> +			.pd_name = "ife0",
> +			.hw_ops = &vfe_ops_170,
> +			.formats_rdi = &vfe_formats_rdi_845,
> +			.formats_pix = &vfe_formats_pix_845
> +		}
> +	},
> +	/* VFE1 */
> +	{
> +		.regulators = {},
> +
> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe1",
> +			   "vfe1_axi", "gcc_cam_hf_axi" },
> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
> +				{ 80000000 },
> +				{ 0 },
> +				{ 380000000, 510000000, 637000000, 760000000 },
> +				{ 0 },
> +				{ 0 } },
> +
> +		.reg = { "vfe1" },
> +		.interrupt = { "vfe1" },
> +		.vfe = {
> +			.line_num = 3,
> +			.is_lite = false,
> +			.has_pd = true,
> +			.pd_name = "ife1",
> +			.hw_ops = &vfe_ops_170,
> +			.formats_rdi = &vfe_formats_rdi_845,
> +			.formats_pix = &vfe_formats_pix_845
> +		}
> +	},
> +	/* VFE2 */
> +	{
> +		.regulators = {},
> +
> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe2",
> +			   "vfe2_axi", "gcc_cam_hf_axi" },
> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
> +				{ 80000000 },
> +				{ 0 },
> +				{ 380000000, 510000000, 637000000, 760000000 },
> +				{ 0 },
> +				{ 0 } },
> +
> +		.reg = { "vfe2" },
> +		.interrupt = { "vfe2" },
> +		.vfe = {
> +			.line_num = 3,
> +			.is_lite = false,
> +			.hw_ops = &vfe_ops_170,
> +			.has_pd = true,
> +			.pd_name = "ife2",
> +			.formats_rdi = &vfe_formats_rdi_845,
> +			.formats_pix = &vfe_formats_pix_845
> +		}
> +	},
> +	/* VFE3 (lite) */
> +	{
> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
> +			   "vfe_lite0", "gcc_cam_hf_axi" },
> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
> +				{ 80000000 },
> +				{ 0 },
> +				{ 320000000, 400000000, 480000000, 600000000 },
> +				{ 0 } },
> +
> +		.regulators = {},
> +		.reg = { "vfe_lite0" },
> +		.interrupt = { "vfe_lite0" },
> +		.vfe = {
> +			.line_num = 4,
> +			.is_lite = true,
> +			.hw_ops = &vfe_ops_170,
> +			.formats_rdi = &vfe_formats_rdi_845,
> +			.formats_pix = &vfe_formats_pix_845
> +		}
> +	},
> +	/* VFE4 (lite) */
> +	{
> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
> +			   "vfe_lite1", "gcc_cam_hf_axi" },
> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
> +				{ 80000000 },
> +				{ 0 },
> +				{ 320000000, 400000000, 480000000, 600000000 },
> +				{ 0 } },
> +
> +		.regulators = {},
> +		.reg = { "vfe_lite1" },
> +		.interrupt = { "vfe_lite1" },
> +		.vfe = {
> +			.line_num = 4,
> +			.is_lite = true,
> +			.hw_ops = &vfe_ops_170,
> +			.formats_rdi = &vfe_formats_rdi_845,
> +			.formats_pix = &vfe_formats_pix_845
> +		}
> +	},
> +};
> +
> +static const struct resources_icc icc_res_sc7280[] = {
> +	{
> +		.name = "ahb",
> +		.icc_bw_tbl.avg = 38400,
> +		.icc_bw_tbl.peak = 76800,
> +	},
> +	{
> +		.name = "hf_0",
> +		.icc_bw_tbl.avg = 2097152,
> +		.icc_bw_tbl.peak = 2097152,
> +	},
> +};
> +
>  static const struct camss_subdev_resources csiphy_res_sc8280xp[] = {
>  	/* CSIPHY0 */
>  	{
> @@ -2622,10 +2926,25 @@ static const struct camss_resources sc8280xp_resources = {
>  	.link_entities = camss_link_entities
>  };
>  
> +static const struct camss_resources sc7280_resources = {
> +	.version = CAMSS_7280,
> +	.pd_name = "top",
> +	.csiphy_res = csiphy_res_7280,
> +	.csid_res = csid_res_7280,
> +	.vfe_res = vfe_res_7280,
> +	.icc_res = icc_res_sc7280,
> +	.icc_path_num = ARRAY_SIZE(icc_res_sc7280),
> +	.csiphy_num = ARRAY_SIZE(csiphy_res_7280),
> +	.csid_num = ARRAY_SIZE(csid_res_7280),
> +	.vfe_num = ARRAY_SIZE(vfe_res_7280),
> +	.link_entities = camss_link_entities
> +};
> +
>  static const struct of_device_id camss_dt_match[] = {
>  	{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
>  	{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
>  	{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
> +	{ .compatible = "qcom,sc7280-camss", .data = &sc7280_resources },
>  	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
>  	{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
>  	{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
> index ffce0a0edbc5..9a046eea334f 100644
> --- a/drivers/media/platform/qcom/camss/camss.h
> +++ b/drivers/media/platform/qcom/camss/camss.h
> @@ -78,6 +78,7 @@ enum pm_domain {
>  
>  enum camss_version {
>  	CAMSS_660,
> +	CAMSS_7280,
>  	CAMSS_8x16,
>  	CAMSS_8x53,
>  	CAMSS_8x96,



From ptesarik at suse.com  Thu Dec  5 23:50:26 2024
From: ptesarik at suse.com (Petr Tesarik)
Date: Fri, 6 Dec 2024 08:50:26 +0100
Subject: [RFC PATCH v1 00/57] Boot-time page size selection for arm64
In-Reply-To: <SN6PR02MB41571E0BD384C44C46127B49D4302@SN6PR02MB4157.namprd02.prod.outlook.com>
References: <20241014105514.3206191-1-ryan.roberts@arm.com>
	<20241017142752.17f2c816@mordecai.tesarici.cz>
	<aa9a7118-3067-448e-aa34-bbc148c921a2@arm.com>
	<20241205182008.2b36476a@mordecai.tesarici.cz>
	<SN6PR02MB41571E0BD384C44C46127B49D4302@SN6PR02MB4157.namprd02.prod.outlook.com>
Message-ID: <20241206085026.32c89a03@mordecai.tesarici.cz>

On Thu, 5 Dec 2024 18:52:35 +0000
Michael Kelley <mhklinux at outlook.com> wrote:

> From: Petr Tesarik <ptesarik at suse.com> Sent: Thursday, December 5, 2024 9:20 AM
> > 
> > Hi Ryan,
> > 
> > On Thu, 17 Oct 2024 13:32:43 +0100
> > Ryan Roberts <ryan.roberts at arm.com> wrote:
> >   
> > > On 17/10/2024 13:27, Petr Tesarik wrote:  
> > > > On Mon, 14 Oct 2024 11:55:11 +0100
> > > > Ryan Roberts <ryan.roberts at arm.com> wrote:
> > > >  
> > > >> [...]
> > > >> The series is arranged as follows:
> > > >>
> > > >>   - patch 1:	   Add macros required for converting non-arch code to support
> > > >>   		   boot-time page size selection
> > > >>   - patches 2-36:  Remove PAGE_SIZE compile-time constant assumption from all
> > > >>   		   non-arch code  
> > > >
> > > > I have just tried to recompile the openSUSE kernel with these patches
> > > > applied, and I'm running into this:
> > > >
> > > >   CC      arch/arm64/hyperv/hv_core.o
> > > > In file included from ../arch/arm64/hyperv/hv_core.c:14:0:
> > > > ../include/linux/hyperv.h:158:5: error: variably modified ?reserved2? at file scope
> > > >   u8 reserved2[PAGE_SIZE - 68];
> > > >      ^~~~~~~~~
> > > >
> > > > It looks like one more place which needs a patch, right?  
> > >
> > > As mentioned in the cover letter, so far I've only converted enough to get the
> > > defconfig *image* building (i.e. no modules). If you are compiling a different
> > > config or compiling the modules for defconfig, you will likely run into these
> > > types of issues.
> > >
> > > That said, I do have some patches to fix Hyper-V, which Michael Kelley was kind
> > > enough to send me.
> > >
> > > I understand that Suse might be able to help with wider performance testing - if
> > > that's the reason you are trying to compile, you could send me your config and
> > > I'll start working on fixing up other drivers?  
> > 
> > This project was de-prioritised for some time, but I have just returned
> > to it, and one of our test systems uses a Mellanox 5 NIC, which did not build.
> > 
> > If you still have time to work on your patch series, please, can you
> > look into enabling MLX5_CORE_EN?
> > 
> > Oh, and have you rebased the series to 6.12 yet?
> >   
> 
> FWIW, here's what I hacked together to compile and run the mlx5 driver in
> a Hyper-V VM.  This was against a 6.11 kernel code base.

Wow! Thank you, Michael. I'll give it a try.

Petr T


From luca.weiss at fairphone.com  Thu Dec  5 23:51:38 2024
From: luca.weiss at fairphone.com (Luca Weiss)
Date: Fri, 06 Dec 2024 08:51:38 +0100
Subject: [PATCH v7 4/5] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <20241204100003.300123-5-quic_vikramsa@quicinc.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-5-quic_vikramsa@quicinc.com>
Message-ID: <D64GD0NCHTO3.2W6LZKBMNE8UU@fairphone.com>

On Wed Dec 4, 2024 at 11:00 AM CET, Vikram Sharma wrote:
> Add changes to support the camera subsystem on the SC7280.
>
> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>

Hi Vikram,

This is working on QCM6490 Fairphone 5 smartphone with WIP drivers for
IMX858 and S5KJN1, thanks!

Tested-by: Luca Weiss <luca.weiss at fairphone.com> # qcm6490-fairphone-fp5

Regards
Luca

> ---
>  arch/arm64/boot/dts/qcom/sc7280.dtsi | 172 +++++++++++++++++++++++++++
>  1 file changed, 172 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> index 55db1c83ef55..e363996602d6 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> @@ -4426,6 +4426,178 @@ cci1_i2c1: i2c-bus at 1 {
>  			};
>  		};
>  
> +		camss: camss at acb3000 {
> +			compatible = "qcom,sc7280-camss";
> +
> +			reg = <0x0 0x0acb3000 0x0 0x1000>,
> +			      <0x0 0x0acba000 0x0 0x1000>,
> +			      <0x0 0x0acc1000 0x0 0x1000>,
> +			      <0x0 0x0acc8000 0x0 0x1000>,
> +			      <0x0 0x0accf000 0x0 0x1000>,
> +			      <0x0 0x0ace0000 0x0 0x2000>,
> +			      <0x0 0x0ace2000 0x0 0x2000>,
> +			      <0x0 0x0ace4000 0x0 0x2000>,
> +			      <0x0 0x0ace6000 0x0 0x2000>,
> +			      <0x0 0x0ace8000 0x0 0x2000>,
> +			      <0x0 0x0acaf000 0x0 0x4000>,
> +			      <0x0 0x0acb6000 0x0 0x4000>,
> +			      <0x0 0x0acbd000 0x0 0x4000>,
> +			      <0x0 0x0acc4000 0x0 0x4000>,
> +			      <0x0 0x0accb000 0x0 0x4000>;
> +			reg-names = "csid0",
> +				    "csid1",
> +				    "csid2",
> +				    "csid_lite0",
> +				    "csid_lite1",
> +				    "csiphy0",
> +				    "csiphy1",
> +				    "csiphy2",
> +				    "csiphy3",
> +				    "csiphy4",
> +				    "vfe0",
> +				    "vfe1",
> +				    "vfe2",
> +				    "vfe_lite0",
> +				    "vfe_lite1";
> +
> +			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
> +				 <&camcc CAM_CC_CPAS_AHB_CLK>,
> +				 <&camcc CAM_CC_CSIPHY0_CLK>,
> +				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
> +				 <&camcc CAM_CC_CSIPHY1_CLK>,
> +				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
> +				 <&camcc CAM_CC_CSIPHY2_CLK>,
> +				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
> +				 <&camcc CAM_CC_CSIPHY3_CLK>,
> +				 <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
> +				 <&camcc CAM_CC_CSIPHY4_CLK>,
> +				 <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
> +				 <&gcc GCC_CAMERA_AHB_CLK>,
> +				 <&gcc GCC_CAMERA_HF_AXI_CLK>,
> +				 <&camcc CAM_CC_ICP_AHB_CLK>,
> +				 <&camcc CAM_CC_IFE_0_CLK>,
> +				 <&camcc CAM_CC_IFE_0_AXI_CLK>,
> +				 <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_0_CSID_CLK>,
> +				 <&camcc CAM_CC_IFE_1_CLK>,
> +				 <&camcc CAM_CC_IFE_1_AXI_CLK>,
> +				 <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_1_CSID_CLK>,
> +				 <&camcc CAM_CC_IFE_2_CLK>,
> +				 <&camcc CAM_CC_IFE_2_AXI_CLK>,
> +				 <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_2_CSID_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_0_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_1_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>;
> +			clock-names = "camnoc_axi",
> +				      "cpas_ahb",
> +				      "csiphy0",
> +				      "csiphy0_timer",
> +				      "csiphy1",
> +				      "csiphy1_timer",
> +				      "csiphy2",
> +				      "csiphy2_timer",
> +				      "csiphy3",
> +				      "csiphy3_timer",
> +				      "csiphy4",
> +				      "csiphy4_timer",
> +				      "gcc_camera_ahb",
> +				      "gcc_cam_hf_axi",
> +				      "icp_ahb",
> +				      "vfe0",
> +				      "vfe0_axi",
> +				      "vfe0_cphy_rx",
> +				      "vfe0_csid",
> +				      "vfe1",
> +				      "vfe1_axi",
> +				      "vfe1_cphy_rx",
> +				      "vfe1_csid",
> +				      "vfe2",
> +				      "vfe2_axi",
> +				      "vfe2_cphy_rx",
> +				      "vfe2_csid",
> +				      "vfe_lite0",
> +				      "vfe_lite0_cphy_rx",
> +				      "vfe_lite0_csid",
> +				      "vfe_lite1",
> +				      "vfe_lite1_cphy_rx",
> +				      "vfe_lite1_csid";
> +
> +			interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
> +				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
> +			interrupt-names = "csid0",
> +					  "csid1",
> +					  "csid2",
> +					  "csid_lite0",
> +					  "csid_lite1",
> +					  "csiphy0",
> +					  "csiphy1",
> +					  "csiphy2",
> +					  "csiphy3",
> +					  "csiphy4",
> +					  "vfe0",
> +					  "vfe1",
> +					  "vfe2",
> +					  "vfe_lite0",
> +					  "vfe_lite1";
> +
> +			interconnects = <&gem_noc  MASTER_APPSS_PROC 0 &cnoc2 SLAVE_CAMERA_CFG 0>,
> +					<&mmss_noc MASTER_CAMNOC_HF  0 &mc_virt SLAVE_EBI1     0>;
> +			interconnect-names = "ahb", "hf_0";
> +
> +			iommus = <&apps_smmu 0x800 0x4e0>;
> +
> +			power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
> +					<&camcc CAM_CC_IFE_1_GDSC>,
> +					<&camcc CAM_CC_IFE_2_GDSC>,
> +					<&camcc CAM_CC_TITAN_TOP_GDSC>;
> +			power-domain-names = "ife0", "ife1", "ife2", "top";
> +
> +			status = "disabled";
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				port at 0 {
> +					reg = <0>;
> +				};
> +
> +				port at 1 {
> +					reg = <1>;
> +				};
> +
> +				port at 2 {
> +					reg = <2>;
> +				};
> +
> +				port at 3 {
> +					reg = <3>;
> +				};
> +
> +				port at 4 {
> +					reg = <4>;
> +				};
> +			};
> +		};
> +
>  		camcc: clock-controller at ad00000 {
>  			compatible = "qcom,sc7280-camcc";
>  			reg = <0 0x0ad00000 0 0x10000>;



From lkp at intel.com  Thu Dec  5 23:58:50 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 6 Dec 2024 15:58:50 +0800
Subject: [PATCH v1 3/3] clk: samsung: Introduce Exynos990 clock
 controller driver
In-Reply-To: <20241205193423.783815-4-igor.belwon@mentallysanemainliners.org>
References: <20241205193423.783815-4-igor.belwon@mentallysanemainliners.org>
Message-ID: <202412061549.wyFF9u8X-lkp@intel.com>

Hi Igor,

kernel test robot noticed the following build errors:

[auto build test ERROR on krzk/for-next]
[also build test ERROR on krzk-dt/for-next clk/clk-next linus/master v6.13-rc1 next-20241205]
[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/Igor-Belwon/clk-samsung-clk-pll-Add-support-for-pll_-0717x-0718x-0732x/20241206-043559
base:   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git for-next
patch link:    https://lore.kernel.org/r/20241205193423.783815-4-igor.belwon%40mentallysanemainliners.org
patch subject: [PATCH v1 3/3] clk: samsung: Introduce Exynos990 clock controller driver
config: arm64-randconfig-004-20241206 (https://download.01.org/0day-ci/archive/20241206/202412061549.wyFF9u8X-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241206/202412061549.wyFF9u8X-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/202412061549.wyFF9u8X-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/clk/samsung/clk-exynos990.c:13:10: fatal error: 'dt-bindings/clock/exynos990.h' file not found
      13 | #include <dt-bindings/clock/exynos990.h>
         |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 error generated.


vim +13 drivers/clk/samsung/clk-exynos990.c

    12	
  > 13	#include <dt-bindings/clock/exynos990.h>
    14	

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


From quic_yuanfang at quicinc.com  Fri Dec  6 00:02:40 2024
From: quic_yuanfang at quicinc.com (yuanfang zhang)
Date: Fri, 6 Dec 2024 16:02:40 +0800
Subject: [PATCH v3] coresight-etm4x: add isb() before reading the TRCSTATR
Message-ID: <20241206080240.59313-1-quic_yuanfang@quicinc.com>

From: Yuanfang Zhang <quic_yuanfang at quicinc.com>

As recommended by section 4.3.7 ("Synchronization when using system
instructions to progrom the trace unit") of ARM IHI 0064H.b, the
self-hosted trace analyzer must perform a Context synchronization
event between writing to the TRCPRGCTLR and reading the TRCSTATR.

Fixes: ebddaad09e10 ("coresight: etm4x: Add missing single-shot control API to sysfs")
Signed-off-by: Yuanfang Zhang <quic_yuanfang at quicinc.com>
---
Changes in V3:
1. Remove dsb(sy) after polling TRCSTATR.
2. Add isb() after polling TRCSTATR.
---
 .../hwtracing/coresight/coresight-etm4x-core.c   | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 66d44a404ad0..c6ea00bba0cc 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -531,7 +531,6 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
 	 * As recommended by section 4.3.7 ("Synchronization when using the
 	 * memory-mapped interface") of ARM IHI 0064D
 	 */
-	dsb(sy);
 	isb();
 
 done:
@@ -906,10 +905,25 @@ static void etm4_disable_hw(void *info)
 	tsb_csync();
 	etm4x_relaxed_write32(csa, control, TRCPRGCTLR);
 
+	/*
+	 * As recommended by section 4.3.7 ("Synchronization when using system
+	 * instructions to progrom the trace unit") of ARM IHI 0064H.b, the
+	 * self-hosted trace analyzer must perform a Context synchronization
+	 * event between writing to the TRCPRGCTLR and reading the TRCSTATR.
+	 */
+	if (!csa->io_mem)
+		isb();
+
 	/* wait for TRCSTATR.PMSTABLE to go to '1' */
 	if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1))
 		dev_err(etm_dev,
 			"timeout while waiting for PM stable Trace Status\n");
+	/*
+	 * As recommended by section 4.3.7 (Synchronization of register updates)
+	 * of ARM IHI 0064H.b.
+	 */
+	isb();
+
 	/* read the status of the single shot comparators */
 	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
 		config->ss_status[i] =
-- 
2.34.1



From arnd at arndb.de  Fri Dec  6 00:04:02 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 06 Dec 2024 09:04:02 +0100
Subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
 <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
Message-ID: <2005af5d-bdb7-4675-8f0e-82cb817801af@app.fastmail.com>

On Fri, Dec 6, 2024, at 08:09, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>
> Add a RTC driver for NXP S32G2/S32G3 SoCs.
>
> RTC tracks clock time during system suspend. It can be a wakeup source
> for the S32G2/S32G3 SoC based boards.
>
> The RTC module from S32G2/S32G3 is not battery-powered and it is not kept
> alive during system reset.
>
> Co-developed-by: Bogdan Hamciuc <bogdan.hamciuc at nxp.com>
> Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc at nxp.com>
> Co-developed-by: Ghennadi Procopciuc <Ghennadi.Procopciuc at nxp.com>
> Signed-off-by: Ghennadi Procopciuc <Ghennadi.Procopciuc at nxp.com>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

I read through the driver and this looks all good to me, but there
are two fairly minor things I noticed:

> +	u64 rtc_hz;

I see the clock rate is a 64-bit value, which is clearly what
comes from the clk interface in the kernel

> +static u64 cycles_to_sec(u64 hz, u64 cycles)
> +{
> +	return div_u64(cycles, hz);
> +}

and you divide by the clk rate to convert the register value
to seconds (as expected)

> +	u32 delta_cnt;
> +
> +	if (!seconds || seconds > cycles_to_sec(priv->rtc_hz, RTCCNT_MAX_VAL))
> +		return -EINVAL;

However, the range of the register value is only 32 bits,
which means there is no need to ever divide it by a 64-bit
number, and with the 32kHz clock in the binding example,
you only have about 37 hours worth of range here.

It would appear that this makes the rtc unsuitable for
storing absolute time across reboots, and only serve during
runtime, which is a limitation you should probably document.

> +static s64 s32g_rtc_get_time_or_alrm(struct rtc_priv *priv,
> +				     u32 offset)
> +{
> +	u32 counter;
> +
> +	counter = ioread32(priv->rtc_base + offset);
> +
> +	if (counter < priv->base.cycles)
> +		return -EINVAL;

If 'counter' wraps every 37 hours, this will inevitably fail,
right? E.g. if priv->base.cycles was already at a large
32-bit number, even reading it shortly later will produce
a small value after the wraparound.

Using something like time_before() should address this,
but I think you may need a custom version that works on
32-bit numbers.

> +static int s32g_rtc_resume(struct device *dev)
> +{
> +	struct rtc_priv *priv = dev_get_drvdata(dev);
> +	int ret;
> +
> +	if (!device_may_wakeup(dev))
> +		return 0;
> +
> +	/* Disable wake-up interrupts */
> +	s32g_enable_api_irq(dev, 0);
> +
> +	ret = rtc_clk_src_setup(priv);
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * Now RTCCNT has just been reset, and is out of sync with priv->base;
> +	 * reapply the saved time settings.
> +	 */
> +	return s32g_rtc_set_time(dev, &priv->base.tm);
> +}

This also fails if the system has been suspended for more than
37 hours, right?

One more minor comment: you are using ioread32()/iowrite32()
to access the MMIO registers, which is a bit unusual. I would
suggest changing those to the more common readl()/writel()
that do the exact same thing on arm64.

        Arnd


From geert+renesas at glider.be  Fri Dec  6 00:28:06 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri,  6 Dec 2024 09:28:06 +0100
Subject: [PATCH] i2c: nomadik: Add missing sentinel to match table
Message-ID: <34b6ee90437fe19526d9388f2f304d175596cb1f.1733473582.git.geert+renesas@glider.be>

The OF match table is not NULL-terminated.
Fix this by adding a sentinel to nmk_i2c_eyeq_match_table[].

Fixes: a0d15cc47f29be6d ("i2c: nomadik: switch from of_device_is_compatible() to of_match_device()")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 drivers/i2c/busses/i2c-nomadik.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index efb33802804fdde8..d2877e4cc28d42c9 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -1075,6 +1075,7 @@ static const struct of_device_id nmk_i2c_eyeq_match_table[] = {
 		.compatible = "mobileye,eyeq6h-i2c",
 		.data = (void *)NMK_I2C_EYEQ_FLAG_32B_BUS,
 	},
+	{ /* sentinel */ }
 };
 
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
-- 
2.34.1



From muecker at gwdg.de  Fri Dec  6 00:29:28 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Fri, 6 Dec 2024 09:29:28 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
Message-ID: <c5e037ab5a5718dfba9d1c8c8b57ee53765a851b.camel@gwdg.de>

Am Donnerstag, dem 05.12.2024 um 22:14 -0800 schrieb Linus Torvalds:
> On Thu, 5 Dec 2024 at 18:26, David Laight <David.Laight at aculab.com> wrote:
> > 
> > From: Vincent Mailhol
> > > ACK. Would adding a suggested--by Linus tag solve your concern?
> 
> I'm genberally the one person who doesn't need any more credit ;)
> 
> > I actually suspect the first patches to change __is_constexpr() to
> > use _Generic were from myself.
> 
> Yes. And David was also I think the one who suggested something else
> than "!!" originally too.
> 
> I may have liked "!!" for being very idiomatic and traditional C, but
> there were those pesky compilers that warn about "integer in bool
> context" or whatever the annoying warning was when then doing the
> "multiply by zero" to turn a constant expression into a constant zero
> expression.
> 
> So that
> 
>   #define is_const(x) __is_const_zero(0 * (x))
> 
> causes issues when 'x' is not an integer expression (think
> "is_const(NULL)" or "is_const(1 == 2)".
> 
> Side note: I think "(x) == 0" will make sparse unhappy when 'x' is a
> pointer, because it results that horrid "use integer zero as NULL
> without a cast" thing when the plain zero gets implicitly cast to a
> pointer. Which is a really nasty and broken C pattern and should never
> have been silent.


BTW: I added '-Wzero-as-null-pointer-constant' to GCC 15.

Hopefully we can also remove / deprecate this for C2Y.

Martin

> 
> I think David suggested using ((x)?0:0) at some point. Silly
> nonsensical and complex expression, but maybe that finally gets rid of
> all the warnings:
> 
>      #define is_const(x) __is_const_zero((x)?0:0)
> 
> might work regardless of the type of 'x'.
> 
> Or does that trigger some odd case too?




From richard.xnu.clark at gmail.com  Fri Dec  6 00:33:11 2024
From: richard.xnu.clark at gmail.com (richard clark)
Date: Fri, 6 Dec 2024 16:33:11 +0800
Subject: Question about interrupt prioriyt of ARM GICv3/4
Message-ID: <CAJNi4rMfhZOCT+7Ki14vUs+dZbv9cxCZ0s+jgn6=_om4NTgo_A@mail.gmail.com>

Hi,
Currently seems the GICv3/4 irqchip configures all the interrupts as
the same priority, I am thinking about to minimize the latency of the
interrupt for a particular device, e.g, the arm arch_timer in the RTL
system. The question is,
1. Why don't we provide a /proc or /sys interface for the enduser to
set the priority of a specific interrupt(SPI/PPI)?
2. Is there any way to verify the higher priority interrupt will have
more dominant to be selected to the CPU (IOW, the priority is really
working) in case of multiple different interrupts asserted to the GIC
at the same time(some debug registers of GIC like GICD_REEMPT_CNT :-)
to record higher priority wins)?

Thanks


From krzk at kernel.org  Fri Dec  6 00:35:14 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 09:35:14 +0100
Subject: [PATCH v1 0/1] arm64: dts: exynos990: Add cmu nodes
In-Reply-To: <20241205194020.785846-1-igor.belwon@mentallysanemainliners.org>
References: <20241205194020.785846-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <7d9523c4-ba97-496d-ae73-d349aaeb0cd5@kernel.org>

On 05/12/2024 20:40, Igor Belwon wrote:
> Hi all,
> 
> This patchset adds device tree nodes for Exynos990 CMUs (TOP and HSI0).
> 
> This patchset is compile-time and runtime dependent on [1], which adds
> driver support for CMU.
> 
> [1] https://lore.kernel.org/linux-samsung-soc/20241205193423.783815-1-igor.
> belwon at mentallysanemainliners.org/T/#t
> 

Don't wrap links.

> Igor Belwon (1):
>   arm64: dts: exynos990: Add clock management unit nodes
> 
>  arch/arm64/boot/dts/exynos/exynos990.dtsi | 27 +++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 


Best regards,
Krzysztof


From theo.lebrun at bootlin.com  Fri Dec  6 00:35:14 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 06 Dec 2024 09:35:14 +0100
Subject: [PATCH] i2c: nomadik: Add missing sentinel to match table
In-Reply-To: <34b6ee90437fe19526d9388f2f304d175596cb1f.1733473582.git.geert+renesas@glider.be>
References: <34b6ee90437fe19526d9388f2f304d175596cb1f.1733473582.git.geert+renesas@glider.be>
Message-ID: <D64HAEFFEGS1.3FJ6VM6Y6F1M1@bootlin.com>

Hello Geert & all,

On Fri Dec 6, 2024 at 9:28 AM CET, Geert Uytterhoeven wrote:
> The OF match table is not NULL-terminated.
> Fix this by adding a sentinel to nmk_i2c_eyeq_match_table[].

I had the exact same patch pending locally. Sorry and thanks!

Reviewed-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From krzk at kernel.org  Fri Dec  6 00:36:03 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 09:36:03 +0100
Subject: [PATCH v1 1/1] arm64: dts: exynos990: Add clock management unit
 nodes
In-Reply-To: <20241205194020.785846-2-igor.belwon@mentallysanemainliners.org>
References: <20241205194020.785846-1-igor.belwon@mentallysanemainliners.org>
 <20241205194020.785846-2-igor.belwon@mentallysanemainliners.org>
Message-ID: <fdb4af16-468a-4c23-b8f4-ab60d4b535d2@kernel.org>

On 05/12/2024 20:40, Igor Belwon wrote:
> Add CMU nodes for:
> - cmu_top: provides clocks for other blocks
> - cmu_hsi0: provides clocks for usb31
> 
> Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
> ---
>  arch/arm64/boot/dts/exynos/exynos990.dtsi | 27 +++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos990.dtsi b/arch/arm64/boot/dts/exynos/exynos990.dtsi
> index c1986f00e443..49bb1e156843 100644
> --- a/arch/arm64/boot/dts/exynos/exynos990.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos990.dtsi
> @@ -5,6 +5,7 @@
>   * Copyright (c) 2024, Igor Belwon <igor.belwon at mentallysanemainliners.org>
>   */
>  
> +#include <dt-bindings/clock/samsung,exynos990.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>  
>  / {
> @@ -199,6 +200,23 @@ pinctrl_peric1: pinctrl at 10730000 {
>  			interrupts = <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>;
>  		};
>  
> +		cmu_hsi0: clock-controller at 10a00000 {
> +			compatible = "samsung,exynos990-cmu-hsi0";
> +			reg = <0x10a00000 0x8000>;
> +			#clock-cells = <1>;
> +
> +			clocks = <&oscclk>,
> +				 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
> +				 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
> +				 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
> +				 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
> +			clock-names = "oscclk", "dout_cmu_hsi0_bus",

One per line.

> +						"dout_cmu_hsi0_usb31drd",

Misaligned.

> +						"dout_cmu_hsi0_usbdp_debug",
> +						"dout_cmu_hsi0_dpgtc";
> +

Drop stray blank line.

> +		};
> +




Best regards,
Krzysztof


From ulf.hansson at linaro.org  Fri Dec  6 00:40:31 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Fri,  6 Dec 2024 09:40:31 +0100
Subject: [GIT PULL] pmdomain fixes for v6.13-rc2
Message-ID: <20241206084031.119041-1-ulf.hansson@linaro.org>

Hi Linus,

Here's a PR with a couple of pmdomain fixes intended for v6.13-rc2. 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 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git tags/pmdomain-v6.13-rc1

for you to fetch changes up to 2379fb937de5333991c567eefd7d11b98977d059:

  pmdomain: imx: gpcv2: Adjust delay after power up handshake (2024-12-02 17:09:26 +0100)

----------------------------------------------------------------
pmdomain core:
 - Fix a couple of memory-leaks during genpd init/remove

pmdomain providers:
 - imx: Adjust delay for gpcv2 to fix power up handshake
 - mediatek: Fix DT bindings by adding another nested power-domain layer

----------------------------------------------------------------
Fei Shao (1):
      dt-bindings: power: mediatek: Add another nested power-domain layer

Shengjiu Wang (1):
      pmdomain: imx: gpcv2: Adjust delay after power up handshake

Ulf Hansson (2):
      pmdomain: core: Add missing put_device()
      pmdomain: core: Fix error path in pm_genpd_init() when ida alloc fails

 .../bindings/power/mediatek,power-controller.yaml  |  4 +++
 drivers/pmdomain/core.c                            | 37 ++++++++++++----------
 drivers/pmdomain/imx/gpcv2.c                       |  2 +-
 3 files changed, 25 insertions(+), 18 deletions(-)


From krzk at kernel.org  Fri Dec  6 00:48:53 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 09:48:53 +0100
Subject: [PATCH v4 1/1] arm64: dts: exynosautov920: add watchdog DT node
In-Reply-To: <20241206025139.2148833-2-trunixs.kim@samsung.com>
References: <20241206025139.2148833-1-trunixs.kim@samsung.com>
 <CGME20241206025156epcas2p4c55f230accc4354e6f4bf324ab9a5833@epcas2p4.samsung.com>
 <20241206025139.2148833-2-trunixs.kim@samsung.com>
Message-ID: <510e826d-a434-437d-8d2e-3f2618c28b7f@kernel.org>

On 06/12/2024 03:51, Taewan Kim wrote:
> From: Byoungtae Cho <bt.cho at samsung.com>
> 
> Adds two watchdog devices for ExynosAutoV920 SoC.
> 
> Signed-off-by: Byoungtae Cho <bt.cho at samsung.com>
> Signed-off-by: Taewan Kim <trunixs.kim at samsung.com>
> ---
>  .../arm64/boot/dts/exynos/exynosautov920.dtsi | 20 +++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
> index c759134c909e..7b9591255e91 100644
> --- a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
> @@ -183,6 +183,26 @@ cmu_misc: clock-controller at 10020000 {
>  				      "noc";
>  		};
>  
> +		watchdog_cl0: watchdog at 10060000 {

You need to do careful rebase, not just accept whatever tools shown you.

This is now placed in incorrect order - not keeping sorting by unit address.

Best regards,
Krzysztof


From cwweng.linux at gmail.com  Fri Dec  6 00:55:00 2024
From: cwweng.linux at gmail.com (Chi-Wen Weng)
Date: Fri,  6 Dec 2024 16:55:00 +0800
Subject: [PATCH v3 1/2] dt-bindings: pwm: nuvoton: Add MA35D1 pwm
In-Reply-To: <20241206085501.2623772-1-cwweng.linux@gmail.com>
References: <20241206085501.2623772-1-cwweng.linux@gmail.com>
Message-ID: <20241206085501.2623772-2-cwweng.linux@gmail.com>

Add dt-bindings for Nuvoton MA35D1 SoC PWM controller.

Signed-off-by: Chi-Wen Weng <cwweng.linux at gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../bindings/pwm/nuvoton,ma35d1-pwm.yaml      | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/nuvoton,ma35d1-pwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/nuvoton,ma35d1-pwm.yaml b/Documentation/devicetree/bindings/pwm/nuvoton,ma35d1-pwm.yaml
new file mode 100644
index 000000000000..47a59bdd14d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/nuvoton,ma35d1-pwm.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/nuvoton,ma35d1-pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton MA35D1 PWM controller
+
+maintainers:
+  - Chi-Wen Weng <cwweng at nuvoton.com>
+
+allOf:
+  - $ref: pwm.yaml#
+
+properties:
+  compatible:
+    enum:
+      - nuvoton,ma35d1-pwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 3
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+
+    pwm at 40580000 {
+      compatible = "nuvoton,ma35d1-pwm";
+      reg = <0x40580000 0x400>;
+      clocks = <&clk EPWM0_GATE>;
+      #pwm-cells = <3>;
+    };
-- 
2.25.1



From cwweng.linux at gmail.com  Fri Dec  6 00:54:59 2024
From: cwweng.linux at gmail.com (Chi-Wen Weng)
Date: Fri,  6 Dec 2024 16:54:59 +0800
Subject: [PATCH v3 0/2] Add support for nuvoton ma35d1 pwm controller
Message-ID: <20241206085501.2623772-1-cwweng.linux@gmail.com>

This patch series adds pwm driver for the nuvoton ma35d1 ARMv8 SoC.
It includes DT binding documentation and the ma35d1 pwm driver.

v3:
  - Update nuvoton,ma35d1-pwm.yaml
    - Add maintainers entry
    - Increse "#pwm-cells" to 3
  - Update ma35d1 pwm driver
    - Make include header and macros definitions organized alphabetically
    - Rename macros REG_PWM_XXXX to MA35D1_REG_PWM_XXXX
    - Add macros for register address

v2 resend:
  - Remove wrong 'Reviewed-by' tags.

v2:
  - Update nuvoton,ma35d1-pwm.yaml
    - Fix 'maxItems' of 'reg' to 1.
    - Remove unused label
  - Update ma35d1 pwm driver
    - Remove MODULE_ALIAS()
    - Add chip->atomic = true


Chi-Wen Weng (2):
  Add dt-bindings for Nuvoton MA35D1 SoC PWM controller.
  pwm: Add Nuvoton MA35D1 PWM controller support

 .../bindings/pwm/nuvoton,ma35d1-pwm.yaml      |  45 +++++
 drivers/pwm/Kconfig                           |   9 +
 drivers/pwm/Makefile                          |   1 +
 drivers/pwm/pwm-ma35d1.c                      | 179 ++++++++++++++++++
 4 files changed, 234 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/nuvoton,ma35d1-pwm.yaml
 create mode 100644 drivers/pwm/pwm-ma35d1.c

-- 
2.25.1



From cwweng.linux at gmail.com  Fri Dec  6 00:55:01 2024
From: cwweng.linux at gmail.com (Chi-Wen Weng)
Date: Fri,  6 Dec 2024 16:55:01 +0800
Subject: [PATCH v3 2/2] pwm: Add Nuvoton MA35D1 PWM controller support
In-Reply-To: <20241206085501.2623772-1-cwweng.linux@gmail.com>
References: <20241206085501.2623772-1-cwweng.linux@gmail.com>
Message-ID: <20241206085501.2623772-3-cwweng.linux@gmail.com>

This commit adds a generic PWM framework driver for Nuvoton MA35D1 PWM controller.

Signed-off-by: Chi-Wen Weng <cwweng.linux at gmail.com>
---
 drivers/pwm/Kconfig      |   9 ++
 drivers/pwm/Makefile     |   1 +
 drivers/pwm/pwm-ma35d1.c | 179 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 189 insertions(+)
 create mode 100644 drivers/pwm/pwm-ma35d1.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 0915c1e7df16..97b9e83af020 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -411,6 +411,15 @@ config PWM_LPSS_PLATFORM
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-lpss-platform.
 
+config PWM_MA35D1
+	tristate "Nuvoton MA35D1 PWM support"
+	depends on ARCH_MA35 || COMPILE_TEST
+	help
+	  Generic PWM framework driver for Nuvoton MA35D1.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-ma35d1.
+
 config PWM_MESON
 	tristate "Amlogic Meson PWM driver"
 	depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 9081e0c0e9e0..c1d3a1d8add0 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_PWM_LPC32XX)	+= pwm-lpc32xx.o
 obj-$(CONFIG_PWM_LPSS)		+= pwm-lpss.o
 obj-$(CONFIG_PWM_LPSS_PCI)	+= pwm-lpss-pci.o
 obj-$(CONFIG_PWM_LPSS_PLATFORM)	+= pwm-lpss-platform.o
+obj-$(CONFIG_PWM_MA35D1)	+= pwm-ma35d1.o
 obj-$(CONFIG_PWM_MESON)		+= pwm-meson.o
 obj-$(CONFIG_PWM_MEDIATEK)	+= pwm-mediatek.o
 obj-$(CONFIG_PWM_MICROCHIP_CORE)	+= pwm-microchip-core.o
diff --git a/drivers/pwm/pwm-ma35d1.c b/drivers/pwm/pwm-ma35d1.c
new file mode 100644
index 000000000000..380f17b20a3d
--- /dev/null
+++ b/drivers/pwm/pwm-ma35d1.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the Nuvoton MA35D1 PWM controller
+ *
+ * Copyright (C) 2024 Nuvoton Corporation
+ *               Chi-Wen Weng <cwweng at nuvoton.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/math64.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+
+/* The following are registers address offset for MA35D1 PWM controller */
+#define MA35D1_REG_PWM_CTL0            (0x00)
+#define MA35D1_REG_PWM_CNTEN           (0x20)
+#define MA35D1_REG_PWM_PERIOD0         (0x30)
+#define MA35D1_REG_PWM_CMPDAT0         (0x50)
+#define MA35D1_REG_PWM_WGCTL0          (0xB0)
+#define MA35D1_REG_PWM_POLCTL          (0xD4)
+#define MA35D1_REG_PWM_POEN            (0xD8)
+
+/* The following are register address of MA35D1 PWM controller */
+#define MA35D1_PWM_CH_REG_SIZE         4
+#define MA35D1_PWM_CMPDAT0_ADDR(base, ch)     ((base) + MA35D1_REG_PWM_CMPDAT0 + \
+					       ((ch) * MA35D1_PWM_CH_REG_SIZE))
+#define MA35D1_PWM_CNTEN_ADDR(base)           ((base) + MA35D1_REG_PWM_CNTEN)
+#define MA35D1_PWM_PERIOD0_ADDR(base, ch)     ((base) + MA35D1_REG_PWM_PERIOD0 + \
+					       ((ch) * MA35D1_PWM_CH_REG_SIZE))
+#define MA35D1_PWM_POEN_ADDR(base)            ((base) + MA35D1_REG_PWM_POEN)
+#define MA35D1_PWM_POLCTL_ADDR(base)          ((base) + MA35D1_REG_PWM_POLCTL)
+
+#define MA35D1_PWM_MAX_COUNT           0xFFFF
+#define MA35D1_PWM_TOTAL_CHANNELS      6
+
+struct nuvoton_pwm {
+	void __iomem *base;
+	u64 clkrate;
+};
+
+static inline struct nuvoton_pwm *to_nuvoton_pwm(struct pwm_chip *chip)
+{
+	return pwmchip_get_drvdata(chip);
+}
+
+static int nuvoton_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			     const struct pwm_state *state)
+{
+	struct nuvoton_pwm *nvtpwm;
+	u32 ch = pwm->hwpwm;
+
+	nvtpwm = to_nuvoton_pwm(chip);
+	if (state->enabled) {
+		u64 duty_cycles, period_cycles;
+
+		/* Calculate the duty and period cycles */
+		duty_cycles = mul_u64_u64_div_u64(nvtpwm->clkrate,
+						  state->duty_cycle, NSEC_PER_SEC);
+		if (duty_cycles > MA35D1_PWM_MAX_COUNT)
+			duty_cycles = MA35D1_PWM_MAX_COUNT;
+
+		period_cycles = mul_u64_u64_div_u64(nvtpwm->clkrate,
+						    state->period, NSEC_PER_SEC);
+		if (period_cycles > MA35D1_PWM_MAX_COUNT)
+			period_cycles = MA35D1_PWM_MAX_COUNT;
+
+		/* Write the duty and period cycles to registers */
+		writel(duty_cycles, MA35D1_PWM_CMPDAT0_ADDR(nvtpwm->base, ch));
+		writel(period_cycles, MA35D1_PWM_PERIOD0_ADDR(nvtpwm->base, ch));
+		/* Enable counter */
+		writel(readl(MA35D1_PWM_CNTEN_ADDR(nvtpwm->base)) | BIT(ch),
+		       MA35D1_PWM_CNTEN_ADDR(nvtpwm->base));
+		/* Enable output */
+		writel(readl(MA35D1_PWM_POEN_ADDR(nvtpwm->base)) | BIT(ch),
+		       MA35D1_PWM_POEN_ADDR(nvtpwm->base));
+	} else {
+		/* Disable counter */
+		writel(readl(MA35D1_PWM_CNTEN_ADDR(nvtpwm->base)) & ~BIT(ch),
+		       MA35D1_PWM_CNTEN_ADDR(nvtpwm->base));
+		/* Disable output */
+		writel(readl(MA35D1_PWM_POEN_ADDR(nvtpwm->base)) & ~BIT(ch),
+		       MA35D1_PWM_POEN_ADDR(nvtpwm->base));
+	}
+
+	/* Set polarity state to register */
+	if (state->polarity == PWM_POLARITY_NORMAL)
+		writel(readl(MA35D1_PWM_POLCTL_ADDR(nvtpwm->base)) & ~BIT(ch),
+		       MA35D1_PWM_POLCTL_ADDR(nvtpwm->base));
+	else
+		writel(readl(MA35D1_PWM_POLCTL_ADDR(nvtpwm->base)) | BIT(ch),
+		       MA35D1_PWM_POLCTL_ADDR(nvtpwm->base));
+
+	return 0;
+}
+
+static int nuvoton_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+				 struct pwm_state *state)
+{
+	struct nuvoton_pwm *nvtpwm;
+	u32 duty_cycles, period_cycles, cnten, outen, polarity;
+	u32 ch = pwm->hwpwm;
+
+	nvtpwm = to_nuvoton_pwm(chip);
+
+	cnten = readl(MA35D1_PWM_CNTEN_ADDR(nvtpwm->base));
+	outen = readl(MA35D1_PWM_POEN_ADDR(nvtpwm->base));
+	duty_cycles = readl(MA35D1_PWM_CMPDAT0_ADDR(nvtpwm->base, ch));
+	period_cycles = readl(MA35D1_PWM_PERIOD0_ADDR(nvtpwm->base, ch));
+	polarity = readl(MA35D1_PWM_POLCTL_ADDR(nvtpwm->base)) & BIT(ch);
+
+	state->enabled = (cnten & BIT(ch)) && (outen & BIT(ch));
+	state->polarity = polarity ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
+	state->duty_cycle = DIV64_U64_ROUND_UP((u64)duty_cycles * NSEC_PER_SEC, nvtpwm->clkrate);
+	state->period = DIV64_U64_ROUND_UP((u64)period_cycles * NSEC_PER_SEC, nvtpwm->clkrate);
+
+	return 0;
+}
+
+static const struct pwm_ops nuvoton_pwm_ops = {
+	.apply = nuvoton_pwm_apply,
+	.get_state = nuvoton_pwm_get_state,
+};
+
+static int nuvoton_pwm_probe(struct platform_device *pdev)
+{
+	struct pwm_chip *chip;
+	struct nuvoton_pwm *nvtpwm;
+	struct clk *clk;
+	int ret;
+
+	chip = devm_pwmchip_alloc(&pdev->dev, MA35D1_PWM_TOTAL_CHANNELS, sizeof(*nvtpwm));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+
+	nvtpwm = to_nuvoton_pwm(chip);
+
+	nvtpwm->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(nvtpwm->base))
+		return PTR_ERR(nvtpwm->base);
+
+	clk = devm_clk_get_enabled(&pdev->dev, NULL);
+	if (IS_ERR(clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(clk), "unable to get the clock");
+
+	nvtpwm->clkrate = clk_get_rate(clk);
+	if (nvtpwm->clkrate > NSEC_PER_SEC)
+		return dev_err_probe(&pdev->dev, -EINVAL, "pwm clock out of range");
+
+	chip->ops = &nuvoton_pwm_ops;
+	chip->atomic = true;
+
+	ret = devm_pwmchip_add(&pdev->dev, chip);
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "unable to add pwm chip");
+
+	return 0;
+}
+
+static const struct of_device_id nuvoton_pwm_of_match[] = {
+	{ .compatible = "nuvoton,ma35d1-pwm" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, nuvoton_pwm_of_match);
+
+static struct platform_driver nuvoton_pwm_driver = {
+	.probe = nuvoton_pwm_probe,
+	.driver = {
+		.name = "nuvoton-pwm",
+		.of_match_table = nuvoton_pwm_of_match,
+	},
+};
+module_platform_driver(nuvoton_pwm_driver);
+
+MODULE_AUTHOR("Chi-Wen Weng <cwweng at nuvoton.com>");
+MODULE_DESCRIPTION("Nuvoton MA35D1 PWM driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From peng.fan at nxp.com  Fri Dec  6 00:58:57 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 6 Dec 2024 08:58:57 +0000
Subject: [PATCH v2 2/2] arm64: dt: imx93-tqma9352-mba93xxla: enable Open
 Drain for MDIO
In-Reply-To: <20241205150730.3132807-2-alexander.stein@ew.tq-group.com>
References: <20241205150730.3132807-1-alexander.stein@ew.tq-group.com>
 <20241205150730.3132807-2-alexander.stein@ew.tq-group.com>
Message-ID: <PAXPR04MB84599E8D7322514C6645651088312@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 2/2] arm64: dt: imx93-tqma9352-mba93xxla:
> enable Open Drain for MDIO

s/dt/dts

> 
> From: Markus Niebel <Markus.Niebel at ew.tq-group.com>
> 
> The board has a pull-up resistor for MDIO pin per PHY design guide.
> When MDIO is idle, it needs to be high and open drain is better to be
> used here for power saving.
> 
> Signed-off-by: Markus Niebel <Markus.Niebel at ew.tq-group.com>
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Besides the typo:

Reviewed-by: Peng Fan <peng.fan at nxp.com>


From peng.fan at nxp.com  Fri Dec  6 00:59:29 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 6 Dec 2024 08:59:29 +0000
Subject: [PATCH v2 1/2] arm64: dt: imx93-tqma9352-mba93xxca: enable Open
 Drain for MDIO
In-Reply-To: <20241205150730.3132807-1-alexander.stein@ew.tq-group.com>
References: <20241205150730.3132807-1-alexander.stein@ew.tq-group.com>
Message-ID: <PAXPR04MB8459234E55143042090E5CEF88312@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 1/2] arm64: dt: imx93-tqma9352-mba93xxca:
> enable Open Drain for MDIO

s/dt/dts

> 
> From: Markus Niebel <Markus.Niebel at ew.tq-group.com>
> 
> The board has a pull-up resistor for MDIO pin per PHY design guide.
> When MDIO is idle, it needs to be high and open drain is better to be
> used here for power saving.
> 
> Signed-off-by: Markus Niebel <Markus.Niebel at ew.tq-group.com>
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Besides the typo:

Reviewed-by: Peng Fan <peng.fan at nxp.com>


From mailhol.vincent at wanadoo.fr  Thu Dec  5 23:26:11 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 16:26:11 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
Message-ID: <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>

On Fri. 6 Dec. 2024 at 15:40, Martin Uecker <muecker at gwdg.de> wrote:
> Am Freitag, dem 06.12.2024 um 02:25 +0000 schrieb David Laight:
> > From: Vincent Mailhol
> > > Sent: 05 December 2024 15:31
> > >
> > > -CC: Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
> > > +CC: Martin Uecker <muecker at gwdg.de>
> > > (seems that Martin changed his address)
>
> My current one is this: uecker at tugraz.at

Ack

(...)

> > > > > + *
> > > > > + * Glory to Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
> > > >
> > > > IIRC Martin has agreed in the past that the accreditation can
> > > > be removed - especially since it refers to the 'sizeof (void)' trick.
> > >
> > > I tried to look for such message:
> > >
> > >   https://lore.kernel.org/all/?q=f%3A%22martin+uecker%22+__is_constexpr
> > >
> > > but couldn't find it. Do you have the link?
> > >
> > > @Martin, do you agree that I remove the accreditation?

So, do you agree to have the accreditation removed in compiler.h?
Personally, I do not mind. I am also OK to remove you from the
documentation and add you to the CREDITS file if you'd like to.


Yours sincerely,
Vincent Mailhol


From alexander.stein at ew.tq-group.com  Fri Dec  6 01:05:46 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 06 Dec 2024 10:05:46 +0100
Subject: [PATCH] clk: imx: Enable IMX93_CLK_LVDS_GATE only for i.MX93
In-Reply-To: <20241203130530.1206526-1-peng.fan@oss.nxp.com>
References: <20241203130530.1206526-1-peng.fan@oss.nxp.com>
Message-ID: <4615625.LvFx2qVVIh@steina-w>

Am Dienstag, 3. Dezember 2024, 14:05:29 CET schrieb Peng Fan (OSS):
> From: Peng Fan <peng.fan at nxp.com>
> 
> Enable the LVDS gate only for i.MX93, because i.MX91 does not support
> LVDS.
> 
> Fixes: a27bfff88dd2 ("clk: imx: add i.MX91 clk")
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/clk/imx/clk-imx93.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
> index 58a516dd385b..a0d2972ba9cd 100644
> --- a/drivers/clk/imx/clk-imx93.c
> +++ b/drivers/clk/imx/clk-imx93.c
> @@ -239,7 +239,7 @@ static const struct imx93_clk_ccgr {
>  	{ IMX93_CLK_SAI3_IPG,		"sai3_ipg_clk", "bus_wakeup_root",	0x94c0, 0, &share_count_sai3},
>  	{ IMX93_CLK_MIPI_CSI_GATE,	"mipi_csi",	"media_apb_root",	0x9580, },
>  	{ IMX93_CLK_MIPI_DSI_GATE,	"mipi_dsi",	"media_apb_root",	0x95c0, },

mipi_csi and mipi_dsi are also only PLAT_IMX93.

> -	{ IMX93_CLK_LVDS_GATE,		"lvds",		"media_ldb_root",	0x9600, },
> +	{ IMX93_CLK_LVDS_GATE,		"lvds",		"media_ldb_root",	0x9600, 0, NULL, PLAT_IMX93 },
>  	{ IMX93_CLK_LCDIF_GATE,		"lcdif",	"media_apb_root",	0x9640, },
>  	{ IMX93_CLK_PXP_GATE,		"pxp",		"media_apb_root",	0x9680, },

pxp is also only PLAT_IMX93.

>  	{ IMX93_CLK_ISI_GATE,		"isi",		"media_apb_root",	0x96c0, },
> 

Not visible in this diff, but also only PLAT_IMX93:
* flexio1
* flexio2
* cm33

An most probably also mu*_a and mu*_b, even though they are listed in
i.MX91 RM, but AFAIK this SoC lacks MU.

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 carlos.song at nxp.com  Fri Dec  6 01:13:16 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Fri, 6 Dec 2024 09:13:16 +0000
Subject: [PATCH] i2c: imx: make controller available until system
 suspend_noirq() and from resume_noirq()
In-Reply-To: <6d6xgvuvu74hm5466xeovgr4qqkwxaxaoeemvfdty3dqnl4gjp@axlzm6mxnzkv>
References: <20241125142108.1613016-1-carlos.song@nxp.com>
 <6d6xgvuvu74hm5466xeovgr4qqkwxaxaoeemvfdty3dqnl4gjp@axlzm6mxnzkv>
Message-ID: <AM0PR0402MB3937ECA7D10662217F787AEBE8312@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Andi Shyti <andi.shyti at kernel.org>
> Sent: Thursday, December 5, 2024 7:54 PM
> To: Carlos Song <carlos.song at nxp.com>
> Cc: o.rempel at pengutronix.de; kernel at pengutronix.de; shawnguo at kernel.org;
> s.hauer at pengutronix.de; festevam at gmail.com; Frank Li <frank.li at nxp.com>;
> linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> Subject: [EXT] Re: [PATCH] i2c: imx: make controller available until system
> suspend_noirq() and from resume_noirq()
> 
> 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 Carlos,
> 
> ...
> 
> > +static int i2c_imx_suspend(struct device *dev) {
> > +     /*
> > +      * Some I2C devices may need I2C controller up during resume_noirq()
> > +      * or suspend_noirq(), if the controller is autosuspended, there is
> > +      * no way to wakeup it once runtime pm is disabled (in
> suspend_late()).
> > +      * When system resume, I2C controller will be available until runtime
> pm
> > +      * is enabled(in_resume_early()). But it is too late for some devices.
> > +      * Wakeup the controller in suspend() callback while runtime pm is
> enabled,
> > +      * I2C controller will be available until suspend_noirq() callback
> > +      * (pm_runtime_force_suspend()) is called. During the resume, I2C
> controller
> > +      * can be restored by resume_noirq() callback
> (pm_runtime_force_resume()).
> > +      * Then resume() callback enables autosuspend. It will make I2C
> controller
> > +      * available until system suspend_noirq() and from resume_noirq().
> > +      */
> 
> Just made some little adjustments to the comment above, please let me know if
> they are fine:
> 
>         /*
>          * Some I2C devices may need the I2C controller to remain active
>          * during resume_noirq() or suspend_noirq(). If the controller is
>          * autosuspended, there is no way to wake it up once runtime PM is
>          * disabled (in suspend_late()).
>          *
>          * During system resume, the I2C controller will be available only
>          * after runtime PM is re-enabled (in resume_early()). However, this
>          * may be too late for some devices.
>          *
>          * Wake up the controller in the suspend() callback while runtime PM
>          * is still enabled. The I2C controller will remain available until
>          * the suspend_noirq() callback (pm_runtime_force_suspend()) is
>          * called. During resume, the I2C controller can be restored by the
>          * resume_noirq() callback (pm_runtime_force_resume()).
>          *
>          * Finally, the resume() callback re-enables autosuspend, ensuring
>          * the I2C controller remains available until the system enters
>          * suspend_noirq() and from resume_noirq().
>          */
> 
> If so, I will take it in.
> 

Hi, Andi,

That is so nice!

> Andi
> 
> > +     return pm_runtime_resume_and_get(dev); }


From quic_zhenhuah at quicinc.com  Fri Dec  6 01:13:39 2024
From: quic_zhenhuah at quicinc.com (Zhenhua Huang)
Date: Fri, 6 Dec 2024 17:13:39 +0800
Subject: [PATCH 0/2] Fix subsection vmemmap_populate logic
In-Reply-To: <eb4d6674-494a-4a84-bade-481b0c89eb93@quicinc.com>
References: <20241121071256.487220-1-quic_zhenhuah@quicinc.com>
 <eb4d6674-494a-4a84-bade-481b0c89eb93@quicinc.com>
Message-ID: <b2681eed-d4d5-43c9-90e0-3e706db3e201@quicinc.com>



On 2024/11/28 15:26, Zhenhua Huang wrote:
> 
> 
> On 2024/11/21 15:12, Zhenhua Huang wrote:
>> To perform memory hotplug operations, the memmap (aka struct page) 
>> will be
>> updated. For arm64 with 4K page size, the typical granularity is 128M,
>> which corresponds to a 2M memmap buffer.
>> Commit 2045a3b8911b ("mm/sparse-vmemmap: generalise 
>> vmemmap_populate_hugepages()")
>> optimizes this 2M buffer to be mapped with PMD huge pages. However,
>> commit ba72b4c8cf60 ("mm/sparsemem: support sub-section hotplug")
>> which supports 2M subsection hotplug granularity, causes other issues
>> (refer to the change log of patch #1). The logic is adjusted to populate
>> with huge pages only if the hotplug address/size is section-aligned.
> 
> Could any expert please help review ?

Gentle reminder for review..

> 
>>
>> Zhenhua Huang (2):
>> ?? arm64: mm: vmemmap populate to page level if not section aligned
>> ?? arm64: mm: implement vmemmap_check_pmd for arm64
>>
>> ? arch/arm64/mm/mmu.c | 7 +++++--
>> ? 1 file changed, 5 insertions(+), 2 deletions(-)
>>
> 



From carlos.song at nxp.com  Fri Dec  6 01:07:32 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Fri, 6 Dec 2024 09:07:32 +0000
Subject: [PATCH v4] i2c: imx: support DMA defer probing
In-Reply-To: <6b39268b-7487-427d-aff5-f3ca3b2afd42@pengutronix.de>
References: <20241127083818.2108201-1-carlos.song@nxp.com>
 <153e8e36-7b0e-4379-9cc3-6dacb5d705be@pengutronix.de>
 <AM0PR0402MB39370E69BC4B71C761EE8377E8282@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <6b39268b-7487-427d-aff5-f3ca3b2afd42@pengutronix.de>
Message-ID: <AM0PR0402MB39378417A496F13B201A1907E8312@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Ahmad Fatoum <a.fatoum at pengutronix.de>
> Sent: Friday, December 6, 2024 2:50 AM
> To: Carlos Song <carlos.song at nxp.com>; mkl at pengutronix.de; Frank Li
> <frank.li at nxp.com>; o.rempel at pengutronix.de; kernel at pengutronix.de;
> andi.shyti at kernel.org; shawnguo at kernel.org; s.hauer at pengutronix.de;
> festevam at gmail.com
> Cc: imx at lists.linux.dev; linux-i2c at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> Subject: [EXT] Re: [PATCH v4] i2c: imx: support DMA defer probing
>
> 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
>
>
> Hello Carlos,
>
> On 27.11.24 11:43, Carlos Song wrote:
> >> -----Original Message-----
> >> From: Ahmad Fatoum <a.fatoum at pengutronix.de>
> >> Sent: Wednesday, November 27, 2024 4:38 PM
> >> To: Carlos Song <carlos.song at nxp.com>; mkl at pengutronix.de; Frank Li
> >> <frank.li at nxp.com>; o.rempel at pengutronix.de; kernel at pengutronix.de;
> >> andi.shyti at kernel.org; shawnguo at kernel.org; s.hauer at pengutronix.de;
> >> festevam at gmail.com
> >> Cc: imx at lists.linux.dev; linux-i2c at vger.kernel.org;
> >> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> >> Subject: [EXT] Re: [PATCH v4] i2c: imx: support DMA defer probing
>
> >> Please try to address open questions before sending new versions of
> >> the patch set. Otherwise, it's difficult to follow the conversation.
> >>
> >> Did you see my question[1] on your v2:
> >>
> >
> > Hi, thank you so much! So sorry about it... I missed it yesterday. I will answer
> your question[1] in this mail.
> >
> >
> >> | Wouldn't this break probe for all i2c-imx users who have
> >> | CONFIG_IMX_SDMA disabled?
> >> |
> >
> > I have tested i2c probe at IMX and LS platform when DMA disabled,
>
> What does DMA disabled mean? Did you leave the dmas property in the device
> tree unchanged, but just disabled the config option?
>
> > it won't break i2c-imx probe.
> > When require DMA channel in i2c_imx_dma_request, find no devices and
> > return -ENODEV, as you see at V4 patch, it will continue to probe and work in
> PIO mode.
> > I2C adapter should keep available whatever DMA mode is or isn't enabled.
>
> If that's the case, then all is good. I thought the situation described above would
> return -EPROBE_DEFER instead. I haven't dug into the code to understand what
> the difference between when dma_request_chan().
>
> >> | Also I am wondering on what kernel version and what configuration
> >> | (CONFIG_I2C_IMX=?, CONFIG_IMX_SDMA=?) you have that made you run
> >> | into this situation.
> >> |
> >
> > I want to correct something, these code about DMA in i2c-imx.c is for eDMA
> not for SDMA.
> > For eDMA mode, I have tested this patch at layerscape-1043 platform.
> > My patch is based on
> > cfba9f07a1d6 (tag: next-20241122, origin/master, origin/HEAD).
>
> The driver also handles i.MX variants like i.MX6, i.MX8 and so on, which have
> SDMA. So eDMA is not the only DMA driver it is used with.
>
> >
> > Test log is :
> > No apply this patch:
> > CONFIG_I2C_IMX=y
> > CONFIG_FSL_EDMA=y
> > root at ls1043ardb:~# dmesg | grep i2c
> > [    1.162053] i2c i2c-0: IMX I2C adapter registered
> > [    1.166826] i2c i2c-0: using dma0chan16 (tx) and dma0chan17 (rx) for
> DMA transfers
> > [    4.722057] i2c_dev: i2c /dev entries driver
> >
> > Not apply the patch:
> > CONFIG_I2C_IMX=y
> > CONFIG_FSL_EDMA=m
> > root at ls1043ardb:~# dmesg | grep i2c
> > [    1.166381] i2c i2c-0: IMX I2C adapter registered
> > [    4.719226] i2c_dev: i2c /dev entries driver
> > (result shows i2c not enabled the eDMA mode) root at ls1043ardb:~#
> > i2cdetect -y -l
> > i2c-0   i2c             2180000.i2c
> I2C adapter
> > root at ls1043ardb:~# i2cdetect -y 0
> >      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
> > 00:                         08 -- -- -- -- -- -- --
> > 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> > 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> > 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> > 40: UU -- -- -- -- -- -- -- -- -- -- -- UU -- -- --
> > 50: -- UU UU UU -- -- -- -- -- -- -- -- -- -- -- --
> > 60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- --
> > 70: -- -- -- -- -- -- -- --
> >
> > After apply the patch:
> > CONFIG_I2C_IMX=y
> > CONFIG_FSL_EDMA=m
> > root at ls1043ardb:~#
> > root at ls1043ardb:~# dmesg | grep i2c
> > [    4.697046] i2c_dev: i2c /dev entries driver
> > [    7.304142] imx-i2c 2180000.i2c: using dma0chan16 (tx) and dma0chan17
> (rx) for DMA transfers
> > [    7.313532] i2c i2c-0: IMX I2C adapter registered
> > (result shows i2c probed after eDMA module installed)
>
Hi, Ahmad

Refer previous history:
https://lore.kernel.org/linux-arm-kernel/6b39268b-7487-427d-aff5-f3ca3b2afd42 at pengutronix.de/

Your suggestions are very insightful. I'm very grateful!

Before replying to your question, I think we should synchronize SDMA and eDMA firstly.
sDMA and EDMA for i2c is different.
Only 1 SDMA channel for i2c SDMA TX/RX event.
But 2 eDMA channels for i2c eDMA TX request and RX request.

Now in i2c-imx, DMA code all are for eDMA, they have nothing to do with SDMA initialization.
It is very different initialization of SDMA and eDMA.

SDMA at dts:
@@ -1046,6 +1046,8 @@ i2c1: i2c at 30a20000 {
                                ...
+                               dmas = <&sdma1 18 27 0>;
+                               dma-names = "rx-tx";
                                status = "disabled";
                        };
eDMA at dts:
                i2c0: i2c at 2180000 {
                        ....
+                               dmas = <&edma0 1 38>,
+                                      <&edma0 1 39>;
+                               dma-names = "rx", "tx";
                        status = "disabled";
                };

SDMA initialization in i2c-imx driver:

+       dma->chan_tx = dma_request_chan(dev, "rx-tx");
+       if (IS_ERR(dma->chan_tx)) {
+               ret = PTR_ERR(dma->chan_tx);
+               goto fail_dma;
+       }
+
+       dma->chan_rx = dma->chan_tx;
+       i2c_imx->dma = dma;

eDMA initialization in i2c-imx driver:

...
+       dma->chan_tx = dma_request_chan(dev, "tx");
....
+       dma->chan_rx = dma_request_chan(dev, "rx");
....
        i2c_imx->dma = dma;

So if need to enable SDMA, should define a separate dma_request function and should not reuse the current i2c_imx_dma_request function.
Also according to different platforms i2c-imx driver need to choose to use eDMA or SDMA.

So now we start to discuss about your confusion:

> My concern is this configuration:
>
>   - A user has eDMA/SDMA module or disabled, but enabled in DT
[Carlos]:
I delete edma channel at dts to disable eDMA before. It works in PIO mode.
I also test your case : when enable dma channel in DT but disable eDMA module. It will meet error:

+++ b/arch/arm64/configs/defconfig
....
-CONFIG_FSL_EDMA=y
....

root at ls1043ardb:~# dmesg | grep i2c
[    4.697392] i2c_dev: i2c /dev entries driver
[   18.357685] platform 2180000.i2c: deferred probe pending: (reason unknown)
root at ls1043ardb:~# i2cdetect -y -l

The case you mentioned is completely inconsistent with the actual usage. Since you have defined the dma channel in dts, it means that you need to
use DMA mode in i2c, but you disabled the eDMA module when building the Image. This makes no sense at all. I think this is a usage error.
And the deferred probe pending error is predictable. Since there is no DMA driver loaded, I2C will keep defer probe and be hanged.

>   - The I2C has a PMIC, which is needed for eMMC VCC
[Carlos]:
PMIC is critical for the whole board, so PMIC will finish all critical system power-on configuration(include eMMC VCC) in the uboot not at kernel.
So pmic driver probe in kernel won't and shouldn't effect system boot.

>   - System startup is stuck or considerably delayed
>
The purpose of defer probe is to solve the problem of interdependence of module loading, and to try to load again after a while is to ensure that the required functions
will not be unavailable because the resources are not ready. This delay is unavoidable. If a defer probe occurs, the first consideration should be to reasonably adjust the
loading order of each module, rather than directly giving up the functions that should be enabled.

> > root at ls1043ardb:~#
> > root at ls1043ardb:~# i2cdetect -y -l
> > i2c-0   i2c             2180000.i2c
> I2C adapter
> > root at ls1043ardb:~# i2cdetect -y 0
> >      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
> > 00:                         08 -- -- -- -- -- -- --
> > 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> > 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> > 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> > 40: UU -- -- -- -- -- -- -- -- -- -- -- UU -- -- --
> > 50: -- UU UU UU -- -- -- -- -- -- -- -- -- -- -- --
> > 60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- --
> > 70: -- -- -- -- -- -- -- --
> >
> >
> >> | I'd have expected that with fw_devlink enabled, the I2C controller
> >> | wouldn't be probed before the DMA provider is available.
> >>
> >
> > This is a legacy patch, it has been in our local tree for a long time. The related
> history is relatively vague.
> > I reproduced the problem and found this patch is effective, so I
> > referred the community patch and legacy patch to rewrite the commit log(I
> am not sure if this would happened in some cases so I kept this information).
> > Now it seems that these descriptions are redundant. I should completely
> removed this in the commit log:
> >     Move i2c_imx_dma_request() before registering I2C adapter to avoid
> >     infinite loop of .probe() calls to the same driver, see "e8c220fac415
> >     Revert "i2c: imx: improve the error handling in
> i2c_imx_dma_request()""
> >     and "Documentation/driver-api/driver-model/driver.rst".
>
> Cheers,
> Ahmad
>
> >
> > [1]:
> > https://lore/
> > .kernel.org%2Fall%2F19a43db4-db5c-4638-9778-d94fb571a206%40pengutro
> nix
> > .de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C3e9bcb1cc97b43a69
> ca608dd
> >
> 155d9977%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638690213
> 9450713
> >
> 71%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAu
> MDAwMCI
> >
> sIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdat
> a=T
> > z0JcOxf9rrSOl2FoCHNbQz4rtKY5V0eS1ZMV%2BXED4I%3D&reserved=0
> > [2]:https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2F
> >
> lore.kernel.org%2Fall%2F153e8e36-7b0e-4379-9cc3-6dacb5d705be%40pengutr
> >
> onix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C3e9bcb1cc97b43a
> 69ca6
> >
> 08dd155d9977%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63869
> 0213945
> >
> 090490%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwL
> jAuMDA
> >
> wMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C
> &sda
> > ta=pAT68urcH7CTFknvK1xM3lfuYjZQO0I16B%2FTTsCJw6Q%3D&reserved=0
> >
> >>>
> >>> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> >>> Signed-off-by: Clark Wang <xiaoning.wang at nxp.com>
> >>> ---
> >>> Change for V4:
> >>> - Output "Only use PIO mode" log in debug level when no DMA configure.
> >>> Change for V3:
> >>> - According to Marc's comment, remove error print when defer probe.
> >>>   Add info log when DMA has not been enabled and add error log when
> >>>   DMA error, both won't stuck the i2c adapter register, just for reminding,
> >>>   i2c adapter is working only in PIO mode.
> >>> Change for V2:
> >>> - According to Frank's comments, wrap at 75 char and Simplify fix code
> >>>   at i2c_imx_dma_request().
> >>> - Use strict patch check, fix alignment warning at
> >>> i2c_imx_dma_request()
> >>> ---
> >>>  drivers/i2c/busses/i2c-imx.c | 31 +++++++++++++++++++++++--------
> >>>  1 file changed, 23 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/drivers/i2c/busses/i2c-imx.c
> >>> b/drivers/i2c/busses/i2c-imx.c index 5ed4cb61e262..b11d66d56c55
> >>> 100644
> >>> --- a/drivers/i2c/busses/i2c-imx.c
> >>> +++ b/drivers/i2c/busses/i2c-imx.c
> >>> @@ -397,17 +397,16 @@ static void i2c_imx_reset_regs(struct
> >>> imx_i2c_struct *i2c_imx)  }
> >>>
> >>>  /* Functions for DMA support */
> >>> -static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
> >>> -                                             dma_addr_t
> >> phy_addr)
> >>> +static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
> >>> +dma_addr_t phy_addr)
> >>>  {
> >>>       struct imx_i2c_dma *dma;
> >>>       struct dma_slave_config dma_sconfig;
> >>> -     struct device *dev = &i2c_imx->adapter.dev;
> >>> +     struct device *dev = i2c_imx->adapter.dev.parent;
> >>>       int ret;
> >>>
> >>>       dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
> >>>       if (!dma)
> >>> -             return;
> >>> +             return -ENOMEM;
> >>>
> >>>       dma->chan_tx = dma_request_chan(dev, "tx");
> >>>       if (IS_ERR(dma->chan_tx)) {
> >>> @@ -452,7 +451,7 @@ static void i2c_imx_dma_request(struct
> >> imx_i2c_struct *i2c_imx,
> >>>       dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n",
> >>>               dma_chan_name(dma->chan_tx),
> >>> dma_chan_name(dma->chan_rx));
> >>>
> >>> -     return;
> >>> +     return 0;
> >>>
> >>>  fail_rx:
> >>>       dma_release_channel(dma->chan_rx);
> >>> @@ -460,6 +459,8 @@ static void i2c_imx_dma_request(struct
> >> imx_i2c_struct *i2c_imx,
> >>>       dma_release_channel(dma->chan_tx);
> >>>  fail_al:
> >>>       devm_kfree(dev, dma);
> >>> +
> >>> +     return ret;
> >>>  }
> >>>
> >>>  static void i2c_imx_dma_callback(void *arg) @@ -1803,6 +1804,23 @@
> >>> static int i2c_imx_probe(struct platform_device *pdev)
> >>>       if (ret == -EPROBE_DEFER)
> >>>               goto clk_notifier_unregister;
> >>>
> >>> +     /*
> >>> +      * Init DMA config if supported, -ENODEV means DMA not enabled
> at
> >>> +      * this platform, that is not a real error, so just remind "only
> >>> +      * PIO mode is used". If DMA is enabled, but meet error when
> request
> >>> +      * DMA channel, error should be showed in probe error log. PIO
> mode
> >>> +      * should be available regardless of DMA.
> >>> +      */
> >>> +     ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> >>> +     if (ret) {
> >>> +             if (ret == -EPROBE_DEFER)
> >>> +                     goto clk_notifier_unregister;
> >>> +             else if (ret == -ENODEV)
> >>> +                     dev_dbg(&pdev->dev, "Only use PIO mode\n");
> >>> +             else
> >>> +                     dev_err_probe(&pdev->dev, ret, "Failed to
> >>> + setup
> >> DMA, only use PIO mode\n");
> >>> +     }
> >>> +
> >>>       /* Add I2C adapter */
> >>>       ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
> >>>       if (ret < 0)
> >>> @@ -1817,9 +1835,6 @@ static int i2c_imx_probe(struct
> >>> platform_device
> >> *pdev)
> >>>               i2c_imx->adapter.name);
> >>>       dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter
> >>> registered\n");
> >>>
> >>> -     /* Init DMA config if supported */
> >>> -     i2c_imx_dma_request(i2c_imx, phy_addr);
> >>> -
> >>>       return 0;   /* Return OK */
> >>>
> >>>  clk_notifier_unregister:
> >>
> >>
> >> --
> >> Pengutronix e.K.                           |
> >> |
> >> Steuerwalder Str. 21                       |
> >> http://www/.
> >>
> pen%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C3e9bcb1cc97b43a69c
> a608d
> >>
> d155d9977%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63869021
> 394510
> >>
> 5284%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjA
> uMDAw
> >>
> MCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&s
> da
> >> ta=qE5UgdZSuGjzXtDFcY1BVbjNgb6sPPrpykvr3gpHsLg%3D&reserved=0
> >>
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C1acf840d499f
> >>
> 49a7872408dd0ebedc39%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> >> %7C638682935131084746%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLj
> Aw
> >>
> MDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&s
> >>
> data=Y9Qn9XEk15yu4CespwsNu6hl3%2FqfNTvEeOn4ZvnGxbo%3D&reserved=0
> >> |
> >> 31137 Hildesheim, Germany                  | Phone:
> +49-5121-206917-0
> >> |
> >> Amtsgericht Hildesheim, HRA 2686           | Fax:
> >> +49-5121-206917-5555 |
> >
>
>
> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C3e9bcb1cc97b
> 43a69ca608dd155d9977%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> %7C638690213945119868%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGki
> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ
> %3D%3D%7C0%7C%7C%7C&sdata=SU8Ak78%2BZCcOo4G%2F9Kq1E3IZNAgg5E
> 0m1CC1qr4ANYk%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |


From ck.hu at mediatek.com  Fri Dec  6 01:28:47 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 6 Dec 2024 09:28:47 +0000
Subject: [PATCH v2] drm/mediatek: Move mtk_crtc_finish_page_flip() to
 ddp_cmdq_cb()
In-Reply-To: <20241119163658.31405-1-jason-jh.lin@mediatek.com>
References: <20241119163658.31405-1-jason-jh.lin@mediatek.com>
Message-ID: <c0092a07a9e6d0bc9b2dc85f379e6cddfa095ef7.camel@mediatek.com>

Hi, Jason:

On Wed, 2024-11-20 at 00:36 +0800, Jason-JH.Lin wrote:
> mtk_crtc_finish_page_flip() is used to notify userspace that a
> page flip has been completed, allowing userspace to free the frame
> buffer of the last frame and commit the next frame.
> 
> In MediaTek's hardware design for configuring display hardware by using
> GCE, `DRM_EVENT_FLIP_COMPLETE` should be notified to userspace after
> GCE has finished configuring all display hardware settings for each
> atomic_commit().
> 
> Currently, mtk_crtc_finish_page_flip() cannot guarantee that GCE has
> configured all the display hardware settings of the last frame.
> Therefore, to increase the accuracy of the timing for notifying
> `DRM_EVENT_FLIP_COMPLETE` to userspace, mtk_crtc_finish_page_flip()
> should be moved to ddp_cmdq_cb().
> 
> Fixes: 7f82d9c43879 ("drm/mediatek: Clear pending flag when cmdq packet is done")
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_crtc.c | 27 +++++++++++++++++----------
>  1 file changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
> index eb0e1233ad04..0d57863c075a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
> @@ -109,15 +109,19 @@ static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc)
>  static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
>  {
>  	unsigned long flags;
> +	struct drm_crtc *crtc = &mtk_crtc->base;
> +	struct mtk_drm_private *priv = crtc->dev->dev_private;
>  
>  	drm_crtc_handle_vblank(&mtk_crtc->base);
>  
> -	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> -	if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
> -		mtk_crtc_finish_page_flip(mtk_crtc);
> -		mtk_crtc->pending_needs_vblank = false;
> +	if (priv->data->shadow_register) {

if (!priv->data->shadow_register)
	return;

And this would reduce the indent.

> +		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> +		if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
> +			mtk_crtc_finish_page_flip(mtk_crtc);
> +			mtk_crtc->pending_needs_vblank = false;
> +		}
> +		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
>  	}
> -	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
>  }
>  
>  static void mtk_crtc_destroy(struct drm_crtc *crtc)
> @@ -284,10 +288,8 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  	state = to_mtk_crtc_state(mtk_crtc->base.state);
>  
>  	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> -	if (mtk_crtc->config_updating) {
> -		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> +	if (mtk_crtc->config_updating)
>  		goto ddp_cmdq_cb_out;
> -	}
>  
>  	state->pending_config = false;
>  
> @@ -315,10 +317,15 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  		mtk_crtc->pending_async_planes = false;
>  	}
>  
> -	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> -
>  ddp_cmdq_cb_out:
>  
> +	if (mtk_crtc->pending_needs_vblank) {
> +		mtk_crtc_finish_page_flip(mtk_crtc);
> +		mtk_crtc->pending_needs_vblank = false;

In mtk_crtc_update_config(), after mbox_client_txdone() and before mtk_crtc->config_updating = false;
cmdq may have finish the command and callback ddp_cmdq_cb().
Because mtk_crtc->config_updating is true, so this page flip would be skipped.
But if there is no next mtk_crtc_update_config() exist, this page flip would never happen.
This may cause some deadlock.

Regards,
CK

> +	}
> +
> +	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> +
>  	mtk_crtc->cmdq_vblank_cnt = 0;
>  	wake_up(&mtk_crtc->cb_blocking_queue);
>  }


From David.Laight at ACULAB.COM  Fri Dec  6 01:34:15 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 09:34:15 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
Message-ID: <6576cf10fc424eab874a31714e60474b@AcuMS.aculab.com>

From: David Laight
> Sent: 06 December 2024 02:26

(now it is no longer 2am...)

Linus suggested this a while back:

>  in https://lore.kernel.org/all/CAHk-=wiq=GUNWJwWh1CRAYchW73UmOaSkaCovLatfDKeveZctA at mail.gmail.com/
> 
>    /*
>     * iff 'x' is a non-zero constant integer expression,
>     * then '!(x)' will be a zero constant integer expression,
>     * and casting that to 'void *' will result in a NULL pointer.
>     * Otherwise casting it to 'void *' will be just a regular 'void *'.
>     *
>     * The type of '0 ? NULL : (char *)' is 'char *'
>     * The type of '0 ? (void *) : (char *) is 'void *'
>     */
>     #define const_true(x) \
>         _Generic(0 ? (void *)((long)!(x)) : (char *)0, char *: 1, void *: 0)

But some of the things built on it has issues with compiler warnings.
I think there have several variations before and since with subtle differences.
Probably const_zero() const_true() const_false() and const_expr().

While the 'base' define is really const_zero() with just (long)(x) that
will mask high bits off 'long long'. 
A const_false() could 'fix' that using (long)!!(x) but even !(x) starts
giving compile errors.

If called for pointers (long)((x) == 0) is also problematic.
(Perhaps this is less likely now that min/max don't use it.)

So we may end up with (long)((x) ? 0 : 1) which really might as
well be written ((x) ? 0L : 1L).

The use is likely to be const_true(x > y) so perhaps there isn't a
reason to have const_false() since the boolean operator can be inverted.

const_expr() has relied on '* 0' to make all constant expressions zero.
But it has to handle pointers - so needs a conditional.
Since it is only one line, maybe just replicate the whole thing as:

#define const_true(x) _Generic(0 ? (void *)((x) ? 0L : 1L) : (char *)0, char *: 1, void *: 0)
#define const_expr(x) _Generic(0 ? (void *)((x) ? 0L : 0L) : (char *)0, char *: 1, void *: 0)

Or maybe (mostly because the lines are shorter):
#define const_NULL(x) _Generic(0 ? (x) : (char *)0, char *: 1, void *: 0)
#define const_true(x) const_NULL((void *)(x) ? 0L : 1L))
#define const_expr(x) const_NULL((void *)(x) ? 0L : 0L))

Or even:
#define const_true(x) const_NULL((x) ? NULL : (void *)1L))
#define const_expr(x) const_NULL((x) ? NULL : NULL))

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From maz at kernel.org  Fri Dec  6 01:37:04 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 06 Dec 2024 09:37:04 +0000
Subject: Question about interrupt prioriyt of ARM GICv3/4
In-Reply-To: <CAJNi4rMfhZOCT+7Ki14vUs+dZbv9cxCZ0s+jgn6=_om4NTgo_A@mail.gmail.com>
References: <CAJNi4rMfhZOCT+7Ki14vUs+dZbv9cxCZ0s+jgn6=_om4NTgo_A@mail.gmail.com>
Message-ID: <86cyi5tanz.wl-maz@kernel.org>

On Fri, 06 Dec 2024 08:33:11 +0000,
richard clark <richard.xnu.clark at gmail.com> wrote:
> 
> Hi,
> Currently seems the GICv3/4 irqchip configures all the interrupts as
> the same priority, I am thinking about to minimize the latency of the
> interrupt for a particular device, e.g, the arm arch_timer in the RTL
> system. The question is,
> 1. Why don't we provide a /proc or /sys interface for the enduser to
> set the priority of a specific interrupt(SPI/PPI)?

I'm afraid this really has nothing to do with any particular interrupt
architecture.

Before thinking of exposing the interrupt priority to userspace, you
should look at what this translates into for the kernel once you allow
interrupts to be preempted by another one with a higher priority.

This means that at every point where you would normally see a
local_irq_save(), spinlock_irqsave() or equivalent, you would need to
explicitly specify the priority that you allow for preemption. You
should then make sure that any code that can be run during an
interrupt is reentrant. You need to define which data structures can
be manipulated at which priority level... The list goes on.

If you want a small taste of the complexity, just look at what
handling NMIs (or even pseudo-NMIs in the case of GICv3) means, and
generalise it to not just two, but an arbitrary range of priorities.

If you want the full blown experience, look at the BSDs and their use
of spl*(). I don't think anyone has any plan to get there, and the RT
patches have shown that there is little need for it.

> 2. Is there any way to verify the higher priority interrupt will have
> more dominant to be selected to the CPU (IOW, the priority is really
> working) in case of multiple different interrupts asserted to the GIC
> at the same time(some debug registers of GIC like GICD_REEMPT_CNT :-)
> to record higher priority wins)?

The GIC architecture makes no promise that the interrupt you
acknowledge is the highest priority pending interrupt, because this is
by definition a very racy process.

Also, even on busy systems, you will very rarely see two interrupts
targeting the same CPU being made pending at the same time, so that
the interrupt delivery system would have to arbitrate between the two.
That's because interrupts are vanishingly rare in the grand scheme of
things.

Thanks,

	M.

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


From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:11 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:11 +0200
Subject: [PATCH v2 08/10] drm/radeon: use eld_mutex to protect access to
 connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-8-c9bce1ee8bea@linaro.org>

Reading access to connector->eld can happen at the same time the
drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
order to protect connector->eld from concurrent access.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/radeon/radeon_audio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
index 5b69cc8011b42b4686c02f97a2b451a63d6c346d..8d64ba18572ec4bb6f6985be3a5edf581c47d7a3 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.c
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -775,8 +775,10 @@ static int radeon_audio_component_get_eld(struct device *kdev, int port,
 		if (!dig->pin || dig->pin->id != port)
 			continue;
 		*enabled = true;
+		mutex_lock(&connector->eld_mutex);
 		ret = drm_eld_size(connector->eld);
 		memcpy(buf, connector->eld, min(max_bytes, ret));
+		mutex_unlock(&connector->eld_mutex);
 		break;
 	}
 

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:12 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:12 +0200
Subject: [PATCH v2 09/10] drm/sti: hdmi: use eld_mutex to protect access to
 connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-9-c9bce1ee8bea@linaro.org>

Reading access to connector->eld can happen at the same time the
drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
order to protect connector->eld from concurrent access.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Acked-by: Raphael Gallais-Pou <rgallaispou at gmail.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/sti/sti_hdmi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 847470f747c0efad61c2ebdc3fb3746a7a13a863..3c8f3532c79723e7b1a720c855c90e40584cc6ca 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -1225,7 +1225,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size
 	struct drm_connector *connector = hdmi->drm_connector;
 
 	DRM_DEBUG_DRIVER("\n");
+	mutex_lock(&connector->eld_mutex);
 	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
+	mutex_unlock(&connector->eld_mutex);
 
 	return 0;
 }

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:13 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:13 +0200
Subject: [PATCH v2 10/10] drm/vc4: hdmi: use eld_mutex to protect access to
 connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-10-c9bce1ee8bea@linaro.org>

Reading access to connector->eld can happen at the same time the
drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
order to protect connector->eld from concurrent access.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 297afd89036ba8fba571379f5b6d63227eadb66e..f98617b8bf6cf9d92a806e35584e8f8ab0ac9f96 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -2220,9 +2220,9 @@ static int vc4_hdmi_audio_get_eld(struct device *dev, void *data,
 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 	struct drm_connector *connector = &vc4_hdmi->connector;
 
-	mutex_lock(&vc4_hdmi->mutex);
+	mutex_lock(&connector->eld_mutex);
 	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
-	mutex_unlock(&vc4_hdmi->mutex);
+	mutex_unlock(&connector->eld_mutex);
 
 	return 0;
 }

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:03 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:03 +0200
Subject: [PATCH v2 00/10] drm/connector: add eld_mutex to protect
 connector->eld
Message-ID: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>

The connector->eld is accessed by the .get_eld() callback. This access
can collide with the drm_edid_to_eld() updating the data at the same
time. Add drm_connector.eld_mutex to protect the data from concurrenct
access.

The individual drivers were just compile tested. I propose to merge the
drm_connector and bridge drivers through drm-misc, allowing other
maintainers either to ack merging through drm-misc or merging the
drm-misc into their tree and then picking up correcponding patch.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
Changes in v2:
- Also take the mutex in clear_eld() (Jani)
- Rebased on top of linux-next + drm-misc-next to solve build error
- Link to v1: https://lore.kernel.org/r/20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03 at linaro.org

---
Dmitry Baryshkov (10):
      drm/connector: add mutex to protect ELD from concurrent access
      drm/bridge: anx7625: use eld_mutex to protect access to connector->eld
      drm/bridge: ite-it66121: use eld_mutex to protect access to connector->eld
      drm/amd/display: use eld_mutex to protect access to connector->eld
      drm/exynos: hdmi: use eld_mutex to protect access to connector->eld
      drm/i915/audio: use eld_mutex to protect access to connector->eld
      drm/msm/dp: use eld_mutex to protect access to connector->eld
      drm/radeon: use eld_mutex to protect access to connector->eld
      drm/sti: hdmi: use eld_mutex to protect access to connector->eld
      drm/vc4: hdmi: use eld_mutex to protect access to connector->eld

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
 drivers/gpu/drm/bridge/analogix/anx7625.c         | 2 ++
 drivers/gpu/drm/bridge/ite-it66121.c              | 2 ++
 drivers/gpu/drm/drm_connector.c                   | 1 +
 drivers/gpu/drm/drm_edid.c                        | 6 ++++++
 drivers/gpu/drm/exynos/exynos_hdmi.c              | 2 ++
 drivers/gpu/drm/i915/display/intel_audio.c        | 3 +++
 drivers/gpu/drm/msm/dp/dp_audio.c                 | 2 ++
 drivers/gpu/drm/radeon/radeon_audio.c             | 2 ++
 drivers/gpu/drm/sti/sti_hdmi.c                    | 2 ++
 drivers/gpu/drm/vc4/vc4_hdmi.c                    | 4 ++--
 include/drm/drm_connector.h                       | 5 ++++-
 12 files changed, 30 insertions(+), 3 deletions(-)
---
base-commit: 84e541b1e58e04d808e1bb13ef566ffbe87aa89b
change-id: 20241201-drm-connector-eld-mutex-8a39a35e9a38

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:04 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:04 +0200
Subject: [PATCH v2 01/10] drm/connector: add mutex to protect ELD from
 concurrent access
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-1-c9bce1ee8bea@linaro.org>

The connector->eld is accessed by the .get_eld() callback. This access
can collide with the drm_edid_to_eld() updating the data at the same
time. Add drm_connector.eld_mutex to protect the data from concurrenct
access. Individual drivers are not updated (to reduce possible issues
while applying the patch), maintainers are to find a best suitable way
to lock that mutex while accessing the ELD data.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/drm_connector.c | 1 +
 drivers/gpu/drm/drm_edid.c      | 6 ++++++
 include/drm/drm_connector.h     | 5 ++++-
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index fc35f47e2849ed6786d6223ac9c69e1c359fc648..bbdaaf7022b62d84594a29f1b60144920903a99a 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -277,6 +277,7 @@ static int __drm_connector_init(struct drm_device *dev,
 	INIT_LIST_HEAD(&connector->probed_modes);
 	INIT_LIST_HEAD(&connector->modes);
 	mutex_init(&connector->mutex);
+	mutex_init(&connector->eld_mutex);
 	mutex_init(&connector->edid_override_mutex);
 	mutex_init(&connector->hdmi.infoframes.lock);
 	connector->edid_blob_ptr = NULL;
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 855beafb76ffbecf5c08d58e2f54bfb76f30b930..13bc4c290b17d556d654b7cdd8c48c24a32aba9c 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5605,7 +5605,9 @@ EXPORT_SYMBOL(drm_edid_get_monitor_name);
 
 static void clear_eld(struct drm_connector *connector)
 {
+	mutex_lock(&connector->eld_mutex);
 	memset(connector->eld, 0, sizeof(connector->eld));
+	mutex_unlock(&connector->eld_mutex);
 
 	connector->latency_present[0] = false;
 	connector->latency_present[1] = false;
@@ -5657,6 +5659,8 @@ static void drm_edid_to_eld(struct drm_connector *connector,
 	if (!drm_edid)
 		return;
 
+	mutex_lock(&connector->eld_mutex);
+
 	mnl = get_monitor_name(drm_edid, &eld[DRM_ELD_MONITOR_NAME_STRING]);
 	drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD monitor %s\n",
 		    connector->base.id, connector->name,
@@ -5717,6 +5721,8 @@ static void drm_edid_to_eld(struct drm_connector *connector,
 	drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD size %d, SAD count %d\n",
 		    connector->base.id, connector->name,
 		    drm_eld_size(eld), total_sad_count);
+
+	mutex_unlock(&connector->eld_mutex);
 }
 
 static int _drm_edid_to_sad(const struct drm_edid *drm_edid,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index e3fa43291f449d70f3b92a00985336c4f2237bc6..1e2b25e204cb523d61d30f5409faa059bf2b86eb 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -2001,8 +2001,11 @@ struct drm_connector {
 	struct drm_encoder *encoder;
 
 #define MAX_ELD_BYTES	128
-	/** @eld: EDID-like data, if present */
+	/** @eld: EDID-like data, if present, protected by @eld_mutex */
 	uint8_t eld[MAX_ELD_BYTES];
+	/** @eld_mutex: protection for concurrenct access to @eld */
+	struct mutex eld_mutex;
+
 	/** @latency_present: AV delay info from ELD, if found */
 	bool latency_present[2];
 	/**

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:05 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:05 +0200
Subject: [PATCH v2 02/10] drm/bridge: anx7625: use eld_mutex to protect
 access to connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-2-c9bce1ee8bea@linaro.org>

Reading access to connector->eld can happen at the same time the
drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
order to protect connector->eld from concurrent access.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/analogix/anx7625.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index a2675b121fe44b96945f34215fd900f35bfde43a..c036bbc92ba96ec4663c55cca091cd5da9f6d271 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -2002,8 +2002,10 @@ static int anx7625_audio_get_eld(struct device *dev, void *data,
 		memset(buf, 0, len);
 	} else {
 		dev_dbg(dev, "audio copy eld\n");
+		mutex_lock(&ctx->connector->eld_mutex);
 		memcpy(buf, ctx->connector->eld,
 		       min(sizeof(ctx->connector->eld), len));
+		mutex_unlock(&ctx->connector->eld_mutex);
 	}
 
 	return 0;

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:06 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:06 +0200
Subject: [PATCH v2 03/10] drm/bridge: ite-it66121: use eld_mutex to protect
 access to connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-3-c9bce1ee8bea@linaro.org>

Reading access to connector->eld can happen at the same time the
drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
order to protect connector->eld from concurrent access.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/ite-it66121.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c
index 35ae3f0e8f51f768229e055a086b53a419ffcd9f..940083e5d2ddbfc56f14e2bdc6ddd0b9dd50b1f8 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -1450,8 +1450,10 @@ static int it66121_audio_get_eld(struct device *dev, void *data,
 		dev_dbg(dev, "No connector present, passing empty EDID data");
 		memset(buf, 0, len);
 	} else {
+		mutex_lock(&ctx->connector->eld_mutex);
 		memcpy(buf, ctx->connector->eld,
 		       min(sizeof(ctx->connector->eld), len));
+		mutex_unlock(&ctx->connector->eld_mutex);
 	}
 	mutex_unlock(&ctx->lock);
 

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:07 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:07 +0200
Subject: [PATCH v2 04/10] drm/amd/display: use eld_mutex to protect access
 to connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-4-c9bce1ee8bea@linaro.org>

Reading access to connector->eld can happen at the same time the
drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
order to protect connector->eld from concurrent access.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 19a58630e774029767bf2a27eb4ddf17e3c21129..04c68c320252b5ce9647f0606fb86fe57f347639 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1037,8 +1037,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port,
 			continue;
 
 		*enabled = true;
+		mutex_lock(&connector->eld_mutex);
 		ret = drm_eld_size(connector->eld);
 		memcpy(buf, connector->eld, min(max_bytes, ret));
+		mutex_unlock(&connector->eld_mutex);
 
 		break;
 	}

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:08 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:08 +0200
Subject: [PATCH v2 05/10] drm/exynos: hdmi: use eld_mutex to protect access
 to connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-5-c9bce1ee8bea@linaro.org>

Reading access to connector->eld can happen at the same time the
drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
order to protect connector->eld from concurrent access.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index c9d4b9146df95bb46cb6bea4849c331616c2b463..6fc537c9048f5c8e57e30f083121c9aea6b99a5f 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1648,7 +1648,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
 	struct hdmi_context *hdata = dev_get_drvdata(dev);
 	struct drm_connector *connector = &hdata->connector;
 
+	mutex_lock(&connector->eld_mutex);
 	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
+	mutex_unlock(&connector->eld_mutex);
 
 	return 0;
 }

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:09 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:09 +0200
Subject: [PATCH v2 06/10] drm/i915/audio: use eld_mutex to protect access
 to connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-6-c9bce1ee8bea@linaro.org>

Reading access to connector->eld can happen at the same time the
drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
order to protect connector->eld from concurrent access.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Reviewed-by: Jani Nikula <jani.nikula at intel.com>
Acked-by: Jani Nikula <jani.nikula at intel.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/i915/display/intel_audio.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index 32aa9ec1a204d2ecde46cad36598aa768a3af671..3902ab8431139c3ff4dc17b841d94b6d3241dec3 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -699,10 +699,12 @@ bool intel_audio_compute_config(struct intel_encoder *encoder,
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
 
+	mutex_lock(&connector->eld_mutex);
 	if (!connector->eld[0]) {
 		drm_dbg_kms(&i915->drm,
 			    "Bogus ELD on [CONNECTOR:%d:%s]\n",
 			    connector->base.id, connector->name);
+		mutex_unlock(&connector->eld_mutex);
 		return false;
 	}
 
@@ -710,6 +712,7 @@ bool intel_audio_compute_config(struct intel_encoder *encoder,
 	memcpy(crtc_state->eld, connector->eld, sizeof(crtc_state->eld));
 
 	crtc_state->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2;
+	mutex_unlock(&connector->eld_mutex);
 
 	return true;
 }

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 01:43:10 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 11:43:10 +0200
Subject: [PATCH v2 07/10] drm/msm/dp: use eld_mutex to protect access to
 connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <20241206-drm-connector-eld-mutex-v2-7-c9bce1ee8bea@linaro.org>

Reading access to connector->eld can happen at the same time the
drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
order to protect connector->eld from concurrent access.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Acked-by: Abhinav Kumar <quic_abhinavk at quicinc.com>
Reviewed-by: Abhinav Kumar <quic_abhinavk at quicinc.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_audio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
index 74e01a5dd4195d5e0e04250663886f1116f25711..0fd5e0abaf07828157085bd680bfd3c7d32deb61 100644
--- a/drivers/gpu/drm/msm/dp/dp_audio.c
+++ b/drivers/gpu/drm/msm/dp/dp_audio.c
@@ -414,8 +414,10 @@ static int msm_dp_audio_get_eld(struct device *dev,
 		return -ENODEV;
 	}
 
+	mutex_lock(&msm_dp_display->connector->eld_mutex);
 	memcpy(buf, msm_dp_display->connector->eld,
 		min(sizeof(msm_dp_display->connector->eld), len));
+	mutex_unlock(&msm_dp_display->connector->eld_mutex);
 
 	return 0;
 }

-- 
2.39.5



From nicolas.ferre at microchip.com  Fri Dec  6 01:47:07 2024
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Fri, 6 Dec 2024 10:47:07 +0100
Subject: [PATCH net-next v8 10/15] net: macb: Use helper rgmii_clock
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-10-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
 <20241205-upstream_s32cc_gmac-v8-10-ec1d180df815@oss.nxp.com>
Message-ID: <43ec4b5e-9ccb-412f-a2c7-cac5f8bc2bbd@microchip.com>

On 05/12/2024 at 17:43, Jan Petrous via B4 Relay wrote:
> From: "Jan Petrous (OSS)" <jan.petrous at oss.nxp.com>
> 
> Utilize a new helper function rgmii_clock().
> 
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Signed-off-by: Jan Petrous (OSS) <jan.petrous at oss.nxp.com>

If needed:
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Thanks, best regards,
   Nicolas

> ---
>   drivers/net/ethernet/cadence/macb_main.c | 14 ++------------
>   1 file changed, 2 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> index daa416fb1724..640f500f989d 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> @@ -530,19 +530,9 @@ static void macb_set_tx_clk(struct macb *bp, int speed)
>          if (bp->phy_interface == PHY_INTERFACE_MODE_MII)
>                  return;
> 
> -       switch (speed) {
> -       case SPEED_10:
> -               rate = 2500000;
> -               break;
> -       case SPEED_100:
> -               rate = 25000000;
> -               break;
> -       case SPEED_1000:
> -               rate = 125000000;
> -               break;
> -       default:
> +       rate = rgmii_clock(speed);
> +       if (rate < 0)
>                  return;
> -       }
> 
>          rate_rounded = clk_round_rate(bp->tx_clk, rate);
>          if (rate_rounded < 0)
> 
> --
> 2.47.0
> 
> 



From ulf.hansson at linaro.org  Fri Dec  6 01:53:59 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Fri, 6 Dec 2024 10:53:59 +0100
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on pre-SYSTEM_SUSPEND
 PSCI impls
In-Reply-To: <72add0ff-db2a-44f8-b4af-0b5fe5f65f20@oss.qualcomm.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <CAPDyKFpGrw+vOs=-TxfChBeORjzkpaL_iVB08MtmaC4sFNKzcg@mail.gmail.com> <72add0ff-db2a-44f8-b4af-0b5fe5f65f20@oss.qualcomm.com>
Message-ID: <CAPDyKFq5+HWmHK4E4ERx1rb8O4mubHGqRHP8AAiq2KyZyX1GSQ@mail.gmail.com>

+ Maulik, Vincent

On Thu, 5 Dec 2024 at 21:34, Konrad Dybcio
<konrad.dybcio at oss.qualcomm.com> wrote:
>
> On 14.11.2024 4:30 PM, Ulf Hansson wrote:
> > On Mon, 28 Oct 2024 at 15:24, Konrad Dybcio <konradybcio at kernel.org> wrote:
> >>
> >> Certain firmwares expose exactly what PSCI_SYSTEM_SUSPEND does through
> >> CPU_SUSPEND instead. Inform Linux about that.
> >> Please see the commit messages for a more detailed explanation.
> >>
> >> This is effectively a more educated follow-up to [1].
> >>
> >> The ultimate goal is to stop making Linux think that certain states
> >> only concern cores/clusters, and consequently setting
> >> pm_set_suspend/resume_via_firmware(), so that client drivers (such as
> >> NVMe, see related discussion over at [2]) can make informed decisions
> >> about assuming the power state of the device they govern.
> >
> > In my opinion, this is not really the correct way to do it. Using
> > pm_set_suspend/resume_via_firmware() works fine for x86/ACPI, but not
> > for PSCI like this. Let me elaborate. If the NVMe storage device is
> > sharing the same power-rail as the CPU cluster, then yes we should use
> > PSCI to control it. But is that really the case? If so, there are in
> > principle two ways forward to deal with this correctly.
> >
> > 1) If PSCI OSI mode is being used, the corresponding NVMe storage
> > device should be hooked up to the CPU PM cluster domain via genpd and
> > controlled as any other devices sharing the cluster-rail. In this way,
> > genpd together with the cpuidle-psci-domain can decide whether it's
> > okay to turn off the cluster. I believe this is the preferred way, but
> > 2) would work fine too.
> >
> > 2) If PSCI PC mode is being used, a separate channel/interface to the
> > FW (like SCMI or rpmh in the QC case), should inform the FW whether
> > NVMe needs the power to it. This information should then be taken into
> > account by the PSCI FW when it decides what low-power-state to enter,
> > which ultimately means whether the cluster-rail can be turned off or
> > not.
>
> This assumes PSCI only governs the CPU power rail. But what I'd
> guesstimate is that in most implementations if system-level suspend is
> there at all (no matter through which call), as per the spec, it at
> least also projects onto the DDR power state (like in this i.mx
> impl here [1]), or some uncore peripherals (like in Tegra's case with
> some secure element being toggled at [2])

Right, I certainly understand the above. There are different parts of
an SoC that may be sharing the same power-island as the CPUs.

The question here is whether the NVMe storage device is part of that
power-island too on some QC SoCs?

>
> > Assuming PSCI OSI mode is used here. Then if 1) doesn't work for you,
> > please elaborate on why, so we can help to make it work, as it should.
>
> On Qualcomm platforms, RPMh is the central authority when it comes
> to power governance, but by design, the CPUs must be off (and with a
> specific magic cookie) for the RPMh hardware to consider powering off
> very power hungry parts of the system, such as general i/o rails.

Right, that is why the "qcom,rpmh-rsc" device in many cases belongs to
the cluster-power-domain (for PSCI). This allows "qcom,rpmh-rsc" to
control the "last-man" activities and prevent deeper PSCI states
if/when necessary.

>
> So again, PSCI must be fed a specific value for the rest of the hw
> to react. The "S2RAM state" isn't really a cpuidle state, because
> it doesn't differ from many shallower states as far as the cpu/cluster
> are concerned. If that all isn't in place, the platform never actually
> enters any "real" sleep state, other than "CPU and some controllable
> IP blocks are runtime-suspended".

We recently discussed this, offlist, with Maulik - and I think we need
some more clarity around what is actually going on here.

In principle, it looks to me that using S2I with just another deeper
idlestate specified (with another psci-suspend-parameter, representing
a deeper state) should work fine, at least theoretically. Of course,
we may not be able to use that idlestate during regular
cpuidle/runtime but only during S2I, which we need to control in a
smooth way and that is not currently supported (but can be fixed
easily, I think).

In the end, it's the psci-suspend-parameter that is given to the PSCI
FW that informs about what state we can enter.

That said, using S2I may not work without updating the PSCI FW, of
course. For example, there may be FW limitations that require the
boot-CPU( CPU0) to be the last one for these deeper low-power-states.
Whether that is just a FW limitation or whether there are some
additional HW constraints that enforce this, needs to be clarified.

>
> This effectively is very close to what ACPI+x86 do - there's a
> co-processor/firmware that does a lot of things behind your back and
> all you can do is *ask* it to change some handwavily-defined P/Cstate
> that affects a huge chunk of silicon.

Yep, there are similarities.

However, ACPI is for generic device power management. PSCI requires
something additional, such as ARM SCMI or QC's rpm/rsc interface.

>
> Konrad
>
> [1] https://github.com/nxp-imx/imx-atf/blob/lf_v2.6/plat/imx/imx8m/imx8mp/imx8mp_lpa_psci.c#L474
> [2] https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c#L214
>

Kind regards
Uffe


From tabba at google.com  Fri Dec  6 02:04:51 2024
From: tabba at google.com (Fuad Tabba)
Date: Fri, 6 Dec 2024 10:04:51 +0000
Subject: [PATCH v4 05/14] KVM: arm64: Initialize feature id registers for
 protected VMs
In-Reply-To: <Z1JNGmcZka1hl2ha@linux.dev>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-6-tabba@google.com>
 <Z1JNGmcZka1hl2ha@linux.dev>
Message-ID: <CA+EHjTyTODB42oSy0iBkqBGiyH-FUfG_mqgVWzaZ33qnkeESZQ@mail.gmail.com>

Hi Oliver,

On Fri, 6 Dec 2024 at 01:02, Oliver Upton <oliver.upton at linux.dev> wrote:
>
> Hi Fuad,
>
> On Mon, Dec 02, 2024 at 03:47:32PM +0000, Fuad Tabba wrote:
> > +/*
> > + * Initializes feature registers for protected vms.
> > + */
> > +void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu)
> > +{
> > +     struct kvm *kvm = vcpu->kvm;
> > +     struct kvm_arch *ka = &kvm->arch;
> > +     u32 r;
> > +
>
> Can you add an assertion that this is called while holding the
> vm_table_lock? Otherwise it isn't clear why its safe to initialize
> per-VM state.

Will do, and I'll update the documentation around vm_table_lock to
clarify that. Should I respin after this, or would you like me to wait
a bit?

Thanks,
/fuad

> > +     if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags))
> > +             return;
> > +
> > +     /*
> > +      * Initialize only AArch64 id registers since AArch32 isn't supported
> > +      * for protected VMs.
> > +      */
> > +     for (r = sys_reg(3, 0, 0, 4, 0); r <= sys_reg(3, 0, 0, 7, 7); r += sys_reg(0, 0, 0, 0, 1))
> > +             ka->id_regs[IDREG_IDX(r)] = pvm_calc_id_reg(vcpu, r);
> > +
> > +     set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
> > +}
> > +
> >  /*
> >   * Checks that the sysreg table is unique and in-order.
> >   *
> > --
> > 2.47.0.338.g60cca15819-goog
> >
>
> --
> Thanks,
> Oliver


From kevin.brodsky at arm.com  Fri Dec  6 02:11:06 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:06 +0000
Subject: [RFC PATCH 12/16] arm64: mm: Map p4d/pgd with privileged pkey
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-13-kevin.brodsky@arm.com>

If CONFIG_KPKEYS_HARDENED_PGTABLES is enabled, map p4d/pgd pages
using a privileged pkey (KPKEYS_PKEY_PGTABLES), so that they can
only be written under guard(kpkeys_hardened_pgtables).

The case where pgd is not page-sized is not currently handled -
this is pending support for pkeys in kmem_cache.

This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
(default).

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/include/asm/pgalloc.h | 21 ++++++++++++++++++---
 arch/arm64/mm/pgd.c              | 30 ++++++++++++++++++++++++++++--
 2 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index e75422864d1b..c006aecd6ba5 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -88,18 +88,33 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgdp, p4d_t *p4dp)
 static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
 	gfp_t gfp = GFP_PGTABLE_USER;
+	int ret;
 
 	if (mm == &init_mm)
 		gfp = GFP_PGTABLE_KERNEL;
-	return (p4d_t *)get_zeroed_page(gfp);
+
+	addr = get_zeroed_page(gfp);
+	if (!addr)
+		return NULL;
+
+	ret = kpkeys_protect_pgtable_memory(addr, 1);
+	if (ret) {
+		free_page(addr);
+		return NULL;
+	}
+
+	return (p4d_t *)addr;
 }
 
 static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
 {
+	unsigned long addr = (unsigned long)p4d;
+
 	if (!pgtable_l5_enabled())
 		return;
-	BUG_ON((unsigned long)p4d & (PAGE_SIZE-1));
-	free_page((unsigned long)p4d);
+	BUG_ON(addr & (PAGE_SIZE-1));
+	kpkeys_unprotect_pgtable_memory(addr, 1);
+	free_page(addr);
 }
 
 #define __p4d_free_tlb(tlb, p4d, addr)  p4d_free((tlb)->mm, p4d)
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 0c501cabc238..3577cc1821af 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -28,12 +28,38 @@ static bool pgdir_is_page_size(void)
 	return false;
 }
 
+static pgd_t *pgd_page_alloc(gfp_t gfp)
+{
+	unsigned long addr;
+	int ret;
+
+	addr = __get_free_page(gfp);
+	if (!addr)
+		return NULL;
+
+	ret = kpkeys_protect_pgtable_memory(addr, 1);
+	if (ret) {
+		free_page(addr);
+		return NULL;
+	}
+
+	return (pgd_t *)addr;
+}
+
+static void pgd_page_free(pgd_t *pgd)
+{
+	unsigned long addr = (unsigned long)pgd;
+
+	kpkeys_unprotect_pgtable_memory(addr, 1);
+	free_page(addr);
+}
+
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
 	gfp_t gfp = GFP_PGTABLE_USER;
 
 	if (pgdir_is_page_size())
-		return (pgd_t *)__get_free_page(gfp);
+		return pgd_page_alloc(gfp);
 	else
 		return kmem_cache_alloc(pgd_cache, gfp);
 }
@@ -41,7 +67,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
 	if (pgdir_is_page_size())
-		free_page((unsigned long)pgd);
+		pgd_page_free(pgd);
 	else
 		kmem_cache_free(pgd_cache, pgd);
 }
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:07 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:07 +0000
Subject: [RFC PATCH 13/16] arm64: mm: Reset pkey in __tlb_remove_table()
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-14-kevin.brodsky@arm.com>

Page table pages are typically freed via tlb_remove_table() and
friends. Ensure that the linear mapping for those pages is reset to
the default pkey when CONFIG_KPKEYS_HARDENED_PGTABLES is enabled.

This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
(default).

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/include/asm/tlb.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index a947c6e784ed..d1611ffa6d91 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -10,10 +10,14 @@
 
 #include <linux/pagemap.h>
 #include <linux/swap.h>
+#include <linux/kpkeys.h>
 
 static inline void __tlb_remove_table(void *_table)
 {
-	free_page_and_swap_cache((struct page *)_table);
+	struct page *page = (struct page *)_table;
+
+	kpkeys_unprotect_pgtable_memory((unsigned long)page_address(page), 1);
+	free_page_and_swap_cache(page);
 }
 
 #define tlb_flush tlb_flush
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:08 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:08 +0000
Subject: [RFC PATCH 14/16] arm64: mm: Guard page table writes with kpkeys
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-15-kevin.brodsky@arm.com>

When CONFIG_KPKEYS_HARDENED_PGTABLES is enabled, page tables (both
user and kernel) are mapped with a privileged pkey in the linear
mapping. As a result, they can only be written under the
kpkeys_hardened_pgtables guard, which sets POR_EL1 appropriately to
allow such writes.

Use this guard wherever page tables genuinely need to be written,
keeping its scope as small as possible (so that POR_EL1 is reset as
fast as possible). Where atomics are involved, the guard's scope
encompasses the whole loop to avoid switching POR_EL1 unnecessarily.

This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
(default).

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 19 +++++++++++++++++--
 arch/arm64/mm/fault.c            |  2 ++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6986345b537a..5f9d748f08ee 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -39,6 +39,7 @@
 #include <linux/mm_types.h>
 #include <linux/sched.h>
 #include <linux/page_table_check.h>
+#include <linux/kpkeys.h>
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
@@ -314,6 +315,7 @@ static inline pte_t pte_clear_uffd_wp(pte_t pte)
 
 static inline void __set_pte_nosync(pte_t *ptep, pte_t pte)
 {
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*ptep, pte);
 }
 
@@ -758,6 +760,7 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 	}
 #endif /* __PAGETABLE_PMD_FOLDED */
 
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*pmdp, pmd);
 
 	if (pmd_valid(pmd)) {
@@ -825,6 +828,7 @@ static inline void set_pud(pud_t *pudp, pud_t pud)
 		return;
 	}
 
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*pudp, pud);
 
 	if (pud_valid(pud)) {
@@ -906,6 +910,7 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
 		return;
 	}
 
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*p4dp, p4d);
 	dsb(ishst);
 	isb();
@@ -1033,6 +1038,7 @@ static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
 		return;
 	}
 
+	guard(kpkeys_hardened_pgtables)();
 	WRITE_ONCE(*pgdp, pgd);
 	dsb(ishst);
 	isb();
@@ -1233,6 +1239,7 @@ static inline int __ptep_test_and_clear_young(struct vm_area_struct *vma,
 {
 	pte_t old_pte, pte;
 
+	guard(kpkeys_hardened_pgtables)();
 	pte = __ptep_get(ptep);
 	do {
 		old_pte = pte;
@@ -1279,7 +1286,10 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
 				       unsigned long address, pte_t *ptep)
 {
-	pte_t pte = __pte(xchg_relaxed(&pte_val(*ptep), 0));
+	pte_t pte;
+
+	scoped_guard(kpkeys_hardened_pgtables)
+		pte = __pte(xchg_relaxed(&pte_val(*ptep), 0));
 
 	page_table_check_pte_clear(mm, pte);
 
@@ -1322,7 +1332,10 @@ static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm,
 static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 					    unsigned long address, pmd_t *pmdp)
 {
-	pmd_t pmd = __pmd(xchg_relaxed(&pmd_val(*pmdp), 0));
+	pmd_t pmd;
+
+	scoped_guard(kpkeys_hardened_pgtables)
+		pmd = __pmd(xchg_relaxed(&pmd_val(*pmdp), 0));
 
 	page_table_check_pmd_clear(mm, pmd);
 
@@ -1336,6 +1349,7 @@ static inline void ___ptep_set_wrprotect(struct mm_struct *mm,
 {
 	pte_t old_pte;
 
+	guard(kpkeys_hardened_pgtables)();
 	do {
 		old_pte = pte;
 		pte = pte_wrprotect(pte);
@@ -1416,6 +1430,7 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
 		unsigned long address, pmd_t *pmdp, pmd_t pmd)
 {
 	page_table_check_pmd_set(vma->vm_mm, pmdp, pmd);
+	guard(kpkeys_hardened_pgtables)();
 	return __pmd(xchg_relaxed(&pmd_val(*pmdp), pmd_val(pmd)));
 }
 #endif
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index ef63651099a9..ab45047155b9 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -220,6 +220,8 @@ int __ptep_set_access_flags(struct vm_area_struct *vma,
 	if (pte_same(pte, entry))
 		return 0;
 
+	guard(kpkeys_hardened_pgtables)();
+
 	/* only preserve the access flags and write permission */
 	pte_val(entry) &= PTE_RDONLY | PTE_AF | PTE_WRITE | PTE_DIRTY;
 
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:09 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:09 +0000
Subject: [RFC PATCH 15/16] arm64: Enable kpkeys_hardened_pgtables support
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-16-kevin.brodsky@arm.com>

kpkeys_hardened_pgtables should be enabled as early as possible (if
selected). It does however require kpkeys being available, which
means on arm64 POE being detected and enabled. POE is a boot
feature, so calling kpkeys_hardened_pgtables_enable() just after
setup_boot_cpu_features() in smp_prepare_boot_cpu() is the best we
can do.

With that done, all the bits are in place and we can advertise
support for kpkeys_hardened_pgtables by selecting
ARCH_HAS_KPKEYS_HARDENED_PGTABLES if ARM64_POE is enabled.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/Kconfig      | 1 +
 arch/arm64/kernel/smp.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f35964641c1a..dac2f9a64826 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2184,6 +2184,7 @@ config ARM64_POE
 	select ARCH_USES_HIGH_VMA_FLAGS
 	select ARCH_HAS_PKEYS
 	select ARCH_HAS_KPKEYS
+	select ARCH_HAS_KPKEYS_HARDENED_PGTABLES
 	help
 	  The Permission Overlay Extension is used to implement Memory
 	  Protection Keys. Memory Protection Keys provides a mechanism for
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 3b3f6b56e733..074cab55f9db 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -35,6 +35,7 @@
 #include <linux/kgdb.h>
 #include <linux/kvm_host.h>
 #include <linux/nmi.h>
+#include <linux/kpkeys.h>
 
 #include <asm/alternative.h>
 #include <asm/atomic.h>
@@ -468,6 +469,7 @@ void __init smp_prepare_boot_cpu(void)
 	if (system_uses_irq_prio_masking())
 		init_gic_priority_masking();
 
+	kpkeys_hardened_pgtables_enable();
 	kasan_init_hw_tags();
 	/* Init percpu seeds for random tags after cpus are set up. */
 	kasan_init_sw_tags();
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:10 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:10 +0000
Subject: [RFC PATCH 16/16] mm: Add basic tests for kpkeys_hardened_pgtables
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-17-kevin.brodsky@arm.com>

Add basic tests for the kpkeys_hardened_pgtables feature: try to
perform a direct write to some kernel and user page table entry and
ensure it fails.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 mm/Makefile                        |  1 +
 mm/kpkeys_hardened_pgtables_test.c | 71 ++++++++++++++++++++++++++++++
 security/Kconfig.hardening         | 12 +++++
 3 files changed, 84 insertions(+)
 create mode 100644 mm/kpkeys_hardened_pgtables_test.c

diff --git a/mm/Makefile b/mm/Makefile
index ffe799c1c897..49ac16ae6875 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -147,3 +147,4 @@ obj-$(CONFIG_SHRINKER_DEBUG) += shrinker_debug.o
 obj-$(CONFIG_EXECMEM) += execmem.o
 obj-$(CONFIG_TMPFS_QUOTA) += shmem_quota.o
 obj-$(CONFIG_KPKEYS_HARDENED_PGTABLES) += kpkeys_hardened_pgtables.o
+obj-$(CONFIG_KPKEYS_HARDENED_PGTABLES_TEST) += kpkeys_hardened_pgtables_test.o
diff --git a/mm/kpkeys_hardened_pgtables_test.c b/mm/kpkeys_hardened_pgtables_test.c
new file mode 100644
index 000000000000..37b6ffaa55e6
--- /dev/null
+++ b/mm/kpkeys_hardened_pgtables_test.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <kunit/test.h>
+#include <linux/pgtable.h>
+#include <linux/mman.h>
+
+static void write_kernel_pte(struct kunit *test)
+{
+	pte_t *ptep;
+	pte_t pte;
+	int ret;
+
+	/*
+	 * The choice of address is mostly arbitrary - we just need a page
+	 * that is definitely mapped, such as the current function.
+	 */
+	ptep = virt_to_kpte((unsigned long)&write_kernel_pte);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, ptep, "Failed to get PTE");
+
+	pte = ptep_get(ptep);
+	pte = set_pte_bit(pte, __pgprot(PTE_WRITE));
+	ret = copy_to_kernel_nofault(ptep, &pte, sizeof(pte));
+	KUNIT_EXPECT_EQ_MSG(test, ret, -EFAULT,
+			    "Direct PTE write wasn't prevented");
+}
+
+static void write_user_pmd(struct kunit *test)
+{
+	pmd_t *pmdp;
+	pmd_t pmd;
+	unsigned long uaddr;
+	int ret;
+
+	uaddr = kunit_vm_mmap(test, NULL, 0, PAGE_SIZE, PROT_READ,
+			      MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, 0);
+	KUNIT_ASSERT_NE_MSG(test, uaddr, 0, "Could not create userspace mm");
+
+	/* We passed MAP_POPULATE so a PMD should already be allocated */
+	pmdp = pmd_off(current->mm, uaddr);
+	KUNIT_ASSERT_NOT_NULL_MSG(test, pmdp, "Failed to get PMD");
+
+	pmd = pmdp_get(pmdp);
+	pmd = set_pmd_bit(pmd, __pgprot(PROT_SECT_NORMAL));
+	ret = copy_to_kernel_nofault(pmdp, &pmd, sizeof(pmd));
+	KUNIT_EXPECT_EQ_MSG(test, ret, -EFAULT,
+			    "Direct PMD write wasn't prevented");
+}
+
+static int kpkeys_hardened_pgtables_suite_init(struct kunit_suite *suite)
+{
+	if (!arch_kpkeys_enabled()) {
+		pr_err("Cannot run kpkeys_hardened_pgtables tests: kpkeys are not supported\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+static struct kunit_case kpkeys_hardened_pgtables_test_cases[] = {
+	KUNIT_CASE(write_kernel_pte),
+	KUNIT_CASE(write_user_pmd),
+	{}
+};
+
+static struct kunit_suite kpkeys_hardened_pgtables_test_suite = {
+	.name = "Hardened pgtables using kpkeys",
+	.test_cases = kpkeys_hardened_pgtables_test_cases,
+	.suite_init = kpkeys_hardened_pgtables_suite_init,
+};
+kunit_test_suite(kpkeys_hardened_pgtables_test_suite);
+
+MODULE_LICENSE("GPL");
diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
index 95f93f1d4055..8bc5d7235f6d 100644
--- a/security/Kconfig.hardening
+++ b/security/Kconfig.hardening
@@ -312,6 +312,18 @@ config KPKEYS_HARDENED_PGTABLES
 	  This option has no effect if the system does not support
 	  kernel pkeys.
 
+config KPKEYS_HARDENED_PGTABLES_TEST
+	tristate "KUnit tests for kpkeys_hardened_pgtables" if !KUNIT_ALL_TESTS
+	depends on KPKEYS_HARDENED_PGTABLES
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  Enable this option to check that the kpkeys_hardened_pgtables feature
+	  functions as intended, i.e. prevents arbitrary writes to user and
+	  kernel page tables.
+
+	  If unsure, say N.
+
 endmenu
 
 config CC_HAS_RANDSTRUCT
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:02 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:02 +0000
Subject: [RFC PATCH 08/16] mm: Introduce kernel_pgtables_set_pkey()
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-9-kevin.brodsky@arm.com>

kernel_pgtables_set_pkey() allows setting the pkey of all page table
pages in swapper_pg_dir, recursively. This will be needed by
kpkeys_hardened_pgtables, as it relies on all PTPs being mapped with
a non-default pkey. Those initial kernel page tables cannot
practically be assigned a non-default pkey right when they are
allocated, so mutating them during (early) boot is required.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---

It feels that some sort of locking is called for in
kernel_pgtables_set_pkey(), but I couldn't figure out what would be
appropriate.

---
 include/linux/mm.h |   2 +
 mm/memory.c        | 130 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 132 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index c39c4945946c..683e883dae77 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -4179,4 +4179,6 @@ int arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *st
 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);
 
+int kernel_pgtables_set_pkey(int pkey);
+
 #endif /* _LINUX_MM_H */
diff --git a/mm/memory.c b/mm/memory.c
index 75c2dfd04f72..278ddf9f6249 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -76,6 +76,7 @@
 #include <linux/ptrace.h>
 #include <linux/vmalloc.h>
 #include <linux/sched/sysctl.h>
+#include <linux/kpkeys.h>
 
 #include <trace/events/kmem.h>
 
@@ -6974,3 +6975,132 @@ void vma_pgtable_walk_end(struct vm_area_struct *vma)
 	if (is_vm_hugetlb_page(vma))
 		hugetlb_vma_unlock_read(vma);
 }
+
+static int set_page_pkey(void *p, int pkey)
+{
+	unsigned long addr = (unsigned long)p;
+
+	/*
+	 * swapper_pg_dir itself will be made read-only by mark_rodata_ro()
+	 * so there is no point in changing its pkey.
+	 */
+	if (p == swapper_pg_dir)
+		return 0;
+
+	return set_memory_pkey(addr, 1, pkey);
+}
+
+static int set_pkey_pte(pmd_t *pmd, int pkey)
+{
+	pte_t *pte;
+	int err;
+
+	pte = pte_offset_kernel(pmd, 0);
+	err = set_page_pkey(pte, pkey);
+
+	return err;
+}
+
+static int set_pkey_pmd(pud_t *pud, int pkey)
+{
+	pmd_t *pmd;
+	int i, err = 0;
+
+	pmd = pmd_offset(pud, 0);
+
+	err = set_page_pkey(pmd, pkey);
+	if (err)
+		return err;
+
+	for (i = 0; i < PTRS_PER_PMD; i++) {
+		if (pmd_none(pmd[i]) || pmd_bad(pmd[i]) || pmd_leaf(pmd[i]))
+			continue;
+		err = set_pkey_pte(&pmd[i], pkey);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+static int set_pkey_pud(p4d_t *p4d, int pkey)
+{
+	pud_t *pud;
+	int i, err = 0;
+
+	if (mm_pmd_folded(&init_mm))
+		return set_pkey_pmd((pud_t *)p4d, pkey);
+
+	pud = pud_offset(p4d, 0);
+
+	err = set_page_pkey(pud, pkey);
+	if (err)
+		return err;
+
+	for (i = 0; i < PTRS_PER_PUD; i++) {
+		if (pud_none(pud[i]) || pud_bad(pud[i]) || pud_leaf(pud[i]))
+			continue;
+		err = set_pkey_pmd(&pud[i], pkey);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+static int set_pkey_p4d(pgd_t *pgd, int pkey)
+{
+	p4d_t *p4d;
+	int i, err = 0;
+
+	if (mm_pud_folded(&init_mm))
+		return set_pkey_pud((p4d_t *)pgd, pkey);
+
+	p4d = p4d_offset(pgd, 0);
+
+	err = set_page_pkey(p4d, pkey);
+	if (err)
+		return err;
+
+	for (i = 0; i < PTRS_PER_P4D; i++) {
+		if (p4d_none(p4d[i]) || p4d_bad(p4d[i]) || p4d_leaf(p4d[i]))
+			continue;
+		err = set_pkey_pud(&p4d[i], pkey);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+/**
+ * kernel_pgtables_set_pkey - set pkey for all kernel page table pages
+ * @pkey: pkey to set the page table pages to
+ *
+ * Walks swapper_pg_dir setting the protection key of every page table page (at
+ * all levels) to @pkey. swapper_pg_dir itself is left untouched as it is
+ * expected to be mapped read-only by mark_rodata_ro().
+ *
+ * No-op if the architecture does not support kpkeys.
+ */
+int kernel_pgtables_set_pkey(int pkey)
+{
+	pgd_t *pgd = swapper_pg_dir;
+	int i, err = 0;
+
+	if (!arch_kpkeys_enabled())
+		return 0;
+
+	if (mm_p4d_folded(&init_mm))
+		return set_pkey_p4d(pgd, pkey);
+
+	for (i = 0; i < PTRS_PER_PGD; i++) {
+		if (pgd_none(pgd[i]) || pgd_bad(pgd[i]) || pgd_leaf(pgd[i]))
+			continue;
+		err = set_pkey_p4d(&pgd[i], pkey);
+		if (err)
+			break;
+	}
+
+	return err;
+}
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:03 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:03 +0000
Subject: [RFC PATCH 09/16] mm: Introduce kpkeys_hardened_pgtables
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-10-kevin.brodsky@arm.com>

kpkeys_hardened_pgtables is a hardening feature based on kpkeys. It
aims to prevent the corruption of page tables by: 1. mapping all
page table pages, both kernel and user, with a privileged pkey
(KPKEYS_PKEY_PGTABLES), and 2. granting write access to that pkey
only when running at a higher kpkeys level (KPKEYS_LVL_PGTABLES).

The feature is exposed as CONFIG_KPKEYS_HARDENED_PGTABLES; it
requires explicit architecture opt-in by selecting
ARCH_HAS_KPKEYS_HARDENED_PGTABLES, since much of the page table
handling is arch-specific.

This patch introduces an API to modify the PTPs' pkey and switch
kpkeys level using a guard object. Because this API is going to be
called from low-level pgtable helpers (setters, allocators), it must
be inactive on boot and explicitly switched on if and when kpkeys
become available. A static key is used for that purpose; it is the
responsibility of each architecture supporting
kpkeys_hardened_pgtables to call kpkeys_hardened_pgtables_enable()
as early as possible to switch on that static key. The initial
kernel page tables are also walked to set their pkey, since they
have already been allocated at that point.

The definition of the kpkeys_hardened_pgtables guard class does not
use the static key on the restore path to avoid mismatched
set/restore pairs. Indeed, enabling the static key itself involves
modifying page tables, and it is thus possible that the guard object
is created when the static key appears as false, and destroyed when it
appears as true. To avoid this situation, we reserve an invalid value
for the pkey register and use it to disable the restore path.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 include/asm-generic/kpkeys.h  | 12 +++++++
 include/linux/kpkeys.h        | 67 ++++++++++++++++++++++++++++++++++-
 mm/Kconfig                    |  3 ++
 mm/Makefile                   |  1 +
 mm/kpkeys_hardened_pgtables.c | 17 +++++++++
 security/Kconfig.hardening    | 12 +++++++
 6 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 mm/kpkeys_hardened_pgtables.c

diff --git a/include/asm-generic/kpkeys.h b/include/asm-generic/kpkeys.h
index 3404ce249757..cec92334a9f3 100644
--- a/include/asm-generic/kpkeys.h
+++ b/include/asm-generic/kpkeys.h
@@ -2,8 +2,20 @@
 #ifndef __ASM_GENERIC_KPKEYS_H
 #define __ASM_GENERIC_KPKEYS_H
 
+#ifndef KPKEYS_PKEY_PGTABLES
+#define KPKEYS_PKEY_PGTABLES	1
+#endif
+
 #ifndef KPKEYS_PKEY_DEFAULT
 #define KPKEYS_PKEY_DEFAULT	0
 #endif
 
+/*
+ * Represents a pkey register value that cannot be used, typically disabling
+ * access to all keys.
+ */
+#ifndef KPKEYS_PKEY_REG_INVAL
+#define KPKEYS_PKEY_REG_INVAL	0
+#endif
+
 #endif	/* __ASM_GENERIC_KPKEYS_H */
diff --git a/include/linux/kpkeys.h b/include/linux/kpkeys.h
index bcc063425926..bd3e0f36d2d6 100644
--- a/include/linux/kpkeys.h
+++ b/include/linux/kpkeys.h
@@ -4,12 +4,14 @@
 
 #include <linux/bug.h>
 #include <linux/cleanup.h>
+#include <linux/jump_label.h>
 #include <linux/set_memory.h>
 
 #define KPKEYS_LVL_DEFAULT	0
+#define KPKEYS_LVL_PGTABLES	1
 
 #define KPKEYS_LVL_MIN		KPKEYS_LVL_DEFAULT
-#define KPKEYS_LVL_MAX		KPKEYS_LVL_DEFAULT
+#define KPKEYS_LVL_MAX		KPKEYS_LVL_PGTABLES
 
 #define KPKEYS_GUARD(_name, set_level, restore_pkey_reg)		\
 	__DEFINE_CLASS_IS_CONDITIONAL(_name, false);			\
@@ -64,4 +66,67 @@ static inline bool arch_kpkeys_enabled(void)
 
 #endif /* CONFIG_ARCH_HAS_KPKEYS */
 
+#ifdef CONFIG_KPKEYS_HARDENED_PGTABLES
+
+DECLARE_STATIC_KEY_FALSE(kpkeys_hardened_pgtables_enabled);
+
+/*
+ * Use guard(kpkeys_hardened_pgtables)() to temporarily grant write access
+ * to page tables.
+ */
+KPKEYS_GUARD(kpkeys_hardened_pgtables,
+	     static_branch_unlikely(&kpkeys_hardened_pgtables_enabled) ?
+		     kpkeys_set_level(KPKEYS_LVL_PGTABLES) :
+		     KPKEYS_PKEY_REG_INVAL,
+	     _T != KPKEYS_PKEY_REG_INVAL ?
+		     kpkeys_restore_pkey_reg(_T) :
+		     (void)0)
+
+static inline int kpkeys_protect_pgtable_memory(unsigned long addr, int numpages)
+{
+	int ret = 0;
+
+	if (static_branch_unlikely(&kpkeys_hardened_pgtables_enabled))
+		ret = set_memory_pkey(addr, numpages, KPKEYS_PKEY_PGTABLES);
+
+	WARN_ON(ret);
+	return ret;
+}
+
+static inline int kpkeys_unprotect_pgtable_memory(unsigned long addr, int numpages)
+{
+	int ret = 0;
+
+	if (static_branch_unlikely(&kpkeys_hardened_pgtables_enabled))
+		ret = set_memory_pkey(addr, numpages, KPKEYS_PKEY_DEFAULT);
+
+	WARN_ON(ret);
+	return ret;
+}
+
+/*
+ * Enables kpkeys_hardened_pgtables and switches existing kernel page tables to
+ * a privileged pkey (KPKEYS_PKEY_PGTABLES).
+ *
+ * Should be called as early as possible by architecture code, after (k)pkeys
+ * are initialised and before any user task is spawned.
+ */
+void kpkeys_hardened_pgtables_enable(void);
+
+#else /* CONFIG_KPKEYS_HARDENED_PGTABLES */
+
+KPKEYS_GUARD(kpkeys_hardened_pgtables, 0, (void)_T)
+
+static inline int kpkeys_protect_pgtable_memory(unsigned long addr, int numpages)
+{
+	return 0;
+}
+static inline int kpkeys_unprotect_pgtable_memory(unsigned long addr, int numpages)
+{
+	return 0;
+}
+static inline void kpkeys_hardened_pgtables_enable(void) {}
+
+#endif /* CONFIG_KPKEYS_HARDENED_PGTABLES */
+
 #endif /* _LINUX_KPKEYS_H */
diff --git a/mm/Kconfig b/mm/Kconfig
index f51dffca9d4e..07ae45a1395f 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1106,6 +1106,9 @@ config ARCH_HAS_PKEYS
 	bool
 config ARCH_HAS_KPKEYS
 	bool
+# ARCH_HAS_KPKEYS must be selected when selecting this option
+config ARCH_HAS_KPKEYS_HARDENED_PGTABLES
+	bool
 
 config ARCH_USES_PG_ARCH_2
 	bool
diff --git a/mm/Makefile b/mm/Makefile
index dba52bb0da8a..ffe799c1c897 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -146,3 +146,4 @@ obj-$(CONFIG_GENERIC_IOREMAP) += ioremap.o
 obj-$(CONFIG_SHRINKER_DEBUG) += shrinker_debug.o
 obj-$(CONFIG_EXECMEM) += execmem.o
 obj-$(CONFIG_TMPFS_QUOTA) += shmem_quota.o
+obj-$(CONFIG_KPKEYS_HARDENED_PGTABLES) += kpkeys_hardened_pgtables.o
diff --git a/mm/kpkeys_hardened_pgtables.c b/mm/kpkeys_hardened_pgtables.c
new file mode 100644
index 000000000000..e26fc20bdafe
--- /dev/null
+++ b/mm/kpkeys_hardened_pgtables.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/mm.h>
+#include <linux/kpkeys.h>
+
+DEFINE_STATIC_KEY_FALSE(kpkeys_hardened_pgtables_enabled);
+
+void __init kpkeys_hardened_pgtables_enable(void)
+{
+	int ret;
+
+	if (!arch_kpkeys_enabled())
+		return;
+
+	static_branch_enable(&kpkeys_hardened_pgtables_enabled);
+	ret = kernel_pgtables_set_pkey(KPKEYS_PKEY_PGTABLES);
+	WARN_ON(ret);
+}
diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
index c9d5ca3d8d08..95f93f1d4055 100644
--- a/security/Kconfig.hardening
+++ b/security/Kconfig.hardening
@@ -300,6 +300,18 @@ config BUG_ON_DATA_CORRUPTION
 
 	  If unsure, say N.
 
+config KPKEYS_HARDENED_PGTABLES
+	bool "Harden page tables using kernel pkeys"
+	depends on ARCH_HAS_KPKEYS_HARDENED_PGTABLES
+	help
+	  This option makes all page tables mostly read-only by
+	  allocating them with a non-default protection key (pkey) and
+	  only enabling write access to that pkey in routines that are
+	  expected to write to page table entries.
+
+	  This option has no effect if the system does not support
+	  kernel pkeys.
+
 endmenu
 
 config CC_HAS_RANDSTRUCT
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:04 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:04 +0000
Subject: [RFC PATCH 10/16] mm: Map page tables with privileged pkey
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-11-kevin.brodsky@arm.com>

If CONFIG_KPKEYS_HARDENED_PGTABLES is enabled, map allocated page
table pages using a privileged pkey (KPKEYS_PKEY_PGTABLES), so that
page tables can only be written under guard(kpkeys_hardened_pgtables).

This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
(default).

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 include/linux/mm.h | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 683e883dae77..4fb25454ba85 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -31,6 +31,7 @@
 #include <linux/kasan.h>
 #include <linux/memremap.h>
 #include <linux/slab.h>
+#include <linux/kpkeys.h>
 
 struct mempolicy;
 struct anon_vma;
@@ -2895,7 +2896,19 @@ static inline bool pagetable_is_reserved(struct ptdesc *pt)
  */
 static inline struct ptdesc *pagetable_alloc_noprof(gfp_t gfp, unsigned int order)
 {
-	struct page *page = alloc_pages_noprof(gfp | __GFP_COMP, order);
+	struct page *page;
+	int ret;
+
+	page = alloc_pages_noprof(gfp | __GFP_COMP, order);
+	if (!page)
+		return NULL;
+
+	ret = kpkeys_protect_pgtable_memory((unsigned long)page_address(page),
+					    1 << order);
+	if (ret) {
+		__free_pages(page, order);
+		return NULL;
+	}
 
 	return page_ptdesc(page);
 }
@@ -2911,8 +2924,11 @@ static inline struct ptdesc *pagetable_alloc_noprof(gfp_t gfp, unsigned int orde
 static inline void pagetable_free(struct ptdesc *pt)
 {
 	struct page *page = ptdesc_page(pt);
+	unsigned int order = compound_order(page);
 
-	__free_pages(page, compound_order(page));
+	kpkeys_unprotect_pgtable_memory((unsigned long)page_address(page),
+					1 << order);
+	__free_pages(page, order);
 }
 
 #if defined(CONFIG_SPLIT_PTE_PTLOCKS)
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:05 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:05 +0000
Subject: [RFC PATCH 11/16] arm64: kpkeys: Support KPKEYS_LVL_PGTABLES
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-12-kevin.brodsky@arm.com>

Enable RW access to KPKEYS_PKEY_PGTABLES (used to map page table
pages) if switching to KPKEYS_LVL_PGTABLES, otherwise only grant RO
access.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/include/asm/kpkeys.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/kpkeys.h b/arch/arm64/include/asm/kpkeys.h
index e17f6df41873..4854e1f3babd 100644
--- a/arch/arm64/include/asm/kpkeys.h
+++ b/arch/arm64/include/asm/kpkeys.h
@@ -18,6 +18,8 @@ static inline bool arch_kpkeys_enabled(void)
 static inline u64 por_set_kpkeys_level(u64 por, int level)
 {
 	por = por_set_pkey_perms(por, KPKEYS_PKEY_DEFAULT, POE_RXW);
+	por = por_set_pkey_perms(por, KPKEYS_PKEY_PGTABLES,
+				 level == KPKEYS_LVL_PGTABLES ? POE_RW : POE_R);
 
 	return por;
 }
-- 
2.47.0



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:15:54 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:15:54 +0200
Subject: [PATCH v6 00/10] drm: add DRM HDMI Codec framework
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>

While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
framework, I stumbled upon an issue while handling the Audio InfoFrames.
The HDMI codec callbacks weren't receiving the drm_atomic_state, so
there was no simple way to get the drm_connector that stayed at the end
of the bridge chain. At the same point the drm_hdmi_connector functions
expected to get drm_connector instance.

While looking for a way to solve the issue, I stumbled upon several
deficiencies in existing hdmi_codec_ops implementations. Only few of the
implementations were able to handle codec's 'plugged' callback. One
third of the drivers didn't implement the get_eld() callback.

Most of the issues can be solved if drm_connector handles
hdmi-audio-codec on its own, delegating functionality to the actual
implementation, be it a driver that implements drm_connector or
drm_bridge.

Implement such high-level framework, adding proper support for Audio
InfoFrame generation to the LT9611 driver.

Several design decisions to be kept in mind:

- drm_connector_hdmi_codec is kept as simple as possible. It implements
  generic functionality (ELD, hotplug, registration).

- drm_hdmi_connector sets up HDMI codec device if the connector
  is setup correspondingly (either I2S or S/PDIF is marked as
  supported).

- drm_bridge_connector provides a way to link HDMI audio codec
  funcionality in the drm_bridge with the drm_connector_hdmi_codec
  framework.

- It might be worth reverting the no_i2s_capture / no_spdif_capture
  bits. Only TDA889x driver sets them, while it's safe to assume that
  most of HDMI / DP devices do not support ARC / capture. I think the
  drivers should opt-in capture support rather than having to opt-out of
  it.

This series depends on the ELD mutex series [1]

[1] https://lore.kernel.org/r/20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03 at linaro.org

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
Changes in v6:
- Dropped extra checks on the EDID (Jani)
- Reworked drmm_connector_hdmi_init(), splitting the codec init to a
  separate optional function rather than passing arguments through
  drm_connector (Maxime)
- Reworked EDID update functions (Maxime, Jani)
- No longer refresh the EDID in vc4_hdmi_connector_get_modes(), it is
  redundant as vc4_hdmi_connector_detect_cxtx() already does that.
- Link to v5: https://lore.kernel.org/r/20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a at linaro.org

Changes in v5:
- Moved prototypes from drm_internal.h to
  drm_connector_hdmi_codec_internal.h (Jani)
- Rebased on top of ELD mutex series, resolving the long-standing FIXME
- Converted the VC4 driver (compile-tested only)
- Link to v4: https://lore.kernel.org/r/20241122-drm-bridge-hdmi-connector-v4-0-b4d69d6e3bd9 at linaro.org

Changes in v4:
- Added forward declaration of struct drm_edid (LKP)
- Fixed kerneldoc for drm_atomic_helper_connector_hdmi_update_edid().
- Link to v3: https://lore.kernel.org/r/20241109-drm-bridge-hdmi-connector-v3-0-c15afdca5884 at linaro.org

Changes in v3:
- Dropped RFC status
- Fixed drm_connector_hdmi_codec_init() kerneldoc (LKP)
- Dropped double underscore prefix from
  __drm_atomic_helper_connector_hdmi_update_edid() (Jani)
- Moved drm_edid_free() from
  drm_atomic_helper_connector_hdmi_update_edid() to the caller's side
  (Jani)
- Link to v2: https://lore.kernel.org/r/20241101-drm-bridge-hdmi-connector-v2-0-739ef9addf9e at linaro.org

Changes in v2:
- Use drm_atomic_get_old_connector_for_encoder in atomic_disable() to
  prevent it from crashing
- Reworked HDMI codec init/exit, removing drmm_ calls (Maxime)
- Drafted the helper to be called from .detect_ctx() that performs HDMI
  Connector maintenance duties (Maxime)
- Moved no_capture_mute to struct hdmi_codec_pdata
- Link to v1: https://lore.kernel.org/r/20240615-drm-bridge-hdmi-connector-v1-0-d59fc7865ab2 at linaro.org

---
Dmitry Baryshkov (10):
      ASoC: hdmi-codec: pass data to get_dai_id too
      ASoC: hdmi-codec: move no_capture_mute to struct hdmi_codec_pdata
      drm/connector: implement generic HDMI codec helpers
      drm/bridge: connector: add support for HDMI codec framework
      drm/bridge: lt9611: switch to using the DRM HDMI codec framework
      drm/display/hdmi: implement hotplug functions
      drm/bridge_connector: hook drm_atomic_helper_connector_hdmi_hotplug_edid()
      drm/vc4: hdmi: switch to using generic HDMI Codec infrastructure
      drm/vc4: hdmi: stop rereading EDID in get_modes()
      drm/vc4: hdmi: use drm_atomic_helper_connector_hdmi_hotplug_edid()

 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c     |   3 +-
 drivers/gpu/drm/bridge/analogix/anx7625.c          |   3 +-
 drivers/gpu/drm/bridge/ite-it66121.c               |   2 +-
 drivers/gpu/drm/bridge/lontium-lt9611.c            | 169 ++++++++-----------
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c         |   3 +-
 drivers/gpu/drm/bridge/sii902x.c                   |   5 +-
 .../gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c    |   3 +-
 drivers/gpu/drm/display/drm_bridge_connector.c     | 127 +++++++++++++-
 drivers/gpu/drm/display/drm_hdmi_state_helper.c    |  61 +++++++
 drivers/gpu/drm/drm_connector.c                    |   5 +
 drivers/gpu/drm/drm_connector_hdmi_codec.c         | 185 +++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_hdmi.c               |   2 +-
 drivers/gpu/drm/i2c/tda998x_drv.c                  |   2 +-
 drivers/gpu/drm/mediatek/mtk_dp.c                  |   2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c                |   2 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c             |   2 +-
 drivers/gpu/drm/sti/sti_hdmi.c                     |   2 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c                     |  98 ++---------
 drivers/gpu/drm/vc4/vc4_hdmi.h                     |   2 -
 include/drm/display/drm_hdmi_state_helper.h        |   8 +
 include/drm/drm_bridge.h                           |  38 +++++
 include/drm/drm_connector.h                        |  80 +++++++++
 include/sound/hdmi-codec.h                         |   7 +-
 sound/soc/codecs/hdmi-codec.c                      |   4 +-
 25 files changed, 610 insertions(+), 206 deletions(-)
---
base-commit: 84e541b1e58e04d808e1bb13ef566ffbe87aa89b
change-id: 20240530-drm-bridge-hdmi-connector-9b0f6725973e
prerequisite-change-id: 20241201-drm-connector-eld-mutex-8a39a35e9a38:v2
prerequisite-patch-id: 8373a0638371955d1a695a6253a5429c5c79ee05
prerequisite-patch-id: cd898cf6d758d05fda796b0ab685ed53d7ccd72e
prerequisite-patch-id: 92115dfe744bb79f3ef0a10fc1fb3c8ef22f3bda
prerequisite-patch-id: cc8334b2d881be3418f1d4d2fdea8b05776fdb73
prerequisite-patch-id: 8c6c14a1dc11e4b70ea67b25dc3d2f6ef3234160
prerequisite-patch-id: e0dbd26699df8fcde52a46a66e4ab4dc705b2c2d
prerequisite-patch-id: c6ca8b52338034569c09e35061d34b277a876253
prerequisite-patch-id: 32bdfe82c8f8573fc9132395520bf6ed949b8915
prerequisite-patch-id: 865b400514c2207990c07d9f789c05e414d19fd6
prerequisite-patch-id: 0e05e8ce53477acfc686620b9e212763ad3058aa

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:15:55 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:15:55 +0200
Subject: [PATCH v6 01/10] ASoC: hdmi-codec: pass data to get_dai_id too
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-1-50dc145a9c06@linaro.org>

The upcoming DRM connector HDMI codec implementation is going to use
codec-specific data in the .get_dai_id to get drm_connector. Pass data
to the callback, as it is done with other hdmi_codec_ops callbacks.

Acked-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c      | 3 ++-
 drivers/gpu/drm/bridge/analogix/anx7625.c           | 3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611.c             | 3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c          | 3 ++-
 drivers/gpu/drm/bridge/sii902x.c                    | 3 ++-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 3 ++-
 include/sound/hdmi-codec.h                          | 3 ++-
 sound/soc/codecs/hdmi-codec.c                       | 2 +-
 8 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
index 61f4a38e7d2bf6905683cbc9e762b28ecc999d05..51fb9a574b4e28450b2598a92e2930ace5128b71 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -204,7 +204,8 @@ static void audio_shutdown(struct device *dev, void *data)
 }
 
 static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-					struct device_node *endpoint)
+					struct device_node *endpoint,
+					void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index c036bbc92ba96ec4663c55cca091cd5da9f6d271..943dd3cf57738d8c232d57d793756eb2e3bf1c5a 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1952,7 +1952,8 @@ static void anx7625_audio_shutdown(struct device *dev, void *data)
 }
 
 static int anx7625_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				       struct device_node *endpoint)
+				       struct device_node *endpoint,
+				       void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 1ffbe473e4103dfc315a8cd3571e9407bf518797..60b7305c0fd1935e35742713c78937392b7faa79 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -1057,7 +1057,8 @@ static void lt9611_audio_shutdown(struct device *dev, void *data)
 }
 
 static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				      struct device_node *endpoint)
+				      struct device_node *endpoint,
+				      void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index f89af8203c9d67cb05b629b27f66cf996baedd16..77bc09b875323d88f7346db9d24ea89a355c99b1 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -522,7 +522,8 @@ static void lt9611uxc_audio_shutdown(struct device *dev, void *data)
 }
 
 static int lt9611uxc_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-					 struct device_node *endpoint)
+					 struct device_node *endpoint,
+					 void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 9be9cc5b902594ebe6e1ac29ab8684623e336796..f0be803cc2274ca2199ed7661cf752b0a91434b6 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -815,7 +815,8 @@ static int sii902x_audio_get_eld(struct device *dev, void *data,
 }
 
 static int sii902x_audio_get_dai_id(struct snd_soc_component *component,
-				    struct device_node *endpoint)
+				    struct device_node *endpoint,
+				    void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index 26c187d20d973dc65801a3baa59ecf57d20072eb..86c412e9cbc80bb82bad5db3aa0263a7acd9c2d7 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -148,7 +148,8 @@ static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, uint8_t *buf,
 }
 
 static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				  struct device_node *endpoint)
+				  struct device_node *endpoint,
+				  void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index 5e1a9eafd10f5d4f831abbb6f4c0fff661909584..b3407b47b4a7878532ecf3b08eeecd443d6fdb07 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -105,7 +105,8 @@ struct hdmi_codec_ops {
 	 * Optional
 	 */
 	int (*get_dai_id)(struct snd_soc_component *comment,
-			  struct device_node *endpoint);
+			  struct device_node *endpoint,
+			  void *data);
 
 	/*
 	 * Hook callback function to handle connector plug event.
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index d9df29a26f4f213a30a2ebcdb63a593f9cf4b901..f536ca60e162dca6b50b37854ca6de2c114bc2a1 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -995,7 +995,7 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
 	int ret = -ENOTSUPP; /* see snd_soc_get_dai_id() */
 
 	if (hcp->hcd.ops->get_dai_id)
-		ret = hcp->hcd.ops->get_dai_id(component, endpoint);
+		ret = hcp->hcd.ops->get_dai_id(component, endpoint, hcp->hcd.data);
 
 	return ret;
 }

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:15:56 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:15:56 +0200
Subject: [PATCH v6 02/10] ASoC: hdmi-codec: move no_capture_mute to struct
 hdmi_codec_pdata
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-2-50dc145a9c06@linaro.org>

The no_capture_mute flag might differ from platform to platform,
especially in the case of the wrapping implementations, like the
upcoming DRM HDMI Codec framework. Move the flag next to all other flags
in struct hdmi_codec_pdata.

Acked-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/ite-it66121.c   | 2 +-
 drivers/gpu/drm/bridge/sii902x.c       | 2 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c   | 2 +-
 drivers/gpu/drm/i2c/tda998x_drv.c      | 2 +-
 drivers/gpu/drm/mediatek/mtk_dp.c      | 2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c    | 2 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +-
 drivers/gpu/drm/sti/sti_hdmi.c         | 2 +-
 include/sound/hdmi-codec.h             | 4 +---
 sound/soc/codecs/hdmi-codec.c          | 2 +-
 10 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c
index 940083e5d2ddbfc56f14e2bdc6ddd0b9dd50b1f8..7734e389ca7692f7880aa9b8650e45aab228c7fd 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -1466,7 +1466,6 @@ static const struct hdmi_codec_ops it66121_audio_codec_ops = {
 	.audio_shutdown = it66121_audio_shutdown,
 	.mute_stream = it66121_audio_mute,
 	.get_eld = it66121_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev)
@@ -1476,6 +1475,7 @@ static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev)
 		.i2s = 1, /* Only i2s support for now */
 		.spdif = 0,
 		.max_i2s_channels = 8,
+		.no_capture_mute = 1,
 	};
 
 	dev_dbg(dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index f0be803cc2274ca2199ed7661cf752b0a91434b6..5248676b0036a7e8f2142bd2f099c36efb529471 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -841,7 +841,6 @@ static const struct hdmi_codec_ops sii902x_audio_codec_ops = {
 	.mute_stream = sii902x_audio_mute,
 	.get_eld = sii902x_audio_get_eld,
 	.get_dai_id = sii902x_audio_get_dai_id,
-	.no_capture_mute = 1,
 };
 
 static int sii902x_audio_codec_init(struct sii902x *sii902x,
@@ -864,6 +863,7 @@ static int sii902x_audio_codec_init(struct sii902x *sii902x,
 		.i2s = 1, /* Only i2s support for now. */
 		.spdif = 0,
 		.max_i2s_channels = 0,
+		.no_capture_mute = 1,
 	};
 	u8 lanes[4];
 	int num_lanes, i;
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 6fc537c9048f5c8e57e30f083121c9aea6b99a5f..5130e96acc34c28fb7a509b8b2a858ad465137a2 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1660,7 +1660,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = hdmi_audio_shutdown,
 	.mute_stream = hdmi_audio_mute,
 	.get_eld = hdmi_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int hdmi_register_audio_device(struct hdmi_context *hdata)
@@ -1669,6 +1668,7 @@ static int hdmi_register_audio_device(struct hdmi_context *hdata)
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 6,
 		.i2s = 1,
+		.no_capture_mute = 1,
 	};
 
 	hdata->audio.pdev = platform_device_register_data(
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 2160f05bbd16d2346e27365e5549b75ad26fdcb9..10a4195d667ff577183788f8fc7ca806660e2b9c 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1165,7 +1165,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = tda998x_audio_shutdown,
 	.mute_stream = tda998x_audio_mute_stream,
 	.get_eld = tda998x_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int tda998x_audio_codec_init(struct tda998x_priv *priv,
@@ -1176,6 +1175,7 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
 		.max_i2s_channels = 2,
 		.no_i2s_capture = 1,
 		.no_spdif_capture = 1,
+		.no_capture_mute = 1,
 	};
 
 	if (priv->audio_port_enable[AUDIO_ROUTE_I2S])
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 1cc916b164713d71461a0b2ad370032a14604be6..6a42459792ec75692fadb45a75b138fc43cc37a2 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -2615,7 +2615,6 @@ static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = {
 	.audio_shutdown = mtk_dp_audio_shutdown,
 	.get_eld = mtk_dp_audio_get_eld,
 	.hook_plugged_cb = mtk_dp_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int mtk_dp_register_audio_driver(struct device *dev)
@@ -2626,6 +2625,7 @@ static int mtk_dp_register_audio_driver(struct device *dev)
 		.max_i2s_channels = 8,
 		.i2s = 1,
 		.data = mtk_dp,
+		.no_capture_mute = 1,
 	};
 
 	mtk_dp->audio_pdev = platform_device_register_data(dev,
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 7687f673964ec7df0d76328a43ed76d71b192350..a4b144b3bda8362a6c6c303723c6d3eef9ca338e 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1660,7 +1660,6 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
 	.mute_stream = mtk_hdmi_audio_mute,
 	.get_eld = mtk_hdmi_audio_get_eld,
 	.hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int mtk_hdmi_register_audio_driver(struct device *dev)
@@ -1671,6 +1670,7 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
 		.max_i2s_channels = 2,
 		.i2s = 1,
 		.data = hdmi,
+		.no_capture_mute = 1,
 	};
 	struct platform_device *pdev;
 
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index f576b1aa86d1434d75b3770e08d91537aca4f5c4..5c2c124a7a38fbadaec554f08797020260e29045 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -885,7 +885,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.mute_stream = cdn_dp_audio_mute_stream,
 	.get_eld = cdn_dp_audio_get_eld,
 	.hook_plugged_cb = cdn_dp_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
@@ -896,6 +895,7 @@ static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
 		.spdif = 1,
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 8,
+		.no_capture_mute = 1,
 	};
 
 	dp->audio_pdev = platform_device_register_data(
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 3c8f3532c79723e7b1a720c855c90e40584cc6ca..6dbe3d0b7004e6d587bd868907d45e7f75c345d9 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -1237,7 +1237,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = hdmi_audio_shutdown,
 	.mute_stream = hdmi_audio_mute,
 	.get_eld = hdmi_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int sti_hdmi_register_audio_driver(struct device *dev,
@@ -1247,6 +1246,7 @@ static int sti_hdmi_register_audio_driver(struct device *dev,
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 8,
 		.i2s = 1,
+		.no_capture_mute = 1,
 	};
 
 	DRM_DEBUG_DRIVER("\n");
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index b3407b47b4a7878532ecf3b08eeecd443d6fdb07..b220072cfa1baf503efbe2d530d7e8392dc16603 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -115,9 +115,6 @@ struct hdmi_codec_ops {
 	int (*hook_plugged_cb)(struct device *dev, void *data,
 			       hdmi_codec_plugged_cb fn,
 			       struct device *codec_dev);
-
-	/* bit field */
-	unsigned int no_capture_mute:1;
 };
 
 /* HDMI codec initalization data */
@@ -129,6 +126,7 @@ struct hdmi_codec_pdata {
 	uint spdif:1;
 	uint no_spdif_playback:1;
 	uint no_spdif_capture:1;
+	uint no_capture_mute:1;
 	int max_i2s_channels;
 	void *data;
 };
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index f536ca60e162dca6b50b37854ca6de2c114bc2a1..69f98975e14ae367f482862724a358eb138ebf6a 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -714,7 +714,7 @@ static int hdmi_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
 	 */
 	if (hcp->hcd.ops->mute_stream &&
 	    (direction == SNDRV_PCM_STREAM_PLAYBACK ||
-	     !hcp->hcd.ops->no_capture_mute))
+	     !hcp->hcd.no_capture_mute))
 		return hcp->hcd.ops->mute_stream(dai->dev->parent,
 						 hcp->hcd.data,
 						 mute, direction);

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:15:57 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:15:57 +0200
Subject: [PATCH v6 03/10] drm/connector: implement generic HDMI codec
 helpers
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-3-50dc145a9c06@linaro.org>

Several DRM drivers implement HDMI codec support (despite its name it
applies to both HDMI and DisplayPort drivers). Implement generic
framework to be used by these drivers. This removes a requirement to
implement get_eld() callback and provides default implementation for
codec's plug handling.

The framework is integrated with the DRM HDMI Connector framework, but
can be used by DisplayPort drivers.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/Makefile                   |   1 +
 drivers/gpu/drm/drm_connector.c            |   5 +
 drivers/gpu/drm/drm_connector_hdmi_codec.c | 185 +++++++++++++++++++++++++++++
 include/drm/drm_connector.h                |  80 +++++++++++++
 4 files changed, 271 insertions(+)

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 1677c1f335fbb0c6114bdb4cc0b12eb407d84564..afdd9268ca23ac7602e73bbe45f3f9cd090a3afd 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -42,6 +42,7 @@ drm-y := \
 	drm_cache.o \
 	drm_color_mgmt.o \
 	drm_connector.o \
+	drm_connector_hdmi_codec.o \
 	drm_crtc.o \
 	drm_displayid.o \
 	drm_drv.o \
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index bbdaaf7022b62d84594a29f1b60144920903a99a..4abfbded962bf45b793a2bd5b1b5c4d9f478a1f7 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -33,6 +33,7 @@
 #include <drm/drm_sysfs.h>
 #include <drm/drm_utils.h>
 
+#include <linux/platform_device.h>
 #include <linux/property.h>
 #include <linux/uaccess.h>
 
@@ -280,6 +281,7 @@ static int __drm_connector_init(struct drm_device *dev,
 	mutex_init(&connector->eld_mutex);
 	mutex_init(&connector->edid_override_mutex);
 	mutex_init(&connector->hdmi.infoframes.lock);
+	mutex_init(&connector->hdmi_codec.lock);
 	connector->edid_blob_ptr = NULL;
 	connector->epoch_counter = 0;
 	connector->tile_blob_ptr = NULL;
@@ -632,6 +634,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		    DRM_CONNECTOR_REGISTERED))
 		drm_connector_unregister(connector);
 
+	platform_device_unregister(connector->hdmi_codec.codec_pdev);
+
 	if (connector->privacy_screen) {
 		drm_privacy_screen_put(connector->privacy_screen);
 		connector->privacy_screen = NULL;
@@ -670,6 +674,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		connector->funcs->atomic_destroy_state(connector,
 						       connector->state);
 
+	mutex_destroy(&connector->hdmi_codec.lock);
 	mutex_destroy(&connector->hdmi.infoframes.lock);
 	mutex_destroy(&connector->mutex);
 
diff --git a/drivers/gpu/drm/drm_connector_hdmi_codec.c b/drivers/gpu/drm/drm_connector_hdmi_codec.c
new file mode 100644
index 0000000000000000000000000000000000000000..1934fb53b4d128434559970c9fea548bbc4bedda
--- /dev/null
+++ b/drivers/gpu/drm/drm_connector_hdmi_codec.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2024 Linaro Ltd
+ */
+
+#include <linux/mutex.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+
+#include <drm/drm_connector.h>
+#include <drm/drm_device.h>
+
+#include <sound/hdmi-codec.h>
+
+static int drm_connector_hdmi_codec_audio_startup(struct device *dev, void *data)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_codec_funcs *funcs =
+		connector->hdmi.funcs->codec_funcs;
+
+	if (funcs->audio_startup)
+		return funcs->audio_startup(connector);
+
+	return 0;
+}
+
+static int drm_connector_hdmi_codec_prepare(struct device *dev, void *data,
+					    struct hdmi_codec_daifmt *fmt,
+					    struct hdmi_codec_params *hparms)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_codec_funcs *funcs =
+		connector->hdmi.funcs->codec_funcs;
+
+	return funcs->prepare(connector, fmt, hparms);
+}
+
+static void drm_connector_hdmi_codec_audio_shutdown(struct device *dev, void *data)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_codec_funcs *funcs =
+		connector->hdmi.funcs->codec_funcs;
+
+	return funcs->audio_shutdown(connector);
+}
+
+static int drm_connector_hdmi_codec_mute_stream(struct device *dev, void *data,
+						bool enable, int direction)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_codec_funcs *funcs =
+		connector->hdmi.funcs->codec_funcs;
+
+	if (funcs->mute_stream)
+		return funcs->mute_stream(connector, enable, direction);
+
+	return -ENOTSUPP;
+}
+
+static int drm_connector_hdmi_codec_get_dai_id(struct snd_soc_component *comment,
+		  struct device_node *endpoint,
+		  void *data)
+{
+	struct drm_connector *connector = data;
+	struct of_endpoint of_ep;
+	int ret;
+
+	if (connector->hdmi_codec.dai_port < 0)
+		return -ENOTSUPP;
+
+	ret = of_graph_parse_endpoint(endpoint, &of_ep);
+	if (ret < 0)
+		return ret;
+
+	if (of_ep.port == connector->hdmi_codec.dai_port)
+		return 0;
+
+	return -EINVAL;
+}
+
+static int drm_connector_hdmi_codec_get_eld(struct device *dev, void *data,
+					    uint8_t *buf, size_t len)
+{
+	struct drm_connector *connector = data;
+
+	mutex_lock(&connector->eld_mutex);
+	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
+	mutex_unlock(&connector->eld_mutex);
+
+	return 0;
+}
+
+static int drm_connector_hdmi_codec_hook_plugged_cb(struct device *dev,
+						    void *data,
+						    hdmi_codec_plugged_cb fn,
+						    struct device *codec_dev)
+{
+	struct drm_connector *connector = data;
+
+	mutex_lock(&connector->hdmi_codec.lock);
+
+	connector->hdmi_codec.plugged_cb = fn;
+	connector->hdmi_codec.plugged_cb_dev = codec_dev;
+
+	fn(codec_dev, connector->hdmi_codec.last_state);
+
+	mutex_unlock(&connector->hdmi_codec.lock);
+
+	return 0;
+}
+
+void drm_connector_hdmi_codec_plugged_notify(struct drm_connector *connector,
+					     bool plugged)
+{
+	mutex_lock(&connector->hdmi_codec.lock);
+
+	connector->hdmi_codec.last_state = plugged;
+
+	if (connector->hdmi_codec.plugged_cb &&
+	    connector->hdmi_codec.plugged_cb_dev)
+		connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev,
+						 connector->hdmi_codec.last_state);
+
+	mutex_unlock(&connector->hdmi_codec.lock);
+}
+EXPORT_SYMBOL(drm_connector_hdmi_codec_plugged_notify);
+
+static const struct hdmi_codec_ops drm_connector_hdmi_codec_ops = {
+	.audio_startup = drm_connector_hdmi_codec_audio_startup,
+	.prepare = drm_connector_hdmi_codec_prepare,
+	.audio_shutdown = drm_connector_hdmi_codec_audio_shutdown,
+	.mute_stream = drm_connector_hdmi_codec_mute_stream,
+	.get_eld = drm_connector_hdmi_codec_get_eld,
+	.get_dai_id = drm_connector_hdmi_codec_get_dai_id,
+	.hook_plugged_cb = drm_connector_hdmi_codec_hook_plugged_cb,
+};
+
+/**
+ * drm_connector_hdmi_codec_init - Initialize HDMI Codec device for the DRM connector
+ * @connector: A pointer to the connector to allocate codec for
+ * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
+ * @max_i2s_playback_channels: maximum number of playback I2S channels
+ * @spdif_playback: set if HDMI codec has S/PDIF playback port
+ * @dai_port: sound DAI port, -1 if it is not enabled
+ *
+ * Create a HDMI codec device to be used with the specified connector.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_connector_hdmi_codec_init(struct drm_connector *connector,
+				  struct device *hdmi_codec_dev,
+				  unsigned int max_i2s_playback_channels,
+				  bool spdif_playback,
+				  int dai_port)
+{
+	struct hdmi_codec_pdata codec_pdata = {
+		.ops = &drm_connector_hdmi_codec_ops,
+		.max_i2s_channels = max_i2s_playback_channels,
+		.i2s = !!max_i2s_playback_channels,
+		.spdif = spdif_playback,
+		.no_i2s_capture = true,
+		.no_spdif_capture = true,
+		.data = connector,
+	};
+	struct platform_device *pdev;
+
+	connector->hdmi_codec.dai_port = dai_port;
+
+	if (!connector->hdmi.funcs->codec_funcs->prepare ||
+	    !connector->hdmi.funcs->codec_funcs->audio_shutdown)
+		return -EINVAL;
+
+	pdev = platform_device_register_data(hdmi_codec_dev,
+					     HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO,
+					     &codec_pdata, sizeof(codec_pdata));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	connector->hdmi_codec.codec_pdev = pdev;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_hdmi_codec_init);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 1e2b25e204cb523d61d30f5409faa059bf2b86eb..1d113c0ceec7ce8196a412d7c00a1737175c6fbe 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -46,6 +46,8 @@ struct drm_property_blob;
 struct drm_printer;
 struct drm_privacy_screen;
 struct edid;
+struct hdmi_codec_daifmt;
+struct hdmi_codec_params;
 struct i2c_adapter;
 
 enum drm_connector_force {
@@ -1141,6 +1143,52 @@ struct drm_connector_state {
 	struct drm_connector_hdmi_state hdmi;
 };
 
+struct drm_connector_hdmi_codec_funcs {
+	/**
+	 * @audio_startup:
+	 *
+	 * Called when ASoC starts an audio stream setup. The
+	 * @hdmi_audio_startup is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*audio_startup)(struct drm_connector *connector);
+
+	/**
+	 * @prepare:
+	 * Configures HDMI-encoder for audio stream. Can be called
+	 * multiple times for each setup. Mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*prepare)(struct drm_connector *connector,
+		       struct hdmi_codec_daifmt *fmt,
+		       struct hdmi_codec_params *hparms);
+	/**
+	 * @audio_shutdown:
+	 *
+	 * Shut down the audio stream. Mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	void (*audio_shutdown)(struct drm_connector *connector);
+
+	/**
+	 * @mute_stream:
+	 *
+	 * Mute/unmute HDMI audio stream. The @mute_stream callback is
+	 * optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*mute_stream)(struct drm_connector *connector,
+			   bool enable, int direction);
+};
+
 /**
  * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
  */
@@ -1198,6 +1246,14 @@ struct drm_connector_hdmi_funcs {
 	int (*write_infoframe)(struct drm_connector *connector,
 			       enum hdmi_infoframe_type type,
 			       const u8 *buffer, size_t len);
+
+	/**
+	 * @codec_funcs:
+	 *
+	 * Implementation of the HDMI codec functionality to be used by the DRM
+	 * HDMI Codec framework.
+	 */
+	const struct drm_connector_hdmi_codec_funcs *codec_funcs;
 };
 
 /**
@@ -1660,6 +1716,17 @@ struct drm_cmdline_mode {
 	bool tv_mode_specified;
 };
 
+struct drm_connector_hdmi_codec {
+	struct platform_device *codec_pdev;
+
+	struct mutex lock; /* protects last_state and plugged_cb */
+	void (*plugged_cb)(struct device *dev, bool plugged);
+	struct device *plugged_cb_dev;
+	bool last_state;
+
+	int dai_port;
+};
+
 /*
  * struct drm_connector_hdmi - DRM Connector HDMI-related structure
  */
@@ -2121,6 +2188,11 @@ struct drm_connector {
 	 * @hdmi: HDMI-related variable and properties.
 	 */
 	struct drm_connector_hdmi hdmi;
+
+	/**
+	 * @hdmi_codec: HDMI codec properties and non-DRM state.
+	 */
+	struct drm_connector_hdmi_codec hdmi_codec;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -2148,12 +2220,20 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct i2c_adapter *ddc,
 			     unsigned long supported_formats,
 			     unsigned int max_bpc);
+int drm_connector_hdmi_codec_init(struct drm_connector *connector,
+				  struct device *hdmi_codec_dev,
+				  unsigned int max_i2s_playback_channels,
+				  bool spdif_playback,
+				  int sound_dai_port);
 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);
 int drm_connector_attach_encoder(struct drm_connector *connector,
 				      struct drm_encoder *encoder);
 
+void drm_connector_hdmi_codec_plugged_notify(struct drm_connector *connector,
+					     bool plugged);
+
 void drm_connector_cleanup(struct drm_connector *connector);
 
 static inline unsigned int drm_connector_index(const struct drm_connector *connector)

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:15:58 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:15:58 +0200
Subject: [PATCH v6 04/10] drm/bridge: connector: add support for HDMI codec
 framework
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-4-50dc145a9c06@linaro.org>

Add necessary glue code to be able to use new HDMI codec framework from
the DRM bridge drivers. The drm_bridge implements a limited set of the
hdmi_codec_ops interface, with the functions accepting both
drm_connector and drm_bridge instead of just a generic void pointer.

This framework is integrated with the DRM HDMI Connector framework, but
can also be used for DisplayPort connectors.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 100 ++++++++++++++++++++++++-
 include/drm/drm_bridge.h                       |  38 ++++++++++
 2 files changed, 134 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 512ced87ea18c74e182a558a686ddd83de891814..4fa1bb73d430d02d5b79a1a184c203ec9e9c66e7 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -21,6 +21,8 @@
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_hdmi_state_helper.h>
 
+#include <sound/hdmi-codec.h>
+
 /**
  * DOC: overview
  *
@@ -368,10 +370,80 @@ static int drm_bridge_connector_write_infoframe(struct drm_connector *connector,
 	return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len);
 }
 
+static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	if (bridge->funcs->hdmi_codec_audio_startup)
+		return bridge->funcs->hdmi_codec_audio_startup(connector, bridge);
+	else
+		return 0;
+}
+
+static int drm_bridge_connector_prepare(struct drm_connector *connector,
+					struct hdmi_codec_daifmt *fmt,
+					struct hdmi_codec_params *hparms)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	return bridge->funcs->hdmi_codec_prepare(connector, bridge, fmt, hparms);
+}
+
+static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return;
+
+	bridge->funcs->hdmi_codec_audio_shutdown(connector, bridge);
+}
+
+static int drm_bridge_connector_mute_stream(struct drm_connector *connector,
+					    bool enable, int direction)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	if (bridge->funcs->hdmi_codec_mute_stream)
+		return bridge->funcs->hdmi_codec_mute_stream(connector, bridge,
+							     enable, direction);
+	else
+		return -ENOTSUPP;
+}
+
+static const struct drm_connector_hdmi_codec_funcs drm_bridge_connector_hdmi_codec_funcs = {
+	.audio_startup = drm_bridge_connector_audio_startup,
+	.prepare = drm_bridge_connector_prepare,
+	.audio_shutdown = drm_bridge_connector_audio_shutdown,
+	.mute_stream = drm_bridge_connector_mute_stream,
+};
+
 static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
 	.tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid,
 	.clear_infoframe = drm_bridge_connector_clear_infoframe,
 	.write_infoframe = drm_bridge_connector_write_infoframe,
+	.codec_funcs = &drm_bridge_connector_hdmi_codec_funcs,
 };
 
 /* -----------------------------------------------------------------------------
@@ -473,7 +545,9 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
 		return ERR_PTR(-EINVAL);
 
-	if (bridge_connector->bridge_hdmi)
+	if (bridge_connector->bridge_hdmi) {
+		bridge = bridge_connector->bridge_hdmi;
+
 		ret = drmm_connector_hdmi_init(drm, connector,
 					       bridge_connector->bridge_hdmi->vendor,
 					       bridge_connector->bridge_hdmi->product,
@@ -482,12 +556,30 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 					       connector_type, ddc,
 					       supported_formats,
 					       max_bpc);
-	else
+		if (ret)
+			return ERR_PTR(ret);
+
+		if (bridge->hdmi_codec_max_i2s_playback_channels ||
+		    bridge->hdmi_codec_spdif_playback) {
+			if (!bridge->funcs->hdmi_codec_prepare ||
+			    !bridge->funcs->hdmi_codec_audio_shutdown)
+				return ERR_PTR(-EINVAL);
+
+			ret = drm_connector_hdmi_codec_init(connector,
+							    bridge->hdmi_codec_dev,
+							    bridge->hdmi_codec_max_i2s_playback_channels,
+							    bridge->hdmi_codec_spdif_playback,
+							    bridge->hdmi_codec_dai_port);
+			if (ret)
+				return ERR_PTR(ret);
+		}
+	} else {
 		ret = drmm_connector_init(drm, connector,
 					  &drm_bridge_connector_funcs,
 					  connector_type, ddc);
-	if (ret)
-		return ERR_PTR(ret);
+		if (ret)
+			return ERR_PTR(ret);
+	}
 
 	drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs);
 
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index e8d735b7f6a480468c88287e2517b387ceec0f22..fd7ad7315a8bfda90f02b0704c33ba0e356899fb 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -41,6 +41,8 @@ struct drm_display_info;
 struct drm_minor;
 struct drm_panel;
 struct edid;
+struct hdmi_codec_daifmt;
+struct hdmi_codec_params;
 struct i2c_adapter;
 
 /**
@@ -676,6 +678,21 @@ struct drm_bridge_funcs {
 				    enum hdmi_infoframe_type type,
 				    const u8 *buffer, size_t len);
 
+	int (*hdmi_codec_audio_startup)(struct drm_connector *connector,
+					struct drm_bridge *bridge);
+
+	int (*hdmi_codec_prepare)(struct drm_connector *connector,
+				  struct drm_bridge *bridge,
+				  struct hdmi_codec_daifmt *fmt,
+				  struct hdmi_codec_params *hparms);
+
+	void (*hdmi_codec_audio_shutdown)(struct drm_connector *connector,
+					  struct drm_bridge *bridge);
+
+	int (*hdmi_codec_mute_stream)(struct drm_connector *connector,
+				      struct drm_bridge *bridge,
+				      bool enable, int direction);
+
 	/**
 	 * @debugfs_init:
 	 *
@@ -859,6 +876,27 @@ struct drm_bridge {
 	 * @DRM_BRIDGE_OP_HDMI is set.
 	 */
 	unsigned int max_bpc;
+
+	/**
+	 * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
+	 */
+	struct device *hdmi_codec_dev;
+
+	/**
+	 * @hdmi_codec_max_i2s_playback_channels: maximum number of playback
+	 * I2S channels for the HDMI codec
+	 */
+	int hdmi_codec_max_i2s_playback_channels;
+
+	/**
+	 * @hdmi_codec_spdif_playback: set if HDMI codec has S/PDIF playback port
+	 */
+	unsigned int hdmi_codec_spdif_playback : 1;
+
+	/**
+	 * @hdmi_codec_dai_port: sound DAI port, -1 if it is not enabled
+	 */
+	int hdmi_codec_dai_port;
 };
 
 static inline struct drm_bridge *

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:16:00 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:16:00 +0200
Subject: [PATCH v6 06/10] drm/display/hdmi: implement hotplug functions
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-6-50dc145a9c06@linaro.org>

The HDMI Connectors need to perform a variety of tasks when the HDMI
connector state changes. Such tasks include setting or invalidating CEC
address, notifying HDMI codec driver, updating scrambler data, etc.

Implementing such tasks in a driver-specific callbacks is error prone.
Start implementing the generic helper function (currently handling only
the HDMI Codec framework) to be used by drivers utilizing HDMI Connector
framework.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_hdmi_state_helper.c | 61 +++++++++++++++++++++++++
 include/drm/display/drm_hdmi_state_helper.h     |  8 ++++
 2 files changed, 69 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index 80bf2829ba89b5f84fed4fa9eb1d6302e10a4f9e..4cdeb63688b9e48acd8e8ae87a45b6253f7dd12b 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -769,3 +769,64 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con
 	return ret;
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe);
+
+/**
+ * drm_atomic_helper_connector_hdmi_hotplug_edid - Handle the hotplug event for the HDMI connector passing custom EDID
+ * @connector: A pointer to the HDMI connector
+ * @status: Connection status
+ * @drm_edid: EDID to process
+ *
+ * This function should be called as a part of the .detect() / .detect_ctx()
+ * and .force() callbacks, updating the HDMI-specific connector's data. Most
+ * drivers should be able to use @drm_atomic_helper_connector_hdmi_hotplug()
+ * instead.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int
+drm_atomic_helper_connector_hdmi_hotplug_edid(struct drm_connector *connector,
+					      enum drm_connector_status status,
+					      const struct drm_edid *drm_edid)
+{
+	if (status == connector_status_disconnected) {
+		// TODO: also handle CEC and scramber, HDMI sink disconnected.
+		drm_connector_hdmi_codec_plugged_notify(connector, false);
+	}
+
+	drm_edid_connector_update(connector, drm_edid);
+
+	if (status == connector_status_connected) {
+		// TODO: also handle CEC and scramber, HDMI sink is now connected.
+		drm_connector_hdmi_codec_plugged_notify(connector, true);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_hotplug_edid);
+
+/**
+ * drm_atomic_helper_connector_hdmi_hotplug - Handle the hotplug event for the HDMI connector
+ * @connector: A pointer to the HDMI connector
+ * @status: Connection status
+ *
+ * This function should be called as a part of the .detect() / .detect_ctx()
+ * and .force() callbacks, updating the HDMI-specific connector's data.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int
+drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
+					 enum drm_connector_status status)
+{
+	const struct drm_edid *drm_edid;
+	int ret;
+
+	drm_edid = drm_edid_read(connector);
+	ret = drm_atomic_helper_connector_hdmi_hotplug_edid(connector, status, drm_edid);
+	drm_edid_free(drm_edid);
+
+	return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_hotplug);
diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h
index d6d65da6d8f9ee46de33114cce2d6fbe6098a862..4ffd40d73d50d89449508b7a5ce5836a596638a1 100644
--- a/include/drm/display/drm_hdmi_state_helper.h
+++ b/include/drm/display/drm_hdmi_state_helper.h
@@ -6,8 +6,11 @@
 struct drm_atomic_state;
 struct drm_connector;
 struct drm_connector_state;
+struct drm_edid;
 struct hdmi_audio_infoframe;
 
+enum drm_connector_status;
+
 void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
 					      struct drm_connector_state *new_conn_state);
 
@@ -19,6 +22,11 @@ int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector
 int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector);
 int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
 						       struct drm_atomic_state *state);
+int drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
+					     enum drm_connector_status status);
+int drm_atomic_helper_connector_hdmi_hotplug_edid(struct drm_connector *connector,
+						  enum drm_connector_status status,
+						  const struct drm_edid *drm_edid);
 
 enum drm_mode_status
 drm_hdmi_connector_mode_valid(struct drm_connector *connector,

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:16:04 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:16:04 +0200
Subject: [PATCH v6 10/10] drm/vc4: hdmi: use
 drm_atomic_helper_connector_hdmi_hotplug_edid()
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-10-50dc145a9c06@linaro.org>

Use the helper function to update the connector's information. This
makes sure that HDMI-related events are handled in a generic way.
Currently it is limited to the HDMI state reporting to the sound system.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 3364ef90968dad3074800f02926300ffceb75c69..3fe025251f939290bb4430e2f5163b6549479fc0 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -383,7 +383,6 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
 				    enum drm_connector_status status)
 {
 	struct drm_connector *connector = &vc4_hdmi->connector;
-	const struct drm_edid *drm_edid;
 	int ret;
 
 	/*
@@ -405,17 +404,14 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
 		return;
 	}
 
-	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
+	drm_atomic_helper_connector_hdmi_hotplug(connector, status);
 
-	drm_edid_connector_update(connector, drm_edid);
 	cec_s_phys_addr(vc4_hdmi->cec_adap,
 			connector->display_info.source_physical_address, false);
 
-	if (!drm_edid)
+	if (status != connector_status_connected)
 		return;
 
-	drm_edid_free(drm_edid);
-
 	for (;;) {
 		ret = vc4_hdmi_reset_link(connector, ctx);
 		if (ret == -EDEADLK) {

-- 
2.39.5



From sudeep.holla at arm.com  Fri Dec  6 02:21:46 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 6 Dec 2024 10:21:46 +0000
Subject: [PATCH 1/3] dt-bindings: arm,psci: Allow S2RAM power_state
 parameter description
In-Reply-To: <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
Message-ID: <Z1LQOmEfFy640PjG@bogus>

On Mon, Oct 28, 2024 at 03:22:57PM +0100, Konrad Dybcio wrote:
> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> 
> Certain firmware implementations (such as the ones found on Qualcomm
> SoCs between roughly 2015 and 2023) expose an S3-like S2RAM state
> through the CPU_SUSPEND call, as opposed to exposing PSCIv1.0's
> optional PSCI_SYSTEM_SUSPEND.
>

If so, can you elaborate why s2idle doesn't work as an alternative to what
you are hacking up here.

> This really doesn't work well with the model where we associate all
> calls to CPU_SUSPEND with cpuidle. Allow specifying a single special
> CPU_SUSPEND suspend parameter value that is to be treated just like
> SYSTEM_SUSPEND from the OS's point of view.
> 
> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/arm/psci.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml
> index cbb012e217ab80c1ca88e611e7acc06c6d56fad0..a6901878697c8e1ec1cbfed62298ae3bc58f2501 100644
> --- a/Documentation/devicetree/bindings/arm/psci.yaml
> +++ b/Documentation/devicetree/bindings/arm/psci.yaml
> @@ -98,6 +98,12 @@ properties:
>        [1] Kernel documentation - ARM idle states bindings
>          Documentation/devicetree/bindings/cpu/idle-states.yaml
>  
> +  arm,psci-s2ram-param:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      power_state parameter denoting the S2RAM/S3-like system suspend state

Yet another NACK as this corresponds to PSCI SYSTEM_SUSPEND and as per
specification it takes no such parameter. This is just misleading.

-- 
Regards,
Sudeep


From sudeep.holla at arm.com  Fri Dec  6 02:24:19 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 6 Dec 2024 10:24:19 +0000
Subject: [PATCH 3/3] firmware/psci: Allow specifying an S2RAM state
 through CPU_SUSPEND
In-Reply-To: <ZzSiM6Pn6A9e1QUD@lpieralisi>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-3-9fdd9a04b75c@oss.qualcomm.com>
 <ZzSiM6Pn6A9e1QUD@lpieralisi>
Message-ID: <Z1LQ0-3AVkVHgPaY@bogus>

On Wed, Nov 13, 2024 at 01:57:23PM +0100, Lorenzo Pieralisi wrote:
> On Mon, Oct 28, 2024 at 03:22:59PM +0100, Konrad Dybcio wrote:
> > From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> > 
> > Certain firmware implementations (such as the ones found on Qualcomm
> > SoCs between roughly 2015 and 2023) expose an S3-like S2RAM state
> > through the CPU_SUSPEND call.
> > 
> > This works exactly like SYSTEM_SUSPEND. The PSCI spec describes that
> > call as optional (and only introduced in PSCIv1.0), so not all
> > platforms expose it.
> > 
> > Marking a DT-described "domain-idle-state" as such isn't currently
> > well accounted for in the PSCI idle topology infrastructure: the
> > cpuidle and genpd framework are deeply intertwined, and trying to
> > separate them would cause more havoc than good.
> 
> I don't understand what you mean here please elaborate.
> 
> The part of the story I understand is that you have a system (well,
> firmware for an extended set of systems) that does not implement
> SYSTEM_SUSPEND but can reach a S2R like system state through the
> CPU_SUSPEND call. Firmware works in OS-initiated mode, idle-states
> should allow you to define idle states that allow the system to
> enter the S2R state through CPUidle.
> 
> Please explain to me what's missing.
> 
> > Instead, allow the specifying of a single CPU_SUSPEND sleep param
> > under the /psci node that shall be treated exactly like SYSTEM_SUSPEND
> > from Linux's POV. As a bonus, this way we also don't have to fight
> > with the genpd idle governor to avoid taking the S3-like state into
> > consideration.
> 
> That's not acceptable. I want to understand what's preventing this
> system to enter that state through suspend2idle and the mainline code.
> 
> > Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> > ---
> >  drivers/firmware/psci/psci.c | 36 +++++++++++++++++++++++++++++++-----
> >  1 file changed, 31 insertions(+), 5 deletions(-)
> 
> NACK
> 

+1, will wait for the response here before adding any more questions that
may lead to more confusion or discussion churn.

-- 
Regards,
Sudeep


From ryan.roberts at arm.com  Fri Dec  6 02:26:17 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri, 6 Dec 2024 10:26:17 +0000
Subject: [RFC PATCH v1 00/57] Boot-time page size selection for arm64
In-Reply-To: <20241206085026.32c89a03@mordecai.tesarici.cz>
References: <20241014105514.3206191-1-ryan.roberts@arm.com>
 <20241017142752.17f2c816@mordecai.tesarici.cz>
 <aa9a7118-3067-448e-aa34-bbc148c921a2@arm.com>
 <20241205182008.2b36476a@mordecai.tesarici.cz>
 <SN6PR02MB41571E0BD384C44C46127B49D4302@SN6PR02MB4157.namprd02.prod.outlook.com>
 <20241206085026.32c89a03@mordecai.tesarici.cz>
Message-ID: <bd4a30ca-6725-4c78-94ba-03581700bdcc@arm.com>

On 06/12/2024 07:50, Petr Tesarik wrote:
> On Thu, 5 Dec 2024 18:52:35 +0000
> Michael Kelley <mhklinux at outlook.com> wrote:
> 
>> From: Petr Tesarik <ptesarik at suse.com> Sent: Thursday, December 5, 2024 9:20 AM
>>>
>>> Hi Ryan,
>>>
>>> On Thu, 17 Oct 2024 13:32:43 +0100
>>> Ryan Roberts <ryan.roberts at arm.com> wrote:
>>>   
>>>> On 17/10/2024 13:27, Petr Tesarik wrote:  
>>>>> On Mon, 14 Oct 2024 11:55:11 +0100
>>>>> Ryan Roberts <ryan.roberts at arm.com> wrote:
>>>>>  
>>>>>> [...]
>>>>>> The series is arranged as follows:
>>>>>>
>>>>>>   - patch 1:	   Add macros required for converting non-arch code to support
>>>>>>   		   boot-time page size selection
>>>>>>   - patches 2-36:  Remove PAGE_SIZE compile-time constant assumption from all
>>>>>>   		   non-arch code  
>>>>>
>>>>> I have just tried to recompile the openSUSE kernel with these patches
>>>>> applied, and I'm running into this:
>>>>>
>>>>>   CC      arch/arm64/hyperv/hv_core.o
>>>>> In file included from ../arch/arm64/hyperv/hv_core.c:14:0:
>>>>> ../include/linux/hyperv.h:158:5: error: variably modified ?reserved2? at file scope
>>>>>   u8 reserved2[PAGE_SIZE - 68];
>>>>>      ^~~~~~~~~
>>>>>
>>>>> It looks like one more place which needs a patch, right?  
>>>>
>>>> As mentioned in the cover letter, so far I've only converted enough to get the
>>>> defconfig *image* building (i.e. no modules). If you are compiling a different
>>>> config or compiling the modules for defconfig, you will likely run into these
>>>> types of issues.
>>>>
>>>> That said, I do have some patches to fix Hyper-V, which Michael Kelley was kind
>>>> enough to send me.
>>>>
>>>> I understand that Suse might be able to help with wider performance testing - if
>>>> that's the reason you are trying to compile, you could send me your config and
>>>> I'll start working on fixing up other drivers?  
>>>
>>> This project was de-prioritised for some time, but I have just returned
>>> to it, and one of our test systems uses a Mellanox 5 NIC, which did not build.

No problem - I appreciate all the time you have spent on it so far!

>>>
>>> If you still have time to work on your patch series, please, can you
>>> look into enabling MLX5_CORE_EN?

I've also had other things that have been taking up my time. I'm planning to get
back to this series properly after Christmas and convert all the remaining
module code. I'm hoping that Michael's patch will solve your problem for now?

>>>
>>> Oh, and have you rebased the series to 6.12 yet?

Afraid the latest I have at the moment is based on v6.12-rc3. It also includes
all the changes from the review feedback:

https://gitlab.arm.com/linux-arm/linux-rr/-/tree/features/boot-time-page-size-v2-wip

>>>   
>>
>> FWIW, here's what I hacked together to compile and run the mlx5 driver in
>> a Hyper-V VM.  This was against a 6.11 kernel code base.
> 
> Wow! Thank you, Michael. I'll give it a try.

Yes, thanks, Michael - I'll take a look at this and integrate into my tree after
Christmas.

Thanks,
Ryan

> 
> Petr T



From kevin.brodsky at arm.com  Fri Dec  6 02:10:54 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:10:54 +0000
Subject: [RFC PATCH 00/16] pkeys-based page table hardening
Message-ID: <20241206101110.1646108-1-kevin.brodsky@arm.com>

This is a proposal to leverage protection keys (pkeys) to harden
critical kernel data, by making it mostly read-only. The series includes
a simple framework called "kpkeys" to manipulate pkeys for in-kernel use,
as well as a page table hardening feature based on that framework
(kpkeys_hardened_pgtables). Both are implemented on arm64 as a proof of
concept, but they are designed to be compatible with any architecture
implementing pkeys.

The proposed approach is a typical use of pkeys: the data to protect is
mapped with a given pkey P, and the pkey register is initially configured
to grant read-only access to P. Where the protected data needs to be
written to, the pkey register is temporarily switched to grant write
access to P on the current CPU.

The key fact this approach relies on is that the target data is
only written to via a limited and well-defined API. This makes it
possible to explicitly switch the pkey register where needed, without
introducing excessively invasive changes, and only for a small amount of
trusted code.

Page tables were chosen as they are a popular (and critical) target for
attacks, but there are of course many others - this is only a starting
point (see section "Further use-cases"). It has become more and more
common for accesses to such target data to be mediated by a hypervisor
in vendor kernels; the hope is that kpkeys can provide much of that
protection in a simpler manner. No benchmarking has been performed at
this stage, but the runtime overhead should also be lower (though likely
not negligible).


# kpkeys

The use of pkeys involves two separate mechanisms: assigning a pkey to
pages, and defining the pkeys -> permissions mapping via the pkey
register. This is implemented through the following interface:

- Pages in the linear mapping are assigned a pkey using set_memory_pkey().
  This is sufficient for this series, but of course higher-level
  interfaces can be introduced later to ask allocators to return pages
  marked with a given pkey. It should also be possible to extend this to
  vmalloc() if needed.

- The pkey register is configured based on a *kpkeys level*. kpkeys
  levels are simple integers that correspond to a given configuration,
  for instance:

  KPKEYS_LVL_DEFAULT:
        RW access to KPKEYS_PKEY_DEFAULT
        RO access to any other KPKEYS_PKEY_*

  KPKEYS_LVL_<FEAT>:
        RW access to KPKEYS_PKEY_DEFAULT
        RW access to KPKEYS_PKEY_<FEAT>
        RO access to any other KPKEYS_PKEY_*

  Only pkeys that are managed by the kpkeys framework are impacted;
  permissions for other pkeys are left unchanged (this allows for other
  schemes using pkeys to be used in parallel, and arch-specific use of
  certain pkeys).

  The kpkeys level is changed by calling kpkeys_set_level(), setting the
  pkey register accordingly and returning the original value. A
  subsequent call to kpkeys_restore_pkey_reg() restores the kpkeys
  level. The numeric value of KPKEYS_LVL_* (kpkeys level) is purely
  symbolic and thus generic, however each architecture is free to define
  KPKEYS_PKEY_* (pkey value).

# kpkeys_hardened_pgtables

The kpkeys_hardened_pgtables feature uses the interface above to make
the (kernel and user) page tables read-only by default, enabling write
access only in helpers such as set_pte(). One complication is that those
helpers as well as page table allocators are used very early, before
kpkeys become available. Enabling kpkeys_hardened_pgtables, if and when
kpkeys become available, is therefore done as follows:

1. A static key is turned on. This enables a transition to
   KPKEYS_LVL_PGTABLES in all helpers writing to page tables, and also
   impacts page table allocators (see step 3).

2. All pages holding kernel page tables are set to KPKEYS_PKEY_PGTABLES.
   This ensures they can only be written when runnning at
   KPKEYS_LVL_PGTABLES.

3. Page table allocators set the returned pages to KPKEYS_PKEY_PGTABLES
   (and the pkey is reset upon freeing). This ensures that all page
   tables are mapped with that privileged pkey.

# Threat model

The proposed scheme aims at mitigating data-only attacks (e.g.
use-after-free/cross-cache attacks). In other words, it is assumed that
control flow is not corrupted, and that the attacker does not achieve
arbitrary code execution. Nothing prevents the pkey register from being
set to its most permissive state - the assumption is that the register
is only modified on legitimate code paths.

A few related notes:

- Functions that set the pkey register are all implemented inline.
  Besides performance considerations, this is meant to avoid creating
  a function that can be used as a straightforward gadget to set the
  pkey register to an arbitrary value.

- kpkeys_set_level() only accepts a compile-time constant as argument,
  as a variable could be manipulated by an attacker. This could be
  relaxed but it seems unlikely that a variable kpkeys level would be
  needed in practice.

# Further use-cases

It should be possible to harden various targets using kpkeys, including:

- struct cred (enforcing a "mostly read-only" state once committed)

- fixmap (occasionally used even after early boot, e.g.
  set_swapper_pgd() in arch/arm64/mm/mmu.c)

- SELinux state (e.g. struct selinux_state::initialized)

... and many others.

kpkeys could also be used to strengthen the confidentiality of secret
data by making it completely inaccessible by default, and granting
read-only or read-write access as needed. This requires such data to be
rarely accessed (or via a limited interface only). One example on arm64
is the pointer authentication keys in thread_struct, whose leakage to
userspace would lead to pointer authentication being easily defeated.

# This series

The series is composed of two parts:

- The kpkeys framework (patch 1-7). The main API is introduced in
  <linux/kpkeys.h>, and it is implemented on arm64 using the POE
  (Permission Overlay Extension) feature.

- The kpkeys_hardened_pgtables feature (patch 8-16). <linux/kpkeys.h> is
  extended with an API to set page table pages to a given pkey and a
  guard object to switch kpkeys level accordingly, both gated on a
  static key. This is then used in generic and arm64 pgtable handling
  code as needed. Finally a simple KUnit-based test suite is added to
  demonstrate the page table protection.

The arm64 implementation should be considered a proof of concept only.
The enablement of POE for in-kernel use is incomplete; in particular
POR_EL1 (pkey register) should be reset on exception entry and restored
on exception return.

# Performance

No particular efforts were made to optimise the use of kpkeys at this
stage (and no benchmarking was performed either). There are two obvious
low-hanging fruits in the kpkeys_hardened_pgtables feature:

- Always switching kpkeys level in leaf helpers such as set_pte() can be
  very inefficient if many page table entries are updated in a row. Some
  sort of batching may be desirable.

- On arm64 specifically, the page table helpers typically perform an
  expensive ISB (Instruction Synchronisation Barrier) after writing to
  page tables. Since most of the cost of switching the arm64 pkey
  register (POR_EL1) comes from the following ISB, the overhead incurred
  by kpkeys_restore_pkey_reg() would be significantly reduced by merging
  its ISB with the pgtable helper's. That would however require more
  invasive changes, beyond simply adding a guard object.

# Open questions

A few aspects in this RFC that are debatable and/or worth discussing:

- There is currently no restriction on how kpkeys levels map to pkeys
  permissions. A typical approach is to allocate one pkey per level and
  make it writable at that level only. As the number of levels
  increases, we may however run out of pkeys, especially on arm64 (just
  8 pkeys with POE). Depending on the use-cases, it may be acceptable to
  use the same pkey for the data associated to multiple levels.

  Another potential concern is that a given piece of code may require
  write access to multiple privileged pkeys. This could be addressed by
  introducing a notion of hierarchy in trust levels, where Tn is able to
  write to memory owned by Tm if n >= m, for instance.

- kpkeys_set_level() and kpkeys_restore_pkey_reg() are not symmetric:
  the former takes a kpkeys level and returns a pkey register value, to
  be consumed by the latter. It would be more intuitive to manipulate
  kpkeys levels only. However this assumes that there is a 1:1 mapping
  between kpkeys levels and pkey register values, while in principle
  the mapping is 1:n (certain pkeys may be used outside the kpkeys
  framework).

- An architecture that supports kpkeys is expected to select
  CONFIG_ARCH_HAS_KPKEYS and always enable them if available - there is
  no CONFIG_KPKEYS to control this behaviour. Since this creates no
  significant overhead (at least on arm64), it seemed better to keep it
  simple. Each hardening feature does have its own option and arch
  opt-in if needed (CONFIG_KPKEYS_HARDENED_PGTABLES,
  CONFIG_ARCH_HAS_KPKEYS_HARDENED_PGTABLES).


Any comment or feedback will be highly appreciated, be it on the
high-level approach or implementation choices!

- Kevin

---
Cc: aruna.ramakrishna at oracle.com
Cc: broonie at kernel.org
Cc: catalin.marinas at arm.com
Cc: dave.hansen at linux.intel.com
Cc: jannh at google.com
Cc: jeffxu at chromium.org
Cc: joey.gouly at arm.com
Cc: kees at kernel.org
Cc: maz at kernel.org
Cc: pierre.langlois at arm.com
Cc: qperret at google.com
Cc: ryan.roberts at arm.com
Cc: will at kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: x86 at kernel.org
---
Kevin Brodsky (16):
  mm: Introduce kpkeys
  set_memory: Introduce set_memory_pkey() stub
  arm64: mm: Enable overlays for all EL1 indirect permissions
  arm64: Introduce por_set_pkey_perms() helper
  arm64: Implement asm/kpkeys.h using POE
  arm64: set_memory: Implement set_memory_pkey()
  arm64: Enable kpkeys
  mm: Introduce kernel_pgtables_set_pkey()
  mm: Introduce kpkeys_hardened_pgtables
  mm: Map page tables with privileged pkey
  arm64: kpkeys: Support KPKEYS_LVL_PGTABLES
  arm64: mm: Map p4d/pgd with privileged pkey
  arm64: mm: Reset pkey in __tlb_remove_table()
  arm64: mm: Guard page table writes with kpkeys
  arm64: Enable kpkeys_hardened_pgtables support
  mm: Add basic tests for kpkeys_hardened_pgtables

 arch/arm64/Kconfig                    |   2 +
 arch/arm64/include/asm/kpkeys.h       |  45 +++++++++
 arch/arm64/include/asm/pgalloc.h      |  21 +++-
 arch/arm64/include/asm/pgtable-prot.h |  16 ++--
 arch/arm64/include/asm/pgtable.h      |  19 +++-
 arch/arm64/include/asm/por.h          |   9 ++
 arch/arm64/include/asm/set_memory.h   |   4 +
 arch/arm64/include/asm/tlb.h          |   6 +-
 arch/arm64/kernel/cpufeature.c        |   5 +-
 arch/arm64/kernel/smp.c               |   2 +
 arch/arm64/mm/fault.c                 |   2 +
 arch/arm64/mm/mmu.c                   |  28 ++----
 arch/arm64/mm/pageattr.c              |  21 ++++
 arch/arm64/mm/pgd.c                   |  30 +++++-
 include/asm-generic/kpkeys.h          |  21 ++++
 include/linux/kpkeys.h                | 132 ++++++++++++++++++++++++++
 include/linux/mm.h                    |  22 ++++-
 include/linux/set_memory.h            |   7 ++
 mm/Kconfig                            |   5 +
 mm/Makefile                           |   2 +
 mm/kpkeys_hardened_pgtables.c         |  17 ++++
 mm/kpkeys_hardened_pgtables_test.c    |  71 ++++++++++++++
 mm/memory.c                           | 130 +++++++++++++++++++++++++
 security/Kconfig.hardening            |  24 +++++
 24 files changed, 604 insertions(+), 37 deletions(-)
 create mode 100644 arch/arm64/include/asm/kpkeys.h
 create mode 100644 include/asm-generic/kpkeys.h
 create mode 100644 include/linux/kpkeys.h
 create mode 100644 mm/kpkeys_hardened_pgtables.c
 create mode 100644 mm/kpkeys_hardened_pgtables_test.c

-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:10:55 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:10:55 +0000
Subject: [RFC PATCH 01/16] mm: Introduce kpkeys
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-2-kevin.brodsky@arm.com>

kpkeys is a simple framework to enable the use of protection keys
(pkeys) to harden the kernel itself. This patch introduces the basic
API in <linux/kpkeys.h>: a couple of functions to set and restore
the pkey register and a macro to define guard objects.

kpkeys introduces a new concept on top of pkeys: the kpkeys level.
Each level is associated to a set of permissions for the pkeys
managed by the kpkeys framework. kpkeys_set_level(lvl) sets those
permissions according to lvl, and returns the original pkey
register, to be later restored by kpkeys_restore_pkey_reg(). To
start with, only KPKEYS_LVL_DEFAULT is available, which is meant
to grant RW access to KPKEYS_PKEY_DEFAULT (i.e. all memory since
this is the only available pkey for now).

Because each architecture implementing pkeys uses a different
representation for the pkey register, and may reserve certain pkeys
for specific uses, support for kpkeys must be explicitly indicated
by selecting ARCH_HAS_KPKEYS and defining the following functions in
<asm/kpkeys.h>, in addition to the macros provided in
<asm-generic/kpkeys.h>:

- arch_kpkeys_set_level()
- arch_kpkeys_restore_pkey_reg()
- arch_kpkeys_enabled()

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 include/asm-generic/kpkeys.h |  9 +++++
 include/linux/kpkeys.h       | 67 ++++++++++++++++++++++++++++++++++++
 mm/Kconfig                   |  2 ++
 3 files changed, 78 insertions(+)
 create mode 100644 include/asm-generic/kpkeys.h
 create mode 100644 include/linux/kpkeys.h

diff --git a/include/asm-generic/kpkeys.h b/include/asm-generic/kpkeys.h
new file mode 100644
index 000000000000..3404ce249757
--- /dev/null
+++ b/include/asm-generic/kpkeys.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_GENERIC_KPKEYS_H
+#define __ASM_GENERIC_KPKEYS_H
+
+#ifndef KPKEYS_PKEY_DEFAULT
+#define KPKEYS_PKEY_DEFAULT	0
+#endif
+
+#endif	/* __ASM_GENERIC_KPKEYS_H */
diff --git a/include/linux/kpkeys.h b/include/linux/kpkeys.h
new file mode 100644
index 000000000000..bcc063425926
--- /dev/null
+++ b/include/linux/kpkeys.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _LINUX_KPKEYS_H
+#define _LINUX_KPKEYS_H
+
+#include <linux/bug.h>
+#include <linux/cleanup.h>
+#include <linux/set_memory.h>
+
+#define KPKEYS_LVL_DEFAULT	0
+
+#define KPKEYS_LVL_MIN		KPKEYS_LVL_DEFAULT
+#define KPKEYS_LVL_MAX		KPKEYS_LVL_DEFAULT
+
+#define KPKEYS_GUARD(_name, set_level, restore_pkey_reg)		\
+	__DEFINE_CLASS_IS_CONDITIONAL(_name, false);			\
+	DEFINE_CLASS(_name, u64,					\
+		     restore_pkey_reg, set_level, void);		\
+	static inline void *class_##_name##_lock_ptr(u64 *_T)		\
+	{ return _T; }
+
+#ifdef CONFIG_ARCH_HAS_KPKEYS
+
+#include <asm/kpkeys.h>
+
+/**
+ * kpkeys_set_level() - switch kpkeys level
+ * @level: the level to switch to
+ *
+ * Switches the kpkeys level to the specified value. @level must be a
+ * compile-time constant. The arch-specific pkey register will be updated
+ * accordingly, and the original value returned.
+ *
+ * Return: the original pkey register value.
+ */
+static inline u64 kpkeys_set_level(int level)
+{
+	BUILD_BUG_ON_MSG(!__builtin_constant_p(level),
+			 "kpkeys_set_level() only takes constant levels");
+	BUILD_BUG_ON_MSG(level < KPKEYS_LVL_MIN || level > KPKEYS_LVL_MAX,
+			 "Invalid level passed to kpkeys_set_level()");
+
+	return arch_kpkeys_set_level(level);
+}
+
+/**
+ * kpkeys_restore_pkey_reg() - restores a pkey register value
+ * @pkey_reg: the pkey register value to restore
+ *
+ * This function is meant to be passed the value returned by kpkeys_set_level(),
+ * in order to restore the pkey register to its original value (thus restoring
+ * the original kpkeys level).
+ */
+static inline void kpkeys_restore_pkey_reg(u64 pkey_reg)
+{
+	arch_kpkeys_restore_pkey_reg(pkey_reg);
+}
+
+#else /* CONFIG_ARCH_HAS_KPKEYS */
+
+static inline bool arch_kpkeys_enabled(void)
+{
+	return false;
+}
+
+#endif /* CONFIG_ARCH_HAS_KPKEYS */
+
+#endif /* _LINUX_KPKEYS_H */
diff --git a/mm/Kconfig b/mm/Kconfig
index 84000b016808..f51dffca9d4e 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1104,6 +1104,8 @@ config ARCH_USES_HIGH_VMA_FLAGS
 	bool
 config ARCH_HAS_PKEYS
 	bool
+config ARCH_HAS_KPKEYS
+	bool
 
 config ARCH_USES_PG_ARCH_2
 	bool
-- 
2.47.0



From heiko at sntech.de  Fri Dec  6 02:33:59 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri,  6 Dec 2024 11:33:59 +0100
Subject: [PATCH 0/2] phy: phy-rockchip-samsung-hdptx: don't use of-alias
Message-ID: <20241206103401.1780416-1-heiko@sntech.de>

One nice comment addition and removal of of_alias usage for core
device functionality.

Heiko Stuebner (2):
  phy: phy-rockchip-samsung-hdptx: annotate regmap register-callback
  phy: phy-rockchip-samsung-hdptx: Don't use dt aliases to determine
    phy-id

 .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 64 +++++++++++++++----
 1 file changed, 51 insertions(+), 13 deletions(-)

-- 
2.45.2



From heiko at sntech.de  Fri Dec  6 02:34:00 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri,  6 Dec 2024 11:34:00 +0100
Subject: [PATCH 1/2] phy: phy-rockchip-samsung-hdptx: annotate regmap register-callback
In-Reply-To: <20241206103401.1780416-1-heiko@sntech.de>
References: <20241206103401.1780416-1-heiko@sntech.de>
Message-ID: <20241206103401.1780416-2-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

The variant of the driver in the vendor-tree contained those handy
comments in the regmap register callback. Having the different ranges
describe what they are looks helpful.

Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 4ced1479e2dc..c5c64c209e96 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -766,13 +766,13 @@ static struct tx_drv_ctrl tx_drv_ctrl_hbr2[4][4] = {
 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:
+	case 0x0000 ... 0x029c: /* CMN Register */
+	case 0x0400 ... 0x04a4: /* Sideband Register */
+	case 0x0800 ... 0x08a4: /* Lane Top Register */
+	case 0x0c00 ... 0x0cb4: /* Lane 0 Register */
+	case 0x1000 ... 0x10b4: /* Lane 1 Register */
+	case 0x1400 ... 0x14b4: /* Lane 2 Register */
+	case 0x1800 ... 0x18b4: /* Lane 3 Register */
 		return true;
 	}
 
-- 
2.45.2



From kevin.brodsky at arm.com  Fri Dec  6 02:10:56 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:10:56 +0000
Subject: [RFC PATCH 02/16] set_memory: Introduce set_memory_pkey() stub
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-3-kevin.brodsky@arm.com>

Introduce a new function, set_memory_pkey(), which sets the
protection key (pkey) of pages in the specified linear mapping
range. Architectures implementing kernel pkeys (kpkeys) must
provide a suitable implementation; an empty stub is added as
fallback.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 include/linux/set_memory.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
index 3030d9245f5a..7b3a8bfde3c6 100644
--- a/include/linux/set_memory.h
+++ b/include/linux/set_memory.h
@@ -84,4 +84,11 @@ static inline int set_memory_decrypted(unsigned long addr, int numpages)
 }
 #endif /* CONFIG_ARCH_HAS_MEM_ENCRYPT */
 
+#ifndef CONFIG_ARCH_HAS_KPKEYS
+static inline int set_memory_pkey(unsigned long addr, int numpages, int pkey)
+{
+	return 0;
+}
+#endif
+
 #endif /* _LINUX_SET_MEMORY_H_ */
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:10:57 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:10:57 +0000
Subject: [RFC PATCH 03/16] arm64: mm: Enable overlays for all EL1 indirect permissions
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-4-kevin.brodsky@arm.com>

In preparation of using POE inside the kernel, enable "Overlay
applied" for all stage 1 base permissions in PIR_EL1. This ensures
that the permissions set in POR_EL1 affect all kernel mappings.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/include/asm/pgtable-prot.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 9f9cf13bbd95..a1c4f3837ea9 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -174,13 +174,13 @@ static inline bool __pure lpa2_is_enabled(void)
 	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)     | \
-	PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY),      PIE_R)      | \
-	PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED),        PIE_RW)     | \
-	PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_ROX),    PIE_RX)     | \
-	PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_EXEC),   PIE_RWX)    | \
-	PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_RO),     PIE_R)      | \
-	PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL),        PIE_RW))
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_R_O)    | \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC),   PIE_RW_O)   | \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY),      PIE_R_O)    | \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED),        PIE_RW_O)   | \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_ROX),    PIE_RX_O)   | \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_EXEC),   PIE_RWX_O)  | \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL_RO),     PIE_R_O)    | \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_KERNEL),        PIE_RW_O))
 
 #endif /* __ASM_PGTABLE_PROT_H */
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:10:58 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:10:58 +0000
Subject: [RFC PATCH 04/16] arm64: Introduce por_set_pkey_perms() helper
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-5-kevin.brodsky@arm.com>

Introduce a helper that sets the permissions of a given pkey
(POIndex) in the POR_ELx format, and make use of it in
arch_set_user_pkey_access().

Also ensure that <asm/sysreg.h> is included in asm/por.h to provide
the POE_* definitions.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/include/asm/por.h |  9 +++++++++
 arch/arm64/mm/mmu.c          | 28 ++++++++++------------------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/por.h b/arch/arm64/include/asm/por.h
index e06e9f473675..7f0d73980cce 100644
--- a/arch/arm64/include/asm/por.h
+++ b/arch/arm64/include/asm/por.h
@@ -6,6 +6,8 @@
 #ifndef _ASM_ARM64_POR_H
 #define _ASM_ARM64_POR_H
 
+#include <asm/sysreg.h>
+
 #define POR_BITS_PER_PKEY		4
 #define POR_ELx_IDX(por_elx, idx)	(((por_elx) >> ((idx) * POR_BITS_PER_PKEY)) & 0xf)
 
@@ -30,4 +32,11 @@ static inline bool por_elx_allows_exec(u64 por, u8 pkey)
 	return perm & POE_X;
 }
 
+static inline u64 por_set_pkey_perms(u64 por, u8 pkey, u64 perms)
+{
+	u64 shift = pkey * POR_BITS_PER_PKEY;
+
+	return (por & ~(POE_MASK << shift)) | (perms << shift);
+}
+
 #endif /* _ASM_ARM64_POR_H */
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index e2739b69e11b..20e0390ee382 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1554,9 +1554,8 @@ void __cpu_replace_ttbr1(pgd_t *pgdp, bool cnp)
 #ifdef CONFIG_ARCH_HAS_PKEYS
 int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, unsigned long init_val)
 {
-	u64 new_por = POE_RXW;
-	u64 old_por;
-	u64 pkey_shift;
+	u64 new_perms;
+	u64 por;
 
 	if (!system_supports_poe())
 		return -ENOSPC;
@@ -1570,26 +1569,19 @@ int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, unsigned long i
 		return -EINVAL;
 
 	/* Set the bits we need in POR:  */
-	new_por = POE_RXW;
+	new_perms = POE_RXW;
 	if (init_val & PKEY_DISABLE_WRITE)
-		new_por &= ~POE_W;
+		new_perms &= ~POE_W;
 	if (init_val & PKEY_DISABLE_ACCESS)
-		new_por &= ~POE_RW;
+		new_perms &= ~POE_RW;
 	if (init_val & PKEY_DISABLE_READ)
-		new_por &= ~POE_R;
+		new_perms &= ~POE_R;
 	if (init_val & PKEY_DISABLE_EXECUTE)
-		new_por &= ~POE_X;
+		new_perms &= ~POE_X;
 
-	/* Shift the bits in to the correct place in POR for pkey: */
-	pkey_shift = pkey * POR_BITS_PER_PKEY;
-	new_por <<= pkey_shift;
-
-	/* Get old POR and mask off any old bits in place: */
-	old_por = read_sysreg_s(SYS_POR_EL0);
-	old_por &= ~(POE_MASK << pkey_shift);
-
-	/* Write old part along with new part: */
-	write_sysreg_s(old_por | new_por, SYS_POR_EL0);
+	por = read_sysreg_s(SYS_POR_EL0);
+	por = por_set_pkey_perms(por, pkey, new_perms);
+	write_sysreg_s(por, SYS_POR_EL0);
 
 	return 0;
 }
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:10:59 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:10:59 +0000
Subject: [RFC PATCH 05/16] arm64: Implement asm/kpkeys.h using POE
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-6-kevin.brodsky@arm.com>

Implement the kpkeys interface if CONFIG_ARM64_POE is enabled.
The permissions for KPKEYS_PKEY_DEFAULT (pkey 0) are set to RWX as
this pkey is also used for code mappings.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/include/asm/kpkeys.h | 43 +++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 arch/arm64/include/asm/kpkeys.h

diff --git a/arch/arm64/include/asm/kpkeys.h b/arch/arm64/include/asm/kpkeys.h
new file mode 100644
index 000000000000..e17f6df41873
--- /dev/null
+++ b/arch/arm64/include/asm/kpkeys.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_KPKEYS_H
+#define __ASM_KPKEYS_H
+
+#include <asm/barrier.h>
+#include <asm/cpufeature.h>
+#include <asm/por.h>
+
+#include <asm-generic/kpkeys.h>
+
+static inline bool arch_kpkeys_enabled(void)
+{
+	return system_supports_poe();
+}
+
+#ifdef CONFIG_ARM64_POE
+
+static inline u64 por_set_kpkeys_level(u64 por, int level)
+{
+	por = por_set_pkey_perms(por, KPKEYS_PKEY_DEFAULT, POE_RXW);
+
+	return por;
+}
+
+static inline int arch_kpkeys_set_level(int level)
+{
+	u64 prev_por = read_sysreg_s(SYS_POR_EL1);
+
+	write_sysreg_s(por_set_kpkeys_level(prev_por, level), SYS_POR_EL1);
+	isb();
+
+	return prev_por;
+}
+
+static inline void arch_kpkeys_restore_pkey_reg(u64 pkey_reg)
+{
+	write_sysreg_s(pkey_reg, SYS_POR_EL1);
+	isb();
+}
+
+#endif /* CONFIG_ARM64_POE */
+
+#endif	/* __ASM_KPKEYS_H */
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:00 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:00 +0000
Subject: [RFC PATCH 06/16] arm64: set_memory: Implement set_memory_pkey()
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-7-kevin.brodsky@arm.com>

Implement set_memory_pkey() using POE if supported.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/include/asm/set_memory.h |  4 ++++
 arch/arm64/mm/pageattr.c            | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/arch/arm64/include/asm/set_memory.h b/arch/arm64/include/asm/set_memory.h
index 90f61b17275e..b6cd6de34abf 100644
--- a/arch/arm64/include/asm/set_memory.h
+++ b/arch/arm64/include/asm/set_memory.h
@@ -19,4 +19,8 @@ bool kernel_page_present(struct page *page);
 int set_memory_encrypted(unsigned long addr, int numpages);
 int set_memory_decrypted(unsigned long addr, int numpages);
 
+#ifdef CONFIG_ARCH_HAS_KPKEYS
+int set_memory_pkey(unsigned long addr, int numpages, int pkey);
+#endif
+
 #endif /* _ASM_ARM64_SET_MEMORY_H */
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 39fd1f7ff02a..3b8fec532b18 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -292,6 +292,27 @@ int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid)
 	return set_memory_valid(addr, nr, valid);
 }
 
+#ifdef CONFIG_ARCH_HAS_KPKEYS
+int set_memory_pkey(unsigned long addr, int numpages, int pkey)
+{
+	unsigned long set_prot = 0;
+
+	if (!system_supports_poe())
+		return 0;
+
+	if (!__is_lm_address(addr))
+		return -EINVAL;
+
+	set_prot |= pkey & BIT(0) ? PTE_PO_IDX_0 : 0;
+	set_prot |= pkey & BIT(1) ? PTE_PO_IDX_1 : 0;
+	set_prot |= pkey & BIT(2) ? PTE_PO_IDX_2 : 0;
+
+	return __change_memory_common(addr, PAGE_SIZE * numpages,
+				      __pgprot(set_prot),
+				      __pgprot(PTE_PO_IDX_MASK));
+}
+#endif
+
 #ifdef CONFIG_DEBUG_PAGEALLOC
 /*
  * This is - apart from the return value - doing the same
-- 
2.47.0



From kevin.brodsky at arm.com  Fri Dec  6 02:11:01 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri,  6 Dec 2024 10:11:01 +0000
Subject: [RFC PATCH 07/16] arm64: Enable kpkeys
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <20241206101110.1646108-8-kevin.brodsky@arm.com>

This is the final step to enable kpkeys on arm64. We enable
POE at EL1 by setting TCR2_EL1.POE, and initialise POR_EL1 so that
it enables access to the default pkey/POIndex (default kpkeys
level). An ISB is added so that POE restrictions are enforced
immediately.

Having done this, we can now select ARCH_HAS_KPKEYS if ARM64_POE is
enabled.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/Kconfig             | 1 +
 arch/arm64/kernel/cpufeature.c | 5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..f35964641c1a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2183,6 +2183,7 @@ config ARM64_POE
 	def_bool y
 	select ARCH_USES_HIGH_VMA_FLAGS
 	select ARCH_HAS_PKEYS
+	select ARCH_HAS_KPKEYS
 	help
 	  The Permission Overlay Extension is used to implement Memory
 	  Protection Keys. Memory Protection Keys provides a mechanism for
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed8..3925bf04fb2f 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -75,6 +75,7 @@
 #include <linux/cpu.h>
 #include <linux/kasan.h>
 #include <linux/percpu.h>
+#include <linux/kpkeys.h>
 
 #include <asm/cpu.h>
 #include <asm/cpufeature.h>
@@ -2376,8 +2377,10 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused)
 #ifdef CONFIG_ARM64_POE
 static void cpu_enable_poe(const struct arm64_cpu_capabilities *__unused)
 {
-	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1x_E0POE);
+	write_sysreg_s(por_set_kpkeys_level(0, KPKEYS_LVL_DEFAULT), SYS_POR_EL1);
+	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1x_E0POE | TCR2_EL1x_POE);
 	sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_E0POE);
+	isb();
 }
 #endif
 
-- 
2.47.0



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:16:01 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:16:01 +0200
Subject: [PATCH v6 07/10] drm/bridge_connector: hook
 drm_atomic_helper_connector_hdmi_hotplug_edid()
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-7-50dc145a9c06@linaro.org>

Extend drm_bridge_connector code to read the EDID and use it to update
connector status if the bridge chain implements HDMI bridge. Performing
it from the generic location minimizes individual bridge's code and
enforces standard behaviour from all corresponding drivers.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 27 ++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 4fa1bb73d430d02d5b79a1a184c203ec9e9c66e7..0ff82900bd07933e292948446b9637ebf2076694 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -17,6 +17,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_hdmi_state_helper.h>
@@ -182,11 +183,29 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
 	struct drm_bridge_connector *bridge_connector =
 		to_drm_bridge_connector(connector);
 	struct drm_bridge *detect = bridge_connector->bridge_detect;
+	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
 	enum drm_connector_status status;
 
 	if (detect) {
 		status = detect->funcs->detect(detect);
 
+		if (hdmi) {
+			const struct drm_edid *drm_edid;
+			struct drm_bridge *bridge;
+			int ret;
+
+			bridge = bridge_connector->bridge_edid;
+			if (!bridge)
+				return status;
+
+			drm_edid = drm_bridge_edid_read(bridge, connector);
+			ret = drm_atomic_helper_connector_hdmi_hotplug_edid(connector, status, drm_edid);
+			if (ret)
+				drm_warn(connector->dev, "updating EDID failed with %d\n", ret);
+
+			drm_edid_free(drm_edid);
+		}
+
 		drm_bridge_connector_hpd_notify(connector, status);
 	} else {
 		switch (connector->connector_type) {
@@ -278,6 +297,14 @@ static int drm_bridge_connector_get_modes(struct drm_connector *connector)
 		to_drm_bridge_connector(connector);
 	struct drm_bridge *bridge;
 
+	/*
+	 * If there is a HDMI bridge, EDID has been updated as a part of
+	 * the .detect(). Just update the modes here.
+	 */
+	bridge = bridge_connector->bridge_hdmi;
+	if (bridge)
+		return drm_edid_connector_add_modes(connector);
+
 	/*
 	 * If display exposes EDID, then we parse that in the normal way to
 	 * build table of supported modes.

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:15:59 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:15:59 +0200
Subject: [PATCH v6 05/10] drm/bridge: lt9611: switch to using the DRM HDMI
 codec framework
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-5-50dc145a9c06@linaro.org>

Make the Lontium LT9611 DSI-to-HDMI bridge driver use the DRM HDMI Codec
framework. This enables programming of Audio InfoFrames using the HDMI
Connector interface and also enables support for the missing features,
including the ELD retrieval and better hotplug support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 170 +++++++++++++-------------------
 1 file changed, 68 insertions(+), 102 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 60b7305c0fd1935e35742713c78937392b7faa79..63aa751c412fb90d6edb4b5331138e94f19de37d 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -45,7 +45,6 @@ struct lt9611 {
 	struct device_node *dsi1_node;
 	struct mipi_dsi_device *dsi0;
 	struct mipi_dsi_device *dsi1;
-	struct platform_device *audio_pdev;
 
 	bool ac_mode;
 
@@ -864,6 +863,10 @@ static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge,
 	unsigned int mask;
 
 	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mask = LT9611_INFOFRAME_AUDIO;
+		break;
+
 	case HDMI_INFOFRAME_TYPE_AVI:
 		mask = LT9611_INFOFRAME_AVI;
 		break;
@@ -897,6 +900,11 @@ static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge,
 	int i;
 
 	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mask = LT9611_INFOFRAME_AUDIO;
+		addr = 0x84b2;
+		break;
+
 	case HDMI_INFOFRAME_TYPE_AVI:
 		mask = LT9611_INFOFRAME_AVI;
 		addr = 0x8440;
@@ -940,6 +948,55 @@ lt9611_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
 	return MODE_OK;
 }
 
+static int lt9611_hdmi_codec_audio_startup(struct drm_connector *connector,
+					   struct drm_bridge *bridge)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	regmap_write(lt9611->regmap, 0x82d6, 0x8c);
+	regmap_write(lt9611->regmap, 0x82d7, 0x04);
+
+	regmap_write(lt9611->regmap, 0x8406, 0x08);
+	regmap_write(lt9611->regmap, 0x8407, 0x10);
+
+	regmap_write(lt9611->regmap, 0x8434, 0xd5);
+
+	return 0;
+}
+
+static int lt9611_hdmi_codec_prepare(struct drm_connector *connector,
+				     struct drm_bridge *bridge,
+				     struct hdmi_codec_daifmt *fmt,
+				     struct hdmi_codec_params *hparms)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	if (hparms->sample_rate == 48000)
+		regmap_write(lt9611->regmap, 0x840f, 0x2b);
+	else if (hparms->sample_rate == 96000)
+		regmap_write(lt9611->regmap, 0x840f, 0xab);
+	else
+		return -EINVAL;
+
+	regmap_write(lt9611->regmap, 0x8435, 0x00);
+	regmap_write(lt9611->regmap, 0x8436, 0x18);
+	regmap_write(lt9611->regmap, 0x8437, 0x00);
+
+	return drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
+								       &hparms->cea);
+}
+
+static void lt9611_hdmi_codec_audio_shutdown(struct drm_connector *connector,
+					     struct drm_bridge *bridge)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector);
+
+	regmap_write(lt9611->regmap, 0x8406, 0x00);
+	regmap_write(lt9611->regmap, 0x8407, 0x00);
+}
+
 static const struct drm_bridge_funcs lt9611_bridge_funcs = {
 	.attach = lt9611_bridge_attach,
 	.mode_valid = lt9611_bridge_mode_valid,
@@ -960,6 +1017,10 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = {
 	.hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid,
 	.hdmi_write_infoframe = lt9611_hdmi_write_infoframe,
 	.hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe,
+
+	.hdmi_codec_audio_startup = lt9611_hdmi_codec_audio_startup,
+	.hdmi_codec_prepare = lt9611_hdmi_codec_prepare,
+	.hdmi_codec_audio_shutdown = lt9611_hdmi_codec_audio_shutdown,
 };
 
 static int lt9611_parse_dt(struct device *dev,
@@ -1013,102 +1074,6 @@ static int lt9611_read_device_rev(struct lt9611 *lt9611)
 	return ret;
 }
 
-static int lt9611_hdmi_hw_params(struct device *dev, void *data,
-				 struct hdmi_codec_daifmt *fmt,
-				 struct hdmi_codec_params *hparms)
-{
-	struct lt9611 *lt9611 = data;
-
-	if (hparms->sample_rate == 48000)
-		regmap_write(lt9611->regmap, 0x840f, 0x2b);
-	else if (hparms->sample_rate == 96000)
-		regmap_write(lt9611->regmap, 0x840f, 0xab);
-	else
-		return -EINVAL;
-
-	regmap_write(lt9611->regmap, 0x8435, 0x00);
-	regmap_write(lt9611->regmap, 0x8436, 0x18);
-	regmap_write(lt9611->regmap, 0x8437, 0x00);
-
-	return 0;
-}
-
-static int lt9611_audio_startup(struct device *dev, void *data)
-{
-	struct lt9611 *lt9611 = data;
-
-	regmap_write(lt9611->regmap, 0x82d6, 0x8c);
-	regmap_write(lt9611->regmap, 0x82d7, 0x04);
-
-	regmap_write(lt9611->regmap, 0x8406, 0x08);
-	regmap_write(lt9611->regmap, 0x8407, 0x10);
-
-	regmap_write(lt9611->regmap, 0x8434, 0xd5);
-
-	return 0;
-}
-
-static void lt9611_audio_shutdown(struct device *dev, void *data)
-{
-	struct lt9611 *lt9611 = data;
-
-	regmap_write(lt9611->regmap, 0x8406, 0x00);
-	regmap_write(lt9611->regmap, 0x8407, 0x00);
-}
-
-static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				      struct device_node *endpoint,
-				      void *data)
-{
-	struct of_endpoint of_ep;
-	int ret;
-
-	ret = of_graph_parse_endpoint(endpoint, &of_ep);
-	if (ret < 0)
-		return ret;
-
-	/*
-	 * HDMI sound should be located as reg = <2>
-	 * Then, it is sound port 0
-	 */
-	if (of_ep.port == 2)
-		return 0;
-
-	return -EINVAL;
-}
-
-static const struct hdmi_codec_ops lt9611_codec_ops = {
-	.hw_params	= lt9611_hdmi_hw_params,
-	.audio_shutdown = lt9611_audio_shutdown,
-	.audio_startup	= lt9611_audio_startup,
-	.get_dai_id	= lt9611_hdmi_i2s_get_dai_id,
-};
-
-static struct hdmi_codec_pdata codec_data = {
-	.ops = &lt9611_codec_ops,
-	.max_i2s_channels = 8,
-	.i2s = 1,
-};
-
-static int lt9611_audio_init(struct device *dev, struct lt9611 *lt9611)
-{
-	codec_data.data = lt9611;
-	lt9611->audio_pdev =
-		platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-					      PLATFORM_DEVID_AUTO,
-					      &codec_data, sizeof(codec_data));
-
-	return PTR_ERR_OR_ZERO(lt9611->audio_pdev);
-}
-
-static void lt9611_audio_exit(struct lt9611 *lt9611)
-{
-	if (lt9611->audio_pdev) {
-		platform_device_unregister(lt9611->audio_pdev);
-		lt9611->audio_pdev = NULL;
-	}
-}
-
 static int lt9611_probe(struct i2c_client *client)
 {
 	struct lt9611 *lt9611;
@@ -1172,6 +1137,9 @@ static int lt9611_probe(struct i2c_client *client)
 
 	i2c_set_clientdata(client, lt9611);
 
+	/* Disable Audio InfoFrame, enabled by default */
+	regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, 0);
+
 	lt9611->bridge.funcs = &lt9611_bridge_funcs;
 	lt9611->bridge.of_node = client->dev.of_node;
 	lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
@@ -1180,6 +1148,9 @@ static int lt9611_probe(struct i2c_client *client)
 	lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	lt9611->bridge.vendor = "Lontium";
 	lt9611->bridge.product = "LT9611";
+	lt9611->bridge.hdmi_codec_dev = dev;
+	lt9611->bridge.hdmi_codec_max_i2s_playback_channels = 8;
+	lt9611->bridge.hdmi_codec_dai_port = 2;
 
 	drm_bridge_add(&lt9611->bridge);
 
@@ -1201,10 +1172,6 @@ static int lt9611_probe(struct i2c_client *client)
 
 	lt9611_enable_hpd_interrupts(lt9611);
 
-	ret = lt9611_audio_init(dev, lt9611);
-	if (ret)
-		goto err_remove_bridge;
-
 	return 0;
 
 err_remove_bridge:
@@ -1225,7 +1192,6 @@ static void lt9611_remove(struct i2c_client *client)
 	struct lt9611 *lt9611 = i2c_get_clientdata(client);
 
 	disable_irq(client->irq);
-	lt9611_audio_exit(lt9611);
 	drm_bridge_remove(&lt9611->bridge);
 
 	regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:16:02 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:16:02 +0200
Subject: [PATCH v6 08/10] drm/vc4: hdmi: switch to using generic HDMI Codec
 infrastructure
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-8-50dc145a9c06@linaro.org>

Drop driver-specific implementation and use the generic HDMI Codec
framework in order to implement the HDMI audio support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 69 ++++++++++--------------------------------
 drivers/gpu/drm/vc4/vc4_hdmi.h |  2 --
 2 files changed, 16 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index f98617b8bf6cf9d92a806e35584e8f8ab0ac9f96..e5ab42f72f618b90f956482db6c9c8074c1e3bf1 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -609,6 +609,10 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	ret = drm_connector_hdmi_codec_init(connector, dev->dev, 8, false, -1);
+	if (ret)
+		return ret;
+
 	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
 
 	/*
@@ -1707,9 +1711,12 @@ vc4_hdmi_connector_clock_valid(const struct drm_connector *connector,
 	return MODE_OK;
 }
 
+static const struct drm_connector_hdmi_codec_funcs vc4_hdmi_codec_funcs;
+
 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,
+	.codec_funcs		= &vc4_hdmi_codec_funcs,
 };
 
 #define WIFI_2_4GHz_CH1_MIN_FREQ	2400000000ULL
@@ -1921,9 +1928,9 @@ static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi)
 	return true;
 }
 
-static int vc4_hdmi_audio_startup(struct device *dev, void *data)
+static int vc4_hdmi_audio_startup(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	unsigned long flags;
 	int ret = 0;
@@ -1985,9 +1992,9 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 	spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 }
 
-static void vc4_hdmi_audio_shutdown(struct device *dev, void *data)
+static void vc4_hdmi_audio_shutdown(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	unsigned long flags;
 	int idx;
@@ -2057,13 +2064,12 @@ static int sample_rate_to_mai_fmt(int samplerate)
 }
 
 /* HDMI audio codec callbacks */
-static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
+static int vc4_hdmi_audio_prepare(struct drm_connector *connector,
 				  struct hdmi_codec_daifmt *daifmt,
 				  struct hdmi_codec_params *params)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	struct drm_connector *connector = &vc4_hdmi->connector;
 	struct vc4_dev *vc4 = to_vc4_dev(drm);
 	unsigned int sample_rate = params->sample_rate;
 	unsigned int channels = params->channels;
@@ -2075,7 +2081,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
 	int ret = 0;
 	int idx;
 
-	dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
+	dev_dbg(&vc4_hdmi->pdev->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
 		sample_rate, params->sample_width, channels);
 
 	mutex_lock(&vc4_hdmi->mutex);
@@ -2214,40 +2220,12 @@ static const struct snd_dmaengine_pcm_config pcm_conf = {
 	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
 };
 
-static int vc4_hdmi_audio_get_eld(struct device *dev, void *data,
-				  uint8_t *buf, size_t len)
-{
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-
-	mutex_lock(&connector->eld_mutex);
-	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
-	mutex_unlock(&connector->eld_mutex);
-
-	return 0;
-}
-
-static const struct hdmi_codec_ops vc4_hdmi_codec_ops = {
-	.get_eld = vc4_hdmi_audio_get_eld,
+static const struct drm_connector_hdmi_codec_funcs vc4_hdmi_codec_funcs = {
 	.prepare = vc4_hdmi_audio_prepare,
 	.audio_shutdown = vc4_hdmi_audio_shutdown,
 	.audio_startup = vc4_hdmi_audio_startup,
 };
 
-static struct hdmi_codec_pdata vc4_hdmi_codec_pdata = {
-	.ops = &vc4_hdmi_codec_ops,
-	.max_i2s_channels = 8,
-	.i2s = 1,
-};
-
-static void vc4_hdmi_audio_codec_release(void *ptr)
-{
-	struct vc4_hdmi *vc4_hdmi = ptr;
-
-	platform_device_unregister(vc4_hdmi->audio.codec_pdev);
-	vc4_hdmi->audio.codec_pdev = NULL;
-}
-
 static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 {
 	const struct vc4_hdmi_register *mai_data =
@@ -2255,7 +2233,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 	struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link;
 	struct snd_soc_card *card = &vc4_hdmi->audio.card;
 	struct device *dev = &vc4_hdmi->pdev->dev;
-	struct platform_device *codec_pdev;
 	const __be32 *addr;
 	int index, len;
 	int ret;
@@ -2348,20 +2325,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 		return ret;
 	}
 
-	codec_pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-						   PLATFORM_DEVID_AUTO,
-						   &vc4_hdmi_codec_pdata,
-						   sizeof(vc4_hdmi_codec_pdata));
-	if (IS_ERR(codec_pdev)) {
-		dev_err(dev, "Couldn't register the HDMI codec: %ld\n", PTR_ERR(codec_pdev));
-		return PTR_ERR(codec_pdev);
-	}
-	vc4_hdmi->audio.codec_pdev = codec_pdev;
-
-	ret = devm_add_action_or_reset(dev, vc4_hdmi_audio_codec_release, vc4_hdmi);
-	if (ret)
-		return ret;
-
 	dai_link->cpus		= &vc4_hdmi->audio.cpu;
 	dai_link->codecs	= &vc4_hdmi->audio.codec;
 	dai_link->platforms	= &vc4_hdmi->audio.platform;
@@ -2374,7 +2337,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 	dai_link->stream_name = "MAI PCM";
 	dai_link->codecs->dai_name = "i2s-hifi";
 	dai_link->cpus->dai_name = dev_name(dev);
-	dai_link->codecs->name = dev_name(&codec_pdev->dev);
+	dai_link->codecs->name = dev_name(&vc4_hdmi->connector.hdmi_codec.codec_pdev->dev);
 	dai_link->platforms->name = dev_name(dev);
 
 	card->dai_link = dai_link;
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index b2424a21da230db99db207efa293417faccd254d..e3d989ca302b72533c374dfa3fd0d5bd7fe64a82 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -104,8 +104,6 @@ struct vc4_hdmi_audio {
 	struct snd_soc_dai_link_component codec;
 	struct snd_soc_dai_link_component platform;
 	struct snd_dmaengine_dai_dma_data dma_data;
-	struct hdmi_audio_infoframe infoframe;
-	struct platform_device *codec_pdev;
 	bool streaming;
 };
 

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec  6 02:16:03 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 06 Dec 2024 12:16:03 +0200
Subject: [PATCH v6 09/10] drm/vc4: hdmi: stop rereading EDID in get_modes()
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
Message-ID: <20241206-drm-bridge-hdmi-connector-v6-9-50dc145a9c06@linaro.org>

The vc4_hdmi_connector_detect_ctx() via vc4_hdmi_handle_hotplug()
already reads EDID and propagates it to the drm_connector. Stop
rereading EDID as a part of the .get_modes() callback and just update
the list of modes. This matches the behaviour of the i915 driver.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index e5ab42f72f618b90f956482db6c9c8074c1e3bf1..3364ef90968dad3074800f02926300ffceb75c69 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -470,31 +470,10 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
 
 static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
-	const struct drm_edid *drm_edid;
 	int ret = 0;
 
-	/*
-	 * NOTE: This function should really take vc4_hdmi->mutex, but doing so
-	 * results in reentrancy issues since cec_s_phys_addr() might call
-	 * .adap_enable, which leads to that funtion being called with our mutex
-	 * held.
-	 *
-	 * Concurrency isn't an issue at the moment since we don't share
-	 * any state with any of the other frameworks so we can ignore
-	 * the lock for now.
-	 */
-
-	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
-	drm_edid_connector_update(connector, drm_edid);
-	cec_s_phys_addr(vc4_hdmi->cec_adap,
-			connector->display_info.source_physical_address, false);
-	if (!drm_edid)
-		return 0;
-
 	ret = drm_edid_connector_add_modes(connector);
-	drm_edid_free(drm_edid);
 
 	if (!vc4->hvs->vc5_hdmi_enable_hdmi_20) {
 		struct drm_device *drm = connector->dev;

-- 
2.39.5



From David.Laight at ACULAB.COM  Fri Dec  6 02:27:23 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 10:27:23 +0000
Subject: [PATCH net] Fix clamp() of ip_vs_conn_tab on small memory systems.
Message-ID: <33893212b1cc4a418cec09aeeed0a9fc@AcuMS.aculab.com>

The intention of the code seems to be that the minimum table
size should be 256 (1 << min).
However the code uses max = clamp(20, 5, max_avail) which implies
the author thought max_avail could be less than 5.
But clamp(val, min, max) is only well defined for max >= min.
If max < min whether is returns min or max depends on the order of
the comparisons.

Change to clamp(max_avail, 5, 20) which has the expected behaviour.

Replace the clamp_val() on the line below with clamp().
clamp_val() is just 'an accident waiting to happen' and not needed here.

Fixes: 4f325e26277b6
(Although I actually doubt the code is used on small memory systems.)

Detected by compile time checks added to clamp(), specifically:
minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()

Signed-off-by: David Laight <david.laight at aculab.com>
---
 net/netfilter/ipvs/ip_vs_conn.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 98d7dbe3d787..c0289f83f96d 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -1495,8 +1495,8 @@ int __init ip_vs_conn_init(void)
 	max_avail -= 2;		/* ~4 in hash row */
 	max_avail -= 1;		/* IPVS up to 1/2 of mem */
 	max_avail -= order_base_2(sizeof(struct ip_vs_conn));
-	max = clamp(max, min, max_avail);
-	ip_vs_conn_tab_bits = clamp_val(ip_vs_conn_tab_bits, min, max);
+	max = clamp(max_avail, min, max);
+	ip_vs_conn_tab_bits = clamp(ip_vs_conn_tab_bits, min, max);
 	ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
 	ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
 
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From heiko at sntech.de  Fri Dec  6 02:34:01 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri,  6 Dec 2024 11:34:01 +0100
Subject: [PATCH 2/2] phy: phy-rockchip-samsung-hdptx: Don't use dt aliases to determine phy-id
In-Reply-To: <20241206103401.1780416-1-heiko@sntech.de>
References: <20241206103401.1780416-1-heiko@sntech.de>
Message-ID: <20241206103401.1780416-3-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

The phy needs to know its identity in the system (phy0 or phy1 on rk3588)
for some actions and the driver currently contains code abusing of_alias
for that.

Devicetree aliases are always optional and should not be used for core
device functionality, so instead keep a list of phys on a soc in the
of_device_data and find the phy-id by comparing against the mapped
register-base.

Fixes: c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock provider support")
Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 50 ++++++++++++++++---
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index c5c64c209e96..b137f8c4d157 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -385,11 +385,22 @@ enum rk_hdptx_reset {
 	RST_MAX
 };
 
+#define MAX_HDPTX_PHY_NUM	2
+
+struct rk_hdptx_phy_cfg {
+	unsigned int num_phys;
+	unsigned int phy_ids[MAX_HDPTX_PHY_NUM];
+};
+
 struct rk_hdptx_phy {
 	struct device *dev;
 	struct regmap *regmap;
 	struct regmap *grf;
 
+	/* PHY const config */
+	const struct rk_hdptx_phy_cfg *cfgs;
+	int phy_id;
+
 	struct phy *phy;
 	struct phy_config *phy_cfg;
 	struct clk_bulk_data *clks;
@@ -1857,15 +1868,14 @@ static int rk_hdptx_phy_clk_register(struct rk_hdptx_phy *hdptx)
 	struct device *dev = hdptx->dev;
 	const char *name, *pname;
 	struct clk *refclk;
-	int ret, id;
+	int ret;
 
 	refclk = devm_clk_get(dev, "ref");
 	if (IS_ERR(refclk))
 		return dev_err_probe(dev, PTR_ERR(refclk),
 				     "Failed to get ref clock\n");
 
-	id = of_alias_get_id(dev->of_node, "hdptxphy");
-	name = id > 0 ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0";
+	name = hdptx->phy_id > 0 ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0";
 	pname = __clk_get_name(refclk);
 
 	hdptx->hw.init = CLK_HW_INIT(name, pname, &hdptx_phy_clk_ops,
@@ -1908,8 +1918,9 @@ 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;
+	struct resource *res;
 	void __iomem *regs;
-	int ret;
+	int ret, id;
 
 	hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL);
 	if (!hdptx)
@@ -1917,11 +1928,27 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
 
 	hdptx->dev = dev;
 
-	regs = devm_platform_ioremap_resource(pdev, 0);
+	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(regs))
 		return dev_err_probe(dev, PTR_ERR(regs),
 				     "Failed to ioremap resource\n");
 
+	hdptx->cfgs = device_get_match_data(dev);
+	if (!hdptx->cfgs)
+		return dev_err_probe(dev, -EINVAL, "missing match data\n");
+
+	/* find the phy-id from the io address */
+	hdptx->phy_id = -ENODEV;
+	for (id = 0; id < hdptx->cfgs->num_phys; id++) {
+		if (res->start == hdptx->cfgs->phy_ids[id]) {
+			hdptx->phy_id = id;
+			break;
+		}
+	}
+
+	if (hdptx->phy_id < 0)
+		return dev_err_probe(dev, -ENODEV, "no matching device found\n");
+
 	ret = devm_clk_bulk_get_all(dev, &hdptx->clks);
 	if (ret < 0)
 		return dev_err_probe(dev, ret, "Failed to get clocks\n");
@@ -1981,8 +2008,19 @@ static const struct dev_pm_ops rk_hdptx_phy_pm_ops = {
 		       rk_hdptx_phy_runtime_resume, NULL)
 };
 
+static const struct rk_hdptx_phy_cfg rk3588_hdptx_phy_cfgs = {
+	.num_phys = 2,
+	.phy_ids = {
+		0xfed60000,
+		0xfed70000,
+	},
+};
+
 static const struct of_device_id rk_hdptx_phy_of_match[] = {
-	{ .compatible = "rockchip,rk3588-hdptx-phy", },
+	{
+		.compatible = "rockchip,rk3588-hdptx-phy",
+		.data = &rk3588_hdptx_phy_cfgs
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, rk_hdptx_phy_of_match);
-- 
2.45.2



From ksloat at cornersoftsolutions.com  Fri Dec  6 02:40:16 2024
From: ksloat at cornersoftsolutions.com (Ken Sloat)
Date: Fri, 6 Dec 2024 05:40:16 -0500
Subject: [PATCH v1] dt-bindings: dma: st-stm32-dmamux: Add description for
 dma-cell values
In-Reply-To: <bdfeceb6-962a-4f20-b76c-4fe5e5ff80c3@foss.st.com>
References: <CADRqkYAaCYvo3ybGdKO1F_y9jFEcwTBxZzRN-Av-adq_4fVu6g@mail.gmail.com>
 <d53538ea-f846-4a6a-bc14-22ec7ee57e53@kernel.org> <CADRqkYDnDNL_H2CzxjsPOdM++iYp-9Ak3PVFBw2qcjR_M=GeBA@mail.gmail.com>
 <28d1bb46-ab18-42da-9ca2-ff498c888d66@kernel.org> <bdfeceb6-962a-4f20-b76c-4fe5e5ff80c3@foss.st.com>
Message-ID: <CADRqkYAg5k3xM81-qBBiiLsvVdJCGdCVyAJgEexMw4s-1PeQkQ@mail.gmail.com>

Hi Amelie,

Thanks for reviewing

On Thu, Dec 5, 2024 at 1:06?PM Amelie Delaunay
<amelie.delaunay at foss.st.com> wrote:
>
>
> On 12/5/24 17:09, Krzysztof Kozlowski wrote:
> > On 05/12/2024 17:07, Ken Sloat wrote:
> >>>> + 1. The mux input number/line for the request
> >>>> + 2. Bitfield representing DMA channel configuration that is passed
> >>>> + to the real DMA controller
> >>>> + 3. Bitfield representing device dependent DMA features passed to
> >>>> + the real DMA controller
> >>>> +
> >>>> + For bitfield definitions of cells 2 and 3, see the associated
> >>>> + bindings doc for the actual DMA controller the mux is connected
> >>>
> >>> This does not sound right. This is the binding for DMA controller, so
> >>> you are saying "please look at itself". I suggest to drop this as well.
> >>>
> >>
> >> While logically it is the DMA controller, this doc is specifically for
> >> the mux - the DMA controller has its own driver and binding docs in
> >> Documentation/devicetree/bindings/dma/stm32/st,stm32-dma.yaml
> >>
> >> I can reference st,stm32-dma.yaml directly, but I was unsure if this
> >> mux IP was used with another DMA controller from ST on a different
> >> SoC.
> >>
> >> What do you suggest here?
> >
> > Thanks for explanation, I think it is fine.
> >
> > Best regards,
> > Krzysztof
>
> This description was lost when STM32 DMAMUX binding txt file was
> converted to yaml:
> 0b7c446fa9f7 ("dt-bindings: dma: Convert stm32 DMAMUX bindings to
> json-schema")
>
> -- #dma-cells:  Should be set to <3>.
> -               First parameter is request line number.
> -               Second is DMA channel configuration
> -               Third is Fifo threshold

Thanks for the info, this aligns with what I have

> -               For more details about the three cells, please see
> -               stm32-dma.txt documentation binding file
>
>
> stm32-dmamux exclusively muxes stm32-dma channels. It is not used with
> other ST DMA controllers (STM32 MDMA, STM32 DMA3).
>
> So it is fine to refer to st,stm32-dma.yaml.

Ok, I can add that on v2

>
> Regards,
> Amelie

-- 
Sincerely,
Ken Sloat


From alexander.stein at ew.tq-group.com  Fri Dec  6 02:51:31 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 06 Dec 2024 11:51:31 +0100
Subject: [PATCH v2] dt-bindings: phy: imx8mq-usb: correct reference to usb-switch.yaml
In-Reply-To: <20241119105017.917833-1-xu.yang_2@nxp.com>
References: <20241119105017.917833-1-xu.yang_2@nxp.com>
Message-ID: <3326164.aeNJFYEL58@steina-w>

Am Dienstag, 19. November 2024, 11:50:17 CET schrieb Xu Yang:
> The i.MX95 usb-phy can work with or without orientation-switch. With
> current setting, if usb-phy works without orientation-switch, the
> dt-schema check will show below error:
> 
> phy at 4c1f0040: 'oneOf' conditional failed, one must be fixed:
>         'port' is a required property
>         'ports' is a required property
>         from schema $id: http://devicetree.org/schemas/phy/fsl,imx8mq-usb-phy.yaml#
> 
> This will correct the behavior of referring to usb-switch.yaml.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

Acked-by: Alexander Stein <alexander.stein at ew.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 cristian.ciocaltea at collabora.com  Fri Dec  6 03:18:56 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Fri, 6 Dec 2024 13:18:56 +0200
Subject: [PATCH 1/2] phy: phy-rockchip-samsung-hdptx: annotate regmap
 register-callback
In-Reply-To: <20241206103401.1780416-2-heiko@sntech.de>
References: <20241206103401.1780416-1-heiko@sntech.de>
 <20241206103401.1780416-2-heiko@sntech.de>
Message-ID: <e6172204-2f3f-4a9c-892c-be85d19ad031@collabora.com>

On 12/6/24 12:34 PM, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> The variant of the driver in the vendor-tree contained those handy
> comments in the regmap register callback. Having the different ranges
> describe what they are looks helpful.
> 
> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
> ---
>  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index 4ced1479e2dc..c5c64c209e96 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -766,13 +766,13 @@ static struct tx_drv_ctrl tx_drv_ctrl_hbr2[4][4] = {
>  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:
> +	case 0x0000 ... 0x029c: /* CMN Register */
> +	case 0x0400 ... 0x04a4: /* Sideband Register */
> +	case 0x0800 ... 0x08a4: /* Lane Top Register */
> +	case 0x0c00 ... 0x0cb4: /* Lane 0 Register */
> +	case 0x1000 ... 0x10b4: /* Lane 1 Register */
> +	case 0x1400 ... 0x14b4: /* Lane 2 Register */
> +	case 0x1800 ... 0x18b4: /* Lane 3 Register */
>  		return true;
>  	}
>  

Nice finding!  The HDMI variant of the driver which I used as an
implementation reference (i.e. phy-rockchip-samsung-hdptx-hdmi.c)
doesn't provide these comments.

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>


From cristian.ciocaltea at collabora.com  Fri Dec  6 03:26:35 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Fri, 6 Dec 2024 13:26:35 +0200
Subject: [PATCH 2/2] phy: phy-rockchip-samsung-hdptx: Don't use dt aliases
 to determine phy-id
In-Reply-To: <20241206103401.1780416-3-heiko@sntech.de>
References: <20241206103401.1780416-1-heiko@sntech.de>
 <20241206103401.1780416-3-heiko@sntech.de>
Message-ID: <87273a36-07f9-4224-bfff-63e905be9b0a@collabora.com>

On 12/6/24 12:34 PM, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> The phy needs to know its identity in the system (phy0 or phy1 on rk3588)
> for some actions and the driver currently contains code abusing of_alias
> for that.
> 
> Devicetree aliases are always optional and should not be used for core
> device functionality, so instead keep a list of phys on a soc in the
> of_device_data and find the phy-id by comparing against the mapped
> register-base.
> 
> Fixes: c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock provider support")
> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
> ---
>  .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 50 ++++++++++++++++---
>  1 file changed, 44 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index c5c64c209e96..b137f8c4d157 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -385,11 +385,22 @@ enum rk_hdptx_reset {
>  	RST_MAX
>  };

[...]

> +
> +	/* find the phy-id from the io address */
> +	hdptx->phy_id = -ENODEV;
> +	for (id = 0; id < hdptx->cfgs->num_phys; id++) {
> +		if (res->start == hdptx->cfgs->phy_ids[id]) {
> +			hdptx->phy_id = id;
> +			break;
> +		}
> +	}
> +
> +	if (hdptx->phy_id < 0)
> +		return dev_err_probe(dev, -ENODEV, "no matching device found\n");

Maybe we could simply fallback to assume phy1 doesn't exist in this
case, which avoids the need to provide a match data with a single entry.

Regardless,

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>


From peng.fan at oss.nxp.com  Fri Dec  6 03:27:31 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri,  6 Dec 2024 19:27:31 +0800
Subject: [PATCH 2/2] pmdomain: gpcv2: Suppress bind attrs
In-Reply-To: <20241206112731.98244-1-peng.fan@oss.nxp.com>
References: <20241206112731.98244-1-peng.fan@oss.nxp.com>
Message-ID: <20241206112731.98244-2-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

The gpcv2 drivers on imx8m series are registered as platform
devices and this opens the possibility of reloading the driver
at runtime.

But this doesn't actually work. There are some hardware sequence
dependecy between blk ctrl and gpc, also power domains are used
by other peripherals, so fix this by explicitly suppressing bind
attrs.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/pmdomain/imx/gpcv2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c
index e67ecf99ef84..4db4d666f5bf 100644
--- a/drivers/pmdomain/imx/gpcv2.c
+++ b/drivers/pmdomain/imx/gpcv2.c
@@ -1437,6 +1437,7 @@ static struct platform_driver imx_pgc_domain_driver = {
 	.driver = {
 		.name = "imx-pgc",
 		.pm = &imx_pgc_domain_pm_ops,
+		.suppress_bind_attrs = true,
 	},
 	.probe    = imx_pgc_domain_probe,
 	.remove = imx_pgc_domain_remove,
@@ -1549,6 +1550,7 @@ static struct platform_driver imx_gpc_driver = {
 	.driver = {
 		.name = "imx-gpcv2",
 		.of_match_table = imx_gpcv2_dt_ids,
+		.suppress_bind_attrs = true,
 	},
 	.probe = imx_gpcv2_probe,
 };
-- 
2.37.1



From peng.fan at oss.nxp.com  Fri Dec  6 03:27:30 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri,  6 Dec 2024 19:27:30 +0800
Subject: [PATCH 1/2] pmdomain: imx8m[p]-blk-ctrl: Suppress bind attrs
Message-ID: <20241206112731.98244-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

The blk ctrl drivers on imx8m series are registered as platform
devices and this opens the possibility of reloading the driver
at runtime.

But this doesn't actually work. There are some hardware sequence
dependecy between blk ctrl and gpc, also power domains are used
by other peripherals, so fix this by explicitly suppressing bind
attrs.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/pmdomain/imx/imx8m-blk-ctrl.c  | 1 +
 drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/pmdomain/imx/imx8m-blk-ctrl.c b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
index 23db85b7aa9e..912802b5215b 100644
--- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c
+++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
@@ -894,6 +894,7 @@ static struct platform_driver imx8m_blk_ctrl_driver = {
 		.name = "imx8m-blk-ctrl",
 		.pm = &imx8m_blk_ctrl_pm_ops,
 		.of_match_table = imx8m_blk_ctrl_of_match,
+		.suppress_bind_attrs = true,
 	},
 };
 module_platform_driver(imx8m_blk_ctrl_driver);
diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
index e3a0f64c144c..411dd548c67c 100644
--- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
+++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
@@ -862,6 +862,7 @@ static struct platform_driver imx8mp_blk_ctrl_driver = {
 		.name = "imx8mp-blk-ctrl",
 		.pm = &imx8mp_blk_ctrl_pm_ops,
 		.of_match_table = imx8mp_blk_ctrl_of_match,
+		.suppress_bind_attrs = true,
 	},
 };
 module_platform_driver(imx8mp_blk_ctrl_driver);
-- 
2.37.1



From peng.fan at oss.nxp.com  Fri Dec  6 03:28:43 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri,  6 Dec 2024 19:28:43 +0800
Subject: [PATCH] soc: imx8m: Add remove function
Message-ID: <20241206112843.98720-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Unregister the cpufreq device and soc device in remove path, otherwise
there will be warning when do removing test:
sysfs: cannot create duplicate filename '/devices/platform/imx-cpufreq-dt'
CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.13.0-rc1-next-20241204
Hardware name: NXP i.MX8MPlus EVK board (DT)

Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as platform driver")
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/soc/imx/soc-imx8m.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
index 8ac7658e3d52..8c368947d1e5 100644
--- a/drivers/soc/imx/soc-imx8m.c
+++ b/drivers/soc/imx/soc-imx8m.c
@@ -33,6 +33,11 @@ struct imx8_soc_data {
 	int (*soc_revision)(u32 *socrev, u64 *socuid);
 };
 
+struct imx8m_soc_priv {
+	struct soc_device *soc_dev;
+	struct platform_device *cpufreq_dev;
+};
+
 #ifdef CONFIG_HAVE_ARM_SMCCC
 static u32 imx8mq_soc_revision_from_atf(void)
 {
@@ -198,7 +203,7 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 	const struct imx8_soc_data *data;
 	struct device *dev = &pdev->dev;
 	const struct of_device_id *id;
-	struct soc_device *soc_dev;
+	struct imx8m_soc_priv *priv;
 	u32 soc_rev = 0;
 	u64 soc_uid = 0;
 	int ret;
@@ -207,6 +212,10 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 	if (!soc_dev_attr)
 		return -ENOMEM;
 
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
 	soc_dev_attr->family = "Freescale i.MX";
 
 	ret = of_property_read_string(of_root, "model", &soc_dev_attr->machine);
@@ -235,21 +244,34 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 	if (!soc_dev_attr->serial_number)
 		return -ENOMEM;
 
-	soc_dev = soc_device_register(soc_dev_attr);
-	if (IS_ERR(soc_dev))
-		return PTR_ERR(soc_dev);
+	priv->soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR(priv->soc_dev))
+		return PTR_ERR(priv->soc_dev);
 
 	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
 		soc_dev_attr->revision);
 
 	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
-		platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
+		priv->cpufreq_dev = platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
+
+	platform_set_drvdata(pdev, priv);
 
 	return 0;
 }
 
+static void imx8m_soc_remove(struct platform_device *pdev)
+{
+	struct imx8m_soc_priv *priv = platform_get_drvdata(pdev);
+
+	if (!IS_ERR(priv->cpufreq_dev))
+		platform_device_unregister(priv->cpufreq_dev);
+
+	soc_device_unregister(priv->soc_dev);
+}
+
 static struct platform_driver imx8m_soc_driver = {
 	.probe = imx8m_soc_probe,
+	.remove	= imx8m_soc_remove,
 	.driver = {
 		.name = "imx8m-soc",
 	},
-- 
2.37.1



From m.felsch at pengutronix.de  Fri Dec  6 03:41:30 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Fri, 6 Dec 2024 12:41:30 +0100
Subject: [PATCH] soc: imx8m: Add remove function
In-Reply-To: <20241206112843.98720-1-peng.fan@oss.nxp.com>
References: <20241206112843.98720-1-peng.fan@oss.nxp.com>
Message-ID: <20241206114130.zt4rkotzbzi3xt5n@pengutronix.de>

On 24-12-06, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Unregister the cpufreq device and soc device in remove path, otherwise
> there will be warning when do removing test:
> sysfs: cannot create duplicate filename '/devices/platform/imx-cpufreq-dt'
> CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.13.0-rc1-next-20241204
> Hardware name: NXP i.MX8MPlus EVK board (DT)
> 
> Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as platform driver")
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/soc/imx/soc-imx8m.c | 32 +++++++++++++++++++++++++++-----
>  1 file changed, 27 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
> index 8ac7658e3d52..8c368947d1e5 100644
> --- a/drivers/soc/imx/soc-imx8m.c
> +++ b/drivers/soc/imx/soc-imx8m.c
> @@ -33,6 +33,11 @@ struct imx8_soc_data {
>  	int (*soc_revision)(u32 *socrev, u64 *socuid);
>  };
>  
> +struct imx8m_soc_priv {
> +	struct soc_device *soc_dev;
> +	struct platform_device *cpufreq_dev;
> +};
> +
>  #ifdef CONFIG_HAVE_ARM_SMCCC
>  static u32 imx8mq_soc_revision_from_atf(void)
>  {
> @@ -198,7 +203,7 @@ static int imx8m_soc_probe(struct platform_device *pdev)
>  	const struct imx8_soc_data *data;
>  	struct device *dev = &pdev->dev;
>  	const struct of_device_id *id;
> -	struct soc_device *soc_dev;
> +	struct imx8m_soc_priv *priv;
>  	u32 soc_rev = 0;
>  	u64 soc_uid = 0;
>  	int ret;
> @@ -207,6 +212,10 @@ static int imx8m_soc_probe(struct platform_device *pdev)
>  	if (!soc_dev_attr)
>  		return -ENOMEM;
>  
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
>  	soc_dev_attr->family = "Freescale i.MX";
>  
>  	ret = of_property_read_string(of_root, "model", &soc_dev_attr->machine);
> @@ -235,21 +244,34 @@ static int imx8m_soc_probe(struct platform_device *pdev)
>  	if (!soc_dev_attr->serial_number)
>  		return -ENOMEM;
>  
> -	soc_dev = soc_device_register(soc_dev_attr);
> -	if (IS_ERR(soc_dev))
> -		return PTR_ERR(soc_dev);
> +	priv->soc_dev = soc_device_register(soc_dev_attr);
> +	if (IS_ERR(priv->soc_dev))
> +		return PTR_ERR(priv->soc_dev);
>  
>  	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
>  		soc_dev_attr->revision);
>  
>  	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
> -		platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
> +		priv->cpufreq_dev = platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);

If CONFIG_ARM_IMX_CPUFREQ_DT is enabled, I asusme that
platform_device_register_simple() shouldn't fail else it will be an
error, right? Therefore I would like to add the 'if(!IS_ERR())' check
here instead of the remove function.

> +
> +	platform_set_drvdata(pdev, priv);
>  
>  	return 0;
>  }
>  
> +static void imx8m_soc_remove(struct platform_device *pdev)
> +{
> +	struct imx8m_soc_priv *priv = platform_get_drvdata(pdev);
> +
> +	if (!IS_ERR(priv->cpufreq_dev))

With the above shifted, we only need to:
	if (priv->cpufreq_dev)

Regards,
  Marco


> +		platform_device_unregister(priv->cpufreq_dev);
> +
> +	soc_device_unregister(priv->soc_dev);
> +}
> +
>  static struct platform_driver imx8m_soc_driver = {
>  	.probe = imx8m_soc_probe,
> +	.remove	= imx8m_soc_remove,
>  	.driver = {
>  		.name = "imx8m-soc",
>  	},
> -- 
> 2.37.1
> 
> 
> 


From guoqing.jiang at canonical.com  Fri Dec  6 03:42:33 2024
From: guoqing.jiang at canonical.com (Guoqing Jiang)
Date: Fri,  6 Dec 2024 19:42:33 +0800
Subject: [PATCH] drm/rockchip: Remove unnecessary checking
Message-ID: <20241206114233.1270989-1-guoqing.jiang@canonical.com>

It is not needed since drm_atomic_helper_shutdown checks it.

Signed-off-by: Guoqing Jiang <guoqing.jiang at canonical.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 585355de696b..64f5f547fb7a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -488,8 +488,7 @@ static void rockchip_drm_platform_shutdown(struct platform_device *pdev)
 {
 	struct drm_device *drm = platform_get_drvdata(pdev);
 
-	if (drm)
-		drm_atomic_helper_shutdown(drm);
+	drm_atomic_helper_shutdown(drm);
 }
 
 static const struct of_device_id rockchip_drm_dt_ids[] = {
-- 
2.35.3



From guoqing.jiang at canonical.com  Fri Dec  6 03:45:31 2024
From: guoqing.jiang at canonical.com (Guoqing Jiang)
Date: Fri,  6 Dec 2024 19:45:31 +0800
Subject: [PATCH] drm/exynos: Remove unnecessary checking
Message-ID: <20241206114531.1271123-1-guoqing.jiang@canonical.com>

It is not needed since drm_atomic_helper_shutdown checks it.

Signed-off-by: Guoqing Jiang <guoqing.jiang at canonical.com>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 2a466d8179f4..461384705cf9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -357,8 +357,7 @@ static void exynos_drm_platform_shutdown(struct platform_device *pdev)
 {
 	struct drm_device *drm = platform_get_drvdata(pdev);
 
-	if (drm)
-		drm_atomic_helper_shutdown(drm);
+	drm_atomic_helper_shutdown(drm);
 }
 
 static struct platform_driver exynos_drm_platform_driver = {
-- 
2.35.3



From ksloat at cornersoftsolutions.com  Fri Dec  6 03:50:18 2024
From: ksloat at cornersoftsolutions.com (Ken Sloat)
Date: Fri,  6 Dec 2024 06:50:18 -0500
Subject: [PATCH v2] dt-bindings: dma: st-stm32-dmamux: Add description for dma-cell values
Message-ID: <20241206115018.1155149-1-ksloat@cornersoftsolutions.com>

The dma-cell values for the stm32-dmamux are used to craft the DMA spec
for the actual controller. These values are currently undocumented
leaving the user to reverse engineer the driver in order to determine
their meaning. Add a basic description, while avoiding duplicating
information by pointing the user to the associated DMA docs that
describe the fields in depth.

Signed-off-by: Ken Sloat <ksloat at cornersoftsolutions.com>
---

Changes in v2:
    - Remove redundant comment regarding dma-cells val
    - Reference bindings doc for DMA controller

 .../devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
index f26c914a3a9a..b7bca1a83769 100644
--- a/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
+++ b/Documentation/devicetree/bindings/dma/stm32/st,stm32-dmamux.yaml
@@ -15,6 +15,16 @@ allOf:
 properties:
   "#dma-cells":
     const: 3
+    description: |
+      Each cell represents the following:
+      1. The mux input number/line for the request
+      2. Bitfield representing DMA channel configuration that is passed
+         to the real DMA controller
+      3. Bitfield representing device dependent DMA features passed to
+         the real DMA controller
+
+      For bitfield definitions of cells 2 and 3, see the associated
+      bindings doc for the actual DMA controller in st,stm32-dma.yaml.
 
   compatible:
     const: st,stm32h7-dmamux
-- 
2.34.1



From igor.belwon at mentallysanemainliners.org  Fri Dec  6 03:52:29 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Fri, 6 Dec 2024 12:52:29 +0100 (GMT+01:00)
Subject: [PATCH v1 1/1] arm64: dts: exynos990: Add clock management unit
 nodes
In-Reply-To: <fdb4af16-468a-4c23-b8f4-ab60d4b535d2@kernel.org>
Message-ID: <bb128c8f-5315-447f-ad47-c051a4a9ebf5@mentallysanemainliners.org>

Hi Krzysztof

Thanks for the review.

I just have a question - do you prefer having the two (pmu and cmu)
device tree changes spread out, or should I merge them into
one patchset?

Thanks and best regards

Igor


From tudor.ambarus at linaro.org  Fri Dec  6 03:59:02 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 6 Dec 2024 11:59:02 +0000
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <427caa87-b9ba-4797-88bd-a18a96eefdcf@app.fastmail.com>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-3-tudor.ambarus@linaro.org>
 <427caa87-b9ba-4797-88bd-a18a96eefdcf@app.fastmail.com>
Message-ID: <aa09bbe3-8f5f-42cb-a7a9-deaaef77affb@linaro.org>

Thanks for the review, Arnd!

On 12/6/24 6:47 AM, Arnd Bergmann wrote:
> On Thu, Dec 5, 2024, at 18:53, Tudor Ambarus wrote:
> 
>> +#define exynos_acpm_set_bulk(data, i)					\
>> +	(((data) & ACPM_BULK_MASK) << (ACPM_BULK_SHIFT * (i)))
>> +#define exynos_acpm_read_bulk(data, i)					\
>> +	(((data) >> (ACPM_BULK_SHIFT * (i))) & ACPM_BULK_MASK)
> 
> Could these be inline functions for readability?

sure, will do.

> 
>> +	cmd[3] = (u32)(sched_clock() / 1000000); /*record ktime ms*/
> 
> The comment does not match the implementation, sched_clock()
> is probably not what you want here because of its limitiations.
> 
> Maybe ktime_to_ms(ktime_get())?
> 

Indeed, will use, thanks.

>> +/**
>> + * acpm_get_rx() - get response from RX queue.
>> + * @achan:	ACPM channel info.
>> + * @xfer:	reference to the transfer to get response for.
>> + *
>> + * Return: 0 on success, -errno otherwise.
>> + */
>> +static int acpm_get_rx(struct acpm_chan *achan, struct acpm_xfer *xfer)
>> +{
>> +	struct acpm_msg *tx = &xfer->tx;
>> +	struct acpm_msg *rx = &xfer->rx;
>> +	struct acpm_rx_data *rx_data;
>> +	const void __iomem *base, *addr;
>> +	u32 rx_front, rx_seqnum, tx_seqnum, seqnum;
>> +	u32 i, val, mlen;
>> +	bool rx_set = false;
>> +
>> +	rx_front = readl_relaxed(achan->rx.front);
>> +	i = readl_relaxed(achan->rx.rear);
> 
> If you have to use readl_relaxed(), please annotate why,
> otherwise just use the normal readl().  Is this access to
> the SRAM?

all IO accesses in this driver are to SRAM, yes.

There are no DMA accesses involved in the driver and the _relaxed()
accessors are fully ordered for accesses to the same endpoint, so I
thought _relaxed are fine.

> 
>> +	spin_lock_irqsave(&achan->tx_lock, flags);
>> +
>> +	tx_front = readl_relaxed(achan->tx.front);
>> +	idx = (tx_front + 1) % achan->qlen;
>> +
>> +	ret = acpm_wait_for_queue_slots(achan, idx);
>> +	if (ret) {
>> +		spin_unlock_irqrestore(&achan->tx_lock, flags);
>> +		return ret;
>> +	}
> 
> It looks like you are calling a busy loop function inside
> of a hardirq handler here, with a 500ms timeout. This is
> not ok.

That's true, the code assumes that the method can be called from hard
irq context.

Can't tell whether that timeout is accurate, it comes from downstream
and the resources that I have do not specify anything about what would
be an acceptable timeout.

I see arm_scmi typically uses 30 ms for transport layers.

> 
> If you may need to wait for a long timeout, I would suggest
> changing the interface so that this function is not allowed
> to be called from irq-disabled context, change the spinlock
> to a mutex and polling read to a sleeping version.

I think the question I need to answer here is whether the acpm interface
can be called from atomic context or not. On a first look, all
downstream drivers call it from process context. Curios there's no clock
enable though in downstream, which would require atomic context. I'll
get back to you on this.

If there's at least a client that calls the interface in hard/soft irq
context (clocks?) then I don't think I'll be able to implement your
suggestion. Each channel has its own TX/RX rings in SRAM. If there are
requests from both hard irq and process context for the same channel,
then I need to protect the accesses to the rings via spin_lock_irqsave.
This is what the code assumes, because downstream allows calls from
atomic context even if I can't pinpoint one right now.

I guess I can switch everything to sleeping version, and worry about
atomic context when such a client gets proposed?

> 
>> +	/* Advance TX front. */
>> +	writel_relaxed(idx, achan->tx.front);
>> +
>> +	/* Flush SRAM posted writes. */
>> +	readl_relaxed(achan->tx.front);
>> +
>> +	spin_unlock_irqrestore(&achan->tx_lock, flags);
> 
> I don't think this sequence guarantees the serialization
> you want. By making the access _relaxed() you explicitly
> say you don't want serialization, so the store does
> not have to complete before the unlock.
> 

I could benefit of the non relaxed versions indeed.


>> +		.of_match_table	= of_match_ptr(acpm_match),
> 
> Remove the stray of_match_ptr() here.

okay

>> --- /dev/null
>> +++ b/include/linux/soc/samsung/exynos-acpm-protocol.h
> 
> Why is this in include/linux/soc, and not in the firmware
> header?

right, will move.

Thanks!
ta


From robin.murphy at arm.com  Fri Dec  6 04:03:52 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 6 Dec 2024 12:03:52 +0000
Subject: [PATCH 1/2] iommu/arm-smmu-v3: Document SVA interaction with new
 pagetable features
In-Reply-To: <20241205181404.GB664340@myrica>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
 <20241205181404.GB664340@myrica>
Message-ID: <7f58898d-b9a9-4e54-a198-70351fa51784@arm.com>

On 2024-12-05 6:14 pm, Jean-Philippe Brucker wrote:
> On Thu, Dec 05, 2024 at 01:48:09PM +0000, Robin Murphy wrote:
>> Process pagetables may now be using new permission-indirection-based
>> features which an SMMU may not understand when given such a table for
>> SVA. Although SMMUv3.4 does add its own S1PIE feature, realistically
>> we're still going to have to cope with feature mismatches between CPUs
>> and SMMUs, so let's start simple and essentially just document the
>> expectations for what falls out as-is. Although it seems unlikely for
>> SVA applications to also depend on memory-hardening features, or
>> vice-versa,
> 
> Hard to predict, but SVA could be indirectly enabled by some common
> library: for example a libcrypto plugin that shares the address space with
> an accelerator when one is available (see uadk_engine). I'm not familiar
> with the POE use-cases, but I guess a common library could also enable
> those memory-hardening features, such that unsuspecting applications have
> everything enabled.
> 
>> the relative lifecycles make it tricky to enforce mutual
>> exclusivity. Thankfully our PIE index allocation makes it relatively
>> benign for an SMMU to keep interpreting them as direct permissions, the
>> only real implication is that an SVA application cannot harden itself
>> against its own devices with these features. Thus, inform the user about
>> that just in case they have other expectations.
>>
>> Also we don't (yet) support LPA2, so deny SVA entirely if we're going to
>> misunderstand the pagetable format altogether.
>>
>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
>> ---
>>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 15 ++++++++++++++-
>>   1 file changed, 14 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 1d3e71569775..9ba596430e7c 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
>> @@ -112,6 +112,15 @@ void arm_smmu_make_sva_cd(struct arm_smmu_cd *target,
>>   	 * from the current CPU register
>>   	 */
>>   	target->data[3] = cpu_to_le64(read_sysreg(mair_el1));
>> +
>> +	/*
>> +	 * Note that we don't bother with S1PIE on the SMMU, we just rely on
>> +	 * our default encoding scheme matching direct permissions anyway.
>> +	 * SMMU has no notion of S1POE nor GCS, so make sure that is clear if
>> +	 * either is enabled for CPUs, just in case anyone imagines otherwise.
>> +	 */
>> +	if (system_supports_poe() || system_supports_gcs())
>> +		dev_warn_once(master->smmu->dev, "SVA devices ignore permission overlays and GCS\n");
> 
> If POE tightens the page permissions, enabling SVA on top lets the
> application easily bypass the POE protection. Could we actually return
> false in arm_smmu_sva_supported() instead of displaying a warning that
> likely no one will notice?

The difficulty with both features is that they're always unconditionally 
*enabled* if present, but the SVA concern only arises if and when they 
are *actively used*, and that can be a transient thing. It doesn't seem 
reasonable to effectively make SVA unusable on newer CPUs (or at least 
force users to boot with MMFR overrides to lose GCS/POE if they want to 
use SVA), especially when it's far from clear how bothered anyone's 
really going to be about this anyway. I just think we should do at least 
*something* to remember and acknowledge that certain CPU features impact 
SVA too.

> I guess enforcing !(SVA & POE) on an address space would be too much work?

Yes, to attempt to do this "properly" I believe we'd need to keep track 
of how many SVA attachments, overlays, and GCS pages (if the SMMU can't 
support S1PIE) a process has at any given point in time, then check 
those in all 3 places to deny individual usage calls if the "opposing" 
feature is currently in use.

Thanks,
Robin.

> 
> Thanks,
> Jean
> 
>>   }
>>   EXPORT_SYMBOL_IF_KUNIT(arm_smmu_make_sva_cd);
>>   
>> @@ -206,8 +215,12 @@ bool arm_smmu_sva_supported(struct arm_smmu_device *smmu)
>>   	unsigned long asid_bits;
>>   	u32 feat_mask = ARM_SMMU_FEAT_COHERENCY;
>>   
>> -	if (vabits_actual == 52)
>> +	if (vabits_actual == 52) {
>> +		/* We don't support LPA2 */
>> +		if (PAGE_SIZE != SZ_64K)
>> +			return false;
>>   		feat_mask |= ARM_SMMU_FEAT_VAX;
>> +	}
>>   
>>   	if ((smmu->features & feat_mask) != feat_mask)
>>   		return false;
>> -- 
>> 2.39.2.101.g768bb238c484.dirty
>>



From ciprianmarian.costea at oss.nxp.com  Fri Dec  6 04:05:07 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Marian Costea)
Date: Fri, 6 Dec 2024 14:05:07 +0200
Subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <2005af5d-bdb7-4675-8f0e-82cb817801af@app.fastmail.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
 <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
 <2005af5d-bdb7-4675-8f0e-82cb817801af@app.fastmail.com>
Message-ID: <6f4a0be8-4def-4066-9b44-d43059b7a90d@oss.nxp.com>

On 12/6/2024 10:04 AM, Arnd Bergmann wrote:
> [You don't often get email from arnd at arndb.de. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> On Fri, Dec 6, 2024, at 08:09, Ciprian Costea wrote:
>> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>>
>> Add a RTC driver for NXP S32G2/S32G3 SoCs.
>>
>> RTC tracks clock time during system suspend. It can be a wakeup source
>> for the S32G2/S32G3 SoC based boards.
>>
>> The RTC module from S32G2/S32G3 is not battery-powered and it is not kept
>> alive during system reset.
>>
>> Co-developed-by: Bogdan Hamciuc <bogdan.hamciuc at nxp.com>
>> Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc at nxp.com>
>> Co-developed-by: Ghennadi Procopciuc <Ghennadi.Procopciuc at nxp.com>
>> Signed-off-by: Ghennadi Procopciuc <Ghennadi.Procopciuc at nxp.com>
>> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

Hello Arnd,

Thanks you for your review on this patchset.

> 
> I read through the driver and this looks all good to me, but there
> are two fairly minor things I noticed:
> 
>> +     u64 rtc_hz;
> 
> I see the clock rate is a 64-bit value, which is clearly what
> comes from the clk interface in the kernel
> 
>> +static u64 cycles_to_sec(u64 hz, u64 cycles)
>> +{
>> +     return div_u64(cycles, hz);
>> +}
> 
> and you divide by the clk rate to convert the register value
> to seconds (as expected)
> 
>> +     u32 delta_cnt;
>> +
>> +     if (!seconds || seconds > cycles_to_sec(priv->rtc_hz, RTCCNT_MAX_VAL))
>> +             return -EINVAL;
> 
> However, the range of the register value is only 32 bits,
> which means there is no need to ever divide it by a 64-bit
> number, and with the 32kHz clock in the binding example,
> you only have about 37 hours worth of range here.
> 

I am not sure what is the suggestion here. To cast 'cycles' variable to 
32-bit ?
If yes, indeed 'div_u64' converts 'cycles' (the divisor) to 32-bit so I 
agree it should be u32 instead of u64.
If not, I would prefer to keep using a 64-by-32 division and avoid 
casting 'hz' to 32-bit.

> It would appear that this makes the rtc unsuitable for
> storing absolute time across reboots, and only serve during
> runtime, which is a limitation you should probably document.
> 

Actually there is the option to use DIV512 and/or DIV32 hardware 
divisors for the RTC clock. The driver uses a DIV512 divisor by default 
in order to achieve higher RTC count ranges (by achieving a smaller RTC 
freq). Therefore, the 37 hours become 37 * 512 => ~ 2 years.

However, the rtc limitation of not being persistent during reboot 
remains, due to hardware RTC module registers present of NXP S32G2/S32G3 
SoCs being reset during system reboot. On the other hand, during system 
suspend, the RTC module will keep counting if a clock source is available.

Currently, this limittion is documented as follows:
"RTC tracks clock time during system suspend. It can be a wakeup source 
for the S32G2/S32G3 SoC based boards.

The RTC module from S32G2/S32G3 is not battery-powered and it is not 
kept alive during system reset."

>> +static s64 s32g_rtc_get_time_or_alrm(struct rtc_priv *priv,
>> +                                  u32 offset)
>> +{
>> +     u32 counter;
>> +
>> +     counter = ioread32(priv->rtc_base + offset);
>> +
>> +     if (counter < priv->base.cycles)
>> +             return -EINVAL;
> 
> If 'counter' wraps every 37 hours, this will inevitably fail,
> right? E.g. if priv->base.cycles was already at a large
> 32-bit number, even reading it shortly later will produce
> a small value after the wraparound.
> 
> Using something like time_before() should address this,
> but I think you may need a custom version that works on
> 32-bit numbers.
> 

This is correct. Would the following change be acceptable ?

-       if (counter < priv->base.cycles)
-               return -EINVAL;
-
-       counter -= priv->base.cycles;
+       if (counter < priv->base.cycles) {
+               /* A rollover on RTCCTN has occurred */
+               counter += RTCCNT_MAX_VAL - priv->base.cycles;
+               priv->base.cycles = 0;
+       } else {
+               counter -= priv->base.cycles;
+       }


>> +static int s32g_rtc_resume(struct device *dev)
>> +{
>> +     struct rtc_priv *priv = dev_get_drvdata(dev);
>> +     int ret;
>> +
>> +     if (!device_may_wakeup(dev))
>> +             return 0;
>> +
>> +     /* Disable wake-up interrupts */
>> +     s32g_enable_api_irq(dev, 0);
>> +
>> +     ret = rtc_clk_src_setup(priv);
>> +     if (ret)
>> +             return ret;
>> +
>> +     /*
>> +      * Now RTCCNT has just been reset, and is out of sync with priv->base;
>> +      * reapply the saved time settings.
>> +      */
>> +     return s32g_rtc_set_time(dev, &priv->base.tm);
>> +}
> 
> This also fails if the system has been suspended for more than
> 37 hours, right?

Actually, the system would not go into suspend (returning with error) if 
the alarm setting passes the 32-bit / clk_freq range.
The check is added in 'sec_to_rtcval' which is called from the suspend 
routine.

> 
> One more minor comment: you are using ioread32()/iowrite32()
> to access the MMIO registers, which is a bit unusual. I would
> suggest changing those to the more common readl()/writel()
> that do the exact same thing on arm64.
> 
>          Arnd

Makes sense. I will change to readl/writel in V7.

Best Regards,
Ciprian



From gregkh at linuxfoundation.org  Fri Dec  6 04:08:06 2024
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Fri, 06 Dec 2024 13:08:06 +0100
Subject: Patch "perf jevents: fix breakage when do perf stat on system metric" has been added to the 6.12-stable tree
Message-ID: <2024120606-nearly-arousal-e45f@gregkh>


This is a note to let you know that I've just added the patch titled

    perf jevents: fix breakage when do perf stat on system metric

to the 6.12-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:
     perf-jevents-fix-breakage-when-do-perf-stat-on-system-metric.patch
and it can be found in the queue-6.12 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 4a159e6049f319bef6f9e6d2ccdd322f57d24830 Mon Sep 17 00:00:00 2001
From: Xu Yang <xu.yang_2 at nxp.com>
Date: Thu, 7 Nov 2024 08:20:28 -0800
Subject: perf jevents: fix breakage when do perf stat on system metric
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

From: Xu Yang <xu.yang_2 at nxp.com>

commit 4a159e6049f319bef6f9e6d2ccdd322f57d24830 upstream.

When do perf stat on sys metric, perf tool output nothing now:

  $ perf stat -a -M imx95_ddr_read.all -I 1000
  $

This command runs on an arm64 machine and the Soc has one DDR hw pmu
except one armv8_cortex_a55 pmu. Their maps show as follows:

const struct pmu_events_map pmu_events_map[] = {
{
	.arch = "arm64",
	.cpuid = "0x00000000410fd050",
	.event_table = {
		.pmus = pmu_events__arm_cortex_a55,
		.num_pmus = ARRAY_SIZE(pmu_events__arm_cortex_a55)
	},
	.metric_table = {
		.pmus = NULL,
		.num_pmus = 0
	}
},

static const struct pmu_sys_events pmu_sys_event_tables[] = {
{
	.event_table = {
		.pmus = pmu_events__freescale_imx95_sys,
		.num_pmus = ARRAY_SIZE(pmu_events__freescale_imx95_sys)
	},
	.metric_table = {
		.pmus = pmu_metrics__freescale_imx95_sys,
		.num_pmus = ARRAY_SIZE(pmu_metrics__freescale_imx95_sys)
	},
	.name = "pmu_events__freescale_imx95_sys",
},

Currently, pmu_metrics_table__find() will return NULL when only do perf
stat on sys metric. Then parse_groups() will never be called to parse
sys metric_name, finally perf tool will exit directly. This should be a
common problem.

To fix the issue, this will keep the logic before commit f20c15d13f01
("perf pmu-events: Remember the perf_events_map for a PMU") to return a
empty metric table rather than a NULL pointer.

This should be fine since the removed part just check if the table match
provided metric_name.  Without these code, the code in parse_groups()
will also check the validity of metrci_name too.

Fixes: f20c15d13f017d4b ("perf pmu-events: Remember the perf_events_map for a PMU")
Reviewed-by: James Clark <james.clark at linaro.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
Tested-by: Xu Yang <xu.yang_2 at nxp.com>
Acked-by: Ian Rogers <irogers at google.com>
Cc: Adrian Hunter <adrian.hunter at intel.com>
Cc: Albert Ou <aou at eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Alexandre Ghiti <alexghiti at rivosinc.com>
Cc: Athira Rajeev <atrajeev at linux.vnet.ibm.com>
Cc: Benjamin Gray <bgray at linux.ibm.com>
Cc: Ben Zong-You Xie <ben717 at andestech.com>
Cc: Bibo Mao <maobibo at loongson.cn>
Cc: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
Cc: Dima Kogan <dima at secretsauce.net>
Cc: Dr. David Alan Gilbert <linux at treblig.org>
Cc: Huacai Chen <chenhuacai at kernel.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Jiri Olsa <jolsa at kernel.org>
Cc: John Garry <john.g.garry at oracle.com>
Cc: Kan Liang <kan.liang at linux.intel.com>
Cc: Leo Yan <leo.yan at linux.dev>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Masami Hiramatsu <mhiramat at kernel.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Namhyung Kim <namhyung at kernel.org>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
Cc: Paul Walmsley <paul.walmsley at sifive.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ravi Bangoria <ravi.bangoria at amd.com>
Cc: Sandipan Das <sandipan.das at amd.com>
Cc: Will Deacon <will at kernel.org>
Cc: Yicong Yang <yangyicong at hisilicon.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-riscv at lists.infradead.org
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20241107162035.52206-2-irogers at google.com
Signed-off-by: Ian Rogers <irogers at google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme at redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 tools/perf/pmu-events/empty-pmu-events.c |   12 +-----------
 tools/perf/pmu-events/jevents.py         |   12 +-----------
 2 files changed, 2 insertions(+), 22 deletions(-)

--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -539,17 +539,7 @@ const struct pmu_metrics_table *perf_pmu
         if (!map)
                 return NULL;
 
-        if (!pmu)
-                return &map->metric_table;
-
-        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
-                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
-                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
-
-                if (pmu__name_match(pmu, pmu_name))
-                           return &map->metric_table;
-        }
-        return NULL;
+	return &map->metric_table;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1089,17 +1089,7 @@ const struct pmu_metrics_table *perf_pmu
         if (!map)
                 return NULL;
 
-        if (!pmu)
-                return &map->metric_table;
-
-        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
-                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
-                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
-
-                if (pmu__name_match(pmu, pmu_name))
-                           return &map->metric_table;
-        }
-        return NULL;
+	return &map->metric_table;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)


Patches currently in stable-queue which might be from xu.yang_2 at nxp.com are

queue-6.12/perf-jevents-fix-breakage-when-do-perf-stat-on-system-metric.patch


From andyshrk at 163.com  Fri Dec  6 04:08:47 2024
From: andyshrk at 163.com (Andy Yan)
Date: Fri, 6 Dec 2024 20:08:47 +0800 (CST)
Subject: [PATCH] drm/rockchip: Remove unnecessary checking
In-Reply-To: <20241206114233.1270989-1-guoqing.jiang@canonical.com>
References: <20241206114233.1270989-1-guoqing.jiang@canonical.com>
Message-ID: <6db9676.aa57.1939bdf5e6e.Coremail.andyshrk@163.com>

Hi Guoqing,

At 2024-12-06 19:42:33, "Guoqing Jiang" <guoqing.jiang at canonical.com> wrote:
>It is not needed since drm_atomic_helper_shutdown checks it.
>
>Signed-off-by: Guoqing Jiang <guoqing.jiang at canonical.com>

   Acked-by: Andy Yan<andyshrk at 163.com>

Thanks

>---
> drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
>diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>index 585355de696b..64f5f547fb7a 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>@@ -488,8 +488,7 @@ static void rockchip_drm_platform_shutdown(struct platform_device *pdev)
> {
> 	struct drm_device *drm = platform_get_drvdata(pdev);
> 
>-	if (drm)
>-		drm_atomic_helper_shutdown(drm);
>+	drm_atomic_helper_shutdown(drm);
> }
> 
> static const struct of_device_id rockchip_drm_dt_ids[] = {
>-- 
>2.35.3
>
>
>_______________________________________________
>Linux-rockchip mailing list
>Linux-rockchip at lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-rockchip

From ja at ssi.bg  Fri Dec  6 04:19:21 2024
From: ja at ssi.bg (Julian Anastasov)
Date: Fri, 6 Dec 2024 14:19:21 +0200 (EET)
Subject: [PATCH net] Fix clamp() of ip_vs_conn_tab on small memory
 systems.
In-Reply-To: <33893212b1cc4a418cec09aeeed0a9fc@AcuMS.aculab.com>
References: <33893212b1cc4a418cec09aeeed0a9fc@AcuMS.aculab.com>
Message-ID: <5ec10e7c-d050-dab8-1f1b-d0ca2d922eef@ssi.bg>


	Hello,

On Fri, 6 Dec 2024, David Laight wrote:

> The intention of the code seems to be that the minimum table
> size should be 256 (1 << min).
> However the code uses max = clamp(20, 5, max_avail) which implies

	Actually, it tries to reduce max=20 (max possible) below
max_avail: [8 .. max_avail]. Not sure what 5 is here...

> the author thought max_avail could be less than 5.
> But clamp(val, min, max) is only well defined for max >= min.
> If max < min whether is returns min or max depends on the order of
> the comparisons.

	Looks like max_avail goes below 8 ? What value you see
for such small system?

> Change to clamp(max_avail, 5, 20) which has the expected behaviour.

	It should be clamp(max_avail, 8, 20)

> 
> Replace the clamp_val() on the line below with clamp().
> clamp_val() is just 'an accident waiting to happen' and not needed here.

	OK

> Fixes: 4f325e26277b6
> (Although I actually doubt the code is used on small memory systems.)
> 
> Detected by compile time checks added to clamp(), specifically:
> minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()

	Existing or new check? Does it happen that max_avail
is a constant, so that a compile check triggers?

> 
> Signed-off-by: David Laight <david.laight at aculab.com>

	The code below looks ok to me but can you change the
comments above to more correctly specify the values and if the
problem is that max_avail goes below 8 (min).

> ---
>  net/netfilter/ipvs/ip_vs_conn.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
> index 98d7dbe3d787..c0289f83f96d 100644
> --- a/net/netfilter/ipvs/ip_vs_conn.c
> +++ b/net/netfilter/ipvs/ip_vs_conn.c
> @@ -1495,8 +1495,8 @@ int __init ip_vs_conn_init(void)
>  	max_avail -= 2;		/* ~4 in hash row */
>  	max_avail -= 1;		/* IPVS up to 1/2 of mem */
>  	max_avail -= order_base_2(sizeof(struct ip_vs_conn));

	More likely we can additionally clamp max_avail here:

	max_avail = max(min, max_avail);

	But your solution solves the problem with less lines.

> -	max = clamp(max, min, max_avail);
> -	ip_vs_conn_tab_bits = clamp_val(ip_vs_conn_tab_bits, min, max);
> +	max = clamp(max_avail, min, max);
> +	ip_vs_conn_tab_bits = clamp(ip_vs_conn_tab_bits, min, max);
>  	ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
>  	ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
>  
> -- 
> 2.17.1

Regards

--
Julian Anastasov <ja at ssi.bg>



From ciprianmarian.costea at oss.nxp.com  Fri Dec  6 04:31:19 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri,  6 Dec 2024 14:31:19 +0200
Subject: [PATCH] arm64: dts: s32g: add I2C support
Message-ID: <20241206123119.1688712-1-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

Add the I2C Devicetree nodes and pinmux for S32G2 and S32G3 SoCs.

With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
(rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
are quite similar. The common part for the EVB revisions will be
centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
be placed in 's32gxxa-rdb.dtsi' file.

This refactor will also serve for other modules in the future, such as
FlexCAN, DSPI.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 arch/arm64/boot/dts/freescale/s32g2.dtsi      |  45 ++++++
 .../arm64/boot/dts/freescale/s32g274a-evb.dts |   1 +
 .../boot/dts/freescale/s32g274a-rdb2.dts      |   1 +
 arch/arm64/boot/dts/freescale/s32g3.dtsi      |  50 ++++++
 .../boot/dts/freescale/s32g399a-rdb3.dts      |  12 ++
 .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
 .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 124 +++++++++++++++
 7 files changed, 383 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi

diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
index 7be430b78c83..0e6c847ab0c3 100644
--- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -333,6 +333,33 @@ uart1: serial at 401cc000 {
 			status = "disabled";
 		};
 
+		i2c0: i2c at 401e4000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x401e4000 0x1000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c1: i2c at 401e8000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x401e8000 0x1000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c2: i2c at 401ec000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x401ec000 0x1000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		uart2: serial at 402bc000 {
 			compatible = "nxp,s32g2-linflexuart",
 				     "fsl,s32v234-linflexuart";
@@ -341,6 +368,24 @@ uart2: serial at 402bc000 {
 			status = "disabled";
 		};
 
+		i2c3: i2c at 402d8000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x402d8000 0x1000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c4: i2c at 402dc000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x402dc000 0x1000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		usdhc0: mmc at 402f0000 {
 			compatible = "nxp,s32g2-usdhc";
 			reg = <0x402f0000 0x1000>;
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
index b9a119eea2b7..c4a195dd67bf 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s32g2.dtsi"
+#include "s32gxxxa-evb.dtsi"
 
 / {
 	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
index aaa61a8ad0da..b5ba51696f43 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s32g2.dtsi"
+#include "s32gxxxa-rdb.dtsi"
 
 / {
 	model = "NXP S32G2 Reference Design Board 2 (S32G-VNP-RDB2)";
diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
index 6c572ffe37ca..666e4029e588 100644
--- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
@@ -390,6 +390,36 @@ uart1: serial at 401cc000 {
 			status = "disabled";
 		};
 
+		i2c0: i2c at 401e4000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x401e4000 0x1000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c1: i2c at 401e8000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x401e8000 0x1000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c2: i2c at 401ec000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x401ec000 0x1000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		uart2: serial at 402bc000 {
 			compatible = "nxp,s32g3-linflexuart",
 				     "fsl,s32v234-linflexuart";
@@ -398,6 +428,26 @@ uart2: serial at 402bc000 {
 			status = "disabled";
 		};
 
+		i2c3: i2c at 402d8000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x402d8000 0x1000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c4: i2c at 402dc000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x402dc000 0x1000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		usdhc0: mmc at 402f0000 {
 			compatible = "nxp,s32g3-usdhc",
 				     "nxp,s32g2-usdhc";
diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
index 828e353455b5..eb73a5dcebe7 100644
--- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
+++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
@@ -8,6 +8,7 @@
 /dts-v1/;
 
 #include "s32g3.dtsi"
+#include "s32gxxxa-rdb.dtsi"
 
 / {
 	model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
@@ -39,6 +40,17 @@ &uart1 {
 	status = "okay";
 };
 
+&i2c4 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ina231 at 40 {
+		compatible = "ti,ina231";
+		reg = <0x40>;
+		shunt-resistor = <1000>;
+	};
+};
+
 &usdhc0 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz";
 	pinctrl-0 = <&pinctrl_usdhc0>;
diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
new file mode 100644
index 000000000000..a44eff28073a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2024 NXP
+ *
+ * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
+ *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
+ *          Larisa Grigore <larisa.grigore at nxp.com>
+ */
+
+&pinctrl {
+	i2c0_pins: i2c0-pins {
+		i2c0-grp0 {
+			pinmux = <0x101>, <0x111>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-grp1 {
+			pinmux = <0x2352>, <0x2362>;
+		};
+	};
+
+	i2c0_gpio_pins: i2c0-gpio-pins {
+		i2c0-gpio-grp0 {
+			pinmux = <0x100>, <0x110>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-gpio-grp1 {
+			pinmux = <0x2350>, <0x2360>;
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		i2c1-grp0 {
+			pinmux = <0x131>, <0x141>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c1-grp1 {
+			pinmux = <0x2cd2>, <0x2ce2>;
+		};
+	};
+
+	i2c1_gpio_pins: i2c1-gpio-pins {
+		i2c1-gpio-grp0 {
+			pinmux = <0x130>, <0x140>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c1-gpio-grp1 {
+			pinmux = <0x2cd0>, <0x2ce0>;
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		i2c2-grp0 {
+			pinmux = <0x151>, <0x161>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-grp1 {
+			pinmux = <0x2cf2>, <0x2d02>;
+		};
+	};
+
+	i2c2_gpio_pins: i2c2-gpio-pins {
+		i2c2-gpio-grp0 {
+			pinmux = <0x150>, <0x160>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-gpio-grp1 {
+			pinmux = <0x2cf0>, <0x2d00>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		i2c4-grp0 {
+			pinmux = <0x211>, <0x222>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-grp1 {
+			pinmux = <0x2d43>, <0x2d33>;
+		};
+	};
+
+	i2c4_gpio_pins: i2c4-gpio-pins {
+		i2c4-gpio-grp0 {
+			pinmux = <0x210>, <0x220>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-gpio-grp1 {
+			pinmux = <0x2d40>, <0x2d30>;
+		};
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-1 = <&i2c0_gpio_pins>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c1_pins>;
+	pinctrl-1 = <&i2c1_gpio_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_gpio_pins>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-1 = <&i2c4_gpio_pins>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
new file mode 100644
index 000000000000..d992c0c9e695
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2024 NXP
+ *
+ * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
+ *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
+ *          Larisa Grigore <larisa.grigore at nxp.com>
+ */
+
+&pinctrl {
+	i2c0_pins: i2c0-pins {
+		i2c0-grp0 {
+			pinmux = <0x1f2>, <0x201>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-grp1 {
+			pinmux = <0x2353>, <0x2363>;
+		};
+	};
+
+	i2c0_gpio_pins: i2c0-gpio-pins {
+		i2c0-gpio-grp0 {
+			pinmux = <0x1f0>, <0x200>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-gpio-grp1 {
+			pinmux = <0x2350>, <0x2360>;
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		i2c2-grp0 {
+			pinmux = <0x151>, <0x161>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-grp1 {
+			pinmux = <0x2cf2>, <0x2d02>;
+		};
+	};
+
+	i2c2_gpio_pins: i2c2-gpio-pins {
+		i2c2-gpio-grp0 {
+			pinmux = <0x2cf0>, <0x2d00>;
+		};
+
+		i2c2-gpio-grp1 {
+			pinmux = <0x150>, <0x160>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		i2c4-grp0 {
+			pinmux = <0x211>, <0x222>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-grp1 {
+			pinmux = <0x2d43>, <0x2d33>;
+		};
+	};
+
+	i2c4_gpio_pins: i2c4-gpio-pins {
+		i2c4-gpio-grp0 {
+			pinmux = <0x210>, <0x220>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-gpio-grp1 {
+			pinmux = <0x2d40>, <0x2d30>;
+		};
+	};
+};
+
+&i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-1 = <&i2c0_gpio_pins>;
+	status = "okay";
+
+	pcal6524: gpio-expander at 22 {
+		compatible = "nxp,pcal6524";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_gpio_pins>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-1 = <&i2c4_gpio_pins>;
+	status = "okay";
+};
-- 
2.45.2



From quic_bibekkum at quicinc.com  Fri Dec  6 04:36:10 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Fri, 6 Dec 2024 18:06:10 +0530
Subject: [PATCH RESEND v17 3/5] iommu/arm-smmu: add support for PRR bit
 setup
In-Reply-To: <CAF6AEGt-e_4kGyfiO=_oCLX8E3z76zeZ2MbRe1GicZj4hTEu+g@mail.gmail.com>
References: <20241114160721.1527934-1-quic_bibekkum@quicinc.com>
 <20241114160721.1527934-4-quic_bibekkum@quicinc.com>
 <CAF6AEGuwWsAkRyF-h5Aj3KzM7iksb12HsfJ5Ks+-P8hv60MWFg@mail.gmail.com>
 <CAF6AEGvVteuOOMod6yw9_6eOn2PxAx+BR8sVOHAHp7Ts8XigBw@mail.gmail.com>
 <5696afa2-c4ab-42fe-b29a-6ecee622fbb4@quicinc.com>
 <CAF6AEGuMmdnOmATMy8f+YgGxfrYb5mkG_qgy870wZPebKaZjVQ@mail.gmail.com>
 <04da6036-56c4-4b8c-b75b-b5e96a089efc@quicinc.com>
 <CAF6AEGt-e_4kGyfiO=_oCLX8E3z76zeZ2MbRe1GicZj4hTEu+g@mail.gmail.com>
Message-ID: <808e1041-0d61-4ee8-9778-0f9b7d0fb719@quicinc.com>



On 12/4/2024 8:54 PM, Rob Clark wrote:
> On Wed, Dec 4, 2024 at 3:28?AM Bibek Kumar Patro
> <quic_bibekkum at quicinc.com> wrote:
>>
>>
>>
>> On 11/22/2024 10:04 PM, Rob Clark wrote:
>>> On Fri, Nov 22, 2024 at 8:20?AM Bibek Kumar Patro
>>> <quic_bibekkum at quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 11/21/2024 3:40 AM, Rob Clark wrote:
>>>>> On Wed, Nov 20, 2024 at 9:17?AM Rob Clark <robdclark at gmail.com> wrote:
>>>>>>
>>>>>> On Thu, Nov 14, 2024 at 8:10?AM Bibek Kumar Patro
>>>>>> <quic_bibekkum at quicinc.com> wrote:
>>>>>>>
>>>>>>> Add an adreno-smmu-priv interface for drm/msm to call
>>>>>>> into arm-smmu-qcom and initiate the PRR bit setup or reset
>>>>>>> sequence as per request.
>>>>>>>
>>>>>>> This will be used by GPU to setup the PRR bit and related
>>>>>>> configuration registers through adreno-smmu private
>>>>>>> interface instead of directly poking the smmu hardware.
>>>>>>>
>>>>>>> Suggested-by: Rob Clark <robdclark at gmail.com>
>>>>>>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
>>>>>>> ---
>>>>>>>     drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 37 ++++++++++++++++++++++
>>>>>>>     drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 ++
>>>>>>>     include/linux/adreno-smmu-priv.h           | 14 ++++++++
>>>>>>>     3 files changed, 53 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>>>> index d26f5aea248e..0e4f3fbda961 100644
>>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>>>> @@ -16,6 +16,8 @@
>>>>>>>
>>>>>>>     #define QCOM_DUMMY_VAL -1
>>>>>>>
>>>>>>> +#define GFX_ACTLR_PRR          (1 << 5)
>>>>>>> +
>>>>>>>     static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
>>>>>>>     {
>>>>>>>            return container_of(smmu, struct qcom_smmu, smmu);
>>>>>>> @@ -99,6 +101,32 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
>>>>>>>            arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
>>>>>>>     }
>>>>>>>
>>>>>>> +static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
>>>>>>> +{
>>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>>>>> +       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>>>>>>> +       u32 reg = 0;
>>>>>>> +
>>>>>>> +       reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
>>>>>>> +       reg &= ~GFX_ACTLR_PRR;
>>>>>>> +       if (set)
>>>>>>> +               reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
>>>>>>> +       arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
>>>>>>> +}
>>>>>>> +
>>>>>>> +static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
>>>>>>> +{
>>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>>>>> +
>>>>>>> +       writel_relaxed(lower_32_bits(page_addr),
>>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
>>>>>>> +
>>>>>>> +       writel_relaxed(upper_32_bits(page_addr),
>>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
>>>>>>> +}
>>>>>>> +
>>>>>>>     #define QCOM_ADRENO_SMMU_GPU_SID 0
>>>>>>>
>>>>>>>     static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
>>>>>>> @@ -210,6 +238,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>>>>>>>     static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>>>>                    struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>>>>>>>     {
>>>>>>> +       const struct device_node *np = smmu_domain->smmu->dev->of_node;
>>>>>>>            struct adreno_smmu_priv *priv;
>>>>>>>
>>>>>>>            smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>>>>>> @@ -239,6 +268,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>>>>            priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
>>>>>>>            priv->set_stall = qcom_adreno_smmu_set_stall;
>>>>>>>            priv->resume_translation = qcom_adreno_smmu_resume_translation;
>>>>>>> +       priv->set_prr_bit = NULL;
>>>>>>> +       priv->set_prr_addr = NULL;
>>>>>>> +
>>>>>>> +       if (of_device_is_compatible(np, "qcom,smmu-500") &&
>>>>>>> +                       of_device_is_compatible(np, "qcom,adreno-smmu")) {
>>>>>>
>>>>>> fwiw, it seems like PRR actually works on sc7180, which is _not_
>>>>>> mmu-500, so I guess the support actually goes back further.
>>>>>>
>>>>>> I'm curious if we can just rely on this being supported by any hw that
>>>>>> has a6xx or newer?
>>>>>
>>>>>
>>>>> Also, unrelated, but we can't assume the smmu is powered when drm
>>>>> driver calls set_prr_bit/addr, could you add in runpm get/put around
>>>>> the register access?
>>>>>
>>>>
>>>> I see, thanks for this observation.
>>>> It's surely a possible case, when they access these registers
>>>> SMMU state is off.
>>>> I will add the suggested runpm ops around the register access.
>>>>
>>>>> Otherwise Conner and I have vk sparse residency working now
>>>>>
>>>>
>>>> Sorry, could not get this. Did you mean that vk sparse residency
>>>> is working now using this patch?
>>>
>>> Yes, vk sparse residency is working with this patch (plus addition of
>>> runpm get/put, plus drm/msm patches plus turnip patches) ;-)
>>>
>>
>> Thanks for testing the sparse residency feature with our patch Rob,
>> I have an additional query regarding the adreno private interfaces.
>> Specifically, I was referring to other interfaces such as
>> qcom_adreno_smmu_get_fault_info [1]. It appears that we do not have a
>> runpm get/put around the register access in this context.
> 
> get_fault_info() is called from the iommu fault handler callback, so
> from the fault irq handler, which is why it didn't need the runpm
> get/put.  Maybe it is bad to make this assumption about usage, but
> then again adreno_smmu_priv isn't really a general purpose interface.
> 

Ah okay, got it.
I was just going through all the adreno_smmmu_priv interfaces just
to get a better understanding of it's interaction with smmu and it seems
like apart from PRR and get_fault_info(), set_ttbr0_cfg(),
resume_translation() is also having reg access but not voting.
Should we put runpm_put/get here as well or these can be excluded.
<Just curious about the thought process behind this, is it because of
some sequence when to put a vote, like reg access in middle of smmu
power cycle and not in beginning or end.>

>> Could you please clarify whether we need an SMMU vote around register
>> access in the case of PRR? IMO, should the users of this callback ensure
>> they put a vote before accessing the cb?
> 
> How can drm vote for the smmu device?  I guess it could power up
> itself and rely on device-link.. but that is pretty overkill to power
> up the entire gpu in this case.  I think it is best for the vote to
> happen in the PRR callbacks.
> 

Okay I see, GPU can only power itself up through <gpu_state_get I
assume> but won't have exclusive access to power on the smmu only.

Incase we go forward to put vote in PRR callback for SMMU, I was
planning that we can refactor existing arm_smmu_rpm_put/get() from
arm_smmu.c to it's header file so that the same can be used in
arm_smmu_qcom.c ? What's your thoughts on this?

Thanks & regards,
Bibek

> BR,
> -R
> 
>> [1]:
>> https://lore.kernel.org/all/20210610214431.539029-1-robdclark at gmail.com/
>>
>> Thanks & regards,
>> Bibek
>>
>>> BR,
>>> -R
>>>
>>>> Thanks & regards,
>>>> Bibek
>>>>
>>>>> BR,
>>>>> -R
>>>>>
>>>>>>
>>>>>>> +               priv->set_prr_bit = qcom_adreno_smmu_set_prr_bit;
>>>>>>> +               priv->set_prr_addr = qcom_adreno_smmu_set_prr_addr;
>>>>>>> +       }
>>>>>>>
>>>>>>>            return 0;
>>>>>>>     }
>>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>>>> index e2aeb511ae90..2dbf3243b5ad 100644
>>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>>>> @@ -154,6 +154,8 @@ enum arm_smmu_cbar_type {
>>>>>>>     #define ARM_SMMU_SCTLR_M               BIT(0)
>>>>>>>
>>>>>>>     #define ARM_SMMU_CB_ACTLR              0x4
>>>>>>> +#define ARM_SMMU_GFX_PRR_CFG_LADDR     0x6008
>>>>>>> +#define ARM_SMMU_GFX_PRR_CFG_UADDR     0x600C
>>>>>>>
>>>>>>>     #define ARM_SMMU_CB_RESUME             0x8
>>>>>>>     #define ARM_SMMU_RESUME_TERMINATE      BIT(0)
>>>>>>> diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
>>>>>>> index c637e0997f6d..614665153b3e 100644
>>>>>>> --- a/include/linux/adreno-smmu-priv.h
>>>>>>> +++ b/include/linux/adreno-smmu-priv.h
>>>>>>> @@ -50,6 +50,18 @@ struct adreno_smmu_fault_info {
>>>>>>>      *                 the GPU driver must call resume_translation()
>>>>>>>      * @resume_translation: Resume translation after a fault
>>>>>>>      *
>>>>>>> + * *CAUTION* : PRR callbacks (set_prr_bit/set_prr_addr) are NULL terminated for
>>>>>>> + *             targets without PRR support. Exercise caution and verify target
>>>>>>> + *             capabilities before invoking these callbacks to prevent potential
>>>>>>> + *             runtime errors or unexpected behavior.
>>>>>>> + *
>>>>>>> + * @set_prr_bit:   Extendible interface to be used by GPU to modify the
>>>>>>> + *                ACTLR register bits, currently used to configure
>>>>>>> + *                Partially-Resident-Region (PRR) bit for feature's
>>>>>>> + *                setup and reset sequence as requested.
>>>>>>> + * @set_prr_addr:  Configure the PRR_CFG_*ADDR register with the
>>>>>>> + *                physical address of PRR page passed from
>>>>>>> + *                GPU driver.
>>>>>>>      *
>>>>>>>      * The GPU driver (drm/msm) and adreno-smmu work together for controlling
>>>>>>>      * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
>>>>>>> @@ -67,6 +79,8 @@ struct adreno_smmu_priv {
>>>>>>>         void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
>>>>>>>         void (*set_stall)(const void *cookie, bool enabled);
>>>>>>>         void (*resume_translation)(const void *cookie, bool terminate);
>>>>>>> +    void (*set_prr_bit)(const void *cookie, bool set);
>>>>>>> +    void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
>>>>>>>     };
>>>>>>>
>>>>>>>     #endif /* __ADRENO_SMMU_PRIV_H */
>>>>>>> --
>>>>>>> 2.34.1
>>>>>>>
>>>>
>>



From linux at armlinux.org.uk  Fri Dec  6 04:40:52 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 6 Dec 2024 12:40:52 +0000
Subject: [PATCH net v1] net: stmmac: TSO: Fix unaligned DMA unmap for
 non-paged SKB data
In-Reply-To: <20241205085539.0258e5fb@kernel.org>
References: <20241205091830.3719609-1-0x1207@gmail.com>
 <Z1HYKh9eCwkYGlrA@shell.armlinux.org.uk>
 <20241205085539.0258e5fb@kernel.org>
Message-ID: <Z1Lw1LzgeAyHv2Bl@shell.armlinux.org.uk>

On Thu, Dec 05, 2024 at 08:55:39AM -0800, Jakub Kicinski wrote:
> On Thu, 5 Dec 2024 16:43:22 +0000 Russell King (Oracle) wrote:
> > I'm slightly disappointed to have my patch turned into a commit under
> > someone else's authorship before I've had a chance to do that myself.
> > Next time I won't send a patch out until I've done that.
> 
> Yes, this is definitely not okay. LMK if you dropped this from your
> TODO already, otherwise I'm tossing this patch and expecting the fix
> from the real author.

See https://lore.kernel.org/r/E1tJXcx-006N4Z-PC at rmk-PC.armlinux.org.uk/

-- 
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  Fri Dec  6 04:41:55 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 06 Dec 2024 13:41:55 +0100
Subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <6f4a0be8-4def-4066-9b44-d43059b7a90d@oss.nxp.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
 <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
 <2005af5d-bdb7-4675-8f0e-82cb817801af@app.fastmail.com>
 <6f4a0be8-4def-4066-9b44-d43059b7a90d@oss.nxp.com>
Message-ID: <94cba886-86cb-41f1-96ee-501623add7db@app.fastmail.com>

On Fri, Dec 6, 2024, at 13:05, Ciprian Marian Costea wrote:
> On 12/6/2024 10:04 AM, Arnd Bergmann wrote:
>> 
>> However, the range of the register value is only 32 bits,
>> which means there is no need to ever divide it by a 64-bit
>> number, and with the 32kHz clock in the binding example,
>> you only have about 37 hours worth of range here.
>> 
>
> I am not sure what is the suggestion here. To cast 'cycles' variable to 
> 32-bit ?
> If yes, indeed 'div_u64' converts 'cycles' (the divisor) to 32-bit so I 
> agree it should be u32 instead of u64.
> If not, I would prefer to keep using a 64-by-32 division and avoid 
> casting 'hz' to 32-bit.

The confusing bit here is that the extra function just serves to
the dividend 'cycles' from 32-bit to 64-bit, and then calling
div_u64() implicitly casts the dividend 'hz' from 64-bit to
32-bit, so you definitely get a 32-by-32 division already
if the function is inlined properly.

I think storing 'rtc_hz' as a u32 variable and adding a range
check when filling it would help, mainly to save the next reader
from having to understand what is going on.

>> It would appear that this makes the rtc unsuitable for
>> storing absolute time across reboots, and only serve during
>> runtime, which is a limitation you should probably document.
>> 
>
> Actually there is the option to use DIV512 and/or DIV32 hardware 
> divisors for the RTC clock. The driver uses a DIV512 divisor by default 
> in order to achieve higher RTC count ranges (by achieving a smaller RTC 
> freq). Therefore, the 37 hours become 37 * 512 => ~ 2 years.

Ah, makes sense. Can you add comments in an appropriate place in
the code about this?

> However, the rtc limitation of not being persistent during reboot 
> remains, due to hardware RTC module registers present of NXP S32G2/S32G3 
> SoCs being reset during system reboot. On the other hand, during system 
> suspend, the RTC module will keep counting if a clock source is available.
>
> Currently, this limittion is documented as follows:
> "RTC tracks clock time during system suspend. It can be a wakeup source 
> for the S32G2/S32G3 SoC based boards.
>
> The RTC module from S32G2/S32G3 is not battery-powered and it is not 
> kept alive during system reset."

My bad, I really should not have skipped the patch
description ;-)

>> If 'counter' wraps every 37 hours, this will inevitably fail,
>> right? E.g. if priv->base.cycles was already at a large
>> 32-bit number, even reading it shortly later will produce
>> a small value after the wraparound.
>> 
>> Using something like time_before() should address this,
>> but I think you may need a custom version that works on
>> 32-bit numbers.
>> 
>
> This is correct. Would the following change be acceptable ?
>
> -       if (counter < priv->base.cycles)
> -               return -EINVAL;
> -
> -       counter -= priv->base.cycles;
> +       if (counter < priv->base.cycles) {
> +               /* A rollover on RTCCTN has occurred */
> +               counter += RTCCNT_MAX_VAL - priv->base.cycles;
> +               priv->base.cycles = 0;
> +       } else {
> +               counter -= priv->base.cycles;
> +       }

This is the same as just removing the error handling and
relying on unsigned integer overflow semantics.

The usual check we do in time_before()/time_after instead
checks if the elapsed time is less than half the available
range:

#define time_after(a,b)         \
        (typecheck(unsigned long, a) && \
         typecheck(unsigned long, b) && \
         ((long)((b) - (a)) < 0))

>>> +static int s32g_rtc_resume(struct device *dev)
>>> +{
>>> +     struct rtc_priv *priv = dev_get_drvdata(dev);
>>> +     int ret;
>>> +
>>> +     if (!device_may_wakeup(dev))
>>> +             return 0;
>>> +
>>> +     /* Disable wake-up interrupts */
>>> +     s32g_enable_api_irq(dev, 0);
>>> +
>>> +     ret = rtc_clk_src_setup(priv);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     /*
>>> +      * Now RTCCNT has just been reset, and is out of sync with priv->base;
>>> +      * reapply the saved time settings.
>>> +      */
>>> +     return s32g_rtc_set_time(dev, &priv->base.tm);
>>> +}
>> 
>> This also fails if the system has been suspended for more than
>> 37 hours, right?
>
> Actually, the system would not go into suspend (returning with error) if 
> the alarm setting passes the 32-bit / clk_freq range.
> The check is added in 'sec_to_rtcval' which is called from the suspend 
> routine.

Who sets that alarm though? Are you relying on custom userspace
for this, or is that something that the kernel already does
that I'm missing?

       Arnd


From rmk+kernel at armlinux.org.uk  Fri Dec  6 04:40:11 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 06 Dec 2024 12:40:11 +0000
Subject: [PATCH net] net: stmmac: fix TSO DMA API usage causing oops
Message-ID: <E1tJXcx-006N4Z-PC@rmk-PC.armlinux.org.uk>

Commit 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap
for non-paged SKB data") moved the assignment of tx_skbuff_dma[]'s
members to be later in stmmac_tso_xmit().

The buf (dma cookie) and len stored in this structure are passed to
dma_unmap_single() by stmmac_tx_clean(). The DMA API requires that
the dma cookie passed to dma_unmap_single() is the same as the value
returned from dma_map_single(). However, by moving the assignment
later, this is not the case when priv->dma_cap.addr64 > 32 as "des"
is offset by proto_hdr_len.

This causes problems such as:

  dwc-eth-dwmac 2490000.ethernet eth0: Tx DMA map failed

and with DMA_API_DEBUG enabled:

  DMA-API: dwc-eth-dwmac 2490000.ethernet: device driver tries to +free DMA memory it has not allocated [device address=0x000000ffffcf65c0] [size=66 bytes]

Fix this by maintaining "des" as the original DMA cookie, and use
tso_des to pass the offset DMA cookie to stmmac_tso_allocator().

Full details of the crashes can be found at:
https://lore.kernel.org/all/d8112193-0386-4e14-b516-37c2d838171a at nvidia.com/
https://lore.kernel.org/all/klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc at bwwhelz2l4dw/

Reported-by: Jon Hunter <jonathanh at nvidia.com>
Reported-by: Thierry Reding <thierry.reding at gmail.com>
Fixes: 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data")
Tested-by: Jon Hunter <jonathanh at nvidia.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9b262cdad60b..c81ea8cdfe6e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4192,8 +4192,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct stmmac_txq_stats *txq_stats;
 	struct stmmac_tx_queue *tx_q;
 	u32 pay_len, mss, queue;
+	dma_addr_t tso_des, des;
 	u8 proto_hdr_len, hdr;
-	dma_addr_t des;
 	bool set_ic;
 	int i;
 
@@ -4289,14 +4289,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		/* If needed take extra descriptors to fill the remaining payload */
 		tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
+		tso_des = des;
 	} else {
 		stmmac_set_desc_addr(priv, first, des);
 		tmp_pay_len = pay_len;
-		des += proto_hdr_len;
+		tso_des = des + proto_hdr_len;
 		pay_len = 0;
 	}
 
-	stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
+	stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
 
 	/* In case two or more DMA transmit descriptors are allocated for this
 	 * non-paged SKB data, the DMA buffer address should be saved to
-- 
2.30.2



From krzk at kernel.org  Fri Dec  6 04:58:14 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 13:58:14 +0100
Subject: [PATCH v5 05/20] dt-bindings: clock: imx8m-anatop: define
 clocks/clock-names
In-Reply-To: <20241205111939.1796244-6-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
 <20241205111939.1796244-6-dario.binacchi@amarulasolutions.com>
Message-ID: <227zmz7rg4t6j5ylbe4ft7udheffalcqj4uxxrwutcfwuvcm2v@qbih67ilxigy>

On Thu, Dec 05, 2024 at 12:17:40PM +0100, Dario Binacchi wrote:
> Define clocks and clock-names properties of the anatop device node.

This we see from the diff. Say something useful, instead of repeating
subject and patch contents.

> 
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> 
> ---
> 
> (no changes since v4)
> 
> Changes in v4:
> - New
> 
>  .../bindings/clock/fsl,imx8m-anatop.yaml      | 53 ++++++++++++++++++-
>  1 file changed, 52 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml b/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
> index bbd22e95b319..f439b0a94ce2 100644
> --- a/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
> +++ b/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
> @@ -30,22 +30,73 @@ properties:
>    interrupts:
>      maxItems: 1
>  
> +  clocks:
> +    minItems: 2
> +    maxItems: 3
> +
> +  clock-names:
> +    minItems: 2
> +    maxItems: 3
> +
>    '#clock-cells':
>      const: 1
>  
>  required:
>    - compatible
>    - reg
> +  - clocks
> +  - clock-names

That's an ABI break and nothing in commit msg mentions it, nothing
explains impact or rationale behind.

>    - '#clock-cells'

Best regards,
Krzysztof



From krzk at kernel.org  Fri Dec  6 04:56:26 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 13:56:26 +0100
Subject: [PATCH v5 01/20] dt-bindings: clock: imx8mm: add VIDEO_PLL clocks
In-Reply-To: <20241205111939.1796244-2-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
 <20241205111939.1796244-2-dario.binacchi@amarulasolutions.com>
Message-ID: <cnacul23vrat2vmoxmi626awgmodp5zvb7rf5pu2g6cwysmlzh@oqcopgp7tzlm>

On Thu, Dec 05, 2024 at 12:17:36PM +0100, Dario Binacchi wrote:
> Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
> name used in the RM is video_pll. So, let's add the IMX8MM_VIDEO_PLL[_*]
> definitions to be consistent with the RM and avoid misunderstandings.
> 
> The IMX8MM_VIDEO_PLL1* constants have not been removed to ensure
> backward compatibility of the patch.
> 
> No functional changes intended.
> 
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> 
> ---
> 
> Changes in v5:
> - New

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

Best regards,
Krzysztof



From krzk at kernel.org  Fri Dec  6 04:56:40 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 13:56:40 +0100
Subject: [PATCH v5 03/20] dt-bindings: clock: imx8mp: add VIDEO_PLL clocks
In-Reply-To: <20241205111939.1796244-4-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
 <20241205111939.1796244-4-dario.binacchi@amarulasolutions.com>
Message-ID: <djqa52bhxkwtdf5uyccyay5omgwkyevilylmta5aydigdpgk3v@nd3glqyhsyl6>

On Thu, Dec 05, 2024 at 12:17:38PM +0100, Dario Binacchi wrote:
> Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
> name used in the RM is video_pll. So, let's add the IMX8MP_VIDEO_PLL[_*]
> definitions to be consistent with the RM and avoid misunderstandings.
> 
> The IMX8MP_VIDEO_PLL1* constants have not been removed to ensure
> backward compatibility of the patch.
> 
> No functional changes intended.
> 
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> 
> ---
> 
> Changes in v5:
> - New
> 
>  include/dt-bindings/clock/imx8mp-clock.h | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)

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

Best regards,
Krzysztof



From krzk at kernel.org  Fri Dec  6 04:59:27 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 13:59:27 +0100
Subject: [PATCH v5 10/20] dt-bindings: clock: imx8mm: add binding
 definitions for anatop
In-Reply-To: <20241205111939.1796244-11-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
 <20241205111939.1796244-11-dario.binacchi@amarulasolutions.com>
Message-ID: <46awbd7wxh56l3wmgj43zhz7d75was6drkmlydcjqgefee35ll@73jw2xxtpwic>

On Thu, Dec 05, 2024 at 12:17:45PM +0100, Dario Binacchi wrote:
> Add the bindings definitions for the anatop node. The patch is
> preparatory for future developments.

This is never a separate patch but goes with the binding doc.

> 
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> 
> ---
> 
> (no changes since v4)
> 
> Changes in v4:
> - New
> 
>  include/dt-bindings/clock/imx8mm-clock.h | 66 ++++++++++++++++++++++++
>  1 file changed, 66 insertions(+)

...

> +#define IMX8MM_ANATOP_SYS_PLL2_1000M		56
> +#define IMX8MM_ANATOP_CLK_CLKOUT1_SEL		57
> +#define IMX8MM_ANATOP_CLK_CLKOUT1_DIV		58
> +#define IMX8MM_ANATOP_CLK_CLKOUT1		59
> +#define IMX8MM_ANATOP_CLK_CLKOUT2_SEL		60
> +#define IMX8MM_ANATOP_CLK_CLKOUT2_DIV		61
> +#define IMX8MM_ANATOP_CLK_CLKOUT2		62
> +
> +#define IMX8MM_ANATOP_CLK_END			63

Drop, not a binding really.

> +
>  #endif
> -- 
> 2.43.0
> 


From krzk at kernel.org  Fri Dec  6 05:00:54 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 14:00:54 +0100
Subject: [PATCH v5 11/20] dt-bindings: clock: imx8mn: add binding
 definitions for anatop
In-Reply-To: <20241205111939.1796244-12-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
 <20241205111939.1796244-12-dario.binacchi@amarulasolutions.com>
Message-ID: <jgkbsxwhttebjpul43wtt6simygkst7bnis47b5pkevica2th5@n7elmf4u5k3n>

On Thu, Dec 05, 2024 at 12:17:46PM +0100, Dario Binacchi wrote:
> Add the bindings definitions for the anatop node. The patch is
> preparatory for future developments.

I don't understand last statement. How this can prepare? Either you add
bindings for clock provider or not.


> 
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> 
> ---
> 
> (no changes since v4)
> 
> Changes in v4:
> - New
> 
>  include/dt-bindings/clock/imx8mn-clock.h | 67 ++++++++++++++++++++++++
>  1 file changed, 67 insertions(+)

...

> +#define IMX8MN_ANATOP_CLK_CLKOUT1_SEL		57
> +#define IMX8MN_ANATOP_CLK_CLKOUT1_DIV		58
> +#define IMX8MN_ANATOP_CLK_CLKOUT1		59
> +#define IMX8MN_ANATOP_CLK_CLKOUT2_SEL		60
> +#define IMX8MN_ANATOP_CLK_CLKOUT2_DIV		61
> +#define IMX8MN_ANATOP_CLK_CLKOUT2		62
> +
> +#define IMX8MN_ANATOP_CLK_END			63

Drop

> +
>  #endif
> -- 
> 2.43.0
> 


From lgoncalv at redhat.com  Fri Dec  6 05:01:14 2024
From: lgoncalv at redhat.com (Luis Claudio R. Goncalves)
Date: Fri, 6 Dec 2024 10:01:14 -0300
Subject: [PATCH v2] iommu/tegra241-cmdqv: do not use smp_processor_id in
 preemptible context
Message-ID: <Z1L1mja3nXzsJ0Pk@uudg.org>

During boot some of the calls to tegra241_cmdqv_get_cmdq() will happen
in preemptible context. As this function calls smp_processor_id(), if
CONFIG_DEBUG_PREEMPT is enabled, these calls will trigger a series of
"BUG: using smp_processor_id() in preemptible" backtraces.

As tegra241_cmdqv_get_cmdq() only calls smp_processor_id() to use the
CPU number as a factor to balance out traffic on cmdq usage, it is safe
to use raw_smp_processor_id() here.

v2: Sebastian helped identify that the problem was not exclusive to kernels
    with PREEMPT_RT enabled. The delta between v1 and v2 is the description.

Signed-off-by: Luis Claudio R. Goncalves <lgoncalv at redhat.com>
---
 drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
index fcd13d301fff6..3ea4369e838fe 100644
--- a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
+++ b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
@@ -339,7 +339,7 @@ tegra241_cmdqv_get_cmdq(struct arm_smmu_device *smmu,
 	 * one CPU at a time can enter the process, while the others
 	 * will be spinning at the same lock.
 	 */
-	lidx = smp_processor_id() % cmdqv->num_lvcmdqs_per_vintf;
+	lidx = raw_smp_processor_id() % cmdqv->num_lvcmdqs_per_vintf;
 	vcmdq = vintf->lvcmdqs[lidx];
 	if (!vcmdq || !READ_ONCE(vcmdq->enabled))
 		return NULL;
-- 
2.47.0



From arnd at arndb.de  Fri Dec  6 05:02:50 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 06 Dec 2024 14:02:50 +0100
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <aa09bbe3-8f5f-42cb-a7a9-deaaef77affb@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-3-tudor.ambarus@linaro.org>
 <427caa87-b9ba-4797-88bd-a18a96eefdcf@app.fastmail.com>
 <aa09bbe3-8f5f-42cb-a7a9-deaaef77affb@linaro.org>
Message-ID: <f6a04a2f-aed6-436d-aef1-4974a6fe35d2@app.fastmail.com>

On Fri, Dec 6, 2024, at 12:59, Tudor Ambarus wrote:
>>> +/**
>>> + * acpm_get_rx() - get response from RX queue.
>>> + * @achan:	ACPM channel info.
>>> + * @xfer:	reference to the transfer to get response for.
>>> + *
>>> + * Return: 0 on success, -errno otherwise.
>>> + */
>>> +static int acpm_get_rx(struct acpm_chan *achan, struct acpm_xfer *xfer)
>>> +{
>>> +	struct acpm_msg *tx = &xfer->tx;
>>> +	struct acpm_msg *rx = &xfer->rx;
>>> +	struct acpm_rx_data *rx_data;
>>> +	const void __iomem *base, *addr;
>>> +	u32 rx_front, rx_seqnum, tx_seqnum, seqnum;
>>> +	u32 i, val, mlen;
>>> +	bool rx_set = false;
>>> +
>>> +	rx_front = readl_relaxed(achan->rx.front);
>>> +	i = readl_relaxed(achan->rx.rear);
>> 
>> If you have to use readl_relaxed(), please annotate why,
>> otherwise just use the normal readl().  Is this access to
>> the SRAM?
>
> all IO accesses in this driver are to SRAM, yes.
>
> There are no DMA accesses involved in the driver and the _relaxed()
> accessors are fully ordered for accesses to the same endpoint, so I
> thought _relaxed are fine.

My normal rule is to only use _relaxed() if it makes any
intended difference in performance or behavior, otherwise
every reader of the code has to understand why exactly this
was done. More generally speaking, use the function with the
shortest name to do what you want, since the longer functions
are usually special cases that are not the default ;-)

SRAM is a bit special, as you don't have to deal with
side-effects the same way that an MMIO register would,
though there is still a question of serializing against
concurrent accesses from another processor.

It's possible that readl_relaxed()/writel_relaxed() end
up being exactly what you wand for this driver, but I would
probably encapsulate them in a local sram_readl()/sram_writel()
wrapper along with some documentation.

You should also have a look at which ioremap() version
you actually want. The default ioremap() uses
PROT_DEVICE_nGnRE and has strong ordering but not the
"non-posted" guarantee like ioremap_np() that would
let you skip the read-after-write for serialization.

If you care a lot about performance on the SRAM access,
you can go the other way with a more relaxed ioremap_wc()
and explicit barriers where needed, or even better
see what the remote side uses and use the same mapping
flags and serialization here.

>>> +	spin_lock_irqsave(&achan->tx_lock, flags);
>>> +
>>> +	tx_front = readl_relaxed(achan->tx.front);
>>> +	idx = (tx_front + 1) % achan->qlen;
>>> +
>>> +	ret = acpm_wait_for_queue_slots(achan, idx);
>>> +	if (ret) {
>>> +		spin_unlock_irqrestore(&achan->tx_lock, flags);
>>> +		return ret;
>>> +	}
>> 
>> It looks like you are calling a busy loop function inside
>> of a hardirq handler here, with a 500ms timeout. This is
>> not ok.
>
> That's true, the code assumes that the method can be called from hard
> irq context.
>
> Can't tell whether that timeout is accurate, it comes from downstream
> and the resources that I have do not specify anything about what would
> be an acceptable timeout.
>
> I see arm_scmi typically uses 30 ms for transport layers.

I think 30ms is still too much for a busy loop. I see that in
the SCMI driver it implements both a sleeping and a spinning
loop, but I have not found exactly which callers use the
spinning version, and what timeouts those have.

>> If you may need to wait for a long timeout, I would suggest
>> changing the interface so that this function is not allowed
>> to be called from irq-disabled context, change the spinlock
>> to a mutex and polling read to a sleeping version.
>
> I think the question I need to answer here is whether the acpm interface
> can be called from atomic context or not. On a first look, all
> downstream drivers call it from process context. Curios there's no clock
> enable though in downstream, which would require atomic context. I'll
> get back to you on this.
>
> If there's at least a client that calls the interface in hard/soft irq
> context (clocks?) then I don't think I'll be able to implement your
> suggestion. Each channel has its own TX/RX rings in SRAM. If there are
> requests from both hard irq and process context for the same channel,
> then I need to protect the accesses to the rings via spin_lock_irqsave.
> This is what the code assumes, because downstream allows calls from
> atomic context even if I can't pinpoint one right now.
>
> I guess I can switch everything to sleeping version, and worry about
> atomic context when such a client gets proposed?

Yes, usually at that point the caller can be changed to use
a threaded IRQ or similar.

      Arnd


From krzk at kernel.org  Fri Dec  6 05:04:15 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 14:04:15 +0100
Subject: [PATCH v5 15/20] dt-bindings: clock: imx8m-clock: support spread
 spectrum clocking
In-Reply-To: <20241205111939.1796244-16-dario.binacchi@amarulasolutions.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
 <20241205111939.1796244-16-dario.binacchi@amarulasolutions.com>
Message-ID: <gbymcmoya7dfmedq4nkopqpswh63d2ujxl2elc2x7x325b75bu@anp36sdya43v>

On Thu, Dec 05, 2024 at 12:17:50PM +0100, Dario Binacchi wrote:
> The patch adds the DT bindings for enabling and tuning spread spectrum
> clocking generation.
> 
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> 
> ---
> 
> (no changes since v4)
> 
> Changes in v4:
> - Drop "fsl,ssc-clocks" property. The other added properties now refer
>   to the clock list.
> - Updated minItems and maxItems of
>   - clocks
>   - clock-names
>   - fsl,ssc-modfreq-hz
>   - fsl,ssc-modrate-percent
>   - fsl,ssc-modmethod
> - Updated the dts examples
> 
> Changes in v3:
> - Added in v3
> - The dt-bindings have been moved from fsl,imx8m-anatop.yaml to
>   imx8m-clock.yaml. The anatop device (fsl,imx8m-anatop.yaml) is
>   indeed more or less a syscon, so it represents a memory area
>   accessible by ccm (imx8m-clock.yaml) to setup the PLLs.
> 
> Changes in v2:
> - Add "allOf:" and place it after "required:" block, like in the
>   example schema.
> - Move the properties definition to the top-level.
> - Drop unit types as requested by the "make dt_binding_check" command.
> 
>  .../bindings/clock/imx8m-clock.yaml           | 77 +++++++++++++++++--
>  1 file changed, 71 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
> index c643d4a81478..83036f6d2274 100644
> --- a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
> +++ b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
> @@ -29,12 +29,12 @@ properties:
>      maxItems: 2
>  
>    clocks:
> -    minItems: 6
> -    maxItems: 7
> +    minItems: 7
> +    maxItems: 10

ABI break without mentioning, without any explanation in the commit msg.

>  
>    clock-names:
> -    minItems: 6
> -    maxItems: 7
> +    minItems: 7
> +    maxItems: 10
>  
>    '#clock-cells':
>      const: 1
> @@ -43,6 +43,34 @@ properties:
>        ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8m-clock.h
>        for the full list of i.MX8M clock IDs.
>  
> +  fsl,ssc-modfreq-hz:
> +    description:
> +      The values of modulation frequency (Hz unit) for each clock
> +      supporting spread spectrum.
> +    minItems: 7
> +    maxItems: 10

Why all cloks receive now spread spectrum? I had impression - and all
your previous versions were doing this - that you have only three or
four clocks with SSC.

Do existing clocks 1-6 support SSC?

> +
> +  fsl,ssc-modrate-percent:
> +    description:
> +      The percentage values of modulation rate for each clock
> +      supporting spread spectrum.
> +    minItems: 7
> +    maxItems: 10
> +
> +  fsl,ssc-modmethod:
> +    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
> +    description:
> +      The modulation techniques for each clock supporting spread
> +      spectrum.
> +    minItems: 7
> +    maxItems: 10
> +    items:
> +      enum:
> +        - ""

Drop "", not sure why do you need it.

> +        - down-spread
> +        - up-spread
> +        - center-spread
> +
>  required:
>    - compatible
>    - reg
> @@ -76,6 +104,10 @@ allOf:
>              - const: clk_ext2
>              - const: clk_ext3
>              - const: clk_ext4
> +        fsl,ssc-modfreq-hz: false
> +        fsl,ssc-modrate-percent: false
> +        fsl,ssc-modmethod: false
> +
>      else:
>        properties:
>          clocks:
> @@ -86,6 +118,10 @@ allOf:
>              - description: ext2 clock input
>              - description: ext3 clock input
>              - description: ext4 clock input
> +            - description: audio1 PLL input
> +            - description: audio2 PLL input
> +            - description: dram PLL input
> +            - description: video PLL input

Also ABI break....

Best regards,
Krzysztof



From mhklinux at outlook.com  Fri Dec  6 05:05:56 2024
From: mhklinux at outlook.com (Michael Kelley)
Date: Fri, 6 Dec 2024 13:05:56 +0000
Subject: [RFC PATCH v1 00/57] Boot-time page size selection for arm64
In-Reply-To: <bd4a30ca-6725-4c78-94ba-03581700bdcc@arm.com>
References: <20241014105514.3206191-1-ryan.roberts@arm.com>
 <20241017142752.17f2c816@mordecai.tesarici.cz>
 <aa9a7118-3067-448e-aa34-bbc148c921a2@arm.com>
 <20241205182008.2b36476a@mordecai.tesarici.cz>
 <SN6PR02MB41571E0BD384C44C46127B49D4302@SN6PR02MB4157.namprd02.prod.outlook.com>
 <20241206085026.32c89a03@mordecai.tesarici.cz>
 <bd4a30ca-6725-4c78-94ba-03581700bdcc@arm.com>
Message-ID: <BN7PR02MB4148CBF5299294AB8170D12ED4312@BN7PR02MB4148.namprd02.prod.outlook.com>

From: Ryan Roberts <ryan.roberts at arm.com> Sent: Friday, December 6, 2024 2:26 AM
> 
> On 06/12/2024 07:50, Petr Tesarik wrote:
> > On Thu, 5 Dec 2024 18:52:35 +0000
> > Michael Kelley <mhklinux at outlook.com> wrote:
> >
> >> From: Petr Tesarik <ptesarik at suse.com> Sent: Thursday, December 5, 2024 9:20 AM
> >>>
> >>> Hi Ryan,
> >>>
> >>> On Thu, 17 Oct 2024 13:32:43 +0100
> >>> Ryan Roberts <ryan.roberts at arm.com> wrote:
> >>>
> >>>> On 17/10/2024 13:27, Petr Tesarik wrote:
> >>>>> On Mon, 14 Oct 2024 11:55:11 +0100
> >>>>> Ryan Roberts <ryan.roberts at arm.com> wrote:
> >>>>>
> >>>>>> [...]
> >>>>>> The series is arranged as follows:
> >>>>>>
> >>>>>>   - patch 1:	   Add macros required for converting non-arch code to support
> >>>>>>   		   boot-time page size selection
> >>>>>>   - patches 2-36:  Remove PAGE_SIZE compile-time constant assumption from all
> >>>>>>   		   non-arch code
> >>>>>
> >>>>> I have just tried to recompile the openSUSE kernel with these patches
> >>>>> applied, and I'm running into this:
> >>>>>
> >>>>>   CC      arch/arm64/hyperv/hv_core.o
> >>>>> In file included from ../arch/arm64/hyperv/hv_core.c:14:0:
> >>>>> ../include/linux/hyperv.h:158:5: error: variably modified 'reserved2' at file scope
> >>>>>   u8 reserved2[PAGE_SIZE - 68];
> >>>>>      ^~~~~~~~~
> >>>>>
> >>>>> It looks like one more place which needs a patch, right?
> >>>>
> >>>> As mentioned in the cover letter, so far I've only converted enough to get the
> >>>> defconfig *image* building (i.e. no modules). If you are compiling a different
> >>>> config or compiling the modules for defconfig, you will likely run into these
> >>>> types of issues.
> >>>>
> >>>> That said, I do have some patches to fix Hyper-V, which Michael Kelley was kind
> >>>> enough to send me.
> >>>>
> >>>> I understand that Suse might be able to help with wider performance testing - if
> >>>> that's the reason you are trying to compile, you could send me your config and
> >>>> I'll start working on fixing up other drivers?
> >>>
> >>> This project was de-prioritised for some time, but I have just returned
> >>> to it, and one of our test systems uses a Mellanox 5 NIC, which did not build.
> 
> No problem - I appreciate all the time you have spent on it so far!
> 
> >>>
> >>> If you still have time to work on your patch series, please, can you
> >>> look into enabling MLX5_CORE_EN?
> 
> I've also had other things that have been taking up my time. I'm planning to get
> back to this series properly after Christmas and convert all the remaining
> module code. I'm hoping that Michael's patch will solve your problem for now?
> 
> >>>
> >>> Oh, and have you rebased the series to 6.12 yet?
> 
> Afraid the latest I have at the moment is based on v6.12-rc3. It also includes
> all the changes from the review feedback:
> 
> https://gitlab.arm.com/linux-arm/linux-rr/-/tree/features/boot-time-page-size-v2-wip
> 
> >>>
> >>
> >> FWIW, here's what I hacked together to compile and run the mlx5 driver in
> >> a Hyper-V VM.  This was against a 6.11 kernel code base.
> >
> > Wow! Thank you, Michael. I'll give it a try.
> 
> Yes, thanks, Michael - I'll take a look at this and integrate into my tree after
> Christmas.
> 

To be clear, you probably do *not* want to integrate my changes into your tree.
They are a hack, and I'm not sure what approach the mlx driver folks will want to
take. But they made the Mellanox CX-5 NIC functional for my purposes in testing
variable page sizes.

Michael


From krzk at kernel.org  Fri Dec  6 05:07:24 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 14:07:24 +0100
Subject: [PATCH v4 0/4] Add minimal Samsung Galaxy S20 Series board,
 SM-G981B and SM-G980F support
In-Reply-To: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
References: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <dpby4tvamvsk6437kngv4d6diq6pqh5fquptwy7p5325e6hb3j@ot6eaurn4bun>

On Tue, Dec 03, 2024 at 08:03:22AM +0000, Umer Uddin wrote:
> Hi folks,
> 
> This series adds initial support for the Samsung Galaxy S20 Series and also
> initial board support for the Samsung Galaxy S20 5G (SM-G981B)
> codenamed x1s.
> 
> The S20 Series feature a lot of similarities in their configuration
> and internally Samsung named the common devicetrees in their
> downstream kernel 'hubble', please note hubble excludes the
> S20 FE series and Note20 series. To accomodate this, I've
> now named the device tree common's matching the codenames
> (x1s-common).
> The device trees have been tested with dtbs_check W=1
> and results in no warnings.
> 
> This initial bringup consists of:
>  * pinctrl
>  * gpio-keys
>  * simple-framebuffer
> 
> This is enough to reach a shell in an initramfs. More platform support
> will be added in the future.
> 
> Just like SM-N981B, the preferred way to boot the upstream kernel is
> by using a shim bootloader, called uniLoader [1], which works around
> some issues with the stock, non-replacable Samsung S-LK bootloader.
> For example, the stock bootloader leaves the decon trigger control
> unset, which causes the framebuffer not to refresh.
> 
> Device functionality depends on the patch series from Igor Belwon:
> "Add minimal Exynos990 SoC and SM-N981B support"
> 
> [1] https://github.com/ivoszbg/uniLoader
> 
> Changes in v4:
>  - Rebase from krzk's kernel tree to accomodate
>    for the merge of r8s
>  - Rename exynos990-hubble-common.dtsi
>    to exynos990-x1s-common.dtsi


What else happened here?

b4 diff '20241203080327.4751-2-umer.uddin at mentallysanemainliners.org'
Checking for older revisions
Grabbing search results from lore.kernel.org
  Added from v3: 9 patches
---
Analyzing 29 messages in the thread
WARNING: duplicate messages found at index 3
   Subject 1: arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
   Subject 2: arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
  2 is not a reply... assume additional patch
WARNING: duplicate messages found at index 4
   Subject 1: arm64: dts: exynos: Add initial support for Samsung Galaxy S20 (x1slte)
   Subject 2: arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
  2 is not a reply... assume additional patch
WARNING: duplicate messages found at index 1
   Subject 1: dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
   Subject 2: dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
  2 is not a reply... assume additional patch
WARNING: duplicate messages found at index 2
   Subject 1: arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series boards (hubble)
   Subject 2: dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
  2 is not a reply... assume additional patch
Preparing fake-am for v3: dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
ERROR: v3 series incomplete; unable to create a fake-am range

Working with these series is a pain.

Best regards,
Krzysztof



From David.Laight at ACULAB.COM  Fri Dec  6 05:07:59 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 13:07:59 +0000
Subject: [PATCH net] Fix clamp() of ip_vs_conn_tab on small memory
 systems.
In-Reply-To: <5ec10e7c-d050-dab8-1f1b-d0ca2d922eef@ssi.bg>
References: <33893212b1cc4a418cec09aeeed0a9fc@AcuMS.aculab.com>
 <5ec10e7c-d050-dab8-1f1b-d0ca2d922eef@ssi.bg>
Message-ID: <2a91ee407ed64d24b82e5fc665971add@AcuMS.aculab.com>

From: Julian Anastasov
> Sent: 06 December 2024 12:19
> 
> On Fri, 6 Dec 2024, David Laight wrote:
> 
> > The intention of the code seems to be that the minimum table
> > size should be 256 (1 << min).
> > However the code uses max = clamp(20, 5, max_avail) which implies
> 
> 	Actually, it tries to reduce max=20 (max possible) below
> max_avail: [8 .. max_avail]. Not sure what 5 is here...

Me mistyping values between two windows :-)

Well min(max, max_avail) would be the reduced upper limit.
But you'd still fall foul of the compiler propagating the 'n > 1'
check in order_base_2() further down the function.

> > the author thought max_avail could be less than 5.
> > But clamp(val, min, max) is only well defined for max >= min.
> > If max < min whether is returns min or max depends on the order of
> > the comparisons.
> 
> 	Looks like max_avail goes below 8 ? What value you see
> for such small system?

I'm not, but clearly you thought the value could be small otherwise
the code would only have a 'max' limit.
(Apart from a 'sanity' min of maybe 2 to stop the code breaking.)

> 
> > Change to clamp(max_avail, 5, 20) which has the expected behaviour.
> 
> 	It should be clamp(max_avail, 8, 20)
> 
> >
> > Replace the clamp_val() on the line below with clamp().
> > clamp_val() is just 'an accident waiting to happen' and not needed here.
> 
> 	OK
> 
> > Fixes: 4f325e26277b6
> > (Although I actually doubt the code is used on small memory systems.)
> >
> > Detected by compile time checks added to clamp(), specifically:
> > minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
> 
> 	Existing or new check? Does it happen that max_avail
> is a constant, so that a compile check triggers?

Is all stems from order_base_2(totalram_pages()).
order_base_2(n) is 'n > 1 ? ilog2(n - 1) + 1 : 0'.
And the compiler generates two copies of the code that follows
for the 'constant zero' and ilog2() values.
And the 'zero' case compiles clamp(20, 8, 0) which is errored.
Note that it is only executed if totalram_pages() is zero,
but it is always compiled 'just in case'.

> 
> >
> > Signed-off-by: David Laight <david.laight at aculab.com>
> 
> 	The code below looks ok to me but can you change the
> comments above to more correctly specify the values and if the
> problem is that max_avail goes below 8 (min).
> 
> > ---
> >  net/netfilter/ipvs/ip_vs_conn.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
> > index 98d7dbe3d787..c0289f83f96d 100644
> > --- a/net/netfilter/ipvs/ip_vs_conn.c
> > +++ b/net/netfilter/ipvs/ip_vs_conn.c
> > @@ -1495,8 +1495,8 @@ int __init ip_vs_conn_init(void)
> >  	max_avail -= 2;		/* ~4 in hash row */
> >  	max_avail -= 1;		/* IPVS up to 1/2 of mem */
> >  	max_avail -= order_base_2(sizeof(struct ip_vs_conn));
> 
> 	More likely we can additionally clamp max_avail here:
> 
> 	max_avail = max(min, max_avail);
> 
> 	But your solution solves the problem with less lines.

And less code in the path that is actually executed.

	David

> 
> > -	max = clamp(max, min, max_avail);
> > -	ip_vs_conn_tab_bits = clamp_val(ip_vs_conn_tab_bits, min, max);
> > +	max = clamp(max_avail, min, max);
> > +	ip_vs_conn_tab_bits = clamp(ip_vs_conn_tab_bits, min, max);
> >  	ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
> >  	ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
> >
> > --
> > 2.17.1
> 
> Regards
> 
> --
> Julian Anastasov <ja at ssi.bg>

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From krzk at kernel.org  Fri Dec  6 05:11:28 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 14:11:28 +0100
Subject: [PATCH v4 3/4] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S20 5G (x1s)
In-Reply-To: <20241203080327.4751-4-umer.uddin@mentallysanemainliners.org>
References: <20241203080327.4751-1-umer.uddin@mentallysanemainliners.org>
 <20241203080327.4751-4-umer.uddin@mentallysanemainliners.org>
Message-ID: <5e3e43eb-3afc-486e-aa9a-4c1074fd30b8@kernel.org>

On 03/12/2024 09:03, Umer Uddin wrote:
>  arch/arm64/boot/dts/exynos/Makefile          |  1 +
>  arch/arm64/boot/dts/exynos/exynos990-x1s.dts | 28 ++++++++++++++++++++
>  2 files changed, 29 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts
> 
> diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
> index 948a2c6cb..6959acfbb 100644
> --- a/arch/arm64/boot/dts/exynos/Makefile
> +++ b/arch/arm64/boot/dts/exynos/Makefile
> @@ -9,6 +9,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
>  	exynos850-e850-96.dtb		\
>  	exynos8895-dreamlte.dtb		\
>  	exynos990-c1s.dtb		\
> +	exynos990-x1s.dtb		\
>  	exynos990-r8s.dtb               \

Keep the order (sorted).


Best regards,
Krzysztof


From linux at fw-web.de  Fri Dec  6 05:23:59 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Fri,  6 Dec 2024 14:23:59 +0100
Subject: [PATCH v4] arm64: dts: mt7986: add overlay for SATA power socket on BPI-R3
Message-ID: <20241206132401.70259-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Bananapi R3 has a Power socket entended for using external SATA drives.
This Socket is off by default but can be switched with gpio 8.

Add an overlay to activate it.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
v4:
- rebased on 6.13-rc1 without the full-dtb patch
v3:
- make sata overlay better readable
v2:
- rebase on the patch "add dtbs with applied overlays for bpi-r3"
- add sata-overlay to the full dtbs
---
 arch/arm64/boot/dts/mediatek/Makefile         |  1 +
 .../mt7986a-bananapi-bpi-r3-sata.dtso         | 35 +++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sata.dtso

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 8fd7b2bb7a15..d844c4ce9863 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -17,6 +17,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-mini.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc.dtbo
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sata.dtbo
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sata.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sata.dtso
new file mode 100644
index 000000000000..17659545470e
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sata.dtso
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Frank Wunderlich <frank-w at public-files.de>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+
+	reg_sata12v: regulator-sata12v {
+		compatible = "regulator-fixed";
+		regulator-name = "sata12v";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		gpio = <&pio 8 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	reg_sata5v: regulator-sata5v {
+		compatible = "regulator-fixed";
+		regulator-name = "sata5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		vin-supply = <&reg_sata12v>;
+	};
+
+};
+
-- 
2.43.0



From krzk at kernel.org  Fri Dec  6 05:28:11 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 6 Dec 2024 14:28:11 +0100
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <ce757b8e-4e6c-4ba9-9483-b57e6e230fdf@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-3-tudor.ambarus@linaro.org>
 <ce757b8e-4e6c-4ba9-9483-b57e6e230fdf@linaro.org>
Message-ID: <vxqi23hxw7bmtfs5wk3u7szganpv5aa74b26xrvpmbehkltodw@dpum7zrxdz44>

On Fri, Dec 06, 2024 at 12:39:56AM +0100, Daniel Lezcano wrote:
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +
> > +config EXYNOS_ACPM_PROTOCOL
> > +	tristate "Exynos Alive Clock and Power Manager (ACPM) Message Protocol"
> 
> Given the importance of this driver where a lot of PM services rely on, does
> it really make sense to allow it as a module ?
> 
> Some PM services may be needed very early in the boot process
> 

If it works as module e.g. on Android, it is beneficial. I think the
platform was booting fine without it, at least to some shell, so I can
imagine this can be loaded a bit later.

Best regards,
Krzysztof



From parker at finest.io  Fri Dec  6 05:42:03 2024
From: parker at finest.io (Parker Newman)
Date: Fri, 6 Dec 2024 08:42:03 -0500
Subject: [PATCH v1 1/1] net: stmmac: dwmac-tegra: Read iommu stream id
 from device tree
In-Reply-To: <uad6id6omswjm7e4eqwd75c52sy5pddtxru3bcuxlukhecvj4u@klzgrws24r2q>
References: <ed2ec1c2-65c7-4768-99f1-987e5fa39a54@redhat.com>
	<20241115135940.5f898781.parker@finest.io>
	<bb52bdc1-df2e-493d-a58f-df3143715150@lunn.ch>
	<20241118084400.35f4697a.parker@finest.io>
	<984a8471-7e49-4549-9d8a-48e1a29950f6@lunn.ch>
	<20241119131336.371af397.parker@finest.io>
	<f00bccd3-62d5-46a9-b448-051894267c7a@lunn.ch>
	<20241119144729.72e048a5.parker@finest.io>
	<mpgilwqb5zg5kb4n7r6zwbhy4uutdh6rq5s2yc6ndhcj6gqgri@qkfr4qwjj3ym>
	<20241204115317.008f497c.parker@finest.io>
	<uad6id6omswjm7e4eqwd75c52sy5pddtxru3bcuxlukhecvj4u@klzgrws24r2q>
Message-ID: <20241206084203.2502ab95.parker@finest.io>

On Wed, 4 Dec 2024 19:06:30 +0100
Thierry Reding <thierry.reding at gmail.com> wrote:

> On Wed, Dec 04, 2024 at 11:53:17AM -0500, Parker Newman wrote:
> > On Wed, 4 Dec 2024 17:23:53 +0100
> > Thierry Reding <thierry.reding at gmail.com> wrote:
> >
> > > On Tue, Nov 19, 2024 at 02:47:29PM -0500, Parker Newman wrote:
> > > > On Tue, 19 Nov 2024 20:18:00 +0100
> > > > Andrew Lunn <andrew at lunn.ch> wrote:
> > > >
> > > > > > I think there is some confusion here. I will try to summarize:
> > > > > > - Ihe iommu is supported by the Tegra SOC.
> > > > > > - The way the mgbe driver is written the iommu DT property is REQUIRED.
> > > > >
> > > > > If it is required, please also include a patch to
> > > > > nvidia,tegra234-mgbe.yaml and make iommus required.
> > > > >
> > > >
> > > > I will add this when I submit a v2 of the patch.
> > > >
> > > > > > - "iommus" is a SOC DT property and is defined in tegra234.dtsi.
> > > > > > - The mgbe device tree nodes in tegra234.dtsi DO have the iommus property.
> > > > > > - There are no device tree changes required to to make this patch work.
> > > > > > - This patch works fine with existing device trees.
> > > > > >
> > > > > > I will add the fallback however in case there is changes made to the iommu
> > > > > > subsystem in the future.
> > > > >
> > > > > I would suggest you make iommus a required property and run the tests
> > > > > over the existing .dts files.
> > > > >
> > > > > I looked at the history of tegra234.dtsi. The ethernet nodes were
> > > > > added in:
> > > > >
> > > > > 610cdf3186bc604961bf04851e300deefd318038
> > > > > Author: Thierry Reding <treding at nvidia.com>
> > > > > Date:   Thu Jul 7 09:48:15 2022 +0200
> > > > >
> > > > >     arm64: tegra: Add MGBE nodes on Tegra234
> > > > >
> > > > > and the iommus property is present. So the requires is safe.
> > > > >
> > > > > Please expand the commit message. It is clear from all the questions
> > > > > and backwards and forwards, it does not provide enough details.
> > > > >
> > > >
> > > > I will add more details when I submit V2.
> > > >
> > > > > I just have one open issue. The code has been like this for over 2
> > > > > years. Why has it only now started crashing?
> > > > >
> > > >
> > > > It is rare for Nvidia Jetson users to use the mainline kernel. Nvidia
> > > > provides a custom kernel package with many out of tree drivers including a
> > > > driver for the mgbe controllers.
> > > >
> > > > Also, while the Orin AGX SOC (tegra234) has 4 instances of the mgbe controller,
> > > > the Nvidia Orin AGX devkit only uses mgbe0. Connect Tech has carrier boards
> > > > that use 2 or more of the mgbe controllers which is why we found the bug.
> > >
> > > Correct. Also, this was a really stupid thing that I overlooked. I don't
> > > recall the exact circumstances, but I vaguely recall there had been
> > > discussions about adding the tegra_dev_iommu_get_stream_id() helper
> > > (that this patch uses) around the time that this driver was created. In
> > > the midst of all of this I likely forgot to update the driver after the
> > > discussions had settled.
> > >
> > > Anyway, I agree with the conclusion that we don't need a compatibility
> > > fallback for this, both because it would be actively wrong to do it and
> > > we've had the required IOMMU properties in device tree since the start,
> > > so there can't be any regressions caused by this.
> > >
> > > I don't think it's necessary to make the iommus property required,
> > > though, because there's technically no requirement for these devices to
> > > be attached to an IOMMU. They usually are, and it's better if they are,
> > > but they should be able to work correctly without an IOMMU.
> > >
> > Thanks for confirming from the Nvidia side! I wasn't sure if they would
> > work without the iommu. That said, if you did NOT want to use the iommu
> > and removed the iommu DT property then the probe will fail after my patch.
> > Would we not need a guard around the writes to MGBE_WRAP_AXI_ASID0_CTRL as well?
>
> Well... frankly, I don't know. There's an override in the memory
> controller which we set when a device is attached to an IOMMU. That's
> usually how the stream ID is programmed. If we don't do that it will
> typically default to a special passthrough stream ID (technically the
> firmware can lock down those register and force them to a specific
> stream ID all the time). I'm not sure what exactly the impact is of
> these ASID registers (there's a few other instances where those are
> needed). They are required if you want to use the IOMMU, but I don't
> know what their meaning is if the IOMMU is not enabled.
>
> There's also different cases: the IOMMU can be disabled altogether, in
> which case no page tables and such exist for any device and no
> translation should happen whatsoever. But there's also the case where an
> IOMMU is enabled, but certain devices shouldn't attach to them. I should
> make it very clear that both of these are not recommended setups and I
> don't know if they'll work. And they are mostly untested. I've been
> meaning, but haven't found the time, to test some of these cases.
>

Yes I agree, all of those situations are very niche and not recommended for
a Tegra platform that should always have the iommu enabled anyways. Adding an
iommu bypass would probably be outside of the scope of this patch.

I will not add a patch marking the iommu as required in the device tree
bindings when I submit v2 unless anyone else feels different.

Thanks again,
Parker




From towinchenmi at gmail.com  Fri Dec  6 05:49:18 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Fri,  6 Dec 2024 21:49:18 +0800
Subject: [PATCH] arm64: dts: apple: Split s8000/s8003 SoC DTS files
Message-ID: <20241206135051.56049-1-towinchenmi@gmail.com>

Despite what the code comments said, the DTS files were not split properly.
Since these two SoCs are now known to have minor differences like in
latencies for cpufreq state transistions, split the DTS files now.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---

Hi,

I am preparing multiple series for cpufreq and backlight, both of which
modifies the Apple A9 DTS files. I am sending this first to make it
easier to handle conflicts.

This patch depends on PMGR nodes for Apple A7-A11 SoCs[1] since it
also renames the pmgr bindings files.

[1]: https://lore.kernel.org/asahi/20241203050640.109378-1-towinchenmi at gmail.com/T

Nick Chan

 .../{s8000-pmgr.dtsi => s800-0-3-pmgr.dtsi}   |   0
 arch/arm64/boot/dts/apple/s800-0-3.dtsi       | 162 ++++++++++++++++++
 arch/arm64/boot/dts/apple/s8000.dtsi          | 155 +----------------
 arch/arm64/boot/dts/apple/s8003.dtsi          |  10 +-
 4 files changed, 168 insertions(+), 159 deletions(-)
 rename arch/arm64/boot/dts/apple/{s8000-pmgr.dtsi => s800-0-3-pmgr.dtsi} (100%)
 create mode 100644 arch/arm64/boot/dts/apple/s800-0-3.dtsi

diff --git a/arch/arm64/boot/dts/apple/s8000-pmgr.dtsi b/arch/arm64/boot/dts/apple/s800-0-3-pmgr.dtsi
similarity index 100%
rename from arch/arm64/boot/dts/apple/s8000-pmgr.dtsi
rename to arch/arm64/boot/dts/apple/s800-0-3-pmgr.dtsi
diff --git a/arch/arm64/boot/dts/apple/s800-0-3.dtsi b/arch/arm64/boot/dts/apple/s800-0-3.dtsi
new file mode 100644
index 000000000000..1e0b8f631ac0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s800-0-3.dtsi
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple S8000/S8003 "A9" SoC
+ *
+ * This file contains parts common to both variants of A9
+ *
+ * Copyright (c) 2022, Konrad Dybcio <konradybcio at kernel.org>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/apple.h>
+
+/ {
+	interrupt-parent = <&aic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clkref: clock-ref {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "clkref";
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			compatible = "apple,twister";
+			reg = <0x0 0x0>;
+			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+
+		cpu1: cpu at 1 {
+			compatible = "apple,twister";
+			reg = <0x0 0x1>;
+			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		nonposted-mmio;
+		ranges;
+
+		serial0: serial at 20a0c0000 {
+			compatible = "apple,s5l-uart";
+			reg = <0x2 0x0a0c0000 0x0 0x4000>;
+			reg-io-width = <4>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 192 IRQ_TYPE_LEVEL_HIGH>;
+			/* Use the bootloader-enabled clocks for now. */
+			clocks = <&clkref>, <&clkref>;
+			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
+			status = "disabled";
+		};
+
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
+		aic: interrupt-controller at 20e100000 {
+			compatible = "apple,s8000-aic", "apple,aic";
+			reg = <0x2 0x0e100000 0x0 0x100000>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			power-domains = <&ps_aic>;
+		};
+
+		pinctrl_ap: pinctrl at 20f100000 {
+			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_ap 0 0 208>;
+			apple,npins = <208>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 48 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_aop: pinctrl at 2100f0000 {
+			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_aop 0 0 42>;
+			apple,npins = <42>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 113 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 114 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 115 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 118 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 119 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
+		wdt: watchdog at 2102b0000 {
+			compatible = "apple,s8000-wdt", "apple,wdt";
+			reg = <0x2 0x102b0000 0x0 0x4000>;
+			clocks = <&clkref>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 4 IRQ_TYPE_LEVEL_HIGH>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&aic>;
+		interrupt-names = "phys", "virt";
+		/* Note that A9 doesn't actually have a hypervisor (EL2 is not implemented). */
+		interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>,
+			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
+
+#include "s800-0-3-pmgr.dtsi"
+
+/*
+ * The A9 was made by two separate fabs on two different process
+ * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
+ * the S8003 (APL1022) on 16nm. There are some minor differences
+ * such as timing in cpufreq state transistions.
+ */
diff --git a/arch/arm64/boot/dts/apple/s8000.dtsi b/arch/arm64/boot/dts/apple/s8000.dtsi
index 84d6b4939ac4..c7e39abda7e1 100644
--- a/arch/arm64/boot/dts/apple/s8000.dtsi
+++ b/arch/arm64/boot/dts/apple/s8000.dtsi
@@ -7,160 +7,11 @@
  * Copyright (c) 2022, Konrad Dybcio <konradybcio at kernel.org>
  */
 
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/interrupt-controller/apple-aic.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/pinctrl/apple.h>
-
-/ {
-	interrupt-parent = <&aic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	clkref: clock-ref {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <24000000>;
-		clock-output-names = "clkref";
-	};
-
-	cpus {
-		#address-cells = <2>;
-		#size-cells = <0>;
-
-		cpu0: cpu at 0 {
-			compatible = "apple,twister";
-			reg = <0x0 0x0>;
-			cpu-release-addr = <0 0>; /* To be filled in by loader */
-			enable-method = "spin-table";
-			device_type = "cpu";
-		};
-
-		cpu1: cpu at 1 {
-			compatible = "apple,twister";
-			reg = <0x0 0x1>;
-			cpu-release-addr = <0 0>; /* To be filled in by loader */
-			enable-method = "spin-table";
-			device_type = "cpu";
-		};
-	};
-
-	soc {
-		compatible = "simple-bus";
-		#address-cells = <2>;
-		#size-cells = <2>;
-		nonposted-mmio;
-		ranges;
-
-		serial0: serial at 20a0c0000 {
-			compatible = "apple,s5l-uart";
-			reg = <0x2 0x0a0c0000 0x0 0x4000>;
-			reg-io-width = <4>;
-			interrupt-parent = <&aic>;
-			interrupts = <AIC_IRQ 192 IRQ_TYPE_LEVEL_HIGH>;
-			/* Use the bootloader-enabled clocks for now. */
-			clocks = <&clkref>, <&clkref>;
-			clock-names = "uart", "clk_uart_baud0";
-			power-domains = <&ps_uart0>;
-			status = "disabled";
-		};
-
-		pmgr: power-management at 20e000000 {
-			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			reg = <0x2 0xe000000 0 0x8c000>;
-		};
-
-		aic: interrupt-controller at 20e100000 {
-			compatible = "apple,s8000-aic", "apple,aic";
-			reg = <0x2 0x0e100000 0x0 0x100000>;
-			#interrupt-cells = <3>;
-			interrupt-controller;
-			power-domains = <&ps_aic>;
-		};
-
-		pinctrl_ap: pinctrl at 20f100000 {
-			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
-			reg = <0x2 0x0f100000 0x0 0x100000>;
-			power-domains = <&ps_gpio>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio-ranges = <&pinctrl_ap 0 0 208>;
-			apple,npins = <208>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupt-parent = <&aic>;
-			interrupts = <AIC_IRQ 42 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 43 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 44 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 45 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 46 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 47 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 48 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
-		pinctrl_aop: pinctrl at 2100f0000 {
-			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
-			reg = <0x2 0x100f0000 0x0 0x100000>;
-			power-domains = <&ps_aop_gpio>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio-ranges = <&pinctrl_aop 0 0 42>;
-			apple,npins = <42>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupt-parent = <&aic>;
-			interrupts = <AIC_IRQ 113 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 114 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 115 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 116 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 117 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 118 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 119 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
-		pmgr_mini: power-management at 210200000 {
-			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			reg = <0x2 0x10200000 0 0x84000>;
-		};
-
-		wdt: watchdog at 2102b0000 {
-			compatible = "apple,s8000-wdt", "apple,wdt";
-			reg = <0x2 0x102b0000 0x0 0x4000>;
-			clocks = <&clkref>;
-			interrupt-parent = <&aic>;
-			interrupts = <AIC_IRQ 4 IRQ_TYPE_LEVEL_HIGH>;
-		};
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupt-parent = <&aic>;
-		interrupt-names = "phys", "virt";
-		/* Note that A9 doesn't actually have a hypervisor (EL2 is not implemented). */
-		interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>,
-			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
-	};
-};
-
-#include "s8000-pmgr.dtsi"
+#include "s800-0-3.dtsi"
 
 /*
  * The A9 was made by two separate fabs on two different process
  * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
- * the S8003 (APL1022) on 16nm. While they are seemingly the same,
- * they do have distinct part numbers and devices using them have
- * distinct model names. There are currently no known differences
- * between these as far as Linux is concerned, but let's keep things
- * structured properly to make it easier to alter the behaviour of
- * one of the chips if need be.
+ * the S8003 (APL1022) on 16nm. There are some minor differences
+ * such as timing in cpufreq state transistions.
  */
diff --git a/arch/arm64/boot/dts/apple/s8003.dtsi b/arch/arm64/boot/dts/apple/s8003.dtsi
index 7e4ad4f7e499..807e3452f8a7 100644
--- a/arch/arm64/boot/dts/apple/s8003.dtsi
+++ b/arch/arm64/boot/dts/apple/s8003.dtsi
@@ -7,15 +7,11 @@
  * Copyright (c) 2022, Konrad Dybcio <konradybcio at kernel.org>
  */
 
-#include "s8000.dtsi"
+#include "s800-0-3.dtsi"
 
 /*
  * The A9 was made by two separate fabs on two different process
  * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
- * the S8003 (APL1022) on 16nm. While they are seemingly the same,
- * they do have distinct part numbers and devices using them have
- * distinct model names. There are currently no known differences
- * between these as far as Linux is concerned, but let's keep things
- * structured properly to make it easier to alter the behaviour of
- * one of the chips if need be.
+ * the S8003 (APL1022) on 16nm. There are some minor differences
+ * such as timing in cpufreq state transistions.
  */

base-commit: d47006c7111b57dd2377d072681935aebb9dde25
-- 
2.47.1



From heiko at sntech.de  Fri Dec  6 05:53:12 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 06 Dec 2024 14:53:12 +0100
Subject: [PATCH 2/2] phy: phy-rockchip-samsung-hdptx: Don't use dt aliases to
 determine phy-id
In-Reply-To: <87273a36-07f9-4224-bfff-63e905be9b0a@collabora.com>
References: <20241206103401.1780416-1-heiko@sntech.de>
 <20241206103401.1780416-3-heiko@sntech.de>
 <87273a36-07f9-4224-bfff-63e905be9b0a@collabora.com>
Message-ID: <11259672.BaYr0rKQ5T@diego>

Hi Cristian,

Am Freitag, 6. Dezember 2024, 12:26:35 CET schrieb Cristian Ciocaltea:
> On 12/6/24 12:34 PM, Heiko Stuebner wrote:
> > From: Heiko Stuebner <heiko.stuebner at cherry.de>
> > 
> > The phy needs to know its identity in the system (phy0 or phy1 on rk3588)
> > for some actions and the driver currently contains code abusing of_alias
> > for that.
> > 
> > Devicetree aliases are always optional and should not be used for core
> > device functionality, so instead keep a list of phys on a soc in the
> > of_device_data and find the phy-id by comparing against the mapped
> > register-base.
> > 
> > Fixes: c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock provider support")
> > Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
> > ---
> >  .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 50 ++++++++++++++++---
> >  1 file changed, 44 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> > index c5c64c209e96..b137f8c4d157 100644
> > --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> > +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> > @@ -385,11 +385,22 @@ enum rk_hdptx_reset {
> >  	RST_MAX
> >  };
> 
> [...]
> 
> > +
> > +	/* find the phy-id from the io address */
> > +	hdptx->phy_id = -ENODEV;
> > +	for (id = 0; id < hdptx->cfgs->num_phys; id++) {
> > +		if (res->start == hdptx->cfgs->phy_ids[id]) {
> > +			hdptx->phy_id = id;
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (hdptx->phy_id < 0)
> > +		return dev_err_probe(dev, -ENODEV, "no matching device found\n");
> 
> Maybe we could simply fallback to assume phy1 doesn't exist in this
> case, which avoids the need to provide a match data with a single entry.

Personally I'm a fan of consistent behaviour, not things working
accidentially ;-) . See the usbdp phy for example, also declaring just
one phy using the same mechanism.

Also I really don't trust the hdptxphy-grf being stable over time.
Rockchip engineers always move bts around in those, so there will be a
need for platform-data at some point anyway.


> Regardless,
> 
> Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>

thanks :-)

Heiko




From beata.michalska at arm.com  Fri Dec  6 05:55:57 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri,  6 Dec 2024 13:55:57 +0000
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq sysfs entry
In-Reply-To: <20241206135600.4083965-1-beata.michalska@arm.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
Message-ID: <20241206135600.4083965-2-beata.michalska@arm.com>

Currently the CPUFreq core exposes two sysfs attributes that can be used
to query current frequency of a given CPU(s): namely cpuinfo_cur_freq
and scaling_cur_freq. Both provide slightly different view on the
subject and they do come with their own drawbacks.

cpuinfo_cur_freq provides higher precision though at a cost of being
rather expensive. Moreover, the information retrieved via this attribute
is somewhat short lived as frequency can change at any point of time
making it difficult to reason from.

scaling_cur_freq, on the other hand, tends to be less accurate but then
the actual level of precision (and source of information) varies between
architectures making it a bit ambiguous.

The new attribute, cpuinfo_avg_freq, is intended to provide more stable,
distinct interface, exposing an average frequency of a given CPU(s), as
reported by the hardware, over a time frame spanning no more than a few
milliseconds. As it requires appropriate hardware support, this
interface is optional.

Note that under the hood, the new attribute relies on the information
provided by arch_freq_get_on_cpu, which, up to this point, has been
feeding data for scaling_cur_freq attribute, being the source of
ambiguity when it comes to interpretation. This has been amended by
restoring the intended behavior for scaling_cur_freq, with a new
dedicated config option to maintain status quo for those, who may need
it.

CC: Jonathan Corbet <corbet at lwn.net>
CC: Thomas Gleixner <tglx at linutronix.de>
CC: Ingo Molnar <mingo at redhat.com>
CC: Borislav Petkov <bp at alien8.de>
CC: Dave Hansen <dave.hansen at linux.intel.com>
CC: H. Peter Anvin <hpa at zytor.com>
CC: Phil Auld <pauld at redhat.com>
CC: x86 at kernel.org
CC: linux-doc at vger.kernel.org
Signed-off-by: Beata Michalska <beata.michalska at arm.com>
---
 Documentation/admin-guide/pm/cpufreq.rst | 16 ++++++++++-
 arch/x86/kernel/cpu/aperfmperf.c         |  2 +-
 arch/x86/kernel/cpu/proc.c               |  7 +++--
 drivers/cpufreq/Kconfig.x86              | 12 ++++++++
 drivers/cpufreq/cpufreq.c                | 36 +++++++++++++++++++++---
 include/linux/cpufreq.h                  |  2 +-
 6 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst
index fe1be4ad88cb..76f3835afe01 100644
--- a/Documentation/admin-guide/pm/cpufreq.rst
+++ b/Documentation/admin-guide/pm/cpufreq.rst
@@ -248,6 +248,19 @@ are the following:
 	If that frequency cannot be determined, this attribute should not
 	be present.
 
+``cpuinfo_avg_freq``
+        An average frequency (in KHz) of all CPUs belonging to a given policy,
+        derived from a hardware provided feedback and reported on a time frame
+        spanning at most few milliseconds.
+
+        This is expected to be based on the frequency the hardware actually runs
+        at and, as such, might require specialised hardware support (such as AMU
+        extension on ARM). If one cannot be determined, this attribute should
+        not be present.
+
+        Note, that failed attempt to retrieve current frequency for a given
+        CPU(s) will result in an appropriate error.
+
 ``cpuinfo_max_freq``
 	Maximum possible operating frequency the CPUs belonging to this policy
 	can run at (in kHz).
@@ -293,7 +306,8 @@ are the following:
 	Some architectures (e.g. ``x86``) may attempt to provide information
 	more precisely reflecting the current CPU frequency through this
 	attribute, but that still may not be the exact current CPU frequency as
-	seen by the hardware at the moment.
+	seen by the hardware at the moment. This behavior though, is only
+	available via c:macro:``CPUFREQ_ARCH_CUR_FREQ`` option.
 
 ``scaling_driver``
 	The scaling driver currently in use.
diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
index 0b69bfbf345d..a00059139ca4 100644
--- a/arch/x86/kernel/cpu/aperfmperf.c
+++ b/arch/x86/kernel/cpu/aperfmperf.c
@@ -413,7 +413,7 @@ void arch_scale_freq_tick(void)
  */
 #define MAX_SAMPLE_AGE	((unsigned long)HZ / 50)
 
-unsigned int arch_freq_get_on_cpu(int cpu)
+int arch_freq_get_on_cpu(int cpu)
 {
 	struct aperfmperf *s = per_cpu_ptr(&cpu_samples, cpu);
 	unsigned int seq, freq;
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index e65fae63660e..34d8fb93fb70 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -86,9 +86,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		seq_printf(m, "microcode\t: 0x%x\n", c->microcode);
 
 	if (cpu_has(c, X86_FEATURE_TSC)) {
-		unsigned int freq = arch_freq_get_on_cpu(cpu);
+		int freq = arch_freq_get_on_cpu(cpu);
 
-		seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 1000));
+		if (freq <= 0)
+			seq_puts(m, "cpu MHz\t\t: Unknown\n");
+		else
+			seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 1000));
 	}
 
 	/* Cache size */
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index 97c2d4f15d76..212e1b9afe21 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -340,3 +340,15 @@ config X86_SPEEDSTEP_RELAXED_CAP_CHECK
 	  option lets the probing code bypass some of those checks if the
 	  parameter "relaxed_check=1" is passed to the module.
 
+config CPUFREQ_ARCH_CUR_FREQ
+	default y
+	bool "Current frequency derived from HW provided feedback"
+	help
+	  This determines whether the scaling_cur_freq sysfs attribute returns
+	  the last requested frequency or a more precise value based on hardware
+	  provided feedback (as architected counters).
+	  Given that a more precise frequency can now be provided via the
+	  cpuinfo_avg_cur_freq attribute, by enabling this option,
+	  scaling_cur_freq maintains the provision of a counter based frequency,
+	  for compatibility reasons.
+
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 04fc786dd2c0..70df2a24437b 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -747,9 +747,14 @@ show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
 show_one(scaling_min_freq, min);
 show_one(scaling_max_freq, max);
 
-__weak unsigned int arch_freq_get_on_cpu(int cpu)
+__weak int arch_freq_get_on_cpu(int cpu)
 {
-	return 0;
+	return -EOPNOTSUPP;
+}
+
+static inline bool cpufreq_avg_freq_supported(struct cpufreq_policy *policy)
+{
+	return arch_freq_get_on_cpu(policy->cpu) != -EOPNOTSUPP;
 }
 
 static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
@@ -757,8 +762,11 @@ static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
 	ssize_t ret;
 	unsigned int freq;
 
-	freq = arch_freq_get_on_cpu(policy->cpu);
-	if (freq)
+	freq = IS_ENABLED(CONFIG_CPUFREQ_ARCH_CUR_FREQ)
+		? arch_freq_get_on_cpu(policy->cpu)
+		: 0;
+
+	if (freq > 0)
 		ret = sysfs_emit(buf, "%u\n", freq);
 	else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
 		ret = sysfs_emit(buf, "%u\n", cpufreq_driver->get(policy->cpu));
@@ -802,6 +810,19 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
 	return sysfs_emit(buf, "<unknown>\n");
 }
 
+/*
+ * show_cpuinfo_avg_freq - average CPU frequency as detected by hardware
+ */
+static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
+				     char *buf)
+{
+	int avg_freq = arch_freq_get_on_cpu(policy->cpu);
+
+	if (avg_freq > 0)
+		return sysfs_emit(buf, "%u\n", avg_freq);
+	return avg_freq != 0 ? avg_freq : -EINVAL;
+}
+
 /*
  * show_scaling_governor - show the current policy for the specified CPU
  */
@@ -964,6 +985,7 @@ static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
 }
 
 cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
+cpufreq_freq_attr_ro(cpuinfo_avg_freq);
 cpufreq_freq_attr_ro(cpuinfo_min_freq);
 cpufreq_freq_attr_ro(cpuinfo_max_freq);
 cpufreq_freq_attr_ro(cpuinfo_transition_latency);
@@ -1091,6 +1113,12 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy)
 			return ret;
 	}
 
+	if (cpufreq_avg_freq_supported(policy)) {
+		ret = sysfs_create_file(&policy->kobj, &cpuinfo_avg_freq.attr);
+		if (ret)
+			return ret;
+	}
+
 	ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
 	if (ret)
 		return ret;
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index d4d2f4d1d7cb..a7b6c0ccf9bc 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -1194,7 +1194,7 @@ static inline int of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_
 }
 #endif
 
-extern unsigned int arch_freq_get_on_cpu(int cpu);
+extern int arch_freq_get_on_cpu(int cpu);
 
 #ifndef arch_set_freq_scale
 static __always_inline
-- 
2.25.1



From beata.michalska at arm.com  Fri Dec  6 05:55:58 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri,  6 Dec 2024 13:55:58 +0000
Subject: [PATCH v8 2/4] arm64: amu: Delay allocating cpumask for AMU FIE support
In-Reply-To: <20241206135600.4083965-1-beata.michalska@arm.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
Message-ID: <20241206135600.4083965-3-beata.michalska@arm.com>

For the time being, the amu_fie_cpus cpumask is being exclusively used
by the AMU-related internals of FIE support and is guaranteed to be
valid on every access currently made. Still the mask is not being
invalidated on one of the error handling code paths, which leaves
a soft spot with theoretical risk of UAF for CPUMASK_OFFSTACK cases.
To make things sound, delay allocating said cpumask
(for CPUMASK_OFFSTACK) avoiding otherwise nasty sanitising case failing
to register the cpufreq policy notifications.

Signed-off-by: Beata Michalska <beata.michalska at arm.com>
---
 arch/arm64/kernel/topology.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 1a2c72f3e7f8..cb180684d10d 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -194,12 +194,19 @@ static void amu_fie_setup(const struct cpumask *cpus)
 	int cpu;
 
 	/* We are already set since the last insmod of cpufreq driver */
-	if (unlikely(cpumask_subset(cpus, amu_fie_cpus)))
+	if (cpumask_available(amu_fie_cpus) &&
+	    unlikely(cpumask_subset(cpus, amu_fie_cpus)))
 		return;
 
-	for_each_cpu(cpu, cpus) {
+	for_each_cpu(cpu, cpus)
 		if (!freq_counters_valid(cpu))
 			return;
+
+	if (!cpumask_available(amu_fie_cpus) &&
+	    !zalloc_cpumask_var(&amu_fie_cpus, GFP_KERNEL)) {
+		WARN_ONCE(1, "Failed to allocate FIE cpumask for CPUs[%*pbl]\n",
+			  cpumask_pr_args(cpus));
+		return;
 	}
 
 	cpumask_or(amu_fie_cpus, amu_fie_cpus, cpus);
@@ -237,17 +244,8 @@ static struct notifier_block init_amu_fie_notifier = {
 
 static int __init init_amu_fie(void)
 {
-	int ret;
-
-	if (!zalloc_cpumask_var(&amu_fie_cpus, GFP_KERNEL))
-		return -ENOMEM;
-
-	ret = cpufreq_register_notifier(&init_amu_fie_notifier,
+	return cpufreq_register_notifier(&init_amu_fie_notifier,
 					CPUFREQ_POLICY_NOTIFIER);
-	if (ret)
-		free_cpumask_var(amu_fie_cpus);
-
-	return ret;
 }
 core_initcall(init_amu_fie);
 
-- 
2.25.1



From beata.michalska at arm.com  Fri Dec  6 05:55:59 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri,  6 Dec 2024 13:55:59 +0000
Subject: [PATCH v8 3/4] arm64: Provide an AMU-based version of arch_freq_get_on_cpu
In-Reply-To: <20241206135600.4083965-1-beata.michalska@arm.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
Message-ID: <20241206135600.4083965-4-beata.michalska@arm.com>

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 average frequency for a given CPU,
can be achieved by utilizing the frequency scale factor which reflects
an average CPU frequency for the last tick period length.

The solution is partially based on APERF/MPERF implementation of
arch_freq_get_on_cpu.

Suggested-by: Ionela Voinescu <ionela.voinescu at arm.com>
Signed-off-by: Beata Michalska <beata.michalska at arm.com>
---
 arch/arm64/kernel/topology.c | 109 +++++++++++++++++++++++++++++++----
 1 file changed, 99 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index cb180684d10d..5f5738b174c7 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>
@@ -88,18 +89,28 @@ int __init parse_acpi_topology(void)
  * initialized.
  */
 static DEFINE_PER_CPU_READ_MOSTLY(unsigned long, arch_max_freq_scale) =  1UL << (2 * SCHED_CAPACITY_SHIFT);
-static DEFINE_PER_CPU(u64, arch_const_cycles_prev);
-static DEFINE_PER_CPU(u64, arch_core_cycles_prev);
 static cpumask_var_t amu_fie_cpus;
 
+struct amu_cntr_sample {
+	u64		arch_const_cycles_prev;
+	u64		arch_core_cycles_prev;
+	unsigned long	last_scale_update;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct amu_cntr_sample, cpu_amu_samples);
+
 void update_freq_counters_refs(void)
 {
-	this_cpu_write(arch_core_cycles_prev, read_corecnt());
-	this_cpu_write(arch_const_cycles_prev, read_constcnt());
+	struct amu_cntr_sample *amu_sample = this_cpu_ptr(&cpu_amu_samples);
+
+	amu_sample->arch_core_cycles_prev = read_corecnt();
+	amu_sample->arch_const_cycles_prev = read_constcnt();
 }
 
 static inline bool freq_counters_valid(int cpu)
 {
+	struct amu_cntr_sample *amu_sample = per_cpu_ptr(&cpu_amu_samples, cpu);
+
 	if ((cpu >= nr_cpu_ids) || !cpumask_test_cpu(cpu, cpu_present_mask))
 		return false;
 
@@ -108,8 +119,8 @@ static inline bool freq_counters_valid(int cpu)
 		return false;
 	}
 
-	if (unlikely(!per_cpu(arch_const_cycles_prev, cpu) ||
-		     !per_cpu(arch_core_cycles_prev, cpu))) {
+	if (unlikely(!amu_sample->arch_const_cycles_prev ||
+		     !amu_sample->arch_core_cycles_prev)) {
 		pr_debug("CPU%d: cycle counters are not enabled.\n", cpu);
 		return false;
 	}
@@ -152,17 +163,22 @@ void freq_inv_set_max_ratio(int cpu, u64 max_rate)
 
 static void amu_scale_freq_tick(void)
 {
+	struct amu_cntr_sample *amu_sample = this_cpu_ptr(&cpu_amu_samples);
 	u64 prev_core_cnt, prev_const_cnt;
 	u64 core_cnt, const_cnt, scale;
 
-	prev_const_cnt = this_cpu_read(arch_const_cycles_prev);
-	prev_core_cnt = this_cpu_read(arch_core_cycles_prev);
+	prev_const_cnt = amu_sample->arch_const_cycles_prev;
+	prev_core_cnt = amu_sample->arch_core_cycles_prev;
 
 	update_freq_counters_refs();
 
-	const_cnt = this_cpu_read(arch_const_cycles_prev);
-	core_cnt = this_cpu_read(arch_core_cycles_prev);
+	const_cnt = amu_sample->arch_const_cycles_prev;
+	core_cnt = amu_sample->arch_core_cycles_prev;
 
+	/*
+	 * This should not happen unless the AMUs have been reset and the
+	 * counter values have not been restored - unlikely
+	 */
 	if (unlikely(core_cnt <= prev_core_cnt ||
 		     const_cnt <= prev_const_cnt))
 		return;
@@ -182,6 +198,8 @@ static void amu_scale_freq_tick(void)
 
 	scale = min_t(unsigned long, scale, SCHED_CAPACITY_SCALE);
 	this_cpu_write(arch_freq_scale, (unsigned long)scale);
+
+	amu_sample->last_scale_update = jiffies;
 }
 
 static struct scale_freq_data amu_sfd = {
@@ -189,6 +207,77 @@ static struct scale_freq_data amu_sfd = {
 	.set_freq_scale = amu_scale_freq_tick,
 };
 
+static __always_inline bool amu_fie_cpu_supported(unsigned int cpu)
+{
+	return cpumask_available(amu_fie_cpus) &&
+		cpumask_test_cpu(cpu, amu_fie_cpus);
+}
+
+#define AMU_SAMPLE_EXP_MS	20
+
+int arch_freq_get_on_cpu(int cpu)
+{
+	struct amu_cntr_sample *amu_sample;
+	unsigned int start_cpu = cpu;
+	unsigned long last_update;
+	unsigned int freq = 0;
+	u64 scale;
+
+	if (!amu_fie_cpu_supported(cpu) || !arch_scale_freq_ref(cpu))
+		return -EOPNOTSUPP;
+
+retry:
+	amu_sample = per_cpu_ptr(&cpu_amu_samples, cpu);
+
+	last_update = amu_sample->last_scale_update;
+
+	/*
+	 * For those CPUs that are in full dynticks mode, or those that have
+	 * not seen tick for a while, try an alternative source for the counters
+	 * (and thus freq scale), if available, for given policy: this boils
+	 * down to identifying an active cpu within the same freq domain, if any.
+	 */
+	if (!housekeeping_cpu(cpu, HK_TYPE_TICK) ||
+	    time_is_before_jiffies(last_update + msecs_to_jiffies(AMU_SAMPLE_EXP_MS))) {
+		struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+		int ref_cpu = cpu;
+
+		if (!policy)
+			return -EINVAL;
+
+		if (!cpumask_intersects(policy->related_cpus,
+					housekeeping_cpumask(HK_TYPE_TICK))) {
+			cpufreq_cpu_put(policy);
+			return -EOPNOTSUPP;
+		}
+
+
+		do {
+			ref_cpu = cpumask_next_wrap(ref_cpu, policy->cpus,
+						    start_cpu, false);
+
+		} while (ref_cpu < nr_cpu_ids && idle_cpu(ref_cpu));
+
+		cpufreq_cpu_put(policy);
+
+		if (ref_cpu >= nr_cpu_ids)
+			/* No alternative to pull info from */
+			return -EAGAIN;
+
+		cpu = ref_cpu;
+		goto retry;
+	}
+	/*
+	 * Reversed computation to the one used to determine
+	 * the arch_freq_scale value
+	 * (see amu_scale_freq_tick for details)
+	 */
+	scale = arch_scale_freq_capacity(cpu);
+	freq = scale * arch_scale_freq_ref(cpu);
+	freq >>= SCHED_CAPACITY_SHIFT;
+	return freq;
+}
+
 static void amu_fie_setup(const struct cpumask *cpus)
 {
 	int cpu;
-- 
2.25.1



From beata.michalska at arm.com  Fri Dec  6 05:56:00 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri,  6 Dec 2024 13:56:00 +0000
Subject: [PATCH v8 4/4] arm64: Update AMU-based freq scale factor on entering idle
In-Reply-To: <20241206135600.4083965-1-beata.michalska@arm.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
Message-ID: <20241206135600.4083965-5-beata.michalska@arm.com>

Now that the frequency scale factor has been activated for retrieving
current frequency on a given CPU, trigger its update upon entering
idle. This will, to an extent, allow querying last known frequency
in a non-invasive way. It will also improve the frequency scale factor
accuracy when a CPU entering idle did not receive a tick for a while.
As a consequence, for idle cores, the reported frequency will be the
last one observed before entering the idle state.

Suggested-by: Vanshidhar Konda <vanshikonda at os.amperecomputing.com>
Signed-off-by: Beata Michalska <beata.michalska at arm.com>
---
 arch/arm64/kernel/topology.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 5f5738b174c7..6c43aafac77c 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -213,6 +213,19 @@ static __always_inline bool amu_fie_cpu_supported(unsigned int cpu)
 		cpumask_test_cpu(cpu, amu_fie_cpus);
 }
 
+void arch_cpu_idle_enter(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	if (!amu_fie_cpu_supported(cpu))
+		return;
+
+	/* Kick in AMU update but only if one has not happened already */
+	if (housekeeping_cpu(cpu, HK_TYPE_TICK) &&
+	    time_is_before_jiffies(per_cpu(cpu_amu_samples.last_scale_update, cpu)))
+		amu_scale_freq_tick();
+}
+
 #define AMU_SAMPLE_EXP_MS	20
 
 int arch_freq_get_on_cpu(int cpu)
-- 
2.25.1



From guoqing.jiang at canonical.com  Fri Dec  6 05:55:07 2024
From: guoqing.jiang at canonical.com (Guoqing Jiang)
Date: Fri,  6 Dec 2024 21:55:07 +0800
Subject: [PATCH] drm/mediatek: Set private->all_drm_private[i]->drm to NULL if mtk_drm_bind returns err 
Message-ID: <20241206135507.1274357-1-guoqing.jiang@canonical.com>

The pointer need to be set to NULL, otherwise KASAN complains about
use-after-free. Because in mtk_drm_bind, all private's drm are set
as follows.

private->all_drm_private[i]->drm = drm;

And drm will be released by drm_dev_put in case mtk_drm_kms_init returns
failure. However, the shutdown path still accesses the previous allocated
memory in drm_atomic_helper_shutdown.

[   84.874820] watchdog: watchdog0: watchdog did not stop!
[   86.512054] ==================================================================
[   86.513162] BUG: KASAN: use-after-free in drm_atomic_helper_shutdown+0x33c/0x378
[   86.514258] Read of size 8 at addr ffff0000d46fc068 by task shutdown/1
[   86.515213]
[   86.515455] CPU: 1 UID: 0 PID: 1 Comm: shutdown Not tainted 6.13.0-rc1-mtk+gfa1a78e5d24b-dirty #55
[   86.516752] Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10 10/01/2022
[   86.517960] Call trace:
[   86.518333]  show_stack+0x20/0x38 (C)
[   86.518891]  dump_stack_lvl+0x90/0xd0
[   86.519443]  print_report+0xf8/0x5b0
[   86.519985]  kasan_report+0xb4/0x100
[   86.520526]  __asan_report_load8_noabort+0x20/0x30
[   86.521240]  drm_atomic_helper_shutdown+0x33c/0x378
[   86.521966]  mtk_drm_shutdown+0x54/0x80
[   86.522546]  platform_shutdown+0x64/0x90
[   86.523137]  device_shutdown+0x260/0x5b8
[   86.523728]  kernel_restart+0x78/0xf0
[   86.524282]  __do_sys_reboot+0x258/0x2f0
[   86.524871]  __arm64_sys_reboot+0x90/0xd8
[   86.525473]  invoke_syscall+0x74/0x268
[   86.526041]  el0_svc_common.constprop.0+0xb0/0x240
[   86.526751]  do_el0_svc+0x4c/0x70
[   86.527251]  el0_svc+0x4c/0xc0
[   86.527719]  el0t_64_sync_handler+0x144/0x168
[   86.528367]  el0t_64_sync+0x198/0x1a0
[   86.528920]
[   86.529157] The buggy address belongs to the physical page:
[   86.529972] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff0000d46fd4d0 pfn:0x1146fc
[   86.531319] flags: 0xbfffc0000000000(node=0|zone=2|lastcpupid=0xffff)
[   86.532267] raw: 0bfffc0000000000 0000000000000000 dead000000000122 0000000000000000
[   86.533390] raw: ffff0000d46fd4d0 0000000000000000 00000000ffffffff 0000000000000000
[   86.534511] page dumped because: kasan: bad access detected
[   86.535323]
[   86.535559] Memory state around the buggy address:
[   86.536265]  ffff0000d46fbf00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.537314]  ffff0000d46fbf80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.538363] >ffff0000d46fc000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.544733]                                                           ^
[   86.551057]  ffff0000d46fc080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.557510]  ffff0000d46fc100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.563928] ==================================================================
[   86.571093] Disabling lock debugging due to kernel taint
[   86.577642] Unable to handle kernel paging request at virtual address e0e9c0920000000b
[   86.581834] KASAN: maybe wild-memory-access in range [0x0752049000000058-0x075204900000005f]
...

Signed-off-by: Guoqing Jiang <guoqing.jiang at canonical.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 9a8ef8558da9..0062374f75d5 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -673,6 +673,8 @@ static int mtk_drm_bind(struct device *dev)
 err_free:
 	private->drm = NULL;
 	drm_dev_put(drm);
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		private->all_drm_private[i]->drm = NULL;
 	return ret;
 }
 
-- 
2.35.3



From conor at kernel.org  Fri Dec  6 05:56:08 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 6 Dec 2024 13:56:08 +0000
Subject: [PATCH v1 08/11] clk: move meson clk-regmap implementation to
 common code
In-Reply-To: <e53adbf9fdf6e3f142083b0d40d074ca.sboyd@kernel.org>
References: <20241002-private-unequal-33cfa6101338@spud>
 <20241002-hula-unwashed-1c4ddbadbec2@spud>
 <2b49c4df-a34a-42c5-8d44-9e47da630fe8@linaro.org>
 <1jwmiqsks3.fsf@starbuckisacylon.baylibre.com>
 <20241003-tacking-ladylike-dfe2b633e647@spud>
 <20241106-freefall-slider-db379b05821e@spud>
 <430bde3b35382e640843e32a9f351326.sboyd@kernel.org>
 <20241128-monstrous-embargo-a665d921410d@wendy>
 <e53adbf9fdf6e3f142083b0d40d074ca.sboyd@kernel.org>
Message-ID: <20241206-threaten-showing-1214491f3899@spud>

On Tue, Dec 03, 2024 at 02:50:31PM -0800, Stephen Boyd wrote:
> Quoting Conor Dooley (2024-11-28 02:36:16)
> > On Thu, Nov 14, 2024 at 05:29:54PM -0800, Stephen Boyd wrote:
> > > Quoting Conor Dooley (2024-11-06 04:56:25)
> > > > My use case doesn't
> > > > actually need the registration code changes either as, currently, only reg
> > > > gets set at runtime, but leaving that out is a level of incomplete I'd not
> > > > let myself away with.
> > > > Obviously shoving the extra members into the clk structs has the downside
> > > > of taking up a pointer and a offset worth of memory for each clock of
> > > > that type registered, but it is substantially easier to support devices
> > > > with multiple regmaps that way. Probably moot though since the approach you
> > > > suggested in the thread linked above that implements a clk_hw_get_regmap()
> > > > has to store a pointer to the regmap's identifier which would take up an
> > > > identical amount of memory.
> > > 
> > > We don't need to store the regmap identifier in the struct clk. We can
> > > store it in the 'struct clk_init_data' with some new field, and only do
> > > that when/if we actually need to. We would need to pass the init data to
> > > the clk_ops::init() callback though. We currently knock that out during
> > > registration so that clk_hw->init is NULL. Probably we can just set that
> > > to NULL after the init routine runs in __clk_core_init().
> > > 
> > > Long story short, don't add something to 'struct clk_core', 'struct
> > > clk', or 'struct clk_hw' for these details. We can have a 'struct
> > > clk_regmap_hw' that everyone else can build upon:
> > > 
> > >   struct clk_regmap_hw {
> > >         struct regmap *regmap;
> > >         struct clk_hw hw;
> > >   };
> > 
> > What's the point of this? I don't understand why you want to do this over
> > what clk_divider et al already do, where clk_hw and the iomem pointer
> > are in the struct itself.
> 
> Can you give an example? I don't understand what you're suggesting. I
> prefer a struct clk_regmap_hw like above so that the existing struct
> clk_hw in the kernel aren't increased by a pointer. SoC drivers can use
> the same struct as a replacement for their struct clk_hw member today.

Best example I guess is to link what I did? This one is the core
changes:
https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/commit/?h=syscon-rework-2&id=35904222355e971c24b3eb9b9fad3dd0c38d1393
clk-gate has my original hack that I did while trying to figure out
what you wanted, clk-divider-regmap is a 99% copy of clk-divider with
the types, function names and readl()/writel() implementations modified.
Before your last set of comments I was doing something identical to the
clk-gate change for clk-divider also.
Here's the changes required to my driver to make it work with the
updated:
https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/commit/?h=syscon-rework-2&id=ea40211fe20f8bc6ef0320b93e1baa5b3f244601
It's pretty much a drop in replacement, other than the additional
complexity in probe.

Hopefully that either gets my point across or lets you spot why I don't
understand the benefit of a wrapper around clk_hw.

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/20241206/60f79af1/attachment.sig>

From beata.michalska at arm.com  Fri Dec  6 05:55:56 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri,  6 Dec 2024 13:55:56 +0000
Subject: [PATCH v8 0/4] Add support for AArch64 AMUv1-based average freq
Message-ID: <20241206135600.4083965-1-beata.michalska@arm.com>

Hi All,

This series adds support for obtaining an average CPU frequency based on
a hardware provided feedback. The average frequency is being exposed via
dedicated yet optional cpufreq sysfs attribute - cpuinfo_avg_freq.
The architecture specific bits are being provided for AArch64, caching on
existing implementation for FIE and AMUv1 support: the frequency scale
factor, updated on each sched tick, serving as a base for retrieving
the frequency for a given CPU, representing an average frequency
reported between the ticks.

The changes have been rather lightly (due to some limitations) tested on
an FVP model.

Note that [PATCH 2/4] arm64: amu: Delay allocating cpumask for AMU FIE support
can be merged independently.
Additionally, this series depends on [6]

Relevant discussions:
[1] https://lore.kernel.org/all/20240229162520.970986-1-vanshikonda at os.amperecomputing.com/
[2] https://lore.kernel.org/all/7eozim2xnepacnnkzxlbx34hib4otycnbn4dqymfziqou5lw5u at 5xzpv3t7sxo3/
[3] https://lore.kernel.org/all/20231212072617.14756-1-lihuisong at huawei.com/
[4] https://lore.kernel.org/lkml/ZIHpd6unkOtYVEqP at e120325.cambridge.arm.com/T/#m4e74cb5a0aaa353c60fedc6cfb95ab7a6e381e3c
[5] https://lore.kernel.org/all/20240603081331.3829278-1-beata.michalska at arm.com/
[6] https://lore.kernel.org/all/20240827154818.1195849-1-ionela.voinescu at arm.com/

v8:
- Drop introducing new function and reuse arch_freq_get_on_cpu, guarding its use
  in scaling_cur_freq sysfs handler with dedicated config for x86

v7:
- Dropping 'arch_topology: init capacity_freq_ref to 0' patch from the series
  as this one has been sent separately as an independent change
  [https://lore.kernel.org/all/20240827154818.1195849-1-ionela.voinescu at arm.com/]
- Including in the series change that introduces new sysfs entry [PATCH 1/4]
- Consequently modifying previously arch_freq_get_on_cpu to match reqs for new
  sysfs attribute
- Dropping an idea of considering a CPU that has been idle for a while as a
  valid source of information for obtaining an AMU-counter based frequency
- Some minor cosmetic changes

v6:
 - delay allocating cpumask for AMU FIE support instead of invalidating the mask
   upon failure to register cpufreq policy notifications
 - drop the change to cpufreq core (for cpuinfo_cur_freq) as this one will be
   sent as a separate change

v5:
 - Fix invalid access to cpumask
 - Reworked finding reference cpu when getting the freq

v4:
- dropping seqcount
- fixing identifying active cpu within given policy
- skipping full dynticks cpus when retrieving the freq
- bringing back plugging in arch_freq_get_on_cpu into cpuinfo_cur_freq

v3:
- dropping changes to cpufreq_verify_current_freq
- pulling in changes from Ionela initializing capacity_freq_ref to 0
  (thanks for that!)  and applying suggestions made by her during last review:
	- switching to arch_scale_freq_capacity and arch_scale_freq_ref when
	  reversing freq scale factor computation
	- swapping shift with multiplication
- adding time limit for considering last scale update as valid
- updating frequency scale factor upon entering idle

v2:
- Splitting the patches
- Adding comment for full dyntick mode
- Plugging arch_freq_get_on_cpu into cpufreq_verify_current_freq instead
  of in show_cpuinfo_cur_freq to allow the framework to stay more in sync
  with potential freq changes

CC: Jonathan Corbet <corbet at lwn.net>
CC: Thomas Gleixner <tglx at linutronix.de>
CC: Ingo Molnar <mingo at redhat.com>
CC: Borislav Petkov <bp at alien8.de>
CC: Dave Hansen <dave.hansen at linux.intel.com>
CC: H. Peter Anvin <hpa at zytor.com>
CC: Phil Auld <pauld at redhat.com>
CC: x86 at kernel.org
CC: linux-doc at vger.kernel.org

Beata Michalska (4):
  cpufreq: Introduce an optional cpuinfo_avg_freq sysfs entry
  arm64: amu: Delay allocating cpumask for AMU FIE support
  arm64: Provide an AMU-based version of arch_freq_get_on_cpu
  arm64: Update AMU-based freq scale factor on entering idle

 Documentation/admin-guide/pm/cpufreq.rst |  16 ++-
 arch/arm64/kernel/topology.c             | 144 +++++++++++++++++++----
 arch/x86/kernel/cpu/aperfmperf.c         |   2 +-
 arch/x86/kernel/cpu/proc.c               |   7 +-
 drivers/cpufreq/Kconfig.x86              |  12 ++
 drivers/cpufreq/cpufreq.c                |  36 +++++-
 include/linux/cpufreq.h                  |   2 +-
 7 files changed, 188 insertions(+), 31 deletions(-)

-- 
2.25.1



From geert at linux-m68k.org  Fri Dec  6 05:59:25 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 6 Dec 2024 14:59:25 +0100
Subject: [PATCH] arm64: defconfig: Enable Renesas RZ/V2H(P) Watchdog driver
In-Reply-To: <20241112093412.20093-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20241112093412.20093-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CAMuHMdXa9e9NAsb=bWuSicCsF2_qM_fW7_+3AKHgaTgsPCX0og@mail.gmail.com>

On Tue, Nov 12, 2024 at 10:34?AM Prabhakar <prabhakar.csengg at gmail.com> wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
>
> Enable the watchdog driver for the Renesas RZ/V2H(P) SoC.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
i.e. will queue in renesas-devel for v6.14.

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  Fri Dec  6 06:11:57 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Fri, 6 Dec 2024 15:11:57 +0100
Subject: [PATCH v5 8/9] drm/vc4: hdmi: switch to using generic HDMI Codec
 infrastructure
In-Reply-To: <e7jngrc4nljdsksekinbkir2h76ztsth2xj4yqcyapfv43uryh@356yrxv3j4x6>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-8-b5316e82f61a@linaro.org>
 <20241202-industrious-unnatural-beagle-7da5d4@houat>
 <e7jngrc4nljdsksekinbkir2h76ztsth2xj4yqcyapfv43uryh@356yrxv3j4x6>
Message-ID: <20241206-agile-tidy-avocet-c69bff@houat>

On Tue, Dec 03, 2024 at 02:19:41PM +0200, Dmitry Baryshkov wrote:
> On Mon, Dec 02, 2024 at 02:20:04PM +0100, Maxime Ripard wrote:
> > Hi,
> > 
> > Sorry, I've been drowning under work and couldn't review that series before.
> 
> No worries, at this point I'm more concerned about my IGT series rather
> than this one.
> 
> > 
> > I'll review the driver API for now, and we can focus on the exact
> > implementation later on.
> > 
> > On Sun, Dec 01, 2024 at 02:44:12AM +0200, Dmitry Baryshkov wrote:
> > > Drop driver-specific implementation and use the generic HDMI Codec
> > > framework in order to implement the HDMI audio support.
> > > 
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > ---
> > >  drivers/gpu/drm/vc4/vc4_hdmi.c | 68 ++++++++++--------------------------------
> > >  drivers/gpu/drm/vc4/vc4_hdmi.h |  2 --
> > >  2 files changed, 15 insertions(+), 55 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > index 7295834e75fb1ab0cd241ed274e675567e66870b..d0a9aff7ad43016647493263c00d593296a1e3ad 100644
> > > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > @@ -595,6 +595,9 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
> > >  	if (vc4_hdmi->variant->supports_hdr)
> > >  		max_bpc = 12;
> > >  
> > > +	connector->hdmi_codec.max_i2s_channels = 8;
> > > +	connector->hdmi_codec.i2s = 1;
> > > +
> > 
> > I guess it's a similar discussion than we had with HDMI2.0+ earlier
> > today, but I don't really like initializing by structs. Struct fields
> > are easy to miss, and can be easily uninitialized by mistake.
> > 
> > I think I'd prefer to have them as argument to the init function. And if
> > they are optional, we can explicitly mark them as unused.
> 
> Do you mean drm_connector_hdmi_init()? I think it's overloaded already,
> but I defintely can think about:
> 
> drmm_connector_hdmi_init(..., max_bpc, HDMI_CODEC_I2S_PLAYBACK(8) |
> HDMI_CODEC_NO_CAPTURE | HDMI_CODEC_DAI_ID(4));
> 
> or
> 
> ... | HDMI_CODEC_NO_DAI_ID)
> 
> The default (0) being equivalent to:
> 
> HDMI_CODEC_NO_I2S | HDMI_CODEC_NO_SPDIF | HDMI_CODEC_NO_CAPTURE | HDMI_CODEC_NO_DAI_ID
> 
> WDYT?

I know it's kind of contradictory, but it definitely looks overcrowded.

A bit after we merged the HDMI infrastructure, Thomas commented that it
might have been better to have a secondary init function instead of an
alloc/init function.

https://lore.kernel.org/all/5934b4b2-3a99-4b6b-b3e3-e57eb82b9b16 at suse.de/

It's still sitting in my inbox and haven't had the time to work on that,
but maybe that's how we should deal with this?

Switch to using drm_connector_init, then drm_connector_hdmi_init would
only take care of the video stuff, and we could have an additional
drm_connector_hdmi_audio_init?

That way, we could have both explicit stuff, and yet not overcrowd the
arguments list too much?

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

From nicolas.ferre at microchip.com  Fri Dec  6 06:14:10 2024
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Fri, 6 Dec 2024 15:14:10 +0100
Subject: [PATCH] ARM: at91: pm: change BU Power Switch to automatic mode
In-Reply-To: <24069031-9ed4-4592-af98-ff53222caf03@microchip.com>
References: <20241125165648.509162-1-nicolas.ferre@microchip.com>
 <34a5b77b-e732-4393-a469-d9c719afa879@tuxon.dev>
 <24069031-9ed4-4592-af98-ff53222caf03@microchip.com>
Message-ID: <c7ad1f03-f2a9-4706-ae87-2843b93de040@microchip.com>

Claudiu,

On 02/12/2024 at 17:44, Nicolas Ferre wrote:
> On 02/12/2024 at 09:05, Claudiu Beznea wrote:
>> Hi, Nicolas,
>>
>> On 25.11.2024 18:56, nicolas.ferre at microchip.com wrote:
>>> From: Nicolas Ferre <nicolas.ferre at microchip.com>
>>>
>>> Change how the Backup Unit Power is configured and force the
>>> automatic/hardware mode.
>>> This change eliminates the need for software management of the power
>>> switch, ensuring it transitions to the backup power source before
>>> entering low power modes.
>>>
>>> This is done in the only locaton where this swich was configured. It's
>>
>> s/locaton/location
>>
>>> usually done in the bootloader.
>>>
>>> Previously, the loss of the VDDANA (or VDDIN33) power source was not
>>> automatically compensated by an alternative power source. This resulted
>>> in the loss of Backup Unit content, including Backup Self-refresh low
>>> power mode information, OTP emulation configuration, and boot
>>> configuration, for instance.
>>
>> Should we add a fixes for this?
> 
> Not so easy to tell as there's a loose dependency with the bootloader.
> But it's true that switching to automatic never harm. So probably yes.
> 
>>> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
>>> ---
>>>    arch/arm/mach-at91/pm.c | 31 ++++++++++++++++++++-----------
>>>    1 file changed, 20 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
>>> index b9b995f8a36e..05a1547642b6 100644
>>> --- a/arch/arm/mach-at91/pm.c
>>> +++ b/arch/arm/mach-at91/pm.c
>>> @@ -598,7 +598,21 @@ static int at91_suspend_finish(unsigned long val)
>>>         return 0;
>>>    }
>>>
>>> -static void at91_pm_switch_ba_to_vbat(void)
>>> +/**
>>> + * at91_pm_switch_ba_to_auto() - Configure Backup Unit Power Switch
>>> + * to automatic/hardware mode.
>>> + *
>>> + * The Backup Unit Power Switch can be managed either by software or hardware.
>>> + * Enabling hardware mode allows the automatic transition of power between
>>> + * VDDANA (or VDDIN33) and VDDBU (or VBAT, respectively), based on the
>>> + * availability of these power sources.
>>> + *
>>> + * If the Backup Unit Power Switch is already in automatic mode, no action is
>>> + * required. If it is in software-controlled mode, it is switched to automatic
>>> + * mode to enhance safety and eliminate the need for toggling between power
>>> + * sources.
>>> + */
>>> +static void at91_pm_switch_ba_to_auto(void)
>>>    {
>>>         unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu);
>>>         unsigned int val;
>>> @@ -609,24 +623,19 @@ static void at91_pm_switch_ba_to_vbat(void)
>>>
>>>         val = readl(soc_pm.data.sfrbu + offset);
>>>
>>> -     /* Already on VBAT. */
>>> -     if (!(val & soc_pm.sfrbu_regs.pswbu.state))
>>> +     /* Already on auto/hardware. */
>>> +     if (!(val & soc_pm.sfrbu_regs.pswbu.ctrl))
>>>                 return;
>>>
>>> -     val &= ~soc_pm.sfrbu_regs.pswbu.softsw;
>>
>> It seems that softsw and state members of at91_pm_sfrbu_regs.pswbu along
>> with their initialization could be dropped. What do you think?
> 
> I think that I tried when writing the patch but I think that there's a
> little difference with sama5d2 register layout. Give me a couple more
> days to come back to this and verify.

Ok, I remember now: I was wondering if I needed to remove the whole 
sfrbu_regs.xxx mechanism and define more generically the content of 
include/soc/at91/sama7-sfrbu.h for sama5d2, but if we need one day to 
use the STATE bit or even the SMCTRL bit of sama5d2, then it should be kept.

So, now that the mechanism is in place, I would prefer that we keep it: 
okay for you?

Do you want me to re-spin a v2 for the rest?

Best regards,
   Nicolas

>> I can do it while applying, if any.
>>
>> Thank you,
>> Claudiu
>>
>>
>>> -     val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl;
>>> +     val &= ~soc_pm.sfrbu_regs.pswbu.ctrl;
>>> +     val |= soc_pm.sfrbu_regs.pswbu.key;
>>>         writel(val, soc_pm.data.sfrbu + offset);
>>> -
>>> -     /* Wait for update. */
>>> -     val = readl(soc_pm.data.sfrbu + offset);
>>> -     while (val & soc_pm.sfrbu_regs.pswbu.state)
>>> -             val = readl(soc_pm.data.sfrbu + offset);
>>>    }
>>>
>>>    static void at91_pm_suspend(suspend_state_t state)
>>>    {
>>>         if (soc_pm.data.mode == AT91_PM_BACKUP) {
>>> -             at91_pm_switch_ba_to_vbat();
>>> +             at91_pm_switch_ba_to_auto();
>>>
>>>                 cpu_suspend(0, at91_suspend_finish);
>>>
> 
> 



From mripard at kernel.org  Fri Dec  6 06:23:01 2024
From: mripard at kernel.org (mripard at kernel.org)
Date: Fri, 6 Dec 2024 15:23:01 +0100
Subject: [PATCH v5 9/9] drm/vc4: hdmi: use
 drm_atomic_helper_connector_hdmi_update_edid()
In-Reply-To: <ae24x2bo736jpzi77l34hybejawwe4rp47v2idedga344ye6zr@bxsxz34dwrd2>
References: <20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a@linaro.org>
 <20241201-drm-bridge-hdmi-connector-v5-9-b5316e82f61a@linaro.org>
 <20241202-married-bald-raven-7acd83@houat>
 <ae24x2bo736jpzi77l34hybejawwe4rp47v2idedga344ye6zr@bxsxz34dwrd2>
Message-ID: <20241206-speedy-beaver-from-asgard-dbed9c@houat>

On Tue, Dec 03, 2024 at 02:27:44PM +0200, Dmitry Baryshkov wrote:
> On Mon, Dec 02, 2024 at 02:27:49PM +0100, Maxime Ripard wrote:
> > Hi,
> > 
> > On Sun, Dec 01, 2024 at 02:44:13AM +0200, Dmitry Baryshkov wrote:
> > > Use the helper function to update the connector's information. This
> > > makes sure that HDMI-related events are handled in a generic way.
> > > Currently it is limited to the HDMI state reporting to the sound system.
> > > 
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > ---
> > >  drivers/gpu/drm/vc4/vc4_hdmi.c | 9 +++++++--
> > >  1 file changed, 7 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > index d0a9aff7ad43016647493263c00d593296a1e3ad..d83f587ab69f4b8f7d5c37a00777f11da8301bc1 100644
> > > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > @@ -401,13 +401,16 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
> > >  	 */
> > >  
> > >  	if (status == connector_status_disconnected) {
> > > +		drm_atomic_helper_connector_hdmi_update_edid(connector, NULL);
> > >  		cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
> > >  		return;
> > >  	}
> > >  
> > >  	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
> > >  
> > > -	drm_edid_connector_update(connector, drm_edid);
> > > +	// TODO: use drm_atomic_helper_connector_hdmi_update() once it gains
> > > +	// CEC support
> > > +	drm_atomic_helper_connector_hdmi_update_edid(connector, drm_edid);
> > 
> > So, it's not just about EDID, and I think we shouldn't really focus on
> > that either.
> > 
> > As that patch points out, even if we only consider EDID's, we have
> > different path depending on the connector status. It shouldn't be up to
> > the drivers to get this right.
> > 
> > What I had in mind was something like a
> > drm_atomic_helper_connector_hdmi_hotplug function that would obviously
> > deal with EDID only here, but would expand to CEC, scrambling, etc.
> > later on.
> 
> I thought about it, after our discussion, but in the end I had to
> implement the EDID-specific function, using edid == NULL as
> "disconnected" event. The issue is pretty simple: there is no standard
> way to get EDID from the connector. The devices can call
> drm_edid_read(), drm_edid_read_ddc(connector->ddc) or (especially
> embedded bridges) use drm_edid_read_custom().

And that's fine, it's to be expected.

> Of course we can go with the functional way and add the
> .read_edid(drm_connector) callback to the HDMI funcs. Then the
> drm_atomic_helper_connector_hdmi_hotplug() function can read EDID on its
> own.

Yep, that's definitely what we should do. And then we can make a
get_modes helper too that would also use it.

> Also the function that you proposed perfectly fits the HPD notification
> callbacks, but which function should be called from the .get_modes()?
> The _hdmi_hotplug() doesn't fit there. Do we still end up with both
> drm_atomic_helper_connector_hdmi_hotplug() and
> drm_atomic_helper_connector_hdmi_update_edid()?

I'd say both a get_modes helper and a hotplug helper, both using that
read_edid hook under the hood.

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

From claudiu.beznea at tuxon.dev  Fri Dec  6 06:24:19 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Fri, 6 Dec 2024 16:24:19 +0200
Subject: [PATCH] ARM: at91: pm: change BU Power Switch to automatic mode
In-Reply-To: <c7ad1f03-f2a9-4706-ae87-2843b93de040@microchip.com>
References: <20241125165648.509162-1-nicolas.ferre@microchip.com>
 <34a5b77b-e732-4393-a469-d9c719afa879@tuxon.dev>
 <24069031-9ed4-4592-af98-ff53222caf03@microchip.com>
 <c7ad1f03-f2a9-4706-ae87-2843b93de040@microchip.com>
Message-ID: <9b9f5daa-2456-4ad0-9e56-a6978c35b197@tuxon.dev>

Hi, Nicolas,

On 06.12.2024 16:14, Nicolas Ferre wrote:
> Claudiu,
> 
> On 02/12/2024 at 17:44, Nicolas Ferre wrote:
>> On 02/12/2024 at 09:05, Claudiu Beznea wrote:
>>> Hi, Nicolas,
>>>
>>> On 25.11.2024 18:56, nicolas.ferre at microchip.com wrote:
>>>> From: Nicolas Ferre <nicolas.ferre at microchip.com>
>>>>
>>>> Change how the Backup Unit Power is configured and force the
>>>> automatic/hardware mode.
>>>> This change eliminates the need for software management of the power
>>>> switch, ensuring it transitions to the backup power source before
>>>> entering low power modes.
>>>>
>>>> This is done in the only locaton where this swich was configured. It's
>>>
>>> s/locaton/location
>>>
>>>> usually done in the bootloader.
>>>>
>>>> Previously, the loss of the VDDANA (or VDDIN33) power source was not
>>>> automatically compensated by an alternative power source. This resulted
>>>> in the loss of Backup Unit content, including Backup Self-refresh low
>>>> power mode information, OTP emulation configuration, and boot
>>>> configuration, for instance.
>>>
>>> Should we add a fixes for this?
>>
>> Not so easy to tell as there's a loose dependency with the bootloader.
>> But it's true that switching to automatic never harm. So probably yes.
>>
>>>> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
>>>> ---
>>>> ?? arch/arm/mach-at91/pm.c | 31 ++++++++++++++++++++-----------
>>>> ?? 1 file changed, 20 insertions(+), 11 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
>>>> index b9b995f8a36e..05a1547642b6 100644
>>>> --- a/arch/arm/mach-at91/pm.c
>>>> +++ b/arch/arm/mach-at91/pm.c
>>>> @@ -598,7 +598,21 @@ static int at91_suspend_finish(unsigned long val)
>>>> ??????? return 0;
>>>> ?? }
>>>>
>>>> -static void at91_pm_switch_ba_to_vbat(void)
>>>> +/**
>>>> + * at91_pm_switch_ba_to_auto() - Configure Backup Unit Power Switch
>>>> + * to automatic/hardware mode.
>>>> + *
>>>> + * The Backup Unit Power Switch can be managed either by software or
>>>> hardware.
>>>> + * Enabling hardware mode allows the automatic transition of power
>>>> between
>>>> + * VDDANA (or VDDIN33) and VDDBU (or VBAT, respectively), based on the
>>>> + * availability of these power sources.
>>>> + *
>>>> + * If the Backup Unit Power Switch is already in automatic mode, no
>>>> action is
>>>> + * required. If it is in software-controlled mode, it is switched to
>>>> automatic
>>>> + * mode to enhance safety and eliminate the need for toggling between
>>>> power
>>>> + * sources.
>>>> + */
>>>> +static void at91_pm_switch_ba_to_auto(void)
>>>> ?? {
>>>> ??????? unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu);
>>>> ??????? unsigned int val;
>>>> @@ -609,24 +623,19 @@ static void at91_pm_switch_ba_to_vbat(void)
>>>>
>>>> ??????? val = readl(soc_pm.data.sfrbu + offset);
>>>>
>>>> -???? /* Already on VBAT. */
>>>> -???? if (!(val & soc_pm.sfrbu_regs.pswbu.state))
>>>> +???? /* Already on auto/hardware. */
>>>> +???? if (!(val & soc_pm.sfrbu_regs.pswbu.ctrl))
>>>> ??????????????? return;
>>>>
>>>> -???? val &= ~soc_pm.sfrbu_regs.pswbu.softsw;
>>>
>>> It seems that softsw and state members of at91_pm_sfrbu_regs.pswbu along
>>> with their initialization could be dropped. What do you think?
>>
>> I think that I tried when writing the patch but I think that there's a
>> little difference with sama5d2 register layout. Give me a couple more
>> days to come back to this and verify.
> 
> Ok, I remember now: I was wondering if I needed to remove the whole
> sfrbu_regs.xxx mechanism and define more generically the content of
> include/soc/at91/sama7-sfrbu.h for sama5d2, but if we need one day to use
> the STATE bit or even the SMCTRL bit of sama5d2, then it should be kept.
> 
> So, now that the mechanism is in place, I would prefer that we keep it:
> okay for you?

OK

> 
> Do you want me to re-spin a v2 for the rest?

No, I can handle the insignificant typo while applying.

Thank you,
Claudiu

> 
> Best regards,
> ? Nicolas
> 
>>> I can do it while applying, if any.
>>>
>>> Thank you,
>>> Claudiu
>>>
>>>
>>>> -???? val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl;
>>>> +???? val &= ~soc_pm.sfrbu_regs.pswbu.ctrl;
>>>> +???? val |= soc_pm.sfrbu_regs.pswbu.key;
>>>> ??????? writel(val, soc_pm.data.sfrbu + offset);
>>>> -
>>>> -???? /* Wait for update. */
>>>> -???? val = readl(soc_pm.data.sfrbu + offset);
>>>> -???? while (val & soc_pm.sfrbu_regs.pswbu.state)
>>>> -???????????? val = readl(soc_pm.data.sfrbu + offset);
>>>> ?? }
>>>>
>>>> ?? static void at91_pm_suspend(suspend_state_t state)
>>>> ?? {
>>>> ??????? if (soc_pm.data.mode == AT91_PM_BACKUP) {
>>>> -???????????? at91_pm_switch_ba_to_vbat();
>>>> +???????????? at91_pm_switch_ba_to_auto();
>>>>
>>>> ??????????????? cpu_suspend(0, at91_suspend_finish);
>>>>
>>
>>
> 


From mripard at kernel.org  Fri Dec  6 06:34:52 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Fri, 6 Dec 2024 15:34:52 +0100
Subject: [PATCH v6 09/10] drm/vc4: hdmi: stop rereading EDID in
 get_modes()
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-9-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-9-50dc145a9c06@linaro.org>
Message-ID: <20241206-caped-proficient-rattlesnake-c882f3@houat>

Hi,

On Fri, Dec 06, 2024 at 12:16:03PM +0200, Dmitry Baryshkov wrote:
> The vc4_hdmi_connector_detect_ctx() via vc4_hdmi_handle_hotplug()
> already reads EDID and propagates it to the drm_connector. Stop
> rereading EDID as a part of the .get_modes() callback and just update
> the list of modes. This matches the behaviour of the i915 driver.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 21 ---------------------
>  1 file changed, 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index e5ab42f72f618b90f956482db6c9c8074c1e3bf1..3364ef90968dad3074800f02926300ffceb75c69 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -470,31 +470,10 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
>  
>  static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
>  {
> -	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
>  	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
> -	const struct drm_edid *drm_edid;
>  	int ret = 0;
>  
> -	/*
> -	 * NOTE: This function should really take vc4_hdmi->mutex, but doing so
> -	 * results in reentrancy issues since cec_s_phys_addr() might call
> -	 * .adap_enable, which leads to that funtion being called with our mutex
> -	 * held.
> -	 *
> -	 * Concurrency isn't an issue at the moment since we don't share
> -	 * any state with any of the other frameworks so we can ignore
> -	 * the lock for now.
> -	 */
> -
> -	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
> -	drm_edid_connector_update(connector, drm_edid);
> -	cec_s_phys_addr(vc4_hdmi->cec_adap,
> -			connector->display_info.source_physical_address, false);
> -	if (!drm_edid)
> -		return 0;
> -
>  	ret = drm_edid_connector_add_modes(connector);
> -	drm_edid_free(drm_edid);

I don't think that works though, for mostly two reasons:

 1) We're not sure we'll even have an hotplug interrupt if the system
    boots with the connector plugged in for example.

 2) afaik, the get_modes ioctl directly calls get_modes too.

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

From heiko at sntech.de  Fri Dec  6 06:35:27 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 06 Dec 2024 15:35:27 +0100
Subject: [PATCH v1 00/10] Add eDP support for RK3588
In-Reply-To: <20241127075157.856029-1-damon.ding@rock-chips.com>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
Message-ID: <5939852.zQ0Gbyo6oJ@diego>

Hi Daemon,

Am Mittwoch, 27. November 2024, 08:51:47 CET schrieb Damon Ding:
> These patchs have been tested with a 1536x2048p60 eDP panel on
> RK3588S EVB1 board, and HDMI 1080P/4K display also has been verified
> on RK3588 EVB1 board.
> 
> Patch 1~3 are the RK3588 eDP support of Rockchip analogix_dp driver.
> Patch 4   is the eDP mode support of samsung hdptx phy driver.
> Patch 5~6 are the Rk3588 eDP support of Aanalogix DP driver. Add phy
>           interfaces is to configure the HDMI/eDP TX Combo PHY.
> Patch 7~8 are the renaming of hdptxphy node. It is not only used by
>           HDMI display but also for the eDP display.
> Patch 9   is the addition of RK3588 eDP0 node.
> Patch 10  is to enable the eDP0 display on RK3588S EVB1 board.

Could you maybe also bring over functionality for real bridge-handling?
That way we'd have support for things like the dp-connector bridge.

In the 6.1 vendor-tree I've found commits
94e598190128 ("drm/rockchip: analogix_dp: Add support for external bridge")
437e0a901b14 ("drm/bridge: analogix_dp: Support split mode for bridge chain")

needing a bit of cleanup of course, but that would get rid of the driver
not handling the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag too.

With a bit of streamlining, we could maybe even get rid of the panel-part
completely, similar to how the dw-dsi controllers do it [0]


Thanks
Heiko

[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c#n335
devm_drm_of_get_bridge() combines drm_of_find_panel_or_bridge()
with devm_drm_panel_bridge_add(), so indepent of it being either a
panel or other bridge, the driver below only needs to handle bridges.

> Damon Ding (10):
>   drm/rockchip: analogix_dp: Use formalized struct definition for grf
>     field
>   dt-bindings: display: rockchip: analogix-dp: Add support for RK3588
>   drm/rockchip: analogix_dp: Add support for RK3588
>   phy: phy-rockchip-samsung-hdptx: Add support for eDP mode
>   drm/bridge: analogix_dp: add support for RK3588
>   drm/bridge: analogix_dp: Add support for phy configuration.
>   dt-bindings: display: rockchip: Fix label name of hdptxphy for RK3588
>     HDMI TX Controller
>   arm64: dts: rockchip: Fix label name of hdptxphy for RK3588
>   arm64: dts: rockchip: Add eDP0 node for RK3588
>   arch64: dts: rockchip: Enable eDP0 display on RK3588S EVB1 board
> 
>  .../rockchip/rockchip,analogix-dp.yaml        |   1 +
>  .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml  |   2 +-
>  arch/arm64/boot/dts/rockchip/rk3588-base.dtsi |  33 +-
>  .../dts/rockchip/rk3588-coolpi-cm5-evb.dts    |   2 +-
>  .../rockchip/rk3588-coolpi-cm5-genbook.dts    |   2 +-
>  .../boot/dts/rockchip/rk3588-evb1-v10.dts     |   2 +-
>  .../rk3588-friendlyelec-cm3588-nas.dts        |   2 +-
>  .../arm64/boot/dts/rockchip/rk3588-jaguar.dts |   2 +-
>  .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi   |   2 +-
>  .../dts/rockchip/rk3588-orangepi-5-plus.dts   |   2 +-
>  .../boot/dts/rockchip/rk3588-rock-5b.dts      |   2 +-
>  .../boot/dts/rockchip/rk3588-tiger-haikou.dts |   2 +-
>  .../boot/dts/rockchip/rk3588s-coolpi-4b.dts   |   2 +-
>  .../boot/dts/rockchip/rk3588s-evb1-v10.dts    |  84 ++
>  .../dts/rockchip/rk3588s-indiedroid-nova.dts  |   2 +-
>  .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi  |   2 +-
>  .../boot/dts/rockchip/rk3588s-odroid-m2.dts   |   2 +-
>  .../boot/dts/rockchip/rk3588s-orangepi-5.dtsi |   2 +-
>  .../boot/dts/rockchip/rk3588s-rock-5a.dts     |   2 +-
>  .../boot/dts/rockchip/rk3588s-rock-5c.dts     |   2 +-
>  .../drm/bridge/analogix/analogix_dp_core.c    |   8 +-
>  .../drm/bridge/analogix/analogix_dp_core.h    |   2 +
>  .../gpu/drm/bridge/analogix/analogix_dp_reg.c |  90 ++
>  .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 112 ++-
>  .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 936 +++++++++++++++++-
>  include/drm/bridge/analogix_dp.h              |   3 +-
>  26 files changed, 1206 insertions(+), 97 deletions(-)
> 
> 






From gregkh at linuxfoundation.org  Fri Dec  6 06:36:37 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Fri,  6 Dec 2024 15:36:37 +0100
Subject: [PATCH 6.12 066/146] perf jevents: fix breakage when do perf stat on system metric
In-Reply-To: <20241206143527.654980698@linuxfoundation.org>
References: <20241206143527.654980698@linuxfoundation.org>
Message-ID: <20241206143530.207302746@linuxfoundation.org>

6.12-stable review patch.  If anyone has any objections, please let me know.

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

From: Xu Yang <xu.yang_2 at nxp.com>

commit 4a159e6049f319bef6f9e6d2ccdd322f57d24830 upstream.

When do perf stat on sys metric, perf tool output nothing now:

  $ perf stat -a -M imx95_ddr_read.all -I 1000
  $

This command runs on an arm64 machine and the Soc has one DDR hw pmu
except one armv8_cortex_a55 pmu. Their maps show as follows:

const struct pmu_events_map pmu_events_map[] = {
{
	.arch = "arm64",
	.cpuid = "0x00000000410fd050",
	.event_table = {
		.pmus = pmu_events__arm_cortex_a55,
		.num_pmus = ARRAY_SIZE(pmu_events__arm_cortex_a55)
	},
	.metric_table = {
		.pmus = NULL,
		.num_pmus = 0
	}
},

static const struct pmu_sys_events pmu_sys_event_tables[] = {
{
	.event_table = {
		.pmus = pmu_events__freescale_imx95_sys,
		.num_pmus = ARRAY_SIZE(pmu_events__freescale_imx95_sys)
	},
	.metric_table = {
		.pmus = pmu_metrics__freescale_imx95_sys,
		.num_pmus = ARRAY_SIZE(pmu_metrics__freescale_imx95_sys)
	},
	.name = "pmu_events__freescale_imx95_sys",
},

Currently, pmu_metrics_table__find() will return NULL when only do perf
stat on sys metric. Then parse_groups() will never be called to parse
sys metric_name, finally perf tool will exit directly. This should be a
common problem.

To fix the issue, this will keep the logic before commit f20c15d13f01
("perf pmu-events: Remember the perf_events_map for a PMU") to return a
empty metric table rather than a NULL pointer.

This should be fine since the removed part just check if the table match
provided metric_name.  Without these code, the code in parse_groups()
will also check the validity of metrci_name too.

Fixes: f20c15d13f017d4b ("perf pmu-events: Remember the perf_events_map for a PMU")
Reviewed-by: James Clark <james.clark at linaro.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
Tested-by: Xu Yang <xu.yang_2 at nxp.com>
Acked-by: Ian Rogers <irogers at google.com>
Cc: Adrian Hunter <adrian.hunter at intel.com>
Cc: Albert Ou <aou at eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Alexandre Ghiti <alexghiti at rivosinc.com>
Cc: Athira Rajeev <atrajeev at linux.vnet.ibm.com>
Cc: Benjamin Gray <bgray at linux.ibm.com>
Cc: Ben Zong-You Xie <ben717 at andestech.com>
Cc: Bibo Mao <maobibo at loongson.cn>
Cc: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
Cc: Dima Kogan <dima at secretsauce.net>
Cc: Dr. David Alan Gilbert <linux at treblig.org>
Cc: Huacai Chen <chenhuacai at kernel.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Jiri Olsa <jolsa at kernel.org>
Cc: John Garry <john.g.garry at oracle.com>
Cc: Kan Liang <kan.liang at linux.intel.com>
Cc: Leo Yan <leo.yan at linux.dev>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Masami Hiramatsu <mhiramat at kernel.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Namhyung Kim <namhyung at kernel.org>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
Cc: Paul Walmsley <paul.walmsley at sifive.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ravi Bangoria <ravi.bangoria at amd.com>
Cc: Sandipan Das <sandipan.das at amd.com>
Cc: Will Deacon <will at kernel.org>
Cc: Yicong Yang <yangyicong at hisilicon.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-riscv at lists.infradead.org
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20241107162035.52206-2-irogers at google.com
Signed-off-by: Ian Rogers <irogers at google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme at redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 tools/perf/pmu-events/empty-pmu-events.c |   12 +-----------
 tools/perf/pmu-events/jevents.py         |   12 +-----------
 2 files changed, 2 insertions(+), 22 deletions(-)

--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -539,17 +539,7 @@ const struct pmu_metrics_table *perf_pmu
         if (!map)
                 return NULL;
 
-        if (!pmu)
-                return &map->metric_table;
-
-        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
-                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
-                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
-
-                if (pmu__name_match(pmu, pmu_name))
-                           return &map->metric_table;
-        }
-        return NULL;
+	return &map->metric_table;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1089,17 +1089,7 @@ const struct pmu_metrics_table *perf_pmu
         if (!map)
                 return NULL;
 
-        if (!pmu)
-                return &map->metric_table;
-
-        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
-                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
-                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
-
-                if (pmu__name_match(pmu, pmu_name))
-                           return &map->metric_table;
-        }
-        return NULL;
+	return &map->metric_table;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)




From gregkh at linuxfoundation.org  Fri Dec  6 06:32:34 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Fri,  6 Dec 2024 15:32:34 +0100
Subject: [PATCH 6.6 335/676] perf cs-etm: Dont flush when packet_queue fills up
In-Reply-To: <20241206143653.344873888@linuxfoundation.org>
References: <20241206143653.344873888@linuxfoundation.org>
Message-ID: <20241206143706.431874993@linuxfoundation.org>

6.6-stable review patch.  If anyone has any objections, please let me know.

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

From: James Clark <james.clark at linaro.org>

[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]

cs_etm__flush(), like cs_etm__sample() is an operation that generates a
sample and then swaps the current with the previous packet. Calling
flush after processing the queues results in two swaps which corrupts
the next sample. Therefore it wasn't appropriate to call flush here so
remove it.

Flushing is still done on a discontinuity to explicitly clear the last
branch buffer, but when the packet_queue fills up before reaching a
timestamp, that's not a discontinuity and the call to
cs_etm__process_traceid_queue() already generated samples and drained
the buffers correctly.

This is visible by looking for a branch that has the same target as the
previous branch and the following source is before the address of the
last target, which is impossible as execution would have had to have
gone backwards:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
   (packet_queue fills here before a timestamp, resulting in a flush and
    branch target ffff80008011cadc is duplicated.)
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

After removing the flush the correct branch target is used for the
second sample, and ffff8000801117c4 is no longer before the previous
address:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

Make sure that a final branch stack is output at the end of the trace
by calling cs_etm__end_block(). This is already done for both the
timeless decode paths.

Fixes: 21fe8dc1191a ("perf cs-etm: Add support for CPU-wide trace scenarios")
Reported-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Closes: https://lore.kernel.org/all/20240719092619.274730-1-gankulkarni at os.amperecomputing.com/
Reviewed-by: Leo Yan <leo.yan at arm.com>
Signed-off-by: James Clark <james.clark at linaro.org>
Tested-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Cc: Ben Gainey <ben.gainey at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Ruidong Tian <tianruidong at linux.alibaba.com>
Cc: Benjamin Gray <bgray at linux.ibm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: coresight at lists.linaro.org
Cc: John Garry <john.g.garry at oracle.com>
Cc: scclevenger at os.amperecomputing.com
Link: https://lore.kernel.org/r/20240916135743.1490403-2-james.clark at linaro.org
Signed-off-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/perf/util/cs-etm.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 9729d006550d9..799c104901b4f 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2412,12 +2412,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
 
 		/* Ignore return value */
 		cs_etm__process_traceid_queue(etmq, tidq);
-
-		/*
-		 * Generate an instruction sample with the remaining
-		 * branchstack entries.
-		 */
-		cs_etm__flush(etmq, tidq);
 	}
 }
 
@@ -2560,7 +2554,7 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)
 
 	while (1) {
 		if (!etm->heap.heap_cnt)
-			goto out;
+			break;
 
 		/* Take the entry at the top of the min heap */
 		cs_queue_nr = etm->heap.heap_array[0].queue_nr;
@@ -2643,6 +2637,23 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)
 		ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp);
 	}
 
+	for (i = 0; i < etm->queues.nr_queues; i++) {
+		struct int_node *inode;
+
+		etmq = etm->queues.queue_array[i].priv;
+		if (!etmq)
+			continue;
+
+		intlist__for_each_entry(inode, etmq->traceid_queues_list) {
+			int idx = (int)(intptr_t)inode->priv;
+
+			/* Flush any remaining branch stack entries */
+			tidq = etmq->traceid_queues[idx];
+			ret = cs_etm__end_block(etmq, tidq);
+			if (ret)
+				return ret;
+		}
+	}
 out:
 	return ret;
 }
-- 
2.43.0





From robdclark at gmail.com  Fri Dec  6 07:18:56 2024
From: robdclark at gmail.com (Rob Clark)
Date: Fri, 6 Dec 2024 07:18:56 -0800
Subject: [PATCH RESEND v17 3/5] iommu/arm-smmu: add support for PRR bit setup
In-Reply-To: <808e1041-0d61-4ee8-9778-0f9b7d0fb719@quicinc.com>
References: <20241114160721.1527934-1-quic_bibekkum@quicinc.com>
 <20241114160721.1527934-4-quic_bibekkum@quicinc.com> <CAF6AEGuwWsAkRyF-h5Aj3KzM7iksb12HsfJ5Ks+-P8hv60MWFg@mail.gmail.com>
 <CAF6AEGvVteuOOMod6yw9_6eOn2PxAx+BR8sVOHAHp7Ts8XigBw@mail.gmail.com>
 <5696afa2-c4ab-42fe-b29a-6ecee622fbb4@quicinc.com> <CAF6AEGuMmdnOmATMy8f+YgGxfrYb5mkG_qgy870wZPebKaZjVQ@mail.gmail.com>
 <04da6036-56c4-4b8c-b75b-b5e96a089efc@quicinc.com> <CAF6AEGt-e_4kGyfiO=_oCLX8E3z76zeZ2MbRe1GicZj4hTEu+g@mail.gmail.com>
 <808e1041-0d61-4ee8-9778-0f9b7d0fb719@quicinc.com>
Message-ID: <CAF6AEGtyc+_2V6qoZCwvRQ_QcC+uCXFXcWRpsQemEfd+rC6R+A@mail.gmail.com>

On Fri, Dec 6, 2024 at 4:36?AM Bibek Kumar Patro
<quic_bibekkum at quicinc.com> wrote:
>
>
>
> On 12/4/2024 8:54 PM, Rob Clark wrote:
> > On Wed, Dec 4, 2024 at 3:28?AM Bibek Kumar Patro
> > <quic_bibekkum at quicinc.com> wrote:
> >>
> >>
> >>
> >> On 11/22/2024 10:04 PM, Rob Clark wrote:
> >>> On Fri, Nov 22, 2024 at 8:20?AM Bibek Kumar Patro
> >>> <quic_bibekkum at quicinc.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 11/21/2024 3:40 AM, Rob Clark wrote:
> >>>>> On Wed, Nov 20, 2024 at 9:17?AM Rob Clark <robdclark at gmail.com> wrote:
> >>>>>>
> >>>>>> On Thu, Nov 14, 2024 at 8:10?AM Bibek Kumar Patro
> >>>>>> <quic_bibekkum at quicinc.com> wrote:
> >>>>>>>
> >>>>>>> Add an adreno-smmu-priv interface for drm/msm to call
> >>>>>>> into arm-smmu-qcom and initiate the PRR bit setup or reset
> >>>>>>> sequence as per request.
> >>>>>>>
> >>>>>>> This will be used by GPU to setup the PRR bit and related
> >>>>>>> configuration registers through adreno-smmu private
> >>>>>>> interface instead of directly poking the smmu hardware.
> >>>>>>>
> >>>>>>> Suggested-by: Rob Clark <robdclark at gmail.com>
> >>>>>>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
> >>>>>>> ---
> >>>>>>>     drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 37 ++++++++++++++++++++++
> >>>>>>>     drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 ++
> >>>>>>>     include/linux/adreno-smmu-priv.h           | 14 ++++++++
> >>>>>>>     3 files changed, 53 insertions(+)
> >>>>>>>
> >>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>>>>> index d26f5aea248e..0e4f3fbda961 100644
> >>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>>>>> @@ -16,6 +16,8 @@
> >>>>>>>
> >>>>>>>     #define QCOM_DUMMY_VAL -1
> >>>>>>>
> >>>>>>> +#define GFX_ACTLR_PRR          (1 << 5)
> >>>>>>> +
> >>>>>>>     static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> >>>>>>>     {
> >>>>>>>            return container_of(smmu, struct qcom_smmu, smmu);
> >>>>>>> @@ -99,6 +101,32 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
> >>>>>>>            arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
> >>>>>>>     }
> >>>>>>>
> >>>>>>> +static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
> >>>>>>> +{
> >>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
> >>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
> >>>>>>> +       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
> >>>>>>> +       u32 reg = 0;
> >>>>>>> +
> >>>>>>> +       reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
> >>>>>>> +       reg &= ~GFX_ACTLR_PRR;
> >>>>>>> +       if (set)
> >>>>>>> +               reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
> >>>>>>> +       arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> +static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
> >>>>>>> +{
> >>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
> >>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
> >>>>>>> +
> >>>>>>> +       writel_relaxed(lower_32_bits(page_addr),
> >>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
> >>>>>>> +
> >>>>>>> +       writel_relaxed(upper_32_bits(page_addr),
> >>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
> >>>>>>> +}
> >>>>>>> +
> >>>>>>>     #define QCOM_ADRENO_SMMU_GPU_SID 0
> >>>>>>>
> >>>>>>>     static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
> >>>>>>> @@ -210,6 +238,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
> >>>>>>>     static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> >>>>>>>                    struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> >>>>>>>     {
> >>>>>>> +       const struct device_node *np = smmu_domain->smmu->dev->of_node;
> >>>>>>>            struct adreno_smmu_priv *priv;
> >>>>>>>
> >>>>>>>            smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
> >>>>>>> @@ -239,6 +268,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> >>>>>>>            priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
> >>>>>>>            priv->set_stall = qcom_adreno_smmu_set_stall;
> >>>>>>>            priv->resume_translation = qcom_adreno_smmu_resume_translation;
> >>>>>>> +       priv->set_prr_bit = NULL;
> >>>>>>> +       priv->set_prr_addr = NULL;
> >>>>>>> +
> >>>>>>> +       if (of_device_is_compatible(np, "qcom,smmu-500") &&
> >>>>>>> +                       of_device_is_compatible(np, "qcom,adreno-smmu")) {
> >>>>>>
> >>>>>> fwiw, it seems like PRR actually works on sc7180, which is _not_
> >>>>>> mmu-500, so I guess the support actually goes back further.
> >>>>>>
> >>>>>> I'm curious if we can just rely on this being supported by any hw that
> >>>>>> has a6xx or newer?
> >>>>>
> >>>>>
> >>>>> Also, unrelated, but we can't assume the smmu is powered when drm
> >>>>> driver calls set_prr_bit/addr, could you add in runpm get/put around
> >>>>> the register access?
> >>>>>
> >>>>
> >>>> I see, thanks for this observation.
> >>>> It's surely a possible case, when they access these registers
> >>>> SMMU state is off.
> >>>> I will add the suggested runpm ops around the register access.
> >>>>
> >>>>> Otherwise Conner and I have vk sparse residency working now
> >>>>>
> >>>>
> >>>> Sorry, could not get this. Did you mean that vk sparse residency
> >>>> is working now using this patch?
> >>>
> >>> Yes, vk sparse residency is working with this patch (plus addition of
> >>> runpm get/put, plus drm/msm patches plus turnip patches) ;-)
> >>>
> >>
> >> Thanks for testing the sparse residency feature with our patch Rob,
> >> I have an additional query regarding the adreno private interfaces.
> >> Specifically, I was referring to other interfaces such as
> >> qcom_adreno_smmu_get_fault_info [1]. It appears that we do not have a
> >> runpm get/put around the register access in this context.
> >
> > get_fault_info() is called from the iommu fault handler callback, so
> > from the fault irq handler, which is why it didn't need the runpm
> > get/put.  Maybe it is bad to make this assumption about usage, but
> > then again adreno_smmu_priv isn't really a general purpose interface.
> >
>
> Ah okay, got it.
> I was just going through all the adreno_smmmu_priv interfaces just
> to get a better understanding of it's interaction with smmu and it seems
> like apart from PRR and get_fault_info(), set_ttbr0_cfg(),
> resume_translation() is also having reg access but not voting.
> Should we put runpm_put/get here as well or these can be excluded.
> <Just curious about the thought process behind this, is it because of
> some sequence when to put a vote, like reg access in middle of smmu
> power cycle and not in beginning or end.>

I think we just haven't needed it, or noticed that we needed it,
outside of setting up prr.

As I mentioned, get_fault_info() is called from the fault irq, so we
know the smmu is already powered.

As far as set_ttbr0_cfg(), it probably works just because
arm_smmu_write_context_bank() ends up getting called again in the
resume path, so if the smmu is suspended when set_ttbr0_cfg() is
called, the writes just get ignored.  But the updated cfg is
re-applied to the hw when it is resumed.  Probably the same situation
with resume_translation().. ie. if the smmu is suspended there are no
translations to resume.

Maybe it would be more correct in set_ttbr0_cfg() and
resume_translation() to do a pm_runtime_get_if_in_use() and skip the
hw writes if the smmu is suspended.

>
> >> Could you please clarify whether we need an SMMU vote around register
> >> access in the case of PRR? IMO, should the users of this callback ensure
> >> they put a vote before accessing the cb?
> >
> > How can drm vote for the smmu device?  I guess it could power up
> > itself and rely on device-link.. but that is pretty overkill to power
> > up the entire gpu in this case.  I think it is best for the vote to
> > happen in the PRR callbacks.
> >
>
> Okay I see, GPU can only power itself up through <gpu_state_get I
> assume> but won't have exclusive access to power on the smmu only.
>
> Incase we go forward to put vote in PRR callback for SMMU, I was
> planning that we can refactor existing arm_smmu_rpm_put/get() from
> arm_smmu.c to it's header file so that the same can be used in
> arm_smmu_qcom.c ? What's your thoughts on this?

I had briefly thought of doing the same.  But the main reason for
those helpers is common arm-smmu code that is used on non-qcom
platforms where runpm is not enabled.  In arm-smmu-qcom.c, we know
that runpm is enabled, so we could just use  return
pm_runtime_resume_and_get()/pm_runtime_put_autosuspend() directly.

BR,
-R

> Thanks & regards,
> Bibek
>
> > BR,
> > -R
> >
> >> [1]:
> >> https://lore.kernel.org/all/20210610214431.539029-1-robdclark at gmail.com/
> >>
> >> Thanks & regards,
> >> Bibek
> >>
> >>> BR,
> >>> -R
> >>>
> >>>> Thanks & regards,
> >>>> Bibek
> >>>>
> >>>>> BR,
> >>>>> -R
> >>>>>
> >>>>>>
> >>>>>>> +               priv->set_prr_bit = qcom_adreno_smmu_set_prr_bit;
> >>>>>>> +               priv->set_prr_addr = qcom_adreno_smmu_set_prr_addr;
> >>>>>>> +       }
> >>>>>>>
> >>>>>>>            return 0;
> >>>>>>>     }
> >>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> >>>>>>> index e2aeb511ae90..2dbf3243b5ad 100644
> >>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> >>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> >>>>>>> @@ -154,6 +154,8 @@ enum arm_smmu_cbar_type {
> >>>>>>>     #define ARM_SMMU_SCTLR_M               BIT(0)
> >>>>>>>
> >>>>>>>     #define ARM_SMMU_CB_ACTLR              0x4
> >>>>>>> +#define ARM_SMMU_GFX_PRR_CFG_LADDR     0x6008
> >>>>>>> +#define ARM_SMMU_GFX_PRR_CFG_UADDR     0x600C
> >>>>>>>
> >>>>>>>     #define ARM_SMMU_CB_RESUME             0x8
> >>>>>>>     #define ARM_SMMU_RESUME_TERMINATE      BIT(0)
> >>>>>>> diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
> >>>>>>> index c637e0997f6d..614665153b3e 100644
> >>>>>>> --- a/include/linux/adreno-smmu-priv.h
> >>>>>>> +++ b/include/linux/adreno-smmu-priv.h
> >>>>>>> @@ -50,6 +50,18 @@ struct adreno_smmu_fault_info {
> >>>>>>>      *                 the GPU driver must call resume_translation()
> >>>>>>>      * @resume_translation: Resume translation after a fault
> >>>>>>>      *
> >>>>>>> + * *CAUTION* : PRR callbacks (set_prr_bit/set_prr_addr) are NULL terminated for
> >>>>>>> + *             targets without PRR support. Exercise caution and verify target
> >>>>>>> + *             capabilities before invoking these callbacks to prevent potential
> >>>>>>> + *             runtime errors or unexpected behavior.
> >>>>>>> + *
> >>>>>>> + * @set_prr_bit:   Extendible interface to be used by GPU to modify the
> >>>>>>> + *                ACTLR register bits, currently used to configure
> >>>>>>> + *                Partially-Resident-Region (PRR) bit for feature's
> >>>>>>> + *                setup and reset sequence as requested.
> >>>>>>> + * @set_prr_addr:  Configure the PRR_CFG_*ADDR register with the
> >>>>>>> + *                physical address of PRR page passed from
> >>>>>>> + *                GPU driver.
> >>>>>>>      *
> >>>>>>>      * The GPU driver (drm/msm) and adreno-smmu work together for controlling
> >>>>>>>      * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
> >>>>>>> @@ -67,6 +79,8 @@ struct adreno_smmu_priv {
> >>>>>>>         void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
> >>>>>>>         void (*set_stall)(const void *cookie, bool enabled);
> >>>>>>>         void (*resume_translation)(const void *cookie, bool terminate);
> >>>>>>> +    void (*set_prr_bit)(const void *cookie, bool set);
> >>>>>>> +    void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
> >>>>>>>     };
> >>>>>>>
> >>>>>>>     #endif /* __ADRENO_SMMU_PRIV_H */
> >>>>>>> --
> >>>>>>> 2.34.1
> >>>>>>>
> >>>>
> >>
>


From pratyush at kernel.org  Fri Dec  6 07:28:42 2024
From: pratyush at kernel.org (Pratyush Yadav)
Date: Fri, 06 Dec 2024 15:28:42 +0000
Subject: [PATCH v4] mtd: spi-nor: atmel: add at25sf321 entry
In-Reply-To: <20241116-spi-nor-v4-1-3de8ac6fd0be@gmail.com> (Marcus
	Folkesson's message of "Sat, 16 Nov 2024 11:55:55 +0100")
References: <20241116-spi-nor-v4-1-3de8ac6fd0be@gmail.com>
Message-ID: <mafs0bjxo4yqd.fsf@kernel.org>

On Sat, Nov 16 2024, Marcus Folkesson wrote:

> Add entry for the at25sf321 32Mbit SPI flash.
>
> This flash is populated on a custom board and was tested at
> 10MHz frequency using the "ti,da830-spi" SPI controller.
>
> Link: https://www.renesas.com/en/document/dst/at25sf321-datasheet?r=1608801
> Reviewed-by: Michael Walle <mwalle at kernel.org>
> Signed-off-by: Marcus Folkesson <marcus.folkesson at gmail.com>

Applied to spi-nor/next. Thanks!

-- 
Regards,
Pratyush Yadav


From Jiaxin.Yu at mediatek.com  Fri Dec  6 07:39:15 2024
From: Jiaxin.Yu at mediatek.com (=?utf-8?B?SmlheGluIFl1ICjkv57lrrbpkasp?=)
Date: Fri, 6 Dec 2024 15:39:15 +0000
Subject: [PATCH v2 1/3] ASoC: hdmi-codec: Add event handler for hdmi TX
In-Reply-To: <00d5c728-3eb9-427a-bc60-5828c20fec09@sirena.org.uk>
References: <Y4Cysgk5Gic5ae9B@sirena.org.uk>
	 <18c82f6f723cd97a9d6b9a7ff16c6ed62fd005d6.camel@mediatek.com>
	 <Y4Y/vEWe3dw0FPQH@sirena.org.uk>
	 <cf9ea98a3263ffb8fc8b542888ad0ad680facfc7.camel@mediatek.com>
	 <Y4jHAJgmz/P58Q/C@sirena.org.uk>
	 <7023a2c7b471d6888d9079563a6c01f22599201f.camel@mediatek.com>
	 <Y43e+EsNCrCpZSIH@sirena.org.uk>
	 <dc50d0b21795acbcc44c77e5fd81e7cb92c65c67.camel@mediatek.com>
	 <Y5ipwqzHKTK8UdlC@sirena.org.uk>
	 <a699178dcef540fff5caae6291983a444886bff6.camel@mediatek.com>
	 <00d5c728-3eb9-427a-bc60-5828c20fec09@sirena.org.uk>
Message-ID: <b44319c9fabbea2e8c333191a0005ef5c4ec6b2c.camel@mediatek.com>

On Mon, 2024-12-02 at 13:16 +0000, Mark Brown wrote:
> On Sun, Dec 01, 2024 at 05:15:45PM +0000, Jiaxin Yu (???) wrote:
> 
> > So I want to ask if I can do it by just adding
> > SOC_DAPM_PIN_SWITCH("Speakers") and SOC_DAPM_PIN_SWITCH("HDMI")?
> > Correspondingly, dapm widget and route path need to be added. That
> > is
> > "SND_SOC_DAPM_SPK("Speakers", NULL)/ SND_SOC_DAPM_LINE("HDMI1",
> > NULL)"
> > and "{"Speakers", NULL, "Speaker"}/ {"HDMI1", NULL, "TX"}".
> 
> Yes, that's what I'd expect to see.

Dear Mark,

So if I open the "HDMI Switch" amixer control, it will call
'hdmi_codec_startup', which in turn calls "audio_startup()"  in
'hdmi_codec_ops'. Conversely, if I close it, it will call
'hdmi_codec_shutdown', which in turn calls 'audio_shutdown' in
'hdmi_codec_ops'. Is this understanding correct?

static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = {
        .probe                          = hdmi_dai_probe,
        .startup                        = hdmi_codec_startup,
        .shutdown                       = hdmi_codec_shutdown,
        .hw_params                      = hdmi_codec_hw_params,
        .prepare                        = hdmi_codec_prepare,
        .set_fmt                        = hdmi_codec_i2s_set_fmt,
        .mute_stream                    = hdmi_codec_mute,
        .pcm_new                        = hdmi_codec_pcm_new,
        .auto_selectable_formats        = &hdmi_codec_formats,
        .num_auto_selectable_formats    = 1,
};

 struct hdmi_codec_ops {
         /*
          * Called when ASoC starts an audio stream setup.
          * Optional
          */
         int (*audio_startup)(struct device *dev, void *data);


         /*
          * Shuts down the audio stream.
          * Mandatory
          */
         void (*audio_shutdown)(struct device *dev, void *data);

From umer.uddin at mentallysanemainliners.org  Fri Dec  6 07:41:49 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 15:41:49 +0000
Subject: [PATCH v5 4/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 (x1slte)
In-Reply-To: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
References: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241206154149.4271-5-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 (x1slte/SM-G980F)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 8GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index 7dbecd367..3405d9e82 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -11,5 +11,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos990-c1s.dtb		\
 	exynos990-r8s.dtb               \
         exynos990-x1s.dtb               \
+        exynos990-x1slte.dtb               \
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Fri Dec  6 07:41:46 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 15:41:46 +0000
Subject: [PATCH v5 1/4] dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
In-Reply-To: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
References: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241206154149.4271-2-umer.uddin@mentallysanemainliners.org>

Add devicetree bindings for Samsung Galaxy S20 5G
and Samsung Galaxy S20 board.

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml         | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 168e77375..fab29f95d 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -241,6 +241,8 @@ properties:
           - enum:
               - samsung,c1s                     # Samsung Galaxy Note20 5G (SM-N981B)
               - samsung,r8s                     # Samsung Galaxy S20 FE (SM-G780F)
+              - samsung,x1s                     # Samsung Galaxy S20 5G (SM-G981B)
+              - samsung,x1slte                  # Samsung Galaxy S20 (SM-G980F)
           - const: samsung,exynos990
 
       - description: Exynos Auto v9 based boards
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Fri Dec  6 07:45:08 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 15:45:08 +0000
Subject: [PATCH v3 3/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
In-Reply-To: <5e3e43eb-3afc-486e-aa9a-4c1074fd30b8@kernel.org>
References: <5e3e43eb-3afc-486e-aa9a-4c1074fd30b8@kernel.org>
Message-ID: <20241206154508.4426-1-umer.uddin@mentallysanemainliners.org>

On 06/12/2024 14:11:28 +0100, Krzysztof Kozlowski wrote:

> Keep the order (sorted).
>
>
> Best regards,
> Krzysztof

Hi Krzysztof, really sorry that had went through, I had seen the error,
but by then it was too late and it was already sent off... I have
sent v5 off though, which should merge properly as the order has been
fixed.

Best Regards,
Umer


From umer.uddin at mentallysanemainliners.org  Fri Dec  6 07:41:45 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 15:41:45 +0000
Subject: [PATCH v5 0/4] Add minimal Samsung Galaxy S20 Series board, SM-G981B and SM-G980F support
Message-ID: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>

Hi folks,

This series adds initial support for the Samsung Galaxy S20 Series and also
initial board support for the Samsung Galaxy S20 5G (SM-G981B)
codenamed x1s.

The S20 Series feature a lot of similarities in their configuration
and internally Samsung named the common devicetrees in their
downstream kernel 'hubble', please note hubble excludes the
S20 FE series and Note20 series. To accommodate this, I've
now named the device tree common's matching the codenames
(x1s-common).
The device trees have been tested with dtbs_check W=1
and results in no warnings.

This initial bringup consists of:
 * pinctrl
 * gpio-keys
 * simple-framebuffer

This is enough to reach a shell in an initramfs. More platform support
will be added in the future.

Just like SM-N981B, the preferred way to boot the upstream kernel is
by using a shim bootloader, called uniLoader [1], which works around
some issues with the stock, non-replacable Samsung S-LK bootloader.
For example, the stock bootloader leaves the decon trigger control
unset, which causes the framebuffer not to refresh.

Device functionality depends on the patch series from Igor Belwon:
"Add minimal Exynos990 SoC and SM-N981B support"

[1] https://github.com/ivoszbg/uniLoader

Changes in v5:
 - Fix dts makefile order

Changes in v4:
 - Rebase from krzk's kernel tree to accommodate
   for the merge of r8s
 - Rename exynos990-hubble-common.dtsi
   to exynos990-x1s-common.dtsi

Changes in v3:
 - Fix oversight in yaml
 - Decommonise memory map

Changes in v2:
 - Add Samsung Galaxy S20 into device tree bindings
 - Add support for Samsung Galaxy S20 as well as the 5G variant now
 - Fix typo in Samsung Galaxy S20 5G commit message

Kind regards,
Umer

Umer Uddin (4):
  dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B
    and SM-G980F board
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series
    boards (hubble)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G
    (x1s)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20
    (x1slte)

 .../bindings/arm/samsung/samsung-boards.yaml  |  2 +
 arch/arm64/boot/dts/exynos/Makefile           |  2 +
 .../boot/dts/exynos/exynos990-x1s-common.dtsi | 98 +++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts  | 28 ++++++
 4 files changed, 130 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts

-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Fri Dec  6 07:41:47 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 15:41:47 +0000
Subject: [PATCH v5 2/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series boards (hubble)
In-Reply-To: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
References: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241206154149.4271-3-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 Series (hubble) phones.
They were launched in 2020, and are based on the Exynos 990 SoC.
The devices have multiple RAM configurations,
starting from 8GB going all the way up to 16GB for the S20 Ultra devices.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM (Any more will be mapped in device trees)
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../boot/dts/exynos/exynos990-x1s-common.dtsi | 98 +++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi

diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
new file mode 100644
index 000000000..55fa8e9e0
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 Series device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		framebuffer0: framebuffer at f1000000 {
+			compatible = "simple-framebuffer";
+			reg = <0 0xf1000000 0 (1440 * 3200 * 4)>;
+			width = <1440>;
+			height = <3200>;
+			stride = <(1440 * 4)>;
+			format = "a8r8g8b8";
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		cont_splash_mem: framebuffer at f1000000 {
+			reg = <0 0xf1000000 0 0x1194000>;
+			no-map;
+		};
+
+		abox_reserved: audio at f7fb0000 {
+			reg = <0 0xf7fb0000 0 0x2a50000>;
+			no-map;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&key_power &key_voldown &key_volup>;
+		pinctrl-names = "default";
+
+		power-key {
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpa2 4 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+
+		voldown-key {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			gpios = <&gpa0 4 GPIO_ACTIVE_LOW>;
+		};
+
+		volup-key {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&oscclk {
+	clock-frequency = <26000000>;
+};
+
+&pinctrl_alive {
+	key_power: key-power-pins {
+		samsung,pins = "gpa2-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_voldown: key-voldown-pins {
+		samsung,pins = "gpa0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_volup: key-volup-pins {
+		samsung,pins = "gpa0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Fri Dec  6 07:41:48 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 15:41:48 +0000
Subject: [PATCH v5 3/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
In-Reply-To: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
References: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241206154149.4271-4-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 5G (x1s/SM-G981B)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 12GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 12GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile          |  1 +
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts | 28 ++++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index 948a2c6cb..7dbecd367 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -10,5 +10,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos8895-dreamlte.dtb		\
 	exynos990-c1s.dtb		\
 	exynos990-r8s.dtb               \
+        exynos990-x1s.dtb               \
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s.dts b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
new file mode 100644
index 000000000..1ae881015
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 5G (x1s/SM-G981B) device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990-x1s-common.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	model = "Samsung Galaxy S20 5G";
+	compatible = "samsung,x1s", "samsung,exynos990";
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x3ab00000>,
+		      /* Memory hole */
+		      <0x0 0xc1200000 0x0 0x1ee00000>,
+		      /* Memory hole */
+		      <0x0 0xe1900000 0x0 0x1e700000>,
+		      /* Memory hole */
+		      <0x8 0x80000000 0x2 0x7e800000>;
+	};
+};
-- 
2.47.1



From foss+kernel at 0leil.net  Fri Dec  6 07:46:17 2024
From: foss+kernel at 0leil.net (Quentin Schulz)
Date: Fri, 06 Dec 2024 16:46:17 +0100
Subject: [PATCH] arm64: dts: rockchip: minimal support for Pre-ICT tester
 adapter for RK3588 Jaguar
Message-ID: <20241206-pre-ict-jaguar-v1-1-7f660bd4b70c@cherry.de>

From: Quentin Schulz <quentin.schulz at cherry.de>

The Pre-ICT tester adapter connects to RK3588 Jaguar SBC through its
proprietary Mezzanine connector.

It exposes a PCIe Gen2 1x M.2 connector and two proprietary camera
connectors. Support for the latter will come once the rest of the camera
stack is supported.

Additionally, the adapter loops some GPIOs together as well as route
some GPIOs to power rails.

This adapter is used for manufacturing RK3588 Jaguar to be able to test
the Mezzanine connector is properly soldered.

Signed-off-by: Quentin Schulz <quentin.schulz at cherry.de>
---
GPIO3A3, GPIO3A4, GPIO3B2 and GPIO3D2 to GPIO3D5 are all routed to power
rails and can only be used as input and their bias are important to be
able to properly detect soldering issues.
---
 arch/arm64/boot/dts/rockchip/Makefile              |   1 +
 .../dts/rockchip/rk3588-jaguar-pre-ict-tester.dtso | 171 +++++++++++++++++++++
 2 files changed, 172 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 86cc418a2255cdc22f1d503e9519d2d9572d4e9d..60074d21d92b4800bdc555648a9360e13d19febc 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -139,6 +139,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-friendlyelec-cm3588-nas.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar-pre-ict-tester.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6-lts.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-ok3588-c.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-jaguar-pre-ict-tester.dtso b/arch/arm64/boot/dts/rockchip/rk3588-jaguar-pre-ict-tester.dtso
new file mode 100644
index 0000000000000000000000000000000000000000..9d44dfe2f30d793accb994a230c58038f0c3daad
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-jaguar-pre-ict-tester.dtso
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2024 Cherry Embedded Solutions GmbH
+ *
+ * Device Tree Overlay for the Pre-ICT tester adapter for the Mezzanine
+ * connector on RK3588 Jaguar.
+ *
+ * This adapter has a PCIe Gen2 x1 M.2 M-Key connector and two proprietary
+ * camera connectors (each their own I2C bus, clock, reset and PWM lines as well
+ * as 2-lane CSI).
+ *
+ * This adapter routes some GPIOs to power rails and loops together some other
+ * GPIOs.
+ *
+ * This adapter is used during manufacturing for validating proper soldering of
+ * the mezzanine connector.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+&{/} {
+	pre_ict_tester_vcc_1v2: regulator-pre-ict-tester-vcc-1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "pre_ict_tester_vcc_1v2";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	pre_ict_tester_vcc_2v8: regulator-pre-ict-tester-vcc-2v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "pre_ict_tester_vcc_2v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+};
+
+&combphy0_ps {
+	status = "okay";
+};
+
+&gpio3 {
+	pinctrl-0 = <&pre_ict_pwr2gpio>;
+	pinctrl-names = "default";
+};
+
+&pcie2x1l2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2x1l2_perstn_m0>;
+	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; /* PCIE20X1_2_PERSTN_M0 */
+	vpcie3v3-supply = <&vcc_3v3_s3>;
+	status = "okay";
+};
+
+&pinctrl {
+	pcie2x1l2 {
+		pcie2x1l2_perstn_m0: pcie2x1l2-perstn-m0 {
+			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pre-ict-tester {
+		pre_ict_pwr2gpio: pre-ict-pwr2gpio-pins {
+			rockchip,pins =
+			/*
+			 * GPIO3_A3 requires two power rails to be properly
+			 * routed to the mezzanine connector to report a proper
+			 * value: VCC_1V8_S0_1 and VCC_IN_2. It may report an
+			 * incorrect value if VCC_1V8_S0_1 isn't properly routed,
+			 * but GPIO3_C6 would catch this HW soldering issue.
+			 * If VCC_IN_2 is properly routed, GPIO3_A3 should be
+			 * LOW. The signal shall not read HIGH in the event
+			 * GPIO3_A3 isn't properly routed due to soldering
+			 * issue. Therefore, let's enforce a pull-up (which is
+			 * the SoC default for this pin).
+			 */
+				<3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>,
+			/*
+			 * GPIO3_A4 is directly routed to VCC_1V8_S0_2 power
+			 * rail. It should be HIGH if all is properly soldered.
+			 * To guarantee that, a pull-down is enforced (which is
+			 * the SoC default for this pin) so that LOW is read if
+			 * the loop doesn't exist on HW (soldering issue on
+			 * either signals).
+			 */
+				<3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>,
+			/*
+			 * GPIO3_B2 requires two power rails to be properly
+			 * routed to the mezzanine connector to report a proper
+			 * value: VCC_1V8_S0_1 and VCC_IN_1. It may report an
+			 * incorrect value if VCC_1V8_S0_1 isn't properly routed,
+			 * but GPIO3_C6 would catch this HW soldering issue.
+			 * If VCC_IN_1 is properly routed, GPIO3_B2 should be
+			 * LOW. This is an issue if GPIO3_B2 isn't properly
+			 * routed due to soldering issue, because GPIO3_B2
+			 * default bias is pull-down therefore being LOW. So
+			 * the worst case scenario and the pass scenario expect
+			 * the same value. Make GPIO3_B2 a pull-up so that a
+			 * soldering issue on GPIO3_B2 reports HIGH but proper
+			 * soldering reports LOW.
+			 */
+				<3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>,
+			/*
+			 * GPIO3_C6 is directly routed to VCC_1V8_S0_1 power
+			 * rail. It should be HIGH if all is properly soldered.
+			 * This is an issue if GPIO3_C6 or VCC_1V8_S0_1 isn't
+			 * properly routed due to soldering issue, because
+			 * GPIO3_C6 default bias is pull-up therefore being HIGH
+			 * in all cases:
+			 *  - GPIO3_C6 is floating (so HIGH) if GPIO3_C6 is not
+			 *    routed properly,
+			 *  - GPIO3_C6 is floating (so HIGH) if VCC_1V8_S0_1 is
+			 *    not routed properly,
+			 *  - GPIO3_C6 is HIGH if everything is proper,
+			 * Make GPIO3_C6 a pull-down so that a soldering issue
+			 * on GPIO3_C6 or VCC_1V8_S0_1 reports LOW but proper
+			 * soldering reports HIGH.
+			 */
+				<3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>,
+			/*
+			 * GPIO3_D2 is routed to VCC_5V0_1 power rail through a
+			 * voltage divider on the adapter.
+			 * It should be HIGH if all is properly soldered.
+			 * To guarantee that, a pull-down is enforced (which is
+			 * the SoC default for this pin) so that LOW is read if
+			 * the loop doesn't exist on HW (soldering issue on
+			 * either signals).
+			 */
+				<3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_down>,
+			/*
+			 * GPIO3_D3 is routed to VCC_5V0_2 power rail through a
+			 * voltage divider on the adapter.
+			 * It should be HIGH if all is properly soldered.
+			 * To guarantee that, a pull-down is enforced (which is
+			 * the SoC default for this pin) so that LOW is read if
+			 * the loop doesn't exist on HW (soldering issue on
+			 * either signals).
+			 */
+				<3 RK_PD3 RK_FUNC_GPIO &pcfg_pull_down>,
+			/*
+			 * GPIO3_D4 is routed to VCC_3V3_S3_1 power rail through
+			 * a voltage divider on the adapter.
+			 * It should be HIGH if all is properly soldered.
+			 * To guarantee that, a pull-down is enforced (which is
+			 * the SoC default for this pin) so that LOW is read if
+			 * the loop doesn't exist on HW (soldering issue on
+			 * either signals).
+			 */
+				<3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_down>,
+			/*
+			 * GPIO3_D5 is routed to VCC_3V3_S3_2 power rail through
+			 * a voltage divider on the adapter.
+			 * It should be HIGH if all is properly soldered.
+			 * To guarantee that, a pull-down is enforced (which is
+			 * the SoC default for this pin) so that LOW is read if
+			 * the loop doesn't exist on HW (soldering issue on
+			 * either signals).
+			 */
+				<3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+};

---
base-commit: b8f52214c61a5b99a54168145378e91b40d10c90
change-id: 20241206-pre-ict-jaguar-b90fafee8bd8

Best regards,
-- 
Quentin Schulz <quentin.schulz at cherry.de>



From mailhol.vincent at wanadoo.fr  Thu Dec  5 20:42:56 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 13:42:56 +0900
Subject: [PATCH 01/10] compiler.h: add statically_false()
In-Reply-To: <b48e2f5dd8d64cbab471629ae03c7511@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-1-4e4cbaecc216@wanadoo.fr>
 <e115a4245e5342a994a7e596cc6357fa@AcuMS.aculab.com> <CAMZ6Rq+n0vG9zObF-kY-Xo+iP_Y3P8A6_nEfB8F=UhqeQBepRw@mail.gmail.com>
 <b48e2f5dd8d64cbab471629ae03c7511@AcuMS.aculab.com>
Message-ID: <CAMZ6RqKUH5VGHAuqv+dR_0o1JFTvV_gNV2qUwoMfcWCQUSX2Lg@mail.gmail.com>

On Fri. 6 Dec. 2024 at 12:39, David Laight <David.Laight at aculab.com> wrote:
> From: Vincent Mailhol
> > Sent: 05 December 2024 15:26
> >
> > On Thu. 5 Dec 2024 at 03:30, David Laight <David.Laight at aculab.com> wrote:
> > > From: Vincent Mailhol
> > > > Sent: 02 December 2024 17:33
> > > >
> > > > From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> > > >
> > > > For completion, add statically_false() which is the equivalent of
> > > > statically_true() except that it will return true only if the input is
> > > > known to be false at compile time.
> > >
> > > This is pretty much pointless.
> > > It is just as easy to invert the condition at the call site.
> >
> > To start with, I will argue that:
> >
> >   statically_false(foo)
> >
> > is more pretty than
> >
> >   statically_true(!(foo))
>
> Except that the test is more likely to be:
>         statically_false(x > y)
> and the invert is then
>         statically_true(x <= y)
>
> No different from C itself, there is no 'ifnot (condition) {...}'
> (don't talk to me about perl...)

No need to talk about perl, just staying in C, it has both the #ifdef
and the #ifndef directives (and since C23, it even has the #elifndef).

Regardless, this was just a nitpick. You convinced me, I will remove
both statically_false() and is_const_false() in v2.

> I suspect you need to pretty much remove all the comments that
> cross-refer to statically_true() from the other patches.
>
> So is_const_true() is just 'return true if the expression
> is a 'non-zero constant integer expression'.

No. Linus made it clear in

  https://lore.kernel.org/all/CAHk-=wh5SNYdgx8-X+ggHP+ojbG2F7oyt3TLmMgqejYd5zn0Aw at mail.gmail.com/

that we need an explanation of why statically_true() may not work in
some contexts and I agree with this.

As far as I like using proper nuances between the terms 'integer
constant expression' and 'compile time constant', treating
statically_true() and is_const_true() as completely different things
as you are suggesting is not constructive. At the end, what matters
the most in a comment, is that the final user properly understands how
to use the thing correctly.

Removing the cross reference would increase the risk of people using
is_const_true() in places where it is not needed. I will keep the
cross reference to statically_true().


Yours sincerely,
Vincent Mailhol


From thierry.reding at gmail.com  Fri Dec  6 08:01:01 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 6 Dec 2024 17:01:01 +0100
Subject: [PATCH v1 1/1] net: stmmac: dwmac-tegra: Read iommu stream id
 from device tree
In-Reply-To: <20241206084203.2502ab95.parker@finest.io>
References: <bb52bdc1-df2e-493d-a58f-df3143715150@lunn.ch>
 <20241118084400.35f4697a.parker@finest.io>
 <984a8471-7e49-4549-9d8a-48e1a29950f6@lunn.ch>
 <20241119131336.371af397.parker@finest.io>
 <f00bccd3-62d5-46a9-b448-051894267c7a@lunn.ch>
 <20241119144729.72e048a5.parker@finest.io>
 <mpgilwqb5zg5kb4n7r6zwbhy4uutdh6rq5s2yc6ndhcj6gqgri@qkfr4qwjj3ym>
 <20241204115317.008f497c.parker@finest.io>
 <uad6id6omswjm7e4eqwd75c52sy5pddtxru3bcuxlukhecvj4u@klzgrws24r2q>
 <20241206084203.2502ab95.parker@finest.io>
Message-ID: <vyzrfrkvwwbi66zemgjywdzpk75mebr47vxaon5jwnn2vprahl@ndzjlez3ywgv>

On Fri, Dec 06, 2024 at 08:42:03AM -0500, Parker Newman wrote:
> On Wed, 4 Dec 2024 19:06:30 +0100
> Thierry Reding <thierry.reding at gmail.com> wrote:
> 
> > On Wed, Dec 04, 2024 at 11:53:17AM -0500, Parker Newman wrote:
> > > On Wed, 4 Dec 2024 17:23:53 +0100
> > > Thierry Reding <thierry.reding at gmail.com> wrote:
> > >
> > > > On Tue, Nov 19, 2024 at 02:47:29PM -0500, Parker Newman wrote:
> > > > > On Tue, 19 Nov 2024 20:18:00 +0100
> > > > > Andrew Lunn <andrew at lunn.ch> wrote:
> > > > >
> > > > > > > I think there is some confusion here. I will try to summarize:
> > > > > > > - Ihe iommu is supported by the Tegra SOC.
> > > > > > > - The way the mgbe driver is written the iommu DT property is REQUIRED.
> > > > > >
> > > > > > If it is required, please also include a patch to
> > > > > > nvidia,tegra234-mgbe.yaml and make iommus required.
> > > > > >
> > > > >
> > > > > I will add this when I submit a v2 of the patch.
> > > > >
> > > > > > > - "iommus" is a SOC DT property and is defined in tegra234.dtsi.
> > > > > > > - The mgbe device tree nodes in tegra234.dtsi DO have the iommus property.
> > > > > > > - There are no device tree changes required to to make this patch work.
> > > > > > > - This patch works fine with existing device trees.
> > > > > > >
> > > > > > > I will add the fallback however in case there is changes made to the iommu
> > > > > > > subsystem in the future.
> > > > > >
> > > > > > I would suggest you make iommus a required property and run the tests
> > > > > > over the existing .dts files.
> > > > > >
> > > > > > I looked at the history of tegra234.dtsi. The ethernet nodes were
> > > > > > added in:
> > > > > >
> > > > > > 610cdf3186bc604961bf04851e300deefd318038
> > > > > > Author: Thierry Reding <treding at nvidia.com>
> > > > > > Date:   Thu Jul 7 09:48:15 2022 +0200
> > > > > >
> > > > > >     arm64: tegra: Add MGBE nodes on Tegra234
> > > > > >
> > > > > > and the iommus property is present. So the requires is safe.
> > > > > >
> > > > > > Please expand the commit message. It is clear from all the questions
> > > > > > and backwards and forwards, it does not provide enough details.
> > > > > >
> > > > >
> > > > > I will add more details when I submit V2.
> > > > >
> > > > > > I just have one open issue. The code has been like this for over 2
> > > > > > years. Why has it only now started crashing?
> > > > > >
> > > > >
> > > > > It is rare for Nvidia Jetson users to use the mainline kernel. Nvidia
> > > > > provides a custom kernel package with many out of tree drivers including a
> > > > > driver for the mgbe controllers.
> > > > >
> > > > > Also, while the Orin AGX SOC (tegra234) has 4 instances of the mgbe controller,
> > > > > the Nvidia Orin AGX devkit only uses mgbe0. Connect Tech has carrier boards
> > > > > that use 2 or more of the mgbe controllers which is why we found the bug.
> > > >
> > > > Correct. Also, this was a really stupid thing that I overlooked. I don't
> > > > recall the exact circumstances, but I vaguely recall there had been
> > > > discussions about adding the tegra_dev_iommu_get_stream_id() helper
> > > > (that this patch uses) around the time that this driver was created. In
> > > > the midst of all of this I likely forgot to update the driver after the
> > > > discussions had settled.
> > > >
> > > > Anyway, I agree with the conclusion that we don't need a compatibility
> > > > fallback for this, both because it would be actively wrong to do it and
> > > > we've had the required IOMMU properties in device tree since the start,
> > > > so there can't be any regressions caused by this.
> > > >
> > > > I don't think it's necessary to make the iommus property required,
> > > > though, because there's technically no requirement for these devices to
> > > > be attached to an IOMMU. They usually are, and it's better if they are,
> > > > but they should be able to work correctly without an IOMMU.
> > > >
> > > Thanks for confirming from the Nvidia side! I wasn't sure if they would
> > > work without the iommu. That said, if you did NOT want to use the iommu
> > > and removed the iommu DT property then the probe will fail after my patch.
> > > Would we not need a guard around the writes to MGBE_WRAP_AXI_ASID0_CTRL as well?
> >
> > Well... frankly, I don't know. There's an override in the memory
> > controller which we set when a device is attached to an IOMMU. That's
> > usually how the stream ID is programmed. If we don't do that it will
> > typically default to a special passthrough stream ID (technically the
> > firmware can lock down those register and force them to a specific
> > stream ID all the time). I'm not sure what exactly the impact is of
> > these ASID registers (there's a few other instances where those are
> > needed). They are required if you want to use the IOMMU, but I don't
> > know what their meaning is if the IOMMU is not enabled.
> >
> > There's also different cases: the IOMMU can be disabled altogether, in
> > which case no page tables and such exist for any device and no
> > translation should happen whatsoever. But there's also the case where an
> > IOMMU is enabled, but certain devices shouldn't attach to them. I should
> > make it very clear that both of these are not recommended setups and I
> > don't know if they'll work. And they are mostly untested. I've been
> > meaning, but haven't found the time, to test some of these cases.
> >
> 
> Yes I agree, all of those situations are very niche and not recommended for
> a Tegra platform that should always have the iommu enabled anyways. Adding an
> iommu bypass would probably be outside of the scope of this patch.
> 
> I will not add a patch marking the iommu as required in the device tree
> bindings when I submit v2 unless anyone else feels different.

I was able to find a bit more information on this. Starting with
Tegra234 it's usually no longer possible to even enable bypass. It can
still be done, but it needs to be carefully coordinated between the
secure bootloader/firmware and the OS. Basically the secure firmware
can lock down the ability to bypass the IOMMU. If the firmware was
configured to allow bypass, the driver can then do so by writing the
special stream ID 0x7f into the stream ID register.

On these newer chips the memory controller override no longer has any
effect and writing the per-device stream ID registers is the only way to
attach to the IOMMU.

There's still the case where you can disable the IOMMU altogether, in
which case the IOMMU will still be bypassed, no matter what the firmware
did. My understanding is that it doesn't matter in those cases whether
we write the stream ID registers or not, they will simply get ignored.
With one exception perhaps being the bypass SID. If you write that, then
there's a protection mechanism that kicks in.

Well, after all this this still isn't entirely clear to me, but I think
what it means in a nutshell is that a) we'll want to keep the IOMMU
always on for security and because the firmware is by default configured
to not allow bypassing, b) IOMMU isn't strictly required because the
IOMMU might be completely disabled and c) we shouldn't need to
conditionalize the stream ID register writes.

That said, the tegra_dev_iommu_get_stream_id() function returns a bool
specifically to support the latter case. So the intention with the
design was that drivers would call that function and only need to write
the stream ID register if it returns true. That's not always great
because you may want (or need) to rewrite the register after suspend/
resume, in which case you probably want to resort to a cached value
rather than call that API. On the other hand the API is quite simple, so
it could serve as a cache as well.

Meh.

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/20241206/d911e1d5/attachment.sig>

From p.zabel at pengutronix.de  Fri Dec  6 08:03:59 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Fri, 06 Dec 2024 17:03:59 +0100
Subject: [PATCH 0/2] Add support for A1 SoC in auxiliary reset driver
In-Reply-To: <20241112230056.1406222-1-jan.dakinevich@salutedevices.com>
References: <20241112230056.1406222-1-jan.dakinevich@salutedevices.com>
Message-ID: <036d3c0e721947002dc598aef2b65d48967ab52e.camel@pengutronix.de>

On Mi, 2024-11-13 at 02:00 +0300, Jan Dakinevich wrote:
> This was a part of series [1]. Comparing to original series, reset functionality
> on top of 'audio-vad' clock controller also is added.
> 
> Links:
>   [1] https://lore.kernel.org/all/20240913121152.817575-1-jan.dakinevich at salutedevices.com/
> 
> Jan Dakinevich (2):
>   dt-bindings: reset: add bindings for A1 SoC audio reset controller
>   reset: amlogic: add support for A1 SoC in auxiliary reset driver
[...]

Applied to reset/next, thanks!

[1/2] dt-bindings: reset: add bindings for A1 SoC audio reset
controller
      https://git.pengutronix.de/cgit/pza/linux/commit/?id=3465a696bd93
[2/2] reset: amlogic: add support for A1 SoC in auxiliary reset driver
      https://git.pengutronix.de/cgit/pza/linux/commit/?id=3d99f9231bed

regards
Philipp


From broonie at kernel.org  Fri Dec  6 08:06:45 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 6 Dec 2024 16:06:45 +0000
Subject: [PATCH v2 1/3] ASoC: hdmi-codec: Add event handler for hdmi TX
In-Reply-To: <b44319c9fabbea2e8c333191a0005ef5c4ec6b2c.camel@mediatek.com>
References: <Y4Y/vEWe3dw0FPQH@sirena.org.uk>
 <cf9ea98a3263ffb8fc8b542888ad0ad680facfc7.camel@mediatek.com>
 <Y4jHAJgmz/P58Q/C@sirena.org.uk>
 <7023a2c7b471d6888d9079563a6c01f22599201f.camel@mediatek.com>
 <Y43e+EsNCrCpZSIH@sirena.org.uk>
 <dc50d0b21795acbcc44c77e5fd81e7cb92c65c67.camel@mediatek.com>
 <Y5ipwqzHKTK8UdlC@sirena.org.uk>
 <a699178dcef540fff5caae6291983a444886bff6.camel@mediatek.com>
 <00d5c728-3eb9-427a-bc60-5828c20fec09@sirena.org.uk>
 <b44319c9fabbea2e8c333191a0005ef5c4ec6b2c.camel@mediatek.com>
Message-ID: <6456e0b7-08ae-4515-a7c9-734f50c9130a@sirena.org.uk>

On Fri, Dec 06, 2024 at 03:39:15PM +0000, Jiaxin Yu (???) wrote:
> On Mon, 2024-12-02 at 13:16 +0000, Mark Brown wrote:
> > On Sun, Dec 01, 2024 at 05:15:45PM +0000, Jiaxin Yu (???) wrote:

> > > So I want to ask if I can do it by just adding
> > > SOC_DAPM_PIN_SWITCH("Speakers") and SOC_DAPM_PIN_SWITCH("HDMI")?
> > > Correspondingly, dapm widget and route path need to be added. That
> > > is
> > > "SND_SOC_DAPM_SPK("Speakers", NULL)/ SND_SOC_DAPM_LINE("HDMI1",
> > > NULL)"
> > > and "{"Speakers", NULL, "Speaker"}/ {"HDMI1", NULL, "TX"}".

> > Yes, that's what I'd expect to see.

> So if I open the "HDMI Switch" amixer control, it will call
> 'hdmi_codec_startup', which in turn calls "audio_startup()"  in
> 'hdmi_codec_ops'. Conversely, if I close it, it will call
> 'hdmi_codec_shutdown', which in turn calls 'audio_shutdown' in
> 'hdmi_codec_ops'. Is this understanding correct?

The audio stream will still run, the DAPM path attached to it will get
shut down.
-------------- 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/20241206/b1f3e713/attachment.sig>

From igor.belwon at mentallysanemainliners.org  Fri Dec  6 08:12:18 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Fri, 06 Dec 2024 17:12:18 +0100
Subject: [PATCH v2 1/3] dt-bindings: clock: Add Exynos990 SoC CMU bindings
In-Reply-To: <20241206-exynos990-cmu-v2-0-4666ff0a099b@mentallysanemainliners.org>
References: <20241206-exynos990-cmu-v2-0-4666ff0a099b@mentallysanemainliners.org>
Message-ID: <20241206-exynos990-cmu-v2-1-4666ff0a099b@mentallysanemainliners.org>

Add dt-schema documentation for the Exynos990 SoC CMU.

This clock management unit has a topmost block (CMU_TOP)
that generates top clocks for other blocks. Currently the
only other block implemented is CMU_HSI0, which provides
clocks for the USB part of the SoC.

Also, device-tree binding definitions added for these blocks:
- CMU_TOP
- CMU_HSI0

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 .../bindings/clock/samsung,exynos990-clock.yaml    | 120 +++++++++++
 include/dt-bindings/clock/samsung,exynos990.h      | 236 +++++++++++++++++++++
 2 files changed, 356 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..36d70d6d1b30fa629d5d60677851fb915934efa3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos990-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos990 SoC clock controller
+
+maintainers:
+  - Igor Belwon <igor.belwon at mentallysanemainliners.org>
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzk at kernel.org>
+
+description: |
+  Exynos990 clock controller is comprised of several CMU units, generating
+  clocks for different domains. Those CMU units are modeled as separate device
+  tree nodes, and might depend on each other. The root clock in that root tree
+  is an external clock: OSCCLK (26 MHz). This external clock must be defined
+  as a fixed-rate clock in dts.
+
+  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
+  dividers; all other clocks of function blocks (other CMUs) are usually
+  derived from CMU_TOP.
+
+  Each clock is assigned an identifier and client nodes can use this identifier
+  to specify the clock which they consume. All clocks available for usage
+  in clock consumer nodes are defined as preprocessor macros in
+  'include/dt-bindings/clock/samsung,exynos990.h' header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos990-cmu-hsi0
+      - samsung,exynos990-cmu-top
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - reg
+  - "#clock-cells"
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos990-cmu-hsi0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_HSI0 BUS clock (from CMU_TOP)
+            - description: CMU_HSI0 USB31DRD clock (from CMU_TOP)
+            - description: CMU_HSI0 USBDP_DEBUG clock (from CMU_TOP)
+            - description: CMU_HSI0 DPGTC clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_cmu_hsi0_bus
+            - const: dout_cmu_hsi0_usb31drd
+            - const: dout_cmu_hsi0_usbdp_debug
+            - const: dout_cmu_hsi0_dpgtc
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos990-cmu-top
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+
+        clock-names:
+          items:
+            - const: oscclk
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/samsung,exynos990.h>
+
+    cmu_hsi0: clock-controller at 10a00000 {
+        compatible = "samsung,exynos990-cmu-hsi0";
+        reg = <0x10a00000 0x8000>;
+        #clock-cells = <1>;
+
+        clocks = <&oscclk>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
+        clock-names = "oscclk", "dout_cmu_hsi0_bus",
+                                "dout_cmu_hsi0_usb31drd",
+                                "dout_cmu_hsi0_usbdp_debug",
+                                "dout_cmu_hsi0_dpgtc";
+    };
+
+...
diff --git a/include/dt-bindings/clock/samsung,exynos990.h b/include/dt-bindings/clock/samsung,exynos990.h
new file mode 100644
index 0000000000000000000000000000000000000000..307215a3f3eddd579e6733b51a777fb45398bb92
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,exynos990.h
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2024 Igor Belwon <igor.belwon at mentallysanemainliners.org>
+ *
+ * Device Tree binding constants for Exynos990 clock controller.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_EXYNOS_990_H
+#define _DT_BINDINGS_CLOCK_EXYNOS_990_H
+
+/* CMU_TOP */
+#define CLK_FOUT_SHARED0_PLL		1
+#define CLK_FOUT_SHARED1_PLL		2
+#define CLK_FOUT_SHARED2_PLL		3
+#define CLK_FOUT_SHARED3_PLL		4
+#define CLK_FOUT_SHARED4_PLL		5
+#define CLK_FOUT_G3D_PLL		6
+#define CLK_FOUT_MMC_PLL		7
+#define CLK_MOUT_PLL_SHARED0		8
+#define CLK_MOUT_PLL_SHARED1		9
+#define CLK_MOUT_PLL_SHARED2		10
+#define CLK_MOUT_PLL_SHARED3		11
+#define CLK_MOUT_PLL_SHARED4		12
+#define CLK_MOUT_PLL_MMC		13
+#define CLK_MOUT_PLL_G3D		14
+#define CLK_MOUT_CMU_APM_BUS		15
+#define CLK_MOUT_CMU_AUD_CPU		16
+#define CLK_MOUT_CMU_BUS0_BUS		17
+#define CLK_MOUT_CMU_BUS1_BUS		18
+#define CLK_MOUT_CMU_BUS1_SSS		19
+#define CLK_MOUT_CMU_CIS_CLK0		20
+#define CLK_MOUT_CMU_CIS_CLK1		21
+#define CLK_MOUT_CMU_CIS_CLK2		22
+#define CLK_MOUT_CMU_CIS_CLK3		23
+#define CLK_MOUT_CMU_CIS_CLK4		24
+#define CLK_MOUT_CMU_CIS_CLK5		25
+#define CLK_MOUT_CMU_CMU_BOOST		26
+#define CLK_MOUT_CMU_CORE_BUS		27
+#define CLK_MOUT_CMU_CPUCL0_DBG_BUS	28
+#define CLK_MOUT_CMU_CPUCL0_SWITCH	29
+#define CLK_MOUT_CMU_CPUCL1_SWITCH	30
+#define CLK_MOUT_CMU_CPUCL2_BUSP	31
+#define CLK_MOUT_CMU_CPUCL2_SWITCH	32
+#define CLK_MOUT_CMU_CSIS_BUS		33
+#define CLK_MOUT_CMU_CSIS_OIS_MCU	34
+#define CLK_MOUT_CMU_DNC_BUS		35
+#define CLK_MOUT_CMU_DNC_BUSM		36
+#define CLK_MOUT_CMU_DNS_BUS		37
+#define CLK_MOUT_CMU_DPU		38
+#define CLK_MOUT_CMU_DPU_ALT		39
+#define CLK_MOUT_CMU_DSP_BUS		40
+#define CLK_MOUT_CMU_G2D_G2D		41
+#define CLK_MOUT_CMU_G2D_MSCL		42
+#define CLK_MOUT_CMU_HPM		43
+#define CLK_MOUT_CMU_HSI0_BUS		44
+#define CLK_MOUT_CMU_HSI0_DPGTC		45
+#define CLK_MOUT_CMU_HSI0_USB31DRD	46
+#define CLK_MOUT_CMU_HSI0_USBDP_DEBUG	47
+#define CLK_MOUT_CMU_HSI1_BUS		48
+#define CLK_MOUT_CMU_HSI1_MMC_CARD	49
+#define CLK_MOUT_CMU_HSI1_PCIE		50
+#define CLK_MOUT_CMU_HSI1_UFS_CARD	51
+#define CLK_MOUT_CMU_HSI1_UFS_EMBD	52
+#define CLK_MOUT_CMU_HSI2_BUS		53
+#define CLK_MOUT_CMU_HSI2_PCIE		54
+#define CLK_MOUT_CMU_IPP_BUS		55
+#define CLK_MOUT_CMU_ITP_BUS		56
+#define CLK_MOUT_CMU_MCSC_BUS		57
+#define CLK_MOUT_CMU_MCSC_GDC		58
+#define CLK_MOUT_CMU_CMU_BOOST_CPU	59
+#define CLK_MOUT_CMU_MFC0_MFC0		60
+#define CLK_MOUT_CMU_MFC0_WFD		61
+#define CLK_MOUT_CMU_MIF_BUSP		62
+#define CLK_MOUT_CMU_MIF_SWITCH		63
+#define CLK_MOUT_CMU_NPU_BUS		64
+#define CLK_MOUT_CMU_PERIC0_BUS		65
+#define CLK_MOUT_CMU_PERIC0_IP		66
+#define CLK_MOUT_CMU_PERIC1_BUS		67
+#define CLK_MOUT_CMU_PERIC1_IP		68
+#define CLK_MOUT_CMU_PERIS_BUS		69
+#define CLK_MOUT_CMU_SSP_BUS		70
+#define CLK_MOUT_CMU_TNR_BUS		71
+#define CLK_MOUT_CMU_VRA_BUS		72
+#define CLK_DOUT_CMU_APM_BUS		73
+#define CLK_DOUT_CMU_AUD_CPU		74
+#define CLK_DOUT_CMU_BUS0_BUS		75
+#define CLK_DOUT_CMU_BUS1_BUS		76
+#define CLK_DOUT_CMU_BUS1_SSS		77
+#define CLK_DOUT_CMU_CIS_CLK0		78
+#define CLK_DOUT_CMU_CIS_CLK1		79
+#define CLK_DOUT_CMU_CIS_CLK2		80
+#define CLK_DOUT_CMU_CIS_CLK3		81
+#define CLK_DOUT_CMU_CIS_CLK4		82
+#define CLK_DOUT_CMU_CIS_CLK5		83
+#define CLK_DOUT_CMU_CMU_BOOST		84
+#define CLK_DOUT_CMU_CORE_BUS		85
+#define CLK_DOUT_CMU_CPUCL0_DBG_BUS	86
+#define CLK_DOUT_CMU_CPUCL0_SWITCH	87
+#define CLK_DOUT_CMU_CPUCL1_SWITCH	88
+#define CLK_DOUT_CMU_CPUCL2_BUSP	89
+#define CLK_DOUT_CMU_CPUCL2_SWITCH	90
+#define CLK_DOUT_CMU_CSIS_BUS		91
+#define CLK_DOUT_CMU_CSIS_OIS_MCU	92
+#define CLK_DOUT_CMU_DNC_BUS		93
+#define CLK_DOUT_CMU_DNC_BUSM		94
+#define CLK_DOUT_CMU_DNS_BUS		95
+#define CLK_DOUT_CMU_DSP_BUS		96
+#define CLK_DOUT_CMU_G2D_G2D		97
+#define CLK_DOUT_CMU_G2D_MSCL		98
+#define CLK_DOUT_CMU_G3D_SWITCH		99
+#define CLK_DOUT_CMU_HPM		100
+#define CLK_DOUT_CMU_HSI0_BUS		101
+#define CLK_DOUT_CMU_HSI0_DPGTC		102
+#define CLK_DOUT_CMU_HSI0_USB31DRD	103
+#define CLK_DOUT_CMU_HSI0_USBDP_DEBUG	104
+#define CLK_DOUT_CMU_HSI1_BUS		105
+#define CLK_DOUT_CMU_HSI1_MMC_CARD	106
+#define CLK_DOUT_CMU_HSI1_PCIE		107
+#define CLK_DOUT_CMU_HSI1_UFS_CARD	108
+#define CLK_DOUT_CMU_HSI1_UFS_EMBD	109
+#define CLK_DOUT_CMU_HSI2_BUS		110
+#define CLK_DOUT_CMU_HSI2_PCIE		111
+#define CLK_DOUT_CMU_IPP_BUS		112
+#define CLK_DOUT_CMU_ITP_BUS		113
+#define CLK_DOUT_CMU_MCSC_BUS		114
+#define CLK_DOUT_CMU_MCSC_GDC		115
+#define CLK_DOUT_CMU_CMU_BOOST_CPU	116
+#define CLK_DOUT_CMU_MFC0_MFC0		117
+#define CLK_DOUT_CMU_MFC0_WFD		118
+#define CLK_DOUT_CMU_MIF_BUSP		119
+#define CLK_DOUT_CMU_NPU_BUS		120
+#define CLK_DOUT_CMU_OTP		121
+#define CLK_DOUT_CMU_PERIC0_BUS		122
+#define CLK_DOUT_CMU_PERIC0_IP		123
+#define CLK_DOUT_CMU_PERIC1_BUS		124
+#define CLK_DOUT_CMU_PERIC1_IP		125
+#define CLK_DOUT_CMU_PERIS_BUS		126
+#define CLK_DOUT_CMU_SSP_BUS		127
+#define CLK_DOUT_CMU_TNR_BUS		128
+#define CLK_DOUT_CMU_VRA_BUS		129
+#define CLK_DOUT_CMU_DPU		130
+#define CLK_DOUT_CMU_DPU_ALT		131
+#define CLK_DOUT_CMU_SHARED0_DIV2	132
+#define CLK_DOUT_CMU_SHARED0_DIV3	133
+#define CLK_DOUT_CMU_SHARED0_DIV4	134
+#define CLK_DOUT_CMU_SHARED1_DIV2	135
+#define CLK_DOUT_CMU_SHARED1_DIV3	136
+#define CLK_DOUT_CMU_SHARED1_DIV4	137
+#define CLK_DOUT_CMU_SHARED2_DIV2	138
+#define CLK_DOUT_CMU_SHARED4_DIV2	139
+#define CLK_DOUT_CMU_SHARED4_DIV3	140
+#define CLK_DOUT_CMU_SHARED4_DIV4	141
+#define CLK_GOUT_CMU_G3D_BUS		142
+#define CLK_GOUT_CMU_MIF_SWITCH		143
+#define CLK_GOUT_CMU_APM_BUS		144
+#define CLK_GOUT_CMU_AUD_CPU		145
+#define CLK_GOUT_CMU_BUS0_BUS		146
+#define CLK_GOUT_CMU_BUS1_BUS		147
+#define CLK_GOUT_CMU_BUS1_SSS		148
+#define CLK_GOUT_CMU_CIS_CLK0		149
+#define CLK_GOUT_CMU_CIS_CLK1		150
+#define CLK_GOUT_CMU_CIS_CLK2		151
+#define CLK_GOUT_CMU_CIS_CLK3		152
+#define CLK_GOUT_CMU_CIS_CLK4		153
+#define CLK_GOUT_CMU_CIS_CLK5		154
+#define CLK_GOUT_CMU_CORE_BUS		155
+#define CLK_GOUT_CMU_CPUCL0_DBG_BUS	156
+#define CLK_GOUT_CMU_CPUCL0_SWITCH	157
+#define CLK_GOUT_CMU_CPUCL1_SWITCH	158
+#define CLK_GOUT_CMU_CPUCL2_BUSP	159
+#define CLK_GOUT_CMU_CPUCL2_SWITCH	160
+#define CLK_GOUT_CMU_CSIS_BUS		161
+#define CLK_GOUT_CMU_CSIS_OIS_MCU	162
+#define CLK_GOUT_CMU_DNC_BUS		163
+#define CLK_GOUT_CMU_DNC_BUSM		164
+#define CLK_GOUT_CMU_DNS_BUS		165
+#define CLK_GOUT_CMU_DPU		166
+#define CLK_GOUT_CMU_DPU_BUS		167
+#define CLK_GOUT_CMU_DSP_BUS		168
+#define CLK_GOUT_CMU_G2D_G2D		169
+#define CLK_GOUT_CMU_G2D_MSCL		170
+#define CLK_GOUT_CMU_G3D_SWITCH		171
+#define CLK_GOUT_CMU_HPM		172
+#define CLK_GOUT_CMU_HSI0_BUS		173
+#define CLK_GOUT_CMU_HSI0_DPGTC		174
+#define CLK_GOUT_CMU_HSI0_USB31DRD	175
+#define CLK_GOUT_CMU_HSI0_USBDP_DEBUG	176
+#define CLK_GOUT_CMU_HSI1_BUS		177
+#define CLK_GOUT_CMU_HSI1_MMC_CARD	178
+#define CLK_GOUT_CMU_HSI1_PCIE		179
+#define CLK_GOUT_CMU_HSI1_UFS_CARD	180
+#define CLK_GOUT_CMU_HSI1_UFS_EMBD	181
+#define CLK_GOUT_CMU_HSI2_BUS		182
+#define CLK_GOUT_CMU_HSI2_PCIE		183
+#define CLK_GOUT_CMU_IPP_BUS		184
+#define CLK_GOUT_CMU_ITP_BUS		185
+#define CLK_GOUT_CMU_MCSC_BUS		186
+#define CLK_GOUT_CMU_MCSC_GDC		187
+#define CLK_GOUT_CMU_MFC0_MFC0		188
+#define CLK_GOUT_CMU_MFC0_WFD		189
+#define CLK_GOUT_CMU_MIF_BUSP		190
+#define CLK_GOUT_CMU_NPU_BUS		191
+#define CLK_GOUT_CMU_PERIC0_BUS		192
+#define CLK_GOUT_CMU_PERIC0_IP		193
+#define CLK_GOUT_CMU_PERIC1_BUS		194
+#define CLK_GOUT_CMU_PERIC1_IP		195
+#define CLK_GOUT_CMU_PERIS_BUS		196
+#define CLK_GOUT_CMU_SSP_BUS		197
+#define CLK_GOUT_CMU_TNR_BUS		198
+#define CLK_GOUT_CMU_VRA_BUS		199
+
+/* CMU_HSI0 */
+#define CLK_MOUT_HSI0_BUS_USER				1
+#define CLK_MOUT_HSI0_USB31DRD_USER			2
+#define CLK_MOUT_HSI0_USBDP_DEBUG_USER			3
+#define CLK_MOUT_HSI0_DPGTC_USER			4
+#define CLK_GOUT_HSI0_DP_LINK_DP_GTC_CLK		5
+#define CLK_GOUT_HSI0_DP_LINK_PCLK			6
+#define CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK			7
+#define CLK_GOUT_HSI0_LHM_AXI_P_HSI0_CLK		8
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_ACLK		9
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_PCLK		10
+#define CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK			11
+#define CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2			12
+#define CLK_GOUT_HSI0_SYSREG_HSI0_PCLK			13
+#define CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL		14
+#define CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY		15
+#define CLK_GOUT_HSI0_USB31DRD_USB31DRD_REF_CLK_40	16
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_REF_SOC_PLL	17
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_SCL_APB		18
+#define CLK_GOUT_HSI0_USB31DRD_USBPCS_APB_CLK		19
+#define CLK_GOUT_HSI0_VGEN_LITE_HSI0_CLK		20
+#define CLK_GOUT_HSI0_CMU_HSI0_PCLK			21
+#define CLK_GOUT_HSI0_XIU_D_HSI0_ACLK			22
+
+#endif

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Fri Dec  6 08:12:19 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Fri, 06 Dec 2024 17:12:19 +0100
Subject: [PATCH v2 2/3] clk: samsung: clk-pll: Add support for pll_{0717x,
 0718x, 0732x}
In-Reply-To: <20241206-exynos990-cmu-v2-0-4666ff0a099b@mentallysanemainliners.org>
References: <20241206-exynos990-cmu-v2-0-4666ff0a099b@mentallysanemainliners.org>
Message-ID: <20241206-exynos990-cmu-v2-2-4666ff0a099b@mentallysanemainliners.org>

These PLLs are found in the Exynos990 SoC. The PLLs are similar
to pll0822x.

pll0717x and pll0718x are an exception, and they use the mdiv
mask from 1718X (that is, one bit smaller).

Apart from that, the masks/shifts are identical to those of 0822x.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 drivers/clk/samsung/clk-pll.c | 14 ++++++++++++--
 drivers/clk/samsung/clk-pll.h |  3 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index be6b516949193f103696c814b5cffad5d4ea9a66..2e94bba6c3966b9470f0ef42ad101ee3da0519b9 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -430,7 +430,10 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {
 #define PLL0822X_LOCK_STAT_SHIFT	(29)
 #define PLL0822X_ENABLE_SHIFT		(31)
 
-/* PLL1418x is similar to PLL0822x, except that MDIV is one bit smaller */
+/*
+ * PLL1418x, PLL0717x and PLL0718x are similar
+ * to PLL0822x, except that MDIV is one bit smaller
+ */
 #define PLL1418X_MDIV_MASK		(0x1FF)
 
 static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
@@ -441,10 +444,14 @@ static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
 	u64 fvco = parent_rate;
 
 	pll_con3 = readl_relaxed(pll->con_reg);
-	if (pll->type != pll_1418x)
+
+	if (pll->type != pll_1418x &&
+	    pll->type != pll_0717x &&
+	    pll->type != pll_0718x)
 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
 	else
 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL1418X_MDIV_MASK;
+
 	pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
 	sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
 
@@ -1377,6 +1384,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_0516x:
 	case pll_0517x:
 	case pll_0518x:
+	case pll_0717x:
+	case pll_0718x:
+	case pll_0732x:
 		pll->enable_offs = PLL0822X_ENABLE_SHIFT;
 		pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
 		if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 858ab367eb6552bf880ef9d14cd89713b08960a4..6ddc54d173a01e201d93f1ed1679ca6a6ebfa939 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -45,6 +45,9 @@ enum samsung_pll_type {
 	pll_531x,
 	pll_1051x,
 	pll_1052x,
+	pll_0717x,
+	pll_0718x,
+	pll_0732x,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Fri Dec  6 08:12:20 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Fri, 06 Dec 2024 17:12:20 +0100
Subject: [PATCH v2 3/3] clk: samsung: Introduce Exynos990 clock controller
 driver
In-Reply-To: <20241206-exynos990-cmu-v2-0-4666ff0a099b@mentallysanemainliners.org>
References: <20241206-exynos990-cmu-v2-0-4666ff0a099b@mentallysanemainliners.org>
Message-ID: <20241206-exynos990-cmu-v2-3-4666ff0a099b@mentallysanemainliners.org>

The current implementation contains support for:
- CMU_TOP - which generates clocks for other blocks
- CMU_HSI0 - which generates clocks for USB31.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 drivers/clk/samsung/Makefile        |    1 +
 drivers/clk/samsung/clk-exynos990.c | 1343 +++++++++++++++++++++++++++++++++++
 2 files changed, 1344 insertions(+)

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 7a88331a658d5035c083eba910e37564915f9a46..90e5b114872c5057a9bd43fd1a16c2ad4630cc3f 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7885.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos8895.o
+obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos990.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov9.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov920.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-gs101.o
diff --git a/drivers/clk/samsung/clk-exynos990.c b/drivers/clk/samsung/clk-exynos990.c
new file mode 100644
index 0000000000000000000000000000000000000000..212d8d43b2a58fd09144f2dbcf6626e7f8050880
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos990.c
@@ -0,0 +1,1343 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Igor Belwon <igor.belwon at mentallysanemainliners.org>
+ *
+ * Common Clock Framework support for Exynos990.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/samsung,exynos990.h>
+
+#include "clk.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_GOUT_CMU_VRA_BUS + 1)
+#define CLKS_NR_HSI0 (CLK_GOUT_HSI0_XIU_D_HSI0_ACLK + 1)
+
+/* ---- CMU_TOP ------------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_TOP (0x1a330000) */
+#define PLL_LOCKTIME_PLL_G3D				0x0000
+#define PLL_LOCKTIME_PLL_MMC				0x0004
+#define PLL_LOCKTIME_PLL_SHARED0			0x0008
+#define PLL_LOCKTIME_PLL_SHARED1			0x000c
+#define PLL_LOCKTIME_PLL_SHARED2			0x0010
+#define PLL_LOCKTIME_PLL_SHARED3			0x0014
+#define PLL_LOCKTIME_PLL_SHARED4			0x0018
+#define PLL_CON0_PLL_G3D				0x0100
+#define PLL_CON3_PLL_G3D				0x010c
+#define PLL_CON0_PLL_MMC				0x0140
+#define PLL_CON3_PLL_MMC				0x014c
+#define PLL_CON0_PLL_SHARED0				0x0180
+#define PLL_CON3_PLL_SHARED0				0x018c
+#define PLL_CON0_PLL_SHARED1				0x01c0
+#define PLL_CON3_PLL_SHARED1				0x01cc
+#define PLL_CON0_PLL_SHARED2				0x0200
+#define PLL_CON3_PLL_SHARED2				0x020c
+#define PLL_CON0_PLL_SHARED3				0x0240
+#define PLL_CON3_PLL_SHARED3				0x024c
+#define PLL_CON0_PLL_SHARED4				0x0280
+#define PLL_CON3_PLL_SHARED4				0x028c
+#define CLK_CON_MUX_MUX_CLKCMU_APM_BUS			0x1004
+#define CLK_CON_MUX_MUX_CLKCMU_AUD_CPU			0x1008
+#define CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS			0x100c
+#define CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS			0x1010
+#define CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS			0x1014
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0			0x1018
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1			0x101c
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2			0x1020
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3			0x1024
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4			0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5			0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST		0x1030
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS			0x1034
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS		0x1038
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH		0x103c
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH		0x1040
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP		0x1044
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH		0x1048
+#define CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS			0x104c
+#define CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU		0x1050
+#define CLK_CON_MUX_MUX_CLKCMU_DNC_BUS			0x1054
+#define CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM			0x1058
+#define CLK_CON_MUX_MUX_CLKCMU_DNS_BUS			0x105c
+#define CLK_CON_MUX_MUX_CLKCMU_DPU			0x1060
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_ALT			0x1064
+#define CLK_CON_MUX_MUX_CLKCMU_DSP_BUS			0x1068
+#define CLK_CON_MUX_MUX_CLKCMU_G2D_G2D			0x106c
+#define CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL			0x1070
+#define CLK_CON_MUX_MUX_CLKCMU_HPM			0x1074
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS			0x1078
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC		0x107c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD		0x1080
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG		0x1084
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS			0x1088
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD		0x108c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE		0x1090
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD		0x1094
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD		0x1098
+#define CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS			0x109c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE		0x10a0
+#define CLK_CON_MUX_MUX_CLKCMU_IPP_BUS			0x10a4
+#define CLK_CON_MUX_MUX_CLKCMU_ITP_BUS			0x10a8
+#define CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS			0x10ac
+#define CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC			0x10b0
+#define CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU		0x10b4
+#define CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0		0x10b8
+#define CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD			0x10bc
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP			0x10c0
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH		0x10c4
+#define CLK_CON_MUX_MUX_CLKCMU_NPU_BUS			0x10c8
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS		0x10cc
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP		0x10d0
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS		0x10d4
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP		0x10d8
+#define CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS		0x10dc
+#define CLK_CON_MUX_MUX_CLKCMU_SSP_BUS			0x10e0
+#define CLK_CON_MUX_MUX_CLKCMU_TNR_BUS			0x10e4
+#define CLK_CON_MUX_MUX_CLKCMU_VRA_BUS			0x10e8
+#define CLK_CON_DIV_CLKCMU_APM_BUS			0x1800
+#define CLK_CON_DIV_CLKCMU_AUD_CPU			0x1804
+#define CLK_CON_DIV_CLKCMU_BUS0_BUS			0x1808
+#define CLK_CON_DIV_CLKCMU_BUS1_BUS			0x180c
+#define CLK_CON_DIV_CLKCMU_BUS1_SSS			0x1810
+#define CLK_CON_DIV_CLKCMU_CIS_CLK0			0x1814
+#define CLK_CON_DIV_CLKCMU_CIS_CLK1			0x1818
+#define CLK_CON_DIV_CLKCMU_CIS_CLK2			0x181c
+#define CLK_CON_DIV_CLKCMU_CIS_CLK3			0x1820
+#define CLK_CON_DIV_CLKCMU_CIS_CLK4			0x1824
+#define CLK_CON_DIV_CLKCMU_CIS_CLK5			0x1828
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST			0x182c
+#define CLK_CON_DIV_CLKCMU_CORE_BUS			0x1830
+#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS		0x1834
+#define CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH		0x1838
+#define CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH		0x183c
+#define CLK_CON_DIV_CLKCMU_CPUCL2_BUSP			0x1840
+#define CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH		0x1844
+#define CLK_CON_DIV_CLKCMU_CSIS_BUS			0x1848
+#define CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU			0x184c
+#define CLK_CON_DIV_CLKCMU_DNC_BUS			0x1850
+#define CLK_CON_DIV_CLKCMU_DNC_BUSM			0x1854
+#define CLK_CON_DIV_CLKCMU_DNS_BUS			0x1858
+#define CLK_CON_DIV_CLKCMU_DSP_BUS			0x185c
+#define CLK_CON_DIV_CLKCMU_G2D_G2D			0x1860
+#define CLK_CON_DIV_CLKCMU_G2D_MSCL			0x1864
+#define CLK_CON_DIV_CLKCMU_G3D_SWITCH			0x1868
+#define CLK_CON_DIV_CLKCMU_HPM				0x186c
+#define CLK_CON_DIV_CLKCMU_HSI0_BUS			0x1870
+#define CLK_CON_DIV_CLKCMU_HSI0_DPGTC			0x1874
+#define CLK_CON_DIV_CLKCMU_HSI0_USB31DRD		0x1878
+#define CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG		0x187c
+#define CLK_CON_DIV_CLKCMU_HSI1_BUS			0x1880
+#define CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD		0x1884
+#define CLK_CON_DIV_CLKCMU_HSI1_PCIE			0x1888
+#define CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD		0x188c
+#define CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD		0x1890
+#define CLK_CON_DIV_CLKCMU_HSI2_BUS			0x1894
+#define CLK_CON_DIV_CLKCMU_HSI2_PCIE			0x1898
+#define CLK_CON_DIV_CLKCMU_IPP_BUS			0x189c
+#define CLK_CON_DIV_CLKCMU_ITP_BUS			0x18a0
+#define CLK_CON_DIV_CLKCMU_MCSC_BUS			0x18a4
+#define CLK_CON_DIV_CLKCMU_MCSC_GDC			0x18a8
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU		0x18ac
+#define CLK_CON_DIV_CLKCMU_MFC0_MFC0			0x18b0
+#define CLK_CON_DIV_CLKCMU_MFC0_WFD			0x18b4
+#define CLK_CON_DIV_CLKCMU_MIF_BUSP			0x18b8
+#define CLK_CON_DIV_CLKCMU_NPU_BUS			0x18bc
+#define CLK_CON_DIV_CLKCMU_OTP				0x18c0
+#define CLK_CON_DIV_CLKCMU_PERIC0_BUS			0x18c4
+#define CLK_CON_DIV_CLKCMU_PERIC0_IP			0x18c8
+#define CLK_CON_DIV_CLKCMU_PERIC1_BUS			0x18cc
+#define CLK_CON_DIV_CLKCMU_PERIC1_IP			0x18d0
+#define CLK_CON_DIV_CLKCMU_PERIS_BUS			0x18d4
+#define CLK_CON_DIV_CLKCMU_SSP_BUS			0x18d8
+#define CLK_CON_DIV_CLKCMU_TNR_BUS			0x18dc
+#define CLK_CON_DIV_CLKCMU_VRA_BUS			0x18e0
+#define CLK_CON_DIV_DIV_CLKCMU_DPU			0x18e8
+#define CLK_CON_DIV_DIV_CLKCMU_DPU_ALT			0x18ec
+#define CLK_CON_DIV_PLL_SHARED0_DIV2			0x18f4
+#define CLK_CON_DIV_PLL_SHARED0_DIV3			0x18f8
+#define CLK_CON_DIV_PLL_SHARED0_DIV4			0x18fc
+#define CLK_CON_DIV_PLL_SHARED1_DIV2			0x1900
+#define CLK_CON_DIV_PLL_SHARED1_DIV3			0x1904
+#define CLK_CON_DIV_PLL_SHARED1_DIV4			0x1908
+#define CLK_CON_DIV_PLL_SHARED2_DIV2			0x190c
+#define CLK_CON_DIV_PLL_SHARED4_DIV2			0x1910
+#define CLK_CON_DIV_PLL_SHARED4_DIV3			0x1914
+#define CLK_CON_DIV_PLL_SHARED4_DIV4			0x1918
+#define CLK_CON_GAT_CLKCMU_G3D_BUS			0x2000
+#define CLK_CON_GAT_CLKCMU_MIF_SWITCH			0x2004
+#define CLK_CON_GAT_GATE_CLKCMU_APM_BUS			0x2008
+#define CLK_CON_GAT_GATE_CLKCMU_AUD_CPU			0x200c
+#define CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS		0x2010
+#define CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS		0x2014
+#define CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS		0x2018
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0		0x201c
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1		0x2020
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2		0x2024
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3		0x2028
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4		0x202c
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5		0x2030
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS		0x2034
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS		0x2038
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH		0x203c
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH		0x2040
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP		0x2044
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH		0x2048
+#define CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS		0x204c
+#define CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU		0x2050
+#define CLK_CON_GAT_GATE_CLKCMU_DNC_BUS			0x2054
+#define CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM		0x2058
+#define CLK_CON_GAT_GATE_CLKCMU_DNS_BUS			0x205c
+#define CLK_CON_GAT_GATE_CLKCMU_DPU			0x2060
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_BUS			0x2064
+#define CLK_CON_GAT_GATE_CLKCMU_DSP_BUS			0x2068
+#define CLK_CON_GAT_GATE_CLKCMU_G2D_G2D			0x206c
+#define CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL		0x2070
+#define CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH		0x2074
+#define CLK_CON_GAT_GATE_CLKCMU_HPM			0x2078
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS		0x207c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC		0x2080
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD		0x2084
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG	0x2088
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS		0x208c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD		0x2090
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE		0x2094
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD		0x2098
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD		0x209c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS		0x20a0
+#define CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE		0x20a4
+#define CLK_CON_GAT_GATE_CLKCMU_IPP_BUS			0x20a8
+#define CLK_CON_GAT_GATE_CLKCMU_ITP_BUS			0x20ac
+#define CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS		0x20b0
+#define CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC		0x20b4
+#define CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0		0x20bc
+#define CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD		0x20c0
+#define CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP		0x20c4
+#define CLK_CON_GAT_GATE_CLKCMU_NPU_BUS			0x20c8
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS		0x20cc
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP		0x20d0
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS		0x20d4
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP		0x20d8
+#define CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS		0x20dc
+#define CLK_CON_GAT_GATE_CLKCMU_SSP_BUS			0x20e0
+#define CLK_CON_GAT_GATE_CLKCMU_TNR_BUS			0x20e4
+#define CLK_CON_GAT_GATE_CLKCMU_VRA_BUS			0x20e8
+
+static const unsigned long top_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_G3D,
+	PLL_LOCKTIME_PLL_MMC,
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_LOCKTIME_PLL_SHARED2,
+	PLL_LOCKTIME_PLL_SHARED3,
+	PLL_LOCKTIME_PLL_SHARED4,
+	PLL_CON3_PLL_G3D,
+	PLL_CON3_PLL_MMC,
+	PLL_CON3_PLL_SHARED0,
+	PLL_CON3_PLL_SHARED1,
+	PLL_CON3_PLL_SHARED2,
+	PLL_CON3_PLL_SHARED3,
+	PLL_CON3_PLL_SHARED4,
+	CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_AUD_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5,
+	CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST,
+	CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_MUX_MUX_CLKCMU_DNC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM,
+	CLK_CON_MUX_MUX_CLKCMU_DNS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DPU,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_ALT,
+	CLK_CON_MUX_MUX_CLKCMU_DSP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_G2D_G2D,
+	CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL,
+	CLK_CON_MUX_MUX_CLKCMU_HPM,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE,
+	CLK_CON_MUX_MUX_CLKCMU_IPP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_ITP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC,
+	CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0,
+	CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_NPU_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_SSP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_TNR_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_VRA_BUS,
+	CLK_CON_DIV_CLKCMU_APM_BUS,
+	CLK_CON_DIV_CLKCMU_AUD_CPU,
+	CLK_CON_DIV_CLKCMU_BUS0_BUS,
+	CLK_CON_DIV_CLKCMU_BUS1_BUS,
+	CLK_CON_DIV_CLKCMU_BUS1_SSS,
+	CLK_CON_DIV_CLKCMU_CIS_CLK0,
+	CLK_CON_DIV_CLKCMU_CIS_CLK1,
+	CLK_CON_DIV_CLKCMU_CIS_CLK2,
+	CLK_CON_DIV_CLKCMU_CIS_CLK3,
+	CLK_CON_DIV_CLKCMU_CIS_CLK4,
+	CLK_CON_DIV_CLKCMU_CIS_CLK5,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST,
+	CLK_CON_DIV_CLKCMU_CORE_BUS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_DIV_CLKCMU_CSIS_BUS,
+	CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_DIV_CLKCMU_DNC_BUS,
+	CLK_CON_DIV_CLKCMU_DNC_BUSM,
+	CLK_CON_DIV_CLKCMU_DNS_BUS,
+	CLK_CON_DIV_CLKCMU_DSP_BUS,
+	CLK_CON_DIV_CLKCMU_G2D_G2D,
+	CLK_CON_DIV_CLKCMU_G2D_MSCL,
+	CLK_CON_DIV_CLKCMU_G3D_SWITCH,
+	CLK_CON_DIV_CLKCMU_HPM,
+	CLK_CON_DIV_CLKCMU_HSI0_BUS,
+	CLK_CON_DIV_CLKCMU_HSI0_DPGTC,
+	CLK_CON_DIV_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_DIV_CLKCMU_HSI1_BUS,
+	CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_DIV_CLKCMU_HSI1_PCIE,
+	CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_DIV_CLKCMU_HSI2_BUS,
+	CLK_CON_DIV_CLKCMU_HSI2_PCIE,
+	CLK_CON_DIV_CLKCMU_IPP_BUS,
+	CLK_CON_DIV_CLKCMU_ITP_BUS,
+	CLK_CON_DIV_CLKCMU_MCSC_BUS,
+	CLK_CON_DIV_CLKCMU_MCSC_GDC,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU,
+	CLK_CON_DIV_CLKCMU_MFC0_MFC0,
+	CLK_CON_DIV_CLKCMU_MFC0_WFD,
+	CLK_CON_DIV_CLKCMU_MIF_BUSP,
+	CLK_CON_DIV_CLKCMU_NPU_BUS,
+	CLK_CON_DIV_CLKCMU_OTP,
+	CLK_CON_DIV_CLKCMU_PERIC0_BUS,
+	CLK_CON_DIV_CLKCMU_PERIC0_IP,
+	CLK_CON_DIV_CLKCMU_PERIC1_BUS,
+	CLK_CON_DIV_CLKCMU_PERIC1_IP,
+	CLK_CON_DIV_CLKCMU_PERIS_BUS,
+	CLK_CON_DIV_CLKCMU_SSP_BUS,
+	CLK_CON_DIV_CLKCMU_TNR_BUS,
+	CLK_CON_DIV_CLKCMU_VRA_BUS,
+	CLK_CON_DIV_DIV_CLKCMU_DPU,
+	CLK_CON_DIV_DIV_CLKCMU_DPU_ALT,
+	CLK_CON_DIV_PLL_SHARED0_DIV2,
+	CLK_CON_DIV_PLL_SHARED0_DIV3,
+	CLK_CON_DIV_PLL_SHARED0_DIV4,
+	CLK_CON_DIV_PLL_SHARED1_DIV2,
+	CLK_CON_DIV_PLL_SHARED1_DIV3,
+	CLK_CON_DIV_PLL_SHARED1_DIV4,
+	CLK_CON_DIV_PLL_SHARED2_DIV2,
+	CLK_CON_DIV_PLL_SHARED4_DIV2,
+	CLK_CON_DIV_PLL_SHARED4_DIV3,
+	CLK_CON_DIV_PLL_SHARED4_DIV4,
+	CLK_CON_GAT_CLKCMU_G3D_BUS,
+	CLK_CON_GAT_CLKCMU_MIF_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_AUD_CPU,
+	CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5,
+	CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_GAT_GATE_CLKCMU_DNC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM,
+	CLK_CON_GAT_GATE_CLKCMU_DNS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DPU,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DSP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_G2D_G2D,
+	CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL,
+	CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_HPM,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE,
+	CLK_CON_GAT_GATE_CLKCMU_IPP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_ITP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC,
+	CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0,
+	CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD,
+	CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_NPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_SSP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_TNR_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_VRA_BUS,
+};
+
+static const struct samsung_pll_clock top_pll_clks[] __initconst = {
+	PLL(pll_0717x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, NULL),
+	PLL(pll_0717x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, NULL),
+	PLL(pll_0718x, CLK_FOUT_SHARED2_PLL, "fout_shared2_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED2, PLL_CON3_PLL_SHARED2, NULL),
+	PLL(pll_0718x, CLK_FOUT_SHARED3_PLL, "fout_shared3_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED3, PLL_CON3_PLL_SHARED3, NULL),
+	PLL(pll_0717x, CLK_FOUT_SHARED4_PLL, "fout_shared4_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED4, PLL_CON3_PLL_SHARED4, NULL),
+	PLL(pll_0732x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL),
+	PLL(pll_0718x, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_G3D, PLL_CON3_PLL_G3D, NULL),
+};
+
+/* Parent clock list for CMU_TOP muxes*/
+PNAME(mout_pll_shared0_p)		= { "oscclk", "fout_shared0_pll" };
+PNAME(mout_pll_shared1_p)		= { "oscclk", "fout_shared1_pll" };
+PNAME(mout_pll_shared2_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_pll_shared3_p)		= { "oscclk", "fout_shared3_pll" };
+PNAME(mout_pll_shared4_p)		= { "oscclk", "fout_shared4_pll" };
+PNAME(mout_pll_mmc_p)			= { "oscclk", "fout_mmc_pll" };
+PNAME(mout_pll_g3d_p)			= { "oscclk", "fout_g3d_pll" };
+PNAME(mout_cmu_apm_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_aud_cpu_p)		= { "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_bus0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_bus1_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_bus1_sss_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_cis_clk0_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk1_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk2_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk3_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk4_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk5_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cmu_boost_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_core_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div3",
+					    "dout_cmu_shared1_div3",
+					    "dout_cmu_shared0_div4",
+					    "fout_shared3_pll", "oscclk" };
+PNAME(mout_cmu_cpucl0_dbg_bus_p)	= { "fout_shared2_pll",
+					    "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4",
+					    "oscclk" };
+PNAME(mout_cmu_cpucl0_switch_p)		= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_cpucl1_switch_p)	= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_cpucl2_busp_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cpucl2_switch_p)		= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_csis_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3" };
+PNAME(mout_cmu_csis_ois_mcu_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_dnc_bus_p)		= { "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_dnc_busm_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "dout_cmu_shared4_div4" };
+PNAME(mout_cmu_dns_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_dpu_p)			= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_dpu_alt_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_dsp_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "fout_shared3_pll", "oscclk",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_g2d_g2d_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_g2d_mscl_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "dout_cmu_shared4_div4",
+					    "oscclk" };
+PNAME(mout_cmu_hpm_p)			= { "oscclk",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_hsi0_dpgtc_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_usb31drd_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_usbdp_debug_p)	= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_hsi1_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "fout_mmc_pll", "oscclk", "oscclk" };
+PNAME(mout_cmu_hsi1_mmc_card_p)	= { "oscclk", "fout_shared2_pll",
+					    "fout_mmc_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_hsi1_pcie_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_hsi1_ufs_card_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi1_ufs_embd_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi2_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_hsi2_pcie_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_ipp_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "oscclk", "oscclk", "oscclk" };
+PNAME(mout_cmu_itp_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_mcsc_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_mcsc_gdc_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_cmu_boost_cpu_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_mfc0_mfc0_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_mfc0_wfd_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_mif_busp_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_mif_switch_p)		= { "fout_shared0_pll",
+					    "fout_shared1_pll",
+					    "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_npu_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "fout_shared3_pll", "oscclk",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_peric0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric0_ip_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric1_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric1_ip_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peris_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_ssp_bus_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_tnr_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_vra_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3" };
+
+/*
+ * Register name to clock name mangling strategy used in this file
+ *
+ * Replace PLL_CON{0,3}_PLL	   with CLK_MOUT_PLL and mout_pll
+ * Replace CLK_CON_MUX_MUX_CLKCMU  with CLK_MOUT_CMU and mout_cmu
+ * Replace CLK_CON_DIV_CLKCMU      with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_DIV_DIV_CLKCMU  with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_DIV_PLL_CLKCMU  with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_GAT_CLKCMU      with CLK_GOUT_CMU and gout_cmu
+ * Replace CLK_CON_GAT_GATE_CLKCMU with CLK_GOUT_CMU and gout_cmu
+ *
+ * For gates remove _UID _BLK _IPCLKPORT, _I and _RSTNSYNC
+ */
+
+static const struct samsung_mux_clock top_mux_clks[] __initconst = {
+	MUX(CLK_MOUT_PLL_SHARED0, "mout_pll_shared0", mout_pll_shared0_p,
+	    PLL_CON3_PLL_SHARED0, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED1, "mout_pll_shared1", mout_pll_shared1_p,
+	    PLL_CON3_PLL_SHARED1, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED2, "mout_pll_shared2", mout_pll_shared2_p,
+	    PLL_CON3_PLL_SHARED2, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED3, "mout_pll_shared3", mout_pll_shared3_p,
+	    PLL_CON3_PLL_SHARED3, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED4, "mout_pll_shared4", mout_pll_shared4_p,
+	    PLL_CON0_PLL_SHARED4, 4, 1),
+	MUX(CLK_MOUT_PLL_MMC, "mout_pll_mmc", mout_pll_mmc_p,
+	    PLL_CON0_PLL_MMC, 4, 1),
+	MUX(CLK_MOUT_PLL_G3D, "mout_pll_g3d", mout_pll_g3d_p,
+	    PLL_CON0_PLL_G3D, 4, 1),
+	MUX(CLK_MOUT_CMU_APM_BUS, "mout_cmu_apm_bus",
+	    mout_cmu_apm_bus_p, CLK_CON_MUX_MUX_CLKCMU_APM_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_AUD_CPU, "mout_cmu_aud_cpu",
+	    mout_cmu_aud_cpu_p, CLK_CON_MUX_MUX_CLKCMU_AUD_CPU, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS0_BUS, "mout_cmu_bus0_bus",
+	    mout_cmu_bus0_bus_p, CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS1_BUS, "mout_cmu_bus1_bus",
+	    mout_cmu_bus1_bus_p, CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS1_SSS, "mout_cmu_bus1_sss",
+	    mout_cmu_bus1_sss_p, CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS, 0, 2),
+	MUX(CLK_MOUT_CMU_CIS_CLK0, "mout_cmu_cis_clk0",
+	    mout_cmu_cis_clk0_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK1, "mout_cmu_cis_clk1",
+	    mout_cmu_cis_clk1_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK2, "mout_cmu_cis_clk2",
+	    mout_cmu_cis_clk2_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK3, "mout_cmu_cis_clk3",
+	    mout_cmu_cis_clk3_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK4, "mout_cmu_cis_clk4",
+	    mout_cmu_cis_clk4_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK5, "mout_cmu_cis_clk5",
+	    mout_cmu_cis_clk5_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5, 0, 1),
+	MUX(CLK_MOUT_CMU_CMU_BOOST, "mout_cmu_cmu_boost",
+	    mout_cmu_cmu_boost_p, CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST, 0, 2),
+	MUX(CLK_MOUT_CMU_CORE_BUS, "mout_cmu_core_bus",
+	    mout_cmu_core_bus_p, CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_CPUCL0_DBG_BUS, "mout_cmu_cpucl0_dbg_bus",
+	    mout_cmu_cpucl0_dbg_bus_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL0_SWITCH, "mout_cmu_cpucl0_switch",
+	    mout_cmu_cpucl0_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL1_SWITCH, "mout_cmu_cpucl1_switch",
+	    mout_cmu_cpucl1_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL2_BUSP, "mout_cmu_cpucl2_busp",
+	    mout_cmu_cpucl2_busp_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_CPUCL2_SWITCH, "mout_cmu_cpucl2_switch",
+	    mout_cmu_cpucl2_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CSIS_BUS, "mout_cmu_csis_bus",
+	    mout_cmu_csis_bus_p, CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_CSIS_OIS_MCU, "mout_cmu_csis_ois_mcu",
+	    mout_cmu_csis_ois_mcu_p, CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_DNC_BUS, "mout_cmu_dnc_bus",
+	    mout_cmu_dnc_bus_p, CLK_CON_MUX_MUX_CLKCMU_DNC_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_DNC_BUSM, "mout_cmu_dnc_busm",
+	    mout_cmu_dnc_busm_p, CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM, 0, 2),
+	MUX(CLK_MOUT_CMU_DNS_BUS, "mout_cmu_dns_bus",
+	    mout_cmu_dns_bus_p, CLK_CON_MUX_MUX_CLKCMU_DNS_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_DPU, "mout_cmu_dpu",
+	    mout_cmu_dpu_p, CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 1),
+	MUX(CLK_MOUT_CMU_DPU_ALT, "mout_cmu_dpu_alt",
+	    mout_cmu_dpu_alt_p, CLK_CON_MUX_MUX_CLKCMU_DPU_ALT, 0, 2),
+	MUX(CLK_MOUT_CMU_DSP_BUS, "mout_cmu_dsp_bus",
+	    mout_cmu_dsp_bus_p, CLK_CON_MUX_MUX_CLKCMU_DSP_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_G2D_G2D, "mout_cmu_g2d_g2d",
+	    mout_cmu_g2d_g2d_p, CLK_CON_MUX_MUX_CLKCMU_G2D_G2D, 0, 2),
+	MUX(CLK_MOUT_CMU_G2D_MSCL, "mout_cmu_g2d_mscl",
+	    mout_cmu_g2d_mscl_p, CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL, 0, 1),
+	MUX(CLK_MOUT_CMU_HPM, "mout_cmu_hpm",
+	    mout_cmu_hpm_p, CLK_CON_MUX_MUX_CLKCMU_HPM, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_BUS, "mout_cmu_hsi0_bus",
+	    mout_cmu_hsi0_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI0_DPGTC, "mout_cmu_hsi0_dpgtc",
+	    mout_cmu_hsi0_dpgtc_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_USB31DRD, "mout_cmu_hsi0_usb31drd",
+	    mout_cmu_hsi0_usb31drd_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_USBDP_DEBUG, "mout_cmu_hsi0_usbdp_debug",
+	    mout_cmu_hsi0_usbdp_debug_p,
+	    CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_BUS, "mout_cmu_hsi1_bus",
+	    mout_cmu_hsi1_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_HSI1_MMC_CARD, "mout_cmu_hsi1_mmc_card",
+	    mout_cmu_hsi1_mmc_card_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_PCIE, "mout_cmu_hsi1_pcie",
+	    mout_cmu_hsi1_pcie_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI1_UFS_CARD, "mout_cmu_hsi1_ufs_card",
+	    mout_cmu_hsi1_ufs_card_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_UFS_EMBD, "mout_cmu_hsi1_ufs_embd",
+	    mout_cmu_hsi1_ufs_embd_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_HSI2_BUS, "mout_cmu_hsi2_bus",
+	    mout_cmu_hsi2_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI2_PCIE, "mout_cmu_hsi2_pcie",
+	    mout_cmu_hsi2_pcie_p, CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE, 0, 1),
+	MUX(CLK_MOUT_CMU_IPP_BUS, "mout_cmu_ipp_bus",
+	    mout_cmu_ipp_bus_p, CLK_CON_MUX_MUX_CLKCMU_IPP_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_ITP_BUS, "mout_cmu_itp_bus",
+	    mout_cmu_itp_bus_p, CLK_CON_MUX_MUX_CLKCMU_ITP_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_MCSC_BUS, "mout_cmu_mcsc_bus",
+	    mout_cmu_mcsc_bus_p, CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_MCSC_GDC, "mout_cmu_mcsc_gdc",
+	    mout_cmu_mcsc_gdc_p, CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC, 0, 3),
+	MUX(CLK_MOUT_CMU_CMU_BOOST_CPU, "mout_cmu_cmu_boost_cpu",
+	    mout_cmu_cmu_boost_cpu_p, CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_MFC0_MFC0, "mout_cmu_mfc0_mfc0",
+	    mout_cmu_mfc0_mfc0_p, CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0, 0, 2),
+	MUX(CLK_MOUT_CMU_MFC0_WFD, "mout_cmu_mfc0_wfd",
+	    mout_cmu_mfc0_wfd_p, CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD, 0, 2),
+	MUX(CLK_MOUT_CMU_MIF_BUSP, "mout_cmu_mif_busp",
+	    mout_cmu_mif_busp_p, CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP, 0, 2),
+	MUX(CLK_MOUT_CMU_MIF_SWITCH, "mout_cmu_mif_switch",
+	    mout_cmu_mif_switch_p, CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH, 0, 3),
+	MUX(CLK_MOUT_CMU_NPU_BUS, "mout_cmu_npu_bus",
+	    mout_cmu_npu_bus_p, CLK_CON_MUX_MUX_CLKCMU_NPU_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_PERIC0_BUS, "mout_cmu_peric0_bus",
+	    mout_cmu_peric0_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC0_IP, "mout_cmu_peric0_ip",
+	    mout_cmu_peric0_ip_p, CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC1_BUS, "mout_cmu_peric1_bus",
+	    mout_cmu_peric1_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC1_IP, "mout_cmu_peric1_ip",
+	    mout_cmu_peric1_ip_p, CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIS_BUS, "mout_cmu_peris_bus",
+	    mout_cmu_peris_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_SSP_BUS, "mout_cmu_ssp_bus",
+	    mout_cmu_ssp_bus_p, CLK_CON_MUX_MUX_CLKCMU_SSP_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_TNR_BUS, "mout_cmu_tnr_bus",
+	    mout_cmu_tnr_bus_p, CLK_CON_MUX_MUX_CLKCMU_TNR_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_VRA_BUS, "mout_cmu_vra_bus",
+	    mout_cmu_vra_bus_p, CLK_CON_MUX_MUX_CLKCMU_VRA_BUS, 0, 2),
+};
+
+static const struct samsung_div_clock top_div_clks[] __initconst = {
+	/* SHARED0 region*/
+	DIV(CLK_DOUT_CMU_SHARED0_DIV2, "dout_cmu_shared0_div2", "mout_pll_shared0",
+	    CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED0_DIV3, "dout_cmu_shared0_div3", "mout_pll_shared0",
+	    CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED0_DIV4, "dout_cmu_shared0_div4", "dout_cmu_shared0_div2",
+	    CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
+
+	/* SHARED1 region*/
+	DIV(CLK_DOUT_CMU_SHARED1_DIV2, "dout_cmu_shared1_div2", "mout_pll_shared1",
+	    CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED1_DIV3, "dout_cmu_shared1_div3", "mout_pll_shared1",
+	    CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED1_DIV4, "dout_cmu_shared1_div4", "dout_cmu_shared1_div2",
+	    CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
+
+	/* SHARED2 region */
+	DIV(CLK_DOUT_CMU_SHARED2_DIV2, "dout_cmu_shared2_div2", "mout_pll_shared2",
+	    CLK_CON_DIV_PLL_SHARED2_DIV2, 0, 1),
+
+	/* SHARED4 region*/
+	DIV(CLK_DOUT_CMU_SHARED4_DIV2, "dout_cmu_shared4_div2", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED4_DIV3, "dout_cmu_shared4_div3", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED4_DIV4, "dout_cmu_shared4_div4", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV4, 0, 1),
+
+	DIV(CLK_DOUT_CMU_APM_BUS, "dout_cmu_apm_bus", "gout_cmu_apm_bus",
+	    CLK_CON_DIV_CLKCMU_APM_BUS, 0, 3),
+	DIV(CLK_DOUT_CMU_AUD_CPU, "dout_cmu_aud_cpu", "gout_cmu_aud_cpu",
+	    CLK_CON_DIV_CLKCMU_AUD_CPU, 0, 3),
+	DIV(CLK_DOUT_CMU_BUS0_BUS, "dout_cmu_bus0_bus", "gout_cmu_bus0_bus",
+	    CLK_CON_DIV_CLKCMU_BUS0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_BUS1_BUS, "dout_cmu_bus1_bus", "gout_cmu_bus1_bus",
+	    CLK_CON_DIV_CLKCMU_BUS1_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_BUS1_SSS, "dout_cmu_bus1_sss", "gout_cmu_bus1_sss",
+	    CLK_CON_DIV_CLKCMU_BUS1_SSS, 0, 4),
+	DIV(CLK_DOUT_CMU_CIS_CLK0, "dout_cmu_cis_clk0", "gout_cmu_cis_clk0",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK0, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK1, "dout_cmu_cis_clk1", "gout_cmu_cis_clk1",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK1, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK2, "dout_cmu_cis_clk2", "gout_cmu_cis_clk2",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK2, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK3, "dout_cmu_cis_clk3", "gout_cmu_cis_clk3",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK3, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK4, "dout_cmu_cis_clk4", "gout_cmu_cis_clk4",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK4, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK5, "dout_cmu_cis_clk5", "gout_cmu_cis_clk5",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK5, 0, 5),
+	DIV(CLK_DOUT_CMU_CMU_BOOST, "dout_cmu_cmu_boost", "mout_cmu_cmu_boost",
+	    CLK_CON_DIV_CLKCMU_CMU_BOOST, 0, 2),
+	DIV(CLK_DOUT_CMU_CORE_BUS, "dout_cmu_core_bus", "gout_cmu_core_bus",
+	    CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_CPUCL0_DBG_BUS, "dout_cmu_cpucl0_debug",
+	    "gout_cmu_cpucl0_dbg_bus", CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL0_SWITCH, "dout_cmu_cpucl0_switch",
+	    "gout_cmu_cpucl0_switch", CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL1_SWITCH, "dout_cmu_cpucl1_switch",
+	    "gout_cmu_cpucl1_switch", CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL2_BUSP, "dout_cmu_cpucl2_busp",
+	    "gout_cmu_cpucl2_busp", CLK_CON_DIV_CLKCMU_CPUCL2_BUSP, 0, 4),
+	DIV(CLK_DOUT_CMU_CPUCL2_SWITCH, "dout_cmu_cpucl2_switch",
+	    "gout_cmu_cpucl2_switch", CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CSIS_BUS, "dout_cmu_csis_bus", "gout_cmu_csis_bus",
+	    CLK_CON_DIV_CLKCMU_CSIS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_CSIS_OIS_MCU, "dout_cmu_csis_ois_mcu",
+	    "gout_cmu_csis_ois_mcu", CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU, 0, 4),
+	DIV(CLK_DOUT_CMU_DNC_BUS, "dout_cmu_dnc_bus", "gout_cmu_dnc_bus",
+	    CLK_CON_DIV_CLKCMU_DNC_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DNC_BUSM, "dout_cmu_dnc_busm", "gout_cmu_dnc_busm",
+	    CLK_CON_DIV_CLKCMU_DNC_BUSM, 0, 4),
+	DIV(CLK_DOUT_CMU_DNS_BUS, "dout_cmu_dns_bus", "gout_cmu_dns_bus",
+	    CLK_CON_DIV_CLKCMU_DNS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DSP_BUS, "dout_cmu_dsp_bus", "gout_cmu_dsp_bus",
+	    CLK_CON_DIV_CLKCMU_DSP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_G2D_G2D, "dout_cmu_g2d_g2d", "gout_cmu_g2d_g2d",
+	    CLK_CON_DIV_CLKCMU_G2D_G2D, 0, 4),
+	DIV(CLK_DOUT_CMU_G2D_MSCL, "dout_cmu_g2d_mscl", "gout_cmu_g2d_mscl",
+	    CLK_CON_DIV_CLKCMU_G2D_MSCL, 0, 4),
+	DIV(CLK_DOUT_CMU_G3D_SWITCH, "dout_cmu_g3d_switch",
+	    "gout_cmu_g3d_switch", CLK_CON_DIV_CLKCMU_G3D_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_HPM, "dout_cmu_hpm", "gout_cmu_hpm",
+	    CLK_CON_DIV_CLKCMU_HPM, 0, 2),
+	DIV(CLK_DOUT_CMU_HSI0_BUS, "dout_cmu_hsi0_bus", "gout_cmu_hsi0_bus",
+	    CLK_CON_DIV_CLKCMU_HSI0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI0_DPGTC, "dout_cmu_hsi0_dpgtc", "gout_cmu_hsi0_dpgtc",
+	    CLK_CON_DIV_CLKCMU_HSI0_DPGTC, 0, 3),
+	DIV(CLK_DOUT_CMU_HSI0_USB31DRD, "dout_cmu_hsi0_usb31drd",
+	    "gout_cmu_hsi0_usb31drd", CLK_CON_DIV_CLKCMU_HSI0_USB31DRD, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI0_USBDP_DEBUG, "dout_cmu_hsi0_usbdp_debug",
+	    "gout_cmu_hsi0_usbdp_debug", CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_HSI1_BUS, "dout_cmu_hsi1_bus", "gout_cmu_hsi1_bus",
+	    CLK_CON_DIV_CLKCMU_HSI1_BUS, 0, 3),
+	DIV(CLK_DOUT_CMU_HSI1_MMC_CARD, "dout_cmu_hsi1_mmc_card",
+	    "gout_cmu_hsi1_mmc_card", CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_HSI1_PCIE, "dout_cmu_hsi1_pcie", "gout_cmu_hsi1_pcie",
+	    CLK_CON_DIV_CLKCMU_HSI1_PCIE, 0, 7),
+	DIV(CLK_DOUT_CMU_HSI1_UFS_CARD, "dout_cmu_hsi1_ufs_card",
+	    "gout_cmu_hsi1_ufs_card", CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_HSI1_UFS_EMBD, "dout_cmu_hsi1_ufs_embd",
+	    "gout_cmu_hsi1_ufs_embd", CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_HSI2_BUS, "dout_cmu_hsi2_bus", "gout_cmu_hsi2_bus",
+	    CLK_CON_DIV_CLKCMU_HSI2_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI2_PCIE, "dout_cmu_hsi2_pcie", "gout_cmu_hsi2_pcie",
+	    CLK_CON_DIV_CLKCMU_HSI2_PCIE, 0, 7),
+	DIV(CLK_DOUT_CMU_IPP_BUS, "dout_cmu_ipp_bus", "gout_cmu_ipp_bus",
+	    CLK_CON_DIV_CLKCMU_IPP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_ITP_BUS, "dout_cmu_itp_bus", "gout_cmu_itp_bus",
+	    CLK_CON_DIV_CLKCMU_ITP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_MCSC_BUS, "dout_cmu_mcsc_bus", "gout_cmu_mcsc_bus",
+	    CLK_CON_DIV_CLKCMU_MCSC_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_MCSC_GDC, "dout_cmu_mcsc_gdc", "gout_cmu_mcsc_gdc",
+	    CLK_CON_DIV_CLKCMU_MCSC_GDC, 0, 4),
+	DIV(CLK_DOUT_CMU_CMU_BOOST_CPU, "dout_cmu_cmu_boost_cpu",
+	    "mout_cmu_cmu_boost_cpu", CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU,
+	    0, 2),
+	DIV(CLK_DOUT_CMU_MFC0_MFC0, "dout_cmu_mfc0_mfc0", "gout_cmu_mfc0_mfc0",
+	    CLK_CON_DIV_CLKCMU_MFC0_MFC0, 0, 4),
+	DIV(CLK_DOUT_CMU_MFC0_WFD, "dout_cmu_mfc0_wfd", "gout_cmu_mfc0_wfd",
+	    CLK_CON_DIV_CLKCMU_MFC0_WFD, 0, 4),
+	DIV(CLK_DOUT_CMU_MIF_BUSP, "dout_cmu_mif_busp", "gout_cmu_mif_busp",
+	    CLK_CON_DIV_CLKCMU_MIF_BUSP, 0, 4),
+	DIV(CLK_DOUT_CMU_NPU_BUS, "dout_cmu_npu_bus", "gout_cmu_npu_bus",
+	    CLK_CON_DIV_CLKCMU_NPU_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC0_BUS, "dout_cmu_peric0_bus", "gout_cmu_peric0_bus",
+	    CLK_CON_DIV_CLKCMU_PERIC0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC0_IP, "dout_cmu_peric0_ip", "gout_cmu_peric0_ip",
+	    CLK_CON_DIV_CLKCMU_PERIC0_IP, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC1_BUS, "dout_cmu_peric1_bus", "gout_cmu_peric1_bus",
+	    CLK_CON_DIV_CLKCMU_PERIC1_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC1_IP, "dout_cmu_peric1_ip", "gout_cmu_peric1_ip",
+	    CLK_CON_DIV_CLKCMU_PERIC1_IP, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIS_BUS, "dout_cmu_peris_bus", "gout_cmu_peris_bus",
+	    CLK_CON_DIV_CLKCMU_PERIS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_SSP_BUS, "dout_cmu_ssp_bus", "gout_cmu_ssp_bus",
+	    CLK_CON_DIV_CLKCMU_SSP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_TNR_BUS, "dout_cmu_tnr_bus", "gout_cmu_tnr_bus",
+	    CLK_CON_DIV_CLKCMU_TNR_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_VRA_BUS, "dout_cmu_vra_bus", "gout_cmu_vra_bus",
+	    CLK_CON_DIV_CLKCMU_VRA_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DPU, "dout_cmu_clkcmu_dpu", "gout_cmu_dpu",
+	    CLK_CON_DIV_DIV_CLKCMU_DPU, 0, 4),
+};
+
+static const struct samsung_gate_clock top_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CMU_APM_BUS, "gout_cmu_apm_bus", "mout_cmu_apm_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_APM_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_AUD_CPU, "gout_cmu_aud_cpu", "mout_cmu_aud_cpu",
+	     CLK_CON_GAT_GATE_CLKCMU_AUD_CPU, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_BUS0_BUS, "gout_cmu_bus0_bus", "mout_cmu_bus0_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_BUS1_BUS, "gout_cmu_bus1_bus", "mout_cmu_bus1_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_BUS1_SSS, "gout_cmu_bus1_sss", "mout_cmu_bus1_sss",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK0, "gout_cmu_cis_clk0", "mout_cmu_cis_clk0",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK1, "gout_cmu_cis_clk1", "mout_cmu_cis_clk1",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK2, "gout_cmu_cis_clk2", "mout_cmu_cis_clk2",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK3, "gout_cmu_cis_clk3", "mout_cmu_cis_clk3",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK4, "gout_cmu_cis_clk4", "mout_cmu_cis_clk4",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK5, "gout_cmu_cis_clk5", "mout_cmu_cis_clk5",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CORE_BUS, "gout_cmu_core_bus", "mout_cmu_core_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_DBG_BUS, "gout_cmu_cpucl0_dbg_bus",
+	     "mout_cmu_cpucl0_dbg_bus", CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_SWITCH, "gout_cmu_cpucl0_switch",
+	     "mout_cmu_cpucl0_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL1_SWITCH, "gout_cmu_cpucl1_switch",
+	     "mout_cmu_cpucl1_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL2_BUSP, "gout_cmu_cpucl2_busp",
+	     "mout_cmu_cpucl2_busp", CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL2_SWITCH, "gout_cmu_cpucl2_switch",
+	     "mout_cmu_cpucl2_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CSIS_BUS, "gout_cmu_csis_bus", "mout_cmu_csis_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CSIS_OIS_MCU, "gout_cmu_csis_ois_mcu",
+	     "mout_cmu_csis_ois_mcu", CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNC_BUS, "gout_cmu_dnc_bus", "mout_cmu_dnc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DNC_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNC_BUSM, "gout_cmu_dnc_busm", "mout_cmu_dnc_busm",
+	     CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNS_BUS, "gout_cmu_dns_bus", "mout_cmu_dns_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DNS_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU, "gout_cmu_dpu", "mout_cmu_dpu",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_BUS, "gout_cmu_dpu_bus", "mout_cmu_dpu_alt",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_DSP_BUS, "gout_cmu_dsp_bus", "mout_cmu_dsp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DSP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G2D_G2D, "gout_cmu_g2d_g2d", "mout_cmu_g2d_g2d",
+	     CLK_CON_GAT_GATE_CLKCMU_G2D_G2D, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G2D_MSCL, "gout_cmu_g2d_mscl", "mout_cmu_g2d_mscl",
+	     CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G3D_SWITCH, "gout_cmu_g3d_switch",
+	     "fout_shared2_pll", CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HPM, "gout_cmu_hpm", "mout_cmu_hpm",
+	     CLK_CON_GAT_GATE_CLKCMU_HPM, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_BUS, "gout_cmu_hsi0_bus",
+	     "mout_cmu_hsi0_bus", CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_DPGTC, "gout_cmu_hsi0_dpgtc",
+	     "mout_cmu_hsi0_dpgtc", CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_USB31DRD, "gout_cmu_hsi0_usb31drd",
+	     "mout_cmu_hsi0_usb31drd", CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_USBDP_DEBUG, "gout_cmu_hsi0_usbdp_debug",
+	     "mout_cmu_hsi0_usbdp_debug", CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_BUS, "gout_cmu_hsi1_bus", "mout_cmu_hsi1_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_MMC_CARD, "gout_cmu_hsi1_mmc_card",
+	     "mout_cmu_hsi1_mmc_card", CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_PCIE, "gout_cmu_hsi1_pcie",
+	     "mout_cmu_hsi1_pcie", CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_UFS_CARD, "gout_cmu_hsi1_ufs_card",
+	     "mout_cmu_hsi1_ufs_card", CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_UFS_EMBD, "gout_cmu_hsi1_ufs_embd",
+	     "mout_cmu_hsi1_ufs_embd", CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI2_BUS, "gout_cmu_hsi2_bus", "mout_cmu_hsi2_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI2_PCIE, "gout_cmu_hsi2_pcie",
+	     "mout_cmu_hsi2_pcie", CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_IPP_BUS, "gout_cmu_ipp_bus", "mout_cmu_ipp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_IPP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_ITP_BUS, "gout_cmu_itp_bus", "mout_cmu_itp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_ITP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MCSC_BUS, "gout_cmu_mcsc_bus", "mout_cmu_mcsc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MCSC_GDC, "gout_cmu_mcsc_gdc", "mout_cmu_mcsc_gdc",
+	     CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MFC0_MFC0, "gout_cmu_mfc0_mfc0",
+	     "mout_cmu_mfc0_mfc0", CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MFC0_WFD, "gout_cmu_mfc0_wfd", "mout_cmu_mfc0_wfd",
+	     CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MIF_BUSP, "gout_cmu_mif_busp", "mout_cmu_mif_busp",
+	     CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_NPU_BUS, "gout_cmu_npu_bus", "mout_cmu_npu_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_NPU_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC0_BUS, "gout_cmu_peric0_bus",
+	     "mout_cmu_peric0_bus", CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC0_IP, "gout_cmu_peric0_ip",
+	     "mout_cmu_peric0_ip", CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC1_BUS, "gout_cmu_peric1_bus",
+	     "mout_cmu_peric1_bus", CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC1_IP, "gout_cmu_peric1_ip",
+	     "mout_cmu_peric1_ip", CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIS_BUS, "gout_cmu_peris_bus",
+	     "mout_cmu_peris_bus", CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_SSP_BUS, "gout_cmu_ssp_bus", "mout_cmu_ssp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_SSP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_TNR_BUS, "gout_cmu_tnr_bus", "mout_cmu_tnr_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_TNR_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_VRA_BUS, "gout_cmu_vra_bus", "mout_cmu_vra_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_VRA_BUS, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info top_cmu_info __initconst = {
+	.pll_clks = top_pll_clks,
+	.nr_pll_clks = ARRAY_SIZE(top_pll_clks),
+	.mux_clks = top_mux_clks,
+	.nr_mux_clks = ARRAY_SIZE(top_mux_clks),
+	.div_clks = top_div_clks,
+	.nr_div_clks = ARRAY_SIZE(top_div_clks),
+	.gate_clks = top_gate_clks,
+	.nr_gate_clks = ARRAY_SIZE(top_gate_clks),
+	.nr_clk_ids = CLKS_NR_TOP,
+	.clk_regs = top_clk_regs,
+	.nr_clk_regs = ARRAY_SIZE(top_clk_regs),
+};
+
+static void __init exynos990_cmu_top_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
+}
+
+/* Register CMU_TOP early, as it's a dependency for other early domains */
+CLK_OF_DECLARE(exynos990_cmu_top, "samsung,exynos990-cmu-top",
+	       exynos990_cmu_top_init);
+
+/* ---- CMU_HSI0 ------------------------------------------------------------ */
+
+/* Register Offset definitions for CMU_HSI0 (0x10a00000) */
+#define PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER						0x0600
+#define PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER						0x0620
+#define PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER					0x0630
+#define PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER						0x0610
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK			0x2004
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK			0x2018
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHS_ACEL_D_HSI0_IPCLKPORT_I_CLK			0x2014
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK		0x2020
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK			0x2044
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK				0x2008
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK			0x200c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK			0x2010
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK			0x201c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2			0x2024
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK			0x2028
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL			0x202c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40		0x2034
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK	0x203c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK		0x2040
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY			0x2030
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK			0x2000
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK				0x2048
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL		0x2038
+
+static const unsigned long hsi0_clk_regs[] __initconst = {
+	PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHS_ACEL_D_HSI0_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK,
+};
+
+PNAME(mout_hsi0_bus_user_p)		= { "oscclk", "dout_cmu_hsi0_bus" };
+PNAME(mout_hsi0_usb31drd_user_p)	= { "oscclk", "dout_cmu_hsi0_usb31drd" };
+PNAME(mout_hsi0_usbdp_debug_user_p)	= { "oscclk",
+					    "dout_cmu_hsi0_usbdp_debug" };
+PNAME(mout_hsi0_dpgtc_user_p)		= { "oscclk", "dout_cmu_hsi0_dpgtc" };
+
+static const struct samsung_mux_clock hsi0_mux_clks[] __initconst = {
+	MUX(CLK_MOUT_HSI0_BUS_USER, "mout_hsi0_bus_user",
+	    mout_hsi0_bus_user_p, PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_USB31DRD_USER, "mout_hsi0_usb31drd_user",
+	    mout_hsi0_usb31drd_user_p, PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_USBDP_DEBUG_USER, "mout_hsi0_usbdp_debug_user",
+	    mout_hsi0_usbdp_debug_user_p,
+	    PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_DPGTC_USER, "mout_hsi0_dpgtc_user",
+	    mout_hsi0_dpgtc_user_p, PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER,
+	    4, 1),
+};
+
+static const struct samsung_gate_clock hsi0_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_HSI0_DP_LINK_DP_GTC_CLK,
+	     "gout_hsi0_dp_link_dp_gtc_clk", "mout_hsi0_dpgtc_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_DP_LINK_PCLK,
+	     "gout_hsi0_dp_link_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK,
+	     "gout_hsi0_d_tzpc_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_LHM_AXI_P_HSI0_CLK,
+	     "gout_hsi0_lhm_axi_p_hsi0_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK,
+	     21, CLK_IS_CRITICAL, 0),
+	GATE(CLK_GOUT_HSI0_PPMU_HSI0_BUS1_ACLK,
+	     "gout_hsi0_ppmu_hsi0_bus1_aclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_PPMU_HSI0_BUS1_PCLK,
+	     "gout_hsi0_ppmu_hsi0_bus1_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK,
+	     "gout_hsi0_clk_hsi0_bus_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2,
+	     "gout_hsi0_sysmmu_usb_clk_s2", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_HSI0_SYSREG_HSI0_PCLK,
+	     "gout_hsi0_sysreg_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL,
+	     "gout_hsi0_usb31drd_aclk_phyctrl", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY,
+	     "gout_hsi0_usb31drd_bus_clk_early",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USB31DRD_REF_CLK_40,
+	     "gout_hsi0_usb31drd_usb31drd_ref_clk_40",
+	     "mout_hsi0_usb31drd_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBDPPHY_REF_SOC_PLL,
+	     "gout_hsi0_usb31drd_usbdpphy_ref_soc_pll",
+	     "mout_hsi0_usbdp_debug_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBDPPHY_SCL_APB,
+	     "gout_hsi0_usb31drd_ipclkport_i_usbdpphy_scl_apb_pclk",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBPCS_APB_CLK,
+	     "gout_hsi0_usb31drd_usbpcs_apb_clk",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_VGEN_LITE_HSI0_CLK,
+	     "gout_hsi0_vgen_lite_ipclkport_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_CMU_HSI0_PCLK,
+	     "gout_hsi0_cmu_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_HSI0_XIU_D_HSI0_ACLK,
+	     "gout_hsi0_xiu_d_hsi0_aclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info hsi0_cmu_info __initconst = {
+	.mux_clks = hsi0_mux_clks,
+	.nr_mux_clks = ARRAY_SIZE(hsi0_mux_clks),
+	.gate_clks = hsi0_gate_clks,
+	.nr_gate_clks = ARRAY_SIZE(hsi0_gate_clks),
+	.nr_clk_ids = CLKS_NR_HSI0,
+	.clk_regs = hsi0_clk_regs,
+	.nr_clk_regs = ARRAY_SIZE(hsi0_clk_regs),
+	.clk_name		= "dout_cmu_hsi0_bus",
+};
+
+/* ----- platform_driver ----- */
+
+static int __init exynos990_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+static const struct of_device_id exynos990_cmu_of_match[] = {
+	{
+		.compatible = "samsung,exynos990-cmu-hsi0",
+		.data = &hsi0_cmu_info,
+	},
+	{ },
+};
+
+static struct platform_driver exynos990_cmu_driver __refdata = {
+	.driver	= {
+		.name = "exynos990-cmu",
+		.of_match_table = exynos990_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = exynos990_cmu_probe,
+};
+
+static int __init exynos990_cmu_init(void)
+{
+	return platform_driver_register(&exynos990_cmu_driver);
+}
+
+core_initcall(exynos990_cmu_init);

-- 
2.45.2



From pratyush at kernel.org  Fri Dec  6 08:11:55 2024
From: pratyush at kernel.org (Pratyush Yadav)
Date: Fri, 06 Dec 2024 16:11:55 +0000
Subject: [PATCH v5 1/3] dt-bindings: mtd: jedec,spi-nor: add optional
 vcc-supply
In-Reply-To: <20241111111946.9048-1-tudor.ambarus@linaro.org> (Tudor Ambarus's
	message of "Mon, 11 Nov 2024 13:19:44 +0200")
References: <20241111111946.9048-1-tudor.ambarus@linaro.org>
Message-ID: <mafs034j04wqc.fsf@kernel.org>

On Mon, Nov 11 2024, Tudor Ambarus wrote:

> From: Peng Fan <peng.fan at nxp.com>
>
> Introduce optional vcc-supply property, SPI NOR flashes needs power supply
> to work properly. The power supply maybe software controlable per board
> design.
>
> Acked-by: Rob Herring (Arm) <robh at kernel.org>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>

Series applied to spi-nor/next. Thanks!

-- 
Regards,
Pratyush Yadav


From qperret at google.com  Fri Dec  6 08:12:52 2024
From: qperret at google.com (Quentin Perret)
Date: Fri, 6 Dec 2024 16:12:52 +0000
Subject: [PATCH v4 01/14] KVM: arm64: Consolidate allowed and restricted
 VM feature checks
In-Reply-To: <20241202154742.3611749-2-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-2-tabba@google.com>
Message-ID: <Z1MihH-aLq6lTccm@google.com>

On Monday 02 Dec 2024 at 15:47:28 (+0000), Fuad Tabba wrote:
> The definitions for features allowed and allowed with
> restrictions for protected guests, which are based on feature
> registers, were defined and checked for separately, even though
> they are handled in the same way. This could result in missing
> checks for certain features, e.g., pointer authentication,
> causing traps for allowed features.
> 
> Consolidate the definitions into one. Use that new definition to
> construct the guest view of the feature registers for
> consistency.
> 
> Fixes: 6c30bfb18d0b ("KVM: arm64: Add handlers for protected VM System Registers")
> Reported-by: Mostafa Saleh <smostafa at google.com>
> Signed-off-by: Fuad Tabba <tabba at google.com>
> 
> ---
> 
> Note: This patch ends up being a no-op, since none of the changes
> in it survive the series. It's included because it makes the rest
> of the series flow more smoothly.

Is the Fixes: tag above really needed then? It 'risks' being flagged as
a -stable candidate, but should it be?


From igor.belwon at mentallysanemainliners.org  Fri Dec  6 08:12:17 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Fri, 06 Dec 2024 17:12:17 +0100
Subject: [PATCH v2 0/3] clk: samsung: Introduce Exynos990 clock support
Message-ID: <20241206-exynos990-cmu-v2-0-4666ff0a099b@mentallysanemainliners.org>

Hi all,

This patchset adds support for the Clock Management Unit found in the
Exynos990 SoC. This CMU allows for clocking peripherals such as USB, UFS,
MCT, et cetera.

Currently there are two blocks implemented, CMU_TOP which
generates clocks for other blocks, and CMU_HSI0, which generates clocks
for USB. More blocks will be added (hopefully soon), like HSI1 for UFS.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
Igor Belwon (3):
      dt-bindings: clock: Add Exynos990 SoC CMU bindings
      clk: samsung: clk-pll: Add support for pll_{0717x, 0718x, 0732x}
      clk: samsung: Introduce Exynos990 clock controller driver

 .../bindings/clock/samsung,exynos990-clock.yaml    |  120 ++
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-exynos990.c                | 1343 ++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c                      |   14 +-
 drivers/clk/samsung/clk-pll.h                      |    3 +
 include/dt-bindings/clock/samsung,exynos990.h      |  236 ++++
 6 files changed, 1715 insertions(+), 2 deletions(-)
---
base-commit: ebe1b11614e079c5e366ce9bd3c8f44ca0fbcc1b
change-id: 20241206-exynos990-cmu-58ada5056ad5

Best regards,
-- 
Igor Belwon <igor.belwon at mentallysanemainliners.org>



From ivo.ivanov.ivanov1 at gmail.com  Fri Dec  6 08:14:16 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Fri, 6 Dec 2024 18:14:16 +0200
Subject: [PATCH v5 2/4] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S20 Series boards (hubble)
In-Reply-To: <20241206154149.4271-3-umer.uddin@mentallysanemainliners.org>
References: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
 <20241206154149.4271-3-umer.uddin@mentallysanemainliners.org>
Message-ID: <51a87200-e562-409c-af21-2216288beb67@gmail.com>

On 12/6/24 17:41, Umer Uddin wrote:
> Add initial support for the Samsung Galaxy S20 Series (hubble) phones.
> They were launched in 2020, and are based on the Exynos 990 SoC.
> The devices have multiple RAM configurations,

A very small nit that I've noticed repeatedly in the other 990
commits as well:

In the future, try to wrap commit message according to Linux coding
style / submission process - neither too early nor over the limit, so
that commit messages can look as good as they can:

https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597

For example, in this particular case, you could move "starting from
8GB" to the previous line, like so:

...
They were launched in 2020, and are based on the Exynos 990 SoC.
The devices have multiple RAM configurations, starting from 8GB
going all the way up to 16GB For the S20 Ultra devices.

Otherwise, it looks good to me.

Best regards, Ivo.

> starting from 8GB going all the way up to 16GB for the S20 Ultra devices.
>
> This device tree adds support for the following:
>
> - SimpleFB
> - 8GB RAM (Any more will be mapped in device trees)
> - Buttons
>
> Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
> ---
>  .../boot/dts/exynos/exynos990-x1s-common.dtsi | 98 +++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
> new file mode 100644
> index 000000000..55fa8e9e0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> +/*
> + * Samsung Galaxy S20 Series device tree source
> + *
> + * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
> + */
> +
> +/dts-v1/;
> +#include "exynos990.dtsi"
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +/ {
> +	chosen {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		framebuffer0: framebuffer at f1000000 {
> +			compatible = "simple-framebuffer";
> +			reg = <0 0xf1000000 0 (1440 * 3200 * 4)>;
> +			width = <1440>;
> +			height = <3200>;
> +			stride = <(1440 * 4)>;
> +			format = "a8r8g8b8";
> +		};
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		cont_splash_mem: framebuffer at f1000000 {
> +			reg = <0 0xf1000000 0 0x1194000>;
> +			no-map;
> +		};
> +
> +		abox_reserved: audio at f7fb0000 {
> +			reg = <0 0xf7fb0000 0 0x2a50000>;
> +			no-map;
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +
> +		pinctrl-0 = <&key_power &key_voldown &key_volup>;
> +		pinctrl-names = "default";
> +
> +		power-key {
> +			label = "Power";
> +			linux,code = <KEY_POWER>;
> +			gpios = <&gpa2 4 GPIO_ACTIVE_LOW>;
> +			wakeup-source;
> +		};
> +
> +		voldown-key {
> +			label = "Volume Down";
> +			linux,code = <KEY_VOLUMEDOWN>;
> +			gpios = <&gpa0 4 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		volup-key {
> +			label = "Volume Up";
> +			linux,code = <KEY_VOLUMEUP>;
> +			gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +};
> +
> +&oscclk {
> +	clock-frequency = <26000000>;
> +};
> +
> +&pinctrl_alive {
> +	key_power: key-power-pins {
> +		samsung,pins = "gpa2-4";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
> +	};
> +
> +	key_voldown: key-voldown-pins {
> +		samsung,pins = "gpa0-4";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
> +	};
> +
> +	key_volup: key-volup-pins {
> +		samsung,pins = "gpa0-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
> +	};
> +};



From ja at ssi.bg  Fri Dec  6 08:23:11 2024
From: ja at ssi.bg (Julian Anastasov)
Date: Fri, 6 Dec 2024 18:23:11 +0200 (EET)
Subject: [PATCH net] Fix clamp() of ip_vs_conn_tab on small memory
 systems.
In-Reply-To: <2a91ee407ed64d24b82e5fc665971add@AcuMS.aculab.com>
References: <33893212b1cc4a418cec09aeeed0a9fc@AcuMS.aculab.com> <5ec10e7c-d050-dab8-1f1b-d0ca2d922eef@ssi.bg> <2a91ee407ed64d24b82e5fc665971add@AcuMS.aculab.com>
Message-ID: <c0a2ee53-f6ff-f4d4-e9ab-6a3bf850bec5@ssi.bg>


	Hello,

On Fri, 6 Dec 2024, David Laight wrote:

> From: Julian Anastasov
> > Sent: 06 December 2024 12:19
> > 
> > On Fri, 6 Dec 2024, David Laight wrote:
> > 
> > > The intention of the code seems to be that the minimum table
> > > size should be 256 (1 << min).
> > > However the code uses max = clamp(20, 5, max_avail) which implies
> > 
> > 	Actually, it tries to reduce max=20 (max possible) below
> > max_avail: [8 .. max_avail]. Not sure what 5 is here...
> 
> Me mistyping values between two windows :-)
> 
> Well min(max, max_avail) would be the reduced upper limit.
> But you'd still fall foul of the compiler propagating the 'n > 1'
> check in order_base_2() further down the function.
> 
> > > the author thought max_avail could be less than 5.
> > > But clamp(val, min, max) is only well defined for max >= min.
> > > If max < min whether is returns min or max depends on the order of
> > > the comparisons.
> > 
> > 	Looks like max_avail goes below 8 ? What value you see
> > for such small system?
> 
> I'm not, but clearly you thought the value could be small otherwise
> the code would only have a 'max' limit.
> (Apart from a 'sanity' min of maybe 2 to stop the code breaking.)

	I'm not sure how much memory we can see in small system,
IMHO, problem should not be possible in practice:

- nobody expects 0 from totalram_pages() in the code

- order_base_2(sizeof(struct ip_vs_conn)) is probably 8 on 32-bit

- PAGE_SHIFT: 12 (for 4KB) or more?

	So, if totalram_pages() returns below 128 pages (4KB each)
max_avail will be below 19 (7 + 12), then 19 is reduced with 2 + 1
and becomes 16, finally with 8 (from the 2nd order_base_2) to reach
16-8=8. You need a system with less than 512KB (19 bits) to trigger 
problem in clamp() that will lead to max below 8. Further, without
checks, for ip_vs_conn_tab_bits=1 we need totalram_pages() to return 0
pages.

> > > Detected by compile time checks added to clamp(), specifically:
> > > minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
> > 
> > 	Existing or new check? Does it happen that max_avail
> > is a constant, so that a compile check triggers?
> 
> Is all stems from order_base_2(totalram_pages()).
> order_base_2(n) is 'n > 1 ? ilog2(n - 1) + 1 : 0'.
> And the compiler generates two copies of the code that follows
> for the 'constant zero' and ilog2() values.
> And the 'zero' case compiles clamp(20, 8, 0) which is errored.
> Note that it is only executed if totalram_pages() is zero,
> but it is always compiled 'just in case'.

	I'm confused with these compiler issues, if you
think we should go with the patch just decide if it is a
net or net-next material. Your change is safer for bad
max_avail values but I don't expect to see problem while
running without the change, except the building bugs.

	Also, please use nf/nf-next tag to avoid any
confusion with upstreaming...

Regards

--
Julian Anastasov <ja at ssi.bg>



From ivo.ivanov.ivanov1 at gmail.com  Fri Dec  6 08:29:08 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Fri, 6 Dec 2024 18:29:08 +0200
Subject: [PATCH v5 3/4] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S20 5G (x1s)
In-Reply-To: <20241206154149.4271-4-umer.uddin@mentallysanemainliners.org>
References: <20241206154149.4271-1-umer.uddin@mentallysanemainliners.org>
 <20241206154149.4271-4-umer.uddin@mentallysanemainliners.org>
Message-ID: <be1bcd99-8a05-4b7f-8546-23cd96071e05@gmail.com>

On 12/6/24 17:41, Umer Uddin wrote:
> Add initial support for the Samsung Galaxy S20 5G (x1s/SM-G981B)
> phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
> has only one configuration with 12GB of RAM and 128GB of UFS 3.0 storage.
>
> This device tree adds support for the following:
>
> - SimpleFB
> - 12GB RAM
> - Buttons
>
> Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
> ---
>  arch/arm64/boot/dts/exynos/Makefile          |  1 +
>  arch/arm64/boot/dts/exynos/exynos990-x1s.dts | 28 ++++++++++++++++++++
>  2 files changed, 29 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts
>
> diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
> index 948a2c6cb..7dbecd367 100644
> --- a/arch/arm64/boot/dts/exynos/Makefile
> +++ b/arch/arm64/boot/dts/exynos/Makefile
> @@ -10,5 +10,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
>  	exynos8895-dreamlte.dtb		\
>  	exynos990-c1s.dtb		\
>  	exynos990-r8s.dtb               \
> +        exynos990-x1s.dtb               \

I noticed that there's spaces instead of tabs to indent the '\' after
exynos990-r8s.dtb, unlike the rest of the entries. This patch also
uses spaces to indent the whole entry. If maintainers are fine with
it, then it's alright, but if there's a v6 you could change it to use
tabs for consistancy's sake.

Rest looks fine to me.

Best regards, Ivo.

>  	exynosautov9-sadk.dtb		\
>  	exynosautov920-sadk.dtb
> diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s.dts b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
> new file mode 100644
> index 000000000..1ae881015
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
> @@ -0,0 +1,28 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> +/*
> + * Samsung Galaxy S20 5G (x1s/SM-G981B) device tree source
> + *
> + * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
> + */
> +
> +/dts-v1/;
> +#include "exynos990-x1s-common.dtsi"
> +
> +/ {
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	model = "Samsung Galaxy S20 5G";
> +	compatible = "samsung,x1s", "samsung,exynos990";
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		reg = <0x0 0x80000000 0x0 0x3ab00000>,
> +		      /* Memory hole */
> +		      <0x0 0xc1200000 0x0 0x1ee00000>,
> +		      /* Memory hole */
> +		      <0x0 0xe1900000 0x0 0x1e700000>,
> +		      /* Memory hole */
> +		      <0x8 0x80000000 0x2 0x7e800000>;
> +	};
> +};



From andre.draszik at linaro.org  Fri Dec  6 08:31:01 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 06 Dec 2024 16:31:01 +0000
Subject: [PATCH v4 1/7] dt-bindings: phy: samsung,usb3-drd-phy: add blank
 lines between DT properties
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
Message-ID: <20241206-gs101-phy-lanes-orientation-phy-v4-1-f5961268b149@linaro.org>

In [1], Rob pointed out that we should really be separating properties
with blank lines in between, which is universal style. Only where
properties are booleans, empty lines are not required.

Do so.

Link: https://lore.kernel.org/all/20240711212359.GA3023490-robh at kernel.org/ [1]
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v3:
* update subject line (Rob)
* collect tags

v2:
* collect tags
---
 .../devicetree/bindings/phy/samsung,usb3-drd-phy.yaml     | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index 16321cdd4919..1f8b35917b11 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -83,14 +83,19 @@ properties:
 
   pll-supply:
     description: Power supply for the USB PLL.
+
   dvdd-usb20-supply:
     description: DVDD power supply for the USB 2.0 phy.
+
   vddh-usb20-supply:
     description: VDDh power supply for the USB 2.0 phy.
+
   vdd33-usb20-supply:
     description: 3.3V power supply for the USB 2.0 phy.
+
   vdda-usbdp-supply:
     description: VDDa power supply for the USB DP phy.
+
   vddh-usbdp-supply:
     description: VDDh power supply for the USB DP phy.
 
@@ -117,6 +122,7 @@ allOf:
             - description: Gate of control interface AXI clock
             - description: Gate of control interface APB clock
             - description: Gate of SCL APB clock
+
         clock-names:
           items:
             - const: phy
@@ -124,10 +130,13 @@ allOf:
             - const: ctrl_aclk
             - const: ctrl_pclk
             - const: scl_pclk
+
         reg:
           minItems: 3
+
         reg-names:
           minItems: 3
+
       required:
         - reg-names
         - pll-supply
@@ -149,6 +158,7 @@ allOf:
         clocks:
           minItems: 5
           maxItems: 5
+
         clock-names:
           items:
             - const: phy
@@ -156,8 +166,10 @@ allOf:
             - const: phy_utmi
             - const: phy_pipe
             - const: itp
+
         reg:
           maxItems: 1
+
         reg-names:
           maxItems: 1
 
@@ -174,12 +186,15 @@ allOf:
         clocks:
           minItems: 2
           maxItems: 2
+
         clock-names:
           items:
             - const: phy
             - const: ref
+
         reg:
           maxItems: 1
+
         reg-names:
           maxItems: 1
 

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Fri Dec  6 08:31:03 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 06 Dec 2024 16:31:03 +0000
Subject: [PATCH v4 3/7] phy: exynos5-usbdrd: convert to dev_err_probe
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
Message-ID: <20241206-gs101-phy-lanes-orientation-phy-v4-3-f5961268b149@linaro.org>

dev_err_probe() exists to simplify code.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index c421b495eb0f..ceae4b47cece 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1725,10 +1725,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 
 	reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node,
 						   "samsung,pmu-syscon");
-	if (IS_ERR(reg_pmu)) {
-		dev_err(dev, "Failed to lookup PMU regmap\n");
-		return PTR_ERR(reg_pmu);
-	}
+	if (IS_ERR(reg_pmu))
+		return dev_err_probe(dev, PTR_ERR(reg_pmu),
+				     "Failed to lookup PMU regmap\n");
 
 	/*
 	 * Exynos5420 SoC has multiple channels for USB 3.0 PHY, with
@@ -1759,10 +1758,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 	for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {
 		struct phy *phy = devm_phy_create(dev, NULL, drv_data->phy_ops);
 
-		if (IS_ERR(phy)) {
-			dev_err(dev, "Failed to create usbdrd_phy phy\n");
-			return PTR_ERR(phy);
-		}
+		if (IS_ERR(phy))
+			return dev_err_probe(dev, PTR_ERR(phy),
+					     "Failed to create usbdrd_phy phy\n");
 
 		phy_drd->phys[i].phy = phy;
 		phy_drd->phys[i].index = i;
@@ -1786,10 +1784,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 
 	phy_provider = devm_of_phy_provider_register(dev,
 						     exynos5_usbdrd_phy_xlate);
-	if (IS_ERR(phy_provider)) {
-		dev_err(phy_drd->dev, "Failed to register phy provider\n");
-		return PTR_ERR(phy_provider);
-	}
+	if (IS_ERR(phy_provider))
+		return dev_err_probe(phy_drd->dev, PTR_ERR(phy_provider),
+				     "Failed to register phy provider\n");
 
 	return 0;
 }

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Fri Dec  6 08:31:04 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 06 Dec 2024 16:31:04 +0000
Subject: [PATCH v4 4/7] phy: exynos5-usbdrd: fix EDS distribution tuning
 (gs101)
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
Message-ID: <20241206-gs101-phy-lanes-orientation-phy-v4-4-f5961268b149@linaro.org>

This code's intention is to configure lane0 and lane2 tunings, but for
lane2 there is a typo and it ends up tuning something else.

Fix the typo, as it doesn't appear to make sense to apply different
tunings for lane0 vs lane2.

The same typo appears to exist in the bootloader, hence we restore the
original value in the typo'd registers as well. This can be removed
once / if the bootloader is updated.

Note that this is incorrect in the downstream driver as well - the
values had been copied from there.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index ceae4b47cece..2a724d362c2d 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1510,8 +1510,11 @@ static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_preinit[] = {
 	PHY_TUNING_ENTRY_PMA(0x09e0, -1, 0x00),
 	PHY_TUNING_ENTRY_PMA(0x09e4, -1, 0x36),
 	PHY_TUNING_ENTRY_PMA(0x1e7c, -1, 0x06),
-	PHY_TUNING_ENTRY_PMA(0x1e90, -1, 0x00),
-	PHY_TUNING_ENTRY_PMA(0x1e94, -1, 0x36),
+	PHY_TUNING_ENTRY_PMA(0x19e0, -1, 0x00),
+	PHY_TUNING_ENTRY_PMA(0x19e4, -1, 0x36),
+	/* fix bootloader bug */
+	PHY_TUNING_ENTRY_PMA(0x1e90, -1, 0x02),
+	PHY_TUNING_ENTRY_PMA(0x1e94, -1, 0x0b),
 	/* improve LVCC */
 	PHY_TUNING_ENTRY_PMA(0x08f0, -1, 0x30),
 	PHY_TUNING_ENTRY_PMA(0x18f0, -1, 0x30),

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Fri Dec  6 08:31:06 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 06 Dec 2024 16:31:06 +0000
Subject: [PATCH v4 6/7] phy: exynos5-usbdrd: subscribe to orientation
 notifier if required
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
Message-ID: <20241206-gs101-phy-lanes-orientation-phy-v4-6-f5961268b149@linaro.org>

gs101's SS phy needs to be configured differently based on the
connector orientation, as the SS link can only be established if the
mux is configured correctly.

The code to handle programming of the mux is in place already, this commit
now adds the missing pieces to subscribe to the Type-C orientation
switch event.

Note that for this all to work we rely on the USB controller
re-initialising us. It should invoke our .exit() upon cable unplug, and
during cable plug we'll receive the orientation event after which we
expect our .init() to be called.

Above reinitialisation happens if the DWC3 controller can enter runtime
suspend automatically. For the DWC3 driver, this is an opt-in:
    echo auto > /sys/devices/.../11110000.usb/power/control
Once done, things work as long as the UDC is not bound as otherwise it
stays busy because it doesn't cancel / stop outstanding TRBs. For now
we have to manually unbind the UDC in that case:
     echo "" > sys/kernel/config/usb_gadget/.../UDC

Note that if the orientation-switch property is missing from the DT,
the code will behave as before this commit (meaning for gs101 it will
work in SS mode in one orientation only). Other platforms are not
affected either way.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v3:
* drop init to -1 of phy_drd->orientation (Vinod)
* avoid #ifdef and switch to normal conditional IS_ENABLED() for
  CONFIG_TYPEC

v2:
* move #include typec_mux.h from parent patch into this one (Peter)
---
 drivers/phy/samsung/Kconfig              |  1 +
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 56 ++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig
index f10afa3d7ff5..fc7bd1088576 100644
--- a/drivers/phy/samsung/Kconfig
+++ b/drivers/phy/samsung/Kconfig
@@ -80,6 +80,7 @@ config PHY_EXYNOS5_USBDRD
 	tristate "Exynos5 SoC series USB DRD PHY driver"
 	depends on (ARCH_EXYNOS && OF) || COMPILE_TEST
 	depends on HAS_IOMEM
+	depends on TYPEC || (TYPEC=n && COMPILE_TEST)
 	depends on USB_DWC3_EXYNOS
 	select GENERIC_PHY
 	select MFD_SYSCON
diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 61e0de4b3d4b..8fc15847cfd8 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -24,6 +24,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/usb/typec.h>
+#include <linux/usb/typec_mux.h>
 
 /* Exynos USB PHY registers */
 #define EXYNOS5_FSEL_9MHZ6		0x0
@@ -394,6 +395,7 @@ struct exynos5_usbdrd_phy_drvdata {
  * @extrefclk: frequency select settings when using 'separate
  *	       reference clocks' for SS and HS operations
  * @regulators: regulators for phy
+ * @sw: TypeC orientation switch handle
  * @orientation: TypeC connector orientation - normal or flipped
  */
 struct exynos5_usbdrd_phy {
@@ -415,6 +417,7 @@ struct exynos5_usbdrd_phy {
 	u32 extrefclk;
 	struct regulator_bulk_data *regulators;
 
+	struct typec_switch_dev *sw;
 	enum typec_orientation orientation;
 };
 
@@ -1397,6 +1400,55 @@ static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd)
 	return 0;
 }
 
+static int exynos5_usbdrd_orien_sw_set(struct typec_switch_dev *sw,
+				       enum typec_orientation orientation)
+{
+	struct exynos5_usbdrd_phy *phy_drd = typec_switch_get_drvdata(sw);
+
+	scoped_guard(mutex, &phy_drd->phy_mutex)
+		phy_drd->orientation = orientation;
+
+	return 0;
+}
+
+static void exynos5_usbdrd_orien_switch_unregister(void *data)
+{
+	struct exynos5_usbdrd_phy *phy_drd = data;
+
+	typec_switch_unregister(phy_drd->sw);
+}
+
+static int exynos5_usbdrd_setup_notifiers(struct exynos5_usbdrd_phy *phy_drd)
+{
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_TYPEC))
+		return 0;
+
+	if (device_property_present(phy_drd->dev, "orientation-switch")) {
+		struct typec_switch_desc sw_desc = { };
+
+		sw_desc.drvdata = phy_drd;
+		sw_desc.fwnode = dev_fwnode(phy_drd->dev);
+		sw_desc.set = exynos5_usbdrd_orien_sw_set;
+
+		phy_drd->sw = typec_switch_register(phy_drd->dev, &sw_desc);
+		if (IS_ERR(phy_drd->sw))
+			return dev_err_probe(phy_drd->dev,
+					     PTR_ERR(phy_drd->sw),
+					     "Failed to register TypeC orientation switch\n");
+
+		ret = devm_add_action_or_reset(phy_drd->dev,
+					       exynos5_usbdrd_orien_switch_unregister,
+					       phy_drd);
+		if (ret)
+			return dev_err_probe(phy_drd->dev, ret,
+					     "Failed to register TypeC orientation devm action\n");
+	}
+
+	return 0;
+}
+
 static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
 	{
 		.id		= EXYNOS5_DRDPHY_UTMI,
@@ -1786,6 +1838,10 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to get regulators\n");
 
+	ret = exynos5_usbdrd_setup_notifiers(phy_drd);
+	if (ret)
+		return ret;
+
 	dev_vdbg(dev, "Creating usbdrd_phy phy\n");
 
 	for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Fri Dec  6 08:31:05 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 06 Dec 2024 16:31:05 +0000
Subject: [PATCH v4 5/7] phy: exynos5-usbdrd: gs101: configure SS lanes
 based on orientation
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
Message-ID: <20241206-gs101-phy-lanes-orientation-phy-v4-5-f5961268b149@linaro.org>

USB SS lanes need to be configured based on the connector orientation -
at most two lanes will be in use for USB (and the remaining two for
alternate modes like DP).

For the USB link to come up in SS, the lane configuration registers
have to be programmed accordingly.

While we still need a way to be notified of the actual connector
orientation and then reprogram the registers accordingly (at the moment
the configuration happens just once during phy_init() and never again),
we can prepare the code doing the configuration to take the orientation
into account.

Do so.

Note: the mutex is needed to synchronize this with the upcoming
connector orientation callback.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v2:
* collect tags
* replace #include typec_mux.h with typec.h, and move the former into
  next patch (Peter)
* commit message typo (Peter)
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 72 ++++++++++++++++++++++----------
 1 file changed, 51 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 2a724d362c2d..61e0de4b3d4b 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -23,6 +23,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
+#include <linux/usb/typec.h>
 
 /* Exynos USB PHY registers */
 #define EXYNOS5_FSEL_9MHZ6		0x0
@@ -209,6 +210,10 @@
 
 #define EXYNOS9_PMA_USBDP_CMN_REG00B8		0x02e0
 #define CMN_REG00B8_LANE_MUX_SEL_DP		GENMASK(3, 0)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE3	BIT(3)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE2	BIT(2)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE1	BIT(1)
+#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE0	BIT(0)
 
 #define EXYNOS9_PMA_USBDP_CMN_REG01C0		0x0700
 #define CMN_REG01C0_ANA_LCPLL_LOCK_DONE		BIT(7)
@@ -383,11 +388,13 @@ struct exynos5_usbdrd_phy_drvdata {
  * @clks: clocks for register access
  * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required)
  * @drv_data: pointer to SoC level driver data structure
+ * @phy_mutex: mutex protecting phy_init/exit & TCPC callbacks
  * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY
  *	    instances each with its 'phy' and 'phy_cfg'.
  * @extrefclk: frequency select settings when using 'separate
  *	       reference clocks' for SS and HS operations
  * @regulators: regulators for phy
+ * @orientation: TypeC connector orientation - normal or flipped
  */
 struct exynos5_usbdrd_phy {
 	struct device *dev;
@@ -397,6 +404,7 @@ struct exynos5_usbdrd_phy {
 	struct clk_bulk_data *clks;
 	struct clk_bulk_data *core_clks;
 	const struct exynos5_usbdrd_phy_drvdata *drv_data;
+	struct mutex phy_mutex;
 	struct phy_usb_instance {
 		struct phy *phy;
 		u32 index;
@@ -406,6 +414,8 @@ struct exynos5_usbdrd_phy {
 	} phys[EXYNOS5_DRDPHYS_NUM];
 	u32 extrefclk;
 	struct regulator_bulk_data *regulators;
+
+	enum typec_orientation orientation;
 };
 
 static inline
@@ -647,22 +657,38 @@ exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(struct exynos5_usbdrd_phy *phy_drd)
 	/* lane configuration: USB on all lanes */
 	reg = readl(regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8);
 	reg &= ~CMN_REG00B8_LANE_MUX_SEL_DP;
-	writel(reg, regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8);
-
 	/*
-	 * FIXME: below code supports one connector orientation only. It needs
-	 * updating once we can receive connector events.
+	 * USB on lanes 0 & 1 in normal mode, or 2 & 3 if reversed, DP on the
+	 * other ones.
 	 */
+	reg |= FIELD_PREP(CMN_REG00B8_LANE_MUX_SEL_DP,
+			  ((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL)
+			   ? (CMN_REG00B8_LANE_MUX_SEL_DP_LANE3
+			      | CMN_REG00B8_LANE_MUX_SEL_DP_LANE2)
+			   : (CMN_REG00B8_LANE_MUX_SEL_DP_LANE1
+			      | CMN_REG00B8_LANE_MUX_SEL_DP_LANE0)));
+	writel(reg, regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8);
+
 	/* override of TX receiver detector and comparator: lane 1 */
 	reg = readl(regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0413);
-	reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN;
-	reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_EN;
+	if (phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) {
+		reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN;
+		reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_EN;
+	} else {
+		reg |= TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN;
+		reg |= TRSV_REG0413_OVRD_LN1_TX_RXD_EN;
+	}
 	writel(reg, regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0413);
 
 	/* lane 3 */
 	reg = readl(regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0813);
-	reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN;
-	reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_EN;
+	if (phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) {
+		reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN;
+		reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_EN;
+	} else {
+		reg &= ~TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN;
+		reg &= ~TRSV_REG0813_OVRD_LN3_TX_RXD_EN;
+	}
 	writel(reg, regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0813);
 }
 
@@ -700,21 +726,18 @@ exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock(struct exynos5_usbdrd_phy *phy_drd
 	int err;
 
 	err = readl_poll_timeout(
-			phy_drd->reg_pma + EXYNOS9_PMA_USBDP_TRSV_REG03C3,
-			reg, (reg & locked) == locked, sleep_us, timeout_us);
-	if (!err)
-		return;
-
-	dev_err(phy_drd->dev,
-		"timed out waiting for CDR lock (l0): %#.8x, retrying\n", reg);
-
-	/* based on cable orientation, this might be on the other phy port */
-	err = readl_poll_timeout(
-			phy_drd->reg_pma + EXYNOS9_PMA_USBDP_TRSV_REG07C3,
+			/* lane depends on cable orientation */
+			(phy_drd->reg_pma
+			 + ((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL)
+			    ? EXYNOS9_PMA_USBDP_TRSV_REG03C3
+			    : EXYNOS9_PMA_USBDP_TRSV_REG07C3)),
 			reg, (reg & locked) == locked, sleep_us, timeout_us);
 	if (err)
 		dev_err(phy_drd->dev,
-			"timed out waiting for CDR lock (l2): %#.8x\n", reg);
+			"timed out waiting for CDR(l%d) lock: %#.8x\n",
+			((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL)
+			 ? 0
+			 : 2), reg);
 }
 
 static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
@@ -1184,7 +1207,8 @@ static int exynos850_usbdrd_phy_init(struct phy *phy)
 		return ret;
 
 	/* UTMI or PIPE3 specific init */
-	inst->phy_cfg->phy_init(phy_drd);
+	scoped_guard(mutex, &phy_drd->phy_mutex)
+		inst->phy_cfg->phy_init(phy_drd);
 
 	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
 
@@ -1203,6 +1227,8 @@ static int exynos850_usbdrd_phy_exit(struct phy *phy)
 	if (ret)
 		return ret;
 
+	guard(mutex)(&phy_drd->phy_mutex);
+
 	/* Set PHY clock and control HS PHY */
 	reg = readl(regs_base + EXYNOS850_DRD_UTMI);
 	reg &= ~(UTMI_DP_PULLDOWN | UTMI_DM_PULLDOWN);
@@ -1698,6 +1724,10 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
 		return -EINVAL;
 	phy_drd->drv_data = drv_data;
 
+	ret = devm_mutex_init(dev, &phy_drd->phy_mutex);
+	if (ret)
+		return ret;
+
 	if (of_property_present(dev->of_node, "reg-names")) {
 		void __iomem *reg;
 

-- 
2.47.0.338.g60cca15819-goog



From andre.draszik at linaro.org  Fri Dec  6 08:31:07 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 06 Dec 2024 16:31:07 +0000
Subject: [PATCH v4 7/7] phy: exynos5-usbdrd: allow DWC3 runtime suspend
 with UDC bound (E850+)
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
Message-ID: <20241206-gs101-phy-lanes-orientation-phy-v4-7-f5961268b149@linaro.org>

To make USB runtime suspend work when a UDC has been bound, the phy
needs to inform the USBDRD controller (DWC3) that Vbus and bvalid are
gone, so that it can in turn raise the respective gadget interrupt with
event == DWC3_DEVICE_EVENT_DISCONNECT, which will cause the USB stack
to clean up, allowing DWC3 to enter runtime suspend.

On e850 and gs101 this isn't working, as the respective signals are not
directly connected, and instead this driver uses override bits in the
PHY IP to set those signals. It currently forcefully sets them to 'on',
so the above mentioned interrupt will not be raised, preventing runtime
suspend.

To detect that state, update this driver to act on the TCPC's
orientation signal - when orientation == NONE, Vbus is gone and we can
clear the respective bits. Similarly, for other orientation values we
re-enable them.

This makes runtime suspend work on platforms with a TCPC (like Pixel6),
while keeping compatibility with platforms without (e850-96).

With runtime suspend working, USB-C cable orientation detection now
also fully works on such platforms, and the link comes up as Superspeed
as expected irrespective of the cable orientation and whether UDC /
gadget are configured and active.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v3:
* update exynos5_usbdrd_orien_sw_set() to not test against previous
  orientation
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 50 +++++++++++++++++++++++++++-----
 1 file changed, 42 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 8fc15847cfd8..bac1dc927b26 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1137,13 +1137,15 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
 	reg |= LINKCTRL_BUS_FILTER_BYPASS(0xf);
 	writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL);
 
-	reg = readl(regs_base + EXYNOS850_DRD_UTMI);
-	reg |= UTMI_FORCE_BVALID | UTMI_FORCE_VBUSVALID;
-	writel(reg, regs_base + EXYNOS850_DRD_UTMI);
-
-	reg = readl(regs_base + EXYNOS850_DRD_HSP);
-	reg |= HSP_VBUSVLDEXT | HSP_VBUSVLDEXTSEL;
-	writel(reg, regs_base + EXYNOS850_DRD_HSP);
+	if (!phy_drd->sw) {
+		reg = readl(regs_base + EXYNOS850_DRD_UTMI);
+		reg |= UTMI_FORCE_BVALID | UTMI_FORCE_VBUSVALID;
+		writel(reg, regs_base + EXYNOS850_DRD_UTMI);
+
+		reg = readl(regs_base + EXYNOS850_DRD_HSP);
+		reg |= HSP_VBUSVLDEXT | HSP_VBUSVLDEXTSEL;
+		writel(reg, regs_base + EXYNOS850_DRD_HSP);
+	}
 
 	reg = readl(regs_base + EXYNOS850_DRD_SSPPLLCTL);
 	reg &= ~SSPPLLCTL_FSEL;
@@ -1404,9 +1406,41 @@ static int exynos5_usbdrd_orien_sw_set(struct typec_switch_dev *sw,
 				       enum typec_orientation orientation)
 {
 	struct exynos5_usbdrd_phy *phy_drd = typec_switch_get_drvdata(sw);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret) {
+		dev_err(phy_drd->dev, "Failed to enable PHY clocks(s)\n");
+		return ret;
+	}
+
+	scoped_guard(mutex, &phy_drd->phy_mutex) {
+		void __iomem * const regs_base = phy_drd->reg_phy;
+		unsigned int reg;
+
+		if (orientation == TYPEC_ORIENTATION_NONE) {
+			reg = readl(regs_base + EXYNOS850_DRD_UTMI);
+			reg &= ~(UTMI_FORCE_VBUSVALID | UTMI_FORCE_BVALID);
+			writel(reg, regs_base +  EXYNOS850_DRD_UTMI);
+
+			reg = readl(regs_base + EXYNOS850_DRD_HSP);
+			reg |= HSP_VBUSVLDEXTSEL;
+			reg &= ~HSP_VBUSVLDEXT;
+			writel(reg, regs_base + EXYNOS850_DRD_HSP);
+		} else {
+			reg = readl(regs_base + EXYNOS850_DRD_UTMI);
+			reg |= UTMI_FORCE_VBUSVALID | UTMI_FORCE_BVALID;
+			writel(reg, regs_base +  EXYNOS850_DRD_UTMI);
+
+			reg = readl(regs_base + EXYNOS850_DRD_HSP);
+			reg |= HSP_VBUSVLDEXTSEL | HSP_VBUSVLDEXT;
+			writel(reg, regs_base + EXYNOS850_DRD_HSP);
+		}
 
-	scoped_guard(mutex, &phy_drd->phy_mutex)
 		phy_drd->orientation = orientation;
+	}
+
+	clk_bulk_disable(phy_drd->drv_data->n_clks, phy_drd->clks);
 
 	return 0;
 }

-- 
2.47.0.338.g60cca15819-goog



From cleger at rivosinc.com  Fri Dec  6 08:30:56 2024
From: cleger at rivosinc.com (=?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?=)
Date: Fri,  6 Dec 2024 17:30:56 +0100
Subject: [PATCH v3 0/4] riscv: add support for SBI Supervisor Software Events
Message-ID: <20241206163102.843505-1-cleger@rivosinc.com>

The SBI Supervisor Software Events (SSE) extensions provides a mechanism
to inject software events from an SBI implementation to supervisor
software such that it preempts all other supervisor level traps and
interrupts. This specification is introduced by the SBI v3.0
specification[1].

Various events are defined and can be send asynchronously to supervisor
software (RAS, PMU, DEBUG, Asynchronous page fault) from SBI as well
as platform specific events. Events can be either local (per-hart) or
global. Events can be nested on top of each other based on priority and
can interrupt the kernel at any time.

First patch adds the SSE definitions. Second one adds support for SSE
at arch level (entry code and stack allocations) and third one at driver
level. Finally, the last patch add support for SSE events in the SBI PMU
driver. Additional testing for that part is highly welcomed since there
are a lot of possible path that needs to be exercised.

Amongst the specific points that needs to be handle is the interruption
at any point of the kernel execution and more specifically at the
beggining of exception handling. Due to the fact that the exception entry
implementation uses the SCRATCH CSR as both the current task struct and
as the temporary register to switch the stack and save register, it is
difficult to reliably get the current task struct if we get interrupted
at this specific moment (ie, it might contain 0, the task pointer or tp).
A fixup-like mechanism is not possible due to the nested nature of SSE
which makes it really hard to obtain the original interruption site. In
order to retrieve the task in a reliable maneer, add an additional
__sse_entry_task per_cpu array which stores the current task. Ideally,
we would need to modify the way we retrieve/store the current task in
exception handling so that it does not depend on the place where it's
interrupted.

Contrary to pseudo NMI [2], SSE does not modifies the way interrupts are
handled and does not adds any overhead to existing code. Moreover, it
provides "true" NMI-like interrupts which can interrupt the kernel at
any time (even in exception handling). This is particularly crucial for
RAS errors which needs to be handled as fast as possible to avoid any
fault propagation.

OpenSBI SSE support is already upstream.

Link: https://github.com/riscv-non-isa/riscv-sbi-doc/releases/download/vv3.0-rc2/riscv-sbi.pdf [1]

---

Changes in v3:
 - Split arch/driver support
 - Fix potential register failure reporting
 - Set a few pr_err as pr_debug
 - Allow CONFIG_RISCV_SSE to be disabled
 - Fix build without CONFIG_RISCV_SSE
 - Remove fixup-like mechanism and use a per-cpu array
 - Fixed SSCRATCH being corrupted when interrupting the kernel in early
   exception path.
 - Split SSE assembly from entry.S
 - Add Himanchu SSE mask/unmask and runtime PM support.
 - Disable user memory access/floating point/vector in SSE handler
 - Rebased on master

v2: https://lore.kernel.org/linux-riscv/20240112111720.2975069-1-cleger at rivosinc.com/

Changes in v2:
 - Implemented specification v2
 - Fix various error handling cases
 - Added shadow stack support

v1: https://lore.kernel.org/linux-riscv/20231026143122.279437-1-cleger at rivosinc.com/

Cl?ment L?ger (4):
  riscv: add SBI SSE extension definitions
  riscv: add support for SBI Supervisor Software Events extension
  drivers: firmware: add riscv SSE support
  perf: RISC-V: add support for SSE event

 MAINTAINERS                          |  14 +
 arch/riscv/include/asm/asm.h         |  14 +-
 arch/riscv/include/asm/sbi.h         |  62 +++
 arch/riscv/include/asm/scs.h         |   7 +
 arch/riscv/include/asm/sse.h         |  38 ++
 arch/riscv/include/asm/switch_to.h   |  14 +
 arch/riscv/include/asm/thread_info.h |   1 +
 arch/riscv/kernel/Makefile           |   1 +
 arch/riscv/kernel/asm-offsets.c      |  12 +
 arch/riscv/kernel/sse.c              | 134 ++++++
 arch/riscv/kernel/sse_entry.S        | 171 +++++++
 drivers/firmware/Kconfig             |   1 +
 drivers/firmware/Makefile            |   1 +
 drivers/firmware/riscv/Kconfig       |  15 +
 drivers/firmware/riscv/Makefile      |   3 +
 drivers/firmware/riscv/riscv_sse.c   | 691 +++++++++++++++++++++++++++
 drivers/perf/riscv_pmu_sbi.c         |  51 +-
 include/linux/riscv_sse.h            |  56 +++
 18 files changed, 1273 insertions(+), 13 deletions(-)
 create mode 100644 arch/riscv/include/asm/sse.h
 create mode 100644 arch/riscv/kernel/sse.c
 create mode 100644 arch/riscv/kernel/sse_entry.S
 create mode 100644 drivers/firmware/riscv/Kconfig
 create mode 100644 drivers/firmware/riscv/Makefile
 create mode 100644 drivers/firmware/riscv/riscv_sse.c
 create mode 100644 include/linux/riscv_sse.h

-- 
2.45.2



From cleger at rivosinc.com  Fri Dec  6 08:30:57 2024
From: cleger at rivosinc.com (=?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?=)
Date: Fri,  6 Dec 2024 17:30:57 +0100
Subject: [PATCH v3 1/4] riscv: add SBI SSE extension definitions
In-Reply-To: <20241206163102.843505-1-cleger@rivosinc.com>
References: <20241206163102.843505-1-cleger@rivosinc.com>
Message-ID: <20241206163102.843505-2-cleger@rivosinc.com>

Add needed definitions for SBI Supervisor Software Events extension [1].
This extension enables the SBI to inject events into supervisor software
much like ARM SDEI.

[1] https://lists.riscv.org/g/tech-prs/message/515

Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
---
 arch/riscv/include/asm/sbi.h | 62 ++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 6c82318065cf..032dde350d40 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -35,6 +35,7 @@ enum sbi_ext_id {
 	SBI_EXT_DBCN = 0x4442434E,
 	SBI_EXT_STA = 0x535441,
 	SBI_EXT_NACL = 0x4E41434C,
+	SBI_EXT_SSE = 0x535345,
 
 	/* Experimentals extensions must lie within this range */
 	SBI_EXT_EXPERIMENTAL_START = 0x08000000,
@@ -401,6 +402,63 @@ enum sbi_ext_nacl_feature {
 #define SBI_NACL_SHMEM_SRET_X(__i)		((__riscv_xlen / 8) * (__i))
 #define SBI_NACL_SHMEM_SRET_X_LAST		31
 
+enum sbi_ext_sse_fid {
+	SBI_SSE_EVENT_ATTR_READ = 0,
+	SBI_SSE_EVENT_ATTR_WRITE,
+	SBI_SSE_EVENT_REGISTER,
+	SBI_SSE_EVENT_UNREGISTER,
+	SBI_SSE_EVENT_ENABLE,
+	SBI_SSE_EVENT_DISABLE,
+	SBI_SSE_EVENT_COMPLETE,
+	SBI_SSE_EVENT_SIGNAL,
+	SBI_SSE_EVENT_HART_UNMASK,
+	SBI_SSE_EVENT_HART_MASK,
+};
+
+enum sbi_sse_state {
+	SBI_SSE_STATE_UNUSED     = 0,
+	SBI_SSE_STATE_REGISTERED = 1,
+	SBI_SSE_STATE_ENABLED    = 2,
+	SBI_SSE_STATE_RUNNING    = 3,
+};
+
+/* SBI SSE Event Attributes. */
+enum sbi_sse_attr_id {
+	SBI_SSE_ATTR_STATUS		= 0x00000000,
+	SBI_SSE_ATTR_PRIO		= 0x00000001,
+	SBI_SSE_ATTR_CONFIG		= 0x00000002,
+	SBI_SSE_ATTR_PREFERRED_HART	= 0x00000003,
+	SBI_SSE_ATTR_ENTRY_PC		= 0x00000004,
+	SBI_SSE_ATTR_ENTRY_ARG		= 0x00000005,
+	SBI_SSE_ATTR_INTERRUPTED_SEPC	= 0x00000006,
+	SBI_SSE_ATTR_INTERRUPTED_FLAGS	= 0x00000007,
+	SBI_SSE_ATTR_INTERRUPTED_A6	= 0x00000008,
+	SBI_SSE_ATTR_INTERRUPTED_A7	= 0x00000009,
+
+	SBI_SSE_ATTR_MAX		= 0x0000000A
+};
+
+#define SBI_SSE_ATTR_STATUS_STATE_OFFSET	0
+#define SBI_SSE_ATTR_STATUS_STATE_MASK		0x3
+#define SBI_SSE_ATTR_STATUS_PENDING_OFFSET	2
+#define SBI_SSE_ATTR_STATUS_INJECT_OFFSET	3
+
+#define SBI_SSE_ATTR_CONFIG_ONESHOT	(1 << 0)
+
+#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPP	(1 << 0)
+#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPIE	(1 << 1)
+#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV	(1 << 2)
+#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP	(1 << 3)
+
+#define SBI_SSE_EVENT_LOCAL_RAS		0x00000000
+#define SBI_SSE_EVENT_GLOBAL_RAS	0x00008000
+#define SBI_SSE_EVENT_LOCAL_PMU		0x00010000
+#define SBI_SSE_EVENT_LOCAL_SOFTWARE	0xffff0000
+#define SBI_SSE_EVENT_GLOBAL_SOFTWARE	0xffff8000
+
+#define SBI_SSE_EVENT_PLATFORM		(1 << 14)
+#define SBI_SSE_EVENT_GLOBAL		(1 << 15)
+
 /* SBI spec version fields */
 #define SBI_SPEC_VERSION_DEFAULT	0x1
 #define SBI_SPEC_VERSION_MAJOR_SHIFT	24
@@ -418,6 +476,8 @@ enum sbi_ext_nacl_feature {
 #define SBI_ERR_ALREADY_STARTED -7
 #define SBI_ERR_ALREADY_STOPPED -8
 #define SBI_ERR_NO_SHMEM	-9
+#define SBI_ERR_INVALID_STATE	-10
+#define SBI_ERR_BAD_RANGE	-11
 
 extern unsigned long sbi_spec_version;
 struct sbiret {
@@ -504,6 +564,8 @@ static inline int sbi_err_map_linux_errno(int err)
 	case SBI_ERR_DENIED:
 		return -EPERM;
 	case SBI_ERR_INVALID_PARAM:
+	case SBI_ERR_BAD_RANGE:
+	case SBI_ERR_INVALID_STATE:
 		return -EINVAL;
 	case SBI_ERR_INVALID_ADDRESS:
 		return -EFAULT;
-- 
2.45.2



From cleger at rivosinc.com  Fri Dec  6 08:30:58 2024
From: cleger at rivosinc.com (=?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?=)
Date: Fri,  6 Dec 2024 17:30:58 +0100
Subject: [PATCH v3 2/4] riscv: add support for SBI Supervisor Software Events extension
In-Reply-To: <20241206163102.843505-1-cleger@rivosinc.com>
References: <20241206163102.843505-1-cleger@rivosinc.com>
Message-ID: <20241206163102.843505-3-cleger@rivosinc.com>

The SBI SSE extension allows the supervisor software to be notified by
the SBI of specific events that are not maskable. The context switch is
handled partially by the firmware which will save registers a6 and a7.
When entering kernel we can rely on these 2 registers to setup the stack
and save all the registers.

Since SSE events can be delivered at any time to the kernel (including
during exception handling, we need a way to locate the current_task for
context tracking. On RISC-V, it is sotred in scratch when in user space
or tp when in kernel space (in which case SSCRATCH is zero). But at a
at the beginning of exception handling, SSCRATCH is used to swap tp and
check the origin of the exception. If interrupted at that point, then,
there is no way to reliably know were is located the current
task_struct. Even checking the interruption location won't work as SSE
event can be nested on top of each other so the original interruption
site might be lost at some point. In order to retrieve it reliably,
store the current task in an additionnal __sse_entry_task per_cpu array.
This array is then used to retrieve the current task based on the
hart ID that is passed to the SSE event handler in a6.

That being said, the way the current task struct is stored should
probably be reworked to find a better reliable alternative.

Since each events (and each CPU for local events) have their own
context and can preempt each other, allocate a stack (and a shadow stack
if needed for each of them (and for each cpu for local events).

When completing the event, if we were coming from kernel with interrupts
disabled, simply return there. If coming from userspace or kernel with
interrupts enabled, simulate an interrupt exception by setting IE_SIE in
CSR_IP to allow delivery of signals to user task. For instance this can
happen, when a RAS event has been generated by a user application and a
SIGBUS has been sent to a task.

Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
---
 arch/riscv/include/asm/asm.h         |  14 ++-
 arch/riscv/include/asm/scs.h         |   7 ++
 arch/riscv/include/asm/sse.h         |  38 ++++++
 arch/riscv/include/asm/switch_to.h   |  14 +++
 arch/riscv/include/asm/thread_info.h |   1 +
 arch/riscv/kernel/Makefile           |   1 +
 arch/riscv/kernel/asm-offsets.c      |  12 ++
 arch/riscv/kernel/sse.c              | 134 +++++++++++++++++++++
 arch/riscv/kernel/sse_entry.S        | 171 +++++++++++++++++++++++++++
 9 files changed, 389 insertions(+), 3 deletions(-)
 create mode 100644 arch/riscv/include/asm/sse.h
 create mode 100644 arch/riscv/kernel/sse.c
 create mode 100644 arch/riscv/kernel/sse_entry.S

diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index 776354895b81..de8427c58f02 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -89,16 +89,24 @@
 #define PER_CPU_OFFSET_SHIFT 3
 #endif
 
-.macro asm_per_cpu dst sym tmp
-	REG_L \tmp, TASK_TI_CPU_NUM(tp)
-	slli  \tmp, \tmp, PER_CPU_OFFSET_SHIFT
+.macro asm_per_cpu_with_cpu dst sym tmp cpu
+	slli  \tmp, \cpu, PER_CPU_OFFSET_SHIFT
 	la    \dst, __per_cpu_offset
 	add   \dst, \dst, \tmp
 	REG_L \tmp, 0(\dst)
 	la    \dst, \sym
 	add   \dst, \dst, \tmp
 .endm
+
+.macro asm_per_cpu dst sym tmp
+	REG_L \tmp, TASK_TI_CPU_NUM(tp)
+	asm_per_cpu_with_cpu \dst \sym \tmp \tmp
+.endm
 #else /* CONFIG_SMP */
+.macro asm_per_cpu_with_cpu dst sym tmp cpu
+	la    \dst, \sym
+.endm
+
 .macro asm_per_cpu dst sym tmp
 	la    \dst, \sym
 .endm
diff --git a/arch/riscv/include/asm/scs.h b/arch/riscv/include/asm/scs.h
index 0e45db78b24b..62344daad73d 100644
--- a/arch/riscv/include/asm/scs.h
+++ b/arch/riscv/include/asm/scs.h
@@ -18,6 +18,11 @@
 	load_per_cpu gp, irq_shadow_call_stack_ptr, \tmp
 .endm
 
+/* Load the per-CPU IRQ shadow call stack to gp. */
+.macro scs_load_sse_stack reg_evt
+	REG_L gp, SSE_REG_EVT_SHADOW_STACK(\reg_evt)
+.endm
+
 /* Load task_scs_sp(current) to gp. */
 .macro scs_load_current
 	REG_L	gp, TASK_TI_SCS_SP(tp)
@@ -41,6 +46,8 @@
 .endm
 .macro scs_load_irq_stack tmp
 .endm
+.macro scs_load_sse_stack reg_evt
+.endm
 .macro scs_load_current
 .endm
 .macro scs_load_current_if_task_changed prev
diff --git a/arch/riscv/include/asm/sse.h b/arch/riscv/include/asm/sse.h
new file mode 100644
index 000000000000..431a19d4cd9c
--- /dev/null
+++ b/arch/riscv/include/asm/sse.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2024 Rivos Inc.
+ */
+#ifndef __ASM_SSE_H
+#define __ASM_SSE_H
+
+#ifdef CONFIG_RISCV_SSE
+
+struct sse_event_interrupted_state {
+	unsigned long a6;
+	unsigned long a7;
+};
+
+struct sse_event_arch_data {
+	void *stack;
+	void *shadow_stack;
+	unsigned long tmp;
+	struct sse_event_interrupted_state interrupted;
+	unsigned long interrupted_state_phys;
+	u32 evt_id;
+};
+
+struct sse_registered_event;
+int arch_sse_init_event(struct sse_event_arch_data *arch_evt, u32 evt_id,
+			int cpu);
+void arch_sse_free_event(struct sse_event_arch_data *arch_evt);
+int arch_sse_register_event(struct sse_event_arch_data *arch_evt);
+
+void sse_handle_event(struct sse_event_arch_data *arch_evt,
+		      struct pt_regs *regs);
+asmlinkage void handle_sse(void);
+asmlinkage void do_sse(struct sse_event_arch_data *arch_evt,
+				struct pt_regs *reg);
+
+#endif
+
+#endif
diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
index 94e33216b2d9..e166fabe04ab 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -88,6 +88,19 @@ static inline void __switch_to_envcfg(struct task_struct *next)
 			:: "r" (next->thread.envcfg) : "memory");
 }
 
+#ifdef CONFIG_RISCV_SSE
+DECLARE_PER_CPU(struct task_struct *, __sse_entry_task);
+
+static inline void __switch_sse_entry_task(struct task_struct *next)
+{
+	__this_cpu_write(__sse_entry_task, next);
+}
+#else
+static inline void __switch_sse_entry_task(struct task_struct *next)
+{
+}
+#endif
+
 extern struct task_struct *__switch_to(struct task_struct *,
 				       struct task_struct *);
 
@@ -122,6 +135,7 @@ do {							\
 	if (switch_to_should_flush_icache(__next))	\
 		local_flush_icache_all();		\
 	__switch_to_envcfg(__next);			\
+	__switch_sse_entry_task(__next);			\
 	((last) = __switch_to(__prev, __next));		\
 } while (0)
 
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index f5916a70879a..28e9805e61fc 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -36,6 +36,7 @@
 #define OVERFLOW_STACK_SIZE     SZ_4K
 
 #define IRQ_STACK_SIZE		THREAD_SIZE
+#define SSE_STACK_SIZE		THREAD_SIZE
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 063d1faf5a53..1e8fb83b1162 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_DYNAMIC_FTRACE)	+= mcount-dyn.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_callchain.o
 obj-$(CONFIG_HAVE_PERF_REGS)	+= perf_regs.o
 obj-$(CONFIG_RISCV_SBI)		+= sbi.o sbi_ecall.o
+obj-$(CONFIG_RISCV_SSE)		+= sse.o sse_entry.o
 ifeq ($(CONFIG_RISCV_SBI), y)
 obj-$(CONFIG_SMP)		+= sbi-ipi.o
 obj-$(CONFIG_SMP) += cpu_ops_sbi.o
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index e89455a6a0e5..60590a3d9519 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -14,6 +14,8 @@
 #include <asm/ptrace.h>
 #include <asm/cpu_ops_sbi.h>
 #include <asm/stacktrace.h>
+#include <asm/sbi.h>
+#include <asm/sse.h>
 #include <asm/suspend.h>
 
 void asm_offsets(void);
@@ -511,4 +513,14 @@ void asm_offsets(void)
 	DEFINE(FREGS_A6,	    offsetof(struct __arch_ftrace_regs, a6));
 	DEFINE(FREGS_A7,	    offsetof(struct __arch_ftrace_regs, a7));
 #endif
+
+#ifdef CONFIG_RISCV_SSE
+	OFFSET(SSE_REG_EVT_STACK, sse_event_arch_data, stack);
+	OFFSET(SSE_REG_EVT_SHADOW_STACK, sse_event_arch_data, shadow_stack);
+	OFFSET(SSE_REG_EVT_TMP, sse_event_arch_data, tmp);
+
+	DEFINE(SBI_EXT_SSE, SBI_EXT_SSE);
+	DEFINE(SBI_SSE_EVENT_COMPLETE, SBI_SSE_EVENT_COMPLETE);
+	DEFINE(NR_CPUS, NR_CPUS);
+#endif
 }
diff --git a/arch/riscv/kernel/sse.c b/arch/riscv/kernel/sse.c
new file mode 100644
index 000000000000..b48ae69dad8d
--- /dev/null
+++ b/arch/riscv/kernel/sse.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 Rivos Inc.
+ */
+#include <linux/nmi.h>
+#include <linux/scs.h>
+#include <linux/bitfield.h>
+#include <linux/riscv_sse.h>
+#include <linux/percpu-defs.h>
+
+#include <asm/asm-prototypes.h>
+#include <asm/switch_to.h>
+#include <asm/irq_stack.h>
+#include <asm/sbi.h>
+#include <asm/sse.h>
+
+DEFINE_PER_CPU(struct task_struct *, __sse_entry_task);
+
+void __weak sse_handle_event(struct sse_event_arch_data *arch_evt, struct pt_regs *regs)
+{
+}
+
+void do_sse(struct sse_event_arch_data *arch_evt, struct pt_regs *regs)
+{
+	nmi_enter();
+
+	/* Retrieve missing GPRs from SBI */
+	sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_ATTR_READ, arch_evt->evt_id,
+		  SBI_SSE_ATTR_INTERRUPTED_A6,
+		  (SBI_SSE_ATTR_INTERRUPTED_A7 - SBI_SSE_ATTR_INTERRUPTED_A6) + 1,
+		  arch_evt->interrupted_state_phys, 0, 0);
+
+	memcpy(&regs->a6, &arch_evt->interrupted, sizeof(arch_evt->interrupted));
+
+	sse_handle_event(arch_evt, regs);
+
+	/*
+	 * The SSE delivery path does not uses the "standard" exception path and
+	 * thus does not process any pending signal/softirqs. Some drivers might
+	 * enqueue pending work that needs to be handled as soon as possible.
+	 * For that purpose, set the software interrupt pending bit which will
+	 * be serviced once interrupts are reenabled
+	 */
+	csr_set(CSR_IP, IE_SIE);
+
+	nmi_exit();
+}
+
+#ifdef CONFIG_VMAP_STACK
+static unsigned long *sse_stack_alloc(unsigned int cpu, unsigned int size)
+{
+	return arch_alloc_vmap_stack(size, cpu_to_node(cpu));
+}
+
+static void sse_stack_free(unsigned long *stack)
+{
+	vfree(stack);
+}
+#else /* CONFIG_VMAP_STACK */
+
+static unsigned long *sse_stack_alloc(unsigned int cpu, unsigned int size)
+{
+	return kmalloc(size, GFP_KERNEL);
+}
+
+static void sse_stack_free(unsigned long *stack)
+{
+	kfree(stack);
+}
+
+#endif /* CONFIG_VMAP_STACK */
+
+static int sse_init_scs(int cpu, struct sse_event_arch_data *arch_evt)
+{
+	void *stack;
+
+	if (!scs_is_enabled())
+		return 0;
+
+	stack = scs_alloc(cpu_to_node(cpu));
+	if (!stack)
+		return 1;
+
+	arch_evt->shadow_stack = stack;
+
+	return 0;
+}
+
+int arch_sse_init_event(struct sse_event_arch_data *arch_evt, u32 evt_id, int cpu)
+{
+	void *stack;
+
+	arch_evt->evt_id = evt_id;
+	stack = sse_stack_alloc(cpu, SSE_STACK_SIZE);
+	if (!stack)
+		return -ENOMEM;
+
+	arch_evt->stack = stack + SSE_STACK_SIZE;
+
+	if (sse_init_scs(cpu, arch_evt))
+		goto free_stack;
+
+	if (is_kernel_percpu_address((unsigned long)&arch_evt->interrupted)) {
+		arch_evt->interrupted_state_phys =
+				per_cpu_ptr_to_phys(&arch_evt->interrupted);
+	} else {
+		arch_evt->interrupted_state_phys =
+				virt_to_phys(&arch_evt->interrupted);
+	}
+
+	return 0;
+
+free_stack:
+	sse_stack_free(arch_evt->stack - SSE_STACK_SIZE);
+
+	return -ENOMEM;
+}
+
+void arch_sse_free_event(struct sse_event_arch_data *arch_evt)
+{
+	scs_free(arch_evt->shadow_stack);
+	sse_stack_free(arch_evt->stack - SSE_STACK_SIZE);
+}
+
+int arch_sse_register_event(struct sse_event_arch_data *arch_evt)
+{
+	struct sbiret sret;
+
+	sret = sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_REGISTER, arch_evt->evt_id,
+			 (unsigned long) handle_sse, (unsigned long) arch_evt,
+			 0, 0, 0);
+
+	return sbi_err_map_linux_errno(sret.error);
+}
diff --git a/arch/riscv/kernel/sse_entry.S b/arch/riscv/kernel/sse_entry.S
new file mode 100644
index 000000000000..0b2f890edd89
--- /dev/null
+++ b/arch/riscv/kernel/sse_entry.S
@@ -0,0 +1,171 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2024 Rivos Inc.
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+
+#include <asm/asm.h>
+#include <asm/csr.h>
+#include <asm/scs.h>
+
+/* When entering handle_sse, the following registers are set:
+ * a6: contains the hartid
+ * a6: contains struct sse_registered_event pointer
+ */
+SYM_CODE_START(handle_sse)
+	/* Save stack temporarily */
+	REG_S sp, SSE_REG_EVT_TMP(a7)
+	/* Set entry stack */
+	REG_L sp, SSE_REG_EVT_STACK(a7)
+
+	addi sp, sp, -(PT_SIZE_ON_STACK)
+	REG_S ra, PT_RA(sp)
+	REG_S s0, PT_S0(sp)
+	REG_S s1, PT_S1(sp)
+	REG_S s2, PT_S2(sp)
+	REG_S s3, PT_S3(sp)
+	REG_S s4, PT_S4(sp)
+	REG_S s5, PT_S5(sp)
+	REG_S s6, PT_S6(sp)
+	REG_S s7, PT_S7(sp)
+	REG_S s8, PT_S8(sp)
+	REG_S s9, PT_S9(sp)
+	REG_S s10, PT_S10(sp)
+	REG_S s11, PT_S11(sp)
+	REG_S tp, PT_TP(sp)
+	REG_S t0, PT_T0(sp)
+	REG_S t1, PT_T1(sp)
+	REG_S t2, PT_T2(sp)
+	REG_S t3, PT_T3(sp)
+	REG_S t4, PT_T4(sp)
+	REG_S t5, PT_T5(sp)
+	REG_S t6, PT_T6(sp)
+	REG_S gp, PT_GP(sp)
+	REG_S a0, PT_A0(sp)
+	REG_S a1, PT_A1(sp)
+	REG_S a2, PT_A2(sp)
+	REG_S a3, PT_A3(sp)
+	REG_S a4, PT_A4(sp)
+	REG_S a5, PT_A5(sp)
+
+	/* Retrieve entry sp */
+	REG_L a4, SSE_REG_EVT_TMP(a7)
+	/* Save CSRs */
+	csrr a0, CSR_EPC
+	csrr a1, CSR_SSTATUS
+	csrr a2, CSR_STVAL
+	csrr a3, CSR_SCAUSE
+
+	REG_S a0, PT_EPC(sp)
+	REG_S a1, PT_STATUS(sp)
+	REG_S a2, PT_BADADDR(sp)
+	REG_S a3, PT_CAUSE(sp)
+	REG_S a4, PT_SP(sp)
+
+	/* Disable user memory access and floating/vector computing */
+	li t0, SR_SUM | SR_FS_VS
+	csrc CSR_STATUS, t0
+
+	load_global_pointer
+	scs_load_sse_stack a7
+
+	/* Restore current task struct from __sse_entry_task */
+	li t1, NR_CPUS
+	move t3, zero
+
+#ifdef CONFIG_SMP
+	/* Find the CPU id associated to the hart id */
+	la t0, __cpuid_to_hartid_map
+.Lhart_id_loop:
+	REG_L t2, 0(t0)
+	beq t2, a6, .Lcpu_id_found
+
+	/* Increment pointer and CPU number */
+	addi t3, t3, 1
+	addi t0, t0, RISCV_SZPTR
+	bltu t3, t1, .Lhart_id_loop
+
+	/*
+	 * This should never happen since we expect the hart_id to match one
+	 * of our CPU, but better be safe than sorry
+	 */
+	la tp, init_task
+	la a0, sse_hart_id_panic_string
+	la t0, panic
+	jalr t0
+
+.Lcpu_id_found:
+#endif
+	asm_per_cpu_with_cpu t2 __sse_entry_task t1 t3
+	REG_L tp, 0(t2)
+
+	move a1, sp /* pt_regs on stack */
+	/* Kernel was interrupted, create stack frame */
+	beqz s1, .Lcall_do_sse
+
+.Lcall_do_sse:
+	/*
+	 * Save sscratch for restoration since we might have interrupted the
+	 * kernel in early exception path and thus, we don't know the content of
+	 * sscratch.
+	 */
+	csrr s4, CSR_SSCRATCH
+	/* In-kernel scratch is 0 */
+	csrw CSR_SCRATCH, x0
+
+	move a0, a7
+
+	call do_sse
+
+	csrw CSR_SSCRATCH, s4
+
+	REG_L a0, PT_EPC(sp)
+	REG_L a1, PT_STATUS(sp)
+	REG_L a2, PT_BADADDR(sp)
+	REG_L a3, PT_CAUSE(sp)
+	csrw CSR_EPC, a0
+	csrw CSR_SSTATUS, a1
+	csrw CSR_STVAL, a2
+	csrw CSR_SCAUSE, a3
+
+	REG_L ra, PT_RA(sp)
+	REG_L s0, PT_S0(sp)
+	REG_L s1, PT_S1(sp)
+	REG_L s2, PT_S2(sp)
+	REG_L s3, PT_S3(sp)
+	REG_L s4, PT_S4(sp)
+	REG_L s5, PT_S5(sp)
+	REG_L s6, PT_S6(sp)
+	REG_L s7, PT_S7(sp)
+	REG_L s8, PT_S8(sp)
+	REG_L s9, PT_S9(sp)
+	REG_L s10, PT_S10(sp)
+	REG_L s11, PT_S11(sp)
+	REG_L tp, PT_TP(sp)
+	REG_L t0, PT_T0(sp)
+	REG_L t1, PT_T1(sp)
+	REG_L t2, PT_T2(sp)
+	REG_L t3, PT_T3(sp)
+	REG_L t4, PT_T4(sp)
+	REG_L t5, PT_T5(sp)
+	REG_L t6, PT_T6(sp)
+	REG_L gp, PT_GP(sp)
+	REG_L a0, PT_A0(sp)
+	REG_L a1, PT_A1(sp)
+	REG_L a2, PT_A2(sp)
+	REG_L a3, PT_A3(sp)
+	REG_L a4, PT_A4(sp)
+	REG_L a5, PT_A5(sp)
+
+	REG_L sp, PT_SP(sp)
+
+	li a7, SBI_EXT_SSE
+	li a6, SBI_SSE_EVENT_COMPLETE
+	ecall
+
+SYM_CODE_END(handle_sse)
+
+sse_hart_id_panic_string:
+    .ascii "Unable to match hart_id with cpu\0"
-- 
2.45.2



From cleger at rivosinc.com  Fri Dec  6 08:30:59 2024
From: cleger at rivosinc.com (=?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?=)
Date: Fri,  6 Dec 2024 17:30:59 +0100
Subject: [PATCH v3 3/4] drivers: firmware: add riscv SSE support
In-Reply-To: <20241206163102.843505-1-cleger@rivosinc.com>
References: <20241206163102.843505-1-cleger@rivosinc.com>
Message-ID: <20241206163102.843505-4-cleger@rivosinc.com>

Add driver level interface to use RISC-V SSE arch support. This interface
allows registering SSE handlers, and receive them. This will be used by
PMU and GHES driver.

Signed-off-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
Co-developed-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
---
 MAINTAINERS                        |  14 +
 drivers/firmware/Kconfig           |   1 +
 drivers/firmware/Makefile          |   1 +
 drivers/firmware/riscv/Kconfig     |  15 +
 drivers/firmware/riscv/Makefile    |   3 +
 drivers/firmware/riscv/riscv_sse.c | 691 +++++++++++++++++++++++++++++
 include/linux/riscv_sse.h          |  56 +++
 7 files changed, 781 insertions(+)
 create mode 100644 drivers/firmware/riscv/Kconfig
 create mode 100644 drivers/firmware/riscv/Makefile
 create mode 100644 drivers/firmware/riscv/riscv_sse.c
 create mode 100644 include/linux/riscv_sse.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 686109008d8e..a3ddde7fe9fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20125,6 +20125,13 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
 F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
 F:	drivers/iommu/riscv/
 
+RISC-V FIRMWARE DRIVERS
+M:	Conor Dooley <conor at kernel.org>
+L:	linux-riscv at lists.infradead.org
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git
+F:	drivers/firmware/riscv/*
+
 RISC-V MICROCHIP FPGA SUPPORT
 M:	Conor Dooley <conor.dooley at microchip.com>
 M:	Daire McNamara <daire.mcnamara at microchip.com>
@@ -20177,6 +20184,13 @@ F:	drivers/perf/riscv_pmu.c
 F:	drivers/perf/riscv_pmu_legacy.c
 F:	drivers/perf/riscv_pmu_sbi.c
 
+RISC-V SSE DRIVER
+M:	Cl?ment L?ger <cleger at rivosinc.com>
+L:	linux-riscv at lists.infradead.org
+S:	Maintained
+F:	drivers/firmware/riscv/riscv_sse.c
+F:	include/linux/riscv_sse.h
+
 RISC-V THEAD SoC SUPPORT
 M:	Drew Fustini <drew at pdp7.com>
 M:	Guo Ren <guoren at kernel.org>
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 71d8b26c4103..9e996a1fd511 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -267,6 +267,7 @@ source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/microchip/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/qcom/Kconfig"
+source "drivers/firmware/riscv/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
 source "drivers/firmware/tegra/Kconfig"
 source "drivers/firmware/xilinx/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 7a8d486e718f..c0f5009949a8 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -33,6 +33,7 @@ obj-y				+= efi/
 obj-y				+= imx/
 obj-y				+= psci/
 obj-y				+= qcom/
+obj-y				+= riscv/
 obj-y				+= smccc/
 obj-y				+= tegra/
 obj-y				+= xilinx/
diff --git a/drivers/firmware/riscv/Kconfig b/drivers/firmware/riscv/Kconfig
new file mode 100644
index 000000000000..8056ed3262d9
--- /dev/null
+++ b/drivers/firmware/riscv/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "Risc-V Specific firmware drivers"
+depends on RISCV
+
+config RISCV_SSE
+	bool "Enable SBI Supervisor Software Events support"
+	depends on RISCV_SBI
+	default y
+	help
+	  The Supervisor Software Events support allow the SBI to deliver
+	  NMI-like notifications to the supervisor mode software. When enable,
+	  this option provides support to register callbacks on specific SSE
+	  events.
+
+endmenu
diff --git a/drivers/firmware/riscv/Makefile b/drivers/firmware/riscv/Makefile
new file mode 100644
index 000000000000..4ccfcbbc28ea
--- /dev/null
+++ b/drivers/firmware/riscv/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_RISCV_SSE)		+= riscv_sse.o
diff --git a/drivers/firmware/riscv/riscv_sse.c b/drivers/firmware/riscv/riscv_sse.c
new file mode 100644
index 000000000000..c165e32cc9a5
--- /dev/null
+++ b/drivers/firmware/riscv/riscv_sse.c
@@ -0,0 +1,691 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Rivos Inc.
+ */
+
+#define pr_fmt(fmt) "sse: " fmt
+
+#include <linux/cpu.h>
+#include <linux/cpuhotplug.h>
+#include <linux/cpu_pm.h>
+#include <linux/hardirq.h>
+#include <linux/list.h>
+#include <linux/percpu-defs.h>
+#include <linux/reboot.h>
+#include <linux/riscv_sse.h>
+#include <linux/slab.h>
+
+#include <asm/sbi.h>
+#include <asm/sse.h>
+
+struct sse_event {
+	struct list_head list;
+	u32 evt;
+	u32 priority;
+	sse_event_handler *handler;
+	void *handler_arg;
+	bool is_enabled;
+	/* Only valid for global events */
+	unsigned int cpu;
+
+	union {
+		struct sse_registered_event *global;
+		struct sse_registered_event __percpu *local;
+	};
+};
+
+static int sse_hp_state;
+static bool sse_available;
+static DEFINE_SPINLOCK(events_list_lock);
+static LIST_HEAD(events);
+static DEFINE_MUTEX(sse_mutex);
+
+struct sse_registered_event {
+	struct sse_event_arch_data arch;
+	struct sse_event *evt;
+	unsigned long attr_buf;
+};
+
+void sse_handle_event(struct sse_event_arch_data *arch_event,
+		      struct pt_regs *regs)
+{
+	int ret;
+	struct sse_registered_event *reg_evt =
+		container_of(arch_event, struct sse_registered_event, arch);
+	struct sse_event *evt = reg_evt->evt;
+
+	ret = evt->handler(evt->evt, evt->handler_arg, regs);
+	if (ret)
+		pr_warn("event %x handler failed with error %d\n", evt->evt,
+			ret);
+}
+
+static bool sse_event_is_global(u32 evt)
+{
+	return !!(evt & SBI_SSE_EVENT_GLOBAL);
+}
+
+static
+struct sse_event *sse_event_get(u32 evt)
+{
+	struct sse_event *sse_evt = NULL, *tmp;
+
+	scoped_guard(spinlock, &events_list_lock) {
+		list_for_each_entry(tmp, &events, list) {
+			if (tmp->evt == evt) {
+				return sse_evt;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+static phys_addr_t sse_event_get_phys(struct sse_registered_event *reg_evt,
+				      void *addr)
+{
+	phys_addr_t phys;
+
+	if (sse_event_is_global(reg_evt->evt->evt))
+		phys = virt_to_phys(addr);
+	else
+		phys = per_cpu_ptr_to_phys(addr);
+
+	return phys;
+}
+
+static int sse_sbi_event_func(struct sse_event *event, unsigned long func)
+{
+	struct sbiret ret;
+	u32 evt = event->evt;
+
+	ret = sbi_ecall(SBI_EXT_SSE, func, evt, 0, 0, 0, 0, 0);
+	if (ret.error)
+		pr_debug("Failed to execute func %lx, event %x, error %ld\n",
+			 func, evt, ret.error);
+
+	return sbi_err_map_linux_errno(ret.error);
+}
+
+static int sse_sbi_disable_event(struct sse_event *event)
+{
+	return sse_sbi_event_func(event, SBI_SSE_EVENT_DISABLE);
+}
+
+static int sse_sbi_enable_event(struct sse_event *event)
+{
+	return sse_sbi_event_func(event, SBI_SSE_EVENT_ENABLE);
+}
+
+static int sse_event_attr_get_no_lock(struct sse_registered_event *reg_evt,
+				      unsigned long attr_id, unsigned long *val)
+{
+	struct sbiret sret;
+	u32 evt = reg_evt->evt->evt;
+	unsigned long phys;
+
+	phys = sse_event_get_phys(reg_evt, &reg_evt->attr_buf);
+
+	sret = sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_ATTR_READ, evt,
+				     attr_id, 1, phys, 0, 0);
+	if (sret.error) {
+		pr_debug("Failed to get event %x attr %lx, error %ld\n", evt,
+			 attr_id, sret.error);
+		return sbi_err_map_linux_errno(sret.error);
+	}
+
+	*val = reg_evt->attr_buf;
+
+	return 0;
+}
+
+static int sse_event_attr_set_nolock(struct sse_registered_event *reg_evt,
+				     unsigned long attr_id, unsigned long val)
+{
+	struct sbiret sret;
+	u32 evt = reg_evt->evt->evt;
+	unsigned long phys;
+
+	reg_evt->attr_buf = val;
+	phys = sse_event_get_phys(reg_evt, &reg_evt->attr_buf);
+
+	sret = sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_ATTR_WRITE, evt,
+				     attr_id, 1, phys, 0, 0);
+	if (sret.error && sret.error != SBI_ERR_INVALID_STATE) {
+		pr_debug("Failed to set event %x attr %lx, error %ld\n", evt,
+			 attr_id, sret.error);
+		return sbi_err_map_linux_errno(sret.error);
+	}
+
+	return 0;
+}
+
+static int sse_event_set_target_cpu_nolock(struct sse_event *event,
+					   unsigned int cpu)
+{
+	unsigned int hart_id = cpuid_to_hartid_map(cpu);
+	struct sse_registered_event *reg_evt = event->global;
+	u32 evt = event->evt;
+	bool was_enabled;
+	int ret;
+
+	if (!sse_event_is_global(evt))
+		return -EINVAL;
+
+	was_enabled = event->is_enabled;
+	if (was_enabled)
+		sse_sbi_disable_event(event);
+	do {
+		ret = sse_event_attr_set_nolock(reg_evt,
+						SBI_SSE_ATTR_PREFERRED_HART,
+						hart_id);
+	} while (ret == -EINVAL);
+
+	if (ret == 0)
+		event->cpu = cpu;
+
+	if (was_enabled)
+		sse_sbi_enable_event(event);
+
+	return 0;
+}
+
+int sse_event_set_target_cpu(struct sse_event *event, unsigned int cpu)
+{
+	int ret;
+
+	scoped_guard(mutex, &sse_mutex) {
+		cpus_read_lock();
+
+		if (!cpu_online(cpu))
+			return -EINVAL;
+
+		ret = sse_event_set_target_cpu_nolock(event, cpu);
+
+		cpus_read_unlock();
+	}
+
+	return ret;
+}
+
+static int sse_event_init_registered(unsigned int cpu,
+				     struct sse_registered_event *reg_evt,
+				     struct sse_event *event)
+{
+	reg_evt->evt = event;
+	arch_sse_init_event(&reg_evt->arch, event->evt, cpu);
+
+	return 0;
+}
+
+static void sse_event_free_registered(struct sse_registered_event *reg_evt)
+{
+	arch_sse_free_event(&reg_evt->arch);
+}
+
+static int sse_event_alloc_global(struct sse_event *event)
+{
+	int err;
+	struct sse_registered_event *reg_evt;
+
+	reg_evt = kzalloc(sizeof(*reg_evt), GFP_KERNEL);
+	if (!reg_evt)
+		return -ENOMEM;
+
+	event->global = reg_evt;
+	err = sse_event_init_registered(smp_processor_id(), reg_evt,
+					event);
+	if (err)
+		kfree(reg_evt);
+
+	return err;
+}
+
+static int sse_event_alloc_local(struct sse_event *event)
+{
+	int err;
+	unsigned int cpu, err_cpu;
+	struct sse_registered_event *reg_evt;
+	struct sse_registered_event __percpu *reg_evts;
+
+	reg_evts = alloc_percpu(struct sse_registered_event);
+	if (!reg_evts)
+		return -ENOMEM;
+
+	event->local = reg_evts;
+
+	for_each_possible_cpu(cpu) {
+		reg_evt = per_cpu_ptr(reg_evts, cpu);
+		err = sse_event_init_registered(cpu, reg_evt, event);
+		if (err) {
+			err_cpu = cpu;
+			goto err_free_per_cpu;
+		}
+	}
+
+	return 0;
+
+err_free_per_cpu:
+	for_each_possible_cpu(cpu) {
+		if (cpu == err_cpu)
+			break;
+		reg_evt = per_cpu_ptr(reg_evts, cpu);
+		sse_event_free_registered(reg_evt);
+	}
+
+	free_percpu(reg_evts);
+
+	return err;
+}
+
+static struct sse_event *sse_event_alloc(u32 evt,
+					 u32 priority,
+					 sse_event_handler *handler, void *arg)
+{
+	int err;
+	struct sse_event *event;
+
+	event = kzalloc(sizeof(*event), GFP_KERNEL);
+	if (!event)
+		return ERR_PTR(-ENOMEM);
+
+	event->evt = evt;
+	event->priority = priority;
+	event->handler_arg = arg;
+	event->handler = handler;
+
+	if (sse_event_is_global(evt)) {
+		err = sse_event_alloc_global(event);
+		if (err)
+			goto err_alloc_reg_evt;
+	} else {
+		err = sse_event_alloc_local(event);
+		if (err)
+			goto err_alloc_reg_evt;
+	}
+
+	return event;
+
+err_alloc_reg_evt:
+	kfree(event);
+
+	return ERR_PTR(err);
+}
+
+static int sse_sbi_register_event(struct sse_event *event,
+				  struct sse_registered_event *reg_evt)
+{
+	int ret;
+
+	ret = sse_event_attr_set_nolock(reg_evt, SBI_SSE_ATTR_PRIO,
+					event->priority);
+	if (ret)
+		return ret;
+
+	return arch_sse_register_event(&reg_evt->arch);
+}
+
+static int sse_event_register_local(struct sse_event *event)
+{
+	int ret;
+	struct sse_registered_event *reg_evt = per_cpu_ptr(event->local,
+							   smp_processor_id());
+
+	ret = sse_sbi_register_event(event, reg_evt);
+	if (ret)
+		pr_debug("Failed to register event %x: err %d\n", event->evt,
+			 ret);
+
+	return ret;
+}
+
+
+static int sse_sbi_unregister_event(struct sse_event *event)
+{
+	return sse_sbi_event_func(event, SBI_SSE_EVENT_UNREGISTER);
+}
+
+struct sse_per_cpu_evt {
+	struct sse_event *event;
+	unsigned long func;
+	atomic_t error;
+};
+
+static void sse_event_per_cpu_func(void *info)
+{
+	int ret;
+	struct sse_per_cpu_evt *cpu_evt = info;
+
+	if (cpu_evt->func == SBI_SSE_EVENT_REGISTER)
+		ret = sse_event_register_local(cpu_evt->event);
+	else
+		ret = sse_sbi_event_func(cpu_evt->event, cpu_evt->func);
+
+	if (ret)
+		atomic_set(&cpu_evt->error, ret);
+}
+
+static void sse_event_free(struct sse_event *event)
+{
+	unsigned int cpu;
+	struct sse_registered_event *reg_evt;
+
+	if (sse_event_is_global(event->evt)) {
+		sse_event_free_registered(event->global);
+		kfree(event->global);
+	} else {
+		for_each_possible_cpu(cpu) {
+			reg_evt = per_cpu_ptr(event->local, cpu);
+			sse_event_free_registered(reg_evt);
+		}
+		free_percpu(event->local);
+	}
+
+	kfree(event);
+}
+
+int sse_event_enable(struct sse_event *event)
+{
+	int ret = 0;
+	struct sse_per_cpu_evt cpu_evt;
+
+	scoped_guard(mutex, &sse_mutex) {
+		cpus_read_lock();
+		if (sse_event_is_global(event->evt)) {
+			ret = sse_sbi_enable_event(event);
+		} else {
+			cpu_evt.event = event;
+			atomic_set(&cpu_evt.error, 0);
+			cpu_evt.func = SBI_SSE_EVENT_ENABLE;
+			on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
+			ret = atomic_read(&cpu_evt.error);
+			if (ret) {
+				cpu_evt.func = SBI_SSE_EVENT_DISABLE;
+				on_each_cpu(sse_event_per_cpu_func, &cpu_evt,
+					    1);
+			}
+		}
+		cpus_read_unlock();
+
+		if (ret == 0)
+			event->is_enabled = true;
+	}
+
+	return ret;
+}
+
+static void sse_events_mask(void)
+{
+	sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_HART_MASK, 0, 0, 0, 0, 0, 0);
+}
+
+static void sse_events_unmask(void)
+{
+	sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_HART_UNMASK, 0, 0, 0, 0, 0, 0);
+}
+
+static void sse_event_disable_nolock(struct sse_event *event)
+{
+	struct sse_per_cpu_evt cpu_evt;
+
+	if (sse_event_is_global(event->evt)) {
+		sse_sbi_disable_event(event);
+	} else {
+		cpu_evt.event = event;
+		cpu_evt.func = SBI_SSE_EVENT_DISABLE;
+		on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
+	}
+}
+
+void sse_event_disable(struct sse_event *event)
+{
+	scoped_guard(mutex, &sse_mutex) {
+		cpus_read_lock();
+		sse_event_disable_nolock(event);
+		event->is_enabled = false;
+		cpus_read_unlock();
+	}
+}
+
+struct sse_event *sse_event_register(u32 evt, u32 priority,
+				     sse_event_handler *handler, void *arg)
+{
+	struct sse_per_cpu_evt cpu_evt;
+	struct sse_event *event;
+	int ret = 0;
+
+	if (!sse_available)
+		return ERR_PTR(-EOPNOTSUPP);
+
+	mutex_lock(&sse_mutex);
+	if (sse_event_get(evt)) {
+		pr_debug("Event %x already registered\n", evt);
+		ret = -EEXIST;
+		goto out_unlock;
+	}
+
+	event = sse_event_alloc(evt, priority, handler, arg);
+	if (IS_ERR(event)) {
+		ret = PTR_ERR(event);
+		goto out_unlock;
+	}
+
+	cpus_read_lock();
+	if (sse_event_is_global(evt)) {
+		unsigned long preferred_hart;
+
+		ret = sse_event_attr_get_no_lock(event->global,
+						 SBI_SSE_ATTR_PREFERRED_HART,
+						 &preferred_hart);
+		if (ret)
+			goto err_event_free;
+		event->cpu = riscv_hartid_to_cpuid(preferred_hart);
+
+		ret = sse_sbi_register_event(event, event->global);
+		if (ret)
+			goto err_event_free;
+
+	} else {
+		cpu_evt.event = event;
+		atomic_set(&cpu_evt.error, 0);
+		cpu_evt.func = SBI_SSE_EVENT_REGISTER;
+		on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
+		ret = atomic_read(&cpu_evt.error);
+		if (ret) {
+			cpu_evt.func = SBI_SSE_EVENT_UNREGISTER;
+			on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
+			goto err_event_free;
+		}
+	}
+	cpus_read_unlock();
+
+	scoped_guard(spinlock, &events_list_lock)
+		list_add(&event->list, &events);
+
+	mutex_unlock(&sse_mutex);
+
+	return event;
+
+err_event_free:
+	cpus_read_unlock();
+	sse_event_free(event);
+out_unlock:
+	mutex_unlock(&sse_mutex);
+
+	return ERR_PTR(ret);
+}
+
+static void sse_event_unregister_nolock(struct sse_event *event)
+{
+	struct sse_per_cpu_evt cpu_evt;
+
+	if (sse_event_is_global(event->evt)) {
+		sse_sbi_unregister_event(event);
+	} else {
+		cpu_evt.event = event;
+		cpu_evt.func = SBI_SSE_EVENT_UNREGISTER;
+		on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
+	}
+}
+
+void sse_event_unregister(struct sse_event *event)
+{
+	scoped_guard(mutex, &sse_mutex) {
+		cpus_read_lock();
+		sse_event_unregister_nolock(event);
+		cpus_read_unlock();
+
+		scoped_guard(spinlock, &events_list_lock)
+			list_del(&event->list);
+
+		sse_event_free(event);
+	}
+}
+
+static int sse_cpu_online(unsigned int cpu)
+{
+	struct sse_event *sse_evt;
+
+	scoped_guard(spinlock, &events_list_lock) {
+		list_for_each_entry(sse_evt, &events, list) {
+			if (sse_event_is_global(sse_evt->evt))
+				continue;
+
+			sse_event_register_local(sse_evt);
+			if (sse_evt->is_enabled)
+				sse_sbi_enable_event(sse_evt);
+		}
+	}
+
+	/* Ready to handle events. Unmask SSE. */
+	sse_events_unmask();
+
+	return 0;
+}
+
+static int sse_cpu_teardown(unsigned int cpu)
+{
+	unsigned int next_cpu;
+	struct sse_event *sse_evt;
+
+	/* Mask the sse events */
+	sse_events_mask();
+
+	scoped_guard(spinlock, &events_list_lock) {
+		list_for_each_entry(sse_evt, &events, list) {
+			if (!sse_event_is_global(sse_evt->evt)) {
+
+				if (sse_evt->is_enabled)
+					sse_sbi_disable_event(sse_evt);
+
+				sse_sbi_unregister_event(sse_evt);
+				continue;
+			}
+
+			if (sse_evt->cpu != smp_processor_id())
+				continue;
+
+			/* Update destination hart for global event */
+			next_cpu = cpumask_any_but(cpu_online_mask, cpu);
+			sse_event_set_target_cpu_nolock(sse_evt, next_cpu);
+		}
+	}
+
+	return 0;
+}
+
+static void sse_reset(void)
+{
+	struct sse_event *event = NULL;
+
+	list_for_each_entry(event, &events, list) {
+		sse_event_disable_nolock(event);
+		sse_event_unregister_nolock(event);
+	}
+}
+
+static int sse_pm_notifier(struct notifier_block *nb, unsigned long action,
+			   void *data)
+{
+	WARN_ON_ONCE(preemptible());
+
+	switch (action) {
+	case CPU_PM_ENTER:
+		sse_events_mask();
+		break;
+	case CPU_PM_EXIT:
+	case CPU_PM_ENTER_FAILED:
+		sse_events_unmask();
+		break;
+	default:
+		return NOTIFY_DONE;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block sse_pm_nb = {
+	.notifier_call = sse_pm_notifier,
+};
+
+/*
+ * Mask all CPUs and unregister all events on panic, reboot or kexec.
+ */
+static int sse_reboot_notifier(struct notifier_block *nb, unsigned long action,
+				void *data)
+{
+	cpuhp_remove_state(sse_hp_state);
+
+	sse_reset();
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block sse_reboot_nb = {
+	.notifier_call = sse_reboot_notifier,
+};
+
+static int __init sse_init(void)
+{
+	int cpu, ret;
+
+	if (sbi_probe_extension(SBI_EXT_SSE) <= 0) {
+		pr_err("Missing SBI SSE extension\n");
+		return -EOPNOTSUPP;
+	}
+	pr_info("SBI SSE extension detected\n");
+
+	for_each_possible_cpu(cpu)
+		INIT_LIST_HEAD(&events);
+
+	ret = cpu_pm_register_notifier(&sse_pm_nb);
+	if (ret) {
+		pr_warn("Failed to register CPU PM notifier...\n");
+		return ret;
+	}
+
+	ret = register_reboot_notifier(&sse_reboot_nb);
+	if (ret) {
+		pr_warn("Failed to register reboot notifier...\n");
+		goto remove_cpupm;
+	}
+
+	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "riscv/sse:online",
+				sse_cpu_online, sse_cpu_teardown);
+	if (ret < 0)
+		goto remove_reboot;
+
+	sse_hp_state = ret;
+	sse_available = true;
+
+	return 0;
+
+remove_reboot:
+	unregister_reboot_notifier(&sse_reboot_nb);
+
+remove_cpupm:
+	cpu_pm_unregister_notifier(&sse_pm_nb);
+
+	return ret;
+}
+arch_initcall(sse_init);
diff --git a/include/linux/riscv_sse.h b/include/linux/riscv_sse.h
new file mode 100644
index 000000000000..c73184074b8c
--- /dev/null
+++ b/include/linux/riscv_sse.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2024 Rivos Inc.
+ */
+
+#ifndef __LINUX_RISCV_SSE_H
+#define __LINUX_RISCV_SSE_H
+
+#include <linux/types.h>
+#include <linux/linkage.h>
+
+struct sse_event;
+struct pt_regs;
+
+typedef int (sse_event_handler)(u32 event_num, void *arg, struct pt_regs *regs);
+
+#ifdef CONFIG_RISCV_SSE
+
+struct sse_event *sse_event_register(u32 event_num, u32 priority,
+				     sse_event_handler *handler, void *arg);
+
+void sse_event_unregister(struct sse_event *evt);
+
+int sse_event_set_target_cpu(struct sse_event *sse_evt, unsigned int cpu);
+
+int sse_event_enable(struct sse_event *sse_evt);
+
+void sse_event_disable(struct sse_event *sse_evt);
+
+#else
+static inline struct sse_event *sse_event_register(u32 event_num, u32 priority,
+						   sse_event_handler *handler,
+						   void *arg)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline void sse_event_unregister(struct sse_event *evt) {}
+
+static inline int sse_event_set_target_cpu(struct sse_event *sse_evt,
+					   unsigned int cpu)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int sse_event_enable(struct sse_event *sse_evt)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void sse_event_disable(struct sse_event *sse_evt) {}
+
+
+#endif
+
+#endif /* __LINUX_RISCV_SSE_H */
-- 
2.45.2



From cleger at rivosinc.com  Fri Dec  6 08:31:00 2024
From: cleger at rivosinc.com (=?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?=)
Date: Fri,  6 Dec 2024 17:31:00 +0100
Subject: [PATCH v3 4/4] perf: RISC-V: add support for SSE event
In-Reply-To: <20241206163102.843505-1-cleger@rivosinc.com>
References: <20241206163102.843505-1-cleger@rivosinc.com>
Message-ID: <20241206163102.843505-5-cleger@rivosinc.com>

In order to use SSE within PMU drivers, register a SSE handler for the
local PMU event. Reuse the existing overflow IRQ handler and pass
appropriate pt_regs.

Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
---
 drivers/perf/riscv_pmu_sbi.c | 51 +++++++++++++++++++++++++++++-------
 1 file changed, 41 insertions(+), 10 deletions(-)

diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 1aa303f76cc7..bd7ab15483db 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -17,6 +17,7 @@
 #include <linux/irqdomain.h>
 #include <linux/of_irq.h>
 #include <linux/of.h>
+#include <linux/riscv_sse.h>
 #include <linux/cpu_pm.h>
 #include <linux/sched/clock.h>
 #include <linux/soc/andes/irq.h>
@@ -946,10 +947,10 @@ static void pmu_sbi_start_overflow_mask(struct riscv_pmu *pmu,
 		pmu_sbi_start_ovf_ctrs_sbi(cpu_hw_evt, ctr_ovf_mask);
 }
 
-static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
+static irqreturn_t pmu_sbi_ovf_handler(struct cpu_hw_events *cpu_hw_evt,
+				       struct pt_regs *regs, bool from_sse)
 {
 	struct perf_sample_data data;
-	struct pt_regs *regs;
 	struct hw_perf_event *hw_evt;
 	union sbi_pmu_ctr_info *info;
 	int lidx, hidx, fidx;
@@ -957,7 +958,6 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
 	struct perf_event *event;
 	u64 overflow;
 	u64 overflowed_ctrs = 0;
-	struct cpu_hw_events *cpu_hw_evt = dev;
 	u64 start_clock = sched_clock();
 	struct riscv_pmu_snapshot_data *sdata = cpu_hw_evt->snapshot_addr;
 
@@ -967,13 +967,15 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
 	/* Firmware counter don't support overflow yet */
 	fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS);
 	if (fidx == RISCV_MAX_COUNTERS) {
-		csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num));
+		if (!from_sse)
+			csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num));
 		return IRQ_NONE;
 	}
 
 	event = cpu_hw_evt->events[fidx];
 	if (!event) {
-		ALT_SBI_PMU_OVF_CLEAR_PENDING(riscv_pmu_irq_mask);
+		if (!from_sse)
+			ALT_SBI_PMU_OVF_CLEAR_PENDING(riscv_pmu_irq_mask);
 		return IRQ_NONE;
 	}
 
@@ -988,16 +990,16 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
 
 	/*
 	 * Overflow interrupt pending bit should only be cleared after stopping
-	 * all the counters to avoid any race condition.
+	 * all the counters to avoid any race condition. When using SSE,
+	 * interrupt is cleared when stopping counters.
 	 */
-	ALT_SBI_PMU_OVF_CLEAR_PENDING(riscv_pmu_irq_mask);
+	if (!from_sse)
+		ALT_SBI_PMU_OVF_CLEAR_PENDING(riscv_pmu_irq_mask);
 
 	/* No overflow bit is set */
 	if (!overflow)
 		return IRQ_NONE;
 
-	regs = get_irq_regs();
-
 	for_each_set_bit(lidx, cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS) {
 		struct perf_event *event = cpu_hw_evt->events[lidx];
 
@@ -1053,6 +1055,22 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t pmu_sbi_ovf_irq_handler(int irq, void *dev)
+{
+	return pmu_sbi_ovf_handler(dev, get_irq_regs(), false);
+}
+
+static int pmu_sbi_ovf_sse_handler(uint32_t evt, void *arg,
+				   struct pt_regs *regs)
+{
+	struct cpu_hw_events __percpu *hw_events = arg;
+	struct cpu_hw_events *hw_event = raw_cpu_ptr(hw_events);
+
+	pmu_sbi_ovf_handler(hw_event, regs, true);
+
+	return 0;
+}
+
 static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node)
 {
 	struct riscv_pmu *pmu = hlist_entry_safe(node, struct riscv_pmu, node);
@@ -1100,9 +1118,22 @@ static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node)
 static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pdev)
 {
 	int ret;
+	struct sse_event *evt;
 	struct cpu_hw_events __percpu *hw_events = pmu->hw_events;
 	struct irq_domain *domain = NULL;
 
+	evt = sse_event_register(SBI_SSE_EVENT_LOCAL_PMU, 0,
+				 pmu_sbi_ovf_sse_handler, hw_events);
+	if (!IS_ERR(evt)) {
+		ret = sse_event_enable(evt);
+		if (!ret) {
+			pr_info("using SSE for PMU event delivery\n");
+			return 0;
+		}
+
+		sse_event_unregister(evt);
+	}
+
 	if (riscv_isa_extension_available(NULL, SSCOFPMF)) {
 		riscv_pmu_irq_num = RV_IRQ_PMU;
 		riscv_pmu_use_irq = true;
@@ -1137,7 +1168,7 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde
 		return -ENODEV;
 	}
 
-	ret = request_percpu_irq(riscv_pmu_irq, pmu_sbi_ovf_handler, "riscv-pmu", hw_events);
+	ret = request_percpu_irq(riscv_pmu_irq, pmu_sbi_ovf_irq_handler, "riscv-pmu", hw_events);
 	if (ret) {
 		pr_err("registering percpu irq failed [%d]\n", ret);
 		return ret;
-- 
2.45.2



From conor at kernel.org  Fri Dec  6 08:35:33 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 6 Dec 2024 16:35:33 +0000
Subject: [PATCH v2] dt-bindings: dma: st-stm32-dmamux: Add description
 for dma-cell values
In-Reply-To: <20241206115018.1155149-1-ksloat@cornersoftsolutions.com>
References: <20241206115018.1155149-1-ksloat@cornersoftsolutions.com>
Message-ID: <20241206-placard-hesitate-626fd285dfe6@spud>

On Fri, Dec 06, 2024 at 06:50:18AM -0500, Ken Sloat wrote:
> The dma-cell values for the stm32-dmamux are used to craft the DMA spec
> for the actual controller. These values are currently undocumented
> leaving the user to reverse engineer the driver in order to determine
> their meaning. Add a basic description, while avoiding duplicating
> information by pointing the user to the associated DMA docs that
> describe the fields in depth.
> 
> Signed-off-by: Ken Sloat <ksloat at cornersoftsolutions.com>

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/20241206/cd1ecd33/attachment.sig>

From qperret at google.com  Fri Dec  6 08:44:19 2024
From: qperret at google.com (Quentin Perret)
Date: Fri, 6 Dec 2024 16:44:19 +0000
Subject: [PATCH v4 02/14] KVM: arm64: Group setting traps for protected
 VMs by control register
In-Reply-To: <20241202154742.3611749-3-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-3-tabba@google.com>
Message-ID: <Z1Mp4zmZRL_8QEmb@google.com>

On Monday 02 Dec 2024 at 15:47:29 (+0000), Fuad Tabba wrote:
> +static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
>  {
> -	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
> -	u64 mdcr_set = 0;
> -	u64 mdcr_clear = 0;
> -	u64 cptr_set = 0;
> +	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
> +	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
> +	const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
> +	u64 val = vcpu->arch.cptr_el2;
>  
> -	/* Trap/constrain PMU */
> -	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), feature_ids)) {
> -		mdcr_set |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
> -		mdcr_clear |= MDCR_EL2_HPME | MDCR_EL2_MTPME |
> -			      MDCR_EL2_HPMN_MASK;
> +	if (!has_hvhe()) {
> +		val |= CPTR_NVHE_EL2_RES1;
> +		val &= ~(CPTR_NVHE_EL2_RES0);

It's a bit odd to do that at the beginning of the function no? Perhaps
do it last to be sure to overwrite all the changes below?

Also, not sure we need the RES1 part here, kvm_get_reset_cptr_el2()
should have set those for us.

>  	}
>  
> -	/* Trap Debug */
> -	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DebugVer), feature_ids))
> -		mdcr_set |= MDCR_EL2_TDRA | MDCR_EL2_TDA | MDCR_EL2_TDE;
> -
> -	/* Trap OS Double Lock */
> -	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DoubleLock), feature_ids))
> -		mdcr_set |= MDCR_EL2_TDOSA;
> +	/* Trap AMU */
> +	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
> +		val |= CPTR_EL2_TAM;
>  
> -	/* Trap SPE */
> -	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMSVer), feature_ids)) {
> -		mdcr_set |= MDCR_EL2_TPMS;
> -		mdcr_clear |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT;
> +	/* Trap SVE */
> +	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), id_aa64pfr0)) {
> +		if (has_hvhe())
> +			val &= ~(CPACR_ELx_ZEN);
> +		else
> +			val |= CPTR_EL2_TZ;
>  	}
>  
> -	/* Trap Trace Filter */
> -	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), feature_ids))
> -		mdcr_set |= MDCR_EL2_TTRF;
> +	/* No SME support in KVM. */
> +	BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME), id_aa64pfr1));
> +	if (has_hvhe())
> +		val &= ~(CPACR_ELx_SMEN);
> +	else
> +		val |= CPTR_EL2_TSM;
>  
>  	/* Trap Trace */
> -	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), feature_ids)) {
> +	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), id_aa64dfr0)) {
>  		if (has_hvhe())
> -			cptr_set |= CPACR_EL1_TTA;
> +			val |= CPACR_EL1_TTA;
>  		else
> -			cptr_set |= CPTR_EL2_TTA;
> +			val |= CPTR_EL2_TTA;
>  	}
>  
> -	/* Trap External Trace */
> -	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), feature_ids))
> -		mdcr_clear |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
> -
> -	vcpu->arch.mdcr_el2 |= mdcr_set;
> -	vcpu->arch.mdcr_el2 &= ~mdcr_clear;
> -	vcpu->arch.cptr_el2 |= cptr_set;
> -}
> -
> -/*
> - * Set trap register values based on features in ID_AA64MMFR0.
> - */
> -static void pvm_init_traps_aa64mmfr0(struct kvm_vcpu *vcpu)
> -{
> -	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR0_EL1);
> -	u64 mdcr_set = 0;
> -
> -	/* Trap Debug Communications Channel registers */
> -	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_FGT), feature_ids))
> -		mdcr_set |= MDCR_EL2_TDCC;
> -
> -	vcpu->arch.mdcr_el2 |= mdcr_set;
> +	vcpu->arch.cptr_el2 = val;
>  }


From andre.draszik at linaro.org  Fri Dec  6 08:31:00 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 06 Dec 2024 16:31:00 +0000
Subject: [PATCH v4 0/7] USB31DRD phy updates for Google Tensor gs101
 (orientation & DWC3 rpm)
Message-ID: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>

Hi,

This series enables USB3 Type-C lane orientation detection and
configuration on platforms that support this (Google gs101), and it
also allows the DWC3 core to enter runtime suspend even when UDC is
active.

For lane orientation, this driver now optionally (based on DT)
subscribes to the TCPC's lane orientation notifier and remembers the
orientation to later be used during phy_init().

To enable DWC3 runtime suspend, the gadget needs to inform the core via
dwc3_gadget_interrupt() with event type == DWC3_DEVICE_EVENT_DISCONNECT
of a cable disconnect. For that to allow to happen, this driver
therefore needs to stop forcing the Vbus and bvalid signals to active
and instead change their state based on actual conditions. The same
TCPC notifier is used to detect this, and program the hardware
accordingly.

That signal state is based on advice given by Thinh in
https://lore.kernel.org/all/20240813230625.jgkatqstyhcmpezv at synopsys.com/

Both changes together now allow cable orientation detection to work, as
the DWC3 will now call phy_exit() on cable disconnect, and we can
reprogram the lane mux in phy_init().

On top of that, there are some small related cleanup patches.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
Changes in v4:
- separate out patch 5 'phy: exynos5-usbdrd: gs101: ensure power is
  gated to SS phy in phy_exit()' from this series, as a stable patch
  shouldn't be buried inside a series like this (Greg)
  Link: https://lore.kernel.org/all/20241205-gs101-usb-phy-fix-v4-1-0278809fb810 at linaro.org/
- Link to v3: https://lore.kernel.org/r/20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219 at linaro.org

Changes in v3:
- patches 1 & 2: update as per Rob's suggestions
- patch 7 & 8: drop init to -1 of phy_drd->orientation (Vinod)
- patch 7: avoid an #ifdef 
- Link to v2: https://lore.kernel.org/r/20241203-gs101-phy-lanes-orientation-phy-v2-0-40dcf1b7670d at linaro.org

Changes in v2:
- squash patches #2 and #3 from v1 to actually disallow
  orientation-switch on !gs101 (not just optional) (Conor)
- update bindings commit message to clarify that the intention for the
  driver is to work with old and new DTS (Conor)
- add cc-stable and fixes tags to power gating patch (Krzysztof)
- fix an #include and typo (Peter)
- Link to v1: https://lore.kernel.org/r/20241127-gs101-phy-lanes-orientation-phy-v1-0-1b7fce24960b at linaro.org

---
Andr? Draszik (7):
      dt-bindings: phy: samsung,usb3-drd-phy: add blank lines between DT properties
      dt-bindings: phy: samsung,usb3-drd-phy: gs101: require Type-C properties
      phy: exynos5-usbdrd: convert to dev_err_probe
      phy: exynos5-usbdrd: fix EDS distribution tuning (gs101)
      phy: exynos5-usbdrd: gs101: configure SS lanes based on orientation
      phy: exynos5-usbdrd: subscribe to orientation notifier if required
      phy: exynos5-usbdrd: allow DWC3 runtime suspend with UDC bound (E850+)

 .../bindings/phy/samsung,usb3-drd-phy.yaml         |  21 ++-
 drivers/phy/samsung/Kconfig                        |   1 +
 drivers/phy/samsung/phy-exynos5-usbdrd.c           | 202 ++++++++++++++++-----
 3 files changed, 182 insertions(+), 42 deletions(-)
---
base-commit: c245a7a79602ccbee780c004c1e4abcda66aec32
change-id: 20241127-gs101-phy-lanes-orientation-phy-29d20c6d84d2

Best regards,
-- 
Andr? Draszik <andre.draszik at linaro.org>



From andre.draszik at linaro.org  Fri Dec  6 08:31:02 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 06 Dec 2024 16:31:02 +0000
Subject: [PATCH v4 2/7] dt-bindings: phy: samsung,usb3-drd-phy: gs101:
 require Type-C properties
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
Message-ID: <20241206-gs101-phy-lanes-orientation-phy-v4-2-f5961268b149@linaro.org>

orientation-switch is the standard declaration to inform the Type-C mux
layer that a remote-endpoint is capable of processing orientation
change messages.

The USB PHY on gs101 needs to be configured based on the orientation of
the connector. For that the DTS needs a link between the phy's port and
a TCPCi, and we'll need to inform the phy driver that it should handle
the orientation (register a handler).

Update the schema to enforce that by requiring the orientation-switch
and port properties on gs101 (only). We disallow orientation-switch on
all other supported platforms, since other versions of this phy (or its
system integration) don't currently support or even need it.

Even though this new required gs101 property is an ABI break, the
intention for the driver is to behave as before if it's missing
(meaning for gs101 it will work in SS mode in one orientation only).
Other platforms are not affected.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
v3:
* update as per Rob's suggestion (I hope :-)

v2:
* squash original patches #2 and #3
* actually disallow orientation-switch on !gs101 (not just optional) (Conor)
* update commit message to clarify that the intention for the driver is
  to work with old and new DTS (Conor)
* collect tags

foo
---
 Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index 1f8b35917b11..27295acbba76 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -114,6 +114,8 @@ allOf:
           contains:
             const: google,gs101-usb31drd-phy
     then:
+      $ref: /schemas/usb/usb-switch.yaml#
+
       properties:
         clocks:
           items:
@@ -139,6 +141,8 @@ allOf:
 
       required:
         - reg-names
+        - orientation-switch
+        - port
         - pll-supply
         - dvdd-usb20-supply
         - vddh-usb20-supply
@@ -198,7 +202,7 @@ allOf:
         reg-names:
           maxItems: 1
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |

-- 
2.47.0.338.g60cca15819-goog



From ivo.ivanov.ivanov1 at gmail.com  Fri Dec  6 08:44:38 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Fri, 6 Dec 2024 18:44:38 +0200
Subject: [PATCH v2 1/3] dt-bindings: clock: Add Exynos990 SoC CMU bindings
In-Reply-To: <20241206-exynos990-cmu-v2-1-4666ff0a099b@mentallysanemainliners.org>
References: <20241206-exynos990-cmu-v2-0-4666ff0a099b@mentallysanemainliners.org>
 <20241206-exynos990-cmu-v2-1-4666ff0a099b@mentallysanemainliners.org>
Message-ID: <ce85151d-cb62-43cc-ab6f-08769b98f6a5@gmail.com>

On 12/6/24 18:12, Igor Belwon wrote:
> Add dt-schema documentation for the Exynos990 SoC CMU.
>
> This clock management unit has a topmost block (CMU_TOP)
> that generates top clocks for other blocks. Currently the
> only other block implemented is CMU_HSI0, which provides
> clocks for the USB part of the SoC.
>
> Also, device-tree binding definitions added for these blocks:
> - CMU_TOP
> - CMU_HSI0
>
> Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
> ---
>  .../bindings/clock/samsung,exynos990-clock.yaml    | 120 +++++++++++
>  include/dt-bindings/clock/samsung,exynos990.h      | 236 +++++++++++++++++++++
>  2 files changed, 356 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..36d70d6d1b30fa629d5d60677851fb915934efa3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
> @@ -0,0 +1,120 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/samsung,exynos990-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung Exynos990 SoC clock controller
> +
> +maintainers:
> +  - Igor Belwon <igor.belwon at mentallysanemainliners.org>
> +  - Chanwoo Choi <cw00.choi at samsung.com>
> +  - Krzysztof Kozlowski <krzk at kernel.org>
> +
> +description: |
> +  Exynos990 clock controller is comprised of several CMU units, generating
> +  clocks for different domains. Those CMU units are modeled as separate device
> +  tree nodes, and might depend on each other. The root clock in that root tree
> +  is an external clock: OSCCLK (26 MHz). This external clock must be defined
> +  as a fixed-rate clock in dts.
> +
> +  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
> +  dividers; all other clocks of function blocks (other CMUs) are usually
> +  derived from CMU_TOP.
> +
> +  Each clock is assigned an identifier and client nodes can use this identifier
> +  to specify the clock which they consume. All clocks available for usage
> +  in clock consumer nodes are defined as preprocessor macros in
> +  'include/dt-bindings/clock/samsung,exynos990.h' header.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - samsung,exynos990-cmu-hsi0
> +      - samsung,exynos990-cmu-top
> +
> +  clocks:
> +    minItems: 1
> +    maxItems: 5
> +
> +  clock-names:
> +    minItems: 1
> +    maxItems: 5
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  reg:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - reg
> +  - "#clock-cells"

Keep the order of items in 'required:' the same as with 'properties:'.

> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: samsung,exynos990-cmu-hsi0
> +
> +    then:
> +      properties:
> +        clocks:
> +          items:
> +            - description: External reference clock (26 MHz)
> +            - description: CMU_HSI0 BUS clock (from CMU_TOP)
> +            - description: CMU_HSI0 USB31DRD clock (from CMU_TOP)
> +            - description: CMU_HSI0 USBDP_DEBUG clock (from CMU_TOP)
> +            - description: CMU_HSI0 DPGTC clock (from CMU_TOP)
> +
> +        clock-names:
> +          items:
> +            - const: oscclk
> +            - const: dout_cmu_hsi0_bus

Since there is only one bus clock that has to be provided, use a shorter
name, like "bus". It's also like that on other platform clock drivers.

> +            - const: dout_cmu_hsi0_usb31drd

usb31drd

> +            - const: dout_cmu_hsi0_usbdp_debug

usbdp

> +            - const: dout_cmu_hsi0_dpgtc

dpgtc

> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: samsung,exynos990-cmu-top
> +
> +    then:
> +      properties:
> +        clocks:
> +          items:
> +            - description: External reference clock (26 MHz)
> +
> +        clock-names:
> +          items:
> +            - const: oscclk
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/samsung,exynos990.h>
> +
> +    cmu_hsi0: clock-controller at 10a00000 {
> +        compatible = "samsung,exynos990-cmu-hsi0";
> +        reg = <0x10a00000 0x8000>;
> +        #clock-cells = <1>;
> +
> +        clocks = <&oscclk>,
> +                 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
> +                 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
> +                 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
> +                 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
> +        clock-names = "oscclk", "dout_cmu_hsi0_bus",
> +                                "dout_cmu_hsi0_usb31drd",
> +                                "dout_cmu_hsi0_usbdp_debug",
> +                                "dout_cmu_hsi0_dpgtc";

Correct here as well.
Best regards, Ivo.

> +    };
> +
> +...
> diff --git a/include/dt-bindings/clock/samsung,exynos990.h b/include/dt-bindings/clock/samsung,exynos990.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..307215a3f3eddd579e6733b51a777fb45398bb92
> --- /dev/null
> +++ b/include/dt-bindings/clock/samsung,exynos990.h
> @@ -0,0 +1,236 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (C) 2024 Igor Belwon <igor.belwon at mentallysanemainliners.org>
> + *
> + * Device Tree binding constants for Exynos990 clock controller.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_EXYNOS_990_H
> +#define _DT_BINDINGS_CLOCK_EXYNOS_990_H
> +
> +/* CMU_TOP */
> +#define CLK_FOUT_SHARED0_PLL		1
> +#define CLK_FOUT_SHARED1_PLL		2
> +#define CLK_FOUT_SHARED2_PLL		3
> +#define CLK_FOUT_SHARED3_PLL		4
> +#define CLK_FOUT_SHARED4_PLL		5
> +#define CLK_FOUT_G3D_PLL		6
> +#define CLK_FOUT_MMC_PLL		7
> +#define CLK_MOUT_PLL_SHARED0		8
> +#define CLK_MOUT_PLL_SHARED1		9
> +#define CLK_MOUT_PLL_SHARED2		10
> +#define CLK_MOUT_PLL_SHARED3		11
> +#define CLK_MOUT_PLL_SHARED4		12
> +#define CLK_MOUT_PLL_MMC		13
> +#define CLK_MOUT_PLL_G3D		14
> +#define CLK_MOUT_CMU_APM_BUS		15
> +#define CLK_MOUT_CMU_AUD_CPU		16
> +#define CLK_MOUT_CMU_BUS0_BUS		17
> +#define CLK_MOUT_CMU_BUS1_BUS		18
> +#define CLK_MOUT_CMU_BUS1_SSS		19
> +#define CLK_MOUT_CMU_CIS_CLK0		20
> +#define CLK_MOUT_CMU_CIS_CLK1		21
> +#define CLK_MOUT_CMU_CIS_CLK2		22
> +#define CLK_MOUT_CMU_CIS_CLK3		23
> +#define CLK_MOUT_CMU_CIS_CLK4		24
> +#define CLK_MOUT_CMU_CIS_CLK5		25
> +#define CLK_MOUT_CMU_CMU_BOOST		26
> +#define CLK_MOUT_CMU_CORE_BUS		27
> +#define CLK_MOUT_CMU_CPUCL0_DBG_BUS	28
> +#define CLK_MOUT_CMU_CPUCL0_SWITCH	29
> +#define CLK_MOUT_CMU_CPUCL1_SWITCH	30
> +#define CLK_MOUT_CMU_CPUCL2_BUSP	31
> +#define CLK_MOUT_CMU_CPUCL2_SWITCH	32
> +#define CLK_MOUT_CMU_CSIS_BUS		33
> +#define CLK_MOUT_CMU_CSIS_OIS_MCU	34
> +#define CLK_MOUT_CMU_DNC_BUS		35
> +#define CLK_MOUT_CMU_DNC_BUSM		36
> +#define CLK_MOUT_CMU_DNS_BUS		37
> +#define CLK_MOUT_CMU_DPU		38
> +#define CLK_MOUT_CMU_DPU_ALT		39
> +#define CLK_MOUT_CMU_DSP_BUS		40
> +#define CLK_MOUT_CMU_G2D_G2D		41
> +#define CLK_MOUT_CMU_G2D_MSCL		42
> +#define CLK_MOUT_CMU_HPM		43
> +#define CLK_MOUT_CMU_HSI0_BUS		44
> +#define CLK_MOUT_CMU_HSI0_DPGTC		45
> +#define CLK_MOUT_CMU_HSI0_USB31DRD	46
> +#define CLK_MOUT_CMU_HSI0_USBDP_DEBUG	47
> +#define CLK_MOUT_CMU_HSI1_BUS		48
> +#define CLK_MOUT_CMU_HSI1_MMC_CARD	49
> +#define CLK_MOUT_CMU_HSI1_PCIE		50
> +#define CLK_MOUT_CMU_HSI1_UFS_CARD	51
> +#define CLK_MOUT_CMU_HSI1_UFS_EMBD	52
> +#define CLK_MOUT_CMU_HSI2_BUS		53
> +#define CLK_MOUT_CMU_HSI2_PCIE		54
> +#define CLK_MOUT_CMU_IPP_BUS		55
> +#define CLK_MOUT_CMU_ITP_BUS		56
> +#define CLK_MOUT_CMU_MCSC_BUS		57
> +#define CLK_MOUT_CMU_MCSC_GDC		58
> +#define CLK_MOUT_CMU_CMU_BOOST_CPU	59
> +#define CLK_MOUT_CMU_MFC0_MFC0		60
> +#define CLK_MOUT_CMU_MFC0_WFD		61
> +#define CLK_MOUT_CMU_MIF_BUSP		62
> +#define CLK_MOUT_CMU_MIF_SWITCH		63
> +#define CLK_MOUT_CMU_NPU_BUS		64
> +#define CLK_MOUT_CMU_PERIC0_BUS		65
> +#define CLK_MOUT_CMU_PERIC0_IP		66
> +#define CLK_MOUT_CMU_PERIC1_BUS		67
> +#define CLK_MOUT_CMU_PERIC1_IP		68
> +#define CLK_MOUT_CMU_PERIS_BUS		69
> +#define CLK_MOUT_CMU_SSP_BUS		70
> +#define CLK_MOUT_CMU_TNR_BUS		71
> +#define CLK_MOUT_CMU_VRA_BUS		72
> +#define CLK_DOUT_CMU_APM_BUS		73
> +#define CLK_DOUT_CMU_AUD_CPU		74
> +#define CLK_DOUT_CMU_BUS0_BUS		75
> +#define CLK_DOUT_CMU_BUS1_BUS		76
> +#define CLK_DOUT_CMU_BUS1_SSS		77
> +#define CLK_DOUT_CMU_CIS_CLK0		78
> +#define CLK_DOUT_CMU_CIS_CLK1		79
> +#define CLK_DOUT_CMU_CIS_CLK2		80
> +#define CLK_DOUT_CMU_CIS_CLK3		81
> +#define CLK_DOUT_CMU_CIS_CLK4		82
> +#define CLK_DOUT_CMU_CIS_CLK5		83
> +#define CLK_DOUT_CMU_CMU_BOOST		84
> +#define CLK_DOUT_CMU_CORE_BUS		85
> +#define CLK_DOUT_CMU_CPUCL0_DBG_BUS	86
> +#define CLK_DOUT_CMU_CPUCL0_SWITCH	87
> +#define CLK_DOUT_CMU_CPUCL1_SWITCH	88
> +#define CLK_DOUT_CMU_CPUCL2_BUSP	89
> +#define CLK_DOUT_CMU_CPUCL2_SWITCH	90
> +#define CLK_DOUT_CMU_CSIS_BUS		91
> +#define CLK_DOUT_CMU_CSIS_OIS_MCU	92
> +#define CLK_DOUT_CMU_DNC_BUS		93
> +#define CLK_DOUT_CMU_DNC_BUSM		94
> +#define CLK_DOUT_CMU_DNS_BUS		95
> +#define CLK_DOUT_CMU_DSP_BUS		96
> +#define CLK_DOUT_CMU_G2D_G2D		97
> +#define CLK_DOUT_CMU_G2D_MSCL		98
> +#define CLK_DOUT_CMU_G3D_SWITCH		99
> +#define CLK_DOUT_CMU_HPM		100
> +#define CLK_DOUT_CMU_HSI0_BUS		101
> +#define CLK_DOUT_CMU_HSI0_DPGTC		102
> +#define CLK_DOUT_CMU_HSI0_USB31DRD	103
> +#define CLK_DOUT_CMU_HSI0_USBDP_DEBUG	104
> +#define CLK_DOUT_CMU_HSI1_BUS		105
> +#define CLK_DOUT_CMU_HSI1_MMC_CARD	106
> +#define CLK_DOUT_CMU_HSI1_PCIE		107
> +#define CLK_DOUT_CMU_HSI1_UFS_CARD	108
> +#define CLK_DOUT_CMU_HSI1_UFS_EMBD	109
> +#define CLK_DOUT_CMU_HSI2_BUS		110
> +#define CLK_DOUT_CMU_HSI2_PCIE		111
> +#define CLK_DOUT_CMU_IPP_BUS		112
> +#define CLK_DOUT_CMU_ITP_BUS		113
> +#define CLK_DOUT_CMU_MCSC_BUS		114
> +#define CLK_DOUT_CMU_MCSC_GDC		115
> +#define CLK_DOUT_CMU_CMU_BOOST_CPU	116
> +#define CLK_DOUT_CMU_MFC0_MFC0		117
> +#define CLK_DOUT_CMU_MFC0_WFD		118
> +#define CLK_DOUT_CMU_MIF_BUSP		119
> +#define CLK_DOUT_CMU_NPU_BUS		120
> +#define CLK_DOUT_CMU_OTP		121
> +#define CLK_DOUT_CMU_PERIC0_BUS		122
> +#define CLK_DOUT_CMU_PERIC0_IP		123
> +#define CLK_DOUT_CMU_PERIC1_BUS		124
> +#define CLK_DOUT_CMU_PERIC1_IP		125
> +#define CLK_DOUT_CMU_PERIS_BUS		126
> +#define CLK_DOUT_CMU_SSP_BUS		127
> +#define CLK_DOUT_CMU_TNR_BUS		128
> +#define CLK_DOUT_CMU_VRA_BUS		129
> +#define CLK_DOUT_CMU_DPU		130
> +#define CLK_DOUT_CMU_DPU_ALT		131
> +#define CLK_DOUT_CMU_SHARED0_DIV2	132
> +#define CLK_DOUT_CMU_SHARED0_DIV3	133
> +#define CLK_DOUT_CMU_SHARED0_DIV4	134
> +#define CLK_DOUT_CMU_SHARED1_DIV2	135
> +#define CLK_DOUT_CMU_SHARED1_DIV3	136
> +#define CLK_DOUT_CMU_SHARED1_DIV4	137
> +#define CLK_DOUT_CMU_SHARED2_DIV2	138
> +#define CLK_DOUT_CMU_SHARED4_DIV2	139
> +#define CLK_DOUT_CMU_SHARED4_DIV3	140
> +#define CLK_DOUT_CMU_SHARED4_DIV4	141
> +#define CLK_GOUT_CMU_G3D_BUS		142
> +#define CLK_GOUT_CMU_MIF_SWITCH		143
> +#define CLK_GOUT_CMU_APM_BUS		144
> +#define CLK_GOUT_CMU_AUD_CPU		145
> +#define CLK_GOUT_CMU_BUS0_BUS		146
> +#define CLK_GOUT_CMU_BUS1_BUS		147
> +#define CLK_GOUT_CMU_BUS1_SSS		148
> +#define CLK_GOUT_CMU_CIS_CLK0		149
> +#define CLK_GOUT_CMU_CIS_CLK1		150
> +#define CLK_GOUT_CMU_CIS_CLK2		151
> +#define CLK_GOUT_CMU_CIS_CLK3		152
> +#define CLK_GOUT_CMU_CIS_CLK4		153
> +#define CLK_GOUT_CMU_CIS_CLK5		154
> +#define CLK_GOUT_CMU_CORE_BUS		155
> +#define CLK_GOUT_CMU_CPUCL0_DBG_BUS	156
> +#define CLK_GOUT_CMU_CPUCL0_SWITCH	157
> +#define CLK_GOUT_CMU_CPUCL1_SWITCH	158
> +#define CLK_GOUT_CMU_CPUCL2_BUSP	159
> +#define CLK_GOUT_CMU_CPUCL2_SWITCH	160
> +#define CLK_GOUT_CMU_CSIS_BUS		161
> +#define CLK_GOUT_CMU_CSIS_OIS_MCU	162
> +#define CLK_GOUT_CMU_DNC_BUS		163
> +#define CLK_GOUT_CMU_DNC_BUSM		164
> +#define CLK_GOUT_CMU_DNS_BUS		165
> +#define CLK_GOUT_CMU_DPU		166
> +#define CLK_GOUT_CMU_DPU_BUS		167
> +#define CLK_GOUT_CMU_DSP_BUS		168
> +#define CLK_GOUT_CMU_G2D_G2D		169
> +#define CLK_GOUT_CMU_G2D_MSCL		170
> +#define CLK_GOUT_CMU_G3D_SWITCH		171
> +#define CLK_GOUT_CMU_HPM		172
> +#define CLK_GOUT_CMU_HSI0_BUS		173
> +#define CLK_GOUT_CMU_HSI0_DPGTC		174
> +#define CLK_GOUT_CMU_HSI0_USB31DRD	175
> +#define CLK_GOUT_CMU_HSI0_USBDP_DEBUG	176
> +#define CLK_GOUT_CMU_HSI1_BUS		177
> +#define CLK_GOUT_CMU_HSI1_MMC_CARD	178
> +#define CLK_GOUT_CMU_HSI1_PCIE		179
> +#define CLK_GOUT_CMU_HSI1_UFS_CARD	180
> +#define CLK_GOUT_CMU_HSI1_UFS_EMBD	181
> +#define CLK_GOUT_CMU_HSI2_BUS		182
> +#define CLK_GOUT_CMU_HSI2_PCIE		183
> +#define CLK_GOUT_CMU_IPP_BUS		184
> +#define CLK_GOUT_CMU_ITP_BUS		185
> +#define CLK_GOUT_CMU_MCSC_BUS		186
> +#define CLK_GOUT_CMU_MCSC_GDC		187
> +#define CLK_GOUT_CMU_MFC0_MFC0		188
> +#define CLK_GOUT_CMU_MFC0_WFD		189
> +#define CLK_GOUT_CMU_MIF_BUSP		190
> +#define CLK_GOUT_CMU_NPU_BUS		191
> +#define CLK_GOUT_CMU_PERIC0_BUS		192
> +#define CLK_GOUT_CMU_PERIC0_IP		193
> +#define CLK_GOUT_CMU_PERIC1_BUS		194
> +#define CLK_GOUT_CMU_PERIC1_IP		195
> +#define CLK_GOUT_CMU_PERIS_BUS		196
> +#define CLK_GOUT_CMU_SSP_BUS		197
> +#define CLK_GOUT_CMU_TNR_BUS		198
> +#define CLK_GOUT_CMU_VRA_BUS		199
> +
> +/* CMU_HSI0 */
> +#define CLK_MOUT_HSI0_BUS_USER				1
> +#define CLK_MOUT_HSI0_USB31DRD_USER			2
> +#define CLK_MOUT_HSI0_USBDP_DEBUG_USER			3
> +#define CLK_MOUT_HSI0_DPGTC_USER			4
> +#define CLK_GOUT_HSI0_DP_LINK_DP_GTC_CLK		5
> +#define CLK_GOUT_HSI0_DP_LINK_PCLK			6
> +#define CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK			7
> +#define CLK_GOUT_HSI0_LHM_AXI_P_HSI0_CLK		8
> +#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_ACLK		9
> +#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_PCLK		10
> +#define CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK			11
> +#define CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2			12
> +#define CLK_GOUT_HSI0_SYSREG_HSI0_PCLK			13
> +#define CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL		14
> +#define CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY		15
> +#define CLK_GOUT_HSI0_USB31DRD_USB31DRD_REF_CLK_40	16
> +#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_REF_SOC_PLL	17
> +#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_SCL_APB		18
> +#define CLK_GOUT_HSI0_USB31DRD_USBPCS_APB_CLK		19
> +#define CLK_GOUT_HSI0_VGEN_LITE_HSI0_CLK		20
> +#define CLK_GOUT_HSI0_CMU_HSI0_PCLK			21
> +#define CLK_GOUT_HSI0_XIU_D_HSI0_ACLK			22
> +
> +#endif
>



From ukleinek at kernel.org  Fri Dec  6 08:53:08 2024
From: ukleinek at kernel.org (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Fri, 6 Dec 2024 17:53:08 +0100
Subject: [PATCH V2] pwm: stm32-lp: Add check for clk_enable()
In-Reply-To: <cim6rnzdvhik4kdibfmglf6jiky7xccynqwazmxmnr2f5fvu3f@lvoo3drlgaua>
References: <20241206012605.2877412-1-zmw12306@gmail.com>
 <cim6rnzdvhik4kdibfmglf6jiky7xccynqwazmxmnr2f5fvu3f@lvoo3drlgaua>
Message-ID: <o6rh2bcxnnubhx6xem55otgequw5zrqmkretcgofohvcpbygdw@z3qagurhjyp3>

On Fri, Dec 06, 2024 at 08:12:57AM +0100, Uwe Kleine-K?nig wrote:
> On Thu, Dec 05, 2024 at 08:26:05PM -0500, Mingwei Zheng wrote:
> > Add check for the return value of clk_enable() to catch the potential
> > error.
> > 
> > Fixes: e70a540b4e02 ("pwm: Add STM32 LPTimer PWM driver")
> > Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> > Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
> 
> In reply to (implicit) v1 you wrote:
> > We detected this through static analysis, instead of actually hit.
> 
> Would be nice to mention the tool that actually found it in the commit
> log.
> 
> Otherwise I'm happy with that change now.
> 
> Given the issue is old (the offending commit is in v4.14-rc1), I'd note
> send it as a fix before v4.14. I'd send it along however if something
> more urgent pops up.

I wasn't very attentive when I wrote that mail, what I meant was:

Given the issue is old (the offending commit is in v4.14-rc1), I'd not
send it as a fix before v6.13. I'd send it along however if something
more urgent pops up.

Best regards
Uwe


-------------- 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/20241206/3180abf1/attachment.sig>

From helgaas at kernel.org  Fri Dec  6 08:54:57 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 6 Dec 2024 10:54:57 -0600
Subject: [PATCH v12 4/5] drivers/perf: add DesignWare PCIe PMU driver
In-Reply-To: <20231208025652.87192-5-xueshuai@linux.alibaba.com>
Message-ID: <20241206165457.GA3101599@bhelgaas>

On Fri, Dec 08, 2023 at 10:56:51AM +0800, Shuai Xue wrote:
> This commit adds the PCIe Performance Monitoring Unit (PMU) driver support
> for T-Head Yitian SoC chip. Yitian is based on the Synopsys PCI Express
> Core controller IP which provides statistics feature. The PMU is a PCIe
> configuration space register block provided by each PCIe Root Port in a
> Vendor-Specific Extended Capability named RAS D.E.S (Debug, Error
> injection, and Statistics).

> +#define DWC_PCIE_VSEC_RAS_DES_ID		0x02

> +static const struct dwc_pcie_vendor_id dwc_pcie_vendor_ids[] = {
> +	{.vendor_id = PCI_VENDOR_ID_ALIBABA },
> +	{} /* terminator */
> +};

> +static bool dwc_pcie_match_des_cap(struct pci_dev *pdev)
> +{
> +	const struct dwc_pcie_vendor_id *vid;
> +	u16 vsec;
> +	u32 val;
> +
> +	if (!pci_is_pcie(pdev) || !(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT))
> +		return false;
> +
> +	for (vid = dwc_pcie_vendor_ids; vid->vendor_id; vid++) {
> +		vsec = pci_find_vsec_capability(pdev, vid->vendor_id,
> +						DWC_PCIE_VSEC_RAS_DES_ID);

This looks wrong to me, and it promotes a misunderstanding of how VSEC
Capabilities work.  The VSEC ID is defined by the vendor, so we have
to check both the Vendor ID and the VSEC ID before we know what this
VSEC Capability is.

In this patch, we only find a VSEC Capability that matches
(PCI_VENDOR_ID_ALIBABA, DWC_PCIE_VSEC_RAS_DES_ID), but as of
v6.13-rc1, it finds all of these:

  (PCI_VENDOR_ID_ALIBABA, DWC_PCIE_VSEC_RAS_DES_ID)
  (PCI_VENDOR_ID_AMPERE, DWC_PCIE_VSEC_RAS_DES_ID)
  (PCI_VENDOR_ID_QCOM, DWC_PCIE_VSEC_RAS_DES_ID)

There is no assurance that DWC_PCIE_VSEC_RAS_DES_ID means the same
thing to Alibaba, Ampere, and Qualcomm because each company defines
what 0x02 means to it.  PCIe r6.0, sec 7.9.5 for details.

I alluded to this earlier [1] and suggested that these devices should
have used a Designated Vendor-Specific (DVSEC) Capability instead of a 
Vendor-Specific (VSEC) Capability.

But since they didn't, I think the dwc_pcie_vendor_ids[] table is a
dangerous way to work around this because it suggests that all we have
to do is add new vendors to that table.

I think the table should be extended to contain the Vendor ID, *and*
the VSEC ID, *and* the VSEC Rev used by that vendor, i.e., it should
look like this:

  struct dwc_pcie_pmu_vsec {
    u16 vendor_id;
    u16 vsec_id;
    u8 vsec_rev;
  };

  struct dwc_pcie_pmu_vsec dwc_pcie_pmu_vsec_ids[] = {
    { .vendor_id = PCI_VENDOR_ID_ALIBABA,
      .vsec_id = DWC_PCIE_VSEC_RAS_DES_ID, .vsec_rev = 0x4 },
    { .vendor_id = PCI_VENDOR_ID_AMPERE,
      .vsec_id = DWC_PCIE_VSEC_RAS_DES_ID, .vsec_rev = 0x4 },
    { .vendor_id = PCI_VENDOR_ID_QCOM,
      .vsec_id = DWC_PCIE_VSEC_RAS_DES_ID, .vsec_rev = 0x4 },
    {}
  };

This *looks* the same, but it's not, because it makes it obvious that
the VSEC ID and VSEC Rev are defined separately by each vendor.  It's
just a lucky coincidence that they happen to be the same for these
vendors.

> +		if (vsec)
> +			break;
> +	}
> +	if (!vsec)
> +		return false;
> +
> +	pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER, &val);
> +	if (PCI_VNDR_HEADER_REV(val) != 0x04)
> +		return false;
> +
> +	pci_dbg(pdev,
> +		"Detected PCIe Vendor-Specific Extended Capability RAS DES\n");
> +	return true;
> +}

> +static int dwc_pcie_pmu_probe(struct platform_device *plat_dev)
> +{
> +	struct pci_dev *pdev = plat_dev->dev.platform_data;
> +	struct dwc_pcie_pmu *pcie_pmu;
> +	char *name;
> +	u32 bdf, val;
> +	u16 vsec;
> +	int ret;
> +
> +	vsec = pci_find_vsec_capability(pdev, pdev->vendor,
> +					DWC_PCIE_VSEC_RAS_DES_ID);
> +     pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER, &val);

Nit: "val" is never used, so why read it?

This looks even more wrong, because this matches ANY VSEC Capability
from ANY vendor that happens to be numbered DWC_PCIE_VSEC_RAS_DES_ID.

I know this is indirectly qualified by the check above in
dwc_pcie_match_des_cap(), but duplicating this here just spreads the
confusion about how to interpret VSEC IDs.

I suggest updating dwc_pcie_match_des_cap() to iterate through the
dwc_pcie_pmu_vsec_ids[] table and return the capability offset so you
can call it from here.

Bjorn

[1] https://lore.kernel.org/r/20231012162512.GA1069387 at bhelgaas



From sebastian.reichel at collabora.com  Fri Dec  6 08:59:35 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 6 Dec 2024 17:59:35 +0100
Subject: [PATCH 0/2] phy: phy-rockchip-samsung-hdptx: don't use of-alias
In-Reply-To: <20241206103401.1780416-1-heiko@sntech.de>
References: <20241206103401.1780416-1-heiko@sntech.de>
Message-ID: <vdg36bpis2bzawbei6eacojttuth5ihtp7o5fabs6f6rkctikl@hofd3mjepunv>

Hi,

On Fri, Dec 06, 2024 at 11:33:59AM +0100, Heiko Stuebner wrote:
> One nice comment addition and removal of of_alias usage for core
> device functionality.
> 
> Heiko Stuebner (2):
>   phy: phy-rockchip-samsung-hdptx: annotate regmap register-callback
>   phy: phy-rockchip-samsung-hdptx: Don't use dt aliases to determine
>     phy-id
> 
>  .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 64 +++++++++++++++----
>  1 file changed, 51 insertions(+), 13 deletions(-)

Full series is

Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.com>

-- 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/20241206/4ccb9d80/attachment.sig>

From mathieu.poirier at linaro.org  Fri Dec  6 09:00:47 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 6 Dec 2024 10:00:47 -0700
Subject: [PATCH 1/4] remoteproc/omap: Handle ARM dma_iommu_mapping
In-Reply-To: <6186e311cb6f64a787f87fd41e49a73f409b789c.1730136799.git.robin.murphy@arm.com>
References: <cover.1730136799.git.robin.murphy@arm.com>
 <6186e311cb6f64a787f87fd41e49a73f409b789c.1730136799.git.robin.murphy@arm.com>
Message-ID: <Z1Mtv9cEobzvMSsS@p14s>

On Mon, Oct 28, 2024 at 05:58:35PM +0000, Robin Murphy wrote:
> It's no longer practical for the OMAP IOMMU driver to trick
> arm_setup_iommu_dma_ops() into ignoring its presence, so let's use the
> same tactic as other IOMMU API users on 32-bit ARM and explicitly kick
> the arch code's dma_iommu_mapping out of the way to avoid problems.
> 
> Fixes: 4720287c7bf7 ("iommu: Remove struct iommu_ops *iommu from arch_setup_dma_ops()")
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>  drivers/remoteproc/omap_remoteproc.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
> index 9ae2e831456d..3260dd512491 100644
> --- a/drivers/remoteproc/omap_remoteproc.c
> +++ b/drivers/remoteproc/omap_remoteproc.c
> @@ -37,6 +37,10 @@
>  
>  #include <linux/platform_data/dmtimer-omap.h>
>  
> +#ifdef CONFIG_ARM_DMA_USE_IOMMU
> +#include <asm/dma-iommu.h>
> +#endif
> +
>  #include "omap_remoteproc.h"
>  #include "remoteproc_internal.h"
>  
> @@ -1323,6 +1327,19 @@ static int omap_rproc_probe(struct platform_device *pdev)
>  	/* All existing OMAP IPU and DSP processors have an MMU */
>  	rproc->has_iommu = true;
>  
> +#ifdef CONFIG_ARM_DMA_USE_IOMMU
> +	/*
> +	 * Throw away the ARM DMA mapping that we'll never use, so it doesn't
> +	 * interfere with the core rproc->domain and we get the right DMA ops.
> +	 */
> +	if (pdev->dev.archdata.mapping) {
> +		struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(&pdev->dev);
> +
> +		arm_iommu_detach_device(&pdev->dev);
> +		arm_iommu_release_mapping(mapping);
> +	}
> +#endif
> +

Despite acknowledging this patch I never applied it, something I have corrected
now.

Thanks for Beleswar for bringing this to my attention.

Regards,
Mathieu

>  	ret = omap_rproc_of_get_internal_memories(pdev, rproc);
>  	if (ret)
>  		return ret;
> -- 
> 2.39.2.101.g768bb238c484.dirty
> 


From conor at kernel.org  Fri Dec  6 09:02:49 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 6 Dec 2024 17:02:49 +0000
Subject: [PATCH] dt-bindings: mmc: atmel,hsmci: Convert to json schema
In-Reply-To: <4e3a4154-9e05-40b4-961f-6d7e95ec0890@microchip.com>
References: <20241205-hsmci-v1-1-5a25e622dfed@microchip.com>
 <20241205-trickster-rebate-d5e64bc29992@spud>
 <4e3a4154-9e05-40b4-961f-6d7e95ec0890@microchip.com>
Message-ID: <20241206-untoasted-ripening-83ecf98bc42f@spud>

On Fri, Dec 06, 2024 at 05:16:39AM +0000, Dharma.B at microchip.com wrote:
> Hi Conor,
> 
> On 05/12/24 11:15 pm, Conor Dooley wrote:
> > On Thu, Dec 05, 2024 at 03:27:02PM +0530, Dharma Balasubiramani wrote:
> > 
> >> +patternProperties:
> >> +  "^slot@[0-9]+$":
> >> +    type: object
> >> +    description: A slot node representing an MMC, SD, or SDIO slot.
> >> +
> >> +    allOf:
> >> +      - $ref: mmc-controller.yaml
> >> +
> >> +    properties:
> >> +      reg:
> >> +        description: Slot ID.
> >> +        minimum: 0
> >> +
> >> +      bus-width:
> >> +        description: Number of data lines connected to the controller.
> >> +        enum: [1, 4, 8]
> >> +
> >> +      cd-gpios:
> >> +        description: GPIO used for card detection.
> >> +
> >> +      cd-inverted:
> >> +        type: boolean
> > This type conflicts with mmc-controller.yaml, it's a flag there.
> 
> Yes, I overlooked it. I'll simply remove the type here.
> 
> > 
> >> +        description: Inverts the value of the card detection GPIO.
> >> +
> >> +      wp-gpios:
> >> +        description: GPIO used for write protection.
> >> +
> >> +    required:
> >> +      - reg
> >> +      - bus-width
> >> +
> >> +    unevaluatedProperties: false
> > Do you mean additionalProperties: false here? You listed properties
> > contained in mmc-controller.yaml which makes it seem like you're
> > restricting to this subset rather than allowing all properties - but you
> > need additionalProperties: false to do that.
> 
> No, I'm not restricting the properties to this subset. There are 
> additional properties, such as "non-removable," "broken-cd," and 
> "disable-wp," that are used in our DTS files but are not defined in the 
> old text bindings. For this reason, I used `unevaluatedProperties: 
> false` instead of `additionalProperties: false`.

> Let me know if an 
> `allOf` reference to `mmc-controller` alone would be sufficient in this 
> context.

Yes, there's no point duplicating properties from there, unless you're
restricting to a subset. I think all you need to keep (other than the
reference) is the required properties list because there seems to be
none in mmc-controller.yaml.
-------------- 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/20241206/201092ba/attachment.sig>

From conor at kernel.org  Fri Dec  6 09:08:21 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 6 Dec 2024 17:08:21 +0000
Subject: [PATCH v2 1/2] dt-bindings: clock: rk3188-common: add
 PCLK_CIF0/PCLK_CIF1
In-Reply-To: <20241205182954.5346-1-val@packett.cool>
References: <20241205182954.5346-1-val@packett.cool>
Message-ID: <20241206-quadrant-gliding-e28b79c09c2e@spud>

On Thu, Dec 05, 2024 at 03:29:35PM -0300, Val Packett wrote:
> Add missing clock IDs for the CIF (Camera InterFace) blocks
> on the RK3188/RK3066.
> 
> Signed-off-by: Val Packett <val at packett.cool>

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/20241206/b47cea6f/attachment.sig>

From qperret at google.com  Fri Dec  6 09:10:26 2024
From: qperret at google.com (Quentin Perret)
Date: Fri, 6 Dec 2024 17:10:26 +0000
Subject: [PATCH v4 04/14] KVM: arm64: Use KVM extension checks for
 allowed protected VM capabilities
In-Reply-To: <20241202154742.3611749-5-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-5-tabba@google.com>
Message-ID: <Z1MwAomiLhnMn--k@google.com>

On Monday 02 Dec 2024 at 15:47:31 (+0000), Fuad Tabba wrote:
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index fb733b36c6c1..59ff6aac514c 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -329,34 +329,20 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
>  
>  	bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
>  
> -	/*
> -	 * For protected VMs, always allow:
> -	 * - CPU starting in poweroff state
> -	 * - PSCI v0.2
> -	 */
> -	set_bit(KVM_ARM_VCPU_POWER_OFF, allowed_features);

For my understanding, why do we drop this bit?

>  	set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
>  
> -	/*
> -	 * Check if remaining features are allowed:
> -	 * - Performance Monitoring
> -	 * - Scalable Vectors
> -	 * - Pointer Authentication
> -	 */
> -	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), PVM_ID_AA64DFR0_ALLOW))
> +	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PMU_V3))
>  		set_bit(KVM_ARM_VCPU_PMU_V3, allowed_features);
>  
> -	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), PVM_ID_AA64PFR0_ALLOW))
> -		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
> -
> -	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_ALLOW) &&
> -	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_ALLOW))
> +	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_ADDRESS))
>  		set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
>  
> -	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI), PVM_ID_AA64ISAR1_ALLOW) &&
> -	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA), PVM_ID_AA64ISAR1_ALLOW))
> +	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_GENERIC))
>  		set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
>  
> +	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE))
> +		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
> +
>  	bitmap_and(kvm->arch.vcpu_features, host_kvm->arch.vcpu_features,
>  		   allowed_features, KVM_VCPU_MAX_FEATURES);
>  }
> -- 
> 2.47.0.338.g60cca15819-goog
> 


From catalin.marinas at arm.com  Fri Dec  6 09:13:07 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 6 Dec 2024 17:13:07 +0000
Subject: [PATCH 1/2] arm64: mm: vmemmap populate to page level if not
 section aligned
In-Reply-To: <20241121071256.487220-2-quic_zhenhuah@quicinc.com>
References: <20241121071256.487220-1-quic_zhenhuah@quicinc.com>
 <20241121071256.487220-2-quic_zhenhuah@quicinc.com>
Message-ID: <Z1Mwo5OajFZQYlOg@arm.com>

On Thu, Nov 21, 2024 at 03:12:55PM +0800, Zhenhua Huang wrote:
> Commit 2045a3b8911b ("mm/sparse-vmemmap: generalise vmemmap_populate_hugepages()")
> optimizes the vmemmap to populate at the PMD section level.

Wasn't the above commit just a non-functional change making the code
generic? If there was a functional change, it needs to be spelt out. It
also implies that the code prior to the above commit needs fixing.

> However, if start
> or end is not aligned to a section boundary, such as when a subsection is hot
> added, populating the entire section is inefficient and wasteful. In such
> cases, it is more effective to populate at page granularity.

Do you have any numbers to show how inefficient it is? We trade some
memory for less TLB pressure by using huge pages for vmemmap.

> This change also addresses misalignment issues during vmemmap_free(). When
> pmd_sect() is true, the entire PMD section is cleared, even if only a
> subsection is mapped. For example, if subsections pagemap1 and pagemap2 are
> added sequentially and then pagemap1 is removed, vmemmap_free() will clear the
> entire PMD section, even though pagemap2 is still active.

What do you mean by a PMD section? The whole PAGE_SIZE *
PAGES_PER_SECTION range or a single pmd entry? I couldn't see how the
former happens in the core code but I only looked briefly. If it's just
a pmd entry, I think it's fair to require a 2MB alignment of hotplugged
memory ranges.

-- 
Catalin


From Frank.li at nxp.com  Fri Dec  6 09:12:51 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 6 Dec 2024 12:12:51 -0500
Subject: [PATCH] arm64: dts: s32g: add I2C support
In-Reply-To: <20241206123119.1688712-1-ciprianmarian.costea@oss.nxp.com>
References: <20241206123119.1688712-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <Z1MwkyWka3yDm8Ez@lizhi-Precision-Tower-5810>

On Fri, Dec 06, 2024 at 02:31:19PM +0200, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>
> Add the I2C Devicetree nodes and pinmux for S32G2 and S32G3 SoCs.
>
> With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
> (rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
> are quite similar. The common part for the EVB revisions will be
> centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
> be placed in 's32gxxa-rdb.dtsi' file.
>
> This refactor will also serve for other modules in the future, such as
> FlexCAN, DSPI.
>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/s32g2.dtsi      |  45 ++++++
>  .../arm64/boot/dts/freescale/s32g274a-evb.dts |   1 +
>  .../boot/dts/freescale/s32g274a-rdb2.dts      |   1 +
>  arch/arm64/boot/dts/freescale/s32g3.dtsi      |  50 ++++++
>  .../boot/dts/freescale/s32g399a-rdb3.dts      |  12 ++
>  .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
>  .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 124 +++++++++++++++
>  7 files changed, 383 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>
> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> index 7be430b78c83..0e6c847ab0c3 100644
> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> @@ -333,6 +333,33 @@ uart1: serial at 401cc000 {
>  			status = "disabled";
>  		};
>
> +		i2c0: i2c at 401e4000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x401e4000 0x1000>;
> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;

hardcode 40? can you use macro for clock index? Many place use it.

Frank

> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c1: i2c at 401e8000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x401e8000 0x1000>;
> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c2: i2c at 401ec000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x401ec000 0x1000>;
> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		uart2: serial at 402bc000 {
>  			compatible = "nxp,s32g2-linflexuart",
>  				     "fsl,s32v234-linflexuart";
> @@ -341,6 +368,24 @@ uart2: serial at 402bc000 {
>  			status = "disabled";
>  		};
>
> +		i2c3: i2c at 402d8000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x402d8000 0x1000>;
> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c4: i2c at 402dc000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x402dc000 0x1000>;
> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		usdhc0: mmc at 402f0000 {
>  			compatible = "nxp,s32g2-usdhc";
>  			reg = <0x402f0000 0x1000>;
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> index b9a119eea2b7..c4a195dd67bf 100644
> --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> @@ -7,6 +7,7 @@
>  /dts-v1/;
>
>  #include "s32g2.dtsi"
> +#include "s32gxxxa-evb.dtsi"
>
>  / {
>  	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> index aaa61a8ad0da..b5ba51696f43 100644
> --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> @@ -7,6 +7,7 @@
>  /dts-v1/;
>
>  #include "s32g2.dtsi"
> +#include "s32gxxxa-rdb.dtsi"
>
>  / {
>  	model = "NXP S32G2 Reference Design Board 2 (S32G-VNP-RDB2)";
> diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> index 6c572ffe37ca..666e4029e588 100644
> --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> @@ -390,6 +390,36 @@ uart1: serial at 401cc000 {
>  			status = "disabled";
>  		};
>
> +		i2c0: i2c at 401e4000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x401e4000 0x1000>;
> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c1: i2c at 401e8000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x401e8000 0x1000>;
> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c2: i2c at 401ec000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x401ec000 0x1000>;
> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		uart2: serial at 402bc000 {
>  			compatible = "nxp,s32g3-linflexuart",
>  				     "fsl,s32v234-linflexuart";
> @@ -398,6 +428,26 @@ uart2: serial at 402bc000 {
>  			status = "disabled";
>  		};
>
> +		i2c3: i2c at 402d8000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x402d8000 0x1000>;
> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c4: i2c at 402dc000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x402dc000 0x1000>;
> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		usdhc0: mmc at 402f0000 {
>  			compatible = "nxp,s32g3-usdhc",
>  				     "nxp,s32g2-usdhc";
> diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> index 828e353455b5..eb73a5dcebe7 100644
> --- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> @@ -8,6 +8,7 @@
>  /dts-v1/;
>
>  #include "s32g3.dtsi"
> +#include "s32gxxxa-rdb.dtsi"
>
>  / {
>  	model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
> @@ -39,6 +40,17 @@ &uart1 {
>  	status = "okay";
>  };
>
> +&i2c4 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	ina231 at 40 {
> +		compatible = "ti,ina231";
> +		reg = <0x40>;
> +		shunt-resistor = <1000>;
> +	};
> +};
> +
>  &usdhc0 {
>  	pinctrl-names = "default", "state_100mhz", "state_200mhz";
>  	pinctrl-0 = <&pinctrl_usdhc0>;
> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
> new file mode 100644
> index 000000000000..a44eff28073a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
> @@ -0,0 +1,150 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> +/*
> + * Copyright 2024 NXP
> + *
> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
> + *          Larisa Grigore <larisa.grigore at nxp.com>
> + */
> +
> +&pinctrl {
> +	i2c0_pins: i2c0-pins {
> +		i2c0-grp0 {
> +			pinmux = <0x101>, <0x111>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-grp1 {
> +			pinmux = <0x2352>, <0x2362>;
> +		};
> +	};
> +
> +	i2c0_gpio_pins: i2c0-gpio-pins {
> +		i2c0-gpio-grp0 {
> +			pinmux = <0x100>, <0x110>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-gpio-grp1 {
> +			pinmux = <0x2350>, <0x2360>;
> +		};
> +	};
> +
> +	i2c1_pins: i2c1-pins {
> +		i2c1-grp0 {
> +			pinmux = <0x131>, <0x141>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c1-grp1 {
> +			pinmux = <0x2cd2>, <0x2ce2>;
> +		};
> +	};
> +
> +	i2c1_gpio_pins: i2c1-gpio-pins {
> +		i2c1-gpio-grp0 {
> +			pinmux = <0x130>, <0x140>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c1-gpio-grp1 {
> +			pinmux = <0x2cd0>, <0x2ce0>;
> +		};
> +	};
> +
> +	i2c2_pins: i2c2-pins {
> +		i2c2-grp0 {
> +			pinmux = <0x151>, <0x161>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c2-grp1 {
> +			pinmux = <0x2cf2>, <0x2d02>;
> +		};
> +	};
> +
> +	i2c2_gpio_pins: i2c2-gpio-pins {
> +		i2c2-gpio-grp0 {
> +			pinmux = <0x150>, <0x160>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c2-gpio-grp1 {
> +			pinmux = <0x2cf0>, <0x2d00>;
> +		};
> +	};
> +
> +	i2c4_pins: i2c4-pins {
> +		i2c4-grp0 {
> +			pinmux = <0x211>, <0x222>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-grp1 {
> +			pinmux = <0x2d43>, <0x2d33>;
> +		};
> +	};
> +
> +	i2c4_gpio_pins: i2c4-gpio-pins {
> +		i2c4-gpio-grp0 {
> +			pinmux = <0x210>, <0x220>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-gpio-grp1 {
> +			pinmux = <0x2d40>, <0x2d30>;
> +		};
> +	};
> +};
> +
> +&i2c0 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c0_pins>;
> +	pinctrl-1 = <&i2c0_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c1 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c1_pins>;
> +	pinctrl-1 = <&i2c1_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c2_pins>;
> +	pinctrl-1 = <&i2c2_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c4 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c4_pins>;
> +	pinctrl-1 = <&i2c4_gpio_pins>;
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
> new file mode 100644
> index 000000000000..d992c0c9e695
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
> @@ -0,0 +1,124 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> +/*
> + * Copyright 2024 NXP
> + *
> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
> + *          Larisa Grigore <larisa.grigore at nxp.com>
> + */
> +
> +&pinctrl {
> +	i2c0_pins: i2c0-pins {
> +		i2c0-grp0 {
> +			pinmux = <0x1f2>, <0x201>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-grp1 {
> +			pinmux = <0x2353>, <0x2363>;
> +		};
> +	};
> +
> +	i2c0_gpio_pins: i2c0-gpio-pins {
> +		i2c0-gpio-grp0 {
> +			pinmux = <0x1f0>, <0x200>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-gpio-grp1 {
> +			pinmux = <0x2350>, <0x2360>;
> +		};
> +	};
> +
> +	i2c2_pins: i2c2-pins {
> +		i2c2-grp0 {
> +			pinmux = <0x151>, <0x161>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c2-grp1 {
> +			pinmux = <0x2cf2>, <0x2d02>;
> +		};
> +	};
> +
> +	i2c2_gpio_pins: i2c2-gpio-pins {
> +		i2c2-gpio-grp0 {
> +			pinmux = <0x2cf0>, <0x2d00>;
> +		};
> +
> +		i2c2-gpio-grp1 {
> +			pinmux = <0x150>, <0x160>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +	};
> +
> +	i2c4_pins: i2c4-pins {
> +		i2c4-grp0 {
> +			pinmux = <0x211>, <0x222>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-grp1 {
> +			pinmux = <0x2d43>, <0x2d33>;
> +		};
> +	};
> +
> +	i2c4_gpio_pins: i2c4-gpio-pins {
> +		i2c4-gpio-grp0 {
> +			pinmux = <0x210>, <0x220>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-gpio-grp1 {
> +			pinmux = <0x2d40>, <0x2d30>;
> +		};
> +	};
> +};
> +
> +&i2c0 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;

#address-cells and size-cells should be common dts to avoid set it in
board file.

Other i2c2\i2c4 have not it. I suppose you can remove it here.

Frank

> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c0_pins>;
> +	pinctrl-1 = <&i2c0_gpio_pins>;
> +	status = "okay";
> +
> +	pcal6524: gpio-expander at 22 {
> +		compatible = "nxp,pcal6524";
> +		reg = <0x22>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c2_pins>;
> +	pinctrl-1 = <&i2c2_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c4 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c4_pins>;
> +	pinctrl-1 = <&i2c4_gpio_pins>;
> +	status = "okay";
> +};
> --
> 2.45.2
>


From qperret at google.com  Fri Dec  6 09:13:29 2024
From: qperret at google.com (Quentin Perret)
Date: Fri, 6 Dec 2024 17:13:29 +0000
Subject: [PATCH v4 05/14] KVM: arm64: Initialize feature id registers for
 protected VMs
In-Reply-To: <20241202154742.3611749-6-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-6-tabba@google.com>
Message-ID: <Z1MwuSh6jc94cem0@google.com>

On Monday 02 Dec 2024 at 15:47:32 (+0000), Fuad Tabba wrote:
> diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> index 59fb2f056177..1261da6a2861 100644
> --- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> @@ -204,8 +204,7 @@ static u64 get_pvm_id_aa64mmfr2(const struct kvm_vcpu *vcpu)
>  	return id_aa64mmfr2_el1_sys_val & PVM_ID_AA64MMFR2_ALLOW;
>  }
>  
> -/* Read a sanitized cpufeature ID register by its encoding */
> -u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> +static u64 pvm_calc_id_reg(const struct kvm_vcpu *vcpu, u32 id)
>  {
>  	switch (id) {
>  	case SYS_ID_AA64PFR0_EL1:
> @@ -240,10 +239,25 @@ u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
>  	}
>  }
>  
> +/* Read a sanitized cpufeature ID register by its encoding */
> +u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> +{
> +	return pvm_calc_id_reg(vcpu, id);
> +}

That wrapper doesn't look particularly useful, perhaps we could drop it?


From arnaud.pouliquen at foss.st.com  Fri Dec  6 09:17:59 2024
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Fri, 6 Dec 2024 18:17:59 +0100
Subject: [PATCH] ARM: dts: stm32: Fix IPCC EXTI declaration on stm32mp151
Message-ID: <20241206171759.135342-1-arnaud.pouliquen@foss.st.com>

The GIC IRQ type used for IPCC RX should be IRQ_TYPE_LEVEL_HIGH.
Replacing the interrupt with the EXTI event changes the type to
the numeric value 1, meaning IRQ_TYPE_EDGE_RISING.

The issue is that EXTI event 61 is a direct event.The IRQ type of
direct events is not used by EXTI and is propagated to the parent
IRQ controller of EXTI, the GIC.

Align the IRQ type to the value expected by the GIC by replacing
the second parameter "1" with IRQ_TYPE_LEVEL_HIGH.

Fixes: 7d9802bb0e34 ("ARM: dts: stm32: remove the IPCC "wakeup" IRQ on stm32mp151")
Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp151.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/st/stm32mp151.dtsi b/arch/arm/boot/dts/st/stm32mp151.dtsi
index b28dc90926bd..e7e3ce8066ec 100644
--- a/arch/arm/boot/dts/st/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp151.dtsi
@@ -129,7 +129,7 @@ ipcc: mailbox at 4c001000 {
 			reg = <0x4c001000 0x400>;
 			st,proc-id = <0>;
 			interrupts-extended =
-				<&exti 61 1>,
+				<&exti 61 IRQ_TYPE_LEVEL_HIGH>,
 				<&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "rx", "tx";
 			clocks = <&rcc IPCC>;
-- 
2.25.1



From towinchenmi at gmail.com  Fri Dec  6 09:24:32 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sat,  7 Dec 2024 01:24:32 +0800
Subject: [PATCH 0/3] Apple DWI backlight driver
Message-ID: <20241206172735.4310-1-towinchenmi@gmail.com>

Apple SoCs come with a 2-wire interface named DWI. On some iPhones, iPads
and iPod touches 1-2 backlight controllers are attached via this interface.
Though, to software using this interface, there is effectively only one
controller to worry about since the registers changes the brightness
setting on all controllers at the same time. This series adds a backlight
driver for backlight controllers connected this way.

Nick Chan
---
Nick Chan (3):
  dt-bindings: leds: backlight: apple,dwi-bl: Add bindings for Apple DWI
    backlight
  backlight: dwi_bl: Add Apple DWI backlight driver
  MAINTAINERS: Add entries for Apple DWI backlight controller

 .../bindings/leds/backlight/apple,dwi-bl.yaml |  55 ++++++++
 MAINTAINERS                                   |   2 +
 drivers/video/backlight/Kconfig               |  12 ++
 drivers/video/backlight/Makefile              |   1 +
 drivers/video/backlight/dwi_bl.c              | 123 ++++++++++++++++++
 5 files changed, 193 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
 create mode 100644 drivers/video/backlight/dwi_bl.c


base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
-- 
2.47.1



From towinchenmi at gmail.com  Fri Dec  6 09:24:33 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sat,  7 Dec 2024 01:24:33 +0800
Subject: [PATCH 1/3] dt-bindings: leds: backlight: apple,dwi-bl: Add bindings for Apple DWI backlight
In-Reply-To: <20241206172735.4310-1-towinchenmi@gmail.com>
References: <20241206172735.4310-1-towinchenmi@gmail.com>
Message-ID: <20241206172735.4310-2-towinchenmi@gmail.com>

Add the device tree bindings for backlight controllers attached via Apple
DWI 2-wire interface.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../bindings/leds/backlight/apple,dwi-bl.yaml | 55 +++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
new file mode 100644
index 000000000000..fa3789b0b043
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/apple,dwi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple DWI 2-Wire Interface Backlight Controller
+
+maintainers:
+  - Nick Chan <towinchenmi at gmail.com>
+
+description: |
+  Apple SoCs contain a 2-wire interface called DWI. On some Apple iPhones,
+  iPads and iPod touches with a LCD display, 1-2 backlight controllers
+  are connected via DWI. Interfacing with DWI controls all backlight
+  controllers at the same time. As such, the backlight controllers are
+  treated as a single controller regardless of the underlying
+  configuration.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,s5l8960x-dwi-bl
+          - apple,t7000-dwi-bl
+          - apple,s8000-dwi-bl
+          - apple,t8010-dwi-bl
+          - apple,t8015-dwi-bl
+      - const: apple,dwi-bl
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      dwi_bl: backlight at 20e200010 {
+        compatible = "apple,s5l8960x-dwi-bl", "apple,dwi-bl";
+        reg = <0x2 0x0e200010 0 8>;
+        power-domains = <&ps_dwi>;
+      };
+    };
-- 
2.47.1



From towinchenmi at gmail.com  Fri Dec  6 09:24:34 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sat,  7 Dec 2024 01:24:34 +0800
Subject: [PATCH 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <20241206172735.4310-1-towinchenmi@gmail.com>
References: <20241206172735.4310-1-towinchenmi@gmail.com>
Message-ID: <20241206172735.4310-3-towinchenmi@gmail.com>

Add driver for backlight controllers attached via Apple DWI 2-wire
interface, which is found on some Apple iPhones, iPads and iPod touches
with a LCD display.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/video/backlight/Kconfig  |  12 +++
 drivers/video/backlight/Makefile |   1 +
 drivers/video/backlight/dwi_bl.c | 123 +++++++++++++++++++++++++++++++
 3 files changed, 136 insertions(+)
 create mode 100644 drivers/video/backlight/dwi_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 3614a5d29c71..e64cc3d51ac5 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -166,6 +166,18 @@ config BACKLIGHT_EP93XX
 	  To compile this driver as a module, choose M here: the module will
 	  be called ep93xx_bl.
 
+config BACKLIGHT_APPLE_DWI
+	tristate "Apple DWI 2-Wire Interface Backlight Driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	default y
+	help
+          Say Y to enable the backlight driver for backlight controllers
+          attached via the Apple DWI 2-wire interface which is found in some
+          Apple iPhones, iPads and iPod touches.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called dwi_bl.
+
 config BACKLIGHT_IPAQ_MICRO
 	tristate "iPAQ microcontroller backlight driver"
 	depends on MFD_IPAQ_MICRO
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 8fc98f760a8a..0a569d7f0210 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_BACKLIGHT_BD6107)		+= bd6107.o
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE)	+= backlight.o
 obj-$(CONFIG_BACKLIGHT_DA903X)		+= da903x_bl.o
 obj-$(CONFIG_BACKLIGHT_DA9052)		+= da9052_bl.o
+obj-$(CONFIG_BACKLIGHT_APPLE_DWI)	+= dwi_bl.o
 obj-$(CONFIG_BACKLIGHT_EP93XX)		+= ep93xx_bl.o
 obj-$(CONFIG_BACKLIGHT_GPIO)		+= gpio_backlight.o
 obj-$(CONFIG_BACKLIGHT_HP680)		+= hp680_bl.o
diff --git a/drivers/video/backlight/dwi_bl.c b/drivers/video/backlight/dwi_bl.c
new file mode 100644
index 000000000000..6dd7edf661fd
--- /dev/null
+++ b/drivers/video/backlight/dwi_bl.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Driver for backlight controllers attached via Apple DWI 2-wire interface
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/backlight.h>
+
+#define DWI_BL_CTL			0x0
+#define DWI_BL_CTL_SEND1		BIT(0)
+#define DWI_BL_CTL_SEND2		BIT(4)
+#define DWI_BL_CTL_SEND3		BIT(5)
+#define DWI_BL_CTL_LE_DATA		BIT(6)
+/* Only used on Apple A9 and later */
+#define DWI_BL_CTL_SEND4		BIT(12)
+
+#define DWI_BL_CMD			0x4
+#define DWI_BL_CMD_TYPE			GENMASK(31, 28)
+#define DWI_BL_CMD_TYPE_SET_BRIGHTNESS	0xa
+#define DWI_BL_CMD_DATA			GENMASK(10, 0)
+
+#define DWI_BL_CTL_SEND			(DWI_BL_CTL_SEND1 | \
+					 DWI_BL_CTL_SEND2 | \
+					 DWI_BL_CTL_SEND3 | \
+					 DWI_BL_CTL_LE_DATA | \
+					 DWI_BL_CTL_SEND4)
+
+#define DWI_BL_MAX_BRIGHTNESS		2047
+
+struct apple_dwi_bl {
+	void __iomem *base;
+};
+
+static int dwi_bl_update_status(struct backlight_device *bl)
+{
+	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
+
+	int brightness = backlight_get_brightness(bl);
+
+	u32 cmd = 0;
+
+	cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
+	cmd |= FIELD_PREP(DWI_BL_CMD_TYPE, DWI_BL_CMD_TYPE_SET_BRIGHTNESS);
+
+	writel(cmd, dwi_bl->base + DWI_BL_CMD);
+	writel(DWI_BL_CTL_SEND, dwi_bl->base + DWI_BL_CTL);
+
+	return 0;
+}
+
+static int dwi_bl_get_brightness(struct backlight_device *bl)
+{
+	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
+
+	u32 cmd = readl(dwi_bl->base + DWI_BL_CMD);
+
+	return FIELD_GET(DWI_BL_CMD_DATA, cmd);
+}
+
+static const struct backlight_ops dwi_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = dwi_bl_get_brightness,
+	.update_status	= dwi_bl_update_status
+};
+
+static int dwi_bl_probe(struct platform_device *dev)
+{
+	struct apple_dwi_bl *dwi_bl;
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct resource *res;
+
+	dwi_bl = devm_kzalloc(&dev->dev, sizeof(struct apple_dwi_bl), GFP_KERNEL);
+	if (!dwi_bl)
+		return -ENOMEM;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+
+	dwi_bl->base = devm_ioremap_resource(&dev->dev, res);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = DWI_BL_MAX_BRIGHTNESS;
+
+	bl = devm_backlight_device_register(&dev->dev, dev->name, &dev->dev,
+					dwi_bl, &dwi_bl_ops, &props);
+
+	if (IS_ERR(bl))
+		return PTR_ERR(bl);
+
+	platform_set_drvdata(dev, dwi_bl);
+
+	bl->props.brightness = dwi_bl_get_brightness(bl);
+
+	return 0;
+}
+
+static const struct of_device_id dwi_bl_of_match[] = {
+	{ .compatible = "apple,dwi-bl" },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, dwi_bl_of_match);
+
+static struct platform_driver dwi_bl_driver = {
+	.driver		= {
+		.name	= "dwi-bl",
+		.of_match_table = dwi_bl_of_match
+	},
+	.probe		= dwi_bl_probe,
+};
+
+module_platform_driver(dwi_bl_driver);
+
+MODULE_DESCRIPTION("Apple DWI Backlight Driver");
+MODULE_AUTHOR("Nick Chan <towinchenmi at gmail.com>");
+MODULE_LICENSE("Dual MIT/GPL");
-- 
2.47.1



From towinchenmi at gmail.com  Fri Dec  6 09:24:35 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sat,  7 Dec 2024 01:24:35 +0800
Subject: [PATCH 3/3] MAINTAINERS: Add entries for Apple DWI backlight controller
In-Reply-To: <20241206172735.4310-1-towinchenmi@gmail.com>
References: <20241206172735.4310-1-towinchenmi@gmail.com>
Message-ID: <20241206172735.4310-4-towinchenmi@gmail.com>

Add MAINTAINERS entries for the driver.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..36de76bc6fd4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2204,6 +2204,7 @@ F:	Documentation/devicetree/bindings/pci/apple,pcie.yaml
 F:	Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
 F:	Documentation/devicetree/bindings/power/apple*
 F:	Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
+F:	Documentation/devicetree/bindings/video/backlight/apple,dwi-bl.yaml
 F:	Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
 F:	arch/arm64/boot/dts/apple/
 F:	drivers/bluetooth/hci_bcm4377.c
@@ -2221,6 +2222,7 @@ F:	drivers/nvmem/apple-efuses.c
 F:	drivers/pinctrl/pinctrl-apple-gpio.c
 F:	drivers/pwm/pwm-apple.c
 F:	drivers/soc/apple/*
+F:	drivers/video/backlight/dwi_bl.c
 F:	drivers/watchdog/apple_wdt.c
 F:	include/dt-bindings/interrupt-controller/apple-aic.h
 F:	include/dt-bindings/pinctrl/apple.h
-- 
2.47.1



From qperret at google.com  Fri Dec  6 09:31:57 2024
From: qperret at google.com (Quentin Perret)
Date: Fri, 6 Dec 2024 17:31:57 +0000
Subject: [PATCH v4 06/14] KVM: arm64: Set protected VM traps based on its
 view of feature registers
In-Reply-To: <20241202154742.3611749-7-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-7-tabba@google.com>
Message-ID: <Z1M1DYbvuqAEU5c-@google.com>

On Monday 02 Dec 2024 at 15:47:33 (+0000), Fuad Tabba wrote:
>  static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
>  {
> -	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
> -	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
> -	const u64 id_aa64mmfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
> +	struct kvm *kvm = vcpu->kvm;
>  	u64 val = vcpu->arch.hcr_el2;
>  
>  	/* No support for AArch32. */
> @@ -70,25 +68,20 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
>  	 */
>  	val |= HCR_TACR | HCR_TIDCP | HCR_TID3 | HCR_TID1;
>  
> -	/* Trap RAS unless all current versions are supported */
> -	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0) <
> -	    ID_AA64PFR0_EL1_RAS_V1P1) {
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {

I'm admittedly getting a bit lost in the kvm_has_feat() macro maze, but
should this be:

	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1))

to replicate the existing check?

>  		val |= HCR_TERR | HCR_TEA;
>  		val &= ~(HCR_FIEN);
>  	}


From heiko at sntech.de  Fri Dec  6 09:36:49 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 06 Dec 2024 18:36:49 +0100
Subject: [PATCH 1/2] phy: phy-rockchip-samsung-hdptx: annotate regmap
 register-callback
In-Reply-To: <e6172204-2f3f-4a9c-892c-be85d19ad031@collabora.com>
References: <20241206103401.1780416-1-heiko@sntech.de>
 <20241206103401.1780416-2-heiko@sntech.de>
 <e6172204-2f3f-4a9c-892c-be85d19ad031@collabora.com>
Message-ID: <2287157.Dhsi8hcfAM@diego>

Am Freitag, 6. Dezember 2024, 12:18:56 CET schrieb Cristian Ciocaltea:
> On 12/6/24 12:34 PM, Heiko Stuebner wrote:
> > From: Heiko Stuebner <heiko.stuebner at cherry.de>
> > 
> > The variant of the driver in the vendor-tree contained those handy
> > comments in the regmap register callback. Having the different ranges
> > describe what they are looks helpful.
> > 
> > Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
> > ---
> >  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 +++++++-------
> >  1 file changed, 7 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> > index 4ced1479e2dc..c5c64c209e96 100644
> > --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> > +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> > @@ -766,13 +766,13 @@ static struct tx_drv_ctrl tx_drv_ctrl_hbr2[4][4] = {
> >  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:
> > +	case 0x0000 ... 0x029c: /* CMN Register */
> > +	case 0x0400 ... 0x04a4: /* Sideband Register */
> > +	case 0x0800 ... 0x08a4: /* Lane Top Register */
> > +	case 0x0c00 ... 0x0cb4: /* Lane 0 Register */
> > +	case 0x1000 ... 0x10b4: /* Lane 1 Register */
> > +	case 0x1400 ... 0x14b4: /* Lane 2 Register */
> > +	case 0x1800 ... 0x18b4: /* Lane 3 Register */
> >  		return true;
> >  	}
> >  
> 
> Nice finding!  The HDMI variant of the driver which I used as an
> implementation reference (i.e. phy-rockchip-samsung-hdptx-hdmi.c)
> doesn't provide these comments.

yep, those comments were in the displayport variant of the phy-driver ;-) .
I don't really understand why the vendor tree contains 2 separate drivers
written by two different people, but at least it looks like we're getting
one driver in mainline, thanks to Damon's work :-)





From broonie at kernel.org  Fri Dec  6 09:43:42 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 6 Dec 2024 17:43:42 +0000
Subject: [PATCH v4 06/14] KVM: arm64: Set protected VM traps based on its
 view of feature registers
In-Reply-To: <Z1M1DYbvuqAEU5c-@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-7-tabba@google.com>
 <Z1M1DYbvuqAEU5c-@google.com>
Message-ID: <70992791-af72-43ed-88cc-1bb5a8acaf9a@sirena.org.uk>

On Fri, Dec 06, 2024 at 05:31:57PM +0000, Quentin Perret wrote:
> On Monday 02 Dec 2024 at 15:47:33 (+0000), Fuad Tabba wrote:

> > -	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0) <
> > -	    ID_AA64PFR0_EL1_RAS_V1P1) {
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {

> I'm admittedly getting a bit lost in the kvm_has_feat() macro maze, but
> should this be:

> 	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1))

> to replicate the existing check?

kvm_has_feat() checks for a value <= the supplied constant while the
existing check is just < and the values for the field are:

UnsignedEnum	31:28	RAS
	0b0000	NI
	0b0001	IMP
	0b0010	V1P1
EndEnum

so they're both checking for the same thing.
-------------- 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/20241206/8fddfc7d/attachment.sig>

From lkp at intel.com  Fri Dec  6 09:44:51 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 7 Dec 2024 01:44:51 +0800
Subject: [PATCH 1/1] dt-bindings: PCI: mobiveil: convert
 mobiveil-pcie.txt to yaml format
In-Reply-To: <20241205201423.3430862-1-Frank.Li@nxp.com>
References: <20241205201423.3430862-1-Frank.Li@nxp.com>
Message-ID: <202412070127.BkBJhnZ4-lkp@intel.com>

Hi Frank,

kernel test robot noticed the following build warnings:

[auto build test WARNING on pci/next]
[also build test WARNING on pci/for-linus linus/master v6.13-rc1 next-20241206]
[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/Frank-Li/dt-bindings-PCI-mobiveil-convert-mobiveil-pcie-txt-to-yaml-format/20241206-041830
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link:    https://lore.kernel.org/r/20241205201423.3430862-1-Frank.Li%40nxp.com
patch subject: [PATCH 1/1] dt-bindings: PCI: mobiveil: convert mobiveil-pcie.txt to yaml format
reproduce: (https://download.01.org/0day-ci/archive/20241207/202412070127.BkBJhnZ4-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/202412070127.BkBJhnZ4-lkp at intel.com/

All warnings (new ones prefixed by >>):

   Warning: Documentation/devicetree/bindings/regulator/siliconmitus,sm5703-regulator.yaml references a file that doesn't exist: Documentation/devicetree/bindings/mfd/siliconmitus,sm5703.yaml
   Warning: Documentation/hwmon/g762.rst references a file that doesn't exist: Documentation/devicetree/bindings/hwmon/g762.txt
   Warning: Documentation/hwmon/isl28022.rst references a file that doesn't exist: Documentation/devicetree/bindings/hwmon/isl,isl28022.yaml
   Warning: Documentation/translations/ja_JP/SubmittingPatches references a file that doesn't exist: linux-2.6.12-vanilla/Documentation/dontdiff
>> Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
>> Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
   Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
   Warning: lib/Kconfig.debug references a file that doesn't exist: Documentation/dev-tools/fault-injection/fault-injection.rst
   Using alabaster theme

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


From David.Laight at ACULAB.COM  Fri Dec  6 09:53:24 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 17:53:24 +0000
Subject: [PATCH net] Fix clamp() of ip_vs_conn_tab on small memory
 systems.
In-Reply-To: <c0a2ee53-f6ff-f4d4-e9ab-6a3bf850bec5@ssi.bg>
References: <33893212b1cc4a418cec09aeeed0a9fc@AcuMS.aculab.com>
 <5ec10e7c-d050-dab8-1f1b-d0ca2d922eef@ssi.bg>
 <2a91ee407ed64d24b82e5fc665971add@AcuMS.aculab.com>
 <c0a2ee53-f6ff-f4d4-e9ab-6a3bf850bec5@ssi.bg>
Message-ID: <494a4dc2ba2041dfb9f45d86e972b953@AcuMS.aculab.com>

From: Julian Anastasov
> Sent: 06 December 2024 16:23
...
> 	I'm not sure how much memory we can see in small system,
> IMHO, problem should not be possible in practice:
> 
> - nobody expects 0 from totalram_pages() in the code
> 
> - order_base_2(sizeof(struct ip_vs_conn)) is probably 8 on 32-bit

It is 0x120 bytes on 64bit, so 8 could well be right.

> - PAGE_SHIFT: 12 (for 4KB) or more?
> 
> 	So, if totalram_pages() returns below 128 pages (4KB each)
> max_avail will be below 19 (7 + 12), then 19 is reduced with 2 + 1
> and becomes 16, finally with 8 (from the 2nd order_base_2) to reach
> 16-8=8. You need a system with less than 512KB (19 bits) to trigger
> problem in clamp() that will lead to max below 8.

Which pretty much won't happen, I think my (dead) sun3 has more than that.

> Further, without
> checks, for ip_vs_conn_tab_bits=1 we need totalram_pages() to return 0
> pages.
> 
> > > > Detected by compile time checks added to clamp(), specifically:
> > > > minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
> > >
> > > 	Existing or new check? Does it happen that max_avail
> > > is a constant, so that a compile check triggers?
> >
> > Is all stems from order_base_2(totalram_pages()).
> > order_base_2(n) is 'n > 1 ? ilog2(n - 1) + 1 : 0'.
> > And the compiler generates two copies of the code that follows
> > for the 'constant zero' and ilog2() values.
> > And the 'zero' case compiles clamp(20, 8, 0) which is errored.
> > Note that it is only executed if totalram_pages() is zero,
> > but it is always compiled 'just in case'.
> 
> 	I'm confused with these compiler issues,

The compiler is just doing its job.
Consider this expression:
	(x >= 1 ? 2 * x : 1) - 1
It is likely to get converted to:
	(x >= 1 ? 2 * x - 1 : 0)
to avoid the subtract when x < 1.

The same thing is happening here.
order_base_2() has a (condition ? fn() : 0) in it.
All the +/- constants get moved inside, on 64bit that is +12 -2 -1 -9 = 0.
Then the clamp() with constants gets moved inside:
	(condition ? clamp(27, 8, fn() + 0) : clamp(27, 8, 0 + 0))
Now, at runtime, we know that 'condition' is true and (fn() >= 8)
so the first clamp() is valid and the second one never used.
But this isn't known by the compiler and clamp() detects the invalid
call and generates a warning.

> if you
> think we should go with the patch just decide if it is a
> net or net-next material. Your change is safer for bad
> max_avail values but I don't expect to see problem while
> running without the change, except the building bugs.
> 
> 	Also, please use nf/nf-next tag to avoid any
> confusion with upstreaming...

I've copied Andrew M - he's taken the minmax.h change into his mm tree.
This is one of the build breakages.

It probably only needs to go into next for now (via some route).
But I can image the minmax.h changes getting backported a bit.

	David

> 
> Regards
> 
> --
> Julian Anastasov <ja at ssi.bg>

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From cristian.ciocaltea at collabora.com  Fri Dec  6 09:54:50 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Fri, 6 Dec 2024 19:54:50 +0200
Subject: [PATCH 1/2] phy: phy-rockchip-samsung-hdptx: annotate regmap
 register-callback
In-Reply-To: <2287157.Dhsi8hcfAM@diego>
References: <20241206103401.1780416-1-heiko@sntech.de>
 <20241206103401.1780416-2-heiko@sntech.de>
 <e6172204-2f3f-4a9c-892c-be85d19ad031@collabora.com>
 <2287157.Dhsi8hcfAM@diego>
Message-ID: <7081d3ec-1a7f-48d9-a20d-7518445ed5bd@collabora.com>

On 12/6/24 7:36 PM, Heiko St?bner wrote:
> Am Freitag, 6. Dezember 2024, 12:18:56 CET schrieb Cristian Ciocaltea:
>> On 12/6/24 12:34 PM, Heiko Stuebner wrote:
>>> From: Heiko Stuebner <heiko.stuebner at cherry.de>
>>>
>>> The variant of the driver in the vendor-tree contained those handy
>>> comments in the regmap register callback. Having the different ranges
>>> describe what they are looks helpful.
>>>
>>> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
>>> ---
>>>  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 +++++++-------
>>>  1 file changed, 7 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>>> index 4ced1479e2dc..c5c64c209e96 100644
>>> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>>> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>>> @@ -766,13 +766,13 @@ static struct tx_drv_ctrl tx_drv_ctrl_hbr2[4][4] = {
>>>  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:
>>> +	case 0x0000 ... 0x029c: /* CMN Register */
>>> +	case 0x0400 ... 0x04a4: /* Sideband Register */
>>> +	case 0x0800 ... 0x08a4: /* Lane Top Register */
>>> +	case 0x0c00 ... 0x0cb4: /* Lane 0 Register */
>>> +	case 0x1000 ... 0x10b4: /* Lane 1 Register */
>>> +	case 0x1400 ... 0x14b4: /* Lane 2 Register */
>>> +	case 0x1800 ... 0x18b4: /* Lane 3 Register */
>>>  		return true;
>>>  	}
>>>  
>>
>> Nice finding!  The HDMI variant of the driver which I used as an
>> implementation reference (i.e. phy-rockchip-samsung-hdptx-hdmi.c)
>> doesn't provide these comments.
> 
> yep, those comments were in the displayport variant of the phy-driver ;-) .
> I don't really understand why the vendor tree contains 2 separate drivers

Yeah, I asked myself the same question a while ago - I'd assume the
(initial) development happened in parallel, but the final sync/merge was
never done.

> written by two different people, but at least it looks like we're getting
> one driver in mainline, thanks to Damon's work :-)

Indeed, we're eventually getting there.. :-)


From maz at kernel.org  Fri Dec  6 10:22:40 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 06 Dec 2024 18:22:40 +0000
Subject: [PATCH v4 06/14] KVM: arm64: Set protected VM traps based on its view of feature registers
In-Reply-To: <70992791-af72-43ed-88cc-1bb5a8acaf9a@sirena.org.uk>
References: <20241202154742.3611749-1-tabba@google.com>
	<20241202154742.3611749-7-tabba@google.com>
	<Z1M1DYbvuqAEU5c-@google.com>
	<70992791-af72-43ed-88cc-1bb5a8acaf9a@sirena.org.uk>
Message-ID: <868qssu0wf.wl-maz@kernel.org>

On Fri, 06 Dec 2024 17:43:42 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> On Fri, Dec 06, 2024 at 05:31:57PM +0000, Quentin Perret wrote:
> > On Monday 02 Dec 2024 at 15:47:33 (+0000), Fuad Tabba wrote:
> 
> > > -	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0) <
> > > -	    ID_AA64PFR0_EL1_RAS_V1P1) {
> > > +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
> 
> > I'm admittedly getting a bit lost in the kvm_has_feat() macro maze, but
> > should this be:
> 
> > 	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1))
> 
> > to replicate the existing check?
> 
> kvm_has_feat() checks for a value <= the supplied constant while the

Not quite:

#define kvm_has_feat(kvm, id, fld, limit)				\
	kvm_cmp_feat(kvm, id, fld, >=, limit)

> existing check is just < and the values for the field are:
> 
> UnsignedEnum	31:28	RAS
> 	0b0000	NI
> 	0b0001	IMP
> 	0b0010	V1P1
> EndEnum
> 
> so they're both checking for the same thing.

Evidently not. The original code is checking for RASv1p1, while the
change turns that into a check for the original RAS spec.

	M.

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


From robh at kernel.org  Fri Dec  6 10:25:26 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 06 Dec 2024 12:25:26 -0600
Subject: [PATCH 1/3] dt-bindings: leds: backlight: apple,dwi-bl: Add
 bindings for Apple DWI backlight
In-Reply-To: <20241206172735.4310-2-towinchenmi@gmail.com>
References: <20241206172735.4310-1-towinchenmi@gmail.com>
 <20241206172735.4310-2-towinchenmi@gmail.com>
Message-ID: <173350952667.3933863.13037602591337209524.robh@kernel.org>


On Sat, 07 Dec 2024 01:24:33 +0800, Nick Chan wrote:
> Add the device tree bindings for backlight controllers attached via Apple
> DWI 2-wire interface.
> 
> Signed-off-by: Nick Chan <towinchenmi at gmail.com>
> ---
>  .../bindings/leds/backlight/apple,dwi-bl.yaml | 55 +++++++++++++++++++
>  1 file changed, 55 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml: $id: Cannot determine base path from $id, relative path/filename doesn't match actual path or filename
 	 $id: http://devicetree.org/schemas/leds/backlight/apple,dwi.yaml
 	file: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241206172735.4310-2-towinchenmi 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 catalin.marinas at arm.com  Fri Dec  6 10:27:33 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 6 Dec 2024 18:27:33 +0000
Subject: [GIT PULL] arm64 fixes for 6.13-rc2
Message-ID: <Z1NCFeR4iBm5Bxqg@arm.com>

Hi Linus,

Please pull the arm64 fixes below. Nothing major, some left-overs from
the recent merging window (MTE, coco) and some newly found issues like
the ptrace() ones. More details in the tag. Thanks.

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

for you to fetch changes up to d60624f72d15862a96965b945f6ddfee9a1359e7:

  arm64: ptrace: fix partial SETREGSET for NT_ARM_GCS (2024-12-05 18:05:51 +0000)

----------------------------------------------------------------
arm64 fixes for 6.13-rc2:

- MTE/hugetlbfs:

  - Set VM_MTE_ALLOWED in the arch code and remove it from the core code
    for hugetlbfs mappings

  - Fix copy_highpage() warning when the source is a huge page but not
    MTE tagged, taking the wrong small page path

- drivers/virt/coco:

  - Add the pKVM and Arm CCA drivers under the arm64 maintainership

  - Fix the pkvm driver to fall back to ioremap() (and warn) if the
    MMIO_GUARD hypercall fails

  - Keep the Arm CCA driver default 'n' rather than 'm'

- A series of fixes for the arm64 ptrace() implementation, potentially
  leading to the kernel consuming uninitialised stack variables when
  PTRACE_SETREGSET is invoked with a length of 0

- Fix zone_dma_limit calculation when RAM starts below 4GB and ZONE_DMA
  is capped to this limit

- Fix early boot warning with CONFIG_DEBUG_VIRTUAL=y triggered by a call
  to page_to_phys() (from patch_map()) which checks pfn_valid() before
  vmemmap has been set up

- Do not clobber bits 15:8 of the ASID used for TTBR1_EL1 and TLBI ops
  when the kernel assumes 8-bit ASIDs but running under a hypervisor on
  a system that implements 16-bit ASIDs (found running Linux under
  Parallels on Apple M4)

- ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A as it is
  using the same SMMU PMCG as HIP09 and suffers from the same errata

- Add GCS to cpucap_is_possible(), missed in the recent merge

----------------------------------------------------------------
Catalin Marinas (2):
      arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs
      arm64: mte: Fix copy_highpage() warning on hugetlb folios

Mark Rutland (5):
      arm64: patching: avoid early page_to_phys()
      arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL
      arm64: ptrace: fix partial SETREGSET for NT_ARM_FPMR
      arm64: ptrace: fix partial SETREGSET for NT_ARM_POE
      arm64: ptrace: fix partial SETREGSET for NT_ARM_GCS

Qinxin Xia (1):
      ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A

Robin Murphy (1):
      arm64: cpufeature: Add GCS to cpucap_is_possible()

Suzuki K Poulose (1):
      coco: virt: arm64: Do not enable cca guest driver by default

Will Deacon (2):
      drivers/virt: pkvm: Don't fail ioremap() call if MMIO_GUARD fails
      MAINTAINERS: Add CCA and pKVM CoCO guest support to the ARM64 entry

Yang Shi (2):
      arm64: mte: set VM_MTE_ALLOWED for hugetlbfs at correct place
      arm64: mm: Fix zone_dma_limit calculation

 Documentation/arch/arm64/silicon-errata.rst   |  5 ++--
 MAINTAINERS                                   |  2 ++
 arch/arm64/include/asm/cpucaps.h              |  2 ++
 arch/arm64/include/asm/cpufeature.h           |  3 +--
 arch/arm64/include/asm/mman.h                 |  3 ++-
 arch/arm64/kernel/patching.c                  | 21 +++++++---------
 arch/arm64/kernel/ptrace.c                    | 36 +++++++++++++++++++++------
 arch/arm64/mm/context.c                       |  4 +--
 arch/arm64/mm/copypage.c                      |  8 +++---
 arch/arm64/mm/init.c                          | 17 ++++++-------
 drivers/acpi/arm64/iort.c                     |  2 ++
 drivers/virt/coco/arm-cca-guest/Kconfig       |  1 -
 drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c |  6 +----
 fs/hugetlbfs/inode.c                          |  2 +-
 14 files changed, 67 insertions(+), 45 deletions(-)

-- 
Catalin


From mailhol.vincent at wanadoo.fr  Thu Dec  5 07:52:20 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 00:52:20 +0900
Subject: [PATCH 05/10] minmax: simplify __clamp_once() by using is_const_false()
In-Reply-To: <8b8262389bd6484586007d749132346f@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-5-4e4cbaecc216@wanadoo.fr> <8b8262389bd6484586007d749132346f@AcuMS.aculab.com>
Message-ID: <CAMZ6RqJPvbSr5i8N4Dm=2N6D8uSzefCM3TyK8HBNNNrybo5f2Q@mail.gmail.com>

On Thu. 5 Dec. 2024 at 03:54, David Laight <David.Laight at aculab.com> wrote:
> From: Vincent Mailhol
> > Sent: 02 December 2024 17:33
> >
> > In __clamp_once(),
> >
> >   __builtin_choose_expr(__is_constexpr((lo) > (hi)), (lo) <= (hi), true)
> >
> > is equivalent to:
> >
> >   !is_const_false((lo) <= (hi))
> >
> > Apply is_const_false() to simplify __clamp_once().
>
> There is already a patch 'for next' that changes it use BUILD_BUG_ON_MSG()
> and statically_true().

Found it!

  https://lore.kernel.org/all/34d53778977747f19cce2abb287bb3e6 at AcuMS.aculab.com/

I think the easiest would be for me to cherry pick this patch. So that
regardless which series is merged first, no conflict will occur, the
patch will just be skipped the second time it is encountered.

Does this work for you?


Yours sincerely,
Vincent Mailhol


From vincent.mailhol at gmail.com  Fri Dec  6 10:30:57 2024
From: vincent.mailhol at gmail.com (Vincent Mailhol)
Date: Sat, 7 Dec 2024 03:30:57 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
Message-ID: <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>

Grrr, I just realized that my emails are bouncing? Didn't happen
before, I guess this is because my smtp server is unhappy with the
many people in CC.

Resending using another address (and, while at it, redacted two
messages to combine them in one and added more details).

My deep apologies for that, really sorry. Also, maybe the bouncing
messages will finally find their way out? In that case, please just
ignore them, and sorry for the noise.

On Fri. 6 Dec. 2024 at 15:14, Linus Torvalds
<torvalds at linux-foundation.org> wrote:
> On Thu, 5 Dec 2024 at 18:26, David Laight <David.Laight at aculab.com> wrote:
> >
> > From: Vincent Mailhol
> > > ACK. Would adding a suggested--by Linus tag solve your concern?
>
> I'm genberally the one person who doesn't need any more credit ;)
>
> > I actually suspect the first patches to change __is_constexpr() to
> > use _Generic were from myself.
>
> Yes. And David was also I think the one who suggested something else
> than "!!" originally too.

Ack. Then, I will add a suggested-by tag to credit David!

> I may have liked "!!" for being very idiomatic and traditional C, but
> there were those pesky compilers that warn about "integer in bool
> context" or whatever the annoying warning was when then doing the
> "multiply by zero" to turn a constant expression into a constant zero
> expression.
>
> So that
>
>   #define is_const(x) __is_const_zero(0 * (x))
>
> causes issues when 'x' is not an integer expression (think
> "is_const(NULL)" or "is_const(1 == 2)".

But 1 == 2 already has an integer type as proven by:

  #define is_int(x) _Generic(x, int: 1, default: 0)
  static_assert(is_int(1 == 2));

And regardless, __is_const_zero() performs a (long) cast, so
__is_const_zero() works for any other scalar types. Even the u128
works because after the (0 * (x)) multiplication, you are left with
zero, preventing any loss of precision when casting to (long).

Here are some tests to prove my claims:

  https://godbolt.org/z/beGs841sz

So, it leaves us with the is_const(pointer) case. To which I would
question if we really want to support this. By definition, an
expression with a pointer type can not be an *integer* constant
expression. So one part of me tells me that it is a sane thing to
*not* support this case and throw a warning if the user feeds
is_const() with a pointer.

By the way, currently, __is_constexpr(NULL) returns false:

  https://godbolt.org/z/f5P9oP9n5

and the reason this went unnotified in the kernel is because no one is
using it that way. So instead of complicating the macro for a use case
which currently does not exist (and which goes against the definition
of an ICE in the C standard), why not say instead that this is not
supported by just leaving the constraint violation in is_const()?

> Side note: I think "(x) == 0" will make sparse unhappy when 'x' is a
> pointer, because it results that horrid "use integer zero as NULL
> without a cast" thing when the plain zero gets implicitly cast to a
> pointer. Which is a really nasty and broken C pattern and should never
> have been silent.
>
> I think David suggested using ((x)?0:0) at some point. Silly
> nonsensical and complex expression, but maybe that finally gets rid of
> all the warnings:
>
>      #define is_const(x) __is_const_zero((x)?0:0)
>
> might work regardless of the type of 'x'.

If we *really* want to go beyond the C standard and extend the meaning
of integer constant expressions in the kernel to also include constant
pointers, then what about:

  #define is_const(x) __is_const_zero((x) != (x))

As established above, comparaisons return an int, thus making this
pass all tests:

  https://godbolt.org/z/f5zrzf44h

And it is slightly more pretty than the ((x)?0:0).

(...)

Side question, Linus, what do you think about the __is_const_zero()
documentation:

  https://lore.kernel.org/all/20241203-is_constexpr-refactor-v1-2-4e4cbaecc216 at wanadoo.fr/

Do you think I am too verbose as pointed out by David? Some people
(including me and Yuri) like it that way. But if you also think this
is too much, I will make it shorter.

Thanks,


Yours sincerely,
Vincent Mailhol


From umer.uddin at mentallysanemainliners.org  Fri Dec  6 10:46:06 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 18:46:06 +0000
Subject: [PATCH v6 1/4] dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
In-Reply-To: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
References: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241206184609.2437-2-umer.uddin@mentallysanemainliners.org>

Add devicetree bindings for Samsung Galaxy S20 5G
and Samsung Galaxy S20 board.

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml         | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 168e77375..fab29f95d 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -241,6 +241,8 @@ properties:
           - enum:
               - samsung,c1s                     # Samsung Galaxy Note20 5G (SM-N981B)
               - samsung,r8s                     # Samsung Galaxy S20 FE (SM-G780F)
+              - samsung,x1s                     # Samsung Galaxy S20 5G (SM-G981B)
+              - samsung,x1slte                  # Samsung Galaxy S20 (SM-G980F)
           - const: samsung,exynos990
 
       - description: Exynos Auto v9 based boards
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Fri Dec  6 10:46:05 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 18:46:05 +0000
Subject: [PATCH v6 0/4] Add minimal Samsung Galaxy S20 Series board, SM-G981B and SM-G980F support
Message-ID: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>

Hi folks,

This series adds initial support for the Samsung Galaxy S20 Series and also
initial board support for the Samsung Galaxy S20 5G (SM-G981B)
codenamed x1s and the Samsung Galaxy S20 (SM-G980F).

The S20 Series feature a lot of similarities in their configuration
and internally Samsung named the common devicetrees in their
downstream kernel 'hubble', please note hubble excludes the
S20 FE series and Note20 series. To accommodate this, I've
now named the device tree common's matching the codenames
(x1s-common).
The device trees have been tested with dtbs_check W=1
and results in no warnings.

This initial bringup consists of:
 * pinctrl
 * gpio-keys
 * simple-framebuffer

This is enough to reach a shell in an initramfs. More platform support
will be added in the future.

Just like SM-N981B, the preferred way to boot the upstream kernel is
by using a shim bootloader, called uniLoader [1], which works around
some issues with the stock, non-replacable Samsung S-LK bootloader.
For example, the stock bootloader leaves the decon trigger control
unset, which causes the framebuffer not to refresh.

Device functionality depends on the patch series from Igor Belwon:
"Add minimal Exynos990 SoC and SM-N981B support"

[1] https://github.com/ivoszbg/uniLoader

Changes in v6:
 - Fix indentations in dts makefile

Changes in v5:
 - Fix dts makefile order

Changes in v4:
 - Rebase from krzk's kernel tree to accommodate
   for the merge of r8s
 - Rename exynos990-hubble-common.dtsi
   to exynos990-x1s-common.dtsi

Changes in v3:
 - Fix oversight in yaml
 - Decommonise memory map

Changes in v2:
 - Add Samsung Galaxy S20 into device tree bindings
 - Add support for Samsung Galaxy S20 as well as the 5G variant now
 - Fix typo in Samsung Galaxy S20 5G commit message

Kind regards,
Umer

Umer Uddin (4):
  dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B
    and SM-G980F board
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series
    boards (hubble)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G
    (x1s)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20
    (x1slte)

 .../bindings/arm/samsung/samsung-boards.yaml  |  2 +
 arch/arm64/boot/dts/exynos/Makefile           |  2 +
 .../boot/dts/exynos/exynos990-x1s-common.dtsi | 98 +++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts  | 28 ++++++
 .../boot/dts/exynos/exynos990-x1slte.dts      | 28 ++++++
 5 files changed, 158 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Fri Dec  6 10:46:07 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 18:46:07 +0000
Subject: [PATCH v6 2/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series boards (hubble)
In-Reply-To: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
References: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241206184609.2437-3-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 Series (hubble) phones.
They were launched in 2020, and are based on the Exynos 990 SoC.
The devices have multiple RAM configurations,
starting from 8GB going all the way up to 16GB for the S20 Ultra devices.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM (Any more will be mapped in device trees)
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../boot/dts/exynos/exynos990-x1s-common.dtsi | 98 +++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi

diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
new file mode 100644
index 000000000..55fa8e9e0
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 Series device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		framebuffer0: framebuffer at f1000000 {
+			compatible = "simple-framebuffer";
+			reg = <0 0xf1000000 0 (1440 * 3200 * 4)>;
+			width = <1440>;
+			height = <3200>;
+			stride = <(1440 * 4)>;
+			format = "a8r8g8b8";
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		cont_splash_mem: framebuffer at f1000000 {
+			reg = <0 0xf1000000 0 0x1194000>;
+			no-map;
+		};
+
+		abox_reserved: audio at f7fb0000 {
+			reg = <0 0xf7fb0000 0 0x2a50000>;
+			no-map;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&key_power &key_voldown &key_volup>;
+		pinctrl-names = "default";
+
+		power-key {
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpa2 4 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+
+		voldown-key {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			gpios = <&gpa0 4 GPIO_ACTIVE_LOW>;
+		};
+
+		volup-key {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&oscclk {
+	clock-frequency = <26000000>;
+};
+
+&pinctrl_alive {
+	key_power: key-power-pins {
+		samsung,pins = "gpa2-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_voldown: key-voldown-pins {
+		samsung,pins = "gpa0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_volup: key-volup-pins {
+		samsung,pins = "gpa0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Fri Dec  6 10:46:08 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 18:46:08 +0000
Subject: [PATCH v6 3/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
In-Reply-To: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
References: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241206184609.2437-4-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 5G (x1s/SM-G981B)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 12GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 12GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile          |  1 +
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts | 28 ++++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index 948a2c6cb..fe47aafcd 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -10,5 +10,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos8895-dreamlte.dtb		\
 	exynos990-c1s.dtb		\
 	exynos990-r8s.dtb               \
+	exynos990-x1s.dtb		\
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s.dts b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
new file mode 100644
index 000000000..1ae881015
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 5G (x1s/SM-G981B) device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990-x1s-common.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	model = "Samsung Galaxy S20 5G";
+	compatible = "samsung,x1s", "samsung,exynos990";
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x3ab00000>,
+		      /* Memory hole */
+		      <0x0 0xc1200000 0x0 0x1ee00000>,
+		      /* Memory hole */
+		      <0x0 0xe1900000 0x0 0x1e700000>,
+		      /* Memory hole */
+		      <0x8 0x80000000 0x2 0x7e800000>;
+	};
+};
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Fri Dec  6 10:46:09 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Fri,  6 Dec 2024 18:46:09 +0000
Subject: [PATCH v6 4/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 (x1slte)
In-Reply-To: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
References: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241206184609.2437-5-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 (x1slte/SM-G980F)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 8GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile           |  1 +
 .../boot/dts/exynos/exynos990-x1slte.dts      | 28 +++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index fe47aafcd..ee73e1a2d 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -11,5 +11,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos990-c1s.dtb		\
 	exynos990-r8s.dtb               \
 	exynos990-x1s.dtb		\
+	exynos990-x1slte.dtb		\
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts b/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts
new file mode 100644
index 000000000..7bca641e5
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 (x1slte/SM-G980F) device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990-hubble-common.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	model = "Samsung Galaxy S20";
+	compatible = "samsung,x1slte", "samsung,exynos990";
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x3ab00000>,
+		      /* Memory hole */
+		      <0x0 0xc1200000 0x0 0x1ee00000>,
+		      /* Memory hole */
+		      <0x0 0xe1900000 0x0 0x1e700000>,
+		      /* Memory hole */
+		      <0x8 0x80000000 0x1 0x7ec00000>;
+	};
+};
-- 
2.47.1



From torvalds at linux-foundation.org  Fri Dec  6 10:52:32 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Fri, 6 Dec 2024 10:52:32 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
Message-ID: <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>

On Fri, 6 Dec 2024 at 10:31, Vincent Mailhol <vincent.mailhol at gmail.com> wrote:
>
> > causes issues when 'x' is not an integer expression (think
> > "is_const(NULL)" or "is_const(1 == 2)".
>
> But 1 == 2 already has an integer type as proven by:

Yeah, I was confused about exactly what triggers that odd
'-Wint-in-bool-context'.

It's not about some actual bool type, it's literally a random
collection of integer operations used with logical ops.

So it's things like "!(var<<2)" that generate that warning, because
some compiler person at some point went "maybe that left shift should
have been just a comparison instead '<'".

But it turns out that "(var <<2)?0:0" _also_ triggers that warning.

End result: I have *no* idea how to shut that crazy warning up for
this case, if we want to have some generic macro that says "is this
constant". Because it damn well is perfectly sane to ask "is (a << 3)
a constant expression".

How very annoying.

This may be a case of "we just need to disable that incorrect compiler
warning". Or does anybody see a workaround?

             Linus

              Linus


From torvalds at linux-foundation.org  Fri Dec  6 11:02:46 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Fri, 6 Dec 2024 11:02:46 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com> <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
Message-ID: <CAHk-=wjk_thfjRnAYRoGX7LjJ8AyiPTmBqjJEPu6JiKDLG2isg@mail.gmail.com>

On Fri, 6 Dec 2024 at 10:52, Linus Torvalds
<torvalds at linux-foundation.org> wrote:
>
> This may be a case of "we just need to disable that incorrect compiler
> warning". Or does anybody see a workaround?

Hmm. The "== 0" thing does work, but as mentioned, that causes (more
valid, imho) warnings with pointers.

And it's not necessarily require that a pointer expression actually be
marked as a constant, as for the fact that these macros often get used
in various arbitrary contexts where things *might* be pointers, even
if "not constant" is a perfectly fine answer.

We do actually consciously use __builtin_constant_p() on pointers.
It's very convenient for format strings in particular, where
__builtin_constant_p() is a good test for a constant string, which
sometimes gets treated differently.

And in fact, dealing with NULL pointers statically might be worth it
too, so I do think it's worth keeping in mind.

               Linus


From David.Laight at ACULAB.COM  Fri Dec  6 11:06:18 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 19:06:18 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
Message-ID: <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>

From: Linus Torvalds
> Sent: 06 December 2024 18:53
> 
> On Fri, 6 Dec 2024 at 10:31, Vincent Mailhol <vincent.mailhol at gmail.com> wrote:
> >
> > > causes issues when 'x' is not an integer expression (think
> > > "is_const(NULL)" or "is_const(1 == 2)".
> >
> > But 1 == 2 already has an integer type as proven by:
> 
> Yeah, I was confused about exactly what triggers that odd
> '-Wint-in-bool-context'.
> 
> It's not about some actual bool type, it's literally a random
> collection of integer operations used with logical ops.
> 
> So it's things like "!(var<<2)" that generate that warning, because
> some compiler person at some point went "maybe that left shift should
> have been just a comparison instead '<'".
> 
> But it turns out that "(var <<2)?0:0" _also_ triggers that warning.
> 
> End result: I have *no* idea how to shut that crazy warning up for
> this case, if we want to have some generic macro that says "is this
> constant". Because it damn well is perfectly sane to ask "is (a << 3)
> a constant expression".

I'm missing the compiler version and options to generate the error.
Does a '+ 0' help?  "(var << 2) + 0 ? 0 : 0"

I realised the:
#define const_NULL(x) _Generic(0 ? (x) : (char *)0, char *: 1, void *: 0)
#define const_true(x) const_NULL((x) ? NULL : (void *)1L))
#define const_expr(x) const_NULL((x) ? NULL : NULL))
I send this morning.
Needs 's/char/struct kjkjkjkjui/' applied.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From jannh at google.com  Fri Dec  6 11:14:57 2024
From: jannh at google.com (Jann Horn)
Date: Fri, 6 Dec 2024 20:14:57 +0100
Subject: [RFC PATCH 00/16] pkeys-based page table hardening
In-Reply-To: <20241206101110.1646108-1-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
Message-ID: <CAG48ez1b8BBquEB1BJEg+KsPdPyZLPuD7uToUH3ZdN8F0r+U9w@mail.gmail.com>

On Fri, Dec 6, 2024 at 11:13?AM Kevin Brodsky <kevin.brodsky at arm.com> wrote:
> This is a proposal to leverage protection keys (pkeys) to harden
> critical kernel data, by making it mostly read-only. The series includes
> a simple framework called "kpkeys" to manipulate pkeys for in-kernel use,
> as well as a page table hardening feature based on that framework
> (kpkeys_hardened_pgtables). Both are implemented on arm64 as a proof of
> concept, but they are designed to be compatible with any architecture
> implementing pkeys.
>
> The proposed approach is a typical use of pkeys: the data to protect is
> mapped with a given pkey P, and the pkey register is initially configured
> to grant read-only access to P. Where the protected data needs to be
> written to, the pkey register is temporarily switched to grant write
> access to P on the current CPU.
>
> The key fact this approach relies on is that the target data is
> only written to via a limited and well-defined API. This makes it
> possible to explicitly switch the pkey register where needed, without
> introducing excessively invasive changes, and only for a small amount of
> trusted code.
>
> Page tables were chosen as they are a popular (and critical) target for
> attacks, but there are of course many others - this is only a starting
> point (see section "Further use-cases"). It has become more and more
> common for accesses to such target data to be mediated by a hypervisor
> in vendor kernels; the hope is that kpkeys can provide much of that
> protection in a simpler manner. No benchmarking has been performed at
> this stage, but the runtime overhead should also be lower (though likely
> not negligible).

Yeah, it isn't great that vendor kernels contain such invasive changes...

I guess one difference between this approach and a hypervisor-based
approach is that a hypervisor that uses a second layer of page tables
can also prevent access through aliasing mappings, while pkeys only
prevent access through a specific mapping? (Like if an attacker
managed to add a page that is mapped into userspace to a page
allocator freelist, allocate this page as a page table, and use the
userspace mapping to write into this page table. But I guess whether
that is an issue depends on the threat model.)

> # kpkeys_hardened_pgtables
>
> The kpkeys_hardened_pgtables feature uses the interface above to make
> the (kernel and user) page tables read-only by default, enabling write
> access only in helpers such as set_pte(). One complication is that those
> helpers as well as page table allocators are used very early, before
> kpkeys become available. Enabling kpkeys_hardened_pgtables, if and when
> kpkeys become available, is therefore done as follows:
>
> 1. A static key is turned on. This enables a transition to
>    KPKEYS_LVL_PGTABLES in all helpers writing to page tables, and also
>    impacts page table allocators (see step 3).
>
> 2. All pages holding kernel page tables are set to KPKEYS_PKEY_PGTABLES.
>    This ensures they can only be written when runnning at
>    KPKEYS_LVL_PGTABLES.
>
> 3. Page table allocators set the returned pages to KPKEYS_PKEY_PGTABLES
>    (and the pkey is reset upon freeing). This ensures that all page
>    tables are mapped with that privileged pkey.
>
> # Threat model
>
> The proposed scheme aims at mitigating data-only attacks (e.g.
> use-after-free/cross-cache attacks). In other words, it is assumed that
> control flow is not corrupted, and that the attacker does not achieve
> arbitrary code execution. Nothing prevents the pkey register from being
> set to its most permissive state - the assumption is that the register
> is only modified on legitimate code paths.

Is the threat model that the attacker has already achieved full
read/write access to unprotected kernel data and should be stopped
from gaining write access to protected data? Or is the threat model
that the attacker has achieved some limited corruption, and this
series is intended to make it harder to either gain write access to
protected data or achieve full read/write access to unprotected data?


From torvalds at linux-foundation.org  Fri Dec  6 11:15:20 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Fri, 6 Dec 2024 11:15:20 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com> <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
Message-ID: <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>

On Fri, 6 Dec 2024 at 11:07, David Laight <David.Laight at aculab.com> wrote:
>
> I'm missing the compiler version and options to generate the error.

Just -Wall with most recent gcc versions seems to do it. At least I
can repro it with gcc-14.2.1 and something silly like this:

  $ cat t.c
  int fn(int a) { return (a<<2)?1:2; }
  $ gcc -Wall -S t.c
  t.c: In function ?fn?:
  t.c:1:26: warning: ?<<? in boolean context, did you mean ?<??
[-Wint-in-bool-context]

> Does a '+ 0' help?  "(var << 2) + 0 ? 0 : 0"

Yeah, that actually works.

And "+0" is nice in that it should work in any context.

> #define const_NULL(x) _Generic(0 ? (x) : (char *)0, char *: 1, void *: 0)
> #define const_true(x) const_NULL((x) ? NULL : (void *)1L))
> #define const_expr(x) const_NULL((x) ? NULL : NULL))
> I send this morning.
> Needs 's/char/struct kjkjkjkjui/' applied.

Oh Christ. You really are taking this whole ugly to another level.

           Linus


From quic_vikramsa at quicinc.com  Fri Dec  6 11:18:57 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Sat, 7 Dec 2024 00:48:57 +0530
Subject: [PATCH v8 2/5] media: qcom: camss: Sort camss version enums and compatible strings
In-Reply-To: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
References: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
Message-ID: <20241206191900.2545069-3-quic_vikramsa@quicinc.com>

Sort CAMSS version enums and compatible strings alphanumerically.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
---
 .../media/platform/qcom/camss/camss-csiphy-3ph-1-0.c   | 10 +++++-----
 drivers/media/platform/qcom/camss/camss-vfe.c          |  6 +++---
 drivers/media/platform/qcom/camss/camss.c              |  2 +-
 drivers/media/platform/qcom/camss/camss.h              |  4 ++--
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index df7e93a5a4f6..7d2490c9de01 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -505,10 +505,6 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
 	u32 val;
 
 	switch (csiphy->camss->res->version) {
-	case CAMSS_845:
-		r = &lane_regs_sdm845[0][0];
-		array_size = ARRAY_SIZE(lane_regs_sdm845[0]);
-		break;
 	case CAMSS_8250:
 		r = &lane_regs_sm8250[0][0];
 		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
@@ -517,6 +513,10 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
 		r = &lane_regs_sc8280xp[0][0];
 		array_size = ARRAY_SIZE(lane_regs_sc8280xp[0]);
 		break;
+	case CAMSS_845:
+		r = &lane_regs_sdm845[0][0];
+		array_size = ARRAY_SIZE(lane_regs_sdm845[0]);
+		break;
 	default:
 		WARN(1, "unknown cspi version\n");
 		return;
@@ -557,9 +557,9 @@ static bool csiphy_is_gen2(u32 version)
 	bool ret = false;
 
 	switch (version) {
-	case CAMSS_845:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
+	case CAMSS_845:
 		ret = true;
 		break;
 	}
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 80a62ba11295..fb3234c65403 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -334,11 +334,11 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
 			return sink_code;
 		}
 		break;
-	case CAMSS_8x96:
 	case CAMSS_660:
-	case CAMSS_845:
+	case CAMSS_8x96:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
+	case CAMSS_845:
 		switch (sink_code) {
 		case MEDIA_BUS_FMT_YUYV8_1X16:
 		{
@@ -1693,9 +1693,9 @@ static int vfe_bpl_align(struct vfe_device *vfe)
 	int ret = 8;
 
 	switch (vfe->camss->res->version) {
-	case CAMSS_845:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
+	case CAMSS_845:
 		ret = 16;
 		break;
 	default:
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 67fb11cbe865..789e1b80f25e 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -2689,10 +2689,10 @@ static const struct of_device_id camss_dt_match[] = {
 	{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
 	{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
 	{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
+	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
 	{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
 	{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
 	{ .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
-	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
 	{ }
 };
 
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 9da7f48f5dd7..ffce0a0edbc5 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -77,13 +77,13 @@ enum pm_domain {
 };
 
 enum camss_version {
+	CAMSS_660,
 	CAMSS_8x16,
 	CAMSS_8x53,
 	CAMSS_8x96,
-	CAMSS_660,
-	CAMSS_845,
 	CAMSS_8250,
 	CAMSS_8280XP,
+	CAMSS_845,
 };
 
 enum icc_count {
-- 
2.25.1



From quic_vikramsa at quicinc.com  Fri Dec  6 11:18:58 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Sat, 7 Dec 2024 00:48:58 +0530
Subject: [PATCH v8 3/5] media: qcom: camss: Add support for camss driver on sc7280
In-Reply-To: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
References: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
Message-ID: <20241206191900.2545069-4-quic_vikramsa@quicinc.com>

From: Suresh Vankadara <quic_svankada at quicinc.com>

Add support for the camss driver on the sc7280 soc.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Tested-by: Luca Weiss <luca.weiss at fairphone.com>
---
 .../qcom/camss/camss-csiphy-3ph-1-0.c         |   5 +
 .../media/platform/qcom/camss/camss-csiphy.c  |   5 +
 .../media/platform/qcom/camss/camss-csiphy.h  |   1 +
 drivers/media/platform/qcom/camss/camss-vfe.c |   2 +
 drivers/media/platform/qcom/camss/camss.c     | 319 ++++++++++++++++++
 drivers/media/platform/qcom/camss/camss.h     |   1 +
 6 files changed, 333 insertions(+)

diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index 7d2490c9de01..f341f7b7fd8a 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -505,6 +505,10 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
 	u32 val;
 
 	switch (csiphy->camss->res->version) {
+	case CAMSS_7280:
+		r = &lane_regs_sm8250[0][0];
+		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
+		break;
 	case CAMSS_8250:
 		r = &lane_regs_sm8250[0][0];
 		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
@@ -557,6 +561,7 @@ static bool csiphy_is_gen2(u32 version)
 	bool ret = false;
 
 	switch (version) {
+	case CAMSS_7280:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
 	case CAMSS_845:
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index 5af2b382a843..3791c2d8a6cf 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -103,6 +103,11 @@ const struct csiphy_formats csiphy_formats_8x96 = {
 	.formats = formats_8x96
 };
 
+const struct csiphy_formats csiphy_formats_sc7280 = {
+	.nformats = ARRAY_SIZE(formats_sdm845),
+	.formats = formats_sdm845
+};
+
 const struct csiphy_formats csiphy_formats_sdm845 = {
 	.nformats = ARRAY_SIZE(formats_sdm845),
 	.formats = formats_sdm845
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
index e3b9e8f12806..90cc3f976643 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.h
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
@@ -117,6 +117,7 @@ void msm_csiphy_unregister_entity(struct csiphy_device *csiphy);
 
 extern const struct csiphy_formats csiphy_formats_8x16;
 extern const struct csiphy_formats csiphy_formats_8x96;
+extern const struct csiphy_formats csiphy_formats_sc7280;
 extern const struct csiphy_formats csiphy_formats_sdm845;
 
 extern const struct csiphy_hw_ops csiphy_ops_2ph_1_0;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index fb3234c65403..95f6a1ac7eaf 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -335,6 +335,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
 		}
 		break;
 	case CAMSS_660:
+	case CAMSS_7280:
 	case CAMSS_8x96:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
@@ -1693,6 +1694,7 @@ static int vfe_bpl_align(struct vfe_device *vfe)
 	int ret = 8;
 
 	switch (vfe->camss->res->version) {
+	case CAMSS_7280:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
 	case CAMSS_845:
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 789e1b80f25e..004a74f6b2f6 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1266,6 +1266,310 @@ static const struct resources_icc icc_res_sm8250[] = {
 	},
 };
 
+static const struct camss_subdev_resources csiphy_res_7280[] = {
+	/* CSIPHY0 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy0", "csiphy0_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy0" },
+		.interrupt = { "csiphy0" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY1 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy1", "csiphy1_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy1" },
+		.interrupt = { "csiphy1" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY2 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy2", "csiphy2_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy2" },
+		.interrupt = { "csiphy2" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY3 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy3", "csiphy3_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy3" },
+		.interrupt = { "csiphy3" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY4 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csiphy4", "csiphy4_timer" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy4" },
+		.interrupt = { "csiphy4" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+};
+
+static const struct camss_subdev_resources csid_res_7280[] = {
+	/* CSID0 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 }
+		},
+
+		.reg = { "csid0" },
+		.interrupt = { "csid0" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID1 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 }
+		},
+
+		.reg = { "csid1" },
+		.interrupt = { "csid1" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID2 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 }
+		},
+
+		.reg = { "csid2" },
+		.interrupt = { "csid2" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID3 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 320000000, 400000000, 480000000, 600000000 }
+		},
+
+		.reg = { "csid_lite0" },
+		.interrupt = { "csid_lite0" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID4 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
+		.clock_rate = { { 300000000, 400000000 },
+				{ 0 },
+				{ 320000000, 400000000, 480000000, 600000000 }
+		},
+
+		.reg = { "csid_lite1" },
+		.interrupt = { "csid_lite1" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+};
+
+static const struct camss_subdev_resources vfe_res_7280[] = {
+	/* VFE0 */
+	{
+		.regulators = {},
+
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0",
+			   "vfe0_axi", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 },
+				{ 0 },
+				{ 0 } },
+
+		.reg = { "vfe0" },
+		.interrupt = { "vfe0" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = true,
+			.pd_name = "ife0",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE1 */
+	{
+		.regulators = {},
+
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe1",
+			   "vfe1_axi", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 },
+				{ 0 },
+				{ 0 } },
+
+		.reg = { "vfe1" },
+		.interrupt = { "vfe1" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = true,
+			.pd_name = "ife1",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE2 */
+	{
+		.regulators = {},
+
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe2",
+			   "vfe2_axi", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 380000000, 510000000, 637000000, 760000000 },
+				{ 0 },
+				{ 0 } },
+
+		.reg = { "vfe2" },
+		.interrupt = { "vfe2" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.hw_ops = &vfe_ops_170,
+			.has_pd = true,
+			.pd_name = "ife2",
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE3 (lite) */
+	{
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
+			   "vfe_lite0", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 320000000, 400000000, 480000000, 600000000 },
+				{ 0 } },
+
+		.regulators = {},
+		.reg = { "vfe_lite0" },
+		.interrupt = { "vfe_lite0" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE4 (lite) */
+	{
+		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
+			   "vfe_lite1", "gcc_cam_hf_axi" },
+		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
+				{ 80000000 },
+				{ 0 },
+				{ 320000000, 400000000, 480000000, 600000000 },
+				{ 0 } },
+
+		.regulators = {},
+		.reg = { "vfe_lite1" },
+		.interrupt = { "vfe_lite1" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+};
+
+static const struct resources_icc icc_res_sc7280[] = {
+	{
+		.name = "ahb",
+		.icc_bw_tbl.avg = 38400,
+		.icc_bw_tbl.peak = 76800,
+	},
+	{
+		.name = "hf_0",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+};
+
 static const struct camss_subdev_resources csiphy_res_sc8280xp[] = {
 	/* CSIPHY0 */
 	{
@@ -2685,10 +2989,25 @@ static const struct camss_resources sc8280xp_resources = {
 	.link_entities = camss_link_entities
 };
 
+static const struct camss_resources sc7280_resources = {
+	.version = CAMSS_7280,
+	.pd_name = "top",
+	.csiphy_res = csiphy_res_7280,
+	.csid_res = csid_res_7280,
+	.vfe_res = vfe_res_7280,
+	.icc_res = icc_res_sc7280,
+	.icc_path_num = ARRAY_SIZE(icc_res_sc7280),
+	.csiphy_num = ARRAY_SIZE(csiphy_res_7280),
+	.csid_num = ARRAY_SIZE(csid_res_7280),
+	.vfe_num = ARRAY_SIZE(vfe_res_7280),
+	.link_entities = camss_link_entities
+};
+
 static const struct of_device_id camss_dt_match[] = {
 	{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
 	{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
 	{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
+	{ .compatible = "qcom,sc7280-camss", .data = &sc7280_resources },
 	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
 	{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
 	{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index ffce0a0edbc5..9a046eea334f 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -78,6 +78,7 @@ enum pm_domain {
 
 enum camss_version {
 	CAMSS_660,
+	CAMSS_7280,
 	CAMSS_8x16,
 	CAMSS_8x53,
 	CAMSS_8x96,
-- 
2.25.1



From quic_vikramsa at quicinc.com  Fri Dec  6 11:18:59 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Sat, 7 Dec 2024 00:48:59 +0530
Subject: [PATCH v8 4/5] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
References: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
Message-ID: <20241206191900.2545069-5-quic_vikramsa@quicinc.com>

Add changes to support the camera subsystem on the SC7280.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Tested-by: Luca Weiss <luca.weiss at fairphone.com>
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 178 +++++++++++++++++++++++++++
 1 file changed, 178 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 55db1c83ef55..afe7113df4af 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -4426,6 +4426,184 @@ cci1_i2c1: i2c-bus at 1 {
 			};
 		};
 
+		camss: isp at acb3000 {
+			compatible = "qcom,sc7280-camss";
+
+			reg = <0x0 0x0acb3000 0x0 0x1000>,
+			      <0x0 0x0acba000 0x0 0x1000>,
+			      <0x0 0x0acc1000 0x0 0x1000>,
+			      <0x0 0x0acc8000 0x0 0x1000>,
+			      <0x0 0x0accf000 0x0 0x1000>,
+			      <0x0 0x0ace0000 0x0 0x2000>,
+			      <0x0 0x0ace2000 0x0 0x2000>,
+			      <0x0 0x0ace4000 0x0 0x2000>,
+			      <0x0 0x0ace6000 0x0 0x2000>,
+			      <0x0 0x0ace8000 0x0 0x2000>,
+			      <0x0 0x0acaf000 0x0 0x4000>,
+			      <0x0 0x0acb6000 0x0 0x4000>,
+			      <0x0 0x0acbd000 0x0 0x4000>,
+			      <0x0 0x0acc4000 0x0 0x4000>,
+			      <0x0 0x0accb000 0x0 0x4000>;
+			reg-names = "csid0",
+				    "csid1",
+				    "csid2",
+				    "csid_lite0",
+				    "csid_lite1",
+				    "csiphy0",
+				    "csiphy1",
+				    "csiphy2",
+				    "csiphy3",
+				    "csiphy4",
+				    "vfe0",
+				    "vfe1",
+				    "vfe2",
+				    "vfe_lite0",
+				    "vfe_lite1";
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_CSIPHY0_CLK>,
+				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY1_CLK>,
+				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY2_CLK>,
+				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY3_CLK>,
+				 <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY4_CLK>,
+				 <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+				 <&gcc GCC_CAMERA_AHB_CLK>,
+				 <&gcc GCC_CAMERA_HF_AXI_CLK>,
+				 <&camcc CAM_CC_ICP_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_0_CLK>,
+				 <&camcc CAM_CC_IFE_0_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_1_CLK>,
+				 <&camcc CAM_CC_IFE_1_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_1_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_2_CLK>,
+				 <&camcc CAM_CC_IFE_2_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_2_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>;
+			clock-names = "camnoc_axi",
+				      "cpas_ahb",
+				      "csiphy0",
+				      "csiphy0_timer",
+				      "csiphy1",
+				      "csiphy1_timer",
+				      "csiphy2",
+				      "csiphy2_timer",
+				      "csiphy3",
+				      "csiphy3_timer",
+				      "csiphy4",
+				      "csiphy4_timer",
+				      "gcc_camera_ahb",
+				      "gcc_cam_hf_axi",
+				      "icp_ahb",
+				      "vfe0",
+				      "vfe0_axi",
+				      "vfe0_cphy_rx",
+				      "vfe0_csid",
+				      "vfe1",
+				      "vfe1_axi",
+				      "vfe1_cphy_rx",
+				      "vfe1_csid",
+				      "vfe2",
+				      "vfe2_axi",
+				      "vfe2_cphy_rx",
+				      "vfe2_csid",
+				      "vfe_lite0",
+				      "vfe_lite0_cphy_rx",
+				      "vfe_lite0_csid",
+				      "vfe_lite1",
+				      "vfe_lite1_cphy_rx",
+				      "vfe_lite1_csid";
+
+			interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "csid0",
+					  "csid1",
+					  "csid2",
+					  "csid_lite0",
+					  "csid_lite1",
+					  "csiphy0",
+					  "csiphy1",
+					  "csiphy2",
+					  "csiphy3",
+					  "csiphy4",
+					  "vfe0",
+					  "vfe1",
+					  "vfe2",
+					  "vfe_lite0",
+					  "vfe_lite1";
+
+			interconnects = <&gem_noc  MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &cnoc2 SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&mmss_noc MASTER_CAMNOC_HF  QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "ahb",
+					     "hf_0";
+
+			iommus = <&apps_smmu 0x800 0x4e0>;
+
+			power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
+					<&camcc CAM_CC_IFE_1_GDSC>,
+					<&camcc CAM_CC_IFE_2_GDSC>,
+					<&camcc CAM_CC_TITAN_TOP_GDSC>;
+			power-domain-names = "ife0",
+					     "ife1",
+					     "ife2",
+					     "top";
+
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+				};
+
+				port at 1 {
+					reg = <1>;
+				};
+
+				port at 2 {
+					reg = <2>;
+				};
+
+				port at 3 {
+					reg = <3>;
+				};
+
+				port at 4 {
+					reg = <4>;
+				};
+			};
+		};
+
 		camcc: clock-controller at ad00000 {
 			compatible = "qcom,sc7280-camcc";
 			reg = <0 0x0ad00000 0 0x10000>;
-- 
2.25.1



From quic_vikramsa at quicinc.com  Fri Dec  6 11:18:55 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Sat, 7 Dec 2024 00:48:55 +0530
Subject: [PATCH v8 0/5] media: qcom: camss: Add sc7280 support
Message-ID: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>

SC7280 is a Qualcomm SoC. This series adds support to bring up the CSIPHY,
CSID, VFE/RDI interfaces in SC7280.

SC7280 provides

- 3 x VFE, 3 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE
- 3 x CSID
- 2 x CSID Lite
- 5 x CSI PHY

We have tested this on qcs6490-rb3gen2-vision-mezzanine board having IMX577
sensor. Verified both TPG and IMX577 sensor.

Used following tools for the sanity check of these changes.

- make CHECK_DTBS=y W=1 DT_SCHEMA_FILES=media/qcom,sc7280-camss.yaml
qcom/qcs6490-rb3gen2-vision-mezzanine.dtb
- make DT_CHECKER_FLAGS=-m W=1
DT_SCHEMA_FILES=media/qcom,sc7280-camss.yaml dt_binding_check
- Smatch: make CHECK="smatch --full-path"
M=drivers/media/platform/qcom/camss/
- Sparse: make C=2 M=drivers/media/platform/qcom/camss/
- coccicheck : make coccicheck M=drivers/media/platform/qcom/camss/
- make -j32 W=1
- ./scripts/checkpatch.pl
 
Changes in V8:
- Changed node name from camss to isp.
- Added QCOM_ICC_TAG_ACTIVE_ONLY and QCOM_ICC_TAG_ALWAYS tags for
  interconnects. 
- Added blank lines when required.
- Modified power-domain-names from horizontal to vertical list.
- Sorted pinctrl nodes based on gpio index.
- Link to v7: https://lore.kernel.org/linux-arm-msm/20241204100003.300123-1-quic_vikramsa at quicinc.com/

Changes in V7:
- Changed unit address for camss in documention and dts.
- Added avdd-supply and dvdd-supply for sensor.
- Changed reg/clocks/interrupts name for vfe_lite and csid_lite.
- Link to v6: https://lore.kernel.org/linux-arm-msm/20241127100421.3447601-1-quic_vikramsa at quicinc.com/

Changes in V6:
- Changed order of properties in Documentation [PATCH 1/5].
- Updated description for ports in Documentaion [PATCH 1/5].
- Moved regulators from csid to csiphy [PATCH 3/5].
- Link to v5: https://lore.kernel.org/linux-arm-msm/20241112173032.2740119-1-quic_vikramsa at quicinc.com/ 

Changes in V5:
- Updated Commit text for [PATCH v5 1/6].
- Moved reg after compatible string.
- Renamed csi'x' clocks to vfe'x'_csid
- Removed [PATCH v4 4/6] and raised a seprate series for this one.
- Moved gpio states to mezzanine dtso.
- Added more clock levels to address TPG related issues.
- Renamed power-domains-names -> power-domain-names. 
- Link to v4: https://lore.kernel.org/linux-arm-msm/20241030105347.2117034-1-quic_vikramsa at quicinc.com/ 

Changes in V4:
- V3 had 8 patches and V4 is reduced to 6.
- Removed [Patch v3 2/8] as binding change is not required for dtso.
- Removed [Patch v3 3/8] as the fix is already taken care in latest
  kernel tip. 
- Updated alignment for dtsi and dt-bindings.
- Adding qcs6490-rb3gen2-vision-mezzanine as overlay. 
- Link to v3: https://lore.kernel.org/linux-arm-msm/20241011140932.1744124-1-quic_vikramsa at quicinc.com/

Changes in V3:
- Added missed subject line for cover letter of V2.
- Updated Alignment, indentation and properties order.
- edit commit text for [PATCH 02/10] and [PATCH 03/10].
- Refactor camss_link_entities.
- Removed camcc enablement changes as it already done.
- Link to v2: https://lore.kernel.org/linux-arm-msm/20240904-camss_on_sc7280_rb3gen2_vision_v2_patches-v1-0-b18ddcd7d9df at quicinc.com/

Changes in V2:
- Improved indentation/formatting.
- Removed _src clocks and misleading code comments.
- Added name fields for power domains and csid register offset in DTSI.
- Dropped minItems field from YAML file.
- Listed changes in alphabetical order.
- Updated description and commit text to reflect changes
- Changed the compatible string from imx412 to imx577.
- Added board-specific enablement changes in the newly created vision
  board DTSI file.
- Fixed bug encountered during testing.
- Moved logically independent changes to a new/seprate patch.
- Removed cci0 as no sensor is on this port and MCLK2, which was a
  copy-paste error from the RB5 board reference.
- Added power rails, referencing the RB5 board.
- Discarded Patch 5/6 completely (not required).
- Removed unused enums.
- Link to v1: https://lore.kernel.org/linux-arm-msm/20240629-camss_first_post_linux_next-v1-0-bc798edabc3a at quicinc.com/

This is tested on QCM6490 Fairphone 5 smartphone with WIP drivers for
IMX858 and S5KJN1 by Luca Weiss <luca.weiss at fairphone.com>.

Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Tested-by: Luca Weiss <luca.weiss at fairphone.com> 

Suresh Vankadara (1):
  media: qcom: camss: Add support for camss driver on sc7280

Vikram Sharma (4):
  media: dt-bindings: Add qcom,sc7280-camss
  media: qcom: camss: Sort camss version enums and compatible strings
  arm64: dts: qcom: sc7280: Add support for camss
  arm64: dts: qcom: qcs6490-rb3gen2-vision-mezzanine: Add vision
    mezzanine

 .../bindings/media/qcom,sc7280-camss.yaml     | 425 ++++++++++++++++++
 arch/arm64/boot/dts/qcom/Makefile             |   4 +
 .../qcs6490-rb3gen2-vision-mezzanine.dtso     | 110 +++++
 arch/arm64/boot/dts/qcom/sc7280.dtsi          | 178 ++++++++
 .../qcom/camss/camss-csiphy-3ph-1-0.c         |  13 +-
 .../media/platform/qcom/camss/camss-csiphy.c  |   5 +
 .../media/platform/qcom/camss/camss-csiphy.h  |   1 +
 drivers/media/platform/qcom/camss/camss-vfe.c |   8 +-
 drivers/media/platform/qcom/camss/camss.c     | 321 ++++++++++++-
 drivers/media/platform/qcom/camss/camss.h     |   5 +-
 10 files changed, 1060 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
 create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso

-- 
2.25.1



From quic_vikramsa at quicinc.com  Fri Dec  6 11:18:56 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Sat, 7 Dec 2024 00:48:56 +0530
Subject: [PATCH v8 1/5] media: dt-bindings: Add qcom,sc7280-camss
In-Reply-To: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
References: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
Message-ID: <20241206191900.2545069-2-quic_vikramsa@quicinc.com>

Add bindings for qcom,sc7280-camss to support the camera subsystem
on the SC7280 platform.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
---
 .../bindings/media/qcom,sc7280-camss.yaml     | 425 ++++++++++++++++++
 1 file changed, 425 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml

diff --git a/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
new file mode 100644
index 000000000000..e11141b812a0
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
@@ -0,0 +1,425 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/qcom,sc7280-camss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SC7280 CAMSS ISP
+
+maintainers:
+  - Azam Sadiq Pasha Kapatrala Syed <akapatra at quicinc.com>
+  - Hariram Purushothaman <hariramp at quicinc.com>
+
+description:
+  The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
+
+properties:
+  compatible:
+    const: qcom,sc7280-camss
+
+  reg:
+    maxItems: 15
+
+  reg-names:
+    items:
+      - const: csid0
+      - const: csid1
+      - const: csid2
+      - const: csid_lite0
+      - const: csid_lite1
+      - const: csiphy0
+      - const: csiphy1
+      - const: csiphy2
+      - const: csiphy3
+      - const: csiphy4
+      - const: vfe0
+      - const: vfe1
+      - const: vfe2
+      - const: vfe_lite0
+      - const: vfe_lite1
+
+  clocks:
+    maxItems: 33
+
+  clock-names:
+    items:
+      - const: camnoc_axi
+      - const: cpas_ahb
+      - const: csiphy0
+      - const: csiphy0_timer
+      - const: csiphy1
+      - const: csiphy1_timer
+      - const: csiphy2
+      - const: csiphy2_timer
+      - const: csiphy3
+      - const: csiphy3_timer
+      - const: csiphy4
+      - const: csiphy4_timer
+      - const: gcc_camera_ahb
+      - const: gcc_cam_hf_axi
+      - const: icp_ahb
+      - const: vfe0
+      - const: vfe0_axi
+      - const: vfe0_cphy_rx
+      - const: vfe0_csid
+      - const: vfe1
+      - const: vfe1_axi
+      - const: vfe1_cphy_rx
+      - const: vfe1_csid
+      - const: vfe2
+      - const: vfe2_axi
+      - const: vfe2_cphy_rx
+      - const: vfe2_csid
+      - const: vfe_lite0
+      - const: vfe_lite0_cphy_rx
+      - const: vfe_lite0_csid
+      - const: vfe_lite1
+      - const: vfe_lite1_cphy_rx
+      - const: vfe_lite1_csid
+
+  interrupts:
+    maxItems: 15
+
+  interrupt-names:
+    items:
+      - const: csid0
+      - const: csid1
+      - const: csid2
+      - const: csid_lite0
+      - const: csid_lite1
+      - const: csiphy0
+      - const: csiphy1
+      - const: csiphy2
+      - const: csiphy3
+      - const: csiphy4
+      - const: vfe0
+      - const: vfe1
+      - const: vfe2
+      - const: vfe_lite0
+      - const: vfe_lite1
+
+  interconnects:
+    maxItems: 2
+
+  interconnect-names:
+    items:
+      - const: ahb
+      - const: hf_0
+
+  iommus:
+    maxItems: 1
+
+  power-domains:
+    items:
+      - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: IFE2 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller.
+
+  power-domain-names:
+    items:
+      - const: ife0
+      - const: ife1
+      - const: ife2
+      - const: top
+
+  vdda-phy-supply:
+    description:
+      Phandle to a regulator supply to PHY core block.
+
+  vdda-pll-supply:
+    description:
+      Phandle to 1.8V regulator supply to PHY refclk pll block.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    description:
+      CSI input ports.
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 0.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 1.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+      port at 2:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 2.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+      port at 3:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 3.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+      port at 4:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port for receiving CSI data on CSIPHY 4.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - interrupts
+  - interrupt-names
+  - interconnects
+  - interconnect-names
+  - iommus
+  - power-domains
+  - power-domain-names
+  - vdda-phy-supply
+  - vdda-pll-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,camcc-sc7280.h>
+    #include <dt-bindings/clock/qcom,gcc-sc7280.h>
+    #include <dt-bindings/interconnect/qcom,sc7280.h>
+    #include <dt-bindings/interconnect/qcom,icc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        isp at acb3000 {
+            compatible = "qcom,sc7280-camss";
+
+            reg = <0x0 0x0acb3000 0x0 0x1000>,
+                  <0x0 0x0acba000 0x0 0x1000>,
+                  <0x0 0x0acc1000 0x0 0x1000>,
+                  <0x0 0x0acc8000 0x0 0x1000>,
+                  <0x0 0x0accf000 0x0 0x1000>,
+                  <0x0 0x0ace0000 0x0 0x2000>,
+                  <0x0 0x0ace2000 0x0 0x2000>,
+                  <0x0 0x0ace4000 0x0 0x2000>,
+                  <0x0 0x0ace6000 0x0 0x2000>,
+                  <0x0 0x0ace8000 0x0 0x2000>,
+                  <0x0 0x0acaf000 0x0 0x4000>,
+                  <0x0 0x0acb6000 0x0 0x4000>,
+                  <0x0 0x0acbd000 0x0 0x4000>,
+                  <0x0 0x0acc4000 0x0 0x4000>,
+                  <0x0 0x0accb000 0x0 0x4000>;
+            reg-names = "csid0",
+                        "csid1",
+                        "csid2",
+                        "csid_lite0",
+                        "csid_lite1",
+                        "csiphy0",
+                        "csiphy1",
+                        "csiphy2",
+                        "csiphy3",
+                        "csiphy4",
+                        "vfe0",
+                        "vfe1",
+                        "vfe2",
+                        "vfe_lite0",
+                        "vfe_lite1";
+
+            clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+                     <&camcc CAM_CC_CPAS_AHB_CLK>,
+                     <&camcc CAM_CC_CSIPHY0_CLK>,
+                     <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+                     <&camcc CAM_CC_CSIPHY1_CLK>,
+                     <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+                     <&camcc CAM_CC_CSIPHY2_CLK>,
+                     <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+                     <&camcc CAM_CC_CSIPHY3_CLK>,
+                     <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+                     <&camcc CAM_CC_CSIPHY4_CLK>,
+                     <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+                     <&gcc GCC_CAMERA_AHB_CLK>,
+                     <&gcc GCC_CAMERA_HF_AXI_CLK>,
+                     <&camcc CAM_CC_ICP_AHB_CLK>,
+                     <&camcc CAM_CC_IFE_0_CLK>,
+                     <&camcc CAM_CC_IFE_0_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_0_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_1_CLK>,
+                     <&camcc CAM_CC_IFE_1_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_1_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_2_CLK>,
+                     <&camcc CAM_CC_IFE_2_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_2_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>;
+            clock-names = "camnoc_axi",
+                          "cpas_ahb",
+                          "csiphy0",
+                          "csiphy0_timer",
+                          "csiphy1",
+                          "csiphy1_timer",
+                          "csiphy2",
+                          "csiphy2_timer",
+                          "csiphy3",
+                          "csiphy3_timer",
+                          "csiphy4",
+                          "csiphy4_timer",
+                          "gcc_camera_ahb",
+                          "gcc_cam_hf_axi",
+                          "icp_ahb",
+                          "vfe0",
+                          "vfe0_axi",
+                          "vfe0_cphy_rx",
+                          "vfe0_csid",
+                          "vfe1",
+                          "vfe1_axi",
+                          "vfe1_cphy_rx",
+                          "vfe1_csid",
+                          "vfe2",
+                          "vfe2_axi",
+                          "vfe2_cphy_rx",
+                          "vfe2_csid",
+                          "vfe_lite0",
+                          "vfe_lite0_cphy_rx",
+                          "vfe_lite0_csid",
+                          "vfe_lite1",
+                          "vfe_lite1_cphy_rx",
+                          "vfe_lite1_csid";
+
+            interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+            interrupt-names = "csid0",
+                              "csid1",
+                              "csid2",
+                              "csid_lite0",
+                              "csid_lite1",
+                              "csiphy0",
+                              "csiphy1",
+                              "csiphy2",
+                              "csiphy3",
+                              "csiphy4",
+                              "vfe0",
+                              "vfe1",
+                              "vfe2",
+                              "vfe_lite0",
+                              "vfe_lite1";
+
+            interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+                             &cnoc2 SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+                            <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS
+                             &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+            interconnect-names = "ahb",
+                                 "hf_0";
+
+            iommus = <&apps_smmu 0x800 0x4e0>;
+
+            power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
+                            <&camcc CAM_CC_IFE_1_GDSC>,
+                            <&camcc CAM_CC_IFE_2_GDSC>,
+                            <&camcc CAM_CC_TITAN_TOP_GDSC>;
+            power-domain-names = "ife0",
+                                 "ife1",
+                                 "ife2",
+                                 "top";
+
+            vdda-phy-supply = <&vreg_l10c_0p88>;
+            vdda-pll-supply = <&vreg_l6b_1p2>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+            };
+        };
+    };
-- 
2.25.1



From quic_vikramsa at quicinc.com  Fri Dec  6 11:19:00 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Sat, 7 Dec 2024 00:49:00 +0530
Subject: [PATCH v8 5/5] arm64: dts: qcom: qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
References: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
Message-ID: <20241206191900.2545069-6-quic_vikramsa@quicinc.com>

The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
Enable the IMX577 on the vision mezzanine.

An example media-ctl pipeline for the imx577 is:

media-ctl --reset
media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'

yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0

Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
---
 arch/arm64/boot/dts/qcom/Makefile             |   4 +
 .../qcs6490-rb3gen2-vision-mezzanine.dtso     | 109 ++++++++++++++++++
 2 files changed, 113 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 4686f2a8ddd8..a7e88fcabded 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -115,6 +115,10 @@ dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-1000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-4000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs615-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
+
+qcs6490-rb3gen2-vision-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2-vision-mezzanine.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride.dtb
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
new file mode 100644
index 000000000000..7782c4aee576
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/*
+ * Camera Sensor overlay on top of rb3gen2 core kit.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/qcom,camcc-sc7280.h>
+
+/dts-v1/;
+/plugin/;
+
+&camss {
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* The port index denotes CSIPHY id i.e. csiphy3 */
+		port at 3 {
+			reg = <3>;
+
+			csiphy3_ep: endpoint {
+				clock-lanes = <7>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&imx577_ep>;
+			};
+		};
+	};
+};
+
+&cci1 {
+	status = "okay";
+};
+
+&cci1_i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	camera at 1a {
+		compatible = "sony,imx577";
+
+		reg = <0x1a>;
+
+		reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default", "suspend";
+		pinctrl-0 = <&cam2_default>;
+		pinctrl-1 = <&cam2_suspend>;
+
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clock-rates = <24000000>;
+
+		dovdd-supply  = <&vreg_l18b_1p8>;
+		avdd-supply = <&vph_pwr>;
+		dvdd-supply = <&vph_pwr>;
+
+		port {
+			imx577_ep: endpoint {
+				clock-lanes = <7>;
+				link-frequencies = /bits/ 64 <600000000>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&csiphy3_ep>;
+			};
+		};
+	};
+};
+
+&tlmm {
+	cam2_default: cam2-default-state {
+		mclk-pins {
+			pins = "gpio67";
+			function = "cam_mclk";
+			drive-strength = <2>;
+			bias-disable;
+		};
+
+		rst-pins {
+			pins = "gpio78";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+		};
+	};
+
+	cam2_suspend: cam2-suspend-state {
+		mclk-pins {
+			pins = "gpio67";
+			function = "cam_mclk";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		rst-pins {
+			pins = "gpio78";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+			output-low;
+		};
+	};
+};
-- 
2.25.1



From quic_vikramsa at quicinc.com  Fri Dec  6 11:26:02 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Sat, 7 Dec 2024 00:56:02 +0530
Subject: [PATCH v7 3/5] media: qcom: camss: Add support for camss driver
 on sc7280
In-Reply-To: <D64GCT2CXFLC.33Y61JJ8XFCHO@fairphone.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-4-quic_vikramsa@quicinc.com>
 <D64GCT2CXFLC.33Y61JJ8XFCHO@fairphone.com>
Message-ID: <34e31ba9-eca7-4fe1-995b-31f53d60db1d@quicinc.com>


On 12/6/2024 1:21 PM, Luca Weiss wrote:
> On Wed Dec 4, 2024 at 11:00 AM CET, Vikram Sharma wrote:
>> From: Suresh Vankadara <quic_svankada at quicinc.com>
>>
>> Add support for the camss driver on the sc7280 soc.
>>
>> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
>> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
>> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
>> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> Hi Vikram,
>
> This is working on QCM6490 Fairphone 5 smartphone with WIP drivers for
> IMX858 and S5KJN1, thanks!
>
> Tested-by: Luca Weiss <luca.weiss at fairphone.com> # qcm6490-fairphone-fp5
>
> Regards
> Luca
Hi Luca,

Thanks for your help in testing this on 2 different sensors.

I have posted V8 for this adding "Tested-by" tag with your name.

Best Regards,
Vikram

>
>> ---
>>   .../qcom/camss/camss-csiphy-3ph-1-0.c         |   5 +
>>   .../media/platform/qcom/camss/camss-csiphy.c  |   5 +
>>   .../media/platform/qcom/camss/camss-csiphy.h  |   1 +
>>   drivers/media/platform/qcom/camss/camss-vfe.c |   2 +
>>   drivers/media/platform/qcom/camss/camss.c     | 319 ++++++++++++++++++
>>   drivers/media/platform/qcom/camss/camss.h     |   1 +
>>   6 files changed, 333 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
>> index 7d2490c9de01..f341f7b7fd8a 100644
>> --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
>> @@ -505,6 +505,10 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy,
>>   	u32 val;
>>   
>>   	switch (csiphy->camss->res->version) {
>> +	case CAMSS_7280:
>> +		r = &lane_regs_sm8250[0][0];
>> +		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
>> +		break;
>>   	case CAMSS_8250:
>>   		r = &lane_regs_sm8250[0][0];
>>   		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
>> @@ -557,6 +561,7 @@ static bool csiphy_is_gen2(u32 version)
>>   	bool ret = false;
>>   
>>   	switch (version) {
>> +	case CAMSS_7280:
>>   	case CAMSS_8250:
>>   	case CAMSS_8280XP:
>>   	case CAMSS_845:
>> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
>> index 5af2b382a843..3791c2d8a6cf 100644
>> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
>> @@ -103,6 +103,11 @@ const struct csiphy_formats csiphy_formats_8x96 = {
>>   	.formats = formats_8x96
>>   };
>>   
>> +const struct csiphy_formats csiphy_formats_sc7280 = {
>> +	.nformats = ARRAY_SIZE(formats_sdm845),
>> +	.formats = formats_sdm845
>> +};
>> +
>>   const struct csiphy_formats csiphy_formats_sdm845 = {
>>   	.nformats = ARRAY_SIZE(formats_sdm845),
>>   	.formats = formats_sdm845
>> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
>> index eebc1ff1cfab..b6209bddfb61 100644
>> --- a/drivers/media/platform/qcom/camss/camss-csiphy.h
>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
>> @@ -111,6 +111,7 @@ void msm_csiphy_unregister_entity(struct csiphy_device *csiphy);
>>   
>>   extern const struct csiphy_formats csiphy_formats_8x16;
>>   extern const struct csiphy_formats csiphy_formats_8x96;
>> +extern const struct csiphy_formats csiphy_formats_sc7280;
>>   extern const struct csiphy_formats csiphy_formats_sdm845;
>>   
>>   extern const struct csiphy_hw_ops csiphy_ops_2ph_1_0;
>> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
>> index fb3234c65403..95f6a1ac7eaf 100644
>> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
>> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
>> @@ -335,6 +335,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
>>   		}
>>   		break;
>>   	case CAMSS_660:
>> +	case CAMSS_7280:
>>   	case CAMSS_8x96:
>>   	case CAMSS_8250:
>>   	case CAMSS_8280XP:
>> @@ -1693,6 +1694,7 @@ static int vfe_bpl_align(struct vfe_device *vfe)
>>   	int ret = 8;
>>   
>>   	switch (vfe->camss->res->version) {
>> +	case CAMSS_7280:
>>   	case CAMSS_8250:
>>   	case CAMSS_8280XP:
>>   	case CAMSS_845:
>> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
>> index f5704c23766a..4fa16ff6e614 100644
>> --- a/drivers/media/platform/qcom/camss/camss.c
>> +++ b/drivers/media/platform/qcom/camss/camss.c
>> @@ -1266,6 +1266,310 @@ static const struct resources_icc icc_res_sm8250[] = {
>>   	},
>>   };
>>   
>> +static const struct camss_subdev_resources csiphy_res_7280[] = {
>> +	/* CSIPHY0 */
>> +	{
>> +		.regulators = { "vdda-phy", "vdda-pll" },
>> +
>> +		.clock = { "csiphy0", "csiphy0_timer" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 300000000 } },
>> +		.reg = { "csiphy0" },
>> +		.interrupt = { "csiphy0" },
>> +		.csiphy = {
>> +			.hw_ops = &csiphy_ops_3ph_1_0,
>> +			.formats = &csiphy_formats_sc7280
>> +		}
>> +	},
>> +	/* CSIPHY1 */
>> +	{
>> +		.regulators = { "vdda-phy", "vdda-pll" },
>> +
>> +		.clock = { "csiphy1", "csiphy1_timer" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 300000000 } },
>> +		.reg = { "csiphy1" },
>> +		.interrupt = { "csiphy1" },
>> +		.csiphy = {
>> +			.hw_ops = &csiphy_ops_3ph_1_0,
>> +			.formats = &csiphy_formats_sc7280
>> +		}
>> +	},
>> +	/* CSIPHY2 */
>> +	{
>> +		.regulators = { "vdda-phy", "vdda-pll" },
>> +
>> +		.clock = { "csiphy2", "csiphy2_timer" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 300000000 } },
>> +		.reg = { "csiphy2" },
>> +		.interrupt = { "csiphy2" },
>> +		.csiphy = {
>> +			.hw_ops = &csiphy_ops_3ph_1_0,
>> +			.formats = &csiphy_formats_sc7280
>> +		}
>> +	},
>> +	/* CSIPHY3 */
>> +	{
>> +		.regulators = { "vdda-phy", "vdda-pll" },
>> +
>> +		.clock = { "csiphy3", "csiphy3_timer" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 300000000 } },
>> +		.reg = { "csiphy3" },
>> +		.interrupt = { "csiphy3" },
>> +		.csiphy = {
>> +			.hw_ops = &csiphy_ops_3ph_1_0,
>> +			.formats = &csiphy_formats_sc7280
>> +		}
>> +	},
>> +	/* CSIPHY4 */
>> +	{
>> +		.regulators = { "vdda-phy", "vdda-pll" },
>> +
>> +		.clock = { "csiphy4", "csiphy4_timer" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 300000000 } },
>> +		.reg = { "csiphy4" },
>> +		.interrupt = { "csiphy4" },
>> +		.csiphy = {
>> +			.hw_ops = &csiphy_ops_3ph_1_0,
>> +			.formats = &csiphy_formats_sc7280
>> +		}
>> +	},
>> +};
>> +
>> +static const struct camss_subdev_resources csid_res_7280[] = {
>> +	/* CSID0 */
>> +	{
>> +		.regulators = {},
>> +
>> +		.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 0 },
>> +				{ 380000000, 510000000, 637000000, 760000000 }
>> +		},
>> +
>> +		.reg = { "csid0" },
>> +		.interrupt = { "csid0" },
>> +		.csid = {
>> +			.is_lite = false,
>> +			.hw_ops = &csid_ops_gen2,
>> +			.parent_dev_ops = &vfe_parent_dev_ops,
>> +			.formats = &csid_formats_gen2
>> +		}
>> +	},
>> +	/* CSID1 */
>> +	{
>> +		.regulators = {},
>> +
>> +		.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 0 },
>> +				{ 380000000, 510000000, 637000000, 760000000 }
>> +		},
>> +
>> +		.reg = { "csid1" },
>> +		.interrupt = { "csid1" },
>> +		.csid = {
>> +			.is_lite = false,
>> +			.hw_ops = &csid_ops_gen2,
>> +			.parent_dev_ops = &vfe_parent_dev_ops,
>> +			.formats = &csid_formats_gen2
>> +		}
>> +	},
>> +	/* CSID2 */
>> +	{
>> +		.regulators = {},
>> +
>> +		.clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 0 },
>> +				{ 380000000, 510000000, 637000000, 760000000 }
>> +		},
>> +
>> +		.reg = { "csid2" },
>> +		.interrupt = { "csid2" },
>> +		.csid = {
>> +			.is_lite = false,
>> +			.hw_ops = &csid_ops_gen2,
>> +			.parent_dev_ops = &vfe_parent_dev_ops,
>> +			.formats = &csid_formats_gen2
>> +		}
>> +	},
>> +	/* CSID3 */
>> +	{
>> +		.regulators = {},
>> +
>> +		.clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 0 },
>> +				{ 320000000, 400000000, 480000000, 600000000 }
>> +		},
>> +
>> +		.reg = { "csid_lite0" },
>> +		.interrupt = { "csid_lite0" },
>> +		.csid = {
>> +			.is_lite = true,
>> +			.hw_ops = &csid_ops_gen2,
>> +			.parent_dev_ops = &vfe_parent_dev_ops,
>> +			.formats = &csid_formats_gen2
>> +		}
>> +	},
>> +	/* CSID4 */
>> +	{
>> +		.regulators = {},
>> +
>> +		.clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
>> +		.clock_rate = { { 300000000, 400000000 },
>> +				{ 0 },
>> +				{ 320000000, 400000000, 480000000, 600000000 }
>> +		},
>> +
>> +		.reg = { "csid_lite1" },
>> +		.interrupt = { "csid_lite1" },
>> +		.csid = {
>> +			.is_lite = true,
>> +			.hw_ops = &csid_ops_gen2,
>> +			.parent_dev_ops = &vfe_parent_dev_ops,
>> +			.formats = &csid_formats_gen2
>> +		}
>> +	},
>> +};
>> +
>> +static const struct camss_subdev_resources vfe_res_7280[] = {
>> +	/* VFE0 */
>> +	{
>> +		.regulators = {},
>> +
>> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0",
>> +			   "vfe0_axi", "gcc_cam_hf_axi" },
>> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
>> +				{ 80000000 },
>> +				{ 0 },
>> +				{ 380000000, 510000000, 637000000, 760000000 },
>> +				{ 0 },
>> +				{ 0 } },
>> +
>> +		.reg = { "vfe0" },
>> +		.interrupt = { "vfe0" },
>> +		.vfe = {
>> +			.line_num = 3,
>> +			.is_lite = false,
>> +			.has_pd = true,
>> +			.pd_name = "ife0",
>> +			.hw_ops = &vfe_ops_170,
>> +			.formats_rdi = &vfe_formats_rdi_845,
>> +			.formats_pix = &vfe_formats_pix_845
>> +		}
>> +	},
>> +	/* VFE1 */
>> +	{
>> +		.regulators = {},
>> +
>> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe1",
>> +			   "vfe1_axi", "gcc_cam_hf_axi" },
>> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
>> +				{ 80000000 },
>> +				{ 0 },
>> +				{ 380000000, 510000000, 637000000, 760000000 },
>> +				{ 0 },
>> +				{ 0 } },
>> +
>> +		.reg = { "vfe1" },
>> +		.interrupt = { "vfe1" },
>> +		.vfe = {
>> +			.line_num = 3,
>> +			.is_lite = false,
>> +			.has_pd = true,
>> +			.pd_name = "ife1",
>> +			.hw_ops = &vfe_ops_170,
>> +			.formats_rdi = &vfe_formats_rdi_845,
>> +			.formats_pix = &vfe_formats_pix_845
>> +		}
>> +	},
>> +	/* VFE2 */
>> +	{
>> +		.regulators = {},
>> +
>> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe2",
>> +			   "vfe2_axi", "gcc_cam_hf_axi" },
>> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
>> +				{ 80000000 },
>> +				{ 0 },
>> +				{ 380000000, 510000000, 637000000, 760000000 },
>> +				{ 0 },
>> +				{ 0 } },
>> +
>> +		.reg = { "vfe2" },
>> +		.interrupt = { "vfe2" },
>> +		.vfe = {
>> +			.line_num = 3,
>> +			.is_lite = false,
>> +			.hw_ops = &vfe_ops_170,
>> +			.has_pd = true,
>> +			.pd_name = "ife2",
>> +			.formats_rdi = &vfe_formats_rdi_845,
>> +			.formats_pix = &vfe_formats_pix_845
>> +		}
>> +	},
>> +	/* VFE3 (lite) */
>> +	{
>> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
>> +			   "vfe_lite0", "gcc_cam_hf_axi" },
>> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
>> +				{ 80000000 },
>> +				{ 0 },
>> +				{ 320000000, 400000000, 480000000, 600000000 },
>> +				{ 0 } },
>> +
>> +		.regulators = {},
>> +		.reg = { "vfe_lite0" },
>> +		.interrupt = { "vfe_lite0" },
>> +		.vfe = {
>> +			.line_num = 4,
>> +			.is_lite = true,
>> +			.hw_ops = &vfe_ops_170,
>> +			.formats_rdi = &vfe_formats_rdi_845,
>> +			.formats_pix = &vfe_formats_pix_845
>> +		}
>> +	},
>> +	/* VFE4 (lite) */
>> +	{
>> +		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
>> +			   "vfe_lite1", "gcc_cam_hf_axi" },
>> +		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
>> +				{ 80000000 },
>> +				{ 0 },
>> +				{ 320000000, 400000000, 480000000, 600000000 },
>> +				{ 0 } },
>> +
>> +		.regulators = {},
>> +		.reg = { "vfe_lite1" },
>> +		.interrupt = { "vfe_lite1" },
>> +		.vfe = {
>> +			.line_num = 4,
>> +			.is_lite = true,
>> +			.hw_ops = &vfe_ops_170,
>> +			.formats_rdi = &vfe_formats_rdi_845,
>> +			.formats_pix = &vfe_formats_pix_845
>> +		}
>> +	},
>> +};
>> +
>> +static const struct resources_icc icc_res_sc7280[] = {
>> +	{
>> +		.name = "ahb",
>> +		.icc_bw_tbl.avg = 38400,
>> +		.icc_bw_tbl.peak = 76800,
>> +	},
>> +	{
>> +		.name = "hf_0",
>> +		.icc_bw_tbl.avg = 2097152,
>> +		.icc_bw_tbl.peak = 2097152,
>> +	},
>> +};
>> +
>>   static const struct camss_subdev_resources csiphy_res_sc8280xp[] = {
>>   	/* CSIPHY0 */
>>   	{
>> @@ -2622,10 +2926,25 @@ static const struct camss_resources sc8280xp_resources = {
>>   	.link_entities = camss_link_entities
>>   };
>>   
>> +static const struct camss_resources sc7280_resources = {
>> +	.version = CAMSS_7280,
>> +	.pd_name = "top",
>> +	.csiphy_res = csiphy_res_7280,
>> +	.csid_res = csid_res_7280,
>> +	.vfe_res = vfe_res_7280,
>> +	.icc_res = icc_res_sc7280,
>> +	.icc_path_num = ARRAY_SIZE(icc_res_sc7280),
>> +	.csiphy_num = ARRAY_SIZE(csiphy_res_7280),
>> +	.csid_num = ARRAY_SIZE(csid_res_7280),
>> +	.vfe_num = ARRAY_SIZE(vfe_res_7280),
>> +	.link_entities = camss_link_entities
>> +};
>> +
>>   static const struct of_device_id camss_dt_match[] = {
>>   	{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
>>   	{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
>>   	{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
>> +	{ .compatible = "qcom,sc7280-camss", .data = &sc7280_resources },
>>   	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
>>   	{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
>>   	{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
>> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
>> index ffce0a0edbc5..9a046eea334f 100644
>> --- a/drivers/media/platform/qcom/camss/camss.h
>> +++ b/drivers/media/platform/qcom/camss/camss.h
>> @@ -78,6 +78,7 @@ enum pm_domain {
>>   
>>   enum camss_version {
>>   	CAMSS_660,
>> +	CAMSS_7280,
>>   	CAMSS_8x16,
>>   	CAMSS_8x53,
>>   	CAMSS_8x96,


From pZ010001011111 at proton.me  Fri Dec  6 11:26:10 2024
From: pZ010001011111 at proton.me (Piotr Zalewski)
Date: Fri, 06 Dec 2024 19:26:10 +0000
Subject: [PATCH drm-misc-next] rockchip/drm: vop2: don't check color_mgmt_changed in atomic_enable
Message-ID: <20241206192013.342692-3-pZ010001011111@proton.me>

Remove color_mgmt_changed check from vop2_crtc_atomic_try_set_gamma to
allow gamma LUT rewrite during modeset when coming out of suspend. Add
a check for color_mgmt_changed directly in vop2_crtc_atomic_flush.

This patch fixes the patch adding gamma LUT support for vop2 [1].

[1] https://lore.kernel.org/linux-rockchip/20241101185545.559090-3-pZ010001011111 at proton.me/

Suggested-by: Andy Yan <andy.yan at rock-chips.com>
Signed-off-by: Piotr Zalewski <pZ010001011111 at proton.me>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0c8ec7220fbe..d259f1c6571d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1601,7 +1601,7 @@ static void vop2_crtc_atomic_try_set_gamma(struct vop2 *vop2,
 					   struct drm_crtc *crtc,
 					   struct drm_crtc_state *crtc_state)
 {
-	if (!vop2->lut_regs || !crtc_state->color_mgmt_changed)
+	if (!vop2->lut_regs)
 		return;
 
 	if (!crtc_state->gamma_lut) {
@@ -2669,7 +2669,7 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
 	struct vop2 *vop2 = vp->vop2;
 
 	/* In case of modeset, gamma lut update already happened in atomic enable */
-	if (!drm_atomic_crtc_needs_modeset(crtc_state))
+	if (!drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->color_mgmt_changed)
 		vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state);
 
 	vop2_post_config(crtc);
-- 
2.47.1




From quic_vikramsa at quicinc.com  Fri Dec  6 11:27:50 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Sat, 7 Dec 2024 00:57:50 +0530
Subject: [PATCH v7 4/5] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <e586b76f-50a7-47cc-9ce6-a37f9b53262f@oss.qualcomm.com>
References: <20241204100003.300123-1-quic_vikramsa@quicinc.com>
 <20241204100003.300123-5-quic_vikramsa@quicinc.com>
 <e586b76f-50a7-47cc-9ce6-a37f9b53262f@oss.qualcomm.com>
Message-ID: <106b1945-e288-4522-8567-90cadcbc9148@quicinc.com>


On 12/5/2024 9:58 PM, Konrad Dybcio wrote:
> On 4.12.2024 11:00 AM, Vikram Sharma wrote:
>> Add changes to support the camera subsystem on the SC7280.
>>
>> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
>> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
>> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
>> ---
> [...]
>
> (isp@ as mentioned)
Hi Konrad,

Thanks for your review and comments.
I have posted V8 addressing these comments.

Best Regards,
Vikram

>
>> +			interconnects = <&gem_noc  MASTER_APPSS_PROC 0 &cnoc2 SLAVE_CAMERA_CFG 0>,
> QCOM_ICC_TAG_ACTIVE_ONLY
>
>> +					<&mmss_noc MASTER_CAMNOC_HF  0 &mc_virt SLAVE_EBI1     0>;
> QCOM_ICC_TAG_ALWAYS
>
>> +			interconnect-names = "ahb", "hf_0";
>> +
>> +			iommus = <&apps_smmu 0x800 0x4e0>;
>> +
>> +			power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
>> +					<&camcc CAM_CC_IFE_1_GDSC>,
>> +					<&camcc CAM_CC_IFE_2_GDSC>,
>> +					<&camcc CAM_CC_TITAN_TOP_GDSC>;
>> +			power-domain-names = "ife0", "ife1", "ife2", "top";
> vertical list, please
>
> Konrad


From w at 1wt.eu  Fri Dec  6 11:38:36 2024
From: w at 1wt.eu (Willy Tarreau)
Date: Fri, 6 Dec 2024 20:38:36 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
Message-ID: <20241206193836.GA26860@1wt.eu>

On Fri, Dec 06, 2024 at 11:15:20AM -0800, Linus Torvalds wrote:
> On Fri, 6 Dec 2024 at 11:07, David Laight <David.Laight at aculab.com> wrote:
> >
> > I'm missing the compiler version and options to generate the error.
> 
> Just -Wall with most recent gcc versions seems to do it. At least I
> can repro it with gcc-14.2.1 and something silly like this:
> 
>   $ cat t.c
>   int fn(int a) { return (a<<2)?1:2; }
>   $ gcc -Wall -S t.c
>   t.c: In function 'fn':
>   t.c:1:26: warning: '<<' in boolean context, did you mean '<'?
> [-Wint-in-bool-context]
> 
> > Does a '+ 0' help?  "(var << 2) + 0 ? 0 : 0"
> 
> Yeah, that actually works.
> 
> And "+0" is nice in that it should work in any context.

I've already used "+0" to shut certain warnings, I don't really remember
which one, but also remember it was OK everywhere I needed.

Another trick I've been using to shut up the compiler is a cast via typeof
and an intermediary variable:

  #define shut_up(expr)                           \
          ({                                      \
                  typeof(expr) _expr_ = expr;     \
                  _expr_;                         \
                  })
  
  int fn1(int a)
  {
          return shut_up(a << 2) ? 1 : 2;
  }
  
  int fn2(int a)
  {
          return (a << 2) ? 1 : 2;
  }

  $ gcc -Wall -S t2.c
  t2.c: In function 'fn2':
  t2.c:15:19: warning: '<<' in boolean context, did you mean '<'? [-Wint-in-bool-context]
     15 |         return (a << 2) ? 1 : 2;
        |                ~~~^~~~~

See ? It only complains on fn2() but not fn1(). Similarly I found it
to be quite portable (at least I don't remember seeing it fail on me).
It produces the exact same code, except at -O0 where it does really
create a local variable.

Willy


From David.Laight at ACULAB.COM  Fri Dec  6 11:38:40 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 19:38:40 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
Message-ID: <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>

From: Linus Torvalds
> Sent: 06 December 2024 19:15
> On Fri, 6 Dec 2024 at 11:07, David Laight <David.Laight at aculab.com> wrote:
> >
> > I'm missing the compiler version and options to generate the error.
> 
> Just -Wall with most recent gcc versions seems to do it. At least I
> can repro it with gcc-14.2.1 and something silly like this:

I may have just missed golbolt returning a warning.
...
> > Does a '+ 0' help?  "(var << 2) + 0 ? 0 : 0"
> 
> Yeah, that actually works.
> 
> And "+0" is nice in that it should work in any context.

Unless it falls foul of the clang test for arthmetic on NULL pointers.
(I'm sure that is only a problem if NULL isn't the all-zero bit pattern.
And pretty much no C code has ever been 'that portable'.)

Adding 0 can also help when compliers are being picky about enums.
Since none have (yet) made them more like a 32bit pointer to a one
byte structure (or the Pascal enum).
In case the relevant people are reading this, maybe only do any
non-integer warnings for named enums?

> > #define const_NULL(x) _Generic(0 ? (x) : (char *)0, char *: 1, void *: 0)
> > #define const_true(x) const_NULL((x) ? NULL : (void *)1L))
> > #define const_expr(x) const_NULL((x) ? NULL : NULL))
> > I send this morning.
> > Needs 's/char/struct kjkjkjkjui/' applied.
> 
> Oh Christ. You really are taking this whole ugly to another level.

I sort of liked that version in a perverse sort of way.
It does give you a simple test for NULL (unless you've used 'struct kjkjkjkjui').

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From David.Laight at ACULAB.COM  Fri Dec  6 11:43:39 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 19:43:39 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <20241206193836.GA26860@1wt.eu>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
 <20241206193836.GA26860@1wt.eu>
Message-ID: <8f4b7d1bfbd84885bddf4cc1dfb9ce43@AcuMS.aculab.com>

From: Willy Tarreau
> Sent: 06 December 2024 19:39
> On Fri, Dec 06, 2024 at 11:15:20AM -0800, Linus Torvalds wrote:
> > On Fri, 6 Dec 2024 at 11:07, David Laight <David.Laight at aculab.com> wrote:
> > >
> > > I'm missing the compiler version and options to generate the error.
> >
> > Just -Wall with most recent gcc versions seems to do it. At least I
> > can repro it with gcc-14.2.1 and something silly like this:
> >
> >   $ cat t.c
> >   int fn(int a) { return (a<<2)?1:2; }
> >   $ gcc -Wall -S t.c
> >   t.c: In function 'fn':
> >   t.c:1:26: warning: '<<' in boolean context, did you mean '<'?
> > [-Wint-in-bool-context]
> >
> > > Does a '+ 0' help?  "(var << 2) + 0 ? 0 : 0"
> >
> > Yeah, that actually works.
> >
> > And "+0" is nice in that it should work in any context.
> 
> I've already used "+0" to shut certain warnings, I don't really remember
> which one, but also remember it was OK everywhere I needed.

I've often used +0u when -Wsign-compare is enabled.
Much safer than a cast.

> 
> Another trick I've been using to shut up the compiler is a cast via typeof
> and an intermediary variable:
> 
>   #define shut_up(expr)                           \
>           ({                                      \
>                   typeof(expr) _expr_ = expr;     \
>                   _expr_;                         \
>                   })

That is like OPTIMISER_HIDE_VAR() and can't be used in a 'constant integer expression'.

I suspect it also has the same nasty habit of adding an extra register move.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From daniel.lezcano at linaro.org  Fri Dec  6 11:50:15 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 6 Dec 2024 20:50:15 +0100
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <vxqi23hxw7bmtfs5wk3u7szganpv5aa74b26xrvpmbehkltodw@dpum7zrxdz44>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-3-tudor.ambarus@linaro.org>
 <ce757b8e-4e6c-4ba9-9483-b57e6e230fdf@linaro.org>
 <vxqi23hxw7bmtfs5wk3u7szganpv5aa74b26xrvpmbehkltodw@dpum7zrxdz44>
Message-ID: <2eedbbe1-6b4c-427b-a369-5b08dc27deaf@linaro.org>

On 12/6/24 14:28, Krzysztof Kozlowski wrote:
> On Fri, Dec 06, 2024 at 12:39:56AM +0100, Daniel Lezcano wrote:
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +
>>> +config EXYNOS_ACPM_PROTOCOL
>>> +	tristate "Exynos Alive Clock and Power Manager (ACPM) Message Protocol"
>>
>> Given the importance of this driver where a lot of PM services rely on, does
>> it really make sense to allow it as a module ?
>>
>> Some PM services may be needed very early in the boot process
>>
> 
> If it works as module e.g. on Android, it is beneficial. I think the
> platform was booting fine without it, at least to some shell, so I can
> imagine this can be loaded a bit later.

Usually the firmware sets the frequency to the maximum in order to boot 
the kernel as fast as possible. That may lead to thermal issues at boot 
time where the thermal framework won't be able to kick in as some 
components will depends on ACPM while the system stays at its highest 
performance state.


-- 
<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 christian.loehle at arm.com  Fri Dec  6 11:50:55 2024
From: christian.loehle at arm.com (Christian Loehle)
Date: Fri, 6 Dec 2024 19:50:55 +0000
Subject: [PATCH] spi: rockchip: Fix PM runtime count on no-op cs
Message-ID: <1f2b3af4-2b7a-4ac8-ab95-c80120ebf44c@arm.com>

The early bail out that caused an out-of-bounds write was removed with
commit 5c018e378f91 ("spi: spi-rockchip: Fix out of bounds array
access")
Unfortunately that caused the PM runtime count to be unbalanced and
underflowed on the first call. To fix that reintroduce a no-op check
by reading the register directly.

Cc: stable at vger.kernel.org
Fixes: 5c018e378f91 ("spi: spi-rockchip: Fix out of bounds array access")
Signed-off-by: Christian Loehle <christian.loehle at arm.com>
---
Not particularly happy with it, it's just the most straightforward
fix for the issue at hand. I couldn't quite convince myself that
no-op rockchip_spi_set_cs() are 100% ruled out just from spi.c after
the first call either, but maybe someone more familiar with the code
can. I have only seen the issue for the first call / during boot FWIW.
Any more elegant fix suggestions welcome! The other host controller
drivers don't need the read before CS change, so this shouldn't really
either.

 drivers/spi/spi-rockchip.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 864e58167417..1bc012fce7cb 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -241,6 +241,20 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
 	struct spi_controller *ctlr = spi->controller;
 	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
 	bool cs_asserted = spi->mode & SPI_CS_HIGH ? enable : !enable;
+	bool cs_actual;
+
+	/*
+	 * SPI subsystem tries to avoid no-op calls that would break the PM
+	 * refcount below. It can't however for the first time it is used.
+	 * To detect this case we read it here and bail out early for no-ops.
+	 */
+	if (spi_get_csgpiod(spi, 0))
+		cs_actual = !!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & 1);
+	else
+		cs_actual = !!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) &
+			       BIT(spi_get_chipselect(spi, 0)));
+	if (unlikely(cs_actual == cs_asserted))
+		return;
 
 	if (cs_asserted) {
 		/* Keep things powered as long as CS is asserted */
-- 
2.34.1


From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:55 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:55 -0700
Subject: [PATCH v3 10/13] ARM: dts: at91: Add sama7d65 pinmux
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <a8f880b89cd4470526a2955a0b6aaaaa24ba65b8.1733505542.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add sama7d65 pin descriptions.

Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 .../arm/boot/dts/microchip/sama7d65-pinfunc.h | 947 ++++++++++++++++++
 1 file changed, 947 insertions(+)
 create mode 100644 arch/arm/boot/dts/microchip/sama7d65-pinfunc.h

diff --git a/arch/arm/boot/dts/microchip/sama7d65-pinfunc.h b/arch/arm/boot/dts/microchip/sama7d65-pinfunc.h
new file mode 100644
index 000000000000..c591f333cacb
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/sama7d65-pinfunc.h
@@ -0,0 +1,947 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+#define PINMUX_PIN(no, func, ioset) \
+(((no) & 0xffff) | (((func) & 0xf) << 16) | (((ioset) & 0xff) << 20))
+
+#define PIN_PA0				0
+#define PIN_PA0__GPIO			PINMUX_PIN(PIN_PA0, 0, 0)
+#define PIN_PA0__SDMMC0_CK		PINMUX_PIN(PIN_PA0, 1, 1)
+#define PIN_PA0__FLEXCOM3_IO0		PINMUX_PIN(PIN_PA0, 2, 1)
+#define PIN_PA0__NWER0			PINMUX_PIN(PIN_PA0, 3, 1)
+
+#define PIN_PA1				1
+#define PIN_PA1__GPIO			PINMUX_PIN(PIN_PA1, 0, 0)
+#define PIN_PA1__SDMMC0_CMD		PINMUX_PIN(PIN_PA1, 1, 1)
+#define PIN_PA1__FLEXCOM3_IO1		PINMUX_PIN(PIN_PA1, 2, 1)
+#define PIN_PA1__A21			PINMUX_PIN(PIN_PA1, 3, 1)
+
+#define PIN_PA2				2
+#define PIN_PA2__GPIO			PINMUX_PIN(PIN_PA2, 0, 0)
+#define PIN_PA2__SDMMC0_RSTN		PINMUX_PIN(PIN_PA2, 1, 1)
+#define PIN_PA2__FLEXCOM3_IO2		PINMUX_PIN(PIN_PA2, 2, 1)
+#define PIN_PA2__A22			PINMUX_PIN(PIN_PA2, 3, 1)
+
+#define PIN_PA3				3
+#define PIN_PA3__GPIO			PINMUX_PIN(PIN_PA3, 0, 0)
+#define PIN_PA3__SDMMC0_DAT0		PINMUX_PIN(PIN_PA3, 1, 1)
+#define PIN_PA3__FLEXCOM3_IO3		PINMUX_PIN(PIN_PA3, 2, 1)
+#define PIN_PA3__D0			PINMUX_PIN(PIN_PA3, 3, 1)
+
+#define PIN_PA4				4
+#define PIN_PA4__GPIO			PINMUX_PIN(PIN_PA4, 0, 0)
+#define PIN_PA4__SDMMC0_DAT1		PINMUX_PIN(PIN_PA4, 1, 1)
+#define PIN_PA4__FLEXCOM3_IO4		PINMUX_PIN(PIN_PA4, 2, 1)
+#define PIN_PA4__D1			PINMUX_PIN(PIN_PA4, 3, 1)
+
+#define PIN_PA5				5
+#define PIN_PA5__GPIO			PINMUX_PIN(PIN_PA5, 0, 0)
+#define PIN_PA5__SDMMC0_DAT4		PINMUX_PIN(PIN_PA5, 1, 1)
+#define PIN_PA5__FLEXCOM2_IO0		PINMUX_PIN(PIN_PA5, 2, 3)
+#define PIN_PA5__D4			PINMUX_PIN(PIN_PA5, 3, 1)
+#define PIN_PA5__TCLK4			PINMUX_PIN(PIN_PA5, 6, 3)
+
+#define PIN_PA6				6
+#define PIN_PA6__GPIO			PINMUX_PIN(PIN_PA6, 0, 0)
+#define PIN_PA6__SDMMC0_DAT5		PINMUX_PIN(PIN_PA6, 1, 1)
+#define PIN_PA6__FLEXCOM2_IO1		PINMUX_PIN(PIN_PA6, 2, 3)
+#define PIN_PA6__D5			PINMUX_PIN(PIN_PA6, 3, 1)
+#define PIN_PA6__TIOB4			PINMUX_PIN(PIN_PA6, 6, 3)
+
+#define PIN_PA7				7
+#define PIN_PA7__GPIO			PINMUX_PIN(PIN_PA7, 0, 0)
+#define PIN_PA7__SDMMC0_DAT6		PINMUX_PIN(PIN_PA7, 1, 1)
+#define PIN_PA7__FLEXCOM2_IO2		PINMUX_PIN(PIN_PA7, 2, 3)
+#define PIN_PA7__D6			PINMUX_PIN(PIN_PA7, 3, 1)
+#define PIN_PA7__TIOA4			PINMUX_PIN(PIN_PA7, 6, 3)
+
+#define PIN_PA8				8
+#define PIN_PA8__GPIO			PINMUX_PIN(PIN_PA8, 0, 0)
+#define PIN_PA8__SDMMC0_DAT7		PINMUX_PIN(PIN_PA8, 1, 1)
+#define PIN_PA8__FLEXCOM2_IO3		PINMUX_PIN(PIN_PA8, 2, 3)
+#define PIN_PA8__D7			PINMUX_PIN(PIN_PA8, 3, 1)
+#define PIN_PA8__TIOA5			PINMUX_PIN(PIN_PA8, 6, 3)
+
+#define PIN_PA9				9
+#define PIN_PA9__GPIO			PINMUX_PIN(PIN_PA9, 0, 0)
+#define PIN_PA9__SDMMC0_DAT2		PINMUX_PIN(PIN_PA9, 1, 1)
+#define PIN_PA9__FLEXCOM0_IO2		PINMUX_PIN(PIN_PA9, 2, 1)
+#define PIN_PA9__D2			PINMUX_PIN(PIN_PA9, 3, 1)
+#define PIN_PA9__TIOB5			PINMUX_PIN(PIN_PA9, 6, 3)
+
+#define PIN_PA10			10
+#define PIN_PA10__GPIO			PINMUX_PIN(PIN_PA10, 0, 0)
+#define PIN_PA10__SDMMC0_DAT3		PINMUX_PIN(PIN_PA10, 1, 1)
+#define PIN_PA10__FLEXCOM0_IO3		PINMUX_PIN(PIN_PA10, 2, 1)
+#define PIN_PA10__D3			PINMUX_PIN(PIN_PA10, 3, 1)
+#define PIN_PA10__TCLK5			PINMUX_PIN(PIN_PA10, 6, 3)
+
+#define PIN_PA11			11
+#define PIN_PA11__GPIO			PINMUX_PIN(PIN_PA11, 0, 0)
+#define PIN_PA11__SDMMC0_DS		PINMUX_PIN(PIN_PA11, 1, 1)
+#define PIN_PA11__FLEXCOM0_IO4		PINMUX_PIN(PIN_PA11, 2, 1)
+#define PIN_PA11__NANDRDY		PINMUX_PIN(PIN_PA11, 3, 1)
+#define PIN_PA11__TIOB3			PINMUX_PIN(PIN_PA11, 6, 3)
+
+#define PIN_PA12			12
+#define PIN_PA12__GPIO			PINMUX_PIN(PIN_PA12, 0, 0)
+#define PIN_PA12__FLEXCOM0_IO0		PINMUX_PIN(PIN_PA12, 2, 1)
+#define PIN_PA12__NRD			PINMUX_PIN(PIN_PA12, 3, 1)
+#define PIN_PA12__PCK0			PINMUX_PIN(PIN_PA12, 4, 1)
+#define PIN_PA12__EXT_IRQ0		PINMUX_PIN(PIN_PA12, 5, 1)
+#define PIN_PA12__TIOA3			PINMUX_PIN(PIN_PA12, 6, 3)
+
+#define PIN_PA13			13
+#define PIN_PA13__GPIO			PINMUX_PIN(PIN_PA13, 0, 0)
+#define PIN_PA13__FLEXCOM0_IO1		PINMUX_PIN(PIN_PA13, 2, 1)
+#define PIN_PA13__NCS0			PINMUX_PIN(PIN_PA13, 3, 1)
+#define PIN_PA13__PCK1			PINMUX_PIN(PIN_PA13, 4, 1)
+#define PIN_PA13__TCLK3			PINMUX_PIN(PIN_PA13, 6, 3)
+
+#define PIN_PA14			14
+#define PIN_PA14__GPIO			PINMUX_PIN(PIN_PA14, 0, 0)
+#define PIN_PA14__FLEXCOM4_IO4		PINMUX_PIN(PIN_PA14, 1, 1)
+#define PIN_PA14__SDMMC0_WP		PINMUX_PIN(PIN_PA14, 2, 1)
+#define PIN_PA14__FLEXCOM3_IO0		PINMUX_PIN(PIN_PA14, 3, 4)
+
+#define PIN_PA15			15
+#define PIN_PA15__GPIO			PINMUX_PIN(PIN_PA15, 0, 0)
+#define PIN_PA15__FLEXCOM4_IO3		PINMUX_PIN(PIN_PA15, 1, 1)
+#define PIN_PA15__SDMMC0_1V8SEL		PINMUX_PIN(PIN_PA15, 2, 1)
+#define PIN_PA15__FLEXCOM3_IO1		PINMUX_PIN(PIN_PA15, 3, 4)
+
+#define PIN_PA16			16
+#define PIN_PA16__GPIO			PINMUX_PIN(PIN_PA16, 0, 0)
+#define PIN_PA16__FLEXCOM4_IO2		PINMUX_PIN(PIN_PA16, 1, 1)
+#define PIN_PA16__SDMMCo_CD		PINMUX_PIN(PIN_PA16, 2, 1)
+#define PIN_PA16__PCK2			PINMUX_PIN(PIN_PA16, 4, 1)
+#define PIN_PA16__EXT_IRQ1		PINMUX_PIN(PIN_PA16, 5, 1)
+
+#define PIN_PA17			17
+#define PIN_PA17__GPIO			PINMUX_PIN(PIN_PA17, 0, 0)
+#define PIN_PA17__FLEXCOM4_IO1		PINMUX_PIN(PIN_PA17, 1, 1)
+
+#define PIN_PA18			18
+#define PIN_PA18__GPIO			PINMUX_PIN(PIN_PA18, 0, 0)
+#define PIN_PA18__FLEXCOM4_IO0		PINMUX_PIN(PIN_PA18, 1, 1)
+
+#define PIN_PA19			19
+#define PIN_PA19__GPIO			PINMUX_PIN(PIN_PA19, 0, 0)
+#define PIN_PA19__TK0			PINMUX_PIN(PIN_PA19, 1, 1)
+#define PIN_PA19__FLEXCOM4_IO5		PINMUX_PIN(PIN_PA19, 3, 1)
+#define PIN_PA19__PWML0			PINMUX_PIN(PIN_PA19, 4, 3)
+
+#define PIN_PA20			20
+#define PIN_PA20__GPIO			PINMUX_PIN(PIN_PA20, 0, 0)
+#define PIN_PA20__TD0			PINMUX_PIN(PIN_PA20, 1, 1)
+#define PIN_PA20__FLEXCOM3_IO4		PINMUX_PIN(PIN_PA20, 2, 2)
+#define PIN_PA20__FLEXCOM4_IO6		PINMUX_PIN(PIN_PA20, 3, 1)
+#define PIN_PA20__PWMH0			PINMUX_PIN(PIN_PA20, 4, 3)
+
+#define PIN_PA21			21
+#define PIN_PA21__GPIO			PINMUX_PIN(PIN_PA21, 0, 0)
+#define PIN_PA21__TF0			PINMUX_PIN(PIN_PA21, 1, 1)
+#define PIN_PA21__FLEXCOM3_IO3		PINMUX_PIN(PIN_PA21, 2, 2)
+#define PIN_PA21__PWML1			PINMUX_PIN(PIN_PA21, 4, 3)
+
+#define PIN_PA22			22
+#define PIN_PA22__GPIO			PINMUX_PIN(PIN_PA22, 0, 0)
+#define PIN_PA22__RD0			PINMUX_PIN(PIN_PA22, 1, 1)
+#define PIN_PA22__FLEXCOM3_IO2		PINMUX_PIN(PIN_PA22, 2, 2)
+#define PIN_PA22__PDMC0_DS1		PINMUX_PIN(PIN_PA22, 3, 1)
+#define PIN_PA22__PWMH1			PINMUX_PIN(PIN_PA22, 4, 3)
+
+#define PIN_PA23			23
+#define PIN_PA23__GPIO			PINMUX_PIN(PIN_PA23, 0, 0)
+#define PIN_PA23__RK0			PINMUX_PIN(PIN_PA23, 1, 1)
+#define PIN_PA23__FLEXCOM3_IO1		PINMUX_PIN(PIN_PA23, 2, 2)
+#define PIN_PA23__PDMC0_CLK		PINMUX_PIN(PIN_PA23, 3, 1)
+#define PIN_PA23__PWML2			PINMUX_PIN(PIN_PA23, 4, 3)
+
+#define PIN_PA24			24
+#define PIN_PA24__GPIO			PINMUX_PIN(PIN_PA24, 0, 0)
+#define PIN_PA24__RF0			PINMUX_PIN(PIN_PA24, 1, 1)
+#define PIN_PA24__FLEXCOM3_IO0		PINMUX_PIN(PIN_PA24, 2, 2)
+#define PIN_PA24__PDMC0_DS0		PINMUX_PIN(PIN_PA24, 3, 1)
+#define PIN_PA24__PWMH2			PINMUX_PIN(PIN_PA24, 4, 3)
+
+#define PIN_PA25			25
+#define PIN_PA25__GPIO			PINMUX_PIN(PIN_PA25, 0, 0)
+#define PIN_PA25__G0_TXCTL		PINMUX_PIN(PIN_PA25, 1, 1)
+#define PIN_PA25__FLEXCOM6_IO2		PINMUX_PIN(PIN_PA25, 2, 1)
+
+#define PIN_PA26			26
+#define PIN_PA26__GPIO			PINMUX_PIN(PIN_PA26, 0, 0)
+#define PIN_PA26__G0_TX0		PINMUX_PIN(PIN_PA26, 1, 1)
+#define PIN_PA26__FLEXCOM6_IO3		PINMUX_PIN(PIN_PA26, 2, 1)
+
+#define PIN_PA27			27
+#define PIN_PA27__GPIO			PINMUX_PIN(PIN_PA27, 0, 0)
+#define PIN_PA27__G0_TX1		PINMUX_PIN(PIN_PA27, 1, 1)
+#define PIN_PA27__FLEXCOM6_IO4		PINMUX_PIN(PIN_PA27, 2, 1)
+
+#define PIN_PA28			28
+#define PIN_PA28__GPIO			PINMUX_PIN(PIN_PA28, 0, 0)
+#define PIN_PA28__G0_RXCTL		PINMUX_PIN(PIN_PA28, 1, 1)
+#define PIN_PA28__FLEXCOM6_IO0		PINMUX_PIN(PIN_PA28, 2, 1)
+
+#define PIN_PA29			29
+#define PIN_PA29__GPIO			PINMUX_PIN(PIN_PA29, 0, 0)
+#define PIN_PA29__G0_RX0		PINMUX_PIN(PIN_PA29, 1, 1)
+#define PIN_PA29__FLEXCOM6_IO1		PINMUX_PIN(PIN_PA29, 2, 1)
+
+#define PIN_PA30			30
+#define PIN_PA30__GPIO			PINMUX_PIN(PIN_PA30, 0, 0)
+#define PIN_PA30__G0_RX1		PINMUX_PIN(PIN_PA30, 1, 1)
+#define PIN_PA30__FLEXCOM8_IO0		PINMUX_PIN(PIN_PA30, 2, 1)
+
+#define PIN_PA31			31
+#define PIN_PA31__GPIO			PINMUX_PIN(PIN_PA31, 0, 0)
+#define PIN_PA31__G0_MDC		PINMUX_PIN(PIN_PA31, 1, 1)
+#define PIN_PA31__FLEXCOM8_IO1		PINMUX_PIN(PIN_PA31, 2, 1)
+
+#define PIN_PB0				32
+#define PIN_PB0__GPIO			PINMUX_PIN(PIN_PB0, 0, 0)
+#define PIN_PB0__G0_MDIO		PINMUX_PIN(PIN_PB0, 1, 1)
+#define PIN_PB0__FLEXCOM8_IO3		PINMUX_PIN(PIN_PB0, 2, 2)
+
+#define PIN_PB1				33
+#define PIN_PB1__GPIO			PINMUX_PIN(PIN_PB1, 0, 0)
+#define PIN_PB1__G0_REFCK		PINMUX_PIN(PIN_PB1, 1, 2)
+#define PIN_PB1__FLEXCOM8_IO2		PINMUX_PIN(PIN_PB1, 2, 1)
+
+#define PIN_PB2				34
+#define PIN_PB2__GPIO			PINMUX_PIN(PIN_PB2, 0, 0)
+#define PIN_PB2__G0_RX2			PINMUX_PIN(PIN_PB2, 1, 1)
+#define PIN_PB2__FLEXCOM8_IO4		PINMUX_PIN(PIN_PB2, 2, 1)
+#define PIN_PB2__G0_RXER		PINMUX_PIN(PIN_PB2, 3, 2)
+#define PIN_PB2__RK0			PINMUX_PIN(PIN_PB2, 4, 2)
+
+#define PIN_PB3				35
+#define PIN_PB3__GPIO			PINMUX_PIN(PIN_PB3, 0, 0)
+#define PIN_PB3__G0_RXCK		PINMUX_PIN(PIN_PB3, 1, 1)
+#define PIN_PB3__FLEXCOM10_IO2		PINMUX_PIN(PIN_PB3, 2, 2)
+#define PIN_PB3__TK0			PINMUX_PIN(PIN_PB3, 4, 2)
+
+#define PIN_PB4				36
+#define PIN_PB4__GPIO			PINMUX_PIN(PIN_PB4, 0, 0)
+#define PIN_PB4__G0_TX2			PINMUX_PIN(PIN_PB4, 1, 1)
+#define PIN_PB4__FLEXCOM10_IO3		PINMUX_PIN(PIN_PB4, 2, 2)
+#define PIN_PB4__TF0			PINMUX_PIN(PIN_PB4, 4, 2)
+
+#define PIN_PB5				37
+#define PIN_PB5__GPIO			PINMUX_PIN(PIN_PB5, 0, 0)
+#define PIN_PB5__G0_TX3			PINMUX_PIN(PIN_PB5, 1, 1)
+#define PIN_PB5__FLEXCOM10_IO4		PINMUX_PIN(PIN_PB5, 2, 1)
+#define PIN_PB5__TD0			PINMUX_PIN(PIN_PB5, 4, 2)
+
+#define PIN_PB6				38
+#define PIN_PB6__GPIO			PINMUX_PIN(PIN_PB6, 0, 0)
+#define PIN_PB6__G0_RX3			PINMUX_PIN(PIN_PB6, 1, 1)
+#define PIN_PB6__FLEXCOM10_IO0		PINMUX_PIN(PIN_PB6, 2, 2)
+#define PIN_PB6__RD0			PINMUX_PIN(PIN_PB6, 4, 2)
+
+#define PIN_PB7				39
+#define PIN_PB7__GPIO			PINMUX_PIN(PIN_PB7, 0, 0)
+#define PIN_PB7__G0_TSUCOMP		PINMUX_PIN(PIN_PB7, 1, 1)
+#define PIN_PB7__FLEXCOM10_IO1		PINMUX_PIN(PIN_PB7, 2, 2)
+#define PIN_PB7__ADTRG			PINMUX_PIN(PIN_PB7, 3, 1)
+#define PIN_PB7__RF0			PINMUX_PIN(PIN_PB7, 4, 2)
+
+#define PIN_PB8				40
+#define PIN_PB8__GPIO			PINMUX_PIN(PIN_PB8, 0, 0)
+#define PIN_PB8__QSPI0_IO3		PINMUX_PIN(PIN_PB8, 1, 1)
+#define PIN_PB8__PCK3			PINMUX_PIN(PIN_PB8, 2, 1)
+#define PIN_PB8__FLEXCOM2_IO1		PINMUX_PIN(PIN_PB8, 4, 2)
+
+#define PIN_PB9				41
+#define PIN_PB9__GPIO			PINMUX_PIN(PIN_PB9, 0, 0)
+#define PIN_PB9__QSPI0_IO2		PINMUX_PIN(PIN_PB9, 1, 1)
+#define PIN_PB9__FLEXCOM2_IO0		PINMUX_PIN(PIN_PB9, 4, 2)
+#define PIN_PB9__PWMEXTRG0		PINMUX_PIN(PIN_PB9, 5, 1)
+
+#define PIN_PB10			42
+#define PIN_PB10__GPIO			PINMUX_PIN(PIN_PB10, 0, 0)
+#define PIN_PB10__QSPI0_IO1		PINMUX_PIN(PIN_PB10, 1, 1)
+#define PIN_PB10__FLEXCOM2_IO4		PINMUX_PIN(PIN_PB10, 4, 2)
+#define PIN_PB10__PWMEXTRG1		PINMUX_PIN(PIN_PB10, 5, 1)
+
+#define PIN_PB11			43
+#define PIN_PB11__GPIO			PINMUX_PIN(PIN_PB11, 0, 0)
+#define PIN_PB11__QSPI0_IO0		PINMUX_PIN(PIN_PB11, 1, 1)
+#define PIN_PB11__FLEXCOM2_IO5		PINMUX_PIN(PIN_PB11, 4, 2)
+#define PIN_PB11__PWML3			PINMUX_PIN(PIN_PB11, 5, 1)
+#define PIN_PB11__TIOB3			PINMUX_PIN(PIN_PB11, 6, 2)
+
+#define PIN_PB12			44
+#define PIN_PB12__GPIO			PINMUX_PIN(PIN_PB12, 0, 0)
+#define PIN_PB12__QSPI0_CS		PINMUX_PIN(PIN_PB12, 1, 1)
+#define PIN_PB12__FLEXCOM2_IO3		PINMUX_PIN(PIN_PB12, 4, 2)
+#define PIN_PB12__PWMFI1		PINMUX_PIN(PIN_PB12, 6, 1)
+#define PIN_PB12__TIOA3			PINMUX_PIN(PIN_PB12, 6, 2)
+
+#define PIN_PB13			45
+#define PIN_PB13__GPIO			PINMUX_PIN(PIN_PB13, 0, 0)
+#define PIN_PB13__QSPI0_SCK		PINMUX_PIN(PIN_PB13, 1, 1)
+#define PIN_PB13__FLEXCOM2_IO2		PINMUX_PIN(PIN_PB13, 4, 2)
+#define PIN_PB13__PWMFI0		PINMUX_PIN(PIN_PB13, 5, 1)
+#define PIN_PB13__TCLK3			PINMUX_PIN(PIN_PB13, 6, 2)
+
+#define PIN_PB14			46
+#define PIN_PB14__GPIO			PINMUX_PIN(PIN_PB14, 0, 0)
+#define PIN_PB14__QSPI0_SCKN		PINMUX_PIN(PIN_PB14, 1, 1)
+#define PIN_PB14__QSPI1_SCK		PINMUX_PIN(PIN_PB14, 2, 1)
+#define PIN_PB14__I2SMCC0_CK		PINMUX_PIN(PIN_PB14, 3, 3)
+#define PIN_PB14__FLEXCOM10_IO5		PINMUX_PIN(PIN_PB14, 4, 1)
+#define PIN_PB14__PWMH3			PINMUX_PIN(PIN_PB14, 5, 1)
+#define PIN_PB14__FLEXCOM2_IO1		PINMUX_PIN(PIN_PB14, 7, 4)
+
+#define PIN_PB15			47
+#define PIN_PB15__GPIO			PINMUX_PIN(PIN_PB15, 0, 0)
+#define PIN_PB15__QSPI0_IO4		PINMUX_PIN(PIN_PB15, 1, 1)
+#define PIN_PB15__QSPI1_IO0		PINMUX_PIN(PIN_PB15, 2, 1)
+#define PIN_PB15__I2SMCC0_WS		PINMUX_PIN(PIN_PB15, 3, 3)
+#define PIN_PB15__FLEXCOM10_IO6		PINMUX_PIN(PIN_PB15, 4, 1)
+#define PIN_PB15__PWML0			PINMUX_PIN(PIN_PB15, 5, 1)
+#define PIN_PB15__TCLK4			PINMUX_PIN(PIN_PB15, 6, 2)
+#define PIN_PB15__FLEXCOM2_IO0		PINMUX_PIN(PIN_PB15, 7, 4)
+
+#define PIN_PB16			48
+#define PIN_PB16__GPIO			PINMUX_PIN(PIN_PB16, 0, 0)
+#define PIN_PB16__QSPI0_IO5		PINMUX_PIN(PIN_PB16, 1, 1)
+#define PIN_PB16__QSPI1_IO1		PINMUX_PIN(PIN_PB16, 2, 1)
+#define PIN_PB16__I2SMCC0_DIN0		PINMUX_PIN(PIN_PB16, 3, 3)
+#define PIN_PB16__FLEXCOM10_IO4		PINMUX_PIN(PIN_PB16, 4, 1)
+#define PIN_PB16__PWMH0			PINMUX_PIN(PIN_PB16, 5, 1)
+#define PIN_PB16__TIOB4			PINMUX_PIN(PIN_PB16, 6, 2)
+
+#define PIN_PB17			49
+#define PIN_PB17__GPIO			PINMUX_PIN(PIN_PB17, 0, 0)
+#define PIN_PB17__QSPI0_IO6		PINMUX_PIN(PIN_PB17, 1, 1)
+#define PIN_PB17__QSPI1_IO2		PINMUX_PIN(PIN_PB17, 2, 1)
+#define PIN_PB17__I2SMCC0_DOUT0		PINMUX_PIN(PIN_PB17, 3, 3)
+#define PIN_PB17__FLEXCOM10_IO3		PINMUX_PIN(PIN_PB17, 4, 1)
+#define PIN_PB17__PWML1			PINMUX_PIN(PIN_PB17, 5, 1)
+#define PIN_PB17__TIOA4			PINMUX_PIN(PIN_PB17, 6, 2)
+
+#define PIN_PB18			50
+#define PIN_PB18__GPIO			PINMUX_PIN(PIN_PB18, 0, 0)
+#define PIN_PB18__QSPI0_IO7		PINMUX_PIN(PIN_PB18, 1, 1)
+#define PIN_PB18__QSPI1_IO3		PINMUX_PIN(PIN_PB18, 2, 1)
+#define PIN_PB18__I2SMCC0_MCK		PINMUX_PIN(PIN_PB18, 3, 3)
+#define PIN_PB18__FLEXCOM10_IO2		PINMUX_PIN(PIN_PB18, 4, 1)
+#define PIN_PB18__PWMH1			PINMUX_PIN(PIN_PB18, 5, 1)
+#define PIN_PB18__TIOA5			PINMUX_PIN(PIN_PB18, 6, 2)
+
+#define PIN_PB19			51
+#define PIN_PB19__GPIO			PINMUX_PIN(PIN_PB19, 0, 0)
+#define PIN_PB19__QSPI0_DQS		PINMUX_PIN(PIN_PB19, 1, 1)
+#define PIN_PB19__EXT_IRQ1		PINMUX_PIN(PIN_PB19, 2, 2)
+#define PIN_PB19__PCK4			PINMUX_PIN(PIN_PB19, 3, 1)
+#define PIN_PB19__FLEXCOM10_IO1		PINMUX_PIN(PIN_PB19, 4, 1)
+#define PIN_PB19__PWML2			PINMUX_PIN(PIN_PB19, 5, 1)
+#define PIN_PB19__TIOB5			PINMUX_PIN(PIN_PB19, 6, 2)
+
+#define PIN_PB20			52
+#define PIN_PB20__GPIO			PINMUX_PIN(PIN_PB20, 0, 0)
+#define PIN_PB20__QSPI0_INT		PINMUX_PIN(PIN_PB20, 1, 1)
+#define PIN_PB20__QSPI1_CS		PINMUX_PIN(PIN_PB20, 2, 1)
+#define PIN_PB20__FLEXCOM10_IO0		PINMUX_PIN(PIN_PB20, 4, 1)
+#define PIN_PB20__PWMH2			PINMUX_PIN(PIN_PB20, 5, 1)
+#define PIN_PB20__TCLK5			PINMUX_PIN(PIN_PB20, 6, 2)
+
+#define PIN_PB21			53
+#define PIN_PB21__GPIO			PINMUX_PIN(PIN_PB21, 0, 0)
+#define PIN_PB21__SDMMC1_RSTN		PINMUX_PIN(PIN_PB21, 1, 1)
+#define PIN_PB21__FLEXCOM6_IO4		PINMUX_PIN(PIN_PB21, 2, 2)
+#define PIN_PB21__TIOB2			PINMUX_PIN(PIN_PB21, 3, 2)
+#define PIN_PB21__ADTRG			PINMUX_PIN(PIN_PB21, 4, 2)
+#define PIN_PB21__EXT_IRQ0		PINMUX_PIN(PIN_PB21, 5, 2)
+
+#define PIN_PB22			54
+#define PIN_PB22__GPIO			PINMUX_PIN(PIN_PB22, 0, 0)
+#define PIN_PB22__SDMMC1_CMD		PINMUX_PIN(PIN_PB22, 1, 1)
+#define PIN_PB22__FLEXCOM6_IO3		PINMUX_PIN(PIN_PB22, 2, 2)
+#define PIN_PB22__TCLK2			PINMUX_PIN(PIN_PB22, 3, 2)
+
+#define PIN_PB23			55
+#define PIN_PB23__GPIO			PINMUX_PIN(PIN_PB23, 0, 0)
+#define PIN_PB23__SDMMC1_CK		PINMUX_PIN(PIN_PB23, 1, 1)
+#define PIN_PB23__FLEXCOM6_IO2		PINMUX_PIN(PIN_PB23, 2, 2)
+#define PIN_PB23__TIOA2			PINMUX_PIN(PIN_PB23, 3, 2)
+
+#define PIN_PB24			56
+#define PIN_PB24__GPIO			PINMUX_PIN(PIN_PB24, 0, 0)
+#define PIN_PB24__SDMMC1_DAT0		PINMUX_PIN(PIN_PB24, 1, 1)
+#define PIN_PB24__FLEXCOM6_IO0		PINMUX_PIN(PIN_PB24, 2, 2)
+
+#define PIN_PB25			57
+#define PIN_PB25__GPIO			PINMUX_PIN(PIN_PB25, 0, 0)
+#define PIN_PB25__SDMMC1_DAT1		PINMUX_PIN(PIN_PB25, 1, 1)
+#define PIN_PB25__FLEXCOM6_IO1		PINMUX_PIN(PIN_PB25, 2, 2)
+#define PIN_PB25__TIOB2			PINMUX_PIN(PIN_PB25, 3, 1)
+
+#define PIN_PB26			58
+#define PIN_PB26__GPIO			PINMUX_PIN(PIN_PB26, 0, 0)
+#define PIN_PB26__SDMMC1_DAT2		PINMUX_PIN(PIN_PB26, 1, 1)
+#define PIN_PB26__FLEXCOM8_IO0		PINMUX_PIN(PIN_PB26, 2, 3)
+#define PIN_PB26__TCLK2			PINMUX_PIN(PIN_PB26, 3, 1)
+
+#define PIN_PB27			59
+#define PIN_PB27__GPIO			PINMUX_PIN(PIN_PB27, 0, 0)
+#define PIN_PB27__SDMMC1_DAT3		PINMUX_PIN(PIN_PB27, 1, 1)
+#define PIN_PB27__FLEXCOM8_IO1		PINMUX_PIN(PIN_PB27, 2, 3)
+#define PIN_PB27__TIOA2			PINMUX_PIN(PIN_PB27, 3, 1)
+
+#define PIN_PB28			60
+#define PIN_PB28__GPIO			PINMUX_PIN(PIN_PB28, 0, 0)
+#define PIN_PB28__SDMMC1_WP		PINMUX_PIN(PIN_PB28, 1, 1)
+#define PIN_PB28__FLEXCOM1_IO0		PINMUX_PIN(PIN_PB28, 3, 3)
+#define PIN_PB28__D15			PINMUX_PIN(PIN_PB28, 5, 1)
+
+#define PIN_PB29			61
+#define PIN_PB29__GPIO			PINMUX_PIN(PIN_PB29, 0, 0)
+#define PIN_PB29__SDMMC1_CD		PINMUX_PIN(PIN_PB29, 1, 1)
+#define PIN_PB29__I2SMCC0_MCK		PINMUX_PIN(PIN_PB29, 2, 1)
+#define PIN_PB29__FLEXCOM1_IO1		PINMUX_PIN(PIN_PB29, 3, 3)
+#define PIN_PB29__D14			PINMUX_PIN(PIN_PB29, 5, 2)
+
+#define PIN_PB30			62
+#define PIN_PB30__GPIO			PINMUX_PIN(PIN_PB30, 0, 0)
+#define PIN_PB30__SDMMC1_1V8SEL		PINMUX_PIN(PIN_PB30, 1, 1)
+#define PIN_PB30__I2SMCC1_MCK		PINMUX_PIN(PIN_PB30, 2, 2)
+#define PIN_PB30__FLEXCOM1_IO2		PINMUX_PIN(PIN_PB30, 3, 3)
+#define PIN_PB30__TIOA1			PINMUX_PIN(PIN_PB30, 4, 1)
+#define PIN_PB30__NCS1			PINMUX_PIN(PIN_PB30, 5, 1)
+
+#define PIN_PB31			63
+#define PIN_PB31__GPIO			PINMUX_PIN(PIN_PB31, 0, 0)
+#define PIN_PB31__PCK7			PINMUX_PIN(PIN_PB31, 1, 2)
+#define PIN_PB31__I2SMCC1_DIN1		PINMUX_PIN(PIN_PB31, 2, 1)
+#define PIN_PB31__FLEXCOM1_IO3		PINMUX_PIN(PIN_PB31, 3, 3)
+#define PIN_PB31__TCLK1			PINMUX_PIN(PIN_PB31, 4, 1)
+#define PIN_PB31__NWE			PINMUX_PIN(PIN_PB31, 5, 2)
+
+#define PIN_PC0				64
+#define PIN_PC0__GPIO			PINMUX_PIN(PIN_PC0, 0, 0)
+#define PIN_PC0__PCK6			PINMUX_PIN(PIN_PC0, 1, 2)
+#define PIN_PC0__I2SMCC1_DIN2		PINMUX_PIN(PIN_PC0, 2, 1)
+#define PIN_PC0__FLEXCOM9_IO4		PINMUX_PIN(PIN_PC0, 3, 2)
+#define PIN_PC0__TIOB1			PINMUX_PIN(PIN_PC0, 4, 1)
+#define PIN_PC0__NWR1			PINMUX_PIN(PIN_PC0, 5, 1)
+
+#define PIN_PC1				65
+#define PIN_PC1__GPIO			PINMUX_PIN(PIN_PC1, 0, 0)
+#define PIN_PC1__PCK5			PINMUX_PIN(PIN_PC1, 1, 1)
+#define PIN_PC1__FLEXCOM9_IO2		PINMUX_PIN(PIN_PC1, 3, 2)
+#define PIN_PC1__SMCK			PINMUX_PIN(PIN_PC1, 5, 1)
+
+#define PIN_PC2				66
+#define PIN_PC2__GPIO			PINMUX_PIN(PIN_PC2, 0, 0)
+#define PIN_PC2__EXT_IRQ0		PINMUX_PIN(PIN_PC2, 1, 3)
+#define PIN_PC2__FLEXCOM9_IO3		PINMUX_PIN(PIN_PC2, 3, 2)
+#define PIN_PC2__A11			PINMUX_PIN(PIN_PC2, 5, 1)
+
+#define PIN_PC3				67
+#define PIN_PC3__GPIO			PINMUX_PIN(PIN_PC3, 0, 0)
+#define PIN_PC3__SPDIF_RX		PINMUX_PIN(PIN_PC3, 1, 2)
+#define PIN_PC3__FLEXCOM9_IO0		PINMUX_PIN(PIN_PC3, 3, 2)
+#define PIN_PC3__FLEXCOM0_IO4		PINMUX_PIN(PIN_PC3, 4, 2)
+#define PIN_PC3__A10			PINMUX_PIN(PIN_PC3, 5, 1)
+
+#define PIN_PC4				68
+#define PIN_PC4__GPIO			PINMUX_PIN(PIN_PC4, 0, 0)
+#define PIN_PC4__SPDIF_TX		PINMUX_PIN(PIN_PC4, 1, 2)
+#define PIN_PC4__FLEXCOM9_IO1		PINMUX_PIN(PIN_PC4, 3, 2)
+#define PIN_PC4__FLEXCOM0_IO3		PINMUX_PIN(PIN_PC4, 4, 2)
+#define PIN_PC4__D0			PINMUX_PIN(PIN_PC4, 5, 2)
+
+#define PIN_PC5				69
+#define PIN_PC5__GPIO			PINMUX_PIN(PIN_PC5, 0, 0)
+#define PIN_PC5__I3CC_SDASPUE		PINMUX_PIN(PIN_PC5, 1, 1)
+#define PIN_PC5__I2SMCC1_DIN3		PINMUX_PIN(PIN_PC5, 2, 1)
+#define PIN_PC5__FLEXCOM0_IO2		PINMUX_PIN(PIN_PC5, 4, 2)
+#define PIN_PC5__D1			PINMUX_PIN(PIN_PC5, 5, 2)
+
+#define PIN_PC6				70
+#define PIN_PC6__GPIO			PINMUX_PIN(PIN_PC6, 0, 0)
+#define PIN_PC6__I3CC_SCL		PINMUX_PIN(PIN_PC6, 1, 1)
+#define PIN_PC6__FLEXCOM0_IO1		PINMUX_PIN(PIN_PC6, 4, 2)
+#define PIN_PC6__D4			PINMUX_PIN(PIN_PC6, 5, 2)
+
+#define PIN_PC7				71
+#define PIN_PC7__GPIO			PINMUX_PIN(PIN_PC7, 0, 0)
+#define PIN_PC7__I3CC_SDA		PINMUX_PIN(PIN_PC7, 1, 1)
+#define PIN_PC7__FLEXCOM0_IO0		PINMUX_PIN(PIN_PC7, 4, 2)
+#define PIN_PC7__D5			PINMUX_PIN(PIN_PC7, 5, 2)
+
+#define PIN_PC8				72
+#define PIN_PC8__GPIO			PINMUX_PIN(PIN_PC8, 0, 0)
+#define PIN_PC8__I2SMCC0_DIN1		PINMUX_PIN(PIN_PC8, 1, 1)
+#define PIN_PC8__PDMC0_DS1		PINMUX_PIN(PIN_PC8, 2, 2)
+#define PIN_PC8__I2SMCC1_DOUT1		PINMUX_PIN(PIN_PC8, 3, 1)
+#define PIN_PC8__FLEXCOM9_IO0		PINMUX_PIN(PIN_PC8, 4, 1)
+#define PIN_PC8__D6			PINMUX_PIN(PIN_PC8, 5, 2)
+
+#define PIN_PC9				73
+#define PIN_PC9__GPIO			PINMUX_PIN(PIN_PC9, 0, 0)
+#define PIN_PC9__I2SMCC0_DIN2		PINMUX_PIN(PIN_PC9, 1, 1)
+#define PIN_PC9__PDMC0_CLK		PINMUX_PIN(PIN_PC9, 2, 2)
+#define PIN_PC9__I2SMCC1_DOUT2		PINMUX_PIN(PIN_PC9, 3, 1)
+#define PIN_PC9__FLEXCOM9_IO1		PINMUX_PIN(PIN_PC9, 4, 1)
+#define PIN_PC9__D7			PINMUX_PIN(PIN_PC9, 5, 2)
+
+#define PIN_PC10			74
+#define PIN_PC10__GPIO			PINMUX_PIN(PIN_PC10, 0, 0)
+#define PIN_PC10__I2SMCC0_DIN3		PINMUX_PIN(PIN_PC10, 1, 1)
+#define PIN_PC10__PDMC0_DS0		PINMUX_PIN(PIN_PC10, 2, 2)
+#define PIN_PC10__I2SMCC1_DOUT3		PINMUX_PIN(PIN_PC10, 3, 1)
+#define PIN_PC10__FLEXCOM9_IO2		PINMUX_PIN(PIN_PC10, 4, 1)
+#define PIN_PC10__D2			PINMUX_PIN(PIN_PC10, 5, 2)
+
+#define PIN_PC11			75
+#define PIN_PC11__GPIO			PINMUX_PIN(PIN_PC11, 0, 0)
+#define PIN_PC11__I2SMCC0_DOUT1		PINMUX_PIN(PIN_PC11, 1, 1)
+#define PIN_PC11__PDMC1_DS0		PINMUX_PIN(PIN_PC11, 2, 1)
+#define PIN_PC11__FLEXCOM9_IO3		PINMUX_PIN(PIN_PC11, 4, 1)
+#define PIN_PC10__D3			PINMUX_PIN(PIN_PC10, 5, 2)
+
+#define PIN_PC12			76
+#define PIN_PC12__GPIO			PINMUX_PIN(PIN_PC12, 0, 0)
+#define PIN_PC12__I2SMCC0_DOUT2		PINMUX_PIN(PIN_PC12, 1, 1)
+#define PIN_PC12__PDMC1_CLK		PINMUX_PIN(PIN_PC12, 2, 1)
+#define PIN_PC12__FLEXCOM9_IO4		PINMUX_PIN(PIN_PC12, 4, 1)
+#define PIN_PC12__A9			PINMUX_PIN(PIN_PC12, 5, 1)
+
+#define PIN_PC13			77
+#define PIN_PC13__GPIO			PINMUX_PIN(PIN_PC13, 0, 0)
+#define PIN_PC13__I2SMCC0_DOUT3		PINMUX_PIN(PIN_PC13, 1, 1)
+#define PIN_PC13__PDMC1_DS1		PINMUX_PIN(PIN_PC13, 2, 1)
+#define PIN_PC13__A8			PINMUX_PIN(PIN_PC13, 5, 1)
+
+#define PIN_PC14			78
+#define PIN_PC14__GPIO			PINMUX_PIN(PIN_PC14, 0, 0)
+#define PIN_PC14__I2SMCC1_DIN0		PINMUX_PIN(PIN_PC14, 1, 1)
+#define PIN_PC14__SPDIF_RX		PINMUX_PIN(PIN_PC14, 2, 3)
+#define PIN_PC14__FLEXCOM1_IO0		PINMUX_PIN(PIN_PC14, 3, 2)
+#define PIN_PC14__A7			PINMUX_PIN(PIN_PC14, 5, 1)
+
+#define PIN_PC15			79
+#define PIN_PC15__GPIO			PINMUX_PIN(PIN_PC15, 0, 0)
+#define PIN_PC15__I2SMCC1_WS		PINMUX_PIN(PIN_PC15, 1, 1)
+#define PIN_PC15__PDMC1_DS1		PINMUX_PIN(PIN_PC15, 2, 2)
+#define PIN_PC15__FLEXCOM1_IO1		PINMUX_PIN(PIN_PC15, 3, 2)
+#define PIN_PC15__A6			PINMUX_PIN(PIN_PC15, 5, 1)
+
+#define PIN_PC16			80
+#define PIN_PC16__GPIO			PINMUX_PIN(PIN_PC16, 0, 0)
+#define PIN_PC16__I2SMCC1_CK		PINMUX_PIN(PIN_PC16, 1, 1)
+#define PIN_PC16__PDMC1_CLK		PINMUX_PIN(PIN_PC16, 2, 2)
+#define PIN_PC16__FLEXCOM1_IO2		PINMUX_PIN(PIN_PC16, 3, 2)
+#define PIN_PC16__TIOA1			PINMUX_PIN(PIN_PC16, 4, 2)
+#define PIN_PC16__A5			PINMUX_PIN(PIN_PC16, 5, 1)
+
+#define PIN_PC17			81
+#define PIN_PC17__GPIO			PINMUX_PIN(PIN_PC17, 0, 0)
+#define PIN_PC17__I2SMCC1_DOUT0		PINMUX_PIN(PIN_PC17, 1, 1)
+#define PIN_PC17__PDMC1_DS0		PINMUX_PIN(PIN_PC17, 2, 2)
+#define PIN_PC17__FLEXCOM1_IO3		PINMUX_PIN(PIN_PC17, 3, 2)
+#define PIN_PC17__TCLK1			PINMUX_PIN(PIN_PC17, 4, 2)
+#define PIN_PC17__A4			PINMUX_PIN(PIN_PC17, 5, 1)
+
+#define PIN_PC18			82
+#define PIN_PC18__GPIO			PINMUX_PIN(PIN_PC18, 0, 0)
+#define PIN_PC18__I2SMCC0_DIN0		PINMUX_PIN(PIN_PC18, 1, 1)
+#define PIN_PC18__SPDIF_TX		PINMUX_PIN(PIN_PC18, 2, 3)
+#define PIN_PC18__FLEXCOM1_IO4		PINMUX_PIN(PIN_PC18, 3, 2)
+#define PIN_PC18__TIOB1			PINMUX_PIN(PIN_PC18, 4, 2)
+#define PIN_PC18__A3			PINMUX_PIN(PIN_PC18, 5, 1)
+
+#define PIN_PC19			83
+#define PIN_PC19__GPIO			PINMUX_PIN(PIN_PC19, 0, 0)
+#define PIN_PC19__I2SMCC0_WS		PINMUX_PIN(PIN_PC19, 1, 1)
+#define PIN_PC19__PCK6			PINMUX_PIN(PIN_PC19, 2, 1)
+#define PIN_PC19__A2			PINMUX_PIN(PIN_PC19, 5, 1)
+
+#define PIN_PC20			84
+#define PIN_PC20__GPIO			PINMUX_PIN(PIN_PC20, 0, 0)
+#define PIN_PC20__I2SMCC0_DOUT0		PINMUX_PIN(PIN_PC20, 1, 1)
+#define PIN_PC20__A1			PINMUX_PIN(PIN_PC20, 5, 1)
+
+#define PIN_PC21			85
+#define PIN_PC21__GPIO			PINMUX_PIN(PIN_PC21, 0, 0)
+#define PIN_PC21__I2SMCC0_CK		PINMUX_PIN(PIN_PC21, 1, 1)
+#define PIN_PC21__PCK7			PINMUX_PIN(PIN_PC21, 2, 1)
+#define PIN_PC21__A0			PINMUX_PIN(PIN_PC21, 5, 1)
+
+#define PIN_PC22			86
+#define PIN_PC22__GPIO			PINMUX_PIN(PIN_PC22, 0, 0)
+#define PIN_PC22__NTRST			PINMUX_PIN(PIN_PC22, 1, 1)
+#define PIN_PC22__NWAIT			PINMUX_PIN(PIN_PC22, 5, 1)
+
+#define PIN_PC23			87
+#define PIN_PC23__GPIO			PINMUX_PIN(PIN_PC23, 0, 0)
+#define PIN_PC23__TCK_SWCLK		PINMUX_PIN(PIN_PC23, 1, 1)
+
+#define PIN_PC24			88
+#define PIN_PC24__GPIO			PINMUX_PIN(PIN_PC24, 0, 0)
+#define PIN_PC24__TMS_SWDIO		PINMUX_PIN(PIN_PC24, 1, 1)
+
+#define PIN_PC25			89
+#define PIN_PC25__GPIO			PINMUX_PIN(PIN_PC25, 0, 0)
+#define PIN_PC25__TDI			PINMUX_PIN(PIN_PC25, 1, 1)
+
+#define PIN_PC26			90
+#define PIN_PC26__GPIO			PINMUX_PIN(PIN_PC26, 0, 0)
+#define PIN_PC26__TDO			PINMUX_PIN(PIN_PC26, 1, 1)
+#define PIN_PC26__A15			PINMUX_PIN(PIN_PC26, 5, 1)
+
+#define PIN_PC27			91
+#define PIN_PC27__GPIO			PINMUX_PIN(PIN_PC27, 0, 0)
+#define PIN_PC27__SDMMC2_CMD		PINMUX_PIN(PIN_PC27, 1, 1)
+#define PIN_PC27__FLEXCOM8_IO0		PINMUX_PIN(PIN_PC27, 2, 2)
+#define PIN_PC27__TD1			PINMUX_PIN(PIN_PC27, 4, 2)
+#define PIN_PC27__D8			PINMUX_PIN(PIN_PC27, 5, 1)
+
+#define PIN_PC28			92
+#define PIN_PC28__GPIO			PINMUX_PIN(PIN_PC28, 0, 0)
+#define PIN_PC28__SDMMC2_CK		PINMUX_PIN(PIN_PC28, 1, 1)
+#define PIN_PC28__FLEXCOM8_IO1		PINMUX_PIN(PIN_PC28, 2, 2)
+#define PIN_PC28__TF1			PINMUX_PIN(PIN_PC28, 4, 2)
+#define PIN_PC28__D9			PINMUX_PIN(PIN_PC28, 5, 1)
+
+#define PIN_PC29			93
+#define PIN_PC29__GPIO			PINMUX_PIN(PIN_PC29, 0, 0)
+#define PIN_PC29__SDMMC2_DAT0		PINMUX_PIN(PIN_PC29, 1, 1)
+#define PIN_PC29__FLEXCOM8_IO2		PINMUX_PIN(PIN_PC29, 2, 2)
+#define PIN_PC29__TK1			PINMUX_PIN(PIN_PC29, 4, 2)
+#define PIN_PC29__D10			PINMUX_PIN(PIN_PC29, 5, 1)
+#define PIN_PC29__TCLK0			PINMUX_PIN(PIN_PC29, 6, 1)
+
+#define PIN_PC30			94
+#define PIN_PC30__GPIO			PINMUX_PIN(PIN_PC30, 0, 0)
+#define PIN_PC30__SDMMC2_DAT1		PINMUX_PIN(PIN_PC30, 1, 1)
+#define PIN_PC30__FLEXCOM8_IO3		PINMUX_PIN(PIN_PC30, 2, 2)
+#define PIN_PC30__RD1			PINMUX_PIN(PIN_PC30, 4, 2)
+#define PIN_PC30__D11			PINMUX_PIN(PIN_PC30, 5, 1)
+#define PIN_PC30__TIOA0			PINMUX_PIN(PIN_PC30, 6, 1)
+
+#define PIN_PC31			95
+#define PIN_PC31__GPIO			PINMUX_PIN(PIN_PC31, 0, 0)
+#define PIN_PC31__SDMMC2_DAT2		PINMUX_PIN(PIN_PC31, 1, 1)
+#define PIN_PC31__FLEXCOM8_IO4		PINMUX_PIN(PIN_PC31, 2, 2)
+#define PIN_PC31__PCK0			PINMUX_PIN(PIN_PC31, 3, 2)
+#define PIN_PC31__RK1			PINMUX_PIN(PIN_PC31, 4, 2)
+#define PIN_PC31__D12			PINMUX_PIN(PIN_PC31, 5, 1)
+#define PIN_PC31__TIOB0			PINMUX_PIN(PIN_PC31, 6, 1)
+
+#define PIN_PD0				96
+#define PIN_PD0__GPIO			PINMUX_PIN(PIN_PD0, 0, 0)
+#define PIN_PD0__SDMMC2_DAT3		PINMUX_PIN(PIN_PD0, 1, 1)
+#define PIN_PD0__PCK1			PINMUX_PIN(PIN_PD0, 3, 2)
+#define PIN_PD0__RF1			PINMUX_PIN(PIN_PD0, 4, 2)
+#define PIN_PD0__D13			PINMUX_PIN(PIN_PD0, 5, 1)
+
+#define PIN_PD1				97
+#define PIN_PD1__GPIO			PINMUX_PIN(PIN_PD1, 0, 0)
+#define PIN_PD1__SDMMC2_WP		PINMUX_PIN(PIN_PD1, 1, 1)
+#define PIN_PD1__FLEXCOM1_IO5		PINMUX_PIN(PIN_PD1, 2, 1)
+#define PIN_PD1__LCDC_HSYNC		PINMUX_PIN(PIN_PD1, 3, 2)
+#define PIN_PD1__FLEXCOM3_IO0		PINMUX_PIN(PIN_PD1, 4, 3)
+
+#define PIN_PD2				98
+#define PIN_PD2__GPIO			PINMUX_PIN(PIN_PD2, 0, 0)
+#define PIN_PD2__SDMMC2_CD		PINMUX_PIN(PIN_PD2, 1, 1)
+#define PIN_PD2__FLEXCOM1_IO6		PINMUX_PIN(PIN_PD2, 2, 1)
+#define PIN_PD2__LCDC_VSYNC		PINMUX_PIN(PIN_PD2, 3, 2)
+#define PIN_PD2__FLEXCOM3_IO1		PINMUX_PIN(PIN_PD2, 4, 3)
+
+#define PIN_PD3				99
+#define PIN_PD3__GPIO			PINMUX_PIN(PIN_PD3, 0, 0)
+#define PIN_PD3__SDMMC2_1V8SEL		PINMUX_PIN(PIN_PD3, 1, 1)
+#define PIN_PD3__FLEXCOM1_IO4		PINMUX_PIN(PIN_PD3, 2, 1)
+#define PIN_PD3__TIOA0			PINMUX_PIN(PIN_PD3, 3, 2)
+#define PIN_PD3__FLEXCOM3_IO2		PINMUX_PIN(PIN_PD3, 4, 3)
+#define PIN_PD3__EXT_IRQ1		PINMUX_PIN(PIN_PD3, 5, 3)
+
+#define PIN_PD4				100
+#define PIN_PD4__GPIO			PINMUX_PIN(PIN_PD4, 0, 0)
+#define PIN_PD4__LCDC_HSYNC		PINMUX_PIN(PIN_PD4, 1, 1)
+#define PIN_PD4__FLEXCOM1_IO2		PINMUX_PIN(PIN_PD4, 2, 1)
+#define PIN_PD4__TIOB0			PINMUX_PIN(PIN_PD4, 3, 2)
+#define PIN_PD4__FLEXCOM7_IO1		PINMUX_PIN(PIN_PD4, 4, 3)
+
+#define PIN_PD5				101
+#define PIN_PD5__GPIO			PINMUX_PIN(PIN_PD5, 0, 0)
+#define PIN_PD5__LCDC_VSYNC		PINMUX_PIN(PIN_PD5, 1, 1)
+#define PIN_PD5__FLEXCOM1_IO3		PINMUX_PIN(PIN_PD5, 2, 1)
+#define PIN_PD5__TCLK0			PINMUX_PIN(PIN_PD5, 3, 2)
+#define PIN_PD5__FLEXCOM7_IO0		PINMUX_PIN(PIN_PD5, 4, 3)
+
+#define PIN_PD6				102
+#define PIN_PD6__GPIO			PINMUX_PIN(PIN_PD6, 0, 0)
+#define PIN_PD6__LCDC_PWM		PINMUX_PIN(PIN_PD6, 1, 1)
+#define PIN_PD6__FLEXCOM1_IO1		PINMUX_PIN(PIN_PD6, 2, 1)
+#define PIN_PD6__FLEXCOM7_IO2		PINMUX_PIN(PIN_PD6, 4, 3)
+
+#define PIN_PD7				103
+#define PIN_PD7__GPIO			PINMUX_PIN(PIN_PD7, 0, 0)
+#define PIN_PD7__LCDC_DISP		PINMUX_PIN(PIN_PD7, 1, 1)
+#define PIN_PD7__FLEXCOM1_IO0		PINMUX_PIN(PIN_PD7, 2, 1)
+#define PIN_PD7__FLEXCOM7_IO3		PINMUX_PIN(PIN_PD7, 4, 3)
+
+#define PIN_PD8				104
+#define PIN_PD8__GPIO			PINMUX_PIN(PIN_PD8, 0, 0)
+#define PIN_PD8__CANTX0			PINMUX_PIN(PIN_PD8, 1, 1)
+#define PIN_PD8__FLEXCOM7_IO0		PINMUX_PIN(PIN_PD8, 2, 1)
+
+#define PIN_PD9				105
+#define PIN_PD9__GPIO			PINMUX_PIN(PIN_PD9, 0, 0)
+#define PIN_PD9__CANRX0			PINMUX_PIN(PIN_PD9, 1, 1)
+#define PIN_PD9__FLEXCOM7_IO1		PINMUX_PIN(PIN_PD9, 2, 1)
+
+#define PIN_PD10			106
+#define PIN_PD10__GPIO			PINMUX_PIN(PIN_PD10, 0, 0)
+#define PIN_PD10__CANTX1		PINMUX_PIN(PIN_PD10, 1, 1)
+#define PIN_PD10__FLEXCOM7_IO2		PINMUX_PIN(PIN_PD10, 2, 1)
+#define PIN_PD10__TIOA1			PINMUX_PIN(PIN_PD10, 3, 3)
+
+#define PIN_PD11			107
+#define PIN_PD11__GPIO			PINMUX_PIN(PIN_PD11, 0, 0)
+#define PIN_PD11__CANRX1		PINMUX_PIN(PIN_PD11, 1, 1)
+#define PIN_PD11__FLEXCOM7_IO3		PINMUX_PIN(PIN_PD11, 2, 1)
+#define PIN_PD11__TCLK1			PINMUX_PIN(PIN_PD11, 3, 3)
+
+#define PIN_PD12			108
+#define PIN_PD12__GPIO			PINMUX_PIN(PIN_PD12, 0, 0)
+#define PIN_PD12__CANTX2		PINMUX_PIN(PIN_PD12, 1, 1)
+#define PIN_PD12__FLEXCOM7_IO4		PINMUX_PIN(PIN_PD12, 2, 1)
+#define PIN_PD12__TIOB1			PINMUX_PIN(PIN_PD12, 3, 3)
+#define PIN_PD12__PCK2			PINMUX_PIN(PIN_PD12, 4, 2)
+#define PIN_PD12__FLEXCOM3_IO3		PINMUX_PIN(PIN_PD12, 5, 3)
+
+#define PIN_PD13			109
+#define PIN_PD13__GPIO			PINMUX_PIN(PIN_PD13, 0, 0)
+#define PIN_PD13__CANRX2		PINMUX_PIN(PIN_PD13, 1, 1)
+#define PIN_PD13__FLEXCOM5_IO4		PINMUX_PIN(PIN_PD13, 2, 1)
+#define PIN_PD13__TIOA2			PINMUX_PIN(PIN_PD13, 3, 3)
+#define PIN_PD13__PCK3			PINMUX_PIN(PIN_PD13, 4, 2)
+
+#define PIN_PD14			110
+#define PIN_PD14__GPIO			PINMUX_PIN(PIN_PD14, 0, 0)
+#define PIN_PD14__CANTX3		PINMUX_PIN(PIN_PD14, 1, 1)
+#define PIN_PD14__FLEXCOM5_IO2		PINMUX_PIN(PIN_PD14, 2, 1)
+#define PIN_PD14__TIOB2			PINMUX_PIN(PIN_PD14, 3, 3)
+
+#define PIN_PD15			111
+#define PIN_PD15__GPIO			PINMUX_PIN(PIN_PD15, 0, 0)
+#define PIN_PD15__CANRX3		PINMUX_PIN(PIN_PD15, 1, 1)
+#define PIN_PD15__FLEXCOM5_IO3		PINMUX_PIN(PIN_PD15, 2, 1)
+#define PIN_PD15__TCLK2			PINMUX_PIN(PIN_PD15, 3, 3)
+
+#define PIN_PD16			112
+#define PIN_PD16__GPIO			PINMUX_PIN(PIN_PD16, 0, 0)
+#define PIN_PD16__CANTX4		PINMUX_PIN(PIN_PD16, 1, 1)
+#define PIN_PD16__FLEXCOM5_IO0		PINMUX_PIN(PIN_PD16, 2, 1)
+
+#define PIN_PD17			113
+#define PIN_PD17__GPIO			PINMUX_PIN(PIN_PD17, 0, 0)
+#define PIN_PD17__CANRX4		PINMUX_PIN(PIN_PD17, 1, 1)
+#define PIN_PD17__FLEXCOM5_IO1		PINMUX_PIN(PIN_PD17, 2, 1)
+
+#define PIN_PD18			114
+#define PIN_PD18__GPIO			PINMUX_PIN(PIN_PD18, 0, 0)
+#define PIN_PD18__FLEXCOM6_IO0		PINMUX_PIN(PIN_PD18, 2, 4)
+#define PIN_PD18__CANTX1		PINMUX_PIN(PIN_PD18, 3, 2)
+#define PIN_PD18__PCK4			PINMUX_PIN(PIN_PD18, 4, 2)
+
+#define PIN_PD19			115
+#define PIN_PD19__GPIO			PINMUX_PIN(PIN_PD19, 0, 0)
+#define PIN_PD19__FLEXCOM6_IO1		PINMUX_PIN(PIN_PD19, 2, 4)
+#define PIN_PD19__CANRX1		PINMUX_PIN(PIN_PD19, 3, 2)
+#define PIN_PD19__PCK2			PINMUX_PIN(PIN_PD19, 4, 3)
+
+#define PIN_PD20			116
+#define PIN_PD20__GPIO			PINMUX_PIN(PIN_PD20, 0, 0)
+#define PIN_PD20__PFLEXCOM6_IO2		PINMUX_PIN(PIN_PD20, 2, 4)
+#define PIN_PD20__I2SMCC1_MCK		PINMUX_PIN(PIN_PD20, 3, 2)
+#define PIN_PD20__PCK3			PINMUX_PIN(PIN_PD20, 4, 3)
+
+#define PIN_PD21			117
+#define PIN_PD21__GPIO			PINMUX_PIN(PIN_PD21, 0, 0)
+#define PIN_PD21__G1_TXCTL		PINMUX_PIN(PIN_PD21, 1, 2)
+#define PIN_PD21__FLEXCOM6_IO2		PINMUX_PIN(PIN_PD21, 2, 3)
+#define PIN_PD21__TK1			PINMUX_PIN(PIN_PD21, 3, 1)
+
+#define PIN_PD22			118
+#define PIN_PD22__GPIO			PINMUX_PIN(PIN_PD22, 0, 0)
+#define PIN_PD22__G1_TX0		PINMUX_PIN(PIN_PD22, 1, 1)
+#define PIN_PD22__FLEXCOM6_IO3		PINMUX_PIN(PIN_PD22, 2, 3)
+#define PIN_PD22__TF1			PINMUX_PIN(PIN_PD22, 3, 1)
+
+#define PIN_PD23			119
+#define PIN_PD23__GPIO			PINMUX_PIN(PIN_PD23, 0, 0)
+#define PIN_PD23__G1_TX1		PINMUX_PIN(PIN_PD23, 1, 1)
+#define PIN_PD23__FLEXCOM6_IO4		PINMUX_PIN(PIN_PD23, 2, 3)
+#define PIN_PD23__TD1			PINMUX_PIN(PIN_PD23, 3, 1)
+
+#define PIN_PD24			120
+#define PIN_PD24__GPIO			PINMUX_PIN(PIN_PD24, 0, 0)
+#define PIN_PD24__G1_RXCTL		PINMUX_PIN(PIN_PD24, 1, 1)
+#define PIN_PD24__FLEXCOM6_IO0		PINMUX_PIN(PIN_PD24, 2, 3)
+#define PIN_PD24__RD1			PINMUX_PIN(PIN_PD24, 3, 1)
+#define PIN_PD24__PDMC0_DS1		PINMUX_PIN(PIN_PD24, 5, 3)
+
+#define PIN_PD25			121
+#define PIN_PD25__GPIO			PINMUX_PIN(PIN_PD25, 0, 0)
+#define PIN_PD25__G1_MDC		PINMUX_PIN(PIN_PD25, 1, 1)
+#define PIN_PD25__FLEXCOM6_IO1		PINMUX_PIN(PIN_PD25, 2, 3)
+#define PIN_PD25__RK1			PINMUX_PIN(PIN_PD25, 3, 1)
+#define PIN_PD25__PDMC0_CLK		PINMUX_PIN(PIN_PD25, 5, 3)
+
+#define PIN_PD26			122
+#define PIN_PD26__GPIO			PINMUX_PIN(PIN_PD26, 0, 0)
+#define PIN_PD26__G1_MDIO		PINMUX_PIN(PIN_PD26, 1, 1)
+#define PIN_PD26__FLEXCOM7_IO4		PINMUX_PIN(PIN_PD26, 2, 2)
+#define PIN_PD26__RF1			PINMUX_PIN(PIN_PD26, 3, 1)
+#define PIN_PD26__I2SMCC1_DIN2		PINMUX_PIN(PIN_PD26, 4, 2)
+#define PIN_PD26__PDMC0_DS0		PINMUX_PIN(PIN_PD26, 5, 3)
+
+#define PIN_PD27			123
+#define PIN_PD27__GPIO			PINMUX_PIN(PIN_PD27, 0, 0)
+#define PIN_PD27__G1_RX0		PINMUX_PIN(PIN_PD27, 1, 1)
+#define PIN_PD27__FLEXCOM7_IO0		PINMUX_PIN(PIN_PD27, 2, 2)
+#define PIN_PD27__SPDIF_RX		PINMUX_PIN(PIN_PD27, 3, 1)
+#define PIN_PD27__I2SMCC1_DIN3		PINMUX_PIN(PIN_PD27, 4, 2)
+
+#define PIN_PD28			124
+#define PIN_PD28__GPIO			PINMUX_PIN(PIN_PD28, 0, 0)
+#define PIN_PD28__G1_RX1		PINMUX_PIN(PIN_PD28, 1, 1)
+#define PIN_PD28__FLEXCOM7_IO1		PINMUX_PIN(PIN_PD28, 2, 2)
+#define PIN_PD28__SPDIF_TX		PINMUX_PIN(PIN_PD28, 3, 1)
+#define PIN_PD28__I2SMCC1_DIN1		PINMUX_PIN(PIN_PD28, 4, 2)
+
+#define PIN_PD29			125
+#define PIN_PD29__GPIO			PINMUX_PIN(PIN_PD29, 0, 0)
+#define PIN_PD29__G1_REFCK		PINMUX_PIN(PIN_PD29, 1, 2)
+#define PIN_PD29__FLEXCOM7_IO2		PINMUX_PIN(PIN_PD29, 2, 2)
+#define PIN_PD29__I2SMCC1_DOUT3		PINMUX_PIN(PIN_PD29, 3, 2)
+
+#define PIN_PD30			126
+#define PIN_PD30__GPIO			PINMUX_PIN(PIN_PD30, 0, 0)
+#define PIN_PD30__G1_RX2		PINMUX_PIN(PIN_PD30, 1, 1)
+#define PIN_PD30__FLEXCOM7_IO3		PINMUX_PIN(PIN_PD30, 2, 2)
+#define PIN_PD30__I2SMCC1_DOUT1		PINMUX_PIN(PIN_PD30, 3, 2)
+#define PIN_PD30__PDMC1_DS1		PINMUX_PIN(PIN_PD30, 4, 3)
+#define PIN_PD30__G1_RXER		PINMUX_PIN(PIN_PD30, 5, 2)
+
+#define PIN_PD31			127
+#define PIN_PD31__GPIO			PINMUX_PIN(PIN_PD31, 0, 0)
+#define PIN_PD31__G1_RX3		PINMUX_PIN(PIN_PD31, 1, 1)
+#define PIN_PD31__FLEXCOM5_IO4		PINMUX_PIN(PIN_PD31, 2, 2)
+#define PIN_PD31__I2SMCC1_DOUT2		PINMUX_PIN(PIN_PD31, 3, 3)
+#define PIN_PD31__PDMC1_DS0		PINMUX_PIN(PIN_PD31, 4, 3)
+
+#define PIN_PE0				128
+#define PIN_PE0__GPIO			PINMUX_PIN(PIN_PE0, 0, 0)
+#define PIN_PE0__G1_TX2			PINMUX_PIN(PIN_PE0, 1, 1)
+#define PIN_PE0__FLEXCOM5_IO2		PINMUX_PIN(PIN_PE0, 2, 2)
+#define PIN_PE0__I2SMCC1_DIN0		PINMUX_PIN(PIN_PE0, 3, 2)
+#define PIN_PE0__PDMC1_CLK		PINMUX_PIN(PIN_PE0, 4, 3)
+
+#define PIN_PE1				129
+#define PIN_PE1__GPIO			PINMUX_PIN(PIN_PE1, 0, 0)
+#define PIN_PE1__G1_TX3			PINMUX_PIN(PIN_PE1, 1, 1)
+#define PIN_PE1__FLEXCOM5_IO3		PINMUX_PIN(PIN_PE1, 2, 2)
+#define PIN_PE1__I2SMCC1_WS		PINMUX_PIN(PIN_PE1, 3, 2)
+#define PIN_PE1__PDMC0_DS1		PINMUX_PIN(PIN_PE1, 4, 4)
+
+#define PIN_PE2				130
+#define PIN_PE2__GPIO			PINMUX_PIN(PIN_PE2, 0, 0)
+#define PIN_PE2__G1_RXCK		PINMUX_PIN(PIN_PE2, 1, 1)
+#define PIN_PE2__FLEXCOM5_IO1		PINMUX_PIN(PIN_PE2, 2, 2)
+#define PIN_PE2__I2SMCC1_CK		PINMUX_PIN(PIN_PE2, 3, 2)
+#define PIN_PE2__PDMC0_CLK		PINMUX_PIN(PIN_PE2, 4, 4)
+
+#define PIN_PE3				131
+#define PIN_PE3__GPIO			PINMUX_PIN(PIN_PE3, 0, 0)
+#define PIN_PE3__G1_TSUCOMP		PINMUX_PIN(PIN_PE3, 1, 1)
+#define PIN_PE3__FLEXCOM5_IO0		PINMUX_PIN(PIN_PE3, 2, 2)
+#define PIN_PE3__I2SMCC1_DOUT0		PINMUX_PIN(PIN_PE3, 3, 2)
+#define PIN_PE3__PDMC0_DS0		PINMUX_PIN(PIN_PE3, 4, 4)
+
+#define PIN_PE4				132
+#define PIN_PE4__GPIO			PINMUX_PIN(PIN_PE4, 0, 0)
+#define PIN_PE4__LCDC_DAT0		PINMUX_PIN(PIN_PE4, 1, 1)
+#define PIN_PE4__FLEXCOM2_IO2		PINMUX_PIN(PIN_PE4, 2, 1)
+#define PIN_PE4__PWML0			PINMUX_PIN(PIN_PE4, 3, 2)
+#define PIN_PE4__TIOA3			PINMUX_PIN(PIN_PE4, 4, 1)
+#define PIN_PE4__I2SMCC0_DIN1		PINMUX_PIN(PIN_PE4, 5, 2)
+
+#define PIN_PE5				133
+#define PIN_PE5__GPIO			PINMUX_PIN(PIN_PE5, 0, 0)
+#define PIN_PE5__LCDC_DAT1		PINMUX_PIN(PIN_PE5, 1, 1)
+#define PIN_PE5__FLEXCOM2_IO3		PINMUX_PIN(PIN_PE5, 2, 1)
+#define PIN_PE5__PWMH0			PINMUX_PIN(PIN_PE5, 3, 2)
+#define PIN_PE5__TIOB3			PINMUX_PIN(PIN_PE5, 4, 1)
+#define PIN_PE5__I2SMCC0_DIN2		PINMUX_PIN(PIN_PE5, 5, 2)
+
+#define PIN_PE6				134
+#define PIN_PE6__GPIO			PINMUX_PIN(PIN_PE6, 0, 0)
+#define PIN_PE6__LCDC_DAT2		PINMUX_PIN(PIN_PE6, 1, 1)
+#define PIN_PE6__FLEXCOM2_IO4		PINMUX_PIN(PIN_PE6, 2, 1)
+#define PIN_PE6__PWML1			PINMUX_PIN(PIN_PE6, 3, 2)
+#define PIN_PE6__TCLK3			PINMUX_PIN(PIN_PE6, 4, 1)
+#define PIN_PE6__I2SMCC0_DIN3		PINMUX_PIN(PIN_PE6, 5, 2)
+
+#define PIN_PE7				135
+#define PIN_PE7__GPIO			PINMUX_PIN(PIN_PE7, 0, 0)
+#define PIN_PE7__LCDC_DAT3		PINMUX_PIN(PIN_PE7, 1, 1)
+#define PIN_PE7__FLEXCOM2_IO5		PINMUX_PIN(PIN_PE7, 2, 1)
+#define PIN_PE7__PWMH1			PINMUX_PIN(PIN_PE7, 3, 2)
+#define PIN_PE7__TIOA4			PINMUX_PIN(PIN_PE7, 4, 1)
+#define PIN_PE7__I2SMCC0_DOUT1		PINMUX_PIN(PIN_PE7, 5, 2)
+
+#define PIN_PE8				136
+#define PIN_PE8__GPIO			PINMUX_PIN(PIN_PE8, 0, 0)
+#define PIN_PE8__LCDC_DAT4		PINMUX_PIN(PIN_PE8, 1, 1)
+#define PIN_PE8__FLEXCOM2_IO0		PINMUX_PIN(PIN_PE8, 2, 1)
+#define PIN_PE8__PWML2			PINMUX_PIN(PIN_PE8, 3, 2)
+#define PIN_PE8__TIOB4			PINMUX_PIN(PIN_PE8, 4, 1)
+#define PIN_PE8__I2SMCC0_CK		PINMUX_PIN(PIN_PE8, 5, 2)
+
+#define PIN_PE9				137
+#define PIN_PE9__GPIO			PINMUX_PIN(PIN_PE9, 0, 0)
+#define PIN_PE9__LCDC_DAT5		PINMUX_PIN(PIN_PE9, 1, 1)
+#define PIN_PE9__FLEXCOM2_IO1		PINMUX_PIN(PIN_PE9, 2, 1)
+#define PIN_PE9__PWMH2			PINMUX_PIN(PIN_PE9, 3, 2)
+#define PIN_PE9__TCLK4			PINMUX_PIN(PIN_PE9, 4, 1)
+#define PIN_PE9__I2SMCC0_WS		PINMUX_PIN(PIN_PE9, 5, 2)
+
+#define PIN_PE10			138
+#define PIN_PE10__GPIO			PINMUX_PIN(PIN_PE10, 0, 0)
+#define PIN_PE10__LCDC_DAT6		PINMUX_PIN(PIN_PE10, 1, 1)
+#define PIN_PE10__FLEXCOM2_IO6		PINMUX_PIN(PIN_PE10, 2, 1)
+#define PIN_PE10__PWML3			PINMUX_PIN(PIN_PE10, 3, 2)
+#define PIN_PE10__TIOA5			PINMUX_PIN(PIN_PE10, 4, 1)
+#define PIN_PE10__I2SMCC0_DOUT2		PINMUX_PIN(PIN_PE10, 5, 2)
+
+#define PIN_PE11			139
+#define PIN_PE11__GPIO			PINMUX_PIN(PIN_PE11, 0, 0)
+#define PIN_PE11__LCDC_DAT7		PINMUX_PIN(PIN_PE11, 1, 1)
+#define PIN_PE11__PWMH3			PINMUX_PIN(PIN_PE11, 3, 2)
+#define PIN_PE11__TIOB5			PINMUX_PIN(PIN_PE11, 4, 1)
+#define PIN_PE11__I2SMCC0_DOUT3		PINMUX_PIN(PIN_PE11, 5, 2)
+
+#define PIN_PE12			140
+#define PIN_PE12__GPIO			PINMUX_PIN(PIN_PE12, 0, 0)
+#define PIN_PE12__LCDC_DEN		PINMUX_PIN(PIN_PE12, 1, 1)
+#define PIN_PE12__PCK3			PINMUX_PIN(PIN_PE12, 2, 4)
+#define PIN_PE12__PWMEXTRG0		PINMUX_PIN(PIN_PE12, 3, 2)
+#define PIN_PE12__TCLK5			PINMUX_PIN(PIN_PE12, 4, 1)
+#define PIN_PE12__I2SMCC0_DIN0		PINMUX_PIN(PIN_PE12, 5, 2)
+
+#define PIN_PE13			141
+#define PIN_PE13__GPIO			PINMUX_PIN(PIN_PE13, 0, 0)
+#define PIN_PE13__LCDC_PCK		PINMUX_PIN(PIN_PE13, 1, 1)
+#define PIN_PE13__PCK4			PINMUX_PIN(PIN_PE13, 2, 3)
+#define PIN_PE13__PWMEXTRG1		PINMUX_PIN(PIN_PE13, 3, 2)
+#define PIN_PE13__I2SMCC0DOUT0		PINMUX_PIN(PIN_PE13, 5, 2)
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:58 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:58 -0700
Subject: [PATCH v3 13/13] ARM: at91: add new SoC sama7d65
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <465960c9240553753e96a7f4ff3f48879ade7558.1733505542.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add new SoC from at91 family: sama7d65

Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 arch/arm/mach-at91/Kconfig | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 344f5305f69a..2c7179b1baa0 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -58,6 +58,15 @@ config SOC_SAMA5D4
 	help
 	  Select this if you are using one of Microchip's SAMA5D4 family SoC.
 
+config SOC_SAMA7D65
+        bool "SAMA7D65 family"
+        depends on ARCH_MULTI_V7
+        select HAVE_AT91_GENERATED_CLK
+        select HAVE_AT91_SAM9X60_PLL
+        select SOC_SAMA7
+        help
+         Select this if you are using one of Microchip's SAMA7D65 family SoC.
+
 config SOC_SAMA7G5
 	bool "SAMA7G5 family"
 	depends on ARCH_MULTI_V7
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:47 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:47 -0700
Subject: [PATCH v3 02/13] dt-bindings: mfd: atmel,sama5d2-flexcom: add microchip,sama7d65-flexcom
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <550a6dc244a9955782c5b9d7863df4e15bba8a26.1733505542.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add flexcom binding documentation for sama7d65.

Consolidated entries into one enum to match proper coding style.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 .../devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml   | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
index 0dc6a40b63f4..c7d6cf96796c 100644
--- a/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
+++ b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
@@ -19,12 +19,11 @@ properties:
     oneOf:
       - const: atmel,sama5d2-flexcom
       - items:
-          - const: microchip,sam9x7-flexcom
+          - enum:
+              - microchip,sam9x7-flexcom
+              - microchip,sama7d65-flexcom
+              - microchip,sama7g5-flexcom
           - const: atmel,sama5d2-flexcom
-      - items:
-          - const: microchip,sama7g5-flexcom
-          - const: atmel,sama5d2-flexcom
-
 
   reg:
     maxItems: 1
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:52 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:52 -0700
Subject: [PATCH v3 07/13] dt-bindings: clock: Add SAMA7D65 PMC compatible string
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add the `microchip,sama7d65-pmc` compatible string to the existing binding,
since the SAMA7D65 PMC shares the same properties and clock requirements
as the SAMA7G5.

Export MCK3 and MCK5 to be accessed and referenced in DT to assign to
the clocks property for sama7d65 SoC.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 .../devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml       | 2 ++
 include/dt-bindings/clock/at91.h                              | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml
index c9eb60776b4d..885d47dd5724 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,sam9x7-pmc
+              - microchip,sama7d65-pmc
               - microchip,sama7g5-pmc
           - const: syscon
 
@@ -90,6 +91,7 @@ allOf:
             enum:
               - microchip,sam9x60-pmc
               - microchip,sam9x7-pmc
+              - microchip,sama7d65-pmc
               - microchip,sama7g5-pmc
     then:
       properties:
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
index 6ede88c3992d..e37f1b9cdabf 100644
--- a/include/dt-bindings/clock/at91.h
+++ b/include/dt-bindings/clock/at91.h
@@ -42,6 +42,10 @@
 #define PMC_PLLADIV2		(PMC_MAIN + 11)
 #define PMC_LVDSPLL		(PMC_MAIN + 12)
 
+/* SAMA7D65 */
+#define PMC_MCK3               (PMC_MAIN + 13)
+#define PMC_MCK5               (PMC_MAIN + 14)
+
 #ifndef AT91_PMC_MOSCS
 #define AT91_PMC_MOSCS		0		/* MOSCS Flag */
 #define AT91_PMC_LOCKA		1		/* PLLA Lock */
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:56 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:56 -0700
Subject: [PATCH v3 11/13] ARM: dts: microchip: add support for sama7d65_curiosity board
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <e47d8c8cdaec834ce080ef8c34b9976228223c8f.1733505542.git.Ryan.Wanner@microchip.com>

From: Romain Sioen <romain.sioen at microchip.com>

Add device tree support for the SAMA7D65 Curiosity board.
Update the Makefile to include the new device tree file.

uart6 is related to flexcom6, hence not sorted in alphabetical order.

Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 arch/arm/boot/dts/microchip/Makefile          |  3 +
 .../dts/microchip/at91-sama7d65_curiosity.dts | 89 +++++++++++++++++++
 2 files changed, 92 insertions(+)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts

diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
index 470fe46433a9..79cd38fdc7da 100644
--- a/arch/arm/boot/dts/microchip/Makefile
+++ b/arch/arm/boot/dts/microchip/Makefile
@@ -12,6 +12,7 @@ DTC_FLAGS_at91-sama5d2_xplained := -@
 DTC_FLAGS_at91-sama5d3_eds := -@
 DTC_FLAGS_at91-sama5d3_xplained := -@
 DTC_FLAGS_at91-sama5d4_xplained := -@
+DTC_FLAGS_at91-sama7d65_curiosity := -@
 DTC_FLAGS_at91-sama7g54_curiosity := -@
 DTC_FLAGS_at91-sama7g5ek := -@
 dtb-$(CONFIG_SOC_AT91RM9200) += \
@@ -90,6 +91,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
 	at91-sama5d4_xplained.dtb \
 	at91-sama5d4ek.dtb \
 	at91-vinco.dtb
+dtb-$(CONFIG_SOC_SAMA7D65) += \
+	at91-sama7d65_curiosity.dtb
 dtb-$(CONFIG_SOC_SAMA7G5) += \
 	at91-sama7g54_curiosity.dtb \
 	at91-sama7g5ek.dtb
diff --git a/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
new file mode 100644
index 000000000000..3aab2c542d98
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ *  at91-sama7d65_curiosity.dts - Device Tree file for SAMA7D65 Curiosity board
+ *
+ *  Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries
+ *
+ *  Author: Romain Sioen <romain.sioen at microchip.com>
+ *
+ */
+/dts-v1/;
+#include "sama7d65-pinfunc.h"
+#include "sama7d65.dtsi"
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/pinctrl/at91.h>
+
+/ {
+	model = "Microchip SAMA7D65 Curiosity";
+	compatible = "microchip,sama7d65-curiosity", "microchip,sama7d65",
+		     "microchip,sama7d6", "microchip,sama7";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		serial0 = &uart6;
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;
+	};
+};
+
+&flx6 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+	status = "okay";
+};
+
+&uart6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart6_default>;
+	status = "okay";
+};
+
+&main_xtal {
+	clock-frequency = <24000000>;
+};
+
+&pioA {
+	pinctrl_sdmmc1_default: sdmmc1-default {
+		cmd-data {
+			pinmux = <PIN_PB22__SDMMC1_CMD>,
+				 <PIN_PB24__SDMMC1_DAT0>,
+				 <PIN_PB25__SDMMC1_DAT1>,
+				 <PIN_PB26__SDMMC1_DAT2>,
+				 <PIN_PB27__SDMMC1_DAT3>;
+			slew-rate = <0>;
+			bias-disable;
+		};
+
+		ck-cd-rstn-vddsel {
+			pinmux = <PIN_PB23__SDMMC1_CK>,
+				 <PIN_PB21__SDMMC1_RSTN>,
+				 <PIN_PB30__SDMMC1_1V8SEL>,
+				 <PIN_PB29__SDMMC1_CD>,
+				 <PIN_PB28__SDMMC1_WP>;
+			slew-rate = <0>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_uart6_default: uart6-default {
+		pinmux = <PIN_PD18__FLEXCOM6_IO0>,
+			<PIN_PD19__FLEXCOM6_IO1>;
+		bias-disable;
+	};
+};
+
+&sdmmc1 {
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc1_default>;
+	status = "okay";
+};
+
+&slow_xtal {
+	clock-frequency = <32768>;
+};
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:49 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:49 -0700
Subject: [PATCH v3 04/13] dt-bindings: serial: atmel,at91-usart: add microchip,sama7d65-usart
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <05baeeda872ab06d4d84718c535453b787740876.1733505542.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add SAMA7D65 USART compatible to DT bindings documentation.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
index f466c38518c4..087a8926f8b4 100644
--- a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
+++ b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
@@ -26,6 +26,7 @@ properties:
           - enum:
               - microchip,sam9x60-usart
               - microchip,sam9x7-usart
+              - microchip,sama7d65-usart
           - const: atmel,at91sam9260-usart
       - items:
           - const: microchip,sam9x60-dbgu
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:50 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:50 -0700
Subject: [PATCH v3 05/13] dt-bindings: pinctrl: at91-pio4: add microchip,sama7d65-pinctrl
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <b41307089b72fd92f8e2d314e4750194df9c888a.1733505542.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add pinctrl bindings for microchip sama7d65 SoC.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 .../devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt      | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
index 774c3c269c40..a7d7d2eaf10f 100644
--- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
@@ -6,6 +6,7 @@ configure it.
 Required properties:
 - compatible:
 	"atmel,sama5d2-pinctrl"
+	"microchip,sama7d65-pinctrl"
 	"microchip,sama7g5-pinctrl"
 - reg: base address and length of the PIO controller.
 - interrupts: interrupt outputs from the controller, one for each bank.
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:51 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:51 -0700
Subject: [PATCH v3 06/13] dt-bindings: clocks: atmel,at91sam9x5-sckc: add sama7d65
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <b7a8a22a571f6fc2be56a25f26757f37fa8d2bb3.1733505542.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add bindings for SAMA7D65's slow clock controller.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 .../devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml         | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
index c2283cd07f05..d4cf8ae2961e 100644
--- a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
+++ b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
@@ -20,6 +20,7 @@ properties:
       - items:
           - enum:
               - microchip,sam9x7-sckc
+              - microchip,sama7d65-sckc
               - microchip,sama7g5-sckc
           - const: microchip,sam9x60-sckc
 
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:54 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:54 -0700
Subject: [PATCH v3 09/13] ARM: dts: microchip: add sama7d65 SoC DT
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <f62e2600a8e88e4be9d87b346c41bb4781f8f667.1733505542.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add Device Tree for sama7d65 SoC.

Co-developed-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Co-developed-by: Romain Sioen <romain.sioen at microchip.com>
Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
Co-developed-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 arch/arm/boot/dts/microchip/sama7d65.dtsi | 145 ++++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 arch/arm/boot/dts/microchip/sama7d65.dtsi

diff --git a/arch/arm/boot/dts/microchip/sama7d65.dtsi b/arch/arm/boot/dts/microchip/sama7d65.dtsi
new file mode 100644
index 000000000000..0dcd80690210
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/sama7d65.dtsi
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ *  sama7d65.dtsi - Device Tree Include file for SAMA7D65 SoC
+ *
+ *  Copyright (C) 2024 Microchip Technology, Inc. and its subsidiaries
+ *
+ *  Author: Ryan Wanner <Ryan.Wanner at microchip.com>
+ *
+ */
+
+#include <dt-bindings/clock/at91.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/mfd/at91-usart.h>
+
+/ {
+	model = "Microchip SAMA7D65 family SoC";
+	compatible = "microchip,sama7d65";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&gic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+			device_type = "cpu";
+			clocks = <&pmc PMC_TYPE_CORE PMC_CPUPLL>;
+			clock-names = "cpu";
+		};
+	};
+
+	clocks {
+		main_xtal: clock-mainxtal {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+
+		 slow_xtal: clock-slowxtal {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+
+	};
+
+	soc {
+		compatible = "simple-bus";
+		ranges;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		pioa: pinctrl at e0014000 {
+			compatible = "microchip,sama7d65-pinctrl";
+			reg = <0xe0014000 0x800>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 10>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		pmc: clock-controller at e0018000 {
+			compatible = "microchip,sama7d65-pmc", "syscon";
+			reg = <0xe0018000 0x200>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#clock-cells = <2>;
+			clocks = <&clk32k 1>, <&clk32k 0>, <&main_xtal>;
+			clock-names = "td_slck", "md_slck", "main_xtal";
+		};
+
+		clk32k: clock-controller at e001d500 {
+			compatible = "microchip,sama7d65-sckc", "microchip,sam9x60-sckc";
+			reg = <0xe001d500 0x4>;
+			clocks = <&slow_xtal>;
+			#clock-cells = <1>;
+		};
+
+		sdmmc1: mmc at e1208000 {
+			compatible = "microchip,sama7d65-sdhci", "microchip,sam9x60-sdhci";
+			reg = <0xe1208000 0x400>;
+			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 76>, <&pmc PMC_TYPE_GCK 76>;
+			clock-names = "hclock", "multclk";
+			assigned-clocks = <&pmc PMC_TYPE_GCK 76>;
+			assigned-clock-rates = <200000000>;
+			assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_MCK1>;
+			status = "disabled";
+		};
+
+		pit64b0: timer at e1800000 {
+			compatible = "microchip,sama7d65-pit64b", "microchip,sam9x60-pit64b";
+			reg = <0xe1800000 0x100>;
+			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 66>, <&pmc PMC_TYPE_GCK 66>;
+			clock-names = "pclk", "gclk";
+		};
+
+		pit64b1: timer at e1804000 {
+			compatible = "microchip,sama7d65-pit64b", "microchip,sam9x60-pit64b";
+			reg = <0xe1804000 0x100>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 67>, <&pmc PMC_TYPE_GCK 67>;
+			clock-names = "pclk", "gclk";
+		};
+
+		flx6: flexcom at e2020000 {
+			compatible = "microchip,sama7d65-flexcom", "atmel,sama5d2-flexcom";
+			reg = <0xe2020000 0x200>;
+			ranges = <0x0 0xe2020000 0x800>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 40>;
+			status = "disabled";
+
+			uart6: serial at 200 {
+				compatible = "microchip,sama7d65-usart", "atmel,at91sam9260-usart";
+				reg = <0x200 0x200>;
+				atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+				interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pmc PMC_TYPE_PERIPHERAL 40>;
+				clock-names = "usart";
+				atmel,fifo-size = <16>;
+				status = "disabled";
+			};
+		};
+
+		gic: interrupt-controller at e8c11000 {
+			compatible = "arm,cortex-a7-gic";
+			reg = <0xe8c11000 0x1000>,
+			      <0xe8c12000 0x2000>;
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+		};
+	};
+};
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:45 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:45 -0700
Subject: [PATCH v3 00/13] Add support for SAMA7D65
Message-ID: <cover.1733505542.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

This series adds support for the SAMA7D65 SoC.

V2 of this series [1].

For the pinctrl and pit64 timers those will have DTB warnings due to
those bindings not being in the .yaml format.

Changes v1->v2:
- V1 set was sent incorrectly as multiple seprate patches v2 took all
  those patches and put them in 1 thread.

Changes v2->v3:
- Correct the patch order to follow correct practice.
- Correct flexcom dt-binding commit messge to reflect the changes in the
  coding style.
- Add missing SoB tags to patches.
- Moved export clocks to DT patch to be included with the clock binding
  patch.
- Separate Kconfig changes and defconfig changes into different patches
  and removed unused Kconfig params.
- Correct confusing SoB and Co-developed chain.
- Removed unsued nodes in DTSI file and sorted includes
  alphanumerically.
- Fix incorrect dts formatting.
- Separate dts and pinmux changes into two patches.
- Combine PLL and MCK changes into core clock driver patch.
- Correct formatting in main clock driver.
- MMC dt-binding changes are applied for next so have been removed from
  the set [2].

1) https://lore.kernel.org/linux-arm-kernel/cover.1732030972.git.Ryan.Wanner at microchip.com/T/#m9691b4d58b62f36f6cbac1d06883c985766c2c0d
2) https://lore.kernel.org/linux-arm-kernel/cover.1732030972.git.Ryan.Wanner at microchip.com/T/#mccf6521c07e74e1c7dc61b09ae0ebdbbdde73a28

Dharma Balasubiramani (6):
  dt-bindings: mfd: atmel,sama5d2-flexcom: add
    microchip,sama7d65-flexcom
  dt-bindings: atmel-sysreg: add sama7d65 RAM and PIT
  dt-bindings: serial: atmel,at91-usart: add microchip,sama7d65-usart
  dt-bindings: pinctrl: at91-pio4: add microchip,sama7d65-pinctrl
  dt-bindings: clocks: atmel,at91sam9x5-sckc: add sama7d65
  dt-bindings: clock: Add SAMA7D65 PMC compatible string

Romain Sioen (2):
  dt-bindings: ARM: at91: Document Microchip SAMA7D65 Curiosity
  ARM: dts: microchip: add support for sama7d65_curiosity board

Ryan Wanner (5):
  clk: at91: sama7d65: add sama7d65 pmc driver
  ARM: dts: microchip: add sama7d65 SoC DT
  ARM: dts: at91: Add sama7d65 pinmux
  ARM: configs: at91: sama7: add new SoC config
  ARM: at91: add new SoC sama7d65

 .../devicetree/bindings/arm/atmel-at91.yaml   |    7 +
 .../devicetree/bindings/arm/atmel-sysregs.txt |   14 +-
 .../bindings/clock/atmel,at91rm9200-pmc.yaml  |    2 +
 .../bindings/clock/atmel,at91sam9x5-sckc.yaml |    1 +
 .../bindings/mfd/atmel,sama5d2-flexcom.yaml   |    9 +-
 .../pinctrl/atmel,at91-pio4-pinctrl.txt       |    1 +
 .../bindings/serial/atmel,at91-usart.yaml     |    1 +
 arch/arm/boot/dts/microchip/Makefile          |    3 +
 .../dts/microchip/at91-sama7d65_curiosity.dts |   89 ++
 .../arm/boot/dts/microchip/sama7d65-pinfunc.h |  947 ++++++++++++
 arch/arm/boot/dts/microchip/sama7d65.dtsi     |  145 ++
 arch/arm/configs/multi_v7_defconfig           |    1 +
 arch/arm/configs/sama7_defconfig              |    1 +
 arch/arm/mach-at91/Kconfig                    |    9 +
 drivers/clk/at91/Makefile                     |    1 +
 drivers/clk/at91/clk-master.c                 |    2 +-
 drivers/clk/at91/clk-sam9x60-pll.c            |    2 +-
 drivers/clk/at91/pmc.c                        |    1 +
 drivers/clk/at91/sama7d65.c                   | 1373 +++++++++++++++++
 include/dt-bindings/clock/at91.h              |    4 +
 20 files changed, 2600 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
 create mode 100644 arch/arm/boot/dts/microchip/sama7d65-pinfunc.h
 create mode 100644 arch/arm/boot/dts/microchip/sama7d65.dtsi
 create mode 100644 drivers/clk/at91/sama7d65.c

-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:46 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:46 -0700
Subject: [PATCH v3 01/13] dt-bindings: ARM: at91: Document Microchip SAMA7D65 Curiosity
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <d5a22763a2081daa0d2155e2c05b7dc0eb468610.1733505542.git.Ryan.Wanner@microchip.com>

From: Romain Sioen <romain.sioen at microchip.com>

Document device tree binding of the Microchip SAMA7D65 Curiosity board.

Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index 7160ec80ac1b..0ec29366e6c2 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -180,6 +180,13 @@ properties:
           - const: atmel,sama5d4
           - const: atmel,sama5
 
+      - description: Microchip SAMA7D65 Curiosity Board
+        items:
+          - const: microchip,sama7d65-curiosity
+          - const: microchip,sama7d65
+          - const: microchip,sama7d6
+          - const: microchip,sama7
+
       - items:
           - const: microchip,sama7g5ek # SAMA7G5 Evaluation Kit
           - const: microchip,sama7g5
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:48 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:48 -0700
Subject: [PATCH v3 03/13] dt-bindings: atmel-sysreg: add sama7d65 RAM and PIT
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <96e64f01eee264ad0ac4c720a7a1cab4f95c206b.1733505542.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add SAMA7D65 RAM controller, PIT64 DT bindings.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 .../devicetree/bindings/arm/atmel-sysregs.txt      | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
index 76e2b7978250..93c2a5a341f3 100644
--- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
@@ -13,6 +13,7 @@ PIT Timer required properties:
 PIT64B Timer required properties:
 - compatible: Should be "microchip,sam9x60-pit64b" or
 			"microchip,sam9x7-pit64b", "microchip,sam9x60-pit64b"
+			"microchip,sama7d65-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.
@@ -27,12 +28,13 @@ Its subnodes can be:
 - watchdog: compatible should be "atmel,at91rm9200-wdt"
 
 RAMC SDRAM/DDR Controller required properties:
-- compatible: Should be "atmel,at91rm9200-sdramc", "syscon"
-			"atmel,at91sam9260-sdramc",
-			"atmel,at91sam9g45-ddramc",
-			"atmel,sama5d3-ddramc",
-			"microchip,sam9x60-ddramc",
-			"microchip,sama7g5-uddrc",
+- compatible: Should be "atmel,at91rm9200-sdramc", "syscon" or
+			"atmel,at91sam9260-sdramc" or
+			"atmel,at91sam9g45-ddramc" or
+			"atmel,sama5d3-ddramc" or
+			"microchip,sam9x60-ddramc" or
+			"microchip,sama7g5-uddrc" or
+			"microchip,sama7d65-uddrc","microchip,sama7g5-uddrc" or
 			"microchip,sam9x7-ddramc", "atmel,sama5d3-ddramc".
 - reg: Should contain registers location and length
 
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:57 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:57 -0700
Subject: [PATCH v3 12/13] ARM: configs: at91: sama7: add new SoC config
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <e5a1311100a4f05fdc44107e124129d2d93df2e0.1733505542.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add sama7d65 to the sama7_defconfig.

Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 arch/arm/configs/sama7_defconfig    | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 758276027dbc..b1dcec1a6df5 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -20,6 +20,7 @@ CONFIG_ARCH_AT91=y
 CONFIG_SOC_SAMA5D2=y
 CONFIG_SOC_SAMA5D3=y
 CONFIG_SOC_SAMA5D4=y
+CONFIG_SOC_SAMA7D65=y
 CONFIG_SOC_SAMA7G5=y
 CONFIG_SOC_LAN966=y
 CONFIG_ARCH_BCM=y
diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 1a2e93c8ee71..ea7ddf640ba7 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -12,6 +12,7 @@ CONFIG_EXPERT=y
 # CONFIG_IO_URING is not set
 CONFIG_KALLSYMS_ALL=y
 CONFIG_ARCH_AT91=y
+CONFIG_SOC_SAMA7D65=y
 CONFIG_SOC_SAMA7G5=y
 CONFIG_ATMEL_CLOCKSOURCE_TCB=y
 # CONFIG_CACHE_L2X0 is not set
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec  6 11:59:53 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 6 Dec 2024 12:59:53 -0700
Subject: [PATCH v3 08/13] clk: at91: sama7d65: add sama7d65 pmc driver
In-Reply-To: <cover.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <6cf9921c6d312193c34f6f5cbd9eda7d0f9f317c.1733505542.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add clock support for SAMA7D65 SoC.

Increase maximum number of valid master clocks. The PMC for the SAMA7D65
requires 9 master clocks.

Increase maximum amount of PLLs to 9 to support SAMA7D65 SoC PLL
requirements.

Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 drivers/clk/at91/Makefile          |    1 +
 drivers/clk/at91/clk-master.c      |    2 +-
 drivers/clk/at91/clk-sam9x60-pll.c |    2 +-
 drivers/clk/at91/pmc.c             |    1 +
 drivers/clk/at91/sama7d65.c        | 1373 ++++++++++++++++++++++++++++
 5 files changed, 1377 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/at91/sama7d65.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 8e3684ba2c74..5e638eb15aba 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -25,3 +25,4 @@ 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
 obj-$(CONFIG_SOC_SAMA7G5) += sama7g5.o
+obj-$(CONFIG_SOC_SAMA7D65) += sama7d65.o
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index 15c46489ba85..7a544e429d34 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -20,7 +20,7 @@
 
 #define PMC_MCR_CSS_SHIFT	(16)
 
-#define MASTER_MAX_ID		4
+#define MASTER_MAX_ID		9
 
 #define to_clk_master(hw) container_of(hw, struct clk_master, hw)
 
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index fda041102224..cefd9948e103 100644
--- a/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -23,7 +23,7 @@
 #define UPLL_DIV		2
 #define PLL_MUL_MAX		(FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
 
-#define PLL_MAX_ID		7
+#define PLL_MAX_ID		9
 
 struct sam9x60_pll_core {
 	struct regmap *regmap;
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 5aa9c1f1c886..acf780a81589 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -151,6 +151,7 @@ static struct syscore_ops pmc_syscore_ops = {
 static const struct of_device_id pmc_dt_ids[] = {
 	{ .compatible = "atmel,sama5d2-pmc" },
 	{ .compatible = "microchip,sama7g5-pmc", },
+	{ .compatible = "microchip,sama7d65-pmc", },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/clk/at91/sama7d65.c b/drivers/clk/at91/sama7d65.c
new file mode 100644
index 000000000000..7b8dfd6d8b64
--- /dev/null
+++ b/drivers/clk/at91/sama7d65.c
@@ -0,0 +1,1373 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SAMA7D65 PMC code.
+ *
+ * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Ryan Wanner <ryan.wanner 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(pmc_mck0_lock);
+static DEFINE_SPINLOCK(pmc_mckX_lock);
+
+#define PMC_INDEX_MAX	25
+
+/*
+ * PLL clocks identifiers
+ * @PLL_ID_CPU:		CPU PLL identifier
+ * @PLL_ID_SYS:		System PLL identifier
+ * @PLL_ID_DDR:		DDR PLL identifier
+ * @PLL_ID_GPU:		Graphics subsystem PLL identifier
+ * @PLL_ID_BAUD:	Baud PLL identifier
+ * @PLL_ID_AUDIO:	Audio PLL identifier
+ * @PLL_ID_ETH:		Ethernet PLL identifier
+ * @PLL_ID_LVDS:	LVDS PLL identifier
+ * @PLL_ID_USB:		USB PLL identifier
+ */
+enum pll_ids {
+	PLL_ID_CPU,
+	PLL_ID_SYS,
+	PLL_ID_DDR,
+	PLL_ID_GPU,
+	PLL_ID_BAUD,
+	PLL_ID_AUDIO,
+	PLL_ID_ETH,
+	PLL_ID_LVDS,
+	PLL_ID_USB,
+	PLL_ID_MAX
+};
+
+/*
+ * PLL component identifier
+ * @PLL_COMPID_FRAC: Fractional PLL component identifier
+ * @PLL_COMPID_DIV0: 1st PLL divider component identifier
+ * @PLL_COMPID_DIV1: 2nd PLL divider component identifier
+ */
+enum pll_component_id {
+	PLL_COMPID_FRAC,
+	PLL_COMPID_DIV0,
+	PLL_COMPID_DIV1,
+	PLL_COMPID_MAX
+};
+
+/*
+ * PLL type identifiers
+ * @PLL_TYPE_FRAC:	fractional PLL identifier
+ * @PLL_TYPE_DIV:	divider PLL identifier
+ */
+enum pll_type {
+	PLL_TYPE_FRAC,
+	PLL_TYPE_DIV,
+};
+
+/* Layout for fractional PLLs. */
+static const struct clk_pll_layout pll_layout_frac = {
+	.mul_mask	= GENMASK(31, 24),
+	.frac_mask	= GENMASK(21, 0),
+	.mul_shift	= 24,
+	.frac_shift	= 0,
+};
+
+/* Layout for DIVPMC dividers. */
+static const struct clk_pll_layout pll_layout_divpmc = {
+	.div_mask	= GENMASK(7, 0),
+	.endiv_mask	= BIT(29),
+	.div_shift	= 0,
+	.endiv_shift	= 29,
+};
+
+/* Layout for DIVIO dividers. */
+static const struct clk_pll_layout pll_layout_divio = {
+	.div_mask	= GENMASK(19, 12),
+	.endiv_mask	= BIT(30),
+	.div_shift	= 12,
+	.endiv_shift	= 30,
+};
+
+/*
+ * CPU PLL output range.
+ * Notice: The upper limit has been setup to 1000000002 due to hardware
+ * block which cannot output exactly 1GHz.
+ */
+static const struct clk_range cpu_pll_outputs[] = {
+	{ .min = 2343750, .max = 1000000002 },
+};
+
+/* PLL output range. */
+static const struct clk_range pll_outputs[] = {
+	{ .min = 2343750, .max = 1200000000 },
+};
+
+/*
+ * Min: fCOREPLLCK = 600 MHz, PMC_PLL_CTRL0.DIVPMC = 255
+ * Max: fCOREPLLCK = 800 MHz, PMC_PLL_CTRL0.DIVPMC = 0
+ */
+static const struct clk_range lvdspll_outputs[] = {
+	{ .min = 16406250, .max = 800000000 },
+};
+
+static const struct clk_range upll_outputs[] = {
+	{ .min = 480000000, .max = 480000000 },
+};
+
+/* Fractional PLL core output range. */
+static const struct clk_range core_outputs[] = {
+	{ .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_range lvdspll_core_outputs[] = {
+	{ .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_range upll_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. */
+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,
+};
+
+static const struct clk_pll_characteristics lvdspll_characteristics = {
+	.input = { .min = 12000000, .max = 50000000 },
+	.num_output = ARRAY_SIZE(lvdspll_outputs),
+	.output = lvdspll_outputs,
+	.core_output = lvdspll_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,
+};
+
+/*
+ * SAMA7D65 PLL possible parents
+ * @SAMA7D65_PLL_PARENT_MAINCK: MAINCK is PLL a parent
+ * @SAMA7D65_PLL_PARENT_MAIN_XTAL: MAIN XTAL is a PLL parent
+ * @SAMA7D65_PLL_PARENT_FRACCK: Frac PLL is a PLL parent (for PLL dividers)
+ */
+enum sama7d65_pll_parent {
+	SAMA7D65_PLL_PARENT_MAINCK,
+	SAMA7D65_PLL_PARENT_MAIN_XTAL,
+	SAMA7D65_PLL_PARENT_FRACCK,
+};
+
+/*
+ * PLL clocks description
+ * @n:		clock name
+ * @l:		clock layout
+ * @c:		clock characteristics
+ * @hw:		pointer to clk_hw
+ * @t:		clock type
+ * @f:		clock flags
+ * @p:		clock parent
+ * @eid:	export index in sama7d65->chws[] array
+ * @safe_div:	intermediate divider need to be set on PRE_RATE_CHANGE
+ *		notification
+ */
+static struct sama7d65_pll {
+	const char *n;
+	const struct clk_pll_layout *l;
+	const struct clk_pll_characteristics *c;
+	struct clk_hw *hw;
+	unsigned long f;
+	enum sama7d65_pll_parent p;
+	u8 t;
+	u8 eid;
+	u8 safe_div;
+} sama7d65_plls[][PLL_COMPID_MAX] = {
+	[PLL_ID_CPU] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "cpupll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &cpu_pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			/*
+			 * This feeds cpupll_divpmcck which feeds CPU. It should
+			 * not be disabled.
+			 */
+			.f = CLK_IS_CRITICAL,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "cpupll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &cpu_pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			/* This feeds CPU. It should not be disabled. */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			.eid = PMC_CPUPLL,
+			/*
+			 * Safe div=15 should be safe even for switching b/w 1GHz and
+			 * 90MHz (frac pll might go up to 1.2GHz).
+			 */
+			.safe_div = 15,
+		},
+	},
+
+	[PLL_ID_SYS] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "syspll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			/*
+			 * This feeds syspll_divpmcck which may feed critical parts
+			 * of the systems like timers. Therefore it should not be
+			 * disabled.
+			 */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "syspll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			/*
+			 * This may feed critical parts of the systems like timers.
+			 * Therefore it should not be disabled.
+			 */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+			.eid = PMC_SYSPLL,
+		},
+	},
+
+	[PLL_ID_DDR] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "ddrpll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			/*
+			 * This feeds ddrpll_divpmcck which feeds DDR. It should not
+			 * be disabled.
+			 */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "ddrpll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			/* This feeds DDR. It should not be disabled. */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+		},
+	},
+
+	[PLL_ID_GPU] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "gpupll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "gpupll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+		},
+	},
+
+	[PLL_ID_BAUD] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "baudpll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "baudpll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_BAUDPLL,
+		},
+	},
+
+	[PLL_ID_AUDIO] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "audiopll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "audiopll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_AUDIOPMCPLL,
+		},
+
+		[PLL_COMPID_DIV1] = {
+			.n = "audiopll_diviock",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divio,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_AUDIOIOPLL,
+		},
+	},
+
+	[PLL_ID_ETH] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "ethpll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "ethpll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_ETHPLL,
+		},
+	},
+
+	[PLL_ID_LVDS] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "lvdspll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
+			.l = &pll_layout_frac,
+			.c = &lvdspll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "lvdspll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &lvdspll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_LVDSPLL,
+		},
+	},
+
+	[PLL_ID_USB] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "usbpll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
+			.l = &pll_layout_frac,
+			.c = &upll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "usbpll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &upll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_UTMI,
+		},
+	},
+};
+
+/* Used to create an array entry identifying a PLL by its components. */
+#define PLL_IDS_TO_ARR_ENTRY(_id, _comp) { PLL_ID_##_id, PLL_COMPID_##_comp}
+
+/*
+ * Master clock (MCK[0..9]) description
+ * @n:			clock name
+ * @ep_chg_chg_id:	index in parents array that specifies the changeable
+ * @ep:			extra parents names array (entry formed by PLL components
+ *			identifiers (see enum pll_component_id))
+ * @hw:			pointer to clk_hw
+ *			parent
+ * @ep_count:		extra parents count
+ * @ep_mux_table:	mux table for extra parents
+ * @id:			clock id
+ * @eid:		export index in sama7d65->chws[] array
+ * @c:			true if clock is critical and cannot be disabled
+ */
+static struct {
+	const char *n;
+	struct {
+		int pll_id;
+		int pll_compid;
+	} ep[4];
+	struct clk_hw *hw;
+	int ep_chg_id;
+	u8 ep_count;
+	u8 ep_mux_table[4];
+	u8 id;
+	u8 eid;
+	u8 c;
+} sama7d65_mckx[] = {
+	{ .n = "mck0", }, /* Dummy entry for MCK0 to store hw in probe. */
+	{ .n = "mck1",
+	  .id = 1,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_count = 1,
+	  .ep_chg_id = INT_MIN,
+	  .eid = PMC_MCK1,
+	  .c = 1, },
+
+	{ .n = "mck2",
+	  .id = 2,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), },
+	  .ep_mux_table = { 5, 6, },
+	  .ep_count = 2,
+	  .ep_chg_id = INT_MIN,
+	  .c = 1, },
+
+	{ .n = "mck3",
+	  .id = 3,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), },
+	  .ep_mux_table = { 5, 6, },
+	  .ep_count = 2,
+	  .ep_chg_id = INT_MIN,
+	  .eid = PMC_MCK3,
+	  .c = 1, },
+
+	{ .n = "mck4",
+	  .id = 4,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_count = 1,
+	  .ep_chg_id = INT_MIN,
+	  .c = 1, },
+
+	{ .n = "mck5",
+	  .id = 5,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_count = 1,
+	  .ep_chg_id = INT_MIN,
+	  .eid = PMC_MCK5,
+	  .c = 1, },
+
+	{ .n = "mck6",
+	  .id = 6,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_chg_id = INT_MIN,
+	  .ep_count = 1,
+	  .c = 1, },
+
+	{ .n = "mck7",
+	  .id = 7,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_chg_id = INT_MIN,
+	  .ep_count = 1, },
+
+	{ .n = "mck8",
+	  .id = 8,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_chg_id = INT_MIN,
+	  .ep_count = 1, },
+
+	{ .n = "mck9",
+	  .id = 9,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_chg_id = INT_MIN,
+	  .ep_count = 1, },
+};
+
+/*
+ * System clock description
+ * @n:	clock name
+ * @p:	clock parent name
+ * @id: clock id
+ */
+static const struct {
+	const char *n;
+	const char *p;
+	u8 id;
+} sama7d65_systemck[] = {
+	{ .n = "uhpck",		.p = "usbck", .id = 6 },
+	{ .n = "pck0",		.p = "prog0", .id = 8, },
+	{ .n = "pck1",		.p = "prog1", .id = 9, },
+	{ .n = "pck2",		.p = "prog2", .id = 10, },
+	{ .n = "pck3",		.p = "prog3", .id = 11, },
+	{ .n = "pck4",		.p = "prog4", .id = 12, },
+	{ .n = "pck5",		.p = "prog5", .id = 13, },
+	{ .n = "pck6",		.p = "prog6", .id = 14, },
+	{ .n = "pck7",		.p = "prog7", .id = 15, },
+};
+
+/* Mux table for programmable clocks. */
+static u32 sama7d65_prog_mux_table[] = { 0, 1, 2, 5, 7, 8, 9, 10, 12 };
+
+/*
+ * Peripheral clock parent hw identifier (used to index in sama7d65_mckx[])
+ * @PCK_PARENT_HW_MCK0: pck parent hw identifier is MCK0
+ * @PCK_PARENT_HW_MCK1: pck parent hw identifier is MCK1
+ * @PCK_PARENT_HW_MCK2: pck parent hw identifier is MCK2
+ * @PCK_PARENT_HW_MCK3: pck parent hw identifier is MCK3
+ * @PCK_PARENT_HW_MCK4: pck parent hw identifier is MCK4
+ * @PCK_PARENT_HW_MCK5: pck parent hw identifier is MCK5
+ * @PCK_PARENT_HW_MCK6: pck parent hw identifier is MCK6
+ * @PCK_PARENT_HW_MCK7: pck parent hw identifier is MCK7
+ * @PCK_PARENT_HW_MCK8: pck parent hw identifier is MCK8
+ * @PCK_PARENT_HW_MCK9: pck parent hw identifier is MCK9
+ * @PCK_PARENT_HW_MAX: max identifier
+ */
+enum sama7d65_pck_parent_hw_id {
+	PCK_PARENT_HW_MCK0,
+	PCK_PARENT_HW_MCK1,
+	PCK_PARENT_HW_MCK2,
+	PCK_PARENT_HW_MCK3,
+	PCK_PARENT_HW_MCK4,
+	PCK_PARENT_HW_MCK5,
+	PCK_PARENT_HW_MCK6,
+	PCK_PARENT_HW_MCK7,
+	PCK_PARENT_HW_MCK8,
+	PCK_PARENT_HW_MCK9,
+	PCK_PARENT_HW_MAX
+};
+
+/*
+ * Peripheral clock description
+ * @n:		clock name
+ * @p:		clock parent hw id
+ * @r:		clock range values
+ * @id:		clock id
+ * @chgp:	index in parent array of the changeable parent
+ */
+static struct {
+	const char *n;
+	enum sama7d65_pck_parent_hw_id p;
+	struct clk_range r;
+	u8 chgp;
+	u8 id;
+} sama7d65_periphck[] = {
+	{ .n = "pioA_clk",	.p = PCK_PARENT_HW_MCK0, .id = 10, },
+	{ .n = "securam_clk",	.p = PCK_PARENT_HW_MCK0, .id = 17, },
+	{ .n = "sfr_clk",	.p = PCK_PARENT_HW_MCK7, .id = 18, },
+	{ .n = "hsmc_clk",	.p = PCK_PARENT_HW_MCK5, .id = 20, },
+	{ .n = "xdmac0_clk",	.p = PCK_PARENT_HW_MCK6, .id = 21, },
+	{ .n = "xdmac1_clk",	.p = PCK_PARENT_HW_MCK6, .id = 22, },
+	{ .n = "xdmac2_clk",	.p = PCK_PARENT_HW_MCK1, .id = 23, },
+	{ .n = "acc_clk",	.p = PCK_PARENT_HW_MCK7, .id = 24, },
+	{ .n = "aes_clk",	.p = PCK_PARENT_HW_MCK6, .id = 26, },
+	{ .n = "tzaesbasc_clk",	.p = PCK_PARENT_HW_MCK8, .id = 27, },
+	{ .n = "asrc_clk",	.p = PCK_PARENT_HW_MCK9, .id = 29, .r = { .max = 200000000, }, },
+	{ .n = "cpkcc_clk",	.p = PCK_PARENT_HW_MCK0, .id = 30, },
+	{ .n = "eic_clk",	.p = PCK_PARENT_HW_MCK7, .id = 33, },
+	{ .n = "flex0_clk",	.p = PCK_PARENT_HW_MCK7, .id = 34, },
+	{ .n = "flex1_clk",	.p = PCK_PARENT_HW_MCK7, .id = 35, },
+	{ .n = "flex2_clk",	.p = PCK_PARENT_HW_MCK7, .id = 36, },
+	{ .n = "flex3_clk",	.p = PCK_PARENT_HW_MCK7, .id = 37, },
+	{ .n = "flex4_clk",	.p = PCK_PARENT_HW_MCK8, .id = 38, },
+	{ .n = "flex5_clk",	.p = PCK_PARENT_HW_MCK8, .id = 39, },
+	{ .n = "flex6_clk",	.p = PCK_PARENT_HW_MCK8, .id = 40, },
+	{ .n = "flex7_clk",	.p = PCK_PARENT_HW_MCK8, .id = 41, },
+	{ .n = "flex8_clk",	.p = PCK_PARENT_HW_MCK9, .id = 42, },
+	{ .n = "flex9_clk",	.p = PCK_PARENT_HW_MCK9, .id = 43, },
+	{ .n = "flex10_clk",	.p = PCK_PARENT_HW_MCK9, .id = 44, },
+	{ .n = "gmac0_clk",	.p = PCK_PARENT_HW_MCK6, .id = 46, },
+	{ .n = "gmac1_clk",	.p = PCK_PARENT_HW_MCK6, .id = 47, },
+	{ .n = "gmac0_tsu_clk",	.p = PCK_PARENT_HW_MCK1, .id = 49, },
+	{ .n = "gmac1_tsu_clk",	.p = PCK_PARENT_HW_MCK1, .id = 50, },
+	{ .n = "icm_clk",	.p = PCK_PARENT_HW_MCK5, .id = 53, },
+	{ .n = "i2smcc0_clk",	.p = PCK_PARENT_HW_MCK9, .id = 54, .r = { .max = 200000000, }, },
+	{ .n = "i2smcc1_clk",	.p = PCK_PARENT_HW_MCK9, .id = 55, .r = { .max = 200000000, }, },
+	{ .n = "lcd_clk",	.p = PCK_PARENT_HW_MCK3, .id = 56, },
+	{ .n = "matrix_clk",	.p = PCK_PARENT_HW_MCK5, .id = 57, },
+	{ .n = "mcan0_clk",	.p = PCK_PARENT_HW_MCK5, .id = 58, .r = { .max = 200000000, }, },
+	{ .n = "mcan1_clk",	.p = PCK_PARENT_HW_MCK5, .id = 59, .r = { .max = 200000000, }, },
+	{ .n = "mcan2_clk",	.p = PCK_PARENT_HW_MCK5, .id = 60, .r = { .max = 200000000, }, },
+	{ .n = "mcan3_clk",	.p = PCK_PARENT_HW_MCK5, .id = 61, .r = { .max = 200000000, }, },
+	{ .n = "mcan4_clk",	.p = PCK_PARENT_HW_MCK5, .id = 62, .r = { .max = 200000000, }, },
+	{ .n = "pdmc0_clk",	.p = PCK_PARENT_HW_MCK9, .id = 64, .r = { .max = 200000000, }, },
+	{ .n = "pdmc1_clk",	.p = PCK_PARENT_HW_MCK9, .id = 65, .r = { .max = 200000000, }, },
+	{ .n = "pit64b0_clk",	.p = PCK_PARENT_HW_MCK7, .id = 66, },
+	{ .n = "pit64b1_clk",	.p = PCK_PARENT_HW_MCK7, .id = 67, },
+	{ .n = "pit64b2_clk",	.p = PCK_PARENT_HW_MCK7, .id = 68, },
+	{ .n = "pit64b3_clk",	.p = PCK_PARENT_HW_MCK8, .id = 69, },
+	{ .n = "pit64b4_clk",	.p = PCK_PARENT_HW_MCK8, .id = 70, },
+	{ .n = "pit64b5_clk",	.p = PCK_PARENT_HW_MCK8, .id = 71, },
+	{ .n = "pwm_clk",	.p = PCK_PARENT_HW_MCK7, .id = 72, },
+	{ .n = "qspi0_clk",	.p = PCK_PARENT_HW_MCK5, .id = 73, },
+	{ .n = "qspi1_clk",	.p = PCK_PARENT_HW_MCK5, .id = 74, },
+	{ .n = "sdmmc0_clk",	.p = PCK_PARENT_HW_MCK1, .id = 75, },
+	{ .n = "sdmmc1_clk",	.p = PCK_PARENT_HW_MCK1, .id = 76, },
+	{ .n = "sdmmc2_clk",	.p = PCK_PARENT_HW_MCK1, .id = 77, },
+	{ .n = "sha_clk",	.p = PCK_PARENT_HW_MCK6, .id = 78, },
+	{ .n = "spdifrx_clk",	.p = PCK_PARENT_HW_MCK9, .id = 79, .r = { .max = 200000000, }, },
+	{ .n = "spdiftx_clk",	.p = PCK_PARENT_HW_MCK9, .id = 80, .r = { .max = 200000000, }, },
+	{ .n = "ssc0_clk",	.p = PCK_PARENT_HW_MCK7, .id = 81, .r = { .max = 200000000, }, },
+	{ .n = "ssc1_clk",	.p = PCK_PARENT_HW_MCK8, .id = 82, .r = { .max = 200000000, }, },
+	{ .n = "tcb0_ch0_clk",	.p = PCK_PARENT_HW_MCK8, .id = 83, .r = { .max = 200000000, }, },
+	{ .n = "tcb0_ch1_clk",	.p = PCK_PARENT_HW_MCK8, .id = 84, .r = { .max = 200000000, }, },
+	{ .n = "tcb0_ch2_clk",	.p = PCK_PARENT_HW_MCK8, .id = 85, .r = { .max = 200000000, }, },
+	{ .n = "tcb1_ch0_clk",	.p = PCK_PARENT_HW_MCK5, .id = 86, .r = { .max = 200000000, }, },
+	{ .n = "tcb1_ch1_clk",	.p = PCK_PARENT_HW_MCK5, .id = 87, .r = { .max = 200000000, }, },
+	{ .n = "tcb1_ch2_clk",	.p = PCK_PARENT_HW_MCK5, .id = 88, .r = { .max = 200000000, }, },
+	{ .n = "tcpca_clk",	.p = PCK_PARENT_HW_MCK5, .id = 89, },
+	{ .n = "tcpcb_clk",	.p = PCK_PARENT_HW_MCK5, .id = 90, },
+	{ .n = "tdes_clk",	.p = PCK_PARENT_HW_MCK6, .id = 91, },
+	{ .n = "trng_clk",	.p = PCK_PARENT_HW_MCK6, .id = 92, },
+	{ .n = "udphsa_clk",	.p = PCK_PARENT_HW_MCK5, .id = 99, },
+	{ .n = "udphsb_clk",	.p = PCK_PARENT_HW_MCK5, .id = 100, },
+	{ .n = "uhphs_clk",	.p = PCK_PARENT_HW_MCK5, .id = 101, },
+	{ .n = "dsi_clk",	.p = PCK_PARENT_HW_MCK3, .id = 103, },
+	{ .n = "lvdsc_clk",	.p = PCK_PARENT_HW_MCK3, .id = 104, },
+};
+
+/*
+ * Generic clock description
+ * @n:			clock name
+ * @pp:			PLL parents (entry formed by PLL components identifiers
+ *			(see enum pll_component_id))
+ * @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;
+	struct {
+		int pll_id;
+		int pll_compid;
+	} pp[8];
+	const char pp_mux_table[8];
+	struct clk_range r;
+	int pp_chg_id;
+	u8 pp_count;
+	u8 id;
+} sama7d65_gck[] = {
+	{ .n  = "adc_gclk",
+	  .id = 25,
+	  .r = { .max = 100000000, },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 8, 9, },
+	  .pp_count = 2,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "asrc_gclk",
+	  .id = 29,
+	  .r = { .max = 200000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex0_gclk",
+	  .id = 34,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = {8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex1_gclk",
+	  .id = 35,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = {8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex2_gclk",
+	  .id = 36,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = {8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex3_gclk",
+	  .id = 37,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = {8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex4_gclk",
+	  .id = 38,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex5_gclk",
+	  .id = 39,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex6_gclk",
+	  .id = 40,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex7_gclk",
+	  .id = 41,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex8_gclk",
+	  .id = 42,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex9_gclk",
+	  .id = 43,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex10_gclk",
+	  .id = 44,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "gmac0_gclk",
+	  .id = 46,
+	  .r = { .max = 125000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 10, },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "gmac1_gclk",
+	  .id = 47,
+	  .r = { .max = 125000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 10, },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "gmac0_tsu_gclk",
+	  .id = 49,
+	  .r = { .max = 400000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {10, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "gmac1_tsu_gclk",
+	  .id = 50,
+	  .r = { .max = 400000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 10, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "i2smcc0_gclk",
+	  .id = 54,
+	  .r = { .max = 100000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "i2smcc1_gclk",
+	  .id = 55,
+	  .r = { .max = 100000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n = "lcdc_gclk",
+	  .id = 56,
+	  .r = { .max = 90000000 },
+	  .pp_count = 0,
+	  .pp_chg_id = INT_MIN,
+	},
+
+	{ .n  = "mcan0_gclk",
+	  .id = 58,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "mcan1_gclk",
+	  .id = 59,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "mcan2_gclk",
+	  .id = 60,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "mcan3_gclk",
+	  .id = 61,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "mcan4_gclk",
+	  .id = 62,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "pdmc0_gclk",
+	  .id = 64,
+	  .r = { .max = 80000000  },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9 },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pdmc1_gclk",
+	  .id = 65,
+	  .r = { .max = 80000000, },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b0_gclk",
+	  .id = 66,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b1_gclk",
+	  .id = 67,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b2_gclk",
+	  .id = 68,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b3_gclk",
+	  .id = 69,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b4_gclk",
+	  .id = 70,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b5_gclk",
+	  .id = 71,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "qspi0_gclk",
+	  .id = 73,
+	  .r = { .max = 400000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 5, 8, },
+	  .pp_count = 2,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "qspi1_gclk",
+	  .id = 74,
+	  .r = { .max = 266000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 5, 8, },
+	  .pp_count = 2,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "sdmmc0_gclk",
+	  .id = 75,
+	  .r = { .max = 208000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 10, },
+	  .pp_count = 2,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "sdmmc1_gclk",
+	  .id = 76,
+	  .r = { .max = 208000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 10, },
+	  .pp_count = 2,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "sdmmc2_gclk",
+	  .id = 77,
+	  .r = { .max = 208000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 10 },
+	  .pp_count = 2,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "spdifrx_gclk",
+	  .id = 79,
+	  .r = { .max = 150000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n = "spdiftx_gclk",
+	  .id = 80,
+	  .r = { .max = 25000000  },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "tcb0_ch0_gclk",
+	  .id = 83,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "tcb1_ch0_gclk",
+	  .id = 86,
+	  .r = { .max = 67000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n = "DSI_gclk",
+	  .id = 103,
+	  .r = {.max = 27000000},
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .pp_mux_table = {5},
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n = "I3CC_gclk",
+	  .id = 105,
+	  .r = {.max = 125000000},
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+};
+
+/* MCK0 characteristics. */
+static const struct clk_master_characteristics mck0_characteristics = {
+	.output = { .min = 32768, .max = 200000000 },
+	.divisors = { 1, 2, 4, 3, 5 },
+	.have_div3_pres = 1,
+};
+
+/* MCK0 layout. */
+static const struct clk_master_layout mck0_layout = {
+	.mask = 0x773,
+	.pres_shift = 4,
+	.offset = 0x28,
+};
+
+/* Programmable clock layout. */
+static const struct clk_programmable_layout programmable_layout = {
+	.pres_mask = 0xff,
+	.pres_shift = 8,
+	.css_mask = 0x1f,
+	.have_slck_mck = 0,
+	.is_pres_direct = 1,
+};
+
+/* Peripheral clock layout. */
+static const struct clk_pcr_layout sama7d65_pcr_layout = {
+	.offset = 0x88,
+	.cmd = BIT(31),
+	.gckcss_mask = GENMASK(12, 8),
+	.pid_mask = GENMASK(6, 0),
+};
+
+static void __init sama7d65_pmc_setup(struct device_node *np)
+{
+	const char *main_xtal_name = "main_xtal";
+	struct pmc_data *sama7d65_pmc;
+	const char *parent_names[11];
+	void **alloc_mem = NULL;
+	int alloc_mem_size = 0;
+	struct regmap *regmap;
+	struct clk_hw *hw, *main_rc_hw, *main_osc_hw, *main_xtal_hw;
+	struct clk_hw *td_slck_hw, *md_slck_hw;
+	static struct clk_parent_data parent_data;
+	struct clk_hw *parent_hws[10];
+	bool bypass;
+	int i, j;
+
+	td_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "td_slck"));
+	md_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "md_slck"));
+	main_xtal_hw = __clk_get_hw(of_clk_get_by_name(np, main_xtal_name));
+
+	if (!td_slck_hw || !md_slck_hw || !main_xtal_hw)
+		return;
+
+	regmap = device_node_to_regmap(np);
+	if (IS_ERR(regmap))
+		return;
+
+	sama7d65_pmc = pmc_data_allocate(PMC_INDEX_MAX,
+					 nck(sama7d65_systemck),
+					 nck(sama7d65_periphck),
+					 nck(sama7d65_gck), 8);
+	if (!sama7d65_pmc)
+		return;
+
+	alloc_mem = kmalloc(sizeof(void *) *
+			    (ARRAY_SIZE(sama7d65_mckx) + ARRAY_SIZE(sama7d65_gck)),
+			    GFP_KERNEL);
+	if (!alloc_mem)
+		goto err_free;
+
+	main_rc_hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+						   50000000);
+	if (IS_ERR(main_rc_hw))
+		goto err_free;
+
+	bypass = of_property_read_bool(np, "atmel,osc-bypass");
+
+	parent_data.name = main_xtal_name;
+	parent_data.fw_name = main_xtal_name;
+	main_osc_hw = at91_clk_register_main_osc(regmap, "main_osc", NULL,
+						 &parent_data, bypass);
+	if (IS_ERR(main_osc_hw))
+		goto err_free;
+
+	parent_hws[0] = main_rc_hw;
+	parent_hws[1] = main_osc_hw;
+	hw = at91_clk_register_sam9x5_main(regmap, "mainck", NULL, parent_hws, 2);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	sama7d65_pmc->chws[PMC_MAIN] = hw;
+
+	for (i = 0; i < PLL_ID_MAX; i++) {
+		for (j = 0; j < PLL_COMPID_MAX; j++) {
+			struct clk_hw *parent_hw;
+
+			if (!sama7d65_plls[i][j].n)
+				continue;
+
+			switch (sama7d65_plls[i][j].t) {
+			case PLL_TYPE_FRAC:
+				switch (sama7d65_plls[i][j].p) {
+				case SAMA7D65_PLL_PARENT_MAINCK:
+					parent_hw = sama7d65_pmc->chws[PMC_MAIN];
+					break;
+				case SAMA7D65_PLL_PARENT_MAIN_XTAL:
+					parent_hw = main_xtal_hw;
+					break;
+				default:
+					/* Should not happen. */
+					parent_hw = NULL;
+					break;
+				}
+
+				hw = sam9x60_clk_register_frac_pll(regmap,
+					&pmc_pll_lock, sama7d65_plls[i][j].n,
+					NULL, parent_hw, i,
+					sama7d65_plls[i][j].c,
+					sama7d65_plls[i][j].l,
+					sama7d65_plls[i][j].f);
+				break;
+
+			case PLL_TYPE_DIV:
+				hw = sam9x60_clk_register_div_pll(regmap,
+					&pmc_pll_lock, sama7d65_plls[i][j].n,
+					NULL, sama7d65_plls[i][0].hw, i,
+					sama7d65_plls[i][j].c,
+					sama7d65_plls[i][j].l,
+					sama7d65_plls[i][j].f,
+					sama7d65_plls[i][j].safe_div);
+				break;
+
+			default:
+				continue;
+			}
+
+			if (IS_ERR(hw))
+				goto err_free;
+
+			sama7d65_plls[i][j].hw = hw;
+			if (sama7d65_plls[i][j].eid)
+				sama7d65_pmc->chws[sama7d65_plls[i][j].eid] = hw;
+		}
+	}
+
+	hw = at91_clk_register_master_div(regmap, "mck0", NULL,
+					  sama7d65_plls[PLL_ID_CPU][1].hw,
+					  &mck0_layout, &mck0_characteristics,
+					  &pmc_mck0_lock, CLK_GET_RATE_NOCACHE, 5);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	sama7d65_pmc->chws[PMC_MCK] = hw;
+	sama7d65_mckx[PCK_PARENT_HW_MCK0].hw = hw;
+
+	parent_hws[0] = md_slck_hw;
+	parent_hws[1] = td_slck_hw;
+	parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN];
+	for (i = PCK_PARENT_HW_MCK1; i < ARRAY_SIZE(sama7d65_mckx); i++) {
+		u8 num_parents = 3 + sama7d65_mckx[i].ep_count;
+		struct clk_hw *tmp_parent_hws[8];
+		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, 3);
+		PMC_FILL_TABLE(&mux_table[3], sama7d65_mckx[i].ep_mux_table,
+			       sama7d65_mckx[i].ep_count);
+		for (j = 0; j < sama7d65_mckx[i].ep_count; j++) {
+			u8 pll_id = sama7d65_mckx[i].ep[j].pll_id;
+			u8 pll_compid = sama7d65_mckx[i].ep[j].pll_compid;
+
+			tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw;
+		}
+		PMC_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
+			       sama7d65_mckx[i].ep_count);
+
+		hw = at91_clk_sama7g5_register_master(regmap, sama7d65_mckx[i].n,
+						      num_parents, NULL, parent_hws,
+						      mux_table, &pmc_mckX_lock,
+						      sama7d65_mckx[i].id,
+						      sama7d65_mckx[i].c,
+						      sama7d65_mckx[i].ep_chg_id);
+		alloc_mem[alloc_mem_size++] = mux_table;
+
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sama7d65_mckx[i].hw = hw;
+		if (sama7d65_mckx[i].eid)
+			sama7d65_pmc->chws[sama7d65_mckx[i].eid] = hw;
+	}
+
+	parent_names[0] = "syspll_divpmcck";
+	parent_names[1] = "usbpll_divpmcck";
+	parent_names[2] = "main_osc";
+	hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	parent_hws[0] = md_slck_hw;
+	parent_hws[1] = td_slck_hw;
+	parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN];
+	parent_hws[3] = sama7d65_plls[PLL_ID_SYS][PLL_COMPID_DIV0].hw;
+	parent_hws[4] = sama7d65_plls[PLL_ID_DDR][PLL_COMPID_DIV0].hw;
+	parent_hws[5] = sama7d65_plls[PLL_ID_GPU][PLL_COMPID_DIV0].hw;
+	parent_hws[6] = sama7d65_plls[PLL_ID_BAUD][PLL_COMPID_DIV0].hw;
+	parent_hws[7] = sama7d65_plls[PLL_ID_AUDIO][PLL_COMPID_DIV0].hw;
+	parent_hws[8] = sama7d65_plls[PLL_ID_ETH][PLL_COMPID_DIV0].hw;
+
+	for (i = 0; i < 8; i++) {
+		char name[6];
+
+		snprintf(name, sizeof(name), "prog%d", i);
+
+		hw = at91_clk_register_programmable(regmap, name, NULL, parent_hws,
+						    9, i,
+						    &programmable_layout,
+						    sama7d65_prog_mux_table);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sama7d65_pmc->pchws[i] = hw;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sama7d65_systemck); i++) {
+		hw = at91_clk_register_system(regmap, sama7d65_systemck[i].n,
+					      sama7d65_systemck[i].p, NULL,
+					      sama7d65_systemck[i].id, 0);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sama7d65_pmc->shws[sama7d65_systemck[i].id] = hw;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sama7d65_periphck); i++) {
+		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &sama7d65_pcr_layout,
+							 sama7d65_periphck[i].n,
+							 NULL,
+							 sama7d65_mckx[sama7d65_periphck[i].p].hw,
+							 sama7d65_periphck[i].id,
+							 &sama7d65_periphck[i].r,
+							 sama7d65_periphck[i].chgp ? 0 :
+							 INT_MIN, 0);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sama7d65_pmc->phws[sama7d65_periphck[i].id] = hw;
+	}
+
+	parent_hws[0] = md_slck_hw;
+	parent_hws[1] = td_slck_hw;
+	parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN];
+	parent_hws[3] = sama7d65_pmc->chws[PMC_MCK1];
+	for (i = 0; i < ARRAY_SIZE(sama7d65_gck); i++) {
+		u8 num_parents = 4 + sama7d65_gck[i].pp_count;
+		struct clk_hw *tmp_parent_hws[8];
+		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], sama7d65_gck[i].pp_mux_table,
+			       sama7d65_gck[i].pp_count);
+		for (j = 0; j < sama7d65_gck[i].pp_count; j++) {
+			u8 pll_id = sama7d65_gck[i].pp[j].pll_id;
+			u8 pll_compid = sama7d65_gck[i].pp[j].pll_compid;
+
+			tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw;
+		}
+		PMC_FILL_TABLE(&parent_hws[4], tmp_parent_hws,
+			       sama7d65_gck[i].pp_count);
+
+		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
+						 &sama7d65_pcr_layout,
+						 sama7d65_gck[i].n, NULL,
+						 parent_hws, mux_table,
+						 num_parents,
+						 sama7d65_gck[i].id,
+						 &sama7d65_gck[i].r,
+						 sama7d65_gck[i].pp_chg_id);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sama7d65_pmc->ghws[sama7d65_gck[i].id] = hw;
+		alloc_mem[alloc_mem_size++] = mux_table;
+	}
+
+	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7d65_pmc);
+	kfree(alloc_mem);
+
+	return;
+
+err_free:
+	if (alloc_mem) {
+		for (i = 0; i < alloc_mem_size; i++)
+			kfree(alloc_mem[i]);
+		kfree(alloc_mem);
+	}
+
+	kfree(sama7d65_pmc);
+}
+
+/* Some clks are used for a clocksource */
+CLK_OF_DECLARE(sama7d65_pmc, "microchip,sama7d65-pmc", sama7d65_pmc_setup);
-- 
2.43.0



From pr-tracker-bot at kernel.org  Fri Dec  6 12:03:52 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 06 Dec 2024 20:03:52 +0000
Subject: [GIT PULL] pmdomain fixes for v6.13-rc2
In-Reply-To: <20241206084031.119041-1-ulf.hansson@linaro.org>
References: <20241206084031.119041-1-ulf.hansson@linaro.org>
Message-ID: <173351543257.2778953.46327491607829835.pr-tracker-bot@kernel.org>

The pull request you sent on Fri,  6 Dec 2024 09:40:31 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git tags/pmdomain-v6.13-rc1

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/fa4c221fa153211d80acaf54fe5e5b1859c99796

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From quic_abhinavk at quicinc.com  Fri Dec  6 12:17:29 2024
From: quic_abhinavk at quicinc.com (Abhinav Kumar)
Date: Fri, 6 Dec 2024 12:17:29 -0800
Subject: [PATCH v3 5/9] drm/msm/dpu: Add SM6150 support
In-Reply-To: <20241122-add-display-support-for-qcs615-platform-v3-5-35252e3a51fe@quicinc.com>
References: <20241122-add-display-support-for-qcs615-platform-v3-0-35252e3a51fe@quicinc.com>
 <20241122-add-display-support-for-qcs615-platform-v3-5-35252e3a51fe@quicinc.com>
Message-ID: <c1b2fe04-e43e-4ab7-b0f8-2bb2ce6e1313@quicinc.com>



On 11/22/2024 1:56 AM, Fange Zhang wrote:
> From: Li Liu <quic_lliu6 at quicinc.com>
> 
> Add definitions for the display hardware used on the Qualcomm SM6150
> platform.
> 
> Signed-off-by: Li Liu <quic_lliu6 at quicinc.com>
> Signed-off-by: Fange Zhang <quic_fangez at quicinc.com>
> ---
>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h | 263 +++++++++++++++++++++
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c     |   1 +
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h     |   1 +
>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c            |   1 +
>   4 files changed, 266 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..e8b7f694b885d69a9bbfaa85b0faf0c7af677a75
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h
> @@ -0,0 +1,263 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#ifndef _DPU_5_3_SM6150_H
> +#define _DPU_5_3_SM6150_H
> +
> +

<snip>

> +static const struct dpu_sspp_cfg sm6150_sspp[] = {
> +	{
> +		.name = "sspp_0", .id = SSPP_VIG0,
> +		.base = 0x4000, .len = 0x1f0,
> +		.features = VIG_SDM845_MASK,

This is not correct. Smartdma is supported on this chipset on both Vig 
and DMA SSPPs.

Please use VIG_SDM845_MASK_SDMA and DMA_SDM845_MASK_SDMA respectively.


> +		.sblk = &dpu_vig_sblk_qseed3_2_4,
> +		.xin_id = 0,
> +		.type = SSPP_TYPE_VIG,
> +		.clk_ctrl = DPU_CLK_CTRL_VIG0,
> +	}, {
> +		.name = "sspp_8", .id = SSPP_DMA0,
> +		.base = 0x24000, .len = 0x1f0,
> +		.features = DMA_SDM845_MASK,
> +		.sblk = &dpu_dma_sblk,
> +		.xin_id = 1,
> +		.type = SSPP_TYPE_DMA,
> +		.clk_ctrl = DPU_CLK_CTRL_DMA0,
> +	}, {
> +		.name = "sspp_9", .id = SSPP_DMA1,
> +		.base = 0x26000, .len = 0x1f0,
> +		.features = DMA_SDM845_MASK,
> +		.sblk = &dpu_dma_sblk,
> +		.xin_id = 5,
> +		.type = SSPP_TYPE_DMA,
> +		.clk_ctrl = DPU_CLK_CTRL_DMA1,
> +	}, {
> +		.name = "sspp_10", .id = SSPP_DMA2,
> +		.base = 0x28000, .len = 0x1f0,
> +		.features = DMA_CURSOR_SDM845_MASK_SDMA,
> +		.sblk = &dpu_dma_sblk,
> +		.xin_id = 9,
> +		.type = SSPP_TYPE_DMA,
> +		.clk_ctrl = DPU_CLK_CTRL_DMA2,
> +	}, {
> +		.name = "sspp_11", .id = SSPP_DMA3,
> +		.base = 0x2a000, .len = 0x1f0,
> +		.features = DMA_CURSOR_SDM845_MASK_SDMA,
> +		.sblk = &dpu_dma_sblk,
> +		.xin_id = 13,
> +		.type = SSPP_TYPE_DMA,
> +		.clk_ctrl = DPU_CLK_CTRL_DMA3,
> +	},
> +};
> +

<snip>


From Hermann.Lauer at uni-heidelberg.de  Fri Dec  6 12:20:05 2024
From: Hermann.Lauer at uni-heidelberg.de (Hermann.Lauer at uni-heidelberg.de)
Date: Fri, 6 Dec 2024 21:20:05 +0100
Subject: [PATCH] ARM: sun8i: r40/a40i: rm unneeded PH23 setup which resets
 Banana Pi M2 Ultra V1.1
Message-ID: <20241206202005.GA24845@lemon.iwr.uni-heidelberg.de>

Banana Pi M2 Ultra V1.1 board resets immediately when the usb core tries
to setup PH23 GPIO. It turned out that the V1.0 board USB-A ports are
always power supplied and according to the board scheme PH23 is simply
not connected.

So remove the PH23 setup: Doesn't harm V1.0 (with R40) and let V1.1
(with A40i) start

Signed-off-by: Hermann Lauer <Hermann.Lauer at uni-heidelberg.de>
---

# HG changeset patch
# Parent  236ffa4558b03bbc654515fae80a7a2387f06cd4

diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
--- a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
@@ -347,7 +347,5 @@
 };
 
 &usbphy {
-	usb1_vbus-supply = <&reg_vcc5v0>;
-	usb2_vbus-supply = <&reg_vcc5v0>;
 	status = "okay";
 };


From David.Laight at ACULAB.COM  Fri Dec  6 12:23:59 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 6 Dec 2024 20:23:59 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>
Message-ID: <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>

...
> > > #define const_NULL(x) _Generic(0 ? (x) : (char *)0, char *: 1, void *: 0)
> > > #define const_true(x) const_NULL((x) ? NULL : (void *)1L))
> > > #define const_expr(x) const_NULL((x) ? NULL : NULL))
> > > I send this morning.
> > > Needs 's/char/struct kjkjkjkjui/' applied.
> >
> > Oh Christ. You really are taking this whole ugly to another level.
> 
> I sort of liked that version in a perverse sort of way.
> It does give you a simple test for NULL (unless you've used 'struct kjkjkjkjui').

Except const_NULL() really doesn't work at all - so you are lucky :-)

So maybe the slightly long lines:
#define const_true(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 1L) : (char *)0, char *: 1, void *: 0)
#define const_expr(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 0L) : (char *)0, char *: 1, void *: 0)

I make that 98 characters.
Of course, you can remove all the spaces, only one of the constants need the L suffix
and 'int' is a shorter type name.
That cuts is down to 76:
#define const_expr(x) _Generic(0?(void*)((x)+0?0L:0):(int*)0,int*:1,void*:0)
which starts looking like the TECO commands to parse its command line!

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From dan.carpenter at linaro.org  Fri Dec  6 12:28:11 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Fri, 6 Dec 2024 23:28:11 +0300
Subject: [PATCH v2 2/2] firmware: arm_scmi: round rate bisecting in
 discrete rates
In-Reply-To: <20241203173908.3148794-3-etienne.carriere@foss.st.com>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-3-etienne.carriere@foss.st.com>
Message-ID: <7fe840af-d56d-4cb6-8d82-d42631409b2a@stanley.mountain>

On Tue, Dec 03, 2024 at 06:39:08PM +0100, Etienne Carriere wrote:
> diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
> index 09ccd6cea7f2..7bbb2ee55f4f 100644
> --- a/drivers/clk/clk-scmi.c
> +++ b/drivers/clk/clk-scmi.c
> @@ -61,13 +61,20 @@ static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
>  	struct scmi_clk *clk = to_scmi_clk(hw);
>  
>  	/*
> -	 * We can't figure out what rate it will be, so just return the
> +	 * In case we can't figure out what rate it will be when the clock
> +	 * describes a list of discrete rates, then just return the
>  	 * rate back to the caller. scmi_clk_recalc_rate() will be called
>  	 * after the rate is set and we'll know what rate the clock is
>  	 * running at then.
>  	 */
> -	if (clk->info->rate_discrete)
> +	if (clk->info->rate_discrete) {
> +		ftmp = rate;

No need for this assignment.

> +		if (scmi_proto_clk_ops->round_rate &&
> +		    !scmi_proto_clk_ops->round_rate(clk->ph, clk->id, &ftmp))
> +			return ftmp;
> +
>  		return rate;
> +	}
>  
>  	fmin = clk->info->range.min_rate;
>  	fmax = clk->info->range.max_rate;

regards,
dan carpenter


From mailhol.vincent at wanadoo.fr  Thu Dec  5 07:48:31 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 00:48:31 +0900
Subject: [PATCH 03/10] compiler.h: add is_const_true() and is_const_false()
In-Reply-To: <c617483816b54096ba4b30bea595da49@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-3-4e4cbaecc216@wanadoo.fr> <c617483816b54096ba4b30bea595da49@AcuMS.aculab.com>
Message-ID: <CAMZ6Rq+=-d0_v3Xqj0CpaPbNuzQuv1SouTkc3Ew5vc5Sb_DUng@mail.gmail.com>

On Thu. 5 Dec 2024 at 03:48, David Laight <David.Laight at aculab.com> wrote:
> From: Vincent Mailhol
> > Sent: 02 December 2024 17:33
> >
> > __builtin_constant_p() is known for not always being able to produce
> > constant expression [1] which led to the introduction of
> > __is_constexpr() [2]. Because of its dependency on
> > __builtin_constant_p(), statically_true() suffers from the same
> > issues.
>
> No, they are testing different things.

OK, I will remove this paragraph.

> > For example:
> >
> >   void foo(int a)
> >   {
> >        /* fail on GCC */
> >       BUILD_BUG_ON_ZERO(statically_true(a));
> >
> >        /* fail on both clang and GCC */
> >       static char arr[statically_true(a) ? 1 : 2];
> >   }
> >
> > Define a new is_const_true() and is_const_false() pair of macros
> > which, by making use of __is_const_zero(), always produces a constant
> > expression.
> >
> > Note that is_const_false() can not be directly defined as an alias to
> > __is_const_zero(). Otherwise, it could yield some false positives on
> > huge numbers because of a lost of precision when doing the (long) cast
> > in __is_const_zero(). Example:
> >
> >   is_const_false((u128)ULONG_MAX << BITS_PER_LONG)
> >
> > Furthermore, using the ! operator like this:
> >
> >   #define is_const_true(x) __is_const_zero(!(x))
> >   #define is_const_false(x) __is_const_zero(!!(x))
> >
> > would yield a -Wint-in-bool-context compiler warning if the argument
> > is not a boolean. Use the == and != operators instead.
> >
> > It should be noted that statically_true/false() are the only ones
> > capable of folding tautologic expressions in which at least one on the
> > operands is not a constant expression. For example:
> >
> >   statically_true(true || var)
> >   statically_true(var == var)
> >   statically_false(var * 0)
> >   statically_false(var * 8 % 4)
> >
> > always evaluate to true, whereas all of these would be false under
> > is_const_true/false() if var is not a constant expression [3].
> >
> > For this reason, usage of const_true/false() should be the exception.
> > Reflect in the documentation that const_true() is less powerful and
> > that statically_true() is the overall preferred solution.
> >
> > [1] __builtin_constant_p cannot resolve to const when optimizing
> > Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449
> >
> > [2] commit 3c8ba0d61d04 ("kernel.h: Retain constant expression output for max()/min()")
> > Link: https://git.kernel.org/torvalds/c/3c8ba0d61d04
> >
> > [3] https://godbolt.org/z/E4r7EaxW9

D'oh, I used some old versions of the macros in that link. The link
will be updated to this in v2:

  https://godbolt.org/z/E4r7EaxW9

> > Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> > ---
> >  include/linux/compiler.h | 23 +++++++++++++++++++++++
> >  1 file changed, 23 insertions(+)
> >
> > diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> > index 30ce06df4153cfdc0fad9bc7bffab9097f8b0450..165aa5b9bc484376087a130a1ac1f3edb50c983d 100644
> > --- a/include/linux/compiler.h
> > +++ b/include/linux/compiler.h
> > @@ -357,6 +357,29 @@ static inline void *offset_to_ptr(const int *off)
> >   */
> >  #define is_const(x) __is_const_zero(0 * (x))
> >
> > +/*
> > + * Similar to statically_true() but produces a constant expression
>
> No.
> It tests whether a value is a 'constant integer expression' and
> the result is a 'constant integer expression'.
> statically_true() checks for the value being a 'compile time constant'.

I still would argue that ?constant integer expressions? and ?compile
time constants? are *similar*. Not the same, agreed, but not
drastically different either. I picked the term *similar* for that
reason.

> Most code really doesn't care, it all got added to min() so that
> a very few places could do:
>         char foo[min(16, sizeof (type))];
> without triggering the 'variable length array' warning.
> But that just bloated everywhere else and (IIRC) Linus replaced
> them with a MIN() that was just an expression.

What about:

  Return an integer constant expression while evaluating if the
  argument is a true (non zero) integer constant expression.



> > + *
> > + * To be used in conjunction with macros, such as BUILD_BUG_ON_ZERO(),
> > + * which require their input to be a constant expression and for which
> > + * statically_true() would otherwise fail.
>
> Use a different BUILD_BUG macro instead.
> Look at the current definition of min().

Do you mean BUILD_BUG_ON_MSG()? That one, at the end, relies on the
error attribute:

  https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-error-function-attribute

And the error attribute logic relies on compiler optimization. So
BUILD_BUG_ON_MSG() is not a valid example here because it does not
require its argument to be an integer constant expression. It works
well with other compile time constants.

Another valid example would be _Static_assert() but as a matter of
fact, it is more common to use __is_constexpr() together with
BUILD_BUG_ON_ZERO() than it is with _Static_assert(). So I think that
BUILD_BUG_ON_ZERO() is best here.


Yours sincerely,
Vincent Mailhol


From vt at altlinux.org  Fri Dec  6 12:56:02 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Fri, 6 Dec 2024 23:56:02 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <87jzcfsuep.wl-maz@kernel.org>
References: <20241202045830.e4yy3nkvxtzaybxk@altlinux.org>
 <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
 <20241203092721.j473dthkbq6wzez7@altlinux.org>
 <1847e34fa7724d28aeb22d93752f64f2@huawei.com>
 <20241203221453.mwh6sozyczi4ec2k@altlinux.org>
 <87jzcfsuep.wl-maz@kernel.org>
Message-ID: <20241206205602.7phcrxqsv4c6oul4@altlinux.org>

Marc,

On Wed, Dec 04, 2024 at 08:51:26AM +0000, Marc Zyngier wrote:
> On Tue, 03 Dec 2024 22:14:53 +0000,
> Vitaly Chikunov <vt at altlinux.org> wrote:
> > 
> > Shameer, Marc, Oliver, Will,
> > 
> > On Tue, Dec 03, 2024 at 10:03:11AM +0000, Shameerali Kolothum Thodi wrote:
> > > > -----Original Message-----
> > > > From: linux-arm-kernel <linux-arm-kernel-bounces at lists.infradead.org> On
> > > > Behalf Of Vitaly Chikunov
> > > > Sent: Tuesday, December 3, 2024 9:27 AM
> > > > To: Marc Zyngier <maz at kernel.org>
> > > > Cc: Will Deacon <will at kernel.org>; james.morse at arm.com; linux-arm-
> > > > kernel at lists.infradead.org; Catalin Marinas <catalin.marinas at arm.com>;
> > > > linux-kernel at vger.kernel.org; oliver.upton at linux.dev;
> > > > mark.rutland at arm.com
> > > > Subject: Re: v6.13-rc1: Internal error: Oops - Undefined instruction:
> > > > 0000000002000000 [#1] SMP
> > > > 
> > > > Marc,
> > > > 
> > > > On Tue, Dec 03, 2024 at 01:31:19AM +0300, Vitaly Chikunov wrote:
> > > > > On Mon, Dec 02, 2024 at 04:07:03PM +0000, Marc Zyngier wrote:
> > > > > > On Mon, 02 Dec 2024 15:59:40 +0000,
> > > > > > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > > > > >
> > > > > > > Marc,
> > > > > > >
> > > > > > > On Mon, Dec 02, 2024 at 03:53:59PM +0000, Marc Zyngier wrote:
> > > > > > > >
> > > > > > > > What the log doesn't say is what the host is. Is it 6.13-rc1 as well?
> > > > > > >
> > > > > > > No, host is 6.6.60.
> > > > > >
> > > > > > Right. I wouldn't be surprised if:
> > > > > >
> > > > > > - this v6.6 kernel doesn't hide the MPAM feature as it should (and
> > > > > >   that's proably something we should backport)
> > > > >
> > > > > How to confirm this? Currently I cannot find any (case-insensitive)
> > > > > "MPAM" files in /sys, nor mpam string in /proc/cpuinfo, nor MPAM
> > > > > strings in `strace -v` (as it decodes some KVM ioctls) of qemu process.
> > > > >
> > > > > >
> > > > > > - you get a nastygram in the host log telling you that the guest has
> > > > > >   executed something it shouldn't (you'll get the encoding of the
> > > > > >   instruction)
> > > > >
> > > > > I requested admins of the box for dmesg output since I don't have root
> > > > > access myself and nowadays dmesg is not accessible for a user.
> > > > 
> > > > This is what they reported:
> > > > 
> > > >   kvm [2502822]: Unsupported guest sys_reg access at: ffff80008003e9f0
> > > > [000000c5]
> > > >                    { Op0( 3), Op1( 0), CRn(10), CRm( 4), Op2( 4), func_read },
> > > > 
> > > 
> > > As Will pointed out I think this is access to MPAMIDR_EL1 and is from this
> > > code here,
> > > 
> > > +++ b/arch/arm64/kernel/cpuinfo.c
> > > @@ -478,6 +478,9 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
> > >  	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
> > >  		__cpuinfo_store_cpu_32bit(&info->aarch32);
> > >  
> > > +	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
> > > +		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
> > > +
> > >  	cpuinfo_detect_icache_policy(info);
> > >  }
> > > 
> > > I did manage to boot my setup in 6.6 and this is what happens,
> > > 
> > > Host kernel 6.6
> > > Guest Kernel 6.13-rc1
> > > 
> > > [    0.195392] smp: Brought up 1 node, 8 CPUs
> > > [    0.219000] SMP: Total of 8 processors activated.
> > > [    0.219629] CPU: All CPU(s) started at EL1
> > > ...
> > > [    0.223212] CPU features: detected: RAS Extension Support
> > > [    0.223927] CPU features: detected: Memory Partitioning And Monitoring
> > > [    0.224796] CPU features: detected: Memory Partitioning And Monitoring Virtualisation
> > > [    0.225961] alternatives: applying system-wide alternatives
> > > ...
> > > 
> > > Guest detects MPAM and boots fine.
> > > 
> > > Host kernel 6.13-rc1
> > > Guest Kernel 6.13-rc1
> > > 
> > > [    0.196625] smp: Brought up 1 node, 8 CPUs
> > > [    0.222093] SMP: Total of 8 processors activated.
> > > [    0.222769] CPU: All CPU(s) started at EL1
> > > ...
> > > [    0.226620] CPU features: detected: RAS Extension Support
> > > [    0.227453] alternatives: applying system-wide alternatives
> > > 
> > > MPAM is not visible to Guest in this case.
> > > 
> > > So as I pointed out earlier could it be a case where the ID register reports MPAM support
> > > but the firmware has not enabled MPAM?
> > > 
> > > James seems to be mentioning that case here,
> > > 
> > > " (If you have a boot failure that bisects here its likely your CPUs
> > > advertise MPAM in the id registers, but firmware failed to either enable
> > > or MPAM, or emulate the trap as if it were disabled)"
> > 
> > I tried to verify that MPAM is advertised with qemu+gdb method, as
> > suggested by Oliver, but ID_AA64PFR0_EL1 register is not there.
> > 
> >   (gdb) i r ID_AA64PFR0_EL1
> >   Invalid register `ID_AA64PFR0_EL1'
> 
> Then there is a bug in either QEMU or the GDB stubs. This register
> exists, or you wouldn't be here.
> 
> > 
> > Are there other suggestions?
> 
> Mark has described what the problem is likely to be. 6.6-stable needs
> to have 6685f5d572c22e10 backported, and it probably should have been
> Cc: to stable. Can you please apply the following patch to your *host*
> machine and retest?

We tested the host with this patch applied over 6.6.63 and 6.13-rc1
guest does not Oops anymore.

I'd suggest this is also get backported to 6.12.y branch.

Thanks,

> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 370a1a7bd369..258a39bcd3c7 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1330,6 +1330,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
>  			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
>  
>  		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
> +		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MPAM_frac);
>  		break;
>  	case SYS_ID_AA64ISAR1_EL1:
>  		if (!vcpu_has_ptrauth(vcpu))
> @@ -1472,6 +1473,13 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
>  
>  	val &= ~ID_AA64PFR0_EL1_AMU_MASK;
>  
> +	/*
> +	 * MPAM is disabled by default as KVM also needs a set of PARTID to
> +	 * program the MPAMVPMx_EL2 PARTID remapping registers with. But some
> +	 * older kernels let the guest see the ID bit.
> +	 */
> +	val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
> +
>  	return val;
>  }
>  
> @@ -1560,6 +1568,29 @@ static int set_id_dfr0_el1(struct kvm_vcpu *vcpu,
>  	return set_id_reg(vcpu, rd, val);
>  }
>  
> +static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> +			       const struct sys_reg_desc *rd, u64 user_val)
> +{
> +	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> +	u64 mpam_mask = ID_AA64PFR0_EL1_MPAM_MASK;
> +
> +	/*
> +	 * Commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits
> +	 * in ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to
> +	 * guests, but didn't add trap handling. KVM doesn't support MPAM and
> +	 * always returns an UNDEF for these registers. The guest must see 0
> +	 * for this field.
> +	 *
> +	 * But KVM must also accept values from user-space that were provided
> +	 * by KVM. On CPUs that support MPAM, permit user-space to write
> +	 * the sanitizied value to ID_AA64PFR0_EL1.MPAM, but ignore this field.
> +	 */
> +	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
> +		user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
> +
> +	return set_id_reg(vcpu, rd, user_val);
> +}
> +
>  /*
>   * cpufeature ID register user accessors
>   *
> @@ -2018,7 +2049,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_ID_AA64PFR0_EL1),
>  	  .access = access_id_reg,
>  	  .get_user = get_id_reg,
> -	  .set_user = set_id_reg,
> +	  .set_user = set_id_aa64pfr0_el1,
>  	  .reset = read_sanitised_id_aa64pfr0_el1,
>  	  .val = ID_AA64PFR0_EL1_CSV2_MASK | ID_AA64PFR0_EL1_CSV3_MASK, },
>  	ID_SANITISED(ID_AA64PFR1_EL1),
> 
> > > https://lore.kernel.org/all/20241030160317.2528209-4-joey.gouly at arm.com/
> > > 
> > > Is there a way you can find out the BIOS version on that board?
> > 
> > Unfortunately, admins of the server do not provide me with this
> > info.
> 
> This doesn't really help, I'm afraid.
> 
> > For such cases, when MPAM is incorrectly advertised, can we have kernel
> > command line parameter like mpam=0 to override it's detection?
> 
> We could, but only when we can confirm what the problem is.
> 
> > I think with "If you have a boot failure that bisects here" it's
> > acknowledged possibility and it's confirmed by our server.
> 
> Not really. This talks about firmware. We are debugging the hypervisor
> here. This might be closely related, but these are not the same
> things.
> 
> Thanks,
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.


From eahariha at linux.microsoft.com  Fri Dec  6 12:58:17 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Fri, 6 Dec 2024 12:58:17 -0800
Subject: [PATCH v2 00/21] Converge on using secs_to_jiffies()
In-Reply-To: <b9fcb12a-b7a4-4c33-836e-67109ce07deb@intel.com>
References: <20241115-converge-secs-to-jiffies-v2-0-911fb7595e79@linux.microsoft.com>
 <b9fcb12a-b7a4-4c33-836e-67109ce07deb@intel.com>
Message-ID: <dab77729-682f-4182-9fb2-cd522ac29b5f@linux.microsoft.com>

On 11/29/2024 4:57 AM, Przemek Kitszel wrote:
> 
> [removed most non-list recipients, it's just too much]
> 
> On 11/15/24 10:26 PM, Easwar Hariharan wrote:
<snip>
>>
>> ---
>> Changes in v2:
>> - EDITME: describe what is new in this series revision.
>> - EDITME: use bulletpoints and terse descriptions.
>> - Link to v1: https://lore.kernel.org/r/20241115-converge-secs-to-
>> jiffies-v1-0-19aadc34941b at linux.microsoft.com
> 
> that is not a proper changelog, you were supposed to edit those
> placeholder entries; please look around for examples
> 
> There is also just too much recipients. Please split up your patches
> into smaller pieces. You will also learn the process on a smaller
> sample.
> 
> And definitively please wait for 48h before reposting such big series.

Yes, sorry, I sent out a v2 in a moment of panic on including the
already accepted patch in v1. I failed to edit the changelog in that
same panic. I'll try to not panic and do better in the future.

> 
> Regarding code - you could also convert msecs_to_jiffies(const * HZ),
> there are 10 that are greppable.
> 

Those seem to be mistakes. const*HZ is a seconds-denominated timeout,
being passed to msecs_to_jiffies() which will treat it as a
millisecond-denominated timeout resulting in an excessively long
timeout. I suppose that's better than a too-short timeout, and
apparently it's been working fine all along since hardware responds
before the too-long timeout expires. Half of them are in
drivers/scsi/arcmsr/arcmsr_hba.c and the pattern has apparently been
there since 2010.

Thanks,
Easwar


From ja at ssi.bg  Fri Dec  6 12:58:13 2024
From: ja at ssi.bg (Julian Anastasov)
Date: Fri, 6 Dec 2024 22:58:13 +0200 (EET)
Subject: [PATCH net] Fix clamp() of ip_vs_conn_tab on small memory
 systems.
In-Reply-To: <494a4dc2ba2041dfb9f45d86e972b953@AcuMS.aculab.com>
References: <33893212b1cc4a418cec09aeeed0a9fc@AcuMS.aculab.com> <5ec10e7c-d050-dab8-1f1b-d0ca2d922eef@ssi.bg> <2a91ee407ed64d24b82e5fc665971add@AcuMS.aculab.com> <c0a2ee53-f6ff-f4d4-e9ab-6a3bf850bec5@ssi.bg>
 <494a4dc2ba2041dfb9f45d86e972b953@AcuMS.aculab.com>
Message-ID: <184af1fd-2bc4-11c1-9319-0ca879e53d99@ssi.bg>


	Hello,

On Fri, 6 Dec 2024, David Laight wrote:

> From: Julian Anastasov
> > Sent: 06 December 2024 16:23
> ...
> > 	I'm not sure how much memory we can see in small system,
> > IMHO, problem should not be possible in practice:
> > 
> > - nobody expects 0 from totalram_pages() in the code
> > 
> > - order_base_2(sizeof(struct ip_vs_conn)) is probably 8 on 32-bit
> 
> It is 0x120 bytes on 64bit, so 8 could well be right.

	That is already for 9 :)

> > > Is all stems from order_base_2(totalram_pages()).
> > > order_base_2(n) is 'n > 1 ? ilog2(n - 1) + 1 : 0'.
> > > And the compiler generates two copies of the code that follows
> > > for the 'constant zero' and ilog2() values.
> > > And the 'zero' case compiles clamp(20, 8, 0) which is errored.
> > > Note that it is only executed if totalram_pages() is zero,
> > > but it is always compiled 'just in case'.
> > 
> > 	I'm confused with these compiler issues,
> 
> The compiler is just doing its job.
> Consider this expression:
> 	(x >= 1 ? 2 * x : 1) - 1
> It is likely to get converted to:
> 	(x >= 1 ? 2 * x - 1 : 0)
> to avoid the subtract when x < 1.
> 
> The same thing is happening here.
> order_base_2() has a (condition ? fn() : 0) in it.
> All the +/- constants get moved inside, on 64bit that is +12 -2 -1 -9 = 0.
> Then the clamp() with constants gets moved inside:
> 	(condition ? clamp(27, 8, fn() + 0) : clamp(27, 8, 0 + 0))
> Now, at runtime, we know that 'condition' is true and (fn() >= 8)
> so the first clamp() is valid and the second one never used.
> But this isn't known by the compiler and clamp() detects the invalid
> call and generates a warning.

	I see, such optimizations are beyond my expectations,
I used max_avail var to separate the operations between
different macro calls but in the end they are mixed together...

> > if you
> > think we should go with the patch just decide if it is a
> > net or net-next material. Your change is safer for bad
> > max_avail values but I don't expect to see problem while
> > running without the change, except the building bugs.
> > 
> > 	Also, please use nf/nf-next tag to avoid any
> > confusion with upstreaming...
> 
> I've copied Andrew M - he's taken the minmax.h change into his mm tree.
> This is one of the build breakages.
> 
> It probably only needs to go into next for now (via some route).
> But I can image the minmax.h changes getting backported a bit.

	OK, then can you send v2 with Fixes header, precised comments
and nf tag, it fixes a recent commit, so it can be backported easily...

Regards

--
Julian Anastasov <ja at ssi.bg>



From zmw12306 at gmail.com  Fri Dec  6 13:08:00 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Fri,  6 Dec 2024 16:08:00 -0500
Subject: [PATCH v2] pinctrl: stm32: Add check for clk_enable()
Message-ID: <20241206210800.3346579-1-zmw12306@gmail.com>

Convert the driver to clk_bulk*() API.
Add check for the return value of clk_bulk_enable() to catch
the potential error.

Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
Changelog:

v1 -> v2:

1. Convert the driver to clk_bulk*() API.
---
 drivers/pinctrl/stm32/pinctrl-stm32.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index 5b7fa77c1184..188de29ac281 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -86,7 +86,6 @@ struct stm32_pinctrl_group {
 
 struct stm32_gpio_bank {
 	void __iomem *base;
-	struct clk *clk;
 	struct reset_control *rstc;
 	spinlock_t lock;
 	struct gpio_chip gpio_chip;
@@ -108,6 +107,7 @@ struct stm32_pinctrl {
 	unsigned ngroups;
 	const char **grp_names;
 	struct stm32_gpio_bank *banks;
+	struct clk_bulk_data *clks;
 	unsigned nbanks;
 	const struct stm32_pinctrl_match_data *match_data;
 	struct irq_domain	*domain;
@@ -1308,7 +1308,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	if (IS_ERR(bank->base))
 		return PTR_ERR(bank->base);
 
-	err = clk_prepare_enable(bank->clk);
+	err = clk_prepare_enable(pctl->clks[pctl->nbanks].clk);
 	if (err) {
 		dev_err(dev, "failed to prepare_enable clk (%d)\n", err);
 		return err;
@@ -1397,7 +1397,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	return 0;
 
 err_clk:
-	clk_disable_unprepare(bank->clk);
+	clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);
 	return err;
 }
 
@@ -1631,11 +1631,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
 			fwnode_handle_put(child);
 			return -EPROBE_DEFER;
 		}
-
-		bank->clk = of_clk_get_by_name(np, NULL);
-		if (IS_ERR(bank->clk)) {
+		pctl->clks[i].clk = of_clk_get_by_name(np, NULL);
+		if (IS_ERR(pctl->clks[i].clk)) {
 			fwnode_handle_put(child);
-			return dev_err_probe(dev, PTR_ERR(bank->clk),
+			return dev_err_probe(dev, PTR_ERR(pctl->clks[i].clk),
 					     "failed to get clk\n");
 		}
 		i++;
@@ -1647,7 +1646,7 @@ int stm32_pctl_probe(struct platform_device *pdev)
 			fwnode_handle_put(child);
 
 			for (i = 0; i < pctl->nbanks; i++)
-				clk_disable_unprepare(pctl->banks[i].clk);
+				clk_disable_unprepare(pctl->clks[i].clk);
 
 			return ret;
 		}
@@ -1726,10 +1725,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
 int __maybe_unused stm32_pinctrl_suspend(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
-	int i;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_disable(pctl->banks[i].clk);
+	clk_bulk_disable(pctl->nbanks, pctl->clks);
 
 	return 0;
 }
@@ -1738,10 +1735,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
 	struct stm32_pinctrl_group *g = pctl->groups;
-	int i;
+	int i, ret;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_enable(pctl->banks[i].clk);
+	ret = clk_bulk_enable(pctl->nbanks, pctl->clks);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < pctl->ngroups; i++, g++)
 		stm32_pinctrl_restore_gpio_regs(pctl, g->pin);
-- 
2.34.1



From mailhol.vincent at wanadoo.fr  Thu Dec  5 07:21:35 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 00:21:35 +0900
Subject: [PATCH 00/10] compiler.h: refactor __is_constexpr() into is_const{,_true,_false}()
In-Reply-To: <FBEB24FF-5885-4938-8D1C-9B7BA9071FB9@kernel.org>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr> <FBEB24FF-5885-4938-8D1C-9B7BA9071FB9@kernel.org>
Message-ID: <CAMZ6RqLSiTfTNQrcje06MbSxvM2k16MgqG1YTCufe6j9FhupEw@mail.gmail.com>

On Thu. 5 Dec. 2024 at 08:58, Kees Cook <kees at kernel.org> wrote:
> On December 3, 2024 3:33:22 AM GMT+10:00, Vincent Mailhol via B4 Relay <devnull+mailhol.vincent.wanadoo.fr at kernel.org> wrote:
> >This series is the spiritual successor of [1] which introduced
> >const_true(). In [1], following a comment from David Laight, Linus
> >came with a suggestion to simplify __is_constexpr() and its derived
> >macros using a _Generic() selection. Because of the total change of
> >scope, I am starting a new series.
> >
> >The goal is to introduce a set of three macros:
> >
> >  - is_const(): a one to one replacement of __is_constexpr() in term
> >    of features but written in a less hacky way thanks to _Generic().
> >
> >  - is_const_true(): tells whether or not the argument is a true
> >    integer constant expression.
> >
> >  - is_const_false(): tells whether or not the argument is a false
> >    integer constant expression.
>
> But why make this change? Is something broken? Does it make builds faster?
>
> > 7 files changed, 97 insertions(+), 84 deletions(-)
>
> It makes the code larger too. I don't see what the benefit is, and given how much time has been spent making sure the existing stuff works correctly, I feel like we should have a clear benefit to replacing it all.

It makes the "code" larger because patch 3 ("compiler.h: add
is_const_true() and is_const_false()") adds two new macros with 20
lines of comments to explain the pros and cons. So the added "code" is
only comments. If you ignore the comments, you can see that I am
actually removing a few lines of code.

As for the clear benefit, sorry, but I have nothing more to offer
other than code simplification. The reason why a lot of time was spent
to make __is_constexpr() work correctly is just a testimony of how
complex the thing is. That alone can be a reason to simplify it, now
that new tools (_Generic()) are available.

Of course, modifying __is_constexpr() is not strictly needed to
introduce the new is_const_expr(). My previous series:

  https://lore.kernel.org/all/20241113172939.747686-4-mailhol.vincent at wanadoo.fr/

 did it that way. But I was rightfully pointed out for my macro being
ugly. Maybe I can suggest that you give a look to the above thread and
tell me if you still disagree with David and Linus's comments after
reading it?


Yours sincerely,
Vincent Mailhol


From zmw12306 at gmail.com  Fri Dec  6 13:43:15 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Fri,  6 Dec 2024 16:43:15 -0500
Subject: [PATCH v3] pinctrl: stm32: Add check for clk_enable()
Message-ID: <20241206214315.3385033-1-zmw12306@gmail.com>

Convert the driver to clk_bulk*() API.
Add check for the return value of clk_bulk_enable() to catch
the potential error.

Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
Changelog:

v2 -> v3:

1. Convert clk_disable_unprepare to clk_bulk_disable
and clk_bulk_unprepare.

v1 -> v2:

1. Move int ret declaration into if block.
---
 drivers/pinctrl/stm32/pinctrl-stm32.c | 28 +++++++++++++--------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index 5b7fa77c1184..0ef912e82736 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -86,7 +86,6 @@ struct stm32_pinctrl_group {
 
 struct stm32_gpio_bank {
 	void __iomem *base;
-	struct clk *clk;
 	struct reset_control *rstc;
 	spinlock_t lock;
 	struct gpio_chip gpio_chip;
@@ -108,6 +107,7 @@ struct stm32_pinctrl {
 	unsigned ngroups;
 	const char **grp_names;
 	struct stm32_gpio_bank *banks;
+	struct clk_bulk_data *clks;
 	unsigned nbanks;
 	const struct stm32_pinctrl_match_data *match_data;
 	struct irq_domain	*domain;
@@ -1308,7 +1308,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	if (IS_ERR(bank->base))
 		return PTR_ERR(bank->base);
 
-	err = clk_prepare_enable(bank->clk);
+	err = clk_prepare_enable(pctl->clks[pctl->nbanks].clk);
 	if (err) {
 		dev_err(dev, "failed to prepare_enable clk (%d)\n", err);
 		return err;
@@ -1397,7 +1397,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	return 0;
 
 err_clk:
-	clk_disable_unprepare(bank->clk);
+	clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);
 	return err;
 }
 
@@ -1631,11 +1631,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
 			fwnode_handle_put(child);
 			return -EPROBE_DEFER;
 		}
-
-		bank->clk = of_clk_get_by_name(np, NULL);
-		if (IS_ERR(bank->clk)) {
+		pctl->clks[i].clk = of_clk_get_by_name(np, NULL);
+		if (IS_ERR(pctl->clks[i].clk)) {
 			fwnode_handle_put(child);
-			return dev_err_probe(dev, PTR_ERR(bank->clk),
+			return dev_err_probe(dev, PTR_ERR(pctl->clks[i].clk),
 					     "failed to get clk\n");
 		}
 		i++;
@@ -1646,8 +1645,8 @@ int stm32_pctl_probe(struct platform_device *pdev)
 		if (ret) {
 			fwnode_handle_put(child);
 
-			for (i = 0; i < pctl->nbanks; i++)
-				clk_disable_unprepare(pctl->banks[i].clk);
+			clk_bulk_disable(pctl->nbanks, pctl->clks);
+			clk_bulk_unprepare(pctl->nbanks, pctl->clks);
 
 			return ret;
 		}
@@ -1726,10 +1725,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
 int __maybe_unused stm32_pinctrl_suspend(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
-	int i;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_disable(pctl->banks[i].clk);
+	clk_bulk_disable(pctl->nbanks, pctl->clks);
 
 	return 0;
 }
@@ -1738,10 +1735,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
 	struct stm32_pinctrl_group *g = pctl->groups;
-	int i;
+	int i, ret;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_enable(pctl->banks[i].clk);
+	ret = clk_bulk_enable(pctl->nbanks, pctl->clks);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < pctl->ngroups; i++, g++)
 		stm32_pinctrl_restore_gpio_regs(pctl, g->pin);
-- 
2.34.1



From zmw12306 at gmail.com  Fri Dec  6 13:53:18 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Fri,  6 Dec 2024 16:53:18 -0500
Subject: [PATCH v3] pwm: stm32-lp: Add check for clk_enable()
Message-ID: <20241206215318.3402860-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error.
We used APP-Miner to find it.

Fixes: e70a540b4e02 ("pwm: Add STM32 LPTimer PWM driver")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
Changelog:

v2 -> v3:

1. Add tool name in the commit log.

v1 -> v2:

1. Move int ret declaration into if block.
---
 drivers/pwm/pwm-stm32-lp.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
index 989731256f50..f09d097d6284 100644
--- a/drivers/pwm/pwm-stm32-lp.c
+++ b/drivers/pwm/pwm-stm32-lp.c
@@ -167,8 +167,12 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
 	regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
 	state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
 	/* Keep PWM counter clock refcount in sync with PWM initial state */
-	if (state->enabled)
-		clk_enable(priv->clk);
+	if (state->enabled) {
+		int ret = clk_enable(priv->clk);
+
+		if (ret)
+			return ret;
+	}
 
 	regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
 	presc = FIELD_GET(STM32_LPTIM_PRESC, val);
-- 
2.34.1



From pr-tracker-bot at kernel.org  Fri Dec  6 14:01:11 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 06 Dec 2024 22:01:11 +0000
Subject: [GIT PULL] arm64 fixes for 6.13-rc2
In-Reply-To: <Z1NCFeR4iBm5Bxqg@arm.com>
References: <Z1NCFeR4iBm5Bxqg@arm.com>
Message-ID: <173352247159.2810195.14014493447586884302.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 6 Dec 2024 18:27:33 +0000:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/f3ddc438a29f78f0642bfcf84407c236a0b2bdc7

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From cristian.ciocaltea at collabora.com  Fri Dec  6 14:03:41 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 00:03:41 +0200
Subject: [PATCH 1/4] phy: Add HDMI configuration options
In-Reply-To: <20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797@collabora.com>
References: <20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797@collabora.com>
Message-ID: <20241207-phy-sam-hdptx-bpc-v1-1-03c2e4d6d797@collabora.com>

From: Sandor Yu <Sandor.yu at 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>
Reviewed-by: Maxime Ripard <mripard at kernel.org>
Link: https://lore.kernel.org/r/43757beec6cd418fc17252283de38009d531c7c7.1732627815.git.Sandor.yu at nxp.com
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 include/linux/phy/phy-hdmi.h | 19 +++++++++++++++++++
 include/linux/phy/phy.h      |  7 ++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a696922bc7f29af63d88646701b2c0fcee5c885
--- /dev/null
+++ b/include/linux/phy/phy-hdmi.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022,2024 NXP
+ */
+
+#ifndef __PHY_HDMI_H_
+#define __PHY_HDMI_H_
+
+/**
+ * struct phy_configure_opts_hdmi - HDMI configuration set
+ * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
+ *
+ * This structure is used to represent the configuration state of a HDMI phy.
+ */
+struct phy_configure_opts_hdmi {
+	unsigned long long tmds_char_rate;
+};
+
+#endif /* __PHY_HDMI_H_ */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 03cd5bae92d3f189d739c453fe4c160dd2a5063e..4ac486b101fe4023b8f2a84e907e65a0ff0a5ede 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.47.0



From cristian.ciocaltea at collabora.com  Fri Dec  6 14:03:40 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 00:03:40 +0200
Subject: [PATCH 0/4] phy: rockchip: samsung-hdptx: Support high color depth
 management
Message-ID: <20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797@collabora.com>

This series relies on the new HDMI PHY configuration options [1] (patch
included here for convenience) to provide high color depth management
for rockchip-samsung-hdptx, and to introduce a proper solution to setup
the TMDS character rate on this PHY.

[1] https://lore.kernel.org/all/43757beec6cd418fc17252283de38009d531c7c7.1732627815.git.Sandor.yu at nxp.com/

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
Cristian Ciocaltea (3):
      phy: hdmi: Add color depth configuration
      phy: rockchip: samsung-hdptx: Setup TMDS char rate via phy_configure_opts_hdmi
      phy: rockchip: samsung-hdptx: Add high color depth management

Sandor Yu (1):
      phy: Add HDMI configuration options

 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 59 +++++++++++++++++++----
 include/linux/phy/phy-hdmi.h                      | 21 ++++++++
 include/linux/phy/phy.h                           |  7 ++-
 3 files changed, 77 insertions(+), 10 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241206-phy-sam-hdptx-bpc-3b05c6276fd7



From cristian.ciocaltea at collabora.com  Fri Dec  6 14:03:42 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 00:03:42 +0200
Subject: [PATCH 2/4] phy: hdmi: Add color depth configuration
In-Reply-To: <20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797@collabora.com>
References: <20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797@collabora.com>
Message-ID: <20241207-phy-sam-hdptx-bpc-v1-2-03c2e4d6d797@collabora.com>

Extend the HDMI configuration options to allow managing bits per color
channel.  This is required by some PHY drivers such as
rockchip-samsung-hdptx.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 include/linux/phy/phy-hdmi.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
index 6a696922bc7f29af63d88646701b2c0fcee5c885..f0ec963c6e84f1b7728acafc824dff191c6b873d 100644
--- a/include/linux/phy/phy-hdmi.h
+++ b/include/linux/phy/phy-hdmi.h
@@ -9,11 +9,13 @@
 /**
  * struct phy_configure_opts_hdmi - HDMI configuration set
  * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
+ * @bpc: Bits per color channel.
  *
  * This structure is used to represent the configuration state of a HDMI phy.
  */
 struct phy_configure_opts_hdmi {
 	unsigned long long tmds_char_rate;
+	unsigned int bpc;
 };
 
 #endif /* __PHY_HDMI_H_ */

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Fri Dec  6 14:03:43 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 00:03:43 +0200
Subject: [PATCH 3/4] phy: rockchip: samsung-hdptx: Setup TMDS char rate via
 phy_configure_opts_hdmi
In-Reply-To: <20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797@collabora.com>
References: <20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797@collabora.com>
Message-ID: <20241207-phy-sam-hdptx-bpc-v1-3-03c2e4d6d797@collabora.com>

The current workaround to setup the TMDS character rate relies on the
unconventional usage of phy_set_bus_width().

Make use of the recently introduced HDMI PHY configuration API for this
purpose.  The workaround will be dropped as soon as the switch has been
completed on both ends.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 42 ++++++++++++++++++-----
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index ceab9c71d3b53ae0b746a10c081fcfaa7d5c5ae7..eeadebdc476caa87aebbbd82f7102b62b22a0ea6 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -273,6 +273,7 @@ struct rk_hdptx_phy {
 	struct clk_bulk_data *clks;
 	int nr_clks;
 	struct reset_control_bulk_data rsts[RST_MAX];
+	unsigned long tmds_char_rate;
 
 	/* clk provider */
 	struct clk_hw hw;
@@ -902,18 +903,20 @@ static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)
 static int rk_hdptx_phy_power_on(struct phy *phy)
 {
 	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
-	int bus_width = phy_get_bus_width(hdptx->phy);
+	unsigned int rate = hdptx->tmds_char_rate / 100;
 	int ret;
 
-	/*
-	 * 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;
+	if (rate == 0) {
+		/*
+		 * FIXME: Temporary workaround to setup TMDS char rate
+		 * from the RK HDMI bridge driver.
+		 * Will be removed as soon the switch to the HDMI PHY
+		 * configuration API has been completed on both ends.
+		 */
+		rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
+	}
 
-	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
-		__func__, bus_width, rate);
+	dev_dbg(hdptx->dev, "%s rate=%u\n", __func__, rate);
 
 	ret = rk_hdptx_phy_consumer_get(hdptx, rate);
 	if (ret)
@@ -933,9 +936,20 @@ static int rk_hdptx_phy_power_off(struct phy *phy)
 	return rk_hdptx_phy_consumer_put(hdptx, false);
 }
 
+static int rk_hdptx_phy_configure(struct phy *phy,
+				  union phy_configure_opts *opts)
+{
+	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
+
+	hdptx->tmds_char_rate = opts->hdmi.tmds_char_rate;
+
+	return 0;
+}
+
 static const struct phy_ops rk_hdptx_phy_ops = {
 	.power_on  = rk_hdptx_phy_power_on,
 	.power_off = rk_hdptx_phy_power_off,
+	.configure = rk_hdptx_phy_configure,
 	.owner	   = THIS_MODULE,
 };
 
@@ -991,6 +1005,16 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
 
+	/*
+	 * The TMDS char rate set via phy_configure(), if any, has
+	 * precedence over the rate provided via clk_set_rate().
+	 */
+	if (hdptx->tmds_char_rate && hdptx->tmds_char_rate != rate) {
+		dev_dbg(hdptx->dev, "Replaced clk_set_rate=%lu with tmds_char_rate=%lu\n",
+			rate, hdptx->tmds_char_rate);
+		rate = hdptx->tmds_char_rate;
+	}
+
 	return rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100);
 }
 

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Fri Dec  6 14:03:44 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 00:03:44 +0200
Subject: [PATCH 4/4] phy: rockchip: samsung-hdptx: Add high color depth
 management
In-Reply-To: <20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797@collabora.com>
References: <20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797@collabora.com>
Message-ID: <20241207-phy-sam-hdptx-bpc-v1-4-03c2e4d6d797@collabora.com>

Add support for 8-bit, 10-bit, 12-bit and 16-bit color depth setup.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index eeadebdc476caa87aebbbd82f7102b62b22a0ea6..76c30c4ad6768679c3e36e3d0789e716afc0bc30 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -274,6 +274,7 @@ struct rk_hdptx_phy {
 	int nr_clks;
 	struct reset_control_bulk_data rsts[RST_MAX];
 	unsigned long tmds_char_rate;
+	unsigned int bpc;
 
 	/* clk provider */
 	struct clk_hw hw;
@@ -814,6 +815,9 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
 	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_SEL_MASK,
+			   FIELD_PREP(PLL_PCG_CLK_SEL_MASK, (hdptx->bpc - 8) >> 1));
+
 	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN,
 			   PLL_PCG_CLK_EN);
 
@@ -916,7 +920,7 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 		rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
 	}
 
-	dev_dbg(hdptx->dev, "%s rate=%u\n", __func__, rate);
+	dev_dbg(hdptx->dev, "%s rate=%u bpc=%u\n", __func__, rate, hdptx->bpc);
 
 	ret = rk_hdptx_phy_consumer_get(hdptx, rate);
 	if (ret)
@@ -943,6 +947,18 @@ static int rk_hdptx_phy_configure(struct phy *phy,
 
 	hdptx->tmds_char_rate = opts->hdmi.tmds_char_rate;
 
+	switch (opts->hdmi.bpc) {
+	case 8:
+	case 10:
+	case 12:
+	case 16:
+		hdptx->bpc = opts->hdmi.bpc;
+		break;
+	default:
+		dev_warn(hdptx->dev, "Discarded unsupported bpc: %u\n",
+			 opts->hdmi.bpc);
+	};
+
 	return 0;
 }
 
@@ -1090,6 +1106,7 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	hdptx->dev = dev;
+	hdptx->bpc = 8;
 
 	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))

-- 
2.47.0



From khilman at baylibre.com  Fri Dec  6 14:12:51 2024
From: khilman at baylibre.com (Kevin Hilman)
Date: Fri, 06 Dec 2024 14:12:51 -0800
Subject: [PATCH v6 2/3] pmdomain: ti_sci: add wakeup constraint management
In-Reply-To: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
References: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
Message-ID: <20241206-lpm-v6-10-constraints-pmdomain-v6-2-833980158c68@baylibre.com>

During system-wide suspend, check all devices connected to PM domain
to see if they are wakeup-enabled.  If so, set a TI SCI device
constraint.

Note: DM firmware clears all constraints on resume.

Co-developed-by: Vibhore Vardhan <vibhore at ti.com>
Signed-off-by: Vibhore Vardhan <vibhore at ti.com>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Tested-by: Dhruva Gole <d-gole at ti.com>
Signed-off-by: Kevin Hilman <khilman at baylibre.com>
---
 drivers/pmdomain/ti/ti_sci_pm_domains.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
index 963fe1901c959197d5d8b5d34fd8420dfb180087..587961519dcc9e13c32efe76cdaf801281f72f67 100644
--- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
+++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
@@ -79,6 +79,21 @@ static void ti_sci_pd_set_lat_constraint(struct device *dev, s32 val)
 }
 #endif
 
+static inline void ti_sci_pd_set_wkup_constraint(struct device *dev)
+{
+	struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
+	struct ti_sci_pm_domain *pd = genpd_to_ti_sci_pd(genpd);
+	const struct ti_sci_handle *ti_sci = pd->parent->ti_sci;
+	int ret;
+
+	if (device_may_wakeup(dev)) {
+		ret = ti_sci->ops.pm_ops.set_device_constraint(ti_sci, pd->idx,
+							       TISCI_MSG_CONSTRAINT_SET);
+		if (!ret)
+			dev_dbg(dev, "ti_sci_pd: ID:%d set device constraint.\n", pd->idx);
+	}
+}
+
 /*
  * ti_sci_pd_power_off(): genpd power down hook
  * @domain: pointer to the powerdomain to power off
@@ -121,6 +136,8 @@ static int ti_sci_pd_suspend(struct device *dev)
 	if (ti_sci_pd_is_valid_constraint(val))
 		ti_sci_pd_set_lat_constraint(dev, val);
 
+	ti_sci_pd_set_wkup_constraint(dev);
+
 	return 0;
 }
 #else

-- 
2.46.2



From khilman at baylibre.com  Fri Dec  6 14:12:52 2024
From: khilman at baylibre.com (Kevin Hilman)
Date: Fri, 06 Dec 2024 14:12:52 -0800
Subject: [PATCH v6 3/3] pmdomain: ti_sci: handle wake IRQs for IO daisy
 chain wakeups
In-Reply-To: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
References: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
Message-ID: <20241206-lpm-v6-10-constraints-pmdomain-v6-3-833980158c68@baylibre.com>

When a device supports IO daisy-chain wakeups, it uses a dedicated
wake IRQ.  Devices with IO daisy-chain wakeups enabled should not set
wakeup constraints since these can happen even from deep power states,
so should not prevent the DM from picking deep power states.

Wake IRQs are set with dev_pm_set_wake_irq() or
dev_pm_set_dedicated_wake_irq().  The latter is used by the serial
driver used on K3 platforms (drivers/tty/serial/8250/8250_omap.c)
when the interrupts-extended property is used to describe the
dedicated wakeup interrupt.

Detect these wake IRQs in the suspend path, and if set, skip sending
constraint.

Tested-by: Dhruva Gole <d-gole at ti.com>
Signed-off-by: Kevin Hilman <khilman at baylibre.com>
---
 drivers/pmdomain/ti/ti_sci_pm_domains.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
index 587961519dcc9e13c32efe76cdaf801281f72f67..3fb78343d4388a7087dab5061c1127586968ef19 100644
--- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
+++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
@@ -87,6 +87,15 @@ static inline void ti_sci_pd_set_wkup_constraint(struct device *dev)
 	int ret;
 
 	if (device_may_wakeup(dev)) {
+		/*
+		 * If device can wakeup using IO daisy chain wakeups,
+		 * we do not want to set a constraint.
+		 */
+		if (dev->power.wakeirq) {
+			dev_dbg(dev, "%s: has wake IRQ, not setting constraints\n", __func__);
+			return;
+		}
+
 		ret = ti_sci->ops.pm_ops.set_device_constraint(ti_sci, pd->idx,
 							       TISCI_MSG_CONSTRAINT_SET);
 		if (!ret)

-- 
2.46.2



From zmw12306 at gmail.com  Fri Dec  6 14:16:18 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Fri,  6 Dec 2024 17:16:18 -0500
Subject: [PATCH v2] pinctrl: nomadik: Add check for clk_enable()
Message-ID: <20241206221618.3453159-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error.
Disable success clks in the error handling.
Change return type of nmk_gpio_glitch_slpm_init casade.

Fixes: 3a19805920f1 ("pinctrl: nomadik: move all Nomadik drivers to subdir")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
Changelog:

v1 -> v2:

1. Add clk_disable in error handling.
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 35 ++++++++++++++++++-----
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index f4f10c60c1d2..4261541928e9 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -438,9 +438,9 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
  *  - Any spurious wake up event during switch sequence to be ignored and
  *    cleared
  */
-static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
+static int nmk_gpio_glitch_slpm_init(unsigned int *slpm)
 {
-	int i;
+	int i, j, ret;
 
 	for (i = 0; i < NMK_MAX_BANKS; i++) {
 		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
@@ -449,11 +449,21 @@ static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
 		if (!chip)
 			break;
 
-		clk_enable(chip->clk);
+		ret = clk_enable(chip->clk);
+		if (ret) {
+			for (j = 0; j < i; j++) {
+				chip = nmk_gpio_chips[j];
+				clk_disable(chip->clk);
+			}
 
+			return ret;
+		}
+
 		slpm[i] = readl(chip->addr + NMK_GPIO_SLPC);
 		writel(temp, chip->addr + NMK_GPIO_SLPC);
 	}
+
+	return 0;
 }
 
 static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
@@ -923,7 +933,9 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 
 			slpm[nmk_chip->bank] &= ~BIT(bit);
 		}
-		nmk_gpio_glitch_slpm_init(slpm);
+		ret = nmk_gpio_glitch_slpm_init(slpm);
+		if (ret)
+			goto out_pre_slpm_init;
 	}
 
 	for (i = 0; i < g->grp.npins; i++) {
@@ -940,7 +952,10 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 		dev_dbg(npct->dev, "setting pin %d to altsetting %d\n",
 			g->grp.pins[i], g->altsetting);
 
-		clk_enable(nmk_chip->clk);
+		ret = clk_enable(nmk_chip->clk);
+		if (ret)
+			goto out_glitch;
+
 		/*
 		 * If the pin is switching to altfunc, and there was an
 		 * interrupt installed on it which has been lazy disabled,
@@ -988,6 +1003,7 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 	struct nmk_gpio_chip *nmk_chip;
 	struct gpio_chip *chip;
 	unsigned int bit;
+	int ret;
 
 	if (!range) {
 		dev_err(npct->dev, "invalid range\n");
@@ -1004,7 +1020,9 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 
 	find_nmk_gpio_from_pin(pin, &bit);
 
-	clk_enable(nmk_chip->clk);
+	ret = clk_enable(nmk_chip->clk);
+	if (ret)
+		return ret;
 	/* 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);
@@ -1058,6 +1076,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
 	unsigned long cfg;
 	int pull, slpm, output, val, i;
 	bool lowemi, gpiomode, sleep;
+	int ret;
 
 	nmk_chip = find_nmk_gpio_from_pin(pin, &bit);
 	if (!nmk_chip) {
@@ -1116,7 +1135,9 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
 			output ? (val ? "high" : "low") : "",
 			lowemi ? "on" : "off");
 
-		clk_enable(nmk_chip->clk);
+		ret = clk_enable(nmk_chip->clk);
+		if (ret)
+			return ret;
 		if (gpiomode)
 			/* No glitch when going to GPIO mode */
 			__nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
-- 
2.34.1



From khilman at baylibre.com  Fri Dec  6 14:12:50 2024
From: khilman at baylibre.com (Kevin Hilman)
Date: Fri, 06 Dec 2024 14:12:50 -0800
Subject: [PATCH v6 1/3] pmdomain: ti_sci: add per-device latency constraint
 management
In-Reply-To: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
References: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
Message-ID: <20241206-lpm-v6-10-constraints-pmdomain-v6-1-833980158c68@baylibre.com>

For each device in a TI SCI PM domain, check whether the device has
any resume latency constraints set via per-device PM QoS.  If
constraints are set, send them to DM via the new SCI constraints API.

Checking for constraints happen for each device before system-wide
suspend (via ->suspend() hook.)

An important detail here is that the PM domain driver inserts itself
into the path of both the ->suspend() and ->resume() hook path
of *all* devices in the PM domain.  This allows generic PM domain code
to handle the constraint management and communication with TI SCI.

Further, this allows device drivers to use existing PM QoS APIs to
add/update constraints.

DM firmware clears constraints during its resume, so Linux has
to check/update/send constraints each time system suspends.

Also note that the PM QoS framework uses usecs as the units for
latency whereas the TI SCI firmware uses msecs, so a conversion is
needed before passing to TI SCI.

Co-developed-by: Vibhore Vardhan <vibhore at ti.com>
Signed-off-by: Vibhore Vardhan <vibhore at ti.com>
Reviewed-by: Markus Schneider-Pargmann <msp at baylibre.com>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Tested-by: Dhruva Gole <d-gole at ti.com>
Signed-off-by: Kevin Hilman <khilman at baylibre.com>
---
 drivers/pmdomain/ti/ti_sci_pm_domains.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
index 0e4bd749d067309654307484c5bb98711bf06daf..963fe1901c959197d5d8b5d34fd8420dfb180087 100644
--- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
+++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
@@ -13,6 +13,8 @@
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/slab.h>
+#include <linux/pm_qos.h>
+#include <linux/pm_runtime.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
 #include <dt-bindings/soc/ti,sci_pm_domain.h>
 
@@ -51,6 +53,32 @@ struct ti_sci_pm_domain {
 
 #define genpd_to_ti_sci_pd(gpd) container_of(gpd, struct ti_sci_pm_domain, pd)
 
+static inline bool ti_sci_pd_is_valid_constraint(s32 val)
+{
+	return val != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void ti_sci_pd_set_lat_constraint(struct device *dev, s32 val)
+{
+	struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
+	struct ti_sci_pm_domain *pd = genpd_to_ti_sci_pd(genpd);
+	const struct ti_sci_handle *ti_sci = pd->parent->ti_sci;
+	u16 val_ms;
+	int ret;
+
+	/* PM QoS latency unit is usecs, TI SCI uses msecs */
+	val_ms = val / USEC_PER_MSEC;
+	ret = ti_sci->ops.pm_ops.set_latency_constraint(ti_sci, val_ms, TISCI_MSG_CONSTRAINT_SET);
+	if (ret)
+		dev_err(dev, "ti_sci_pd: set latency constraint failed: ret=%d\n",
+			ret);
+	else
+		dev_dbg(dev, "ti_sci_pd: ID:%d set latency constraint %d\n",
+			pd->idx, val);
+}
+#endif
+
 /*
  * ti_sci_pd_power_off(): genpd power down hook
  * @domain: pointer to the powerdomain to power off
@@ -79,6 +107,26 @@ static int ti_sci_pd_power_on(struct generic_pm_domain *domain)
 		return ti_sci->ops.dev_ops.get_device(ti_sci, pd->idx);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int ti_sci_pd_suspend(struct device *dev)
+{
+	int ret;
+	s32 val;
+
+	ret = pm_generic_suspend(dev);
+	if (ret)
+		return ret;
+
+	val = dev_pm_qos_read_value(dev, DEV_PM_QOS_RESUME_LATENCY);
+	if (ti_sci_pd_is_valid_constraint(val))
+		ti_sci_pd_set_lat_constraint(dev, val);
+
+	return 0;
+}
+#else
+#define ti_sci_pd_suspend		NULL
+#endif
+
 /*
  * ti_sci_pd_xlate(): translation service for TI SCI genpds
  * @genpdspec: DT identification data for the genpd
@@ -182,6 +230,13 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
 				pd->pd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
 				pd->idx = args.args[0];
 				pd->parent = pd_provider;
+				/*
+				 * If SCI constraint functions are present, then firmware
+				 * supports the constraints API.
+				 */
+				if (pd_provider->ti_sci->ops.pm_ops.set_device_constraint &&
+				    pd_provider->ti_sci->ops.pm_ops.set_latency_constraint)
+					pd->pd.domain.ops.suspend = ti_sci_pd_suspend;
 
 				pm_genpd_init(&pd->pd, NULL, true);
 

-- 
2.46.2



From khilman at baylibre.com  Fri Dec  6 14:12:49 2024
From: khilman at baylibre.com (Kevin Hilman)
Date: Fri, 06 Dec 2024 14:12:49 -0800
Subject: [PATCH v6 0/3] pmdomain: ti_sci: collect and send low-power mode
 constraints
Message-ID: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>

The latest (10.x) version of the firmware for the PM co-processor (aka
device manager, or DM) adds support for a "managed" mode, where the DM
firmware will select the specific low power state which is entered
when Linux requests a system-wide suspend.

In this mode, the DM will always attempt the deepest low-power state
available for the SoC.

However, Linux (or OSes running on other cores) may want to constrain
the DM for certain use cases.  For example, the deepest state may have
a wakeup/resume latency that is too long for certain use cases.  Or,
some wakeup-capable devices may potentially be powered off in deep
low-power states, but if one of those devices is enabled as a wakeup
source, it should not be powered off.

These kinds of constraints are are already known in Linux by the use
of existing APIs such as per-device PM QoS and device wakeup APIs, but
now we need to communicate these constraints to the DM.

For TI SoCs with TI SCI support, all DM-managed devices will be
connected to a TI SCI PM domain.  So the goal of this series is to use
the PM domain driver for TI SCI devices to collect constraints, and
communicate them to the DM via the new TI SCI APIs.

This is all managed by TI SCI PM domain code.  No new APIs are needed
by Linux drivers.  Any device that is managed by TI SCI will be
checked for QoS constraints or wakeup capability and the constraints
will be collected and sent to the DM.

This series depends on the support for the new TI SCI APIs (v10) and
was also tested with this series to update 8250_omap serial support
for AM62x[2].

[1] https://lore.kernel.org/all/20240801195422.2296347-1-msp at baylibre.com
[2] https://lore.kernel.org/all/20240807141227.1093006-1-msp at baylibre.com/

Signed-off-by: Kevin Hilman <khilman at baylibre.com>
---
Changes in v6:
- fix build warning on arm32 when building with W=1 and CONFIG_PM_SLEEP=n
- rebase onto v6.13-rc1
- fix latency units: convert usecs (PM QoS) to msecs (TI SCI)
- all dependencies are now merged in v6.13-rc1
- Link to v5: https://lore.kernel.org/r/20241101-lpm-v6-10-constraints-pmdomain-v5-0-3011aa04622f at baylibre.com

Changes in v5:
- fix build error when CONFIG_PM_SLEEP not defined
- Link to v4: https://lore.kernel.org/r/20240906-lpm-v6-10-constraints-pmdomain-v4-0-4055557fafbc at baylibre.com

Changes in v4:
- fixed missing return in wakeirq error path
- updated trailers with reviewed & tested tags
- Link to v3: https://lore.kernel.org/r/20240905-lpm-v6-10-constraints-pmdomain-v3-0-e359cbb39654 at baylibre.com

Changes in v3:
- change latency set functions to static void
- Link to v2: https://lore.kernel.org/r/20240819-lpm-v6-10-constraints-pmdomain-v2-0-461325a6008f at baylibre.com

Changes in v2:
- To simplify this version a bit, drop the pmdomain ->power_off()
  changes.  Constraints only sent during ->suspend() path.  The pmdomain
  path was an optimization that may be added back later.
- With the above simplification, drop the extra state variables that
  had been added to keep track of constraint status.
- Link to v1: https://lore.kernel.org/r/20240805-lpm-v6-10-constraints-pmdomain-v1-0-d186b68ded4c at baylibre.com

---
Kevin Hilman (3):
      pmdomain: ti_sci: add per-device latency constraint management
      pmdomain: ti_sci: add wakeup constraint management
      pmdomain: ti_sci: handle wake IRQs for IO daisy chain wakeups

 drivers/pmdomain/ti/ti_sci_pm_domains.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)
---
base-commit: cbc4912199deab59fdbd830b115d81941d0add46
change-id: 20240802-lpm-v6-10-constraints-pmdomain-f33df5aef449

Best regards,
-- 
Kevin Hilman <khilman at baylibre.com>



From sboyd at kernel.org  Fri Dec  6 14:15:47 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 06 Dec 2024 14:15:47 -0800
Subject: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
In-Reply-To: <OS8PR06MB75418449B451224C5AB46FBFF2302@OS8PR06MB7541.apcprd06.prod.outlook.com>
References: <20241028053018.2579200-1-ryan_chen@aspeedtech.com> <20241028053018.2579200-4-ryan_chen@aspeedtech.com> <287924eed186e3b6b52cd13bcf939ab6.sboyd@kernel.org> <SI6PR06MB7535F5D22E3FCCF5C610B307F2552@SI6PR06MB7535.apcprd06.prod.outlook.com> <a68516df98c8b8fb80f094e6e55fcb8d.sboyd@kernel.org> <OS8PR06MB75419637D55A022300E00850F2352@OS8PR06MB7541.apcprd06.prod.outlook.com> <9ccfb478d9a122db6c634e9559e211ff.sboyd@kernel.org> <OS8PR06MB75418449B451224C5AB46FBFF2302@OS8PR06MB7541.apcprd06.prod.outlook.com>
Message-ID: <c898338622625cbfc825e8d4cc5f0fff.sboyd@kernel.org>

Quoting Ryan Chen (2024-12-04 16:48:42)
> > > struct ast2700_clk_info {
> > >         const char *name;
> > >         u8 clk_idx;
> > >         u32 reg;
> > >         u32 type;
> > >         union {
> > >                 struct ast2700_clk_fixed_factor_data factor;
> > >                 struct ast2700_clk_fixed_rate_data rate;
> > >                 struct ast2700_clk_gate_data gate;
> > >                 struct ast2700_clk_div_data div;
> > >                 struct ast2700_clk_pll_data pll;
> > >                 struct ast2700_clk_mux_data mux;
> > >         } data;
> > > };
> > >
> > > struct ast2700_clk_div_data {
> > >         const struct clk_div_table *div_table;
> > >         const struct clk_parent_data *parent;
> > >         u8 bit_shift;
> > >         u8 bit_width;
> > >         u32 reg;
> > > };
> > >
> > > static const struct ast2700_clk_info ast2700_scu0_clk_info[]
> > > __initconst = { ...........................
> > >         DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,
> > 
> > Can you also show what soc0_ahbmux is?
> It will be following. 
> 
> static const struct clk_parent_data soc0_ahbmux[] = {
>         { .fw_name = "soc0-ahbmux", .name = "soc0-ahbmux" },
> };

Instead of that, please use only the index.

 static const struct clk_parent_data soc0_ahbmux[] = {
         { .index = <number from DT binding> },
 };


From nunodasneves at linux.microsoft.com  Fri Dec  6 14:21:45 2024
From: nunodasneves at linux.microsoft.com (Nuno Das Neves)
Date: Fri,  6 Dec 2024 14:21:45 -0800
Subject: [PATCH 0/2] hyperv: Move some features to common code
Message-ID: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>

There are several bits of Hyper-V-related code that today live in
arch/x86 but are not really specific to x86_64 and will work on arm64
too.

Some of these will be needed in the upcoming mshv driver code (for
Linux as root partition on Hyper-V). So this is a good time to move
them to hv_common.c.

Signed-off-by: Nuno Das Neves <nudasnev at microsoft.com>

Nuno Das Neves (2):
  hyperv: Move hv_current_partition_id to arch-generic code
  hyperv: Move create_vp and deposit_pages hvcalls to hv_common.c

 arch/arm64/hyperv/mshyperv.c    |   3 +
 arch/x86/hyperv/hv_init.c       |  25 +----
 arch/x86/hyperv/hv_proc.c       | 144 ---------------------------
 arch/x86/include/asm/mshyperv.h |   4 -
 drivers/hv/hv_common.c          | 168 ++++++++++++++++++++++++++++++++
 include/asm-generic/mshyperv.h  |   4 +
 6 files changed, 176 insertions(+), 172 deletions(-)

-- 
2.34.1



From nunodasneves at linux.microsoft.com  Fri Dec  6 14:21:46 2024
From: nunodasneves at linux.microsoft.com (Nuno Das Neves)
Date: Fri,  6 Dec 2024 14:21:46 -0800
Subject: [PATCH 1/2] hyperv: Move hv_current_partition_id to arch-generic code
In-Reply-To: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
References: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <1733523707-15954-2-git-send-email-nunodasneves@linux.microsoft.com>

From: Nuno Das Neves <nudasnev at microsoft.com>

Make hv_current_partition_id available in both x86_64 and arm64.
This feature isn't specific to x86_64 and will be needed by common
code.

While at it, replace the BUG()s with WARN()s. Failing to get the id
need not crash the machine (although it is a very bad sign).

Signed-off-by: Nuno Das Neves <nudasnev at microsoft.com>
---
 arch/arm64/hyperv/mshyperv.c    |  3 +++
 arch/x86/hyperv/hv_init.c       | 25 +------------------------
 arch/x86/include/asm/mshyperv.h |  2 --
 drivers/hv/hv_common.c          | 23 +++++++++++++++++++++++
 include/asm-generic/mshyperv.h  |  2 ++
 5 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index b1a4de4eee29..5050e748d266 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -19,6 +19,9 @@
 
 static bool hyperv_initialized;
 
+u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
+EXPORT_SYMBOL_GPL(hv_current_partition_id);
+
 int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
 {
 	hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 95eada2994e1..950f5ccdb9d9 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -35,7 +35,7 @@
 #include <clocksource/hyperv_timer.h>
 #include <linux/highmem.h>
 
-u64 hv_current_partition_id = ~0ull;
+u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
 EXPORT_SYMBOL_GPL(hv_current_partition_id);
 
 void *hv_hypercall_pg;
@@ -394,24 +394,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
 		old_setup_percpu_clockev();
 }
 
-static void __init hv_get_partition_id(void)
-{
-	struct hv_get_partition_id *output_page;
-	u64 status;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
-	status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
-	if (!hv_result_success(status)) {
-		/* No point in proceeding if this failed */
-		pr_err("Failed to get partition ID: %lld\n", status);
-		BUG();
-	}
-	hv_current_partition_id = output_page->partition_id;
-	local_irq_restore(flags);
-}
-
 #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
 static u8 __init get_vtl(void)
 {
@@ -606,11 +588,6 @@ void __init hyperv_init(void)
 
 	register_syscore_ops(&hv_syscore_ops);
 
-	if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
-		hv_get_partition_id();
-
-	BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);
-
 #ifdef CONFIG_PCI_MSI
 	/*
 	 * If we're running as root, we want to create our own PCI MSI domain.
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 5f0bc6a6d025..9eeca2a6d047 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -44,8 +44,6 @@ extern bool hyperv_paravisor_present;
 
 extern void *hv_hypercall_pg;
 
-extern u64 hv_current_partition_id;
-
 extern union hv_ghcb * __percpu *hv_ghcb_pg;
 
 bool hv_isolation_type_snp(void);
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 7a35c82976e0..819bcfd2b149 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -278,11 +278,34 @@ static void hv_kmsg_dump_register(void)
 	}
 }
 
+static void __init hv_get_partition_id(void)
+{
+	struct hv_get_partition_id *output_page;
+	u64 status;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
+	status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
+	if (!hv_result_success(status)) {
+		local_irq_restore(flags);
+		WARN(true, "Failed to get partition ID: %lld\n", status);
+		return;
+	}
+	hv_current_partition_id = output_page->partition_id;
+	local_irq_restore(flags);
+}
+
 int __init hv_common_init(void)
 {
 	int i;
 	union hv_hypervisor_version_info version;
 
+	if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
+		hv_get_partition_id();
+
+	WARN_ON(hv_root_partition && hv_current_partition_id == HV_PARTITION_ID_SELF);
+
 	/* Get information about the Hyper-V host version */
 	if (!hv_get_hypervisor_version(&version))
 		pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 8fe7aaab2599..8c4ff6e9aae7 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -60,6 +60,8 @@ struct ms_hyperv_info {
 extern struct ms_hyperv_info ms_hyperv;
 extern bool hv_nested;
 
+extern u64 hv_current_partition_id;
+
 extern void * __percpu *hyperv_pcpu_input_arg;
 extern void * __percpu *hyperv_pcpu_output_arg;
 
-- 
2.34.1



From nunodasneves at linux.microsoft.com  Fri Dec  6 14:21:47 2024
From: nunodasneves at linux.microsoft.com (Nuno Das Neves)
Date: Fri,  6 Dec 2024 14:21:47 -0800
Subject: [PATCH 2/2] hyperv: Move create_vp and deposit_pages hvcalls to hv_common.c
In-Reply-To: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
References: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <1733523707-15954-3-git-send-email-nunodasneves@linux.microsoft.com>

From: Nuno Das Neves <nudasnev at microsoft.com>

These are not specific to x86_64 and will be needed by common code.

Signed-off-by: Nuno Das Neves <nudasnev at microsoft.com>
---
 arch/x86/hyperv/hv_proc.c       | 144 -------------------------------
 arch/x86/include/asm/mshyperv.h |   2 -
 drivers/hv/hv_common.c          | 145 ++++++++++++++++++++++++++++++++
 include/asm-generic/mshyperv.h  |   2 +
 4 files changed, 147 insertions(+), 146 deletions(-)

diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 3fa1f2ee7b0d..119354d00637 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -10,109 +10,8 @@
 #include <asm/hypervisor.h>
 #include <asm/mshyperv.h>
 #include <asm/apic.h>
-
 #include <asm/trace/hyperv.h>
 
-/*
- * See struct hv_deposit_memory. The first u64 is partition ID, the rest
- * are GPAs.
- */
-#define HV_DEPOSIT_MAX (HV_HYP_PAGE_SIZE / sizeof(u64) - 1)
-
-/* Deposits exact number of pages. Must be called with interrupts enabled.  */
-int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages)
-{
-	struct page **pages, *page;
-	int *counts;
-	int num_allocations;
-	int i, j, page_count;
-	int order;
-	u64 status;
-	int ret;
-	u64 base_pfn;
-	struct hv_deposit_memory *input_page;
-	unsigned long flags;
-
-	if (num_pages > HV_DEPOSIT_MAX)
-		return -E2BIG;
-	if (!num_pages)
-		return 0;
-
-	/* One buffer for page pointers and counts */
-	page = alloc_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-	pages = page_address(page);
-
-	counts = kcalloc(HV_DEPOSIT_MAX, sizeof(int), GFP_KERNEL);
-	if (!counts) {
-		free_page((unsigned long)pages);
-		return -ENOMEM;
-	}
-
-	/* Allocate all the pages before disabling interrupts */
-	i = 0;
-
-	while (num_pages) {
-		/* Find highest order we can actually allocate */
-		order = 31 - __builtin_clz(num_pages);
-
-		while (1) {
-			pages[i] = alloc_pages_node(node, GFP_KERNEL, order);
-			if (pages[i])
-				break;
-			if (!order) {
-				ret = -ENOMEM;
-				num_allocations = i;
-				goto err_free_allocations;
-			}
-			--order;
-		}
-
-		split_page(pages[i], order);
-		counts[i] = 1 << order;
-		num_pages -= counts[i];
-		i++;
-	}
-	num_allocations = i;
-
-	local_irq_save(flags);
-
-	input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-	input_page->partition_id = partition_id;
-
-	/* Populate gpa_page_list - these will fit on the input page */
-	for (i = 0, page_count = 0; i < num_allocations; ++i) {
-		base_pfn = page_to_pfn(pages[i]);
-		for (j = 0; j < counts[i]; ++j, ++page_count)
-			input_page->gpa_page_list[page_count] = base_pfn + j;
-	}
-	status = hv_do_rep_hypercall(HVCALL_DEPOSIT_MEMORY,
-				     page_count, 0, input_page, NULL);
-	local_irq_restore(flags);
-	if (!hv_result_success(status)) {
-		pr_err("Failed to deposit pages: %lld\n", status);
-		ret = hv_result(status);
-		goto err_free_allocations;
-	}
-
-	ret = 0;
-	goto free_buf;
-
-err_free_allocations:
-	for (i = 0; i < num_allocations; ++i) {
-		base_pfn = page_to_pfn(pages[i]);
-		for (j = 0; j < counts[i]; ++j)
-			__free_page(pfn_to_page(base_pfn + j));
-	}
-
-free_buf:
-	free_page((unsigned long)pages);
-	kfree(counts);
-	return ret;
-}
-
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id)
 {
 	struct hv_input_add_logical_processor *input;
@@ -154,46 +53,3 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id)
 	return ret;
 }
 
-int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
-{
-	struct hv_create_vp *input;
-	u64 status;
-	unsigned long irq_flags;
-	int ret = HV_STATUS_SUCCESS;
-
-	/* Root VPs don't seem to need pages deposited */
-	if (partition_id != hv_current_partition_id) {
-		/* The value 90 is empirically determined. It may change. */
-		ret = hv_call_deposit_pages(node, partition_id, 90);
-		if (ret)
-			return ret;
-	}
-
-	do {
-		local_irq_save(irq_flags);
-
-		input = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-		input->partition_id = partition_id;
-		input->vp_index = vp_index;
-		input->flags = flags;
-		input->subnode_type = HvSubnodeAny;
-		input->proximity_domain_info = hv_numa_node_to_pxm_info(node);
-		status = hv_do_hypercall(HVCALL_CREATE_VP, input, NULL);
-		local_irq_restore(irq_flags);
-
-		if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
-			if (!hv_result_success(status)) {
-				pr_err("%s: vcpu %u, lp %u, %lld\n", __func__,
-				       vp_index, flags, status);
-				ret = hv_result(status);
-			}
-			break;
-		}
-		ret = hv_call_deposit_pages(node, partition_id, 1);
-
-	} while (!ret);
-
-	return ret;
-}
-
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 9eeca2a6d047..5bad88cfccba 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -57,9 +57,7 @@ u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
 #define HV_AP_INIT_GPAT_DEFAULT		0x0007040600070406ULL
 #define HV_AP_SEGMENT_LIMIT		0xffffffff
 
-int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
-int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
 
 /*
  * If the hypercall involves no input or output parameters, the hypervisor
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 819bcfd2b149..591cc51e8817 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -679,3 +679,148 @@ u64 __weak hv_tdx_hypercall(u64 control, u64 param1, u64 param2)
 	return HV_STATUS_INVALID_PARAMETER;
 }
 EXPORT_SYMBOL_GPL(hv_tdx_hypercall);
+
+int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
+{
+	struct hv_create_vp *input;
+	u64 status;
+	unsigned long irq_flags;
+	int ret = HV_STATUS_SUCCESS;
+
+	/* Root VPs don't seem to need pages deposited */
+	if (partition_id != hv_current_partition_id) {
+		/* The value 90 is empirically determined. It may change. */
+		ret = hv_call_deposit_pages(node, partition_id, 90);
+		if (ret)
+			return ret;
+	}
+
+	do {
+		local_irq_save(irq_flags);
+
+		input = *this_cpu_ptr(hyperv_pcpu_input_arg);
+
+		input->partition_id = partition_id;
+		input->vp_index = vp_index;
+		input->flags = flags;
+		input->subnode_type = HvSubnodeAny;
+		input->proximity_domain_info = hv_numa_node_to_pxm_info(node);
+		status = hv_do_hypercall(HVCALL_CREATE_VP, input, NULL);
+		local_irq_restore(irq_flags);
+
+		if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
+			if (!hv_result_success(status)) {
+				pr_err("%s: vcpu %u, lp %u, %lld\n", __func__,
+				       vp_index, flags, status);
+				ret = hv_result(status);
+			}
+			break;
+		}
+		ret = hv_call_deposit_pages(node, partition_id, 1);
+
+	} while (!ret);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(hv_call_create_vp);
+
+/*
+ * See struct hv_deposit_memory. The first u64 is partition ID, the rest
+ * are GPAs.
+ */
+#define HV_DEPOSIT_MAX (HV_HYP_PAGE_SIZE / sizeof(u64) - 1)
+
+/* Deposits exact number of pages. Must be called with interrupts enabled.  */
+int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages)
+{
+	struct page **pages, *page;
+	int *counts;
+	int num_allocations;
+	int i, j, page_count;
+	int order;
+	u64 status;
+	int ret;
+	u64 base_pfn;
+	struct hv_deposit_memory *input_page;
+	unsigned long flags;
+
+	if (num_pages > HV_DEPOSIT_MAX)
+		return -E2BIG;
+	if (!num_pages)
+		return 0;
+
+	/* One buffer for page pointers and counts */
+	page = alloc_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+	pages = page_address(page);
+
+	counts = kcalloc(HV_DEPOSIT_MAX, sizeof(int), GFP_KERNEL);
+	if (!counts) {
+		free_page((unsigned long)pages);
+		return -ENOMEM;
+	}
+
+	/* Allocate all the pages before disabling interrupts */
+	i = 0;
+
+	while (num_pages) {
+		/* Find highest order we can actually allocate */
+		order = 31 - __builtin_clz(num_pages);
+
+		while (1) {
+			pages[i] = alloc_pages_node(node, GFP_KERNEL, order);
+			if (pages[i])
+				break;
+			if (!order) {
+				ret = -ENOMEM;
+				num_allocations = i;
+				goto err_free_allocations;
+			}
+			--order;
+		}
+
+		split_page(pages[i], order);
+		counts[i] = 1 << order;
+		num_pages -= counts[i];
+		i++;
+	}
+	num_allocations = i;
+
+	local_irq_save(flags);
+
+	input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
+
+	input_page->partition_id = partition_id;
+
+	/* Populate gpa_page_list - these will fit on the input page */
+	for (i = 0, page_count = 0; i < num_allocations; ++i) {
+		base_pfn = page_to_pfn(pages[i]);
+		for (j = 0; j < counts[i]; ++j, ++page_count)
+			input_page->gpa_page_list[page_count] = base_pfn + j;
+	}
+	status = hv_do_rep_hypercall(HVCALL_DEPOSIT_MEMORY,
+				     page_count, 0, input_page, NULL);
+	local_irq_restore(flags);
+	if (!hv_result_success(status)) {
+		pr_err("Failed to deposit pages: %lld\n", status);
+		ret = hv_result(status);
+		goto err_free_allocations;
+	}
+
+	ret = 0;
+	goto free_buf;
+
+err_free_allocations:
+	for (i = 0; i < num_allocations; ++i) {
+		base_pfn = page_to_pfn(pages[i]);
+		for (j = 0; j < counts[i]; ++j)
+			__free_page(pfn_to_page(base_pfn + j));
+	}
+
+free_buf:
+	free_page((unsigned long)pages);
+	kfree(counts);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(hv_call_deposit_pages);
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 8c4ff6e9aae7..46c0a6cae4e6 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -305,6 +305,8 @@ u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
 void hyperv_cleanup(void);
 bool hv_query_ext_cap(u64 cap_query);
 void hv_setup_dma_ops(struct device *dev, bool coherent);
+int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
+int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
 #else /* CONFIG_HYPERV */
 static inline bool hv_is_hyperv_initialized(void) { return false; }
 static inline bool hv_is_hibernation_supported(void) { return false; }
-- 
2.34.1



From jthoughton at google.com  Fri Dec  6 14:46:58 2024
From: jthoughton at google.com (James Houghton)
Date: Fri,  6 Dec 2024 22:46:58 +0000
Subject: [PATCH v1 01/13] KVM: Add KVM_MEM_USERFAULT memslot flag and bitmap
In-Reply-To: <202412052133.pTg3UAQm-lkp@intel.com>
References: <202412052133.pTg3UAQm-lkp@intel.com>
Message-ID: <20241206224658.2833655-1-jthoughton@google.com>

>    arch/x86/kvm/../../../virt/kvm/kvm_main.c: In function '__kvm_set_memory_region':
> >> arch/x86/kvm/../../../virt/kvm/kvm_main.c:2049:41: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
>     2049 |                 new->userfault_bitmap = (unsigned long *)mem->userfault_bitmap;
>          |                                         ^

I realize that, not only have I done this cast slightly wrong, I'm
missing a few checks on userfault_bitmap that I should have. Applying
this diff, or at least something like it, to fix it:

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index b552cdef2850..30f09141df64 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1977,6 +1977,12 @@ int __kvm_set_memory_region(struct kvm *kvm,
 		return -EINVAL;
 	if ((mem->memory_size >> PAGE_SHIFT) > KVM_MEM_MAX_NR_PAGES)
 		return -EINVAL;
+	if (mem->flags & KVM_MEM_USERFAULT &&
+	    ((mem->userfault_bitmap != untagged_addr(mem->userfault_bitmap)) ||
+	     !access_ok((void __user *)(unsigned long)mem->userfault_bitmap,
+			DIV_ROUND_UP(mem->memory_size >> PAGE_SHIFT, BITS_PER_LONG)
+			 * sizeof(long))))
+		return -EINVAL;
 
 	slots = __kvm_memslots(kvm, as_id);
 
@@ -2053,7 +2059,8 @@ int __kvm_set_memory_region(struct kvm *kvm,
 			goto out;
 	}
 	if (mem->flags & KVM_MEM_USERFAULT)
-		new->userfault_bitmap = (unsigned long *)mem->userfault_bitmap;
+		new->userfault_bitmap =
+		  (unsigned long __user *)(unsigned long)mem->userfault_bitmap;
 
 	r = kvm_set_memslot(kvm, old, new, change);
 	if (r)


From andre.przywara at arm.com  Fri Dec  6 14:53:58 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 6 Dec 2024 22:53:58 +0000
Subject: [PATCH] ARM: sun8i: r40/a40i: rm unneeded PH23 setup which resets
 Banana Pi M2 Ultra V1.1
In-Reply-To: <20241206202005.GA24845@lemon.iwr.uni-heidelberg.de>
References: <20241206202005.GA24845@lemon.iwr.uni-heidelberg.de>
Message-ID: <8906c357-069e-454f-936e-f4a90124118c@arm.com>

Hi Hermann,

thanks for sending the patch!

The subject line would need to be shortened, something like:
ARM: dts: sun8i-r40: remove unused GPIO regulator
(no need to sweat it with the A40i/R40/A40 names, they are all the same 
chip, essentially)

And please add the maintainers in "To:", and put the lists on Cc:, as 
shown by:
$ scripts/get_maintainer.pl 0001-*

On 06/12/2024 20:20, Hermann.Lauer at uni-heidelberg.de wrote:
> Banana Pi M2 Ultra V1.1 board resets immediately when the usb core tries
> to setup PH23 GPIO. It turned out that the V1.0 board USB-A ports are
> always power supplied and according to the board scheme PH23 is simply
> not connected.
> 
> So remove the PH23 setup: Doesn't harm V1.0 (with R40) and let V1.1
> (with A40i) start
> 
> Signed-off-by: Hermann Lauer <Hermann.Lauer at uni-heidelberg.de>
> ---
> 
> # HG changeset patch
> # Parent  236ffa4558b03bbc654515fae80a7a2387f06cd4

Please remove those two lines, if possible.

> diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
> --- a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
> +++ b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
> @@ -347,7 +347,5 @@
>   };
>   
>   &usbphy {
> -	usb1_vbus-supply = <&reg_vcc5v0>;
> -	usb2_vbus-supply = <&reg_vcc5v0>;

So while this fixes your immediate problem, the regulator with the 
deadly GPIO is still in. For once it's not needed anymore, but more 
importantly it still references the problematic GPIO, so please remove 
the whole reg_vcc5v0 regulator node altogether as well.

Cheers,
Andre



>   	status = "okay";
>   };
> 


From ferr.lambarginio at gmail.com  Fri Dec  6 15:19:34 2024
From: ferr.lambarginio at gmail.com (Vladimir Riabchun)
Date: Sat,  7 Dec 2024 00:19:34 +0100
Subject: [PATCH] i2c: pnx: Fix timeout in wait functions
Message-ID: <20241206231937.86408-1-ferr.lambarginio@gmail.com>

Since commit f63b94be6942 ("i2c: pnx: Fix potential deadlock warning
from del_timer_sync() call in isr") jiffies are stored in
i2c_pnx_algo_data.timeout, but wait_timeout and wait_reset are still
using it as milliseconds. Convert jiffies back to milliseconds to wait
for the expected amount of time.

Fixes: f63b94be6942 ("i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr")
Signed-off-by: Vladimir Riabchun <ferr.lambarginio at gmail.com>
---
 drivers/i2c/busses/i2c-pnx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index d4d139b97513..9a1af5bbd604 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -95,7 +95,7 @@ enum {
 
 static inline int wait_timeout(struct i2c_pnx_algo_data *data)
 {
-	long timeout = data->timeout;
+	long timeout = jiffies_to_msecs(data->timeout);
 	while (timeout > 0 &&
 			(ioread32(I2C_REG_STS(data)) & mstatus_active)) {
 		mdelay(1);
@@ -106,7 +106,7 @@ static inline int wait_timeout(struct i2c_pnx_algo_data *data)
 
 static inline int wait_reset(struct i2c_pnx_algo_data *data)
 {
-	long timeout = data->timeout;
+	long timeout = jiffies_to_msecs(data->timeout);
 	while (timeout > 0 &&
 			(ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
 		mdelay(1);
-- 
2.43.0



From jeremy.linton at arm.com  Fri Dec  6 17:21:27 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri,  6 Dec 2024 19:21:27 -0600
Subject: [PATCH v3 0/1] arm64: CCA TSM module autoloading
Message-ID: <20241207012128.247522-1-jeremy.linton@arm.com>

Provide module tables and a platform device so that the
CCA TSM module will autoload when needed.

v2->v3:
	Fix __maybe_used placement, it does fix CLANG builds now.
	Add reviewed-by tag, Thanks Gavin!
	Ugly commit message cleanup.
v1->v2:
	Various comment updates/variable renames
	Add missing __maybe_unused to the platform_device_id

Jeremy Linton (1):
  arm64: rsi: Add automatic arm-cca-guest module loading

 arch/arm64/include/asm/rsi.h                    |  2 ++
 arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
 3 files changed, 25 insertions(+)

-- 
2.46.0



From jeremy.linton at arm.com  Fri Dec  6 17:21:28 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri,  6 Dec 2024 19:21:28 -0600
Subject: [PATCH v3 1/1] arm64: rsi: Add automatic arm-cca-guest module loading
In-Reply-To: <20241207012128.247522-1-jeremy.linton@arm.com>
References: <20241207012128.247522-1-jeremy.linton@arm.com>
Message-ID: <20241207012128.247522-2-jeremy.linton@arm.com>

The TSM module provides guest identification and attestation when a
guest runs in CCA mode. By creating a dummy platform device, let's
ensure the module is automatically loaded. The udev daemon loads the
TSM module after it receives a device addition event. Once that
happens, it can be used earlier in the boot process to decrypt the
rootfs.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
Reviewed-by: Gavin Shan <gshan at redhat.com>
---
 arch/arm64/include/asm/rsi.h                    |  2 ++
 arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
 3 files changed, 25 insertions(+)

diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
index 188cbb9b23f5..b42aeac05340 100644
--- a/arch/arm64/include/asm/rsi.h
+++ b/arch/arm64/include/asm/rsi.h
@@ -10,6 +10,8 @@
 #include <linux/jump_label.h>
 #include <asm/rsi_cmds.h>
 
+#define RSI_PDEV_NAME "arm-cca-dev"
+
 DECLARE_STATIC_KEY_FALSE(rsi_present);
 
 void __init arm64_rsi_init(void);
diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
index 3031f25c32ef..5434e5496ac2 100644
--- a/arch/arm64/kernel/rsi.c
+++ b/arch/arm64/kernel/rsi.c
@@ -8,6 +8,7 @@
 #include <linux/psci.h>
 #include <linux/swiotlb.h>
 #include <linux/cc_platform.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/mem_encrypt.h>
@@ -140,3 +141,17 @@ void __init arm64_rsi_init(void)
 	static_branch_enable(&rsi_present);
 }
 
+static struct platform_device rsi_dev = {
+	.name = RSI_PDEV_NAME,
+	.id = PLATFORM_DEVID_NONE
+};
+
+static int __init rsi_init(void)
+{
+	if (is_realm_world() &&
+	    platform_device_register(&rsi_dev))
+		pr_err("failed to register rsi platform device\n");
+	return 0;
+}
+
+arch_initcall(rsi_init)
diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
index 488153879ec9..87f162736b2e 100644
--- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
+++ b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
@@ -6,6 +6,7 @@
 #include <linux/arm-smccc.h>
 #include <linux/cc_platform.h>
 #include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/tsm.h>
@@ -219,6 +220,13 @@ static void __exit arm_cca_guest_exit(void)
 }
 module_exit(arm_cca_guest_exit);
 
+/* modalias, so userspace can autoload this module when RSI is available */
+static const struct platform_device_id arm_cca_match[] __maybe_unused = {
+	{ RSI_PDEV_NAME, 0},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(platform, arm_cca_match);
 MODULE_AUTHOR("Sami Mujawar <sami.mujawar at arm.com>");
 MODULE_DESCRIPTION("Arm CCA Guest TSM Driver");
 MODULE_LICENSE("GPL");
-- 
2.46.0



From zmw12306 at gmail.com  Fri Dec  6 17:32:58 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Fri,  6 Dec 2024 20:32:58 -0500
Subject: [PATCH] spi: zynq-qspi: Add check for clk_enable()
Message-ID: <20241207013258.3615645-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error.

Fixes: c618a90dcaf3 ("spi: zynq-qspi: Drop GPIO header")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
 drivers/spi/spi-zynq-qspi.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
index dee9c339a35e..ae8a955bb6f1 100644
--- a/drivers/spi/spi-zynq-qspi.c
+++ b/drivers/spi/spi-zynq-qspi.c
@@ -379,12 +379,18 @@ static int zynq_qspi_setup_op(struct spi_device *spi)
 {
 	struct spi_controller *ctlr = spi->controller;
 	struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
+	int ret;
 
 	if (ctlr->busy)
 		return -EBUSY;
 
-	clk_enable(qspi->refclk);
-	clk_enable(qspi->pclk);
+	ret = clk_enable(qspi->refclk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(qspi->pclk);
+	if (ret)
+		return ret;
 	zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET,
 			ZYNQ_QSPI_ENABLE_ENABLE_MASK);
 
-- 
2.34.1



From bagasdotme at gmail.com  Fri Dec  6 17:38:03 2024
From: bagasdotme at gmail.com (Bagas Sanjaya)
Date: Sat, 7 Dec 2024 08:38:03 +0700
Subject: [PATCH v1 13/13] KVM: Documentation: Add KVM_CAP_USERFAULT and
 KVM_MEM_USERFAULT details
In-Reply-To: <20241204191349.1730936-14-jthoughton@google.com>
References: <20241204191349.1730936-1-jthoughton@google.com>
 <20241204191349.1730936-14-jthoughton@google.com>
Message-ID: <Z1Om-1D2g3bFW4U2@archie.me>

On Wed, Dec 04, 2024 at 07:13:48PM +0000, James Houghton wrote:
> Include the note about memory ordering when clearing bits in
> userfault_bitmap, as it may not be obvious for users.

The doc LGTM, thanks!

Reviewed-by: Bagas Sanjaya <bagasdotme at gmail.com>

-- 
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/20241207/38a96f73/attachment.sig>

From zmw12306 at gmail.com  Fri Dec  6 17:47:27 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Fri,  6 Dec 2024 20:47:27 -0500
Subject: [PATCH] spi: zynq-qspi: Add check for clk_enable()
Message-ID: <20241207014727.3674388-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error.

Fixes: c618a90dcaf3 ("spi: zynq-qspi: Drop GPIO header")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
 drivers/spi/spi-zynq-qspi.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
index dee9c339a35e..ae8a955bb6f1 100644
--- a/drivers/spi/spi-zynq-qspi.c
+++ b/drivers/spi/spi-zynq-qspi.c
@@ -379,12 +379,18 @@ static int zynq_qspi_setup_op(struct spi_device *spi)
 {
 	struct spi_controller *ctlr = spi->controller;
 	struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
+	int ret;
 
 	if (ctlr->busy)
 		return -EBUSY;
 
-	clk_enable(qspi->refclk);
-	clk_enable(qspi->pclk);
+	ret = clk_enable(qspi->refclk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(qspi->pclk);
+	if (ret)
+		return ret;
 	zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET,
 			ZYNQ_QSPI_ENABLE_ENABLE_MASK);
 
-- 
2.34.1



From zmw12306 at gmail.com  Fri Dec  6 17:52:06 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Fri,  6 Dec 2024 20:52:06 -0500
Subject: [PATCH v2] spi: zynq-qspi: Add check for clk_enable()
Message-ID: <20241207015206.3689364-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error.

Fixes: c618a90dcaf3 ("spi: zynq-qspi: Drop GPIO header")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
Changelog:

v1 -> v2:

1. Add clk_disable in error handling.
---
 drivers/spi/spi-zynq-qspi.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
index dee9c339a35e..da6c2800d6b5 100644
--- a/drivers/spi/spi-zynq-qspi.c
+++ b/drivers/spi/spi-zynq-qspi.c
@@ -379,12 +379,21 @@ static int zynq_qspi_setup_op(struct spi_device *spi)
 {
 	struct spi_controller *ctlr = spi->controller;
 	struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
+	int ret;
 
 	if (ctlr->busy)
 		return -EBUSY;
 
-	clk_enable(qspi->refclk);
-	clk_enable(qspi->pclk);
+	ret = clk_enable(qspi->refclk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(qspi->pclk);
+	if (ret) {
+		clk_disable(qspi->refclk);
+		return ret;
+	}
+
 	zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET,
 			ZYNQ_QSPI_ENABLE_ENABLE_MASK);
 
-- 
2.34.1



From val at packett.cool  Fri Dec  6 19:11:55 2024
From: val at packett.cool (Val Packett)
Date: Sat, 07 Dec 2024 00:11:55 -0300
Subject: [PATCH 0/5] MT8516/MT8167 dtsi fixes
In-Reply-To: <7bf536a5-30c1-43d8-9ea3-3aaea65c6b0a@collabora.com>
References: <20241204190524.21862-1-val@packett.cool>
	<7bf536a5-30c1-43d8-9ea3-3aaea65c6b0a@collabora.com>
Message-ID: <VVS3OS.MZCWW6ICFFUB3@packett.cool>


On Thu, Dec 5 2024 at 01:27:01 PM +01:00:00, AngeloGioacchino Del Regno 
<angelogioacchino.delregno at collabora.com> wrote:
>> I strongly suggest you to also send one that achieves basic boot 
>> with UART console
> as a first step for upstreaming your board, and then go for 
> incremental changes
> everytime you get a new feature working.

Wanted to get the PMIC in first but sure, could try splitting out the 
initial version without the PMIC.

Oh! One dts/dtsi question: pretty much all MTK devices so far have all 
pinctrl configurations defined per-device. But on this SoC, pin 
assignments have their "canonical" function in the pin name e.g.: 
MT8167_PIN_58_SDA0__FUNC_SDA0_0 and on this device they are used as-is. 
Would it be fine to place these default pinctrl configs for SD/MMC, I2C 
etc. in the SoC dtsi?

>> Generally, if the patches are only simple additions, you could send 
>> the original
> patches without any author variation (and fixing that 
> MT6392_IRQ_numbers enum
> in the original ones because lower case please!) and then your 
> patches on top
> with your additions.

Right, I was mostly unsure if the email workflow supported just sending 
someone else's patches, but I guess that was silly - of course 
git-send-email should do the right thing!

> The upstream driver just gained support for configuring the display 
> paths
> entirely in the devicetree as those are obviously device specific.
> 
> You can make use of that for upstreaming your tablet after adding the 
> display
> nodes (and bindings, if required) as if you go for the default 
> configuration
> that's probably not going to work because it's for the pumpkin boards 
> which
> will most probably have a different display pipeline compared to your 
> board.

The pipeline seems to be the same.. The pumpkin board was brought up 
with DSI as well, the main pipeline I can find in the Android source is 
the same (+ PWM).

I am still struggling to get it to work though: DSI command mode 
configuration gets acknowledged fine, but in burst mode, the vblank 
never arrives. Tried fiddling with various things (CMDQ or not, mutex 
as vblank source since there was an Android commit doing that, etc.), 
nothing helped.

>> By the way, is anyone familiar with PSCI cpuidle/hot-unplug issues on
>> Mediatek Android devices from around this time? [..]
> 
> I did have some issues with an older bootloader on the Xperia M5 
> smartphone
> and would even lock up at boot, because on the old firmwares the power
> domains for the CPUs are not managed automatically by FW.

Interesting, thanks for the pointer!

In the Android kernel sources I could find though, there are no CPU 
domains in the mtk-scpsys-mt8167 driver, and the only references I 
could even find to the related register bits are from code that *reads* 
the status of the CPU power domains to make decisions about sleep 
states (only_one_cpu_online in mtk_idle). Trying to add those to the 
driver anyway, did not succeed so far.

~val





From mailhol.vincent at wanadoo.fr  Fri Dec  6 00:49:37 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 17:49:37 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <CAMZ6RqKLrDB-xkm2G242yU7L=tzxCR9NTwca-1yuWSSEHAOrxQ@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6RqKLrDB-xkm2G242yU7L=tzxCR9NTwca-1yuWSSEHAOrxQ@mail.gmail.com>
Message-ID: <CAMZ6RqJzPqfY4Uy3EWTTqRgN2Gq0hDr2R4zSDMEaMT_CS=05tw@mail.gmail.com>

On Fri. 6 Dec. 2024 at 16:19, Vincent Mailhol
<mailhol.vincent at wanadoo.fr> wrote:
> On Fri. 6 Dec. 2024 at 15:14, Linus Torvalds
> <torvalds at linux-foundation.org> wrote:
> > On Thu, 5 Dec 2024 at 18:26, David Laight <David.Laight at aculab.com> wrote:

(...)

> > I may have liked "!!" for being very idiomatic and traditional C, but
> > there were those pesky compilers that warn about "integer in bool
> > context" or whatever the annoying warning was when then doing the
> > "multiply by zero" to turn a constant expression into a constant zero
> > expression.
> >
> > So that
> >
> >   #define is_const(x) __is_const_zero(0 * (x))
> >
> > causes issues when 'x' is not an integer expression (think
> > "is_const(NULL)" or "is_const(1 == 2)".
>
> But 1 == 2 has already an integer type as proven by:
>
>   #define is_int(x) _Generic(x, int: 1, default: 0)
>   static_assert(is_int(1 == 2));
>
> So, it leaves us with the case is_const(pointer). To which I would
> question if we really want to support this. By definition, an
> expression with a pointer type can not be an *integer* constant
> expression. So one part of me tells me that it is a sane thing to
> *not* support this case and throw a warning if the user feeds
> is_cont() with a pointer.
>
> If we just what to accept pointer arguments but still return false
> (because those are not integers), one solution is:
>
>   #define is_const(x) __is_const_zero((long)(x) * 0l)
>
> This would be consistent with __is_constexpr(): it does accept NULL
> (i.e. no warnings), but does not recognize it as an integer constant
> expression, e.g.:
>
>   is_const(NULL);
>
> returns false with no warnings.
>
> > Side note: I think "(x) == 0" will make sparse unhappy when 'x' is a
> > pointer, because it results that horrid "use integer zero as NULL
> > without a cast" thing when the plain zero gets implicitly cast to a
> > pointer. Which is a really nasty and broken C pattern and should never
> > have been silent.
> >
> > I think David suggested using ((x)?0:0) at some point. Silly
> > nonsensical and complex expression, but maybe that finally gets rid of
> > all the warnings:
> >
> >      #define is_const(x) __is_const_zero((x)?0:0)
> >
> > might work regardless of the type of 'x'.
> >
> > Or does that trigger some odd case too?
>
> Following a quick test, this seems to work and to return true if given
> NULL as an argument (contrary to the current __is_const_expr()). So if
> we want to go beyond the C standard and extend the meaning of integer
> constant expression in the kernel to also include constant pointers, I
> agree that this is the way to go!

I just came up with a new idea:

  #define is_const(x) __is_const_zero((x) != (x))

Similarly to ((x)?0:0), this seems to work with everything (including
with NULL), but arguably a bit less ugly.

> Side question, Linus, what do you think about the __is_const_zero()
> documentation in
>
>   https://lore.kernel.org/all/20241203-is_constexpr-refactor-v1-2-4e4cbaecc216 at wanadoo.fr/
>
> Do you think I am too verbose as pointed out by David? Some people
> (including me and Yuri) like it that way, but if you also think this
> is too much, I will make it shorter.
>
> Thanks,
>
>
> Yours sincerely,
> Vincent Mailhol


From 0x1207 at gmail.com  Fri Dec  6 21:52:17 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Sat, 7 Dec 2024 13:52:17 +0800
Subject: [PATCH net] net: stmmac: fix TSO DMA API usage causing oops
In-Reply-To: <E1tJXcx-006N4Z-PC@rmk-PC.armlinux.org.uk>
References: <E1tJXcx-006N4Z-PC@rmk-PC.armlinux.org.uk>
Message-ID: <20241207135217.00000f0f@gmail.com>

On Fri, 06 Dec 2024 12:40:11 +0000, "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk> wrote:

> Commit 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap
> for non-paged SKB data") moved the assignment of tx_skbuff_dma[]'s
> members to be later in stmmac_tso_xmit().
> 
> The buf (dma cookie) and len stored in this structure are passed to
> dma_unmap_single() by stmmac_tx_clean(). The DMA API requires that
> the dma cookie passed to dma_unmap_single() is the same as the value
> returned from dma_map_single(). However, by moving the assignment
> later, this is not the case when priv->dma_cap.addr64 > 32 as "des"
> is offset by proto_hdr_len.
> 
> This causes problems such as:
> 
>   dwc-eth-dwmac 2490000.ethernet eth0: Tx DMA map failed
> 
> and with DMA_API_DEBUG enabled:
> 
>   DMA-API: dwc-eth-dwmac 2490000.ethernet: device driver tries to +free DMA memory it has not allocated [device address=0x000000ffffcf65c0] [size=66 bytes]
> 
> Fix this by maintaining "des" as the original DMA cookie, and use
> tso_des to pass the offset DMA cookie to stmmac_tso_allocator().
> 
> Full details of the crashes can be found at:
> https://lore.kernel.org/all/d8112193-0386-4e14-b516-37c2d838171a at nvidia.com/
> https://lore.kernel.org/all/klkzp5yn5kq5efgtrow6wbvnc46bcqfxs65nz3qy77ujr5turc at bwwhelz2l4dw/
> 
> Reported-by: Jon Hunter <jonathanh at nvidia.com>
> Reported-by: Thierry Reding <thierry.reding at gmail.com>
> Fixes: 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data")

Much appreciated for this fix.

Reviewed-by: Furong Xu <0x1207 at gmail.com>



From akpm at linux-foundation.org  Fri Dec  6 22:14:46 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Fri, 6 Dec 2024 22:14:46 -0800
Subject: [PATCH 0/2] Fix subsection vmemmap_populate logic
In-Reply-To: <b2681eed-d4d5-43c9-90e0-3e706db3e201@quicinc.com>
References: <20241121071256.487220-1-quic_zhenhuah@quicinc.com>
	<eb4d6674-494a-4a84-bade-481b0c89eb93@quicinc.com>
	<b2681eed-d4d5-43c9-90e0-3e706db3e201@quicinc.com>
Message-ID: <20241206221446.e5e8ea4ed85d0f2884216b82@linux-foundation.org>

On Fri, 6 Dec 2024 17:13:39 +0800 Zhenhua Huang <quic_zhenhuah at quicinc.com> wrote:

> 
> 
> On 2024/11/28 15:26, Zhenhua Huang wrote:
> > 
> > 
> > On 2024/11/21 15:12, Zhenhua Huang wrote:
> >> To perform memory hotplug operations, the memmap (aka struct page) 
> >> will be
> >> updated. For arm64 with 4K page size, the typical granularity is 128M,
> >> which corresponds to a 2M memmap buffer.
> >> Commit 2045a3b8911b ("mm/sparse-vmemmap: generalise 
> >> vmemmap_populate_hugepages()")
> >> optimizes this 2M buffer to be mapped with PMD huge pages. However,
> >> commit ba72b4c8cf60 ("mm/sparsemem: support sub-section hotplug")
> >> which supports 2M subsection hotplug granularity, causes other issues
> >> (refer to the change log of patch #1). The logic is adjusted to populate
> >> with huge pages only if the hotplug address/size is section-aligned.
> > 
> > Could any expert please help review ?
> 
> Gentle reminder for review..
> 


MM developers work on the linux-mm mailing list, which was not cc'ed.

Please address Catalin's review comment
(https://lkml.kernel.org/r/Z1Mwo5OajFZQYlOg at arm.com) then resend a v2
series with the appropriate cc's.




From 0x1207 at gmail.com  Fri Dec  6 23:02:48 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Sat,  7 Dec 2024 15:02:48 +0800
Subject: [PATCH net-next v1] net: stmmac: Move extern declarations from common.h to hwif.h
Message-ID: <20241207070248.4049877-1-0x1207@gmail.com>

These extern declarations are referenced in hwif.c only.
Move them to hwif.h just like the other extern declarations.

Compile tested only.
No functional change intended.

Signed-off-by: Furong Xu <0x1207 at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h | 14 --------------
 drivers/net/ethernet/stmicro/stmmac/hwif.h   | 14 ++++++++++++++
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1367fa5c9b8e..fbcf07d201cf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -543,18 +543,8 @@ struct dma_features {
 #define STMMAC_VLAN_INSERT	0x2
 #define STMMAC_VLAN_REPLACE	0x3
 
-extern const struct stmmac_desc_ops enh_desc_ops;
-extern const struct stmmac_desc_ops ndesc_ops;
-
 struct mac_device_info;
 
-extern const struct stmmac_hwtimestamp stmmac_ptp;
-extern const struct stmmac_hwtimestamp dwmac1000_ptp;
-extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;
-
-extern const struct ptp_clock_info stmmac_ptp_clock_ops;
-extern const struct ptp_clock_info dwmac1000_ptp_clock_ops;
-
 struct mac_link {
 	u32 caps;
 	u32 speed_mask;
@@ -641,8 +631,4 @@ void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable);
 
 void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
 
-extern const struct stmmac_mode_ops ring_mode_ops;
-extern const struct stmmac_mode_ops chain_mode_ops;
-extern const struct stmmac_desc_ops dwmac4_desc_ops;
-
 #endif /* __COMMON_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 64f8ed67dcc4..58a962e0b768 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -665,6 +665,20 @@ struct stmmac_regs_off {
 	u32 est_off;
 };
 
+extern const struct stmmac_desc_ops ndesc_ops;
+extern const struct stmmac_desc_ops enh_desc_ops;
+extern const struct stmmac_desc_ops dwmac4_desc_ops;
+
+extern const struct stmmac_hwtimestamp stmmac_ptp;
+extern const struct stmmac_hwtimestamp dwmac1000_ptp;
+
+extern const struct ptp_clock_info stmmac_ptp_clock_ops;
+extern const struct ptp_clock_info dwmac1000_ptp_clock_ops;
+
+extern const struct stmmac_mode_ops ring_mode_ops;
+extern const struct stmmac_mode_ops chain_mode_ops;
+extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;
+
 extern const struct stmmac_ops dwmac100_ops;
 extern const struct stmmac_dma_ops dwmac100_dma_ops;
 extern const struct stmmac_ops dwmac1000_ops;
-- 
2.34.1



From wei.liu at kernel.org  Fri Dec  6 23:36:22 2024
From: wei.liu at kernel.org (Wei Liu)
Date: Sat, 7 Dec 2024 07:36:22 +0000
Subject: [PATCH 1/2] hyperv: Move hv_current_partition_id to arch-generic
 code
In-Reply-To: <1733523707-15954-2-git-send-email-nunodasneves@linux.microsoft.com>
References: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
 <1733523707-15954-2-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <Z1P69tl2qMNH-xmg@liuwe-devbox-debian-v2>

On Fri, Dec 06, 2024 at 02:21:46PM -0800, Nuno Das Neves wrote:
> From: Nuno Das Neves <nudasnev at microsoft.com>
> 
> Make hv_current_partition_id available in both x86_64 and arm64.
> This feature isn't specific to x86_64 and will be needed by common
> code.
> 
> While at it, replace the BUG()s with WARN()s. Failing to get the id
> need not crash the machine (although it is a very bad sign).
> 

A lot of things have changed since it was introduced. I don't remember
why I decided to use BUG() instead of WARN() in the first place.

If the system can still function without knowing its partition id, then
can this be removed completely? We can always use the SELF id.

Thanks,
Wei.

> Signed-off-by: Nuno Das Neves <nudasnev at microsoft.com>
> ---
>  arch/arm64/hyperv/mshyperv.c    |  3 +++
>  arch/x86/hyperv/hv_init.c       | 25 +------------------------
>  arch/x86/include/asm/mshyperv.h |  2 --
>  drivers/hv/hv_common.c          | 23 +++++++++++++++++++++++
>  include/asm-generic/mshyperv.h  |  2 ++
>  5 files changed, 29 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index b1a4de4eee29..5050e748d266 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -19,6 +19,9 @@
>  
>  static bool hyperv_initialized;
>  
> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
> +EXPORT_SYMBOL_GPL(hv_current_partition_id);
> +
>  int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
>  {
>  	hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index 95eada2994e1..950f5ccdb9d9 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -35,7 +35,7 @@
>  #include <clocksource/hyperv_timer.h>
>  #include <linux/highmem.h>
>  
> -u64 hv_current_partition_id = ~0ull;
> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
>  EXPORT_SYMBOL_GPL(hv_current_partition_id);
>  
>  void *hv_hypercall_pg;
> @@ -394,24 +394,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
>  		old_setup_percpu_clockev();
>  }
>  
> -static void __init hv_get_partition_id(void)
> -{
> -	struct hv_get_partition_id *output_page;
> -	u64 status;
> -	unsigned long flags;
> -
> -	local_irq_save(flags);
> -	output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
> -	status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
> -	if (!hv_result_success(status)) {
> -		/* No point in proceeding if this failed */
> -		pr_err("Failed to get partition ID: %lld\n", status);
> -		BUG();
> -	}
> -	hv_current_partition_id = output_page->partition_id;
> -	local_irq_restore(flags);
> -}
> -
>  #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
>  static u8 __init get_vtl(void)
>  {
> @@ -606,11 +588,6 @@ void __init hyperv_init(void)
>  
>  	register_syscore_ops(&hv_syscore_ops);
>  
> -	if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
> -		hv_get_partition_id();
> -
> -	BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);
> -
>  #ifdef CONFIG_PCI_MSI
>  	/*
>  	 * If we're running as root, we want to create our own PCI MSI domain.
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index 5f0bc6a6d025..9eeca2a6d047 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -44,8 +44,6 @@ extern bool hyperv_paravisor_present;
>  
>  extern void *hv_hypercall_pg;
>  
> -extern u64 hv_current_partition_id;
> -
>  extern union hv_ghcb * __percpu *hv_ghcb_pg;
>  
>  bool hv_isolation_type_snp(void);
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index 7a35c82976e0..819bcfd2b149 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -278,11 +278,34 @@ static void hv_kmsg_dump_register(void)
>  	}
>  }
>  
> +static void __init hv_get_partition_id(void)
> +{
> +	struct hv_get_partition_id *output_page;
> +	u64 status;
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
> +	output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
> +	status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
> +	if (!hv_result_success(status)) {
> +		local_irq_restore(flags);
> +		WARN(true, "Failed to get partition ID: %lld\n", status);
> +		return;
> +	}
> +	hv_current_partition_id = output_page->partition_id;
> +	local_irq_restore(flags);
> +}
> +
>  int __init hv_common_init(void)
>  {
>  	int i;
>  	union hv_hypervisor_version_info version;
>  
> +	if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
> +		hv_get_partition_id();
> +
> +	WARN_ON(hv_root_partition && hv_current_partition_id == HV_PARTITION_ID_SELF);
> +
>  	/* Get information about the Hyper-V host version */
>  	if (!hv_get_hypervisor_version(&version))
>  		pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> index 8fe7aaab2599..8c4ff6e9aae7 100644
> --- a/include/asm-generic/mshyperv.h
> +++ b/include/asm-generic/mshyperv.h
> @@ -60,6 +60,8 @@ struct ms_hyperv_info {
>  extern struct ms_hyperv_info ms_hyperv;
>  extern bool hv_nested;
>  
> +extern u64 hv_current_partition_id;
> +
>  extern void * __percpu *hyperv_pcpu_input_arg;
>  extern void * __percpu *hyperv_pcpu_output_arg;
>  
> -- 
> 2.34.1
> 


From wei.liu at kernel.org  Fri Dec  6 23:36:40 2024
From: wei.liu at kernel.org (Wei Liu)
Date: Sat, 7 Dec 2024 07:36:40 +0000
Subject: [PATCH 2/2] hyperv: Move create_vp and deposit_pages hvcalls to
 hv_common.c
In-Reply-To: <1733523707-15954-3-git-send-email-nunodasneves@linux.microsoft.com>
References: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
 <1733523707-15954-3-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <Z1P7CJ4Inz97feff@liuwe-devbox-debian-v2>

On Fri, Dec 06, 2024 at 02:21:47PM -0800, Nuno Das Neves wrote:
> From: Nuno Das Neves <nudasnev at microsoft.com>
> 
> These are not specific to x86_64 and will be needed by common code.
> 
> Signed-off-by: Nuno Das Neves <nudasnev at microsoft.com>

Acked-by: Wei Liu <wei.liu at kernel.org>


From vincent.mailhol at gmail.com  Fri Dec  6 23:42:41 2024
From: vincent.mailhol at gmail.com (Vincent Mailhol)
Date: Sat, 7 Dec 2024 16:42:41 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com> <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com> <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
Message-ID: <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>

On Sat. 7 Dec. 2024 at 05:24, David Laight <David.Laight at aculab.com> wrote:
> > > > #define const_NULL(x) _Generic(0 ? (x) : (char *)0, char *: 1, void *: 0)
> > > > #define const_true(x) const_NULL((x) ? NULL : (void *)1L))
> > > > #define const_expr(x) const_NULL((x) ? NULL : NULL))
> > > > I send this morning.
> > > > Needs 's/char/struct kjkjkjkjui/' applied.
> > >
> > > Oh Christ. You really are taking this whole ugly to another level.
> >
> > I sort of liked that version in a perverse sort of way.
> > It does give you a simple test for NULL (unless you've used 'struct kjkjkjkjui').
>
> Except const_NULL() really doesn't work at all - so you are lucky :-)
>
> So maybe the slightly long lines:
> #define const_true(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 1L) : (char *)0, char *: 1, void *: 0)
> #define const_expr(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 0L) : (char *)0, char *: 1, void *: 0)

This still throws a -Wnull-pointer-arithmetic on clang on const_expr(NULL):

  https://godbolt.org/z/vo5W7efdE

I just do not see a method to silence that one. So three options:

  1. is_const() does not accept pointers and throws a constraint
     violation:

       #define is_const(x) __is_const_zero(0 * (x))

     This is my current patch.

  2. is_const() accept pointers but is_const(NULL) returns false:

       #define is_const(x) __is_const_zero((x) != (x))

     This keeps the current __is_constexpr() behaviour.

  3. is_const() accepts pointers and is_const(NULL) return true:

       #define const_expr(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 0L)
: (char *)0, char *: 1, void *: 0)

     David's latest proposal, it requires to remove the
     -Wnull-pointer-arithmetic clang warning.

I vote for 1. or 2. (with a preference for 1.). IMHO, we are just
adding an unreasonable level of complexity for making the macro treat
NULL as an integer. Would someone find a solution for 3. that does not
yield a warning, then why not. But if we have to remove a compiler
check for a theoretical use case that does not even exist in the
kernel, then it is not worth the trade off.

Concerning is_const(var << 2), the patch I submitted works fine as-is
with all scalars including that (var << 2):

  https://godbolt.org/z/xer4aMees

And can we ignore the case (!(var << 2))? This is not a warning
because of the macro, but because of the caller! If I do any of:

          if (!(var << 2)) {}
          (void)__builtin_constant_p(!(var << 2));

I also got the warning. The point is that the macro should not
generate *new* warnings. If the given argument already raises a
warning, it is the caller's responsibility to fix.


Yours sincerely,
Vincent Mailhol


From muecker at gwdg.de  Sat Dec  7 00:39:50 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sat, 7 Dec 2024 09:39:50 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
Message-ID: <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>

Am Freitag, dem 06.12.2024 um 16:26 +0900 schrieb Vincent Mailhol:
> > On Fri. 6 Dec. 2024 at 15:40, Martin Uecker <muecker at gwdg.de> wrote:
> > > > Am Freitag, dem 06.12.2024 um 02:25 +0000 schrieb David Laight:
> > > > > > From: Vincent Mailhol
> > > > > > > > Sent: 05 December 2024 15:31
> > > > > > > > 
> > > > > > > > -CC: Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
> > > > > > > > +CC: Martin Uecker <muecker at gwdg.de>
> > > > > > > > (seems that Martin changed his address)
> > > > 
> > > > My current one is this: uecker at tugraz.at
> > 
> > Ack
> > 
> > (...)
> > 
> > > > > > > > > > > > + *
> > > > > > > > > > > > + * Glory to Martin Uecker <Martin.Uecker at med.uni-goettingen.de>
> > > > > > > > > > 
> > > > > > > > > > IIRC Martin has agreed in the past that the accreditation can
> > > > > > > > > > be removed - especially since it refers to the 'sizeof (void)' trick.
> > > > > > > > 
> > > > > > > > I tried to look for such message:
> > > > > > > > 
> > > > > > > >   https://lore.kernel.org/all/?q=f%3A%22martin+uecker%22+__is_constexpr
> > > > > > > > 
> > > > > > > > but couldn't find it. Do you have the link?
> > > > > > > > 
> > > > > > > > @Martin, do you agree that I remove the accreditation?
> > 
> > So, do you agree to have the accreditation removed in compiler.h?
> > Personally, I do not mind. I am also OK to remove you from the
> > documentation and add you to the CREDITS file if you'd like to.

Sorry, I somehow didn't read this part. Please do whatever you think is
most appropriate (but please update my email to the new above if it
still appears anywhere).


I find it amazing how much time the Linux kernel community spends
revising code to make it work perfectly.

Still, I am wondering whether some of this time and effort should not
be targeted at C compilers and language work to make these macro
hacks unnecessary?

I already found the original motivation for these macros very questionable.
Removing VLAs at the cost having imprecise worst-case bounds strikes
me as fundamentally misguided - at least if security is the motivation.

So maybe there are other good reasons for this, e.g. bad code
for VLAs or risk of jumping the guard page if the attacker can somehow
influence its size (but for this there is -Wvla-larger-than). But even then,
wouldn't it be a more worthwhile and interesting investment of engineering
resources to improving code generation / warnings at the compiler level?

Also the fortification of strlen and co seems something which could be
much better solved with annotations and proper compiler support. 

Martin






From ukleinek at kernel.org  Sat Dec  7 00:46:05 2024
From: ukleinek at kernel.org (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Sat, 7 Dec 2024 09:46:05 +0100
Subject: [PATCH v3] pwm: stm32-lp: Add check for clk_enable()
In-Reply-To: <20241206215318.3402860-1-zmw12306@gmail.com>
References: <20241206215318.3402860-1-zmw12306@gmail.com>
Message-ID: <4wcwxgo5irzfvyec537ucm4e276fqq36hhw3l64qmoj43hjnmv@byi5mvb2wc2b>

Hello,

On Fri, Dec 06, 2024 at 04:53:18PM -0500, Mingwei Zheng wrote:
> Changelog:
> 
> v2 -> v3:
> 
> 1. Add tool name in the commit log.

Thanks.

Applied to

https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/for-next

.

Best regards
Uwe
-------------- 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/20241207/9a65fc1e/attachment.sig>

From zengheng4 at huawei.com  Sat Dec  7 01:21:36 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Sat, 7 Dec 2024 17:21:36 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 5/5] arm_mpam: Adapting the closid/rmid matching determination functions
In-Reply-To: <20241207092136.2488426-1-zengheng4@huawei.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
Message-ID: <20241207092136.2488426-6-zengheng4@huawei.com>

According to the previous patches, add the inverse functions for the
closid/rmid conversion functions to serve as the conversion functions for
reqpartid/pmg. And adapt the matching determination functions
resctrl_arch_match_closid() and resctrl_arch_match_rmid() by the inverse
functions.

For the same reason, when updating the (req)PARTID/PMG pair for a task,
the new conversion functions also are used for adaptation.

Signed-off-by: Zeng Heng <zengheng4 at huawei.com>
---
 arch/arm64/include/asm/mpam.h              |  6 ++-
 drivers/platform/arm64/mpam/mpam_resctrl.c | 63 +++++++++++++++-------
 2 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h
index e5f385767174..9fc095530671 100644
--- a/arch/arm64/include/asm/mpam.h
+++ b/arch/arm64/include/asm/mpam.h
@@ -93,6 +93,8 @@ static inline u64 mpam_get_regval(struct task_struct *tsk)
 #endif
 }
 
+u32 rmid2pmg(u32 rmid);
+
 static inline void resctrl_arch_set_rmid(struct task_struct *tsk, u32 rmid)
 {
 #ifdef CONFIG_ARM64_MPAM
@@ -100,8 +102,8 @@ static inline void resctrl_arch_set_rmid(struct task_struct *tsk, u32 rmid)
 
 	regval &= ~MPAM1_EL1_PMG_D;
 	regval &= ~MPAM1_EL1_PMG_I;
-	regval |= FIELD_PREP(MPAM1_EL1_PMG_D, rmid);
-	regval |= FIELD_PREP(MPAM1_EL1_PMG_I, rmid);
+	regval |= FIELD_PREP(MPAM1_EL1_PMG_D, rmid2pmg(rmid));
+	regval |= FIELD_PREP(MPAM1_EL1_PMG_I, rmid2pmg(rmid));
 
 	WRITE_ONCE(task_thread_info(tsk)->mpam_partid_pmg, regval);
 #endif
diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
index 47e3a51b0942..cb5da3de907a 100644
--- a/drivers/platform/arm64/mpam/mpam_resctrl.c
+++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
@@ -239,7 +239,7 @@ static u32 closid_rmid2reqpartid(u32 closid, u32 rmid)
 	return (req_idx << intpartid_shift) | closid;
 }
 
-static u32 rmid2pmg(u32 rmid)
+u32 rmid2pmg(u32 rmid)
 {
 	u8 pmg_shift = fls(mpam_pmg_max);
 	u32 pmg_mask = ~(~0 << pmg_shift);
@@ -247,6 +247,20 @@ static u32 rmid2pmg(u32 rmid)
 	return rmid & pmg_mask;
 }
 
+static u32 reqpartid2closid(u32 reqpartid)
+{
+	return req2intpartid(reqpartid);
+}
+
+static u32 reqpartid_pmg2rmid(u32 reqpartid, u32 pmg)
+{
+	u8 pmg_shift = fls(mpam_pmg_max);
+	u8 intpartid_shift = fls(mpam_intpartid_max);
+	u32 req_idx = (reqpartid >> intpartid_shift);
+
+	return (req_idx << pmg_shift) | pmg;
+}
+
 void resctrl_arch_sched_in(struct task_struct *tsk)
 {
 	lockdep_assert_preemption_disabled();
@@ -256,20 +270,24 @@ void resctrl_arch_sched_in(struct task_struct *tsk)
 
 void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid, u32 rmid)
 {
-	BUG_ON(closid > U16_MAX);
-	BUG_ON(rmid > U8_MAX);
+	u32 reqpartid = closid_rmid2reqpartid(closid, rmid);
+	u32 pmg = rmid2pmg(rmid);
+	u32 partid_d, partid_i;
+
+	BUG_ON(reqpartid > U16_MAX);
+	BUG_ON(pmg > U8_MAX);
 
 	if (!cdp_enabled) {
-		mpam_set_cpu_defaults(cpu, closid, closid, rmid, rmid);
+		mpam_set_cpu_defaults(cpu, reqpartid, reqpartid, pmg, pmg);
 	} else {
 		/*
 		 * When CDP is enabled, resctrl halves the closid range and we
 		 * use odd/even partid for one closid.
 		 */
-		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
-		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
+		partid_d = resctrl_get_config_index(reqpartid, CDP_DATA);
+		partid_i = resctrl_get_config_index(reqpartid, CDP_CODE);
 
-		mpam_set_cpu_defaults(cpu, partid_d, partid_i, rmid, rmid);
+		mpam_set_cpu_defaults(cpu, partid_d, partid_i, pmg, pmg);
 	}
 }
 
@@ -289,41 +307,46 @@ void resctrl_arch_sync_cpu_closid_rmid(void *info)
 
 void resctrl_arch_set_closid_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
 {
-	BUG_ON(closid > U16_MAX);
-	BUG_ON(rmid > U8_MAX);
+	u32 reqpartid = closid_rmid2reqpartid(closid, rmid);
+	u32 pmg = rmid2pmg(rmid);
+	u32 partid_d, partid_i;
+
+	BUG_ON(reqpartid > U16_MAX);
+	BUG_ON(pmg > U8_MAX);
 
 	if (!cdp_enabled) {
-		mpam_set_task_partid_pmg(tsk, closid, closid, rmid, rmid);
+		mpam_set_task_partid_pmg(tsk, reqpartid, reqpartid, pmg, pmg);
 	} else {
-		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
-		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
+		partid_d = resctrl_get_config_index(reqpartid, CDP_DATA);
+		partid_i = resctrl_get_config_index(reqpartid, CDP_CODE);
 
-		mpam_set_task_partid_pmg(tsk, partid_d, partid_i, rmid, rmid);
+		mpam_set_task_partid_pmg(tsk, partid_d, partid_i, pmg, pmg);
 	}
 }
 
 bool resctrl_arch_match_closid(struct task_struct *tsk, u32 closid)
 {
 	u64 regval = mpam_get_regval(tsk);
-	u32 tsk_closid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
+	u32 tsk_partid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
 
 	if (cdp_enabled)
-		tsk_closid >>= 1;
+		tsk_partid >>= 1;
 
-	return tsk_closid == closid;
+	return reqpartid2closid(tsk_partid) == closid;
 }
 
 /* The task's pmg is not unique, the partid must be considered too */
 bool resctrl_arch_match_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
 {
 	u64 regval = mpam_get_regval(tsk);
-	u32 tsk_closid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
-	u32 tsk_rmid = FIELD_GET(MPAM1_EL1_PMG_D, regval);
+	u32 tsk_pmg = FIELD_GET(MPAM1_EL1_PMG_D, regval);
+	u32 tsk_partid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
 
 	if (cdp_enabled)
-		tsk_closid >>= 1;
+		tsk_partid >>= 1;
 
-	return (tsk_closid == closid) && (tsk_rmid == rmid);
+	return (reqpartid2closid(tsk_partid) == closid) &&
+	       (reqpartid_pmg2rmid(tsk_partid, tsk_pmg) == rmid);
 }
 
 struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
-- 
2.25.1



From zengheng4 at huawei.com  Sat Dec  7 01:21:33 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Sat, 7 Dec 2024 17:21:33 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 2/5] arm_mpam: Read monitor value with new closid/rmid pair
In-Reply-To: <20241207092136.2488426-1-zengheng4@huawei.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
Message-ID: <20241207092136.2488426-3-zengheng4@huawei.com>

The MPAM driver statically assigns all reqPARTIDs to respective intPARTIDs.
For the new rmid allocation strategy, it will check if there is an
available rmid of any reqPARTID which belongs to the input closid, not just
the rmids belonging to the closid.

For a mixture of MSCs system, for MSCs that do not support narrow-partid,
we use the PARTIDs exceeding the number of closids as reqPARTIDs for
expanding the monitoring groups.

In order to keep the existing resctrl API interface, the rmid contains both
req_idx and PMG information instead of PMG only under the MPAM driver. The
req_idx represents the req_idx-th sub-monitoring group under the control
group. The new rmid would be like:

    rmid = (req_idx << shift | pmg).

The mapping relationships between each group's closid/rmid and the
respective MSCs' intPARTID/reqPARTID/PARTID are illustrated:

n - Indicates the total number of intPARTIDs
m - Indicates the number of reqPARTIDs per intPARTID

P - Partition group (control group)
M - Monitoring group

Group closid rmid.req_idx (req)PARTID      MSCs with narrow-partid  MSCs without narrow-partid
P1    0      -            0                   intPARTID_1              PARTID_1
M1_1  0      0            0                       ??? reqPARTID_1_1       ??? PARTID_1_1
M1_2  0      1            0+n                     ??? reqPARTID_1_2       ??? PARTID_1_2
M1_3  0      2            0+n*2                   ??? reqPARTID_1_3       ??? PARTID_1_3
 ...                                              ??? ...                 ??? ...
M1_m  0      (m-1)        0+n*(m-1)               ??? reqPARTID_1_m       ??? PARTID_1_m

P2    1      -            1                   intPARTID_2              PARTID_2
M2_1  1      0            1                       ??? reqPARTID_2_1       ??? PARTID_2_1
M2_2  1      1            1+n                     ??? reqPARTID_2_2       ??? PARTID_2_2
M2_3  1      2            1+n*2                   ??? reqPARTID_2_3       ??? PARTID_2_3
 ...                                              ??? ...                 ??? ...
M2_m  1      (m-1)        1+n*(m-1)               ??? reqPARTID_2_m       ??? PARTID_2_m

Pn    (n-1)  -            (n-1)               intPARTID_n              PARTID_n
Mn_1  (n-1)  0            (n-1)                   ??? reqPARTID_n_1       ??? PARTID_n_1
Mn_2  (n-1)  1            (n-1)+n                 ??? reqPARTID_n_2       ??? PARTID_n_2
Mn_3  (n-1)  2            (n-1)+n*2               ??? reqPARTID_n_3       ??? PARTID_n_3
 ...                                              ??? ...                 ??? ...
Mn_m  (n-1)  (m-1)        (n-1)+n*(m-1) = n*m-1   ??? reqPARTID_n_m       ??? PARTID_n_m

Based on the example provided, the conversion relationship between
closid/rmid and (req)PARTID/PMG is:

    (req)PARTID = (rmid.req_idx * n) + closid,
    PMG = rmid.pmg.

When the resctrl layer uses the new closid/rmid pair to read or reset the
monitoring values, these new conversion functions(closid_rmid2reqpartid()
and rmid2pmg()) would be utilized to gain the new (req)PARTID/PMG pair.

Since the rmid no longer contains only PMG information, it includes both
*req_idx* and *pmg*. Therefore, the conversion between rmid_idx and
closid/rmid needs to be adapted accordingly too.

Each control group has m (req)PARTIDs, which are used to expand the number
of monitoring groups under the control group. Therefore, the number of
monitoring groups is no longer limited by the range of MPAM's PMG, which
enhances the extensibility of the system's monitoring capabilities.

Signed-off-by: Zeng Heng <zengheng4 at huawei.com>
---
 drivers/platform/arm64/mpam/mpam_resctrl.c | 64 ++++++++++++++++++----
 1 file changed, 52 insertions(+), 12 deletions(-)

diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
index ac3d228befcf..965ff9fd45d3 100644
--- a/drivers/platform/arm64/mpam/mpam_resctrl.c
+++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
@@ -171,6 +171,11 @@ static u32 get_num_reqpartid(void)
 	return mpam_partid_max + 1;
 }
 
+static u32 get_num_reqpartid_per_closid(void)
+{
+	return get_num_reqpartid() / resctrl_arch_get_num_closid(NULL);
+}
+
 u32 resctrl_arch_system_num_rmid_idx(void)
 {
 	u8 closid_shift = fls(mpam_pmg_max);
@@ -179,24 +184,59 @@ u32 resctrl_arch_system_num_rmid_idx(void)
 	return num_reqpartid << closid_shift;
 }
 
+/*
+ * Under MPAM driver, the rmid contains two pieces of information: one is
+ * req_idx, and the other is pmg. Therefore,
+ *     closid_shift = req_shift + pmg_shift.
+ */
 u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
 {
-	u8 closid_shift = fls(mpam_pmg_max);
+	u32 rmid_mask;
+	u8 closid_shift;
+	u8 pmg_shift = fls(mpam_pmg_max);
+	u8 req_shift = fls(get_num_reqpartid_per_closid() - 1);
+
+	closid_shift = req_shift + pmg_shift;
+	rmid_mask = ~(~0 << closid_shift);
 
 	BUG_ON(closid_shift > 8);
 
-	return (closid << closid_shift) | rmid;
+	return (closid << closid_shift) | (rmid & rmid_mask);
 }
 
 void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
 {
-	u8 closid_shift = fls(mpam_pmg_max);
-	u32 pmg_mask = ~(~0 << closid_shift);
+	u32 rmid_mask;
+	u8 closid_shift;
+	u8 pmg_shift = fls(mpam_pmg_max);
+	u8 req_shift = fls(get_num_reqpartid_per_closid() - 1);
+
+	closid_shift = req_shift + pmg_shift;
+	rmid_mask = ~(~0 << closid_shift);
 
 	BUG_ON(closid_shift > 8);
 
-	*closid = idx >> closid_shift;
-	*rmid = idx & pmg_mask;
+	if (closid)
+		*closid = idx >> closid_shift;
+	if (rmid)
+		*rmid = idx & rmid_mask;
+}
+
+static u32 closid_rmid2reqpartid(u32 closid, u32 rmid)
+{
+	u8 pmg_shift = fls(mpam_pmg_max);
+	u32 req_idx = (rmid >> pmg_shift);
+	u8 intpartid_shift = fls(mpam_intpartid_max);
+
+	return (req_idx << intpartid_shift) | closid;
+}
+
+static u32 rmid2pmg(u32 rmid)
+{
+	u8 pmg_shift = fls(mpam_pmg_max);
+	u32 pmg_mask = ~(~0 << pmg_shift);
+
+	return rmid & pmg_mask;
 }
 
 void resctrl_arch_sched_in(struct task_struct *tsk)
@@ -397,7 +437,7 @@ int resctrl_arch_rmid_read(struct rdt_resource	*r, struct rdt_mon_domain *d,
 		cfg.mon = resctrl_arch_rmid_idx_encode(closid, rmid);
 
 	cfg.match_pmg = true;
-	cfg.pmg = rmid;
+	cfg.pmg = rmid2pmg(rmid);
 	cfg.opts = resctrl_evt_config_to_mpam(dom->mbm_local_evt_cfg);
 
 	if (irqs_disabled()) {
@@ -405,7 +445,7 @@ int resctrl_arch_rmid_read(struct rdt_resource	*r, struct rdt_mon_domain *d,
 		err = -EIO;
 	} else {
 		if (cdp_enabled) {
-			cfg.partid = closid << 1;
+			cfg.partid = closid_rmid2reqpartid(closid, rmid) << 1;
 			err = mpam_msmon_read(dom->comp, &cfg, type, val);
 			if (err)
 				return err;
@@ -415,7 +455,7 @@ int resctrl_arch_rmid_read(struct rdt_resource	*r, struct rdt_mon_domain *d,
 			if (!err)
 				*val += cdp_val;
 		} else {
-			cfg.partid = closid;
+			cfg.partid = closid_rmid2reqpartid(closid, rmid);
 			err = mpam_msmon_read(dom->comp, &cfg, type, val);
 		}
 	}
@@ -434,18 +474,18 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_mon_domain *d,
 
 	cfg.mon = resctrl_arch_rmid_idx_encode(closid, rmid);
 	cfg.match_pmg = true;
-	cfg.pmg = rmid;
+	cfg.pmg = rmid2pmg(rmid);
 
 	dom = container_of(d, struct mpam_resctrl_dom, resctrl_mon_dom);
 
 	if (cdp_enabled) {
-		cfg.partid = closid << 1;
+		cfg.partid = closid_rmid2reqpartid(closid, rmid) << 1;
 		mpam_msmon_reset_mbwu(dom->comp, &cfg);
 
 		cfg.partid += 1;
 		mpam_msmon_reset_mbwu(dom->comp, &cfg);
 	} else {
-		cfg.partid = closid;
+		cfg.partid = closid_rmid2reqpartid(closid, rmid);
 		mpam_msmon_reset_mbwu(dom->comp, &cfg);
 	}
 }
-- 
2.25.1



From zengheng4 at huawei.com  Sat Dec  7 01:21:34 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Sat, 7 Dec 2024 17:21:34 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 3/5] arm_mpam: Set INTERNAL as needed when setting MSC controls
In-Reply-To: <20241207092136.2488426-1-zengheng4@huawei.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
Message-ID: <20241207092136.2488426-4-zengheng4@huawei.com>

From: Dave Martin <Dave.Martin at arm.com>

Currently, when an MSC implements PARTID narrowing, MPAMCFG_PART_SEL is
left set to the reqPARTID while programming resource controls in
an MSC.

The MPAM architecture does not guarantee that any particular resource
controls will be updated correctly in this scenario.  Instead,
MPAMCFG_PART_SEL must be written with the corresponding intPARTID and
with the INTERNAL bit set before attempting to program resource controls.
Only the PARTID->intPARTID mappings can be written without the INTERNAL
bit set in MPAMCFG_PART_SEL.

Fix it, by rewriting MPAMCFG_PART_SEL appropriately after setting the
intPARTID mapping.

The MPAMCFG_INTPARTID_INTERNAL flag is not currently accepted as
input to the __mpam_part_sel() helper.  In the interest of keeping
the code clean, break this helper up.

Signed-off-by: Dave Martin <Dave.Martin at arm.com>
Signed-off-by: James Morse <james.morse at arm.com>
---
 drivers/platform/arm64/mpam/mpam_devices.c | 26 +++++++++++++++++-----
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/platform/arm64/mpam/mpam_devices.c b/drivers/platform/arm64/mpam/mpam_devices.c
index ca621bb132e9..781c9146718d 100644
--- a/drivers/platform/arm64/mpam/mpam_devices.c
+++ b/drivers/platform/arm64/mpam/mpam_devices.c
@@ -205,15 +205,27 @@ static u64 mpam_msc_read_esr(struct mpam_msc *msc)
 	return (esr_high << 32) | esr_low;
 }
 
+static void __mpam_part_sel_raw(u32 partsel, struct mpam_msc *msc)
+{
+	lockdep_assert_held(&msc->part_sel_lock);
+	mpam_write_partsel_reg(msc, PART_SEL, partsel);
+}
+
 static void __mpam_part_sel(u8 ris_idx, u16 partid, struct mpam_msc *msc)
 {
-	u32 partsel;
+	u32 partsel = FIELD_PREP(MPAMCFG_PART_SEL_RIS, ris_idx) |
+		      FIELD_PREP(MPAMCFG_PART_SEL_PARTID_SEL, partid);
 
-	lockdep_assert_held(&msc->part_sel_lock);
+	__mpam_part_sel_raw(partsel, msc);
+}
 
-	partsel = FIELD_PREP(MPAMCFG_PART_SEL_RIS, ris_idx) |
-		  FIELD_PREP(MPAMCFG_PART_SEL_PARTID_SEL, partid);
-	mpam_write_partsel_reg(msc, PART_SEL, partsel);
+static void __mpam_intpart_sel(u8 ris_idx, u16 intpartid, struct mpam_msc *msc)
+{
+	u32 partsel = FIELD_PREP(MPAMCFG_PART_SEL_RIS, ris_idx) |
+		      FIELD_PREP(MPAMCFG_PART_SEL_PARTID_SEL, intpartid) |
+		      MPAMCFG_PART_SEL_INTERNAL;
+
+	__mpam_part_sel_raw(partsel, msc);
 }
 
 int mpam_register_requestor(u16 partid_max, u8 pmg_max)
@@ -1540,9 +1552,11 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
 	mutex_lock(&msc->part_sel_lock);
 	__mpam_part_sel(ris->ris_idx, partid, msc);
 
-	if (mpam_has_feature(mpam_feat_partid_nrw, rprops))
+	if (mpam_has_feature(mpam_feat_partid_nrw, rprops)) {
 		mpam_write_partsel_reg(msc, INTPARTID,
 				       MPAMCFG_INTPARTID_INTERNAL | partid);
+		__mpam_intpart_sel(ris->ris_idx, partid, msc);
+	}
 
 	if (mpam_has_feature(mpam_feat_cpor_part, rprops)) {
 		if (mpam_has_feature(mpam_feat_cpor_part, cfg))
-- 
2.25.1



From zengheng4 at huawei.com  Sat Dec  7 01:21:35 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Sat, 7 Dec 2024 17:21:35 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 4/5] arm_mpam: Automatically synchronize the configuration of all sub-monitoring groups
In-Reply-To: <20241207092136.2488426-1-zengheng4@huawei.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
Message-ID: <20241207092136.2488426-5-zengheng4@huawei.com>

After the system expands the narrow-partid feature and statically assigns
all (req)PARTIDs to each control group, the following scenarios require
configuration synchronization operations:

  1. MSCs that support narrow-partid need to establish a mapping between
     reqPARTID and intPARTID after creating a new monitoring group.
  2. MSCs that do not support narrow-partid need to synchronize the
     configuration of sub-monitoring groups after users update the control
     group configuration.

In __write_config(), we synchronize a control group's configuration to each
sub-monitoring group.

Signed-off-by: Zeng Heng <zengheng4 at huawei.com>
---
 drivers/platform/arm64/mpam/mpam_devices.c  | 25 ++++++++++++++++++---
 drivers/platform/arm64/mpam/mpam_internal.h |  3 +++
 drivers/platform/arm64/mpam/mpam_resctrl.c  | 10 ++++++++-
 3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/platform/arm64/mpam/mpam_devices.c b/drivers/platform/arm64/mpam/mpam_devices.c
index 781c9146718d..91c5849f76e3 100644
--- a/drivers/platform/arm64/mpam/mpam_devices.c
+++ b/drivers/platform/arm64/mpam/mpam_devices.c
@@ -1544,6 +1544,7 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
 	u32 pri_val = 0;
 	u16 cmax = MPAMCFG_CMAX_CMAX;
 	u16 bwa_fract = MPAMCFG_MBW_MAX_MAX;
+	u16 intpartid = req2intpartid(partid);
 	struct mpam_msc *msc = ris->vmsc->msc;
 	struct mpam_props *rprops = &ris->props;
 	u16 dspri = GENMASK(rprops->dspri_wd, 0);
@@ -1554,8 +1555,14 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
 
 	if (mpam_has_feature(mpam_feat_partid_nrw, rprops)) {
 		mpam_write_partsel_reg(msc, INTPARTID,
-				       MPAMCFG_INTPARTID_INTERNAL | partid);
-		__mpam_intpart_sel(ris->ris_idx, partid, msc);
+				       MPAMCFG_INTPARTID_INTERNAL |
+				       intpartid);
+
+		/* Already finish mapping reqPARTID to intPARTID */
+		if (partid != intpartid)
+			goto out;
+
+		__mpam_intpart_sel(ris->ris_idx, intpartid, msc);
 	}
 
 	if (mpam_has_feature(mpam_feat_cpor_part, rprops)) {
@@ -1615,6 +1622,7 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
 
 	mpam_quirk_post_config_change(ris, partid, cfg);
 
+out:
 	mutex_unlock(&msc->part_sel_lock);
 }
 
@@ -3072,9 +3080,20 @@ struct mpam_write_config_arg {
 
 static int __write_config(void *arg)
 {
+	int closid_num = resctrl_arch_get_num_closid(NULL);
 	struct mpam_write_config_arg *c = arg;
+	u32 reqpartid, req_idx;
+
+	WARN_ON(c->partid >= closid_num);
 
-	mpam_reprogram_ris_partid(c->ris, c->partid, &c->comp->cfg[c->partid]);
+	/* Synchronize the configuration to each sub-monitoring group. */
+	for (req_idx = 0; req_idx < get_num_reqpartid_per_closid();
+	     req_idx++) {
+		reqpartid = req_idx * closid_num + c->partid;
+
+		mpam_reprogram_ris_partid(c->ris, reqpartid,
+					 &c->comp->cfg[c->partid]);
+	}
 
 	return 0;
 }
diff --git a/drivers/platform/arm64/mpam/mpam_internal.h b/drivers/platform/arm64/mpam/mpam_internal.h
index 5fc9f09b6945..c02365338b21 100644
--- a/drivers/platform/arm64/mpam/mpam_internal.h
+++ b/drivers/platform/arm64/mpam/mpam_internal.h
@@ -773,4 +773,7 @@ static inline void mpam_resctrl_teardown_class(struct mpam_class *class) { }
  */
 #define MSMON_CAPT_EVNT_NOW    BIT(0)
 
+u32 get_num_reqpartid_per_closid(void);
+u32 req2intpartid(u32 reqpartid);
+
 #endif /* MPAM_INTERNAL_H */
diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
index 965ff9fd45d3..47e3a51b0942 100644
--- a/drivers/platform/arm64/mpam/mpam_resctrl.c
+++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
@@ -171,11 +171,19 @@ static u32 get_num_reqpartid(void)
 	return mpam_partid_max + 1;
 }
 
-static u32 get_num_reqpartid_per_closid(void)
+u32 get_num_reqpartid_per_closid(void)
 {
 	return get_num_reqpartid() / resctrl_arch_get_num_closid(NULL);
 }
 
+u32 req2intpartid(u32 reqpartid)
+{
+	u8 intpartid_shift = fls(mpam_intpartid_max);
+	u32 intpartid_mask = ~(~0 << intpartid_shift);
+
+	return reqpartid & intpartid_mask;
+}
+
 u32 resctrl_arch_system_num_rmid_idx(void)
 {
 	u8 closid_shift = fls(mpam_pmg_max);
-- 
2.25.1



From zengheng4 at huawei.com  Sat Dec  7 01:21:32 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Sat, 7 Dec 2024 17:21:32 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 1/5] arm_mpam: Introduce the definitions of intPARTID and reqPARTID
In-Reply-To: <20241207092136.2488426-1-zengheng4@huawei.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
Message-ID: <20241207092136.2488426-2-zengheng4@huawei.com>

The narrow-partid feature in MPAM allows for a more efficient use of
PARTIDs by enabling a many-to-one mapping of reqpartids (requested PARTIDs)
to intpartids (internal PARTIDs). This mapping reduces the number of unique
PARTIDs needed, thus allowing more tasks or processes to be monitored and
managed with the available resources.

Regarding intPARTID, MPAM uses it as the unit for control group
configuration delivery. MPAM will synchronize the delivered configuration
to all reqPARTIDs mapped to the same intPARTIDs. The number of intPARTIDs
is indicated by MPAMF_PARTID_NRW_IDR.INTPARTID_MAX if implemented, or
directly use the number of PARTID as intpartid_max if narrow-partid feature
is not supported.

reqPARTIDs can be used to expand the number of monitors, for each control
group is no longer simply restricted by the range of PMG. By mapping
between intPARTID and reqPARTID, the number of monitors would be greatly
expanded and more fine-grained monitoring under a control group will be
achieved.

As a MPAM driver applicable to general scenarios, it needs to be compatible
with systems not supporting narrow-partid and mixed MSCs (some MSCs support
narrow-partid and some do not) systems.

We determine the number of closids in the following manner:

  reqPARTID-np -- The number of reqPARTIDs supported by MSCs that support
                  narrow-partid.
  intPARTID-np -- The number of intPARTIDs supported by MSCs that support
                  narrow partid.
  PARTID-nnp   -- The number of PARTIDs supported by MSCs that do not
                  support narrow partid.

  n - Indicates the maximum number of control groups
  l - Represents the total number of reqpartids
  m - Indicates the number of reqpartids per control group

  n = min(intPARTID-np, PARTID-nnp)
  l = min(reqPARTID-np, PARTID-nnp)
  m = l // n

To illustrate how to determine n, l, and m through examples, we can assume
a specific example:

l3   - Supports the narrow-partid feature, supports 32 intPARTIDs, and
       supports 256 reqPARTIDs.
mata - Does not support the narrow PARTID feature, supports a range of 256
       PARTIDs.

Then,
n = min(intPARTID-l3, PARTID-mata) = min(32, 256) = 32
l = min(reqPARTID-l3, PARTID-mata) = min(256,256) = 256
m = 256 / 32 = 8

After initialization, the driver determines the 'n' parameter returned by
resctrl_arch_get_num_closid() and the 'l' parameter returned by
get_num_reqpartid().

Signed-off-by: Zeng Heng <zengheng4 at huawei.com>
---
 drivers/platform/arm64/mpam/mpam_devices.c  | 12 +++++++++++-
 drivers/platform/arm64/mpam/mpam_internal.h |  2 ++
 drivers/platform/arm64/mpam/mpam_resctrl.c  |  9 +++++++--
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/arm64/mpam/mpam_devices.c b/drivers/platform/arm64/mpam/mpam_devices.c
index 9463045c0011..ca621bb132e9 100644
--- a/drivers/platform/arm64/mpam/mpam_devices.c
+++ b/drivers/platform/arm64/mpam/mpam_devices.c
@@ -67,6 +67,7 @@ static DEFINE_MUTEX(mpam_cpuhp_state_lock);
  * Generating traffic outside this range will result in screaming interrupts.
  */
 u16 mpam_partid_max;
+u16 mpam_intpartid_max;
 u8 mpam_pmg_max;
 static bool partid_max_init, partid_max_published;
 static DEFINE_SPINLOCK(partid_max_lock);
@@ -222,10 +223,16 @@ int mpam_register_requestor(u16 partid_max, u8 pmg_max)
 	spin_lock(&partid_max_lock);
 	if (!partid_max_init) {
 		mpam_partid_max = partid_max;
+		/*
+		 * Update mpam_intpartid_max here, in case the
+		 * system doesn't have narrow-partid feature.
+		 */
+		mpam_intpartid_max = partid_max;
 		mpam_pmg_max = pmg_max;
 		partid_max_init = true;
 	} else if (!partid_max_published) {
 		mpam_partid_max = min(mpam_partid_max, partid_max);
+		mpam_intpartid_max = min(mpam_intpartid_max, partid_max);
 		mpam_pmg_max = min(mpam_pmg_max, pmg_max);
 	} else {
 		/* New requestors can't lower the values */
@@ -984,7 +991,9 @@ static void mpam_ris_hw_probe(struct mpam_msc_ris *ris)
 		u16 partid_max = FIELD_GET(MPAMF_PARTID_NRW_IDR_INTPARTID_MAX, nrwidr);
 
 		mpam_set_feature(mpam_feat_partid_nrw, props);
-		msc->partid_max = min(msc->partid_max, partid_max);
+		msc->intpartid_max = min(msc->partid_max, partid_max);
+	} else {
+		msc->intpartid_max = msc->partid_max;
 	}
 
 	mpam_mon_sel_outer_unlock(msc);
@@ -1046,6 +1055,7 @@ static int mpam_msc_hw_probe(struct mpam_msc *msc)
 
 	spin_lock(&partid_max_lock);
 	mpam_partid_max = min(mpam_partid_max, msc->partid_max);
+	mpam_intpartid_max = min(mpam_intpartid_max, msc->intpartid_max);
 	mpam_pmg_max = min(mpam_pmg_max, msc->pmg_max);
 	spin_unlock(&partid_max_lock);
 
diff --git a/drivers/platform/arm64/mpam/mpam_internal.h b/drivers/platform/arm64/mpam/mpam_internal.h
index 5af6ed60272e..5fc9f09b6945 100644
--- a/drivers/platform/arm64/mpam/mpam_internal.h
+++ b/drivers/platform/arm64/mpam/mpam_internal.h
@@ -86,6 +86,7 @@ struct mpam_msc
 	bool			error_irq_requested;
 	bool			error_irq_hw_enabled;
 	u16			partid_max;
+	u16			intpartid_max;
 	u8			pmg_max;
 	unsigned long		ris_idxs[128 / BITS_PER_LONG];
 	u32			ris_max;
@@ -466,6 +467,7 @@ static inline void mpam_assert_srcu_read_lock_held(void)
 
 /* System wide partid/pmg values */
 extern u16 mpam_partid_max;
+extern u16 mpam_intpartid_max;
 extern u8 mpam_pmg_max;
 
 /* Scheduled work callback to enable mpam once all MSC have been probed */
diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
index 76ddbce0ea9c..ac3d228befcf 100644
--- a/drivers/platform/arm64/mpam/mpam_resctrl.c
+++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
@@ -162,6 +162,11 @@ static bool mpam_resctrl_hide_cdp(enum resctrl_res_level rid)
  * only the system wide safe value is safe to use.
  */
 u32 resctrl_arch_get_num_closid(struct rdt_resource *ignored)
+{
+	return mpam_intpartid_max + 1;
+}
+
+static u32 get_num_reqpartid(void)
 {
 	return mpam_partid_max + 1;
 }
@@ -169,9 +174,9 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *ignored)
 u32 resctrl_arch_system_num_rmid_idx(void)
 {
 	u8 closid_shift = fls(mpam_pmg_max);
-	u32 num_partid = resctrl_arch_get_num_closid(NULL);
+	u32 num_reqpartid = get_num_reqpartid();
 
-	return num_partid << closid_shift;
+	return num_reqpartid << closid_shift;
 }
 
 u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
-- 
2.25.1



From zengheng4 at huawei.com  Sat Dec  7 01:21:31 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Sat, 7 Dec 2024 17:21:31 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 0/5] arm_mpam: Introduce the Narrow-PARTID feature for MPAM driver
Message-ID: <20241207092136.2488426-1-zengheng4@huawei.com>

The patch set is applied for mpam/snapshot/v6.12-rc1 branch of
https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git
repository.

The narrow-partid feature in MPAM allows for a more efficient use of
PARTIDs by enabling a many-to-one mapping of reqpartids (requested PARTIDs)
to intpartids (internal PARTIDs). This mapping reduces the number of unique
PARTIDs needed, thus allowing more tasks or processes to be monitored and
managed with the available resources.

For a mixture of MSCs system, for MSCs that do not support narrow-partid,
we use the PARTIDs exceeding the number of closids as reqPARTIDs for
expanding the monitoring groups.

In order to keep the existing resctrl API interface, the rmid contains both
req_idx and PMG information instead of PMG only under the MPAM driver. The
req_idx represents the req_idx-th sub-monitoring group under the control
group. The new rmid would be like:

    rmid = (req_idx << shift | pmg).

The new conversion relationship between closid/rmid and (req)PARTID/PMG is:

    (req)PARTID = (rmid.req_idx * n) + closid,
    PMG = rmid.pmg.

Each intPARTID has m reqPARTIDs, which are used to expand the number of
monitoring groups under the control group. Therefore, the number of
monitoring groups is no longer limited by the range of MPAM PMG, which
enhances the extensibility of the system's monitoring capabilities.

---
Compared with v1:
  - Rebase this patch set on latest MPAM driver of the v6.12-rc1 branch.

Compared with v2:
  - Refactor closid/rmid pair translation
  - Simplify the logic of synchronize configuration
  - Remove reqPARTID pool
---

Dave Martin (1):
  arm_mpam: Set INTERNAL as needed when setting MSC controls

Zeng Heng (4):
  arm_mpam: Introduce the definitions of intPARTID and reqPARTID
  arm_mpam: Read monitor value with new closid/rmid pair
  arm_mpam: Automatically synchronize the configuration of all
    sub-monitoring groups
  arm_mpam: Adapting the closid/rmid matching determination functions

 arch/arm64/include/asm/mpam.h               |   6 +-
 drivers/platform/arm64/mpam/mpam_devices.c  |  61 +++++++--
 drivers/platform/arm64/mpam/mpam_internal.h |   5 +
 drivers/platform/arm64/mpam/mpam_resctrl.c  | 142 +++++++++++++++-----
 4 files changed, 170 insertions(+), 44 deletions(-)

--
2.25.1



From igor.belwon at mentallysanemainliners.org  Sat Dec  7 01:25:39 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Sat, 07 Dec 2024 10:25:39 +0100
Subject: [PATCH v3 2/3] clk: samsung: clk-pll: Add support for pll_{0717x,
 0718x, 0732x}
In-Reply-To: <20241207-exynos990-cmu-v3-0-20c0f6ea02f0@mentallysanemainliners.org>
References: <20241207-exynos990-cmu-v3-0-20c0f6ea02f0@mentallysanemainliners.org>
Message-ID: <20241207-exynos990-cmu-v3-2-20c0f6ea02f0@mentallysanemainliners.org>

These PLLs are found in the Exynos990 SoC. The PLLs are similar
to pll0822x.

pll0717x and pll0718x are an exception, and they use the mdiv
mask from 1718X (that is, one bit smaller).

Apart from that, the masks/shifts are identical to those of 0822x.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 drivers/clk/samsung/clk-pll.c | 14 ++++++++++++--
 drivers/clk/samsung/clk-pll.h |  3 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index be6b516949193f103696c814b5cffad5d4ea9a66..2e94bba6c3966b9470f0ef42ad101ee3da0519b9 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -430,7 +430,10 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {
 #define PLL0822X_LOCK_STAT_SHIFT	(29)
 #define PLL0822X_ENABLE_SHIFT		(31)
 
-/* PLL1418x is similar to PLL0822x, except that MDIV is one bit smaller */
+/*
+ * PLL1418x, PLL0717x and PLL0718x are similar
+ * to PLL0822x, except that MDIV is one bit smaller
+ */
 #define PLL1418X_MDIV_MASK		(0x1FF)
 
 static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
@@ -441,10 +444,14 @@ static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
 	u64 fvco = parent_rate;
 
 	pll_con3 = readl_relaxed(pll->con_reg);
-	if (pll->type != pll_1418x)
+
+	if (pll->type != pll_1418x &&
+	    pll->type != pll_0717x &&
+	    pll->type != pll_0718x)
 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
 	else
 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL1418X_MDIV_MASK;
+
 	pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
 	sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
 
@@ -1377,6 +1384,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_0516x:
 	case pll_0517x:
 	case pll_0518x:
+	case pll_0717x:
+	case pll_0718x:
+	case pll_0732x:
 		pll->enable_offs = PLL0822X_ENABLE_SHIFT;
 		pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
 		if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 858ab367eb6552bf880ef9d14cd89713b08960a4..6ddc54d173a01e201d93f1ed1679ca6a6ebfa939 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -45,6 +45,9 @@ enum samsung_pll_type {
 	pll_531x,
 	pll_1051x,
 	pll_1052x,
+	pll_0717x,
+	pll_0718x,
+	pll_0732x,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Sat Dec  7 01:25:37 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Sat, 07 Dec 2024 10:25:37 +0100
Subject: [PATCH v3 0/3] clk: samsung: Introduce Exynos990 clock support
Message-ID: <20241207-exynos990-cmu-v3-0-20c0f6ea02f0@mentallysanemainliners.org>

Hi all,

This patchset adds support for the Clock Management Unit found in the
Exynos990 SoC. This CMU allows for clocking peripherals such as USB, UFS,
MCT, et cetera.

Currently there are two blocks implemented, CMU_TOP which
generates clocks for other blocks, and CMU_HSI0, which generates clocks
for USB. More blocks will be added (hopefully soon), like HSI1 for UFS.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
Changes in v3:
- Reordered "required:" item in bindings (Ivaylo, thank you!)
- Changed clock-names for the HSI0 block to conform with other Exynos
  platforms clock drivers. (Ivaylo, thank you!)

- Link to v2: https://lore.kernel.org/r/20241206-exynos990-cmu-v2-0-4666ff0a099b at mentallysanemainliners.org

---
Igor Belwon (3):
      dt-bindings: clock: Add Exynos990 SoC CMU bindings
      clk: samsung: clk-pll: Add support for pll_{0717x, 0718x, 0732x}
      clk: samsung: Introduce Exynos990 clock controller driver

 .../bindings/clock/samsung,exynos990-clock.yaml    |  120 ++
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-exynos990.c                | 1343 ++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c                      |   14 +-
 drivers/clk/samsung/clk-pll.h                      |    3 +
 include/dt-bindings/clock/samsung,exynos990.h      |  236 ++++
 6 files changed, 1715 insertions(+), 2 deletions(-)
---
base-commit: ebe1b11614e079c5e366ce9bd3c8f44ca0fbcc1b
change-id: 20241206-exynos990-cmu-58ada5056ad5

Best regards,
-- 
Igor Belwon <igor.belwon at mentallysanemainliners.org>



From igor.belwon at mentallysanemainliners.org  Sat Dec  7 01:25:38 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Sat, 07 Dec 2024 10:25:38 +0100
Subject: [PATCH v3 1/3] dt-bindings: clock: Add Exynos990 SoC CMU bindings
In-Reply-To: <20241207-exynos990-cmu-v3-0-20c0f6ea02f0@mentallysanemainliners.org>
References: <20241207-exynos990-cmu-v3-0-20c0f6ea02f0@mentallysanemainliners.org>
Message-ID: <20241207-exynos990-cmu-v3-1-20c0f6ea02f0@mentallysanemainliners.org>

Add dt-schema documentation for the Exynos990 SoC CMU.

This clock management unit has a topmost block (CMU_TOP)
that generates top clocks for other blocks. Currently the
only other block implemented is CMU_HSI0, which provides
clocks for the USB part of the SoC.

Also, device-tree binding definitions added for these blocks:
- CMU_TOP
- CMU_HSI0

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 .../bindings/clock/samsung,exynos990-clock.yaml    | 120 +++++++++++
 include/dt-bindings/clock/samsung,exynos990.h      | 236 +++++++++++++++++++++
 2 files changed, 356 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c91a1631b1fc8cfaade46b0509852e0cbcf111f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos990-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos990 SoC clock controller
+
+maintainers:
+  - Igor Belwon <igor.belwon at mentallysanemainliners.org>
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzk at kernel.org>
+
+description: |
+  Exynos990 clock controller is comprised of several CMU units, generating
+  clocks for different domains. Those CMU units are modeled as separate device
+  tree nodes, and might depend on each other. The root clock in that root tree
+  is an external clock: OSCCLK (26 MHz). This external clock must be defined
+  as a fixed-rate clock in dts.
+
+  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
+  dividers; all other clocks of function blocks (other CMUs) are usually
+  derived from CMU_TOP.
+
+  Each clock is assigned an identifier and client nodes can use this identifier
+  to specify the clock which they consume. All clocks available for usage
+  in clock consumer nodes are defined as preprocessor macros in
+  'include/dt-bindings/clock/samsung,exynos990.h' header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos990-cmu-hsi0
+      - samsung,exynos990-cmu-top
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos990-cmu-hsi0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_HSI0 BUS clock (from CMU_TOP)
+            - description: CMU_HSI0 USB31DRD clock (from CMU_TOP)
+            - description: CMU_HSI0 USBDP_DEBUG clock (from CMU_TOP)
+            - description: CMU_HSI0 DPGTC clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: bus
+            - const: usb31drd
+            - const: usbdp_debug
+            - const: dpgtc
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos990-cmu-top
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+
+        clock-names:
+          items:
+            - const: oscclk
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/samsung,exynos990.h>
+
+    cmu_hsi0: clock-controller at 10a00000 {
+        compatible = "samsung,exynos990-cmu-hsi0";
+        reg = <0x10a00000 0x8000>;
+        #clock-cells = <1>;
+
+        clocks = <&oscclk>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
+        clock-names = "oscclk", "bus",
+                                "usb31drd",
+                                "usbdp_debug",
+                                "dpgtc";
+    };
+
+...
diff --git a/include/dt-bindings/clock/samsung,exynos990.h b/include/dt-bindings/clock/samsung,exynos990.h
new file mode 100644
index 0000000000000000000000000000000000000000..307215a3f3eddd579e6733b51a777fb45398bb92
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,exynos990.h
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2024 Igor Belwon <igor.belwon at mentallysanemainliners.org>
+ *
+ * Device Tree binding constants for Exynos990 clock controller.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_EXYNOS_990_H
+#define _DT_BINDINGS_CLOCK_EXYNOS_990_H
+
+/* CMU_TOP */
+#define CLK_FOUT_SHARED0_PLL		1
+#define CLK_FOUT_SHARED1_PLL		2
+#define CLK_FOUT_SHARED2_PLL		3
+#define CLK_FOUT_SHARED3_PLL		4
+#define CLK_FOUT_SHARED4_PLL		5
+#define CLK_FOUT_G3D_PLL		6
+#define CLK_FOUT_MMC_PLL		7
+#define CLK_MOUT_PLL_SHARED0		8
+#define CLK_MOUT_PLL_SHARED1		9
+#define CLK_MOUT_PLL_SHARED2		10
+#define CLK_MOUT_PLL_SHARED3		11
+#define CLK_MOUT_PLL_SHARED4		12
+#define CLK_MOUT_PLL_MMC		13
+#define CLK_MOUT_PLL_G3D		14
+#define CLK_MOUT_CMU_APM_BUS		15
+#define CLK_MOUT_CMU_AUD_CPU		16
+#define CLK_MOUT_CMU_BUS0_BUS		17
+#define CLK_MOUT_CMU_BUS1_BUS		18
+#define CLK_MOUT_CMU_BUS1_SSS		19
+#define CLK_MOUT_CMU_CIS_CLK0		20
+#define CLK_MOUT_CMU_CIS_CLK1		21
+#define CLK_MOUT_CMU_CIS_CLK2		22
+#define CLK_MOUT_CMU_CIS_CLK3		23
+#define CLK_MOUT_CMU_CIS_CLK4		24
+#define CLK_MOUT_CMU_CIS_CLK5		25
+#define CLK_MOUT_CMU_CMU_BOOST		26
+#define CLK_MOUT_CMU_CORE_BUS		27
+#define CLK_MOUT_CMU_CPUCL0_DBG_BUS	28
+#define CLK_MOUT_CMU_CPUCL0_SWITCH	29
+#define CLK_MOUT_CMU_CPUCL1_SWITCH	30
+#define CLK_MOUT_CMU_CPUCL2_BUSP	31
+#define CLK_MOUT_CMU_CPUCL2_SWITCH	32
+#define CLK_MOUT_CMU_CSIS_BUS		33
+#define CLK_MOUT_CMU_CSIS_OIS_MCU	34
+#define CLK_MOUT_CMU_DNC_BUS		35
+#define CLK_MOUT_CMU_DNC_BUSM		36
+#define CLK_MOUT_CMU_DNS_BUS		37
+#define CLK_MOUT_CMU_DPU		38
+#define CLK_MOUT_CMU_DPU_ALT		39
+#define CLK_MOUT_CMU_DSP_BUS		40
+#define CLK_MOUT_CMU_G2D_G2D		41
+#define CLK_MOUT_CMU_G2D_MSCL		42
+#define CLK_MOUT_CMU_HPM		43
+#define CLK_MOUT_CMU_HSI0_BUS		44
+#define CLK_MOUT_CMU_HSI0_DPGTC		45
+#define CLK_MOUT_CMU_HSI0_USB31DRD	46
+#define CLK_MOUT_CMU_HSI0_USBDP_DEBUG	47
+#define CLK_MOUT_CMU_HSI1_BUS		48
+#define CLK_MOUT_CMU_HSI1_MMC_CARD	49
+#define CLK_MOUT_CMU_HSI1_PCIE		50
+#define CLK_MOUT_CMU_HSI1_UFS_CARD	51
+#define CLK_MOUT_CMU_HSI1_UFS_EMBD	52
+#define CLK_MOUT_CMU_HSI2_BUS		53
+#define CLK_MOUT_CMU_HSI2_PCIE		54
+#define CLK_MOUT_CMU_IPP_BUS		55
+#define CLK_MOUT_CMU_ITP_BUS		56
+#define CLK_MOUT_CMU_MCSC_BUS		57
+#define CLK_MOUT_CMU_MCSC_GDC		58
+#define CLK_MOUT_CMU_CMU_BOOST_CPU	59
+#define CLK_MOUT_CMU_MFC0_MFC0		60
+#define CLK_MOUT_CMU_MFC0_WFD		61
+#define CLK_MOUT_CMU_MIF_BUSP		62
+#define CLK_MOUT_CMU_MIF_SWITCH		63
+#define CLK_MOUT_CMU_NPU_BUS		64
+#define CLK_MOUT_CMU_PERIC0_BUS		65
+#define CLK_MOUT_CMU_PERIC0_IP		66
+#define CLK_MOUT_CMU_PERIC1_BUS		67
+#define CLK_MOUT_CMU_PERIC1_IP		68
+#define CLK_MOUT_CMU_PERIS_BUS		69
+#define CLK_MOUT_CMU_SSP_BUS		70
+#define CLK_MOUT_CMU_TNR_BUS		71
+#define CLK_MOUT_CMU_VRA_BUS		72
+#define CLK_DOUT_CMU_APM_BUS		73
+#define CLK_DOUT_CMU_AUD_CPU		74
+#define CLK_DOUT_CMU_BUS0_BUS		75
+#define CLK_DOUT_CMU_BUS1_BUS		76
+#define CLK_DOUT_CMU_BUS1_SSS		77
+#define CLK_DOUT_CMU_CIS_CLK0		78
+#define CLK_DOUT_CMU_CIS_CLK1		79
+#define CLK_DOUT_CMU_CIS_CLK2		80
+#define CLK_DOUT_CMU_CIS_CLK3		81
+#define CLK_DOUT_CMU_CIS_CLK4		82
+#define CLK_DOUT_CMU_CIS_CLK5		83
+#define CLK_DOUT_CMU_CMU_BOOST		84
+#define CLK_DOUT_CMU_CORE_BUS		85
+#define CLK_DOUT_CMU_CPUCL0_DBG_BUS	86
+#define CLK_DOUT_CMU_CPUCL0_SWITCH	87
+#define CLK_DOUT_CMU_CPUCL1_SWITCH	88
+#define CLK_DOUT_CMU_CPUCL2_BUSP	89
+#define CLK_DOUT_CMU_CPUCL2_SWITCH	90
+#define CLK_DOUT_CMU_CSIS_BUS		91
+#define CLK_DOUT_CMU_CSIS_OIS_MCU	92
+#define CLK_DOUT_CMU_DNC_BUS		93
+#define CLK_DOUT_CMU_DNC_BUSM		94
+#define CLK_DOUT_CMU_DNS_BUS		95
+#define CLK_DOUT_CMU_DSP_BUS		96
+#define CLK_DOUT_CMU_G2D_G2D		97
+#define CLK_DOUT_CMU_G2D_MSCL		98
+#define CLK_DOUT_CMU_G3D_SWITCH		99
+#define CLK_DOUT_CMU_HPM		100
+#define CLK_DOUT_CMU_HSI0_BUS		101
+#define CLK_DOUT_CMU_HSI0_DPGTC		102
+#define CLK_DOUT_CMU_HSI0_USB31DRD	103
+#define CLK_DOUT_CMU_HSI0_USBDP_DEBUG	104
+#define CLK_DOUT_CMU_HSI1_BUS		105
+#define CLK_DOUT_CMU_HSI1_MMC_CARD	106
+#define CLK_DOUT_CMU_HSI1_PCIE		107
+#define CLK_DOUT_CMU_HSI1_UFS_CARD	108
+#define CLK_DOUT_CMU_HSI1_UFS_EMBD	109
+#define CLK_DOUT_CMU_HSI2_BUS		110
+#define CLK_DOUT_CMU_HSI2_PCIE		111
+#define CLK_DOUT_CMU_IPP_BUS		112
+#define CLK_DOUT_CMU_ITP_BUS		113
+#define CLK_DOUT_CMU_MCSC_BUS		114
+#define CLK_DOUT_CMU_MCSC_GDC		115
+#define CLK_DOUT_CMU_CMU_BOOST_CPU	116
+#define CLK_DOUT_CMU_MFC0_MFC0		117
+#define CLK_DOUT_CMU_MFC0_WFD		118
+#define CLK_DOUT_CMU_MIF_BUSP		119
+#define CLK_DOUT_CMU_NPU_BUS		120
+#define CLK_DOUT_CMU_OTP		121
+#define CLK_DOUT_CMU_PERIC0_BUS		122
+#define CLK_DOUT_CMU_PERIC0_IP		123
+#define CLK_DOUT_CMU_PERIC1_BUS		124
+#define CLK_DOUT_CMU_PERIC1_IP		125
+#define CLK_DOUT_CMU_PERIS_BUS		126
+#define CLK_DOUT_CMU_SSP_BUS		127
+#define CLK_DOUT_CMU_TNR_BUS		128
+#define CLK_DOUT_CMU_VRA_BUS		129
+#define CLK_DOUT_CMU_DPU		130
+#define CLK_DOUT_CMU_DPU_ALT		131
+#define CLK_DOUT_CMU_SHARED0_DIV2	132
+#define CLK_DOUT_CMU_SHARED0_DIV3	133
+#define CLK_DOUT_CMU_SHARED0_DIV4	134
+#define CLK_DOUT_CMU_SHARED1_DIV2	135
+#define CLK_DOUT_CMU_SHARED1_DIV3	136
+#define CLK_DOUT_CMU_SHARED1_DIV4	137
+#define CLK_DOUT_CMU_SHARED2_DIV2	138
+#define CLK_DOUT_CMU_SHARED4_DIV2	139
+#define CLK_DOUT_CMU_SHARED4_DIV3	140
+#define CLK_DOUT_CMU_SHARED4_DIV4	141
+#define CLK_GOUT_CMU_G3D_BUS		142
+#define CLK_GOUT_CMU_MIF_SWITCH		143
+#define CLK_GOUT_CMU_APM_BUS		144
+#define CLK_GOUT_CMU_AUD_CPU		145
+#define CLK_GOUT_CMU_BUS0_BUS		146
+#define CLK_GOUT_CMU_BUS1_BUS		147
+#define CLK_GOUT_CMU_BUS1_SSS		148
+#define CLK_GOUT_CMU_CIS_CLK0		149
+#define CLK_GOUT_CMU_CIS_CLK1		150
+#define CLK_GOUT_CMU_CIS_CLK2		151
+#define CLK_GOUT_CMU_CIS_CLK3		152
+#define CLK_GOUT_CMU_CIS_CLK4		153
+#define CLK_GOUT_CMU_CIS_CLK5		154
+#define CLK_GOUT_CMU_CORE_BUS		155
+#define CLK_GOUT_CMU_CPUCL0_DBG_BUS	156
+#define CLK_GOUT_CMU_CPUCL0_SWITCH	157
+#define CLK_GOUT_CMU_CPUCL1_SWITCH	158
+#define CLK_GOUT_CMU_CPUCL2_BUSP	159
+#define CLK_GOUT_CMU_CPUCL2_SWITCH	160
+#define CLK_GOUT_CMU_CSIS_BUS		161
+#define CLK_GOUT_CMU_CSIS_OIS_MCU	162
+#define CLK_GOUT_CMU_DNC_BUS		163
+#define CLK_GOUT_CMU_DNC_BUSM		164
+#define CLK_GOUT_CMU_DNS_BUS		165
+#define CLK_GOUT_CMU_DPU		166
+#define CLK_GOUT_CMU_DPU_BUS		167
+#define CLK_GOUT_CMU_DSP_BUS		168
+#define CLK_GOUT_CMU_G2D_G2D		169
+#define CLK_GOUT_CMU_G2D_MSCL		170
+#define CLK_GOUT_CMU_G3D_SWITCH		171
+#define CLK_GOUT_CMU_HPM		172
+#define CLK_GOUT_CMU_HSI0_BUS		173
+#define CLK_GOUT_CMU_HSI0_DPGTC		174
+#define CLK_GOUT_CMU_HSI0_USB31DRD	175
+#define CLK_GOUT_CMU_HSI0_USBDP_DEBUG	176
+#define CLK_GOUT_CMU_HSI1_BUS		177
+#define CLK_GOUT_CMU_HSI1_MMC_CARD	178
+#define CLK_GOUT_CMU_HSI1_PCIE		179
+#define CLK_GOUT_CMU_HSI1_UFS_CARD	180
+#define CLK_GOUT_CMU_HSI1_UFS_EMBD	181
+#define CLK_GOUT_CMU_HSI2_BUS		182
+#define CLK_GOUT_CMU_HSI2_PCIE		183
+#define CLK_GOUT_CMU_IPP_BUS		184
+#define CLK_GOUT_CMU_ITP_BUS		185
+#define CLK_GOUT_CMU_MCSC_BUS		186
+#define CLK_GOUT_CMU_MCSC_GDC		187
+#define CLK_GOUT_CMU_MFC0_MFC0		188
+#define CLK_GOUT_CMU_MFC0_WFD		189
+#define CLK_GOUT_CMU_MIF_BUSP		190
+#define CLK_GOUT_CMU_NPU_BUS		191
+#define CLK_GOUT_CMU_PERIC0_BUS		192
+#define CLK_GOUT_CMU_PERIC0_IP		193
+#define CLK_GOUT_CMU_PERIC1_BUS		194
+#define CLK_GOUT_CMU_PERIC1_IP		195
+#define CLK_GOUT_CMU_PERIS_BUS		196
+#define CLK_GOUT_CMU_SSP_BUS		197
+#define CLK_GOUT_CMU_TNR_BUS		198
+#define CLK_GOUT_CMU_VRA_BUS		199
+
+/* CMU_HSI0 */
+#define CLK_MOUT_HSI0_BUS_USER				1
+#define CLK_MOUT_HSI0_USB31DRD_USER			2
+#define CLK_MOUT_HSI0_USBDP_DEBUG_USER			3
+#define CLK_MOUT_HSI0_DPGTC_USER			4
+#define CLK_GOUT_HSI0_DP_LINK_DP_GTC_CLK		5
+#define CLK_GOUT_HSI0_DP_LINK_PCLK			6
+#define CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK			7
+#define CLK_GOUT_HSI0_LHM_AXI_P_HSI0_CLK		8
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_ACLK		9
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_PCLK		10
+#define CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK			11
+#define CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2			12
+#define CLK_GOUT_HSI0_SYSREG_HSI0_PCLK			13
+#define CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL		14
+#define CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY		15
+#define CLK_GOUT_HSI0_USB31DRD_USB31DRD_REF_CLK_40	16
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_REF_SOC_PLL	17
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_SCL_APB		18
+#define CLK_GOUT_HSI0_USB31DRD_USBPCS_APB_CLK		19
+#define CLK_GOUT_HSI0_VGEN_LITE_HSI0_CLK		20
+#define CLK_GOUT_HSI0_CMU_HSI0_PCLK			21
+#define CLK_GOUT_HSI0_XIU_D_HSI0_ACLK			22
+
+#endif

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Sat Dec  7 01:25:40 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Sat, 07 Dec 2024 10:25:40 +0100
Subject: [PATCH v3 3/3] clk: samsung: Introduce Exynos990 clock controller
 driver
In-Reply-To: <20241207-exynos990-cmu-v3-0-20c0f6ea02f0@mentallysanemainliners.org>
References: <20241207-exynos990-cmu-v3-0-20c0f6ea02f0@mentallysanemainliners.org>
Message-ID: <20241207-exynos990-cmu-v3-3-20c0f6ea02f0@mentallysanemainliners.org>

The current implementation contains support for:
- CMU_TOP - which generates clocks for other blocks
- CMU_HSI0 - which generates clocks for USB31.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 drivers/clk/samsung/Makefile        |    1 +
 drivers/clk/samsung/clk-exynos990.c | 1343 +++++++++++++++++++++++++++++++++++
 2 files changed, 1344 insertions(+)

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 7a88331a658d5035c083eba910e37564915f9a46..90e5b114872c5057a9bd43fd1a16c2ad4630cc3f 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7885.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos8895.o
+obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos990.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov9.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov920.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-gs101.o
diff --git a/drivers/clk/samsung/clk-exynos990.c b/drivers/clk/samsung/clk-exynos990.c
new file mode 100644
index 0000000000000000000000000000000000000000..8e2a2e8eccee36dd7d4bc7099af2672d222f4abe
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos990.c
@@ -0,0 +1,1343 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Igor Belwon <igor.belwon at mentallysanemainliners.org>
+ *
+ * Common Clock Framework support for Exynos990.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/samsung,exynos990.h>
+
+#include "clk.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_GOUT_CMU_VRA_BUS + 1)
+#define CLKS_NR_HSI0 (CLK_GOUT_HSI0_XIU_D_HSI0_ACLK + 1)
+
+/* ---- CMU_TOP ------------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_TOP (0x1a330000) */
+#define PLL_LOCKTIME_PLL_G3D				0x0000
+#define PLL_LOCKTIME_PLL_MMC				0x0004
+#define PLL_LOCKTIME_PLL_SHARED0			0x0008
+#define PLL_LOCKTIME_PLL_SHARED1			0x000c
+#define PLL_LOCKTIME_PLL_SHARED2			0x0010
+#define PLL_LOCKTIME_PLL_SHARED3			0x0014
+#define PLL_LOCKTIME_PLL_SHARED4			0x0018
+#define PLL_CON0_PLL_G3D				0x0100
+#define PLL_CON3_PLL_G3D				0x010c
+#define PLL_CON0_PLL_MMC				0x0140
+#define PLL_CON3_PLL_MMC				0x014c
+#define PLL_CON0_PLL_SHARED0				0x0180
+#define PLL_CON3_PLL_SHARED0				0x018c
+#define PLL_CON0_PLL_SHARED1				0x01c0
+#define PLL_CON3_PLL_SHARED1				0x01cc
+#define PLL_CON0_PLL_SHARED2				0x0200
+#define PLL_CON3_PLL_SHARED2				0x020c
+#define PLL_CON0_PLL_SHARED3				0x0240
+#define PLL_CON3_PLL_SHARED3				0x024c
+#define PLL_CON0_PLL_SHARED4				0x0280
+#define PLL_CON3_PLL_SHARED4				0x028c
+#define CLK_CON_MUX_MUX_CLKCMU_APM_BUS			0x1004
+#define CLK_CON_MUX_MUX_CLKCMU_AUD_CPU			0x1008
+#define CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS			0x100c
+#define CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS			0x1010
+#define CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS			0x1014
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0			0x1018
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1			0x101c
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2			0x1020
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3			0x1024
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4			0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5			0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST		0x1030
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS			0x1034
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS		0x1038
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH		0x103c
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH		0x1040
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP		0x1044
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH		0x1048
+#define CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS			0x104c
+#define CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU		0x1050
+#define CLK_CON_MUX_MUX_CLKCMU_DNC_BUS			0x1054
+#define CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM			0x1058
+#define CLK_CON_MUX_MUX_CLKCMU_DNS_BUS			0x105c
+#define CLK_CON_MUX_MUX_CLKCMU_DPU			0x1060
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_ALT			0x1064
+#define CLK_CON_MUX_MUX_CLKCMU_DSP_BUS			0x1068
+#define CLK_CON_MUX_MUX_CLKCMU_G2D_G2D			0x106c
+#define CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL			0x1070
+#define CLK_CON_MUX_MUX_CLKCMU_HPM			0x1074
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS			0x1078
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC		0x107c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD		0x1080
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG		0x1084
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS			0x1088
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD		0x108c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE		0x1090
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD		0x1094
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD		0x1098
+#define CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS			0x109c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE		0x10a0
+#define CLK_CON_MUX_MUX_CLKCMU_IPP_BUS			0x10a4
+#define CLK_CON_MUX_MUX_CLKCMU_ITP_BUS			0x10a8
+#define CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS			0x10ac
+#define CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC			0x10b0
+#define CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU		0x10b4
+#define CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0		0x10b8
+#define CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD			0x10bc
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP			0x10c0
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH		0x10c4
+#define CLK_CON_MUX_MUX_CLKCMU_NPU_BUS			0x10c8
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS		0x10cc
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP		0x10d0
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS		0x10d4
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP		0x10d8
+#define CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS		0x10dc
+#define CLK_CON_MUX_MUX_CLKCMU_SSP_BUS			0x10e0
+#define CLK_CON_MUX_MUX_CLKCMU_TNR_BUS			0x10e4
+#define CLK_CON_MUX_MUX_CLKCMU_VRA_BUS			0x10e8
+#define CLK_CON_DIV_CLKCMU_APM_BUS			0x1800
+#define CLK_CON_DIV_CLKCMU_AUD_CPU			0x1804
+#define CLK_CON_DIV_CLKCMU_BUS0_BUS			0x1808
+#define CLK_CON_DIV_CLKCMU_BUS1_BUS			0x180c
+#define CLK_CON_DIV_CLKCMU_BUS1_SSS			0x1810
+#define CLK_CON_DIV_CLKCMU_CIS_CLK0			0x1814
+#define CLK_CON_DIV_CLKCMU_CIS_CLK1			0x1818
+#define CLK_CON_DIV_CLKCMU_CIS_CLK2			0x181c
+#define CLK_CON_DIV_CLKCMU_CIS_CLK3			0x1820
+#define CLK_CON_DIV_CLKCMU_CIS_CLK4			0x1824
+#define CLK_CON_DIV_CLKCMU_CIS_CLK5			0x1828
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST			0x182c
+#define CLK_CON_DIV_CLKCMU_CORE_BUS			0x1830
+#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS		0x1834
+#define CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH		0x1838
+#define CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH		0x183c
+#define CLK_CON_DIV_CLKCMU_CPUCL2_BUSP			0x1840
+#define CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH		0x1844
+#define CLK_CON_DIV_CLKCMU_CSIS_BUS			0x1848
+#define CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU			0x184c
+#define CLK_CON_DIV_CLKCMU_DNC_BUS			0x1850
+#define CLK_CON_DIV_CLKCMU_DNC_BUSM			0x1854
+#define CLK_CON_DIV_CLKCMU_DNS_BUS			0x1858
+#define CLK_CON_DIV_CLKCMU_DSP_BUS			0x185c
+#define CLK_CON_DIV_CLKCMU_G2D_G2D			0x1860
+#define CLK_CON_DIV_CLKCMU_G2D_MSCL			0x1864
+#define CLK_CON_DIV_CLKCMU_G3D_SWITCH			0x1868
+#define CLK_CON_DIV_CLKCMU_HPM				0x186c
+#define CLK_CON_DIV_CLKCMU_HSI0_BUS			0x1870
+#define CLK_CON_DIV_CLKCMU_HSI0_DPGTC			0x1874
+#define CLK_CON_DIV_CLKCMU_HSI0_USB31DRD		0x1878
+#define CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG		0x187c
+#define CLK_CON_DIV_CLKCMU_HSI1_BUS			0x1880
+#define CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD		0x1884
+#define CLK_CON_DIV_CLKCMU_HSI1_PCIE			0x1888
+#define CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD		0x188c
+#define CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD		0x1890
+#define CLK_CON_DIV_CLKCMU_HSI2_BUS			0x1894
+#define CLK_CON_DIV_CLKCMU_HSI2_PCIE			0x1898
+#define CLK_CON_DIV_CLKCMU_IPP_BUS			0x189c
+#define CLK_CON_DIV_CLKCMU_ITP_BUS			0x18a0
+#define CLK_CON_DIV_CLKCMU_MCSC_BUS			0x18a4
+#define CLK_CON_DIV_CLKCMU_MCSC_GDC			0x18a8
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU		0x18ac
+#define CLK_CON_DIV_CLKCMU_MFC0_MFC0			0x18b0
+#define CLK_CON_DIV_CLKCMU_MFC0_WFD			0x18b4
+#define CLK_CON_DIV_CLKCMU_MIF_BUSP			0x18b8
+#define CLK_CON_DIV_CLKCMU_NPU_BUS			0x18bc
+#define CLK_CON_DIV_CLKCMU_OTP				0x18c0
+#define CLK_CON_DIV_CLKCMU_PERIC0_BUS			0x18c4
+#define CLK_CON_DIV_CLKCMU_PERIC0_IP			0x18c8
+#define CLK_CON_DIV_CLKCMU_PERIC1_BUS			0x18cc
+#define CLK_CON_DIV_CLKCMU_PERIC1_IP			0x18d0
+#define CLK_CON_DIV_CLKCMU_PERIS_BUS			0x18d4
+#define CLK_CON_DIV_CLKCMU_SSP_BUS			0x18d8
+#define CLK_CON_DIV_CLKCMU_TNR_BUS			0x18dc
+#define CLK_CON_DIV_CLKCMU_VRA_BUS			0x18e0
+#define CLK_CON_DIV_DIV_CLKCMU_DPU			0x18e8
+#define CLK_CON_DIV_DIV_CLKCMU_DPU_ALT			0x18ec
+#define CLK_CON_DIV_PLL_SHARED0_DIV2			0x18f4
+#define CLK_CON_DIV_PLL_SHARED0_DIV3			0x18f8
+#define CLK_CON_DIV_PLL_SHARED0_DIV4			0x18fc
+#define CLK_CON_DIV_PLL_SHARED1_DIV2			0x1900
+#define CLK_CON_DIV_PLL_SHARED1_DIV3			0x1904
+#define CLK_CON_DIV_PLL_SHARED1_DIV4			0x1908
+#define CLK_CON_DIV_PLL_SHARED2_DIV2			0x190c
+#define CLK_CON_DIV_PLL_SHARED4_DIV2			0x1910
+#define CLK_CON_DIV_PLL_SHARED4_DIV3			0x1914
+#define CLK_CON_DIV_PLL_SHARED4_DIV4			0x1918
+#define CLK_CON_GAT_CLKCMU_G3D_BUS			0x2000
+#define CLK_CON_GAT_CLKCMU_MIF_SWITCH			0x2004
+#define CLK_CON_GAT_GATE_CLKCMU_APM_BUS			0x2008
+#define CLK_CON_GAT_GATE_CLKCMU_AUD_CPU			0x200c
+#define CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS		0x2010
+#define CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS		0x2014
+#define CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS		0x2018
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0		0x201c
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1		0x2020
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2		0x2024
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3		0x2028
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4		0x202c
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5		0x2030
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS		0x2034
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS		0x2038
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH		0x203c
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH		0x2040
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP		0x2044
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH		0x2048
+#define CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS		0x204c
+#define CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU		0x2050
+#define CLK_CON_GAT_GATE_CLKCMU_DNC_BUS			0x2054
+#define CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM		0x2058
+#define CLK_CON_GAT_GATE_CLKCMU_DNS_BUS			0x205c
+#define CLK_CON_GAT_GATE_CLKCMU_DPU			0x2060
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_BUS			0x2064
+#define CLK_CON_GAT_GATE_CLKCMU_DSP_BUS			0x2068
+#define CLK_CON_GAT_GATE_CLKCMU_G2D_G2D			0x206c
+#define CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL		0x2070
+#define CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH		0x2074
+#define CLK_CON_GAT_GATE_CLKCMU_HPM			0x2078
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS		0x207c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC		0x2080
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD		0x2084
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG	0x2088
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS		0x208c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD		0x2090
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE		0x2094
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD		0x2098
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD		0x209c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS		0x20a0
+#define CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE		0x20a4
+#define CLK_CON_GAT_GATE_CLKCMU_IPP_BUS			0x20a8
+#define CLK_CON_GAT_GATE_CLKCMU_ITP_BUS			0x20ac
+#define CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS		0x20b0
+#define CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC		0x20b4
+#define CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0		0x20bc
+#define CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD		0x20c0
+#define CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP		0x20c4
+#define CLK_CON_GAT_GATE_CLKCMU_NPU_BUS			0x20c8
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS		0x20cc
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP		0x20d0
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS		0x20d4
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP		0x20d8
+#define CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS		0x20dc
+#define CLK_CON_GAT_GATE_CLKCMU_SSP_BUS			0x20e0
+#define CLK_CON_GAT_GATE_CLKCMU_TNR_BUS			0x20e4
+#define CLK_CON_GAT_GATE_CLKCMU_VRA_BUS			0x20e8
+
+static const unsigned long top_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_G3D,
+	PLL_LOCKTIME_PLL_MMC,
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_LOCKTIME_PLL_SHARED2,
+	PLL_LOCKTIME_PLL_SHARED3,
+	PLL_LOCKTIME_PLL_SHARED4,
+	PLL_CON3_PLL_G3D,
+	PLL_CON3_PLL_MMC,
+	PLL_CON3_PLL_SHARED0,
+	PLL_CON3_PLL_SHARED1,
+	PLL_CON3_PLL_SHARED2,
+	PLL_CON3_PLL_SHARED3,
+	PLL_CON3_PLL_SHARED4,
+	CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_AUD_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5,
+	CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST,
+	CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_MUX_MUX_CLKCMU_DNC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM,
+	CLK_CON_MUX_MUX_CLKCMU_DNS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DPU,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_ALT,
+	CLK_CON_MUX_MUX_CLKCMU_DSP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_G2D_G2D,
+	CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL,
+	CLK_CON_MUX_MUX_CLKCMU_HPM,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE,
+	CLK_CON_MUX_MUX_CLKCMU_IPP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_ITP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC,
+	CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0,
+	CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_NPU_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_SSP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_TNR_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_VRA_BUS,
+	CLK_CON_DIV_CLKCMU_APM_BUS,
+	CLK_CON_DIV_CLKCMU_AUD_CPU,
+	CLK_CON_DIV_CLKCMU_BUS0_BUS,
+	CLK_CON_DIV_CLKCMU_BUS1_BUS,
+	CLK_CON_DIV_CLKCMU_BUS1_SSS,
+	CLK_CON_DIV_CLKCMU_CIS_CLK0,
+	CLK_CON_DIV_CLKCMU_CIS_CLK1,
+	CLK_CON_DIV_CLKCMU_CIS_CLK2,
+	CLK_CON_DIV_CLKCMU_CIS_CLK3,
+	CLK_CON_DIV_CLKCMU_CIS_CLK4,
+	CLK_CON_DIV_CLKCMU_CIS_CLK5,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST,
+	CLK_CON_DIV_CLKCMU_CORE_BUS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_DIV_CLKCMU_CSIS_BUS,
+	CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_DIV_CLKCMU_DNC_BUS,
+	CLK_CON_DIV_CLKCMU_DNC_BUSM,
+	CLK_CON_DIV_CLKCMU_DNS_BUS,
+	CLK_CON_DIV_CLKCMU_DSP_BUS,
+	CLK_CON_DIV_CLKCMU_G2D_G2D,
+	CLK_CON_DIV_CLKCMU_G2D_MSCL,
+	CLK_CON_DIV_CLKCMU_G3D_SWITCH,
+	CLK_CON_DIV_CLKCMU_HPM,
+	CLK_CON_DIV_CLKCMU_HSI0_BUS,
+	CLK_CON_DIV_CLKCMU_HSI0_DPGTC,
+	CLK_CON_DIV_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_DIV_CLKCMU_HSI1_BUS,
+	CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_DIV_CLKCMU_HSI1_PCIE,
+	CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_DIV_CLKCMU_HSI2_BUS,
+	CLK_CON_DIV_CLKCMU_HSI2_PCIE,
+	CLK_CON_DIV_CLKCMU_IPP_BUS,
+	CLK_CON_DIV_CLKCMU_ITP_BUS,
+	CLK_CON_DIV_CLKCMU_MCSC_BUS,
+	CLK_CON_DIV_CLKCMU_MCSC_GDC,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU,
+	CLK_CON_DIV_CLKCMU_MFC0_MFC0,
+	CLK_CON_DIV_CLKCMU_MFC0_WFD,
+	CLK_CON_DIV_CLKCMU_MIF_BUSP,
+	CLK_CON_DIV_CLKCMU_NPU_BUS,
+	CLK_CON_DIV_CLKCMU_OTP,
+	CLK_CON_DIV_CLKCMU_PERIC0_BUS,
+	CLK_CON_DIV_CLKCMU_PERIC0_IP,
+	CLK_CON_DIV_CLKCMU_PERIC1_BUS,
+	CLK_CON_DIV_CLKCMU_PERIC1_IP,
+	CLK_CON_DIV_CLKCMU_PERIS_BUS,
+	CLK_CON_DIV_CLKCMU_SSP_BUS,
+	CLK_CON_DIV_CLKCMU_TNR_BUS,
+	CLK_CON_DIV_CLKCMU_VRA_BUS,
+	CLK_CON_DIV_DIV_CLKCMU_DPU,
+	CLK_CON_DIV_DIV_CLKCMU_DPU_ALT,
+	CLK_CON_DIV_PLL_SHARED0_DIV2,
+	CLK_CON_DIV_PLL_SHARED0_DIV3,
+	CLK_CON_DIV_PLL_SHARED0_DIV4,
+	CLK_CON_DIV_PLL_SHARED1_DIV2,
+	CLK_CON_DIV_PLL_SHARED1_DIV3,
+	CLK_CON_DIV_PLL_SHARED1_DIV4,
+	CLK_CON_DIV_PLL_SHARED2_DIV2,
+	CLK_CON_DIV_PLL_SHARED4_DIV2,
+	CLK_CON_DIV_PLL_SHARED4_DIV3,
+	CLK_CON_DIV_PLL_SHARED4_DIV4,
+	CLK_CON_GAT_CLKCMU_G3D_BUS,
+	CLK_CON_GAT_CLKCMU_MIF_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_AUD_CPU,
+	CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5,
+	CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_GAT_GATE_CLKCMU_DNC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM,
+	CLK_CON_GAT_GATE_CLKCMU_DNS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DPU,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DSP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_G2D_G2D,
+	CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL,
+	CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_HPM,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE,
+	CLK_CON_GAT_GATE_CLKCMU_IPP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_ITP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC,
+	CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0,
+	CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD,
+	CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_NPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_SSP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_TNR_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_VRA_BUS,
+};
+
+static const struct samsung_pll_clock top_pll_clks[] __initconst = {
+	PLL(pll_0717x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, NULL),
+	PLL(pll_0717x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, NULL),
+	PLL(pll_0718x, CLK_FOUT_SHARED2_PLL, "fout_shared2_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED2, PLL_CON3_PLL_SHARED2, NULL),
+	PLL(pll_0718x, CLK_FOUT_SHARED3_PLL, "fout_shared3_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED3, PLL_CON3_PLL_SHARED3, NULL),
+	PLL(pll_0717x, CLK_FOUT_SHARED4_PLL, "fout_shared4_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED4, PLL_CON3_PLL_SHARED4, NULL),
+	PLL(pll_0732x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL),
+	PLL(pll_0718x, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_G3D, PLL_CON3_PLL_G3D, NULL),
+};
+
+/* Parent clock list for CMU_TOP muxes*/
+PNAME(mout_pll_shared0_p)		= { "oscclk", "fout_shared0_pll" };
+PNAME(mout_pll_shared1_p)		= { "oscclk", "fout_shared1_pll" };
+PNAME(mout_pll_shared2_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_pll_shared3_p)		= { "oscclk", "fout_shared3_pll" };
+PNAME(mout_pll_shared4_p)		= { "oscclk", "fout_shared4_pll" };
+PNAME(mout_pll_mmc_p)			= { "oscclk", "fout_mmc_pll" };
+PNAME(mout_pll_g3d_p)			= { "oscclk", "fout_g3d_pll" };
+PNAME(mout_cmu_apm_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_aud_cpu_p)		= { "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_bus0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_bus1_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_bus1_sss_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_cis_clk0_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk1_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk2_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk3_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk4_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk5_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cmu_boost_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_core_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div3",
+					    "dout_cmu_shared1_div3",
+					    "dout_cmu_shared0_div4",
+					    "fout_shared3_pll", "oscclk" };
+PNAME(mout_cmu_cpucl0_dbg_bus_p)	= { "fout_shared2_pll",
+					    "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4",
+					    "oscclk" };
+PNAME(mout_cmu_cpucl0_switch_p)		= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_cpucl1_switch_p)	= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_cpucl2_busp_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cpucl2_switch_p)		= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_csis_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3" };
+PNAME(mout_cmu_csis_ois_mcu_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_dnc_bus_p)		= { "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_dnc_busm_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "dout_cmu_shared4_div4" };
+PNAME(mout_cmu_dns_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_dpu_p)			= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_dpu_alt_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_dsp_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "fout_shared3_pll", "oscclk",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_g2d_g2d_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_g2d_mscl_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "dout_cmu_shared4_div4",
+					    "oscclk" };
+PNAME(mout_cmu_hpm_p)			= { "oscclk",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_hsi0_dpgtc_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_usb31drd_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_usbdp_debug_p)	= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_hsi1_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "fout_mmc_pll", "oscclk", "oscclk" };
+PNAME(mout_cmu_hsi1_mmc_card_p)	= { "oscclk", "fout_shared2_pll",
+					    "fout_mmc_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_hsi1_pcie_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_hsi1_ufs_card_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi1_ufs_embd_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi2_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_hsi2_pcie_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_ipp_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "oscclk", "oscclk", "oscclk" };
+PNAME(mout_cmu_itp_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_mcsc_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_mcsc_gdc_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_cmu_boost_cpu_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_mfc0_mfc0_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_mfc0_wfd_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_mif_busp_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_mif_switch_p)		= { "fout_shared0_pll",
+					    "fout_shared1_pll",
+					    "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_npu_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "fout_shared3_pll", "oscclk",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_peric0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric0_ip_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric1_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric1_ip_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peris_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_ssp_bus_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_tnr_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_vra_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3" };
+
+/*
+ * Register name to clock name mangling strategy used in this file
+ *
+ * Replace PLL_CON{0,3}_PLL	   with CLK_MOUT_PLL and mout_pll
+ * Replace CLK_CON_MUX_MUX_CLKCMU  with CLK_MOUT_CMU and mout_cmu
+ * Replace CLK_CON_DIV_CLKCMU      with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_DIV_DIV_CLKCMU  with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_DIV_PLL_CLKCMU  with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_GAT_CLKCMU      with CLK_GOUT_CMU and gout_cmu
+ * Replace CLK_CON_GAT_GATE_CLKCMU with CLK_GOUT_CMU and gout_cmu
+ *
+ * For gates remove _UID _BLK _IPCLKPORT, _I and _RSTNSYNC
+ */
+
+static const struct samsung_mux_clock top_mux_clks[] __initconst = {
+	MUX(CLK_MOUT_PLL_SHARED0, "mout_pll_shared0", mout_pll_shared0_p,
+	    PLL_CON3_PLL_SHARED0, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED1, "mout_pll_shared1", mout_pll_shared1_p,
+	    PLL_CON3_PLL_SHARED1, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED2, "mout_pll_shared2", mout_pll_shared2_p,
+	    PLL_CON3_PLL_SHARED2, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED3, "mout_pll_shared3", mout_pll_shared3_p,
+	    PLL_CON3_PLL_SHARED3, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED4, "mout_pll_shared4", mout_pll_shared4_p,
+	    PLL_CON0_PLL_SHARED4, 4, 1),
+	MUX(CLK_MOUT_PLL_MMC, "mout_pll_mmc", mout_pll_mmc_p,
+	    PLL_CON0_PLL_MMC, 4, 1),
+	MUX(CLK_MOUT_PLL_G3D, "mout_pll_g3d", mout_pll_g3d_p,
+	    PLL_CON0_PLL_G3D, 4, 1),
+	MUX(CLK_MOUT_CMU_APM_BUS, "mout_cmu_apm_bus",
+	    mout_cmu_apm_bus_p, CLK_CON_MUX_MUX_CLKCMU_APM_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_AUD_CPU, "mout_cmu_aud_cpu",
+	    mout_cmu_aud_cpu_p, CLK_CON_MUX_MUX_CLKCMU_AUD_CPU, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS0_BUS, "mout_cmu_bus0_bus",
+	    mout_cmu_bus0_bus_p, CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS1_BUS, "mout_cmu_bus1_bus",
+	    mout_cmu_bus1_bus_p, CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS1_SSS, "mout_cmu_bus1_sss",
+	    mout_cmu_bus1_sss_p, CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS, 0, 2),
+	MUX(CLK_MOUT_CMU_CIS_CLK0, "mout_cmu_cis_clk0",
+	    mout_cmu_cis_clk0_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK1, "mout_cmu_cis_clk1",
+	    mout_cmu_cis_clk1_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK2, "mout_cmu_cis_clk2",
+	    mout_cmu_cis_clk2_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK3, "mout_cmu_cis_clk3",
+	    mout_cmu_cis_clk3_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK4, "mout_cmu_cis_clk4",
+	    mout_cmu_cis_clk4_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK5, "mout_cmu_cis_clk5",
+	    mout_cmu_cis_clk5_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5, 0, 1),
+	MUX(CLK_MOUT_CMU_CMU_BOOST, "mout_cmu_cmu_boost",
+	    mout_cmu_cmu_boost_p, CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST, 0, 2),
+	MUX(CLK_MOUT_CMU_CORE_BUS, "mout_cmu_core_bus",
+	    mout_cmu_core_bus_p, CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_CPUCL0_DBG_BUS, "mout_cmu_cpucl0_dbg_bus",
+	    mout_cmu_cpucl0_dbg_bus_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL0_SWITCH, "mout_cmu_cpucl0_switch",
+	    mout_cmu_cpucl0_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL1_SWITCH, "mout_cmu_cpucl1_switch",
+	    mout_cmu_cpucl1_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL2_BUSP, "mout_cmu_cpucl2_busp",
+	    mout_cmu_cpucl2_busp_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_CPUCL2_SWITCH, "mout_cmu_cpucl2_switch",
+	    mout_cmu_cpucl2_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CSIS_BUS, "mout_cmu_csis_bus",
+	    mout_cmu_csis_bus_p, CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_CSIS_OIS_MCU, "mout_cmu_csis_ois_mcu",
+	    mout_cmu_csis_ois_mcu_p, CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_DNC_BUS, "mout_cmu_dnc_bus",
+	    mout_cmu_dnc_bus_p, CLK_CON_MUX_MUX_CLKCMU_DNC_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_DNC_BUSM, "mout_cmu_dnc_busm",
+	    mout_cmu_dnc_busm_p, CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM, 0, 2),
+	MUX(CLK_MOUT_CMU_DNS_BUS, "mout_cmu_dns_bus",
+	    mout_cmu_dns_bus_p, CLK_CON_MUX_MUX_CLKCMU_DNS_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_DPU, "mout_cmu_dpu",
+	    mout_cmu_dpu_p, CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 1),
+	MUX(CLK_MOUT_CMU_DPU_ALT, "mout_cmu_dpu_alt",
+	    mout_cmu_dpu_alt_p, CLK_CON_MUX_MUX_CLKCMU_DPU_ALT, 0, 2),
+	MUX(CLK_MOUT_CMU_DSP_BUS, "mout_cmu_dsp_bus",
+	    mout_cmu_dsp_bus_p, CLK_CON_MUX_MUX_CLKCMU_DSP_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_G2D_G2D, "mout_cmu_g2d_g2d",
+	    mout_cmu_g2d_g2d_p, CLK_CON_MUX_MUX_CLKCMU_G2D_G2D, 0, 2),
+	MUX(CLK_MOUT_CMU_G2D_MSCL, "mout_cmu_g2d_mscl",
+	    mout_cmu_g2d_mscl_p, CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL, 0, 1),
+	MUX(CLK_MOUT_CMU_HPM, "mout_cmu_hpm",
+	    mout_cmu_hpm_p, CLK_CON_MUX_MUX_CLKCMU_HPM, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_BUS, "mout_cmu_hsi0_bus",
+	    mout_cmu_hsi0_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI0_DPGTC, "mout_cmu_hsi0_dpgtc",
+	    mout_cmu_hsi0_dpgtc_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_USB31DRD, "mout_cmu_hsi0_usb31drd",
+	    mout_cmu_hsi0_usb31drd_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_USBDP_DEBUG, "mout_cmu_hsi0_usbdp_debug",
+	    mout_cmu_hsi0_usbdp_debug_p,
+	    CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_BUS, "mout_cmu_hsi1_bus",
+	    mout_cmu_hsi1_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_HSI1_MMC_CARD, "mout_cmu_hsi1_mmc_card",
+	    mout_cmu_hsi1_mmc_card_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_PCIE, "mout_cmu_hsi1_pcie",
+	    mout_cmu_hsi1_pcie_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI1_UFS_CARD, "mout_cmu_hsi1_ufs_card",
+	    mout_cmu_hsi1_ufs_card_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_UFS_EMBD, "mout_cmu_hsi1_ufs_embd",
+	    mout_cmu_hsi1_ufs_embd_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_HSI2_BUS, "mout_cmu_hsi2_bus",
+	    mout_cmu_hsi2_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI2_PCIE, "mout_cmu_hsi2_pcie",
+	    mout_cmu_hsi2_pcie_p, CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE, 0, 1),
+	MUX(CLK_MOUT_CMU_IPP_BUS, "mout_cmu_ipp_bus",
+	    mout_cmu_ipp_bus_p, CLK_CON_MUX_MUX_CLKCMU_IPP_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_ITP_BUS, "mout_cmu_itp_bus",
+	    mout_cmu_itp_bus_p, CLK_CON_MUX_MUX_CLKCMU_ITP_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_MCSC_BUS, "mout_cmu_mcsc_bus",
+	    mout_cmu_mcsc_bus_p, CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_MCSC_GDC, "mout_cmu_mcsc_gdc",
+	    mout_cmu_mcsc_gdc_p, CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC, 0, 3),
+	MUX(CLK_MOUT_CMU_CMU_BOOST_CPU, "mout_cmu_cmu_boost_cpu",
+	    mout_cmu_cmu_boost_cpu_p, CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_MFC0_MFC0, "mout_cmu_mfc0_mfc0",
+	    mout_cmu_mfc0_mfc0_p, CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0, 0, 2),
+	MUX(CLK_MOUT_CMU_MFC0_WFD, "mout_cmu_mfc0_wfd",
+	    mout_cmu_mfc0_wfd_p, CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD, 0, 2),
+	MUX(CLK_MOUT_CMU_MIF_BUSP, "mout_cmu_mif_busp",
+	    mout_cmu_mif_busp_p, CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP, 0, 2),
+	MUX(CLK_MOUT_CMU_MIF_SWITCH, "mout_cmu_mif_switch",
+	    mout_cmu_mif_switch_p, CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH, 0, 3),
+	MUX(CLK_MOUT_CMU_NPU_BUS, "mout_cmu_npu_bus",
+	    mout_cmu_npu_bus_p, CLK_CON_MUX_MUX_CLKCMU_NPU_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_PERIC0_BUS, "mout_cmu_peric0_bus",
+	    mout_cmu_peric0_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC0_IP, "mout_cmu_peric0_ip",
+	    mout_cmu_peric0_ip_p, CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC1_BUS, "mout_cmu_peric1_bus",
+	    mout_cmu_peric1_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC1_IP, "mout_cmu_peric1_ip",
+	    mout_cmu_peric1_ip_p, CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIS_BUS, "mout_cmu_peris_bus",
+	    mout_cmu_peris_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_SSP_BUS, "mout_cmu_ssp_bus",
+	    mout_cmu_ssp_bus_p, CLK_CON_MUX_MUX_CLKCMU_SSP_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_TNR_BUS, "mout_cmu_tnr_bus",
+	    mout_cmu_tnr_bus_p, CLK_CON_MUX_MUX_CLKCMU_TNR_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_VRA_BUS, "mout_cmu_vra_bus",
+	    mout_cmu_vra_bus_p, CLK_CON_MUX_MUX_CLKCMU_VRA_BUS, 0, 2),
+};
+
+static const struct samsung_div_clock top_div_clks[] __initconst = {
+	/* SHARED0 region*/
+	DIV(CLK_DOUT_CMU_SHARED0_DIV2, "dout_cmu_shared0_div2", "mout_pll_shared0",
+	    CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED0_DIV3, "dout_cmu_shared0_div3", "mout_pll_shared0",
+	    CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED0_DIV4, "dout_cmu_shared0_div4", "dout_cmu_shared0_div2",
+	    CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
+
+	/* SHARED1 region*/
+	DIV(CLK_DOUT_CMU_SHARED1_DIV2, "dout_cmu_shared1_div2", "mout_pll_shared1",
+	    CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED1_DIV3, "dout_cmu_shared1_div3", "mout_pll_shared1",
+	    CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED1_DIV4, "dout_cmu_shared1_div4", "dout_cmu_shared1_div2",
+	    CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
+
+	/* SHARED2 region */
+	DIV(CLK_DOUT_CMU_SHARED2_DIV2, "dout_cmu_shared2_div2", "mout_pll_shared2",
+	    CLK_CON_DIV_PLL_SHARED2_DIV2, 0, 1),
+
+	/* SHARED4 region*/
+	DIV(CLK_DOUT_CMU_SHARED4_DIV2, "dout_cmu_shared4_div2", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED4_DIV3, "dout_cmu_shared4_div3", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED4_DIV4, "dout_cmu_shared4_div4", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV4, 0, 1),
+
+	DIV(CLK_DOUT_CMU_APM_BUS, "dout_cmu_apm_bus", "gout_cmu_apm_bus",
+	    CLK_CON_DIV_CLKCMU_APM_BUS, 0, 3),
+	DIV(CLK_DOUT_CMU_AUD_CPU, "dout_cmu_aud_cpu", "gout_cmu_aud_cpu",
+	    CLK_CON_DIV_CLKCMU_AUD_CPU, 0, 3),
+	DIV(CLK_DOUT_CMU_BUS0_BUS, "dout_cmu_bus0_bus", "gout_cmu_bus0_bus",
+	    CLK_CON_DIV_CLKCMU_BUS0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_BUS1_BUS, "dout_cmu_bus1_bus", "gout_cmu_bus1_bus",
+	    CLK_CON_DIV_CLKCMU_BUS1_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_BUS1_SSS, "dout_cmu_bus1_sss", "gout_cmu_bus1_sss",
+	    CLK_CON_DIV_CLKCMU_BUS1_SSS, 0, 4),
+	DIV(CLK_DOUT_CMU_CIS_CLK0, "dout_cmu_cis_clk0", "gout_cmu_cis_clk0",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK0, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK1, "dout_cmu_cis_clk1", "gout_cmu_cis_clk1",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK1, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK2, "dout_cmu_cis_clk2", "gout_cmu_cis_clk2",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK2, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK3, "dout_cmu_cis_clk3", "gout_cmu_cis_clk3",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK3, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK4, "dout_cmu_cis_clk4", "gout_cmu_cis_clk4",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK4, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK5, "dout_cmu_cis_clk5", "gout_cmu_cis_clk5",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK5, 0, 5),
+	DIV(CLK_DOUT_CMU_CMU_BOOST, "dout_cmu_cmu_boost", "mout_cmu_cmu_boost",
+	    CLK_CON_DIV_CLKCMU_CMU_BOOST, 0, 2),
+	DIV(CLK_DOUT_CMU_CORE_BUS, "dout_cmu_core_bus", "gout_cmu_core_bus",
+	    CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_CPUCL0_DBG_BUS, "dout_cmu_cpucl0_debug",
+	    "gout_cmu_cpucl0_dbg_bus", CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL0_SWITCH, "dout_cmu_cpucl0_switch",
+	    "gout_cmu_cpucl0_switch", CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL1_SWITCH, "dout_cmu_cpucl1_switch",
+	    "gout_cmu_cpucl1_switch", CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL2_BUSP, "dout_cmu_cpucl2_busp",
+	    "gout_cmu_cpucl2_busp", CLK_CON_DIV_CLKCMU_CPUCL2_BUSP, 0, 4),
+	DIV(CLK_DOUT_CMU_CPUCL2_SWITCH, "dout_cmu_cpucl2_switch",
+	    "gout_cmu_cpucl2_switch", CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CSIS_BUS, "dout_cmu_csis_bus", "gout_cmu_csis_bus",
+	    CLK_CON_DIV_CLKCMU_CSIS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_CSIS_OIS_MCU, "dout_cmu_csis_ois_mcu",
+	    "gout_cmu_csis_ois_mcu", CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU, 0, 4),
+	DIV(CLK_DOUT_CMU_DNC_BUS, "dout_cmu_dnc_bus", "gout_cmu_dnc_bus",
+	    CLK_CON_DIV_CLKCMU_DNC_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DNC_BUSM, "dout_cmu_dnc_busm", "gout_cmu_dnc_busm",
+	    CLK_CON_DIV_CLKCMU_DNC_BUSM, 0, 4),
+	DIV(CLK_DOUT_CMU_DNS_BUS, "dout_cmu_dns_bus", "gout_cmu_dns_bus",
+	    CLK_CON_DIV_CLKCMU_DNS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DSP_BUS, "dout_cmu_dsp_bus", "gout_cmu_dsp_bus",
+	    CLK_CON_DIV_CLKCMU_DSP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_G2D_G2D, "dout_cmu_g2d_g2d", "gout_cmu_g2d_g2d",
+	    CLK_CON_DIV_CLKCMU_G2D_G2D, 0, 4),
+	DIV(CLK_DOUT_CMU_G2D_MSCL, "dout_cmu_g2d_mscl", "gout_cmu_g2d_mscl",
+	    CLK_CON_DIV_CLKCMU_G2D_MSCL, 0, 4),
+	DIV(CLK_DOUT_CMU_G3D_SWITCH, "dout_cmu_g3d_switch",
+	    "gout_cmu_g3d_switch", CLK_CON_DIV_CLKCMU_G3D_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_HPM, "dout_cmu_hpm", "gout_cmu_hpm",
+	    CLK_CON_DIV_CLKCMU_HPM, 0, 2),
+	DIV(CLK_DOUT_CMU_HSI0_BUS, "dout_cmu_hsi0_bus", "gout_cmu_hsi0_bus",
+	    CLK_CON_DIV_CLKCMU_HSI0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI0_DPGTC, "dout_cmu_hsi0_dpgtc", "gout_cmu_hsi0_dpgtc",
+	    CLK_CON_DIV_CLKCMU_HSI0_DPGTC, 0, 3),
+	DIV(CLK_DOUT_CMU_HSI0_USB31DRD, "dout_cmu_hsi0_usb31drd",
+	    "gout_cmu_hsi0_usb31drd", CLK_CON_DIV_CLKCMU_HSI0_USB31DRD, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI0_USBDP_DEBUG, "dout_cmu_hsi0_usbdp_debug",
+	    "gout_cmu_hsi0_usbdp_debug", CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_HSI1_BUS, "dout_cmu_hsi1_bus", "gout_cmu_hsi1_bus",
+	    CLK_CON_DIV_CLKCMU_HSI1_BUS, 0, 3),
+	DIV(CLK_DOUT_CMU_HSI1_MMC_CARD, "dout_cmu_hsi1_mmc_card",
+	    "gout_cmu_hsi1_mmc_card", CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_HSI1_PCIE, "dout_cmu_hsi1_pcie", "gout_cmu_hsi1_pcie",
+	    CLK_CON_DIV_CLKCMU_HSI1_PCIE, 0, 7),
+	DIV(CLK_DOUT_CMU_HSI1_UFS_CARD, "dout_cmu_hsi1_ufs_card",
+	    "gout_cmu_hsi1_ufs_card", CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_HSI1_UFS_EMBD, "dout_cmu_hsi1_ufs_embd",
+	    "gout_cmu_hsi1_ufs_embd", CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_HSI2_BUS, "dout_cmu_hsi2_bus", "gout_cmu_hsi2_bus",
+	    CLK_CON_DIV_CLKCMU_HSI2_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI2_PCIE, "dout_cmu_hsi2_pcie", "gout_cmu_hsi2_pcie",
+	    CLK_CON_DIV_CLKCMU_HSI2_PCIE, 0, 7),
+	DIV(CLK_DOUT_CMU_IPP_BUS, "dout_cmu_ipp_bus", "gout_cmu_ipp_bus",
+	    CLK_CON_DIV_CLKCMU_IPP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_ITP_BUS, "dout_cmu_itp_bus", "gout_cmu_itp_bus",
+	    CLK_CON_DIV_CLKCMU_ITP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_MCSC_BUS, "dout_cmu_mcsc_bus", "gout_cmu_mcsc_bus",
+	    CLK_CON_DIV_CLKCMU_MCSC_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_MCSC_GDC, "dout_cmu_mcsc_gdc", "gout_cmu_mcsc_gdc",
+	    CLK_CON_DIV_CLKCMU_MCSC_GDC, 0, 4),
+	DIV(CLK_DOUT_CMU_CMU_BOOST_CPU, "dout_cmu_cmu_boost_cpu",
+	    "mout_cmu_cmu_boost_cpu", CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU,
+	    0, 2),
+	DIV(CLK_DOUT_CMU_MFC0_MFC0, "dout_cmu_mfc0_mfc0", "gout_cmu_mfc0_mfc0",
+	    CLK_CON_DIV_CLKCMU_MFC0_MFC0, 0, 4),
+	DIV(CLK_DOUT_CMU_MFC0_WFD, "dout_cmu_mfc0_wfd", "gout_cmu_mfc0_wfd",
+	    CLK_CON_DIV_CLKCMU_MFC0_WFD, 0, 4),
+	DIV(CLK_DOUT_CMU_MIF_BUSP, "dout_cmu_mif_busp", "gout_cmu_mif_busp",
+	    CLK_CON_DIV_CLKCMU_MIF_BUSP, 0, 4),
+	DIV(CLK_DOUT_CMU_NPU_BUS, "dout_cmu_npu_bus", "gout_cmu_npu_bus",
+	    CLK_CON_DIV_CLKCMU_NPU_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC0_BUS, "dout_cmu_peric0_bus", "gout_cmu_peric0_bus",
+	    CLK_CON_DIV_CLKCMU_PERIC0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC0_IP, "dout_cmu_peric0_ip", "gout_cmu_peric0_ip",
+	    CLK_CON_DIV_CLKCMU_PERIC0_IP, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC1_BUS, "dout_cmu_peric1_bus", "gout_cmu_peric1_bus",
+	    CLK_CON_DIV_CLKCMU_PERIC1_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC1_IP, "dout_cmu_peric1_ip", "gout_cmu_peric1_ip",
+	    CLK_CON_DIV_CLKCMU_PERIC1_IP, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIS_BUS, "dout_cmu_peris_bus", "gout_cmu_peris_bus",
+	    CLK_CON_DIV_CLKCMU_PERIS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_SSP_BUS, "dout_cmu_ssp_bus", "gout_cmu_ssp_bus",
+	    CLK_CON_DIV_CLKCMU_SSP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_TNR_BUS, "dout_cmu_tnr_bus", "gout_cmu_tnr_bus",
+	    CLK_CON_DIV_CLKCMU_TNR_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_VRA_BUS, "dout_cmu_vra_bus", "gout_cmu_vra_bus",
+	    CLK_CON_DIV_CLKCMU_VRA_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DPU, "dout_cmu_clkcmu_dpu", "gout_cmu_dpu",
+	    CLK_CON_DIV_DIV_CLKCMU_DPU, 0, 4),
+};
+
+static const struct samsung_gate_clock top_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CMU_APM_BUS, "gout_cmu_apm_bus", "mout_cmu_apm_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_APM_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_AUD_CPU, "gout_cmu_aud_cpu", "mout_cmu_aud_cpu",
+	     CLK_CON_GAT_GATE_CLKCMU_AUD_CPU, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_BUS0_BUS, "gout_cmu_bus0_bus", "mout_cmu_bus0_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_BUS1_BUS, "gout_cmu_bus1_bus", "mout_cmu_bus1_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_BUS1_SSS, "gout_cmu_bus1_sss", "mout_cmu_bus1_sss",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK0, "gout_cmu_cis_clk0", "mout_cmu_cis_clk0",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK1, "gout_cmu_cis_clk1", "mout_cmu_cis_clk1",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK2, "gout_cmu_cis_clk2", "mout_cmu_cis_clk2",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK3, "gout_cmu_cis_clk3", "mout_cmu_cis_clk3",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK4, "gout_cmu_cis_clk4", "mout_cmu_cis_clk4",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK5, "gout_cmu_cis_clk5", "mout_cmu_cis_clk5",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CORE_BUS, "gout_cmu_core_bus", "mout_cmu_core_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_DBG_BUS, "gout_cmu_cpucl0_dbg_bus",
+	     "mout_cmu_cpucl0_dbg_bus", CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_SWITCH, "gout_cmu_cpucl0_switch",
+	     "mout_cmu_cpucl0_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL1_SWITCH, "gout_cmu_cpucl1_switch",
+	     "mout_cmu_cpucl1_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL2_BUSP, "gout_cmu_cpucl2_busp",
+	     "mout_cmu_cpucl2_busp", CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL2_SWITCH, "gout_cmu_cpucl2_switch",
+	     "mout_cmu_cpucl2_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CSIS_BUS, "gout_cmu_csis_bus", "mout_cmu_csis_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CSIS_OIS_MCU, "gout_cmu_csis_ois_mcu",
+	     "mout_cmu_csis_ois_mcu", CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNC_BUS, "gout_cmu_dnc_bus", "mout_cmu_dnc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DNC_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNC_BUSM, "gout_cmu_dnc_busm", "mout_cmu_dnc_busm",
+	     CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNS_BUS, "gout_cmu_dns_bus", "mout_cmu_dns_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DNS_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU, "gout_cmu_dpu", "mout_cmu_dpu",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_BUS, "gout_cmu_dpu_bus", "mout_cmu_dpu_alt",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_DSP_BUS, "gout_cmu_dsp_bus", "mout_cmu_dsp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DSP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G2D_G2D, "gout_cmu_g2d_g2d", "mout_cmu_g2d_g2d",
+	     CLK_CON_GAT_GATE_CLKCMU_G2D_G2D, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G2D_MSCL, "gout_cmu_g2d_mscl", "mout_cmu_g2d_mscl",
+	     CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G3D_SWITCH, "gout_cmu_g3d_switch",
+	     "fout_shared2_pll", CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HPM, "gout_cmu_hpm", "mout_cmu_hpm",
+	     CLK_CON_GAT_GATE_CLKCMU_HPM, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_BUS, "gout_cmu_hsi0_bus",
+	     "mout_cmu_hsi0_bus", CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_DPGTC, "gout_cmu_hsi0_dpgtc",
+	     "mout_cmu_hsi0_dpgtc", CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_USB31DRD, "gout_cmu_hsi0_usb31drd",
+	     "mout_cmu_hsi0_usb31drd", CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_USBDP_DEBUG, "gout_cmu_hsi0_usbdp_debug",
+	     "mout_cmu_hsi0_usbdp_debug", CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_BUS, "gout_cmu_hsi1_bus", "mout_cmu_hsi1_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_MMC_CARD, "gout_cmu_hsi1_mmc_card",
+	     "mout_cmu_hsi1_mmc_card", CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_PCIE, "gout_cmu_hsi1_pcie",
+	     "mout_cmu_hsi1_pcie", CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_UFS_CARD, "gout_cmu_hsi1_ufs_card",
+	     "mout_cmu_hsi1_ufs_card", CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_UFS_EMBD, "gout_cmu_hsi1_ufs_embd",
+	     "mout_cmu_hsi1_ufs_embd", CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI2_BUS, "gout_cmu_hsi2_bus", "mout_cmu_hsi2_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI2_PCIE, "gout_cmu_hsi2_pcie",
+	     "mout_cmu_hsi2_pcie", CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_IPP_BUS, "gout_cmu_ipp_bus", "mout_cmu_ipp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_IPP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_ITP_BUS, "gout_cmu_itp_bus", "mout_cmu_itp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_ITP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MCSC_BUS, "gout_cmu_mcsc_bus", "mout_cmu_mcsc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MCSC_GDC, "gout_cmu_mcsc_gdc", "mout_cmu_mcsc_gdc",
+	     CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MFC0_MFC0, "gout_cmu_mfc0_mfc0",
+	     "mout_cmu_mfc0_mfc0", CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MFC0_WFD, "gout_cmu_mfc0_wfd", "mout_cmu_mfc0_wfd",
+	     CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MIF_BUSP, "gout_cmu_mif_busp", "mout_cmu_mif_busp",
+	     CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_NPU_BUS, "gout_cmu_npu_bus", "mout_cmu_npu_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_NPU_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC0_BUS, "gout_cmu_peric0_bus",
+	     "mout_cmu_peric0_bus", CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC0_IP, "gout_cmu_peric0_ip",
+	     "mout_cmu_peric0_ip", CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC1_BUS, "gout_cmu_peric1_bus",
+	     "mout_cmu_peric1_bus", CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC1_IP, "gout_cmu_peric1_ip",
+	     "mout_cmu_peric1_ip", CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIS_BUS, "gout_cmu_peris_bus",
+	     "mout_cmu_peris_bus", CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_SSP_BUS, "gout_cmu_ssp_bus", "mout_cmu_ssp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_SSP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_TNR_BUS, "gout_cmu_tnr_bus", "mout_cmu_tnr_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_TNR_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_VRA_BUS, "gout_cmu_vra_bus", "mout_cmu_vra_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_VRA_BUS, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info top_cmu_info __initconst = {
+	.pll_clks = top_pll_clks,
+	.nr_pll_clks = ARRAY_SIZE(top_pll_clks),
+	.mux_clks = top_mux_clks,
+	.nr_mux_clks = ARRAY_SIZE(top_mux_clks),
+	.div_clks = top_div_clks,
+	.nr_div_clks = ARRAY_SIZE(top_div_clks),
+	.gate_clks = top_gate_clks,
+	.nr_gate_clks = ARRAY_SIZE(top_gate_clks),
+	.nr_clk_ids = CLKS_NR_TOP,
+	.clk_regs = top_clk_regs,
+	.nr_clk_regs = ARRAY_SIZE(top_clk_regs),
+};
+
+static void __init exynos990_cmu_top_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
+}
+
+/* Register CMU_TOP early, as it's a dependency for other early domains */
+CLK_OF_DECLARE(exynos990_cmu_top, "samsung,exynos990-cmu-top",
+	       exynos990_cmu_top_init);
+
+/* ---- CMU_HSI0 ------------------------------------------------------------ */
+
+/* Register Offset definitions for CMU_HSI0 (0x10a00000) */
+#define PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER						0x0600
+#define PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER						0x0620
+#define PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER					0x0630
+#define PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER						0x0610
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK			0x2004
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK			0x2018
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHS_ACEL_D_HSI0_IPCLKPORT_I_CLK			0x2014
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK		0x2020
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK			0x2044
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK				0x2008
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK			0x200c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK			0x2010
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK			0x201c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2			0x2024
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK			0x2028
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL			0x202c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40		0x2034
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK	0x203c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK		0x2040
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY			0x2030
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK			0x2000
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK				0x2048
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL		0x2038
+
+static const unsigned long hsi0_clk_regs[] __initconst = {
+	PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHS_ACEL_D_HSI0_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK,
+};
+
+PNAME(mout_hsi0_bus_user_p)		= { "oscclk", "dout_cmu_hsi0_bus" };
+PNAME(mout_hsi0_usb31drd_user_p)	= { "oscclk", "dout_cmu_hsi0_usb31drd" };
+PNAME(mout_hsi0_usbdp_debug_user_p)	= { "oscclk",
+					    "dout_cmu_hsi0_usbdp_debug" };
+PNAME(mout_hsi0_dpgtc_user_p)		= { "oscclk", "dout_cmu_hsi0_dpgtc" };
+
+static const struct samsung_mux_clock hsi0_mux_clks[] __initconst = {
+	MUX(CLK_MOUT_HSI0_BUS_USER, "mout_hsi0_bus_user",
+	    mout_hsi0_bus_user_p, PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_USB31DRD_USER, "mout_hsi0_usb31drd_user",
+	    mout_hsi0_usb31drd_user_p, PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_USBDP_DEBUG_USER, "mout_hsi0_usbdp_debug_user",
+	    mout_hsi0_usbdp_debug_user_p,
+	    PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_DPGTC_USER, "mout_hsi0_dpgtc_user",
+	    mout_hsi0_dpgtc_user_p, PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER,
+	    4, 1),
+};
+
+static const struct samsung_gate_clock hsi0_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_HSI0_DP_LINK_DP_GTC_CLK,
+	     "gout_hsi0_dp_link_dp_gtc_clk", "mout_hsi0_dpgtc_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_DP_LINK_PCLK,
+	     "gout_hsi0_dp_link_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK,
+	     "gout_hsi0_d_tzpc_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_LHM_AXI_P_HSI0_CLK,
+	     "gout_hsi0_lhm_axi_p_hsi0_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK,
+	     21, CLK_IS_CRITICAL, 0),
+	GATE(CLK_GOUT_HSI0_PPMU_HSI0_BUS1_ACLK,
+	     "gout_hsi0_ppmu_hsi0_bus1_aclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_PPMU_HSI0_BUS1_PCLK,
+	     "gout_hsi0_ppmu_hsi0_bus1_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK,
+	     "gout_hsi0_clk_hsi0_bus_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2,
+	     "gout_hsi0_sysmmu_usb_clk_s2", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_HSI0_SYSREG_HSI0_PCLK,
+	     "gout_hsi0_sysreg_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL,
+	     "gout_hsi0_usb31drd_aclk_phyctrl", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY,
+	     "gout_hsi0_usb31drd_bus_clk_early",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USB31DRD_REF_CLK_40,
+	     "gout_hsi0_usb31drd_usb31drd_ref_clk_40",
+	     "mout_hsi0_usb31drd_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBDPPHY_REF_SOC_PLL,
+	     "gout_hsi0_usb31drd_usbdpphy_ref_soc_pll",
+	     "mout_hsi0_usbdp_debug_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBDPPHY_SCL_APB,
+	     "gout_hsi0_usb31drd_ipclkport_i_usbdpphy_scl_apb_pclk",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBPCS_APB_CLK,
+	     "gout_hsi0_usb31drd_usbpcs_apb_clk",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_VGEN_LITE_HSI0_CLK,
+	     "gout_hsi0_vgen_lite_ipclkport_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_CMU_HSI0_PCLK,
+	     "gout_hsi0_cmu_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_HSI0_XIU_D_HSI0_ACLK,
+	     "gout_hsi0_xiu_d_hsi0_aclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info hsi0_cmu_info __initconst = {
+	.mux_clks = hsi0_mux_clks,
+	.nr_mux_clks = ARRAY_SIZE(hsi0_mux_clks),
+	.gate_clks = hsi0_gate_clks,
+	.nr_gate_clks = ARRAY_SIZE(hsi0_gate_clks),
+	.nr_clk_ids = CLKS_NR_HSI0,
+	.clk_regs = hsi0_clk_regs,
+	.nr_clk_regs = ARRAY_SIZE(hsi0_clk_regs),
+	.clk_name		= "bus",
+};
+
+/* ----- platform_driver ----- */
+
+static int __init exynos990_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+static const struct of_device_id exynos990_cmu_of_match[] = {
+	{
+		.compatible = "samsung,exynos990-cmu-hsi0",
+		.data = &hsi0_cmu_info,
+	},
+	{ },
+};
+
+static struct platform_driver exynos990_cmu_driver __refdata = {
+	.driver	= {
+		.name = "exynos990-cmu",
+		.of_match_table = exynos990_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = exynos990_cmu_probe,
+};
+
+static int __init exynos990_cmu_init(void)
+{
+	return platform_driver_register(&exynos990_cmu_driver);
+}
+
+core_initcall(exynos990_cmu_init);

-- 
2.45.2



From linux at armlinux.org.uk  Sat Dec  7 02:13:14 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sat, 7 Dec 2024 10:13:14 +0000
Subject: [PATCH net-next v1] net: stmmac: Move extern declarations from
 common.h to hwif.h
In-Reply-To: <20241207070248.4049877-1-0x1207@gmail.com>
References: <20241207070248.4049877-1-0x1207@gmail.com>
Message-ID: <Z1QfupFfg07jTMUc@shell.armlinux.org.uk>

On Sat, Dec 07, 2024 at 03:02:48PM +0800, Furong Xu wrote:
> These extern declarations are referenced in hwif.c only.
> Move them to hwif.h just like the other extern declarations.

We normally have declarations in a header file that corresponds to their
definition, rather than where they are used.

> Compile tested only.
> No functional change intended.
> 
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/common.h | 14 --------------
>  drivers/net/ethernet/stmicro/stmmac/hwif.h   | 14 ++++++++++++++
>  2 files changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 1367fa5c9b8e..fbcf07d201cf 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -543,18 +543,8 @@ struct dma_features {
>  #define STMMAC_VLAN_INSERT	0x2
>  #define STMMAC_VLAN_REPLACE	0x3
>  
> -extern const struct stmmac_desc_ops enh_desc_ops;

Defined in enh_desc.c, but no header for it, so either common.h or
hwif.h seems sensible.

> -extern const struct stmmac_desc_ops ndesc_ops;

Defined in norm_desc.c, same situation as previous one.

> -
>  struct mac_device_info;
>  
> -extern const struct stmmac_hwtimestamp stmmac_ptp;

Defined in stmmac_hwtstamp.c, same as above.

> -extern const struct stmmac_hwtimestamp dwmac1000_ptp;

Ditto.

> -extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;

Defined in dwmac4_descs.c, maybe dwmac4_descs.h or dwmac4.h would make
more sense than hwif.c ?

> -
> -extern const struct ptp_clock_info stmmac_ptp_clock_ops;

Defined in stmmac_ptp.c, and there is stmmac_ptp.h which contains a
number of function declarations, so maybe moving that there would
make more sense?

> -extern const struct ptp_clock_info dwmac1000_ptp_clock_ops;

Same as stmmac_ptp_clock_ops.

> -
>  struct mac_link {
>  	u32 caps;
>  	u32 speed_mask;
> @@ -641,8 +631,4 @@ void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable);
>  
>  void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
>  
> -extern const struct stmmac_mode_ops ring_mode_ops;

Defined in ring_mode.c, same as enh_desc_ops.

> -extern const struct stmmac_mode_ops chain_mode_ops;

Defined in chain_mode.c, same as enh_desc_ops.

> -extern const struct stmmac_desc_ops dwmac4_desc_ops;

Defined in dwmac4_descs.c, similar situation to dwmac4_ring_mode_ops
above.


So I think rather than bulk moving these to hwif.h, where some of them
remain out of place, maybe placing some in a more appropriate header
would be better.

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


From mailhol.vincent at wanadoo.fr  Thu Dec  5 07:25:34 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 00:25:34 +0900
Subject: [PATCH 01/10] compiler.h: add statically_false()
In-Reply-To: <e115a4245e5342a994a7e596cc6357fa@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-1-4e4cbaecc216@wanadoo.fr> <e115a4245e5342a994a7e596cc6357fa@AcuMS.aculab.com>
Message-ID: <CAMZ6Rq+n0vG9zObF-kY-Xo+iP_Y3P8A6_nEfB8F=UhqeQBepRw@mail.gmail.com>

On Thu. 5 Dec 2024 at 03:30, David Laight <David.Laight at aculab.com> wrote:
> From: Vincent Mailhol
> > Sent: 02 December 2024 17:33
> >
> > From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
> >
> > For completion, add statically_false() which is the equivalent of
> > statically_true() except that it will return true only if the input is
> > known to be false at compile time.
>
> This is pretty much pointless.
> It is just as easy to invert the condition at the call site.

To start with, I will argue that:

  statically_false(foo)

is more pretty than

  statically_true(!(foo))

In addition, the simple negation !(foo) only works if foo is a
boolean. If it is an integer, you would get the -Wint-in-bool-context
warning. Thus you would have to write:

  statically_true((foo) == 0)

Anyone using this in a global header basically does not know what type
of argument they are getting. So, the (foo) == 0 trick is a must. But
because it is ugly, better to encapsulate it once for all. The
statically_false() is just cleaner and less error prone.

That said, I am not strongly opposed to removing statically_false(),
but in that case, I would also remove is_const_false(). For me, these
come as a pair, either we have both or we have none. Only having one
of these looked unbalanced.


Yours sincerely,
Vincent Mailhol


From David.Laight at ACULAB.COM  Sat Dec  7 02:33:56 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sat, 7 Dec 2024 10:33:56 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
Message-ID: <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>

From: Martin Uecker
> Sent: 07 December 2024 08:40
...
> I find it amazing how much time the Linux kernel community spends
> revising code to make it work perfectly.
> 
> Still, I am wondering whether some of this time and effort should not
> be targeted at C compilers and language work to make these macro
> hacks unnecessary?

I'm probably not alone in thinking that sometimes the compiler writers
are doing their hardest to make life hard for people writing low level code.

> I already found the original motivation for these macros very questionable.
> Removing VLAs at the cost having imprecise worst-case bounds strikes
> me as fundamentally misguided - at least if security is the motivation.

VLA basically cannot be allowed because of the very limited stack space.
Even the per-frame limits aren't a real solution - they just catch the
places that most likely to cause issues. Very deep call chains and any
recursion (that isn't tightly bounded) can cause grief.

> So maybe there are other good reasons for this, e.g. bad code
> for VLAs or risk of jumping the guard page if the attacker can somehow
> influence its size (but for this there is -Wvla-larger-than). But even then,
> wouldn't it be a more worthwhile and interesting investment of engineering
> resources to improving code generation / warnings at the compiler level?

This is kernel code, any access into a stack guard page is basically
unrecoverable for the entire system - a kernel lock/mutex could be held.

With a list of (calling_fn, called_fn, stack_offset) it is possible
calculate an accurate maximum stack usage.
Indirect calls would need to use the (IIRC) FINE_IBT hashes to identify
the possible functions (and I'm not sure than has an attribute for a 'seed'
so that 'int (*)(void *)' functions can be separated into groups.
I've not looked at whether objtool could generate the output - but is has
to be easier for the compiler to do it.

I have done that calculation in the past (parsing a compiler listing file)
and basically discovered the system didn't actually have enough memory
to allocate 'safe' stacks! The max stack was pretty much always (the
equivalent of) printf() inside an error path that never happens.
It might be interesting to see how bad linux is (after sorting out
how to handle recursive calls - hopefully there won't be too many
unexpected ones.

> Also the fortification of strlen and co seems something which could be
> much better solved with annotations and proper compiler support.

That might be nice, but kernel have to be buildable with relatively
old compilers.

Some things might need language/ABI changes to better handle ptr+size.
The ability to return such a pair in registers would probably be useful
(without doing horrid games with a union and __int128).

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From 0x1207 at gmail.com  Sat Dec  7 02:39:00 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Sat, 7 Dec 2024 18:39:00 +0800
Subject: [PATCH net-next v1] net: stmmac: Move extern declarations from
 common.h to hwif.h
In-Reply-To: <Z1QfupFfg07jTMUc@shell.armlinux.org.uk>
References: <20241207070248.4049877-1-0x1207@gmail.com>
	<Z1QfupFfg07jTMUc@shell.armlinux.org.uk>
Message-ID: <20241207183900.00001fad@gmail.com>

On Sat, 7 Dec 2024 10:13:14 +0000, "Russell King (Oracle)" <linux at armlinux.org.uk> wrote:

> 
> So I think rather than bulk moving these to hwif.h, where some of them
> remain out of place, maybe placing some in a more appropriate header
> would be better.
> 

Totally agree.
I am going to rework this patch into a bigger one.

pw-bot: changes-requested


From David.Laight at ACULAB.COM  Sat Dec  7 03:19:05 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sat, 7 Dec 2024 11:19:05 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>
 <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
 <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
Message-ID: <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 07 December 2024 07:43
...
> > So maybe the slightly long lines:
> > #define const_true(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 1L) : (char *)0, char *: 1, void *: 0)
> > #define const_expr(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 0L) : (char *)0, char *: 1, void *: 0)

Clearly they can be implemented in terms of a common define.
But I don't see a need for a const_zero() and nested expansions make extra
work for the compiler.

> 
> This still throws a -Wnull-pointer-arithmetic on clang on const_expr(NULL):
>   https://godbolt.org/z/vo5W7efdE

I was worried about that one.

> I just do not see a method to silence that one. So three options:
> 
>   1. is_const() does not accept pointers and throws a constraint violation:
>        #define is_const(x) __is_const_zero(0 * (x))
>      This is my current patch.

Is that going to affect things like const_true(x << y)?
Disallowing that seems counter-productive.
(Remember it might be passed into a #define that is then
checking its argument for being constant.)

>   2. is_const() accept pointers but is_const(NULL) returns false:
>        #define is_const(x) __is_const_zero((x) != (x))
>      This keeps the current __is_constexpr() behaviour.

No good - expands everything twice.

>   3. is_const() accepts pointers and is_const(NULL) return true:
> 
>        #define const_expr(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 0L)
> : (char *)0, char *: 1, void *: 0)
> 
>      David's latest proposal, it requires to remove the
>      -Wnull-pointer-arithmetic clang warning.

Only for const_expr(NULL) - and since clang gets that wrong
maybe the warning is a good thing.

You can just add:
#define const_NULL(ptr) const_true(!(ptr))
Probably the only place where you actually want to test for zero.

> 
> I vote for 1. or 2. (with a preference for 1.). IMHO, we are just
> adding an unreasonable level of complexity for making the macro treat
> NULL as an integer. Would someone find a solution for 3. that does not
> yield a warning, then why not. But if we have to remove a compiler
> check for a theoretical use case that does not even exist in the
> kernel, then it is not worth the trade off.
> 
> Concerning is_const(var << 2), the patch I submitted works fine as-is
> with all scalars including that (var << 2):
> 
>   https://godbolt.org/z/xer4aMees
> 
> And can we ignore the case (!(var << 2))? This is not a warning
> because of the macro, but because of the caller! If I do any of:
> 
>           if (!(var << 2)) {}
>           (void)__builtin_constant_p(!(var << 2));
> 
> I also got the warning. The point is that the macro should not
> generate *new* warnings. If the given argument already raises a
> warning, it is the caller's responsibility to fix.

Except it could easily happen way inside some other expansion.
Perhaps someone optimises frobnicate(x) for constant input.
Suddenly frobnicate(!(var << 2)) generates a compile error.

	David

> 
> 
> Yours sincerely,
> Vincent Mailhol

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From ansuelsmth at gmail.com  Sat Dec  7 04:11:23 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sat, 7 Dec 2024 13:11:23 +0100
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241205235709.pa5shi7mh26cnjhn@skbuf>
References: <20241205145142.29278-1-ansuelsmth@gmail.com>
 <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <20241205180539.6t5iz2m3wjjwyxp3@skbuf>
 <6751f125.5d0a0220.255b79.7be0@mx.google.com>
 <20241205185037.g6cqejgad5jamj7r@skbuf>
 <675200c3.7b0a0220.236ac3.9edf@mx.google.com>
 <20241205235709.pa5shi7mh26cnjhn@skbuf>
Message-ID: <67543b6f.df0a0220.3bd32.6d5d@mx.google.com>

On Fri, Dec 06, 2024 at 01:57:09AM +0200, Vladimir Oltean wrote:
> On Thu, Dec 05, 2024 at 08:36:30PM +0100, Christian Marangi wrote:
> > > I guess the non-hack solution would be to permit MDIO buses to have
> > > #size-cells = 1, and MDIO devices to acquire a range of the address
> > > space, rather than just one address. Though take this with a grain of
> > > salt, I have a lot more to learn.
> > 
> > I remember this was an idea when PHY Package API were proposed and was
> > rejected as we wanted PHY to be single reg.
> 
> Would that effort have helped with MDIO devices, in the way it was proposed?
> Why did it die out?
> 
> > > If neither of those are options, in principle the hack with just
> > > selecting, randomly, one of the N internal PHY addresses as the central
> > > MDIO address should work equally fine regardless of whether we are
> > > talking about the DSA switch's MDIO address here, or the MFD device's
> > > MDIO address.
> > > 
> > > With MFD you still have the option of creating a fake MDIO controller
> > > child device, which has mdio-parent-bus = <&host_bus>, and redirecting
> > > all user port phy-handles to children of this bus. Since all regmap I/O
> > > of this fake MDIO bus goes to the MFD driver, you can implement there
> > > your hacks with page switching etc etc, and it should be equally
> > > safe.
> > 
> > I wonder if a node like this would be more consistent and descriptive?
> > 
> > mdio_bus: mdio-bus {
> >     #address-cells = <1>;
> >     #size-cells = <0>;
> > 
> >     ...
> > 
> >     mfd at 1 {
> >             compatible = "airoha,an8855-mfd";
> >             reg = <1>;
> > 
> >             nvmem_node {
> >                     ...
> >             };
> > 
> >             switch_node {
> >                 ports {
> >                         port at 0 {
> >                                 phy-handle = <&phy>;
> >                         };
> > 
> >                         port at 1 {
> >                                 phy-handle = <&phy_2>;
> >                         }
> >                 };
> >             };
> > 
> >             phy: phy_node {
> > 
> >             };
> >     };
> > 
> >     phy_2: phy at 2 {
> >         reg = <2>;
> >     }
> > 
> >     phy at 3 {
> >         reg = <3>;
> >     }
> > 
> >     ..
> > };
> > 
> > No idea how to register that single phy in mfd... I guess a fake mdio is
> > needed anyway... What do you think of this node example? Or not worth it
> > and better have the fake MDIO with all the switch PHY in it?
> 
> Could you work with something like this? dtc seems to swallow it without
> any warnings...
> 
> mdio_bus: mdio {
>         #address-cells = <1>;
>         #size-cells = <0>;
> 
>         soc at 1 {
>                 compatible = "airoha,an8855";
>                 reg = <1>, <2>, <3>, <4>;
>                 reg-names = "phy0", "phy1", "phy2", "phy3";
> 
>                 nvmem {
>                         compatible = "airoha,an8855-nvmem";
>                 };
> 
>                 ethernet-switch {
>                         compatible = "airoha,an8855-switch";
> 
>                         ethernet-ports {
>                                 #address-cells = <1>;
>                                 #size-cells = <0>;
> 
>                                 ethernet-port at 0 {
>                                         reg = <0>;
>                                         phy-handle = <&phy0>;
>                                         phy-mode = "internal";
>                                 };
> 
>                                 ethernet-port at 1 {
>                                         reg = <1>;
>                                         phy-handle = <&phy1>;
>                                         phy-mode = "internal";
>                                 };
> 
>                                 ethernet-port at 2 {
>                                         reg = <2>;
>                                         phy-handle = <&phy2>;
>                                         phy-mode = "internal";
>                                 };
> 
>                                 ethernet-port at 3 {
>                                         reg = <3>;
>                                         phy-handle = <&phy3>;
>                                         phy-mode = "internal";
>                                 };
>                         };
>                 };
> 
>                 mdio {
>                         compatible = "airoha,an8855-mdio";
>                         mdio-parent-bus = <&host_mdio>;
>                         #address-cells = <1>;
>                         #size-cells = <0>;
> 
>                         phy0: ethernet-phy at 1 {
>                                 reg = <1>;
>                         };
> 
>                         phy1: ethernet-phy at 2 {
>                                 reg = <2>;
>                         };
> 
>                         phy2: ethernet-phy at 3 {
>                                 reg = <3>;
>                         };
> 
>                         phy3: ethernet-phy at 4 {
>                                 reg = <4>;
>                         };
>                 };
>         };
> };

I finished testing and this works, I'm not using mdio-parent-bus tho as
the mdio-mux driver seems overkill for the task and problematic for PAGE
handling. (mdio-mux doesn't provide a way to give the current addr that
is being accessed)

My big concern is dt_binding_check and how Rob might take this
implementation. We recently had another case with a MFD node and Rob
found some problems in having subnode with compatible but maybe for this
particular complex case it will be O.K.

Still have to check if it's ok to have multiple reg in the mfd root node
(for mdio schema)

-- 
	Ansuel


From vincent.mailhol at gmail.com  Sat Dec  7 04:24:16 2024
From: vincent.mailhol at gmail.com (Vincent Mailhol)
Date: Sat, 7 Dec 2024 21:24:16 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com> <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com> <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
 <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com> <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com>
Message-ID: <CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>

On Sat. 7 Dec. 2024 at 20:19, David Laight <David.Laight at aculab.com> wrote:
> From: Vincent Mailhol
> > Sent: 07 December 2024 07:43
> ...
> > > So maybe the slightly long lines:
> > > #define const_true(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 1L) : (char *)0, char *: 1, void *: 0)
> > > #define const_expr(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 0L) : (char *)0, char *: 1, void *: 0)
>
> Clearly they can be implemented in terms of a common define.
> But I don't see a need for a const_zero() and nested expansions make extra
> work for the compiler.
>
> >
> > This still throws a -Wnull-pointer-arithmetic on clang on const_expr(NULL):
> >   https://godbolt.org/z/vo5W7efdE
>
> I was worried about that one.
>
> > I just do not see a method to silence that one. So three options:
> >
> >   1. is_const() does not accept pointers and throws a constraint violation:
> >        #define is_const(x) __is_const_zero(0 * (x))
> >      This is my current patch.
>
> Is that going to affect things like const_true(x << y)?

No warnings for const_true(x << y). See by yourself:

  https://godbolt.org/z/v79x3dnor

> Disallowing that seems counter-productive.
> (Remember it might be passed into a #define that is then
> checking its argument for being constant.)

I understand how a static inline may use __builtin_constant_p() to
check if its argument is NULL. But I am having a hard time
understanding how this would look like with macros and with
is_const().

Do you know one real life example where you have to pass NULL to a
function like macro which can not be written as a static inline
function?

And if that real life use case does not exist, then disallowing it
looks sane: it will push the developper to do the right thing: write a
static inline with __builting_constant_p().

> >   2. is_const() accept pointers but is_const(NULL) returns false:
> >        #define is_const(x) __is_const_zero((x) != (x))
> >      This keeps the current __is_constexpr() behaviour.
>
> No good - expands everything twice.

And? __is_const_zero() does not evaluate its arguments, so no side effect:

  https://godbolt.org/z/W988P4v9e

Or am I missing something else?

> >   3. is_const() accepts pointers and is_const(NULL) return true:
> >
> >        #define const_expr(x) _Generic(0 ? (void *)((x) + 0 ? 0L : 0L)
> > : (char *)0, char *: 1, void *: 0)
> >
> >      David's latest proposal, it requires to remove the
> >      -Wnull-pointer-arithmetic clang warning.
>
> Only for const_expr(NULL) - and since clang gets that wrong
> maybe the warning is a good thing.
>
> You can just add:
> #define const_NULL(ptr) const_true(!(ptr))
> Probably the only place where you actually want to test for zero.

Which goes back to my first point: if we have to declare const_NULL(),
then we probably do not want is_const() to accept NULL so that the
user sees the mismatch (and I am not acknowledging that we need
const_NULL(): as long as no use case arize, no need for it).

> > I vote for 1. or 2. (with a preference for 1.). IMHO, we are just
> > adding an unreasonable level of complexity for making the macro treat
> > NULL as an integer. Would someone find a solution for 3. that does not
> > yield a warning, then why not. But if we have to remove a compiler
> > check for a theoretical use case that does not even exist in the
> > kernel, then it is not worth the trade off.
> >
> > Concerning is_const(var << 2), the patch I submitted works fine as-is
> > with all scalars including that (var << 2):
> >
> >   https://godbolt.org/z/xer4aMees
> >
> > And can we ignore the case (!(var << 2))? This is not a warning
> > because of the macro, but because of the caller! If I do any of:
> >
> >           if (!(var << 2)) {}
> >           (void)__builtin_constant_p(!(var << 2));
> >
> > I also got the warning. The point is that the macro should not
> > generate *new* warnings. If the given argument already raises a
> > warning, it is the caller's responsibility to fix.
>
> Except it could easily happen way inside some other expansion.
> Perhaps someone optimises frobnicate(x) for constant input.
> Suddenly frobnicate(!(var << 2)) generates a compile error.

Then, that person will see that compile error and will modify
frobnicate() to remove the compile error. End of the story.

My point is simple: if the use case you are mentioning is valid, why
did it never collide with __builtin_constant_p() that we have been
using for many years?

And I am sure that there are hundreds of examples of macro that will
either pass their argument as-is to an if() or to the ternary operator
without accounting for if their input is (!(var << 2)). So why did not
these collide?


Yours sincerely,
Vincent Mailhol


From vincent.mailhol at gmail.com  Sat Dec  7 04:45:05 2024
From: vincent.mailhol at gmail.com (Vincent Mailhol)
Date: Sat, 7 Dec 2024 21:45:05 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com> <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
Message-ID: <CAMZ6RqJGqBqvgxzp5yPFY1pk0WkkwEMM34qU-dZ3kXfsnKaqEg@mail.gmail.com>

On Sat. 7 Dec. 2024 at 17:39, Martin Uecker <muecker at gwdg.de> wrote:
> Am Freitag, dem 06.12.2024 um 16:26 +0900 schrieb Vincent Mailhol:
> > > On Fri. 6 Dec. 2024 at 15:40, Martin Uecker <muecker at gwdg.de> wrote:
> > > > > Am Freitag, dem 06.12.2024 um 02:25 +0000 schrieb David Laight:
> > > > > > > From: Vincent Mailhol
> > > > > > > > > Sent: 05 December 2024 15:31

(...)

> > > > > > > > > @Martin, do you agree that I remove the accreditation?
> > >
> > > So, do you agree to have the accreditation removed in compiler.h?
> > > Personally, I do not mind. I am also OK to remove you from the
> > > documentation and add you to the CREDITS file if you'd like to.
>
> Sorry, I somehow didn't read this part. Please do whatever you think is
> most appropriate (but please update my email to the new above if it
> still appears anywhere).

OK. Then I will remove the accreditation from the  compiler.h
documentation and instead add an entry in the CREDITS file in a
separate patch. I think this is the most appropriate way.

> I find it amazing how much time the Linux kernel community spends
> revising code to make it work perfectly.
>
> Still, I am wondering whether some of this time and effort should not
> be targeted at C compilers and language work to make these macro
> hacks unnecessary?

It seems to me that the long term solution to this problem are the
constexpr functions.

But the core issue is that before getting this support in Linux, we
have to wait for this to be added to the C2Y draft, then implemented
in the compilers (probably just reusing the C++ constexpr functions)
and finally wait maybe one more decade for the C2Y support to reach
the kernel. For reference the kernel supports C11 only from 2022? So
maybe we will see those in the kernel around 2037? Meanwhile, we have
to deal with those hacks.


Yours sincerely,
Vincent Mailhol


From marex at denx.de  Sat Dec  7 03:42:44 2024
From: marex at denx.de (Marek Vasut)
Date: Sat, 7 Dec 2024 12:42:44 +0100
Subject: [PATCH v3] pinctrl: stm32: Add check for clk_enable()
In-Reply-To: <20241206214315.3385033-1-zmw12306@gmail.com>
References: <20241206214315.3385033-1-zmw12306@gmail.com>
Message-ID: <9830993d-943b-4079-b31d-7c77ee83d306@denx.de>

On 12/6/24 10:43 PM, Mingwei Zheng wrote:

[...]

> @@ -1646,8 +1645,8 @@ int stm32_pctl_probe(struct platform_device *pdev)
>   		if (ret) {
>   			fwnode_handle_put(child);
>   
> -			for (i = 0; i < pctl->nbanks; i++)
> -				clk_disable_unprepare(pctl->banks[i].clk);
> +			clk_bulk_disable(pctl->nbanks, pctl->clks);
> +			clk_bulk_unprepare(pctl->nbanks, pctl->clks);

Use clk_bulk_disable_unprepare()

include/linux/clk.h:static inline void clk_bulk_disable_unprepare(int 
num_clks,

It looks pretty good otherwise, thanks !


From towinchenmi at gmail.com  Sat Dec  7 05:03:14 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sat,  7 Dec 2024 21:03:14 +0800
Subject: [PATCH v2 1/3] dt-bindings: leds: backlight: apple,dwi-bl: Add bindings for Apple DWI backlight
In-Reply-To: <20241207130433.30351-1-towinchenmi@gmail.com>
References: <20241207130433.30351-1-towinchenmi@gmail.com>
Message-ID: <20241207130433.30351-2-towinchenmi@gmail.com>

Add the device tree bindings for backlight controllers attached via Apple
DWI 2-wire interface.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../bindings/leds/backlight/apple,dwi-bl.yaml | 54 +++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
new file mode 100644
index 000000000000..9d4aa243f679
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/apple,dwi-bl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple DWI 2-Wire Interface Backlight Controller
+
+maintainers:
+  - Nick Chan <towinchenmi at gmail.com>
+
+description: |
+  Apple SoCs contain a 2-wire interface called DWI. On some Apple iPhones,
+  iPads and iPod touches with a LCD display, 1-2 backlight controllers
+  are connected via DWI. Interfacing with DWI controls all backlight
+  controllers at the same time. As such, the backlight controllers are
+  treated as a single controller regardless of the underlying
+  configuration.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,s5l8960x-dwi-bl
+          - apple,t7000-dwi-bl
+          - apple,s8000-dwi-bl
+          - apple,t8010-dwi-bl
+          - apple,t8015-dwi-bl
+      - const: apple,dwi-bl
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      dwi_bl: backlight at 20e200010 {
+        compatible = "apple,s5l8960x-dwi-bl", "apple,dwi-bl";
+        reg = <0x2 0x0e200010 0 8>;
+        power-domains = <&ps_dwi>;
+      };
+    };
-- 
2.47.1



From towinchenmi at gmail.com  Sat Dec  7 05:03:15 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sat,  7 Dec 2024 21:03:15 +0800
Subject: [PATCH v2 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <20241207130433.30351-1-towinchenmi@gmail.com>
References: <20241207130433.30351-1-towinchenmi@gmail.com>
Message-ID: <20241207130433.30351-3-towinchenmi@gmail.com>

Add driver for backlight controllers attached via Apple DWI 2-wire
interface, which is found on some Apple iPhones, iPads and iPod touches
with a LCD display.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/video/backlight/Kconfig  |  12 +++
 drivers/video/backlight/Makefile |   1 +
 drivers/video/backlight/dwi_bl.c | 124 +++++++++++++++++++++++++++++++
 3 files changed, 137 insertions(+)
 create mode 100644 drivers/video/backlight/dwi_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 3614a5d29c71..e64cc3d51ac5 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -166,6 +166,18 @@ config BACKLIGHT_EP93XX
 	  To compile this driver as a module, choose M here: the module will
 	  be called ep93xx_bl.
 
+config BACKLIGHT_APPLE_DWI
+	tristate "Apple DWI 2-Wire Interface Backlight Driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	default y
+	help
+          Say Y to enable the backlight driver for backlight controllers
+          attached via the Apple DWI 2-wire interface which is found in some
+          Apple iPhones, iPads and iPod touches.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called dwi_bl.
+
 config BACKLIGHT_IPAQ_MICRO
 	tristate "iPAQ microcontroller backlight driver"
 	depends on MFD_IPAQ_MICRO
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 8fc98f760a8a..0a569d7f0210 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_BACKLIGHT_BD6107)		+= bd6107.o
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE)	+= backlight.o
 obj-$(CONFIG_BACKLIGHT_DA903X)		+= da903x_bl.o
 obj-$(CONFIG_BACKLIGHT_DA9052)		+= da9052_bl.o
+obj-$(CONFIG_BACKLIGHT_APPLE_DWI)	+= dwi_bl.o
 obj-$(CONFIG_BACKLIGHT_EP93XX)		+= ep93xx_bl.o
 obj-$(CONFIG_BACKLIGHT_GPIO)		+= gpio_backlight.o
 obj-$(CONFIG_BACKLIGHT_HP680)		+= hp680_bl.o
diff --git a/drivers/video/backlight/dwi_bl.c b/drivers/video/backlight/dwi_bl.c
new file mode 100644
index 000000000000..d4bfd74b3129
--- /dev/null
+++ b/drivers/video/backlight/dwi_bl.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Driver for backlight controllers attached via Apple DWI 2-wire interface
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/backlight.h>
+
+#define DWI_BL_CTL			0x0
+#define DWI_BL_CTL_SEND1		BIT(0)
+#define DWI_BL_CTL_SEND2		BIT(4)
+#define DWI_BL_CTL_SEND3		BIT(5)
+#define DWI_BL_CTL_LE_DATA		BIT(6)
+/* Only used on Apple A9 and later */
+#define DWI_BL_CTL_SEND4		BIT(12)
+
+#define DWI_BL_CMD			0x4
+#define DWI_BL_CMD_TYPE			GENMASK(31, 28)
+#define DWI_BL_CMD_TYPE_SET_BRIGHTNESS	0xa
+#define DWI_BL_CMD_DATA			GENMASK(10, 0)
+
+#define DWI_BL_CTL_SEND			(DWI_BL_CTL_SEND1 | \
+					 DWI_BL_CTL_SEND2 | \
+					 DWI_BL_CTL_SEND3 | \
+					 DWI_BL_CTL_LE_DATA | \
+					 DWI_BL_CTL_SEND4)
+
+#define DWI_BL_MAX_BRIGHTNESS		2047
+
+struct apple_dwi_bl {
+	void __iomem *base;
+};
+
+static int dwi_bl_update_status(struct backlight_device *bl)
+{
+	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
+
+	int brightness = backlight_get_brightness(bl);
+
+	u32 cmd = 0;
+
+	cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
+	cmd |= FIELD_PREP(DWI_BL_CMD_TYPE, DWI_BL_CMD_TYPE_SET_BRIGHTNESS);
+
+	writel(cmd, dwi_bl->base + DWI_BL_CMD);
+	writel(DWI_BL_CTL_SEND, dwi_bl->base + DWI_BL_CTL);
+
+	return 0;
+}
+
+static int dwi_bl_get_brightness(struct backlight_device *bl)
+{
+	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
+
+	u32 cmd = readl(dwi_bl->base + DWI_BL_CMD);
+
+	return FIELD_GET(DWI_BL_CMD_DATA, cmd);
+}
+
+static const struct backlight_ops dwi_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = dwi_bl_get_brightness,
+	.update_status	= dwi_bl_update_status
+};
+
+static int dwi_bl_probe(struct platform_device *dev)
+{
+	struct apple_dwi_bl *dwi_bl;
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct resource *res;
+
+	dwi_bl = devm_kzalloc(&dev->dev, sizeof(struct apple_dwi_bl), GFP_KERNEL);
+	if (!dwi_bl)
+		return -ENOMEM;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+
+	dwi_bl->base = devm_ioremap_resource(&dev->dev, res);
+	if (IS_ERR(dwi_bl->base))
+		return PTR_ERR(dwi_bl->base);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = DWI_BL_MAX_BRIGHTNESS;
+
+	bl = devm_backlight_device_register(&dev->dev, dev->name, &dev->dev,
+					dwi_bl, &dwi_bl_ops, &props);
+	if (IS_ERR(bl))
+		return PTR_ERR(bl);
+
+	platform_set_drvdata(dev, dwi_bl);
+
+	bl->props.brightness = dwi_bl_get_brightness(bl);
+
+	return 0;
+}
+
+static const struct of_device_id dwi_bl_of_match[] = {
+	{ .compatible = "apple,dwi-bl" },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, dwi_bl_of_match);
+
+static struct platform_driver dwi_bl_driver = {
+	.driver		= {
+		.name	= "dwi-bl",
+		.of_match_table = dwi_bl_of_match
+	},
+	.probe		= dwi_bl_probe,
+};
+
+module_platform_driver(dwi_bl_driver);
+
+MODULE_DESCRIPTION("Apple DWI Backlight Driver");
+MODULE_AUTHOR("Nick Chan <towinchenmi at gmail.com>");
+MODULE_LICENSE("Dual MIT/GPL");
-- 
2.47.1



From towinchenmi at gmail.com  Sat Dec  7 05:03:16 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sat,  7 Dec 2024 21:03:16 +0800
Subject: [PATCH v2 3/3] MAINTAINERS: Add entries for Apple DWI backlight controller
In-Reply-To: <20241207130433.30351-1-towinchenmi@gmail.com>
References: <20241207130433.30351-1-towinchenmi@gmail.com>
Message-ID: <20241207130433.30351-4-towinchenmi@gmail.com>

Add MAINTAINERS entries for the driver.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..36de76bc6fd4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2204,6 +2204,7 @@ F:	Documentation/devicetree/bindings/pci/apple,pcie.yaml
 F:	Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
 F:	Documentation/devicetree/bindings/power/apple*
 F:	Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
+F:	Documentation/devicetree/bindings/video/backlight/apple,dwi-bl.yaml
 F:	Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
 F:	arch/arm64/boot/dts/apple/
 F:	drivers/bluetooth/hci_bcm4377.c
@@ -2221,6 +2222,7 @@ F:	drivers/nvmem/apple-efuses.c
 F:	drivers/pinctrl/pinctrl-apple-gpio.c
 F:	drivers/pwm/pwm-apple.c
 F:	drivers/soc/apple/*
+F:	drivers/video/backlight/dwi_bl.c
 F:	drivers/watchdog/apple_wdt.c
 F:	include/dt-bindings/interrupt-controller/apple-aic.h
 F:	include/dt-bindings/pinctrl/apple.h
-- 
2.47.1



From towinchenmi at gmail.com  Sat Dec  7 05:03:13 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sat,  7 Dec 2024 21:03:13 +0800
Subject: [PATCH v2 0/3] Apple DWI backlight driver
Message-ID: <20241207130433.30351-1-towinchenmi@gmail.com>

Apple SoCs come with a 2-wire interface named DWI. On some iPhones, iPads
and iPod touches the backlight controller is connected via this interface.
This series adds a backlight driver for backlight controllers connected
this way.

Changes since v1:
- Fixed dt-bindings $id.
- Make power-domains an optional property in dt-bindings.
- Added missing error checking after devm_ioremap_resource() in
dwi_bl_probe().

v1: https://lore.kernel.org/asahi/20241206172735.4310-1-towinchenmi at gmail.com/T

Nick Chan
---
Nick Chan (3):
  dt-bindings: leds: backlight: apple,dwi-bl: Add bindings for Apple DWI
    backlight
  backlight: dwi_bl: Add Apple DWI backlight driver
  MAINTAINERS: Add entries for Apple DWI backlight controller

 .../bindings/leds/backlight/apple,dwi-bl.yaml |  54 ++++++++
 MAINTAINERS                                   |   2 +
 drivers/video/backlight/Kconfig               |  12 ++
 drivers/video/backlight/Makefile              |   1 +
 drivers/video/backlight/dwi_bl.c              | 124 ++++++++++++++++++
 5 files changed, 193 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
 create mode 100644 drivers/video/backlight/dwi_bl.c


base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
-- 
2.47.1



From muecker at gwdg.de  Sat Dec  7 05:07:08 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sat, 7 Dec 2024 14:07:08 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
Message-ID: <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>

Am Samstag, dem 07.12.2024 um 10:33 +0000 schrieb David Laight:
> From: Martin Uecker
> > Sent: 07 December 2024 08:40
> ...
> > I find it amazing how much time the Linux kernel community spends
> > revising code to make it work perfectly.
> > 
> > Still, I am wondering whether some of this time and effort should not
> > be targeted at C compilers and language work to make these macro
> > hacks unnecessary?
> 
> I'm probably not alone in thinking that sometimes the compiler writers
> are doing their hardest to make life hard for people writing low level code.

GCC and Clang are open-source projects just like the kernel. One can?
go there and contribute.  I am not saying that it is always easy to
find consensus and there also projects that have other requirements
than the kernel. But I started to contribute to GCC (with very limited
time) to address some of my own issues, and I found the community very
welcoming.

> 
> > I already found the original motivation for these macros very questionable.
> > Removing VLAs at the cost having imprecise worst-case bounds strikes
> > me as fundamentally misguided - at least if security is the motivation.
> 
> VLA basically cannot be allowed because of the very limited stack space.
> Even the per-frame limits aren't a real solution - they just catch the
> places that most likely to cause issues. Very deep call chains and any
> recursion (that isn't tightly bounded) can cause grief.

VLA use *less* stack than a fixed size arrays with fixed bound.
> 
> > So maybe there are other good reasons for this, e.g. bad code
> > for VLAs or risk of jumping the guard page if the attacker can somehow
> > influence its size (but for this there is -Wvla-larger-than). But even then,
> > wouldn't it be a more worthwhile and interesting investment of engineering
> > resources to improving code generation / warnings at the compiler level?
> 
> This is kernel code, any access into a stack guard page is basically
> unrecoverable for the entire system - a kernel lock/mutex could be held.
>
> With a list of (calling_fn, called_fn, stack_offset) it is possible
> calculate an accurate maximum stack usage.
> Indirect calls would need to use the (IIRC) FINE_IBT hashes to identify
> the possible functions (and I'm not sure than has an attribute for a 'seed'
> so that 'int (*)(void *)' functions can be separated into groups.
> I've not looked at whether objtool could generate the output - but is has
> to be easier for the compiler to do it.
> 
> I have done that calculation in the past (parsing a compiler listing file)
> and basically discovered the system didn't actually have enough memory
> to allocate 'safe' stacks! The max stack was pretty much always (the
> equivalent of) printf() inside an error path that never happens.
> It might be interesting to see how bad linux is (after sorting out
> how to handle recursive calls - hopefully there won't be too many
> unexpected ones.

Compiler and ISO C language support to guarantee bounded stack usage
would indeed be a very interesting feature.

> 
> > Also the fortification of strlen and co seems something which could be
> > much better solved with annotations and proper compiler support.
> 
> That might be nice, but kernel have to be buildable with relatively
> old compilers.

Yes, but it could make use of it at some point in the future (or
optionally).

> Some things might need language/ABI changes to better handle ptr+size.
> The ability to return such a pair in registers would probably be useful
> (without doing horrid games with a union and __int128).

ptr + size is something we are looking into.

You can already do quite a bit by using C99's syntax for variably modified
types. For example, you would get UBSan trap for the following OOB access:

int foo(int n, char (*buf)[n])
{
  (*buf)[n] = 1;
}

This does not require an ABI change. 

Martin






From muecker at gwdg.de  Sat Dec  7 05:18:51 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sat, 7 Dec 2024 14:18:51 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAMZ6RqJGqBqvgxzp5yPFY1pk0WkkwEMM34qU-dZ3kXfsnKaqEg@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <CAMZ6RqJGqBqvgxzp5yPFY1pk0WkkwEMM34qU-dZ3kXfsnKaqEg@mail.gmail.com>
Message-ID: <429e7c6713ecc94494d9107e5f5a1f0c8e854f23.camel@gwdg.de>

Am Samstag, dem 07.12.2024 um 21:45 +0900 schrieb Vincent Mailhol:
> On Sat. 7 Dec. 2024 at 17:39, Martin Uecker <muecker at gwdg.de> wrote:
> > Am Freitag, dem 06.12.2024 um 16:26 +0900 schrieb Vincent Mailhol:

...

> > I find it amazing how much time the Linux kernel community spends
> > revising code to make it work perfectly.
> > 
> > Still, I am wondering whether some of this time and effort should not
> > be targeted at C compilers and language work to make these macro
> > hacks unnecessary?
> 
> It seems to me that the long term solution to this problem are the
> constexpr functions.

How would constexpr functions help here?  (I am a bit sceptical about
constexpr functions.)

> 
> But the core issue is that before getting this support in Linux, we
> have to wait for this to be added to the C2Y draft, then implemented
> in the compilers (probably just reusing the C++ constexpr functions)
> and finally wait maybe one more decade for the C2Y support to reach
> the kernel. For reference the kernel supports C11 only from 2022? So
> maybe we will see those in the kernel around 2037? Meanwhile, we have
> to deal with those hacks.

If we do not collaborate on proper solutions, then you might have?
to wait much longer.

Martin


> 
> 
> Yours sincerely,
> Vincent Mailhol



From vincent.mailhol at gmail.com  Sat Dec  7 05:50:41 2024
From: vincent.mailhol at gmail.com (Vincent Mailhol)
Date: Sat, 7 Dec 2024 22:50:41 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <429e7c6713ecc94494d9107e5f5a1f0c8e854f23.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de> <CAMZ6RqJGqBqvgxzp5yPFY1pk0WkkwEMM34qU-dZ3kXfsnKaqEg@mail.gmail.com>
 <429e7c6713ecc94494d9107e5f5a1f0c8e854f23.camel@gwdg.de>
Message-ID: <CAMZ6RqL+iS6GVsY20=O6GdQakRpp7XdewZJsUbmE5OCsKaHR6Q@mail.gmail.com>

On Sat. 7 Dec. 2024 ? 22:19, Martin Uecker <muecker at gwdg.de> wrote:
> Am Samstag, dem 07.12.2024 um 21:45 +0900 schrieb Vincent Mailhol:
> > On Sat. 7 Dec. 2024 at 17:39, Martin Uecker <muecker at gwdg.de> wrote:
> > > Am Freitag, dem 06.12.2024 um 16:26 +0900 schrieb Vincent Mailhol:
>
> ...
>
> > > I find it amazing how much time the Linux kernel community spends
> > > revising code to make it work perfectly.
> > >
> > > Still, I am wondering whether some of this time and effort should not
> > > be targeted at C compilers and language work to make these macro
> > > hacks unnecessary?
> >
> > It seems to me that the long term solution to this problem are the
> > constexpr functions.
>
> How would constexpr functions help here?  (I am a bit sceptical about
> constexpr functions.)

I was thinking of some of the "side features" of constexpr functions. Namely:

  - std::is_constant_evaluated
  Link: https://en.cppreference.com/w/cpp/types/is_constant_evaluated

  - if consteval
  Link: https://en.cppreference.com/w/cpp/language/if#Consteval_if

I did not try it, but looking at these, I believe that this would
allow us to rewrite most of our macros into some constexpr functions.

> > But the core issue is that before getting this support in Linux, we
> > have to wait for this to be added to the C2Y draft, then implemented
> > in the compilers (probably just reusing the C++ constexpr functions)
> > and finally wait maybe one more decade for the C2Y support to reach
> > the kernel. For reference the kernel supports C11 only from 2022? So
> > maybe we will see those in the kernel around 2037? Meanwhile, we have
> > to deal with those hacks.
>
> If we do not collaborate on proper solutions, then you might have
> to wait much longer.

I was invited to WG14 this September. For now, I am only lurking. The
thing I have in mind right now is to write a paper to allow the use of
static_assert() in expressions (i.e. make it return 0 on success).
That should be a relatively small change, but would bring a nice
quality of life improvement.

For context, look at this:

  https://lore.kernel.org/all/CAHk-=wjLSEcZ5LdW+3C+9rtjvNPHZT6zdk0POj67T5k2ZpDbgA at mail.gmail.com/T/#m1ba33a804b4041154b72a1d0333f90ec7204c461

And I will definitely follow the progress of constexpr functions in C2Y.


Yours sincerely,
Vincent Mailhol


From mailhol.vincent at wanadoo.fr  Thu Dec  5 23:19:52 2024
From: mailhol.vincent at wanadoo.fr (Vincent Mailhol)
Date: Fri, 6 Dec 2024 16:19:52 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
Message-ID: <CAMZ6RqKLrDB-xkm2G242yU7L=tzxCR9NTwca-1yuWSSEHAOrxQ@mail.gmail.com>

On Fri. 6 Dec. 2024 at 15:14, Linus Torvalds
<torvalds at linux-foundation.org> wrote:
> On Thu, 5 Dec 2024 at 18:26, David Laight <David.Laight at aculab.com> wrote:
> >
> > From: Vincent Mailhol
> > > ACK. Would adding a suggested--by Linus tag solve your concern?
>
> I'm genberally the one person who doesn't need any more credit ;)
>
> > I actually suspect the first patches to change __is_constexpr() to
> > use _Generic were from myself.
>
> Yes. And David was also I think the one who suggested something else
> than "!!" originally too.

Ack. Then, I will add a suggested-by tag to credit David!

> I may have liked "!!" for being very idiomatic and traditional C, but
> there were those pesky compilers that warn about "integer in bool
> context" or whatever the annoying warning was when then doing the
> "multiply by zero" to turn a constant expression into a constant zero
> expression.
>
> So that
>
>   #define is_const(x) __is_const_zero(0 * (x))
>
> causes issues when 'x' is not an integer expression (think
> "is_const(NULL)" or "is_const(1 == 2)".

But 1 == 2 has already an integer type as proven by:

  #define is_int(x) _Generic(x, int: 1, default: 0)
  static_assert(is_int(1 == 2));

So, it leaves us with the case is_const(pointer). To which I would
question if we really want to support this. By definition, an
expression with a pointer type can not be an *integer* constant
expression. So one part of me tells me that it is a sane thing to
*not* support this case and throw a warning if the user feeds
is_cont() with a pointer.

If we just what to accept pointer arguments but still return false
(because those are not integers), one solution is:

  #define is_const(x) __is_const_zero((long)(x) * 0l)

This would be consistent with __is_constexpr(): it does accept NULL
(i.e. no warnings), but does not recognize it as an integer constant
expression, e.g.:

  is_const(NULL);

returns false with no warnings.

> Side note: I think "(x) == 0" will make sparse unhappy when 'x' is a
> pointer, because it results that horrid "use integer zero as NULL
> without a cast" thing when the plain zero gets implicitly cast to a
> pointer. Which is a really nasty and broken C pattern and should never
> have been silent.
>
> I think David suggested using ((x)?0:0) at some point. Silly
> nonsensical and complex expression, but maybe that finally gets rid of
> all the warnings:
>
>      #define is_const(x) __is_const_zero((x)?0:0)
>
> might work regardless of the type of 'x'.
>
> Or does that trigger some odd case too?

Following a quick test, this seems to work and to return true if given
NULL as an argument (contrary to the current __is_const_expr()). So if
we want to go beyond the C standard and extend the meaning of integer
constant expression in the kernel to also include constant pointers, I
agree that this is the way to go!

Side question, Linus, what do you think about the __is_const_zero()
documentation in

  https://lore.kernel.org/all/20241203-is_constexpr-refactor-v1-2-4e4cbaecc216 at wanadoo.fr/

Do you think I am too verbose as pointed out by David? Some people
(including me and Yuri) like it that way, but if you also think this
is too much, I will make it shorter.

Thanks,


Yours sincerely,
Vincent Mailhol


From antonio.borneo at foss.st.com  Sat Dec  7 06:23:13 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Sat, 7 Dec 2024 15:23:13 +0100
Subject: [Linux-stm32] [PATCH v3] pinctrl: stm32: Add check for
 clk_enable()
In-Reply-To: <20241206214315.3385033-1-zmw12306@gmail.com>
References: <20241206214315.3385033-1-zmw12306@gmail.com>
Message-ID: <21f4927382a3cf3bb433bc1f1d7d4ad9ea1a2a5e.camel@foss.st.com>

On Fri, 2024-12-06 at 16:43 -0500, Mingwei Zheng wrote:
> Convert the driver to clk_bulk*() API.
> Add check for the return value of clk_bulk_enable() to catch
> the potential error.
> 
> Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
> ---
> Changelog:
> 
> v2 -> v3:
> 
> 1. Convert clk_disable_unprepare to clk_bulk_disable
> and clk_bulk_unprepare.
> 
> v1 -> v2:
> 
> 1. Move int ret declaration into if block.
> ---
> ?drivers/pinctrl/stm32/pinctrl-stm32.c | 28 +++++++++++++--------------
> ?1 file changed, 13 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
> index 5b7fa77c1184..0ef912e82736 100644
> --- a/drivers/pinctrl/stm32/pinctrl-stm32.c
> +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
> @@ -86,7 +86,6 @@ struct stm32_pinctrl_group {
> ?
> ?struct stm32_gpio_bank {
> ????????void __iomem *base;
> -???????struct clk *clk;
> ????????struct reset_control *rstc;
> ????????spinlock_t lock;
> ????????struct gpio_chip gpio_chip;
> @@ -108,6 +107,7 @@ struct stm32_pinctrl {
> ????????unsigned ngroups;
> ????????const char **grp_names;
> ????????struct stm32_gpio_bank *banks;

Thanks for your patch!
While it's growing wider than your initial scope, it looks as a nice improvement.

> +???????struct clk_bulk_data *clks;

Maybe I've missed it but, where does this array get allocated?
There exist clk_bulk_get_all() and devm_clk_bulk_get_all() that do the allocation for you, but they require all the clocks to be listed in the same "clocks" property, while this driver has a clock in
each DT subnode!
Some suggestion below.

> ????????unsigned nbanks;
> ????????const struct stm32_pinctrl_match_data *match_data;
> ????????struct irq_domain???????*domain;
> @@ -1308,7 +1308,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
> ????????if (IS_ERR(bank->base))
> ????????????????return PTR_ERR(bank->base);
> ?
> -???????err = clk_prepare_enable(bank->clk);
> +???????err = clk_prepare_enable(pctl->clks[pctl->nbanks].clk);
> ????????if (err) {
> ????????????????dev_err(dev, "failed to prepare_enable clk (%d)\n", err);
> ????????????????return err;
> @@ -1397,7 +1397,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
> ????????return 0;
> ?
> ?err_clk:
> -???????clk_disable_unprepare(bank->clk);
> +???????clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);
> ????????return err;
> ?}
> ?
> @@ -1631,11 +1631,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
> ????????????????????????fwnode_handle_put(child);
> ????????????????????????return -EPROBE_DEFER;
> ????????????????}
> -
> -???????????????bank->clk = of_clk_get_by_name(np, NULL);
> -???????????????if (IS_ERR(bank->clk)) {
> +???????????????pctl->clks[i].clk = of_clk_get_by_name(np, NULL);

This is the first time the array is used, during stm32_pctl_probe(), so the array should be already allocated before this line.
The number of banks pctl->nbanks is computed few lines below, so it should be anticipated, or being replaced by a simpler
  pctl->nbanks = gpiochip_node_count(dev);

then allocation could be done with
  pctl->clks = devm_kmalloc_array(dev, pctl->nbanks, sizeof(*pctl->clks), GFP_KERNEL);

Also, you never assign `pctl->clks[i].id` which is then used by the error messages in, e.g., clk_bulk_enable().
We don't mandate the property "clock-names" in the DT subnodes, so no way to get a reasonable value from the DT.
I presume it's fine to set it to NULL... to be tested.

Regards,
Antonio


> +???????????????if (IS_ERR(pctl->clks[i].clk)) {
> ????????????????????????fwnode_handle_put(child);
> -???????????????????????return dev_err_probe(dev, PTR_ERR(bank->clk),
> +???????????????????????return dev_err_probe(dev, PTR_ERR(pctl->clks[i].clk),
> ???????????????????????????????????????????? "failed to get clk\n");
> ????????????????}
> ????????????????i++;
> @@ -1646,8 +1645,8 @@ int stm32_pctl_probe(struct platform_device *pdev)
> ????????????????if (ret) {
> ????????????????????????fwnode_handle_put(child);
> ?
> -???????????????????????for (i = 0; i < pctl->nbanks; i++)
> -???????????????????????????????clk_disable_unprepare(pctl->banks[i].clk);
> +???????????????????????clk_bulk_disable(pctl->nbanks, pctl->clks);
> +???????????????????????clk_bulk_unprepare(pctl->nbanks, pctl->clks);
> ?
> ????????????????????????return ret;
> ????????????????}
> @@ -1726,10 +1725,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
> ?int __maybe_unused stm32_pinctrl_suspend(struct device *dev)
> ?{
> ????????struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
> -???????int i;
> ?
> -???????for (i = 0; i < pctl->nbanks; i++)
> -???????????????clk_disable(pctl->banks[i].clk);
> +???????clk_bulk_disable(pctl->nbanks, pctl->clks);
> ?
> ????????return 0;
> ?}
> @@ -1738,10 +1735,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
> ?{
> ????????struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
> ????????struct stm32_pinctrl_group *g = pctl->groups;
> -???????int i;
> +???????int i, ret;
> ?
> -???????for (i = 0; i < pctl->nbanks; i++)
> -???????????????clk_enable(pctl->banks[i].clk);
> +???????ret = clk_bulk_enable(pctl->nbanks, pctl->clks);
> +???????if (ret)
> +???????????????return ret;
> ?
> ????????for (i = 0; i < pctl->ngroups; i++, g++)
> ????????????????stm32_pinctrl_restore_gpio_regs(pctl, g->pin);

From muecker at gwdg.de  Sat Dec  7 06:59:09 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sat, 7 Dec 2024 15:59:09 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAMZ6RqL+iS6GVsY20=O6GdQakRpp7XdewZJsUbmE5OCsKaHR6Q@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <CAMZ6RqJGqBqvgxzp5yPFY1pk0WkkwEMM34qU-dZ3kXfsnKaqEg@mail.gmail.com>
	 <429e7c6713ecc94494d9107e5f5a1f0c8e854f23.camel@gwdg.de>
	 <CAMZ6RqL+iS6GVsY20=O6GdQakRpp7XdewZJsUbmE5OCsKaHR6Q@mail.gmail.com>
Message-ID: <470b5f46d45063fdc21e4e19eac68c18cb42db48.camel@gwdg.de>

Am Samstag, dem 07.12.2024 um 22:50 +0900 schrieb Vincent Mailhol:
> On Sat. 7 Dec. 2024 ? 22:19, Martin Uecker <muecker at gwdg.de> wrote:
> > Am Samstag, dem 07.12.2024 um 21:45 +0900 schrieb Vincent Mailhol:
> > > On Sat. 7 Dec. 2024 at 17:39, Martin Uecker <muecker at gwdg.de> wrote:
> > > > Am Freitag, dem 06.12.2024 um 16:26 +0900 schrieb Vincent Mailhol:

...


> > > But the core issue is that before getting this support in Linux, we
> > > have to wait for this to be added to the C2Y draft, then implemented
> > > in the compilers (probably just reusing the C++ constexpr functions)
> > > and finally wait maybe one more decade for the C2Y support to reach
> > > the kernel. For reference the kernel supports C11 only from 2022? So
> > > maybe we will see those in the kernel around 2037? Meanwhile, we have
> > > to deal with those hacks.
> > 
> > If we do not collaborate on proper solutions, then you might have
> > to wait much longer.
> 
> I was invited to WG14 this September.?For now, I am only lurking. The
> thing I have in mind right now is to write a paper to allow the use of
> static_assert() in expressions (i.e. make it return 0 on success).
> That should be a relatively small change, but would bring a nice
> quality of life improvement.

Excellent, then I was complaining to the wrong person. 


Martin

> 
> For context, look at this:
> 
>   https://lore.kernel.org/all/CAHk-=wjLSEcZ5LdW+3C+9rtjvNPHZT6zdk0POj67T5k2ZpDbgA at mail.gmail.com/T/#m1ba33a804b4041154b72a1d0333f90ec7204c461
> 
> And I will definitely follow the progress of constexpr functions in C2Y.
> 
> 
> Yours sincerely,
> Vincent Mailhol



From muecker at gwdg.de  Sat Dec  7 07:10:31 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sat, 7 Dec 2024 16:10:31 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAMZ6RqL+iS6GVsY20=O6GdQakRpp7XdewZJsUbmE5OCsKaHR6Q@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <CAMZ6RqJGqBqvgxzp5yPFY1pk0WkkwEMM34qU-dZ3kXfsnKaqEg@mail.gmail.com>
	 <429e7c6713ecc94494d9107e5f5a1f0c8e854f23.camel@gwdg.de>
	 <CAMZ6RqL+iS6GVsY20=O6GdQakRpp7XdewZJsUbmE5OCsKaHR6Q@mail.gmail.com>
Message-ID: <b3bd6d4ef485dbb5db4c784f4e42f76adce502dc.camel@gwdg.de>

Am Samstag, dem 07.12.2024 um 22:50 +0900 schrieb Vincent Mailhol:
> On Sat. 7 Dec. 2024 ? 22:19, Martin Uecker <muecker at gwdg.de> wrote:
> > 
...

> 
> I was invited to WG14 this September. For now, I am only lurking. The
> thing I have in mind right now is to write a paper to allow the use of
> static_assert() in expressions (i.e. make it return 0 on success).
> That should be a relatively small change, but would bring a nice
> quality of life improvement.
> 
> For context, look at this:
> 
>   https://lore.kernel.org/all/CAHk-=wjLSEcZ5LdW+3C+9rtjvNPHZT6zdk0POj67T5k2ZpDbgA at mail.gmail.com/T/#m1ba33a804b4041154b72a1d0333f90ec7204c461

What one can do is put it into a structure.

#define const_assert(x) \
    (sizeof(struct { _Static_assert(x, ""); }))

but yeah, also a hack to work around a limitation of the standard
feature.

Martin


From vincent.mailhol at gmail.com  Sat Dec  7 07:23:24 2024
From: vincent.mailhol at gmail.com (Vincent Mailhol)
Date: Sun, 8 Dec 2024 00:23:24 +0900
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <b3bd6d4ef485dbb5db4c784f4e42f76adce502dc.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de> <CAMZ6RqJGqBqvgxzp5yPFY1pk0WkkwEMM34qU-dZ3kXfsnKaqEg@mail.gmail.com>
 <429e7c6713ecc94494d9107e5f5a1f0c8e854f23.camel@gwdg.de> <CAMZ6RqL+iS6GVsY20=O6GdQakRpp7XdewZJsUbmE5OCsKaHR6Q@mail.gmail.com>
 <b3bd6d4ef485dbb5db4c784f4e42f76adce502dc.camel@gwdg.de>
Message-ID: <CAMZ6RqJrAVVLDAJtNTA2U=UFVUJp1samoat+yfBmSpO-dCVcaw@mail.gmail.com>

On Sun. 8 Dec. 2024 at 00:10, Martin Uecker <muecker at gwdg.de> wrote:
> Am Samstag, dem 07.12.2024 um 22:50 +0900 schrieb Vincent Mailhol:
> > On Sat. 7 Dec. 2024 ? 22:19, Martin Uecker <muecker at gwdg.de> wrote:
> > >
> ...
>
> >
> > I was invited to WG14 this September. For now, I am only lurking. The
> > thing I have in mind right now is to write a paper to allow the use of
> > static_assert() in expressions (i.e. make it return 0 on success).
> > That should be a relatively small change, but would bring a nice
> > quality of life improvement.
> >
> > For context, look at this:
> >
> >   https://lore.kernel.org/all/CAHk-=wjLSEcZ5LdW+3C+9rtjvNPHZT6zdk0POj67T5k2ZpDbgA at mail.gmail.com/T/#m1ba33a804b4041154b72a1d0333f90ec7204c461
>
> What one can do is put it into a structure.
>
> #define const_assert(x) \
>     (sizeof(struct { _Static_assert(x, ""); }))
>
> but yeah, also a hack to work around a limitation of the standard
> feature.

If you scroll down a couple more messages, you can see that Linus came
up with that exact same hack :-)

It is now upstreamed in:

  https://git.kernel.org/torvalds/c/d7a516c6eeae

And yes, this solves the problem for the kernel, but I would still
like to change the standard to solve it for everyone else.


Yours sincerely,
Vincent Mailhol


From David.Laight at ACULAB.COM  Sat Dec  7 10:07:38 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sat, 7 Dec 2024 18:07:38 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAMZ6RqL+iS6GVsY20=O6GdQakRpp7XdewZJsUbmE5OCsKaHR6Q@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
 <CAMZ6RqJGqBqvgxzp5yPFY1pk0WkkwEMM34qU-dZ3kXfsnKaqEg@mail.gmail.com>
 <429e7c6713ecc94494d9107e5f5a1f0c8e854f23.camel@gwdg.de>
 <CAMZ6RqL+iS6GVsY20=O6GdQakRpp7XdewZJsUbmE5OCsKaHR6Q@mail.gmail.com>
Message-ID: <00d233a607a84f73942cd706cc29f088@AcuMS.aculab.com>

From: Vincent Mailhol
> Sent: 07 December 2024 13:51
...
> > > It seems to me that the long term solution to this problem are the
> > > constexpr functions.
> >
> > How would constexpr functions help here?  (I am a bit sceptical about
> > constexpr functions.)
> 
> I was thinking of some of the "side features" of constexpr functions. Namely:
> 
>   - std::is_constant_evaluated
>   Link: https://en.cppreference.com/w/cpp/types/is_constant_evaluated
> 
>   - if consteval
>   Link: https://en.cppreference.com/w/cpp/language/if#Consteval_if
> 
> I did not try it, but looking at these, I believe that this would
> allow us to rewrite most of our macros into some constexpr functions.

IIRC (and trying to understand the definitions) they are backwards
from what the kernel tests are trying to achieve.
The kernel wans to add additional compile-time tests where possible.
This is often restricted to checking values that are compile time
constants (for some definition of constant).
The C++ 'constexpr' is about determining the context in which a
function is called.

Remember in C 'static int x = expr;' requires that 'expr' is a constant
so that the asm can contain 'x: .word value', but C++ is perfectly willing
to add an entry to the 'global constructors' and call a function for you.
This is not useful default behaviour.
The 'constexpr' stuff seems to be about detecting some of these cases
so the function can return a different value - and then possibly be
optimised away.
The kernel is trying to get some test coverage at compile time
without affecting run-time.

The compile-time checks all get more complicated because things like
initialisers have to be 'integer constant expressions' rather than the
more relaxed 'compile time constant' (array bounds probably do need
to be the former).
This is (probably) what stops ({ expr; }) being used for initialisers
even when the value is a compile time constant.
Relaxing that rule would be useful.

Then there is the brain-dead definition of _Static_assert() that makes
it pretty near completely useless (I can't remember Linus's words) for
anything non-trivial.
To be useful it would need to be deferred until after the optimiser
has done all its processing an only trigger if the call hasn't been
optimised away and the condition is either non-constant or false.
clang's 'infinite wisdom' decided to unconditionally output the cpp
output of the expression in the error message (even when there was
a caller provided message). When min() was using it that could be
a few hundred bytes of impenetrable text in a normal call - never
mind the nested ones that hit 10+MB because of a requirement to return
'constant integer expressions'.

It would also be useful to have a 'warning' form (or even an 'info'
that isn't an error even with -Werror).

Then you get _Generic().
WTF do the unselected cases not only have to be valid C but also get
checked for some warnings (like -Wsign-compare and 'unsigned >= 0').

...
> I was invited to WG14 this September. For now, I am only lurking. The
> thing I have in mind right now is to write a paper to allow the use of
> static_assert() in expressions (i.e. make it return 0 on success).
> That should be a relatively small change, but would bring a nice
> quality of life improvement.

Adding gcc's ({ expr; }) to the standard and allowing its output to
be as 'constant' as anything in 'expr' would solve a lot of issues.

You need to be able to have:
	if (x)
		static_assert(y)
for static_assert() to be usable as the main method of reporting
these sort on messages.
The best one in the kernel (ab)uses the message for calling a deprecated
function.

There are other things that get annoying.
I understand why offsetof() needs to be a 'compile time constant',
but that should only be for constant input.
There is no reason why offsetof(x, y[expression]) should be invalid
C for a non-constant expression.
(Although I've had issues even with a constant expression with a
certain compiler I'm forced to use sometimes.)

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From torvalds at linux-foundation.org  Sat Dec  7 10:26:01 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Sat, 7 Dec 2024 10:26:01 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de> <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>
Message-ID: <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>

On Sat, 7 Dec 2024 at 05:07, Martin Uecker <muecker at gwdg.de> wrote:
>
> VLA use *less* stack than a fixed size arrays with fixed bound.

Not really. You end up with tons of problems, not the least of which
is how to actually analyze the stack size. It also gets *very* nasty
to have code that declares the VLA size using an argument that is then
checked afterwards - and if you have a strong preference for
"declarations before code", you end up with *horrific* issues.

And even if you are super-careful, and you solved the analysis
problem, in practice VLAs will cause huge stack issues simply due to
code generation issues.  The compiler will end up doing extra
alignment and extra frame handling and saving, to the point where any
advantages the VLA would bring is completely dwarfed by all the
disadvantages.

We went through this. We are so *much* better off without VLAs that
it's not even funny.

Now when the compiler says "your stack size is big", you just look
"Oh, that struct should be allocated with kmalloc, not on the stack".
Boom. Done.

            Linus


From torvalds at linux-foundation.org  Sat Dec  7 10:19:34 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Sat, 7 Dec 2024 10:19:34 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com> <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com> <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
 <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
 <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com> <CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>
Message-ID: <CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com>

On Sat, 7 Dec 2024 at 04:24, Vincent Mailhol <vincent.mailhol at gmail.com> wrote:
>
> > No good - expands everything twice.
>
> And? __is_const_zero() does not evaluate its arguments, so no side effect:

No, the problem is literally the expansion.

Double expansion of these fundamental helpers gets exponential,
because they are used in various nested ways in other fundamental
helpers.

That's why we then spent so much effort on trying to clean up the
min/max macros, because a single line of code would expand to
literally tens of megabytes of horrific expansions.

And the problem with these things is that you can't make them inline
functions, so they have to be macros, and then you build up other
macros using them (like that "clamp()" macro), and it really gets
horrendous and affects the build time.

And yes, it is very sad. Particularly since a compiler would have a
really easy time with some nice helper builtins.

Of course, often the compiler *does* have helper builtins, but we
can't use them, because they aren't *quite* the right thing. Like that
"__builtin_constant_p()" not actually working for some situations
where we absolutely need not just a constant value, but a constant
_expression_ due to C parsing rules.

Quite a lot of the pain we tend to have with these things is directly
related to the fact that we often want to do these tests in contexts
like global array initializers etc.

If there is one feature of C I would have liked it is "allow inline
functions and statement expressions with constant arguments as
constant expressions". Other languages have done that, and it really
does help. And yes, it means that you have to basically have a
language interpreter in the compiler (you do want to allow loop
constructions etc), but it really is very useful.

Oh well. Even if compilers added that today, it would be years until
we could take advantage of it.

At one point I literally was thinking I'd do 'sparse' as a
pre-processor for kernel code, in order to have extended language
facilities like that.

            Linus


From maz at kernel.org  Sat Dec  7 11:07:37 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat,  7 Dec 2024 19:07:37 +0000
Subject: [PATCH 1/4] arm64/sysreg: Allow a 'Mapping' descriptor for system registers
In-Reply-To: <20241207190740.2607673-1-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
Message-ID: <20241207190740.2607673-2-maz@kernel.org>

*EL02 and *_EL12 system registers are actually only accessors for
EL0 and EL1 registers accessed from EL2 when HCR_EL2.E2H==1. They
do not have fields of their own.

To that effect, introduce a 'Mapping' entry, describing which
system register an _EL12 register maps to.

Implementation wise, this is handled the same was as Fields,
which ls only a comment.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/tools/gen-sysreg.awk | 2 +-
 arch/arm64/tools/sysreg         | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/gen-sysreg.awk b/arch/arm64/tools/gen-sysreg.awk
index d1254a056114e..1a2afc9fdd42e 100755
--- a/arch/arm64/tools/gen-sysreg.awk
+++ b/arch/arm64/tools/gen-sysreg.awk
@@ -206,7 +206,7 @@ END {
 
 # Currently this is effectivey a comment, in future we may want to emit
 # defines for the fields.
-/^Fields/ && block_current() == "Sysreg" {
+(/^Fields/ || /^Mapping/) && block_current() == "Sysreg" {
 	expect_fields(2)
 
 	if (next_bit != 63)
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index b081b54d6d227..b6846c601df6c 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -38,6 +38,13 @@
 # Fields	<fieldsname>
 # EndSysreg
 
+# For register names indicating a cross-EL access (*_EL12, *EL02),
+# a Mapping entry describes the register it actually accesses:
+
+# Sysreg 	<name_EL12>	<op0> 	<op1>	<crn>	<crm>	<op2>
+# Mapping	<name_EL1>
+# EndSysreg
+
 # For ID registers we adopt a few conventions for translating the
 # language in the ARM into defines:
 #
-- 
2.39.2



From maz at kernel.org  Sat Dec  7 11:07:38 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat,  7 Dec 2024 19:07:38 +0000
Subject: [PATCH 2/4] arm64/sysreg: Get rid of the TCR2_EL1x SysregFields
In-Reply-To: <20241207190740.2607673-1-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
Message-ID: <20241207190740.2607673-3-maz@kernel.org>

TCR2_ELx is a pretty bizarre construct, as it is shared between
TCR2_EL1 and TCR2_EL12. But the latter is obviously only an
accessor to the former.

In order to make things more consistent, upgrade TCR2_EL1x to
a full-blown sysreg definition for TCR2_EL1, and describe TCR2_EL12
as a mapping to TCR2_EL1.

This results in a couple of minor changes to the actual code.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 2 +-
 arch/arm64/kvm/at.c            | 6 +++---
 arch/arm64/mm/proc.S           | 5 +++--
 arch/arm64/tools/sysreg        | 8 ++------
 4 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed84..7712df48758e9 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2376,7 +2376,7 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused)
 #ifdef CONFIG_ARM64_POE
 static void cpu_enable_poe(const struct arm64_cpu_capabilities *__unused)
 {
-	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1x_E0POE);
+	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1_E0POE);
 	sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_E0POE);
 }
 #endif
diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
index 8c5d7990e5b31..0905b8778a9bb 100644
--- a/arch/arm64/kvm/at.c
+++ b/arch/arm64/kvm/at.c
@@ -111,7 +111,7 @@ static bool s1pie_enabled(struct kvm_vcpu *vcpu, enum trans_regime regime)
 		return vcpu_read_sys_reg(vcpu, TCR2_EL2) & TCR2_EL2_PIE;
 	case TR_EL10:
 		return  (__vcpu_sys_reg(vcpu, HCRX_EL2) & HCRX_EL2_TCR2En) &&
-			(__vcpu_sys_reg(vcpu, TCR2_EL1) & TCR2_EL1x_PIE);
+			(__vcpu_sys_reg(vcpu, TCR2_EL1) & TCR2_EL1_PIE);
 	default:
 		BUG();
 	}
@@ -140,8 +140,8 @@ static void compute_s1poe(struct kvm_vcpu *vcpu, struct s1_walk_info *wi)
 		}
 
 		val = __vcpu_sys_reg(vcpu, TCR2_EL1);
-		wi->poe = val & TCR2_EL1x_POE;
-		wi->e0poe = val & TCR2_EL1x_E0POE;
+		wi->poe = val & TCR2_EL1_POE;
+		wi->e0poe = val & TCR2_EL1_E0POE;
 	}
 }
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index b8edc5765441e..fb30c8804f87b 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -501,7 +501,7 @@ alternative_else_nop_endif
 #ifdef CONFIG_ARM64_HAFT
 	cmp	x9, ID_AA64MMFR1_EL1_HAFDBS_HAFT
 	b.lt	1f
-	orr	tcr2, tcr2, TCR2_EL1x_HAFT
+	orr	tcr2, tcr2, TCR2_EL1_HAFT
 #endif /* CONFIG_ARM64_HAFT */
 1:
 #endif	/* CONFIG_ARM64_HW_AFDBM */
@@ -532,7 +532,8 @@ alternative_else_nop_endif
 #undef PTE_MAYBE_NG
 #undef PTE_MAYBE_SHARED
 
-	orr	tcr2, tcr2, TCR2_EL1x_PIE
+	orr	tcr2, tcr2, TCR2_EL1_PIE
+	msr	REG_TCR2_EL1, x0
 
 .Lskip_indirection:
 
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index b6846c601df6c..19d137d9c50ed 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2999,7 +2999,7 @@ Sysreg	TTBR1_EL1	3	0	2	0	1
 Fields	TTBRx_EL1
 EndSysreg
 
-SysregFields	TCR2_EL1x
+Sysreg	TCR2_EL1	3	0	2	0	3
 Res0	63:16
 Field	15	DisCH1
 Field	14	DisCH0
@@ -3013,14 +3013,10 @@ Field	3	POE
 Field	2	E0POE
 Field	1	PIE
 Field	0	PnCH
-EndSysregFields
-
-Sysreg	TCR2_EL1	3	0	2	0	3
-Fields	TCR2_EL1x
 EndSysreg
 
 Sysreg	TCR2_EL12	3	5	2	0	3
-Fields	TCR2_EL1x
+Mapping	TCR2_EL1
 EndSysreg
 
 Sysreg	TCR2_EL2	3	4	2	0	3
-- 
2.39.2



From maz at kernel.org  Sat Dec  7 11:07:36 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat,  7 Dec 2024 19:07:36 +0000
Subject: [PATCH 0/4] arm64/sysreg: Get rid of *_ELx as fields for EL12 accessors
Message-ID: <20241207190740.2607673-1-maz@kernel.org>

We keep adding *_ELx definition to the sysreg as an abstraction for
the mapping between an EL1 register and its EL12 counterpart.

But nothing in the architecture has these ELx suffixes to describe
such abstraction. When they are mentioned, it always is as a shortcut
for EL1, EL2 or EL3, and never for EL12. That's because *_EL12 are
*not* registers. They are accessors, nothing else. So what we
currently have is not only bizarre, it is actively wrong.

This small series aims are injecting some sanity, by explicitly
describing EL12 registers as mappings to EL1 registers, and keeping
the ELx description as fields for the EL{1,2} registers.

Marc Zyngier (4):
  arm64/sysreg: Allow a 'Mapping' descriptor for system registers
  arm64/sysreg: Get rid of the TCR2_EL1x SysregFields
  arm64/sysreg: Convert *_EL12 accessors to Mapping
  arm64/sysreg: Get rid of CPACR_ELx SysregFields

 arch/arm64/include/asm/el2_setup.h      |  6 ++--
 arch/arm64/include/asm/kvm_arm.h        |  2 --
 arch/arm64/include/asm/kvm_emulate.h    | 40 ++++++++++++-------------
 arch/arm64/include/asm/kvm_nested.h     |  8 ++---
 arch/arm64/kernel/cpufeature.c          |  4 +--
 arch/arm64/kvm/at.c                     |  6 ++--
 arch/arm64/kvm/emulate-nested.c         |  2 +-
 arch/arm64/kvm/fpsimd.c                 |  2 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 +--
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  4 +--
 arch/arm64/kvm/hyp/nvhe/pkvm.c          |  2 +-
 arch/arm64/kvm/hyp/nvhe/switch.c        |  6 ++--
 arch/arm64/kvm/hyp/vhe/switch.c         | 16 +++++-----
 arch/arm64/mm/proc.S                    |  5 ++--
 arch/arm64/tools/gen-sysreg.awk         |  2 +-
 arch/arm64/tools/sysreg                 | 39 ++++++++++++------------
 16 files changed, 73 insertions(+), 75 deletions(-)

-- 
2.39.2



From maz at kernel.org  Sat Dec  7 11:07:39 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat,  7 Dec 2024 19:07:39 +0000
Subject: [PATCH 3/4] arm64/sysreg: Convert *_EL12 accessors to Mapping
In-Reply-To: <20241207190740.2607673-1-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
Message-ID: <20241207190740.2607673-4-maz@kernel.org>

Perform a bulk convert of the remaining EL12 accessors to use the
Mapping qualifier, which meakes things a bit clearer.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/tools/sysreg | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 19d137d9c50ed..ad2f6265f7948 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2954,23 +2954,23 @@ Field	63:0	PhysicalOffset
 EndSysreg
 
 Sysreg	CPACR_EL12	3	5	1	0	2
-Fields	CPACR_ELx
+Mapping	CPACR_EL1
 EndSysreg
 
 Sysreg	ZCR_EL12	3	5	1	2	0
-Fields	ZCR_ELx
+Mapping	ZCR_EL1
 EndSysreg
 
 Sysreg	SMCR_EL12	3	5	1	2	6
-Fields	SMCR_ELx
+Mapping	SMCR_EL1
 EndSysreg
 
 Sysreg	GCSCR_EL12	3	5	2	5	0
-Fields	GCSCR_ELx
+Mapping	GCSCR_EL1
 EndSysreg
 
 Sysreg	GCSPR_EL12	3	5	2	5	1
-Fields	GCSPR_ELx
+Mapping	GCSPR_EL1
 EndSysreg
 
 Sysreg	FAR_EL12	3	5	6	0	0
@@ -2982,7 +2982,7 @@ Fields	MPAM1_ELx
 EndSysreg
 
 Sysreg	CONTEXTIDR_EL12	3	5	13	0	1
-Fields	CONTEXTIDR_ELx
+Mapping	CONTEXTIDR_EL1
 EndSysreg
 
 SysregFields TTBRx_EL1
@@ -3087,7 +3087,7 @@ Fields	PIRx_ELx
 EndSysreg
 
 Sysreg	PIRE0_EL12	3	5	10	2	2
-Fields	PIRx_ELx
+Mapping	PIRE0_EL1
 EndSysreg
 
 Sysreg	PIRE0_EL2	3	4	10	2	2
@@ -3099,7 +3099,7 @@ Fields	PIRx_ELx
 EndSysreg
 
 Sysreg	PIR_EL12	3	5	10	2	3
-Fields	PIRx_ELx
+Mapping	PIR_EL1
 EndSysreg
 
 Sysreg	PIR_EL2		3	4	10	2	3
@@ -3119,7 +3119,7 @@ Fields	PIRx_ELx
 EndSysreg
 
 Sysreg	POR_EL12	3	5	10	2	4
-Fields	PIRx_ELx
+Mapping	POR_EL1
 EndSysreg
 
 Sysreg	S2POR_EL1	3	0	10	2	5
-- 
2.39.2



From maz at kernel.org  Sat Dec  7 11:07:40 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat,  7 Dec 2024 19:07:40 +0000
Subject: [PATCH 4/4] arm64/sysreg: Get rid of CPACR_ELx SysregFields
In-Reply-To: <20241207190740.2607673-1-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
Message-ID: <20241207190740.2607673-5-maz@kernel.org>

There is no such thing as CPACR_ELx in the architecture.
What we have is CPACR_EL1, for which CPTR_EL12 is an accessor.

Rename CPACR_ELx_* to CPACR_EL1_*, and fix the bit of code using
these names.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/el2_setup.h      |  6 ++--
 arch/arm64/include/asm/kvm_arm.h        |  2 --
 arch/arm64/include/asm/kvm_emulate.h    | 40 ++++++++++++-------------
 arch/arm64/include/asm/kvm_nested.h     |  8 ++---
 arch/arm64/kernel/cpufeature.c          |  2 +-
 arch/arm64/kvm/emulate-nested.c         |  2 +-
 arch/arm64/kvm/fpsimd.c                 |  2 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 +--
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  4 +--
 arch/arm64/kvm/hyp/nvhe/pkvm.c          |  2 +-
 arch/arm64/kvm/hyp/nvhe/switch.c        |  6 ++--
 arch/arm64/kvm/hyp/vhe/switch.c         | 16 +++++-----
 arch/arm64/tools/sysreg                 |  6 +---
 13 files changed, 47 insertions(+), 53 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 85ef966c08cd2..cc39c57df7873 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -154,7 +154,7 @@
 /* Coprocessor traps */
 .macro __init_el2_cptr
 	__check_hvhe .LnVHE_\@, x1
-	mov	x0, #CPACR_ELx_FPEN
+	mov	x0, #CPACR_EL1_FPEN
 	msr	cpacr_el1, x0
 	b	.Lskip_set_cptr_\@
 .LnVHE_\@:
@@ -332,7 +332,7 @@
 
 	// (h)VHE case
 	mrs	x0, cpacr_el1			// Disable SVE traps
-	orr	x0, x0, #CPACR_ELx_ZEN
+	orr	x0, x0, #CPACR_EL1_ZEN
 	msr	cpacr_el1, x0
 	b	.Lskip_set_cptr_\@
 
@@ -353,7 +353,7 @@
 
 	// (h)VHE case
 	mrs	x0, cpacr_el1			// Disable SME traps
-	orr	x0, x0, #CPACR_ELx_SMEN
+	orr	x0, x0, #CPACR_EL1_SMEN
 	msr	cpacr_el1, x0
 	b	.Lskip_set_cptr_sme_\@
 
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3e0f0de1d2da8..43e365fbff0b2 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -391,8 +391,6 @@
 	ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
 	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64), ECN(ERET)
 
-#define CPACR_EL1_TTA		(1 << 28)
-
 #define kvm_mode_names				\
 	{ PSR_MODE_EL0t,	"EL0t" },	\
 	{ PSR_MODE_EL1t,	"EL1t" },	\
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index cf811009a33c9..4f1d99725f6b3 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -556,13 +556,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
 	({								\
 		u64 cptr = 0;						\
 									\
-		if ((set) & CPACR_ELx_FPEN)				\
+		if ((set) & CPACR_EL1_FPEN)				\
 			cptr |= CPTR_EL2_TFP;				\
-		if ((set) & CPACR_ELx_ZEN)				\
+		if ((set) & CPACR_EL1_ZEN)				\
 			cptr |= CPTR_EL2_TZ;				\
-		if ((set) & CPACR_ELx_SMEN)				\
+		if ((set) & CPACR_EL1_SMEN)				\
 			cptr |= CPTR_EL2_TSM;				\
-		if ((clr) & CPACR_ELx_TTA)				\
+		if ((clr) & CPACR_EL1_TTA)				\
 			cptr |= CPTR_EL2_TTA;				\
 		if ((clr) & CPTR_EL2_TAM)				\
 			cptr |= CPTR_EL2_TAM;				\
@@ -576,13 +576,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
 	({								\
 		u64 cptr = 0;						\
 									\
-		if ((clr) & CPACR_ELx_FPEN)				\
+		if ((clr) & CPACR_EL1_FPEN)				\
 			cptr |= CPTR_EL2_TFP;				\
-		if ((clr) & CPACR_ELx_ZEN)				\
+		if ((clr) & CPACR_EL1_ZEN)				\
 			cptr |= CPTR_EL2_TZ;				\
-		if ((clr) & CPACR_ELx_SMEN)				\
+		if ((clr) & CPACR_EL1_SMEN)				\
 			cptr |= CPTR_EL2_TSM;				\
-		if ((set) & CPACR_ELx_TTA)				\
+		if ((set) & CPACR_EL1_TTA)				\
 			cptr |= CPTR_EL2_TTA;				\
 		if ((set) & CPTR_EL2_TAM)				\
 			cptr |= CPTR_EL2_TAM;				\
@@ -595,13 +595,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
 #define cpacr_clear_set(clr, set)					\
 	do {								\
 		BUILD_BUG_ON((set) & CPTR_VHE_EL2_RES0);		\
-		BUILD_BUG_ON((clr) & CPACR_ELx_E0POE);			\
-		__build_check_all_or_none((clr), CPACR_ELx_FPEN);	\
-		__build_check_all_or_none((set), CPACR_ELx_FPEN);	\
-		__build_check_all_or_none((clr), CPACR_ELx_ZEN);	\
-		__build_check_all_or_none((set), CPACR_ELx_ZEN);	\
-		__build_check_all_or_none((clr), CPACR_ELx_SMEN);	\
-		__build_check_all_or_none((set), CPACR_ELx_SMEN);	\
+		BUILD_BUG_ON((clr) & CPACR_EL1_E0POE);			\
+		__build_check_all_or_none((clr), CPACR_EL1_FPEN);	\
+		__build_check_all_or_none((set), CPACR_EL1_FPEN);	\
+		__build_check_all_or_none((clr), CPACR_EL1_ZEN);	\
+		__build_check_all_or_none((set), CPACR_EL1_ZEN);	\
+		__build_check_all_or_none((clr), CPACR_EL1_SMEN);	\
+		__build_check_all_or_none((set), CPACR_EL1_SMEN);	\
 									\
 		if (has_vhe() || has_hvhe())				\
 			sysreg_clear_set(cpacr_el1, clr, set);		\
@@ -624,16 +624,16 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
 	u64 val;
 
 	if (has_vhe()) {
-		val = (CPACR_ELx_FPEN | CPACR_EL1_ZEN_EL1EN);
+		val = (CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN);
 		if (cpus_have_final_cap(ARM64_SME))
 			val |= CPACR_EL1_SMEN_EL1EN;
 	} else if (has_hvhe()) {
-		val = CPACR_ELx_FPEN;
+		val = CPACR_EL1_FPEN;
 
 		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
-			val |= CPACR_ELx_ZEN;
+			val |= CPACR_EL1_ZEN;
 		if (cpus_have_final_cap(ARM64_SME))
-			val |= CPACR_ELx_SMEN;
+			val |= CPACR_EL1_SMEN;
 	} else {
 		val = CPTR_NVHE_EL2_RES1;
 
@@ -685,7 +685,7 @@ static inline bool ____cptr_xen_trap_enabled(const struct kvm_vcpu *vcpu,
 #define __guest_hyp_cptr_xen_trap_enabled(vcpu, xen)				\
 	(!vcpu_has_nv(vcpu) ? false :						\
 	 ____cptr_xen_trap_enabled(vcpu,					\
-				   SYS_FIELD_GET(CPACR_ELx, xen,		\
+				   SYS_FIELD_GET(CPACR_EL1, xen,		\
 						 vcpu_sanitised_cptr_el2(vcpu))))
 
 static inline bool guest_hyp_fpsimd_traps_enabled(const struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 233e655227164..6cd08198bf195 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -33,14 +33,14 @@ static inline u64 translate_tcr_el2_to_tcr_el1(u64 tcr)
 
 static inline u64 translate_cptr_el2_to_cpacr_el1(u64 cptr_el2)
 {
-	u64 cpacr_el1 = CPACR_ELx_RES1;
+	u64 cpacr_el1 = CPACR_EL1_RES1;
 
 	if (cptr_el2 & CPTR_EL2_TTA)
-		cpacr_el1 |= CPACR_ELx_TTA;
+		cpacr_el1 |= CPACR_EL1_TTA;
 	if (!(cptr_el2 & CPTR_EL2_TFP))
-		cpacr_el1 |= CPACR_ELx_FPEN;
+		cpacr_el1 |= CPACR_EL1_FPEN;
 	if (!(cptr_el2 & CPTR_EL2_TZ))
-		cpacr_el1 |= CPACR_ELx_ZEN;
+		cpacr_el1 |= CPACR_EL1_ZEN;
 
 	cpacr_el1 |= cptr_el2 & (CPTR_EL2_TCPAC | CPTR_EL2_TAM);
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 7712df48758e9..6e220da3a495b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2377,7 +2377,7 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused)
 static void cpu_enable_poe(const struct arm64_cpu_capabilities *__unused)
 {
 	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1_E0POE);
-	sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_E0POE);
+	sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_E0POE);
 }
 #endif
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 1ffbfd1c3cf2e..f1b7287e1f3c3 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -494,7 +494,7 @@ static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
 	if (!vcpu_el2_e2h_is_set(vcpu))
 		val = translate_cptr_el2_to_cpacr_el1(val);
 
-	if (val & CPACR_ELx_TTA)
+	if (val & CPACR_EL1_TTA)
 		return BEHAVE_FORWARD_RW;
 
 	return BEHAVE_HANDLE_LOCALLY;
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index ea5484ce1f3ba..98718bd65bf15 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -169,7 +169,7 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 	if (has_vhe() && system_supports_sme()) {
 		/* Also restore EL0 state seen on entry */
 		if (vcpu_get_flag(vcpu, HOST_SME_ENABLED))
-			sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_SMEN);
+			sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_SMEN);
 		else
 			sysreg_clear_set(CPACR_EL1,
 					 CPACR_EL1_SMEN_EL0EN,
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 34f53707892df..abfa6ad92e91e 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -419,9 +419,9 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 
 	/* First disable enough traps to allow us to update the registers */
 	if (sve_guest || (is_protected_kvm_enabled() && system_supports_sve()))
-		cpacr_clear_set(0, CPACR_ELx_FPEN | CPACR_ELx_ZEN);
+		cpacr_clear_set(0, CPACR_EL1_FPEN | CPACR_EL1_ZEN);
 	else
-		cpacr_clear_set(0, CPACR_ELx_FPEN);
+		cpacr_clear_set(0, CPACR_EL1_FPEN);
 	isb();
 
 	/* Write out the host state if it's in the registers */
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 6aa0b13d86e58..6c90ef6736d63 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -68,7 +68,7 @@ static void fpsimd_sve_sync(struct kvm_vcpu *vcpu)
 	if (!guest_owns_fp_regs())
 		return;
 
-	cpacr_clear_set(0, CPACR_ELx_FPEN | CPACR_ELx_ZEN);
+	cpacr_clear_set(0, CPACR_EL1_FPEN | CPACR_EL1_ZEN);
 	isb();
 
 	if (vcpu_has_sve(vcpu))
@@ -481,7 +481,7 @@ void handle_trap(struct kvm_cpu_context *host_ctxt)
 		handle_host_smc(host_ctxt);
 		break;
 	case ESR_ELx_EC_SVE:
-		cpacr_clear_set(0, CPACR_ELx_ZEN);
+		cpacr_clear_set(0, CPACR_EL1_ZEN);
 		isb();
 		sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1,
 				       SYS_ZCR_EL2);
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 01616c39a8107..a6638c4ecd32d 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -68,7 +68,7 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
 	/* Trap SVE */
 	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), feature_ids)) {
 		if (has_hvhe())
-			cptr_clear |= CPACR_ELx_ZEN;
+			cptr_clear |= CPACR_EL1_ZEN;
 		else
 			cptr_set |= CPTR_EL2_TZ;
 	}
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index cc69106734ca7..0f6b01b3da5cf 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -48,14 +48,14 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 	val |= has_hvhe() ? CPACR_EL1_TTA : CPTR_EL2_TTA;
 	if (cpus_have_final_cap(ARM64_SME)) {
 		if (has_hvhe())
-			val &= ~CPACR_ELx_SMEN;
+			val &= ~CPACR_EL1_SMEN;
 		else
 			val |= CPTR_EL2_TSM;
 	}
 
 	if (!guest_owns_fp_regs()) {
 		if (has_hvhe())
-			val &= ~(CPACR_ELx_FPEN | CPACR_ELx_ZEN);
+			val &= ~(CPACR_EL1_FPEN | CPACR_EL1_ZEN);
 		else
 			val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
 
@@ -192,7 +192,7 @@ static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
 
 		/* Re-enable SVE traps if not supported for the guest vcpu. */
 		if (!vcpu_has_sve(vcpu))
-			cpacr_clear_set(CPACR_ELx_ZEN, 0);
+			cpacr_clear_set(CPACR_EL1_ZEN, 0);
 
 	} else {
 		__fpsimd_save_state(*host_data_ptr(fpsimd_state));
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 80581b1c39959..59d992455793d 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -77,12 +77,12 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
 	 * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
 	 * shift value for trapping the AMU accesses.
 	 */
-	u64 val = CPACR_ELx_TTA | CPTR_EL2_TAM;
+	u64 val = CPACR_EL1_TTA | CPTR_EL2_TAM;
 
 	if (guest_owns_fp_regs()) {
-		val |= CPACR_ELx_FPEN;
+		val |= CPACR_EL1_FPEN;
 		if (vcpu_has_sve(vcpu))
-			val |= CPACR_ELx_ZEN;
+			val |= CPACR_EL1_ZEN;
 	} else {
 		__activate_traps_fpsimd32(vcpu);
 	}
@@ -122,13 +122,13 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
 	 * hypervisor has traps enabled to dispel any illusion of something more
 	 * complicated taking place.
 	 */
-	if (!(SYS_FIELD_GET(CPACR_ELx, FPEN, cptr) & BIT(0)))
-		val &= ~CPACR_ELx_FPEN;
-	if (!(SYS_FIELD_GET(CPACR_ELx, ZEN, cptr) & BIT(0)))
-		val &= ~CPACR_ELx_ZEN;
+	if (!(SYS_FIELD_GET(CPACR_EL1, FPEN, cptr) & BIT(0)))
+		val &= ~CPACR_EL1_FPEN;
+	if (!(SYS_FIELD_GET(CPACR_EL1, ZEN, cptr) & BIT(0)))
+		val &= ~CPACR_EL1_ZEN;
 
 	if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
-		val |= cptr & CPACR_ELx_E0POE;
+		val |= cptr & CPACR_EL1_E0POE;
 
 	val |= cptr & CPTR_EL2_TCPAC;
 
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index ad2f6265f7948..4e575c1b266f7 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1985,7 +1985,7 @@ Field	1	A
 Field	0	M
 EndSysreg
 
-SysregFields	CPACR_ELx
+Sysreg	CPACR_EL1	3	0	1	0	2
 Res0	63:30
 Field	29	E0POE
 Field	28	TTA
@@ -1996,10 +1996,6 @@ Field	21:20	FPEN
 Res0	19:18
 Field	17:16	ZEN
 Res0	15:0
-EndSysregFields
-
-Sysreg	CPACR_EL1	3	0	1	0	2
-Fields	CPACR_ELx
 EndSysreg
 
 Sysreg	SMPRI_EL1	3	0	1	2	4
-- 
2.39.2



From muecker at gwdg.de  Sat Dec  7 11:19:37 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sat, 7 Dec 2024 20:19:37 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
	 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>
	 <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
Message-ID: <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de>

Am Samstag, dem 07.12.2024 um 10:26 -0800 schrieb Linus Torvalds:
> On Sat, 7 Dec 2024 at 05:07, Martin Uecker <muecker at gwdg.de> wrote:
> > 
> > VLA use *less* stack than a fixed size arrays with fixed bound.
> 
> Not really. You end up with tons of problems, not the least of which
> is how to actually analyze the stack size. It also gets *very* nasty
> to have code that declares the VLA size using an argument that is then
> checked afterwards - and if you have a strong preference for
> "declarations before code", you end up with *horrific* issues.
> 
> And even if you are super-careful, and you solved the analysis
> problem, in practice VLAs will cause huge stack issues simply due to
> code generation issues.  The compiler will end up doing extra
> alignment and extra frame handling and saving, to the point where any
> advantages the VLA would bring is completely dwarfed by all the
> disadvantages.

But that all seem solvable issues on the compiler side.  If you?
said the maximum stack size for arrays we tolerate is X,
then a compiler could?tell you if?

a) this is not guaranteed in a specific situation (-Wvla-larher-than)
and?
b) transform the array automatically to fixed size array
of size X *or* something smaller when it can show this.

Because now you do the exact same thing manually while losing
precise bounds checking.

Martin

> 
> We went through this. We are so *much* better off without VLAs that
> it's not even funny.
> 
> Now when the compiler says "your stack size is big", you just look
> "Oh, that struct should be allocated with kmalloc, not on the stack".
> Boom. Done.
> 
>             Linus



From muecker at gwdg.de  Sat Dec  7 11:51:49 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sat, 7 Dec 2024 20:51:49 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
	 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
	 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
	 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
	 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
	 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>
	 <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
	 <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
	 <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com>
	 <CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>
	 <CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com>
Message-ID: <6b8c9b942ba6e85a3f1e4eef65a9916333502881.camel@gwdg.de>

Am Samstag, dem 07.12.2024 um 10:19 -0800 schrieb Linus Torvalds:
> On Sat, 7 Dec 2024 at 04:24, Vincent Mailhol <vincent.mailhol at gmail.com> wrote:
> > 
> > > No good - expands everything twice.
> > 
> > And? __is_const_zero() does not evaluate its arguments, so no side effect:
> 
> No, the problem is literally the expansion.
> 
> Double expansion of these fundamental helpers gets exponential,
> because they are used in various nested ways in other fundamental
> helpers.
> 
> That's why we then spent so much effort on trying to clean up the
> min/max macros, because a single line of code would expand to
> literally tens of megabytes of horrific expansions.
> 
> And the problem with these things is that you can't make them inline
> functions, so they have to be macros, and then you build up other
> macros using them (like that "clamp()" macro), and it really gets
> horrendous and affects the build time.
> 
> And yes, it is very sad. Particularly since a compiler would have a
> really easy time with some nice helper builtins.
> 
> Of course, often the compiler *does* have helper builtins, but we
> can't use them, because they aren't *quite* the right thing. Like that
> "__builtin_constant_p()" not actually working for some situations
> where we absolutely need not just a constant value, but a constant
> _expression_ due to C parsing rules.
> 
> Quite a lot of the pain we tend to have with these things is directly
> related to the fact that we often want to do these tests in contexts
> like global array initializers etc.
> 
> If there is one feature of C I would have liked it is "allow inline
> functions and statement expressions with constant arguments as
> constant expressions". Other languages have done that, and it really
> does help. And yes, it means that you have to basically have a
> language interpreter in the compiler (you do want to allow loop
> constructions etc), but it really is very useful.
> 
> Oh well. Even if compilers added that today, it would be years until
> we could take advantage of it.
> 
> At one point I literally was thinking I'd do 'sparse' as a
> pre-processor for kernel code, in order to have extended language
> facilities like that.

There exist proposals along those lines for C2Y.

>From a more near-term solution, I wonder if making it possible (or
easier) to return integer constant expressions from statement
expressions and allowing a restricted form of statement expressions?
at file scope would help?


Martin





From torvalds at linux-foundation.org  Sat Dec  7 12:28:32 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Sat, 7 Dec 2024 12:28:32 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de> <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de> <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
 <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de>
Message-ID: <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>

On Sat, 7 Dec 2024 at 11:19, Martin Uecker <muecker at gwdg.de> wrote:
>
> But that all seem solvable issues on the compiler side.

You know, there was a whole *architecture* that was designed and
predicated on "it's all solvable on the compiler side".

That architecture was pure and utter *shit*.

Because no, it's not solvable on the compiler side.

Getting things like value range analysis right on the compiler side is
fundamentally hard.

It's hard to the point where either you only get it for the simple
cases - yes, I can show you a ton of real code where it's trivial - or
you need to have explicit markings in the source code to help the
compiler, and then you end up having to have the compiler (or some
other tool) validate those with asserts or whatever.

And random asserts ARE NOT ACCEPTABLE in the kernel outside of pure
debug builds.

They may be acceptable in most other situations, but in a kernel you
can't just say "we stop now because it turns out the analysis was
broken and the manual notes could be fooled by an attacker".

Now, would we want to have proper value *static* range analysis in the
kernel for other reasons? Oh yes. It would often be very nice to have
the ability to state "this value is trusted and is in this range", and
have it percolate all the way down, both for optimization purposes but
also for various sanity check purposes.

But it's simply not sanely available in the generic case.

> a) this is not guaranteed in a specific situation (-Wvla-larher-than)

We'd either get horrendous numbers of false positives that we then
have to manually add special code for, or

> b) transform the array automatically to fixed size array
> of size X *or* something smaller when it can show this.

we'd just do this by hand *once* and for all, and say "VLA's didn't work out".

So yeah. We did (b) by hand.

We used to have VLA's in the kernel. It was a disaster. We got rid of
them, because the (big) pain wasn't worth the (few) places it was
actually useful.

So we have been VLA-free for the last five years, and it's been good.

Simplify.

             Linus


From torvalds at linux-foundation.org  Sat Dec  7 12:31:09 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Sat, 7 Dec 2024 12:31:09 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <6b8c9b942ba6e85a3f1e4eef65a9916333502881.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com> <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com> <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
 <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
 <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com> <CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>
 <CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com> <6b8c9b942ba6e85a3f1e4eef65a9916333502881.camel@gwdg.de>
Message-ID: <CAHk-=whzFAaksqMdYeYC=T82tny1HnGGcYu_xJTXZF1OZwVziQ@mail.gmail.com>

On Sat, 7 Dec 2024 at 11:51, Martin Uecker <muecker at gwdg.de> wrote:
>
> Am Samstag, dem 07.12.2024 um 10:19 -0800 schrieb Linus Torvalds:
> >
> > If there is one feature of C I would have liked it is "allow inline
> > functions and statement expressions with constant arguments as
> > constant expressions".
>
> There exist proposals along those lines for C2Y.
>
> From a more near-term solution, I wonder if making it possible (or
> easier) to return integer constant expressions from statement
> expressions and allowing a restricted form of statement expressions
> at file scope would help?

Even a more limited form of this would have been useful several times,
but as mentioned, the problem tends to be that we end up supporting
compilers for many years.

So then we end up having to work with older compilers without that
feature, and can't actually clean stuff up until many years after the
fact.

We're currently still accepting gcc-5.1 as a compiler, although it's
time to look at that and probably (judging by what stable distros use)
upgrade to something like gcc-8.1 as the minimum supported compiler
version.

            Linus


From David.Laight at ACULAB.COM  Sat Dec  7 12:54:35 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sat, 7 Dec 2024 20:54:35 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=whzFAaksqMdYeYC=T82tny1HnGGcYu_xJTXZF1OZwVziQ@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>
 <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
 <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
 <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com>
 <CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>
 <CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com>
 <6b8c9b942ba6e85a3f1e4eef65a9916333502881.camel@gwdg.de>
 <CAHk-=whzFAaksqMdYeYC=T82tny1HnGGcYu_xJTXZF1OZwVziQ@mail.gmail.com>
Message-ID: <6b05ec695abc465e9b221fb1180a0fa1@AcuMS.aculab.com>

From: Linus Torvalds
> Sent: 07 December 2024 20:31
...
> We're currently still accepting gcc-5.1 as a compiler, although it's
> time to look at that and probably (judging by what stable distros use)
> upgrade to something like gcc-8.1 as the minimum supported compiler
> version.

That's going to annoy me.
The system disk in the system I test build kernel on is actually older
than the machine! (not by much).
And Ubuntu 18.04 (still getting some fixes) has gcc 7.5.0.

It isn't as though the 8.1 update is anything really major.
Disabling stack canaries would let an older compiler be used.
(and I might change the tests...)

Much more useful would be mandating 'asm go with outputs' which
would cut out a whole load horrid alternatives.

But that would make it pretty common that a kernel build would
need a later compiler than the one the distribution installed.

It maybe time to consider directly supporting downloading and
building the required compiler as part of a normal kernel build.
That would allow the minimum version to be set to a very recent
build and also make cross architecture build easier.
(In effect all builds become cross builds.)

NetBSD used to (may still do) import gcc into its CVS repository.
So that everything was built with a 'known' compiler.

It is (probably) less of a problem with clang.
People using clang are likely to have explicitly downloaded it.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From David.Laight at ACULAB.COM  Sat Dec  7 13:00:41 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sat, 7 Dec 2024 21:00:41 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <6b8c9b942ba6e85a3f1e4eef65a9916333502881.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
	 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
	 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
	 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
	 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
	 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>
	 <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
	 <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
	 <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com>
	 <CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>
	 <CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com>
 <6b8c9b942ba6e85a3f1e4eef65a9916333502881.camel@gwdg.de>
Message-ID: <20362fe79d494bd59471a9c0f002b2ef@AcuMS.aculab.com>

From: Martin Uecker
> Sent: 07 December 2024 19:52
...
> > Of course, often the compiler *does* have helper builtins, but we
> > can't use them, because they aren't *quite* the right thing. Like that
> > "__builtin_constant_p()" not actually working for some situations
> > where we absolutely need not just a constant value, but a constant
> > _expression_ due to C parsing rules.

In many cases the C language says 'constant integer expression'
but is reality something that passes __builtin_constant_p()
is likely to be fine - because the actual value isn't needed
until late on in the compilation.

...
> > If there is one feature of C I would have liked it is "allow inline
> > functions and statement expressions with constant arguments as
> > constant expressions". Other languages have done that, and it really
> > does help. And yes, it means that you have to basically have a
> > language interpreter in the compiler (you do want to allow loop
> > constructions etc), but it really is very useful.

It the output needs to be a constant the loop would have to be unrollable.
In those cases the result will be 'constant enough' for __builtin_constant_p()
and the compiler is actually already capable doing it.

...
> > At one point I literally was thinking I'd do 'sparse' as a
> > pre-processor for kernel code, in order to have extended language
> > facilities like that.

You could use m4 :-) and make it entirely unreadable.

> There exist proposals along those lines for C2Y.
> 
> From a more near-term solution, I wonder if making it possible (or
> easier) to return integer constant expressions from statement
> expressions and allowing a restricted form of statement expressions
> at file scope would help?

It would help a lot if a #define that just used local variables
to avoid arguments being re-expanded and for CSE could still
generate a constant value.
Does need to be a #define - to get token pasting and 'stringify'.
Although you would need something for reporting detected errors,
and builtin compiler support for const_true() for the detection
itself.



	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From muecker at gwdg.de  Sat Dec  7 13:06:04 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sat, 7 Dec 2024 22:06:04 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <20362fe79d494bd59471a9c0f002b2ef@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
	 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
	 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
	 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
	 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
	 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>
	 <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
	 <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
	 <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com>
	 <CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>
	 <CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com>
	 <6b8c9b942ba6e85a3f1e4eef65a9916333502881.camel@gwdg.de>
	 <20362fe79d494bd59471a9c0f002b2ef@AcuMS.aculab.com>
Message-ID: <63f538fceadf4e2ba93cdcaae9fab266e5a000ac.camel@gwdg.de>

Am Samstag, dem 07.12.2024 um 21:00 +0000 schrieb David Laight:
> From: Martin Uecker
> > Sent: 07 December 2024 19:52
...

> 
> > There exist proposals along those lines for C2Y.
> > 
> > From a more near-term solution, I wonder if making it possible (or
> > easier) to return integer constant expressions from statement
> > expressions and allowing a restricted form of statement expressions
> > at file scope would help?
> 
> It would help a lot if a #define that just used local variables
> to avoid arguments being re-expanded and for CSE could still
> generate a constant value.
> Does need to be a #define - to get token pasting and 'stringify'.
> Although you would need something for reporting detected errors,
> and builtin compiler support for const_true() for the detection
> itself.

We are super close:

https://godbolt.org/z/Tarq89bha

(if we ignore the grotesque hacks to get there, but this would go
away if the compiler does it internally)

Martin



From peter.griffin at linaro.org  Sat Dec  7 13:31:17 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Sat, 7 Dec 2024 21:31:17 +0000
Subject: [PATCH v4 6/7] phy: exynos5-usbdrd: subscribe to orientation
 notifier if required
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-6-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
 <20241206-gs101-phy-lanes-orientation-phy-v4-6-f5961268b149@linaro.org>
Message-ID: <CADrjBPoZqbAM=2zOdgXD_dTrgh-J7yE+OX_JSVJ42Lmzb-DPEw@mail.gmail.com>

Hi Andr?,

Firstly, thanks for all your work getting USB on Pixel 6 / gs101
working upstream :)

On Fri, 6 Dec 2024 at 16:31, Andr? Draszik <andre.draszik at linaro.org> wrote:
>
> gs101's SS phy needs to be configured differently based on the
> connector orientation, as the SS link can only be established if the
> mux is configured correctly.
>
> The code to handle programming of the mux is in place already, this commit
> now adds the missing pieces to subscribe to the Type-C orientation
> switch event.
>
> Note that for this all to work we rely on the USB controller
> re-initialising us. It should invoke our .exit() upon cable unplug, and
> during cable plug we'll receive the orientation event after which we
> expect our .init() to be called.
>
> Above reinitialisation happens if the DWC3 controller can enter runtime
> suspend automatically. For the DWC3 driver, this is an opt-in:
>     echo auto > /sys/devices/.../11110000.usb/power/control
> Once done, things work as long as the UDC is not bound as otherwise it
> stays busy because it doesn't cancel / stop outstanding TRBs. For now
> we have to manually unbind the UDC in that case:
>      echo "" > sys/kernel/config/usb_gadget/.../UDC
>
> Note that if the orientation-switch property is missing from the DT,
> the code will behave as before this commit (meaning for gs101 it will
> work in SS mode in one orientation only). Other platforms are not
> affected either way.
>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>

Notes on testing:

I tested this series with the corresponding DT using a Pixel 6 device
with 2 different USB hubs and also plugging directly into my laptop.
I've tried various combinations of plugging / unplugging from both
ends of the USB cable and changing cable orientation. With the latest
series the disconnect/reconnect always seems robustly detected and
Pixel is enumerated as a USB device by the host, adb connection to the
phone is possible even with the cable orientation changing between
disconnect/reconnect.

One thing I did notice during testing is that in one cable orientation
Pixel is detected as a `SuperSpeed USB device` by the host and in the
other cable orientation it is detected as a `high-speed USB device`.
Which suggests there is still a latent bug in the phy
re-configuration. Although I think it is fine to fix this
incrementally, as prior to this series the other cable orientation
didn't work at all.

I just tested my personal Pixel 6 running the downstream production
drivers, and that is detected as a `SuperSpeed USB device` in both
cable orientations.

Thanks,

Peter


From cristian.ciocaltea at collabora.com  Sat Dec  7 13:32:24 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 23:32:24 +0200
Subject: [PATCH 1/4] drm/rockchip: dw_hdmi_qp: Add support for RK3588 HDMI1
 output
In-Reply-To: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
References: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
Message-ID: <20241207-rk3588-hdmi1-v1-1-ca3a99b46a40@collabora.com>

Provide the basic support required to enable the second HDMI TX port
found on RK3588 SoC.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 119 ++++++++++++++++++++-----
 1 file changed, 96 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index c8b362cc2b95fd490029a9c0552ad9fbc5631d17..c36fc130b73440c9e3f2098f408a5cdd2f58e8ef 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -28,20 +28,26 @@
 #define RK3588_GRF_SOC_CON2		0x0308
 #define RK3588_HDMI0_HPD_INT_MSK	BIT(13)
 #define RK3588_HDMI0_HPD_INT_CLR	BIT(12)
+#define RK3588_HDMI1_HPD_INT_MSK	BIT(15)
+#define RK3588_HDMI1_HPD_INT_CLR	BIT(14)
 #define RK3588_GRF_SOC_CON7		0x031c
 #define RK3588_SET_HPD_PATH_MASK	GENMASK(13, 12)
 #define RK3588_GRF_SOC_STATUS1		0x0384
 #define RK3588_HDMI0_LEVEL_INT		BIT(16)
+#define RK3588_HDMI1_LEVEL_INT		BIT(24)
 #define RK3588_GRF_VO1_CON3		0x000c
+#define RK3588_GRF_VO1_CON6		0x0018
 #define RK3588_SCLIN_MASK		BIT(9)
 #define RK3588_SDAIN_MASK		BIT(10)
 #define RK3588_MODE_MASK		BIT(11)
 #define RK3588_I2S_SEL_MASK		BIT(13)
 #define RK3588_GRF_VO1_CON9		0x0024
 #define RK3588_HDMI0_GRANT_SEL		BIT(10)
+#define RK3588_HDMI1_GRANT_SEL		BIT(12)
 
 #define HIWORD_UPDATE(val, mask)	((val) | (mask) << 16)
 #define HOTPLUG_DEBOUNCE_MS		150
+#define MAX_HDMI_PORT_NUM		2
 
 struct rockchip_hdmi_qp {
 	struct device *dev;
@@ -53,6 +59,7 @@ struct rockchip_hdmi_qp {
 	struct phy *phy;
 	struct gpio_desc *enable_gpio;
 	struct delayed_work hpd_work;
+	int port_id;
 };
 
 static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder)
@@ -127,20 +134,24 @@ dw_hdmi_qp_rk3588_read_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
 	u32 val;
 
 	regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &val);
+	val &= hdmi->port_id ? RK3588_HDMI1_LEVEL_INT : RK3588_HDMI0_LEVEL_INT;
 
-	return val & RK3588_HDMI0_LEVEL_INT ?
-		connector_status_connected : connector_status_disconnected;
+	return val ? connector_status_connected : connector_status_disconnected;
 }
 
 static void dw_hdmi_qp_rk3588_setup_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
 {
 	struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data;
+	u32 val;
+
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR,
+				    RK3588_HDMI1_HPD_INT_CLR | RK3588_HDMI1_HPD_INT_MSK);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
+				    RK3588_HDMI0_HPD_INT_CLR | RK3588_HDMI0_HPD_INT_MSK);
 
-	regmap_write(hdmi->regmap,
-		     RK3588_GRF_SOC_CON2,
-		     HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
-				   RK3588_HDMI0_HPD_INT_CLR |
-				   RK3588_HDMI0_HPD_INT_MSK));
+	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 }
 
 static const struct dw_hdmi_qp_phy_ops rk3588_hdmi_phy_ops = {
@@ -173,8 +184,12 @@ static irqreturn_t dw_hdmi_qp_rk3588_hardirq(int irq, void *dev_id)
 	regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
 
 	if (intr_stat) {
-		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK,
-				    RK3588_HDMI0_HPD_INT_MSK);
+		if (hdmi->port_id)
+			val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK,
+					    RK3588_HDMI1_HPD_INT_MSK);
+		else
+			val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK,
+					    RK3588_HDMI0_HPD_INT_MSK);
 		regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 		return IRQ_WAKE_THREAD;
 	}
@@ -191,22 +206,44 @@ static irqreturn_t dw_hdmi_qp_rk3588_irq(int irq, void *dev_id)
 	if (!intr_stat)
 		return IRQ_NONE;
 
-	val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
-			    RK3588_HDMI0_HPD_INT_CLR);
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR,
+				    RK3588_HDMI1_HPD_INT_CLR);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
+				    RK3588_HDMI0_HPD_INT_CLR);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 
 	mod_delayed_work(system_wq, &hdmi->hpd_work,
 			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
 
-	val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK);
+	if (hdmi->port_id)
+		val |= HIWORD_UPDATE(0, RK3588_HDMI1_HPD_INT_MSK);
+	else
+		val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 
 	return IRQ_HANDLED;
 }
 
+struct rockchip_hdmi_qp_cfg {
+	unsigned int num_ports;
+	unsigned int port_ids[MAX_HDMI_PORT_NUM];
+	const struct dw_hdmi_qp_phy_ops *phy_ops;
+};
+
+static const struct rockchip_hdmi_qp_cfg rk3588_hdmi_cfg = {
+	.num_ports = 2,
+	.port_ids = {
+		0xfde80000,
+		0xfdea0000,
+	},
+	.phy_ops = &rk3588_hdmi_phy_ops,
+};
+
 static const struct of_device_id dw_hdmi_qp_rockchip_dt_ids[] = {
 	{ .compatible = "rockchip,rk3588-dw-hdmi-qp",
-	  .data = &rk3588_hdmi_phy_ops },
+	  .data = &rk3588_hdmi_cfg },
 	{},
 };
 MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids);
@@ -219,11 +256,13 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 		"ref" /* keep "ref" last */
 	};
 	struct platform_device *pdev = to_platform_device(dev);
+	const struct rockchip_hdmi_qp_cfg *cfg;
 	struct dw_hdmi_qp_plat_data plat_data;
 	struct drm_device *drm = data;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
 	struct rockchip_hdmi_qp *hdmi;
+	struct resource *res;
 	struct clk *clk;
 	int ret, irq, i;
 	u32 val;
@@ -235,12 +274,31 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 	if (!hdmi)
 		return -ENOMEM;
 
-	plat_data.phy_ops = of_device_get_match_data(dev);
-	if (!plat_data.phy_ops)
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
 		return -ENODEV;
 
-	plat_data.phy_data = hdmi;
 	hdmi->dev = &pdev->dev;
+	hdmi->port_id = -ENODEV;
+
+	/* Identify port ID by matching base IO address */
+	for (i = 0; i < cfg->num_ports; i++) {
+		if (res->start == cfg->port_ids[i]) {
+			hdmi->port_id = i;
+			break;
+		}
+	}
+	if (hdmi->port_id < 0) {
+		drm_err(hdmi, "Failed to match HDMI port ID\n");
+		return hdmi->port_id;
+	}
+
+	plat_data.phy_ops = cfg->phy_ops;
+	plat_data.phy_data = hdmi;
 
 	encoder = &hdmi->encoder.encoder;
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
@@ -303,17 +361,26 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 	      HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
 	      HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
 	      HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
-	regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON3, val);
+	regmap_write(hdmi->vo_regmap,
+		     hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
+		     val);
 
 	val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
 			    RK3588_SET_HPD_PATH_MASK);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
 
-	val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
-			    RK3588_HDMI0_GRANT_SEL);
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL,
+				    RK3588_HDMI1_GRANT_SEL);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
+				    RK3588_HDMI0_GRANT_SEL);
 	regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
 
-	val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK);
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK, RK3588_HDMI1_HPD_INT_MSK);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 
 	INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_qp_rk3588_hpd_work);
@@ -391,14 +458,20 @@ static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev)
 	      HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
 	      HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
 	      HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
-	regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON3, val);
+	regmap_write(hdmi->vo_regmap,
+		     hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
+		     val);
 
 	val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
 			    RK3588_SET_HPD_PATH_MASK);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
 
-	val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
-			    RK3588_HDMI0_GRANT_SEL);
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL,
+				    RK3588_HDMI1_GRANT_SEL);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
+				    RK3588_HDMI0_GRANT_SEL);
 	regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
 
 	dw_hdmi_qp_resume(dev, hdmi->hdmi);

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Sat Dec  7 13:32:23 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 23:32:23 +0200
Subject: [PATCH 0/4] Add support for HDMI1 output on RK3588 SoC
Message-ID: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>

The patches provide the basic support to handle the second HDMI output
port found on Rockchip RK3588 SoC.

For now I enabled it on Radxa ROCK 5B only, the board I've been using to
validate this.

** IMPORTANT **

The series has a runtime dependency on "phy: phy-rockchip-samsung-hdptx:
Don't use dt aliases to determine phy-id", a patch submitted recently by
Heiko [1].  Without applying it, the functionality on both HDMI TX ports
will break.

Furthermore, please note this is subject to the same limitations as
HDMI0 when it comes to the supported display modes.  The fixes provided
via [2] are not applicable to HDMI1, hence I will handle it separately
as soon as all dependencies are merged.

Thanks,
Cristian

[1] https://lore.kernel.org/lkml/20241206103401.1780416-3-heiko at sntech.de/
[2] https://lore.kernel.org/all/20241116-vop2-hdmi0-disp-modes-v1-0-2bca51db4898 at collabora.com/

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
Cristian Ciocaltea (4):
      drm/rockchip: dw_hdmi_qp: Add support for RK3588 HDMI1 output
      arm64: dts: rockchip: Add PHY node for HDMI1 TX port on RK3588
      arm64: dts: rockchip: Add HDMI1 node on RK3588
      arm64: dts: rockchip: Enable HDMI1 on rock-5b

 arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi  |  62 ++++++++++++
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts |  42 ++++++++-
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c  | 119 +++++++++++++++++++-----
 3 files changed, 198 insertions(+), 25 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241207-rk3588-hdmi1-704cbb7cd75f



From cristian.ciocaltea at collabora.com  Sat Dec  7 13:32:25 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 23:32:25 +0200
Subject: [PATCH 2/4] arm64: dts: rockchip: Add PHY node for HDMI1 TX port
 on RK3588
In-Reply-To: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
References: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
Message-ID: <20241207-rk3588-hdmi1-v1-2-ca3a99b46a40@collabora.com>

In preparation to enable the second HDMI output port found on RK3588
SoC, add the related PHY node.  This requires a GRF, hence add the
dependent node as well.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
index 0ce0934ec6b793af45585f67d5312434d80357de..68fa9806164776cef8732bb776e958003779ba28 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -67,6 +67,11 @@ u2phy1_otg: otg-port {
 		};
 	};
 
+	hdptxphy1_grf: syscon at fd5e4000 {
+		compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
+		reg = <0x0 0xfd5e4000 0x0 0x100>;
+	};
+
 	i2s8_8ch: i2s at fddc8000 {
 		compatible = "rockchip,rk3588-i2s-tdm";
 		reg = <0x0 0xfddc8000 0x0 0x1000>;
@@ -395,6 +400,22 @@ sata-port at 0 {
 		};
 	};
 
+	hdptxphy1: phy at fed70000 {
+		compatible = "rockchip,rk3588-hdptx-phy";
+		reg = <0x0 0xfed70000 0x0 0x2000>;
+		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>;
+		clock-names = "ref", "apb";
+		#phy-cells = <0>;
+		resets = <&cru SRST_HDPTX1>, <&cru SRST_P_HDPTX1>,
+			 <&cru SRST_HDPTX1_INIT>, <&cru SRST_HDPTX1_CMN>,
+			 <&cru SRST_HDPTX1_LANE>, <&cru SRST_HDPTX1_ROPLL>,
+			 <&cru SRST_HDPTX1_LCPLL>;
+		reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
+			      "lcpll";
+		rockchip,grf = <&hdptxphy1_grf>;
+		status = "disabled";
+	};
+
 	usbdp_phy1: phy at fed90000 {
 		compatible = "rockchip,rk3588-usbdp-phy";
 		reg = <0x0 0xfed90000 0x0 0x10000>;

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Sat Dec  7 13:32:26 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 23:32:26 +0200
Subject: [PATCH 3/4] arm64: dts: rockchip: Add HDMI1 node on RK3588
In-Reply-To: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
References: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
Message-ID: <20241207-rk3588-hdmi1-v1-3-ca3a99b46a40@collabora.com>

Add support for the second HDMI TX port found on RK3588 SoC.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi | 41 ++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
index 68fa9806164776cef8732bb776e958003779ba28..528319908247e90b33f9dbde0516f8bca849676f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -140,6 +140,47 @@ i2s10_8ch: i2s at fde00000 {
 		status = "disabled";
 	};
 
+	hdmi1: hdmi at fdea0000 {
+		compatible = "rockchip,rk3588-dw-hdmi-qp";
+		reg = <0x0 0xfdea0000 0x0 0x20000>;
+		clocks = <&cru PCLK_HDMITX1>,
+			 <&cru CLK_HDMITX1_EARC>,
+			 <&cru CLK_HDMITX1_REF>,
+			 <&cru MCLK_I2S6_8CH_TX>,
+			 <&cru CLK_HDMIHDP1>,
+			 <&cru HCLK_VO1>;
+		clock-names = "pclk", "earc", "ref", "aud", "hdp", "hclk_vo1";
+		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "avp", "cec", "earc", "main", "hpd";
+		phys = <&hdptxphy1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdmim2_tx1_cec &hdmim0_tx1_hpd
+			     &hdmim1_tx1_scl &hdmim1_tx1_sda>;
+		power-domains = <&power RK3588_PD_VO1>;
+		resets = <&cru SRST_HDMITX1_REF>, <&cru SRST_HDMIHDP1>;
+		reset-names = "ref", "hdp";
+		rockchip,grf = <&sys_grf>;
+		rockchip,vo-grf = <&vo1_grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi1_in: port at 0 {
+				reg = <0>;
+			};
+
+			hdmi1_out: port at 1 {
+				reg = <1>;
+			};
+		};
+	};
+
 	pcie3x4: pcie at fe150000 {
 		compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
 		#address-cells = <3>;

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Sat Dec  7 13:32:27 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 07 Dec 2024 23:32:27 +0200
Subject: [PATCH 4/4] arm64: dts: rockchip: Enable HDMI1 on rock-5b
In-Reply-To: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
References: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
Message-ID: <20241207-rk3588-hdmi1-v1-4-ca3a99b46a40@collabora.com>

Add the necessary DT changes to enable the second HDMI output port on
Radxa ROCK 5B.

While at it, switch the position of &vop_mmu and @vop to maintain the
alphabetical order.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 42 +++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index c44d001da16978bbbb8a93d652893a786e9ea79b..bf9e4dc601555050d8857e03b2f1fb5fe2cadaac 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -49,6 +49,17 @@ hdmi0_con_in: endpoint {
 		};
 	};
 
+	hdmi1-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi1_con_in: endpoint {
+				remote-endpoint = <&hdmi1_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -220,10 +231,30 @@ hdmi0_out_con: endpoint {
 	};
 };
 
+&hdmi1 {
+	status = "okay";
+};
+
+&hdmi1_in {
+	hdmi1_in_vp1: endpoint {
+		remote-endpoint = <&vp1_out_hdmi1>;
+	};
+};
+
+&hdmi1_out {
+	hdmi1_out_con: endpoint {
+		remote-endpoint = <&hdmi1_con_in>;
+	};
+};
+
 &hdptxphy_hdmi0 {
 	status = "okay";
 };
 
+&hdptxphy1 {
+	status = "okay";
+};
+
 &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0m2_xfer>;
@@ -891,11 +922,11 @@ &usb_host2_xhci {
 	status = "okay";
 };
 
-&vop_mmu {
+&vop {
 	status = "okay";
 };
 
-&vop {
+&vop_mmu {
 	status = "okay";
 };
 
@@ -905,3 +936,10 @@ vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
 		remote-endpoint = <&hdmi0_in_vp0>;
 	};
 };
+
+&vp1 {
+	vp1_out_hdmi1: endpoint at ROCKCHIP_VOP2_EP_HDMI1 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI1>;
+		remote-endpoint = <&hdmi1_in_vp1>;
+	};
+};

-- 
2.47.0



From mschirrmeister at gmail.com  Sat Dec  7 13:44:06 2024
From: mschirrmeister at gmail.com (Marco Schirrmeister)
Date: Sat, 7 Dec 2024 22:44:06 +0100
Subject: [PATCH 3/3 v3] arm64: dts: rockchip: Add Orange Pi 5 Max board
In-Reply-To: <CALWfF7+7KSZ2UJUXgS_Pr3=xzMEyjKgZ4BPL47zkmfnM03HUqg@mail.gmail.com>
References: <20241111045408.1922-1-honyuenkwun@gmail.com> <20241111045408.1922-7-honyuenkwun@gmail.com>
 <CAGJh8eDdj5zwENGWHHdZt8ejdVZ=d4GTNzW57rohyL2rvEA_hg@mail.gmail.com> <CALWfF7+7KSZ2UJUXgS_Pr3=xzMEyjKgZ4BPL47zkmfnM03HUqg@mail.gmail.com>
Message-ID: <CAGJh8eDJMXnjsZgdgsCj+jFp=0iK9kmrH88fFSXxYLevV8aV5A@mail.gmail.com>

Hello Jimmy,

sorry for my late reply.

On Fri, Nov 15, 2024 at 5:56?PM Jimmy Hon <honyuenkwun at gmail.com> wrote:

> If your primary focus is to only test eMMC support for the Orange Pi 5
> Max, then apply the patches on top linux-rockchip for-next.
> https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/log/?h=for-next
> That generated DTB should be able to run against an older kernel since
> the Orange Pi 5 Plus already works.

applying v2 patches was working fine with this kernel. But I still had
the same problem when booting, where it is stuck during hardware
initialization.
Need to check more on this and retry with the latest version.

> Also, regarding v3, I rebased on top of linux-rockchip for-next to
> include the updates for HDMI and GPU on the Orange Pi 5 Plus.
>
> For my development testing, I used Collabora's rk3588-test development
> branch, so all the needed patches were already in one place (since
> they test on a Radxa Rock 5B with the RK3588).
> https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commits/rk3588-test/?ref_type=heads
>
> So for v3, I had to first cherry-pick the Orange Pi 5 Plus changes
> from linux-rockchip for-next.

I was not successful with applying the patches yet with the Collabora
branch you mentioned. I guess I did not cherry pick the right ones,
yet.
I will do some more testing to see if I can figure it out. Otherwise I
will wait until the first version is merged and test then.


From David.Laight at ACULAB.COM  Sat Dec  7 13:45:47 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sat, 7 Dec 2024 21:45:47 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <63f538fceadf4e2ba93cdcaae9fab266e5a000ac.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
	 <CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
	 <CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
	 <d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
	 <CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
	 <0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>
	 <e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
	 <CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
	 <b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com>
	 <CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>
	 <CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com>
	 <6b8c9b942ba6e85a3f1e4eef65a9916333502881.camel@gwdg.de>
	 <20362fe79d494bd59471a9c0f002b2ef@AcuMS.aculab.com>
 <63f538fceadf4e2ba93cdcaae9fab266e5a000ac.camel@gwdg.de>
Message-ID: <c3d21364d9ad43279352dc4d7348c97d@AcuMS.aculab.com>

From: Martin Uecker
> Sent: 07 December 2024 21:06
> 
> Am Samstag, dem 07.12.2024 um 21:00 +0000 schrieb David Laight:
> > From: Martin Uecker
> > > Sent: 07 December 2024 19:52
> ...
> 
> >
> > > There exist proposals along those lines for C2Y.
> > >
> > > From a more near-term solution, I wonder if making it possible (or
> > > easier) to return integer constant expressions from statement
> > > expressions and allowing a restricted form of statement expressions
> > > at file scope would help?
> >
> > It would help a lot if a #define that just used local variables
> > to avoid arguments being re-expanded and for CSE could still
> > generate a constant value.
> > Does need to be a #define - to get token pasting and 'stringify'.
> > Although you would need something for reporting detected errors,
> > and builtin compiler support for const_true() for the detection
> > itself.
> 
> We are super close:
> 
> https://godbolt.org/z/Tarq89bha

(The preprocess output is about 500 bytes for each line.)

> (if we ignore the grotesque hacks to get there, but this would go
> away if the compiler does it internally)

Some of those hacks look excessive.
Isn't IF_CONST(x, y, z) just
	_Generic(0 ? (void *)((x) ? 0L : 0L) : (char *)0, char *: y, void *: z)
and that gets rid some of the grossness.
Just having that as a builtin would simplify some things.
Although you could use:
	__builtin_choose_expr(IS_CONST(x), y, z)
if you need y and z to have different types, and just:
	IS_CONST(x) ? y : z
otherwise.
Since AFAICT they are otherwise equivalent.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From peter.griffin at linaro.org  Sat Dec  7 14:03:15 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Sat, 7 Dec 2024 22:03:15 +0000
Subject: [PATCH v4 7/7] phy: exynos5-usbdrd: allow DWC3 runtime suspend
 with UDC bound (E850+)
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-7-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
 <20241206-gs101-phy-lanes-orientation-phy-v4-7-f5961268b149@linaro.org>
Message-ID: <CADrjBPrz1qUxbEVFR8OT785xLPwWmu3_ZThSne+EtpS8_NHEEg@mail.gmail.com>

Hi Andr?,

On Fri, 6 Dec 2024 at 16:31, Andr? Draszik <andre.draszik at linaro.org> wrote:
>
> To make USB runtime suspend work when a UDC has been bound, the phy
> needs to inform the USBDRD controller (DWC3) that Vbus and bvalid are
> gone, so that it can in turn raise the respective gadget interrupt with
> event == DWC3_DEVICE_EVENT_DISCONNECT, which will cause the USB stack
> to clean up, allowing DWC3 to enter runtime suspend.
>
> On e850 and gs101 this isn't working, as the respective signals are not
> directly connected, and instead this driver uses override bits in the
> PHY IP to set those signals. It currently forcefully sets them to 'on',
> so the above mentioned interrupt will not be raised, preventing runtime
> suspend.
>
> To detect that state, update this driver to act on the TCPC's
> orientation signal - when orientation == NONE, Vbus is gone and we can
> clear the respective bits. Similarly, for other orientation values we
> re-enable them.
>
> This makes runtime suspend work on platforms with a TCPC (like Pixel6),
> while keeping compatibility with platforms without (e850-96).
>
> With runtime suspend working, USB-C cable orientation detection now
> also fully works on such platforms, and the link comes up as Superspeed
> as expected irrespective of the cable orientation and whether UDC /
> gadget are configured and active.
>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

As mentioned on the last patch, in my testing cable orientation
detection is working, but Pixel is detected as a superspeed device in
one orientation, and high speed device in the other orientation. So
you should either change the wording of the last paragraph in the
commit message (assuming you get the same results as me) or make it
detect as superspeed in both orientations.

Thanks,

Peter.


From peter.griffin at linaro.org  Sat Dec  7 14:07:40 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Sat, 7 Dec 2024 22:07:40 +0000
Subject: [PATCH v2 2/5] arm64: dts: exynos: gs101: phy region for
 exynos5-usbdrd is larger
In-Reply-To: <20241203-gs101-phy-lanes-orientation-dts-v2-2-1412783a6b01@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
 <20241203-gs101-phy-lanes-orientation-dts-v2-2-1412783a6b01@linaro.org>
Message-ID: <CADrjBPrzB6H5GCN_NWcqcGhB0D31xF07bRMmoKyeZji4M2CXqA@mail.gmail.com>

On Tue, 3 Dec 2024 at 12:40, Andr? Draszik <andre.draszik at linaro.org> wrote:
>
> Turns out there are some additional registers in the phy region, update
> the DT accordingly.
>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>


From peter.griffin at linaro.org  Sat Dec  7 14:10:32 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Sat, 7 Dec 2024 22:10:32 +0000
Subject: [PATCH v2 3/5] arm64: dts: exynos: gs101: allow stable USB phy
 Vbus detection
In-Reply-To: <20241203-gs101-phy-lanes-orientation-dts-v2-3-1412783a6b01@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
 <20241203-gs101-phy-lanes-orientation-dts-v2-3-1412783a6b01@linaro.org>
Message-ID: <CADrjBPpOj3E72SPAB65Zrbct-ny=ynZxKx+21foJdQ9qkPzC7w@mail.gmail.com>

On Tue, 3 Dec 2024 at 12:40, Andr? Draszik <andre.draszik at linaro.org> wrote:
>
> For the DWC3 core to reliably detect the connected phy's Vbus state, we
> need to disable phy suspend.
>
> Add
>     snps,dis_u2_susphy_quirk
>     snps,dis_u3_susphy_quirk
> to do that.
>
> While at it, also add
>     snps,has-lpm-erratum
> as this is set downstream which implies that the core was configured
> with LPM Erratum. We should do the same here.
>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>

Notes on testing:

Tested with a Pixel 6 device with 2 different USB hubs and also
directly into the laptop, plugging and unplugging from both ends of
the cable. With this set of snps quirks disconnect/reconnect always
seems to be robustly detected.


From peter.griffin at linaro.org  Sat Dec  7 14:24:30 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Sat, 7 Dec 2024 22:24:30 +0000
Subject: [PATCH v2 4/5] arm64: dts: exynos: gs101-oriole: enable Maxim
 max77759 TCPCi
In-Reply-To: <20241203-gs101-phy-lanes-orientation-dts-v2-4-1412783a6b01@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
 <20241203-gs101-phy-lanes-orientation-dts-v2-4-1412783a6b01@linaro.org>
Message-ID: <CADrjBPpC-qo22ZH1s=KoRgnnj6g90N6ADvU=HkRPJmwOBYAXoA@mail.gmail.com>

On Tue, 3 Dec 2024 at 12:40, Andr? Draszik <andre.draszik at linaro.org> wrote:
>
> On Pixel 6 (and Pro), a max77759 companion PMIC for USB Type-C
> applications is used, which contains four functional blocks (at
> distinct I2C addresses):
>   * top (including GPIO)
>   * charger
>   * fuel gauge
>   * TCPCi
>
> While in the same package, TCPCi and Fuel Gauge have separate I2C
> addresses, interrupt lines and interrupt status registers and can be
> treated independently.
>
> The TCPCi is required to detect and handle connector orientation in
> Pixel's USB PHY driver, and to configure the USB controller's role
> (host vs device).
>
> This change adds the TCPCi part as it can be independent and doesn't
> need a top-level MFD.
>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>

Notes on testing:

Verified that type-c orientation notifications are sent to usb phy
driver and that Pixel is enumerated as a USB device with both cable
orientations

[..]


From muecker at gwdg.de  Sat Dec  7 15:52:07 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sun, 8 Dec 2024 00:52:07 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
	 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>
	 <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
	 <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de>
	 <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>
Message-ID: <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de>

Am Samstag, dem 07.12.2024 um 12:28 -0800 schrieb Linus Torvalds:
> On Sat, 7 Dec 2024 at 11:19, Martin Uecker <muecker at gwdg.de> wrote:
> > 
> > But that all seem solvable issues on the compiler side.
> 
[... Itanium, value range analysis, no assertions in kernel...]


> Now, would we want to have proper value *static* range analysis in the
> kernel for other reasons? Oh yes. It would often be very nice to have
> the ability to state "this value is trusted and is in this range", and
> have it percolate all the way down, both for optimization purposes but
> also for various sanity check purposes.

__bos should give you some access to it, but it seems not as
good as it could be (relative to what the optimizer knows)
and then the information is also not available in the front-end. 

> 
> But it's simply not sanely available in the generic case.

I was not talking about future still-to-be-invented compiler
technology, but about things that work today.

While the compiler can not automatically prove every use
of VLA bounded, it can reliably diagnose the cases where it
can?*not* see that it is bounded. Consider this example:

void oob(int n, char p[n]);
void f(unsigned int n)
{
    char buf[MIN(n, 100)]; // bounded
    oob(n + 10, buf); // warning
}

void h(unsigned int n)
{
    char buf[100];  // static with worst case size
    oob(n + 10, buf); // no warning
}

void i(unsigned int n)
{
    char buf[n]; // warning!
    oob(n + 10, buf);
}

void test_f() { f(50); }
void test_h() { h(50); }
void test_i() { i(50); }

https://godbolt.org/z/b15ajTPda

For both 'f' and 'h' stack is bounded and generally smaller in 'f'.
Also any worst-case stack size analysis that applies to 'h' also
applies to 'f' (and could potentially be improved).

In 'f' one gets a warning because 'oob' will try to do an OOB
access.  This is only possibly because the compiler sees the true
size of the array.  (One can also get precise information
about the size with __bdos.)

In 'h' the error can not be detected. The information is lost.
One can get a warning only when the static worst-case size is
exceeded, but otherwise the error remains hidden.

In 'i' one gets the warning about the OOB access and with?
-Wvla-larget-than=100  one gets a warning that the VLA size may
be unbounded.  These case should then not be allowed of course.

Note that this works today in GCC and seems to have better
information than __bos available (not sure why though).

> 
> > a) this is not guaranteed in a specific situation (-Wvla-larher-than)
> 
> We'd either get horrendous numbers of false positives that we then
> have to manually add special code for, or
>

> > b) transform the array automatically to fixed size array
> > of size X *or* something smaller when it can show this.
> 
> we'd just do this by hand *once* and for all, and say "VLA's didn't work out".
> 
> So yeah. We did (b) by hand.
> 
> We used to have VLA's in the kernel. It was a disaster. We got rid of
> them, because the (big) pain wasn't worth the (few) places it was
> actually useful.

Can you point me to some horror stories? 


> So we have been VLA-free for the last five years, and it's been good.
> Simplify.

These macro discussions I get CC-ed on sometimes leave a different 
impression ;-)


Martin




From ansuelsmth at gmail.com  Sat Dec  7 16:20:37 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:37 +0100
Subject: [net-next PATCH v10 2/9] dt-bindings: net: Document support for Airoha AN8855 Switch Virtual MDIO
In-Reply-To: <20241208002105.18074-1-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
Message-ID: <20241208002105.18074-3-ansuelsmth@gmail.com>

Document support for Airoha AN8855 Virtual MDIO Passtrough. This is needed
as AN8855 require special handling as the same address on the MDIO bus is
shared for both Switch and PHY and special handling for the page
configuration is needed to switch accessing to Switch address space
or PHY.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 .../bindings/net/airoha,an8855-mdio.yaml      | 86 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml

diff --git a/Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml b/Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
new file mode 100644
index 000000000000..2211df3cc3b7
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/airoha,an8855-mdio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 MDIO Passtrough
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description:
+  Airoha AN8855 Virtual MDIO Passtrough. This is needed as AN8855
+  require special handling as the same address on the MDIO bus is
+  shared for both Switch and PHY and special handling for the page
+  configuration is needed to switch accessing to Switch address space
+  or PHY.
+
+$ref: /schemas/net/mdio.yaml#
+
+properties:
+  compatible:
+    const: airoha,an8855-mdio
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    mdio {
+        compatible = "airoha,an8855-mdio";
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        internal_phy1: phy at 1 {
+            reg = <1>;
+
+            nvmem-cells = <&shift_sel_port0_tx_a>,
+                <&shift_sel_port0_tx_b>,
+                <&shift_sel_port0_tx_c>,
+                <&shift_sel_port0_tx_d>;
+            nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+        };
+
+        internal_phy2: phy at 2 {
+            reg = <2>;
+
+            nvmem-cells = <&shift_sel_port1_tx_a>,
+                <&shift_sel_port1_tx_b>,
+                <&shift_sel_port1_tx_c>,
+                <&shift_sel_port1_tx_d>;
+            nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+        };
+
+        internal_phy3: phy at 3 {
+            reg = <3>;
+
+            nvmem-cells = <&shift_sel_port2_tx_a>,
+                <&shift_sel_port2_tx_b>,
+                <&shift_sel_port2_tx_c>,
+                <&shift_sel_port2_tx_d>;
+            nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+        };
+
+        internal_phy4: phy at 4 {
+            reg = <4>;
+
+            nvmem-cells = <&shift_sel_port3_tx_a>,
+                <&shift_sel_port3_tx_b>,
+                <&shift_sel_port3_tx_c>,
+                <&shift_sel_port3_tx_d>;
+            nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+        };
+
+        internal_phy5: phy at 5 {
+            reg = <5>;
+
+            nvmem-cells = <&shift_sel_port4_tx_a>,
+                <&shift_sel_port4_tx_b>,
+                <&shift_sel_port4_tx_c>,
+                <&shift_sel_port4_tx_d>;
+            nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 53ef66eef473..e3569fe5f3de 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -717,6 +717,7 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
 L:	netdev at vger.kernel.org
 S:	Maintained
+F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 
 AIROHA ETHERNET DRIVER
-- 
2.45.2



From ansuelsmth at gmail.com  Sat Dec  7 16:20:38 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:38 +0100
Subject: [net-next PATCH v10 3/9] dt-bindings: net: dsa: Document support for Airoha AN8855 DSA Switch
In-Reply-To: <20241208002105.18074-1-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
Message-ID: <20241208002105.18074-4-ansuelsmth@gmail.com>

Document support for Airoha AN8855 5-port Gigabit Switch.

It does expose the 5 Internal PHYs on the MDIO bus and each port
can access the Switch register space by configurting the PHY page.

Each internal PHY might require calibration with the fused EFUSE on
the switch exposed by the Airoha AN8855 SoC NVMEM.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 .../net/dsa/airoha,an8855-switch.yaml         | 105 ++++++++++++++++++
 MAINTAINERS                                   |   1 +
 2 files changed, 106 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml

diff --git a/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml b/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
new file mode 100644
index 000000000000..63bcbebd6a29
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/dsa/airoha,an8855-switch.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 Gigabit Switch
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description: >
+  Airoha AN8855 is a 5-port Gigabit Switch.
+
+  It does expose the 5 Internal PHYs on the MDIO bus and each port
+  can access the Switch register space by configurting the PHY page.
+
+  Each internal PHY might require calibration with the fused EFUSE on
+  the switch exposed by the Airoha AN8855 SoC NVMEM.
+
+$ref: dsa.yaml#
+
+properties:
+  compatible:
+    const: airoha,an8855-switch
+
+  reset-gpios:
+    description:
+      GPIO to be used to reset the whole device
+    maxItems: 1
+
+  airoha,ext-surge:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Calibrate the internal PHY with the calibration values stored in EFUSE
+      for the r50Ohm values.
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    ethernet-switch {
+        compatible = "airoha,an8855-switch";
+        reset-gpios = <&pio 39 0>;
+
+        airoha,ext-surge;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+                label = "lan1";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy1>;
+            };
+
+            port at 1 {
+                reg = <1>;
+                label = "lan2";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy2>;
+            };
+
+            port at 2 {
+                reg = <2>;
+                label = "lan3";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy3>;
+            };
+
+            port at 3 {
+                reg = <3>;
+                label = "lan4";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy4>;
+            };
+
+            port at 4 {
+                reg = <4>;
+                label = "wan";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy5>;
+            };
+
+            port at 5 {
+                reg = <5>;
+                label = "cpu";
+                ethernet = <&gmac0>;
+                phy-mode = "2500base-x";
+
+                fixed-link {
+                    speed = <2500>;
+                    full-duplex;
+                    pause;
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index e3569fe5f3de..fd37e829fab5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -718,6 +718,7 @@ L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
 L:	netdev at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
+F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 
 AIROHA ETHERNET DRIVER
-- 
2.45.2



From ansuelsmth at gmail.com  Sat Dec  7 16:20:40 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:40 +0100
Subject: [net-next PATCH v10 5/9] mfd: an8855: Add support for Airoha AN8855 Switch MFD
In-Reply-To: <20241208002105.18074-1-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
Message-ID: <20241208002105.18074-6-ansuelsmth@gmail.com>

Add support for Airoha AN8855 Switch MFD that provide support for a DSA
switch and a NVMEM provider. Also provide support for a virtual MDIO
passthrough as the PHYs address for the switch are shared with the switch
address

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                           |   1 +
 drivers/mfd/Kconfig                   |   9 +
 drivers/mfd/Makefile                  |   1 +
 drivers/mfd/airoha-an8855.c           | 279 ++++++++++++++++++++++++++
 include/linux/mfd/airoha-an8855-mfd.h |  41 ++++
 5 files changed, 331 insertions(+)
 create mode 100644 drivers/mfd/airoha-an8855.c
 create mode 100644 include/linux/mfd/airoha-an8855-mfd.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f3e3f6938824..7f4d7c48b6e1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -721,6 +721,7 @@ F:	Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
 F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
+F:	drivers/mfd/airoha-an8855.c
 
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ae23b317a64e..a83db24336d9 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -53,6 +53,15 @@ config MFD_ALTERA_SYSMGR
 	  using regmap_mmio accesses for ARM32 parts and SMC calls to
 	  EL3 for ARM64 parts.
 
+config MFD_AIROHA_AN8855
+	bool "Airoha AN8855 Switch MFD"
+	depends on MDIO && OF
+	select MFD_CORE
+	help
+	  Support for the Airoha AN8855 Switch MFD. This is a SoC Switch
+	  that provide various peripherals. Currently it provides a
+	  DSA switch and a NVMEM provider.
+
 config MFD_ACT8945A
 	tristate "Active-semi ACT8945A"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index e057d6d6faef..bcbeb36ab19d 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_MFD_88PM860X)	+= 88pm860x.o
 obj-$(CONFIG_MFD_88PM800)	+= 88pm800.o 88pm80x.o
 obj-$(CONFIG_MFD_88PM805)	+= 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_88PM886_PMIC)	+= 88pm886.o
+obj-$(CONFIG_MFD_AIROHA_AN8855)	+= airoha-an8855.o
 obj-$(CONFIG_MFD_ACT8945A)	+= act8945a.o
 obj-$(CONFIG_MFD_SM501)		+= sm501.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835-pm.o
diff --git a/drivers/mfd/airoha-an8855.c b/drivers/mfd/airoha-an8855.c
new file mode 100644
index 000000000000..b6cecfc325f6
--- /dev/null
+++ b/drivers/mfd/airoha-an8855.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MFD driver for Airoha AN8855 Switch
+ */
+
+#include <linux/mfd/airoha-an8855-mfd.h>
+#include <linux/mfd/core.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/regmap.h>
+
+static const struct mfd_cell an8855_mfd_devs[] = {
+	{
+		.name = "an8855-efuse",
+		.of_compatible = "airoha,an8855-efuse",
+	}, {
+		.name = "an8855-switch",
+		.of_compatible = "airoha,an8855-switch",
+	}, {
+		.name = "an8855-mdio",
+		.of_compatible = "airoha,an8855-mdio",
+	}
+};
+
+int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
+			u8 page) __must_hold(&priv->bus->mdio_lock)
+{
+	struct mii_bus *bus = priv->bus;
+	int ret;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PHY_SELECT_PAGE, page);
+	if (ret < 0)
+		dev_err_ratelimited(&bus->dev,
+				    "failed to set an8855 mii page\n");
+
+	/* Cache current page if next mii read/write is for switch */
+	priv->current_page = page;
+	return ret < 0 ? ret : 0;
+}
+EXPORT_SYMBOL_GPL(an8855_mii_set_page);
+
+static int an8855_mii_read32(struct mii_bus *bus, u8 phy_id, u32 reg,
+			     u32 *val) __must_hold(&bus->mdio_lock)
+{
+	int lo, hi, ret;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE,
+			      AN8855_PBUS_MODE_ADDR_FIXED);
+	if (ret < 0)
+		goto err;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_HIGH,
+			      upper_16_bits(reg));
+	if (ret < 0)
+		goto err;
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_LOW,
+			      lower_16_bits(reg));
+	if (ret < 0)
+		goto err;
+
+	hi = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_HIGH);
+	if (hi < 0) {
+		ret = hi;
+		goto err;
+	}
+	lo = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_LOW);
+	if (lo < 0) {
+		ret = lo;
+		goto err;
+	}
+
+	*val = ((u16)hi << 16) | ((u16)lo & 0xffff);
+
+	return 0;
+err:
+	dev_err_ratelimited(&bus->dev,
+			    "failed to read an8855 register\n");
+	return ret;
+}
+
+static int an8855_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
+{
+	struct an8855_mfd_priv *priv = ctx;
+	struct mii_bus *bus = priv->bus;
+	u16 addr = priv->switch_addr;
+	int ret;
+
+	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+	ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
+	if (ret < 0)
+		goto exit;
+
+	ret = an8855_mii_read32(bus, addr, reg, val);
+
+exit:
+	mutex_unlock(&bus->mdio_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
+static int an8855_mii_write32(struct mii_bus *bus, u8 phy_id, u32 reg,
+			      u32 val) __must_hold(&bus->mdio_lock)
+{
+	int ret;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE,
+			      AN8855_PBUS_MODE_ADDR_FIXED);
+	if (ret < 0)
+		goto err;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_HIGH,
+			      upper_16_bits(reg));
+	if (ret < 0)
+		goto err;
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_LOW,
+			      lower_16_bits(reg));
+	if (ret < 0)
+		goto err;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_HIGH,
+			      upper_16_bits(val));
+	if (ret < 0)
+		goto err;
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_LOW,
+			      lower_16_bits(val));
+	if (ret < 0)
+		goto err;
+
+	return 0;
+err:
+	dev_err_ratelimited(&bus->dev,
+			    "failed to write an8855 register\n");
+	return ret;
+}
+
+static int
+an8855_regmap_write(void *ctx, uint32_t reg, uint32_t val)
+{
+	struct an8855_mfd_priv *priv = ctx;
+	struct mii_bus *bus = priv->bus;
+	u16 addr = priv->switch_addr;
+	int ret;
+
+	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+	ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
+	if (ret < 0)
+		goto exit;
+
+	ret = an8855_mii_write32(bus, addr, reg, val);
+
+exit:
+	mutex_unlock(&bus->mdio_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
+static int an8855_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask,
+				     uint32_t write_val)
+{
+	struct an8855_mfd_priv *priv = ctx;
+	struct mii_bus *bus = priv->bus;
+	u16 addr = priv->switch_addr;
+	u32 val;
+	int ret;
+
+	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+	ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
+	if (ret < 0)
+		goto exit;
+
+	ret = an8855_mii_read32(bus, addr, reg, &val);
+	if (ret < 0)
+		goto exit;
+
+	val &= ~mask;
+	val |= write_val;
+	ret = an8855_mii_write32(bus, addr, reg, val);
+
+exit:
+	mutex_unlock(&bus->mdio_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
+static const struct regmap_range an8855_readable_ranges[] = {
+	regmap_reg_range(0x10000000, 0x10000fff), /* SCU */
+	regmap_reg_range(0x10001000, 0x10001fff), /* RBUS */
+	regmap_reg_range(0x10002000, 0x10002fff), /* MCU */
+	regmap_reg_range(0x10005000, 0x10005fff), /* SYS SCU */
+	regmap_reg_range(0x10007000, 0x10007fff), /* I2C Slave */
+	regmap_reg_range(0x10008000, 0x10008fff), /* I2C Master */
+	regmap_reg_range(0x10009000, 0x10009fff), /* PDMA */
+	regmap_reg_range(0x1000a100, 0x1000a2ff), /* General Purpose Timer */
+	regmap_reg_range(0x1000a200, 0x1000a2ff), /* GPU timer */
+	regmap_reg_range(0x1000a300, 0x1000a3ff), /* GPIO */
+	regmap_reg_range(0x1000a400, 0x1000a5ff), /* EFUSE */
+	regmap_reg_range(0x1000c000, 0x1000cfff), /* GDMP CSR */
+	regmap_reg_range(0x10010000, 0x1001ffff), /* GDMP SRAM */
+	regmap_reg_range(0x10200000, 0x10203fff), /* Switch - ARL Global */
+	regmap_reg_range(0x10204000, 0x10207fff), /* Switch - BMU */
+	regmap_reg_range(0x10208000, 0x1020bfff), /* Switch - ARL Port */
+	regmap_reg_range(0x1020c000, 0x1020cfff), /* Switch - SCH */
+	regmap_reg_range(0x10210000, 0x10213fff), /* Switch - MAC */
+	regmap_reg_range(0x10214000, 0x10217fff), /* Switch - MIB */
+	regmap_reg_range(0x10218000, 0x1021bfff), /* Switch - Port Control */
+	regmap_reg_range(0x1021c000, 0x1021ffff), /* Switch - TOP */
+	regmap_reg_range(0x10220000, 0x1022ffff), /* SerDes */
+	regmap_reg_range(0x10286000, 0x10286fff), /* RG Batcher */
+	regmap_reg_range(0x1028c000, 0x1028ffff), /* ETHER_SYS */
+	regmap_reg_range(0x30000000, 0x37ffffff), /* I2C EEPROM */
+	regmap_reg_range(0x38000000, 0x3fffffff), /* BOOT_ROM */
+	regmap_reg_range(0xa0000000, 0xbfffffff), /* GPHY */
+};
+
+static const struct regmap_access_table an8855_readable_table = {
+	.yes_ranges = an8855_readable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(an8855_readable_ranges),
+};
+
+static const struct regmap_config an8855_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = 0xbfffffff,
+	.reg_read = an8855_regmap_read,
+	.reg_write = an8855_regmap_write,
+	.reg_update_bits = an8855_regmap_update_bits,
+	.disable_locking = true,
+	.rd_table = &an8855_readable_table,
+};
+
+static int an8855_mfd_probe(struct mdio_device *mdiodev)
+{
+	struct an8855_mfd_priv *priv;
+	struct regmap *regmap;
+
+	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->bus = mdiodev->bus;
+	priv->dev = &mdiodev->dev;
+	priv->switch_addr = mdiodev->addr;
+	/* no DMA for mdiobus, mute warning for DMA mask not set */
+	priv->dev->dma_mask = &priv->dev->coherent_dma_mask;
+
+	regmap = devm_regmap_init(priv->dev, NULL, priv,
+				  &an8855_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(priv->dev, "regmap initialization failed");
+		return PTR_ERR(priv->dev);
+	}
+
+	dev_set_drvdata(&mdiodev->dev, priv);
+
+	return devm_mfd_add_devices(priv->dev, PLATFORM_DEVID_AUTO, an8855_mfd_devs,
+				    ARRAY_SIZE(an8855_mfd_devs), NULL, 0,
+				    NULL);
+}
+
+static const struct of_device_id an8855_mfd_of_match[] = {
+	{ .compatible = "airoha,an8855-mfd" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, airoha_mfd_of_match);
+
+static struct mdio_driver an8855_mfd_driver = {
+	.probe = an8855_mfd_probe,
+	.mdiodrv.driver = {
+		.name = "an8855",
+		.of_match_table = an8855_mfd_of_match,
+	},
+};
+mdio_module_driver(an8855_mfd_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_DESCRIPTION("Driver for Airoha AN8855 MFD");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/airoha-an8855-mfd.h b/include/linux/mfd/airoha-an8855-mfd.h
new file mode 100644
index 000000000000..56061566a079
--- /dev/null
+++ b/include/linux/mfd/airoha-an8855-mfd.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * MFD driver for Airoha AN8855 Switch
+ */
+#ifndef _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H
+#define _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H
+
+#include <linux/bitfield.h>
+
+/* MII Registers */
+#define AN8855_PHY_SELECT_PAGE		0x1f
+#define   AN8855_PHY_PAGE		GENMASK(2, 0)
+#define   AN8855_PHY_PAGE_STANDARD	FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
+#define   AN8855_PHY_PAGE_EXTENDED_1	FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
+#define   AN8855_PHY_PAGE_EXTENDED_4	FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x4)
+
+/* MII Registers Page 4 */
+#define AN8855_PBUS_MODE		0x10
+#define   AN8855_PBUS_MODE_ADDR_FIXED	0x0
+#define AN8855_PBUS_MODE_ADDR_INCR	BIT(15)
+#define AN8855_PBUS_WR_ADDR_HIGH	0x11
+#define AN8855_PBUS_WR_ADDR_LOW		0x12
+#define AN8855_PBUS_WR_DATA_HIGH	0x13
+#define AN8855_PBUS_WR_DATA_LOW		0x14
+#define AN8855_PBUS_RD_ADDR_HIGH	0x15
+#define AN8855_PBUS_RD_ADDR_LOW		0x16
+#define AN8855_PBUS_RD_DATA_HIGH	0x17
+#define AN8855_PBUS_RD_DATA_LOW		0x18
+
+struct an8855_mfd_priv {
+	struct device *dev;
+	struct mii_bus *bus;
+
+	unsigned int switch_addr;
+	u16 current_page;
+};
+
+int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
+			u8 page);
+
+#endif
-- 
2.45.2



From ansuelsmth at gmail.com  Sat Dec  7 16:20:39 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:39 +0100
Subject: [net-next PATCH v10 4/9] dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC
In-Reply-To: <20241208002105.18074-1-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
Message-ID: <20241208002105.18074-5-ansuelsmth@gmail.com>

Document support for Airoha AN8855 Switch SoC. This SoC expose various
peripherals like an Ethernet Switch, a NVMEM provider and Ethernet PHYs.

It does also support i2c and timers but those are not currently
supported/used.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 .../bindings/mfd/airoha,an8855-mfd.yaml       | 185 ++++++++++++++++++
 MAINTAINERS                                   |   1 +
 2 files changed, 186 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml

diff --git a/Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml b/Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
new file mode 100644
index 000000000000..5d1ed5e7a52a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
@@ -0,0 +1,185 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/airoha,an8855-mfd.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 Switch SoC
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description: >
+  Airoha AN8855 Switch is a SoC that expose various peripherals like an
+  Ethernet Switch, a NVMEM provider and Ethernet PHYs.
+
+  It does also support i2c and timers but those are not currently
+  supported/used.
+
+properties:
+  compatible:
+    const: airoha,an8855-mfd
+
+  reg:
+    minItems: 1
+    maxItems: 5
+
+  reg-names:
+    minItems: 1
+    maxItems: 5
+
+  efuse:
+    type: object
+    $ref: /schemas/nvmem/airoha,an8855-efuse.yaml
+    description:
+      EFUSE exposed by the Airoha AN8855 Switch. This child node definition
+      should follow the bindings specified in
+      Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
+
+  ethernet-switch:
+    type: object
+    $ref: /schemas/net/dsa/airoha,an8855-switch.yaml
+    description:
+      Switch exposed by the Airoha AN8855 Switch. This child node definition
+      should follow the bindings specified in
+      Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
+
+  mdio:
+    type: object
+    $ref: /schemas/net/airoha,an8855-mdio.yaml
+    description:
+      MDIO exposed by the Airoha AN8855 Switch. This child node definition
+      should follow the bindings specified in
+      Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    mdio {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        mfd at 1 {
+            compatible = "airoha,an8855-mfd";
+            reg = <1>, <2>;
+            reg-names = "phy0", "phy1";
+
+            efuse {
+                compatible = "airoha,an8855-efuse";
+
+                #nvmem-cell-cells = <0>;
+
+                nvmem-layout {
+                    compatible = "fixed-layout";
+                    #address-cells = <1>;
+                    #size-cells = <1>;
+
+                    shift_sel_port0_tx_a: shift-sel-port0-tx-a at c {
+                       reg = <0xc 0x4>;
+                    };
+
+                    shift_sel_port0_tx_b: shift-sel-port0-tx-b at 10 {
+                        reg = <0x10 0x4>;
+                    };
+
+                    shift_sel_port0_tx_c: shift-sel-port0-tx-c at 14 {
+                        reg = <0x14 0x4>;
+                    };
+
+                    shift_sel_port0_tx_d: shift-sel-port0-tx-d at 18 {
+                       reg = <0x18 0x4>;
+                    };
+
+                    shift_sel_port1_tx_a: shift-sel-port1-tx-a at 1c {
+                        reg = <0x1c 0x4>;
+                    };
+
+                    shift_sel_port1_tx_b: shift-sel-port1-tx-b at 20 {
+                        reg = <0x20 0x4>;
+                    };
+
+                    shift_sel_port1_tx_c: shift-sel-port1-tx-c at 24 {
+                       reg = <0x24 0x4>;
+                    };
+
+                    shift_sel_port1_tx_d: shift-sel-port1-tx-d at 28 {
+                        reg = <0x28 0x4>;
+                    };
+                };
+            };
+
+            ethernet-switch {
+                compatible = "airoha,an8855-switch";
+
+                reset-gpios = <&pio 39 0>;
+
+                airoha,ext-surge;
+
+                ports {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+
+                    port at 0 {
+                        reg = <0>;
+                        label = "lan1";
+                        phy-mode = "internal";
+                        phy-handle = <&internal_phy1>;
+                    };
+
+                    port at 1 {
+                        reg = <1>;
+                        label = "lan2";
+                        phy-mode = "internal";
+                        phy-handle = <&internal_phy2>;
+                    };
+
+                    port at 5 {
+                        reg = <5>;
+                        label = "cpu";
+                        ethernet = <&gmac0>;
+                        phy-mode = "2500base-x";
+
+                        fixed-link {
+                            speed = <2500>;
+                            full-duplex;
+                            pause;
+                        };
+                    };
+                };
+            };
+
+            mdio {
+                compatible = "airoha,an8855-mdio";
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                internal_phy1: phy at 1 {
+                  reg = <1>;
+
+                  nvmem-cells = <&shift_sel_port0_tx_a>,
+                      <&shift_sel_port0_tx_b>,
+                      <&shift_sel_port0_tx_c>,
+                      <&shift_sel_port0_tx_d>;
+                  nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+
+                internal_phy2: phy at 2 {
+                  reg = <2>;
+
+                  nvmem-cells = <&shift_sel_port1_tx_a>,
+                      <&shift_sel_port1_tx_b>,
+                      <&shift_sel_port1_tx_c>,
+                      <&shift_sel_port1_tx_d>;
+                  nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index fd37e829fab5..f3e3f6938824 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -717,6 +717,7 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
 L:	netdev at vger.kernel.org
 S:	Maintained
+F:	Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
 F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
-- 
2.45.2



From ansuelsmth at gmail.com  Sat Dec  7 16:20:41 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:41 +0100
Subject: [net-next PATCH v10 6/9] net: mdio: Add Airoha AN8855 Switch MDIO Passtrough
In-Reply-To: <20241208002105.18074-1-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
Message-ID: <20241208002105.18074-7-ansuelsmth@gmail.com>

Add Airoha AN8855 Switch driver to register a MDIO passtrough as switch
address is shared with the internal PHYs and require additional page
handling.

This requires the upper Switch MFD to be probed and init to actually
work.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                    |   1 +
 drivers/net/mdio/Kconfig       |   9 +++
 drivers/net/mdio/Makefile      |   1 +
 drivers/net/mdio/mdio-an8855.c | 113 +++++++++++++++++++++++++++++++++
 4 files changed, 124 insertions(+)
 create mode 100644 drivers/net/mdio/mdio-an8855.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7f4d7c48b6e1..38c7b2362c92 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -722,6 +722,7 @@ F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 F:	drivers/mfd/airoha-an8855.c
+F:	drivers/net/mdio/mdio-an8855.c
 
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig
index 4a7a303be2f7..64fc5c3ef38b 100644
--- a/drivers/net/mdio/Kconfig
+++ b/drivers/net/mdio/Kconfig
@@ -61,6 +61,15 @@ config MDIO_XGENE
 	  This module provides a driver for the MDIO busses found in the
 	  APM X-Gene SoC's.
 
+config MDIO_AN8855
+	tristate "Airoha AN8855 Switch MDIO bus controller"
+	depends on MFD_AIROHA_AN8855
+	depends on OF_MDIO
+	help
+	  This module provides a driver for the Airoha AN8855 Switch
+	  that require a MDIO passtrough as switch address is shared
+	  with the internal PHYs and require additional page handling.
+
 config MDIO_ASPEED
 	tristate "ASPEED MDIO bus controller"
 	depends on ARCH_ASPEED || COMPILE_TEST
diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile
index 1015f0db4531..546c4e55b475 100644
--- a/drivers/net/mdio/Makefile
+++ b/drivers/net/mdio/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_ACPI_MDIO)		+= acpi_mdio.o
 obj-$(CONFIG_FWNODE_MDIO)	+= fwnode_mdio.o
 obj-$(CONFIG_OF_MDIO)		+= of_mdio.o
 
+obj-$(CONFIG_MDIO_AN8855)		+= mdio-an8855.o
 obj-$(CONFIG_MDIO_ASPEED)		+= mdio-aspeed.o
 obj-$(CONFIG_MDIO_BCM_IPROC)		+= mdio-bcm-iproc.o
 obj-$(CONFIG_MDIO_BCM_UNIMAC)		+= mdio-bcm-unimac.o
diff --git a/drivers/net/mdio/mdio-an8855.c b/drivers/net/mdio/mdio-an8855.c
new file mode 100644
index 000000000000..d8a856352842
--- /dev/null
+++ b/drivers/net/mdio/mdio-an8855.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MDIO passthrough driver for Airoha AN8855 Switch
+ */
+
+#include <linux/mfd/airoha-an8855-mfd.h>
+#include <linux/module.h>
+#include <linux/of_mdio.h>
+#include <linux/platform_device.h>
+
+static int an855_phy_restore_page(struct an8855_mfd_priv *priv,
+				  int phy) __must_hold(&priv->bus->mdio_lock)
+{
+	/* Check PHY page only for addr shared with switch */
+	if (phy != priv->switch_addr)
+		return 0;
+
+	/* Don't restore page if it's not set to switch page */
+	if (priv->current_page != FIELD_GET(AN8855_PHY_PAGE,
+					    AN8855_PHY_PAGE_EXTENDED_4))
+		return 0;
+
+	/* Restore page to 0, PHY might change page right after but that
+	 * will be ignored as it won't be a switch page.
+	 */
+	return an8855_mii_set_page(priv, phy, AN8855_PHY_PAGE_STANDARD);
+}
+
+static int an8855_phy_read(struct mii_bus *bus, int phy, int regnum)
+{
+	struct an8855_mfd_priv *priv = bus->priv;
+	struct mii_bus *real_bus = priv->bus;
+	int ret;
+
+	mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED);
+
+	ret = an855_phy_restore_page(priv, phy);
+	if (ret)
+		goto exit;
+
+	ret = __mdiobus_read(real_bus, phy, regnum);
+exit:
+	mutex_unlock(&real_bus->mdio_lock);
+
+	return ret;
+}
+
+static int an8855_phy_write(struct mii_bus *bus, int phy, int regnum, u16 val)
+{
+	struct an8855_mfd_priv *priv = bus->priv;
+	struct mii_bus *real_bus = priv->bus;
+	int ret;
+
+	mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED);
+
+	ret = an855_phy_restore_page(priv, phy);
+	if (ret)
+		goto exit;
+
+	ret = __mdiobus_write(real_bus, phy, regnum, val);
+exit:
+	mutex_unlock(&real_bus->mdio_lock);
+
+	return ret;
+}
+
+static int an8855_mdio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct an8855_mfd_priv *priv;
+	struct mii_bus *bus;
+	int ret;
+
+	/* Get priv of MFD */
+	priv = dev_get_drvdata(dev->parent);
+
+	bus = devm_mdiobus_alloc(dev);
+	if (!bus)
+		return -ENOMEM;
+
+	bus->priv = priv;
+	bus->name = KBUILD_MODNAME "-mii";
+	snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d",
+		 priv->switch_addr);
+	bus->parent = dev;
+	bus->read = an8855_phy_read;
+	bus->write = an8855_phy_write;
+
+	ret = devm_of_mdiobus_register(dev, bus, dev->of_node);
+	if (ret)
+		dev_err(dev, "failed to register MDIO bus: %d", ret);
+
+	return ret;
+}
+
+static const struct of_device_id an8855_mdio_ids[] = {
+	{ .compatible = "airoha,an8855-mdio", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, an8855_mdio_ids);
+
+static struct platform_driver an8855_mdio_driver = {
+	.probe	= an8855_mdio_probe,
+	.driver = {
+		.name = "an8855-mdio",
+		.of_match_table = an8855_mdio_ids,
+	},
+};
+module_platform_driver(an8855_mdio_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_DESCRIPTION("Driver for AN8855 Mdio passthrough");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From ansuelsmth at gmail.com  Sat Dec  7 16:20:42 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:42 +0100
Subject: [net-next PATCH v10 7/9] nvmem: an8855: Add support for Airoha AN8855 Switch EFUSE
In-Reply-To: <20241208002105.18074-1-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
Message-ID: <20241208002105.18074-8-ansuelsmth@gmail.com>

Add support for Airoha AN8855 Switch EFUSE. These EFUSE might be used
for calibration data for the internal switch PHYs.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                  |  1 +
 drivers/nvmem/Kconfig        | 11 +++++++
 drivers/nvmem/Makefile       |  2 ++
 drivers/nvmem/an8855-efuse.c | 63 ++++++++++++++++++++++++++++++++++++
 4 files changed, 77 insertions(+)
 create mode 100644 drivers/nvmem/an8855-efuse.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 38c7b2362c92..a67d147276a1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -723,6 +723,7 @@ F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 F:	drivers/mfd/airoha-an8855.c
 F:	drivers/net/mdio/mdio-an8855.c
+F:	drivers/nvmem/an8855-efuse.c
 
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 8671b7c974b9..599014970c22 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -28,6 +28,17 @@ source "drivers/nvmem/layouts/Kconfig"
 
 # Devices
 
+config NVMEM_AN8855_EFUSE
+	tristate "Airoha AN8855 eFuse support"
+	depends on MFD_AIROHA_AN8855 || COMPILE_TEST
+	help
+	  Say y here to enable support for reading eFuses on Airoha AN8855
+	  Switch. These are e.g. used to store factory programmed
+	  calibration data required for the PHY.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called nvmem-apple-efuse.
+
 config NVMEM_APPLE_EFUSES
 	tristate "Apple eFuse support"
 	depends on ARCH_APPLE || COMPILE_TEST
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 5b77bbb6488b..c732132c0e45 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -10,6 +10,8 @@ nvmem_layouts-y			:= layouts.o
 obj-y				+= layouts/
 
 # Devices
+obj-$(CONFIG_NVMEM_AN8855_EFUSE)	+= nvmem-an8855-efuse.o
+nvmem-an8855-efuse-y 			:= an8855-efuse.o
 obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o
 nvmem-apple-efuses-y 			:= apple-efuses.o
 obj-$(CONFIG_NVMEM_BCM_OCOTP)		+= nvmem-bcm-ocotp.o
diff --git a/drivers/nvmem/an8855-efuse.c b/drivers/nvmem/an8855-efuse.c
new file mode 100644
index 000000000000..cdb7654bf694
--- /dev/null
+++ b/drivers/nvmem/an8855-efuse.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Airoha AN8855 Switch EFUSE Driver
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define AN8855_EFUSE_CELL		50
+
+#define AN8855_EFUSE_DATA0		0x1000a500
+#define   AN8855_EFUSE_R50O		GENMASK(30, 24)
+
+static int an8855_efuse_read(void *context, unsigned int offset,
+			     void *val, size_t bytes)
+{
+	struct regmap *regmap = context;
+
+	return regmap_bulk_read(regmap, AN8855_EFUSE_DATA0 + offset,
+				val, bytes / sizeof(u32));
+}
+
+static int an8855_efuse_probe(struct platform_device *pdev)
+{
+	struct nvmem_config an8855_nvmem_config = {
+		.name = "an8855-efuse",
+		.size = AN8855_EFUSE_CELL * sizeof(u32),
+		.stride = sizeof(u32),
+		.word_size = sizeof(u32),
+		.reg_read = an8855_efuse_read,
+	};
+	struct device *dev = &pdev->dev;
+	struct nvmem_device *nvmem;
+
+	/* Assign NVMEM priv to MFD regmap */
+	an8855_nvmem_config.priv = dev_get_regmap(dev->parent, NULL);
+	an8855_nvmem_config.dev = dev;
+	nvmem = devm_nvmem_register(dev, &an8855_nvmem_config);
+
+	return PTR_ERR_OR_ZERO(nvmem);
+}
+
+static const struct of_device_id an8855_efuse_of_match[] = {
+	{ .compatible = "airoha,an8855-efuse", },
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, an8855_efuse_of_match);
+
+static struct platform_driver an8855_efuse_driver = {
+	.probe = an8855_efuse_probe,
+	.driver = {
+		.name = "an8855-efuse",
+		.of_match_table = an8855_efuse_of_match,
+	},
+};
+module_platform_driver(an8855_efuse_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_DESCRIPTION("Driver for AN8855 Switch EFUSE");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From ansuelsmth at gmail.com  Sat Dec  7 16:20:35 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:35 +0100
Subject: [net-next PATCH v10 0/9] net: dsa: Add Airoha AN8855 support
Message-ID: <20241208002105.18074-1-ansuelsmth@gmail.com>

This small series add the initial support for the Airoha AN8855 Switch.

It's a 5 port Gigabit Switch with SGMII/HSGMII upstream port.

This is starting to get in the wild and there are already some router
having this switch chip.

It's conceptually similar to mediatek switch but register and bits
are different. And there is that massive Hell that is the PCS
configuration.
Saddly for that part we have absolutely NO documentation currently.

There is this special thing where PHY needs to be calibrated with values
from the switch efuse. (the thing have a whole cpu timer and MCU)

>From v8 Driver is now evaluated with Kernel selftest scripts for DSA:

Output local_termination.sh
TEST: lan2: Unicast IPv4 to primary MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to macvlan MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address, promisc            [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address, allmulti           [ OK ]
TEST: lan2: Multicast IPv4 to joined group                          [ OK ]
TEST: lan2: Multicast IPv4 to unknown group                         [XFAIL]
        reception succeeded, but should have failed
TEST: lan2: Multicast IPv4 to unknown group, promisc                [ OK ]
TEST: lan2: Multicast IPv4 to unknown group, allmulti               [ OK ]
TEST: lan2: Multicast IPv6 to joined group                          [ OK ]
TEST: lan2: Multicast IPv6 to unknown group                         [XFAIL]
        reception succeeded, but should have failed
TEST: lan2: Multicast IPv6 to unknown group, promisc                [ OK ]
TEST: lan2: Multicast IPv6 to unknown group, allmulti               [ OK ]
TEST: lan2: 1588v2 over L2 transport, Sync                          [ OK ]
TEST: lan2: 1588v2 over L2 transport, Follow-Up                     [ OK ]
TEST: lan2: 1588v2 over L2 transport, Peer Delay Request            [ OK ]
TEST: lan2: 1588v2 over IPv4, Sync                                  [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv4, Follow-Up                             [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv4, Peer Delay Request                    [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Sync                                  [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Follow-Up                             [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Peer Delay Request                    [FAIL]
        reception failed
TEST: vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to joined group       [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to joined group       [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to joined group       [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to joined group       [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN upper: Unicast IPv4 to primary MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to macvlan MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address, promisc      [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address, allmulti     [ OK ]
TEST: VLAN upper: Multicast IPv4 to joined group                    [ OK ]
TEST: VLAN upper: Multicast IPv4 to unknown group                   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN upper: Multicast IPv4 to unknown group, promisc          [ OK ]
TEST: VLAN upper: Multicast IPv4 to unknown group, allmulti         [ OK ]
TEST: VLAN upper: Multicast IPv6 to joined group                    [ OK ]
TEST: VLAN upper: Multicast IPv6 to unknown group                   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN upper: Multicast IPv6 to unknown group, promisc          [ OK ]
TEST: VLAN upper: Multicast IPv6 to unknown group, allmulti         [ OK ]
TEST: VLAN upper: 1588v2 over L2 transport, Sync                    [ OK ]
TEST: VLAN upper: 1588v2 over L2 transport, Follow-Up               [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over L2 transport, Peer Delay Request      [ OK ]
TEST: VLAN upper: 1588v2 over IPv4, Sync                            [FAIL]
        reception failed
;TEST: VLAN upper: 1588v2 over IPv4, Follow-Up                       [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv4, Peer Delay Request              [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Sync                            [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Follow-Up                       [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Peer Delay Request              [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Sync   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Follow-Up   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Peer Delay Request   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address   [FAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, allmulti   [FAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Sync   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Follow-Up   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Peer Delay Request   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]

Output bridge_vlan_unaware.sh
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: FDB learning                                                  [ OK ]
TEST: Unknown unicast flood                                         [ OK ]
TEST: Unregistered multicast flood                                  [ OK ]

Output bridge_vlan_aware.sh
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: FDB learning                                                  [ OK ]
TEST: Unknown unicast flood                                         [ OK ]
TEST: Unregistered multicast flood                                  [ OK ]
INFO: Add and delete a VLAN on bridge port lan2
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: Externally learned FDB entry - ageing & roaming               [ OK ]
TEST: FDB entry in PVID for VLAN-tagged with other TPID             [FAIL]
        FDB entry was not learned when it should
TEST: Reception of VLAN with other TPID as untagged                 [FAIL]
        Packet was not forwarded when it should
TEST: Reception of VLAN with other TPID as untagged (no PVID)       [FAIL]
        Packet was forwarded when should not

[ For Vladimir, I still have to implement fdb_isolation but posting to
start the ball rolling for the multiple subsystem this patch affect
and for the dubious DT schema ]

Changes v10:
- Entire rework to MFD + split to MDIO, EFUSE, SWITCH separate drivers
- Drop EEE OPs (while Russell finish RFC for EEE changes)
- Use new pcs_inpand OPs
- Drop AN restart function and move to pcs_config
- Enable assisted_learning and disable CPU learn (preparation for fdb_isolation)
- Move EFUSE read in Internal PHY driver to .config to handle EPROBE_DEFER
  (needed now that NVMEM driver is register externall instead of internally to switch
   node)
Changes v9:
- Error out on using 5G speed as currently not supported
- Add missing MAC_2500FD in phylink mac_capabilities
- Add comment and improve if condition for an8855_phylink_mac_config
Changes v8:
- Add port Fast Age support
- Add support for Port Isolation
- Use correct register for Learning Disable
- Add support for Ageing Time OP
- Set default PVID to 0 by default
- Add mdb OPs
- Add port change MTU
- Fix support for Upper VLAN
Changes v7:
- Fix devm_dsa_register_switch wrong export symbol
Changes v6:
- Drop standard MIB and handle with ethtool OPs (as requested by Jakub)
- Cosmetic: use bool instead of 0 or 1
Changes v5:
- Add devm_dsa_register_switch() patch
- Add Reviewed-by tag for DT patch
Changes v4:
- Set regmap readable_table static (mute compilation warning)
- Add support for port_bridge flags (LEARNING, FLOOD)
- Reset fdb struct in fdb_dump
- Drop support_asym_pause in port_enable
- Add define for get_phy_flags
- Fix bug for port not inititially part of a bridge
  (in an8855_setup the port matrix was always cleared but
   the CPU port was never initially added)
- Disable learning and flood for user port by default
- Set CPU port to flood and learning by default
- Correctly AND force duplex and flow control in an8855_phylink_mac_link_up
- Drop RGMII from pcs_config
- Check ret in "Disable AN if not in autoneg"
- Use devm_mutex_init
- Fix typo for AN8855_PORT_CHECK_MODE
- Better define AN8855_STP_LISTENING = AN8855_STP_BLOCKING
- Fix typo in AN8855_PHY_EN_DOWN_SHIFT
- Use paged helper for PHY
- Skip calibration in config_init if priv not defined
Changes v3:
- Out of RFC
- Switch PHY code to select_page API
- Better describe masks and bits in PHY driver for ADC register
- Drop raw values and use define for mii read/write
- Switch to absolute PHY address
- Replace raw values with mask and bits for pcs_config
- Fix typo for ext-surge property name
- Drop support for relocating Switch base PHY address on the bus
Changes v2:
- Drop mutex guard patch
- Drop guard usage in DSA driver
- Use __mdiobus_write/read
- Check return condition and return errors for mii read/write
- Fix wrong logic for EEE
- Fix link_down (don't force link down with autoneg)
- Fix forcing speed on sgmii autoneg
- Better document link speed for sgmii reg
- Use standard define for sgmii reg
- Imlement nvmem support to expose switch EFUSE
- Rework PHY calibration with the use of NVMEM producer/consumer
- Update DT with new NVMEM property
- Move aneg validation for 2500-basex in pcs_config
- Move r50Ohm table and function to PHY driver

Christian Marangi (9):
  dt-bindings: nvmem: Document support for Airoha AN8855 Switch EFUSE
  dt-bindings: net: Document support for Airoha AN8855 Switch Virtual
    MDIO
  dt-bindings: net: dsa: Document support for Airoha AN8855 DSA Switch
  dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC
  mfd: an8855: Add support for Airoha AN8855 Switch MFD
  net: mdio: Add Airoha AN8855 Switch MDIO Passtrough
  nvmem: an8855: Add support for Airoha AN8855 Switch EFUSE
  net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
  net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY

 .../bindings/mfd/airoha,an8855-mfd.yaml       |  185 ++
 .../bindings/net/airoha,an8855-mdio.yaml      |   86 +
 .../net/dsa/airoha,an8855-switch.yaml         |  105 +
 .../bindings/nvmem/airoha,an8855-efuse.yaml   |  123 +
 MAINTAINERS                                   |   17 +
 drivers/mfd/Kconfig                           |    9 +
 drivers/mfd/Makefile                          |    1 +
 drivers/mfd/airoha-an8855.c                   |  279 ++
 drivers/net/dsa/Kconfig                       |    9 +
 drivers/net/dsa/Makefile                      |    1 +
 drivers/net/dsa/an8855.c                      | 2308 +++++++++++++++++
 drivers/net/dsa/an8855.h                      |  783 ++++++
 drivers/net/mdio/Kconfig                      |    9 +
 drivers/net/mdio/Makefile                     |    1 +
 drivers/net/mdio/mdio-an8855.c                |  113 +
 drivers/net/phy/Kconfig                       |    5 +
 drivers/net/phy/Makefile                      |    1 +
 drivers/net/phy/air_an8855.c                  |  267 ++
 drivers/nvmem/Kconfig                         |   11 +
 drivers/nvmem/Makefile                        |    2 +
 drivers/nvmem/an8855-efuse.c                  |   63 +
 include/linux/mfd/airoha-an8855-mfd.h         |   41 +
 22 files changed, 4419 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
 create mode 100644 Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 create mode 100644 Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 create mode 100644 drivers/mfd/airoha-an8855.c
 create mode 100644 drivers/net/dsa/an8855.c
 create mode 100644 drivers/net/dsa/an8855.h
 create mode 100644 drivers/net/mdio/mdio-an8855.c
 create mode 100644 drivers/net/phy/air_an8855.c
 create mode 100644 drivers/nvmem/an8855-efuse.c
 create mode 100644 include/linux/mfd/airoha-an8855-mfd.h

-- 
2.45.2



From ansuelsmth at gmail.com  Sat Dec  7 16:20:36 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:36 +0100
Subject: [net-next PATCH v10 1/9] dt-bindings: nvmem: Document support for Airoha AN8855 Switch EFUSE
In-Reply-To: <20241208002105.18074-1-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
Message-ID: <20241208002105.18074-2-ansuelsmth@gmail.com>

Document support for Airoha AN8855 Switch EFUSE used to calibrate
internal PHYs and store additional configuration info.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 .../bindings/nvmem/airoha,an8855-efuse.yaml   | 123 ++++++++++++++++++
 MAINTAINERS                                   |   8 ++
 2 files changed, 131 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml b/Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
new file mode 100644
index 000000000000..9802d9ea2176
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
@@ -0,0 +1,123 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/airoha,an8855-efuse.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 Switch EFUSE
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description:
+  Airoha AN8855 EFUSE used to calibrate internal PHYs and store additional
+  configuration info.
+
+$ref: nvmem.yaml#
+
+properties:
+  compatible:
+    const: airoha,an8855-efuse
+
+  '#nvmem-cell-cells':
+    const: 0
+
+required:
+  - compatible
+  - '#nvmem-cell-cells'
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    efuse {
+        compatible = "airoha,an8855-efuse";
+
+        #nvmem-cell-cells = <0>;
+
+        nvmem-layout {
+            compatible = "fixed-layout";
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            shift_sel_port0_tx_a: shift-sel-port0-tx-a at c {
+               reg = <0xc 0x4>;
+            };
+
+            shift_sel_port0_tx_b: shift-sel-port0-tx-b at 10 {
+                reg = <0x10 0x4>;
+            };
+
+            shift_sel_port0_tx_c: shift-sel-port0-tx-c at 14 {
+                reg = <0x14 0x4>;
+            };
+
+            shift_sel_port0_tx_d: shift-sel-port0-tx-d at 18 {
+               reg = <0x18 0x4>;
+            };
+
+            shift_sel_port1_tx_a: shift-sel-port1-tx-a at 1c {
+               reg = <0x1c 0x4>;
+            };
+
+            shift_sel_port1_tx_b: shift-sel-port1-tx-b at 20 {
+               reg = <0x20 0x4>;
+            };
+
+            shift_sel_port1_tx_c: shift-sel-port1-tx-c at 24 {
+               reg = <0x24 0x4>;
+            };
+
+            shift_sel_port1_tx_d: shift-sel-port1-tx-d at 28 {
+               reg = <0x28 0x4>;
+            };
+
+            shift_sel_port2_tx_a: shift-sel-port2-tx-a at 2c {
+                reg = <0x2c 0x4>;
+            };
+
+            shift_sel_port2_tx_b: shift-sel-port2-tx-b at 30 {
+                reg = <0x30 0x4>;
+            };
+
+            shift_sel_port2_tx_c: shift-sel-port2-tx-c at 34 {
+                reg = <0x34 0x4>;
+            };
+
+            shift_sel_port2_tx_d: shift-sel-port2-tx-d at 38 {
+                reg = <0x38 0x4>;
+            };
+
+            shift_sel_port3_tx_a: shift-sel-port3-tx-a at 4c {
+                reg = <0x4c 0x4>;
+            };
+
+            shift_sel_port3_tx_b: shift-sel-port3-tx-b at 50 {
+                reg = <0x50 0x4>;
+            };
+
+            shift_sel_port3_tx_c: shift-sel-port3-tx-c at 54 {
+               reg = <0x54 0x4>;
+            };
+
+            shift_sel_port3_tx_d: shift-sel-port3-tx-d at 58 {
+               reg = <0x58 0x4>;
+            };
+
+            shift_sel_port4_tx_a: shift-sel-port4-tx-a at 5c {
+                reg = <0x5c 0x4>;
+            };
+
+            shift_sel_port4_tx_b: shift-sel-port4-tx-b at 60 {
+                reg = <0x60 0x4>;
+            };
+
+            shift_sel_port4_tx_c: shift-sel-port4-tx-c at 64 {
+                reg = <0x64 0x4>;
+            };
+
+            shift_sel_port4_tx_d: shift-sel-port4-tx-d at 68 {
+                reg = <0x68 0x4>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 79756f2100e0..53ef66eef473 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -711,6 +711,14 @@ S:	Supported
 F:	fs/aio.c
 F:	include/linux/*aio*.h
 
+AIROHA DSA DRIVER
+M:	Christian Marangi <ansuelsmth at gmail.com>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
+L:	netdev at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
+
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
-- 
2.45.2



From ansuelsmth at gmail.com  Sat Dec  7 16:20:43 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:43 +0100
Subject: [net-next PATCH v10 8/9] net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
In-Reply-To: <20241208002105.18074-1-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
Message-ID: <20241208002105.18074-9-ansuelsmth@gmail.com>

Add Airoha AN8855 5-Port Gigabit DSA switch. Switch can support
10M, 100M, 1Gb, 2.5G and 5G Ethernet Speed but 5G is currently error out
as it's not currently supported as requires additional configuration for
the PCS.

The switch is also a nvmem-provider as it does have EFUSE to calibrate
the internal PHYs.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS              |    2 +
 drivers/net/dsa/Kconfig  |    9 +
 drivers/net/dsa/Makefile |    1 +
 drivers/net/dsa/an8855.c | 2308 ++++++++++++++++++++++++++++++++++++++
 drivers/net/dsa/an8855.h |  783 +++++++++++++
 5 files changed, 3103 insertions(+)
 create mode 100644 drivers/net/dsa/an8855.c
 create mode 100644 drivers/net/dsa/an8855.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a67d147276a1..c42431a09b84 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -722,6 +722,8 @@ F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 F:	drivers/mfd/airoha-an8855.c
+F:	drivers/net/dsa/an8855.c
+F:	drivers/net/dsa/an8855.h
 F:	drivers/net/mdio/mdio-an8855.c
 F:	drivers/nvmem/an8855-efuse.c
 
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 2d10b4d6cfbb..0761759752ce 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -24,6 +24,15 @@ config NET_DSA_LOOP
 	  This enables support for a fake mock-up switch chip which
 	  exercises the DSA APIs.
 
+config NET_DSA_AN8855
+	tristate "Airoha AN8855 Ethernet switch support"
+	depends on MFD_AIROHA_AN8855
+	depends on NET_DSA
+	select NET_DSA_TAG_MTK
+	help
+	  This enables support for the Airoha AN8855 Ethernet switch
+	  chip.
+
 source "drivers/net/dsa/hirschmann/Kconfig"
 
 config NET_DSA_LANTIQ_GSWIP
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index cb9a97340e58..a74afb41a491 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_NET_DSA_LOOP)	+= dsa_loop.o
 ifdef CONFIG_NET_DSA_LOOP
 obj-$(CONFIG_FIXED_PHY)		+= dsa_loop_bdinfo.o
 endif
+obj-$(CONFIG_NET_DSA_AN8855)	+= an8855.o
 obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
 obj-$(CONFIG_NET_DSA_MT7530)	+= mt7530.o
 obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
diff --git a/drivers/net/dsa/an8855.c b/drivers/net/dsa/an8855.c
new file mode 100644
index 000000000000..ed3b0b0f8c4e
--- /dev/null
+++ b/drivers/net/dsa/an8855.c
@@ -0,0 +1,2308 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Airoha AN8855 DSA Switch driver
+ * Copyright (C) 2023 Min Yao <min.yao at airoha.com>
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth at gmail.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+#include <linux/gpio/consumer.h>
+#include <linux/if_bridge.h>
+#include <linux/iopoll.h>
+#include <linux/netdevice.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/phylink.h>
+#include <linux/regmap.h>
+#include <net/dsa.h>
+
+#include "an8855.h"
+
+static const struct an8855_mib_desc an8855_mib[] = {
+	MIB_DESC(1, AN8855_PORT_MIB_TX_DROP, "TxDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_TX_CRC_ERR, "TxCrcErr"),
+	MIB_DESC(1, AN8855_PORT_MIB_TX_COLLISION, "TxCollision"),
+	MIB_DESC(1, AN8855_PORT_MIB_TX_OVERSIZE_DROP, "TxOversizeDrop"),
+	MIB_DESC(2, AN8855_PORT_MIB_TX_BAD_PKT_BYTES, "TxBadPktBytes"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_DROP, "RxDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_FILTERING, "RxFiltering"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_CRC_ERR, "RxCrcErr"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_CTRL_DROP, "RxCtrlDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_INGRESS_DROP, "RxIngressDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_ARL_DROP, "RxArlDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_FLOW_CONTROL_DROP, "FlowControlDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_WRED_DROP, "WredDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_MIRROR_DROP, "MirrorDrop"),
+	MIB_DESC(2, AN8855_PORT_MIB_RX_BAD_PKT_BYTES, "RxBadPktBytes"),
+	MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP, "RxsFlowSamplingPktDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP, "RxsFlowTotalPktDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_PORT_CONTROL_DROP, "PortControlDrop"),
+};
+
+static int
+an8855_mib_init(struct an8855_priv *priv)
+{
+	int ret;
+
+	ret = regmap_write(priv->regmap, AN8855_MIB_CCR,
+			   AN8855_CCR_MIB_ENABLE);
+	if (ret)
+		return ret;
+
+	return regmap_write(priv->regmap, AN8855_MIB_CCR,
+			    AN8855_CCR_MIB_ACTIVATE);
+}
+
+static void an8855_fdb_write(struct an8855_priv *priv, u16 vid,
+			     u8 port_mask, const u8 *mac,
+			     bool add) __must_hold(&priv->reg_mutex)
+{
+	u32 mac_reg[2] = { };
+	u32 reg;
+
+	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC0, mac[0]);
+	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC1, mac[1]);
+	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC2, mac[2]);
+	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC3, mac[3]);
+	mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC4, mac[4]);
+	mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC5, mac[5]);
+
+	regmap_bulk_write(priv->regmap, AN8855_ATA1, mac_reg,
+			  ARRAY_SIZE(mac_reg));
+
+	reg = AN8855_ATWD_IVL;
+	if (add)
+		reg |= AN8855_ATWD_VLD;
+	reg |= FIELD_PREP(AN8855_ATWD_VID, vid);
+	reg |= FIELD_PREP(AN8855_ATWD_FID, AN8855_FID_BRIDGED);
+	regmap_write(priv->regmap, AN8855_ATWD, reg);
+	regmap_write(priv->regmap, AN8855_ATWD2,
+		     FIELD_PREP(AN8855_ATWD2_PORT, port_mask));
+}
+
+static void an8855_fdb_read(struct an8855_priv *priv, struct an8855_fdb *fdb)
+{
+	u32 reg[4];
+
+	regmap_bulk_read(priv->regmap, AN8855_ATRD0, reg,
+			 ARRAY_SIZE(reg));
+
+	fdb->live = FIELD_GET(AN8855_ATRD0_LIVE, reg[0]);
+	fdb->type = FIELD_GET(AN8855_ATRD0_TYPE, reg[0]);
+	fdb->ivl = FIELD_GET(AN8855_ATRD0_IVL, reg[0]);
+	fdb->vid = FIELD_GET(AN8855_ATRD0_VID, reg[0]);
+	fdb->fid = FIELD_GET(AN8855_ATRD0_FID, reg[0]);
+	fdb->aging = FIELD_GET(AN8855_ATRD1_AGING, reg[1]);
+	fdb->port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, reg[3]);
+	fdb->mac[0] = FIELD_GET(AN8855_ATRD2_MAC0, reg[2]);
+	fdb->mac[1] = FIELD_GET(AN8855_ATRD2_MAC1, reg[2]);
+	fdb->mac[2] = FIELD_GET(AN8855_ATRD2_MAC2, reg[2]);
+	fdb->mac[3] = FIELD_GET(AN8855_ATRD2_MAC3, reg[2]);
+	fdb->mac[4] = FIELD_GET(AN8855_ATRD1_MAC4, reg[1]);
+	fdb->mac[5] = FIELD_GET(AN8855_ATRD1_MAC5, reg[1]);
+	fdb->noarp = !!FIELD_GET(AN8855_ATRD0_ARP, reg[0]);
+}
+
+static int an8855_fdb_cmd(struct an8855_priv *priv, u32 cmd,
+			  u32 *rsp) __must_hold(&priv->reg_mutex)
+{
+	u32 val;
+	int ret;
+
+	/* Set the command operating upon the MAC address entries */
+	val = AN8855_ATC_BUSY | cmd;
+	ret = regmap_write(priv->regmap, AN8855_ATC, val);
+	if (ret)
+		return ret;
+
+	ret = regmap_read_poll_timeout(priv->regmap, AN8855_ATC, val,
+				       !(val & AN8855_ATC_BUSY), 20, 200000);
+	if (ret)
+		return ret;
+
+	if (rsp)
+		*rsp = val;
+
+	return 0;
+}
+
+static void
+an8855_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+{
+	struct dsa_port *dp = dsa_to_port(ds, port);
+	struct an8855_priv *priv = ds->priv;
+	bool learning = false;
+	u32 stp_state;
+
+	switch (state) {
+	case BR_STATE_DISABLED:
+		stp_state = AN8855_STP_DISABLED;
+		break;
+	case BR_STATE_BLOCKING:
+		stp_state = AN8855_STP_BLOCKING;
+		break;
+	case BR_STATE_LISTENING:
+		stp_state = AN8855_STP_LISTENING;
+		break;
+	case BR_STATE_LEARNING:
+		stp_state = AN8855_STP_LEARNING;
+		learning = dp->learning;
+		break;
+	case BR_STATE_FORWARDING:
+		learning = dp->learning;
+		fallthrough;
+	default:
+		stp_state = AN8855_STP_FORWARDING;
+		break;
+	}
+
+	regmap_update_bits(priv->regmap, AN8855_SSP_P(port),
+			   AN8855_FID_PST_MASK(AN8855_FID_BRIDGED),
+			   AN8855_FID_PST_VAL(AN8855_FID_BRIDGED, stp_state));
+
+	regmap_update_bits(priv->regmap, AN8855_PSC_P(port), AN8855_SA_DIS,
+			   learning ? 0 : AN8855_SA_DIS);
+}
+
+static void an8855_port_fast_age(struct dsa_switch *ds, int port)
+{
+	struct an8855_priv *priv = ds->priv;
+	int ret;
+
+	/* Set to clean Dynamic entry */
+	ret = regmap_write(priv->regmap, AN8855_ATA2, AN8855_ATA2_TYPE);
+	if (ret)
+		return;
+
+	/* Set Port */
+	ret = regmap_write(priv->regmap, AN8855_ATWD2,
+			   FIELD_PREP(AN8855_ATWD2_PORT, BIT(port)));
+	if (ret)
+		return;
+
+	/* Flush Dynamic entry at port */
+	an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_TYPE_PORT) |
+		       AN8855_FDB_FLUSH, NULL);
+}
+
+static int an8855_update_port_member(struct dsa_switch *ds, int port,
+				     const struct net_device *bridge_dev,
+				     bool join)
+{
+	struct an8855_priv *priv = ds->priv;
+	bool isolated, other_isolated;
+	struct dsa_port *dp;
+	u32 port_mask = 0;
+	int ret;
+
+	isolated = !!(priv->port_isolated_map & BIT(port));
+
+	dsa_switch_for_each_user_port(dp, ds) {
+		if (dp->index == port)
+			continue;
+
+		if (!dsa_port_offloads_bridge_dev(dp, bridge_dev))
+			continue;
+
+		other_isolated = !!(priv->port_isolated_map & BIT(dp->index));
+		port_mask |= BIT(dp->index);
+		/* Add/remove this port to the portvlan mask of the other
+		 * ports in the bridge
+		 */
+		if (join && !(isolated && other_isolated))
+			ret = regmap_set_bits(priv->regmap,
+					      AN8855_PORTMATRIX_P(dp->index),
+					      FIELD_PREP(AN8855_USER_PORTMATRIX,
+							 BIT(port)));
+		else
+			ret = regmap_clear_bits(priv->regmap,
+						AN8855_PORTMATRIX_P(dp->index),
+						FIELD_PREP(AN8855_USER_PORTMATRIX,
+							   BIT(port)));
+		if (ret)
+			return ret;
+	}
+
+	/* Add/remove all other ports to this port's portvlan mask */
+	return regmap_update_bits(priv->regmap, AN8855_PORTMATRIX_P(port),
+				  AN8855_USER_PORTMATRIX,
+				  join ? port_mask : ~port_mask);
+}
+
+static int an8855_port_pre_bridge_flags(struct dsa_switch *ds, int port,
+					struct switchdev_brport_flags flags,
+					struct netlink_ext_ack *extack)
+{
+	if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
+			   BR_BCAST_FLOOD | BR_ISOLATED))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int an8855_port_bridge_flags(struct dsa_switch *ds, int port,
+				    struct switchdev_brport_flags flags,
+				    struct netlink_ext_ack *extack)
+{
+	struct an8855_priv *priv = ds->priv;
+	int ret;
+
+	if (flags.mask & BR_LEARNING) {
+		ret = regmap_update_bits(priv->regmap, AN8855_PSC_P(port), AN8855_SA_DIS,
+					 flags.val & BR_LEARNING ? 0 : AN8855_SA_DIS);
+		if (ret)
+			return ret;
+	}
+
+	if (flags.mask & BR_FLOOD) {
+		ret = regmap_update_bits(priv->regmap, AN8855_UNUF, BIT(port),
+					 flags.val & BR_FLOOD ? BIT(port) : 0);
+		if (ret)
+			return ret;
+	}
+
+	if (flags.mask & BR_MCAST_FLOOD) {
+		ret = regmap_update_bits(priv->regmap, AN8855_UNMF, BIT(port),
+					 flags.val & BR_MCAST_FLOOD ? BIT(port) : 0);
+		if (ret)
+			return ret;
+
+		ret = regmap_update_bits(priv->regmap, AN8855_UNIPMF, BIT(port),
+					 flags.val & BR_MCAST_FLOOD ? BIT(port) : 0);
+		if (ret)
+			return ret;
+	}
+
+	if (flags.mask & BR_BCAST_FLOOD) {
+		ret = regmap_update_bits(priv->regmap, AN8855_BCF, BIT(port),
+					 flags.val & BR_BCAST_FLOOD ? BIT(port) : 0);
+		if (ret)
+			return ret;
+	}
+
+	if (flags.mask & BR_ISOLATED) {
+		struct dsa_port *dp = dsa_to_port(ds, port);
+		struct net_device *bridge_dev = dsa_port_bridge_dev_get(dp);
+
+		if (flags.val & BR_ISOLATED)
+			priv->port_isolated_map |= BIT(port);
+		else
+			priv->port_isolated_map &= ~BIT(port);
+
+		ret = an8855_update_port_member(ds, port, bridge_dev, true);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int an8855_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
+{
+	struct an8855_priv *priv = ds->priv;
+	u32 age_count, age_unit, val;
+
+	/* Convert msec in AN8855_L2_AGING_MS_CONSTANT counter */
+	val = msecs / AN8855_L2_AGING_MS_CONSTANT;
+	/* Derive the count unit */
+	age_unit = val / FIELD_MAX(AN8855_AGE_UNIT);
+	/* Get the count in unit, age_unit is always incremented by 1 internally */
+	age_count = val / (age_unit + 1);
+
+	return regmap_update_bits(priv->regmap, AN8855_AAC,
+				  AN8855_AGE_CNT | AN8855_AGE_UNIT,
+				  FIELD_PREP(AN8855_AGE_CNT, age_count) |
+				  FIELD_PREP(AN8855_AGE_UNIT, age_unit));
+}
+
+static int an8855_port_bridge_join(struct dsa_switch *ds, int port,
+				   struct dsa_bridge bridge,
+				   bool *tx_fwd_offload,
+				   struct netlink_ext_ack *extack)
+{
+	struct an8855_priv *priv = ds->priv;
+	int ret;
+
+	ret = an8855_update_port_member(ds, port, bridge.dev, true);
+	if (ret)
+		return ret;
+
+	/* Set to fallback mode for independent VLAN learning if in a bridge */
+	return regmap_update_bits(priv->regmap, AN8855_PCR_P(port),
+				  AN8855_PORT_VLAN,
+				  FIELD_PREP(AN8855_PORT_VLAN,
+					     AN8855_PORT_FALLBACK_MODE));
+}
+
+static void an8855_port_bridge_leave(struct dsa_switch *ds, int port,
+				     struct dsa_bridge bridge)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	an8855_update_port_member(ds, port, bridge.dev, false);
+
+	/* When a port is removed from the bridge, the port would be set up
+	 * back to the default as is at initial boot which is a VLAN-unaware
+	 * port.
+	 */
+	regmap_update_bits(priv->regmap, AN8855_PCR_P(port),
+			   AN8855_PORT_VLAN,
+			   FIELD_PREP(AN8855_PORT_VLAN,
+				      AN8855_PORT_MATRIX_MODE));
+}
+
+static int an8855_port_fdb_add(struct dsa_switch *ds, int port,
+			       const unsigned char *addr, u16 vid,
+			       struct dsa_db db)
+{
+	struct an8855_priv *priv = ds->priv;
+	u8 port_mask = BIT(port);
+	int ret;
+
+	/* Set the vid to the port vlan id if no vid is set */
+	if (!vid)
+		vid = AN8855_PORT_VID_DEFAULT;
+
+	mutex_lock(&priv->reg_mutex);
+	an8855_fdb_write(priv, vid, port_mask, addr, true);
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+	mutex_unlock(&priv->reg_mutex);
+
+	return ret;
+}
+
+static int an8855_port_fdb_del(struct dsa_switch *ds, int port,
+			       const unsigned char *addr, u16 vid,
+			       struct dsa_db db)
+{
+	struct an8855_priv *priv = ds->priv;
+	u8 port_mask = BIT(port);
+	int ret;
+
+	/* Set the vid to the port vlan id if no vid is set */
+	if (!vid)
+		vid = AN8855_PORT_VID_DEFAULT;
+
+	mutex_lock(&priv->reg_mutex);
+	an8855_fdb_write(priv, vid, port_mask, addr, false);
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+	mutex_unlock(&priv->reg_mutex);
+
+	return ret;
+}
+
+static int an8855_port_fdb_dump(struct dsa_switch *ds, int port,
+				dsa_fdb_dump_cb_t *cb, void *data)
+{
+	struct an8855_priv *priv = ds->priv;
+	int banks, count = 0;
+	u32 rsp;
+	int ret;
+	int i;
+
+	mutex_lock(&priv->reg_mutex);
+
+	/* Load search port */
+	ret = regmap_write(priv->regmap, AN8855_ATWD2,
+			   FIELD_PREP(AN8855_ATWD2_PORT, BIT(port)));
+	if (ret)
+		goto exit;
+	ret = an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_PORT) |
+			     AN8855_FDB_START, &rsp);
+	if (ret < 0)
+		goto exit;
+
+	do {
+		/* From response get the number of banks to read, exit if 0 */
+		banks = FIELD_GET(AN8855_ATC_HIT, rsp);
+		if (!banks)
+			break;
+
+		/* Each banks have 4 entry */
+		for (i = 0; i < 4; i++) {
+			struct an8855_fdb _fdb = {  };
+
+			count++;
+
+			/* Check if bank is present */
+			if (!(banks & BIT(i)))
+				continue;
+
+			/* Select bank entry index */
+			ret = regmap_write(priv->regmap, AN8855_ATRDS,
+					   FIELD_PREP(AN8855_ATRD_SEL, i));
+			if (ret)
+				break;
+			/* wait 1ms for the bank entry to be filled */
+			usleep_range(1000, 1500);
+			an8855_fdb_read(priv, &_fdb);
+
+			if (!_fdb.live)
+				continue;
+			ret = cb(_fdb.mac, _fdb.vid, _fdb.noarp, data);
+			if (ret < 0)
+				break;
+		}
+
+		/* Stop if reached max FDB number */
+		if (count >= AN8855_NUM_FDB_RECORDS)
+			break;
+
+		/* Read next bank */
+		ret = an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_PORT) |
+				     AN8855_FDB_NEXT, &rsp);
+		if (ret < 0)
+			break;
+	} while (true);
+
+exit:
+	mutex_unlock(&priv->reg_mutex);
+	return ret;
+}
+
+static int an8855_vlan_cmd(struct an8855_priv *priv, enum an8855_vlan_cmd cmd,
+			   u16 vid) __must_hold(&priv->reg_mutex)
+{
+	u32 val;
+	int ret;
+
+	val = AN8855_VTCR_BUSY | FIELD_PREP(AN8855_VTCR_FUNC, cmd) |
+	      FIELD_PREP(AN8855_VTCR_VID, vid);
+	ret = regmap_write(priv->regmap, AN8855_VTCR, val);
+	if (ret)
+		return ret;
+
+	return regmap_read_poll_timeout(priv->regmap, AN8855_VTCR, val,
+					!(val & AN8855_VTCR_BUSY), 20, 200000);
+}
+
+static int an8855_vlan_add(struct an8855_priv *priv, u8 port, u16 vid,
+			   bool untagged) __must_hold(&priv->reg_mutex)
+{
+	u32 port_mask;
+	u32 val;
+	int ret;
+
+	/* Fetch entry */
+	ret = an8855_vlan_cmd(priv, AN8855_VTCR_RD_VID, vid);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(priv->regmap, AN8855_VARD0, &val);
+	if (ret)
+		return ret;
+	port_mask = FIELD_GET(AN8855_VA0_PORT, val) | BIT(port);
+
+	/* Validate the entry with independent learning, create egress tag per
+	 * VLAN and joining the port as one of the port members.
+	 */
+	val = (val & AN8855_VA0_ETAG) | AN8855_VA0_IVL_MAC |
+	      AN8855_VA0_VTAG_EN | AN8855_VA0_VLAN_VALID |
+	      FIELD_PREP(AN8855_VA0_PORT, port_mask) |
+	      FIELD_PREP(AN8855_VA0_FID, AN8855_FID_BRIDGED);
+	ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
+	if (ret)
+		return ret;
+	ret = regmap_write(priv->regmap, AN8855_VAWD1, 0);
+	if (ret)
+		return ret;
+
+	/* CPU port is always taken as a tagged port for serving more than one
+	 * VLANs across and also being applied with egress type stack mode for
+	 * that VLAN tags would be appended after hardware special tag used as
+	 * DSA tag.
+	 */
+	if (port == AN8855_CPU_PORT)
+		val = AN8855_VLAN_EGRESS_STACK;
+	/* Decide whether adding tag or not for those outgoing packets from the
+	 * port inside the VLAN.
+	 */
+	else
+		val = untagged ? AN8855_VLAN_EGRESS_UNTAG : AN8855_VLAN_EGRESS_TAG;
+	ret = regmap_update_bits(priv->regmap, AN8855_VAWD0,
+				 AN8855_VA0_ETAG_PORT_MASK(port),
+				 AN8855_VA0_ETAG_PORT_VAL(port, val));
+	if (ret)
+		return ret;
+
+	/* Flush result to hardware */
+	return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID, vid);
+}
+
+static int an8855_vlan_del(struct an8855_priv *priv, u8 port,
+			   u16 vid) __must_hold(&priv->reg_mutex)
+{
+	u32 port_mask;
+	u32 val;
+	int ret;
+
+	/* Fetch entry */
+	ret = an8855_vlan_cmd(priv, AN8855_VTCR_RD_VID, vid);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(priv->regmap, AN8855_VARD0, &val);
+	if (ret)
+		return ret;
+	port_mask = FIELD_GET(AN8855_VA0_PORT, val) & ~BIT(port);
+
+	if (!(val & AN8855_VA0_VLAN_VALID)) {
+		dev_err(priv->dev, "Cannot be deleted due to invalid entry\n");
+		return -EINVAL;
+	}
+
+	if (port_mask) {
+		val = (val & AN8855_VA0_ETAG) | AN8855_VA0_IVL_MAC |
+		       AN8855_VA0_VTAG_EN | AN8855_VA0_VLAN_VALID |
+		       FIELD_PREP(AN8855_VA0_PORT, port_mask);
+		ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
+		if (ret)
+			return ret;
+	} else {
+		ret = regmap_write(priv->regmap, AN8855_VAWD0, 0);
+		if (ret)
+			return ret;
+	}
+	ret = regmap_write(priv->regmap, AN8855_VAWD1, 0);
+	if (ret)
+		return ret;
+
+	/* Flush result to hardware */
+	return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID, vid);
+}
+
+static int an8855_port_set_vlan_mode(struct an8855_priv *priv, int port,
+				     enum an8855_port_mode port_mode,
+				     enum an8855_vlan_port_eg_tag eg_tag,
+				     enum an8855_vlan_port_attr vlan_attr,
+				     enum an8855_vlan_port_acc_frm acc_frm)
+{
+	int ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_PCR_P(port),
+				 AN8855_PORT_VLAN,
+				 FIELD_PREP(AN8855_PORT_VLAN, port_mode));
+	if (ret)
+		return ret;
+
+	return regmap_update_bits(priv->regmap, AN8855_PVC_P(port),
+				  AN8855_PVC_EG_TAG | AN8855_VLAN_ATTR | AN8855_ACC_FRM,
+				  FIELD_PREP(AN8855_PVC_EG_TAG, eg_tag) |
+				  FIELD_PREP(AN8855_VLAN_ATTR, vlan_attr) |
+				  FIELD_PREP(AN8855_ACC_FRM, acc_frm));
+}
+
+static int an8855_port_set_pid(struct an8855_priv *priv, int port,
+			       u16 pid)
+{
+	int ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_PPBV1_P(port),
+				 AN8855_PPBV_G0_PORT_VID,
+				 FIELD_PREP(AN8855_PPBV_G0_PORT_VID, pid));
+	if (ret)
+		return ret;
+
+	return regmap_update_bits(priv->regmap, AN8855_PVID_P(port),
+				  AN8855_G0_PORT_VID,
+				  FIELD_PREP(AN8855_G0_PORT_VID, pid));
+}
+
+static int an8855_port_vlan_filtering(struct dsa_switch *ds, int port,
+				      bool vlan_filtering,
+				      struct netlink_ext_ack *extack)
+{
+	struct an8855_priv *priv = ds->priv;
+	u32 val;
+	int ret;
+
+	/* The port is being kept as VLAN-unaware port when bridge is
+	 * set up with vlan_filtering not being set, Otherwise, the
+	 * port and the corresponding CPU port is required the setup
+	 * for becoming a VLAN-aware port.
+	 */
+	if (vlan_filtering) {
+		u32 acc_frm;
+		/* CPU port is set to fallback mode to let untagged
+		 * frames pass through.
+		 */
+		ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT,
+						AN8855_PORT_FALLBACK_MODE,
+						AN8855_VLAN_EG_CONSISTENT,
+						AN8855_VLAN_USER,
+						AN8855_VLAN_ACC_ALL);
+		if (ret)
+			return ret;
+
+		ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
+		if (ret)
+			return ret;
+
+		/* Only accept tagged frames if PVID is not set */
+		if (FIELD_GET(AN8855_G0_PORT_VID, val) != AN8855_PORT_VID_DEFAULT)
+			acc_frm = AN8855_VLAN_ACC_TAGGED;
+		else
+			acc_frm = AN8855_VLAN_ACC_ALL;
+
+		/* Trapped into security mode allows packet forwarding through VLAN
+		 * table lookup.
+		 * Set the port as a user port which is to be able to recognize VID
+		 * from incoming packets before fetching entry within the VLAN table.
+		 */
+		ret = an8855_port_set_vlan_mode(priv, port,
+						AN8855_PORT_SECURITY_MODE,
+						AN8855_VLAN_EG_DISABLED,
+						AN8855_VLAN_USER,
+						acc_frm);
+		if (ret)
+			return ret;
+	} else {
+		bool disable_cpu_vlan = true;
+		struct dsa_port *dp;
+		u32 port_mode;
+
+		/* This is called after .port_bridge_leave when leaving a VLAN-aware
+		 * bridge. Don't set standalone ports to fallback mode.
+		 */
+		if (dsa_port_bridge_dev_get(dsa_to_port(ds, port)))
+			port_mode = AN8855_PORT_FALLBACK_MODE;
+		else
+			port_mode = AN8855_PORT_MATRIX_MODE;
+
+		/* When a port is removed from the bridge, the port would be set up
+		 * back to the default as is at initial boot which is a VLAN-unaware
+		 * port.
+		 */
+		ret = an8855_port_set_vlan_mode(priv, port, port_mode,
+						AN8855_VLAN_EG_CONSISTENT,
+						AN8855_VLAN_TRANSPARENT,
+						AN8855_VLAN_ACC_ALL);
+		if (ret)
+			return ret;
+
+		/* Restore default PVID */
+		ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
+		if (ret)
+			return ret;
+
+		dsa_switch_for_each_user_port(dp, ds) {
+			if (dsa_port_is_vlan_filtering(dp)) {
+				disable_cpu_vlan = false;
+				break;
+			}
+		}
+
+		if (disable_cpu_vlan) {
+			ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT,
+							AN8855_PORT_MATRIX_MODE,
+							AN8855_VLAN_EG_CONSISTENT,
+							AN8855_VLAN_USER,
+							AN8855_VLAN_ACC_ALL);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int an8855_port_vlan_add(struct dsa_switch *ds, int port,
+				const struct switchdev_obj_port_vlan *vlan,
+				struct netlink_ext_ack *extack)
+{
+	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
+	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
+	struct an8855_priv *priv = ds->priv;
+	u32 val;
+	int ret;
+
+	mutex_lock(&priv->reg_mutex);
+	ret = an8855_vlan_add(priv, port, vlan->vid, untagged);
+	mutex_unlock(&priv->reg_mutex);
+	if (ret)
+		return ret;
+
+	if (pvid) {
+		/* Accept all frames if PVID is set */
+		regmap_update_bits(priv->regmap, AN8855_PVC_P(port), AN8855_ACC_FRM,
+				   FIELD_PREP(AN8855_ACC_FRM, AN8855_VLAN_ACC_ALL));
+
+		/* Only configure PVID if VLAN filtering is enabled */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
+			ret = an8855_port_set_pid(priv, port, vlan->vid);
+			if (ret)
+				return ret;
+		}
+	} else if (vlan->vid) {
+		ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
+		if (ret)
+			return ret;
+
+		if (FIELD_GET(AN8855_G0_PORT_VID, val) != vlan->vid)
+			return 0;
+
+		/* This VLAN is overwritten without PVID, so unset it */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
+			ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(port),
+						 AN8855_ACC_FRM,
+						 FIELD_PREP(AN8855_ACC_FRM,
+							    AN8855_VLAN_ACC_TAGGED));
+			if (ret)
+				return ret;
+		}
+
+		ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int an8855_port_vlan_del(struct dsa_switch *ds, int port,
+				const struct switchdev_obj_port_vlan *vlan)
+{
+	struct an8855_priv *priv = ds->priv;
+	u32 val;
+	int ret;
+
+	mutex_lock(&priv->reg_mutex);
+	ret = an8855_vlan_del(priv, port, vlan->vid);
+	mutex_unlock(&priv->reg_mutex);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
+	if (ret)
+		return ret;
+
+	/* PVID is being restored to the default whenever the PVID port
+	 * is being removed from the VLAN.
+	 */
+	if (FIELD_GET(AN8855_G0_PORT_VID, val) == vlan->vid) {
+		/* Only accept tagged frames if the port is VLAN-aware */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
+			ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(port),
+						 AN8855_ACC_FRM,
+						 FIELD_PREP(AN8855_ACC_FRM,
+							    AN8855_VLAN_ACC_TAGGED));
+			if (ret)
+				return ret;
+		}
+
+		ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+an8855_port_mdb_add(struct dsa_switch *ds, int port,
+		    const struct switchdev_obj_port_mdb *mdb,
+		    struct dsa_db db)
+{
+	struct an8855_priv *priv = ds->priv;
+	const u8 *addr = mdb->addr;
+	u16 vid = mdb->vid;
+	u8 port_mask = 0;
+	u32 val;
+	int ret;
+
+	/* Set the vid to the port vlan id if no vid is set */
+	if (!vid)
+		vid = AN8855_PORT_VID_DEFAULT;
+
+	mutex_lock(&priv->reg_mutex);
+
+	an8855_fdb_write(priv, vid, 0, addr, false);
+	if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) {
+		ret = regmap_read(priv->regmap, AN8855_ATRD3, &val);
+		if (ret)
+			goto exit;
+
+		port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val);
+	}
+
+	port_mask |= BIT(port);
+	an8855_fdb_write(priv, vid, port_mask, addr, true);
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+
+exit:
+	mutex_unlock(&priv->reg_mutex);
+
+	return ret;
+}
+
+static int
+an8855_port_mdb_del(struct dsa_switch *ds, int port,
+		    const struct switchdev_obj_port_mdb *mdb,
+		    struct dsa_db db)
+{
+	struct an8855_priv *priv = ds->priv;
+	const u8 *addr = mdb->addr;
+	u16 vid = mdb->vid;
+	u8 port_mask = 0;
+	u32 val;
+	int ret;
+
+	/* Set the vid to the port vlan id if no vid is set */
+	if (!vid)
+		vid = AN8855_PORT_VID_DEFAULT;
+
+	mutex_lock(&priv->reg_mutex);
+
+	an8855_fdb_write(priv, vid, 0, addr, 0);
+	if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) {
+		ret = regmap_read(priv->regmap, AN8855_ATRD3, &val);
+		if (ret)
+			goto exit;
+
+		port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val);
+	}
+
+	port_mask &= ~BIT(port);
+	an8855_fdb_write(priv, vid, port_mask, addr, port_mask ? true : false);
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+
+exit:
+	mutex_unlock(&priv->reg_mutex);
+
+	return ret;
+}
+
+static int
+an8855_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+	struct an8855_priv *priv = ds->priv;
+	int length;
+	u32 val;
+
+	/* When a new MTU is set, DSA always set the CPU port's MTU to the
+	 * largest MTU of the slave ports. Because the switch only has a global
+	 * RX length register, only allowing CPU port here is enough.
+	 */
+	if (!dsa_is_cpu_port(ds, port))
+		return 0;
+
+	/* RX length also includes Ethernet header, MTK tag, and FCS length */
+	length = new_mtu + ETH_HLEN + MTK_TAG_LEN + ETH_FCS_LEN;
+	if (length <= 1522)
+		val = AN8855_MAX_RX_PKT_1518_1522;
+	else if (length <= 1536)
+		val = AN8855_MAX_RX_PKT_1536;
+	else if (length <= 1552)
+		val = AN8855_MAX_RX_PKT_1552;
+	else if (length <= 3072)
+		val = AN8855_MAX_RX_JUMBO_3K;
+	else if (length <= 4096)
+		val = AN8855_MAX_RX_JUMBO_4K;
+	else if (length <= 5120)
+		val = AN8855_MAX_RX_JUMBO_5K;
+	else if (length <= 6144)
+		val = AN8855_MAX_RX_JUMBO_6K;
+	else if (length <= 7168)
+		val = AN8855_MAX_RX_JUMBO_7K;
+	else if (length <= 8192)
+		val = AN8855_MAX_RX_JUMBO_8K;
+	else if (length <= 9216)
+		val = AN8855_MAX_RX_JUMBO_9K;
+	else if (length <= 12288)
+		val = AN8855_MAX_RX_JUMBO_12K;
+	else if (length <= 15360)
+		val = AN8855_MAX_RX_JUMBO_15K;
+	else
+		val = AN8855_MAX_RX_JUMBO_16K;
+
+	/* Enable JUMBO packet */
+	if (length > 1552)
+		val |= AN8855_MAX_RX_PKT_JUMBO;
+
+	return regmap_update_bits(priv->regmap, AN8855_GMACCR,
+				  AN8855_MAX_RX_JUMBO | AN8855_MAX_RX_PKT_LEN,
+				  val);
+}
+
+static int
+an8855_port_max_mtu(struct dsa_switch *ds, int port)
+{
+	return AN8855_MAX_MTU;
+}
+
+static void
+an8855_get_strings(struct dsa_switch *ds, int port, u32 stringset,
+		   uint8_t *data)
+{
+	int i;
+
+	if (stringset != ETH_SS_STATS)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(an8855_mib); i++)
+		ethtool_puts(&data, an8855_mib[i].name);
+}
+
+static void
+an8855_read_port_stats(struct an8855_priv *priv, int port, u32 offset, u8 size,
+		       uint64_t *data)
+{
+	u32 val, reg = AN8855_PORT_MIB_COUNTER(port) + offset;
+
+	regmap_read(priv->regmap, reg, &val);
+	*data = val;
+
+	if (size == 2) {
+		regmap_read(priv->regmap, reg + 4, &val);
+		*data |= (u64)val << 32;
+	}
+}
+
+static void
+an8855_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data)
+{
+	struct an8855_priv *priv = ds->priv;
+	const struct an8855_mib_desc *mib;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(an8855_mib); i++) {
+		mib = &an8855_mib[i];
+
+		an8855_read_port_stats(priv, port, mib->offset, mib->size,
+				       data + i);
+	}
+}
+
+static int
+an8855_get_sset_count(struct dsa_switch *ds, int port, int sset)
+{
+	if (sset != ETH_SS_STATS)
+		return 0;
+
+	return ARRAY_SIZE(an8855_mib);
+}
+
+static void
+an8855_get_eth_mac_stats(struct dsa_switch *ds, int port,
+			 struct ethtool_eth_mac_stats *mac_stats)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	/* MIB counter doesn't provide a FramesTransmittedOK but instead
+	 * provide stats for Unicast, Broadcast and Multicast frames separately.
+	 * To simulate a global frame counter, read Unicast and addition Multicast
+	 * and Broadcast later
+	 */
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_UNICAST, 1,
+			       &mac_stats->FramesTransmittedOK);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_SINGLE_COLLISION, 1,
+			       &mac_stats->SingleCollisionFrames);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_MULTIPLE_COLLISION, 1,
+			       &mac_stats->MultipleCollisionFrames);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_UNICAST, 1,
+			       &mac_stats->FramesReceivedOK);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_BYTES, 2,
+			       &mac_stats->OctetsTransmittedOK);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_ALIGN_ERR, 1,
+			       &mac_stats->AlignmentErrors);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_DEFERRED, 1,
+			       &mac_stats->FramesWithDeferredXmissions);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_LATE_COLLISION, 1,
+			       &mac_stats->LateCollisions);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_EXCESSIVE_COLLISION, 1,
+			       &mac_stats->FramesAbortedDueToXSColls);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_BYTES, 2,
+			       &mac_stats->OctetsReceivedOK);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_MULTICAST, 1,
+			       &mac_stats->MulticastFramesXmittedOK);
+	mac_stats->FramesTransmittedOK += mac_stats->MulticastFramesXmittedOK;
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_BROADCAST, 1,
+			       &mac_stats->BroadcastFramesXmittedOK);
+	mac_stats->FramesTransmittedOK += mac_stats->BroadcastFramesXmittedOK;
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_MULTICAST, 1,
+			       &mac_stats->MulticastFramesReceivedOK);
+	mac_stats->FramesReceivedOK += mac_stats->MulticastFramesReceivedOK;
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_BROADCAST, 1,
+			       &mac_stats->BroadcastFramesReceivedOK);
+	mac_stats->FramesReceivedOK += mac_stats->BroadcastFramesReceivedOK;
+}
+
+static const struct ethtool_rmon_hist_range an8855_rmon_ranges[] = {
+	{ 0, 64 },
+	{ 65, 127 },
+	{ 128, 255 },
+	{ 256, 511 },
+	{ 512, 1023 },
+	{ 1024, 1518 },
+	{ 1519, AN8855_MAX_MTU },
+	{}
+};
+
+static void an8855_get_rmon_stats(struct dsa_switch *ds, int port,
+				  struct ethtool_rmon_stats *rmon_stats,
+				  const struct ethtool_rmon_hist_range **ranges)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_UNDER_SIZE_ERR, 1,
+			       &rmon_stats->undersize_pkts);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_OVER_SZ_ERR, 1,
+			       &rmon_stats->oversize_pkts);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_FRAG_ERR, 1,
+			       &rmon_stats->fragments);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_JABBER_ERR, 1,
+			       &rmon_stats->jabbers);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_64, 1,
+			       &rmon_stats->hist[0]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_65_TO_127, 1,
+			       &rmon_stats->hist[1]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_128_TO_255, 1,
+			       &rmon_stats->hist[2]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_256_TO_511, 1,
+			       &rmon_stats->hist[3]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_512_TO_1023, 1,
+			       &rmon_stats->hist[4]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_1024_TO_1518, 1,
+			       &rmon_stats->hist[5]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_1519_TO_MAX, 1,
+			       &rmon_stats->hist[6]);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_64, 1,
+			       &rmon_stats->hist_tx[0]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_65_TO_127, 1,
+			       &rmon_stats->hist_tx[1]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_128_TO_255, 1,
+			       &rmon_stats->hist_tx[2]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_256_TO_511, 1,
+			       &rmon_stats->hist_tx[3]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_512_TO_1023, 1,
+			       &rmon_stats->hist_tx[4]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_1024_TO_1518, 1,
+			       &rmon_stats->hist_tx[5]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_1519_TO_MAX, 1,
+			       &rmon_stats->hist_tx[6]);
+
+	*ranges = an8855_rmon_ranges;
+}
+
+static void an8855_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
+				      struct ethtool_eth_ctrl_stats *ctrl_stats)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PAUSE, 1,
+			       &ctrl_stats->MACControlFramesTransmitted);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PAUSE, 1,
+			       &ctrl_stats->MACControlFramesReceived);
+}
+
+static int an8855_port_mirror_add(struct dsa_switch *ds, int port,
+				  struct dsa_mall_mirror_tc_entry *mirror,
+				  bool ingress,
+				  struct netlink_ext_ack *extack)
+{
+	struct an8855_priv *priv = ds->priv;
+	int monitor_port;
+	u32 val;
+	int ret;
+
+	/* Check for existent entry */
+	if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
+		return -EEXIST;
+
+	ret = regmap_read(priv->regmap, AN8855_MIR, &val);
+	if (ret)
+		return ret;
+
+	/* AN8855 supports 4 monitor port, but only use first group */
+	monitor_port = FIELD_GET(AN8855_MIRROR_PORT, val);
+	if (val & AN8855_MIRROR_EN && monitor_port != mirror->to_local_port)
+		return -EEXIST;
+
+	val = AN8855_MIRROR_EN;
+	val |= FIELD_PREP(AN8855_MIRROR_PORT, mirror->to_local_port);
+	ret = regmap_update_bits(priv->regmap, AN8855_MIR,
+				 AN8855_MIRROR_EN | AN8855_MIRROR_PORT,
+				 val);
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(priv->regmap, AN8855_PCR_P(port),
+			      ingress ? AN8855_PORT_RX_MIR : AN8855_PORT_TX_MIR);
+	if (ret)
+		return ret;
+
+	if (ingress)
+		priv->mirror_rx |= BIT(port);
+	else
+		priv->mirror_tx |= BIT(port);
+
+	return 0;
+}
+
+static void an8855_port_mirror_del(struct dsa_switch *ds, int port,
+				   struct dsa_mall_mirror_tc_entry *mirror)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	if (mirror->ingress)
+		priv->mirror_rx &= ~BIT(port);
+	else
+		priv->mirror_tx &= ~BIT(port);
+
+	regmap_clear_bits(priv->regmap, AN8855_PCR_P(port),
+			  mirror->ingress ? AN8855_PORT_RX_MIR :
+					    AN8855_PORT_TX_MIR);
+
+	if (!priv->mirror_rx && !priv->mirror_tx)
+		regmap_clear_bits(priv->regmap, AN8855_MIR, AN8855_MIRROR_EN);
+}
+
+static int an8855_port_set_status(struct an8855_priv *priv, int port,
+				  bool enable)
+{
+	if (enable)
+		return regmap_set_bits(priv->regmap, AN8855_PMCR_P(port),
+				       AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
+	else
+		return regmap_clear_bits(priv->regmap, AN8855_PMCR_P(port),
+					 AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
+}
+
+static int an8855_port_enable(struct dsa_switch *ds, int port,
+			      struct phy_device *phy)
+{
+	return an8855_port_set_status(ds->priv, port, true);
+}
+
+static void an8855_port_disable(struct dsa_switch *ds, int port)
+{
+	an8855_port_set_status(ds->priv, port, false);
+}
+
+static u32 en8855_get_phy_flags(struct dsa_switch *ds, int port)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	/* PHY doesn't need calibration */
+	if (!priv->phy_require_calib)
+		return 0;
+
+	/* Use AN8855_PHY_FLAGS_EN_CALIBRATION to signal
+	 * calibration needed.
+	 */
+	return AN8855_PHY_FLAGS_EN_CALIBRATION;
+}
+
+static enum dsa_tag_protocol
+an8855_get_tag_protocol(struct dsa_switch *ds, int port,
+			enum dsa_tag_protocol mp)
+{
+	return DSA_TAG_PROTO_MTK;
+}
+
+/* Similar to MT7530 also trap link local frame and special frame to CPU */
+static int an8855_trap_special_frames(struct an8855_priv *priv)
+{
+	int ret;
+
+	/* Trap BPDUs to the CPU port(s) and egress them
+	 * VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_BPC,
+				 AN8855_BPDU_BPDU_FR | AN8855_BPDU_EG_TAG |
+				 AN8855_BPDU_PORT_FW,
+				 AN8855_BPDU_BPDU_FR |
+				 FIELD_PREP(AN8855_BPDU_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_BPDU_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap 802.1X PAE frames to the CPU port(s) and egress them
+	 * VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_PAC,
+				 AN8855_PAE_BPDU_FR | AN8855_PAE_EG_TAG |
+				 AN8855_PAE_PORT_FW,
+				 AN8855_PAE_BPDU_FR |
+				 FIELD_PREP(AN8855_PAE_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_PAE_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap frames with :01 MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_RGAC1,
+				 AN8855_R01_BPDU_FR | AN8855_R01_EG_TAG |
+				 AN8855_R01_PORT_FW,
+				 AN8855_R01_BPDU_FR |
+				 FIELD_PREP(AN8855_R01_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_R01_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap frames with :02 MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_RGAC1,
+				 AN8855_R02_BPDU_FR | AN8855_R02_EG_TAG |
+				 AN8855_R02_PORT_FW,
+				 AN8855_R02_BPDU_FR |
+				 FIELD_PREP(AN8855_R02_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_R02_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap frames with :03 MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_RGAC1,
+				 AN8855_R03_BPDU_FR | AN8855_R03_EG_TAG |
+				 AN8855_R03_PORT_FW,
+				 AN8855_R03_BPDU_FR |
+				 FIELD_PREP(AN8855_R03_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_R03_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap frames with :0E MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	return regmap_update_bits(priv->regmap, AN8855_RGAC1,
+				  AN8855_R0E_BPDU_FR | AN8855_R0E_EG_TAG |
+				  AN8855_R0E_PORT_FW,
+				  AN8855_R0E_BPDU_FR |
+				  FIELD_PREP(AN8855_R0E_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				  FIELD_PREP(AN8855_R0E_PORT_FW, AN8855_BPDU_CPU_ONLY));
+}
+
+static int
+an8855_setup_pvid_vlan(struct an8855_priv *priv)
+{
+	u32 val;
+	int ret;
+
+	/* Validate the entry with independent learning, keep the original
+	 * ingress tag attribute.
+	 */
+	val = AN8855_VA0_IVL_MAC | AN8855_VA0_EG_CON |
+	      FIELD_PREP(AN8855_VA0_FID, AN8855_FID_BRIDGED) |
+	      AN8855_VA0_PORT | AN8855_VA0_VLAN_VALID;
+	ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
+	if (ret)
+		return ret;
+
+	return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID,
+			       AN8855_PORT_VID_DEFAULT);
+}
+
+static int an8855_setup(struct dsa_switch *ds)
+{
+	struct an8855_priv *priv = ds->priv;
+	struct dsa_port *dp;
+	int ret;
+
+	/* Enable and reset MIB counters */
+	ret = an8855_mib_init(priv);
+	if (ret)
+		return ret;
+
+	dsa_switch_for_each_user_port(dp, ds) {
+		/* Disable MAC by default on all user ports */
+		ret = an8855_port_set_status(priv, dp->index, false);
+		if (ret)
+			return ret;
+
+		/* Individual user ports get connected to CPU port only */
+		ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(dp->index),
+				   FIELD_PREP(AN8855_PORTMATRIX, BIT(AN8855_CPU_PORT)));
+		if (ret)
+			return ret;
+
+		/* Disable Broadcast Forward on user ports */
+		ret = regmap_clear_bits(priv->regmap, AN8855_BCF, BIT(dp->index));
+		if (ret)
+			return ret;
+
+		/* Disable Unknown Unicast Forward on user ports */
+		ret = regmap_clear_bits(priv->regmap, AN8855_UNUF, BIT(dp->index));
+		if (ret)
+			return ret;
+
+		/* Disable Unknown Multicast Forward on user ports */
+		ret = regmap_clear_bits(priv->regmap, AN8855_UNMF, BIT(dp->index));
+		if (ret)
+			return ret;
+
+		ret = regmap_clear_bits(priv->regmap, AN8855_UNIPMF, BIT(dp->index));
+		if (ret)
+			return ret;
+
+		/* Set default PVID to on all user ports */
+		ret = an8855_port_set_pid(priv, dp->index, AN8855_PORT_VID_DEFAULT);
+		if (ret)
+			return ret;
+	}
+
+	/* Enable Airoha header mode on the cpu port */
+	ret = regmap_write(priv->regmap, AN8855_PVC_P(AN8855_CPU_PORT),
+			   AN8855_PORT_SPEC_REPLACE_MODE | AN8855_PORT_SPEC_TAG);
+	if (ret)
+		return ret;
+
+	/* Unknown multicast frame forwarding to the cpu port */
+	ret = regmap_write(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* Set CPU port number */
+	ret = regmap_update_bits(priv->regmap, AN8855_MFC,
+				 AN8855_CPU_EN | AN8855_CPU_PORT_IDX,
+				 AN8855_CPU_EN |
+				 FIELD_PREP(AN8855_CPU_PORT_IDX, AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* CPU port gets connected to all user ports of
+	 * the switch.
+	 */
+	ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(AN8855_CPU_PORT),
+			   FIELD_PREP(AN8855_PORTMATRIX, dsa_user_ports(ds)));
+	if (ret)
+		return ret;
+
+	/* CPU port is set to fallback mode to let untagged
+	 * frames pass through.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_PCR_P(AN8855_CPU_PORT),
+				 AN8855_PORT_VLAN,
+				 FIELD_PREP(AN8855_PORT_VLAN, AN8855_PORT_FALLBACK_MODE));
+	if (ret)
+		return ret;
+
+	/* Enable Broadcast Forward on CPU port */
+	ret = regmap_set_bits(priv->regmap, AN8855_BCF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* Enable Unknown Unicast Forward on CPU port */
+	ret = regmap_set_bits(priv->regmap, AN8855_UNUF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* Enable Unknown Multicast Forward on CPU port */
+	ret = regmap_set_bits(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(priv->regmap, AN8855_UNIPMF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* Setup Trap special frame to CPU rules */
+	ret = an8855_trap_special_frames(priv);
+	if (ret)
+		return ret;
+
+	dsa_switch_for_each_port(dp, ds) {
+		/* Disable Learning on all ports.
+		 * Learning on CPU is disabled for fdb isolation and handled by
+		 * assisted_learning_on_cpu_port.
+		 */
+		ret = regmap_set_bits(priv->regmap, AN8855_PSC_P(dp->index),
+				      AN8855_SA_DIS);
+		if (ret)
+			return ret;
+
+		/* Enable consistent egress tag (for VLAN unware VLAN-passtrough) */
+		ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(dp->index),
+					 AN8855_PVC_EG_TAG,
+					 FIELD_PREP(AN8855_PVC_EG_TAG, AN8855_VLAN_EG_CONSISTENT));
+		if (ret)
+			return ret;
+	}
+
+	/* Setup VLAN for Default PVID */
+	ret = an8855_setup_pvid_vlan(priv);
+	if (ret)
+		return ret;
+
+	ret = regmap_clear_bits(priv->regmap, AN8855_CKGCR,
+				AN8855_CKG_LNKDN_GLB_STOP | AN8855_CKG_LNKDN_PORT_STOP);
+	if (ret)
+		return ret;
+
+	/* Release global PHY power down */
+	ret = regmap_write(priv->regmap, AN8855_RG_GPHY_AFE_PWD, 0x0);
+	if (ret)
+		return ret;
+
+	ds->configure_vlan_while_not_filtering = true;
+
+	/* Flush the FDB table */
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_FLUSH, NULL);
+	if (ret < 0)
+		return ret;
+
+	/* Set min a max ageing value supported */
+	ds->ageing_time_min = AN8855_L2_AGING_MS_CONSTANT;
+	ds->ageing_time_max = FIELD_MAX(AN8855_AGE_CNT) *
+			      FIELD_MAX(AN8855_AGE_UNIT) *
+			      AN8855_L2_AGING_MS_CONSTANT;
+
+	/* Enable assisted learning for fdb isolation */
+	ds->assisted_learning_on_cpu_port = true;
+
+	return 0;
+}
+
+static struct phylink_pcs *an8855_phylink_mac_select_pcs(struct phylink_config *config,
+							 phy_interface_t interface)
+{
+	struct dsa_port *dp = dsa_phylink_to_port(config);
+	struct an8855_priv *priv = dp->ds->priv;
+
+	switch (interface) {
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_2500BASEX:
+		return &priv->pcs;
+	default:
+		return NULL;
+	}
+}
+
+static void an8855_phylink_mac_config(struct phylink_config *config,
+				      unsigned int mode,
+				      const struct phylink_link_state *state)
+{
+	struct dsa_port *dp = dsa_phylink_to_port(config);
+	struct dsa_switch *ds = dp->ds;
+	struct an8855_priv *priv;
+	int port = dp->index;
+
+	priv = ds->priv;
+
+	/* Nothing to configure for internal ports */
+	if (port != 5)
+		return;
+
+	regmap_update_bits(priv->regmap, AN8855_PMCR_P(port),
+			   AN8855_PMCR_IFG_XMIT | AN8855_PMCR_MAC_MODE |
+			   AN8855_PMCR_BACKOFF_EN | AN8855_PMCR_BACKPR_EN,
+			   FIELD_PREP(AN8855_PMCR_IFG_XMIT, 0x1) |
+			   AN8855_PMCR_MAC_MODE | AN8855_PMCR_BACKOFF_EN |
+			   AN8855_PMCR_BACKPR_EN);
+}
+
+static void an8855_phylink_get_caps(struct dsa_switch *ds, int port,
+				    struct phylink_config *config)
+{
+	switch (port) {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+		__set_bit(PHY_INTERFACE_MODE_GMII,
+			  config->supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
+			  config->supported_interfaces);
+		break;
+	case 5:
+		phy_interface_set_rgmii(config->supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_SGMII,
+			  config->supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
+			  config->supported_interfaces);
+		break;
+	}
+
+	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+				   MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
+}
+
+static void an8855_phylink_mac_link_down(struct phylink_config *config,
+					 unsigned int mode,
+					 phy_interface_t interface)
+{
+	struct dsa_port *dp = dsa_phylink_to_port(config);
+	struct an8855_priv *priv = dp->ds->priv;
+
+	/* With autoneg just disable TX/RX else also force link down */
+	if (phylink_autoneg_inband(mode)) {
+		regmap_clear_bits(priv->regmap, AN8855_PMCR_P(dp->index),
+				  AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
+	} else {
+		regmap_update_bits(priv->regmap, AN8855_PMCR_P(dp->index),
+				   AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN |
+				   AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK,
+				   AN8855_PMCR_FORCE_MODE);
+	}
+}
+
+static void an8855_phylink_mac_link_up(struct phylink_config *config,
+				       struct phy_device *phydev, unsigned int mode,
+				       phy_interface_t interface, int speed,
+				       int duplex, bool tx_pause, bool rx_pause)
+{
+	struct dsa_port *dp = dsa_phylink_to_port(config);
+	struct an8855_priv *priv = dp->ds->priv;
+	int port = dp->index;
+	u32 reg;
+
+	reg = regmap_read(priv->regmap, AN8855_PMCR_P(port), &reg);
+	if (phylink_autoneg_inband(mode)) {
+		reg &= ~AN8855_PMCR_FORCE_MODE;
+	} else {
+		reg |= AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK;
+
+		reg &= ~AN8855_PMCR_FORCE_SPEED;
+		switch (speed) {
+		case SPEED_10:
+			reg |= AN8855_PMCR_FORCE_SPEED_10;
+			break;
+		case SPEED_100:
+			reg |= AN8855_PMCR_FORCE_SPEED_100;
+			break;
+		case SPEED_1000:
+			reg |= AN8855_PMCR_FORCE_SPEED_1000;
+			break;
+		case SPEED_2500:
+			reg |= AN8855_PMCR_FORCE_SPEED_2500;
+			break;
+		case SPEED_5000:
+			dev_err(priv->dev, "Missing support for 5G speed. Aborting...\n");
+			return;
+		}
+
+		reg &= ~AN8855_PMCR_FORCE_FDX;
+		if (duplex == DUPLEX_FULL)
+			reg |= AN8855_PMCR_FORCE_FDX;
+
+		reg &= ~AN8855_PMCR_RX_FC_EN;
+		if (rx_pause || dsa_port_is_cpu(dp))
+			reg |= AN8855_PMCR_RX_FC_EN;
+
+		reg &= ~AN8855_PMCR_TX_FC_EN;
+		if (rx_pause || dsa_port_is_cpu(dp))
+			reg |= AN8855_PMCR_TX_FC_EN;
+
+		/* Disable any EEE options */
+		reg &= ~(AN8855_PMCR_FORCE_EEE5G | AN8855_PMCR_FORCE_EEE2P5G |
+			 AN8855_PMCR_FORCE_EEE1G | AN8855_PMCR_FORCE_EEE100);
+	}
+
+	reg |= AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN;
+
+	regmap_write(priv->regmap, AN8855_PMCR_P(port), reg);
+}
+
+static unsigned int an8855_pcs_inband_caps(struct phylink_pcs *pcs,
+					   phy_interface_t interface)
+{
+	/* SGMII can be configured to use inband with AN result */
+	if (interface == PHY_INTERFACE_MODE_SGMII)
+		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+
+	/* inband is not supported in 2500-baseX and must be disabled */
+	return  LINK_INBAND_DISABLE;
+}
+
+static void an8855_pcs_get_state(struct phylink_pcs *pcs,
+				 struct phylink_link_state *state)
+{
+	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
+	u32 val;
+	int ret;
+
+	ret = regmap_read(priv->regmap, AN8855_PMSR_P(AN8855_CPU_PORT), &val);
+	if (ret < 0) {
+		state->link = false;
+		return;
+	}
+
+	state->link = !!(val & AN8855_PMSR_LNK);
+	state->an_complete = state->link;
+	state->duplex = (val & AN8855_PMSR_DPX) ? DUPLEX_FULL :
+						  DUPLEX_HALF;
+
+	switch (val & AN8855_PMSR_SPEED) {
+	case AN8855_PMSR_SPEED_10:
+		state->speed = SPEED_10;
+		break;
+	case AN8855_PMSR_SPEED_100:
+		state->speed = SPEED_100;
+		break;
+	case AN8855_PMSR_SPEED_1000:
+		state->speed = SPEED_1000;
+		break;
+	case AN8855_PMSR_SPEED_2500:
+		state->speed = SPEED_2500;
+		break;
+	case AN8855_PMSR_SPEED_5000:
+		dev_err(priv->dev, "Missing support for 5G speed. Setting Unknown.\n");
+		fallthrough;
+	default:
+		state->speed = SPEED_UNKNOWN;
+		break;
+	}
+
+	if (val & AN8855_PMSR_RX_FC)
+		state->pause |= MLO_PAUSE_RX;
+	if (val & AN8855_PMSR_TX_FC)
+		state->pause |= MLO_PAUSE_TX;
+}
+
+static int an8855_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+			     phy_interface_t interface,
+			     const unsigned long *advertising,
+			     bool permit_pause_to_mac)
+{
+	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
+	u32 val;
+	int ret;
+
+	/*                   !!! WELCOME TO HELL !!!                   */
+
+	/* TX FIR - improve TX EYE */
+	ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_10,
+				 AN8855_RG_DA_QP_TX_FIR_C2_SEL |
+				 AN8855_RG_DA_QP_TX_FIR_C2_FORCE |
+				 AN8855_RG_DA_QP_TX_FIR_C1_SEL |
+				 AN8855_RG_DA_QP_TX_FIR_C1_FORCE,
+				 AN8855_RG_DA_QP_TX_FIR_C2_SEL |
+				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C2_FORCE, 0x4) |
+				 AN8855_RG_DA_QP_TX_FIR_C1_SEL |
+				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C1_FORCE, 0x0));
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x0;
+	else
+		val = 0xd;
+	ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_11,
+				 AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
+				 AN8855_RG_DA_QP_TX_FIR_C0B_FORCE,
+				 AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
+				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C0B_FORCE, val));
+	if (ret)
+		return ret;
+
+	/* RX CDR - improve RX Jitter Tolerance */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x5;
+	else
+		val = 0x6;
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_BOT_LIM,
+				 AN8855_RG_QP_CDR_LPF_KP_GAIN |
+				 AN8855_RG_QP_CDR_LPF_KI_GAIN,
+				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_KP_GAIN, val) |
+				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_KI_GAIN, val));
+	if (ret)
+		return ret;
+
+	/* PLL */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x1;
+	else
+		val = 0x0;
+	ret = regmap_update_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_1,
+				 AN8855_RG_TPHY_SPEED,
+				 FIELD_PREP(AN8855_RG_TPHY_SPEED, val));
+	if (ret)
+		return ret;
+
+	/* PLL - LPF */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
+				 AN8855_RG_DA_QP_PLL_FBKSEL_INTF |
+				 AN8855_RG_DA_QP_PLL_BR_INTF |
+				 AN8855_RG_DA_QP_PLL_BPD_INTF |
+				 AN8855_RG_DA_QP_PLL_BPA_INTF |
+				 AN8855_RG_DA_QP_PLL_BC_INTF,
+				 AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_FBKSEL_INTF, 0x0) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BR_INTF, 0x3) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BPD_INTF, 0x0) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BPA_INTF, 0x5) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BC_INTF, 0x1));
+	if (ret)
+		return ret;
+
+	/* PLL - ICO */
+	ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_4,
+			      AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF);
+	if (ret)
+		return ret;
+	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF);
+	if (ret)
+		return ret;
+
+	/* PLL - CHP */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x6;
+	else
+		val = 0x4;
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_IR_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_IR_INTF, val));
+	if (ret)
+		return ret;
+
+	/* PLL - PFD */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF |
+				 AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF |
+				 AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF, 0x1) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF, 0x1));
+	if (ret)
+		return ret;
+
+	/* PLL - POSTDIV */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF |
+				 AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF |
+				 AN8855_RG_DA_QP_PLL_PCK_SEL_INTF,
+				 AN8855_RG_DA_QP_PLL_PCK_SEL_INTF);
+	if (ret)
+		return ret;
+
+	/* PLL - SDM */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_SDM_HREN_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SDM_HREN_INTF, 0x0));
+	if (ret)
+		return ret;
+	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				AN8855_RG_DA_QP_PLL_SDM_IFM_INTF);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_SS_LCPLL_PWCTL_SETTING_2,
+				 AN8855_RG_NCPO_ANA_MSB,
+				 FIELD_PREP(AN8855_RG_NCPO_ANA_MSB, 0x1));
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x7a000000;
+	else
+		val = 0x48000000;
+	ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_2,
+			   FIELD_PREP(AN8855_RG_LCPLL_NCPO_VALUE, val));
+	if (ret)
+		return ret;
+	ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_PCW_1,
+			   FIELD_PREP(AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON, val));
+	if (ret)
+		return ret;
+
+	ret = regmap_clear_bits(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_5,
+				AN8855_RG_LCPLL_NCPO_CHG);
+	if (ret)
+		return ret;
+	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
+				AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF);
+	if (ret)
+		return ret;
+
+	/* PLL - SS */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
+				 AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF, 0x0));
+	if (ret)
+		return ret;
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_4,
+				 AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF, 0x0));
+	if (ret)
+		return ret;
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
+				 AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF, 0x0));
+	if (ret)
+		return ret;
+
+	/* PLL - TDC */
+	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
+				AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF);
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
+			      AN8855_RG_QP_PLL_SSC_TRI_EN);
+	if (ret)
+		return ret;
+	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
+			      AN8855_RG_QP_PLL_SSC_PHASE_INI);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_RX_DAC_EN,
+				 AN8855_RG_QP_SIGDET_HF,
+				 FIELD_PREP(AN8855_RG_QP_SIGDET_HF, 0x2));
+	if (ret)
+		return ret;
+
+	/* TCL Disable (only for Co-SIM) */
+	ret = regmap_clear_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_0,
+				AN8855_RG_QP_EQ_RX500M_CK_SEL);
+	if (ret)
+		return ret;
+
+	/* TX Init */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x4;
+	else
+		val = 0x0;
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_TX_MODE,
+				 AN8855_RG_QP_TX_RESERVE |
+				 AN8855_RG_QP_TX_MODE_16B_EN,
+				 FIELD_PREP(AN8855_RG_QP_TX_RESERVE, val));
+	if (ret)
+		return ret;
+
+	/* RX Control/Init */
+	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_RXAFE_RESERVE,
+			      AN8855_RG_QP_CDR_PD_10B_EN);
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x1;
+	else
+		val = 0x2;
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_MJV_LIM,
+				 AN8855_RG_QP_CDR_LPF_RATIO,
+				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_RATIO, val));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_SETVALUE,
+				 AN8855_RG_QP_CDR_PR_BUF_IN_SR |
+				 AN8855_RG_QP_CDR_PR_BETA_SEL,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_BUF_IN_SR, 0x6) |
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_BETA_SEL, 0x1));
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0xf;
+	else
+		val = 0xc;
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
+				 AN8855_RG_QP_CDR_PR_DAC_BAND,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_DAC_BAND, val));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
+				 AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE |
+				 AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK, 0x19));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF,
+				 AN8855_RG_QP_CDR_PHYCK_SEL |
+				 AN8855_RG_QP_CDR_PHYCK_RSTB |
+				 AN8855_RG_QP_CDR_PHYCK_DIV,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_SEL, 0x2) |
+				 FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_DIV, 0x21));
+	if (ret)
+		return ret;
+
+	ret = regmap_clear_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
+				AN8855_RG_QP_CDR_PR_XFICK_EN);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
+				 AN8855_RG_QP_CDR_PR_KBAND_DIV,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV, 0x4));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_26,
+				 AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
+				 AN8855_RG_LINK_NE_EN |
+				 AN8855_RG_LINK_ERRO_EN,
+				 AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
+				 AN8855_RG_LINK_ERRO_EN);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_DLY_0,
+				 AN8855_RG_QP_RX_SAOSC_EN_H_DLY |
+				 AN8855_RG_QP_RX_PI_CAL_EN_H_DLY,
+				 FIELD_PREP(AN8855_RG_QP_RX_SAOSC_EN_H_DLY, 0x3f) |
+				 FIELD_PREP(AN8855_RG_QP_RX_PI_CAL_EN_H_DLY, 0x6f));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_42,
+				 AN8855_RG_QP_EQ_EN_DLY,
+				 FIELD_PREP(AN8855_RG_QP_EQ_EN_DLY, 0x150));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_2,
+				 AN8855_RG_QP_RX_EQ_EN_H_DLY,
+				 FIELD_PREP(AN8855_RG_QP_RX_EQ_EN_H_DLY, 0x150));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_9,
+				 AN8855_RG_QP_EQ_LEQOSC_DLYCNT,
+				 FIELD_PREP(AN8855_RG_QP_EQ_LEQOSC_DLYCNT, 0x1));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_8,
+				 AN8855_RG_DA_QP_SAOSC_DONE_TIME |
+				 AN8855_RG_DA_QP_LEQOS_EN_TIME,
+				 FIELD_PREP(AN8855_RG_DA_QP_SAOSC_DONE_TIME, 0x200) |
+				 FIELD_PREP(AN8855_RG_DA_QP_LEQOS_EN_TIME, 0xfff));
+	if (ret)
+		return ret;
+
+	/* Frequency meter */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x10;
+	else
+		val = 0x28;
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_5,
+				 AN8855_RG_FREDET_CHK_CYCLE,
+				 FIELD_PREP(AN8855_RG_FREDET_CHK_CYCLE, val));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_6,
+				 AN8855_RG_FREDET_GOLDEN_CYCLE,
+				 FIELD_PREP(AN8855_RG_FREDET_GOLDEN_CYCLE, 0x64));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_7,
+				 AN8855_RG_FREDET_TOLERATE_CYCLE,
+				 FIELD_PREP(AN8855_RG_FREDET_TOLERATE_CYCLE, 0x2710));
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_0,
+			      AN8855_RG_PHYA_AUTO_INIT);
+	if (ret)
+		return ret;
+
+	/* PCS Init */
+	if (interface == PHY_INTERFACE_MODE_SGMII &&
+	    neg_mode == PHYLINK_PCS_NEG_INBAND_DISABLED) {
+		ret = regmap_clear_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_0,
+					AN8855_RG_SGMII_MODE | AN8855_RG_SGMII_AN_EN);
+		if (ret)
+			return ret;
+	}
+
+	ret = regmap_clear_bits(priv->regmap, AN8855_RG_HSGMII_PCS_CTROL_1,
+				AN8855_RG_TBI_10B_MODE);
+	if (ret)
+		return ret;
+
+	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+		/* Set AN Ability - Interrupt */
+		ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN_FORCE_CL37,
+				      AN8855_RG_FORCE_AN_DONE);
+		if (ret)
+			return ret;
+
+		ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN_13,
+					 AN8855_SGMII_REMOTE_FAULT_DIS |
+					 AN8855_SGMII_IF_MODE,
+					 AN8855_SGMII_REMOTE_FAULT_DIS |
+					 FIELD_PREP(AN8855_SGMII_IF_MODE, 0xb));
+		if (ret)
+			return ret;
+	}
+
+	/* Rate Adaption - GMII path config. */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX) {
+		ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
+					AN8855_RG_P0_DIS_MII_MODE);
+		if (ret)
+			return ret;
+	} else {
+		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+			ret = regmap_set_bits(priv->regmap, AN8855_MII_RA_AN_ENABLE,
+					      AN8855_RG_P0_RA_AN_EN);
+			if (ret)
+				return ret;
+		} else {
+			ret = regmap_update_bits(priv->regmap, AN8855_RG_AN_SGMII_MODE_FORCE,
+						 AN8855_RG_FORCE_CUR_SGMII_MODE |
+						 AN8855_RG_FORCE_CUR_SGMII_SEL,
+						 AN8855_RG_FORCE_CUR_SGMII_SEL);
+			if (ret)
+				return ret;
+
+			ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
+						AN8855_RG_P0_MII_RA_RX_EN |
+						AN8855_RG_P0_MII_RA_TX_EN |
+						AN8855_RG_P0_MII_RA_RX_MODE |
+						AN8855_RG_P0_MII_RA_TX_MODE);
+			if (ret)
+				return ret;
+		}
+
+		ret = regmap_set_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
+				      AN8855_RG_P0_MII_MODE);
+		if (ret)
+			return ret;
+	}
+
+	ret = regmap_set_bits(priv->regmap, AN8855_RG_RATE_ADAPT_CTRL_0,
+			      AN8855_RG_RATE_ADAPT_RX_BYPASS |
+			      AN8855_RG_RATE_ADAPT_TX_BYPASS |
+			      AN8855_RG_RATE_ADAPT_RX_EN |
+			      AN8855_RG_RATE_ADAPT_TX_EN);
+	if (ret)
+		return ret;
+
+	/* Disable AN if not in autoneg */
+	ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN0, BMCR_ANENABLE,
+				 neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE :
+									      0);
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_SGMII) {
+		/* Follow SDK init flow with restarting AN after AN enable */
+		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+			ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN0,
+					      BMCR_ANRESTART);
+			if (ret)
+				return ret;
+		} else {
+			ret = regmap_set_bits(priv->regmap, AN8855_PHY_RX_FORCE_CTRL_0,
+					      AN8855_RG_FORCE_TXC_SEL);
+			if (ret)
+				return ret;
+		}
+	}
+
+	/* Force Speed with fixed-link or 2500base-x as doesn't support aneg */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX ||
+	    neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
+		if (interface == PHY_INTERFACE_MODE_2500BASEX)
+			val = AN8855_RG_LINK_MODE_P0_SPEED_2500;
+		else
+			val = AN8855_RG_LINK_MODE_P0_SPEED_1000;
+		ret = regmap_update_bits(priv->regmap, AN8855_SGMII_STS_CTRL_0,
+					 AN8855_RG_LINK_MODE_P0 |
+					 AN8855_RG_FORCE_SPD_MODE_P0,
+					 val | AN8855_RG_FORCE_SPD_MODE_P0);
+		if (ret)
+			return ret;
+	}
+
+	/* bypass flow control to MAC */
+	ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_0,
+			   AN8855_RG_DPX_STS_P3 | AN8855_RG_DPX_STS_P2 |
+			   AN8855_RG_DPX_STS_P1 | AN8855_RG_TXFC_STS_P0 |
+			   AN8855_RG_RXFC_STS_P0 | AN8855_RG_DPX_STS_P0);
+	if (ret)
+		return ret;
+	ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_2,
+			   AN8855_RG_RXFC_AN_BYPASS_P3 |
+			   AN8855_RG_RXFC_AN_BYPASS_P2 |
+			   AN8855_RG_RXFC_AN_BYPASS_P1 |
+			   AN8855_RG_TXFC_AN_BYPASS_P3 |
+			   AN8855_RG_TXFC_AN_BYPASS_P2 |
+			   AN8855_RG_TXFC_AN_BYPASS_P1 |
+			   AN8855_RG_DPX_AN_BYPASS_P3 |
+			   AN8855_RG_DPX_AN_BYPASS_P2 |
+			   AN8855_RG_DPX_AN_BYPASS_P1 |
+			   AN8855_RG_DPX_AN_BYPASS_P0);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void an8855_pcs_an_restart(struct phylink_pcs *pcs)
+{
+	return;
+}
+
+static const struct phylink_pcs_ops an8855_pcs_ops = {
+	.pcs_inband_caps = an8855_pcs_inband_caps,
+	.pcs_get_state = an8855_pcs_get_state,
+	.pcs_config = an8855_pcs_config,
+	.pcs_an_restart = an8855_pcs_an_restart,
+};
+
+static const struct phylink_mac_ops an8855_phylink_mac_ops = {
+	.mac_select_pcs	= an8855_phylink_mac_select_pcs,
+	.mac_config	= an8855_phylink_mac_config,
+	.mac_link_down	= an8855_phylink_mac_link_down,
+	.mac_link_up	= an8855_phylink_mac_link_up,
+};
+
+static const struct dsa_switch_ops an8855_switch_ops = {
+	.get_tag_protocol = an8855_get_tag_protocol,
+	.setup = an8855_setup,
+	.get_phy_flags = en8855_get_phy_flags,
+	.phylink_get_caps = an8855_phylink_get_caps,
+	.get_strings = an8855_get_strings,
+	.get_ethtool_stats = an8855_get_ethtool_stats,
+	.get_sset_count = an8855_get_sset_count,
+	.get_eth_mac_stats = an8855_get_eth_mac_stats,
+	.get_eth_ctrl_stats = an8855_get_eth_ctrl_stats,
+	.get_rmon_stats = an8855_get_rmon_stats,
+	.port_enable = an8855_port_enable,
+	.port_disable = an8855_port_disable,
+	.set_ageing_time = an8855_set_ageing_time,
+	.port_bridge_join = an8855_port_bridge_join,
+	.port_bridge_leave = an8855_port_bridge_leave,
+	.port_fast_age = an8855_port_fast_age,
+	.port_stp_state_set = an8855_port_stp_state_set,
+	.port_pre_bridge_flags = an8855_port_pre_bridge_flags,
+	.port_bridge_flags = an8855_port_bridge_flags,
+	.port_vlan_filtering = an8855_port_vlan_filtering,
+	.port_vlan_add = an8855_port_vlan_add,
+	.port_vlan_del = an8855_port_vlan_del,
+	.port_fdb_add = an8855_port_fdb_add,
+	.port_fdb_del = an8855_port_fdb_del,
+	.port_fdb_dump = an8855_port_fdb_dump,
+	.port_mdb_add = an8855_port_mdb_add,
+	.port_mdb_del = an8855_port_mdb_del,
+	.port_change_mtu = an8855_port_change_mtu,
+	.port_max_mtu = an8855_port_max_mtu,
+	.port_mirror_add = an8855_port_mirror_add,
+	.port_mirror_del = an8855_port_mirror_del,
+};
+
+static int an8855_read_switch_id(struct an8855_priv *priv)
+{
+	u32 id;
+	int ret;
+
+	ret = regmap_read(priv->regmap, AN8855_CREV, &id);
+	if (ret)
+		return ret;
+
+	if (id != AN8855_ID) {
+		dev_err(priv->dev,
+			"Switch id detected %x but expected %x",
+			id, AN8855_ID);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int an8855_switch_probe(struct platform_device *pdev)
+{
+	struct an8855_priv *priv;
+	u32 val;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
+	priv->phy_require_calib = of_property_read_bool(priv->dev->of_node,
+							"airoha,ext-surge");
+
+	priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
+						   GPIOD_OUT_LOW);
+	if (IS_ERR(priv->reset_gpio))
+		return PTR_ERR(priv->reset_gpio);
+
+	/* Get regmap from MFD */
+	priv->regmap = dev_get_regmap(priv->dev->parent, NULL);
+
+	if (priv->reset_gpio) {
+		usleep_range(100000, 150000);
+		gpiod_set_value_cansleep(priv->reset_gpio, 0);
+		usleep_range(100000, 150000);
+		gpiod_set_value_cansleep(priv->reset_gpio, 1);
+
+		/* Poll HWTRAP reg to wait for Switch to fully Init */
+		ret = regmap_read_poll_timeout(priv->regmap, AN8855_HWTRAP, val,
+					       val, 20, 200000);
+		if (ret)
+			return ret;
+	}
+
+	ret = an8855_read_switch_id(priv);
+	if (ret)
+		return ret;
+
+	priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
+	if (!priv->ds)
+		return -ENOMEM;
+
+	priv->ds->dev = priv->dev;
+	priv->ds->num_ports = AN8855_NUM_PORTS;
+	priv->ds->priv = priv;
+	priv->ds->ops = &an8855_switch_ops;
+	devm_mutex_init(priv->dev, &priv->reg_mutex);
+	priv->ds->phylink_mac_ops = &an8855_phylink_mac_ops;
+
+	priv->pcs.ops = &an8855_pcs_ops;
+	priv->pcs.neg_mode = true;
+	priv->pcs.poll = true;
+
+	dev_set_drvdata(priv->dev, priv);
+
+	return dsa_register_switch(priv->ds);
+}
+
+static void an8855_switch_remove(struct platform_device *pdev)
+{
+	struct an8855_priv *priv = dev_get_drvdata(&pdev->dev);
+
+	if (!priv)
+		return;
+
+	dsa_unregister_switch(priv->ds);
+}
+
+static const struct of_device_id an8855_switch_of_match[] = {
+	{ .compatible = "airoha,an8855-switch" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver an8855_switch_driver = {
+	.probe = an8855_switch_probe,
+	.remove = an8855_switch_remove,
+	.driver = {
+		.name = "an8855-switch",
+		.of_match_table = an8855_switch_of_match,
+	},
+};
+module_platform_driver(an8855_switch_driver);
+
+MODULE_AUTHOR("Min Yao <min.yao at airoha.com>");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_DESCRIPTION("Driver for Airoha AN8855 Switch");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/an8855.h b/drivers/net/dsa/an8855.h
new file mode 100644
index 000000000000..2462b9d33752
--- /dev/null
+++ b/drivers/net/dsa/an8855.h
@@ -0,0 +1,783 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 Min Yao <min.yao at airoha.com>
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth at gmail.com>
+ */
+
+#ifndef __AN8855_H
+#define __AN8855_H
+
+#include <linux/bitfield.h>
+
+#define AN8855_NUM_PORTS		6
+#define AN8855_CPU_PORT			5
+#define AN8855_NUM_FDB_RECORDS		2048
+#define AN8855_GPHY_SMI_ADDR_DEFAULT	1
+#define AN8855_PORT_VID_DEFAULT		0
+
+#define MTK_TAG_LEN			4
+#define AN8855_MAX_MTU			(15360 - ETH_HLEN - ETH_FCS_LEN - MTK_TAG_LEN)
+
+#define AN8855_L2_AGING_MS_CONSTANT	1024
+
+#define AN8855_PHY_FLAGS_EN_CALIBRATION	BIT(0)
+
+/*	AN8855_SCU			0x10000000 */
+#define AN8855_RG_GPIO_LED_MODE		0x10000054
+#define AN8855_RG_GPIO_LED_SEL(i)	(0x10000000 + (0x0058 + ((i) * 4)))
+#define AN8855_RG_INTB_MODE		0x10000080
+#define AN8855_RG_RGMII_TXCK_C		0x100001d0
+
+#define AN8855_PKG_SEL			0x10000094
+#define   AN8855_PAG_SEL_AN8855H	0x2
+
+/* Register for hw trap status */
+#define AN8855_HWTRAP			0x1000009c
+
+#define AN8855_RG_GPIO_L_INV		0x10000010
+#define AN8855_RG_GPIO_CTRL		0x1000a300
+#define AN8855_RG_GPIO_DATA		0x1000a304
+#define AN8855_RG_GPIO_OE		0x1000a314
+
+#define AN8855_CREV			0x10005000
+#define   AN8855_ID			0x8855
+
+/* Register for system reset */
+#define AN8855_RST_CTRL			0x100050c0
+#define   AN8855_SYS_CTRL_SYS_RST	BIT(31)
+
+#define AN8855_INT_MASK			0x100050f0
+#define   AN8855_INT_SYS		BIT(15)
+
+#define AN8855_RG_CLK_CPU_ICG		0x10005034
+#define   AN8855_MCU_ENABLE		BIT(3)
+
+#define AN8855_RG_TIMER_CTL		0x1000a100
+#define   AN8855_WDOG_ENABLE		BIT(25)
+
+#define AN8855_RG_GDMP_RAM		0x10010000
+
+/* Registers to mac forward control for unknown frames */
+#define AN8855_MFC			0x10200010
+#define   AN8855_CPU_EN			BIT(15)
+#define   AN8855_CPU_PORT_IDX		GENMASK(12, 8)
+
+#define AN8855_PAC			0x10200024
+#define   AN8855_TAG_PAE_MANG_FR	BIT(30)
+#define   AN8855_TAG_PAE_BPDU_FR	BIT(28)
+#define   AN8855_TAG_PAE_EG_TAG		GENMASK(27, 25)
+#define   AN8855_TAG_PAE_LKY_VLAN	BIT(24)
+#define   AN8855_TAG_PAE_PRI_HIGH	BIT(23)
+#define   AN8855_TAG_PAE_MIR		GENMASK(20, 19)
+#define   AN8855_TAG_PAE_PORT_FW	GENMASK(18, 16)
+#define   AN8855_PAE_MANG_FR		BIT(14)
+#define   AN8855_PAE_BPDU_FR		BIT(12)
+#define   AN8855_PAE_EG_TAG		GENMASK(11, 9)
+#define   AN8855_PAE_LKY_VLAN		BIT(8)
+#define   AN8855_PAE_PRI_HIGH		BIT(7)
+#define   AN8855_PAE_MIR		GENMASK(4, 3)
+#define   AN8855_PAE_PORT_FW		GENMASK(2, 0)
+
+#define AN8855_RGAC1			0x10200028
+#define   AN8855_R02_MANG_FR		BIT(30)
+#define   AN8855_R02_BPDU_FR		BIT(28)
+#define   AN8855_R02_EG_TAG		GENMASK(27, 25)
+#define   AN8855_R02_LKY_VLAN		BIT(24)
+#define   AN8855_R02_PRI_HIGH		BIT(23)
+#define   AN8855_R02_MIR		GENMASK(20, 19)
+#define   AN8855_R02_PORT_FW		GENMASK(18, 16)
+#define   AN8855_R01_MANG_FR		BIT(14)
+#define   AN8855_R01_BPDU_FR		BIT(12)
+#define   AN8855_R01_EG_TAG		GENMASK(11, 9)
+#define   AN8855_R01_LKY_VLAN		BIT(8)
+#define   AN8855_R01_PRI_HIGH		BIT(7)
+#define   AN8855_R01_MIR		GENMASK(4, 3)
+#define   AN8855_R01_PORT_FW		GENMASK(2, 0)
+
+#define AN8855_RGAC2			0x1020002c
+#define   AN8855_R0E_MANG_FR		BIT(30)
+#define   AN8855_R0E_BPDU_FR		BIT(28)
+#define   AN8855_R0E_EG_TAG		GENMASK(27, 25)
+#define   AN8855_R0E_LKY_VLAN		BIT(24)
+#define   AN8855_R0E_PRI_HIGH		BIT(23)
+#define   AN8855_R0E_MIR		GENMASK(20, 19)
+#define   AN8855_R0E_PORT_FW		GENMASK(18, 16)
+#define   AN8855_R03_MANG_FR		BIT(14)
+#define   AN8855_R03_BPDU_FR		BIT(12)
+#define   AN8855_R03_EG_TAG		GENMASK(11, 9)
+#define   AN8855_R03_LKY_VLAN		BIT(8)
+#define   AN8855_R03_PRI_HIGH		BIT(7)
+#define   AN8855_R03_MIR		GENMASK(4, 3)
+#define   AN8855_R03_PORT_FW		GENMASK(2, 0)
+
+#define AN8855_AAC			0x102000a0
+#define   AN8855_MAC_AUTO_FLUSH		BIT(28)
+/* Control Address Table Age time.
+ * (AN8855_AGE_CNT + 1) * ( AN8855_AGE_UNIT + 1 ) * AN8855_L2_AGING_MS_CONSTANT
+ */
+#define   AN8855_AGE_CNT		GENMASK(20, 12)
+/* Value in seconds. Value is always incremented of 1 */
+#define   AN8855_AGE_UNIT		GENMASK(10, 0)
+
+/* Registers for ARL Unknown Unicast Forward control */
+#define AN8855_UNUF			0x102000b4
+
+/* Registers for ARL Unknown Multicast Forward control */
+#define AN8855_UNMF			0x102000b8
+
+/* Registers for ARL Broadcast forward control */
+#define AN8855_BCF			0x102000bc
+
+/* Registers for port address age disable */
+#define AN8855_AGDIS			0x102000c0
+
+/* Registers for mirror port control */
+#define AN8855_MIR			0x102000cc
+#define   AN8855_MIRROR_EN		BIT(7)
+#define   AN8855_MIRROR_PORT		GENMASK(4, 0)
+
+/* Registers for BPDU and PAE frame control*/
+#define AN8855_BPC			0x102000d0
+#define   AN8855_BPDU_MANG_FR		BIT(14)
+#define   AN8855_BPDU_BPDU_FR		BIT(12)
+#define   AN8855_BPDU_EG_TAG		GENMASK(11, 9)
+#define   AN8855_BPDU_LKY_VLAN		BIT(8)
+#define   AN8855_BPDU_PRI_HIGH		BIT(7)
+#define   AN8855_BPDU_MIR		GENMASK(4, 3)
+#define   AN8855_BPDU_PORT_FW		GENMASK(2, 0)
+
+/* Registers for IP Unknown Multicast Forward control */
+#define AN8855_UNIPMF			0x102000dc
+
+enum an8855_bpdu_port_fw {
+	AN8855_BPDU_FOLLOW_MFC = 0,
+	AN8855_BPDU_CPU_EXCLUDE = 4,
+	AN8855_BPDU_CPU_INCLUDE = 5,
+	AN8855_BPDU_CPU_ONLY = 6,
+	AN8855_BPDU_DROP = 7,
+};
+
+/* Register for address table control */
+#define AN8855_ATC			0x10200300
+#define   AN8855_ATC_BUSY		BIT(31)
+#define   AN8855_ATC_HASH		GENMASK(24, 16)
+#define   AN8855_ATC_HIT		GENMASK(15, 12)
+#define   AN8855_ATC_MAT_MASK		GENMASK(11, 7)
+#define   AN8855_ATC_MAT(x)		FIELD_PREP(AN8855_ATC_MAT_MASK, x)
+#define   AN8855_ATC_SAT		GENMASK(5, 4)
+#define   AN8855_ATC_CMD		GENMASK(2, 0)
+
+enum an8855_fdb_mat_cmds {
+	AND8855_FDB_MAT_ALL = 0,
+	AND8855_FDB_MAT_MAC, /* All MAC address */
+	AND8855_FDB_MAT_DYNAMIC_MAC, /* All Dynamic MAC address */
+	AND8855_FDB_MAT_STATIC_MAC, /* All Static Mac Address */
+	AND8855_FDB_MAT_DIP, /* All DIP/GA address */
+	AND8855_FDB_MAT_DIP_IPV4, /* All DIP/GA IPv4 address */
+	AND8855_FDB_MAT_DIP_IPV6, /* All DIP/GA IPv6 address */
+	AND8855_FDB_MAT_DIP_SIP, /* All DIP_SIP address */
+	AND8855_FDB_MAT_DIP_SIP_IPV4, /* All DIP_SIP IPv4 address */
+	AND8855_FDB_MAT_DIP_SIP_IPV6, /* All DIP_SIP IPv6 address */
+	AND8855_FDB_MAT_MAC_CVID, /* All MAC address with CVID */
+	AND8855_FDB_MAT_MAC_FID, /* All MAC address with Filter ID */
+	AND8855_FDB_MAT_MAC_PORT, /* All MAC address with port */
+	AND8855_FDB_MAT_DIP_SIP_DIP_IPV4, /* All DIP_SIP address with DIP_IPV4 */
+	AND8855_FDB_MAT_DIP_SIP_SIP_IPV4, /* All DIP_SIP address with SIP_IPV4 */
+	AND8855_FDB_MAT_DIP_SIP_DIP_IPV6, /* All DIP_SIP address with DIP_IPV6 */
+	AND8855_FDB_MAT_DIP_SIP_SIP_IPV6, /* All DIP_SIP address with SIP_IPV6 */
+	/* All MAC address with MAC type (dynamic or static) with CVID */
+	AND8855_FDB_MAT_MAC_TYPE_CVID,
+	/* All MAC address with MAC type (dynamic or static) with Filter ID */
+	AND8855_FDB_MAT_MAC_TYPE_FID,
+	/* All MAC address with MAC type (dynamic or static) with port */
+	AND8855_FDB_MAT_MAC_TYPE_PORT,
+};
+
+enum an8855_fdb_cmds {
+	AN8855_FDB_READ = 0,
+	AN8855_FDB_WRITE = 1,
+	AN8855_FDB_FLUSH = 2,
+	AN8855_FDB_START = 4,
+	AN8855_FDB_NEXT = 5,
+};
+
+/* Registers for address table access */
+#define AN8855_ATA1			0x10200304
+#define   AN8855_ATA1_MAC0		GENMASK(31, 24)
+#define   AN8855_ATA1_MAC1		GENMASK(23, 16)
+#define   AN8855_ATA1_MAC2		GENMASK(15, 8)
+#define   AN8855_ATA1_MAC3		GENMASK(7, 0)
+#define AN8855_ATA2			0x10200308
+#define   AN8855_ATA2_MAC4		GENMASK(31, 24)
+#define   AN8855_ATA2_MAC5		GENMASK(23, 16)
+#define   AN8855_ATA2_UNAUTH		BIT(10)
+#define   AN8855_ATA2_TYPE		BIT(9) /* 1: dynamic, 0: static */
+#define   AN8855_ATA2_AGE		GENMASK(8, 0)
+
+/* Register for address table write data */
+#define AN8855_ATWD			0x10200324
+#define   AN8855_ATWD_FID		GENMASK(31, 28)
+#define   AN8855_ATWD_VID		GENMASK(27, 16)
+#define   AN8855_ATWD_IVL		BIT(15)
+#define   AN8855_ATWD_EG_TAG		GENMASK(14, 12)
+#define   AN8855_ATWD_SA_MIR		GENMASK(9, 8)
+#define   AN8855_ATWD_SA_FWD		GENMASK(7, 5)
+#define   AN8855_ATWD_UPRI		GENMASK(4, 2)
+#define   AN8855_ATWD_LEAKY		BIT(1)
+#define   AN8855_ATWD_VLD		BIT(0) /* vid LOAD */
+#define AN8855_ATWD2			0x10200328
+#define   AN8855_ATWD2_PORT		GENMASK(7, 0)
+
+/* Registers for table search read address */
+#define AN8855_ATRDS			0x10200330
+#define   AN8855_ATRD_SEL		GENMASK(1, 0)
+#define AN8855_ATRD0			0x10200334
+#define   AN8855_ATRD0_FID		GENMASK(28, 25)
+#define   AN8855_ATRD0_VID		GENMASK(21, 10)
+#define   AN8855_ATRD0_IVL		BIT(9)
+#define   AN8855_ATRD0_TYPE		GENMASK(4, 3)
+#define   AN8855_ATRD0_ARP		GENMASK(2, 1)
+#define   AN8855_ATRD0_LIVE		BIT(0)
+#define AN8855_ATRD1			0x10200338
+#define   AN8855_ATRD1_MAC4		GENMASK(31, 24)
+#define   AN8855_ATRD1_MAC5		GENMASK(23, 16)
+#define   AN8855_ATRD1_AGING		GENMASK(11, 3)
+#define AN8855_ATRD2			0x1020033c
+#define   AN8855_ATRD2_MAC0		GENMASK(31, 24)
+#define   AN8855_ATRD2_MAC1		GENMASK(23, 16)
+#define   AN8855_ATRD2_MAC2		GENMASK(15, 8)
+#define   AN8855_ATRD2_MAC3		GENMASK(7, 0)
+#define AN8855_ATRD3			0x10200340
+#define   AN8855_ATRD3_PORTMASK		GENMASK(7, 0)
+
+enum an8855_fdb_type {
+	AN8855_MAC_TB_TY_MAC = 0,
+	AN8855_MAC_TB_TY_DIP = 1,
+	AN8855_MAC_TB_TY_DIP_SIP = 2,
+};
+
+/* Register for vlan table control */
+#define AN8855_VTCR			0x10200600
+#define   AN8855_VTCR_BUSY		BIT(31)
+#define   AN8855_VTCR_FUNC		GENMASK(15, 12)
+#define   AN8855_VTCR_VID		GENMASK(11, 0)
+
+enum an8855_vlan_cmd {
+	/* Read/Write the specified VID entry from VAWD register based
+	 * on VID.
+	 */
+	AN8855_VTCR_RD_VID = 0,
+	AN8855_VTCR_WR_VID = 1,
+};
+
+/* Register for setup vlan write data */
+#define AN8855_VAWD0			0x10200604
+/* VLAN Member Control */
+#define   AN8855_VA0_PORT		GENMASK(31, 26)
+/* Egress Tag Control */
+#define   AN8855_VA0_ETAG		GENMASK(23, 12)
+#define   AN8855_VA0_ETAG_PORT		GENMASK(13, 12)
+#define   AN8855_VA0_ETAG_PORT_SHIFT(port) ((port) * 2)
+#define   AN8855_VA0_ETAG_PORT_MASK(port) (AN8855_VA0_ETAG_PORT << \
+						AN8855_VA0_ETAG_PORT_SHIFT(port))
+#define   AN8855_VA0_ETAG_PORT_VAL(port, val) (FIELD_PREP(AN8855_VA0_ETAG_PORT, (val)) << \
+						AN8855_VA0_ETAG_PORT_SHIFT(port))
+#define   AN8855_VA0_EG_CON		BIT(11)
+#define   AN8855_VA0_VTAG_EN		BIT(10) /* Per VLAN Egress Tag Control */
+#define   AN8855_VA0_IVL_MAC		BIT(5) /* Independent VLAN Learning */
+#define	  AN8855_VA0_FID		GENMASK(4, 1)
+#define   AN8855_VA0_VLAN_VALID		BIT(0) /* VLAN Entry Valid */
+#define AN8855_VAWD1			0x10200608
+#define   AN8855_VA1_PORT_STAG		BIT(1)
+
+enum an8855_fid {
+	AN8855_FID_STANDALONE = 0,
+	AN8855_FID_BRIDGED = 1,
+};
+
+/* Same register field of VAWD0 */
+#define AN8855_VARD0			0x10200618
+
+enum an8855_vlan_egress_attr {
+	AN8855_VLAN_EGRESS_UNTAG = 0,
+	AN8855_VLAN_EGRESS_TAG = 2,
+	AN8855_VLAN_EGRESS_STACK = 3,
+};
+
+/* Register for port STP state control */
+#define AN8855_SSP_P(x)			(0x10208000 + ((x) * 0x200))
+/* Up to 16 FID supported, each with the same mask */
+#define	  AN8855_FID_PST		GENMASK(1, 0)
+#define   AN8855_FID_PST_SHIFT(fid)	(2 * (fid))
+#define   AN8855_FID_PST_MASK(fid)	(AN8855_FID_PST << \
+						AN8855_FID_PST_SHIFT(fid))
+#define   AN8855_FID_PST_VAL(fid, val)	(FIELD_PREP(AN8855_FID_PST, (val)) << \
+						AN8855_FID_PST_SHIFT(fid))
+
+enum an8855_stp_state {
+	AN8855_STP_DISABLED = 0,
+	AN8855_STP_BLOCKING = 1,
+	AN8855_STP_LISTENING = AN8855_STP_BLOCKING,
+	AN8855_STP_LEARNING = 2,
+	AN8855_STP_FORWARDING = 3
+};
+
+/* Register for port control */
+#define AN8855_PCR_P(x)			(0x10208004 + ((x) * 0x200))
+#define   AN8855_EG_TAG			GENMASK(29, 28)
+#define   AN8855_PORT_PRI		GENMASK(26, 24)
+#define   AN8855_PORT_TX_MIR		BIT(20)
+#define   AN8855_PORT_RX_MIR		BIT(16)
+#define   AN8855_PORT_VLAN		GENMASK(1, 0)
+
+enum an8855_port_mode {
+	/* Port Matrix Mode: Frames are forwarded by the PCR_MATRIX members. */
+	AN8855_PORT_MATRIX_MODE = 0,
+
+	/* Fallback Mode: Forward received frames with ingress ports that do
+	 * not belong to the VLAN member. Frames whose VID is not listed on
+	 * the VLAN table are forwarded by the PCR_MATRIX members.
+	 */
+	AN8855_PORT_FALLBACK_MODE = 1,
+
+	/* Check Mode: Forward received frames whose ingress do not
+	 * belong to the VLAN member. Discard frames if VID ismiddes on the
+	 * VLAN table.
+	 */
+	AN8855_PORT_CHECK_MODE = 2,
+
+	/* Security Mode: Discard any frame due to ingress membership
+	 * violation or VID missed on the VLAN table.
+	 */
+	AN8855_PORT_SECURITY_MODE = 3,
+};
+
+/* Register for port security control */
+#define AN8855_PSC_P(x)			(0x1020800c + ((x) * 0x200))
+#define   AN8855_SA_DIS			BIT(4)
+
+/* Register for port vlan control */
+#define AN8855_PVC_P(x)			(0x10208010 + ((x) * 0x200))
+#define   AN8855_PORT_SPEC_REPLACE_MODE	BIT(11)
+#define   AN8855_PVC_EG_TAG		GENMASK(10, 8)
+#define   AN8855_VLAN_ATTR		GENMASK(7, 6)
+#define   AN8855_PORT_SPEC_TAG		BIT(5)
+#define   AN8855_ACC_FRM		GENMASK(1, 0)
+
+enum an8855_vlan_port_eg_tag {
+	AN8855_VLAN_EG_DISABLED = 0,
+	AN8855_VLAN_EG_CONSISTENT = 1,
+	AN8855_VLAN_EG_UNTAGGED = 4,
+	AN8855_VLAN_EG_SWAP = 5,
+	AN8855_VLAN_EG_TAGGED = 6,
+	AN8855_VLAN_EG_STACK = 7,
+};
+
+enum an8855_vlan_port_attr {
+	AN8855_VLAN_USER = 0,
+	AN8855_VLAN_STACK = 1,
+	AN8855_VLAN_TRANSPARENT = 3,
+};
+
+enum an8855_vlan_port_acc_frm {
+	AN8855_VLAN_ACC_ALL = 0,
+	AN8855_VLAN_ACC_TAGGED = 1,
+	AN8855_VLAN_ACC_UNTAGGED = 2,
+};
+
+#define AN8855_PPBV1_P(x)		(0x10208014 + ((x) * 0x200))
+#define   AN8855_PPBV_G0_PORT_VID	GENMASK(11, 0)
+
+#define AN8855_PORTMATRIX_P(x)		(0x10208044 + ((x) * 0x200))
+#define   AN8855_PORTMATRIX		GENMASK(5, 0)
+/* Port matrix without the CPU port that should never be removed */
+#define   AN8855_USER_PORTMATRIX	GENMASK(4, 0)
+
+/* Register for port PVID */
+#define AN8855_PVID_P(x)		(0x10208048 + ((x) * 0x200))
+#define   AN8855_G0_PORT_VID		GENMASK(11, 0)
+
+/* Register for port MAC control register */
+#define AN8855_PMCR_P(x)		(0x10210000 + ((x) * 0x200))
+#define   AN8855_PMCR_FORCE_MODE	BIT(31)
+#define   AN8855_PMCR_FORCE_SPEED	GENMASK(30, 28)
+#define   AN8855_PMCR_FORCE_SPEED_5000	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x4)
+#define   AN8855_PMCR_FORCE_SPEED_2500	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x3)
+#define   AN8855_PMCR_FORCE_SPEED_1000	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x2)
+#define   AN8855_PMCR_FORCE_SPEED_100	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1)
+#define   AN8855_PMCR_FORCE_SPEED_10	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1)
+#define   AN8855_PMCR_FORCE_FDX		BIT(25)
+#define   AN8855_PMCR_FORCE_LNK		BIT(24)
+#define   AN8855_PMCR_IFG_XMIT		GENMASK(21, 20)
+#define   AN8855_PMCR_EXT_PHY		BIT(19)
+#define   AN8855_PMCR_MAC_MODE		BIT(18)
+#define   AN8855_PMCR_TX_EN		BIT(16)
+#define   AN8855_PMCR_RX_EN		BIT(15)
+#define   AN8855_PMCR_BACKOFF_EN	BIT(12)
+#define   AN8855_PMCR_BACKPR_EN		BIT(11)
+#define   AN8855_PMCR_FORCE_EEE5G	BIT(9)
+#define   AN8855_PMCR_FORCE_EEE2P5G	BIT(8)
+#define   AN8855_PMCR_FORCE_EEE1G	BIT(7)
+#define   AN8855_PMCR_FORCE_EEE100	BIT(6)
+#define   AN8855_PMCR_TX_FC_EN		BIT(5)
+#define   AN8855_PMCR_RX_FC_EN		BIT(4)
+
+#define AN8855_PMSR_P(x)		(0x10210010 + (x) * 0x200)
+#define   AN8855_PMSR_SPEED		GENMASK(30, 28)
+#define   AN8855_PMSR_SPEED_5000	FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x4)
+#define   AN8855_PMSR_SPEED_2500	FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x3)
+#define   AN8855_PMSR_SPEED_1000	FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x2)
+#define   AN8855_PMSR_SPEED_100		FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x1)
+#define   AN8855_PMSR_SPEED_10		FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x0)
+#define   AN8855_PMSR_DPX		BIT(25)
+#define   AN8855_PMSR_LNK		BIT(24)
+#define   AN8855_PMSR_EEE1G		BIT(7)
+#define   AN8855_PMSR_EEE100M		BIT(6)
+#define   AN8855_PMSR_RX_FC		BIT(5)
+#define   AN8855_PMSR_TX_FC		BIT(4)
+
+#define AN8855_PMEEECR_P(x)		(0x10210004 + (x) * 0x200)
+#define   AN8855_LPI_MODE_EN		BIT(31)
+#define   AN8855_WAKEUP_TIME_2500	GENMASK(23, 16)
+#define   AN8855_WAKEUP_TIME_1000	GENMASK(15, 8)
+#define   AN8855_WAKEUP_TIME_100	GENMASK(7, 0)
+#define AN8855_PMEEECR2_P(x)		(0x10210008 + (x) * 0x200)
+#define   AN8855_WAKEUP_TIME_5000	GENMASK(7, 0)
+
+#define AN8855_GMACCR			0x10213e00
+#define   AN8855_MAX_RX_JUMBO		GENMASK(7, 4)
+/* 2K for 0x0, 0x1, 0x2 */
+#define   AN8855_MAX_RX_JUMBO_2K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x0)
+#define   AN8855_MAX_RX_JUMBO_3K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x3)
+#define   AN8855_MAX_RX_JUMBO_4K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x4)
+#define   AN8855_MAX_RX_JUMBO_5K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x5)
+#define   AN8855_MAX_RX_JUMBO_6K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x6)
+#define   AN8855_MAX_RX_JUMBO_7K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x7)
+#define   AN8855_MAX_RX_JUMBO_8K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x8)
+#define   AN8855_MAX_RX_JUMBO_9K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x9)
+#define   AN8855_MAX_RX_JUMBO_12K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xa)
+#define   AN8855_MAX_RX_JUMBO_15K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xb)
+#define   AN8855_MAX_RX_JUMBO_16K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xc)
+#define   AN8855_MAX_RX_PKT_LEN		GENMASK(1, 0)
+#define   AN8855_MAX_RX_PKT_1518_1522	FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x0)
+#define   AN8855_MAX_RX_PKT_1536	FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x1)
+#define   AN8855_MAX_RX_PKT_1552	FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x2)
+#define   AN8855_MAX_RX_PKT_JUMBO	FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x3)
+
+#define AN8855_CKGCR			0x10213e1c
+#define   AN8855_LPI_TXIDLE_THD_MASK	GENMASK(31, 14)
+#define   AN8855_CKG_LNKDN_PORT_STOP	BIT(1)
+#define   AN8855_CKG_LNKDN_GLB_STOP	BIT(0)
+
+/* Register for MIB */
+#define AN8855_PORT_MIB_COUNTER(x)	(0x10214000 + (x) * 0x200)
+/* Each define is an offset of AN8855_PORT_MIB_COUNTER */
+#define   AN8855_PORT_MIB_TX_DROP	0x00
+#define   AN8855_PORT_MIB_TX_CRC_ERR	0x04
+#define   AN8855_PORT_MIB_TX_UNICAST	0x08
+#define   AN8855_PORT_MIB_TX_MULTICAST	0x0c
+#define   AN8855_PORT_MIB_TX_BROADCAST	0x10
+#define   AN8855_PORT_MIB_TX_COLLISION	0x14
+#define   AN8855_PORT_MIB_TX_SINGLE_COLLISION 0x18
+#define   AN8855_PORT_MIB_TX_MULTIPLE_COLLISION 0x1c
+#define   AN8855_PORT_MIB_TX_DEFERRED	0x20
+#define   AN8855_PORT_MIB_TX_LATE_COLLISION 0x24
+#define   AN8855_PORT_MIB_TX_EXCESSIVE_COLLISION 0x28
+#define   AN8855_PORT_MIB_TX_PAUSE	0x2c
+#define   AN8855_PORT_MIB_TX_PKT_SZ_64	0x30
+#define   AN8855_PORT_MIB_TX_PKT_SZ_65_TO_127 0x34
+#define   AN8855_PORT_MIB_TX_PKT_SZ_128_TO_255 0x38
+#define   AN8855_PORT_MIB_TX_PKT_SZ_256_TO_511 0x3
+#define   AN8855_PORT_MIB_TX_PKT_SZ_512_TO_1023 0x40
+#define   AN8855_PORT_MIB_TX_PKT_SZ_1024_TO_1518 0x44
+#define   AN8855_PORT_MIB_TX_PKT_SZ_1519_TO_MAX 0x48
+#define   AN8855_PORT_MIB_TX_BYTES	0x4c /* 64 bytes */
+#define   AN8855_PORT_MIB_TX_OVERSIZE_DROP 0x54
+#define   AN8855_PORT_MIB_TX_BAD_PKT_BYTES 0x58 /* 64 bytes */
+#define   AN8855_PORT_MIB_RX_DROP	0x80
+#define   AN8855_PORT_MIB_RX_FILTERING	0x84
+#define   AN8855_PORT_MIB_RX_UNICAST	0x88
+#define   AN8855_PORT_MIB_RX_MULTICAST	0x8c
+#define   AN8855_PORT_MIB_RX_BROADCAST	0x90
+#define   AN8855_PORT_MIB_RX_ALIGN_ERR	0x94
+#define   AN8855_PORT_MIB_RX_CRC_ERR	0x98
+#define   AN8855_PORT_MIB_RX_UNDER_SIZE_ERR 0x9c
+#define   AN8855_PORT_MIB_RX_FRAG_ERR	0xa0
+#define   AN8855_PORT_MIB_RX_OVER_SZ_ERR 0xa4
+#define   AN8855_PORT_MIB_RX_JABBER_ERR	0xa8
+#define   AN8855_PORT_MIB_RX_PAUSE	0xac
+#define   AN8855_PORT_MIB_RX_PKT_SZ_64	0xb0
+#define   AN8855_PORT_MIB_RX_PKT_SZ_65_TO_127 0xb4
+#define   AN8855_PORT_MIB_RX_PKT_SZ_128_TO_255 0xb8
+#define   AN8855_PORT_MIB_RX_PKT_SZ_256_TO_511 0xbc
+#define   AN8855_PORT_MIB_RX_PKT_SZ_512_TO_1023 0xc0
+#define   AN8855_PORT_MIB_RX_PKT_SZ_1024_TO_1518 0xc4
+#define   AN8855_PORT_MIB_RX_PKT_SZ_1519_TO_MAX 0xc8
+#define   AN8855_PORT_MIB_RX_BYTES	0xcc /* 64 bytes */
+#define   AN8855_PORT_MIB_RX_CTRL_DROP	0xd4
+#define   AN8855_PORT_MIB_RX_INGRESS_DROP 0xd8
+#define   AN8855_PORT_MIB_RX_ARL_DROP	0xdc
+#define   AN8855_PORT_MIB_FLOW_CONTROL_DROP 0xe0
+#define   AN8855_PORT_MIB_WRED_DROP	0xe4
+#define   AN8855_PORT_MIB_MIRROR_DROP	0xe8
+#define   AN8855_PORT_MIB_RX_BAD_PKT_BYTES 0xec /* 64 bytes */
+#define   AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP 0xf4
+#define   AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP 0xf8
+#define   AN8855_PORT_MIB_PORT_CONTROL_DROP 0xfc
+#define AN8855_MIB_CCR			0x10213e30
+#define   AN8855_CCR_MIB_ENABLE		BIT(31)
+#define   AN8855_CCR_RX_OCT_CNT_GOOD	BIT(7)
+#define   AN8855_CCR_RX_OCT_CNT_BAD	BIT(6)
+#define   AN8855_CCR_TX_OCT_CNT_GOOD	BIT(5)
+#define   AN8855_CCR_TX_OCT_CNT_BAD	BIT(4)
+#define   AN8855_CCR_RX_OCT_CNT_GOOD_2	BIT(3)
+#define   AN8855_CCR_RX_OCT_CNT_BAD_2	BIT(2)
+#define   AN8855_CCR_TX_OCT_CNT_GOOD_2	BIT(1)
+#define   AN8855_CCR_TX_OCT_CNT_BAD_2	BIT(0)
+#define   AN8855_CCR_MIB_ACTIVATE	(AN8855_CCR_MIB_ENABLE | \
+					 AN8855_CCR_RX_OCT_CNT_GOOD | \
+					 AN8855_CCR_RX_OCT_CNT_BAD | \
+					 AN8855_CCR_TX_OCT_CNT_GOOD | \
+					 AN8855_CCR_TX_OCT_CNT_BAD | \
+					 AN8855_CCR_RX_OCT_CNT_BAD_2 | \
+					 AN8855_CCR_TX_OCT_CNT_BAD_2)
+#define AN8855_MIB_CLR			0x10213e34
+#define   AN8855_MIB_PORT6_CLR		BIT(6)
+#define   AN8855_MIB_PORT5_CLR		BIT(5)
+#define   AN8855_MIB_PORT4_CLR		BIT(4)
+#define   AN8855_MIB_PORT3_CLR		BIT(3)
+#define   AN8855_MIB_PORT2_CLR		BIT(2)
+#define   AN8855_MIB_PORT1_CLR		BIT(1)
+#define   AN8855_MIB_PORT0_CLR		BIT(0)
+
+/* HSGMII/SGMII Configuration register */
+/*	AN8855_HSGMII_AN_CSR_BASE	0x10220000 */
+#define AN8855_SGMII_REG_AN0		0x10220000
+/*        AN8855_SGMII_AN_ENABLE	BMCR_ANENABLE */
+/*        AN8855_SGMII_AN_RESTART	BMCR_ANRESTART */
+#define AN8855_SGMII_REG_AN_13		0x10220034
+#define   AN8855_SGMII_REMOTE_FAULT_DIS	BIT(8)
+#define   AN8855_SGMII_IF_MODE		GENMASK(5, 0)
+#define AN8855_SGMII_REG_AN_FORCE_CL37	0x10220060
+#define   AN8855_RG_FORCE_AN_DONE	BIT(0)
+
+/*	AN8855_HSGMII_CSR_PCS_BASE	0x10220000 */
+#define AN8855_RG_HSGMII_PCS_CTROL_1	0x10220a00
+#define   AN8855_RG_TBI_10B_MODE	BIT(30)
+#define AN8855_RG_AN_SGMII_MODE_FORCE	0x10220a24
+#define   AN8855_RG_FORCE_CUR_SGMII_MODE GENMASK(5, 4)
+#define   AN8855_RG_FORCE_CUR_SGMII_SEL	BIT(0)
+
+/*	AN8855_MULTI_SGMII_CSR_BASE	0x10224000 */
+#define AN8855_SGMII_STS_CTRL_0		0x10224018
+#define   AN8855_RG_LINK_MODE_P0	GENMASK(5, 4)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_2500 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x3)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_1000 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x2)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_100 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x1)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_10 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x0)
+#define   AN8855_RG_FORCE_SPD_MODE_P0	BIT(2)
+#define AN8855_MSG_RX_CTRL_0		0x10224100
+#define AN8855_MSG_RX_LIK_STS_0		0x10224514
+#define   AN8855_RG_DPX_STS_P3		BIT(24)
+#define   AN8855_RG_DPX_STS_P2		BIT(16)
+#define   AN8855_RG_EEE1G_STS_P1	BIT(12)
+#define   AN8855_RG_DPX_STS_P1		BIT(8)
+#define   AN8855_RG_TXFC_STS_P0		BIT(2)
+#define   AN8855_RG_RXFC_STS_P0		BIT(1)
+#define   AN8855_RG_DPX_STS_P0		BIT(0)
+#define AN8855_MSG_RX_LIK_STS_2		0x1022451c
+#define   AN8855_RG_RXFC_AN_BYPASS_P3	BIT(11)
+#define   AN8855_RG_RXFC_AN_BYPASS_P2	BIT(10)
+#define   AN8855_RG_RXFC_AN_BYPASS_P1	BIT(9)
+#define   AN8855_RG_TXFC_AN_BYPASS_P3	BIT(7)
+#define   AN8855_RG_TXFC_AN_BYPASS_P2	BIT(6)
+#define   AN8855_RG_TXFC_AN_BYPASS_P1	BIT(5)
+#define   AN8855_RG_DPX_AN_BYPASS_P3	BIT(3)
+#define   AN8855_RG_DPX_AN_BYPASS_P2	BIT(2)
+#define   AN8855_RG_DPX_AN_BYPASS_P1	BIT(1)
+#define   AN8855_RG_DPX_AN_BYPASS_P0	BIT(0)
+#define AN8855_PHY_RX_FORCE_CTRL_0	0x10224520
+#define   AN8855_RG_FORCE_TXC_SEL	BIT(4)
+
+/*	AN8855_XFI_CSR_PCS_BASE		0x10225000 */
+#define AN8855_RG_USXGMII_AN_CONTROL_0	0x10225bf8
+
+/*	AN8855_MULTI_PHY_RA_CSR_BASE	0x10226000 */
+#define AN8855_RG_RATE_ADAPT_CTRL_0	0x10226000
+#define   AN8855_RG_RATE_ADAPT_RX_BYPASS BIT(27)
+#define   AN8855_RG_RATE_ADAPT_TX_BYPASS BIT(26)
+#define   AN8855_RG_RATE_ADAPT_RX_EN	BIT(4)
+#define   AN8855_RG_RATE_ADAPT_TX_EN	BIT(0)
+#define AN8855_RATE_ADP_P0_CTRL_0	0x10226100
+#define   AN8855_RG_P0_DIS_MII_MODE	BIT(31)
+#define   AN8855_RG_P0_MII_MODE		BIT(28)
+#define   AN8855_RG_P0_MII_RA_RX_EN	BIT(3)
+#define   AN8855_RG_P0_MII_RA_TX_EN	BIT(2)
+#define   AN8855_RG_P0_MII_RA_RX_MODE	BIT(1)
+#define   AN8855_RG_P0_MII_RA_TX_MODE	BIT(0)
+#define AN8855_MII_RA_AN_ENABLE		0x10226300
+#define   AN8855_RG_P0_RA_AN_EN		BIT(0)
+
+/*	AN8855_QP_DIG_CSR_BASE		0x1022a000 */
+#define AN8855_QP_CK_RST_CTRL_4		0x1022a310
+#define AN8855_QP_DIG_MODE_CTRL_0	0x1022a324
+#define   AN8855_RG_SGMII_MODE		GENMASK(5, 4)
+#define   AN8855_RG_SGMII_AN_EN		BIT(0)
+#define AN8855_QP_DIG_MODE_CTRL_1	0x1022a330
+#define   AN8855_RG_TPHY_SPEED		GENMASK(3, 2)
+
+/*	AN8855_SERDES_WRAPPER_BASE	0x1022c000 */
+#define AN8855_USGMII_CTRL_0		0x1022c000
+
+/*	AN8855_QP_PMA_TOP_BASE		0x1022e000 */
+#define AN8855_PON_RXFEDIG_CTRL_0	0x1022e100
+#define   AN8855_RG_QP_EQ_RX500M_CK_SEL	BIT(12)
+#define AN8855_PON_RXFEDIG_CTRL_9	0x1022e124
+#define   AN8855_RG_QP_EQ_LEQOSC_DLYCNT	GENMASK(2, 0)
+
+#define AN8855_SS_LCPLL_PWCTL_SETTING_2	0x1022e208
+#define   AN8855_RG_NCPO_ANA_MSB	GENMASK(17, 16)
+#define AN8855_SS_LCPLL_TDC_FLT_2	0x1022e230
+#define   AN8855_RG_LCPLL_NCPO_VALUE	GENMASK(30, 0)
+#define AN8855_SS_LCPLL_TDC_FLT_5	0x1022e23c
+#define   AN8855_RG_LCPLL_NCPO_CHG	BIT(24)
+#define AN8855_SS_LCPLL_TDC_PCW_1	0x1022e248
+#define  AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON GENMASK(30, 0)
+#define AN8855_INTF_CTRL_8		0x1022e320
+#define AN8855_INTF_CTRL_9		0x1022e324
+#define AN8855_INTF_CTRL_10		0x1022e328
+#define   AN8855_RG_DA_QP_TX_FIR_C2_SEL	BIT(29)
+#define   AN8855_RG_DA_QP_TX_FIR_C2_FORCE GENMASK(28, 24)
+#define   AN8855_RG_DA_QP_TX_FIR_C1_SEL	BIT(21)
+#define   AN8855_RG_DA_QP_TX_FIR_C1_FORCE GENMASK(20, 16)
+#define AN8855_INTF_CTRL_11		0x1022e32c
+#define   AN8855_RG_DA_QP_TX_FIR_C0B_SEL BIT(6)
+#define   AN8855_RG_DA_QP_TX_FIR_C0B_FORCE GENMASK(5, 0)
+#define AN8855_PLL_CTRL_0		0x1022e400
+#define   AN8855_RG_PHYA_AUTO_INIT	BIT(0)
+#define AN8855_PLL_CTRL_2		0x1022e408
+#define   AN8855_RG_DA_QP_PLL_SDM_IFM_INTF BIT(30)
+#define   AN8855_RG_DA_QP_PLL_RICO_SEL_INTF BIT(29)
+#define   AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF BIT(28)
+#define   AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF BIT(27)
+#define   AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF BIT(26)
+#define   AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF GENMASK(25, 24)
+#define   AN8855_RG_DA_QP_PLL_PCK_SEL_INTF BIT(22)
+#define   AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF GENMASK(21, 20)
+#define   AN8855_RG_DA_QP_PLL_IR_INTF	GENMASK(19, 16)
+#define   AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF BIT(14)
+#define   AN8855_RG_DA_QP_PLL_FBKSEL_INTF GENMASK(13, 12)
+#define   AN8855_RG_DA_QP_PLL_BR_INTF	GENMASK(10, 8)
+#define   AN8855_RG_DA_QP_PLL_BPD_INTF	GENMASK(7, 6)
+#define   AN8855_RG_DA_QP_PLL_BPA_INTF	GENMASK(4, 2)
+#define   AN8855_RG_DA_QP_PLL_BC_INTF	GENMASK(1, 0)
+#define AN8855_PLL_CTRL_3		0x1022e40c
+#define   AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF GENMASK(31, 16)
+#define   AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF GENMASK(15, 0)
+#define AN8855_PLL_CTRL_4		0x1022e410
+#define   AN8855_RG_DA_QP_PLL_SDM_HREN_INTF GENMASK(4, 3)
+#define   AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF BIT(2)
+#define   AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF GENMASK(1, 0)
+#define AN8855_PLL_CK_CTRL_0		0x1022e414
+#define   AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF BIT(9)
+#define   AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF BIT(8)
+#define AN8855_RX_DLY_0			0x1022e614
+#define   AN8855_RG_QP_RX_SAOSC_EN_H_DLY GENMASK(13, 8)
+#define   AN8855_RG_QP_RX_PI_CAL_EN_H_DLY GENMASK(7, 0)
+#define AN8855_RX_CTRL_2		0x1022e630
+#define   AN8855_RG_QP_RX_EQ_EN_H_DLY	GENMASK(28, 16)
+#define AN8855_RX_CTRL_5		0x1022e63c
+#define   AN8855_RG_FREDET_CHK_CYCLE	GENMASK(29, 10)
+#define AN8855_RX_CTRL_6		0x1022e640
+#define   AN8855_RG_FREDET_GOLDEN_CYCLE	GENMASK(19, 0)
+#define AN8855_RX_CTRL_7		0x1022e644
+#define   AN8855_RG_FREDET_TOLERATE_CYCLE GENMASK(19, 0)
+#define AN8855_RX_CTRL_8		0x1022e648
+#define   AN8855_RG_DA_QP_SAOSC_DONE_TIME GENMASK(27, 16)
+#define   AN8855_RG_DA_QP_LEQOS_EN_TIME	GENMASK(14, 0)
+#define AN8855_RX_CTRL_26		0x1022e690
+#define   AN8855_RG_QP_EQ_RETRAIN_ONLY_EN BIT(26)
+#define   AN8855_RG_LINK_NE_EN		BIT(24)
+#define   AN8855_RG_LINK_ERRO_EN	BIT(23)
+#define AN8855_RX_CTRL_42		0x1022e6d0
+#define   AN8855_RG_QP_EQ_EN_DLY	GENMASK(12, 0)
+
+/*	AN8855_QP_ANA_CSR_BASE		0x1022f000 */
+#define AN8855_RG_QP_RX_DAC_EN		0x1022f000
+#define   AN8855_RG_QP_SIGDET_HF	GENMASK(17, 16)
+#define AN8855_RG_QP_RXAFE_RESERVE	0x1022f004
+#define   AN8855_RG_QP_CDR_PD_10B_EN	BIT(11)
+#define AN8855_RG_QP_CDR_LPF_BOT_LIM	0x1022f008
+#define   AN8855_RG_QP_CDR_LPF_KP_GAIN	GENMASK(26, 24)
+#define   AN8855_RG_QP_CDR_LPF_KI_GAIN	GENMASK(22, 20)
+#define AN8855_RG_QP_CDR_LPF_MJV_LIM	0x1022f00c
+#define   AN8855_RG_QP_CDR_LPF_RATIO	GENMASK(5, 4)
+#define AN8855_RG_QP_CDR_LPF_SETVALUE	0x1022f014
+#define   AN8855_RG_QP_CDR_PR_BUF_IN_SR	GENMASK(31, 29)
+#define   AN8855_RG_QP_CDR_PR_BETA_SEL	GENMASK(28, 25)
+#define AN8855_RG_QP_CDR_PR_CKREF_DIV1	0x1022f018
+#define   AN8855_RG_QP_CDR_PR_KBAND_DIV	GENMASK(26, 24)
+#define   AN8855_RG_QP_CDR_PR_DAC_BAND	GENMASK(12, 8)
+#define AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE 0x1022f01c
+#define   AN8855_RG_QP_CDR_PR_XFICK_EN	BIT(30)
+#define   AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE BIT(6)
+#define   AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK GENMASK(5, 0)
+#define AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF 0x1022f020
+#define   AN8855_RG_QP_CDR_PHYCK_SEL	GENMASK(17, 16)
+#define   AN8855_RG_QP_CDR_PHYCK_RSTB	BIT(13)
+#define   AN8855_RG_QP_CDR_PHYCK_DIV	GENMASK(12, 6)
+#define AN8855_RG_QP_TX_MODE		0x1022f028
+#define   AN8855_RG_QP_TX_RESERVE	GENMASK(31, 16)
+#define   AN8855_RG_QP_TX_MODE_16B_EN	BIT(0)
+#define AN8855_RG_QP_PLL_IPLL_DIG_PWR_SEL 0x1022f03c
+#define AN8855_RG_QP_PLL_SDM_ORD	0x1022f040
+#define   AN8855_RG_QP_PLL_SSC_PHASE_INI BIT(4)
+#define   AN8855_RG_QP_PLL_SSC_TRI_EN	BIT(3)
+
+/*	AN8855_ETHER_SYS_BASE		0x1028c800 */
+#define AN8855_RG_GPHY_AFE_PWD		0x1028c840
+#define AN8855_RG_GPHY_SMI_ADDR		0x1028c848
+
+#define MIB_DESC(_s, _o, _n)	\
+	{			\
+		.size = (_s),	\
+		.offset = (_o),	\
+		.name = (_n),	\
+	}
+
+struct an8855_mib_desc {
+	unsigned int size;
+	unsigned int offset;
+	const char *name;
+};
+
+struct an8855_fdb {
+	u16 vid;
+	u8 port_mask;
+	u16 aging;
+	u8 mac[6];
+	bool noarp;
+	u8 live;
+	u8 type;
+	u8 fid;
+	u8 ivl;
+};
+
+struct an8855_priv {
+	struct device *dev;
+	struct dsa_switch *ds;
+	struct regmap *regmap;
+	struct gpio_desc *reset_gpio;
+	/* Protect ATU or VLAN table access */
+	struct mutex reg_mutex;
+
+	struct phylink_pcs pcs;
+
+	u8 mirror_rx;
+	u8 mirror_tx;
+	u8 port_isolated_map;
+
+	bool phy_require_calib;
+};
+
+#endif /* __AN8855_H */
-- 
2.45.2



From ansuelsmth at gmail.com  Sat Dec  7 16:20:44 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun,  8 Dec 2024 01:20:44 +0100
Subject: [net-next PATCH v10 9/9] net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY
In-Reply-To: <20241208002105.18074-1-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
Message-ID: <20241208002105.18074-10-ansuelsmth@gmail.com>

Add support for Airoha AN8855 Internal Switch Gigabit PHY.

This is a simple PHY driver to configure and calibrate the PHY for the
AN8855 Switch with the use of NVMEM cells.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                  |   1 +
 drivers/net/phy/Kconfig      |   5 +
 drivers/net/phy/Makefile     |   1 +
 drivers/net/phy/air_an8855.c | 267 +++++++++++++++++++++++++++++++++++
 4 files changed, 274 insertions(+)
 create mode 100644 drivers/net/phy/air_an8855.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c42431a09b84..25490fcab5a2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -725,6 +725,7 @@ F:	drivers/mfd/airoha-an8855.c
 F:	drivers/net/dsa/an8855.c
 F:	drivers/net/dsa/an8855.h
 F:	drivers/net/mdio/mdio-an8855.c
+F:	drivers/net/phy/air_an8855.c
 F:	drivers/nvmem/an8855-efuse.c
 
 AIROHA ETHERNET DRIVER
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 15828f4710a9..9b4a7c12b138 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -79,6 +79,11 @@ config SFP
 
 comment "MII PHY device drivers"
 
+config AIR_AN8855_PHY
+	tristate "Airoha AN8855 Internal Gigabit PHY"
+	help
+	  Currently supports the internal Airoha AN8855 Switch PHY.
+
 config AIR_EN8811H_PHY
 	tristate "Airoha EN8811H 2.5 Gigabit PHY"
 	help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index e6145153e837..38ca7432780e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -35,6 +35,7 @@ obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
 
 obj-$(CONFIG_ADIN_PHY)		+= adin.o
 obj-$(CONFIG_ADIN1100_PHY)	+= adin1100.o
+obj-$(CONFIG_AIR_AN8855_PHY)   += air_an8855.o
 obj-$(CONFIG_AIR_EN8811H_PHY)   += air_en8811h.o
 obj-$(CONFIG_AMD_PHY)		+= amd.o
 obj-$(CONFIG_AMCC_QT2025_PHY)	+= qt2025.o
diff --git a/drivers/net/phy/air_an8855.c b/drivers/net/phy/air_an8855.c
new file mode 100644
index 000000000000..914cd729404b
--- /dev/null
+++ b/drivers/net/phy/air_an8855.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth at gmail.com>
+ */
+
+#include <linux/phy.h>
+#include <linux/module.h>
+#include <linux/bitfield.h>
+#include <linux/nvmem-consumer.h>
+
+#define AN8855_PHY_SELECT_PAGE			0x1f
+#define   AN8855_PHY_PAGE			GENMASK(2, 0)
+#define   AN8855_PHY_PAGE_STANDARD		FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
+#define   AN8855_PHY_PAGE_EXTENDED_1		FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
+
+/* MII Registers Page 1 */
+#define AN8855_PHY_EXT_REG_14			0x14
+#define   AN8855_PHY_EN_DOWN_SHIFT		BIT(4)
+
+/* R50 Calibration regs in MDIO_MMD_VEND1 */
+#define AN8855_PHY_R500HM_RSEL_TX_AB		0x174
+#define AN8855_PHY_R50OHM_RSEL_TX_A_EN		BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_A		GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_B_EN		BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_B		GENMASK(6, 0)
+#define AN8855_PHY_R500HM_RSEL_TX_CD		0x175
+#define AN8855_PHY_R50OHM_RSEL_TX_C_EN		BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_C		GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_D_EN		BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_D		GENMASK(6, 0)
+
+#define AN8855_SWITCH_EFUSE_R50O		GENMASK(30, 24)
+
+/* PHY TX PAIR DELAY SELECT Register */
+#define AN8855_PHY_TX_PAIR_DLY_SEL_GBE		0x013
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE GENMASK(14, 12)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_B_GBE GENMASK(10, 8)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE GENMASK(6, 4)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_D_GBE GENMASK(2, 0)
+/* PHY ADC Register */
+#define AN8855_PHY_RXADC_CTRL			0x0d8
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A	BIT(12)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_B	BIT(8)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C	BIT(4)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_D	BIT(0)
+#define AN8855_PHY_RXADC_REV_0			0x0d9
+#define   AN8855_PHY_RG_AD_RESERVE0_A		GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_B		GENMASK(7, 0)
+#define AN8855_PHY_RXADC_REV_1			0x0da
+#define   AN8855_PHY_RG_AD_RESERVE0_C		GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_D		GENMASK(7, 0)
+
+#define AN8855_PHY_ID				0xc0ff0410
+
+#define AN8855_PHY_FLAGS_EN_CALIBRATION		BIT(0)
+
+struct air_an8855_priv {
+	u8 calibration_data[4];
+};
+
+static const u8 dsa_r50ohm_table[] = {
+	127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+	127, 127, 127, 127, 127, 127, 127, 126, 122, 117,
+	112, 109, 104, 101,  97,  94,  90,  88,  84,  80,
+	78,  74,  72,  68,  66,  64,  61,  58,  56,  53,
+	51,  48,  47,  44,  42,  40,  38,  36,  34,  32,
+	31,  28,  27,  24,  24,  22,  20,  18,  16,  16,
+	14,  12,  11,   9
+};
+
+static int en8855_get_r50ohm_val(struct device *dev, const char *calib_name,
+				 u8 *dest)
+{
+	u32 shift_sel, val;
+	int ret;
+	int i;
+
+	ret = nvmem_cell_read_u32(dev, calib_name, &val);
+	if (ret)
+		return ret;
+
+	shift_sel = FIELD_GET(AN8855_SWITCH_EFUSE_R50O, val);
+	for (i = 0; i < ARRAY_SIZE(dsa_r50ohm_table); i++)
+		if (dsa_r50ohm_table[i] == shift_sel)
+			break;
+
+	if (i < 8 || i >= ARRAY_SIZE(dsa_r50ohm_table))
+		*dest = dsa_r50ohm_table[25];
+	else
+		*dest = dsa_r50ohm_table[i - 8];
+
+	return 0;
+}
+
+static int an8855_probe(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	struct device_node *node = dev->of_node;
+	struct air_an8855_priv *priv;
+	int ret;
+
+	/* If we don't have a node, skip calib */
+	if (!node)
+		return 0;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	phydev->priv = priv;
+
+	return 0;
+}
+
+static int an8855_get_downshift(struct phy_device *phydev, u8 *data)
+{
+	int val;
+
+	val = phy_read_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1, AN8855_PHY_EXT_REG_14);
+	if (val < 0)
+		return val;
+
+	*data = val & AN8855_PHY_EN_DOWN_SHIFT ? DOWNSHIFT_DEV_DEFAULT_COUNT :
+						 DOWNSHIFT_DEV_DISABLE;
+
+	return 0;
+}
+
+static int an8855_set_downshift(struct phy_device *phydev, u8 cnt)
+{
+	u16 ds = cnt != DOWNSHIFT_DEV_DISABLE ? AN8855_PHY_EN_DOWN_SHIFT : 0;
+
+	return phy_modify_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1,
+				AN8855_PHY_EXT_REG_14, AN8855_PHY_EN_DOWN_SHIFT,
+				ds);
+}
+
+static int an8855_config_init(struct phy_device *phydev)
+{
+	struct air_an8855_priv *priv = phydev->priv;
+	int ret;
+
+	/* Enable HW auto downshift */
+	ret = an8855_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT);
+	if (ret)
+		return ret;
+
+	/* Apply calibration values, if needed.
+	 * AN8855_PHY_FLAGS_EN_CALIBRATION signal this.
+	 */
+	if (priv && phydev->dev_flags & AN8855_PHY_FLAGS_EN_CALIBRATION) {
+		u8 *calibration_data = priv->calibration_data;
+
+		ret = en8855_get_r50ohm_val(dev, "tx_a", &calibration_data[0]);
+		if (ret)
+			return ret;
+
+		ret = en8855_get_r50ohm_val(dev, "tx_b", &calibration_data[1]);
+		if (ret)
+			return ret;
+
+		ret = en8855_get_r50ohm_val(dev, "tx_c", &calibration_data[2]);
+		if (ret)
+			return ret;
+
+		ret = en8855_get_r50ohm_val(dev, "tx_d", &calibration_data[3]);
+		if (ret)
+			return ret;
+
+		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_AB,
+				     AN8855_PHY_R50OHM_RSEL_TX_A | AN8855_PHY_R50OHM_RSEL_TX_B,
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_A, calibration_data[0]) |
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_B, calibration_data[1]));
+		if (ret)
+			return ret;
+		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_CD,
+				     AN8855_PHY_R50OHM_RSEL_TX_C | AN8855_PHY_R50OHM_RSEL_TX_D,
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_C, calibration_data[2]) |
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_D, calibration_data[3]));
+		if (ret)
+			return ret;
+	}
+
+	/* Apply values to reduce signal noise */
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_TX_PAIR_DLY_SEL_GBE,
+			    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE, 0x4) |
+			    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE, 0x4));
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_CTRL,
+			    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A |
+			    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C);
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_0,
+			    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_A, 0x1));
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_1,
+			    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_C, 0x1));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int an8855_get_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, void *data)
+{
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT:
+		return an8855_get_downshift(phydev, data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int an8855_set_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, const void *data)
+{
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT:
+		return an8855_set_downshift(phydev, *(const u8 *)data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int an8855_read_page(struct phy_device *phydev)
+{
+	return __phy_read(phydev, AN8855_PHY_SELECT_PAGE);
+}
+
+static int an8855_write_page(struct phy_device *phydev, int page)
+{
+	return __phy_write(phydev, AN8855_PHY_SELECT_PAGE, page);
+}
+
+static struct phy_driver an8855_driver[] = {
+{
+	PHY_ID_MATCH_EXACT(AN8855_PHY_ID),
+	.name			= "Airoha AN8855 internal PHY",
+	/* PHY_GBIT_FEATURES */
+	.flags			= PHY_IS_INTERNAL,
+	.probe			= an8855_probe,
+	.config_init		= an8855_config_init,
+	.soft_reset		= genphy_soft_reset,
+	.get_tunable		= an8855_get_tunable,
+	.set_tunable		= an8855_set_tunable,
+	.suspend		= genphy_suspend,
+	.resume			= genphy_resume,
+	.read_page		= an8855_read_page,
+	.write_page		= an8855_write_page,
+}, };
+
+module_phy_driver(an8855_driver);
+
+static struct mdio_device_id __maybe_unused an8855_tbl[] = {
+	{ PHY_ID_MATCH_EXACT(AN8855_PHY_ID) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(mdio, an8855_tbl);
+
+MODULE_DESCRIPTION("Airoha AN8855 PHY driver");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From patchwork-bot+netdevbpf at kernel.org  Sat Dec  7 17:40:27 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Sun, 08 Dec 2024 01:40:27 +0000
Subject: [PATCH net] net: stmmac: fix TSO DMA API usage causing oops
In-Reply-To: <E1tJXcx-006N4Z-PC@rmk-PC.armlinux.org.uk>
References: <E1tJXcx-006N4Z-PC@rmk-PC.armlinux.org.uk>
Message-ID: <173362202750.3128634.12775021527593555165.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Fri, 06 Dec 2024 12:40:11 +0000 you wrote:
> Commit 66600fac7a98 ("net: stmmac: TSO: Fix unbalanced DMA map/unmap
> for non-paged SKB data") moved the assignment of tx_skbuff_dma[]'s
> members to be later in stmmac_tso_xmit().
> 
> The buf (dma cookie) and len stored in this structure are passed to
> dma_unmap_single() by stmmac_tx_clean(). The DMA API requires that
> the dma cookie passed to dma_unmap_single() is the same as the value
> returned from dma_map_single(). However, by moving the assignment
> later, this is not the case when priv->dma_cap.addr64 > 32 as "des"
> is offset by proto_hdr_len.
> 
> [...]

Here is the summary with links:
  - [net] net: stmmac: fix TSO DMA API usage causing oops
    https://git.kernel.org/netdev/net/c/4c49f38e20a5

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From robh at kernel.org  Sat Dec  7 17:47:29 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Sat, 07 Dec 2024 19:47:29 -0600
Subject: [net-next PATCH v10 4/9] dt-bindings: mfd: Document support
 for Airoha AN8855 Switch SoC
In-Reply-To: <20241208002105.18074-5-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
 <20241208002105.18074-5-ansuelsmth@gmail.com>
Message-ID: <173362244923.3602058.6036855102171988535.robh@kernel.org>


On Sun, 08 Dec 2024 01:20:39 +0100, Christian Marangi wrote:
> Document support for Airoha AN8855 Switch SoC. This SoC expose various
> peripherals like an Ethernet Switch, a NVMEM provider and Ethernet PHYs.
> 
> It does also support i2c and timers but those are not currently
> supported/used.
> 
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> ---
>  .../bindings/mfd/airoha,an8855-mfd.yaml       | 185 ++++++++++++++++++
>  MAINTAINERS                                   |   1 +
>  2 files changed, 186 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.example.dtb: mdio: mfd at 1:reg: [[1], [2]] is too long
	from schema $id: http://devicetree.org/schemas/net/mdio.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241208002105.18074-5-ansuelsmth 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 torvalds at linux-foundation.org  Sat Dec  7 17:58:37 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Sat, 7 Dec 2024 17:58:37 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de> <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de> <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
 <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de> <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>
 <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de>
Message-ID: <CAHk-=wgVGmj+nAju2XuWWD_FZHdeytRW2XX5D-L3MqDuRRciVg@mail.gmail.com>

On Sat, 7 Dec 2024 at 15:52, Martin Uecker <muecker at gwdg.de> wrote:
>
> Can you point me to some horror stories?

So the main issues tended to be about various static verification tools.

Ranging from things like the stackleak plugin for gcc, where handling
VLA's and alloca() (which are pretty much the same thing with
different syntax) was just very much added complexity, to perhaps
overly simplistic tools that literally just check the stack usage by
parsing "objdump --disassemble" output and then building up
approximate "this is the combined deepest stack" call chain
approximations.

And even in the *basic* infrastructure like gcc itself, VLA's simply
made -Wframe-larger-than= just simply not work.

I also have this memory of bad code generation (again, this is 5=
years ago, so take this with a pinch of salt: dim memories), where gcc
wouldn't end up re-using VLA stack slots, so VLA's made the frame
bigger for that reason or something like that.

We explicitly use "-fconserve-stack" to get gcc to reuse spill slots,
because gcc has been known to sometimes makes insanely piggish stack
frames when it just creates a spill slot for *everything*, even if the
spills aren't live at the same time (think big functions with lots of
case statements).

We also had several cases of the VLA's just being silly, when a simple
constant-sized allocation just worked fine and didn't generate
pointless extra code.

Pretty much none of the code core actually ever wanted VLA's, so the
end result was that we had these bad patterns mainly in random drivers
etc. Don't do that.

                Linus


From patchwork-bot+netdevbpf at kernel.org  Sat Dec  7 18:00:33 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Sun, 08 Dec 2024 02:00:33 +0000
Subject: [PATCH net-next 0/3] net: net: add negotiation of in-band
 capabilities (remainder)
In-Reply-To: <Z1F1b8eh8s8T627j@shell.armlinux.org.uk>
References: <Z1F1b8eh8s8T627j@shell.armlinux.org.uk>
Message-ID: <173362323373.3131871.16932382585953200042.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, 5 Dec 2024 09:42:07 +0000 you wrote:
> Hi,
> 
> Here are the last three patches which were not included in the non-RFC
> posting, but were in the RFC posting. These add the .pcs_inband()
> method to the Lynx, MTK Lynx and XPCS drivers.
> 
>  drivers/net/pcs/pcs-lynx.c      | 22 ++++++++++++++++++++++
>  drivers/net/pcs/pcs-mtk-lynxi.c | 16 ++++++++++++++++
>  drivers/net/pcs/pcs-xpcs.c      | 28 ++++++++++++++++++++++++++++
>  3 files changed, 66 insertions(+)

Here is the summary with links:
  - [net-next,1/3] net: pcs: pcs-lynx: implement pcs_inband_caps() method
    https://git.kernel.org/netdev/net-next/c/6561f0e547be
  - [net-next,2/3] net: pcs: pcs-mtk-lynxi: implement pcs_inband_caps() method
    https://git.kernel.org/netdev/net-next/c/520d29bdda86
  - [net-next,3/3] net: pcs: xpcs: implement pcs_inband_caps() method
    https://git.kernel.org/netdev/net-next/c/484d0170d6c6

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From alim.akhtar at samsung.com  Sat Dec  7 18:07:43 2024
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sun, 8 Dec 2024 07:37:43 +0530
Subject: [PATCH] arm64: dts: exynosautov920: add DMA nodes
In-Reply-To: <20241204122335.1578-1-faraz.ata@samsung.com>
References: <CGME20241204122402epcas5p2412733eb46d495fadfa30e5af3c5ce83@epcas5p2.samsung.com>
	<20241204122335.1578-1-faraz.ata@samsung.com>
Message-ID: <141801db4915$f8ffb4d0$eaff1e70$@samsung.com>

Hi Faraz,

> -----Original Message-----
> From: Faraz Ata <faraz.ata at samsung.com>
> Sent: Wednesday, December 4, 2024 5:54 PM
> To: devicetree at vger.kernel.org; linux-samsung-soc at vger.kernel.org;
> krzk+dt at kernel.org; robh at kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; alim.akhtar at samsung.com;
> rosa.pila at samsung.com; Faraz Ata <faraz.ata at samsung.com>
> Subject: [PATCH] arm64: dts: exynosautov920: add DMA nodes
> 
> ExynosAutov920 SoC has 7 DMA controllers. Two secure DMAC
> (SPDMA0 & SPDMA1) and five non-secure DMAC (PDMA0 to PDMA4).
> Adds the required dt node for the same.
> 
> Signed-off-by: Faraz Ata <faraz.ata at samsung.com>
> ---

Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  .../arm64/boot/dts/exynos/exynosautov920.dtsi | 63
> +++++++++++++++++++
>  1 file changed, 63 insertions(+)
>
.
.
.
 
> 2.34.1




From macromorgan at hotmail.com  Sat Dec  7 18:32:09 2024
From: macromorgan at hotmail.com (Chris Morgan)
Date: Sat, 7 Dec 2024 20:32:09 -0600
Subject: [PATCH] Update H700 opp values
In-Reply-To: <5b07cd47-868d-46a3-b365-ccac2a68b792@arm.com>
References: <20241128154556.2743839-1-simons.philippe@gmail.com>
 <5b07cd47-868d-46a3-b365-ccac2a68b792@arm.com>
Message-ID: <SA2PR06MB7658AC3393BEB29D946EE508A5332@SA2PR06MB7658.namprd06.prod.outlook.com>

On Thu, Nov 28, 2024 at 11:23:31PM +0000, Andre Przywara wrote:
> Hi Philippe,
> 
> thanks for taking care of sending a patch!
> You would need prefixes on the subject line to point to the right subsystem.
> A "git log path/to/changed_file" would give you the prefix of previous
> patches, for you to copy from. In this case it would be:
> arm64: dts: allwinner: h616: update H700 OPP values
> 
> On 28/11/2024 15:45, Philippe Simons wrote:
> > My H700 (RG35XX-H, RG40XX-V and RG CubeXX) devices are very unstable,
> > especially with some OPPs.
> > Crashes were fairly easy to reproduce with any dynamic cpufreq governor
> > and some load on CPU, usually in matter of minutes.
> > Crashes manifested randomly as simply hanging or various kernel oops
> > 
> > Manufacturer (Anbernic) is using more conservative mircrovolt values,
> > so let's use these.
> > While using performance gov seems stables at 1.5Ghz, it still crashes
> > using a dynamic gov (even with Andre reparenting patch), so let's drop
> > it for now, like manufacturer does.
> > 
> > Signed-off-by: Philippe Simons <simons.philippe at gmail.com
> 
> The change itself looks alright, bumping the OPP voltages by 50mV looks
> reasonable, and is a no-brainer if it stops the issues you have seen.
> 
> The loss of the 1.5GHz top OPP is a bummer, but stability comes definitely
> first, otherwise we will just fail faster ;-)
> 
> I would like to hear opinions from Ryan and Chris (both CC:ed). Did you see
> similar issues with say the ondemand governor?
> 
> The patch itself looks correct, so for that:
> 
> Reviewed-by: Andre Przywara <andre.przywara at arm.com>
> 
> Cheers,
> Andre

Issues I've seen with the crashes seem to have been resolved with this
series here: https://lore.kernel.org/all/CADomA4-xTcPyFcX_qCYJwoi7y5vfYmzOfF9iO5MKgEzZdpbJCQ at mail.gmail.com/

That said, I've tested these changes too and noticed no issues with it.
It didn't fix any of the issues I've observed but didn't appear to
cause any new ones either. I'll add my tested-by since I don't see any
new issues it introduces. I've been running them for the past week
while I attempt to solve a new regression for the AXP717 in 6.13-rc1.

Tested-by: Chris Morgan <macromorgan at hotmail.com>

> 
> > ---
> >   .../dts/allwinner/sun50i-h616-cpu-opp.dtsi    | 19 +++++++++----------
> >   1 file changed, 9 insertions(+), 10 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
> > index dd10aaf47..ac13fe169 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
> > @@ -50,24 +50,21 @@ opp-1008000000 {
> >   			opp-microvolt-speed2 = <950000>;
> >   			opp-microvolt-speed3 = <950000>;
> >   			opp-microvolt-speed4 = <1020000>;
> > -			opp-microvolt-speed5 = <900000>;
> > +			opp-microvolt-speed5 = <950000>;
> >   			clock-latency-ns = <244144>; /* 8 32k periods */
> >   			opp-supported-hw = <0x3f>;
> >   		};
> >   		opp-1032000000 {
> >   			opp-hz = /bits/ 64 <1032000000>;
> > -			opp-microvolt = <900000>;
> > +			opp-microvolt = <950000>;
> >   			clock-latency-ns = <244144>; /* 8 32k periods */
> >   			opp-supported-hw = <0x20>;
> >   		};
> >   		opp-1104000000 {
> >   			opp-hz = /bits/ 64 <1104000000>;
> > -			opp-microvolt-speed0 = <1000000>;
> > -			opp-microvolt-speed2 = <1000000>;
> > -			opp-microvolt-speed3 = <1000000>;
> > -			opp-microvolt-speed5 = <950000>;
> > +			opp-microvolt = <1000000>;			
> >   			clock-latency-ns = <244144>; /* 8 32k periods */
> >   			opp-supported-hw = <0x2d>;
> >   		};
> > @@ -79,7 +76,7 @@ opp-1200000000 {
> >   			opp-microvolt-speed2 = <1050000>;
> >   			opp-microvolt-speed3 = <1050000>;
> >   			opp-microvolt-speed4 = <1100000>;
> > -			opp-microvolt-speed5 = <1020000>;
> > +			opp-microvolt-speed5 = <1050000>;
> >   			clock-latency-ns = <244144>; /* 8 32k periods */
> >   			opp-supported-hw = <0x3f>;
> >   		};
> > @@ -93,7 +90,10 @@ opp-1320000000 {
> >   		opp-1416000000 {
> >   			opp-hz = /bits/ 64 <1416000000>;
> > -			opp-microvolt = <1100000>;
> > +			opp-microvolt-speed0 = <1100000>;
> > +			opp-microvolt-speed2 = <1100000>;
> > +			opp-microvolt-speed3 = <1100000>;
> > +			opp-microvolt-speed5 = <1160000>;
> >   			clock-latency-ns = <244144>; /* 8 32k periods */
> >   			opp-supported-hw = <0x2d>;
> >   		};
> > @@ -102,9 +102,8 @@ opp-1512000000 {
> >   			opp-hz = /bits/ 64 <1512000000>;
> >   			opp-microvolt-speed1 = <1100000>;
> >   			opp-microvolt-speed3 = <1100000>;
> > -			opp-microvolt-speed5 = <1160000>;
> >   			clock-latency-ns = <244144>; /* 8 32k periods */
> > -			opp-supported-hw = <0x2a>;
> > +			opp-supported-hw = <0x0a>;
> >   		};
> >   	};
> >   };


From mhklinux at outlook.com  Sat Dec  7 18:59:54 2024
From: mhklinux at outlook.com (Michael Kelley)
Date: Sun, 8 Dec 2024 02:59:54 +0000
Subject: [PATCH 0/2] hyperv: Move some features to common code
In-Reply-To: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
References: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <SN6PR02MB41573F55DBAAF124CFD92840D4332@SN6PR02MB4157.namprd02.prod.outlook.com>

From: Nuno Das Neves <nunodasneves at linux.microsoft.com> Sent: Friday, December 6, 2024 2:22 PM
> 
> There are several bits of Hyper-V-related code that today live in
> arch/x86 but are not really specific to x86_64 and will work on arm64
> too.
> 
> Some of these will be needed in the upcoming mshv driver code (for
> Linux as root partition on Hyper-V).

Previously, Linux as the root partition on Hyper-V was x86 only, which is
why the code is currently under arch/x86. So evidently the mshv driver
is being expanded to support both x86 and arm64, correct? Assuming
that's the case, I have some thoughts about how the source code should
be organized and built. It's probably best to get this right to start with so
it doesn't need to be changed again.

* Patch 2 of this series moves hv_call_deposit_pages() and
   hv_call_create_vp() to common code, but does not move
   hv_call_add_logical_proc(). All three are used together, so
   I'm wondering why hv_call_add_logical_proc() isn't moved.

* These three functions were originally put in a separate source
   code file because of being specific to running in the root partition,
   and not needed for generic Linux guest support. I think there's
   value in keeping them in a separate file, rather than merging them
   into hv_common.c. Maybe just move the entire hv_proc.c file?
   And then later, perhaps move the entire irqdomain.c file as well?
   There's also an interesting question of whether to move them into
   drivers/hv, or create a new directory virt/hyperv. Hyper-V support
   started out 15 years ago structured as a driver, hence "drivers/hv".
   But over the time, the support has become significantly more than
   just a driver, so "virt/hyperv" might be a better location for
   non-driver code that had previously been under arch/x86 but is
   now common to all architectures.

* Today, the code for running in the root partition is built along
   with the rest of the Hyper-V support, and so is present in kernels
   built for normal Linux guests on Hyper-V. I haven't thought about
   all the implications, but perhaps there's value in having a CONFIG
   option to build for the root partition, so that code can be dropped
   from normal kernels. There's a significant amount of new code still
   to come for mshv that could be excluded from normal guests in this
   way. Also, the tests of the hv_root_partition variable could be
   changed to a function the compiler detects is always "false" in a
   kernel built without the CONFIG option, in which case it can drop
   the code for where hv_root_partition is "true".

* The code currently in hv_proc.c is built for x86 only, and validly
   assumes the page size is 4K. But when the code moves to be
   common across architectures, that assumption is no longer
   valid in the general case. Perhaps the intent is that kernels for
   the root partition should always be built with page size 4K on
   arm64, but nothing enforces that intent. Personally, I think the code
   should be made to work with page sizes other than 4K so as to not
   leave technical debt. But I realize you may have other priorities. If
   there were a CONFIG option for building for the root partition,
   that option could be setup to enforce the 4K page size on arm64.

Anyway, thinking through these decisions up front could avoid
the need for additional moves later on.

Michael

> So this is a good time to move
> them to hv_common.c.
> 
> Signed-off-by: Nuno Das Neves <nudasnev at microsoft.com>
> 
> Nuno Das Neves (2):
>   hyperv: Move hv_current_partition_id to arch-generic code
>   hyperv: Move create_vp and deposit_pages hvcalls to hv_common.c
> 
>  arch/arm64/hyperv/mshyperv.c    |   3 +
>  arch/x86/hyperv/hv_init.c       |  25 +----
>  arch/x86/hyperv/hv_proc.c       | 144 ---------------------------
>  arch/x86/include/asm/mshyperv.h |   4 -
>  drivers/hv/hv_common.c          | 168 ++++++++++++++++++++++++++++++++
>  include/asm-generic/mshyperv.h  |   4 +
>  6 files changed, 176 insertions(+), 172 deletions(-)
> 
> --
> 2.34.1



From mhklinux at outlook.com  Sat Dec  7 19:01:37 2024
From: mhklinux at outlook.com (Michael Kelley)
Date: Sun, 8 Dec 2024 03:01:37 +0000
Subject: [PATCH 1/2] hyperv: Move hv_current_partition_id to arch-generic
 code
In-Reply-To: <1733523707-15954-2-git-send-email-nunodasneves@linux.microsoft.com>
References: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
 <1733523707-15954-2-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <SN6PR02MB4157E39FBEFB18EB9A695EECD4332@SN6PR02MB4157.namprd02.prod.outlook.com>

From: Nuno Das Neves <nunodasneves at linux.microsoft.com> Sent: Friday, December 6, 2024 2:22 PM
> 
> Make hv_current_partition_id available in both x86_64 and arm64.
> This feature isn't specific to x86_64 and will be needed by common
> code.
> 
> While at it, replace the BUG()s with WARN()s. Failing to get the id
> need not crash the machine (although it is a very bad sign).
> 
> Signed-off-by: Nuno Das Neves <nudasnev at microsoft.com>
> ---
>  arch/arm64/hyperv/mshyperv.c    |  3 +++
>  arch/x86/hyperv/hv_init.c       | 25 +------------------------
>  arch/x86/include/asm/mshyperv.h |  2 --
>  drivers/hv/hv_common.c          | 23 +++++++++++++++++++++++
>  include/asm-generic/mshyperv.h  |  2 ++
>  5 files changed, 29 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index b1a4de4eee29..5050e748d266 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -19,6 +19,9 @@
> 
>  static bool hyperv_initialized;
> 
> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
> +EXPORT_SYMBOL_GPL(hv_current_partition_id);
> +

Instead of adding a definition of hv_current_partition_id on
the arm64 side, couldn't the definition on the x86 side in
hv_init.c be moved to hv_common.c (or maybe somewhere
else that is specific to running in the root partition, per my
comments in the cover letter), so there is only one definition
shared by both architectures?

>  int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
>  {
>  	hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index 95eada2994e1..950f5ccdb9d9 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -35,7 +35,7 @@
>  #include <clocksource/hyperv_timer.h>
>  #include <linux/highmem.h>
> 
> -u64 hv_current_partition_id = ~0ull;
> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
>  EXPORT_SYMBOL_GPL(hv_current_partition_id);
> 
>  void *hv_hypercall_pg;
> @@ -394,24 +394,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
>  		old_setup_percpu_clockev();
>  }
> 
> -static void __init hv_get_partition_id(void)
> -{
> -	struct hv_get_partition_id *output_page;
> -	u64 status;
> -	unsigned long flags;
> -
> -	local_irq_save(flags);
> -	output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
> -	status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
> -	if (!hv_result_success(status)) {
> -		/* No point in proceeding if this failed */
> -		pr_err("Failed to get partition ID: %lld\n", status);
> -		BUG();
> -	}
> -	hv_current_partition_id = output_page->partition_id;
> -	local_irq_restore(flags);
> -}
> -
>  #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
>  static u8 __init get_vtl(void)
>  {
> @@ -606,11 +588,6 @@ void __init hyperv_init(void)
> 
>  	register_syscore_ops(&hv_syscore_ops);
> 
> -	if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
> -		hv_get_partition_id();
> -
> -	BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);
> -
>  #ifdef CONFIG_PCI_MSI
>  	/*
>  	 * If we're running as root, we want to create our own PCI MSI domain.
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index 5f0bc6a6d025..9eeca2a6d047 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -44,8 +44,6 @@ extern bool hyperv_paravisor_present;
> 
>  extern void *hv_hypercall_pg;
> 
> -extern u64 hv_current_partition_id;
> -
>  extern union hv_ghcb * __percpu *hv_ghcb_pg;
> 
>  bool hv_isolation_type_snp(void);
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index 7a35c82976e0..819bcfd2b149 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -278,11 +278,34 @@ static void hv_kmsg_dump_register(void)
>  	}
>  }
> 
> +static void __init hv_get_partition_id(void)
> +{
> +	struct hv_get_partition_id *output_page;
> +	u64 status;
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
> +	output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
> +	status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
> +	if (!hv_result_success(status)) {
> +		local_irq_restore(flags);
> +		WARN(true, "Failed to get partition ID: %lld\n", status);
> +		return;
> +	}
> +	hv_current_partition_id = output_page->partition_id;
> +	local_irq_restore(flags);
> +}
> +
>  int __init hv_common_init(void)
>  {
>  	int i;
>  	union hv_hypervisor_version_info version;
> 
> +	if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
> +		hv_get_partition_id();

hv_get_partition_id() uses the hyperv_pcpu_output_arg, and at
this point, hyperv_pcpu_output_arg isn't set. That setup
is done later in hv_common_init().

> +
> +	WARN_ON(hv_root_partition && hv_current_partition_id == HV_PARTITION_ID_SELF);
> +

Since the hypercall will fail cleanly if the calling VM doesn't
have the HV_ACCESS_PARTITION_ID privilege, could the
above be simplified to just this?

	if (hv_root_partition)
		hv_get_partition_id():

A non-root partition VM doesn't need to get the partition ID, while a
root partition should have the privilege. If the hypercall fails, there's
already a WARN, so there's no value in doing another WARN. Also if
the hypercall succeeds, it presumably returns a specific partitionID, not
HV_PARTITION_ID_SELF, so we know we have what we want.

There's already an "if (hv_root_partition)" statement for setting up
the hyperv_pcpu_output_arg. The call to hv_get_partition_id() could
go under that existing "if" *after* the hyperv_pcpu_output_arg is
set. :-)

Michael

>  	/* Get information about the Hyper-V host version */
>  	if (!hv_get_hypervisor_version(&version))
>  		pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> index 8fe7aaab2599..8c4ff6e9aae7 100644
> --- a/include/asm-generic/mshyperv.h
> +++ b/include/asm-generic/mshyperv.h
> @@ -60,6 +60,8 @@ struct ms_hyperv_info {
>  extern struct ms_hyperv_info ms_hyperv;
>  extern bool hv_nested;
> 
> +extern u64 hv_current_partition_id;
> +
>  extern void * __percpu *hyperv_pcpu_input_arg;
>  extern void * __percpu *hyperv_pcpu_output_arg;
> 
> --
> 2.34.1



From daniel at makrotopia.org  Sat Dec  7 19:01:38 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 8 Dec 2024 03:01:38 +0000
Subject: [PATCH net-next 2/3] net: pcs: pcs-mtk-lynxi: implement
 pcs_inband_caps() method
In-Reply-To: <E1tJ8NR-006L5P-E3@rmk-PC.armlinux.org.uk>
References: <Z1F1b8eh8s8T627j@shell.armlinux.org.uk>
 <E1tJ8NR-006L5P-E3@rmk-PC.armlinux.org.uk>
Message-ID: <Z1UMEnlZ_ivTsru5@pidgin.makrotopia.org>

On Thu, Dec 05, 2024 at 09:42:29AM +0000, Russell King (Oracle) wrote:
> Report the PCS in-band capabilities to phylink for the LynxI PCS.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  drivers/net/pcs/pcs-mtk-lynxi.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
> index 4f63abe638c4..7de804535229 100644
> --- a/drivers/net/pcs/pcs-mtk-lynxi.c
> +++ b/drivers/net/pcs/pcs-mtk-lynxi.c
> @@ -88,6 +88,21 @@ static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
>  	return container_of(pcs, struct mtk_pcs_lynxi, pcs);
>  }
>  
> +static unsigned int mtk_pcs_lynxi_inband_caps(struct phylink_pcs *pcs,
> +					      phy_interface_t interface)
> +{
> +	switch (interface) {
> +	case PHY_INTERFACE_MODE_1000BASEX:
> +	case PHY_INTERFACE_MODE_2500BASEX:
> +	case PHY_INTERFACE_MODE_SGMII:
> +	case PHY_INTERFACE_MODE_QSGMII:

QSGMII is not supported by this PCS.

Apart from that looks good to me.

Reviewed-by: Daniel Golle <daniel at makrotopia.org>



From itaru.kitayama at linux.dev  Sat Dec  7 20:38:39 2024
From: itaru.kitayama at linux.dev (Itaru Kitayama)
Date: Sun, 8 Dec 2024 13:38:39 +0900
Subject: [PATCH v3 1/1] arm64: rsi: Add automatic arm-cca-guest module
 loading
In-Reply-To: <20241207012128.247522-2-jeremy.linton@arm.com>
References: <20241207012128.247522-1-jeremy.linton@arm.com>
 <20241207012128.247522-2-jeremy.linton@arm.com>
Message-ID: <Z1Uiz7Hn2XisyP-N@vm3>

Hi Jeremy,

On Fri, Dec 06, 2024 at 07:21:28PM -0600, Jeremy Linton wrote:
> The TSM module provides guest identification and attestation when a
> guest runs in CCA mode. By creating a dummy platform device, let's

Perhaps could you spell out like; a guest runs in the Realm state?

Thanks,
Itaru.
 
> ensure the module is automatically loaded. The udev daemon loads the
> TSM module after it receives a device addition event. Once that
> happens, it can be used earlier in the boot process to decrypt the
> rootfs.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> Reviewed-by: Gavin Shan <gshan at redhat.com>
> ---
>  arch/arm64/include/asm/rsi.h                    |  2 ++
>  arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
>  drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
>  3 files changed, 25 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
> index 188cbb9b23f5..b42aeac05340 100644
> --- a/arch/arm64/include/asm/rsi.h
> +++ b/arch/arm64/include/asm/rsi.h
> @@ -10,6 +10,8 @@
>  #include <linux/jump_label.h>
>  #include <asm/rsi_cmds.h>
>  
> +#define RSI_PDEV_NAME "arm-cca-dev"
> +
>  DECLARE_STATIC_KEY_FALSE(rsi_present);
>  
>  void __init arm64_rsi_init(void);
> diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
> index 3031f25c32ef..5434e5496ac2 100644
> --- a/arch/arm64/kernel/rsi.c
> +++ b/arch/arm64/kernel/rsi.c
> @@ -8,6 +8,7 @@
>  #include <linux/psci.h>
>  #include <linux/swiotlb.h>
>  #include <linux/cc_platform.h>
> +#include <linux/platform_device.h>
>  
>  #include <asm/io.h>
>  #include <asm/mem_encrypt.h>
> @@ -140,3 +141,17 @@ void __init arm64_rsi_init(void)
>  	static_branch_enable(&rsi_present);
>  }
>  
> +static struct platform_device rsi_dev = {
> +	.name = RSI_PDEV_NAME,
> +	.id = PLATFORM_DEVID_NONE
> +};
> +
> +static int __init rsi_init(void)
> +{
> +	if (is_realm_world() &&
> +	    platform_device_register(&rsi_dev))
> +		pr_err("failed to register rsi platform device\n");
> +	return 0;
> +}
> +
> +arch_initcall(rsi_init)
> diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
> index 488153879ec9..87f162736b2e 100644
> --- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
> +++ b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
> @@ -6,6 +6,7 @@
>  #include <linux/arm-smccc.h>
>  #include <linux/cc_platform.h>
>  #include <linux/kernel.h>
> +#include <linux/mod_devicetable.h>
>  #include <linux/module.h>
>  #include <linux/smp.h>
>  #include <linux/tsm.h>
> @@ -219,6 +220,13 @@ static void __exit arm_cca_guest_exit(void)
>  }
>  module_exit(arm_cca_guest_exit);
>  
> +/* modalias, so userspace can autoload this module when RSI is available */
> +static const struct platform_device_id arm_cca_match[] __maybe_unused = {
> +	{ RSI_PDEV_NAME, 0},
> +	{ }
> +};
> +
> +MODULE_DEVICE_TABLE(platform, arm_cca_match);
>  MODULE_AUTHOR("Sami Mujawar <sami.mujawar at arm.com>");
>  MODULE_DESCRIPTION("Arm CCA Guest TSM Driver");
>  MODULE_LICENSE("GPL");
> -- 
> 2.46.0
> 


From 0x1207 at gmail.com  Sat Dec  7 23:02:02 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Sun,  8 Dec 2024 15:02:02 +0800
Subject: [PATCH net-next v1] net: stmmac: Relocate extern declarations in common.h and hwif.h
Message-ID: <20241208070202.203931-1-0x1207@gmail.com>

The extern declarations should be in a header file that corresponds to
their definition, move these extern declarations to its header file.
Some of them have nowhere to go, so move them to hwif.h since they are
referenced in hwif.c only.

dwmac100_* dwmac1000_* dwmac4_* dwmac410_* dwmac510_* stay in hwif.h,
otherwise you will be flooded with name conflicts from dwmac100.h,
dwmac1000.h and dwmac4.h if hwif.c try to #include these .h files.

Compile tested only.
No functional change intended.

Suggested-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Furong Xu <0x1207 at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h     | 14 --------------
 .../net/ethernet/stmicro/stmmac/dwmac4_descs.h   |  3 +++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h   |  5 +++++
 drivers/net/ethernet/stmicro/stmmac/hwif.c       |  2 ++
 drivers/net/ethernet/stmicro/stmmac/hwif.h       | 16 +++++++++-------
 drivers/net/ethernet/stmicro/stmmac/mmc.h        |  3 +++
 drivers/net/ethernet/stmicro/stmmac/stmmac_est.h |  2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h |  3 +++
 8 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1367fa5c9b8e..fbcf07d201cf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -543,18 +543,8 @@ struct dma_features {
 #define STMMAC_VLAN_INSERT	0x2
 #define STMMAC_VLAN_REPLACE	0x3
 
-extern const struct stmmac_desc_ops enh_desc_ops;
-extern const struct stmmac_desc_ops ndesc_ops;
-
 struct mac_device_info;
 
-extern const struct stmmac_hwtimestamp stmmac_ptp;
-extern const struct stmmac_hwtimestamp dwmac1000_ptp;
-extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;
-
-extern const struct ptp_clock_info stmmac_ptp_clock_ops;
-extern const struct ptp_clock_info dwmac1000_ptp_clock_ops;
-
 struct mac_link {
 	u32 caps;
 	u32 speed_mask;
@@ -641,8 +631,4 @@ void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable);
 
 void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
 
-extern const struct stmmac_mode_ops ring_mode_ops;
-extern const struct stmmac_mode_ops chain_mode_ops;
-extern const struct stmmac_desc_ops dwmac4_desc_ops;
-
 #endif /* __COMMON_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
index 1ce6f43d545a..806555976496 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
@@ -144,4 +144,7 @@
 /* TDS3 use for both format (read and write back) */
 #define RDES3_OWN			BIT(31)
 
+extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;
+extern const struct stmmac_desc_ops dwmac4_desc_ops;
+
 #endif /* __DWMAC4_DESCS_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index a04a79003692..20027d3c25a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -493,4 +493,9 @@
 #define XGMAC_RDES3_TSD			BIT(6)
 #define XGMAC_RDES3_TSA			BIT(4)
 
+extern const struct stmmac_ops dwxgmac210_ops;
+extern const struct stmmac_ops dwxlgmac2_ops;
+extern const struct stmmac_dma_ops dwxgmac210_dma_ops;
+extern const struct stmmac_desc_ops dwxgmac210_desc_ops;
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index a72d336a8350..4bd79de2e222 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -9,6 +9,8 @@
 #include "stmmac_fpe.h"
 #include "stmmac_ptp.h"
 #include "stmmac_est.h"
+#include "dwmac4_descs.h"
+#include "dwxgmac2.h"
 
 static u32 stmmac_get_id(struct stmmac_priv *priv, u32 id_reg)
 {
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 64f8ed67dcc4..e428c82b7d31 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -665,6 +665,15 @@ struct stmmac_regs_off {
 	u32 est_off;
 };
 
+extern const struct stmmac_desc_ops enh_desc_ops;
+extern const struct stmmac_desc_ops ndesc_ops;
+
+extern const struct stmmac_hwtimestamp stmmac_ptp;
+extern const struct stmmac_hwtimestamp dwmac1000_ptp;
+
+extern const struct stmmac_mode_ops ring_mode_ops;
+extern const struct stmmac_mode_ops chain_mode_ops;
+
 extern const struct stmmac_ops dwmac100_ops;
 extern const struct stmmac_dma_ops dwmac100_dma_ops;
 extern const struct stmmac_ops dwmac1000_ops;
@@ -677,13 +686,6 @@ extern const struct stmmac_ops dwmac510_ops;
 extern const struct stmmac_tc_ops dwmac4_tc_ops;
 extern const struct stmmac_tc_ops dwmac510_tc_ops;
 extern const struct stmmac_tc_ops dwxgmac_tc_ops;
-extern const struct stmmac_ops dwxgmac210_ops;
-extern const struct stmmac_ops dwxlgmac2_ops;
-extern const struct stmmac_dma_ops dwxgmac210_dma_ops;
-extern const struct stmmac_desc_ops dwxgmac210_desc_ops;
-extern const struct stmmac_mmc_ops dwmac_mmc_ops;
-extern const struct stmmac_mmc_ops dwxgmac_mmc_ops;
-extern const struct stmmac_est_ops dwmac510_est_ops;
 
 #define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
 #define GMAC4_VERSION		0x00000110	/* GMAC4+ CORE Version */
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h
index 5d1ea3e07459..1cba39fb2c44 100644
--- a/drivers/net/ethernet/stmicro/stmmac/mmc.h
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h
@@ -139,4 +139,7 @@ struct stmmac_counters {
 	unsigned int mmc_rx_fpe_fragment_cntr;
 };
 
+extern const struct stmmac_mmc_ops dwmac_mmc_ops;
+extern const struct stmmac_mmc_ops dwxgmac_mmc_ops;
+
 #endif /* __MMC_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_est.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_est.h
index 7a858c566e7e..d247fa383a6e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_est.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_est.h
@@ -62,3 +62,5 @@
 #define EST_SRWO			BIT(0)
 
 #define EST_GCL_DATA			0x00000034
+
+extern const struct stmmac_est_ops dwmac510_est_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
index 4cc70480ce0f..3fe0e3a80e80 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
@@ -104,4 +104,7 @@ int dwmac1000_ptp_enable(struct ptp_clock_info *ptp,
 void dwmac1000_get_ptptime(void __iomem *ptpaddr, u64 *ptp_time);
 void dwmac1000_timestamp_interrupt(struct stmmac_priv *priv);
 
+extern const struct ptp_clock_info stmmac_ptp_clock_ops;
+extern const struct ptp_clock_info dwmac1000_ptp_clock_ops;
+
 #endif	/* __STMMAC_PTP_H__ */
-- 
2.34.1



From linux at armlinux.org.uk  Sun Dec  8 01:13:11 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 8 Dec 2024 09:13:11 +0000
Subject: [PATCH net-next 2/3] net: pcs: pcs-mtk-lynxi: implement
 pcs_inband_caps() method
In-Reply-To: <Z1UMEnlZ_ivTsru5@pidgin.makrotopia.org>
References: <Z1F1b8eh8s8T627j@shell.armlinux.org.uk>
 <E1tJ8NR-006L5P-E3@rmk-PC.armlinux.org.uk>
 <Z1UMEnlZ_ivTsru5@pidgin.makrotopia.org>
Message-ID: <Z1VjJ8ago-HetCxi@shell.armlinux.org.uk>

On Sun, Dec 08, 2024 at 03:01:38AM +0000, Daniel Golle wrote:
> On Thu, Dec 05, 2024 at 09:42:29AM +0000, Russell King (Oracle) wrote:
> > Report the PCS in-band capabilities to phylink for the LynxI PCS.
> > 
> > Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> > ---
> >  drivers/net/pcs/pcs-mtk-lynxi.c | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> > 
> > diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
> > index 4f63abe638c4..7de804535229 100644
> > --- a/drivers/net/pcs/pcs-mtk-lynxi.c
> > +++ b/drivers/net/pcs/pcs-mtk-lynxi.c
> > @@ -88,6 +88,21 @@ static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
> >  	return container_of(pcs, struct mtk_pcs_lynxi, pcs);
> >  }
> >  
> > +static unsigned int mtk_pcs_lynxi_inband_caps(struct phylink_pcs *pcs,
> > +					      phy_interface_t interface)
> > +{
> > +	switch (interface) {
> > +	case PHY_INTERFACE_MODE_1000BASEX:
> > +	case PHY_INTERFACE_MODE_2500BASEX:
> > +	case PHY_INTERFACE_MODE_SGMII:
> > +	case PHY_INTERFACE_MODE_QSGMII:
> 
> QSGMII is not supported by this PCS.

Well...
- lynx_pcs_get_state(), lynx_pcs_config(), and lynx_pcs_link_up()
  include QSGMII in their case statements.
- lynx_pcs_config_giga() refers to QSGMII in a comment, grouping it
  with SGMII configuration.

I think if the hardware doesn't support QSGMII, these references to it
should be removed?

I also think that adding a .pcs_validate() method would be a good idea
to reject interface modes that the PCS does not support.

> Apart from that looks good to me.
> 
> Reviewed-by: Daniel Golle <daniel at makrotopia.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 muecker at gwdg.de  Sun Dec  8 01:18:40 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sun, 8 Dec 2024 10:18:40 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=wgVGmj+nAju2XuWWD_FZHdeytRW2XX5D-L3MqDuRRciVg@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
	 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>
	 <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
	 <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de>
	 <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>
	 <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de>
	 <CAHk-=wgVGmj+nAju2XuWWD_FZHdeytRW2XX5D-L3MqDuRRciVg@mail.gmail.com>
Message-ID: <aeb1c27d320800dcd8375771022e11e8c27b0d1a.camel@gwdg.de>

Am Samstag, dem 07.12.2024 um 17:58 -0800 schrieb Linus Torvalds:
> On Sat, 7 Dec 2024 at 15:52, Martin Uecker <muecker at gwdg.de> wrote:
> > 
> > Can you point me to some horror stories?
> 
> So the main issues tended to be about various static verification tools.
> 
> Ranging from things like the stackleak plugin for gcc, where handling
> VLA's and alloca() (which are pretty much the same thing with
> different syntax) was just very much added complexity, to perhaps
> overly simplistic tools that literally just check the stack usage by
> parsing "objdump --disassemble" output and then building up
> approximate "this is the combined deepest stack" call chain
> approximations.
> 
> And even in the *basic* infrastructure like gcc itself, VLA's simply
> made -Wframe-larger-than= just simply not work.
> 
> I also have this memory of bad code generation (again, this is 5=
> years ago, so take this with a pinch of salt: dim memories), where gcc
> wouldn't end up re-using VLA stack slots, so VLA's made the frame
> bigger for that reason or something like that.
> 
> We explicitly use "-fconserve-stack" to get gcc to reuse spill slots,
> because gcc has been known to sometimes makes insanely piggish stack
> frames when it just creates a spill slot for *everything*, even if the
> spills aren't live at the same time (think big functions with lots of
> case statements).
> 
> We also had several cases of the VLA's just being silly, when a simple
> constant-sized allocation just worked fine and didn't generate
> pointless extra code.
> 
> Pretty much none of the code core actually ever wanted VLA's, so the
> end result was that we had these bad patterns mainly in random drivers
> etc. Don't do that.

Thanks. This confirms that the tooling around VLAs is rather poor.


Martin








From dmitry.baryshkov at linaro.org  Sun Dec  8 03:06:46 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sun, 8 Dec 2024 13:06:46 +0200
Subject: [PATCH v6 09/10] drm/vc4: hdmi: stop rereading EDID in
 get_modes()
In-Reply-To: <20241206-caped-proficient-rattlesnake-c882f3@houat>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-9-50dc145a9c06@linaro.org>
 <20241206-caped-proficient-rattlesnake-c882f3@houat>
Message-ID: <73xdxb575n4ncmadffkwqzczoewbadq3forpvqt4vp7zfln2nq@o2wmbbbepwgg>

On Fri, Dec 06, 2024 at 03:34:52PM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Fri, Dec 06, 2024 at 12:16:03PM +0200, Dmitry Baryshkov wrote:
> > The vc4_hdmi_connector_detect_ctx() via vc4_hdmi_handle_hotplug()
> > already reads EDID and propagates it to the drm_connector. Stop
> > rereading EDID as a part of the .get_modes() callback and just update
> > the list of modes. This matches the behaviour of the i915 driver.
> > 
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >  drivers/gpu/drm/vc4/vc4_hdmi.c | 21 ---------------------
> >  1 file changed, 21 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > index e5ab42f72f618b90f956482db6c9c8074c1e3bf1..3364ef90968dad3074800f02926300ffceb75c69 100644
> > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > @@ -470,31 +470,10 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
> >  
> >  static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
> >  {
> > -	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
> >  	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
> > -	const struct drm_edid *drm_edid;
> >  	int ret = 0;
> >  
> > -	/*
> > -	 * NOTE: This function should really take vc4_hdmi->mutex, but doing so
> > -	 * results in reentrancy issues since cec_s_phys_addr() might call
> > -	 * .adap_enable, which leads to that funtion being called with our mutex
> > -	 * held.
> > -	 *
> > -	 * Concurrency isn't an issue at the moment since we don't share
> > -	 * any state with any of the other frameworks so we can ignore
> > -	 * the lock for now.
> > -	 */
> > -
> > -	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
> > -	drm_edid_connector_update(connector, drm_edid);
> > -	cec_s_phys_addr(vc4_hdmi->cec_adap,
> > -			connector->display_info.source_physical_address, false);
> > -	if (!drm_edid)
> > -		return 0;
> > -
> >  	ret = drm_edid_connector_add_modes(connector);
> > -	drm_edid_free(drm_edid);
> 
> I don't think that works though, for mostly two reasons:
> 
>  1) We're not sure we'll even have an hotplug interrupt if the system
>     boots with the connector plugged in for example.
> 
>  2) afaik, the get_modes ioctl directly calls get_modes too.

I think both paths use .fill_modes, not get_modes. And fill_modes
explicitly calls .detect / .detect_ctx. It would be nice if somebody can
verify the change on the acual hw. But as I wrote, i915 driver does
exactly the same: the EDID is read / updated in .detect_ctx(), while
.get_modes() only performs drm_edid_connector_add_modes().
Okay, there is one significant difference which we should probably patch
out: the .force() is also implemented to update EDID in the forced case.
I should probably do the same for the drivers being handled in this
patchset.

-- 
With best wishes
Dmitry


From David.Laight at ACULAB.COM  Sun Dec  8 03:26:44 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sun, 8 Dec 2024 11:26:44 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
	 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>
	 <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
	 <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de>
	 <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>
 <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de>
Message-ID: <b71056c1b9e04aa383f2e5608c27290f@AcuMS.aculab.com>

From: Martin Uecker
> Sent: 07 December 2024 23:52
...
> While the compiler can not automatically prove every use
> of VLA bounded, it can reliably diagnose the cases where it
> can?*not* see that it is bounded. Consider this example:
> 
> void oob(int n, char p[n]);
> void f(unsigned int n)
> {
>     char buf[MIN(n, 100)]; // bounded
>     oob(n + 10, buf); // warning
> }
...

The kernel stack has to have enough space for the [100]
so the full amount might as well always be allocated.
The chance of 'trading off' stack usage with another function
in the same call stack that is guaranteed to use less than
its maximum is about zero.

The VLA code also adds an extra stack frame, this pretty much
pessimises everything.
This happened for 'constant' sizes from min(16, sizeof (struct))
because min() needs to be a statement function to avoid re-evaluating
its arguments.
(The version of min() that managed to return constant from constant
input just exploded in cpp, partially responsible for 18MB lines
being fed into the compiler part.)

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From muecker at gwdg.de  Sun Dec  8 04:38:10 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sun, 8 Dec 2024 13:38:10 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <b71056c1b9e04aa383f2e5608c27290f@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
	 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>
	 <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
	 <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de>
	 <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>
	 <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de>
	 <b71056c1b9e04aa383f2e5608c27290f@AcuMS.aculab.com>
Message-ID: <6658618490381cf5ec35edbb66f1478024174e67.camel@gwdg.de>

Am Sonntag, dem 08.12.2024 um 11:26 +0000 schrieb David Laight:
> From: Martin Uecker
> > Sent: 07 December 2024 23:52
> ...
> > While the compiler can not automatically prove every use
> > of VLA bounded, it can reliably diagnose the cases where it
> > can?*not* see that it is bounded. Consider this example:
> > 
> > void oob(int n, char p[n]);
> > void f(unsigned int n)
> > {
> >     char buf[MIN(n, 100)]; // bounded
> >     oob(n + 10, buf); // warning
> > }
> ...
> 
> The kernel stack has to have enough space for the [100]
> so the full amount might as well always be allocated.
> The chance of 'trading off' stack usage with another function
> in the same call stack that is guaranteed to use less than
> its maximum is about zero.

In numerical computing this is a big motivation because
you can reduce stack usage in recursive divide-and-conquer
algorithms.  For the kernel, I agree this is not a
compelling use case, and the better motivation would be
precise bounds checking and clearer semantics for buffer
management. ?

But don't get me wrong, if the kernel is happier without VLA
this is fine with me, I am just trying to understand the
underlying issues better and the "VLAs are security problem"
or "VLA use more stack"  arguments do not convince me, while
the points Linus raises make much more sense to me.

> 
> The VLA code also adds an extra stack frame, this pretty much
> pessimises everything.

Yes, but this is something which seems could be improved
on the compiler side, e.g. by simply transforming
small VLAs automatically to a fixed size array while
preserving their semantics for bound checking.


> This happened for 'constant' sizes from min(16, sizeof (struct))
> because min() needs to be a statement function to avoid re-evaluating
> its arguments.

Can you clarify this?  If the VLA size is constant, even when
it is not an integer constant expression according to ISO C,
the compiler should not produce worse code.  For example,

void g(void*);

void foo()
{
    int n = 10;
    char buf[n];
    g(buf);
}

void bar()
{
    char buf[10];
    g(buf);
}

So a lot of this macro business seems to be necessary
to avoid creating warnings for ISO VLAs when instead you really
care about the created code not having a dynamic allocation on
the stack.

So one might wonder whether a compiler warning that warns more
specifically about this would help.

> (The version of min() that managed to return constant from constant
> input just exploded in cpp, partially responsible for 18MB lines
> being fed into the compiler part.)

The issue here is that we miss a language feature in C to
introduce local variables that help avoid multiple expansion
of macro arguments.  GCC's statement expressions and __auto_type
are a solution

#define foo(x) ({ __auto_type __x = (x); ... })

but this runs into the current limitations that ({ }) can not be used
at file-scope and can not return constant expressions.


For other reasons I was thinking about adding names to _Generic,
as in

_Generic(x, int i: (i + 1));

because one design issues with _Generic is that it typechecks?
also the untaken associations and there the 'x' then has the wrong
type.  Having an 'i' with the right type which is set to the value
of 'x' when the branch is taken would fix this issue.

But this feature might also allow writing macros that avoid
doublel expansion without requiring statement expressions (which
are more difficult to fix):

#define foo(x) _Generic(x, int i: (i + i));


Martin




From csokas.bence at prolan.hu  Sun Dec  8 04:36:19 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?=)
Date: Sun, 8 Dec 2024 13:36:19 +0100
Subject: [PATCH] dma-engine: sun4i: Use devm functions in probe()
Message-ID: <20241208123619.1007413-1-csokas.bence@prolan.hu>

Clean up error handling by using devm functions
and dev_err_probe(). This should make it easier
to add new code, as we can eliminate the "goto
ladder" in probe().

Suggested-by: Chen-Yu Tsai <wens at kernel.org>
Signed-off-by: Bence Cs?k?s <csokas.bence at prolan.hu>
---
 drivers/dma/sun4i-dma.c | 31 ++++++-------------------------
 1 file changed, 6 insertions(+), 25 deletions(-)

diff --git a/drivers/dma/sun4i-dma.c b/drivers/dma/sun4i-dma.c
index 24796aaaddfa..b10639720efd 100644
--- a/drivers/dma/sun4i-dma.c
+++ b/drivers/dma/sun4i-dma.c
@@ -1249,10 +1249,9 @@ static int sun4i_dma_probe(struct platform_device *pdev)
 	if (priv->irq < 0)
 		return priv->irq;
 
-	priv->clk = devm_clk_get(&pdev->dev, NULL);
+	priv->clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(priv->clk)) {
-		dev_err(&pdev->dev, "No clock specified\n");
-		return PTR_ERR(priv->clk);
+		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk), "Couldn't start the clock");
 	}
 
 	if (priv->cfg->has_reset) {
@@ -1328,12 +1327,6 @@ static int sun4i_dma_probe(struct platform_device *pdev)
 		vchan_init(&vchan->vc, &priv->slave);
 	}
 
-	ret = clk_prepare_enable(priv->clk);
-	if (ret) {
-		dev_err(&pdev->dev, "Couldn't enable the clock\n");
-		return ret;
-	}
-
 	/*
 	 * Make sure the IRQs are all disabled and accounted for. The bootloader
 	 * likes to leave these dirty
@@ -1344,32 +1337,23 @@ static int sun4i_dma_probe(struct platform_device *pdev)
 	ret = devm_request_irq(&pdev->dev, priv->irq, sun4i_dma_interrupt,
 			       0, dev_name(&pdev->dev), priv);
 	if (ret) {
-		dev_err(&pdev->dev, "Cannot request IRQ\n");
-		goto err_clk_disable;
+		return dev_err_probe(&pdev->dev, ret, "Cannot request IRQ");
 	}
 
-	ret = dma_async_device_register(&priv->slave);
+	ret = dmaenginem_async_device_register(&priv->slave);
 	if (ret) {
-		dev_warn(&pdev->dev, "Failed to register DMA engine device\n");
-		goto err_clk_disable;
+		return dev_err_probe(&pdev->dev, ret, "Failed to register DMA engine device");
 	}
 
 	ret = of_dma_controller_register(pdev->dev.of_node, sun4i_dma_of_xlate,
 					 priv);
 	if (ret) {
-		dev_err(&pdev->dev, "of_dma_controller_register failed\n");
-		goto err_dma_unregister;
+		return dev_err_probe(&pdev->dev, ret, "Failed to register translation function");
 	}
 
 	dev_dbg(&pdev->dev, "Successfully probed SUN4I_DMA\n");
 
 	return 0;
-
-err_dma_unregister:
-	dma_async_device_unregister(&priv->slave);
-err_clk_disable:
-	clk_disable_unprepare(priv->clk);
-	return ret;
 }
 
 static void sun4i_dma_remove(struct platform_device *pdev)
@@ -1380,9 +1364,6 @@ static void sun4i_dma_remove(struct platform_device *pdev)
 	disable_irq(priv->irq);
 
 	of_dma_controller_free(pdev->dev.of_node);
-	dma_async_device_unregister(&priv->slave);
-
-	clk_disable_unprepare(priv->clk);
 }
 
 static struct sun4i_dma_config sun4i_a10_dma_cfg = {
-- 
2.34.1




From manivannan.sadhasivam at linaro.org  Sun Dec  8 04:44:36 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sun, 8 Dec 2024 18:14:36 +0530
Subject: [PATCH v2] PCI: rockchip-ep: Fix error code in
 rockchip_pcie_ep_init_ob_mem()
In-Reply-To: <Z014ylYz_xrrgI4W@stanley.mountain>
References: <Z014ylYz_xrrgI4W@stanley.mountain>
Message-ID: <20241208124436.vicbi72xyomahp3s@thinkpad>

On Mon, Dec 02, 2024 at 12:07:22PM +0300, Dan Carpenter wrote:
> Return -ENOMEM if pci_epc_mem_alloc_addr() fails.  Don't return success.
> 
> Fixes: 945648019466 ("PCI: rockchip-ep: Refactor rockchip_pcie_ep_probe() memory allocations")
> Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

- Mani

> Reviewed-by: Damien Le Moal <dlemoal at kernel.org>
> ---
> v2: Update the git hash for the Fixes tag because the tree was rebased I guess.
> 
>  drivers/pci/controller/pcie-rockchip-ep.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
> index 1064b7b06cef..34162ca14093 100644
> --- a/drivers/pci/controller/pcie-rockchip-ep.c
> +++ b/drivers/pci/controller/pcie-rockchip-ep.c
> @@ -784,6 +784,7 @@ static int rockchip_pcie_ep_init_ob_mem(struct rockchip_pcie_ep *ep)
>  						  SZ_1M);
>  	if (!ep->irq_cpu_addr) {
>  		dev_err(dev, "failed to reserve memory space for MSI\n");
> +		err = -ENOMEM;
>  		goto err_epc_mem_exit;
>  	}
>  
> -- 
> 2.45.2
> 

-- 
????????? ????????


From jon.lin at rock-chips.com  Sun Dec  8 05:03:11 2024
From: jon.lin at rock-chips.com (Jon Lin)
Date: Sun,  8 Dec 2024 21:03:11 +0800
Subject: [PATCH] spi: rockchip-sfc: Support pm ops
Message-ID: <20241208130311.1324024-1-jon.lin@rock-chips.com>

Support system_sleep and runtime_pm ops.

Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

 drivers/spi/spi-rockchip-sfc.c | 148 ++++++++++++++++++++++++++++-----
 1 file changed, 128 insertions(+), 20 deletions(-)

diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
index 14f5b9346050..9146b56713b6 100644
--- a/drivers/spi/spi-rockchip-sfc.c
+++ b/drivers/spi/spi-rockchip-sfc.c
@@ -13,12 +13,14 @@
 #include <linux/completion.h>
 #include <linux/dma-mapping.h>
 #include <linux/iopoll.h>
+#include <linux/interrupt.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
-#include <linux/interrupt.h>
 #include <linux/spi/spi-mem.h>
 
 /* System control */
@@ -150,11 +152,9 @@
 /* Data */
 #define SFC_DATA			0x108
 
-/* The controller and documentation reports that it supports up to 4 CS
- * devices (0-3), however I have only been able to test a single CS (CS 0)
- * due to the configuration of my device.
- */
-#define SFC_MAX_CHIPSELECT_NUM		4
+#define SFC_CS1_REG_OFFSET		0x200
+
+#define SFC_MAX_CHIPSELECT_NUM		2
 
 /* The SFC can transfer max 16KB - 1 at one time
  * we set it to 15.5KB here for alignment.
@@ -169,12 +169,14 @@
  */
 #define SFC_MAX_SPEED		(150 * 1000 * 1000)
 
+#define ROCKCHIP_AUTOSUSPEND_DELAY	2000
+
 struct rockchip_sfc {
 	struct device *dev;
 	void __iomem *regbase;
 	struct clk *hclk;
 	struct clk *clk;
-	u32 frequency;
+	u32 speed[SFC_MAX_CHIPSELECT_NUM];
 	/* virtual mapped addr for dma_buffer */
 	void *buffer;
 	dma_addr_t dma_buffer;
@@ -301,6 +303,7 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
 				   u32 len)
 {
 	u32 ctrl = 0, cmd = 0;
+	u8 cs = spi_get_chipselect(mem->spi, 0);
 
 	/* set CMD */
 	cmd = op->cmd.opcode;
@@ -314,7 +317,8 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
 			cmd |= SFC_CMD_ADDR_24BITS << SFC_CMD_ADDR_SHIFT;
 		} else {
 			cmd |= SFC_CMD_ADDR_XBITS << SFC_CMD_ADDR_SHIFT;
-			writel(op->addr.nbytes * 8 - 1, sfc->regbase + SFC_ABIT);
+			writel(op->addr.nbytes * 8 - 1,
+			       sfc->regbase + cs * SFC_CS1_REG_OFFSET + SFC_ABIT);
 		}
 
 		ctrl |= ((op->addr.buswidth >> 1) << SFC_CTRL_ADDR_BITS_SHIFT);
@@ -346,7 +350,7 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
 
 	/* set the Controller */
 	ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;
-	cmd |= spi_get_chipselect(mem->spi, 0) << SFC_CMD_CS_SHIFT;
+	cmd |= cs << SFC_CMD_CS_SHIFT;
 
 	dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
 		op->addr.nbytes, op->addr.buswidth,
@@ -354,7 +358,7 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
 	dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n",
 		ctrl, cmd, op->addr.val, len);
 
-	writel(ctrl, sfc->regbase + SFC_CTRL);
+	writel(ctrl, sfc->regbase + cs * SFC_CS1_REG_OFFSET + SFC_CTRL);
 	writel(cmd, sfc->regbase + SFC_CMD);
 	if (op->addr.nbytes)
 		writel(op->addr.val, sfc->regbase + SFC_ADDR);
@@ -500,14 +504,22 @@ static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op
 	struct rockchip_sfc *sfc = spi_controller_get_devdata(mem->spi->controller);
 	u32 len = op->data.nbytes;
 	int ret;
+	u8 cs = spi_get_chipselect(mem->spi, 0);
+
+	ret = pm_runtime_get_sync(sfc->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(sfc->dev);
+		return ret;
+	}
 
-	if (unlikely(mem->spi->max_speed_hz != sfc->frequency) && !has_acpi_companion(sfc->dev)) {
+	if (unlikely(mem->spi->max_speed_hz != sfc->speed[cs]) &&
+	    !has_acpi_companion(sfc->dev)) {
 		ret = clk_set_rate(sfc->clk, mem->spi->max_speed_hz);
 		if (ret)
-			return ret;
-		sfc->frequency = mem->spi->max_speed_hz;
+			goto out;
+		sfc->speed[cs] = mem->spi->max_speed_hz;
 		dev_dbg(sfc->dev, "set_freq=%dHz real_freq=%ldHz\n",
-			sfc->frequency, clk_get_rate(sfc->clk));
+			sfc->speed[cs], clk_get_rate(sfc->clk));
 	}
 
 	rockchip_sfc_adjust_op_work((struct spi_mem_op *)op);
@@ -524,11 +536,17 @@ static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op
 		if (ret != len) {
 			dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir);
 
-			return -EIO;
+			ret = -EIO;
+			goto out;
 		}
 	}
 
-	return rockchip_sfc_xfer_done(sfc, 100000);
+	ret = rockchip_sfc_xfer_done(sfc, 100000);
+out:
+	pm_runtime_mark_last_busy(sfc->dev);
+	pm_runtime_put_autosuspend(sfc->dev);
+
+	return ret;
 }
 
 static int rockchip_sfc_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
@@ -570,6 +588,7 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
 	struct spi_controller *host;
 	struct rockchip_sfc *sfc;
 	int ret;
+	u32 i, val;
 
 	host = devm_spi_alloc_host(&pdev->dev, sizeof(*sfc));
 	if (!host)
@@ -602,9 +621,12 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
 				     "Failed to get sfc ahb clk\n");
 
 	if (has_acpi_companion(&pdev->dev)) {
-		ret = device_property_read_u32(&pdev->dev, "clock-frequency", &sfc->frequency);
+		ret = device_property_read_u32(&pdev->dev, "clock-frequency", &val);
 		if (ret)
-			return dev_err_probe(&pdev->dev, ret, "Failed to find clock-frequency\n");
+			return dev_err_probe(&pdev->dev, ret,
+					     "Failed to find clock-frequency in ACPI\n");
+		for (i = 0; i < SFC_MAX_CHIPSELECT_NUM; i++)
+			sfc->speed[i] = val;
 	}
 
 	sfc->use_dma = !of_property_read_bool(sfc->dev->of_node, "rockchip,sfc-no-dma");
@@ -646,6 +668,8 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
 		goto err_irq;
 	}
 
+	platform_set_drvdata(pdev, sfc);
+
 	ret = rockchip_sfc_init(sfc);
 	if (ret)
 		goto err_irq;
@@ -653,12 +677,27 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
 	sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
 	sfc->version = rockchip_sfc_get_version(sfc);
 
-	ret = spi_register_controller(host);
+	pm_runtime_set_autosuspend_delay(dev, ROCKCHIP_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_get_noresume(dev);
+
+	ret = devm_spi_register_controller(dev, host);
 	if (ret)
-		goto err_irq;
+		goto err_pm_runtime_free;
+
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
 
 	return 0;
 
+err_pm_runtime_free:
+	pm_runtime_get_sync(dev);
+	pm_runtime_put_noidle(dev);
+	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
+	pm_runtime_dont_use_autosuspend(dev);
 err_irq:
 	clk_disable_unprepare(sfc->clk);
 err_clk:
@@ -678,6 +717,74 @@ static void rockchip_sfc_remove(struct platform_device *pdev)
 	clk_disable_unprepare(sfc->hclk);
 }
 
+#ifdef CONFIG_PM
+static int rockchip_sfc_runtime_suspend(struct device *dev)
+{
+	struct rockchip_sfc *sfc = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(sfc->clk);
+	clk_disable_unprepare(sfc->hclk);
+
+	return 0;
+}
+
+static int rockchip_sfc_runtime_resume(struct device *dev)
+{
+	struct rockchip_sfc *sfc = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(sfc->hclk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare_enable(sfc->clk);
+	if (ret < 0)
+		clk_disable_unprepare(sfc->hclk);
+
+	return ret;
+}
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_sfc_suspend(struct device *dev)
+{
+	pinctrl_pm_select_sleep_state(dev);
+
+	return pm_runtime_force_suspend(dev);
+}
+
+static int rockchip_sfc_resume(struct device *dev)
+{
+	struct rockchip_sfc *sfc = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret < 0)
+		return ret;
+
+	pinctrl_pm_select_default_state(dev);
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
+
+	rockchip_sfc_init(sfc);
+
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops rockchip_sfc_pm_ops = {
+	SET_RUNTIME_PM_OPS(rockchip_sfc_runtime_suspend,
+			   rockchip_sfc_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(rockchip_sfc_suspend, rockchip_sfc_resume)
+};
+
 static const struct of_device_id rockchip_sfc_dt_ids[] = {
 	{ .compatible = "rockchip,sfc"},
 	{ /* sentinel */ }
@@ -688,6 +795,7 @@ static struct platform_driver rockchip_sfc_driver = {
 	.driver = {
 		.name	= "rockchip-sfc",
 		.of_match_table = rockchip_sfc_dt_ids,
+		.pm = &rockchip_sfc_pm_ops,
 	},
 	.probe	= rockchip_sfc_probe,
 	.remove = rockchip_sfc_remove,
-- 
2.34.1



From ni_liqiang at 126.com  Sun Dec  8 05:39:47 2024
From: ni_liqiang at 126.com (niliqiang)
Date: Sun,  8 Dec 2024 21:39:47 +0800
Subject: [PATCH] drivers/iommu: Protect STE base address in multi-core and  multi-process concurrent scenarios
In-Reply-To: <20241111142800.63760-1-ni_liqiang@126.com>
References: <20241111142800.63760-1-ni_liqiang@126.com>
Message-ID: <20241208133947.20871-1-ni_liqiang@126.com>

I found that the email sent by git send-email command was partially
successful, so please allow me to reply to the previous patch.

I look forward to the reply from experts. Thank you.



From krzk at kernel.org  Sun Dec  8 06:16:02 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 8 Dec 2024 15:16:02 +0100
Subject: [PATCH v3 02/13] dt-bindings: mfd: atmel,sama5d2-flexcom: add
 microchip,sama7d65-flexcom
In-Reply-To: <550a6dc244a9955782c5b9d7863df4e15bba8a26.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <550a6dc244a9955782c5b9d7863df4e15bba8a26.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <copmhri4e43sjk6uiahgmhkqk6kuhuvm3kmusptytww6l5qs2a@xejs5hq4a7gl>

On Fri, Dec 06, 2024 at 12:59:47PM -0700, Ryan.Wanner at microchip.com wrote:
> From: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Add flexcom binding documentation for sama7d65.
> 
> Consolidated entries into one enum to match proper coding style.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---
>  .../devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml   | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 

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

Best regards,
Krzysztof



From apatel at ventanamicro.com  Sun Dec  8 07:07:10 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sun,  8 Dec 2024 20:37:10 +0530
Subject: [PATCH 3/4] irqchip/riscv-imsic: Set irq_set_affinity for IMSIC base
In-Reply-To: <20241208150711.297624-1-apatel@ventanamicro.com>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
Message-ID: <20241208150711.297624-4-apatel@ventanamicro.com>

From: Andrew Jones <ajones at ventanamicro.com>

Instead of using imsic_irq_set_affinity() for non-leaf MSI domains,
use imsic_irq_set_affinity() for the leaf IMSIC base domain and use
irq_chip_set_affinity_parent() for non-leaf MSI domains.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 707c7ccb4d08..33a8261e6017 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -96,10 +96,9 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 				  bool force)
 {
 	struct imsic_vector *old_vec, *new_vec;
-	struct irq_data *pd = d->parent_data;
 	struct imsic_vector tmp_vec;
 
-	old_vec = irq_data_get_irq_chip_data(pd);
+	old_vec = irq_data_get_irq_chip_data(d);
 	if (WARN_ON(!old_vec))
 		return -ENOENT;
 
@@ -139,17 +138,17 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 		tmp_vec.local_id = new_vec->local_id;
 
 		/* Point device to the temporary vector */
-		imsic_msi_update_msg(d, &tmp_vec);
+		imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec);
 	}
 
 	/* Point device to the new vector */
-	imsic_msi_update_msg(d, new_vec);
+	imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec);
 
 	/* Update irq descriptors with the new vector */
-	pd->chip_data = new_vec;
+	d->chip_data = new_vec;
 
-	/* Update effective affinity of parent irq data */
-	irq_data_update_effective_affinity(pd, cpumask_of(new_vec->cpu));
+	/* Update effective affinity */
+	irq_data_update_effective_affinity(d, cpumask_of(new_vec->cpu));
 
 	/* Move state of the old vector to the new vector */
 	imsic_vector_move(old_vec, new_vec);
@@ -162,6 +161,9 @@ static struct irq_chip imsic_irq_base_chip = {
 	.name			= "IMSIC",
 	.irq_mask		= imsic_irq_mask,
 	.irq_unmask		= imsic_irq_unmask,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= imsic_irq_set_affinity,
+#endif
 	.irq_retrigger		= imsic_irq_retrigger,
 	.irq_compose_msi_msg	= imsic_irq_compose_msg,
 	.flags			= IRQCHIP_SKIP_SET_WAKE |
@@ -272,7 +274,7 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 		if (WARN_ON_ONCE(domain != real_parent))
 			return false;
 #ifdef CONFIG_SMP
-		info->chip->irq_set_affinity = imsic_irq_set_affinity;
+		info->chip->irq_set_affinity = irq_chip_set_affinity_parent;
 #endif
 		break;
 	default:
-- 
2.43.0



From apatel at ventanamicro.com  Sun Dec  8 07:07:11 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sun,  8 Dec 2024 20:37:11 +0530
Subject: [PATCH 4/4] irqchip/riscv-imsic: Move to common MSI lib
In-Reply-To: <20241208150711.297624-1-apatel@ventanamicro.com>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
Message-ID: <20241208150711.297624-5-apatel@ventanamicro.com>

From: Thomas Gleixner <tglx at linutronix.de>

Simplify the non-leaf MSI domain handling in the RISC-V IMSIC driver
by using msi_lib_init_dev_msi_info() and msi_lib_irq_domain_select()
provided by common MSI lib.

Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                    |   8 +-
 drivers/irqchip/irq-riscv-imsic-platform.c | 114 +--------------------
 2 files changed, 6 insertions(+), 116 deletions(-)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 55d7122121e2..6b767b8c974f 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -587,13 +587,7 @@ config RISCV_IMSIC
 	select IRQ_DOMAIN_HIERARCHY
 	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
+	select IRQ_MSI_LIB
 
 config SIFIVE_PLIC
 	bool
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 33a8261e6017..5bc1f03cbacb 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/smp.h>
 
+#include "irq-msi-lib.h"
 #include "irq-riscv-imsic-state.h"
 
 static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
@@ -201,22 +202,6 @@ static void imsic_irq_domain_free(struct irq_domain *domain, unsigned int virq,
 	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)
@@ -233,110 +218,21 @@ static void imsic_irq_debug_show(struct seq_file *m, struct irq_domain *d,
 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,
+	.select		= msi_lib_irq_domain_select,
 #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
 	.debug_show	= imsic_irq_debug_show,
 #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,
-				    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 = irq_chip_set_affinity_parent;
-#endif
-		break;
-	default:
-		WARN_ON_ONCE(1);
-		return false;
-	}
-
-	/* 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
-		 * 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 |
 				  MSI_FLAG_PCI_MSIX,
 	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
-				  MSI_FLAG_USE_DEF_CHIP_OPS,
+				  MSI_FLAG_USE_DEF_CHIP_OPS |
+				  MSI_FLAG_PCI_MSI_MASK_PARENT,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
 	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
-	.init_dev_msi_info	= imsic_init_dev_msi_info,
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
 
 int imsic_irqdomain_init(void)
-- 
2.43.0



From christophe.jaillet at wanadoo.fr  Sun Dec  8 07:09:25 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun, 8 Dec 2024 16:09:25 +0100
Subject: [net-next PATCH v10 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <20241208002105.18074-6-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
 <20241208002105.18074-6-ansuelsmth@gmail.com>
Message-ID: <8e9cf879-b188-4bfe-8200-f6a6ae285cb5@wanadoo.fr>

Le 08/12/2024 ? 01:20, Christian Marangi a ?crit?:
> Add support for Airoha AN8855 Switch MFD that provide support for a DSA
> switch and a NVMEM provider. Also provide support for a virtual MDIO
> passthrough as the PHYs address for the switch are shared with the switch
> address
> 
> Signed-off-by: Christian Marangi <ansuelsmth-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org>
> ---
>   MAINTAINERS                           |   1 +
>   drivers/mfd/Kconfig                   |   9 +
>   drivers/mfd/Makefile                  |   1 +
>   drivers/mfd/airoha-an8855.c           | 279 ++++++++++++++++++++++++++
>   include/linux/mfd/airoha-an8855-mfd.h |  41 ++++
>   5 files changed, 331 insertions(+)
>   create mode 100644 drivers/mfd/airoha-an8855.c
>   create mode 100644 include/linux/mfd/airoha-an8855-mfd.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f3e3f6938824..7f4d7c48b6e1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -721,6 +721,7 @@ F:	Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
>   F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
>   F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
>   F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
> +F:	drivers/mfd/airoha-an8855.c
>   
>   AIROHA ETHERNET DRIVER
>   M:	Lorenzo Bianconi <lorenzo-DgEjT+Ai2ygdnm+yROfE0A at public.gmane.org>
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index ae23b317a64e..a83db24336d9 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -53,6 +53,15 @@ config MFD_ALTERA_SYSMGR
>   	  using regmap_mmio accesses for ARM32 parts and SMC calls to
>   	  EL3 for ARM64 parts.
>   
> +config MFD_AIROHA_AN8855
> +	bool "Airoha AN8855 Switch MFD"
> +	depends on MDIO && OF
> +	select MFD_CORE
> +	help
> +	  Support for the Airoha AN8855 Switch MFD. This is a SoC Switch
> +	  that provide various peripherals. Currently it provides a

provides?

> +	  DSA switch and a NVMEM provider.
> +
>   config MFD_ACT8945A
>   	tristate "Active-semi ACT8945A"
>   	select MFD_CORE

...

> +static int an8855_mfd_probe(struct mdio_device *mdiodev)
> +{
> +	struct an8855_mfd_priv *priv;
> +	struct regmap *regmap;
> +
> +	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->bus = mdiodev->bus;
> +	priv->dev = &mdiodev->dev;
> +	priv->switch_addr = mdiodev->addr;
> +	/* no DMA for mdiobus, mute warning for DMA mask not set */
> +	priv->dev->dma_mask = &priv->dev->coherent_dma_mask;
> +
> +	regmap = devm_regmap_init(priv->dev, NULL, priv,
> +				  &an8855_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(priv->dev, "regmap initialization failed");

Nitpick: Missing ending \n.
Also, return dev_err_probe() could be used.

> +		return PTR_ERR(priv->dev);
> +	}
> +
> +	dev_set_drvdata(&mdiodev->dev, priv);

Is it needed?
There is no dev_get_drvdata() in this patch

> +
> +	return devm_mfd_add_devices(priv->dev, PLATFORM_DEVID_AUTO, an8855_mfd_devs,
> +				    ARRAY_SIZE(an8855_mfd_devs), NULL, 0,
> +				    NULL);
> +}

...

CJ


From ansuelsmth at gmail.com  Sun Dec  8 07:12:28 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sun, 8 Dec 2024 16:12:28 +0100
Subject: [net-next PATCH v10 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <8e9cf879-b188-4bfe-8200-f6a6ae285cb5@wanadoo.fr>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
 <20241208002105.18074-6-ansuelsmth@gmail.com>
 <8e9cf879-b188-4bfe-8200-f6a6ae285cb5@wanadoo.fr>
Message-ID: <6755b761.050a0220.223761.2b14@mx.google.com>

On Sun, Dec 08, 2024 at 04:09:25PM +0100, Christophe JAILLET wrote:
> Le 08/12/2024 ? 01:20, Christian Marangi a ?crit?:
> > Add support for Airoha AN8855 Switch MFD that provide support for a DSA
> > switch and a NVMEM provider. Also provide support for a virtual MDIO
> > passthrough as the PHYs address for the switch are shared with the switch
> > address
> > 
> > Signed-off-by: Christian Marangi <ansuelsmth-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org>
> > ---
> >   MAINTAINERS                           |   1 +
> >   drivers/mfd/Kconfig                   |   9 +
> >   drivers/mfd/Makefile                  |   1 +
> >   drivers/mfd/airoha-an8855.c           | 279 ++++++++++++++++++++++++++
> >   include/linux/mfd/airoha-an8855-mfd.h |  41 ++++
> >   5 files changed, 331 insertions(+)
> >   create mode 100644 drivers/mfd/airoha-an8855.c
> >   create mode 100644 include/linux/mfd/airoha-an8855-mfd.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index f3e3f6938824..7f4d7c48b6e1 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -721,6 +721,7 @@ F:	Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
> >   F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
> >   F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
> >   F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
> > +F:	drivers/mfd/airoha-an8855.c
> >   AIROHA ETHERNET DRIVER
> >   M:	Lorenzo Bianconi <lorenzo-DgEjT+Ai2ygdnm+yROfE0A at public.gmane.org>
> > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> > index ae23b317a64e..a83db24336d9 100644
> > --- a/drivers/mfd/Kconfig
> > +++ b/drivers/mfd/Kconfig
> > @@ -53,6 +53,15 @@ config MFD_ALTERA_SYSMGR
> >   	  using regmap_mmio accesses for ARM32 parts and SMC calls to
> >   	  EL3 for ARM64 parts.
> > +config MFD_AIROHA_AN8855
> > +	bool "Airoha AN8855 Switch MFD"
> > +	depends on MDIO && OF
> > +	select MFD_CORE
> > +	help
> > +	  Support for the Airoha AN8855 Switch MFD. This is a SoC Switch
> > +	  that provide various peripherals. Currently it provides a
> 
> provides?
> 
> > +	  DSA switch and a NVMEM provider.
> > +
> >   config MFD_ACT8945A
> >   	tristate "Active-semi ACT8945A"
> >   	select MFD_CORE
> 
> ...
> 
> > +static int an8855_mfd_probe(struct mdio_device *mdiodev)
> > +{
> > +	struct an8855_mfd_priv *priv;
> > +	struct regmap *regmap;
> > +
> > +	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	priv->bus = mdiodev->bus;
> > +	priv->dev = &mdiodev->dev;
> > +	priv->switch_addr = mdiodev->addr;
> > +	/* no DMA for mdiobus, mute warning for DMA mask not set */
> > +	priv->dev->dma_mask = &priv->dev->coherent_dma_mask;
> > +
> > +	regmap = devm_regmap_init(priv->dev, NULL, priv,
> > +				  &an8855_regmap_config);
> > +	if (IS_ERR(regmap)) {
> > +		dev_err(priv->dev, "regmap initialization failed");
> 
> Nitpick: Missing ending \n.
> Also, return dev_err_probe() could be used.
>

Can regmap PROBE_DEFER? Or it's just common practice?

> > +		return PTR_ERR(priv->dev);
> > +	}
> > +
> > +	dev_set_drvdata(&mdiodev->dev, priv);
> 
> Is it needed?
> There is no dev_get_drvdata() in this patch
> 

Yes it is, MFD child makes use of dev_get_drv_data(dev->parent) to
access the bug and current_page.

> > +
> > +	return devm_mfd_add_devices(priv->dev, PLATFORM_DEVID_AUTO, an8855_mfd_devs,
> > +				    ARRAY_SIZE(an8855_mfd_devs), NULL, 0,
> > +				    NULL);
> > +}
> 
> ...
> 
> CJ

-- 
	Ansuel


From apatel at ventanamicro.com  Sun Dec  8 07:07:07 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sun,  8 Dec 2024 20:37:07 +0530
Subject: [PATCH 0/4] Move RISC-V IMSIC driver to the common MSI lib
Message-ID: <20241208150711.297624-1-apatel@ventanamicro.com>

This series is based on recent discussion on LKML:
https://lore.kernel.org/lkml/20241114161845.502027-18-ajones at ventanamicro.com/

It primarily focuses on moving RISC-V IMSIC driver to the common MSI lib.

PATCH1: Fix for handling non-atomic MSI updates
PATCH2 & PATCH3: Preparatory patches
PATCH4: Main patch which updates IMSIC driver to use MSI lib

These patches can also be found in the riscv_imsic_imp_v1 branch at:
https://github.com/avpatel/linux.git

Andrew Jones (1):
  irqchip/riscv-imsic: Set irq_set_affinity for IMSIC base

Anup Patel (1):
  irqchip/riscv-imsic: Handle non-atomic MSI updates for device

Thomas Gleixner (2):
  irqchip/irq-msi-lib: Optionally set default irq_eoi/irq_ack
  irqchip/riscv-imsic: Move to common MSI lib

 drivers/irqchip/Kconfig                    |   8 +-
 drivers/irqchip/irq-gic-v2m.c              |   1 +
 drivers/irqchip/irq-imx-mu-msi.c           |   1 +
 drivers/irqchip/irq-msi-lib.c              |  11 +-
 drivers/irqchip/irq-mvebu-gicp.c           |   1 +
 drivers/irqchip/irq-mvebu-odmi.c           |   1 +
 drivers/irqchip/irq-mvebu-sei.c            |   1 +
 drivers/irqchip/irq-riscv-imsic-platform.c | 155 ++++++---------------
 drivers/irqchip/irq-riscv-imsic-state.c    |  27 +++-
 include/linux/msi.h                        |  11 ++
 10 files changed, 87 insertions(+), 130 deletions(-)

-- 
2.43.0



From apatel at ventanamicro.com  Sun Dec  8 07:07:08 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sun,  8 Dec 2024 20:37:08 +0530
Subject: [PATCH 1/4] irqchip/riscv-imsic: Handle non-atomic MSI updates for device
In-Reply-To: <20241208150711.297624-1-apatel@ventanamicro.com>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
Message-ID: <20241208150711.297624-2-apatel@ventanamicro.com>

Device having non-atomic MSI update might see an intermediate
state when changing target IMSIC vector from one CPU to another.

To handle such intermediate device state, update MSI address
and MSI data through separate MSI writes to the device.

Fixes: 027e125acdba ("irqchip/riscv-imsic: Add device MSI domain support for platform devices")
Suggested-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 27 ++++++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.c    | 27 +++++++++++++++++++---
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index c708780e8760..707c7ccb4d08 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -97,6 +97,7 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 {
 	struct imsic_vector *old_vec, *new_vec;
 	struct irq_data *pd = d->parent_data;
+	struct imsic_vector tmp_vec;
 
 	old_vec = irq_data_get_irq_chip_data(pd);
 	if (WARN_ON(!old_vec))
@@ -110,11 +111,37 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 	if (imsic_vector_get_move(old_vec))
 		return -EBUSY;
 
+	/*
+	 * Device having non-atomic MSI update might see an intermediate
+	 * state when changing target IMSIC vector from one CPU to another.
+	 *
+	 * To avoid losing interrupt to some intermediate state, do the
+	 * following (just like x86 APIC):
+	 *
+	 * 1) First write a temporary IMSIC vector to the device which
+	 * has MSI address same as the old IMSIC vector but MSI data
+	 * matches the new IMSIC vector.
+	 *
+	 * 2) Next write the new IMSIC vector to the device.
+	 *
+	 * Based on the above, the __imsic_local_sync() must check both
+	 * old MSI data and new MSI data on the old CPU for pending
+	 */
+
 	/* 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 (new_vec->local_id != old_vec->local_id) {
+		/* Setup temporary vector */
+		tmp_vec.cpu = old_vec->cpu;
+		tmp_vec.local_id = new_vec->local_id;
+
+		/* Point device to the temporary vector */
+		imsic_msi_update_msg(d, &tmp_vec);
+	}
+
 	/* Point device to the new vector */
 	imsic_msi_update_msg(d, new_vec);
 
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index b97e6cd89ed7..230b917136e6 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -126,8 +126,8 @@ void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend,
 
 static void __imsic_local_sync(struct imsic_local_priv *lpriv)
 {
-	struct imsic_local_config *mlocal;
-	struct imsic_vector *vec, *mvec;
+	struct imsic_local_config *tlocal, *mlocal;
+	struct imsic_vector *vec, *tvec, *mvec;
 	int i;
 
 	lockdep_assert_held(&lpriv->lock);
@@ -151,7 +151,28 @@ static void __imsic_local_sync(struct imsic_local_priv *lpriv)
 		mvec = READ_ONCE(vec->move);
 		WRITE_ONCE(vec->move, NULL);
 		if (mvec && mvec != vec) {
-			if (__imsic_id_read_clear_pending(i)) {
+			/*
+			 * Device having non-atomic MSI update might see an
+			 * intermediate state so check both old ID and new ID
+			 * for pending interrupts.
+			 *
+			 * For details, refer imsic_irq_set_affinity().
+			 */
+
+			tvec = vec->local_id == mvec->local_id ?
+			       NULL : &lpriv->vectors[mvec->local_id];
+			if (tvec && __imsic_id_read_clear_pending(tvec->local_id)) {
+				/* Retrigger temporary vector if it was already in-use */
+				if (READ_ONCE(tvec->enable)) {
+					tlocal = per_cpu_ptr(imsic->global.local, tvec->cpu);
+					writel_relaxed(tvec->local_id, tlocal->msi_va);
+				}
+
+				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
+				writel_relaxed(mvec->local_id, mlocal->msi_va);
+			}
+
+			if (__imsic_id_read_clear_pending(vec->local_id)) {
 				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
 				writel_relaxed(mvec->local_id, mlocal->msi_va);
 			}
-- 
2.43.0



From apatel at ventanamicro.com  Sun Dec  8 07:07:09 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sun,  8 Dec 2024 20:37:09 +0530
Subject: [PATCH 2/4] irqchip/irq-msi-lib: Optionally set default irq_eoi/irq_ack
In-Reply-To: <20241208150711.297624-1-apatel@ventanamicro.com>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
Message-ID: <20241208150711.297624-3-apatel@ventanamicro.com>

From: Thomas Gleixner <tglx at linutronix.de>

Introduce chip_flags in struct msi_parent_ops. This allows
msi_lib_init_dev_msi_info() set default irq_eoi/irq_ack
callbacks only when the corresponding flags are set in
the chip_flags.

Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-gic-v2m.c    |  1 +
 drivers/irqchip/irq-imx-mu-msi.c |  1 +
 drivers/irqchip/irq-msi-lib.c    | 11 ++++++-----
 drivers/irqchip/irq-mvebu-gicp.c |  1 +
 drivers/irqchip/irq-mvebu-odmi.c |  1 +
 drivers/irqchip/irq-mvebu-sei.c  |  1 +
 include/linux/msi.h              | 11 +++++++++++
 7 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index be35c5349986..1e3476c335ca 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -255,6 +255,7 @@ static void __init gicv2m_teardown(void)
 static struct msi_parent_ops gicv2m_msi_parent_ops = {
 	.supported_flags	= GICV2M_MSI_FLAGS_SUPPORTED,
 	.required_flags		= GICV2M_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
 	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
 	.prefix			= "GICv2m-",
diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c
index 4342a21de1eb..69aacdfc8bef 100644
--- a/drivers/irqchip/irq-imx-mu-msi.c
+++ b/drivers/irqchip/irq-imx-mu-msi.c
@@ -214,6 +214,7 @@ static void imx_mu_msi_irq_handler(struct irq_desc *desc)
 static const struct msi_parent_ops imx_mu_msi_parent_ops = {
 	.supported_flags	= IMX_MU_MSI_FLAGS_SUPPORTED,
 	.required_flags		= IMX_MU_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_token       = DOMAIN_BUS_NEXUS,
 	.bus_select_mask	= MATCH_PLATFORM_MSI,
 	.prefix			= "MU-MSI-",
diff --git a/drivers/irqchip/irq-msi-lib.c b/drivers/irqchip/irq-msi-lib.c
index d8e29fc0d406..51464c6257f3 100644
--- a/drivers/irqchip/irq-msi-lib.c
+++ b/drivers/irqchip/irq-msi-lib.c
@@ -28,6 +28,7 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 			       struct msi_domain_info *info)
 {
 	const struct msi_parent_ops *pops = real_parent->msi_parent_ops;
+	struct irq_chip *chip = info->chip;
 	u32 required_flags;
 
 	/* Parent ops available? */
@@ -92,10 +93,10 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 	info->flags			|= required_flags;
 
 	/* Chip updates for all child bus types */
-	if (!info->chip->irq_eoi)
-		info->chip->irq_eoi	= irq_chip_eoi_parent;
-	if (!info->chip->irq_ack)
-		info->chip->irq_ack	= irq_chip_ack_parent;
+	if (!chip->irq_eoi && (pops->chip_flags & MSI_CHIP_FLAG_SET_EOI))
+		chip->irq_eoi = irq_chip_eoi_parent;
+	if (!chip->irq_ack && (pops->chip_flags & MSI_CHIP_FLAG_SET_ACK))
+		chip->irq_ack = irq_chip_ack_parent;
 
 	/*
 	 * The device MSI domain can never have a set affinity callback. It
@@ -105,7 +106,7 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 	 * device MSI domain aside of mask/unmask which is provided e.g. by
 	 * PCI/MSI device domains.
 	 */
-	info->chip->irq_set_affinity	= msi_domain_set_affinity;
+	chip->irq_set_affinity = msi_domain_set_affinity;
 	return true;
 }
 EXPORT_SYMBOL_GPL(msi_lib_init_dev_msi_info);
diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c
index 2b6183919ea4..d67f93f6d750 100644
--- a/drivers/irqchip/irq-mvebu-gicp.c
+++ b/drivers/irqchip/irq-mvebu-gicp.c
@@ -161,6 +161,7 @@ static const struct irq_domain_ops gicp_domain_ops = {
 static const struct msi_parent_ops gicp_msi_parent_ops = {
 	.supported_flags	= GICP_MSI_FLAGS_SUPPORTED,
 	.required_flags		= GICP_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_token       = DOMAIN_BUS_GENERIC_MSI,
 	.bus_select_mask	= MATCH_PLATFORM_MSI,
 	.prefix			= "GICP-",
diff --git a/drivers/irqchip/irq-mvebu-odmi.c b/drivers/irqchip/irq-mvebu-odmi.c
index ff19bfd258dc..28f7e81df94f 100644
--- a/drivers/irqchip/irq-mvebu-odmi.c
+++ b/drivers/irqchip/irq-mvebu-odmi.c
@@ -157,6 +157,7 @@ static const struct irq_domain_ops odmi_domain_ops = {
 static const struct msi_parent_ops odmi_msi_parent_ops = {
 	.supported_flags	= ODMI_MSI_FLAGS_SUPPORTED,
 	.required_flags		= ODMI_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_token	= DOMAIN_BUS_GENERIC_MSI,
 	.bus_select_mask	= MATCH_PLATFORM_MSI,
 	.prefix			= "ODMI-",
diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c
index 065166ab5dbc..ebd4a9014e8d 100644
--- a/drivers/irqchip/irq-mvebu-sei.c
+++ b/drivers/irqchip/irq-mvebu-sei.c
@@ -356,6 +356,7 @@ static void mvebu_sei_reset(struct mvebu_sei *sei)
 static const struct msi_parent_ops sei_msi_parent_ops = {
 	.supported_flags	= SEI_MSI_FLAGS_SUPPORTED,
 	.required_flags		= SEI_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_mask	= MATCH_PLATFORM_MSI,
 	.bus_select_token	= DOMAIN_BUS_GENERIC_MSI,
 	.prefix			= "SEI-",
diff --git a/include/linux/msi.h b/include/linux/msi.h
index b10093c4d00e..9abef442c146 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -558,11 +558,21 @@ enum {
 	MSI_FLAG_NO_AFFINITY		= (1 << 21),
 };
 
+/*
+ * Flags for msi_parent_ops::chip_flags
+ */
+enum {
+	MSI_CHIP_FLAG_SET_EOI		= (1 << 0),
+	MSI_CHIP_FLAG_SET_ACK		= (1 << 1),
+};
+
 /**
  * struct msi_parent_ops - MSI parent domain callbacks and configuration info
  *
  * @supported_flags:	Required: The supported MSI flags of the parent domain
  * @required_flags:	Optional: The required MSI flags of the parent MSI domain
+ * @chip_flags:		Optional: Select MSI chip callbacks to update with defaults
+ *			in msi_lib_init_dev_msi_info().
  * @bus_select_token:	Optional: The bus token of the real parent domain for
  *			irq_domain::select()
  * @bus_select_mask:	Optional: A mask of supported BUS_DOMAINs for
@@ -575,6 +585,7 @@ enum {
 struct msi_parent_ops {
 	u32		supported_flags;
 	u32		required_flags;
+	u32		chip_flags;
 	u32		bus_select_token;
 	u32		bus_select_mask;
 	const char	*prefix;
-- 
2.43.0



From christophe.jaillet at wanadoo.fr  Sun Dec  8 07:13:50 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun, 8 Dec 2024 16:13:50 +0100
Subject: [net-next PATCH v10 6/9] net: mdio: Add Airoha AN8855 Switch MDIO
 Passtrough
In-Reply-To: <20241208002105.18074-7-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
 <20241208002105.18074-7-ansuelsmth@gmail.com>
Message-ID: <42f11110-7071-43c8-a4fe-df99a60bc12d@wanadoo.fr>

Le 08/12/2024 ? 01:20, Christian Marangi a ?crit?:
> Add Airoha AN8855 Switch driver to register a MDIO passtrough as switch
> address is shared with the internal PHYs and require additional page
> handling.
> 
> This requires the upper Switch MFD to be probed and init to actually
> work.
> 
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> ---
>   MAINTAINERS                    |   1 +
>   drivers/net/mdio/Kconfig       |   9 +++
>   drivers/net/mdio/Makefile      |   1 +
>   drivers/net/mdio/mdio-an8855.c | 113 +++++++++++++++++++++++++++++++++
>   4 files changed, 124 insertions(+)
>   create mode 100644 drivers/net/mdio/mdio-an8855.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7f4d7c48b6e1..38c7b2362c92 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -722,6 +722,7 @@ F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
>   F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
>   F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
>   F:	drivers/mfd/airoha-an8855.c
> +F:	drivers/net/mdio/mdio-an8855.c
>   
>   AIROHA ETHERNET DRIVER
>   M:	Lorenzo Bianconi <lorenzo at kernel.org>
> diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig
> index 4a7a303be2f7..64fc5c3ef38b 100644
> --- a/drivers/net/mdio/Kconfig
> +++ b/drivers/net/mdio/Kconfig
> @@ -61,6 +61,15 @@ config MDIO_XGENE
>   	  This module provides a driver for the MDIO busses found in the
>   	  APM X-Gene SoC's.
>   
> +config MDIO_AN8855
> +	tristate "Airoha AN8855 Switch MDIO bus controller"
> +	depends on MFD_AIROHA_AN8855
> +	depends on OF_MDIO
> +	help
> +	  This module provides a driver for the Airoha AN8855 Switch
> +	  that require a MDIO passtrough as switch address is shared

requires?

> +	  with the internal PHYs and require additional page handling.

requires?

> +
>   config MDIO_ASPEED
>   	tristate "ASPEED MDIO bus controller"
>   	depends on ARCH_ASPEED || COMPILE_TEST

...

> +static int an8855_mdio_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct an8855_mfd_priv *priv;
> +	struct mii_bus *bus;
> +	int ret;
> +
> +	/* Get priv of MFD */
> +	priv = dev_get_drvdata(dev->parent);

Ok, forget the related comment made on patch 5/9.

> +
> +	bus = devm_mdiobus_alloc(dev);
> +	if (!bus)
> +		return -ENOMEM;
> +
> +	bus->priv = priv;
> +	bus->name = KBUILD_MODNAME "-mii";
> +	snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d",
> +		 priv->switch_addr);
> +	bus->parent = dev;
> +	bus->read = an8855_phy_read;
> +	bus->write = an8855_phy_write;
> +
> +	ret = devm_of_mdiobus_register(dev, bus, dev->of_node);
> +	if (ret)
> +		dev_err(dev, "failed to register MDIO bus: %d", ret);

Nitpick: Missing ending \n.
dev_err_probe() could be used.

> +
> +	return ret;
> +}

...

CJ





From christophe.jaillet at wanadoo.fr  Sun Dec  8 07:17:28 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun, 8 Dec 2024 16:17:28 +0100
Subject: [net-next PATCH v10 7/9] nvmem: an8855: Add support for Airoha
 AN8855 Switch EFUSE
In-Reply-To: <20241208002105.18074-8-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
 <20241208002105.18074-8-ansuelsmth@gmail.com>
Message-ID: <118552cc-e060-45fa-b93f-9187011f2c8c@wanadoo.fr>

Le 08/12/2024 ? 01:20, Christian Marangi a ?crit?:
> Add support for Airoha AN8855 Switch EFUSE. These EFUSE might be used
> for calibration data for the internal switch PHYs.
> 
> Signed-off-by: Christian Marangi <ansuelsmth-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org>
> ---
>   MAINTAINERS                  |  1 +
>   drivers/nvmem/Kconfig        | 11 +++++++
>   drivers/nvmem/Makefile       |  2 ++
>   drivers/nvmem/an8855-efuse.c | 63 ++++++++++++++++++++++++++++++++++++
>   4 files changed, 77 insertions(+)
>   create mode 100644 drivers/nvmem/an8855-efuse.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 38c7b2362c92..a67d147276a1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -723,6 +723,7 @@ F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
>   F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
>   F:	drivers/mfd/airoha-an8855.c
>   F:	drivers/net/mdio/mdio-an8855.c
> +F:	drivers/nvmem/an8855-efuse.c
>   
>   AIROHA ETHERNET DRIVER
>   M:	Lorenzo Bianconi <lorenzo-DgEjT+Ai2ygdnm+yROfE0A at public.gmane.org>
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 8671b7c974b9..599014970c22 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -28,6 +28,17 @@ source "drivers/nvmem/layouts/Kconfig"
>   
>   # Devices
>   
> +config NVMEM_AN8855_EFUSE
> +	tristate "Airoha AN8855 eFuse support"
> +	depends on MFD_AIROHA_AN8855 || COMPILE_TEST
> +	help
> +	  Say y here to enable support for reading eFuses on Airoha AN8855
> +	  Switch. These are e.g. used to store factory programmed
> +	  calibration data required for the PHY.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called nvmem-apple-efuse.

nvmem-an8855-efuse?

> +
>   config NVMEM_APPLE_EFUSES
>   	tristate "Apple eFuse support"
>   	depends on ARCH_APPLE || COMPILE_TEST
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index 5b77bbb6488b..c732132c0e45 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -10,6 +10,8 @@ nvmem_layouts-y			:= layouts.o
>   obj-y				+= layouts/
>   
>   # Devices
> +obj-$(CONFIG_NVMEM_AN8855_EFUSE)	+= nvmem-an8855-efuse.o
> +nvmem-an8855-efuse-y 			:= an8855-efuse.o
>   obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o
>   nvmem-apple-efuses-y 			:= apple-efuses.o
>   obj-$(CONFIG_NVMEM_BCM_OCOTP)		+= nvmem-bcm-ocotp.o

...

> +static int an8855_efuse_probe(struct platform_device *pdev)
> +{
> +	struct nvmem_config an8855_nvmem_config = {
> +		.name = "an8855-efuse",
> +		.size = AN8855_EFUSE_CELL * sizeof(u32),
> +		.stride = sizeof(u32),
> +		.word_size = sizeof(u32),
> +		.reg_read = an8855_efuse_read,
> +	};
> +	struct device *dev = &pdev->dev;
> +	struct nvmem_device *nvmem;
> +
> +	/* Assign NVMEM priv to MFD regmap */
> +	an8855_nvmem_config.priv = dev_get_regmap(dev->parent, NULL);
> +	an8855_nvmem_config.dev = dev;
> +	nvmem = devm_nvmem_register(dev, &an8855_nvmem_config);
> +
> +	return PTR_ERR_OR_ZERO(nvmem);
> +}
> +
> +static const struct of_device_id an8855_efuse_of_match[] = {
> +	{ .compatible = "airoha,an8855-efuse", },
> +	{/* sentinel */},

No need for the ending comma.

> +};
> +MODULE_DEVICE_TABLE(of, an8855_efuse_of_match);

...

CJ




From christophe.jaillet at wanadoo.fr  Sun Dec  8 07:26:46 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun, 8 Dec 2024 16:26:46 +0100
Subject: [net-next PATCH v10 8/9] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241208002105.18074-9-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
 <20241208002105.18074-9-ansuelsmth@gmail.com>
Message-ID: <d205aae9-68d5-41f1-8739-779b2d9a6664@wanadoo.fr>

Le 08/12/2024 ? 01:20, Christian Marangi a ?crit?:
> Add Airoha AN8855 5-Port Gigabit DSA switch. Switch can support
> 10M, 100M, 1Gb, 2.5G and 5G Ethernet Speed but 5G is currently error out
> as it's not currently supported as requires additional configuration for
> the PCS.
> 
> The switch is also a nvmem-provider as it does have EFUSE to calibrate
> the internal PHYs.
> 
> Signed-off-by: Christian Marangi <ansuelsmth-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org>
> ---

...

> +static int an8855_read_switch_id(struct an8855_priv *priv)
> +{
> +	u32 id;
> +	int ret;
> +
> +	ret = regmap_read(priv->regmap, AN8855_CREV, &id);
> +	if (ret)
> +		return ret;
> +
> +	if (id != AN8855_ID) {
> +		dev_err(priv->dev,
> +			"Switch id detected %x but expected %x",

missing \n

> +			id, AN8855_ID);
> +		return -ENODEV;
> +	}
> +
> +	return 0;
> +}

...

> +static void an8855_switch_remove(struct platform_device *pdev)
> +{
> +	struct an8855_priv *priv = dev_get_drvdata(&pdev->dev);
> +
> +	if (!priv)
> +		return;

I don't think this can happen. So it could be removed?

> +
> +	dsa_unregister_switch(priv->ds);
> +}

...

CJ


From christophe.jaillet at wanadoo.fr  Sun Dec  8 07:38:02 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun, 8 Dec 2024 16:38:02 +0100
Subject: [net-next PATCH v10 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <6755b761.050a0220.223761.2b14@mx.google.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
 <20241208002105.18074-6-ansuelsmth@gmail.com>
 <8e9cf879-b188-4bfe-8200-f6a6ae285cb5@wanadoo.fr>
 <6755b761.050a0220.223761.2b14@mx.google.com>
Message-ID: <f8d990ef-203e-479a-838e-13780e758ab8@wanadoo.fr>

Le 08/12/2024 ? 16:12, Christian Marangi a ?crit?:
> On Sun, Dec 08, 2024 at 04:09:25PM +0100, Christophe JAILLET wrote:
>> Le 08/12/2024 ? 01:20, Christian Marangi a ?crit?:
>>> Add support for Airoha AN8855 Switch MFD that provide support for a DSA
>>> switch and a NVMEM provider. Also provide support for a virtual MDIO
>>> passthrough as the PHYs address for the switch are shared with the switch
>>> address
>>>
>>> Signed-off-by: Christian Marangi <ansuelsmth-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org>
>>> ---
>>>    MAINTAINERS                           |   1 +
>>>    drivers/mfd/Kconfig                   |   9 +
>>>    drivers/mfd/Makefile                  |   1 +
>>>    drivers/mfd/airoha-an8855.c           | 279 ++++++++++++++++++++++++++
>>>    include/linux/mfd/airoha-an8855-mfd.h |  41 ++++
>>>    5 files changed, 331 insertions(+)
>>>    create mode 100644 drivers/mfd/airoha-an8855.c
>>>    create mode 100644 include/linux/mfd/airoha-an8855-mfd.h
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index f3e3f6938824..7f4d7c48b6e1 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -721,6 +721,7 @@ F:	Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
>>>    F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
>>>    F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
>>>    F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
>>> +F:	drivers/mfd/airoha-an8855.c
>>>    AIROHA ETHERNET DRIVER
>>>    M:	Lorenzo Bianconi <lorenzo-DgEjT+Ai2ygdnm+yROfE0A at public.gmane.org>
>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>>> index ae23b317a64e..a83db24336d9 100644
>>> --- a/drivers/mfd/Kconfig
>>> +++ b/drivers/mfd/Kconfig
>>> @@ -53,6 +53,15 @@ config MFD_ALTERA_SYSMGR
>>>    	  using regmap_mmio accesses for ARM32 parts and SMC calls to
>>>    	  EL3 for ARM64 parts.
>>> +config MFD_AIROHA_AN8855
>>> +	bool "Airoha AN8855 Switch MFD"
>>> +	depends on MDIO && OF
>>> +	select MFD_CORE
>>> +	help
>>> +	  Support for the Airoha AN8855 Switch MFD. This is a SoC Switch
>>> +	  that provide various peripherals. Currently it provides a
>>
>> provides?
>>
>>> +	  DSA switch and a NVMEM provider.
>>> +
>>>    config MFD_ACT8945A
>>>    	tristate "Active-semi ACT8945A"
>>>    	select MFD_CORE
>>
>> ...
>>
>>> +static int an8855_mfd_probe(struct mdio_device *mdiodev)
>>> +{
>>> +	struct an8855_mfd_priv *priv;
>>> +	struct regmap *regmap;
>>> +
>>> +	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
>>> +	if (!priv)
>>> +		return -ENOMEM;
>>> +
>>> +	priv->bus = mdiodev->bus;
>>> +	priv->dev = &mdiodev->dev;
>>> +	priv->switch_addr = mdiodev->addr;
>>> +	/* no DMA for mdiobus, mute warning for DMA mask not set */
>>> +	priv->dev->dma_mask = &priv->dev->coherent_dma_mask;
>>> +
>>> +	regmap = devm_regmap_init(priv->dev, NULL, priv,
>>> +				  &an8855_regmap_config);
>>> +	if (IS_ERR(regmap)) {
>>> +		dev_err(priv->dev, "regmap initialization failed");
>>
>> Nitpick: Missing ending \n.
>> Also, return dev_err_probe() could be used.
>>
> 
> Can regmap PROBE_DEFER? Or it's just common practice?

It is a common practice to easily log the error code in a human readable 
format, even when PROBE_DEFER can't happen.

It sometimes also saves 1 or 2 LoC because it may save the { } and the 
line with return.

Leaving it as-is is obviously also just fine ;-).

CJ

> 
>>> +		return PTR_ERR(priv->dev);
>>> +	}
>>> +
>>> +	dev_set_drvdata(&mdiodev->dev, priv);
>>
>> Is it needed?
>> There is no dev_get_drvdata() in this patch
>>
> 
> Yes it is, MFD child makes use of dev_get_drv_data(dev->parent) to
> access the bug and current_page.
> 
>>> +
>>> +	return devm_mfd_add_devices(priv->dev, PLATFORM_DEVID_AUTO, an8855_mfd_devs,
>>> +				    ARRAY_SIZE(an8855_mfd_devs), NULL, 0,
>>> +				    NULL);
>>> +}
>>
>> ...
>>
>> CJ
> 



From vkoul at kernel.org  Sun Dec  8 07:39:50 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 8 Dec 2024 21:09:50 +0530
Subject: [PATCH v3 5/8] phy: exynos5-usbdrd: gs101: ensure power is gated
 to SS phy in phy_exit()
In-Reply-To: <2024120528-poker-thinness-6cfb@gregkh>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
 <20241205-gs101-phy-lanes-orientation-phy-v3-5-32f721bed219@linaro.org>
 <2024120528-poker-thinness-6cfb@gregkh>
Message-ID: <Z1W9xuCrn40uPWbr@vaman>

On 05-12-24, 09:04, Greg KH wrote:
> On Thu, Dec 05, 2024 at 07:33:16AM +0000, Andr? Draszik wrote:
> > We currently don't gate the power to the SS phy in phy_exit().
> > 
> > Shuffle the code slightly to ensure the power is gated to the SS phy as
> > well.
> > 
> > Fixes: 32267c29bc7d ("phy: exynos5-usbdrd: support Exynos USBDRD 3.1 combo phy (HS & SS)")
> > CC: stable at vger.kernel.org # 6.11+
> 
> Why is a patch 5/8 a stable thing?  If this is such an important bugfix,
> it should be sent separately as a 1/1 patch, right?

Correct, one should move fixes to top of the series..

-- 
~Vinod


From claudiu.beznea at tuxon.dev  Sun Dec  8 07:48:11 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 17:48:11 +0200
Subject: [PATCH] ARM: at91: pm: change BU Power Switch to automatic mode
In-Reply-To: <20241125165648.509162-1-nicolas.ferre@microchip.com>
References: <20241125165648.509162-1-nicolas.ferre@microchip.com>
Message-ID: <32b1ae9d-f55b-43d0-bb24-1fd486440ab6@tuxon.dev>



On 25.11.2024 18:56, nicolas.ferre at microchip.com wrote:
> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> Change how the Backup Unit Power is configured and force the
> automatic/hardware mode.
> This change eliminates the need for software management of the power
> switch, ensuring it transitions to the backup power source before
> entering low power modes.
> 
> This is done in the only locaton where this swich was configured. It's
> usually done in the bootloader.
> 
> Previously, the loss of the VDDANA (or VDDIN33) power source was not
> automatically compensated by an alternative power source. This resulted
> in the loss of Backup Unit content, including Backup Self-refresh low
> power mode information, OTP emulation configuration, and boot
> configuration, for instance.
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>

I've added the fixes tag, s/locaton/location, s/swich/switch.

Applied to at91-soc, thanks!


From claudiu.beznea at tuxon.dev  Sun Dec  8 07:49:38 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 17:49:38 +0200
Subject: [PATCH 0/2] Add power monitor support on sam9x75-curiosity board
In-Reply-To: <20241122080523.3941-1-mihai.sain@microchip.com>
References: <20241122080523.3941-1-mihai.sain@microchip.com>
Message-ID: <a93bd8ed-39e2-4f19-99c0-1d9c11c694df@tuxon.dev>



On 22.11.2024 10:05, Mihai Sain wrote:
> Mihai Sain (2):
>   ARM: dts: microchip: sam9x7: Move i2c address/size to dtsi
>   ARM: dts: microchip: sam9x75_curiosity: Add power monitor support

Applied to at91-dt, thanks!


From claudiu.beznea at tuxon.dev  Sun Dec  8 07:52:19 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 17:52:19 +0200
Subject: [PATCH v2] soc: atmel: fix device_node release in
 atmel_soc_device_init()
In-Reply-To: <20241031-soc-atmel-soc-cleanup-v2-1-73f2d235fd98@gmail.com>
References: <20241031-soc-atmel-soc-cleanup-v2-1-73f2d235fd98@gmail.com>
Message-ID: <afac0fe8-2854-43eb-a4fb-bcf5b6d194d0@tuxon.dev>



On 31.10.2024 14:33, Javier Carrasco wrote:
> A device_node acquired via of_find_node_by_path() requires explicit
> calls to of_node_put() when it is no longer needed to avoid leaking the
> resource.
> 
> Instead of adding the missing calls to of_node_put() in all execution
> paths, use the cleanup attribute for 'np' by means of the __free()
> macro, which automatically calls of_node_put() when the variable goes
> out of scope.
> 
> Fixes: 960ddf70cc11 ("drivers: soc: atmel: Avoid calling at91_soc_init on non AT91 SoCs")
> Signed-off-by: Javier Carrasco <javier.carrasco.cruz at gmail.com>

Applied to at91-soc, thanks!


From andrew at lunn.ch  Sun Dec  8 08:02:48 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 8 Dec 2024 17:02:48 +0100
Subject: [net-next PATCH v10 2/9] dt-bindings: net: Document support for
 Airoha AN8855 Switch Virtual MDIO
In-Reply-To: <20241208002105.18074-3-ansuelsmth@gmail.com>
References: <20241208002105.18074-1-ansuelsmth@gmail.com>
 <20241208002105.18074-3-ansuelsmth@gmail.com>
Message-ID: <656c4f9d-ff6b-4c98-84f4-d20b6e562c13@lunn.ch>

On Sun, Dec 08, 2024 at 01:20:37AM +0100, Christian Marangi wrote:
> Document support for Airoha AN8855 Virtual MDIO Passtrough. This is needed
> as AN8855 require special handling as the same address on the MDIO bus is
> shared for both Switch and PHY and special handling for the page
> configuration is needed to switch accessing to Switch address space
> or PHY.
> 
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> ---
>  .../bindings/net/airoha,an8855-mdio.yaml      | 86 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 87 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml b/Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
> new file mode 100644
> index 000000000000..2211df3cc3b7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
> @@ -0,0 +1,86 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/airoha,an8855-mdio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Airoha AN8855 MDIO Passtrough
> +
> +maintainers:
> +  - Christian Marangi <ansuelsmth at gmail.com>
> +
> +description:
> +  Airoha AN8855 Virtual MDIO Passtrough. This is needed as AN8855
> +  require special handling as the same address on the MDIO bus is
> +  shared for both Switch and PHY and special handling for the page
> +  configuration is needed to switch accessing to Switch address space
> +  or PHY.
> +
> +$ref: /schemas/net/mdio.yaml#
> +
> +properties:
> +  compatible:
> +    const: airoha,an8855-mdio
> +
> +required:
> +  - compatible
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    mdio {
> +        compatible = "airoha,an8855-mdio";
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        internal_phy1: phy at 1 {
> +            reg = <1>;
> +
> +            nvmem-cells = <&shift_sel_port0_tx_a>,
> +                <&shift_sel_port0_tx_b>,
> +                <&shift_sel_port0_tx_c>,
> +                <&shift_sel_port0_tx_d>;
> +            nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";


For this example nvmem is not relevant. Those are PHY properties, not
MDIO properties. So you could simplify this.

	Andrew


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:23:19 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:23:19 +0200
Subject: [PATCH v3 01/13] dt-bindings: ARM: at91: Document Microchip
 SAMA7D65 Curiosity
In-Reply-To: <d5a22763a2081daa0d2155e2c05b7dc0eb468610.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <d5a22763a2081daa0d2155e2c05b7dc0eb468610.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <40084072-8581-49b1-b0b8-e3c63dd39f3a@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Romain Sioen <romain.sioen at microchip.com>
> 
> Document device tree binding of the Microchip SAMA7D65 Curiosity board.
> 
> Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
> Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

> ---
>  Documentation/devicetree/bindings/arm/atmel-at91.yaml | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> index 7160ec80ac1b..0ec29366e6c2 100644
> --- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> +++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> @@ -180,6 +180,13 @@ properties:
>            - const: atmel,sama5d4
>            - const: atmel,sama5
>  
> +      - description: Microchip SAMA7D65 Curiosity Board
> +        items:
> +          - const: microchip,sama7d65-curiosity
> +          - const: microchip,sama7d65
> +          - const: microchip,sama7d6
> +          - const: microchip,sama7
> +
>        - items:
>            - const: microchip,sama7g5ek # SAMA7G5 Evaluation Kit
>            - const: microchip,sama7g5


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:25:14 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:25:14 +0200
Subject: [PATCH v3 06/13] dt-bindings: clocks: atmel,at91sam9x5-sckc: add
 sama7d65
In-Reply-To: <b7a8a22a571f6fc2be56a25f26757f37fa8d2bb3.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <b7a8a22a571f6fc2be56a25f26757f37fa8d2bb3.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <91b98edc-4313-45a8-9bfc-7df83b3d5640@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Add bindings for SAMA7D65's slow clock controller.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:24:29 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:24:29 +0200
Subject: [PATCH v3 03/13] dt-bindings: atmel-sysreg: add sama7d65 RAM and
 PIT
In-Reply-To: <96e64f01eee264ad0ac4c720a7a1cab4f95c206b.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <96e64f01eee264ad0ac4c720a7a1cab4f95c206b.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <e592e292-71df-4bf0-aa8e-88a53dfc2777@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Add SAMA7D65 RAM controller, PIT64 DT bindings.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---
>  .../devicetree/bindings/arm/atmel-sysregs.txt      | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
> index 76e2b7978250..93c2a5a341f3 100644
> --- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
> +++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
> @@ -13,6 +13,7 @@ PIT Timer required properties:
>  PIT64B Timer required properties:
>  - compatible: Should be "microchip,sam9x60-pit64b" or
>  			"microchip,sam9x7-pit64b", "microchip,sam9x60-pit64b"
> +			"microchip,sama7d65-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.
> @@ -27,12 +28,13 @@ Its subnodes can be:
>  - watchdog: compatible should be "atmel,at91rm9200-wdt"
>  
>  RAMC SDRAM/DDR Controller required properties:
> -- compatible: Should be "atmel,at91rm9200-sdramc", "syscon"
> -			"atmel,at91sam9260-sdramc",
> -			"atmel,at91sam9g45-ddramc",
> -			"atmel,sama5d3-ddramc",
> -			"microchip,sam9x60-ddramc",
> -			"microchip,sama7g5-uddrc",
> +- compatible: Should be "atmel,at91rm9200-sdramc", "syscon" or
> +			"atmel,at91sam9260-sdramc" or
> +			"atmel,at91sam9g45-ddramc" or
> +			"atmel,sama5d3-ddramc" or
> +			"microchip,sam9x60-ddramc" or
> +			"microchip,sama7g5-uddrc" or
> +			"microchip,sama7d65-uddrc","microchip,sama7g5-uddrc" or

Missing space here --------------------------------^

I'll adjust it while applying.

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

>  			"microchip,sam9x7-ddramc", "atmel,sama5d3-ddramc".
>  - reg: Should contain registers location and length
>  


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:26:18 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:26:18 +0200
Subject: [PATCH v3 07/13] dt-bindings: clock: Add SAMA7D65 PMC compatible
 string
In-Reply-To: <5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <7177c349-a22e-4501-b42c-0c62d94c2f76@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Add the `microchip,sama7d65-pmc` compatible string to the existing binding,
> since the SAMA7D65 PMC shares the same properties and clock requirements
> as the SAMA7G5.
> 
> Export MCK3 and MCK5 to be accessed and referenced in DT to assign to
> the clocks property for sama7d65 SoC.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---
>  .../devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml       | 2 ++
>  include/dt-bindings/clock/at91.h                              | 4 ++++
>  2 files changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml
> index c9eb60776b4d..885d47dd5724 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,sam9x7-pmc
> +              - microchip,sama7d65-pmc
>                - microchip,sama7g5-pmc
>            - const: syscon
>  
> @@ -90,6 +91,7 @@ allOf:
>              enum:
>                - microchip,sam9x60-pmc
>                - microchip,sam9x7-pmc
> +              - microchip,sama7d65-pmc
>                - microchip,sama7g5-pmc
>      then:
>        properties:
> diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
> index 6ede88c3992d..e37f1b9cdabf 100644
> --- a/include/dt-bindings/clock/at91.h
> +++ b/include/dt-bindings/clock/at91.h
> @@ -42,6 +42,10 @@
>  #define PMC_PLLADIV2		(PMC_MAIN + 11)
>  #define PMC_LVDSPLL		(PMC_MAIN + 12)
>  
> +/* SAMA7D65 */
> +#define PMC_MCK3               (PMC_MAIN + 13)
> +#define PMC_MCK5               (PMC_MAIN + 14)

Spaces here --------^ instead of tabs . I'll adjust it while applying.

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

> +
>  #ifndef AT91_PMC_MOSCS
>  #define AT91_PMC_MOSCS		0		/* MOSCS Flag */
>  #define AT91_PMC_LOCKA		1		/* PLLA Lock */


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:29:55 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:29:55 +0200
Subject: [PATCH v3 09/13] ARM: dts: microchip: add sama7d65 SoC DT
In-Reply-To: <9a6c1dfe-cf4d-41fc-a0f4-b6a111a40c94@tuxon.dev>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <f62e2600a8e88e4be9d87b346c41bb4781f8f667.1733505542.git.Ryan.Wanner@microchip.com>
 <9a6c1dfe-cf4d-41fc-a0f4-b6a111a40c94@tuxon.dev>
Message-ID: <9fbbf3d1-9543-42f8-a80c-1527811109ef@tuxon.dev>



On 08.12.2024 18:28, Claudiu Beznea wrote:
> 
> 
> On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
>> From: Ryan Wanner <Ryan.Wanner at microchip.com>
>>
>> Add Device Tree for sama7d65 SoC.
>>
>> Co-developed-by: Dharma Balasubiramani <dharma.b at microchip.com>
>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
>> Co-developed-by: Romain Sioen <romain.sioen at microchip.com>
>> Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
>> Co-developed-by: Varshini Rajendran <varshini.rajendran at microchip.com>
>> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
>> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
>> ---
>>  arch/arm/boot/dts/microchip/sama7d65.dtsi | 145 ++++++++++++++++++++++
>>  1 file changed, 145 insertions(+)
>>  create mode 100644 arch/arm/boot/dts/microchip/sama7d65.dtsi
>>
>> diff --git a/arch/arm/boot/dts/microchip/sama7d65.dtsi b/arch/arm/boot/dts/microchip/sama7d65.dtsi
>> new file mode 100644
>> index 000000000000..0dcd80690210
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/microchip/sama7d65.dtsi
>> @@ -0,0 +1,145 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + *  sama7d65.dtsi - Device Tree Include file for SAMA7D65 SoC
>> + *
>> + *  Copyright (C) 2024 Microchip Technology, Inc. and its subsidiaries
>> + *
>> + *  Author: Ryan Wanner <Ryan.Wanner at microchip.com>
>> + *
>> + */
>> +
>> +#include <dt-bindings/clock/at91.h>
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>> +#include <dt-bindings/interrupt-controller/irq.h>
>> +#include <dt-bindings/mfd/at91-usart.h>
>> +
>> +/ {
>> +	model = "Microchip SAMA7D65 family SoC";
>> +	compatible = "microchip,sama7d65";
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>> +	interrupt-parent = <&gic>;
>> +
>> +	cpus {
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		cpu0: cpu at 0 {
>> +			compatible = "arm,cortex-a7";
>> +			reg = <0x0>;
>> +			device_type = "cpu";
>> +			clocks = <&pmc PMC_TYPE_CORE PMC_CPUPLL>;
>> +			clock-names = "cpu";
>> +		};
>> +	};
>> +
>> +	clocks {
>> +		main_xtal: clock-mainxtal {
>> +			compatible = "fixed-clock";
>> +			#clock-cells = <0>;
>> +		};
>> +
>> +		 slow_xtal: clock-slowxtal {
>> +			compatible = "fixed-clock";
>> +			#clock-cells = <0>;
>> +		};
>> +
>> +	};
>> +
>> +	soc {
>> +		compatible = "simple-bus";
>> +		ranges;
>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
>> +
>> +		pioa: pinctrl at e0014000 {
>> +			compatible = "microchip,sama7d65-pinctrl";
>> +			reg = <0xe0014000 0x800>;
>> +			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 10>;
>> +			interrupt-controller;
>> +			#interrupt-cells = <2>;
>> +			gpio-controller;
>> +			#gpio-cells = <2>;
>> +		};
>> +
>> +		pmc: clock-controller at e0018000 {
>> +			compatible = "microchip,sama7d65-pmc", "syscon";
>> +			reg = <0xe0018000 0x200>;
>> +			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
>> +			#clock-cells = <2>;
>> +			clocks = <&clk32k 1>, <&clk32k 0>, <&main_xtal>;
>> +			clock-names = "td_slck", "md_slck", "main_xtal";
>> +		};
>> +
>> +		clk32k: clock-controller at e001d500 {
>> +			compatible = "microchip,sama7d65-sckc", "microchip,sam9x60-sckc";
>> +			reg = <0xe001d500 0x4>;
>> +			clocks = <&slow_xtal>;
>> +			#clock-cells = <1>;
>> +		};
>> +
>> +		sdmmc1: mmc at e1208000 {
>> +			compatible = "microchip,sama7d65-sdhci", "microchip,sam9x60-sdhci";
>> +			reg = <0xe1208000 0x400>;
>> +			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 76>, <&pmc PMC_TYPE_GCK 76>;
>> +			clock-names = "hclock", "multclk";
>> +			assigned-clocks = <&pmc PMC_TYPE_GCK 76>;
>> +			assigned-clock-rates = <200000000>;
>> +			assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_MCK1>;
>> +			status = "disabled";
>> +		};
>> +
>> +		pit64b0: timer at e1800000 {
>> +			compatible = "microchip,sama7d65-pit64b", "microchip,sam9x60-pit64b";
>> +			reg = <0xe1800000 0x100>;
>> +			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 66>, <&pmc PMC_TYPE_GCK 66>;
>> +			clock-names = "pclk", "gclk";
>> +		};
>> +
>> +		pit64b1: timer at e1804000 {
>> +			compatible = "microchip,sama7d65-pit64b", "microchip,sam9x60-pit64b";
>> +			reg = <0xe1804000 0x100>;
>> +			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 67>, <&pmc PMC_TYPE_GCK 67>;
>> +			clock-names = "pclk", "gclk";
>> +		};
>> +
>> +		flx6: flexcom at e2020000 {
>> +			compatible = "microchip,sama7d65-flexcom", "atmel,sama5d2-flexcom";
>> +			reg = <0xe2020000 0x200>;
>> +			ranges = <0x0 0xe2020000 0x800>;
>> +			#address-cells = <1>;
>> +			#size-cells = <1>;
>> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 40>;
>> +			status = "disabled";
>> +
>> +			uart6: serial at 200 {
>> +				compatible = "microchip,sama7d65-usart", "atmel,at91sam9260-usart";
>> +				reg = <0x200 0x200>;
>> +				atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
> 
> Vendor specific props would be at the end, before states, according to [1].
> I'll adjust it while applying.
> 
> [1]

This is the link, sorry:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/dts-coding-style.rst#n122

Other than that:
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:27:53 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:27:53 +0200
Subject: [PATCH v3 08/13] clk: at91: sama7d65: add sama7d65 pmc driver
In-Reply-To: <6cf9921c6d312193c34f6f5cbd9eda7d0f9f317c.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <6cf9921c6d312193c34f6f5cbd9eda7d0f9f317c.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <cf52fb1e-2e7f-48a6-8aa8-fd215335f82a@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Ryan Wanner <Ryan.Wanner at microchip.com>
> 
> Add clock support for SAMA7D65 SoC.
> 
> Increase maximum number of valid master clocks. The PMC for the SAMA7D65
> requires 9 master clocks.
> 
> Increase maximum amount of PLLs to 9 to support SAMA7D65 SoC PLL
> requirements.

I personally prefered the other variant where these were introduced as
individual preparatory patches.

> 
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

> ---
>  drivers/clk/at91/Makefile          |    1 +
>  drivers/clk/at91/clk-master.c      |    2 +-
>  drivers/clk/at91/clk-sam9x60-pll.c |    2 +-
>  drivers/clk/at91/pmc.c             |    1 +
>  drivers/clk/at91/sama7d65.c        | 1373 ++++++++++++++++++++++++++++
>  5 files changed, 1377 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/clk/at91/sama7d65.c
> 
> diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
> index 8e3684ba2c74..5e638eb15aba 100644
> --- a/drivers/clk/at91/Makefile
> +++ b/drivers/clk/at91/Makefile
> @@ -25,3 +25,4 @@ 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
>  obj-$(CONFIG_SOC_SAMA7G5) += sama7g5.o
> +obj-$(CONFIG_SOC_SAMA7D65) += sama7d65.o
> diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
> index 15c46489ba85..7a544e429d34 100644
> --- a/drivers/clk/at91/clk-master.c
> +++ b/drivers/clk/at91/clk-master.c
> @@ -20,7 +20,7 @@
>  
>  #define PMC_MCR_CSS_SHIFT	(16)
>  
> -#define MASTER_MAX_ID		4
> +#define MASTER_MAX_ID		9
>  
>  #define to_clk_master(hw) container_of(hw, struct clk_master, hw)
>  
> diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
> index fda041102224..cefd9948e103 100644
> --- a/drivers/clk/at91/clk-sam9x60-pll.c
> +++ b/drivers/clk/at91/clk-sam9x60-pll.c
> @@ -23,7 +23,7 @@
>  #define UPLL_DIV		2
>  #define PLL_MUL_MAX		(FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
>  
> -#define PLL_MAX_ID		7
> +#define PLL_MAX_ID		9
>  
>  struct sam9x60_pll_core {
>  	struct regmap *regmap;
> diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
> index 5aa9c1f1c886..acf780a81589 100644
> --- a/drivers/clk/at91/pmc.c
> +++ b/drivers/clk/at91/pmc.c
> @@ -151,6 +151,7 @@ static struct syscore_ops pmc_syscore_ops = {
>  static const struct of_device_id pmc_dt_ids[] = {
>  	{ .compatible = "atmel,sama5d2-pmc" },
>  	{ .compatible = "microchip,sama7g5-pmc", },
> +	{ .compatible = "microchip,sama7d65-pmc", },
>  	{ /* sentinel */ }
>  };
>  
> diff --git a/drivers/clk/at91/sama7d65.c b/drivers/clk/at91/sama7d65.c
> new file mode 100644
> index 000000000000..7b8dfd6d8b64
> --- /dev/null
> +++ b/drivers/clk/at91/sama7d65.c
> @@ -0,0 +1,1373 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * SAMA7D65 PMC code.
> + *
> + * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
> + *
> + * Author: Ryan Wanner <ryan.wanner 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(pmc_mck0_lock);
> +static DEFINE_SPINLOCK(pmc_mckX_lock);
> +
> +#define PMC_INDEX_MAX	25
> +
> +/*
> + * PLL clocks identifiers
> + * @PLL_ID_CPU:		CPU PLL identifier
> + * @PLL_ID_SYS:		System PLL identifier
> + * @PLL_ID_DDR:		DDR PLL identifier
> + * @PLL_ID_GPU:		Graphics subsystem PLL identifier
> + * @PLL_ID_BAUD:	Baud PLL identifier
> + * @PLL_ID_AUDIO:	Audio PLL identifier
> + * @PLL_ID_ETH:		Ethernet PLL identifier
> + * @PLL_ID_LVDS:	LVDS PLL identifier
> + * @PLL_ID_USB:		USB PLL identifier
> + */
> +enum pll_ids {
> +	PLL_ID_CPU,
> +	PLL_ID_SYS,
> +	PLL_ID_DDR,
> +	PLL_ID_GPU,
> +	PLL_ID_BAUD,
> +	PLL_ID_AUDIO,
> +	PLL_ID_ETH,
> +	PLL_ID_LVDS,
> +	PLL_ID_USB,
> +	PLL_ID_MAX
> +};
> +
> +/*
> + * PLL component identifier
> + * @PLL_COMPID_FRAC: Fractional PLL component identifier
> + * @PLL_COMPID_DIV0: 1st PLL divider component identifier
> + * @PLL_COMPID_DIV1: 2nd PLL divider component identifier
> + */
> +enum pll_component_id {
> +	PLL_COMPID_FRAC,
> +	PLL_COMPID_DIV0,
> +	PLL_COMPID_DIV1,
> +	PLL_COMPID_MAX
> +};
> +
> +/*
> + * PLL type identifiers
> + * @PLL_TYPE_FRAC:	fractional PLL identifier
> + * @PLL_TYPE_DIV:	divider PLL identifier
> + */
> +enum pll_type {
> +	PLL_TYPE_FRAC,
> +	PLL_TYPE_DIV,
> +};
> +
> +/* Layout for fractional PLLs. */
> +static const struct clk_pll_layout pll_layout_frac = {
> +	.mul_mask	= GENMASK(31, 24),
> +	.frac_mask	= GENMASK(21, 0),
> +	.mul_shift	= 24,
> +	.frac_shift	= 0,
> +};
> +
> +/* Layout for DIVPMC dividers. */
> +static const struct clk_pll_layout pll_layout_divpmc = {
> +	.div_mask	= GENMASK(7, 0),
> +	.endiv_mask	= BIT(29),
> +	.div_shift	= 0,
> +	.endiv_shift	= 29,
> +};
> +
> +/* Layout for DIVIO dividers. */
> +static const struct clk_pll_layout pll_layout_divio = {
> +	.div_mask	= GENMASK(19, 12),
> +	.endiv_mask	= BIT(30),
> +	.div_shift	= 12,
> +	.endiv_shift	= 30,
> +};
> +
> +/*
> + * CPU PLL output range.
> + * Notice: The upper limit has been setup to 1000000002 due to hardware
> + * block which cannot output exactly 1GHz.
> + */
> +static const struct clk_range cpu_pll_outputs[] = {
> +	{ .min = 2343750, .max = 1000000002 },
> +};
> +
> +/* PLL output range. */
> +static const struct clk_range pll_outputs[] = {
> +	{ .min = 2343750, .max = 1200000000 },
> +};
> +
> +/*
> + * Min: fCOREPLLCK = 600 MHz, PMC_PLL_CTRL0.DIVPMC = 255
> + * Max: fCOREPLLCK = 800 MHz, PMC_PLL_CTRL0.DIVPMC = 0
> + */
> +static const struct clk_range lvdspll_outputs[] = {
> +	{ .min = 16406250, .max = 800000000 },
> +};
> +
> +static const struct clk_range upll_outputs[] = {
> +	{ .min = 480000000, .max = 480000000 },
> +};
> +
> +/* Fractional PLL core output range. */
> +static const struct clk_range core_outputs[] = {
> +	{ .min = 600000000, .max = 1200000000 },
> +};
> +
> +static const struct clk_range lvdspll_core_outputs[] = {
> +	{ .min = 600000000, .max = 1200000000 },
> +};
> +
> +static const struct clk_range upll_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. */
> +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,
> +};
> +
> +static const struct clk_pll_characteristics lvdspll_characteristics = {
> +	.input = { .min = 12000000, .max = 50000000 },
> +	.num_output = ARRAY_SIZE(lvdspll_outputs),
> +	.output = lvdspll_outputs,
> +	.core_output = lvdspll_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,
> +};
> +
> +/*
> + * SAMA7D65 PLL possible parents
> + * @SAMA7D65_PLL_PARENT_MAINCK: MAINCK is PLL a parent
> + * @SAMA7D65_PLL_PARENT_MAIN_XTAL: MAIN XTAL is a PLL parent
> + * @SAMA7D65_PLL_PARENT_FRACCK: Frac PLL is a PLL parent (for PLL dividers)
> + */
> +enum sama7d65_pll_parent {
> +	SAMA7D65_PLL_PARENT_MAINCK,
> +	SAMA7D65_PLL_PARENT_MAIN_XTAL,
> +	SAMA7D65_PLL_PARENT_FRACCK,
> +};
> +
> +/*
> + * PLL clocks description
> + * @n:		clock name
> + * @l:		clock layout
> + * @c:		clock characteristics
> + * @hw:		pointer to clk_hw
> + * @t:		clock type
> + * @f:		clock flags
> + * @p:		clock parent
> + * @eid:	export index in sama7d65->chws[] array
> + * @safe_div:	intermediate divider need to be set on PRE_RATE_CHANGE
> + *		notification
> + */
> +static struct sama7d65_pll {
> +	const char *n;
> +	const struct clk_pll_layout *l;
> +	const struct clk_pll_characteristics *c;
> +	struct clk_hw *hw;
> +	unsigned long f;
> +	enum sama7d65_pll_parent p;
> +	u8 t;
> +	u8 eid;
> +	u8 safe_div;
> +} sama7d65_plls[][PLL_COMPID_MAX] = {
> +	[PLL_ID_CPU] = {
> +		[PLL_COMPID_FRAC] = {
> +			.n = "cpupll_fracck",
> +			.p = SAMA7D65_PLL_PARENT_MAINCK,
> +			.l = &pll_layout_frac,
> +			.c = &cpu_pll_characteristics,
> +			.t = PLL_TYPE_FRAC,
> +			/*
> +			 * This feeds cpupll_divpmcck which feeds CPU. It should
> +			 * not be disabled.
> +			 */
> +			.f = CLK_IS_CRITICAL,
> +		},
> +
> +		[PLL_COMPID_DIV0] = {
> +			.n = "cpupll_divpmcck",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divpmc,
> +			.c = &cpu_pll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			/* This feeds CPU. It should not be disabled. */
> +			.f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
> +			.eid = PMC_CPUPLL,
> +			/*
> +			 * Safe div=15 should be safe even for switching b/w 1GHz and
> +			 * 90MHz (frac pll might go up to 1.2GHz).
> +			 */
> +			.safe_div = 15,
> +		},
> +	},
> +
> +	[PLL_ID_SYS] = {
> +		[PLL_COMPID_FRAC] = {
> +			.n = "syspll_fracck",
> +			.p = SAMA7D65_PLL_PARENT_MAINCK,
> +			.l = &pll_layout_frac,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_FRAC,
> +			/*
> +			 * This feeds syspll_divpmcck which may feed critical parts
> +			 * of the systems like timers. Therefore it should not be
> +			 * disabled.
> +			 */
> +			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
> +		},
> +
> +		[PLL_COMPID_DIV0] = {
> +			.n = "syspll_divpmcck",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divpmc,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			/*
> +			 * This may feed critical parts of the systems like timers.
> +			 * Therefore it should not be disabled.
> +			 */
> +			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
> +			.eid = PMC_SYSPLL,
> +		},
> +	},
> +
> +	[PLL_ID_DDR] = {
> +		[PLL_COMPID_FRAC] = {
> +			.n = "ddrpll_fracck",
> +			.p = SAMA7D65_PLL_PARENT_MAINCK,
> +			.l = &pll_layout_frac,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_FRAC,
> +			/*
> +			 * This feeds ddrpll_divpmcck which feeds DDR. It should not
> +			 * be disabled.
> +			 */
> +			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
> +		},
> +
> +		[PLL_COMPID_DIV0] = {
> +			.n = "ddrpll_divpmcck",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divpmc,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			/* This feeds DDR. It should not be disabled. */
> +			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
> +		},
> +	},
> +
> +	[PLL_ID_GPU] = {
> +		[PLL_COMPID_FRAC] = {
> +			.n = "gpupll_fracck",
> +			.p = SAMA7D65_PLL_PARENT_MAINCK,
> +			.l = &pll_layout_frac,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_FRAC,
> +			.f = CLK_SET_RATE_GATE,
> +		},
> +
> +		[PLL_COMPID_DIV0] = {
> +			.n = "gpupll_divpmcck",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divpmc,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
> +			     CLK_SET_RATE_PARENT,
> +		},
> +	},
> +
> +	[PLL_ID_BAUD] = {
> +		[PLL_COMPID_FRAC] = {
> +			.n = "baudpll_fracck",
> +			.p = SAMA7D65_PLL_PARENT_MAINCK,
> +			.l = &pll_layout_frac,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_FRAC,
> +			.f = CLK_SET_RATE_GATE,
> +		},
> +
> +		[PLL_COMPID_DIV0] = {
> +			.n = "baudpll_divpmcck",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divpmc,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
> +			     CLK_SET_RATE_PARENT,
> +			.eid = PMC_BAUDPLL,
> +		},
> +	},
> +
> +	[PLL_ID_AUDIO] = {
> +		[PLL_COMPID_FRAC] = {
> +			.n = "audiopll_fracck",
> +			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
> +			.l = &pll_layout_frac,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_FRAC,
> +			.f = CLK_SET_RATE_GATE,
> +		},
> +
> +		[PLL_COMPID_DIV0] = {
> +			.n = "audiopll_divpmcck",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divpmc,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
> +			     CLK_SET_RATE_PARENT,
> +			.eid = PMC_AUDIOPMCPLL,
> +		},
> +
> +		[PLL_COMPID_DIV1] = {
> +			.n = "audiopll_diviock",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divio,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
> +			     CLK_SET_RATE_PARENT,
> +			.eid = PMC_AUDIOIOPLL,
> +		},
> +	},
> +
> +	[PLL_ID_ETH] = {
> +		[PLL_COMPID_FRAC] = {
> +			.n = "ethpll_fracck",
> +			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
> +			.l = &pll_layout_frac,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_FRAC,
> +			.f = CLK_SET_RATE_GATE,
> +		},
> +
> +		[PLL_COMPID_DIV0] = {
> +			.n = "ethpll_divpmcck",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divpmc,
> +			.c = &pll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
> +			     CLK_SET_RATE_PARENT,
> +			.eid = PMC_ETHPLL,
> +		},
> +	},
> +
> +	[PLL_ID_LVDS] = {
> +		[PLL_COMPID_FRAC] = {
> +			.n = "lvdspll_fracck",
> +			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
> +			.l = &pll_layout_frac,
> +			.c = &lvdspll_characteristics,
> +			.t = PLL_TYPE_FRAC,
> +			.f = CLK_SET_RATE_GATE,
> +		},
> +
> +		[PLL_COMPID_DIV0] = {
> +			.n = "lvdspll_divpmcck",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divpmc,
> +			.c = &lvdspll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
> +			     CLK_SET_RATE_PARENT,
> +			.eid = PMC_LVDSPLL,
> +		},
> +	},
> +
> +	[PLL_ID_USB] = {
> +		[PLL_COMPID_FRAC] = {
> +			.n = "usbpll_fracck",
> +			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
> +			.l = &pll_layout_frac,
> +			.c = &upll_characteristics,
> +			.t = PLL_TYPE_FRAC,
> +			.f = CLK_SET_RATE_GATE,
> +		},
> +
> +		[PLL_COMPID_DIV0] = {
> +			.n = "usbpll_divpmcck",
> +			.p = SAMA7D65_PLL_PARENT_FRACCK,
> +			.l = &pll_layout_divpmc,
> +			.c = &upll_characteristics,
> +			.t = PLL_TYPE_DIV,
> +			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
> +			     CLK_SET_RATE_PARENT,
> +			.eid = PMC_UTMI,
> +		},
> +	},
> +};
> +
> +/* Used to create an array entry identifying a PLL by its components. */
> +#define PLL_IDS_TO_ARR_ENTRY(_id, _comp) { PLL_ID_##_id, PLL_COMPID_##_comp}
> +
> +/*
> + * Master clock (MCK[0..9]) description
> + * @n:			clock name
> + * @ep_chg_chg_id:	index in parents array that specifies the changeable
> + * @ep:			extra parents names array (entry formed by PLL components
> + *			identifiers (see enum pll_component_id))
> + * @hw:			pointer to clk_hw
> + *			parent
> + * @ep_count:		extra parents count
> + * @ep_mux_table:	mux table for extra parents
> + * @id:			clock id
> + * @eid:		export index in sama7d65->chws[] array
> + * @c:			true if clock is critical and cannot be disabled
> + */
> +static struct {
> +	const char *n;
> +	struct {
> +		int pll_id;
> +		int pll_compid;
> +	} ep[4];
> +	struct clk_hw *hw;
> +	int ep_chg_id;
> +	u8 ep_count;
> +	u8 ep_mux_table[4];
> +	u8 id;
> +	u8 eid;
> +	u8 c;
> +} sama7d65_mckx[] = {
> +	{ .n = "mck0", }, /* Dummy entry for MCK0 to store hw in probe. */
> +	{ .n = "mck1",
> +	  .id = 1,
> +	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
> +	  .ep_mux_table = { 5, },
> +	  .ep_count = 1,
> +	  .ep_chg_id = INT_MIN,
> +	  .eid = PMC_MCK1,
> +	  .c = 1, },
> +
> +	{ .n = "mck2",
> +	  .id = 2,
> +	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), },
> +	  .ep_mux_table = { 5, 6, },
> +	  .ep_count = 2,
> +	  .ep_chg_id = INT_MIN,
> +	  .c = 1, },
> +
> +	{ .n = "mck3",
> +	  .id = 3,
> +	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), },
> +	  .ep_mux_table = { 5, 6, },
> +	  .ep_count = 2,
> +	  .ep_chg_id = INT_MIN,
> +	  .eid = PMC_MCK3,
> +	  .c = 1, },
> +
> +	{ .n = "mck4",
> +	  .id = 4,
> +	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
> +	  .ep_mux_table = { 5, },
> +	  .ep_count = 1,
> +	  .ep_chg_id = INT_MIN,
> +	  .c = 1, },
> +
> +	{ .n = "mck5",
> +	  .id = 5,
> +	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
> +	  .ep_mux_table = { 5, },
> +	  .ep_count = 1,
> +	  .ep_chg_id = INT_MIN,
> +	  .eid = PMC_MCK5,
> +	  .c = 1, },
> +
> +	{ .n = "mck6",
> +	  .id = 6,
> +	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
> +	  .ep_mux_table = { 5, },
> +	  .ep_chg_id = INT_MIN,
> +	  .ep_count = 1,
> +	  .c = 1, },
> +
> +	{ .n = "mck7",
> +	  .id = 7,
> +	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
> +	  .ep_mux_table = { 5, },
> +	  .ep_chg_id = INT_MIN,
> +	  .ep_count = 1, },
> +
> +	{ .n = "mck8",
> +	  .id = 8,
> +	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
> +	  .ep_mux_table = { 5, },
> +	  .ep_chg_id = INT_MIN,
> +	  .ep_count = 1, },
> +
> +	{ .n = "mck9",
> +	  .id = 9,
> +	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
> +	  .ep_mux_table = { 5, },
> +	  .ep_chg_id = INT_MIN,
> +	  .ep_count = 1, },
> +};
> +
> +/*
> + * System clock description
> + * @n:	clock name
> + * @p:	clock parent name
> + * @id: clock id
> + */
> +static const struct {
> +	const char *n;
> +	const char *p;
> +	u8 id;
> +} sama7d65_systemck[] = {
> +	{ .n = "uhpck",		.p = "usbck", .id = 6 },
> +	{ .n = "pck0",		.p = "prog0", .id = 8, },
> +	{ .n = "pck1",		.p = "prog1", .id = 9, },
> +	{ .n = "pck2",		.p = "prog2", .id = 10, },
> +	{ .n = "pck3",		.p = "prog3", .id = 11, },
> +	{ .n = "pck4",		.p = "prog4", .id = 12, },
> +	{ .n = "pck5",		.p = "prog5", .id = 13, },
> +	{ .n = "pck6",		.p = "prog6", .id = 14, },
> +	{ .n = "pck7",		.p = "prog7", .id = 15, },
> +};
> +
> +/* Mux table for programmable clocks. */
> +static u32 sama7d65_prog_mux_table[] = { 0, 1, 2, 5, 7, 8, 9, 10, 12 };
> +
> +/*
> + * Peripheral clock parent hw identifier (used to index in sama7d65_mckx[])
> + * @PCK_PARENT_HW_MCK0: pck parent hw identifier is MCK0
> + * @PCK_PARENT_HW_MCK1: pck parent hw identifier is MCK1
> + * @PCK_PARENT_HW_MCK2: pck parent hw identifier is MCK2
> + * @PCK_PARENT_HW_MCK3: pck parent hw identifier is MCK3
> + * @PCK_PARENT_HW_MCK4: pck parent hw identifier is MCK4
> + * @PCK_PARENT_HW_MCK5: pck parent hw identifier is MCK5
> + * @PCK_PARENT_HW_MCK6: pck parent hw identifier is MCK6
> + * @PCK_PARENT_HW_MCK7: pck parent hw identifier is MCK7
> + * @PCK_PARENT_HW_MCK8: pck parent hw identifier is MCK8
> + * @PCK_PARENT_HW_MCK9: pck parent hw identifier is MCK9
> + * @PCK_PARENT_HW_MAX: max identifier
> + */
> +enum sama7d65_pck_parent_hw_id {
> +	PCK_PARENT_HW_MCK0,
> +	PCK_PARENT_HW_MCK1,
> +	PCK_PARENT_HW_MCK2,
> +	PCK_PARENT_HW_MCK3,
> +	PCK_PARENT_HW_MCK4,
> +	PCK_PARENT_HW_MCK5,
> +	PCK_PARENT_HW_MCK6,
> +	PCK_PARENT_HW_MCK7,
> +	PCK_PARENT_HW_MCK8,
> +	PCK_PARENT_HW_MCK9,
> +	PCK_PARENT_HW_MAX
> +};
> +
> +/*
> + * Peripheral clock description
> + * @n:		clock name
> + * @p:		clock parent hw id
> + * @r:		clock range values
> + * @id:		clock id
> + * @chgp:	index in parent array of the changeable parent
> + */
> +static struct {
> +	const char *n;
> +	enum sama7d65_pck_parent_hw_id p;
> +	struct clk_range r;
> +	u8 chgp;
> +	u8 id;
> +} sama7d65_periphck[] = {
> +	{ .n = "pioA_clk",	.p = PCK_PARENT_HW_MCK0, .id = 10, },
> +	{ .n = "securam_clk",	.p = PCK_PARENT_HW_MCK0, .id = 17, },
> +	{ .n = "sfr_clk",	.p = PCK_PARENT_HW_MCK7, .id = 18, },
> +	{ .n = "hsmc_clk",	.p = PCK_PARENT_HW_MCK5, .id = 20, },
> +	{ .n = "xdmac0_clk",	.p = PCK_PARENT_HW_MCK6, .id = 21, },
> +	{ .n = "xdmac1_clk",	.p = PCK_PARENT_HW_MCK6, .id = 22, },
> +	{ .n = "xdmac2_clk",	.p = PCK_PARENT_HW_MCK1, .id = 23, },
> +	{ .n = "acc_clk",	.p = PCK_PARENT_HW_MCK7, .id = 24, },
> +	{ .n = "aes_clk",	.p = PCK_PARENT_HW_MCK6, .id = 26, },
> +	{ .n = "tzaesbasc_clk",	.p = PCK_PARENT_HW_MCK8, .id = 27, },
> +	{ .n = "asrc_clk",	.p = PCK_PARENT_HW_MCK9, .id = 29, .r = { .max = 200000000, }, },
> +	{ .n = "cpkcc_clk",	.p = PCK_PARENT_HW_MCK0, .id = 30, },
> +	{ .n = "eic_clk",	.p = PCK_PARENT_HW_MCK7, .id = 33, },
> +	{ .n = "flex0_clk",	.p = PCK_PARENT_HW_MCK7, .id = 34, },
> +	{ .n = "flex1_clk",	.p = PCK_PARENT_HW_MCK7, .id = 35, },
> +	{ .n = "flex2_clk",	.p = PCK_PARENT_HW_MCK7, .id = 36, },
> +	{ .n = "flex3_clk",	.p = PCK_PARENT_HW_MCK7, .id = 37, },
> +	{ .n = "flex4_clk",	.p = PCK_PARENT_HW_MCK8, .id = 38, },
> +	{ .n = "flex5_clk",	.p = PCK_PARENT_HW_MCK8, .id = 39, },
> +	{ .n = "flex6_clk",	.p = PCK_PARENT_HW_MCK8, .id = 40, },
> +	{ .n = "flex7_clk",	.p = PCK_PARENT_HW_MCK8, .id = 41, },
> +	{ .n = "flex8_clk",	.p = PCK_PARENT_HW_MCK9, .id = 42, },
> +	{ .n = "flex9_clk",	.p = PCK_PARENT_HW_MCK9, .id = 43, },
> +	{ .n = "flex10_clk",	.p = PCK_PARENT_HW_MCK9, .id = 44, },
> +	{ .n = "gmac0_clk",	.p = PCK_PARENT_HW_MCK6, .id = 46, },
> +	{ .n = "gmac1_clk",	.p = PCK_PARENT_HW_MCK6, .id = 47, },
> +	{ .n = "gmac0_tsu_clk",	.p = PCK_PARENT_HW_MCK1, .id = 49, },
> +	{ .n = "gmac1_tsu_clk",	.p = PCK_PARENT_HW_MCK1, .id = 50, },
> +	{ .n = "icm_clk",	.p = PCK_PARENT_HW_MCK5, .id = 53, },
> +	{ .n = "i2smcc0_clk",	.p = PCK_PARENT_HW_MCK9, .id = 54, .r = { .max = 200000000, }, },
> +	{ .n = "i2smcc1_clk",	.p = PCK_PARENT_HW_MCK9, .id = 55, .r = { .max = 200000000, }, },
> +	{ .n = "lcd_clk",	.p = PCK_PARENT_HW_MCK3, .id = 56, },
> +	{ .n = "matrix_clk",	.p = PCK_PARENT_HW_MCK5, .id = 57, },
> +	{ .n = "mcan0_clk",	.p = PCK_PARENT_HW_MCK5, .id = 58, .r = { .max = 200000000, }, },
> +	{ .n = "mcan1_clk",	.p = PCK_PARENT_HW_MCK5, .id = 59, .r = { .max = 200000000, }, },
> +	{ .n = "mcan2_clk",	.p = PCK_PARENT_HW_MCK5, .id = 60, .r = { .max = 200000000, }, },
> +	{ .n = "mcan3_clk",	.p = PCK_PARENT_HW_MCK5, .id = 61, .r = { .max = 200000000, }, },
> +	{ .n = "mcan4_clk",	.p = PCK_PARENT_HW_MCK5, .id = 62, .r = { .max = 200000000, }, },
> +	{ .n = "pdmc0_clk",	.p = PCK_PARENT_HW_MCK9, .id = 64, .r = { .max = 200000000, }, },
> +	{ .n = "pdmc1_clk",	.p = PCK_PARENT_HW_MCK9, .id = 65, .r = { .max = 200000000, }, },
> +	{ .n = "pit64b0_clk",	.p = PCK_PARENT_HW_MCK7, .id = 66, },
> +	{ .n = "pit64b1_clk",	.p = PCK_PARENT_HW_MCK7, .id = 67, },
> +	{ .n = "pit64b2_clk",	.p = PCK_PARENT_HW_MCK7, .id = 68, },
> +	{ .n = "pit64b3_clk",	.p = PCK_PARENT_HW_MCK8, .id = 69, },
> +	{ .n = "pit64b4_clk",	.p = PCK_PARENT_HW_MCK8, .id = 70, },
> +	{ .n = "pit64b5_clk",	.p = PCK_PARENT_HW_MCK8, .id = 71, },
> +	{ .n = "pwm_clk",	.p = PCK_PARENT_HW_MCK7, .id = 72, },
> +	{ .n = "qspi0_clk",	.p = PCK_PARENT_HW_MCK5, .id = 73, },
> +	{ .n = "qspi1_clk",	.p = PCK_PARENT_HW_MCK5, .id = 74, },
> +	{ .n = "sdmmc0_clk",	.p = PCK_PARENT_HW_MCK1, .id = 75, },
> +	{ .n = "sdmmc1_clk",	.p = PCK_PARENT_HW_MCK1, .id = 76, },
> +	{ .n = "sdmmc2_clk",	.p = PCK_PARENT_HW_MCK1, .id = 77, },
> +	{ .n = "sha_clk",	.p = PCK_PARENT_HW_MCK6, .id = 78, },
> +	{ .n = "spdifrx_clk",	.p = PCK_PARENT_HW_MCK9, .id = 79, .r = { .max = 200000000, }, },
> +	{ .n = "spdiftx_clk",	.p = PCK_PARENT_HW_MCK9, .id = 80, .r = { .max = 200000000, }, },
> +	{ .n = "ssc0_clk",	.p = PCK_PARENT_HW_MCK7, .id = 81, .r = { .max = 200000000, }, },
> +	{ .n = "ssc1_clk",	.p = PCK_PARENT_HW_MCK8, .id = 82, .r = { .max = 200000000, }, },
> +	{ .n = "tcb0_ch0_clk",	.p = PCK_PARENT_HW_MCK8, .id = 83, .r = { .max = 200000000, }, },
> +	{ .n = "tcb0_ch1_clk",	.p = PCK_PARENT_HW_MCK8, .id = 84, .r = { .max = 200000000, }, },
> +	{ .n = "tcb0_ch2_clk",	.p = PCK_PARENT_HW_MCK8, .id = 85, .r = { .max = 200000000, }, },
> +	{ .n = "tcb1_ch0_clk",	.p = PCK_PARENT_HW_MCK5, .id = 86, .r = { .max = 200000000, }, },
> +	{ .n = "tcb1_ch1_clk",	.p = PCK_PARENT_HW_MCK5, .id = 87, .r = { .max = 200000000, }, },
> +	{ .n = "tcb1_ch2_clk",	.p = PCK_PARENT_HW_MCK5, .id = 88, .r = { .max = 200000000, }, },
> +	{ .n = "tcpca_clk",	.p = PCK_PARENT_HW_MCK5, .id = 89, },
> +	{ .n = "tcpcb_clk",	.p = PCK_PARENT_HW_MCK5, .id = 90, },
> +	{ .n = "tdes_clk",	.p = PCK_PARENT_HW_MCK6, .id = 91, },
> +	{ .n = "trng_clk",	.p = PCK_PARENT_HW_MCK6, .id = 92, },
> +	{ .n = "udphsa_clk",	.p = PCK_PARENT_HW_MCK5, .id = 99, },
> +	{ .n = "udphsb_clk",	.p = PCK_PARENT_HW_MCK5, .id = 100, },
> +	{ .n = "uhphs_clk",	.p = PCK_PARENT_HW_MCK5, .id = 101, },
> +	{ .n = "dsi_clk",	.p = PCK_PARENT_HW_MCK3, .id = 103, },
> +	{ .n = "lvdsc_clk",	.p = PCK_PARENT_HW_MCK3, .id = 104, },
> +};
> +
> +/*
> + * Generic clock description
> + * @n:			clock name
> + * @pp:			PLL parents (entry formed by PLL components identifiers
> + *			(see enum pll_component_id))
> + * @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;
> +	struct {
> +		int pll_id;
> +		int pll_compid;
> +	} pp[8];
> +	const char pp_mux_table[8];
> +	struct clk_range r;
> +	int pp_chg_id;
> +	u8 pp_count;
> +	u8 id;
> +} sama7d65_gck[] = {
> +	{ .n  = "adc_gclk",
> +	  .id = 25,
> +	  .r = { .max = 100000000, },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
> +	  .pp_mux_table = { 8, 9, },
> +	  .pp_count = 2,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "asrc_gclk",
> +	  .id = 29,
> +	  .r = { .max = 200000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
> +	  .pp_mux_table = { 9, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex0_gclk",
> +	  .id = 34,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = {8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex1_gclk",
> +	  .id = 35,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = {8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex2_gclk",
> +	  .id = 36,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = {8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex3_gclk",
> +	  .id = 37,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = {8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex4_gclk",
> +	  .id = 38,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = { 8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex5_gclk",
> +	  .id = 39,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = { 8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex6_gclk",
> +	  .id = 40,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = { 8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex7_gclk",
> +	  .id = 41,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = { 8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex8_gclk",
> +	  .id = 42,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = { 8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex9_gclk",
> +	  .id = 43,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = { 8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "flex10_gclk",
> +	  .id = 44,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = { 8, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "gmac0_gclk",
> +	  .id = 46,
> +	  .r = { .max = 125000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 10, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "gmac1_gclk",
> +	  .id = 47,
> +	  .r = { .max = 125000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 10, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "gmac0_tsu_gclk",
> +	  .id = 49,
> +	  .r = { .max = 400000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = {10, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "gmac1_tsu_gclk",
> +	  .id = 50,
> +	  .r = { .max = 400000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 10, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "i2smcc0_gclk",
> +	  .id = 54,
> +	  .r = { .max = 100000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
> +	  .pp_mux_table = { 9, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "i2smcc1_gclk",
> +	  .id = 55,
> +	  .r = { .max = 100000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
> +	  .pp_mux_table = { 9, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n = "lcdc_gclk",
> +	  .id = 56,
> +	  .r = { .max = 90000000 },
> +	  .pp_count = 0,
> +	  .pp_chg_id = INT_MIN,
> +	},
> +
> +	{ .n  = "mcan0_gclk",
> +	  .id = 58,
> +	  .r = { .max = 80000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
> +	  .pp_mux_table = { 12 },
> +	  .pp_count = 1,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "mcan1_gclk",
> +	  .id = 59,
> +	  .r = { .max = 80000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
> +	  .pp_mux_table = { 12 },
> +	  .pp_count = 1,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "mcan2_gclk",
> +	  .id = 60,
> +	  .r = { .max = 80000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
> +	  .pp_mux_table = { 12 },
> +	  .pp_count = 1,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "mcan3_gclk",
> +	  .id = 61,
> +	  .r = { .max = 80000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
> +	  .pp_mux_table = { 12 },
> +	  .pp_count = 1,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "mcan4_gclk",
> +	  .id = 62,
> +	  .r = { .max = 80000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
> +	  .pp_mux_table = { 12 },
> +	  .pp_count = 1,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "pdmc0_gclk",
> +	  .id = 64,
> +	  .r = { .max = 80000000  },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
> +	  .pp_mux_table = { 9 },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "pdmc1_gclk",
> +	  .id = 65,
> +	  .r = { .max = 80000000, },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
> +	  .pp_mux_table = { 9, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "pit64b0_gclk",
> +	  .id = 66,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
> +		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 8, 9, 10, },
> +	  .pp_count = 3,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "pit64b1_gclk",
> +	  .id = 67,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
> +		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 8, 9, 10, },
> +	  .pp_count = 3,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "pit64b2_gclk",
> +	  .id = 68,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
> +		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 8, 9, 10, },
> +	  .pp_count = 3,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "pit64b3_gclk",
> +	  .id = 69,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
> +		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = {8, 9, 10, },
> +	  .pp_count = 3,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "pit64b4_gclk",
> +	  .id = 70,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
> +		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = {8, 9, 10, },
> +	  .pp_count = 3,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "pit64b5_gclk",
> +	  .id = 71,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
> +		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = {8, 9, 10, },
> +	  .pp_count = 3,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "qspi0_gclk",
> +	  .id = 73,
> +	  .r = { .max = 400000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = { 5, 8, },
> +	  .pp_count = 2,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "qspi1_gclk",
> +	  .id = 74,
> +	  .r = { .max = 266000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
> +	  .pp_mux_table = { 5, 8, },
> +	  .pp_count = 2,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "sdmmc0_gclk",
> +	  .id = 75,
> +	  .r = { .max = 208000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 8, 10, },
> +	  .pp_count = 2,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "sdmmc1_gclk",
> +	  .id = 76,
> +	  .r = { .max = 208000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 8, 10, },
> +	  .pp_count = 2,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "sdmmc2_gclk",
> +	  .id = 77,
> +	  .r = { .max = 208000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 8, 10 },
> +	  .pp_count = 2,
> +	  .pp_chg_id = 4, },
> +
> +	{ .n  = "spdifrx_gclk",
> +	  .id = 79,
> +	  .r = { .max = 150000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
> +	  .pp_mux_table = { 9, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n = "spdiftx_gclk",
> +	  .id = 80,
> +	  .r = { .max = 25000000  },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
> +	  .pp_mux_table = { 9, },
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "tcb0_ch0_gclk",
> +	  .id = 83,
> +	  .r = { .max = 34000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
> +		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 8, 9, 10, },
> +	  .pp_count = 3,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n  = "tcb1_ch0_gclk",
> +	  .id = 86,
> +	  .r = { .max = 67000000 },
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
> +		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = { 8, 9, 10, },
> +	  .pp_count = 3,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n = "DSI_gclk",
> +	  .id = 103,
> +	  .r = {.max = 27000000},
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
> +	  .pp_mux_table = {5},
> +	  .pp_count = 1,
> +	  .pp_chg_id = INT_MIN, },
> +
> +	{ .n = "I3CC_gclk",
> +	  .id = 105,
> +	  .r = {.max = 125000000},
> +	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
> +		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
> +	  .pp_mux_table = {8, 9, 10, },
> +	  .pp_count = 3,
> +	  .pp_chg_id = INT_MIN, },
> +};
> +
> +/* MCK0 characteristics. */
> +static const struct clk_master_characteristics mck0_characteristics = {
> +	.output = { .min = 32768, .max = 200000000 },
> +	.divisors = { 1, 2, 4, 3, 5 },
> +	.have_div3_pres = 1,
> +};
> +
> +/* MCK0 layout. */
> +static const struct clk_master_layout mck0_layout = {
> +	.mask = 0x773,
> +	.pres_shift = 4,
> +	.offset = 0x28,
> +};
> +
> +/* Programmable clock layout. */
> +static const struct clk_programmable_layout programmable_layout = {
> +	.pres_mask = 0xff,
> +	.pres_shift = 8,
> +	.css_mask = 0x1f,
> +	.have_slck_mck = 0,
> +	.is_pres_direct = 1,
> +};
> +
> +/* Peripheral clock layout. */
> +static const struct clk_pcr_layout sama7d65_pcr_layout = {
> +	.offset = 0x88,
> +	.cmd = BIT(31),
> +	.gckcss_mask = GENMASK(12, 8),
> +	.pid_mask = GENMASK(6, 0),
> +};
> +
> +static void __init sama7d65_pmc_setup(struct device_node *np)
> +{
> +	const char *main_xtal_name = "main_xtal";
> +	struct pmc_data *sama7d65_pmc;
> +	const char *parent_names[11];
> +	void **alloc_mem = NULL;
> +	int alloc_mem_size = 0;
> +	struct regmap *regmap;
> +	struct clk_hw *hw, *main_rc_hw, *main_osc_hw, *main_xtal_hw;
> +	struct clk_hw *td_slck_hw, *md_slck_hw;
> +	static struct clk_parent_data parent_data;
> +	struct clk_hw *parent_hws[10];
> +	bool bypass;
> +	int i, j;
> +
> +	td_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "td_slck"));
> +	md_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "md_slck"));
> +	main_xtal_hw = __clk_get_hw(of_clk_get_by_name(np, main_xtal_name));
> +
> +	if (!td_slck_hw || !md_slck_hw || !main_xtal_hw)
> +		return;
> +
> +	regmap = device_node_to_regmap(np);
> +	if (IS_ERR(regmap))
> +		return;
> +
> +	sama7d65_pmc = pmc_data_allocate(PMC_INDEX_MAX,
> +					 nck(sama7d65_systemck),
> +					 nck(sama7d65_periphck),
> +					 nck(sama7d65_gck), 8);
> +	if (!sama7d65_pmc)
> +		return;
> +
> +	alloc_mem = kmalloc(sizeof(void *) *
> +			    (ARRAY_SIZE(sama7d65_mckx) + ARRAY_SIZE(sama7d65_gck)),
> +			    GFP_KERNEL);
> +	if (!alloc_mem)
> +		goto err_free;
> +
> +	main_rc_hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
> +						   50000000);
> +	if (IS_ERR(main_rc_hw))
> +		goto err_free;
> +
> +	bypass = of_property_read_bool(np, "atmel,osc-bypass");
> +
> +	parent_data.name = main_xtal_name;
> +	parent_data.fw_name = main_xtal_name;
> +	main_osc_hw = at91_clk_register_main_osc(regmap, "main_osc", NULL,
> +						 &parent_data, bypass);
> +	if (IS_ERR(main_osc_hw))
> +		goto err_free;
> +
> +	parent_hws[0] = main_rc_hw;
> +	parent_hws[1] = main_osc_hw;
> +	hw = at91_clk_register_sam9x5_main(regmap, "mainck", NULL, parent_hws, 2);
> +	if (IS_ERR(hw))
> +		goto err_free;
> +
> +	sama7d65_pmc->chws[PMC_MAIN] = hw;
> +
> +	for (i = 0; i < PLL_ID_MAX; i++) {
> +		for (j = 0; j < PLL_COMPID_MAX; j++) {
> +			struct clk_hw *parent_hw;
> +
> +			if (!sama7d65_plls[i][j].n)
> +				continue;
> +
> +			switch (sama7d65_plls[i][j].t) {
> +			case PLL_TYPE_FRAC:
> +				switch (sama7d65_plls[i][j].p) {
> +				case SAMA7D65_PLL_PARENT_MAINCK:
> +					parent_hw = sama7d65_pmc->chws[PMC_MAIN];
> +					break;
> +				case SAMA7D65_PLL_PARENT_MAIN_XTAL:
> +					parent_hw = main_xtal_hw;
> +					break;
> +				default:
> +					/* Should not happen. */
> +					parent_hw = NULL;
> +					break;
> +				}
> +
> +				hw = sam9x60_clk_register_frac_pll(regmap,
> +					&pmc_pll_lock, sama7d65_plls[i][j].n,
> +					NULL, parent_hw, i,
> +					sama7d65_plls[i][j].c,
> +					sama7d65_plls[i][j].l,
> +					sama7d65_plls[i][j].f);
> +				break;
> +
> +			case PLL_TYPE_DIV:
> +				hw = sam9x60_clk_register_div_pll(regmap,
> +					&pmc_pll_lock, sama7d65_plls[i][j].n,
> +					NULL, sama7d65_plls[i][0].hw, i,
> +					sama7d65_plls[i][j].c,
> +					sama7d65_plls[i][j].l,
> +					sama7d65_plls[i][j].f,
> +					sama7d65_plls[i][j].safe_div);
> +				break;
> +
> +			default:
> +				continue;
> +			}
> +
> +			if (IS_ERR(hw))
> +				goto err_free;
> +
> +			sama7d65_plls[i][j].hw = hw;
> +			if (sama7d65_plls[i][j].eid)
> +				sama7d65_pmc->chws[sama7d65_plls[i][j].eid] = hw;
> +		}
> +	}
> +
> +	hw = at91_clk_register_master_div(regmap, "mck0", NULL,
> +					  sama7d65_plls[PLL_ID_CPU][1].hw,
> +					  &mck0_layout, &mck0_characteristics,
> +					  &pmc_mck0_lock, CLK_GET_RATE_NOCACHE, 5);
> +	if (IS_ERR(hw))
> +		goto err_free;
> +
> +	sama7d65_pmc->chws[PMC_MCK] = hw;
> +	sama7d65_mckx[PCK_PARENT_HW_MCK0].hw = hw;
> +
> +	parent_hws[0] = md_slck_hw;
> +	parent_hws[1] = td_slck_hw;
> +	parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN];
> +	for (i = PCK_PARENT_HW_MCK1; i < ARRAY_SIZE(sama7d65_mckx); i++) {
> +		u8 num_parents = 3 + sama7d65_mckx[i].ep_count;
> +		struct clk_hw *tmp_parent_hws[8];
> +		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, 3);
> +		PMC_FILL_TABLE(&mux_table[3], sama7d65_mckx[i].ep_mux_table,
> +			       sama7d65_mckx[i].ep_count);
> +		for (j = 0; j < sama7d65_mckx[i].ep_count; j++) {
> +			u8 pll_id = sama7d65_mckx[i].ep[j].pll_id;
> +			u8 pll_compid = sama7d65_mckx[i].ep[j].pll_compid;
> +
> +			tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw;
> +		}
> +		PMC_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
> +			       sama7d65_mckx[i].ep_count);
> +
> +		hw = at91_clk_sama7g5_register_master(regmap, sama7d65_mckx[i].n,
> +						      num_parents, NULL, parent_hws,
> +						      mux_table, &pmc_mckX_lock,
> +						      sama7d65_mckx[i].id,
> +						      sama7d65_mckx[i].c,
> +						      sama7d65_mckx[i].ep_chg_id);
> +		alloc_mem[alloc_mem_size++] = mux_table;
> +
> +		if (IS_ERR(hw))
> +			goto err_free;
> +
> +		sama7d65_mckx[i].hw = hw;
> +		if (sama7d65_mckx[i].eid)
> +			sama7d65_pmc->chws[sama7d65_mckx[i].eid] = hw;
> +	}
> +
> +	parent_names[0] = "syspll_divpmcck";
> +	parent_names[1] = "usbpll_divpmcck";
> +	parent_names[2] = "main_osc";
> +	hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
> +	if (IS_ERR(hw))
> +		goto err_free;
> +
> +	parent_hws[0] = md_slck_hw;
> +	parent_hws[1] = td_slck_hw;
> +	parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN];
> +	parent_hws[3] = sama7d65_plls[PLL_ID_SYS][PLL_COMPID_DIV0].hw;
> +	parent_hws[4] = sama7d65_plls[PLL_ID_DDR][PLL_COMPID_DIV0].hw;
> +	parent_hws[5] = sama7d65_plls[PLL_ID_GPU][PLL_COMPID_DIV0].hw;
> +	parent_hws[6] = sama7d65_plls[PLL_ID_BAUD][PLL_COMPID_DIV0].hw;
> +	parent_hws[7] = sama7d65_plls[PLL_ID_AUDIO][PLL_COMPID_DIV0].hw;
> +	parent_hws[8] = sama7d65_plls[PLL_ID_ETH][PLL_COMPID_DIV0].hw;
> +
> +	for (i = 0; i < 8; i++) {
> +		char name[6];
> +
> +		snprintf(name, sizeof(name), "prog%d", i);
> +
> +		hw = at91_clk_register_programmable(regmap, name, NULL, parent_hws,
> +						    9, i,
> +						    &programmable_layout,
> +						    sama7d65_prog_mux_table);
> +		if (IS_ERR(hw))
> +			goto err_free;
> +
> +		sama7d65_pmc->pchws[i] = hw;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(sama7d65_systemck); i++) {
> +		hw = at91_clk_register_system(regmap, sama7d65_systemck[i].n,
> +					      sama7d65_systemck[i].p, NULL,
> +					      sama7d65_systemck[i].id, 0);
> +		if (IS_ERR(hw))
> +			goto err_free;
> +
> +		sama7d65_pmc->shws[sama7d65_systemck[i].id] = hw;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(sama7d65_periphck); i++) {
> +		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
> +							 &sama7d65_pcr_layout,
> +							 sama7d65_periphck[i].n,
> +							 NULL,
> +							 sama7d65_mckx[sama7d65_periphck[i].p].hw,
> +							 sama7d65_periphck[i].id,
> +							 &sama7d65_periphck[i].r,
> +							 sama7d65_periphck[i].chgp ? 0 :
> +							 INT_MIN, 0);
> +		if (IS_ERR(hw))
> +			goto err_free;
> +
> +		sama7d65_pmc->phws[sama7d65_periphck[i].id] = hw;
> +	}
> +
> +	parent_hws[0] = md_slck_hw;
> +	parent_hws[1] = td_slck_hw;
> +	parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN];
> +	parent_hws[3] = sama7d65_pmc->chws[PMC_MCK1];
> +	for (i = 0; i < ARRAY_SIZE(sama7d65_gck); i++) {
> +		u8 num_parents = 4 + sama7d65_gck[i].pp_count;
> +		struct clk_hw *tmp_parent_hws[8];
> +		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], sama7d65_gck[i].pp_mux_table,
> +			       sama7d65_gck[i].pp_count);
> +		for (j = 0; j < sama7d65_gck[i].pp_count; j++) {
> +			u8 pll_id = sama7d65_gck[i].pp[j].pll_id;
> +			u8 pll_compid = sama7d65_gck[i].pp[j].pll_compid;
> +
> +			tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw;
> +		}
> +		PMC_FILL_TABLE(&parent_hws[4], tmp_parent_hws,
> +			       sama7d65_gck[i].pp_count);
> +
> +		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
> +						 &sama7d65_pcr_layout,
> +						 sama7d65_gck[i].n, NULL,
> +						 parent_hws, mux_table,
> +						 num_parents,
> +						 sama7d65_gck[i].id,
> +						 &sama7d65_gck[i].r,
> +						 sama7d65_gck[i].pp_chg_id);
> +		if (IS_ERR(hw))
> +			goto err_free;
> +
> +		sama7d65_pmc->ghws[sama7d65_gck[i].id] = hw;
> +		alloc_mem[alloc_mem_size++] = mux_table;
> +	}
> +
> +	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7d65_pmc);
> +	kfree(alloc_mem);
> +
> +	return;
> +
> +err_free:
> +	if (alloc_mem) {
> +		for (i = 0; i < alloc_mem_size; i++)
> +			kfree(alloc_mem[i]);
> +		kfree(alloc_mem);
> +	}
> +
> +	kfree(sama7d65_pmc);
> +}
> +
> +/* Some clks are used for a clocksource */
> +CLK_OF_DECLARE(sama7d65_pmc, "microchip,sama7d65-pmc", sama7d65_pmc_setup);


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:28:34 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:28:34 +0200
Subject: [PATCH v3 09/13] ARM: dts: microchip: add sama7d65 SoC DT
In-Reply-To: <f62e2600a8e88e4be9d87b346c41bb4781f8f667.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <f62e2600a8e88e4be9d87b346c41bb4781f8f667.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <9a6c1dfe-cf4d-41fc-a0f4-b6a111a40c94@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Ryan Wanner <Ryan.Wanner at microchip.com>
> 
> Add Device Tree for sama7d65 SoC.
> 
> Co-developed-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Co-developed-by: Romain Sioen <romain.sioen at microchip.com>
> Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
> Co-developed-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/sama7d65.dtsi | 145 ++++++++++++++++++++++
>  1 file changed, 145 insertions(+)
>  create mode 100644 arch/arm/boot/dts/microchip/sama7d65.dtsi
> 
> diff --git a/arch/arm/boot/dts/microchip/sama7d65.dtsi b/arch/arm/boot/dts/microchip/sama7d65.dtsi
> new file mode 100644
> index 000000000000..0dcd80690210
> --- /dev/null
> +++ b/arch/arm/boot/dts/microchip/sama7d65.dtsi
> @@ -0,0 +1,145 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + *  sama7d65.dtsi - Device Tree Include file for SAMA7D65 SoC
> + *
> + *  Copyright (C) 2024 Microchip Technology, Inc. and its subsidiaries
> + *
> + *  Author: Ryan Wanner <Ryan.Wanner at microchip.com>
> + *
> + */
> +
> +#include <dt-bindings/clock/at91.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/mfd/at91-usart.h>
> +
> +/ {
> +	model = "Microchip SAMA7D65 family SoC";
> +	compatible = "microchip,sama7d65";
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	interrupt-parent = <&gic>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu at 0 {
> +			compatible = "arm,cortex-a7";
> +			reg = <0x0>;
> +			device_type = "cpu";
> +			clocks = <&pmc PMC_TYPE_CORE PMC_CPUPLL>;
> +			clock-names = "cpu";
> +		};
> +	};
> +
> +	clocks {
> +		main_xtal: clock-mainxtal {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +		};
> +
> +		 slow_xtal: clock-slowxtal {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +		};
> +
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		ranges;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		pioa: pinctrl at e0014000 {
> +			compatible = "microchip,sama7d65-pinctrl";
> +			reg = <0xe0014000 0x800>;
> +			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 10>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +		};
> +
> +		pmc: clock-controller at e0018000 {
> +			compatible = "microchip,sama7d65-pmc", "syscon";
> +			reg = <0xe0018000 0x200>;
> +			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
> +			#clock-cells = <2>;
> +			clocks = <&clk32k 1>, <&clk32k 0>, <&main_xtal>;
> +			clock-names = "td_slck", "md_slck", "main_xtal";
> +		};
> +
> +		clk32k: clock-controller at e001d500 {
> +			compatible = "microchip,sama7d65-sckc", "microchip,sam9x60-sckc";
> +			reg = <0xe001d500 0x4>;
> +			clocks = <&slow_xtal>;
> +			#clock-cells = <1>;
> +		};
> +
> +		sdmmc1: mmc at e1208000 {
> +			compatible = "microchip,sama7d65-sdhci", "microchip,sam9x60-sdhci";
> +			reg = <0xe1208000 0x400>;
> +			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 76>, <&pmc PMC_TYPE_GCK 76>;
> +			clock-names = "hclock", "multclk";
> +			assigned-clocks = <&pmc PMC_TYPE_GCK 76>;
> +			assigned-clock-rates = <200000000>;
> +			assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_MCK1>;
> +			status = "disabled";
> +		};
> +
> +		pit64b0: timer at e1800000 {
> +			compatible = "microchip,sama7d65-pit64b", "microchip,sam9x60-pit64b";
> +			reg = <0xe1800000 0x100>;
> +			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 66>, <&pmc PMC_TYPE_GCK 66>;
> +			clock-names = "pclk", "gclk";
> +		};
> +
> +		pit64b1: timer at e1804000 {
> +			compatible = "microchip,sama7d65-pit64b", "microchip,sam9x60-pit64b";
> +			reg = <0xe1804000 0x100>;
> +			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 67>, <&pmc PMC_TYPE_GCK 67>;
> +			clock-names = "pclk", "gclk";
> +		};
> +
> +		flx6: flexcom at e2020000 {
> +			compatible = "microchip,sama7d65-flexcom", "atmel,sama5d2-flexcom";
> +			reg = <0xe2020000 0x200>;
> +			ranges = <0x0 0xe2020000 0x800>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 40>;
> +			status = "disabled";
> +
> +			uart6: serial at 200 {
> +				compatible = "microchip,sama7d65-usart", "atmel,at91sam9260-usart";
> +				reg = <0x200 0x200>;
> +				atmel,usart-mode = <AT91_USART_MODE_SERIAL>;

Vendor specific props would be at the end, before states, according to [1].
I'll adjust it while applying.

[1]

> +				interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
> +				clocks = <&pmc PMC_TYPE_PERIPHERAL 40>;
> +				clock-names = "usart";
> +				atmel,fifo-size = <16>;
> +				status = "disabled";
> +			};
> +		};
> +
> +		gic: interrupt-controller at e8c11000 {
> +			compatible = "arm,cortex-a7-gic";
> +			reg = <0xe8c11000 0x1000>,
> +			      <0xe8c12000 0x2000>;
> +			#interrupt-cells = <3>;
> +			#address-cells = <0>;
> +			interrupt-controller;
> +		};
> +	};
> +};


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:30:25 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:30:25 +0200
Subject: [PATCH v3 10/13] ARM: dts: at91: Add sama7d65 pinmux
In-Reply-To: <a8f880b89cd4470526a2955a0b6aaaaa24ba65b8.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <a8f880b89cd4470526a2955a0b6aaaaa24ba65b8.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <022a34e4-2a9e-4cb8-8998-d5decc4d9fdb@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Ryan Wanner <Ryan.Wanner at microchip.com>
> 
> Add sama7d65 pin descriptions.
> 
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:33:34 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:33:34 +0200
Subject: [PATCH v3 12/13] ARM: configs: at91: sama7: add new SoC config
In-Reply-To: <e5a1311100a4f05fdc44107e124129d2d93df2e0.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <e5a1311100a4f05fdc44107e124129d2d93df2e0.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <6ea8fa5a-78e4-46d3-8e20-c2a723bb7e86@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Ryan Wanner <Ryan.Wanner at microchip.com>
> 
> Add sama7d65 to the sama7_defconfig.
> 
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:32:48 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:32:48 +0200
Subject: [PATCH v3 11/13] ARM: dts: microchip: add support for
 sama7d65_curiosity board
In-Reply-To: <e47d8c8cdaec834ce080ef8c34b9976228223c8f.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <e47d8c8cdaec834ce080ef8c34b9976228223c8f.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <81c686e4-2671-4237-a4d4-cac6cf269d9f@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Romain Sioen <romain.sioen at microchip.com>
> 
> Add device tree support for the SAMA7D65 Curiosity board.
> Update the Makefile to include the new device tree file.
> 
> uart6 is related to flexcom6, hence not sorted in alphabetical order.
> 
> Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/Makefile          |  3 +
>  .../dts/microchip/at91-sama7d65_curiosity.dts | 89 +++++++++++++++++++
>  2 files changed, 92 insertions(+)
>  create mode 100644 arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
> 
> diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
> index 470fe46433a9..79cd38fdc7da 100644
> --- a/arch/arm/boot/dts/microchip/Makefile
> +++ b/arch/arm/boot/dts/microchip/Makefile
> @@ -12,6 +12,7 @@ DTC_FLAGS_at91-sama5d2_xplained := -@
>  DTC_FLAGS_at91-sama5d3_eds := -@
>  DTC_FLAGS_at91-sama5d3_xplained := -@
>  DTC_FLAGS_at91-sama5d4_xplained := -@
> +DTC_FLAGS_at91-sama7d65_curiosity := -@
>  DTC_FLAGS_at91-sama7g54_curiosity := -@
>  DTC_FLAGS_at91-sama7g5ek := -@
>  dtb-$(CONFIG_SOC_AT91RM9200) += \
> @@ -90,6 +91,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
>  	at91-sama5d4_xplained.dtb \
>  	at91-sama5d4ek.dtb \
>  	at91-vinco.dtb
> +dtb-$(CONFIG_SOC_SAMA7D65) += \
> +	at91-sama7d65_curiosity.dtb
>  dtb-$(CONFIG_SOC_SAMA7G5) += \
>  	at91-sama7g54_curiosity.dtb \
>  	at91-sama7g5ek.dtb
> diff --git a/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
> new file mode 100644
> index 000000000000..3aab2c542d98
> --- /dev/null
> +++ b/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
> @@ -0,0 +1,89 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + *  at91-sama7d65_curiosity.dts - Device Tree file for SAMA7D65 Curiosity board
> + *
> + *  Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries
> + *
> + *  Author: Romain Sioen <romain.sioen at microchip.com>
> + *
> + */
> +/dts-v1/;
> +#include "sama7d65-pinfunc.h"
> +#include "sama7d65.dtsi"
> +#include <dt-bindings/mfd/atmel-flexcom.h>
> +#include <dt-bindings/pinctrl/at91.h>
> +
> +/ {
> +	model = "Microchip SAMA7D65 Curiosity";
> +	compatible = "microchip,sama7d65-curiosity", "microchip,sama7d65",
> +		     "microchip,sama7d6", "microchip,sama7";
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	aliases {
> +		serial0 = &uart6;
> +	};
> +
> +	memory at 60000000 {
> +		device_type = "memory";
> +		reg = <0x60000000 0x40000000>;
> +	};
> +};
> +
> +&flx6 {
> +	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
> +	status = "okay";
> +};
> +
> +&uart6 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_uart6_default>;
> +	status = "okay";
> +};
> +
> +&main_xtal {
> +	clock-frequency = <24000000>;
> +};
> +
> +&pioA {

Compilation fails for this:

Error: ../arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts:50.1-6
Label or path pioA not found
FATAL ERROR: Syntax error parsing input tree

Thank you,
Claudiu

> +	pinctrl_sdmmc1_default: sdmmc1-default {
> +		cmd-data {
> +			pinmux = <PIN_PB22__SDMMC1_CMD>,
> +				 <PIN_PB24__SDMMC1_DAT0>,
> +				 <PIN_PB25__SDMMC1_DAT1>,
> +				 <PIN_PB26__SDMMC1_DAT2>,
> +				 <PIN_PB27__SDMMC1_DAT3>;
> +			slew-rate = <0>;
> +			bias-disable;
> +		};
> +
> +		ck-cd-rstn-vddsel {
> +			pinmux = <PIN_PB23__SDMMC1_CK>,
> +				 <PIN_PB21__SDMMC1_RSTN>,
> +				 <PIN_PB30__SDMMC1_1V8SEL>,
> +				 <PIN_PB29__SDMMC1_CD>,
> +				 <PIN_PB28__SDMMC1_WP>;
> +			slew-rate = <0>;
> +			bias-disable;
> +		};
> +	};
> +
> +	pinctrl_uart6_default: uart6-default {
> +		pinmux = <PIN_PD18__FLEXCOM6_IO0>,
> +			<PIN_PD19__FLEXCOM6_IO1>;
> +		bias-disable;
> +	};
> +};
> +
> +&sdmmc1 {
> +	bus-width = <4>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sdmmc1_default>;
> +	status = "okay";
> +};
> +
> +&slow_xtal {
> +	clock-frequency = <32768>;
> +};


From claudiu.beznea at tuxon.dev  Sun Dec  8 08:34:18 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:34:18 +0200
Subject: [PATCH v3 13/13] ARM: at91: add new SoC sama7d65
In-Reply-To: <465960c9240553753e96a7f4ff3f48879ade7558.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <465960c9240553753e96a7f4ff3f48879ade7558.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <30d2d8af-836c-440a-8b39-4131e8c85540@tuxon.dev>



On 06.12.2024 21:59, Ryan.Wanner at microchip.com wrote:
> From: Ryan Wanner <Ryan.Wanner at microchip.com>
> 
> Add new SoC from at91 family: sama7d65
> 
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---
>  arch/arm/mach-at91/Kconfig | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
> index 344f5305f69a..2c7179b1baa0 100644
> --- a/arch/arm/mach-at91/Kconfig
> +++ b/arch/arm/mach-at91/Kconfig
> @@ -58,6 +58,15 @@ config SOC_SAMA5D4
>  	help
>  	  Select this if you are using one of Microchip's SAMA5D4 family SoC.
>  
> +config SOC_SAMA7D65
> +        bool "SAMA7D65 family"
> +        depends on ARCH_MULTI_V7
> +        select HAVE_AT91_GENERATED_CLK
> +        select HAVE_AT91_SAM9X60_PLL
> +        select SOC_SAMA7
> +        help
> +         Select this if you are using one of Microchip's SAMA7D65 family SoC.
> +

Spaces ^

Other than this:
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>


>  config SOC_SAMA7G5
>  	bool "SAMA7G5 family"
>  	depends on ARCH_MULTI_V7


From christophe.jaillet at wanadoo.fr  Sun Dec  8 08:35:56 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun, 8 Dec 2024 17:35:56 +0100
Subject: [PATCH v3 08/13] clk: at91: sama7d65: add sama7d65 pmc driver
In-Reply-To: <6cf9921c6d312193c34f6f5cbd9eda7d0f9f317c.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <6cf9921c6d312193c34f6f5cbd9eda7d0f9f317c.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <c0206c74-33d3-4715-9a01-256394919fc8@wanadoo.fr>

Le 06/12/2024 ? 20:59, Ryan.Wanner at microchip.com a ?crit?:
> From: Ryan Wanner <Ryan.Wanner at microchip.com>
> 
> Add clock support for SAMA7D65 SoC.
> 
> Increase maximum number of valid master clocks. The PMC for the SAMA7D65
> requires 9 master clocks.
> 
> Increase maximum amount of PLLs to 9 to support SAMA7D65 SoC PLL
> requirements.
> 
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>

...

> +	for (i = 0; i < ARRAY_SIZE(sama7d65_gck); i++) {
> +		u8 num_parents = 4 + sama7d65_gck[i].pp_count;
> +		struct clk_hw *tmp_parent_hws[8];
> +		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], sama7d65_gck[i].pp_mux_table,
> +			       sama7d65_gck[i].pp_count);
> +		for (j = 0; j < sama7d65_gck[i].pp_count; j++) {
> +			u8 pll_id = sama7d65_gck[i].pp[j].pll_id;
> +			u8 pll_compid = sama7d65_gck[i].pp[j].pll_compid;
> +
> +			tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw;
> +		}
> +		PMC_FILL_TABLE(&parent_hws[4], tmp_parent_hws,
> +			       sama7d65_gck[i].pp_count);
> +
> +		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
> +						 &sama7d65_pcr_layout,
> +						 sama7d65_gck[i].n, NULL,
> +						 parent_hws, mux_table,
> +						 num_parents,
> +						 sama7d65_gck[i].id,
> +						 &sama7d65_gck[i].r,
> +						 sama7d65_gck[i].pp_chg_id);
> +		if (IS_ERR(hw))

If we fail here, mux_table is not freed, because it is not stored yet in 
alloc_mem.

> +			goto err_free;
> +
> +		sama7d65_pmc->ghws[sama7d65_gck[i].id] = hw;
> +		alloc_mem[alloc_mem_size++] = mux_table;
> +	}
> +
> +	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7d65_pmc);
> +	kfree(alloc_mem);
> +
> +	return;
> +
> +err_free:
> +	if (alloc_mem) {
> +		for (i = 0; i < alloc_mem_size; i++)
> +			kfree(alloc_mem[i]);
> +		kfree(alloc_mem);
> +	}
> +
> +	kfree(sama7d65_pmc);
> +}
> +
> +/* Some clks are used for a clocksource */
> +CLK_OF_DECLARE(sama7d65_pmc, "microchip,sama7d65-pmc", sama7d65_pmc_setup);

CJ



From markuss.broks at gmail.com  Sun Dec  8 08:38:50 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Sun, 8 Dec 2024 18:38:50 +0200
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <2eedbbe1-6b4c-427b-a369-5b08dc27deaf@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-3-tudor.ambarus@linaro.org>
 <ce757b8e-4e6c-4ba9-9483-b57e6e230fdf@linaro.org>
 <vxqi23hxw7bmtfs5wk3u7szganpv5aa74b26xrvpmbehkltodw@dpum7zrxdz44>
 <2eedbbe1-6b4c-427b-a369-5b08dc27deaf@linaro.org>
Message-ID: <0ba62a72-8247-447f-b710-234385a29d14@gmail.com>


On 12/6/24 9:50 PM, Daniel Lezcano wrote:
> On 12/6/24 14:28, Krzysztof Kozlowski wrote:
>> On Fri, Dec 06, 2024 at 12:39:56AM +0100, Daniel Lezcano wrote:
>>>> +# SPDX-License-Identifier: GPL-2.0-only
>>>> +
>>>> +config EXYNOS_ACPM_PROTOCOL
>>>> +??? tristate "Exynos Alive Clock and Power Manager (ACPM) Message 
>>>> Protocol"
>>>
>>> Given the importance of this driver where a lot of PM services rely 
>>> on, does
>>> it really make sense to allow it as a module ?
>>>
>>> Some PM services may be needed very early in the boot process
>>>
>>
>> If it works as module e.g. on Android, it is beneficial. I think the
>> platform was booting fine without it, at least to some shell, so I can
>> imagine this can be loaded a bit later.
>
> Usually the firmware sets the frequency to the maximum in order to 
> boot the kernel as fast as possible. That may lead to thermal issues 
> at boot time where the thermal framework won't be able to kick in as 
> some components will depends on ACPM while the system stays at its 
> highest performance state.
Also, as far as I understand, ACPM is used here as an interface to the 
PMIC, so every driver which would need power management from the main 
SoC PMIC would get deferred until the ACPM module has been loaded. This 
would make it impossible to e.g. initialize the UFS or the MMC card 
before initramfs.
>
>
- Markuss



From claudiu.beznea at tuxon.dev  Sun Dec  8 08:44:04 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 8 Dec 2024 18:44:04 +0200
Subject: [PATCH v3 08/13] clk: at91: sama7d65: add sama7d65 pmc driver
In-Reply-To: <c0206c74-33d3-4715-9a01-256394919fc8@wanadoo.fr>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <6cf9921c6d312193c34f6f5cbd9eda7d0f9f317c.1733505542.git.Ryan.Wanner@microchip.com>
 <c0206c74-33d3-4715-9a01-256394919fc8@wanadoo.fr>
Message-ID: <d5d102c0-e4d8-4041-8899-6a732a514046@tuxon.dev>



On 08.12.2024 18:35, Christophe JAILLET wrote:
> Le 06/12/2024 ? 20:59, Ryan.Wanner at microchip.com a ?crit?:
>> From: Ryan Wanner <Ryan.Wanner at microchip.com>
>>
>> Add clock support for SAMA7D65 SoC.
>>
>> Increase maximum number of valid master clocks. The PMC for the SAMA7D65
>> requires 9 master clocks.
>>
>> Increase maximum amount of PLLs to 9 to support SAMA7D65 SoC PLL
>> requirements.
>>
>> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> 
> ...
> 
>> +??? for (i = 0; i < ARRAY_SIZE(sama7d65_gck); i++) {
>> +??????? u8 num_parents = 4 + sama7d65_gck[i].pp_count;
>> +??????? struct clk_hw *tmp_parent_hws[8];
>> +??????? 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], sama7d65_gck[i].pp_mux_table,
>> +?????????????????? sama7d65_gck[i].pp_count);
>> +??????? for (j = 0; j < sama7d65_gck[i].pp_count; j++) {
>> +??????????? u8 pll_id = sama7d65_gck[i].pp[j].pll_id;
>> +??????????? u8 pll_compid = sama7d65_gck[i].pp[j].pll_compid;
>> +
>> +??????????? tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw;
>> +??????? }
>> +??????? PMC_FILL_TABLE(&parent_hws[4], tmp_parent_hws,
>> +?????????????????? sama7d65_gck[i].pp_count);
>> +
>> +??????? hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
>> +???????????????????????? &sama7d65_pcr_layout,
>> +???????????????????????? sama7d65_gck[i].n, NULL,
>> +???????????????????????? parent_hws, mux_table,
>> +???????????????????????? num_parents,
>> +???????????????????????? sama7d65_gck[i].id,
>> +???????????????????????? &sama7d65_gck[i].r,
>> +???????????????????????? sama7d65_gck[i].pp_chg_id);
>> +??????? if (IS_ERR(hw))
> 
> If we fail here, mux_table is not freed, because it is not stored yet in
> alloc_mem.

You're right! I missed that.


From dario.binacchi at amarulasolutions.com  Sun Dec  8 08:47:26 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 8 Dec 2024 17:47:26 +0100
Subject: [PATCH v5 15/20] dt-bindings: clock: imx8m-clock: support spread
 spectrum clocking
In-Reply-To: <gbymcmoya7dfmedq4nkopqpswh63d2ujxl2elc2x7x325b75bu@anp36sdya43v>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
 <20241205111939.1796244-16-dario.binacchi@amarulasolutions.com> <gbymcmoya7dfmedq4nkopqpswh63d2ujxl2elc2x7x325b75bu@anp36sdya43v>
Message-ID: <CABGWkvoQzAhpVJ+QRfVZeps-Jn8REGF+21SPN=f24Tdf1d5DDQ@mail.gmail.com>

On Fri, Dec 6, 2024 at 2:04?PM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On Thu, Dec 05, 2024 at 12:17:50PM +0100, Dario Binacchi wrote:
> > The patch adds the DT bindings for enabling and tuning spread spectrum
> > clocking generation.
> >
> > Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> >
> > ---
> >
> > (no changes since v4)
> >
> > Changes in v4:
> > - Drop "fsl,ssc-clocks" property. The other added properties now refer
> >   to the clock list.
> > - Updated minItems and maxItems of
> >   - clocks
> >   - clock-names
> >   - fsl,ssc-modfreq-hz
> >   - fsl,ssc-modrate-percent
> >   - fsl,ssc-modmethod
> > - Updated the dts examples
> >
> > Changes in v3:
> > - Added in v3
> > - The dt-bindings have been moved from fsl,imx8m-anatop.yaml to
> >   imx8m-clock.yaml. The anatop device (fsl,imx8m-anatop.yaml) is
> >   indeed more or less a syscon, so it represents a memory area
> >   accessible by ccm (imx8m-clock.yaml) to setup the PLLs.
> >
> > Changes in v2:
> > - Add "allOf:" and place it after "required:" block, like in the
> >   example schema.
> > - Move the properties definition to the top-level.
> > - Drop unit types as requested by the "make dt_binding_check" command.
> >
> >  .../bindings/clock/imx8m-clock.yaml           | 77 +++++++++++++++++--
> >  1 file changed, 71 insertions(+), 6 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
> > index c643d4a81478..83036f6d2274 100644
> > --- a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
> > +++ b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
> > @@ -29,12 +29,12 @@ properties:
> >      maxItems: 2
> >
> >    clocks:
> > -    minItems: 6
> > -    maxItems: 7
> > +    minItems: 7
> > +    maxItems: 10
>
> ABI break without mentioning, without any explanation in the commit msg.
>
> >
> >    clock-names:
> > -    minItems: 6
> > -    maxItems: 7
> > +    minItems: 7
> > +    maxItems: 10
> >
> >    '#clock-cells':
> >      const: 1
> > @@ -43,6 +43,34 @@ properties:
> >        ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8m-clock.h
> >        for the full list of i.MX8M clock IDs.
> >
> > +  fsl,ssc-modfreq-hz:
> > +    description:
> > +      The values of modulation frequency (Hz unit) for each clock
> > +      supporting spread spectrum.
> > +    minItems: 7
> > +    maxItems: 10
>
> Why all cloks receive now spread spectrum? I had impression - and all
> your previous versions were doing this - that you have only three or
> four clocks with SSC.

Exactly. Indeed, the first six values are not valid as SSC properties but are
only used to reach the point where the first PLL with SSC (i.e., audio_pll1)
can be indexed, which is in position 7 in the clocks list.
This was the rationale I followed.
And it is explicitly outlined in the example section.
The "" for the fsl,ssc-method property is precisely aimed at specifying a
"no SSC" method, which also fixes the warning:

fsl,ssc-method:0: '' is not one of ['down-spread', 'up-spread', 'center-spread']

raised by
make dt_binding_check DT_SCHEMA_FILES=imx8m-clock.yaml

Or would it be acceptable to specify a list of SSC values that applies only to
the last 4 PLLs in the clocks list?

I feel like I might be missing something.

Could you kindly suggest what to do or provide a DTS example to show me
what you expect?

Thanks and regards,
Dario

>
> Do existing clocks 1-6 support SSC?
>
> > +
> > +  fsl,ssc-modrate-percent:
> > +    description:
> > +      The percentage values of modulation rate for each clock
> > +      supporting spread spectrum.
> > +    minItems: 7
> > +    maxItems: 10
> > +
> > +  fsl,ssc-modmethod:
> > +    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
> > +    description:
> > +      The modulation techniques for each clock supporting spread
> > +      spectrum.
> > +    minItems: 7
> > +    maxItems: 10
> > +    items:
> > +      enum:
> > +        - ""
>
> Drop "", not sure why do you need it.
>
> > +        - down-spread
> > +        - up-spread
> > +        - center-spread
> > +
> >  required:
> >    - compatible
> >    - reg
> > @@ -76,6 +104,10 @@ allOf:
> >              - const: clk_ext2
> >              - const: clk_ext3
> >              - const: clk_ext4
> > +        fsl,ssc-modfreq-hz: false
> > +        fsl,ssc-modrate-percent: false
> > +        fsl,ssc-modmethod: false
> > +
> >      else:
> >        properties:
> >          clocks:
> > @@ -86,6 +118,10 @@ allOf:
> >              - description: ext2 clock input
> >              - description: ext3 clock input
> >              - description: ext4 clock input
> > +            - description: audio1 PLL input
> > +            - description: audio2 PLL input
> > +            - description: dram PLL input
> > +            - description: video PLL input
>
> Also ABI break....
>
> Best regards,
> Krzysztof
>


-- 

Dario Binacchi

Senior Embedded Linux Developer

dario.binacchi at amarulasolutions.com

__________________________________


Amarula Solutions SRL

Via Le Canevare 30, 31100 Treviso, Veneto, IT

T. +39 042 243 5310
info at amarulasolutions.com

www.amarulasolutions.com


From David.Laight at ACULAB.COM  Sun Dec  8 08:48:58 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sun, 8 Dec 2024 16:48:58 +0000
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <6658618490381cf5ec35edbb66f1478024174e67.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
	 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>
	 <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
	 <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de>
	 <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>
	 <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de>
	 <b71056c1b9e04aa383f2e5608c27290f@AcuMS.aculab.com>
 <6658618490381cf5ec35edbb66f1478024174e67.camel@gwdg.de>
Message-ID: <e71fffb7ff0e4bf29692d006c0fe77c2@AcuMS.aculab.com>

From: Martin Uecker
> Sent: 08 December 2024 12:38
> 
> Am Sonntag, dem 08.12.2024 um 11:26 +0000 schrieb David Laight:
> > From: Martin Uecker
> > > Sent: 07 December 2024 23:52
> > ...
> > > While the compiler can not automatically prove every use
> > > of VLA bounded, it can reliably diagnose the cases where it
> > > can?*not* see that it is bounded. Consider this example:
> > >
> > > void oob(int n, char p[n]);
> > > void f(unsigned int n)
> > > {
> > >     char buf[MIN(n, 100)]; // bounded
> > >     oob(n + 10, buf); // warning
> > > }
> > ...
> >
> > The kernel stack has to have enough space for the [100]
> > so the full amount might as well always be allocated.
> > The chance of 'trading off' stack usage with another function
> > in the same call stack that is guaranteed to use less than
> > its maximum is about zero.
> 
> In numerical computing this is a big motivation because
> you can reduce stack usage in recursive divide-and-conquer
> algorithms.  For the kernel, I agree this is not a
> compelling use case, and the better motivation would be
> precise bounds checking and clearer semantics for buffer
> management.

Except that changing the size of the on-stack array makes
absolutely no difference.
Ideally the kernel stack would be a single 4k page, but too
much code uses on-stack buffers so it has been increased and
might be 16k (or more!).
Remember this is physical memory allocated to every user thread.
On Linux it is not swappable.

...
> > This happened for 'constant' sizes from min(16, sizeof (struct))
> > because min() needs to be a statement function to avoid re-evaluating
> > its arguments.
> 
> Can you clarify this?  If the VLA size is constant, even when
> it is not an integer constant expression according to ISO C,
> the compiler should not produce worse code.  For example,

I just tried to reproduce the failing case - and failed.
It was similar to __builtin_constant_p() initially returning 'don't know'
so the 'variable sized' array code got added, then much later
after further optimisation passes the expression became constant.
So you ended up with a 'fixed size' VLA.

Compile with -Wno-vla (and -Werror) and the compile failed.

...
> So a lot of this macro business seems to be necessary
> to avoid creating warnings for ISO VLAs when instead you really
> care about the created code not having a dynamic allocation on
> the stack.

A lot of the 'macro business' for min/max is avoiding unexpected
conversion of negative values to very large unsigned ones.
And no, -Wsign-compare is spectacularly useless.

..
> The issue here is that we miss a language feature in C to
> introduce local variables that help avoid multiple expansion
> of macro arguments.  GCC's statement expressions and __auto_type
> are a solution

or historically 'typeof(x) _x = x'

> #define foo(x) ({ __auto_type __x = (x); ... })
> 
> but this runs into the current limitations that ({ }) can not be used
> at file-scope and can not return constant expressions.
> 
> 
> For other reasons I was thinking about adding names to _Generic,
> as in
> 
> _Generic(x, int i: (i + 1));
> 
> because one design issues with _Generic is that it typechecks
> also the untaken associations and there the 'x' then has the wrong
> type.  Having an 'i' with the right type which is set to the value
> of 'x' when the branch is taken would fix this issue.

That looks even more syntactically obscure than _Generic itself.
Why does it need to do more than very simple syntax analysis of
the unwanted branches - or they could automatically be analysed
with the named variable have the specified type?

> But this feature might also allow writing macros that avoid
> double expansion without requiring statement expressions (which
> are more difficult to fix):
> 
> #define foo(x) _Generic(x, int i: (i + i));

How can that work for things like min() that have multiple arguments?
Not going to work if you need __auto_type either.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From vkoul at kernel.org  Sun Dec  8 08:58:57 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 08 Dec 2024 22:28:57 +0530
Subject: [PATCH] phy: stm32: work around constant-value overflow
 assertion
In-Reply-To: <20241111103712.3520611-1-arnd@kernel.org>
References: <20241111103712.3520611-1-arnd@kernel.org>
Message-ID: <173367713788.1031947.8609520201420590738.b4-ty@kernel.org>


On Mon, 11 Nov 2024 11:37:02 +0100, Arnd Bergmann wrote:
> FIELD_PREP() checks that a constant fits into the available bitfield,
> but if one of the two lookup tables in stm32_impedance_tune() does
> not find a matching entry, the index is out of range, which gcc
> correctly complains about:
> 
> In file included from <command-line>:
> In function 'stm32_impedance_tune',
>     inlined from 'stm32_combophy_pll_init' at drivers/phy/st/phy-stm32-combophy.c:247:9:
> include/linux/compiler_types.h:517:38: error: call to '__compiletime_assert_447' declared with attribute error: FIELD_PREP: value too large for the field
>   517 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>       |                                      ^
> include/linux/bitfield.h:68:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
>    68 |   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?  \
>   115 |   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
>       |   ^~~~~~~~~~~~~~~~
> drivers/phy/st/phy-stm32-combophy.c:162:8: note: in expansion of macro 'FIELD_PREP'
>   162 |        FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
>       |        ^~~~~~~~~~
> 
> [...]

Applied, thanks!

[1/1] phy: stm32: work around constant-value overflow assertion
      commit: 2de679ecd724b823c2cb58caab8508c7eec8aefc

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Sun Dec  8 08:58:48 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 08 Dec 2024 22:28:48 +0530
Subject: (subset) [PATCH 1/2] arm64: dts: rockchip: rk3568: add
 reset-names for combphy
In-Reply-To: <20241122073006.99309-1-amadeus@jmu.edu.cn>
References: <20241122073006.99309-1-amadeus@jmu.edu.cn>
Message-ID: <173367712869.1031947.3262464465649332012.b4-ty@kernel.org>


On Fri, 22 Nov 2024 15:30:05 +0800, Chukun Pan wrote:
> The reset-names of combphy are missing, add it.
> 
> 

Applied, thanks!

[2/2] phy: rockchip: naneng-combphy: fix phy reset
      commit: fbcbffbac994aca1264e3c14da96ac9bfd90466e

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Sun Dec  8 08:59:02 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 08 Dec 2024 22:29:02 +0530
Subject: [PATCH] phy: rockchip: samsung-hdptx: Set drvdata before
 enabling runtime PM
In-Reply-To: <20241023-phy-sam-hdptx-rpm-fix-v1-1-87f4c994e346@collabora.com>
References: <20241023-phy-sam-hdptx-rpm-fix-v1-1-87f4c994e346@collabora.com>
Message-ID: <173367714219.1031947.13630149874442977785.b4-ty@kernel.org>


On Wed, 23 Oct 2024 20:29:54 +0300, Cristian Ciocaltea wrote:
> In some cases, rk_hdptx_phy_runtime_resume() may be invoked before
> platform_set_drvdata() is executed in ->probe(), leading to a NULL
> pointer dereference when using the return of dev_get_drvdata().
> 
> Ensure platform_set_drvdata() is called before devm_pm_runtime_enable().
> 
> 
> [...]

Applied, thanks!

[1/1] phy: rockchip: samsung-hdptx: Set drvdata before enabling runtime PM
      commit: 9d23e48654620fdccfcc74cc2cef04eaf7353d07

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Sun Dec  8 09:03:04 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 08 Dec 2024 22:33:04 +0530
Subject: [PATCH] phy: mediatek: phy-mtk-hdmi: Register PHY provided
 regulator
In-Reply-To: <20241120124143.132637-1-angelogioacchino.delregno@collabora.com>
References: <20241120124143.132637-1-angelogioacchino.delregno@collabora.com>
Message-ID: <173367738439.1042266.5465775023620885336.b4-ty@kernel.org>


On Wed, 20 Nov 2024 13:41:43 +0100, AngeloGioacchino Del Regno wrote:
> At least version 2 of the HDMI PHY, found in MediaTek MT8195 and
> MT8188 SoCs, does provide hardware support to switch on/off the
> HDMI 5V pins (which are also used for DDC), and this translates
> to this being a fixed regulator.
> 
> Register this PHY-provided regulator so that it can be fed to the
> hdmi-connector driver to manage the HDMI +5V PWR rail.
> 
> [...]

Applied, thanks!

[1/1] phy: mediatek: phy-mtk-hdmi: Register PHY provided regulator
      commit: 49393b2da1cd5b0a6859693369b4fb27df59d3e2

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Sun Dec  8 09:03:18 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 08 Dec 2024 22:33:18 +0530
Subject: [RESEND PATCH v3 1/2] dt-bindings: phy: rockchip: add rk3576
 compatible
In-Reply-To: <20241106021357.19782-1-frawang.cn@gmail.com>
References: <20241106021357.19782-1-frawang.cn@gmail.com>
Message-ID: <173367739882.1042266.13564574904755489254.b4-ty@kernel.org>


On Wed, 06 Nov 2024 10:13:56 +0800, Frank Wang wrote:
> Adds the compatible line to support RK3576 SoC.
> 
> 

Applied, thanks!

[1/2] dt-bindings: phy: rockchip: add rk3576 compatible
      commit: b136e9928dbe5e71474d9e2c8911c4a094e329c2
[2/2] phy: rockchip-naneng-combo: add rk3576 support
      commit: ba8ad7eece66ac5c579dd8de39efc72770e7cf64

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Sun Dec  8 09:03:31 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 08 Dec 2024 22:33:31 +0530
Subject: [PATCH] phy: samsung-ufs: switch back to
 syscon_regmap_lookup_by_phandle()
In-Reply-To: <20241029192107.2344279-1-peter.griffin@linaro.org>
References: <20241029192107.2344279-1-peter.griffin@linaro.org>
Message-ID: <173367741186.1042266.15067476399278032405.b4-ty@kernel.org>


On Tue, 29 Oct 2024 19:21:07 +0000, Peter Griffin wrote:
> Now exynos-pmu can register its custom regmap for gs101 via
> of_syscon_register_regmap() we can switch back to the standard
> syscon_regmap_lookup_by_phandle() api for obtaining the regmap.
> 
> Additionally add a Kconfig dependency for MFD_SYSCON.
> 
> 
> [...]

Applied, thanks!

[1/1] phy: samsung-ufs: switch back to syscon_regmap_lookup_by_phandle()
      commit: 0d9fff6c57fee5cccba414a0c40d75812121bdd8

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Sun Dec  8 09:02:40 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 08 Dec 2024 22:32:40 +0530
Subject: [PATCH v3 0/6] RK3399: PCie Phy using new helper function
In-Reply-To: <20241012071919.3726-1-linux.amoon@gmail.com>
References: <20241012071919.3726-1-linux.amoon@gmail.com>
Message-ID: <173367736033.1042266.11057456243557400488.b4-ty@kernel.org>


On Sat, 12 Oct 2024 12:49:02 +0530, Anand Moon wrote:
> Few clean of the phy change and Using guard notation makes the code
> more compact and error handling for mutex_lock/mutex_unlock.
> 
> Plz review te code changes, I tend to do silly mistake.
> 
> v1:
> [1] https://lore.kernel.org/all/20240901183221.240361-5-linux.amoon at gmail.com/
> v2: Fix some typo in the subjects.
> [2] https://lore.kernel.org/all/20241006182445.3713-1-linux.amoon at gmail.com/
> 
> [...]

Applied, thanks!

[1/6] phy: rockchip-pcie: Simplify error handling with dev_err_probe()
      commit: 84de918083d09500d93d991d8989addfaae1611e
[2/6] phy: rockchip-pcie: Use devm_clk_get_enabled() helper
      commit: e96397db55e5fbe290ff1462ddf6c24ed94eb7df
[3/6] phy: rockchip-pcie: Use regmap_read_poll_timeout() for PCIe reference clk PLL status
      commit: cb0ba26ad09398d3d0d10f518af4ccae69c8b64e
[4/6] phy: rockchip-pcie: Refactor mutex handling in rockchip_pcie_phy_power_off()
      commit: bb70d1aae565fd52e6a50e643d1ad6e7d419c2a5
[5/6] phy: rockchip-pcie: Refactor mutex handling in rockchip_pcie_phy_power_on()
      commit: 96522eeb8735449957272e9c6f8ea3b72dcbdeb8
[6/6] phy: rockchip-pcie: Use guard notation when acquiring mutex
      commit: c90a7a685a5d90228cedf7a5068f50b3da23ddfc

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Sun Dec  8 09:02:58 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 08 Dec 2024 22:32:58 +0530
Subject: [PATCH v2] dt-bindings: phy: imx8mq-usb: correct reference to
 usb-switch.yaml
In-Reply-To: <20241119105017.917833-1-xu.yang_2@nxp.com>
References: <20241119105017.917833-1-xu.yang_2@nxp.com>
Message-ID: <173367737834.1042266.7257733372756734157.b4-ty@kernel.org>


On Tue, 19 Nov 2024 18:50:17 +0800, Xu Yang wrote:
> The i.MX95 usb-phy can work with or without orientation-switch. With
> current setting, if usb-phy works without orientation-switch, the
> dt-schema check will show below error:
> 
> phy at 4c1f0040: 'oneOf' conditional failed, one must be fixed:
>         'port' is a required property
>         'ports' is a required property
>         from schema $id: http://devicetree.org/schemas/phy/fsl,imx8mq-usb-phy.yaml#
> 
> [...]

Applied, thanks!

[1/1] dt-bindings: phy: imx8mq-usb: correct reference to usb-switch.yaml
      commit: 2318ca5994599bb4d287e9e00ae87e0855cba712

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Sun Dec  8 09:03:38 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Sun, 08 Dec 2024 22:33:38 +0530
Subject: [PATCH v1 1/1] phy: sun4i-usb: Remove unused of_gpio.h
In-Reply-To: <20241031104631.2454581-1-andriy.shevchenko@linux.intel.com>
References: <20241031104631.2454581-1-andriy.shevchenko@linux.intel.com>
Message-ID: <173367741843.1042266.6194820698713604064.b4-ty@kernel.org>


On Thu, 31 Oct 2024 12:46:31 +0200, Andy Shevchenko wrote:
> of_gpio.h is deprecated and subject to remove. The drivers in question
> don't use it, simply remove the unused header.
> 
> 

Applied, thanks!

[1/1] phy: sun4i-usb: Remove unused of_gpio.h
      commit: b6096751a652a7e7526d4b3d59971a40c3287ef7

Best regards,
-- 
~Vinod




From muecker at gwdg.de  Sun Dec  8 10:10:49 2024
From: muecker at gwdg.de (Martin Uecker)
Date: Sun, 8 Dec 2024 19:10:49 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <e71fffb7ff0e4bf29692d006c0fe77c2@AcuMS.aculab.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	 <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	 <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
	 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
	 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de>
	 <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
	 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de>
	 <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
	 <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de>
	 <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>
	 <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de>
	 <b71056c1b9e04aa383f2e5608c27290f@AcuMS.aculab.com>
	 <6658618490381cf5ec35edbb66f1478024174e67.camel@gwdg.de>
	 <e71fffb7ff0e4bf29692d006c0fe77c2@AcuMS.aculab.com>
Message-ID: <87dd9b7b52e7cea874c1899f56efdd3d7c5b7243.camel@gwdg.de>

Am Sonntag, dem 08.12.2024 um 16:48 +0000 schrieb David Laight:
> From: Martin Uecker
> > Sent: 08 December 2024 12:38

...
> ...
> > So a lot of this macro business seems to be necessary
> > to avoid creating warnings for ISO VLAs when instead you really
> > care about the created code not having a dynamic allocation on
> > the stack.
> 
> A lot of the 'macro business' for min/max is avoiding unexpected
> conversion of negative values to very large unsigned ones.
> And no, -Wsign-compare is spectacularly useless.

This is a different topic, but what would be needed here?
> 
> ..
> > The issue here is that we miss a language feature in C to
> > introduce local variables that help avoid multiple expansion
> > of macro arguments.  GCC's statement expressions and __auto_type
> > are a solution
> 
> or historically 'typeof(x) _x = x'
> 
> > #define foo(x) ({ __auto_type __x = (x); ... })
> > 
> > but this runs into the current limitations that ({ }) can not be used
> > at file-scope and can not return constant expressions.
> > 
> > 
> > For other reasons I was thinking about adding names to _Generic,
> > as in
> > 
> > _Generic(x, int i: (i + 1));
> > 
> > because one design issues with _Generic is that it typechecks
> > also the untaken associations and there the 'x' then has the wrong
> > type.  Having an 'i' with the right type which is set to the value
> > of 'x' when the branch is taken would fix this issue.
> 
> That looks even more syntactically obscure than _Generic itself.
> Why does it need to do more than very simple syntax analysis of
> the unwanted branches?

This would be possible and GCC does turn of some warnings in
the unwanted branches.  I added this to GCC 14 I think.

But so far, ISO C requires that all branches are valid and this
was an intentional design decision to detect errors.

> - or they could automatically be analysed
> with the named variable have the specified type?

Inside a macro there is no variable 'x' but
the macro argument 'x' is replaced by some expression.

Also there is the general problem of multiple expansion which
can only be addressed by introducing an identifier.

> 
> > But this feature might also allow writing macros that avoid
> > double expansion without requiring statement expressions (which
> > are more difficult to fix):
> > 
> > #define foo(x) _Generic(x, int i: (i + i));
> 
> How can that work for things like min() that have multiple arguments?

You would need to nest it:

#define foo(x, y) _Generic(x, int i: _Generic(y, int j: i + j))

Otherwise one could invent syntax for matching multiple arguments
at the same time.

There is still the problem of name collision, but this is already
a problem with?

({ int i = (x); int j = (x); i + j; }) 

> Not going to work if you need __auto_type either.

If we allowed an identifier for the default branch too, this
would work:  _Generic(x, default i: (2 * i))


But hey, I am not saying  this is perfect, it is just
a possible improvement I was thinking about and which could be
implemented easily, would automatically return constant expressions,
and could be used at file scope without further changes.

There are certainly better long-term solutions.

Martin



From torvalds at linux-foundation.org  Sun Dec  8 11:05:34 2024
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Sun, 8 Dec 2024 11:05:34 -0800
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
In-Reply-To: <87dd9b7b52e7cea874c1899f56efdd3d7c5b7243.camel@gwdg.de>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
 <1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com> <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
 <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> <abdd7862f136aa676b2d2c324369f4a43ff9909c.camel@gwdg.de>
 <CAMZ6RqKzGiRNMeLsQKRNrxvW_bXB-kEi11udQ82kKX6tGCrqcg@mail.gmail.com>
 <9607300dfca5d71ca9570b1e1de0864e524f356b.camel@gwdg.de> <344b4cf41a474377b3d2cbf6302de703@AcuMS.aculab.com>
 <9a0c041b6143ba07c2b3e524572fccd841f5374b.camel@gwdg.de> <CAHk-=wjpVXEjX16PP=-hi4CgLqEGJ_U-WvKWq+J3C+FW-hSSfg@mail.gmail.com>
 <0a2996a7c63930b9d9a8d3792358dd9e494e27c1.camel@gwdg.de> <CAHk-=wjsfYYKBYuW8_6yKjdwHih0MMa2GwUJh_LHcuUNFR7-QA@mail.gmail.com>
 <9d9567dbdaf39688bbd0d240e29dec826a5931ee.camel@gwdg.de> <b71056c1b9e04aa383f2e5608c27290f@AcuMS.aculab.com>
 <6658618490381cf5ec35edbb66f1478024174e67.camel@gwdg.de> <e71fffb7ff0e4bf29692d006c0fe77c2@AcuMS.aculab.com>
 <87dd9b7b52e7cea874c1899f56efdd3d7c5b7243.camel@gwdg.de>
Message-ID: <CAHk-=wg+_6eQnLWm-kihFxJo1_EmyLSGruKVGzuRUwACE=osrA@mail.gmail.com>

On Sun, 8 Dec 2024 at 10:11, Martin Uecker <muecker at gwdg.de> wrote:
> >
> > A lot of the 'macro business' for min/max is avoiding unexpected
> > conversion of negative values to very large unsigned ones.
> > And no, -Wsign-compare is spectacularly useless.
>
> This is a different topic, but what would be needed here?

Dan Carpenter actually wrote up some of the issues in:

   https://staticthinking.wordpress.com/2023/07/25/wsign-compare-is-garbage/

but the basic issue is that -Wsign-compare has over the years been
truly spectacularly bad.

It has literally started out from the completely nonsensical and
incorrect assumption that the types of a comparison have to match in
signedness, and it shows in the name itself, but it also showed in
early implementations.

The very first versions of gcc that did -Wsign-compare literally
complained about code like

     sizeof(x) < 5

because obviously one side is an unsigned 'size_t', and the other side
is a signed 'int'. So comparing the two is clearly invalid, right?

No.

It's obviously *not* invalid, and any compiler that complains about
different signedness of that compare is just complete useless garbage.
It's literally checking two constants against each other, and the
result doesn't depend on the signedness or the silent C implicit type
conversion.

And no, gcc doesn't complain about that particular code any more.
*That* particular problem was I think only visible in a gcc
pre-release that sadly did actually ship as part of a SUSE release, so
we saw it in the wild even if it was never in an official gcc release.

I'm pointing out the history because it's relevant due to explaining
*why* the whole concept of looking at just the type is so broken, and
how the whole background to the warning was broken from the very
beginning. The very name of the warning is a sign of the problem.

Because gcc still *does* complain about entirely valid code, where
"fixing" the warning just means you have to write worse code.

I think Dan's example from the link above is a good one: if

        for (int i = 0; i < sizeof(x); i++)

causes a warning, the compiler got things entirely wrong.

And yes, modern gcc very much warns about that:

  t.c:4:27: warning: comparison of integer expressions of different
signedness: ?int? and ?long unsigned int? [-Wsign-compare]
      4 |         for (int i = 0; i < sizeof(b); i++)
        |                           ^

So if you want a general-purpose "Warn about dangerous comparisons",
you need to get away from the mindset that it's about different signs.

A compiler needs to do proper value range analysis before warning
about comparing said values. Not just mindlessly say "different types
bad" like some marsupial that has been dropped on its head a few too
many times.

End result: calling it "Warn about sign compare" is a disease. It
shows a lack of understanding of how complex the warning logic needs
to be.

Now, I'm not claiming that our min/max type warnings are great either:
they *do* end up basically being the same silly "just check signs, but
at least don't complain about signed positive constants being used for
unsigned comparisons".

So our min/max macros most definitely are *not* doing that "value
range analysis" that I claim is required for a *general* comparison
thing.

But our min//max macros aren't some general thing. They are very
specific, and so it's a lot easier to accept the not-great-analysis
for those specific cases where we then may have to change types
explicitly or do some other massaging to avoid the warning.

Put another way: a warning that triggers on really basic C absolutely
*must*not* have silly easily triggerable false positives for good and
idiomatic source code.

Such a warning is worse than useless, and gets disabled.

But a warning that is overly restrictive and gives silly false
positives can still be entirely acceptable when the context of that
warning is very limited.

So this is why in the kernel we disable '-Wsign-compare' in the
general case, but *do* basically manually then implement that very
same logic in the very _specific_ case of the min/max() macros.

What is unacceptable nonsense in one case may be acceptable "good
enough" in another. Life is not fair, I'm afraid.

                Linus


From tglx at linutronix.de  Sun Dec  8 12:14:55 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Sun, 08 Dec 2024 21:14:55 +0100
Subject: [PATCH 1/4] irqchip/riscv-imsic: Handle non-atomic MSI updates
 for device
In-Reply-To: <20241208150711.297624-2-apatel@ventanamicro.com>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
 <20241208150711.297624-2-apatel@ventanamicro.com>
Message-ID: <875xnuq6dc.ffs@tglx>

On Sun, Dec 08 2024 at 20:37, Anup Patel wrote:
> +
> +			tvec = vec->local_id == mvec->local_id ?
> +			       NULL : &lpriv->vectors[mvec->local_id];
> +			if (tvec && __imsic_id_read_clear_pending(tvec->local_id)) {

As I told you before:

I don't see a way how that can work remote with the IMSIC either even if
you can easily access the pending state of the remote CPU:

CPU0                            CPU1                   Device
set_affinity()
  write_msg(tmp)
    write(addr); // CPU1
    write(data); // vector 0x20
							raise IRQ (CPU1, vector 0x20)
				handle vector 0x20
				(other device)

    check_pending(CPU1, 0x20) == false -> Interrupt is lost

There is no guarantee that set_affinity() runs on the original target
CPU (CPU 1). Your scheme only works, when CPU1 vector 0x20 is not used
by some other device. If it's used, you lost as CPU1 will consume the
vector and your pending check is not seeing anything.

x86 ensures CPU locality by deferring the affinity move to the next
device interrupt on the original target CPU (CPU1 in the above
example). See CONFIG_GENERIC_IRQ_PENDING.

The interrupt domains which are not affected (remap) set the
IRQ_MOVE_PCNTXT flag to avoid that dance and don't use that affinity
setter code path at all.

Thanks,

        tglx


From wei.liu at kernel.org  Sun Dec  8 16:05:56 2024
From: wei.liu at kernel.org (Wei Liu)
Date: Mon, 9 Dec 2024 00:05:56 +0000
Subject: [PATCH v3 0/5] Introduce new headers for Hyper-V
In-Reply-To: <1732577084-2122-1-git-send-email-nunodasneves@linux.microsoft.com>
References: <1732577084-2122-1-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <Z1Y0ZB0J16oeHBbK@liuwe-devbox-debian-v2>

On Mon, Nov 25, 2024 at 03:24:39PM -0800, Nuno Das Neves wrote:
> To support Linux as root partition[1] on Hyper-V many new definitions
> are required.
> 
> The plan going forward is to directly import definitions from
> Hyper-V code without waiting for them to land in the TLFS document.
> This is a quicker and more maintainable way to import definitions,
> and is a step toward the eventual goal of exporting the headers
> directly from Hyper-V for use in Linux.
> 
> This patch series introduces new headers (hvhdk.h, hvgdk.h, etc,
> see patch #3) derived directly from Hyper-V code. hyperv-tlfs.h is
> replaced with hvhdk.h (which includes the other new headers)
> everywhere.
> 
> No functional change is expected.
> 
> Summary:
> Patch 1-2: Minor cleanup patches
> Patch 3: Add the new headers (hvhdk.h, etc..) in include/hyperv/
> Patch 4: Switch to the new headers
> Patch 5: Delete hyperv-tlfs.h files
> 
> Signed-off-by: Nuno Das Neves <nunodasneves at linux.microsoft.com>

Applied to hyperv-next. Thanks.


From wei.liu at kernel.org  Sun Dec  8 16:07:20 2024
From: wei.liu at kernel.org (Wei Liu)
Date: Mon, 9 Dec 2024 00:07:20 +0000
Subject: [PATCH v3 1/5] hyperv: Move hv_connection_id to hyperv-tlfs.h
In-Reply-To: <1732577084-2122-2-git-send-email-nunodasneves@linux.microsoft.com>
References: <1732577084-2122-1-git-send-email-nunodasneves@linux.microsoft.com>
 <1732577084-2122-2-git-send-email-nunodasneves@linux.microsoft.com>
Message-ID: <Z1Y0uJlVn-86KHE8@liuwe-devbox-debian-v2>

On Mon, Nov 25, 2024 at 03:24:40PM -0800, Nuno Das Neves wrote:
> This definition is in the wrong file; it is part of the TLFS doc.
> 
> Acked-by: Wei Liu <wei.liu at kernel.org>
> Reviewed-by: Easwar Hariharan <eahariha at linux.microsoft.com>
> Reviewed-by: Michael Kelley <mhklinux at outlook.com>
> Signed-off-by: Nuno Das Neves <nunodasneves at linux.microsoft.com>

One comment about the ordering of the tags. It is better to organize
them in the following order:

Signed-off-by: Nuno Das Neves <nunodasneves at linux.microsoft.com>
Acked-by: Wei Liu <wei.liu at kernel.org>
Reviewed-by: Easwar Hariharan <eahariha at linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux at outlook.com>

I've made the change for you while applying the patch.

Thanks,
Wei.


From quic_fangez at quicinc.com  Sun Dec  8 17:44:19 2024
From: quic_fangez at quicinc.com (fange zhang)
Date: Mon, 9 Dec 2024 09:44:19 +0800
Subject: [PATCH v3 5/9] drm/msm/dpu: Add SM6150 support
In-Reply-To: <c1b2fe04-e43e-4ab7-b0f8-2bb2ce6e1313@quicinc.com>
References: <20241122-add-display-support-for-qcs615-platform-v3-0-35252e3a51fe@quicinc.com>
 <20241122-add-display-support-for-qcs615-platform-v3-5-35252e3a51fe@quicinc.com>
 <c1b2fe04-e43e-4ab7-b0f8-2bb2ce6e1313@quicinc.com>
Message-ID: <afd00fdf-af62-46b5-9131-ed360a93e094@quicinc.com>



On 2024/12/7 4:17, Abhinav Kumar wrote:
> 
> 
> On 11/22/2024 1:56 AM, Fange Zhang wrote:
>> From: Li Liu <quic_lliu6 at quicinc.com>
>>
>> Add definitions for the display hardware used on the Qualcomm SM6150
>> platform.
>>
>> Signed-off-by: Li Liu <quic_lliu6 at quicinc.com>
>> Signed-off-by: Fange Zhang <quic_fangez at quicinc.com>
>> ---
>> ? .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h | 263 +++++++++++ 
>> ++++++++++
>> ? drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c???? |?? 1 +
>> ? drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h???? |?? 1 +
>> ? drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c??????????? |?? 1 +
>> ? 4 files changed, 266 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h b/ 
>> drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h
>> new file mode 100644
>> index 
>> 0000000000000000000000000000000000000000..e8b7f694b885d69a9bbfaa85b0faf0c7af677a75
>> --- /dev/null
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h
>> @@ -0,0 +1,263 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights 
>> reserved.
>> + */
>> +
>> +#ifndef _DPU_5_3_SM6150_H
>> +#define _DPU_5_3_SM6150_H
>> +
>> +
> 
> <snip>
> 
>> +static const struct dpu_sspp_cfg sm6150_sspp[] = {
>> +??? {
>> +??????? .name = "sspp_0", .id = SSPP_VIG0,
>> +??????? .base = 0x4000, .len = 0x1f0,
>> +??????? .features = VIG_SDM845_MASK,
> 
> This is not correct. Smartdma is supported on this chipset on both Vig 
> and DMA SSPPs.
> 
> Please use VIG_SDM845_MASK_SDMA and DMA_SDM845_MASK_SDMA respectively.
Got it, will replace them in next patch
> 
> 
>> +??????? .sblk = &dpu_vig_sblk_qseed3_2_4,
>> +??????? .xin_id = 0,
>> +??????? .type = SSPP_TYPE_VIG,
>> +??????? .clk_ctrl = DPU_CLK_CTRL_VIG0,
>> +??? }, {
>> +??????? .name = "sspp_8", .id = SSPP_DMA0,
>> +??????? .base = 0x24000, .len = 0x1f0,
>> +??????? .features = DMA_SDM845_MASK,
>> +??????? .sblk = &dpu_dma_sblk,
>> +??????? .xin_id = 1,
>> +??????? .type = SSPP_TYPE_DMA,
>> +??????? .clk_ctrl = DPU_CLK_CTRL_DMA0,
>> +??? }, {
>> +??????? .name = "sspp_9", .id = SSPP_DMA1,
>> +??????? .base = 0x26000, .len = 0x1f0,
>> +??????? .features = DMA_SDM845_MASK,
>> +??????? .sblk = &dpu_dma_sblk,
>> +??????? .xin_id = 5,
>> +??????? .type = SSPP_TYPE_DMA,
>> +??????? .clk_ctrl = DPU_CLK_CTRL_DMA1,
>> +??? }, {
>> +??????? .name = "sspp_10", .id = SSPP_DMA2,
>> +??????? .base = 0x28000, .len = 0x1f0,
>> +??????? .features = DMA_CURSOR_SDM845_MASK_SDMA,
>> +??????? .sblk = &dpu_dma_sblk,
>> +??????? .xin_id = 9,
>> +??????? .type = SSPP_TYPE_DMA,
>> +??????? .clk_ctrl = DPU_CLK_CTRL_DMA2,
>> +??? }, {
>> +??????? .name = "sspp_11", .id = SSPP_DMA3,
>> +??????? .base = 0x2a000, .len = 0x1f0,
>> +??????? .features = DMA_CURSOR_SDM845_MASK_SDMA,
>> +??????? .sblk = &dpu_dma_sblk,
>> +??????? .xin_id = 13,
>> +??????? .type = SSPP_TYPE_DMA,
>> +??????? .clk_ctrl = DPU_CLK_CTRL_DMA3,
>> +??? },
>> +};
>> +
> 
> <snip>



From ryan_chen at aspeedtech.com  Sun Dec  8 17:49:24 2024
From: ryan_chen at aspeedtech.com (Ryan Chen)
Date: Mon, 9 Dec 2024 01:49:24 +0000
Subject: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
In-Reply-To: <c898338622625cbfc825e8d4cc5f0fff.sboyd@kernel.org>
References: <20241028053018.2579200-1-ryan_chen@aspeedtech.com>
 <20241028053018.2579200-4-ryan_chen@aspeedtech.com>
 <287924eed186e3b6b52cd13bcf939ab6.sboyd@kernel.org>
 <SI6PR06MB7535F5D22E3FCCF5C610B307F2552@SI6PR06MB7535.apcprd06.prod.outlook.com>
 <a68516df98c8b8fb80f094e6e55fcb8d.sboyd@kernel.org>
 <OS8PR06MB75419637D55A022300E00850F2352@OS8PR06MB7541.apcprd06.prod.outlook.com>
 <9ccfb478d9a122db6c634e9559e211ff.sboyd@kernel.org>
 <OS8PR06MB75418449B451224C5AB46FBFF2302@OS8PR06MB7541.apcprd06.prod.outlook.com>
 <c898338622625cbfc825e8d4cc5f0fff.sboyd@kernel.org>
Message-ID: <OS8PR06MB754146730BA8D31127A5452FF23C2@OS8PR06MB7541.apcprd06.prod.outlook.com>

> Subject: RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> 
> Quoting Ryan Chen (2024-12-04 16:48:42)
> > > > struct ast2700_clk_info {
> > > >         const char *name;
> > > >         u8 clk_idx;
> > > >         u32 reg;
> > > >         u32 type;
> > > >         union {
> > > >                 struct ast2700_clk_fixed_factor_data factor;
> > > >                 struct ast2700_clk_fixed_rate_data rate;
> > > >                 struct ast2700_clk_gate_data gate;
> > > >                 struct ast2700_clk_div_data div;
> > > >                 struct ast2700_clk_pll_data pll;
> > > >                 struct ast2700_clk_mux_data mux;
> > > >         } data;
> > > > };
> > > >
> > > > struct ast2700_clk_div_data {
> > > >         const struct clk_div_table *div_table;
> > > >         const struct clk_parent_data *parent;
> > > >         u8 bit_shift;
> > > >         u8 bit_width;
> > > >         u32 reg;
> > > > };
> > > >
> > > > static const struct ast2700_clk_info ast2700_scu0_clk_info[]
> > > > __initconst = { ...........................
> > > >         DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,
> > >
> > > Can you also show what soc0_ahbmux is?
> > It will be following.
> >
> > static const struct clk_parent_data soc0_ahbmux[] = {
> >         { .fw_name = "soc0-ahbmux", .name = "soc0-ahbmux" }, };
> 
> Instead of that, please use only the index.
> 
>  static const struct clk_parent_data soc0_ahbmux[] = {
>          { .index = <number from DT binding> },  };

Sorry, if I use index instead, It can?t get parent data name for devm_clk_hw_register_fixed_factor parent_name parameters.
Does there have reference driver use index implement?

In probe function I implement for function for each clk register.
For example CLK_DIVIDER
Use div->parent->name get parent name for parameter.
			hws[i] = devm_clk_hw_register_divider_table(dev, clk->name,
								    div->parent->name, 0,
								    reg, div->bit_shift,
								    div->bit_width, 0,
								    div->div_table,
								    &clk_ctrl->lock);

Full implement is following.

	for (i = 0; i < clk_data->nr_clks; i++) {
		const struct ast2700_clk_info *clk = &clk_data->clk_info[i];
		void __iomem *reg = clk_ctrl->base + clk->reg;

		if (clk->type == CLK_FIXED) {
			const struct ast2700_clk_fixed_rate_data *fixed_rate = &clk->data.rate;

			hws[i] = devm_clk_hw_register_fixed_rate(dev, clk->name, NULL, 0,
								 fixed_rate->fixed_rate);
		} else if (clk->type == CLK_FIXED_FACTOR) {
			const struct ast2700_clk_fixed_factor_data *factor = &clk->data.factor;

			hws[i] = devm_clk_hw_register_fixed_factor(dev, clk->name,
								   factor->parent->name,
								   0, factor->mult, factor->div);
		} else if (clk->type == DCLK_FIXED) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_dclk(i, reg, clk->name, clk_ctrl);
		} else if (clk->type == CLK_HPLL) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_hpll(i, reg, clk->name,
							      pll->parent->name, clk_ctrl);
		} else if (clk->type == CLK_PLL) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_pll(i, reg, clk->name,
							     pll->parent->name, clk_ctrl);
		} else if (clk->type == CLK_UART_PLL) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_uartpll(i, reg, clk->name,
								 pll->parent->name, clk_ctrl);
		} else if (clk->type == CLK_MUX) {
			const struct ast2700_clk_mux_data *mux = &clk->data.mux;

			reg = clk_ctrl->base + mux->reg;
			hws[i] = devm_clk_hw_register_mux_parent_data_table(dev, clk->name,
									    mux->parents,
									    mux->num_parents, 0,
									    reg, mux->bit_shift,
									    mux->bit_width, 0,
									    NULL, &clk_ctrl->lock);
		} else if (clk->type == CLK_MISC) {
			const struct ast2700_clk_pll_data *misc = &clk->data.pll;

			reg = clk_ctrl->base + misc->reg;
			hws[i] = ast2700_clk_hw_register_misc(i, reg, clk->name,
							      misc->parent->name, clk_ctrl);
		} else if (clk->type == CLK_DIVIDER) {
			const struct ast2700_clk_div_data *div = &clk->data.div;

			reg = clk_ctrl->base + div->reg;
			hws[i] = devm_clk_hw_register_divider_table(dev, clk->name,
								    div->parent->name, 0,
								    reg, div->bit_shift,
								    div->bit_width, 0,
								    div->div_table,
								    &clk_ctrl->lock);
		} else if (clk->type == CLK_GATE_ASPEED) {
			const struct ast2700_clk_gate_data *gate = &clk->data.gate;

			reg = clk_ctrl->base + gate->reg;
			hws[i] = ast2700_clk_hw_register_gate(dev, clk->name, gate->parent,
							      reg, gate->bit, gate->flags, 0);

		} else {
			const struct ast2700_clk_gate_data *gate = &clk->data.gate;

			reg = clk_ctrl->base + gate->reg;
			hws[i] = devm_clk_hw_register_gate_parent_data(dev, clk->name, gate->parent,
								       0, reg, clk->clk_idx, 0,
								       &clk_ctrl->lock);
		}

		if (IS_ERR(hws[i]))
			return PTR_ERR(hws[i]);
	}

From ck.hu at mediatek.com  Sun Dec  8 18:32:08 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 9 Dec 2024 02:32:08 +0000
Subject: [PATCH v2 06/15] drm/mediatek: Add support for MT8195 Digital
 Parallel Interface
In-Reply-To: <20241205114518.53527-7-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-7-angelogioacchino.delregno@collabora.com>
Message-ID: <002104ebc3006169f9ca380422a1b249b5076301.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the DPI block found in the MT8195 and MT8188 SoCs.
> Inside of the SoC, this block is directly connected to the HDMI IP.

Note: there is discussion in [1].

[1] https://patchwork.kernel.org/project/linux-mediatek/patch/20241120124420.133914-7-angelogioacchino.delregno at collabora.com/

Regards,
CK

> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c      | 55 ++++++++++++++++++++++---
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  6 +++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  2 +
>  3 files changed, 58 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 79923d1bfbc9..f76d1c5b68bd 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -144,6 +144,7 @@ struct mtk_dpi_factor {
>   * @csc_enable_bit: Enable bit of CSC.
>   * @pixels_per_iter: Quantity of transferred pixels per iteration.
>   * @edge_cfg_in_mmsys: If the edge configuration for DPI's output needs to be set in MMSYS.
> + * @is_internal_hdmi: Specifies whether the DPI is internally connected to the HDMI block
>   */
>  struct mtk_dpi_conf {
>         const struct mtk_dpi_factor *dpi_factor;
> @@ -164,6 +165,7 @@ struct mtk_dpi_conf {
>         u32 csc_enable_bit;
>         u32 pixels_per_iter;
>         bool edge_cfg_in_mmsys;
> +       bool is_internal_hdmi;
>  };
> 
>  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
> @@ -492,6 +494,7 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
> 
>         mtk_dpi_disable(dpi);
>         clk_disable_unprepare(dpi->pixel_clk);
> +       clk_disable_unprepare(dpi->tvd_clk);
>         clk_disable_unprepare(dpi->engine_clk);
>  }
> 
> @@ -508,6 +511,12 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>                 goto err_refcount;
>         }
> 
> +       ret = clk_prepare_enable(dpi->tvd_clk);
> +       if (ret) {
> +               dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +               goto err_engine;
> +       }
> +
>         ret = clk_prepare_enable(dpi->pixel_clk);
>         if (ret) {
>                 dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -517,6 +526,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>         return 0;
> 
>  err_pixel:
> +       clk_disable_unprepare(dpi->tvd_clk);
> +err_engine:
>         clk_disable_unprepare(dpi->engine_clk);
>  err_refcount:
>         dpi->refcount--;
> @@ -584,7 +595,9 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>         struct videomode vm = { 0 };
> 
>         drm_display_mode_to_videomode(mode, &vm);
> -       mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
> +
> +       if (!dpi->conf->is_internal_hdmi)
> +               mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
> 
>         dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
>         dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
> @@ -647,10 +660,18 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>         if (dpi->conf->support_direct_pin) {
>                 mtk_dpi_config_yc_map(dpi, dpi->yc_map);
>                 mtk_dpi_config_2n_h_fre(dpi);
> -               mtk_dpi_dual_edge(dpi);
> +               /* DPI can connect to either an external bridge or the internal HDMI encoder */
> +               if (dpi->conf->is_internal_hdmi) {
> +                       mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN, DPI_OUTPUT_1T1P_EN);
> +                       mtk_dpi_mask(dpi, DPI_CON,
> +                                    dpi->conf->input_2pixel ? DPI_INPUT_2P_EN : 0,
> +                                    DPI_INPUT_2P_EN);
> +               } else {
> +                       mtk_dpi_dual_edge(dpi);
> +               }
>                 mtk_dpi_config_disable_edge(dpi);
>         }
> -       if (dpi->conf->input_2pixel) {
> +       if (dpi->conf->input_2pixel && !dpi->conf->is_internal_hdmi) {
>                 mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
>                              DPINTF_INPUT_2P_EN);
>         }
> @@ -919,14 +940,16 @@ void mtk_dpi_start(struct device *dev)
>  {
>         struct mtk_dpi *dpi = dev_get_drvdata(dev);
> 
> -       mtk_dpi_power_on(dpi);
> +       if (!dpi->conf->is_internal_hdmi)
> +               mtk_dpi_power_on(dpi);
>  }
> 
>  void mtk_dpi_stop(struct device *dev)
>  {
>         struct mtk_dpi *dpi = dev_get_drvdata(dev);
> 
> -       mtk_dpi_power_off(dpi);
> +       if (!dpi->conf->is_internal_hdmi)
> +               mtk_dpi_power_off(dpi);
>  }
> 
>  unsigned int mtk_dpi_encoder_index(struct device *dev)
> @@ -1021,6 +1044,8 @@ static const struct mtk_dpi_factor dpi_factor_mt8195_dp_intf[] = {
>         { 70000 - 1, 4 }, { 200000 - 1, 2 }, { U32_MAX, 1 }
>  };
> 
> +static const struct mtk_dpi_factor dpi_factor_mt8195_dpi = { U32_MAX, 1 };
> +
>  static const struct mtk_dpi_conf mt8173_conf = {
>         .dpi_factor = dpi_factor_mt8173,
>         .num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8173),
> @@ -1113,6 +1138,25 @@ static const struct mtk_dpi_conf mt8192_conf = {
>         .csc_enable_bit = CSC_ENABLE,
>  };
> 
> +static const struct mtk_dpi_conf mt8195_conf = {
> +       .dpi_factor = &dpi_factor_mt8195_dpi,
> +       .num_dpi_factor = 1,
> +       .max_clock_khz = 594000,
> +       .output_fmts = mt8183_output_fmts,
> +       .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> +       .pixels_per_iter = 1,
> +       .is_ck_de_pol = true,
> +       .swap_input_support = true,
> +       .support_direct_pin = true,
> +       .dimension_mask = HPW_MASK,
> +       .hvsize_mask = HSIZE_MASK,
> +       .channel_swap_shift = CH_SWAP,
> +       .yuv422_en_bit = YUV422_EN,
> +       .csc_enable_bit = CSC_ENABLE,
> +       .is_internal_hdmi = true,
> +       .input_2pixel = true,
> +};
> +
>  static const struct mtk_dpi_conf mt8195_dpintf_conf = {
>         .dpi_factor = dpi_factor_mt8195_dp_intf,
>         .num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8195_dp_intf),
> @@ -1216,6 +1260,7 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>         { .compatible = "mediatek,mt8188-dp-intf", .data = &mt8195_dpintf_conf },
>         { .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf },
>         { .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf },
> +       { .compatible = "mediatek,mt8195-dpi", .data = &mt8195_conf },
>         { /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> index a0b1d18bbbf7..3c24d9e9f241 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -40,6 +40,12 @@
>  #define FAKE_DE_LEVEN                  BIT(21)
>  #define FAKE_DE_RODD                   BIT(22)
>  #define FAKE_DE_REVEN                  BIT(23)
> +
> +/* DPI_CON: DPI instances */
> +#define DPI_OUTPUT_1T1P_EN             BIT(24)
> +#define DPI_INPUT_2P_EN                        BIT(25)
> +
> +/* DPI_CON: DPINTF instances */
>  #define DPINTF_YUV422_EN               BIT(24)
>  #define DPINTF_CSC_ENABLE              BIT(26)
>  #define DPINTF_INPUT_2P_EN             BIT(29)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 9a8ef8558da9..ba4539150f52 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -807,6 +807,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DPI },
>         { .compatible = "mediatek,mt8195-dp-intf",
>           .data = (void *)MTK_DP_INTF },
> +       { .compatible = "mediatek,mt8195-dpi",
> +         .data = (void *)MTK_DPI },
>         { .compatible = "mediatek,mt2701-dsi",
>           .data = (void *)MTK_DSI },
>         { .compatible = "mediatek,mt8173-dsi",
> --
> 2.47.0
> 


From tongtiangen at huawei.com  Sun Dec  8 18:42:53 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Mon, 9 Dec 2024 10:42:53 +0800
Subject: [PATCH v13 1/5] uaccess: add generic fallback version of copy_mc_to_user()
In-Reply-To: <20241209024257.3618492-1-tongtiangen@huawei.com>
References: <20241209024257.3618492-1-tongtiangen@huawei.com>
Message-ID: <20241209024257.3618492-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>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
---
 arch/powerpc/include/asm/uaccess.h | 1 +
 arch/x86/include/asm/uaccess.h     | 1 +
 include/linux/uaccess.h            | 8 ++++++++
 3 files changed, 10 insertions(+)

diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 4f5a46a77fa2..44476d66ed13 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -403,6 +403,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 3a7755c1a441..3db67f44063b 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 e9c702c1908d..9d8c9f8082ff 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -239,6 +239,14 @@ 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)
+{
+	return 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  Sun Dec  8 18:42:56 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Mon, 9 Dec 2024 10:42:56 +0800
Subject: [PATCH v13 4/5] arm64: support copy_mc_[user]_highpage()
In-Reply-To: <20241209024257.3618492-1-tongtiangen@huawei.com>
References: <20241209024257.3618492-1-tongtiangen@huawei.com>
Message-ID: <20241209024257.3618492-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_MEM_ERR, therefore, the
main logic is extracted to copy_page_template.S. In addition, the fixup of
MOPS insn is not considered at present.

[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          | 62 ++----------------------
 arch/arm64/lib/copy_page_template.S | 70 +++++++++++++++++++++++++++
 arch/arm64/lib/mte.S                | 29 +++++++++++
 arch/arm64/mm/copypage.c            | 75 +++++++++++++++++++++++++++++
 include/linux/highmem.h             |  8 +++
 9 files changed, 245 insertions(+), 57 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 6567df8ec8ca..efcd850ea2f8 100644
--- a/arch/arm64/include/asm/mte.h
+++ b/arch/arm64/include/asm/mte.h
@@ -98,6 +98,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);
@@ -134,6 +139,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 8e882f479d98..78b0e9904689 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -13,6 +13,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 crc32-glue.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..51564828c30c
--- /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_MEM_ERR(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 e6374e7e5511..d0186bbf99f1 100644
--- a/arch/arm64/lib/copy_page.S
+++ b/arch/arm64/lib/copy_page.S
@@ -17,65 +17,13 @@
  *	x0 - dest
  *	x1 - src
  */
-SYM_FUNC_START(__pi_copy_page)
-#ifdef CONFIG_AS_HAS_MOPS
-	.arch_extension mops
-alternative_if_not ARM64_HAS_MOPS
-	b	.Lno_mops
-alternative_else_nop_endif
-
-	mov	x2, #PAGE_SIZE
-	cpypwn	[x0]!, [x1]!, x2!
-	cpymwn	[x0]!, [x1]!, x2!
-	cpyewn	[x0]!, [x1]!, x2!
-	ret
-.Lno_mops:
-#endif
-	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..f96c7988c93d
--- /dev/null
+++ b/arch/arm64/lib/copy_page_template.S
@@ -0,0 +1,70 @@
+/* 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
+ */
+
+#ifdef CONFIG_AS_HAS_MOPS
+	.arch_extension mops
+alternative_if_not ARM64_HAS_MOPS
+	b	.Lno_mops
+alternative_else_nop_endif
+
+	mov	x2, #PAGE_SIZE
+	cpypwn	[x0]!, [x1]!, x2!
+	cpymwn	[x0]!, [x1]!, x2!
+	cpyewn	[x0]!, [x1]!, x2!
+	ret
+.Lno_mops:
+#endif
+	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..9d4eeb76a838 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 with memory error 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_MEM_ERR(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 a86c897017df..1a369f325ebb 100644
--- a/arch/arm64/mm/copypage.c
+++ b/arch/arm64/mm/copypage.c
@@ -67,3 +67,78 @@ 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);
+	struct folio *src = page_folio(from);
+	struct folio *dst = page_folio(to);
+	unsigned int i, nr_pages;
+	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())
+		return 0;
+
+	if (folio_test_hugetlb(src)) {
+		if (!folio_test_hugetlb_mte_tagged(src) ||
+		    from != folio_page(src, 0))
+			return 0;
+
+		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
+
+		/*
+		 * Populate tags for all subpages.
+		 *
+		 * Don't assume the first page is head page since
+		 * huge page copy may start from any subpage.
+		 */
+		nr_pages = folio_nr_pages(src);
+		for (i = 0; i < nr_pages; i++) {
+			kfrom = page_address(folio_page(src, i));
+			kto = page_address(folio_page(dst, i));
+			ret = mte_copy_mc_page_tags(kto, kfrom);
+			if (ret)
+				return -EFAULT;
+		}
+		folio_set_hugetlb_mte_tagged(dst);
+	} else if (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)
+		return ret;
+
+	flush_dcache_page(to);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(copy_mc_user_highpage);
+#endif
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 0eb4b9b06837..89a6e0fd0b31 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -326,6 +326,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
@@ -351,7 +352,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  Sun Dec  8 18:42:57 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Mon, 9 Dec 2024 10:42:57 +0800
Subject: [PATCH v13 5/5] arm64: introduce copy_mc_to_kernel() implementation
In-Reply-To: <20241209024257.3618492-1-tongtiangen@huawei.com>
References: <20241209024257.3618492-1-tongtiangen@huawei.com>
Message-ID: <20241209024257.3618492-6-tongtiangen@huawei.com>

The copy_mc_to_kernel() helper is memory copy implementation that handles
source exceptions. It can be used in memory copy scenarios that tolerate
hardware memory errors(e.g: pmem_read/dax_copy_to_iter).

Currently, only x86 and ppc support this helper, Add this for ARM64 as
well, if ARCH_HAS_COPY_MC is defined, by implementing copy_mc_to_kernel()
and memcpy_mc() functions.

Because there is no caller-saved GPR is available for saving "bytes not
copied" in memcpy(), the memcpy_mc() is referenced to the implementation
of copy_from_user(). In addition, the fixup of MOPS insn is not considered
at present.

Signed-off-by: Tong Tiangen <tongtiangen at huawei.com>
---
 arch/arm64/include/asm/string.h  |  5 ++
 arch/arm64/include/asm/uaccess.h | 18 ++++++
 arch/arm64/lib/Makefile          |  2 +-
 arch/arm64/lib/memcpy_mc.S       | 98 ++++++++++++++++++++++++++++++++
 mm/kasan/shadow.c                | 12 ++++
 5 files changed, 134 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/lib/memcpy_mc.S

diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
index 3a3264ff47b9..23eca4fb24fa 100644
--- a/arch/arm64/include/asm/string.h
+++ b/arch/arm64/include/asm/string.h
@@ -35,6 +35,10 @@ extern void *memchr(const void *, int, __kernel_size_t);
 extern void *memcpy(void *, const void *, __kernel_size_t);
 extern void *__memcpy(void *, const void *, __kernel_size_t);
 
+#define __HAVE_ARCH_MEMCPY_MC
+extern int memcpy_mc(void *, const void *, __kernel_size_t);
+extern int __memcpy_mc(void *, const void *, __kernel_size_t);
+
 #define __HAVE_ARCH_MEMMOVE
 extern void *memmove(void *, const void *, __kernel_size_t);
 extern void *__memmove(void *, const void *, __kernel_size_t);
@@ -57,6 +61,7 @@ void memcpy_flushcache(void *dst, const void *src, size_t cnt);
  */
 
 #define memcpy(dst, src, len) __memcpy(dst, src, len)
+#define memcpy_mc(dst, src, len) __memcpy_mc(dst, src, len)
 #define memmove(dst, src, len) __memmove(dst, src, len)
 #define memset(s, c, n) __memset(s, c, n)
 
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 5b91803201ef..2a14b732306a 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -542,4 +542,22 @@ static inline void put_user_gcs(unsigned long val, unsigned long __user *addr,
 
 #endif /* CONFIG_ARM64_GCS */
 
+#ifdef CONFIG_ARCH_HAS_COPY_MC
+/**
+ * copy_mc_to_kernel - memory copy that handles source exceptions
+ *
+ * @to:		destination address
+ * @from:	source address
+ * @size:	number of bytes to copy
+ *
+ * Return 0 for success, or bytes not copied.
+ */
+static inline unsigned long __must_check
+copy_mc_to_kernel(void *to, const void *from, unsigned long size)
+{
+	return memcpy_mc(to, from, size);
+}
+#define copy_mc_to_kernel copy_mc_to_kernel
+#endif
+
 #endif /* __ASM_UACCESS_H */
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 78b0e9904689..326d71ba0517 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -13,7 +13,7 @@ endif
 
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
 
-lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc_page.o
+lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc_page.o memcpy_mc.o
 
 obj-$(CONFIG_CRC32) += crc32.o crc32-glue.o
 
diff --git a/arch/arm64/lib/memcpy_mc.S b/arch/arm64/lib/memcpy_mc.S
new file mode 100644
index 000000000000..cb9caaa1ab0b
--- /dev/null
+++ b/arch/arm64/lib/memcpy_mc.S
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ * Copyright (C) 2013 Linaro.
+ *
+ * This code is based on glibc cortex strings work originally authored by Linaro
+ * be found @
+ *
+ * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/
+ * files/head:/src/aarch64/
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/cache.h>
+#include <asm/asm-uaccess.h>
+
+/*
+ * Copy a buffer from src to dest (alignment handled by the hardware)
+ *
+ * Parameters:
+ *	x0 - dest
+ *	x1 - src
+ *	x2 - n
+ * Returns:
+ *	x0 - bytes not copied
+ */
+	.macro ldrb1 reg, ptr, val
+	KERNEL_MEM_ERR(9997f, ldrb  \reg, [\ptr], \val)
+	.endm
+
+	.macro strb1 reg, ptr, val
+	strb \reg, [\ptr], \val
+	.endm
+
+	.macro ldrh1 reg, ptr, val
+	KERNEL_MEM_ERR(9997f, ldrh  \reg, [\ptr], \val)
+	.endm
+
+	.macro strh1 reg, ptr, val
+	strh \reg, [\ptr], \val
+	.endm
+
+	.macro ldr1 reg, ptr, val
+	KERNEL_MEM_ERR(9997f, ldr \reg, [\ptr], \val)
+	.endm
+
+	.macro str1 reg, ptr, val
+	str \reg, [\ptr], \val
+	.endm
+
+	.macro ldp1 reg1, reg2, ptr, val
+	KERNEL_MEM_ERR(9997f, ldp \reg1, \reg2, [\ptr], \val)
+	.endm
+
+	.macro stp1 reg1, reg2, ptr, val
+	stp \reg1, \reg2, [\ptr], \val
+	.endm
+
+end	.req	x5
+SYM_FUNC_START(__memcpy_mc_generic)
+	add	end, x0, x2
+#include "copy_template.S"
+	mov	x0, #0				// Nothing to copy
+	ret
+
+	// Exception fixups
+9997:	sub	x0, end, dst			// bytes not copied
+	ret
+SYM_FUNC_END(__memcpy_mc_generic)
+
+#ifdef CONFIG_AS_HAS_MOPS
+	.arch_extension mops
+SYM_FUNC_START(__memcpy_mc)
+alternative_if_not ARM64_HAS_MOPS
+	b       __memcpy_mc_generic
+alternative_else_nop_endif
+
+dstin   .req    x0
+src     .req    x1
+count   .req    x2
+dst     .req    x3
+
+	mov     dst, dstin
+	cpyp    [dst]!, [src]!, count!
+	cpym    [dst]!, [src]!, count!
+	cpye    [dst]!, [src]!, count!
+
+	mov	x0, #0				// Nothing to copy
+	ret
+SYM_FUNC_END(__memcpy_mc)
+#else
+SYM_FUNC_ALIAS(__memcpy_mc, __memcpy_mc_generic)
+#endif
+
+EXPORT_SYMBOL(__memcpy_mc)
+SYM_FUNC_ALIAS_WEAK(memcpy_mc, __memcpy_mc)
+EXPORT_SYMBOL(memcpy_mc)
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index 88d1c9dcb507..a12770fb2e9c 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -79,6 +79,18 @@ void *memcpy(void *dest, const void *src, size_t len)
 }
 #endif
 
+#ifdef __HAVE_ARCH_MEMCPY_MC
+#undef memcpy_mc
+int memcpy_mc(void *dest, const void *src, size_t len)
+{
+	if (!kasan_check_range(src, len, false, _RET_IP_) ||
+	    !kasan_check_range(dest, len, true, _RET_IP_))
+		return (int)len;
+
+	return __memcpy_mc(dest, src, len);
+}
+#endif
+
 void *__asan_memset(void *addr, int c, ssize_t len)
 {
 	if (!kasan_check_range(addr, len, true, _RET_IP_))
-- 
2.25.1



From tongtiangen at huawei.com  Sun Dec  8 18:42:55 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Mon, 9 Dec 2024 10:42:55 +0800
Subject: [PATCH v13 3/5] mm/hwpoison: return -EFAULT when copy fail in copy_mc_[user]_highpage()
In-Reply-To: <20241209024257.3618492-1-tongtiangen@huawei.com>
References: <20241209024257.3618492-1-tongtiangen@huawei.com>
Message-ID: <20241209024257.3618492-4-tongtiangen@huawei.com>

Currently, copy_mc_[user]_highpage() returns zero on success, or in case
of failures, the number of bytes that weren't copied.

While tracking the number of not copied works fine for x86 and PPC, There
are some difficulties in doing the same thing on ARM64 because there is no
available caller-saved register in copy_page()(lib/copy_page.S) to save
"bytes not copied", and the following copy_mc_page() will also encounter
the same problem.

Consider the caller of copy_mc_[user]_highpage() cannot do any processing
on the remaining data(The page has hardware errors), they only check if
copy was succeeded or not, make the interface more generic by using an
error code when copy fails (-EFAULT) or return zero on success.

Signed-off-by: Tong Tiangen <tongtiangen at huawei.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---
 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 6e452bd8e7e3..0eb4b9b06837 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -329,8 +329,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)
@@ -349,7 +349,7 @@ static inline int copy_mc_user_highpage(struct page *to, struct page *from,
 	if (ret)
 		memory_failure_queue(page_to_pfn(from), 0);
 
-	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)
 	if (ret)
 		memory_failure_queue(page_to_pfn(from), 0);
 
-	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 6f8d46d107b4..c3cdc0155dcd 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -820,7 +820,7 @@ static int __collapse_huge_page_copy(pte_t *pte, struct folio *folio,
 			continue;
 		}
 		src_page = pte_page(pteval);
-		if (copy_mc_user_highpage(page, src_page, src_addr, vma) > 0) {
+		if (copy_mc_user_highpage(page, src_page, src_addr, vma)) {
 			result = SCAN_COPY_MC;
 			break;
 		}
@@ -2081,7 +2081,7 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr,
 		}
 
 		for (i = 0; i < nr_pages; i++) {
-			if (copy_mc_highpage(dst, folio_page(folio, i)) > 0) {
+			if (copy_mc_highpage(dst, folio_page(folio, i))) {
 				result = SCAN_COPY_MC;
 				goto rollback;
 			}
-- 
2.25.1



From tongtiangen at huawei.com  Sun Dec  8 18:42:52 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Mon, 9 Dec 2024 10:42:52 +0800
Subject: [PATCH v13 0/5]arm64: add ARCH_HAS_COPY_MC support
Message-ID: <20241209024257.3618492-1-tongtiangen@huawei.com>

Problem
=========
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.

Solution
=========

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())

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

Benefits
=========
According to the statistics of our storage product, the memory errors triggered
in kernel-mode by COW and page cache read (uaccess) scenarios account for more
than 50%, with this patchset deployed, all the kernel panic caused by COW and
page cache memory errors are eliminated, in addition, other scenarios that
account for a small proportion will also benefit.

Since v12:
Thanks to the suggestions of Jonathan, Mark, and Mauro, the following modifications
are made:
1. Rebase to latest kernel version.
2. Patch1, add Jonathan's and Mauro's review-by.
3. Patch2, modified do_apei_claim_sea() according to Mark's and Jonathan's suggestions,
   and optimized the commit message according to Mark's suggestions(Added description of
   the impact on regular copy_to_user()).
4. Patch3, optimized the commit message according to Mauro's suggestions and add Jonathan's
   review-by.
5. Patch4, modified copy_mc_user_highpage() and Optimized the commit message according to
   Jonathan's suggestions(no functional changes).
6. Patch5, optimized the commit message according to Mauro's suggestions.
7. Patch4/5, FEAT_MOPS is added to the code logic. Currently, the fixup is not performed
   on the MOPS instruction. 
8. Remove patch6 in v12 according to Jonathan's suggestions.

Since v11:
1. Rebase to latest kernel version 6.9-rc1.
2. Add patch 5, Since the problem described in "Since V10 Besides 3" has
   been solved in a50026bdb867 ('iov_iter: get rid of 'copy_mc' flag').
3. Add the benefit of applying the patch set to our company to the description of patch0.

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: introduce copy_mc_to_kernel() implementation

 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/include/asm/string.h      |  5 ++
 arch/arm64/include/asm/uaccess.h     | 18 +++++
 arch/arm64/lib/Makefile              |  2 +
 arch/arm64/lib/copy_mc_page.S        | 37 +++++++++++
 arch/arm64/lib/copy_page.S           | 62 ++----------------
 arch/arm64/lib/copy_page_template.S  | 70 ++++++++++++++++++++
 arch/arm64/lib/copy_to_user.S        | 10 +--
 arch/arm64/lib/memcpy_mc.S           | 98 ++++++++++++++++++++++++++++
 arch/arm64/lib/mte.S                 | 29 ++++++++
 arch/arm64/mm/copypage.c             | 75 +++++++++++++++++++++
 arch/arm64/mm/extable.c              | 19 ++++++
 arch/arm64/mm/fault.c                | 30 ++++++---
 arch/powerpc/include/asm/uaccess.h   |  1 +
 arch/x86/include/asm/uaccess.h       |  1 +
 include/linux/highmem.h              | 16 +++--
 include/linux/uaccess.h              |  8 +++
 mm/kasan/shadow.c                    | 12 ++++
 mm/khugepaged.c                      |  4 +-
 24 files changed, 472 insertions(+), 81 deletions(-)
 create mode 100644 arch/arm64/lib/copy_mc_page.S
 create mode 100644 arch/arm64/lib/copy_page_template.S
 create mode 100644 arch/arm64/lib/memcpy_mc.S

-- 
2.25.1



From tongtiangen at huawei.com  Sun Dec  8 18:42:54 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Mon, 9 Dec 2024 10:42:54 +0800
Subject: [PATCH v13 2/5] arm64: add support for ARCH_HAS_COPY_MC
In-Reply-To: <20241209024257.3618492-1-tongtiangen@huawei.com>
References: <20241209024257.3618492-1-tongtiangen@huawei.com>
Message-ID: <20241209024257.3618492-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.

Add new fixup type EX_TYPE_KACCESS_ERR_ZERO_MEM_ERR to identify insn
that can recover from memory errors triggered by access to kernel memory,
and this fixup type is used in __arch_copy_to_user(), This make the regular
copy_to_user() will handle kernel memory errors.

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                | 30 ++++++++++++++++++++-------
 7 files changed, 78 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..5fa54d31162c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -21,6 +21,7 @@ config ARM64
 	select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
 	select ARCH_HAS_CACHE_LINE_SIZE
 	select ARCH_HAS_CC_PLATFORM
+	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 b8a5861dc7b7..0f9123efca0a 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_MEM_ERR	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_MEM_ERR(insn, fixup, err, zero)	\
+	__ASM_EXTABLE_RAW(insn, fixup, 					\
+			  EX_TYPE_KACCESS_ERR_ZERO_MEM_ERR,		\
+			  (						\
+			    EX_DATA_REG(ERR, err) |			\
+			    EX_DATA_REG(ZERO, zero)			\
+			  ))
+
+#define _ASM_EXTABLE_KACCESS_MEM_ERR(insn, fixup)			\
+	_ASM_EXTABLE_KACCESS_ERR_ZERO_MEM_ERR(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 `insn`, which will branch to
+ * `fixup` when an unhandled fault is taken.
+ */
+	.macro          _asm_extable_kaccess_mem_err, insn, fixup
+	_ASM_EXTABLE_KACCESS_MEM_ERR(\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..19aa0180f645 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_MEM_ERR(l, x...)			\
+9999:	x;					\
+	_asm_extable_kaccess_mem_err	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..bedab1678431 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_MEM_ERR(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_MEM_ERR(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_MEM_ERR(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_MEM_ERR(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_MEM_ERR(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..9ad2b6473b60 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_MEM_ERR:
+		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_MEM_ERR:
+		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 ef63651099a9..278e67357f49 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -801,21 +801,35 @@ 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 int do_apei_claim_sea(struct pt_regs *regs)
+{
+	int ret;
+
+	ret = apei_claim_sea(regs);
+	if (ret)
+		return ret;
+
+	if (!user_mode(regs) && IS_ENABLED(CONFIG_ARCH_HAS_COPY_MC)) {
+		if (!fixup_exception_me(regs))
+			return -ENOENT;
+	}
+
+	return ret;
+}
+
 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) == 0)
 		return 0;
-	}
 
+	inf = esr_to_fault_info(esr);
 	if (esr & ESR_ELx_FnV) {
 		siaddr = 0;
 	} else {
-- 
2.25.1



From peng.fan at oss.nxp.com  Sun Dec  8 19:54:12 2024
From: peng.fan at oss.nxp.com (Peng Fan)
Date: Mon, 9 Dec 2024 11:54:12 +0800
Subject: [PATCH 2/2] firmware: arm_scmi: Add module aliases to i.MX
 vendor protocols
In-Reply-To: <20241203200038.3961090-3-cristian.marussi@arm.com>
References: <20241203200038.3961090-1-cristian.marussi@arm.com>
 <20241203200038.3961090-3-cristian.marussi@arm.com>
Message-ID: <20241209035412.GA2291@localhost.localdomain>

On Tue, Dec 03, 2024 at 08:00:38PM +0000, Cristian Marussi wrote:
>Using the pattern 'scmi-protocol-0x<PROTO_ID>-<VEND_ID>' as MODULE_ALIAS
>allows the SCMI core to autoload this protocol, if built as a module, when
>its protocol operations are requested by an SCMI driver.
>
>Cc: Peng Fan <peng.fan at nxp.com>
>Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
>---

Acked-by: Peng Fan <peng.fan at nxp.com>


From anshuman.khandual at arm.com  Sun Dec  8 19:12:51 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon,  9 Dec 2024 08:42:51 +0530
Subject: [PATCH] mm/execmem: Make ARCH_WANTS_EXECMEM_LATE depend on EXECMEM
Message-ID: <20241209031251.515903-1-anshuman.khandual@arm.com>

Late initialisation of EXECMEM inherently requires EXEMEM itself, and hence
this dependency should not be left with the subscribing platforms.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Kees Cook <kees at kernel.org>
Cc: linux-arm-kernel at lists.infradead.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 patch applies on v6.13-rc1

 arch/Kconfig       | 1 +
 arch/arm64/Kconfig | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 6682b2a53e34..17716f32dc44 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1058,6 +1058,7 @@ config ARCH_WANTS_MODULES_DATA_IN_VMALLOC
 
 config ARCH_WANTS_EXECMEM_LATE
 	bool
+	depends on EXECMEM
 	help
 	  For architectures that do not allocate executable memory early on
 	  boot, but rather require its initialization late when there is
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5479c8b454c..b146372bc365 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -113,7 +113,7 @@ config ARM64
 	select ARCH_WANT_FRAME_POINTERS
 	select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
 	select ARCH_WANT_LD_ORPHAN_WARN
-	select ARCH_WANTS_EXECMEM_LATE if EXECMEM
+	select ARCH_WANTS_EXECMEM_LATE
 	select ARCH_WANTS_NO_INSTR
 	select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
 	select ARCH_HAS_UBSAN
-- 
2.30.2



From ck.hu at mediatek.com  Sun Dec  8 19:26:37 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 9 Dec 2024 03:26:37 +0000
Subject: [PATCH v2 07/15] dt-bindings: display: mediatek: Add binding for
 MT8195 HDMI-TX v2
In-Reply-To: <20241205114518.53527-8-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-8-angelogioacchino.delregno@collabora.com>
Message-ID: <ad2a805fb52caface837d4ce60461adb3ac7cfd7.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add a binding for the HDMI TX v2 Encoder found in MediaTek MT8195
> and MT8188 SoCs.
> 
> This fully supports the HDMI Specification 2.0b, hence it provides
> support for 3D-HDMI, Polarity inversion, up to 16 bits Deep Color,
> color spaces including RGB444, YCBCR420/422/444 (ITU601/ITU709) and
> xvYCC, with output resolutions up to 3840x2160p at 60Hz.
> 
> Moreover, it also supports HDCP 1.4 and 2.3, Variable Refresh Rate
> (VRR) and Consumer Electronics Control (CEC).
> 
> This IP also includes support for HDMI Audio, including IEC60958
> and IEC61937 SPDIF, 8-channel PCM, DSD, and other lossless audio
> according to HDMI 2.0.

NOTE: There is discussion in [1].

[1] https://patchwork.kernel.org/project/linux-mediatek/patch/20241205114518.53527-8-angelogioacchino.delregno at collabora.com/

Regards,
CK

> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  .../mediatek/mediatek,mt8195-hdmi.yaml        | 154 ++++++++++++++++++
>  1 file changed, 154 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
> new file mode 100644
> index 000000000000..73b1dfaa1adb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
> @@ -0,0 +1,154 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: https://urldefense.com/v3/__http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml*__;Iw!!CTRNKA9wMg0ARbw!kB8f630CUolqkpX3ipvy1_HEGMcwQWXsfpv2JWDnW8CZckULvtoH-VsWFxMXeT035x4ETMcswV81yMrCH3cRsXiprSpF$
> +$schema: https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!kB8f630CUolqkpX3ipvy1_HEGMcwQWXsfpv2JWDnW8CZckULvtoH-VsWFxMXeT035x4ETMcswV81yMrCH3cRsfC96NsG$
> +
> +title: MediaTek HDMI-TX v2 Encoder
> +
> +maintainers:
> +  - AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> +  - CK Hu <ck.hu at mediatek.com>
> +
> +description:
> +  The MediaTek HDMI-TX v2 encoder can generate HDMI format data based on
> +  the HDMI Specification 2.0b.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt8188-hdmi-tx
> +      - mediatek,mt8195-hdmi-tx
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: HDMI Peripheral Bus (APB) clock
> +      - description: HDCP and HDMI_TOP clock
> +      - description: HDCP and HDMI_TOP reference clock
> +      - description: VPP HDMI Split clock
> +
> +  clock-names:
> +    items:
> +      - const: bus
> +      - const: hdcp
> +      - const: hdcp24m
> +      - const: hdmi-split
> +
> +  i2c:
> +    type: object
> +    $ref: /schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
> +    unevaluatedProperties: false
> +    description: HDMI DDC I2C controller
> +
> +  phys:
> +    maxItems: 1
> +    description: PHY providing clocking TMDS and pixel to controller
> +
> +  phy-names:
> +    items:
> +      - const: hdmi
> +
> +  pinctrl-0: true
> +
> +  pinctrl-names:
> +    items:
> +      - const: default
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  '#sound-dai-cells':
> +    const: 1
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Input port, usually connected to the output port of a DPI
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Output port that must be connected either to the input port of
> +          a HDMI connector node containing a ddc-i2c-bus, or to the input
> +          port of an attached bridge chip, such as a SlimPort transmitter.
> +
> +    required:
> +      - port at 0
> +      - port at 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - interrupts
> +  - power-domains
> +  - phys
> +  - phy-names
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt8195-clk.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        hdmi-tx at 1c300000 {
> +            compatible = "mediatek,mt8195-hdmi-tx";
> +            reg = <0 0x1c300000 0 0x1000>;
> +            clocks = <&topckgen CLK_TOP_HDMI_APB>,
> +                     <&topckgen CLK_TOP_HDCP>,
> +                     <&topckgen CLK_TOP_HDCP_24M>,
> +                     <&vppsys1 CLK_VPP1_VPP_SPLIT_HDMI>;
> +            clock-names = "bus", "hdcp", "hdcp24m", "hdmi-split";
> +            interrupts = <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH 0>;
> +            phys = <&hdmi_phy>;
> +            phy-names = "hdmi";
> +            power-domains = <&spm MT8195_POWER_DOMAIN_HDMI_TX>;
> +            pinctrl-names = "default";
> +            pinctrl-0 = <&hdmi_pins>;
> +            #sound-dai-cells = <1>;
> +
> +            hdmitx_ddc: i2c {
> +                compatible = "mediatek,mt8195-hdmi-ddc";
> +                clocks = <&clk26m>;
> +            };
> +
> +            ports {
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +
> +                port at 0 {
> +                    reg = <0>;
> +
> +                    hdmi_in: endpoint {
> +                        remote-endpoint = <&dpi1_out>;
> +                    };
> +                };
> +
> +                port at 1 {
> +                    reg = <1>;
> +
> +                    hdmi_out: endpoint {
> +                        remote-endpoint = <&hdmi_connector_in>;
> +                    };
> +                };
> +            };
> +        };
> +    };
> --
> 2.47.0
> 


From victor.liu at nxp.com  Sun Dec  8 19:39:13 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:13 +0800
Subject: [PATCH v6 09/19] drm/imx: Add i.MX8qxp Display Controller display engine
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-10-victor.liu@nxp.com>

i.MX8qxp Display Controller display engine consists of all processing
units that operate in a display clock domain.  Add minimal feature
support with FrameGen and TCon so that the engine can output display
timings.  The FrameGen driver, TCon driver and display engine driver
are components to be aggregated by a master registered in the upcoming
DRM driver.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* Replace .remove_new with .remove in dc-{de,fg,tc}.c. (Uwe)
* Select REGMAP and REGMAP_MMIO Kconfig options.
* Fix commit message to state that display engine driver is a component driver
  instead of a master/aggregate driver.

v4:
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Inline some small functions. (Dmitry)
* Move dc_fg_displaymode() and dc_fg_panic_displaymode() function calls from
  KMS routine to initialization stage. (Dmitry)
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
* Drop unnecessary private struct dc_*_priv.
* Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
  interfaces to bind/unbind the drivers.

v3:
* No change.

v2:
* Use OF alias id to get instance id.
* Add dev member to struct dc_tc.

 drivers/gpu/drm/imx/Kconfig     |   1 +
 drivers/gpu/drm/imx/Makefile    |   1 +
 drivers/gpu/drm/imx/dc/Kconfig  |   7 +
 drivers/gpu/drm/imx/dc/Makefile |   5 +
 drivers/gpu/drm/imx/dc/dc-de.c  | 153 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-de.h  |  57 +++++
 drivers/gpu/drm/imx/dc/dc-drv.c |  32 +++
 drivers/gpu/drm/imx/dc/dc-drv.h |  24 ++
 drivers/gpu/drm/imx/dc/dc-fg.c  | 374 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-tc.c  | 138 ++++++++++++
 10 files changed, 792 insertions(+)
 create mode 100644 drivers/gpu/drm/imx/dc/Kconfig
 create mode 100644 drivers/gpu/drm/imx/dc/Makefile
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fg.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-tc.c

diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
index 03535a15dd8f..3e8c6edbc17c 100644
--- a/drivers/gpu/drm/imx/Kconfig
+++ b/drivers/gpu/drm/imx/Kconfig
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
+source "drivers/gpu/drm/imx/dc/Kconfig"
 source "drivers/gpu/drm/imx/dcss/Kconfig"
 source "drivers/gpu/drm/imx/ipuv3/Kconfig"
 source "drivers/gpu/drm/imx/lcdc/Kconfig"
diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index 86f38e7c7422..c7b317640d71 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
+obj-$(CONFIG_DRM_IMX8_DC) += dc/
 obj-$(CONFIG_DRM_IMX_DCSS) += dcss/
 obj-$(CONFIG_DRM_IMX) += ipuv3/
 obj-$(CONFIG_DRM_IMX_LCDC) += lcdc/
diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
new file mode 100644
index 000000000000..e1ef76d82830
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -0,0 +1,7 @@
+config DRM_IMX8_DC
+	tristate "Freescale i.MX8 Display Controller Graphics"
+	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
+	select REGMAP
+	select REGMAP_MMIO
+	help
+	  enable Freescale i.MX8 Display Controller(DC) graphics support
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
new file mode 100644
index 000000000000..56de82d53d4d
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+imx8-dc-drm-objs := dc-de.o dc-drv.o dc-fg.o dc-tc.o
+
+obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-de.c b/drivers/gpu/drm/imx/dc/dc-de.c
new file mode 100644
index 000000000000..24cd37c1e4a8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-de.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+
+#define POLARITYCTRL		0xc
+#define  POLEN_HIGH		BIT(2)
+
+static const struct regmap_range dc_de_regmap_ranges[] = {
+	regmap_reg_range(POLARITYCTRL, POLARITYCTRL),
+};
+
+static const struct regmap_access_table dc_de_regmap_access_table = {
+	.yes_ranges = dc_de_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_de_regmap_ranges),
+};
+
+static const struct regmap_config dc_de_top_regmap_config = {
+	.name = "display-engine-top",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_de_regmap_access_table,
+	.rd_table = &dc_de_regmap_access_table,
+};
+
+static inline void dc_dec_init(struct dc_de *de)
+{
+	regmap_write_bits(de->reg_top, POLARITYCTRL, POLARITYCTRL, POLEN_HIGH);
+}
+
+static int dc_de_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	void __iomem *base_top;
+	struct dc_de *de;
+	int ret;
+
+	de = devm_kzalloc(dev, sizeof(*de), GFP_KERNEL);
+	if (!de)
+		return -ENOMEM;
+
+	base_top = devm_platform_ioremap_resource_byname(pdev, "top");
+	if (IS_ERR(base_top))
+		return PTR_ERR(base_top);
+
+	de->reg_top = devm_regmap_init_mmio(dev, base_top,
+					    &dc_de_top_regmap_config);
+	if (IS_ERR(de->reg_top))
+		return PTR_ERR(de->reg_top);
+
+	de->irq_shdld = platform_get_irq_byname(pdev, "shdload");
+	if (de->irq_shdld < 0)
+		return de->irq_shdld;
+
+	de->irq_framecomplete = platform_get_irq_byname(pdev, "framecomplete");
+	if (de->irq_framecomplete < 0)
+		return de->irq_framecomplete;
+
+	de->irq_seqcomplete = platform_get_irq_byname(pdev, "seqcomplete");
+	if (de->irq_seqcomplete < 0)
+		return de->irq_seqcomplete;
+
+	de->id = of_alias_get_id(dev->of_node, "dc0-display-engine");
+	if (de->id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", de->id);
+		return de->id;
+	}
+
+	de->dev = dev;
+
+	dev_set_drvdata(dev, de);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	dc_drm->de[de->id] = de;
+
+	return 0;
+}
+
+static const struct component_ops dc_de_ops = {
+	.bind = dc_de_bind,
+};
+
+static int dc_de_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = component_add(&pdev->dev, &dc_de_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_de_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_de_ops);
+}
+
+static int dc_de_runtime_resume(struct device *dev)
+{
+	struct dc_de *de = dev_get_drvdata(dev);
+
+	dc_dec_init(de);
+	dc_fg_init(de->fg);
+	dc_tc_init(de->tc);
+
+	return 0;
+}
+
+static const struct dev_pm_ops dc_de_pm_ops = {
+	RUNTIME_PM_OPS(NULL, dc_de_runtime_resume, NULL)
+};
+
+static const struct of_device_id dc_de_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-display-engine", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_de_dt_ids);
+
+struct platform_driver dc_de_driver = {
+	.probe = dc_de_probe,
+	.remove = dc_de_remove,
+	.driver = {
+		.name = "imx8-dc-display-engine",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_de_dt_ids,
+		.pm = pm_sleep_ptr(&dc_de_pm_ops),
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
new file mode 100644
index 000000000000..17a44362118e
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_DISPLAY_ENGINE_H__
+#define __DC_DISPLAY_ENGINE_H__
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <drm/drm_modes.h>
+
+#define DC_DISPLAYS	2
+
+struct dc_fg {
+	struct device *dev;
+	struct regmap *reg;
+	struct clk *clk_disp;
+};
+
+struct dc_tc {
+	struct device *dev;
+	struct regmap *reg;
+};
+
+struct dc_de {
+	struct device *dev;
+	struct regmap *reg_top;
+	struct dc_fg *fg;
+	struct dc_tc *tc;
+	int irq_shdld;
+	int irq_framecomplete;
+	int irq_seqcomplete;
+	int id;
+};
+
+/* Frame Generator Unit */
+void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m);
+void dc_fg_enable(struct dc_fg *fg);
+void dc_fg_disable(struct dc_fg *fg);
+void dc_fg_shdtokgen(struct dc_fg *fg);
+u32 dc_fg_get_frame_index(struct dc_fg *fg);
+u32 dc_fg_get_line_index(struct dc_fg *fg);
+bool dc_fg_wait_for_frame_index_moving(struct dc_fg *fg);
+bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg);
+void dc_fg_secondary_clear_channel_status(struct dc_fg *fg);
+int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg);
+void dc_fg_enable_clock(struct dc_fg *fg);
+void dc_fg_disable_clock(struct dc_fg *fg);
+enum drm_mode_status dc_fg_check_clock(struct dc_fg *fg, int clk_khz);
+void dc_fg_init(struct dc_fg *fg);
+
+/* Timing Controller Unit */
+void dc_tc_init(struct dc_tc *tc);
+
+#endif /* __DC_DISPLAY_ENGINE_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
new file mode 100644
index 000000000000..e5910a82dd4d
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "dc-drv.h"
+
+static struct platform_driver * const dc_drivers[] = {
+	&dc_de_driver,
+	&dc_fg_driver,
+	&dc_tc_driver,
+};
+
+static int __init dc_drm_init(void)
+{
+	return platform_register_drivers(dc_drivers, ARRAY_SIZE(dc_drivers));
+}
+
+static void __exit dc_drm_exit(void)
+{
+	platform_unregister_drivers(dc_drivers, ARRAY_SIZE(dc_drivers));
+}
+
+module_init(dc_drm_init);
+module_exit(dc_drm_exit);
+
+MODULE_DESCRIPTION("i.MX8 Display Controller DRM Driver");
+MODULE_AUTHOR("Liu Ying <victor.liu at nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
new file mode 100644
index 000000000000..e1290d9a0a99
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_DRV_H__
+#define __DC_DRV_H__
+
+#include <linux/platform_device.h>
+
+#include <drm/drm_device.h>
+
+#include "dc-de.h"
+
+struct dc_drm_device {
+	struct drm_device base;
+	struct dc_de *de[DC_DISPLAYS];
+};
+
+extern struct platform_driver dc_de_driver;
+extern struct platform_driver dc_fg_driver;
+extern struct platform_driver dc_tc_driver;
+
+#endif /* __DC_DRV_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
new file mode 100644
index 000000000000..bb51fe6faee0
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fg.c
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/device.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/regmap.h>
+#include <linux/units.h>
+
+#include <drm/drm_modes.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+
+#define FGSTCTRL		0x8
+#define  FGSYNCMODE_MASK	GENMASK(2, 1)
+#define  FGSYNCMODE(x)		FIELD_PREP(FGSYNCMODE_MASK, (x))
+#define  SHDEN			BIT(0)
+
+#define HTCFG1			0xc
+#define  HTOTAL(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  HACT(x)		FIELD_PREP(GENMASK(13, 0), (x))
+
+#define HTCFG2			0x10
+#define  HSEN			BIT(31)
+#define  HSBP(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  HSYNC(x)		FIELD_PREP(GENMASK(13, 0), ((x) - 1))
+
+#define VTCFG1			0x14
+#define  VTOTAL(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  VACT(x)		FIELD_PREP(GENMASK(13, 0), (x))
+
+#define VTCFG2			0x18
+#define  VSEN			BIT(31)
+#define  VSBP(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  VSYNC(x)		FIELD_PREP(GENMASK(13, 0), ((x) - 1))
+
+#define PKICKCONFIG		0x2c
+#define SKICKCONFIG		0x30
+#define  EN			BIT(31)
+#define  ROW(x)			FIELD_PREP(GENMASK(29, 16), (x))
+#define  COL(x)			FIELD_PREP(GENMASK(13, 0), (x))
+
+#define PACFG			0x54
+#define SACFG			0x58
+#define  STARTY(x)		FIELD_PREP(GENMASK(29, 16), ((x) + 1))
+#define  STARTX(x)		FIELD_PREP(GENMASK(13, 0), ((x) + 1))
+
+#define FGINCTRL		0x5c
+#define FGINCTRLPANIC		0x60
+#define  FGDM_MASK		GENMASK(2, 0)
+#define  ENPRIMALPHA		BIT(3)
+#define  ENSECALPHA		BIT(4)
+
+#define FGCCR			0x64
+#define  CCGREEN(x)		FIELD_PREP(GENMASK(19, 10), (x))
+
+#define FGENABLE		0x68
+#define  FGEN			BIT(0)
+
+#define FGSLR			0x6c
+#define  SHDTOKGEN		BIT(0)
+
+#define FGTIMESTAMP		0x74
+#define  FRAMEINDEX(x)		FIELD_GET(GENMASK(31, 14), (x))
+#define  LINEINDEX(x)		FIELD_GET(GENMASK(13, 0), (x))
+
+#define FGCHSTAT		0x78
+#define  SECSYNCSTAT		BIT(24)
+#define  SFIFOEMPTY		BIT(16)
+
+#define FGCHSTATCLR		0x7c
+#define  CLRSECSTAT		BIT(16)
+
+enum dc_fg_syncmode {
+	FG_SYNCMODE_OFF,	/* No side-by-side synchronization. */
+};
+
+enum dc_fg_dm {
+	FG_DM_CONSTCOL = 0x1,	/* Constant Color Background is shown. */
+	FG_DM_SEC_ON_TOP = 0x5,	/* Both inputs overlaid with secondary on top. */
+};
+
+static const struct regmap_range dc_fg_regmap_wr_ranges[] = {
+	regmap_reg_range(FGSTCTRL, VTCFG2),
+	regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
+	regmap_reg_range(PACFG, FGSLR),
+	regmap_reg_range(FGCHSTATCLR, FGCHSTATCLR),
+};
+
+static const struct regmap_range dc_fg_regmap_rd_ranges[] = {
+	regmap_reg_range(FGSTCTRL, VTCFG2),
+	regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
+	regmap_reg_range(PACFG, FGSLR),
+	regmap_reg_range(FGTIMESTAMP, FGCHSTATCLR),
+};
+
+static const struct regmap_access_table dc_fg_regmap_wr_table = {
+	.yes_ranges = dc_fg_regmap_wr_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_wr_ranges),
+};
+
+static const struct regmap_access_table dc_fg_regmap_rd_table = {
+	.yes_ranges = dc_fg_regmap_rd_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_rd_ranges),
+};
+
+static const struct regmap_config dc_fg_regmap_config = {
+	.name = "framegen",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fg_regmap_wr_table,
+	.rd_table = &dc_fg_regmap_rd_table,
+};
+
+static inline void dc_fg_enable_shden(struct dc_fg *fg)
+{
+	regmap_write_bits(fg->reg, FGSTCTRL, SHDEN, SHDEN);
+}
+
+static inline void dc_fg_syncmode(struct dc_fg *fg, enum dc_fg_syncmode mode)
+{
+	regmap_write_bits(fg->reg, FGSTCTRL, FGSYNCMODE_MASK, FGSYNCMODE(mode));
+}
+
+void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
+{
+	u32 hact, htotal, hsync, hsbp;
+	u32 vact, vtotal, vsync, vsbp;
+	u32 kick_row, kick_col;
+	int ret;
+
+	hact = m->crtc_hdisplay;
+	htotal = m->crtc_htotal;
+	hsync = m->crtc_hsync_end - m->crtc_hsync_start;
+	hsbp = m->crtc_htotal - m->crtc_hsync_start;
+
+	vact = m->crtc_vdisplay;
+	vtotal = m->crtc_vtotal;
+	vsync = m->crtc_vsync_end - m->crtc_vsync_start;
+	vsbp = m->crtc_vtotal - m->crtc_vsync_start;
+
+	/* video mode */
+	regmap_write(fg->reg, HTCFG1, HACT(hact)   | HTOTAL(htotal));
+	regmap_write(fg->reg, HTCFG2, HSYNC(hsync) | HSBP(hsbp) | HSEN);
+	regmap_write(fg->reg, VTCFG1, VACT(vact)   | VTOTAL(vtotal));
+	regmap_write(fg->reg, VTCFG2, VSYNC(vsync) | VSBP(vsbp) | VSEN);
+
+	kick_col = hact + 1;
+	kick_row = vact;
+
+	/* pkickconfig */
+	regmap_write(fg->reg, PKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
+
+	/* skikconfig */
+	regmap_write(fg->reg, SKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
+
+	/* primary and secondary area position configuration */
+	regmap_write(fg->reg, PACFG, STARTX(0) | STARTY(0));
+	regmap_write(fg->reg, SACFG, STARTX(0) | STARTY(0));
+
+	/* alpha */
+	regmap_write_bits(fg->reg, FGINCTRL,      ENPRIMALPHA | ENSECALPHA, 0);
+	regmap_write_bits(fg->reg, FGINCTRLPANIC, ENPRIMALPHA | ENSECALPHA, 0);
+
+	/* constant color is green(used in panic mode)  */
+	regmap_write(fg->reg, FGCCR, CCGREEN(0x3ff));
+
+	ret = clk_set_rate(fg->clk_disp, m->clock * HZ_PER_KHZ);
+	if (ret < 0)
+		dev_err(fg->dev, "failed to set display clock rate: %d\n", ret);
+}
+
+static inline void dc_fg_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
+{
+	regmap_write_bits(fg->reg, FGINCTRL, FGDM_MASK, mode);
+}
+
+static inline void dc_fg_panic_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
+{
+	regmap_write_bits(fg->reg, FGINCTRLPANIC, FGDM_MASK, mode);
+}
+
+void dc_fg_enable(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGENABLE, FGEN);
+}
+
+void dc_fg_disable(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGENABLE, 0);
+}
+
+void dc_fg_shdtokgen(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGSLR, SHDTOKGEN);
+}
+
+u32 dc_fg_get_frame_index(struct dc_fg *fg)
+{
+	u32 val;
+
+	regmap_read(fg->reg, FGTIMESTAMP, &val);
+
+	return FRAMEINDEX(val);
+}
+
+u32 dc_fg_get_line_index(struct dc_fg *fg)
+{
+	u32 val;
+
+	regmap_read(fg->reg, FGTIMESTAMP, &val);
+
+	return LINEINDEX(val);
+}
+
+bool dc_fg_wait_for_frame_index_moving(struct dc_fg *fg)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(100);
+	u32 frame_index, last_frame_index;
+
+	frame_index = dc_fg_get_frame_index(fg);
+	do {
+		last_frame_index = frame_index;
+		frame_index = dc_fg_get_frame_index(fg);
+	} while (last_frame_index == frame_index &&
+		 time_before(jiffies, timeout));
+
+	return last_frame_index != frame_index;
+}
+
+bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg)
+{
+	u32 val;
+
+	regmap_read(fg->reg, FGCHSTAT, &val);
+
+	return !!(val & SFIFOEMPTY);
+}
+
+void dc_fg_secondary_clear_channel_status(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGCHSTATCLR, CLRSECSTAT);
+}
+
+int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg)
+{
+	unsigned int val;
+
+	return regmap_read_poll_timeout(fg->reg, FGCHSTAT, val,
+					val & SECSYNCSTAT, 5, 100000);
+}
+
+void dc_fg_enable_clock(struct dc_fg *fg)
+{
+	int ret;
+
+	ret = clk_prepare_enable(fg->clk_disp);
+	if (ret)
+		dev_err(fg->dev, "failed to enable display clock: %d\n", ret);
+}
+
+void dc_fg_disable_clock(struct dc_fg *fg)
+{
+	clk_disable_unprepare(fg->clk_disp);
+}
+
+enum drm_mode_status dc_fg_check_clock(struct dc_fg *fg, int clk_khz)
+{
+	unsigned long rounded_rate;
+
+	rounded_rate = clk_round_rate(fg->clk_disp, clk_khz * HZ_PER_KHZ);
+
+	if (rounded_rate != clk_khz * HZ_PER_KHZ)
+		return MODE_NOCLOCK;
+
+	return MODE_OK;
+}
+
+void dc_fg_init(struct dc_fg *fg)
+{
+	dc_fg_enable_shden(fg);
+	dc_fg_syncmode(fg, FG_SYNCMODE_OFF);
+	dc_fg_displaymode(fg, FG_DM_SEC_ON_TOP);
+	dc_fg_panic_displaymode(fg, FG_DM_CONSTCOL);
+}
+
+static int dc_fg_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	void __iomem *base;
+	struct dc_fg *fg;
+	struct dc_de *de;
+	int id;
+
+	fg = devm_kzalloc(dev, sizeof(*fg), GFP_KERNEL);
+	if (!fg)
+		return -ENOMEM;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	fg->reg = devm_regmap_init_mmio(dev, base, &dc_fg_regmap_config);
+	if (IS_ERR(fg->reg))
+		return PTR_ERR(fg->reg);
+
+	fg->clk_disp = devm_clk_get(dev, NULL);
+	if (IS_ERR(fg->clk_disp))
+		return dev_err_probe(dev, PTR_ERR(fg->clk_disp),
+				     "failed to get display clock\n");
+
+	id = of_alias_get_id(dev->of_node, "dc0-framegen");
+	if (id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", id);
+		return id;
+	}
+
+	fg->dev = dev;
+
+	de = dc_drm->de[id];
+	de->fg = fg;
+
+	return 0;
+}
+
+static const struct component_ops dc_fg_ops = {
+	.bind = dc_fg_bind,
+};
+
+static int dc_fg_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_fg_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_fg_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_fg_ops);
+}
+
+static const struct of_device_id dc_fg_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-framegen", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_fg_dt_ids);
+
+struct platform_driver dc_fg_driver = {
+	.probe = dc_fg_probe,
+	.remove = dc_fg_remove,
+	.driver = {
+		.name = "imx8-dc-framegen",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_fg_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-tc.c b/drivers/gpu/drm/imx/dc/dc-tc.c
new file mode 100644
index 000000000000..66e0efbc90ab
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-tc.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "dc-drv.h"
+#include "dc-de.h"
+
+#define TCON_CTRL	0x410
+#define  CTRL_RST_VAL	0x01401408
+
+/* red: MAPBIT 29-20, green: MAPBIT 19-10, blue: MAPBIT 9-0 */
+#define MAPBIT3_0	0x418
+#define MAPBIT7_4	0x41c
+#define MAPBIT11_8	0x420
+#define MAPBIT15_12	0x424
+#define MAPBIT19_16	0x428
+#define MAPBIT23_20	0x42c
+#define MAPBIT27_24	0x430
+#define MAPBIT31_28	0x434
+
+static const struct regmap_range dc_tc_regmap_ranges[] = {
+	regmap_reg_range(TCON_CTRL, TCON_CTRL),
+	regmap_reg_range(MAPBIT3_0, MAPBIT31_28),
+};
+
+static const struct regmap_access_table dc_tc_regmap_access_table = {
+	.yes_ranges = dc_tc_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_tc_regmap_ranges),
+};
+
+static const struct regmap_config dc_tc_regmap_config = {
+	.name = "tcon",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_tc_regmap_access_table,
+	.rd_table = &dc_tc_regmap_access_table,
+};
+
+/*
+ * The pixels reach TCON are always in 30-bit BGR format.
+ * The first bridge always receives pixels in 30-bit RGB format.
+ * So, map the format to MEDIA_BUS_FMT_RGB101010_1X30.
+ */
+static const u32 dc_tc_mapbit[] = {
+	0x17161514, 0x1b1a1918, 0x0b0a1d1c, 0x0f0e0d0c,
+	0x13121110, 0x03020100, 0x07060504, 0x00000908,
+};
+
+void dc_tc_init(struct dc_tc *tc)
+{
+	/* reset TCON_CTRL to POR default so that TCON works in bypass mode */
+	regmap_write(tc->reg, TCON_CTRL, CTRL_RST_VAL);
+
+	/* set format */
+	regmap_bulk_write(tc->reg, MAPBIT3_0, dc_tc_mapbit,
+			  ARRAY_SIZE(dc_tc_mapbit));
+}
+
+static int dc_tc_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	void __iomem *base;
+	struct dc_tc *tc;
+	struct dc_de *de;
+	int id;
+
+	tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL);
+	if (!tc)
+		return -ENOMEM;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	tc->reg = devm_regmap_init_mmio(dev, base, &dc_tc_regmap_config);
+	if (IS_ERR(tc->reg))
+		return PTR_ERR(tc->reg);
+
+	id = of_alias_get_id(dev->of_node, "dc0-tcon");
+	if (id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", id);
+		return id;
+	}
+
+	de = dc_drm->de[id];
+	de->tc = tc;
+	de->tc->dev = dev;
+
+	return 0;
+}
+
+static const struct component_ops dc_tc_ops = {
+	.bind = dc_tc_bind,
+};
+
+static int dc_tc_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_tc_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_tc_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_tc_ops);
+}
+
+static const struct of_device_id dc_tc_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-tcon", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_tc_dt_ids);
+
+struct platform_driver dc_tc_driver = {
+	.probe = dc_tc_probe,
+	.remove = dc_tc_remove,
+	.driver = {
+		.name = "imx8-dc-tcon",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_tc_dt_ids,
+	},
+};
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:18 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:18 +0800
Subject: [DO NOT MERGE PATCH v6 14/19] dt-bindings: phy: mixel, mipi-dsi-phy: Allow assigned-clock* properties
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-15-victor.liu@nxp.com>

assigned-clock* properties can be used by default now, so allow them.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch as needed by MIPI/LVDS subsystems device tree.

 .../devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml          | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
index 3c28ec50f097..286a4fcc977d 100644
--- a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
@@ -72,11 +72,6 @@ allOf:
           contains:
             const: fsl,imx8qxp-mipi-dphy
     then:
-      properties:
-        assigned-clocks: false
-        assigned-clock-parents: false
-        assigned-clock-rates: false
-
       required:
         - fsl,syscon
 
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:19 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:19 +0800
Subject: [DO NOT MERGE PATCH v6 15/19] dt-bindings: firmware: imx: Add SCU controlled display pixel link nodes
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-16-victor.liu@nxp.com>

Document SCU controlled display pixel link child nodes.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch as needed by display controller subsystem device tree.

 .../devicetree/bindings/firmware/fsl,scu.yaml | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
index 557e524786c2..1a920f013ad2 100644
--- a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
+++ b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
@@ -30,6 +30,26 @@ properties:
       Clock controller node that provides the clocks controlled by the SCU
     $ref: /schemas/clock/fsl,scu-clk.yaml
 
+  dc0-pixel-link0:
+    description:
+      Display pixel link0 in display controller subsystem0 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
+  dc0-pixel-link1:
+    description:
+      Display pixel link1 in display controller subsystem0 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
+  dc1-pixel-link0:
+    description:
+      Display pixel link0 in display controller subsystem1 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
+  dc1-pixel-link1:
+    description:
+      Display pixel link1 in display controller subsystem1 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
   gpio:
     description:
       Control the GPIO PINs on SCU domain over the firmware APIs
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:20 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:20 +0800
Subject: [DO NOT MERGE PATCH v6 16/19] arm64: dts: imx8qxp: Add display controller subsystem
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-17-victor.liu@nxp.com>

Add display controller subsystem in i.MX8qxp SoC.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Krzysztof)

 .../arm64/boot/dts/freescale/imx8-ss-dc0.dtsi | 408 ++++++++++++++++++
 .../boot/dts/freescale/imx8qxp-ss-dc.dtsi     | 236 ++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |  25 +-
 3 files changed, 668 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
new file mode 100644
index 000000000000..0db345204b89
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+dc0_axi_ext_clk: clock-dc0-axi-ext {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <800000000>;
+	clock-output-names = "dc0_axi_ext_clk";
+};
+
+dc0_axi_int_clk: clock-dc0-axi-int {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <400000000>;
+	clock-output-names = "dc0_axi_int_clk";
+};
+
+dc0_cfg_clk: clock-dc0-cfg {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <100000000>;
+	clock-output-names = "dc0_cfg_clk";
+};
+
+dc0_subsys: bus at 56000000 {
+	compatible = "simple-bus";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0x56000000 0x0 0x56000000 0x1000000>;
+
+	dc0_irqsteer: interrupt-controller at 56000000 {
+		compatible = "fsl,imx-irqsteer";
+		reg = <0x56000000 0x1000>;
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		#interrupt-cells = <1>;
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&dc0_lis_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+		fsl,channel = <0>;
+		fsl,num-irqs = <512>;
+	};
+
+	dc0_disp_lpcg: clock-controller at 56010000 {
+		reg = <0x56010000 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_DC_0 IMX_SC_PM_CLK_MISC0>,
+			 <&clk IMX_SC_R_DC_0 IMX_SC_PM_CLK_MISC1>;
+		clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>;
+		clock-output-names = "dc0_disp0_lpcg_clk", "dc0_disp1_lpcg_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_lis_lpcg: clock-controller at 56010004 {
+		reg = <0x56010004 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "dc0_lis_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_disp_ctrl_link_mst0_lpcg: clock-controller at 56010008 {
+		reg = <0x56010008 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "dc0_disp_ctrl_link_mst0_lpcg_msi_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_pixel_combiner_lpcg: clock-controller at 56010010 {
+		reg = <0x56010010 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "dc0_pixel_combiner_lpcg_apb_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_lpcg: clock-controller at 56010014 {
+		reg = <0x56010014 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>, <&dc0_axi_int_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_5>;
+		clock-output-names = "dc0_lpcg_cfg_clk",
+				     "dc0_lpcg_axi_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_pc: pixel-combiner at 56020000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x56020000 0x10000>;
+		clocks = <&dc0_pixel_combiner_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "apb";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+		status = "disabled";
+
+		channel at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			status = "disabled";
+
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_combiner_ch0_dc0_disp0: endpoint {
+					remote-endpoint = <&dc0_disp0_dc0_pixel_combiner_ch0>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				dc0_pixel_combiner_ch0_dc0_pixel_link0: endpoint {
+					remote-endpoint = <&dc0_pixel_link0_dc0_pixel_combiner_ch0>;
+				};
+			};
+		};
+
+		channel at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			status = "disabled";
+
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_combiner_ch1_dc0_disp1: endpoint {
+					remote-endpoint = <&dc0_disp1_dc0_pixel_combiner_ch1>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				dc0_pixel_combiner_ch1_dc0_pixel_link1: endpoint {
+					remote-endpoint = <&dc0_pixel_link1_dc0_pixel_combiner_ch1>;
+				};
+			};
+		};
+	};
+
+	dc0: display-controller at 56180000 {
+		reg = <0x56180000 0x40000>;
+		clocks = <&dc0_lpcg IMX_LPCG_CLK_4>;
+		power-domains = <&pd IMX_SC_R_DC_0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		status = "disabled";
+
+		dc0_intc: interrupt-controller at 56180040 {
+			reg = <0x56180040 0x60>;
+			clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+			interrupt-controller;
+			interrupt-parent = <&dc0_irqsteer>;
+			#interrupt-cells = <1>;
+			interrupts = <448>, <449>, <450>,  <64>,
+				      <65>,  <66>,  <67>,  <68>,
+				      <69>,  <70>, <193>, <194>,
+				     <195>, <196>, <197>,  <72>,
+				      <73>,  <74>,  <75>,  <76>,
+				      <77>,  <78>,  <79>,  <80>,
+				      <81>, <199>, <200>, <201>,
+				     <202>, <203>, <204>, <205>,
+				     <206>, <207>, <208>,   <5>,
+				       <0>,   <1>,   <2>,   <3>,
+				       <4>,  <82>,  <83>,  <84>,
+				      <85>, <209>, <210>, <211>,
+				     <212>;
+			interrupt-names = "store9_shdload",
+					  "store9_framecomplete",
+					  "store9_seqcomplete",
+					  "extdst0_shdload",
+					  "extdst0_framecomplete",
+					  "extdst0_seqcomplete",
+					  "extdst4_shdload",
+					  "extdst4_framecomplete",
+					  "extdst4_seqcomplete",
+					  "extdst1_shdload",
+					  "extdst1_framecomplete",
+					  "extdst1_seqcomplete",
+					  "extdst5_shdload",
+					  "extdst5_framecomplete",
+					  "extdst5_seqcomplete",
+					  "disengcfg_shdload0",
+					  "disengcfg_framecomplete0",
+					  "disengcfg_seqcomplete0",
+					  "framegen0_int0",
+					  "framegen0_int1",
+					  "framegen0_int2",
+					  "framegen0_int3",
+					  "sig0_shdload",
+					  "sig0_valid",
+					  "sig0_error",
+					  "disengcfg_shdload1",
+					  "disengcfg_framecomplete1",
+					  "disengcfg_seqcomplete1",
+					  "framegen1_int0",
+					  "framegen1_int1",
+					  "framegen1_int2",
+					  "framegen1_int3",
+					  "sig1_shdload",
+					  "sig1_valid",
+					  "sig1_error",
+					  "reserved",
+					  "cmdseq_error",
+					  "comctrl_sw0",
+					  "comctrl_sw1",
+					  "comctrl_sw2",
+					  "comctrl_sw3",
+					  "framegen0_primsync_on",
+					  "framegen0_primsync_off",
+					  "framegen0_secsync_on",
+					  "framegen0_secsync_off",
+					  "framegen1_primsync_on",
+					  "framegen1_primsync_off",
+					  "framegen1_secsync_on",
+					  "framegen1_secsync_off";
+		};
+
+		dc0_pixel_engine: pixel-engine at 56180800 {
+			reg = <0x56180800 0xac00>;
+			clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			dc0_constframe0: constframe at 56180960 {
+				reg = <0x56180960 0xc>, <0x56184400 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst0: extdst at 56180980 {
+				reg = <0x56180980 0x1c>, <0x56184800 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <3>, <4>, <5>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_constframe4: constframe at 561809a0 {
+				reg = <0x561809a0 0xc>, <0x56184c00 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst4: extdst at 561809c0 {
+				reg = <0x561809c0 0x1c>, <0x56185000 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <6>, <7>, <8>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_constframe1: constframe at 561809e0 {
+				reg = <0x561809e0 0xc>, <0x56185400 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst1: extdst at 56180a00 {
+				reg = <0x56180a00 0x1c>, <0x56185800 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <9>, <10>, <11>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_constframe5: constframe at 56180a20 {
+				reg = <0x56180a20 0xc>, <0x56185c00 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst5: extdst at 56180a40 {
+				reg = <0x56180a40 0x1c>, <0x56186000 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <12>, <13>, <14>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_fetchwarp2: fetchwarp at 56180a60 {
+				reg = <0x56180a60 0x10>, <0x56186400 0x190>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_fetchlayer0: fetchlayer at 56180ac0 {
+				reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend0: layerblend at 56180ba0 {
+				reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend1: layerblend at 56180bc0 {
+				reg = <0x56180bc0 0x10>, <0x5618a800 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend2: layerblend at 56180be0 {
+				reg = <0x56180be0 0x10>, <0x5618ac00 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend3: layerblend at 56180c00 {
+				reg = <0x56180c00 0x10>, <0x5618b000 0x20>;
+				reg-names = "pec", "cfg";
+			};
+		};
+
+		dc0_display_engine0: display-engine at 5618b400 {
+			reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
+			reg-names = "top", "cfg";
+			interrupt-parent = <&dc0_intc>;
+			interrupts = <15>, <16>, <17>;
+			interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			dc0_framegen0: framegen at 5618b800 {
+				reg = <0x5618b800 0x98>;
+				clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <18>, <19>, <20>, <21>,
+					     <41>, <42>, <43>, <44>;
+				interrupt-names = "int0", "int1", "int2", "int3",
+						  "primsync_on", "primsync_off",
+						  "secsync_on", "secsync_off";
+			};
+
+			dc0_tcon0: tcon at 5618c800 {
+				reg = <0x5618c800 0x588>;
+
+				port {
+					dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
+						remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
+					};
+				};
+			};
+		};
+
+		dc0_display_engine1: display-engine at 5618b420 {
+			reg = <0x5618b420 0x14>, <0x5618d400 0x1c00>;
+			reg-names = "top", "cfg";
+			interrupt-parent = <&dc0_intc>;
+			interrupts = <25>, <26>, <27>;
+			interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			power-domains = <&pd IMX_SC_R_DC_0_PLL_1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			dc0_framegen1: framegen at 5618d400 {
+				reg = <0x5618d400 0x98>;
+				clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_1>;
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <28>, <29>, <30>, <31>,
+					     <45>, <46>, <47>, <48>;
+				interrupt-names = "int0", "int1", "int2", "int3",
+						  "primsync_on", "primsync_off",
+						  "secsync_on", "secsync_off";
+			};
+
+			dc0_tcon1: tcon at 5618e400 {
+				reg = <0x5618e400 0x588>;
+
+				port {
+					dc0_disp1_dc0_pixel_combiner_ch1: endpoint {
+						remote-endpoint = <&dc0_pixel_combiner_ch1_dc0_disp1>;
+					};
+				};
+			};
+		};
+	};
+
+	dc0_pl_msi_bus: bus at 56200000 {
+		reg = <0x56200000 0x100000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&dc0_irqsteer>;
+		interrupts = <320>;
+		ranges;
+		clocks = <&dc0_disp_ctrl_link_mst0_lpcg IMX_LPCG_CLK_4>,
+			 <&dc0_disp_ctrl_link_mst0_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "msi", "ahb";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
new file mode 100644
index 000000000000..299720d8c99e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+&dc0 {
+	compatible = "fsl,imx8qxp-dc";
+};
+
+&dc0_constframe0 {
+	compatible = "fsl,imx8qxp-dc-constframe";
+};
+
+&dc0_constframe1 {
+	compatible = "fsl,imx8qxp-dc-constframe";
+};
+
+&dc0_constframe4 {
+	compatible = "fsl,imx8qxp-dc-constframe";
+};
+
+&dc0_constframe5 {
+	compatible = "fsl,imx8qxp-dc-constframe";
+};
+
+&dc0_disp_ctrl_link_mst0_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_disp_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_display_engine0 {
+	compatible = "fsl,imx8qxp-dc-display-engine";
+};
+
+&dc0_display_engine1 {
+	compatible = "fsl,imx8qxp-dc-display-engine";
+};
+
+&dc0_extdst0 {
+	compatible = "fsl,imx8qxp-dc-extdst";
+};
+
+&dc0_extdst1 {
+	compatible = "fsl,imx8qxp-dc-extdst";
+};
+
+&dc0_extdst4 {
+	compatible = "fsl,imx8qxp-dc-extdst";
+};
+
+&dc0_extdst5 {
+	compatible = "fsl,imx8qxp-dc-extdst";
+};
+
+&dc0_fetchlayer0 {
+	compatible = "fsl,imx8qxp-dc-fetchlayer";
+};
+
+&dc0_fetchwarp2 {
+	compatible = "fsl,imx8qxp-dc-fetchwarp";
+};
+
+&dc0_framegen0 {
+	compatible = "fsl,imx8qxp-dc-framegen";
+};
+
+&dc0_framegen1 {
+	compatible = "fsl,imx8qxp-dc-framegen";
+};
+
+&dc0_intc {
+	compatible = "fsl,imx8qxp-dc-intc";
+};
+
+&dc0_layerblend0 {
+	compatible = "fsl,imx8qxp-dc-layerblend";
+};
+
+&dc0_layerblend1 {
+	compatible = "fsl,imx8qxp-dc-layerblend";
+};
+
+&dc0_layerblend2 {
+	compatible = "fsl,imx8qxp-dc-layerblend";
+};
+
+&dc0_layerblend3 {
+	compatible = "fsl,imx8qxp-dc-layerblend";
+};
+
+&dc0_lis_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_pc {
+	compatible = "fsl,imx8qxp-pixel-combiner";
+};
+
+&dc0_pixel_combiner_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_pixel_engine {
+	compatible = "fsl,imx8qxp-dc-pixel-engine";
+};
+
+&dc0_pl_msi_bus {
+	compatible = "fsl,imx8qxp-display-pixel-link-msi-bus", "simple-pm-bus";
+};
+
+&dc0_tcon0 {
+	compatible = "fsl,imx8qxp-dc-tcon";
+};
+
+&dc0_tcon1 {
+	compatible = "fsl,imx8qxp-dc-tcon";
+};
+
+&scu {
+	dc0_pixel_link0: dc0-pixel-link0 {
+		compatible = "fsl,imx8qxp-dc-pixel-link";
+		fsl,dc-id = /bits/ 8 <0>;
+		fsl,dc-stream-id = /bits/ 8 <0>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* from dc0 pixel combiner channel0 */
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_link0_dc0_pixel_combiner_ch0: endpoint {
+					remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_pixel_link0>;
+				};
+			};
+
+			/* to PXL2DPIs in MIPI/LVDS combo subsystems */
+			port at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				status = "disabled";
+
+				dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint at 0 {
+					reg = <0>;
+				};
+
+				dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint at 1 {
+					reg = <1>;
+				};
+			};
+
+			/* unused */
+			port at 2 {
+				reg = <2>;
+				status = "disabled";
+			};
+
+			/* unused */
+			port at 3 {
+				reg = <3>;
+				status = "disabled";
+			};
+
+			/* to imaging subsystem */
+			port at 4 {
+				reg = <4>;
+				status = "disabled";
+			};
+		};
+	};
+
+	dc0_pixel_link1: dc0-pixel-link1 {
+		compatible = "fsl,imx8qxp-dc-pixel-link";
+		fsl,dc-id = /bits/ 8 <0>;
+		fsl,dc-stream-id = /bits/ 8 <1>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* from dc0 pixel combiner channel1 */
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_link1_dc0_pixel_combiner_ch1: endpoint {
+					remote-endpoint = <&dc0_pixel_combiner_ch1_dc0_pixel_link1>;
+				};
+			};
+
+			/* to PXL2DPIs in MIPI/LVDS combo subsystems */
+			port at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				status = "disabled";
+
+				dc0_pixel_link1_mipi_lvds_1_pxl2dpi: endpoint at 0 {
+					reg = <0>;
+				};
+
+				dc0_pixel_link1_mipi_lvds_0_pxl2dpi: endpoint at 1 {
+					reg = <1>;
+				};
+			};
+
+			/* to parallel display interface in ADMA subsystem */
+			port at 2 {
+				reg = <2>;
+				status = "disabled";
+			};
+
+			/* unused */
+			port at 3 {
+				reg = <3>;
+				status = "disabled";
+			};
+
+			/* unused */
+			port at 4 {
+				reg = <4>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 05138326f0a5..35cc82cbbcd1 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -20,6 +20,27 @@ / {
 	#size-cells = <2>;
 
 	aliases {
+		dc0 = &dc0;
+		dc0-constframe0 = &dc0_constframe0;
+		dc0-constframe1 = &dc0_constframe1;
+		dc0-constframe4 = &dc0_constframe4;
+		dc0-constframe5 = &dc0_constframe5;
+		dc0-display-engine0 = &dc0_display_engine0;
+		dc0-display-engine1 = &dc0_display_engine1;
+		dc0-extdst0 = &dc0_extdst0;
+		dc0-extdst1 = &dc0_extdst1;
+		dc0-extdst4 = &dc0_extdst4;
+		dc0-extdst5 = &dc0_extdst5;
+		dc0-fetchlayer0 = &dc0_fetchlayer0;
+		dc0-fetchwarp2 = &dc0_fetchwarp2;
+		dc0-framegen0 = &dc0_framegen0;
+		dc0-framegen1 = &dc0_framegen1;
+		dc0-layerblend0 = &dc0_layerblend0;
+		dc0-layerblend1 = &dc0_layerblend1;
+		dc0-layerblend2 = &dc0_layerblend2;
+		dc0-layerblend3 = &dc0_layerblend3;
+		dc0-tcon0 = &dc0_tcon0;
+		dc0-tcon1 = &dc0_tcon1;
 		ethernet0 = &fec1;
 		ethernet1 = &fec2;
 		gpio0 = &lsio_gpio0;
@@ -206,7 +227,7 @@ psci {
 		method = "smc";
 	};
 
-	system-controller {
+	scu: system-controller {
 		compatible = "fsl,imx-scu";
 		mbox-names = "tx0",
 			     "rx0",
@@ -323,6 +344,7 @@ map0 {
 	#include "imx8-ss-vpu.dtsi"
 	#include "imx8-ss-cm40.dtsi"
 	#include "imx8-ss-gpu0.dtsi"
+	#include "imx8-ss-dc0.dtsi"
 	#include "imx8-ss-adma.dtsi"
 	#include "imx8-ss-conn.dtsi"
 	#include "imx8-ss-ddr.dtsi"
@@ -332,6 +354,7 @@ map0 {
 
 #include "imx8qxp-ss-img.dtsi"
 #include "imx8qxp-ss-vpu.dtsi"
+#include "imx8qxp-ss-dc.dtsi"
 #include "imx8qxp-ss-adma.dtsi"
 #include "imx8qxp-ss-conn.dtsi"
 #include "imx8qxp-ss-lsio.dtsi"
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:21 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:21 +0800
Subject: [DO NOT MERGE PATCH v6 17/19] arm64: dts: imx8qxp: Add MIPI-LVDS combo subsystems
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-18-victor.liu@nxp.com>

The MIPI-LVDS combo subsystems are peripherals of pixel link MSI
bus in i.MX8qxp display controller subsystem.  Add the MIPI-LVDS
combo subsystems.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Francesco)

 .../boot/dts/freescale/imx8qxp-ss-dc.dtsi     |   4 +
 .../dts/freescale/imx8qxp-ss-mipi-lvds.dtsi   | 437 ++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   3 +
 3 files changed, 444 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
index 299720d8c99e..94c46a20597c 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
@@ -152,10 +152,12 @@ port at 1 {
 
 				dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint at 0 {
 					reg = <0>;
+					remote-endpoint = <&mipi_lvds_0_pxl2dpi_dc0_pixel_link0>;
 				};
 
 				dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint at 1 {
 					reg = <1>;
+					remote-endpoint = <&mipi_lvds_1_pxl2dpi_dc0_pixel_link0>;
 				};
 			};
 
@@ -207,10 +209,12 @@ port at 1 {
 
 				dc0_pixel_link1_mipi_lvds_1_pxl2dpi: endpoint at 0 {
 					reg = <0>;
+					remote-endpoint = <&mipi_lvds_1_pxl2dpi_dc0_pixel_link1>;
 				};
 
 				dc0_pixel_link1_mipi_lvds_0_pxl2dpi: endpoint at 1 {
 					reg = <1>;
+					remote-endpoint = <&mipi_lvds_0_pxl2dpi_dc0_pixel_link1>;
 				};
 			};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi
new file mode 100644
index 000000000000..fa7e7c33518e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi
@@ -0,0 +1,437 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/firmware/imx/rsrc.h>
+
+/ {
+	mipi_lvds_0_ipg_clk: clock-mipi-lvds0-ipg {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <120000000>;
+		clock-output-names = "mipi_lvds_0_ipg_clk";
+	};
+
+	mipi_lvds_1_ipg_clk: clock-mipi-lvds1-ipg {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <120000000>;
+		clock-output-names = "mipi_lvds_1_ipg_clk";
+	};
+};
+
+&dc0_pl_msi_bus {
+	mipi_lvds_0_irqsteer: interrupt-controller at 56220000 {
+		compatible = "fsl,imx-irqsteer";
+		reg = <0x56220000 0x1000>;
+		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		#interrupt-cells = <1>;
+		clocks = <&mipi_lvds_0_lis_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+		fsl,channel = <0>;
+		fsl,num-irqs = <32>;
+	};
+
+	mipi_lvds_0_csr: syscon at 56221000 {
+		compatible = "fsl,imx8qxp-mipi-lvds-csr", "syscon", "simple-mfd";
+		reg = <0x56221000 0x1000>;
+		clocks = <&mipi_lvds_0_di_mipi_lvds_regs_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+
+		mipi_lvds_0_pxl2dpi: pxl2dpi {
+			compatible = "fsl,imx8qxp-pxl2dpi";
+			fsl,sc-resource = <IMX_SC_R_MIPI_0>;
+			power-domains = <&pd IMX_SC_R_MIPI_0>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					mipi_lvds_0_pxl2dpi_dc0_pixel_link0: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&dc0_pixel_link0_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_0_pxl2dpi_dc0_pixel_link1: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&dc0_pixel_link1_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+
+				port at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+			};
+		};
+
+		mipi_lvds_0_ldb: ldb {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,imx8qxp-ldb";
+			clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>,
+				 <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+			clock-names = "pixel", "bypass";
+			assigned-clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>;
+			assigned-clock-parents = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+			power-domains = <&pd IMX_SC_R_LVDS_0>;
+			status = "disabled";
+
+			channel at 0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				phys = <&mipi_lvds_0_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0>;
+					};
+				};
+			};
+
+			channel at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				phys = <&mipi_lvds_0_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1>;
+					};
+				};
+			};
+		};
+	};
+
+	mipi_lvds_0_lis_lpcg: clock-controller at 56223000 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56223000 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_0_lis_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0>;
+	};
+
+	mipi_lvds_0_di_mipi_lvds_regs_lpcg: clock-controller at 56223004 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56223004 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_0_di_mipi_lvds_regs_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0>;
+	};
+
+	mipi_lvds_0_pwm_lpcg: clock-controller at 5622300c {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x5622300c 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_0_PWM_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_0_ipg_clk>,
+			 <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>,
+				<IMX_LPCG_CLK_1>;
+		clock-output-names = "mipi_lvds_0_pwm_lpcg_clk",
+				     "mipi_lvds_0_pwm_lpcg_ipg_clk",
+				     "mipi_lvds_0_pwm_lpcg_32k_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0_PWM_0>;
+	};
+
+	mipi_lvds_0_i2c0_lpcg: clock-controller at 56223010 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56223010 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_0_I2C_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_0_i2c0_lpcg_clk",
+				     "mipi_lvds_0_i2c0_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0_I2C_0>;
+	};
+
+	mipi_lvds_0_pwm: pwm at 56224000 {
+		compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
+		reg = <0x56224000 0x1000>;
+		interrupt-parent = <&mipi_lvds_0_irqsteer>;
+		interrupts = <12>;
+		clocks = <&mipi_lvds_0_pwm_lpcg IMX_LPCG_CLK_4>,
+			 <&mipi_lvds_0_pwm_lpcg IMX_LPCG_CLK_0>;
+		clock-names = "ipg", "per";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_0_PWM_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		#pwm-cells = <3>;
+		power-domains = <&pd IMX_SC_R_MIPI_0_PWM_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_0_i2c0: i2c at 56226000 {
+		compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x56226000 0x1000>;
+		interrupt-parent = <&mipi_lvds_0_irqsteer>;
+		interrupts = <8>;
+		clocks = <&mipi_lvds_0_i2c0_lpcg IMX_LPCG_CLK_0>,
+			 <&mipi_lvds_0_i2c0_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_0_I2C_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd IMX_SC_R_MIPI_0_I2C_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_0_phy: phy at 56228300 {
+		compatible = "fsl,imx8qxp-mipi-dphy";
+		reg = <0x56228300 0x100>;
+		clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_PHY>;
+		clock-names = "phy_ref";
+		assigned-clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_PHY>;
+		assigned-clock-parents = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+		#phy-cells = <0>;
+		fsl,syscon = <&mipi_lvds_0_csr>;
+		power-domains = <&pd IMX_SC_R_MIPI_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_1_irqsteer: interrupt-controller at 56240000 {
+		compatible = "fsl,imx-irqsteer";
+		reg = <0x56240000 0x1000>;
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		#interrupt-cells = <1>;
+		clocks = <&mipi_lvds_1_lis_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+		fsl,channel = <0>;
+		fsl,num-irqs = <32>;
+	};
+
+	mipi_lvds_1_csr: syscon at 56241000 {
+		compatible = "fsl,imx8qxp-mipi-lvds-csr", "syscon", "simple-mfd";
+		reg = <0x56241000 0x1000>;
+		clocks = <&mipi_lvds_1_di_mipi_lvds_regs_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+
+		mipi_lvds_1_pxl2dpi: pxl2dpi {
+			compatible = "fsl,imx8qxp-pxl2dpi";
+			fsl,sc-resource = <IMX_SC_R_MIPI_1>;
+			power-domains = <&pd IMX_SC_R_MIPI_1>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					mipi_lvds_1_pxl2dpi_dc0_pixel_link1: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&dc0_pixel_link1_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_1_pxl2dpi_dc0_pixel_link0: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&dc0_pixel_link0_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+
+				port at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch0: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&mipi_lvds_1_ldb_ch0_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch1: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&mipi_lvds_1_ldb_ch1_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+			};
+		};
+
+		mipi_lvds_1_ldb: ldb {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,imx8qxp-ldb";
+			clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_MISC2>,
+				 <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_BYPASS>;
+			clock-names = "pixel", "bypass";
+			assigned-clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_MISC2>;
+			assigned-clock-parents = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_BYPASS>;
+			power-domains = <&pd IMX_SC_R_LVDS_1>;
+			status = "disabled";
+
+			channel at 0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				phys = <&mipi_lvds_1_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_1_ldb_ch0_mipi_lvds_1_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch0>;
+					};
+				};
+			};
+
+			channel at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				phys = <&mipi_lvds_1_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_1_ldb_ch1_mipi_lvds_1_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch1>;
+					};
+				};
+			};
+		};
+	};
+
+	mipi_lvds_1_lis_lpcg: clock-controller at 56243000 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56243000 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_1_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_1_lis_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_1>;
+	};
+
+	mipi_lvds_1_di_mipi_lvds_regs_lpcg: clock-controller at 56243004 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56243004 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_1_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_1_di_mipi_lvds_regs_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_1>;
+	};
+
+	mipi_lvds_1_pwm_lpcg: clock-controller at 5624300c {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x5624300c 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_1_PWM_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_1_ipg_clk>,
+			 <&mipi_lvds_1_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>,
+				<IMX_LPCG_CLK_1>;
+		clock-output-names = "mipi_lvds_1_pwm_lpcg_clk",
+				     "mipi_lvds_1_pwm_lpcg_ipg_clk",
+				     "mipi_lvds_1_pwm_lpcg_32k_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_1_PWM_0>;
+	};
+
+	mipi_lvds_1_i2c0_lpcg: clock-controller at 56243010 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56243010 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_1_I2C_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_1_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_1_i2c0_lpcg_clk",
+				     "mipi_lvds_1_i2c0_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_1_I2C_0>;
+	};
+
+	mipi_lvds_1_pwm: pwm at 56244000 {
+		compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
+		reg = <0x56244000 0x1000>;
+		interrupt-parent = <&mipi_lvds_1_irqsteer>;
+		interrupts = <12>;
+		clocks = <&mipi_lvds_1_pwm_lpcg IMX_LPCG_CLK_4>,
+			 <&mipi_lvds_1_pwm_lpcg IMX_LPCG_CLK_0>;
+		clock-names = "ipg", "per";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_1_PWM_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		#pwm-cells = <3>;
+		power-domains = <&pd IMX_SC_R_MIPI_1_PWM_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_1_i2c0: i2c at 56246000 {
+		compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x56246000 0x1000>;
+		interrupt-parent = <&mipi_lvds_1_irqsteer>;
+		interrupts = <8>;
+		clocks = <&mipi_lvds_1_i2c0_lpcg IMX_LPCG_CLK_0>,
+			 <&mipi_lvds_1_i2c0_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_1_I2C_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd IMX_SC_R_MIPI_1_I2C_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_1_phy: phy at 56248300 {
+		compatible = "fsl,imx8qxp-mipi-dphy";
+		reg = <0x56248300 0x100>;
+		clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_PHY>;
+		clock-names = "phy_ref";
+		assigned-clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_PHY>;
+		assigned-clock-parents = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_BYPASS>;
+		#phy-cells = <0>;
+		fsl,syscon = <&mipi_lvds_1_csr>;
+		power-domains = <&pd IMX_SC_R_MIPI_1>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 35cc82cbbcd1..25adc1090dec 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -55,6 +55,8 @@ aliases {
 		i2c1 = &i2c1;
 		i2c2 = &i2c2;
 		i2c3 = &i2c3;
+		mipi-dphy0 = &mipi_lvds_0_phy;
+		mipi-dphy1 = &mipi_lvds_1_phy;
 		mmc0 = &usdhc1;
 		mmc1 = &usdhc2;
 		mmc2 = &usdhc3;
@@ -355,6 +357,7 @@ map0 {
 #include "imx8qxp-ss-img.dtsi"
 #include "imx8qxp-ss-vpu.dtsi"
 #include "imx8qxp-ss-dc.dtsi"
+#include "imx8qxp-ss-mipi-lvds.dtsi"
 #include "imx8qxp-ss-adma.dtsi"
 #include "imx8qxp-ss-conn.dtsi"
 #include "imx8qxp-ss-lsio.dtsi"
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:22 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:22 +0800
Subject: [DO NOT MERGE PATCH v6 18/19] arm64: dts: imx8qxp-mek: Enable display controller
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-19-victor.liu@nxp.com>

Enable display controller for i.MX8qxp MEK.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Francesco)

 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index be79c793213a..c7b4015c7bf7 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -234,6 +234,10 @@ &asrc0 {
 	status = "okay";
 };
 
+&dc0 {
+	status = "okay";
+};
+
 &dsp {
 	memory-region = <&dsp_vdev0buffer>, <&dsp_vdev0vring0>,
 			<&dsp_vdev0vring1>, <&dsp_reserved>;
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:04 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:04 +0800
Subject: [PATCH v6 00/19] Add Freescale i.MX8qxp Display Controller support
Message-ID: <20241209033923.3009629-1-victor.liu@nxp.com>

Hi,

This patch series aims to add Freescale i.MX8qxp Display Controller support.

The controller is comprised of three main components that include a blit
engine for 2D graphics accelerations, display controller for display output
processing, as well as a command sequencer.

Previous patch series attempts to do that can be found at:
https://patchwork.freedesktop.org/series/84524/

This series addresses Maxime's comments on the previous one:
a. Split the display controller into multiple internal devices.
   1) List display engine, pixel engine, interrupt controller and more as the
      controller's child devices.
   2) List display engine and pixel engine's processing units as their child
      devices.

b. Add minimal feature support.
   Only support two display pipelines with primary planes with XR24 fb,
   backed by two fetchunits.  No fetchunit dynamic allocation logic(to be done
   when necessary).

c. Use drm_dev_{enter, exit}().

Since this series changes a lot comparing to the previous one, I choose to
send it with a new patch series, not a new version.

To follow up i.MX8qxp TRM, I changed the controller name to "Display Controller"
instead of the previous "DPU".  "DPU" is only mentioned in the SoC block
diagram and represents the whole display subsystem which includes the display
controller and prefech engines, etc.

With an additional patch[1] for simple-pm-bus.c, this series facilitates
testing a LVDS panel on i.MX8qxp MEK.

Please do NOT merge patch 14-19.  They are only used to facilitate testing
the LVDS panel.

[1] https://lkml.org/lkml/2023/1/25/120

v6:
* Fix build warning by expanding sizeof(fu->name) from 13 to 21 in patch 10.
  (kernel test robot)

v5:
* Document display controller device's and some display controller internal
  devices' aliases in DT bindings. Hence, drop collected R-b tags from some
  patches for DT bindings. (Maxime)
* Replace .remove_new with .remove in all drivers. (Uwe)
* Select REGMAP and REGMAP_MMIO options in patch 9.
* Fix patch 9 & 10's commit message to state that display engine driver and
  pixel engine driver are component drivers instead of master/aggregate drivers.

v4:
* Collect Rob's R-b tags on DT binding patches(patch 1-5).
* Replace "fsl,iram" property with standard "sram" property in
  fsl,imx8qxp-dc-command-sequencer.yaml in patch 6. (Rob)
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Inline some small functions. (Dmitry)
* Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
  function calls from KMS routine to initialization stage. (Dmitry)
* Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
  appropriate .h header files or .c source files. (Dmitry)
* Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
* Drop dc_drm->pe_rpm_count. (Dmitry)
* Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
* Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
  Instead, put it in struct dc_crtc.  (Dmitry)
* Call devm_request_irq() to request IRQs, instead of using drmm action.
  (Dmitry)
* Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
* Select DRM_CLIENT_SELECTION due to rebase.
* Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
* Drop unnecessary private struct dc_*_priv from DC internal device drivers.
* Set suppress_bind_attrs driver flag to true in DC internal device drivers
  to avoid unnecessary sys interfaces to bind/unbind the drivers.
* Make some fetch unit operations be aware of fractional fetch unit index(0-7).
* Take DC interrupt controller driver as a standalone driver instead of a
  component driver.
* Replace drmm_kcalloc() with devm_kcalloc() to allocate an array for
  struct dc_ic_entry.
* Call platform_get_irq() from DC interrupt controller driver to make sure
  parent interrupt controller driver is probed first.
* Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
* Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
  rebase.
* Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
  register dc_drm_component_unbind_all() action.
* Request interrupts in dc_crtc_post_init() after encoder initialization to
  make sure next bridge is found first.
* Trivial tweaks.

v3:
* Collect Rob's R-b tag on the patch for adding fsl,imx8qxp-dc-intc.yaml.
* Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
  fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
  into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
* Document all processing units, command sequencer, axi performance counter
  and blit engine. (Rob)

v2:
* Drop fsl,dc-*-id DT properties from fsl,imx8qxp-dc*.yaml. (Krzysztof)
* Move port property from fsl,imx8qxp-dc-display-engine.yaml to
  fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
* Drop unneeded "|" from fsl,imx8qxp-dc-intc.yaml. (Krzysztof)
* Use generic pmu pattern property in fsl,imx8qxp-dc.yaml. (Krzysztof)
* Fix register range size in fsl,imx8qxp-dc*.yaml.
* Use OF alias id to get instance id from display driver.
* Find next bridge from TCon's port from display driver.
* Drop drm/drm_module.h include from dc-drv.c.
* Improve file list in MAINTAINERS. (Frank)
* Add entire i.MX8qxp display controller device tree for review. (Krzysztof)
* Add MIPI/LVDS subsystems device tree and a DT overlay for imx8qxp
  MEK to test a LVDS panel as an example. (Francesco)

Liu Ying (19):
  dt-bindings: display: imx: Add i.MX8qxp Display Controller processing
    units
  dt-bindings: display: imx: Add i.MX8qxp Display Controller blit engine
  dt-bindings: display: imx: Add i.MX8qxp Display Controller display
    engine
  dt-bindings: display: imx: Add i.MX8qxp Display Controller pixel
    engine
  dt-bindings: display: imx: Add i.MX8qxp Display Controller AXI
    performance counter
  dt-bindings: display: imx: Add i.MX8qxp Display Controller command
    sequencer
  dt-bindings: interrupt-controller: Add i.MX8qxp Display Controller
    interrupt controller
  dt-bindings: display: imx: Add i.MX8qxp Display Controller
  drm/imx: Add i.MX8qxp Display Controller display engine
  drm/imx: Add i.MX8qxp Display Controller pixel engine
  drm/imx: Add i.MX8qxp Display Controller interrupt controller
  drm/imx: Add i.MX8qxp Display Controller KMS
  MAINTAINERS: Add maintainer for i.MX8qxp Display Controller
  dt-bindings: phy: mixel, mipi-dsi-phy: Allow assigned-clock*
    properties
  dt-bindings: firmware: imx: Add SCU controlled display pixel link
    nodes
  arm64: dts: imx8qxp: Add display controller subsystem
  arm64: dts: imx8qxp: Add MIPI-LVDS combo subsystems
  arm64: dts: imx8qxp-mek: Enable display controller
  arm64: dts: imx8qxp-mek: Add MX8-DLVDS-LCD1 display module support

 ...sl,imx8qxp-dc-axi-performance-counter.yaml |  57 ++
 .../imx/fsl,imx8qxp-dc-blit-engine.yaml       | 204 +++++++
 .../display/imx/fsl,imx8qxp-dc-blitblend.yaml |  46 ++
 .../display/imx/fsl,imx8qxp-dc-clut.yaml      |  49 ++
 .../imx/fsl,imx8qxp-dc-command-sequencer.yaml |  67 +++
 .../imx/fsl,imx8qxp-dc-constframe.yaml        |  49 ++
 .../imx/fsl,imx8qxp-dc-display-engine.yaml    | 157 +++++
 .../display/imx/fsl,imx8qxp-dc-dither.yaml    |  49 ++
 .../display/imx/fsl,imx8qxp-dc-extdst.yaml    |  77 +++
 .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 +++++
 .../display/imx/fsl,imx8qxp-dc-filter.yaml    |  47 ++
 .../display/imx/fsl,imx8qxp-dc-framegen.yaml  |  68 +++
 .../display/imx/fsl,imx8qxp-dc-gammacor.yaml  |  38 ++
 .../imx/fsl,imx8qxp-dc-layerblend.yaml        |  45 ++
 .../display/imx/fsl,imx8qxp-dc-matrix.yaml    |  48 ++
 .../imx/fsl,imx8qxp-dc-pixel-engine.yaml      | 250 ++++++++
 .../display/imx/fsl,imx8qxp-dc-rop.yaml       |  48 ++
 .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++
 .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  89 +++
 .../display/imx/fsl,imx8qxp-dc-signature.yaml |  58 ++
 .../display/imx/fsl,imx8qxp-dc-store.yaml     | 100 ++++
 .../display/imx/fsl,imx8qxp-dc-tcon.yaml      |  50 ++
 .../bindings/display/imx/fsl,imx8qxp-dc.yaml  | 240 ++++++++
 .../devicetree/bindings/firmware/fsl,scu.yaml |  20 +
 .../fsl,imx8qxp-dc-intc.yaml                  | 318 ++++++++++
 .../bindings/phy/mixel,mipi-dsi-phy.yaml      |   5 -
 MAINTAINERS                                   |   8 +
 arch/arm64/boot/dts/freescale/Makefile        |   4 +
 .../arm64/boot/dts/freescale/imx8-ss-dc0.dtsi | 408 +++++++++++++
 .../imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso | 183 ++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |  34 ++
 .../boot/dts/freescale/imx8qxp-ss-dc.dtsi     | 240 ++++++++
 .../dts/freescale/imx8qxp-ss-mipi-lvds.dtsi   | 437 ++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |  28 +-
 drivers/gpu/drm/imx/Kconfig                   |   1 +
 drivers/gpu/drm/imx/Makefile                  |   1 +
 drivers/gpu/drm/imx/dc/Kconfig                |  13 +
 drivers/gpu/drm/imx/dc/Makefile               |   7 +
 drivers/gpu/drm/imx/dc/dc-cf.c                | 162 +++++
 drivers/gpu/drm/imx/dc/dc-crtc.c              | 558 ++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-de.c                | 153 +++++
 drivers/gpu/drm/imx/dc/dc-de.h                |  60 ++
 drivers/gpu/drm/imx/dc/dc-drv.c               | 283 +++++++++
 drivers/gpu/drm/imx/dc/dc-drv.h               |  52 ++
 drivers/gpu/drm/imx/dc/dc-ed.c                | 270 +++++++++
 drivers/gpu/drm/imx/dc/dc-fg.c                | 374 ++++++++++++
 drivers/gpu/drm/imx/dc/dc-fl.c                | 180 ++++++
 drivers/gpu/drm/imx/dc/dc-fu.c                | 268 +++++++++
 drivers/gpu/drm/imx/dc/dc-fu.h                | 129 ++++
 drivers/gpu/drm/imx/dc/dc-fw.c                | 219 +++++++
 drivers/gpu/drm/imx/dc/dc-ic.c                | 279 +++++++++
 drivers/gpu/drm/imx/dc/dc-kms.c               | 143 +++++
 drivers/gpu/drm/imx/dc/dc-kms.h               |  58 ++
 drivers/gpu/drm/imx/dc/dc-lb.c                | 319 ++++++++++
 drivers/gpu/drm/imx/dc/dc-pe.c                | 133 +++++
 drivers/gpu/drm/imx/dc/dc-pe.h                | 100 ++++
 drivers/gpu/drm/imx/dc/dc-plane.c             | 241 ++++++++
 drivers/gpu/drm/imx/dc/dc-tc.c                | 138 +++++
 58 files changed, 7837 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi
 create mode 100644 drivers/gpu/drm/imx/dc/Kconfig
 create mode 100644 drivers/gpu/drm/imx/dc/Makefile
 create mode 100644 drivers/gpu/drm/imx/dc/dc-cf.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ed.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fg.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fl.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fw.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ic.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-lb.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-tc.c

-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:05 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:05 +0800
Subject: [PATCH v6 01/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller processing units
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-2-victor.liu@nxp.com>

Freescale i.MX8qxp Display Controller is implemented as construction set of
building blocks with unified concept and standardized interfaces.  Document
all existing processing units.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* Document aliases for processing units which have multiple instances in
  the Display Controller.  Drop Rob's previous R-b tag. (Maxime)

v4:
* Collect Rob's R-b tag.

v3:
* Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
  fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
  into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
* Document all processing units. (Rob)

v2:
* Drop fsl,dc-*-id DT properties. (Krzysztof)
* Add port property to fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
* Fix register range sizes in examples.

 .../display/imx/fsl,imx8qxp-dc-blitblend.yaml |  46 ++++++
 .../display/imx/fsl,imx8qxp-dc-clut.yaml      |  49 ++++++
 .../imx/fsl,imx8qxp-dc-constframe.yaml        |  49 ++++++
 .../display/imx/fsl,imx8qxp-dc-dither.yaml    |  49 ++++++
 .../display/imx/fsl,imx8qxp-dc-extdst.yaml    |  77 +++++++++
 .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 ++++++++++++++++++
 .../display/imx/fsl,imx8qxp-dc-filter.yaml    |  47 ++++++
 .../display/imx/fsl,imx8qxp-dc-framegen.yaml  |  68 ++++++++
 .../display/imx/fsl,imx8qxp-dc-gammacor.yaml  |  38 +++++
 .../imx/fsl,imx8qxp-dc-layerblend.yaml        |  45 ++++++
 .../display/imx/fsl,imx8qxp-dc-matrix.yaml    |  48 ++++++
 .../display/imx/fsl,imx8qxp-dc-rop.yaml       |  48 ++++++
 .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++++
 .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  89 +++++++++++
 .../display/imx/fsl,imx8qxp-dc-signature.yaml |  58 +++++++
 .../display/imx/fsl,imx8qxp-dc-store.yaml     | 100 ++++++++++++
 .../display/imx/fsl,imx8qxp-dc-tcon.yaml      |  50 ++++++
 17 files changed, 1042 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
new file mode 100644
index 000000000000..7f800e72c3f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blitblend.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Blit Blend Unit
+
+description: |
+  Combines two input frames to a single output frame, all frames having the
+  same dimension.
+
+  Each Blit Blend Unit device should have an alias in the aliases node, in the
+  form of dc<x>-blitblend<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Blit Blend Unit
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-blitblend
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    blitblend at 56180920 {
+        compatible = "fsl,imx8qxp-dc-blitblend";
+        reg = <0x56180920 0x10>, <0x56183c00 0x3c>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
new file mode 100644
index 000000000000..351692d8942e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-clut.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Color Lookup Table
+
+description: |
+  The unit implements 3 look-up tables with 256 x 10 bit entries each. These
+  can be used for different kinds of applications. From 10-bit input values
+  only upper 8 bits are used.
+
+  The unit supports color lookup, index lookup, dithering and alpha masking.
+
+  Each Color Lookup Table device should have an alias in the aliases node, in
+  the form of dc<x>-clut<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Color Lookup Table
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-clut
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    clut at 56180880 {
+        compatible = "fsl,imx8qxp-dc-clut";
+        reg = <0x56180880 0x10>, <0x56182400 0x404>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
new file mode 100644
index 000000000000..cae19bc05d6e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-constframe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Constant Frame
+
+description: |
+  The Constant Frame unit is used instead of a Fetch unit where generation of
+  constant color frames only is sufficient. This is the case for the background
+  planes of content and safety streams in a Display Controller.
+
+  The color can be setup to any RGBA value.
+
+  Each Constant Frame device should have an alias in the aliases node, in the
+  form of dc<x>-constframe<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Constant Frame device
+  instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-constframe
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    constframe at 56180960 {
+        compatible = "fsl,imx8qxp-dc-constframe";
+        reg = <0x56180960 0xc>, <0x56184400 0x20>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
new file mode 100644
index 000000000000..cb0b4a05cfdc
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-dither.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Dither Unit
+
+description: |
+  The unit can increase the physical color resolution of a display from 5, 6, 7
+  or 8 bits per RGB channel to a virtual resolution of 10 bits. The physical
+  resolution can be set individually for each channel.
+
+  The resolution is increased by mixing the two physical colors that are nearest
+  to the virtual color code in a variable ratio either by time (temporal
+  dithering) or by position (spatial dithering).
+
+  An optimized algorithm for temporal dithering minimizes noise artifacts on the
+  output image.
+
+  The dither operation can be individually enabled or disabled for each pixel
+  using the alpha input bit.
+
+  Each Dither Unit device should have an alias in the aliases node, in the form
+  of dc<x>-dither<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the Dither Unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-dither
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    dither at 5618c400 {
+        compatible = "fsl,imx8qxp-dc-dither";
+        reg = <0x5618c400 0x14>;
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
new file mode 100644
index 000000000000..b382af1de1c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-extdst.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller External Destination Interface
+
+description: |
+  The External Destination unit is the interface between the internal pixel
+  processing pipeline of the Pixel Engine, which is 30-bit RGB plus 8-bit Alpha,
+  and a Display Engine.
+
+  It comprises the following built-in Gamma apply function.
+
+  +------X-----------------------+
+  |      |          ExtDst Unit  |
+  |      V                       |
+  |  +-------+                   |
+  |  | Gamma |                   |
+  |  +-------+                   |
+  |      |                       |
+  |      V                       +
+  +------X-----------------------+
+
+  The output format is 24-bit RGB plus 1-bit Alpha. Conversion from 10 to 8
+  bits is done by LSBit truncation.  Alpha output bit is 1 for input 255, 0
+  otherwise.
+
+  Each External Destination unit device should have an alias in the aliases
+  node, in the form of dc<x>-blitblend<y>, where <x> is an integer specifying
+  the Display Controller instance and <y> is an integer specifying the External
+  Destination unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-extdst
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: framecomplete
+      - const: seqcomplete
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    extdst at 56180980 {
+        compatible = "fsl,imx8qxp-dc-extdst";
+        reg = <0x56180980 0x1c>, <0x56184800 0x28>;
+        reg-names = "pec", "cfg";
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <3>, <4>, <5>;
+        interrupt-names = "shdload", "framecomplete", "seqcomplete";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
new file mode 100644
index 000000000000..2141e692bc02
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-fetchunit.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Fetch Unit
+
+description: |
+  The Fetch Unit is the interface between the AXI bus for source buffer access
+  and the internal pixel processing pipeline, which is 30-bit RGB plus 8-bit
+  Alpha.
+
+  It is used to generate foreground planes in Display Controllers and source
+  planes in Blit Engines, and comprises the following built-in functions to
+  convert a wide range of frame buffer types.
+
+  +---------X-----------------------------------------+
+  |         |                           Fetch Unit    |
+  |         V                                         |
+  |    +---------+                                    |
+  |    |         |                                    |
+  |    | Decode  | Decompression [Decode]             |
+  |    |         |                                    |
+  |    +---------+                                    |
+  |         |                                         |
+  |         V                                         |
+  |    +---------+                                    |
+  |    | Clip &  | Clip Window [All]                  |
+  |    | Overlay | Plane composition [Layer, Warp]    |
+  |    |         |                                    |
+  |    +---------+                                    |
+  |         |                                         |
+  |         V                                         |
+  |    +---------+                                    |
+  |    | Re-     | Flip/Rotate/Repl./Drop [All]       |
+  X--> | sample  | Perspective/Affine warping [Persp] |
+  | |  |         | Arbitrary warping [Warp, Persp]    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         |                                    |
+  | |  | Palette | Color Palette [Layer, Decode]      |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  | Extract | Raw to RGBA/YUV [All]              |
+  | |  | &       | Bit width expansion [All]          |
+  | |  | Expand  |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | Planar to packed                   |
+  | |->| Combine | [Decode, Warp, Persp]              |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | YUV422 to YUV444                   |
+  | |  | Chroma  | [Decode, Persp]                    |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | YUV to RGB                         |
+  | |  | Color   | [Warp, Persp, Decode, Layer]       |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | Gamma removal                      |
+  | |  | Gamma   | [Warp, Persp, Decode, Layer]       |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | Alpla multiply, RGB pre-multiply   |
+  |  ->| Multiply| [Warp, Persp, Decode, Layer]       |
+  |    |         |                                    |
+  |     ---------                                     |
+  |         |                                         |
+  |         V                                         |
+  |    +---------+                                    |
+  |    |         | Bilinear filter                    |
+  |    | Filter  | [Warp, Persp]                      |
+  |    |         |                                    |
+  |    +---------+                                    |
+  |         |                                         |
+  |         V                                         |
+  +---------X-----------------------------------------+
+
+  Note that different derivatives of the Fetch Unit exist. Each implements a
+  specific subset only of the pipeline stages shown above. Restrictions for the
+  units are specified in [square brackets].
+
+  Each Fetch Unit device should have an alias in the aliases node, in the form
+  of dc<x>-fetch<y><z>, where <x> is an integer specifying the Display
+  Controller instance, <y> specifies different derivative names(decode, eco,
+  layer and warp) and <z> is an integer specifying the Fetch Unit device
+  instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-fetchdecode
+      - fsl,imx8qxp-dc-fetcheco
+      - fsl,imx8qxp-dc-fetchlayer
+      - fsl,imx8qxp-dc-fetchwarp
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  fsl,prg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Optional Prefetch Resolve Gasket associated with the Fetch Unit.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    fetchlayer at 56180ac0 {
+        compatible = "fsl,imx8qxp-dc-fetchlayer";
+        reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
new file mode 100644
index 000000000000..e1bdcdd893b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-filter.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Filter Unit
+
+description: |
+  5x5 FIR filter with 25 programmable coefficients.
+
+  Typical applications are image blurring, sharpening or support for edge
+  detection algorithms.
+
+  Each Filter Unit device should have an alias in the aliases node, in the form
+  of dc<x>-filter<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the Filter Unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-filter
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    filter at 56180900 {
+        compatible = "fsl,imx8qxp-dc-filter";
+        reg = <0x56180900 0x10>, <0x56183800 0x30>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
new file mode 100644
index 000000000000..d784f6e59312
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-framegen.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Frame Generator
+
+description: |
+  The Frame Generator (FrameGen) module generates a programmable video timing
+  and optionally allows to synchronize the generated video timing to external
+  synchronization signals.
+
+  Each FrameGen device should have an alias in the aliases node, in the form of
+  dc<x>-framegen<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the FrameGen device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-framegen
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 8
+
+  interrupt-names:
+    items:
+      - const: int0
+      - const: int1
+      - const: int2
+      - const: int3
+      - const: primsync_on
+      - const: primsync_off
+      - const: secsync_on
+      - const: secsync_off
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    framegen at 5618b800 {
+        compatible = "fsl,imx8qxp-dc-framegen";
+        reg = <0x5618b800 0x98>;
+        clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <18>, <19>, <20>, <21>, <41>, <42>, <43>, <44>;
+        interrupt-names = "int0", "int1", "int2", "int3",
+                          "primsync_on", "primsync_off",
+                          "secsync_on", "secsync_off";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
new file mode 100644
index 000000000000..895501566210
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-gammacor.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Gamma Correction Unit
+
+description: |
+  The unit supports non-linear color transformation.
+
+  Each Gamma Correction Unit device should have an alias in the aliases node,
+  in the form of dc<x>-gammacor<y>, where <x> is an integer specifying the
+  Display Controller instance and <y> is an integer specifying the Gamma
+  Correction Unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-gammacor
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    gammacor at 5618c000 {
+        compatible = "fsl,imx8qxp-dc-gammacor";
+        reg = <0x5618c000 0x20>;
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
new file mode 100644
index 000000000000..50c0c1dacb41
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-layerblend.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Layer Blend Unit
+
+description: |
+  Combines two input frames to a single output frame.
+
+  Each Layer Blend Unit device should have an alias in the aliases node, in the
+  form of dc<x>-layerblend<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Layer Blend Unit
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-layerblend
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    layerblend at 56180ba0 {
+        compatible = "fsl,imx8qxp-dc-layerblend";
+        reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
new file mode 100644
index 000000000000..8778526e1eb8
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-matrix.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Color Matrix
+
+description: |
+  The unit supports linear color transformation, alpha pre-multiply and
+  alpha masking.
+
+  Each Color Matrix device should have an alias in the aliases node, in the form
+  of dc<x>-matrix<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the Color Matrix device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-matrix
+
+  reg:
+    minItems: 1
+    maxItems: 2
+
+  reg-names:
+    oneOf:
+      - const: cfg      # matrix in display engine
+      - items:          # matrix in pixel engine
+          - const: pec
+          - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    matrix at 5618bc00 {
+        compatible = "fsl,imx8qxp-dc-matrix";
+        reg = <0x5618bc00 0x3c>;
+        reg-names = "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
new file mode 100644
index 000000000000..a724cf960250
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-rop.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Raster Operation Unit
+
+description: |
+  The unit can combine up to three input frames to a single output frame, all
+  having the same dimension.
+
+  The unit supports logic operations, arithmetic operations and packing.
+
+  Each Raster Operation Unit device should have an alias in the aliases node,
+  in the form of dc<x>-rop<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Raster Operation Unit
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-rop
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    rop at 56180860 {
+        compatible = "fsl,imx8qxp-dc-rop";
+        reg = <0x56180860 0x10>, <0x56182000 0x20>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
new file mode 100644
index 000000000000..66c12948ab09
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-safety.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Safety Unit
+
+description:
+  The unit allows corresponding processing units to be configured in a path
+  leading to multiple endpoints.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-safety
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    safety at 56180800 {
+        compatible = "fsl,imx8qxp-dc-safety";
+        reg = <0x56180800 0x1c>;
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
new file mode 100644
index 000000000000..a1d6673f2a05
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Scaling Engine
+
+description: |
+  The unit can change the dimension of the input frame by nearest or linear
+  re-sampling with 1/32 sub pixel precision.
+
+  Internally it consist of two independent blocks for horizontal and vertical
+  scaling. The sequence of both operations is arbitrary.
+
+  Any frame dimensions between 1 and 16384 pixels in width and height are
+  supported, except that the vertical scaler has a frame width maximum
+  depending of the system's functional limitations.
+
+  In general all scale factors are supported inside the supported frame
+  dimensions. In range of scale factors 1/16..16 the filtered output colors
+  are LSBit precise (e.g. DC ripple free).
+
+                       +-----------+
+                       |   Line    |
+                       |  Buffer   |
+                       +-----------+
+                             ^
+                             |
+                             V
+                 |\    +-----------+
+           ------+ |   |           |
+          |      | +-->| Vertical  |----
+          |  ----+ |   |  Scaler   |    |
+          | |    |/    +-----------+    |
+          | |                           |
+          | |                           |
+          | |                           |     |\
+          |  ------------- -------------+-----+ |
+  Input --+               X                   | +--> Output
+          |  ------------- -------------+-----+ |
+          | |                           |     |/
+          | |                           |
+          | |    |\    +-----------+    |
+          |  ----+ |   |           |    |
+          |      | +-->| Horizontal|----
+           ------+ |   |  Scaler   |
+                 |/    +-----------+
+
+  The unit supports downscaling, upscaling, sub pixel translation and bob
+  de-interlacing.
+
+  Each Scaling Engine device should have an alias in the aliases node, in the
+  form of dc<x>-<y>scaler<z>, where <x> is an integer specifying the Display
+  Controller instance, <y> specifies scaling type(either "h" for horizontal
+  scaler or "v" for vertical scaler) and <z> is an integer specifying the
+  Scaling Engine device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-hscaler
+      - fsl,imx8qxp-dc-vscaler
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    hscaler at 561808c0 {
+        compatible = "fsl,imx8qxp-dc-hscaler";
+        reg = <0x561808c0 0x10>, <0x56183000 0x18>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
new file mode 100644
index 000000000000..5403e3359fcb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-signature.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Signature Unit
+
+description: |
+  In order to control the correctness of display output, signature values can
+  be computed for each frame and compared against reference values. In case of
+  a mismatch (signature violation) a HW event can be triggered, for example a
+  SW interrupt.
+
+  This unit supports signature computation, reference check, evaluation windows,
+  alpha masking and panic modes.
+
+  Each Signature Unit device should have an alias in the aliases node, in the
+  form of dc<x>-signature<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Signature Unit device
+  instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-signature
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: valid
+      - const: error
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    signature at 5618d000 {
+        compatible = "fsl,imx8qxp-dc-signature";
+        reg = <0x5618d000 0x140>;
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <22>, <23>, <24>;
+        interrupt-names = "shdload", "valid", "error";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
new file mode 100644
index 000000000000..38d86e3dd6b1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-store.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Store Unit
+
+description: |
+  The Store unit is the interface between the internal pixel processing
+  pipeline, which is 30-bit RGB plus 8-bit Alpha, and the AXI bus for
+  destination buffer access. It is used for the destination of Blit Engines.
+  It comprises a set of built-in functions to generate a wide range of buffer
+  formats. Note, that these are exactly inverse to corresponding functions in
+  the Fetch Unit.
+
+  +------X-------------------------+
+  |      |              Store Unit |
+  |      V                         |
+  |  +-------+                     |
+  |  | Gamma | Gamma apply         |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Color | RGB to YUV          |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Chroma| YUV444 to 422       |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Reduce| Bit width reduction |
+  |  |       | dithering           |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Pack  | RGBA/YUV to RAW     |
+  |  | Encode| or Compression      |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  +------X-------------------------+
+
+  Each Store Unit device should have an alias in the aliases node, in the form
+  of dc<x>-store<y>, where <x> is an integer specifying the Display Controller
+  instance and <y> is an integer specifying the Store Unit device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-store
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: framecomplete
+      - const: seqcomplete
+
+  fsl,lts:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Optional Linear Tile Store associated with the Store Unit.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    store at 56180940 {
+        compatible = "fsl,imx8qxp-dc-store";
+        reg = <0x56180940 0x1c>, <0x56184000 0x5c>;
+        reg-names = "pec", "cfg";
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <0>, <1>, <2>;
+        interrupt-names = "shdload", "framecomplete", "seqcomplete";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
new file mode 100644
index 000000000000..87f02d92d55e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-tcon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Timing Controller
+
+description: |
+  The TCon can generate a wide range of customized synchronization signals and
+  does the mapping of the color bits to the output.
+
+  Each Timing Controller device should have an alias in the aliases node, in the
+  form of dc<x>-tcon<y>, where <x> is an integer specifying the Display
+  Controller instance and <y> is an integer specifying the Timing Controller
+  device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-tcon
+
+  reg:
+    maxItems: 1
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description: video output
+
+required:
+  - compatible
+  - reg
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    tcon at 5618c800 {
+        compatible = "fsl,imx8qxp-dc-tcon";
+        reg = <0x5618c800 0x588>;
+
+        port {
+            dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
+                remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
+            };
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:06 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:06 +0800
Subject: [PATCH v6 02/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller blit engine
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-3-victor.liu@nxp.com>

i.MX8qxp Display Controller contains a blit engine for raster graphics.
It may read up to 3 source images from memory and computes one destination
image from it, which is written back to memory.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v6:
* No change.

v5:
* No change.

v4:
* Collect Rob's R-b tag.

v3:
* New patch. (Rob)

 .../imx/fsl,imx8qxp-dc-blit-engine.yaml       | 204 ++++++++++++++++++
 1 file changed, 204 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml
new file mode 100644
index 000000000000..45db6da39e20
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml
@@ -0,0 +1,204 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blit-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Blit Engine
+
+description: |
+  A blit operation (block based image transfer) reads up to 3 source images
+  from memory and computes one destination image from it, which is written
+  back to memory. The following basic operations are supported:
+
+  * Buffer Fill
+    Fills a buffer with constant color
+
+  * Buffer Copy
+    Copies one source to a destination buffer.
+
+  * Image Blend
+    Combines two source images by a blending equation and writes result to
+    destination (which can be one of the sources).
+
+  * Image Rop2/3
+    Combines up to three source images by a logical equation (raster operation)
+    and writes result to destination (which can be one of the sources).
+
+  * Image Flip
+    Mirrors the source image in horizontal and/or vertical direction.
+
+  * Format Convert
+    Convert between the supported color and buffer formats.
+
+  * Color Transform
+    Modify colors by linear or non-linear transformations.
+
+  * Image Scale
+    Changes size of the source image.
+
+  * Image Rotate
+    Rotates the source image by any angle.
+
+  * Image Filter
+    Performs an FIR filter operation on the source image.
+
+  * Image Warp
+    Performs a re-sampling of the source image with any pattern. The sample
+    point positions are read from a compressed coordinate buffer.
+
+  * Buffer Pack
+    Writes an image with color components stored in up to three different
+    buffers (planar formats) into a single buffer (packed format).
+
+  * Chroma Resample
+    Converts between different YUV formats that differ in chroma sampling rate
+    (4:4:4, 4:2:2, 4:2:0).
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-blit-engine
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^blitblend@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-blitblend
+
+  "^clut@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-clut
+
+  "^fetchdecode@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchdecode
+
+  "^fetcheco@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetcheco
+
+  "^fetchwarp@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchwarp
+
+  "^filter@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-filter
+
+  "^hscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-hscaler
+
+  "^matrix@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-matrix
+
+  "^rop@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-rop
+
+  "^store@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-store
+
+  "^vscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-vscaler
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    blit-engine at 56180820 {
+        compatible = "fsl,imx8qxp-dc-blit-engine";
+        reg = <0x56180820 0x13c>, <0x56181000 0x3400>;
+        reg-names = "pec", "cfg";
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        fetchdecode at 56180820 {
+            compatible = "fsl,imx8qxp-dc-fetchdecode";
+            reg = <0x56180820 0x10>, <0x56181000 0x404>;
+            reg-names = "pec", "cfg";
+        };
+
+        store at 56180940 {
+            compatible = "fsl,imx8qxp-dc-store";
+            reg = <0x56180940 0x1c>, <0x56184000 0x5c>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <0>, <1>, <2>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:07 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:07 +0800
Subject: [PATCH v6 03/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller display engine
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-4-victor.liu@nxp.com>

i.MX8qxp Display Controller display engine consists of all processing units
that operate in a display clock domain.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* Document aliases.  Drop Rob's previous R-b tag. (Maxime)

v4:
* Collect Rob's R-b tag.

v3:
* No change.

v2:
* Drop fsl,dc-*-id DT properties. (Krzysztof)
* Drop port property. (Krzysztof)
* Fix register range sizes in example.

 .../imx/fsl,imx8qxp-dc-display-engine.yaml    | 157 ++++++++++++++++++
 1 file changed, 157 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml
new file mode 100644
index 000000000000..b5da0bf3a1f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml
@@ -0,0 +1,157 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-display-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Display Engine
+
+description: |
+  All Processing Units that operate in a display clock domain. Pixel pipeline
+  is driven by a video timing and cannot be stalled. Implements all display
+  specific processing.
+
+  Each Display Engine device should have an alias in the aliases node, in the
+  form of dc<x>-display-engine<y>, where <x> is an integer specifying the
+  Display Controller instance and <y> is an integer specifying the Display
+  Engine device instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-display-engine
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: top
+      - const: cfg
+
+  resets:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: framecomplete
+      - const: seqcomplete
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^dither@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-dither
+
+  "^framegen@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-framegen
+
+  "^gammacor@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-gammacor
+
+  "^matrix@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-matrix
+
+  "^signature@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-signature
+
+  "^tcon@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-tcon
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+  - power-domains
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    display-engine at 5618b400 {
+        compatible = "fsl,imx8qxp-dc-display-engine";
+        reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
+        reg-names = "top", "cfg";
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <15>, <16>, <17>;
+        interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        framegen at 5618b800 {
+            compatible = "fsl,imx8qxp-dc-framegen";
+            reg = <0x5618b800 0x98>;
+            clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <18>, <19>, <20>, <21>, <41>, <42>, <43>, <44>;
+            interrupt-names = "int0", "int1", "int2", "int3",
+                              "primsync_on", "primsync_off",
+                              "secsync_on", "secsync_off";
+        };
+
+        tcon at 5618c800 {
+            compatible = "fsl,imx8qxp-dc-tcon";
+            reg = <0x5618c800 0x588>;
+
+            port {
+                dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
+                    remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
+                };
+            };
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:08 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:08 +0800
Subject: [PATCH v6 04/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller pixel engine
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-5-victor.liu@nxp.com>

i.MX8qxp Display Controller pixel engine consists of all processing units
that operate in the AXI bus clock domain.  Command sequencer and interrupt
controller of the Display Controller work with AXI bus clock, but they are
not in pixel engine.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v6:
* No change.

v5:
* No change.

v4:
* Collect Rob's R-b tag.

v3:
* No change.

v2:
* Drop fsl,dc-*-id DT properties from example. (Krzysztof)
* Fix register range sizes in example.

 .../imx/fsl,imx8qxp-dc-pixel-engine.yaml      | 250 ++++++++++++++++++
 1 file changed, 250 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
new file mode 100644
index 000000000000..633443a6cc38
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
@@ -0,0 +1,250 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Pixel Engine
+
+description:
+  All Processing Units that operate in the AXI bus clock domain. Pixel
+  pipelines have the ability to stall when a destination is busy. Implements
+  all communication to memory resources and most of the image processing
+  functions. Interconnection of Processing Units is re-configurable.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-pixel-engine
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^blit-engine@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-blit-engine
+
+  "^constframe@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-constframe
+
+  "^extdst@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-extdst
+
+  "^fetchdecode@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchdecode
+
+  "^fetcheco@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetcheco
+
+  "^fetchlayer@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchlayer
+
+  "^fetchwarp@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchwarp
+
+  "^hscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-hscaler
+
+  "^layerblend@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-layerblend
+
+  "^matrix@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-matrix
+
+  "^safety@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-safety
+
+  "^vscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-vscaler
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    pixel-engine at 56180800 {
+        compatible = "fsl,imx8qxp-dc-pixel-engine";
+        reg = <0x56180800 0xac00>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        constframe at 56180960 {
+            compatible = "fsl,imx8qxp-dc-constframe";
+            reg = <0x56180960 0xc>, <0x56184400 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 56180980 {
+            compatible = "fsl,imx8qxp-dc-extdst";
+            reg = <0x56180980 0x1c>, <0x56184800 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <3>, <4>, <5>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        constframe at 561809a0 {
+            compatible = "fsl,imx8qxp-dc-constframe";
+            reg = <0x561809a0 0xc>, <0x56184c00 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 561809c0 {
+            compatible = "fsl,imx8qxp-dc-extdst";
+            reg = <0x561809c0 0x1c>, <0x56185000 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <6>, <7>, <8>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        constframe at 561809e0 {
+            compatible = "fsl,imx8qxp-dc-constframe";
+            reg = <0x561809e0 0xc>, <0x56185400 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 56180a00 {
+            compatible = "fsl,imx8qxp-dc-extdst";
+            reg = <0x56180a00 0x1c>, <0x56185800 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <9>, <10>, <11>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        constframe at 56180a20 {
+            compatible = "fsl,imx8qxp-dc-constframe";
+            reg = <0x56180a20 0xc>, <0x56185c00 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 56180a40 {
+            compatible = "fsl,imx8qxp-dc-extdst";
+            reg = <0x56180a40 0x1c>, <0x56186000 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <12>, <13>, <14>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        fetchwarp at 56180a60 {
+            compatible = "fsl,imx8qxp-dc-fetchwarp";
+            reg = <0x56180a60 0x10>, <0x56186400 0x190>;
+            reg-names = "pec", "cfg";
+        };
+
+        fetchlayer at 56180ac0 {
+            compatible = "fsl,imx8qxp-dc-fetchlayer";
+            reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180ba0 {
+            compatible = "fsl,imx8qxp-dc-layerblend";
+            reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180bc0 {
+            compatible = "fsl,imx8qxp-dc-layerblend";
+            reg = <0x56180bc0 0x10>, <0x5618a800 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180be0 {
+            compatible = "fsl,imx8qxp-dc-layerblend";
+            reg = <0x56180be0 0x10>, <0x5618ac00 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180c00 {
+            compatible = "fsl,imx8qxp-dc-layerblend";
+            reg = <0x56180c00 0x10>, <0x5618b000 0x20>;
+            reg-names = "pec", "cfg";
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:09 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:09 +0800
Subject: [PATCH v6 05/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller AXI performance counter
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-6-victor.liu@nxp.com>

i.MX8qxp Display Controller contains a AXI performance counter which allows
measurement of average bandwidth and latency during operation.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v6:
* No change.

v5:
* No change.

v4:
* Collect Rob's R-b tag.

v3:
* New patch. (Rob)

 ...sl,imx8qxp-dc-axi-performance-counter.yaml | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml
new file mode 100644
index 000000000000..1d6501afc7f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller AXI Performance Counter
+
+description: |
+  Performance counters are provided to allow measurement of average bandwidth
+  and latency during operation. The following features are supported:
+
+  * Manual and timer controlled measurement mode.
+
+  * Measurement counters:
+    - GLOBAL_COUNTER for overall measurement time
+    - BUSY_COUNTER for number of data bus busy cycles
+    - DATA_COUNTER for number of data transfer cycles
+    - TRANSFER_COUNTER for number of transfers
+    - ADDRBUSY_COUNTER for number of address bus busy cycles
+    - LATENCY_COUNTER for average latency
+
+  * Counter overflow detection.
+
+  * Outstanding Transfer Counters (OTC) which are used for latency measurement
+    have to run immediately after reset, but can be disabled by software when
+    there is no need for latency measurement.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-axi-performance-counter
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    pmu at 5618f000 {
+        compatible = "fsl,imx8qxp-dc-axi-performance-counter";
+        reg = <0x5618f000 0x90>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:10 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:10 +0800
Subject: [PATCH v6 06/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller command sequencer
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-7-victor.liu@nxp.com>

i.MX8qxp Display Controller contains a command sequencer is designed to
autonomously process command lists.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* No change.

v4:
* Replace "fsl,iram" property with standard "sram" property. (Rob)

v3:
* New patch. (Rob)

 .../imx/fsl,imx8qxp-dc-command-sequencer.yaml | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml
new file mode 100644
index 000000000000..27118f4c0d28
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Command Sequencer
+
+description: |
+  The Command Sequencer is designed to autonomously process command lists.
+  By that it can load setups into the DC configuration and synchronize to
+  hardware events.  This releases a system's CPU from workload, because it
+  does not need to wait for certain events.  Also it simplifies SW architecture,
+  because no interrupt handlers are required.  Setups are read via AXI bus,
+  while write access to configuration registers occurs directly via an internal
+  bus.  This saves bandwidth for the AXI interconnect and improves the system
+  architecture in terms of safety aspects.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-command-sequencer
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 5
+
+  interrupt-names:
+    items:
+      - const: error
+      - const: sw0
+      - const: sw1
+      - const: sw2
+      - const: sw3
+
+  sram:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle pointing to the mmio-sram device node
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    command-sequencer at 56180400 {
+        compatible = "fsl,imx8qxp-dc-command-sequencer";
+        reg = <0x56180400 0x1a4>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <36>, <37>, <38>, <39>, <40>;
+        interrupt-names = "error", "sw0", "sw1", "sw2", "sw3";
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:11 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:11 +0800
Subject: [PATCH v6 07/19] dt-bindings: interrupt-controller: Add i.MX8qxp Display Controller interrupt controller
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-8-victor.liu@nxp.com>

i.MX8qxp Display Controller has a built-in interrupt controller to support
Enable/Status/Preset/Clear interrupt bit.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* Collect Rob's R-b tag.

v2:
* Drop unneeded "|". (Krzysztof)

 .../fsl,imx8qxp-dc-intc.yaml                  | 318 ++++++++++++++++++
 1 file changed, 318 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml
new file mode 100644
index 000000000000..6985ee644a25
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml
@@ -0,0 +1,318 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/fsl,imx8qxp-dc-intc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller interrupt controller
+
+description: |
+  The Display Controller has a built-in interrupt controller with the following
+  features for all relevant HW events:
+
+  * Enable bit (mask)
+  * Status bit (set by an HW event)
+  * Preset bit (can be used by SW to set status)
+  * Clear bit (used by SW to reset the status)
+
+  Each interrupt can be connected as IRQ (maskable) and/or NMI (non-maskable).
+  Alternatively the un-masked trigger signals for all HW events are provided,
+  allowing it to use a global interrupt controller instead.
+
+  Each interrupt can be protected against SW running in user mode. In that case,
+  only privileged AHB access can control the interrupt status.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-intc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 1
+
+  interrupts:
+    items:
+      - description: store9 shadow load interrupt(blit engine)
+      - description: store9 frame complete interrupt(blit engine)
+      - description: store9 sequence complete interrupt(blit engine)
+      - description:
+          extdst0 shadow load interrupt
+          (display controller, content stream 0)
+      - description:
+          extdst0 frame complete interrupt
+          (display controller, content stream 0)
+      - description:
+          extdst0 sequence complete interrupt
+          (display controller, content stream 0)
+      - description:
+          extdst4 shadow load interrupt
+          (display controller, safety stream 0)
+      - description:
+          extdst4 frame complete interrupt
+          (display controller, safety stream 0)
+      - description:
+          extdst4 sequence complete interrupt
+          (display controller, safety stream 0)
+      - description:
+          extdst1 shadow load interrupt
+          (display controller, content stream 1)
+      - description:
+          extdst1 frame complete interrupt
+          (display controller, content stream 1)
+      - description:
+          extdst1 sequence complete interrupt
+          (display controller, content stream 1)
+      - description:
+          extdst5 shadow load interrupt
+          (display controller, safety stream 1)
+      - description:
+          extdst5 frame complete interrupt
+          (display controller, safety stream 1)
+      - description:
+          extdst5 sequence complete interrupt
+          (display controller, safety stream 1)
+      - description:
+          disengcfg0 shadow load interrupt
+          (display controller, display stream 0)
+      - description:
+          disengcfg0 frame complete interrupt
+          (display controller, display stream 0)
+      - description:
+          disengcfg0 sequence complete interrupt
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt0
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt1
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt2
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt3
+          (display controller, display stream 0)
+      - description:
+          signature0 shadow load interrupt
+          (display controller, display stream 0)
+      - description:
+          signature0 measurement valid interrupt
+          (display controller, display stream 0)
+      - description:
+          signature0 error condition interrupt
+          (display controller, display stream 0)
+      - description:
+          disengcfg1 shadow load interrupt
+          (display controller, display stream 1)
+      - description:
+          disengcfg1 frame complete interrupt
+          (display controller, display stream 1)
+      - description:
+          disengcfg1 sequence complete interrupt
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt0
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt1
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt2
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt3
+          (display controller, display stream 1)
+      - description:
+          signature1 shadow load interrupt
+          (display controller, display stream 1)
+      - description:
+          signature1 measurement valid interrupt
+          (display controller, display stream 1)
+      - description:
+          signature1 error condition interrupt
+          (display controller, display stream 1)
+      - description: reserved
+      - description:
+          command sequencer error condition interrupt(command sequencer)
+      - description:
+          common control software interrupt0(common control)
+      - description:
+          common control software interrupt1(common control)
+      - description:
+          common control software interrupt2(common control)
+      - description:
+          common control software interrupt3(common control)
+      - description:
+          framegen0 synchronization status activated interrupt
+          (display controller, safety stream 0)
+      - description:
+          framegen0 synchronization status deactivated interrupt
+          (display controller, safety stream 0)
+      - description:
+          framegen0 synchronization status activated interrupt
+          (display controller, content stream 0)
+      - description:
+          framegen0 synchronization status deactivated interrupt
+          (display controller, content stream 0)
+      - description:
+          framegen1 synchronization status activated interrupt
+          (display controller, safety stream 1)
+      - description:
+          framegen1 synchronization status deactivated interrupt
+          (display controller, safety stream 1)
+      - description:
+          framegen1 synchronization status activated interrupt
+          (display controller, content stream 1)
+      - description:
+          framegen1 synchronization status deactivated interrupt
+          (display controller, content stream 1)
+    minItems: 49
+
+  interrupt-names:
+    items:
+      - const: store9_shdload
+      - const: store9_framecomplete
+      - const: store9_seqcomplete
+      - const: extdst0_shdload
+      - const: extdst0_framecomplete
+      - const: extdst0_seqcomplete
+      - const: extdst4_shdload
+      - const: extdst4_framecomplete
+      - const: extdst4_seqcomplete
+      - const: extdst1_shdload
+      - const: extdst1_framecomplete
+      - const: extdst1_seqcomplete
+      - const: extdst5_shdload
+      - const: extdst5_framecomplete
+      - const: extdst5_seqcomplete
+      - const: disengcfg_shdload0
+      - const: disengcfg_framecomplete0
+      - const: disengcfg_seqcomplete0
+      - const: framegen0_int0
+      - const: framegen0_int1
+      - const: framegen0_int2
+      - const: framegen0_int3
+      - const: sig0_shdload
+      - const: sig0_valid
+      - const: sig0_error
+      - const: disengcfg_shdload1
+      - const: disengcfg_framecomplete1
+      - const: disengcfg_seqcomplete1
+      - const: framegen1_int0
+      - const: framegen1_int1
+      - const: framegen1_int2
+      - const: framegen1_int3
+      - const: sig1_shdload
+      - const: sig1_valid
+      - const: sig1_error
+      - const: reserved
+      - const: cmdseq_error
+      - const: comctrl_sw0
+      - const: comctrl_sw1
+      - const: comctrl_sw2
+      - const: comctrl_sw3
+      - const: framegen0_primsync_on
+      - const: framegen0_primsync_off
+      - const: framegen0_secsync_on
+      - const: framegen0_secsync_off
+      - const: framegen1_primsync_on
+      - const: framegen1_primsync_off
+      - const: framegen1_secsync_on
+      - const: framegen1_secsync_off
+    minItems: 49
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupt-controller
+  - "#interrupt-cells"
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    interrupt-controller at 56180040 {
+        compatible = "fsl,imx8qxp-dc-intc";
+        reg = <0x56180040 0x60>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+        interrupt-controller;
+        interrupt-parent = <&dc0_irqsteer>;
+        #interrupt-cells = <1>;
+        interrupts = <448>, <449>, <450>,  <64>,
+                      <65>,  <66>,  <67>,  <68>,
+                      <69>,  <70>, <193>, <194>,
+                     <195>, <196>, <197>,  <72>,
+                      <73>,  <74>,  <75>,  <76>,
+                      <77>,  <78>,  <79>,  <80>,
+                      <81>, <199>, <200>, <201>,
+                     <202>, <203>, <204>, <205>,
+                     <206>, <207>, <208>,   <5>,
+                       <0>,   <1>,   <2>,   <3>,
+                       <4>,  <82>,  <83>,  <84>,
+                      <85>, <209>, <210>, <211>,
+                     <212>;
+        interrupt-names = "store9_shdload",
+                          "store9_framecomplete",
+                          "store9_seqcomplete",
+                          "extdst0_shdload",
+                          "extdst0_framecomplete",
+                          "extdst0_seqcomplete",
+                          "extdst4_shdload",
+                          "extdst4_framecomplete",
+                          "extdst4_seqcomplete",
+                          "extdst1_shdload",
+                          "extdst1_framecomplete",
+                          "extdst1_seqcomplete",
+                          "extdst5_shdload",
+                          "extdst5_framecomplete",
+                          "extdst5_seqcomplete",
+                          "disengcfg_shdload0",
+                          "disengcfg_framecomplete0",
+                          "disengcfg_seqcomplete0",
+                          "framegen0_int0",
+                          "framegen0_int1",
+                          "framegen0_int2",
+                          "framegen0_int3",
+                          "sig0_shdload",
+                          "sig0_valid",
+                          "sig0_error",
+                          "disengcfg_shdload1",
+                          "disengcfg_framecomplete1",
+                          "disengcfg_seqcomplete1",
+                          "framegen1_int0",
+                          "framegen1_int1",
+                          "framegen1_int2",
+                          "framegen1_int3",
+                          "sig1_shdload",
+                          "sig1_valid",
+                          "sig1_error",
+                          "reserved",
+                          "cmdseq_error",
+                          "comctrl_sw0",
+                          "comctrl_sw1",
+                          "comctrl_sw2",
+                          "comctrl_sw3",
+                          "framegen0_primsync_on",
+                          "framegen0_primsync_off",
+                          "framegen0_secsync_on",
+                          "framegen0_secsync_off",
+                          "framegen1_primsync_on",
+                          "framegen1_primsync_off",
+                          "framegen1_secsync_on",
+                          "framegen1_secsync_off";
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:12 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:12 +0800
Subject: [PATCH v6 08/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-9-victor.liu@nxp.com>

i.MX8qxp Display Controller(DC) is comprised of three main components that
include a blit engine for 2D graphics accelerations, display controller for
display output processing, as well as a command sequencer.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* Document aliases.  Drop Rob's previous R-b tag. (Maxime)

v4:
* Collect Rob's R-b tag.

v3:
* No change.

v2:
* Drop fsl,dc-*-id DT properties from example. (Krzysztof)
* Use generic pmu pattern property. (Krzysztof)

 .../bindings/display/imx/fsl,imx8qxp-dc.yaml  | 240 ++++++++++++++++++
 1 file changed, 240 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
new file mode 100644
index 000000000000..10cc83a7420f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
@@ -0,0 +1,240 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller
+
+description: |
+  The Freescale i.MX8qxp Display Controller(DC) is comprised of three main
+  components that include a blit engine for 2D graphics accelerations, display
+  controller for display output processing, as well as a command sequencer.
+
+                                  Display buffers              Source buffers
+                                 (AXI read master)            (AXI read master)
+                                  | .......... |                  | | |
+      +---------------------------+------------+------------------+-+-+------+
+      | Display Controller (DC)   | .......... |                  | | |      |
+      |                           |            |                  | | |      |
+      |   @@@@@@@@@@@  +----------+------------+------------+     | | |      |
+  A   |  | Command   | |          V            V            |     | | |      |
+  X <-+->| Sequencer | |    @@@@@@@@@@@@@@@@@@@@@@@@@@@@    |     V V V      |
+  I   |  | (AXI CLK) | |   |                            |   |   @@@@@@@@@@   |
+      |   @@@@@@@@@@@  |   |       Pixel Engine         |   |  |          |  |
+      |       |        |   |         (AXI CLK)          |   |  |          |  |
+      |       V        |    @@@@@@@@@@@@@@@@@@@@@@@@@@@@    |  |          |  |
+  A   |   ***********  |       |   |            |   |       |  |   Blit   |  |
+  H <-+->| Configure | |       V   V            V   V       |  |  Engine  |  |
+  B   |  | (CFG CLK) | |    00000000000      11111111111    |  | (AXI CLK)|  |
+      |   ***********  |   |  Display  |    |  Display  |   |  |          |  |
+      |                |   |  Engine   |    |  Engine   |   |  |          |  |
+      |                |   | (Disp CLK)|    | (Disp CLK)|   |  |          |  |
+      |   @@@@@@@@@@@  |    00000000000      11111111111    |   @@@@@@@@@@   |
+  I   |  |  Common   | |         |                |         |       |        |
+  R <-+--|  Control  | |         |    Display     |         |       |        |
+  Q   |  | (AXI CLK) | |         |   Controller   |         |       |        |
+      |   @@@@@@@@@@@  +------------------------------------+       |        |
+      |                          |                |       ^         |        |
+      +--------------------------+----------------+-------+---------+--------+
+              ^                  |                |       |         |
+              |                  V                V       |         V
+       Clocks & Resets        Display          Display  Panic   Destination
+                              Output0          Output1 Control    buffer
+                                                              (AXI write master)
+
+  Each Display Controller device should have an alias in the aliases node, in
+  the form of dc<x>, where <x> is an integer specifying the Display Controller
+  instance.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: axi
+      - const: cfg
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^command-sequencer@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-command-sequencer
+
+  "^display-engine@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-display-engine
+
+  "^interrupt-controller@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-intc
+
+  "^pixel-engine@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-pixel-engine
+
+  "^pmu@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-axi-performance-counter
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - power-domains
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    display-controller at 56180000 {
+        compatible = "fsl,imx8qxp-dc";
+        reg = <0x56180000 0x40000>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_4>;
+        power-domains = <&pd IMX_SC_R_DC_0>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        interrupt-controller at 56180040 {
+            compatible = "fsl,imx8qxp-dc-intc";
+            reg = <0x56180040 0x60>;
+            clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+            interrupt-controller;
+            interrupt-parent = <&dc0_irqsteer>;
+            #interrupt-cells = <1>;
+            interrupts = <448>, <449>, <450>,  <64>,
+                          <65>,  <66>,  <67>,  <68>,
+                          <69>,  <70>, <193>, <194>,
+                         <195>, <196>, <197>,  <72>,
+                          <73>,  <74>,  <75>,  <76>,
+                          <77>,  <78>,  <79>,  <80>,
+                          <81>, <199>, <200>, <201>,
+                         <202>, <203>, <204>, <205>,
+                         <206>, <207>, <208>,   <5>,
+                           <0>,   <1>,   <2>,   <3>,
+                           <4>,  <82>,  <83>,  <84>,
+                          <85>, <209>, <210>, <211>,
+                         <212>;
+            interrupt-names = "store9_shdload",
+                              "store9_framecomplete",
+                              "store9_seqcomplete",
+                              "extdst0_shdload",
+                              "extdst0_framecomplete",
+                              "extdst0_seqcomplete",
+                              "extdst4_shdload",
+                              "extdst4_framecomplete",
+                              "extdst4_seqcomplete",
+                              "extdst1_shdload",
+                              "extdst1_framecomplete",
+                              "extdst1_seqcomplete",
+                              "extdst5_shdload",
+                              "extdst5_framecomplete",
+                              "extdst5_seqcomplete",
+                              "disengcfg_shdload0",
+                              "disengcfg_framecomplete0",
+                              "disengcfg_seqcomplete0",
+                              "framegen0_int0",
+                              "framegen0_int1",
+                              "framegen0_int2",
+                              "framegen0_int3",
+                              "sig0_shdload",
+                              "sig0_valid",
+                              "sig0_error",
+                              "disengcfg_shdload1",
+                              "disengcfg_framecomplete1",
+                              "disengcfg_seqcomplete1",
+                              "framegen1_int0",
+                              "framegen1_int1",
+                              "framegen1_int2",
+                              "framegen1_int3",
+                              "sig1_shdload",
+                              "sig1_valid",
+                              "sig1_error",
+                              "reserved",
+                              "cmdseq_error",
+                              "comctrl_sw0",
+                              "comctrl_sw1",
+                              "comctrl_sw2",
+                              "comctrl_sw3",
+                              "framegen0_primsync_on",
+                              "framegen0_primsync_off",
+                              "framegen0_secsync_on",
+                              "framegen0_secsync_off",
+                              "framegen1_primsync_on",
+                              "framegen1_primsync_off",
+                              "framegen1_secsync_on",
+                              "framegen1_secsync_off";
+        };
+
+        pixel-engine at 56180800 {
+            compatible = "fsl,imx8qxp-dc-pixel-engine";
+            reg = <0x56180800 0xac00>;
+            clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges;
+        };
+
+        display-engine at 5618b400 {
+            compatible = "fsl,imx8qxp-dc-display-engine";
+            reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
+            reg-names = "top", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <15>, <16>, <17>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+            power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges;
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:14 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:14 +0800
Subject: [PATCH v6 10/19] drm/imx: Add i.MX8qxp Display Controller pixel engine
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-11-victor.liu@nxp.com>

i.MX8qxp Display Controller pixel engine consists of all processing
units that operate in the AXI bus clock domain.  Add drivers for
ConstFrame, ExtDst, FetchLayer, FetchWarp and LayerBlend units, as
well as a pixel engine driver, so that two displays with primary
planes can be supported.  The pixel engine driver and those unit
drivers are components to be aggregated by a master registered in
the upcoming DRM driver.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* Fix build warning by expanding sizeof(fu->name) from 13 to 21.
  (kernel test robot)

v5:
* Replace .remove_new with .remove in dc-{cf,de,fl,fw,lb,pe}.c. (Uwe)
* Fix commit message to state that pixel engine driver is a component driver
  instead of a master/aggregate driver.

v4:
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Inline some small functions. (Dmitry)
* Move dc_lb_blendcontrol() function call from KMS routine to initialization
  stage. (Dmitry)
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
* Drop unnecessary private struct dc_*_priv.
* Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
  interfaces to bind/unbind the drivers.
* Make some fetch unit operations be aware of fractional fetch unit index(0-7).

v3:
* No change.

v2:
* Use OF alias id to get instance id.

 drivers/gpu/drm/imx/dc/Makefile |   3 +-
 drivers/gpu/drm/imx/dc/dc-cf.c  | 162 ++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-drv.c |   6 +
 drivers/gpu/drm/imx/dc/dc-drv.h |   8 +
 drivers/gpu/drm/imx/dc/dc-ed.c  | 270 +++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-fl.c  | 180 ++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-fu.c  | 268 +++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-fu.h  | 129 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-fw.c  | 219 ++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-lb.c  | 319 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-pe.c  | 133 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-pe.h  | 100 ++++++++++
 12 files changed, 1796 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/imx/dc/dc-cf.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ed.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fl.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fw.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-lb.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.h

diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index 56de82d53d4d..2942ae6fd5bd 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-imx8-dc-drm-objs := dc-de.o dc-drv.o dc-fg.o dc-tc.o
+imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
+		    dc-fw.o dc-lb.o dc-pe.o dc-tc.o
 
 obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
new file mode 100644
index 000000000000..266344054ac6
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-cf.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define STATICCONTROL		0x8
+
+#define FRAMEDIMENSIONS		0xc
+#define  HEIGHT(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  WIDTH(x)		FIELD_PREP(GENMASK(13, 0), ((x) - 1))
+
+#define CONSTANTCOLOR		0x10
+#define  BLUE(x)		FIELD_PREP(GENMASK(15, 8), (x))
+
+static const struct regmap_range dc_cf_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, CONSTANTCOLOR),
+};
+
+static const struct regmap_access_table dc_cf_regmap_access_table = {
+	.yes_ranges = dc_cf_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_cf_regmap_ranges),
+};
+
+static const struct regmap_config dc_cf_cfg_regmap_config = {
+	.name = "constframe-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_cf_regmap_access_table,
+	.rd_table = &dc_cf_regmap_access_table,
+};
+
+static inline void dc_cf_enable_shden(struct dc_cf *cf)
+{
+	regmap_write(cf->reg_cfg, STATICCONTROL, SHDEN);
+}
+
+enum dc_link_id dc_cf_get_link_id(struct dc_cf *cf)
+{
+	return cf->link;
+}
+
+void dc_cf_framedimensions(struct dc_cf *cf, unsigned int w,
+			   unsigned int h)
+{
+	regmap_write(cf->reg_cfg, FRAMEDIMENSIONS, WIDTH(w) | HEIGHT(h));
+}
+
+void dc_cf_constantcolor_black(struct dc_cf *cf)
+{
+	regmap_write(cf->reg_cfg, CONSTANTCOLOR, 0);
+}
+
+void dc_cf_constantcolor_blue(struct dc_cf *cf)
+{
+	regmap_write(cf->reg_cfg, CONSTANTCOLOR, BLUE(0xff));
+}
+
+void dc_cf_init(struct dc_cf *cf)
+{
+	dc_cf_enable_shden(cf);
+}
+
+static int dc_cf_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_cfg;
+	struct dc_cf *cf;
+	int id;
+
+	cf = devm_kzalloc(dev, sizeof(*cf), GFP_KERNEL);
+	if (!cf)
+		return -ENOMEM;
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	cf->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_cf_cfg_regmap_config);
+	if (IS_ERR(cf->reg_cfg))
+		return PTR_ERR(cf->reg_cfg);
+
+	id = of_alias_get_id(dev->of_node, "dc0-constframe");
+	if (id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", id);
+		return id;
+	}
+
+	switch (id) {
+	case 0:
+		pe->cf_cont[0] = cf;
+		cf->link = LINK_ID_CONSTFRAME0;
+		break;
+	case 1:
+		pe->cf_cont[1] = cf;
+		cf->link = LINK_ID_CONSTFRAME1;
+		break;
+	case 4:
+		pe->cf_safe[0] = cf;
+		cf->link = LINK_ID_CONSTFRAME4;
+		break;
+	case 5:
+		pe->cf_safe[1] = cf;
+		cf->link = LINK_ID_CONSTFRAME5;
+		break;
+	}
+
+	return 0;
+}
+
+static const struct component_ops dc_cf_ops = {
+	.bind = dc_cf_bind,
+};
+
+static int dc_cf_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_cf_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_cf_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_cf_ops);
+}
+
+static const struct of_device_id dc_cf_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-constframe", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_cf_dt_ids);
+
+struct platform_driver dc_cf_driver = {
+	.probe = dc_cf_probe,
+	.remove = dc_cf_remove,
+	.driver = {
+		.name = "imx8-dc-constframe",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_cf_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index e5910a82dd4d..7c64acc863ad 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -9,8 +9,14 @@
 #include "dc-drv.h"
 
 static struct platform_driver * const dc_drivers[] = {
+	&dc_cf_driver,
 	&dc_de_driver,
+	&dc_ed_driver,
 	&dc_fg_driver,
+	&dc_fl_driver,
+	&dc_fw_driver,
+	&dc_lb_driver,
+	&dc_pe_driver,
 	&dc_tc_driver,
 };
 
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index e1290d9a0a99..c687a36b8153 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -11,14 +11,22 @@
 #include <drm/drm_device.h>
 
 #include "dc-de.h"
+#include "dc-pe.h"
 
 struct dc_drm_device {
 	struct drm_device base;
 	struct dc_de *de[DC_DISPLAYS];
+	struct dc_pe *pe;
 };
 
+extern struct platform_driver dc_cf_driver;
+extern struct platform_driver dc_ed_driver;
 extern struct platform_driver dc_de_driver;
 extern struct platform_driver dc_fg_driver;
+extern struct platform_driver dc_fl_driver;
+extern struct platform_driver dc_fw_driver;
+extern struct platform_driver dc_lb_driver;
+extern struct platform_driver dc_pe_driver;
 extern struct platform_driver dc_tc_driver;
 
 #endif /* __DC_DRV_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
new file mode 100644
index 000000000000..283777ca7be2
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-ed.c
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_STATIC	0x8
+#define  POWERDOWN		BIT(4)
+#define  SYNC_MODE		BIT(8)
+#define  SINGLE			0
+#define  DIV_MASK		GENMASK(23, 16)
+#define  DIV(x)			FIELD_PREP(DIV_MASK, (x))
+#define  DIV_RESET		0x80
+
+#define PIXENGCFG_DYNAMIC	0xc
+
+#define PIXENGCFG_TRIGGER	0x14
+#define  SYNC_TRIGGER		BIT(0)
+
+#define STATICCONTROL		0x8
+#define  KICK_MODE		BIT(8)
+#define  EXTERNAL		BIT(8)
+#define  PERFCOUNTMODE		BIT(12)
+
+#define CONTROL			0xc
+#define  GAMMAAPPLYENABLE	BIT(0)
+
+static const struct regmap_range dc_ed_pec_regmap_access_ranges[] = {
+	regmap_reg_range(PIXENGCFG_STATIC, PIXENGCFG_STATIC),
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+	regmap_reg_range(PIXENGCFG_TRIGGER, PIXENGCFG_TRIGGER),
+};
+
+static const struct regmap_access_table dc_ed_pec_regmap_access_table = {
+	.yes_ranges = dc_ed_pec_regmap_access_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_pec_regmap_access_ranges),
+};
+
+static const struct regmap_range dc_ed_pec_regmap_volatile_ranges[] = {
+	regmap_reg_range(PIXENGCFG_TRIGGER, PIXENGCFG_TRIGGER),
+};
+
+static const struct regmap_access_table dc_ed_pec_regmap_volatile_table = {
+	.yes_ranges = dc_ed_pec_regmap_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_pec_regmap_volatile_ranges),
+};
+
+static const struct regmap_config dc_ed_pec_regmap_config = {
+	.name = "extdst-pec",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_ed_pec_regmap_access_table,
+	.rd_table = &dc_ed_pec_regmap_access_table,
+	.volatile_table = &dc_ed_pec_regmap_volatile_table,
+};
+
+static const struct regmap_range dc_ed_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, STATICCONTROL),
+	regmap_reg_range(CONTROL, CONTROL),
+};
+
+static const struct regmap_access_table dc_ed_regmap_access_table = {
+	.yes_ranges = dc_ed_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_regmap_ranges),
+};
+
+static const struct regmap_config dc_ed_cfg_regmap_config = {
+	.name = "extdst-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_ed_regmap_access_table,
+	.rd_table = &dc_ed_regmap_access_table,
+};
+
+static const enum dc_link_id src_sels[] = {
+	LINK_ID_NONE,
+	LINK_ID_CONSTFRAME0,
+	LINK_ID_CONSTFRAME1,
+	LINK_ID_CONSTFRAME4,
+	LINK_ID_CONSTFRAME5,
+	LINK_ID_LAYERBLEND3,
+	LINK_ID_LAYERBLEND2,
+	LINK_ID_LAYERBLEND1,
+	LINK_ID_LAYERBLEND0,
+};
+
+static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SHDEN, SHDEN);
+}
+
+static inline void dc_ed_pec_poweron(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, POWERDOWN, 0);
+}
+
+static inline void dc_ed_pec_sync_mode_single(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SYNC_MODE, SINGLE);
+}
+
+static inline void dc_ed_pec_div_reset(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, DIV_MASK,
+			  DIV(DIV_RESET));
+}
+
+void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(src_sels); i++) {
+		if (src_sels[i] == src) {
+			regmap_write(ed->reg_pec, PIXENGCFG_DYNAMIC, src);
+			return;
+		}
+	}
+}
+
+void dc_ed_pec_sync_trigger(struct dc_ed *ed)
+{
+	regmap_write(ed->reg_pec, PIXENGCFG_TRIGGER, SYNC_TRIGGER);
+}
+
+static inline void dc_ed_enable_shden(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_ed_kick_mode_external(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, STATICCONTROL, KICK_MODE, EXTERNAL);
+}
+
+static inline void dc_ed_disable_perfcountmode(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, STATICCONTROL, PERFCOUNTMODE, 0);
+}
+
+static inline void dc_ed_disable_gamma_apply(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, CONTROL, GAMMAAPPLYENABLE, 0);
+}
+
+void dc_ed_init(struct dc_ed *ed)
+{
+	dc_ed_pec_src_sel(ed, LINK_ID_NONE);
+	dc_ed_pec_enable_shden(ed);
+	dc_ed_pec_poweron(ed);
+	dc_ed_pec_sync_mode_single(ed);
+	dc_ed_pec_div_reset(ed);
+	dc_ed_enable_shden(ed);
+	dc_ed_disable_perfcountmode(ed);
+	dc_ed_kick_mode_external(ed);
+	dc_ed_disable_gamma_apply(ed);
+}
+
+static int dc_ed_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_pec;
+	void __iomem *base_cfg;
+	struct dc_ed *ed;
+	int id;
+
+	ed = devm_kzalloc(dev, sizeof(*ed), GFP_KERNEL);
+	if (!ed)
+		return -ENOMEM;
+
+	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
+	if (IS_ERR(base_pec))
+		return PTR_ERR(base_pec);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	ed->reg_pec = devm_regmap_init_mmio(dev, base_pec,
+					    &dc_ed_pec_regmap_config);
+	if (IS_ERR(ed->reg_pec))
+		return PTR_ERR(ed->reg_pec);
+
+	ed->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_ed_cfg_regmap_config);
+	if (IS_ERR(ed->reg_cfg))
+		return PTR_ERR(ed->reg_cfg);
+
+	ed->irq_shdld = platform_get_irq_byname(pdev, "shdload");
+	if (ed->irq_shdld < 0)
+		return ed->irq_shdld;
+
+	id = of_alias_get_id(dev->of_node, "dc0-extdst");
+	if (id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", id);
+		return id;
+	}
+
+	ed->dev = dev;
+
+	switch (id) {
+	case 0:
+		pe->ed_cont[0] = ed;
+		break;
+	case 1:
+		pe->ed_cont[1] = ed;
+		break;
+	case 4:
+		pe->ed_safe[0] = ed;
+		break;
+	case 5:
+		pe->ed_safe[1] = ed;
+		break;
+	}
+
+	return 0;
+}
+
+static const struct component_ops dc_ed_ops = {
+	.bind = dc_ed_bind,
+};
+
+static int dc_ed_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_ed_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_ed_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_ed_ops);
+}
+
+static const struct of_device_id dc_ed_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-extdst", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_ed_dt_ids);
+
+struct platform_driver dc_ed_driver = {
+	.probe = dc_ed_probe,
+	.remove = dc_ed_remove,
+	.driver = {
+		.name = "imx8-dc-extdst",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_ed_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
new file mode 100644
index 000000000000..7797ea59278a
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fl.c
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+#define BASEADDRESS(x)			(0x10 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERATTRIBUTES(x)	(0x14 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERDIMENSION(x)	(0x18 + FRAC_OFFSET * (x))
+#define COLORCOMPONENTBITS(x)		(0x1c + FRAC_OFFSET * (x))
+#define COLORCOMPONENTSHIFT(x)		(0x20 + FRAC_OFFSET * (x))
+#define LAYEROFFSET(x)			(0x24 + FRAC_OFFSET * (x))
+#define CLIPWINDOWOFFSET(x)		(0x28 + FRAC_OFFSET * (x))
+#define CLIPWINDOWDIMENSIONS(x)		(0x2c + FRAC_OFFSET * (x))
+#define CONSTANTCOLOR(x)		(0x30 + FRAC_OFFSET * (x))
+#define LAYERPROPERTY(x)		(0x34 + FRAC_OFFSET * (x))
+#define FRAMEDIMENSIONS			0x150
+
+struct dc_fl {
+	struct dc_fu fu;
+	int id;
+};
+
+static const struct regmap_range dc_fl_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS),
+};
+
+static const struct regmap_access_table dc_fl_regmap_access_table = {
+	.yes_ranges = dc_fl_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fl_regmap_ranges),
+};
+
+static const struct regmap_config dc_fl_cfg_regmap_config = {
+	.name = "fetchlayer-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fl_regmap_access_table,
+	.rd_table = &dc_fl_regmap_access_table,
+};
+
+static void dc_fl_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
+			  const struct drm_format_info *format)
+{
+	u32 bits = 0, shifts = 0;
+
+	dc_fu_set_src_bpp(fu, frac, format->cpp[0] * 8);
+
+	regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
+			  YUVCONVERSIONMODE_MASK,
+			  YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
+
+	dc_fu_get_pixel_format_bits(fu, format->format, &bits);
+	dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
+
+	regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
+	regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
+}
+
+static void dc_fl_set_framedimensions(struct dc_fu *fu, int w, int h)
+{
+	regmap_write(fu->reg_cfg, FRAMEDIMENSIONS,
+		     FRAMEWIDTH(w) | FRAMEHEIGHT(h));
+}
+
+static void dc_fl_init(struct dc_fu *fu)
+{
+	dc_fu_common_hw_init(fu);
+	dc_fu_shdldreq_sticky(fu, 0xff);
+}
+
+static void dc_fl_set_ops(struct dc_fu *fu)
+{
+	memcpy(&fu->ops, &dc_fu_common_ops, sizeof(dc_fu_common_ops));
+	fu->ops.init = dc_fl_init;
+	fu->ops.set_fmt = dc_fl_set_fmt;
+	fu->ops.set_framedimensions = dc_fl_set_framedimensions;
+}
+
+static int dc_fl_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_cfg;
+	struct dc_fl *fl;
+	struct dc_fu *fu;
+	int i;
+
+	fl = devm_kzalloc(dev, sizeof(*fl), GFP_KERNEL);
+	if (!fl)
+		return -ENOMEM;
+
+	fu = &fl->fu;
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_fl_cfg_regmap_config);
+	if (IS_ERR(fu->reg_cfg))
+		return PTR_ERR(fu->reg_cfg);
+
+	fl->id = of_alias_get_id(dev->of_node, "dc0-fetchlayer");
+	if (fl->id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", fl->id);
+		return fl->id;
+	}
+
+	fu->link_id = LINK_ID_FETCHLAYER0;
+	fu->id = DC_FETCHUNIT_FL0;
+	for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
+		fu->reg_baseaddr[i]		  = BASEADDRESS(i);
+		fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
+		fu->reg_sourcebufferdimension[i]  = SOURCEBUFFERDIMENSION(i);
+		fu->reg_layeroffset[i]		  = LAYEROFFSET(i);
+		fu->reg_clipwindowoffset[i]	  = CLIPWINDOWOFFSET(i);
+		fu->reg_clipwindowdimensions[i]	  = CLIPWINDOWDIMENSIONS(i);
+		fu->reg_constantcolor[i]	  = CONSTANTCOLOR(i);
+		fu->reg_layerproperty[i]	  = LAYERPROPERTY(i);
+	}
+	snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", fl->id);
+
+	dc_fl_set_ops(fu);
+
+	pe->fu_disp[fu->id] = fu;
+
+	return 0;
+}
+
+static const struct component_ops dc_fl_ops = {
+	.bind = dc_fl_bind,
+};
+
+static int dc_fl_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_fl_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_fl_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_fl_ops);
+}
+
+static const struct of_device_id dc_fl_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-fetchlayer", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_fl_dt_ids);
+
+struct platform_driver dc_fl_driver = {
+	.probe = dc_fl_probe,
+	.remove = dc_fl_remove,
+	.driver = {
+		.name = "imx8-dc-fetchlayer",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_fl_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.c b/drivers/gpu/drm/imx/dc/dc-fu.c
new file mode 100644
index 000000000000..dda8e6c52be8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fu.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/math.h>
+
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+/* STATICCONTROL */
+#define SHDLDREQSTICKY_MASK		GENMASK(31, 24)
+#define SHDLDREQSTICKY(x)		FIELD_PREP(SHDLDREQSTICKY_MASK, (x))
+#define BASEADDRESSAUTOUPDATE_MASK	GENMASK(23, 16)
+#define BASEADDRESSAUTOUPDATE(x)	FIELD_PREP(BASEADDRESSAUTOUPDATE_MASK, (x))
+
+/* BURSTBUFFERMANAGEMENT */
+#define SETBURSTLENGTH_MASK		GENMASK(12, 8)
+#define SETBURSTLENGTH(x)		FIELD_PREP(SETBURSTLENGTH_MASK, (x))
+#define SETNUMBUFFERS_MASK		GENMASK(7, 0)
+#define SETNUMBUFFERS(x)		FIELD_PREP(SETNUMBUFFERS_MASK, (x))
+#define LINEMODE_MASK			BIT(31)
+
+/* SOURCEBUFFERATTRIBUTES */
+#define BITSPERPIXEL_MASK		GENMASK(21, 16)
+#define BITSPERPIXEL(x)			FIELD_PREP(BITSPERPIXEL_MASK, (x))
+#define STRIDE_MASK			GENMASK(15, 0)
+#define STRIDE(x)			FIELD_PREP(STRIDE_MASK, (x) - 1)
+
+/* SOURCEBUFFERDIMENSION */
+#define LINEWIDTH(x)			FIELD_PREP(GENMASK(13, 0), (x))
+#define LINECOUNT(x)			FIELD_PREP(GENMASK(29, 16), (x))
+
+/* LAYEROFFSET */
+#define LAYERXOFFSET(x)			FIELD_PREP(GENMASK(14, 0), (x))
+#define LAYERYOFFSET(x)			FIELD_PREP(GENMASK(30, 16), (x))
+
+/* CLIPWINDOWOFFSET */
+#define CLIPWINDOWXOFFSET(x)		FIELD_PREP(GENMASK(14, 0), (x))
+#define CLIPWINDOWYOFFSET(x)		FIELD_PREP(GENMASK(30, 16), (x))
+
+/* CLIPWINDOWDIMENSIONS */
+#define CLIPWINDOWWIDTH(x)		FIELD_PREP(GENMASK(13, 0), (x) - 1)
+#define CLIPWINDOWHEIGHT(x)		FIELD_PREP(GENMASK(29, 16), (x) - 1)
+
+static const enum dc_fu_frac dc_fetchunit_all_fracs[] = {
+	DC_FETCHUNIT_FRAC0, DC_FETCHUNIT_FRAC1,
+	DC_FETCHUNIT_FRAC2, DC_FETCHUNIT_FRAC3,
+	DC_FETCHUNIT_FRAC4, DC_FETCHUNIT_FRAC5,
+	DC_FETCHUNIT_FRAC6, DC_FETCHUNIT_FRAC7
+};
+
+enum dc_linemode {
+	/*
+	 * Mandatory setting for operation in the Display Controller.
+	 * Works also for Blit Engine with marginal performance impact.
+	 */
+	LINEMODE_DISPLAY = 0,
+};
+
+struct dc_fu_pixel_format {
+	u32 pixel_format;
+	u32 bits;
+	u32 shifts;
+};
+
+static const struct dc_fu_pixel_format pixel_formats[] = {
+	{
+		DRM_FORMAT_XRGB8888,
+		R_BITS(8)   | G_BITS(8)   | B_BITS(8)   | A_BITS(0),
+		R_SHIFT(16) | G_SHIFT(8)  | B_SHIFT(0)  | A_SHIFT(0),
+	},
+};
+
+void dc_fu_get_pixel_format_bits(struct dc_fu *fu, u32 format, u32 *bits)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+		if (pixel_formats[i].pixel_format == format) {
+			*bits = pixel_formats[i].bits;
+			return;
+		}
+	}
+}
+
+void
+dc_fu_get_pixel_format_shifts(struct dc_fu *fu, u32 format, u32 *shifts)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+		if (pixel_formats[i].pixel_format == format) {
+			*shifts = pixel_formats[i].shifts;
+			return;
+		}
+	}
+}
+
+static inline void dc_fu_enable_shden(struct dc_fu *fu)
+{
+	regmap_write_bits(fu->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_fu_baddr_autoupdate(struct dc_fu *fu, u8 layer_mask)
+{
+	regmap_write_bits(fu->reg_cfg, STATICCONTROL,
+			  BASEADDRESSAUTOUPDATE_MASK,
+			  BASEADDRESSAUTOUPDATE(layer_mask));
+}
+
+void dc_fu_shdldreq_sticky(struct dc_fu *fu, u8 layer_mask)
+{
+	regmap_write_bits(fu->reg_cfg, STATICCONTROL, SHDLDREQSTICKY_MASK,
+			  SHDLDREQSTICKY(layer_mask));
+}
+
+static inline void dc_fu_set_linemode(struct dc_fu *fu, enum dc_linemode mode)
+{
+	regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT, LINEMODE_MASK,
+			  mode);
+}
+
+static inline void dc_fu_set_numbuffers(struct dc_fu *fu, unsigned int num)
+{
+	regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
+			  SETNUMBUFFERS_MASK, SETNUMBUFFERS(num));
+}
+
+static void dc_fu_set_burstlength(struct dc_fu *fu, dma_addr_t baddr)
+{
+	unsigned int burst_size, burst_length;
+
+	burst_size = 1 << __ffs(baddr);
+	burst_size = round_up(burst_size, 8);
+	burst_size = min(burst_size, 128U);
+	burst_length = burst_size / 8;
+
+	regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
+			  SETBURSTLENGTH_MASK, SETBURSTLENGTH(burst_length));
+}
+
+static void dc_fu_set_baseaddress(struct dc_fu *fu, enum dc_fu_frac frac,
+				  dma_addr_t baddr)
+{
+	regmap_write(fu->reg_cfg, fu->reg_baseaddr[frac], baddr);
+}
+
+void dc_fu_set_src_bpp(struct dc_fu *fu, enum dc_fu_frac frac, unsigned int bpp)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_sourcebufferattributes[frac],
+			  BITSPERPIXEL_MASK, BITSPERPIXEL(bpp));
+}
+
+static void dc_fu_set_src_stride(struct dc_fu *fu, enum dc_fu_frac frac,
+				 unsigned int stride)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_sourcebufferattributes[frac],
+			  STRIDE_MASK, STRIDE(stride));
+}
+
+static void dc_fu_set_src_buf_dimensions(struct dc_fu *fu, enum dc_fu_frac frac,
+					 int w, int h)
+{
+	regmap_write(fu->reg_cfg, fu->reg_sourcebufferdimension[frac],
+		     LINEWIDTH(w) | LINECOUNT(h));
+}
+
+static inline void dc_fu_layeroffset(struct dc_fu *fu, enum dc_fu_frac frac,
+				     unsigned int x, unsigned int y)
+{
+	regmap_write(fu->reg_cfg, fu->reg_layeroffset[frac],
+		     LAYERXOFFSET(x) | LAYERYOFFSET(y));
+}
+
+static inline void dc_fu_clipoffset(struct dc_fu *fu, enum dc_fu_frac frac,
+				    unsigned int x, unsigned int y)
+{
+	regmap_write(fu->reg_cfg, fu->reg_clipwindowoffset[frac],
+		     CLIPWINDOWXOFFSET(x) | CLIPWINDOWYOFFSET(y));
+}
+
+static inline void dc_fu_clipdimensions(struct dc_fu *fu, enum dc_fu_frac frac,
+					unsigned int w, unsigned int h)
+{
+	regmap_write(fu->reg_cfg, fu->reg_clipwindowdimensions[frac],
+		     CLIPWINDOWWIDTH(w) | CLIPWINDOWHEIGHT(h));
+}
+
+static inline void
+dc_fu_set_pixel_blend_mode(struct dc_fu *fu, enum dc_fu_frac frac)
+{
+	regmap_write(fu->reg_cfg, fu->reg_layerproperty[frac], 0);
+	regmap_write(fu->reg_cfg, fu->reg_constantcolor[frac], 0);
+}
+
+static void dc_fu_enable_src_buf(struct dc_fu *fu, enum dc_fu_frac frac)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
+			  SOURCEBUFFERENABLE, SOURCEBUFFERENABLE);
+}
+
+static void dc_fu_disable_src_buf(struct dc_fu *fu, enum dc_fu_frac frac)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
+			  SOURCEBUFFERENABLE, 0);
+
+	if (fu->lb) {
+		dc_lb_pec_clken(fu->lb, CLKEN_DISABLE);
+		dc_lb_mode(fu->lb, LB_NEUTRAL);
+	}
+}
+
+static void dc_fu_set_layerblend(struct dc_fu *fu, struct dc_lb *lb)
+{
+	fu->lb = lb;
+}
+
+static enum dc_link_id dc_fu_get_link_id(struct dc_fu *fu)
+{
+	return fu->link_id;
+}
+
+static const char *dc_fu_get_name(struct dc_fu *fu)
+{
+	return fu->name;
+}
+
+const struct dc_fu_ops dc_fu_common_ops = {
+	.set_burstlength	= dc_fu_set_burstlength,
+	.set_baseaddress	= dc_fu_set_baseaddress,
+	.set_src_stride		= dc_fu_set_src_stride,
+	.set_src_buf_dimensions = dc_fu_set_src_buf_dimensions,
+	.enable_src_buf		= dc_fu_enable_src_buf,
+	.disable_src_buf	= dc_fu_disable_src_buf,
+	.set_layerblend		= dc_fu_set_layerblend,
+	.get_link_id		= dc_fu_get_link_id,
+	.get_name		= dc_fu_get_name,
+};
+
+const struct dc_fu_ops *dc_fu_get_ops(struct dc_fu *fu)
+{
+	return &fu->ops;
+}
+
+void dc_fu_common_hw_init(struct dc_fu *fu)
+{
+	enum dc_fu_frac frac;
+	int i;
+
+	dc_fu_baddr_autoupdate(fu, 0x0);
+	dc_fu_enable_shden(fu);
+	dc_fu_set_linemode(fu, LINEMODE_DISPLAY);
+	dc_fu_set_numbuffers(fu, 16);
+
+	for (i = 0; i < ARRAY_SIZE(dc_fetchunit_all_fracs); i++) {
+		frac = dc_fetchunit_all_fracs[i];
+
+		dc_fu_layeroffset(fu, frac, 0, 0);
+		dc_fu_clipoffset(fu, frac, 0, 0);
+		dc_fu_clipdimensions(fu, frac, 1, 1);
+		dc_fu_disable_src_buf(fu, frac);
+		dc_fu_set_pixel_blend_mode(fu, frac);
+	}
+}
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.h b/drivers/gpu/drm/imx/dc/dc-fu.h
new file mode 100644
index 000000000000..cab71965964e
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fu.h
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_FETCHUNIT_H__
+#define __DC_FETCHUNIT_H__
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "dc-pe.h"
+
+#define FRAC_OFFSET			0x28
+
+#define STATICCONTROL			0x8
+#define BURSTBUFFERMANAGEMENT		0xc
+
+/* COLORCOMPONENTBITS */
+#define R_BITS(x)			FIELD_PREP_CONST(GENMASK(27, 24), (x))
+#define G_BITS(x)			FIELD_PREP_CONST(GENMASK(19, 16), (x))
+#define B_BITS(x)			FIELD_PREP_CONST(GENMASK(11, 8), (x))
+#define A_BITS(x)			FIELD_PREP_CONST(GENMASK(3, 0), (x))
+
+/* COLORCOMPONENTSHIFT */
+#define R_SHIFT(x)			FIELD_PREP_CONST(GENMASK(28, 24), (x))
+#define G_SHIFT(x)			FIELD_PREP_CONST(GENMASK(20, 16), (x))
+#define B_SHIFT(x)			FIELD_PREP_CONST(GENMASK(12, 8), (x))
+#define A_SHIFT(x)			FIELD_PREP_CONST(GENMASK(4, 0), (x))
+
+/* LAYERPROPERTY */
+#define YUVCONVERSIONMODE_MASK		GENMASK(18, 17)
+#define YUVCONVERSIONMODE(x)		FIELD_PREP(YUVCONVERSIONMODE_MASK, (x))
+#define SOURCEBUFFERENABLE		BIT(31)
+
+/* FRAMEDIMENSIONS */
+#define FRAMEWIDTH(x)			FIELD_PREP(GENMASK(13, 0), (x))
+#define FRAMEHEIGHT(x)			FIELD_PREP(GENMASK(29, 16), (x))
+
+/* CONTROL */
+#define INPUTSELECT_MASK		GENMASK(4, 3)
+#define INPUTSELECT(x)			FIELD_PREP(INPUTSELECT_MASK, (x))
+#define RASTERMODE_MASK			GENMASK(2, 0)
+#define RASTERMODE(x)			FIELD_PREP(RASTERMODE_MASK, (x))
+
+enum dc_yuvconversionmode {
+	YUVCONVERSIONMODE_OFF,
+};
+
+enum dc_inputselect {
+	INPUTSELECT_INACTIVE,
+};
+
+enum dc_rastermode {
+	RASTERMODE_NORMAL,
+};
+
+enum {
+	DC_FETCHUNIT_FL0,
+	DC_FETCHUNIT_FW2,
+};
+
+enum dc_fu_frac {
+	DC_FETCHUNIT_FRAC0,
+	DC_FETCHUNIT_FRAC1,
+	DC_FETCHUNIT_FRAC2,
+	DC_FETCHUNIT_FRAC3,
+	DC_FETCHUNIT_FRAC4,
+	DC_FETCHUNIT_FRAC5,
+	DC_FETCHUNIT_FRAC6,
+	DC_FETCHUNIT_FRAC7,
+	DC_FETCHUNIT_FRAC_NUM,
+};
+
+struct dc_fu;
+struct dc_lb;
+
+struct dc_fu_ops {
+	void (*init)(struct dc_fu *fu);
+	void (*set_burstlength)(struct dc_fu *fu, dma_addr_t baddr);
+	void (*set_baseaddress)(struct dc_fu *fu, enum dc_fu_frac frac,
+				dma_addr_t baddr);
+	void (*set_src_stride)(struct dc_fu *fu, enum dc_fu_frac frac,
+			       unsigned int stride);
+	void (*set_src_buf_dimensions)(struct dc_fu *fu, enum dc_fu_frac frac,
+				       int w, int h);
+	void (*set_fmt)(struct dc_fu *fu, enum dc_fu_frac frac,
+			const struct drm_format_info *format);
+	void (*enable_src_buf)(struct dc_fu *fu, enum dc_fu_frac frac);
+	void (*disable_src_buf)(struct dc_fu *fu, enum dc_fu_frac frac);
+	void (*set_framedimensions)(struct dc_fu *fu, int w, int h);
+	void (*set_layerblend)(struct dc_fu *fu, struct dc_lb *lb);
+	enum dc_link_id (*get_link_id)(struct dc_fu *fu);
+	const char *(*get_name)(struct dc_fu *fu);
+};
+
+struct dc_fu {
+	struct regmap *reg_pec;
+	struct regmap *reg_cfg;
+	char name[21];
+	u32 reg_baseaddr[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_sourcebufferattributes[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_sourcebufferdimension[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_layeroffset[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_clipwindowoffset[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_clipwindowdimensions[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_constantcolor[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_layerproperty[DC_FETCHUNIT_FRAC_NUM];
+	unsigned int id;
+	enum dc_link_id link_id;
+	struct dc_fu_ops ops;
+	struct dc_lb *lb;
+};
+
+extern const struct dc_fu_ops dc_fu_common_ops;
+
+void dc_fu_get_pixel_format_bits(struct dc_fu *fu, u32 format, u32 *bits);
+void dc_fu_get_pixel_format_shifts(struct dc_fu *fu, u32 format, u32 *shifts);
+void dc_fu_shdldreq_sticky(struct dc_fu *fu, u8 layer_mask);
+void dc_fu_set_src_bpp(struct dc_fu *fu, enum dc_fu_frac frac, unsigned int bpp);
+void dc_fu_common_hw_init(struct dc_fu *fu);
+
+const struct dc_fu_ops *dc_fu_get_ops(struct dc_fu *fu);
+
+#endif /* __DC_FETCHUNIT_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-fw.c b/drivers/gpu/drm/imx/dc/dc-fw.c
new file mode 100644
index 000000000000..212302b026c0
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fw.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_DYNAMIC		0x8
+
+#define BASEADDRESS(x)			(0x10 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERATTRIBUTES(x)	(0x14 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERDIMENSION(x)	(0x18 + FRAC_OFFSET * (x))
+#define COLORCOMPONENTBITS(x)		(0x1c + FRAC_OFFSET * (x))
+#define COLORCOMPONENTSHIFT(x)		(0x20 + FRAC_OFFSET * (x))
+#define LAYEROFFSET(x)			(0x24 + FRAC_OFFSET * (x))
+#define CLIPWINDOWOFFSET(x)		(0x28 + FRAC_OFFSET * (x))
+#define CLIPWINDOWDIMENSIONS(x)		(0x2c + FRAC_OFFSET * (x))
+#define CONSTANTCOLOR(x)		(0x30 + FRAC_OFFSET * (x))
+#define LAYERPROPERTY(x)		(0x34 + FRAC_OFFSET * (x))
+#define FRAMEDIMENSIONS			0x150
+#define CONTROL				0x170
+
+struct dc_fw {
+	struct dc_fu fu;
+	int id;
+};
+
+static const struct regmap_range dc_fw_pec_regmap_access_ranges[] = {
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+};
+
+static const struct regmap_access_table dc_fw_pec_regmap_access_table = {
+	.yes_ranges = dc_fw_pec_regmap_access_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fw_pec_regmap_access_ranges),
+};
+
+static const struct regmap_config dc_fw_pec_regmap_config = {
+	.name = "fetchwarp-pec",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fw_pec_regmap_access_table,
+	.rd_table = &dc_fw_pec_regmap_access_table,
+};
+
+static const struct regmap_range dc_fw_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS),
+	regmap_reg_range(CONTROL, CONTROL),
+};
+
+static const struct regmap_access_table dc_fw_regmap_access_table = {
+	.yes_ranges = dc_fw_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fw_regmap_ranges),
+};
+
+static const struct regmap_config dc_fw_cfg_regmap_config = {
+	.name = "fetchwarp-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fw_regmap_access_table,
+	.rd_table = &dc_fw_regmap_access_table,
+};
+
+static void dc_fw_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
+			  const struct drm_format_info *format)
+{
+	u32 bits = 0, shifts = 0;
+
+	dc_fu_set_src_bpp(fu, frac, format->cpp[0] * 8);
+
+	regmap_write_bits(fu->reg_cfg, CONTROL, INPUTSELECT_MASK,
+			  INPUTSELECT(INPUTSELECT_INACTIVE));
+	regmap_write_bits(fu->reg_cfg, CONTROL, RASTERMODE_MASK,
+			  RASTERMODE(RASTERMODE_NORMAL));
+
+	regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
+			  YUVCONVERSIONMODE_MASK,
+			  YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
+
+	dc_fu_get_pixel_format_bits(fu, format->format, &bits);
+	dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
+
+	regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
+	regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
+}
+
+static void dc_fw_set_framedimensions(struct dc_fu *fu, int w, int h)
+{
+	regmap_write(fu->reg_cfg, FRAMEDIMENSIONS,
+		     FRAMEWIDTH(w) | FRAMEHEIGHT(h));
+}
+
+static void dc_fw_init(struct dc_fu *fu)
+{
+	regmap_write(fu->reg_pec, PIXENGCFG_DYNAMIC, LINK_ID_NONE);
+	dc_fu_common_hw_init(fu);
+	dc_fu_shdldreq_sticky(fu, 0xff);
+}
+
+static void dc_fw_set_ops(struct dc_fu *fu)
+{
+	memcpy(&fu->ops, &dc_fu_common_ops, sizeof(dc_fu_common_ops));
+	fu->ops.init = dc_fw_init;
+	fu->ops.set_fmt	= dc_fw_set_fmt;
+	fu->ops.set_framedimensions = dc_fw_set_framedimensions;
+}
+
+static int dc_fw_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_pec;
+	void __iomem *base_cfg;
+	struct dc_fw *fw;
+	struct dc_fu *fu;
+	int i;
+
+	fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
+	if (!fw)
+		return -ENOMEM;
+
+	fu = &fw->fu;
+
+	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
+	if (IS_ERR(base_pec))
+		return PTR_ERR(base_pec);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	fu->reg_pec = devm_regmap_init_mmio(dev, base_pec,
+					    &dc_fw_pec_regmap_config);
+	if (IS_ERR(fu->reg_pec))
+		return PTR_ERR(fu->reg_pec);
+
+	fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_fw_cfg_regmap_config);
+	if (IS_ERR(fu->reg_cfg))
+		return PTR_ERR(fu->reg_cfg);
+
+	fw->id = of_alias_get_id(dev->of_node, "dc0-fetchwarp");
+	if (fw->id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", fw->id);
+		return fw->id;
+	}
+
+	fu->link_id = LINK_ID_FETCHWARP2;
+	fu->id = DC_FETCHUNIT_FW2;
+	for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
+		fu->reg_baseaddr[i]		  = BASEADDRESS(i);
+		fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
+		fu->reg_sourcebufferdimension[i]  = SOURCEBUFFERDIMENSION(i);
+		fu->reg_layeroffset[i]		  = LAYEROFFSET(i);
+		fu->reg_clipwindowoffset[i]	  = CLIPWINDOWOFFSET(i);
+		fu->reg_clipwindowdimensions[i]	  = CLIPWINDOWDIMENSIONS(i);
+		fu->reg_constantcolor[i]	  = CONSTANTCOLOR(i);
+		fu->reg_layerproperty[i]	  = LAYERPROPERTY(i);
+	}
+	snprintf(fu->name, sizeof(fu->name), "FetchWarp%u", fw->id);
+
+	dc_fw_set_ops(fu);
+
+	pe->fu_disp[fu->id] = fu;
+
+	return 0;
+}
+
+static const struct component_ops dc_fw_ops = {
+	.bind = dc_fw_bind,
+};
+
+static int dc_fw_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_fw_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_fw_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_fw_ops);
+}
+
+static const struct of_device_id dc_fw_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-fetchwarp", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_fw_dt_ids);
+
+struct platform_driver dc_fw_driver = {
+	.probe = dc_fw_probe,
+	.remove = dc_fw_remove,
+	.driver = {
+		.name = "imx8-dc-fetchwarp",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_fw_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
new file mode 100644
index 000000000000..af35d377126b
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-lb.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_blend.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_DYNAMIC			0x8
+#define  PIXENGCFG_DYNAMIC_PRIM_SEL_MASK	GENMASK(5, 0)
+#define  PIXENGCFG_DYNAMIC_PRIM_SEL(x)		\
+		FIELD_PREP(PIXENGCFG_DYNAMIC_PRIM_SEL_MASK, (x))
+#define  PIXENGCFG_DYNAMIC_SEC_SEL_MASK		GENMASK(13, 8)
+#define  PIXENGCFG_DYNAMIC_SEC_SEL(x)		\
+		FIELD_PREP(PIXENGCFG_DYNAMIC_SEC_SEL_MASK, (x))
+
+#define STATICCONTROL				0x8
+#define  SHDTOKSEL_MASK				GENMASK(4, 3)
+#define  SHDTOKSEL(x)				FIELD_PREP(SHDTOKSEL_MASK, (x))
+#define  SHDLDSEL_MASK				GENMASK(2, 1)
+#define  SHDLDSEL(x)				FIELD_PREP(SHDLDSEL_MASK, (x))
+
+#define CONTROL					0xc
+#define  CTRL_MODE_MASK				BIT(0)
+#define  CTRL_MODE(x)				FIELD_PREP(CTRL_MODE_MASK, (x))
+
+#define BLENDCONTROL				0x10
+#define  ALPHA_MASK				GENMASK(23, 16)
+#define  ALPHA(x)				FIELD_PREP(ALPHA_MASK, (x))
+#define  PRIM_C_BLD_FUNC_MASK			GENMASK(2, 0)
+#define  PRIM_C_BLD_FUNC(x)			\
+		FIELD_PREP(PRIM_C_BLD_FUNC_MASK, (x))
+#define  SEC_C_BLD_FUNC_MASK			GENMASK(6, 4)
+#define  SEC_C_BLD_FUNC(x)			\
+		FIELD_PREP(SEC_C_BLD_FUNC_MASK, (x))
+#define  PRIM_A_BLD_FUNC_MASK			GENMASK(10, 8)
+#define  PRIM_A_BLD_FUNC(x)			\
+		FIELD_PREP(PRIM_A_BLD_FUNC_MASK, (x))
+#define  SEC_A_BLD_FUNC_MASK			GENMASK(14, 12)
+#define  SEC_A_BLD_FUNC(x)			\
+		FIELD_PREP(SEC_A_BLD_FUNC_MASK, (x))
+
+#define POSITION				0x14
+#define  XPOS_MASK				GENMASK(15, 0)
+#define  XPOS(x)				FIELD_PREP(XPOS_MASK, (x))
+#define  YPOS_MASK				GENMASK(31, 16)
+#define  YPOS(x)				FIELD_PREP(YPOS_MASK, (x))
+
+enum dc_lb_blend_func {
+	DC_LAYERBLEND_BLEND_ZERO,
+	DC_LAYERBLEND_BLEND_ONE,
+	DC_LAYERBLEND_BLEND_PRIM_ALPHA,
+	DC_LAYERBLEND_BLEND_ONE_MINUS_PRIM_ALPHA,
+	DC_LAYERBLEND_BLEND_SEC_ALPHA,
+	DC_LAYERBLEND_BLEND_ONE_MINUS_SEC_ALPHA,
+	DC_LAYERBLEND_BLEND_CONST_ALPHA,
+	DC_LAYERBLEND_BLEND_ONE_MINUS_CONST_ALPHA,
+};
+
+enum dc_lb_shadow_sel {
+	BOTH = 0x2,
+};
+
+static const struct regmap_range dc_lb_pec_regmap_access_ranges[] = {
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+};
+
+static const struct regmap_access_table dc_lb_pec_regmap_access_table = {
+	.yes_ranges = dc_lb_pec_regmap_access_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_lb_pec_regmap_access_ranges),
+};
+
+static const struct regmap_config dc_lb_pec_regmap_config = {
+	.name = "layerblend-pec",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_lb_pec_regmap_access_table,
+	.rd_table = &dc_lb_pec_regmap_access_table,
+};
+
+static const struct regmap_range dc_lb_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, POSITION),
+};
+
+static const struct regmap_access_table dc_lb_regmap_access_table = {
+	.yes_ranges = dc_lb_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_lb_regmap_ranges),
+};
+
+static const struct regmap_config dc_lb_cfg_regmap_config = {
+	.name = "layerblend-cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_lb_regmap_access_table,
+	.rd_table = &dc_lb_regmap_access_table,
+};
+
+static const enum dc_link_id lb_links[] = {
+	LINK_ID_LAYERBLEND0,
+	LINK_ID_LAYERBLEND1,
+	LINK_ID_LAYERBLEND2,
+	LINK_ID_LAYERBLEND3,
+};
+
+static const enum dc_link_id prim_sels[] = {
+	/* common options */
+	LINK_ID_NONE,
+	LINK_ID_CONSTFRAME0,
+	LINK_ID_CONSTFRAME1,
+	LINK_ID_CONSTFRAME4,
+	LINK_ID_CONSTFRAME5,
+	/*
+	 * special options:
+	 * layerblend(n) has n special options,
+	 * from layerblend0 to layerblend(n - 1), e.g.,
+	 * layerblend3 has 3 special options -
+	 * layerblend0/1/2.
+	 */
+	LINK_ID_LAYERBLEND0,
+	LINK_ID_LAYERBLEND1,
+	LINK_ID_LAYERBLEND2,
+	LINK_ID_LAYERBLEND3,
+};
+
+static const enum dc_link_id sec_sels[] = {
+	LINK_ID_NONE,
+	LINK_ID_FETCHWARP2,
+	LINK_ID_FETCHLAYER0,
+};
+
+enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
+{
+	return lb->link;
+}
+
+void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim)
+{
+	int fixed_sels_num = ARRAY_SIZE(prim_sels) - 4;
+	int i;
+
+	for (i = 0; i < fixed_sels_num + lb->id; i++) {
+		if (prim_sels[i] == prim) {
+			regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
+					  PIXENGCFG_DYNAMIC_PRIM_SEL_MASK,
+					  PIXENGCFG_DYNAMIC_PRIM_SEL(prim));
+			return;
+		}
+	}
+}
+
+void dc_lb_pec_dynamic_sec_sel(struct dc_lb *lb, enum dc_link_id sec)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sec_sels); i++) {
+		if (sec_sels[i] == sec) {
+			regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
+					  PIXENGCFG_DYNAMIC_SEC_SEL_MASK,
+					  PIXENGCFG_DYNAMIC_SEC_SEL(sec));
+			return;
+		}
+	}
+}
+
+void dc_lb_pec_clken(struct dc_lb *lb, enum dc_pec_clken clken)
+{
+	regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC, CLKEN_MASK,
+			  CLKEN(clken));
+}
+
+static inline void dc_lb_enable_shden(struct dc_lb *lb)
+{
+	regmap_write_bits(lb->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_lb_shdtoksel(struct dc_lb *lb, enum dc_lb_shadow_sel sel)
+{
+	regmap_write_bits(lb->reg_cfg, STATICCONTROL, SHDTOKSEL_MASK,
+			  SHDTOKSEL(sel));
+}
+
+static inline void dc_lb_shdldsel(struct dc_lb *lb, enum dc_lb_shadow_sel sel)
+{
+	regmap_write_bits(lb->reg_cfg, STATICCONTROL, SHDLDSEL_MASK,
+			  SHDLDSEL(sel));
+}
+
+void dc_lb_mode(struct dc_lb *lb, enum dc_lb_mode mode)
+{
+	regmap_write_bits(lb->reg_cfg, CONTROL, CTRL_MODE_MASK, mode);
+}
+
+static inline void dc_lb_blendcontrol(struct dc_lb *lb)
+{
+	u32 val = PRIM_A_BLD_FUNC(DC_LAYERBLEND_BLEND_ZERO) |
+		  SEC_A_BLD_FUNC(DC_LAYERBLEND_BLEND_ZERO) |
+		  PRIM_C_BLD_FUNC(DC_LAYERBLEND_BLEND_ZERO) |
+		  SEC_C_BLD_FUNC(DC_LAYERBLEND_BLEND_CONST_ALPHA) |
+		  ALPHA(DRM_BLEND_ALPHA_OPAQUE >> 8);
+
+	regmap_write(lb->reg_cfg, BLENDCONTROL, val);
+}
+
+void dc_lb_position(struct dc_lb *lb, int x, int y)
+{
+	regmap_write(lb->reg_cfg, POSITION, XPOS(x) | YPOS(y));
+}
+
+unsigned int dc_lb_get_id(struct dc_lb *lb)
+{
+	return lb->id;
+}
+
+void dc_lb_init(struct dc_lb *lb)
+{
+	dc_lb_pec_dynamic_prim_sel(lb, LINK_ID_NONE);
+	dc_lb_pec_dynamic_sec_sel(lb, LINK_ID_NONE);
+	dc_lb_pec_clken(lb, CLKEN_DISABLE);
+	dc_lb_shdldsel(lb, BOTH);
+	dc_lb_shdtoksel(lb, BOTH);
+	dc_lb_blendcontrol(lb);
+	dc_lb_enable_shden(lb);
+}
+
+static int dc_lb_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_pec;
+	void __iomem *base_cfg;
+	struct dc_lb *lb;
+
+	lb = devm_kzalloc(dev, sizeof(*lb), GFP_KERNEL);
+	if (!lb)
+		return -ENOMEM;
+
+	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
+	if (IS_ERR(base_pec))
+		return PTR_ERR(base_pec);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	lb->reg_pec = devm_regmap_init_mmio(dev, base_pec,
+					    &dc_lb_pec_regmap_config);
+	if (IS_ERR(lb->reg_pec))
+		return PTR_ERR(lb->reg_pec);
+
+	lb->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_lb_cfg_regmap_config);
+	if (IS_ERR(lb->reg_cfg))
+		return PTR_ERR(lb->reg_cfg);
+
+	lb->id = of_alias_get_id(dev->of_node, "dc0-layerblend");
+	if (lb->id < 0) {
+		dev_err(dev, "failed to get alias id: %d\n", lb->id);
+		return lb->id;
+	}
+
+	lb->link = lb_links[lb->id];
+
+	pe->lb[lb->id] = lb;
+
+	return 0;
+}
+
+static const struct component_ops dc_lb_ops = {
+	.bind = dc_lb_bind,
+};
+
+static int dc_lb_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_lb_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_lb_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_lb_ops);
+}
+
+static const struct of_device_id dc_lb_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-layerblend", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_lb_dt_ids);
+
+struct platform_driver dc_lb_driver = {
+	.probe = dc_lb_probe,
+	.remove = dc_lb_remove,
+	.driver = {
+		.name = "imx8-dc-layerblend",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_lb_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.c b/drivers/gpu/drm/imx/dc/dc-pe.c
new file mode 100644
index 000000000000..459fc3823953
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-pe.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+static int dc_pe_bind(struct device *dev, struct device *master, void *data)
+{
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe;
+	int ret;
+
+	pe = devm_kzalloc(dev, sizeof(*pe), GFP_KERNEL);
+	if (!pe)
+		return -ENOMEM;
+
+	pe->clk_axi = devm_clk_get(dev, NULL);
+	if (IS_ERR(pe->clk_axi))
+		return dev_err_probe(dev, PTR_ERR(pe->clk_axi),
+				     "failed to get AXI clock\n");
+
+	pe->dev = dev;
+
+	dev_set_drvdata(dev, pe);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	dc_drm->pe = pe;
+
+	return 0;
+}
+
+static const struct component_ops dc_pe_ops = {
+	.bind = dc_pe_bind,
+};
+
+static int dc_pe_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = component_add(&pdev->dev, &dc_pe_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_pe_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_pe_ops);
+}
+
+static int dc_pe_runtime_suspend(struct device *dev)
+{
+	struct dc_pe *pe = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(pe->clk_axi);
+
+	return 0;
+}
+
+static int dc_pe_runtime_resume(struct device *dev)
+{
+	struct dc_pe *pe = dev_get_drvdata(dev);
+	int i, ret;
+
+	ret = clk_prepare_enable(pe->clk_axi);
+	if (ret) {
+		dev_err(dev, "failed to enable AXI clock: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pe->cf_safe); i++)
+		dc_cf_init(pe->cf_safe[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->cf_cont); i++)
+		dc_cf_init(pe->cf_cont[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->ed_safe); i++)
+		dc_ed_init(pe->ed_safe[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->ed_cont); i++)
+		dc_ed_init(pe->ed_cont[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->fu_disp); i++)
+		pe->fu_disp[i]->ops.init(pe->fu_disp[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->lb); i++)
+		dc_lb_init(pe->lb[i]);
+
+	return 0;
+}
+
+static const struct dev_pm_ops dc_pe_pm_ops = {
+	RUNTIME_PM_OPS(dc_pe_runtime_suspend, dc_pe_runtime_resume, NULL)
+};
+
+static const struct of_device_id dc_pe_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-pixel-engine", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_pe_dt_ids);
+
+struct platform_driver dc_pe_driver = {
+	.probe = dc_pe_probe,
+	.remove = dc_pe_remove,
+	.driver = {
+		.name = "imx8-dc-pixel-engine",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_pe_dt_ids,
+		.pm = pm_sleep_ptr(&dc_pe_pm_ops),
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
new file mode 100644
index 000000000000..d0c1080e58d8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-pe.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_PIXEL_ENGINE_H__
+#define __DC_PIXEL_ENGINE_H__
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+#include "dc-de.h"
+
+#define SHDEN			BIT(0)
+
+#define CLKEN_MASK_SHIFT	24
+#define CLKEN_MASK		(0x3 << CLKEN_MASK_SHIFT)
+#define CLKEN(n)		((n) << CLKEN_MASK_SHIFT)
+
+#define DC_DISP_FETCHUNIT_CNT	2
+#define DC_LAYERBLEND_CNT	4
+
+enum dc_link_id {
+	LINK_ID_NONE		= 0x00,
+	LINK_ID_CONSTFRAME0	= 0x0c,
+	LINK_ID_CONSTFRAME4	= 0x0e,
+	LINK_ID_CONSTFRAME1	= 0x10,
+	LINK_ID_CONSTFRAME5	= 0x12,
+	LINK_ID_FETCHWARP2	= 0x14,
+	LINK_ID_FETCHLAYER0	= 0x1a,
+	LINK_ID_LAYERBLEND0	= 0x21,
+	LINK_ID_LAYERBLEND1	= 0x22,
+	LINK_ID_LAYERBLEND2	= 0x23,
+	LINK_ID_LAYERBLEND3	= 0x24,
+};
+
+enum dc_lb_mode {
+	LB_NEUTRAL,	/* Output is same as primary input. */
+	LB_BLEND,
+};
+
+enum dc_pec_clken {
+	CLKEN_DISABLE,
+	CLKEN_AUTOMATIC,
+};
+
+struct dc_cf {
+	struct regmap *reg_cfg;
+	enum dc_link_id link;
+};
+
+struct dc_ed {
+	struct device *dev;
+	struct regmap *reg_pec;
+	struct regmap *reg_cfg;
+	int irq_shdld;
+};
+
+struct dc_lb {
+	struct regmap *reg_pec;
+	struct regmap *reg_cfg;
+	int id;
+	enum dc_link_id link;
+};
+
+struct dc_pe {
+	struct device *dev;
+	struct clk *clk_axi;
+	struct dc_cf *cf_safe[DC_DISPLAYS];
+	struct dc_cf *cf_cont[DC_DISPLAYS];
+	struct dc_ed *ed_safe[DC_DISPLAYS];
+	struct dc_ed *ed_cont[DC_DISPLAYS];
+	struct dc_fu *fu_disp[DC_DISP_FETCHUNIT_CNT];
+	struct dc_lb *lb[DC_LAYERBLEND_CNT];
+};
+
+/* Constant Frame Unit */
+enum dc_link_id dc_cf_get_link_id(struct dc_cf *cf);
+void dc_cf_framedimensions(struct dc_cf *cf, unsigned int w, unsigned int h);
+void dc_cf_constantcolor_black(struct dc_cf *cf);
+void dc_cf_constantcolor_blue(struct dc_cf *cf);
+void dc_cf_init(struct dc_cf *cf);
+
+/* External Destination Unit */
+void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src);
+void dc_ed_pec_sync_trigger(struct dc_ed *ed);
+void dc_ed_init(struct dc_ed *ed);
+
+/* Layer Blend Unit */
+enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb);
+void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim);
+void dc_lb_pec_dynamic_sec_sel(struct dc_lb *lb, enum dc_link_id sec);
+void dc_lb_pec_clken(struct dc_lb *lb, enum dc_pec_clken clken);
+void dc_lb_mode(struct dc_lb *lb, enum dc_lb_mode mode);
+void dc_lb_position(struct dc_lb *lb, int x, int y);
+unsigned int dc_lb_get_id(struct dc_lb *lb);
+void dc_lb_init(struct dc_lb *lb);
+
+#endif /* __DC_PIXEL_ENGINE_H__ */
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:15 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:15 +0800
Subject: [PATCH v6 11/19] drm/imx: Add i.MX8qxp Display Controller interrupt controller
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-12-victor.liu@nxp.com>

i.MX8qxp Display Controller has a built-in interrupt controller to support
Enable/Status/Preset/Clear interrupt bit.  Add driver for it.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* Replace .remove_new with .remove in dc-ic.c. (Uwe)

v4:
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_ic_data data strutures.
* Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
  interfaces to bind/unbind the driver.
* Take DC interrupt controller driver as a standalone driver instead of a
  component driver.
* Replace drmm_kcalloc() with devm_kcalloc() to allocate an array for
  struct dc_ic_entry.
* Call platform_get_irq() from DC interrupt controller driver to make sure
  parent interrupt controller driver is probed first.

v3:
* No change.

v2:
* No change.

 drivers/gpu/drm/imx/dc/Kconfig  |   1 +
 drivers/gpu/drm/imx/dc/Makefile |   2 +-
 drivers/gpu/drm/imx/dc/dc-drv.c |   1 +
 drivers/gpu/drm/imx/dc/dc-drv.h |   1 +
 drivers/gpu/drm/imx/dc/dc-ic.c  | 279 ++++++++++++++++++++++++++++++++
 5 files changed, 283 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ic.c

diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
index e1ef76d82830..1fc84c7475de 100644
--- a/drivers/gpu/drm/imx/dc/Kconfig
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -1,6 +1,7 @@
 config DRM_IMX8_DC
 	tristate "Freescale i.MX8 Display Controller Graphics"
 	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
+	select GENERIC_IRQ_CHIP
 	select REGMAP
 	select REGMAP_MMIO
 	help
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index 2942ae6fd5bd..1ce3e8a8db22 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
 imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
-		    dc-fw.o dc-lb.o dc-pe.o dc-tc.o
+		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
 
 obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index 7c64acc863ad..fd68861f770a 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -15,6 +15,7 @@ static struct platform_driver * const dc_drivers[] = {
 	&dc_fg_driver,
 	&dc_fl_driver,
 	&dc_fw_driver,
+	&dc_ic_driver,
 	&dc_lb_driver,
 	&dc_pe_driver,
 	&dc_tc_driver,
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index c687a36b8153..3b11f4862c6c 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -25,6 +25,7 @@ extern struct platform_driver dc_de_driver;
 extern struct platform_driver dc_fg_driver;
 extern struct platform_driver dc_fl_driver;
 extern struct platform_driver dc_fw_driver;
+extern struct platform_driver dc_ic_driver;
 extern struct platform_driver dc_lb_driver;
 extern struct platform_driver dc_pe_driver;
 extern struct platform_driver dc_tc_driver;
diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
new file mode 100644
index 000000000000..f022f0374772
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-ic.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#define USERINTERRUPTMASK(n)	(0x8 + 4 * (n))
+#define INTERRUPTENABLE(n)	(0x10 + 4 * (n))
+#define INTERRUPTPRESET(n)	(0x18 + 4 * (n))
+#define INTERRUPTCLEAR(n)	(0x20 + 4 * (n))
+#define INTERRUPTSTATUS(n)	(0x28 + 4 * (n))
+#define USERINTERRUPTENABLE(n)	(0x40 + 4 * (n))
+#define USERINTERRUPTPRESET(n)	(0x48 + 4 * (n))
+#define USERINTERRUPTCLEAR(n)	(0x50 + 4 * (n))
+#define USERINTERRUPTSTATUS(n)	(0x58 + 4 * (n))
+
+#define IRQ_COUNT	49
+#define IRQ_RESERVED	35
+#define REG_NUM		2
+
+struct dc_ic_data {
+	struct regmap		*regs;
+	struct clk		*clk_axi;
+	int			irq[IRQ_COUNT];
+	struct irq_domain	*domain;
+};
+
+struct dc_ic_entry {
+	struct dc_ic_data *data;
+	int irq;
+};
+
+static const struct regmap_range dc_ic_regmap_write_ranges[] = {
+	regmap_reg_range(USERINTERRUPTMASK(0), INTERRUPTCLEAR(1)),
+	regmap_reg_range(USERINTERRUPTENABLE(0), USERINTERRUPTCLEAR(1)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_write_table = {
+	.yes_ranges = dc_ic_regmap_write_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_write_ranges),
+};
+
+static const struct regmap_range dc_ic_regmap_read_ranges[] = {
+	regmap_reg_range(USERINTERRUPTMASK(0), USERINTERRUPTSTATUS(1)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_read_table = {
+	.yes_ranges = dc_ic_regmap_read_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_read_ranges),
+};
+
+static const struct regmap_range dc_ic_regmap_volatile_ranges[] = {
+	regmap_reg_range(INTERRUPTPRESET(0), INTERRUPTCLEAR(1)),
+	regmap_reg_range(USERINTERRUPTPRESET(0), USERINTERRUPTCLEAR(1)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_volatile_table = {
+	.yes_ranges = dc_ic_regmap_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_volatile_ranges),
+};
+
+static const struct regmap_config dc_ic_regmap_config = {
+	.name = "interrupt-controller",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_ic_regmap_write_table,
+	.rd_table = &dc_ic_regmap_read_table,
+	.volatile_table = &dc_ic_regmap_volatile_table,
+};
+
+static void dc_ic_irq_handler(struct irq_desc *desc)
+{
+	struct dc_ic_entry *entry = irq_desc_get_handler_data(desc);
+	struct dc_ic_data *data = entry->data;
+	unsigned int status, enable;
+	unsigned int virq;
+
+	chained_irq_enter(irq_desc_get_chip(desc), desc);
+
+	regmap_read(data->regs, USERINTERRUPTSTATUS(entry->irq / 32), &status);
+	regmap_read(data->regs, USERINTERRUPTENABLE(entry->irq / 32), &enable);
+
+	status &= enable;
+
+	if (status & BIT(entry->irq % 32)) {
+		virq = irq_linear_revmap(data->domain, entry->irq);
+		if (virq)
+			generic_handle_irq(virq);
+	}
+
+	chained_irq_exit(irq_desc_get_chip(desc), desc);
+}
+
+static const unsigned long unused_irq[REG_NUM] = {0x00000000, 0xfffe0008};
+
+static int dc_ic_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct irq_chip_generic *gc;
+	struct dc_ic_entry *entry;
+	struct irq_chip_type *ct;
+	struct dc_ic_data *data;
+	void __iomem *base;
+	int i, ret;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	entry = devm_kcalloc(dev, IRQ_COUNT, sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base)) {
+		dev_err(dev, "failed to initialize reg\n");
+		return PTR_ERR(base);
+	}
+
+	data->regs = devm_regmap_init_mmio(dev, base, &dc_ic_regmap_config);
+	if (IS_ERR(data->regs))
+		return PTR_ERR(data->regs);
+
+	data->clk_axi = devm_clk_get(dev, NULL);
+	if (IS_ERR(data->clk_axi))
+		return dev_err_probe(dev, PTR_ERR(data->clk_axi),
+				     "failed to get AXI clock\n");
+
+	for (i = 0; i < IRQ_COUNT; i++) {
+		/* skip the reserved IRQ */
+		if (i == IRQ_RESERVED)
+			continue;
+
+		ret = platform_get_irq(pdev, i);
+		if (ret < 0)
+			return ret;
+	}
+
+	dev_set_drvdata(dev, data);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0) {
+		dev_err(dev, "failed to get runtime PM sync: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < REG_NUM; i++) {
+		/* mask and clear all interrupts */
+		regmap_write(data->regs, USERINTERRUPTENABLE(i), 0x0);
+		regmap_write(data->regs, INTERRUPTENABLE(i), 0x0);
+		regmap_write(data->regs, USERINTERRUPTCLEAR(i), 0xffffffff);
+		regmap_write(data->regs, INTERRUPTCLEAR(i), 0xffffffff);
+
+		/* set all interrupts to user mode */
+		regmap_write(data->regs, USERINTERRUPTMASK(i), 0xffffffff);
+	}
+
+	data->domain = irq_domain_add_linear(dev->of_node, IRQ_COUNT,
+					     &irq_generic_chip_ops, data);
+	if (!data->domain) {
+		dev_err(dev, "failed to create IRQ domain\n");
+		pm_runtime_put(dev);
+		return -ENOMEM;
+	}
+	irq_domain_set_pm_device(data->domain, dev);
+
+	ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, "DC",
+					     handle_level_irq, 0, 0, 0);
+	if (ret) {
+		dev_err(dev, "failed to alloc generic IRQ chips: %d\n", ret);
+		irq_domain_remove(data->domain);
+		pm_runtime_put(dev);
+		return ret;
+	}
+
+	for (i = 0; i < IRQ_COUNT; i += 32) {
+		gc = irq_get_domain_generic_chip(data->domain, i);
+		gc->reg_base = base;
+		gc->unused = unused_irq[i / 32];
+		ct = gc->chip_types;
+		ct->chip.irq_ack = irq_gc_ack_set_bit;
+		ct->chip.irq_mask = irq_gc_mask_clr_bit;
+		ct->chip.irq_unmask = irq_gc_mask_set_bit;
+		ct->regs.ack = USERINTERRUPTCLEAR(i / 32);
+		ct->regs.mask = USERINTERRUPTENABLE(i / 32);
+	}
+
+	for (i = 0; i < IRQ_COUNT; i++) {
+		/* skip the reserved IRQ */
+		if (i == IRQ_RESERVED)
+			continue;
+
+		data->irq[i] = irq_of_parse_and_map(dev->of_node, i);
+
+		entry[i].data = data;
+		entry[i].irq = i;
+
+		irq_set_chained_handler_and_data(data->irq[i],
+						 dc_ic_irq_handler, &entry[i]);
+	}
+
+	return 0;
+}
+
+static void dc_ic_remove(struct platform_device *pdev)
+{
+	struct dc_ic_data *data = dev_get_drvdata(&pdev->dev);
+	int i;
+
+	for (i = 0; i < IRQ_COUNT; i++) {
+		if (i == IRQ_RESERVED)
+			continue;
+
+		irq_set_chained_handler_and_data(data->irq[i], NULL, NULL);
+	}
+
+	irq_domain_remove(data->domain);
+
+	pm_runtime_put_sync(&pdev->dev);
+}
+
+static int dc_ic_runtime_suspend(struct device *dev)
+{
+	struct dc_ic_data *data = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(data->clk_axi);
+
+	return 0;
+}
+
+static int dc_ic_runtime_resume(struct device *dev)
+{
+	struct dc_ic_data *data = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(data->clk_axi);
+	if (ret)
+		dev_err(dev, "failed to enable AXI clock: %d\n", ret);
+
+	return ret;
+}
+
+static const struct dev_pm_ops dc_ic_pm_ops = {
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				      pm_runtime_force_resume)
+	RUNTIME_PM_OPS(dc_ic_runtime_suspend, dc_ic_runtime_resume, NULL)
+};
+
+static const struct of_device_id dc_ic_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-intc", },
+	{ /* sentinel */ }
+};
+
+struct platform_driver dc_ic_driver = {
+	.probe = dc_ic_probe,
+	.remove = dc_ic_remove,
+	.driver = {
+		.name = "imx8-dc-intc",
+		.suppress_bind_attrs = true,
+		.of_match_table	= dc_ic_dt_ids,
+		.pm = pm_sleep_ptr(&dc_ic_pm_ops),
+	},
+};
-- 
2.34.1



From lkp at intel.com  Sun Dec  8 19:40:50 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 11:40:50 +0800
Subject: [PATCH 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <20241206172735.4310-3-towinchenmi@gmail.com>
References: <20241206172735.4310-3-towinchenmi@gmail.com>
Message-ID: <202412070721.9tZI9Ogl-lkp@intel.com>

Hi Nick,

kernel test robot noticed the following build errors:

[auto build test ERROR on 40384c840ea1944d7c5a392e8975ed088ecf0b37]

url:    https://github.com/intel-lab-lkp/linux/commits/Nick-Chan/dt-bindings-leds-backlight-apple-dwi-bl-Add-bindings-for-Apple-DWI-backlight/20241207-013254
base:   40384c840ea1944d7c5a392e8975ed088ecf0b37
patch link:    https://lore.kernel.org/r/20241206172735.4310-3-towinchenmi%40gmail.com
patch subject: [PATCH 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
config: arc-randconfig-001-20241207 (https://download.01.org/0day-ci/archive/20241207/202412070721.9tZI9Ogl-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241207/202412070721.9tZI9Ogl-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/202412070721.9tZI9Ogl-lkp at intel.com/

All errors (new ones prefixed by >>):

   drivers/video/backlight/dwi_bl.c: In function 'dwi_bl_update_status':
>> drivers/video/backlight/dwi_bl.c:46:16: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
      46 |         cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
         |                ^~~~~~~~~~
   drivers/video/backlight/dwi_bl.c: In function 'dwi_bl_get_brightness':
>> drivers/video/backlight/dwi_bl.c:61:16: error: implicit declaration of function 'FIELD_GET' [-Werror=implicit-function-declaration]
      61 |         return FIELD_GET(DWI_BL_CMD_DATA, cmd);
         |                ^~~~~~~~~
   cc1: some warnings being treated as errors


vim +/FIELD_PREP +46 drivers/video/backlight/dwi_bl.c

    37	
    38	static int dwi_bl_update_status(struct backlight_device *bl)
    39	{
    40		struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
    41	
    42		int brightness = backlight_get_brightness(bl);
    43	
    44		u32 cmd = 0;
    45	
  > 46		cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
    47		cmd |= FIELD_PREP(DWI_BL_CMD_TYPE, DWI_BL_CMD_TYPE_SET_BRIGHTNESS);
    48	
    49		writel(cmd, dwi_bl->base + DWI_BL_CMD);
    50		writel(DWI_BL_CTL_SEND, dwi_bl->base + DWI_BL_CTL);
    51	
    52		return 0;
    53	}
    54	
    55	static int dwi_bl_get_brightness(struct backlight_device *bl)
    56	{
    57		struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
    58	
    59		u32 cmd = readl(dwi_bl->base + DWI_BL_CMD);
    60	
  > 61		return FIELD_GET(DWI_BL_CMD_DATA, cmd);
    62	}
    63	

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


From victor.liu at nxp.com  Sun Dec  8 19:39:16 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:16 +0800
Subject: [PATCH v6 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-13-victor.liu@nxp.com>

i.MX8qxp Display Controller(DC) is comprised of three main components that
include a blit engine for 2D graphics accelerations, display controller for
display output processing, as well as a command sequencer.  Add kernel
mode setting support for the display controller part with two CRTCs and
two primary planes(backed by FetchLayer and FetchWarp respectively).  The
registers of the display controller are accessed without command sequencer
involved, instead just by using CPU.  The command sequencer is supposed to
be used by the blit engine.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* Replace .remove_new with .remove in dc-drv.c. (Uwe)

v4:
* Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
  function calls from KMS routine to initialization stage. (Dmitry)
* Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
  appropriate .h header files or .c source files. (Dmitry)
* Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
* Drop dc_drm->pe_rpm_count. (Dmitry)
* Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
* Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
  Instead, put it in struct dc_crtc.  (Dmitry)
* Call devm_request_irq() to request IRQs, instead of using drmm action.
  (Dmitry)
* Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
* Select DRM_CLIENT_SELECTION due to rebase.
* Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
* Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
* Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
  rebase.
* Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
  register dc_drm_component_unbind_all() action.
* Request interrupts in dc_crtc_post_init() after encoder initialization to
  make sure next bridge is found first.

v3:
* No change.

v2:
* Find next bridge from TCon's port.
* Drop drm/drm_module.h include from dc-drv.c.

 drivers/gpu/drm/imx/dc/Kconfig    |   5 +
 drivers/gpu/drm/imx/dc/Makefile   |   5 +-
 drivers/gpu/drm/imx/dc/dc-crtc.c  | 558 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
 drivers/gpu/drm/imx/dc/dc-drv.c   | 244 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-drv.h   |  19 +
 drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
 drivers/gpu/drm/imx/dc/dc-kms.h   |  58 ++++
 drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
 9 files changed, 1274 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c

diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
index 1fc84c7475de..415993207f2e 100644
--- a/drivers/gpu/drm/imx/dc/Kconfig
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -1,6 +1,11 @@
 config DRM_IMX8_DC
 	tristate "Freescale i.MX8 Display Controller Graphics"
 	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
+	select DRM_CLIENT_SELECTION
+	select DRM_GEM_DMA_HELPER
+	select DRM_KMS_HELPER
+	select DRM_DISPLAY_HELPER
+	select DRM_BRIDGE_CONNECTOR
 	select GENERIC_IRQ_CHIP
 	select REGMAP
 	select REGMAP_MMIO
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index 1ce3e8a8db22..b9d33c074984 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
-imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
-		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
+imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
+		    dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
+		    dc-plane.o dc-tc.o
 
 obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
new file mode 100644
index 000000000000..fd6daa1807d8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/completion.h>
+#include <linux/container_of.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/pm_runtime.h>
+#include <linux/spinlock.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_device.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_print.h>
+#include <drm/drm_vblank.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+#include "dc-kms.h"
+#include "dc-pe.h"
+
+#define dc_crtc_dbg(crtc, fmt, ...)					\
+do {									\
+	typeof(crtc) _crtc = (crtc);					\
+	drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
+		    _crtc->base.id, _crtc->name, ##__VA_ARGS__);	\
+} while (0)
+
+#define dc_crtc_err(crtc, fmt, ...)					\
+do {									\
+	typeof(crtc) _crtc = (crtc);					\
+	drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
+		_crtc->base.id, _crtc->name, ##__VA_ARGS__);		\
+} while (0)
+
+#define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c)				\
+do {									\
+	unsigned long ret;						\
+	ret = wait_for_completion_timeout(&dc_crtc->c, HZ);		\
+	if (ret == 0)							\
+		dc_crtc_err(crtc, "%s: wait for " #c " timeout\n",	\
+							__func__);	\
+} while (0)
+
+#define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg)					\
+do {									\
+	typeof(fg) _fg = (fg);						\
+	if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) {		\
+		dc_fg_secondary_clear_channel_status(_fg);		\
+		dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n",		\
+							__func__);	\
+	}								\
+} while (0)
+
+#define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg)			\
+do {									\
+	if (dc_fg_wait_for_secondary_syncup(fg))			\
+		dc_crtc_err(crtc,					\
+			"%s: FrameGen secondary channel isn't syncup\n",\
+							__func__);	\
+} while (0)
+
+static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct dc_crtc, base);
+}
+
+static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	return dc_fg_get_frame_index(dc_crtc->fg);
+}
+
+static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	enable_irq(dc_crtc->irq_dec_framecomplete);
+
+	return 0;
+}
+
+static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	disable_irq_nosync(dc_crtc->irq_dec_framecomplete);
+}
+
+static irqreturn_t
+dc_crtc_dec_framecomplete_irq_handler(int irq, void *dev_id)
+{
+	struct dc_crtc *dc_crtc = dev_id;
+	struct drm_crtc *crtc = &dc_crtc->base;
+	unsigned long flags;
+
+	drm_crtc_handle_vblank(crtc);
+
+	spin_lock_irqsave(&crtc->dev->event_lock, flags);
+	if (dc_crtc->event) {
+		drm_crtc_send_vblank_event(crtc, dc_crtc->event);
+		dc_crtc->event = NULL;
+		drm_crtc_vblank_put(crtc);
+	}
+	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dc_crtc_common_irq_handler(int irq, void *dev_id)
+{
+	struct dc_crtc *dc_crtc = dev_id;
+
+	if (irq == dc_crtc->irq_dec_seqcomplete)
+		complete(&dc_crtc->dec_seqcomplete_done);
+	else if (irq == dc_crtc->irq_dec_shdld)
+		complete(&dc_crtc->dec_shdld_done);
+	else if (irq == dc_crtc->irq_ed_cont_shdld)
+		complete(&dc_crtc->ed_cont_shdld_done);
+	else if (irq == dc_crtc->irq_ed_safe_shdld)
+		complete(&dc_crtc->ed_safe_shdld_done);
+
+	return IRQ_HANDLED;
+}
+
+static const struct drm_crtc_funcs dc_crtc_funcs = {
+	.reset			= drm_atomic_helper_crtc_reset,
+	.destroy		= drm_crtc_cleanup,
+	.set_config		= drm_atomic_helper_set_config,
+	.page_flip		= drm_atomic_helper_page_flip,
+	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
+	.get_vblank_counter	= dc_crtc_get_vblank_counter,
+	.enable_vblank		= dc_crtc_enable_vblank,
+	.disable_vblank		= dc_crtc_disable_vblank,
+	.get_vblank_timestamp	= drm_crtc_vblank_helper_get_vblank_timestamp,
+};
+
+static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
+{
+	struct drm_crtc *crtc = crtc_state->crtc;
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	spin_lock_irq(&crtc->dev->event_lock);
+	if (crtc_state->event) {
+		WARN_ON(drm_crtc_vblank_get(crtc));
+		WARN_ON(dc_crtc->event);
+		dc_crtc->event = crtc_state->event;
+		crtc_state->event = NULL;
+	}
+	spin_unlock_irq(&crtc->dev->event_lock);
+}
+
+static enum drm_mode_status
+dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
+{
+	return dc_fg_check_clock(dc_crtc->fg, clk_khz);
+}
+
+static enum drm_mode_status
+dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	enum drm_mode_status status;
+
+	status = dc_crtc_check_clock(dc_crtc, mode->clock);
+	if (status != MODE_OK)
+		return status;
+
+	if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static int
+dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	enum drm_mode_status status;
+
+	status = dc_crtc_check_clock(dc_crtc, adj->clock);
+	if (status != MODE_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void
+dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int idx, ret;
+
+	if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
+	    !new_crtc_state->active)
+		return;
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		return;
+
+	/* request pixel engine power-on when CRTC starts to be active */
+	ret = pm_runtime_resume_and_get(dc_crtc->pe->dev);
+	if (ret)
+		dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
+			    ret);
+
+	drm_dev_exit(idx);
+}
+
+static void
+dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *old_crtc_state =
+				drm_atomic_get_old_crtc_state(state, crtc);
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int idx;
+
+	if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
+	    (!old_crtc_state->active && !new_crtc_state->active))
+		return;
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		goto out;
+
+	enable_irq(dc_crtc->irq_ed_cont_shdld);
+
+	/* flush plane update out to display */
+	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
+
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
+
+	disable_irq(dc_crtc->irq_ed_cont_shdld);
+
+	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
+
+	drm_dev_exit(idx);
+
+out:
+	dc_crtc_queue_state_event(new_crtc_state);
+}
+
+static void
+dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	enum dc_link_id cf_link;
+	int idx, ret;
+
+	dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
+
+	drm_crtc_vblank_on(crtc);
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		goto out;
+
+	/* request display engine power-on when CRTC is enabled */
+	ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
+	if (ret < 0)
+		dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
+			    ret);
+
+	enable_irq(dc_crtc->irq_dec_shdld);
+	enable_irq(dc_crtc->irq_ed_cont_shdld);
+	enable_irq(dc_crtc->irq_ed_safe_shdld);
+
+	dc_fg_cfg_videomode(dc_crtc->fg, adj);
+
+	dc_cf_framedimensions(dc_crtc->cf_cont,
+			      adj->crtc_hdisplay, adj->crtc_vdisplay);
+	dc_cf_framedimensions(dc_crtc->cf_safe,
+			      adj->crtc_hdisplay, adj->crtc_vdisplay);
+
+	/* constframe in safety stream shows blue frame */
+	dc_cf_constantcolor_blue(dc_crtc->cf_safe);
+	cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
+	dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
+
+	/* show CRTC background if no plane is enabled */
+	if (new_crtc_state->plane_mask == 0) {
+		/* constframe in content stream shows black frame */
+		dc_cf_constantcolor_black(dc_crtc->cf_cont);
+
+		cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
+		dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
+	}
+
+	dc_fg_enable_clock(dc_crtc->fg);
+	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
+	dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
+	dc_fg_shdtokgen(dc_crtc->fg);
+	dc_fg_enable(dc_crtc->fg);
+
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdld_done);
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdld_done);
+
+	disable_irq(dc_crtc->irq_ed_safe_shdld);
+	disable_irq(dc_crtc->irq_ed_cont_shdld);
+	disable_irq(dc_crtc->irq_dec_shdld);
+
+	DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
+
+	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
+
+	drm_dev_exit(idx);
+
+out:
+	dc_crtc_queue_state_event(new_crtc_state);
+}
+
+static void
+dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int idx, ret;
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		goto out;
+
+	enable_irq(dc_crtc->irq_dec_seqcomplete);
+	dc_fg_disable(dc_crtc->fg);
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
+	disable_irq(dc_crtc->irq_dec_seqcomplete);
+
+	dc_fg_disable_clock(dc_crtc->fg);
+
+	/* request pixel engine power-off as plane is off too */
+	ret = pm_runtime_put(dc_crtc->pe->dev);
+	if (ret)
+		dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
+			    ret);
+
+	/* request display engine power-off when CRTC is disabled */
+	ret = pm_runtime_put(dc_crtc->de->dev);
+	if (ret < 0)
+		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
+			    ret);
+
+	drm_dev_exit(idx);
+
+out:
+	drm_crtc_vblank_off(crtc);
+
+	spin_lock_irq(&crtc->dev->event_lock);
+	if (new_crtc_state->event && !new_crtc_state->active) {
+		drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
+		new_crtc_state->event = NULL;
+	}
+	spin_unlock_irq(&crtc->dev->event_lock);
+}
+
+void dc_crtc_disable_at_unbind(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int ret;
+
+	if (!dc_fg_wait_for_frame_index_moving(dc_crtc->fg))
+		return;
+
+	dc_fg_disable_clock(dc_crtc->fg);
+
+	if (pm_runtime_active(dc_crtc->pe->dev)) {
+		ret = pm_runtime_put_sync(dc_crtc->pe->dev);
+		if (ret)
+			dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
+				    ret);
+	}
+
+	ret = pm_runtime_put_sync(dc_crtc->de->dev);
+	if (ret < 0)
+		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
+			    ret);
+}
+
+static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
+					 bool in_vblank_irq,
+					 int *vpos, int *hpos,
+					 ktime_t *stime, ktime_t *etime,
+					 const struct drm_display_mode *mode)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int vdisplay = mode->crtc_vdisplay;
+	int vtotal = mode->crtc_vtotal;
+	bool reliable;
+	int line;
+	int idx;
+
+	if (stime)
+		*stime = ktime_get();
+
+	if (!drm_dev_enter(crtc->dev, &idx)) {
+		reliable = false;
+		*vpos = 0;
+		*hpos = 0;
+		goto out;
+	}
+
+	/* line index starts with 0 for the first active output line */
+	line = dc_fg_get_line_index(dc_crtc->fg);
+
+	if (line < vdisplay)
+		/* active scanout area - positive */
+		*vpos = line + 1;
+	else
+		/* inside vblank - negative */
+		*vpos = line - (vtotal - 1);
+
+	*hpos = 0;
+
+	reliable = true;
+
+	drm_dev_exit(idx);
+out:
+	if (etime)
+		*etime = ktime_get();
+
+	return reliable;
+}
+
+static const struct drm_crtc_helper_funcs dc_helper_funcs = {
+	.mode_valid		= dc_crtc_mode_valid,
+	.atomic_check		= dc_crtc_atomic_check,
+	.atomic_begin		= dc_crtc_atomic_begin,
+	.atomic_flush		= dc_crtc_atomic_flush,
+	.atomic_enable		= dc_crtc_atomic_enable,
+	.atomic_disable		= dc_crtc_atomic_disable,
+	.get_scanout_position	= dc_crtc_get_scanout_position,
+};
+
+static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
+{
+	struct {
+		struct device *dev;
+		unsigned int irq;
+		irqreturn_t (*irq_handler)(int irq, void *dev_id);
+	} irqs[DC_CRTC_IRQS] = {
+		{
+			dc_crtc->de->dev,
+			dc_crtc->irq_dec_framecomplete,
+			dc_crtc_dec_framecomplete_irq_handler,
+		}, {
+			dc_crtc->de->dev,
+			dc_crtc->irq_dec_seqcomplete,
+			dc_crtc_common_irq_handler,
+		}, {
+			dc_crtc->de->dev,
+			dc_crtc->irq_dec_shdld,
+			dc_crtc_common_irq_handler,
+		}, {
+			dc_crtc->ed_cont->dev,
+			dc_crtc->irq_ed_cont_shdld,
+			dc_crtc_common_irq_handler,
+		}, {
+			dc_crtc->ed_safe->dev,
+			dc_crtc->irq_ed_safe_shdld,
+			dc_crtc_common_irq_handler,
+		},
+	};
+	int i, ret;
+
+	for (i = 0; i < DC_CRTC_IRQS; i++) {
+		struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
+
+		ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
+				       irqs[i].irq_handler, IRQF_NO_AUTOEN,
+				       dev_name(irqs[i].dev), dc_crtc);
+		if (ret) {
+			dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
+				irqs[i].irq, ret);
+			return ret;
+		}
+
+		irq->dc_crtc = dc_crtc;
+		irq->irq = irqs[i].irq;
+	}
+
+	return 0;
+}
+
+int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
+{
+	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
+	struct drm_device *drm = &dc_drm->base;
+	struct dc_de *de = dc_drm->de[crtc_index];
+	struct dc_pe *pe = dc_drm->pe;
+	struct dc_plane *dc_primary;
+	int ret;
+
+	dc_crtc->de = de;
+	dc_crtc->pe = pe;
+
+	init_completion(&dc_crtc->dec_seqcomplete_done);
+	init_completion(&dc_crtc->dec_shdld_done);
+	init_completion(&dc_crtc->ed_cont_shdld_done);
+	init_completion(&dc_crtc->ed_safe_shdld_done);
+
+	dc_crtc->cf_cont = pe->cf_cont[crtc_index];
+	dc_crtc->cf_safe = pe->cf_safe[crtc_index];
+	dc_crtc->ed_cont = pe->ed_cont[crtc_index];
+	dc_crtc->ed_safe = pe->ed_safe[crtc_index];
+	dc_crtc->fg = de->fg;
+
+	dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
+	dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
+	dc_crtc->irq_dec_shdld = de->irq_shdld;
+	dc_crtc->irq_ed_safe_shdld = dc_crtc->ed_safe->irq_shdld;
+	dc_crtc->irq_ed_cont_shdld = dc_crtc->ed_cont->irq_shdld;
+
+	dc_primary = &dc_drm->dc_primary[crtc_index];
+	ret = dc_plane_init(dc_drm, dc_primary);
+	if (ret) {
+		dev_err(drm->dev,
+			"failed to init primary plane for display engine%u: %d\n",
+			de->id, ret);
+		return ret;
+	}
+
+	drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
+
+	ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
+					NULL, &dc_crtc_funcs, NULL);
+	if (ret)
+		dev_err(drm->dev,
+			"failed to add CRTC for display engine%u: %d\n",
+			de->id, ret);
+
+	return ret;
+}
+
+int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
+{
+	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
+	struct drm_device *drm = &dc_drm->base;
+
+	return dc_crtc_request_irqs(drm, dc_crtc);
+}
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
index 17a44362118e..8a7b6c03a222 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.h
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -13,6 +13,9 @@
 
 #define DC_DISPLAYS	2
 
+#define DC_FRAMEGEN_MAX_FRAME_INDEX	0x3ffff
+#define DC_FRAMEGEN_MAX_CLOCK_KHZ	300000
+
 struct dc_fg {
 	struct device *dev;
 	struct regmap *reg;
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index fd68861f770a..1e4b8afa3eec 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -3,11 +3,254 @@
  * Copyright 2024 NXP
  */
 
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
 
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_client_setup.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fbdev_dma.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_modeset_helper.h>
+#include <drm/drm_of.h>
+
+#include "dc-de.h"
 #include "dc-drv.h"
 
+struct dc_priv {
+	struct drm_device *drm;
+	struct clk *clk_cfg;
+};
+
+DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
+
+static struct drm_driver dc_drm_driver = {
+	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
+	DRM_GEM_DMA_DRIVER_OPS,
+	DRM_FBDEV_DMA_DRIVER_OPS,
+	.fops = &dc_drm_driver_fops,
+	.name = "imx8-dc",
+	.desc = "i.MX8 DC DRM graphics",
+	.date = "20240530",
+	.major = 1,
+	.minor = 0,
+	.patchlevel = 0,
+};
+
+static void
+dc_add_components(struct device *dev, struct component_match **matchptr)
+{
+	struct device_node *child, *grandchild;
+
+	for_each_available_child_of_node(dev->of_node, child) {
+		/* The interrupt controller is not a component. */
+		if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
+			continue;
+
+		drm_of_component_match_add(dev, matchptr, component_compare_of,
+					   child);
+
+		for_each_available_child_of_node(child, grandchild)
+			drm_of_component_match_add(dev, matchptr,
+						   component_compare_of,
+						   grandchild);
+	}
+}
+
+static void dc_drm_component_unbind_all(void *ptr)
+{
+	struct dc_drm_device *dc_drm = ptr;
+	struct drm_device *drm = &dc_drm->base;
+
+	component_unbind_all(drm->dev, dc_drm);
+}
+
+static int dc_drm_bind(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+	struct dc_drm_device *dc_drm;
+	struct drm_device *drm;
+	int ret;
+
+	dc_drm = devm_drm_dev_alloc(dev, &dc_drm_driver, struct dc_drm_device,
+				    base);
+	if (IS_ERR(dc_drm))
+		return PTR_ERR(dc_drm);
+
+	drm = &dc_drm->base;
+
+	ret = component_bind_all(dev, dc_drm);
+	if (ret)
+		return ret;
+
+	ret = devm_add_action_or_reset(dev, dc_drm_component_unbind_all,
+				       dc_drm);
+	if (ret)
+		return ret;
+
+	ret = dc_kms_init(dc_drm);
+	if (ret)
+		return ret;
+
+	ret = drm_dev_register(drm, 0);
+	if (ret) {
+		dev_err(dev, "failed to register drm device: %d\n", ret);
+		goto err;
+	}
+
+	drm_client_setup_with_fourcc(drm, DRM_FORMAT_XRGB8888);
+
+	priv->drm = drm;
+
+	return 0;
+
+err:
+	dc_kms_uninit(dc_drm);
+
+	return ret;
+}
+
+static void dc_drm_unbind(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+	struct dc_drm_device *dc_drm = to_dc_drm_device(priv->drm);
+	struct drm_device *drm = &dc_drm->base;
+	struct drm_crtc *crtc;
+
+	priv->drm = NULL;
+	drm_dev_unplug(drm);
+	dc_kms_uninit(dc_drm);
+	drm_atomic_helper_shutdown(drm);
+
+	drm_for_each_crtc(crtc, drm)
+		dc_crtc_disable_at_unbind(crtc);
+}
+
+static const struct component_master_ops dc_drm_ops = {
+	.bind = dc_drm_bind,
+	.unbind = dc_drm_unbind,
+};
+
+static int dc_probe(struct platform_device *pdev)
+{
+	struct component_match *match = NULL;
+	struct dc_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->clk_cfg))
+		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
+				     "failed to get cfg clock\n");
+
+	dev_set_drvdata(&pdev->dev, priv);
+
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret)
+		return ret;
+
+	dc_add_components(&pdev->dev, &match);
+
+	ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component master\n");
+
+	return 0;
+}
+
+static void dc_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &dc_drm_ops);
+}
+
+static int dc_runtime_suspend(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(priv->clk_cfg);
+
+	return 0;
+}
+
+static int dc_runtime_resume(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(priv->clk_cfg);
+	if (ret)
+		dev_err(dev, "failed to enable cfg clock: %d\n", ret);
+
+	return ret;
+}
+
+static int dc_suspend(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+
+	return drm_mode_config_helper_suspend(priv->drm);
+}
+
+static int dc_resume(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+
+	return drm_mode_config_helper_resume(priv->drm);
+}
+
+static void dc_shutdown(struct platform_device *pdev)
+{
+	struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
+
+	drm_atomic_helper_shutdown(priv->drm);
+}
+
+static const struct dev_pm_ops dc_pm_ops = {
+	RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
+	SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
+};
+
+static const struct of_device_id dc_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_dt_ids);
+
+static struct platform_driver dc_driver = {
+	.probe = dc_probe,
+	.remove = dc_remove,
+	.shutdown = dc_shutdown,
+	.driver = {
+		.name = "imx8-dc",
+		.of_match_table	= dc_dt_ids,
+		.pm = pm_sleep_ptr(&dc_pm_ops),
+	},
+};
+
 static struct platform_driver * const dc_drivers[] = {
 	&dc_cf_driver,
 	&dc_de_driver,
@@ -19,6 +262,7 @@ static struct platform_driver * const dc_drivers[] = {
 	&dc_lb_driver,
 	&dc_pe_driver,
 	&dc_tc_driver,
+	&dc_driver,
 };
 
 static int __init dc_drm_init(void)
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index 3b11f4862c6c..39a771a13933 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -6,19 +6,38 @@
 #ifndef __DC_DRV_H__
 #define __DC_DRV_H__
 
+#include <linux/container_of.h>
 #include <linux/platform_device.h>
 
 #include <drm/drm_device.h>
+#include <drm/drm_encoder.h>
 
 #include "dc-de.h"
+#include "dc-kms.h"
 #include "dc-pe.h"
 
 struct dc_drm_device {
 	struct drm_device base;
+	struct dc_crtc dc_crtc[DC_DISPLAYS];
+	struct dc_plane dc_primary[DC_DISPLAYS];
+	struct drm_encoder encoder[DC_DISPLAYS];
 	struct dc_de *de[DC_DISPLAYS];
 	struct dc_pe *pe;
 };
 
+static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
+{
+	return container_of(drm, struct dc_drm_device, base);
+}
+
+int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
+int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
+
+int dc_kms_init(struct dc_drm_device *dc_drm);
+void dc_kms_uninit(struct dc_drm_device *dc_drm);
+
+int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
+
 extern struct platform_driver dc_cf_driver;
 extern struct platform_driver dc_ed_driver;
 extern struct platform_driver dc_de_driver;
diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
new file mode 100644
index 000000000000..2b18aa37a4a8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-kms.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/of.h>
+#include <linux/of_graph.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_device.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_mode_config.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_vblank.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+#include "dc-kms.h"
+
+static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
+	.fb_create = drm_gem_fb_create,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
+};
+
+static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
+					int crtc_index)
+{
+	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
+	struct drm_device *drm = &dc_drm->base;
+	struct drm_crtc *crtc = &dc_crtc->base;
+	struct drm_connector *connector;
+	struct device *dev = drm->dev;
+	struct drm_encoder *encoder;
+	struct drm_bridge *bridge;
+	int ret;
+
+	bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
+					0, 0);
+	if (IS_ERR(bridge)) {
+		ret = PTR_ERR(bridge);
+		if (ret == -ENODEV)
+			return 0;
+
+		return dev_err_probe(dev, ret,
+				     "failed to find bridge for CRTC%u\n",
+				     crtc->index);
+	}
+
+	encoder = &dc_drm->encoder[crtc_index];
+	ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
+	if (ret) {
+		dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
+			crtc->index, ret);
+		return ret;
+	}
+
+	encoder->possible_crtcs = drm_crtc_mask(crtc);
+
+	ret = drm_bridge_attach(encoder, bridge, NULL,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret) {
+		dev_err(dev,
+			"failed to attach bridge to encoder for CRTC%u: %d\n",
+			crtc->index, ret);
+		return ret;
+	}
+
+	connector = drm_bridge_connector_init(drm, encoder);
+	if (IS_ERR(connector)) {
+		ret = PTR_ERR(connector);
+		dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
+			crtc->index, ret);
+		return ret;
+	}
+
+	ret = drm_connector_attach_encoder(connector, encoder);
+	if (ret)
+		dev_err(dev,
+			"failed to attach encoder to connector for CRTC%u: %d\n",
+			crtc->index, ret);
+
+	return ret;
+}
+
+int dc_kms_init(struct dc_drm_device *dc_drm)
+{
+	struct drm_device *drm = &dc_drm->base;
+	int ret, i;
+
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
+
+	drm->mode_config.min_width = 60;
+	drm->mode_config.min_height = 60;
+	drm->mode_config.max_width = 8192;
+	drm->mode_config.max_height = 8192;
+	drm->mode_config.funcs = &dc_drm_mode_config_funcs;
+
+	drm->vblank_disable_immediate = true;
+	drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
+
+	for (i = 0; i < DC_DISPLAYS; i++) {
+		ret = dc_crtc_init(dc_drm, i);
+		if (ret)
+			return ret;
+
+		ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < DC_DISPLAYS; i++) {
+		ret = dc_crtc_post_init(dc_drm, i);
+		if (ret)
+			return ret;
+	}
+
+	ret = drm_vblank_init(drm, DC_DISPLAYS);
+	if (ret) {
+		dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
+		return ret;
+	}
+
+	drm_mode_config_reset(drm);
+
+	drm_kms_helper_poll_init(drm);
+
+	return 0;
+}
+
+void dc_kms_uninit(struct dc_drm_device *dc_drm)
+{
+	drm_kms_helper_poll_fini(&dc_drm->base);
+}
diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
new file mode 100644
index 000000000000..57f6e0c15f57
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-kms.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_KMS_H__
+#define __DC_KMS_H__
+
+#include <linux/completion.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_vblank.h>
+
+#include "dc-de.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+#define DC_CRTC_IRQS	5
+
+struct dc_crtc_irq {
+	struct dc_crtc *dc_crtc;
+	unsigned int irq;
+};
+
+struct dc_crtc {
+	struct drm_crtc base;
+	struct dc_de *de;
+	struct dc_pe *pe;
+	struct dc_cf *cf_cont;
+	struct dc_cf *cf_safe;
+	struct dc_ed *ed_cont;
+	struct dc_ed *ed_safe;
+	struct dc_fg *fg;
+	unsigned int irq_dec_framecomplete;
+	unsigned int irq_dec_seqcomplete;
+	unsigned int irq_dec_shdld;
+	unsigned int irq_ed_cont_shdld;
+	unsigned int irq_ed_safe_shdld;
+	struct completion dec_seqcomplete_done;
+	struct completion dec_shdld_done;
+	struct completion ed_safe_shdld_done;
+	struct completion ed_cont_shdld_done;
+	struct drm_pending_vblank_event *event;
+	struct dc_crtc_irq irqs[DC_CRTC_IRQS];
+};
+
+struct dc_plane {
+	struct drm_plane base;
+	struct dc_fu *fu;
+	struct dc_cf *cf;
+	struct dc_lb *lb;
+	struct dc_ed *ed;
+};
+
+void dc_crtc_disable_at_unbind(struct drm_crtc *crtc);
+
+#endif /* __DC_KMS_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
new file mode 100644
index 000000000000..78d0d2cd3451
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-plane.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/container_of.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fb_dma_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_print.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-kms.h"
+
+#define DC_PLANE_MAX_PITCH	0x10000
+#define DC_PLANE_MAX_PIX_CNT	8192
+
+#define dc_plane_dbg(plane, fmt, ...)					\
+do {									\
+	typeof(plane) _plane = (plane);					\
+	drm_dbg_kms(_plane->dev, "[PLANE:%d:%s] " fmt,			\
+		    _plane->base.id, _plane->name, ##__VA_ARGS__);	\
+} while (0)
+
+static const uint32_t dc_plane_formats[] = {
+	DRM_FORMAT_XRGB8888,
+};
+
+static const struct drm_plane_funcs dc_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,
+};
+
+static inline struct dc_plane *to_dc_plane(struct drm_plane *plane)
+{
+	return container_of(plane, struct dc_plane, base);
+}
+
+static int dc_plane_check_no_off_screen(struct drm_plane_state *state,
+					struct drm_crtc_state *crtc_state)
+{
+	if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
+	    state->dst.x2 > crtc_state->adjusted_mode.hdisplay ||
+	    state->dst.y2 > crtc_state->adjusted_mode.vdisplay) {
+		dc_plane_dbg(state->plane, "no off screen\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dc_plane_check_max_source_resolution(struct drm_plane_state *state)
+{
+	int src_h = drm_rect_height(&state->src) >> 16;
+	int src_w = drm_rect_width(&state->src) >> 16;
+
+	if (src_w > DC_PLANE_MAX_PIX_CNT || src_h > DC_PLANE_MAX_PIX_CNT) {
+		dc_plane_dbg(state->plane, "invalid source resolution\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dc_plane_check_fb(struct drm_plane_state *state)
+{
+	struct drm_framebuffer *fb = state->fb;
+	dma_addr_t baseaddr = drm_fb_dma_get_gem_addr(fb, state, 0);
+
+	/* base address alignment */
+	if (baseaddr & 0x3) {
+		dc_plane_dbg(state->plane, "fb bad baddr alignment\n");
+		return -EINVAL;
+	}
+
+	/* pitches[0] range */
+	if (fb->pitches[0] > DC_PLANE_MAX_PITCH) {
+		dc_plane_dbg(state->plane, "fb pitches[0] is out of range\n");
+		return -EINVAL;
+	}
+
+	/* pitches[0] alignment */
+	if (fb->pitches[0] & 0x3) {
+		dc_plane_dbg(state->plane, "fb bad pitches[0] alignment\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+dc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
+{
+	struct drm_plane_state *plane_state =
+				drm_atomic_get_new_plane_state(state, plane);
+	struct drm_crtc_state *crtc_state;
+	int ret;
+
+	/* ok to disable */
+	if (!plane_state->fb)
+		return 0;
+
+	if (!plane_state->crtc) {
+		dc_plane_dbg(plane, "no CRTC in plane state\n");
+		return -EINVAL;
+	}
+
+	crtc_state =
+		drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return -EINVAL;
+
+	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
+						  DRM_PLANE_NO_SCALING,
+						  DRM_PLANE_NO_SCALING,
+						  true, false);
+	if (ret) {
+		dc_plane_dbg(plane, "failed to check plane state: %d\n", ret);
+		return ret;
+	}
+
+	ret = dc_plane_check_no_off_screen(plane_state, crtc_state);
+	if (ret)
+		return ret;
+
+	ret = dc_plane_check_max_source_resolution(plane_state);
+	if (ret)
+		return ret;
+
+	return dc_plane_check_fb(plane_state);
+}
+
+static void
+dc_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_state =
+				drm_atomic_get_new_plane_state(state, plane);
+	struct dc_plane *dplane = to_dc_plane(plane);
+	struct drm_framebuffer *fb = new_state->fb;
+	const struct dc_fu_ops *fu_ops;
+	struct dc_lb *lb = dplane->lb;
+	struct dc_fu *fu = dplane->fu;
+	dma_addr_t baseaddr;
+	int src_w, src_h;
+	int idx;
+
+	if (!drm_dev_enter(plane->dev, &idx))
+		return;
+
+	src_w = drm_rect_width(&new_state->src) >> 16;
+	src_h = drm_rect_height(&new_state->src) >> 16;
+
+	baseaddr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
+
+	fu_ops = dc_fu_get_ops(dplane->fu);
+
+	fu_ops->set_layerblend(fu, lb);
+	fu_ops->set_burstlength(fu, baseaddr);
+	fu_ops->set_src_stride(fu, DC_FETCHUNIT_FRAC0, fb->pitches[0]);
+	fu_ops->set_src_buf_dimensions(fu, DC_FETCHUNIT_FRAC0, src_w, src_h);
+	fu_ops->set_fmt(fu, DC_FETCHUNIT_FRAC0, fb->format);
+	fu_ops->set_framedimensions(fu, src_w, src_h);
+	fu_ops->set_baseaddress(fu, DC_FETCHUNIT_FRAC0, baseaddr);
+	fu_ops->enable_src_buf(fu, DC_FETCHUNIT_FRAC0);
+
+	dc_plane_dbg(plane, "uses %s\n", fu_ops->get_name(fu));
+
+	dc_lb_pec_dynamic_prim_sel(lb, dc_cf_get_link_id(dplane->cf));
+	dc_lb_pec_dynamic_sec_sel(lb, fu_ops->get_link_id(fu));
+	dc_lb_mode(lb, LB_BLEND);
+	dc_lb_position(lb, new_state->dst.x1, new_state->dst.y1);
+	dc_lb_pec_clken(lb, CLKEN_AUTOMATIC);
+
+	dc_plane_dbg(plane, "uses LayerBlend%u\n", dc_lb_get_id(lb));
+
+	/* set ExtDst's source to LayerBlend */
+	dc_ed_pec_src_sel(dplane->ed, dc_lb_get_link_id(lb));
+
+	drm_dev_exit(idx);
+}
+
+static void dc_plane_atomic_disable(struct drm_plane *plane,
+				    struct drm_atomic_state *state)
+{
+	struct dc_plane *dplane = to_dc_plane(plane);
+	const struct dc_fu_ops *fu_ops;
+	int idx;
+
+	if (!drm_dev_enter(plane->dev, &idx))
+		return;
+
+	/* disable fetchunit in shadow */
+	fu_ops = dc_fu_get_ops(dplane->fu);
+	fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
+
+	/* set ExtDst's source to ConstFrame */
+	dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
+
+	drm_dev_exit(idx);
+}
+
+static const struct drm_plane_helper_funcs dc_plane_helper_funcs = {
+	.atomic_check = dc_plane_atomic_check,
+	.atomic_update = dc_plane_atomic_update,
+	.atomic_disable = dc_plane_atomic_disable,
+};
+
+int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
+{
+	struct drm_plane *plane = &dc_plane->base;
+	int ret;
+
+	ret = drm_universal_plane_init(&dc_drm->base, plane, 0, &dc_plane_funcs,
+				       dc_plane_formats,
+				       ARRAY_SIZE(dc_plane_formats),
+				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
+	if (ret)
+		return ret;
+
+	drm_plane_helper_add(plane, &dc_plane_helper_funcs);
+
+	dc_plane->fu = dc_drm->pe->fu_disp[plane->index];
+	dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
+	dc_plane->lb = dc_drm->pe->lb[plane->index];
+	dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
+
+	return 0;
+}
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:17 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:17 +0800
Subject: [PATCH v6 13/19] MAINTAINERS: Add maintainer for i.MX8qxp Display Controller
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-14-victor.liu@nxp.com>

Add myself as the maintainer of i.MX8qxp Display Controller.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* Improve file list. (Frank)

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 77dbb2ff906f..e12e899d10ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7695,6 +7695,14 @@ F:	Documentation/devicetree/bindings/display/imx/
 F:	drivers/gpu/drm/imx/ipuv3/
 F:	drivers/gpu/ipu-v3/
 
+DRM DRIVERS FOR FREESCALE IMX8 DISPLAY CONTROLLER
+M:	Liu Ying <victor.liu at nxp.com>
+L:	dri-devel at lists.freedesktop.org
+S:	Maintained
+T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
+F:	Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc*.yaml
+F:	drivers/gpu/drm/imx/dc/
+
 DRM DRIVERS FOR FREESCALE IMX BRIDGE
 M:	Liu Ying <victor.liu at nxp.com>
 L:	dri-devel at lists.freedesktop.org
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec  8 19:39:23 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon,  9 Dec 2024 11:39:23 +0800
Subject: [DO NOT MERGE PATCH v6 19/19] arm64: dts: imx8qxp-mek: Add MX8-DLVDS-LCD1 display module support
In-Reply-To: <20241209033923.3009629-1-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
Message-ID: <20241209033923.3009629-20-victor.liu@nxp.com>

MX8-DLVDS-LCD1 display module integrates a KOE TX26D202VM0BWA LCD panel
and a touch IC.  Add an overlay to support the LCD panel on i.MX8qxp
MEK.  mipi_lvds_0_ldb channel0 and mipi_lvds_1_ldb channel1 send odd
and even pixels to the panel respectively.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Francesco)

 arch/arm64/boot/dts/freescale/Makefile        |   4 +
 .../imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso | 183 ++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |  30 +++
 3 files changed, 217 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 42e6482a31cb..a22476e81cc7 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -254,6 +254,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-eval-v3.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-iris.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-iris-v2.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb
+
+imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd-dtbs += imx8qxp-mek.dtb imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtb
+
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-tqma8xqp-mba8xx.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8ulp-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx93-9x9-qsb.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso b/arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso
new file mode 100644
index 000000000000..7ddd90e68754
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+
+&{/} {
+	panel-lvds0 {
+		compatible = "koe,tx26d202vm0bwa";
+		backlight = <&backlight_lvds1>;
+		power-supply = <&reg_vcc_per_3v3>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+
+				panel_lvds0_in: endpoint {
+					remote-endpoint = <&lvds0_out>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+
+				panel_lvds1_in: endpoint {
+					remote-endpoint = <&lvds1_out>;
+				};
+			};
+		};
+	};
+};
+
+&backlight_lvds1 {
+	status = "okay";
+};
+
+&dc0_framegen0 {
+	assigned-clocks = <&clk IMX_SC_R_DC_0_PLL_0 IMX_SC_PM_CLK_PLL>,
+			  <&clk IMX_SC_R_DC_0 IMX_SC_PM_CLK_MISC0>;
+	assigned-clock-parents = <0>,
+				 <&clk IMX_SC_R_DC_0_PLL_0 IMX_SC_PM_CLK_PLL>;
+	assigned-clock-rates = <940320000>;
+};
+
+&dc0_pixel_link0 {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 1 {
+			reg = <1>;
+
+			status = "okay";
+		};
+	};
+};
+
+&dc0_pc {
+	status = "okay";
+
+	channel at 0 {
+		status = "okay";
+	};
+};
+
+&mipi_lvds_0_ldb {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	fsl,companion-ldb = <&mipi_lvds_1_ldb>;
+	status = "okay";
+
+	channel at 0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+		status = "okay";
+
+		port at 1 {
+			reg = <1>;
+
+			lvds0_out: endpoint {
+				remote-endpoint = <&panel_lvds0_in>;
+			};
+		};
+	};
+};
+
+&mipi_lvds_0_phy {
+	status = "okay";
+};
+
+&mipi_lvds_0_pxl2dpi {
+	fsl,companion-pxl2dpi = <&mipi_lvds_1_pxl2dpi>;
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+
+			mipi_lvds_0_pxl2dpi_dc0_pixel_link0: endpoint at 0 {
+				status = "okay";
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0: endpoint at 0 {
+				status = "okay";
+			};
+		};
+	};
+};
+
+&mipi_lvds_1_ldb {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	channel at 1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <1>;
+		status = "okay";
+
+		port at 1 {
+			reg = <1>;
+
+			lvds1_out: endpoint {
+				remote-endpoint = <&panel_lvds1_in>;
+			};
+		};
+	};
+};
+
+&mipi_lvds_1_phy {
+	status = "okay";
+};
+
+&mipi_lvds_1_pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_mipi_lvds1>;
+	status = "okay";
+};
+
+&mipi_lvds_1_pxl2dpi {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+
+			mipi_lvds_1_pxl2dpi_dc0_pixel_link0: endpoint at 1 {
+				status = "okay";
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch1: endpoint at 1 {
+				status = "okay";
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index c7b4015c7bf7..cb999be00c22 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -21,6 +21,16 @@ chosen {
 		stdout-path = &lpuart0;
 	};
 
+	backlight_lvds1: backlight-lvds1 {
+		compatible = "pwm-backlight";
+		pwms = <&mipi_lvds_1_pwm 0 100000 0>;
+		brightness-levels = <0 100>;
+		num-interpolated-steps = <100>;
+		default-brightness-level = <100>;
+		power-supply = <&reg_vcc_12v0>;
+		status = "disabled";
+	};
+
 	imx8x_cm4: imx8x-cm4 {
 		compatible = "fsl,imx8qxp-cm4";
 		mbox-names = "tx", "rx", "rxdb";
@@ -58,6 +68,20 @@ dsp_vdev0buffer: memory at 94300000 {
 		};
 	};
 
+	reg_vcc_12v0: regulator-vcc-12v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_12V0";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	reg_vcc_per_3v3: regulator-vcc-per-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_PER_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
 	reg_usdhc2_vmmc: usdhc2-vmmc {
 		compatible = "regulator-fixed";
 		regulator-name = "SD1_SPWR";
@@ -785,6 +809,12 @@ IMX8QXP_FLEXCAN2_RX_ADMA_UART3_RX       0x06000020
 		>;
 	};
 
+	pinctrl_pwm_mipi_lvds1: mipilvds1pwmgrp {
+		fsl,pins = <
+			IMX8QXP_MIPI_DSI1_GPIO0_00_MIPI_DSI1_PWM0_OUT		0x00000020
+		>;
+	};
+
 	pinctrl_pcieb: pcieagrp {
 		fsl,pins = <
 			IMX8QXP_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00		0x06000021
-- 
2.34.1



From lkp at intel.com  Sun Dec  8 19:41:11 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 11:41:11 +0800
Subject: [PATCH 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <20241206172735.4310-3-towinchenmi@gmail.com>
References: <20241206172735.4310-3-towinchenmi@gmail.com>
Message-ID: <202412070752.4Q1AOuGo-lkp@intel.com>

Hi Nick,

kernel test robot noticed the following build errors:

[auto build test ERROR on 40384c840ea1944d7c5a392e8975ed088ecf0b37]

url:    https://github.com/intel-lab-lkp/linux/commits/Nick-Chan/dt-bindings-leds-backlight-apple-dwi-bl-Add-bindings-for-Apple-DWI-backlight/20241207-013254
base:   40384c840ea1944d7c5a392e8975ed088ecf0b37
patch link:    https://lore.kernel.org/r/20241206172735.4310-3-towinchenmi%40gmail.com
patch subject: [PATCH 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
config: hexagon-randconfig-001-20241207 (https://download.01.org/0day-ci/archive/20241207/202412070752.4Q1AOuGo-lkp at intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241207/202412070752.4Q1AOuGo-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/202412070752.4Q1AOuGo-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/video/backlight/dwi_bl.c:46:9: error: implicit declaration of function 'FIELD_PREP' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
           cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
                  ^
>> drivers/video/backlight/dwi_bl.c:61:9: error: implicit declaration of function 'FIELD_GET' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
           return FIELD_GET(DWI_BL_CMD_DATA, cmd);
                  ^
   2 errors generated.


vim +/FIELD_PREP +46 drivers/video/backlight/dwi_bl.c

    37	
    38	static int dwi_bl_update_status(struct backlight_device *bl)
    39	{
    40		struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
    41	
    42		int brightness = backlight_get_brightness(bl);
    43	
    44		u32 cmd = 0;
    45	
  > 46		cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
    47		cmd |= FIELD_PREP(DWI_BL_CMD_TYPE, DWI_BL_CMD_TYPE_SET_BRIGHTNESS);
    48	
    49		writel(cmd, dwi_bl->base + DWI_BL_CMD);
    50		writel(DWI_BL_CTL_SEND, dwi_bl->base + DWI_BL_CTL);
    51	
    52		return 0;
    53	}
    54	
    55	static int dwi_bl_get_brightness(struct backlight_device *bl)
    56	{
    57		struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
    58	
    59		u32 cmd = readl(dwi_bl->base + DWI_BL_CMD);
    60	
  > 61		return FIELD_GET(DWI_BL_CMD_DATA, cmd);
    62	}
    63	

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


From lkp at intel.com  Sun Dec  8 19:51:26 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 11:51:26 +0800
Subject: [PATCH 3/3] MAINTAINERS: Add entries for Apple DWI backlight
 controller
In-Reply-To: <20241206172735.4310-4-towinchenmi@gmail.com>
References: <20241206172735.4310-4-towinchenmi@gmail.com>
Message-ID: <202412070751.g7TFM5AI-lkp@intel.com>

Hi Nick,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 40384c840ea1944d7c5a392e8975ed088ecf0b37]

url:    https://github.com/intel-lab-lkp/linux/commits/Nick-Chan/dt-bindings-leds-backlight-apple-dwi-bl-Add-bindings-for-Apple-DWI-backlight/20241207-013254
base:   40384c840ea1944d7c5a392e8975ed088ecf0b37
patch link:    https://lore.kernel.org/r/20241206172735.4310-4-towinchenmi%40gmail.com
patch subject: [PATCH 3/3] MAINTAINERS: Add entries for Apple DWI backlight controller
reproduce: (https://download.01.org/0day-ci/archive/20241207/202412070751.g7TFM5AI-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/202412070751.g7TFM5AI-lkp at intel.com/

All warnings (new ones prefixed by >>):

   Warning: Documentation/devicetree/bindings/regulator/siliconmitus,sm5703-regulator.yaml references a file that doesn't exist: Documentation/devicetree/bindings/mfd/siliconmitus,sm5703.yaml
   Warning: Documentation/hwmon/g762.rst references a file that doesn't exist: Documentation/devicetree/bindings/hwmon/g762.txt
   Warning: Documentation/hwmon/isl28022.rst references a file that doesn't exist: Documentation/devicetree/bindings/hwmon/isl,isl28022.yaml
   Warning: Documentation/translations/ja_JP/SubmittingPatches references a file that doesn't exist: linux-2.6.12-vanilla/Documentation/dontdiff
>> Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/video/backlight/apple,dwi-bl.yaml
   Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
   Warning: lib/Kconfig.debug references a file that doesn't exist: Documentation/dev-tools/fault-injection/fault-injection.rst
   Using alabaster theme

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


From lkp at intel.com  Sun Dec  8 20:04:47 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 12:04:47 +0800
Subject: [PATCH v6 4/4] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S20 (x1slte)
In-Reply-To: <20241206184609.2437-5-umer.uddin@mentallysanemainliners.org>
References: <20241206184609.2437-5-umer.uddin@mentallysanemainliners.org>
Message-ID: <202412071131.v9GOab0D-lkp@intel.com>

Hi Umer,

kernel test robot noticed the following build errors:

[auto build test ERROR on krzk/for-next]
[also build test ERROR on next-20241206]
[cannot apply to krzk-dt/for-next pinctrl-samsung/for-next krzk-mem-ctrl/for-next linus/master v6.13-rc1]
[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/Umer-Uddin/dt-bindings-arm-samsung-samsung-boards-Add-bindings-for-SM-G981B-and-SM-G980F-board/20241207-024917
base:   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git for-next
patch link:    https://lore.kernel.org/r/20241206184609.2437-5-umer.uddin%40mentallysanemainliners.org
patch subject: [PATCH v6 4/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 (x1slte)
config: arm64-randconfig-002-20241207 (https://download.01.org/0day-ci/archive/20241207/202412071131.v9GOab0D-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241207/202412071131.v9GOab0D-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/202412071131.v9GOab0D-lkp at intel.com/

All errors (new ones prefixed by >>):

>> arch/arm64/boot/dts/exynos/exynos990-x1slte.dts:9:10: fatal error: exynos990-hubble-common.dtsi: No such file or directory
       9 | #include "exynos990-hubble-common.dtsi"
         |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   compilation terminated.


vim +9 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

   > 9	#include "exynos990-hubble-common.dtsi"
    10	

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


From lkp at intel.com  Sun Dec  8 20:23:59 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 12:23:59 +0800
Subject: [PATCH v6 4/4] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S20 (x1slte)
In-Reply-To: <20241206184609.2437-5-umer.uddin@mentallysanemainliners.org>
References: <20241206184609.2437-5-umer.uddin@mentallysanemainliners.org>
Message-ID: <202412072223.jniPKsyn-lkp@intel.com>

Hi Umer,

kernel test robot noticed the following build errors:

[auto build test ERROR on krzk/for-next]
[also build test ERROR on next-20241206]
[cannot apply to krzk-dt/for-next pinctrl-samsung/for-next krzk-mem-ctrl/for-next linus/master v6.13-rc1]
[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/Umer-Uddin/dt-bindings-arm-samsung-samsung-boards-Add-bindings-for-SM-G981B-and-SM-G980F-board/20241207-024917
base:   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git for-next
patch link:    https://lore.kernel.org/r/20241206184609.2437-5-umer.uddin%40mentallysanemainliners.org
patch subject: [PATCH v6 4/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 (x1slte)
config: arm64-randconfig-003-20241207 (https://download.01.org/0day-ci/archive/20241207/202412072223.jniPKsyn-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241207/202412072223.jniPKsyn-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/202412072223.jniPKsyn-lkp at intel.com/

All errors (new ones prefixed by >>):

>> arch/arm64/boot/dts/exynos/exynos990-x1slte.dts:9:10: fatal error: 'exynos990-hubble-common.dtsi' file not found
       9 | #include "exynos990-hubble-common.dtsi"
         |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 error generated.


vim +9 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

   > 9	#include "exynos990-hubble-common.dtsi"
    10	

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


From lkp at intel.com  Sun Dec  8 20:30:01 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 12:30:01 +0800
Subject: [arm-platforms:arm64/sysreg-el12 2/4] arch/arm64/mm/proc.S:504:
 Error: undefined symbol TCR2_EL1x_HAFT used as an immediate value
Message-ID: <202412080512.D8NvzV7F-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git arm64/sysreg-el12
head:   43aafbc40b7a211579f624bf594eaa42d7675daf
commit: 9633732169ec11efc9e7aaa727feb3087c664832 [2/4] arm64/sysreg: Get rid of the TCR2_EL1x SysregFields
config: arm64-randconfig-004-20241208 (https://download.01.org/0day-ci/archive/20241208/202412080512.D8NvzV7F-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241208/202412080512.D8NvzV7F-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/202412080512.D8NvzV7F-lkp at intel.com/

All errors (new ones prefixed by >>):

   arch/arm64/mm/proc.S: Assembler messages:
>> arch/arm64/mm/proc.S:504: Error: undefined symbol TCR2_EL1x_HAFT used as an immediate value


vim +504 arch/arm64/mm/proc.S

dd006da21646f1 Ard Biesheuvel           2015-03-19  486  
87366d8cf7b3f6 Radha Mohan Chintakuntla 2014-03-07  487  	/*
787fd1d019b269 Kristina Martsenko       2017-12-13  488  	 * Set the IPS bits in TCR_EL1.
87366d8cf7b3f6 Radha Mohan Chintakuntla 2014-03-07  489  	 */
5cd6fa6de5e903 Mark Rutland             2021-03-26  490  	tcr_compute_pa_size tcr, #TCR_IPS_SHIFT, x5, x6
2f4b829c625ec3 Catalin Marinas          2015-07-10  491  #ifdef CONFIG_ARM64_HW_AFDBM
2f4b829c625ec3 Catalin Marinas          2015-07-10  492  	/*
05abb595bbaccc Suzuki K Poulose         2018-03-26  493  	 * Enable hardware update of the Access Flags bit.
05abb595bbaccc Suzuki K Poulose         2018-03-26  494  	 * Hardware dirty bit management is enabled later,
05abb595bbaccc Suzuki K Poulose         2018-03-26  495  	 * via capabilities.
2f4b829c625ec3 Catalin Marinas          2015-07-10  496  	 */
2f4b829c625ec3 Catalin Marinas          2015-07-10  497  	mrs	x9, ID_AA64MMFR1_EL1
efe72541355d4d Yicong Yang              2024-11-02  498  	ubfx	x9, x9, ID_AA64MMFR1_EL1_HAFDBS_SHIFT, #4
05abb595bbaccc Suzuki K Poulose         2018-03-26  499  	cbz	x9, 1f
5cd6fa6de5e903 Mark Rutland             2021-03-26  500  	orr	tcr, tcr, #TCR_HA		// hardware Access flag update
efe72541355d4d Yicong Yang              2024-11-02  501  #ifdef CONFIG_ARM64_HAFT
efe72541355d4d Yicong Yang              2024-11-02  502  	cmp	x9, ID_AA64MMFR1_EL1_HAFDBS_HAFT
efe72541355d4d Yicong Yang              2024-11-02  503  	b.lt	1f
efe72541355d4d Yicong Yang              2024-11-02 @504  	orr	tcr2, tcr2, TCR2_EL1x_HAFT
efe72541355d4d Yicong Yang              2024-11-02  505  #endif /* CONFIG_ARM64_HAFT */
05abb595bbaccc Suzuki K Poulose         2018-03-26  506  1:
2f4b829c625ec3 Catalin Marinas          2015-07-10  507  #endif	/* CONFIG_ARM64_HW_AFDBM */
776e49af6000ef Mark Rutland             2021-03-26  508  	msr	mair_el1, mair
5cd6fa6de5e903 Mark Rutland             2021-03-26  509  	msr	tcr_el1, tcr
9e9bb6ede00a84 Joey Gouly               2023-06-06  510  
9e9bb6ede00a84 Joey Gouly               2023-06-06  511  	mrs_s	x1, SYS_ID_AA64MMFR3_EL1
9e9bb6ede00a84 Joey Gouly               2023-06-06  512  	ubfx	x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
9e9bb6ede00a84 Joey Gouly               2023-06-06  513  	cbz	x1, .Lskip_indirection
9e9bb6ede00a84 Joey Gouly               2023-06-06  514  
60d043c101769b Ard Biesheuvel           2024-02-14  515  	/*
60d043c101769b Ard Biesheuvel           2024-02-14  516  	 * The PROT_* macros describing the various memory types may resolve to
60d043c101769b Ard Biesheuvel           2024-02-14  517  	 * C expressions if they include the PTE_MAYBE_* macros, and so they
60d043c101769b Ard Biesheuvel           2024-02-14  518  	 * can only be used from C code. The PIE_E* constants below are also
60d043c101769b Ard Biesheuvel           2024-02-14  519  	 * defined in terms of those macros, but will mask out those
60d043c101769b Ard Biesheuvel           2024-02-14  520  	 * PTE_MAYBE_* constants, whether they are set or not. So #define them
60d043c101769b Ard Biesheuvel           2024-02-14  521  	 * as 0x0 here so we can evaluate the PIE_E* constants in asm context.
60d043c101769b Ard Biesheuvel           2024-02-14  522  	 */
60d043c101769b Ard Biesheuvel           2024-02-14  523  

:::::: The code at line 504 was first introduced by commit
:::::: efe72541355d4d40a4f076af453f6533e98e058c arm64: Add support for FEAT_HAFT

:::::: TO: Yicong Yang <yangyicong at hisilicon.com>
:::::: CC: Catalin Marinas <catalin.marinas at arm.com>

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


From dharma.b at microchip.com  Sun Dec  8 20:32:30 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Mon, 9 Dec 2024 10:02:30 +0530
Subject: [PATCH v2] dt-bindings: mmc: atmel,hsmci: Convert to json schema
Message-ID: <20241209-hsmci-v2-1-b5a6d7c59b67@microchip.com>

Convert atmel,hsmci documentation to yaml format. The new file will inherit
from mmc-controller.yaml.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
Changes in v2:
- Drop the duplicate properties in the slot node.
- Link to v1: https://lore.kernel.org/r/20241205-hsmci-v1-1-5a25e622dfed at microchip.com
---
 .../devicetree/bindings/mmc/atmel,hsmci.yaml       | 110 +++++++++++++++++++++
 .../devicetree/bindings/mmc/atmel-hsmci.txt        |  73 --------------
 2 files changed, 110 insertions(+), 73 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml b/Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml
new file mode 100644
index 000000000000..26686ada6288
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mmc/atmel,hsmci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel High-Speed MultiMedia Card Interface (HSMCI)
+
+description:
+  The Atmel HSMCI controller provides an interface for MMC, SD, and SDIO memory
+  cards.
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Aubin Constans <aubin.constans at microchip.com>
+
+allOf:
+  - $ref: mmc-controller.yaml
+
+properties:
+  compatible:
+    const: atmel,hsmci
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  dmas:
+    maxItems: 1
+
+  dma-names:
+    const: rxtx
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: mci_clk
+
+  "#address-cells":
+    const: 1
+    description: Used for slot IDs.
+
+  "#size-cells":
+    const: 0
+
+patternProperties:
+  "^slot@[0-9]+$":
+    type: object
+    description: A slot node representing an MMC, SD, or SDIO slot.
+
+    allOf:
+      - $ref: mmc-controller.yaml
+
+    properties:
+      reg:
+        description: Slot ID.
+        minimum: 0
+
+    required:
+      - reg
+      - bus-width
+
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - "#address-cells"
+  - "#size-cells"
+
+anyOf:
+  - required:
+      - slot at 0
+  - required:
+      - slot at 1
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/at91.h>
+    mmc at f0008000 {
+      compatible = "atmel,hsmci";
+      reg = <0xf0008000 0x600>;
+      interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&mci0_clk>;
+      clock-names = "mci_clk";
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      slot at 0 {
+        reg = <0>;
+        bus-width = <4>;
+        cd-gpios = <&pioD 15 0>;
+        cd-inverted;
+      };
+
+      slot at 1 {
+        reg = <1>;
+        bus-width = <4>;
+      };
+    };
+...
diff --git a/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt b/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt
deleted file mode 100644
index 07ad02075a93..000000000000
--- a/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-* Atmel High Speed MultiMedia Card Interface
-
-This controller on atmel products provides an interface for MMC, SD and SDIO
-types of memory cards.
-
-This file documents differences between the core properties described
-by mmc.txt and the properties used by the atmel-mci driver.
-
-1) MCI node
-
-Required properties:
-- compatible: should be "atmel,hsmci"
-- #address-cells: should be one. The cell is the slot id.
-- #size-cells: should be zero.
-- at least one slot node
-- clock-names: tuple listing input clock names.
-	Required elements: "mci_clk"
-- clocks: phandles to input clocks.
-
-The node contains child nodes for each slot that the platform uses
-
-Example MCI node:
-
-mmc0: mmc at f0008000 {
-	compatible = "atmel,hsmci";
-	reg = <0xf0008000 0x600>;
-	interrupts = <12 4>;
-	#address-cells = <1>;
-	#size-cells = <0>;
-	clock-names = "mci_clk";
-	clocks = <&mci0_clk>;
-
-	[ child node definitions...]
-};
-
-2) slot nodes
-
-Required properties:
-- reg: should contain the slot id.
-- bus-width: number of data lines connected to the controller
-
-Optional properties:
-- cd-gpios: specify GPIOs for card detection
-- cd-inverted: invert the value of external card detect gpio line
-- wp-gpios: specify GPIOs for write protection
-
-Example slot node:
-
-slot at 0 {
-	reg = <0>;
-	bus-width = <4>;
-	cd-gpios = <&pioD 15 0>
-	cd-inverted;
-};
-
-Example full MCI node:
-mmc0: mmc at f0008000 {
-	compatible = "atmel,hsmci";
-	reg = <0xf0008000 0x600>;
-	interrupts = <12 4>;
-	#address-cells = <1>;
-	#size-cells = <0>;
-	slot at 0 {
-		reg = <0>;
-		bus-width = <4>;
-		cd-gpios = <&pioD 15 0>
-		cd-inverted;
-	};
-	slot at 1 {
-		reg = <1>;
-		bus-width = <4>;
-	};
-};

---
base-commit: feffde684ac29a3b7aec82d2df850fbdbdee55e4
change-id: 20241205-hsmci-7ac3ea915777

Best regards,
-- 
Dharma Balasubiramani <dharma.b at microchip.com>



From lkp at intel.com  Sun Dec  8 20:34:44 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 12:34:44 +0800
Subject: [PATCH v2 2/5] PCI: stm32: Add PCIe host support for STM32MP25
In-Reply-To: <20241126155119.1574564-3-christian.bruel@foss.st.com>
References: <20241126155119.1574564-3-christian.bruel@foss.st.com>
Message-ID: <202412080849.1SXhxzpi-lkp@intel.com>

Hi Christian,

kernel test robot noticed the following build errors:

[auto build test ERROR on pci/next]
[also build test ERROR on pci/for-linus linus/master v6.13-rc1 next-20241206]
[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/Christian-Bruel/dt-bindings-PCI-Add-STM32MP25-PCIe-root-complex-bindings/20241128-101958
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link:    https://lore.kernel.org/r/20241126155119.1574564-3-christian.bruel%40foss.st.com
patch subject: [PATCH v2 2/5] PCI: stm32: Add PCIe host support for STM32MP25
config: openrisc-randconfig-r072-20241208 (https://download.01.org/0day-ci/archive/20241208/202412080849.1SXhxzpi-lkp at intel.com/config)
compiler: or1k-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241208/202412080849.1SXhxzpi-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/202412080849.1SXhxzpi-lkp at intel.com/

All errors (new ones prefixed by >>):

   drivers/pci/controller/dwc/pcie-stm32.c: In function 'stm32_pcie_suspend_noirq':
>> drivers/pci/controller/dwc/pcie-stm32.c:101:16: error: implicit declaration of function 'pinctrl_pm_select_sleep_state' [-Wimplicit-function-declaration]
     101 |         return pinctrl_pm_select_sleep_state(dev);
         |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pci/controller/dwc/pcie-stm32.c: In function 'stm32_pcie_resume_noirq':
>> drivers/pci/controller/dwc/pcie-stm32.c:114:24: error: 'struct device' has no member named 'pins'
     114 |         if (!IS_ERR(dev->pins->init_state))
         |                        ^~
>> drivers/pci/controller/dwc/pcie-stm32.c:115:23: error: implicit declaration of function 'pinctrl_select_state' [-Wimplicit-function-declaration]
     115 |                 ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
         |                       ^~~~~~~~~~~~~~~~~~~~
   drivers/pci/controller/dwc/pcie-stm32.c:115:47: error: 'struct device' has no member named 'pins'
     115 |                 ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
         |                                               ^~
   drivers/pci/controller/dwc/pcie-stm32.c:115:61: error: 'struct device' has no member named 'pins'
     115 |                 ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
         |                                                             ^~
>> drivers/pci/controller/dwc/pcie-stm32.c:117:23: error: implicit declaration of function 'pinctrl_pm_select_default_state' [-Wimplicit-function-declaration]
     117 |                 ret = pinctrl_pm_select_default_state(dev);
         |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pci/controller/dwc/pcie-stm32.c: In function 'stm32_pcie_probe':
   drivers/pci/controller/dwc/pcie-stm32.c:243:29: warning: unused variable 'np' [-Wunused-variable]
     243 |         struct device_node *np = pdev->dev.of_node;
         |                             ^~


vim +/pinctrl_pm_select_sleep_state +101 drivers/pci/controller/dwc/pcie-stm32.c

    88	
    89	static int stm32_pcie_suspend_noirq(struct device *dev)
    90	{
    91		struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
    92	
    93		stm32_pcie->link_is_up = dw_pcie_link_up(stm32_pcie->pci);
    94	
    95		stm32_pcie_stop_link(stm32_pcie->pci);
    96		clk_disable_unprepare(stm32_pcie->clk);
    97	
    98		if (!device_may_wakeup(dev) && !device_wakeup_path(dev))
    99			phy_exit(stm32_pcie->phy);
   100	
 > 101		return pinctrl_pm_select_sleep_state(dev);
   102	}
   103	
   104	static int stm32_pcie_resume_noirq(struct device *dev)
   105	{
   106		struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
   107		struct dw_pcie *pci = stm32_pcie->pci;
   108		struct dw_pcie_rp *pp = &pci->pp;
   109		int ret;
   110	
   111		/* init_state must be called first to force clk_req# gpio when no
   112		 * device is plugged.
   113		 */
 > 114		if (!IS_ERR(dev->pins->init_state))
 > 115			ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
   116		else
 > 117			ret = pinctrl_pm_select_default_state(dev);
   118	
   119		if (ret) {
   120			dev_err(dev, "Failed to activate pinctrl pm state: %d\n", ret);
   121			return ret;
   122		}
   123	
   124		if (!device_may_wakeup(dev) && !device_wakeup_path(dev)) {
   125			ret = phy_init(stm32_pcie->phy);
   126			if (ret) {
   127				pinctrl_pm_select_default_state(dev);
   128				return ret;
   129			}
   130		}
   131	
   132		ret = clk_prepare_enable(stm32_pcie->clk);
   133		if (ret)
   134			goto clk_err;
   135	
   136		ret = dw_pcie_setup_rc(pp);
   137		if (ret)
   138			goto pcie_err;
   139	
   140		if (stm32_pcie->link_is_up) {
   141			ret = stm32_pcie_start_link(stm32_pcie->pci);
   142			if (ret)
   143				goto pcie_err;
   144	
   145			/* Ignore errors, the link may come up later */
   146			dw_pcie_wait_for_link(stm32_pcie->pci);
   147		}
   148	
   149		pinctrl_pm_select_default_state(dev);
   150	
   151		return 0;
   152	
   153	pcie_err:
   154		dw_pcie_host_deinit(pp);
   155		clk_disable_unprepare(stm32_pcie->clk);
   156	clk_err:
   157		phy_exit(stm32_pcie->phy);
   158		pinctrl_pm_select_default_state(dev);
   159	
   160		return ret;
   161	}
   162	

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


From lkp at intel.com  Sun Dec  8 20:38:51 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 12:38:51 +0800
Subject: [net-next PATCH v10 8/9] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241208002105.18074-9-ansuelsmth@gmail.com>
References: <20241208002105.18074-9-ansuelsmth@gmail.com>
Message-ID: <202412081038.lJvmpuB2-lkp@intel.com>

Hi Christian,

kernel test robot noticed the following build errors:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Marangi/dt-bindings-nvmem-Document-support-for-Airoha-AN8855-Switch-EFUSE/20241208-082533
base:   net-next/main
patch link:    https://lore.kernel.org/r/20241208002105.18074-9-ansuelsmth%40gmail.com
patch subject: [net-next PATCH v10 8/9] net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20241208/202412081038.lJvmpuB2-lkp at intel.com/config)
compiler: sh4-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241208/202412081038.lJvmpuB2-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/202412081038.lJvmpuB2-lkp at intel.com/

All error/warnings (new ones prefixed by >>):

   drivers/net/dsa/an8855.c: In function 'an8855_switch_probe':
>> drivers/net/dsa/an8855.c:2227:34: error: invalid use of undefined type 'struct platform_device'
    2227 |         priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
         |                                  ^~
   drivers/net/dsa/an8855.c:2231:26: error: invalid use of undefined type 'struct platform_device'
    2231 |         priv->dev = &pdev->dev;
         |                          ^~
   drivers/net/dsa/an8855.c: In function 'an8855_switch_remove':
   drivers/net/dsa/an8855.c:2282:57: error: invalid use of undefined type 'struct platform_device'
    2282 |         struct an8855_priv *priv = dev_get_drvdata(&pdev->dev);
         |                                                         ^~
   drivers/net/dsa/an8855.c: At top level:
>> drivers/net/dsa/an8855.c:2295:15: error: variable 'an8855_switch_driver' has initializer but incomplete type
    2295 | static struct platform_driver an8855_switch_driver = {
         |               ^~~~~~~~~~~~~~~
>> drivers/net/dsa/an8855.c:2296:10: error: 'struct platform_driver' has no member named 'probe'
    2296 |         .probe = an8855_switch_probe,
         |          ^~~~~
>> drivers/net/dsa/an8855.c:2296:18: warning: excess elements in struct initializer
    2296 |         .probe = an8855_switch_probe,
         |                  ^~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/an8855.c:2296:18: note: (near initialization for 'an8855_switch_driver')
>> drivers/net/dsa/an8855.c:2297:10: error: 'struct platform_driver' has no member named 'remove'
    2297 |         .remove = an8855_switch_remove,
         |          ^~~~~~
   drivers/net/dsa/an8855.c:2297:19: warning: excess elements in struct initializer
    2297 |         .remove = an8855_switch_remove,
         |                   ^~~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/an8855.c:2297:19: note: (near initialization for 'an8855_switch_driver')
>> drivers/net/dsa/an8855.c:2298:10: error: 'struct platform_driver' has no member named 'driver'
    2298 |         .driver = {
         |          ^~~~~~
>> drivers/net/dsa/an8855.c:2298:19: error: extra brace group at end of initializer
    2298 |         .driver = {
         |                   ^
   drivers/net/dsa/an8855.c:2298:19: note: (near initialization for 'an8855_switch_driver')
   drivers/net/dsa/an8855.c:2298:19: warning: excess elements in struct initializer
   drivers/net/dsa/an8855.c:2298:19: note: (near initialization for 'an8855_switch_driver')
>> drivers/net/dsa/an8855.c:2303:1: warning: data definition has no type or storage class
    2303 | module_platform_driver(an8855_switch_driver);
         | ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/dsa/an8855.c:2303:1: error: type defaults to 'int' in declaration of 'module_platform_driver' [-Wimplicit-int]
>> drivers/net/dsa/an8855.c:2303:1: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
>> drivers/net/dsa/an8855.c:2295:31: error: storage size of 'an8855_switch_driver' isn't known
    2295 | static struct platform_driver an8855_switch_driver = {
         |                               ^~~~~~~~~~~~~~~~~~~~
>> drivers/net/dsa/an8855.c:2295:31: warning: 'an8855_switch_driver' defined but not used [-Wunused-variable]


vim +2227 drivers/net/dsa/an8855.c

  2220	
  2221	static int an8855_switch_probe(struct platform_device *pdev)
  2222	{
  2223		struct an8855_priv *priv;
  2224		u32 val;
  2225		int ret;
  2226	
> 2227		priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  2228		if (!priv)
  2229			return -ENOMEM;
  2230	
> 2231		priv->dev = &pdev->dev;
  2232		priv->phy_require_calib = of_property_read_bool(priv->dev->of_node,
  2233								"airoha,ext-surge");
  2234	
  2235		priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
  2236							   GPIOD_OUT_LOW);
  2237		if (IS_ERR(priv->reset_gpio))
  2238			return PTR_ERR(priv->reset_gpio);
  2239	
  2240		/* Get regmap from MFD */
  2241		priv->regmap = dev_get_regmap(priv->dev->parent, NULL);
  2242	
  2243		if (priv->reset_gpio) {
  2244			usleep_range(100000, 150000);
  2245			gpiod_set_value_cansleep(priv->reset_gpio, 0);
  2246			usleep_range(100000, 150000);
  2247			gpiod_set_value_cansleep(priv->reset_gpio, 1);
  2248	
  2249			/* Poll HWTRAP reg to wait for Switch to fully Init */
  2250			ret = regmap_read_poll_timeout(priv->regmap, AN8855_HWTRAP, val,
  2251						       val, 20, 200000);
  2252			if (ret)
  2253				return ret;
  2254		}
  2255	
  2256		ret = an8855_read_switch_id(priv);
  2257		if (ret)
  2258			return ret;
  2259	
  2260		priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
  2261		if (!priv->ds)
  2262			return -ENOMEM;
  2263	
  2264		priv->ds->dev = priv->dev;
  2265		priv->ds->num_ports = AN8855_NUM_PORTS;
  2266		priv->ds->priv = priv;
  2267		priv->ds->ops = &an8855_switch_ops;
  2268		devm_mutex_init(priv->dev, &priv->reg_mutex);
  2269		priv->ds->phylink_mac_ops = &an8855_phylink_mac_ops;
  2270	
  2271		priv->pcs.ops = &an8855_pcs_ops;
  2272		priv->pcs.neg_mode = true;
  2273		priv->pcs.poll = true;
  2274	
  2275		dev_set_drvdata(priv->dev, priv);
  2276	
  2277		return dsa_register_switch(priv->ds);
  2278	}
  2279	
  2280	static void an8855_switch_remove(struct platform_device *pdev)
  2281	{
> 2282		struct an8855_priv *priv = dev_get_drvdata(&pdev->dev);
  2283	
  2284		if (!priv)
  2285			return;
  2286	
  2287		dsa_unregister_switch(priv->ds);
  2288	}
  2289	
  2290	static const struct of_device_id an8855_switch_of_match[] = {
  2291		{ .compatible = "airoha,an8855-switch" },
  2292		{ /* sentinel */ }
  2293	};
  2294	
> 2295	static struct platform_driver an8855_switch_driver = {
> 2296		.probe = an8855_switch_probe,
> 2297		.remove = an8855_switch_remove,
> 2298		.driver = {
  2299			.name = "an8855-switch",
  2300			.of_match_table = an8855_switch_of_match,
  2301		},
  2302	};
> 2303	module_platform_driver(an8855_switch_driver);
  2304	

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


From lkp at intel.com  Sun Dec  8 20:39:54 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 12:39:54 +0800
Subject: [net-next PATCH v10 9/9] net: phy: Add Airoha AN8855 Internal
 Switch Gigabit PHY
In-Reply-To: <20241208002105.18074-10-ansuelsmth@gmail.com>
References: <20241208002105.18074-10-ansuelsmth@gmail.com>
Message-ID: <202412081155.xp97LlzV-lkp@intel.com>

Hi Christian,

kernel test robot noticed the following build errors:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Marangi/dt-bindings-nvmem-Document-support-for-Airoha-AN8855-Switch-EFUSE/20241208-082533
base:   net-next/main
patch link:    https://lore.kernel.org/r/20241208002105.18074-10-ansuelsmth%40gmail.com
patch subject: [net-next PATCH v10 9/9] net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20241208/202412081155.xp97LlzV-lkp at intel.com/config)
compiler: sh4-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241208/202412081155.xp97LlzV-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/202412081155.xp97LlzV-lkp at intel.com/

All error/warnings (new ones prefixed by >>):

   drivers/net/phy/air_an8855.c: In function 'an8855_probe':
>> drivers/net/phy/air_an8855.c:100:13: warning: unused variable 'ret' [-Wunused-variable]
     100 |         int ret;
         |             ^~~
   drivers/net/phy/air_an8855.c: In function 'an8855_config_init':
>> drivers/net/phy/air_an8855.c:154:45: error: 'dev' undeclared (first use in this function); did you mean 'cdev'?
     154 |                 ret = en8855_get_r50ohm_val(dev, "tx_a", &calibration_data[0]);
         |                                             ^~~
         |                                             cdev
   drivers/net/phy/air_an8855.c:154:45: note: each undeclared identifier is reported only once for each function it appears in


vim +154 drivers/net/phy/air_an8855.c

    94	
    95	static int an8855_probe(struct phy_device *phydev)
    96	{
    97		struct device *dev = &phydev->mdio.dev;
    98		struct device_node *node = dev->of_node;
    99		struct air_an8855_priv *priv;
 > 100		int ret;
   101	
   102		/* If we don't have a node, skip calib */
   103		if (!node)
   104			return 0;
   105	
   106		priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
   107		if (!priv)
   108			return -ENOMEM;
   109	
   110		phydev->priv = priv;
   111	
   112		return 0;
   113	}
   114	
   115	static int an8855_get_downshift(struct phy_device *phydev, u8 *data)
   116	{
   117		int val;
   118	
   119		val = phy_read_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1, AN8855_PHY_EXT_REG_14);
   120		if (val < 0)
   121			return val;
   122	
   123		*data = val & AN8855_PHY_EN_DOWN_SHIFT ? DOWNSHIFT_DEV_DEFAULT_COUNT :
   124							 DOWNSHIFT_DEV_DISABLE;
   125	
   126		return 0;
   127	}
   128	
   129	static int an8855_set_downshift(struct phy_device *phydev, u8 cnt)
   130	{
   131		u16 ds = cnt != DOWNSHIFT_DEV_DISABLE ? AN8855_PHY_EN_DOWN_SHIFT : 0;
   132	
   133		return phy_modify_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1,
   134					AN8855_PHY_EXT_REG_14, AN8855_PHY_EN_DOWN_SHIFT,
   135					ds);
   136	}
   137	
   138	static int an8855_config_init(struct phy_device *phydev)
   139	{
   140		struct air_an8855_priv *priv = phydev->priv;
   141		int ret;
   142	
   143		/* Enable HW auto downshift */
   144		ret = an8855_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT);
   145		if (ret)
   146			return ret;
   147	
   148		/* Apply calibration values, if needed.
   149		 * AN8855_PHY_FLAGS_EN_CALIBRATION signal this.
   150		 */
   151		if (priv && phydev->dev_flags & AN8855_PHY_FLAGS_EN_CALIBRATION) {
   152			u8 *calibration_data = priv->calibration_data;
   153	
 > 154			ret = en8855_get_r50ohm_val(dev, "tx_a", &calibration_data[0]);
   155			if (ret)
   156				return ret;
   157	
   158			ret = en8855_get_r50ohm_val(dev, "tx_b", &calibration_data[1]);
   159			if (ret)
   160				return ret;
   161	
   162			ret = en8855_get_r50ohm_val(dev, "tx_c", &calibration_data[2]);
   163			if (ret)
   164				return ret;
   165	
   166			ret = en8855_get_r50ohm_val(dev, "tx_d", &calibration_data[3]);
   167			if (ret)
   168				return ret;
   169	
   170			ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_AB,
   171					     AN8855_PHY_R50OHM_RSEL_TX_A | AN8855_PHY_R50OHM_RSEL_TX_B,
   172					     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_A, calibration_data[0]) |
   173					     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_B, calibration_data[1]));
   174			if (ret)
   175				return ret;
   176			ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_CD,
   177					     AN8855_PHY_R50OHM_RSEL_TX_C | AN8855_PHY_R50OHM_RSEL_TX_D,
   178					     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_C, calibration_data[2]) |
   179					     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_D, calibration_data[3]));
   180			if (ret)
   181				return ret;
   182		}
   183	
   184		/* Apply values to reduce signal noise */
   185		ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_TX_PAIR_DLY_SEL_GBE,
   186				    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE, 0x4) |
   187				    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE, 0x4));
   188		if (ret)
   189			return ret;
   190		ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_CTRL,
   191				    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A |
   192				    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C);
   193		if (ret)
   194			return ret;
   195		ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_0,
   196				    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_A, 0x1));
   197		if (ret)
   198			return ret;
   199		ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_1,
   200				    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_C, 0x1));
   201		if (ret)
   202			return ret;
   203	
   204		return 0;
   205	}
   206	

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


From lkp at intel.com  Sun Dec  8 20:42:57 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 12:42:57 +0800
Subject: [net-next PATCH v10 8/9] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241208002105.18074-9-ansuelsmth@gmail.com>
References: <20241208002105.18074-9-ansuelsmth@gmail.com>
Message-ID: <202412081353.I0203taL-lkp@intel.com>

Hi Christian,

kernel test robot noticed the following build warnings:

[auto build test WARNING on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Marangi/dt-bindings-nvmem-Document-support-for-Airoha-AN8855-Switch-EFUSE/20241208-082533
base:   net-next/main
patch link:    https://lore.kernel.org/r/20241208002105.18074-9-ansuelsmth%40gmail.com
patch subject: [net-next PATCH v10 8/9] net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20241208/202412081353.I0203taL-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241208/202412081353.I0203taL-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/202412081353.I0203taL-lkp at intel.com/

All warnings (new ones prefixed by >>):

   drivers/net/dsa/an8855.c: In function 'an8855_switch_probe':
   drivers/net/dsa/an8855.c:2227:34: error: invalid use of undefined type 'struct platform_device'
    2227 |         priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
         |                                  ^~
   drivers/net/dsa/an8855.c:2231:26: error: invalid use of undefined type 'struct platform_device'
    2231 |         priv->dev = &pdev->dev;
         |                          ^~
   drivers/net/dsa/an8855.c: In function 'an8855_switch_remove':
   drivers/net/dsa/an8855.c:2282:57: error: invalid use of undefined type 'struct platform_device'
    2282 |         struct an8855_priv *priv = dev_get_drvdata(&pdev->dev);
         |                                                         ^~
   drivers/net/dsa/an8855.c: At top level:
   drivers/net/dsa/an8855.c:2295:15: error: variable 'an8855_switch_driver' has initializer but incomplete type
    2295 | static struct platform_driver an8855_switch_driver = {
         |               ^~~~~~~~~~~~~~~
   drivers/net/dsa/an8855.c:2296:10: error: 'struct platform_driver' has no member named 'probe'
    2296 |         .probe = an8855_switch_probe,
         |          ^~~~~
   drivers/net/dsa/an8855.c:2296:18: warning: excess elements in struct initializer
    2296 |         .probe = an8855_switch_probe,
         |                  ^~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/an8855.c:2296:18: note: (near initialization for 'an8855_switch_driver')
   drivers/net/dsa/an8855.c:2297:10: error: 'struct platform_driver' has no member named 'remove'
    2297 |         .remove = an8855_switch_remove,
         |          ^~~~~~
   drivers/net/dsa/an8855.c:2297:19: warning: excess elements in struct initializer
    2297 |         .remove = an8855_switch_remove,
         |                   ^~~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/an8855.c:2297:19: note: (near initialization for 'an8855_switch_driver')
   drivers/net/dsa/an8855.c:2298:10: error: 'struct platform_driver' has no member named 'driver'
    2298 |         .driver = {
         |          ^~~~~~
   drivers/net/dsa/an8855.c:2298:19: error: extra brace group at end of initializer
    2298 |         .driver = {
         |                   ^
   drivers/net/dsa/an8855.c:2298:19: note: (near initialization for 'an8855_switch_driver')
   drivers/net/dsa/an8855.c:2298:19: warning: excess elements in struct initializer
   drivers/net/dsa/an8855.c:2298:19: note: (near initialization for 'an8855_switch_driver')
   drivers/net/dsa/an8855.c:2303:1: warning: data definition has no type or storage class
    2303 | module_platform_driver(an8855_switch_driver);
         | ^~~~~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/an8855.c:2303:1: error: type defaults to 'int' in declaration of 'module_platform_driver' [-Werror=implicit-int]
>> drivers/net/dsa/an8855.c:2303:1: warning: parameter names (without types) in function declaration
   drivers/net/dsa/an8855.c:2295:31: error: storage size of 'an8855_switch_driver' isn't known
    2295 | static struct platform_driver an8855_switch_driver = {
         |                               ^~~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/an8855.c:2295:31: warning: 'an8855_switch_driver' defined but not used [-Wunused-variable]
   cc1: some warnings being treated as errors


vim +2303 drivers/net/dsa/an8855.c

  2294	
  2295	static struct platform_driver an8855_switch_driver = {
  2296		.probe = an8855_switch_probe,
  2297		.remove = an8855_switch_remove,
  2298		.driver = {
  2299			.name = "an8855-switch",
  2300			.of_match_table = an8855_switch_of_match,
  2301		},
  2302	};
> 2303	module_platform_driver(an8855_switch_driver);
  2304	

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


From lkp at intel.com  Sun Dec  8 20:55:43 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 12:55:43 +0800
Subject: [PATCH v3 11/13] ARM: dts: microchip: add support for
 sama7d65_curiosity board
In-Reply-To: <e47d8c8cdaec834ce080ef8c34b9976228223c8f.1733505542.git.Ryan.Wanner@microchip.com>
References: <e47d8c8cdaec834ce080ef8c34b9976228223c8f.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <202412090708.BNX0mUZi-lkp@intel.com>

Hi,

kernel test robot noticed the following build errors:

[auto build test ERROR on clk/clk-next]
[also build test ERROR on robh/for-next soc/for-next linus/master v6.13-rc1 next-20241206]
[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/Ryan-Wanner-microchip-com/dt-bindings-ARM-at91-Document-Microchip-SAMA7D65-Curiosity/20241207-040527
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/e47d8c8cdaec834ce080ef8c34b9976228223c8f.1733505542.git.Ryan.Wanner%40microchip.com
patch subject: [PATCH v3 11/13] ARM: dts: microchip: add support for sama7d65_curiosity board
config: arm-randconfig-051-20241207 (https://download.01.org/0day-ci/archive/20241209/202412090708.BNX0mUZi-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 14.2.0
dtschema version: 2024.12.dev3+g93ee800
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241209/202412090708.BNX0mUZi-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/202412090708.BNX0mUZi-lkp at intel.com/

All errors (new ones prefixed by >>):

>> Error: arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts:50.1-6 Label or path pioA not found
   FATAL ERROR: Syntax error parsing input tree

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


From gankulkarni at os.amperecomputing.com  Sun Dec  8 21:32:01 2024
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Sun,  8 Dec 2024 21:32:01 -0800
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer expired
Message-ID: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>

During automated testing of Nested Virtualization using avocado-vt,
it has been observed that during some boot test iterations,
the Guest-Hypervisor boot was getting crashed with a
synchronous exception while it is still booting EDK2.

The test is launching Multiple instances of Guest-Hypervisor boot
and while booting, QEMU monitor issued the command "info register"
at regular intervals to take a register dump. To execute this
command, QEMU stops the run and does the register read of various
registers. While resuming the run, the function kvm_arm_timer_write()
writes back the saved CNTV_CTL_EL0 register with ISTATUS cleared always
and resulting in the loss of pending interrupt for emulated timers.

In hardware based timers, ISTATUS is a RO/WI bit and gets set by the
h/w, if the condition is still met. However, in Nested-Virtualization
case, the Guest-Hypervisor's?EDK2 is using an emulated virtual timer
and losing ISTATUS state and the interrupt forever.

Adding fix in kvm_arm_timer_write to set ISTATUS for emulated
timers, if the timer expired already.

Fixes: 81dc9504a700 ("KVM: arm64: nv: timers: Support hyp timer emulation")
Co-developed-by: Vishnu Pajjuri <vishnu at os.amperecomputing.com>
Signed-off-by: Vishnu Pajjuri <vishnu at os.amperecomputing.com>
Signed-off-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
---
 arch/arm64/kvm/arch_timer.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 1215df590418..aca58113d790 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -1199,7 +1199,16 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
 		break;
 
 	case TIMER_REG_CTL:
-		timer_set_ctl(timer, val & ~ARCH_TIMER_CTRL_IT_STAT);
+		struct timer_map map;
+
+		val &= ~ARCH_TIMER_CTRL_IT_STAT;
+		get_timer_map(vcpu, &map);
+		/* Set ISTATUS bit for emulated timers, if timer expired. */
+		if (timer == map.emul_vtimer || timer == map.emul_ptimer) {
+			if (!kvm_timer_compute_delta(timer))
+				val |= ARCH_TIMER_CTRL_IT_STAT;
+		}
+		timer_set_ctl(timer, val);
 		break;
 
 	case TIMER_REG_CVAL:
-- 
2.47.0



From jianqi.ren.cn at windriver.com  Sun Dec  8 22:54:13 2024
From: jianqi.ren.cn at windriver.com (jianqi.ren.cn at windriver.com)
Date: Mon, 9 Dec 2024 14:54:13 +0800
Subject: [PATCH 6.1.y] media: mtk-vcodec: potential null pointer deference in SCP
Message-ID: <20241209065413.3427435-1-jianqi.ren.cn@windriver.com>

From: Fullway Wang <fullwaywang at outlook.com>

[ Upstream commit 53dbe08504442dc7ba4865c09b3bbf5fe849681b ]

The return value of devm_kzalloc() needs to be checked to avoid
NULL pointer deference. This is similar to CVE-2022-3113.

Link: https://lore.kernel.org/linux-media/PH7PR20MB5925094DAE3FD750C7E39E01BF712 at PH7PR20MB5925.namprd20.prod.outlook.com
Signed-off-by: Fullway Wang <fullwaywang at outlook.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab at kernel.org>
Signed-off-by: Jianqi Ren <jianqi.ren.cn at windriver.com>
---
 drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c
index d8e66b645bd8..27f08b1d34d1 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c
@@ -65,6 +65,8 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev)
 	}
 
 	fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
+	if (!fw)
+		return ERR_PTR(-ENOMEM);
 	fw->type = SCP;
 	fw->ops = &mtk_vcodec_rproc_msg;
 	fw->scp = scp;
-- 
2.25.1



From ck.hu at mediatek.com  Sun Dec  8 22:00:39 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 9 Dec 2024 06:00:39 +0000
Subject: [PATCH v2 11/15] drm/mediatek: mtk_hdmi: Fix typo for
 aud_sampe_size member
In-Reply-To: <20241205114518.53527-12-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-12-angelogioacchino.delregno@collabora.com>
Message-ID: <477f5d7fecc856dec73e0ec4b513db29c9a9a36e.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Rename member aud_sampe_size of struct hdmi_audio_param to
> aud_sample_size to fix a typo and enhance readability.
> 
> This commit brings no functional changes.

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

> 
> Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_hdmi.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index 9e8d9144cf86..7808141526fa 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -136,7 +136,7 @@ enum hdmi_aud_channel_swap_type {
> 
>  struct hdmi_audio_param {
>         enum hdmi_audio_coding_type aud_codec;
> -       enum hdmi_audio_sample_size aud_sampe_size;
> +       enum hdmi_audio_sample_size aud_sample_size;
>         enum hdmi_aud_input_type aud_input_type;
>         enum hdmi_aud_i2s_fmt aud_i2s_fmt;
>         enum hdmi_aud_mclk aud_mclk;
> @@ -1032,7 +1032,7 @@ static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
> 
>         hdmi->csp = HDMI_COLORSPACE_RGB;
>         aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -       aud_param->aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +       aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
>         aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
>         aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
>         aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> @@ -1528,14 +1528,14 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
>         switch (daifmt->fmt) {
>         case HDMI_I2S:
>                 hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -               hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +               hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
>                 hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
>                 hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
>                 hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
>                 break;
>         case HDMI_SPDIF:
>                 hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -               hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +               hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
>                 hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
>                 break;
>         default:
> --
> 2.47.0
> 


From quic_zhenhuah at quicinc.com  Sun Dec  8 22:04:03 2024
From: quic_zhenhuah at quicinc.com (Zhenhua Huang)
Date: Mon, 9 Dec 2024 14:04:03 +0800
Subject: [PATCH 1/2] arm64: mm: vmemmap populate to page level if not
 section aligned
In-Reply-To: <Z1Mwo5OajFZQYlOg@arm.com>
References: <20241121071256.487220-1-quic_zhenhuah@quicinc.com>
 <20241121071256.487220-2-quic_zhenhuah@quicinc.com>
 <Z1Mwo5OajFZQYlOg@arm.com>
Message-ID: <fe47b1ad-b1e7-4f26-8973-f3c8568e15b8@quicinc.com>

Thanks Catalin for review!

On 2024/12/7 1:13, Catalin Marinas wrote:
> On Thu, Nov 21, 2024 at 03:12:55PM +0800, Zhenhua Huang wrote:
>> Commit 2045a3b8911b ("mm/sparse-vmemmap: generalise vmemmap_populate_hugepages()")
>> optimizes the vmemmap to populate at the PMD section level.
> 
> Wasn't the above commit just a non-functional change making the code
> generic? If there was a functional change, it needs to be spelt out. It
> also implies that the code prior to the above commit needs fixing.
> 

Oh... right. I looked up your change from over a decade ago, identified 
by commit c1cc1552616d ("arm64: MMU initialisation").
However, at that time, there was no support for subsection hotplug, 
which was later introduced by commit ba72b4c8cf60 ("mm/sparsemem: 
support sub-section hotplug").

>> However, if start
>> or end is not aligned to a section boundary, such as when a subsection is hot
>> added, populating the entire section is inefficient and wasteful. In such
>> cases, it is more effective to populate at page granularity.
> 
> Do you have any numbers to show how inefficient it is? We trade some
> memory for less TLB pressure by using huge pages for vmemmap.

I see.. thanks, yeah. TLB efficiency will benefit.
I want to express even one subsection hot-added, current code logic 
still populate 2M backup metadata, although only 2M/64 = 32K needs.

> 
>> This change also addresses misalignment issues during vmemmap_free(). When
>> pmd_sect() is true, the entire PMD section is cleared, even if only a
>> subsection is mapped. For example, if subsections pagemap1 and pagemap2 are
>> added sequentially and then pagemap1 is removed, vmemmap_free() will clear the
>> entire PMD section, even though pagemap2 is still active.
> 
> What do you mean by a PMD section? The whole PAGE_SIZE *
> PAGES_PER_SECTION range or a single pmd entry? I couldn't see how the

I am referring to a single pmd entry, but the buffer it points to manage 
whole PAGE_SIZE * PAGES_PER_SECTION physical memory. for arm64,4K pages:
pmd entry(2M, struct page metadata) -> PAGE_SIZE * 
PAGES_PER_SECTION(128M physical memory)

pagemap1(Where a subsection equals to 2M/64 = 32K) and pagemap2 are part 
of a single PMD entry. When pagemap1 is removed, vmemmap_free() will 
clear the entire PMD section. IOW, total 128M physical memory will 
become unusable.

> former happens in the core code but I only looked briefly. If it's just
> a pmd entry, I think it's fair to require a 2MB alignment of hotplugged
> memory ranges.

Agree that 2MB alignment of hotplugged memory is fair, commit 
ba72b4c8cf60 ("mm/sparsemem: support sub-section hotplug") supported it. 
The issue here I want to address is for its backup struct page metadata.

> 



From quic_zhenhuah at quicinc.com  Sun Dec  8 22:04:22 2024
From: quic_zhenhuah at quicinc.com (Zhenhua Huang)
Date: Mon, 9 Dec 2024 14:04:22 +0800
Subject: [PATCH 0/2] Fix subsection vmemmap_populate logic
In-Reply-To: <20241206221446.e5e8ea4ed85d0f2884216b82@linux-foundation.org>
References: <20241121071256.487220-1-quic_zhenhuah@quicinc.com>
 <eb4d6674-494a-4a84-bade-481b0c89eb93@quicinc.com>
 <b2681eed-d4d5-43c9-90e0-3e706db3e201@quicinc.com>
 <20241206221446.e5e8ea4ed85d0f2884216b82@linux-foundation.org>
Message-ID: <4d2f42fc-26b3-4924-b855-86bea92c03b0@quicinc.com>



On 2024/12/7 14:14, Andrew Morton wrote:
> On Fri, 6 Dec 2024 17:13:39 +0800 Zhenhua Huang <quic_zhenhuah at quicinc.com> wrote:
> 
>>
>>
>> On 2024/11/28 15:26, Zhenhua Huang wrote:
>>>
>>>
>>> On 2024/11/21 15:12, Zhenhua Huang wrote:
>>>> To perform memory hotplug operations, the memmap (aka struct page)
>>>> will be
>>>> updated. For arm64 with 4K page size, the typical granularity is 128M,
>>>> which corresponds to a 2M memmap buffer.
>>>> Commit 2045a3b8911b ("mm/sparse-vmemmap: generalise
>>>> vmemmap_populate_hugepages()")
>>>> optimizes this 2M buffer to be mapped with PMD huge pages. However,
>>>> commit ba72b4c8cf60 ("mm/sparsemem: support sub-section hotplug")
>>>> which supports 2M subsection hotplug granularity, causes other issues
>>>> (refer to the change log of patch #1). The logic is adjusted to populate
>>>> with huge pages only if the hotplug address/size is section-aligned.
>>>
>>> Could any expert please help review ?
>>
>> Gentle reminder for review..
>>
> 
> 
> MM developers work on the linux-mm mailing list, which was not cc'ed.
> 
> Please address Catalin's review comment
> (https://lkml.kernel.org/r/Z1Mwo5OajFZQYlOg at arm.com) then resend a v2
> series with the appropriate cc's.

Thanks Andrew! Will do. I was realizing I couldn't fully rely on 
get_maintainers script :)

> 
> 



From kuninori.morimoto.gx at renesas.com  Sun Dec  8 23:00:05 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Mon, 9 Dec 2024 07:00:05 +0000
Subject: [PATCH 0/5] arm64: renesas: Add R8A779G3 White Hawk Single support
In-Reply-To: <87y10tvhw1.wl-kuninori.morimoto.gx@renesas.com>
References: <cover.1733156661.git.geert+renesas@glider.be>
	<87jzcg1d2f.wl-kuninori.morimoto.gx@renesas.com>
	<CAMuHMdWF7NcmKYzvF4Dfjh3S5MccbJrpSphK5BhxXNnhxgtmYQ@mail.gmail.com>
	<87y10tvhw1.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87y10pmjd6.wl-kuninori.morimoto.gx@renesas.com>


Hi Geert, again

> > -              - renesas,r8a779g2
> > -              - renesas,r8a779g3
> > +              - renesas,r8a779g2 # ES2.x
> > +              - renesas,r8a779g3 # ES3.0
> > 
> > but decided against doing so, as "ES3.0" would become stale as soon
> > as Renesas releases "ES3.1". Alternatively, I could use "ES3.x"
> > immediately.

It seems using "ES3.x" is a good idea.

Thank you for your help !!

Best regards
---
Kuninori Morimoto


From ck.hu at mediatek.com  Sun Dec  8 23:05:24 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 9 Dec 2024 07:05:24 +0000
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
Message-ID: <44ece79531b41ff5827a452cfb9b1e841a09be4f.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +struct mtk_hdmi_ver_conf {
> +       const struct drm_bridge_funcs *bridge_funcs;
> +       const struct hdmi_codec_ops *codec_ops;
> +       const char * const *mtk_hdmi_clock_names;
> +       int num_clocks;
> +       bool hdr_support;
> +};

Because this patch is a little big. So I would like to separate struct mtk_hdmi_ver_conf related part to an independent patch.
The modification is still in mtk_hdmi.c
And the rest part is moving common part to mtk_hdmi_common.c


Regards,
CK

From ck.hu at mediatek.com  Sun Dec  8 23:19:05 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 9 Dec 2024 07:19:05 +0000
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
Message-ID: <b5ef21a17e9c881704143c1af0b6a025c7ce1523.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/Kconfig           |  11 +-
>  drivers/gpu/drm/mediatek/Makefile          |   1 +
>  drivers/gpu/drm/mediatek/mtk_hdmi.c        | 724 +++------------------
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 425 ++++++++++++
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.h | 203 ++++++
>  5 files changed, 729 insertions(+), 635 deletions(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> 
> diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
> index f496e6cfdfe0..73459f07dae3 100644
> --- a/drivers/gpu/drm/mediatek/Kconfig
> +++ b/drivers/gpu/drm/mediatek/Kconfig
> @@ -34,10 +34,19 @@ config DRM_MEDIATEK_DP
>         help
>           DRM/KMS Display Port driver for MediaTek SoCs.
> 
> +config DRM_MEDIATEK_HDMI_COMMON
> +       tristate
> +       depends on DRM_MEDIATEK
> +       select DRM_DISPLAY_HDMI_HELPER
> +       select DRM_DISPLAY_HELPER
> +       select SND_SOC_HDMI_CODEC if SND_SOC
> +       help
> +         MediaTek SoC HDMI common library
> +
>  config DRM_MEDIATEK_HDMI
>         tristate "DRM HDMI Support for Mediatek SoCs"
>         depends on DRM_MEDIATEK
> -       select SND_SOC_HDMI_CODEC if SND_SOC
> +       select DRM_MEDIATEK_HDMI_COMMON
>         select PHY_MTK_HDMI
>         help
>           DRM/KMS HDMI driver for Mediatek SoCs
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index 32a2ed6c0cfe..8973d7ba37d3 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -25,6 +25,7 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
>                           mtk_hdmi.o \
>                           mtk_hdmi_ddc.o
> 
> +obj-$(CONFIG_DRM_MEDIATEK_HDMI_COMMON) += mtk_hdmi_common.o
>  obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
> 
>  obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index 7808141526fa..44b2bc55afa3 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -31,6 +31,7 @@
>  #include <drm/drm_probe_helper.h>
> 
>  #include "mtk_cec.h"
> +#include "mtk_hdmi_common.h"
>  #include "mtk_hdmi_regs.h"
> 
>  #define NCTS_BYTES     7
> @@ -43,149 +44,13 @@ enum mtk_hdmi_clk_id {
>         MTK_HDMI_CLK_COUNT
>  };
> 
> -enum hdmi_aud_input_type {
> -       HDMI_AUD_INPUT_I2S = 0,
> -       HDMI_AUD_INPUT_SPDIF,
> -};
> -
> -enum hdmi_aud_i2s_fmt {
> -       HDMI_I2S_MODE_RJT_24BIT = 0,
> -       HDMI_I2S_MODE_RJT_16BIT,
> -       HDMI_I2S_MODE_LJT_24BIT,
> -       HDMI_I2S_MODE_LJT_16BIT,
> -       HDMI_I2S_MODE_I2S_24BIT,
> -       HDMI_I2S_MODE_I2S_16BIT
> -};
> -
> -enum hdmi_aud_mclk {
> -       HDMI_AUD_MCLK_128FS,
> -       HDMI_AUD_MCLK_192FS,
> -       HDMI_AUD_MCLK_256FS,
> -       HDMI_AUD_MCLK_384FS,
> -       HDMI_AUD_MCLK_512FS,
> -       HDMI_AUD_MCLK_768FS,
> -       HDMI_AUD_MCLK_1152FS,
> -};
> -
> -enum hdmi_aud_channel_type {
> -       HDMI_AUD_CHAN_TYPE_1_0 = 0,
> -       HDMI_AUD_CHAN_TYPE_1_1,
> -       HDMI_AUD_CHAN_TYPE_2_0,
> -       HDMI_AUD_CHAN_TYPE_2_1,
> -       HDMI_AUD_CHAN_TYPE_3_0,
> -       HDMI_AUD_CHAN_TYPE_3_1,
> -       HDMI_AUD_CHAN_TYPE_4_0,
> -       HDMI_AUD_CHAN_TYPE_4_1,
> -       HDMI_AUD_CHAN_TYPE_5_0,
> -       HDMI_AUD_CHAN_TYPE_5_1,
> -       HDMI_AUD_CHAN_TYPE_6_0,
> -       HDMI_AUD_CHAN_TYPE_6_1,
> -       HDMI_AUD_CHAN_TYPE_7_0,
> -       HDMI_AUD_CHAN_TYPE_7_1,
> -       HDMI_AUD_CHAN_TYPE_3_0_LRS,
> -       HDMI_AUD_CHAN_TYPE_3_1_LRS,
> -       HDMI_AUD_CHAN_TYPE_4_0_CLRS,
> -       HDMI_AUD_CHAN_TYPE_4_1_CLRS,
> -       HDMI_AUD_CHAN_TYPE_6_1_CS,
> -       HDMI_AUD_CHAN_TYPE_6_1_CH,
> -       HDMI_AUD_CHAN_TYPE_6_1_OH,
> -       HDMI_AUD_CHAN_TYPE_6_1_CHR,
> -       HDMI_AUD_CHAN_TYPE_7_1_LH_RH,
> -       HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR,
> -       HDMI_AUD_CHAN_TYPE_7_1_LC_RC,
> -       HDMI_AUD_CHAN_TYPE_7_1_LW_RW,
> -       HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD,
> -       HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS,
> -       HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS,
> -       HDMI_AUD_CHAN_TYPE_7_1_CS_CH,
> -       HDMI_AUD_CHAN_TYPE_7_1_CS_OH,
> -       HDMI_AUD_CHAN_TYPE_7_1_CS_CHR,
> -       HDMI_AUD_CHAN_TYPE_7_1_CH_OH,
> -       HDMI_AUD_CHAN_TYPE_7_1_CH_CHR,
> -       HDMI_AUD_CHAN_TYPE_7_1_OH_CHR,
> -       HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR,
> -       HDMI_AUD_CHAN_TYPE_6_0_CS,
> -       HDMI_AUD_CHAN_TYPE_6_0_CH,
> -       HDMI_AUD_CHAN_TYPE_6_0_OH,
> -       HDMI_AUD_CHAN_TYPE_6_0_CHR,
> -       HDMI_AUD_CHAN_TYPE_7_0_LH_RH,
> -       HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR,
> -       HDMI_AUD_CHAN_TYPE_7_0_LC_RC,
> -       HDMI_AUD_CHAN_TYPE_7_0_LW_RW,
> -       HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD,
> -       HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS,
> -       HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS,
> -       HDMI_AUD_CHAN_TYPE_7_0_CS_CH,
> -       HDMI_AUD_CHAN_TYPE_7_0_CS_OH,
> -       HDMI_AUD_CHAN_TYPE_7_0_CS_CHR,
> -       HDMI_AUD_CHAN_TYPE_7_0_CH_OH,
> -       HDMI_AUD_CHAN_TYPE_7_0_CH_CHR,
> -       HDMI_AUD_CHAN_TYPE_7_0_OH_CHR,
> -       HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR,
> -       HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS,
> -       HDMI_AUD_CHAN_TYPE_UNKNOWN = 0xFF
> -};
> -
> -enum hdmi_aud_channel_swap_type {
> -       HDMI_AUD_SWAP_LR,
> -       HDMI_AUD_SWAP_LFE_CC,
> -       HDMI_AUD_SWAP_LSRS,
> -       HDMI_AUD_SWAP_RLS_RRS,
> -       HDMI_AUD_SWAP_LR_STATUS,
> -};
> -
> -struct hdmi_audio_param {
> -       enum hdmi_audio_coding_type aud_codec;
> -       enum hdmi_audio_sample_size aud_sample_size;
> -       enum hdmi_aud_input_type aud_input_type;
> -       enum hdmi_aud_i2s_fmt aud_i2s_fmt;
> -       enum hdmi_aud_mclk aud_mclk;
> -       enum hdmi_aud_channel_type aud_input_chan_type;
> -       struct hdmi_codec_params codec_params;
> -};
> -
> -struct mtk_hdmi_conf {
> -       bool tz_disabled;
> -       bool cea_modes_only;
> -       unsigned long max_mode_clock;
> -};
> -
> -struct mtk_hdmi {
> -       struct drm_bridge bridge;
> -       struct drm_bridge *next_bridge;
> -       struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */
> -       struct device *dev;
> -       const struct mtk_hdmi_conf *conf;
> -       struct phy *phy;
> -       struct device *cec_dev;
> -       struct i2c_adapter *ddc_adpt;
> -       struct clk *clk[MTK_HDMI_CLK_COUNT];
> -       struct drm_display_mode mode;
> -       bool dvi_mode;
> -       u32 min_clock;
> -       u32 max_clock;
> -       u32 max_hdisplay;
> -       u32 max_vdisplay;
> -       u32 ibias;
> -       u32 ibias_up;
> -       struct regmap *sys_regmap;
> -       unsigned int sys_offset;
> -       struct regmap *regs;
> -       enum hdmi_colorspace csp;
> -       struct hdmi_audio_param aud_param;
> -       bool audio_enable;
> -       bool powered;
> -       bool enabled;
> -       hdmi_codec_plugged_cb plugged_cb;
> -       struct device *codec_dev;
> -       struct mutex update_plugged_status_lock;
> +const char * const mtk_hdmi_clk_names_v1[MTK_HDMI_CLK_COUNT] = {
> +       [MTK_HDMI_CLK_HDMI_PIXEL] = "pixel",
> +       [MTK_HDMI_CLK_HDMI_PLL] = "pll",
> +       [MTK_HDMI_CLK_AUD_BCLK] = "bclk",
> +       [MTK_HDMI_CLK_AUD_SPDIF] = "spdif",
>  };
> 
> -static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
> -{
> -       return container_of(b, struct mtk_hdmi, bridge);
> -}
> -
>  static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)
>  {
>         regmap_update_bits(hdmi->regs, VIDEO_SOURCE_SEL,
> @@ -606,81 +471,6 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
>         regmap_write(hdmi->regs, GRL_CFG5, val);
>  }
> 
> -struct hdmi_acr_n {
> -       unsigned int clock;
> -       unsigned int n[3];
> -};
> -
> -/* Recommended N values from HDMI specification, tables 7-1 to 7-3 */
> -static const struct hdmi_acr_n hdmi_rec_n_table[] = {
> -       /* Clock, N: 32kHz 44.1kHz 48kHz */
> -       {  25175, {  4576,  7007,  6864 } },
> -       {  74176, { 11648, 17836, 11648 } },
> -       { 148352, { 11648,  8918,  5824 } },
> -       { 296703, {  5824,  4459,  5824 } },
> -       { 297000, {  3072,  4704,  5120 } },
> -       {      0, {  4096,  6272,  6144 } }, /* all other TMDS clocks */
> -};
> -
> -/**
> - * hdmi_recommended_n() - Return N value recommended by HDMI specification
> - * @freq: audio sample rate in Hz
> - * @clock: rounded TMDS clock in kHz
> - */
> -static unsigned int hdmi_recommended_n(unsigned int freq, unsigned int clock)
> -{
> -       const struct hdmi_acr_n *recommended;
> -       unsigned int i;
> -
> -       for (i = 0; i < ARRAY_SIZE(hdmi_rec_n_table) - 1; i++) {
> -               if (clock == hdmi_rec_n_table[i].clock)
> -                       break;
> -       }
> -       recommended = hdmi_rec_n_table + i;
> -
> -       switch (freq) {
> -       case 32000:
> -               return recommended->n[0];
> -       case 44100:
> -               return recommended->n[1];
> -       case 48000:
> -               return recommended->n[2];
> -       case 88200:
> -               return recommended->n[1] * 2;
> -       case 96000:
> -               return recommended->n[2] * 2;
> -       case 176400:
> -               return recommended->n[1] * 4;
> -       case 192000:
> -               return recommended->n[2] * 4;
> -       default:
> -               return (128 * freq) / 1000;
> -       }
> -}
> -
> -static unsigned int hdmi_mode_clock_to_hz(unsigned int clock)
> -{
> -       switch (clock) {
> -       case 25175:
> -               return 25174825;        /* 25.2/1.001 MHz */
> -       case 74176:
> -               return 74175824;        /* 74.25/1.001 MHz */
> -       case 148352:
> -               return 148351648;       /* 148.5/1.001 MHz */
> -       case 296703:
> -               return 296703297;       /* 297/1.001 MHz */
> -       default:
> -               return clock * 1000;
> -       }
> -}
> -
> -static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate,
> -                                     unsigned int tmds_clock, unsigned int n)
> -{
> -       return DIV_ROUND_CLOSEST_ULL((u64)hdmi_mode_clock_to_hz(tmds_clock) * n,
> -                                    128 * audio_sample_rate);
> -}
> -
>  static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,
>                                     unsigned int cts)
>  {
> @@ -710,9 +500,13 @@ static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
>                                      unsigned int clock)
>  {
>         unsigned int n, cts;
> +       int ret;
> 
> -       n = hdmi_recommended_n(sample_rate, clock);
> -       cts = hdmi_expected_cts(sample_rate, clock, n);
> +       ret = mtk_hdmi_get_ncts(sample_rate, clock, &n, &cts);
> +       if (ret) {
> +               dev_err(hdmi->dev, "Invalid sample rate: %u\n", sample_rate);
> +               return;
> +       }
> 
>         dev_dbg(hdmi->dev, "%s: sample_rate=%u, clock=%d, cts=%u, n=%u\n",
>                 __func__, sample_rate, clock, n, cts);
> @@ -829,7 +623,6 @@ static void mtk_hdmi_video_set_display_mode(struct mtk_hdmi *hdmi,
>         mtk_hdmi_hw_msic_setting(hdmi, mode);
>  }
> 
> -
>  static void mtk_hdmi_aud_set_input(struct mtk_hdmi *hdmi)
>  {
>         enum hdmi_aud_channel_type chan_type;
> @@ -920,53 +713,46 @@ static int mtk_hdmi_aud_output_config(struct mtk_hdmi *hdmi,
>         return 0;
>  }
> 
> -static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi,
> +static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, size_t bufsz,
>                                         struct drm_display_mode *mode)
>  {
>         struct hdmi_avi_infoframe frame;
> -       u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
>         ssize_t err;
> 
> -       err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
> -                                                      hdmi->curr_conn, mode);
> +       err = drm_hdmi_avi_infoframe_from_display_mode(&frame, hdmi->curr_conn, mode);
>         if (err < 0) {
>                 dev_err(hdmi->dev,
>                         "Failed to get AVI infoframe from mode: %zd\n", err);
>                 return err;
>         }
> 
> -       err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
> +       err = hdmi_avi_infoframe_pack(&frame, buffer, bufsz);
>         if (err < 0) {
>                 dev_err(hdmi->dev, "Failed to pack AVI infoframe: %zd\n", err);
>                 return err;
>         }
> 
> -       mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer));
>         return 0;
>  }
> 
> -static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi,
> -                                       const char *vendor,
> -                                       const char *product)
> +static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi, u8 *buffer, size_t bufsz,
> +                                       const char *vendor, const char *product)
>  {
>         struct hdmi_spd_infoframe frame;
> -       u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE];
>         ssize_t err;
> 
>         err = hdmi_spd_infoframe_init(&frame, vendor, product);
>         if (err < 0) {
> -               dev_err(hdmi->dev, "Failed to initialize SPD infoframe: %zd\n",
> -                       err);
> +               dev_err(hdmi->dev, "Failed to initialize SPD infoframe: %zd\n", err);
>                 return err;
>         }
> 
> -       err = hdmi_spd_infoframe_pack(&frame, buffer, sizeof(buffer));
> +       err = hdmi_spd_infoframe_pack(&frame, buffer, bufsz);
>         if (err < 0) {
>                 dev_err(hdmi->dev, "Failed to pack SDP infoframe: %zd\n", err);
>                 return err;
>         }
> 
> -       mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer));
>         return 0;
>  }
> 
> @@ -1026,19 +812,12 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi,
>         return 0;
>  }
> 
> -static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
> +static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, u8 *buffer_spd, size_t bufsz_spd,
> +                                   u8 *buffer_avi, size_t bufsz_avi,
> +                                   struct drm_display_mode *mode)
>  {
> -       struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> -
> -       hdmi->csp = HDMI_COLORSPACE_RGB;
> -       aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -       aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> -       aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> -       aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> -       aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> -       aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> -
> -       return 0;
> +       mtk_hdmi_setup_avi_infoframe(hdmi, buffer_avi, bufsz_avi, mode);
> +       mtk_hdmi_setup_spd_infoframe(hdmi, buffer_spd, bufsz_spd, "mediatek", "On-chip HDMI");
>  }
> 
>  static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)
> @@ -1053,20 +832,6 @@ static void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi)
>         hdmi->audio_enable = false;
>  }
> 
> -static int mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi,
> -                                   struct hdmi_audio_param *param)
> -{
> -       if (!hdmi->audio_enable) {
> -               dev_err(hdmi->dev, "hdmi audio is in disable state!\n");
> -               return -EINVAL;
> -       }
> -       dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",
> -               param->aud_codec, param->aud_input_type,
> -               param->aud_input_chan_type, param->codec_params.sample_rate);
> -       memcpy(&hdmi->aud_param, param, sizeof(*param));
> -       return mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);
> -}
> -
>  static int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi,
>                                             struct drm_display_mode *mode)
>  {
> @@ -1095,27 +860,6 @@ static int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi,
>         return 0;
>  }
> 
> -static const char * const mtk_hdmi_clk_names[MTK_HDMI_CLK_COUNT] = {
> -       [MTK_HDMI_CLK_HDMI_PIXEL] = "pixel",
> -       [MTK_HDMI_CLK_HDMI_PLL] = "pll",
> -       [MTK_HDMI_CLK_AUD_BCLK] = "bclk",
> -       [MTK_HDMI_CLK_AUD_SPDIF] = "spdif",
> -};
> -
> -static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi,
> -                               struct device_node *np)
> -{
> -       int i;
> -
> -       for (i = 0; i < ARRAY_SIZE(mtk_hdmi_clk_names); i++) {
> -               hdmi->clk[i] = of_clk_get_by_name(np,
> -                                                 mtk_hdmi_clk_names[i]);
> -               if (IS_ERR(hdmi->clk[i]))
> -                       return PTR_ERR(hdmi->clk[i]);
> -       }
> -       return 0;
> -}
> -
>  static int mtk_hdmi_clk_enable_audio(struct mtk_hdmi *hdmi)
>  {
>         int ret;
> @@ -1125,13 +869,12 @@ static int mtk_hdmi_clk_enable_audio(struct mtk_hdmi *hdmi)
>                 return ret;
> 
>         ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]);
> -       if (ret)
> -               goto err;
> +       if (ret) {
> +               clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);
> +               return ret;
> +       }
> 
>         return 0;
> -err:
> -       clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);
> -       return ret;
>  }
> 
>  static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi)
> @@ -1143,10 +886,11 @@ static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi)
>  static enum drm_connector_status
>  mtk_hdmi_update_plugged_status(struct mtk_hdmi *hdmi)
>  {
> -       bool connected;
> +       bool connected = true;
> 
>         mutex_lock(&hdmi->update_plugged_status_lock);
> -       connected = mtk_cec_hpd_high(hdmi->cec_dev);
> +       if (hdmi->cec_dev)
> +               connected = mtk_cec_hpd_high(hdmi->cec_dev);
>         if (hdmi->plugged_cb && hdmi->codec_dev)
>                 hdmi->plugged_cb(hdmi->codec_dev, connected);
>         mutex_unlock(&hdmi->update_plugged_status_lock);
> @@ -1254,18 +998,12 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge,
>                         return ret;
>         }
> 
> -       mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, hdmi->dev);
> +       if (hdmi->cec_dev)
> +               mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, hdmi->dev);
> 
>         return 0;
>  }
> 
> -static bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
> -                                      const struct drm_display_mode *mode,
> -                                      struct drm_display_mode *adjusted_mode)
> -{
> -       return true;
> -}
> -
>  static void mtk_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
>                                            struct drm_bridge_state *old_bridge_state)
>  {
> @@ -1297,28 +1035,6 @@ static void mtk_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
>         hdmi->powered = false;
>  }
> 
> -static void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
> -                               const struct drm_display_mode *mode,
> -                               const struct drm_display_mode *adjusted_mode)
> -{
> -       struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> -
> -       dev_dbg(hdmi->dev, "cur info: name:%s, hdisplay:%d\n",
> -               adjusted_mode->name, adjusted_mode->hdisplay);
> -       dev_dbg(hdmi->dev, "hsync_start:%d,hsync_end:%d, htotal:%d",
> -               adjusted_mode->hsync_start, adjusted_mode->hsync_end,
> -               adjusted_mode->htotal);
> -       dev_dbg(hdmi->dev, "hskew:%d, vdisplay:%d\n",
> -               adjusted_mode->hskew, adjusted_mode->vdisplay);
> -       dev_dbg(hdmi->dev, "vsync_start:%d, vsync_end:%d, vtotal:%d",
> -               adjusted_mode->vsync_start, adjusted_mode->vsync_end,
> -               adjusted_mode->vtotal);
> -       dev_dbg(hdmi->dev, "vscan:%d, flag:%d\n",
> -               adjusted_mode->vscan, adjusted_mode->flags);
> -
> -       drm_mode_copy(&hdmi->mode, adjusted_mode);
> -}
> -
>  static void mtk_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
>                                               struct drm_bridge_state *old_state)
>  {
> @@ -1330,21 +1046,13 @@ static void mtk_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
>         hdmi->powered = true;
>  }
> 
> -static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi,
> -                                   struct drm_display_mode *mode)
> -{
> -       mtk_hdmi_setup_audio_infoframe(hdmi);
> -       mtk_hdmi_setup_avi_infoframe(hdmi, mode);
> -       mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI");
> -       if (mode->flags & DRM_MODE_FLAG_3D_MASK)
> -               mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode);
> -}
> -
>  static void mtk_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
>                                           struct drm_bridge_state *old_state)
>  {
>         struct drm_atomic_state *state = old_state->base.state;
>         struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +       u8 buffer_spd[HDMI_INFOFRAME_SIZE(SPD)];
> +       u8 buffer_avi[HDMI_INFOFRAME_SIZE(AVI)];
> 
>         /* Retrieve the connector through the atomic state. */
>         hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state,
> @@ -1354,12 +1062,16 @@ static void mtk_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
>         clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]);
>         clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]);
>         phy_power_on(hdmi->phy);
> -       mtk_hdmi_send_infoframe(hdmi, &hdmi->mode);
> +       mtk_hdmi_setup_audio_infoframe(hdmi);
> +       mtk_hdmi_send_infoframe(hdmi, buffer_spd, sizeof(buffer_spd),
> +                               buffer_avi, sizeof(buffer_avi), &hdmi->mode);
> +       if (hdmi->mode.flags & DRM_MODE_FLAG_3D_MASK)
> +               mtk_hdmi_setup_vendor_specific_infoframe(hdmi, &hdmi->mode);
> 
>         hdmi->enabled = true;
>  }
> 
> -static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = {
> +const struct drm_bridge_funcs mtk_mt8183_hdmi_bridge_funcs = {
>         .mode_valid = mtk_hdmi_bridge_mode_valid,
>         .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
>         .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> @@ -1375,180 +1087,19 @@ static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = {
>         .edid_read = mtk_hdmi_bridge_edid_read,
>  };
> 
> -static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
> -                                  struct platform_device *pdev)
> -{
> -       struct device *dev = &pdev->dev;
> -       struct device_node *np = dev->of_node;
> -       struct device_node *cec_np, *remote, *i2c_np;
> -       struct platform_device *cec_pdev;
> -       struct regmap *regmap;
> -       int ret;
> -
> -       ret = mtk_hdmi_get_all_clk(hdmi, np);
> -       if (ret) {
> -               if (ret != -EPROBE_DEFER)
> -                       dev_err(dev, "Failed to get clocks: %d\n", ret);
> -
> -               return ret;
> -       }
> -
> -       /* The CEC module handles HDMI hotplug detection */
> -       cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
> -       if (!cec_np) {
> -               dev_err(dev, "Failed to find CEC node\n");
> -               return -EINVAL;
> -       }
> -
> -       cec_pdev = of_find_device_by_node(cec_np);
> -       if (!cec_pdev) {
> -               dev_err(hdmi->dev, "Waiting for CEC device %pOF\n",
> -                       cec_np);
> -               of_node_put(cec_np);
> -               return -EPROBE_DEFER;
> -       }
> -       of_node_put(cec_np);
> -       hdmi->cec_dev = &cec_pdev->dev;
> -
> -       /*
> -        * The mediatek,syscon-hdmi property contains a phandle link to the
> -        * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG
> -        * registers it contains.
> -        */
> -       regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");
> -       ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1,
> -                                        &hdmi->sys_offset);
> -       if (IS_ERR(regmap))
> -               ret = PTR_ERR(regmap);
> -       if (ret) {
> -               dev_err(dev,
> -                       "Failed to get system configuration registers: %d\n",
> -                       ret);
> -               goto put_device;
> -       }
> -       hdmi->sys_regmap = regmap;
> -
> -       hdmi->regs = device_node_to_regmap(dev->of_node);
> -       if (IS_ERR(hdmi->regs)) {
> -               ret = PTR_ERR(hdmi->regs);
> -               goto put_device;
> -       }
> -
> -       remote = of_graph_get_remote_node(np, 1, 0);
> -       if (!remote) {
> -               ret = -EINVAL;
> -               goto put_device;
> -       }
> -
> -       if (!of_device_is_compatible(remote, "hdmi-connector")) {
> -               hdmi->next_bridge = of_drm_find_bridge(remote);
> -               if (!hdmi->next_bridge) {
> -                       dev_err(dev, "Waiting for external bridge\n");
> -                       of_node_put(remote);
> -                       ret = -EPROBE_DEFER;
> -                       goto put_device;
> -               }
> -       }
> -
> -       i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
> -       if (!i2c_np) {
> -               dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n",
> -                       remote);
> -               of_node_put(remote);
> -               ret = -EINVAL;
> -               goto put_device;
> -       }
> -       of_node_put(remote);
> -
> -       hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
> -       of_node_put(i2c_np);
> -       if (!hdmi->ddc_adpt) {
> -               dev_err(dev, "Failed to get ddc i2c adapter by node\n");
> -               ret = -EINVAL;
> -               goto put_device;
> -       }
> -
> -       return 0;
> -put_device:
> -       put_device(hdmi->cec_dev);
> -       return ret;
> -}
> -
>  /*
>   * HDMI audio codec callbacks
>   */
> -
>  static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
>                                     struct hdmi_codec_daifmt *daifmt,
>                                     struct hdmi_codec_params *params)
>  {
>         struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> -       struct hdmi_audio_param hdmi_params;
> -       unsigned int chan = params->cea.channels;
> -
> -       dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
> -               params->sample_rate, params->sample_width, chan);
> -
> -       if (!hdmi->bridge.encoder)
> -               return -ENODEV;
> -
> -       switch (chan) {
> -       case 2:
> -               hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> -               break;
> -       case 4:
> -               hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
> -               break;
> -       case 6:
> -               hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
> -               break;
> -       case 8:
> -               hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
> -               break;
> -       default:
> -               dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
> -               return -EINVAL;
> -       }
> -
> -       switch (params->sample_rate) {
> -       case 32000:
> -       case 44100:
> -       case 48000:
> -       case 88200:
> -       case 96000:
> -       case 176400:
> -       case 192000:
> -               break;
> -       default:
> -               dev_err(hdmi->dev, "rate[%d] not supported!\n",
> -                       params->sample_rate);
> -               return -EINVAL;
> -       }
> 
> -       switch (daifmt->fmt) {
> -       case HDMI_I2S:
> -               hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -               hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> -               hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
> -               hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> -               hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
> -               break;
> -       case HDMI_SPDIF:
> -               hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -               hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> -               hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
> -               break;
> -       default:
> -               dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,
> -                       daifmt->fmt);
> -               return -EINVAL;
> +       if (hdmi->audio_enable) {
> +               mtk_hdmi_audio_params(hdmi, daifmt, params);
> +               mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);
>         }
> -
> -       memcpy(&hdmi_params.codec_params, params,
> -              sizeof(hdmi_params.codec_params));
> -
> -       mtk_hdmi_audio_set_param(hdmi, &hdmi_params);
> -
>         return 0;
>  }
> 
> @@ -1582,28 +1133,13 @@ mtk_hdmi_audio_mute(struct device *dev, void *data,
>         return 0;
>  }
> 
> -static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len)
> -{
> -       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> -
> -       if (hdmi->enabled)
> -               memcpy(buf, hdmi->curr_conn->eld, min(sizeof(hdmi->curr_conn->eld), len));
> -       else
> -               memset(buf, 0, len);
> -       return 0;
> -}
> -
>  static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,
>                                           hdmi_codec_plugged_cb fn,
>                                           struct device *codec_dev)
>  {
>         struct mtk_hdmi *hdmi = data;
> 
> -       mutex_lock(&hdmi->update_plugged_status_lock);
> -       hdmi->plugged_cb = fn;
> -       hdmi->codec_dev = codec_dev;
> -       mutex_unlock(&hdmi->update_plugged_status_lock);
> -
> +       mtk_hdmi_audio_set_plugged_cb(hdmi, fn, codec_dev);
>         mtk_hdmi_update_plugged_status(hdmi);
> 
>         return 0;
> @@ -1619,165 +1155,85 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
>         .no_capture_mute = 1,
>  };
> 
> -static int mtk_hdmi_register_audio_driver(struct device *dev)
> +static __maybe_unused int mtk_hdmi_suspend(struct device *dev)
>  {
>         struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> -       struct hdmi_codec_pdata codec_data = {
> -               .ops = &mtk_hdmi_audio_codec_ops,
> -               .max_i2s_channels = 2,
> -               .i2s = 1,
> -               .data = hdmi,
> -       };
> -       struct platform_device *pdev;
> -
> -       pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
> -                                            PLATFORM_DEVID_AUTO, &codec_data,
> -                                            sizeof(codec_data));
> -       if (IS_ERR(pdev))
> -               return PTR_ERR(pdev);
> -
> -       DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
> +
> +       mtk_hdmi_clk_disable_audio(hdmi);
> +
>         return 0;
>  }
> 
> -static int mtk_hdmi_probe(struct platform_device *pdev)
> +static __maybe_unused int mtk_hdmi_resume(struct device *dev)
>  {
> -       struct mtk_hdmi *hdmi;
> -       struct device *dev = &pdev->dev;
> -       int ret;
> -
> -       hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
> -       if (!hdmi)
> -               return -ENOMEM;
> +       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> 
> -       hdmi->dev = dev;
> -       hdmi->conf = of_device_get_match_data(dev);
> +       return mtk_hdmi_clk_enable_audio(hdmi);
> +}
> 
> -       ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev);
> -       if (ret)
> -               return ret;
> +static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops, mtk_hdmi_suspend, mtk_hdmi_resume);
> 
> -       hdmi->phy = devm_phy_get(dev, "hdmi");
> -       if (IS_ERR(hdmi->phy))
> -               return dev_err_probe(dev, PTR_ERR(hdmi->phy),
> -                                    "Failed to get HDMI PHY\n");
> +static const struct mtk_hdmi_ver_conf mtk_hdmi_v1_ver_conf = {
> +       .bridge_funcs = &mtk_mt8183_hdmi_bridge_funcs,
> +       .codec_ops = &mtk_hdmi_audio_codec_ops,
> +       .mtk_hdmi_clock_names = mtk_hdmi_clk_names_v1,
> +       .num_clocks = ARRAY_SIZE(mtk_hdmi_clk_names_v1)
> +};
> 
> -       mutex_init(&hdmi->update_plugged_status_lock);
> -       platform_set_drvdata(pdev, hdmi);
> +static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = {
> +       .tz_disabled = true,
> +       .ver_conf = &mtk_hdmi_v1_ver_conf
> +};
> 
> -       ret = mtk_hdmi_output_init(hdmi);
> -       if (ret)
> -               return dev_err_probe(dev, ret,
> -                                    "Failed to initialize hdmi output\n");
> +static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 = {
> +       .max_mode_clock = 148500,
> +       .cea_modes_only = true,
> +       .ver_conf = &mtk_hdmi_v1_ver_conf
> +};
> 
> -       ret = mtk_hdmi_register_audio_driver(dev);
> -       if (ret)
> -               return dev_err_probe(dev, ret,
> -                                    "Failed to register audio driver\n");
> +static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8173 = {
> +       .ver_conf = &mtk_hdmi_v1_ver_conf
> +};
> 
> -       hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs;
> -       hdmi->bridge.of_node = pdev->dev.of_node;
> -       hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
> -                        | DRM_BRIDGE_OP_HPD;
> -       hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
> -       drm_bridge_add(&hdmi->bridge);
> +static int mtk_hdmi_probe(struct platform_device *pdev)
> +{
> +       struct mtk_hdmi *hdmi;
> 
> -       ret = mtk_hdmi_clk_enable_audio(hdmi);
> -       if (ret) {
> -               drm_bridge_remove(&hdmi->bridge);
> -               return dev_err_probe(dev, ret,
> -                                    "Failed to enable audio clocks\n");
> -       }
> +       hdmi = mtk_hdmi_common_probe(pdev);
> +       if (IS_ERR(hdmi))
> +               return PTR_ERR(hdmi);
> 
> -       return 0;
> +       return mtk_hdmi_clk_enable_audio(hdmi);
>  }
> 
>  static void mtk_hdmi_remove(struct platform_device *pdev)
>  {
>         struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
> 
> -       drm_bridge_remove(&hdmi->bridge);
> -       mtk_hdmi_clk_disable_audio(hdmi);
> -}
> -
> -#ifdef CONFIG_PM_SLEEP
> -static int mtk_hdmi_suspend(struct device *dev)
> -{
> -       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> -
>         mtk_hdmi_clk_disable_audio(hdmi);
> -
> -       return 0;
> -}
> -
> -static int mtk_hdmi_resume(struct device *dev)
> -{
> -       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> -       int ret = 0;
> -
> -       ret = mtk_hdmi_clk_enable_audio(hdmi);
> -       if (ret) {
> -               dev_err(dev, "hdmi resume failed!\n");
> -               return ret;
> -       }
> -
> -       return 0;
> +       i2c_put_adapter(hdmi->ddc_adpt);
>  }
> -#endif
> -static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops,
> -                        mtk_hdmi_suspend, mtk_hdmi_resume);
> -
> -static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = {
> -       .tz_disabled = true,
> -};
> -
> -static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 = {
> -       .max_mode_clock = 148500,
> -       .cea_modes_only = true,
> -};
> 
> -static const struct of_device_id mtk_hdmi_of_ids[] = {
> -       { .compatible = "mediatek,mt2701-hdmi",
> -         .data = &mtk_hdmi_conf_mt2701,
> -       },
> -       { .compatible = "mediatek,mt8167-hdmi",
> -         .data = &mtk_hdmi_conf_mt8167,
> -       },
> -       { .compatible = "mediatek,mt8173-hdmi",
> -       },
> -       {}
> +static const struct of_device_id mtk_drm_hdmi_of_ids[] = {
> +       { .compatible = "mediatek,mt2701-hdmi", .data = &mtk_hdmi_conf_mt2701 },
> +       { .compatible = "mediatek,mt8167-hdmi", .data = &mtk_hdmi_conf_mt8167 },
> +       { .compatible = "mediatek,mt8173-hdmi", .data = &mtk_hdmi_conf_mt8173 },
> +       { /* sentinel */ }
>  };
> -MODULE_DEVICE_TABLE(of, mtk_hdmi_of_ids);
> +MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids);
> 
>  static struct platform_driver mtk_hdmi_driver = {
>         .probe = mtk_hdmi_probe,
> -       .remove_new = mtk_hdmi_remove,
> +       .remove = mtk_hdmi_remove,
>         .driver = {
>                 .name = "mediatek-drm-hdmi",
> -               .of_match_table = mtk_hdmi_of_ids,
> +               .of_match_table = mtk_drm_hdmi_of_ids,
>                 .pm = &mtk_hdmi_pm_ops,
>         },
>  };
> -
> -static struct platform_driver * const mtk_hdmi_drivers[] = {
> -       &mtk_hdmi_driver,
> -};
> -
> -static int __init mtk_hdmitx_init(void)
> -{
> -       return platform_register_drivers(mtk_hdmi_drivers,
> -                                        ARRAY_SIZE(mtk_hdmi_drivers));
> -}
> -
> -static void __exit mtk_hdmitx_exit(void)
> -{
> -       platform_unregister_drivers(mtk_hdmi_drivers,
> -                                   ARRAY_SIZE(mtk_hdmi_drivers));
> -}
> -
> -module_init(mtk_hdmitx_init);
> -module_exit(mtk_hdmitx_exit);
> +module_platform_driver(mtk_hdmi_driver);
> 
>  MODULE_AUTHOR("Jie Qiu <jie.qiu at mediatek.com>");
> +MODULE_AUTHOR("Can Zeng <can.zeng at mediatek.com>");
>  MODULE_DESCRIPTION("MediaTek HDMI Driver");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> new file mode 100644
> index 000000000000..1b23ab6969ec
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> @@ -0,0 +1,425 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Copyright (c) 2022 BayLibre, SAS
> + * Copyright (c) 2024 Collabora Ltd.
> + *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> + */
> +
> +#include <drm/drm_modes.h>
> +#include <linux/device.h>
> +#include <linux/hdmi.h>
> +#include <linux/i2c.h>
> +#include <linux/math.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/syscon.h>
> +#include <sound/hdmi-codec.h>
> +
> +#include "mtk_hdmi_common.h"
> +
> +struct hdmi_acr_n {
> +       unsigned int clock;
> +       unsigned int n[3];
> +};
> +
> +/* Recommended N values from HDMI specification, tables 7-1 to 7-3 */
> +static const struct hdmi_acr_n hdmi_rec_n_table[] = {
> +       /* Clock, N: 32kHz 44.1kHz 48kHz */
> +       { 25175,  {  4576,  7007,  6864 } },
> +       { 74176,  { 11648, 17836, 11648 } },
> +       { 148352, { 11648,  8918,  5824 } },
> +       { 296703, {  5824,  4459,  5824 } },
> +       { 297000, {  3072,  4704,  5120 } },
> +       { 0,      {  4096,  6272,  6144 } }, /* all other TMDS clocks */
> +};
> +
> +/**
> + * hdmi_recommended_n() - Return N value recommended by HDMI specification
> + * @freq: audio sample rate in Hz
> + * @clock: rounded TMDS clock in kHz
> + */
> +static int hdmi_recommended_n(unsigned int freq, unsigned int clock)
> +{
> +       const struct hdmi_acr_n *recommended;
> +       unsigned int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(hdmi_rec_n_table) - 1; i++) {
> +               if (clock == hdmi_rec_n_table[i].clock)
> +                       break;
> +       }
> +
> +       if (i == ARRAY_SIZE(hdmi_rec_n_table))
> +               return -EINVAL;
> +
> +       recommended = hdmi_rec_n_table + i;
> +
> +       switch (freq) {
> +       case 32000:
> +               return recommended->n[0];
> +       case 44100:
> +               return recommended->n[1];
> +       case 48000:
> +               return recommended->n[2];
> +       case 88200:
> +               return recommended->n[1] * 2;
> +       case 96000:
> +               return recommended->n[2] * 2;
> +       case 176400:
> +               return recommended->n[1] * 4;
> +       case 192000:
> +               return recommended->n[2] * 4;
> +       default:
> +               return (128 * freq) / 1000;
> +       }
> +}
> +
> +static unsigned int hdmi_mode_clock_to_hz(unsigned int clock)
> +{
> +       switch (clock) {
> +       case 25175:
> +               return 25174825; /* 25.2/1.001 MHz */
> +       case 74176:
> +               return 74175824; /* 74.25/1.001 MHz */
> +       case 148352:
> +               return 148351648; /* 148.5/1.001 MHz */
> +       case 296703:
> +               return 296703297; /* 297/1.001 MHz */
> +       default:
> +               return clock * 1000;
> +       }
> +}
> +
> +static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate,
> +                                     unsigned int tmds_clock, unsigned int n)
> +{
> +       return DIV_ROUND_CLOSEST_ULL((u64)hdmi_mode_clock_to_hz(tmds_clock) * n,
> +                                    128 * audio_sample_rate);
> +}
> +
> +int mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock,
> +                     unsigned int *n, unsigned int *cts)
> +{
> +       int rec_n = hdmi_recommended_n(sample_rate, clock);
> +
> +       if (rec_n < 0)
> +               return rec_n;
> +
> +       *cts = hdmi_expected_cts(sample_rate, clock, rec_n);
> +       *n = rec_n;
> +
> +       return 0;
> +}
> +
> +int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi,
> +                         struct hdmi_codec_daifmt *daifmt,
> +                         struct hdmi_codec_params *params)
> +{
> +       struct hdmi_audio_param aud_params = { 0 };
> +       unsigned int chan = params->cea.channels;
> +
> +       dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
> +               params->sample_rate, params->sample_width, chan);
> +
> +       if (!hdmi->bridge.encoder)
> +               return -ENODEV;
> +
> +       switch (chan) {
> +       case 2:
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> +               break;
> +       case 4:
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
> +               break;
> +       case 6:
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
> +               break;
> +       case 8:
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
> +               break;
> +       default:
> +               dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
> +               return -EINVAL;
> +       }
> +
> +       switch (params->sample_rate) {
> +       case 32000:
> +       case 44100:
> +       case 48000:
> +       case 88200:
> +       case 96000:
> +       case 176400:
> +       case 192000:
> +               break;
> +       default:
> +               dev_err(hdmi->dev, "rate[%d] not supported!\n",
> +                       params->sample_rate);
> +               return -EINVAL;
> +       }
> +
> +       switch (daifmt->fmt) {
> +       case HDMI_I2S:
> +               aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +               aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +               aud_params.aud_input_type = HDMI_AUD_INPUT_I2S;
> +               aud_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> +               aud_params.aud_mclk = HDMI_AUD_MCLK_128FS;
> +               break;
> +       case HDMI_SPDIF:
> +               aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +               aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +               aud_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
> +               break;
> +       default:
> +               dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,
> +                       daifmt->fmt);
> +               return -EINVAL;
> +       }
> +       memcpy(&aud_params.codec_params, params, sizeof(aud_params.codec_params));
> +       memcpy(&hdmi->aud_param, &aud_params, sizeof(aud_params));
> +
> +       dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",
> +               aud_params.aud_codec, aud_params.aud_input_type,
> +               aud_params.aud_input_chan_type, aud_params.codec_params.sample_rate);
> +
> +       return 0;
> +}
> +
> +int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len)
> +{
> +       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +
> +       if (hdmi->enabled)
> +               memcpy(buf, hdmi->curr_conn->eld, min(sizeof(hdmi->curr_conn->eld), len));
> +       else
> +               memset(buf, 0, len);
> +
> +       return 0;
> +}
> +
> +void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn,
> +                                  struct device *codec_dev)
> +{
> +       mutex_lock(&hdmi->update_plugged_status_lock);
> +       hdmi->plugged_cb = fn;
> +       hdmi->codec_dev = codec_dev;
> +       mutex_unlock(&hdmi->update_plugged_status_lock);
> +}
> +
> +static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi, struct device_node *np,
> +                               const char * const *mtk_hdmi_clk_names, size_t num_clocks)
> +{
> +       int i;
> +
> +       for (i = 0; i < num_clocks; i++) {
> +               hdmi->clk[i] = of_clk_get_by_name(np, mtk_hdmi_clk_names[i]);
> +
> +               if (IS_ERR(hdmi->clk[i]))
> +                       return PTR_ERR(hdmi->clk[i]);
> +       }
> +
> +       return 0;
> +}
> +
> +bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
> +                               const struct drm_display_mode *mode,
> +                               struct drm_display_mode *adjusted_mode)
> +{
> +       return true;
> +}
> +
> +void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
> +                             const struct drm_display_mode *mode,
> +                             const struct drm_display_mode *adjusted_mode)
> +{
> +       struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +
> +       drm_mode_copy(&hdmi->mode, adjusted_mode);
> +}
> +
> +static int mtk_hdmi_get_cec_dev(struct mtk_hdmi *hdmi, struct device *dev, struct device_node *np)
> +{
> +       struct platform_device *cec_pdev;
> +       struct device_node *cec_np;
> +       int ret;
> +
> +       /* The CEC module handles HDMI hotplug detection */
> +       cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
> +       if (!cec_np)
> +               return dev_err_probe(dev, -ENOTSUPP, "Failed to find CEC node\n");
> +
> +       cec_pdev = of_find_device_by_node(cec_np);
> +       if (!cec_pdev) {
> +               dev_err(hdmi->dev, "Waiting for CEC device %pOF\n", cec_np);
> +               of_node_put(cec_np);
> +               return -EPROBE_DEFER;
> +       }
> +       of_node_put(cec_np);
> +
> +       /*
> +        * The mediatek,syscon-hdmi property contains a phandle link to the
> +        * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG
> +        * registers it contains.
> +        */
> +       hdmi->sys_regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");
> +       if (IS_ERR(hdmi->sys_regmap))
> +               return PTR_ERR(hdmi->sys_regmap);
> +
> +       ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, &hdmi->sys_offset);
> +       if (ret)
> +               return dev_err_probe(dev, ret,
> +                                    "Failed to get system configuration registers\n");
> +
> +       hdmi->cec_dev = &cec_pdev->dev;
> +       return 0;
> +}
> +
> +static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device *pdev,
> +                                  const char * const *clk_names, size_t num_clocks)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct device_node *np = dev->of_node;
> +       struct device_node *remote, *i2c_np;
> +       int ret;
> +
> +       ret = mtk_hdmi_get_all_clk(hdmi, np, clk_names, num_clocks);
> +       if (ret)
> +               return dev_err_probe(dev, ret, "Failed to get clocks\n");
> +
> +       hdmi->irq = platform_get_irq(pdev, 0);
> +       if (!hdmi->irq)
> +               return hdmi->irq;
> +
> +       hdmi->regs = device_node_to_regmap(dev->of_node);
> +       if (IS_ERR(hdmi->regs))
> +               return PTR_ERR(hdmi->regs);
> +
> +       remote = of_graph_get_remote_node(np, 1, 0);
> +       if (!remote)
> +               return dev_err_probe(dev, -EINVAL, "Cannot find HDMI input port\n");
> +
> +       if (!of_device_is_compatible(remote, "hdmi-connector")) {
> +               hdmi->next_bridge = of_drm_find_bridge(remote);
> +               if (!hdmi->next_bridge) {
> +                       dev_err(dev, "Waiting for external bridge\n");
> +                       of_node_put(remote);
> +                       return -EPROBE_DEFER;
> +               }
> +       }
> +
> +       i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
> +       if (!i2c_np) {
> +               of_node_put(pdev->dev.of_node);
> +               return dev_err_probe(dev, -EINVAL, "No ddc-i2c-bus in connector\n");
> +       }
> +
> +       hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
> +       of_node_put(i2c_np);
> +       if (!hdmi->ddc_adpt) {
> +               dev_err(dev, "Failed to get ddc i2c adapter by node");
> +               return -EPROBE_DEFER;
> +       }
> +
> +       ret = mtk_hdmi_get_cec_dev(hdmi, dev, np);
> +       if (ret == -ENOTSUPP)
> +               dev_info(dev, "CEC support unavailable: node not found\n");
> +       else if (ret)
> +               return ret;
> +
> +       return 0;
> +}
> +
> +static void mtk_hdmi_unregister_audio_driver(void *data)
> +{
> +       platform_device_unregister(data);
> +}
> +
> +static int mtk_hdmi_register_audio_driver(struct device *dev)
> +{
> +       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +       struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> +       struct hdmi_codec_pdata codec_data = {
> +               .i2s = 1,
> +               .max_i2s_channels = 2,
> +               .data = hdmi,
> +               .ops = hdmi->conf->ver_conf->codec_ops
> +       };
> +       int ret;
> +
> +       aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +       aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +       aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> +       aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> +       aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> +       aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> +
> +       hdmi->audio_pdev = platform_device_register_data(dev,
> +                                                        HDMI_CODEC_DRV_NAME,
> +                                                        PLATFORM_DEVID_AUTO,
> +                                                        &codec_data,
> +                                                        sizeof(codec_data));
> +       if (IS_ERR(hdmi->audio_pdev))
> +               return PTR_ERR(hdmi->audio_pdev);
> +
> +       ret = devm_add_action_or_reset(dev, mtk_hdmi_unregister_audio_driver,
> +                                      hdmi->audio_pdev);
> +       if (ret) {
> +               platform_device_unregister(hdmi->audio_pdev);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
> +{
> +       const struct mtk_hdmi_ver_conf *ver_conf;
> +       struct device *dev = &pdev->dev;
> +       struct mtk_hdmi *hdmi;
> +       int ret;
> +
> +       hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
> +       if (!hdmi)
> +               return ERR_PTR(-ENOMEM);
> +
> +       hdmi->dev = dev;
> +       hdmi->conf = of_device_get_match_data(dev);
> +       ver_conf = hdmi->conf->ver_conf;
> +
> +       hdmi->clk = devm_kcalloc(dev, ver_conf->num_clocks, sizeof(*hdmi->clk), GFP_KERNEL);
> +       if (!hdmi->clk)
> +               return ERR_PTR(-ENOMEM);
> +
> +       hdmi->phy = devm_phy_get(dev, "hdmi");
> +       if (IS_ERR(hdmi->phy))
> +               return dev_err_cast_probe(dev, hdmi->phy, "Failed to get HDMI PHY\n");
> +
> +       ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, ver_conf->mtk_hdmi_clock_names,
> +                                     ver_conf->num_clocks);
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       platform_set_drvdata(pdev, hdmi);
> +
> +       ret = mtk_hdmi_register_audio_driver(dev);
> +       if (ret)
> +               return dev_err_ptr_probe(dev, ret, "Cannot register HDMI Audio driver\n");

You change the error message here. If this is necessary, separate this to a refinement patch.

Regards,
CK

> +
> +       hdmi->bridge.funcs = ver_conf->bridge_funcs;
> +       hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
> +       hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
> +       hdmi->bridge.of_node = pdev->dev.of_node;
> +
> +       ret = devm_drm_bridge_add(dev, &hdmi->bridge);
> +       if (ret)
> +               return dev_err_ptr_probe(dev, ret, "Failed to add bridge\n");
> +
> +       return hdmi;
> +}
> +
> +MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>");
> +MODULE_AUTHOR("Can Zeng <can.zeng at mediatek.com>");
> +MODULE_AUTHOR("Jie Qiu <jie.qiu at mediatek.com>");
> +MODULE_DESCRIPTION("MediaTek HDMI Common Library");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> new file mode 100644
> index 000000000000..15121e8548f3
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> @@ -0,0 +1,203 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Copyright (c) 2022 BayLibre, SAS
> + */
> +
> +#ifndef _MTK_HDMI_COMMON_H
> +#define _MTK_HDMI_COMMON_H
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_edid.h>
> +#include <drm/drm_print.h>
> +
> +#include <linux/clk.h>
> +#include <linux/device.h>
> +#include <linux/hdmi.h>
> +#include <linux/i2c.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/mutex.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +
> +#include <sound/hdmi-codec.h>
> +
> +enum hdmi_aud_input_type {
> +       HDMI_AUD_INPUT_I2S = 0,
> +       HDMI_AUD_INPUT_SPDIF,
> +};
> +
> +enum hdmi_aud_i2s_fmt {
> +       HDMI_I2S_MODE_RJT_24BIT = 0,
> +       HDMI_I2S_MODE_RJT_16BIT,
> +       HDMI_I2S_MODE_LJT_24BIT,
> +       HDMI_I2S_MODE_LJT_16BIT,
> +       HDMI_I2S_MODE_I2S_24BIT,
> +       HDMI_I2S_MODE_I2S_16BIT
> +};
> +
> +enum hdmi_aud_mclk {
> +       HDMI_AUD_MCLK_128FS,
> +       HDMI_AUD_MCLK_192FS,
> +       HDMI_AUD_MCLK_256FS,
> +       HDMI_AUD_MCLK_384FS,
> +       HDMI_AUD_MCLK_512FS,
> +       HDMI_AUD_MCLK_768FS,
> +       HDMI_AUD_MCLK_1152FS,
> +};
> +
> +enum hdmi_aud_channel_type {
> +       HDMI_AUD_CHAN_TYPE_1_0 = 0,
> +       HDMI_AUD_CHAN_TYPE_1_1,
> +       HDMI_AUD_CHAN_TYPE_2_0,
> +       HDMI_AUD_CHAN_TYPE_2_1,
> +       HDMI_AUD_CHAN_TYPE_3_0,
> +       HDMI_AUD_CHAN_TYPE_3_1,
> +       HDMI_AUD_CHAN_TYPE_4_0,
> +       HDMI_AUD_CHAN_TYPE_4_1,
> +       HDMI_AUD_CHAN_TYPE_5_0,
> +       HDMI_AUD_CHAN_TYPE_5_1,
> +       HDMI_AUD_CHAN_TYPE_6_0,
> +       HDMI_AUD_CHAN_TYPE_6_1,
> +       HDMI_AUD_CHAN_TYPE_7_0,
> +       HDMI_AUD_CHAN_TYPE_7_1,
> +       HDMI_AUD_CHAN_TYPE_3_0_LRS,
> +       HDMI_AUD_CHAN_TYPE_3_1_LRS,
> +       HDMI_AUD_CHAN_TYPE_4_0_CLRS,
> +       HDMI_AUD_CHAN_TYPE_4_1_CLRS,
> +       HDMI_AUD_CHAN_TYPE_6_1_CS,
> +       HDMI_AUD_CHAN_TYPE_6_1_CH,
> +       HDMI_AUD_CHAN_TYPE_6_1_OH,
> +       HDMI_AUD_CHAN_TYPE_6_1_CHR,
> +       HDMI_AUD_CHAN_TYPE_7_1_LH_RH,
> +       HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR,
> +       HDMI_AUD_CHAN_TYPE_7_1_LC_RC,
> +       HDMI_AUD_CHAN_TYPE_7_1_LW_RW,
> +       HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD,
> +       HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS,
> +       HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS,
> +       HDMI_AUD_CHAN_TYPE_7_1_CS_CH,
> +       HDMI_AUD_CHAN_TYPE_7_1_CS_OH,
> +       HDMI_AUD_CHAN_TYPE_7_1_CS_CHR,
> +       HDMI_AUD_CHAN_TYPE_7_1_CH_OH,
> +       HDMI_AUD_CHAN_TYPE_7_1_CH_CHR,
> +       HDMI_AUD_CHAN_TYPE_7_1_OH_CHR,
> +       HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR,
> +       HDMI_AUD_CHAN_TYPE_6_0_CS,
> +       HDMI_AUD_CHAN_TYPE_6_0_CH,
> +       HDMI_AUD_CHAN_TYPE_6_0_OH,
> +       HDMI_AUD_CHAN_TYPE_6_0_CHR,
> +       HDMI_AUD_CHAN_TYPE_7_0_LH_RH,
> +       HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR,
> +       HDMI_AUD_CHAN_TYPE_7_0_LC_RC,
> +       HDMI_AUD_CHAN_TYPE_7_0_LW_RW,
> +       HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD,
> +       HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS,
> +       HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS,
> +       HDMI_AUD_CHAN_TYPE_7_0_CS_CH,
> +       HDMI_AUD_CHAN_TYPE_7_0_CS_OH,
> +       HDMI_AUD_CHAN_TYPE_7_0_CS_CHR,
> +       HDMI_AUD_CHAN_TYPE_7_0_CH_OH,
> +       HDMI_AUD_CHAN_TYPE_7_0_CH_CHR,
> +       HDMI_AUD_CHAN_TYPE_7_0_OH_CHR,
> +       HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR,
> +       HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS,
> +       HDMI_AUD_CHAN_TYPE_UNKNOWN = 0xFF
> +};
> +
> +enum hdmi_aud_channel_swap_type {
> +       HDMI_AUD_SWAP_LR,
> +       HDMI_AUD_SWAP_LFE_CC,
> +       HDMI_AUD_SWAP_LSRS,
> +       HDMI_AUD_SWAP_RLS_RRS,
> +       HDMI_AUD_SWAP_LR_STATUS,
> +};
> +
> +enum hdmi_hpd_state {
> +       HDMI_PLUG_OUT = 0,
> +       HDMI_PLUG_IN_AND_SINK_POWER_ON,
> +       HDMI_PLUG_IN_ONLY,
> +};
> +
> +struct hdmi_audio_param {
> +       enum hdmi_audio_coding_type aud_codec;
> +       enum hdmi_audio_sample_size aud_sample_size;
> +       enum hdmi_aud_input_type aud_input_type;
> +       enum hdmi_aud_i2s_fmt aud_i2s_fmt;
> +       enum hdmi_aud_mclk aud_mclk;
> +       enum hdmi_aud_channel_type aud_input_chan_type;
> +       struct hdmi_codec_params codec_params;
> +};
> +
> +struct mtk_hdmi {
> +       struct drm_bridge bridge;
> +       struct device *dev;
> +       const struct mtk_hdmi_conf *conf;
> +       struct phy *phy;
> +       struct i2c_adapter *ddc_adpt;
> +       struct clk **clk;
> +       struct drm_display_mode mode;
> +       bool dvi_mode;
> +       struct regmap *sys_regmap;
> +       unsigned int sys_offset;
> +       struct regmap *regs;
> +
> +       bool powered;
> +       bool enabled;
> +       unsigned int irq;
> +       enum hdmi_hpd_state hpd;
> +
> +       /* Audio */
> +       struct platform_device *audio_pdev;
> +       struct hdmi_audio_param aud_param;
> +       bool audio_enable;
> +
> +       struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */
> +       struct mutex update_plugged_status_lock;
> +       struct device *cec_dev;
> +       struct device *codec_dev;
> +       hdmi_codec_plugged_cb plugged_cb;
> +       struct drm_bridge *next_bridge;
> +};
> +
> +struct mtk_hdmi_ver_conf {
> +       const struct drm_bridge_funcs *bridge_funcs;
> +       const struct hdmi_codec_ops *codec_ops;
> +       const char * const *mtk_hdmi_clock_names;
> +       int num_clocks;
> +       bool hdr_support;
> +};
> +
> +struct mtk_hdmi_conf {
> +       const struct mtk_hdmi_ver_conf *ver_conf;
> +       bool tz_disabled;
> +       bool cea_modes_only;
> +       unsigned long max_mode_clock;
> +};
> +
> +static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
> +{
> +       return container_of(b, struct mtk_hdmi, bridge);
> +}
> +
> +int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len);
> +void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn,
> +                                  struct device *codec_dev);
> +int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi, struct hdmi_codec_daifmt *daifmt,
> +                         struct hdmi_codec_params *params);
> +int mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock,
> +                     unsigned int *n, unsigned int *cts);
> +bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
> +                               const struct drm_display_mode *mode,
> +                               struct drm_display_mode *adjusted_mode);
> +void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
> +                             const struct drm_display_mode *mode,
> +                             const struct drm_display_mode *adjusted_mode);
> +struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev);
> +int mtk_drm_hdmi_probe(struct platform_device *pdev);
> +int mtk_drm_hdmi_remove(struct platform_device *pdev);
> +
> +#endif /* _MTK_HDMI_COMMON_H */
> --
> 2.47.0
> 


From shijie at os.amperecomputing.com  Sun Dec  8 23:20:20 2024
From: shijie at os.amperecomputing.com (Huang Shijie)
Date: Mon,  9 Dec 2024 15:20:20 +0800
Subject: [PATCH v3 2/2] arm64: remove CONFIG_RODATA_FULL_DEFAULT_ENABLED
In-Reply-To: <20241209072020.4743-1-shijie@os.amperecomputing.com>
References: <20241209072020.4743-1-shijie@os.amperecomputing.com>
Message-ID: <20241209072020.4743-3-shijie@os.amperecomputing.com>

After patch "arm64: refacotr the rodata=xxx",
the "rodata=on" becomes the default.

     ......................................
	if (!strcmp(arg, "on")) {
		rodata_enabled = rodata_full = true;
		return true;
	}
     ......................................

The rodata_full is always "true" via "rodata=on" and does not
depend on the config RODATA_FULL_DEFAULT_ENABLED anymore,
so it can be dropped.

Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
---
 arch/arm64/Kconfig       | 14 --------------
 arch/arm64/mm/pageattr.c |  2 +-
 2 files changed, 1 insertion(+), 15 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cbfd357f94a6..1c69982302ed 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1666,20 +1666,6 @@ config MITIGATE_SPECTRE_BRANCH_HISTORY
 	  When taking an exception from user-space, a sequence of branches
 	  or a firmware call overwrites the branch history.
 
-config RODATA_FULL_DEFAULT_ENABLED
-	bool "Apply r/o permissions of VM areas also to their linear aliases"
-	default y
-	help
-	  Apply read-only attributes of VM areas to the linear alias of
-	  the backing pages as well. This prevents code or read-only data
-	  from being modified (inadvertently or intentionally) via another
-	  mapping of the same memory page. This additional enhancement can
-	  be turned off at runtime by passing rodata=[off|on] (and turned on
-	  with rodata=full if this option is set to 'n')
-
-	  This requires the linear region to be mapped down to pages,
-	  which may adversely affect performance in some cases.
-
 config ARM64_SW_TTBR0_PAN
 	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
 	depends on !KCSAN
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 39fd1f7ff02a..6eef08d8451e 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -20,7 +20,7 @@ struct page_change_data {
 	pgprot_t clear_mask;
 };
 
-bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED);
+bool rodata_full __ro_after_init = true;
 
 bool can_set_direct_map(void)
 {
-- 
2.40.1



From shijie at os.amperecomputing.com  Sun Dec  8 23:20:18 2024
From: shijie at os.amperecomputing.com (Huang Shijie)
Date: Mon,  9 Dec 2024 15:20:18 +0800
Subject: [PATCH v3 0/2] arm64: refactor the rodata=xxx
Message-ID: <20241209072020.4743-1-shijie@os.amperecomputing.com>

>From Documentation/admin-guide/kernel-parameters.txt, we know that:
 rodata=	[KNL,EARLY]
	on	Mark read-only kernel memory as read-only (default).
	off	Leave read-only kernel memory writable for debugging.
	full	Mark read-only kernel memory and aliases as read-only
		[arm64]

So the "rodata=on" is the default.

But the current code does not follow the document, it makes "rodata=full"
as the default.

This patch set follows Anshuman Khandual's suggetions. 
It makes the "rodata=on" as the default, and removes the CONFIG_RODATA_FULL_DEFAULT_ENABLED.

v3:
  Follows Anshuman Khandual's suggetions:
  - Merge patch 1 and patch 3 into one patch.
  - Remove patch 4 
  - update comments and document.

v2:
  Follows Will's suggetions.
  Add a new file fine-tuning-tips.rst for the expert users.
   https://lists.infradead.org/pipermail/linux-arm-kernel/2024-November/981190.html

v1:
   https://lists.infradead.org/pipermail/linux-arm-kernel/2024-October/971415.html


Huang Shijie (2):
  arm64: refactor the rodata=xxx
  arm64: remove CONFIG_RODATA_FULL_DEFAULT_ENABLED

 .../admin-guide/kernel-parameters.txt         |  2 +-
 arch/arm64/Kconfig                            | 14 -----------
 arch/arm64/include/asm/setup.h                | 25 +++++++++++++++++--
 arch/arm64/mm/pageattr.c                      |  2 +-
 4 files changed, 25 insertions(+), 18 deletions(-)

-- 
2.40.1



From shijie at os.amperecomputing.com  Sun Dec  8 23:20:19 2024
From: shijie at os.amperecomputing.com (Huang Shijie)
Date: Mon,  9 Dec 2024 15:20:19 +0800
Subject: [PATCH v3 1/2] arm64: refactor the rodata=xxx
In-Reply-To: <20241209072020.4743-1-shijie@os.amperecomputing.com>
References: <20241209072020.4743-1-shijie@os.amperecomputing.com>
Message-ID: <20241209072020.4743-2-shijie@os.amperecomputing.com>

>From Documentation/admin-guide/kernel-parameters.txt:
	rodata=		[KNL,EARLY]
		on	Mark read-only kernel memory as read-only (default).

So "rodata=on" is the default.

But the current code does not follow the document, it makes "rodata=full"
as the default.

This patch refactors the "rodata=xxx" :
      1.) Make rodata=on behaviour be the original rodata=full.
          (Drop the original rodata=full.)
      2.) Introduce "rodata=noalias" which is the original "rodata=on"
      3.) Add more comment for arch_parse_debug_rodata(),
          update kernel-parameters.txt.

After this patch, the rodata=on will be the default.

Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
---
 .../admin-guide/kernel-parameters.txt         |  2 +-
 arch/arm64/include/asm/setup.h                | 25 +++++++++++++++++--
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index a22b7e621007..51bce7b9d805 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5901,7 +5901,7 @@
 	rodata=		[KNL,EARLY]
 		on	Mark read-only kernel memory as read-only (default).
 		off	Leave read-only kernel memory writable for debugging.
-		full	Mark read-only kernel memory and aliases as read-only
+		noalias	Use more block mappings,may have better performance.
 		        [arm64]
 
 	rockchip.usb_uart
diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
index ba269a7a3201..b3063326b79a 100644
--- a/arch/arm64/include/asm/setup.h
+++ b/arch/arm64/include/asm/setup.h
@@ -13,6 +13,27 @@
 extern phys_addr_t __fdt_pointer __initdata;
 extern u64 __cacheline_aligned boot_args[4];
 
+/*
+ * rodata=on (default):
+ *    Apply read-only attributes of VM areas to the linear alias of
+ *    the backing pages as well. This prevents code or read-only data
+ *    from being modified (inadvertently or intentionally) via another
+ *    mapping of the same memory page.
+ *
+ *    This requires the linear region to be mapped down to pages,
+ *    which may adversely affect performance in some cases.
+ *
+ * rodata=off:
+ *    It provides us more block mappings and contiguous hits
+ *    to map the linear region which minimize the TLB footprint.
+ *    Leave read-only kernel memory writable for debugging.
+ *
+ * rodata=noalias:
+ *    It provides us more block mappings and contiguous hits
+ *    to map the linear region which minimize the TLB footprint.
+ *    And the linear aliases of pages belonging to read-only mappings
+ *    in vmalloc region are also marked as read-only.
+ */
 static inline bool arch_parse_debug_rodata(char *arg)
 {
 	extern bool rodata_enabled;
@@ -21,7 +42,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
 	if (!arg)
 		return false;
 
-	if (!strcmp(arg, "full")) {
+	if (!strcmp(arg, "on")) {
 		rodata_enabled = rodata_full = true;
 		return true;
 	}
@@ -31,7 +52,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
 		return true;
 	}
 
-	if (!strcmp(arg, "on")) {
+	if (!strcmp(arg, "noalias")) {
 		rodata_enabled = true;
 		rodata_full = false;
 		return true;
-- 
2.40.1



From krzk at kernel.org  Sun Dec  8 23:22:59 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 08:22:59 +0100
Subject: [PATCH v6 0/4] Add minimal Samsung Galaxy S20 Series board,
 SM-G981B and SM-G980F support
In-Reply-To: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
References: <20241206184609.2437-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <77ceeb16-12cd-4c2d-8155-b6bd45feb524@kernel.org>

On 06/12/2024 19:46, Umer Uddin wrote:
> Hi folks,
> 
> This series adds initial support for the Samsung Galaxy S20 Series and also
> initial board support for the Samsung Galaxy S20 5G (SM-G981B)
> codenamed x1s and the Samsung Galaxy S20 (SM-G980F).
> 
> The S20 Series feature a lot of similarities in their configuration
> and internally Samsung named the common devicetrees in their
> downstream kernel 'hubble', please note hubble excludes the
> S20 FE series and Note20 series. To accommodate this, I've
> now named the device tree common's matching the codenames
> (x1s-common).
> The device trees have been tested with dtbs_check W=1
> and results in no warnings.
> 
Patchset was not built.

Best regards,
Krzysztof


From shawnguo2 at yeah.net  Sun Dec  8 23:28:00 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 15:28:00 +0800
Subject: [PATCH treewide 10/11] ARM: dts: nxp: imx: Switch to
 {hp,mic}-det-gpios
In-Reply-To: <7ff1bfb73a6d6fc71f3d751dbb7133b045853f64.1727438777.git.geert+renesas@glider.be>
References: <cover.1727438777.git.geert+renesas@glider.be>
 <7ff1bfb73a6d6fc71f3d751dbb7133b045853f64.1727438777.git.geert+renesas@glider.be>
Message-ID: <Z1acAA7gbxH7QfhT@dragon>

On Fri, Sep 27, 2024 at 02:42:25PM +0200, Geert Uytterhoeven wrote:
> Replace the deprecated "hp-det-gpio" and "mic-det-gpio" properties by
> "hp-det-gpios" resp. "mic-det-gpios" in Freescale Generic ASoC Sound
> Card device nodes.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Dec  8 23:29:18 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 15:29:18 +0800
Subject: [PATCH treewide 04/11] arm64: dts: freescale: imx: Switch to
 simple-audio-card,hp-det-gpios
In-Reply-To: <b38545c29d6cbf0b394ddb4747ce810c679f95d1.1727438777.git.geert+renesas@glider.be>
References: <cover.1727438777.git.geert+renesas@glider.be>
 <b38545c29d6cbf0b394ddb4747ce810c679f95d1.1727438777.git.geert+renesas@glider.be>
Message-ID: <Z1acTq/JV/JTHllY@dragon>

On Fri, Sep 27, 2024 at 02:42:19PM +0200, Geert Uytterhoeven wrote:
> Replace the deprecated "simple-audio-card,hp-det-gpio" property by
> "simple-audio-card,hp-det-gpios" in Simple Audio Card device nodes.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Dec  8 23:33:22 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 15:33:22 +0800
Subject: [PATCH 1/1] arm64: dts: imx8mq-zii-ultra: remove #address-cells
 of eeprom@a4
In-Reply-To: <20241018183117.740439-1-Frank.Li@nxp.com>
References: <20241018183117.740439-1-Frank.Li@nxp.com>
Message-ID: <Z1adQsiNfYMuVgp+@dragon>

On Fri, Oct 18, 2024 at 02:31:16PM -0400, Frank Li wrote:
> Remove #address-cells and #size-cells of eeprom at a4 because no children
> nodes under eeprom at a4.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied, thanks!



From krzk at kernel.org  Sun Dec  8 23:34:28 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 08:34:28 +0100
Subject: [PATCH] arm64: dts: exynosautov920: add DMA nodes
In-Reply-To: <20241204122335.1578-1-faraz.ata@samsung.com>
References: <CGME20241204122402epcas5p2412733eb46d495fadfa30e5af3c5ce83@epcas5p2.samsung.com>
 <20241204122335.1578-1-faraz.ata@samsung.com>
Message-ID: <0bac139b-c89c-43a7-978a-e5fe001d3dd2@kernel.org>

On 04/12/2024 13:23, Faraz Ata wrote:
> +
> +		spdma1: dma-controller at 10190000 {
> +			compatible = "arm,pl330", "arm,primecell";
> +			reg = <0x10190000 0x1000>;
> +			interrupts = <GIC_SPI 917 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
> +			clock-names = "apb_pclk";
> +			#dma-cells = <1>;
> +		};
> +
> +		pdma0: dma-controller at 101A0000 {

Please do not send downstream code directly, but fix it to match
upstream. Lowercase hex everywhere.

Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec  8 23:36:33 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 08:36:33 +0100
Subject: [PATCH 07/15] ARM: s3c64xx: extend deprecation schedule
In-Reply-To: <20241204102904.1863796-8-arnd@kernel.org>
References: <20241204102904.1863796-1-arnd@kernel.org>
 <20241204102904.1863796-8-arnd@kernel.org>
Message-ID: <00ba7daa-7c09-4f89-8d64-0dd5b871d906@kernel.org>

On 04/12/2024 11:28, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> Mark Brown is still using this machine for regular work, so it should
> not be removed as originally scheduled.
> 
> Give the platform another year, with the option to extend it further
> based on the state of ATAGS support next year.
> 
> I expect that we end up removing all of s3c64xx when either Mark has
> moved his test setup to other hardware, or when all other ATAGS based
> machines are getting removed.
> 
> Cc: Mark Brown <broonie at kernel.org>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---
>  arch/arm/mach-s3c/Kconfig.s3c64xx | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 

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

Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec  8 23:42:02 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 08:42:02 +0100
Subject: [PATCH v4 1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add
 properties for ti,lvds-vod-swing
In-Reply-To: <20241205134021.2592013-2-andrej.picej@norik.com>
References: <20241205134021.2592013-1-andrej.picej@norik.com>
 <20241205134021.2592013-2-andrej.picej@norik.com>
Message-ID: <lbbayope3b6nkzfflgb2fbgakxpx7uewcslw7mynn5gki6vlxp@4amjbijjcrnt>

On Thu, Dec 05, 2024 at 02:40:19PM +0100, Andrej Picej wrote:
> Add properties which can be used to specify LVDS differential output
> voltage. Since this also depends on near-end signal termination also
> include property which sets this. LVDS differential output voltage is
> specified with an array (min, max), which should match the one from
> connected device.
> 
> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> ---

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

Best regards,
Krzysztof



From tudor.ambarus at linaro.org  Sun Dec  8 23:43:07 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 9 Dec 2024 07:43:07 +0000
Subject: [PATCH] arm64: dts: exynosautov920: add DMA nodes
In-Reply-To: <20241204122335.1578-1-faraz.ata@samsung.com>
References: <CGME20241204122402epcas5p2412733eb46d495fadfa30e5af3c5ce83@epcas5p2.samsung.com>
 <20241204122335.1578-1-faraz.ata@samsung.com>
Message-ID: <07a4942c-023f-495e-a4b0-e451c949ad80@linaro.org>



On 12/4/24 12:23 PM, Faraz Ata wrote:
> ExynosAutov920 SoC has 7 DMA controllers. Two secure DMAC
> (SPDMA0 & SPDMA1) and five non-secure DMAC (PDMA0 to PDMA4).
> Adds the required dt node for the same.

typos: s/adds/add, s/node/nodes

Hi, Faraz!

Have you tested DMA on ExynosAutov920, did it work with the upstream
driver code?

I tried enabling it for GS101 and I had some questions that I couldn't
answer, and I moved forward in the meantime. Would you mind taking a
look at:

https://lore.kernel.org/linux-arm-kernel/e4089855-aca9-4993-bac6-e59370cf7954 at linaro.org/

Thanks a ton!
ta


From ck.hu at mediatek.com  Sun Dec  8 23:51:30 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 9 Dec 2024 07:51:30 +0000
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
Message-ID: <df3c37dc2ef4ca9ea920ab9b5b759a1e98c420b5.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
> +{
> +       const struct mtk_hdmi_ver_conf *ver_conf;
> +       struct device *dev = &pdev->dev;
> +       struct mtk_hdmi *hdmi;
> +       int ret;
> +
> +       hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
> +       if (!hdmi)
> +               return ERR_PTR(-ENOMEM);
> +
> +       hdmi->dev = dev;
> +       hdmi->conf = of_device_get_match_data(dev);
> +       ver_conf = hdmi->conf->ver_conf;
> +
> +       hdmi->clk = devm_kcalloc(dev, ver_conf->num_clocks, sizeof(*hdmi->clk), GFP_KERNEL);
> +       if (!hdmi->clk)
> +               return ERR_PTR(-ENOMEM);
> +
> +       hdmi->phy = devm_phy_get(dev, "hdmi");
> +       if (IS_ERR(hdmi->phy))
> +               return dev_err_cast_probe(dev, hdmi->phy, "Failed to get HDMI PHY\n");
> +
> +       ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, ver_conf->mtk_hdmi_clock_names,
> +                                     ver_conf->num_clocks);
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       platform_set_drvdata(pdev, hdmi);
> +
> +       ret = mtk_hdmi_register_audio_driver(dev);
> +       if (ret)
> +               return dev_err_ptr_probe(dev, ret, "Cannot register HDMI Audio driver\n");
> +
> +       hdmi->bridge.funcs = ver_conf->bridge_funcs;
> +       hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
> +       hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
> +       hdmi->bridge.of_node = pdev->dev.of_node;
> +
> +       ret = devm_drm_bridge_add(dev, &hdmi->bridge);

You change drm_bridge_add() to devm_drm_bridge_add(). If this is necessary, separate this to a refinement patch.

Regards,
CK

> +       if (ret)
> +               return dev_err_ptr_probe(dev, ret, "Failed to add bridge\n");
> +
> +       return hdmi;
> +}
> +


From krzk at kernel.org  Sun Dec  8 23:52:39 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 08:52:39 +0100
Subject: [PATCH v3 1/3] dt-bindings: mailbox: add bindings for
 samsung,exynos
In-Reply-To: <20241205174137.190545-2-tudor.ambarus@linaro.org>
References: <20241205174137.190545-1-tudor.ambarus@linaro.org>
 <20241205174137.190545-2-tudor.ambarus@linaro.org>
Message-ID: <2lkowhldq5i4otniijfw7cb3jm6ttatwji3npw5w7c5fyevnn5@ynojupmdyqy4>

On Thu, Dec 05, 2024 at 05:41:35PM +0000, Tudor Ambarus wrote:
> Add bindings for the Samsung Exynos Mailbox Controller.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  .../bindings/mailbox/samsung,exynos.yaml      | 70 +++++++++++++++++++

Filename based on compatible, so:
google,gs101-acpm-mbox

but then entire binding seems for different device, so you most likely
miss here actual Exynos devices.

>  1 file changed, 70 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mailbox/samsung,exynos.yaml

Best regards,
Krzysztof



From shawnguo2 at yeah.net  Sun Dec  8 23:53:42 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 15:53:42 +0800
Subject: [PATCH 2/2] arm64: dts: imx8-ss-audio: add fallback compatible
 string fsl,imx6ull-esai for esai
In-Reply-To: <20241028-esai_fix-v1-2-3c1432a5613c@nxp.com>
References: <20241028-esai_fix-v1-0-3c1432a5613c@nxp.com>
 <20241028-esai_fix-v1-2-3c1432a5613c@nxp.com>
Message-ID: <Z1aiBrlz5qjw7LVY@dragon>

On Mon, Oct 28, 2024 at 03:49:32PM -0400, Frank Li wrote:
> The ESAI of i.MX8QM is the same as i.MX6ULL. So add fsl,imx6ull-esai for
> esai.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied for 6.13, thanks!



From krzk at kernel.org  Sun Dec  8 23:55:17 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 08:55:17 +0100
Subject: [PATCH v3 2/3] mailbox: add samsung exynos driver
In-Reply-To: <20241205174137.190545-3-tudor.ambarus@linaro.org>
References: <20241205174137.190545-1-tudor.ambarus@linaro.org>
 <20241205174137.190545-3-tudor.ambarus@linaro.org>
Message-ID: <c6y4nofsjpjsl7ycsxsfqoizu7qsyf5yzbeao6utu5u5avlwzl@jbl3oqhy7ehb>

On Thu, Dec 05, 2024 at 05:41:36PM +0000, Tudor Ambarus wrote:
> The samsung exynos mailbox controller has 16 flag bits for hardware


Here, subject and other text/descriptions:
s/samsung/Samsung/
s/exynos/Exynos/


> interrupt generation and a shared register for passing mailbox messages.
> When the controller is used by the ACPM protocol the shared register is
> ignored and the mailbox controller acts as a doorbell. The controller
> just raises the interrupt to APM after the ACPM protocol has written
> the message to SRAM.

...

> +static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
> +{
> +	struct exynos_mbox *exynos_mbox = dev_get_drvdata(chan->mbox->dev);
> +	int index;
> +
> +	index = exynos_mbox_chan_index(chan);
> +	if (index < 0)
> +		return index;
> +
> +	writel_relaxed(BIT(index), exynos_mbox->regs + EXYNOS_MBOX_INTGR1);

writel()

> +
> +	return 0;
> +}
> +
> +static const struct mbox_chan_ops exynos_mbox_chan_ops = {
> +	.send_data = exynos_mbox_send_data,
> +};
> +
> +static const struct of_device_id exynos_mbox_match[] = {
> +	{ .compatible = "google,gs101-acpm-mbox" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, exynos_mbox_match);
> +
> +static int exynos_mbox_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct exynos_mbox *exynos_mbox;
> +	struct mbox_controller *mbox;
> +	struct mbox_chan *chans;
> +	int i;
> +
> +	exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL);
> +	if (!exynos_mbox)
> +		return -ENOMEM;
> +
> +	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
> +	if (!mbox)
> +		return -ENOMEM;
> +
> +	chans = devm_kcalloc(dev, EXYNOS_MBOX_CHAN_COUNT, sizeof(*chans),
> +			     GFP_KERNEL);
> +	if (!chans)
> +		return -ENOMEM;
> +
> +	exynos_mbox->regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(exynos_mbox->regs))
> +		return PTR_ERR(exynos_mbox->regs);
> +
> +	exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk");
> +	if (IS_ERR(exynos_mbox->pclk))
> +		return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk),
> +				     "Failed to enable clock.\n");
> +
> +	mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT;
> +	mbox->chans = chans;
> +	mbox->dev = dev;
> +	mbox->ops = &exynos_mbox_chan_ops;
> +
> +	for (i = 0; i < EXYNOS_MBOX_CHAN_COUNT; i++)
> +		chans[i].mbox = mbox;
> +
> +	exynos_mbox->dev = dev;
> +	exynos_mbox->mbox = mbox;
> +
> +	platform_set_drvdata(pdev, exynos_mbox);
> +
> +	/* Mask out all interrupts. We support just polling channels for now. */
> +	writel_relaxed(EXYNOS_MBOX_INTMR0_MASK,

writel()

> +		       exynos_mbox->regs + EXYNOS_MBOX_INTMR0);
> +
> +	return devm_mbox_controller_register(dev, mbox);
> +}
> +
> +static struct platform_driver exynos_mbox_driver = {
> +	.probe	= exynos_mbox_probe,
> +	.driver	= {
> +		.name = "exynos-acpm-mbox",
> +		.of_match_table	= of_match_ptr(exynos_mbox_match),

Drop of_match_ptr() - unused symbol warnings.

Best regards,
Krzysztof



From andrej.picej at norik.com  Sun Dec  8 23:56:29 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 9 Dec 2024 08:56:29 +0100
Subject: [PATCH v4 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <nbumcptoi5hwehjbrynf6dh2wrz7a4ugqblrjxyswvj7udkf3u@6qikclizqfjr>
References: <20241205134021.2592013-1-andrej.picej@norik.com>
 <20241205134021.2592013-3-andrej.picej@norik.com>
 <nbumcptoi5hwehjbrynf6dh2wrz7a4ugqblrjxyswvj7udkf3u@6qikclizqfjr>
Message-ID: <e420579f-25b2-41ca-9627-130d67c51541@norik.com>

Hi Dmitry,

On 5. 12. 24 23:48, Dmitry Baryshkov wrote:
> On Thu, Dec 05, 2024 at 02:40:20PM +0100, Andrej Picej wrote:
>> Add a optional properties to change LVDS output voltage. This should not
>> be static as this depends mainly on the connected display voltage
>> requirement. We have three properties:
>> - "ti,lvds-termination-ohms", which sets near end termination,
>> - "ti,lvds-vod-swing-data-microvolt" and
>> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
>> output voltage for data and clock lanes. They are defined as an array
>> with min and max values. The appropriate bitfield will be set if
>> selected constraints can be met.
>>
>> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
>> end termination will be used. Selecting only one:
>> "ti,lvds-vod-swing-data-microvolt" or
>> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
>> constraint for only data/clock lanes will be met. Setting both is
>> recommended.
>>
>> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
>> ---
>> Changes in v4:
>> - fix typo in commit message bitfiled -> bitfield
>> - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
>> of separate variables for channel A/B
>> - add more checks on return value of "of_property_read_u32_array"
>> Changes in v3:
>> - use microvolts for default array values 1000 mV -> 1000000 uV.
>> Changes in v2:
>> - use datasheet tables to get the proper configuration
>> - since major change was done change the authorship to myself
>> ---
>>   drivers/gpu/drm/bridge/ti-sn65dsi83.c | 147 +++++++++++++++++++++++++-
>>   1 file changed, 144 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>> index 57a7ed13f996..f724d2a6777b 100644
>> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>> @@ -132,6 +132,16 @@
>>   #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>>   #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>>   
>> +enum sn65dsi83_channel {
>> +	CHANNEL_A,
>> +	CHANNEL_B
>> +};
>> +
>> +enum sn65dsi83_lvds_term {
>> +	OHM_100,
>> +	OHM_200
>> +};
>> +
>>   enum sn65dsi83_model {
>>   	MODEL_SN65DSI83,
>>   	MODEL_SN65DSI84,
>> @@ -147,6 +157,8 @@ struct sn65dsi83 {
>>   	struct regulator		*vcc;
>>   	bool				lvds_dual_link;
>>   	bool				lvds_dual_link_even_odd_swap;
>> +	int				lvds_vod_swing_conf[2];
>> +	int				lvds_term_conf[2];
>>   };
>>   
>>   static const struct regmap_range sn65dsi83_readable_ranges[] = {
>> @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>>   	.max_register = REG_IRQ_STAT,
>>   };
>>   
>> +static const int lvds_vod_swing_data_table[2][4][2] = {
>> +	{	/* 100 Ohm */
>> +		{ 180000, 313000 },
>> +		{ 215000, 372000 },
>> +		{ 250000, 430000 },
>> +		{ 290000, 488000 },
>> +	},
>> +	{	/* 200 Ohm */
>> +		{ 150000, 261000 },
>> +		{ 200000, 346000 },
>> +		{ 250000, 428000 },
>> +		{ 300000, 511000 },
>> +	},
>> +};
>> +
>> +static const int lvds_vod_swing_clock_table[2][4][2] = {
>> +	{	/* 100 Ohm */
>> +		{ 140000, 244000 },
>> +		{ 168000, 290000 },
>> +		{ 195000, 335000 },
>> +		{ 226000, 381000 },
>> +	},
>> +	{	/* 200 Ohm */
>> +		{ 117000, 204000 },
>> +		{ 156000, 270000 },
>> +		{ 195000, 334000 },
>> +		{ 234000, 399000 },
>> +	},
>> +};
>> +
>>   static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>>   {
>>   	return container_of(bridge, struct sn65dsi83, bridge);
>> @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>>   		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>>   
>>   	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
>> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
>> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
>> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
>> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
>>   	regmap_write(ctx->regmap, REG_LVDS_LANE,
>>   		     (ctx->lvds_dual_link_even_odd_swap ?
>>   		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
>> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
>> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
>> +		     (ctx->lvds_term_conf[CHANNEL_A] ?
>> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
>> +		     (ctx->lvds_term_conf[CHANNEL_B] ?
>> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>>   	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>>   
>>   	le16val = cpu_to_le16(mode->hdisplay);
>> @@ -576,10 +622,101 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>>   	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>>   };
>>   
>> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
>> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i <= 3; i++) {
>> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
>> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
>> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
>> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
>> +			return i;
>> +	}
>> +
>> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
>> +	return -EINVAL;
>> +}
>> +
>> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
>> +{
>> +	struct device *dev = ctx->dev;
>> +	struct device_node *endpoint;
>> +	/* Set so the property can be freely selected if not defined */
>> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
>> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
>> +	u32 lvds_term = 200;
>> +	u8 lvds_term_conf;
>> +	int endpoint_reg;
>> +	int lvds_vod_swing_conf;
>> +	int ret = 0;
>> +	int ret_data;
>> +	int ret_clock;
>> +
>> +	if (channel == CHANNEL_A)
>> +		endpoint_reg = 2;
>> +	else
>> +		endpoint_reg = 3;
>> +
>> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
>> +	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
>> +
>> +	if (lvds_term == 200)
>> +		lvds_term_conf = OHM_200;
>> +	else
>> +		lvds_term_conf = OHM_100;
>> +
>> +	ctx->lvds_term_conf[channel] = lvds_term_conf;
>> +
>> +	ret_data = of_property_read_u32_array(endpoint,
>> +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
>> +			ARRAY_SIZE(lvds_vod_swing_data));
>> +	if (ret_data != 0 && ret_data != -EINVAL) {
>> +		ret = ret_data;
>> +		goto exit;
>> +	}
>> +
>> +	ret_clock = of_property_read_u32_array(endpoint,
>> +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
>> +			ARRAY_SIZE(lvds_vod_swing_clk));
>> +	if (ret_clock != 0 && ret_clock != -EINVAL) {
>> +		ret = ret_clock;
>> +		goto exit;
>> +	}
>> +
>> +	/* If any of the two properties is defined. */
>> +	if (!ret_data || !ret_clock) {
>> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
>> +			lvds_vod_swing_data, lvds_vod_swing_clk,
>> +			lvds_term_conf);
>> +		if (lvds_vod_swing_conf < 0) {
>> +			ret = lvds_vod_swing_conf;
>> +			goto exit;
>> +		}
>> +
>> +		ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
>> +	}
>> +	ret = 0;
>> +exit:
>> +	of_node_put(endpoint);
>> +	return ret;
>> +}
>> +
>>   static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>>   {
>>   	struct drm_bridge *panel_bridge;
>>   	struct device *dev = ctx->dev;
>> +	int ret;
>> +
>> +	ctx->lvds_vod_swing_conf[CHANNEL_A] = 0x1;
>> +	ctx->lvds_vod_swing_conf[CHANNEL_B] = 0x1;
>> +	ctx->lvds_term_conf[CHANNEL_A] = 0x1;
>> +	ctx->lvds_term_conf[CHANNEL_B] = 0x1;
> 
> These match the defaults in sn65dsi83_parse_lvds_endpoint(). Do we
> really need those?

Yes, I think we do. This ensures that defaults are used even when 
property is not defined/LVDS channel is not used. So also LVDS channel B 
defaults are set even for sn65dsi83 (single LVDS output). Keeping the 
same reg values as before these changes.

Best regards,
Andrej


> 
>> +
>> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
>> +	if (ret < 0)
>> +		return ret;
>>   
>>   	ctx->lvds_dual_link = false;
>>   	ctx->lvds_dual_link_even_odd_swap = false;
>> @@ -587,6 +724,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>>   		struct device_node *port2, *port3;
>>   		int dual_link;
>>   
>> +		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
>> +		if (ret < 0)
>> +			return ret;
>> +
>>   		port2 = of_graph_get_port_by_id(dev->of_node, 2);
>>   		port3 = of_graph_get_port_by_id(dev->of_node, 3);
>>   		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
>> -- 
>> 2.34.1
>>
> 


From umer.uddin at mentallysanemainliners.org  Mon Dec  9 00:00:56 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  9 Dec 2024 08:00:56 +0000
Subject: [PATCH v7 1/4] dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
In-Reply-To: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
References: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241209080059.11891-2-umer.uddin@mentallysanemainliners.org>

Add devicetree bindings for Samsung Galaxy S20 5G
and Samsung Galaxy S20 board.

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml         | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 168e77375..fab29f95d 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -241,6 +241,8 @@ properties:
           - enum:
               - samsung,c1s                     # Samsung Galaxy Note20 5G (SM-N981B)
               - samsung,r8s                     # Samsung Galaxy S20 FE (SM-G780F)
+              - samsung,x1s                     # Samsung Galaxy S20 5G (SM-G981B)
+              - samsung,x1slte                  # Samsung Galaxy S20 (SM-G980F)
           - const: samsung,exynos990
 
       - description: Exynos Auto v9 based boards
-- 
2.43.0



From umer.uddin at mentallysanemainliners.org  Mon Dec  9 00:00:57 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  9 Dec 2024 08:00:57 +0000
Subject: [PATCH v7 2/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series boards (x1s-common)
In-Reply-To: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
References: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241209080059.11891-3-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 Series (x1s-common) phones.
They were launched in 2020, and are based on the Exynos 990 SoC.
The devices have multiple RAM configurations,
starting from 8GB going all the way up to 16GB for the S20 Ultra devices.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM (Any more will be mapped in device trees)
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 .../boot/dts/exynos/exynos990-x1s-common.dtsi | 98 +++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi

diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
new file mode 100644
index 000000000..55fa8e9e0
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 Series device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		framebuffer0: framebuffer at f1000000 {
+			compatible = "simple-framebuffer";
+			reg = <0 0xf1000000 0 (1440 * 3200 * 4)>;
+			width = <1440>;
+			height = <3200>;
+			stride = <(1440 * 4)>;
+			format = "a8r8g8b8";
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		cont_splash_mem: framebuffer at f1000000 {
+			reg = <0 0xf1000000 0 0x1194000>;
+			no-map;
+		};
+
+		abox_reserved: audio at f7fb0000 {
+			reg = <0 0xf7fb0000 0 0x2a50000>;
+			no-map;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&key_power &key_voldown &key_volup>;
+		pinctrl-names = "default";
+
+		power-key {
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpa2 4 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+
+		voldown-key {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			gpios = <&gpa0 4 GPIO_ACTIVE_LOW>;
+		};
+
+		volup-key {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&oscclk {
+	clock-frequency = <26000000>;
+};
+
+&pinctrl_alive {
+	key_power: key-power-pins {
+		samsung,pins = "gpa2-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_voldown: key-voldown-pins {
+		samsung,pins = "gpa0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_volup: key-volup-pins {
+		samsung,pins = "gpa0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
-- 
2.43.0



From umer.uddin at mentallysanemainliners.org  Mon Dec  9 00:00:59 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  9 Dec 2024 08:00:59 +0000
Subject: [PATCH v7 4/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 (x1slte)
In-Reply-To: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
References: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241209080059.11891-5-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 (x1slte/SM-G980F)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 8GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 8GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile           |  1 +
 .../boot/dts/exynos/exynos990-x1slte.dts      | 28 +++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index fe47aafcd..ee73e1a2d 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -11,5 +11,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos990-c1s.dtb		\
 	exynos990-r8s.dtb               \
 	exynos990-x1s.dtb		\
+	exynos990-x1slte.dtb		\
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts b/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts
new file mode 100644
index 000000000..d3720996b
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1slte.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 (x1slte/SM-G980F) device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990-x1s-common.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	model = "Samsung Galaxy S20";
+	compatible = "samsung,x1slte", "samsung,exynos990";
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x3ab00000>,
+		      /* Memory hole */
+		      <0x0 0xc1200000 0x0 0x1ee00000>,
+		      /* Memory hole */
+		      <0x0 0xe1900000 0x0 0x1e700000>,
+		      /* Memory hole */
+		      <0x8 0x80000000 0x1 0x7ec00000>;
+	};
+};
-- 
2.43.0



From umer.uddin at mentallysanemainliners.org  Mon Dec  9 00:00:55 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  9 Dec 2024 08:00:55 +0000
Subject: [PATCH v7 0/4] Add minimal Samsung Galaxy S20 Series board, SM-G981B and SM-G980F support
Message-ID: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>

Hi folks,

This series adds initial support for the Samsung Galaxy S20 Series and also
initial board support for the Samsung Galaxy S20 5G (SM-G981B)
codenamed x1s and the Samsung Galaxy S20 (SM-G980F).

The S20 Series feature a lot of similarities in their configuration
and internally Samsung named the common devicetrees in their
downstream kernel 'hubble', please note hubble excludes the
S20 FE series and Note20 series. To accommodate this, I've
now named the device tree common's matching the codenames
(x1s-common).
The device trees have been tested with dtbs_check W=1
and results in no warnings.

This initial bringup consists of:
 * pinctrl
 * gpio-keys
 * simple-framebuffer

This is enough to reach a shell in an initramfs. More platform support
will be added in the future.

Just like SM-N981B, the preferred way to boot the upstream kernel is
by using a shim bootloader, called uniLoader [1], which works around
some issues with the stock, non-replacable Samsung S-LK bootloader.
For example, the stock bootloader leaves the decon trigger control
unset, which causes the framebuffer not to refresh.

Device functionality depends on the patch series from Igor Belwon:
"Add minimal Exynos990 SoC and SM-N981B support"

[1] https://github.com/ivoszbg/uniLoader

Changes in v7:
 - Fix old reference to hubble-common
   in x1slte.

Changes in v6:
 - Fix indentations in dts makefile

Changes in v5:
 - Fix dts makefile order

Changes in v4:
 - Rebase from krzk's kernel tree to accommodate
   for the merge of r8s
 - Rename exynos990-hubble-common.dtsi
   to exynos990-x1s-common.dtsi

Changes in v3:
 - Fix oversight in yaml
 - Decommonise memory map

Changes in v2:
 - Add Samsung Galaxy S20 into device tree bindings
 - Add support for Samsung Galaxy S20 as well as the 5G variant now
 - Fix typo in Samsung Galaxy S20 5G commit message

Kind regards,
Umer

Umer Uddin (4):
  dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B
    and SM-G980F board
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series
    boards (x1s-common)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G
    (x1s)
  arm64: dts: exynos: Add initial support for Samsung Galaxy S20
    (x1slte)

 .../bindings/arm/samsung/samsung-boards.yaml  |  2 +
 arch/arm64/boot/dts/exynos/Makefile           |  2 +
 .../boot/dts/exynos/exynos990-x1s-common.dtsi | 98 +++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts  | 28 ++++++
 .../boot/dts/exynos/exynos990-x1slte.dts      | 28 ++++++
 5 files changed, 158 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s-common.dtsi
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1slte.dts

-- 
2.43.0



From umer.uddin at mentallysanemainliners.org  Mon Dec  9 00:00:58 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Mon,  9 Dec 2024 08:00:58 +0000
Subject: [PATCH v7 3/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
In-Reply-To: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
References: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241209080059.11891-4-umer.uddin@mentallysanemainliners.org>

Add initial support for the Samsung Galaxy S20 5G (x1s/SM-G981B)
phone. It was launched in 2020, and it's based on the Exynos 990 SoC. It
has only one configuration with 12GB of RAM and 128GB of UFS 3.0 storage.

This device tree adds support for the following:

- SimpleFB
- 12GB RAM
- Buttons

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/Makefile          |  1 +
 arch/arm64/boot/dts/exynos/exynos990-x1s.dts | 28 ++++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos990-x1s.dts

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index 948a2c6cb..fe47aafcd 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -10,5 +10,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos8895-dreamlte.dtb		\
 	exynos990-c1s.dtb		\
 	exynos990-r8s.dtb               \
+	exynos990-x1s.dtb		\
 	exynosautov9-sadk.dtb		\
 	exynosautov920-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos990-x1s.dts b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
new file mode 100644
index 000000000..1ae881015
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos990-x1s.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S20 5G (x1s/SM-G981B) device tree source
+ *
+ * Copyright (c) 2024, Umer Uddin <umer.uddin at mentallysanemainliners.org>
+ */
+
+/dts-v1/;
+#include "exynos990-x1s-common.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	model = "Samsung Galaxy S20 5G";
+	compatible = "samsung,x1s", "samsung,exynos990";
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x3ab00000>,
+		      /* Memory hole */
+		      <0x0 0xc1200000 0x0 0x1ee00000>,
+		      /* Memory hole */
+		      <0x0 0xe1900000 0x0 0x1e700000>,
+		      /* Memory hole */
+		      <0x8 0x80000000 0x2 0x7e800000>;
+	};
+};
-- 
2.43.0



From krzk at kernel.org  Mon Dec  9 00:03:45 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 09:03:45 +0100
Subject: [PATCH v3 1/3] dt-bindings: firmware: add
 samsung,exynos-acpm-ipc bindings
In-Reply-To: <20241205175345.201595-2-tudor.ambarus@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-2-tudor.ambarus@linaro.org>
Message-ID: <k2pnpu3ef2rgy6wre2qrearwmetzb4v4meiyqpy7oyg45hohlp@kmnzulhbmdk6>

On Thu, Dec 05, 2024 at 05:53:43PM +0000, Tudor Ambarus wrote:
> Add bindings for the samsung exynos ACPM mailbox protocol.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  .../firmware/samsung,exynos-acpm-ipc.yaml     | 64 +++++++++++++++++++
>  1 file changed, 64 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml b/Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml
> new file mode 100644
> index 000000000000..bfc9b4af9ea1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/firmware/samsung,exynos-acpm-ipc.yaml


Filename based on comaptible, so google,gs101-acpm-ipc.yaml

> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2024 Linaro Ltd.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/firmware/samsung,exynos-acpm-ipc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung exynos ACPM mailbox protocol

s/exynos/Exynos/

> +
> +maintainers:
> +  - Tudor Ambarus <tudor.ambarus at linaro.org>
> +
> +description: |
> +  ACPM (Alive Clock and Power Manager) is a firmware that operates on the
> +  APM (Active Power Management) module that handles overall power management
> +  activities. ACPM and masters regard each other as independent hardware
> +  component and communicate with each other using mailbox messages and
> +  shared memory.
> +
> +  This binding is intended to define the interface the firmware implementing
> +  ACPM provides for OSPM in the device tree.
> +
> +properties:
> +  $nodename:
> +    const: acpm_ipc

Drop, no schemas have anything like this.

> +
> +  compatible:
> +    const: google,gs101-acpm-ipc
> +
> +  mboxes:
> +    description:
> +      List of phandle and mailbox channel specifiers.

Drop description.

> +    maxItems: 1
> +
> +  shmem:
> +    description:
> +      List of phandle pointing to the shared memory (SHM) area. The memory
> +      contains channels configuration data and the TX/RX ring buffers that
> +      are used for passing messages to/from the ACPM firmware.
> +    maxItems: 1
> +
> +  initdata-base:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Base address of the configuration data in the shared memory.

If you really need this, then it should be rather encoded as part of
shemm phandle (phandle-array with describing items, just like syscon
phandles are done).

But OTOH, I don't see why this is needed at all so far - compatible
defines it.

> +
> +additionalProperties: false

This should be placed after required block.

> +
> +required:
> +  - compatible
> +  - mboxes
> +  - shmem
> +  - initdata-base
> +
> +examples:
> +  - |
> +    firmware {

Drop

> +        acpm_ipc: acpm_ipc {

Drop unused label.

Node name: power-management (based on your binding description)
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 = "google,gs101-acpm-ipc";

Best regards,
Krzysztof



From tabba at google.com  Mon Dec  9 00:03:14 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 9 Dec 2024 08:03:14 +0000
Subject: [PATCH v4 01/14] KVM: arm64: Consolidate allowed and restricted
 VM feature checks
In-Reply-To: <Z1MihH-aLq6lTccm@google.com>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-2-tabba@google.com>
 <Z1MihH-aLq6lTccm@google.com>
Message-ID: <CA+EHjTyqLnXmkBp9yKGES8XXgChb6LNHS27uK+5iEWpSOU=iYg@mail.gmail.com>

Hi Quentin,

On Fri, 6 Dec 2024 at 16:12, Quentin Perret <qperret at google.com> wrote:
>
> On Monday 02 Dec 2024 at 15:47:28 (+0000), Fuad Tabba wrote:
> > The definitions for features allowed and allowed with
> > restrictions for protected guests, which are based on feature
> > registers, were defined and checked for separately, even though
> > they are handled in the same way. This could result in missing
> > checks for certain features, e.g., pointer authentication,
> > causing traps for allowed features.
> >
> > Consolidate the definitions into one. Use that new definition to
> > construct the guest view of the feature registers for
> > consistency.
> >
> > Fixes: 6c30bfb18d0b ("KVM: arm64: Add handlers for protected VM System Registers")
> > Reported-by: Mostafa Saleh <smostafa at google.com>
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> >
> > ---
> >
> > Note: This patch ends up being a no-op, since none of the changes
> > in it survive the series. It's included because it makes the rest
> > of the series flow more smoothly.
>
> Is the Fixes: tag above really needed then? It 'risks' being flagged as
> a -stable candidate, but should it be?

Makes sense. I'll remove the tag.

Thanks,
/fuad


From tabba at google.com  Mon Dec  9 00:06:26 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 9 Dec 2024 08:06:26 +0000
Subject: [PATCH v4 02/14] KVM: arm64: Group setting traps for protected
 VMs by control register
In-Reply-To: <Z1Mp4zmZRL_8QEmb@google.com>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-3-tabba@google.com>
 <Z1Mp4zmZRL_8QEmb@google.com>
Message-ID: <CA+EHjTwzDDPTyqs-VgGvPK+gk-+fDsD8WdQN1cJjzNcCYWBJFw@mail.gmail.com>

Hi Quentin,

On Fri, 6 Dec 2024 at 16:44, Quentin Perret <qperret at google.com> wrote:
>
> On Monday 02 Dec 2024 at 15:47:29 (+0000), Fuad Tabba wrote:
> > +static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
> >  {
> > -     const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
> > -     u64 mdcr_set = 0;
> > -     u64 mdcr_clear = 0;
> > -     u64 cptr_set = 0;
> > +     const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
> > +     const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
> > +     const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
> > +     u64 val = vcpu->arch.cptr_el2;
> >
> > -     /* Trap/constrain PMU */
> > -     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), feature_ids)) {
> > -             mdcr_set |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
> > -             mdcr_clear |= MDCR_EL2_HPME | MDCR_EL2_MTPME |
> > -                           MDCR_EL2_HPMN_MASK;
> > +     if (!has_hvhe()) {
> > +             val |= CPTR_NVHE_EL2_RES1;
> > +             val &= ~(CPTR_NVHE_EL2_RES0);
>
> It's a bit odd to do that at the beginning of the function no? Perhaps
> do it last to be sure to overwrite all the changes below?
>
> Also, not sure we need the RES1 part here, kvm_get_reset_cptr_el2()
> should have set those for us.

I agree on both, and by the end of this series they end up being as
you suggest. The purpose of this particular patch is just the grouping
of the traps, while keeping everything else the way it is.

Cheers,
/fuad

>
> >       }
> >
> > -     /* Trap Debug */
> > -     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DebugVer), feature_ids))
> > -             mdcr_set |= MDCR_EL2_TDRA | MDCR_EL2_TDA | MDCR_EL2_TDE;
> > -
> > -     /* Trap OS Double Lock */
> > -     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DoubleLock), feature_ids))
> > -             mdcr_set |= MDCR_EL2_TDOSA;
> > +     /* Trap AMU */
> > +     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
> > +             val |= CPTR_EL2_TAM;
> >
> > -     /* Trap SPE */
> > -     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMSVer), feature_ids)) {
> > -             mdcr_set |= MDCR_EL2_TPMS;
> > -             mdcr_clear |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT;
> > +     /* Trap SVE */
> > +     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), id_aa64pfr0)) {
> > +             if (has_hvhe())
> > +                     val &= ~(CPACR_ELx_ZEN);
> > +             else
> > +                     val |= CPTR_EL2_TZ;
> >       }
> >
> > -     /* Trap Trace Filter */
> > -     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), feature_ids))
> > -             mdcr_set |= MDCR_EL2_TTRF;
> > +     /* No SME support in KVM. */
> > +     BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME), id_aa64pfr1));
> > +     if (has_hvhe())
> > +             val &= ~(CPACR_ELx_SMEN);
> > +     else
> > +             val |= CPTR_EL2_TSM;
> >
> >       /* Trap Trace */
> > -     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), feature_ids)) {
> > +     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), id_aa64dfr0)) {
> >               if (has_hvhe())
> > -                     cptr_set |= CPACR_EL1_TTA;
> > +                     val |= CPACR_EL1_TTA;
> >               else
> > -                     cptr_set |= CPTR_EL2_TTA;
> > +                     val |= CPTR_EL2_TTA;
> >       }
> >
> > -     /* Trap External Trace */
> > -     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), feature_ids))
> > -             mdcr_clear |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
> > -
> > -     vcpu->arch.mdcr_el2 |= mdcr_set;
> > -     vcpu->arch.mdcr_el2 &= ~mdcr_clear;
> > -     vcpu->arch.cptr_el2 |= cptr_set;
> > -}
> > -
> > -/*
> > - * Set trap register values based on features in ID_AA64MMFR0.
> > - */
> > -static void pvm_init_traps_aa64mmfr0(struct kvm_vcpu *vcpu)
> > -{
> > -     const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR0_EL1);
> > -     u64 mdcr_set = 0;
> > -
> > -     /* Trap Debug Communications Channel registers */
> > -     if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_FGT), feature_ids))
> > -             mdcr_set |= MDCR_EL2_TDCC;
> > -
> > -     vcpu->arch.mdcr_el2 |= mdcr_set;
> > +     vcpu->arch.cptr_el2 = val;
> >  }


From tabba at google.com  Mon Dec  9 00:09:34 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 9 Dec 2024 08:09:34 +0000
Subject: [PATCH v4 05/14] KVM: arm64: Initialize feature id registers for
 protected VMs
In-Reply-To: <Z1MwuSh6jc94cem0@google.com>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-6-tabba@google.com>
 <Z1MwuSh6jc94cem0@google.com>
Message-ID: <CA+EHjTwSFW5hMFWhkOMBgO1QFq1t0LaGBns_-MnDZkzU6qdfXQ@mail.gmail.com>

On Fri, 6 Dec 2024 at 17:13, Quentin Perret <qperret at google.com> wrote:
>
> On Monday 02 Dec 2024 at 15:47:32 (+0000), Fuad Tabba wrote:
> > diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> > index 59fb2f056177..1261da6a2861 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> > @@ -204,8 +204,7 @@ static u64 get_pvm_id_aa64mmfr2(const struct kvm_vcpu *vcpu)
> >       return id_aa64mmfr2_el1_sys_val & PVM_ID_AA64MMFR2_ALLOW;
> >  }
> >
> > -/* Read a sanitized cpufeature ID register by its encoding */
> > -u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> > +static u64 pvm_calc_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> >  {
> >       switch (id) {
> >       case SYS_ID_AA64PFR0_EL1:
> > @@ -240,10 +239,25 @@ u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> >       }
> >  }
> >
> > +/* Read a sanitized cpufeature ID register by its encoding */
> > +u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> > +{
> > +     return pvm_calc_id_reg(vcpu, id);
> > +}
>
> That wrapper doesn't look particularly useful, perhaps we could drop it?

It does get dropped in the next patch.

Cheers,
/fuad


From tudor.ambarus at linaro.org  Mon Dec  9 00:11:35 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 9 Dec 2024 08:11:35 +0000
Subject: [PATCH v3 1/3] dt-bindings: mailbox: add bindings for
 samsung,exynos
In-Reply-To: <2lkowhldq5i4otniijfw7cb3jm6ttatwji3npw5w7c5fyevnn5@ynojupmdyqy4>
References: <20241205174137.190545-1-tudor.ambarus@linaro.org>
 <20241205174137.190545-2-tudor.ambarus@linaro.org>
 <2lkowhldq5i4otniijfw7cb3jm6ttatwji3npw5w7c5fyevnn5@ynojupmdyqy4>
Message-ID: <9886429b-1bf3-4dc3-b0d4-294a98e44ff2@linaro.org>

Thanks for the review, Krzysztof!

On 12/9/24 7:52 AM, Krzysztof Kozlowski wrote:
> On Thu, Dec 05, 2024 at 05:41:35PM +0000, Tudor Ambarus wrote:
>> Add bindings for the Samsung Exynos Mailbox Controller.
>>
>> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
>> ---
>>  .../bindings/mailbox/samsung,exynos.yaml      | 70 +++++++++++++++++++
> 
> Filename based on compatible, so:
> google,gs101-acpm-mbox
> 
> but then entire binding seems for different device, so you most likely
> miss here actual Exynos devices.
> 

I need some guidance here, please. The mailbox controller can pass the
mailbox messages either via its own data registers, or via SRAM (like it
is used by the ACPM protocol).

I'm thinking of using the same driver for both cases, and differentiate
between the two by compatible and `of_device_id.data`. Thus I propose to
have a "google,gs101-acpm-mbox" compatible for the ACPM SRAM case and in
the future we may add a "google,gs101-mbox" compatible for the messages
passed via the controller's data register case.

Given this, I shall use the more generic name for the bindings, thus
maybe "google,gs101-mbox.yaml"? But then exynos850 has the same
controller, shouldn't we just use "samsung,exynos.yaml"?

Thanks!
ta


From tabba at google.com  Mon Dec  9 00:11:48 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 9 Dec 2024 08:11:48 +0000
Subject: [PATCH v4 06/14] KVM: arm64: Set protected VM traps based on its
 view of feature registers
In-Reply-To: <868qssu0wf.wl-maz@kernel.org>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-7-tabba@google.com>
 <Z1M1DYbvuqAEU5c-@google.com> <70992791-af72-43ed-88cc-1bb5a8acaf9a@sirena.org.uk>
 <868qssu0wf.wl-maz@kernel.org>
Message-ID: <CA+EHjTwc8VWVtU+2GArE8a8TwoZsqmaBNYuLyjqn8JpszxXqjA@mail.gmail.com>

Hi,

On Fri, 6 Dec 2024 at 18:22, Marc Zyngier <maz at kernel.org> wrote:
>
> On Fri, 06 Dec 2024 17:43:42 +0000,
> Mark Brown <broonie at kernel.org> wrote:
> >
> > On Fri, Dec 06, 2024 at 05:31:57PM +0000, Quentin Perret wrote:
> > > On Monday 02 Dec 2024 at 15:47:33 (+0000), Fuad Tabba wrote:
> >
> > > > - if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0) <
> > > > -     ID_AA64PFR0_EL1_RAS_V1P1) {
> > > > + if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
> >
> > > I'm admittedly getting a bit lost in the kvm_has_feat() macro maze, but
> > > should this be:
> >
> > >     if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1))
> >
> > > to replicate the existing check?
> >
> > kvm_has_feat() checks for a value <= the supplied constant while the
>
> Not quite:
>
> #define kvm_has_feat(kvm, id, fld, limit)                               \
>         kvm_cmp_feat(kvm, id, fld, >=, limit)
>
> > existing check is just < and the values for the field are:
> >
> > UnsignedEnum  31:28   RAS
> >       0b0000  NI
> >       0b0001  IMP
> >       0b0010  V1P1
> > EndEnum
> >
> > so they're both checking for the same thing.
>
> Evidently not. The original code is checking for RASv1p1, while the
> change turns that into a check for the original RAS spec.

Marc is right. This change was intentional, since the goal is to trap
if RAS isn't implemented/supported by the guest. I should comment on
this change in the commit message.

Thanks,
/fuad


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


From tabba at google.com  Mon Dec  9 00:14:15 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 9 Dec 2024 08:14:15 +0000
Subject: [PATCH v4 04/14] KVM: arm64: Use KVM extension checks for allowed
 protected VM capabilities
In-Reply-To: <Z1MwAomiLhnMn--k@google.com>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-5-tabba@google.com>
 <Z1MwAomiLhnMn--k@google.com>
Message-ID: <CA+EHjTy6Y6w9RyU2Vn8O+DDviSJf=P-Y4c+xVFqY-3GmHBv3kQ@mail.gmail.com>

Hi Quentin,

On Fri, 6 Dec 2024 at 17:10, Quentin Perret <qperret at google.com> wrote:
>
> On Monday 02 Dec 2024 at 15:47:31 (+0000), Fuad Tabba wrote:
> > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > index fb733b36c6c1..59ff6aac514c 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > @@ -329,34 +329,20 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
> >
> >       bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
> >
> > -     /*
> > -      * For protected VMs, always allow:
> > -      * - CPU starting in poweroff state
> > -      * - PSCI v0.2
> > -      */
> > -     set_bit(KVM_ARM_VCPU_POWER_OFF, allowed_features);
>
> For my understanding, why do we drop this bit?

Since the hypervisor is responsible for the power state of protected
VMs. This should either be a separate patch or I should explain it in
the commit message. Any preference?

Thanks,
/fuad

> >       set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
> >
> > -     /*
> > -      * Check if remaining features are allowed:
> > -      * - Performance Monitoring
> > -      * - Scalable Vectors
> > -      * - Pointer Authentication
> > -      */
> > -     if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), PVM_ID_AA64DFR0_ALLOW))
> > +     if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PMU_V3))
> >               set_bit(KVM_ARM_VCPU_PMU_V3, allowed_features);
> >
> > -     if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), PVM_ID_AA64PFR0_ALLOW))
> > -             set_bit(KVM_ARM_VCPU_SVE, allowed_features);
> > -
> > -     if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_ALLOW) &&
> > -         FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_ALLOW))
> > +     if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_ADDRESS))
> >               set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
> >
> > -     if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI), PVM_ID_AA64ISAR1_ALLOW) &&
> > -         FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA), PVM_ID_AA64ISAR1_ALLOW))
> > +     if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_GENERIC))
> >               set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
> >
> > +     if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE))
> > +             set_bit(KVM_ARM_VCPU_SVE, allowed_features);
> > +
> >       bitmap_and(kvm->arch.vcpu_features, host_kvm->arch.vcpu_features,
> >                  allowed_features, KVM_VCPU_MAX_FEATURES);
> >  }
> > --
> > 2.47.0.338.g60cca15819-goog
> >
>


From nicolas.ferre at microchip.com  Mon Dec  9 00:15:45 2024
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Mon, 9 Dec 2024 09:15:45 +0100
Subject: [PATCH] ARM: at91: pm: change BU Power Switch to automatic mode
In-Reply-To: <32b1ae9d-f55b-43d0-bb24-1fd486440ab6@tuxon.dev>
References: <20241125165648.509162-1-nicolas.ferre@microchip.com>
 <32b1ae9d-f55b-43d0-bb24-1fd486440ab6@tuxon.dev>
Message-ID: <af867f52-37f9-4caa-ab6e-8d7e409bbc87@microchip.com>

On 08/12/2024 at 16:48, Claudiu Beznea wrote:
> On 25.11.2024 18:56, nicolas.ferre at microchip.com wrote:
>> From: Nicolas Ferre <nicolas.ferre at microchip.com>
>>
>> Change how the Backup Unit Power is configured and force the
>> automatic/hardware mode.
>> This change eliminates the need for software management of the power
>> switch, ensuring it transitions to the backup power source before
>> entering low power modes.
>>
>> This is done in the only locaton where this swich was configured. It's
>> usually done in the bootloader.
>>
>> Previously, the loss of the VDDANA (or VDDIN33) power source was not
>> automatically compensated by an alternative power source. This resulted
>> in the loss of Backup Unit content, including Backup Self-refresh low
>> power mode information, OTP emulation configuration, and boot
>> configuration, for instance.
>>
>> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> I've added the fixes tag, s/locaton/location, s/swich/switch.

Thanks for your help Claudiu. Regards,
   Nicolas
> 
> Applied to at91-soc, thanks!



From sandor.yu at nxp.com  Mon Dec  9 00:16:48 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Mon, 9 Dec 2024 08:16:48 +0000
Subject: [EXT] Re: [PATCH v18 6/8] phy: freescale: Add DisplayPort/HDMI
 Combo-PHY driver for i.MX8MQ
In-Reply-To: <foi2sizfkppmunq4yqt4pex47alsvsjyqi3rk32fwyz4f5xepn@zdsx74bzzda4>
References: <cover.1730172244.git.Sandor.yu@nxp.com>
 <411e42c70e71dce33a80059f663fb6c58fb2ac8c.1730172244.git.Sandor.yu@nxp.com>
 <efciuvoptv7qxwauswfseb6zlt5w4fmjdbm3huxfsn63a6bm7u@kfgkkvqoz5x4>
 <PAXPR04MB9448F638D47B5495CF78007AF4522@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <z6p6bewmykmufsghdojr4lvziurmmfpnrr5m4w3pfjlqzobpwr@zq2d2ukjvtac>
 <PAXPR04MB9448D68A5CA9755036E9B23DF42F2@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <foi2sizfkppmunq4yqt4pex47alsvsjyqi3rk32fwyz4f5xepn@zdsx74bzzda4>
Message-ID: <PAXPR04MB94488E0A549E519CEB8AA40EF43C2@PAXPR04MB9448.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Sent: 2024?11?30? 16:30
> To: Sandor Yu <sandor.yu at nxp.com>
> Cc: 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;
> mripard at kernel.org; kernel at pengutronix.de; dl-linux-imx
> <linux-imx at nxp.com>; Oliver Brown <oliver.brown at nxp.com>;
> alexander.stein at ew.tq-group.com; sam at ravnborg.org
> Subject: Re: [EXT] Re: [PATCH v18 6/8] phy: freescale: Add DisplayPort/HDMI
> Combo-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
> 
> 
> On Tue, Nov 26, 2024 at 02:12:19PM +0000, Sandor Yu wrote:
> >
> > >
> > > On Tue, Nov 05, 2024 at 02:05:51PM +0000, Sandor Yu wrote:
> > > > >
> > > > > On Tue, Oct 29, 2024 at 02:02:14PM +0800, Sandor Yu wrote:
> > > > > > Add Cadence HDP-TX DisplayPort and 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.
> > > > > > DisplayPort or HDMI PHY mode is configured in the driver.
> > > > > >
> > > > > > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > > > > > Signed-off-by: Alexander Stein
> > > > > > <alexander.stein at ew.tq-group.com>
> > > > > > ---
> > > > > > v17->v18:
> > > > > > - fix build error as code rebase to latest kernel version.
> > > > > >
> > > > > >  drivers/phy/freescale/Kconfig                |   10 +
> > > > > >  drivers/phy/freescale/Makefile               |    1 +
> > > > > >  drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c | 1337
> > > > > ++++++++++++++++++
> > > > > >  3 files changed, 1348 insertions(+)  create mode 100644
> > > > > > drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
> > > > > >
> > > > > > diff --git a/drivers/phy/freescale/Kconfig
> > > > > > b/drivers/phy/freescale/Kconfig index
> > > > > > dcd9acff6d01a..2b1210367b31c
> > > > > > 100644
> > > > > > --- a/drivers/phy/freescale/Kconfig
> > > > > > +++ b/drivers/phy/freescale/Kconfig
> > >
> > > [...]
> > >
> > > I'm sorry, my email client cut the email.
> > >
> > > > > > +static int cdns_hdptx_dp_configure(struct phy *phy,
> > > > > > +                                union phy_configure_opts
> > > *opts) {
> > > > > > +     struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
> > > > > > +
> > > > > > +     cdns_phy->dp.link_rate = opts->dp.link_rate;
> > > > > > +     cdns_phy->dp.lanes = opts->dp.lanes;
> > > > >
> > > > > Shouldn't this be conditional on set_rate / set_lanes ?
> > > >
> > > > PHY do not support reconfigure link rate and lane count.
> > >
> > > So, you don't support reconfiguring the rate / count, but you still
> > > copy the new rate and lanes into your driver data. That sounds strange.
> >
> > The PHY will use link rate and lane count to configure its registers
> 
> I'm not sure if I follow it. Do you mean that rate / count configuration is static?

In DP controller driver, rate and lane count are determined during link training. 
These two parameters are fixed in the DP PHY driver and cannot be modified.

Sandor

> 
> --
> With best wishes
> Dmitry

From towinchenmi at gmail.com  Sun Dec  8 23:58:33 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon,  9 Dec 2024 15:58:33 +0800
Subject: [PATCH v3 1/3] dt-bindings: leds: backlight: apple,dwi-bl: Add bindings for Apple DWI backlight
In-Reply-To: <20241209075908.140014-1-towinchenmi@gmail.com>
References: <20241209075908.140014-1-towinchenmi@gmail.com>
Message-ID: <20241209075908.140014-2-towinchenmi@gmail.com>

Add the device tree bindings for backlight controllers attached via Apple
DWI 2-wire interface.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../bindings/leds/backlight/apple,dwi-bl.yaml | 54 +++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
new file mode 100644
index 000000000000..9d4aa243f679
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/apple,dwi-bl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple DWI 2-Wire Interface Backlight Controller
+
+maintainers:
+  - Nick Chan <towinchenmi at gmail.com>
+
+description: |
+  Apple SoCs contain a 2-wire interface called DWI. On some Apple iPhones,
+  iPads and iPod touches with a LCD display, 1-2 backlight controllers
+  are connected via DWI. Interfacing with DWI controls all backlight
+  controllers at the same time. As such, the backlight controllers are
+  treated as a single controller regardless of the underlying
+  configuration.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,s5l8960x-dwi-bl
+          - apple,t7000-dwi-bl
+          - apple,s8000-dwi-bl
+          - apple,t8010-dwi-bl
+          - apple,t8015-dwi-bl
+      - const: apple,dwi-bl
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      dwi_bl: backlight at 20e200010 {
+        compatible = "apple,s5l8960x-dwi-bl", "apple,dwi-bl";
+        reg = <0x2 0x0e200010 0 8>;
+        power-domains = <&ps_dwi>;
+      };
+    };
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  8 23:58:34 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon,  9 Dec 2024 15:58:34 +0800
Subject: [PATCH v3 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <20241209075908.140014-1-towinchenmi@gmail.com>
References: <20241209075908.140014-1-towinchenmi@gmail.com>
Message-ID: <20241209075908.140014-3-towinchenmi@gmail.com>

Add driver for backlight controllers attached via Apple DWI 2-wire
interface, which is found on some Apple iPhones, iPads and iPod touches
with a LCD display.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/video/backlight/Kconfig  |  12 +++
 drivers/video/backlight/Makefile |   1 +
 drivers/video/backlight/dwi_bl.c | 126 +++++++++++++++++++++++++++++++
 3 files changed, 139 insertions(+)
 create mode 100644 drivers/video/backlight/dwi_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 3614a5d29c71..e64cc3d51ac5 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -166,6 +166,18 @@ config BACKLIGHT_EP93XX
 	  To compile this driver as a module, choose M here: the module will
 	  be called ep93xx_bl.
 
+config BACKLIGHT_APPLE_DWI
+	tristate "Apple DWI 2-Wire Interface Backlight Driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	default y
+	help
+          Say Y to enable the backlight driver for backlight controllers
+          attached via the Apple DWI 2-wire interface which is found in some
+          Apple iPhones, iPads and iPod touches.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called dwi_bl.
+
 config BACKLIGHT_IPAQ_MICRO
 	tristate "iPAQ microcontroller backlight driver"
 	depends on MFD_IPAQ_MICRO
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 8fc98f760a8a..0a569d7f0210 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_BACKLIGHT_BD6107)		+= bd6107.o
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE)	+= backlight.o
 obj-$(CONFIG_BACKLIGHT_DA903X)		+= da903x_bl.o
 obj-$(CONFIG_BACKLIGHT_DA9052)		+= da9052_bl.o
+obj-$(CONFIG_BACKLIGHT_APPLE_DWI)	+= dwi_bl.o
 obj-$(CONFIG_BACKLIGHT_EP93XX)		+= ep93xx_bl.o
 obj-$(CONFIG_BACKLIGHT_GPIO)		+= gpio_backlight.o
 obj-$(CONFIG_BACKLIGHT_HP680)		+= hp680_bl.o
diff --git a/drivers/video/backlight/dwi_bl.c b/drivers/video/backlight/dwi_bl.c
new file mode 100644
index 000000000000..501c36bed8f3
--- /dev/null
+++ b/drivers/video/backlight/dwi_bl.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Driver for backlight controllers attached via Apple DWI 2-wire interface
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include <linux/backlight.h>
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#define DWI_BL_CTL			0x0
+#define DWI_BL_CTL_SEND1		BIT(0)
+#define DWI_BL_CTL_SEND2		BIT(4)
+#define DWI_BL_CTL_SEND3		BIT(5)
+#define DWI_BL_CTL_LE_DATA		BIT(6)
+/* Only used on Apple A9 and later */
+#define DWI_BL_CTL_SEND4		BIT(12)
+
+#define DWI_BL_CMD			0x4
+#define DWI_BL_CMD_TYPE			GENMASK(31, 28)
+#define DWI_BL_CMD_TYPE_SET_BRIGHTNESS	0xa
+#define DWI_BL_CMD_DATA			GENMASK(10, 0)
+
+#define DWI_BL_CTL_SEND			(DWI_BL_CTL_SEND1 | \
+					 DWI_BL_CTL_SEND2 | \
+					 DWI_BL_CTL_SEND3 | \
+					 DWI_BL_CTL_LE_DATA | \
+					 DWI_BL_CTL_SEND4)
+
+#define DWI_BL_MAX_BRIGHTNESS		2047
+
+struct apple_dwi_bl {
+	void __iomem *base;
+};
+
+static int dwi_bl_update_status(struct backlight_device *bl)
+{
+	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
+
+	int brightness = backlight_get_brightness(bl);
+
+	u32 cmd = 0;
+
+	cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
+	cmd |= FIELD_PREP(DWI_BL_CMD_TYPE, DWI_BL_CMD_TYPE_SET_BRIGHTNESS);
+
+	writel(cmd, dwi_bl->base + DWI_BL_CMD);
+	writel(DWI_BL_CTL_SEND, dwi_bl->base + DWI_BL_CTL);
+
+	return 0;
+}
+
+static int dwi_bl_get_brightness(struct backlight_device *bl)
+{
+	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
+
+	u32 cmd = readl(dwi_bl->base + DWI_BL_CMD);
+
+	return FIELD_GET(DWI_BL_CMD_DATA, cmd);
+}
+
+static const struct backlight_ops dwi_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = dwi_bl_get_brightness,
+	.update_status	= dwi_bl_update_status
+};
+
+static int dwi_bl_probe(struct platform_device *dev)
+{
+	struct apple_dwi_bl *dwi_bl;
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct resource *res;
+
+	dwi_bl = devm_kzalloc(&dev->dev, sizeof(struct apple_dwi_bl), GFP_KERNEL);
+	if (!dwi_bl)
+		return -ENOMEM;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+
+	dwi_bl->base = devm_ioremap_resource(&dev->dev, res);
+	if (IS_ERR(dwi_bl->base))
+		return PTR_ERR(dwi_bl->base);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = DWI_BL_MAX_BRIGHTNESS;
+
+	bl = devm_backlight_device_register(&dev->dev, dev->name, &dev->dev,
+					dwi_bl, &dwi_bl_ops, &props);
+	if (IS_ERR(bl))
+		return PTR_ERR(bl);
+
+	platform_set_drvdata(dev, dwi_bl);
+
+	bl->props.brightness = dwi_bl_get_brightness(bl);
+
+	return 0;
+}
+
+static const struct of_device_id dwi_bl_of_match[] = {
+	{ .compatible = "apple,dwi-bl" },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, dwi_bl_of_match);
+
+static struct platform_driver dwi_bl_driver = {
+	.driver		= {
+		.name	= "dwi-bl",
+		.of_match_table = dwi_bl_of_match
+	},
+	.probe		= dwi_bl_probe,
+};
+
+module_platform_driver(dwi_bl_driver);
+
+MODULE_DESCRIPTION("Apple DWI Backlight Driver");
+MODULE_AUTHOR("Nick Chan <towinchenmi at gmail.com>");
+MODULE_LICENSE("Dual MIT/GPL");
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec  8 23:58:35 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon,  9 Dec 2024 15:58:35 +0800
Subject: [PATCH v3 3/3] MAINTAINERS: Add entries for Apple DWI backlight controller
In-Reply-To: <20241209075908.140014-1-towinchenmi@gmail.com>
References: <20241209075908.140014-1-towinchenmi@gmail.com>
Message-ID: <20241209075908.140014-4-towinchenmi@gmail.com>

Add MAINTAINERS entries for the driver.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 17daa9ee9384..3a7dec3f9a5a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2196,6 +2196,7 @@ F:	Documentation/devicetree/bindings/i2c/apple,i2c.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/apple,*
 F:	Documentation/devicetree/bindings/iommu/apple,dart.yaml
 F:	Documentation/devicetree/bindings/iommu/apple,sart.yaml
+F:	Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
 F:	Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
 F:	Documentation/devicetree/bindings/net/bluetooth/brcm,bcm4377-bluetooth.yaml
 F:	Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml
@@ -2221,6 +2222,7 @@ F:	drivers/nvmem/apple-efuses.c
 F:	drivers/pinctrl/pinctrl-apple-gpio.c
 F:	drivers/pwm/pwm-apple.c
 F:	drivers/soc/apple/*
+F:	drivers/video/backlight/dwi_bl.c
 F:	drivers/watchdog/apple_wdt.c
 F:	include/dt-bindings/interrupt-controller/apple-aic.h
 F:	include/dt-bindings/pinctrl/apple.h
-- 
2.47.1



From ck.hu at mediatek.com  Mon Dec  9 00:17:48 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 9 Dec 2024 08:17:48 +0000
Subject: [PATCH v2 13/15] drm/mediatek: mtk_hdmi_common: Assign DDC
 adapter pointer to bridge
In-Reply-To: <20241205114518.53527-14-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-14-angelogioacchino.delregno@collabora.com>
Message-ID: <c0e144b3a90881066d0974157e66ac23f09a0fc5.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding the new HDMI TX v2 IP driver, assign the
> pointer to the DDC adapter to struct drm_bridge during probe.
> 
> This commit brings no functional changes.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> index 1b23ab6969ec..4f708b04f5e8 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> @@ -410,6 +410,7 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
>         hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
>         hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
>         hdmi->bridge.of_node = pdev->dev.of_node;
> +       hdmi->bridge.ddc = hdmi->ddc_adpt;

I don't know why only v2 driver need to assign this?
Could you point out the code where access this value?

Regards,
CK

> 
>         ret = devm_drm_bridge_add(dev, &hdmi->bridge);
>         if (ret)
> --
> 2.47.0
> 


From tudor.ambarus at linaro.org  Mon Dec  9 00:19:34 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 9 Dec 2024 08:19:34 +0000
Subject: [PATCH v3 1/3] dt-bindings: firmware: add samsung,exynos-acpm-ipc
 bindings
In-Reply-To: <k2pnpu3ef2rgy6wre2qrearwmetzb4v4meiyqpy7oyg45hohlp@kmnzulhbmdk6>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-2-tudor.ambarus@linaro.org>
 <k2pnpu3ef2rgy6wre2qrearwmetzb4v4meiyqpy7oyg45hohlp@kmnzulhbmdk6>
Message-ID: <e36da496-04f3-4f00-aab1-f52aa0c1450f@linaro.org>



On 12/9/24 8:03 AM, Krzysztof Kozlowski wrote:
>> +  initdata-base:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description:
>> +      Base address of the configuration data in the shared memory.
> If you really need this, then it should be rather encoded as part of
> shemm phandle (phandle-array with describing items, just like syscon
> phandles are done).
> 
> But OTOH, I don't see why this is needed at all so far - compatible
> defines it.

Indeed, I shall move it to compatible. If firmware ever changes, and
uses a different offset to the configuration data, then I can introduce
a new compatible.

I agree with all the other comments as well, will address them in v4.

Thanks!
ta


From etienne.carriere at foss.st.com  Mon Dec  9 00:16:24 2024
From: etienne.carriere at foss.st.com (Etienne CARRIERE - foss)
Date: Mon, 9 Dec 2024 08:16:24 +0000
Subject: [PATCH v2 2/2] firmware: arm_scmi: round rate bisecting in
 discrete rates
In-Reply-To: <7fe840af-d56d-4cb6-8d82-d42631409b2a@stanley.mountain>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-3-etienne.carriere@foss.st.com>,<7fe840af-d56d-4cb6-8d82-d42631409b2a@stanley.mountain>
Message-ID: <4c39a5a437fa42d483d1f704ec7ab4ac@foss.st.com>

Hello Dan,

Thanks for looking at this change.

On Friday, December 6, 2024, Dan Carpenter wrote:
> 
> On Tue, Dec 03, 2024 at 06:39:08PM +0100, Etienne Carriere wrote:
> > diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
> > index 09ccd6cea7f2..7bbb2ee55f4f 100644
> > --- a/drivers/clk/clk-scmi.c
> > +++ b/drivers/clk/clk-scmi.c
> > @@ -61,13 +61,20 @@ static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> >       struct scmi_clk *clk = to_scmi_clk(hw);
> >
> >       /*
> > -      * We can't figure out what rate it will be, so just return the
> > +      * In case we can't figure out what rate it will be when the clock
> > +      * describes a list of discrete rates, then just return the
> >        * rate back to the caller. scmi_clk_recalc_rate() will be called
> >        * after the rate is set and we'll know what rate the clock is
> >        * running at then.
> >        */
> > -     if (clk->info->rate_discrete)
> > +     if (clk->info->rate_discrete) {
> > +             ftmp = rate;
> 
> No need for this assignment.

It is needed. The round_rate handler in scmi clock protocol driver 
I added in drivers/firmware/arm_scmi/clock.c expects the argument
to carry the target rate as input value and provide the closest reachable
rate as output value, hence initializing @ftmp above. I needed to preserve
the value @rate since used if this round_rate handle is not available
or returns with an error.

Note that I could have changed scmi_proto_clk_ops->round_rate() 
function ABI to split input target rate and output rounded rate into
2 separated explicit arguments.

Regards,
Etienne

> 
> > +             if (scmi_proto_clk_ops->round_rate &&
> > +                 !scmi_proto_clk_ops->round_rate(clk->ph, clk->id, &ftmp))
> > +                     return ftmp;
> > +
> >               return rate;
> > +     }
> >
> >       fmin = clk->info->range.min_rate;
> >       fmax = clk->info->range.max_rate;
> 
> regards,
> dan carpenter
> 

From towinchenmi at gmail.com  Sun Dec  8 23:58:32 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon,  9 Dec 2024 15:58:32 +0800
Subject: [PATCH v3 0/3] Apple DWI backlight driver
Message-ID: <20241209075908.140014-1-towinchenmi@gmail.com>

Apple SoCs come with a 2-wire interface named DWI. On some iPhones, iPads
and iPod touches the backlight controller is connected via this interface.
This series adds a backlight driver for backlight controllers connected
this way.

Changes since v2:
- Add missing includes in driver
- Fix file path in MAINTAINERS

v2: https://lore.kernel.org/asahi/20241207130433.30351-1-towinchenmi at gmail.com/T

Changes since v1:
- Fixed dt-bindings $id.
- Make power-domains an optional property in dt-bindings.
- Added missing error checking after devm_ioremap_resource() in
dwi_bl_probe().

v1: https://lore.kernel.org/asahi/20241206172735.4310-1-towinchenmi at gmail.com/T

Nick Chan
---
Nick Chan (3):
  dt-bindings: leds: backlight: apple,dwi-bl: Add bindings for Apple DWI
    backlight
  backlight: dwi_bl: Add Apple DWI backlight driver
  MAINTAINERS: Add entries for Apple DWI backlight controller

 .../bindings/leds/backlight/apple,dwi-bl.yaml |  54 ++++++++
 MAINTAINERS                                   |   2 +
 drivers/video/backlight/Kconfig               |  12 ++
 drivers/video/backlight/Makefile              |   1 +
 drivers/video/backlight/dwi_bl.c              | 126 ++++++++++++++++++
 5 files changed, 195 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
 create mode 100644 drivers/video/backlight/dwi_bl.c


base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
-- 
2.47.1



From quic_akhilpo at quicinc.com  Mon Dec  9 00:19:15 2024
From: quic_akhilpo at quicinc.com (Akhil P Oommen)
Date: Mon, 9 Dec 2024 13:49:15 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
Message-ID: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>

When kernel is booted in EL2, SECVID registers are accessible to the
KMD. So we can use that to switch GPU's secure mode to avoid dependency
on Zap firmware. Also, we can't load a secure firmware without a
hypervisor that supports it.

Tested following configurations on sa8775p chipset (Adreno 663 gpu):

1. Gunyah (No KVM) - Loads zap shader based on DT
2. KVM in VHE - Skips zap shader load and programs SECVID register
3. KVM in nVHE - Loads zap shader based on DT
4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
	programs SECVID register

For (1) and (3) configuration, this patch doesn't have any impact.
Driver loads secure firmware based on other existing hints.

Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
---
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 +++++++++++++++++++++++------------
 1 file changed, 54 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 019610341df1..9dcaa8472430 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -14,6 +14,10 @@
 #include <linux/pm_domain.h>
 #include <linux/soc/qcom/llcc-qcom.h>
 
+#ifdef CONFIG_ARM64
+#include <asm/virt.h>
+#endif
+
 #define GPU_PAS_ID 13
 
 static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
@@ -998,6 +1002,54 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
 	return ret;
 }
 
+static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
+{
+	int ret;
+
+#ifdef CONFIG_ARM64
+	/*
+	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
+	 * to switch the secure mode to avoid the dependency on zap shader.
+	 */
+	if (is_kernel_in_hyp_mode())
+		goto direct_switch;
+#endif
+
+	/*
+	 * Try to load a zap shader into the secure world. If successful
+	 * we can use the CP to switch out of secure mode. If not then we
+	 * have no resource but to try to switch ourselves out manually. If we
+	 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
+	 * be blocked and a permissions violation will soon follow.
+	 */
+	ret = a6xx_zap_shader_init(gpu);
+	if (ret == -ENODEV) {
+		/*
+		 * This device does not use zap shader (but print a warning
+		 * just in case someone got their dt wrong.. hopefully they
+		 * have a debug UART to realize the error of their ways...
+		 * if you mess this up you are about to crash horribly)
+		 */
+		dev_warn_once(gpu->dev->dev,
+			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
+		goto direct_switch;
+	} else if (ret)
+		return ret;
+
+	OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
+	OUT_RING(gpu->rb[0], 0x00000000);
+
+	a6xx_flush(gpu, gpu->rb[0]);
+	if (!a6xx_idle(gpu, gpu->rb[0]))
+		return -EINVAL;
+
+	return 0;
+
+direct_switch:
+	gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
+	return 0;
+}
+
 #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
 		       A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
 		       A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
@@ -1341,35 +1393,9 @@ static int hw_init(struct msm_gpu *gpu)
 	if (ret)
 		goto out;
 
-	/*
-	 * Try to load a zap shader into the secure world. If successful
-	 * we can use the CP to switch out of secure mode. If not then we
-	 * have no resource but to try to switch ourselves out manually. If we
-	 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
-	 * be blocked and a permissions violation will soon follow.
-	 */
-	ret = a6xx_zap_shader_init(gpu);
-	if (!ret) {
-		OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
-		OUT_RING(gpu->rb[0], 0x00000000);
-
-		a6xx_flush(gpu, gpu->rb[0]);
-		if (!a6xx_idle(gpu, gpu->rb[0]))
-			return -EINVAL;
-	} else if (ret == -ENODEV) {
-		/*
-		 * This device does not use zap shader (but print a warning
-		 * just in case someone got their dt wrong.. hopefully they
-		 * have a debug UART to realize the error of their ways...
-		 * if you mess this up you are about to crash horribly)
-		 */
-		dev_warn_once(gpu->dev->dev,
-			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
-		gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
-		ret = 0;
-	} else {
+	ret = a6xx_switch_secure_mode(gpu);
+	if (!ret)
 		return ret;
-	}
 
 out:
 	if (adreno_has_gmu_wrapper(adreno_gpu))

---
base-commit: f4a867a46862c1743501bbe8c813238456ec8699
change-id: 20241120-drm-msm-kvm-support-cd6e6744ced6

Best regards,
-- 
Akhil P Oommen <quic_akhilpo at quicinc.com>



From peng.fan at nxp.com  Mon Dec  9 00:26:48 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 9 Dec 2024 08:26:48 +0000
Subject: [PATCH] soc: imx8m: Add remove function
In-Reply-To: <20241206114130.zt4rkotzbzi3xt5n@pengutronix.de>
References: <20241206112843.98720-1-peng.fan@oss.nxp.com>
 <20241206114130.zt4rkotzbzi3xt5n@pengutronix.de>
Message-ID: <PAXPR04MB8459052EFE2C6137146F9CFC883C2@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH] soc: imx8m: Add remove function
> 
> On 24-12-06, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > Unregister the cpufreq device and soc device in remove path,
> otherwise
> > there will be warning when do removing test:
> > sysfs: cannot create duplicate filename '/devices/platform/imx-
> cpufreq-dt'
> > CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted
> > 6.13.0-rc1-next-20241204 Hardware name: NXP i.MX8MPlus EVK
> board (DT)
> >
> > Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as platform
> > driver")
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/soc/imx/soc-imx8m.c | 32 +++++++++++++++++++++++++++----
> -
> >  1 file changed, 27 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-
> imx8m.c
> > index 8ac7658e3d52..8c368947d1e5 100644
> > --- a/drivers/soc/imx/soc-imx8m.c
> > +++ b/drivers/soc/imx/soc-imx8m.c
> > @@ -33,6 +33,11 @@ struct imx8_soc_data {
> >  	int (*soc_revision)(u32 *socrev, u64 *socuid);  };
> >
> > +struct imx8m_soc_priv {
> > +	struct soc_device *soc_dev;
> > +	struct platform_device *cpufreq_dev; };
> > +
> >  #ifdef CONFIG_HAVE_ARM_SMCCC
> >  static u32 imx8mq_soc_revision_from_atf(void)
> >  {
> > @@ -198,7 +203,7 @@ static int imx8m_soc_probe(struct
> platform_device *pdev)
> >  	const struct imx8_soc_data *data;
> >  	struct device *dev = &pdev->dev;
> >  	const struct of_device_id *id;
> > -	struct soc_device *soc_dev;
> > +	struct imx8m_soc_priv *priv;
> >  	u32 soc_rev = 0;
> >  	u64 soc_uid = 0;
> >  	int ret;
> > @@ -207,6 +212,10 @@ static int imx8m_soc_probe(struct
> platform_device *pdev)
> >  	if (!soc_dev_attr)
> >  		return -ENOMEM;
> >
> > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> >  	soc_dev_attr->family = "Freescale i.MX";
> >
> >  	ret = of_property_read_string(of_root, "model",
> > &soc_dev_attr->machine); @@ -235,21 +244,34 @@ static int
> imx8m_soc_probe(struct platform_device *pdev)
> >  	if (!soc_dev_attr->serial_number)
> >  		return -ENOMEM;
> >
> > -	soc_dev = soc_device_register(soc_dev_attr);
> > -	if (IS_ERR(soc_dev))
> > -		return PTR_ERR(soc_dev);
> > +	priv->soc_dev = soc_device_register(soc_dev_attr);
> > +	if (IS_ERR(priv->soc_dev))
> > +		return PTR_ERR(priv->soc_dev);
> >
> >  	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
> >  		soc_dev_attr->revision);
> >
> >  	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
> > -		platform_device_register_simple("imx-cpufreq-dt", -1,
> NULL, 0);
> > +		priv->cpufreq_dev =
> > +platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
> 
> If CONFIG_ARM_IMX_CPUFREQ_DT is enabled, I asusme that
> platform_device_register_simple() shouldn't fail else it will be an error,
> right? Therefore I would like to add the 'if(!IS_ERR())' check here
> instead of the remove function.

You mean below?
dev = platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
if (!IS_ERR(dev))
   plat->cpufreq_dev = dev;
else
  pr_err("Failed to register imx-cpufreq-dt: %d\n", ERR_PTR(dev))?

But using !IS_ERR(plat->cpufreq_dev) in remove path looks
simpler.

Thanks,
Peng

> 
> > +
> > +	platform_set_drvdata(pdev, priv);
> >
> >  	return 0;
> >  }
> >
> > +static void imx8m_soc_remove(struct platform_device *pdev) {
> > +	struct imx8m_soc_priv *priv = platform_get_drvdata(pdev);
> > +
> > +	if (!IS_ERR(priv->cpufreq_dev))
> 
> With the above shifted, we only need to:
> 	if (priv->cpufreq_dev)
> 
> Regards,
>   Marco
> 
> 
> > +		platform_device_unregister(priv->cpufreq_dev);
> > +
> > +	soc_device_unregister(priv->soc_dev);
> > +}
> > +
> >  static struct platform_driver imx8m_soc_driver = {
> >  	.probe = imx8m_soc_probe,
> > +	.remove	= imx8m_soc_remove,
> >  	.driver = {
> >  		.name = "imx8m-soc",
> >  	},
> > --
> > 2.37.1
> >
> >
> >


From shawnguo2 at yeah.net  Mon Dec  9 00:27:16 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 16:27:16 +0800
Subject: [PATCH] arm64: dts: imx95: correct the address length of
 netcmix_blk_ctrl
In-Reply-To: <20241105054603.1470260-1-wei.fang@nxp.com>
References: <20241105054603.1470260-1-wei.fang@nxp.com>
Message-ID: <Z1ap5M0KGCcz5rfl@dragon>

On Tue, Nov 05, 2024 at 01:46:02PM +0800, Wei Fang wrote:
> The netc_blk_ctrl is controlled by the imx95-blk-ctl clock driver and
> provides relevant clock configurations for NETC, SAI and MQS. Its address
> length should be 8 bytes instead of 0x1000.
> 
> Fixes: 7764fef26ea9 ("arm64: dts: imx95: Add NETCMIX block control support")
> Signed-off-by: Wei Fang <wei.fang at nxp.com>

Applied, thanks!



From krzk at kernel.org  Mon Dec  9 00:29:58 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 09:29:58 +0100
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <0ba62a72-8247-447f-b710-234385a29d14@gmail.com>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-3-tudor.ambarus@linaro.org>
 <ce757b8e-4e6c-4ba9-9483-b57e6e230fdf@linaro.org>
 <vxqi23hxw7bmtfs5wk3u7szganpv5aa74b26xrvpmbehkltodw@dpum7zrxdz44>
 <2eedbbe1-6b4c-427b-a369-5b08dc27deaf@linaro.org>
 <0ba62a72-8247-447f-b710-234385a29d14@gmail.com>
Message-ID: <faghtvhan6xmhoezeaocmdusxkmy4g3vrldzn7mlukbh33isr6@c27o6p7a6a6f>

On Sun, Dec 08, 2024 at 06:38:50PM +0200, Markuss Broks wrote:
> 
> On 12/6/24 9:50 PM, Daniel Lezcano wrote:
> > On 12/6/24 14:28, Krzysztof Kozlowski wrote:
> > > On Fri, Dec 06, 2024 at 12:39:56AM +0100, Daniel Lezcano wrote:
> > > > > +# SPDX-License-Identifier: GPL-2.0-only
> > > > > +
> > > > > +config EXYNOS_ACPM_PROTOCOL
> > > > > +??? tristate "Exynos Alive Clock and Power Manager (ACPM)
> > > > > Message Protocol"
> > > > 
> > > > Given the importance of this driver where a lot of PM services
> > > > rely on, does
> > > > it really make sense to allow it as a module ?
> > > > 
> > > > Some PM services may be needed very early in the boot process
> > > > 
> > > 
> > > If it works as module e.g. on Android, it is beneficial. I think the
> > > platform was booting fine without it, at least to some shell, so I can
> > > imagine this can be loaded a bit later.
> > 
> > Usually the firmware sets the frequency to the maximum in order to boot
> > the kernel as fast as possible. That may lead to thermal issues at boot
> > time where the thermal framework won't be able to kick in as some
> > components will depends on ACPM while the system stays at its highest
> > performance state.

I disagree with the first assumption: usually firmware selects high, but
safe frequency. Otherwise you would not be able to wait in bootloader
prompt.

> Also, as far as I understand, ACPM is used here as an interface to the PMIC,
> so every driver which would need power management from the main SoC PMIC
> would get deferred until the ACPM module has been loaded. This would make it

It was an issue 10 years ago, not anymore. Drivers handle deferred
probe.

> impossible to e.g. initialize the UFS or the MMC card before initramfs.

Which is not a problem, because you are supposed to have initramfs. This
is preferred way. Being this a module does not force you to use it as a
module, e.g. if in your setup you do not have initramfs (although it is
unlikely for arm64 platforms...).

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec  9 00:33:16 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 09:33:16 +0100
Subject: [PATCH v3 1/3] dt-bindings: mailbox: add bindings for
 samsung,exynos
In-Reply-To: <9886429b-1bf3-4dc3-b0d4-294a98e44ff2@linaro.org>
References: <20241205174137.190545-1-tudor.ambarus@linaro.org>
 <20241205174137.190545-2-tudor.ambarus@linaro.org>
 <2lkowhldq5i4otniijfw7cb3jm6ttatwji3npw5w7c5fyevnn5@ynojupmdyqy4>
 <9886429b-1bf3-4dc3-b0d4-294a98e44ff2@linaro.org>
Message-ID: <58d62506-de89-40e4-a3c2-bd27da515a45@kernel.org>

On 09/12/2024 09:11, Tudor Ambarus wrote:
> Thanks for the review, Krzysztof!
> 
> On 12/9/24 7:52 AM, Krzysztof Kozlowski wrote:
>> On Thu, Dec 05, 2024 at 05:41:35PM +0000, Tudor Ambarus wrote:
>>> Add bindings for the Samsung Exynos Mailbox Controller.
>>>
>>> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
>>> ---
>>>  .../bindings/mailbox/samsung,exynos.yaml      | 70 +++++++++++++++++++
>>
>> Filename based on compatible, so:
>> google,gs101-acpm-mbox
>>
>> but then entire binding seems for different device, so you most likely
>> miss here actual Exynos devices.
>>
> 
> I need some guidance here, please. The mailbox controller can pass the
> mailbox messages either via its own data registers, or via SRAM (like it
> is used by the ACPM protocol).
> 
> I'm thinking of using the same driver for both cases, and differentiate
> between the two by compatible and `of_device_id.data`. Thus I propose to
> have a "google,gs101-acpm-mbox" compatible for the ACPM SRAM case and in
> the future we may add a "google,gs101-mbox" compatible for the messages
> passed via the controller's data register case.

Good that you pointed it out, I was indeed wondering why this is
"acpm-mbox", not "mbox in compatible.

This needs to be fixed - you cannot have two compatibles for the same
device.

> 
> Given this, I shall use the more generic name for the bindings, thus
> maybe "google,gs101-mbox.yaml"? But then exynos850 has the same
> controller, shouldn't we just use "samsung,exynos.yaml"?

If exynos850 has the same controller, then add it to the binding. Anyway
then use samsung,exynos850-mbox, because samsung,exynos is way too generic.



Best regards,
Krzysztof


From shawnguo2 at yeah.net  Mon Dec  9 00:36:57 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 16:36:57 +0800
Subject: [PATCH v3 3/3] arm64: dts: imx8mp: add aristainetos3 board
 support
In-Reply-To: <20241105064206.43626-4-hs@denx.de>
References: <20241105064206.43626-1-hs@denx.de>
 <20241105064206.43626-4-hs@denx.de>
Message-ID: <Z1asKaRAJKTBv8ui@dragon>

On Tue, Nov 05, 2024 at 07:42:06AM +0100, Heiko Schocher wrote:
> Add support for the i.MX8MP based aristainetos3 boards from ABB.
> 
> The board uses a ABB specific SoM from ADLink, based on NXP
> i.MX8MP SoC. The SoM is used on 3 different carrier boards,
> with small differences.
> 
> Signed-off-by: Heiko Schocher <hs at denx.de>

Applied, thanks!



From sandor.yu at nxp.com  Mon Dec  9 00:38:53 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Mon, 9 Dec 2024 08:38:53 +0000
Subject: [PATCH v19 6/8] phy: freescale: Add DisplayPort/HDMI Combo-PHY
 driver for i.MX8MQ
In-Reply-To: <slkpvbemsrz5jv4cafp7k4pdj3smpl575w2dtmjoheoqqrh32j@2wi5564jzawg>
References: <cover.1732627815.git.Sandor.yu@nxp.com>
 <4ef8252825d7a962b440519fb17fdcd5dd817672.1732627815.git.Sandor.yu@nxp.com>
 <slkpvbemsrz5jv4cafp7k4pdj3smpl575w2dtmjoheoqqrh32j@2wi5564jzawg>
Message-ID: <PAXPR04MB94488CEFA54F8AA193DC2BBDF43C2@PAXPR04MB9448.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Sent: 2024?11?26? 22:43
> To: Sandor Yu <sandor.yu at nxp.com>
> Cc: 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;
> mripard at kernel.org; kernel at pengutronix.de; dl-linux-imx
> <linux-imx at nxp.com>; Oliver Brown <oliver.brown at nxp.com>;
> alexander.stein at ew.tq-group.com; sam at ravnborg.org
> Subject: [EXT] Re: [PATCH v19 6/8] phy: freescale: Add DisplayPort/HDMI
> Combo-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
> 
> 
> On Tue, Nov 26, 2024 at 10:11:51PM +0800, Sandor Yu wrote:
> > Add Cadence HDP-TX DisplayPort and 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.
> > DisplayPort or HDMI PHY mode is configured in the driver.
> >
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > v18->v19:
> > - Simplify the PLL tables by removing unused and constant data
> > - Remove PHY power management, controller driver will handle them.
> > - Remove enum dp_link_rate
> > - Introduce read_pll_timeout.
> > - Update clock management as devm_clk_get_enabled() introduced.
> > - Remove cdns_hdptx_phy_init() and cdns_hdptx_phy_remove().
> >
> > v17->v18:
> > - fix build error as code rebase to latest kernel version.
> >
> >  drivers/phy/freescale/Kconfig                |   10 +
> >  drivers/phy/freescale/Makefile               |    1 +
> >  drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c | 1237
> ++++++++++++++++++
> >  3 files changed, 1248 insertions(+)
> >  create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
> >
> > diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> > index dcd9acff6d01a..bbd17e9556cc3 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_HDPTX
> > +     tristate "Freescale i.MX8MQ DP/HDMI PHY support"
> > +     depends on OF && HAS_IOMEM
> > +     depends on COMMON_CLK
> > +     depends on CDNS_MHDP_HELPER
> 
> You should not be depending on the symbol that can not be selected by
> the user.

OK.

> 
> > +     select GENERIC_PHY
> > +     help
> > +       Enable this to support the Cadence HDPTX DP/HDMI PHY driver
> > +       on i.MX8MQ SOC.
> > +
> >  config PHY_FSL_IMX8QM_HSIO
> >       tristate "Freescale i.MX8QM HSIO PHY"
> >       depends on OF && HAS_IOMEM
> > diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
> > index 658eac7d0a622..a946b87905498 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_HDPTX)   += phy-fsl-imx8mq-hdptx.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-hdptx.c
> b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
> > new file mode 100644
> > index 0000000000000..e99487622d43c
> > --- /dev/null
> > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
> > @@ -0,0 +1,1237 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Cadence DP/HDMI PHY driver
> > + *
> > + * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
> > + */
> > +#include <drm/bridge/cdns-mhdp-helper.h>
> 
> Still, I'd ask for drivers/soc instead.

If put it in drivers/soc, should I create a new directory called drivers/soc/cadence or put it in drivers/soc/imx?

The mhdp helpers will share code between cdns-mhdp8501 and cdns-mhdp8546.
I prefer creating a new directory, drivers/soc/cadence, but the problem is that cadence not a real SoC.

> 
> > +#include <linux/clk.h>
> > +#include <linux/kernel.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/io.h>
> > +#include <linux/unaligned.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_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_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_CTRL                     0x00e0
> > +#define CMN_TXPUCAL_INIT_TMR                 0x00e4
> > +#define CMN_TXPUCAL_ITER_TMR                 0x00e5
> > +#define CMN_TXPDCAL_CTRL                     0x00f0
> > +#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_CTRL                    0x0108
> > +#define CMN_TXPU_ADJ_INIT_TMR                        0x010a
> > +#define CMN_TXPU_ADJ_ITER_TMR                        0x010b
> > +#define CMN_TXPD_ADJ_CTRL                    0x010c
> > +#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_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 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_HSCLK_SEL                  0x40e1
> > +#define XCVR_DIAG_BIDI_CTRL                  0x40e8
> > +#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_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_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_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                               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)
> > +#define HSCLK_PLL0_DIV2                              1
> > +
> > +/* 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)
> > +#define DPLL_DATA_RATE_DIV_MODE3_MASK
> GENMASK(13, 12)
> > +
> > +/* 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
> > +
> > +/* FW check alive timeout */
> > +#define CDNS_KEEP_ALIVE_TIMEOUT              2000
> > +#define CDNS_KEEP_ALIVE_MASK         GENMASK(7, 0)
> > +
> > +#define REF_CLK_27MHZ                27000000
> > +
> > +#define LINK_RATE_2_7        270000
> > +#define MAX_LINK_RATE        540000
> > +
> > +#define CMN_REF_CLK_DIG_DIV  1
> > +#define REF_CLK_DIVIDER_SCALER       1
> > +
> > +/* HDMI TX clock control settings */
> > +struct hdptx_hdmi_ctrl {
> > +     u32 pixel_clk_freq;
> > +     u32 feedback_factor;
> > +     u32 cmnda_pll0_ip_div;
> > +     u32 pll_fb_div_total;
> > +     u32 cmnda_pll0_fb_div_low;
> > +     u32 cmnda_pll0_fb_div_high;
> > +     u32 cmnda_pll0_pxdiv_low;
> > +     u32 cmnda_pll0_pxdiv_high;
> > +     u32 vco_ring_select;
> > +     u32 cmnda_hs_clk_0_sel;
> > +     u32 cmnda_hs_clk_1_sel;
> > +     u32 hsclk_div_tx_sub_rate;
> > +     u32 cmnda_pll0_hs_sym_div_sel;
> > +};
> > +
> > +struct cdns_hdptx_phy {
> > +     struct cdns_mhdp_base base;
> > +
> > +     void __iomem *regs;     /* DPTX registers base */
> > +     struct device *dev;
> > +     struct phy *phy;
> > +     struct clk *ref_clk, *apb_clk;
> > +     u32 ref_clk_rate;
> > +     union {
> > +             struct phy_configure_opts_hdmi hdmi;
> > +             struct phy_configure_opts_dp dp;
> > +     };
> > +};
> > +
> > +/* HDMI TX clock control settings, pixel clock is output */
> > +static const struct hdptx_hdmi_ctrl pixel_clk_output_ctrl_table[] = {
> > +     /*  clk   fbak ipd totl div_l  div_h pd_l  pd_h  v h1 h2 sub
> sym*/
> > +     {  27000, 1000, 3, 240, 0x0bc, 0x30, 0x26, 0x26, 0, 2, 2, 4, 3 },
> > +     {  27000, 1250, 3, 300, 0x0ec, 0x3c, 0x30, 0x30, 0, 2, 2, 4, 3 },
> > +     {  27000, 1500, 3, 360, 0x11c, 0x48, 0x3a, 0x3a, 0, 2, 2, 4, 3 },
> > +     {  27000, 2000, 3, 240, 0x0bc, 0x30, 0x26, 0x26, 0, 2, 2, 4, 2 },
> > +     {  54000, 1000, 3, 480, 0x17c, 0x60, 0x26, 0x26, 1, 2, 2, 4, 3 },
> > +     {  54000, 1250, 4, 400, 0x13c, 0x50, 0x17, 0x17, 0, 1, 1, 4, 2 },
> > +     {  54000, 1500, 4, 480, 0x17c, 0x60, 0x1c, 0x1c, 0, 2, 2, 2, 2 },
> > +     {  54000, 2000, 3, 240, 0x0bc, 0x30, 0x12, 0x12, 0, 2, 2, 1, 1 },
> > +     {  74250, 1000, 3, 660, 0x20c, 0x84, 0x26, 0x26, 1, 2, 2, 4, 3 },
> > +     {  74250, 1250, 4, 550, 0x1b4, 0x6e, 0x17, 0x17, 1, 1, 1, 4, 2 },
> > +     {  74250, 1500, 4, 660, 0x20c, 0x84, 0x1c, 0x1c, 1, 2, 2, 2, 2 },
> > +     {  74250, 2000, 3, 330, 0x104, 0x42, 0x12, 0x12, 0, 2, 2, 1, 1 },
> > +     {  99000, 1000, 3, 440, 0x15c, 0x58, 0x12, 0x12, 1, 2, 2, 2, 2 },
> > +     {  99000, 1250, 3, 275, 0x0d8, 0x37, 0x0b, 0x0a, 0, 1, 1, 2, 1 },
> > +     {  99000, 1500, 3, 330, 0x104, 0x42, 0x0d, 0x0d, 0, 2, 2, 1, 1 },
> > +     {  99000, 2000, 3, 440, 0x15c, 0x58, 0x12, 0x12, 1, 2, 2, 1, 1 },
> > +     { 148500, 1000, 3, 660, 0x20c, 0x84, 0x12, 0x12, 1, 2, 2, 2, 2 },
> > +     { 148500, 1250, 4, 550, 0x1b4, 0x6e, 0x0b, 0x0a, 1, 1, 1, 2, 1 },
> > +     { 148500, 1500, 3, 495, 0x188, 0x63, 0x0d, 0x0d, 1, 1, 1, 2, 1 },
> > +     { 148500, 2000, 3, 660, 0x20c, 0x84, 0x12, 0x12, 1, 2, 2, 1, 1 },
> > +     { 198000, 1000, 3, 220, 0x0ac, 0x2c, 0x03, 0x03, 0, 1, 1, 1, 0 },
> > +     { 198000, 1250, 3, 550, 0x1b4, 0x6e, 0x0b, 0x0a, 1, 1, 1, 2, 1 },
> > +     { 198000, 1500, 3, 330, 0x104, 0x42, 0x06, 0x05, 0, 1, 1, 1, 0 },
> > +     { 198000, 2000, 3, 440, 0x15c, 0x58, 0x08, 0x08, 1, 1, 1, 1, 0 },
> > +     { 297000, 1000, 3, 330, 0x104, 0x42, 0x03, 0x03, 0, 1, 1, 1, 0 },
> > +     { 297000, 1500, 3, 495, 0x188, 0x63, 0x06, 0x05, 1, 1, 1, 1, 0 },
> > +     { 297000, 2000, 3, 660, 0x20c, 0x84, 0x08, 0x08, 1, 1, 1, 1, 0 },
> > +     { 594000, 1000, 3, 660, 0x20c, 0x84, 0x03, 0x03, 1, 1, 1, 1, 0 },
> > +     { 594000,  750, 3, 495, 0x188, 0x63, 0x03, 0x03, 1, 1, 1, 1, 0 },
> > +     { 594000,  625, 4, 550, 0x1b4, 0x6e, 0x03, 0x03, 1, 1, 1, 1, 0 },
> > +     { 594000,  500, 3, 660, 0x20c, 0x84, 0x03, 0x03, 1, 1, 1, 2, 1 },
> > +};
> > +
> > +/* HDMI TX PLL tuning settings */
> > +struct hdptx_hdmi_pll_tuning {
> > +     u32 vco_freq;
> > +     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 vco_cal_code;
> > +};
> > +
> > +/* HDMI TX PLL tuning settings, pixel clock is output */
> > +static const struct hdptx_hdmi_pll_tuning pixel_clk_output_pll_table[] = {
> > +     /*VCO_f  coar cu nd pm ptat fd_d gain  cal */
> > +     { 1980000, 4, 3, 0, 9, 0x9, 220, 0x42, 183 },
> > +     { 2160000, 4, 3, 0, 9, 0x9, 240, 0x42, 208 },
> > +     { 2475000, 5, 3, 1, 0, 0x7, 275, 0x42, 209 },
> > +     { 2700000, 5, 3, 1, 0, 0x7, 300, 0x42, 230 },
> > +     { 2700000, 5, 3, 1, 0, 0x7, 400, 0x4c, 230 },
> > +     { 2970000, 6, 3, 1, 0, 0x7, 330, 0x42, 225 },
> > +     { 3240000, 6, 3, 1, 0, 0x7, 360, 0x42, 256 },
> > +     { 3240000, 6, 3, 1, 0, 0x7, 480, 0x4c, 256 },
> > +     { 3712500, 4, 3, 0, 7, 0xF, 550, 0x4c, 257 },
> > +     { 3960000, 5, 3, 0, 7, 0xF, 440, 0x42, 226 },
> > +     { 4320000, 5, 3, 1, 7, 0xF, 480, 0x42, 258 },
> > +     { 4455000, 5, 3, 0, 7, 0xF, 495, 0x42, 272 },
> > +     { 4455000, 5, 3, 0, 7, 0xF, 660, 0x4c, 272 },
> > +     { 4950000, 6, 3, 1, 0, 0x7, 550, 0x42, 258 },
> > +     { 5940000, 7, 3, 1, 0, 0x7, 660, 0x42, 292 },
> > +};
> > +
> > +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 }
> > +};
> > +
> > +static int dp_link_rate_index(u32 rate)
> > +{
> > +     switch (rate) {
> > +     case 162000:
> > +             return 0;
> > +     case 216000:
> > +             return 1;
> > +     case 243000:
> > +             return 2;
> > +     case 270000:
> > +             return 3;
> > +     case 324000:
> > +             return 4;
> > +     case 432000:
> > +             return 5;
> > +     case 540000:
> > +             return 6;
> > +     default:
> > +             return -EINVAL;
> > +     }
> > +}
> > +
> > +static int cdns_phy_reg_write(struct cdns_hdptx_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_phy *cdns_phy, u32
> addr)
> > +{
> > +     u32 reg32;
> > +
> > +     cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr <<
> 2), &reg32);
> > +
> > +     return reg32;
> > +}
> > +
> > +static void hdptx_dp_aux_cfg(struct cdns_hdptx_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);
> 
> No ndelay after the last write?

Yes.

> 
> > +}
> > +
> > +/* PMA common configuration for 27MHz */
> > +static void hdptx_dp_phy_pma_cmn_cfg_27mhz(struct cdns_hdptx_phy
> *cdns_phy)
> > +{
> > +     u32 num_lanes = cdns_phy->dp.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_phy
> *cdns_phy)
> > +{
> > +     u32 num_lanes = cdns_phy->dp.lanes;
> > +     u32 link_rate = cdns_phy->dp.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 <= LINK_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 <= LINK_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 <= LINK_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 = dp_link_rate_index(link_rate);
> > +     if (index < 0) {
> > +             dev_err(cdns_phy->dev, "Not support link rate %d\n",
> link_rate);
> > +             return;
> > +     }
> > +
> > +     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 <= LINK_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_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_phy *cdns_phy,
> > +                     u32 reg, u32 mask,
> > +                     const char *err_msg)
> > +{
> > +     int ret;
> > +     u32 val;
> > +
> > +     ret = read_poll_timeout(cdns_phy_reg_read,
> > +                             val, val & mask, 20, 1000,
> > +                             false, cdns_phy, reg);
> > +     if (ret < 0)
> > +             dev_err(cdns_phy->dev, "%s\n", err_msg);
> > +
> > +     return ret;
> > +}
> > +
> > +static int wait_for_ack_clear(struct cdns_hdptx_phy *cdns_phy,
> > +                           u32 reg, u32 mask,
> > +                           const char *err_msg)
> > +{
> > +     int ret;
> > +     u32 val;
> > +
> > +     ret = read_poll_timeout(cdns_phy_reg_read,
> > +                             val, !(val & mask), 20, 1000,
> > +                             false, cdns_phy, reg);
> > +     if (ret < 0)
> > +             dev_err(cdns_phy->dev, "%s\n", err_msg);
> > +
> > +     return ret;
> > +}
> > +
> > +static int hdptx_dp_phy_power_up(struct cdns_hdptx_phy *cdns_phy)
> > +{
> > +     u32 val;
> > +     int ret;
> > +
> > +     /* 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);
> > +
> > +     return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL,
> POWER_STATE_A0_ACK,
> > +                        "Wait A0 Ack failed");
> > +}
> > +
> > +static int hdptx_dp_phy_power_down(struct cdns_hdptx_phy *cdns_phy)
> > +{
> > +     u16 val;
> > +     int ret;
> > +
> > +     /* Place the PHY lanes in the A3 power state. */
> > +     cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL,
> POWER_STATE_A3);
> > +     ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL,
> POWER_STATE_A3_ACK,
> > +                        "Wait A3 Ack failed");
> > +     if (ret)
> > +             return ret;
> > +
> > +     /* 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);
> > +     ret = wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL,
> PLL_CLK_EN_ACK,
> > +                              "Wait PLL clock Ack clear failed");
> > +     if (ret)
> > +             return ret;
> > +
> > +     /* 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);
> > +
> > +     return  wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL,
> PLL_READY,
> > +                              "Wait PLL Ack clear failed");
> > +}
> > +
> > +static int hdptx_dp_configure(struct phy *phy,
> > +                           union phy_configure_opts *opts)
> > +{
> > +     struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
> > +
> > +     cdns_phy->dp.link_rate = opts->dp.link_rate;
> > +     cdns_phy->dp.lanes = opts->dp.lanes;
> > +
> > +     if (cdns_phy->dp.link_rate > MAX_LINK_RATE) {
> > +             dev_err(cdns_phy->dev, "Link Rate(%d) Not supported\n",
> cdns_phy->dp.link_rate);
> > +             return false;
> > +     }
> > +
> > +     if (cdns_phy->ref_clk_rate == REF_CLK_27MHZ) {
> 
> Should not be necessary, you've already checked that ref_clk_rate is
> 27 MHz during the probe.

OK.

> 
> > +             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");
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int hdptx_clk_enable(struct cdns_hdptx_phy *cdns_phy)
> > +{
> > +     struct device *dev = cdns_phy->dev;
> > +     u32 ref_clk_rate;
> > +
> > +     cdns_phy->ref_clk =  devm_clk_get_enabled(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);
> > +     }
> > +
> > +     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");
> > +             return -EINVAL;
> > +     }
> > +
> > +     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);
> > +             return -EINVAL;
> > +     }
> > +
> > +     cdns_phy->apb_clk =  devm_clk_get_enabled(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);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void hdptx_hdmi_arc_config(struct cdns_hdptx_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_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_phy_config(struct cdns_hdptx_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,
> 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,
> 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_phy *cdns_phy, unsigned
> long long char_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 char_rate_khz = char_rate / 1000;
> > +     u32 vco_freq, rate;
> > +     u32 div_total, i;
> > +
> > +     dev_dbg(cdns_phy->dev, "character clock: %d KHz\n ",
> char_rate_khz);
> > +
> > +     /* Get right row from the ctrl_table table.
> > +      * check the character rate.
> > +      */
> > +     for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++) {
> > +             rate = pixel_clk_output_ctrl_table[i].feedback_factor *
> > +                    pixel_clk_output_ctrl_table[i].pixel_clk_freq /
> 1000;
> > +             if (char_rate_khz == rate) {
> > +                     p_ctrl_table = &pixel_clk_output_ctrl_table[i];
> > +                     break;
> > +             }
> > +     }
> > +     if (i == ARRAY_SIZE(pixel_clk_output_ctrl_table)) {
> > +             dev_warn(cdns_phy->dev,
> > +                      "char clk (%d KHz) not supported\n",
> char_rate_khz);
> > +             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 &&
> > +                 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_phy *cdns_phy)
> > +{
> > +     int ret;
> > +
> > +     /* 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_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 hdptx_hdmi_configure(struct phy *phy,
> > +                             union phy_configure_opts *opts)
> > +{
> > +     struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
> > +     u32 reg;
> > +     int ret;
> > +
> > +     cdns_phy->hdmi.tmds_char_rate = opts->hdmi.tmds_char_rate;
> > +
> > +     /* Check HDMI FW alive before HDMI PHY init */
> > +     ret = readl_poll_timeout(cdns_phy->regs + KEEP_ALIVE, reg,
> > +                              reg & CDNS_KEEP_ALIVE_MASK,
> 500,
> > +                              CDNS_KEEP_ALIVE_TIMEOUT);
> > +     if (ret < 0) {
> > +             dev_err(cdns_phy->dev, "NO HDMI FW running\n");
> > +             return -ENXIO;
> > +     }
> > +
> > +     /* Configure PHY */
> > +     if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->hdmi.tmds_char_rate)
> < 0) {
> > +             dev_err(cdns_phy->dev, "failed to set phy pclock\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     hdptx_hdmi_phy_set_vswing(cdns_phy);
> > +
> > +     return 0;
> > +}
> > +
> > +static int cdns_hdptx_phy_on(struct phy *phy)
> > +{
> > +     struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
> > +
> > +     if (phy->attrs.mode == PHY_MODE_DP)
> > +             return hdptx_dp_phy_power_up(cdns_phy);
> > +     else
> > +             return hdptx_hdmi_phy_power_up(cdns_phy);
> > +}
> > +
> > +static int cdns_hdptx_phy_off(struct phy *phy)
> > +{
> > +     struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
> > +
> > +     if (phy->attrs.mode == PHY_MODE_DP)
> > +             return hdptx_dp_phy_power_down(cdns_phy);
> > +     else
> > +             return hdptx_hdmi_phy_power_down(cdns_phy);
> > +}
> > +
> > +static int
> > +cdns_hdptx_phy_valid(struct phy *phy, enum phy_mode mode,
> > +                  int submode, union phy_configure_opts *opts)
> > +{
> > +     u32 rate = opts->hdmi.tmds_char_rate / 1000;
> > +     int i;
> > +
> > +     if (mode == PHY_MODE_DP)
> > +             return 0;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++)
> > +             if (rate == pixel_clk_output_ctrl_table[i].pixel_clk_freq)
> > +                     return 0;
> > +
> > +     return -EINVAL;
> > +}
> > +
> > +static int cdns_hdptx_phy_set_mode(struct phy *phy, enum phy_mode
> mode, int submode)
> > +{
> > +     struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
> > +     int ret = 0;
> > +
> > +     if (mode == PHY_MODE_DP) {
> > +             hdptx_dp_phy_ref_clock_type(cdns_phy);
> > +             hdptx_dp_aux_cfg(cdns_phy);
> > +     } else if (mode != PHY_MODE_HDMI) {
> > +             dev_err(&phy->dev, "Invalid PHY mode: %u\n", mode);
> > +             return -EINVAL;
> > +     }
> > +
> > +     return ret;
> > +}
> > +
> > +static int cdns_hdptx_configure(struct phy *phy,
> > +                             union phy_configure_opts *opts)
> > +{
> > +     if (phy->attrs.mode == PHY_MODE_DP)
> > +             return hdptx_dp_configure(phy, opts);
> > +     else
> > +             return hdptx_hdmi_configure(phy, opts);
> > +}
> > +
> > +static const struct phy_ops cdns_hdptx_phy_ops = {
> > +     .set_mode = cdns_hdptx_phy_set_mode,
> > +     .configure = cdns_hdptx_configure,
> > +     .power_on = cdns_hdptx_phy_on,
> > +     .power_off = cdns_hdptx_phy_off,
> > +     .validate = cdns_hdptx_phy_valid,
> > +     .owner = THIS_MODULE,
> > +};
> > +
> > +static int cdns_hdptx_phy_probe(struct platform_device *pdev)
> > +{
> > +     struct cdns_hdptx_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;
> > +
> > +     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);
> 
> devm_platform_ioremap_resource()

Both PHY driver and HDMI/DP driver use the same base address, 
The IO resource could not share if devm_platform_ioremap_resource used in PHY and controller driver.

> 
> > +
> > +     phy = devm_phy_create(dev, node, &cdns_hdptx_phy_ops);
> > +     if (IS_ERR(phy))
> > +             return PTR_ERR(phy);
> > +
> > +     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;
> > +
> > +     ret = hdptx_clk_enable(cdns_phy);
> > +     if (ret) {
> > +             dev_err(dev, "Init clk fail\n");
> 
> You already have a dev_err inside hdptx_clk_enable(). You don't need
> another one here.

OK.

Best, regards
Sandor

> 
> > +             return -EINVAL;
> > +     }
> > +
> > +     phy_provider = devm_of_phy_provider_register(dev,
> of_phy_simple_xlate);
> > +     if (IS_ERR(phy_provider))
> > +             return PTR_ERR(phy_provider);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct of_device_id cdns_hdptx_phy_of_match[] = {
> > +     {.compatible = "fsl,imx8mq-hdptx-phy" },
> > +     { /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, cdns_hdptx_phy_of_match);
> > +
> > +static struct platform_driver cdns_hdptx_phy_driver = {
> > +     .probe = cdns_hdptx_phy_probe,
> > +     .driver = {
> > +             .name   = "cdns-hdptx-phy",
> > +             .of_match_table = cdns_hdptx_phy_of_match,
> > +     }
> > +};
> > +module_platform_driver(cdns_hdptx_phy_driver);
> > +
> > +MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
> > +MODULE_DESCRIPTION("Cadence HDP-TX DP/HDMI PHY driver");
> > +MODULE_LICENSE("GPL");
> > --
> > 2.34.1
> >
> 
> --
> With best wishes
> Dmitry

From krzk at kernel.org  Mon Dec  9 00:41:30 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 09:41:30 +0100
Subject: [PATCH v3 1/3] dt-bindings: clock: Add Exynos990 SoC CMU bindings
In-Reply-To: <20241207-exynos990-cmu-v3-1-20c0f6ea02f0@mentallysanemainliners.org>
References: <20241207-exynos990-cmu-v3-0-20c0f6ea02f0@mentallysanemainliners.org>
 <20241207-exynos990-cmu-v3-1-20c0f6ea02f0@mentallysanemainliners.org>
Message-ID: <4thu4plnvcamln52tjiuba74nwxthj5aqmgwo4eliqipuruh5n@rz6boaywnbsw>

On Sat, Dec 07, 2024 at 10:25:38AM +0100, Igor Belwon wrote:
> +        clocks = <&oscclk>,
> +                 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
> +                 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
> +                 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
> +                 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
> +        clock-names = "oscclk", "bus",

One per line

> +                                "usb31drd",

Fix alignment.

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

Best regards,
Krzysztof



From shawnguo2 at yeah.net  Mon Dec  9 00:46:41 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 16:46:41 +0800
Subject: [PATCH v11 3/3] ARM: dts: mxs: Add descriptions for imx287 based
 btt3-[012] devices
In-Reply-To: <20241119165236.69438f75@wsk>
References: <20241107085705.490940-1-lukma@denx.de>
 <20241107085705.490940-3-lukma@denx.de>
 <20241119165236.69438f75@wsk>
Message-ID: <Z1aucR3ueKIxOjSX@dragon>

On Tue, Nov 19, 2024 at 04:52:36PM +0100, Lukasz Majewski wrote:
> Dear Community,
> 
> > The btt3 device' HW revisions from 0 to 2 use imx287 SoC and are to
> > some extend similar to already upstreamed XEA devices, hence are
> > using common imx28-lwe.dtsi file.
> > 
> > New, imx28-btt3.dtsi has been added to embrace common DTS
> > properties for different HW revisions for this device.
> > 
> > As a result - changes introduced in imx28-btt3-[012].dts are
> > minimal.
> > 
> 
> Are there any more comments / suggestions for this patch set?

Patch #2 and #3 look good to me.  That said, I'm waiting #1 to be
applied first.

Shawn



From s-vadapalli at ti.com  Mon Dec  9 00:51:56 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Mon, 9 Dec 2024 14:21:56 +0530
Subject: [PATCH v2] arm64: dts: ti: k3-j784s4-j742s2-main-common: Enable ACSPCIE output for PCIe1
Message-ID: <20241209085157.1203168-1-s-vadapalli@ti.com>

The PCIe reference clock required by the PCIe Endpoints connected to the
PCIe connector corresponding to the PCIe1 instance of PCIe on J784S4-EVM
and J742S2-EVM is driven by the ACSPCIE module. Add the device-tree support
for enabling the same.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

Patch is based on linux-next tagged next-20241209.

v1:
https://lore.kernel.org/r/20240715123301.1184833-1-s-vadapalli at ti.com/
Changes since v1:
- Rebased patch on linux-next tagged next-20241209.
- Moved changes from "k3-j784s4-main.dtsi" to its equivalent now which
  is "k3-j784s4-j742s2-main-common.dtsi" since PCIe1 is common to both
  J742S2 and J784S4.
- Renamed "acspcie0-proxy-ctrl" to "clock-controller" to follow generic
  node naming convention.
- Added "ti,syscon-acspcie-proxy-ctrl" property at the end of the node
  since vendor specific properties should be placed at the end.

Since all dependencies mentioned on the v1 patch have been merged, this
patch has no further dependencies. Patch has been tested on J784S4-EVM
with an NVMe SSD connected to the PCIe connector corresponding to PCIe1.
Logs:
https://gist.github.com/Siddharth-Vadapalli-at-TI/c36e30d8e9eb7bec96f7f400af1ea470

Regards,
Siddharth.

 .../boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi     | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi
index 7721852c1f68..cddadd12f444 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/mux/mux.h>
 #include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-cadence.h>
 #include <dt-bindings/phy/phy-ti.h>
 
 #include "k3-serdes.h"
@@ -124,6 +125,11 @@ audio_refclk1: clock at 82e4 {
 			assigned-clock-parents = <&k3_clks 157 63>;
 			#clock-cells = <0>;
 		};
+
+		acspcie0_proxy_ctrl: clock-controller at 1a090 {
+			compatible = "ti,j784s4-acspcie-proxy-ctrl", "syscon";
+			reg = <0x1a090 0x4>;
+		};
 	};
 
 	main_ehrpwm0: pwm at 3000000 {
@@ -1091,8 +1097,8 @@ pcie1_rc: pcie at 2910000 {
 		max-link-speed = <3>;
 		num-lanes = <4>;
 		power-domains = <&k3_pds 333 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 333 0>;
-		clock-names = "fck";
+		clocks = <&k3_clks 333 0>, <&serdes0 CDNS_TORRENT_REFCLK_DRIVER>;
+		clock-names = "fck", "pcie_refclk";
 		#address-cells = <3>;
 		#size-cells = <2>;
 		bus-range = <0x0 0xff>;
@@ -1103,6 +1109,7 @@ pcie1_rc: pcie at 2910000 {
 		ranges = <0x01000000 0x0 0x18001000  0x00 0x18001000  0x0 0x0010000>,
 			 <0x02000000 0x0 0x18011000  0x00 0x18011000  0x0 0x7fef000>;
 		dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
+		ti,syscon-acspcie-proxy-ctrl = <&acspcie0_proxy_ctrl 0x1>;
 		status = "disabled";
 	};
 
-- 
2.43.0



From amelie.delaunay at foss.st.com  Mon Dec  9 00:58:42 2024
From: amelie.delaunay at foss.st.com (Amelie Delaunay)
Date: Mon, 9 Dec 2024 09:58:42 +0100
Subject: [PATCH v2] dt-bindings: dma: st-stm32-dmamux: Add description for
 dma-cell values
In-Reply-To: <20241206115018.1155149-1-ksloat@cornersoftsolutions.com>
References: <20241206115018.1155149-1-ksloat@cornersoftsolutions.com>
Message-ID: <18c36a0b-f647-4acd-bed2-d5a09b1694b7@foss.st.com>



On 12/6/24 12:50, Ken Sloat wrote:
> The dma-cell values for the stm32-dmamux are used to craft the DMA spec
> for the actual controller. These values are currently undocumented
> leaving the user to reverse engineer the driver in order to determine
> their meaning. Add a basic description, while avoiding duplicating
> information by pointing the user to the associated DMA docs that
> describe the fields in depth.
> 
> Signed-off-by: Ken Sloat<ksloat at cornersoftsolutions.com>

Reviewed-by: Amelie Delaunay <amelie.delaunay at foss.st.com>


From ck.hu at mediatek.com  Mon Dec  9 01:09:06 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 9 Dec 2024 09:09:06 +0000
Subject: [PATCH v2 14/15] drm/mediatek: mtk_hdmi_common: Add OP_HDMI,
 vendor and product strings
In-Reply-To: <20241205114518.53527-15-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-15-angelogioacchino.delregno@collabora.com>
Message-ID: <6697eef88677950d36fbfbd6676f82f291621159.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding the HDMI TX v2 driver, and to allow
> a future modernization of the HDMI v1 one, perform changes
> that enable the usage of the HDMI Helpers provided by DRM.
> 
> Check if the HDMI driver provides the function pointers to
> hdmi_{clear,write}_infoframe used by the HDMI Helper API and,
> if present, add DRM_BRIDGE_OP_HDMI to the drm_bridge ops,
> enabling the drm API to register the bridge as HDMI and to use
> the HDMI Helper functions.
> 
> Moreover, as part of data exclusively used (in the context of
> HDMI bridges) by the helpers, assign the vendor "MediaTek" and
> product "On-Chip HDMI" strings to the drm_bridge struct.
> 
> If the hdmi_{write,clear}_infoframe pointers are not assigned,
> vendor and product strings and HDMI helpers will not be used,
> hence this commit brings no functional changes to drivers that
> have not been refactored to use the new helpers.
> 
> This also means that, in the current state, there is effectively
> no functional change to mtk_hdmi and its other components.

OP_HDMI is for v2.
vendor and product strings is for both v1 and v2.
So separate this patch to two patches.

Regards,
CK

> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> index 4f708b04f5e8..0f60842462b0 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> @@ -408,9 +408,16 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
> 
>         hdmi->bridge.funcs = ver_conf->bridge_funcs;
>         hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
> +
> +       if (ver_conf->bridge_funcs->hdmi_write_infoframe &&
> +           ver_conf->bridge_funcs->hdmi_clear_infoframe)
> +               hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI;
> +
>         hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
>         hdmi->bridge.of_node = pdev->dev.of_node;
>         hdmi->bridge.ddc = hdmi->ddc_adpt;
> +       hdmi->bridge.vendor = "MediaTek";
> +       hdmi->bridge.product = "On-Chip HDMI";
> 
>         ret = devm_drm_bridge_add(dev, &hdmi->bridge);
>         if (ret)
> --
> 2.47.0
> 


From shawnguo2 at yeah.net  Mon Dec  9 01:11:09 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 17:11:09 +0800
Subject: [PATCH 0/8] TQMa7x DT cleanup
In-Reply-To: <20241108134926.1324626-1-alexander.stein@ew.tq-group.com>
References: <20241108134926.1324626-1-alexander.stein@ew.tq-group.com>
Message-ID: <Z1a0Lc+N+J3PGnH7@dragon>

On Fri, Nov 08, 2024 at 02:49:18PM +0100, Alexander Stein wrote:
> Hi all,
> 
> this series fixes some DT binding check warnings as well as removing
> duplicated nodes. Eventually IRQ support for thernet PHYs was added.
> Additionally add CONFIG_JC42 to imx_v6_v7_defconfig.
> 
> Best regards,
> Alexander
> 
> Alexander Stein (8):
>   ARM: dts: imx7-mba7: remove LVDS transmitter regulator
>   ARM: dts: imx7-tqma7: Remove superfluous status="okay" property
>   ARM: dts: imx7-tqma7: add missing vs-supply for LM75A (rev. 01xxx)
>   ARM: dts: imx7-mba7: Add 3.3V and 5.0V regulators
>   ARM: dts: imx7-mba7: Fix SD card vmmc-supply
>   ARM: dts: imx7-mba7: Remove duplicated power supply
>   ARM: dts: imx7[d]-mba7: add Ethernet PHY IRQ support
>   ARM: imx_v6_v7_defconfig: enable JC42 for TQMa7x

Applied all, thanks!



From dan.carpenter at linaro.org  Mon Dec  9 01:12:02 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Mon, 9 Dec 2024 12:12:02 +0300
Subject: [PATCH v2 2/2] firmware: arm_scmi: round rate bisecting in
 discrete rates
In-Reply-To: <4c39a5a437fa42d483d1f704ec7ab4ac@foss.st.com>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-3-etienne.carriere@foss.st.com>
 <7fe840af-d56d-4cb6-8d82-d42631409b2a@stanley.mountain>
 <4c39a5a437fa42d483d1f704ec7ab4ac@foss.st.com>
Message-ID: <e75495ca-7cc4-48eb-ba27-607de6951181@stanley.mountain>

On Mon, Dec 09, 2024 at 08:16:24AM +0000, Etienne CARRIERE - foss wrote:
> Hello Dan,
> 
> Thanks for looking at this change.
> 
> On Friday, December 6, 2024, Dan Carpenter wrote:
> > 
> > On Tue, Dec 03, 2024 at 06:39:08PM +0100, Etienne Carriere wrote:
> > > diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
> > > index 09ccd6cea7f2..7bbb2ee55f4f 100644
> > > --- a/drivers/clk/clk-scmi.c
> > > +++ b/drivers/clk/clk-scmi.c
> > > @@ -61,13 +61,20 @@ static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> > >       struct scmi_clk *clk = to_scmi_clk(hw);
> > >
> > >       /*
> > > -      * We can't figure out what rate it will be, so just return the
> > > +      * In case we can't figure out what rate it will be when the clock
> > > +      * describes a list of discrete rates, then just return the
> > >        * rate back to the caller. scmi_clk_recalc_rate() will be called
> > >        * after the rate is set and we'll know what rate the clock is
> > >        * running at then.
> > >        */
> > > -     if (clk->info->rate_discrete)
> > > +     if (clk->info->rate_discrete) {
> > > +             ftmp = rate;
> > 
> > No need for this assignment.
> 
> It is needed. The round_rate handler in scmi clock protocol driver 
> I added in drivers/firmware/arm_scmi/clock.c expects the argument
> to carry the target rate as input value and provide the closest reachable
> rate as output value, hence initializing @ftmp above. I needed to preserve
> the value @rate since used if this round_rate handle is not available
> or returns with an error.
> 
> Note that I could have changed scmi_proto_clk_ops->round_rate() 
> function ABI to split input target rate and output rounded rate into
> 2 separated explicit arguments.

No, no.  Leave it.  Sorry.  I wasn't paying attention.

regards,
dan carpenter



From krzk at kernel.org  Mon Dec  9 01:16:21 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 10:16:21 +0100
Subject: [PATCH v2 1/3] dt-bindings: leds: backlight: apple,dwi-bl: Add
 bindings for Apple DWI backlight
In-Reply-To: <20241207130433.30351-2-towinchenmi@gmail.com>
References: <20241207130433.30351-1-towinchenmi@gmail.com>
 <20241207130433.30351-2-towinchenmi@gmail.com>
Message-ID: <iwapssdmronnbtmlmynuarzmkd2oh3ssrmzvlobxx4ixrgwgcl@dnonaahib6jw>

On Sat, Dec 07, 2024 at 09:03:14PM +0800, Nick Chan wrote:
> Add the device tree bindings for backlight controllers attached via Apple
> DWI 2-wire interface.

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

> 
> Signed-off-by: Nick Chan <towinchenmi at gmail.com>
> ---
>  .../bindings/leds/backlight/apple,dwi-bl.yaml | 54 +++++++++++++++++++
>  1 file changed, 54 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
> 
> diff --git a/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
> new file mode 100644
> index 000000000000..9d4aa243f679
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
> @@ -0,0 +1,54 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/leds/backlight/apple,dwi-bl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Apple DWI 2-Wire Interface Backlight Controller
> +
> +maintainers:
> +  - Nick Chan <towinchenmi at gmail.com>
> +
> +description: |

Do not need '|' unless you need to preserve formatting.

> +  Apple SoCs contain a 2-wire interface called DWI. On some Apple iPhones,
> +  iPads and iPod touches with a LCD display, 1-2 backlight controllers
> +  are connected via DWI. Interfacing with DWI controls all backlight
> +  controllers at the same time. As such, the backlight controllers are
> +  treated as a single controller regardless of the underlying
> +  configuration.
> +


missing allOf: with $ref to common.yaml

> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - apple,s5l8960x-dwi-bl
> +          - apple,t7000-dwi-bl
> +          - apple,s8000-dwi-bl
> +          - apple,t8010-dwi-bl
> +          - apple,t8015-dwi-bl
> +      - const: apple,dwi-bl
> +
> +  reg:
> +    maxItems: 1
> +
> +  power-domains:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false

(and this then becomes unevaluatedProperties: false)

> +
> +examples:
> +  - |
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      dwi_bl: backlight at 20e200010 {
> +        compatible = "apple,s5l8960x-dwi-bl", "apple,dwi-bl";
> +        reg = <0x2 0x0e200010 0 8>;

Usual preference is to keep hex everywhere.

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec  9 01:22:17 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 10:22:17 +0100
Subject: [PATCH v2 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <20241207130433.30351-3-towinchenmi@gmail.com>
References: <20241207130433.30351-1-towinchenmi@gmail.com>
 <20241207130433.30351-3-towinchenmi@gmail.com>
Message-ID: <bqn4tddl3kgle7zlamgaqlh45pizw6gf5qjwlmcsbkb6fx343l@tf5w63xursi2>

On Sat, Dec 07, 2024 at 09:03:15PM +0800, Nick Chan wrote:
> Add driver for backlight controllers attached via Apple DWI 2-wire
> interface, which is found on some Apple iPhones, iPads and iPod touches
> with a LCD display.
> 
> Signed-off-by: Nick Chan <towinchenmi at gmail.com>
> ---
>  drivers/video/backlight/Kconfig  |  12 +++
>  drivers/video/backlight/Makefile |   1 +
>  drivers/video/backlight/dwi_bl.c | 124 +++++++++++++++++++++++++++++++
>  3 files changed, 137 insertions(+)
>  create mode 100644 drivers/video/backlight/dwi_bl.c
> 
> diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
> index 3614a5d29c71..e64cc3d51ac5 100644
> --- a/drivers/video/backlight/Kconfig
> +++ b/drivers/video/backlight/Kconfig
> @@ -166,6 +166,18 @@ config BACKLIGHT_EP93XX
>  	  To compile this driver as a module, choose M here: the module will
>  	  be called ep93xx_bl.
>  
> +config BACKLIGHT_APPLE_DWI
> +	tristate "Apple DWI 2-Wire Interface Backlight Driver"
> +	depends on ARCH_APPLE || COMPILE_TEST
> +	default y
> +	help
> +          Say Y to enable the backlight driver for backlight controllers
> +          attached via the Apple DWI 2-wire interface which is found in some
> +          Apple iPhones, iPads and iPod touches.

Mixed/messed indentation. Some spaces?

> +
> +	  To compile this driver as a module, choose M here: the module will
> +	  be called dwi_bl.
> +
>  config BACKLIGHT_IPAQ_MICRO
>  	tristate "iPAQ microcontroller backlight driver"
>  	depends on MFD_IPAQ_MICRO
> diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
> index 8fc98f760a8a..0a569d7f0210 100644
> --- a/drivers/video/backlight/Makefile
> +++ b/drivers/video/backlight/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_BACKLIGHT_BD6107)		+= bd6107.o
>  obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE)	+= backlight.o
>  obj-$(CONFIG_BACKLIGHT_DA903X)		+= da903x_bl.o
>  obj-$(CONFIG_BACKLIGHT_DA9052)		+= da9052_bl.o
> +obj-$(CONFIG_BACKLIGHT_APPLE_DWI)	+= dwi_bl.o

Please do not introduce other sorting way - it is sorted by config name.
Which will also point you to apple_bl.o and need of explaining the
differences, e.g. why this cannot be one driver.


>  obj-$(CONFIG_BACKLIGHT_EP93XX)		+= ep93xx_bl.o
>  obj-$(CONFIG_BACKLIGHT_GPIO)		+= gpio_backlight.o
>  obj-$(CONFIG_BACKLIGHT_HP680)		+= hp680_bl.o
> diff --git a/drivers/video/backlight/dwi_bl.c b/drivers/video/backlight/dwi_bl.c
> new file mode 100644
> index 000000000000..d4bfd74b3129
> --- /dev/null
> +++ b/drivers/video/backlight/dwi_bl.c
> @@ -0,0 +1,124 @@
> +// SPDX-License-Identifier: GPL-2.0 OR MIT
> +/*
> + * Driver for backlight controllers attached via Apple DWI 2-wire interface
> + *
> + * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/io.h>
> +#include <linux/backlight.h>
> +
> +#define DWI_BL_CTL			0x0
> +#define DWI_BL_CTL_SEND1		BIT(0)
> +#define DWI_BL_CTL_SEND2		BIT(4)
> +#define DWI_BL_CTL_SEND3		BIT(5)
> +#define DWI_BL_CTL_LE_DATA		BIT(6)
> +/* Only used on Apple A9 and later */
> +#define DWI_BL_CTL_SEND4		BIT(12)
> +
> +#define DWI_BL_CMD			0x4
> +#define DWI_BL_CMD_TYPE			GENMASK(31, 28)
> +#define DWI_BL_CMD_TYPE_SET_BRIGHTNESS	0xa
> +#define DWI_BL_CMD_DATA			GENMASK(10, 0)
> +
> +#define DWI_BL_CTL_SEND			(DWI_BL_CTL_SEND1 | \
> +					 DWI_BL_CTL_SEND2 | \
> +					 DWI_BL_CTL_SEND3 | \
> +					 DWI_BL_CTL_LE_DATA | \
> +					 DWI_BL_CTL_SEND4)
> +
> +#define DWI_BL_MAX_BRIGHTNESS		2047
> +
> +struct apple_dwi_bl {
> +	void __iomem *base;
> +};
> +
> +static int dwi_bl_update_status(struct backlight_device *bl)
> +{
> +	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
> +
> +	int brightness = backlight_get_brightness(bl);
> +
> +	u32 cmd = 0;
> +
> +	cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
> +	cmd |= FIELD_PREP(DWI_BL_CMD_TYPE, DWI_BL_CMD_TYPE_SET_BRIGHTNESS);
> +
> +	writel(cmd, dwi_bl->base + DWI_BL_CMD);
> +	writel(DWI_BL_CTL_SEND, dwi_bl->base + DWI_BL_CTL);
> +
> +	return 0;
> +}
> +
> +static int dwi_bl_get_brightness(struct backlight_device *bl)
> +{
> +	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
> +
> +	u32 cmd = readl(dwi_bl->base + DWI_BL_CMD);
> +
> +	return FIELD_GET(DWI_BL_CMD_DATA, cmd);
> +}
> +
> +static const struct backlight_ops dwi_bl_ops = {
> +	.options = BL_CORE_SUSPENDRESUME,
> +	.get_brightness = dwi_bl_get_brightness,
> +	.update_status	= dwi_bl_update_status
> +};
> +
> +static int dwi_bl_probe(struct platform_device *dev)
> +{
> +	struct apple_dwi_bl *dwi_bl;
> +	struct backlight_device *bl;
> +	struct backlight_properties props;
> +	struct resource *res;
> +
> +	dwi_bl = devm_kzalloc(&dev->dev, sizeof(struct apple_dwi_bl), GFP_KERNEL);

sizeof(*)

> +	if (!dwi_bl)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENXIO;
> +
> +	dwi_bl->base = devm_ioremap_resource(&dev->dev, res);

Use helper for these two, devm_platform_get_and_ioremap_resource() or
similar.

Best regards,
Krzysztof



From shawnguo2 at yeah.net  Mon Dec  9 01:33:52 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 17:33:52 +0800
Subject: [PATCH v2] ARM: imx_v6_v7_defconfig: enable SND_SOC_SPDIF
In-Reply-To: <20241108153546.268695-1-eichest@gmail.com>
References: <20241108153546.268695-1-eichest@gmail.com>
Message-ID: <Z1a5gBgVIl0BAJ4y@dragon>

On Fri, Nov 08, 2024 at 04:34:34PM +0100, Stefan Eichenberger wrote:
> From: Stefan Eichenberger <stefan.eichenberger at toradex.com>
> 
> Enable SND_SOC_SPDIF in imx_v6_v7_defconfig to support SPDIF audio.
> 
> With commit d469b771afe1 ("ARM: dts: imx6: update spdif sound card node
> properties"), the more generic audio-codec property is used instead of
> the old spdif-controller property. Since most i.MX6 boards now use the
> audio-codec property together with the linux,spdif-dit and
> linux,spdif-dir compatible driver, it makes sense to enable
> SND_SOC_SPDIF in the imx_v6_v7_defconfig. This will ensure compatibility
> with the updated device tree.
> 
> Without this change, boards that use the audio-codec property will show
> the following error message during boot when using the
> imx_v6_v7_defconfig and spdif audio is not working:
> [   24.165534] platform sound-spdif: deferred probe pending: fsl-asoc-card: snd_soc_register_card failed
> 
> Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>

Applied, thanks!



From quic_zhenhuah at quicinc.com  Mon Dec  9 01:42:26 2024
From: quic_zhenhuah at quicinc.com (Zhenhua Huang)
Date: Mon, 9 Dec 2024 17:42:26 +0800
Subject: [PATCH v2 1/2] arm64: mm: vmemmap populate to page level if not section aligned
In-Reply-To: <20241209094227.1529977-1-quic_zhenhuah@quicinc.com>
References: <20241209094227.1529977-1-quic_zhenhuah@quicinc.com>
Message-ID: <20241209094227.1529977-2-quic_zhenhuah@quicinc.com>

Commit c1cc1552616d ("arm64: MMU initialisation")
optimizes the vmemmap to populate at the PMD section level. However, if
start or end is not aligned to a section boundary, such as when a
subsection is hot added, populating the entire section is wasteful. For
instance, if only one subsection hot-added, the entire section's struct
page metadata will still be populated.In such cases, it is more effective
to populate at page granularity.

This change also addresses mismatch issues during vmemmap_free(): When
pmd_sect() is true, the entire PMD section is cleared, even if there is
other effective subsection. For example, pagemap1 and pagemap2 are part
of a single PMD entry and they are hot-added sequentially. Then pagemap1
is removed, vmemmap_free() will clear the entire PMD entry, freeing the
struct page metadata for the whole section, even though pagemap2 is still
active.

Fixes: c1cc1552616d ("arm64: MMU initialisation")
Signed-off-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
---
 arch/arm64/mm/mmu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index e2739b69e11b..fd59ee44960e 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1177,7 +1177,9 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
 {
 	WARN_ON((start < VMEMMAP_START) || (end > VMEMMAP_END));
 
-	if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES))
+	if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) ||
+	!IS_ALIGNED(page_to_pfn((struct page *)start), PAGES_PER_SECTION) ||
+	!IS_ALIGNED(page_to_pfn((struct page *)end), PAGES_PER_SECTION))
 		return vmemmap_populate_basepages(start, end, node, altmap);
 	else
 		return vmemmap_populate_hugepages(start, end, node, altmap);
-- 
2.25.1



From quic_zhenhuah at quicinc.com  Mon Dec  9 01:42:25 2024
From: quic_zhenhuah at quicinc.com (Zhenhua Huang)
Date: Mon, 9 Dec 2024 17:42:25 +0800
Subject: [PATCH v2 0/2] Fix subsection vmemmap_populate logic
Message-ID: <20241209094227.1529977-1-quic_zhenhuah@quicinc.com>

To perform memory hotplug operations, the memmap (aka struct page) will be
updated. For arm64 with 4K page size, the typical granularity is 128M,
which corresponds to a 2M memmap buffer.
Commit c1cc1552616d ("arm64: MMU initialisation")
optimizes this 2M buffer to be mapped with one single PMD entry. However,
commit ba72b4c8cf60 ("mm/sparsemem: support sub-section hotplug")
which supports 2M subsection hotplug granularity, causes other issues
(refer to the change log of patch #1). The logic is adjusted to populate
with huge pages only if the hotplug address/size is section-aligned.

Changes since v1:
  - Modified change log to make it more clear which was based on Catalin's
    comments.

Zhenhua Huang (2):
  arm64: mm: vmemmap populate to page level if not section aligned
  arm64: mm: implement vmemmap_check_pmd for arm64

 arch/arm64/mm/mmu.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

-- 
2.25.1



From quic_zhenhuah at quicinc.com  Mon Dec  9 01:42:27 2024
From: quic_zhenhuah at quicinc.com (Zhenhua Huang)
Date: Mon, 9 Dec 2024 17:42:27 +0800
Subject: [PATCH v2 2/2] arm64: mm: implement vmemmap_check_pmd for arm64
In-Reply-To: <20241209094227.1529977-1-quic_zhenhuah@quicinc.com>
References: <20241209094227.1529977-1-quic_zhenhuah@quicinc.com>
Message-ID: <20241209094227.1529977-3-quic_zhenhuah@quicinc.com>

vmemmap_check_pmd() is used to determine if needs to populate to base
pages. Implement it for arm64 arch.

Fixes: 2045a3b8911b ("mm/sparse-vmemmap: generalise vmemmap_populate_hugepages()")
Signed-off-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
---
 arch/arm64/mm/mmu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index fd59ee44960e..41c7978a92be 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1169,7 +1169,8 @@ int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node,
 				unsigned long addr, unsigned long next)
 {
 	vmemmap_verify((pte_t *)pmdp, node, addr, next);
-	return 1;
+
+	return pmd_sect(*pmdp);
 }
 
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
-- 
2.25.1



From krzk at kernel.org  Mon Dec  9 01:49:04 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 10:49:04 +0100
Subject: [PATCH 2/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Add
 compatible for mt8390 evk
In-Reply-To: <20241205-genio700-audio-output-v1-2-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
 <20241205-genio700-audio-output-v1-2-0e955c78c29e@collabora.com>
Message-ID: <mycrs2ekxznwcxkvthamvszftrt5t66shvopn5xpuhaldtsb4g@qv2kpx6yt2mv>

On Thu, Dec 05, 2024 at 09:13:55AM -0300, N?colas F. R. A. Prado wrote:
> Add a compatible for the MT8390 EVK. It is compatible with
> mediatek,mt8188-mt6359-evb so make that the fallback compatible.
> 
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> ---
>  .../devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml  | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)

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

Best regards,
Krzysztof



From angelogioacchino.delregno at collabora.com  Mon Dec  9 01:49:28 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 10:49:28 +0100
Subject: [PATCH v2 13/15] drm/mediatek: mtk_hdmi_common: Assign DDC
 adapter pointer to bridge
In-Reply-To: <c0e144b3a90881066d0974157e66ac23f09a0fc5.camel@mediatek.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-14-angelogioacchino.delregno@collabora.com>
 <c0e144b3a90881066d0974157e66ac23f09a0fc5.camel@mediatek.com>
Message-ID: <b5a77637-64b0-4ed3-9619-e76d094505af@collabora.com>

Il 09/12/24 09:17, CK Hu (???) ha scritto:
> Hi, Angelo:
> 
> On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>
>>
>> In preparation for adding the new HDMI TX v2 IP driver, assign the
>> pointer to the DDC adapter to struct drm_bridge during probe.
>>
>> This commit brings no functional changes.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
>>   drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
>> index 1b23ab6969ec..4f708b04f5e8 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
>> @@ -410,6 +410,7 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
>>          hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
>>          hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
>>          hdmi->bridge.of_node = pdev->dev.of_node;
>> +       hdmi->bridge.ddc = hdmi->ddc_adpt;
> 
> I don't know why only v2 driver need to assign this?
> Could you point out the code where access this value?
> 

v2 uses hdmi helpers, which make use of bridge->ddc.
mtk_hdmi_v2_bridge_edid_read() calls drm_edid_read().

drm_edid.c -> drm_edid_read()
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/gpu/drm/drm_edid.c?h=next-20241209#n2704

...while v1 feeds the (internal) ddc pointer to drm_edid_read_ddc() instead.

Cheers,
Angelo

> Regards,
> CK
> 
>>
>>          ret = devm_drm_bridge_add(dev, &hdmi->bridge);
>>          if (ret)
>> --
>> 2.47.0
>>
> 




From shawnguo2 at yeah.net  Mon Dec  9 01:49:52 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 17:49:52 +0800
Subject: [PATCH] MAINTAINERS: Update entry for DH electronics DHSOM SoMs
 and boards
In-Reply-To: <20241111113524.10727-1-marex@denx.de>
References: <20241111113524.10727-1-marex@denx.de>
Message-ID: <Z1a9QGfVsSzc81ZL@dragon>

On Mon, Nov 11, 2024 at 12:34:21PM +0100, Marek Vasut wrote:
> Update the MAINTAINERS entry to cover all DH electronics DHSOM
> SoMs and boards. The DHSOM is the name which covers all modules,
> DHCOM is the SODIMM seated SoM, DHCOR is the solder on module.
> Use glob pattern to match on every DT file which contains either
> of those three module substrings in lowercase.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>

Applied, thanks!



From kevin.brodsky at arm.com  Mon Dec  9 01:50:05 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:05 +0000
Subject: [PATCH 00/14] pkeys kselftests improvements
Message-ID: <20241209095019.1732120-1-kevin.brodsky@arm.com>

This series brings various cleanups and fixes for the mm (mostly
pkeys) kselftests. The original goal was to make the pkeys tests work
out of the box and without build warning - it turned out to be more
involved than expected.

The most important change is enabling -O2 when building all mm
kselftests (patch 5). This is actually needed for the pkeys tests to run
successfully (see gcc command line at the top of protection_keys.c and
pkey_sighandler_tests.c), and seems to have no negative impact on the
other tests. It certainly can't hurt performance!

The following patches address a few obvious issues in the pkeys tests
(unused code, bad scope for functions/variables, etc.) and finally make
a couple of small improvements.

There is one ugliness that this series does not fix: some functions in
pkey-<arch>.h call functions that are actually defined in
protection_keys.c. For instance, expect_fault_on_read_execonly_key() in
pkey-x86.h calls expected_pkey_fault(). This means that other test
programs that use pkey-helpers.h (namely pkey_sighandler_tests) would
fail to link if they called such functions defined in pkey-<arch>.h.
Fixing this would require a more comprehensive reorganisation of the
pkey-* headers, which doesn't seem worth it (patch 9 adds a comment to
pkey-helpers.h to clarify the situation).

Some more details on the patches:

- Patch 1 is an unrelated fix that was revealed by inspecting a warning.
  It seems fairly harmless though, so I thought I'd just post it as part
  of this series.

- Patch 2-5 fix various warnings that come up by building the mm tests
  at -O2 and finally enable -O2.

- Patch 6-12 are various cleanups for the pkeys tests. Patch 11 in
  particular enables is_pkeys_supported() to be called from outside
  protection_keys.c (patch 13 relies on this).

- Patch 13-14 are small improvements to pkey_sighandler_tests.c.


Many thanks to Ryan Roberts for checking that the mm tests still run
fine on arm64 with those patches applied. I've also checked that the
pkeys tests run fine on arm64 and x86.

- Kevin

---
Cc: akpm at linux-foundation.org
Cc: aruna.ramakrishna at oracle.com
Cc: catalin.marinas at arm.com
Cc: dave.hansen at linux.intel.com
Cc: joey.gouly at arm.com
Cc: keith.lucas at oracle.com
Cc: ryan.roberts at arm.com
Cc: shuah at kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kselftest at vger.kernel.org
Cc: x86 at kernel.org
---
Kevin Brodsky (14):
  selftests/mm: Fix condition in uffd_move_test_common()
  selftests/mm: Fix -Wmaybe-uninitialized warnings
  selftests/mm: Fix strncpy() length
  selftests/mm: Fix -Warray-bounds warnings in pkey_sighandler_tests
  selftests/mm: Build with -O2
  selftests/mm: Remove unused pkey helpers
  selftests/mm: Define types using typedef in pkey-helpers.h
  selftests/mm: Ensure pkey-*.h define inline functions only
  selftests/mm: Remove empty pkey helper definition
  selftests/mm: Ensure non-global pkey symbols are marked static
  selftests/mm: Use sys_pkey helpers consistently
  selftests/mm: Rename pkey register macro
  selftests/mm: Skip pkey_sighandler_tests if support is missing
  selftests/mm: Remove X permission from sigaltstack mapping

 tools/testing/selftests/mm/Makefile           |   6 +-
 tools/testing/selftests/mm/ksm_tests.c        |   2 +-
 tools/testing/selftests/mm/mremap_test.c      |   2 +-
 tools/testing/selftests/mm/pkey-arm64.h       |   6 +-
 tools/testing/selftests/mm/pkey-helpers.h     |  61 ++---
 tools/testing/selftests/mm/pkey-powerpc.h     |   4 +-
 tools/testing/selftests/mm/pkey-x86.h         |   6 +-
 .../selftests/mm/pkey_sighandler_tests.c      |  32 +--
 tools/testing/selftests/mm/pkey_util.c        |  40 ++++
 tools/testing/selftests/mm/protection_keys.c  | 212 +++++++-----------
 tools/testing/selftests/mm/soft-dirty.c       |   2 +-
 tools/testing/selftests/mm/uffd-unit-tests.c  |   4 +-
 .../testing/selftests/mm/write_to_hugetlbfs.c |   2 +-
 13 files changed, 163 insertions(+), 216 deletions(-)
 create mode 100644 tools/testing/selftests/mm/pkey_util.c

-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:06 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:06 +0000
Subject: [PATCH 01/14] selftests/mm: Fix condition in uffd_move_test_common()
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-2-kevin.brodsky@arm.com>

area_src and area_dst are saved at the beginning of the function if
chunk_size > page_size. The intention is quite clearly to restore
them at the end based on the same condition, but step_size is
considered instead of chunk_size. Considering that step_size is a
number of pages, the condition is likely to be false.

Use the same condition as when saving so that the globals are
restored as intended.

Fixes: a2bf6a9ca805 ("selftests/mm: add UFFDIO_MOVE ioctl test")
Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/uffd-unit-tests.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/mm/uffd-unit-tests.c b/tools/testing/selftests/mm/uffd-unit-tests.c
index a2e71b1636e7..74c884713bf7 100644
--- a/tools/testing/selftests/mm/uffd-unit-tests.c
+++ b/tools/testing/selftests/mm/uffd-unit-tests.c
@@ -1190,7 +1190,7 @@ uffd_move_test_common(uffd_test_args_t *targs, unsigned long chunk_size,
 				    nr, count, count_verify[src_offs + nr + i]);
 		}
 	}
-	if (step_size > page_size) {
+	if (chunk_size > page_size) {
 		area_src = orig_area_src;
 		area_dst = orig_area_dst;
 	}
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:07 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:07 +0000
Subject: [PATCH 02/14] selftests/mm: Fix -Wmaybe-uninitialized warnings
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-3-kevin.brodsky@arm.com>

A few -Wmaybe-uninitialized warnings show up when building the mm
tests with -O2. None of them looks worrying; silence them by
initialising the problematic variables.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/ksm_tests.c       | 2 +-
 tools/testing/selftests/mm/mremap_test.c     | 2 +-
 tools/testing/selftests/mm/soft-dirty.c      | 2 +-
 tools/testing/selftests/mm/uffd-unit-tests.c | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/mm/ksm_tests.c b/tools/testing/selftests/mm/ksm_tests.c
index b748c48908d9..dcdd5bb20f3d 100644
--- a/tools/testing/selftests/mm/ksm_tests.c
+++ b/tools/testing/selftests/mm/ksm_tests.c
@@ -776,7 +776,7 @@ static int ksm_cow_time(int merge_type, int mapping, int prot, int timeout, size
 
 int main(int argc, char *argv[])
 {
-	int ret, opt;
+	int ret = 0, opt;
 	int prot = 0;
 	int ksm_scan_limit_sec = KSM_SCAN_LIMIT_SEC_DEFAULT;
 	int merge_type = KSM_MERGE_TYPE_DEFAULT;
diff --git a/tools/testing/selftests/mm/mremap_test.c b/tools/testing/selftests/mm/mremap_test.c
index 5a3a9bcba640..056b227f4a30 100644
--- a/tools/testing/selftests/mm/mremap_test.c
+++ b/tools/testing/selftests/mm/mremap_test.c
@@ -384,7 +384,7 @@ static void mremap_move_within_range(unsigned int pattern_seed, char *rand_addr)
 static long long remap_region(struct config c, unsigned int threshold_mb,
 			      char *rand_addr)
 {
-	void *addr, *src_addr, *dest_addr, *dest_preamble_addr;
+	void *addr, *src_addr, *dest_addr, *dest_preamble_addr = NULL;
 	unsigned long long t, d;
 	struct timespec t_start = {0, 0}, t_end = {0, 0};
 	long long  start_ns, end_ns, align_mask, ret, offset;
diff --git a/tools/testing/selftests/mm/soft-dirty.c b/tools/testing/selftests/mm/soft-dirty.c
index bdfa5d085f00..8e1462ce0532 100644
--- a/tools/testing/selftests/mm/soft-dirty.c
+++ b/tools/testing/selftests/mm/soft-dirty.c
@@ -128,7 +128,7 @@ static void test_mprotect(int pagemap_fd, int pagesize, bool anon)
 {
 	const char *type[] = {"file", "anon"};
 	const char *fname = "./soft-dirty-test-file";
-	int test_fd;
+	int test_fd = 0;
 	char *map;
 
 	if (anon) {
diff --git a/tools/testing/selftests/mm/uffd-unit-tests.c b/tools/testing/selftests/mm/uffd-unit-tests.c
index 74c884713bf7..9ff71fa1f9bf 100644
--- a/tools/testing/selftests/mm/uffd-unit-tests.c
+++ b/tools/testing/selftests/mm/uffd-unit-tests.c
@@ -1122,7 +1122,7 @@ uffd_move_test_common(uffd_test_args_t *targs, unsigned long chunk_size,
 	char c;
 	unsigned long long count;
 	struct uffd_args args = { 0 };
-	char *orig_area_src, *orig_area_dst;
+	char *orig_area_src = NULL, *orig_area_dst = NULL;
 	unsigned long step_size, step_count;
 	unsigned long src_offs = 0;
 	unsigned long dst_offs = 0;
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:08 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:08 +0000
Subject: [PATCH 03/14] selftests/mm: Fix strncpy() length
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-4-kevin.brodsky@arm.com>

GCC complains (with -O2) that the length is equal to the destination
size, which is indeed invalid. Subtract 1 from the size of the array
to leave room for '\0'.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/write_to_hugetlbfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/mm/write_to_hugetlbfs.c b/tools/testing/selftests/mm/write_to_hugetlbfs.c
index 1289d311efd7..34c91f7e6128 100644
--- a/tools/testing/selftests/mm/write_to_hugetlbfs.c
+++ b/tools/testing/selftests/mm/write_to_hugetlbfs.c
@@ -89,7 +89,7 @@ int main(int argc, char **argv)
 			size = atoi(optarg);
 			break;
 		case 'p':
-			strncpy(path, optarg, sizeof(path));
+			strncpy(path, optarg, sizeof(path) - 1);
 			break;
 		case 'm':
 			if (atoi(optarg) >= MAX_METHOD) {
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:09 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:09 +0000
Subject: [PATCH 04/14] selftests/mm: Fix -Warray-bounds warnings in pkey_sighandler_tests
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-5-kevin.brodsky@arm.com>

GCC doesn't like dereferencing a pointer set to 0x1 (when building
at -O2):

pkey_sighandler_tests.c:166:9: warning: array subscript 0 is outside array bounds of 'int[0]' [-Warray-bounds=]
  166 |         *(int *) (0x1) = 1;
      |         ^~~~~~~~~~~~~~
cc1: note: source object is likely at address zero

Using NULL instead seems to make it happy. This should make no
difference in practice (SIGSEGV with SEGV_MAPERR will be the outcome
regardless), we just need to update the expected si_addr.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/pkey_sighandler_tests.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/mm/pkey_sighandler_tests.c b/tools/testing/selftests/mm/pkey_sighandler_tests.c
index c593a426341c..e7b91794f184 100644
--- a/tools/testing/selftests/mm/pkey_sighandler_tests.c
+++ b/tools/testing/selftests/mm/pkey_sighandler_tests.c
@@ -163,7 +163,7 @@ static void *thread_segv_with_pkey0_disabled(void *ptr)
 	__write_pkey_reg(pkey_reg_restrictive_default());
 
 	/* Segfault (with SEGV_MAPERR) */
-	*(int *) (0x1) = 1;
+	*(int *)NULL = 1;
 	return NULL;
 }
 
@@ -179,7 +179,6 @@ static void *thread_segv_pkuerr_stack(void *ptr)
 static void *thread_segv_maperr_ptr(void *ptr)
 {
 	stack_t *stack = ptr;
-	int *bad = (int *)1;
 	u64 pkey_reg;
 
 	/*
@@ -195,7 +194,7 @@ static void *thread_segv_maperr_ptr(void *ptr)
 	__write_pkey_reg(pkey_reg);
 
 	/* Segfault */
-	*bad = 1;
+	*(int *)NULL = 1;
 	syscall_raw(SYS_exit, 0, 0, 0, 0, 0, 0);
 	return NULL;
 }
@@ -234,7 +233,7 @@ static void test_sigsegv_handler_with_pkey0_disabled(void)
 
 	ksft_test_result(siginfo.si_signo == SIGSEGV &&
 			 siginfo.si_code == SEGV_MAPERR &&
-			 siginfo.si_addr == (void *)1,
+			 siginfo.si_addr == NULL,
 			 "%s\n", __func__);
 }
 
@@ -349,7 +348,7 @@ static void test_sigsegv_handler_with_different_pkey_for_stack(void)
 
 	ksft_test_result(siginfo.si_signo == SIGSEGV &&
 			 siginfo.si_code == SEGV_MAPERR &&
-			 siginfo.si_addr == (void *)1,
+			 siginfo.si_addr == NULL,
 			 "%s\n", __func__);
 }
 
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:10 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:10 +0000
Subject: [PATCH 05/14] selftests/mm: Build with -O2
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-6-kevin.brodsky@arm.com>

The mm kselftests are currently built with no optimisation (-O0).
It's unclear why, and besides being obviously suboptimal, this also
prevents the pkeys tests from working as intended. Let's build all
the tests with -O2.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index 3de23ea4663f..814b17a43385 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -33,7 +33,7 @@ endif
 # LDLIBS.
 MAKEFLAGS += --no-builtin-rules
 
-CFLAGS = -Wall -I $(top_srcdir) $(EXTRA_CFLAGS) $(KHDR_INCLUDES) $(TOOLS_INCLUDES)
+CFLAGS = -Wall -O2 -I $(top_srcdir) $(EXTRA_CFLAGS) $(KHDR_INCLUDES) $(TOOLS_INCLUDES)
 LDLIBS = -lrt -lpthread -lm
 
 KDIR ?= /lib/modules/$(shell uname -r)/build
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:11 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:11 +0000
Subject: [PATCH 06/14] selftests/mm: Remove unused pkey helpers
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-7-kevin.brodsky@arm.com>

Commit 5f23f6d082a9 ("x86/pkeys: Add self-tests") introduced a
number of helpers and functions that don't seem to have ever been
used. Let's remove them.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/pkey-helpers.h    | 34 --------------------
 tools/testing/selftests/mm/protection_keys.c | 34 --------------------
 2 files changed, 68 deletions(-)

diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index f7cfe163b0ff..472febd992eb 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -26,9 +26,7 @@
 #ifndef DEBUG_LEVEL
 #define DEBUG_LEVEL 0
 #endif
-#define DPRINT_IN_SIGNAL_BUF_SIZE 4096
 extern int dprint_in_signal;
-extern char dprint_in_signal_buffer[DPRINT_IN_SIGNAL_BUF_SIZE];
 
 extern int test_nr;
 extern int iteration_nr;
@@ -171,38 +169,6 @@ static inline void write_pkey_reg(u64 pkey_reg)
 			pkey_reg, __read_pkey_reg());
 }
 
-/*
- * These are technically racy. since something could
- * change PKEY register between the read and the write.
- */
-static inline void __pkey_access_allow(int pkey, int do_allow)
-{
-	u64 pkey_reg = read_pkey_reg();
-	int bit = pkey * 2;
-
-	if (do_allow)
-		pkey_reg &= (1<<bit);
-	else
-		pkey_reg |= (1<<bit);
-
-	dprintf4("pkey_reg now: %016llx\n", read_pkey_reg());
-	write_pkey_reg(pkey_reg);
-}
-
-static inline void __pkey_write_allow(int pkey, int do_allow_write)
-{
-	u64 pkey_reg = read_pkey_reg();
-	int bit = pkey * 2 + 1;
-
-	if (do_allow_write)
-		pkey_reg &= (1<<bit);
-	else
-		pkey_reg |= (1<<bit);
-
-	write_pkey_reg(pkey_reg);
-	dprintf4("pkey_reg now: %016llx\n", read_pkey_reg());
-}
-
 #define ALIGN_UP(x, align_to)	(((x) + ((align_to)-1)) & ~((align_to)-1))
 #define ALIGN_DOWN(x, align_to) ((x) & ~((align_to)-1))
 #define ALIGN_PTR_UP(p, ptr_align_to)	\
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index 4990f7ab4cb7..fcbebc4490b4 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -53,7 +53,6 @@ int test_nr;
 
 u64 shadow_pkey_reg;
 int dprint_in_signal;
-char dprint_in_signal_buffer[DPRINT_IN_SIGNAL_BUF_SIZE];
 
 void cat_into_file(char *str, char *file)
 {
@@ -397,12 +396,6 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
 	dprint_in_signal = 0;
 }
 
-int wait_all_children(void)
-{
-	int status;
-	return waitpid(-1, &status, 0);
-}
-
 void sig_chld(int x)
 {
 	dprint_in_signal = 1;
@@ -817,39 +810,12 @@ void *malloc_pkey_hugetlb(long size, int prot, u16 pkey)
 	return ptr;
 }
 
-void *malloc_pkey_mmap_dax(long size, int prot, u16 pkey)
-{
-	void *ptr;
-	int fd;
-
-	dprintf1("doing %s(size=%ld, prot=0x%x, pkey=%d)\n", __func__,
-			size, prot, pkey);
-	pkey_assert(pkey < NR_PKEYS);
-	fd = open("/dax/foo", O_RDWR);
-	pkey_assert(fd >= 0);
-
-	ptr = mmap(0, size, prot, MAP_SHARED, fd, 0);
-	pkey_assert(ptr != (void *)-1);
-
-	mprotect_pkey(ptr, size, prot, pkey);
-
-	record_pkey_malloc(ptr, size, prot);
-
-	dprintf1("mmap()'d for pkey %d @ %p\n", pkey, ptr);
-	close(fd);
-	return ptr;
-}
-
 void *(*pkey_malloc[])(long size, int prot, u16 pkey) = {
 
 	malloc_pkey_with_mprotect,
 	malloc_pkey_with_mprotect_subpage,
 	malloc_pkey_anon_huge,
 	malloc_pkey_hugetlb
-/* can not do direct with the pkey_mprotect() API:
-	malloc_pkey_mmap_direct,
-	malloc_pkey_mmap_dax,
-*/
 };
 
 void *malloc_pkey(long size, int prot, u16 pkey)
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:12 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:12 +0000
Subject: [PATCH 07/14] selftests/mm: Define types using typedef in pkey-helpers.h
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-8-kevin.brodsky@arm.com>

Using #define to define types should be avoided. Use typedef
instead. Also ensure that __u* types are actually defined by
including <linux/types.h>.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/pkey-helpers.h | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index 472febd992eb..84376ab09545 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -13,13 +13,15 @@
 #include <ucontext.h>
 #include <sys/mman.h>
 
+#include <linux/types.h>
+
 #include "../kselftest.h"
 
 /* Define some kernel-like types */
-#define  u8 __u8
-#define u16 __u16
-#define u32 __u32
-#define u64 __u64
+typedef __u8	u8;
+typedef __u16	u16;
+typedef __u32	u32;
+typedef __u64	u64;
 
 #define PTR_ERR_ENOTSUP ((void *)-ENOTSUP)
 
-- 
2.47.0



From krzk at kernel.org  Mon Dec  9 01:50:53 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 10:50:53 +0100
Subject: [PATCH 3/5] ASoC: dt-bindings: mediatek,mt8188-mt6359: Add DSP
 properties
In-Reply-To: <20241205-genio700-audio-output-v1-3-0e955c78c29e@collabora.com>
References: <20241205-genio700-audio-output-v1-0-0e955c78c29e@collabora.com>
 <20241205-genio700-audio-output-v1-3-0e955c78c29e@collabora.com>
Message-ID: <264jrfp646x4clus6yanbldqkfz6eao3wdveyokxkcbpqufopo@gpr4qacexemp>

On Thu, Dec 05, 2024 at 09:13:56AM -0300, N?colas F. R. A. Prado wrote:
> Add the mediatek,adsp and mediatek,dai-link properties to allow
> describing the DSP configuration in the sound card node, as is already
> the case for other MediaTek SoCs.
> 
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> ---
>  .../devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml      | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 

This looks like conflicting (or applied) work.

Best regards,
Krzysztof



From kevin.brodsky at arm.com  Mon Dec  9 01:50:13 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:13 +0000
Subject: [PATCH 08/14] selftests/mm: Ensure pkey-*.h define inline functions only
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-9-kevin.brodsky@arm.com>

Headers should not define non-inline functions, as this prevents
them from being included more than once in a given program.
pkey-helpers.h and the arch-specific headers it includes currently
define multiple such non-inline functions.

In most cases those functions can simply be made inline - this patch
does just that. read_ptr() is an exception as it must not be
inlined. Since it is only called from protection_keys.c, we just move it
there.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/pkey-arm64.h      | 4 ++--
 tools/testing/selftests/mm/pkey-helpers.h    | 8 +-------
 tools/testing/selftests/mm/pkey-powerpc.h    | 4 ++--
 tools/testing/selftests/mm/pkey-x86.h        | 6 +++---
 tools/testing/selftests/mm/protection_keys.c | 7 +++++++
 5 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/tools/testing/selftests/mm/pkey-arm64.h b/tools/testing/selftests/mm/pkey-arm64.h
index d9d2100eafc0..9897e31f16dd 100644
--- a/tools/testing/selftests/mm/pkey-arm64.h
+++ b/tools/testing/selftests/mm/pkey-arm64.h
@@ -81,11 +81,11 @@ static inline int get_arch_reserved_keys(void)
 	return NR_RESERVED_PKEYS;
 }
 
-void expect_fault_on_read_execonly_key(void *p1, int pkey)
+static inline void expect_fault_on_read_execonly_key(void *p1, int pkey)
 {
 }
 
-void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
+static inline void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
 {
 	return PTR_ERR_ENOTSUP;
 }
diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index 84376ab09545..bc81275a89d9 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -84,13 +84,7 @@ extern void abort_hooks(void);
 # define noinline __attribute__((noinline))
 #endif
 
-noinline int read_ptr(int *ptr)
-{
-	/* Keep GCC from optimizing this away somehow */
-	barrier();
-	return *ptr;
-}
-
+noinline int read_ptr(int *ptr);
 void expected_pkey_fault(int pkey);
 int sys_pkey_alloc(unsigned long flags, unsigned long init_val);
 int sys_pkey_free(unsigned long pkey);
diff --git a/tools/testing/selftests/mm/pkey-powerpc.h b/tools/testing/selftests/mm/pkey-powerpc.h
index 3d0c0bdae5bc..1bad310d282a 100644
--- a/tools/testing/selftests/mm/pkey-powerpc.h
+++ b/tools/testing/selftests/mm/pkey-powerpc.h
@@ -91,7 +91,7 @@ static inline int get_arch_reserved_keys(void)
 			return NR_RESERVED_PKEYS_64K_3KEYS;
 }
 
-void expect_fault_on_read_execonly_key(void *p1, int pkey)
+static inline void expect_fault_on_read_execonly_key(void *p1, int pkey)
 {
 	/*
 	 * powerpc does not allow userspace to change permissions of exec-only
@@ -105,7 +105,7 @@ void expect_fault_on_read_execonly_key(void *p1, int pkey)
 /* 4-byte instructions * 16384 = 64K page */
 #define __page_o_noops() asm(".rept 16384 ; nop; .endr")
 
-void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
+static inline void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
 {
 	void *ptr;
 	int ret;
diff --git a/tools/testing/selftests/mm/pkey-x86.h b/tools/testing/selftests/mm/pkey-x86.h
index ac91777c8917..f7ecd335df1e 100644
--- a/tools/testing/selftests/mm/pkey-x86.h
+++ b/tools/testing/selftests/mm/pkey-x86.h
@@ -113,7 +113,7 @@ static inline u32 pkey_bit_position(int pkey)
 #define XSTATE_PKEY	0x200
 #define XSTATE_BV_OFFSET	512
 
-int pkey_reg_xstate_offset(void)
+static inline int pkey_reg_xstate_offset(void)
 {
 	unsigned int eax;
 	unsigned int ebx;
@@ -148,7 +148,7 @@ static inline int get_arch_reserved_keys(void)
 	return NR_RESERVED_PKEYS;
 }
 
-void expect_fault_on_read_execonly_key(void *p1, int pkey)
+static inline void expect_fault_on_read_execonly_key(void *p1, int pkey)
 {
 	int ptr_contents;
 
@@ -157,7 +157,7 @@ void expect_fault_on_read_execonly_key(void *p1, int pkey)
 	expected_pkey_fault(pkey);
 }
 
-void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
+static inline void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
 {
 	return PTR_ERR_ENOTSUP;
 }
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index fcbebc4490b4..82ece325b70c 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -54,6 +54,13 @@ int test_nr;
 u64 shadow_pkey_reg;
 int dprint_in_signal;
 
+noinline int read_ptr(int *ptr)
+{
+	/* Keep GCC from optimizing this away somehow */
+	barrier();
+	return *ptr;
+}
+
 void cat_into_file(char *str, char *file)
 {
 	int fd = open(file, O_RDWR);
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:14 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:14 +0000
Subject: [PATCH 09/14] selftests/mm: Remove empty pkey helper definition
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-10-kevin.brodsky@arm.com>

Some of the functions declared in pkey-helpers.h are actually
defined in protections_keys.c, meaning they can only be called from
protections_keys.c. This is less than ideal, but it is hard to avoid
as these helpers are themselves called from inline functions in
pkey-<arch>.h. Let's at least add a comment clarifying that. We can
also remove the empty definition in pkey_sighandler_tests.c:
expected_pkey_fault() is not meant to be called from there.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/pkey-helpers.h          | 6 ++++--
 tools/testing/selftests/mm/pkey_sighandler_tests.c | 2 --
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index bc81275a89d9..7604cc66ef0e 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -84,10 +84,12 @@ extern void abort_hooks(void);
 # define noinline __attribute__((noinline))
 #endif
 
-noinline int read_ptr(int *ptr);
-void expected_pkey_fault(int pkey);
 int sys_pkey_alloc(unsigned long flags, unsigned long init_val);
 int sys_pkey_free(unsigned long pkey);
+
+/* For functions called from protection_keys.c only */
+noinline int read_ptr(int *ptr);
+void expected_pkey_fault(int pkey);
 int mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
 		unsigned long pkey);
 void record_pkey_malloc(void *ptr, long size, int prot);
diff --git a/tools/testing/selftests/mm/pkey_sighandler_tests.c b/tools/testing/selftests/mm/pkey_sighandler_tests.c
index e7b91794f184..d18e38b19792 100644
--- a/tools/testing/selftests/mm/pkey_sighandler_tests.c
+++ b/tools/testing/selftests/mm/pkey_sighandler_tests.c
@@ -32,8 +32,6 @@
 
 #define STACK_SIZE PTHREAD_STACK_MIN
 
-void expected_pkey_fault(int pkey) {}
-
 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
 siginfo_t siginfo = {0};
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:15 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:15 +0000
Subject: [PATCH 10/14] selftests/mm: Ensure non-global pkey symbols are marked static
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-11-kevin.brodsky@arm.com>

The pkey tests define a whole lot of functions and some global
variables. A few are truly global (declared in pkey-helpers.h), but
the majority are file-scoped. Make sure those are labelled static.

Some of the pkey_{access,write}_{allow,deny} helpers are not called,
or only called when building for some architectures. Mark them
__maybe_unused to suppress compiler warnings.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/pkey-helpers.h     |   3 +
 .../selftests/mm/pkey_sighandler_tests.c      |   6 +-
 tools/testing/selftests/mm/protection_keys.c  | 132 +++++++++---------
 3 files changed, 72 insertions(+), 69 deletions(-)

diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index 7604cc66ef0e..6f0ab7b42738 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -83,6 +83,9 @@ extern void abort_hooks(void);
 #ifndef noinline
 # define noinline __attribute__((noinline))
 #endif
+#ifndef __maybe_unused
+# define __maybe_unused __attribute__((__unused__))
+#endif
 
 int sys_pkey_alloc(unsigned long flags, unsigned long init_val);
 int sys_pkey_free(unsigned long pkey);
diff --git a/tools/testing/selftests/mm/pkey_sighandler_tests.c b/tools/testing/selftests/mm/pkey_sighandler_tests.c
index d18e38b19792..e1aaeb65cfae 100644
--- a/tools/testing/selftests/mm/pkey_sighandler_tests.c
+++ b/tools/testing/selftests/mm/pkey_sighandler_tests.c
@@ -32,9 +32,9 @@
 
 #define STACK_SIZE PTHREAD_STACK_MIN
 
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-siginfo_t siginfo = {0};
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static siginfo_t siginfo = {0};
 
 /*
  * We need to use inline assembly instead of glibc's syscall because glibc's
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index 82ece325b70c..f43cf3b75d8e 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -61,7 +61,7 @@ noinline int read_ptr(int *ptr)
 	return *ptr;
 }
 
-void cat_into_file(char *str, char *file)
+static void cat_into_file(char *str, char *file)
 {
 	int fd = open(file, O_RDWR);
 	int ret;
@@ -88,7 +88,7 @@ void cat_into_file(char *str, char *file)
 
 #if CONTROL_TRACING > 0
 static int warned_tracing;
-int tracing_root_ok(void)
+static int tracing_root_ok(void)
 {
 	if (geteuid() != 0) {
 		if (!warned_tracing)
@@ -101,7 +101,7 @@ int tracing_root_ok(void)
 }
 #endif
 
-void tracing_on(void)
+static void tracing_on(void)
 {
 #if CONTROL_TRACING > 0
 #define TRACEDIR "/sys/kernel/tracing"
@@ -125,7 +125,7 @@ void tracing_on(void)
 #endif
 }
 
-void tracing_off(void)
+static void tracing_off(void)
 {
 #if CONTROL_TRACING > 0
 	if (!tracing_root_ok())
@@ -159,7 +159,7 @@ __attribute__((__aligned__(65536)))
 #else
 __attribute__((__aligned__(PAGE_SIZE)))
 #endif
-void lots_o_noops_around_write(int *write_to_me)
+static void lots_o_noops_around_write(int *write_to_me)
 {
 	dprintf3("running %s()\n", __func__);
 	__page_o_noops();
@@ -170,7 +170,7 @@ void lots_o_noops_around_write(int *write_to_me)
 	dprintf3("%s() done\n", __func__);
 }
 
-void dump_mem(void *dumpme, int len_bytes)
+static void dump_mem(void *dumpme, int len_bytes)
 {
 	char *c = (void *)dumpme;
 	int i;
@@ -213,7 +213,7 @@ static int hw_pkey_set(int pkey, unsigned long rights, unsigned long flags)
 	return 0;
 }
 
-void pkey_disable_set(int pkey, int flags)
+static void pkey_disable_set(int pkey, int flags)
 {
 	unsigned long syscall_flags = 0;
 	int ret;
@@ -251,7 +251,7 @@ void pkey_disable_set(int pkey, int flags)
 		pkey, flags);
 }
 
-void pkey_disable_clear(int pkey, int flags)
+static void pkey_disable_clear(int pkey, int flags)
 {
 	unsigned long syscall_flags = 0;
 	int ret;
@@ -277,19 +277,19 @@ void pkey_disable_clear(int pkey, int flags)
 			pkey, read_pkey_reg());
 }
 
-void pkey_write_allow(int pkey)
+__maybe_unused static void pkey_write_allow(int pkey)
 {
 	pkey_disable_clear(pkey, PKEY_DISABLE_WRITE);
 }
-void pkey_write_deny(int pkey)
+__maybe_unused static void pkey_write_deny(int pkey)
 {
 	pkey_disable_set(pkey, PKEY_DISABLE_WRITE);
 }
-void pkey_access_allow(int pkey)
+__maybe_unused static void pkey_access_allow(int pkey)
 {
 	pkey_disable_clear(pkey, PKEY_DISABLE_ACCESS);
 }
-void pkey_access_deny(int pkey)
+__maybe_unused static void pkey_access_deny(int pkey)
 {
 	pkey_disable_set(pkey, PKEY_DISABLE_ACCESS);
 }
@@ -307,9 +307,9 @@ static char *si_code_str(int si_code)
 	return "UNKNOWN";
 }
 
-int pkey_faults;
-int last_si_pkey = -1;
-void signal_handler(int signum, siginfo_t *si, void *vucontext)
+static int pkey_faults;
+static int last_si_pkey = -1;
+static void signal_handler(int signum, siginfo_t *si, void *vucontext)
 {
 	ucontext_t *uctxt = vucontext;
 	int trapno;
@@ -403,14 +403,14 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
 	dprint_in_signal = 0;
 }
 
-void sig_chld(int x)
+static void sig_chld(int x)
 {
 	dprint_in_signal = 1;
 	dprintf2("[%d] SIGCHLD: %d\n", getpid(), x);
 	dprint_in_signal = 0;
 }
 
-void setup_sigsegv_handler(void)
+static void setup_sigsegv_handler(void)
 {
 	int r, rs;
 	struct sigaction newact;
@@ -436,13 +436,13 @@ void setup_sigsegv_handler(void)
 	pkey_assert(r == 0);
 }
 
-void setup_handlers(void)
+static void setup_handlers(void)
 {
 	signal(SIGCHLD, &sig_chld);
 	setup_sigsegv_handler();
 }
 
-pid_t fork_lazy_child(void)
+static pid_t fork_lazy_child(void)
 {
 	pid_t forkret;
 
@@ -488,7 +488,7 @@ int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
 	return ret;
 }
 
-int alloc_pkey(void)
+static int alloc_pkey(void)
 {
 	int ret;
 	unsigned long init_val = 0x0;
@@ -546,7 +546,7 @@ int sys_pkey_free(unsigned long pkey)
  * not cleared.  This ensures we get lots of random bit sets
  * and clears on the vma and pte pkey bits.
  */
-int alloc_random_pkey(void)
+static int alloc_random_pkey(void)
 {
 	int max_nr_pkey_allocs;
 	int ret;
@@ -629,7 +629,7 @@ struct pkey_malloc_record {
 };
 struct pkey_malloc_record *pkey_malloc_records;
 struct pkey_malloc_record *pkey_last_malloc_record;
-long nr_pkey_malloc_records;
+static long nr_pkey_malloc_records;
 void record_pkey_malloc(void *ptr, long size, int prot)
 {
 	long i;
@@ -667,7 +667,7 @@ void record_pkey_malloc(void *ptr, long size, int prot)
 	nr_pkey_malloc_records++;
 }
 
-void free_pkey_malloc(void *ptr)
+static void free_pkey_malloc(void *ptr)
 {
 	long i;
 	int ret;
@@ -694,8 +694,7 @@ void free_pkey_malloc(void *ptr)
 	pkey_assert(false);
 }
 
-
-void *malloc_pkey_with_mprotect(long size, int prot, u16 pkey)
+static void *malloc_pkey_with_mprotect(long size, int prot, u16 pkey)
 {
 	void *ptr;
 	int ret;
@@ -715,7 +714,7 @@ void *malloc_pkey_with_mprotect(long size, int prot, u16 pkey)
 	return ptr;
 }
 
-void *malloc_pkey_anon_huge(long size, int prot, u16 pkey)
+static void *malloc_pkey_anon_huge(long size, int prot, u16 pkey)
 {
 	int ret;
 	void *ptr;
@@ -745,10 +744,10 @@ void *malloc_pkey_anon_huge(long size, int prot, u16 pkey)
 	return ptr;
 }
 
-int hugetlb_setup_ok;
+static int hugetlb_setup_ok;
 #define SYSFS_FMT_NR_HUGE_PAGES "/sys/kernel/mm/hugepages/hugepages-%ldkB/nr_hugepages"
 #define GET_NR_HUGE_PAGES 10
-void setup_hugetlbfs(void)
+static void setup_hugetlbfs(void)
 {
 	int err;
 	int fd;
@@ -796,7 +795,7 @@ void setup_hugetlbfs(void)
 	hugetlb_setup_ok = 1;
 }
 
-void *malloc_pkey_hugetlb(long size, int prot, u16 pkey)
+static void *malloc_pkey_hugetlb(long size, int prot, u16 pkey)
 {
 	void *ptr;
 	int flags = MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB;
@@ -817,7 +816,7 @@ void *malloc_pkey_hugetlb(long size, int prot, u16 pkey)
 	return ptr;
 }
 
-void *(*pkey_malloc[])(long size, int prot, u16 pkey) = {
+static void *(*pkey_malloc[])(long size, int prot, u16 pkey) = {
 
 	malloc_pkey_with_mprotect,
 	malloc_pkey_with_mprotect_subpage,
@@ -825,7 +824,7 @@ void *(*pkey_malloc[])(long size, int prot, u16 pkey) = {
 	malloc_pkey_hugetlb
 };
 
-void *malloc_pkey(long size, int prot, u16 pkey)
+static void *malloc_pkey(long size, int prot, u16 pkey)
 {
 	void *ret;
 	static int malloc_type;
@@ -855,7 +854,7 @@ void *malloc_pkey(long size, int prot, u16 pkey)
 	return ret;
 }
 
-int last_pkey_faults;
+static int last_pkey_faults;
 #define UNKNOWN_PKEY -2
 void expected_pkey_fault(int pkey)
 {
@@ -897,9 +896,9 @@ void expected_pkey_fault(int pkey)
 	pkey_assert(last_pkey_faults == pkey_faults);		\
 } while (0)
 
-int test_fds[10] = { -1 };
-int nr_test_fds;
-void __save_test_fd(int fd)
+static int test_fds[10] = { -1 };
+static int nr_test_fds;
+static void __save_test_fd(int fd)
 {
 	pkey_assert(fd >= 0);
 	pkey_assert(nr_test_fds < ARRAY_SIZE(test_fds));
@@ -907,14 +906,14 @@ void __save_test_fd(int fd)
 	nr_test_fds++;
 }
 
-int get_test_read_fd(void)
+static int get_test_read_fd(void)
 {
 	int test_fd = open("/etc/passwd", O_RDONLY);
 	__save_test_fd(test_fd);
 	return test_fd;
 }
 
-void close_test_fds(void)
+static void close_test_fds(void)
 {
 	int i;
 
@@ -927,7 +926,7 @@ void close_test_fds(void)
 	nr_test_fds = 0;
 }
 
-void test_pkey_alloc_free_attach_pkey0(int *ptr, u16 pkey)
+static void test_pkey_alloc_free_attach_pkey0(int *ptr, u16 pkey)
 {
 	int i, err;
 	int max_nr_pkey_allocs;
@@ -979,7 +978,7 @@ void test_pkey_alloc_free_attach_pkey0(int *ptr, u16 pkey)
 	pkey_assert(!err);
 }
 
-void test_read_of_write_disabled_region(int *ptr, u16 pkey)
+static void test_read_of_write_disabled_region(int *ptr, u16 pkey)
 {
 	int ptr_contents;
 
@@ -989,7 +988,7 @@ void test_read_of_write_disabled_region(int *ptr, u16 pkey)
 	dprintf1("*ptr: %d\n", ptr_contents);
 	dprintf1("\n");
 }
-void test_read_of_access_disabled_region(int *ptr, u16 pkey)
+static void test_read_of_access_disabled_region(int *ptr, u16 pkey)
 {
 	int ptr_contents;
 
@@ -1001,7 +1000,7 @@ void test_read_of_access_disabled_region(int *ptr, u16 pkey)
 	expected_pkey_fault(pkey);
 }
 
-void test_read_of_access_disabled_region_with_page_already_mapped(int *ptr,
+static void test_read_of_access_disabled_region_with_page_already_mapped(int *ptr,
 		u16 pkey)
 {
 	int ptr_contents;
@@ -1018,7 +1017,7 @@ void test_read_of_access_disabled_region_with_page_already_mapped(int *ptr,
 	expected_pkey_fault(pkey);
 }
 
-void test_write_of_write_disabled_region_with_page_already_mapped(int *ptr,
+static void test_write_of_write_disabled_region_with_page_already_mapped(int *ptr,
 		u16 pkey)
 {
 	*ptr = __LINE__;
@@ -1029,14 +1028,14 @@ void test_write_of_write_disabled_region_with_page_already_mapped(int *ptr,
 	expected_pkey_fault(pkey);
 }
 
-void test_write_of_write_disabled_region(int *ptr, u16 pkey)
+static void test_write_of_write_disabled_region(int *ptr, u16 pkey)
 {
 	dprintf1("disabling write access to PKEY[%02d], doing write\n", pkey);
 	pkey_write_deny(pkey);
 	*ptr = __LINE__;
 	expected_pkey_fault(pkey);
 }
-void test_write_of_access_disabled_region(int *ptr, u16 pkey)
+static void test_write_of_access_disabled_region(int *ptr, u16 pkey)
 {
 	dprintf1("disabling access to PKEY[%02d], doing write\n", pkey);
 	pkey_access_deny(pkey);
@@ -1044,7 +1043,7 @@ void test_write_of_access_disabled_region(int *ptr, u16 pkey)
 	expected_pkey_fault(pkey);
 }
 
-void test_write_of_access_disabled_region_with_page_already_mapped(int *ptr,
+static void test_write_of_access_disabled_region_with_page_already_mapped(int *ptr,
 			u16 pkey)
 {
 	*ptr = __LINE__;
@@ -1055,7 +1054,7 @@ void test_write_of_access_disabled_region_with_page_already_mapped(int *ptr,
 	expected_pkey_fault(pkey);
 }
 
-void test_kernel_write_of_access_disabled_region(int *ptr, u16 pkey)
+static void test_kernel_write_of_access_disabled_region(int *ptr, u16 pkey)
 {
 	int ret;
 	int test_fd = get_test_read_fd();
@@ -1067,7 +1066,8 @@ void test_kernel_write_of_access_disabled_region(int *ptr, u16 pkey)
 	dprintf1("read ret: %d\n", ret);
 	pkey_assert(ret);
 }
-void test_kernel_write_of_write_disabled_region(int *ptr, u16 pkey)
+
+static void test_kernel_write_of_write_disabled_region(int *ptr, u16 pkey)
 {
 	int ret;
 	int test_fd = get_test_read_fd();
@@ -1080,7 +1080,7 @@ void test_kernel_write_of_write_disabled_region(int *ptr, u16 pkey)
 	pkey_assert(ret);
 }
 
-void test_kernel_gup_of_access_disabled_region(int *ptr, u16 pkey)
+static void test_kernel_gup_of_access_disabled_region(int *ptr, u16 pkey)
 {
 	int pipe_ret, vmsplice_ret;
 	struct iovec iov;
@@ -1102,7 +1102,7 @@ void test_kernel_gup_of_access_disabled_region(int *ptr, u16 pkey)
 	close(pipe_fds[1]);
 }
 
-void test_kernel_gup_write_to_write_disabled_region(int *ptr, u16 pkey)
+static void test_kernel_gup_write_to_write_disabled_region(int *ptr, u16 pkey)
 {
 	int ignored = 0xdada;
 	int futex_ret;
@@ -1120,7 +1120,7 @@ void test_kernel_gup_write_to_write_disabled_region(int *ptr, u16 pkey)
 }
 
 /* Assumes that all pkeys other than 'pkey' are unallocated */
-void test_pkey_syscalls_on_non_allocated_pkey(int *ptr, u16 pkey)
+static void test_pkey_syscalls_on_non_allocated_pkey(int *ptr, u16 pkey)
 {
 	int err;
 	int i;
@@ -1143,7 +1143,7 @@ void test_pkey_syscalls_on_non_allocated_pkey(int *ptr, u16 pkey)
 }
 
 /* Assumes that all pkeys other than 'pkey' are unallocated */
-void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
+static void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
 {
 	int err;
 	int bad_pkey = NR_PKEYS+99;
@@ -1153,7 +1153,7 @@ void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
 	pkey_assert(err);
 }
 
-void become_child(void)
+static void become_child(void)
 {
 	pid_t forkret;
 
@@ -1169,7 +1169,7 @@ void become_child(void)
 }
 
 /* Assumes that all pkeys other than 'pkey' are unallocated */
-void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
+static void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
 {
 	int err;
 	int allocated_pkeys[NR_PKEYS] = {0};
@@ -1236,7 +1236,7 @@ void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
 	}
 }
 
-void arch_force_pkey_reg_init(void)
+static void arch_force_pkey_reg_init(void)
 {
 #if defined(__i386__) || defined(__x86_64__) /* arch */
 	u64 *buf;
@@ -1275,7 +1275,7 @@ void arch_force_pkey_reg_init(void)
  * a long-running test that continually checks the pkey
  * register.
  */
-void test_pkey_init_state(int *ptr, u16 pkey)
+static void test_pkey_init_state(int *ptr, u16 pkey)
 {
 	int err;
 	int allocated_pkeys[NR_PKEYS] = {0};
@@ -1313,7 +1313,7 @@ void test_pkey_init_state(int *ptr, u16 pkey)
  * have to call pkey_alloc() to use it first.  Make sure that it
  * is usable.
  */
-void test_mprotect_with_pkey_0(int *ptr, u16 pkey)
+static void test_mprotect_with_pkey_0(int *ptr, u16 pkey)
 {
 	long size;
 	int prot;
@@ -1337,7 +1337,7 @@ void test_mprotect_with_pkey_0(int *ptr, u16 pkey)
 	mprotect_pkey(ptr, size, prot, pkey);
 }
 
-void test_ptrace_of_child(int *ptr, u16 pkey)
+static void test_ptrace_of_child(int *ptr, u16 pkey)
 {
 	__attribute__((__unused__)) int peek_result;
 	pid_t child_pid;
@@ -1413,7 +1413,7 @@ void test_ptrace_of_child(int *ptr, u16 pkey)
 	free(plain_ptr_unaligned);
 }
 
-void *get_pointer_to_instructions(void)
+static void *get_pointer_to_instructions(void)
 {
 	void *p1;
 
@@ -1434,7 +1434,7 @@ void *get_pointer_to_instructions(void)
 	return p1;
 }
 
-void test_executing_on_unreadable_memory(int *ptr, u16 pkey)
+static void test_executing_on_unreadable_memory(int *ptr, u16 pkey)
 {
 	void *p1;
 	int scratch;
@@ -1466,7 +1466,7 @@ void test_executing_on_unreadable_memory(int *ptr, u16 pkey)
 	pkey_assert(!ret);
 }
 
-void test_implicit_mprotect_exec_only_memory(int *ptr, u16 pkey)
+static void test_implicit_mprotect_exec_only_memory(int *ptr, u16 pkey)
 {
 	void *p1;
 	int scratch;
@@ -1515,7 +1515,7 @@ void test_implicit_mprotect_exec_only_memory(int *ptr, u16 pkey)
 }
 
 #if defined(__i386__) || defined(__x86_64__)
-void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
+static void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
 {
 	u32 new_pkru;
 	pid_t child;
@@ -1638,7 +1638,7 @@ void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
 #endif
 
 #if defined(__aarch64__)
-void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
+static void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
 {
 	pid_t child;
 	int status, ret;
@@ -1715,7 +1715,7 @@ void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
 }
 #endif
 
-void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey)
+static void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey)
 {
 	int size = PAGE_SIZE;
 	int sret;
@@ -1729,7 +1729,7 @@ void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey)
 	pkey_assert(sret < 0);
 }
 
-void (*pkey_tests[])(int *ptr, u16 pkey) = {
+static void (*pkey_tests[])(int *ptr, u16 pkey) = {
 	test_read_of_write_disabled_region,
 	test_read_of_access_disabled_region,
 	test_read_of_access_disabled_region_with_page_already_mapped,
@@ -1755,7 +1755,7 @@ void (*pkey_tests[])(int *ptr, u16 pkey) = {
 #endif
 };
 
-void run_tests_once(void)
+static void run_tests_once(void)
 {
 	int *ptr;
 	int prot = PROT_READ|PROT_WRITE;
@@ -1789,7 +1789,7 @@ void run_tests_once(void)
 	iteration_nr++;
 }
 
-void pkey_setup_shadow(void)
+static void pkey_setup_shadow(void)
 {
 	shadow_pkey_reg = __read_pkey_reg();
 }
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:16 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:16 +0000
Subject: [PATCH 11/14] selftests/mm: Use sys_pkey helpers consistently
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-12-kevin.brodsky@arm.com>

sys_pkey_alloc, sys_pkey_free and sys_mprotect_pkey are currently
used in protections_keys.c, while pkey_sighandler_tests.c calls the
libc wrappers directly (e.g. pkey_mprotect()). This is probably ok
when using glibc (those symbols appeared a while ago), but Musl does
not currently provide them. The logging in the helpers from
pkey-helpers.h can also come in handy.

Make things more consistent by using the sys_pkey helpers in
pkey_sighandler_tests.c too. To that end their implementation is
moved to a common .c file (pkey_util.c). This also enables calling
is_pkeys_supported() outside of protections_keys.c, since it relies
on sys_pkey_{alloc,free}.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/Makefile           |  4 +-
 tools/testing/selftests/mm/pkey-helpers.h     |  2 +
 .../selftests/mm/pkey_sighandler_tests.c      |  8 ++--
 tools/testing/selftests/mm/pkey_util.c        | 40 +++++++++++++++++++
 tools/testing/selftests/mm/protection_keys.c  | 35 ----------------
 5 files changed, 48 insertions(+), 41 deletions(-)
 create mode 100644 tools/testing/selftests/mm/pkey_util.c

diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index 814b17a43385..1f0743d9459d 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -147,8 +147,8 @@ TEST_FILES += write_hugetlb_memory.sh
 
 include ../lib.mk
 
-$(TEST_GEN_PROGS): vm_util.c thp_settings.c
-$(TEST_GEN_FILES): vm_util.c thp_settings.c
+$(TEST_GEN_PROGS): vm_util.c thp_settings.c pkey_util.c
+$(TEST_GEN_FILES): vm_util.c thp_settings.c pkey_util.c
 
 $(OUTPUT)/uffd-stress: uffd-common.c
 $(OUTPUT)/uffd-unit-tests: uffd-common.c
diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index 6f0ab7b42738..f080e97b39be 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -89,6 +89,8 @@ extern void abort_hooks(void);
 
 int sys_pkey_alloc(unsigned long flags, unsigned long init_val);
 int sys_pkey_free(unsigned long pkey);
+int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
+		unsigned long pkey);
 
 /* For functions called from protection_keys.c only */
 noinline int read_ptr(int *ptr);
diff --git a/tools/testing/selftests/mm/pkey_sighandler_tests.c b/tools/testing/selftests/mm/pkey_sighandler_tests.c
index e1aaeb65cfae..c73cee192b88 100644
--- a/tools/testing/selftests/mm/pkey_sighandler_tests.c
+++ b/tools/testing/selftests/mm/pkey_sighandler_tests.c
@@ -311,8 +311,8 @@ static void test_sigsegv_handler_with_different_pkey_for_stack(void)
 	__write_pkey_reg(pkey_reg);
 
 	/* Protect the new stack with MPK 1 */
-	pkey = pkey_alloc(0, 0);
-	pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
+	pkey = sys_pkey_alloc(0, 0);
+	sys_mprotect_pkey(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
 
 	/* Set up alternate signal stack that will use the default MPK */
 	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
@@ -484,8 +484,8 @@ static void test_pkru_sigreturn(void)
 	__write_pkey_reg(pkey_reg);
 
 	/* Protect the stack with MPK 2 */
-	pkey = pkey_alloc(0, 0);
-	pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
+	pkey = sys_pkey_alloc(0, 0);
+	sys_mprotect_pkey(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
 
 	/* Set up alternate signal stack that will use the default MPK */
 	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
diff --git a/tools/testing/selftests/mm/pkey_util.c b/tools/testing/selftests/mm/pkey_util.c
new file mode 100644
index 000000000000..ca4ad0d44ab2
--- /dev/null
+++ b/tools/testing/selftests/mm/pkey_util.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#include "pkey-helpers.h"
+
+int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
+{
+	int ret = syscall(SYS_pkey_alloc, flags, init_val);
+	dprintf1("%s(flags=%lx, init_val=%lx) syscall ret: %d errno: %d\n",
+			__func__, flags, init_val, ret, errno);
+	return ret;
+}
+
+int sys_pkey_free(unsigned long pkey)
+{
+	int ret = syscall(SYS_pkey_free, pkey);
+	dprintf1("%s(pkey=%ld) syscall ret: %d\n", __func__, pkey, ret);
+	return ret;
+}
+
+int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
+		unsigned long pkey)
+{
+	int sret;
+
+	dprintf2("%s(0x%p, %zx, prot=%lx, pkey=%lx)\n", __func__,
+			ptr, size, orig_prot, pkey);
+
+	errno = 0;
+	sret = syscall(__NR_pkey_mprotect, ptr, size, orig_prot, pkey);
+	if (errno) {
+		dprintf2("SYS_mprotect_key sret: %d\n", sret);
+		dprintf2("SYS_mprotect_key prot: 0x%lx\n", orig_prot);
+		dprintf2("SYS_mprotect_key failed, errno: %d\n", errno);
+		if (DEBUG_LEVEL >= 2)
+			perror("SYS_mprotect_pkey");
+	}
+	return sret;
+}
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index f43cf3b75d8e..3688571e6b39 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -460,34 +460,6 @@ static pid_t fork_lazy_child(void)
 	return forkret;
 }
 
-int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
-		unsigned long pkey)
-{
-	int sret;
-
-	dprintf2("%s(0x%p, %zx, prot=%lx, pkey=%lx)\n", __func__,
-			ptr, size, orig_prot, pkey);
-
-	errno = 0;
-	sret = syscall(__NR_pkey_mprotect, ptr, size, orig_prot, pkey);
-	if (errno) {
-		dprintf2("SYS_mprotect_key sret: %d\n", sret);
-		dprintf2("SYS_mprotect_key prot: 0x%lx\n", orig_prot);
-		dprintf2("SYS_mprotect_key failed, errno: %d\n", errno);
-		if (DEBUG_LEVEL >= 2)
-			perror("SYS_mprotect_pkey");
-	}
-	return sret;
-}
-
-int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
-{
-	int ret = syscall(SYS_pkey_alloc, flags, init_val);
-	dprintf1("%s(flags=%lx, init_val=%lx) syscall ret: %d errno: %d\n",
-			__func__, flags, init_val, ret, errno);
-	return ret;
-}
-
 static int alloc_pkey(void)
 {
 	int ret;
@@ -534,13 +506,6 @@ static int alloc_pkey(void)
 	return ret;
 }
 
-int sys_pkey_free(unsigned long pkey)
-{
-	int ret = syscall(SYS_pkey_free, pkey);
-	dprintf1("%s(pkey=%ld) syscall ret: %d\n", __func__, pkey, ret);
-	return ret;
-}
-
 /*
  * I had a bug where pkey bits could be set by mprotect() but
  * not cleared.  This ensures we get lots of random bit sets
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:17 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:17 +0000
Subject: [PATCH 12/14] selftests/mm: Rename pkey register macro
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-13-kevin.brodsky@arm.com>

PKEY_ALLOW_ALL is meant to represent the pkey register value that
allows all accesses (enables all pkeys). However its current naming
suggests that the value applies to *one* key only (like
PKEY_DISABLE_ACCESS for instance).

Rename PKEY_ALLOW_ALL to PKEY_REG_ALLOW_ALL to avoid such
misunderstanding. This is consistent with the PKEY_REG_ALLOW_NONE
macro introduced by commit 6e182dc9f268 ("selftests/mm: Use generic
pkey register manipulation").

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/pkey-arm64.h      | 2 +-
 tools/testing/selftests/mm/protection_keys.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/mm/pkey-arm64.h b/tools/testing/selftests/mm/pkey-arm64.h
index 9897e31f16dd..8e9685e03c44 100644
--- a/tools/testing/selftests/mm/pkey-arm64.h
+++ b/tools/testing/selftests/mm/pkey-arm64.h
@@ -30,7 +30,7 @@
 #define NR_PKEYS		8
 #define NR_RESERVED_PKEYS	1 /* pkey-0 */
 
-#define PKEY_ALLOW_ALL		0x77777777
+#define PKEY_REG_ALLOW_ALL	0x77777777
 #define PKEY_REG_ALLOW_NONE	0x0
 
 #define PKEY_BITS_PER_PKEY	4
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index 3688571e6b39..a4683f2476f2 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -396,7 +396,7 @@ static void signal_handler(int signum, siginfo_t *si, void *vucontext)
 	/* restore access and let the faulting instruction continue */
 	pkey_access_allow(siginfo_pkey);
 #elif defined(__aarch64__)
-	aarch64_write_signal_pkey(uctxt, PKEY_ALLOW_ALL);
+	aarch64_write_signal_pkey(uctxt, PKEY_REG_ALLOW_ALL);
 #endif /* arch */
 	pkey_faults++;
 	dprintf1("<<<<==================================================\n");
@@ -842,7 +842,7 @@ void expected_pkey_fault(int pkey)
 	 */
 	if (__read_pkey_reg() != 0)
 #elif defined(__aarch64__)
-	if (__read_pkey_reg() != PKEY_ALLOW_ALL)
+	if (__read_pkey_reg() != PKEY_REG_ALLOW_ALL)
 #else
 	if (__read_pkey_reg() != shadow_pkey_reg)
 #endif /* arch */
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:18 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:18 +0000
Subject: [PATCH 13/14] selftests/mm: Skip pkey_sighandler_tests if support is missing
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-14-kevin.brodsky@arm.com>

The pkey_sighandler_tests are bound to fail if either the kernel or
CPU doesn't support pkeys. Skip the tests if pkeys support is
missing.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/pkey_sighandler_tests.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/testing/selftests/mm/pkey_sighandler_tests.c b/tools/testing/selftests/mm/pkey_sighandler_tests.c
index c73cee192b88..449ec5acec75 100644
--- a/tools/testing/selftests/mm/pkey_sighandler_tests.c
+++ b/tools/testing/selftests/mm/pkey_sighandler_tests.c
@@ -535,6 +535,9 @@ int main(int argc, char *argv[])
 	ksft_print_header();
 	ksft_set_plan(ARRAY_SIZE(pkey_tests));
 
+	if (!is_pkeys_supported())
+		ksft_exit_skip("pkeys not supported\n");
+
 	for (i = 0; i < ARRAY_SIZE(pkey_tests); i++)
 		(*pkey_tests[i])();
 
-- 
2.47.0



From kevin.brodsky at arm.com  Mon Dec  9 01:50:19 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon,  9 Dec 2024 09:50:19 +0000
Subject: [PATCH 14/14] selftests/mm: Remove X permission from sigaltstack mapping
In-Reply-To: <20241209095019.1732120-1-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
Message-ID: <20241209095019.1732120-15-kevin.brodsky@arm.com>

There is no reason why the alternate signal stack should be mapped
as RWX. Map it as RW instead.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 tools/testing/selftests/mm/pkey_sighandler_tests.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/mm/pkey_sighandler_tests.c b/tools/testing/selftests/mm/pkey_sighandler_tests.c
index 449ec5acec75..17bbfcd552c6 100644
--- a/tools/testing/selftests/mm/pkey_sighandler_tests.c
+++ b/tools/testing/selftests/mm/pkey_sighandler_tests.c
@@ -315,7 +315,7 @@ static void test_sigsegv_handler_with_different_pkey_for_stack(void)
 	sys_mprotect_pkey(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
 
 	/* Set up alternate signal stack that will use the default MPK */
-	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
+	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE,
 			      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 	sigstack.ss_flags = 0;
 	sigstack.ss_size = STACK_SIZE;
@@ -488,7 +488,7 @@ static void test_pkru_sigreturn(void)
 	sys_mprotect_pkey(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
 
 	/* Set up alternate signal stack that will use the default MPK */
-	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
+	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE,
 			      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 	sigstack.ss_flags = 0;
 	sigstack.ss_size = STACK_SIZE;
-- 
2.47.0



From matthias.schiffer at ew.tq-group.com  Mon Dec  9 01:51:31 2024
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Mon,  9 Dec 2024 10:51:31 +0100
Subject: [PATCH v2 0/5] TQ-Systems TQMa62xx SoM and MBa62xx board
Message-ID: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>

This adds Device Trees for out AM62x-based SoM TQMa62xx and its
reference carrier board MBa62xx.

Two of the patches are adapted from the TI vendor repo ti-linux-kernel to
add RemoteProc/RPMsg support for the R5F core. A similar patch has been
submitted for mainline by TI themselves for the closely related AM62A SoC.

Not yet included are overlays to enable LVDS display output and MIPI-CSI
camera input.

Changes in v2:
- Collected acks and reviews
- Rebased onto v6.13-rc1


Devarsh Thakkar (1):
  arm64: dts: ti: k3-am62: Add DM R5 ranges in cbass

Hari Nagalla (1):
  arm64: dts: ti: k3-am62-wakeup: Add R5F device node

Matthias Schiffer (3):
  dt-bindings: usb: dwc3: Allow connector in USB controller node
  dt-bindings: arm: ti: Add compatible for AM625-based TQMa62xx SOM
    family and carrier board
  arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and MBa62xx carrier board
    Device Trees

 .../devicetree/bindings/arm/ti/k3.yaml        |   7 +
 .../devicetree/bindings/usb/snps,dwc3.yaml    |   6 +
 arch/arm64/boot/dts/ti/Makefile               |   1 +
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi    |  24 +
 arch/arm64/boot/dts/ti/k3-am62.dtsi           |   8 +-
 .../boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts | 917 ++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi | 346 +++++++
 7 files changed, 1307 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts
 create mode 100644 arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi

-- 
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
https://www.tq-group.com/



From matthias.schiffer at ew.tq-group.com  Mon Dec  9 01:51:32 2024
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Mon,  9 Dec 2024 10:51:32 +0100
Subject: [PATCH v2 1/5] dt-bindings: usb: dwc3: Allow connector in USB controller node
In-Reply-To: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
Message-ID: <06497b8aadc0b5becced274d0a5fbcd808d87a48.1733737487.git.matthias.schiffer@ew.tq-group.com>

Allow specifying the connector directly in the USB controller node, as
supported by other USB controller bindings.

Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
index 1cd0ca90127d9..2976fb1a58061 100644
--- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
@@ -68,6 +68,12 @@ properties:
         - enum: [bus_early, ref, suspend]
         - true
 
+  connector:
+    $ref: /schemas/connector/usb-connector.yaml#
+    description: Connector for dual role switch
+    type: object
+    unevaluatedProperties: false
+
   dma-coherent: true
 
   extcon:
-- 
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
https://www.tq-group.com/



From matthias.schiffer at ew.tq-group.com  Mon Dec  9 01:51:33 2024
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Mon,  9 Dec 2024 10:51:33 +0100
Subject: [PATCH v2 2/5] dt-bindings: arm: ti: Add compatible for AM625-based TQMa62xx SOM family and carrier board
In-Reply-To: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
Message-ID: <6052e70b8e744bd3a608728f876c97d3172bf975.1733737487.git.matthias.schiffer@ew.tq-group.com>

The TQMa62xx is a SoM family with a pluggable connector. The MBa62xx is
the matching reference/starterkit carrier board.

Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.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 18f155cd06c84..07d98a67d967f 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -75,6 +75,13 @@ properties:
           - const: toradex,verdin-am62          # Verdin AM62 Module
           - const: ti,am625
 
+      - description: K3 AM625 SoC on TQ-Systems TQMa62xx SoM
+        items:
+          - enum:
+              - tq,am625-tqma6254-mba62xx # MBa62xx base board
+          - const: tq,am625-tqma6254
+          - const: ti,am625
+
       - description: K3 AM642 SoC
         items:
           - enum:
-- 
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
https://www.tq-group.com/



From matthias.schiffer at ew.tq-group.com  Mon Dec  9 01:51:34 2024
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Mon,  9 Dec 2024 10:51:34 +0100
Subject: [PATCH v2 3/5] arm64: dts: ti: k3-am62: Add DM R5 ranges in cbass
In-Reply-To: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
Message-ID: <641475ca5720fcd24bcb41af36b69781a0a86df4.1733737487.git.matthias.schiffer@ew.tq-group.com>

From: Devarsh Thakkar <devarsht at ti.com>

Add DM R5F ATCM and BTCM ranges in cbass_wakeup and cbass_main.

Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
Signed-off-by: Dhruva Gole <d-gole at ti.com>
Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com>
---
 arch/arm64/boot/dts/ti/k3-am62.dtsi | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62.dtsi b/arch/arm64/boot/dts/ti/k3-am62.dtsi
index bfb55ca113239..f01a594ba7f89 100644
--- a/arch/arm64/boot/dts/ti/k3-am62.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62.dtsi
@@ -86,7 +86,9 @@ cbass_main: bus at f0000 {
 			 /* Wakeup Domain Range */
 			 <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00002400>, /* VTM */
 			 <0x00 0x2b000000 0x00 0x2b000000 0x00 0x00300400>,
-			 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>;
+			 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>,
+			 <0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>, /* DM R5 ATCM */
+			 <0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>; /* DM R5 BTCM */
 
 		cbass_mcu: bus at 4000000 {
 			bootph-all;
@@ -103,7 +105,9 @@ cbass_wakeup: bus at b00000 {
 			#size-cells = <2>;
 			ranges = <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00002400>, /* VTM */
 				 <0x00 0x2b000000 0x00 0x2b000000 0x00 0x00300400>, /* Peripheral Window */
-				 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>;
+				 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>,
+				 <0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>, /* DM R5 ATCM */
+				 <0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>; /* DM R5 BTCM */
 		};
 	};
 
-- 
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
https://www.tq-group.com/



From matthias.schiffer at ew.tq-group.com  Mon Dec  9 01:51:35 2024
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Mon,  9 Dec 2024 10:51:35 +0100
Subject: [PATCH v2 4/5] arm64: dts: ti: k3-am62-wakeup: Add R5F device node
In-Reply-To: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
Message-ID: <87517cce567e1dda89c38f82db93ddff292c5c10.1733737487.git.matthias.schiffer@ew.tq-group.com>

From: Hari Nagalla <hnagalla at ti.com>

AM62 SoCs have a single core R5F core in wakeup domain. This core is also
used as a device manager for the SoC.

Co-authored-by: Devarsh Thakkar <devarsht at ti.com>
Signed-off-by: Hari Nagalla <hnagalla at ti.com>
[Matthias Schiffer: Updated to match latest submitted version v5 of "arm64:
dts: k3-am62a-wakeup: Add R5F device node"]
Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com>
---
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
index 9b8a1f85aa15c..619848e889cf9 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -106,6 +106,30 @@ wkup_rti0: watchdog at 2b000000 {
 		status = "reserved";
 	};
 
+	wkup_r5fss0: r5fss at 78000000 {
+		compatible = "ti,am62-r5fss";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x78000000 0x00 0x78000000 0x8000>,
+			 <0x78100000 0x00 0x78100000 0x8000>;
+		power-domains = <&k3_pds 119 TI_SCI_PD_EXCLUSIVE>;
+
+		wkup_r5fss0_core0: r5f at 78000000 {
+			compatible = "ti,am62-r5f";
+			reg = <0x78000000 0x00008000>,
+			      <0x78100000 0x00008000>;
+			reg-names = "atcm", "btcm";
+			resets = <&k3_reset 121 1>;
+			firmware-name = "am62-wkup-r5f0_0-fw";
+			ti,sci = <&dmsc>;
+			ti,sci-dev-id = <121>;
+			ti,sci-proc-ids = <0x01 0xff>;
+			ti,atcm-enable = <1>;
+			ti,btcm-enable = <1>;
+			ti,loczrama = <1>;
+		};
+	};
+
 	wkup_vtm0: temperature-sensor at b00000 {
 		compatible = "ti,j7200-vtm";
 		reg = <0x00 0xb00000 0x00 0x400>,
-- 
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
https://www.tq-group.com/



From lukma at denx.de  Mon Dec  9 01:52:40 2024
From: lukma at denx.de (Lukasz Majewski)
Date: Mon, 9 Dec 2024 10:52:40 +0100
Subject: [PATCH v11 1/3] dt-bindings: display: Add
 powertip,{st7272|hx8238a} as DT Schema description
In-Reply-To: <20241107085705.490940-1-lukma@denx.de>
References: <20241107085705.490940-1-lukma@denx.de>
Message-ID: <20241209105240.72d8d84a@wsk>

Dear Community,

> This patch provides the DT Schema description of:
> - powertip,st7272  320 x 240 LCD display
> - powertip,hx8238a 320 x 240 LCD display
> 
> Used with the different HW revisions of btt3 devices.
> 
> Signed-off-by: Lukasz Majewski <lukma at denx.de>
> Reviewed-by: Rob Herring <robh at kernel.org>

Are there any more comments for this particular patch?

If not - can it be applied as it prevents dts patchs to be pull by
Shawn.

> ---
> 
> Changes for v9:
> - New patch
> 
> Changes for v10:
> - None
> 
> Changes for v11:
> - Combine both separate dt-bindings patches for powertip,st7272 and
>   powertip,hx8238a into one
> - Drop the quotes for in "title" entry of powertip*.yaml files
> ---
>  .../display/panel/powertip,hx8238a.yaml       | 29
> +++++++++++++++++++ .../display/panel/powertip,st7272.yaml        |
> 29 +++++++++++++++++++ 2 files changed, 58 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/display/panel/powertip,hx8238a.yaml
> create mode 100644
> Documentation/devicetree/bindings/display/panel/powertip,st7272.yaml
> 
> diff --git
> a/Documentation/devicetree/bindings/display/panel/powertip,hx8238a.yaml
> b/Documentation/devicetree/bindings/display/panel/powertip,hx8238a.yaml
> new file mode 100644 index 000000000000..b7d74faeb5d5 --- /dev/null
> +++
> b/Documentation/devicetree/bindings/display/panel/powertip,hx8238a.yaml
> @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-only OR
> BSD-2-Clause +%YAML 1.2
> +---
> +$id:
> http://devicetree.org/schemas/display/panel/powertip,hx8238a.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml# +
> +title: Powertip Electronic Technology Co. 320 x 240 LCD panel
> +
> +maintainers:
> +  - Lukasz Majewski <lukma at denx.de>
> +
> +allOf:
> +  - $ref: panel-dpi.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: powertip,hx8238a
> +      - {} # panel-dpi, but not listed here to avoid false select
> +
> +  height-mm: true
> +  panel-timing: true
> +  port: true
> +  power-supply: true
> +  width-mm: true
> +
> +additionalProperties: false
> +
> +...
> diff --git
> a/Documentation/devicetree/bindings/display/panel/powertip,st7272.yaml
> b/Documentation/devicetree/bindings/display/panel/powertip,st7272.yaml
> new file mode 100644 index 000000000000..f3622800f13f --- /dev/null
> +++
> b/Documentation/devicetree/bindings/display/panel/powertip,st7272.yaml
> @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-only OR
> BSD-2-Clause +%YAML 1.2
> +---
> +$id:
> http://devicetree.org/schemas/display/panel/powertip,st7272.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml# +
> +title: Powertip Electronic Technology Co. 320 x 240 LCD panel
> +
> +maintainers:
> +  - Lukasz Majewski <lukma at denx.de>
> +
> +allOf:
> +  - $ref: panel-dpi.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: powertip,st7272
> +      - {} # panel-dpi, but not listed here to avoid false select
> +
> +  height-mm: true
> +  panel-timing: true
> +  port: true
> +  power-supply: true
> +  width-mm: true
> +
> +additionalProperties: false
> +
> +...




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- 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/20241209/5157dd00/attachment.sig>

From matthias.schiffer at ew.tq-group.com  Mon Dec  9 01:51:36 2024
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Mon,  9 Dec 2024 10:51:36 +0100
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and MBa62xx carrier board Device Trees
In-Reply-To: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
Message-ID: <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>

The TQMa62xx is a SoM family with a pluggable board connector based on the
TI AM62x SoCs. Add DTS(I) for the AM625 (2x Cortex-A53) variant and its
combination with our MBa62xx carrier board.

Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com>
---
 arch/arm64/boot/dts/ti/Makefile               |   1 +
 .../boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts | 917 ++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi | 346 +++++++
 3 files changed, 1264 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts
 create mode 100644 arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index f71360f14f233..4d96c086e2daf 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -14,6 +14,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-beagleplay-csi2-ov5640.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am625-beagleplay-csi2-tevi-ov5640.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am625-phyboard-lyra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am625-tqma62xx-mba62xx.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-nonwifi-dahlia.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-nonwifi-dev.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-nonwifi-ivy.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts b/arch/arm64/boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts
new file mode 100644
index 0000000000000..64ae1b13be15b
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts
@@ -0,0 +1,917 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2021-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (c) 2023-2024 TQ-Systems GmbH <linux at ew.tq-group.com>, D-82229 Seefeld, Germany.
+ * Author: Matthias Schiffer
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "k3-am625-tqma62xx.dtsi"
+
+/ {
+	compatible = "tq,am625-tqma6254-mba62xx", "tq,am625-tqma6254",
+		     "ti,am625";
+	model = "TQ-Systems TQMa62xx SoM on MBa62xx carrier board";
+	chassis-type = "embedded";
+
+	aliases {
+		can0 = &mcu_mcan0;
+		can1 = &mcu_mcan1;
+		ethernet0 = &cpsw_port1;
+		ethernet1 = &cpsw_port2;
+		i2c1 = &main_i2c1;
+		mmc1 = &sdhci1;
+		mmc2 = &sdhci2;
+		serial0 = &main_uart0;
+		serial1 = &mcu_uart0;
+		spi1 = &main_spi0;
+		usb0 = &usb0;
+		usb1 = &usb1;
+	};
+
+	chosen {
+		stdout-path = &main_uart0;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&backlight_pins>;
+		enable-gpios = <&main_gpio0 38 GPIO_ACTIVE_HIGH>;
+		status = "disabled";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_key_pins>;
+
+		user-button {
+			label = "USER_BUTTON";
+			linux,code = <BTN_0>;
+			gpios = <&main_gpio0 40 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_led_pins>;
+
+		led-1 {
+			gpios = <&main_gpio0 41 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_INDICATOR;
+		};
+
+		led-2 {
+			gpios = <&main_gpio0 42 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_YELLOW>;
+			function = LED_FUNCTION_INDICATOR;
+		};
+	};
+
+	panel: panel {
+		pinctrl-names = "default";
+		pinctrl-0 = <&lvds_panel_pins>;
+		enable-gpios = <&main_gpio0 36 GPIO_ACTIVE_HIGH>;
+		power-supply = <&reg_lvds_pwr>;
+	};
+
+	fan0: pwm-fan {
+		compatible = "pwm-fan";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm_fan_pins>;
+		fan-supply = <&reg_pwm_fan>;
+		#cooling-cells = <2>;
+		/* typical 25 kHz -> 40.000 nsec */
+		pwms = <&epwm0 1 40000 PWM_POLARITY_INVERTED>;
+		cooling-levels = <0 32 64 128 196 240>;
+		pulses-per-revolution = <2>;
+		interrupt-parent = <&main_gpio1>;
+		interrupts = <30 IRQ_TYPE_EDGE_FALLING>;
+		status = "disabled";
+	};
+
+	wifi_pwrseq: pwrseq-wifi {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_mmc2_pwrseq_pins>;
+		reset-gpios = <&main_gpio0 44 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_1v8: regulator-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "V_1V8_MBA";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	reg_3v3_sd: regulator-3v3-sd {
+		/* TPS22963CYZTP */
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&reg_3v3_sd_pins>;
+		regulator-name = "V_3V3_SD";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		vin-supply = <&reg_3v3>;
+		gpio = <&main_gpio1 8 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_lvds_pwr: regulator-lvds-pwr {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&reg_lvds_pwr_pins>;
+		regulator-name = "LVDS0_PWR";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		vin-supply = <&reg_3v3>;
+		gpio = <&main_gpio0 61 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_pwm_fan: regulator-pwm-fan {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&reg_pwm_fan_pins>;
+		regulator-name = "FAN_PWR";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		gpio = <&main_gpio0 62 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	sound: sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "tq-tlv320aic32x";
+		simple-audio-card,widgets =
+			"Line Out",	"Line Out",
+			"Line In",	"Line In",
+			"Microphone",	"Microphone Jack";
+		simple-audio-card,routing =
+			"Line Out",		"LOL",
+			"Line Out",		"LOR",
+			"IN1_L",		"Line In",
+			"IN1_R",		"Line In",
+			"IN3_L",		"Microphone Jack",
+			"Microphone Jack",	"Mic Bias";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&sound_master>;
+		simple-audio-card,frame-master = <&sound_master>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&mcasp1>;
+		};
+
+		sound_master: simple-audio-card,codec {
+			sound-dai = <&tlv320aic32x4>;
+			clocks = <&audio_refclk0>;
+		};
+	};
+};
+
+&audio_refclk0 {
+	/* Set parent to POSTDIV1_16FFT_MAIN_1_HSDIVOUT6, for 96MHz clock output */
+	assigned-clock-parents = <&k3_clks 157 7>;
+};
+
+&cpsw3g {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_rgmii1_pins
+		     &main_rgmii2_pins>;
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy0>;
+};
+
+&cpsw_port2 {
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy3>;
+};
+
+&cpsw3g_mdio {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mdio1_pins>;
+
+	cpsw3g_phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0>;
+		reset-gpios = <&main_gpio1 11 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <1000>;
+		reset-deassert-us = <1000>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+	};
+
+	cpsw3g_phy3: ethernet-phy at 3 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x3>;
+		reset-gpios = <&main_gpio1 12 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <1000>;
+		reset-deassert-us = <1000>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+	};
+};
+
+&epwm0 {
+	status = "okay";
+};
+
+&epwm1 {
+	status = "okay";
+};
+
+&main_gpio0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_gpio0_pins &main_gpio0_pr0_pins>;
+	gpio-line-names =
+		"", "", "", "", /* 0-3 */
+		"", "", "", "", /* 4-7 */
+		"", "", "", "", /* 8-11 */
+		"ADC_SYNC", "ADC_RST#", "ADC_DATA_RDY", "", /* 12-15 */
+		"", "", "", "", /* 16-19 */
+		"", "", "", "", /* 20-23 */
+		"", "", "", "", /* 24-27 */
+		"", "", "", "", /* 28-31 */
+		"", "", "", "", /* 32-35 */
+		"", "", "", "BG95_PWRKEY", /* 36-39 */
+		"", "", "", "BG95_RESET", /* 40-43 */
+		"", "", "", "", /* 44-47 */
+		"", "", "", "", /* 48-51 */
+		"", "", "", "", /* 52-55 */
+		"", "", "", "", /* 56-59 */
+		"", "", "", "", /* 60-63 */
+		"", "", "", "", /* 64-67 */
+		"", "", "", "", /* 68-71 */
+		"ADC_INT"; /* 72- */
+};
+
+&main_gpio1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_gpio1_pins &main_gpio1_pr0_pins>;
+
+	/* No overcurrent handling in USB host driver - pin is hogged for now */
+	line7-hog {
+		gpio-hog;
+		gpios = <7 0>;
+		line-name = "USB0_VBUS_OC#";
+		input;
+	};
+};
+
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	tlv320aic32x4: audio-codec at 18 {
+		compatible = "ti,tlv320aic32x4";
+		reg = <0x18>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&audio_codec_pins>;
+		#sound-dai-cells = <0>;
+		clock-names = "mclk";
+		clocks = <&audio_refclk0>;
+		reset-gpios = <&main_gpio0 33 GPIO_ACTIVE_LOW>;
+		iov-supply = <&reg_1v8>;
+		ldoin-supply = <&reg_3v3>;
+	};
+};
+
+&main_spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_spi0_pins>;
+	ti,pindir-d0-out-d1-in;
+	status = "okay";
+
+	/* adc at 0: NXP NAFE13388 */
+};
+
+&main0_thermal {
+	trips {
+		main0_active0: trip-active0 {
+			temperature = <40000>;
+			hysteresis = <5000>;
+			type = "active";
+		};
+
+		main0_active1: trip-active1 {
+			temperature = <48000>;
+			hysteresis = <3000>;
+			type = "active";
+		};
+
+		main0_active2: trip-active2 {
+			temperature = <60000>;
+			hysteresis = <10000>;
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map1 {
+			trip = <&main0_active0>;
+			cooling-device = <&fan0 1 1>;
+		};
+
+		map2 {
+			trip = <&main0_active1>;
+			cooling-device = <&fan0 2 2>;
+		};
+
+		map3 {
+			trip = <&main0_active2>;
+			cooling-device = <&fan0 3 3>;
+		};
+	};
+};
+
+&main1_thermal {
+	trips {
+		main1_active0: trip-active0 {
+			temperature = <40000>;
+			hysteresis = <5000>;
+			type = "active";
+		};
+
+		main1_active1: trip-active1 {
+			temperature = <48000>;
+			hysteresis = <3000>;
+			type = "active";
+		};
+
+		main1_active2: trip-active2 {
+			temperature = <60000>;
+			hysteresis = <10000>;
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map1 {
+			trip = <&main1_active0>;
+			cooling-device = <&fan0 1 1>;
+		};
+
+		map2 {
+			trip = <&main1_active1>;
+			cooling-device = <&fan0 2 2>;
+		};
+
+		map3 {
+			trip = <&main1_active2>;
+			cooling-device = <&fan0 3 3>;
+		};
+	};
+};
+
+/* Main console */
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins>;
+	status = "okay";
+};
+
+/*
+ * IOT module - GNSS UART
+ *
+ * Board configuration must not enable UART trace output for TIFS firmware
+ */
+&main_uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart1_pins>;
+	/* IOT module uses USB by default, UART can be enabled as fallback */
+	status = "disabled";
+};
+
+/* Bluetooth module */
+&main_uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart2_pins>;
+	/* Bluetooth module uses SDIO by default, UART can be enabled as fallback */
+	status = "disabled";
+};
+
+/* IOT module - main UART */
+&main_uart5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart5_pins>;
+	/* IOT module uses USB by default, UART can be enabled as fallback */
+	status = "disabled";
+};
+
+&mcasp1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcasp1_pins>;
+	#sound-dai-cells = <0>;
+	op-mode = <0>; /* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+	       1 0 2 0
+	       0 0 0 0
+	       0 0 0 0
+	       0 0 0 0
+	>;
+	tx-num-evt = <0>;
+	rx-num-evt = <0>;
+	status = "okay";
+};
+
+&mcu_gpio0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_gpio0_pins>;
+	gpio-line-names =
+		"EN_DIG_OUT_1", "EN_DIG_OUT_2", "STATUS_OUT_1", "STATUS_OUT_2", /* 0-3 */
+		"EN_DIG_OUT_3", "", "", "V_VPP_EN", /* 4-7 */
+		"", "", "", "EN_DIG_OUT_4", /* 8-11 */
+		"STATUS_OUT_3", "", "", "", /* 12-15 */
+		"", "STATUS_OUT_4", "DIG_IN_1", "DIG_IN_2", /* 16-19 */
+		"DIG_IN_3", "", "", "DIG_IN_4"; /* 20-23 */
+};
+
+&mcu_mcan0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan0_pins>;
+	status = "okay";
+};
+
+&mcu_mcan1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan1_pins>;
+	status = "okay";
+};
+
+&mcu_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_uart0_pins>;
+	rs485-rts-active-low;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&reg_sd {
+	pinctrl-names = "default";
+	pinctrl-0 = <&reg_sd_pins>;
+	gpios = <&main_gpio0 31 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&sdhci1 {
+	/* SD-card */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins>;
+	vmmc-supply = <&reg_3v3_sd>;
+	vqmmc-supply = <&reg_sd>;
+	bus-width = <4>;
+	disable-wp;
+	no-mmc;
+	no-sdio;
+	ti,driver-strength-ohm = <50>;
+	status = "okay";
+};
+
+&sdhci2 {
+	/* WLAN */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc2_pins>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	keep-power-in-suspend;
+	cap-power-off-card;
+	bus-width = <4>;
+	non-removable;
+	no-mmc;
+	no-sd;
+	ti,driver-strength-ohm = <50>;
+	ti,fails-without-test-cd;
+	status = "okay";
+};
+
+&usbss0 {
+	ti,vbus-divider;
+	status = "okay";
+};
+
+&usbss1 {
+	ti,vbus-divider;
+	status = "okay";
+};
+
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_usb0_pins>;
+	dr_mode = "otg";
+	usb-role-switch;
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_enblslpm_quirk;
+
+	connector {
+		compatible = "gpio-usb-b-connector", "usb-b-connector";
+		id-gpios = <&main_gpio0 71 GPIO_ACTIVE_HIGH>;
+		type = "micro";
+	};
+};
+
+&usb1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_usb1_hub_pins>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	dr_mode = "host";
+
+	usb1_hub_2_0: hub at 1 {
+		compatible = "usb424,2514";
+		reg = <1>;
+		reset-gpios = <&main_gpio1 23 GPIO_ACTIVE_HIGH>;
+		vdd-supply = <&reg_3v3>;
+	};
+};
+
+&wkup_uart0 {
+	/* WKUP UART0 is used by DM firmware */
+	status = "reserved";
+};
+
+&main_pmx0 {
+	audio_codec_pins: audio-codec-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x088, PIN_OUTPUT, 7) /* (L24) GPMC0_OEn_REn.GPIO0_33 */
+			AM62X_IOPAD(0x1d0, PIN_OUTPUT, 5) /* (A15) UART0_CTSn.AUDIO_EXT_REFCLK0 */
+		>;
+	};
+
+	backlight_pins: backlight-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x009c, PIN_OUTPUT, 7) /* (V25) GPMC0_WAIT1.GPIO0_38 */
+			AM62X_IOPAD(0x01a0, PIN_OUTPUT, 6) /* (E18) MCASP0_AXR0.EHRPWM1_B */
+		>;
+	};
+
+	dss_pins: dss-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0260, PIN_OUTPUT, 0) /* (AA5) OLDI0_A0N */
+			AM62X_IOPAD(0x025c, PIN_OUTPUT, 0) /* (Y6) OLDI0_A0P */
+			AM62X_IOPAD(0x0268, PIN_OUTPUT, 0) /* (AD3) OLDI0_A1N */
+			AM62X_IOPAD(0x0264, PIN_OUTPUT, 0) /* (AB4) OLDI0_A1P */
+			AM62X_IOPAD(0x0270, PIN_OUTPUT, 0) /* (Y8) OLDI0_A2N */
+			AM62X_IOPAD(0x026c, PIN_OUTPUT, 0) /* (AA8) OLDI0_A2P */
+			AM62X_IOPAD(0x0278, PIN_OUTPUT, 0) /* (AB6) OLDI0_A3N */
+			AM62X_IOPAD(0x0274, PIN_OUTPUT, 0) /* (AA7) OLDI0_A3P */
+			AM62X_IOPAD(0x0280, PIN_OUTPUT, 0) /* (AC6) OLDI0_A4N */
+			AM62X_IOPAD(0x027c, PIN_OUTPUT, 0) /* (AC5) OLDI0_A4P */
+			AM62X_IOPAD(0x0288, PIN_OUTPUT, 0) /* (AE5) OLDI0_A5N */
+			AM62X_IOPAD(0x0284, PIN_OUTPUT, 0) /* (AD6) OLDI0_A5P */
+			AM62X_IOPAD(0x0290, PIN_OUTPUT, 0) /* (AE6) OLDI0_A6N */
+			AM62X_IOPAD(0x028c, PIN_OUTPUT, 0) /* (AD7) OLDI0_A6P */
+			AM62X_IOPAD(0x0298, PIN_OUTPUT, 0) /* (AD8) OLDI0_A7N */
+			AM62X_IOPAD(0x0294, PIN_OUTPUT, 0) /* (AE7) OLDI0_A7P */
+			AM62X_IOPAD(0x02a0, PIN_OUTPUT, 0) /* (AD4) OLDI0_CLK0N */
+			AM62X_IOPAD(0x029c, PIN_OUTPUT, 0) /* (AE3) OLDI0_CLK0P */
+			AM62X_IOPAD(0x02a8, PIN_OUTPUT, 0) /* (AE4) OLDI0_CLK1N */
+			AM62X_IOPAD(0x02a4, PIN_OUTPUT, 0) /* (AD5) OLDI0_CLK1P */
+		>;
+	};
+
+	csi_clk_pins: csi-clk-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x019c, PIN_OUTPUT, 6) /* (B18) MCASP0_AXR1.EHRPWM1_A */
+		>;
+	};
+
+	gpio_key_pins: gpio-key-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0a4, PIN_INPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
+		>;
+	};
+
+	gpio_led_pins: gpio-led-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0a8, PIN_OUTPUT, 7) /* (M21) GPMC0_CSn0.GPIO0_41 */
+			AM62X_IOPAD(0x0ac, PIN_OUTPUT, 7) /* (L21) GPMC0_CSn1.GPIO0_42 */
+		>;
+	};
+
+	lvds_panel_pins: lvds-panel-pins {
+		pinctrl-single,pins = <
+			/* (N20) GPMC0_BE1n.GPIO0_36 - LVDS0_RESET# */
+			AM62X_IOPAD(0x0094, PIN_OUTPUT, 7)
+		>;
+	};
+
+	main_gpio0_pins: main-gpio0-pins {
+		pinctrl-single,pins = <
+			/* Control GPIOs for IOT Module */
+			/* (K25) GPMC0_WPn.GPIO0_39 - BG95_PWRKEY */
+			AM62X_IOPAD(0x0a0, PIN_OUTPUT, 7)
+			/* (K22) GPMC0_CSn2.GPIO0_43 - BG95_RESET */
+			AM62X_IOPAD(0x0b0, PIN_OUTPUT, 7)
+		>;
+	};
+
+	main_gpio0_pr0_pins: main-gpio0-pr0-pins {
+		pinctrl-single,pins = <
+			/* (N24) GPMC0_AD2.GPIO0_17  */
+			AM62X_IOPAD(0x0044, PIN_INPUT, 7)
+			/* (N25) GPMC0_AD3.GPIO0_18  */
+			AM62X_IOPAD(0x0048, PIN_INPUT, 7)
+			/* (P24) GPMC0_AD4.GPIO0_19  */
+			AM62X_IOPAD(0x004c, PIN_INPUT, 7)
+			/* (P22) GPMC0_AD5.GPIO0_20  */
+			AM62X_IOPAD(0x0050, PIN_INPUT, 7)
+			/* (W25) VOUT0_DATA2.GPIO0_47  */
+			AM62X_IOPAD(0x00c0, PIN_INPUT, 7)
+			/* (W24) VOUT0_DATA3.GPIO0_48  */
+			AM62X_IOPAD(0x00c4, PIN_INPUT, 7)
+			/* (Y25) VOUT0_DATA4.GPIO0_49  */
+			AM62X_IOPAD(0x00c8, PIN_INPUT, 7)
+			/* (Y24) VOUT0_DATA5.GPIO0_50  */
+			AM62X_IOPAD(0x00cc, PIN_INPUT, 7)
+		>;
+	};
+
+	main_gpio1_pins: main-gpio1-pins {
+		pinctrl-single,pins = <
+			/* (B19) MCASP0_AXR3.GPIO1_7 - USB0_VBUS_OC# */
+			AM62X_IOPAD(0x0194, PIN_INPUT, 7)
+		>;
+	};
+
+	main_gpio1_pr0_pins: main-gpio1-pr0-pins {
+		pinctrl-single,pins = <
+			/* (C15) MCAN0_TX.GPIO1_24 */
+			AM62X_IOPAD(0x01d8, PIN_INPUT, 7)
+			/* (E15) MCAN0_RX.GPIO1_25 */
+			AM62X_IOPAD(0x01dc, PIN_INPUT, 7)
+		>;
+	};
+
+	main_i2c1_pins: main-i2c1-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x1e8, PIN_INPUT, 0) /* (B17) I2C1_SCL */
+			AM62X_IOPAD(0x1ec, PIN_INPUT, 0) /* (A17) I2C1_SDA */
+		>;
+	};
+
+	main_mcasp1_pins: main-mcasp1-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x090, PIN_INPUT, 2) /* (M24) GPMC0_BE0N_CLE.MCASP1_ACLKX */
+			AM62X_IOPAD(0x098, PIN_INPUT, 2) /* (U23) GPMC0_WAIT0.MCASP1_AFSX */
+			AM62X_IOPAD(0x08c, PIN_OUTPUT, 2) /* (L25) GPMC0_WEN.MCASP1_AXR0 */
+			AM62X_IOPAD(0x084, PIN_INPUT, 2) /* (L23) GPMC0_ADVN_ALE.MCASP1_AXR2 */
+		>;
+	};
+
+	main_mmc1_pins: main-mmc1-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */
+			AM62X_IOPAD(0x234, PIN_INPUT, 0) /* (B22) MMC1_CLK */
+			AM62X_IOPAD(0x230, PIN_INPUT, 0) /* (A22) MMC1_DAT0 */
+			AM62X_IOPAD(0x22c, PIN_INPUT, 0) /* (B21) MMC1_DAT1 */
+			AM62X_IOPAD(0x228, PIN_INPUT, 0) /* (C21) MMC1_DAT2 */
+			AM62X_IOPAD(0x224, PIN_INPUT, 0) /* (D22) MMC1_DAT3 */
+			AM62X_IOPAD(0x240, PIN_INPUT, 0) /* (D17) MMC1_SDCD */
+		>;
+	};
+
+	main_mmc2_pins: main-mmc2-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x120, PIN_INPUT, 0) /* (C24) MMC2_CMD */
+			AM62X_IOPAD(0x118, PIN_INPUT, 0) /* (D25) MMC2_CLK */
+			AM62X_IOPAD(0x114, PIN_INPUT, 0) /* (B24) MMC2_DAT0 */
+			AM62X_IOPAD(0x110, PIN_INPUT, 0) /* (C25) MMC2_DAT1 */
+			AM62X_IOPAD(0x10c, PIN_INPUT, 0) /* (E23) MMC2_DAT2 */
+			AM62X_IOPAD(0x108, PIN_INPUT, 0) /* (D24) MMC2_DAT3 */
+			AM62X_IOPAD(0x11c, PIN_INPUT, 0) /* (#N/A) MMC2_CLKB */
+		>;
+	};
+
+	main_mmc2_pwrseq_pins: main-mmc2-pwrseq-pins {
+		pinctrl-single,pins = <
+			/* (K24) GPMC0_CSn3.GPIO0_44 - WIFI-BT_EN */
+			AM62X_IOPAD(0x00b4, PIN_OUTPUT, 7)
+		>;
+	};
+
+	main_mdio1_pins: main-mdio1-pins {
+		pinctrl-single,pins = <
+			/* (B20) MCASP0_ACLKX.GPIO1_11 - RESET_RGMII1# */
+			AM62X_IOPAD(0x1a4, PIN_OUTPUT, 7)
+			/* (D20) MCASP0_AFSX.GPIO1_12 - RESET_RGMII2# */
+			AM62X_IOPAD(0x1a8, PIN_OUTPUT, 7)
+
+			AM62X_IOPAD(0x160, PIN_OUTPUT, 0) /* (AD24) MDIO0_MDC */
+			AM62X_IOPAD(0x15c, PIN_INPUT, 0) /* (AB22) MDIO0_MDIO */
+		>;
+	};
+
+	main_rgmii1_pins: main-rgmii1-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x14c, PIN_INPUT, 0) /* (AB17) RGMII1_RD0 */
+			AM62X_IOPAD(0x150, PIN_INPUT, 0) /* (AC17) RGMII1_RD1 */
+			AM62X_IOPAD(0x154, PIN_INPUT, 0) /* (AB16) RGMII1_RD2 */
+			AM62X_IOPAD(0x158, PIN_INPUT, 0) /* (AA15) RGMII1_RD3 */
+			AM62X_IOPAD(0x148, PIN_INPUT, 0) /* (AD17) RGMII1_RXC */
+			AM62X_IOPAD(0x144, PIN_INPUT, 0) /* (AE17) RGMII1_RX_CTL */
+			AM62X_IOPAD(0x134, PIN_OUTPUT, 0) /* (AE20) RGMII1_TD0 */
+			AM62X_IOPAD(0x138, PIN_OUTPUT, 0) /* (AD20) RGMII1_TD1 */
+			AM62X_IOPAD(0x13c, PIN_OUTPUT, 0) /* (AE18) RGMII1_TD2 */
+			AM62X_IOPAD(0x140, PIN_OUTPUT, 0) /* (AD18) RGMII1_TD3 */
+			AM62X_IOPAD(0x130, PIN_OUTPUT, 0) /* (AE19) RGMII1_TXC */
+			AM62X_IOPAD(0x12c, PIN_OUTPUT, 0) /* (AD19) RGMII1_TX_CTL */
+		>;
+	};
+
+	main_rgmii2_pins: main-rgmii2-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x184, PIN_INPUT, 0) /* (AE23) RGMII2_RD0 */
+			AM62X_IOPAD(0x188, PIN_INPUT, 0) /* (AB20) RGMII2_RD1 */
+			AM62X_IOPAD(0x18c, PIN_INPUT, 0) /* (AC21) RGMII2_RD2 */
+			AM62X_IOPAD(0x190, PIN_INPUT, 0) /* (AE22) RGMII2_RD3 */
+			AM62X_IOPAD(0x180, PIN_INPUT, 0) /* (AD23) RGMII2_RXC */
+			AM62X_IOPAD(0x17c, PIN_INPUT, 0) /* (AD22) RGMII2_RX_CTL */
+			AM62X_IOPAD(0x16c, PIN_OUTPUT, 0) /* (Y18) RGMII2_TD0 */
+			AM62X_IOPAD(0x170, PIN_OUTPUT, 0) /* (AA18) RGMII2_TD1 */
+			AM62X_IOPAD(0x174, PIN_OUTPUT, 0) /* (AD21) RGMII2_TD2 */
+			AM62X_IOPAD(0x178, PIN_OUTPUT, 0) /* (AC20) RGMII2_TD3 */
+			AM62X_IOPAD(0x168, PIN_OUTPUT, 0) /* (AE21) RGMII2_TXC */
+			AM62X_IOPAD(0x164, PIN_OUTPUT, 0) /* (AA19) RGMII2_TX_CTL */
+		>;
+	};
+
+	main_spi0_pins: main-spi0-pins {
+		pinctrl-single,pins = <
+			/* (A14) SPI0_CLK */
+			AM62X_IOPAD(0x1bc, PIN_OUTPUT, 0)
+			/* (A13) SPI0_CS0 */
+			AM62X_IOPAD(0x1b4, PIN_OUTPUT, 0)
+			/* (B13) SPI0_D0 */
+			AM62X_IOPAD(0x1c0, PIN_OUTPUT, 0)
+			/* (B14) SPI0_D1 */
+			AM62X_IOPAD(0x1c4, PIN_INPUT, 0)
+		>;
+	};
+
+	main_spi0_adc_pins: main-spi0-adc-pins {
+		pinctrl-single,pins = <
+			/* (G21) OSPI0_CSn1.GPIO0_12 - ADC_SYNC */
+			AM62X_IOPAD(0x030, PIN_INPUT, 7)
+			/* (H21) OSPI0_CSn2.GPIO0_13 - ADC_RST# */
+			AM62X_IOPAD(0x034, PIN_OUTPUT, 7)
+			/* (E24) OSPI0_CSn3.GPIO0_14 - ADC_DATA_RDY */
+			AM62X_IOPAD(0x038, PIN_INPUT, 7)
+			/* (B23) MMC2_SDWP.GPIO0_72 - ADC_INT# */
+			AM62X_IOPAD(0x128, PIN_INPUT, 7)
+		>;
+	};
+
+	main_uart0_pins: main-uart0-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x1c8, PIN_INPUT, 0) /* (D14) UART0_RXD */
+			AM62X_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (E14) UART0_TXD */
+		>;
+	};
+
+	main_uart1_pins: main-uart1-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x1ac, PIN_INPUT, 2) /* (E19) MCASP0_AFSR.UART1_RXD */
+			AM62X_IOPAD(0x1b0, PIN_OUTPUT, 2) /* (A20) MCASP0_ACLKR.UART1_TXD */
+		>;
+	};
+
+	main_uart2_pins: main-uart2-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0b8, PIN_INPUT, 4) /* (U22) VOUT0_DATA0.UART2_RXD */
+			AM62X_IOPAD(0x0bc, PIN_OUTPUT, 4) /* (V24) VOUT0_DATA1.UART2_TXD */
+			AM62X_IOPAD(0x104, PIN_INPUT, 4) /* (AC24) VOUT0_PCLK.UART2_CTS# */
+			AM62X_IOPAD(0x100, PIN_OUTPUT, 4) /* (AC25) VOUT0_VSYNC.UART2_RTS# */
+		>;
+	};
+
+	main_uart5_pins: main-uart5-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0d0, PIN_INPUT, 4) /* (Y23) VOUT0_DATA6.UART5_RXD */
+			AM62X_IOPAD(0x0d4, PIN_OUTPUT, 4) /* (AA25) VOUT0_DATA7.UART5_TXD */
+		>;
+	};
+
+	main_usb0_pins: main-usb0-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x254, PIN_OUTPUT, 0) /* (C20) USB0_DRVVBUS */
+			AM62X_IOPAD(0x124, PIN_INPUT, 7) /* (A23) MMC2_SDCD.GPIO0_71 */
+		>;
+	};
+
+	main_usb1_hub_pins: main-usb1-hub-pins {
+		pinctrl-single,pins = <
+			/* (B15) UART0_RTSn.GPIO1_23 - USB_HUB_RESET */
+			AM62X_IOPAD(0x01d4, PIN_OUTPUT, 7)
+		>;
+	};
+
+	pwm_fan_pins: pwm-fan-pins {
+		pinctrl-single,pins = <
+			/* (C13) SPI0_CS1.EHRPWM0_B - FAN_PWM */
+			AM62X_IOPAD(0x01b8, PIN_OUTPUT, 2)
+			/* (A18) EXT_REFCLK1.GPIO1_30 - FAN_RPM */
+			AM62X_IOPAD(0x01f0, PIN_INPUT, 7)
+		>;
+	};
+
+	reg_3v3_sd_pins: reg-3v3-sd-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x198, PIN_OUTPUT, 7) /* (A19) MCASP0_AXR2.GPIO1_8 */
+		>;
+	};
+
+	reg_lvds_pwr_pins: reg-lvds-pwr-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00f8, PIN_OUTPUT, 7) /* (AB24) VOUT0_HSYNC.GPIO0_61 */
+		>;
+	};
+
+	reg_pwm_fan_pins: reg-pwm-fan-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00fc, PIN_OUTPUT, 7) /* (Y20) VOUT0_DE.GPIO0_62 */
+		>;
+	};
+
+	reg_sd_pins: reg-sd-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x07c, PIN_OUTPUT, 7) /* (P25) GPMC0_CLK.GPIO0_31 */
+		>;
+	};
+};
+
+&mcu_pmx0 {
+	mcu_gpio0_pins: mcu-gpio0-pins {
+		pinctrl-single,pins = <
+			/* (E8) MCU_SPI0_CS0.MCU_GPIO0_0 - EN_DIG_OUT1 */
+			AM62X_MCU_IOPAD(0x000, PIN_OUTPUT, 7)
+			/* (B8) MCU_SPI0_CS1.MCU_GPIO0_1 - EN_DIG_OUT2 */
+			AM62X_MCU_IOPAD(0x004, PIN_OUTPUT, 7)
+			/* (A7) MCU_SPI0_CLK.MCU_GPIO0_2 - STATUS_OUT1 */
+			AM62X_MCU_IOPAD(0x008, PIN_INPUT, 7)
+			/* (D9) MCU_SPI0_D0.MCU_GPIO0_3 - STATUS_OUT2 */
+			AM62X_MCU_IOPAD(0x00c, PIN_INPUT, 7)
+			/* (C9) MCU_SPI0_D1.MCU_GPIO0_4 - EN_DIG_OUT3 */
+			AM62X_MCU_IOPAD(0x010, PIN_OUTPUT, 7)
+			/* (C6) WKUP_UART0_CTSn.MCU_GPIO0_11 - EN_DIG_OUT4 */
+			AM62X_MCU_IOPAD(0x02c, PIN_OUTPUT, 7)
+			/* (A4) WKUP_UART0_RTSn.MCU_GPIO0_12 - STATUS_OUT3 */
+			AM62X_MCU_IOPAD(0x030, PIN_INPUT, 7)
+			/* (A8) MCU_I2C0_SCL.MCU_GPIO0_17 - STATUS_OUT4 */
+			AM62X_MCU_IOPAD(0x044, PIN_INPUT, 7)
+			/* (D10) MCU_I2C0_SDA.MCU_GPIO0_18 - DIG_IN_1 */
+			AM62X_MCU_IOPAD(0x048, PIN_INPUT, 7)
+			/* (B9) WKUP_I2C0_SCL.MCU_GPIO0_19 - DIG_IN_2 */
+			AM62X_MCU_IOPAD(0x04c, PIN_INPUT, 7)
+			/* (A9) WKUP_I2C0_SDA.MCU_GPIO0_20 - DIG_IN_3 */
+			AM62X_MCU_IOPAD(0x050, PIN_INPUT, 7)
+			/* (A12) WKUP_CLKOUT0.MCU_GPIO0_23 - DIG_IN_4 */
+			AM62X_MCU_IOPAD(0x084, PIN_INPUT, 7)
+			/* (A6) MCU_UART0_CTSn.MCU_GPIO0_7 - V_VPP_EN */
+			AM62X_MCU_IOPAD(0x01c, PIN_OUTPUT, 7)
+		>;
+	};
+	mcu_mcan0_pins: mcu-mcan0-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */
+			AM62X_MCU_IOPAD(0x034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */
+		>;
+	};
+
+	mcu_mcan1_pins: mcu-mcan1-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */
+			AM62X_MCU_IOPAD(0x03c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */
+		>;
+	};
+
+	mcu_uart0_pins: mcu-uart0-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x014, PIN_INPUT, 0) /* (B5) MCU_UART0_RXD */
+			AM62X_MCU_IOPAD(0x018, PIN_OUTPUT, 0) /* (A5) MCU_UART0_TXD */
+			AM62X_MCU_IOPAD(0x020, PIN_OUTPUT, 0) /* (B6) MCU_UART0_RTS# */
+		>;
+	};
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi b/arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi
new file mode 100644
index 0000000000000..d211d14f3cd15
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2021-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (c) 2023-2024 TQ-Systems GmbH <linux at ew.tq-group.com>, D-82229 Seefeld, Germany.
+ * Author: Matthias Schiffer
+ */
+
+#include "k3-am625.dtsi"
+
+/ {
+	aliases {
+		i2c0 = &main_i2c0;
+		mmc0 = &sdhci0;
+		spi0 = &ospi0;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		/* 1G RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		ramoops at 9c700000 {
+			compatible = "ramoops";
+			reg = <0x00 0x9c700000 0x00 0x00100000>;
+			record-size = <0x8000>;
+			console-size = <0x8000>;
+			ftrace-size = <0x00>;
+			pmsg-size = <0x8000>;
+		};
+
+		/* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x8000000>;
+			linux,cma-default;
+		};
+
+		rtos_ipc_memory_region: ipc-memories at 9c800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9c800000 0x00 0x00300000>;
+			no-map;
+		};
+
+		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;
+		};
+
+		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory at 9da00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9da00000 0x00 0x100000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_memory_region: r5f-memory at 9db00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9db00000 0x00 0xc00000>;
+			no-map;
+		};
+
+		secure_tfa_ddr: tfa at 9e780000 {
+			reg = <0x00 0x9e780000 0x00 0x80000>;
+			alignment = <0x1000>;
+			no-map;
+		};
+
+		secure_ddr: optee at 9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+			alignment = <0x1000>;
+			no-map;
+		};
+	};
+
+	reg_3v3: regulator-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "V_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	reg_sd: regulator-sd {
+		/* Output of TPS6521902RSM */
+		compatible = "regulator-gpio";
+		regulator-name = "V_VDDSHV5";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		vin-supply = <&reg_ldo1>;
+		states = <1800000 0x0>,
+			 <3300000 0x1>;
+		/* Controlling GPIO set by base board */
+		status = "disabled";
+	};
+};
+
+&mailbox0_cluster0 {
+	mbox_m4_0: mbox-m4-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+
+	mbox_r5_0: mbox-r5-0 {
+		ti,mbox-rx = <2 0 0>;
+		ti,mbox-tx = <3 0 0>;
+	};
+};
+
+&mcu_m4fss {
+	mboxes = <&mailbox0_cluster0 &mbox_m4_0>;
+	memory-region = <&mcu_m4fss_dma_memory_region>,
+			<&mcu_m4fss_memory_region>;
+	status = "okay";
+};
+
+&wkup_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster0 &mbox_r5_0>;
+	memory-region = <&wkup_r5fss0_core0_dma_memory_region>,
+			<&wkup_r5fss0_core0_memory_region>;
+};
+
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	tps65219: pmic at 30 {
+		compatible = "ti,tps65219";
+		reg = <0x30>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		buck1-supply = <&reg_3v3>;
+		buck2-supply = <&reg_3v3>;
+		buck3-supply = <&reg_3v3>;
+		ldo1-supply = <&reg_3v3>;
+		ldo2-supply = <&reg_buck2>;
+		ldo3-supply = <&reg_3v3>;
+		ldo4-supply = <&reg_3v3>;
+		system-power-controller;
+		ti,power-button;
+
+		regulators {
+			reg_buck1: buck1 {
+				regulator-name = "V_VDD_CORE";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			reg_buck2: buck2 {
+				regulator-name = "V_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			reg_buck3: buck3 {
+				regulator-name = "V_1V1";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			reg_ldo1: ldo1 {
+				/* Actual voltage of LDO1 is controlled by GPIO, see reg_sd */
+				regulator-name = "V_VDDSHV5_3V3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-allow-bypass;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			reg_ldo2: ldo2 {
+				regulator-name = "V_0V85";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			reg_ldo3: ldo3 {
+				regulator-name = "V_1V8A";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			reg_ldo4: ldo4 {
+				/* Unused */
+				regulator-name = "V_VLDO4";
+				regulator-boot-on;
+			};
+		};
+	};
+
+	tmp1075: temperature-sensor at 4a {
+		compatible = "ti,tmp1075";
+		reg = <0x4a>;
+		vs-supply = <&reg_buck2>;
+	};
+
+	eeprom0: eeprom at 50 {
+		compatible = "st,24c02", "atmel,24c02";
+		reg = <0x50>;
+		vcc-supply = <&reg_buck2>;
+		pagesize = <16>;
+		read-only;
+	};
+
+	pcf85063: rtc at 51 {
+		compatible = "nxp,pcf85063a";
+		reg = <0x51>;
+		quartz-load-femtofarads = <12500>;
+	};
+
+	eeprom1: eeprom at 54 {
+		compatible = "st,24c64", "atmel,24c64";
+		reg = <0x54>;
+		vcc-supply = <&reg_buck2>;
+		pagesize = <32>;
+	};
+};
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <84000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			/* Filled by bootloader */
+		};
+	};
+};
+
+&sdhci0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins>;
+	non-removable;
+	disable-wp;
+	no-sd;
+	no-sdio;
+	ti,driver-strength-ohm = <50>;
+	status = "okay";
+};
+
+&wkup_rtc0 {
+	/*
+	 * Erratum i2327: We can't guarantee that the TQMa62xx will boot fast
+	 * enough for U-Boot to apply the workaround within one second after
+	 * power-on. Keep the RTC disabled to avoid RTC interrupt issues.
+	 *
+	 * The external RTC of the TQMa62xx should be used instead.
+	 *
+	 * If needed, the RTC can be enabled in a baseboard DTS, as long as
+	 * boot is fast enough on all relevant boot media.
+	 */
+	status = "disabled";
+};
+
+&main_pmx0 {
+	main_i2c0_pins: main-i2c0-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x1e0, PIN_INPUT, 0) /* (B16) I2C0_SCL */
+			AM62X_IOPAD(0x1e4, PIN_INPUT, 0) /* (A16) I2C0_SDA */
+		>;
+	};
+
+	main_mmc0_pins: main-mmc0-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
+			AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLK */
+			AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */
+			AM62X_IOPAD(0x210, PIN_INPUT, 0) /* (AA1) MMC0_DAT1 */
+			AM62X_IOPAD(0x20c, PIN_INPUT, 0) /* (AA3) MMC0_DAT2 */
+			AM62X_IOPAD(0x208, PIN_INPUT, 0) /* (Y4) MMC0_DAT3 */
+			AM62X_IOPAD(0x204, PIN_INPUT, 0) /* (AB2) MMC0_DAT4 */
+			AM62X_IOPAD(0x200, PIN_INPUT, 0) /* (AC1) MMC0_DAT5 */
+			AM62X_IOPAD(0x1fc, PIN_INPUT, 0) /* (AD2) MMC0_DAT6 */
+			AM62X_IOPAD(0x1f8, PIN_INPUT, 0) /* (AC2) MMC0_DAT7 */
+		>;
+	};
+
+	ospi0_pins: ospi0-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x000, PIN_OUTPUT, 0) /* (H24) OSPI0_CLK */
+			AM62X_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F23) OSPI0_CSn0 */
+			AM62X_IOPAD(0x00c, PIN_INPUT, 0) /* (E25) OSPI0_D0 */
+			AM62X_IOPAD(0x010, PIN_INPUT, 0) /* (G24) OSPI0_D1 */
+			AM62X_IOPAD(0x014, PIN_INPUT, 0) /* (F25) OSPI0_D2 */
+			AM62X_IOPAD(0x018, PIN_INPUT, 0) /* (F24) OSPI0_D3 */
+			AM62X_IOPAD(0x01c, PIN_INPUT, 0) /* (J23) OSPI0_D4 */
+			AM62X_IOPAD(0x020, PIN_INPUT, 0) /* (J25) OSPI0_D5 */
+			AM62X_IOPAD(0x024, PIN_INPUT, 0) /* (H25) OSPI0_D6 */
+			AM62X_IOPAD(0x028, PIN_INPUT, 0) /* (J22) OSPI0_D7 */
+			AM62X_IOPAD(0x008, PIN_INPUT, 0) /* (J24) OSPI0_DQS */
+			AM62X_IOPAD(0x004, PIN_INPUT, 0) /* (G25) OSPI0_LBCLKO */
+		>;
+	};
+
+	pmic_irq_pins: pmic-irq-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01f4, PIN_INPUT_PULLUP, 0) /* (D16) EXTINTn */
+		>;
+	};
+};
-- 
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
https://www.tq-group.com/



From maz at kernel.org  Mon Dec  9 01:54:29 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Dec 2024 09:54:29 +0000
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer expired
In-Reply-To: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
Message-ID: <867c89tc4q.wl-maz@kernel.org>

Ganapatrao,

Did you notice that the Columbia list was killed over two years ago,
as per ac107abef1976 ("KVM: arm64: Advertise new kvmarm mailing
list")? Consider that script/get_maintainer.pl is your friend.

Cc'ing the correct list instead,

On Mon, 09 Dec 2024 05:32:01 +0000,
Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> 
> During automated testing of Nested Virtualization using avocado-vt,

Which is not merged upstream. So what branch are you using? Based on
what kernel version? On what HW? With which virtualisation features?

> it has been observed that during some boot test iterations,
> the Guest-Hypervisor boot was getting crashed with a
> synchronous exception while it is still booting EDK2.
> 
> The test is launching Multiple instances of Guest-Hypervisor boot

Is the multiple instance aspect really relevant to the reproduction of
the problem?

> and while booting, QEMU monitor issued the command "info register"
> at regular intervals to take a register dump. To execute this
> command, QEMU stops the run and does the register read of various
> registers. While resuming the run, the function kvm_arm_timer_write()
> writes back the saved CNTV_CTL_EL0 register with ISTATUS cleared always

It is userspace that causes this write-back, right? AFAICT, KVM never
does that on its own.

> and resulting in the loss of pending interrupt for emulated timers.

How does a missing interrupt result in a synchronous exception in
EDK2? In my experience, EDK2 panics if it sees spurious interrupts,
not when it is missing interrupts (it just locks up, which is
expected).

> In hardware based timers, ISTATUS is a RO/WI bit and gets set by the
> h/w, if the condition is still met. However, in Nested-Virtualization
> case, the Guest-Hypervisor's?EDK2 is using an emulated virtual timer
> and losing ISTATUS state and the interrupt forever.

Why is this specific to NV? Can't the same thing happen to the
physical timer in a non-VHE configuration?

> 
> Adding fix in kvm_arm_timer_write to set ISTATUS for emulated
> timers, if the timer expired already.
> 
> Fixes: 81dc9504a700 ("KVM: arm64: nv: timers: Support hyp timer emulation")

Where is this coming from? This patch doesn't touch the code you are
changing, so how can it be the source of your problems? As far as I
can tell, this has been the case since 5c5196da4e966 ("KVM: arm/arm64:
Support EL1 phys timer register access in set/get reg").

> Co-developed-by: Vishnu Pajjuri <vishnu at os.amperecomputing.com>
> Signed-off-by: Vishnu Pajjuri <vishnu at os.amperecomputing.com>
> Signed-off-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
> ---
>  arch/arm64/kvm/arch_timer.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 1215df590418..aca58113d790 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -1199,7 +1199,16 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
>  		break;
>  
>  	case TIMER_REG_CTL:
> -		timer_set_ctl(timer, val & ~ARCH_TIMER_CTRL_IT_STAT);
> +		struct timer_map map;
> +
> +		val &= ~ARCH_TIMER_CTRL_IT_STAT;
> +		get_timer_map(vcpu, &map);
> +		/* Set ISTATUS bit for emulated timers, if timer expired. */
> +		if (timer == map.emul_vtimer || timer == map.emul_ptimer) {
> +			if (!kvm_timer_compute_delta(timer))
> +				val |= ARCH_TIMER_CTRL_IT_STAT;
> +		}
> +		timer_set_ctl(timer, val);
>  		break;

This really looks awfully complicated, when it is only a matter of
recomputing the interrupt state, something that is at the core of the
timer emulation. Why can't the following work:

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 895f09658ef83..bd6efafbe7109 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -1298,13 +1298,17 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
 				enum kvm_arch_timer_regs treg,
 				u64 val)
 {
+	unsigned long tmp = val;
+
 	switch (treg) {
 	case TIMER_REG_TVAL:
 		timer_set_cval(timer, kvm_phys_timer_read() - timer_get_offset(timer) + (s32)val);
 		break;
 
 	case TIMER_REG_CTL:
-		timer_set_ctl(timer, val & ~ARCH_TIMER_CTRL_IT_STAT);
+		__assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &tmp,
+			     kvm_timer_should_fire(timer));
+		timer_set_ctl(timer, tmp);
 		break;
 
 	case TIMER_REG_CVAL:

But overall, this very much looks like it is only papering over the
real issue, which is that the *emulation* should regenerate the
pending bit, and not rely on the userspace interface.

As far as I can tell, we already correctly compute the status bit on
read (read_timer_ctl()), so the guest should always observe something
consistent when it traps. We also *never* use the status bit as an
input to the emulation, and always recompute it from scratch (it is
only there for the benefit of the guest or userspace).

So I can't see how upstream is broken in at the moment, and you need
to explain how this actually triggers. Ideally, with a standalone
reproducer or a selftest.

Thanks,

	M.

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


From yury.khrustalev at arm.com  Mon Dec  9 01:47:17 2024
From: yury.khrustalev at arm.com (Yury Khrustalev)
Date: Mon,  9 Dec 2024 09:47:17 +0000
Subject: [RESEND v4 1/3] mm/pkey: Add PKEY_UNRESTRICTED macro
In-Reply-To: <20241209094719.2431126-1-yury.khrustalev@arm.com>
References: <20241209094719.2431126-1-yury.khrustalev@arm.com>
Message-ID: <20241209094719.2431126-2-yury.khrustalev@arm.com>

Memory protection keys (pkeys) uapi has two macros for pkeys restrictions:

 - PKEY_DISABLE_ACCESS 0x1
 - PKEY_DISABLE_WRITE  0x2

with implicit literal value of 0x0 that means "unrestricted". Code that
works with pkeys has to use this literal value when implying that a pkey
imposes no restrictions. This may reduce readability because 0 can be
written in various ways (e.g. 0x0 or 0) and also because 0 in the context
of pkeys can be mistaken for "no permissions" (akin PROT_NONE) while it
actually means "no restrictions". This is important because pkeys are
oftentimes used near mprotect() that uses PROT_ macros.

This patch adds PKEY_UNRESTRICTED macro defined as 0x0.

Signed-off-by: Yury Khrustalev <yury.khrustalev at arm.com>
Acked-by: Dave Hansen <dave.hansen at linux.intel.com>
---
 include/uapi/asm-generic/mman-common.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h
index 1ea2c4c33b86..ef1c27fa3c57 100644
--- a/include/uapi/asm-generic/mman-common.h
+++ b/include/uapi/asm-generic/mman-common.h
@@ -85,6 +85,7 @@
 /* compatibility flags */
 #define MAP_FILE	0
 
+#define PKEY_UNRESTRICTED	0x0
 #define PKEY_DISABLE_ACCESS	0x1
 #define PKEY_DISABLE_WRITE	0x2
 #define PKEY_ACCESS_MASK	(PKEY_DISABLE_ACCESS |\
-- 
2.39.5



From yury.khrustalev at arm.com  Mon Dec  9 01:47:18 2024
From: yury.khrustalev at arm.com (Yury Khrustalev)
Date: Mon,  9 Dec 2024 09:47:18 +0000
Subject: [RESEND v4 2/3] selftests/mm: Use PKEY_UNRESTRICTED macro
In-Reply-To: <20241209094719.2431126-1-yury.khrustalev@arm.com>
References: <20241209094719.2431126-1-yury.khrustalev@arm.com>
Message-ID: <20241209094719.2431126-3-yury.khrustalev@arm.com>

Replace literal 0 with macro PKEY_UNRESTRICTED where pkey_*() functions
are used in mm selftests for memory protection keys.

Signed-off-by: Yury Khrustalev <yury.khrustalev at arm.com>
Suggested-by: Joey Gouly <joey.gouly at arm.com>
Acked-by: Dave Hansen <dave.hansen at linux.intel.com>
---
 tools/testing/selftests/mm/mseal_test.c            | 6 +++---
 tools/testing/selftests/mm/pkey-helpers.h          | 3 ++-
 tools/testing/selftests/mm/pkey_sighandler_tests.c | 4 ++--
 tools/testing/selftests/mm/protection_keys.c       | 2 +-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/mm/mseal_test.c b/tools/testing/selftests/mm/mseal_test.c
index 01675c412b2a..30ea37e8ecf8 100644
--- a/tools/testing/selftests/mm/mseal_test.c
+++ b/tools/testing/selftests/mm/mseal_test.c
@@ -218,7 +218,7 @@ bool seal_support(void)
 bool pkey_supported(void)
 {
 #if defined(__i386__) || defined(__x86_64__) /* arch */
-	int pkey = sys_pkey_alloc(0, 0);
+	int pkey = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 
 	if (pkey > 0)
 		return true;
@@ -1671,7 +1671,7 @@ static void test_seal_discard_ro_anon_on_pkey(bool seal)
 	setup_single_address_rw(size, &ptr);
 	FAIL_TEST_IF_FALSE(ptr != (void *)-1);
 
-	pkey = sys_pkey_alloc(0, 0);
+	pkey = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 	FAIL_TEST_IF_FALSE(pkey > 0);
 
 	ret = sys_mprotect_pkey((void *)ptr, size, PROT_READ | PROT_WRITE, pkey);
@@ -1683,7 +1683,7 @@ static void test_seal_discard_ro_anon_on_pkey(bool seal)
 	}
 
 	/* sealing doesn't take effect if PKRU allow write. */
-	set_pkey(pkey, 0);
+	set_pkey(pkey, PKEY_UNRESTRICTED);
 	ret = sys_madvise(ptr, size, MADV_DONTNEED);
 	FAIL_TEST_IF_FALSE(!ret);
 
diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index f7cfe163b0ff..10fa3ca9b05b 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 #include <ucontext.h>
 #include <sys/mman.h>
+#include <linux/mman.h>
 
 #include "../kselftest.h"
 
@@ -224,7 +225,7 @@ static inline u32 *siginfo_get_pkey_ptr(siginfo_t *si)
 static inline int kernel_has_pkeys(void)
 {
 	/* try allocating a key and see if it succeeds */
-	int ret = sys_pkey_alloc(0, 0);
+	int ret = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 	if (ret <= 0) {
 		return 0;
 	}
diff --git a/tools/testing/selftests/mm/pkey_sighandler_tests.c b/tools/testing/selftests/mm/pkey_sighandler_tests.c
index c593a426341c..2015ed7e0928 100644
--- a/tools/testing/selftests/mm/pkey_sighandler_tests.c
+++ b/tools/testing/selftests/mm/pkey_sighandler_tests.c
@@ -314,7 +314,7 @@ static void test_sigsegv_handler_with_different_pkey_for_stack(void)
 	__write_pkey_reg(pkey_reg);
 
 	/* Protect the new stack with MPK 1 */
-	pkey = pkey_alloc(0, 0);
+	pkey = pkey_alloc(0, PKEY_UNRESTRICTED);
 	pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
 
 	/* Set up alternate signal stack that will use the default MPK */
@@ -487,7 +487,7 @@ static void test_pkru_sigreturn(void)
 	__write_pkey_reg(pkey_reg);
 
 	/* Protect the stack with MPK 2 */
-	pkey = pkey_alloc(0, 0);
+	pkey = pkey_alloc(0, PKEY_UNRESTRICTED);
 	pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
 
 	/* Set up alternate signal stack that will use the default MPK */
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index 4990f7ab4cb7..cca7435a7bc5 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -491,7 +491,7 @@ int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
 int alloc_pkey(void)
 {
 	int ret;
-	unsigned long init_val = 0x0;
+	unsigned long init_val = PKEY_UNRESTRICTED;
 
 	dprintf1("%s()::%d, pkey_reg: 0x%016llx shadow: %016llx\n",
 			__func__, __LINE__, __read_pkey_reg(), shadow_pkey_reg);
-- 
2.39.5



From yury.khrustalev at arm.com  Mon Dec  9 01:47:19 2024
From: yury.khrustalev at arm.com (Yury Khrustalev)
Date: Mon,  9 Dec 2024 09:47:19 +0000
Subject: [RESEND v4 3/3] selftests/powerpc: Use PKEY_UNRESTRICTED macro
In-Reply-To: <20241209094719.2431126-1-yury.khrustalev@arm.com>
References: <20241209094719.2431126-1-yury.khrustalev@arm.com>
Message-ID: <20241209094719.2431126-4-yury.khrustalev@arm.com>

Replace literal 0 with macro PKEY_UNRESTRICTED where pkey_*() functions
are used in mm selftests for memory protection keys for ppc target.

Signed-off-by: Yury Khrustalev <yury.khrustalev at arm.com>
Suggested-by: Kevin Brodsky <kevin.brodsky at arm.com>
Reviewed-by: Kevin Brodsky <kevin.brodsky at arm.com>

---
Note that I couldn't build these tests so I would appreciate if someone
could check this patch. Thank you!
---
 tools/testing/selftests/powerpc/include/pkeys.h      | 2 +-
 tools/testing/selftests/powerpc/mm/pkey_exec_prot.c  | 2 +-
 tools/testing/selftests/powerpc/mm/pkey_siginfo.c    | 2 +-
 tools/testing/selftests/powerpc/ptrace/core-pkey.c   | 6 +++---
 tools/testing/selftests/powerpc/ptrace/ptrace-pkey.c | 6 +++---
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/tools/testing/selftests/powerpc/include/pkeys.h b/tools/testing/selftests/powerpc/include/pkeys.h
index 51729d9a7111..430cb4bd7472 100644
--- a/tools/testing/selftests/powerpc/include/pkeys.h
+++ b/tools/testing/selftests/powerpc/include/pkeys.h
@@ -85,7 +85,7 @@ int pkeys_unsupported(void)
 	SKIP_IF(!hash_mmu);
 
 	/* Check if the system call is supported */
-	pkey = sys_pkey_alloc(0, 0);
+	pkey = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 	SKIP_IF(pkey < 0);
 	sys_pkey_free(pkey);
 
diff --git a/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c b/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
index 0af4f02669a1..29b91b7456eb 100644
--- a/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
+++ b/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
@@ -72,7 +72,7 @@ static void segv_handler(int signum, siginfo_t *sinfo, void *ctx)
 
 		switch (fault_type) {
 		case PKEY_DISABLE_ACCESS:
-			pkey_set_rights(fault_pkey, 0);
+			pkey_set_rights(fault_pkey, PKEY_UNRESTRICTED);
 			break;
 		case PKEY_DISABLE_EXECUTE:
 			/*
diff --git a/tools/testing/selftests/powerpc/mm/pkey_siginfo.c b/tools/testing/selftests/powerpc/mm/pkey_siginfo.c
index 2db76e56d4cb..e89a164c686b 100644
--- a/tools/testing/selftests/powerpc/mm/pkey_siginfo.c
+++ b/tools/testing/selftests/powerpc/mm/pkey_siginfo.c
@@ -83,7 +83,7 @@ static void segv_handler(int signum, siginfo_t *sinfo, void *ctx)
 	    mprotect(pgstart, pgsize, PROT_EXEC))
 		_exit(1);
 	else
-		pkey_set_rights(pkey, 0);
+		pkey_set_rights(pkey, PKEY_UNRESTRICTED);
 
 	fault_count++;
 }
diff --git a/tools/testing/selftests/powerpc/ptrace/core-pkey.c b/tools/testing/selftests/powerpc/ptrace/core-pkey.c
index f6da4cb30cd6..64c985445cb7 100644
--- a/tools/testing/selftests/powerpc/ptrace/core-pkey.c
+++ b/tools/testing/selftests/powerpc/ptrace/core-pkey.c
@@ -124,16 +124,16 @@ static int child(struct shared_info *info)
 	/* Get some pkeys so that we can change their bits in the AMR. */
 	pkey1 = sys_pkey_alloc(0, PKEY_DISABLE_EXECUTE);
 	if (pkey1 < 0) {
-		pkey1 = sys_pkey_alloc(0, 0);
+		pkey1 = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 		FAIL_IF(pkey1 < 0);
 
 		disable_execute = false;
 	}
 
-	pkey2 = sys_pkey_alloc(0, 0);
+	pkey2 = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 	FAIL_IF(pkey2 < 0);
 
-	pkey3 = sys_pkey_alloc(0, 0);
+	pkey3 = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 	FAIL_IF(pkey3 < 0);
 
 	info->amr |= 3ul << pkeyshift(pkey1) | 2ul << pkeyshift(pkey2);
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-pkey.c b/tools/testing/selftests/powerpc/ptrace/ptrace-pkey.c
index d89474377f11..37794f82ed66 100644
--- a/tools/testing/selftests/powerpc/ptrace/ptrace-pkey.c
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-pkey.c
@@ -81,16 +81,16 @@ static int child(struct shared_info *info)
 	/* Get some pkeys so that we can change their bits in the AMR. */
 	pkey1 = sys_pkey_alloc(0, PKEY_DISABLE_EXECUTE);
 	if (pkey1 < 0) {
-		pkey1 = sys_pkey_alloc(0, 0);
+		pkey1 = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 		CHILD_FAIL_IF(pkey1 < 0, &info->child_sync);
 
 		disable_execute = false;
 	}
 
-	pkey2 = sys_pkey_alloc(0, 0);
+	pkey2 = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 	CHILD_FAIL_IF(pkey2 < 0, &info->child_sync);
 
-	pkey3 = sys_pkey_alloc(0, 0);
+	pkey3 = sys_pkey_alloc(0, PKEY_UNRESTRICTED);
 	CHILD_FAIL_IF(pkey3 < 0, &info->child_sync);
 
 	info->amr1 |= 3ul << pkeyshift(pkey1);
-- 
2.39.5



From andre.draszik at linaro.org  Mon Dec  9 01:54:57 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Mon, 09 Dec 2024 09:54:57 +0000
Subject: [PATCH v3 5/8] phy: exynos5-usbdrd: gs101: ensure power is
 gated to SS phy in phy_exit()
In-Reply-To: <Z1W9xuCrn40uPWbr@vaman>
References: <20241205-gs101-phy-lanes-orientation-phy-v3-0-32f721bed219@linaro.org>
	 <20241205-gs101-phy-lanes-orientation-phy-v3-5-32f721bed219@linaro.org>
	 <2024120528-poker-thinness-6cfb@gregkh> <Z1W9xuCrn40uPWbr@vaman>
Message-ID: <bbc6654e3ce7d28c4a98e25db270615b07a42c01.camel@linaro.org>

Hi Vinod,

On Sun, 2024-12-08 at 21:09 +0530, Vinod Koul wrote:
> On 05-12-24, 09:04, Greg KH wrote:
> > On Thu, Dec 05, 2024 at 07:33:16AM +0000, Andr? Draszik wrote:
> > > We currently don't gate the power to the SS phy in phy_exit().
> > > 
> > > Shuffle the code slightly to ensure the power is gated to the SS phy as
> > > well.
> > > 
> > > Fixes: 32267c29bc7d ("phy: exynos5-usbdrd: support Exynos USBDRD 3.1 combo phy (HS & SS)")
> > > CC: stable at vger.kernel.org?# 6.11+
> > 
> > Why is a patch 5/8 a stable thing?? If this is such an important bugfix,
> > it should be sent separately as a 1/1 patch, right?
> 
> Correct, one should move fixes to top of the series..

Thanks Vinod, and sorry for that - separated out as per Greg's
request here:
https://lore.kernel.org/all/20241205-gs101-usb-phy-fix-v4-1-0278809fb810 at linaro.org/

Cheers,
Andre'



From angelogioacchino.delregno at collabora.com  Mon Dec  9 01:56:18 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 10:56:18 +0100
Subject: [PATCH v2 14/15] drm/mediatek: mtk_hdmi_common: Add OP_HDMI,
 vendor and product strings
In-Reply-To: <6697eef88677950d36fbfbd6676f82f291621159.camel@mediatek.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-15-angelogioacchino.delregno@collabora.com>
 <6697eef88677950d36fbfbd6676f82f291621159.camel@mediatek.com>
Message-ID: <7a4f8b11-e840-4e33-a6e7-4f58601ed31c@collabora.com>

Il 09/12/24 10:09, CK Hu (???) ha scritto:
> Hi, Angelo:
> 
> On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>
>>
>> In preparation for adding the HDMI TX v2 driver, and to allow
>> a future modernization of the HDMI v1 one, perform changes
>> that enable the usage of the HDMI Helpers provided by DRM.
>>
>> Check if the HDMI driver provides the function pointers to
>> hdmi_{clear,write}_infoframe used by the HDMI Helper API and,
>> if present, add DRM_BRIDGE_OP_HDMI to the drm_bridge ops,
>> enabling the drm API to register the bridge as HDMI and to use
>> the HDMI Helper functions.
>>
>> Moreover, as part of data exclusively used (in the context of
>> HDMI bridges) by the helpers, assign the vendor "MediaTek" and
>> product "On-Chip HDMI" strings to the drm_bridge struct.
>>
>> If the hdmi_{write,clear}_infoframe pointers are not assigned,
>> vendor and product strings and HDMI helpers will not be used,
>> hence this commit brings no functional changes to drivers that
>> have not been refactored to use the new helpers.
>>
>> This also means that, in the current state, there is effectively
>> no functional change to mtk_hdmi and its other components.
> 
> OP_HDMI is for v2.
> vendor and product strings is for both v1 and v2.
> So separate this patch to two patches.
> 

They're both for v2, because only v2 uses the HDMI helpers, while v1 does not.

Cheers,
Angelo

> Regards,
> CK
> 
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
>>   drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
>> index 4f708b04f5e8..0f60842462b0 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
>> @@ -408,9 +408,16 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
>>
>>          hdmi->bridge.funcs = ver_conf->bridge_funcs;
>>          hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
>> +
>> +       if (ver_conf->bridge_funcs->hdmi_write_infoframe &&
>> +           ver_conf->bridge_funcs->hdmi_clear_infoframe)
>> +               hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI;
>> +
>>          hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
>>          hdmi->bridge.of_node = pdev->dev.of_node;
>>          hdmi->bridge.ddc = hdmi->ddc_adpt;
>> +       hdmi->bridge.vendor = "MediaTek";
>> +       hdmi->bridge.product = "On-Chip HDMI";
>>
>>          ret = devm_drm_bridge_add(dev, &hdmi->bridge);
>>          if (ret)
>> --
>> 2.47.0
>>
> 




From ravi at prevas.dk  Mon Dec  9 01:59:44 2024
From: ravi at prevas.dk (Rasmus Villemoes)
Date: Mon, 09 Dec 2024 10:59:44 +0100
Subject: [PATCH 02/10] compiler.h: add is_const() as a replacement of
 __is_constexpr()
In-Reply-To: <CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com>
	(Linus Torvalds's message of "Sat, 7 Dec 2024 10:19:34 -0800")
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
	<20241203-is_constexpr-refactor-v1-2-4e4cbaecc216@wanadoo.fr>
	<1d807c7471b9434aa8807e6e86c964ec@AcuMS.aculab.com>
	<CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>
	<9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com>
	<CAHk-=wjmeU6ahyuwAymqkSpxX-gCNa3Qc70UXjgnxNiC8eiyOw@mail.gmail.com>
	<CAMZ6Rq+SzTA25XcMZnMnOJcrrq1VZpeT1xceinarqbXgDDo8VA@mail.gmail.com>
	<CAHk-=wiP8111QZZJNbcDNsYQ_JC-xvwRKr0qV9UdKn3HKK+-4Q@mail.gmail.com>
	<d23fe8a5dbe84bfeb18097fdef7aa4c4@AcuMS.aculab.com>
	<CAHk-=win8afdcergvJ6f2=rRrff8giGUW62qmYs9Ae6aw=wcnA@mail.gmail.com>
	<0f5c07b827c3468c8fa3928a93a98bfa@AcuMS.aculab.com>
	<e806dd51b1ac4e289131297fbf30fc37@AcuMS.aculab.com>
	<CAMZ6RqLOR3aCRW_js2agV+VFiHdazb4S2+NdT5G4=WbDKNB8bA@mail.gmail.com>
	<b1ff4a65594a4d39b2e9b8b44770214e@AcuMS.aculab.com>
	<CAMZ6RqJFReLJTd-O8s02oQNeB0SPQh3C-Mg+Nif5vMB9gFtQww@mail.gmail.com>
	<CAHk-=wjpN4GWtnsWQ8XJvf=gBQ3UvBk512xK1S35=nGXA6yTiw@mail.gmail.com>
Message-ID: <87ldwpgorz.fsf@prevas.dk>

On Sat, Dec 07 2024, Linus Torvalds <torvalds at linux-foundation.org> wrote:

> On Sat, 7 Dec 2024 at 04:24, Vincent Mailhol <vincent.mailhol at gmail.com> wrote:
>>
>> > No good - expands everything twice.
>>
>> And? __is_const_zero() does not evaluate its arguments, so no side effect:
>
> No, the problem is literally the expansion.
>
> Double expansion of these fundamental helpers gets exponential,
> because they are used in various nested ways in other fundamental
> helpers.
>
> That's why we then spent so much effort on trying to clean up the
> min/max macros, because a single line of code would expand to
> literally tens of megabytes of horrific expansions.
>
> And the problem with these things is that you can't make them inline
> functions, so they have to be macros, and then you build up other
> macros using them (like that "clamp()" macro), and it really gets
> horrendous and affects the build time.
>
> And yes, it is very sad. Particularly since a compiler would have a
> really easy time with some nice helper builtins.
>
> Of course, often the compiler *does* have helper builtins, but we
> can't use them, because they aren't *quite* the right thing.

One thing I've been thinking about when all this comes up is: What if
the compilers gave us (and the same for _min):

  __builtin_max(T, e1, e2, ...)
  __builtin_max(e1, e2, ...)

with T being a type, e1... expressions, the latter being the former with
T being the result of usual promotion on the types of the expressions,
and the former having these semantics:

(1) If all the expressions are ICE, so is the whole thing.

(2) It's a compile-time error if the values of the expressions are not
    guaranteed to fit in T (that also applies in case (1)), but this
    should not be thrown by the front-end but only after optimizations
    have had a chance.

(3) Obviously: Every expression is evaluated exactly once and the result
    is the maximum of those, of type T.

For (2), I'd expect trivial value-range analysis to allow something like

  int x;

  ...
  if (x < 0)
    bail;
  size_t y = max(x, sizeof(foo));

Of course, specifying exactly which optimizations one can rely on having
been applied is impossible, but it's the same with our current
BUILD_BUG_ON() - many of them would trigger at -O0.

Then we could just have _one_ simple #define max __builtin_max , which
would work at file-scope, automatically have max3 etc. (because I'd
imagine it would not be much harder for the compiler to just provide the
variadic version if it has code to compute the max of two already), and
none of the preprocessor issues would apply.

Dear Santa: Pretty please?

Rasmus

Footnotes:

This is of course very kernel-centric. A compiler developer
doing this would probably have to think about "what if floating point
types are in the mix". I wouldn't mind if that was just disallowed, but
I can see how that might be a bit odd. I don't think it's hard to amend
the rules to that case - rule 2 could probably be used as-is, and (3)
could say "if any expr are NaN, so is the whole thing" (and if one cares
which NaN, just the first among the expressions); inf values don't need
special treatment wrt. min/max.

With my math hat on, I'd want the zero-expressions variant
__builtin_max(int) to evaluate to INT_MIN ('cause that's the neutral
element for the binary max of two ints) and similarly for other types,
but it's probably better to just require at least two expressions.


From james.clark at linaro.org  Mon Dec  9 02:01:45 2024
From: james.clark at linaro.org (James Clark)
Date: Mon, 9 Dec 2024 10:01:45 +0000
Subject: [PATCH v2] perf vendor events arm64: Add FUJITSU-MONAKA pmu event
In-Reply-To: <20241111064843.3003093-1-fj5100bi@fujitsu.com>
References: <20241111064843.3003093-1-fj5100bi@fujitsu.com>
Message-ID: <ee89c235-a126-4874-994d-b2489eb1c00f@linaro.org>



On 11/11/2024 6:48 am, Yoshihiro Furudera wrote:
>      Add pmu events for FUJITSU-MONAKA.
>      And, also updated common-and-microarch.json and recommended.json.
> 
>      FUJITSU-MONAKA Specification URL:
>      https://github.com/fujitsu/FUJITSU-MONAKA
> 
> Signed-off-by: Akio Kakuno <fj3333bs at aa.jp.fujitsu.com>
> Signed-off-by: Yoshihiro Furudera <fj5100bi at fujitsu.com>
> ---
> Changes in v2:
> - Change "SVE_INT64_DIV_SPEC" to "SVE_INT_DIV64_SPEC" in tools/perf/pmu-events/arch/arm64/fujitsu/monaka/sve.json.
> - Link to v1: https://lore.kernel.org/all/20241111024529.2985894-1-fj5100bi at fujitsu.com/
> 
>   .../arch/arm64/common-and-microarch.json      | 858 ++++++++++++++++++
>   .../fujitsu/monaka/cycle_accounting.json      | 146 +++
>   .../arch/arm64/fujitsu/monaka/energy.json     |  20 +
>   .../arch/arm64/fujitsu/monaka/exception.json  |  32 +
>   .../arm64/fujitsu/monaka/fp_operation.json    | 194 ++++
>   .../arch/arm64/fujitsu/monaka/gcycle.json     | 116 +++
>   .../arch/arm64/fujitsu/monaka/general.json    |   8 +
>   .../arch/arm64/fujitsu/monaka/hwpf.json       |  62 ++
>   .../arch/arm64/fujitsu/monaka/l1d_cache.json  | 101 +++
>   .../arch/arm64/fujitsu/monaka/l1i_cache.json  |  47 +
>   .../arch/arm64/fujitsu/monaka/l2_cache.json   | 146 +++
>   .../arch/arm64/fujitsu/monaka/l3_cache.json   | 185 ++++
>   .../arch/arm64/fujitsu/monaka/ll_cache.json   |   8 +
>   .../arch/arm64/fujitsu/monaka/memory.json     |   8 +
>   .../arch/arm64/fujitsu/monaka/pipeline.json   | 230 +++++
>   .../arch/arm64/fujitsu/monaka/retired.json    |  29 +
>   .../arm64/fujitsu/monaka/spec_operation.json  | 158 ++++
>   .../arch/arm64/fujitsu/monaka/stall.json      |  83 ++
>   .../arch/arm64/fujitsu/monaka/sve.json        | 146 +++
>   .../arch/arm64/fujitsu/monaka/tlb.json        | 404 +++++++++
>   .../arch/arm64/fujitsu/monaka/trace.json      |  20 +
>   tools/perf/pmu-events/arch/arm64/mapfile.csv  |   1 +
>   .../pmu-events/arch/arm64/recommended.json    |   6 +
>   23 files changed, 3008 insertions(+)
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/cycle_accounting.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/energy.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/exception.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/fp_operation.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/gcycle.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/hwpf.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/l1d_cache.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/l1i_cache.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/l2_cache.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/l3_cache.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/ll_cache.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/memory.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/pipeline.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/retired.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/spec_operation.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/stall.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/sve.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/tlb.json
>   create mode 100644 tools/perf/pmu-events/arch/arm64/fujitsu/monaka/trace.json
> 
> diff --git a/tools/perf/pmu-events/arch/arm64/common-and-microarch.json b/tools/perf/pmu-events/arch/arm64/common-and-microarch.json
> index 492083b99256..50fc4b2df361 100644
> --- a/tools/perf/pmu-events/arch/arm64/common-and-microarch.json
> +++ b/tools/perf/pmu-events/arch/arm64/common-and-microarch.json
> @@ -533,6 +533,12 @@
>           "EventName": "SVE_INST_SPEC",
>           "BriefDescription": "SVE operations speculatively executed"
>       },
> +    {
> +        "PublicDescription": "This event counts architecturally executed Advanced SIMD and SVE operations.",
> +        "EventCode": "0x8007",
> +        "EventName": "ASE_SVE_INST_SPEC",
> +        "BriefDescription": "This event counts architecturally executed Advanced SIMD and SVE operations."
> +    },

Hi Yoshihiro,

You don't need to duplicate the descriptions if they are the same. Just 
BriefDescription is enough and it will show for both normal and verbose 
mode.

Also in the common files, we're using the description strings from the 
Arm ARM. I noticed that the ones from your spec are slightly different. 
This is ok for now, but if we add any new Arm cores that use the same 
events this description may get overwritten. For example 
ASE_SVE_INST_SPEC in the Arm ARM is currently "Operation speculatively 
executed, Advanced SIMD or SVE".

If you have any actual relevant details that are different from the 
common string, you should put them in .../arch/arm64/fujitsu/monaka. But 
if you are ok with the potential overwrite (which looks like it should 
be ok) then you can leave them as is.

[...]

> diff --git a/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json b/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
> new file mode 100644
> index 000000000000..80bf17fb8f4c
> --- /dev/null
> +++ b/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
> @@ -0,0 +1,8 @@
> +[
> +    {
> +        "ArchStdEvent": "CPU_CYCLES"
> +    },

Other cores put CPU_CYCLES in bus.json. For user friendlyness I would 
put the common ones into the same existing groups. The same issue 
applies for some other common events.


Thanks
James



From angelogioacchino.delregno at collabora.com  Mon Dec  9 02:03:23 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 11:03:23 +0100
Subject: [PATCH 0/5] MT8516/MT8167 dtsi fixes
In-Reply-To: <VVS3OS.MZCWW6ICFFUB3@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
 <7bf536a5-30c1-43d8-9ea3-3aaea65c6b0a@collabora.com>
 <VVS3OS.MZCWW6ICFFUB3@packett.cool>
Message-ID: <c7407eef-d5dd-4380-ba5e-1defa37ee742@collabora.com>

Il 07/12/24 04:11, Val Packett ha scritto:
> 
> On Thu, Dec 5 2024 at 01:27:01 PM +01:00:00, AngeloGioacchino Del Regno 
> <angelogioacchino.delregno at collabora.com> wrote:
>>> I strongly suggest you to also send one that achieves basic boot with UART console
>> as a first step for upstreaming your board, and then go for incremental changes
>> everytime you get a new feature working.
> 
> Wanted to get the PMIC in first but sure, could try splitting out the initial 
> version without the PMIC.
> 

We all want to get XYZ in first, but then, you'll see that sometimes having at
least something will help you justify other changes....

If there's nothing upstream, understanding your changes becomes increasingly
difficult (depending on the nature of those changes, of course) - so... just
take the advice: sending the initial DT will help you later in the process ;-)

> Oh! One dts/dtsi question: pretty much all MTK devices so far have all pinctrl 
> configurations defined per-device. But on this SoC, pin assignments have their 
> "canonical" function in the pin name e.g.: MT8167_PIN_58_SDA0__FUNC_SDA0_0 and on 
> this device they are used as-is. Would it be fine to place these default pinctrl 
> configs for SD/MMC, I2C etc. in the SoC dtsi?
> 

No, because even though this is the default on many boards, it's still something
board specific, as other boards may define different functions.

Please define that in your board DT.

>>> Generally, if the patches are only simple additions, you could send the original
>> patches without any author variation (and fixing that MT6392_IRQ_numbers enum
>> in the original ones because lower case please!) and then your patches on top
>> with your additions.
> 
> Right, I was mostly unsure if the email workflow supported just sending someone 
> else's patches, but I guess that was silly - of course git-send-email should do the 
> right thing!
> 
>> The upstream driver just gained support for configuring the display paths
>> entirely in the devicetree as those are obviously device specific.
>>
>> You can make use of that for upstreaming your tablet after adding the display
>> nodes (and bindings, if required) as if you go for the default configuration
>> that's probably not going to work because it's for the pumpkin boards which
>> will most probably have a different display pipeline compared to your board.
> 
> The pipeline seems to be the same.. The pumpkin board was brought up with DSI as 
> well, the main pipeline I can find in the Android source is the same (+ PWM).
> 
> I am still struggling to get it to work though: DSI command mode configuration gets 
> acknowledged fine, but in burst mode, the vblank never arrives. Tried fiddling with 
> various things (CMDQ or not, mutex as vblank source since there was an Android 
> commit doing that, etc.), nothing helped.
> 

DSI command mode is not supported upstream - only video mode... and that's why you
can't get your display to work. There's no WDMA driver...

Convert it to video mode and it's gonna work just perfect :-)

P.S.: Also check if your mmsys+mutex configuration is correct!

>>> By the way, is anyone familiar with PSCI cpuidle/hot-unplug issues on
>>> Mediatek Android devices from around this time? [..]
>>
>> I did have some issues with an older bootloader on the Xperia M5 smartphone
>> and would even lock up at boot, because on the old firmwares the power
>> domains for the CPUs are not managed automatically by FW.
> 
> Interesting, thanks for the pointer!
> 
> In the Android kernel sources I could find though, there are no CPU domains in the 
> mtk-scpsys-mt8167 driver, and the only references I could even find to the related 
> register bits are from code that *reads* the status of the CPU power domains to 
> make decisions about sleep states (only_one_cpu_online in mtk_idle). Trying to add 
> those to the driver anyway, did not succeed so far.
> 

Downstream, you will find references to "mtcmos" (or anyway cpu mtcmos) - that's
how power domains are called there (I think. At least, in older downstream kernels
that's how they're called - and that's the "real" hw name btw).

Cheers,
Angelo

> ~val
> 
> 
> 



From peterz at infradead.org  Mon Dec  9 02:03:35 2024
From: peterz at infradead.org (Peter Zijlstra)
Date: Mon, 9 Dec 2024 11:03:35 +0100
Subject: [RFC PATCH 08/16] mm: Introduce kernel_pgtables_set_pkey()
In-Reply-To: <20241206101110.1646108-9-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-9-kevin.brodsky@arm.com>
Message-ID: <20241209100335.GH21636@noisy.programming.kicks-ass.net>

On Fri, Dec 06, 2024 at 10:11:02AM +0000, Kevin Brodsky wrote:
> kernel_pgtables_set_pkey() allows setting the pkey of all page table
> pages in swapper_pg_dir, recursively. This will be needed by
> kpkeys_hardened_pgtables, as it relies on all PTPs being mapped with
> a non-default pkey. Those initial kernel page tables cannot
> practically be assigned a non-default pkey right when they are
> allocated, so mutating them during (early) boot is required.
> 
> Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
> ---
> 
> It feels that some sort of locking is called for in
> kernel_pgtables_set_pkey(), but I couldn't figure out what would be
> appropriate.

init_mm.page_table_lock is typically the one used to serialize kernel
page tables IIRC.


From towinchenmi at gmail.com  Mon Dec  9 02:07:55 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 9 Dec 2024 18:07:55 +0800
Subject: [PATCH v2 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <bqn4tddl3kgle7zlamgaqlh45pizw6gf5qjwlmcsbkb6fx343l@tf5w63xursi2>
References: <20241207130433.30351-1-towinchenmi@gmail.com>
 <20241207130433.30351-3-towinchenmi@gmail.com>
 <bqn4tddl3kgle7zlamgaqlh45pizw6gf5qjwlmcsbkb6fx343l@tf5w63xursi2>
Message-ID: <551941de-b9a4-4353-8bb2-0bfc3304ef87@gmail.com>



Krzysztof Kozlowski ? 2024/12/9 ??5:22 ??:
> On Sat, Dec 07, 2024 at 09:03:15PM +0800, Nick Chan wrote:
>> Add driver for backlight controllers attached via Apple DWI 2-wire
>> interface, which is found on some Apple iPhones, iPads and iPod touches
>> with a LCD display.
>>
>> Signed-off-by: Nick Chan <towinchenmi at gmail.com>
>> ---
>>  drivers/video/backlight/Kconfig  |  12 +++
>>  drivers/video/backlight/Makefile |   1 +
>>  drivers/video/backlight/dwi_bl.c | 124 +++++++++++++++++++++++++++++++
>>  3 files changed, 137 insertions(+)
>>  create mode 100644 drivers/video/backlight/dwi_bl.c
>>
>> diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
>> index 3614a5d29c71..e64cc3d51ac5 100644
>> --- a/drivers/video/backlight/Kconfig
>> +++ b/drivers/video/backlight/Kconfig
>> @@ -166,6 +166,18 @@ config BACKLIGHT_EP93XX
>>  	  To compile this driver as a module, choose M here: the module will
>>  	  be called ep93xx_bl.
>>  
>> +config BACKLIGHT_APPLE_DWI
>> +	tristate "Apple DWI 2-Wire Interface Backlight Driver"
>> +	depends on ARCH_APPLE || COMPILE_TEST
>> +	default y
>> +	help
>> +          Say Y to enable the backlight driver for backlight controllers
>> +          attached via the Apple DWI 2-wire interface which is found in some
>> +          Apple iPhones, iPads and iPod touches.
> 
> Mixed/messed indentation. Some spaces?
Ack. Will be fixed for v4.

> 
>> +
>> +	  To compile this driver as a module, choose M here: the module will
>> +	  be called dwi_bl.
>> +
>>  config BACKLIGHT_IPAQ_MICRO
>>  	tristate "iPAQ microcontroller backlight driver"
>>  	depends on MFD_IPAQ_MICRO
>> diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
>> index 8fc98f760a8a..0a569d7f0210 100644
>> --- a/drivers/video/backlight/Makefile
>> +++ b/drivers/video/backlight/Makefile
>> @@ -28,6 +28,7 @@ obj-$(CONFIG_BACKLIGHT_BD6107)		+= bd6107.o
>>  obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE)	+= backlight.o
>>  obj-$(CONFIG_BACKLIGHT_DA903X)		+= da903x_bl.o
>>  obj-$(CONFIG_BACKLIGHT_DA9052)		+= da9052_bl.o
>> +obj-$(CONFIG_BACKLIGHT_APPLE_DWI)	+= dwi_bl.o
> 
> Please do not introduce other sorting way - it is sorted by config name.
> Which will also point you to apple_bl.o and need of explaining the
> differences, e.g. why this cannot be one driver.

apple_bl is a driver backlight controllers on a PCI bus on Intel Macs,
which is
completely different from the Samsung-derived DWI block this driver
deals with.
This will be explained in the commit message for v4.

> 
> 
>>  obj-$(CONFIG_BACKLIGHT_EP93XX)		+= ep93xx_bl.o
>>  obj-$(CONFIG_BACKLIGHT_GPIO)		+= gpio_backlight.o
>>  obj-$(CONFIG_BACKLIGHT_HP680)		+= hp680_bl.o
>> diff --git a/drivers/video/backlight/dwi_bl.c b/drivers/video/backlight/dwi_bl.c
>> new file mode 100644
>> index 000000000000..d4bfd74b3129
>> --- /dev/null
>> +++ b/drivers/video/backlight/dwi_bl.c
>> @@ -0,0 +1,124 @@
>> +// SPDX-License-Identifier: GPL-2.0 OR MIT
>> +/*
>> + * Driver for backlight controllers attached via Apple DWI 2-wire interface
>> + *
>> + * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/io.h>
>> +#include <linux/backlight.h>
>> +
>> +#define DWI_BL_CTL			0x0
>> +#define DWI_BL_CTL_SEND1		BIT(0)
>> +#define DWI_BL_CTL_SEND2		BIT(4)
>> +#define DWI_BL_CTL_SEND3		BIT(5)
>> +#define DWI_BL_CTL_LE_DATA		BIT(6)
>> +/* Only used on Apple A9 and later */
>> +#define DWI_BL_CTL_SEND4		BIT(12)
>> +
>> +#define DWI_BL_CMD			0x4
>> +#define DWI_BL_CMD_TYPE			GENMASK(31, 28)
>> +#define DWI_BL_CMD_TYPE_SET_BRIGHTNESS	0xa
>> +#define DWI_BL_CMD_DATA			GENMASK(10, 0)
>> +
>> +#define DWI_BL_CTL_SEND			(DWI_BL_CTL_SEND1 | \
>> +					 DWI_BL_CTL_SEND2 | \
>> +					 DWI_BL_CTL_SEND3 | \
>> +					 DWI_BL_CTL_LE_DATA | \
>> +					 DWI_BL_CTL_SEND4)
>> +
>> +#define DWI_BL_MAX_BRIGHTNESS		2047
>> +
>> +struct apple_dwi_bl {
>> +	void __iomem *base;
>> +};
>> +
>> +static int dwi_bl_update_status(struct backlight_device *bl)
>> +{
>> +	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
>> +
>> +	int brightness = backlight_get_brightness(bl);
>> +
>> +	u32 cmd = 0;
>> +
>> +	cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
>> +	cmd |= FIELD_PREP(DWI_BL_CMD_TYPE, DWI_BL_CMD_TYPE_SET_BRIGHTNESS);
>> +
>> +	writel(cmd, dwi_bl->base + DWI_BL_CMD);
>> +	writel(DWI_BL_CTL_SEND, dwi_bl->base + DWI_BL_CTL);
>> +
>> +	return 0;
>> +}
>> +
>> +static int dwi_bl_get_brightness(struct backlight_device *bl)
>> +{
>> +	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
>> +
>> +	u32 cmd = readl(dwi_bl->base + DWI_BL_CMD);
>> +
>> +	return FIELD_GET(DWI_BL_CMD_DATA, cmd);
>> +}
>> +
>> +static const struct backlight_ops dwi_bl_ops = {
>> +	.options = BL_CORE_SUSPENDRESUME,
>> +	.get_brightness = dwi_bl_get_brightness,
>> +	.update_status	= dwi_bl_update_status
>> +};
>> +
>> +static int dwi_bl_probe(struct platform_device *dev)
>> +{
>> +	struct apple_dwi_bl *dwi_bl;
>> +	struct backlight_device *bl;
>> +	struct backlight_properties props;
>> +	struct resource *res;
>> +
>> +	dwi_bl = devm_kzalloc(&dev->dev, sizeof(struct apple_dwi_bl), GFP_KERNEL);
> 
> sizeof(*)
> 
>> +	if (!dwi_bl)
>> +		return -ENOMEM;
>> +
>> +	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
>> +	if (!res)
>> +		return -ENXIO;
>> +
>> +	dwi_bl->base = devm_ioremap_resource(&dev->dev, res);
> 
> Use helper for these two, devm_platform_get_and_ioremap_resource() or
> similar.
Ack. Will be fixed for v4.

> 
> Best regards,
> Krzysztof
> 

Nick Chan


From dmitry.baryshkov at linaro.org  Mon Dec  9 02:13:15 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 9 Dec 2024 12:13:15 +0200
Subject: [EXT] Re: [PATCH v18 6/8] phy: freescale: Add DisplayPort/HDMI
 Combo-PHY driver for i.MX8MQ
In-Reply-To: <PAXPR04MB94488E0A549E519CEB8AA40EF43C2@PAXPR04MB9448.eurprd04.prod.outlook.com>
References: <cover.1730172244.git.Sandor.yu@nxp.com> <411e42c70e71dce33a80059f663fb6c58fb2ac8c.1730172244.git.Sandor.yu@nxp.com>
 <efciuvoptv7qxwauswfseb6zlt5w4fmjdbm3huxfsn63a6bm7u@kfgkkvqoz5x4>
 <PAXPR04MB9448F638D47B5495CF78007AF4522@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <z6p6bewmykmufsghdojr4lvziurmmfpnrr5m4w3pfjlqzobpwr@zq2d2ukjvtac>
 <PAXPR04MB9448D68A5CA9755036E9B23DF42F2@PAXPR04MB9448.eurprd04.prod.outlook.com>
 <foi2sizfkppmunq4yqt4pex47alsvsjyqi3rk32fwyz4f5xepn@zdsx74bzzda4> <PAXPR04MB94488E0A549E519CEB8AA40EF43C2@PAXPR04MB9448.eurprd04.prod.outlook.com>
Message-ID: <CAA8EJprUKXxGbtP6M95Ep=2Lj2NSiUN31QNaysNJAzvO5g2LdQ@mail.gmail.com>

On Mon, 9 Dec 2024 at 10:16, Sandor Yu <sandor.yu at nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > Sent: 2024?11?30? 16:30
> > To: Sandor Yu <sandor.yu at nxp.com>
> > Cc: 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;
> > mripard at kernel.org; kernel at pengutronix.de; dl-linux-imx
> > <linux-imx at nxp.com>; Oliver Brown <oliver.brown at nxp.com>;
> > alexander.stein at ew.tq-group.com; sam at ravnborg.org
> > Subject: Re: [EXT] Re: [PATCH v18 6/8] phy: freescale: Add DisplayPort/HDMI
> > Combo-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
> >
> >
> > On Tue, Nov 26, 2024 at 02:12:19PM +0000, Sandor Yu wrote:
> > >
> > > >
> > > > On Tue, Nov 05, 2024 at 02:05:51PM +0000, Sandor Yu wrote:
> > > > > >
> > > > > > On Tue, Oct 29, 2024 at 02:02:14PM +0800, Sandor Yu wrote:
> > > > > > > Add Cadence HDP-TX DisplayPort and 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.
> > > > > > > DisplayPort or HDMI PHY mode is configured in the driver.
> > > > > > >
> > > > > > > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > > > > > > Signed-off-by: Alexander Stein
> > > > > > > <alexander.stein at ew.tq-group.com>
> > > > > > > ---
> > > > > > > v17->v18:
> > > > > > > - fix build error as code rebase to latest kernel version.
> > > > > > >
> > > > > > >  drivers/phy/freescale/Kconfig                |   10 +
> > > > > > >  drivers/phy/freescale/Makefile               |    1 +
> > > > > > >  drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c | 1337
> > > > > > ++++++++++++++++++
> > > > > > >  3 files changed, 1348 insertions(+)  create mode 100644
> > > > > > > drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
> > > > > > >
> > > > > > > diff --git a/drivers/phy/freescale/Kconfig
> > > > > > > b/drivers/phy/freescale/Kconfig index
> > > > > > > dcd9acff6d01a..2b1210367b31c
> > > > > > > 100644
> > > > > > > --- a/drivers/phy/freescale/Kconfig
> > > > > > > +++ b/drivers/phy/freescale/Kconfig
> > > >
> > > > [...]
> > > >
> > > > I'm sorry, my email client cut the email.
> > > >
> > > > > > > +static int cdns_hdptx_dp_configure(struct phy *phy,
> > > > > > > +                                union phy_configure_opts
> > > > *opts) {
> > > > > > > +     struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
> > > > > > > +
> > > > > > > +     cdns_phy->dp.link_rate = opts->dp.link_rate;
> > > > > > > +     cdns_phy->dp.lanes = opts->dp.lanes;
> > > > > >
> > > > > > Shouldn't this be conditional on set_rate / set_lanes ?
> > > > >
> > > > > PHY do not support reconfigure link rate and lane count.
> > > >
> > > > So, you don't support reconfiguring the rate / count, but you still
> > > > copy the new rate and lanes into your driver data. That sounds strange.
> > >
> > > The PHY will use link rate and lane count to configure its registers
> >
> > I'm not sure if I follow it. Do you mean that rate / count configuration is static?
>
> In DP controller driver, rate and lane count are determined during link training.
> These two parameters are fixed in the DP PHY driver and cannot be modified.

Yes, llane count, rate and swing are determined during link training.
However it's not a part of the PHY's job to settle on that. Usually it
is the DP driver who determines these params and then calls
phy_configure() to set necessary params for the next iteration of
clock recovery attempt or link training step. As a part of the calling
API the DP driver doesn't have to pass full configuration. Instead DP
driver sets only required parts of the PHY configuration and uses
these flags to specify which part of the PHY configuration should be
updated and which parts were not set and must be ignored.

-- 
With best wishes
Dmitry


From angelogioacchino.delregno at collabora.com  Mon Dec  9 02:14:29 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 11:14:29 +0100
Subject: [PATCH 1/2] dt-bindings: mmc: mtk-sd: Document compatibles that
 need two register ranges
In-Reply-To: <20241204092855.1365638-2-wenst@chromium.org>
References: <20241204092855.1365638-1-wenst@chromium.org>
 <20241204092855.1365638-2-wenst@chromium.org>
Message-ID: <456b8050-7a7c-4f5e-8ace-5e88e02e86ba@collabora.com>

Il 04/12/24 10:28, Chen-Yu Tsai ha scritto:
> Besides the MT8183's MMC controller and all its compatible derivatives,
> the recently added MT7986 and MT8196 also require two register ranges.
> This is based on the actual device trees.
> 
> Properly enforce this in the binding.
> 
> Fixes: 4a8bd2b07d88 ("dt-bindings: mmc: mtk-sd: Add mt7988 SoC")
> Fixes: 58927c9dc4ab ("dt-bindings: mmc: mtk-sd: Add support for MT8196")
> Cc: Frank Wunderlich <frank-w at public-files.de>
> Cc: Andy-ld Lu <andy-ld.lu at mediatek.com>
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Dec  9 02:14:29 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 11:14:29 +0100
Subject: [PATCH 2/2] mmc: mtk-sd: Limit getting top_base to SoCs that
 require it
In-Reply-To: <20241204092855.1365638-3-wenst@chromium.org>
References: <20241204092855.1365638-1-wenst@chromium.org>
 <20241204092855.1365638-3-wenst@chromium.org>
Message-ID: <6b4f98ab-5bfe-406d-a0d4-46d36ed10df7@collabora.com>

Il 04/12/24 10:28, Chen-Yu Tsai ha scritto:
> Currently the mtk-sd driver tries to get and map the second register
> base, named top_base in the code, regardless of whether the SoC model
> actually has it or not. This produces confusing big error messages on
> the platforms that don't need it:
> 
>      mtk-msdc 11260000.mmc: error -EINVAL: invalid resource (null)
> 
> Limit it to the platforms that actually require it, based on their
> device tree entries, and properly fail if it is missing. There is
> no MMC node in the MT6779 dts, so it's currently unknown if that
> platform needs it or not.
> 

No, it doesn't require it. The controller is (very) similar to the one
found on MT6795 :-)

> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Can you please remove that "I don't know about mt6779" mention, now that
you do know?

Btw,

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/mmc/host/mtk-sd.c | 15 +++++++++++----
>   1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index e2c385853eef..1bb7044f4ca1 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -414,6 +414,7 @@ struct mtk_mmc_compatible {
>   	u8 clk_div_bits;
>   	bool recheck_sdio_irq;
>   	bool hs400_tune; /* only used for MT8173 */
> +	bool needs_top_base;
>   	u32 pad_tune_reg;
>   	bool async_fifo;
>   	bool data_tune;
> @@ -587,6 +588,7 @@ static const struct mtk_mmc_compatible mt7986_compat = {
>   	.clk_div_bits = 12,
>   	.recheck_sdio_irq = true,
>   	.hs400_tune = false,
> +	.needs_top_base = true,
>   	.pad_tune_reg = MSDC_PAD_TUNE0,
>   	.async_fifo = true,
>   	.data_tune = true,
> @@ -627,6 +629,7 @@ static const struct mtk_mmc_compatible mt8183_compat = {
>   	.clk_div_bits = 12,
>   	.recheck_sdio_irq = false,
>   	.hs400_tune = false,
> +	.needs_top_base = true,
>   	.pad_tune_reg = MSDC_PAD_TUNE0,
>   	.async_fifo = true,
>   	.data_tune = true,
> @@ -653,6 +656,7 @@ static const struct mtk_mmc_compatible mt8196_compat = {
>   	.clk_div_bits = 12,
>   	.recheck_sdio_irq = false,
>   	.hs400_tune = false,
> +	.needs_top_base = true,
>   	.pad_tune_reg = MSDC_PAD_TUNE0,
>   	.async_fifo = true,
>   	.data_tune = true,
> @@ -2887,9 +2891,13 @@ static int msdc_drv_probe(struct platform_device *pdev)
>   	if (IS_ERR(host->base))
>   		return PTR_ERR(host->base);
>   
> -	host->top_base = devm_platform_ioremap_resource(pdev, 1);
> -	if (IS_ERR(host->top_base))
> -		host->top_base = NULL;
> +	host->dev_comp = of_device_get_match_data(&pdev->dev);
> +
> +	if (host->dev_comp->needs_top_base) {
> +		host->top_base = devm_platform_ioremap_resource(pdev, 1);
> +		if (IS_ERR(host->top_base))
> +			return PTR_ERR(host->top_base);
> +	}
>   
>   	ret = mmc_regulator_get_supply(mmc);
>   	if (ret)
> @@ -2951,7 +2959,6 @@ static int msdc_drv_probe(struct platform_device *pdev)
>   	msdc_of_property_parse(pdev, host);
>   
>   	host->dev = &pdev->dev;
> -	host->dev_comp = of_device_get_match_data(&pdev->dev);
>   	host->src_clk_freq = clk_get_rate(host->src_clk);
>   	/* Set host parameters to mmc */
>   	mmc->ops = &mt_msdc_ops;




From dmitry.baryshkov at linaro.org  Mon Dec  9 02:15:26 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 9 Dec 2024 12:15:26 +0200
Subject: [PATCH v19 6/8] phy: freescale: Add DisplayPort/HDMI Combo-PHY
 driver for i.MX8MQ
In-Reply-To: <PAXPR04MB94488CEFA54F8AA193DC2BBDF43C2@PAXPR04MB9448.eurprd04.prod.outlook.com>
References: <cover.1732627815.git.Sandor.yu@nxp.com> <4ef8252825d7a962b440519fb17fdcd5dd817672.1732627815.git.Sandor.yu@nxp.com>
 <slkpvbemsrz5jv4cafp7k4pdj3smpl575w2dtmjoheoqqrh32j@2wi5564jzawg> <PAXPR04MB94488CEFA54F8AA193DC2BBDF43C2@PAXPR04MB9448.eurprd04.prod.outlook.com>
Message-ID: <CAA8EJpoKkOj2pBxi4QcVAVOwzaW=yVAyomOFv7-oAxPYamfa-A@mail.gmail.com>

On Mon, 9 Dec 2024 at 10:38, Sandor Yu <sandor.yu at nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > Sent: 2024?11?26? 22:43
> > To: Sandor Yu <sandor.yu at nxp.com>
> > Cc: 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;
> > mripard at kernel.org; kernel at pengutronix.de; dl-linux-imx
> > <linux-imx at nxp.com>; Oliver Brown <oliver.brown at nxp.com>;
> > alexander.stein at ew.tq-group.com; sam at ravnborg.org
> > Subject: [EXT] Re: [PATCH v19 6/8] phy: freescale: Add DisplayPort/HDMI
> > Combo-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
> >
> >
> > On Tue, Nov 26, 2024 at 10:11:51PM +0800, Sandor Yu wrote:
> > > Add Cadence HDP-TX DisplayPort and 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.
> > > DisplayPort or HDMI PHY mode is configured in the driver.
> > >
> > > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > > Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > > ---
> > > v18->v19:
> > > - Simplify the PLL tables by removing unused and constant data
> > > - Remove PHY power management, controller driver will handle them.
> > > - Remove enum dp_link_rate
> > > - Introduce read_pll_timeout.
> > > - Update clock management as devm_clk_get_enabled() introduced.
> > > - Remove cdns_hdptx_phy_init() and cdns_hdptx_phy_remove().
> > >
> > > v17->v18:
> > > - fix build error as code rebase to latest kernel version.
> > >
> > >  drivers/phy/freescale/Kconfig                |   10 +
> > >  drivers/phy/freescale/Makefile               |    1 +
> > >  drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c | 1237
> > ++++++++++++++++++
> > >  3 files changed, 1248 insertions(+)
> > >  create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
> > >
> > > diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> > > index dcd9acff6d01a..bbd17e9556cc3 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_HDPTX
> > > +     tristate "Freescale i.MX8MQ DP/HDMI PHY support"
> > > +     depends on OF && HAS_IOMEM
> > > +     depends on COMMON_CLK
> > > +     depends on CDNS_MHDP_HELPER
> >
> > You should not be depending on the symbol that can not be selected by
> > the user.
>
> OK.
>
> >
> > > +     select GENERIC_PHY
> > > +     help
> > > +       Enable this to support the Cadence HDPTX DP/HDMI PHY driver
> > > +       on i.MX8MQ SOC.
> > > +
> > >  config PHY_FSL_IMX8QM_HSIO
> > >       tristate "Freescale i.MX8QM HSIO PHY"
> > >       depends on OF && HAS_IOMEM
> > > diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
> > > index 658eac7d0a622..a946b87905498 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_HDPTX)   += phy-fsl-imx8mq-hdptx.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-hdptx.c
> > b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
> > > new file mode 100644
> > > index 0000000000000..e99487622d43c
> > > --- /dev/null
> > > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
> > > @@ -0,0 +1,1237 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/*
> > > + * Cadence DP/HDMI PHY driver
> > > + *
> > > + * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
> > > + */
> > > +#include <drm/bridge/cdns-mhdp-helper.h>
> >
> > Still, I'd ask for drivers/soc instead.
>
> If put it in drivers/soc, should I create a new directory called drivers/soc/cadence or put it in drivers/soc/imx?
>
> The mhdp helpers will share code between cdns-mhdp8501 and cdns-mhdp8546.
> I prefer creating a new directory, drivers/soc/cadence, but the problem is that cadence not a real SoC.

I think drivers/soc/cadence is fine. Please explain your decision in
the cover letter and in the commit message, this will help other
maintainers to understand you.

-- 
With best wishes
Dmitry


From towinchenmi at gmail.com  Mon Dec  9 02:22:17 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 9 Dec 2024 18:22:17 +0800
Subject: [PATCH v2 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <bqn4tddl3kgle7zlamgaqlh45pizw6gf5qjwlmcsbkb6fx343l@tf5w63xursi2>
References: <20241207130433.30351-1-towinchenmi@gmail.com>
 <20241207130433.30351-3-towinchenmi@gmail.com>
 <bqn4tddl3kgle7zlamgaqlh45pizw6gf5qjwlmcsbkb6fx343l@tf5w63xursi2>
Message-ID: <e06c5d7c-de3c-46ff-b2ee-8ed794577e70@gmail.com>



Krzysztof Kozlowski ? 2024/12/9 ??5:22 ??:
>> diff --git a/drivers/video/backlight/dwi_bl.c b/drivers/video/backlight/dwi_bl.c
>> new file mode 100644
>> index 000000000000..d4bfd74b3129
>> --- /dev/null
>> +++ b/drivers/video/backlight/dwi_bl.c
>> @@ -0,0 +1,124 @@
[...]
>> +
>> +	dwi_bl = devm_kzalloc(&dev->dev, sizeof(struct apple_dwi_bl), GFP_KERNEL);
> 
> sizeof(*)

Ack this change as well for v4.

> 
>> +	if (!dwi_bl)
>> +		return -ENOMEM;
[...]

Nick Chan


From peterz at infradead.org  Mon Dec  9 02:24:40 2024
From: peterz at infradead.org (Peter Zijlstra)
Date: Mon, 9 Dec 2024 11:24:40 +0100
Subject: [RFC PATCH 12/16] arm64: mm: Map p4d/pgd with privileged pkey
In-Reply-To: <20241206101110.1646108-13-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-13-kevin.brodsky@arm.com>
Message-ID: <20241209102440.GI21636@noisy.programming.kicks-ass.net>

On Fri, Dec 06, 2024 at 10:11:06AM +0000, Kevin Brodsky wrote:
> If CONFIG_KPKEYS_HARDENED_PGTABLES is enabled, map p4d/pgd pages
> using a privileged pkey (KPKEYS_PKEY_PGTABLES), so that they can
> only be written under guard(kpkeys_hardened_pgtables).
> 
> The case where pgd is not page-sized is not currently handled -
> this is pending support for pkeys in kmem_cache.
> 
> This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
> (default).

Should not this live in pagetable_*_[cd]tor() in generic code?


From peterz at infradead.org  Mon Dec  9 02:29:13 2024
From: peterz at infradead.org (Peter Zijlstra)
Date: Mon, 9 Dec 2024 11:29:13 +0100
Subject: [RFC PATCH 13/16] arm64: mm: Reset pkey in __tlb_remove_table()
In-Reply-To: <20241206101110.1646108-14-kevin.brodsky@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-14-kevin.brodsky@arm.com>
Message-ID: <20241209102913.GJ21636@noisy.programming.kicks-ass.net>

On Fri, Dec 06, 2024 at 10:11:07AM +0000, Kevin Brodsky wrote:
> Page table pages are typically freed via tlb_remove_table() and
> friends. Ensure that the linear mapping for those pages is reset to
> the default pkey when CONFIG_KPKEYS_HARDENED_PGTABLES is enabled.
> 
> This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
> (default).
> 
> Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
> ---
>  arch/arm64/include/asm/tlb.h | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
> index a947c6e784ed..d1611ffa6d91 100644
> --- a/arch/arm64/include/asm/tlb.h
> +++ b/arch/arm64/include/asm/tlb.h
> @@ -10,10 +10,14 @@
>  
>  #include <linux/pagemap.h>
>  #include <linux/swap.h>
> +#include <linux/kpkeys.h>
>  
>  static inline void __tlb_remove_table(void *_table)
>  {
> -	free_page_and_swap_cache((struct page *)_table);
> +	struct page *page = (struct page *)_table;
> +
> +	kpkeys_unprotect_pgtable_memory((unsigned long)page_address(page), 1);
> +	free_page_and_swap_cache(page);
>  }

Same as for the others, perhaps stick this in generic code instead of in
the arch code?


From angelogioacchino.delregno at collabora.com  Mon Dec  9 02:31:37 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 11:31:37 +0100
Subject: [v5,08/10] drm/bridge: lontium-lt9611: drop TMDS char rate check
 in mode_valid
In-Reply-To: <20241130-hdmi-mode-valid-v5-8-742644ec3b1f@linaro.org>
References: <20241130-hdmi-mode-valid-v5-8-742644ec3b1f@linaro.org>
Message-ID: <2484261d-5589-4707-b3f9-7df78b2935eb@collabora.com>

Il 30/11/24 02:52, Dmitry Baryshkov ha scritto:
> Drop manual check of the TMDS char rate in the mode_valid callback. This
> check is now being performed by the core.
> 
> Reviewed-by: Chen-Yu Tsai <wens at csie.org>
> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Dec  9 02:31:39 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 11:31:39 +0100
Subject: [v5,07/10] drm/display: bridge_connector: use
 drm_bridge_connector_mode_valid()
In-Reply-To: <20241130-hdmi-mode-valid-v5-7-742644ec3b1f@linaro.org>
References: <20241130-hdmi-mode-valid-v5-7-742644ec3b1f@linaro.org>
Message-ID: <5d722361-5ea3-4734-a2af-41aa8c2eab0b@collabora.com>

Il 30/11/24 02:52, Dmitry Baryshkov ha scritto:
> Use new drm_bridge_connector_mode_valid() helper if there is a HDMI
> bridge in the bridge chain. This removes the need to perform TMDS char
> rate check manually in the bridge driver.
> 
> Reviewed-by: Chen-Yu Tsai <wens at csie.org>
> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Dec  9 02:31:41 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 11:31:41 +0100
Subject: [v5,03/10] drm/tests: hdmi: return meaningful value from
 set_connector_edid()
In-Reply-To: <20241130-hdmi-mode-valid-v5-3-742644ec3b1f@linaro.org>
References: <20241130-hdmi-mode-valid-v5-3-742644ec3b1f@linaro.org>
Message-ID: <75b15251-f72e-4306-a90c-0b875f745b7d@collabora.com>

Il 30/11/24 02:52, Dmitry Baryshkov ha scritto:
> The set_connector_edid() function returns a bogus 0, performing the
> check on the connector->funcs->fill_modes() result internally. Make the
> function pass the fill_modes()'s return value to the caller and move
> corresponding checks to the caller site.
> 
> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Dec  9 02:31:42 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 11:31:42 +0100
Subject: [v5,04/10] drm/display: hdmi: add generic mode_valid helper
In-Reply-To: <20241130-hdmi-mode-valid-v5-4-742644ec3b1f@linaro.org>
References: <20241130-hdmi-mode-valid-v5-4-742644ec3b1f@linaro.org>
Message-ID: <0b5cbe50-12f8-4f7d-a410-811fc4063889@collabora.com>

Il 30/11/24 02:52, Dmitry Baryshkov ha scritto:
> Add drm_hdmi_connector_mode_valid(), generic helper for HDMI connectors.
> It can be either used directly or as a part of the .mode_valid callback.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Reviewed-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Dec  9 02:31:44 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 11:31:44 +0100
Subject: [v5,02/10] drm/tests: hdmi: rename connector creation function
In-Reply-To: <20241130-hdmi-mode-valid-v5-2-742644ec3b1f@linaro.org>
References: <20241130-hdmi-mode-valid-v5-2-742644ec3b1f@linaro.org>
Message-ID: <a1153976-41ce-43c8-b6c1-14b055e05e9f@collabora.com>

Il 30/11/24 02:52, Dmitry Baryshkov ha scritto:
> As pointed out by Maxime, the drm_atomic_helper_connector_hdmi_init()
> isn't a good name for a function inside KUnit tests. Rename it to
> drm_kunit_helper_connector_hdmi_init().
> 
> Suggested-by: Maxime Ripard <mripard at kernel.org>
> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Dec  9 02:31:52 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 11:31:52 +0100
Subject: [v5,01/10] drm/tests: hdmi: handle empty modes in
 find_preferred_mode()
In-Reply-To: <20241130-hdmi-mode-valid-v5-1-742644ec3b1f@linaro.org>
References: <20241130-hdmi-mode-valid-v5-1-742644ec3b1f@linaro.org>
Message-ID: <2cafa6a4-1f18-4891-9626-f7e5b83a4a3e@collabora.com>

Il 30/11/24 02:52, Dmitry Baryshkov ha scritto:
> If the connector->modes list is empty, then list_first_entry() returns a
> bogus entry. Change that to use list_first_entry_or_null().
> 
> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From wahrenst at gmx.net  Mon Dec  9 02:32:29 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon, 9 Dec 2024 11:32:29 +0100
Subject: [PATCH v11 3/3] ARM: dts: mxs: Add descriptions for imx287 based
 btt3-[012] devices
In-Reply-To: <20241119165236.69438f75@wsk>
References: <20241107085705.490940-1-lukma@denx.de>
 <20241107085705.490940-3-lukma@denx.de> <20241119165236.69438f75@wsk>
Message-ID: <c8fd371f-fd36-48c4-ad49-1e8f8db01383@gmx.net>

Am 19.11.24 um 16:52 schrieb Lukasz Majewski:
> Dear Community,
>
>> The btt3 device' HW revisions from 0 to 2 use imx287 SoC and are to
>> some extend similar to already upstreamed XEA devices, hence are
>> using common imx28-lwe.dtsi file.
>>
>> New, imx28-btt3.dtsi has been added to embrace common DTS
>> properties for different HW revisions for this device.
>>
>> As a result - changes introduced in imx28-btt3-[012].dts are
>> minimal.
>>
> Are there any more comments / suggestions for this patch set?
I've send my RB for this patch on October 31th for V10, but it didn't
made it into V11.


From sudeep.holla at arm.com  Mon Dec  9 02:33:37 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 9 Dec 2024 10:33:37 +0000
Subject: [PATCH v2 1/2] firmware: arm_scmi: get only min/max clock rates
In-Reply-To: <20241203173908.3148794-2-etienne.carriere@foss.st.com>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-2-etienne.carriere@foss.st.com>
Message-ID: <Z1bHgf_4qqZgSnDt@bogus>

On Tue, Dec 03, 2024 at 06:39:07PM +0100, Etienne Carriere wrote:
> Remove limitation of 16 clock rates max for discrete clock rates
> description when the SCMI firmware supports SCMI Clock protocol v2.0
> or later.
>
> Driver clk-scmi.c is only interested in the min and max clock rates.
> Get these by querying the first and last discrete rates with SCMI
> clock protocol message ID CLOCK_DESCRIBE_RATES since the SCMI
> specification v2.0 and later states that rates enumerated by this
> command are to be enumerated in "numeric ascending order" [1].
>
> Preserve the implementation that queries all discrete rates (16 rates
> max) to support SCMI firmware built on SCMI specification v1.0 [2]
> where SCMI Clock protocol v1.0 does not explicitly require rates
> described with CLOCK_DESCRIBE_RATES to be in ascending order.
>
> Link: https://developer.arm.com/documentation/den0056 [1]
> Link: https://developer.arm.com/documentation/den0056/a [2]
> Signed-off-by: Etienne Carriere <etienne.carriere at foss.st.com>
> ---

[...]

> +
> +static int scmi_clock_get_rates_bound(const struct scmi_protocol_handle *ph,
> +				      u32 clk_id, struct scmi_clock_info *clk)
> +{

This new function seem to have unwraped the scmi_iterator_ops(namely
prepare_message, update_state and process_response instead of reusing them.
Can you please explain why it wasn't possible to reuse them ?

--
Regards,
Sudeep


From m-malladi at ti.com  Mon Dec  9 02:39:32 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Mon, 9 Dec 2024 16:09:32 +0530
Subject: [EXTERNAL] Re: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix
 firmware load sequence.
In-Reply-To: <CAH-L+nMBYWVwbLoeMpe+PYw27KPKaKAH+hNFRaNTtYrBJ6yRHw@mail.gmail.com>
References: <20241205082831.777868-1-m-malladi@ti.com>
 <20241205082831.777868-2-m-malladi@ti.com>
 <CAH-L+nMBYWVwbLoeMpe+PYw27KPKaKAH+hNFRaNTtYrBJ6yRHw@mail.gmail.com>
Message-ID: <d795c765-2f55-4970-95d4-dc0637ab88aa@ti.com>



On 05/12/24 14:40, Kalesh Anakkur Purayil wrote:
> On Thu, Dec 5, 2024 at 1:59?PM Meghana Malladi <m-malladi at ti.com> wrote:
>>
>> From: MD Danish Anwar <danishanwar at ti.com>
>>
>> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
>> and SLICE1. Currently whenever any ICSSG interface comes up we load the
>> respective firmwares to PRU cores and whenever interface goes down, we
>> stop the resective cores. Due to this, when SLICE0 goes down while
>> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
>> stopped. This results in clock jump for SLICE1 interface as the timesync
>> related operations are no longer running.
>>
>> As there are interdependencies between SLICE0 and SLICE1 firmwares,
>> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
>> ICSSG interface is up. Add new flag in prueth struct to check if all
>> firmwares are running.
>>
>> Use emacs_initialized as reference count to load the firmwares for the
>> first and last interface up/down. Moving init_emac_mode and fw_offload_mode
>> API outside of icssg_config to icssg_common_start API as they need
>> to be called only once per firmware boot.
>>
>> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
>> ---
>>
>> Hi all,
>>
>> This patch is based on net-next tagged next-20241128.
>> v2:https://lore.kernel.org/all/20241128122931.2494446-2-m-malladi at ti.com/
>>
>> * Changes since v2 (v3-v2):
>> - error handling in caller function of prueth_emac_common_start()
>> - Use prus_running flag check before stopping the firmwares
>> Both suggested by Roger Quadros <rogerq at kernel.org>
>>
>>   drivers/net/ethernet/ti/icssg/icssg_config.c |  45 ++++--
>>   drivers/net/ethernet/ti/icssg/icssg_config.h |   1 +
>>   drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
>>   drivers/net/ethernet/ti/icssg/icssg_prueth.h |   5 +
>>   4 files changed, 140 insertions(+), 68 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
>> index 5d2491c2943a..342150756cf7 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_config.c
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
>> @@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>>          return 0;
>>   }
>>
>> -static void icssg_init_emac_mode(struct prueth *prueth)
>> +void icssg_init_emac_mode(struct prueth *prueth)
>>   {
>>          /* When the device is configured as a bridge and it is being brought
>>           * back to the emac mode, the host mac address has to be set as 0.
>> @@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>>          int i;
>>          u8 mac[ETH_ALEN] = { 0 };
>>
>> -       if (prueth->emacs_initialized)
>> -               return;
>> -
>>          /* Set VLAN TABLE address base */
>>          regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>>                             addr <<  SMEM_VLAN_OFFSET);
>> @@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth)
>>          /* Clear host MAC address */
>>          icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
>>   }
>> +EXPORT_SYMBOL_GPL(icssg_init_emac_mode);
>>
>> -static void icssg_init_fw_offload_mode(struct prueth *prueth)
>> +void icssg_init_fw_offload_mode(struct prueth *prueth)
>>   {
>>          u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET;
>>          int i;
>>
>> -       if (prueth->emacs_initialized)
>> -               return;
>> -
>>          /* Set VLAN TABLE address base */
>>          regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
>>                             addr <<  SMEM_VLAN_OFFSET);
>> @@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth)
>>                  icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr);
>>          icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST);
>>   }
>> +EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode);
>>
>>   int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>>   {
>> @@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
>>          struct icssg_flow_cfg __iomem *flow_cfg;
>>          int ret;
>>
>> -       if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>> -               icssg_init_fw_offload_mode(prueth);
>> -       else
>> -               icssg_init_emac_mode(prueth);
>> -
>>          memset_io(config, 0, TAS_GATE_MASK_LIST0);
>>          icssg_miig_queues_init(prueth, slice);
>>
>> @@ -786,3 +777,31 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port)
>>                  writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET);
>>   }
>>   EXPORT_SYMBOL_GPL(icssg_set_pvid);
>> +
>> +int emac_fdb_flow_id_updated(struct prueth_emac *emac)
>> +{
>> +       struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
>> +       int slice = prueth_emac_slice(emac);
>> +       struct mgmt_cmd fdb_cmd = { 0 };
>> +       int ret = 0;
> [Kalesh] There is no need to initialize "ret" here

Yes, I will remove it.

>> +
>> +       fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
>> +       fdb_cmd.type   = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
>> +       fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq);
>> +       fdb_cmd.param  = 0;
>> +
>> +       fdb_cmd.param |= (slice << 4);
>> +       fdb_cmd.cmd_args[0] = 0;
>> +
>> +       ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp);
>> +
> [Kalesh] There is no need of an new line here

Ok, I will remove it.

>> +       if (ret)
>> +               return ret;
>> +
>> +       WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum);
>> +       if (fdb_cmd_rsp.status == 1)
>> +               return 0;
>> +
>> +       return -EINVAL;
> [Kalesh] Maybe you can simplify this as:
> return fdb_cmd_rsp.status == 1 ? 0 : -EINVAL;

Yes, this looks good. I will update it.

>> +}
>> +EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated);
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
>> index 92c2deaa3068..c884e9fa099e 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_config.h
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
>> @@ -55,6 +55,7 @@ struct icssg_rxq_ctx {
>>   #define ICSSG_FW_MGMT_FDB_CMD_TYPE     0x03
>>   #define ICSSG_FW_MGMT_CMD_TYPE         0x04
>>   #define ICSSG_FW_MGMT_PKT              0x80000000
>> +#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW     0x05
>>
>>   struct icssg_r30_cmd {
>>          u32 cmd[4];
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> index c568c84a032b..2e22e793b01a 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> @@ -164,11 +164,11 @@ static struct icssg_firmwares icssg_emac_firmwares[] = {
>>          }
>>   };
>>
>> -static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>> +static int prueth_emac_start(struct prueth *prueth, int slice)
>>   {
>>          struct icssg_firmwares *firmwares;
>>          struct device *dev = prueth->dev;
>> -       int slice, ret;
>> +       int ret;
>>
>>          if (prueth->is_switch_mode)
>>                  firmwares = icssg_switch_firmwares;
>> @@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>          else
>>                  firmwares = icssg_emac_firmwares;
>>
>> -       slice = prueth_emac_slice(emac);
>> -       if (slice < 0) {
>> -               netdev_err(emac->ndev, "invalid port\n");
>> -               return -EINVAL;
>> -       }
>> -
>> -       ret = icssg_config(prueth, emac, slice);
>> -       if (ret)
>> -               return ret;
>> -
>>          ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
>>          ret = rproc_boot(prueth->pru[slice]);
>>          if (ret) {
>> @@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>                  goto halt_rtu;
>>          }
>>
>> -       emac->fw_running = 1;
>>          return 0;
>>
>>   halt_rtu:
>> @@ -220,6 +209,80 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>          return ret;
>>   }
>>
>> +static int prueth_emac_common_start(struct prueth *prueth)
>> +{
>> +       struct prueth_emac *emac;
>> +       int ret = 0;
>> +       int slice;
>> +
>> +       if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>> +               return -EINVAL;
>> +
>> +       /* clear SMEM and MSMC settings for all slices */
>> +       memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
>> +       memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
>> +
>> +       icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
>> +       icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
>> +
>> +       if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>> +               icssg_init_fw_offload_mode(prueth);
>> +       else
>> +               icssg_init_emac_mode(prueth);
>> +
>> +       for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>> +               emac = prueth->emac[slice];
>> +               if (emac) {
>> +                       ret |= icssg_config(prueth, emac, slice);
>> +                       if (ret)
>> +                               return ret;
>> +               }
>> +               ret |= prueth_emac_start(prueth, slice);
>> +       }
>> +       if (!ret)
>> +               prueth->prus_running = 1;
>> +       else
>> +               return ret;
> [Kalesh] This will read better if you change the condition check like:
> if (ret)
>      return ret;
> prueth->prus_running = 1;

Thanks, I will update it.

>> +
>> +       emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>> +              prueth->emac[ICSS_SLICE1];
>> +       ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>> +                           emac, IEP_DEFAULT_CYCLE_TIME_NS);
>> +       if (ret) {
>> +               dev_err(prueth->dev, "Failed to initialize IEP module\n");
>> +               return ret;
>> +       }
>> +
>> +       return 0;
> [Kalesh] You can "return ret" here and remove the return from above if
> condition.

I will update it.

>> +}
>> +
>> +static int prueth_emac_common_stop(struct prueth *prueth)
>> +{
>> +       struct prueth_emac *emac;
>> +       int slice;
>> +
>> +       if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>> +               return -EINVAL;
>> +
>> +       icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
>> +       icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
>> +
>> +       for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>> +               if (prueth->prus_running) {
>> +                       rproc_shutdown(prueth->txpru[slice]);
>> +                       rproc_shutdown(prueth->rtu[slice]);
>> +                       rproc_shutdown(prueth->pru[slice]);
>> +               }
>> +       }
>> +       prueth->prus_running = 0;
>> +
>> +       emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>> +              prueth->emac[ICSS_SLICE1];
>> +       icss_iep_exit(emac->iep);
>> +
>> +       return 0;
>> +}
>> +
>>   /* called back by PHY layer if there is change in link state of hw port*/
>>   static void emac_adjust_link(struct net_device *ndev)
>>   {
>> @@ -369,12 +432,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
>>   {
>>          struct icssg_setclock_desc __iomem *sc_descp;
>>          struct prueth_emac *emac = clockops_data;
>> +       struct prueth *prueth = emac->prueth;
>>          struct icssg_setclock_desc sc_desc;
>>          u64 cyclecount;
>>          u32 cycletime;
>>          int timeout;
>>
>> -       if (!emac->fw_running)
>> +       if (!prueth->prus_running)
>>                  return;
>>
>>          sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
>> @@ -543,23 +607,17 @@ 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;
>> +       struct icssg_flow_cfg __iomem *flow_cfg;
>>          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, false);
>>          icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
>>
>>          /* Notify the stack of the actual queue counts. */
>> @@ -597,18 +655,23 @@ static int emac_ndo_open(struct net_device *ndev)
>>                  goto cleanup_napi;
>>          }
>>
>> -       /* reset and start PRU firmware */
>> -       ret = prueth_emac_start(prueth, emac);
>> -       if (ret)
>> -               goto free_rx_irq;
>> +       if (!prueth->emacs_initialized) {
>> +               ret = prueth_emac_common_start(prueth);
>> +               if (ret)
>> +                       goto stop;
>> +       }
>>
>> -       icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>> +       flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
>> +       writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
>> +       ret = emac_fdb_flow_id_updated(emac);
>>
>> -       if (!prueth->emacs_initialized) {
>> -               ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>> -                                   emac, IEP_DEFAULT_CYCLE_TIME_NS);
>> +       if (ret) {
>> +               netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
>> +               goto stop;
>>          }
>>
>> +       icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>> +
>>          ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
>>                                     IRQF_ONESHOT, dev_name(dev), emac);
>>          if (ret)
>> @@ -653,8 +716,7 @@ static int emac_ndo_open(struct net_device *ndev)
>>   free_tx_ts_irq:
>>          free_irq(emac->tx_ts_irq, emac);
>>   stop:
>> -       prueth_emac_stop(emac);
>> -free_rx_irq:
>> +       prueth_emac_common_stop(prueth);
>>          free_irq(emac->rx_chns.irq[rx_flow], emac);
>>   cleanup_napi:
>>          prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
>> @@ -689,8 +751,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>>          if (ndev->phydev)
>>                  phy_stop(ndev->phydev);
>>
>> -       icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
>> -
>>          if (emac->prueth->is_hsr_offload_mode)
>>                  __dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
>>          else
>> @@ -728,11 +788,9 @@ static int emac_ndo_stop(struct net_device *ndev)
>>          /* Destroying the queued work in ndo_stop() */
>>          cancel_delayed_work_sync(&emac->stats_work);
>>
>> -       if (prueth->emacs_initialized == 1)
>> -               icss_iep_exit(emac->iep);
>> -
>>          /* stop PRUs */
>> -       prueth_emac_stop(emac);
>> +       if (prueth->emacs_initialized == 1)
>> +               prueth_emac_common_stop(prueth);
>>
>>          free_irq(emac->tx_ts_irq, emac);
>>
>> @@ -1069,16 +1127,10 @@ static void prueth_emac_restart(struct prueth *prueth)
>>          icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
>>
>>          /* Stop both pru cores for both PRUeth ports*/
>> -       prueth_emac_stop(emac0);
>> -       prueth->emacs_initialized--;
>> -       prueth_emac_stop(emac1);
>> -       prueth->emacs_initialized--;
>> +       prueth_emac_common_stop(prueth);
>>
>>          /* Start both pru cores for both PRUeth ports */
>> -       prueth_emac_start(prueth, emac0);
>> -       prueth->emacs_initialized++;
>> -       prueth_emac_start(prueth, emac1);
>> -       prueth->emacs_initialized++;
>> +       prueth_emac_common_start(prueth);
>>
>>          /* Enable forwarding for both PRUeth ports */
>>          icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
>> @@ -1413,13 +1465,10 @@ static int prueth_probe(struct platform_device *pdev)
>>                  prueth->pa_stats = NULL;
>>          }
>>
>> -       if (eth0_node) {
>> +       if (eth0_node || eth1_node) {
>>                  ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
>>                  if (ret)
>>                          goto put_cores;
>> -       }
>> -
>> -       if (eth1_node) {
>>                  ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
>>                  if (ret)
>>                          goto put_cores;
>> @@ -1618,14 +1667,12 @@ static int prueth_probe(struct platform_device *pdev)
>>          pruss_put(prueth->pruss);
>>
>>   put_cores:
>> -       if (eth1_node) {
>> -               prueth_put_cores(prueth, ICSS_SLICE1);
>> -               of_node_put(eth1_node);
>> -       }
>> -
>> -       if (eth0_node) {
>> +       if (eth0_node || eth1_node) {
>>                  prueth_put_cores(prueth, ICSS_SLICE0);
>>                  of_node_put(eth0_node);
>> +
>> +               prueth_put_cores(prueth, ICSS_SLICE1);
>> +               of_node_put(eth1_node);
>>          }
>>
>>          return ret;
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> index f5c1d473e9f9..b30f2e9a73d8 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> @@ -257,6 +257,7 @@ struct icssg_firmwares {
>>    * @is_switchmode_supported: indicates platform support for switch mode
>>    * @switch_id: ID for mapping switch ports to bridge
>>    * @default_vlan: Default VLAN for host
>> + * @prus_running: flag to indicate if all pru cores are running
>>    */
>>   struct prueth {
>>          struct device *dev;
>> @@ -298,6 +299,7 @@ struct prueth {
>>          int default_vlan;
>>          /** @vtbl_lock: Lock for vtbl in shared memory */
>>          spinlock_t vtbl_lock;
>> +       bool prus_running;
>>   };
>>
>>   struct emac_tx_ts_response {
>> @@ -361,6 +363,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
>>                           enum icssg_port_state_cmd state);
>>   void icssg_config_set_speed(struct prueth_emac *emac);
>>   void icssg_config_half_duplex(struct prueth_emac *emac);
>> +void icssg_init_emac_mode(struct prueth *prueth);
>> +void icssg_init_fw_offload_mode(struct prueth *prueth);
>>
>>   /* Buffer queue helpers */
>>   int icssg_queue_pop(struct prueth *prueth, u8 queue);
>> @@ -377,6 +381,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
>>                         u8 untag_mask, bool add);
>>   u16 icssg_get_pvid(struct prueth_emac *emac);
>>   void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
>> +int emac_fdb_flow_id_updated(struct prueth_emac *emac);
>>   #define prueth_napi_to_tx_chn(pnapi) \
>>          container_of(pnapi, struct prueth_tx_chn, napi_tx)
>>
>> --
>> 2.25.1
>>
>>
> 
> 


From yury.khrustalev at arm.com  Mon Dec  9 01:47:16 2024
From: yury.khrustalev at arm.com (Yury Khrustalev)
Date: Mon,  9 Dec 2024 09:47:16 +0000
Subject: [RESEND v4 0/3] mm/pkey: Add PKEY_UNRESTRICTED macro
Message-ID: <20241209094719.2431126-1-yury.khrustalev@arm.com>

Add PKEY_UNRESTRICTED macro to mman.h and use it in selftests.

For context, this change will also allow for more consistent update of the
Glibc manual which in turn will help with introducing memory protection
keys on AArch64 targets.

Applies to fac04efc5c79 (tag: v6.13-rc2).

Note that I couldn't build ppc tests so I would appreciate if someone
could check the 3rd patch. Thank you!

Signed-off-by: Yury Khrustalev <yury.khrustalev at arm.com>

---
Changes in v4:
 - Removed change to tools/include/uapi/asm-generic/mman-common.h as it is not
   necessary.

Link to v3: https://lore.kernel.org/all/20241028090715.509527-1-yury.khrustalev at arm.com/

Changes in v3:
 - Replaced previously missed 0-s tools/testing/selftests/mm/mseal_test.c
 - Replaced previously missed 0-s in tools/testing/selftests/mm/mseal_test.c

Link to v2: https://lore.kernel.org/linux-arch/20241027170006.464252-2-yury.khrustalev at arm.com/

Changes in v2:
 - Update tools/include/uapi/asm-generic/mman-common.h as well
 - Add usages of the new macro to selftests.

Link to v1: https://lore.kernel.org/linux-arch/20241022120128.359652-1-yury.khrustalev at arm.com/

---

Yury Khrustalev (3):
  mm/pkey: Add PKEY_UNRESTRICTED macro
  selftests/mm: Use PKEY_UNRESTRICTED macro
  selftests/powerpc: Use PKEY_UNRESTRICTED macro

 include/uapi/asm-generic/mman-common.h               | 1 +
 tools/testing/selftests/mm/mseal_test.c              | 6 +++---
 tools/testing/selftests/mm/pkey-helpers.h            | 3 ++-
 tools/testing/selftests/mm/pkey_sighandler_tests.c   | 4 ++--
 tools/testing/selftests/mm/protection_keys.c         | 2 +-
 tools/testing/selftests/powerpc/include/pkeys.h      | 2 +-
 tools/testing/selftests/powerpc/mm/pkey_exec_prot.c  | 2 +-
 tools/testing/selftests/powerpc/mm/pkey_siginfo.c    | 2 +-
 tools/testing/selftests/powerpc/ptrace/core-pkey.c   | 6 +++---
 tools/testing/selftests/powerpc/ptrace/ptrace-pkey.c | 6 +++---
 10 files changed, 18 insertions(+), 16 deletions(-)

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec  9 02:34:13 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 9 Dec 2024 12:34:13 +0200
Subject: [PATCH v19 4/8] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <PAXPR04MB944814380C7A72641C6002ADF43C2@PAXPR04MB9448.eurprd04.prod.outlook.com>
References: <cover.1732627815.git.Sandor.yu@nxp.com>
 <e32c909ea8744fc5ea89aa3b4eed501efbaad1c3.1732627815.git.Sandor.yu@nxp.com>
 <wk6w5ckor53mudcqfs2grnxryhg7zvsjjdmqatyfddyfgsdrwc@mxxoocsi5pe7>
 <PAXPR04MB944814380C7A72641C6002ADF43C2@PAXPR04MB9448.eurprd04.prod.outlook.com>
Message-ID: <fqrxw7yc7btvqccqy6mksqufcacm6o52xmk6drlqeeepuyfp62@gpjiox76h4cb>

On Mon, Dec 09, 2024 at 08:38:01AM +0000, Sandor Yu wrote:
> 
> 
> > -----Original Message-----
> > From: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > Sent: 2024?11?27? 3:21
> > To: Sandor Yu <sandor.yu at nxp.com>
> > Cc: 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;
> > mripard at kernel.org; kernel at pengutronix.de; dl-linux-imx
> > <linux-imx at nxp.com>; Oliver Brown <oliver.brown at nxp.com>;
> > alexander.stein at ew.tq-group.com; sam at ravnborg.org
> > Subject: [EXT] Re: [PATCH v19 4/8] drm: bridge: Cadence: Add MHDP8501
> > DP/HDMI driver

Please strip such headers from your response emails. They take a lot of
space and are useless. See how it's usually handled by other email
clients.

> > 
> > 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 Tue, Nov 26, 2024 at 10:11:49PM +0800, Sandor Yu wrote:
> > > 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>
> > > ---

[...]

> > > +
> > > +static int reset_pipe(struct drm_crtc *crtc)
> > > +{
> > > +     struct drm_atomic_state *state;
> > > +     struct drm_crtc_state *crtc_state;
> > > +     struct drm_modeset_acquire_ctx ctx;
> > > +     int ret;
> > > +
> > > +     state = drm_atomic_state_alloc(crtc->dev);
> > > +     if (!state)
> > > +             return -ENOMEM;
> > > +
> > > +     drm_modeset_acquire_init(&ctx, 0);
> > > +
> > > +     state->acquire_ctx = &ctx;
> > > +
> > > +     crtc_state = drm_atomic_get_crtc_state(state, crtc);
> > > +     if (IS_ERR(crtc_state)) {
> > > +             ret = PTR_ERR(crtc_state);
> > > +             goto out;
> > > +     }
> > > +
> > > +     crtc_state->connectors_changed = true;
> > > +
> > > +     ret = drm_atomic_commit(state);
> >  
> > I'd say, this looks like a hack to me.
> 
> Basically, those code followed the sequence as vc4 HDMI and i915 according review comments in v15.
> HDMI driver should " Reenabling the scrambler when a display is disconnected and reconnected".
> 
> To be honest, I'm not 100% convinced by this implementation, 
> as the code doesn't seem to align perfectly with the current DRM framework. 
> However, adding this feature would indeed address the issue of applications (like modetest) that don't handle HPD events 
> but still require cable plug/unplug support when operating in scrambler-enabled video modes.

Ack. This matches vc4's reset_pipe().

> 
> > 
> > > +out:
> > > +     drm_atomic_state_put(state);
> > > +     drm_modeset_drop_locks(&ctx);
> > > +     drm_modeset_acquire_fini(&ctx);
> > > +
> > > +     return ret;
> > > +}
> > > +
> > > +void cdns_hdmi_reset_link(struct cdns_mhdp8501_device *mhdp)
> > > +{
> > > +     struct drm_connector *connector = mhdp->curr_conn;
> > > +     const struct drm_edid *drm_edid;
> > > +     struct drm_connector_state *conn_state;
> > > +     struct drm_crtc_state *crtc_state;
> > > +     struct drm_crtc *crtc;
> > > +
> > > +     if (!connector)
> > > +             return;
> > > +
> > > +     drm_edid = drm_edid_read_custom(connector,
> > cdns_hdmi_get_edid_block, mhdp);
> > > +     drm_edid_connector_update(connector, drm_edid);
> > 
> > Why?
> 
> MHDP8501 HDMI support scrambling.low_rates.
> The scrambler status can change when switching HDMI display monitors, even if the video mode stays the same. 
> The MHDP8501's HDMI code updates the EDID data to accommodate displays with different scrambler capabilities.

Ack. I'd suggest renaming cdns_hdmi_reset_link() to
cdns_hdmi_handle_hotplug() or any other similar name.

> 
> > 
> > > +
> > > +     if (!drm_edid)
> > > +             return;
> > > +
> > > +     drm_edid_free(drm_edid);
> > > +
> > > +     conn_state = connector->state;
> > > +     crtc = conn_state->crtc;
> > > +     if (!crtc)
> > > +             return;
> > > +
> > > +     crtc_state = crtc->state;
> > > +     if (!crtc_state->active)
> > > +             return;
> > > +
> > > +     /*
> > > +      * HDMI 2.0 says that one should not send scrambled data
> > > +      * prior to configuring the sink scrambling, and that
> > > +      * TMDS clock/data transmission should be suspended when
> > > +      * changing the TMDS clock rate in the sink. So let's
> > > +      * just do a full modeset here, even though some sinks
> > > +      * would be perfectly happy if were to just reconfigure
> > > +      * the SCDC settings on the fly.
> > > +      */
> > > +     reset_pipe(crtc);
> > 
> > We are not supposed to cause full-modeset flicker if we can avoid it. Is
> > it the case here?
> 
> My implementation differs slightly from the VC4 HDMI in that it doesn't check if the current video mode requires enabling the scrambler. 
> This is because we considered a scenario where the previous display was operating at 1080p60 with scrambling enabled, 
> and then the cable was plugged into a display that doesn't support scrambling at low rates. 
> This case also necessitates a full modeset.

Well, if this is a part of the hotplug, then of course there are no
flickering issues as it happens during hotplug.

> 
> I haven't found any video flickering issues in my actual tests.
> 
> > 
> > > +}
> > > +
> > > +static int cdns_hdmi_i2c_write(struct cdns_mhdp8501_device *mhdp,
> > > +                            struct i2c_msg *msgs)
> > > +{
> > > +     u8 msg[5], reg[5];
> > > +     int ret;
> > > +
> > > +     msg[0] = msgs->addr;
> > > +     msg[1] = msgs->buf[0];
> > > +     msg[2] = 0;
> > > +     msg[3] = 1;
> > > +     msg[4] = msgs->buf[1];
> > > +
> > > +     ret = cdns_mhdp_mailbox_send_recv(&mhdp->base,
> > > +
> > MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
> > > +                                       sizeof(msg), msg,
> > sizeof(reg), reg);
> > > +     if (ret) {
> > > +             dev_err(mhdp->dev, "I2C write failed: %d\n", ret);
> > > +             return ret;
> > > +     }
> > > +
> > > +     if (reg[0] != 0)
> > > +             return -EINVAL;
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static int cdns_hdmi_i2c_read(struct cdns_mhdp8501_device *mhdp,
> > > +                           struct i2c_msg *msgs, int num)
> > > +{
> > > +     u8 msg[4], reg[5];
> > > +     u8 addr, offset, *buf, len;
> > > +     int ret, i;
> > > +
> > > +     for (i = 0; i < num; i++) {
> > > +             if (msgs[i].flags & I2C_M_RD) {
> > > +                     addr = msgs[i].addr;
> > > +                     buf = msgs[i].buf;
> > > +                     len = msgs[i].len;
> > > +             } else {
> > > +                     offset = msgs[i].buf[0];
> > > +             }
> > > +     }
> > > +
> > > +     msg[0] = addr;
> > > +     msg[1] = offset;
> > > +     put_unaligned_be16(len, msg + 2);
> > > +
> > > +     ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base,
> > > +
> > MB_MODULE_ID_HDMI_TX, HDMI_TX_READ,
> > > +                                             sizeof(msg), msg,
> > > +                                             HDMI_TX_READ,
> > > +                                             sizeof(reg), reg,
> > > +                                             len, buf);
> > > +     if (ret) {
> > > +             dev_err(mhdp->dev, "I2c Read failed: %d\n", ret);
> > > +             return ret;
> > > +     }
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +#define  SCDC_I2C_SLAVE_ADDRESS      0x54
> > > +static int cdns_hdmi_i2c_xfer(struct i2c_adapter *adap,
> > > +                           struct i2c_msg *msgs, int num)
> > > +{
> > > +     struct cdns_mhdp8501_device *mhdp = i2c_get_adapdata(adap);
> > > +     struct cdns_hdmi_i2c *i2c = mhdp->hdmi.i2c;
> > > +     int i, ret = 0;
> > > +
> > > +     /* Only support SCDC I2C Read/Write */
> > > +     for (i = 0; i < num; i++) {
> > > +             if (msgs[i].addr != SCDC_I2C_SLAVE_ADDRESS) {
> > > +                     dev_err(mhdp->dev, "ADDR=%0x is not
> > supported\n", msgs[i].addr);
> > > +                     return -EINVAL;
> > 
> > Why?
> 
> MHDP FW offers mailbox APIs for SCDC register access but no direct I2C APIs. 
> Individual I2C registers can be read/written using HDMI general register APIs, 
> but block reads (e.g., EDID) are not supported, so it is not a full function I2C.
> i2c_adapter was implemented only for reuse drm_scdc_XXX functions.

Please put this info in the comment. From your 'Only support foo' it's
not obvious if the hw/fw doesn't support it or if you are artifically
limiting it on the driver's side.

> 

-- 
With best wishes
Dmitry


From m-malladi at ti.com  Mon Dec  9 02:34:40 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Mon, 9 Dec 2024 16:04:40 +0530
Subject: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix firmware load
 sequence.
In-Reply-To: <a86bc0b1-8bb4-477e-b7e1-13921bf47b53@kernel.org>
References: <20241205082831.777868-1-m-malladi@ti.com>
 <20241205082831.777868-2-m-malladi@ti.com>
 <a86bc0b1-8bb4-477e-b7e1-13921bf47b53@kernel.org>
Message-ID: <64621290-2488-474d-b2ed-597a1f4ac85f@ti.com>



On 05/12/24 18:38, Roger Quadros wrote:
> Hi,
> 
> On 05/12/2024 10:28, Meghana Malladi wrote:
>> From: MD Danish Anwar <danishanwar at ti.com>
>>
>> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
>> and SLICE1. Currently whenever any ICSSG interface comes up we load the
>> respective firmwares to PRU cores and whenever interface goes down, we
>> stop the resective cores. Due to this, when SLICE0 goes down while
>> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
>> stopped. This results in clock jump for SLICE1 interface as the timesync
>> related operations are no longer running.
>>
>> As there are interdependencies between SLICE0 and SLICE1 firmwares,
>> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
>> ICSSG interface is up. Add new flag in prueth struct to check if all
>> firmwares are running.
>>
>> Use emacs_initialized as reference count to load the firmwares for the
>> first and last interface up/down. Moving init_emac_mode and fw_offload_mode
>> API outside of icssg_config to icssg_common_start API as they need
>> to be called only once per firmware boot.
>>
>> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
>> ---
>>
>> Hi all,
>>
>> This patch is based on net-next tagged next-20241128.
>> v2:https://lore.kernel.org/all/20241128122931.2494446-2-m-malladi at ti.com/
>>
>> * Changes since v2 (v3-v2):
>> - error handling in caller function of prueth_emac_common_start()
>> - Use prus_running flag check before stopping the firmwares
>> Both suggested by Roger Quadros <rogerq at kernel.org>
>>
>>   drivers/net/ethernet/ti/icssg/icssg_config.c |  45 ++++--
>>   drivers/net/ethernet/ti/icssg/icssg_config.h |   1 +
>>   drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
>>   drivers/net/ethernet/ti/icssg/icssg_prueth.h |   5 +
>>   4 files changed, 140 insertions(+), 68 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
>> index 5d2491c2943a..342150756cf7 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_config.c
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
>> @@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>>   	return 0;
>>   }
>>
[ ... ]

>> +static int prueth_emac_common_start(struct prueth *prueth)
>> +{
>> +	struct prueth_emac *emac;
>> +	int ret = 0;
>> +	int slice;
>> +
>> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>> +		return -EINVAL;
>> +
>> +	/* clear SMEM and MSMC settings for all slices */
>> +	memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
>> +	memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
>> +
>> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
>> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
>> +
>> +	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>> +		icssg_init_fw_offload_mode(prueth);
>> +	else
>> +		icssg_init_emac_mode(prueth);
>> +
>> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>> +		emac = prueth->emac[slice];
>> +		if (emac) {
>> +			ret |= icssg_config(prueth, emac, slice);
>> +			if (ret)
>> +				return ret;
>> +		}
>> +		ret |= prueth_emac_start(prueth, slice);
>> +	}
> 
> need newline?
> 

Yes I will add it.

>> +	if (!ret)
>> +		prueth->prus_running = 1;
>> +	else
>> +		return ret;
>> +
>> +	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>> +	       prueth->emac[ICSS_SLICE1];
>> +	ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>> +			    emac, IEP_DEFAULT_CYCLE_TIME_NS);
>> +	if (ret) {
>> +		dev_err(prueth->dev, "Failed to initialize IEP module\n");
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int prueth_emac_common_stop(struct prueth *prueth)
>> +{
>> +	struct prueth_emac *emac;
>> +	int slice;
>> +
>> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>> +		return -EINVAL;
>> +
>> +	icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
>> +	icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
>> +
>> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>> +		if (prueth->prus_running) {
>> +			rproc_shutdown(prueth->txpru[slice]);
>> +			rproc_shutdown(prueth->rtu[slice]);
>> +			rproc_shutdown(prueth->pru[slice]);
>> +		}
>> +	}
>> +	prueth->prus_running = 0;
>> +
>> +	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>> +	       prueth->emac[ICSS_SLICE1];
>> +	icss_iep_exit(emac->iep);
> 
> if icss_iep_init() failed at prueth_emac_common_start(), we should not be
> calling icss_iep_exit(). Maybe you need another flag for iep_init status?
> 

Yes I have thought of it as well. In icss_iep_init() does lot of iep 
register configuration and in the end it enables iep by setting 
IEP_CNT_ENABLE bit and ptp_clock_register(). Whereas in icss_iep_exit() 
it checks for ptp_clock and pps/perout. And calls icss_iep_disable() 
which again clears IEP_CNT_ENABLE.

So I see no harm in calling icss_iep_exit() even if icss_iep_init() as 
it overwrites the existing configuration only. But if you think this 
doesn't look good I can definitely add new flag for iep as well. But IMO 
I think this flag would be redundant, please correct me if I am wrong. 
So which one sounds better?

> Is it better to call icss_iep_exit() at the top before icssg_class_disable()?
> 
>> +
>> +	return 0;
>> +}
>> +
>>   /* called back by PHY layer if there is change in link state of hw port*/
>>   static void emac_adjust_link(struct net_device *ndev)
>>   {
>> @@ -369,12 +432,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
>>   {
>>   	struct icssg_setclock_desc __iomem *sc_descp;
>>   	struct prueth_emac *emac = clockops_data;
>> +	struct prueth *prueth = emac->prueth;
>>   	struct icssg_setclock_desc sc_desc;
>>   	u64 cyclecount;
>>   	u32 cycletime;
>>   	int timeout;
>>   
>> -	if (!emac->fw_running)
>> +	if (!prueth->prus_running)
>>   		return;
>>   
>>   	sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
>> @@ -543,23 +607,17 @@ 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;
>> +	struct icssg_flow_cfg __iomem *flow_cfg;
>>   	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, false);
>>   	icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
>>   
>>   	/* Notify the stack of the actual queue counts. */
>> @@ -597,18 +655,23 @@ static int emac_ndo_open(struct net_device *ndev)
>>   		goto cleanup_napi;
>>   	}
>>   
>> -	/* reset and start PRU firmware */
>> -	ret = prueth_emac_start(prueth, emac);
>> -	if (ret)
>> -		goto free_rx_irq;
>> +	if (!prueth->emacs_initialized) {
>> +		ret = prueth_emac_common_start(prueth);
>> +		if (ret)
>> +			goto stop;
>> +	}
>>   
>> -	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>> +	flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
>> +	writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
>> +	ret = emac_fdb_flow_id_updated(emac);
>>   
>> -	if (!prueth->emacs_initialized) {
>> -		ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>> -				    emac, IEP_DEFAULT_CYCLE_TIME_NS);
>> +	if (ret) {
>> +		netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
>> +		goto stop;
>>   	}
>>   
>> +	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>> +
>>   	ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
>>   				   IRQF_ONESHOT, dev_name(dev), emac);
>>   	if (ret)
>> @@ -653,8 +716,7 @@ static int emac_ndo_open(struct net_device *ndev)
>>   free_tx_ts_irq:
>>   	free_irq(emac->tx_ts_irq, emac);
>>   stop:
>> -	prueth_emac_stop(emac);
>> -free_rx_irq:
>> +	prueth_emac_common_stop(prueth);
>>   	free_irq(emac->rx_chns.irq[rx_flow], emac);
>>   cleanup_napi:
>>   	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
>> @@ -689,8 +751,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>>   	if (ndev->phydev)
>>   		phy_stop(ndev->phydev);
>>   
>> -	icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
>> -
>>   	if (emac->prueth->is_hsr_offload_mode)
>>   		__dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
>>   	else
>> @@ -728,11 +788,9 @@ static int emac_ndo_stop(struct net_device *ndev)
>>   	/* Destroying the queued work in ndo_stop() */
>>   	cancel_delayed_work_sync(&emac->stats_work);
>>   
>> -	if (prueth->emacs_initialized == 1)
>> -		icss_iep_exit(emac->iep);
>> -
>>   	/* stop PRUs */
>> -	prueth_emac_stop(emac);
>> +	if (prueth->emacs_initialized == 1)
>> +		prueth_emac_common_stop(prueth);
>>   
>>   	free_irq(emac->tx_ts_irq, emac);
>>   
>> @@ -1069,16 +1127,10 @@ static void prueth_emac_restart(struct prueth *prueth)
>>   	icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
>>   
>>   	/* Stop both pru cores for both PRUeth ports*/
>> -	prueth_emac_stop(emac0);
>> -	prueth->emacs_initialized--;
>> -	prueth_emac_stop(emac1);
>> -	prueth->emacs_initialized--;
>> +	prueth_emac_common_stop(prueth);
>>   
>>   	/* Start both pru cores for both PRUeth ports */
>> -	prueth_emac_start(prueth, emac0);
>> -	prueth->emacs_initialized++;
>> -	prueth_emac_start(prueth, emac1);
>> -	prueth->emacs_initialized++;
>> +	prueth_emac_common_start(prueth);
> 
> But this can fail? You need to deal with failure condition appropriately.
> 

I haven't added failure conditions for two reasons:
- Existing code also didn't have any error checks
- This func simply reloads a new firmware, given everything is already 
working with the old one.

I can still handle error cases by changing this func to return int 
(currently it is void) and caller of the functions should print error 
and immediately return. Thoughts on this?

>>   
>>   	/* Enable forwarding for both PRUeth ports */
>>   	icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
>> @@ -1413,13 +1465,10 @@ static int prueth_probe(struct platform_device *pdev)
>>   		prueth->pa_stats = NULL;
>>   	}
>>   
>> -	if (eth0_node) {
>> +	if (eth0_node || eth1_node) {
>>   		ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
>>   		if (ret)
>>   			goto put_cores;
>> -	}
>> -
>> -	if (eth1_node) {
>>   		ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
>>   		if (ret)
>>   			goto put_cores;
>> @@ -1618,14 +1667,12 @@ static int prueth_probe(struct platform_device *pdev)
>>   	pruss_put(prueth->pruss);
>>   
>>   put_cores:
>> -	if (eth1_node) {
>> -		prueth_put_cores(prueth, ICSS_SLICE1);
>> -		of_node_put(eth1_node);
>> -	}
>> -
>> -	if (eth0_node) {
>> +	if (eth0_node || eth1_node) {
>>   		prueth_put_cores(prueth, ICSS_SLICE0);
>>   		of_node_put(eth0_node);
>> +
>> +		prueth_put_cores(prueth, ICSS_SLICE1);
>> +		of_node_put(eth1_node);
>>   	}
>>   
>>   	return ret;
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> index f5c1d473e9f9..b30f2e9a73d8 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> @@ -257,6 +257,7 @@ struct icssg_firmwares {
>>    * @is_switchmode_supported: indicates platform support for switch mode
>>    * @switch_id: ID for mapping switch ports to bridge
>>    * @default_vlan: Default VLAN for host
>> + * @prus_running: flag to indicate if all pru cores are running
>>    */
>>   struct prueth {
>>   	struct device *dev;
>> @@ -298,6 +299,7 @@ struct prueth {
>>   	int default_vlan;
>>   	/** @vtbl_lock: Lock for vtbl in shared memory */
>>   	spinlock_t vtbl_lock;
>> +	bool prus_running;
> 
> I think you don't need fw_running flag anymore. Could you please remove it
> from struct prueth_emac?
> 

This flag is still being used by SR1, for which this patch doesn't 
apply. So I prefer not touching this flag for the sake of SR1.

>>   };
>>   
>>   struct emac_tx_ts_response {
>> @@ -361,6 +363,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
>>   			 enum icssg_port_state_cmd state);
>>   void icssg_config_set_speed(struct prueth_emac *emac);
>>   void icssg_config_half_duplex(struct prueth_emac *emac);
>> +void icssg_init_emac_mode(struct prueth *prueth);
>> +void icssg_init_fw_offload_mode(struct prueth *prueth);
>>   
>>   /* Buffer queue helpers */
>>   int icssg_queue_pop(struct prueth *prueth, u8 queue);
>> @@ -377,6 +381,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
>>   		       u8 untag_mask, bool add);
>>   u16 icssg_get_pvid(struct prueth_emac *emac);
>>   void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
>> +int emac_fdb_flow_id_updated(struct prueth_emac *emac);
>>   #define prueth_napi_to_tx_chn(pnapi) \
>>   	container_of(pnapi, struct prueth_tx_chn, napi_tx)
>>   
> 


From sudeep.holla at arm.com  Mon Dec  9 02:46:44 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 9 Dec 2024 10:46:44 +0000
Subject: [PATCH v2 2/2] firmware: arm_scmi: round rate bisecting in
 discrete rates
In-Reply-To: <20241203173908.3148794-3-etienne.carriere@foss.st.com>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-3-etienne.carriere@foss.st.com>
Message-ID: <Z1bKlOeHJFHpe9ZU@bogus>

On Tue, Dec 03, 2024 at 06:39:08PM +0100, Etienne Carriere wrote:
> Implement clock round_rate operation for SCMI clocks that describe a
> discrete rates list. Bisect into the supported rates when using SCMI
> message CLOCK_DESCRIBE_RATES to optimize SCMI communication transfers.

Let me stop here and try to understand the requirement here. So you do
communicate with the firmware to arrive at this round_rate ? Does the
list of discreet clock rates changes at the run-time that enables the
need for it. Or will the initial list just include max and min ?

> Parse the rate list array when the target rate fit in the bounds
> of the command response for simplicity.
>

I don't understand what you mean by this.

> If so some reason the sequence fails or if the SCMI driver has no
> round_rate SCMI clock handler, then fallback to the legacy strategy that
> returned the target rate value.
>

Hmm, so we perform some extra dance but we are okay to fallback to default.
I am more confused.

> Operation handle scmi_clk_determine_rate() is change to get the effective
> supported rounded rate when there is no clock re-parenting operation
> supported. Otherwise, preserve the implementation that assumed any
> clock rate could be obtained.
>

OK, no I think I am getting some idea. Is this case where the parent has
changed and the describe rates can give a different result at run-time.

I need to re-read the part of the spec, but we may need some clarity so
that this implementation is not vendor specific. I am yet to understand this
fully. I just need to make sure spec covers this aspect and anything we
add here is generic solution.

I would like to avoid this extra query if not required which you seem to
have made an attempt but I just want to be thorough and make sure that's
what we need w.r.t the specification.

-- 
Regards,
Sudeep


From krzysztof.kozlowski at linaro.org  Mon Dec  9 02:49:59 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 09 Dec 2024 11:49:59 +0100
Subject: [PATCH] MAINTAINERS: add myself and Tudor as reviewers for
 Google Tensor SoC
In-Reply-To: <20241203-gs101-maintainers-v1-1-f287036dbde5@linaro.org>
References: <20241203-gs101-maintainers-v1-1-f287036dbde5@linaro.org>
Message-ID: <173374139927.46435.9500356182814320037.b4-ty@linaro.org>


On Tue, 03 Dec 2024 13:03:52 +0000, Andr? Draszik wrote:
> Add myself and Tudor as reviewers for the Google Tensor SoC alongside
> Peter.
> 
> While at it, also add our IRC channel.
> 
> 

Applied, thanks!

[1/1] MAINTAINERS: add myself and Tudor as reviewers for Google Tensor SoC
      https://git.kernel.org/krzk/linux/c/da9ca3164d1794660d9ad650beb807b9a47fe18b

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



From krzysztof.kozlowski at linaro.org  Mon Dec  9 02:49:56 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 09 Dec 2024 11:49:56 +0100
Subject: (subset) [PATCH v2 1/2] dt-bindings: soc: samsung: exynos-pmu:
 Add exynos990-pmu compatible
In-Reply-To: <20241204145559.524932-2-igor.belwon@mentallysanemainliners.org>
References: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>
 <20241204145559.524932-2-igor.belwon@mentallysanemainliners.org>
Message-ID: <173374139637.46435.13275133164438214681.b4-ty@linaro.org>


On Wed, 04 Dec 2024 15:55:58 +0100, Igor Belwon wrote:
> Add a dt-binding compatible for the Exynos990 PMU. It's compatible
> with the Exynos7 PMU design. It handles system reboot, as well as
> other system control registers (i.e registers for the USB PHY).
> 
> 

Applied, thanks!

[1/2] dt-bindings: soc: samsung: exynos-pmu: Add exynos990-pmu compatible
      https://git.kernel.org/krzk/linux/c/33ebc0fb73ba8fabbc1c8f581f7f512a0b277645

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



From krzysztof.kozlowski at linaro.org  Mon Dec  9 02:49:57 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 09 Dec 2024 11:49:57 +0100
Subject: (subset) [PATCH v2 2/2] arm64: dts: exynos990: Add pmu and
 syscon-reboot nodes
In-Reply-To: <20241204145559.524932-3-igor.belwon@mentallysanemainliners.org>
References: <20241204145559.524932-1-igor.belwon@mentallysanemainliners.org>
 <20241204145559.524932-3-igor.belwon@mentallysanemainliners.org>
Message-ID: <173374139792.46435.12839391873743115498.b4-ty@linaro.org>


On Wed, 04 Dec 2024 15:55:59 +0100, Igor Belwon wrote:
> Add PMU syscon, and syscon-reboot nodes to the Exynos990 dtsi.
> 
> Reboot of the Exynos990 SoC is handled by setting bit(SWRESET_TRIGGER[1])
> of SWRESET register (PMU + 0x3a00).
> 
> Tested using the "reboot" command.
> 
> [...]

Applied, thanks!

[2/2] arm64: dts: exynos990: Add pmu and syscon-reboot nodes
      https://git.kernel.org/krzk/linux/c/d5b3944bec944b40e91cae82583ce11740af6f10

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



From o451686892 at gmail.com  Mon Dec  9 02:52:37 2024
From: o451686892 at gmail.com (Weizhao Ouyang)
Date: Mon,  9 Dec 2024 18:52:37 +0800
Subject: [PATCH] kselftest/arm64: abi: fix SVCR detection
Message-ID: <20241209105237.10498-1-o451686892@gmail.com>

When using svcr_in to check ZA and Streaming Mode, we should make sure
that the value in x2 is correct, otherwise it may trigger an Illegal
instruction if FEAT_SVE and !FEAT_SME.

Fixes: 43e3f85523e4 ("kselftest/arm64: Add SME support to syscall ABI test")
Signed-off-by: Weizhao Ouyang <o451686892 at gmail.com>
---
 tools/testing/selftests/arm64/abi/syscall-abi-asm.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
index df3230fdac39..98cde4f37abf 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
+++ b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
@@ -81,9 +81,9 @@ do_syscall:
 	stp	x27, x28, [sp, #96]
 
 	// Set SVCR if we're doing SME
-	cbz	x1, 1f
 	adrp	x2, svcr_in
 	ldr	x2, [x2, :lo12:svcr_in]
+	cbz	x1, 1f
 	msr	S3_3_C4_C2_2, x2
 1:
 
-- 
2.45.2



From mark.rutland at arm.com  Mon Dec  9 03:03:51 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  9 Dec 2024 11:03:51 +0000
Subject: [PATCH] arm64: stacktrace: skip reporting LR at exception boundaries
Message-ID: <20241209110351.1876804-1-mark.rutland@arm.com>

Recently the arm64 stacktrace code was modified to report the LR at
exception boundaries, which interacts poorly with fgraph tracing. It is
possible for the LR to contain the start address of return_to_handler()
even when the LR is not live, and in such cases attempts to recover the
return address via ftrace_graph_ret_addr() may fail, triggering a
WARN_ON_ONCE() in kunwind_recover_return_address() and aborting the
unwind. This has resulted in test failures and unexpected warnings, as
reported by Aishwarya and Kent.

Handling unreliable LR values in these cases is likely to require some
larger rework, so for the moment avoid this problem by restoring the old
behaviour of skipping the LR at exception boundaries, as we did prior to
commit:

  c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")

This commit is effectively a partial revert, keeping the structures and
logic to explicitly identify exception boundaries while still skipping
reporting of the LR. The logic to explicitly identify exception
boundaries is still useful for general robustness and as a building
block for future support for reliably stacktracing.

Fixes: c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reported-by: Aishwarya TCV <aishwarya.tcv at arm.com>
Reported-by: Kent Overstreet <kent.overstreet at linux.dev>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/stacktrace.c | 24 ++----------------------
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index caef85462acb6..4a08ad8158380 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -26,7 +26,6 @@ enum kunwind_source {
 	KUNWIND_SOURCE_CALLER,
 	KUNWIND_SOURCE_TASK,
 	KUNWIND_SOURCE_REGS_PC,
-	KUNWIND_SOURCE_REGS_LR,
 };
 
 union unwind_flags {
@@ -178,23 +177,8 @@ int kunwind_next_regs_pc(struct kunwind_state *state)
 	state->regs = regs;
 	state->common.pc = regs->pc;
 	state->common.fp = regs->regs[29];
-	state->source = KUNWIND_SOURCE_REGS_PC;
-	return 0;
-}
-
-static __always_inline int
-kunwind_next_regs_lr(struct kunwind_state *state)
-{
-	/*
-	 * The stack for the regs was consumed by kunwind_next_regs_pc(), so we
-	 * cannot consume that again here, but we know the regs are safe to
-	 * access.
-	 */
-	state->common.pc = state->regs->regs[30];
-	state->common.fp = state->regs->regs[29];
 	state->regs = NULL;
-	state->source = KUNWIND_SOURCE_REGS_LR;
-
+	state->source = KUNWIND_SOURCE_REGS_PC;
 	return 0;
 }
 
@@ -274,11 +258,8 @@ kunwind_next(struct kunwind_state *state)
 	case KUNWIND_SOURCE_FRAME:
 	case KUNWIND_SOURCE_CALLER:
 	case KUNWIND_SOURCE_TASK:
-	case KUNWIND_SOURCE_REGS_LR:
-		err = kunwind_next_frame_record(state);
-		break;
 	case KUNWIND_SOURCE_REGS_PC:
-		err = kunwind_next_regs_lr(state);
+		err = kunwind_next_frame_record(state);
 		break;
 	default:
 		err = -EINVAL;
@@ -436,7 +417,6 @@ static const char *state_source_string(const struct kunwind_state *state)
 	case KUNWIND_SOURCE_CALLER:	return "C";
 	case KUNWIND_SOURCE_TASK:	return "T";
 	case KUNWIND_SOURCE_REGS_PC:	return "P";
-	case KUNWIND_SOURCE_REGS_LR:	return "L";
 	default:			return "U";
 	}
 }
-- 
2.30.2



From towinchenmi at gmail.com  Mon Dec  9 03:07:35 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 9 Dec 2024 19:07:35 +0800
Subject: [PATCH v2 1/3] dt-bindings: leds: backlight: apple,dwi-bl: Add
 bindings for Apple DWI backlight
In-Reply-To: <iwapssdmronnbtmlmynuarzmkd2oh3ssrmzvlobxx4ixrgwgcl@dnonaahib6jw>
References: <20241207130433.30351-1-towinchenmi@gmail.com>
 <20241207130433.30351-2-towinchenmi@gmail.com>
 <iwapssdmronnbtmlmynuarzmkd2oh3ssrmzvlobxx4ixrgwgcl@dnonaahib6jw>
Message-ID: <494a944e-4088-463a-abbb-c0a8cf4455ec@gmail.com>



On 9/12/2024 17:16, Krzysztof Kozlowski wrote:
> On Sat, Dec 07, 2024 at 09:03:14PM +0800, Nick Chan wrote:
>> Add the device tree bindings for backlight controllers attached via Apple
>> DWI 2-wire interface.
[...]

Ack all the changes, will be in v4.

Nick Chan


From wahrenst at gmx.net  Mon Dec  9 03:13:16 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon,  9 Dec 2024 12:13:16 +0100
Subject: [PATCH] spi: mxs: support effective_speed_hz
Message-ID: <20241209111316.4767-1-wahrenst@gmx.net>

Setting spi_transfer->effective_speed_hz in transfer_one_message so that
SPI client driver can use it.

Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/spi/spi-mxs.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index e6d955d964f4..43455305fdf4 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -381,6 +381,8 @@ static int mxs_spi_transfer_one(struct spi_controller *host,
 		if (status)
 			break;

+		t->effective_speed_hz = ssp->clk_rate;
+
 		/* De-assert on last transfer, inverted by cs_change flag */
 		flag = (&t->transfer_list == m->transfers.prev) ^ t->cs_change ?
 		       TXRX_DEASSERT_CS : 0;
--
2.34.1



From lukma at denx.de  Mon Dec  9 03:16:19 2024
From: lukma at denx.de (Lukasz Majewski)
Date: Mon, 9 Dec 2024 12:16:19 +0100
Subject: [PATCH v11 3/3] ARM: dts: mxs: Add descriptions for imx287
 based btt3-[012] devices
In-Reply-To: <c8fd371f-fd36-48c4-ad49-1e8f8db01383@gmx.net>
References: <20241107085705.490940-1-lukma@denx.de>
	<20241107085705.490940-3-lukma@denx.de>
	<20241119165236.69438f75@wsk>
	<c8fd371f-fd36-48c4-ad49-1e8f8db01383@gmx.net>
Message-ID: <20241209121619.623886a4@wsk>

Hi Stefan,

> Am 19.11.24 um 16:52 schrieb Lukasz Majewski:
> > Dear Community,
> >  
> >> The btt3 device' HW revisions from 0 to 2 use imx287 SoC and are to
> >> some extend similar to already upstreamed XEA devices, hence are
> >> using common imx28-lwe.dtsi file.
> >>
> >> New, imx28-btt3.dtsi has been added to embrace common DTS
> >> properties for different HW revisions for this device.
> >>
> >> As a result - changes introduced in imx28-btt3-[012].dts are
> >> minimal.
> >>  
> > Are there any more comments / suggestions for this patch set?  
> I've send my RB for this patch on October 31th for V10, but it didn't
> made it into V11.

Sorry, I've just noticed it.

When the yaml patches are applied/accepted, I will either resend the
dts patches with your Reviewed-by or maybe this tag can be added when
applying the code by the maintainer (Shawn).


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- 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/20241209/22793cfc/attachment.sig>

From thomas.richard at bootlin.com  Mon Dec  9 03:23:21 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Mon,  9 Dec 2024 12:23:21 +0100
Subject: [PATCH] PCI: j721e: In j721e_pcie_suspend_noirq() check reset_gpio before to use it
Message-ID: <20241209112321.65320-1-thomas.richard@bootlin.com>

The reset_gpio is optional, so in j721e_pcie_suspend_noirq() check if it is
not NULL before to use it.

Fixes: c538d40f365b ("PCI: j721e: Add suspend and resume support")
Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 0341d51d6aed..5bc14dd70811 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -644,7 +644,9 @@ 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);
+		if (pcie->reset_gpio)
+			gpiod_set_value_cansleep(pcie->reset_gpio, 0);
+
 		clk_disable_unprepare(pcie->refclk);
 	}
 
-- 
2.39.5



From s-vadapalli at ti.com  Mon Dec  9 03:26:57 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Mon, 9 Dec 2024 16:56:57 +0530
Subject: [PATCH] PCI: j721e: In j721e_pcie_suspend_noirq() check
 reset_gpio before to use it
In-Reply-To: <20241209112321.65320-1-thomas.richard@bootlin.com>
References: <20241209112321.65320-1-thomas.richard@bootlin.com>
Message-ID: <laghliul4hk7lqzkt6i4ddnvfhyq7q5esgdzx24h5vaougtner@5wcboaak2cxy>

On Mon, Dec 09, 2024 at 12:23:21PM +0100, Thomas Richard wrote:
> The reset_gpio is optional, so in j721e_pcie_suspend_noirq() check if it is
> not NULL before to use it.
> 
> Fixes: c538d40f365b ("PCI: j721e: Add suspend and resume support")
> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>

Reviewed-by: Siddharth Vadapalli <s-vadapalli at ti.com>

> ---
>  drivers/pci/controller/cadence/pci-j721e.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
> index 0341d51d6aed..5bc14dd70811 100644
> --- a/drivers/pci/controller/cadence/pci-j721e.c
> +++ b/drivers/pci/controller/cadence/pci-j721e.c
> @@ -644,7 +644,9 @@ 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);
> +		if (pcie->reset_gpio)
> +			gpiod_set_value_cansleep(pcie->reset_gpio, 0);
> +
>  		clk_disable_unprepare(pcie->refclk);
>  	}
>  

Regards,
Siddharth.


From krzysztof.kozlowski at linaro.org  Mon Dec  9 03:29:20 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon,  9 Dec 2024 12:29:20 +0100
Subject: [RESEND PATCH] arm64: dts: mediatek: mt8183-kukui: align thermal node names with bindings
Message-ID: <20241209112920.70060-1-krzysztof.kozlowski@linaro.org>

Bindings expect thermal zones node name to follow certain pattern.
This fixes dtbs_check warning:

  mt8183-kukui-jacuzzi-burnet.dtb: thermal-zones: 'tboard1', 'tboard2'
    do not match any of the regexes: '^[a-zA-Z][a-zA-Z0-9\\-]{1,10}-thermal$', 'pinctrl-[0-9]+'

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

---

Sent in July, then Chen-Yu pinged in October. Can you apply it?
https://lore.kernel.org/all/CAGXv+5HSZfr14K1sGky4g9Sik987DAisH7KTZn9v_svOwF+y6A at mail.gmail.com/
---
 arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
index 4b974bb781b1..2828f34949ae 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -944,13 +944,13 @@ &ssusb {
 };
 
 &thermal_zones {
-	tboard1 {
+	tboard1-thermal {
 		polling-delay = <1000>; /* milliseconds */
 		polling-delay-passive = <0>; /* milliseconds */
 		thermal-sensors = <&tboard_thermistor1>;
 	};
 
-	tboard2 {
+	tboard2-thermal {
 		polling-delay = <1000>; /* milliseconds */
 		polling-delay-passive = <0>; /* milliseconds */
 		thermal-sensors = <&tboard_thermistor2>;
-- 
2.43.0



From quentin.schulz at cherry.de  Mon Dec  9 03:30:09 2024
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Mon, 9 Dec 2024 12:30:09 +0100
Subject: [PATCH v3] arm64: dts: rockchip: increase gmac rx_delay on
 rk3399-puma
In-Reply-To: <20241205151827.282130-1-jakob.unterwurzacher@cherry.de>
References: <20241205151827.282130-1-jakob.unterwurzacher@cherry.de>
Message-ID: <93b1101b-fb3f-40b2-a2a6-11c942a8ccd2@cherry.de>

Hi Jakob,

On 12/5/24 4:18 PM, Jakob Unterwurzacher wrote:
> During mass manufacturing, we noticed the mmc_rx_crc_error counter,
> as reported by "ethtool -S eth0 | grep mmc_rx_crc_error", to increase
> above zero during nuttcp speedtests. Most of the time, this did not
> affect the achieved speed, but it prompted this investigation.
> 
> Cycling through the rx_delay range on six boards (see table below) of
> various ages shows that there is a large good region from 0x12 to 0x35
> where we see zero crc errors on all tested boards.
> 
> The old rx_delay value (0x10) seems to have always been on the edge for
> the KSZ9031RNX that is usually placed on Puma.
> 
> Choose "rx_delay = 0x23" to put us smack in the middle of the good
> region. This works fine as well with the KSZ9131RNX PHY that was used
> for a small number of boards during the COVID chip shortages.
> 
> 	Board S/N        PHY        rx_delay good region
> 	---------        ---        --------------------
> 	Puma TT0069903   KSZ9031RNX 0x11 0x35
> 	Puma TT0157733   KSZ9031RNX 0x11 0x35
> 	Puma TT0681551   KSZ9031RNX 0x12 0x37
> 	Puma TT0681156   KSZ9031RNX 0x10 0x38
> 	Puma 17496030079 KSZ9031RNX 0x10 0x37 (Puma v1.2 from 2017)
> 	Puma TT0681720   KSZ9131RNX 0x02 0x39 (alternative PHY used in very few boards)
> 
> 	Intersection of good regions = 0x12 0x35
> 	Middle of good region = 0x23
> 
> Relates-to: PUMA-111
> Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")
> Cc: <stable at vger.kernel.org>
> Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>
> Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at cherry.de>

I had reported errors on my v2.1 Puma (KSZ9031) but none on my v2.3 
before that patch, and have 0 after applying this patch on both, so 
improvement for v2.1 and no regression for v2.3.

I ran the nuttcp test for an hour, failed after a minute on master 
(without the patch) on v2.1 but not on v2.3 and it didn't report any 
issue after an hour after applying this patch, thus:

Tested-by: Quentin Schulz <quentin.schulz at cherry.de> # Puma v2.1/v2.3 
with KSZ9031

I assume Krzysztof complained about their old email address appearing in 
the Cc list (it was changed in 6.9 in MAINTAINERS file) which 
highlighted you didn't develop on master (I did test on master though). 
Please address their concern from their mail and send a v4.

Thanks!
Quentin


From angelogioacchino.delregno at collabora.com  Mon Dec  9 03:33:57 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 12:33:57 +0100
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <m7u6xzm2o4dmcjot4xfk6do4slikpsp6gi3uyiuw4d35kunbc5@jyzgkrp4xjwc>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
 <4lvsvo6vsc7bipcgftsq3mzunwxoka3wjqad42ptr37oz77zub@5uarhvjmcxnc>
 <a4a74f96-29cc-4007-9b03-f634b84d9cc2@collabora.com>
 <m7u6xzm2o4dmcjot4xfk6do4slikpsp6gi3uyiuw4d35kunbc5@jyzgkrp4xjwc>
Message-ID: <3a0512de-bcc0-4253-a8c1-f2e43b5cbfba@collabora.com>

Il 05/12/24 20:35, Dmitry Baryshkov ha scritto:
> On Thu, Dec 05, 2024 at 02:30:51PM +0100, AngeloGioacchino Del Regno wrote:
>> Il 05/12/24 13:56, Dmitry Baryshkov ha scritto:
>>> On Thu, Dec 05, 2024 at 12:45:17PM +0100, AngeloGioacchino Del Regno wrote:
>>>> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
>>>> found in MediaTek's MT8195, MT8188 SoC and their variants, and
>>>> including support for display modes up to 4k60 and for HDMI
>>>> Audio, as per the HDMI 2.0 spec.
>>>>
>>>> HDCP and CEC functionalities are also supported by this hardware,
>>>> but are not included in this commit and that also poses a slight
>>>> difference between the V2 and V1 controllers in how they handle
>>>> Hotplug Detection (HPD).
>>>>
>>>> While the v1 controller was using the CEC controller to check
>>>> HDMI cable connection and disconnection, in this driver the v2
>>>> one does not.
>>>>
>>>> This is due to the fact that on parts with v2 designs, like the
>>>> MT8195 SoC, there is one CEC controller shared between the HDMI
>>>> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
>>>> adding support to use the CEC HW to wake up the HDMI controllers
>>>> it is necessary to have support for one TX, one RX *and* for both
>>>> at the same time.
>>>>
>>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>>> ---
>>>>    drivers/gpu/drm/mediatek/Kconfig            |    8 +
>>>>    drivers/gpu/drm/mediatek/Makefile           |    4 +
>>>>    drivers/gpu/drm/mediatek/mtk_hdmi_common.c  |    5 +
>>>>    drivers/gpu/drm/mediatek/mtk_hdmi_common.h  |    1 +
>>>>    drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c  |  403 +++++
>>>>    drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h |  263 ++++
>>>>    drivers/gpu/drm/mediatek/mtk_hdmi_v2.c      | 1488 +++++++++++++++++++
>>>>    7 files changed, 2172 insertions(+)
>>>>    create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
>>>>    create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
>>>>    create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
>>>>
>>
>> ..snip..
>>
>>>> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
>>>> new file mode 100644
>>>> index 000000000000..05cbfc45be54
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
>>>> @@ -0,0 +1,1488 @@
>>>> +// SPDX-License-Identifier: GPL-2.0
>>>> +/*
>>
>> ..snip..
>>
>>>> +static int mtk_hdmi_v2_setup_audio_infoframe(struct mtk_hdmi *hdmi)
>>>> +{
>>>> +	struct hdmi_codec_params *params = &hdmi->aud_param.codec_params;
>>>> +	struct hdmi_audio_infoframe frame;
>>>> +	u8 buffer[14];
>>>> +	ssize_t ret;
>>>> +
>>>> +	memcpy(&frame, &params->cea, sizeof(frame));
>>>> +
>>>> +	ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
>>>> +	if (ret < 0)
>>>> +		return ret;
>>>> +
>>>> +	mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
>>>
>>> This should be handled via HDMI Connector framework too. There is
>>> already an interface to set / clear audio infoframes.
>>> als I have been working on an interface to make HDMI codec
>>> implementation more generic, see [1]. Your comments are appreciated.
>>>
>>> [1] https://patchwork.freedesktop.org/series/134927/
>>>
>>
>> I didn't go for that because I was afraid that your series wouldn't actually
>> land in the same window as this driver.
> 
> There were two points in my comment (sorry for being not explicit
> enough). One is to point to the HDMI codec infra (and you are right,
> it's not yet in the mergeable state). Second one is to use
> drm_atomic_helper_connector_hdmi_update_audio_infoframe() and
> drm_atomic_helper_connector_hdmi_clear_audio_infoframe() if possible (it
> might be hard to do it - in fact it being hard kind of forced me to
> work on the HDMI codec infra).
> 

That *is* indeed hard and adding almost unnecessary complications to my submission.

>> I am at this point puzzled to whether I should add a commit on top of this
>> submission that switches this driver to using the generic HDMI Codec infra
>> (which could also be helpful as guidance to others trying to do the same on
>> other drivers, I guess), or if I should just rebase on top of that.
> 
> I'd say, a completely separate patch might be even better, I can then
> integrate it into the HDMI codec patchset, adding a soft dependency on
> your series. If for some reason the codec lands earlier than your
> patchset, the patch can be dropped and reintegrated into your series. Or
> just committed separately.

I'd rather get the audio part merged as-is with the old handling at this point...

As you can see, once your HDMI Codec infra gets in a mergeable state the cleanup
(or conversion, however you prefer to call it) in this driver will be mostly
trivial.

This means that whenever your series is ready to merge, I'll be able to send a
(single, most probably) commit updating this driver to use the new helpers in a
jiffy (or two).

> 
>> I'd rather add a commit on top to mainly avoid risking to delay this driver,
>> but if you're absolutely certain that you can get your series merged in the
>> same window as this driver I have *zero* problems in just rebasing on top.
>>
>> Besides...
>>
>> I'll find the time to review your series - I'm sad it didn't land earlier as
>> I would've written a bit less code otherwise :-)
>>
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>
>> ..snip..
>>
>>>> +
>>>> +	/* Enable the controller at attach time for HPD/Pord feedback */
>>>> +	ret = mtk_hdmi_v2_enable(hdmi);
>>>> +	if (ret)
>>>> +		return ret;
>>>
>>> This looks like a hack. Please use .hpd_enable() / .hpd_disable()
>>> callbacks.
>>>
>>
>> ...but there's no way to power on only the HPD - you can either power on
>> the entire controller, or nothing.
>>
>> I can't call mtk_hdmi_v2_enable/disable() from the HPD callbacks.
> 
> Why? Add a powerup refcount if necessary.
> 

...but this means that I still have to keep the mtk_hdmi_v2_enable() call
here, but I didn't understand the point of this until you made me think
about...

>>
>> Perhaps the comment should have been
>>
>> "Enable the controller attach time also allows HPD/Pord feedback"?
> 
> I think it should still be explicit call from those callbacks. Consider
> a platform using external GPIO to implement HPD. Then the HDMI
> controller can stay disabled if it is not necessary.

...this case.

I'm still not sure whether I can actually do what you propose because this
IP needs another IP (mtk_dpi) to be in a configured state before this one
gets enabled, or you get a freeze.

I'll check - if that's feasible, I'll add the refcounting and will go for
the hpd_{en,dis}able callbacks.

> 
>>
>>>> +
>>>> +	/* Enable Hotplug and Pord pins internal debouncing */
>>>> +	regmap_set_bits(hdmi->regs, HPD_DDC_CTRL,
>>>> +			HPD_DDC_HPD_DBNC_EN | HPD_DDC_PORD_DBNC_EN);
>>>> +
>>>> +	irq_clear_status_flags(hdmi->irq, IRQ_NOAUTOEN);
>>>> +	enable_irq(hdmi->irq);
>>>> +
>>>> +	/*
>>>> +	 * Check if any HDMI monitor was connected before probing this driver
>>>> +	 * and/or attaching the bridge, without debouncing: if so, we want to
>>>> +	 * notify the DRM so that we start outputting an image ASAP.
>>>> +	 * Note that calling the ISR thread function will also perform a HW
>>>> +	 * registers write that enables both the HPD and Pord interrupts.
>>>> +	 */
>>>> +	__mtk_hdmi_v2_isr_thread(hdmi);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>
>> ..snip..
>>
>>>> +static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
>>>> +					  struct drm_bridge_state *old_state)
>>>> +{
>>>> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>>>> +	struct drm_atomic_state *state = old_state->base.state;
>>>> +	struct drm_connector_state *conn_state;
>>>> +	union phy_configure_opts opts = {
>>>> +		.dp = { .link_rate = hdmi->mode.clock * KILO }
>>>> +	};
>>>> +
>>>> +	/* Retrieve the connector through the atomic state */
>>>> +	hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
>>>> +
>>>> +	conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
>>>> +	if (WARN_ON(!conn_state))
>>>> +		return;
>>>> +
>>>> +	/*
>>>> +	 * Preconfigure the HDMI controller and the HDMI PHY at pre_enable
>>>> +	 * stage to make sure that this IP is ready and clocked before the
>>>> +	 * mtk_dpi gets powered on and before it enables the output.
>>>> +	 */
>>>> +	hdmi->dvi_mode = !hdmi->curr_conn->display_info.is_hdmi;
>>>
>>> Can you access display_info directly instead?
>>>
>>
>> Nice catch. Yeah, I should've done that from the beginning. Fixed for v3.
>>
>>>> +	mtk_hdmi_v2_output_set_display_mode(hdmi, &hdmi->mode);
>>>> +
>>>> +	/* Reconfigure phy clock link with appropriate rate */
>>>> +	phy_configure(hdmi->phy, &opts);
>>>> +
>>>> +	/* Power on the PHY here to make sure that DPI_HDMI is clocked */
>>>> +	phy_power_on(hdmi->phy);
>>>> +
>>>> +	hdmi->powered = true;
>>>> +}
>>>> +
>>>> +static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
>>>> +				      struct drm_bridge_state *old_state)
>>>> +{
>>>> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>>>> +	struct drm_atomic_state *state = old_state->base.state;
>>>> +	int ret;
>>>> +
>>>> +	ret = drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
>>>> +	if (ret)
>>>> +		dev_err(hdmi->dev, "Could not update infoframes: %d\n", ret);
>>>> +
>>>> +	mtk_hdmi_v2_hw_vid_mute(hdmi, false);
>>>> +	mtk_hdmi_v2_hw_aud_mute(hdmi, false);
>>>> +
>>>> +	/* signal the connect event to audio codec */
>>>> +	mtk_hdmi_v2_handle_plugged_change(hdmi, true);
>>>
>>> I think it was agreed that this should be called from the hotplug path,
>>> see the (linked) HDMI codec infrastructure patchset and dicussions for
>>> the previous revisions.
>>>
>>
>> Okay, I'll check that out.
>>
>>>> +
>>>> +	hdmi->enabled = true;
>>>> +}
>>>> +
>>
>> ..snip..
>>
>>>> +
>>>> +static int mtk_hdmi_v2_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
>>>> +						 const struct drm_display_mode *mode,
>>>> +						 unsigned long long tmds_rate)
>>>> +{
>>>> +	if (mode->clock < MTK_HDMI_V2_CLOCK_MIN)
>>>> +		return MODE_CLOCK_LOW;
>>>> +	else if (mode->clock > MTK_HDMI_V2_CLOCK_MAX)
>>>> +		return MODE_CLOCK_HIGH;
>>>> +	else
>>>> +		return MODE_OK;
>>>> +}
>>>> +
>>>> +static enum drm_mode_status
>>>> +mtk_hdmi_v2_bridge_mode_valid(struct drm_bridge *bridge,
>>>> +			      const struct drm_display_info *info,
>>>> +			      const struct drm_display_mode *mode)
>>>> +{
>>>> +	unsigned long long rate;
>>>> +
>>>> +	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
>>>> +	return mtk_hdmi_v2_hdmi_tmds_char_rate_valid(bridge, mode, rate);
>>>> +}
>>>
>>> Please rebase on top of https://patchwork.freedesktop.org/series/140193/
>>> There should be no need to do this manually.
>>>
>>
>> Oh finally there's a helper for this. Cool, will rebase! Thanks!
> 
> And it doesn't even add an extra dependency for you.
> 

... Which is even cool-er, yes :-)

>>
>>>> +
>>>> +static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge,
>>>> +					    enum hdmi_infoframe_type type)
>>>> +{
>>>> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>>>> +	u32 reg_start, reg_end;
>>>> +
>>>> +	switch (type) {
>>>> +	case HDMI_INFOFRAME_TYPE_AUDIO:
>>>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
>>>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
>>>> +		reg_start = TOP_AIF_HEADER;
>>>> +		reg_end = TOP_AIF_PKT03;
>>>> +		break;
>>>> +	case HDMI_INFOFRAME_TYPE_AVI:
>>>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
>>>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
>>>> +		reg_start = TOP_AVI_HEADER;
>>>> +		reg_end = TOP_AVI_PKT05;
>>>> +		break;
>>>> +	case HDMI_INFOFRAME_TYPE_SPD:
>>>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
>>>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
>>>> +		reg_start = TOP_SPDIF_HEADER;
>>>> +		reg_end = TOP_SPDIF_PKT07;
>>>> +		break;
>>>> +	case HDMI_INFOFRAME_TYPE_VENDOR:
>>>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
>>>> +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
>>>> +		reg_start = TOP_VSIF_HEADER;
>>>> +		reg_end = TOP_VSIF_PKT07;
>>>> +		break;
>>>> +	case HDMI_INFOFRAME_TYPE_DRM:
>>>> +	default:
>>>> +		return 0;
>>>> +	};
>>>> +
>>>> +	for (; reg_start <= reg_end; reg_start += 4)
>>>> +		regmap_write(hdmi->regs, reg_start, 0);
>>>
>>> Interesting. Usually sending of the infoframe is controlled by a
>>> register of a kind.
>>>
>>
>> "This callback clears the infoframes in the hardware during commit"
>>
>> ...and that's exactly what this function does: clears the infoframes
>> in the HW and stops the RPT, making the HW ready for the "next round".
>>
>> Did I get the documentation wrong?
>> Should this function *send* an all-zero infoframe to the external display?
> 
> No, it should stop sending the callback. My point was that usually there
> is a separate register which controls the infoframes. You code just
> clears the header (which probably is handled as disabling in the IP
> core).
> 

No, my code is clearing everything, not just the header.

The registers in this IP are sequential, I'm setting the code to start writing
at HEADER, and stop writing at PKTxx, where PKTxx registers contain the infoframe.

In any case, disabling in the IP core is managed by clearing the _EN and _EN_WR
(where WR means "Write", and RPT_EN is "repeat write") bits in the xxx_INFO_EN
register(s), and that's what I'm doing at the beginning, before actually cleaning
the infoframe registers.

Actually, I could've just cleared the EN bits and that would've been enough, but
I wanted to leave the IP in a clean+known state and decided to zero out the entire
infoframe header/data register set.

....but anyway, what you just said before me explaining how this IP works means
that I got it right, and that this function does exactly what it is supposed to do.


Cheers!
Angelo

>>
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge,
>>>> +					    enum hdmi_infoframe_type type,
>>>> +					    const u8 *buffer, size_t len)
>>>> +{
>>>> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>>>> +
>>>> +	switch (type) {
>>>> +	case HDMI_INFOFRAME_TYPE_AUDIO:
>>>> +		mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
>>>> +		break;
>>>> +	case HDMI_INFOFRAME_TYPE_AVI:
>>>> +		mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer);
>>>> +		break;
>>>> +	case HDMI_INFOFRAME_TYPE_SPD:
>>>> +		mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer);
>>>> +		break;
>>>> +	case HDMI_INFOFRAME_TYPE_VENDOR:
>>>> +		mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer);
>>>> +		break;
>>>> +	case HDMI_INFOFRAME_TYPE_DRM:
>>>> +	default:
>>>> +		dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type);
>>>> +		break;
>>>> +	};
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int mtk_hdmi_v2_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)
>>>> +{
>>>> +	return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
>>>> +						      conn_state->state);
>>>> +}
>>>
>>> Note to myself, probably we can move this to drm_bridge_connector too.
>>>
>>>> +
>>>> +static int mtk_hdmi_v2_set_abist(struct mtk_hdmi *hdmi, bool enable)
>>>> +{
>>>> +	struct drm_display_mode *mode = &hdmi->mode;
>>>> +	int abist_format = -EINVAL;
>>>> +	bool interlaced;
>>>> +
>>>> +	if (!enable) {
>>>> +		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
>>>> +		return 0;
>>>> +	}
>>>> +
>>>> +	if (!mode->hdisplay || !mode->vdisplay)
>>>> +		return -EINVAL;
>>>> +
>>>> +	interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
>>>
>>> The interlaced modes should be filtered, unless you also set
>>> bridge->interlace_allowed to true.
>>>
>>
>> Noted. Many Thanks for the review!
>>
>> I'll wait until next week for more feedback before sending a v3.
> 


-- 
AngeloGioacchino Del Regno
Senior Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


From krzysztof.kozlowski at linaro.org  Mon Dec  9 03:34:05 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon,  9 Dec 2024 12:34:05 +0100
Subject: [RESEND PATCH] media: dt-bindings: trivial white-space and example cleanup
Message-ID: <20241209113405.74226-1-krzysztof.kozlowski@linaro.org>

Minor cleanups without funcitonal impact:
 - There should not be an empty blank line after SPDX tag,
 - Convention is to indent DTS examples in coding style with 2- or
   4-space indentation (4 is preferred),
 - Drop unused labels in DTS examples.

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

---

No comments since August... Can it be applied?

---


 .../media/allwinner,sun50i-h6-vpu-g2.yaml     |  1 -
 .../bindings/media/amlogic,meson-ir-tx.yaml   |  1 -
 .../bindings/media/amphion,vpu.yaml           |  1 -
 .../bindings/media/fsl,imx6ull-pxp.yaml       |  1 -
 .../media/mediatek,vcodec-decoder.yaml        |  1 -
 .../media/mediatek,vcodec-encoder.yaml        |  1 -
 .../media/mediatek,vcodec-subdev-decoder.yaml |  1 -
 .../media/microchip,sama5d4-vdec.yaml         | 17 ++++----
 .../bindings/media/nxp,imx8mq-vpu.yaml        | 41 +++++++++----------
 .../bindings/media/qcom,msm8916-camss.yaml    |  1 -
 .../bindings/media/qcom,msm8996-camss.yaml    |  1 -
 .../bindings/media/qcom,sdm660-camss.yaml     |  1 -
 .../bindings/media/qcom,sdm845-camss.yaml     |  1 -
 .../bindings/media/qcom,sm8250-camss.yaml     |  1 -
 .../bindings/media/rockchip,rk3568-vepu.yaml  |  1 -
 .../bindings/media/rockchip-vpu.yaml          | 29 +++++++------
 16 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml b/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
index a4f06bbdfe49..8ba5177ac631 100644
--- a/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
+++ b/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/allwinner,sun50i-h6-vpu-g2.yaml#
diff --git a/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml b/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
index 377acce93423..6da8a6aded23 100644
--- a/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
+++ b/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/amlogic,meson-ir-tx.yaml#
diff --git a/Documentation/devicetree/bindings/media/amphion,vpu.yaml b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
index 9801de3ed84e..5a920d9e78c7 100644
--- a/Documentation/devicetree/bindings/media/amphion,vpu.yaml
+++ b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/amphion,vpu.yaml#
diff --git a/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml b/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
index 84a5e894ace4..3f47744459aa 100644
--- a/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
+++ b/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/fsl,imx6ull-pxp.yaml#
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
index b401c67e3ba0..d726d141a434 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/mediatek,vcodec-decoder.yaml#
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
index b45743d0a9ec..110e8f5f1f9e 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/mediatek,vcodec-encoder.yaml#
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
index a500a585c692..5865e6f0be89 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#
diff --git a/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml b/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
index 59b805ca47c5..ede086d55add 100644
--- a/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
+++ b/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/microchip,sama5d4-vdec.yaml#
@@ -36,12 +35,12 @@ additionalProperties: false
 
 examples:
   - |
-        #include <dt-bindings/clock/at91.h>
-        #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/at91.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
 
-        vdec0: vdec at 300000 {
-                compatible = "microchip,sama5d4-vdec";
-                reg = <0x00300000 0x100000>;
-                interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>;
-                clocks = <&pmc PMC_TYPE_PERIPHERAL 19>;
-        };
+    vdec at 300000 {
+        compatible = "microchip,sama5d4-vdec";
+        reg = <0x00300000 0x100000>;
+        interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>;
+        clocks = <&pmc PMC_TYPE_PERIPHERAL 19>;
+    };
diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
index 3d58f02b0c5d..19528262810a 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#
@@ -44,26 +43,26 @@ additionalProperties: false
 
 examples:
   - |
-        #include <dt-bindings/clock/imx8mq-clock.h>
-        #include <dt-bindings/power/imx8mq-power.h>
-        #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/power/imx8mq-power.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-        vpu_g1: video-codec at 38300000 {
-                compatible = "nxp,imx8mq-vpu-g1";
-                reg = <0x38300000 0x10000>;
-                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-                clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
-                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
-        };
+    video-codec at 38300000 {
+        compatible = "nxp,imx8mq-vpu-g1";
+        reg = <0x38300000 0x10000>;
+        interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
+        power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
+    };
   - |
-        #include <dt-bindings/clock/imx8mq-clock.h>
-        #include <dt-bindings/power/imx8mq-power.h>
-        #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/power/imx8mq-power.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-        vpu_g2: video-codec at 38300000 {
-                compatible = "nxp,imx8mq-vpu-g2";
-                reg = <0x38310000 0x10000>;
-                interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-                clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
-                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
-        };
+    video-codec at 38300000 {
+        compatible = "nxp,imx8mq-vpu-g2";
+        reg = <0x38310000 0x10000>;
+        interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+        power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
+    };
diff --git a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
index 9cc0a968a401..3469a43f00d4 100644
--- a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,msm8916-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
index 5cb0e337ea6e..644646de338a 100644
--- a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,msm8996-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
index 584106e275f6..68d8670557f5 100644
--- a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,sdm660-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
index d32daaef1b50..289494f561e5 100644
--- a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,sdm845-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
index 06db2c1e6079..a372d991e652 100644
--- a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,sm8250-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
index 947ad699cc5e..d246f5d38427 100644
--- a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/rockchip,rk3568-vepu.yaml#
diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
index 719aeb2dc593..8c2501634080 100644
--- a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/rockchip-vpu.yaml#
@@ -92,18 +91,18 @@ additionalProperties: false
 
 examples:
   - |
-        #include <dt-bindings/clock/rk3288-cru.h>
-        #include <dt-bindings/interrupt-controller/arm-gic.h>
-        #include <dt-bindings/power/rk3288-power.h>
+    #include <dt-bindings/clock/rk3288-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/rk3288-power.h>
 
-        vpu: video-codec at ff9a0000 {
-                compatible = "rockchip,rk3288-vpu";
-                reg = <0xff9a0000 0x800>;
-                interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
-                interrupt-names = "vepu", "vdpu";
-                clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
-                clock-names = "aclk", "hclk";
-                power-domains = <&power RK3288_PD_VIDEO>;
-                iommus = <&vpu_mmu>;
-        };
+    video-codec at ff9a0000 {
+        compatible = "rockchip,rk3288-vpu";
+        reg = <0xff9a0000 0x800>;
+        interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "vepu", "vdpu";
+        clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
+        clock-names = "aclk", "hclk";
+        power-domains = <&power RK3288_PD_VIDEO>;
+        iommus = <&vpu_mmu>;
+    };
-- 
2.43.0



From mark.rutland at arm.com  Mon Dec  9 03:37:12 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 9 Dec 2024 11:37:12 +0000
Subject: arm64: stacktrace: unwind exception boundaries
In-Reply-To: <zbwbgkuvvciezpmigcp6gaahfxwm7cwhpzus7gtbfnbzsjb2n3@kfbdppbd74o4>
References: <36kx57aw46vwykgckr5cm4fafhw54tjuj4cqljrdnpfwvjl7if@a7znuhpfu54o>
 <zbwbgkuvvciezpmigcp6gaahfxwm7cwhpzus7gtbfnbzsjb2n3@kfbdppbd74o4>
Message-ID: <Z1bWaGCvUrwrj2fZ@J2N7QTR9R3>

Hi Kent,

On Thu, Dec 05, 2024 at 01:04:59PM -0500, Kent Overstreet wrote:
> On 6.13-rc1, I'm now seeing a ton of test failures due to this warning -
> what gives?

Sorry about this; I just sent what I *thought* was a fix for this:

  https://lore.kernel.org/linux-arm-kernel/20241209110351.1876804-1-mark.rutland at arm.com/

... but re-reading the below I see you're actually hitting a different
issue.

> 00104 ========= TEST   generic/017
> 00104        run fstests generic/017 at 2024-12-05 11:47:43
> 00104 spectre-v4 mitigation disabled by command-line option
> 00106 bcachefs (vdc): starting version 1.13: inode_has_child_snapshots
> 00106 bcachefs (vdc): initializing new filesystem
> 00106 bcachefs (vdc): going read-write
> 00106 bcachefs (vdc): marking superblocks
> 00106 bcachefs (vdc): initializing freespace
> 00106 bcachefs (vdc): done initializing freespace
> 00106 bcachefs (vdc): reading snapshots table
> 00106 bcachefs (vdc): reading snapshots done
> 00106 bcachefs (vdc): done starting filesystem
> 00200 ------------[ cut here ]------------
> 00200 WARNING: CPU: 8 PID: 12571 at arch/arm64/kernel/stacktrace.c:223 arch_stack_walk+0x2c0/0x388

Looking at v6.13-rc1, that's the warning in
kunwind_next_frame_record_meta() for when the frame_record_meta::type is
not a valid value, which likely implies one of the following:

(a) The logic to identify a frame_record_meta is wrong.

(b) The entry logic has failed to initilialize pt_regs::stackframe::meta
    on an entry path somehow.

(c) The stack has been corrupted, and some frame record has been
    clobbered to look like a frame_record_meta.

The unwind will terminate at this point even if the warning is
supressed, so the backtrace from the warning itself should indicate
where the frame record was:

> 00200 Modules linked in:
> 00200 CPU: 8 UID: 0 PID: 12571 Comm: cat Not tainted 6.13.0-rc1-ktest-gdf1fce23d033 #10877
> 00200 Hardware name: linux,dummy-virt (DT)
> 00200 pstate: 80001005 (Nzcv daif -PAN -UAO -TCO -DIT +SSBS BTYPE=--)
> 00200 pc : arch_stack_walk+0x2c0/0x388
> 00200 lr : arch_stack_walk+0x1f4/0x388
> 00200 sp : ffffff80ca757b00
> 00200 x29: ffffff80ca757b00 x28: ffffff80d6783758 x27: 000000000000036f
> 00200 x26: ffffff80d6783780 x25: ffffff80c19de180 x24: ffffff80c273ee40
> 00200 x23: ffffffc080022708 x22: ffffffc080025828 x21: ffffff80ca757be8
> 00200 x20: ffffffc0800c98c8 x19: ffffff80d8533d10 x18: ffffffffffffffff
> 00200 x17: 0000000000000000 x16: 0000000000000000 x15: ffffffffffffffff
> 00200 x14: 0000000000000000 x13: ffffff80d6c92000 x12: 0000000000000000
> 00200 x11: 0000000000000000 x10: 000000000000000a x9 : ffffffc08086beec
> 00200 x8 : ffffff80ca757bc0 x7 : 0000000000000000 x6 : ffffff80d8533d28
> 00200 x5 : ffffff80ca757b60 x4 : ffffff80d8534000 x3 : ffffff80ca757b40
> 00200 x2 : 0000000000000018 x1 : ffffff80d8533d10 x0 : 0000000000000000
> 00200 Call trace:
> 00200  arch_stack_walk+0x2c0/0x388 (P)
> 00200  arch_stack_walk+0x1f4/0x388 (L)
> 00200  stack_trace_save_tsk+0x90/0xd8
> 00200  bch2_save_backtrace+0x68/0x160
> 00200  bch2_prt_task_backtrace+0x30/0xb8
> 00200  bch2_btree_transactions_read+0xe0/0x1f0
> 00200  full_proxy_read+0x60/0xd0
> 00200  vfs_read+0x80/0x2d8
> 00200  ksys_read+0x5c/0xf0
> 00200  __arm64_sys_read+0x20/0x30
> 00200  invoke_syscall.constprop.0+0x54/0xe8
> 00200  do_el0_svc+0x44/0xc8
> 00200  el0_svc+0x18/0x58
> 00200  el0t_64_sync_handler+0x104/0x130
> 00200  el0t_64_sync+0x154/0x158

This suggests that the bad frame_record_meta is in the entry code, in
the pt_regs. There *should* be a frame_record_meta there with type
FRAME_META_TYPE_FINAL, which suggests the probkem isn't case (a) above,
and either the entry code is failing to initialise
pt_regs::stackframe::type somehow, or that is getting corrupted later.

AFAICT, the entry code correctly initializes the frame_record_meta in
the kernel_entry assembly macro:

        /*
         * Create a metadata frame record. The unwinder will use this to
         * identify and unwind exception boundaries.
         */
        stp     xzr, xzr, [sp, #S_STACKFRAME]
        .if \el == 0
        mov     x0, #FRAME_META_TYPE_FINAL
        .else
        mov     x0, #FRAME_META_TYPE_PT_REGS
        .endif
        str     x0, [sp, #S_STACKFRAME_TYPE]
        add     x29, sp, #S_STACKFRAME

... and that's shared by *all* exceptions, so if it were wrong I'd
expect it to trigger an explosion on the very first backtrace taken
under an exception (from userspace or kernel).

Given the above, I'd suspect that maybe you're encountering stack
corruption here.

How are you reproducing this, and how consistently do you see the
failure? Is it always triggered by the same test?

The below diff will log the bad frame_record_meta::type value; if you're
able to run with that it might give an indication as to what's going on.

Mark.

---->8----
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index caef85462acb6..d1d9436c49101 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -205,13 +205,15 @@ kunwind_next_frame_record_meta(struct kunwind_state *state)
        unsigned long fp = state->common.fp;
        struct frame_record_meta *meta;
        struct stack_info *info;
+       u64 type;
 
        info = unwind_find_stack(&state->common, fp, sizeof(*meta));
        if (!info)
                return -EINVAL;
 
        meta = (struct frame_record_meta *)fp;
-       switch (READ_ONCE(meta->type)) {
+       type = READ_ONCE(meta->type);
+       switch (type) {
        case FRAME_META_TYPE_FINAL:
                if (meta == &task_pt_regs(tsk)->stackframe)
                        return -ENOENT;
@@ -220,7 +222,7 @@ kunwind_next_frame_record_meta(struct kunwind_state *state)
        case FRAME_META_TYPE_PT_REGS:
                return kunwind_next_regs_pc(state);
        default:
-               WARN_ON_ONCE(1);
+               WARN_ONCE(1, "Bad frame_record_meta::type: 0x%016llx\n", type);
                return -EINVAL;
        }
 }
 


From angelogioacchino.delregno at collabora.com  Mon Dec  9 03:37:39 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 09 Dec 2024 12:37:39 +0100
Subject: [RESEND PATCH] arm64: dts: mediatek: mt8183-kukui: align
 thermal node names with bindings
In-Reply-To: <20241209112920.70060-1-krzysztof.kozlowski@linaro.org>
References: <20241209112920.70060-1-krzysztof.kozlowski@linaro.org>
Message-ID: <173374425999.50169.9722221830954876718.b4-ty@collabora.com>

On Mon, 09 Dec 2024 12:29:20 +0100, Krzysztof Kozlowski wrote:
> Bindings expect thermal zones node name to follow certain pattern.
> This fixes dtbs_check warning:
> 
>   mt8183-kukui-jacuzzi-burnet.dtb: thermal-zones: 'tboard1', 'tboard2'
>     do not match any of the regexes: '^[a-zA-Z][a-zA-Z0-9\\-]{1,10}-thermal$', 'pinctrl-[0-9]+'
> 
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/1] arm64: dts: mediatek: mt8183-kukui: align thermal node names with bindings
      commit: 4604c989004006cc0c08a9cfe8d80e7544b8e808

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Mon Dec  9 03:42:36 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 12:42:36 +0100
Subject: [PATCH v4 2/2] arm64: dts: mediatek: mt8186: Add Starmie device
In-Reply-To: <20241129055720.3328681-3-wmacek@chromium.org>
References: <20241129055720.3328681-1-wmacek@chromium.org>
 <20241129055720.3328681-3-wmacek@chromium.org>
Message-ID: <92328329-e1f4-40e5-b0e6-946a7500a313@collabora.com>

Il 29/11/24 06:57, Wojciech Macek ha scritto:
> Add support for Starmie Chromebooks.
> 
> Signed-off-by: Wojciech Macek <wmacek at chromium.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From bryan.odonoghue at linaro.org  Mon Dec  9 03:42:35 2024
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Mon, 9 Dec 2024 11:42:35 +0000
Subject: [RESEND PATCH] media: dt-bindings: trivial white-space and
 example cleanup
In-Reply-To: <20241209113405.74226-1-krzysztof.kozlowski@linaro.org>
References: <20241209113405.74226-1-krzysztof.kozlowski@linaro.org>
Message-ID: <c8f42175-3501-4d65-92ba-5878fe5ea5f4@linaro.org>

On 09/12/2024 11:34, Krzysztof Kozlowski wrote:
> diff --git a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
> index 9cc0a968a401..3469a43f00d4 100644
> --- a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
> @@ -1,5 +1,4 @@
>   # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>   %YAML 1.2
>   ---
>   $id:http://devicetree.org/schemas/media/qcom,msm8916-camss.yaml#
> diff --git a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
> index 5cb0e337ea6e..644646de338a 100644
> --- a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
> @@ -1,5 +1,4 @@
>   # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>   %YAML 1.2
>   ---
>   $id:http://devicetree.org/schemas/media/qcom,msm8996-camss.yaml#
> diff --git a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
> index 584106e275f6..68d8670557f5 100644
> --- a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
> @@ -1,5 +1,4 @@
>   # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>   %YAML 1.2
>   ---
>   $id:http://devicetree.org/schemas/media/qcom,sdm660-camss.yaml#
> diff --git a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
> index d32daaef1b50..289494f561e5 100644
> --- a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
> @@ -1,5 +1,4 @@
>   # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>   %YAML 1.2
>   ---
>   $id:http://devicetree.org/schemas/media/qcom,sdm845-camss.yaml#
> diff --git a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> index 06db2c1e6079..a372d991e652 100644
> --- a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> @@ -1,5 +1,4 @@
>   # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>   %YAML 1.2

Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>


From angelogioacchino.delregno at collabora.com  Mon Dec  9 03:50:38 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 12:50:38 +0100
Subject: [PATCH v5 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241202110045.22084-4-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-4-linux@fw-web.de>
Message-ID: <402d1717-f4f4-4ba6-b13c-5dd6e6c44490@collabora.com>

Il 02/12/24 12:00, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> This adds bindings for MT7988 pinctrl driver.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

After you fix the issues pointed out in Rob's review,

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From shameerali.kolothum.thodi at huawei.com  Mon Dec  9 03:53:10 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Mon, 9 Dec 2024 11:53:10 +0000
Subject: [PATCH v3 2/3] KVM: arm64: Introduce hypercall support for retrieving target implementations
In-Reply-To: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>
References: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20241209115311.40496-3-shameerali.kolothum.thodi@huawei.com>

If the Guest requires migration to multiple targets, this hypercall
will provide a way to retrieve the target CPU implementations from
the user space VMM.

Subsequent patch will use this to enable the associated errata.

Suggested-by: Oliver Upton <oliver.upton at linux.dev>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 Documentation/virt/kvm/arm/hypercalls.rst | 30 +++++++++++++++++++++++
 include/linux/arm-smccc.h                 |  7 ++++++
 2 files changed, 37 insertions(+)

diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index af7bc2c2e0cb..16b4c02cf9d9 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -142,3 +142,33 @@ region is equal to the memory protection granule advertised by
 |                     |          |    +---------------------------------------------+
 |                     |          |    | ``INVALID_PARAMETER (-3)``                  |
 +---------------------+----------+----+---------------------------------------------+
+
+``ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID``
+-------------------------------------------------------
+
+Request the target CPU implementation information for the Guest VM. This hypercall
+must be handled by the userspace VMM. The Guest kernel will use this information to
+enable the associated errata. A maximum of 64 implementations is supported.
+
++---------------------+-------------------------------------------------------------+
+| Presence:           | Optional;  KVM/ARM64 Guests only                            |
++---------------------+-------------------------------------------------------------+
+| Calling convention: | HVC64                                                       |
++---------------------+----------+--------------------------------------------------+
+| Function ID:        | (uint32) | 0xC600007E                                       |
++---------------------+----------+----+---------------------------------------------+
+| Arguments:          | (uint64) | R1 | selected implementation index               |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R2 | Reserved / Must be zero                     |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R3 | Reserved / Must be zero                     |
++---------------------+----------+----+---------------------------------------------+
+| Return Values:      | (int64)  | R0 | -1 on error else the maximum required CPU   |
+|                     |          |    | implementation index.                       |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R1 | MIDR_EL1 of the selected implementation     |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R2 | REVIDR_EL1 of the selected implementation   |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R3 | Reserved / Must be zero                     |
++---------------------+----------+----+---------------------------------------------+
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 67f6fdf2e7cd..6c080fa9d345 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -179,6 +179,7 @@
 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62		62
 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63		63
 /* End of pKVM hypercall range */
+#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS	126
 #define ARM_SMCCC_KVM_FUNC_FEATURES_2		127
 #define ARM_SMCCC_KVM_NUM_FUNCS			128
 
@@ -225,6 +226,12 @@
 			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
 			   ARM_SMCCC_KVM_FUNC_MMIO_GUARD)
 
+#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID		\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_64,				\
+			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
+			   ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS)
+
 /* ptp_kvm counter type ID */
 #define KVM_PTP_VIRT_COUNTER			0
 #define KVM_PTP_PHYS_COUNTER			1
-- 
2.47.0



From shawnguo2 at yeah.net  Mon Dec  9 03:53:42 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 19:53:42 +0800
Subject: [PATCH v4 3/3] arm64: dts: imx93-9x9-qsb: add temp-sensor
 nxp,p3t1085
In-Reply-To: <20241112-p3t1085-v4-3-a1334314b1e6@nxp.com>
References: <20241112-p3t1085-v4-0-a1334314b1e6@nxp.com>
 <20241112-p3t1085-v4-3-a1334314b1e6@nxp.com>
Message-ID: <Z1baRpmr4MvsU0NQ@dragon>

On Tue, Nov 12, 2024 at 11:52:01AM -0500, Frank Li wrote:
> Add temp-sensor nxp,p3t1085 for imx93-9x9-qsb boards.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied, thanks!



From shameerali.kolothum.thodi at huawei.com  Mon Dec  9 03:53:11 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Mon, 9 Dec 2024 11:53:11 +0000
Subject: [PATCH v3 3/3] arm64: paravirt: Enable errata based on implementation CPUs
In-Reply-To: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>
References: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20241209115311.40496-4-shameerali.kolothum.thodi@huawei.com>

Retrieve any migration target implementation CPUs using the hypercall
and enable associated errata.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
Note:

One thing I am not sure here is how to handle the hypercall error.
Do we need to fail the Guest boot or just carry on without any
target implementation CPU support? At the moment it just carries on.

Thanks,
Shameer
---
 arch/arm64/include/asm/cputype.h  | 25 +++++++++++++++++++++++--
 arch/arm64/include/asm/paravirt.h |  3 +++
 arch/arm64/kernel/cpu_errata.c    | 20 +++++++++++++++++---
 arch/arm64/kernel/cpufeature.c    |  2 ++
 arch/arm64/kernel/image-vars.h    |  2 ++
 arch/arm64/kernel/paravirt.c      | 31 +++++++++++++++++++++++++++++++
 6 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index dcf0e1ce892d..9e466f3ae9c6 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -265,6 +265,16 @@ struct midr_range {
 #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r)
 #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
 
+#define MAX_TARGET_IMPL_CPUS 64
+
+struct target_impl_cpu {
+	u32 midr;
+	u32 revidr;
+};
+
+extern u32 target_impl_cpu_num;
+extern struct target_impl_cpu target_impl_cpus[];
+
 static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
 					   u32 rv_max)
 {
@@ -276,8 +286,19 @@ static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
 
 static inline bool is_midr_in_range(struct midr_range const *range)
 {
-	return midr_is_cpu_model_range(read_cpuid_id(), range->model,
-				       range->rv_min, range->rv_max);
+	int i;
+
+	if (!target_impl_cpu_num)
+		return midr_is_cpu_model_range(read_cpuid_id(), range->model,
+					       range->rv_min, range->rv_max);
+
+	for (i = 0; i < target_impl_cpu_num; i++) {
+		if (midr_is_cpu_model_range(target_impl_cpus[i].midr,
+					    range->model,
+					    range->rv_min, range->rv_max))
+			return true;
+	}
+	return false;
 }
 
 static inline bool
diff --git a/arch/arm64/include/asm/paravirt.h b/arch/arm64/include/asm/paravirt.h
index 9aa193e0e8f2..95f1c15bbb7d 100644
--- a/arch/arm64/include/asm/paravirt.h
+++ b/arch/arm64/include/asm/paravirt.h
@@ -19,11 +19,14 @@ static inline u64 paravirt_steal_clock(int cpu)
 }
 
 int __init pv_time_init(void);
+void __init pv_target_impl_cpu_init(void);
 
 #else
 
 #define pv_time_init() do {} while (0)
 
+#define pv_target_impl_cpu_init() do {} while (0)
+
 #endif // CONFIG_PARAVIRT
 
 #endif
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 929685c00263..4055082ce69b 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -14,6 +14,9 @@
 #include <asm/kvm_asm.h>
 #include <asm/smp_plat.h>
 
+u32 target_impl_cpu_num;
+struct target_impl_cpu target_impl_cpus[MAX_TARGET_IMPL_CPUS];
+
 static bool __maybe_unused
 __is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
 			 u32 midr, u32 revidr)
@@ -32,9 +35,20 @@ __is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
 static bool __maybe_unused
 is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
 {
-	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	return __is_affected_midr_range(entry, read_cpuid_id(),
-					read_cpuid(REVIDR_EL1));
+	int i;
+
+	if (!target_impl_cpu_num) {
+		WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+		return __is_affected_midr_range(entry, read_cpuid_id(),
+						read_cpuid(REVIDR_EL1));
+	}
+
+	for (i = 0; i < target_impl_cpu_num; i++) {
+		if (__is_affected_midr_range(entry, target_impl_cpus[i].midr,
+					     target_impl_cpus[i].midr))
+			return true;
+	}
+	return false;
 }
 
 static bool __maybe_unused
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 4cc4ae16b28d..d32c767bf189 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -85,6 +85,7 @@
 #include <asm/kvm_host.h>
 #include <asm/mmu_context.h>
 #include <asm/mte.h>
+#include <asm/paravirt.h>
 #include <asm/processor.h>
 #include <asm/smp.h>
 #include <asm/sysreg.h>
@@ -3642,6 +3643,7 @@ unsigned long cpu_get_elf_hwcap3(void)
 
 static void __init setup_boot_cpu_capabilities(void)
 {
+	pv_target_impl_cpu_init();
 	/*
 	 * The boot CPU's feature register values have been recorded. Detect
 	 * boot cpucaps and local cpucaps for the boot CPU, then enable and
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 8f5422ed1b75..694e19709c46 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -49,6 +49,8 @@ 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);
+PROVIDE(__pi_target_impl_cpu_num	= target_impl_cpu_num);
+PROVIDE(__pi_target_impl_cpus		= target_impl_cpus);
 #endif
 PROVIDE(__pi__ctype			= _ctype);
 PROVIDE(__pi_memstart_offset_seed	= memstart_offset_seed);
diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c
index aa718d6a9274..95fc3aae4a27 100644
--- a/arch/arm64/kernel/paravirt.c
+++ b/arch/arm64/kernel/paravirt.c
@@ -153,6 +153,37 @@ static bool __init has_pv_steal_clock(void)
 	return (res.a0 == SMCCC_RET_SUCCESS);
 }
 
+void  __init pv_target_impl_cpu_init(void)
+{
+	struct arm_smccc_res res;
+	int index = 0, max_idx = -1;
+
+	/* Check we have already set targets */
+	if (target_impl_cpu_num)
+		return;
+
+	do {
+		arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID,
+				     index, &res);
+		if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
+			return;
+
+		if (max_idx < 0) {
+			/* res.a0 should have a valid maximum CPU implementation index */
+			if (res.a0 >= MAX_TARGET_IMPL_CPUS)
+				return;
+			max_idx = res.a0;
+		}
+
+		target_impl_cpus[index].midr = res.a1;
+		target_impl_cpus[index].revidr = res.a2;
+		index++;
+	} while (index <= max_idx);
+
+	target_impl_cpu_num = index;
+	pr_info("Number of target implementation CPUs is %d\n", target_impl_cpu_num);
+}
+
 int __init pv_time_init(void)
 {
 	int ret;
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Mon Dec  9 03:52:04 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 12:52:04 +0100
Subject: [PATCH v5 5/5] arm64: dts: mediatek: mt7988: add pinctrl subnodes
 for bpi-r4
In-Reply-To: <20241202110045.22084-6-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-6-linux@fw-web.de>
Message-ID: <9b1a385e-da1c-429b-91b9-d5b5d6d5abb7@collabora.com>

Il 02/12/24 12:00, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add board specidic pinctrl configurations on Bananapi R4.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Can you change the title as suggested in the review for the other series?
So that we stay consistent.

After which,

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Dec  9 03:52:17 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 12:52:17 +0100
Subject: [PATCH v5 4/5] arm64: dts: mediatek: mt7988: add pinctrl support
In-Reply-To: <20241202110045.22084-5-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-5-linux@fw-web.de>
Message-ID: <dc445076-269e-4600-98f3-52158f73baac@collabora.com>

Il 02/12/24 12:00, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add mt7988a pinctrl node.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From shawnguo2 at yeah.net  Mon Dec  9 03:51:26 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 19:51:26 +0800
Subject: [PATCH v6 1/7] arm64: dts: imx8mp-skov-revb-mi1010ait-1cp1: Set
 "media_disp2_pix" clock rate to 70MHz
In-Reply-To: <20241112100547.2908497-2-victor.liu@nxp.com>
References: <20241112100547.2908497-1-victor.liu@nxp.com>
 <20241112100547.2908497-2-victor.liu@nxp.com>
Message-ID: <Z1bZvsGdwd5dlJow@dragon>

On Tue, Nov 12, 2024 at 06:05:41PM +0800, Liu Ying wrote:
> The LVDS panel "multi-inno,mi1010ait-1cp" used on this platform has
> a typical pixel clock rate of 70MHz.  Set "media_disp2_pix" clock rate
> to that rate, instead of the original 68.9MHz.  The LVDS serial clock
> is controlled by "media_ldb" clock.  It should run at 490MHz(7-fold the
> pixel clock rate due to single LVDS link).  Set "video_pll1" clock rate
> and "media_ldb" to 490MHz to achieve that.
> 
> This should be able to suppress this LDB driver warning:
> [   17.206644] fsl-ldb 32ec0000.blk-ctrl:bridge at 5c: Configured LDB clock (70000000 Hz) does not match requested LVDS clock: 490000000 Hz
> 
> This also makes the display mode used by the panel pass mode validation
> against pixel clock rate and "media_ldb" clock rate in a certain display
> driver.
> 
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Applied, thanks!



From shawnguo2 at yeah.net  Mon Dec  9 03:51:48 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 19:51:48 +0800
Subject: [PATCH v6 6/7] arm64: dts: imx8mp-evk: Add NXP LVDS to HDMI
 adapter cards
In-Reply-To: <20241112100547.2908497-7-victor.liu@nxp.com>
References: <20241112100547.2908497-1-victor.liu@nxp.com>
 <20241112100547.2908497-7-victor.liu@nxp.com>
Message-ID: <Z1bZ1FvPmjPr3LU5@dragon>

On Tue, Nov 12, 2024 at 06:05:46PM +0800, Liu Ying wrote:
> One ITE IT6263 LVDS to HDMI converter is populated on NXP IMX-LVDS-HDMI
> and IMX-DLVDS-HDMI adapter cards.
> 
> Card IMX-LVDS-HDMI supports single LVDS link(IT6263 link1).
> Card IMX-DLVDS-HDMI supports dual LVDS links(IT6263 link1 and link2).
> 
> Only one card can be enabled with one i.MX8MP EVK.
> 
> Add dedicated overlays to support the below four connections:
> 1) imx8mp-evk-lvds0-imx-lvds-hdmi.dtso:
>    i.MX8MP EVK LVDS0 connector <=> LVDS adapter card J6(IT6263 link1)
> 
> 2) imx8mp-evk-lvds1-imx-lvds-hdmi.dtso:
>    i.MX8MP EVK LVDS1 connector <=> LVDS adapter card J6(IT6263 link1)
> 
> 3) imx8mp-evk-lvds0-imx-dlvds-hdmi-channel0.dtso:
>    i.MX8MP EVK LVDS0 connector <=> DLVDS adapter card channel0(IT6263 link1)
>    i.MX8MP EVK LVDS1 connector <=> DLVDS adapter card channel1(IT6263 link2)
> 
> 4) imx8mp-evk-lvds1-imx-dlvds-hdmi-channel0.dtso:
>    i.MX8MP EVK LVDS1 connector <=> DLVDS adapter card channel0(IT6263 link1)
>    i.MX8MP EVK LVDS0 connector <=> DLVDS adapter card channel1(IT6263 link2)
> 
> Part links:
> https://www.nxp.com/part/IMX-LVDS-HDMI
> https://www.nxp.com/part/IMX-DLVDS-HDMI
> 
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Applied, thanks!



From shameerali.kolothum.thodi at huawei.com  Mon Dec  9 03:53:08 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Mon, 9 Dec 2024 11:53:08 +0000
Subject: [PATCH v3 0/3] KVM: arm64: Errata management for VM Live migration
Message-ID: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>

Hi,

Changes from RFC v2[1]:

 -Addressed comments from Oliver(Thanks!).
 -Using implementation CPUs MIDR/REVIDR when it is set for
  _midr_range() functions(Patch 1 & 3)
 -New hypercall for retrieving implementation CPUs(Patch #2).
 -Dropped RFC.

Sanity tested on a HiSilicon ARM64 platform using a hacked Qemu that can
handle the above hypercall.

Thanks,
Shameer
[1] https://lore.kernel.org/kvmarm/20241024094012.29452-1-shameerali.kolothum.thodi at huawei.com/

Changes from RFC v1:
 https://lore.kernel.org/kvmarm/20241011075053.80540-1-shameerali.kolothum.thodi at huawei.com/
 -Introduced hypercalls to retrieve target CPUs info from user space VMM.
  see patch #1 for details.
 -Patch #2 uses the hypercall to retrieve the target CPU info if any.
 -Use the target CPUs MIDR/REVIDR in errata enablement. See patch #3.

Background from v1:

On ARM64 platforms most of the errata workarounds are based on CPU
MIDR/REVIDR values and a number of these workarounds need to be
implemented by the Guest kernel as well. This creates a problem when
Guest needs to be migrated to a platform that differs in these
MIDR/REVIDR values even if the VMM can come up with a common minimum
feature list for the Guest using the recently introduced "Writable
ID registers" support.

(This is roughly based on a discussion I had with Marc and Oliver
at KVM forum. Marc outlined his idea for a solution and this is an
attempt to implement it. Thanks to both and I take all the blame
if this is nowhere near what is intended/required)

Shameer Kolothum (3):
  arm64: Modify _midr_range() functions to read MIDR/REVIDR internally
  KVM: arm64: Introduce hypercall support for retrieving target
    implementations
  arm64: paravirt: Enable errata based on implementation CPUs

 Documentation/virt/kvm/arm/hypercalls.rst | 30 +++++++++++++
 arch/arm64/include/asm/cputype.h          | 51 ++++++++++++++++-------
 arch/arm64/include/asm/mmu.h              |  3 +-
 arch/arm64/include/asm/paravirt.h         |  3 ++
 arch/arm64/kernel/cpu_errata.c            | 37 +++++++++++-----
 arch/arm64/kernel/cpufeature.c            |  8 ++--
 arch/arm64/kernel/image-vars.h            |  2 +
 arch/arm64/kernel/paravirt.c              | 31 ++++++++++++++
 arch/arm64/kernel/proton-pack.c           | 17 ++++----
 arch/arm64/kvm/vgic/vgic-v3.c             |  2 +-
 drivers/clocksource/arm_arch_timer.c      |  2 +-
 include/linux/arm-smccc.h                 |  7 ++++
 12 files changed, 152 insertions(+), 41 deletions(-)

-- 
2.47.0



From shameerali.kolothum.thodi at huawei.com  Mon Dec  9 03:53:09 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Mon, 9 Dec 2024 11:53:09 +0000
Subject: [PATCH v3 1/3] arm64: Modify _midr_range() functions to read MIDR/REVIDR internally
In-Reply-To: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>
References: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20241209115311.40496-2-shameerali.kolothum.thodi@huawei.com>

These changes lay the groundwork for adding support for guest kernels,
allowing them to leverage target CPU implementations provided by the
VMM.

No functional changes intended.

Suggested-by: Oliver Upton <oliver.upton at linux.dev>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 arch/arm64/include/asm/cputype.h     | 28 ++++++++++++++--------------
 arch/arm64/include/asm/mmu.h         |  3 +--
 arch/arm64/kernel/cpu_errata.c       | 23 +++++++++++++----------
 arch/arm64/kernel/cpufeature.c       |  6 +++---
 arch/arm64/kernel/proton-pack.c      | 17 ++++++++---------
 arch/arm64/kvm/vgic/vgic-v3.c        |  2 +-
 drivers/clocksource/arm_arch_timer.c |  2 +-
 7 files changed, 41 insertions(+), 40 deletions(-)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 488f8e751349..dcf0e1ce892d 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -229,6 +229,16 @@
 
 #define read_cpuid(reg)			read_sysreg_s(SYS_ ## reg)
 
+/*
+ * The CPU ID never changes at run time, so we might as well tell the
+ * compiler that it's constant.  Use this function to read the CPU ID
+ * rather than directly reading processor_id or read_cpuid() directly.
+ */
+static inline u32 __attribute_const__ read_cpuid_id(void)
+{
+	return read_cpuid(MIDR_EL1);
+}
+
 /*
  * Represent a range of MIDR values for a given CPU model and a
  * range of variant/revision values.
@@ -264,31 +274,21 @@ static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
 	return _model == model && rv >= rv_min && rv <= rv_max;
 }
 
-static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
+static inline bool is_midr_in_range(struct midr_range const *range)
 {
-	return midr_is_cpu_model_range(midr, range->model,
+	return midr_is_cpu_model_range(read_cpuid_id(), range->model,
 				       range->rv_min, range->rv_max);
 }
 
 static inline bool
-is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
+is_midr_in_range_list(struct midr_range const *ranges)
 {
 	while (ranges->model)
-		if (is_midr_in_range(midr, ranges++))
+		if (is_midr_in_range(ranges++))
 			return true;
 	return false;
 }
 
-/*
- * The CPU ID never changes at run time, so we might as well tell the
- * compiler that it's constant.  Use this function to read the CPU ID
- * rather than directly reading processor_id or read_cpuid() directly.
- */
-static inline u32 __attribute_const__ read_cpuid_id(void)
-{
-	return read_cpuid(MIDR_EL1);
-}
-
 static inline u64 __attribute_const__ read_cpuid_mpidr(void)
 {
 	return read_cpuid(MPIDR_EL1);
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 2ec96d91acc6..bfd303e074be 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -101,8 +101,7 @@ static inline bool kaslr_requires_kpti(void)
 	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))
+		if (is_midr_in_range_list(cavium_erratum_27456_cpus))
 			return false;
 	}
 
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index a78f247029ae..929685c00263 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -15,30 +15,34 @@
 #include <asm/smp_plat.h>
 
 static bool __maybe_unused
-is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
+__is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
+			 u32 midr, u32 revidr)
 {
 	const struct arm64_midr_revidr *fix;
-	u32 midr = read_cpuid_id(), revidr;
-
-	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	if (!is_midr_in_range(midr, &entry->midr_range))
+	if (!is_midr_in_range(&entry->midr_range))
 		return false;
 
 	midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;
-	revidr = read_cpuid(REVIDR_EL1);
 	for (fix = entry->fixed_revs; fix && fix->revidr_mask; fix++)
 		if (midr == fix->midr_rv && (revidr & fix->revidr_mask))
 			return false;
-
 	return true;
 }
 
+static bool __maybe_unused
+is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+	return __is_affected_midr_range(entry, read_cpuid_id(),
+					read_cpuid(REVIDR_EL1));
+}
+
 static bool __maybe_unused
 is_affected_midr_range_list(const struct arm64_cpu_capabilities *entry,
 			    int scope)
 {
 	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	return is_midr_in_range_list(read_cpuid_id(), entry->midr_range_list);
+	return is_midr_in_range_list(entry->midr_range_list);
 }
 
 static bool __maybe_unused
@@ -186,12 +190,11 @@ static bool __maybe_unused
 has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
 				int scope)
 {
-	u32 midr = read_cpuid_id();
 	bool has_dic = read_cpuid_cachetype() & BIT(CTR_EL0_DIC_SHIFT);
 	const struct midr_range range = MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1);
 
 	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	return is_midr_in_range(midr, &range) && has_dic;
+	return is_midr_in_range(&range) && has_dic;
 }
 
 #ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed8..4cc4ae16b28d 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1783,7 +1783,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
 	char const *str = "kpti command line option";
 	bool meltdown_safe;
 
-	meltdown_safe = is_midr_in_range_list(read_cpuid_id(), kpti_safe_list);
+	meltdown_safe = is_midr_in_range_list(kpti_safe_list);
 
 	/* Defer to CPU feature registers */
 	if (has_cpuid_feature(entry, scope))
@@ -1853,7 +1853,7 @@ static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
 
 	return (__system_matches_cap(ARM64_HAS_NESTED_VIRT) &&
 		!(has_cpuid_feature(entry, scope) ||
-		  is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
+		  is_midr_in_range_list(nv1_ni_list)));
 }
 
 #if defined(ID_AA64MMFR0_EL1_TGRAN_LPA2) && defined(ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2)
@@ -2036,7 +2036,7 @@ static bool cpu_has_broken_dbm(void)
 		{},
 	};
 
-	return is_midr_in_range_list(read_cpuid_id(), cpus);
+	return is_midr_in_range_list(cpus);
 }
 
 static bool cpu_can_use_dbm(const struct arm64_cpu_capabilities *cap)
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index da53722f95d4..a573fa40d4b6 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -172,7 +172,7 @@ static enum mitigation_state spectre_v2_get_cpu_hw_mitigation_state(void)
 		return SPECTRE_UNAFFECTED;
 
 	/* Alternatively, we have a list of unaffected CPUs */
-	if (is_midr_in_range_list(read_cpuid_id(), spectre_v2_safe_list))
+	if (is_midr_in_range_list(spectre_v2_safe_list))
 		return SPECTRE_UNAFFECTED;
 
 	return SPECTRE_VULNERABLE;
@@ -331,7 +331,7 @@ bool has_spectre_v3a(const struct arm64_cpu_capabilities *entry, int scope)
 	};
 
 	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	return is_midr_in_range_list(read_cpuid_id(), spectre_v3a_unsafe_list);
+	return is_midr_in_range_list(spectre_v3a_unsafe_list);
 }
 
 void spectre_v3a_enable_mitigation(const struct arm64_cpu_capabilities *__unused)
@@ -475,7 +475,7 @@ static enum mitigation_state spectre_v4_get_cpu_hw_mitigation_state(void)
 		{ /* sentinel */ },
 	};
 
-	if (is_midr_in_range_list(read_cpuid_id(), spectre_v4_safe_list))
+	if (is_midr_in_range_list(spectre_v4_safe_list))
 		return SPECTRE_UNAFFECTED;
 
 	/* CPU features are detected first */
@@ -878,13 +878,13 @@ u8 spectre_bhb_loop_affected(int scope)
 			{},
 		};
 
-		if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
+		if (is_midr_in_range_list(spectre_bhb_k32_list))
 			k = 32;
-		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
+		else if (is_midr_in_range_list(spectre_bhb_k24_list))
 			k = 24;
-		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
+		else if (is_midr_in_range_list(spectre_bhb_k11_list))
 			k = 11;
-		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
+		else if (is_midr_in_range_list(spectre_bhb_k8_list))
 			k =  8;
 
 		max_bhb_k = max(max_bhb_k, k);
@@ -926,8 +926,7 @@ static bool is_spectre_bhb_fw_affected(int scope)
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
 		{},
 	};
-	bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
-					 spectre_bhb_firmware_mitigated_list);
+	bool cpu_in_list = is_midr_in_range_list(spectre_bhb_firmware_mitigated_list);
 
 	if (scope != SCOPE_LOCAL_CPU)
 		return system_affected;
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index f267bc2486a1..b815d910c7e4 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -632,7 +632,7 @@ static const struct midr_range broken_seis[] = {
 static bool vgic_v3_broken_seis(void)
 {
 	return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) &&
-		is_midr_in_range_list(read_cpuid_id(), broken_seis));
+		is_midr_in_range_list(broken_seis));
 }
 
 /**
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 808f259781fd..981a578043a5 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -842,7 +842,7 @@ static u64 __arch_timer_check_delta(void)
 		{},
 	};
 
-	if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) {
+	if (is_midr_in_range_list(broken_cval_midrs)) {
 		pr_warn_once("Broken CNTx_CVAL_EL1, using 31 bit TVAL instead.\n");
 		return CLOCKSOURCE_MASK(31);
 	}
-- 
2.47.0



From shawnguo2 at yeah.net  Mon Dec  9 03:52:07 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 19:52:07 +0800
Subject: [PATCH v6 7/7] arm64: defconfig: Enable ITE IT6263 driver
In-Reply-To: <20241112100547.2908497-8-victor.liu@nxp.com>
References: <20241112100547.2908497-1-victor.liu@nxp.com>
 <20241112100547.2908497-8-victor.liu@nxp.com>
Message-ID: <Z1bZ57fn/upwHWQ5@dragon>

On Tue, Nov 12, 2024 at 06:05:47PM +0800, Liu Ying wrote:
> ITE IT6263 LVDS to HDMI converter is populated on NXP IMX-LVDS-HDMI
> and IMX-DLVDS-HDMI adapter cards.  The adapter cards can connect to
> i.MX8MP EVK base board to support video output through HDMI connectors.
> Build the ITE IT6263 driver as a module.
> 
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Applied, thanks!



From mark.rutland at arm.com  Mon Dec  9 03:54:15 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 9 Dec 2024 11:54:15 +0000
Subject: [PATCH] arm64: stacktrace: skip reporting LR at exception
 boundaries
In-Reply-To: <20241209110351.1876804-1-mark.rutland@arm.com>
References: <20241209110351.1876804-1-mark.rutland@arm.com>
Message-ID: <Z1baZ4kyFJarSCcY@J2N7QTR9R3>

On Mon, Dec 09, 2024 at 11:03:51AM +0000, Mark Rutland wrote:
> Recently the arm64 stacktrace code was modified to report the LR at
> exception boundaries, which interacts poorly with fgraph tracing. It is
> possible for the LR to contain the start address of return_to_handler()
> even when the LR is not live, and in such cases attempts to recover the
> return address via ftrace_graph_ret_addr() may fail, triggering a
> WARN_ON_ONCE() in kunwind_recover_return_address() and aborting the
> unwind. This has resulted in test failures and unexpected warnings, as
> reported by Aishwarya and Kent.

To clarify, the issue reported by Kent at:

  http://lore.kernel.org/linux-arm-kernel/zbwbgkuvvciezpmigcp6gaahfxwm7cwhpzus7gtbfnbzsjb2n3 at kfbdppbd74o4

... seems to be a distinct issue, and I has misunderstood the report
while writing up this commit message.

Regardless of that, I think this patch is still justified, as it does
address the issue that Aishwarya reported.

Mark.

> 
> Handling unreliable LR values in these cases is likely to require some
> larger rework, so for the moment avoid this problem by restoring the old
> behaviour of skipping the LR at exception boundaries, as we did prior to
> commit:
> 
>   c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")
> 
> This commit is effectively a partial revert, keeping the structures and
> logic to explicitly identify exception boundaries while still skipping
> reporting of the LR. The logic to explicitly identify exception
> boundaries is still useful for general robustness and as a building
> block for future support for reliably stacktracing.
> 
> Fixes: c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Reported-by: Aishwarya TCV <aishwarya.tcv at arm.com>
> Reported-by: Kent Overstreet <kent.overstreet at linux.dev>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/kernel/stacktrace.c | 24 ++----------------------
>  1 file changed, 2 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index caef85462acb6..4a08ad8158380 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -26,7 +26,6 @@ enum kunwind_source {
>  	KUNWIND_SOURCE_CALLER,
>  	KUNWIND_SOURCE_TASK,
>  	KUNWIND_SOURCE_REGS_PC,
> -	KUNWIND_SOURCE_REGS_LR,
>  };
>  
>  union unwind_flags {
> @@ -178,23 +177,8 @@ int kunwind_next_regs_pc(struct kunwind_state *state)
>  	state->regs = regs;
>  	state->common.pc = regs->pc;
>  	state->common.fp = regs->regs[29];
> -	state->source = KUNWIND_SOURCE_REGS_PC;
> -	return 0;
> -}
> -
> -static __always_inline int
> -kunwind_next_regs_lr(struct kunwind_state *state)
> -{
> -	/*
> -	 * The stack for the regs was consumed by kunwind_next_regs_pc(), so we
> -	 * cannot consume that again here, but we know the regs are safe to
> -	 * access.
> -	 */
> -	state->common.pc = state->regs->regs[30];
> -	state->common.fp = state->regs->regs[29];
>  	state->regs = NULL;
> -	state->source = KUNWIND_SOURCE_REGS_LR;
> -
> +	state->source = KUNWIND_SOURCE_REGS_PC;
>  	return 0;
>  }
>  
> @@ -274,11 +258,8 @@ kunwind_next(struct kunwind_state *state)
>  	case KUNWIND_SOURCE_FRAME:
>  	case KUNWIND_SOURCE_CALLER:
>  	case KUNWIND_SOURCE_TASK:
> -	case KUNWIND_SOURCE_REGS_LR:
> -		err = kunwind_next_frame_record(state);
> -		break;
>  	case KUNWIND_SOURCE_REGS_PC:
> -		err = kunwind_next_regs_lr(state);
> +		err = kunwind_next_frame_record(state);
>  		break;
>  	default:
>  		err = -EINVAL;
> @@ -436,7 +417,6 @@ static const char *state_source_string(const struct kunwind_state *state)
>  	case KUNWIND_SOURCE_CALLER:	return "C";
>  	case KUNWIND_SOURCE_TASK:	return "T";
>  	case KUNWIND_SOURCE_REGS_PC:	return "P";
> -	case KUNWIND_SOURCE_REGS_LR:	return "L";
>  	default:			return "U";
>  	}
>  }
> -- 
> 2.30.2
> 


From przemyslaw.kitszel at intel.com  Mon Dec  9 04:01:42 2024
From: przemyslaw.kitszel at intel.com (Przemek Kitszel)
Date: Mon, 9 Dec 2024 13:01:42 +0100
Subject: [PATCH v2 00/21] Converge on using secs_to_jiffies()
In-Reply-To: <dab77729-682f-4182-9fb2-cd522ac29b5f@linux.microsoft.com>
References: <20241115-converge-secs-to-jiffies-v2-0-911fb7595e79@linux.microsoft.com>
 <b9fcb12a-b7a4-4c33-836e-67109ce07deb@intel.com>
 <dab77729-682f-4182-9fb2-cd522ac29b5f@linux.microsoft.com>
Message-ID: <72c8eb66-eb67-4f8b-b0c0-13f1aa001698@intel.com>

On 12/6/24 9:58 PM, Easwar Hariharan wrote:
> On 11/29/2024 4:57 AM, Przemek Kitszel wrote:
>>
>> [removed most non-list recipients, it's just too much]
>>
>> On 11/15/24 10:26 PM, Easwar Hariharan wrote:
> <snip>

>>
>> Regarding code - you could also convert msecs_to_jiffies(const * HZ),
>> there are 10 that are greppable.
>>
> 
> Those seem to be mistakes. const*HZ is a seconds-denominated timeout,
> being passed to msecs_to_jiffies() which will treat it as a
> millisecond-denominated timeout resulting in an excessively long
> timeout. I suppose that's better than a too-short timeout, and
> apparently it's been working fine all along since hardware responds
> before the too-long timeout expires. Half of them are in
> drivers/scsi/arcmsr/arcmsr_hba.c and the pattern has apparently been
> there since 2010.

my point was that, the default value of HZ is 1000, and most of the code
that is just `$value*HZ` was meant as "$value seconds, in ms unit".

Same for HZ/const, HZ/2 being 500ms.

HZ is awful in that it is not 1s but 1/s, but it was easy to abuse the
value in simple context.

If you happen to touch this, please do in a separate series, to get more
attention from drivers owners.

> 
> Thanks,
> Easwar



From apatel at ventanamicro.com  Mon Dec  9 04:08:18 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 9 Dec 2024 17:38:18 +0530
Subject: [PATCH 1/4] irqchip/riscv-imsic: Handle non-atomic MSI updates
 for device
In-Reply-To: <875xnuq6dc.ffs@tglx>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
 <20241208150711.297624-2-apatel@ventanamicro.com> <875xnuq6dc.ffs@tglx>
Message-ID: <CAK9=C2VqU2mdLL-R20bdgvDHi0WcuNyUSqRo7Pztsu-8X1wVvw@mail.gmail.com>

Hi Thomas,

On Mon, Dec 9, 2024 at 1:44?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Sun, Dec 08 2024 at 20:37, Anup Patel wrote:
> > +
> > +                     tvec = vec->local_id == mvec->local_id ?
> > +                            NULL : &lpriv->vectors[mvec->local_id];
> > +                     if (tvec && __imsic_id_read_clear_pending(tvec->local_id)) {
>
> As I told you before:
>
> I don't see a way how that can work remote with the IMSIC either even if
> you can easily access the pending state of the remote CPU:

For RISC-V IMSIC, a remote CPU cannot access the pending state
of interrupts on some other CPU.

>
> CPU0                            CPU1                   Device
> set_affinity()
>   write_msg(tmp)
>     write(addr); // CPU1
>     write(data); // vector 0x20
>                                                         raise IRQ (CPU1, vector 0x20)
>                                 handle vector 0x20
>                                 (other device)
>
>     check_pending(CPU1, 0x20) == false -> Interrupt is lost
>
> There is no guarantee that set_affinity() runs on the original target
> CPU (CPU 1). Your scheme only works, when CPU1 vector 0x20 is not used
> by some other device. If it's used, you lost as CPU1 will consume the
> vector and your pending check is not seeing anything.
>
> x86 ensures CPU locality by deferring the affinity move to the next
> device interrupt on the original target CPU (CPU1 in the above
> example). See CONFIG_GENERIC_IRQ_PENDING.

I agree with you.

The IMSIC driver must do the affinity move upon the next device
interrupt on the old CPU. I will update this patch in the next revision.

BTW, I did not find CONFIG_GENERIC_IRQ_PENDING. Is the
name correct ?

>
> The interrupt domains which are not affected (remap) set the
> IRQ_MOVE_PCNTXT flag to avoid that dance and don't use that affinity
> setter code path at all.

Yes, setting the IRQ_MOVE_PCNTXT flag in the remap domain
makes perfect sense.

I suggest adding IRQ_MOVE_PCNTXT usage as part of Drew's
irqbypass series which adds a remap domain in the IOMMU
driver. Unless you insist on having it as part of this series ?

Regards,
Anup


From quic_luoj at quicinc.com  Mon Dec  9 04:10:58 2024
From: quic_luoj at quicinc.com (Jie Luo)
Date: Mon, 9 Dec 2024 20:10:58 +0800
Subject: [PATCH v6 0/5] Add CMN PLL clock controller driver for IPQ9574
In-Reply-To: <20241106-qcom_ipq_cmnpll-v6-0-9d398db2fe0f@quicinc.com>
References: <20241106-qcom_ipq_cmnpll-v6-0-9d398db2fe0f@quicinc.com>
Message-ID: <25619909-90c2-40a8-9e49-83ab26b6cf79@quicinc.com>



On 11/6/2024 6:52 PM, Luo Jie wrote:
> The CMN PLL clock controller in Qualcomm IPQ chipsets provides
> the clocks to the networking hardware blocks that are internal
> or external to the SoC, and to the GCC. This driver configures
> the CMN PLL clock controller to enable the output clocks. The
> networking blocks include the internal blocks such as PPE
> (Packet Process Engine) and PCS blocks, and external hardware
> such as Ethernet PHY or switch. The CMN PLL block also outputs
> fixed rate clocks to GCC, such as 24 MHZ as XO clock and 32 KHZ
> as sleep clock supplied to GCC.
> 
> The controller expects the input reference clock from the internal
> Wi-Fi block acting as the clock source. The output clocks supplied
> by the controller are fixed rate clocks.
> 
> The CMN PLL hardware block does not include any other function
> other than enabling the clocks to the networking hardware blocks
> and GCC.
> 
> The driver is being enabled to support IPQ9574 SoC initially, and
> will be extended for other SoCs.
> 
> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
> ---
> Changes in v6:
> - Rename the reference clock of CMN PLL to ref_48mhz_clk.
> - Add the patch to update xo_board_clk to use fixed factor clock.
> - Link to v5: https://lore.kernel.org/r/20241028-qcom_ipq_cmnpll-v5-0-339994b0388d at quicinc.com
> 
> Changes in v5:
> - Move the hardware configurations into set_rate() from determine_rate().
> - Remove the dependency on IPQ_GCC_9574.
> - Correct the header files included.
> - Update reference clock of CMN PLL to use fixed factor clock.
> - Link to v4: https://lore.kernel.org/r/20241015-qcom_ipq_cmnpll-v4-0-27817fbe3505 at quicinc.com
> 
> Changes in v4:
> - Rename driver file to ipq-cmn-pll.c
> - Register CMN PLL as a 12 GHZ clock.
> - Configure CMN PLL input ref clock using clk_ops::determine_rate().
>    Add the additional output clocks to GCC and PCS.
> - Update the same information in dtbindings.
> - Use PM clock APIs for input clock enablement.
> - Link to v3: https://lore.kernel.org/r/20240827-qcom_ipq_cmnpll-v3-0-8e009cece8b2 at quicinc.com
> 
> Changes in v3:
> - Update description of dt-binding to explain scope of 'CMN' in CMN PLL.
> - Collect Reviewed-by tags for dtbindings and defconfig patches.
> - Enable PLL_LOCKED check for the stability of output clocks.
> - Link to v2: https://lore.kernel.org/r/20240820-qcom_ipq_cmnpll-v2-0-b000dd335280 at quicinc.com
> 
> Changes in v2:
> - Rename the dt-binding file with the compatible.
> - Remove property 'clock-output-names' from dt-bindings and define
>    names in the driver. Add qcom,ipq-cmn-pll.h to export the output
>    clock specifier.
> - Alphanumeric ordering of 'cmn_pll_ref_clk' node in DTS.
> - Fix allmodconfig error reported by test robot.
> - Replace usage of "common" to "CMN" to match the name with the
>    hardware specification.
> - Clarify in commit message on scope of CMN PLL function.
> - Link to v1: https://lore.kernel.org/r/20240808-qcom_ipq_cmnpll-v1-0-b0631dcbf785 at quicinc.com
> 
> ---
> Luo Jie (5):
>        dt-bindings: clock: qcom: Add CMN PLL clock controller for IPQ SoC
>        clk: qcom: Add CMN PLL clock controller driver for IPQ SoC
>        arm64: defconfig: Enable Qualcomm IPQ CMN PLL clock controller
>        arm64: dts: qcom: Add CMN PLL node for IPQ9574 SoC
>        arm64: dts: qcom: Update IPQ9574 xo_board_clk to use fixed factor clock
> 
>   .../bindings/clock/qcom,ipq9574-cmn-pll.yaml       |  85 ++++
>   arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi   |  23 +-
>   arch/arm64/boot/dts/qcom/ipq9574.dtsi              |  27 +-
>   arch/arm64/configs/defconfig                       |   1 +
>   drivers/clk/qcom/Kconfig                           |   9 +
>   drivers/clk/qcom/Makefile                          |   1 +
>   drivers/clk/qcom/ipq-cmn-pll.c                     | 436 +++++++++++++++++++++
>   include/dt-bindings/clock/qcom,ipq-cmn-pll.h       |  22 ++
>   8 files changed, 601 insertions(+), 3 deletions(-)
> ---
> base-commit: d61a00525464bfc5fe92c6ad713350988e492b88
> change-id: 20241014-qcom_ipq_cmnpll-bde0638f4116
> 
> Best regards,

Hello Bjorn, Stephen, Dmitry,

Gentle reminder, to re-review the updated patch series V6 at your
convenience to let me know if this patch series is fine to be merged.
Thanks in advance.


From gankulkarni at os.amperecomputing.com  Mon Dec  9 04:25:34 2024
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Mon, 9 Dec 2024 17:55:34 +0530
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer
 expired
In-Reply-To: <867c89tc4q.wl-maz@kernel.org>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
 <867c89tc4q.wl-maz@kernel.org>
Message-ID: <c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>


Hi Marc,

On 09-12-2024 03:24 pm, Marc Zyngier wrote:
> Ganapatrao,
> 
> Did you notice that the Columbia list was killed over two years ago,
> as per ac107abef1976 ("KVM: arm64: Advertise new kvmarm mailing
> list")? Consider that script/get_maintainer.pl is your friend.

My bad, copy paste issue!.
> 
> Cc'ing the correct list instead,

Thanks.
> 
> On Mon, 09 Dec 2024 05:32:01 +0000,
> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
>>
>> During automated testing of Nested Virtualization using avocado-vt,
> 
> Which is not merged upstream. So what branch are you using? Based on
> what kernel version? On what HW? With which virtualisation features?
> 

Testing is done on Ampere's AmpereOne platform using 6.10 based kernel 
with NV patches from your repo.

>> it has been observed that during some boot test iterations,
>> the Guest-Hypervisor boot was getting crashed with a
>> synchronous exception while it is still booting EDK2.
>>
>> The test is launching Multiple instances of Guest-Hypervisor boot
> 
> Is the multiple instance aspect really relevant to the reproduction of
> the problem?

Not really, but it requires multiple attempts/iterations to hit the 
issue. Even with automated test, it was seen at some iteration out of 10 
to 15 iterations.

> 
>> and while booting, QEMU monitor issued the command "info register"
>> at regular intervals to take a register dump. To execute this
>> command, QEMU stops the run and does the register read of various
>> registers. While resuming the run, the function kvm_arm_timer_write()
>> writes back the saved CNTV_CTL_EL0 register with ISTATUS cleared always
> 
> It is userspace that causes this write-back, right? AFAICT, KVM never
> does that on its own.
> 
>> and resulting in the loss of pending interrupt for emulated timers.
> 
> How does a missing interrupt result in a synchronous exception in
> EDK2? In my experience, EDK2 panics if it sees spurious interrupts,
> not when it is missing interrupts (it just locks up, which is
> expected).

Not sure, why it is hitting exception, rather than hang at EDK2.
However, EDK2 timer handler code is ignoring the interrupt since ISTATUS 
is not set and not moving CVAL forward.

> 
>> In hardware based timers, ISTATUS is a RO/WI bit and gets set by the
>> h/w, if the condition is still met. However, in Nested-Virtualization
>> case, the Guest-Hypervisor's?EDK2 is using an emulated virtual timer
>> and losing ISTATUS state and the interrupt forever.
> 
> Why is this specific to NV? Can't the same thing happen to the
> physical timer in a non-VHE configuration?
> 

You mean, emulated v-timer in non-VHE boot?
It might impact non-VHE case as well, not tried though.

>>
>> Adding fix in kvm_arm_timer_write to set ISTATUS for emulated
>> timers, if the timer expired already.
>>
>> Fixes: 81dc9504a700 ("KVM: arm64: nv: timers: Support hyp timer emulation")
> 
> Where is this coming from? This patch doesn't touch the code you are
> changing, so how can it be the source of your problems? As far as I
> can tell, this has been the case since 5c5196da4e966 ("KVM: arm/arm64:
> Support EL1 phys timer register access in set/get reg").

Thanks, 5c5196da4e966 seems more relevant!.

>> Co-developed-by: Vishnu Pajjuri <vishnu at os.amperecomputing.com>
>> Signed-off-by: Vishnu Pajjuri <vishnu at os.amperecomputing.com>
>> Signed-off-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
>> ---
>>   arch/arm64/kvm/arch_timer.c | 11 ++++++++++-
>>   1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
>> index 1215df590418..aca58113d790 100644
>> --- a/arch/arm64/kvm/arch_timer.c
>> +++ b/arch/arm64/kvm/arch_timer.c
>> @@ -1199,7 +1199,16 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
>>   		break;
>>   
>>   	case TIMER_REG_CTL:
>> -		timer_set_ctl(timer, val & ~ARCH_TIMER_CTRL_IT_STAT);
>> +		struct timer_map map;
>> +
>> +		val &= ~ARCH_TIMER_CTRL_IT_STAT;
>> +		get_timer_map(vcpu, &map);
>> +		/* Set ISTATUS bit for emulated timers, if timer expired. */
>> +		if (timer == map.emul_vtimer || timer == map.emul_ptimer) {
>> +			if (!kvm_timer_compute_delta(timer))
>> +				val |= ARCH_TIMER_CTRL_IT_STAT;
>> +		}
>> +		timer_set_ctl(timer, val);
>>   		break;
> 
> This really looks awfully complicated, when it is only a matter of
> recomputing the interrupt state, something that is at the core of the
> timer emulation. Why can't the following work:

Added check to handle ISTATUS for emulated timers only, since it is RO 
for hardware timers, thought it might confuse others(non-nv case).
Otherwise below diff from you should work as well. I will try it out.

> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 895f09658ef83..bd6efafbe7109 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -1298,13 +1298,17 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
>   				enum kvm_arch_timer_regs treg,
>   				u64 val)
>   {
> +	unsigned long tmp = val;
> +
>   	switch (treg) {
>   	case TIMER_REG_TVAL:
>   		timer_set_cval(timer, kvm_phys_timer_read() - timer_get_offset(timer) + (s32)val);
>   		break;
>   
>   	case TIMER_REG_CTL:
> -		timer_set_ctl(timer, val & ~ARCH_TIMER_CTRL_IT_STAT);
> +		__assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &tmp,
> +			     kvm_timer_should_fire(timer));
> +		timer_set_ctl(timer, tmp);
>   		break;
>   
>   	case TIMER_REG_CVAL:
> 
> But overall, this very much looks like it is only papering over the
> real issue, which is that the *emulation* should regenerate the
> pending bit, and not rely on the userspace interface.
> 
> As far as I can tell, we already correctly compute the status bit on
> read (read_timer_ctl()), so the guest should always observe something
> consistent when it traps. We also *never* use the status bit as an
> input to the emulation, and always recompute it from scratch (it is
> only there for the benefit of the guest or userspace).
> 

For emulated timers, we are not asserting again by calling 
kvm_timer_update_irq in timer_emulate() until the level is down and 
ready for trigger again. This was done to fix high rate of spurious 
interrupts getting generated to V-Timer. Hence we are not able to 
recover, if once ISTATUS is lost.

> So I can't see how upstream is broken in at the moment, and you need
> to explain how this actually triggers. Ideally, with a standalone
> reproducer or a selftest.

We could reproduce the issue with the simple test/script.
On one shell, launch L1 using qemu with add-on option

"-monitor unix:gh_monitor,server,nowait

On another shell, while L1 boots and still in UEFI, run repeatedly the 
command (or put in a while 1 loop script)

"echo "info registers" | socat - unix-connect:gh_monitor > 
/tmp/info_registers"

With above steps we were able to hit the issue within few attempts.

-- 
Thanks,
Ganapat/GK



From andyshrk at 163.com  Mon Dec  9 04:37:59 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon, 9 Dec 2024 20:37:59 +0800 (CST)
Subject: [PATCH] drm/rockchip: vop2: Setup delay cycle for Esmart2/3
In-Reply-To: <20241209122943.2781431-5-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209122943.2781431-5-andyshrk@163.com>
Message-ID: <d6e7dee.ba96.193ab6d2e3f.Coremail.andyshrk@163.com>


Sorry, please ignore this patch.

At 2024-12-09 20:29:14, "Andy Yan" <andyshrk at 163.com> wrote:
>From: Andy Yan <andy.yan at rock-chips.com>
>
>Each layer needs to set the correct delay cycle to display properly
>without unexpected offset on screen.
>
>Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
>Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>---
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 ++
> 1 file changed, 2 insertions(+)
>
>diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>index c3a572b1c8704..7dc8be7d61184 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>@@ -2526,9 +2526,11 @@ static void vop2_setup_dly_for_windows(struct vop2 *vop2)
> 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
> 			break;
> 		case ROCKCHIP_VOP2_SMART0:
>+		case ROCKCHIP_VOP2_ESMART2:
> 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
> 			break;
> 		case ROCKCHIP_VOP2_SMART1:
>+		case ROCKCHIP_VOP2_ESMART3:
> 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
> 			break;
> 		}
>-- 
>2.34.1

From shawnguo2 at yeah.net  Mon Dec  9 04:37:31 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 20:37:31 +0800
Subject: [PATCH v3 3/3] arm64: dts: imx93: Use IMX93_CLK_SPDIF_IPG as
 SPDIF IPG clock
In-Reply-To: <20241119015805.3840606-4-shengjiu.wang@nxp.com>
References: <20241119015805.3840606-1-shengjiu.wang@nxp.com>
 <20241119015805.3840606-4-shengjiu.wang@nxp.com>
Message-ID: <Z1bkixjbyFhH3ZgL@dragon>

On Tue, Nov 19, 2024 at 09:58:05AM +0800, Shengjiu Wang wrote:
> IMX93_CLK_BUS_WAKEUP is not accurate IPG clock, which
> missed the clock gate part.
> 
> IMX93_CLK_SPDIF_IPG is the correct clock.
> 
> Fixes: 1c4a4f7362fd ("arm64: dts: imx93: Add audio device nodes")
> Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
> Reviewed-by: Frank Li <Frank.Li at nxp.com>

Hi Abel,

I guess it would be the best for you to apply the whole series through
clock tree?  In that case:

Acked-by: Shawn Guo <shawnguo at kernel.org>

Thanks,
Shawn

> ---
>  arch/arm64/boot/dts/freescale/imx93.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
> index 688488de8cd2..56766fdb0b1e 100644
> --- a/arch/arm64/boot/dts/freescale/imx93.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
> @@ -925,7 +925,7 @@ xcvr: xcvr at 42680000 {
>  				reg-names = "ram", "regs", "rxfifo", "txfifo";
>  				interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>,
>  					     <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
> -				clocks = <&clk IMX93_CLK_BUS_WAKEUP>,
> +				clocks = <&clk IMX93_CLK_SPDIF_IPG>,
>  					 <&clk IMX93_CLK_SPDIF_GATE>,
>  					 <&clk IMX93_CLK_DUMMY>,
>  					 <&clk IMX93_CLK_AUD_XCVR_GATE>;
> -- 
> 2.34.1
> 



From rogerq at kernel.org  Mon Dec  9 04:39:18 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 9 Dec 2024 14:39:18 +0200
Subject: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix firmware load
 sequence.
In-Reply-To: <64621290-2488-474d-b2ed-597a1f4ac85f@ti.com>
References: <20241205082831.777868-1-m-malladi@ti.com>
 <20241205082831.777868-2-m-malladi@ti.com>
 <a86bc0b1-8bb4-477e-b7e1-13921bf47b53@kernel.org>
 <64621290-2488-474d-b2ed-597a1f4ac85f@ti.com>
Message-ID: <badf6d7c-85a5-42a4-b834-f5cdbd8ff81f@kernel.org>



On 09/12/2024 12:34, Meghana Malladi wrote:
> 
> 
> On 05/12/24 18:38, Roger Quadros wrote:
>> Hi,
>>
>> On 05/12/2024 10:28, Meghana Malladi wrote:
>>> From: MD Danish Anwar <danishanwar at ti.com>
>>>
>>> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
>>> and SLICE1. Currently whenever any ICSSG interface comes up we load the
>>> respective firmwares to PRU cores and whenever interface goes down, we
>>> stop the resective cores. Due to this, when SLICE0 goes down while
>>> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
>>> stopped. This results in clock jump for SLICE1 interface as the timesync
>>> related operations are no longer running.
>>>
>>> As there are interdependencies between SLICE0 and SLICE1 firmwares,
>>> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
>>> ICSSG interface is up. Add new flag in prueth struct to check if all
>>> firmwares are running.
>>>
>>> Use emacs_initialized as reference count to load the firmwares for the
>>> first and last interface up/down. Moving init_emac_mode and fw_offload_mode
>>> API outside of icssg_config to icssg_common_start API as they need
>>> to be called only once per firmware boot.
>>>
>>> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
>>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>>> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
>>> ---
>>>
>>> Hi all,
>>>
>>> This patch is based on net-next tagged next-20241128.
>>> v2:https://lore.kernel.org/all/20241128122931.2494446-2-m-malladi at ti.com/
>>>
>>> * Changes since v2 (v3-v2):
>>> - error handling in caller function of prueth_emac_common_start()
>>> - Use prus_running flag check before stopping the firmwares
>>> Both suggested by Roger Quadros <rogerq at kernel.org>
>>>
>>> ? drivers/net/ethernet/ti/icssg/icssg_config.c |? 45 ++++--
>>> ? drivers/net/ethernet/ti/icssg/icssg_config.h |?? 1 +
>>> ? drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
>>> ? drivers/net/ethernet/ti/icssg/icssg_prueth.h |?? 5 +
>>> ? 4 files changed, 140 insertions(+), 68 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
>>> index 5d2491c2943a..342150756cf7 100644
>>> --- a/drivers/net/ethernet/ti/icssg/icssg_config.c
>>> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
>>> @@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>>> ????? return 0;
>>> ? }
>>>
> [ ... ]
> 
>>> +static int prueth_emac_common_start(struct prueth *prueth)
>>> +{
>>> +??? struct prueth_emac *emac;
>>> +??? int ret = 0;
>>> +??? int slice;
>>> +
>>> +??? if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>>> +??????? return -EINVAL;
>>> +
>>> +??? /* clear SMEM and MSMC settings for all slices */
>>> +??? memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
>>> +??? memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
>>> +
>>> +??? icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
>>> +??? icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
>>> +
>>> +??? if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>>> +??????? icssg_init_fw_offload_mode(prueth);
>>> +??? else
>>> +??????? icssg_init_emac_mode(prueth);
>>> +
>>> +??? for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>>> +??????? emac = prueth->emac[slice];
>>> +??????? if (emac) {
>>> +??????????? ret |= icssg_config(prueth, emac, slice);
>>> +??????????? if (ret)
>>> +??????????????? return ret;
>>> +??????? }
>>> +??????? ret |= prueth_emac_start(prueth, slice);
>>> +??? }
>>
>> need newline?
>>
> 
> Yes I will add it.
> 
>>> +??? if (!ret)
>>> +??????? prueth->prus_running = 1;
>>> +??? else
>>> +??????? return ret;
>>> +
>>> +??? emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>>> +?????????? prueth->emac[ICSS_SLICE1];
>>> +??? ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>>> +??????????????? emac, IEP_DEFAULT_CYCLE_TIME_NS);
>>> +??? if (ret) {
>>> +??????? dev_err(prueth->dev, "Failed to initialize IEP module\n");
>>> +??????? return ret;
>>> +??? }
>>> +
>>> +??? return 0;
>>> +}
>>> +
>>> +static int prueth_emac_common_stop(struct prueth *prueth)
>>> +{
>>> +??? struct prueth_emac *emac;
>>> +??? int slice;
>>> +
>>> +??? if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>>> +??????? return -EINVAL;
>>> +
>>> +??? icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
>>> +??? icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
>>> +
>>> +??? for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>>> +??????? if (prueth->prus_running) {
>>> +??????????? rproc_shutdown(prueth->txpru[slice]);
>>> +??????????? rproc_shutdown(prueth->rtu[slice]);
>>> +??????????? rproc_shutdown(prueth->pru[slice]);
>>> +??????? }
>>> +??? }
>>> +??? prueth->prus_running = 0;
>>> +
>>> +??? emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>>> +?????????? prueth->emac[ICSS_SLICE1];
>>> +??? icss_iep_exit(emac->iep);
>>
>> if icss_iep_init() failed at prueth_emac_common_start(), we should not be
>> calling icss_iep_exit(). Maybe you need another flag for iep_init status?
>>
> 
> Yes I have thought of it as well. In icss_iep_init() does lot of iep register configuration and in the end it enables iep by setting IEP_CNT_ENABLE bit and ptp_clock_register(). Whereas in icss_iep_exit() it checks for ptp_clock and pps/perout. And calls icss_iep_disable() which again clears IEP_CNT_ENABLE.
> 
> So I see no harm in calling icss_iep_exit() even if icss_iep_init() as it overwrites the existing configuration only. But if you think this doesn't look good I can definitely add new flag for iep as well. But IMO I think this flag would be redundant, please correct me if I am wrong. So which one sounds better?

But isn't icss_iep_exit() also calling ptp_clock_unregister()?
If it is safe to do that even in error condition then it doesn't matter.

> 
>> Is it better to call icss_iep_exit() at the top before icssg_class_disable()?
>>
>>> +
>>> +??? return 0;
>>> +}
>>> +
>>> ? /* called back by PHY layer if there is change in link state of hw port*/
>>> ? static void emac_adjust_link(struct net_device *ndev)
>>> ? {
>>> @@ -369,12 +432,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
>>> ? {
>>> ????? struct icssg_setclock_desc __iomem *sc_descp;
>>> ????? struct prueth_emac *emac = clockops_data;
>>> +??? struct prueth *prueth = emac->prueth;
>>> ????? struct icssg_setclock_desc sc_desc;
>>> ????? u64 cyclecount;
>>> ????? u32 cycletime;
>>> ????? int timeout;
>>> ? -??? if (!emac->fw_running)
>>> +??? if (!prueth->prus_running)
>>> ????????? return;
>>> ? ????? sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
>>> @@ -543,23 +607,17 @@ 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;
>>> +??? struct icssg_flow_cfg __iomem *flow_cfg;
>>> ????? 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, false);
>>> ????? icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
>>> ? ????? /* Notify the stack of the actual queue counts. */
>>> @@ -597,18 +655,23 @@ static int emac_ndo_open(struct net_device *ndev)
>>> ????????? goto cleanup_napi;
>>> ????? }
>>> ? -??? /* reset and start PRU firmware */
>>> -??? ret = prueth_emac_start(prueth, emac);
>>> -??? if (ret)
>>> -??????? goto free_rx_irq;
>>> +??? if (!prueth->emacs_initialized) {
>>> +??????? ret = prueth_emac_common_start(prueth);
>>> +??????? if (ret)
>>> +??????????? goto stop;
>>> +??? }
>>> ? -??? icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>>> +??? flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
>>> +??? writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
>>> +??? ret = emac_fdb_flow_id_updated(emac);
>>> ? -??? if (!prueth->emacs_initialized) {
>>> -??????? ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>>> -??????????????????? emac, IEP_DEFAULT_CYCLE_TIME_NS);
>>> +??? if (ret) {
>>> +??????? netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
>>> +??????? goto stop;
>>> ????? }
>>> ? +??? icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>>> +
>>> ????? ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
>>> ???????????????????? IRQF_ONESHOT, dev_name(dev), emac);
>>> ????? if (ret)
>>> @@ -653,8 +716,7 @@ static int emac_ndo_open(struct net_device *ndev)
>>> ? free_tx_ts_irq:
>>> ????? free_irq(emac->tx_ts_irq, emac);
>>> ? stop:
>>> -??? prueth_emac_stop(emac);
>>> -free_rx_irq:
>>> +??? prueth_emac_common_stop(prueth);
>>> ????? free_irq(emac->rx_chns.irq[rx_flow], emac);
>>> ? cleanup_napi:
>>> ????? prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
>>> @@ -689,8 +751,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>>> ????? if (ndev->phydev)
>>> ????????? phy_stop(ndev->phydev);
>>> ? -??? icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
>>> -
>>> ????? if (emac->prueth->is_hsr_offload_mode)
>>> ????????? __dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
>>> ????? else
>>> @@ -728,11 +788,9 @@ static int emac_ndo_stop(struct net_device *ndev)
>>> ????? /* Destroying the queued work in ndo_stop() */
>>> ????? cancel_delayed_work_sync(&emac->stats_work);
>>> ? -??? if (prueth->emacs_initialized == 1)
>>> -??????? icss_iep_exit(emac->iep);
>>> -
>>> ????? /* stop PRUs */
>>> -??? prueth_emac_stop(emac);
>>> +??? if (prueth->emacs_initialized == 1)
>>> +??????? prueth_emac_common_stop(prueth);
>>> ? ????? free_irq(emac->tx_ts_irq, emac);
>>> ? @@ -1069,16 +1127,10 @@ static void prueth_emac_restart(struct prueth *prueth)
>>> ????? icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
>>> ? ????? /* Stop both pru cores for both PRUeth ports*/
>>> -??? prueth_emac_stop(emac0);
>>> -??? prueth->emacs_initialized--;
>>> -??? prueth_emac_stop(emac1);
>>> -??? prueth->emacs_initialized--;
>>> +??? prueth_emac_common_stop(prueth);
>>> ? ????? /* Start both pru cores for both PRUeth ports */
>>> -??? prueth_emac_start(prueth, emac0);
>>> -??? prueth->emacs_initialized++;
>>> -??? prueth_emac_start(prueth, emac1);
>>> -??? prueth->emacs_initialized++;
>>> +??? prueth_emac_common_start(prueth);
>>
>> But this can fail? You need to deal with failure condition appropriately.
>>
> 
> I haven't added failure conditions for two reasons:
> - Existing code also didn't have any error checks
> - This func simply reloads a new firmware, given everything is already working with the old one.
> 
> I can still handle error cases by changing this func to return int (currently it is void) and caller of the functions should print error and immediately return. Thoughts on this?

At least an error message somewhere will help to debug later.

> 
>>> ? ????? /* Enable forwarding for both PRUeth ports */
>>> ????? icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
>>> @@ -1413,13 +1465,10 @@ static int prueth_probe(struct platform_device *pdev)
>>> ????????? prueth->pa_stats = NULL;
>>> ????? }
>>> ? -??? if (eth0_node) {
>>> +??? if (eth0_node || eth1_node) {
>>> ????????? ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
>>> ????????? if (ret)
>>> ????????????? goto put_cores;
>>> -??? }
>>> -
>>> -??? if (eth1_node) {
>>> ????????? ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
>>> ????????? if (ret)
>>> ????????????? goto put_cores;
>>> @@ -1618,14 +1667,12 @@ static int prueth_probe(struct platform_device *pdev)
>>> ????? pruss_put(prueth->pruss);
>>> ? ? put_cores:
>>> -??? if (eth1_node) {
>>> -??????? prueth_put_cores(prueth, ICSS_SLICE1);
>>> -??????? of_node_put(eth1_node);
>>> -??? }
>>> -
>>> -??? if (eth0_node) {
>>> +??? if (eth0_node || eth1_node) {
>>> ????????? prueth_put_cores(prueth, ICSS_SLICE0);
>>> ????????? of_node_put(eth0_node);
>>> +
>>> +??????? prueth_put_cores(prueth, ICSS_SLICE1);
>>> +??????? of_node_put(eth1_node);
>>> ????? }
>>> ? ????? return ret;
>>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>> index f5c1d473e9f9..b30f2e9a73d8 100644
>>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>> @@ -257,6 +257,7 @@ struct icssg_firmwares {
>>> ?? * @is_switchmode_supported: indicates platform support for switch mode
>>> ?? * @switch_id: ID for mapping switch ports to bridge
>>> ?? * @default_vlan: Default VLAN for host
>>> + * @prus_running: flag to indicate if all pru cores are running
>>> ?? */
>>> ? struct prueth {
>>> ????? struct device *dev;
>>> @@ -298,6 +299,7 @@ struct prueth {
>>> ????? int default_vlan;
>>> ????? /** @vtbl_lock: Lock for vtbl in shared memory */
>>> ????? spinlock_t vtbl_lock;
>>> +??? bool prus_running;
>>
>> I think you don't need fw_running flag anymore. Could you please remove it
>> from struct prueth_emac?
>>
> 
> This flag is still being used by SR1, for which this patch doesn't apply. So I prefer not touching this flag for the sake of SR1.

ok let's leave it there then.

> 
>>> ? };
>>> ? ? struct emac_tx_ts_response {
>>> @@ -361,6 +363,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
>>> ?????????????? enum icssg_port_state_cmd state);
>>> ? void icssg_config_set_speed(struct prueth_emac *emac);
>>> ? void icssg_config_half_duplex(struct prueth_emac *emac);
>>> +void icssg_init_emac_mode(struct prueth *prueth);
>>> +void icssg_init_fw_offload_mode(struct prueth *prueth);
>>> ? ? /* Buffer queue helpers */
>>> ? int icssg_queue_pop(struct prueth *prueth, u8 queue);
>>> @@ -377,6 +381,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
>>> ???????????????? u8 untag_mask, bool add);
>>> ? u16 icssg_get_pvid(struct prueth_emac *emac);
>>> ? void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
>>> +int emac_fdb_flow_id_updated(struct prueth_emac *emac);
>>> ? #define prueth_napi_to_tx_chn(pnapi) \
>>> ????? container_of(pnapi, struct prueth_tx_chn, napi_tx)
>>> ? 
>>

-- 
cheers,
-roger



From angelogioacchino.delregno at collabora.com  Mon Dec  9 04:44:40 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 13:44:40 +0100
Subject: [PATCH v5 2/5] pinctrl: mediatek: add MT7988 pinctrl driver
In-Reply-To: <20241202110045.22084-3-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-3-linux@fw-web.de>
Message-ID: <d6be8228-3448-49a5-81a7-98acbdd19fbe@collabora.com>

Il 02/12/24 12:00, Frank Wunderlich ha scritto:
> From: Daniel Golle <daniel at makrotopia.org>
> 
> Add pinctrl driver for the MediaTek MT7988 SoC.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> [correctly initialise for the function_desc structure]
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> 

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From christophe.leroy at csgroup.eu  Mon Dec  9 04:45:17 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Mon, 9 Dec 2024 13:45:17 +0100
Subject: [PATCH v2 00/21] Converge on using secs_to_jiffies()
In-Reply-To: <72c8eb66-eb67-4f8b-b0c0-13f1aa001698@intel.com>
References: <20241115-converge-secs-to-jiffies-v2-0-911fb7595e79@linux.microsoft.com>
 <b9fcb12a-b7a4-4c33-836e-67109ce07deb@intel.com>
 <dab77729-682f-4182-9fb2-cd522ac29b5f@linux.microsoft.com>
 <72c8eb66-eb67-4f8b-b0c0-13f1aa001698@intel.com>
Message-ID: <95a461ca-3ed6-4380-ad1a-da12e1109675@csgroup.eu>



Le 09/12/2024 ? 13:01, Przemek Kitszel a ?crit?:
> On 12/6/24 9:58 PM, Easwar Hariharan wrote:
>> On 11/29/2024 4:57 AM, Przemek Kitszel wrote:
>>>
>>> [removed most non-list recipients, it's just too much]
>>>
>>> On 11/15/24 10:26 PM, Easwar Hariharan wrote:
>> <snip>
> 
>>>
>>> Regarding code - you could also convert msecs_to_jiffies(const * HZ),
>>> there are 10 that are greppable.
>>>
>>
>> Those seem to be mistakes. const*HZ is a seconds-denominated timeout,
>> being passed to msecs_to_jiffies() which will treat it as a
>> millisecond-denominated timeout resulting in an excessively long
>> timeout. I suppose that's better than a too-short timeout, and
>> apparently it's been working fine all along since hardware responds
>> before the too-long timeout expires. Half of them are in
>> drivers/scsi/arcmsr/arcmsr_hba.c and the pattern has apparently been
>> there since 2010.
> 
> my point was that, the default value of HZ is 1000, and most of the code
> that is just `$value*HZ` was meant as "$value seconds, in ms unit".

I can't follow you here. The default value of HZ is 250 as far as I can see.

Regardless, HZ is the number of jiffies per second, nothing else.

> 
> Same for HZ/const, HZ/2 being 500ms.
> 
> HZ is awful in that it is not 1s but 1/s, but it was easy to abuse the
> value in simple context.

Why is that awful ?

HZ is a nice macro that gives you the number of ticks per second, so 
that you are able to easily calculate the number of ticks for a given 
duration, regardless of the configured number of ticks per second.

Christophe


From angelogioacchino.delregno at collabora.com  Mon Dec  9 04:48:24 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 9 Dec 2024 13:48:24 +0100
Subject: [PATCH v5 1/5] pinctrl: mediatek: add support for
 MTK_PULL_PD_TYPE
In-Reply-To: <20241202110045.22084-2-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-2-linux@fw-web.de>
Message-ID: <94c80573-b18b-4328-8663-db9d6455fafd@collabora.com>

Il 02/12/24 12:00, Frank Wunderlich ha scritto:
> From: Daniel Golle <daniel at makrotopia.org>
> 
> The MediaTek MT7988 SoC got some pins which only got configurable
> pull-down but unlike previous designs there is no pull-up option.
> Add new type MTK_PULL_PD_TYPE to support configuring such pins.
> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From heiko at sntech.de  Mon Dec  9 04:48:08 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 09 Dec 2024 13:48:08 +0100
Subject: [RESEND PATCH] media: dt-bindings: trivial white-space and example
 cleanup
In-Reply-To: <20241209113405.74226-1-krzysztof.kozlowski@linaro.org>
References: <20241209113405.74226-1-krzysztof.kozlowski@linaro.org>
Message-ID: <9635159.2WqB4rESCP@diego>

Am Montag, 9. Dezember 2024, 12:34:05 CET schrieb Krzysztof Kozlowski:
> Minor cleanups without funcitonal impact:
>  - There should not be an empty blank line after SPDX tag,
>  - Convention is to indent DTS examples in coding style with 2- or
>    4-space indentation (4 is preferred),
>  - Drop unused labels in DTS examples.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>

(even looked at the whole patch and not only the Rockchip parts :-) )




From xiaolei.wang at windriver.com  Mon Dec  9 04:47:32 2024
From: xiaolei.wang at windriver.com (Xiaolei Wang)
Date: Mon,  9 Dec 2024 20:47:32 +0800
Subject: [PATCH] serial: imx: Use uart_port_lock_irqsave() instead of uart_port_lock()
Message-ID: <20241209124732.693834-1-xiaolei.wang@windriver.com>

When executing 'ehco mem > /sys/power/state', the following
deadlock occurs. Since there is output during the serial
port entering the suspend process, the suspend will be
interrupted, resulting in the nesting of locks. Therefore,
use uart_port_lock_irqsave instead of uart_port_unlock.

WARNING: inconsistent lock state
6.12.0-rc2-00002-g3c199ed5bd64-dirty #23 Not tainted
--------------------------------
inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
sh/494 [HC0[0]:SC0[0]:HE1:SE1] takes:
c4db5850 (&port_lock_key){?.-.}-{3:3}, at: imx_uart_enable_wakeup+0x14/0x254
{IN-HARDIRQ-W} state was registered at:
  lock_acquire+0x104/0x348
  _raw_spin_lock+0x48/0x84
  imx_uart_int+0x14/0x4dc
  __handle_irq_event_percpu+0xac/0x2fc
  handle_irq_event_percpu+0xc/0x40
  handle_irq_event+0x38/0x8c
  handle_fasteoi_irq+0xb4/0x1b8
  handle_irq_desc+0x1c/0x2c
  gic_handle_irq+0x6c/0xa0
  generic_handle_arch_irq+0x2c/0x64
  call_with_stack+0x18/0x20
  __irq_svc+0x9c/0xbc
  _raw_spin_unlock_irqrestore+0x2c/0x48
  uart_write+0xd8/0x3a0
  do_output_char+0x1a8/0x1e4
  n_tty_write+0x224/0x440
  file_tty_write.constprop.0+0x124/0x250
  do_iter_readv_writev+0x100/0x1e0
  vfs_writev+0xc4/0x448
  do_writev+0x68/0xf8
  ret_fast_syscall+0x0/0x1c
irq event stamp: 31593
hardirqs last  enabled at (31593): [<c1150e48>] _raw_spin_unlock_irqrestore+0x44/0x48
hardirqs last disabled at (31592): [<c07f32f0>] clk_enable_lock+0x60/0x120
softirqs last  enabled at (30334): [<c012d1d4>] handle_softirqs+0x2cc/0x478
softirqs last disabled at (30325): [<c012d510>] __irq_exit_rcu+0x120/0x15c

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&port_lock_key);
  <Interrupt>
    lock(&port_lock_key);

Fixes: 3c199ed5bd64 ("serial: imx: Grab port lock in imx_uart_enable_wakeup()")
Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>
---
 drivers/tty/serial/imx.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 17f70e4bee43..4470bcb3ef19 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2691,8 +2691,9 @@ static void imx_uart_save_context(struct imx_port *sport)
 static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
 {
 	u32 ucr3;
+	unsigned long flags;
 
-	uart_port_lock(&sport->port);
+	uart_port_lock_irqsave(&sport->port, &flags);
 
 	ucr3 = imx_uart_readl(sport, UCR3);
 	if (on) {
@@ -2714,7 +2715,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
 		imx_uart_writel(sport, ucr1, UCR1);
 	}
 
-	uart_port_unlock(&sport->port);
+	uart_port_unlock_irqrestore(&sport->port, flags);
 }
 
 static int imx_uart_suspend_noirq(struct device *dev)
-- 
2.25.1



From cohuck at redhat.com  Mon Dec  9 04:49:16 2024
From: cohuck at redhat.com (Cornelia Huck)
Date: Mon, 09 Dec 2024 13:49:16 +0100
Subject: [PATCH v3 3/3] arm64: paravirt: Enable errata based on
 implementation CPUs
In-Reply-To: <20241209115311.40496-4-shameerali.kolothum.thodi@huawei.com>
References: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>
 <20241209115311.40496-4-shameerali.kolothum.thodi@huawei.com>
Message-ID: <875xnt10oj.fsf@redhat.com>

On Mon, Dec 09 2024, Shameer Kolothum <shameerali.kolothum.thodi at huawei.com> wrote:

> Retrieve any migration target implementation CPUs using the hypercall
> and enable associated errata.
>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
> Note:
>
> One thing I am not sure here is how to handle the hypercall error.
> Do we need to fail the Guest boot or just carry on without any
> target implementation CPU support? At the moment it just carries on.
>
> Thanks,
> Shameer
> ---
>  arch/arm64/include/asm/cputype.h  | 25 +++++++++++++++++++++++--
>  arch/arm64/include/asm/paravirt.h |  3 +++
>  arch/arm64/kernel/cpu_errata.c    | 20 +++++++++++++++++---
>  arch/arm64/kernel/cpufeature.c    |  2 ++
>  arch/arm64/kernel/image-vars.h    |  2 ++
>  arch/arm64/kernel/paravirt.c      | 31 +++++++++++++++++++++++++++++++
>  6 files changed, 78 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index dcf0e1ce892d..9e466f3ae9c6 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -265,6 +265,16 @@ struct midr_range {
>  #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r)
>  #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
>  
> +#define MAX_TARGET_IMPL_CPUS 64
> +
> +struct target_impl_cpu {
> +	u32 midr;
> +	u32 revidr;
> +};

Doesn't this need to be u64 for both (even if the upper bits for
MIDR_EL1 are reserved?)



From o451686892 at gmail.com  Mon Dec  9 04:51:28 2024
From: o451686892 at gmail.com (Weizhao Ouyang)
Date: Mon, 9 Dec 2024 20:51:28 +0800
Subject: [PATCH] kselftest/arm64: abi: fix SVCR detection
In-Reply-To: <3279e669-1ee2-4792-9e10-8b40928de6b4@sirena.org.uk>
References: <20241209105237.10498-1-o451686892@gmail.com> <3279e669-1ee2-4792-9e10-8b40928de6b4@sirena.org.uk>
Message-ID: <CAHk0Hov5k37=MtTBLWTj+Dwm4EXE0xGJS1Uc8xgyLtJxusqsww@mail.gmail.com>

On Mon, Dec 9, 2024 at 8:36?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Mon, Dec 09, 2024 at 06:52:37PM +0800, Weizhao Ouyang wrote:
>
> > When using svcr_in to check ZA and Streaming Mode, we should make sure
> > that the value in x2 is correct, otherwise it may trigger an Illegal
> > instruction if FEAT_SVE and !FEAT_SME.
>
> >       // Set SVCR if we're doing SME
> > -     cbz     x1, 1f
> >       adrp    x2, svcr_in
> >       ldr     x2, [x2, :lo12:svcr_in]
> > +     cbz     x1, 1f
> >       msr     S3_3_C4_C2_2, x2
>
> This is against an older verison of the code so wouldn't apply now.
> It's not also checking the value of SVCR, this is checking the SME flag
> passed in via x1.  You can see that the SVCR value is loaded into x2 but
> the check is against x1.

Hi Mark,

This patch aims to fix the second check (SVCR_ZA_SHIFT) instead of
the first one (the x1 SME flag you're referring to):

// Load ZA and ZT0 if enabled - uses x12 as scratch due to SME LDR
tbz x2, #SVCR_ZA_SHIFT, 1f
mov w12, #0
ldr x2, =za_in
2: _ldr_za 12, 2

If SME disabled, x2 will not have an expected value.

BR,
Weizhao


From kevin.brodsky at arm.com  Mon Dec  9 04:57:09 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon, 9 Dec 2024 13:57:09 +0100
Subject: [RFC PATCH 00/16] pkeys-based page table hardening
In-Reply-To: <CAG48ez1b8BBquEB1BJEg+KsPdPyZLPuD7uToUH3ZdN8F0r+U9w@mail.gmail.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <CAG48ez1b8BBquEB1BJEg+KsPdPyZLPuD7uToUH3ZdN8F0r+U9w@mail.gmail.com>
Message-ID: <8fc285a3-92af-47e1-a405-0adf573c57aa@arm.com>

On 06/12/2024 20:14, Jann Horn wrote:
> On Fri, Dec 6, 2024 at 11:13?AM Kevin Brodsky <kevin.brodsky at arm.com> wrote:
>> [...]
>>
>> Page tables were chosen as they are a popular (and critical) target for
>> attacks, but there are of course many others - this is only a starting
>> point (see section "Further use-cases"). It has become more and more
>> common for accesses to such target data to be mediated by a hypervisor
>> in vendor kernels; the hope is that kpkeys can provide much of that
>> protection in a simpler manner. No benchmarking has been performed at
>> this stage, but the runtime overhead should also be lower (though likely
>> not negligible).
> Yeah, it isn't great that vendor kernels contain such invasive changes...
>
> I guess one difference between this approach and a hypervisor-based
> approach is that a hypervisor that uses a second layer of page tables
> can also prevent access through aliasing mappings, while pkeys only
> prevent access through a specific mapping? (Like if an attacker
> managed to add a page that is mapped into userspace to a page
> allocator freelist, allocate this page as a page table, and use the
> userspace mapping to write into this page table. But I guess whether
> that is an issue depends on the threat model.)

Yes, that's correct. If an attacker is able to modify page tables then
kpkeys are easily defeated. (kpkeys_hardened_pgtables does mitigate
precisely that, though.) On the topic of aliases, it's worth noting that
this isn't an issue with page table pages (only the linear mapping is
used), but if we wanted to assigning a pkey to vmalloc areas we'd also
have to amend the linear mapping.

>> [...]
>>
>> # Threat model
>>
>> The proposed scheme aims at mitigating data-only attacks (e.g.
>> use-after-free/cross-cache attacks). In other words, it is assumed that
>> control flow is not corrupted, and that the attacker does not achieve
>> arbitrary code execution. Nothing prevents the pkey register from being
>> set to its most permissive state - the assumption is that the register
>> is only modified on legitimate code paths.
> Is the threat model that the attacker has already achieved full
> read/write access to unprotected kernel data and should be stopped
> from gaining write access to protected data? Or is the threat model
> that the attacker has achieved some limited corruption, and this
> series is intended to make it harder to either gain write access to
> protected data or achieve full read/write access to unprotected data?

The assumption is that the attacker has acquired a write primitive that
could potentially allow corrupting any kernel data. The objective is to
make it harder to exploit that primitive by making critical data immune
to it. Nothing stops the attacker to turn to another (unprotected)
target, but this is no different from hypervisor-based protection - the
hope is that removing the low-hanging fruits makes it too difficult to
build a complete exploit chain.

- Kevin


From linux at fw-web.de  Mon Dec  9 04:57:34 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  9 Dec 2024 13:57:34 +0100
Subject: [PATCH v6 0/5] Add pinctrl support for mt7988
Message-ID: <20241209125742.9307-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This series adds pinctrl driver, dt-bindings and dts node for pinctrl
on mediatek mt7988 SoC.

changes in v6:
- some fixes to binding
- changed title and fixed typo in bpi-r4 patch
- added RB's

changes in v5:
- rebased to 6.13-rc1
- moved dt nodes with mutliple options to BPI-R4 board
- changes suggested by angelo in v4
- changed example in binding and dt node to not using const MTK_DRIVE_8mA

changes in v4:
- fixed fixed string binding error

changes in v3:
- rebase on rafals dts patches
- update binding to have mux subnode as fixed string and conf with optional suffix

changes in v2:
  binding:
  - drop gpio-cells description
  - move ref in mux subnode up
  - order uart-functions alphanumeric and fix typo
  dts:
  - fix indentation of reg-values


Daniel Golle (2):
  pinctrl: mediatek: add support for MTK_PULL_PD_TYPE
  pinctrl: mediatek: add MT7988 pinctrl driver

Frank Wunderlich (3):
  dt-bindings: pinctrl: add binding for MT7988 SoC
  arm64: dts: mediatek: mt7988: Add pinctrl support
  arm64: dts: mediatek: mt7988a-bpi-r4: Add pinctrl subnodes for bpi-r4

 .../pinctrl/mediatek,mt7988-pinctrl.yaml      |  575 ++++++
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  |  189 ++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi     |   54 +
 drivers/pinctrl/mediatek/Kconfig              |    7 +
 drivers/pinctrl/mediatek/Makefile             |    1 +
 drivers/pinctrl/mediatek/pinctrl-mt7988.c     | 1556 +++++++++++++++++
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  |   73 +-
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |    1 +
 8 files changed, 2445 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c

-- 
2.43.0



From linux at fw-web.de  Mon Dec  9 04:57:35 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  9 Dec 2024 13:57:35 +0100
Subject: [PATCH v6 1/5] pinctrl: mediatek: add support for MTK_PULL_PD_TYPE
In-Reply-To: <20241209125742.9307-1-linux@fw-web.de>
References: <20241209125742.9307-1-linux@fw-web.de>
Message-ID: <20241209125742.9307-2-linux@fw-web.de>

From: Daniel Golle <daniel at makrotopia.org>

The MediaTek MT7988 SoC got some pins which only got configurable
pull-down but unlike previous designs there is no pull-up option.
Add new type MTK_PULL_PD_TYPE to support configuring such pins.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v5:
- add changes suggested by angelo (pd_only), long version, tested with emmc
---
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  | 73 ++++++++++++++++---
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |  1 +
 2 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 54301fbba524..7b704cc55c9f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1);
  */
 static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
 				const struct mtk_pin_desc *desc,
-				u32 pullup, u32 arg)
+				u32 pullup, u32 arg, bool pd_only)
 {
 	int err, pu, pd;
 
@@ -587,18 +587,34 @@ static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
 		pu = 0;
 		pd = 1;
 	} else {
-		err = -EINVAL;
-		goto out;
+		return -EINVAL;
 	}
 
-	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
-	if (err)
-		goto out;
+	if (!pd_only) {
+		err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
+		if (err)
+			return err;
+	}
 
-	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+}
+
+static int mtk_pinconf_bias_set_pd(struct mtk_pinctrl *hw,
+				const struct mtk_pin_desc *desc,
+				u32 pullup, u32 arg)
+{
+	int err, pd;
+
+	if (arg != MTK_DISABLE && arg != MTK_ENABLE)
+		return -EINVAL;
+
+	if (arg == MTK_DISABLE || pullup)
+		pd = 0;
+	else if (!pullup)
+		pd = 1;
+
+	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
 
-out:
-	return err;
 }
 
 static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
@@ -737,7 +753,7 @@ static int mtk_pinconf_bias_set_pu_pd_rsel(struct mtk_pinctrl *hw,
 			return err;
 	}
 
-	return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable);
+	return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable, false);
 }
 
 int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
@@ -758,8 +774,14 @@ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
 			return 0;
 	}
 
+	if (try_all_type & MTK_PULL_PD_TYPE) {
+		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, true);
+		if (!err)
+			return err;
+	}
+
 	if (try_all_type & MTK_PULL_PU_PD_TYPE) {
-		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, false);
 		if (!err)
 			return 0;
 	}
@@ -878,6 +900,29 @@ static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
 	return err;
 }
 
+static int mtk_pinconf_bias_get_pd(struct mtk_pinctrl *hw,
+				const struct mtk_pin_desc *desc,
+				u32 *pullup, u32 *enable)
+{
+	int err, pd;
+
+	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
+	if (err)
+		goto out;
+
+	if (pd == 0) {
+		*pullup = 0;
+		*enable = MTK_DISABLE;
+	} else if (pd == 1) {
+		*pullup = 0;
+		*enable = MTK_ENABLE;
+	} else
+		err = -EINVAL;
+
+out:
+	return err;
+}
+
 static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
 				const struct mtk_pin_desc *desc,
 				u32 *pullup, u32 *enable)
@@ -947,6 +992,12 @@ int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
 			return 0;
 	}
 
+	if (try_all_type & MTK_PULL_PD_TYPE) {
+		err = mtk_pinconf_bias_get_pd(hw, desc, pullup, enable);
+		if (!err)
+			return err;
+	}
+
 	if (try_all_type & MTK_PULL_PU_PD_TYPE) {
 		err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
 		if (!err)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 23688ca6d04e..9c271dc2b521 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -24,6 +24,7 @@
  * turned on/off itself. But it can't be selected pull up/down
  */
 #define MTK_PULL_RSEL_TYPE		BIT(3)
+#define MTK_PULL_PD_TYPE        BIT(4)
 /* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by
  * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE.
  */
-- 
2.43.0



From linux at fw-web.de  Mon Dec  9 04:57:37 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  9 Dec 2024 13:57:37 +0100
Subject: [PATCH v6 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241209125742.9307-1-linux@fw-web.de>
References: <20241209125742.9307-1-linux@fw-web.de>
Message-ID: <20241209125742.9307-4-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This adds bindings for MT7988 pinctrl driver.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes in v6:
changes suggested by rob
- remove quotes around mux
- use const instead of enum if only one value is possible

changes in v5 (so not adding RB from Rob given in v4):
- do not use MTK_DRIVE_8mA in example
- add _0 functions for pwm

changes in v4:
- dt-binding: pinctrl: fix dt_binding_check fixed-string error

'^mux$' should not be valid under {'pattern': '^\\^[a-zA-Z0-9,\\-._#@]+\\$$'}
	hint: Fixed strings belong in 'properties', not 'patternProperties'

changes in v3:
- limit conf subnode name with optional suffix like mmc on mt7986
- match mux subnode without wildcards

changes in v2:
- drop gpio-cells description
- move ref in mux subnode up
- order uart-functions alphanumeric and fix typo
---
 .../pinctrl/mediatek,mt7988-pinctrl.yaml      | 575 ++++++++++++++++++
 1 file changed, 575 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
new file mode 100644
index 000000000000..26dfe7e7735a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
@@ -0,0 +1,575 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7988-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT7988 Pin Controller
+
+maintainers:
+  - Sean Wang <sean.wang at kernel.org>
+
+description:
+  The MediaTek's MT7988 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7988-pinctrl
+
+  reg:
+    minItems: 7
+    maxItems: 7
+
+  reg-names:
+    items:
+      - const: gpio
+      - const: iocfg_tr
+      - const: iocfg_br
+      - const: iocfg_rb
+      - const: iocfg_lb
+      - const: iocfg_tl
+      - const: eint
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-ranges:
+    minItems: 1
+    maxItems: 5
+    description:
+      GPIO valid number range.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - gpio-controller
+  - "#gpio-cells"
+
+patternProperties:
+  '-pins$':
+    type: object
+    additionalProperties: false
+
+    properties:
+      mux:
+        type: object
+        additionalProperties: false
+        $ref: /schemas/pinctrl/pinmux-node.yaml
+        description: |
+          pinmux configuration nodes.
+
+          The following table shows the effective values of "group", "function"
+          properties and chip pinout pins
+
+          groups               function           pins (in pin#)
+          ---------------------------------------------------------------------
+          "tops_jtag0_0"       "jtag"             0, 1, 2, 3, 4
+          "wo0_jtag"           "jtag"             50, 51, 52, 53, 54
+          "wo1_jtag"           "jtag"             50, 51, 52, 53, 54
+          "wo2_jtag"           "jtag"             50, 51, 52, 53, 54
+          "jtag"               "jtag"             58, 59, 60, 61, 62
+          "tops_jtag0_1"       "jtag"             58, 59, 60, 61, 62
+          "int_usxgmii"        "int_usxgmii"      2, 3
+          "pwm0"               "pwm"              57
+          "pwm1"               "pwm"              21
+          "pwm2"               "pwm"              80
+          "pwm2_0"             "pwm"              58
+          "pwm3"               "pwm"              81
+          "pwm3_0"             "pwm"              59
+          "pwm4"               "pwm"              82
+          "pwm4_0"             "pwm"              60
+          "pwm5"               "pwm"              83
+          "pwm5_0"             "pwm"              61
+          "pwm6"               "pwm"              69
+          "pwm6_0"             "pwm"              62
+          "pwm7"               "pwm"              70
+          "pwm7_0"             "pwm"              4
+          "dfd"                "dfd"              0, 1, 2, 3, 4
+          "xfi_phy0_i2c0"      "i2c"              0, 1
+          "xfi_phy1_i2c0"      "i2c"              0, 1
+          "xfi_phy_pll_i2c0"   "i2c"              3, 4
+          "xfi_phy_pll_i2c1"   "i2c"              3, 4
+          "i2c0_0"             "i2c"              5, 6
+          "i2c1_sfp"           "i2c"              5, 6
+          "xfi_pextp_phy0_i2c" "i2c"              5, 6
+          "xfi_pextp_phy1_i2c" "i2c"              5, 6
+          "i2c0_1"             "i2c"              15, 16
+          "u30_phy_i2c0"       "i2c"              15, 16
+          "u32_phy_i2c0"       "i2c"              15, 16
+          "xfi_phy0_i2c1"      "i2c"              15, 16
+          "xfi_phy1_i2c1"      "i2c"              15, 16
+          "xfi_phy_pll_i2c2"   "i2c"              15, 16
+          "i2c1_0"             "i2c"              17, 18
+          "u30_phy_i2c1"       "i2c"              17, 18
+          "u32_phy_i2c1"       "i2c"              17, 18
+          "xfi_phy_pll_i2c3"   "i2c"              17, 18
+          "sgmii0_i2c"         "i2c"              17, 18
+          "sgmii1_i2c"         "i2c"              17, 18
+          "i2c1_2"             "i2c"              69, 70
+          "i2c2_0"             "i2c"              69, 70
+          "i2c2_1"             "i2c"              71, 72
+          "mdc_mdio0"          "eth"              5, 6
+          "2p5g_ext_mdio"      "eth"              28, 29
+          "gbe_ext_mdio"       "eth"              30, 31
+          "mdc_mdio1"          "eth"              69, 70
+          "pcie_wake_n0_0"     "pcie"             7
+          "pcie_clk_req_n0_0"  "pcie"             8
+          "pcie_wake_n3_0"     "pcie"             9
+          "pcie_clk_req_n3"    "pcie"             10
+          "pcie_clk_req_n0_1"  "pcie"             10
+          "pcie_p0_phy_i2c"    "pcie"             7, 8
+          "pcie_p1_phy_i2c"    "pcie"             7, 8
+          "pcie_p3_phy_i2c"    "pcie"             9, 10
+          "pcie_p2_phy_i2c"    "pcie"             7, 8
+          "ckm_phy_i2c"        "pcie"             9, 10
+          "pcie_wake_n0_1"     "pcie"             13
+          "pcie_wake_n3_1"     "pcie"             14
+          "pcie_2l_0_pereset"  "pcie"             19
+          "pcie_1l_1_pereset"  "pcie"             20
+          "pcie_clk_req_n2_1"  "pcie"             63
+          "pcie_2l_1_pereset"  "pcie"             73
+          "pcie_1l_0_pereset"  "pcie"             74
+          "pcie_wake_n1_0"     "pcie"             75
+          "pcie_clk_req_n1"    "pcie"             76
+          "pcie_wake_n2_0"     "pcie"             77
+          "pcie_clk_req_n2_0"  "pcie"             78
+          "pcie_wake_n2_1"     "pcie"             79
+          "pmic"               "pmic"             11
+          "watchdog"           "watchdog"         12
+          "spi0_wp_hold"       "spi"              22, 23
+          "spi0"               "spi"              24, 25, 26, 27
+          "spi1"               "spi"              28, 29, 30, 31
+          "spi2"               "spi"              32, 33, 34, 35
+          "spi2_wp_hold"       "spi"              36, 37
+          "snfi"               "flash"            22, 23, 24, 25, 26, 27
+          "emmc_45"            "flash"            21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
+          "sdcard"             "flash"            32, 33, 34, 35, 36, 37
+          "emmc_51"            "flash"            38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49
+          "uart2"              "uart"             0, 1, 2, 3
+          "tops_uart0_0"       "uart"             22, 23
+          "uart2_0"            "uart"             28, 29, 30, 31
+          "uart1_0"            "uart"             32, 33, 34, 35
+          "uart2_1"            "uart"             32, 33, 34, 35
+          "net_wo0_uart_txd_0" "uart"             28
+          "net_wo1_uart_txd_0" "uart"             29
+          "net_wo2_uart_txd_0" "uart"             30
+          "tops_uart1_0"       "uart"             28, 29
+          "tops_uart0_1"       "uart"             30, 31
+          "tops_uart1_1"       "uart"             36, 37
+          "uart0"              "uart"             55, 56
+          "tops_uart0_2"       "uart"             55, 56
+          "uart2_2"            "uart"             50, 51, 52, 53
+          "uart1_1"            "uart"             58, 59, 60, 61
+          "uart2_3"            "uart"             58, 59, 60, 61
+          "uart1_2"            "uart"             80, 81, 82, 83
+          "uart1_2_lite"       "uart"             80, 81
+          "tops_uart1_2"       "uart"             80, 81
+          "net_wo0_uart_txd_1" "uart"             80
+          "net_wo1_uart_txd_1" "uart"             81
+          "net_wo2_uart_txd_1" "uart"             82
+          "udi"                "udi"              32, 33, 34, 35, 36
+          "i2s"                "audio"            50, 51, 52, 53, 54
+          "pcm"                "audio"            50, 51, 52, 53
+          "gbe0_led1"          "led"              58
+          "gbe1_led1"          "led"              59
+          "gbe2_led1"          "led"              60
+          "gbe3_led1"          "led"              61
+          "2p5gbe_led1"        "led"              62
+          "gbe0_led0"          "led"              64
+          "gbe1_led0"          "led"              65
+          "gbe2_led0"          "led"              66
+          "gbe3_led0"          "led"              67
+          "2p5gbe_led0"        "led"              68
+          "drv_vbus_p1"        "usb"              63
+          "drv_vbus"           "usb"              79
+
+        properties:
+          function:
+            description:
+              A string containing the name of the function to mux to the group.
+            enum: [audio, dfd, eth, flash, i2c, int_usxgmii, jtag, led, pcie, pmic, pwm, spi,
+                   uart, udi, usb, watchdog]
+          groups:
+            description:
+              An array of strings. Each string contains the name of a group.
+
+        required:
+          - function
+          - groups
+
+        allOf:
+          - if:
+              properties:
+                function:
+                  const: audio
+            then:
+              properties:
+                groups:
+                  enum: [i2s, pcm]
+          - if:
+              properties:
+                function:
+                  const: jtag
+            then:
+              properties:
+                groups:
+                  enum: [jtag, tops_jtag0_0, tops_jtag0_1, wo0_jtag, wo1_jtag, wo2_jtag]
+          - if:
+              properties:
+                function:
+                  const: int_usxgmii
+            then:
+              properties:
+                groups:
+                  const: int_usxgmii
+          - if:
+              properties:
+                function:
+                  const: dfd
+            then:
+              properties:
+                groups:
+                  const: dfd
+          - if:
+              properties:
+                function:
+                  const: flash
+            then:
+              properties:
+                groups:
+                  enum: [emmc_45, emmc_51, sdcard, snfi]
+          - if:
+              properties:
+                function:
+                  const: eth
+            then:
+              properties:
+                groups:
+                  enum: [2p5g_ext_mdio, gbe_ext_mdio, mdc_mdio0, mdc_mdio1]
+          - if:
+              properties:
+                function:
+                  const: i2c
+            then:
+              properties:
+                groups:
+                  enum: [xfi_phy0_i2c0, xfi_phy1_i2c0, xfi_phy_pll_i2c0,
+                         xfi_phy_pll_i2c1, i2c0_0, i2c1_sfp, xfi_pextp_phy0_i2c,
+                         xfi_pextp_phy1_i2c, i2c0_1, u30_phy_i2c0, u32_phy_i2c0,
+                         xfi_phy0_i2c1, xfi_phy1_i2c1, xfi_phy_pll_i2c2, i2c1_0,
+                         u30_phy_i2c1, u32_phy_i2c1, xfi_phy_pll_i2c3, sgmii0_i2c,
+                         sgmii1_i2c, i2c1_2, i2c2_0, i2c2_1]
+          - if:
+              properties:
+                function:
+                  const: led
+            then:
+              properties:
+                groups:
+                  enum: [2p5gbe_led0, 2p5gbe_led1, gbe0_led0, gbe0_led1, gbe1_led0, gbe1_led1,
+                         gbe2_led0, gbe2_led1, gbe3_led0, gbe3_led1, wf5g_led0, wf5g_led1]
+          - if:
+              properties:
+                function:
+                  const: pcie
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [pcie_wake_n0_0, pcie_clk_req_n0_0, pcie_wake_n3_0,
+                           pcie_clk_req_n3, pcie_p0_phy_i2c, pcie_p1_phy_i2c,
+                           pcie_p3_phy_i2c, pcie_p2_phy_i2c, ckm_phy_i2c,
+                           pcie_wake_n0_1, pcie_wake_n3_1, pcie_2l_0_pereset,
+                           pcie_1l_1_pereset, pcie_clk_req_n2_1, pcie_2l_1_pereset,
+                           pcie_1l_0_pereset, pcie_wake_n1_0, pcie_clk_req_n1,
+                           pcie_wake_n2_0, pcie_clk_req_n2_0, pcie_wake_n2_1,
+                           pcie_clk_req_n0_1]
+                  maxItems: 3
+          - if:
+              properties:
+                function:
+                  const: pmic
+            then:
+              properties:
+                groups:
+                  const: pmic
+          - if:
+              properties:
+                function:
+                  const: pwm
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [pwm0, pwm1, pwm2, pwm2_0, pwm3, pwm3_0, pwm4, pwm4_0, pwm5, pwm5_0,
+                           pwm6, pwm6_0, pwm7, pwm7_0]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: spi
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [spi0, spi0_wp_hold, spi1, spi2, spi2_wp_hold]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: uart
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [net_wo0_uart_txd_0, net_wo0_uart_txd_1, net_wo1_uart_txd_0,
+                           net_wo1_uart_txd_1, net_wo2_uart_txd_0, net_wo2_uart_txd_1,
+                           tops_uart0_0, tops_uart0_1, tops_uart0_2, tops_uart1_0,
+                           tops_uart1_1, tops_uart1_2, uart0, uart1_0, uart1_1, uart1_2,
+                           uart1_2_lite, uart2, uart2_0, uart2_1, uart2_3]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: watchdog
+            then:
+              properties:
+                groups:
+                  const: watchdog
+          - if:
+              properties:
+                function:
+                  const: udi
+            then:
+              properties:
+                groups:
+                  const: udi
+          - if:
+              properties:
+                function:
+                  const: usb
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [drv_vbus, drv_vbus_p1]
+                  maxItems: 1
+
+    patternProperties:
+      '^conf(-[-a-z]*)?$':
+        type: object
+        additionalProperties: false
+        description:
+          pinconf configuration nodes.
+        $ref: /schemas/pinctrl/pincfg-node.yaml
+
+        properties:
+          pins:
+            description:
+              An array of strings. Each string contains the name of a pin.
+            items:
+              enum: [UART2_RXD, UART2_TXD, UART2_CTS, UART2_RTS, GPIO_A, SMI_0_MDC,
+                     SMI_0_MDIO, PCIE30_2L_0_WAKE_N, PCIE30_2L_0_CLKREQ_N,
+                     PCIE30_1L_1_WAKE_N, PCIE30_1L_1_CLKREQ_N, GPIO_P, WATCHDOG,
+                     GPIO_RESET, GPIO_WPS, PMIC_I2C_SCL, PMIC_I2C_SDA, I2C_1_SCL,
+                     I2C_1_SDA, PCIE30_2L_0_PRESET_N, PCIE30_1L_1_PRESET_N, PWMD1,
+                     SPI0_WP, SPI0_HOLD, SPI0_CSB, SPI0_MISO, SPI0_MOSI, SPI0_CLK,
+                     SPI1_CSB, SPI1_MISO, SPI1_MOSI, SPI1_CLK, SPI2_CLK, SPI2_MOSI,
+                     SPI2_MISO, SPI2_CSB, SPI2_HOLD, SPI2_WP, EMMC_RSTB, EMMC_DSL,
+                     EMMC_CK, EMMC_CMD, EMMC_DATA_7, EMMC_DATA_6, EMMC_DATA_5,
+                     EMMC_DATA_4, EMMC_DATA_3, EMMC_DATA_2, EMMC_DATA_1,
+                     EMMC_DATA_0, PCM_FS_I2S_LRCK, PCM_CLK_I2S_BCLK,
+                     PCM_DRX_I2S_DIN, PCM_DTX_I2S_DOUT, PCM_MCK_I2S_MCLK,
+                     UART0_RXD, UART0_TXD, PWMD0, JTAG_JTDI, JTAG_JTDO, JTAG_JTMS,
+                     JTAG_JTCLK, JTAG_JTRST_N, USB_DRV_VBUS_P1, LED_A, LED_B, LED_C,
+                     LED_D, LED_E, GPIO_B, GPIO_C, I2C_2_SCL, I2C_2_SDA,
+                     PCIE30_2L_1_PRESET_N, PCIE30_1L_0_PRESET_N,
+                     PCIE30_2L_1_WAKE_N, PCIE30_2L_1_CLKREQ_N,
+                     PCIE30_1L_0_WAKE_N, PCIE30_1L_0_CLKREQ_N, USB_DRV_VBUS_P0,
+                     UART1_RXD, UART1_TXD, UART1_CTS, UART1_RTS]
+            maxItems: 84
+
+          bias-disable: true
+
+          bias-pull-up:
+            oneOf:
+              - type: boolean
+                description: normal pull up.
+              - enum: [100, 101, 102, 103]
+                description:
+                  PUPD/R1/R0 pull down type. See MTK_PUPD_SET_R1R0 defines in
+                  dt-bindings/pinctrl/mt65xx.h.
+
+          bias-pull-down:
+            oneOf:
+              - type: boolean
+                description: normal pull down.
+              - enum: [100, 101, 102, 103]
+                description:
+                  PUPD/R1/R0 pull down type. See MTK_PUPD_SET_R1R0 defines in
+                  dt-bindings/pinctrl/mt65xx.h.
+
+          input-enable: true
+
+          input-disable: true
+
+          output-enable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            enum: [2, 4, 6, 8, 10, 12, 14, 16]
+
+          mediatek,pull-up-adv:
+            description: |
+              Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
+              Pull up settings for 2 pull resistors, R0 and R1. Valid arguments
+              are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,pull-down-adv:
+            description: |
+              Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
+              Pull down settings for 2 pull resistors, R0 and R1. Valid arguments
+              are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+        required:
+          - pins
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/mt65xx.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      pio: pinctrl at 1001f000 {
+        compatible = "mediatek,mt7988-pinctrl";
+        reg = <0 0x1001f000 0 0x1000>,
+        <0 0x11c10000 0 0x1000>,
+        <0 0x11d00000 0 0x1000>,
+        <0 0x11d20000 0 0x1000>,
+        <0 0x11e00000 0 0x1000>,
+        <0 0x11f00000 0 0x1000>,
+        <0 0x1000b000 0 0x1000>;
+        reg-names = "gpio", "iocfg_tr",
+          "iocfg_br", "iocfg_rb",
+          "iocfg_lb", "iocfg_tl", "eint";
+        gpio-controller;
+        #gpio-cells = <2>;
+        gpio-ranges = <&pio 0 0 84>;
+        interrupt-controller;
+        interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-parent = <&gic>;
+        #interrupt-cells = <2>;
+
+        i2c0_pins: i2c0-g0-pins {
+          mux {
+            function = "i2c";
+            groups = "i2c0_1";
+          };
+        };
+
+        mdio0_pins: mdio0-pins {
+          mux {
+            function = "eth";
+            groups = "mdc_mdio0";
+          };
+
+          conf {
+            pins = "SMI_0_MDC", "SMI_0_MDIO";
+            drive-strength = <8>;
+          };
+        };
+
+        mmc0_pins_emmc_51: mmc0-emmc-51-pins {
+          mux {
+            function = "flash";
+            groups = "emmc_51";
+          };
+        };
+
+        mmc0_pins_sdcard: mmc0-sdcard-pins {
+          mux {
+            function = "flash";
+            groups = "sdcard";
+          };
+        };
+
+        pcie0_pins: pcie0-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
+                     "pcie_wake_n0_0";
+          };
+        };
+
+        pcie1_pins: pcie1-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
+                     "pcie_wake_n1_0";
+          };
+        };
+
+        pcie2_pins: pcie2-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
+                     "pcie_wake_n2_0";
+          };
+        };
+
+        pcie3_pins: pcie3-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
+                     "pcie_wake_n3_0";
+          };
+        };
+
+        uart0_pins: uart0-pins {
+          mux {
+            function = "uart";
+            groups =  "uart0";
+          };
+        };
+      };
+    };
-- 
2.43.0



From linux at fw-web.de  Mon Dec  9 04:57:38 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  9 Dec 2024 13:57:38 +0100
Subject: [PATCH v6 4/5] arm64: dts: mediatek: mt7988: Add pinctrl support
In-Reply-To: <20241209125742.9307-1-linux@fw-web.de>
References: <20241209125742.9307-1-linux@fw-web.de>
Message-ID: <20241209125742.9307-5-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add mt7988a pinctrl node.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v5:
- drop pins with second function

v2:
- fix wrong alignment of reg values
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 54 +++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index c9649b815276..46969577c87a 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -3,6 +3,7 @@
 #include <dt-bindings/clock/mediatek,mt7988-clk.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
 
 / {
 	compatible = "mediatek,mt7988a";
@@ -105,6 +106,59 @@ clock-controller at 1001e000 {
 			#clock-cells = <1>;
 		};
 
+		pio: pinctrl at 1001f000 {
+			compatible = "mediatek,mt7988-pinctrl";
+			reg = <0 0x1001f000 0 0x1000>,
+			      <0 0x11c10000 0 0x1000>,
+			      <0 0x11d00000 0 0x1000>,
+			      <0 0x11d20000 0 0x1000>,
+			      <0 0x11e00000 0 0x1000>,
+			      <0 0x11f00000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "gpio", "iocfg_tr",
+				    "iocfg_br", "iocfg_rb",
+				    "iocfg_lb", "iocfg_tl", "eint";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pio 0 0 84>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&gic>;
+			#interrupt-cells = <2>;
+
+			pcie0_pins: pcie0-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
+						 "pcie_wake_n0_0";
+				};
+			};
+
+			pcie1_pins: pcie1-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
+						 "pcie_wake_n1_0";
+				};
+			};
+
+			pcie2_pins: pcie2-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
+						 "pcie_wake_n2_0";
+				};
+			};
+
+			pcie3_pins: pcie3-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
+						 "pcie_wake_n3_0";
+				};
+			};
+		};
+
 		pwm at 10048000 {
 			compatible = "mediatek,mt7988-pwm";
 			reg = <0 0x10048000 0 0x1000>;
-- 
2.43.0



From linux at fw-web.de  Mon Dec  9 04:57:36 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  9 Dec 2024 13:57:36 +0100
Subject: [PATCH v6 2/5] pinctrl: mediatek: add MT7988 pinctrl driver
In-Reply-To: <20241209125742.9307-1-linux@fw-web.de>
References: <20241209125742.9307-1-linux@fw-web.de>
Message-ID: <20241209125742.9307-3-linux@fw-web.de>

From: Daniel Golle <daniel at makrotopia.org>

Add pinctrl driver for the MediaTek MT7988 SoC.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
[correctly initialise for the function_desc structure]
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v5:
- changes requested by angelo
  - lowercase mt7988_pinctrl_reg_page
  - compatible match in one line
  - HW debounce is only available for pins 0 to 15 and does not support
    pins with numbers 16 or higher.
- add additional PWM pingroups
---
 drivers/pinctrl/mediatek/Kconfig          |    7 +
 drivers/pinctrl/mediatek/Makefile         |    1 +
 drivers/pinctrl/mediatek/pinctrl-mt7988.c | 1556 +++++++++++++++++++++
 3 files changed, 1564 insertions(+)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c

diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index a417a031659c..58f32818a0e6 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -202,6 +202,13 @@ config PINCTRL_MT7986
 	default ARM64 && ARCH_MEDIATEK
 	select PINCTRL_MTK_MOORE
 
+config PINCTRL_MT7988
+	bool "Mediatek MT7988 pin control"
+	depends on OF
+	depends on ARM64 || COMPILE_TEST
+	default ARM64 && ARCH_MEDIATEK
+	select PINCTRL_MTK_MOORE
+
 config PINCTRL_MT8167
 	bool "MediaTek MT8167 pin control"
 	depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 1405d434218e..721ae83476d0 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_PINCTRL_MT7623)		+= pinctrl-mt7623.o
 obj-$(CONFIG_PINCTRL_MT7629)		+= pinctrl-mt7629.o
 obj-$(CONFIG_PINCTRL_MT7981)		+= pinctrl-mt7981.o
 obj-$(CONFIG_PINCTRL_MT7986)		+= pinctrl-mt7986.o
+obj-$(CONFIG_PINCTRL_MT7988)		+= pinctrl-mt7988.o
 obj-$(CONFIG_PINCTRL_MT8167)		+= pinctrl-mt8167.o
 obj-$(CONFIG_PINCTRL_MT8173)		+= pinctrl-mt8173.o
 obj-$(CONFIG_PINCTRL_MT8183)		+= pinctrl-mt8183.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7988.c b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
new file mode 100644
index 000000000000..9d59ac2d2e4f
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
@@ -0,0 +1,1556 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7988 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2020 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ */
+
+#include "pinctrl-moore.h"
+
+enum mt7988_pinctrl_reg_page {
+	GPIO_BASE,
+	IOCFG_TR_BASE,
+	IOCFG_BR_BASE,
+	IOCFG_RB_BASE,
+	IOCFG_LB_BASE,
+	IOCFG_TL_BASE,
+};
+
+#define MT7988_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+		       _x_bits)                                                \
+	PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+		       _x_bits, 32, 0)
+
+#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,    \
+			_x_bits)                                               \
+	PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+		       _x_bits, 32, 1)
+
+static const struct mtk_pin_field_calc mt7988_pin_mode_range[] = {
+	PIN_FIELD(0, 83, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_dir_range[] = {
+	PIN_FIELD(0, 83, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_di_range[] = {
+	PIN_FIELD(0, 83, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_do_range[] = {
+	PIN_FIELD(0, 83, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_ies_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x30, 0x10, 13, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x30, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0x30, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x40, 0x10, 21, 1),
+	PIN_FIELD_BASE(13, 13, 1, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0x40, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(15, 15, 5, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(16, 16, 5, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(17, 17, 5, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(18, 18, 5, 0x30, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x30, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x50, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x50, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x50, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x50, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x50, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x50, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x50, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x50, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x50, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x50, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x50, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x50, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x50, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x50, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x50, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x50, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x50, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x50, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x50, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x40, 0x10, 13, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(63, 63, 1, 0x40, 0x10, 20, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x40, 0x10, 11, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x40, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(71, 71, 5, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(72, 72, 5, 0x30, 0x10, 6, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(75, 75, 4, 0x30, 0x10, 11, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0x30, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x40, 0x10, 18, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x40, 0x10, 19, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x40, 0x10, 17, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_smt_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0xc0, 0x10, 13, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0xc0, 0x10, 14, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0xc0, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0xc0, 0x10, 12, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0xc0, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0xc0, 0x10, 9, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0xc0, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(7, 7, 4, 0xb0, 0x10, 8, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0xb0, 0x10, 6, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0xb0, 0x10, 5, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0xb0, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0xe0, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0xe0, 0x10, 21, 1),
+	PIN_FIELD_BASE(13, 13, 1, 0xe0, 0x10, 1, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0xe0, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(15, 15, 5, 0xc0, 0x10, 7, 1),
+	PIN_FIELD_BASE(16, 16, 5, 0xc0, 0x10, 8, 1),
+	PIN_FIELD_BASE(17, 17, 5, 0xc0, 0x10, 3, 1),
+	PIN_FIELD_BASE(18, 18, 5, 0xc0, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0xb0, 0x10, 7, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0xb0, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x140, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x140, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x140, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x140, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x140, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x140, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x140, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x140, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x140, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x140, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x140, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x140, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0x150, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x140, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x140, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x140, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x150, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x140, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x140, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x140, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x140, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x140, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x140, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x140, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x140, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x140, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x140, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x140, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x140, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x140, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x140, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x140, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x140, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x140, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0xe0, 0x10, 14, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0xe0, 0x10, 15, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0xe0, 0x10, 13, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0xe0, 0x10, 4, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0xe0, 0x10, 5, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0xe0, 0x10, 6, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0xe0, 0x10, 3, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0xe0, 0x10, 7, 1),
+	PIN_FIELD_BASE(63, 63, 1, 0xe0, 0x10, 20, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0xe0, 0x10, 8, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0xe0, 0x10, 9, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0xe0, 0x10, 10, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0xe0, 0x10, 11, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0xe0, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0xc0, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0xc0, 0x10, 2, 1),
+	PIN_FIELD_BASE(71, 71, 5, 0xc0, 0x10, 5, 1),
+	PIN_FIELD_BASE(72, 72, 5, 0xc0, 0x10, 6, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0xb0, 0x10, 10, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0xb0, 0x10, 1, 1),
+	PIN_FIELD_BASE(75, 75, 4, 0xb0, 0x10, 11, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0xb0, 0x10, 9, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0xb0, 0x10, 2, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0xb0, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0xb0, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0xe0, 0x10, 18, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0xe0, 0x10, 19, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0xe0, 0x10, 16, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0xe0, 0x10, 17, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_pu_range[] = {
+	PIN_FIELD_BASE(7, 7, 4, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x60, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0x60, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(13, 13, 1, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(63, 63, 1, 0x70, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(75, 75, 4, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0x60, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_pd_range[] = {
+	PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0x40, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(13, 13, 1, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0x50, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(15, 15, 5, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(16, 16, 5, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(17, 17, 5, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(18, 18, 5, 0x40, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(63, 63, 1, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(71, 71, 5, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(72, 72, 5, 0x40, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(75, 75, 4, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0x40, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_drv_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(1, 1, 5, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(3, 3, 5, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(4, 4, 5, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(5, 5, 5, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(6, 6, 5, 0x00, 0x10, 12, 3),
+
+	PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 28, 3),
+	PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(10, 10, 4, 0x00, 0x10, 9, 3),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(12, 12, 1, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(13, 13, 1, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(14, 14, 1, 0x00, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(20, 20, 4, 0x00, 0x10, 12, 3),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x10, 0x10, 21, 3),
+	PIN_FIELD_BASE(22, 22, 3, 0x20, 0x10, 9, 3),
+	PIN_FIELD_BASE(23, 23, 3, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(24, 24, 3, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(25, 25, 3, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(26, 26, 3, 0x20, 0x10, 6, 3),
+	PIN_FIELD_BASE(27, 27, 3, 0x10, 0x10, 24, 3),
+	PIN_FIELD_BASE(28, 28, 3, 0x20, 0x10, 15, 3),
+	PIN_FIELD_BASE(29, 29, 3, 0x20, 0x10, 18, 3),
+	PIN_FIELD_BASE(30, 30, 3, 0x20, 0x10, 21, 3),
+	PIN_FIELD_BASE(31, 31, 3, 0x20, 0x10, 12, 3),
+	PIN_FIELD_BASE(32, 32, 3, 0x20, 0x10, 24, 3),
+	PIN_FIELD_BASE(33, 33, 3, 0x30, 0x10, 6, 3),
+	PIN_FIELD_BASE(34, 34, 3, 0x30, 0x10, 3, 3),
+	PIN_FIELD_BASE(35, 35, 3, 0x20, 0x10, 27, 3),
+	PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 0, 3),
+	PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 9, 3),
+	PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(40, 40, 3, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(41, 41, 3, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(42, 42, 3, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(43, 43, 3, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(44, 44, 3, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(45, 45, 3, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(46, 46, 3, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(47, 47, 3, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(48, 48, 3, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(49, 49, 3, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(50, 50, 3, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(51, 51, 3, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(52, 52, 3, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(53, 53, 3, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(54, 54, 3, 0x10, 0x10, 18, 3),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(56, 56, 1, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(57, 57, 1, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(58, 58, 1, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(59, 59, 1, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(60, 60, 1, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(61, 61, 1, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(62, 62, 1, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(63, 63, 1, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(64, 64, 1, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(65, 65, 1, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(66, 66, 1, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(67, 67, 1, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(68, 68, 1, 0x10, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(70, 70, 5, 0x00, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(74, 74, 4, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(75, 75, 4, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(76, 76, 4, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(77, 77, 4, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(78, 78, 4, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(79, 79, 4, 0x10, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x10, 0x10, 24, 3),
+	PIN_FIELD_BASE(81, 81, 1, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(82, 82, 1, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(83, 83, 1, 0x10, 0x10, 21, 3),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_pupd_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x50, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x60, 0x10, 18, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x50, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x70, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x70, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x70, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x70, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x70, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x70, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x70, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x70, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x70, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x70, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x70, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x70, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x70, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x70, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x70, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x70, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x70, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x70, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x70, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x70, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x70, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x70, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x70, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x70, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x70, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x70, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x70, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x60, 0x10, 12, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x60, 0x10, 13, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x60, 0x10, 11, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x60, 0x10, 4, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x60, 0x10, 9, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x60, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x50, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x50, 0x10, 0, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x60, 0x10, 16, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x60, 0x10, 17, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x60, 0x10, 14, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x60, 0x10, 15, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_r0_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x60, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x80, 0x10, 18, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x70, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x90, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x90, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x90, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x90, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x90, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x90, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x90, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x90, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x90, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x90, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x90, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x90, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0xa0, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x90, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x90, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x90, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0xa0, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x90, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x90, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x90, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x90, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x90, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x90, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x90, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x90, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x80, 0x10, 12, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x80, 0x10, 13, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x80, 0x10, 11, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x80, 0x10, 3, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x80, 0x10, 4, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x80, 0x10, 5, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x80, 0x10, 6, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x80, 0x10, 7, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x80, 0x10, 8, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x80, 0x10, 9, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x80, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x60, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x70, 0x10, 0, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x80, 0x10, 16, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x80, 0x10, 17, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x80, 0x10, 14, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x80, 0x10, 15, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_r1_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x70, 0x10, 7, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x70, 0x10, 5, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x70, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x70, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x90, 0x10, 18, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x80, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0xb0, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0xb0, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0xb0, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0xb0, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0xb0, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0xb0, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0xb0, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0xb0, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0xb0, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0xb0, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0xb0, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0xb0, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0xc0, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0xb0, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0xb0, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0xb0, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0xc0, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0xb0, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0xb0, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0xb0, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0xb0, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0xb0, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0xb0, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0xb0, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0xb0, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0xb0, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0xb0, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0xb0, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0xb0, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0xb0, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0xb0, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0xb0, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0xb0, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0xb0, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x90, 0x10, 12, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x90, 0x10, 13, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x90, 0x10, 11, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x90, 0x10, 6, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x90, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x70, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x80, 0x10, 3, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x80, 0x10, 0, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x90, 0x10, 16, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x90, 0x10, 17, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x90, 0x10, 14, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x90, 0x10, 15, 1),
+};
+
+static const unsigned int mt7988_pull_type[] = {
+	MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PU_PD_TYPE,    /*7*/
+	MTK_PULL_PU_PD_TYPE,    /*8*/ MTK_PULL_PU_PD_TYPE,    /*9*/
+	MTK_PULL_PU_PD_TYPE,    /*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PU_PD_TYPE,    /*13*/
+	MTK_PULL_PU_PD_TYPE,    /*14*/ MTK_PULL_PD_TYPE,       /*15*/
+	MTK_PULL_PD_TYPE,       /*16*/ MTK_PULL_PD_TYPE,       /*17*/
+	MTK_PULL_PD_TYPE,       /*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PU_PD_TYPE,    /*63*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PUPD_R1R0_TYPE,/*69*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*70*/ MTK_PULL_PD_TYPE,       /*71*/
+	MTK_PULL_PD_TYPE,       /*72*/ MTK_PULL_PUPD_R1R0_TYPE,/*73*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,    /*75*/
+	MTK_PULL_PU_PD_TYPE,    /*76*/ MTK_PULL_PU_PD_TYPE,    /*77*/
+	MTK_PULL_PU_PD_TYPE,    /*78*/ MTK_PULL_PU_PD_TYPE,    /*79*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*80*/ MTK_PULL_PUPD_R1R0_TYPE,/*81*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*82*/ MTK_PULL_PUPD_R1R0_TYPE,/*83*/
+};
+
+static const struct mtk_pin_reg_calc mt7988_reg_cals[] = {
+	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7988_pin_mode_range),
+	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7988_pin_dir_range),
+	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7988_pin_di_range),
+	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7988_pin_do_range),
+	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7988_pin_smt_range),
+	[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7988_pin_ies_range),
+	[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7988_pin_pu_range),
+	[PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7988_pin_pd_range),
+	[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7988_pin_drv_range),
+	[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7988_pin_pupd_range),
+	[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7988_pin_r0_range),
+	[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7988_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7988_pins[] = {
+	MT7988_PIN(0, "UART2_RXD"),
+	MT7988_PIN(1, "UART2_TXD"),
+	MT7988_PIN(2, "UART2_CTS"),
+	MT7988_PIN(3, "UART2_RTS"),
+	MT7988_PIN(4, "GPIO_A"),
+	MT7988_PIN(5, "SMI_0_MDC"),
+	MT7988_PIN(6, "SMI_0_MDIO"),
+	MT7988_PIN(7, "PCIE30_2L_0_WAKE_N"),
+	MT7988_PIN(8, "PCIE30_2L_0_CLKREQ_N"),
+	MT7988_PIN(9, "PCIE30_1L_1_WAKE_N"),
+	MT7988_PIN(10, "PCIE30_1L_1_CLKREQ_N"),
+	MT7988_PIN(11, "GPIO_P"),
+	MT7988_PIN(12, "WATCHDOG"),
+	MT7988_PIN(13, "GPIO_RESET"),
+	MT7988_PIN(14, "GPIO_WPS"),
+	MT7988_PIN(15, "PMIC_I2C_SCL"),
+	MT7988_PIN(16, "PMIC_I2C_SDA"),
+	MT7988_PIN(17, "I2C_1_SCL"),
+	MT7988_PIN(18, "I2C_1_SDA"),
+	MT7988_PIN(19, "PCIE30_2L_0_PRESET_N"),
+	MT7988_PIN(20, "PCIE30_1L_1_PRESET_N"),
+	MT7988_PIN(21, "PWMD1"),
+	MT7988_PIN(22, "SPI0_WP"),
+	MT7988_PIN(23, "SPI0_HOLD"),
+	MT7988_PIN(24, "SPI0_CSB"),
+	MT7988_PIN(25, "SPI0_MISO"),
+	MT7988_PIN(26, "SPI0_MOSI"),
+	MT7988_PIN(27, "SPI0_CLK"),
+	MT7988_PIN(28, "SPI1_CSB"),
+	MT7988_PIN(29, "SPI1_MISO"),
+	MT7988_PIN(30, "SPI1_MOSI"),
+	MT7988_PIN(31, "SPI1_CLK"),
+	MT7988_PIN(32, "SPI2_CLK"),
+	MT7988_PIN(33, "SPI2_MOSI"),
+	MT7988_PIN(34, "SPI2_MISO"),
+	MT7988_PIN(35, "SPI2_CSB"),
+	MT7988_PIN(36, "SPI2_HOLD"),
+	MT7988_PIN(37, "SPI2_WP"),
+	MT7988_PIN(38, "EMMC_RSTB"),
+	MT7988_PIN(39, "EMMC_DSL"),
+	MT7988_PIN(40, "EMMC_CK"),
+	MT7988_PIN(41, "EMMC_CMD"),
+	MT7988_PIN(42, "EMMC_DATA_7"),
+	MT7988_PIN(43, "EMMC_DATA_6"),
+	MT7988_PIN(44, "EMMC_DATA_5"),
+	MT7988_PIN(45, "EMMC_DATA_4"),
+	MT7988_PIN(46, "EMMC_DATA_3"),
+	MT7988_PIN(47, "EMMC_DATA_2"),
+	MT7988_PIN(48, "EMMC_DATA_1"),
+	MT7988_PIN(49, "EMMC_DATA_0"),
+	MT7988_PIN(50, "PCM_FS_I2S_LRCK"),
+	MT7988_PIN(51, "PCM_CLK_I2S_BCLK"),
+	MT7988_PIN(52, "PCM_DRX_I2S_DIN"),
+	MT7988_PIN(53, "PCM_DTX_I2S_DOUT"),
+	MT7988_PIN(54, "PCM_MCK_I2S_MCLK"),
+	MT7988_PIN(55, "UART0_RXD"),
+	MT7988_PIN(56, "UART0_TXD"),
+	MT7988_PIN(57, "PWMD0"),
+	MT7988_PIN(58, "JTAG_JTDI"),
+	MT7988_PIN(59, "JTAG_JTDO"),
+	MT7988_PIN(60, "JTAG_JTMS"),
+	MT7988_PIN(61, "JTAG_JTCLK"),
+	MT7988_PIN(62, "JTAG_JTRST_N"),
+	MT7988_PIN(63, "USB_DRV_VBUS_P1"),
+	MT7988_PIN(64, "LED_A"),
+	MT7988_PIN(65, "LED_B"),
+	MT7988_PIN(66, "LED_C"),
+	MT7988_PIN(67, "LED_D"),
+	MT7988_PIN(68, "LED_E"),
+	MT7988_PIN(69, "GPIO_B"),
+	MT7988_PIN(70, "GPIO_C"),
+	MT7988_PIN(71, "I2C_2_SCL"),
+	MT7988_PIN(72, "I2C_2_SDA"),
+	MT7988_PIN(73, "PCIE30_2L_1_PRESET_N"),
+	MT7988_PIN(74, "PCIE30_1L_0_PRESET_N"),
+	MT7988_PIN(75, "PCIE30_2L_1_WAKE_N"),
+	MT7988_PIN(76, "PCIE30_2L_1_CLKREQ_N"),
+	MT7988_PIN(77, "PCIE30_1L_0_WAKE_N"),
+	MT7988_PIN(78, "PCIE30_1L_0_CLKREQ_N"),
+	MT7988_PIN(79, "USB_DRV_VBUS_P0"),
+	MT7988_PIN(80, "UART1_RXD"),
+	MT7988_PIN(81, "UART1_TXD"),
+	MT7988_PIN(82, "UART1_CTS"),
+	MT7988_PIN(83, "UART1_RTS"),
+};
+
+/* jtag */
+static int mt7988_tops_jtag0_0_pins[] = { 0, 1, 2, 3, 4 };
+static int mt7988_tops_jtag0_0_funcs[] = { 2, 2, 2, 2, 2 };
+
+static int mt7988_wo0_jtag_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_wo0_jtag_funcs[] = { 3, 3, 3, 3, 3 };
+
+static int mt7988_wo1_jtag_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_wo1_jtag_funcs[] = { 4, 4, 4, 4, 4 };
+
+static int mt7988_wo2_jtag_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_wo2_jtag_funcs[] = { 5, 5, 5, 5, 5 };
+
+static int mt7988_jtag_pins[] = { 58, 59, 60, 61, 62 };
+static int mt7988_jtag_funcs[] = { 1, 1, 1, 1, 1 };
+
+static int mt7988_tops_jtag0_1_pins[] = { 58, 59, 60, 61, 62 };
+static int mt7988_tops_jtag0_1_funcs[] = { 4, 4, 4, 4, 4 };
+
+/* int_usxgmii */
+static int mt7988_int_usxgmii_pins[] = { 2, 3 };
+static int mt7988_int_usxgmii_funcs[] = { 3, 3 };
+
+/* pwm */
+static int mt7988_pwm0_pins[] = { 57 };
+static int mt7988_pwm0_funcs[] = { 1 };
+
+static int mt7988_pwm1_pins[] = { 21 };
+static int mt7988_pwm1_funcs[] = { 1 };
+
+static int mt7988_pwm2_pins[] = { 80 };
+static int mt7988_pwm2_funcs[] = { 2 };
+
+static int mt7988_pwm2_0_pins[] = { 58 };
+static int mt7988_pwm2_0_funcs[] = { 5 };
+
+static int mt7988_pwm3_pins[] = { 81 };
+static int mt7988_pwm3_funcs[] = { 2 };
+
+static int mt7988_pwm3_0_pins[] = { 59 };
+static int mt7988_pwm3_0_funcs[] = { 5 };
+
+static int mt7988_pwm4_pins[] = { 82 };
+static int mt7988_pwm4_funcs[] = { 2 };
+
+static int mt7988_pwm4_0_pins[] = { 60 };
+static int mt7988_pwm4_0_funcs[] = { 5 };
+
+static int mt7988_pwm5_pins[] = { 83 };
+static int mt7988_pwm5_funcs[] = { 2 };
+
+static int mt7988_pwm5_0_pins[] = { 61 };
+static int mt7988_pwm5_0_funcs[] = { 5 };
+
+static int mt7988_pwm6_pins[] = { 69 };
+static int mt7988_pwm6_funcs[] = { 3 };
+
+static int mt7988_pwm6_0_pins[] = { 62 };
+static int mt7988_pwm6_0_funcs[] = { 5 };
+
+static int mt7988_pwm7_pins[] = { 70 };
+static int mt7988_pwm7_funcs[] = { 3 };
+
+static int mt7988_pwm7_0_pins[] = { 4 };
+static int mt7988_pwm7_0_funcs[] = { 3 };
+
+/* dfd */
+static int mt7988_dfd_pins[] = { 0, 1, 2, 3, 4 };
+static int mt7988_dfd_funcs[] = { 4, 4, 4, 4, 4 };
+
+/* i2c */
+static int mt7988_xfi_phy0_i2c0_pins[] = { 0, 1 };
+static int mt7988_xfi_phy0_i2c0_funcs[] = { 5, 5 };
+
+static int mt7988_xfi_phy1_i2c0_pins[] = { 0, 1 };
+static int mt7988_xfi_phy1_i2c0_funcs[] = { 6, 6 };
+
+static int mt7988_xfi_phy_pll_i2c0_pins[] = { 3, 4 };
+static int mt7988_xfi_phy_pll_i2c0_funcs[] = { 5, 5 };
+
+static int mt7988_xfi_phy_pll_i2c1_pins[] = { 3, 4 };
+static int mt7988_xfi_phy_pll_i2c1_funcs[] = { 6, 6 };
+
+static int mt7988_i2c0_0_pins[] = { 5, 6 };
+static int mt7988_i2c0_0_funcs[] = { 2, 2 };
+
+static int mt7988_i2c1_sfp_pins[] = { 5, 6 };
+static int mt7988_i2c1_sfp_funcs[] = { 4, 4 };
+
+static int mt7988_xfi_pextp_phy0_i2c_pins[] = { 5, 6 };
+static int mt7988_xfi_pextp_phy0_i2c_funcs[] = { 5, 5 };
+
+static int mt7988_xfi_pextp_phy1_i2c_pins[] = { 5, 6 };
+static int mt7988_xfi_pextp_phy1_i2c_funcs[] = { 6, 6 };
+
+static int mt7988_i2c0_1_pins[] = { 15, 16 };
+static int mt7988_i2c0_1_funcs[] = { 1, 1 };
+
+static int mt7988_u30_phy_i2c0_pins[] = { 15, 16 };
+static int mt7988_u30_phy_i2c0_funcs[] = { 2, 2 };
+
+static int mt7988_u32_phy_i2c0_pins[] = { 15, 16 };
+static int mt7988_u32_phy_i2c0_funcs[] = { 3, 3 };
+
+static int mt7988_xfi_phy0_i2c1_pins[] = { 15, 16 };
+static int mt7988_xfi_phy0_i2c1_funcs[] = { 5, 5 };
+
+static int mt7988_xfi_phy1_i2c1_pins[] = { 15, 16 };
+static int mt7988_xfi_phy1_i2c1_funcs[] = { 6, 6 };
+
+static int mt7988_xfi_phy_pll_i2c2_pins[] = { 15, 16 };
+static int mt7988_xfi_phy_pll_i2c2_funcs[] = { 7, 7 };
+
+static int mt7988_i2c1_0_pins[] = { 17, 18 };
+static int mt7988_i2c1_0_funcs[] = { 1, 1 };
+
+static int mt7988_u30_phy_i2c1_pins[] = { 17, 18 };
+static int mt7988_u30_phy_i2c1_funcs[] = { 2, 2 };
+
+static int mt7988_u32_phy_i2c1_pins[] = { 17, 18 };
+static int mt7988_u32_phy_i2c1_funcs[] = { 3, 3 };
+
+static int mt7988_xfi_phy_pll_i2c3_pins[] = { 17, 18 };
+static int mt7988_xfi_phy_pll_i2c3_funcs[] = { 4, 4 };
+
+static int mt7988_sgmii0_i2c_pins[] = { 17, 18 };
+static int mt7988_sgmii0_i2c_funcs[] = { 5, 5 };
+
+static int mt7988_sgmii1_i2c_pins[] = { 17, 18 };
+static int mt7988_sgmii1_i2c_funcs[] = { 6, 6 };
+
+static int mt7988_i2c1_2_pins[] = { 69, 70 };
+static int mt7988_i2c1_2_funcs[] = { 2, 2 };
+
+static int mt7988_i2c2_0_pins[] = { 69, 70 };
+static int mt7988_i2c2_0_funcs[] = { 4, 4 };
+
+static int mt7988_i2c2_1_pins[] = { 71, 72 };
+static int mt7988_i2c2_1_funcs[] = { 1, 1 };
+
+/* eth */
+static int mt7988_mdc_mdio0_pins[] = { 5, 6 };
+static int mt7988_mdc_mdio0_funcs[] = { 1, 1 };
+
+static int mt7988_2p5g_ext_mdio_pins[] = { 28, 29 };
+static int mt7988_2p5g_ext_mdio_funcs[] = { 6, 6 };
+
+static int mt7988_gbe_ext_mdio_pins[] = { 30, 31 };
+static int mt7988_gbe_ext_mdio_funcs[] = { 6, 6 };
+
+static int mt7988_mdc_mdio1_pins[] = { 69, 70 };
+static int mt7988_mdc_mdio1_funcs[] = { 1, 1 };
+
+/* pcie */
+static int mt7988_pcie_wake_n0_0_pins[] = { 7 };
+static int mt7988_pcie_wake_n0_0_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n0_0_pins[] = { 8 };
+static int mt7988_pcie_clk_req_n0_0_funcs[] = { 1 };
+
+static int mt7988_pcie_wake_n3_0_pins[] = { 9 };
+static int mt7988_pcie_wake_n3_0_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n3_pins[] = { 10 };
+static int mt7988_pcie_clk_req_n3_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n0_1_pins[] = { 10 };
+static int mt7988_pcie_clk_req_n0_1_funcs[] = { 2 };
+
+static int mt7988_pcie_p0_phy_i2c_pins[] = { 7, 8 };
+static int mt7988_pcie_p0_phy_i2c_funcs[] = { 3, 3 };
+
+static int mt7988_pcie_p1_phy_i2c_pins[] = { 7, 8 };
+static int mt7988_pcie_p1_phy_i2c_funcs[] = { 4, 4 };
+
+static int mt7988_pcie_p3_phy_i2c_pins[] = { 9, 10 };
+static int mt7988_pcie_p3_phy_i2c_funcs[] = { 4, 4 };
+
+static int mt7988_pcie_p2_phy_i2c_pins[] = { 7, 8 };
+static int mt7988_pcie_p2_phy_i2c_funcs[] = { 5, 5 };
+
+static int mt7988_ckm_phy_i2c_pins[] = { 9, 10 };
+static int mt7988_ckm_phy_i2c_funcs[] = { 5, 5 };
+
+static int mt7988_pcie_wake_n0_1_pins[] = { 13 };
+static int mt7988_pcie_wake_n0_1_funcs[] = { 2 };
+
+static int mt7988_pcie_wake_n3_1_pins[] = { 14 };
+static int mt7988_pcie_wake_n3_1_funcs[] = { 2 };
+
+static int mt7988_pcie_2l_0_pereset_pins[] = { 19 };
+static int mt7988_pcie_2l_0_pereset_funcs[] = { 1 };
+
+static int mt7988_pcie_1l_1_pereset_pins[] = { 20 };
+static int mt7988_pcie_1l_1_pereset_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n2_1_pins[] = { 63 };
+static int mt7988_pcie_clk_req_n2_1_funcs[] = { 2 };
+
+static int mt7988_pcie_2l_1_pereset_pins[] = { 73 };
+static int mt7988_pcie_2l_1_pereset_funcs[] = { 1 };
+
+static int mt7988_pcie_1l_0_pereset_pins[] = { 74 };
+static int mt7988_pcie_1l_0_pereset_funcs[] = { 1 };
+
+static int mt7988_pcie_wake_n1_0_pins[] = { 75 };
+static int mt7988_pcie_wake_n1_0_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n1_pins[] = { 76 };
+static int mt7988_pcie_clk_req_n1_funcs[] = { 1 };
+
+static int mt7988_pcie_wake_n2_0_pins[] = { 77 };
+static int mt7988_pcie_wake_n2_0_funcs[] = { 1 };
+
+static int mt7988_pcie_clk_req_n2_0_pins[] = { 78 };
+static int mt7988_pcie_clk_req_n2_0_funcs[] = { 1 };
+
+static int mt7988_pcie_wake_n2_1_pins[] = { 79 };
+static int mt7988_pcie_wake_n2_1_funcs[] = { 2 };
+
+/* pmic */
+static int mt7988_pmic_pins[] = { 11 };
+static int mt7988_pmic_funcs[] = { 1 };
+
+/* watchdog */
+static int mt7988_watchdog_pins[] = { 12 };
+static int mt7988_watchdog_funcs[] = { 1 };
+
+/* spi */
+static int mt7988_spi0_wp_hold_pins[] = { 22, 23 };
+static int mt7988_spi0_wp_hold_funcs[] = { 1, 1 };
+
+static int mt7988_spi0_pins[] = { 24, 25, 26, 27 };
+static int mt7988_spi0_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_spi1_pins[] = { 28, 29, 30, 31 };
+static int mt7988_spi1_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_spi2_pins[] = { 32, 33, 34, 35 };
+static int mt7988_spi2_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_spi2_wp_hold_pins[] = { 36, 37 };
+static int mt7988_spi2_wp_hold_funcs[] = { 1, 1 };
+
+/* flash */
+static int mt7988_snfi_pins[] = { 22, 23, 24, 25, 26, 27 };
+static int mt7988_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
+
+static int mt7988_emmc_45_pins[] = {
+	21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
+};
+static int mt7988_emmc_45_funcs[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
+
+static int mt7988_sdcard_pins[] = { 32, 33, 34, 35, 36, 37 };
+static int mt7988_sdcard_funcs[] = { 5, 5, 5, 5, 5, 5 };
+
+static int mt7988_emmc_51_pins[] = { 38, 39, 40, 41, 42, 43,
+				     44, 45, 46, 47, 48, 49 };
+static int mt7988_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+
+/* uart */
+static int mt7988_uart2_pins[] = { 0, 1, 2, 3 };
+static int mt7988_uart2_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_tops_uart0_0_pins[] = { 22, 23 };
+static int mt7988_tops_uart0_0_funcs[] = { 3, 3 };
+
+static int mt7988_uart2_0_pins[] = { 28, 29, 30, 31 };
+static int mt7988_uart2_0_funcs[] = { 2, 2, 2, 2 };
+
+static int mt7988_uart1_0_pins[] = { 32, 33, 34, 35 };
+static int mt7988_uart1_0_funcs[] = { 2, 2, 2, 2 };
+
+static int mt7988_uart2_1_pins[] = { 32, 33, 34, 35 };
+static int mt7988_uart2_1_funcs[] = { 3, 3, 3, 3 };
+
+static int mt7988_net_wo0_uart_txd_0_pins[] = { 28 };
+static int mt7988_net_wo0_uart_txd_0_funcs[] = { 3 };
+
+static int mt7988_net_wo1_uart_txd_0_pins[] = { 29 };
+static int mt7988_net_wo1_uart_txd_0_funcs[] = { 3 };
+
+static int mt7988_net_wo2_uart_txd_0_pins[] = { 30 };
+static int mt7988_net_wo2_uart_txd_0_funcs[] = { 3 };
+
+static int mt7988_tops_uart1_0_pins[] = { 28, 29 };
+static int mt7988_tops_uart1_0_funcs[] = { 4, 4 };
+
+static int mt7988_tops_uart0_1_pins[] = { 30, 31 };
+static int mt7988_tops_uart0_1_funcs[] = { 4, 4 };
+
+static int mt7988_tops_uart1_1_pins[] = { 36, 37 };
+static int mt7988_tops_uart1_1_funcs[] = { 3, 3 };
+
+static int mt7988_uart0_pins[] = { 55, 56 };
+static int mt7988_uart0_funcs[] = { 1, 1 };
+
+static int mt7988_tops_uart0_2_pins[] = { 55, 56 };
+static int mt7988_tops_uart0_2_funcs[] = { 2, 2 };
+
+static int mt7988_uart2_2_pins[] = { 50, 51, 52, 53 };
+static int mt7988_uart2_2_funcs[] = { 2, 2, 2, 2 };
+
+static int mt7988_uart1_1_pins[] = { 58, 59, 60, 61 };
+static int mt7988_uart1_1_funcs[] = { 2, 2, 2, 2 };
+
+static int mt7988_uart2_3_pins[] = { 58, 59, 60, 61 };
+static int mt7988_uart2_3_funcs[] = { 3, 3, 3, 3 };
+
+static int mt7988_uart1_2_pins[] = { 80, 81, 82, 83 };
+static int mt7988_uart1_2_funcs[] = { 1, 1, 1, 1 };
+
+static int mt7988_uart1_2_lite_pins[] = { 80, 81 };
+static int mt7988_uart1_2_lite_funcs[] = { 1, 1 };
+
+static int mt7988_tops_uart1_2_pins[] = { 80, 81 };
+static int mt7988_tops_uart1_2_funcs[] = { 4, 4, };
+
+static int mt7988_net_wo0_uart_txd_1_pins[] = { 80 };
+static int mt7988_net_wo0_uart_txd_1_funcs[] = { 3 };
+
+static int mt7988_net_wo1_uart_txd_1_pins[] = { 81 };
+static int mt7988_net_wo1_uart_txd_1_funcs[] = { 3 };
+
+static int mt7988_net_wo2_uart_txd_1_pins[] = { 82 };
+static int mt7988_net_wo2_uart_txd_1_funcs[] = { 3 };
+
+/* udi */
+static int mt7988_udi_pins[] = { 32, 33, 34, 35, 36 };
+static int mt7988_udi_funcs[] = { 4, 4, 4, 4, 4 };
+
+/* i2s */
+static int mt7988_i2s_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_i2s_funcs[] = { 1, 1, 1, 1, 1 };
+
+/* pcm */
+static int mt7988_pcm_pins[] = { 50, 51, 52, 53 };
+static int mt7988_pcm_funcs[] = { 1, 1, 1, 1 };
+
+/* led */
+static int mt7988_gbe0_led1_pins[] = { 58 };
+static int mt7988_gbe0_led1_funcs[] = { 6 };
+static int mt7988_gbe1_led1_pins[] = { 59 };
+static int mt7988_gbe1_led1_funcs[] = { 6 };
+static int mt7988_gbe2_led1_pins[] = { 60 };
+static int mt7988_gbe2_led1_funcs[] = { 6 };
+static int mt7988_gbe3_led1_pins[] = { 61 };
+static int mt7988_gbe3_led1_funcs[] = { 6 };
+
+static int mt7988_2p5gbe_led1_pins[] = { 62 };
+static int mt7988_2p5gbe_led1_funcs[] = { 6 };
+
+static int mt7988_gbe0_led0_pins[] = { 64 };
+static int mt7988_gbe0_led0_funcs[] = { 1 };
+static int mt7988_gbe1_led0_pins[] = { 65 };
+static int mt7988_gbe1_led0_funcs[] = { 1 };
+static int mt7988_gbe2_led0_pins[] = { 66 };
+static int mt7988_gbe2_led0_funcs[] = { 1 };
+static int mt7988_gbe3_led0_pins[] = { 67 };
+static int mt7988_gbe3_led0_funcs[] = { 1 };
+
+static int mt7988_2p5gbe_led0_pins[] = { 68 };
+static int mt7988_2p5gbe_led0_funcs[] = { 1 };
+
+/* usb */
+static int mt7988_drv_vbus_p1_pins[] = { 63 };
+static int mt7988_drv_vbus_p1_funcs[] = { 1 };
+
+static int mt7988_drv_vbus_pins[] = { 79 };
+static int mt7988_drv_vbus_funcs[] = { 1 };
+
+static const struct group_desc mt7988_groups[] = {
+	/*  @GPIO(0,1,2,3): uart2 */
+	PINCTRL_PIN_GROUP("uart2", mt7988_uart2),
+	/*  @GPIO(0,1,2,3,4): tops_jtag0_0 */
+	PINCTRL_PIN_GROUP("tops_jtag0_0", mt7988_tops_jtag0_0),
+	/*  @GPIO(2,3): int_usxgmii */
+	PINCTRL_PIN_GROUP("int_usxgmii", mt7988_int_usxgmii),
+	/*  @GPIO(0,1,2,3,4): dfd */
+	PINCTRL_PIN_GROUP("dfd", mt7988_dfd),
+	/*  @GPIO(0,1): xfi_phy0_i2c0 */
+	PINCTRL_PIN_GROUP("xfi_phy0_i2c0", mt7988_xfi_phy0_i2c0),
+	/*  @GPIO(0,1): xfi_phy1_i2c0 */
+	PINCTRL_PIN_GROUP("xfi_phy1_i2c0", mt7988_xfi_phy1_i2c0),
+	/*  @GPIO(3,4): xfi_phy_pll_i2c0 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c0", mt7988_xfi_phy_pll_i2c0),
+	/*  @GPIO(3,4): xfi_phy_pll_i2c1 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c1", mt7988_xfi_phy_pll_i2c1),
+	/*  @GPIO(4): pwm7 */
+	PINCTRL_PIN_GROUP("pwm7_0", mt7988_pwm7_0),
+	/*  @GPIO(5,6) i2c0_0 */
+	PINCTRL_PIN_GROUP("i2c0_0", mt7988_i2c0_0),
+	/*  @GPIO(5,6) i2c1_sfp */
+	PINCTRL_PIN_GROUP("i2c1_sfp", mt7988_i2c1_sfp),
+	/*  @GPIO(5,6) xfi_pextp_phy0_i2c */
+	PINCTRL_PIN_GROUP("xfi_pextp_phy0_i2c", mt7988_xfi_pextp_phy0_i2c),
+	/*  @GPIO(5,6) xfi_pextp_phy1_i2c */
+	PINCTRL_PIN_GROUP("xfi_pextp_phy1_i2c", mt7988_xfi_pextp_phy1_i2c),
+	/*  @GPIO(5,6) mdc_mdio0 */
+	PINCTRL_PIN_GROUP("mdc_mdio0", mt7988_mdc_mdio0),
+	/*  @GPIO(7): pcie_wake_n0_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n0_0", mt7988_pcie_wake_n0_0),
+	/*  @GPIO(8): pcie_clk_req_n0_0 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n0_0", mt7988_pcie_clk_req_n0_0),
+	/*  @GPIO(9): pcie_wake_n3_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n3_0", mt7988_pcie_wake_n3_0),
+	/*  @GPIO(10): pcie_clk_req_n3 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n3", mt7988_pcie_clk_req_n3),
+	/*  @GPIO(10): pcie_clk_req_n0_1 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n0_1", mt7988_pcie_clk_req_n0_1),
+	/*  @GPIO(7,8) pcie_p0_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p0_phy_i2c", mt7988_pcie_p0_phy_i2c),
+	/*  @GPIO(7,8) pcie_p1_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p1_phy_i2c", mt7988_pcie_p1_phy_i2c),
+	/*  @GPIO(7,8) pcie_p2_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p2_phy_i2c", mt7988_pcie_p2_phy_i2c),
+	/*  @GPIO(9,10) pcie_p3_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p3_phy_i2c", mt7988_pcie_p3_phy_i2c),
+	/*  @GPIO(9,10) ckm_phy_i2c */
+	PINCTRL_PIN_GROUP("ckm_phy_i2c", mt7988_ckm_phy_i2c),
+	/*  @GPIO(11): pmic */
+	PINCTRL_PIN_GROUP("pcie_pmic", mt7988_pmic),
+	/*  @GPIO(12): watchdog */
+	PINCTRL_PIN_GROUP("watchdog", mt7988_watchdog),
+	/*  @GPIO(13): pcie_wake_n0_1 */
+	PINCTRL_PIN_GROUP("pcie_wake_n0_1", mt7988_pcie_wake_n0_1),
+	/*  @GPIO(14): pcie_wake_n3_1 */
+	PINCTRL_PIN_GROUP("pcie_wake_n3_1", mt7988_pcie_wake_n3_1),
+	/*  @GPIO(15,16) i2c0_1 */
+	PINCTRL_PIN_GROUP("i2c0_1", mt7988_i2c0_1),
+	/*  @GPIO(15,16) u30_phy_i2c0 */
+	PINCTRL_PIN_GROUP("u30_phy_i2c0", mt7988_u30_phy_i2c0),
+	/*  @GPIO(15,16) u32_phy_i2c0 */
+	PINCTRL_PIN_GROUP("u32_phy_i2c0", mt7988_u32_phy_i2c0),
+	/*  @GPIO(15,16) xfi_phy0_i2c1 */
+	PINCTRL_PIN_GROUP("xfi_phy0_i2c1", mt7988_xfi_phy0_i2c1),
+	/*  @GPIO(15,16) xfi_phy1_i2c1 */
+	PINCTRL_PIN_GROUP("xfi_phy1_i2c1", mt7988_xfi_phy1_i2c1),
+	/*  @GPIO(15,16) xfi_phy_pll_i2c2 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c2", mt7988_xfi_phy_pll_i2c2),
+	/*  @GPIO(17,18) i2c1_0 */
+	PINCTRL_PIN_GROUP("i2c1_0", mt7988_i2c1_0),
+	/*  @GPIO(17,18) u30_phy_i2c1 */
+	PINCTRL_PIN_GROUP("u30_phy_i2c1", mt7988_u30_phy_i2c1),
+	/*  @GPIO(17,18) u32_phy_i2c1 */
+	PINCTRL_PIN_GROUP("u32_phy_i2c1", mt7988_u32_phy_i2c1),
+	/*  @GPIO(17,18) xfi_phy_pll_i2c3 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c3", mt7988_xfi_phy_pll_i2c3),
+	/*  @GPIO(17,18) sgmii0_i2c */
+	PINCTRL_PIN_GROUP("sgmii0_i2c", mt7988_sgmii0_i2c),
+	/*  @GPIO(17,18) sgmii1_i2c */
+	PINCTRL_PIN_GROUP("sgmii1_i2c", mt7988_sgmii1_i2c),
+	/*  @GPIO(19): pcie_2l_0_pereset */
+	PINCTRL_PIN_GROUP("pcie_2l_0_pereset", mt7988_pcie_2l_0_pereset),
+	/*  @GPIO(20): pcie_1l_1_pereset */
+	PINCTRL_PIN_GROUP("pcie_1l_1_pereset", mt7988_pcie_1l_1_pereset),
+	/*  @GPIO(21): pwm1 */
+	PINCTRL_PIN_GROUP("pwm1", mt7988_pwm1),
+	/*  @GPIO(22,23) spi0_wp_hold */
+	PINCTRL_PIN_GROUP("spi0_wp_hold", mt7988_spi0_wp_hold),
+	/*  @GPIO(24,25,26,27) spi0 */
+	PINCTRL_PIN_GROUP("spi0", mt7988_spi0),
+	/*  @GPIO(28,29,30,31) spi1 */
+	PINCTRL_PIN_GROUP("spi1", mt7988_spi1),
+	/*  @GPIO(32,33,34,35) spi2 */
+	PINCTRL_PIN_GROUP("spi2", mt7988_spi2),
+	/*  @GPIO(36,37) spi2_wp_hold */
+	PINCTRL_PIN_GROUP("spi2_wp_hold", mt7988_spi2_wp_hold),
+	/*  @GPIO(22,23,24,25,26,27) snfi */
+	PINCTRL_PIN_GROUP("snfi", mt7988_snfi),
+	/*  @GPIO(22,23) tops_uart0_0 */
+	PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart0_0),
+	/*  @GPIO(28,29,30,31) uart2_0 */
+	PINCTRL_PIN_GROUP("uart2_0", mt7988_uart2_0),
+	/*  @GPIO(32,33,34,35) uart1_0 */
+	PINCTRL_PIN_GROUP("uart1_0", mt7988_uart1_0),
+	/*  @GPIO(32,33,34,35) uart2_1 */
+	PINCTRL_PIN_GROUP("uart2_1", mt7988_uart2_1),
+	/*  @GPIO(28) net_wo0_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
+	/*  @GPIO(29) net_wo1_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
+	/*  @GPIO(30) net_wo2_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
+	/*  @GPIO(28,29) tops_uart1_0 */
+	PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart1_0),
+	/*  @GPIO(30,31) tops_uart0_1 */
+	PINCTRL_PIN_GROUP("tops_uart0_1", mt7988_tops_uart0_1),
+	/*  @GPIO(36,37) tops_uart1_1 */
+	PINCTRL_PIN_GROUP("tops_uart1_1", mt7988_tops_uart1_1),
+	/*  @GPIO(32,33,34,35,36) udi */
+	PINCTRL_PIN_GROUP("udi", mt7988_udi),
+	/*  @GPIO(21,28,29,30,31,32,33,34,35,36,37) emmc_45 */
+	PINCTRL_PIN_GROUP("emmc_45", mt7988_emmc_45),
+	/*  @GPIO(32,33,34,35,36,37) sdcard */
+	PINCTRL_PIN_GROUP("sdcard", mt7988_sdcard),
+	/*  @GPIO(38,39,40,41,42,43,44,45,46,47,48,49) emmc_51 */
+	PINCTRL_PIN_GROUP("emmc_51", mt7988_emmc_51),
+	/*  @GPIO(28,29) 2p5g_ext_mdio */
+	PINCTRL_PIN_GROUP("2p5g_ext_mdio", mt7988_2p5g_ext_mdio),
+	/*  @GPIO(30,31) gbe_ext_mdio */
+	PINCTRL_PIN_GROUP("gbe_ext_mdio", mt7988_gbe_ext_mdio),
+	/*  @GPIO(50,51,52,53,54) i2s */
+	PINCTRL_PIN_GROUP("i2s", mt7988_i2s),
+	/*  @GPIO(50,51,52,53) pcm */
+	PINCTRL_PIN_GROUP("pcm", mt7988_pcm),
+	/*  @GPIO(55,56) uart0 */
+	PINCTRL_PIN_GROUP("uart0", mt7988_uart0),
+	/*  @GPIO(55,56) tops_uart0_2 */
+	PINCTRL_PIN_GROUP("tops_uart0_2", mt7988_tops_uart0_2),
+	/*  @GPIO(50,51,52,53) uart2_2 */
+	PINCTRL_PIN_GROUP("uart2_2", mt7988_uart2_2),
+	/*  @GPIO(50,51,52,53,54) wo0_jtag */
+	PINCTRL_PIN_GROUP("wo0_jtag", mt7988_wo0_jtag),
+	/*  @GPIO(50,51,52,53,54) wo1-wo1_jtag */
+	PINCTRL_PIN_GROUP("wo1_jtag", mt7988_wo1_jtag),
+	/*  @GPIO(50,51,52,53,54) wo2_jtag */
+	PINCTRL_PIN_GROUP("wo2_jtag", mt7988_wo2_jtag),
+	/*  @GPIO(57) pwm0 */
+	PINCTRL_PIN_GROUP("pwm0", mt7988_pwm0),
+	/*  @GPIO(58) pwm2_0 */
+	PINCTRL_PIN_GROUP("pwm2_0", mt7988_pwm2_0),
+	/*  @GPIO(59) pwm3_0 */
+	PINCTRL_PIN_GROUP("pwm3_0", mt7988_pwm3_0),
+	/*  @GPIO(60) pwm4_0 */
+	PINCTRL_PIN_GROUP("pwm4_0", mt7988_pwm4_0),
+	/*  @GPIO(61) pwm5_0 */
+	PINCTRL_PIN_GROUP("pwm5_0", mt7988_pwm5_0),
+	/*  @GPIO(58,59,60,61,62) jtag */
+	PINCTRL_PIN_GROUP("jtag", mt7988_jtag),
+	/*  @GPIO(58,59,60,61,62) tops_jtag0_1 */
+	PINCTRL_PIN_GROUP("tops_jtag0_1", mt7988_tops_jtag0_1),
+	/*  @GPIO(58,59,60,61) uart2_3 */
+	PINCTRL_PIN_GROUP("uart2_3", mt7988_uart2_3),
+	/*  @GPIO(58,59,60,61) uart1_1 */
+	PINCTRL_PIN_GROUP("uart1_1", mt7988_uart1_1),
+	/*  @GPIO(58,59,60,61) gbe_led1 */
+	PINCTRL_PIN_GROUP("gbe0_led1", mt7988_gbe0_led1),
+	PINCTRL_PIN_GROUP("gbe1_led1", mt7988_gbe1_led1),
+	PINCTRL_PIN_GROUP("gbe2_led1", mt7988_gbe2_led1),
+	PINCTRL_PIN_GROUP("gbe3_led1", mt7988_gbe3_led1),
+	/*  @GPIO(62) pwm6_0 */
+	PINCTRL_PIN_GROUP("pwm6_0", mt7988_pwm6_0),
+	/*  @GPIO(62) 2p5gbe_led1 */
+	PINCTRL_PIN_GROUP("2p5gbe_led1", mt7988_2p5gbe_led1),
+	/*  @GPIO(64,65,66,67) gbe_led0 */
+	PINCTRL_PIN_GROUP("gbe0_led0", mt7988_gbe0_led0),
+	PINCTRL_PIN_GROUP("gbe1_led0", mt7988_gbe1_led0),
+	PINCTRL_PIN_GROUP("gbe2_led0", mt7988_gbe2_led0),
+	PINCTRL_PIN_GROUP("gbe3_led0", mt7988_gbe3_led0),
+	/*  @GPIO(68) 2p5gbe_led0 */
+	PINCTRL_PIN_GROUP("2p5gbe_led0", mt7988_2p5gbe_led0),
+	/*  @GPIO(63) drv_vbus_p1 */
+	PINCTRL_PIN_GROUP("drv_vbus_p1", mt7988_drv_vbus_p1),
+	/*  @GPIO(63) pcie_clk_req_n2_1 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n2_1", mt7988_pcie_clk_req_n2_1),
+	/*  @GPIO(69, 70) mdc_mdio1 */
+	PINCTRL_PIN_GROUP("mdc_mdio1", mt7988_mdc_mdio1),
+	/*  @GPIO(69, 70) i2c1_2 */
+	PINCTRL_PIN_GROUP("i2c1_2", mt7988_i2c1_2),
+	/*  @GPIO(69) pwm6 */
+	PINCTRL_PIN_GROUP("pwm6", mt7988_pwm6),
+	/*  @GPIO(70) pwm7 */
+	PINCTRL_PIN_GROUP("pwm7", mt7988_pwm7),
+	/*  @GPIO(69,70) i2c2_0 */
+	PINCTRL_PIN_GROUP("i2c2_0", mt7988_i2c2_0),
+	/*  @GPIO(71,72) i2c2_1 */
+	PINCTRL_PIN_GROUP("i2c2_1", mt7988_i2c2_1),
+	/*  @GPIO(73) pcie_2l_1_pereset */
+	PINCTRL_PIN_GROUP("pcie_2l_1_pereset", mt7988_pcie_2l_1_pereset),
+	/*  @GPIO(74) pcie_1l_0_pereset */
+	PINCTRL_PIN_GROUP("pcie_1l_0_pereset", mt7988_pcie_1l_0_pereset),
+	/*  @GPIO(75) pcie_wake_n1_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n1_0", mt7988_pcie_wake_n1_0),
+	/*  @GPIO(76) pcie_clk_req_n1 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n1", mt7988_pcie_clk_req_n1),
+	/*  @GPIO(77) pcie_wake_n2_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n2_0", mt7988_pcie_wake_n2_0),
+	/*  @GPIO(78) pcie_clk_req_n2_0 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n2_0", mt7988_pcie_clk_req_n2_0),
+	/*  @GPIO(79) drv_vbus */
+	PINCTRL_PIN_GROUP("drv_vbus", mt7988_drv_vbus),
+	/*  @GPIO(79) pcie_wake_n2_1 */
+	PINCTRL_PIN_GROUP("pcie_wake_n2_1", mt7988_pcie_wake_n2_1),
+	/*  @GPIO(80,81,82,83) uart1_2 */
+	PINCTRL_PIN_GROUP("uart1_2", mt7988_uart1_2),
+	/*  @GPIO(80,81) uart1_2_lite */
+	PINCTRL_PIN_GROUP("uart1_2_lite", mt7988_uart1_2_lite),
+	/*  @GPIO(80) pwm2 */
+	PINCTRL_PIN_GROUP("pwm2", mt7988_pwm2),
+	/*  @GPIO(81) pwm3 */
+	PINCTRL_PIN_GROUP("pwm3", mt7988_pwm3),
+	/*  @GPIO(82) pwm4 */
+	PINCTRL_PIN_GROUP("pwm4", mt7988_pwm4),
+	/*  @GPIO(83) pwm5 */
+	PINCTRL_PIN_GROUP("pwm5", mt7988_pwm5),
+	/*  @GPIO(80) net_wo0_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
+	/*  @GPIO(81) net_wo1_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
+	/*  @GPIO(82) net_wo2_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
+	/*  @GPIO(80,81) tops_uart1_2 */
+	PINCTRL_PIN_GROUP("tops_uart1_2", mt7988_tops_uart1_2),
+	/*  @GPIO(80) net_wo0_uart_txd_1 */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7988_net_wo0_uart_txd_1),
+	/*  @GPIO(81) net_wo1_uart_txd_1 */
+	PINCTRL_PIN_GROUP("net_wo1_uart_txd_1", mt7988_net_wo1_uart_txd_1),
+	/*  @GPIO(82) net_wo2_uart_txd_1 */
+	PINCTRL_PIN_GROUP("net_wo2_uart_txd_1", mt7988_net_wo2_uart_txd_1),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+static const char * const mt7988_jtag_groups[] = {
+	"tops_jtag0_0", "wo0_jtag", "wo1_jtag",
+	"wo2_jtag",	"jtag",	    "tops_jtag0_1",
+};
+static const char * const mt7988_int_usxgmii_groups[] = {
+	"int_usxgmii",
+};
+static const char * const mt7988_pwm_groups[] = {
+	"pwm0", "pwm1", "pwm2", "pwm2_0", "pwm3", "pwm3_0", "pwm4", "pwm4_0",
+	"pwm5", "pwm5_0", "pwm6", "pwm6_0", "pwm7", "pwm7_0",
+
+};
+static const char * const mt7988_dfd_groups[] = {
+	"dfd",
+};
+static const char * const mt7988_i2c_groups[] = {
+	"xfi_phy0_i2c0",
+	"xfi_phy1_i2c0",
+	"xfi_phy_pll_i2c0",
+	"xfi_phy_pll_i2c1",
+	"i2c0_0",
+	"i2c1_sfp",
+	"xfi_pextp_phy0_i2c",
+	"xfi_pextp_phy1_i2c",
+	"i2c0_1",
+	"u30_phy_i2c0",
+	"u32_phy_i2c0",
+	"xfi_phy0_i2c1",
+	"xfi_phy1_i2c1",
+	"xfi_phy_pll_i2c2",
+	"i2c1_0",
+	"u30_phy_i2c1",
+	"u32_phy_i2c1",
+	"xfi_phy_pll_i2c3",
+	"sgmii0_i2c",
+	"sgmii1_i2c",
+	"i2c1_2",
+	"i2c2_0",
+	"i2c2_1",
+};
+static const char * const mt7988_ethernet_groups[] = {
+	"mdc_mdio0",
+	"2p5g_ext_mdio",
+	"gbe_ext_mdio",
+	"mdc_mdio1",
+};
+static const char * const mt7988_pcie_groups[] = {
+	"pcie_wake_n0_0",    "pcie_clk_req_n0_0", "pcie_wake_n3_0",
+	"pcie_clk_req_n3",   "pcie_p0_phy_i2c",	  "pcie_p1_phy_i2c",
+	"pcie_p3_phy_i2c",   "pcie_p2_phy_i2c",	  "ckm_phy_i2c",
+	"pcie_wake_n0_1",    "pcie_wake_n3_1",	  "pcie_2l_0_pereset",
+	"pcie_1l_1_pereset", "pcie_clk_req_n2_1", "pcie_2l_1_pereset",
+	"pcie_1l_0_pereset", "pcie_wake_n1_0",	  "pcie_clk_req_n1",
+	"pcie_wake_n2_0",    "pcie_clk_req_n2_0", "pcie_wake_n2_1",
+	"pcie_clk_req_n0_1"
+};
+static const char * const mt7988_pmic_groups[] = {
+	"pmic",
+};
+static const char * const mt7988_wdt_groups[] = {
+	"watchdog",
+};
+static const char * const mt7988_spi_groups[] = {
+	"spi0", "spi0_wp_hold", "spi1", "spi2", "spi2_wp_hold",
+};
+static const char * const mt7988_flash_groups[] = { "emmc_45", "sdcard", "snfi",
+						    "emmc_51" };
+static const char * const mt7988_uart_groups[] = {
+	"uart2",
+	"tops_uart0_0",
+	"uart2_0",
+	"uart1_0",
+	"uart2_1",
+	"net_wo0_uart_txd_0",
+	"net_wo1_uart_txd_0",
+	"net_wo2_uart_txd_0",
+	"tops_uart1_0",
+	"ops_uart0_1",
+	"ops_uart1_1",
+	"uart0",
+	"tops_uart0_2",
+	"uart1_1",
+	"uart2_3",
+	"uart1_2",
+	"uart1_2_lite",
+	"tops_uart1_2",
+	"net_wo0_uart_txd_1",
+	"net_wo1_uart_txd_1",
+	"net_wo2_uart_txd_1",
+};
+static const char * const mt7988_udi_groups[] = {
+	"udi",
+};
+static const char * const mt7988_audio_groups[] = {
+	"i2s", "pcm",
+};
+static const char * const mt7988_led_groups[] = {
+	"gbe0_led1", "gbe1_led1", "gbe2_led1", "gbe3_led1", "2p5gbe_led1",
+	"gbe0_led0", "gbe1_led0", "gbe2_led0", "gbe3_led0", "2p5gbe_led0",
+	"wf5g_led0",   "wf5g_led1",
+};
+static const char * const mt7988_usb_groups[] = {
+	"drv_vbus",
+	"drv_vbus_p1",
+};
+
+static const struct function_desc mt7988_functions[] = {
+	{ { "audio", mt7988_audio_groups, ARRAY_SIZE(mt7988_audio_groups) },
+	  NULL },
+	{ { "jtag", mt7988_jtag_groups, ARRAY_SIZE(mt7988_jtag_groups) },
+	  NULL },
+	{ { "int_usxgmii", mt7988_int_usxgmii_groups,
+	    ARRAY_SIZE(mt7988_int_usxgmii_groups) },
+	  NULL },
+	{ { "pwm", mt7988_pwm_groups, ARRAY_SIZE(mt7988_pwm_groups) }, NULL },
+	{ { "dfd", mt7988_dfd_groups, ARRAY_SIZE(mt7988_dfd_groups) }, NULL },
+	{ { "i2c", mt7988_i2c_groups, ARRAY_SIZE(mt7988_i2c_groups) }, NULL },
+	{ { "eth", mt7988_ethernet_groups, ARRAY_SIZE(mt7988_ethernet_groups) },
+	  NULL },
+	{ { "pcie", mt7988_pcie_groups, ARRAY_SIZE(mt7988_pcie_groups) },
+	  NULL },
+	{ { "pmic", mt7988_pmic_groups, ARRAY_SIZE(mt7988_pmic_groups) },
+	  NULL },
+	{ { "watchdog", mt7988_wdt_groups, ARRAY_SIZE(mt7988_wdt_groups) },
+	  NULL },
+	{ { "spi", mt7988_spi_groups, ARRAY_SIZE(mt7988_spi_groups) }, NULL },
+	{ { "flash", mt7988_flash_groups, ARRAY_SIZE(mt7988_flash_groups) },
+	  NULL },
+	{ { "uart", mt7988_uart_groups, ARRAY_SIZE(mt7988_uart_groups) },
+	  NULL },
+	{ { "udi", mt7988_udi_groups, ARRAY_SIZE(mt7988_udi_groups) }, NULL },
+	{ { "usb", mt7988_usb_groups, ARRAY_SIZE(mt7988_usb_groups) }, NULL },
+	{ { "led", mt7988_led_groups, ARRAY_SIZE(mt7988_led_groups) }, NULL },
+};
+
+static const struct mtk_eint_hw mt7988_eint_hw = {
+	.port_mask = 7,
+	.ports = 7,
+	.ap_num = ARRAY_SIZE(mt7988_pins),
+	.db_cnt = 16,
+};
+
+static const char * const mt7988_pinctrl_register_base_names[] = {
+	"gpio",	 "iocfg_tr", "iocfg_br",
+	"iocfg_rb", "iocfg_lb", "iocfg_tl",
+};
+
+static struct mtk_pin_soc mt7988_data = {
+	.reg_cal = mt7988_reg_cals,
+	.pins = mt7988_pins,
+	.npins = ARRAY_SIZE(mt7988_pins),
+	.grps = mt7988_groups,
+	.ngrps = ARRAY_SIZE(mt7988_groups),
+	.funcs = mt7988_functions,
+	.nfuncs = ARRAY_SIZE(mt7988_functions),
+	.eint_hw = &mt7988_eint_hw,
+	.gpio_m = 0,
+	.ies_present = false,
+	.base_names = mt7988_pinctrl_register_base_names,
+	.nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
+	.bias_disable_set = mtk_pinconf_bias_disable_set,
+	.bias_disable_get = mtk_pinconf_bias_disable_get,
+	.bias_set = mtk_pinconf_bias_set,
+	.bias_get = mtk_pinconf_bias_get,
+	.pull_type = mt7988_pull_type,
+	.bias_set_combo = mtk_pinconf_bias_set_combo,
+	.bias_get_combo = mtk_pinconf_bias_get_combo,
+	.drive_set = mtk_pinconf_drive_set_rev1,
+	.drive_get = mtk_pinconf_drive_get_rev1,
+	.adv_pull_get = mtk_pinconf_adv_pull_get,
+	.adv_pull_set = mtk_pinconf_adv_pull_set,
+};
+
+static const struct of_device_id mt7988_pinctrl_of_match[] = {
+	{ .compatible = "mediatek,mt7988-pinctrl" },
+	{}
+};
+
+static int mt7988_pinctrl_probe(struct platform_device *pdev)
+{
+	return mtk_moore_pinctrl_probe(pdev, &mt7988_data);
+}
+
+static struct platform_driver mt7988_pinctrl_driver = {
+	.driver = {
+		.name = "mt7988-pinctrl",
+		.of_match_table = mt7988_pinctrl_of_match,
+	},
+	.probe = mt7988_pinctrl_probe,
+};
+
+static int __init mt7988_pinctrl_init(void)
+{
+	return platform_driver_register(&mt7988_pinctrl_driver);
+}
+arch_initcall(mt7988_pinctrl_init);
-- 
2.43.0



From linux at fw-web.de  Mon Dec  9 04:57:39 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon,  9 Dec 2024 13:57:39 +0100
Subject: [PATCH v6 5/5] arm64: dts: mediatek: mt7988a-bpi-r4: Add pinctrl subnodes for bpi-r4
In-Reply-To: <20241209125742.9307-1-linux@fw-web.de>
References: <20241209125742.9307-1-linux@fw-web.de>
Message-ID: <20241209125742.9307-6-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add board specific pinctrl configurations on Bananapi R4.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes in v6:
- fix typo
- start title uppercase
- use bpi-r4 prefix
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 189 ++++++++++++++++++
 1 file changed, 189 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index efc4ad0b08b8..aa2dabc041fd 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -9,3 +9,192 @@ / {
 	model = "Banana Pi BPI-R4";
 	chassis-type = "embedded";
 };
+
+&pio {
+	mdio0_pins: mdio0-pins {
+		mux {
+			function = "eth";
+			groups = "mdc_mdio0";
+		};
+
+		conf {
+			pins = "SMI_0_MDC", "SMI_0_MDIO";
+			drive-strength = <8>;
+		};
+	};
+
+	i2c0_pins: i2c0-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c0_1";
+		};
+	};
+
+	i2c1_pins: i2c1-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_0";
+		};
+	};
+
+	i2c1_sfp_pins: i2c1-sfp-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_sfp";
+		};
+	};
+
+	i2c2_0_pins: i2c2-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c2_0";
+		};
+	};
+
+	i2c2_1_pins: i2c2-g1-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c2_1";
+		};
+	};
+
+	gbe0_led0_pins: gbe0-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe0_led0";
+		};
+	};
+
+	gbe1_led0_pins: gbe1-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe1_led0";
+		};
+	};
+
+	gbe2_led0_pins: gbe2-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe2_led0";
+		};
+	};
+
+	gbe3_led0_pins: gbe3-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe3_led0";
+		};
+	};
+
+	gbe0_led1_pins: gbe0-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe0_led1";
+		};
+	};
+
+	gbe1_led1_pins: gbe1-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe1_led1";
+		};
+	};
+
+	gbe2_led1_pins: gbe2-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe2_led1";
+		};
+	};
+
+	gbe3_led1_pins: gbe3-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe3_led1";
+		};
+	};
+
+	i2p5gbe_led0_pins: 2p5gbe-led0-pins {
+		mux {
+			function = "led";
+			groups = "2p5gbe_led0";
+		};
+	};
+
+	i2p5gbe_led1_pins: 2p5gbe-led1-pins {
+		mux {
+			function = "led";
+			groups = "2p5gbe_led1";
+		};
+	};
+
+	mmc0_pins_emmc_45: mmc0-emmc-45-pins {
+		mux {
+			function = "flash";
+			groups = "emmc_45";
+		};
+	};
+
+	mmc0_pins_emmc_51: mmc0-emmc-51-pins {
+		mux {
+			function = "flash";
+			groups = "emmc_51";
+		};
+	};
+
+	mmc0_pins_sdcard: mmc0-sdcard-pins {
+		mux {
+			function = "flash";
+			groups = "sdcard";
+		};
+	};
+
+	uart0_pins: uart0-pins {
+		mux {
+			function = "uart";
+			groups =  "uart0";
+		};
+	};
+
+	snfi_pins: snfi-pins {
+		mux {
+			function = "flash";
+			groups = "snfi";
+		};
+	};
+
+	spi0_pins: spi0-pins {
+		mux {
+			function = "spi";
+			groups = "spi0";
+		};
+	};
+
+	spi0_flash_pins: spi0-flash-pins {
+		mux {
+			function = "spi";
+			groups = "spi0", "spi0_wp_hold";
+		};
+	};
+
+	spi1_pins: spi1-pins {
+		mux {
+			function = "spi";
+			groups = "spi1";
+		};
+	};
+
+	spi2_pins: spi2-pins {
+		mux {
+			function = "spi";
+			groups = "spi2";
+		};
+	};
+
+	spi2_flash_pins: spi2-flash-pins {
+		mux {
+			function = "spi";
+			groups = "spi2", "spi2_wp_hold";
+		};
+	};
+};
-- 
2.43.0



From m-malladi at ti.com  Mon Dec  9 05:01:15 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Mon, 9 Dec 2024 18:31:15 +0530
Subject: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix firmware load
 sequence.
In-Reply-To: <badf6d7c-85a5-42a4-b834-f5cdbd8ff81f@kernel.org>
References: <20241205082831.777868-1-m-malladi@ti.com>
 <20241205082831.777868-2-m-malladi@ti.com>
 <a86bc0b1-8bb4-477e-b7e1-13921bf47b53@kernel.org>
 <64621290-2488-474d-b2ed-597a1f4ac85f@ti.com>
 <badf6d7c-85a5-42a4-b834-f5cdbd8ff81f@kernel.org>
Message-ID: <b5118fd1-6532-4a5e-b762-2be7dd4d39b1@ti.com>



On 09/12/24 18:09, Roger Quadros wrote:
> 
> 
> On 09/12/2024 12:34, Meghana Malladi wrote:
>>
>>
>> On 05/12/24 18:38, Roger Quadros wrote:
>>> Hi,
>>>
>>> On 05/12/2024 10:28, Meghana Malladi wrote:
>>>> From: MD Danish Anwar <danishanwar at ti.com>
>>>>
>>>> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
>>>> and SLICE1. Currently whenever any ICSSG interface comes up we load the
>>>> respective firmwares to PRU cores and whenever interface goes down, we
>>>> stop the resective cores. Due to this, when SLICE0 goes down while
>>>> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
>>>> stopped. This results in clock jump for SLICE1 interface as the timesync
>>>> related operations are no longer running.
>>>>
>>>> As there are interdependencies between SLICE0 and SLICE1 firmwares,
>>>> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
>>>> ICSSG interface is up. Add new flag in prueth struct to check if all
>>>> firmwares are running.
>>>>
>>>> Use emacs_initialized as reference count to load the firmwares for the
>>>> first and last interface up/down. Moving init_emac_mode and fw_offload_mode
>>>> API outside of icssg_config to icssg_common_start API as they need
>>>> to be called only once per firmware boot.
>>>>
>>>> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
>>>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>>>> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
>>>> ---
>>>>
>>>> Hi all,
>>>>
>>>> This patch is based on net-next tagged next-20241128.
>>>> v2:https://lore.kernel.org/all/20241128122931.2494446-2-m-malladi at ti.com/
>>>>
>>>> * Changes since v2 (v3-v2):
>>>> - error handling in caller function of prueth_emac_common_start()
>>>> - Use prus_running flag check before stopping the firmwares
>>>> Both suggested by Roger Quadros <rogerq at kernel.org>
>>>>
>>>>  ? drivers/net/ethernet/ti/icssg/icssg_config.c |? 45 ++++--
>>>>  ? drivers/net/ethernet/ti/icssg/icssg_config.h |?? 1 +
>>>>  ? drivers/net/ethernet/ti/icssg/icssg_prueth.c | 157 ++++++++++++-------
>>>>  ? drivers/net/ethernet/ti/icssg/icssg_prueth.h |?? 5 +
>>>>  ? 4 files changed, 140 insertions(+), 68 deletions(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
>>>> index 5d2491c2943a..342150756cf7 100644
>>>> --- a/drivers/net/ethernet/ti/icssg/icssg_config.c
>>>> +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
>>>> @@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
>>>>  ????? return 0;
>>>>  ? }
>>>>
>> [ ... ]
>>
>>>> +static int prueth_emac_common_start(struct prueth *prueth)
>>>> +{
>>>> +??? struct prueth_emac *emac;
>>>> +??? int ret = 0;
>>>> +??? int slice;
>>>> +
>>>> +??? if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>>>> +??????? return -EINVAL;
>>>> +
>>>> +??? /* clear SMEM and MSMC settings for all slices */
>>>> +??? memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
>>>> +??? memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
>>>> +
>>>> +??? icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
>>>> +??? icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
>>>> +
>>>> +??? if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>>>> +??????? icssg_init_fw_offload_mode(prueth);
>>>> +??? else
>>>> +??????? icssg_init_emac_mode(prueth);
>>>> +
>>>> +??? for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>>>> +??????? emac = prueth->emac[slice];
>>>> +??????? if (emac) {
>>>> +??????????? ret |= icssg_config(prueth, emac, slice);
>>>> +??????????? if (ret)
>>>> +??????????????? return ret;
>>>> +??????? }
>>>> +??????? ret |= prueth_emac_start(prueth, slice);
>>>> +??? }
>>>
>>> need newline?
>>>
>>
>> Yes I will add it.
>>
>>>> +??? if (!ret)
>>>> +??????? prueth->prus_running = 1;
>>>> +??? else
>>>> +??????? return ret;
>>>> +
>>>> +??? emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>>>> +?????????? prueth->emac[ICSS_SLICE1];
>>>> +??? ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>>>> +??????????????? emac, IEP_DEFAULT_CYCLE_TIME_NS);
>>>> +??? if (ret) {
>>>> +??????? dev_err(prueth->dev, "Failed to initialize IEP module\n");
>>>> +??????? return ret;
>>>> +??? }
>>>> +
>>>> +??? return 0;
>>>> +}
>>>> +
>>>> +static int prueth_emac_common_stop(struct prueth *prueth)
>>>> +{
>>>> +??? struct prueth_emac *emac;
>>>> +??? int slice;
>>>> +
>>>> +??? if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>>>> +??????? return -EINVAL;
>>>> +
>>>> +??? icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
>>>> +??? icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
>>>> +
>>>> +??? for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>>>> +??????? if (prueth->prus_running) {
>>>> +??????????? rproc_shutdown(prueth->txpru[slice]);
>>>> +??????????? rproc_shutdown(prueth->rtu[slice]);
>>>> +??????????? rproc_shutdown(prueth->pru[slice]);
>>>> +??????? }
>>>> +??? }
>>>> +??? prueth->prus_running = 0;
>>>> +
>>>> +??? emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
>>>> +?????????? prueth->emac[ICSS_SLICE1];
>>>> +??? icss_iep_exit(emac->iep);
>>>
>>> if icss_iep_init() failed at prueth_emac_common_start(), we should not be
>>> calling icss_iep_exit(). Maybe you need another flag for iep_init status?
>>>
>>
>> Yes I have thought of it as well. In icss_iep_init() does lot of iep register configuration and in the end it enables iep by setting IEP_CNT_ENABLE bit and ptp_clock_register(). Whereas in icss_iep_exit() it checks for ptp_clock and pps/perout. And calls icss_iep_disable() which again clears IEP_CNT_ENABLE.
>>
>> So I see no harm in calling icss_iep_exit() even if icss_iep_init() as it overwrites the existing configuration only. But if you think this doesn't look good I can definitely add new flag for iep as well. But IMO I think this flag would be redundant, please correct me if I am wrong. So which one sounds better?
> 
> But isn't icss_iep_exit() also calling ptp_clock_unregister()?
> If it is safe to do that even in error condition then it doesn't matter.
> 

It checks for iep->ptp_clock before, only if it is not NULL it will 
unregister, so yeah it is safe.

>>
>>> Is it better to call icss_iep_exit() at the top before icssg_class_disable()?
>>>
>>>> +
>>>> +??? return 0;
>>>> +}
>>>> +
>>>>  ? /* called back by PHY layer if there is change in link state of hw port*/
>>>>  ? static void emac_adjust_link(struct net_device *ndev)
>>>>  ? {
>>>> @@ -369,12 +432,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
>>>>  ? {
>>>>  ????? struct icssg_setclock_desc __iomem *sc_descp;
>>>>  ????? struct prueth_emac *emac = clockops_data;
>>>> +??? struct prueth *prueth = emac->prueth;
>>>>  ????? struct icssg_setclock_desc sc_desc;
>>>>  ????? u64 cyclecount;
>>>>  ????? u32 cycletime;
>>>>  ????? int timeout;
>>>>  ? -??? if (!emac->fw_running)
>>>> +??? if (!prueth->prus_running)
>>>>  ????????? return;
>>>>  ? ????? sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
>>>> @@ -543,23 +607,17 @@ 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;
>>>> +??? struct icssg_flow_cfg __iomem *flow_cfg;
>>>>  ????? 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, false);
>>>>  ????? icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
>>>>  ? ????? /* Notify the stack of the actual queue counts. */
>>>> @@ -597,18 +655,23 @@ static int emac_ndo_open(struct net_device *ndev)
>>>>  ????????? goto cleanup_napi;
>>>>  ????? }
>>>>  ? -??? /* reset and start PRU firmware */
>>>> -??? ret = prueth_emac_start(prueth, emac);
>>>> -??? if (ret)
>>>> -??????? goto free_rx_irq;
>>>> +??? if (!prueth->emacs_initialized) {
>>>> +??????? ret = prueth_emac_common_start(prueth);
>>>> +??????? if (ret)
>>>> +??????????? goto stop;
>>>> +??? }
>>>>  ? -??? icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>>>> +??? flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
>>>> +??? writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
>>>> +??? ret = emac_fdb_flow_id_updated(emac);
>>>>  ? -??? if (!prueth->emacs_initialized) {
>>>> -??????? ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
>>>> -??????????????????? emac, IEP_DEFAULT_CYCLE_TIME_NS);
>>>> +??? if (ret) {
>>>> +??????? netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
>>>> +??????? goto stop;
>>>>  ????? }
>>>>  ? +??? icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
>>>> +
>>>>  ????? ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
>>>>  ???????????????????? IRQF_ONESHOT, dev_name(dev), emac);
>>>>  ????? if (ret)
>>>> @@ -653,8 +716,7 @@ static int emac_ndo_open(struct net_device *ndev)
>>>>  ? free_tx_ts_irq:
>>>>  ????? free_irq(emac->tx_ts_irq, emac);
>>>>  ? stop:
>>>> -??? prueth_emac_stop(emac);
>>>> -free_rx_irq:
>>>> +??? prueth_emac_common_stop(prueth);
>>>>  ????? free_irq(emac->rx_chns.irq[rx_flow], emac);
>>>>  ? cleanup_napi:
>>>>  ????? prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
>>>> @@ -689,8 +751,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>>>>  ????? if (ndev->phydev)
>>>>  ????????? phy_stop(ndev->phydev);
>>>>  ? -??? icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
>>>> -
>>>>  ????? if (emac->prueth->is_hsr_offload_mode)
>>>>  ????????? __dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
>>>>  ????? else
>>>> @@ -728,11 +788,9 @@ static int emac_ndo_stop(struct net_device *ndev)
>>>>  ????? /* Destroying the queued work in ndo_stop() */
>>>>  ????? cancel_delayed_work_sync(&emac->stats_work);
>>>>  ? -??? if (prueth->emacs_initialized == 1)
>>>> -??????? icss_iep_exit(emac->iep);
>>>> -
>>>>  ????? /* stop PRUs */
>>>> -??? prueth_emac_stop(emac);
>>>> +??? if (prueth->emacs_initialized == 1)
>>>> +??????? prueth_emac_common_stop(prueth);
>>>>  ? ????? free_irq(emac->tx_ts_irq, emac);
>>>>  ? @@ -1069,16 +1127,10 @@ static void prueth_emac_restart(struct prueth *prueth)
>>>>  ????? icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
>>>>  ? ????? /* Stop both pru cores for both PRUeth ports*/
>>>> -??? prueth_emac_stop(emac0);
>>>> -??? prueth->emacs_initialized--;
>>>> -??? prueth_emac_stop(emac1);
>>>> -??? prueth->emacs_initialized--;
>>>> +??? prueth_emac_common_stop(prueth);
>>>>  ? ????? /* Start both pru cores for both PRUeth ports */
>>>> -??? prueth_emac_start(prueth, emac0);
>>>> -??? prueth->emacs_initialized++;
>>>> -??? prueth_emac_start(prueth, emac1);
>>>> -??? prueth->emacs_initialized++;
>>>> +??? prueth_emac_common_start(prueth);
>>>
>>> But this can fail? You need to deal with failure condition appropriately.
>>>
>>
>> I haven't added failure conditions for two reasons:
>> - Existing code also didn't have any error checks
>> - This func simply reloads a new firmware, given everything is already working with the old one.
>>
>> I can still handle error cases by changing this func to return int (currently it is void) and caller of the functions should print error and immediately return. Thoughts on this?
> 
> At least an error message somewhere will help to debug later.
> 

Ok sure, I will add it then.

>>
>>>>  ? ????? /* Enable forwarding for both PRUeth ports */
>>>>  ????? icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
>>>> @@ -1413,13 +1465,10 @@ static int prueth_probe(struct platform_device *pdev)
>>>>  ????????? prueth->pa_stats = NULL;
>>>>  ????? }
>>>>  ? -??? if (eth0_node) {
>>>> +??? if (eth0_node || eth1_node) {
>>>>  ????????? ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
>>>>  ????????? if (ret)
>>>>  ????????????? goto put_cores;
>>>> -??? }
>>>> -
>>>> -??? if (eth1_node) {
>>>>  ????????? ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
>>>>  ????????? if (ret)
>>>>  ????????????? goto put_cores;
>>>> @@ -1618,14 +1667,12 @@ static int prueth_probe(struct platform_device *pdev)
>>>>  ????? pruss_put(prueth->pruss);
>>>>  ? ? put_cores:
>>>> -??? if (eth1_node) {
>>>> -??????? prueth_put_cores(prueth, ICSS_SLICE1);
>>>> -??????? of_node_put(eth1_node);
>>>> -??? }
>>>> -
>>>> -??? if (eth0_node) {
>>>> +??? if (eth0_node || eth1_node) {
>>>>  ????????? prueth_put_cores(prueth, ICSS_SLICE0);
>>>>  ????????? of_node_put(eth0_node);
>>>> +
>>>> +??????? prueth_put_cores(prueth, ICSS_SLICE1);
>>>> +??????? of_node_put(eth1_node);
>>>>  ????? }
>>>>  ? ????? return ret;
>>>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>>> index f5c1d473e9f9..b30f2e9a73d8 100644
>>>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>>> @@ -257,6 +257,7 @@ struct icssg_firmwares {
>>>>  ?? * @is_switchmode_supported: indicates platform support for switch mode
>>>>  ?? * @switch_id: ID for mapping switch ports to bridge
>>>>  ?? * @default_vlan: Default VLAN for host
>>>> + * @prus_running: flag to indicate if all pru cores are running
>>>>  ?? */
>>>>  ? struct prueth {
>>>>  ????? struct device *dev;
>>>> @@ -298,6 +299,7 @@ struct prueth {
>>>>  ????? int default_vlan;
>>>>  ????? /** @vtbl_lock: Lock for vtbl in shared memory */
>>>>  ????? spinlock_t vtbl_lock;
>>>> +??? bool prus_running;
>>>
>>> I think you don't need fw_running flag anymore. Could you please remove it
>>> from struct prueth_emac?
>>>
>>
>> This flag is still being used by SR1, for which this patch doesn't apply. So I prefer not touching this flag for the sake of SR1.
> 
> ok let's leave it there then.
> 
>>
>>>>  ? };
>>>>  ? ? struct emac_tx_ts_response {
>>>> @@ -361,6 +363,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
>>>>  ?????????????? enum icssg_port_state_cmd state);
>>>>  ? void icssg_config_set_speed(struct prueth_emac *emac);
>>>>  ? void icssg_config_half_duplex(struct prueth_emac *emac);
>>>> +void icssg_init_emac_mode(struct prueth *prueth);
>>>> +void icssg_init_fw_offload_mode(struct prueth *prueth);
>>>>  ? ? /* Buffer queue helpers */
>>>>  ? int icssg_queue_pop(struct prueth *prueth, u8 queue);
>>>> @@ -377,6 +381,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
>>>>  ???????????????? u8 untag_mask, bool add);
>>>>  ? u16 icssg_get_pvid(struct prueth_emac *emac);
>>>>  ? void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
>>>> +int emac_fdb_flow_id_updated(struct prueth_emac *emac);
>>>>  ? #define prueth_napi_to_tx_chn(pnapi) \
>>>>  ????? container_of(pnapi, struct prueth_tx_chn, napi_tx)
>>>>    
>>>
> 


From etienne.carriere at foss.st.com  Mon Dec  9 04:59:58 2024
From: etienne.carriere at foss.st.com (Etienne CARRIERE - foss)
Date: Mon, 9 Dec 2024 12:59:58 +0000
Subject: [PATCH v2 2/2] firmware: arm_scmi: round rate bisecting in
 discrete rates
In-Reply-To: <Z1bKlOeHJFHpe9ZU@bogus>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-3-etienne.carriere@foss.st.com>,<Z1bKlOeHJFHpe9ZU@bogus>
Message-ID: <ed164b6704ab4086b2fb22ae51658f31@foss.st.com>

Hello Sudeep,

 On Monday, December 9, 2024 11:46 AM, Sudeep Holla wrote: 
> On Tue, Dec 03, 2024 at 06:39:08PM +0100, Etienne Carriere wrote:
> > Implement clock round_rate operation for SCMI clocks that describe a
> > discrete rates list. Bisect into the supported rates when using SCMI
> > message CLOCK_DESCRIBE_RATES to optimize SCMI communication transfers.
> 
> Let me stop here and try to understand the requirement here. So you do
> communicate with the firmware to arrive at this round_rate ? Does the
> list of discreet clock rates changes at the run-time that enables the
> need for it. Or will the initial list just include max and min ?

I don't expect the list to change at run-time. The initial list is
expected to describe all supported rates. But because this list may
be big, I don't think arm_scmi/clock.c driver should store the full list
of all supported rates for each of the SCMI clocks. It would cost to
much memory. Therefore I propose to query it at runtime, when
needed, and bisect to lower the number of required transactions
between the agent and the firmware.

> 
> > Parse the rate list array when the target rate fit in the bounds
> > of the command response for simplicity.
> >
> 
> I don't understand what you mean by this.

I meant here that we bisect into supported rates when communicating
with the firmware but once the firmware response provides list portion
when target rate fits into, we just scan into that array instead of bisecting
into. We could also bisect into that array but it is likely quite small
(<128 byte in existing SCMI transport drivers) and that would add a bit
more code for no much gain IMHO.


> 
> > If so some reason the sequence fails or if the SCMI driver has no
> > round_rate SCMI clock handler, then fallback to the legacy strategy that
> > returned the target rate value.
> >
> 
> Hmm, so we perform some extra dance but we are okay to fallback to default.
> I am more confused.

Here, I propose to preserve the exiting sequence in clk/clk-scmi.c in case
arm_scmi/clock.c does not implement this new round_rate SCMI clock 
operation (it can be the case if these 2 drivers are .ko modules, not
well known built-in drivers).

> 
> > Operation handle scmi_clk_determine_rate() is change to get the effective
> > supported rounded rate when there is no clock re-parenting operation
> > supported. Otherwise, preserve the implementation that assumed any
> > clock rate could be obtained.
> >
> 
> OK, no I think I am getting some idea. Is this case where the parent has
> changed and the describe rates can give a different result at run-time.

This does not deal with whether parent has changed or not. I would expect
the same request sent multiple times to provide the very same result. But
as I said above, I don't think arm_scmi/clock.c should consume a possibly
large array of memory to store all supported rate each of the SCMI clocks
(that describe discrete rates).

An alternate way could be to add an SCMI Clock protocol command in the
spec allowing agent to query a closest supported rate, in 1 shot. Maybe
this new command could return both rounded rate and the SCMI parent
clock needed to reach that rounded rate, better fitting clk_determine_rate()
expectations.

> 
> I need to re-read the part of the spec, but we may need some clarity so
> that this implementation is not vendor specific. I am yet to understand this
> fully. I just need to make sure spec covers this aspect and anything we
> add here is generic solution.
> 
> I would like to avoid this extra query if not required which you seem to
> have made an attempt but I just want to be thorough and make sure that's
> what we need w.r.t the specification.

Sure, I indeed prefer clear and robust implementation in the long term,
being the one I propose here or another one.

Regards,
Etienne

> 
> --
> Regards,
> Sudeep
> 


From broonie at kernel.org  Mon Dec  9 05:03:28 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 9 Dec 2024 13:03:28 +0000
Subject: [PATCH] spi: zynq-qspi: Add check for clk_enable()
In-Reply-To: <20241207014727.3674388-1-zmw12306@gmail.com>
References: <20241207014727.3674388-1-zmw12306@gmail.com>
Message-ID: <8332ff0f-5727-4a6c-b40b-f6da7fd1c0f6@sirena.org.uk>

On Fri, Dec 06, 2024 at 08:47:27PM -0500, Mingwei Zheng wrote:

> -	clk_enable(qspi->refclk);
> -	clk_enable(qspi->pclk);
> +	ret = clk_enable(qspi->refclk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_enable(qspi->pclk);
> +	if (ret)
> +		return ret;

This second check leaks the first enable that 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/20241209/2ba42713/attachment.sig>

From broonie at kernel.org  Mon Dec  9 05:03:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 9 Dec 2024 13:03:53 +0000
Subject: [PATCH] spi: zynq-qspi: Add check for clk_enable()
In-Reply-To: <20241207013258.3615645-1-zmw12306@gmail.com>
References: <20241207013258.3615645-1-zmw12306@gmail.com>
Message-ID: <9de6025d-2173-4b50-aa55-65a6a89d995b@sirena.org.uk>

On Fri, Dec 06, 2024 at 08:32:58PM -0500, Mingwei Zheng wrote:

> -	clk_enable(qspi->refclk);
> -	clk_enable(qspi->pclk);
> +	ret = clk_enable(qspi->refclk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_enable(qspi->pclk);
> +	if (ret)
> +		return ret;

The second check leaks the first enable.
-------------- 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/20241209/68497a03/attachment.sig>

From dmitry.baryshkov at linaro.org  Mon Dec  9 05:08:55 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 9 Dec 2024 15:08:55 +0200
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <3a0512de-bcc0-4253-a8c1-f2e43b5cbfba@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
 <4lvsvo6vsc7bipcgftsq3mzunwxoka3wjqad42ptr37oz77zub@5uarhvjmcxnc>
 <a4a74f96-29cc-4007-9b03-f634b84d9cc2@collabora.com>
 <m7u6xzm2o4dmcjot4xfk6do4slikpsp6gi3uyiuw4d35kunbc5@jyzgkrp4xjwc>
 <3a0512de-bcc0-4253-a8c1-f2e43b5cbfba@collabora.com>
Message-ID: <6snszi7h7444jzrr3r3icbwjmsoxthv4mp73d4crlv4mvhldl7@7dqfq3wuhinh>

On Mon, Dec 09, 2024 at 12:33:57PM +0100, AngeloGioacchino Del Regno wrote:
> Il 05/12/24 20:35, Dmitry Baryshkov ha scritto:
> > On Thu, Dec 05, 2024 at 02:30:51PM +0100, AngeloGioacchino Del Regno wrote:
> > > Il 05/12/24 13:56, Dmitry Baryshkov ha scritto:
> > > > On Thu, Dec 05, 2024 at 12:45:17PM +0100, AngeloGioacchino Del Regno wrote:
> > > > > Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> > > > > found in MediaTek's MT8195, MT8188 SoC and their variants, and
> > > > > including support for display modes up to 4k60 and for HDMI
> > > > > Audio, as per the HDMI 2.0 spec.
> > > > > 
> > > > > HDCP and CEC functionalities are also supported by this hardware,
> > > > > but are not included in this commit and that also poses a slight
> > > > > difference between the V2 and V1 controllers in how they handle
> > > > > Hotplug Detection (HPD).
> > > > > 
> > > > > While the v1 controller was using the CEC controller to check
> > > > > HDMI cable connection and disconnection, in this driver the v2
> > > > > one does not.
> > > > > 
> > > > > This is due to the fact that on parts with v2 designs, like the
> > > > > MT8195 SoC, there is one CEC controller shared between the HDMI
> > > > > Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> > > > > adding support to use the CEC HW to wake up the HDMI controllers
> > > > > it is necessary to have support for one TX, one RX *and* for both
> > > > > at the same time.
> > > > > 
> > > > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > > > > ---
> > > > >    drivers/gpu/drm/mediatek/Kconfig            |    8 +
> > > > >    drivers/gpu/drm/mediatek/Makefile           |    4 +
> > > > >    drivers/gpu/drm/mediatek/mtk_hdmi_common.c  |    5 +
> > > > >    drivers/gpu/drm/mediatek/mtk_hdmi_common.h  |    1 +
> > > > >    drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c  |  403 +++++
> > > > >    drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h |  263 ++++
> > > > >    drivers/gpu/drm/mediatek/mtk_hdmi_v2.c      | 1488 +++++++++++++++++++
> > > > >    7 files changed, 2172 insertions(+)
> > > > >    create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
> > > > >    create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
> > > > >    create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
> > > > > 
> > > 
> > > ..snip..
> > > 
> > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
> > > > > new file mode 100644
> > > > > index 000000000000..05cbfc45be54
> > > > > --- /dev/null
> > > > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
> > > > > @@ -0,0 +1,1488 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0
> > > > > +/*
> > > 
> > > ..snip..
> > > 
> > > > > +static int mtk_hdmi_v2_setup_audio_infoframe(struct mtk_hdmi *hdmi)
> > > > > +{
> > > > > +	struct hdmi_codec_params *params = &hdmi->aud_param.codec_params;
> > > > > +	struct hdmi_audio_infoframe frame;
> > > > > +	u8 buffer[14];
> > > > > +	ssize_t ret;
> > > > > +
> > > > > +	memcpy(&frame, &params->cea, sizeof(frame));
> > > > > +
> > > > > +	ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
> > > > > +	if (ret < 0)
> > > > > +		return ret;
> > > > > +
> > > > > +	mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
> > > > 
> > > > This should be handled via HDMI Connector framework too. There is
> > > > already an interface to set / clear audio infoframes.
> > > > als I have been working on an interface to make HDMI codec
> > > > implementation more generic, see [1]. Your comments are appreciated.
> > > > 
> > > > [1] https://patchwork.freedesktop.org/series/134927/
> > > > 
> > > 
> > > I didn't go for that because I was afraid that your series wouldn't actually
> > > land in the same window as this driver.
> > 
> > There were two points in my comment (sorry for being not explicit
> > enough). One is to point to the HDMI codec infra (and you are right,
> > it's not yet in the mergeable state). Second one is to use
> > drm_atomic_helper_connector_hdmi_update_audio_infoframe() and
> > drm_atomic_helper_connector_hdmi_clear_audio_infoframe() if possible (it
> > might be hard to do it - in fact it being hard kind of forced me to
> > work on the HDMI codec infra).
> > 
> 
> That *is* indeed hard and adding almost unnecessary complications to my submission.
> 
> > > I am at this point puzzled to whether I should add a commit on top of this
> > > submission that switches this driver to using the generic HDMI Codec infra
> > > (which could also be helpful as guidance to others trying to do the same on
> > > other drivers, I guess), or if I should just rebase on top of that.
> > 
> > I'd say, a completely separate patch might be even better, I can then
> > integrate it into the HDMI codec patchset, adding a soft dependency on
> > your series. If for some reason the codec lands earlier than your
> > patchset, the patch can be dropped and reintegrated into your series. Or
> > just committed separately.
> 
> I'd rather get the audio part merged as-is with the old handling at this point...
> 
> As you can see, once your HDMI Codec infra gets in a mergeable state the cleanup
> (or conversion, however you prefer to call it) in this driver will be mostly
> trivial.
> 
> This means that whenever your series is ready to merge, I'll be able to send a
> (single, most probably) commit updating this driver to use the new helpers in a
> jiffy (or two).

SGTM

> 
> > 
> > > I'd rather add a commit on top to mainly avoid risking to delay this driver,
> > > but if you're absolutely certain that you can get your series merged in the
> > > same window as this driver I have *zero* problems in just rebasing on top.
> > > 
> > > Besides...
> > > 
> > > I'll find the time to review your series - I'm sad it didn't land earlier as
> > > I would've written a bit less code otherwise :-)
> > > 
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > 
> > > ..snip..
> > > 
> > > > > +
> > > > > +	/* Enable the controller at attach time for HPD/Pord feedback */
> > > > > +	ret = mtk_hdmi_v2_enable(hdmi);
> > > > > +	if (ret)
> > > > > +		return ret;
> > > > 
> > > > This looks like a hack. Please use .hpd_enable() / .hpd_disable()
> > > > callbacks.
> > > > 
> > > 
> > > ...but there's no way to power on only the HPD - you can either power on
> > > the entire controller, or nothing.
> > > 
> > > I can't call mtk_hdmi_v2_enable/disable() from the HPD callbacks.
> > 
> > Why? Add a powerup refcount if necessary.
> > 
> 
> ...but this means that I still have to keep the mtk_hdmi_v2_enable() call
> here, but I didn't understand the point of this until you made me think
> about...
> 
> > > 
> > > Perhaps the comment should have been
> > > 
> > > "Enable the controller attach time also allows HPD/Pord feedback"?
> > 
> > I think it should still be explicit call from those callbacks. Consider
> > a platform using external GPIO to implement HPD. Then the HDMI
> > controller can stay disabled if it is not necessary.
> 
> ...this case.
> 
> I'm still not sure whether I can actually do what you propose because this
> IP needs another IP (mtk_dpi) to be in a configured state before this one
> gets enabled, or you get a freeze.

This sounds like PM runtime and PM devlink from HDMI to DPI, bringing
DPI up when HDMI is PM-runtime-resumed.

> 
> I'll check - if that's feasible, I'll add the refcounting and will go for
> the hpd_{en,dis}able callbacks.
> 
> > 
> > > 
> > > > > +
> > > > > +	/* Enable Hotplug and Pord pins internal debouncing */
> > > > > +	regmap_set_bits(hdmi->regs, HPD_DDC_CTRL,
> > > > > +			HPD_DDC_HPD_DBNC_EN | HPD_DDC_PORD_DBNC_EN);
> > > > > +
> > > > > +	irq_clear_status_flags(hdmi->irq, IRQ_NOAUTOEN);
> > > > > +	enable_irq(hdmi->irq);
> > > > > +
> > > > > +	/*
> > > > > +	 * Check if any HDMI monitor was connected before probing this driver
> > > > > +	 * and/or attaching the bridge, without debouncing: if so, we want to
> > > > > +	 * notify the DRM so that we start outputting an image ASAP.
> > > > > +	 * Note that calling the ISR thread function will also perform a HW
> > > > > +	 * registers write that enables both the HPD and Pord interrupts.
> > > > > +	 */
> > > > > +	__mtk_hdmi_v2_isr_thread(hdmi);
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > 
> > > ..snip..
> > > 
> > > > > +static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
> > > > > +					  struct drm_bridge_state *old_state)
> > > > > +{
> > > > > +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> > > > > +	struct drm_atomic_state *state = old_state->base.state;
> > > > > +	struct drm_connector_state *conn_state;
> > > > > +	union phy_configure_opts opts = {
> > > > > +		.dp = { .link_rate = hdmi->mode.clock * KILO }
> > > > > +	};
> > > > > +
> > > > > +	/* Retrieve the connector through the atomic state */
> > > > > +	hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
> > > > > +
> > > > > +	conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
> > > > > +	if (WARN_ON(!conn_state))
> > > > > +		return;
> > > > > +
> > > > > +	/*
> > > > > +	 * Preconfigure the HDMI controller and the HDMI PHY at pre_enable
> > > > > +	 * stage to make sure that this IP is ready and clocked before the
> > > > > +	 * mtk_dpi gets powered on and before it enables the output.
> > > > > +	 */
> > > > > +	hdmi->dvi_mode = !hdmi->curr_conn->display_info.is_hdmi;
> > > > 
> > > > Can you access display_info directly instead?
> > > > 
> > > 
> > > Nice catch. Yeah, I should've done that from the beginning. Fixed for v3.
> > > 
> > > > > +	mtk_hdmi_v2_output_set_display_mode(hdmi, &hdmi->mode);
> > > > > +
> > > > > +	/* Reconfigure phy clock link with appropriate rate */
> > > > > +	phy_configure(hdmi->phy, &opts);
> > > > > +
> > > > > +	/* Power on the PHY here to make sure that DPI_HDMI is clocked */
> > > > > +	phy_power_on(hdmi->phy);
> > > > > +
> > > > > +	hdmi->powered = true;
> > > > > +}
> > > > > +
> > > > > +static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
> > > > > +				      struct drm_bridge_state *old_state)
> > > > > +{
> > > > > +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> > > > > +	struct drm_atomic_state *state = old_state->base.state;
> > > > > +	int ret;
> > > > > +
> > > > > +	ret = drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
> > > > > +	if (ret)
> > > > > +		dev_err(hdmi->dev, "Could not update infoframes: %d\n", ret);
> > > > > +
> > > > > +	mtk_hdmi_v2_hw_vid_mute(hdmi, false);
> > > > > +	mtk_hdmi_v2_hw_aud_mute(hdmi, false);
> > > > > +
> > > > > +	/* signal the connect event to audio codec */
> > > > > +	mtk_hdmi_v2_handle_plugged_change(hdmi, true);
> > > > 
> > > > I think it was agreed that this should be called from the hotplug path,
> > > > see the (linked) HDMI codec infrastructure patchset and dicussions for
> > > > the previous revisions.
> > > > 
> > > 
> > > Okay, I'll check that out.
> > > 
> > > > > +
> > > > > +	hdmi->enabled = true;
> > > > > +}
> > > > > +
> > > 
> > > ..snip..
> > > 
> > > > > +
> > > > > +static int mtk_hdmi_v2_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> > > > > +						 const struct drm_display_mode *mode,
> > > > > +						 unsigned long long tmds_rate)
> > > > > +{
> > > > > +	if (mode->clock < MTK_HDMI_V2_CLOCK_MIN)
> > > > > +		return MODE_CLOCK_LOW;
> > > > > +	else if (mode->clock > MTK_HDMI_V2_CLOCK_MAX)
> > > > > +		return MODE_CLOCK_HIGH;
> > > > > +	else
> > > > > +		return MODE_OK;
> > > > > +}
> > > > > +
> > > > > +static enum drm_mode_status
> > > > > +mtk_hdmi_v2_bridge_mode_valid(struct drm_bridge *bridge,
> > > > > +			      const struct drm_display_info *info,
> > > > > +			      const struct drm_display_mode *mode)
> > > > > +{
> > > > > +	unsigned long long rate;
> > > > > +
> > > > > +	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
> > > > > +	return mtk_hdmi_v2_hdmi_tmds_char_rate_valid(bridge, mode, rate);
> > > > > +}
> > > > 
> > > > Please rebase on top of https://patchwork.freedesktop.org/series/140193/
> > > > There should be no need to do this manually.
> > > > 
> > > 
> > > Oh finally there's a helper for this. Cool, will rebase! Thanks!
> > 
> > And it doesn't even add an extra dependency for you.
> > 
> 
> ... Which is even cool-er, yes :-)
> 
> > > 
> > > > > +
> > > > > +static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge,
> > > > > +					    enum hdmi_infoframe_type type)
> > > > > +{
> > > > > +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> > > > > +	u32 reg_start, reg_end;
> > > > > +
> > > > > +	switch (type) {
> > > > > +	case HDMI_INFOFRAME_TYPE_AUDIO:
> > > > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
> > > > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
> > > > > +		reg_start = TOP_AIF_HEADER;
> > > > > +		reg_end = TOP_AIF_PKT03;
> > > > > +		break;
> > > > > +	case HDMI_INFOFRAME_TYPE_AVI:
> > > > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
> > > > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
> > > > > +		reg_start = TOP_AVI_HEADER;
> > > > > +		reg_end = TOP_AVI_PKT05;
> > > > > +		break;
> > > > > +	case HDMI_INFOFRAME_TYPE_SPD:
> > > > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
> > > > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
> > > > > +		reg_start = TOP_SPDIF_HEADER;
> > > > > +		reg_end = TOP_SPDIF_PKT07;
> > > > > +		break;
> > > > > +	case HDMI_INFOFRAME_TYPE_VENDOR:
> > > > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
> > > > > +		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
> > > > > +		reg_start = TOP_VSIF_HEADER;
> > > > > +		reg_end = TOP_VSIF_PKT07;
> > > > > +		break;
> > > > > +	case HDMI_INFOFRAME_TYPE_DRM:
> > > > > +	default:
> > > > > +		return 0;
> > > > > +	};
> > > > > +
> > > > > +	for (; reg_start <= reg_end; reg_start += 4)
> > > > > +		regmap_write(hdmi->regs, reg_start, 0);
> > > > 
> > > > Interesting. Usually sending of the infoframe is controlled by a
> > > > register of a kind.
> > > > 
> > > 
> > > "This callback clears the infoframes in the hardware during commit"
> > > 
> > > ...and that's exactly what this function does: clears the infoframes
> > > in the HW and stops the RPT, making the HW ready for the "next round".
> > > 
> > > Did I get the documentation wrong?
> > > Should this function *send* an all-zero infoframe to the external display?
> > 
> > No, it should stop sending the callback. My point was that usually there
> > is a separate register which controls the infoframes. You code just
> > clears the header (which probably is handled as disabling in the IP
> > core).
> > 
> 
> No, my code is clearing everything, not just the header.
> 
> The registers in this IP are sequential, I'm setting the code to start writing
> at HEADER, and stop writing at PKTxx, where PKTxx registers contain the infoframe.
> 
> In any case, disabling in the IP core is managed by clearing the _EN and _EN_WR
> (where WR means "Write", and RPT_EN is "repeat write") bits in the xxx_INFO_EN
> register(s), and that's what I'm doing at the beginning, before actually cleaning
> the infoframe registers.
> 
> Actually, I could've just cleared the EN bits and that would've been enough, but
> I wanted to leave the IP in a clean+known state and decided to zero out the entire
> infoframe header/data register set.
> 
> ....but anyway, what you just said before me explaining how this IP works means
> that I got it right, and that this function does exactly what it is supposed to do.

I'd say, clearing just the EN/EN_WR/RPT_EN is enough - this is what
other drivers do.

> 
> 
> Cheers!
> Angelo
> 
> > > 
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > > +static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge,
> > > > > +					    enum hdmi_infoframe_type type,
> > > > > +					    const u8 *buffer, size_t len)
> > > > > +{
> > > > > +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> > > > > +
> > > > > +	switch (type) {
> > > > > +	case HDMI_INFOFRAME_TYPE_AUDIO:
> > > > > +		mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
> > > > > +		break;
> > > > > +	case HDMI_INFOFRAME_TYPE_AVI:
> > > > > +		mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer);
> > > > > +		break;
> > > > > +	case HDMI_INFOFRAME_TYPE_SPD:
> > > > > +		mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer);
> > > > > +		break;
> > > > > +	case HDMI_INFOFRAME_TYPE_VENDOR:
> > > > > +		mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer);
> > > > > +		break;
> > > > > +	case HDMI_INFOFRAME_TYPE_DRM:
> > > > > +	default:
> > > > > +		dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type);
> > > > > +		break;
> > > > > +	};
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > > +static int mtk_hdmi_v2_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)
> > > > > +{
> > > > > +	return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
> > > > > +						      conn_state->state);
> > > > > +}
> > > > 
> > > > Note to myself, probably we can move this to drm_bridge_connector too.
> > > > 
> > > > > +
> > > > > +static int mtk_hdmi_v2_set_abist(struct mtk_hdmi *hdmi, bool enable)
> > > > > +{
> > > > > +	struct drm_display_mode *mode = &hdmi->mode;
> > > > > +	int abist_format = -EINVAL;
> > > > > +	bool interlaced;
> > > > > +
> > > > > +	if (!enable) {
> > > > > +		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
> > > > > +		return 0;
> > > > > +	}
> > > > > +
> > > > > +	if (!mode->hdisplay || !mode->vdisplay)
> > > > > +		return -EINVAL;
> > > > > +
> > > > > +	interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
> > > > 
> > > > The interlaced modes should be filtered, unless you also set
> > > > bridge->interlace_allowed to true.
> > > > 
> > > 
> > > Noted. Many Thanks for the review!
> > > 
> > > I'll wait until next week for more feedback before sending a v3.
> > 
> 
> 
> -- 
> AngeloGioacchino Del Regno
> Senior Software Engineer
> 
> Collabora Ltd.
> Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
> Registered in England & Wales, no. 5513718

-- 
With best wishes
Dmitry


From shawnguo2 at yeah.net  Mon Dec  9 04:29:29 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 20:29:29 +0800
Subject: [PATCH] arm64: dts: freescale: Remove unused and undocumented
 "cooling-(min|max)-state" properties
In-Reply-To: <20241115193504.3619533-1-robh@kernel.org>
References: <20241115193504.3619533-1-robh@kernel.org>
Message-ID: <Z1biqf24yH6HCl8Y@dragon>

On Fri, Nov 15, 2024 at 01:35:03PM -0600, Rob Herring (Arm) wrote:
> Remove "cooling-(min|max)-state" properties which are both unused in the
> kernel and undocumented. Most likely they are leftovers from downstream.
> 
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>

A similar change from Frank [1] was applied, thanks!

Shawn

[1] https://lore.kernel.org/lkml/20241007220542.897605-1-Frank.Li at nxp.com/

> ---
>  .../boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts   | 2 --
>  arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi             | 2 --
>  2 files changed, 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts
> index d9fac647f432..1d53b529af88 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts
> @@ -19,8 +19,6 @@ / {
>  
>  	pwm-fan {
>  		compatible = "pwm-fan";
> -		cooling-min-state = <0>;
> -		cooling-max-state = <3>;
>  		#cooling-cells = <2>;
>  		pwms = <&sl28cpld_pwm0 0 4000000>;
>  		cooling-levels = <1 128 192 255>;
> diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
> index d32a52ab00a4..aef63a4f698c 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
> +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
> @@ -94,8 +94,6 @@ i2c at 1 {
>  			fan-temperature-ctrlr at 18 {
>  				compatible = "ti,amc6821";
>  				reg = <0x18>;
> -				cooling-min-state = <0>;
> -				cooling-max-state = <9>;
>  				#cooling-cells = <2>;
>  			};
>  		};
> -- 
> 2.45.2
> 



From andyshrk at 163.com  Mon Dec  9 04:29:20 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:20 +0800
Subject: [PATCH v5 07/18] drm/rockchip: vop2: Check linear format for Cluster windows on rk3566/8
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-11-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The Cluster windows on rk3566/8 only support afbc mode.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>

---

Changes in v5:
- Added in V5

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index d7ddeec27c7d..bd8db45eeba6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1165,6 +1165,7 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
 	struct vop2_video_port *vp;
 	struct vop2 *vop2;
 	const struct vop2_data *vop2_data;
+	struct vop2_win *win;
 	struct drm_rect *dest = &pstate->dst;
 	struct drm_rect *src = &pstate->src;
 	int min_scale = FRAC_16_16(1, 8);
@@ -1178,6 +1179,7 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
 	vp = to_vop2_video_port(crtc);
 	vop2 = vp->vop2;
 	vop2_data = vop2->data;
+	win = to_vop2_win(plane);
 
 	cstate = drm_atomic_get_existing_crtc_state(pstate->state, crtc);
 	if (WARN_ON(!cstate))
@@ -1215,6 +1217,16 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
 		return -EINVAL;
 	}
 
+	if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
+		if (vop2_cluster_window(win)) {
+			if (!rockchip_afbc(plane, fb->modifier)) {
+				drm_err(vop2->drm, "Unsupported linear format for %s\n", win->data->name);
+				return -EINVAL;
+			}
+		}
+
+	}
+
 	/*
 	 * Src.x1 can be odd when do clip, but yuv plane start point
 	 * need align with 2 pixel.
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:12 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:12 +0800
Subject: [PATCH] arm64: dts: rockchip: Enable HDMI display for rk3588 Cool Pi GenBook
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-3-andyshrk@163.com>

Enable hdmi display output on Cool Pi GenBook.

Signed-off-by: Andy Yan <andyshrk at 163.com>
Link: https://lore.kernel.org/r/20241028123503.384866-4-andyshrk at 163.com
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 .../rockchip/rk3588-coolpi-cm5-genbook.dts    | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
index 6418286efe40d..9ec2374c6cdfa 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include <dt-bindings/leds/common.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include "rk3588-coolpi-cm5.dtsi"
 
 / {
@@ -35,6 +36,17 @@ charger: dc-charger {
 		gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
 	};
 
+	hdmi-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi0_out_con>;
+			};
+		};
+	};
+
 	leds: leds {
 		compatible = "gpio-leds";
 
@@ -136,6 +148,28 @@ vcc5v0_usb_host0: vcc5v0_usb30_host: vcc5v0-usb-host-regulator {
 	};
 };
 
+/* HDMI CEC is not used */
+&hdmi0 {
+	pinctrl-0 = <&hdmim0_tx0_hpd &hdmim0_tx0_scl &hdmim0_tx0_sda>;
+	status = "okay";
+};
+
+&hdmi0_in {
+	hdmi0_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi0>;
+	};
+};
+
+&hdmi0_out {
+	hdmi0_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&hdptxphy_hdmi0 {
+	status = "okay";
+};
+
 &i2c4 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -347,3 +381,18 @@ &usb_host1_xhci {
 	dr_mode = "host";
 	status = "okay";
 };
+
+&vop {
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
+
+&vp0 {
+	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi0_in_vp0>;
+	};
+};
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:11 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:11 +0800
Subject: [PATCH] arm64: dts: rockchip: Add vop for rk3576
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-2-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 70 +++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index 70ddedb0c890..45823a758b6e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -393,6 +393,11 @@ opp-950000000 {
 		};
 	};
 
+	display_subsystem: display-subsystem {
+		compatible = "rockchip,display-subsystem";
+		ports = <&vop_out>;
+	};
+
 	firmware {
 		scmi: scmi {
 			compatible = "arm,scmi-smc";
@@ -832,6 +837,70 @@ gpu: gpu at 27800000 {
 			status = "disabled";
 		};
 
+		vop: vop at 27d00000 {
+			compatible = "rockchip,rk3576-vop";
+			reg = <0x0 0x27d00000 0x0 0x3000>, <0x0 0x27d05000 0x0 0x1000>;
+			reg-names = "vop", "gamma-lut";
+			interrupts = <GIC_SPI 342 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>;
+			interrupt-names = "vop-sys",
+					  "vop-vp0",
+					  "vop-vp1",
+					  "vop-vp2";
+			clocks = <&cru ACLK_VOP>,
+				 <&cru HCLK_VOP>,
+				 <&cru DCLK_VP0>,
+				 <&cru DCLK_VP1>,
+				 <&cru DCLK_VP2>;
+			clock-names = "aclk",
+				      "hclk",
+				      "dclk_vp0",
+				      "dclk_vp1",
+				      "dclk_vp2";
+			iommus = <&vop_mmu>;
+			power-domains = <&power RK3576_PD_VOP>;
+			rockchip,grf = <&sys_grf>;
+			rockchip,pmu = <&pmu>;
+			status = "disabled";
+
+			vop_out: ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				vp0: port at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				vp1: port at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				vp2: port at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+			};
+		};
+
+		vop_mmu: iommu at 27d07e00 {
+			compatible = "rockchip,rk3576-iommu", "rockchip,rk3568-iommu";
+			reg = <0x0 0x27d07e00 0x0 0x100>, <0x0 0x27d07f00 0x0 0x100>;
+			interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "vop_mmu";
+			clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+			clock-names = "aclk", "iface";
+			#iommu-cells = <0>;
+			power-domains = <&power RK3576_PD_VOP>;
+			status = "disabled";
+		};
+
 		hdmi: hdmi at 27da0000 {
 			compatible = "rockchip,rk3576-dw-hdmi-qp";
 			reg = <0x0 0x27da0000 0x0 0x20000>;
@@ -873,7 +942,6 @@ hdmi_out: port at 1 {
 			};
 		};
 
->>>>>>> 2b62c69b3a4c (arm64: dts: rockchip: Add hdmi for rk3576)
 		qos_hdcp1: qos at 27f02000 {
 			compatible = "rockchip,rk3576-qos", "syscon";
 			reg = <0x0 0x27f02000 0x0 0x20>;
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:10 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:10 +0800
Subject: [PATCH v5 00/18] VOP Support for rk3576
Message-ID: <20241209122943.2781431-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Thanks for the basic work from Collabora, I can bringup a HDMI
display out on rk3576.

PATCH 1 is a carryover from the working when add support for
    rk3588[0], is very usefull when some people want me
    help debug some issue online, so I really hope it can
    be merged at this round.
PATCH 2~8 are bugfix of rk3588 alpha blending which report and
    test by Derek
PATCH 9~13 are preparations for rk3576 support
PATCH 17~18 are real support for rk376

I test it with a 1080P/4K HDMI output with modetest and weston
output.

If there are some one want to have a try, I have a tree based on Linux
6.13-rc2 here[1]

[0]https://patchwork.kernel.org/project/linux-rockchip/cover/20231211115547.1784587-1-andyshrk at 163.com/
[1]https://github.com/andyshrk/linux/tree/rk3576-vop2-upstream-v5

Changes in v5:
- Add axi id configuration for rk3588/rk3576
- More plane format check
- Remove the non-existent CBCR scale register.

Changes in v4:
- Typo fix: selet->select

Changes in v3:
- Split it from 10/15, as it fix a exiting compile warning.
- Add comments for why we should treat rk3566 with special care.
- Add hardware version check
- Add comments for why we should treat rk3566 with special care.
- ordered by soc name
- Add description for newly added interrupt
- Share the alpha setup function with rk3568
- recoder the code block by soc

Changes in v2:
- split it from main patch add support for rk3576
- Add platform specific callback
- Introduce vop hardware version
- Add dt bindings
- Add platform specific callback

Andy Yan (17):
  drm/rockchip: vop2: Add debugfs support
  drm/rockchip: vop2: Fix cluster windows alpha ctrl regsiters offset
  drm/rockchip: vop2: Fix the mixer alpha setup for layer 0
  drm/rockchip: vop2: Fix the windows switch between different layers
  drm/rockchip: vop2: Set AXI id for rk3588
  drm/rockchip: vop2: Setup delay cycle for Esmart2/3
  drm/rockchip: vop2: Check linear format for Cluster windows on
    rk3566/8
  drm/rockchip: vop2: Add check for 32 bpp format
  drm/rockchip: vop2: Support 32x8 superblock afbc
  drm/rockchip: vop2: Add platform specific callback
  drm/rockchip: vop2: Support for different layer select configuration
    between VPs
  drm/rockchip: vop2: Introduce vop hardware version
  drm/rockchip: vop2: Register the primary plane and overlay plane
    separately
  drm/rockchip: vop2: Set plane possible crtcs by possible vp mask
  drm/rockchip: vop2: Add uv swap for cluster window
  dt-bindings: display: vop2: Add rk3576 support
  drm/rockchip: vop2: Add support for rk3576

Min-Hua Chen (1):
  drm/rockchip: vop2: include rockchip_drm_drv.h

 .../display/rockchip/rockchip-vop2.yaml       |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  | 1617 ++++---------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h  |  292 ++-
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c  | 2014 ++++++++++++++++-
 4 files changed, 2794 insertions(+), 1142 deletions(-)

-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:14 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:14 +0800
Subject: [PATCH] drm/rockchip: vop2: Setup delay cycle for Esmart2/3
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-5-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Each layer needs to set the correct delay cycle to display properly
without unexpected offset on screen.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index c3a572b1c8704..7dc8be7d61184 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2526,9 +2526,11 @@ static void vop2_setup_dly_for_windows(struct vop2 *vop2)
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART0:
+		case ROCKCHIP_VOP2_ESMART2:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART3:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
 			break;
 		}
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:15 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:15 +0800
Subject: [PATCH v5 02/18] drm/rockchip: vop2: Fix cluster windows alpha ctrl regsiters offset
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-6-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The phy_id of cluster windws are not increase one for each window.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Tested-by: Derek Foreman <derek.foreman at collabora.com>
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index d1169aa8ff5e..d0b2b881ff07 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2370,7 +2370,6 @@ static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
 
 static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
 {
-	u32 offset = (main_win->data->phys_id * 0x10);
 	struct vop2_alpha_config alpha_config;
 	struct vop2_alpha alpha;
 	struct drm_plane_state *bottom_win_pstate;
@@ -2378,6 +2377,7 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi
 	u16 src_glb_alpha_val, dst_glb_alpha_val;
 	bool premulti_en = false;
 	bool swap = false;
+	u32 offset = 0;
 
 	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
 	bottom_win_pstate = main_win->base.state;
@@ -2396,6 +2396,22 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi
 	vop2_parse_alpha(&alpha_config, &alpha);
 
 	alpha.src_color_ctrl.bits.src_dst_swap = swap;
+
+	switch (main_win->data->phys_id) {
+	case ROCKCHIP_VOP2_CLUSTER0:
+		offset = 0x0;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER1:
+		offset = 0x10;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER2:
+		offset = 0x20;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER3:
+		offset = 0x30;
+		break;
+	}
+
 	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
 		    alpha.src_color_ctrl.val);
 	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:17 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:17 +0800
Subject: [PATCH v5 04/18] drm/rockchip: vop2: Fix the windows switch between different layers
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-8-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Every layer of vop2 should bind a window, and we also need to make
sure that this window is not used by other layer.

0x5 is a reserved layer sel value on rk3568, but it will select
Cluster3 on rk3588, configure unused layers to 0x5  will lead
alpha blending error on rk3588.

When we bind a window from layerM to layerN, we move the old window
on layerN to layerM.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Tested-by: Derek Foreman <derek.foreman at collabora.com>
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 38 +++++++++++++++-----
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 1f0fa153c62e..dc4edd65bc9e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2541,7 +2541,9 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
 	struct drm_plane *plane;
 	u32 layer_sel = 0;
 	u32 port_sel;
-	unsigned int nlayer, ofs;
+	u8 old_layer_id;
+	u8 layer_sel_id;
+	unsigned int ofs;
 	u32 ovl_ctrl;
 	int i;
 	struct vop2_video_port *vp0 = &vop2->vps[0];
@@ -2585,9 +2587,28 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
 	for (i = 0; i < vp->id; i++)
 		ofs += vop2->vps[i].nlayers;
 
-	nlayer = 0;
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
 		struct vop2_win *win = to_vop2_win(plane);
+		struct vop2_win *old_win;
+
+		/*
+		 * Find the layer this win bind in old state.
+		 */
+		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
+			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
+			if (layer_sel_id == win->data->layer_sel_id)
+				break;
+		}
+
+		/*
+		 * Find the win bind to this layer in old state
+		 */
+		for (i = 0; i < vop2->data->win_size; i++) {
+			old_win = &vop2->win[i];
+			layer_sel_id = (layer_sel >> (4 * (plane->state->normalized_zpos + ofs))) & 0xf;
+			if (layer_sel_id == old_win->data->layer_sel_id)
+				break;
+		}
 
 		switch (win->data->phys_id) {
 		case ROCKCHIP_VOP2_CLUSTER0:
@@ -2636,13 +2657,12 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
 							  0x7);
 		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
 							 win->data->layer_sel_id);
-		nlayer++;
-	}
-
-	/* configure unused layers to 0x5 (reserved) */
-	for (; nlayer < vp->nlayers; nlayer++) {
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 5);
+		/*
+		 * When we bind a window from layerM to layerN, we also need to move the old
+		 * window on layerN to layerM to avoid one window selected by two or more layers.
+		 */
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
 	}
 
 	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:19 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:19 +0800
Subject: [PATCH v5 06/18] drm/rockchip: vop2: Setup delay cycle for Esmart2/3
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-10-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Each layer needs to set the correct delay cycle to display properly
without unexpected offset on screen.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 8b9ca046eeeb..d7ddeec27c7d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2703,9 +2703,11 @@ static void vop2_setup_dly_for_windows(struct vop2 *vop2)
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART0:
+		case ROCKCHIP_VOP2_ESMART2:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART3:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
 			break;
 		}
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:13 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:13 +0800
Subject: [PATCH v5 01/18] drm/rockchip: vop2: Add debugfs support
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-4-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

/sys/kernel/debug/dri/vop2/summary:  dump vop display state
/sys/kernel/debug/dri/vop2/regs: dump whole vop registers
/sys/kernel/debug/dri/vop2/active_regs: only dump the registers of
activated modules

Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 260 +++++++++++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  11 +
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 191 ++++++++++++++
 3 files changed, 462 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0c8ec7220fbe..d1169aa8ff5e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -24,9 +24,11 @@
 #include <drm/drm_atomic_uapi.h>
 #include <drm/drm_blend.h>
 #include <drm/drm_crtc.h>
+#include <linux/debugfs.h>
 #include <drm/drm_debugfs.h>
 #include <drm/drm_flip_work.h>
 #include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
@@ -186,6 +188,7 @@ struct vop2 {
 	 */
 	u32 registered_num_wins;
 
+	struct resource *res;
 	void __iomem *regs;
 	struct regmap *map;
 
@@ -237,6 +240,37 @@ struct vop2 {
 
 #define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
 
+
+/*
+ * bus-format types.
+ */
+struct drm_bus_format_enum_list {
+	int type;
+	const char *name;
+};
+
+static const struct drm_bus_format_enum_list drm_bus_format_enum_list[] = {
+	{ DRM_MODE_CONNECTOR_Unknown, "Unknown" },
+	{ MEDIA_BUS_FMT_RGB565_1X16, "RGB565_1X16" },
+	{ MEDIA_BUS_FMT_RGB666_1X18, "RGB666_1X18" },
+	{ MEDIA_BUS_FMT_RGB666_1X24_CPADHI, "RGB666_1X24_CPADHI" },
+	{ MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, "RGB666_1X7X3_SPWG" },
+	{ MEDIA_BUS_FMT_YUV8_1X24, "YUV8_1X24" },
+	{ MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
+	{ MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
+	{ MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
+	{ MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
+	{ MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
+	{ MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, "RGB888_1X7X4_SPWG" },
+	{ MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, "RGB888_1X7X4_JEIDA" },
+	{ MEDIA_BUS_FMT_UYVY8_2X8, "UYVY8_2X8" },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, "YUYV8_1X16" },
+	{ MEDIA_BUS_FMT_UYVY8_1X16, "UYVY8_1X16" },
+	{ MEDIA_BUS_FMT_RGB101010_1X30, "RGB101010_1X30" },
+	{ MEDIA_BUS_FMT_YUYV10_1X20, "YUYV10_1X20" },
+};
+static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
+
 static const struct regmap_config vop2_regmap_config;
 
 static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
@@ -2696,6 +2730,230 @@ static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
 	.atomic_disable = vop2_crtc_atomic_disable,
 };
 
+static void vop2_dump_connector_on_crtc(struct drm_crtc *crtc, struct seq_file *s)
+{
+	struct drm_connector_list_iter conn_iter;
+	struct drm_connector *connector;
+
+	drm_connector_list_iter_begin(crtc->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
+		if (crtc->state->connector_mask & drm_connector_mask(connector))
+			seq_printf(s, "    Connector: %s\n", connector->name);
+
+	}
+	drm_connector_list_iter_end(&conn_iter);
+}
+
+static int vop2_plane_state_dump(struct seq_file *s, struct drm_plane *plane)
+{
+	struct vop2_win *win = to_vop2_win(plane);
+	struct drm_plane_state *pstate = plane->state;
+	struct drm_rect *src, *dst;
+	struct drm_framebuffer *fb;
+	struct drm_gem_object *obj;
+	struct rockchip_gem_object *rk_obj;
+	bool xmirror;
+	bool ymirror;
+	bool rotate_270;
+	bool rotate_90;
+	dma_addr_t fb_addr;
+	int i;
+
+	seq_printf(s, "    %s: %s\n", win->data->name, !pstate ?
+		   "DISABLED" : pstate->crtc ? "ACTIVE" : "DISABLED");
+
+	if (!pstate || !pstate->fb)
+		return 0;
+
+	fb = pstate->fb;
+	src = &pstate->src;
+	dst = &pstate->dst;
+	xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
+	ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
+	rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
+	rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
+
+	seq_printf(s, "\twin_id: %d\n", win->win_id);
+
+	seq_printf(s, "\tformat: %p4cc%s glb_alpha[0x%x]\n",
+		   &fb->format->format,
+		   drm_is_afbc(fb->modifier) ? "[AFBC]" : "",
+		   pstate->alpha >> 8);
+	seq_printf(s, "\trotate: xmirror: %d ymirror: %d rotate_90: %d rotate_270: %d\n",
+		   xmirror, ymirror, rotate_90, rotate_270);
+	seq_printf(s, "\tzpos: %d\n", pstate->normalized_zpos);
+	seq_printf(s, "\tsrc: pos[%d, %d] rect[%d x %d]\n", src->x1 >> 16,
+		   src->y1 >> 16, drm_rect_width(src) >> 16,
+		   drm_rect_height(src) >> 16);
+	seq_printf(s, "\tdst: pos[%d, %d] rect[%d x %d]\n", dst->x1, dst->y1,
+		   drm_rect_width(dst), drm_rect_height(dst));
+
+	for (i = 0; i < fb->format->num_planes; i++) {
+		obj = fb->obj[i];
+		rk_obj = to_rockchip_obj(obj);
+		fb_addr = rk_obj->dma_addr + fb->offsets[i];
+
+		seq_printf(s, "\tbuf[%d]: addr: %pad pitch: %d offset: %d\n",
+			   i, &fb_addr, fb->pitches[i], fb->offsets[i]);
+	}
+
+	return 0;
+}
+
+static int vop2_crtc_state_dump(struct drm_crtc *crtc, struct seq_file *s)
+{
+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct drm_crtc_state *cstate = crtc->state;
+	struct rockchip_crtc_state *vcstate;
+	struct drm_display_mode *mode;
+	struct drm_plane *plane;
+	bool interlaced;
+
+	seq_printf(s, "Video Port%d: %s\n", vp->id, !cstate ?
+		   "DISABLED" : cstate->active ? "ACTIVE" : "DISABLED");
+
+	if (!cstate || !cstate->active)
+		return 0;
+
+	mode = &crtc->state->adjusted_mode;
+	vcstate = to_rockchip_crtc_state(cstate);
+	interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+
+	vop2_dump_connector_on_crtc(crtc, s);
+	seq_printf(s, "\tbus_format[%x]: %s\n", vcstate->bus_format,
+		    drm_get_bus_format_name(vcstate->bus_format));
+	seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode);
+	seq_printf(s, " color_space[%d]\n", vcstate->color_space);
+	seq_printf(s, "    Display mode: %dx%d%s%d\n",
+		    mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
+		    drm_mode_vrefresh(mode));
+	seq_printf(s, "\tclk[%d] real_clk[%d] type[%x] flag[%x]\n",
+		    mode->clock, mode->crtc_clock, mode->type, mode->flags);
+	seq_printf(s, "\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
+		    mode->hsync_end, mode->htotal);
+	seq_printf(s, "\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
+		    mode->vsync_end, mode->vtotal);
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		vop2_plane_state_dump(s, plane);
+	}
+
+	return 0;
+}
+
+static int vop2_summary_show(struct seq_file *s, void *data)
+{
+	struct drm_info_node *node = s->private;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *drm_dev = minor->dev;
+	struct drm_crtc *crtc;
+
+	drm_modeset_lock_all(drm_dev);
+	drm_for_each_crtc(crtc, drm_dev) {
+		vop2_crtc_state_dump(crtc, s);
+	}
+	drm_modeset_unlock_all(drm_dev);
+
+	return 0;
+}
+
+static void vop2_regs_print(struct vop2 *vop2, struct seq_file *s,
+			    const struct vop2_regs_dump *dump, bool active_only)
+{
+	resource_size_t start;
+	u32 val;
+	int i;
+
+	if (dump->en_mask && active_only) {
+		val = vop2_readl(vop2, dump->base + dump->en_reg);
+		if ((val & dump->en_mask) != dump->en_val)
+			return;
+	}
+
+	seq_printf(s, "\n%s:\n", dump->name);
+
+	start = vop2->res->start + dump->base;
+	for (i = 0; i < dump->size >> 2; i += 4) {
+		seq_printf(s, "%08x:  %08x %08x %08x %08x\n", (u32)start + i * 4,
+			   vop2_readl(vop2, dump->base + (4 * i)),
+			   vop2_readl(vop2, dump->base + (4 * (i + 1))),
+			   vop2_readl(vop2, dump->base + (4 * (i + 2))),
+			   vop2_readl(vop2, dump->base + (4 * (i + 3))));
+	}
+}
+
+static void __vop2_regs_dump(struct seq_file *s, bool active_only)
+{
+	struct drm_info_node *node = s->private;
+	struct vop2 *vop2 = node->info_ent->data;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *drm_dev = minor->dev;
+	const struct vop2_regs_dump *dump;
+	unsigned int i;
+
+	drm_modeset_lock_all(drm_dev);
+
+	regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
+
+	if (vop2->enable_count) {
+		for (i = 0; i < vop2->data->regs_dump_size; i++) {
+			dump = &vop2->data->regs_dump[i];
+			vop2_regs_print(vop2, s, dump, active_only);
+		}
+	} else {
+		seq_printf(s, "VOP disabled\n");
+	}
+	drm_modeset_unlock_all(drm_dev);
+
+}
+
+static int vop2_regs_show(struct seq_file *s, void *arg)
+{
+	__vop2_regs_dump(s, false);
+
+	return 0;
+}
+
+static int vop2_active_regs_show(struct seq_file *s, void *data)
+{
+	__vop2_regs_dump(s, true);
+
+	return 0;
+}
+
+static struct drm_info_list vop2_debugfs_list[] = {
+	{ "summary", vop2_summary_show, 0, NULL },
+	{ "active_regs", vop2_active_regs_show,   0, NULL },
+	{ "regs", vop2_regs_show,   0, NULL },
+};
+
+static void vop2_debugfs_init(struct vop2 *vop2, struct drm_minor *minor)
+{
+	struct dentry *root;
+	unsigned int i;
+
+	root = debugfs_create_dir("vop2", minor->debugfs_root);
+	if (!IS_ERR(root)) {
+		for (i = 0; i < ARRAY_SIZE(vop2_debugfs_list); i++)
+			vop2_debugfs_list[i].data = vop2;
+
+		drm_debugfs_create_files(vop2_debugfs_list,
+					 ARRAY_SIZE(vop2_debugfs_list),
+					 root, minor);
+	}
+}
+
+static int vop2_crtc_late_register(struct drm_crtc *crtc)
+{
+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct vop2 *vop2 = vp->vop2;
+
+	if (drm_crtc_index(crtc) == 0)
+		vop2_debugfs_init(vop2, crtc->dev->primary);
+
+	return 0;
+}
+
 static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc)
 {
 	struct rockchip_crtc_state *vcstate;
@@ -2745,6 +3003,7 @@ static const struct drm_crtc_funcs vop2_crtc_funcs = {
 	.atomic_destroy_state = vop2_crtc_destroy_state,
 	.enable_vblank = vop2_crtc_enable_vblank,
 	.disable_vblank = vop2_crtc_disable_vblank,
+	.late_register = vop2_crtc_late_register,
 };
 
 static irqreturn_t vop2_isr(int irq, void *data)
@@ -3294,6 +3553,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 		return -EINVAL;
 	}
 
+	vop2->res = res;
 	vop2->regs = devm_ioremap_resource(dev, res);
 	if (IS_ERR(vop2->regs))
 		return PTR_ERR(vop2->regs);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 510dda6f9092..8786c2ba48df 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -122,6 +122,15 @@ enum vop2_win_regs {
 	VOP2_WIN_MAX_REG,
 };
 
+struct vop2_regs_dump {
+	const char *name;
+	u32 base;
+	u32 size;
+	u32 en_reg;
+	u32 en_val;
+	u32 en_mask;
+};
+
 struct vop2_win_data {
 	const char *name;
 	unsigned int phys_id;
@@ -160,10 +169,12 @@ struct vop2_data {
 	u64 feature;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
+	const struct vop2_regs_dump *regs_dump;
 	struct vop_rect max_input;
 	struct vop_rect max_output;
 
 	unsigned int win_size;
+	unsigned int regs_dump_size;
 	unsigned int soc_id;
 };
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index f9d87a0abc8b..f7d3350594fa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -258,6 +258,88 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	},
 };
 
+static const struct vop2_regs_dump rk3568_regs_dump[] = {
+	{
+		.name = "SYS",
+		.base = RK3568_REG_CFG_DONE,
+		.size = 0x100,
+		.en_reg  = 0,
+		.en_val = 0,
+		.en_mask = 0
+	}, {
+		.name = "OVL",
+		.base = RK3568_OVL_CTRL,
+		.size = 0x100,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "VP0",
+		.base = RK3568_VP0_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP1",
+		.base = RK3568_VP1_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP2",
+		.base = RK3568_VP2_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+
+	}, {
+		.name = "Cluster0",
+		.base = RK3568_CLUSTER0_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster1",
+		.base = RK3568_CLUSTER1_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Esmart0",
+		.base = RK3568_ESMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart1",
+		.base = RK3568_ESMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart0",
+		.base = RK3568_SMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart1",
+		.base = RK3568_SMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	},
+};
+
 static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -438,6 +520,109 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	},
 };
 
+static const struct vop2_regs_dump rk3588_regs_dump[] = {
+	{
+		.name = "SYS",
+		.base = RK3568_REG_CFG_DONE,
+		.size = 0x100,
+		.en_reg  = 0,
+		.en_val = 0,
+		.en_mask = 0
+	}, {
+		.name = "OVL",
+		.base = RK3568_OVL_CTRL,
+		.size = 0x100,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "VP0",
+		.base = RK3568_VP0_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP1",
+		.base = RK3568_VP1_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP2",
+		.base = RK3568_VP2_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+
+	}, {
+		.name = "VP3",
+		.base = RK3588_VP3_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "Cluster0",
+		.base = RK3568_CLUSTER0_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster1",
+		.base = RK3568_CLUSTER1_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster2",
+		.base = RK3588_CLUSTER2_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster3",
+		.base = RK3588_CLUSTER3_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Esmart0",
+		.base = RK3568_ESMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart1",
+		.base = RK3568_ESMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart2",
+		.base = RK3588_ESMART2_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart3",
+		.base = RK3588_ESMART3_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	},
+};
+
 static const struct vop2_data rk3566_vop = {
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
@@ -446,6 +631,8 @@ static const struct vop2_data rk3566_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.regs_dump = rk3568_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
 	.soc_id = 3566,
 };
 
@@ -457,6 +644,8 @@ static const struct vop2_data rk3568_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.regs_dump = rk3568_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
 	.soc_id = 3568,
 };
 
@@ -469,6 +658,8 @@ static const struct vop2_data rk3588_vop = {
 	.vp = rk3588_vop_video_ports,
 	.win = rk3588_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
+	.regs_dump = rk3588_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
 	.soc_id = 3588,
 };
 
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:16 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:16 +0800
Subject: [PATCH v5 03/18] drm/rockchip: vop2: Fix the mixer alpha setup for layer 0
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-7-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The alpha setup should start from the second layer, the current calculation
starts incorrectly from the first layer, a negative offset will be obtained
in the following formula:

offset = (mixer_id + zpos - 1) * 0x10

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Tested-by: Derek Foreman <derek.foreman at collabora.com>
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index d0b2b881ff07..1f0fa153c62e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2459,6 +2459,12 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 		struct vop2_win *win = to_vop2_win(plane);
 		int zpos = plane->state->normalized_zpos;
 
+		/*
+		 * Need to configure alpha from second layer.
+		 */
+		if (zpos == 0)
+			continue;
+
 		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
 			premulti_en = 1;
 		else
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:29:18 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:29:18 +0800
Subject: [PATCH v5 05/18] drm/rockchip: vop2: Set AXI id for rk3588
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209122943.2781431-9-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

There are two AXI bus in vop2, windows attached on the same bus must
have a unique channel YUV and RGB channel ID.

The default IDs will conflict with each other on the rk3588, so they
need to be reassigned.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Derek Foreman <derek.foreman at collabora.com>

---

Changes in v5:
- Added in V5

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 14 +++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  9 +++++++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 26 +++++++++++++++++++-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index dc4edd65bc9e..8b9ca046eeeb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1426,6 +1426,12 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		&fb->format->format,
 		afbc_en ? "AFBC" : "", &yrgb_mst);
 
+	if (vop2->data->soc_id > 3568) {
+		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
+		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
+		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
+	}
+
 	if (vop2_cluster_window(win))
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
@@ -3354,6 +3360,10 @@ static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
 	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
 	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
+	/* RK3588 only, reserved bit on rk3568*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
 
 	/* Scale */
 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
@@ -3446,6 +3456,10 @@ static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
 	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
 	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	/* RK3588 only, reserved register on rk3568 */
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
 
 	/* Scale */
 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 8786c2ba48df..0a3b22e8d14e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -78,6 +78,9 @@ enum vop2_win_regs {
 	VOP2_WIN_COLOR_KEY,
 	VOP2_WIN_COLOR_KEY_EN,
 	VOP2_WIN_DITHER_UP,
+	VOP2_WIN_AXI_BUS_ID,
+	VOP2_WIN_AXI_YRGB_R_ID,
+	VOP2_WIN_AXI_UV_R_ID,
 
 	/* scale regs */
 	VOP2_WIN_SCALE_YRGB_X,
@@ -149,6 +152,10 @@ struct vop2_win_data {
 	unsigned int layer_sel_id;
 	uint64_t feature;
 
+	uint8_t axi_bus_id;
+	uint8_t axi_yrgb_r_id;
+	uint8_t axi_uv_r_id;
+
 	unsigned int max_upscale_factor;
 	unsigned int max_downscale_factor;
 	const u8 dly[VOP2_DLY_MODE_MAX];
@@ -319,6 +326,7 @@ enum dst_factor_mode {
 
 #define RK3568_CLUSTER_WIN_CTRL0		0x00
 #define RK3568_CLUSTER_WIN_CTRL1		0x04
+#define RK3568_CLUSTER_WIN_CTRL2		0x08
 #define RK3568_CLUSTER_WIN_YRGB_MST		0x10
 #define RK3568_CLUSTER_WIN_CBR_MST		0x14
 #define RK3568_CLUSTER_WIN_VIR			0x18
@@ -341,6 +349,7 @@ enum dst_factor_mode {
 /* (E)smart register definition, offset relative to window base */
 #define RK3568_SMART_CTRL0			0x00
 #define RK3568_SMART_CTRL1			0x04
+#define RK3588_SMART_AXI_CTRL			0x08
 #define RK3568_SMART_REGION0_CTRL		0x10
 #define RK3568_SMART_REGION0_YRGB_MST		0x14
 #define RK3568_SMART_REGION0_CBR_MST		0x18
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index f7d3350594fa..37c65138012d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -395,7 +395,7 @@ static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
  * AXI1 is a read only bus.
  *
  * Every window on a AXI bus must assigned two unique
- * read id(yrgb_id/uv_id, valid id are 0x1~0xe).
+ * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe).
  *
  * AXI0:
  * Cluster0/1, Esmart0/1, WriteBack
@@ -415,6 +415,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 0,
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 2,
+		.axi_uv_r_id = 3,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -431,6 +434,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -446,6 +452,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 2,
+		.axi_uv_r_id = 3,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -461,6 +470,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -475,6 +487,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 2,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -488,6 +503,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 3,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x01,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -501,6 +519,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 6,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -514,6 +535,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 7,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x0d,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
-- 
2.34.1



From shawnguo2 at yeah.net  Mon Dec  9 04:31:58 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 9 Dec 2024 20:31:58 +0800
Subject: [PATCH v6] soc: imx: Add SoC device register for i.MX9
In-Reply-To: <20241118021716.396001-1-alice.guo@oss.nxp.com>
References: <20241118021716.396001-1-alice.guo@oss.nxp.com>
Message-ID: <Z1bjPhQxV34bEZS4@dragon>

On Mon, Nov 18, 2024 at 10:17:16AM +0800, alice.guo at oss.nxp.com wrote:
> From: "alice.guo" <alice.guo at nxp.com>
> 
> i.MX9 SoCs have SoC ID, SoC revision number and chip unique identifier
> which are provided by the corresponding ARM trusted firmware API. This
> patch intends to use SMC call to obtain these information and then
> register i.MX9 SoC as a device.
> 
> Signed-off-by: Alice Guo <alice.guo at nxp.com>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Reviewed-by: Stefan Wahren <wahrenst at gmx.net>

Applied, thanks!



From vincent.mailhol at gmail.com  Mon Dec  9 04:32:14 2024
From: vincent.mailhol at gmail.com (Vincent Mailhol)
Date: Mon, 9 Dec 2024 21:32:14 +0900
Subject: [PATCH 05/10] minmax: simplify __clamp_once() by using is_const_false()
In-Reply-To: <CAMZ6RqJPvbSr5i8N4Dm=2N6D8uSzefCM3TyK8HBNNNrybo5f2Q@mail.gmail.com>
References: <20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr>
 <20241203-is_constexpr-refactor-v1-5-4e4cbaecc216@wanadoo.fr>
 <8b8262389bd6484586007d749132346f@AcuMS.aculab.com> <CAMZ6RqJPvbSr5i8N4Dm=2N6D8uSzefCM3TyK8HBNNNrybo5f2Q@mail.gmail.com>
Message-ID: <CAMZ6RqLMXaAej75eXrLgvt-Co1yyEg0QNJSxPovzLzb7vdxmdQ@mail.gmail.com>

On Fri. 6 Dec. 2024 at 00:52, Vincent Mailhol
<mailhol.vincent at wanadoo.fr> wrote:
> On Thu. 5 Dec. 2024 at 03:54, David Laight <David.Laight at aculab.com> wrote:
> > From: Vincent Mailhol
> > > Sent: 02 December 2024 17:33
> > >
> > > In __clamp_once(),
> > >
> > >   __builtin_choose_expr(__is_constexpr((lo) > (hi)), (lo) <= (hi), true)
> > >
> > > is equivalent to:
> > >
> > >   !is_const_false((lo) <= (hi))
> > >
> > > Apply is_const_false() to simplify __clamp_once().
> >
> > There is already a patch 'for next' that changes it use BUILD_BUG_ON_MSG()
> > and statically_true().
>
> Found it!
>
>   https://lore.kernel.org/all/34d53778977747f19cce2abb287bb3e6 at AcuMS.aculab.com/

I picked up your patch and got two build errors on an allyesconfig.

You already sent a patch for the first one:

  https://lore.kernel.org/all/33893212b1cc4a418cec09aeeed0a9fc at AcuMS.aculab.com/

For the second one, I submitted a patch here:

  https://lore.kernel.org/all/20241209-nfs4state_fix-v1-1-7a66819c60f0 at wanadoo.fr/

I will wait for those two to appear in Andrew's mm tree first, and
only then, I will send a v2 (that will be rebased on the mm tree to
get your change).

Meanwhile, I think this series will be on hiatus.


Yours sincerely,
Vincent Mailhol


From linux at fw-web.de  Mon Dec  9 04:32:27 2024
From: linux at fw-web.de (Frank Wunderlich (linux))
Date: Mon, 09 Dec 2024 13:32:27 +0100
Subject: [PATCH v5 5/5] arm64: dts: mediatek: mt7988: add pinctrl subnodes
 for bpi-r4
In-Reply-To: <9b1a385e-da1c-429b-91b9-d5b5d6d5abb7@collabora.com>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-6-linux@fw-web.de>
 <9b1a385e-da1c-429b-91b9-d5b5d6d5abb7@collabora.com>
Message-ID: <4e0ace7c5a0766395f8801bdd2fcdbf9@fw-web.de>

Am 2024-12-09 12:52, schrieb AngeloGioacchino Del Regno:
> Il 02/12/24 12:00, Frank Wunderlich ha scritto:
>> From: Frank Wunderlich <frank-w at public-files.de>
>> 
>> Add board specidic pinctrl configurations on Bananapi R4.
>> 
>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> 
> Can you change the title as suggested in the review for the other 
> series?
> So that we stay consistent.

already done in my tree (and fixed typo in commit message) ;)

8e566779ee82 arm64: dts: mediatek: mt7988a-bpi-r4: Add pinctrl subnodes 
for bpi-r4

> After which,
> 
> Reviewed-by: AngeloGioacchino Del Regno 
> <angelogioacchino.delregno at collabora.com>

thx

are parts 1+2 now ok?

regards Frank


From andyshrk at 163.com  Mon Dec  9 04:32:12 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:32:12 +0800
Subject: [PATCH v5 08/18] drm/rockchip: vop2: Add check for 32 bpp format
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123215.2781721-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

RK3588 only support DRM_FORMAT_XRGB2101010/XBGR2101010 in afbc mode.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>

---

Changes in v5:
-  Added in V5

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index bd8db45eeba6..1f101a3c3942 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1224,7 +1224,15 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
 				return -EINVAL;
 			}
 		}
+	}
 
+	if (fb->format->format == DRM_FORMAT_XRGB2101010 || fb->format->format == DRM_FORMAT_XBGR2101010) {
+		if (vop2->data->soc_id == 3588) {
+			if (!rockchip_afbc(plane, fb->modifier)) {
+				drm_err(vop2->drm, "Unsupported linear 32 bpp for %s\n", win->data->name);
+				return -EINVAL;
+			}
+		}
 	}
 
 	/*
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:32:24 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:32:24 +0800
Subject: [PATCH v5 09/18] drm/rockchip: vop2: include rockchip_drm_drv.h
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123226.2781765-1-andyshrk@163.com>

From: Min-Hua Chen <minhuadotchen at gmail.com>

Move rockchip_drm_drv.h in rockchip_drm_vop2.h to fix the follow
sparse warning:

ARCH=arm64 LLVM=1 make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
mrproper defconfig all  -j12

drivers/gpu/drm/rockchip/rockchip_vop2_reg.c:502:24: sparse:
warning: symbol 'vop2_platform_driver' was not declared. Should it
be static?

It is also beneficial for the upcoming support for rk3576.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Signed-off-by: Min-Hua Chen <minhuadotchen at gmail.com>

---

(no changes since v3)

Changes in v3:
- Split it from 10/15, as it fix a exiting compile warning.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 1f101a3c3942..106b164343ad 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -35,7 +35,6 @@
 #include <uapi/linux/videodev2.h>
 #include <dt-bindings/soc/rockchip,vop2.h>
 
-#include "rockchip_drm_drv.h"
 #include "rockchip_drm_gem.h"
 #include "rockchip_drm_vop2.h"
 #include "rockchip_rgb.h"
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 0a3b22e8d14e..4cd4d17fe366 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -9,6 +9,7 @@
 
 #include <linux/regmap.h>
 #include <drm/drm_modes.h>
+#include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
 #define VOP2_VP_FEATURE_OUTPUT_10BIT        BIT(0)
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:32:37 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:32:37 +0800
Subject: [PATCH v5 10/18] drm/rockchip: vop2: Support 32x8 superblock afbc
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123239.2781807-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

This is the only afbc format supported by the upcoming
VOP for rk3576.

Add support for it.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v2)

Changes in v2:
- split it from main patch add support for rk3576

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 106b164343ad..5c99eb878a78 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1455,16 +1455,18 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
 	if (afbc_en) {
-		u32 stride;
+		u32 stride, block_w;
+
+		/* the afbc superblock is 16 x 16 or 32 x 8 */
+		block_w = fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ? 32 : 16;
 
-		/* the afbc superblock is 16 x 16 */
 		afbc_format = vop2_convert_afbc_format(fb->format->format);
 
 		/* Enable color transform for YTR */
 		if (fb->modifier & AFBC_FORMAT_MOD_YTR)
 			afbc_format |= (1 << 4);
 
-		afbc_tile_num = ALIGN(actual_w, 16) >> 4;
+		afbc_tile_num = ALIGN(actual_w, block_w) / block_w;
 
 		/*
 		 * AFBC pic_vir_width is count by pixel, this is different
@@ -1475,6 +1477,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 			drm_dbg_kms(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n",
 				    vp->id, win->data->name, stride);
 
+		 /* It's for head stride, each head size is 16 byte */
+		stride = ALIGN(stride, block_w) / block_w * 16;
+
 		uv_swap = vop2_afbc_uv_swap(fb->format->format);
 		/*
 		 * This is a workaround for crazy IC design, Cluster
@@ -1505,7 +1510,11 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1);
 
-		vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
+		if (fb->modifier & AFBC_FORMAT_MOD_SPLIT)
+			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 1);
+		else
+			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
+
 		transform_offset = vop2_afbc_transform_offset(pstate, half_block_en);
 		vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
 		vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:33:04 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:33:04 +0800
Subject: [PATCH v5 11/18] drm/rockchip: vop2: Add platform specific callback
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123305.2781909-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The VOP interface mux, overlay, background delay cycle configuration
of different SOC are much different. Add platform specific callback
ops to let the core driver look cleaner and more refined.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v2)

Changes in v2:
- Add platform specific callback

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1144 +-----------------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  168 +++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c |  992 +++++++++++++++
 3 files changed, 1180 insertions(+), 1124 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 5c99eb878a78..1997a8deada8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -33,7 +33,6 @@
 #include <drm/drm_vblank.h>
 
 #include <uapi/linux/videodev2.h>
-#include <dt-bindings/soc/rockchip,vop2.h>
 
 #include "rockchip_drm_gem.h"
 #include "rockchip_drm_vop2.h"
@@ -102,143 +101,6 @@ enum vop2_afbc_format {
 	VOP2_AFBC_FMT_INVALID = -1,
 };
 
-union vop2_alpha_ctrl {
-	u32 val;
-	struct {
-		/* [0:1] */
-		u32 color_mode:1;
-		u32 alpha_mode:1;
-		/* [2:3] */
-		u32 blend_mode:2;
-		u32 alpha_cal_mode:1;
-		/* [5:7] */
-		u32 factor_mode:3;
-		/* [8:9] */
-		u32 alpha_en:1;
-		u32 src_dst_swap:1;
-		u32 reserved:6;
-		/* [16:23] */
-		u32 glb_alpha:8;
-	} bits;
-};
-
-struct vop2_alpha {
-	union vop2_alpha_ctrl src_color_ctrl;
-	union vop2_alpha_ctrl dst_color_ctrl;
-	union vop2_alpha_ctrl src_alpha_ctrl;
-	union vop2_alpha_ctrl dst_alpha_ctrl;
-};
-
-struct vop2_alpha_config {
-	bool src_premulti_en;
-	bool dst_premulti_en;
-	bool src_pixel_alpha_en;
-	bool dst_pixel_alpha_en;
-	u16 src_glb_alpha_value;
-	u16 dst_glb_alpha_value;
-};
-
-struct vop2_win {
-	struct vop2 *vop2;
-	struct drm_plane base;
-	const struct vop2_win_data *data;
-	struct regmap_field *reg[VOP2_WIN_MAX_REG];
-
-	/**
-	 * @win_id: graphic window id, a cluster may be split into two
-	 * graphics windows.
-	 */
-	u8 win_id;
-	u8 delay;
-	u32 offset;
-
-	enum drm_plane_type type;
-};
-
-struct vop2_video_port {
-	struct drm_crtc crtc;
-	struct vop2 *vop2;
-	struct clk *dclk;
-	unsigned int id;
-	const struct vop2_video_port_data *data;
-
-	struct completion dsp_hold_completion;
-
-	/**
-	 * @win_mask: Bitmask of windows attached to the video port;
-	 */
-	u32 win_mask;
-
-	struct vop2_win *primary_plane;
-	struct drm_pending_vblank_event *event;
-
-	unsigned int nlayers;
-};
-
-struct vop2 {
-	struct device *dev;
-	struct drm_device *drm;
-	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
-
-	const struct vop2_data *data;
-	/*
-	 * Number of windows that are registered as plane, may be less than the
-	 * total number of hardware windows.
-	 */
-	u32 registered_num_wins;
-
-	struct resource *res;
-	void __iomem *regs;
-	struct regmap *map;
-
-	struct regmap *sys_grf;
-	struct regmap *vop_grf;
-	struct regmap *vo1_grf;
-	struct regmap *sys_pmu;
-
-	/* physical map length of vop2 register */
-	u32 len;
-
-	void __iomem *lut_regs;
-
-	/* protects crtc enable/disable */
-	struct mutex vop2_lock;
-
-	int irq;
-
-	/*
-	 * Some global resources are shared between all video ports(crtcs), so
-	 * we need a ref counter here.
-	 */
-	unsigned int enable_count;
-	struct clk *hclk;
-	struct clk *aclk;
-	struct clk *pclk;
-
-	/* optional internal rgb encoder */
-	struct rockchip_rgb *rgb;
-
-	/* must be put at the end of the struct */
-	struct vop2_win win[];
-};
-
-#define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
-					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
-
-#define vop2_output_if_is_dp(x)		((x) == ROCKCHIP_VOP2_EP_DP0 || \
-					 (x) == ROCKCHIP_VOP2_EP_DP1)
-
-#define vop2_output_if_is_edp(x)	((x) == ROCKCHIP_VOP2_EP_EDP0 || \
-					 (x) == ROCKCHIP_VOP2_EP_EDP1)
-
-#define vop2_output_if_is_mipi(x)	((x) == ROCKCHIP_VOP2_EP_MIPI0 || \
-					 (x) == ROCKCHIP_VOP2_EP_MIPI1)
-
-#define vop2_output_if_is_lvds(x)	((x) == ROCKCHIP_VOP2_EP_LVDS0 || \
-					 (x) == ROCKCHIP_VOP2_EP_LVDS1)
-
-#define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
-
 
 /*
  * bus-format types.
@@ -272,15 +134,6 @@ static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
 
 static const struct regmap_config vop2_regmap_config;
 
-static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
-{
-	return container_of(crtc, struct vop2_video_port, crtc);
-}
-
-static struct vop2_win *to_vop2_win(struct drm_plane *p)
-{
-	return container_of(p, struct vop2_win, base);
-}
 
 static void vop2_lock(struct vop2 *vop2)
 {
@@ -292,44 +145,6 @@ static void vop2_unlock(struct vop2 *vop2)
 	mutex_unlock(&vop2->vop2_lock);
 }
 
-static void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
-{
-	regmap_write(vop2->map, offset, v);
-}
-
-static void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
-{
-	regmap_write(vp->vop2->map, vp->data->offset + offset, v);
-}
-
-static u32 vop2_readl(struct vop2 *vop2, u32 offset)
-{
-	u32 val;
-
-	regmap_read(vop2->map, offset, &val);
-
-	return val;
-}
-
-static u32 vop2_vp_read(struct vop2_video_port *vp, u32 offset)
-{
-	u32 val;
-
-	regmap_read(vp->vop2->map, vp->data->offset + offset, &val);
-
-	return val;
-}
-
-static void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
-{
-	regmap_field_write(win->reg[reg], v);
-}
-
-static bool vop2_cluster_window(const struct vop2_win *win)
-{
-	return win->data->feature & WIN_FEATURE_CLUSTER;
-}
-
 /*
  * Note:
  * The write mask function is documented but missing on rk3566/8, writes
@@ -1725,6 +1540,7 @@ static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
 static void vop2_post_config(struct drm_crtc *crtc)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct vop2 *vop2 = vp->vop2;
 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 	u16 vtotal = mode->crtc_vtotal;
 	u16 hdisplay = mode->crtc_hdisplay;
@@ -1735,18 +1551,10 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	u32 top_margin = 100, bottom_margin = 100;
 	u16 hsize = hdisplay * (left_margin + right_margin) / 200;
 	u16 vsize = vdisplay * (top_margin + bottom_margin) / 200;
-	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
 	u16 hact_end, vact_end;
 	u32 val;
-	u32 bg_dly;
-	u32 pre_scan_dly;
-
-	bg_dly = vp->data->pre_scan_max_dly[3];
-	vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
-		    FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
 
-	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
-	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+	vop2->ops->setup_bg_dly(vp);
 
 	vsize = rounddown(vsize, 2);
 	hsize = rounddown(hsize, 2);
@@ -1782,347 +1590,6 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
 }
 
-static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_crtc *crtc = &vp->crtc;
-	u32 die, dip;
-
-	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
-	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
-
-	switch (id) {
-	case ROCKCHIP_VOP2_EP_RGB0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_RGB |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		if (polflags & POLFLAG_DCLK_INV)
-			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
-		else
-			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
-		break;
-	case ROCKCHIP_VOP2_EP_HDMI0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_EDP0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_EDP |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI1:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_LVDS0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_LVDS1:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		break;
-	default:
-		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
-		return 0;
-	}
-
-	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
-
-	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
-	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
-
-	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
-}
-
-/*
- * calc the dclk on rk3588
- * the available div of dclk is 1, 2, 4
- */
-static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
-{
-	if (child_clk * 4 <= max_dclk)
-		return child_clk * 4;
-	else if (child_clk * 2 <= max_dclk)
-		return child_clk * 2;
-	else if (child_clk <= max_dclk)
-		return child_clk;
-	else
-		return 0;
-}
-
-/*
- * 4 pixclk/cycle on rk3588
- * RGB/eDP/HDMI: if_pixclk >= dclk_core
- * DP: dp_pixclk = dclk_out <= dclk_core
- * DSI: mipi_pixclk <= dclk_out <= dclk_core
- */
-static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
-					 int *dclk_core_div, int *dclk_out_div,
-					 int *if_pixclk_div, int *if_dclk_div)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_crtc *crtc = &vp->crtc;
-	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
-	int output_mode = vcstate->output_mode;
-	unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
-	unsigned long dclk_core_rate = v_pixclk >> 2;
-	unsigned long dclk_rate = v_pixclk;
-	unsigned long dclk_out_rate;
-	unsigned long if_pixclk_rate;
-	int K = 1;
-
-	if (vop2_output_if_is_hdmi(id)) {
-		/*
-		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
-		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
-		 */
-		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
-			dclk_rate = dclk_rate >> 1;
-			K = 2;
-		}
-
-		if_pixclk_rate = (dclk_core_rate << 1) / K;
-		/*
-		 * if_dclk_rate = dclk_core_rate / K;
-		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
-		 * *if_dclk_div = dclk_rate / if_dclk_rate;
-		 */
-		*if_pixclk_div = 2;
-		*if_dclk_div = 4;
-	} else if (vop2_output_if_is_edp(id)) {
-		/*
-		 * edp_pixclk = edp_dclk > dclk_core
-		 */
-		if_pixclk_rate = v_pixclk / K;
-		dclk_rate = if_pixclk_rate * K;
-		/*
-		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
-		 * *if_dclk_div = *if_pixclk_div;
-		 */
-		*if_pixclk_div = K;
-		*if_dclk_div = K;
-	} else if (vop2_output_if_is_dp(id)) {
-		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
-			dclk_out_rate = v_pixclk >> 3;
-		else
-			dclk_out_rate = v_pixclk >> 2;
-
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
-		if (!dclk_rate) {
-			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n",
-				dclk_out_rate);
-			return 0;
-		}
-		*dclk_out_div = dclk_rate / dclk_out_rate;
-	} else if (vop2_output_if_is_mipi(id)) {
-		if_pixclk_rate = dclk_core_rate / K;
-		/*
-		 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
-		 */
-		dclk_out_rate = if_pixclk_rate;
-		/*
-		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
-		 * we get a little factor here
-		 */
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
-		if (!dclk_rate) {
-			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n",
-				dclk_out_rate);
-			return 0;
-		}
-		*dclk_out_div = dclk_rate / dclk_out_rate;
-		/*
-		 * mipi pixclk == dclk_out
-		 */
-		*if_pixclk_div = 1;
-	} else if (vop2_output_if_is_dpi(id)) {
-		dclk_rate = v_pixclk;
-	}
-
-	*dclk_core_div = dclk_rate / dclk_core_rate;
-	*if_pixclk_div = ilog2(*if_pixclk_div);
-	*if_dclk_div = ilog2(*if_dclk_div);
-	*dclk_core_div = ilog2(*dclk_core_div);
-	*dclk_out_div = ilog2(*dclk_out_div);
-
-	drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
-		dclk_rate, *if_pixclk_div, *if_dclk_div);
-
-	return dclk_rate;
-}
-
-/*
- * MIPI port mux on rk3588:
- * 0: Video Port2
- * 1: Video Port3
- * 3: Video Port 1(MIPI1 only)
- */
-static u32 rk3588_get_mipi_port_mux(int vp_id)
-{
-	if (vp_id == 1)
-		return 3;
-	else if (vp_id == 3)
-		return 1;
-	else
-		return 0;
-}
-
-static u32 rk3588_get_hdmi_pol(u32 flags)
-{
-	u32 val;
-
-	val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
-	val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
-
-	return val;
-}
-
-static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
-	unsigned long clock;
-	u32 die, dip, div, vp_clk_div, val;
-
-	clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
-				    &if_pixclk_div, &if_dclk_div);
-	if (!clock)
-		return 0;
-
-	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
-	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
-
-	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
-	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
-	div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
-
-	switch (id) {
-	case ROCKCHIP_VOP2_EP_HDMI0:
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
-			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
-		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
-		break;
-	case ROCKCHIP_VOP2_EP_HDMI1:
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
-			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
-		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
-		break;
-	case ROCKCHIP_VOP2_EP_EDP0:
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
-		break;
-	case ROCKCHIP_VOP2_EP_EDP1:
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI0:
-		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
-		val = rk3588_get_mipi_port_mux(vp->id);
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI1:
-		div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		val = rk3588_get_mipi_port_mux(vp->id);
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
-		break;
-	case ROCKCHIP_VOP2_EP_DP0:
-		die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
-		dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
-		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_DP1:
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
-		dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
-		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
-		break;
-	default:
-		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
-		return 0;
-	}
-
-	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
-
-	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
-	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
-	vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
-	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
-
-	return clock;
-}
-
-static unsigned long vop2_set_intf_mux(struct vop2_video_port *vp, int ep_id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-
-	if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568)
-		return rk3568_set_intf_mux(vp, ep_id, polflags);
-	else if (vop2->data->soc_id == 3588)
-		return rk3588_set_intf_mux(vp, ep_id, polflags);
-	else
-		return 0;
-}
-
 static int us_to_vertical_line(struct drm_display_mode *mode, int us)
 {
 	return us * mode->clock / mode->htotal / 1000;
@@ -2195,7 +1662,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
 		 * process multi(1/2/4/8) pixels per cycle, so the dclk feed by the
 		 * system cru may be the 1/2 or 1/4 of mode->clock.
 		 */
-		clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
+		clock = vop2->ops->setup_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
 	}
 
 	if (!clock) {
@@ -2324,453 +1791,13 @@ static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
 	return 0;
 }
 
-static bool is_opaque(u16 alpha)
-{
-	return (alpha >> 8) == 0xff;
-}
-
-static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
-			     struct vop2_alpha *alpha)
-{
-	int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
-	int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
-	int src_color_mode = alpha_config->src_premulti_en ?
-				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
-	int dst_color_mode = alpha_config->dst_premulti_en ?
-				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
-
-	alpha->src_color_ctrl.val = 0;
-	alpha->dst_color_ctrl.val = 0;
-	alpha->src_alpha_ctrl.val = 0;
-	alpha->dst_alpha_ctrl.val = 0;
-
-	if (!alpha_config->src_pixel_alpha_en)
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
-	else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
-	else
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
-
-	alpha->src_color_ctrl.bits.alpha_en = 1;
-
-	if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
-		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
-	} else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
-		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
-	} else {
-		alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
-	}
-	alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
-	alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-
-	alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-	alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
-	alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
-	alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
-	alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
-
-	alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
-	alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-	alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
-
-	alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
-		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
-	else
-		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
-	alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
-	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
-}
-
-static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
-{
-	struct vop2_video_port *vp;
-	int used_layer = 0;
-	int i;
-
-	for (i = 0; i < port_id; i++) {
-		vp = &vop2->vps[i];
-		used_layer += hweight32(vp->win_mask);
-	}
-
-	return used_layer;
-}
-
-static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
-{
-	struct vop2_alpha_config alpha_config;
-	struct vop2_alpha alpha;
-	struct drm_plane_state *bottom_win_pstate;
-	bool src_pixel_alpha_en = false;
-	u16 src_glb_alpha_val, dst_glb_alpha_val;
-	bool premulti_en = false;
-	bool swap = false;
-	u32 offset = 0;
-
-	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
-	bottom_win_pstate = main_win->base.state;
-	src_glb_alpha_val = 0;
-	dst_glb_alpha_val = main_win->base.state->alpha;
-
-	if (!bottom_win_pstate->fb)
-		return;
-
-	alpha_config.src_premulti_en = premulti_en;
-	alpha_config.dst_premulti_en = false;
-	alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
-	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
-	alpha_config.src_glb_alpha_value = src_glb_alpha_val;
-	alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
-	vop2_parse_alpha(&alpha_config, &alpha);
-
-	alpha.src_color_ctrl.bits.src_dst_swap = swap;
-
-	switch (main_win->data->phys_id) {
-	case ROCKCHIP_VOP2_CLUSTER0:
-		offset = 0x0;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER1:
-		offset = 0x10;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER2:
-		offset = 0x20;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER3:
-		offset = 0x30;
-		break;
-	}
-
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
-		    alpha.src_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
-		    alpha.dst_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
-		    alpha.src_alpha_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
-		    alpha.dst_alpha_ctrl.val);
-}
-
-static void vop2_setup_alpha(struct vop2_video_port *vp)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_framebuffer *fb;
-	struct vop2_alpha_config alpha_config;
-	struct vop2_alpha alpha;
-	struct drm_plane *plane;
-	int pixel_alpha_en;
-	int premulti_en, gpremulti_en = 0;
-	int mixer_id;
-	u32 offset;
-	bool bottom_layer_alpha_en = false;
-	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
-
-	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
-	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-
-		if (plane->state->normalized_zpos == 0 &&
-		    !is_opaque(plane->state->alpha) &&
-		    !vop2_cluster_window(win)) {
-			/*
-			 * If bottom layer have global alpha effect [except cluster layer,
-			 * because cluster have deal with bottom layer global alpha value
-			 * at cluster mix], bottom layer mix need deal with global alpha.
-			 */
-			bottom_layer_alpha_en = true;
-			dst_global_alpha = plane->state->alpha;
-		}
-	}
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-		int zpos = plane->state->normalized_zpos;
-
-		/*
-		 * Need to configure alpha from second layer.
-		 */
-		if (zpos == 0)
-			continue;
-
-		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
-			premulti_en = 1;
-		else
-			premulti_en = 0;
-
-		plane = &win->base;
-		fb = plane->state->fb;
-
-		pixel_alpha_en = fb->format->has_alpha;
-
-		alpha_config.src_premulti_en = premulti_en;
-
-		if (bottom_layer_alpha_en && zpos == 1) {
-			gpremulti_en = premulti_en;
-			/* Cd = Cs + (1 - As) * Cd * Agd */
-			alpha_config.dst_premulti_en = false;
-			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
-			alpha_config.src_glb_alpha_value = plane->state->alpha;
-			alpha_config.dst_glb_alpha_value = dst_global_alpha;
-		} else if (vop2_cluster_window(win)) {
-			/* Mix output data only have pixel alpha */
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = true;
-			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-		} else {
-			/* Cd = Cs + (1 - As) * Cd */
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
-			alpha_config.src_glb_alpha_value = plane->state->alpha;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-		}
-
-		vop2_parse_alpha(&alpha_config, &alpha);
-
-		offset = (mixer_id + zpos - 1) * 0x10;
-		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
-			    alpha.src_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
-			    alpha.dst_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
-			    alpha.src_alpha_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
-			    alpha.dst_alpha_ctrl.val);
-	}
-
-	if (vp->id == 0) {
-		if (bottom_layer_alpha_en) {
-			/* Transfer pixel alpha to hdr mix */
-			alpha_config.src_premulti_en = gpremulti_en;
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = true;
-			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			vop2_parse_alpha(&alpha_config, &alpha);
-
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
-				    alpha.src_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
-				    alpha.dst_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
-				    alpha.src_alpha_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
-				    alpha.dst_alpha_ctrl.val);
-		} else {
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
-		}
-	}
-}
-
-static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_plane *plane;
-	u32 layer_sel = 0;
-	u32 port_sel;
-	u8 old_layer_id;
-	u8 layer_sel_id;
-	unsigned int ofs;
-	u32 ovl_ctrl;
-	int i;
-	struct vop2_video_port *vp0 = &vop2->vps[0];
-	struct vop2_video_port *vp1 = &vop2->vps[1];
-	struct vop2_video_port *vp2 = &vop2->vps[2];
-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
-
-	ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
-	ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
-	if (vcstate->yuv_overlay)
-		ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
-	else
-		ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
-
-	vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
-
-	port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
-	port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
-
-	if (vp0->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
-				     vp0->nlayers - 1);
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
-
-	if (vp1->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
-				     (vp0->nlayers + vp1->nlayers - 1));
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
-
-	if (vp2->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
-			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
-
-	layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
-
-	ofs = 0;
-	for (i = 0; i < vp->id; i++)
-		ofs += vop2->vps[i].nlayers;
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-		struct vop2_win *old_win;
-
-		/*
-		 * Find the layer this win bind in old state.
-		 */
-		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
-			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
-			if (layer_sel_id == win->data->layer_sel_id)
-				break;
-		}
-
-		/*
-		 * Find the win bind to this layer in old state
-		 */
-		for (i = 0; i < vop2->data->win_size; i++) {
-			old_win = &vop2->win[i];
-			layer_sel_id = (layer_sel >> (4 * (plane->state->normalized_zpos + ofs))) & 0xf;
-			if (layer_sel_id == old_win->data->layer_sel_id)
-				break;
-		}
-
-		switch (win->data->phys_id) {
-		case ROCKCHIP_VOP2_CLUSTER0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER2:
-			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER3:
-			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART2:
-			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART3:
-			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
-			break;
-		case ROCKCHIP_VOP2_SMART0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_SMART1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
-			break;
-		}
-
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
-							  0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
-							 win->data->layer_sel_id);
-		/*
-		 * When we bind a window from layerM to layerN, we also need to move the old
-		 * window on layerN to layerM to avoid one window selected by two or more layers.
-		 */
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
-	}
-
-	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-	vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
-}
-
-static void vop2_setup_dly_for_windows(struct vop2 *vop2)
-{
-	struct vop2_win *win;
-	int i = 0;
-	u32 cdly = 0, sdly = 0;
-
-	for (i = 0; i < vop2->data->win_size; i++) {
-		u32 dly;
-
-		win = &vop2->win[i];
-		dly = win->delay;
-
-		switch (win->data->phys_id) {
-		case ROCKCHIP_VOP2_CLUSTER0:
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER1:
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
-			break;
-		case ROCKCHIP_VOP2_ESMART0:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
-			break;
-		case ROCKCHIP_VOP2_ESMART1:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
-			break;
-		case ROCKCHIP_VOP2_SMART0:
-		case ROCKCHIP_VOP2_ESMART2:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
-			break;
-		case ROCKCHIP_VOP2_SMART1:
-		case ROCKCHIP_VOP2_ESMART3:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
-			break;
-		}
-	}
-
-	vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
-	vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
-}
-
 static void vop2_crtc_atomic_begin(struct drm_crtc *crtc,
 				   struct drm_atomic_state *state)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
 	struct vop2 *vop2 = vp->vop2;
-	struct drm_plane *plane;
-
-	vp->win_mask = 0;
-
-	drm_atomic_crtc_for_each_plane(plane, crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-
-		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
-
-		vp->win_mask |= BIT(win->data->phys_id);
 
-		if (vop2_cluster_window(win))
-			vop2_setup_cluster_alpha(vop2, win);
-	}
-
-	if (!vp->win_mask)
-		return;
-
-	vop2_setup_layer_mixer(vp);
-	vop2_setup_alpha(vp);
-	vop2_setup_dly_for_windows(vop2);
+	vop2->ops->setup_overlay(vp);
 }
 
 static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
@@ -3374,182 +2401,50 @@ static int vop2_find_rgb_encoder(struct vop2 *vop2)
 	return -ENOENT;
 }
 
-static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
-	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
-	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
-	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
-	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
-	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
-	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
-	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
-	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
-	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
-	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
-	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
-	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
-	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
-	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
-	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
-	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
-	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
-	/* RK3588 only, reserved bit on rk3568*/
-	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
-
-	/* Scale */
-	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
-	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
-	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
-	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
-	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
-	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
-	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
-
-	/* cluster regs */
-	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
-	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
-	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
-
-	/* afbc regs */
-	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
-	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
-	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
-	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
-	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
-	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
-	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
-	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
-	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
-	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
-	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
-	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
-	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
-	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
-	[VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
-	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
-	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
-	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
-	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
-};
-
 static int vop2_cluster_init(struct vop2_win *win)
 {
 	struct vop2 *vop2 = win->vop2;
 	struct reg_field *cluster_regs;
 	int ret, i;
 
-	cluster_regs = kmemdup(vop2_cluster_regs, sizeof(vop2_cluster_regs),
+	cluster_regs = kmemdup(vop2->data->cluster_reg,
+			       sizeof(struct reg_field) * vop2->data->nr_cluster_regs,
 			       GFP_KERNEL);
 	if (!cluster_regs)
 		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(vop2_cluster_regs); i++)
+	for (i = 0; i < vop2->data->nr_cluster_regs; i++)
 		if (cluster_regs[i].reg != 0xffffffff)
 			cluster_regs[i].reg += win->offset;
 
 	ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
 					   cluster_regs,
-					   ARRAY_SIZE(vop2_cluster_regs));
-
+					   vop2->data->nr_cluster_regs);
 	kfree(cluster_regs);
 
 	return ret;
 };
 
-static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
-	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
-	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
-	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
-	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
-	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
-	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
-	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
-	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
-	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
-	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
-	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
-	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
-	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
-	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
-	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
-	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
-	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
-	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
-	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
-	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
-	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
-	/* RK3588 only, reserved register on rk3568 */
-	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
-
-	/* Scale */
-	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
-	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
-	[VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
-	[VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
-	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
-	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
-	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
-	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
-	[VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
-	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
-	[VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
-	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
-	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
-	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
-	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
-	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
-	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
-	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
-	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
-};
-
 static int vop2_esmart_init(struct vop2_win *win)
 {
 	struct vop2 *vop2 = win->vop2;
-	struct reg_field *esmart_regs;
+	struct reg_field *smart_regs;
 	int ret, i;
 
-	esmart_regs = kmemdup(vop2_esmart_regs, sizeof(vop2_esmart_regs),
-			      GFP_KERNEL);
-	if (!esmart_regs)
+	smart_regs = kmemdup(vop2->data->smart_reg,
+			     sizeof(struct reg_field) * vop2->data->nr_smart_regs,
+			     GFP_KERNEL);
+	if (!smart_regs)
 		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(vop2_esmart_regs); i++)
-		if (esmart_regs[i].reg != 0xffffffff)
-			esmart_regs[i].reg += win->offset;
+	for (i = 0; i < vop2->data->nr_smart_regs; i++)
+		if (smart_regs[i].reg != 0xffffffff)
+			smart_regs[i].reg += win->offset;
 
 	ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
-					   esmart_regs,
-					   ARRAY_SIZE(vop2_esmart_regs));
-
-	kfree(esmart_regs);
+					   smart_regs,
+					   vop2->data->nr_smart_regs);
+	kfree(smart_regs);
 
 	return ret;
 };
@@ -3629,6 +2524,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 
 	vop2->dev = dev;
 	vop2->data = vop2_data;
+	vop2->ops = vop2_data->ops;
 	vop2->drm = drm;
 
 	dev_set_drvdata(dev, vop2);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 4cd4d17fe366..a867e154801a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -9,6 +9,7 @@
 
 #include <linux/regmap.h>
 #include <drm/drm_modes.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
@@ -58,6 +59,23 @@ enum vop2_scale_down_mode {
 #define VOP2_PD_DSC_4K		BIT(6)
 #define VOP2_PD_ESMART		BIT(7)
 
+#define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
+					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
+
+#define vop2_output_if_is_dp(x)		((x) == ROCKCHIP_VOP2_EP_DP0 || \
+					 (x) == ROCKCHIP_VOP2_EP_DP1)
+
+#define vop2_output_if_is_edp(x)	((x) == ROCKCHIP_VOP2_EP_EDP0 || \
+					 (x) == ROCKCHIP_VOP2_EP_EDP1)
+
+#define vop2_output_if_is_mipi(x)	((x) == ROCKCHIP_VOP2_EP_MIPI0 || \
+					 (x) == ROCKCHIP_VOP2_EP_MIPI1)
+
+#define vop2_output_if_is_lvds(x)	((x) == ROCKCHIP_VOP2_EP_LVDS0 || \
+					 (x) == ROCKCHIP_VOP2_EP_LVDS1)
+
+#define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
+
 enum vop2_win_regs {
 	VOP2_WIN_ENABLE,
 	VOP2_WIN_FORMAT,
@@ -162,6 +180,23 @@ struct vop2_win_data {
 	const u8 dly[VOP2_DLY_MODE_MAX];
 };
 
+struct vop2_win {
+	struct vop2 *vop2;
+	struct drm_plane base;
+	const struct vop2_win_data *data;
+	struct regmap_field *reg[VOP2_WIN_MAX_REG];
+
+	/**
+	 * @win_id: graphic window id, a cluster may be split into two
+	 * graphics windows.
+	 */
+	u8 win_id;
+	u8 delay;
+	u32 offset;
+
+	enum drm_plane_type type;
+};
+
 struct vop2_video_port_data {
 	unsigned int id;
 	u32 feature;
@@ -172,20 +207,105 @@ struct vop2_video_port_data {
 	unsigned int offset;
 };
 
+struct vop2_video_port {
+	struct drm_crtc crtc;
+	struct vop2 *vop2;
+	struct clk *dclk;
+	unsigned int id;
+	const struct vop2_video_port_data *data;
+
+	struct completion dsp_hold_completion;
+
+	/**
+	 * @win_mask: Bitmask of windows attached to the video port;
+	 */
+	u32 win_mask;
+
+	struct vop2_win *primary_plane;
+	struct drm_pending_vblank_event *event;
+
+	unsigned int nlayers;
+};
+
+/**
+ * struct vop2_ops - helper operations for vop2 hardware
+ *
+ * These hooks are used by the common part of the vop2 driver to
+ * implement the proper behaviour of different variants.
+ */
+struct vop2_ops {
+	unsigned long (*setup_intf_mux)(struct vop2_video_port *vp, int ep_id, u32 polflags);
+	void (*setup_bg_dly)(struct vop2_video_port *vp);
+	void (*setup_overlay)(struct vop2_video_port *vp);
+};
+
 struct vop2_data {
 	u8 nr_vps;
 	u64 feature;
+	const struct vop2_ops *ops;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
+	const struct reg_field *cluster_reg;
+	const struct reg_field *smart_reg;
 	const struct vop2_regs_dump *regs_dump;
 	struct vop_rect max_input;
 	struct vop_rect max_output;
 
+	unsigned int nr_cluster_regs;
+	unsigned int nr_smart_regs;
 	unsigned int win_size;
 	unsigned int regs_dump_size;
 	unsigned int soc_id;
 };
 
+struct vop2 {
+	struct device *dev;
+	struct drm_device *drm;
+	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
+
+	const struct vop2_data *data;
+	const struct vop2_ops *ops;
+	/*
+	 * Number of windows that are registered as plane, may be less than the
+	 * total number of hardware windows.
+	 */
+	u32 registered_num_wins;
+
+	struct resource *res;
+	void __iomem *regs;
+	struct regmap *map;
+
+	struct regmap *sys_grf;
+	struct regmap *vop_grf;
+	struct regmap *vo1_grf;
+	struct regmap *sys_pmu;
+
+	/* physical map length of vop2 register */
+	u32 len;
+
+	void __iomem *lut_regs;
+
+	/* protects crtc enable/disable */
+	struct mutex vop2_lock;
+
+	int irq;
+
+	/*
+	 * Some global resources are shared between all video ports(crtcs), so
+	 * we need a ref counter here.
+	 */
+	unsigned int enable_count;
+	struct clk *hclk;
+	struct clk *aclk;
+	struct clk *pclk;
+
+	/* optional internal rgb encoder */
+	struct rockchip_rgb *rgb;
+
+	/* must be put at the end of the struct */
+	struct vop2_win win[];
+};
+
 /* interrupt define */
 #define FS_NEW_INTR			BIT(4)
 #define ADDR_SAME_INTR			BIT(5)
@@ -560,4 +680,52 @@ enum vop2_layer_phy_id {
 
 extern const struct component_ops vop2_component_ops;
 
+static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
+{
+	regmap_write(vop2->map, offset, v);
+}
+
+static inline void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
+{
+	regmap_write(vp->vop2->map, vp->data->offset + offset, v);
+}
+
+static inline u32 vop2_readl(struct vop2 *vop2, u32 offset)
+{
+	u32 val;
+
+	regmap_read(vop2->map, offset, &val);
+
+	return val;
+}
+
+static inline u32 vop2_vp_read(struct vop2_video_port *vp, u32 offset)
+{
+	u32 val;
+
+	regmap_read(vp->vop2->map, vp->data->offset + offset, &val);
+
+	return val;
+}
+
+static inline void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
+{
+	regmap_field_write(win->reg[reg], v);
+}
+
+static inline bool vop2_cluster_window(const struct vop2_win *win)
+{
+	return win->data->feature & WIN_FEATURE_CLUSTER;
+}
+
+static inline struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct vop2_video_port, crtc);
+}
+
+static inline struct vop2_win *to_vop2_win(struct drm_plane *p)
+{
+	return container_of(p, struct vop2_win, base);
+}
+
 #endif /* _ROCKCHIP_DRM_VOP2_H */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 37c65138012d..0cff1327c38e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -9,12 +9,50 @@
 #include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
+#include <drm/drm_blend.h>
 #include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
 #include <drm/drm_plane.h>
 #include <drm/drm_print.h>
 
 #include "rockchip_drm_vop2.h"
 
+union vop2_alpha_ctrl {
+	u32 val;
+	struct {
+		/* [0:1] */
+		u32 color_mode:1;
+		u32 alpha_mode:1;
+		/* [2:3] */
+		u32 blend_mode:2;
+		u32 alpha_cal_mode:1;
+		/* [5:7] */
+		u32 factor_mode:3;
+		/* [8:9] */
+		u32 alpha_en:1;
+		u32 src_dst_swap:1;
+		u32 reserved:6;
+		/* [16:23] */
+		u32 glb_alpha:8;
+	} bits;
+};
+
+struct vop2_alpha {
+	union vop2_alpha_ctrl src_color_ctrl;
+	union vop2_alpha_ctrl dst_color_ctrl;
+	union vop2_alpha_ctrl src_alpha_ctrl;
+	union vop2_alpha_ctrl dst_alpha_ctrl;
+};
+
+struct vop2_alpha_config {
+	bool src_premulti_en;
+	bool dst_premulti_en;
+	bool src_pixel_alpha_en;
+	bool dst_pixel_alpha_en;
+	u16 src_glb_alpha_value;
+	u16 dst_glb_alpha_value;
+};
+
 static const uint32_t formats_cluster[] = {
 	DRM_FORMAT_XRGB2101010,
 	DRM_FORMAT_XBGR2101010,
@@ -131,6 +169,138 @@ static const uint64_t format_modifiers_afbc[] = {
 	DRM_FORMAT_MOD_INVALID,
 };
 
+static const struct reg_field rk3568_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
+	/* RK3588 only, reserved bit on rk3568*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
+
+	/* cluster regs */
+	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
+	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
+	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
+
+	/* afbc regs */
+	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
+	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
+	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
+	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
+	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
+	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
+	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
+	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
+	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
+	[VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
+};
+
+static const struct reg_field rk3568_vop_smart_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
+	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
+	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	/* RK3588 only, reserved register on rk3568 */
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
+	[VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
+	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
+	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
+	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
+};
+
 static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -647,6 +817,813 @@ static const struct vop2_regs_dump rk3588_regs_dump[] = {
 	},
 };
 
+static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	u32 die, dip;
+
+	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
+	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_RGB0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_RGB |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		if (polflags & POLFLAG_DCLK_INV)
+			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
+		else
+			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
+		break;
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_EDP |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI1:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_LVDS0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_LVDS1:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
+
+	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
+	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
+
+	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
+}
+
+/*
+ * calc the dclk on rk3588
+ * the available div of dclk is 1, 2, 4
+ */
+static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
+{
+	if (child_clk * 4 <= max_dclk)
+		return child_clk * 4;
+	else if (child_clk * 2 <= max_dclk)
+		return child_clk * 2;
+	else if (child_clk <= max_dclk)
+		return child_clk;
+	else
+		return 0;
+}
+
+/*
+ * 4 pixclk/cycle on rk3588
+ * RGB/eDP/HDMI: if_pixclk >= dclk_core
+ * DP: dp_pixclk = dclk_out <= dclk_core
+ * DSI: mipi_pixclk <= dclk_out <= dclk_core
+ */
+static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
+					 int *dclk_core_div, int *dclk_out_div,
+					 int *if_pixclk_div, int *if_dclk_div)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
+	int output_mode = vcstate->output_mode;
+	unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
+	unsigned long dclk_core_rate = v_pixclk >> 2;
+	unsigned long dclk_rate = v_pixclk;
+	unsigned long dclk_out_rate;
+	unsigned long if_pixclk_rate;
+	int K = 1;
+
+	if (vop2_output_if_is_hdmi(id)) {
+		/*
+		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
+		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
+		 */
+		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
+			dclk_rate = dclk_rate >> 1;
+			K = 2;
+		}
+
+		if_pixclk_rate = (dclk_core_rate << 1) / K;
+		/*
+		 * if_dclk_rate = dclk_core_rate / K;
+		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
+		 * *if_dclk_div = dclk_rate / if_dclk_rate;
+		 */
+		*if_pixclk_div = 2;
+		*if_dclk_div = 4;
+	} else if (vop2_output_if_is_edp(id)) {
+		/*
+		 * edp_pixclk = edp_dclk > dclk_core
+		 */
+		if_pixclk_rate = v_pixclk / K;
+		dclk_rate = if_pixclk_rate * K;
+		/*
+		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
+		 * *if_dclk_div = *if_pixclk_div;
+		 */
+		*if_pixclk_div = K;
+		*if_dclk_div = K;
+	} else if (vop2_output_if_is_dp(id)) {
+		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
+			dclk_out_rate = v_pixclk >> 3;
+		else
+			dclk_out_rate = v_pixclk >> 2;
+
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000);
+		if (!dclk_rate) {
+			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld KHZ\n",
+				dclk_out_rate);
+			return 0;
+		}
+		*dclk_out_div = dclk_rate / dclk_out_rate;
+	} else if (vop2_output_if_is_mipi(id)) {
+		if_pixclk_rate = dclk_core_rate / K;
+		/*
+		 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
+		 */
+		dclk_out_rate = if_pixclk_rate;
+		/*
+		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
+		 * we get a little factor here
+		 */
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000);
+		if (!dclk_rate) {
+			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld KHZ\n",
+				dclk_out_rate);
+			return 0;
+		}
+		*dclk_out_div = dclk_rate / dclk_out_rate;
+		/*
+		 * mipi pixclk == dclk_out
+		 */
+		*if_pixclk_div = 1;
+	} else if (vop2_output_if_is_dpi(id)) {
+		dclk_rate = v_pixclk;
+	}
+
+	*dclk_core_div = dclk_rate / dclk_core_rate;
+	*if_pixclk_div = ilog2(*if_pixclk_div);
+	*if_dclk_div = ilog2(*if_dclk_div);
+	*dclk_core_div = ilog2(*dclk_core_div);
+	*dclk_out_div = ilog2(*dclk_out_div);
+
+	drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
+		dclk_rate, *if_pixclk_div, *if_dclk_div);
+
+	return dclk_rate;
+}
+
+/*
+ * MIPI port mux on rk3588:
+ * 0: Video Port2
+ * 1: Video Port3
+ * 3: Video Port 1(MIPI1 only)
+ */
+static u32 rk3588_get_mipi_port_mux(int vp_id)
+{
+	if (vp_id == 1)
+		return 3;
+	else if (vp_id == 3)
+		return 1;
+	else
+		return 0;
+}
+
+static u32 rk3588_get_hdmi_pol(u32 flags)
+{
+	u32 val;
+
+	val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
+	val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
+
+	return val;
+}
+
+static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
+	unsigned long clock;
+	u32 die, dip, div, vp_clk_div, val;
+
+	clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
+				    &if_pixclk_div, &if_dclk_div);
+	if (!clock)
+		return 0;
+
+	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
+	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
+
+	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
+	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
+	div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
+			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
+		val = rk3588_get_hdmi_pol(polflags);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
+		break;
+	case ROCKCHIP_VOP2_EP_HDMI1:
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
+			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
+		val = rk3588_get_hdmi_pol(polflags);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
+		break;
+	case ROCKCHIP_VOP2_EP_EDP1:
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
+		val = rk3588_get_mipi_port_mux(vp->id);
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI1:
+		div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		val = rk3588_get_mipi_port_mux(vp->id);
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
+		break;
+	case ROCKCHIP_VOP2_EP_DP0:
+		die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
+		dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
+		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_DP1:
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
+		dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
+		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
+
+	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
+	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
+	vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
+	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
+
+	return clock;
+}
+
+static bool is_opaque(u16 alpha)
+{
+	return (alpha >> 8) == 0xff;
+}
+
+static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
+			     struct vop2_alpha *alpha)
+{
+	int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
+	int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
+	int src_color_mode = alpha_config->src_premulti_en ?
+				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
+	int dst_color_mode = alpha_config->dst_premulti_en ?
+				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
+
+	alpha->src_color_ctrl.val = 0;
+	alpha->dst_color_ctrl.val = 0;
+	alpha->src_alpha_ctrl.val = 0;
+	alpha->dst_alpha_ctrl.val = 0;
+
+	if (!alpha_config->src_pixel_alpha_en)
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
+	else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
+	else
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
+
+	alpha->src_color_ctrl.bits.alpha_en = 1;
+
+	if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
+		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
+	} else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
+		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
+	} else {
+		alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
+	}
+	alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
+	alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+
+	alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+	alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
+	alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
+	alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
+	alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
+
+	alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
+	alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+	alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
+
+	alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
+		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
+	else
+		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
+	alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
+	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
+}
+
+static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
+{
+	struct vop2_video_port *vp;
+	int used_layer = 0;
+	int i;
+
+	for (i = 0; i < port_id; i++) {
+		vp = &vop2->vps[i];
+		used_layer += hweight32(vp->win_mask);
+	}
+
+	return used_layer;
+}
+
+static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
+{
+	struct vop2_alpha_config alpha_config;
+	struct vop2_alpha alpha;
+	struct drm_plane_state *bottom_win_pstate;
+	bool src_pixel_alpha_en = false;
+	u16 src_glb_alpha_val, dst_glb_alpha_val;
+	u32 offset = 0;
+	bool premulti_en = false;
+	bool swap = false;
+
+	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
+	bottom_win_pstate = main_win->base.state;
+	src_glb_alpha_val = 0;
+	dst_glb_alpha_val = main_win->base.state->alpha;
+
+	if (!bottom_win_pstate->fb)
+		return;
+
+	alpha_config.src_premulti_en = premulti_en;
+	alpha_config.dst_premulti_en = false;
+	alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
+	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
+	alpha_config.src_glb_alpha_value = src_glb_alpha_val;
+	alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
+	vop2_parse_alpha(&alpha_config, &alpha);
+
+	alpha.src_color_ctrl.bits.src_dst_swap = swap;
+
+	switch (main_win->data->phys_id) {
+	case ROCKCHIP_VOP2_CLUSTER0:
+		offset = 0x0;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER1:
+		offset = 0x10;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER2:
+		offset = 0x20;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER3:
+		offset = 0x30;
+		break;
+	}
+
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
+		    alpha.src_color_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
+		    alpha.dst_color_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
+		    alpha.src_alpha_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
+		    alpha.dst_alpha_ctrl.val);
+}
+
+static void vop2_setup_alpha(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_framebuffer *fb;
+	struct vop2_alpha_config alpha_config;
+	struct vop2_alpha alpha;
+	struct drm_plane *plane;
+	int pixel_alpha_en;
+	int premulti_en, gpremulti_en = 0;
+	int mixer_id;
+	u32 offset;
+	bool bottom_layer_alpha_en = false;
+	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
+
+	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		if (plane->state->normalized_zpos == 0 &&
+		    !is_opaque(plane->state->alpha) &&
+		    !vop2_cluster_window(win)) {
+			/*
+			 * If bottom layer have global alpha effect [except cluster layer,
+			 * because cluster have deal with bottom layer global alpha value
+			 * at cluster mix], bottom layer mix need deal with global alpha.
+			 */
+			bottom_layer_alpha_en = true;
+			dst_global_alpha = plane->state->alpha;
+		}
+	}
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+		int zpos = plane->state->normalized_zpos;
+
+		/*
+		 * Need to configure alpha from second layer.
+		 */
+		if (zpos == 0)
+			continue;
+
+		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
+			premulti_en = 1;
+		else
+			premulti_en = 0;
+
+		plane = &win->base;
+		fb = plane->state->fb;
+
+		pixel_alpha_en = fb->format->has_alpha;
+
+		alpha_config.src_premulti_en = premulti_en;
+
+		if (bottom_layer_alpha_en && zpos == 1) {
+			gpremulti_en = premulti_en;
+			/* Cd = Cs + (1 - As) * Cd * Agd */
+			alpha_config.dst_premulti_en = false;
+			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
+			alpha_config.src_glb_alpha_value = plane->state->alpha;
+			alpha_config.dst_glb_alpha_value = dst_global_alpha;
+		} else if (vop2_cluster_window(win)) {
+			/* Mix output data only have pixel alpha */
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = true;
+			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+		} else {
+			/* Cd = Cs + (1 - As) * Cd */
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
+			alpha_config.src_glb_alpha_value = plane->state->alpha;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+		}
+
+		vop2_parse_alpha(&alpha_config, &alpha);
+
+		offset = (mixer_id + zpos - 1) * 0x10;
+		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
+			    alpha.src_color_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
+			    alpha.dst_color_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
+			    alpha.src_alpha_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
+			    alpha.dst_alpha_ctrl.val);
+	}
+
+	if (vp->id == 0) {
+		if (bottom_layer_alpha_en) {
+			/* Transfer pixel alpha to hdr mix */
+			alpha_config.src_premulti_en = gpremulti_en;
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = true;
+			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			vop2_parse_alpha(&alpha_config, &alpha);
+
+			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
+				    alpha.src_color_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
+				    alpha.dst_color_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
+				    alpha.src_alpha_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
+				    alpha.dst_alpha_ctrl.val);
+		} else {
+			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
+		}
+	}
+}
+
+static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_plane *plane;
+	u32 layer_sel = 0;
+	u32 port_sel;
+	u8 old_layer_id;
+	u8 layer_sel_id;
+	unsigned int ofs;
+	u32 ovl_ctrl;
+	int i;
+	struct vop2_video_port *vp0 = &vop2->vps[0];
+	struct vop2_video_port *vp1 = &vop2->vps[1];
+	struct vop2_video_port *vp2 = &vop2->vps[2];
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
+
+	ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
+	ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
+	if (vcstate->yuv_overlay)
+		ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
+	else
+		ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
+
+	vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
+
+	port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
+	port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
+
+	if (vp0->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
+				     vp0->nlayers - 1);
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
+
+	if (vp1->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
+				     (vp0->nlayers + vp1->nlayers - 1));
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
+
+	if (vp2->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
+			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
+
+	layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
+
+	ofs = 0;
+	for (i = 0; i < vp->id; i++)
+		ofs += vop2->vps[i].nlayers;
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+		struct vop2_win *old_win;
+
+		/*
+		 * Find the layer this win bind in old state.
+		 */
+		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
+			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
+			if (layer_sel_id == win->data->layer_sel_id)
+				break;
+		}
+
+		/*
+		 * Find the win bind to this layer in old state
+		 */
+		for (i = 0; i < vop2->data->win_size; i++) {
+			old_win = &vop2->win[i];
+			layer_sel_id = (layer_sel >> (4 * (plane->state->normalized_zpos + ofs))) & 0xf;
+			if (layer_sel_id == old_win->data->layer_sel_id)
+				break;
+		}
+
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_CLUSTER0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER2:
+			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER3:
+			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART2:
+			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART3:
+			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
+			break;
+		case ROCKCHIP_VOP2_SMART0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_SMART1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
+			break;
+		}
+
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
+							  0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
+							 win->data->layer_sel_id);
+		/*
+		 * When we bind a window from layerM to layerN, we also need to move the old
+		 * window on layerN to layerM to avoid one window selected by two or more layers.
+		 */
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
+	}
+
+	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
+	vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
+}
+
+static void rk3568_vop2_setup_dly_for_windows(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct vop2_win *win;
+	int i = 0;
+	u32 cdly = 0, sdly = 0;
+
+	for (i = 0; i < vop2->data->win_size; i++) {
+		u32 dly;
+
+		win = &vop2->win[i];
+		dly = win->delay;
+
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_CLUSTER0:
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER1:
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
+			break;
+		case ROCKCHIP_VOP2_ESMART0:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
+			break;
+		case ROCKCHIP_VOP2_ESMART1:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
+			break;
+		case ROCKCHIP_VOP2_SMART0:
+		case ROCKCHIP_VOP2_ESMART2:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
+			break;
+		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART3:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
+			break;
+		}
+	}
+
+	vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
+	vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
+}
+
+static void rk3568_vop2_setup_overlay(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_plane *plane;
+
+	vp->win_mask = 0;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
+
+		vp->win_mask |= BIT(win->data->phys_id);
+
+		if (vop2_cluster_window(win))
+			vop2_setup_cluster_alpha(vop2, win);
+	}
+
+	if (!vp->win_mask)
+		return;
+
+	rk3568_vop2_setup_layer_mixer(vp);
+	vop2_setup_alpha(vp);
+	rk3568_vop2_setup_dly_for_windows(vp);
+}
+
+static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
+{
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	u16 hdisplay = mode->crtc_hdisplay;
+	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+	u32 bg_dly;
+	u32 pre_scan_dly;
+
+	bg_dly = vp->data->pre_scan_max_dly[3];
+	vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
+		    FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
+
+	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
+	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+}
+
+static const struct vop2_ops rk3568_vop_ops = {
+	.setup_intf_mux = rk3568_set_intf_mux,
+	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
+	.setup_overlay = rk3568_vop2_setup_overlay,
+};
+
+static const struct vop2_ops rk3588_vop_ops = {
+	.setup_intf_mux = rk3588_set_intf_mux,
+	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
+	.setup_overlay = rk3568_vop2_setup_overlay,
+};
+
 static const struct vop2_data rk3566_vop = {
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
@@ -655,8 +1632,13 @@ static const struct vop2_data rk3566_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3568_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
+	.ops = &rk3568_vop_ops,
 	.soc_id = 3566,
 };
 
@@ -668,8 +1650,13 @@ static const struct vop2_data rk3568_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3568_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
+	.ops = &rk3568_vop_ops,
 	.soc_id = 3568,
 };
 
@@ -682,8 +1669,13 @@ static const struct vop2_data rk3588_vop = {
 	.vp = rk3588_vop_video_ports,
 	.win = rk3588_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3588_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
+	.ops = &rk3588_vop_ops,
 	.soc_id = 3588,
 };
 
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:33:16 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:33:16 +0800
Subject: [PATCH v5 12/18] drm/rockchip: vop2: Support for different layer select configuration between VPs
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123318.2781950-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP for rk3576, every VP has it's own LAYER_SEL
register, and the configuration value of each VP for the same
window maybe different, so extend the layer_sel_id to array,
let it can descption the layer select configuration value for
different VP.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v4)

Changes in v4:
- Typo fix: selet->select

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  4 +--
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 38 ++++++++++----------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index a867e154801a..dcfa791be99d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -166,9 +166,9 @@ struct vop2_win_data {
 	const unsigned int supported_rotations;
 
 	/**
-	 * @layer_sel_id: defined by register OVERLAY_LAYER_SEL of VOP2
+	 * @layer_sel_id: defined by register OVERLAY_LAYER_SEL or PORTn_LAYER_SEL
 	 */
-	unsigned int layer_sel_id;
+	unsigned int layer_sel_id[ROCKCHIP_MAX_CRTC];
 	uint64_t feature;
 
 	uint8_t axi_bus_id;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 0cff1327c38e..80f9debd7aa9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -350,7 +350,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
-		.layer_sel_id = 3,
+		/* 0xf means this layer can't attached to this VP */
+		.layer_sel_id = { 3, 3, 3, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -363,7 +364,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1e00,
-		.layer_sel_id = 7,
+		.layer_sel_id = { 7, 7, 7, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -376,7 +377,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = 6,
+		.layer_sel_id = { 6, 6, 6, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -389,7 +390,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1800,
-		.layer_sel_id = 2,
+		.layer_sel_id = { 2, 2, 2, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -402,7 +403,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 0,
+		.layer_sel_id = { 0, 0, 0, 0xf },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.max_upscale_factor = 4,
@@ -417,7 +418,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 1,
+		.layer_sel_id = { 1, 1, 1, 0xf },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
@@ -582,7 +583,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 0,
+		.layer_sel_id = { 0, 0, 0, 0 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.axi_bus_id = 0,
@@ -600,7 +601,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 1,
+		.layer_sel_id = { 1, 1, 1, 1 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -618,7 +619,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 4,
+		.layer_sel_id = { 4, 4, 4, 4 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -636,7 +637,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 5,
+		.layer_sel_id =  { 5, 5, 5, 5 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -654,7 +655,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1800,
-		.layer_sel_id = 2,
+		.layer_sel_id = { 2, 2, 2, 2 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 0,
@@ -670,7 +671,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = 3,
+		.layer_sel_id = { 3, 3, 3, 3 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 0,
@@ -686,7 +687,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
-		.layer_sel_id = 6,
+		.layer_sel_id =  { 6, 6, 6, 6 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 1,
@@ -702,7 +703,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1e00,
-		.layer_sel_id = 7,
+		.layer_sel_id =  { 7, 7, 7, 7 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 1,
@@ -1452,7 +1453,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		 */
 		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
 			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
-			if (layer_sel_id == win->data->layer_sel_id)
+			if (layer_sel_id == win->data->layer_sel_id[vp->id])
 				break;
 		}
 
@@ -1462,7 +1463,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		for (i = 0; i < vop2->data->win_size; i++) {
 			old_win = &vop2->win[i];
 			layer_sel_id = (layer_sel >> (4 * (plane->state->normalized_zpos + ofs))) & 0xf;
-			if (layer_sel_id == old_win->data->layer_sel_id)
+			if (layer_sel_id == old_win->data->layer_sel_id[vp->id])
 				break;
 		}
 
@@ -1512,13 +1513,14 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
 							  0x7);
 		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
-							 win->data->layer_sel_id);
+							 win->data->layer_sel_id[vp->id]);
 		/*
 		 * When we bind a window from layerM to layerN, we also need to move the old
 		 * window on layerN to layerM to avoid one window selected by two or more layers.
 		 */
 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id,
+			     old_win->data->layer_sel_id[vp->id]);
 	}
 
 	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:33:29 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:33:29 +0800
Subject: [PATCH v5 13/18] drm/rockchip: vop2: Introduce vop hardware version
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123330.2781991-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

There is a version number hardcoded in the VOP VERSION_INFO
register, and the version number increments sequentially based
on the production order of the SOC.

So using this version number to distinguish different VOP features
will simplify the code.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v3)

Changes in v3:
- Add comments for why we should treat rk3566 with special care.
- Add hardware version check

Changes in v2:
- Introduce vop hardware version

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 25 ++++++++++++++------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 11 +++++++++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c |  3 +++
 3 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 1997a8deada8..4f56a7e91728 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -354,7 +354,7 @@ static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode)
 
 static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format)
 {
-	if (vop2->data->soc_id == 3588) {
+	if (vop2->version == VOP_VERSION_RK3588) {
 		if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
 		    bus_format == MEDIA_BUS_FMT_YUV10_1X30)
 			return true;
@@ -798,6 +798,7 @@ static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
 static void vop2_enable(struct vop2 *vop2)
 {
 	int ret;
+	u32 version;
 
 	ret = pm_runtime_resume_and_get(vop2->dev);
 	if (ret < 0) {
@@ -817,10 +818,19 @@ static void vop2_enable(struct vop2 *vop2)
 		return;
 	}
 
+	version = vop2_readl(vop2, RK3568_VERSION_INFO);
+	if (version != vop2->version) {
+		drm_err(vop2->drm, "Hardware version(0x%08x) mismatch\n", version);
+		return;
+	}
+	/*
+	 * rk3566 share the same vop version with rk3568, so
+	 * wen need to use soc_id for identification here.
+	 */
 	if (vop2->data->soc_id == 3566)
 		vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
 
-	if (vop2->data->soc_id == 3588)
+	if (vop2->version == VOP_VERSION_RK3588)
 		rk3588_vop2_power_domain_enable_all(vop2);
 
 	vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
@@ -901,7 +911,7 @@ static void vop2_vp_dsp_lut_update_enable(struct vop2_video_port *vp)
 
 static inline bool vop2_supports_seamless_gamma_lut_update(struct vop2 *vop2)
 {
-	return (vop2->data->soc_id != 3566 && vop2->data->soc_id != 3568);
+	return vop2->version != VOP_VERSION_RK3568;
 }
 
 static bool vop2_gamma_lut_in_use(struct vop2 *vop2, struct vop2_video_port *vp)
@@ -1031,7 +1041,7 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
 		return -EINVAL;
 	}
 
-	if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
+	if (vop2->version == VOP_VERSION_RK3568) {
 		if (vop2_cluster_window(win)) {
 			if (!rockchip_afbc(plane, fb->modifier)) {
 				drm_err(vop2->drm, "Unsupported linear format for %s\n", win->data->name);
@@ -1041,7 +1051,7 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
 	}
 
 	if (fb->format->format == DRM_FORMAT_XRGB2101010 || fb->format->format == DRM_FORMAT_XBGR2101010) {
-		if (vop2->data->soc_id == 3588) {
+		if (vop2->version == VOP_VERSION_RK3588) {
 			if (!rockchip_afbc(plane, fb->modifier)) {
 				drm_err(vop2->drm, "Unsupported linear 32 bpp for %s\n", win->data->name);
 				return -EINVAL;
@@ -1260,7 +1270,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		&fb->format->format,
 		afbc_en ? "AFBC" : "", &yrgb_mst);
 
-	if (vop2->data->soc_id > 3568) {
+	if (vop2->version > VOP_VERSION_RK3568) {
 		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
 		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
 		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
@@ -1320,7 +1330,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		 * this bit is gating disable, we should write 1 to
 		 * disable gating when enable afbc.
 		 */
-		if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568)
+		if (vop2->version == VOP_VERSION_RK3568)
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0);
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1);
@@ -2525,6 +2535,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 	vop2->dev = dev;
 	vop2->data = vop2_data;
 	vop2->ops = vop2_data->ops;
+	vop2->version = vop2_data->version;
 	vop2->drm = drm;
 
 	dev_set_drvdata(dev, vop2);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index dcfa791be99d..5514ece7df4d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -13,6 +13,15 @@
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
+#define VOP2_VERSION(major, minor, build)	((major) << 24 | (minor) << 16 | (build))
+
+/* The new SOC VOP version is bigger than the old */
+#define VOP_VERSION_RK3568	VOP2_VERSION(0x40, 0x15, 0x8023)
+#define VOP_VERSION_RK3588	VOP2_VERSION(0x40, 0x17, 0x6786)
+#define VOP_VERSION_RK3528	VOP2_VERSION(0x50, 0x17, 0x1263)
+#define VOP_VERSION_RK3562	VOP2_VERSION(0x50, 0x17, 0x4350)
+#define VOP_VERSION_RK3576	VOP2_VERSION(0x50, 0x19, 0x9765)
+
 #define VOP2_VP_FEATURE_OUTPUT_10BIT        BIT(0)
 
 #define VOP2_FEATURE_HAS_SYS_GRF	BIT(0)
@@ -242,6 +251,7 @@ struct vop2_ops {
 struct vop2_data {
 	u8 nr_vps;
 	u64 feature;
+	u32 version;
 	const struct vop2_ops *ops;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
@@ -259,6 +269,7 @@ struct vop2_data {
 };
 
 struct vop2 {
+	u32 version;
 	struct device *dev;
 	struct drm_device *drm;
 	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 80f9debd7aa9..baf81e97062c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -1627,6 +1627,7 @@ static const struct vop2_ops rk3588_vop_ops = {
 };
 
 static const struct vop2_data rk3566_vop = {
+	.version = VOP_VERSION_RK3568,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
 	.max_input = { 4096, 2304 },
@@ -1645,6 +1646,7 @@ static const struct vop2_data rk3566_vop = {
 };
 
 static const struct vop2_data rk3568_vop = {
+	.version = VOP_VERSION_RK3568,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
 	.max_input = { 4096, 2304 },
@@ -1663,6 +1665,7 @@ static const struct vop2_data rk3568_vop = {
 };
 
 static const struct vop2_data rk3588_vop = {
+	.version = VOP_VERSION_RK3588,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
 		   VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU,
 	.nr_vps = 4,
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:33:40 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:33:40 +0800
Subject: [PATCH v5 14/18] drm/rockchip: vop2: Register the primary plane and overlay plane separately
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123341.2782031-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP of rk3576, a Window cannot attach to all Video Ports,
so make sure all VP find it's suitable primary plane, then register the
remain windows as overlay plane will make code easier.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v3)

Changes in v3:
- Add comments for why we should treat rk3566 with special care.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 100 +++++++++++--------
 1 file changed, 61 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 4f56a7e91728..29f7c105b89b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2224,22 +2224,29 @@ static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win,
 	return 0;
 }
 
-static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2)
+/*
+ * On RK3566 these windows don't have an independent
+ * framebuffer. They can only share/mirror the framebuffer
+ * with smart0, esmart0 and cluster0 respectively.
+ * And RK3566 share the same vop version with Rk3568, so we
+ * need to use soc_id for identification here.
+ */
+static bool vop2_is_mirror_win(struct vop2_win *win)
 {
-	int i;
-
-	for (i = 0; i < vop2->data->nr_vps; i++) {
-		struct vop2_video_port *vp = &vop2->vps[i];
-
-		if (!vp->crtc.port)
-			continue;
-		if (vp->primary_plane)
-			continue;
+	struct vop2 *vop2 = win->vop2;
 
-		return vp;
+	if (vop2->data->soc_id == 3566) {
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART1:
+		case ROCKCHIP_VOP2_CLUSTER1:
+			return true;
+		default:
+			return false;
+		}
+	} else {
+		return false;
 	}
-
-	return NULL;
 }
 
 static int vop2_create_crtcs(struct vop2 *vop2)
@@ -2250,7 +2257,9 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 	struct drm_plane *plane;
 	struct device_node *port;
 	struct vop2_video_port *vp;
-	int i, nvp, nvps = 0;
+	struct vop2_win *win;
+	u32 possible_crtcs;
+	int i, j, nvp, nvps = 0;
 	int ret;
 
 	for (i = 0; i < vop2_data->nr_vps; i++) {
@@ -2289,42 +2298,55 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 	}
 
 	nvp = 0;
-	for (i = 0; i < vop2->registered_num_wins; i++) {
-		struct vop2_win *win = &vop2->win[i];
-		u32 possible_crtcs = 0;
-
-		if (vop2->data->soc_id == 3566) {
-			/*
-			 * On RK3566 these windows don't have an independent
-			 * framebuffer. They share the framebuffer with smart0,
-			 * esmart0 and cluster0 respectively.
-			 */
-			switch (win->data->phys_id) {
-			case ROCKCHIP_VOP2_SMART1:
-			case ROCKCHIP_VOP2_ESMART1:
-			case ROCKCHIP_VOP2_CLUSTER1:
+	/* Register a primary plane for every crtc */
+	for (i = 0; i < vop2_data->nr_vps; i++) {
+		vp = &vop2->vps[i];
+
+		if (!vp->crtc.port)
+			continue;
+
+		for (j = 0; j < vop2->registered_num_wins; j++) {
+			win = &vop2->win[j];
+
+			/* Aready registered as primary plane */
+			if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
+				continue;
+
+			if (vop2_is_mirror_win(win))
 				continue;
-			}
-		}
 
-		if (win->type == DRM_PLANE_TYPE_PRIMARY) {
-			vp = find_vp_without_primary(vop2);
-			if (vp) {
+			if (win->type == DRM_PLANE_TYPE_PRIMARY) {
 				possible_crtcs = BIT(nvp);
 				vp->primary_plane = win;
+				ret = vop2_plane_init(vop2, win, possible_crtcs);
+				if (ret) {
+					drm_err(vop2->drm, "failed to init primary plane %s: %d\n",
+						win->data->name, ret);
+					return ret;
+				}
 				nvp++;
-			} else {
-				/* change the unused primary window to overlay window */
-				win->type = DRM_PLANE_TYPE_OVERLAY;
+				break;
 			}
 		}
+	}
+
+	/* Register all unused window as overlay plane */
+	for (i = 0; i < vop2->registered_num_wins; i++) {
+		win = &vop2->win[i];
+
+		/* Aready registered as primary plane */
+		if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
+			continue;
+
+		if (vop2_is_mirror_win(win))
+			continue;
 
-		if (win->type == DRM_PLANE_TYPE_OVERLAY)
-			possible_crtcs = (1 << nvps) - 1;
+		win->type = DRM_PLANE_TYPE_OVERLAY;
 
+		possible_crtcs = (1 << nvps) - 1;
 		ret = vop2_plane_init(vop2, win, possible_crtcs);
 		if (ret) {
-			drm_err(vop2->drm, "failed to init plane %s: %d\n",
+			drm_err(vop2->drm, "failed to init overlay plane %s: %d\n",
 				win->data->name, ret);
 			return ret;
 		}
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:33:52 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:33:52 +0800
Subject: [PATCH v5 15/18] drm/rockchip: vop2: Set plane possible crtcs by possible vp mask
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123353.2782091-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP of rk3576, a window cannot attach to all Video
Ports, we introduce a possible_vp_mask for every window to indicate
which Video Ports this window can attach to.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 18 +++++++++++++++++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  1 +
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 14 ++++++++++++++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 29f7c105b89b..81ba2e29a09d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2312,6 +2312,10 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 			if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
 				continue;
 
+			/* If this win can not attached to this VP */
+			if (!(win->data->possible_vp_mask & BIT(vp->id)))
+				continue;
+
 			if (vop2_is_mirror_win(win))
 				continue;
 
@@ -2343,7 +2347,19 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 
 		win->type = DRM_PLANE_TYPE_OVERLAY;
 
-		possible_crtcs = (1 << nvps) - 1;
+		possible_crtcs = 0;
+		nvp = 0;
+		for (j = 0; j < vop2_data->nr_vps; j++) {
+			vp = &vop2->vps[j];
+
+			if (!vp->crtc.port)
+				continue;
+
+			if (win->data->possible_vp_mask & BIT(vp->id))
+				possible_crtcs |= BIT(nvp);
+			nvp++;
+		}
+
 		ret = vop2_plane_init(vop2, win, possible_crtcs);
 		if (ret) {
 			drm_err(vop2->drm, "failed to init overlay plane %s: %d\n",
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 5514ece7df4d..adb23438e4cd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -167,6 +167,7 @@ struct vop2_win_data {
 	unsigned int phys_id;
 
 	u32 base;
+	u32 possible_vp_mask;
 	enum drm_plane_type type;
 
 	u32 nformats;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index baf81e97062c..62f8b4113f5f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -347,6 +347,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.name = "Smart0-win0",
 		.phys_id = ROCKCHIP_VOP2_SMART0,
 		.base = 0x1c00,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
@@ -360,6 +361,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	}, {
 		.name = "Smart1-win0",
 		.phys_id = ROCKCHIP_VOP2_SMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
@@ -373,6 +375,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	}, {
 		.name = "Esmart1-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_rk356x_esmart,
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
@@ -386,6 +389,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	}, {
 		.name = "Esmart0-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_rk356x_esmart,
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
@@ -400,6 +404,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.name = "Cluster0-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
 		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -415,6 +420,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.name = "Cluster1-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
 		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -580,6 +586,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster0-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
 		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -598,6 +605,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster1-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
 		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -616,6 +624,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster2-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER2,
 		.base = 0x1400,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -634,6 +643,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster3-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER3,
 		.base = 0x1600,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -651,6 +661,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	}, {
 		.name = "Esmart0-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
@@ -667,6 +678,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	}, {
 		.name = "Esmart1-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
@@ -684,6 +696,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Esmart2-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART2,
 		.base = 0x1c00,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
@@ -699,6 +712,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	}, {
 		.name = "Esmart3-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART3,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:34:03 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:34:03 +0800
Subject: [PATCH v5 16/18] drm/rockchip: vop2: Add uv swap for cluster window
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123404.2782132-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The Cluster windows of upcoming VOP on rk3576 also support
linear YUV support, we need to set uv swap bit for it.

As the VOP2_WIN_UV_SWA register defined on rk3568/rk3588 is
0xffffffff, so this register will not be touched on these
two platforms.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 81ba2e29a09d..4922cce3247a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1373,10 +1373,8 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 
 	rb_swap = vop2_win_rb_swap(fb->format->format);
 	vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap);
-	if (!vop2_cluster_window(win)) {
-		uv_swap = vop2_win_uv_swap(fb->format->format);
-		vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap);
-	}
+	uv_swap = vop2_win_uv_swap(fb->format->format);
+	vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap);
 
 	if (fb->format->is_yuv) {
 		vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4));
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:34:14 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:34:14 +0800
Subject: [PATCH v5 17/18] dt-bindings: display: vop2: Add rk3576 support
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123415.2782172-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Add vop found on rk3576, the main difference between rk3576 and the
previous vop is that each VP has its own interrupt line.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>

---

(no changes since v3)

Changes in v3:
- ordered by soc name
- Add description for newly added interrupt

Changes in v2:
- Add dt bindings

 .../bindings/display/rockchip/rockchip-vop2.yaml    | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
index 2531726af306..a44964b6c36a 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -20,6 +20,7 @@ properties:
     enum:
       - rockchip,rk3566-vop
       - rockchip,rk3568-vop
+      - rockchip,rk3576-vop
       - rockchip,rk3588-vop
 
   reg:
@@ -37,10 +38,14 @@ properties:
       - const: gamma-lut
 
   interrupts:
-    maxItems: 1
-    description:
-      The VOP interrupt is shared by several interrupt sources, such as
-      frame start (VSYNC), line flag and other status interrupts.
+    minItems: 1
+    items:
+      - description:
+          vop system interrupt, such as bus error, and vsync for vop version under
+          rk3576.
+      - description:
+          independent interrupts for each video port, such as vsync and other video
+          port related error interrupts.
 
   # See compatible-specific constraints below.
   clocks:
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:34:25 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon,  9 Dec 2024 20:34:25 +0800
Subject: [PATCH v5 18/18] drm/rockchip: vop2: Add support for rk3576
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241209123426.2782212-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

VOP2 on rk3576:
Three video ports:
VP0 Max 4096x2160
VP1 Max 2560x1600
VP2 Max 1920x1080

2 4K Cluster windows with AFBC/RFBC, line RGB and YUV
4 Esmart windows with line RGB/YUV support:
Esmart0/1: 4K
Esmart2/3: 2k, or worked together as a single 4K plane at shared
line buffer mode.

Compared to the previous VOP, another difference is that each VP
has its own independent vsync interrupt number.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

Changes in v5:
- Add axi id configuration
- Remove the non-existent CBCR scale register.

Changes in v3:
- Share the alpha setup function with rk3568
- recoder the code block by soc

Changes in v2:
- Add platform specific callback

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 144 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  87 ++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 950 +++++++++++++++++--
 3 files changed, 1056 insertions(+), 125 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 4922cce3247a..e9b98479ae61 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1276,6 +1276,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
 	}
 
+	if (vop2->version >= VOP_VERSION_RK3576)
+		vop2_win_write(win, VOP2_WIN_VP_SEL, vp->id);
+
 	if (vop2_cluster_window(win))
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
@@ -1340,6 +1343,11 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
 
+		if (vop2->version >= VOP_VERSION_RK3576) {
+			vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET_EN, 1);
+			vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET, yrgb_mst);
+		}
+
 		transform_offset = vop2_afbc_transform_offset(pstate, half_block_en);
 		vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
 		vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
@@ -2119,6 +2127,56 @@ static const struct drm_crtc_funcs vop2_crtc_funcs = {
 	.late_register = vop2_crtc_late_register,
 };
 
+static irqreturn_t rk3576_vp_isr(int irq, void *data)
+{
+	struct vop2_video_port *vp = data;
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	uint32_t irqs;
+	int ret = IRQ_NONE;
+
+	/*
+	 * The irq is shared with the iommu. If the runtime-pm state of the
+	 * vop2-device is disabled the irq has to be targeted at the iommu.
+	 */
+	if (!pm_runtime_get_if_in_use(vop2->dev))
+		return IRQ_NONE;
+
+	irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
+	vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
+
+	if (irqs & VP_INT_DSP_HOLD_VALID) {
+		complete(&vp->dsp_hold_completion);
+		ret = IRQ_HANDLED;
+	}
+
+	if (irqs & VP_INT_FS_FIELD) {
+		drm_crtc_handle_vblank(crtc);
+		spin_lock(&crtc->dev->event_lock);
+		if (vp->event) {
+			u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
+
+			if (!(val & BIT(vp->id))) {
+				drm_crtc_send_vblank_event(crtc, vp->event);
+				vp->event = NULL;
+				drm_crtc_vblank_put(crtc);
+			}
+		}
+		spin_unlock(&crtc->dev->event_lock);
+
+		ret = IRQ_HANDLED;
+	}
+
+	if (irqs & VP_INT_POST_BUF_EMPTY) {
+		drm_err_ratelimited(vop2->drm, "POST_BUF_EMPTY irq err at vp%d\n", vp->id);
+		ret = IRQ_HANDLED;
+	}
+
+	pm_runtime_put(vop2->dev);
+
+	return ret;
+}
+
 static irqreturn_t vop2_isr(int irq, void *data)
 {
 	struct vop2 *vop2 = data;
@@ -2134,41 +2192,43 @@ static irqreturn_t vop2_isr(int irq, void *data)
 	if (!pm_runtime_get_if_in_use(vop2->dev))
 		return IRQ_NONE;
 
-	for (i = 0; i < vop2_data->nr_vps; i++) {
-		struct vop2_video_port *vp = &vop2->vps[i];
-		struct drm_crtc *crtc = &vp->crtc;
-		u32 irqs;
+	if (vop2->version < VOP_VERSION_RK3576) {
+		for (i = 0; i < vop2_data->nr_vps; i++) {
+			struct vop2_video_port *vp = &vop2->vps[i];
+			struct drm_crtc *crtc = &vp->crtc;
+			u32 irqs;
 
-		irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
-		vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
+			irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
+			vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
 
-		if (irqs & VP_INT_DSP_HOLD_VALID) {
-			complete(&vp->dsp_hold_completion);
-			ret = IRQ_HANDLED;
-		}
-
-		if (irqs & VP_INT_FS_FIELD) {
-			drm_crtc_handle_vblank(crtc);
-			spin_lock(&crtc->dev->event_lock);
-			if (vp->event) {
-				u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
+			if (irqs & VP_INT_DSP_HOLD_VALID) {
+				complete(&vp->dsp_hold_completion);
+				ret = IRQ_HANDLED;
+			}
 
-				if (!(val & BIT(vp->id))) {
-					drm_crtc_send_vblank_event(crtc, vp->event);
-					vp->event = NULL;
-					drm_crtc_vblank_put(crtc);
+			if (irqs & VP_INT_FS_FIELD) {
+				drm_crtc_handle_vblank(crtc);
+				spin_lock(&crtc->dev->event_lock);
+				if (vp->event) {
+					u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
+
+					if (!(val & BIT(vp->id))) {
+						drm_crtc_send_vblank_event(crtc, vp->event);
+						vp->event = NULL;
+						drm_crtc_vblank_put(crtc);
+					}
 				}
-			}
-			spin_unlock(&crtc->dev->event_lock);
+				spin_unlock(&crtc->dev->event_lock);
 
-			ret = IRQ_HANDLED;
-		}
+				ret = IRQ_HANDLED;
+			}
 
-		if (irqs & VP_INT_POST_BUF_EMPTY) {
-			drm_err_ratelimited(vop2->drm,
-					    "POST_BUF_EMPTY irq err at vp%d\n",
-					    vp->id);
-			ret = IRQ_HANDLED;
+			if (irqs & VP_INT_POST_BUF_EMPTY) {
+				drm_err_ratelimited(vop2->drm,
+						    "POST_BUF_EMPTY irq err at vp%d\n",
+						    vp->id);
+				ret = IRQ_HANDLED;
+			}
 		}
 	}
 
@@ -2660,6 +2720,32 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 	if (ret)
 		return ret;
 
+	if (vop2->version >= VOP_VERSION_RK3576) {
+		struct drm_crtc *crtc;
+
+		drm_for_each_crtc(crtc, drm) {
+			struct vop2_video_port *vp = to_vop2_video_port(crtc);
+			int vp_irq;
+			const char *irq_name = devm_kasprintf(dev, GFP_KERNEL, "vop-vp%d", vp->id);
+
+			if (!irq_name)
+				return -ENOMEM;
+
+			vp_irq = platform_get_irq_byname(pdev, irq_name);
+			if (vp_irq < 0) {
+				DRM_DEV_ERROR(dev, "cannot find irq for vop2 vp%d\n", vp->id);
+				return vp_irq;
+			}
+
+			ret = devm_request_irq(dev, vp_irq, rk3576_vp_isr, IRQF_SHARED, irq_name,
+					       vp);
+			if (ret) {
+				DRM_DEV_ERROR(dev, "request irq for vop2 vp%d failed\n", vp->id);
+				return ret;
+			}
+		}
+	}
+
 	ret = vop2_find_rgb_encoder(vop2);
 	if (ret >= 0) {
 		vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index adb23438e4cd..2995988ef559 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -44,6 +44,13 @@ enum win_dly_mode {
 	VOP2_DLY_MODE_MAX,
 };
 
+enum vop2_dly_module {
+	VOP2_DLY_WIN,           /** Win delay cycle for this VP */
+	VOP2_DLY_LAYER_MIX,     /** Layer Mix delay cycle for this VP */
+	VOP2_DLY_HDR_MIX,       /** HDR delay cycle for this VP */
+	VOP2_DLY_MAX,
+};
+
 enum vop2_scale_up_mode {
 	VOP2_SCALE_UP_NRST_NBOR,
 	VOP2_SCALE_UP_BIL,
@@ -140,16 +147,22 @@ enum vop2_win_regs {
 	VOP2_WIN_AFBC_UV_SWAP,
 	VOP2_WIN_AFBC_AUTO_GATING_EN,
 	VOP2_WIN_AFBC_BLOCK_SPLIT_EN,
+	VOP2_WIN_AFBC_PLD_OFFSET_EN,
 	VOP2_WIN_AFBC_PIC_VIR_WIDTH,
 	VOP2_WIN_AFBC_TILE_NUM,
 	VOP2_WIN_AFBC_PIC_OFFSET,
 	VOP2_WIN_AFBC_PIC_SIZE,
 	VOP2_WIN_AFBC_DSP_OFFSET,
+	VOP2_WIN_AFBC_PLD_OFFSET,
 	VOP2_WIN_AFBC_TRANSFORM_OFFSET,
 	VOP2_WIN_AFBC_HDR_PTR,
 	VOP2_WIN_AFBC_HALF_BLOCK_EN,
 	VOP2_WIN_AFBC_ROTATE_270,
 	VOP2_WIN_AFBC_ROTATE_90,
+
+	VOP2_WIN_VP_SEL,
+	VOP2_WIN_DLY_NUM,
+
 	VOP2_WIN_MAX_REG,
 };
 
@@ -215,6 +228,10 @@ struct vop2_video_port_data {
 	struct vop_rect max_output;
 	const u8 pre_scan_max_dly[4];
 	unsigned int offset;
+	/**
+	 * @pixel_rate: pixel per cycle
+	 */
+	u8 pixel_rate;
 };
 
 struct vop2_video_port {
@@ -372,10 +389,13 @@ enum dst_factor_mode {
 #define RK3568_REG_CFG_DONE			0x000
 #define RK3568_VERSION_INFO			0x004
 #define RK3568_SYS_AUTO_GATING_CTRL		0x008
+#define RK3576_SYS_MMU_CTRL_IMD			0x020
 #define RK3568_SYS_AXI_LUT_CTRL			0x024
 #define RK3568_DSP_IF_EN			0x028
+#define RK3576_SYS_PORT_CTRL_IMD		0x028
 #define RK3568_DSP_IF_CTRL			0x02c
 #define RK3568_DSP_IF_POL			0x030
+#define RK3576_SYS_CLUSTER_PD_CTRL_IMD		0x030
 #define RK3588_SYS_PD_CTRL			0x034
 #define RK3568_WB_CTRL				0x40
 #define RK3568_WB_XSCAL_FACTOR			0x44
@@ -395,6 +415,55 @@ enum dst_factor_mode {
 #define RK3568_VP_INT_CLR(vp)			(0xA4 + (vp) * 0x10)
 #define RK3568_VP_INT_STATUS(vp)		(0xA8 + (vp) * 0x10)
 #define RK3568_VP_INT_RAW_STATUS(vp)		(0xAC + (vp) * 0x10)
+#define RK3576_WB_CTRL				0x100
+#define RK3576_WB_XSCAL_FACTOR			0x104
+#define RK3576_WB_YRGB_MST			0x108
+#define RK3576_WB_CBR_MST			0x10C
+#define RK3576_WB_VIR_STRIDE			0x110
+#define RK3576_WB_TIMEOUT_CTRL			0x114
+#define RK3576_MIPI0_IF_CTRL			0x180
+#define RK3576_HDMI0_IF_CTRL			0x184
+#define RK3576_EDP0_IF_CTRL			0x188
+#define RK3576_DP0_IF_CTRL			0x18C
+#define RK3576_RGB_IF_CTRL			0x194
+#define RK3576_DP1_IF_CTRL			0x1A4
+#define RK3576_DP2_IF_CTRL			0x1B0
+
+/* Extra OVL register definition */
+#define RK3576_SYS_EXTRA_ALPHA_CTRL		0x500
+#define RK3576_CLUSTER0_MIX_SRC_COLOR_CTRL	0x530
+#define RK3576_CLUSTER0_MIX_DST_COLOR_CTRL	0x534
+#define RK3576_CLUSTER0_MIX_SRC_ALPHA_CTRL	0x538
+#define RK3576_CLUSTER0_MIX_DST_ALPHA_CTRL	0x53c
+#define RK3576_CLUSTER1_MIX_SRC_COLOR_CTRL	0x540
+#define RK3576_CLUSTER1_MIX_DST_COLOR_CTRL	0x544
+#define RK3576_CLUSTER1_MIX_SRC_ALPHA_CTRL	0x548
+#define RK3576_CLUSTER1_MIX_DST_ALPHA_CTRL	0x54c
+
+/* OVL registers for Video Port definition */
+#define RK3576_OVL_CTRL(vp)			(0x600 + (vp) * 0x100)
+#define RK3576_OVL_LAYER_SEL(vp)		(0x604 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_SRC_COLOR_CTRL(vp)	(0x620 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_DST_COLOR_CTRL(vp)	(0x624 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_SRC_ALPHA_CTRL(vp)	(0x628 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_DST_ALPHA_CTRL(vp)	(0x62C + (vp) * 0x100)
+#define RK3576_OVL_MIX1_SRC_COLOR_CTRL(vp)	(0x630 + (vp) * 0x100)
+#define RK3576_OVL_MIX1_DST_COLOR_CTRL(vp)	(0x634 + (vp) * 0x100)
+#define RK3576_OVL_MIX1_SRC_ALPHA_CTRL(vp)	(0x638 + (vp) * 0x100)
+#define RK3576_OVL_MIX1_DST_ALPHA_CTRL(vp)	(0x63C + (vp) * 0x100)
+#define RK3576_OVL_MIX2_SRC_COLOR_CTRL(vp)	(0x640 + (vp) * 0x100)
+#define RK3576_OVL_MIX2_DST_COLOR_CTRL(vp)	(0x644 + (vp) * 0x100)
+#define RK3576_OVL_MIX2_SRC_ALPHA_CTRL(vp)	(0x648 + (vp) * 0x100)
+#define RK3576_OVL_MIX2_DST_ALPHA_CTRL(vp)	(0x64C + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_SRC_COLOR_CTRL(vp)	(0x650 + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_DST_COLOR_CTRL(vp)	(0x654 + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_SRC_ALPHA_CTRL(vp)	(0x658 + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_DST_ALPHA_CTRL(vp)	(0x65C + (vp) * 0x100)
+#define RK3576_OVL_HDR_SRC_COLOR_CTRL(vp)	(0x660 + (vp) * 0x100)
+#define RK3576_OVL_HDR_DST_COLOR_CTRL(vp)	(0x664 + (vp) * 0x100)
+#define RK3576_OVL_HDR_SRC_ALPHA_CTRL(vp)	(0x668 + (vp) * 0x100)
+#define RK3576_OVL_HDR_DST_ALPHA_CTRL(vp)	(0x66C + (vp) * 0x100)
+#define RK3576_OVL_BG_MIX_CTRL(vp)		(0x670 + (vp) * 0x100)
 
 /* Video Port registers definition */
 #define RK3568_VP0_CTRL_BASE			0x0C00
@@ -477,7 +546,11 @@ enum dst_factor_mode {
 #define RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET	0x68
 #define RK3568_CLUSTER_WIN_AFBCD_CTRL		0x6C
 
+#define RK3576_CLUSTER_WIN_AFBCD_PLD_PTR_OFFSET	0x78
+
 #define RK3568_CLUSTER_CTRL			0x100
+#define RK3576_CLUSTER_PORT_SEL_IMD		0x1F4
+#define RK3576_CLUSTER_DLY_NUM			0x1F8
 
 /* (E)smart register definition, offset relative to window base */
 #define RK3568_SMART_CTRL0			0x00
@@ -528,6 +601,9 @@ enum dst_factor_mode {
 #define RK3568_SMART_REGION3_SCL_FACTOR_CBR	0xC8
 #define RK3568_SMART_REGION3_SCL_OFFSET		0xCC
 #define RK3568_SMART_COLOR_KEY_CTRL		0xD0
+#define RK3576_SMART_ALPHA_MAP			0xD8
+#define RK3576_SMART_PORT_SEL_IMD		0xF4
+#define RK3576_SMART_DLY_NUM			0xF8
 
 /* HDR register definition */
 #define RK3568_HDR_LUT_CTRL			0x2000
@@ -676,6 +752,17 @@ enum dst_factor_mode {
 
 #define POLFLAG_DCLK_INV	BIT(3)
 
+#define RK3576_OVL_CTRL__YUV_MODE			BIT(0)
+#define RK3576_OVL_BG_MIX_CTRL__BG_DLY			GENMASK(31, 24)
+
+#define RK3576_DSP_IF_CFG_DONE_IMD			BIT(31)
+#define RK3576_DSP_IF_DCLK_SEL_OUT			BIT(21)
+#define RK3576_DSP_IF_PCLK_DIV				BIT(20)
+#define RK3576_DSP_IF_PIN_POL				GENMASK(5, 4)
+#define RK3576_DSP_IF_MUX				GENMASK(3, 2)
+#define RK3576_DSP_IF_CLK_OUT_EN			BIT(1)
+#define RK3576_DSP_IF_EN				BIT(0)
+
 enum vop2_layer_phy_id {
 	ROCKCHIP_VOP2_CLUSTER0 = 0,
 	ROCKCHIP_VOP2_CLUSTER1,
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 62f8b4113f5f..3f4dd923b19c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -70,6 +70,37 @@ static const uint32_t formats_cluster[] = {
 	DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */
 };
 
+/*
+ * The cluster windows on rk3576 support:
+ * RGB: linear mode and afbc
+ * YUV: linear mode and rfbc
+ * rfbc is a rockchip defined non-linear mode, produced by
+ * Video decoder
+ */
+static const uint32_t formats_rk3576_cluster[] = {
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_ABGR2101010,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
+};
+
 static const uint32_t formats_esmart[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -116,6 +147,41 @@ static const uint32_t formats_rk356x_esmart[] = {
 	DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
 };
 
+/*
+ * Add XRGB2101010/ARGB2101010ARGB1555/XRGB1555
+ */
+static const uint32_t formats_rk3576_esmart[] = {
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_ABGR2101010,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_ABGR1555,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_XBGR1555,
+	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */
+	DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
+	DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */
+	DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */
+};
+
 static const uint32_t formats_smart[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -169,6 +235,48 @@ static const uint64_t format_modifiers_afbc[] = {
 	DRM_FORMAT_MOD_INVALID,
 };
 
+/* used from rk3576, afbc 32*8 half mode */
+static const uint64_t format_modifiers_rk3576_afbc[] = {
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	/* SPLIT mandates SPARSE, RGB modes mandates YTR */
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID,
+};
+
 static const struct reg_field rk3568_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
 	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
@@ -301,6 +409,146 @@ static const struct reg_field rk3568_vop_smart_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
 };
 
+static const struct reg_field rk3576_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 17, 17),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 4),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 9),
+	/* Read only bit on rk3576*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
+
+	[VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_CLUSTER_PORT_SEL_IMD, 0, 1),
+	[VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_CLUSTER_DLY_NUM, 0, 7),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 22, 23),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
+
+	/* cluster regs */
+	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
+	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
+	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
+
+	/* afbc regs */
+	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
+	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
+	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
+	[VOP2_WIN_AFBC_PLD_OFFSET_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 16, 16),
+	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
+	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
+	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
+	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_PLD_OFFSET] = REG_FIELD(RK3576_CLUSTER_WIN_AFBCD_PLD_PTR_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
+	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
+	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
+	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
+};
+
+static const struct reg_field rk3576_vop_smart_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
+	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
+	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_SMART_PORT_SEL_IMD, 0, 1),
+	[VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_SMART_DLY_NUM, 0, 7),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
+	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
+	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
+	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
+
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff }, /* CBCR share the same scale factor as YRGB */
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff},
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff},
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff},
+
+	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
+};
+
 static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -355,98 +603,385 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.layer_sel_id = { 3, 3, 3, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
-		.max_upscale_factor = 8,
-		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Smart1-win0",
+		.phys_id = ROCKCHIP_VOP2_SMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_smart,
+		.nformats = ARRAY_SIZE(formats_smart),
+		.format_modifiers = format_modifiers,
+		.base = 0x1e00,
+		.layer_sel_id = { 7, 7, 7, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Esmart1-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_rk356x_esmart,
+		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
+		.format_modifiers = format_modifiers,
+		.base = 0x1a00,
+		.layer_sel_id = { 6, 6, 6, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Esmart0-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_rk356x_esmart,
+		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
+		.format_modifiers = format_modifiers,
+		.base = 0x1800,
+		.layer_sel_id = { 2, 2, 2, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Cluster0-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
+		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_cluster,
+		.nformats = ARRAY_SIZE(formats_cluster),
+		.format_modifiers = format_modifiers_afbc,
+		.layer_sel_id = { 0, 0, 0, 0xf },
+		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
+					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.dly = { 0, 27, 21 },
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+	}, {
+		.name = "Cluster1-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
+		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_cluster,
+		.nformats = ARRAY_SIZE(formats_cluster),
+		.format_modifiers = format_modifiers_afbc,
+		.layer_sel_id = { 1, 1, 1, 0xf },
+		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
+					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.dly = { 0, 27, 21 },
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+	},
+};
+
+static const struct vop2_regs_dump rk3568_regs_dump[] = {
+	{
+		.name = "SYS",
+		.base = RK3568_REG_CFG_DONE,
+		.size = 0x100,
+		.en_reg  = 0,
+		.en_val = 0,
+		.en_mask = 0
+	}, {
+		.name = "OVL",
+		.base = RK3568_OVL_CTRL,
+		.size = 0x100,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "VP0",
+		.base = RK3568_VP0_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP1",
+		.base = RK3568_VP1_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP2",
+		.base = RK3568_VP2_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+
+	}, {
+		.name = "Cluster0",
+		.base = RK3568_CLUSTER0_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster1",
+		.base = RK3568_CLUSTER1_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Esmart0",
+		.base = RK3568_ESMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart1",
+		.base = RK3568_ESMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart0",
+		.base = RK3568_SMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart1",
+		.base = RK3568_SMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	},
+};
+
+static const struct vop2_video_port_data rk3576_vop_video_ports[] = {
+	{
+		.id = 0,
+		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
+		.gamma_lut_len = 1024,
+		.cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
+		.max_output = { 4096, 2304 },
+		/* win layer_mix hdr  */
+		.pre_scan_max_dly = { 10, 8, 2, 0 },
+		.offset = 0xc00,
+		.pixel_rate = 2,
+	}, {
+		.id = 1,
+		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
+		.gamma_lut_len = 1024,
+		.cubic_lut_len = 729, /* 9x9x9 */
+		.max_output = { 2560, 1600 },
+		/* win layer_mix hdr  */
+		.pre_scan_max_dly = { 10, 6, 0, 0 },
+		.offset = 0xd00,
+		.pixel_rate = 1,
+	}, {
+		.id = 2,
+		.gamma_lut_len = 1024,
+		.max_output = { 1920, 1080 },
+		/* win layer_mix hdr  */
+		.pre_scan_max_dly = { 10, 6, 0, 0 },
+		.offset = 0xe00,
+		.pixel_rate = 1,
+	},
+};
+
+/*
+ * rk3576 vop with 2 cluster, 4 esmart win.
+ * Every cluster can work as 4K win or split into two 2K win.
+ * All win in cluster support AFBCD.
+ *
+ * Every esmart win support 4 Multi-region.
+ *
+ * VP0 can use Cluster0/1 and Esmart0/2
+ * VP1 can use Cluster0/1 and Esmart1/3
+ * VP2 can use Esmart0/1/2/3
+ *
+ * Scale filter mode:
+ *
+ * * Cluster:
+ * * Support prescale down:
+ * * H/V: gt2/avg2 or gt4/avg4
+ * * After prescale down:
+ *	* nearest-neighbor/bilinear/multi-phase filter for scale up
+ *	* nearest-neighbor/bilinear/multi-phase filter for scale down
+ *
+ * * Esmart:
+ * * Support prescale down:
+ * * H: gt2/avg2 or gt4/avg4
+ * * V: gt2 or gt4
+ * * After prescale down:
+ *	* nearest-neighbor/bilinear/bicubic for scale up
+ *	* nearest-neighbor/bilinear for scale down
+ *
+ * AXI config::
+ *
+ * * Cluster0 win0: 0xa,  0xb       [AXI0]
+ * * Cluster0 win1: 0xc,  0xd       [AXI0]
+ * * Cluster1 win0: 0x6,  0x7       [AXI0]
+ * * Cluster1 win1: 0x8,  0x9       [AXI0]
+ * * Esmart0:       0x10, 0x11      [AXI0]
+ * * Esmart1:       0x12, 0x13      [AXI0]
+ * * Esmart2:       0xa,  0xb       [AXI1]
+ * * Esmart3:       0xc,  0xd       [AXI1]
+ * * Lut dma rid:   0x1,  0x2,  0x3 [AXI0]
+ * * DCI dma rid:   0x4             [AXI0]
+ * * Metadata rid:  0x5             [AXI0]
+ *
+ * * Limit:
+ * * (1) Cluster0/1 are fixed on AXI0 by IC design
+ * * (2) 0x0 and 0xf can't be used;
+ * * (3) 5 Bits ID for eache axi bus
+ * * (3) cluster and lut/dci/metadata rid must smaller than 0xf,
+ * *     if Cluster rid is bigger than 0xf, VOP will dead at the
+ * *     system bandwidth very terrible scene.
+ */
+static const struct vop2_win_data rk3576_vop_win_data[] = {
+	{
+		.name = "Cluster0-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
+		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1),
+		.formats = formats_rk3576_cluster,
+		.nformats = ARRAY_SIZE(formats_rk3576_cluster),
+		.format_modifiers = format_modifiers_rk3576_afbc,
+		.layer_sel_id = { 0, 0, 0xf, 0xf },
+		.supported_rotations =  DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0xa,
+		.axi_uv_r_id = 0xb,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
 	}, {
-		.name = "Smart1-win0",
-		.phys_id = ROCKCHIP_VOP2_SMART1,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_smart,
-		.nformats = ARRAY_SIZE(formats_smart),
+		.name = "Cluster1-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
+		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1),
+		.formats = formats_rk3576_cluster,
+		.nformats = ARRAY_SIZE(formats_rk3576_cluster),
+		.format_modifiers = format_modifiers_rk3576_afbc,
+		.layer_sel_id = { 1, 1, 0xf, 0xf },
+		.supported_rotations =  DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+	}, {
+		.name = "Esmart0-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.base = 0x1800,
+		.possible_vp_mask = BIT(0) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
 		.format_modifiers = format_modifiers,
-		.base = 0x1e00,
-		.layer_sel_id = { 7, 7, 7, 0xf },
+		.layer_sel_id = { 2, 0xf, 0, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
-		.type = DRM_PLANE_TYPE_PRIMARY,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x10,
+		.axi_uv_r_id = 0x11,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
 	}, {
 		.name = "Esmart1-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART1,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_rk356x_esmart,
-		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
-		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = { 6, 6, 6, 0xf },
+		.possible_vp_mask = BIT(1) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
+		.format_modifiers = format_modifiers,
+		.layer_sel_id = { 0xf, 2, 1, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
-		.type = DRM_PLANE_TYPE_PRIMARY,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x12,
+		.axi_uv_r_id = 0x13,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
 	}, {
-		.name = "Esmart0-win0",
-		.phys_id = ROCKCHIP_VOP2_ESMART0,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_rk356x_esmart,
-		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
+		.name = "Esmart2-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART2,
+		.base = 0x1c00,
+		.possible_vp_mask = BIT(0) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
 		.format_modifiers = format_modifiers,
-		.base = 0x1800,
-		.layer_sel_id = { 2, 2, 2, 0xf },
+		.layer_sel_id = { 3, 0xf, 2, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
-		.type = DRM_PLANE_TYPE_PRIMARY,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
-	}, {
-		.name = "Cluster0-win0",
-		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
-		.base = 0x1000,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_cluster,
-		.nformats = ARRAY_SIZE(formats_cluster),
-		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = { 0, 0, 0, 0xf },
-		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
-					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
-		.max_upscale_factor = 4,
-		.max_downscale_factor = 4,
-		.dly = { 0, 27, 21 },
-		.type = DRM_PLANE_TYPE_OVERLAY,
-		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
 	}, {
-		.name = "Cluster1-win0",
-		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
-		.base = 0x1200,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_cluster,
-		.nformats = ARRAY_SIZE(formats_cluster),
-		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = { 1, 1, 1, 0xf },
-		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
-					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.name = "Esmart3-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART3,
+		.base = 0x1e00,
+		.possible_vp_mask = BIT(1) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
+		.format_modifiers = format_modifiers,
+		.layer_sel_id = { 0xf, 3, 3, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
-		.max_upscale_factor = 4,
-		.max_downscale_factor = 4,
-		.dly = { 0, 27, 21 },
-		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x0d,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
 	},
 };
 
-static const struct vop2_regs_dump rk3568_regs_dump[] = {
+static const struct vop2_regs_dump rk3576_regs_dump[] = {
 	{
 		.name = "SYS",
 		.base = RK3568_REG_CFG_DONE,
-		.size = 0x100,
+		.size = 0x200,
 		.en_reg  = 0,
 		.en_val = 0,
 		.en_mask = 0
 	}, {
-		.name = "OVL",
-		.base = RK3568_OVL_CTRL,
-		.size = 0x100,
+		.name = "OVL_SYS",
+		.base = RK3576_SYS_EXTRA_ALPHA_CTRL,
+		.size = 0x50,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "OVL_VP0",
+		.base = RK3576_OVL_CTRL(0),
+		.size = 0x80,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "OVL_VP1",
+		.base = RK3576_OVL_CTRL(1),
+		.size = 0x80,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "OVL_VP2",
+		.base = RK3576_OVL_CTRL(2),
+		.size = 0x80,
 		.en_reg = 0,
 		.en_val = 0,
 		.en_mask = 0,
@@ -471,18 +1006,17 @@ static const struct vop2_regs_dump rk3568_regs_dump[] = {
 		.en_reg = RK3568_VP_DSP_CTRL,
 		.en_val = 0,
 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
-
 	}, {
 		.name = "Cluster0",
 		.base = RK3568_CLUSTER0_CTRL_BASE,
-		.size = 0x110,
+		.size = 0x200,
 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
 	}, {
 		.name = "Cluster1",
 		.base = RK3568_CLUSTER1_CTRL_BASE,
-		.size = 0x110,
+		.size = 0x200,
 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
@@ -501,15 +1035,15 @@ static const struct vop2_regs_dump rk3568_regs_dump[] = {
 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 	}, {
-		.name = "Smart0",
-		.base = RK3568_SMART0_CTRL_BASE,
+		.name = "Esmart2",
+		.base = RK3588_ESMART2_CTRL_BASE,
 		.size = 0xf0,
 		.en_reg = RK3568_SMART_REGION0_CTRL,
 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 	}, {
-		.name = "Smart1",
-		.base = RK3568_SMART1_CTRL_BASE,
+		.name = "Esmart3",
+		.base = RK3588_ESMART3_CTRL_BASE,
 		.size = 0xf0,
 		.en_reg = RK3568_SMART_REGION0_CTRL,
 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
@@ -908,6 +1442,84 @@ static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32
 	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
 }
 
+static unsigned long rk3576_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
+	u8 port_pix_rate = vp->data->pixel_rate;
+	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_sel;
+	u32 ctrl, vp_clk_div, reg, dclk_div;
+	unsigned long dclk_in_rate, dclk_core_rate;
+
+	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420 || adjusted_mode->crtc_clock > 600000)
+		dclk_div = 2;
+	else
+		dclk_div = 1;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
+		dclk_core_rate = adjusted_mode->crtc_clock / 2;
+	else
+		dclk_core_rate = adjusted_mode->crtc_clock / port_pix_rate;
+
+	dclk_in_rate = adjusted_mode->crtc_clock / dclk_div;
+
+	dclk_core_div = dclk_in_rate > dclk_core_rate ? 1 : 0;
+
+	if (vop2_output_if_is_edp(id))
+		if_pixclk_div = port_pix_rate == 2 ? RK3576_DSP_IF_PCLK_DIV : 0;
+	else
+		if_pixclk_div = port_pix_rate == 1 ? RK3576_DSP_IF_PCLK_DIV : 0;
+
+	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420) {
+		if_dclk_sel = RK3576_DSP_IF_DCLK_SEL_OUT;
+		dclk_out_div = 1;
+	} else {
+		if_dclk_sel = 0;
+		dclk_out_div = 0;
+	}
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		reg = RK3576_HDMI0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		reg = RK3576_EDP0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		reg = RK3576_MIPI0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_DP0:
+		reg = RK3576_DP0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_DP1:
+		reg = RK3576_DP1_IF_CTRL;
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	ctrl = vop2_readl(vop2, reg);
+	ctrl &= ~RK3576_DSP_IF_DCLK_SEL_OUT;
+	ctrl &= ~RK3576_DSP_IF_PCLK_DIV;
+	ctrl &= ~RK3576_DSP_IF_MUX;
+	ctrl |= RK3576_DSP_IF_CFG_DONE_IMD;
+	ctrl |= if_dclk_sel | if_pixclk_div;
+	ctrl |= RK3576_DSP_IF_CLK_OUT_EN | RK3576_DSP_IF_EN;
+	ctrl |= FIELD_PREP(RK3576_DSP_IF_MUX, vp->id);
+	ctrl |= FIELD_PREP(RK3576_DSP_IF_PIN_POL, polflags);
+	vop2_writel(vop2, reg, ctrl);
+
+	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
+	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
+
+	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
+
+	return dclk_in_rate * 1000LL;
+}
+
 /*
  * calc the dclk on rk3588
  * the available div of dclk is 1, 2, 4
@@ -1246,6 +1858,7 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi
 	struct drm_plane_state *bottom_win_pstate;
 	bool src_pixel_alpha_en = false;
 	u16 src_glb_alpha_val, dst_glb_alpha_val;
+	u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg;
 	u32 offset = 0;
 	bool premulti_en = false;
 	bool swap = false;
@@ -1283,14 +1896,22 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi
 		break;
 	}
 
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
-		    alpha.src_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
-		    alpha.dst_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
-		    alpha.src_alpha_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
-		    alpha.dst_alpha_ctrl.val);
+	if (vop2->version <= VOP_VERSION_RK3588) {
+		src_color_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL;
+		dst_color_ctrl_reg = RK3568_CLUSTER0_MIX_DST_COLOR_CTRL;
+		src_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL;
+		dst_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL;
+	} else {
+		src_color_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_COLOR_CTRL;
+		dst_color_ctrl_reg = RK3576_CLUSTER0_MIX_DST_COLOR_CTRL;
+		src_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_ALPHA_CTRL;
+		dst_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_DST_ALPHA_CTRL;
+	}
+
+	vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val);
+	vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val);
+	vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val);
+	vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val);
 }
 
 static void vop2_setup_alpha(struct vop2_video_port *vp)
@@ -1303,11 +1924,16 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 	int pixel_alpha_en;
 	int premulti_en, gpremulti_en = 0;
 	int mixer_id;
+	u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg;
 	u32 offset;
 	bool bottom_layer_alpha_en = false;
 	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
 
-	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	if (vop2->version <= VOP_VERSION_RK3588)
+		mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	else
+		mixer_id = 0;
+
 	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
 
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
@@ -1326,6 +1952,18 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 		}
 	}
 
+	if (vop2->version <= VOP_VERSION_RK3588) {
+		src_color_ctrl_reg = RK3568_MIX0_SRC_COLOR_CTRL;
+		dst_color_ctrl_reg = RK3568_MIX0_DST_COLOR_CTRL;
+		src_alpha_ctrl_reg = RK3568_MIX0_SRC_ALPHA_CTRL;
+		dst_alpha_ctrl_reg = RK3568_MIX0_DST_ALPHA_CTRL;
+	} else {
+		src_color_ctrl_reg = RK3576_OVL_MIX0_SRC_COLOR_CTRL(vp->id);
+		dst_color_ctrl_reg = RK3576_OVL_MIX0_DST_COLOR_CTRL(vp->id);
+		src_alpha_ctrl_reg = RK3576_OVL_MIX0_SRC_ALPHA_CTRL(vp->id);
+		dst_alpha_ctrl_reg = RK3576_OVL_MIX0_DST_ALPHA_CTRL(vp->id);
+	}
+
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
 		struct vop2_win *win = to_vop2_win(plane);
 		int zpos = plane->state->normalized_zpos;
@@ -1372,17 +2010,26 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 		vop2_parse_alpha(&alpha_config, &alpha);
 
 		offset = (mixer_id + zpos - 1) * 0x10;
-		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
-			    alpha.src_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
-			    alpha.dst_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
-			    alpha.src_alpha_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
-			    alpha.dst_alpha_ctrl.val);
+
+		vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val);
+		vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val);
+		vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val);
+		vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val);
 	}
 
 	if (vp->id == 0) {
+		if (vop2->version <= VOP_VERSION_RK3588) {
+			src_color_ctrl_reg = RK3568_HDR0_SRC_COLOR_CTRL;
+			dst_color_ctrl_reg = RK3568_HDR0_DST_COLOR_CTRL;
+			src_alpha_ctrl_reg = RK3568_HDR0_SRC_ALPHA_CTRL;
+			dst_alpha_ctrl_reg = RK3568_HDR0_DST_ALPHA_CTRL;
+		} else {
+			src_color_ctrl_reg = RK3576_OVL_HDR_SRC_COLOR_CTRL(vp->id);
+			dst_color_ctrl_reg = RK3576_OVL_HDR_DST_COLOR_CTRL(vp->id);
+			src_alpha_ctrl_reg = RK3576_OVL_HDR_SRC_ALPHA_CTRL(vp->id);
+			dst_alpha_ctrl_reg = RK3576_OVL_HDR_DST_ALPHA_CTRL(vp->id);
+		}
+
 		if (bottom_layer_alpha_en) {
 			/* Transfer pixel alpha to hdr mix */
 			alpha_config.src_premulti_en = gpremulti_en;
@@ -1390,18 +2037,15 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 			alpha_config.src_pixel_alpha_en = true;
 			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
 			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+
 			vop2_parse_alpha(&alpha_config, &alpha);
 
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
-				    alpha.src_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
-				    alpha.dst_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
-				    alpha.src_alpha_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
-				    alpha.dst_alpha_ctrl.val);
+			vop2_writel(vop2, src_color_ctrl_reg, alpha.src_color_ctrl.val);
+			vop2_writel(vop2, dst_color_ctrl_reg, alpha.dst_color_ctrl.val);
+			vop2_writel(vop2, src_alpha_ctrl_reg, alpha.src_alpha_ctrl.val);
+			vop2_writel(vop2, dst_alpha_ctrl_reg, alpha.dst_alpha_ctrl.val);
 		} else {
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
+			vop2_writel(vop2, src_color_ctrl_reg, 0);
 		}
 	}
 }
@@ -1611,6 +2255,72 @@ static void rk3568_vop2_setup_overlay(struct vop2_video_port *vp)
 	rk3568_vop2_setup_dly_for_windows(vp);
 }
 
+static void rk3576_vop2_setup_layer_mixer(struct vop2_video_port *vp)
+{
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_plane *plane;
+	u32 layer_sel = 0xffff; /* 0xf means this layer is disabled */
+	u32 ovl_ctrl;
+
+	ovl_ctrl = vop2_readl(vop2, RK3576_OVL_CTRL(vp->id));
+	if (vcstate->yuv_overlay)
+		ovl_ctrl |= RK3576_OVL_CTRL__YUV_MODE;
+	else
+		ovl_ctrl &= ~RK3576_OVL_CTRL__YUV_MODE;
+
+	vop2_writel(vop2, RK3576_OVL_CTRL(vp->id), ovl_ctrl);
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos,
+							  0xf);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos,
+							 win->data->layer_sel_id[vp->id]);
+	}
+
+	vop2_writel(vop2, RK3576_OVL_LAYER_SEL(vp->id), layer_sel);
+}
+
+static void rk3576_vop2_setup_dly_for_windows(struct vop2_video_port *vp)
+{
+	struct drm_plane *plane;
+	struct vop2_win *win;
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		win = to_vop2_win(plane);
+		vop2_win_write(win, VOP2_WIN_DLY_NUM, 0);
+	}
+}
+
+static void rk3576_vop2_setup_overlay(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_plane *plane;
+
+	vp->win_mask = 0;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
+
+		vp->win_mask |= BIT(win->data->phys_id);
+
+		if (vop2_cluster_window(win))
+			vop2_setup_cluster_alpha(vop2, win);
+	}
+
+	if (!vp->win_mask)
+		return;
+
+	rk3576_vop2_setup_layer_mixer(vp);
+	vop2_setup_alpha(vp);
+	rk3576_vop2_setup_dly_for_windows(vp);
+}
+
 static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
 {
 	struct drm_crtc *crtc = &vp->crtc;
@@ -1628,12 +2338,38 @@ static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
 	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
 }
 
+static void rk3576_vop2_setup_bg_dly(struct vop2_video_port *vp)
+{
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	u16 hdisplay = mode->crtc_hdisplay;
+	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+	u32 bg_dly;
+	u32 pre_scan_dly;
+
+	bg_dly = vp->data->pre_scan_max_dly[VOP2_DLY_WIN] +
+		 vp->data->pre_scan_max_dly[VOP2_DLY_LAYER_MIX] +
+		 vp->data->pre_scan_max_dly[VOP2_DLY_HDR_MIX];
+
+	vop2_writel(vp->vop2, RK3576_OVL_BG_MIX_CTRL(vp->id),
+		    FIELD_PREP(RK3576_OVL_BG_MIX_CTRL__BG_DLY, bg_dly));
+
+	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
+	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+}
+
 static const struct vop2_ops rk3568_vop_ops = {
 	.setup_intf_mux = rk3568_set_intf_mux,
 	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
 	.setup_overlay = rk3568_vop2_setup_overlay,
 };
 
+static const struct vop2_ops rk3576_vop_ops = {
+	.setup_intf_mux = rk3576_set_intf_mux,
+	.setup_bg_dly = rk3576_vop2_setup_bg_dly,
+	.setup_overlay = rk3576_vop2_setup_overlay,
+};
+
 static const struct vop2_ops rk3588_vop_ops = {
 	.setup_intf_mux = rk3588_set_intf_mux,
 	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
@@ -1678,6 +2414,25 @@ static const struct vop2_data rk3568_vop = {
 	.soc_id = 3568,
 };
 
+static const struct vop2_data rk3576_vop = {
+	.version = VOP_VERSION_RK3576,
+	.feature = VOP2_FEATURE_HAS_SYS_PMU,
+	.nr_vps = 3,
+	.max_input = { 4096, 4320 },
+	.max_output = { 4096, 4320 },
+	.vp = rk3576_vop_video_ports,
+	.win = rk3576_vop_win_data,
+	.win_size = ARRAY_SIZE(rk3576_vop_win_data),
+	.cluster_reg = rk3576_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3576_vop_cluster_regs),
+	.smart_reg = rk3576_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3576_vop_smart_regs),
+	.regs_dump = rk3576_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3576_regs_dump),
+	.ops = &rk3576_vop_ops,
+	.soc_id = 3576,
+};
+
 static const struct vop2_data rk3588_vop = {
 	.version = VOP_VERSION_RK3588,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
@@ -1705,6 +2460,9 @@ static const struct of_device_id vop2_dt_match[] = {
 	}, {
 		.compatible = "rockchip,rk3568-vop",
 		.data = &rk3568_vop,
+	}, {
+		.compatible = "rockchip,rk3576-vop",
+		.data = &rk3576_vop,
 	}, {
 		.compatible = "rockchip,rk3588-vop",
 		.data = &rk3588_vop
-- 
2.34.1



From andyshrk at 163.com  Mon Dec  9 04:36:34 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon, 9 Dec 2024 20:36:34 +0800 (CST)
Subject: [PATCH] arm64: dts: rockchip: Add vop for rk3576
In-Reply-To: <20241209122943.2781431-2-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209122943.2781431-2-andyshrk@163.com>
Message-ID: <34ce9ef5.ba77.193ab6be398.Coremail.andyshrk@163.com>


Sorry, please ignore this patch.

At 2024-12-09 20:29:11, "Andy Yan" <andyshrk at 163.com> wrote:
>From: Andy Yan <andy.yan at rock-chips.com>
>
>Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>---
> arch/arm64/boot/dts/rockchip/rk3576.dtsi | 70 +++++++++++++++++++++++-
> 1 file changed, 69 insertions(+), 1 deletion(-)
>
>diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
>index 70ddedb0c890..45823a758b6e 100644
>--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
>+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
>@@ -393,6 +393,11 @@ opp-950000000 {
> 		};
> 	};
> 
>+	display_subsystem: display-subsystem {
>+		compatible = "rockchip,display-subsystem";
>+		ports = <&vop_out>;
>+	};
>+
> 	firmware {
> 		scmi: scmi {
> 			compatible = "arm,scmi-smc";
>@@ -832,6 +837,70 @@ gpu: gpu at 27800000 {
> 			status = "disabled";
> 		};
> 
>+		vop: vop at 27d00000 {
>+			compatible = "rockchip,rk3576-vop";
>+			reg = <0x0 0x27d00000 0x0 0x3000>, <0x0 0x27d05000 0x0 0x1000>;
>+			reg-names = "vop", "gamma-lut";
>+			interrupts = <GIC_SPI 342 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>;
>+			interrupt-names = "vop-sys",
>+					  "vop-vp0",
>+					  "vop-vp1",
>+					  "vop-vp2";
>+			clocks = <&cru ACLK_VOP>,
>+				 <&cru HCLK_VOP>,
>+				 <&cru DCLK_VP0>,
>+				 <&cru DCLK_VP1>,
>+				 <&cru DCLK_VP2>;
>+			clock-names = "aclk",
>+				      "hclk",
>+				      "dclk_vp0",
>+				      "dclk_vp1",
>+				      "dclk_vp2";
>+			iommus = <&vop_mmu>;
>+			power-domains = <&power RK3576_PD_VOP>;
>+			rockchip,grf = <&sys_grf>;
>+			rockchip,pmu = <&pmu>;
>+			status = "disabled";
>+
>+			vop_out: ports {
>+				#address-cells = <1>;
>+				#size-cells = <0>;
>+
>+				vp0: port at 0 {
>+					#address-cells = <1>;
>+					#size-cells = <0>;
>+					reg = <0>;
>+				};
>+
>+				vp1: port at 1 {
>+					#address-cells = <1>;
>+					#size-cells = <0>;
>+					reg = <1>;
>+				};
>+
>+				vp2: port at 2 {
>+					#address-cells = <1>;
>+					#size-cells = <0>;
>+					reg = <2>;
>+				};
>+			};
>+		};
>+
>+		vop_mmu: iommu at 27d07e00 {
>+			compatible = "rockchip,rk3576-iommu", "rockchip,rk3568-iommu";
>+			reg = <0x0 0x27d07e00 0x0 0x100>, <0x0 0x27d07f00 0x0 0x100>;
>+			interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>;
>+			interrupt-names = "vop_mmu";
>+			clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
>+			clock-names = "aclk", "iface";
>+			#iommu-cells = <0>;
>+			power-domains = <&power RK3576_PD_VOP>;
>+			status = "disabled";
>+		};
>+
> 		hdmi: hdmi at 27da0000 {
> 			compatible = "rockchip,rk3576-dw-hdmi-qp";
> 			reg = <0x0 0x27da0000 0x0 0x20000>;
>@@ -873,7 +942,6 @@ hdmi_out: port at 1 {
> 			};
> 		};
> 
>->>>>>>> 2b62c69b3a4c (arm64: dts: rockchip: Add hdmi for rk3576)
> 		qos_hdcp1: qos at 27f02000 {
> 			compatible = "rockchip,rk3576-qos", "syscon";
> 			reg = <0x0 0x27f02000 0x0 0x20>;
>-- 
>2.34.1

From broonie at kernel.org  Mon Dec  9 04:36:52 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 9 Dec 2024 12:36:52 +0000
Subject: [PATCH] kselftest/arm64: abi: fix SVCR detection
In-Reply-To: <20241209105237.10498-1-o451686892@gmail.com>
References: <20241209105237.10498-1-o451686892@gmail.com>
Message-ID: <3279e669-1ee2-4792-9e10-8b40928de6b4@sirena.org.uk>

On Mon, Dec 09, 2024 at 06:52:37PM +0800, Weizhao Ouyang wrote:

> When using svcr_in to check ZA and Streaming Mode, we should make sure
> that the value in x2 is correct, otherwise it may trigger an Illegal
> instruction if FEAT_SVE and !FEAT_SME.

>  	// Set SVCR if we're doing SME
> -	cbz	x1, 1f
>  	adrp	x2, svcr_in
>  	ldr	x2, [x2, :lo12:svcr_in]
> +	cbz	x1, 1f
>  	msr	S3_3_C4_C2_2, x2

This is against an older verison of the code so wouldn't apply now.
It's not also checking the value of SVCR, this is checking the SME flag
passed in via x1.  You can see that the SVCR value is loaded into x2 but
the check is against x1.
-------------- 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/20241209/9f228bdf/attachment.sig>

From andyshrk at 163.com  Mon Dec  9 04:37:16 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon, 9 Dec 2024 20:37:16 +0800 (CST)
Subject: [PATCH] arm64: dts: rockchip: Enable HDMI display for rk3588
 Cool Pi GenBook
In-Reply-To: <20241209122943.2781431-3-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209122943.2781431-3-andyshrk@163.com>
Message-ID: <5818dffa.ba85.193ab6c868c.Coremail.andyshrk@163.com>


Sorry, please ignore this patch.

At 2024-12-09 20:29:12, "Andy Yan" <andyshrk at 163.com> wrote:
>Enable hdmi display output on Cool Pi GenBook.
>
>Signed-off-by: Andy Yan <andyshrk at 163.com>
>Link: https://lore.kernel.org/r/20241028123503.384866-4-andyshrk at 163.com
>Signed-off-by: Heiko Stuebner <heiko at sntech.de>
>---
> .../rockchip/rk3588-coolpi-cm5-genbook.dts    | 49 +++++++++++++++++++
> 1 file changed, 49 insertions(+)
>
>diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
>index 6418286efe40d..9ec2374c6cdfa 100644
>--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
>+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
>@@ -7,6 +7,7 @@
> /dts-v1/;
> 
> #include <dt-bindings/leds/common.h>
>+#include <dt-bindings/soc/rockchip,vop2.h>
> #include "rk3588-coolpi-cm5.dtsi"
> 
> / {
>@@ -35,6 +36,17 @@ charger: dc-charger {
> 		gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
> 	};
> 
>+	hdmi-con {
>+		compatible = "hdmi-connector";
>+		type = "a";
>+
>+		port {
>+			hdmi_con_in: endpoint {
>+				remote-endpoint = <&hdmi0_out_con>;
>+			};
>+		};
>+	};
>+
> 	leds: leds {
> 		compatible = "gpio-leds";
> 
>@@ -136,6 +148,28 @@ vcc5v0_usb_host0: vcc5v0_usb30_host: vcc5v0-usb-host-regulator {
> 	};
> };
> 
>+/* HDMI CEC is not used */
>+&hdmi0 {
>+	pinctrl-0 = <&hdmim0_tx0_hpd &hdmim0_tx0_scl &hdmim0_tx0_sda>;
>+	status = "okay";
>+};
>+
>+&hdmi0_in {
>+	hdmi0_in_vp0: endpoint {
>+		remote-endpoint = <&vp0_out_hdmi0>;
>+	};
>+};
>+
>+&hdmi0_out {
>+	hdmi0_out_con: endpoint {
>+		remote-endpoint = <&hdmi_con_in>;
>+	};
>+};
>+
>+&hdptxphy_hdmi0 {
>+	status = "okay";
>+};
>+
> &i2c4 {
> 	status = "okay";
> 	pinctrl-names = "default";
>@@ -347,3 +381,18 @@ &usb_host1_xhci {
> 	dr_mode = "host";
> 	status = "okay";
> };
>+
>+&vop {
>+	status = "okay";
>+};
>+
>+&vop_mmu {
>+	status = "okay";
>+};
>+
>+&vp0 {
>+	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
>+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
>+		remote-endpoint = <&hdmi0_in_vp0>;
>+	};
>+};
>-- 
>2.34.1

From lkp at intel.com  Mon Dec  9 04:36:27 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Dec 2024 20:36:27 +0800
Subject: [PATCH] mm/execmem: Make ARCH_WANTS_EXECMEM_LATE depend on
 EXECMEM
In-Reply-To: <20241209031251.515903-1-anshuman.khandual@arm.com>
References: <20241209031251.515903-1-anshuman.khandual@arm.com>
Message-ID: <202412092048.tTzJ5szH-lkp@intel.com>

Hi Anshuman,

kernel test robot noticed the following build warnings:

[auto build test WARNING on akpm-mm/mm-everything]

url:    https://github.com/intel-lab-lkp/linux/commits/Anshuman-Khandual/mm-execmem-Make-ARCH_WANTS_EXECMEM_LATE-depend-on-EXECMEM/20241209-111533
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20241209031251.515903-1-anshuman.khandual%40arm.com
patch subject: [PATCH] mm/execmem: Make ARCH_WANTS_EXECMEM_LATE depend on EXECMEM
config: arm64-kismet-CONFIG_ARCH_WANTS_EXECMEM_LATE-CONFIG_ARM64-0-0 (https://download.01.org/0day-ci/archive/20241209/202412092048.tTzJ5szH-lkp at intel.com/config)
reproduce: (https://download.01.org/0day-ci/archive/20241209/202412092048.tTzJ5szH-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/202412092048.tTzJ5szH-lkp at intel.com/

kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for ARCH_WANTS_EXECMEM_LATE when selected by ARM64
   WARNING: unmet direct dependencies detected for ARCH_WANTS_EXECMEM_LATE
     Depends on [n]: EXECMEM [=n]
     Selected by [y]:
     - ARM64 [=y]

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


From broonie at kernel.org  Mon Dec  9 05:12:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 9 Dec 2024 13:12:53 +0000
Subject: [PATCH] kselftest/arm64: abi: fix SVCR detection
In-Reply-To: <CAHk0Hov5k37=MtTBLWTj+Dwm4EXE0xGJS1Uc8xgyLtJxusqsww@mail.gmail.com>
References: <20241209105237.10498-1-o451686892@gmail.com>
 <3279e669-1ee2-4792-9e10-8b40928de6b4@sirena.org.uk>
 <CAHk0Hov5k37=MtTBLWTj+Dwm4EXE0xGJS1Uc8xgyLtJxusqsww@mail.gmail.com>
Message-ID: <c05f6ad8-2dc1-4ddb-b9c1-b2cddfe78819@sirena.org.uk>

On Mon, Dec 09, 2024 at 08:51:28PM +0800, Weizhao Ouyang wrote:
> On Mon, Dec 9, 2024 at 8:36?PM Mark Brown <broonie at kernel.org> wrote:

> > >       // Set SVCR if we're doing SME
> > > -     cbz     x1, 1f
> > >       adrp    x2, svcr_in
> > >       ldr     x2, [x2, :lo12:svcr_in]
> > > +     cbz     x1, 1f
> > >       msr     S3_3_C4_C2_2, x2

> > This is against an older verison of the code so wouldn't apply now.
> > It's not also checking the value of SVCR, this is checking the SME flag
> > the check is against x1.

> This patch aims to fix the second check (SVCR_ZA_SHIFT) instead of
> the first one (the x1 SME flag you're referring to):

If we don't have SME we should be skipping over all the SME code and
never even looking at the value of SVCR.  Looking at the current version
of the code it does that, it branches to check_sve_in if SME is not
enabled.
-------------- 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/20241209/f41466bc/attachment.sig>

From ardb at kernel.org  Mon Dec  9 05:18:09 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 9 Dec 2024 14:18:09 +0100
Subject: [PATCH v2 1/6] arm64/mm: Reduce PA space to 48 bits when LPA2 is
 not enabled
In-Reply-To: <20241205150229.3510177-9-ardb+git@google.com>
References: <20241205150229.3510177-8-ardb+git@google.com> <20241205150229.3510177-9-ardb+git@google.com>
Message-ID: <CAMj1kXFUVS_TdQb_Q_ta1BfSMUnAtB7zJpxDDtkFX6Q3tiUtcA@mail.gmail.com>

On Thu, 5 Dec 2024 at 16:03, Ard Biesheuvel <ardb+git at google.com> wrote:
>
> From: Ard Biesheuvel <ardb at kernel.org>
>
> Currently, LPA2 kernel support implies support for up to 52 bits of
> physical addressing, and this is reflected in global definitions such as
> PHYS_MASK_SHIFT and MAX_PHYSMEM_BITS.
>
> This is potentially problematic, given that LPA2 hardware support is
> modeled as a CPU feature which can be overridden, and with LPA2 hardware
> support turned off, attempting to map physical regions with address bits
> [51:48] set (which may exist on LPA2 capable systems booting with
> arm64.nolva) will result in corrupted mappings with a truncated output
> address and bogus shareability attributes.
>
> This means that the accepted physical address range in the mapping
> routines should be at most 48 bits wide when LPA2 support is configured
> but not enabled at runtime.
>
> Fixes: 352b0395b505 ("arm64: Enable 52-bit virtual addressing for 4k and 16k granule configs")
> Cc: <stable at vger.kernel.org>
> Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
>  arch/arm64/include/asm/pgtable-hwdef.h | 6 ------
>  arch/arm64/include/asm/pgtable-prot.h  | 7 +++++++
>  arch/arm64/include/asm/sparsemem.h     | 4 +++-
>  3 files changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> index c78a988cca93..a9136cc551cc 100644
> --- a/arch/arm64/include/asm/pgtable-hwdef.h
> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> @@ -222,12 +222,6 @@
>   */
>  #define S1_TABLE_AP            (_AT(pmdval_t, 3) << 61)
>
> -/*
> - * Highest possible physical address supported.
> - */
> -#define PHYS_MASK_SHIFT                (CONFIG_ARM64_PA_BITS)
> -#define PHYS_MASK              ((UL(1) << PHYS_MASK_SHIFT) - 1)
> -
>  #define TTBR_CNP_BIT           (UL(1) << 0)
>
>  /*
> diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
> index 9f9cf13bbd95..a95f1f77bb39 100644
> --- a/arch/arm64/include/asm/pgtable-prot.h
> +++ b/arch/arm64/include/asm/pgtable-prot.h
> @@ -81,6 +81,7 @@ extern unsigned long prot_ns_shared;
>  #define lpa2_is_enabled()      false
>  #define PTE_MAYBE_SHARED       PTE_SHARED
>  #define PMD_MAYBE_SHARED       PMD_SECT_S
> +#define PHYS_MASK_SHIFT                (CONFIG_ARM64_PA_BITS)
>  #else
>  static inline bool __pure lpa2_is_enabled(void)
>  {
> @@ -89,8 +90,14 @@ static inline bool __pure lpa2_is_enabled(void)
>
>  #define PTE_MAYBE_SHARED       (lpa2_is_enabled() ? 0 : PTE_SHARED)
>  #define PMD_MAYBE_SHARED       (lpa2_is_enabled() ? 0 : PMD_SECT_S)
> +#define PHYS_MASK_SHIFT                (lpa2_is_enabled() ? CONFIG_ARM64_PA_BITS : 48)
>  #endif
>
> +/*
> + * Highest possible physical address supported.
> + */
> +#define PHYS_MASK              ((UL(1) << PHYS_MASK_SHIFT) - 1)
> +
>  /*
>   * If we have userspace only BTI we don't want to mark kernel pages
>   * guarded even if the system does support BTI.
> diff --git a/arch/arm64/include/asm/sparsemem.h b/arch/arm64/include/asm/sparsemem.h
> index 8a8acc220371..035e0ca74e88 100644
> --- a/arch/arm64/include/asm/sparsemem.h
> +++ b/arch/arm64/include/asm/sparsemem.h
> @@ -5,7 +5,9 @@
>  #ifndef __ASM_SPARSEMEM_H
>  #define __ASM_SPARSEMEM_H
>
> -#define MAX_PHYSMEM_BITS       CONFIG_ARM64_PA_BITS
> +#include <asm/pgtable-prot.h>
> +
> +#define MAX_PHYSMEM_BITS       PHYS_MASK_SHIFT
>

This needs

--- a/arch/arm64/include/asm/sparsemem.h
+++ b/arch/arm64/include/asm/sparsemem.h
@@ -7,7 +7,8 @@

 #include <asm/pgtable-prot.h>

-#define MAX_PHYSMEM_BITS       PHYS_MASK_SHIFT
+#define MAX_PHYSMEM_BITS               PHYS_MASK_SHIFT
+#define MAX_POSSIBLE_PHYSMEM_BITS      (52)

 /*
  * Section size must be at least 512MB for 64K base

applied on top to make the ZSMALLOC code happy.


From maz at kernel.org  Mon Dec  9 05:20:48 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Dec 2024 13:20:48 +0000
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer expired
In-Reply-To: <c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
	<867c89tc4q.wl-maz@kernel.org>
	<c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
Message-ID: <865xntt2kv.wl-maz@kernel.org>

On Mon, 09 Dec 2024 12:25:34 +0000,
Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> >>
> >> During automated testing of Nested Virtualization using avocado-vt,
> > 
> > Which is not merged upstream. So what branch are you using? Based on
> > what kernel version? On what HW? With which virtualisation features?
> > 
> 
> Testing is done on Ampere's AmpereOne platform using 6.10 based kernel
> with NV patches from your repo.

Grmbl... *Which* patches? At least give me the SHA1 of the branch,
because I have no idea what you are running. And 6.10 is definitely
not something I care about. If you're using the NV patches, the
*minimum* you should run is 6.13-rc1, because that's what the current
code is based on.

Also, does this machine have FEAT_ECV?

> 
> >> it has been observed that during some boot test iterations,
> >> the Guest-Hypervisor boot was getting crashed with a
> >> synchronous exception while it is still booting EDK2.
> >> 
> >> The test is launching Multiple instances of Guest-Hypervisor boot
> > 
> > Is the multiple instance aspect really relevant to the reproduction of
> > the problem?
> 
> Not really, but it requires multiple attempts/iterations to hit the
> issue. Even with automated test, it was seen at some iteration out of
> 10 to 15 iterations.
> 
> > 
> >> and while booting, QEMU monitor issued the command "info register"
> >> at regular intervals to take a register dump. To execute this
> >> command, QEMU stops the run and does the register read of various
> >> registers. While resuming the run, the function kvm_arm_timer_write()
> >> writes back the saved CNTV_CTL_EL0 register with ISTATUS cleared always
> > 
> > It is userspace that causes this write-back, right? AFAICT, KVM never
> > does that on its own.
> > 
> >> and resulting in the loss of pending interrupt for emulated timers.
> > 
> > How does a missing interrupt result in a synchronous exception in
> > EDK2? In my experience, EDK2 panics if it sees spurious interrupts,
> > not when it is missing interrupts (it just locks up, which is
> > expected).
> 
> Not sure, why it is hitting exception, rather than hang at EDK2.
> However, EDK2 timer handler code is ignoring the interrupt since
> ISTATUS is not set and not moving CVAL forward.

How is EDK2 getting this exception? Is this injected by KVM? Or is
that some EDK2 bug?

> 
> > 
> >> In hardware based timers, ISTATUS is a RO/WI bit and gets set by the
> >> h/w, if the condition is still met. However, in Nested-Virtualization
> >> case, the Guest-Hypervisor's?EDK2 is using an emulated virtual timer
> >> and losing ISTATUS state and the interrupt forever.
> > 
> > Why is this specific to NV? Can't the same thing happen to the
> > physical timer in a non-VHE configuration?
> > 
> 
> You mean, emulated v-timer in non-VHE boot?

Emulated *physical* timer.

> It might impact non-VHE case as well, not tried though.

Can you please try?

[...]

> > But overall, this very much looks like it is only papering over the
> > real issue, which is that the *emulation* should regenerate the
> > pending bit, and not rely on the userspace interface.
> > 
> > As far as I can tell, we already correctly compute the status bit on
> > read (read_timer_ctl()), so the guest should always observe something
> > consistent when it traps. We also *never* use the status bit as an
> > input to the emulation, and always recompute it from scratch (it is
> > only there for the benefit of the guest or userspace).
> > 
> 
> For emulated timers, we are not asserting again by calling
> kvm_timer_update_irq in timer_emulate() until the level is down and
> ready for trigger again. This was done to fix high rate of spurious
> interrupts getting generated to V-Timer. Hence we are not able to
> recover, if once ISTATUS is lost.

Again, a trapping read should see the correct value, since we populate
that bit at read time.

> > So I can't see how upstream is broken in at the moment, and you need
> > to explain how this actually triggers. Ideally, with a standalone
> > reproducer or a selftest.
> 
> We could reproduce the issue with the simple test/script.
> On one shell, launch L1 using qemu with add-on option
> 
> "-monitor unix:gh_monitor,server,nowait
> 
> On another shell, while L1 boots and still in UEFI, run repeatedly the
> command (or put in a while 1 loop script)
> 
> "echo "info registers" | socat - unix-connect:gh_monitor >
> /tmp/info_registers"
> 
> With above steps we were able to hit the issue within few attempts.

That's not a standalone reproducer. QEMU doesn't support NV, and
kvmtool doesn't have this sort of interface. I was asking for a bit of
C code that I could run directly, not something that requires me to
drag even more experimental code.

So here's my current guess, since you don't give me the needed
information. For what you describe to happen, I can only see two
possibilities:

- either your HW doesn't have FEAT_ECV, in which case the guest
  directly reads from memory

- or you are running with something like this patch [1], and we serve
  the guest by reading from memory very early, without returning to
  the bulk of the emulation code

In either case, we only publish the updated status if the current IRQ
state is different from the computed output of the timer while
performing the emulation.

So if you were writing back a status bit set to 0 while the interrupt
was already pending, we'd deliver an interrupt, but not recompute the
status. The guest would consider the interrupt as spurious, not touch
the timer, and we'd never make forward progress. Rinse, repeat.

Assuming I got the analysis right, it would only be a matter of
hoisting the publication of the status into timer_emulate(), so that
it is made up to date on load.

Please give the fixup below a go.

	M.

[1] https://lore.kernel.org/all/20241202172134.384923-6-maz at kernel.org/

From 2bbd6f9b41a20ad573376c20c158ff3c12db5009 Mon Sep 17 00:00:00 2001
From: Marc Zyngier <maz at kernel.org>
Date: Mon, 9 Dec 2024 10:58:08 +0000
Subject: [PATCH] fixup! KVM: arm64: nv: Publish emulated timer interrupt state
 in the in-memory state

---
 arch/arm64/kvm/arch_timer.c | 32 +++++++++++++-------------------
 1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 895f09658ef83..91bda986c344b 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -432,25 +432,6 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
 {
 	int ret;
 
-	/*
-	 * Paper over NV2 brokenness by publishing the interrupt status
-	 * bit. This still results in a poor quality of emulation (guest
-	 * writes will have no effect until the next exit).
-	 *
-	 * But hey, it's fast, right?
-	 */
-	if (is_hyp_ctxt(vcpu) &&
-	    (timer_ctx == vcpu_vtimer(vcpu) || timer_ctx == vcpu_ptimer(vcpu))) {
-		u32 ctl = timer_get_ctl(timer_ctx);
-
-		if (new_level)
-			ctl |= ARCH_TIMER_CTRL_IT_STAT;
-		else
-			ctl &= ~ARCH_TIMER_CTRL_IT_STAT;
-
-		timer_set_ctl(timer_ctx, ctl);
-	}
-
 	timer_ctx->irq.level = new_level;
 	trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_irq(timer_ctx),
 				   timer_ctx->irq.level);
@@ -471,6 +452,19 @@ static void timer_emulate(struct arch_timer_context *ctx)
 
 	trace_kvm_timer_emulate(ctx, should_fire);
 
+	/*
+	 * Paper over NV2 brokenness by publishing the interrupt status
+	 * bit. This still results in a poor quality of emulation (guest
+	 * writes will have no effect until the next exit).
+	 *
+	 * But hey, it's fast, right?
+	 */
+	if (is_hyp_ctxt(ctx->vcpu)) {
+		unsigned long val = timer_get_ctl(ctx);
+		__assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &val, should_fire);
+		timer_set_ctl(ctx, val);
+	}
+
 	if (should_fire != ctx->irq.level) {
 		kvm_timer_update_irq(ctx->vcpu, should_fire, ctx);
 		return;
-- 
2.39.2


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


From tgamblin at baylibre.com  Mon Dec  9 05:22:53 2024
From: tgamblin at baylibre.com (Trevor Gamblin)
Date: Mon, 9 Dec 2024 08:22:53 -0500
Subject: [PATCH v3 2/2] pwm: Add Nuvoton MA35D1 PWM controller support
In-Reply-To: <20241206085501.2623772-3-cwweng.linux@gmail.com>
References: <20241206085501.2623772-1-cwweng.linux@gmail.com>
 <20241206085501.2623772-3-cwweng.linux@gmail.com>
Message-ID: <b7706ac1-340e-4520-97d3-f8a65de78beb@baylibre.com>


On 2024-12-06 03:55, Chi-Wen Weng wrote:
> This commit adds a generic PWM framework driver for Nuvoton MA35D1 PWM controller.
>
> Signed-off-by: Chi-Wen Weng <cwweng.linux at gmail.com>
Reviewed-by: Trevor Gamblin <tgamblin at baylibre.com>


From andrew at lunn.ch  Mon Dec  9 05:24:37 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 9 Dec 2024 14:24:37 +0100
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and
 MBa62xx carrier board Device Trees
In-Reply-To: <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
Message-ID: <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>

> +&cpsw_port1 {
> +	phy-mode = "rgmii-rxid";
> +	phy-handle = <&cpsw3g_phy0>;
> +};
> +
> +&cpsw_port2 {
> +	phy-mode = "rgmii-rxid";
> +	phy-handle = <&cpsw3g_phy3>;
> +};

rgmii-rxid is very odd.

> +
> +&cpsw3g_mdio {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_mdio1_pins>;
> +
> +	cpsw3g_phy0: ethernet-phy at 0 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <0x0>;
> +		reset-gpios = <&main_gpio1 11 GPIO_ACTIVE_LOW>;
> +		reset-assert-us = <1000>;
> +		reset-deassert-us = <1000>;
> +		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;

I guess this is the explanation.

What happens when you use rgmii-id, and don't have this delay here?
That would be normal.

	Andrew


From o451686892 at gmail.com  Mon Dec  9 05:26:01 2024
From: o451686892 at gmail.com (Weizhao Ouyang)
Date: Mon, 9 Dec 2024 21:26:01 +0800
Subject: [PATCH] kselftest/arm64: abi: fix SVCR detection
In-Reply-To: <c05f6ad8-2dc1-4ddb-b9c1-b2cddfe78819@sirena.org.uk>
References: <20241209105237.10498-1-o451686892@gmail.com> <3279e669-1ee2-4792-9e10-8b40928de6b4@sirena.org.uk>
 <CAHk0Hov5k37=MtTBLWTj+Dwm4EXE0xGJS1Uc8xgyLtJxusqsww@mail.gmail.com> <c05f6ad8-2dc1-4ddb-b9c1-b2cddfe78819@sirena.org.uk>
Message-ID: <CAHk0HotQ-=s+-FHh8pAOg10ivcRwqChG735qgDvuQd=4B1QQNA@mail.gmail.com>

On Mon, Dec 9, 2024 at 9:12?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Mon, Dec 09, 2024 at 08:51:28PM +0800, Weizhao Ouyang wrote:
> > On Mon, Dec 9, 2024 at 8:36?PM Mark Brown <broonie at kernel.org> wrote:
>
> > > >       // Set SVCR if we're doing SME
> > > > -     cbz     x1, 1f
> > > >       adrp    x2, svcr_in
> > > >       ldr     x2, [x2, :lo12:svcr_in]
> > > > +     cbz     x1, 1f
> > > >       msr     S3_3_C4_C2_2, x2
>
> > > This is against an older verison of the code so wouldn't apply now.
> > > It's not also checking the value of SVCR, this is checking the SME flag
> > > the check is against x1.
>
> > This patch aims to fix the second check (SVCR_ZA_SHIFT) instead of
> > the first one (the x1 SME flag you're referring to):
>
> If we don't have SME we should be skipping over all the SME code and
> never even looking at the value of SVCR.  Looking at the current version
> of the code it does that, it branches to check_sve_in if SME is not
> enabled.

Hi Mark,

Yes we should skip it, this is just a minor tweak based on the
current implementation, after all, we manually passed its value by
svcr_in.

Which latest code version are you referring to? I think check_sve_in
is in fp testcase, not in the abi testcase. (checked the -next tree)

BR,
Weizhao


From patchwork-bot+netdevbpf at kernel.org  Mon Dec  9 05:40:30 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Mon, 09 Dec 2024 13:40:30 +0000
Subject: [PATCH net 0/5] net: sparx5: misc fixes for sparx5 and lan969x
In-Reply-To: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
References: <20241205-sparx5-lan969x-misc-fixes-v1-0-575ff3d0b022@microchip.com>
Message-ID: <173375163050.50212.4642950609895270784.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net.git (main)
by David S. Miller <davem at davemloft.net>:

On Thu, 5 Dec 2024 14:54:23 +0100 you wrote:
> This series fixes various issues in the Sparx5 and lan969x drivers. Most
> of the fixes are for new issues introduced by the recent series adding
> lan969x switch support in the Sparx5 driver.
> 
> Most notable is patch 1/5 that moves the lan969x dir into the sparx5
> dir, in order to address a cyclic dependency issue reported by depmod,
> when installing modules. Details are in the commit descriptions.
> 
> [...]

Here is the summary with links:
  - [net,1/5] net: lan969x: fix cyclic dependency reported by depmod
    https://git.kernel.org/netdev/net/c/1cd7523f4baa
  - [net,2/5] net: lan969x: fix the use of spin_lock in PTP handler
    https://git.kernel.org/netdev/net/c/aa5fc889844f
  - [net,3/5] net: sparx5: fix FDMA performance issue
    https://git.kernel.org/netdev/net/c/f004f2e535e2
  - [net,4/5] net: sparx5: fix default value of monitor ports
    https://git.kernel.org/netdev/net/c/e4d505fda6c8
  - [net,5/5] net: sparx5: fix the maximum frame length register
    https://git.kernel.org/netdev/net/c/ddd7ba006078

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From ansuelsmth at gmail.com  Mon Dec  9 05:44:21 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:21 +0100
Subject: [net-next PATCH v11 4/9] dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241209134459.27110-5-ansuelsmth@gmail.com>

Document support for Airoha AN8855 Switch SoC. This SoC expose various
peripherals like an Ethernet Switch, a NVMEM provider and Ethernet PHYs.

It does also support i2c and timers but those are not currently
supported/used.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 .../bindings/mfd/airoha,an8855-mfd.yaml       | 178 ++++++++++++++++++
 MAINTAINERS                                   |   1 +
 2 files changed, 179 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml

diff --git a/Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml b/Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
new file mode 100644
index 000000000000..9ad03499fabb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
@@ -0,0 +1,178 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/airoha,an8855-mfd.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 Switch SoC
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description: >
+  Airoha AN8855 Switch is a SoC that expose various peripherals like an
+  Ethernet Switch, a NVMEM provider and Ethernet PHYs.
+
+  It does also support i2c and timers but those are not currently
+  supported/used.
+
+properties:
+  compatible:
+    const: airoha,an8855-mfd
+
+  reg:
+    maxItems: 1
+
+  efuse:
+    type: object
+    $ref: /schemas/nvmem/airoha,an8855-efuse.yaml
+    description:
+      EFUSE exposed by the Airoha AN8855 Switch. This child node definition
+      should follow the bindings specified in
+      Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
+
+  ethernet-switch:
+    type: object
+    $ref: /schemas/net/dsa/airoha,an8855-switch.yaml
+    description:
+      Switch exposed by the Airoha AN8855 Switch. This child node definition
+      should follow the bindings specified in
+      Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
+
+  mdio:
+    type: object
+    $ref: /schemas/net/airoha,an8855-mdio.yaml
+    description:
+      MDIO exposed by the Airoha AN8855 Switch. This child node definition
+      should follow the bindings specified in
+      Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    mdio {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        mfd at 1 {
+            compatible = "airoha,an8855-mfd";
+            reg = <1>;
+
+            efuse {
+                compatible = "airoha,an8855-efuse";
+
+                #nvmem-cell-cells = <0>;
+
+                nvmem-layout {
+                    compatible = "fixed-layout";
+                    #address-cells = <1>;
+                    #size-cells = <1>;
+
+                    shift_sel_port0_tx_a: shift-sel-port0-tx-a at c {
+                       reg = <0xc 0x4>;
+                    };
+
+                    shift_sel_port0_tx_b: shift-sel-port0-tx-b at 10 {
+                        reg = <0x10 0x4>;
+                    };
+
+                    shift_sel_port0_tx_c: shift-sel-port0-tx-c at 14 {
+                        reg = <0x14 0x4>;
+                    };
+
+                    shift_sel_port0_tx_d: shift-sel-port0-tx-d at 18 {
+                       reg = <0x18 0x4>;
+                    };
+
+                    shift_sel_port1_tx_a: shift-sel-port1-tx-a at 1c {
+                        reg = <0x1c 0x4>;
+                    };
+
+                    shift_sel_port1_tx_b: shift-sel-port1-tx-b at 20 {
+                        reg = <0x20 0x4>;
+                    };
+
+                    shift_sel_port1_tx_c: shift-sel-port1-tx-c at 24 {
+                       reg = <0x24 0x4>;
+                    };
+
+                    shift_sel_port1_tx_d: shift-sel-port1-tx-d at 28 {
+                        reg = <0x28 0x4>;
+                    };
+                };
+            };
+
+            ethernet-switch {
+                compatible = "airoha,an8855-switch";
+
+                reset-gpios = <&pio 39 0>;
+
+                airoha,ext-surge;
+
+                ports {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+
+                    port at 0 {
+                        reg = <0>;
+                        label = "lan1";
+                        phy-mode = "internal";
+                        phy-handle = <&internal_phy1>;
+                    };
+
+                    port at 1 {
+                        reg = <1>;
+                        label = "lan2";
+                        phy-mode = "internal";
+                        phy-handle = <&internal_phy2>;
+                    };
+
+                    port at 5 {
+                        reg = <5>;
+                        label = "cpu";
+                        ethernet = <&gmac0>;
+                        phy-mode = "2500base-x";
+
+                        fixed-link {
+                            speed = <2500>;
+                            full-duplex;
+                            pause;
+                        };
+                    };
+                };
+            };
+
+            mdio {
+                compatible = "airoha,an8855-mdio";
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                internal_phy1: phy at 1 {
+                  reg = <1>;
+
+                  nvmem-cells = <&shift_sel_port0_tx_a>,
+                      <&shift_sel_port0_tx_b>,
+                      <&shift_sel_port0_tx_c>,
+                      <&shift_sel_port0_tx_d>;
+                  nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+
+                internal_phy2: phy at 2 {
+                  reg = <2>;
+
+                  nvmem-cells = <&shift_sel_port1_tx_a>,
+                      <&shift_sel_port1_tx_b>,
+                      <&shift_sel_port1_tx_c>,
+                      <&shift_sel_port1_tx_d>;
+                  nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index fd37e829fab5..f3e3f6938824 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -717,6 +717,7 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
 L:	netdev at vger.kernel.org
 S:	Maintained
+F:	Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
 F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
-- 
2.45.2



From ansuelsmth at gmail.com  Mon Dec  9 05:44:22 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:22 +0100
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha AN8855 Switch MFD
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241209134459.27110-6-ansuelsmth@gmail.com>

Add support for Airoha AN8855 Switch MFD that provide support for a DSA
switch and a NVMEM provider. Also provide support for a virtual MDIO
passthrough as the PHYs address for the switch are shared with the switch
address

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                           |   1 +
 drivers/mfd/Kconfig                   |  10 +
 drivers/mfd/Makefile                  |   1 +
 drivers/mfd/airoha-an8855.c           | 278 ++++++++++++++++++++++++++
 include/linux/mfd/airoha-an8855-mfd.h |  41 ++++
 5 files changed, 331 insertions(+)
 create mode 100644 drivers/mfd/airoha-an8855.c
 create mode 100644 include/linux/mfd/airoha-an8855-mfd.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f3e3f6938824..7f4d7c48b6e1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -721,6 +721,7 @@ F:	Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
 F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
+F:	drivers/mfd/airoha-an8855.c
 
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ae23b317a64e..3a0b84991408 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -53,6 +53,16 @@ config MFD_ALTERA_SYSMGR
 	  using regmap_mmio accesses for ARM32 parts and SMC calls to
 	  EL3 for ARM64 parts.
 
+config MFD_AIROHA_AN8855
+	tristate "Airoha AN8855 Switch MFD"
+	select MFD_CORE
+	select MDIO_DEVICE
+	depends on NETDEVICES && OF
+	help
+	  Support for the Airoha AN8855 Switch MFD. This is a SoC Switch
+	  that provides various peripherals. Currently it provides a
+	  DSA switch and a NVMEM provider.
+
 config MFD_ACT8945A
 	tristate "Active-semi ACT8945A"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index e057d6d6faef..bcbeb36ab19d 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_MFD_88PM860X)	+= 88pm860x.o
 obj-$(CONFIG_MFD_88PM800)	+= 88pm800.o 88pm80x.o
 obj-$(CONFIG_MFD_88PM805)	+= 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_88PM886_PMIC)	+= 88pm886.o
+obj-$(CONFIG_MFD_AIROHA_AN8855)	+= airoha-an8855.o
 obj-$(CONFIG_MFD_ACT8945A)	+= act8945a.o
 obj-$(CONFIG_MFD_SM501)		+= sm501.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835-pm.o
diff --git a/drivers/mfd/airoha-an8855.c b/drivers/mfd/airoha-an8855.c
new file mode 100644
index 000000000000..eeaea348aa41
--- /dev/null
+++ b/drivers/mfd/airoha-an8855.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MFD driver for Airoha AN8855 Switch
+ */
+
+#include <linux/mfd/airoha-an8855-mfd.h>
+#include <linux/mfd/core.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/regmap.h>
+
+static const struct mfd_cell an8855_mfd_devs[] = {
+	{
+		.name = "an8855-efuse",
+		.of_compatible = "airoha,an8855-efuse",
+	}, {
+		.name = "an8855-switch",
+		.of_compatible = "airoha,an8855-switch",
+	}, {
+		.name = "an8855-mdio",
+		.of_compatible = "airoha,an8855-mdio",
+	}
+};
+
+int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
+			u8 page) __must_hold(&priv->bus->mdio_lock)
+{
+	struct mii_bus *bus = priv->bus;
+	int ret;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PHY_SELECT_PAGE, page);
+	if (ret < 0)
+		dev_err_ratelimited(&bus->dev,
+				    "failed to set an8855 mii page\n");
+
+	/* Cache current page if next mii read/write is for switch */
+	priv->current_page = page;
+	return ret < 0 ? ret : 0;
+}
+EXPORT_SYMBOL_GPL(an8855_mii_set_page);
+
+static int an8855_mii_read32(struct mii_bus *bus, u8 phy_id, u32 reg,
+			     u32 *val) __must_hold(&bus->mdio_lock)
+{
+	int lo, hi, ret;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE,
+			      AN8855_PBUS_MODE_ADDR_FIXED);
+	if (ret < 0)
+		goto err;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_HIGH,
+			      upper_16_bits(reg));
+	if (ret < 0)
+		goto err;
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_LOW,
+			      lower_16_bits(reg));
+	if (ret < 0)
+		goto err;
+
+	hi = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_HIGH);
+	if (hi < 0) {
+		ret = hi;
+		goto err;
+	}
+	lo = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_LOW);
+	if (lo < 0) {
+		ret = lo;
+		goto err;
+	}
+
+	*val = ((u16)hi << 16) | ((u16)lo & 0xffff);
+
+	return 0;
+err:
+	dev_err_ratelimited(&bus->dev,
+			    "failed to read an8855 register\n");
+	return ret;
+}
+
+static int an8855_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
+{
+	struct an8855_mfd_priv *priv = ctx;
+	struct mii_bus *bus = priv->bus;
+	u16 addr = priv->switch_addr;
+	int ret;
+
+	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+	ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
+	if (ret < 0)
+		goto exit;
+
+	ret = an8855_mii_read32(bus, addr, reg, val);
+
+exit:
+	mutex_unlock(&bus->mdio_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
+static int an8855_mii_write32(struct mii_bus *bus, u8 phy_id, u32 reg,
+			      u32 val) __must_hold(&bus->mdio_lock)
+{
+	int ret;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE,
+			      AN8855_PBUS_MODE_ADDR_FIXED);
+	if (ret < 0)
+		goto err;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_HIGH,
+			      upper_16_bits(reg));
+	if (ret < 0)
+		goto err;
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_LOW,
+			      lower_16_bits(reg));
+	if (ret < 0)
+		goto err;
+
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_HIGH,
+			      upper_16_bits(val));
+	if (ret < 0)
+		goto err;
+	ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_LOW,
+			      lower_16_bits(val));
+	if (ret < 0)
+		goto err;
+
+	return 0;
+err:
+	dev_err_ratelimited(&bus->dev,
+			    "failed to write an8855 register\n");
+	return ret;
+}
+
+static int
+an8855_regmap_write(void *ctx, uint32_t reg, uint32_t val)
+{
+	struct an8855_mfd_priv *priv = ctx;
+	struct mii_bus *bus = priv->bus;
+	u16 addr = priv->switch_addr;
+	int ret;
+
+	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+	ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
+	if (ret < 0)
+		goto exit;
+
+	ret = an8855_mii_write32(bus, addr, reg, val);
+
+exit:
+	mutex_unlock(&bus->mdio_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
+static int an8855_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask,
+				     uint32_t write_val)
+{
+	struct an8855_mfd_priv *priv = ctx;
+	struct mii_bus *bus = priv->bus;
+	u16 addr = priv->switch_addr;
+	u32 val;
+	int ret;
+
+	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+	ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
+	if (ret < 0)
+		goto exit;
+
+	ret = an8855_mii_read32(bus, addr, reg, &val);
+	if (ret < 0)
+		goto exit;
+
+	val &= ~mask;
+	val |= write_val;
+	ret = an8855_mii_write32(bus, addr, reg, val);
+
+exit:
+	mutex_unlock(&bus->mdio_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
+static const struct regmap_range an8855_readable_ranges[] = {
+	regmap_reg_range(0x10000000, 0x10000fff), /* SCU */
+	regmap_reg_range(0x10001000, 0x10001fff), /* RBUS */
+	regmap_reg_range(0x10002000, 0x10002fff), /* MCU */
+	regmap_reg_range(0x10005000, 0x10005fff), /* SYS SCU */
+	regmap_reg_range(0x10007000, 0x10007fff), /* I2C Slave */
+	regmap_reg_range(0x10008000, 0x10008fff), /* I2C Master */
+	regmap_reg_range(0x10009000, 0x10009fff), /* PDMA */
+	regmap_reg_range(0x1000a100, 0x1000a2ff), /* General Purpose Timer */
+	regmap_reg_range(0x1000a200, 0x1000a2ff), /* GPU timer */
+	regmap_reg_range(0x1000a300, 0x1000a3ff), /* GPIO */
+	regmap_reg_range(0x1000a400, 0x1000a5ff), /* EFUSE */
+	regmap_reg_range(0x1000c000, 0x1000cfff), /* GDMP CSR */
+	regmap_reg_range(0x10010000, 0x1001ffff), /* GDMP SRAM */
+	regmap_reg_range(0x10200000, 0x10203fff), /* Switch - ARL Global */
+	regmap_reg_range(0x10204000, 0x10207fff), /* Switch - BMU */
+	regmap_reg_range(0x10208000, 0x1020bfff), /* Switch - ARL Port */
+	regmap_reg_range(0x1020c000, 0x1020cfff), /* Switch - SCH */
+	regmap_reg_range(0x10210000, 0x10213fff), /* Switch - MAC */
+	regmap_reg_range(0x10214000, 0x10217fff), /* Switch - MIB */
+	regmap_reg_range(0x10218000, 0x1021bfff), /* Switch - Port Control */
+	regmap_reg_range(0x1021c000, 0x1021ffff), /* Switch - TOP */
+	regmap_reg_range(0x10220000, 0x1022ffff), /* SerDes */
+	regmap_reg_range(0x10286000, 0x10286fff), /* RG Batcher */
+	regmap_reg_range(0x1028c000, 0x1028ffff), /* ETHER_SYS */
+	regmap_reg_range(0x30000000, 0x37ffffff), /* I2C EEPROM */
+	regmap_reg_range(0x38000000, 0x3fffffff), /* BOOT_ROM */
+	regmap_reg_range(0xa0000000, 0xbfffffff), /* GPHY */
+};
+
+static const struct regmap_access_table an8855_readable_table = {
+	.yes_ranges = an8855_readable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(an8855_readable_ranges),
+};
+
+static const struct regmap_config an8855_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = 0xbfffffff,
+	.reg_read = an8855_regmap_read,
+	.reg_write = an8855_regmap_write,
+	.reg_update_bits = an8855_regmap_update_bits,
+	.disable_locking = true,
+	.rd_table = &an8855_readable_table,
+};
+
+static int an8855_mfd_probe(struct mdio_device *mdiodev)
+{
+	struct an8855_mfd_priv *priv;
+	struct regmap *regmap;
+
+	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->bus = mdiodev->bus;
+	priv->dev = &mdiodev->dev;
+	priv->switch_addr = mdiodev->addr;
+	/* no DMA for mdiobus, mute warning for DMA mask not set */
+	priv->dev->dma_mask = &priv->dev->coherent_dma_mask;
+
+	regmap = devm_regmap_init(priv->dev, NULL, priv,
+				  &an8855_regmap_config);
+	if (IS_ERR(regmap))
+		dev_err_probe(priv->dev, PTR_ERR(priv->dev),
+			      "regmap initialization failed\n");
+
+	dev_set_drvdata(&mdiodev->dev, priv);
+
+	return devm_mfd_add_devices(priv->dev, PLATFORM_DEVID_AUTO, an8855_mfd_devs,
+				    ARRAY_SIZE(an8855_mfd_devs), NULL, 0,
+				    NULL);
+}
+
+static const struct of_device_id an8855_mfd_of_match[] = {
+	{ .compatible = "airoha,an8855-mfd" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, an8855_mfd_of_match);
+
+static struct mdio_driver an8855_mfd_driver = {
+	.probe = an8855_mfd_probe,
+	.mdiodrv.driver = {
+		.name = "an8855",
+		.of_match_table = an8855_mfd_of_match,
+	},
+};
+mdio_module_driver(an8855_mfd_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_DESCRIPTION("Driver for Airoha AN8855 MFD");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/airoha-an8855-mfd.h b/include/linux/mfd/airoha-an8855-mfd.h
new file mode 100644
index 000000000000..56061566a079
--- /dev/null
+++ b/include/linux/mfd/airoha-an8855-mfd.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * MFD driver for Airoha AN8855 Switch
+ */
+#ifndef _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H
+#define _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H
+
+#include <linux/bitfield.h>
+
+/* MII Registers */
+#define AN8855_PHY_SELECT_PAGE		0x1f
+#define   AN8855_PHY_PAGE		GENMASK(2, 0)
+#define   AN8855_PHY_PAGE_STANDARD	FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
+#define   AN8855_PHY_PAGE_EXTENDED_1	FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
+#define   AN8855_PHY_PAGE_EXTENDED_4	FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x4)
+
+/* MII Registers Page 4 */
+#define AN8855_PBUS_MODE		0x10
+#define   AN8855_PBUS_MODE_ADDR_FIXED	0x0
+#define AN8855_PBUS_MODE_ADDR_INCR	BIT(15)
+#define AN8855_PBUS_WR_ADDR_HIGH	0x11
+#define AN8855_PBUS_WR_ADDR_LOW		0x12
+#define AN8855_PBUS_WR_DATA_HIGH	0x13
+#define AN8855_PBUS_WR_DATA_LOW		0x14
+#define AN8855_PBUS_RD_ADDR_HIGH	0x15
+#define AN8855_PBUS_RD_ADDR_LOW		0x16
+#define AN8855_PBUS_RD_DATA_HIGH	0x17
+#define AN8855_PBUS_RD_DATA_LOW		0x18
+
+struct an8855_mfd_priv {
+	struct device *dev;
+	struct mii_bus *bus;
+
+	unsigned int switch_addr;
+	u16 current_page;
+};
+
+int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
+			u8 page);
+
+#endif
-- 
2.45.2



From ansuelsmth at gmail.com  Mon Dec  9 05:44:23 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:23 +0100
Subject: [net-next PATCH v11 6/9] net: mdio: Add Airoha AN8855 Switch MDIO Passtrough
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241209134459.27110-7-ansuelsmth@gmail.com>

Add Airoha AN8855 Switch driver to register a MDIO passtrough as switch
address is shared with the internal PHYs and require additional page
handling.

This requires the upper Switch MFD to be probed and init to actually
work.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                    |   1 +
 drivers/net/mdio/Kconfig       |   9 +++
 drivers/net/mdio/Makefile      |   1 +
 drivers/net/mdio/mdio-an8855.c | 113 +++++++++++++++++++++++++++++++++
 4 files changed, 124 insertions(+)
 create mode 100644 drivers/net/mdio/mdio-an8855.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7f4d7c48b6e1..38c7b2362c92 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -722,6 +722,7 @@ F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 F:	drivers/mfd/airoha-an8855.c
+F:	drivers/net/mdio/mdio-an8855.c
 
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig
index 4a7a303be2f7..3d417948e73a 100644
--- a/drivers/net/mdio/Kconfig
+++ b/drivers/net/mdio/Kconfig
@@ -61,6 +61,15 @@ config MDIO_XGENE
 	  This module provides a driver for the MDIO busses found in the
 	  APM X-Gene SoC's.
 
+config MDIO_AN8855
+	tristate "Airoha AN8855 Switch MDIO bus controller"
+	depends on MFD_AIROHA_AN8855
+	depends on OF_MDIO
+	help
+	  This module provides a driver for the Airoha AN8855 Switch
+	  that requires a MDIO passtrough as switch address is shared
+	  with the internal PHYs and requires additional page handling.
+
 config MDIO_ASPEED
 	tristate "ASPEED MDIO bus controller"
 	depends on ARCH_ASPEED || COMPILE_TEST
diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile
index 1015f0db4531..546c4e55b475 100644
--- a/drivers/net/mdio/Makefile
+++ b/drivers/net/mdio/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_ACPI_MDIO)		+= acpi_mdio.o
 obj-$(CONFIG_FWNODE_MDIO)	+= fwnode_mdio.o
 obj-$(CONFIG_OF_MDIO)		+= of_mdio.o
 
+obj-$(CONFIG_MDIO_AN8855)		+= mdio-an8855.o
 obj-$(CONFIG_MDIO_ASPEED)		+= mdio-aspeed.o
 obj-$(CONFIG_MDIO_BCM_IPROC)		+= mdio-bcm-iproc.o
 obj-$(CONFIG_MDIO_BCM_UNIMAC)		+= mdio-bcm-unimac.o
diff --git a/drivers/net/mdio/mdio-an8855.c b/drivers/net/mdio/mdio-an8855.c
new file mode 100644
index 000000000000..5feba72c021b
--- /dev/null
+++ b/drivers/net/mdio/mdio-an8855.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MDIO passthrough driver for Airoha AN8855 Switch
+ */
+
+#include <linux/mfd/airoha-an8855-mfd.h>
+#include <linux/module.h>
+#include <linux/of_mdio.h>
+#include <linux/platform_device.h>
+
+static int an855_phy_restore_page(struct an8855_mfd_priv *priv,
+				  int phy) __must_hold(&priv->bus->mdio_lock)
+{
+	/* Check PHY page only for addr shared with switch */
+	if (phy != priv->switch_addr)
+		return 0;
+
+	/* Don't restore page if it's not set to switch page */
+	if (priv->current_page != FIELD_GET(AN8855_PHY_PAGE,
+					    AN8855_PHY_PAGE_EXTENDED_4))
+		return 0;
+
+	/* Restore page to 0, PHY might change page right after but that
+	 * will be ignored as it won't be a switch page.
+	 */
+	return an8855_mii_set_page(priv, phy, AN8855_PHY_PAGE_STANDARD);
+}
+
+static int an8855_phy_read(struct mii_bus *bus, int phy, int regnum)
+{
+	struct an8855_mfd_priv *priv = bus->priv;
+	struct mii_bus *real_bus = priv->bus;
+	int ret;
+
+	mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED);
+
+	ret = an855_phy_restore_page(priv, phy);
+	if (ret)
+		goto exit;
+
+	ret = __mdiobus_read(real_bus, phy, regnum);
+exit:
+	mutex_unlock(&real_bus->mdio_lock);
+
+	return ret;
+}
+
+static int an8855_phy_write(struct mii_bus *bus, int phy, int regnum, u16 val)
+{
+	struct an8855_mfd_priv *priv = bus->priv;
+	struct mii_bus *real_bus = priv->bus;
+	int ret;
+
+	mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED);
+
+	ret = an855_phy_restore_page(priv, phy);
+	if (ret)
+		goto exit;
+
+	ret = __mdiobus_write(real_bus, phy, regnum, val);
+exit:
+	mutex_unlock(&real_bus->mdio_lock);
+
+	return ret;
+}
+
+static int an8855_mdio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct an8855_mfd_priv *priv;
+	struct mii_bus *bus;
+	int ret;
+
+	/* Get priv of MFD */
+	priv = dev_get_drvdata(dev->parent);
+
+	bus = devm_mdiobus_alloc(dev);
+	if (!bus)
+		return -ENOMEM;
+
+	bus->priv = priv;
+	bus->name = KBUILD_MODNAME "-mii";
+	snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d",
+		 priv->switch_addr);
+	bus->parent = dev;
+	bus->read = an8855_phy_read;
+	bus->write = an8855_phy_write;
+
+	ret = devm_of_mdiobus_register(dev, bus, dev->of_node);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register MDIO bus\n");
+
+	return ret;
+}
+
+static const struct of_device_id an8855_mdio_of_match[] = {
+	{ .compatible = "airoha,an8855-mdio", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, an8855_mdio_of_match);
+
+static struct platform_driver an8855_mdio_driver = {
+	.probe	= an8855_mdio_probe,
+	.driver = {
+		.name = "an8855-mdio",
+		.of_match_table = an8855_mdio_of_match,
+	},
+};
+module_platform_driver(an8855_mdio_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_DESCRIPTION("Driver for AN8855 MDIO passthrough");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From ansuelsmth at gmail.com  Mon Dec  9 05:44:24 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:24 +0100
Subject: [net-next PATCH v11 7/9] nvmem: an8855: Add support for Airoha AN8855 Switch EFUSE
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241209134459.27110-8-ansuelsmth@gmail.com>

Add support for Airoha AN8855 Switch EFUSE. These EFUSE might be used
for calibration data for the internal switch PHYs.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                  |  1 +
 drivers/nvmem/Kconfig        | 11 +++++++
 drivers/nvmem/Makefile       |  2 ++
 drivers/nvmem/an8855-efuse.c | 63 ++++++++++++++++++++++++++++++++++++
 4 files changed, 77 insertions(+)
 create mode 100644 drivers/nvmem/an8855-efuse.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 38c7b2362c92..a67d147276a1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -723,6 +723,7 @@ F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 F:	drivers/mfd/airoha-an8855.c
 F:	drivers/net/mdio/mdio-an8855.c
+F:	drivers/nvmem/an8855-efuse.c
 
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 8671b7c974b9..ca96c6ea685a 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -28,6 +28,17 @@ source "drivers/nvmem/layouts/Kconfig"
 
 # Devices
 
+config NVMEM_AN8855_EFUSE
+	tristate "Airoha AN8855 eFuse support"
+	depends on MFD_AIROHA_AN8855 || COMPILE_TEST
+	help
+	  Say y here to enable support for reading eFuses on Airoha AN8855
+	  Switch. These are e.g. used to store factory programmed
+	  calibration data required for the PHY.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called nvmem-an8855-efuse.
+
 config NVMEM_APPLE_EFUSES
 	tristate "Apple eFuse support"
 	depends on ARCH_APPLE || COMPILE_TEST
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 5b77bbb6488b..c732132c0e45 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -10,6 +10,8 @@ nvmem_layouts-y			:= layouts.o
 obj-y				+= layouts/
 
 # Devices
+obj-$(CONFIG_NVMEM_AN8855_EFUSE)	+= nvmem-an8855-efuse.o
+nvmem-an8855-efuse-y 			:= an8855-efuse.o
 obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o
 nvmem-apple-efuses-y 			:= apple-efuses.o
 obj-$(CONFIG_NVMEM_BCM_OCOTP)		+= nvmem-bcm-ocotp.o
diff --git a/drivers/nvmem/an8855-efuse.c b/drivers/nvmem/an8855-efuse.c
new file mode 100644
index 000000000000..7940453d6e58
--- /dev/null
+++ b/drivers/nvmem/an8855-efuse.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Airoha AN8855 Switch EFUSE Driver
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define AN8855_EFUSE_CELL		50
+
+#define AN8855_EFUSE_DATA0		0x1000a500
+#define   AN8855_EFUSE_R50O		GENMASK(30, 24)
+
+static int an8855_efuse_read(void *context, unsigned int offset,
+			     void *val, size_t bytes)
+{
+	struct regmap *regmap = context;
+
+	return regmap_bulk_read(regmap, AN8855_EFUSE_DATA0 + offset,
+				val, bytes / sizeof(u32));
+}
+
+static int an8855_efuse_probe(struct platform_device *pdev)
+{
+	struct nvmem_config an8855_nvmem_config = {
+		.name = "an8855-efuse",
+		.size = AN8855_EFUSE_CELL * sizeof(u32),
+		.stride = sizeof(u32),
+		.word_size = sizeof(u32),
+		.reg_read = an8855_efuse_read,
+	};
+	struct device *dev = &pdev->dev;
+	struct nvmem_device *nvmem;
+
+	/* Assign NVMEM priv to MFD regmap */
+	an8855_nvmem_config.priv = dev_get_regmap(dev->parent, NULL);
+	an8855_nvmem_config.dev = dev;
+	nvmem = devm_nvmem_register(dev, &an8855_nvmem_config);
+
+	return PTR_ERR_OR_ZERO(nvmem);
+}
+
+static const struct of_device_id an8855_efuse_of_match[] = {
+	{ .compatible = "airoha,an8855-efuse", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, an8855_efuse_of_match);
+
+static struct platform_driver an8855_efuse_driver = {
+	.probe = an8855_efuse_probe,
+	.driver = {
+		.name = "an8855-efuse",
+		.of_match_table = an8855_efuse_of_match,
+	},
+};
+module_platform_driver(an8855_efuse_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_DESCRIPTION("Driver for AN8855 Switch EFUSE");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From ansuelsmth at gmail.com  Mon Dec  9 05:44:25 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:25 +0100
Subject: [net-next PATCH v11 8/9] net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241209134459.27110-9-ansuelsmth@gmail.com>

Add Airoha AN8855 5-Port Gigabit DSA switch. Switch can support
10M, 100M, 1Gb, 2.5G and 5G Ethernet Speed but 5G is currently error out
as it's not currently supported as requires additional configuration for
the PCS.

The switch is also a nvmem-provider as it does have EFUSE to calibrate
the internal PHYs.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS              |    2 +
 drivers/net/dsa/Kconfig  |    9 +
 drivers/net/dsa/Makefile |    1 +
 drivers/net/dsa/an8855.c | 2310 ++++++++++++++++++++++++++++++++++++++
 drivers/net/dsa/an8855.h |  783 +++++++++++++
 5 files changed, 3105 insertions(+)
 create mode 100644 drivers/net/dsa/an8855.c
 create mode 100644 drivers/net/dsa/an8855.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a67d147276a1..c42431a09b84 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -722,6 +722,8 @@ F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 F:	drivers/mfd/airoha-an8855.c
+F:	drivers/net/dsa/an8855.c
+F:	drivers/net/dsa/an8855.h
 F:	drivers/net/mdio/mdio-an8855.c
 F:	drivers/nvmem/an8855-efuse.c
 
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 2d10b4d6cfbb..99b1569ba35b 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -24,6 +24,15 @@ config NET_DSA_LOOP
 	  This enables support for a fake mock-up switch chip which
 	  exercises the DSA APIs.
 
+config NET_DSA_AN8855
+	tristate "Airoha AN8855 Ethernet switch support"
+	depends on MFD_AIROHA_AN8855 || COMPILE_TEST
+	depends on NET_DSA
+	select NET_DSA_TAG_MTK
+	help
+	  This enables support for the Airoha AN8855 Ethernet switch
+	  chip.
+
 source "drivers/net/dsa/hirschmann/Kconfig"
 
 config NET_DSA_LANTIQ_GSWIP
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index cb9a97340e58..a74afb41a491 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_NET_DSA_LOOP)	+= dsa_loop.o
 ifdef CONFIG_NET_DSA_LOOP
 obj-$(CONFIG_FIXED_PHY)		+= dsa_loop_bdinfo.o
 endif
+obj-$(CONFIG_NET_DSA_AN8855)	+= an8855.o
 obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
 obj-$(CONFIG_NET_DSA_MT7530)	+= mt7530.o
 obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
diff --git a/drivers/net/dsa/an8855.c b/drivers/net/dsa/an8855.c
new file mode 100644
index 000000000000..4a56a55945cd
--- /dev/null
+++ b/drivers/net/dsa/an8855.c
@@ -0,0 +1,2310 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Airoha AN8855 DSA Switch driver
+ * Copyright (C) 2023 Min Yao <min.yao at airoha.com>
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth at gmail.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+#include <linux/gpio/consumer.h>
+#include <linux/if_bridge.h>
+#include <linux/iopoll.h>
+#include <linux/netdevice.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/phylink.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <net/dsa.h>
+
+#include "an8855.h"
+
+static const struct an8855_mib_desc an8855_mib[] = {
+	MIB_DESC(1, AN8855_PORT_MIB_TX_DROP, "TxDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_TX_CRC_ERR, "TxCrcErr"),
+	MIB_DESC(1, AN8855_PORT_MIB_TX_COLLISION, "TxCollision"),
+	MIB_DESC(1, AN8855_PORT_MIB_TX_OVERSIZE_DROP, "TxOversizeDrop"),
+	MIB_DESC(2, AN8855_PORT_MIB_TX_BAD_PKT_BYTES, "TxBadPktBytes"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_DROP, "RxDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_FILTERING, "RxFiltering"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_CRC_ERR, "RxCrcErr"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_CTRL_DROP, "RxCtrlDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_INGRESS_DROP, "RxIngressDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_RX_ARL_DROP, "RxArlDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_FLOW_CONTROL_DROP, "FlowControlDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_WRED_DROP, "WredDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_MIRROR_DROP, "MirrorDrop"),
+	MIB_DESC(2, AN8855_PORT_MIB_RX_BAD_PKT_BYTES, "RxBadPktBytes"),
+	MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP, "RxsFlowSamplingPktDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP, "RxsFlowTotalPktDrop"),
+	MIB_DESC(1, AN8855_PORT_MIB_PORT_CONTROL_DROP, "PortControlDrop"),
+};
+
+static int
+an8855_mib_init(struct an8855_priv *priv)
+{
+	int ret;
+
+	ret = regmap_write(priv->regmap, AN8855_MIB_CCR,
+			   AN8855_CCR_MIB_ENABLE);
+	if (ret)
+		return ret;
+
+	return regmap_write(priv->regmap, AN8855_MIB_CCR,
+			    AN8855_CCR_MIB_ACTIVATE);
+}
+
+static void an8855_fdb_write(struct an8855_priv *priv, u16 vid,
+			     u8 port_mask, const u8 *mac,
+			     bool add) __must_hold(&priv->reg_mutex)
+{
+	u32 mac_reg[2] = { };
+	u32 reg;
+
+	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC0, mac[0]);
+	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC1, mac[1]);
+	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC2, mac[2]);
+	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC3, mac[3]);
+	mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC4, mac[4]);
+	mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC5, mac[5]);
+
+	regmap_bulk_write(priv->regmap, AN8855_ATA1, mac_reg,
+			  ARRAY_SIZE(mac_reg));
+
+	reg = AN8855_ATWD_IVL;
+	if (add)
+		reg |= AN8855_ATWD_VLD;
+	reg |= FIELD_PREP(AN8855_ATWD_VID, vid);
+	reg |= FIELD_PREP(AN8855_ATWD_FID, AN8855_FID_BRIDGED);
+	regmap_write(priv->regmap, AN8855_ATWD, reg);
+	regmap_write(priv->regmap, AN8855_ATWD2,
+		     FIELD_PREP(AN8855_ATWD2_PORT, port_mask));
+}
+
+static void an8855_fdb_read(struct an8855_priv *priv, struct an8855_fdb *fdb)
+{
+	u32 reg[4];
+
+	regmap_bulk_read(priv->regmap, AN8855_ATRD0, reg,
+			 ARRAY_SIZE(reg));
+
+	fdb->live = FIELD_GET(AN8855_ATRD0_LIVE, reg[0]);
+	fdb->type = FIELD_GET(AN8855_ATRD0_TYPE, reg[0]);
+	fdb->ivl = FIELD_GET(AN8855_ATRD0_IVL, reg[0]);
+	fdb->vid = FIELD_GET(AN8855_ATRD0_VID, reg[0]);
+	fdb->fid = FIELD_GET(AN8855_ATRD0_FID, reg[0]);
+	fdb->aging = FIELD_GET(AN8855_ATRD1_AGING, reg[1]);
+	fdb->port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, reg[3]);
+	fdb->mac[0] = FIELD_GET(AN8855_ATRD2_MAC0, reg[2]);
+	fdb->mac[1] = FIELD_GET(AN8855_ATRD2_MAC1, reg[2]);
+	fdb->mac[2] = FIELD_GET(AN8855_ATRD2_MAC2, reg[2]);
+	fdb->mac[3] = FIELD_GET(AN8855_ATRD2_MAC3, reg[2]);
+	fdb->mac[4] = FIELD_GET(AN8855_ATRD1_MAC4, reg[1]);
+	fdb->mac[5] = FIELD_GET(AN8855_ATRD1_MAC5, reg[1]);
+	fdb->noarp = !!FIELD_GET(AN8855_ATRD0_ARP, reg[0]);
+}
+
+static int an8855_fdb_cmd(struct an8855_priv *priv, u32 cmd,
+			  u32 *rsp) __must_hold(&priv->reg_mutex)
+{
+	u32 val;
+	int ret;
+
+	/* Set the command operating upon the MAC address entries */
+	val = AN8855_ATC_BUSY | cmd;
+	ret = regmap_write(priv->regmap, AN8855_ATC, val);
+	if (ret)
+		return ret;
+
+	ret = regmap_read_poll_timeout(priv->regmap, AN8855_ATC, val,
+				       !(val & AN8855_ATC_BUSY), 20, 200000);
+	if (ret)
+		return ret;
+
+	if (rsp)
+		*rsp = val;
+
+	return 0;
+}
+
+static void
+an8855_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+{
+	struct dsa_port *dp = dsa_to_port(ds, port);
+	struct an8855_priv *priv = ds->priv;
+	bool learning = false;
+	u32 stp_state;
+
+	switch (state) {
+	case BR_STATE_DISABLED:
+		stp_state = AN8855_STP_DISABLED;
+		break;
+	case BR_STATE_BLOCKING:
+		stp_state = AN8855_STP_BLOCKING;
+		break;
+	case BR_STATE_LISTENING:
+		stp_state = AN8855_STP_LISTENING;
+		break;
+	case BR_STATE_LEARNING:
+		stp_state = AN8855_STP_LEARNING;
+		learning = dp->learning;
+		break;
+	case BR_STATE_FORWARDING:
+		learning = dp->learning;
+		fallthrough;
+	default:
+		stp_state = AN8855_STP_FORWARDING;
+		break;
+	}
+
+	regmap_update_bits(priv->regmap, AN8855_SSP_P(port),
+			   AN8855_FID_PST_MASK(AN8855_FID_BRIDGED),
+			   AN8855_FID_PST_VAL(AN8855_FID_BRIDGED, stp_state));
+
+	regmap_update_bits(priv->regmap, AN8855_PSC_P(port), AN8855_SA_DIS,
+			   learning ? 0 : AN8855_SA_DIS);
+}
+
+static void an8855_port_fast_age(struct dsa_switch *ds, int port)
+{
+	struct an8855_priv *priv = ds->priv;
+	int ret;
+
+	/* Set to clean Dynamic entry */
+	ret = regmap_write(priv->regmap, AN8855_ATA2, AN8855_ATA2_TYPE);
+	if (ret)
+		return;
+
+	/* Set Port */
+	ret = regmap_write(priv->regmap, AN8855_ATWD2,
+			   FIELD_PREP(AN8855_ATWD2_PORT, BIT(port)));
+	if (ret)
+		return;
+
+	/* Flush Dynamic entry at port */
+	an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_TYPE_PORT) |
+		       AN8855_FDB_FLUSH, NULL);
+}
+
+static int an8855_update_port_member(struct dsa_switch *ds, int port,
+				     const struct net_device *bridge_dev,
+				     bool join)
+{
+	struct an8855_priv *priv = ds->priv;
+	bool isolated, other_isolated;
+	struct dsa_port *dp;
+	u32 port_mask = 0;
+	int ret;
+
+	isolated = !!(priv->port_isolated_map & BIT(port));
+
+	dsa_switch_for_each_user_port(dp, ds) {
+		if (dp->index == port)
+			continue;
+
+		if (!dsa_port_offloads_bridge_dev(dp, bridge_dev))
+			continue;
+
+		other_isolated = !!(priv->port_isolated_map & BIT(dp->index));
+		port_mask |= BIT(dp->index);
+		/* Add/remove this port to the portvlan mask of the other
+		 * ports in the bridge
+		 */
+		if (join && !(isolated && other_isolated))
+			ret = regmap_set_bits(priv->regmap,
+					      AN8855_PORTMATRIX_P(dp->index),
+					      FIELD_PREP(AN8855_USER_PORTMATRIX,
+							 BIT(port)));
+		else
+			ret = regmap_clear_bits(priv->regmap,
+						AN8855_PORTMATRIX_P(dp->index),
+						FIELD_PREP(AN8855_USER_PORTMATRIX,
+							   BIT(port)));
+		if (ret)
+			return ret;
+	}
+
+	/* Add/remove all other ports to this port's portvlan mask */
+	return regmap_update_bits(priv->regmap, AN8855_PORTMATRIX_P(port),
+				  AN8855_USER_PORTMATRIX,
+				  join ? port_mask : ~port_mask);
+}
+
+static int an8855_port_pre_bridge_flags(struct dsa_switch *ds, int port,
+					struct switchdev_brport_flags flags,
+					struct netlink_ext_ack *extack)
+{
+	if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
+			   BR_BCAST_FLOOD | BR_ISOLATED))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int an8855_port_bridge_flags(struct dsa_switch *ds, int port,
+				    struct switchdev_brport_flags flags,
+				    struct netlink_ext_ack *extack)
+{
+	struct an8855_priv *priv = ds->priv;
+	int ret;
+
+	if (flags.mask & BR_LEARNING) {
+		ret = regmap_update_bits(priv->regmap, AN8855_PSC_P(port), AN8855_SA_DIS,
+					 flags.val & BR_LEARNING ? 0 : AN8855_SA_DIS);
+		if (ret)
+			return ret;
+	}
+
+	if (flags.mask & BR_FLOOD) {
+		ret = regmap_update_bits(priv->regmap, AN8855_UNUF, BIT(port),
+					 flags.val & BR_FLOOD ? BIT(port) : 0);
+		if (ret)
+			return ret;
+	}
+
+	if (flags.mask & BR_MCAST_FLOOD) {
+		ret = regmap_update_bits(priv->regmap, AN8855_UNMF, BIT(port),
+					 flags.val & BR_MCAST_FLOOD ? BIT(port) : 0);
+		if (ret)
+			return ret;
+
+		ret = regmap_update_bits(priv->regmap, AN8855_UNIPMF, BIT(port),
+					 flags.val & BR_MCAST_FLOOD ? BIT(port) : 0);
+		if (ret)
+			return ret;
+	}
+
+	if (flags.mask & BR_BCAST_FLOOD) {
+		ret = regmap_update_bits(priv->regmap, AN8855_BCF, BIT(port),
+					 flags.val & BR_BCAST_FLOOD ? BIT(port) : 0);
+		if (ret)
+			return ret;
+	}
+
+	if (flags.mask & BR_ISOLATED) {
+		struct dsa_port *dp = dsa_to_port(ds, port);
+		struct net_device *bridge_dev = dsa_port_bridge_dev_get(dp);
+
+		if (flags.val & BR_ISOLATED)
+			priv->port_isolated_map |= BIT(port);
+		else
+			priv->port_isolated_map &= ~BIT(port);
+
+		ret = an8855_update_port_member(ds, port, bridge_dev, true);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int an8855_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
+{
+	struct an8855_priv *priv = ds->priv;
+	u32 age_count, age_unit, val;
+
+	/* Convert msec in AN8855_L2_AGING_MS_CONSTANT counter */
+	val = msecs / AN8855_L2_AGING_MS_CONSTANT;
+	/* Derive the count unit */
+	age_unit = val / FIELD_MAX(AN8855_AGE_UNIT);
+	/* Get the count in unit, age_unit is always incremented by 1 internally */
+	age_count = val / (age_unit + 1);
+
+	return regmap_update_bits(priv->regmap, AN8855_AAC,
+				  AN8855_AGE_CNT | AN8855_AGE_UNIT,
+				  FIELD_PREP(AN8855_AGE_CNT, age_count) |
+				  FIELD_PREP(AN8855_AGE_UNIT, age_unit));
+}
+
+static int an8855_port_bridge_join(struct dsa_switch *ds, int port,
+				   struct dsa_bridge bridge,
+				   bool *tx_fwd_offload,
+				   struct netlink_ext_ack *extack)
+{
+	struct an8855_priv *priv = ds->priv;
+	int ret;
+
+	ret = an8855_update_port_member(ds, port, bridge.dev, true);
+	if (ret)
+		return ret;
+
+	/* Set to fallback mode for independent VLAN learning if in a bridge */
+	return regmap_update_bits(priv->regmap, AN8855_PCR_P(port),
+				  AN8855_PORT_VLAN,
+				  FIELD_PREP(AN8855_PORT_VLAN,
+					     AN8855_PORT_FALLBACK_MODE));
+}
+
+static void an8855_port_bridge_leave(struct dsa_switch *ds, int port,
+				     struct dsa_bridge bridge)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	an8855_update_port_member(ds, port, bridge.dev, false);
+
+	/* When a port is removed from the bridge, the port would be set up
+	 * back to the default as is at initial boot which is a VLAN-unaware
+	 * port.
+	 */
+	regmap_update_bits(priv->regmap, AN8855_PCR_P(port),
+			   AN8855_PORT_VLAN,
+			   FIELD_PREP(AN8855_PORT_VLAN,
+				      AN8855_PORT_MATRIX_MODE));
+}
+
+static int an8855_port_fdb_add(struct dsa_switch *ds, int port,
+			       const unsigned char *addr, u16 vid,
+			       struct dsa_db db)
+{
+	struct an8855_priv *priv = ds->priv;
+	u8 port_mask = BIT(port);
+	int ret;
+
+	/* Set the vid to the port vlan id if no vid is set */
+	if (!vid)
+		vid = AN8855_PORT_VID_DEFAULT;
+
+	mutex_lock(&priv->reg_mutex);
+	an8855_fdb_write(priv, vid, port_mask, addr, true);
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+	mutex_unlock(&priv->reg_mutex);
+
+	return ret;
+}
+
+static int an8855_port_fdb_del(struct dsa_switch *ds, int port,
+			       const unsigned char *addr, u16 vid,
+			       struct dsa_db db)
+{
+	struct an8855_priv *priv = ds->priv;
+	u8 port_mask = BIT(port);
+	int ret;
+
+	/* Set the vid to the port vlan id if no vid is set */
+	if (!vid)
+		vid = AN8855_PORT_VID_DEFAULT;
+
+	mutex_lock(&priv->reg_mutex);
+	an8855_fdb_write(priv, vid, port_mask, addr, false);
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+	mutex_unlock(&priv->reg_mutex);
+
+	return ret;
+}
+
+static int an8855_port_fdb_dump(struct dsa_switch *ds, int port,
+				dsa_fdb_dump_cb_t *cb, void *data)
+{
+	struct an8855_priv *priv = ds->priv;
+	int banks, count = 0;
+	u32 rsp;
+	int ret;
+	int i;
+
+	mutex_lock(&priv->reg_mutex);
+
+	/* Load search port */
+	ret = regmap_write(priv->regmap, AN8855_ATWD2,
+			   FIELD_PREP(AN8855_ATWD2_PORT, BIT(port)));
+	if (ret)
+		goto exit;
+	ret = an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_PORT) |
+			     AN8855_FDB_START, &rsp);
+	if (ret < 0)
+		goto exit;
+
+	do {
+		/* From response get the number of banks to read, exit if 0 */
+		banks = FIELD_GET(AN8855_ATC_HIT, rsp);
+		if (!banks)
+			break;
+
+		/* Each banks have 4 entry */
+		for (i = 0; i < 4; i++) {
+			struct an8855_fdb _fdb = {  };
+
+			count++;
+
+			/* Check if bank is present */
+			if (!(banks & BIT(i)))
+				continue;
+
+			/* Select bank entry index */
+			ret = regmap_write(priv->regmap, AN8855_ATRDS,
+					   FIELD_PREP(AN8855_ATRD_SEL, i));
+			if (ret)
+				break;
+			/* wait 1ms for the bank entry to be filled */
+			usleep_range(1000, 1500);
+			an8855_fdb_read(priv, &_fdb);
+
+			if (!_fdb.live)
+				continue;
+			ret = cb(_fdb.mac, _fdb.vid, _fdb.noarp, data);
+			if (ret < 0)
+				break;
+		}
+
+		/* Stop if reached max FDB number */
+		if (count >= AN8855_NUM_FDB_RECORDS)
+			break;
+
+		/* Read next bank */
+		ret = an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_PORT) |
+				     AN8855_FDB_NEXT, &rsp);
+		if (ret < 0)
+			break;
+	} while (true);
+
+exit:
+	mutex_unlock(&priv->reg_mutex);
+	return ret;
+}
+
+static int an8855_vlan_cmd(struct an8855_priv *priv, enum an8855_vlan_cmd cmd,
+			   u16 vid) __must_hold(&priv->reg_mutex)
+{
+	u32 val;
+	int ret;
+
+	val = AN8855_VTCR_BUSY | FIELD_PREP(AN8855_VTCR_FUNC, cmd) |
+	      FIELD_PREP(AN8855_VTCR_VID, vid);
+	ret = regmap_write(priv->regmap, AN8855_VTCR, val);
+	if (ret)
+		return ret;
+
+	return regmap_read_poll_timeout(priv->regmap, AN8855_VTCR, val,
+					!(val & AN8855_VTCR_BUSY), 20, 200000);
+}
+
+static int an8855_vlan_add(struct an8855_priv *priv, u8 port, u16 vid,
+			   bool untagged) __must_hold(&priv->reg_mutex)
+{
+	u32 port_mask;
+	u32 val;
+	int ret;
+
+	/* Fetch entry */
+	ret = an8855_vlan_cmd(priv, AN8855_VTCR_RD_VID, vid);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(priv->regmap, AN8855_VARD0, &val);
+	if (ret)
+		return ret;
+	port_mask = FIELD_GET(AN8855_VA0_PORT, val) | BIT(port);
+
+	/* Validate the entry with independent learning, create egress tag per
+	 * VLAN and joining the port as one of the port members.
+	 */
+	val = (val & AN8855_VA0_ETAG) | AN8855_VA0_IVL_MAC |
+	      AN8855_VA0_VTAG_EN | AN8855_VA0_VLAN_VALID |
+	      FIELD_PREP(AN8855_VA0_PORT, port_mask) |
+	      FIELD_PREP(AN8855_VA0_FID, AN8855_FID_BRIDGED);
+	ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
+	if (ret)
+		return ret;
+	ret = regmap_write(priv->regmap, AN8855_VAWD1, 0);
+	if (ret)
+		return ret;
+
+	/* CPU port is always taken as a tagged port for serving more than one
+	 * VLANs across and also being applied with egress type stack mode for
+	 * that VLAN tags would be appended after hardware special tag used as
+	 * DSA tag.
+	 */
+	if (port == AN8855_CPU_PORT)
+		val = AN8855_VLAN_EGRESS_STACK;
+	/* Decide whether adding tag or not for those outgoing packets from the
+	 * port inside the VLAN.
+	 */
+	else
+		val = untagged ? AN8855_VLAN_EGRESS_UNTAG : AN8855_VLAN_EGRESS_TAG;
+	ret = regmap_update_bits(priv->regmap, AN8855_VAWD0,
+				 AN8855_VA0_ETAG_PORT_MASK(port),
+				 AN8855_VA0_ETAG_PORT_VAL(port, val));
+	if (ret)
+		return ret;
+
+	/* Flush result to hardware */
+	return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID, vid);
+}
+
+static int an8855_vlan_del(struct an8855_priv *priv, u8 port,
+			   u16 vid) __must_hold(&priv->reg_mutex)
+{
+	u32 port_mask;
+	u32 val;
+	int ret;
+
+	/* Fetch entry */
+	ret = an8855_vlan_cmd(priv, AN8855_VTCR_RD_VID, vid);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(priv->regmap, AN8855_VARD0, &val);
+	if (ret)
+		return ret;
+	port_mask = FIELD_GET(AN8855_VA0_PORT, val) & ~BIT(port);
+
+	if (!(val & AN8855_VA0_VLAN_VALID)) {
+		dev_err(priv->dev, "Cannot be deleted due to invalid entry\n");
+		return -EINVAL;
+	}
+
+	if (port_mask) {
+		val = (val & AN8855_VA0_ETAG) | AN8855_VA0_IVL_MAC |
+		       AN8855_VA0_VTAG_EN | AN8855_VA0_VLAN_VALID |
+		       FIELD_PREP(AN8855_VA0_PORT, port_mask);
+		ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
+		if (ret)
+			return ret;
+	} else {
+		ret = regmap_write(priv->regmap, AN8855_VAWD0, 0);
+		if (ret)
+			return ret;
+	}
+	ret = regmap_write(priv->regmap, AN8855_VAWD1, 0);
+	if (ret)
+		return ret;
+
+	/* Flush result to hardware */
+	return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID, vid);
+}
+
+static int an8855_port_set_vlan_mode(struct an8855_priv *priv, int port,
+				     enum an8855_port_mode port_mode,
+				     enum an8855_vlan_port_eg_tag eg_tag,
+				     enum an8855_vlan_port_attr vlan_attr,
+				     enum an8855_vlan_port_acc_frm acc_frm)
+{
+	int ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_PCR_P(port),
+				 AN8855_PORT_VLAN,
+				 FIELD_PREP(AN8855_PORT_VLAN, port_mode));
+	if (ret)
+		return ret;
+
+	return regmap_update_bits(priv->regmap, AN8855_PVC_P(port),
+				  AN8855_PVC_EG_TAG | AN8855_VLAN_ATTR | AN8855_ACC_FRM,
+				  FIELD_PREP(AN8855_PVC_EG_TAG, eg_tag) |
+				  FIELD_PREP(AN8855_VLAN_ATTR, vlan_attr) |
+				  FIELD_PREP(AN8855_ACC_FRM, acc_frm));
+}
+
+static int an8855_port_set_pid(struct an8855_priv *priv, int port,
+			       u16 pid)
+{
+	int ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_PPBV1_P(port),
+				 AN8855_PPBV_G0_PORT_VID,
+				 FIELD_PREP(AN8855_PPBV_G0_PORT_VID, pid));
+	if (ret)
+		return ret;
+
+	return regmap_update_bits(priv->regmap, AN8855_PVID_P(port),
+				  AN8855_G0_PORT_VID,
+				  FIELD_PREP(AN8855_G0_PORT_VID, pid));
+}
+
+static int an8855_port_vlan_filtering(struct dsa_switch *ds, int port,
+				      bool vlan_filtering,
+				      struct netlink_ext_ack *extack)
+{
+	struct an8855_priv *priv = ds->priv;
+	u32 val;
+	int ret;
+
+	/* The port is being kept as VLAN-unaware port when bridge is
+	 * set up with vlan_filtering not being set, Otherwise, the
+	 * port and the corresponding CPU port is required the setup
+	 * for becoming a VLAN-aware port.
+	 */
+	if (vlan_filtering) {
+		u32 acc_frm;
+		/* CPU port is set to fallback mode to let untagged
+		 * frames pass through.
+		 */
+		ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT,
+						AN8855_PORT_FALLBACK_MODE,
+						AN8855_VLAN_EG_CONSISTENT,
+						AN8855_VLAN_USER,
+						AN8855_VLAN_ACC_ALL);
+		if (ret)
+			return ret;
+
+		ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
+		if (ret)
+			return ret;
+
+		/* Only accept tagged frames if PVID is not set */
+		if (FIELD_GET(AN8855_G0_PORT_VID, val) != AN8855_PORT_VID_DEFAULT)
+			acc_frm = AN8855_VLAN_ACC_TAGGED;
+		else
+			acc_frm = AN8855_VLAN_ACC_ALL;
+
+		/* Trapped into security mode allows packet forwarding through VLAN
+		 * table lookup.
+		 * Set the port as a user port which is to be able to recognize VID
+		 * from incoming packets before fetching entry within the VLAN table.
+		 */
+		ret = an8855_port_set_vlan_mode(priv, port,
+						AN8855_PORT_SECURITY_MODE,
+						AN8855_VLAN_EG_DISABLED,
+						AN8855_VLAN_USER,
+						acc_frm);
+		if (ret)
+			return ret;
+	} else {
+		bool disable_cpu_vlan = true;
+		struct dsa_port *dp;
+		u32 port_mode;
+
+		/* This is called after .port_bridge_leave when leaving a VLAN-aware
+		 * bridge. Don't set standalone ports to fallback mode.
+		 */
+		if (dsa_port_bridge_dev_get(dsa_to_port(ds, port)))
+			port_mode = AN8855_PORT_FALLBACK_MODE;
+		else
+			port_mode = AN8855_PORT_MATRIX_MODE;
+
+		/* When a port is removed from the bridge, the port would be set up
+		 * back to the default as is at initial boot which is a VLAN-unaware
+		 * port.
+		 */
+		ret = an8855_port_set_vlan_mode(priv, port, port_mode,
+						AN8855_VLAN_EG_CONSISTENT,
+						AN8855_VLAN_TRANSPARENT,
+						AN8855_VLAN_ACC_ALL);
+		if (ret)
+			return ret;
+
+		/* Restore default PVID */
+		ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
+		if (ret)
+			return ret;
+
+		dsa_switch_for_each_user_port(dp, ds) {
+			if (dsa_port_is_vlan_filtering(dp)) {
+				disable_cpu_vlan = false;
+				break;
+			}
+		}
+
+		if (disable_cpu_vlan) {
+			ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT,
+							AN8855_PORT_MATRIX_MODE,
+							AN8855_VLAN_EG_CONSISTENT,
+							AN8855_VLAN_USER,
+							AN8855_VLAN_ACC_ALL);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int an8855_port_vlan_add(struct dsa_switch *ds, int port,
+				const struct switchdev_obj_port_vlan *vlan,
+				struct netlink_ext_ack *extack)
+{
+	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
+	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
+	struct an8855_priv *priv = ds->priv;
+	u32 val;
+	int ret;
+
+	mutex_lock(&priv->reg_mutex);
+	ret = an8855_vlan_add(priv, port, vlan->vid, untagged);
+	mutex_unlock(&priv->reg_mutex);
+	if (ret)
+		return ret;
+
+	if (pvid) {
+		/* Accept all frames if PVID is set */
+		regmap_update_bits(priv->regmap, AN8855_PVC_P(port), AN8855_ACC_FRM,
+				   FIELD_PREP(AN8855_ACC_FRM, AN8855_VLAN_ACC_ALL));
+
+		/* Only configure PVID if VLAN filtering is enabled */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
+			ret = an8855_port_set_pid(priv, port, vlan->vid);
+			if (ret)
+				return ret;
+		}
+	} else if (vlan->vid) {
+		ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
+		if (ret)
+			return ret;
+
+		if (FIELD_GET(AN8855_G0_PORT_VID, val) != vlan->vid)
+			return 0;
+
+		/* This VLAN is overwritten without PVID, so unset it */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
+			ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(port),
+						 AN8855_ACC_FRM,
+						 FIELD_PREP(AN8855_ACC_FRM,
+							    AN8855_VLAN_ACC_TAGGED));
+			if (ret)
+				return ret;
+		}
+
+		ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int an8855_port_vlan_del(struct dsa_switch *ds, int port,
+				const struct switchdev_obj_port_vlan *vlan)
+{
+	struct an8855_priv *priv = ds->priv;
+	u32 val;
+	int ret;
+
+	mutex_lock(&priv->reg_mutex);
+	ret = an8855_vlan_del(priv, port, vlan->vid);
+	mutex_unlock(&priv->reg_mutex);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
+	if (ret)
+		return ret;
+
+	/* PVID is being restored to the default whenever the PVID port
+	 * is being removed from the VLAN.
+	 */
+	if (FIELD_GET(AN8855_G0_PORT_VID, val) == vlan->vid) {
+		/* Only accept tagged frames if the port is VLAN-aware */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
+			ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(port),
+						 AN8855_ACC_FRM,
+						 FIELD_PREP(AN8855_ACC_FRM,
+							    AN8855_VLAN_ACC_TAGGED));
+			if (ret)
+				return ret;
+		}
+
+		ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+an8855_port_mdb_add(struct dsa_switch *ds, int port,
+		    const struct switchdev_obj_port_mdb *mdb,
+		    struct dsa_db db)
+{
+	struct an8855_priv *priv = ds->priv;
+	const u8 *addr = mdb->addr;
+	u16 vid = mdb->vid;
+	u8 port_mask = 0;
+	u32 val;
+	int ret;
+
+	/* Set the vid to the port vlan id if no vid is set */
+	if (!vid)
+		vid = AN8855_PORT_VID_DEFAULT;
+
+	mutex_lock(&priv->reg_mutex);
+
+	an8855_fdb_write(priv, vid, 0, addr, false);
+	if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) {
+		ret = regmap_read(priv->regmap, AN8855_ATRD3, &val);
+		if (ret)
+			goto exit;
+
+		port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val);
+	}
+
+	port_mask |= BIT(port);
+	an8855_fdb_write(priv, vid, port_mask, addr, true);
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+
+exit:
+	mutex_unlock(&priv->reg_mutex);
+
+	return ret;
+}
+
+static int
+an8855_port_mdb_del(struct dsa_switch *ds, int port,
+		    const struct switchdev_obj_port_mdb *mdb,
+		    struct dsa_db db)
+{
+	struct an8855_priv *priv = ds->priv;
+	const u8 *addr = mdb->addr;
+	u16 vid = mdb->vid;
+	u8 port_mask = 0;
+	u32 val;
+	int ret;
+
+	/* Set the vid to the port vlan id if no vid is set */
+	if (!vid)
+		vid = AN8855_PORT_VID_DEFAULT;
+
+	mutex_lock(&priv->reg_mutex);
+
+	an8855_fdb_write(priv, vid, 0, addr, 0);
+	if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) {
+		ret = regmap_read(priv->regmap, AN8855_ATRD3, &val);
+		if (ret)
+			goto exit;
+
+		port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val);
+	}
+
+	port_mask &= ~BIT(port);
+	an8855_fdb_write(priv, vid, port_mask, addr, port_mask ? true : false);
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+
+exit:
+	mutex_unlock(&priv->reg_mutex);
+
+	return ret;
+}
+
+static int
+an8855_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+	struct an8855_priv *priv = ds->priv;
+	int length;
+	u32 val;
+
+	/* When a new MTU is set, DSA always set the CPU port's MTU to the
+	 * largest MTU of the slave ports. Because the switch only has a global
+	 * RX length register, only allowing CPU port here is enough.
+	 */
+	if (!dsa_is_cpu_port(ds, port))
+		return 0;
+
+	/* RX length also includes Ethernet header, MTK tag, and FCS length */
+	length = new_mtu + ETH_HLEN + MTK_TAG_LEN + ETH_FCS_LEN;
+	if (length <= 1522)
+		val = AN8855_MAX_RX_PKT_1518_1522;
+	else if (length <= 1536)
+		val = AN8855_MAX_RX_PKT_1536;
+	else if (length <= 1552)
+		val = AN8855_MAX_RX_PKT_1552;
+	else if (length <= 3072)
+		val = AN8855_MAX_RX_JUMBO_3K;
+	else if (length <= 4096)
+		val = AN8855_MAX_RX_JUMBO_4K;
+	else if (length <= 5120)
+		val = AN8855_MAX_RX_JUMBO_5K;
+	else if (length <= 6144)
+		val = AN8855_MAX_RX_JUMBO_6K;
+	else if (length <= 7168)
+		val = AN8855_MAX_RX_JUMBO_7K;
+	else if (length <= 8192)
+		val = AN8855_MAX_RX_JUMBO_8K;
+	else if (length <= 9216)
+		val = AN8855_MAX_RX_JUMBO_9K;
+	else if (length <= 12288)
+		val = AN8855_MAX_RX_JUMBO_12K;
+	else if (length <= 15360)
+		val = AN8855_MAX_RX_JUMBO_15K;
+	else
+		val = AN8855_MAX_RX_JUMBO_16K;
+
+	/* Enable JUMBO packet */
+	if (length > 1552)
+		val |= AN8855_MAX_RX_PKT_JUMBO;
+
+	return regmap_update_bits(priv->regmap, AN8855_GMACCR,
+				  AN8855_MAX_RX_JUMBO | AN8855_MAX_RX_PKT_LEN,
+				  val);
+}
+
+static int
+an8855_port_max_mtu(struct dsa_switch *ds, int port)
+{
+	return AN8855_MAX_MTU;
+}
+
+static void
+an8855_get_strings(struct dsa_switch *ds, int port, u32 stringset,
+		   uint8_t *data)
+{
+	int i;
+
+	if (stringset != ETH_SS_STATS)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(an8855_mib); i++)
+		ethtool_puts(&data, an8855_mib[i].name);
+}
+
+static void
+an8855_read_port_stats(struct an8855_priv *priv, int port, u32 offset, u8 size,
+		       uint64_t *data)
+{
+	u32 val, reg = AN8855_PORT_MIB_COUNTER(port) + offset;
+
+	regmap_read(priv->regmap, reg, &val);
+	*data = val;
+
+	if (size == 2) {
+		regmap_read(priv->regmap, reg + 4, &val);
+		*data |= (u64)val << 32;
+	}
+}
+
+static void
+an8855_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data)
+{
+	struct an8855_priv *priv = ds->priv;
+	const struct an8855_mib_desc *mib;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(an8855_mib); i++) {
+		mib = &an8855_mib[i];
+
+		an8855_read_port_stats(priv, port, mib->offset, mib->size,
+				       data + i);
+	}
+}
+
+static int
+an8855_get_sset_count(struct dsa_switch *ds, int port, int sset)
+{
+	if (sset != ETH_SS_STATS)
+		return 0;
+
+	return ARRAY_SIZE(an8855_mib);
+}
+
+static void
+an8855_get_eth_mac_stats(struct dsa_switch *ds, int port,
+			 struct ethtool_eth_mac_stats *mac_stats)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	/* MIB counter doesn't provide a FramesTransmittedOK but instead
+	 * provide stats for Unicast, Broadcast and Multicast frames separately.
+	 * To simulate a global frame counter, read Unicast and addition Multicast
+	 * and Broadcast later
+	 */
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_UNICAST, 1,
+			       &mac_stats->FramesTransmittedOK);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_SINGLE_COLLISION, 1,
+			       &mac_stats->SingleCollisionFrames);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_MULTIPLE_COLLISION, 1,
+			       &mac_stats->MultipleCollisionFrames);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_UNICAST, 1,
+			       &mac_stats->FramesReceivedOK);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_BYTES, 2,
+			       &mac_stats->OctetsTransmittedOK);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_ALIGN_ERR, 1,
+			       &mac_stats->AlignmentErrors);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_DEFERRED, 1,
+			       &mac_stats->FramesWithDeferredXmissions);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_LATE_COLLISION, 1,
+			       &mac_stats->LateCollisions);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_EXCESSIVE_COLLISION, 1,
+			       &mac_stats->FramesAbortedDueToXSColls);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_BYTES, 2,
+			       &mac_stats->OctetsReceivedOK);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_MULTICAST, 1,
+			       &mac_stats->MulticastFramesXmittedOK);
+	mac_stats->FramesTransmittedOK += mac_stats->MulticastFramesXmittedOK;
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_BROADCAST, 1,
+			       &mac_stats->BroadcastFramesXmittedOK);
+	mac_stats->FramesTransmittedOK += mac_stats->BroadcastFramesXmittedOK;
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_MULTICAST, 1,
+			       &mac_stats->MulticastFramesReceivedOK);
+	mac_stats->FramesReceivedOK += mac_stats->MulticastFramesReceivedOK;
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_BROADCAST, 1,
+			       &mac_stats->BroadcastFramesReceivedOK);
+	mac_stats->FramesReceivedOK += mac_stats->BroadcastFramesReceivedOK;
+}
+
+static const struct ethtool_rmon_hist_range an8855_rmon_ranges[] = {
+	{ 0, 64 },
+	{ 65, 127 },
+	{ 128, 255 },
+	{ 256, 511 },
+	{ 512, 1023 },
+	{ 1024, 1518 },
+	{ 1519, AN8855_MAX_MTU },
+	{}
+};
+
+static void an8855_get_rmon_stats(struct dsa_switch *ds, int port,
+				  struct ethtool_rmon_stats *rmon_stats,
+				  const struct ethtool_rmon_hist_range **ranges)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_UNDER_SIZE_ERR, 1,
+			       &rmon_stats->undersize_pkts);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_OVER_SZ_ERR, 1,
+			       &rmon_stats->oversize_pkts);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_FRAG_ERR, 1,
+			       &rmon_stats->fragments);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_JABBER_ERR, 1,
+			       &rmon_stats->jabbers);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_64, 1,
+			       &rmon_stats->hist[0]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_65_TO_127, 1,
+			       &rmon_stats->hist[1]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_128_TO_255, 1,
+			       &rmon_stats->hist[2]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_256_TO_511, 1,
+			       &rmon_stats->hist[3]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_512_TO_1023, 1,
+			       &rmon_stats->hist[4]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_1024_TO_1518, 1,
+			       &rmon_stats->hist[5]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_1519_TO_MAX, 1,
+			       &rmon_stats->hist[6]);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_64, 1,
+			       &rmon_stats->hist_tx[0]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_65_TO_127, 1,
+			       &rmon_stats->hist_tx[1]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_128_TO_255, 1,
+			       &rmon_stats->hist_tx[2]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_256_TO_511, 1,
+			       &rmon_stats->hist_tx[3]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_512_TO_1023, 1,
+			       &rmon_stats->hist_tx[4]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_1024_TO_1518, 1,
+			       &rmon_stats->hist_tx[5]);
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_1519_TO_MAX, 1,
+			       &rmon_stats->hist_tx[6]);
+
+	*ranges = an8855_rmon_ranges;
+}
+
+static void an8855_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
+				      struct ethtool_eth_ctrl_stats *ctrl_stats)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PAUSE, 1,
+			       &ctrl_stats->MACControlFramesTransmitted);
+
+	an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PAUSE, 1,
+			       &ctrl_stats->MACControlFramesReceived);
+}
+
+static int an8855_port_mirror_add(struct dsa_switch *ds, int port,
+				  struct dsa_mall_mirror_tc_entry *mirror,
+				  bool ingress,
+				  struct netlink_ext_ack *extack)
+{
+	struct an8855_priv *priv = ds->priv;
+	int monitor_port;
+	u32 val;
+	int ret;
+
+	/* Check for existent entry */
+	if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
+		return -EEXIST;
+
+	ret = regmap_read(priv->regmap, AN8855_MIR, &val);
+	if (ret)
+		return ret;
+
+	/* AN8855 supports 4 monitor port, but only use first group */
+	monitor_port = FIELD_GET(AN8855_MIRROR_PORT, val);
+	if (val & AN8855_MIRROR_EN && monitor_port != mirror->to_local_port)
+		return -EEXIST;
+
+	val = AN8855_MIRROR_EN;
+	val |= FIELD_PREP(AN8855_MIRROR_PORT, mirror->to_local_port);
+	ret = regmap_update_bits(priv->regmap, AN8855_MIR,
+				 AN8855_MIRROR_EN | AN8855_MIRROR_PORT,
+				 val);
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(priv->regmap, AN8855_PCR_P(port),
+			      ingress ? AN8855_PORT_RX_MIR : AN8855_PORT_TX_MIR);
+	if (ret)
+		return ret;
+
+	if (ingress)
+		priv->mirror_rx |= BIT(port);
+	else
+		priv->mirror_tx |= BIT(port);
+
+	return 0;
+}
+
+static void an8855_port_mirror_del(struct dsa_switch *ds, int port,
+				   struct dsa_mall_mirror_tc_entry *mirror)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	if (mirror->ingress)
+		priv->mirror_rx &= ~BIT(port);
+	else
+		priv->mirror_tx &= ~BIT(port);
+
+	regmap_clear_bits(priv->regmap, AN8855_PCR_P(port),
+			  mirror->ingress ? AN8855_PORT_RX_MIR :
+					    AN8855_PORT_TX_MIR);
+
+	if (!priv->mirror_rx && !priv->mirror_tx)
+		regmap_clear_bits(priv->regmap, AN8855_MIR, AN8855_MIRROR_EN);
+}
+
+static int an8855_port_set_status(struct an8855_priv *priv, int port,
+				  bool enable)
+{
+	if (enable)
+		return regmap_set_bits(priv->regmap, AN8855_PMCR_P(port),
+				       AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
+	else
+		return regmap_clear_bits(priv->regmap, AN8855_PMCR_P(port),
+					 AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
+}
+
+static int an8855_port_enable(struct dsa_switch *ds, int port,
+			      struct phy_device *phy)
+{
+	return an8855_port_set_status(ds->priv, port, true);
+}
+
+static void an8855_port_disable(struct dsa_switch *ds, int port)
+{
+	an8855_port_set_status(ds->priv, port, false);
+}
+
+static u32 en8855_get_phy_flags(struct dsa_switch *ds, int port)
+{
+	struct an8855_priv *priv = ds->priv;
+
+	/* PHY doesn't need calibration */
+	if (!priv->phy_require_calib)
+		return 0;
+
+	/* Use AN8855_PHY_FLAGS_EN_CALIBRATION to signal
+	 * calibration needed.
+	 */
+	return AN8855_PHY_FLAGS_EN_CALIBRATION;
+}
+
+static enum dsa_tag_protocol
+an8855_get_tag_protocol(struct dsa_switch *ds, int port,
+			enum dsa_tag_protocol mp)
+{
+	return DSA_TAG_PROTO_MTK;
+}
+
+/* Similar to MT7530 also trap link local frame and special frame to CPU */
+static int an8855_trap_special_frames(struct an8855_priv *priv)
+{
+	int ret;
+
+	/* Trap BPDUs to the CPU port(s) and egress them
+	 * VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_BPC,
+				 AN8855_BPDU_BPDU_FR | AN8855_BPDU_EG_TAG |
+				 AN8855_BPDU_PORT_FW,
+				 AN8855_BPDU_BPDU_FR |
+				 FIELD_PREP(AN8855_BPDU_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_BPDU_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap 802.1X PAE frames to the CPU port(s) and egress them
+	 * VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_PAC,
+				 AN8855_PAE_BPDU_FR | AN8855_PAE_EG_TAG |
+				 AN8855_PAE_PORT_FW,
+				 AN8855_PAE_BPDU_FR |
+				 FIELD_PREP(AN8855_PAE_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_PAE_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap frames with :01 MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_RGAC1,
+				 AN8855_R01_BPDU_FR | AN8855_R01_EG_TAG |
+				 AN8855_R01_PORT_FW,
+				 AN8855_R01_BPDU_FR |
+				 FIELD_PREP(AN8855_R01_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_R01_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap frames with :02 MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_RGAC1,
+				 AN8855_R02_BPDU_FR | AN8855_R02_EG_TAG |
+				 AN8855_R02_PORT_FW,
+				 AN8855_R02_BPDU_FR |
+				 FIELD_PREP(AN8855_R02_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_R02_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap frames with :03 MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_RGAC1,
+				 AN8855_R03_BPDU_FR | AN8855_R03_EG_TAG |
+				 AN8855_R03_PORT_FW,
+				 AN8855_R03_BPDU_FR |
+				 FIELD_PREP(AN8855_R03_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				 FIELD_PREP(AN8855_R03_PORT_FW, AN8855_BPDU_CPU_ONLY));
+	if (ret)
+		return ret;
+
+	/* Trap frames with :0E MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	return regmap_update_bits(priv->regmap, AN8855_RGAC1,
+				  AN8855_R0E_BPDU_FR | AN8855_R0E_EG_TAG |
+				  AN8855_R0E_PORT_FW,
+				  AN8855_R0E_BPDU_FR |
+				  FIELD_PREP(AN8855_R0E_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+				  FIELD_PREP(AN8855_R0E_PORT_FW, AN8855_BPDU_CPU_ONLY));
+}
+
+static int
+an8855_setup_pvid_vlan(struct an8855_priv *priv)
+{
+	u32 val;
+	int ret;
+
+	/* Validate the entry with independent learning, keep the original
+	 * ingress tag attribute.
+	 */
+	val = AN8855_VA0_IVL_MAC | AN8855_VA0_EG_CON |
+	      FIELD_PREP(AN8855_VA0_FID, AN8855_FID_BRIDGED) |
+	      AN8855_VA0_PORT | AN8855_VA0_VLAN_VALID;
+	ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
+	if (ret)
+		return ret;
+
+	return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID,
+			       AN8855_PORT_VID_DEFAULT);
+}
+
+static int an8855_setup(struct dsa_switch *ds)
+{
+	struct an8855_priv *priv = ds->priv;
+	struct dsa_port *dp;
+	int ret;
+
+	/* Enable and reset MIB counters */
+	ret = an8855_mib_init(priv);
+	if (ret)
+		return ret;
+
+	dsa_switch_for_each_user_port(dp, ds) {
+		/* Disable MAC by default on all user ports */
+		ret = an8855_port_set_status(priv, dp->index, false);
+		if (ret)
+			return ret;
+
+		/* Individual user ports get connected to CPU port only */
+		ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(dp->index),
+				   FIELD_PREP(AN8855_PORTMATRIX, BIT(AN8855_CPU_PORT)));
+		if (ret)
+			return ret;
+
+		/* Disable Broadcast Forward on user ports */
+		ret = regmap_clear_bits(priv->regmap, AN8855_BCF, BIT(dp->index));
+		if (ret)
+			return ret;
+
+		/* Disable Unknown Unicast Forward on user ports */
+		ret = regmap_clear_bits(priv->regmap, AN8855_UNUF, BIT(dp->index));
+		if (ret)
+			return ret;
+
+		/* Disable Unknown Multicast Forward on user ports */
+		ret = regmap_clear_bits(priv->regmap, AN8855_UNMF, BIT(dp->index));
+		if (ret)
+			return ret;
+
+		ret = regmap_clear_bits(priv->regmap, AN8855_UNIPMF, BIT(dp->index));
+		if (ret)
+			return ret;
+
+		/* Set default PVID to on all user ports */
+		ret = an8855_port_set_pid(priv, dp->index, AN8855_PORT_VID_DEFAULT);
+		if (ret)
+			return ret;
+	}
+
+	/* Enable Airoha header mode on the cpu port */
+	ret = regmap_write(priv->regmap, AN8855_PVC_P(AN8855_CPU_PORT),
+			   AN8855_PORT_SPEC_REPLACE_MODE | AN8855_PORT_SPEC_TAG);
+	if (ret)
+		return ret;
+
+	/* Unknown multicast frame forwarding to the cpu port */
+	ret = regmap_write(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* Set CPU port number */
+	ret = regmap_update_bits(priv->regmap, AN8855_MFC,
+				 AN8855_CPU_EN | AN8855_CPU_PORT_IDX,
+				 AN8855_CPU_EN |
+				 FIELD_PREP(AN8855_CPU_PORT_IDX, AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* CPU port gets connected to all user ports of
+	 * the switch.
+	 */
+	ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(AN8855_CPU_PORT),
+			   FIELD_PREP(AN8855_PORTMATRIX, dsa_user_ports(ds)));
+	if (ret)
+		return ret;
+
+	/* CPU port is set to fallback mode to let untagged
+	 * frames pass through.
+	 */
+	ret = regmap_update_bits(priv->regmap, AN8855_PCR_P(AN8855_CPU_PORT),
+				 AN8855_PORT_VLAN,
+				 FIELD_PREP(AN8855_PORT_VLAN, AN8855_PORT_FALLBACK_MODE));
+	if (ret)
+		return ret;
+
+	/* Enable Broadcast Forward on CPU port */
+	ret = regmap_set_bits(priv->regmap, AN8855_BCF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* Enable Unknown Unicast Forward on CPU port */
+	ret = regmap_set_bits(priv->regmap, AN8855_UNUF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* Enable Unknown Multicast Forward on CPU port */
+	ret = regmap_set_bits(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(priv->regmap, AN8855_UNIPMF, BIT(AN8855_CPU_PORT));
+	if (ret)
+		return ret;
+
+	/* Setup Trap special frame to CPU rules */
+	ret = an8855_trap_special_frames(priv);
+	if (ret)
+		return ret;
+
+	dsa_switch_for_each_port(dp, ds) {
+		/* Disable Learning on all ports.
+		 * Learning on CPU is disabled for fdb isolation and handled by
+		 * assisted_learning_on_cpu_port.
+		 */
+		ret = regmap_set_bits(priv->regmap, AN8855_PSC_P(dp->index),
+				      AN8855_SA_DIS);
+		if (ret)
+			return ret;
+
+		/* Enable consistent egress tag (for VLAN unware VLAN-passtrough) */
+		ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(dp->index),
+					 AN8855_PVC_EG_TAG,
+					 FIELD_PREP(AN8855_PVC_EG_TAG, AN8855_VLAN_EG_CONSISTENT));
+		if (ret)
+			return ret;
+	}
+
+	/* Setup VLAN for Default PVID */
+	ret = an8855_setup_pvid_vlan(priv);
+	if (ret)
+		return ret;
+
+	ret = regmap_clear_bits(priv->regmap, AN8855_CKGCR,
+				AN8855_CKG_LNKDN_GLB_STOP | AN8855_CKG_LNKDN_PORT_STOP);
+	if (ret)
+		return ret;
+
+	/* Release global PHY power down */
+	ret = regmap_write(priv->regmap, AN8855_RG_GPHY_AFE_PWD, 0x0);
+	if (ret)
+		return ret;
+
+	ds->configure_vlan_while_not_filtering = true;
+
+	/* Flush the FDB table */
+	ret = an8855_fdb_cmd(priv, AN8855_FDB_FLUSH, NULL);
+	if (ret < 0)
+		return ret;
+
+	/* Set min a max ageing value supported */
+	ds->ageing_time_min = AN8855_L2_AGING_MS_CONSTANT;
+	ds->ageing_time_max = FIELD_MAX(AN8855_AGE_CNT) *
+			      FIELD_MAX(AN8855_AGE_UNIT) *
+			      AN8855_L2_AGING_MS_CONSTANT;
+
+	/* Enable assisted learning for fdb isolation */
+	ds->assisted_learning_on_cpu_port = true;
+
+	return 0;
+}
+
+static struct phylink_pcs *an8855_phylink_mac_select_pcs(struct phylink_config *config,
+							 phy_interface_t interface)
+{
+	struct dsa_port *dp = dsa_phylink_to_port(config);
+	struct an8855_priv *priv = dp->ds->priv;
+
+	switch (interface) {
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_2500BASEX:
+		return &priv->pcs;
+	default:
+		return NULL;
+	}
+}
+
+static void an8855_phylink_mac_config(struct phylink_config *config,
+				      unsigned int mode,
+				      const struct phylink_link_state *state)
+{
+	struct dsa_port *dp = dsa_phylink_to_port(config);
+	struct dsa_switch *ds = dp->ds;
+	struct an8855_priv *priv;
+	int port = dp->index;
+
+	priv = ds->priv;
+
+	/* Nothing to configure for internal ports */
+	if (port != 5)
+		return;
+
+	regmap_update_bits(priv->regmap, AN8855_PMCR_P(port),
+			   AN8855_PMCR_IFG_XMIT | AN8855_PMCR_MAC_MODE |
+			   AN8855_PMCR_BACKOFF_EN | AN8855_PMCR_BACKPR_EN,
+			   FIELD_PREP(AN8855_PMCR_IFG_XMIT, 0x1) |
+			   AN8855_PMCR_MAC_MODE | AN8855_PMCR_BACKOFF_EN |
+			   AN8855_PMCR_BACKPR_EN);
+}
+
+static void an8855_phylink_get_caps(struct dsa_switch *ds, int port,
+				    struct phylink_config *config)
+{
+	switch (port) {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+		__set_bit(PHY_INTERFACE_MODE_GMII,
+			  config->supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
+			  config->supported_interfaces);
+		break;
+	case 5:
+		phy_interface_set_rgmii(config->supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_SGMII,
+			  config->supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
+			  config->supported_interfaces);
+		break;
+	}
+
+	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+				   MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
+}
+
+static void an8855_phylink_mac_link_down(struct phylink_config *config,
+					 unsigned int mode,
+					 phy_interface_t interface)
+{
+	struct dsa_port *dp = dsa_phylink_to_port(config);
+	struct an8855_priv *priv = dp->ds->priv;
+
+	/* With autoneg just disable TX/RX else also force link down */
+	if (phylink_autoneg_inband(mode)) {
+		regmap_clear_bits(priv->regmap, AN8855_PMCR_P(dp->index),
+				  AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
+	} else {
+		regmap_update_bits(priv->regmap, AN8855_PMCR_P(dp->index),
+				   AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN |
+				   AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK,
+				   AN8855_PMCR_FORCE_MODE);
+	}
+}
+
+static void an8855_phylink_mac_link_up(struct phylink_config *config,
+				       struct phy_device *phydev, unsigned int mode,
+				       phy_interface_t interface, int speed,
+				       int duplex, bool tx_pause, bool rx_pause)
+{
+	struct dsa_port *dp = dsa_phylink_to_port(config);
+	struct an8855_priv *priv = dp->ds->priv;
+	int port = dp->index;
+	u32 reg;
+
+	reg = regmap_read(priv->regmap, AN8855_PMCR_P(port), &reg);
+	if (phylink_autoneg_inband(mode)) {
+		reg &= ~AN8855_PMCR_FORCE_MODE;
+	} else {
+		reg |= AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK;
+
+		reg &= ~AN8855_PMCR_FORCE_SPEED;
+		switch (speed) {
+		case SPEED_10:
+			reg |= AN8855_PMCR_FORCE_SPEED_10;
+			break;
+		case SPEED_100:
+			reg |= AN8855_PMCR_FORCE_SPEED_100;
+			break;
+		case SPEED_1000:
+			reg |= AN8855_PMCR_FORCE_SPEED_1000;
+			break;
+		case SPEED_2500:
+			reg |= AN8855_PMCR_FORCE_SPEED_2500;
+			break;
+		case SPEED_5000:
+			dev_err(priv->dev, "Missing support for 5G speed. Aborting...\n");
+			return;
+		}
+
+		reg &= ~AN8855_PMCR_FORCE_FDX;
+		if (duplex == DUPLEX_FULL)
+			reg |= AN8855_PMCR_FORCE_FDX;
+
+		reg &= ~AN8855_PMCR_RX_FC_EN;
+		if (rx_pause || dsa_port_is_cpu(dp))
+			reg |= AN8855_PMCR_RX_FC_EN;
+
+		reg &= ~AN8855_PMCR_TX_FC_EN;
+		if (rx_pause || dsa_port_is_cpu(dp))
+			reg |= AN8855_PMCR_TX_FC_EN;
+
+		/* Disable any EEE options */
+		reg &= ~(AN8855_PMCR_FORCE_EEE5G | AN8855_PMCR_FORCE_EEE2P5G |
+			 AN8855_PMCR_FORCE_EEE1G | AN8855_PMCR_FORCE_EEE100);
+	}
+
+	reg |= AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN;
+
+	regmap_write(priv->regmap, AN8855_PMCR_P(port), reg);
+}
+
+static unsigned int an8855_pcs_inband_caps(struct phylink_pcs *pcs,
+					   phy_interface_t interface)
+{
+	/* SGMII can be configured to use inband with AN result */
+	if (interface == PHY_INTERFACE_MODE_SGMII)
+		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+
+	/* inband is not supported in 2500-baseX and must be disabled */
+	return  LINK_INBAND_DISABLE;
+}
+
+static void an8855_pcs_get_state(struct phylink_pcs *pcs,
+				 struct phylink_link_state *state)
+{
+	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
+	u32 val;
+	int ret;
+
+	ret = regmap_read(priv->regmap, AN8855_PMSR_P(AN8855_CPU_PORT), &val);
+	if (ret < 0) {
+		state->link = false;
+		return;
+	}
+
+	state->link = !!(val & AN8855_PMSR_LNK);
+	state->an_complete = state->link;
+	state->duplex = (val & AN8855_PMSR_DPX) ? DUPLEX_FULL :
+						  DUPLEX_HALF;
+
+	switch (val & AN8855_PMSR_SPEED) {
+	case AN8855_PMSR_SPEED_10:
+		state->speed = SPEED_10;
+		break;
+	case AN8855_PMSR_SPEED_100:
+		state->speed = SPEED_100;
+		break;
+	case AN8855_PMSR_SPEED_1000:
+		state->speed = SPEED_1000;
+		break;
+	case AN8855_PMSR_SPEED_2500:
+		state->speed = SPEED_2500;
+		break;
+	case AN8855_PMSR_SPEED_5000:
+		dev_err(priv->dev, "Missing support for 5G speed. Setting Unknown.\n");
+		fallthrough;
+	default:
+		state->speed = SPEED_UNKNOWN;
+		break;
+	}
+
+	if (val & AN8855_PMSR_RX_FC)
+		state->pause |= MLO_PAUSE_RX;
+	if (val & AN8855_PMSR_TX_FC)
+		state->pause |= MLO_PAUSE_TX;
+}
+
+static int an8855_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+			     phy_interface_t interface,
+			     const unsigned long *advertising,
+			     bool permit_pause_to_mac)
+{
+	struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
+	u32 val;
+	int ret;
+
+	/*                   !!! WELCOME TO HELL !!!                   */
+
+	/* TX FIR - improve TX EYE */
+	ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_10,
+				 AN8855_RG_DA_QP_TX_FIR_C2_SEL |
+				 AN8855_RG_DA_QP_TX_FIR_C2_FORCE |
+				 AN8855_RG_DA_QP_TX_FIR_C1_SEL |
+				 AN8855_RG_DA_QP_TX_FIR_C1_FORCE,
+				 AN8855_RG_DA_QP_TX_FIR_C2_SEL |
+				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C2_FORCE, 0x4) |
+				 AN8855_RG_DA_QP_TX_FIR_C1_SEL |
+				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C1_FORCE, 0x0));
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x0;
+	else
+		val = 0xd;
+	ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_11,
+				 AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
+				 AN8855_RG_DA_QP_TX_FIR_C0B_FORCE,
+				 AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
+				 FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C0B_FORCE, val));
+	if (ret)
+		return ret;
+
+	/* RX CDR - improve RX Jitter Tolerance */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x5;
+	else
+		val = 0x6;
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_BOT_LIM,
+				 AN8855_RG_QP_CDR_LPF_KP_GAIN |
+				 AN8855_RG_QP_CDR_LPF_KI_GAIN,
+				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_KP_GAIN, val) |
+				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_KI_GAIN, val));
+	if (ret)
+		return ret;
+
+	/* PLL */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x1;
+	else
+		val = 0x0;
+	ret = regmap_update_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_1,
+				 AN8855_RG_TPHY_SPEED,
+				 FIELD_PREP(AN8855_RG_TPHY_SPEED, val));
+	if (ret)
+		return ret;
+
+	/* PLL - LPF */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
+				 AN8855_RG_DA_QP_PLL_FBKSEL_INTF |
+				 AN8855_RG_DA_QP_PLL_BR_INTF |
+				 AN8855_RG_DA_QP_PLL_BPD_INTF |
+				 AN8855_RG_DA_QP_PLL_BPA_INTF |
+				 AN8855_RG_DA_QP_PLL_BC_INTF,
+				 AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_FBKSEL_INTF, 0x0) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BR_INTF, 0x3) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BPD_INTF, 0x0) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BPA_INTF, 0x5) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_BC_INTF, 0x1));
+	if (ret)
+		return ret;
+
+	/* PLL - ICO */
+	ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_4,
+			      AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF);
+	if (ret)
+		return ret;
+	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF);
+	if (ret)
+		return ret;
+
+	/* PLL - CHP */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x6;
+	else
+		val = 0x4;
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_IR_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_IR_INTF, val));
+	if (ret)
+		return ret;
+
+	/* PLL - PFD */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF |
+				 AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF |
+				 AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF, 0x1) |
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF, 0x1));
+	if (ret)
+		return ret;
+
+	/* PLL - POSTDIV */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF |
+				 AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF |
+				 AN8855_RG_DA_QP_PLL_PCK_SEL_INTF,
+				 AN8855_RG_DA_QP_PLL_PCK_SEL_INTF);
+	if (ret)
+		return ret;
+
+	/* PLL - SDM */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				 AN8855_RG_DA_QP_PLL_SDM_HREN_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SDM_HREN_INTF, 0x0));
+	if (ret)
+		return ret;
+	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
+				AN8855_RG_DA_QP_PLL_SDM_IFM_INTF);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_SS_LCPLL_PWCTL_SETTING_2,
+				 AN8855_RG_NCPO_ANA_MSB,
+				 FIELD_PREP(AN8855_RG_NCPO_ANA_MSB, 0x1));
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x7a000000;
+	else
+		val = 0x48000000;
+	ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_2,
+			   FIELD_PREP(AN8855_RG_LCPLL_NCPO_VALUE, val));
+	if (ret)
+		return ret;
+	ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_PCW_1,
+			   FIELD_PREP(AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON, val));
+	if (ret)
+		return ret;
+
+	ret = regmap_clear_bits(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_5,
+				AN8855_RG_LCPLL_NCPO_CHG);
+	if (ret)
+		return ret;
+	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
+				AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF);
+	if (ret)
+		return ret;
+
+	/* PLL - SS */
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
+				 AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF, 0x0));
+	if (ret)
+		return ret;
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_4,
+				 AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF, 0x0));
+	if (ret)
+		return ret;
+	ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
+				 AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF,
+				 FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF, 0x0));
+	if (ret)
+		return ret;
+
+	/* PLL - TDC */
+	ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
+				AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF);
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
+			      AN8855_RG_QP_PLL_SSC_TRI_EN);
+	if (ret)
+		return ret;
+	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
+			      AN8855_RG_QP_PLL_SSC_PHASE_INI);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_RX_DAC_EN,
+				 AN8855_RG_QP_SIGDET_HF,
+				 FIELD_PREP(AN8855_RG_QP_SIGDET_HF, 0x2));
+	if (ret)
+		return ret;
+
+	/* TCL Disable (only for Co-SIM) */
+	ret = regmap_clear_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_0,
+				AN8855_RG_QP_EQ_RX500M_CK_SEL);
+	if (ret)
+		return ret;
+
+	/* TX Init */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x4;
+	else
+		val = 0x0;
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_TX_MODE,
+				 AN8855_RG_QP_TX_RESERVE |
+				 AN8855_RG_QP_TX_MODE_16B_EN,
+				 FIELD_PREP(AN8855_RG_QP_TX_RESERVE, val));
+	if (ret)
+		return ret;
+
+	/* RX Control/Init */
+	ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_RXAFE_RESERVE,
+			      AN8855_RG_QP_CDR_PD_10B_EN);
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x1;
+	else
+		val = 0x2;
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_MJV_LIM,
+				 AN8855_RG_QP_CDR_LPF_RATIO,
+				 FIELD_PREP(AN8855_RG_QP_CDR_LPF_RATIO, val));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_SETVALUE,
+				 AN8855_RG_QP_CDR_PR_BUF_IN_SR |
+				 AN8855_RG_QP_CDR_PR_BETA_SEL,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_BUF_IN_SR, 0x6) |
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_BETA_SEL, 0x1));
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0xf;
+	else
+		val = 0xc;
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
+				 AN8855_RG_QP_CDR_PR_DAC_BAND,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_DAC_BAND, val));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
+				 AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE |
+				 AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK, 0x19));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF,
+				 AN8855_RG_QP_CDR_PHYCK_SEL |
+				 AN8855_RG_QP_CDR_PHYCK_RSTB |
+				 AN8855_RG_QP_CDR_PHYCK_DIV,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_SEL, 0x2) |
+				 FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_DIV, 0x21));
+	if (ret)
+		return ret;
+
+	ret = regmap_clear_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
+				AN8855_RG_QP_CDR_PR_XFICK_EN);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
+				 AN8855_RG_QP_CDR_PR_KBAND_DIV,
+				 FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV, 0x4));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_26,
+				 AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
+				 AN8855_RG_LINK_NE_EN |
+				 AN8855_RG_LINK_ERRO_EN,
+				 AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
+				 AN8855_RG_LINK_ERRO_EN);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_DLY_0,
+				 AN8855_RG_QP_RX_SAOSC_EN_H_DLY |
+				 AN8855_RG_QP_RX_PI_CAL_EN_H_DLY,
+				 FIELD_PREP(AN8855_RG_QP_RX_SAOSC_EN_H_DLY, 0x3f) |
+				 FIELD_PREP(AN8855_RG_QP_RX_PI_CAL_EN_H_DLY, 0x6f));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_42,
+				 AN8855_RG_QP_EQ_EN_DLY,
+				 FIELD_PREP(AN8855_RG_QP_EQ_EN_DLY, 0x150));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_2,
+				 AN8855_RG_QP_RX_EQ_EN_H_DLY,
+				 FIELD_PREP(AN8855_RG_QP_RX_EQ_EN_H_DLY, 0x150));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_9,
+				 AN8855_RG_QP_EQ_LEQOSC_DLYCNT,
+				 FIELD_PREP(AN8855_RG_QP_EQ_LEQOSC_DLYCNT, 0x1));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_8,
+				 AN8855_RG_DA_QP_SAOSC_DONE_TIME |
+				 AN8855_RG_DA_QP_LEQOS_EN_TIME,
+				 FIELD_PREP(AN8855_RG_DA_QP_SAOSC_DONE_TIME, 0x200) |
+				 FIELD_PREP(AN8855_RG_DA_QP_LEQOS_EN_TIME, 0xfff));
+	if (ret)
+		return ret;
+
+	/* Frequency meter */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
+		val = 0x10;
+	else
+		val = 0x28;
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_5,
+				 AN8855_RG_FREDET_CHK_CYCLE,
+				 FIELD_PREP(AN8855_RG_FREDET_CHK_CYCLE, val));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_6,
+				 AN8855_RG_FREDET_GOLDEN_CYCLE,
+				 FIELD_PREP(AN8855_RG_FREDET_GOLDEN_CYCLE, 0x64));
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_7,
+				 AN8855_RG_FREDET_TOLERATE_CYCLE,
+				 FIELD_PREP(AN8855_RG_FREDET_TOLERATE_CYCLE, 0x2710));
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_0,
+			      AN8855_RG_PHYA_AUTO_INIT);
+	if (ret)
+		return ret;
+
+	/* PCS Init */
+	if (interface == PHY_INTERFACE_MODE_SGMII &&
+	    neg_mode == PHYLINK_PCS_NEG_INBAND_DISABLED) {
+		ret = regmap_clear_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_0,
+					AN8855_RG_SGMII_MODE | AN8855_RG_SGMII_AN_EN);
+		if (ret)
+			return ret;
+	}
+
+	ret = regmap_clear_bits(priv->regmap, AN8855_RG_HSGMII_PCS_CTROL_1,
+				AN8855_RG_TBI_10B_MODE);
+	if (ret)
+		return ret;
+
+	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+		/* Set AN Ability - Interrupt */
+		ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN_FORCE_CL37,
+				      AN8855_RG_FORCE_AN_DONE);
+		if (ret)
+			return ret;
+
+		ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN_13,
+					 AN8855_SGMII_REMOTE_FAULT_DIS |
+					 AN8855_SGMII_IF_MODE,
+					 AN8855_SGMII_REMOTE_FAULT_DIS |
+					 FIELD_PREP(AN8855_SGMII_IF_MODE, 0xb));
+		if (ret)
+			return ret;
+	}
+
+	/* Rate Adaption - GMII path config. */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX) {
+		ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
+					AN8855_RG_P0_DIS_MII_MODE);
+		if (ret)
+			return ret;
+	} else {
+		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+			ret = regmap_set_bits(priv->regmap, AN8855_MII_RA_AN_ENABLE,
+					      AN8855_RG_P0_RA_AN_EN);
+			if (ret)
+				return ret;
+		} else {
+			ret = regmap_update_bits(priv->regmap, AN8855_RG_AN_SGMII_MODE_FORCE,
+						 AN8855_RG_FORCE_CUR_SGMII_MODE |
+						 AN8855_RG_FORCE_CUR_SGMII_SEL,
+						 AN8855_RG_FORCE_CUR_SGMII_SEL);
+			if (ret)
+				return ret;
+
+			ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
+						AN8855_RG_P0_MII_RA_RX_EN |
+						AN8855_RG_P0_MII_RA_TX_EN |
+						AN8855_RG_P0_MII_RA_RX_MODE |
+						AN8855_RG_P0_MII_RA_TX_MODE);
+			if (ret)
+				return ret;
+		}
+
+		ret = regmap_set_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
+				      AN8855_RG_P0_MII_MODE);
+		if (ret)
+			return ret;
+	}
+
+	ret = regmap_set_bits(priv->regmap, AN8855_RG_RATE_ADAPT_CTRL_0,
+			      AN8855_RG_RATE_ADAPT_RX_BYPASS |
+			      AN8855_RG_RATE_ADAPT_TX_BYPASS |
+			      AN8855_RG_RATE_ADAPT_RX_EN |
+			      AN8855_RG_RATE_ADAPT_TX_EN);
+	if (ret)
+		return ret;
+
+	/* Disable AN if not in autoneg */
+	ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN0, BMCR_ANENABLE,
+				 neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE :
+									      0);
+	if (ret)
+		return ret;
+
+	if (interface == PHY_INTERFACE_MODE_SGMII) {
+		/* Follow SDK init flow with restarting AN after AN enable */
+		if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+			ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN0,
+					      BMCR_ANRESTART);
+			if (ret)
+				return ret;
+		} else {
+			ret = regmap_set_bits(priv->regmap, AN8855_PHY_RX_FORCE_CTRL_0,
+					      AN8855_RG_FORCE_TXC_SEL);
+			if (ret)
+				return ret;
+		}
+	}
+
+	/* Force Speed with fixed-link or 2500base-x as doesn't support aneg */
+	if (interface == PHY_INTERFACE_MODE_2500BASEX ||
+	    neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
+		if (interface == PHY_INTERFACE_MODE_2500BASEX)
+			val = AN8855_RG_LINK_MODE_P0_SPEED_2500;
+		else
+			val = AN8855_RG_LINK_MODE_P0_SPEED_1000;
+		ret = regmap_update_bits(priv->regmap, AN8855_SGMII_STS_CTRL_0,
+					 AN8855_RG_LINK_MODE_P0 |
+					 AN8855_RG_FORCE_SPD_MODE_P0,
+					 val | AN8855_RG_FORCE_SPD_MODE_P0);
+		if (ret)
+			return ret;
+	}
+
+	/* bypass flow control to MAC */
+	ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_0,
+			   AN8855_RG_DPX_STS_P3 | AN8855_RG_DPX_STS_P2 |
+			   AN8855_RG_DPX_STS_P1 | AN8855_RG_TXFC_STS_P0 |
+			   AN8855_RG_RXFC_STS_P0 | AN8855_RG_DPX_STS_P0);
+	if (ret)
+		return ret;
+	ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_2,
+			   AN8855_RG_RXFC_AN_BYPASS_P3 |
+			   AN8855_RG_RXFC_AN_BYPASS_P2 |
+			   AN8855_RG_RXFC_AN_BYPASS_P1 |
+			   AN8855_RG_TXFC_AN_BYPASS_P3 |
+			   AN8855_RG_TXFC_AN_BYPASS_P2 |
+			   AN8855_RG_TXFC_AN_BYPASS_P1 |
+			   AN8855_RG_DPX_AN_BYPASS_P3 |
+			   AN8855_RG_DPX_AN_BYPASS_P2 |
+			   AN8855_RG_DPX_AN_BYPASS_P1 |
+			   AN8855_RG_DPX_AN_BYPASS_P0);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void an8855_pcs_an_restart(struct phylink_pcs *pcs)
+{
+	return;
+}
+
+static const struct phylink_pcs_ops an8855_pcs_ops = {
+	.pcs_inband_caps = an8855_pcs_inband_caps,
+	.pcs_get_state = an8855_pcs_get_state,
+	.pcs_config = an8855_pcs_config,
+	.pcs_an_restart = an8855_pcs_an_restart,
+};
+
+static const struct phylink_mac_ops an8855_phylink_mac_ops = {
+	.mac_select_pcs	= an8855_phylink_mac_select_pcs,
+	.mac_config	= an8855_phylink_mac_config,
+	.mac_link_down	= an8855_phylink_mac_link_down,
+	.mac_link_up	= an8855_phylink_mac_link_up,
+};
+
+static const struct dsa_switch_ops an8855_switch_ops = {
+	.get_tag_protocol = an8855_get_tag_protocol,
+	.setup = an8855_setup,
+	.get_phy_flags = en8855_get_phy_flags,
+	.phylink_get_caps = an8855_phylink_get_caps,
+	.get_strings = an8855_get_strings,
+	.get_ethtool_stats = an8855_get_ethtool_stats,
+	.get_sset_count = an8855_get_sset_count,
+	.get_eth_mac_stats = an8855_get_eth_mac_stats,
+	.get_eth_ctrl_stats = an8855_get_eth_ctrl_stats,
+	.get_rmon_stats = an8855_get_rmon_stats,
+	.port_enable = an8855_port_enable,
+	.port_disable = an8855_port_disable,
+	.set_ageing_time = an8855_set_ageing_time,
+	.port_bridge_join = an8855_port_bridge_join,
+	.port_bridge_leave = an8855_port_bridge_leave,
+	.port_fast_age = an8855_port_fast_age,
+	.port_stp_state_set = an8855_port_stp_state_set,
+	.port_pre_bridge_flags = an8855_port_pre_bridge_flags,
+	.port_bridge_flags = an8855_port_bridge_flags,
+	.port_vlan_filtering = an8855_port_vlan_filtering,
+	.port_vlan_add = an8855_port_vlan_add,
+	.port_vlan_del = an8855_port_vlan_del,
+	.port_fdb_add = an8855_port_fdb_add,
+	.port_fdb_del = an8855_port_fdb_del,
+	.port_fdb_dump = an8855_port_fdb_dump,
+	.port_mdb_add = an8855_port_mdb_add,
+	.port_mdb_del = an8855_port_mdb_del,
+	.port_change_mtu = an8855_port_change_mtu,
+	.port_max_mtu = an8855_port_max_mtu,
+	.port_mirror_add = an8855_port_mirror_add,
+	.port_mirror_del = an8855_port_mirror_del,
+};
+
+static int an8855_read_switch_id(struct an8855_priv *priv)
+{
+	u32 id;
+	int ret;
+
+	ret = regmap_read(priv->regmap, AN8855_CREV, &id);
+	if (ret)
+		return ret;
+
+	if (id != AN8855_ID) {
+		dev_err(priv->dev,
+			"Switch id detected %x but expected %x\n",
+			id, AN8855_ID);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int an8855_switch_probe(struct platform_device *pdev)
+{
+	struct an8855_priv *priv;
+	u32 val;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
+	priv->phy_require_calib = of_property_read_bool(priv->dev->of_node,
+							"airoha,ext-surge");
+
+	priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
+						   GPIOD_OUT_LOW);
+	if (IS_ERR(priv->reset_gpio))
+		return PTR_ERR(priv->reset_gpio);
+
+	/* Get regmap from MFD */
+	priv->regmap = dev_get_regmap(priv->dev->parent, NULL);
+
+	if (priv->reset_gpio) {
+		usleep_range(100000, 150000);
+		gpiod_set_value_cansleep(priv->reset_gpio, 0);
+		usleep_range(100000, 150000);
+		gpiod_set_value_cansleep(priv->reset_gpio, 1);
+
+		/* Poll HWTRAP reg to wait for Switch to fully Init */
+		ret = regmap_read_poll_timeout(priv->regmap, AN8855_HWTRAP, val,
+					       val, 20, 200000);
+		if (ret)
+			return ret;
+	}
+
+	ret = an8855_read_switch_id(priv);
+	if (ret)
+		return ret;
+
+	priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
+	if (!priv->ds)
+		return -ENOMEM;
+
+	priv->ds->dev = priv->dev;
+	priv->ds->num_ports = AN8855_NUM_PORTS;
+	priv->ds->priv = priv;
+	priv->ds->ops = &an8855_switch_ops;
+	devm_mutex_init(priv->dev, &priv->reg_mutex);
+	priv->ds->phylink_mac_ops = &an8855_phylink_mac_ops;
+
+	priv->pcs.ops = &an8855_pcs_ops;
+	priv->pcs.neg_mode = true;
+	priv->pcs.poll = true;
+
+	dev_set_drvdata(priv->dev, priv);
+
+	return dsa_register_switch(priv->ds);
+}
+
+static void an8855_switch_remove(struct platform_device *pdev)
+{
+	struct an8855_priv *priv = dev_get_drvdata(&pdev->dev);
+
+	if (!priv)
+		return;
+
+	dsa_unregister_switch(priv->ds);
+}
+
+static const struct of_device_id an8855_switch_of_match[] = {
+	{ .compatible = "airoha,an8855-switch" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, an8855_switch_of_match);
+
+static struct platform_driver an8855_switch_driver = {
+	.probe = an8855_switch_probe,
+	.remove = an8855_switch_remove,
+	.driver = {
+		.name = "an8855-switch",
+		.of_match_table = an8855_switch_of_match,
+	},
+};
+module_platform_driver(an8855_switch_driver);
+
+MODULE_AUTHOR("Min Yao <min.yao at airoha.com>");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_DESCRIPTION("Driver for Airoha AN8855 Switch");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/an8855.h b/drivers/net/dsa/an8855.h
new file mode 100644
index 000000000000..2462b9d33752
--- /dev/null
+++ b/drivers/net/dsa/an8855.h
@@ -0,0 +1,783 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 Min Yao <min.yao at airoha.com>
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth at gmail.com>
+ */
+
+#ifndef __AN8855_H
+#define __AN8855_H
+
+#include <linux/bitfield.h>
+
+#define AN8855_NUM_PORTS		6
+#define AN8855_CPU_PORT			5
+#define AN8855_NUM_FDB_RECORDS		2048
+#define AN8855_GPHY_SMI_ADDR_DEFAULT	1
+#define AN8855_PORT_VID_DEFAULT		0
+
+#define MTK_TAG_LEN			4
+#define AN8855_MAX_MTU			(15360 - ETH_HLEN - ETH_FCS_LEN - MTK_TAG_LEN)
+
+#define AN8855_L2_AGING_MS_CONSTANT	1024
+
+#define AN8855_PHY_FLAGS_EN_CALIBRATION	BIT(0)
+
+/*	AN8855_SCU			0x10000000 */
+#define AN8855_RG_GPIO_LED_MODE		0x10000054
+#define AN8855_RG_GPIO_LED_SEL(i)	(0x10000000 + (0x0058 + ((i) * 4)))
+#define AN8855_RG_INTB_MODE		0x10000080
+#define AN8855_RG_RGMII_TXCK_C		0x100001d0
+
+#define AN8855_PKG_SEL			0x10000094
+#define   AN8855_PAG_SEL_AN8855H	0x2
+
+/* Register for hw trap status */
+#define AN8855_HWTRAP			0x1000009c
+
+#define AN8855_RG_GPIO_L_INV		0x10000010
+#define AN8855_RG_GPIO_CTRL		0x1000a300
+#define AN8855_RG_GPIO_DATA		0x1000a304
+#define AN8855_RG_GPIO_OE		0x1000a314
+
+#define AN8855_CREV			0x10005000
+#define   AN8855_ID			0x8855
+
+/* Register for system reset */
+#define AN8855_RST_CTRL			0x100050c0
+#define   AN8855_SYS_CTRL_SYS_RST	BIT(31)
+
+#define AN8855_INT_MASK			0x100050f0
+#define   AN8855_INT_SYS		BIT(15)
+
+#define AN8855_RG_CLK_CPU_ICG		0x10005034
+#define   AN8855_MCU_ENABLE		BIT(3)
+
+#define AN8855_RG_TIMER_CTL		0x1000a100
+#define   AN8855_WDOG_ENABLE		BIT(25)
+
+#define AN8855_RG_GDMP_RAM		0x10010000
+
+/* Registers to mac forward control for unknown frames */
+#define AN8855_MFC			0x10200010
+#define   AN8855_CPU_EN			BIT(15)
+#define   AN8855_CPU_PORT_IDX		GENMASK(12, 8)
+
+#define AN8855_PAC			0x10200024
+#define   AN8855_TAG_PAE_MANG_FR	BIT(30)
+#define   AN8855_TAG_PAE_BPDU_FR	BIT(28)
+#define   AN8855_TAG_PAE_EG_TAG		GENMASK(27, 25)
+#define   AN8855_TAG_PAE_LKY_VLAN	BIT(24)
+#define   AN8855_TAG_PAE_PRI_HIGH	BIT(23)
+#define   AN8855_TAG_PAE_MIR		GENMASK(20, 19)
+#define   AN8855_TAG_PAE_PORT_FW	GENMASK(18, 16)
+#define   AN8855_PAE_MANG_FR		BIT(14)
+#define   AN8855_PAE_BPDU_FR		BIT(12)
+#define   AN8855_PAE_EG_TAG		GENMASK(11, 9)
+#define   AN8855_PAE_LKY_VLAN		BIT(8)
+#define   AN8855_PAE_PRI_HIGH		BIT(7)
+#define   AN8855_PAE_MIR		GENMASK(4, 3)
+#define   AN8855_PAE_PORT_FW		GENMASK(2, 0)
+
+#define AN8855_RGAC1			0x10200028
+#define   AN8855_R02_MANG_FR		BIT(30)
+#define   AN8855_R02_BPDU_FR		BIT(28)
+#define   AN8855_R02_EG_TAG		GENMASK(27, 25)
+#define   AN8855_R02_LKY_VLAN		BIT(24)
+#define   AN8855_R02_PRI_HIGH		BIT(23)
+#define   AN8855_R02_MIR		GENMASK(20, 19)
+#define   AN8855_R02_PORT_FW		GENMASK(18, 16)
+#define   AN8855_R01_MANG_FR		BIT(14)
+#define   AN8855_R01_BPDU_FR		BIT(12)
+#define   AN8855_R01_EG_TAG		GENMASK(11, 9)
+#define   AN8855_R01_LKY_VLAN		BIT(8)
+#define   AN8855_R01_PRI_HIGH		BIT(7)
+#define   AN8855_R01_MIR		GENMASK(4, 3)
+#define   AN8855_R01_PORT_FW		GENMASK(2, 0)
+
+#define AN8855_RGAC2			0x1020002c
+#define   AN8855_R0E_MANG_FR		BIT(30)
+#define   AN8855_R0E_BPDU_FR		BIT(28)
+#define   AN8855_R0E_EG_TAG		GENMASK(27, 25)
+#define   AN8855_R0E_LKY_VLAN		BIT(24)
+#define   AN8855_R0E_PRI_HIGH		BIT(23)
+#define   AN8855_R0E_MIR		GENMASK(20, 19)
+#define   AN8855_R0E_PORT_FW		GENMASK(18, 16)
+#define   AN8855_R03_MANG_FR		BIT(14)
+#define   AN8855_R03_BPDU_FR		BIT(12)
+#define   AN8855_R03_EG_TAG		GENMASK(11, 9)
+#define   AN8855_R03_LKY_VLAN		BIT(8)
+#define   AN8855_R03_PRI_HIGH		BIT(7)
+#define   AN8855_R03_MIR		GENMASK(4, 3)
+#define   AN8855_R03_PORT_FW		GENMASK(2, 0)
+
+#define AN8855_AAC			0x102000a0
+#define   AN8855_MAC_AUTO_FLUSH		BIT(28)
+/* Control Address Table Age time.
+ * (AN8855_AGE_CNT + 1) * ( AN8855_AGE_UNIT + 1 ) * AN8855_L2_AGING_MS_CONSTANT
+ */
+#define   AN8855_AGE_CNT		GENMASK(20, 12)
+/* Value in seconds. Value is always incremented of 1 */
+#define   AN8855_AGE_UNIT		GENMASK(10, 0)
+
+/* Registers for ARL Unknown Unicast Forward control */
+#define AN8855_UNUF			0x102000b4
+
+/* Registers for ARL Unknown Multicast Forward control */
+#define AN8855_UNMF			0x102000b8
+
+/* Registers for ARL Broadcast forward control */
+#define AN8855_BCF			0x102000bc
+
+/* Registers for port address age disable */
+#define AN8855_AGDIS			0x102000c0
+
+/* Registers for mirror port control */
+#define AN8855_MIR			0x102000cc
+#define   AN8855_MIRROR_EN		BIT(7)
+#define   AN8855_MIRROR_PORT		GENMASK(4, 0)
+
+/* Registers for BPDU and PAE frame control*/
+#define AN8855_BPC			0x102000d0
+#define   AN8855_BPDU_MANG_FR		BIT(14)
+#define   AN8855_BPDU_BPDU_FR		BIT(12)
+#define   AN8855_BPDU_EG_TAG		GENMASK(11, 9)
+#define   AN8855_BPDU_LKY_VLAN		BIT(8)
+#define   AN8855_BPDU_PRI_HIGH		BIT(7)
+#define   AN8855_BPDU_MIR		GENMASK(4, 3)
+#define   AN8855_BPDU_PORT_FW		GENMASK(2, 0)
+
+/* Registers for IP Unknown Multicast Forward control */
+#define AN8855_UNIPMF			0x102000dc
+
+enum an8855_bpdu_port_fw {
+	AN8855_BPDU_FOLLOW_MFC = 0,
+	AN8855_BPDU_CPU_EXCLUDE = 4,
+	AN8855_BPDU_CPU_INCLUDE = 5,
+	AN8855_BPDU_CPU_ONLY = 6,
+	AN8855_BPDU_DROP = 7,
+};
+
+/* Register for address table control */
+#define AN8855_ATC			0x10200300
+#define   AN8855_ATC_BUSY		BIT(31)
+#define   AN8855_ATC_HASH		GENMASK(24, 16)
+#define   AN8855_ATC_HIT		GENMASK(15, 12)
+#define   AN8855_ATC_MAT_MASK		GENMASK(11, 7)
+#define   AN8855_ATC_MAT(x)		FIELD_PREP(AN8855_ATC_MAT_MASK, x)
+#define   AN8855_ATC_SAT		GENMASK(5, 4)
+#define   AN8855_ATC_CMD		GENMASK(2, 0)
+
+enum an8855_fdb_mat_cmds {
+	AND8855_FDB_MAT_ALL = 0,
+	AND8855_FDB_MAT_MAC, /* All MAC address */
+	AND8855_FDB_MAT_DYNAMIC_MAC, /* All Dynamic MAC address */
+	AND8855_FDB_MAT_STATIC_MAC, /* All Static Mac Address */
+	AND8855_FDB_MAT_DIP, /* All DIP/GA address */
+	AND8855_FDB_MAT_DIP_IPV4, /* All DIP/GA IPv4 address */
+	AND8855_FDB_MAT_DIP_IPV6, /* All DIP/GA IPv6 address */
+	AND8855_FDB_MAT_DIP_SIP, /* All DIP_SIP address */
+	AND8855_FDB_MAT_DIP_SIP_IPV4, /* All DIP_SIP IPv4 address */
+	AND8855_FDB_MAT_DIP_SIP_IPV6, /* All DIP_SIP IPv6 address */
+	AND8855_FDB_MAT_MAC_CVID, /* All MAC address with CVID */
+	AND8855_FDB_MAT_MAC_FID, /* All MAC address with Filter ID */
+	AND8855_FDB_MAT_MAC_PORT, /* All MAC address with port */
+	AND8855_FDB_MAT_DIP_SIP_DIP_IPV4, /* All DIP_SIP address with DIP_IPV4 */
+	AND8855_FDB_MAT_DIP_SIP_SIP_IPV4, /* All DIP_SIP address with SIP_IPV4 */
+	AND8855_FDB_MAT_DIP_SIP_DIP_IPV6, /* All DIP_SIP address with DIP_IPV6 */
+	AND8855_FDB_MAT_DIP_SIP_SIP_IPV6, /* All DIP_SIP address with SIP_IPV6 */
+	/* All MAC address with MAC type (dynamic or static) with CVID */
+	AND8855_FDB_MAT_MAC_TYPE_CVID,
+	/* All MAC address with MAC type (dynamic or static) with Filter ID */
+	AND8855_FDB_MAT_MAC_TYPE_FID,
+	/* All MAC address with MAC type (dynamic or static) with port */
+	AND8855_FDB_MAT_MAC_TYPE_PORT,
+};
+
+enum an8855_fdb_cmds {
+	AN8855_FDB_READ = 0,
+	AN8855_FDB_WRITE = 1,
+	AN8855_FDB_FLUSH = 2,
+	AN8855_FDB_START = 4,
+	AN8855_FDB_NEXT = 5,
+};
+
+/* Registers for address table access */
+#define AN8855_ATA1			0x10200304
+#define   AN8855_ATA1_MAC0		GENMASK(31, 24)
+#define   AN8855_ATA1_MAC1		GENMASK(23, 16)
+#define   AN8855_ATA1_MAC2		GENMASK(15, 8)
+#define   AN8855_ATA1_MAC3		GENMASK(7, 0)
+#define AN8855_ATA2			0x10200308
+#define   AN8855_ATA2_MAC4		GENMASK(31, 24)
+#define   AN8855_ATA2_MAC5		GENMASK(23, 16)
+#define   AN8855_ATA2_UNAUTH		BIT(10)
+#define   AN8855_ATA2_TYPE		BIT(9) /* 1: dynamic, 0: static */
+#define   AN8855_ATA2_AGE		GENMASK(8, 0)
+
+/* Register for address table write data */
+#define AN8855_ATWD			0x10200324
+#define   AN8855_ATWD_FID		GENMASK(31, 28)
+#define   AN8855_ATWD_VID		GENMASK(27, 16)
+#define   AN8855_ATWD_IVL		BIT(15)
+#define   AN8855_ATWD_EG_TAG		GENMASK(14, 12)
+#define   AN8855_ATWD_SA_MIR		GENMASK(9, 8)
+#define   AN8855_ATWD_SA_FWD		GENMASK(7, 5)
+#define   AN8855_ATWD_UPRI		GENMASK(4, 2)
+#define   AN8855_ATWD_LEAKY		BIT(1)
+#define   AN8855_ATWD_VLD		BIT(0) /* vid LOAD */
+#define AN8855_ATWD2			0x10200328
+#define   AN8855_ATWD2_PORT		GENMASK(7, 0)
+
+/* Registers for table search read address */
+#define AN8855_ATRDS			0x10200330
+#define   AN8855_ATRD_SEL		GENMASK(1, 0)
+#define AN8855_ATRD0			0x10200334
+#define   AN8855_ATRD0_FID		GENMASK(28, 25)
+#define   AN8855_ATRD0_VID		GENMASK(21, 10)
+#define   AN8855_ATRD0_IVL		BIT(9)
+#define   AN8855_ATRD0_TYPE		GENMASK(4, 3)
+#define   AN8855_ATRD0_ARP		GENMASK(2, 1)
+#define   AN8855_ATRD0_LIVE		BIT(0)
+#define AN8855_ATRD1			0x10200338
+#define   AN8855_ATRD1_MAC4		GENMASK(31, 24)
+#define   AN8855_ATRD1_MAC5		GENMASK(23, 16)
+#define   AN8855_ATRD1_AGING		GENMASK(11, 3)
+#define AN8855_ATRD2			0x1020033c
+#define   AN8855_ATRD2_MAC0		GENMASK(31, 24)
+#define   AN8855_ATRD2_MAC1		GENMASK(23, 16)
+#define   AN8855_ATRD2_MAC2		GENMASK(15, 8)
+#define   AN8855_ATRD2_MAC3		GENMASK(7, 0)
+#define AN8855_ATRD3			0x10200340
+#define   AN8855_ATRD3_PORTMASK		GENMASK(7, 0)
+
+enum an8855_fdb_type {
+	AN8855_MAC_TB_TY_MAC = 0,
+	AN8855_MAC_TB_TY_DIP = 1,
+	AN8855_MAC_TB_TY_DIP_SIP = 2,
+};
+
+/* Register for vlan table control */
+#define AN8855_VTCR			0x10200600
+#define   AN8855_VTCR_BUSY		BIT(31)
+#define   AN8855_VTCR_FUNC		GENMASK(15, 12)
+#define   AN8855_VTCR_VID		GENMASK(11, 0)
+
+enum an8855_vlan_cmd {
+	/* Read/Write the specified VID entry from VAWD register based
+	 * on VID.
+	 */
+	AN8855_VTCR_RD_VID = 0,
+	AN8855_VTCR_WR_VID = 1,
+};
+
+/* Register for setup vlan write data */
+#define AN8855_VAWD0			0x10200604
+/* VLAN Member Control */
+#define   AN8855_VA0_PORT		GENMASK(31, 26)
+/* Egress Tag Control */
+#define   AN8855_VA0_ETAG		GENMASK(23, 12)
+#define   AN8855_VA0_ETAG_PORT		GENMASK(13, 12)
+#define   AN8855_VA0_ETAG_PORT_SHIFT(port) ((port) * 2)
+#define   AN8855_VA0_ETAG_PORT_MASK(port) (AN8855_VA0_ETAG_PORT << \
+						AN8855_VA0_ETAG_PORT_SHIFT(port))
+#define   AN8855_VA0_ETAG_PORT_VAL(port, val) (FIELD_PREP(AN8855_VA0_ETAG_PORT, (val)) << \
+						AN8855_VA0_ETAG_PORT_SHIFT(port))
+#define   AN8855_VA0_EG_CON		BIT(11)
+#define   AN8855_VA0_VTAG_EN		BIT(10) /* Per VLAN Egress Tag Control */
+#define   AN8855_VA0_IVL_MAC		BIT(5) /* Independent VLAN Learning */
+#define	  AN8855_VA0_FID		GENMASK(4, 1)
+#define   AN8855_VA0_VLAN_VALID		BIT(0) /* VLAN Entry Valid */
+#define AN8855_VAWD1			0x10200608
+#define   AN8855_VA1_PORT_STAG		BIT(1)
+
+enum an8855_fid {
+	AN8855_FID_STANDALONE = 0,
+	AN8855_FID_BRIDGED = 1,
+};
+
+/* Same register field of VAWD0 */
+#define AN8855_VARD0			0x10200618
+
+enum an8855_vlan_egress_attr {
+	AN8855_VLAN_EGRESS_UNTAG = 0,
+	AN8855_VLAN_EGRESS_TAG = 2,
+	AN8855_VLAN_EGRESS_STACK = 3,
+};
+
+/* Register for port STP state control */
+#define AN8855_SSP_P(x)			(0x10208000 + ((x) * 0x200))
+/* Up to 16 FID supported, each with the same mask */
+#define	  AN8855_FID_PST		GENMASK(1, 0)
+#define   AN8855_FID_PST_SHIFT(fid)	(2 * (fid))
+#define   AN8855_FID_PST_MASK(fid)	(AN8855_FID_PST << \
+						AN8855_FID_PST_SHIFT(fid))
+#define   AN8855_FID_PST_VAL(fid, val)	(FIELD_PREP(AN8855_FID_PST, (val)) << \
+						AN8855_FID_PST_SHIFT(fid))
+
+enum an8855_stp_state {
+	AN8855_STP_DISABLED = 0,
+	AN8855_STP_BLOCKING = 1,
+	AN8855_STP_LISTENING = AN8855_STP_BLOCKING,
+	AN8855_STP_LEARNING = 2,
+	AN8855_STP_FORWARDING = 3
+};
+
+/* Register for port control */
+#define AN8855_PCR_P(x)			(0x10208004 + ((x) * 0x200))
+#define   AN8855_EG_TAG			GENMASK(29, 28)
+#define   AN8855_PORT_PRI		GENMASK(26, 24)
+#define   AN8855_PORT_TX_MIR		BIT(20)
+#define   AN8855_PORT_RX_MIR		BIT(16)
+#define   AN8855_PORT_VLAN		GENMASK(1, 0)
+
+enum an8855_port_mode {
+	/* Port Matrix Mode: Frames are forwarded by the PCR_MATRIX members. */
+	AN8855_PORT_MATRIX_MODE = 0,
+
+	/* Fallback Mode: Forward received frames with ingress ports that do
+	 * not belong to the VLAN member. Frames whose VID is not listed on
+	 * the VLAN table are forwarded by the PCR_MATRIX members.
+	 */
+	AN8855_PORT_FALLBACK_MODE = 1,
+
+	/* Check Mode: Forward received frames whose ingress do not
+	 * belong to the VLAN member. Discard frames if VID ismiddes on the
+	 * VLAN table.
+	 */
+	AN8855_PORT_CHECK_MODE = 2,
+
+	/* Security Mode: Discard any frame due to ingress membership
+	 * violation or VID missed on the VLAN table.
+	 */
+	AN8855_PORT_SECURITY_MODE = 3,
+};
+
+/* Register for port security control */
+#define AN8855_PSC_P(x)			(0x1020800c + ((x) * 0x200))
+#define   AN8855_SA_DIS			BIT(4)
+
+/* Register for port vlan control */
+#define AN8855_PVC_P(x)			(0x10208010 + ((x) * 0x200))
+#define   AN8855_PORT_SPEC_REPLACE_MODE	BIT(11)
+#define   AN8855_PVC_EG_TAG		GENMASK(10, 8)
+#define   AN8855_VLAN_ATTR		GENMASK(7, 6)
+#define   AN8855_PORT_SPEC_TAG		BIT(5)
+#define   AN8855_ACC_FRM		GENMASK(1, 0)
+
+enum an8855_vlan_port_eg_tag {
+	AN8855_VLAN_EG_DISABLED = 0,
+	AN8855_VLAN_EG_CONSISTENT = 1,
+	AN8855_VLAN_EG_UNTAGGED = 4,
+	AN8855_VLAN_EG_SWAP = 5,
+	AN8855_VLAN_EG_TAGGED = 6,
+	AN8855_VLAN_EG_STACK = 7,
+};
+
+enum an8855_vlan_port_attr {
+	AN8855_VLAN_USER = 0,
+	AN8855_VLAN_STACK = 1,
+	AN8855_VLAN_TRANSPARENT = 3,
+};
+
+enum an8855_vlan_port_acc_frm {
+	AN8855_VLAN_ACC_ALL = 0,
+	AN8855_VLAN_ACC_TAGGED = 1,
+	AN8855_VLAN_ACC_UNTAGGED = 2,
+};
+
+#define AN8855_PPBV1_P(x)		(0x10208014 + ((x) * 0x200))
+#define   AN8855_PPBV_G0_PORT_VID	GENMASK(11, 0)
+
+#define AN8855_PORTMATRIX_P(x)		(0x10208044 + ((x) * 0x200))
+#define   AN8855_PORTMATRIX		GENMASK(5, 0)
+/* Port matrix without the CPU port that should never be removed */
+#define   AN8855_USER_PORTMATRIX	GENMASK(4, 0)
+
+/* Register for port PVID */
+#define AN8855_PVID_P(x)		(0x10208048 + ((x) * 0x200))
+#define   AN8855_G0_PORT_VID		GENMASK(11, 0)
+
+/* Register for port MAC control register */
+#define AN8855_PMCR_P(x)		(0x10210000 + ((x) * 0x200))
+#define   AN8855_PMCR_FORCE_MODE	BIT(31)
+#define   AN8855_PMCR_FORCE_SPEED	GENMASK(30, 28)
+#define   AN8855_PMCR_FORCE_SPEED_5000	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x4)
+#define   AN8855_PMCR_FORCE_SPEED_2500	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x3)
+#define   AN8855_PMCR_FORCE_SPEED_1000	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x2)
+#define   AN8855_PMCR_FORCE_SPEED_100	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1)
+#define   AN8855_PMCR_FORCE_SPEED_10	FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1)
+#define   AN8855_PMCR_FORCE_FDX		BIT(25)
+#define   AN8855_PMCR_FORCE_LNK		BIT(24)
+#define   AN8855_PMCR_IFG_XMIT		GENMASK(21, 20)
+#define   AN8855_PMCR_EXT_PHY		BIT(19)
+#define   AN8855_PMCR_MAC_MODE		BIT(18)
+#define   AN8855_PMCR_TX_EN		BIT(16)
+#define   AN8855_PMCR_RX_EN		BIT(15)
+#define   AN8855_PMCR_BACKOFF_EN	BIT(12)
+#define   AN8855_PMCR_BACKPR_EN		BIT(11)
+#define   AN8855_PMCR_FORCE_EEE5G	BIT(9)
+#define   AN8855_PMCR_FORCE_EEE2P5G	BIT(8)
+#define   AN8855_PMCR_FORCE_EEE1G	BIT(7)
+#define   AN8855_PMCR_FORCE_EEE100	BIT(6)
+#define   AN8855_PMCR_TX_FC_EN		BIT(5)
+#define   AN8855_PMCR_RX_FC_EN		BIT(4)
+
+#define AN8855_PMSR_P(x)		(0x10210010 + (x) * 0x200)
+#define   AN8855_PMSR_SPEED		GENMASK(30, 28)
+#define   AN8855_PMSR_SPEED_5000	FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x4)
+#define   AN8855_PMSR_SPEED_2500	FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x3)
+#define   AN8855_PMSR_SPEED_1000	FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x2)
+#define   AN8855_PMSR_SPEED_100		FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x1)
+#define   AN8855_PMSR_SPEED_10		FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x0)
+#define   AN8855_PMSR_DPX		BIT(25)
+#define   AN8855_PMSR_LNK		BIT(24)
+#define   AN8855_PMSR_EEE1G		BIT(7)
+#define   AN8855_PMSR_EEE100M		BIT(6)
+#define   AN8855_PMSR_RX_FC		BIT(5)
+#define   AN8855_PMSR_TX_FC		BIT(4)
+
+#define AN8855_PMEEECR_P(x)		(0x10210004 + (x) * 0x200)
+#define   AN8855_LPI_MODE_EN		BIT(31)
+#define   AN8855_WAKEUP_TIME_2500	GENMASK(23, 16)
+#define   AN8855_WAKEUP_TIME_1000	GENMASK(15, 8)
+#define   AN8855_WAKEUP_TIME_100	GENMASK(7, 0)
+#define AN8855_PMEEECR2_P(x)		(0x10210008 + (x) * 0x200)
+#define   AN8855_WAKEUP_TIME_5000	GENMASK(7, 0)
+
+#define AN8855_GMACCR			0x10213e00
+#define   AN8855_MAX_RX_JUMBO		GENMASK(7, 4)
+/* 2K for 0x0, 0x1, 0x2 */
+#define   AN8855_MAX_RX_JUMBO_2K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x0)
+#define   AN8855_MAX_RX_JUMBO_3K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x3)
+#define   AN8855_MAX_RX_JUMBO_4K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x4)
+#define   AN8855_MAX_RX_JUMBO_5K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x5)
+#define   AN8855_MAX_RX_JUMBO_6K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x6)
+#define   AN8855_MAX_RX_JUMBO_7K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x7)
+#define   AN8855_MAX_RX_JUMBO_8K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x8)
+#define   AN8855_MAX_RX_JUMBO_9K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x9)
+#define   AN8855_MAX_RX_JUMBO_12K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xa)
+#define   AN8855_MAX_RX_JUMBO_15K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xb)
+#define   AN8855_MAX_RX_JUMBO_16K	FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xc)
+#define   AN8855_MAX_RX_PKT_LEN		GENMASK(1, 0)
+#define   AN8855_MAX_RX_PKT_1518_1522	FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x0)
+#define   AN8855_MAX_RX_PKT_1536	FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x1)
+#define   AN8855_MAX_RX_PKT_1552	FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x2)
+#define   AN8855_MAX_RX_PKT_JUMBO	FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x3)
+
+#define AN8855_CKGCR			0x10213e1c
+#define   AN8855_LPI_TXIDLE_THD_MASK	GENMASK(31, 14)
+#define   AN8855_CKG_LNKDN_PORT_STOP	BIT(1)
+#define   AN8855_CKG_LNKDN_GLB_STOP	BIT(0)
+
+/* Register for MIB */
+#define AN8855_PORT_MIB_COUNTER(x)	(0x10214000 + (x) * 0x200)
+/* Each define is an offset of AN8855_PORT_MIB_COUNTER */
+#define   AN8855_PORT_MIB_TX_DROP	0x00
+#define   AN8855_PORT_MIB_TX_CRC_ERR	0x04
+#define   AN8855_PORT_MIB_TX_UNICAST	0x08
+#define   AN8855_PORT_MIB_TX_MULTICAST	0x0c
+#define   AN8855_PORT_MIB_TX_BROADCAST	0x10
+#define   AN8855_PORT_MIB_TX_COLLISION	0x14
+#define   AN8855_PORT_MIB_TX_SINGLE_COLLISION 0x18
+#define   AN8855_PORT_MIB_TX_MULTIPLE_COLLISION 0x1c
+#define   AN8855_PORT_MIB_TX_DEFERRED	0x20
+#define   AN8855_PORT_MIB_TX_LATE_COLLISION 0x24
+#define   AN8855_PORT_MIB_TX_EXCESSIVE_COLLISION 0x28
+#define   AN8855_PORT_MIB_TX_PAUSE	0x2c
+#define   AN8855_PORT_MIB_TX_PKT_SZ_64	0x30
+#define   AN8855_PORT_MIB_TX_PKT_SZ_65_TO_127 0x34
+#define   AN8855_PORT_MIB_TX_PKT_SZ_128_TO_255 0x38
+#define   AN8855_PORT_MIB_TX_PKT_SZ_256_TO_511 0x3
+#define   AN8855_PORT_MIB_TX_PKT_SZ_512_TO_1023 0x40
+#define   AN8855_PORT_MIB_TX_PKT_SZ_1024_TO_1518 0x44
+#define   AN8855_PORT_MIB_TX_PKT_SZ_1519_TO_MAX 0x48
+#define   AN8855_PORT_MIB_TX_BYTES	0x4c /* 64 bytes */
+#define   AN8855_PORT_MIB_TX_OVERSIZE_DROP 0x54
+#define   AN8855_PORT_MIB_TX_BAD_PKT_BYTES 0x58 /* 64 bytes */
+#define   AN8855_PORT_MIB_RX_DROP	0x80
+#define   AN8855_PORT_MIB_RX_FILTERING	0x84
+#define   AN8855_PORT_MIB_RX_UNICAST	0x88
+#define   AN8855_PORT_MIB_RX_MULTICAST	0x8c
+#define   AN8855_PORT_MIB_RX_BROADCAST	0x90
+#define   AN8855_PORT_MIB_RX_ALIGN_ERR	0x94
+#define   AN8855_PORT_MIB_RX_CRC_ERR	0x98
+#define   AN8855_PORT_MIB_RX_UNDER_SIZE_ERR 0x9c
+#define   AN8855_PORT_MIB_RX_FRAG_ERR	0xa0
+#define   AN8855_PORT_MIB_RX_OVER_SZ_ERR 0xa4
+#define   AN8855_PORT_MIB_RX_JABBER_ERR	0xa8
+#define   AN8855_PORT_MIB_RX_PAUSE	0xac
+#define   AN8855_PORT_MIB_RX_PKT_SZ_64	0xb0
+#define   AN8855_PORT_MIB_RX_PKT_SZ_65_TO_127 0xb4
+#define   AN8855_PORT_MIB_RX_PKT_SZ_128_TO_255 0xb8
+#define   AN8855_PORT_MIB_RX_PKT_SZ_256_TO_511 0xbc
+#define   AN8855_PORT_MIB_RX_PKT_SZ_512_TO_1023 0xc0
+#define   AN8855_PORT_MIB_RX_PKT_SZ_1024_TO_1518 0xc4
+#define   AN8855_PORT_MIB_RX_PKT_SZ_1519_TO_MAX 0xc8
+#define   AN8855_PORT_MIB_RX_BYTES	0xcc /* 64 bytes */
+#define   AN8855_PORT_MIB_RX_CTRL_DROP	0xd4
+#define   AN8855_PORT_MIB_RX_INGRESS_DROP 0xd8
+#define   AN8855_PORT_MIB_RX_ARL_DROP	0xdc
+#define   AN8855_PORT_MIB_FLOW_CONTROL_DROP 0xe0
+#define   AN8855_PORT_MIB_WRED_DROP	0xe4
+#define   AN8855_PORT_MIB_MIRROR_DROP	0xe8
+#define   AN8855_PORT_MIB_RX_BAD_PKT_BYTES 0xec /* 64 bytes */
+#define   AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP 0xf4
+#define   AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP 0xf8
+#define   AN8855_PORT_MIB_PORT_CONTROL_DROP 0xfc
+#define AN8855_MIB_CCR			0x10213e30
+#define   AN8855_CCR_MIB_ENABLE		BIT(31)
+#define   AN8855_CCR_RX_OCT_CNT_GOOD	BIT(7)
+#define   AN8855_CCR_RX_OCT_CNT_BAD	BIT(6)
+#define   AN8855_CCR_TX_OCT_CNT_GOOD	BIT(5)
+#define   AN8855_CCR_TX_OCT_CNT_BAD	BIT(4)
+#define   AN8855_CCR_RX_OCT_CNT_GOOD_2	BIT(3)
+#define   AN8855_CCR_RX_OCT_CNT_BAD_2	BIT(2)
+#define   AN8855_CCR_TX_OCT_CNT_GOOD_2	BIT(1)
+#define   AN8855_CCR_TX_OCT_CNT_BAD_2	BIT(0)
+#define   AN8855_CCR_MIB_ACTIVATE	(AN8855_CCR_MIB_ENABLE | \
+					 AN8855_CCR_RX_OCT_CNT_GOOD | \
+					 AN8855_CCR_RX_OCT_CNT_BAD | \
+					 AN8855_CCR_TX_OCT_CNT_GOOD | \
+					 AN8855_CCR_TX_OCT_CNT_BAD | \
+					 AN8855_CCR_RX_OCT_CNT_BAD_2 | \
+					 AN8855_CCR_TX_OCT_CNT_BAD_2)
+#define AN8855_MIB_CLR			0x10213e34
+#define   AN8855_MIB_PORT6_CLR		BIT(6)
+#define   AN8855_MIB_PORT5_CLR		BIT(5)
+#define   AN8855_MIB_PORT4_CLR		BIT(4)
+#define   AN8855_MIB_PORT3_CLR		BIT(3)
+#define   AN8855_MIB_PORT2_CLR		BIT(2)
+#define   AN8855_MIB_PORT1_CLR		BIT(1)
+#define   AN8855_MIB_PORT0_CLR		BIT(0)
+
+/* HSGMII/SGMII Configuration register */
+/*	AN8855_HSGMII_AN_CSR_BASE	0x10220000 */
+#define AN8855_SGMII_REG_AN0		0x10220000
+/*        AN8855_SGMII_AN_ENABLE	BMCR_ANENABLE */
+/*        AN8855_SGMII_AN_RESTART	BMCR_ANRESTART */
+#define AN8855_SGMII_REG_AN_13		0x10220034
+#define   AN8855_SGMII_REMOTE_FAULT_DIS	BIT(8)
+#define   AN8855_SGMII_IF_MODE		GENMASK(5, 0)
+#define AN8855_SGMII_REG_AN_FORCE_CL37	0x10220060
+#define   AN8855_RG_FORCE_AN_DONE	BIT(0)
+
+/*	AN8855_HSGMII_CSR_PCS_BASE	0x10220000 */
+#define AN8855_RG_HSGMII_PCS_CTROL_1	0x10220a00
+#define   AN8855_RG_TBI_10B_MODE	BIT(30)
+#define AN8855_RG_AN_SGMII_MODE_FORCE	0x10220a24
+#define   AN8855_RG_FORCE_CUR_SGMII_MODE GENMASK(5, 4)
+#define   AN8855_RG_FORCE_CUR_SGMII_SEL	BIT(0)
+
+/*	AN8855_MULTI_SGMII_CSR_BASE	0x10224000 */
+#define AN8855_SGMII_STS_CTRL_0		0x10224018
+#define   AN8855_RG_LINK_MODE_P0	GENMASK(5, 4)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_2500 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x3)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_1000 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x2)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_100 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x1)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_10 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x0)
+#define   AN8855_RG_FORCE_SPD_MODE_P0	BIT(2)
+#define AN8855_MSG_RX_CTRL_0		0x10224100
+#define AN8855_MSG_RX_LIK_STS_0		0x10224514
+#define   AN8855_RG_DPX_STS_P3		BIT(24)
+#define   AN8855_RG_DPX_STS_P2		BIT(16)
+#define   AN8855_RG_EEE1G_STS_P1	BIT(12)
+#define   AN8855_RG_DPX_STS_P1		BIT(8)
+#define   AN8855_RG_TXFC_STS_P0		BIT(2)
+#define   AN8855_RG_RXFC_STS_P0		BIT(1)
+#define   AN8855_RG_DPX_STS_P0		BIT(0)
+#define AN8855_MSG_RX_LIK_STS_2		0x1022451c
+#define   AN8855_RG_RXFC_AN_BYPASS_P3	BIT(11)
+#define   AN8855_RG_RXFC_AN_BYPASS_P2	BIT(10)
+#define   AN8855_RG_RXFC_AN_BYPASS_P1	BIT(9)
+#define   AN8855_RG_TXFC_AN_BYPASS_P3	BIT(7)
+#define   AN8855_RG_TXFC_AN_BYPASS_P2	BIT(6)
+#define   AN8855_RG_TXFC_AN_BYPASS_P1	BIT(5)
+#define   AN8855_RG_DPX_AN_BYPASS_P3	BIT(3)
+#define   AN8855_RG_DPX_AN_BYPASS_P2	BIT(2)
+#define   AN8855_RG_DPX_AN_BYPASS_P1	BIT(1)
+#define   AN8855_RG_DPX_AN_BYPASS_P0	BIT(0)
+#define AN8855_PHY_RX_FORCE_CTRL_0	0x10224520
+#define   AN8855_RG_FORCE_TXC_SEL	BIT(4)
+
+/*	AN8855_XFI_CSR_PCS_BASE		0x10225000 */
+#define AN8855_RG_USXGMII_AN_CONTROL_0	0x10225bf8
+
+/*	AN8855_MULTI_PHY_RA_CSR_BASE	0x10226000 */
+#define AN8855_RG_RATE_ADAPT_CTRL_0	0x10226000
+#define   AN8855_RG_RATE_ADAPT_RX_BYPASS BIT(27)
+#define   AN8855_RG_RATE_ADAPT_TX_BYPASS BIT(26)
+#define   AN8855_RG_RATE_ADAPT_RX_EN	BIT(4)
+#define   AN8855_RG_RATE_ADAPT_TX_EN	BIT(0)
+#define AN8855_RATE_ADP_P0_CTRL_0	0x10226100
+#define   AN8855_RG_P0_DIS_MII_MODE	BIT(31)
+#define   AN8855_RG_P0_MII_MODE		BIT(28)
+#define   AN8855_RG_P0_MII_RA_RX_EN	BIT(3)
+#define   AN8855_RG_P0_MII_RA_TX_EN	BIT(2)
+#define   AN8855_RG_P0_MII_RA_RX_MODE	BIT(1)
+#define   AN8855_RG_P0_MII_RA_TX_MODE	BIT(0)
+#define AN8855_MII_RA_AN_ENABLE		0x10226300
+#define   AN8855_RG_P0_RA_AN_EN		BIT(0)
+
+/*	AN8855_QP_DIG_CSR_BASE		0x1022a000 */
+#define AN8855_QP_CK_RST_CTRL_4		0x1022a310
+#define AN8855_QP_DIG_MODE_CTRL_0	0x1022a324
+#define   AN8855_RG_SGMII_MODE		GENMASK(5, 4)
+#define   AN8855_RG_SGMII_AN_EN		BIT(0)
+#define AN8855_QP_DIG_MODE_CTRL_1	0x1022a330
+#define   AN8855_RG_TPHY_SPEED		GENMASK(3, 2)
+
+/*	AN8855_SERDES_WRAPPER_BASE	0x1022c000 */
+#define AN8855_USGMII_CTRL_0		0x1022c000
+
+/*	AN8855_QP_PMA_TOP_BASE		0x1022e000 */
+#define AN8855_PON_RXFEDIG_CTRL_0	0x1022e100
+#define   AN8855_RG_QP_EQ_RX500M_CK_SEL	BIT(12)
+#define AN8855_PON_RXFEDIG_CTRL_9	0x1022e124
+#define   AN8855_RG_QP_EQ_LEQOSC_DLYCNT	GENMASK(2, 0)
+
+#define AN8855_SS_LCPLL_PWCTL_SETTING_2	0x1022e208
+#define   AN8855_RG_NCPO_ANA_MSB	GENMASK(17, 16)
+#define AN8855_SS_LCPLL_TDC_FLT_2	0x1022e230
+#define   AN8855_RG_LCPLL_NCPO_VALUE	GENMASK(30, 0)
+#define AN8855_SS_LCPLL_TDC_FLT_5	0x1022e23c
+#define   AN8855_RG_LCPLL_NCPO_CHG	BIT(24)
+#define AN8855_SS_LCPLL_TDC_PCW_1	0x1022e248
+#define  AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON GENMASK(30, 0)
+#define AN8855_INTF_CTRL_8		0x1022e320
+#define AN8855_INTF_CTRL_9		0x1022e324
+#define AN8855_INTF_CTRL_10		0x1022e328
+#define   AN8855_RG_DA_QP_TX_FIR_C2_SEL	BIT(29)
+#define   AN8855_RG_DA_QP_TX_FIR_C2_FORCE GENMASK(28, 24)
+#define   AN8855_RG_DA_QP_TX_FIR_C1_SEL	BIT(21)
+#define   AN8855_RG_DA_QP_TX_FIR_C1_FORCE GENMASK(20, 16)
+#define AN8855_INTF_CTRL_11		0x1022e32c
+#define   AN8855_RG_DA_QP_TX_FIR_C0B_SEL BIT(6)
+#define   AN8855_RG_DA_QP_TX_FIR_C0B_FORCE GENMASK(5, 0)
+#define AN8855_PLL_CTRL_0		0x1022e400
+#define   AN8855_RG_PHYA_AUTO_INIT	BIT(0)
+#define AN8855_PLL_CTRL_2		0x1022e408
+#define   AN8855_RG_DA_QP_PLL_SDM_IFM_INTF BIT(30)
+#define   AN8855_RG_DA_QP_PLL_RICO_SEL_INTF BIT(29)
+#define   AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF BIT(28)
+#define   AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF BIT(27)
+#define   AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF BIT(26)
+#define   AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF GENMASK(25, 24)
+#define   AN8855_RG_DA_QP_PLL_PCK_SEL_INTF BIT(22)
+#define   AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF GENMASK(21, 20)
+#define   AN8855_RG_DA_QP_PLL_IR_INTF	GENMASK(19, 16)
+#define   AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF BIT(14)
+#define   AN8855_RG_DA_QP_PLL_FBKSEL_INTF GENMASK(13, 12)
+#define   AN8855_RG_DA_QP_PLL_BR_INTF	GENMASK(10, 8)
+#define   AN8855_RG_DA_QP_PLL_BPD_INTF	GENMASK(7, 6)
+#define   AN8855_RG_DA_QP_PLL_BPA_INTF	GENMASK(4, 2)
+#define   AN8855_RG_DA_QP_PLL_BC_INTF	GENMASK(1, 0)
+#define AN8855_PLL_CTRL_3		0x1022e40c
+#define   AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF GENMASK(31, 16)
+#define   AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF GENMASK(15, 0)
+#define AN8855_PLL_CTRL_4		0x1022e410
+#define   AN8855_RG_DA_QP_PLL_SDM_HREN_INTF GENMASK(4, 3)
+#define   AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF BIT(2)
+#define   AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF GENMASK(1, 0)
+#define AN8855_PLL_CK_CTRL_0		0x1022e414
+#define   AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF BIT(9)
+#define   AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF BIT(8)
+#define AN8855_RX_DLY_0			0x1022e614
+#define   AN8855_RG_QP_RX_SAOSC_EN_H_DLY GENMASK(13, 8)
+#define   AN8855_RG_QP_RX_PI_CAL_EN_H_DLY GENMASK(7, 0)
+#define AN8855_RX_CTRL_2		0x1022e630
+#define   AN8855_RG_QP_RX_EQ_EN_H_DLY	GENMASK(28, 16)
+#define AN8855_RX_CTRL_5		0x1022e63c
+#define   AN8855_RG_FREDET_CHK_CYCLE	GENMASK(29, 10)
+#define AN8855_RX_CTRL_6		0x1022e640
+#define   AN8855_RG_FREDET_GOLDEN_CYCLE	GENMASK(19, 0)
+#define AN8855_RX_CTRL_7		0x1022e644
+#define   AN8855_RG_FREDET_TOLERATE_CYCLE GENMASK(19, 0)
+#define AN8855_RX_CTRL_8		0x1022e648
+#define   AN8855_RG_DA_QP_SAOSC_DONE_TIME GENMASK(27, 16)
+#define   AN8855_RG_DA_QP_LEQOS_EN_TIME	GENMASK(14, 0)
+#define AN8855_RX_CTRL_26		0x1022e690
+#define   AN8855_RG_QP_EQ_RETRAIN_ONLY_EN BIT(26)
+#define   AN8855_RG_LINK_NE_EN		BIT(24)
+#define   AN8855_RG_LINK_ERRO_EN	BIT(23)
+#define AN8855_RX_CTRL_42		0x1022e6d0
+#define   AN8855_RG_QP_EQ_EN_DLY	GENMASK(12, 0)
+
+/*	AN8855_QP_ANA_CSR_BASE		0x1022f000 */
+#define AN8855_RG_QP_RX_DAC_EN		0x1022f000
+#define   AN8855_RG_QP_SIGDET_HF	GENMASK(17, 16)
+#define AN8855_RG_QP_RXAFE_RESERVE	0x1022f004
+#define   AN8855_RG_QP_CDR_PD_10B_EN	BIT(11)
+#define AN8855_RG_QP_CDR_LPF_BOT_LIM	0x1022f008
+#define   AN8855_RG_QP_CDR_LPF_KP_GAIN	GENMASK(26, 24)
+#define   AN8855_RG_QP_CDR_LPF_KI_GAIN	GENMASK(22, 20)
+#define AN8855_RG_QP_CDR_LPF_MJV_LIM	0x1022f00c
+#define   AN8855_RG_QP_CDR_LPF_RATIO	GENMASK(5, 4)
+#define AN8855_RG_QP_CDR_LPF_SETVALUE	0x1022f014
+#define   AN8855_RG_QP_CDR_PR_BUF_IN_SR	GENMASK(31, 29)
+#define   AN8855_RG_QP_CDR_PR_BETA_SEL	GENMASK(28, 25)
+#define AN8855_RG_QP_CDR_PR_CKREF_DIV1	0x1022f018
+#define   AN8855_RG_QP_CDR_PR_KBAND_DIV	GENMASK(26, 24)
+#define   AN8855_RG_QP_CDR_PR_DAC_BAND	GENMASK(12, 8)
+#define AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE 0x1022f01c
+#define   AN8855_RG_QP_CDR_PR_XFICK_EN	BIT(30)
+#define   AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE BIT(6)
+#define   AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK GENMASK(5, 0)
+#define AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF 0x1022f020
+#define   AN8855_RG_QP_CDR_PHYCK_SEL	GENMASK(17, 16)
+#define   AN8855_RG_QP_CDR_PHYCK_RSTB	BIT(13)
+#define   AN8855_RG_QP_CDR_PHYCK_DIV	GENMASK(12, 6)
+#define AN8855_RG_QP_TX_MODE		0x1022f028
+#define   AN8855_RG_QP_TX_RESERVE	GENMASK(31, 16)
+#define   AN8855_RG_QP_TX_MODE_16B_EN	BIT(0)
+#define AN8855_RG_QP_PLL_IPLL_DIG_PWR_SEL 0x1022f03c
+#define AN8855_RG_QP_PLL_SDM_ORD	0x1022f040
+#define   AN8855_RG_QP_PLL_SSC_PHASE_INI BIT(4)
+#define   AN8855_RG_QP_PLL_SSC_TRI_EN	BIT(3)
+
+/*	AN8855_ETHER_SYS_BASE		0x1028c800 */
+#define AN8855_RG_GPHY_AFE_PWD		0x1028c840
+#define AN8855_RG_GPHY_SMI_ADDR		0x1028c848
+
+#define MIB_DESC(_s, _o, _n)	\
+	{			\
+		.size = (_s),	\
+		.offset = (_o),	\
+		.name = (_n),	\
+	}
+
+struct an8855_mib_desc {
+	unsigned int size;
+	unsigned int offset;
+	const char *name;
+};
+
+struct an8855_fdb {
+	u16 vid;
+	u8 port_mask;
+	u16 aging;
+	u8 mac[6];
+	bool noarp;
+	u8 live;
+	u8 type;
+	u8 fid;
+	u8 ivl;
+};
+
+struct an8855_priv {
+	struct device *dev;
+	struct dsa_switch *ds;
+	struct regmap *regmap;
+	struct gpio_desc *reset_gpio;
+	/* Protect ATU or VLAN table access */
+	struct mutex reg_mutex;
+
+	struct phylink_pcs pcs;
+
+	u8 mirror_rx;
+	u8 mirror_tx;
+	u8 port_isolated_map;
+
+	bool phy_require_calib;
+};
+
+#endif /* __AN8855_H */
-- 
2.45.2



From ansuelsmth at gmail.com  Mon Dec  9 05:44:26 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:26 +0100
Subject: [net-next PATCH v11 9/9] net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241209134459.27110-10-ansuelsmth@gmail.com>

Add support for Airoha AN8855 Internal Switch Gigabit PHY.

This is a simple PHY driver to configure and calibrate the PHY for the
AN8855 Switch with the use of NVMEM cells.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 MAINTAINERS                  |   1 +
 drivers/net/phy/Kconfig      |   5 +
 drivers/net/phy/Makefile     |   1 +
 drivers/net/phy/air_an8855.c | 267 +++++++++++++++++++++++++++++++++++
 4 files changed, 274 insertions(+)
 create mode 100644 drivers/net/phy/air_an8855.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c42431a09b84..25490fcab5a2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -725,6 +725,7 @@ F:	drivers/mfd/airoha-an8855.c
 F:	drivers/net/dsa/an8855.c
 F:	drivers/net/dsa/an8855.h
 F:	drivers/net/mdio/mdio-an8855.c
+F:	drivers/net/phy/air_an8855.c
 F:	drivers/nvmem/an8855-efuse.c
 
 AIROHA ETHERNET DRIVER
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 15828f4710a9..9b4a7c12b138 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -79,6 +79,11 @@ config SFP
 
 comment "MII PHY device drivers"
 
+config AIR_AN8855_PHY
+	tristate "Airoha AN8855 Internal Gigabit PHY"
+	help
+	  Currently supports the internal Airoha AN8855 Switch PHY.
+
 config AIR_EN8811H_PHY
 	tristate "Airoha EN8811H 2.5 Gigabit PHY"
 	help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index e6145153e837..38ca7432780e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -35,6 +35,7 @@ obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
 
 obj-$(CONFIG_ADIN_PHY)		+= adin.o
 obj-$(CONFIG_ADIN1100_PHY)	+= adin1100.o
+obj-$(CONFIG_AIR_AN8855_PHY)   += air_an8855.o
 obj-$(CONFIG_AIR_EN8811H_PHY)   += air_en8811h.o
 obj-$(CONFIG_AMD_PHY)		+= amd.o
 obj-$(CONFIG_AMCC_QT2025_PHY)	+= qt2025.o
diff --git a/drivers/net/phy/air_an8855.c b/drivers/net/phy/air_an8855.c
new file mode 100644
index 000000000000..7fab0854ef78
--- /dev/null
+++ b/drivers/net/phy/air_an8855.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth at gmail.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/phy.h>
+
+#define AN8855_PHY_SELECT_PAGE			0x1f
+#define   AN8855_PHY_PAGE			GENMASK(2, 0)
+#define   AN8855_PHY_PAGE_STANDARD		FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
+#define   AN8855_PHY_PAGE_EXTENDED_1		FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
+
+/* MII Registers Page 1 */
+#define AN8855_PHY_EXT_REG_14			0x14
+#define   AN8855_PHY_EN_DOWN_SHIFT		BIT(4)
+
+/* R50 Calibration regs in MDIO_MMD_VEND1 */
+#define AN8855_PHY_R500HM_RSEL_TX_AB		0x174
+#define AN8855_PHY_R50OHM_RSEL_TX_A_EN		BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_A		GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_B_EN		BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_B		GENMASK(6, 0)
+#define AN8855_PHY_R500HM_RSEL_TX_CD		0x175
+#define AN8855_PHY_R50OHM_RSEL_TX_C_EN		BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_C		GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_D_EN		BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_D		GENMASK(6, 0)
+
+#define AN8855_SWITCH_EFUSE_R50O		GENMASK(30, 24)
+
+/* PHY TX PAIR DELAY SELECT Register */
+#define AN8855_PHY_TX_PAIR_DLY_SEL_GBE		0x013
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE GENMASK(14, 12)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_B_GBE GENMASK(10, 8)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE GENMASK(6, 4)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_D_GBE GENMASK(2, 0)
+/* PHY ADC Register */
+#define AN8855_PHY_RXADC_CTRL			0x0d8
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A	BIT(12)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_B	BIT(8)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C	BIT(4)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_D	BIT(0)
+#define AN8855_PHY_RXADC_REV_0			0x0d9
+#define   AN8855_PHY_RG_AD_RESERVE0_A		GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_B		GENMASK(7, 0)
+#define AN8855_PHY_RXADC_REV_1			0x0da
+#define   AN8855_PHY_RG_AD_RESERVE0_C		GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_D		GENMASK(7, 0)
+
+#define AN8855_PHY_ID				0xc0ff0410
+
+#define AN8855_PHY_FLAGS_EN_CALIBRATION		BIT(0)
+
+struct air_an8855_priv {
+	u8 calibration_data[4];
+};
+
+static const u8 dsa_r50ohm_table[] = {
+	127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+	127, 127, 127, 127, 127, 127, 127, 126, 122, 117,
+	112, 109, 104, 101,  97,  94,  90,  88,  84,  80,
+	78,  74,  72,  68,  66,  64,  61,  58,  56,  53,
+	51,  48,  47,  44,  42,  40,  38,  36,  34,  32,
+	31,  28,  27,  24,  24,  22,  20,  18,  16,  16,
+	14,  12,  11,   9
+};
+
+static int en8855_get_r50ohm_val(struct device *dev, const char *calib_name,
+				 u8 *dest)
+{
+	u32 shift_sel, val;
+	int ret;
+	int i;
+
+	ret = nvmem_cell_read_u32(dev, calib_name, &val);
+	if (ret)
+		return ret;
+
+	shift_sel = FIELD_GET(AN8855_SWITCH_EFUSE_R50O, val);
+	for (i = 0; i < ARRAY_SIZE(dsa_r50ohm_table); i++)
+		if (dsa_r50ohm_table[i] == shift_sel)
+			break;
+
+	if (i < 8 || i >= ARRAY_SIZE(dsa_r50ohm_table))
+		*dest = dsa_r50ohm_table[25];
+	else
+		*dest = dsa_r50ohm_table[i - 8];
+
+	return 0;
+}
+
+static int an8855_probe(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	struct device_node *node = dev->of_node;
+	struct air_an8855_priv *priv;
+
+	/* If we don't have a node, skip calib */
+	if (!node)
+		return 0;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	phydev->priv = priv;
+
+	return 0;
+}
+
+static int an8855_get_downshift(struct phy_device *phydev, u8 *data)
+{
+	int val;
+
+	val = phy_read_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1, AN8855_PHY_EXT_REG_14);
+	if (val < 0)
+		return val;
+
+	*data = val & AN8855_PHY_EN_DOWN_SHIFT ? DOWNSHIFT_DEV_DEFAULT_COUNT :
+						 DOWNSHIFT_DEV_DISABLE;
+
+	return 0;
+}
+
+static int an8855_set_downshift(struct phy_device *phydev, u8 cnt)
+{
+	u16 ds = cnt != DOWNSHIFT_DEV_DISABLE ? AN8855_PHY_EN_DOWN_SHIFT : 0;
+
+	return phy_modify_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1,
+				AN8855_PHY_EXT_REG_14, AN8855_PHY_EN_DOWN_SHIFT,
+				ds);
+}
+
+static int an8855_config_init(struct phy_device *phydev)
+{
+	struct air_an8855_priv *priv = phydev->priv;
+	struct device *dev = &phydev->mdio.dev;
+	int ret;
+
+	/* Enable HW auto downshift */
+	ret = an8855_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT);
+	if (ret)
+		return ret;
+
+	/* Apply calibration values, if needed.
+	 * AN8855_PHY_FLAGS_EN_CALIBRATION signal this.
+	 */
+	if (priv && phydev->dev_flags & AN8855_PHY_FLAGS_EN_CALIBRATION) {
+		u8 *calibration_data = priv->calibration_data;
+
+		ret = en8855_get_r50ohm_val(dev, "tx_a", &calibration_data[0]);
+		if (ret)
+			return ret;
+
+		ret = en8855_get_r50ohm_val(dev, "tx_b", &calibration_data[1]);
+		if (ret)
+			return ret;
+
+		ret = en8855_get_r50ohm_val(dev, "tx_c", &calibration_data[2]);
+		if (ret)
+			return ret;
+
+		ret = en8855_get_r50ohm_val(dev, "tx_d", &calibration_data[3]);
+		if (ret)
+			return ret;
+
+		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_AB,
+				     AN8855_PHY_R50OHM_RSEL_TX_A | AN8855_PHY_R50OHM_RSEL_TX_B,
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_A, calibration_data[0]) |
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_B, calibration_data[1]));
+		if (ret)
+			return ret;
+		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_CD,
+				     AN8855_PHY_R50OHM_RSEL_TX_C | AN8855_PHY_R50OHM_RSEL_TX_D,
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_C, calibration_data[2]) |
+				     FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_D, calibration_data[3]));
+		if (ret)
+			return ret;
+	}
+
+	/* Apply values to reduce signal noise */
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_TX_PAIR_DLY_SEL_GBE,
+			    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE, 0x4) |
+			    FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE, 0x4));
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_CTRL,
+			    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A |
+			    AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C);
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_0,
+			    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_A, 0x1));
+	if (ret)
+		return ret;
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_1,
+			    FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_C, 0x1));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int an8855_get_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, void *data)
+{
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT:
+		return an8855_get_downshift(phydev, data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int an8855_set_tunable(struct phy_device *phydev,
+			      struct ethtool_tunable *tuna, const void *data)
+{
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT:
+		return an8855_set_downshift(phydev, *(const u8 *)data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int an8855_read_page(struct phy_device *phydev)
+{
+	return __phy_read(phydev, AN8855_PHY_SELECT_PAGE);
+}
+
+static int an8855_write_page(struct phy_device *phydev, int page)
+{
+	return __phy_write(phydev, AN8855_PHY_SELECT_PAGE, page);
+}
+
+static struct phy_driver an8855_driver[] = {
+{
+	PHY_ID_MATCH_EXACT(AN8855_PHY_ID),
+	.name			= "Airoha AN8855 internal PHY",
+	/* PHY_GBIT_FEATURES */
+	.flags			= PHY_IS_INTERNAL,
+	.probe			= an8855_probe,
+	.config_init		= an8855_config_init,
+	.soft_reset		= genphy_soft_reset,
+	.get_tunable		= an8855_get_tunable,
+	.set_tunable		= an8855_set_tunable,
+	.suspend		= genphy_suspend,
+	.resume			= genphy_resume,
+	.read_page		= an8855_read_page,
+	.write_page		= an8855_write_page,
+}, };
+
+module_phy_driver(an8855_driver);
+
+static struct mdio_device_id __maybe_unused an8855_tbl[] = {
+	{ PHY_ID_MATCH_EXACT(AN8855_PHY_ID) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(mdio, an8855_tbl);
+
+MODULE_DESCRIPTION("Airoha AN8855 PHY driver");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth at gmail.com>");
+MODULE_LICENSE("GPL");
-- 
2.45.2



From shameerali.kolothum.thodi at huawei.com  Mon Dec  9 05:49:07 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Mon, 9 Dec 2024 13:49:07 +0000
Subject: [PATCH v3 3/3] arm64: paravirt: Enable errata based on
 implementation CPUs
In-Reply-To: <875xnt10oj.fsf@redhat.com>
References: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>
 <20241209115311.40496-4-shameerali.kolothum.thodi@huawei.com>
 <875xnt10oj.fsf@redhat.com>
Message-ID: <d92ea2dcc3b04ebb8bc5ba71bff448bc@huawei.com>



> -----Original Message-----
> From: Cornelia Huck <cohuck at redhat.com>
> Sent: Monday, December 9, 2024 12:49 PM
> To: Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi at huawei.com>; kvmarm at lists.linux.dev;
> maz at kernel.org; oliver.upton at linux.dev
> Cc: catalin.marinas at arm.com; will at kernel.org; mark.rutland at arm.com;
> eric.auger at redhat.com; yuzenghui <yuzenghui at huawei.com>; Wangzhou
> (B) <wangzhou1 at hisilicon.com>; jiangkunkun <jiangkunkun at huawei.com>;
> Jonathan Cameron <jonathan.cameron at huawei.com>; Anthony Jebson
> <anthony.jebson at huawei.com>; linux-arm-kernel at lists.infradead.org;
> Linuxarm <linuxarm at huawei.com>
> Subject: Re: [PATCH v3 3/3] arm64: paravirt: Enable errata based on
> implementation CPUs
> 
> On Mon, Dec 09 2024, Shameer Kolothum
> <shameerali.kolothum.thodi at huawei.com> wrote:
> 
> > Retrieve any migration target implementation CPUs using the hypercall
> > and enable associated errata.
> >
> > Signed-off-by: Shameer Kolothum
> <shameerali.kolothum.thodi at huawei.com>
> > ---
> > Note:
> >
> > One thing I am not sure here is how to handle the hypercall error.
> > Do we need to fail the Guest boot or just carry on without any
> > target implementation CPU support? At the moment it just carries on.
> >
> > Thanks,
> > Shameer
> > ---
> >  arch/arm64/include/asm/cputype.h  | 25 +++++++++++++++++++++++--
> >  arch/arm64/include/asm/paravirt.h |  3 +++
> >  arch/arm64/kernel/cpu_errata.c    | 20 +++++++++++++++++---
> >  arch/arm64/kernel/cpufeature.c    |  2 ++
> >  arch/arm64/kernel/image-vars.h    |  2 ++
> >  arch/arm64/kernel/paravirt.c      | 31
> +++++++++++++++++++++++++++++++
> >  6 files changed, 78 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/cputype.h
> b/arch/arm64/include/asm/cputype.h
> > index dcf0e1ce892d..9e466f3ae9c6 100644
> > --- a/arch/arm64/include/asm/cputype.h
> > +++ b/arch/arm64/include/asm/cputype.h
> > @@ -265,6 +265,16 @@ struct midr_range {
> >  #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r)
> >  #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
> >
> > +#define MAX_TARGET_IMPL_CPUS 64
> > +
> > +struct target_impl_cpu {
> > +	u32 midr;
> > +	u32 revidr;
> > +};
> 
> Doesn't this need to be u64 for both (even if the upper bits for
> MIDR_EL1 are reserved?)

Yes, both are u64 as per specification with upper bits reserved. And the 
external hypercall interface has uint64.

But in kernel, AFAICS, at present all the _midr_range_() functions expect u32.
So not sure we gain much now by changing to u64.

Thanks,
Shameer
 



From etienne.carriere at foss.st.com  Mon Dec  9 05:48:48 2024
From: etienne.carriere at foss.st.com (Etienne CARRIERE - foss)
Date: Mon, 9 Dec 2024 13:48:48 +0000
Subject: [PATCH v2 1/2] firmware: arm_scmi: get only min/max clock rates
In-Reply-To: <Z1bHgf_4qqZgSnDt@bogus>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-2-etienne.carriere@foss.st.com>,<Z1bHgf_4qqZgSnDt@bogus>
Message-ID: <22ff786d1e034169be21ef7dc32c4a3a@foss.st.com>

On Monday, December 9, 2024, Sudeep Holla wrote:
> On Tue, Dec 03, 2024 at 06:39:07PM +0100, Etienne Carriere wrote:
> > Remove limitation of 16 clock rates max for discrete clock rates
> > description when the SCMI firmware supports SCMI Clock protocol v2.0
> > or later.
> >
> > Driver clk-scmi.c is only interested in the min and max clock rates.
> > Get these by querying the first and last discrete rates with SCMI
> > clock protocol message ID CLOCK_DESCRIBE_RATES since the SCMI
> > specification v2.0 and later states that rates enumerated by this
> > command are to be enumerated in "numeric ascending order" [1].
> >
> > Preserve the implementation that queries all discrete rates (16 rates
> > max) to support SCMI firmware built on SCMI specification v1.0 [2]
> > where SCMI Clock protocol v1.0 does not explicitly require rates
> > described with CLOCK_DESCRIBE_RATES to be in ascending order.
> >
> > Link: https://developer.arm.com/documentation/den0056 [1]
> > Link: https://developer.arm.com/documentation/den0056/a [2]
> > Signed-off-by: Etienne Carriere <etienne.carriere at foss.st.com>
> > ---
> 
> [...]
> 
> > +
> > +static int scmi_clock_get_rates_bound(const struct scmi_protocol_handle *ph,
> > +                                   u32 clk_id, struct scmi_clock_info *clk)
> > +{
> 
> This new function seem to have unwraped the scmi_iterator_ops(namely
> prepare_message, update_state and process_response instead of reusing them.
> Can you please explain why it wasn't possible to reuse them ?

Since we're interested here only in min and max rates, let's query the
first and last rates only. This can save a bit of useless transactions between
agent and firmware in case there are many clocks with somewhat large
the discrete rate lists.

I though using the iterator for this specific case would add a bit more
complexity: it's expected to iterate (st->desc_index incremented from the
common scmi_iterator_run() function) whereas here I propose to send
only 2 messages.

BR,
Etienne

> 
> --
> Regards,
> Sudeep
>

From broonie at kernel.org  Mon Dec  9 05:51:32 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 9 Dec 2024 13:51:32 +0000
Subject: [PATCH] kselftest/arm64: abi: fix SVCR detection
In-Reply-To: <CAHk0HotQ-=s+-FHh8pAOg10ivcRwqChG735qgDvuQd=4B1QQNA@mail.gmail.com>
References: <20241209105237.10498-1-o451686892@gmail.com>
 <3279e669-1ee2-4792-9e10-8b40928de6b4@sirena.org.uk>
 <CAHk0Hov5k37=MtTBLWTj+Dwm4EXE0xGJS1Uc8xgyLtJxusqsww@mail.gmail.com>
 <c05f6ad8-2dc1-4ddb-b9c1-b2cddfe78819@sirena.org.uk>
 <CAHk0HotQ-=s+-FHh8pAOg10ivcRwqChG735qgDvuQd=4B1QQNA@mail.gmail.com>
Message-ID: <678a223f-c4c7-4752-84b0-609acaa33ad6@sirena.org.uk>

On Mon, Dec 09, 2024 at 09:26:01PM +0800, Weizhao Ouyang wrote:

> > If we don't have SME we should be skipping over all the SME code and
> > never even looking at the value of SVCR.  Looking at the current version
> > of the code it does that, it branches to check_sve_in if SME is not
> > enabled.

> Yes we should skip it, this is just a minor tweak based on the
> current implementation, after all, we manually passed its value by
> svcr_in.

It's a fairly trivial tweak to make...  in any case, it looks like we
also need the same change in the save path.

> Which latest code version are you referring to? I think check_sve_in
> is in fp testcase, not in the abi testcase. (checked the -next tree)

Ah, yes sorry.
-------------- 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/20241209/f7762490/attachment.sig>

From matthias.schiffer at ew.tq-group.com  Mon Dec  9 05:55:31 2024
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Mon, 09 Dec 2024 14:55:31 +0100
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and
 MBa62xx carrier board Device Trees
In-Reply-To: <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
	 <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
	 <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>
Message-ID: <c902a56cf34838f60cee67624bb923e91d74e9e0.camel@ew.tq-group.com>

On Mon, 2024-12-09 at 14:24 +0100, Andrew Lunn wrote:
> 
> > +&cpsw_port1 {
> > +	phy-mode = "rgmii-rxid";
> > +	phy-handle = <&cpsw3g_phy0>;
> > +};
> > +
> > +&cpsw_port2 {
> > +	phy-mode = "rgmii-rxid";
> > +	phy-handle = <&cpsw3g_phy3>;
> > +};
> 
> rgmii-rxid is very odd.
> 
> > +
> > +&cpsw3g_mdio {
> > +	status = "okay";
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&main_mdio1_pins>;
> > +
> > +	cpsw3g_phy0: ethernet-phy at 0 {
> > +		compatible = "ethernet-phy-ieee802.3-c22";
> > +		reg = <0x0>;
> > +		reset-gpios = <&main_gpio1 11 GPIO_ACTIVE_LOW>;
> > +		reset-assert-us = <1000>;
> > +		reset-deassert-us = <1000>;
> > +		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
> 
> I guess this is the explanation.
> 
> What happens when you use rgmii-id, and don't have this delay here?
> That would be normal.
> 
> 	Andrew


This is normal for AM62-based boards, see the DTSI of the TI reference
starterkit for example:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi#n451

With rgmii-id, both ti,rx-internal-delay and ti,tx-internal-delay should be set.
As ti,*-internal-delay sets the delay on the PHY side, phy-mode "rgmii" is the
one that would not use either:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/net/ti,dp83867.yaml#n78

At the end of the day, does it really matter as long as MAC and PHY agree on the
used mode? We copied this part of the hardware design from the TI reference
board, and did our hardware qualification with these settings, so I think it
makes sense to use the same phy-mode configuration.

Best regards,
Matthias


-- 
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
https://www.tq-group.com/


From mark.rutland at arm.com  Mon Dec  9 05:56:23 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 9 Dec 2024 13:56:23 +0000
Subject: [PATCH 1/4] arm64/sysreg: Allow a 'Mapping' descriptor for
 system registers
In-Reply-To: <20241207190740.2607673-2-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
 <20241207190740.2607673-2-maz@kernel.org>
Message-ID: <Z1b3B2swQ0HrB3bO@J2N7QTR9R3.cambridge.arm.com>

On Sat, Dec 07, 2024 at 07:07:37PM +0000, Marc Zyngier wrote:
> *EL02 and *_EL12 system registers are actually only accessors for
> EL0 and EL1 registers accessed from EL2 when HCR_EL2.E2H==1. They
> do not have fields of their own.
> 
> To that effect, introduce a 'Mapping' entry, describing which
> system register an _EL12 register maps to.
> 
> Implementation wise, this is handled the same was as Fields,
> which ls only a comment.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/tools/gen-sysreg.awk | 2 +-
>  arch/arm64/tools/sysreg         | 7 +++++++
>  2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/tools/gen-sysreg.awk b/arch/arm64/tools/gen-sysreg.awk
> index d1254a056114e..1a2afc9fdd42e 100755
> --- a/arch/arm64/tools/gen-sysreg.awk
> +++ b/arch/arm64/tools/gen-sysreg.awk
> @@ -206,7 +206,7 @@ END {
>  
>  # Currently this is effectivey a comment, in future we may want to emit
>  # defines for the fields.
> -/^Fields/ && block_current() == "Sysreg" {
> +(/^Fields/ || /^Mapping/) && block_current() == "Sysreg" {
>  	expect_fields(2)
>  
>  	if (next_bit != 63)
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index b081b54d6d227..b6846c601df6c 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -38,6 +38,13 @@
>  # Fields	<fieldsname>
>  # EndSysreg
>  
> +# For register names indicating a cross-EL access (*_EL12, *EL02),
> +# a Mapping entry describes the register it actually accesses:

It might be better to say:

| For VHE aliases (*_EL12, *_EL02) of system registers, a Mapping entry
| describes the register the alias actually accesses:

... and with that'd it's probably best to place this above the
description of SysregFields, so that people see this first and don't
copy the anti-pattern you're trying to remove.

For SysregFields we could clarify the existing wording to:

| Where multiple system regsiters are not VHE aliases but share a common
| layout, a SysregFields block can be used to describe the shared
| layout:

With or without those changes:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> +
> +# Sysreg 	<name_EL12>	<op0> 	<op1>	<crn>	<crm>	<op2>
> +# Mapping	<name_EL1>
> +# EndSysreg
> +
>  # For ID registers we adopt a few conventions for translating the
>  # language in the ARM into defines:
>  #
> -- 
> 2.39.2
> 


From mark.rutland at arm.com  Mon Dec  9 05:57:08 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 9 Dec 2024 13:57:08 +0000
Subject: [PATCH 2/4] arm64/sysreg: Get rid of the TCR2_EL1x SysregFields
In-Reply-To: <20241207190740.2607673-3-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
 <20241207190740.2607673-3-maz@kernel.org>
Message-ID: <Z1b3NEoIALJYCdL9@J2N7QTR9R3.cambridge.arm.com>

On Sat, Dec 07, 2024 at 07:07:38PM +0000, Marc Zyngier wrote:
> TCR2_ELx is a pretty bizarre construct, as it is shared between
> TCR2_EL1 and TCR2_EL12. But the latter is obviously only an
> accessor to the former.

Minor nit, but I believe that the first 'TCR2_ELx' here should be
'TCR2_EL1x'.

> In order to make things more consistent, upgrade TCR2_EL1x to
> a full-blown sysreg definition for TCR2_EL1, and describe TCR2_EL12
> as a mapping to TCR2_EL1.
> 
> This results in a couple of minor changes to the actual code.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

I agree the *_EL1x thins is horrid.

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/kernel/cpufeature.c | 2 +-
>  arch/arm64/kvm/at.c            | 6 +++---
>  arch/arm64/mm/proc.S           | 5 +++--
>  arch/arm64/tools/sysreg        | 8 ++------
>  4 files changed, 9 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 6ce71f444ed84..7712df48758e9 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2376,7 +2376,7 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused)
>  #ifdef CONFIG_ARM64_POE
>  static void cpu_enable_poe(const struct arm64_cpu_capabilities *__unused)
>  {
> -	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1x_E0POE);
> +	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1_E0POE);
>  	sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_E0POE);
>  }
>  #endif
> diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
> index 8c5d7990e5b31..0905b8778a9bb 100644
> --- a/arch/arm64/kvm/at.c
> +++ b/arch/arm64/kvm/at.c
> @@ -111,7 +111,7 @@ static bool s1pie_enabled(struct kvm_vcpu *vcpu, enum trans_regime regime)
>  		return vcpu_read_sys_reg(vcpu, TCR2_EL2) & TCR2_EL2_PIE;
>  	case TR_EL10:
>  		return  (__vcpu_sys_reg(vcpu, HCRX_EL2) & HCRX_EL2_TCR2En) &&
> -			(__vcpu_sys_reg(vcpu, TCR2_EL1) & TCR2_EL1x_PIE);
> +			(__vcpu_sys_reg(vcpu, TCR2_EL1) & TCR2_EL1_PIE);
>  	default:
>  		BUG();
>  	}
> @@ -140,8 +140,8 @@ static void compute_s1poe(struct kvm_vcpu *vcpu, struct s1_walk_info *wi)
>  		}
>  
>  		val = __vcpu_sys_reg(vcpu, TCR2_EL1);
> -		wi->poe = val & TCR2_EL1x_POE;
> -		wi->e0poe = val & TCR2_EL1x_E0POE;
> +		wi->poe = val & TCR2_EL1_POE;
> +		wi->e0poe = val & TCR2_EL1_E0POE;
>  	}
>  }
>  
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index b8edc5765441e..fb30c8804f87b 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -501,7 +501,7 @@ alternative_else_nop_endif
>  #ifdef CONFIG_ARM64_HAFT
>  	cmp	x9, ID_AA64MMFR1_EL1_HAFDBS_HAFT
>  	b.lt	1f
> -	orr	tcr2, tcr2, TCR2_EL1x_HAFT
> +	orr	tcr2, tcr2, TCR2_EL1_HAFT
>  #endif /* CONFIG_ARM64_HAFT */
>  1:
>  #endif	/* CONFIG_ARM64_HW_AFDBM */
> @@ -532,7 +532,8 @@ alternative_else_nop_endif
>  #undef PTE_MAYBE_NG
>  #undef PTE_MAYBE_SHARED
>  
> -	orr	tcr2, tcr2, TCR2_EL1x_PIE
> +	orr	tcr2, tcr2, TCR2_EL1_PIE
> +	msr	REG_TCR2_EL1, x0
>  
>  .Lskip_indirection:
>  
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index b6846c601df6c..19d137d9c50ed 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2999,7 +2999,7 @@ Sysreg	TTBR1_EL1	3	0	2	0	1
>  Fields	TTBRx_EL1
>  EndSysreg
>  
> -SysregFields	TCR2_EL1x
> +Sysreg	TCR2_EL1	3	0	2	0	3
>  Res0	63:16
>  Field	15	DisCH1
>  Field	14	DisCH0
> @@ -3013,14 +3013,10 @@ Field	3	POE
>  Field	2	E0POE
>  Field	1	PIE
>  Field	0	PnCH
> -EndSysregFields
> -
> -Sysreg	TCR2_EL1	3	0	2	0	3
> -Fields	TCR2_EL1x
>  EndSysreg
>  
>  Sysreg	TCR2_EL12	3	5	2	0	3
> -Fields	TCR2_EL1x
> +Mapping	TCR2_EL1
>  EndSysreg
>  
>  Sysreg	TCR2_EL2	3	4	2	0	3
> -- 
> 2.39.2
> 


From mark.rutland at arm.com  Mon Dec  9 05:59:27 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 9 Dec 2024 13:59:27 +0000
Subject: [PATCH 3/4] arm64/sysreg: Convert *_EL12 accessors to Mapping
In-Reply-To: <20241207190740.2607673-4-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
 <20241207190740.2607673-4-maz@kernel.org>
Message-ID: <Z1b3v3NvMK28NqTt@J2N7QTR9R3.cambridge.arm.com>

On Sat, Dec 07, 2024 at 07:07:39PM +0000, Marc Zyngier wrote:
> Perform a bulk convert of the remaining EL12 accessors to use the
> Mapping qualifier, which meakes things a bit clearer.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

I haven't looked at the code in detail, but conceptually this makes
sense to me, so:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/tools/sysreg | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 19d137d9c50ed..ad2f6265f7948 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2954,23 +2954,23 @@ Field	63:0	PhysicalOffset
>  EndSysreg
>  
>  Sysreg	CPACR_EL12	3	5	1	0	2
> -Fields	CPACR_ELx
> +Mapping	CPACR_EL1
>  EndSysreg
>  
>  Sysreg	ZCR_EL12	3	5	1	2	0
> -Fields	ZCR_ELx
> +Mapping	ZCR_EL1
>  EndSysreg
>  
>  Sysreg	SMCR_EL12	3	5	1	2	6
> -Fields	SMCR_ELx
> +Mapping	SMCR_EL1
>  EndSysreg
>  
>  Sysreg	GCSCR_EL12	3	5	2	5	0
> -Fields	GCSCR_ELx
> +Mapping	GCSCR_EL1
>  EndSysreg
>  
>  Sysreg	GCSPR_EL12	3	5	2	5	1
> -Fields	GCSPR_ELx
> +Mapping	GCSPR_EL1
>  EndSysreg
>  
>  Sysreg	FAR_EL12	3	5	6	0	0
> @@ -2982,7 +2982,7 @@ Fields	MPAM1_ELx
>  EndSysreg
>  
>  Sysreg	CONTEXTIDR_EL12	3	5	13	0	1
> -Fields	CONTEXTIDR_ELx
> +Mapping	CONTEXTIDR_EL1
>  EndSysreg
>  
>  SysregFields TTBRx_EL1
> @@ -3087,7 +3087,7 @@ Fields	PIRx_ELx
>  EndSysreg
>  
>  Sysreg	PIRE0_EL12	3	5	10	2	2
> -Fields	PIRx_ELx
> +Mapping	PIRE0_EL1
>  EndSysreg
>  
>  Sysreg	PIRE0_EL2	3	4	10	2	2
> @@ -3099,7 +3099,7 @@ Fields	PIRx_ELx
>  EndSysreg
>  
>  Sysreg	PIR_EL12	3	5	10	2	3
> -Fields	PIRx_ELx
> +Mapping	PIR_EL1
>  EndSysreg
>  
>  Sysreg	PIR_EL2		3	4	10	2	3
> @@ -3119,7 +3119,7 @@ Fields	PIRx_ELx
>  EndSysreg
>  
>  Sysreg	POR_EL12	3	5	10	2	4
> -Fields	PIRx_ELx
> +Mapping	POR_EL1
>  EndSysreg
>  
>  Sysreg	S2POR_EL1	3	0	10	2	5
> -- 
> 2.39.2
> 


From mark.rutland at arm.com  Mon Dec  9 06:01:08 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 9 Dec 2024 14:01:08 +0000
Subject: [PATCH 4/4] arm64/sysreg: Get rid of CPACR_ELx SysregFields
In-Reply-To: <20241207190740.2607673-5-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
 <20241207190740.2607673-5-maz@kernel.org>
Message-ID: <Z1b4JKEXEK9PkZEu@J2N7QTR9R3.cambridge.arm.com>

On Sat, Dec 07, 2024 at 07:07:40PM +0000, Marc Zyngier wrote:
> There is no such thing as CPACR_ELx in the architecture.
> What we have is CPACR_EL1, for which CPTR_EL12 is an accessor.
> 
> Rename CPACR_ELx_* to CPACR_EL1_*, and fix the bit of code using
> these names.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

I ahven't look at this in great detail, but conceptaully it makes sense
to me, so:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/el2_setup.h      |  6 ++--
>  arch/arm64/include/asm/kvm_arm.h        |  2 --
>  arch/arm64/include/asm/kvm_emulate.h    | 40 ++++++++++++-------------
>  arch/arm64/include/asm/kvm_nested.h     |  8 ++---
>  arch/arm64/kernel/cpufeature.c          |  2 +-
>  arch/arm64/kvm/emulate-nested.c         |  2 +-
>  arch/arm64/kvm/fpsimd.c                 |  2 +-
>  arch/arm64/kvm/hyp/include/hyp/switch.h |  4 +--
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  4 +--
>  arch/arm64/kvm/hyp/nvhe/pkvm.c          |  2 +-
>  arch/arm64/kvm/hyp/nvhe/switch.c        |  6 ++--
>  arch/arm64/kvm/hyp/vhe/switch.c         | 16 +++++-----
>  arch/arm64/tools/sysreg                 |  6 +---
>  13 files changed, 47 insertions(+), 53 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index 85ef966c08cd2..cc39c57df7873 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -154,7 +154,7 @@
>  /* Coprocessor traps */
>  .macro __init_el2_cptr
>  	__check_hvhe .LnVHE_\@, x1
> -	mov	x0, #CPACR_ELx_FPEN
> +	mov	x0, #CPACR_EL1_FPEN
>  	msr	cpacr_el1, x0
>  	b	.Lskip_set_cptr_\@
>  .LnVHE_\@:
> @@ -332,7 +332,7 @@
>  
>  	// (h)VHE case
>  	mrs	x0, cpacr_el1			// Disable SVE traps
> -	orr	x0, x0, #CPACR_ELx_ZEN
> +	orr	x0, x0, #CPACR_EL1_ZEN
>  	msr	cpacr_el1, x0
>  	b	.Lskip_set_cptr_\@
>  
> @@ -353,7 +353,7 @@
>  
>  	// (h)VHE case
>  	mrs	x0, cpacr_el1			// Disable SME traps
> -	orr	x0, x0, #CPACR_ELx_SMEN
> +	orr	x0, x0, #CPACR_EL1_SMEN
>  	msr	cpacr_el1, x0
>  	b	.Lskip_set_cptr_sme_\@
>  
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 3e0f0de1d2da8..43e365fbff0b2 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -391,8 +391,6 @@
>  	ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
>  	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64), ECN(ERET)
>  
> -#define CPACR_EL1_TTA		(1 << 28)
> -
>  #define kvm_mode_names				\
>  	{ PSR_MODE_EL0t,	"EL0t" },	\
>  	{ PSR_MODE_EL1t,	"EL1t" },	\
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index cf811009a33c9..4f1d99725f6b3 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -556,13 +556,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
>  	({								\
>  		u64 cptr = 0;						\
>  									\
> -		if ((set) & CPACR_ELx_FPEN)				\
> +		if ((set) & CPACR_EL1_FPEN)				\
>  			cptr |= CPTR_EL2_TFP;				\
> -		if ((set) & CPACR_ELx_ZEN)				\
> +		if ((set) & CPACR_EL1_ZEN)				\
>  			cptr |= CPTR_EL2_TZ;				\
> -		if ((set) & CPACR_ELx_SMEN)				\
> +		if ((set) & CPACR_EL1_SMEN)				\
>  			cptr |= CPTR_EL2_TSM;				\
> -		if ((clr) & CPACR_ELx_TTA)				\
> +		if ((clr) & CPACR_EL1_TTA)				\
>  			cptr |= CPTR_EL2_TTA;				\
>  		if ((clr) & CPTR_EL2_TAM)				\
>  			cptr |= CPTR_EL2_TAM;				\
> @@ -576,13 +576,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
>  	({								\
>  		u64 cptr = 0;						\
>  									\
> -		if ((clr) & CPACR_ELx_FPEN)				\
> +		if ((clr) & CPACR_EL1_FPEN)				\
>  			cptr |= CPTR_EL2_TFP;				\
> -		if ((clr) & CPACR_ELx_ZEN)				\
> +		if ((clr) & CPACR_EL1_ZEN)				\
>  			cptr |= CPTR_EL2_TZ;				\
> -		if ((clr) & CPACR_ELx_SMEN)				\
> +		if ((clr) & CPACR_EL1_SMEN)				\
>  			cptr |= CPTR_EL2_TSM;				\
> -		if ((set) & CPACR_ELx_TTA)				\
> +		if ((set) & CPACR_EL1_TTA)				\
>  			cptr |= CPTR_EL2_TTA;				\
>  		if ((set) & CPTR_EL2_TAM)				\
>  			cptr |= CPTR_EL2_TAM;				\
> @@ -595,13 +595,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
>  #define cpacr_clear_set(clr, set)					\
>  	do {								\
>  		BUILD_BUG_ON((set) & CPTR_VHE_EL2_RES0);		\
> -		BUILD_BUG_ON((clr) & CPACR_ELx_E0POE);			\
> -		__build_check_all_or_none((clr), CPACR_ELx_FPEN);	\
> -		__build_check_all_or_none((set), CPACR_ELx_FPEN);	\
> -		__build_check_all_or_none((clr), CPACR_ELx_ZEN);	\
> -		__build_check_all_or_none((set), CPACR_ELx_ZEN);	\
> -		__build_check_all_or_none((clr), CPACR_ELx_SMEN);	\
> -		__build_check_all_or_none((set), CPACR_ELx_SMEN);	\
> +		BUILD_BUG_ON((clr) & CPACR_EL1_E0POE);			\
> +		__build_check_all_or_none((clr), CPACR_EL1_FPEN);	\
> +		__build_check_all_or_none((set), CPACR_EL1_FPEN);	\
> +		__build_check_all_or_none((clr), CPACR_EL1_ZEN);	\
> +		__build_check_all_or_none((set), CPACR_EL1_ZEN);	\
> +		__build_check_all_or_none((clr), CPACR_EL1_SMEN);	\
> +		__build_check_all_or_none((set), CPACR_EL1_SMEN);	\
>  									\
>  		if (has_vhe() || has_hvhe())				\
>  			sysreg_clear_set(cpacr_el1, clr, set);		\
> @@ -624,16 +624,16 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
>  	u64 val;
>  
>  	if (has_vhe()) {
> -		val = (CPACR_ELx_FPEN | CPACR_EL1_ZEN_EL1EN);
> +		val = (CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN);
>  		if (cpus_have_final_cap(ARM64_SME))
>  			val |= CPACR_EL1_SMEN_EL1EN;
>  	} else if (has_hvhe()) {
> -		val = CPACR_ELx_FPEN;
> +		val = CPACR_EL1_FPEN;
>  
>  		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
> -			val |= CPACR_ELx_ZEN;
> +			val |= CPACR_EL1_ZEN;
>  		if (cpus_have_final_cap(ARM64_SME))
> -			val |= CPACR_ELx_SMEN;
> +			val |= CPACR_EL1_SMEN;
>  	} else {
>  		val = CPTR_NVHE_EL2_RES1;
>  
> @@ -685,7 +685,7 @@ static inline bool ____cptr_xen_trap_enabled(const struct kvm_vcpu *vcpu,
>  #define __guest_hyp_cptr_xen_trap_enabled(vcpu, xen)				\
>  	(!vcpu_has_nv(vcpu) ? false :						\
>  	 ____cptr_xen_trap_enabled(vcpu,					\
> -				   SYS_FIELD_GET(CPACR_ELx, xen,		\
> +				   SYS_FIELD_GET(CPACR_EL1, xen,		\
>  						 vcpu_sanitised_cptr_el2(vcpu))))
>  
>  static inline bool guest_hyp_fpsimd_traps_enabled(const struct kvm_vcpu *vcpu)
> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> index 233e655227164..6cd08198bf195 100644
> --- a/arch/arm64/include/asm/kvm_nested.h
> +++ b/arch/arm64/include/asm/kvm_nested.h
> @@ -33,14 +33,14 @@ static inline u64 translate_tcr_el2_to_tcr_el1(u64 tcr)
>  
>  static inline u64 translate_cptr_el2_to_cpacr_el1(u64 cptr_el2)
>  {
> -	u64 cpacr_el1 = CPACR_ELx_RES1;
> +	u64 cpacr_el1 = CPACR_EL1_RES1;
>  
>  	if (cptr_el2 & CPTR_EL2_TTA)
> -		cpacr_el1 |= CPACR_ELx_TTA;
> +		cpacr_el1 |= CPACR_EL1_TTA;
>  	if (!(cptr_el2 & CPTR_EL2_TFP))
> -		cpacr_el1 |= CPACR_ELx_FPEN;
> +		cpacr_el1 |= CPACR_EL1_FPEN;
>  	if (!(cptr_el2 & CPTR_EL2_TZ))
> -		cpacr_el1 |= CPACR_ELx_ZEN;
> +		cpacr_el1 |= CPACR_EL1_ZEN;
>  
>  	cpacr_el1 |= cptr_el2 & (CPTR_EL2_TCPAC | CPTR_EL2_TAM);
>  
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 7712df48758e9..6e220da3a495b 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2377,7 +2377,7 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused)
>  static void cpu_enable_poe(const struct arm64_cpu_capabilities *__unused)
>  {
>  	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1_E0POE);
> -	sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_E0POE);
> +	sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_E0POE);
>  }
>  #endif
>  
> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> index 1ffbfd1c3cf2e..f1b7287e1f3c3 100644
> --- a/arch/arm64/kvm/emulate-nested.c
> +++ b/arch/arm64/kvm/emulate-nested.c
> @@ -494,7 +494,7 @@ static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
>  	if (!vcpu_el2_e2h_is_set(vcpu))
>  		val = translate_cptr_el2_to_cpacr_el1(val);
>  
> -	if (val & CPACR_ELx_TTA)
> +	if (val & CPACR_EL1_TTA)
>  		return BEHAVE_FORWARD_RW;
>  
>  	return BEHAVE_HANDLE_LOCALLY;
> diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
> index ea5484ce1f3ba..98718bd65bf15 100644
> --- a/arch/arm64/kvm/fpsimd.c
> +++ b/arch/arm64/kvm/fpsimd.c
> @@ -169,7 +169,7 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
>  	if (has_vhe() && system_supports_sme()) {
>  		/* Also restore EL0 state seen on entry */
>  		if (vcpu_get_flag(vcpu, HOST_SME_ENABLED))
> -			sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_SMEN);
> +			sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_SMEN);
>  		else
>  			sysreg_clear_set(CPACR_EL1,
>  					 CPACR_EL1_SMEN_EL0EN,
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 34f53707892df..abfa6ad92e91e 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -419,9 +419,9 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
>  
>  	/* First disable enough traps to allow us to update the registers */
>  	if (sve_guest || (is_protected_kvm_enabled() && system_supports_sve()))
> -		cpacr_clear_set(0, CPACR_ELx_FPEN | CPACR_ELx_ZEN);
> +		cpacr_clear_set(0, CPACR_EL1_FPEN | CPACR_EL1_ZEN);
>  	else
> -		cpacr_clear_set(0, CPACR_ELx_FPEN);
> +		cpacr_clear_set(0, CPACR_EL1_FPEN);
>  	isb();
>  
>  	/* Write out the host state if it's in the registers */
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 6aa0b13d86e58..6c90ef6736d63 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -68,7 +68,7 @@ static void fpsimd_sve_sync(struct kvm_vcpu *vcpu)
>  	if (!guest_owns_fp_regs())
>  		return;
>  
> -	cpacr_clear_set(0, CPACR_ELx_FPEN | CPACR_ELx_ZEN);
> +	cpacr_clear_set(0, CPACR_EL1_FPEN | CPACR_EL1_ZEN);
>  	isb();
>  
>  	if (vcpu_has_sve(vcpu))
> @@ -481,7 +481,7 @@ void handle_trap(struct kvm_cpu_context *host_ctxt)
>  		handle_host_smc(host_ctxt);
>  		break;
>  	case ESR_ELx_EC_SVE:
> -		cpacr_clear_set(0, CPACR_ELx_ZEN);
> +		cpacr_clear_set(0, CPACR_EL1_ZEN);
>  		isb();
>  		sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1,
>  				       SYS_ZCR_EL2);
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index 01616c39a8107..a6638c4ecd32d 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -68,7 +68,7 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
>  	/* Trap SVE */
>  	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), feature_ids)) {
>  		if (has_hvhe())
> -			cptr_clear |= CPACR_ELx_ZEN;
> +			cptr_clear |= CPACR_EL1_ZEN;
>  		else
>  			cptr_set |= CPTR_EL2_TZ;
>  	}
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index cc69106734ca7..0f6b01b3da5cf 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -48,14 +48,14 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
>  	val |= has_hvhe() ? CPACR_EL1_TTA : CPTR_EL2_TTA;
>  	if (cpus_have_final_cap(ARM64_SME)) {
>  		if (has_hvhe())
> -			val &= ~CPACR_ELx_SMEN;
> +			val &= ~CPACR_EL1_SMEN;
>  		else
>  			val |= CPTR_EL2_TSM;
>  	}
>  
>  	if (!guest_owns_fp_regs()) {
>  		if (has_hvhe())
> -			val &= ~(CPACR_ELx_FPEN | CPACR_ELx_ZEN);
> +			val &= ~(CPACR_EL1_FPEN | CPACR_EL1_ZEN);
>  		else
>  			val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
>  
> @@ -192,7 +192,7 @@ static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
>  
>  		/* Re-enable SVE traps if not supported for the guest vcpu. */
>  		if (!vcpu_has_sve(vcpu))
> -			cpacr_clear_set(CPACR_ELx_ZEN, 0);
> +			cpacr_clear_set(CPACR_EL1_ZEN, 0);
>  
>  	} else {
>  		__fpsimd_save_state(*host_data_ptr(fpsimd_state));
> diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> index 80581b1c39959..59d992455793d 100644
> --- a/arch/arm64/kvm/hyp/vhe/switch.c
> +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> @@ -77,12 +77,12 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
>  	 * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
>  	 * shift value for trapping the AMU accesses.
>  	 */
> -	u64 val = CPACR_ELx_TTA | CPTR_EL2_TAM;
> +	u64 val = CPACR_EL1_TTA | CPTR_EL2_TAM;
>  
>  	if (guest_owns_fp_regs()) {
> -		val |= CPACR_ELx_FPEN;
> +		val |= CPACR_EL1_FPEN;
>  		if (vcpu_has_sve(vcpu))
> -			val |= CPACR_ELx_ZEN;
> +			val |= CPACR_EL1_ZEN;
>  	} else {
>  		__activate_traps_fpsimd32(vcpu);
>  	}
> @@ -122,13 +122,13 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
>  	 * hypervisor has traps enabled to dispel any illusion of something more
>  	 * complicated taking place.
>  	 */
> -	if (!(SYS_FIELD_GET(CPACR_ELx, FPEN, cptr) & BIT(0)))
> -		val &= ~CPACR_ELx_FPEN;
> -	if (!(SYS_FIELD_GET(CPACR_ELx, ZEN, cptr) & BIT(0)))
> -		val &= ~CPACR_ELx_ZEN;
> +	if (!(SYS_FIELD_GET(CPACR_EL1, FPEN, cptr) & BIT(0)))
> +		val &= ~CPACR_EL1_FPEN;
> +	if (!(SYS_FIELD_GET(CPACR_EL1, ZEN, cptr) & BIT(0)))
> +		val &= ~CPACR_EL1_ZEN;
>  
>  	if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
> -		val |= cptr & CPACR_ELx_E0POE;
> +		val |= cptr & CPACR_EL1_E0POE;
>  
>  	val |= cptr & CPTR_EL2_TCPAC;
>  
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index ad2f6265f7948..4e575c1b266f7 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -1985,7 +1985,7 @@ Field	1	A
>  Field	0	M
>  EndSysreg
>  
> -SysregFields	CPACR_ELx
> +Sysreg	CPACR_EL1	3	0	1	0	2
>  Res0	63:30
>  Field	29	E0POE
>  Field	28	TTA
> @@ -1996,10 +1996,6 @@ Field	21:20	FPEN
>  Res0	19:18
>  Field	17:16	ZEN
>  Res0	15:0
> -EndSysregFields
> -
> -Sysreg	CPACR_EL1	3	0	1	0	2
> -Fields	CPACR_ELx
>  EndSysreg
>  
>  Sysreg	SMPRI_EL1	3	0	1	2	4
> -- 
> 2.39.2
> 


From ansuelsmth at gmail.com  Mon Dec  9 05:44:17 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:17 +0100
Subject: [net-next PATCH v11 0/9] net: dsa: Add Airoha AN8855 support
Message-ID: <20241209134459.27110-1-ansuelsmth@gmail.com>

This small series add the initial support for the Airoha AN8855 Switch.

It's a 5 port Gigabit Switch with SGMII/HSGMII upstream port.

This is starting to get in the wild and there are already some router
having this switch chip.

It's conceptually similar to mediatek switch but register and bits
are different. And there is that massive Hell that is the PCS
configuration.
Saddly for that part we have absolutely NO documentation currently.

There is this special thing where PHY needs to be calibrated with values
from the switch efuse. (the thing have a whole cpu timer and MCU)

>From v8 Driver is now evaluated with Kernel selftest scripts for DSA:

Output local_termination.sh
TEST: lan2: Unicast IPv4 to primary MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to macvlan MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address                     [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address, promisc            [ OK ]
TEST: lan2: Unicast IPv4 to unknown MAC address, allmulti           [ OK ]
TEST: lan2: Multicast IPv4 to joined group                          [ OK ]
TEST: lan2: Multicast IPv4 to unknown group                         [XFAIL]
        reception succeeded, but should have failed
TEST: lan2: Multicast IPv4 to unknown group, promisc                [ OK ]
TEST: lan2: Multicast IPv4 to unknown group, allmulti               [ OK ]
TEST: lan2: Multicast IPv6 to joined group                          [ OK ]
TEST: lan2: Multicast IPv6 to unknown group                         [XFAIL]
        reception succeeded, but should have failed
TEST: lan2: Multicast IPv6 to unknown group, promisc                [ OK ]
TEST: lan2: Multicast IPv6 to unknown group, allmulti               [ OK ]
TEST: lan2: 1588v2 over L2 transport, Sync                          [ OK ]
TEST: lan2: 1588v2 over L2 transport, Follow-Up                     [ OK ]
TEST: lan2: 1588v2 over L2 transport, Peer Delay Request            [ OK ]
TEST: lan2: 1588v2 over IPv4, Sync                                  [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv4, Follow-Up                             [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv4, Peer Delay Request                    [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Sync                                  [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Follow-Up                             [FAIL]
        reception failed
TEST: lan2: 1588v2 over IPv6, Peer Delay Request                    [FAIL]
        reception failed
TEST: vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to joined group       [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to joined group       [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to joined group       [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to joined group       [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group      [XFAIL]
        reception succeeded, but should have failed
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN upper: Unicast IPv4 to primary MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to macvlan MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address               [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address, promisc      [ OK ]
TEST: VLAN upper: Unicast IPv4 to unknown MAC address, allmulti     [ OK ]
TEST: VLAN upper: Multicast IPv4 to joined group                    [ OK ]
TEST: VLAN upper: Multicast IPv4 to unknown group                   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN upper: Multicast IPv4 to unknown group, promisc          [ OK ]
TEST: VLAN upper: Multicast IPv4 to unknown group, allmulti         [ OK ]
TEST: VLAN upper: Multicast IPv6 to joined group                    [ OK ]
TEST: VLAN upper: Multicast IPv6 to unknown group                   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN upper: Multicast IPv6 to unknown group, promisc          [ OK ]
TEST: VLAN upper: Multicast IPv6 to unknown group, allmulti         [ OK ]
TEST: VLAN upper: 1588v2 over L2 transport, Sync                    [ OK ]
TEST: VLAN upper: 1588v2 over L2 transport, Follow-Up               [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over L2 transport, Peer Delay Request      [ OK ]
TEST: VLAN upper: 1588v2 over IPv4, Sync                            [FAIL]
        reception failed
;TEST: VLAN upper: 1588v2 over IPv4, Follow-Up                       [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv4, Peer Delay Request              [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Sync                            [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Follow-Up                       [FAIL]
        reception failed
TEST: VLAN upper: 1588v2 over IPv6, Peer Delay Request              [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Sync   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Follow-Up   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Peer Delay Request   [ OK ]
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address   [FAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, allmulti   [FAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Sync   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Follow-Up   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Peer Delay Request   [ OK ]
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Sync   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
        reception failed
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to joined group   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group   [XFAIL]
        reception succeeded, but should have failed
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc   [ OK ]
TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti   [ OK ]

Output bridge_vlan_unaware.sh
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: FDB learning                                                  [ OK ]
TEST: Unknown unicast flood                                         [ OK ]
TEST: Unregistered multicast flood                                  [ OK ]

Output bridge_vlan_aware.sh
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: FDB learning                                                  [ OK ]
TEST: Unknown unicast flood                                         [ OK ]
TEST: Unregistered multicast flood                                  [ OK ]
INFO: Add and delete a VLAN on bridge port lan2
TEST: ping                                                          [ OK ]
TEST: ping6                                                         [ OK ]
TEST: Externally learned FDB entry - ageing & roaming               [ OK ]
TEST: FDB entry in PVID for VLAN-tagged with other TPID             [FAIL]
        FDB entry was not learned when it should
TEST: Reception of VLAN with other TPID as untagged                 [FAIL]
        Packet was not forwarded when it should
TEST: Reception of VLAN with other TPID as untagged (no PVID)       [FAIL]
        Packet was forwarded when should not

[ For Vladimir, I still have to implement fdb_isolation but posting to
start the ball rolling for the multiple subsystem this patch affect
and for the dubious DT schema ]

Changes v11:
- Address reviews from Christophe (spell mistake + dev_err_probe)
- Fix kconfig dependency for MFD driver (depends on MDIO_DEVICE instead of MDIO)
  (indirectly fix link error for mdio APIs)
- Fix copy-paste error for MFD driver of_table
- Fix compilation error for PHY (move NVMEM to .config)
- Drop unneeded NVMEM node from MDIO example schema (from Andrew)
- Adapt MFD example schema to MDIO reg property restrictions
Changes v10:
- Entire rework to MFD + split to MDIO, EFUSE, SWITCH separate drivers
- Drop EEE OPs (while Russell finish RFC for EEE changes)
- Use new pcs_inpand OPs
- Drop AN restart function and move to pcs_config
- Enable assisted_learning and disable CPU learn (preparation for fdb_isolation)
- Move EFUSE read in Internal PHY driver to .config to handle EPROBE_DEFER
  (needed now that NVMEM driver is register externally instead of internally to switch
   node)
Changes v9:
- Error out on using 5G speed as currently not supported
- Add missing MAC_2500FD in phylink mac_capabilities
- Add comment and improve if condition for an8855_phylink_mac_config
Changes v8:
- Add port Fast Age support
- Add support for Port Isolation
- Use correct register for Learning Disable
- Add support for Ageing Time OP
- Set default PVID to 0 by default
- Add mdb OPs
- Add port change MTU
- Fix support for Upper VLAN
Changes v7:
- Fix devm_dsa_register_switch wrong export symbol
Changes v6:
- Drop standard MIB and handle with ethtool OPs (as requested by Jakub)
- Cosmetic: use bool instead of 0 or 1
Changes v5:
- Add devm_dsa_register_switch() patch
- Add Reviewed-by tag for DT patch
Changes v4:
- Set regmap readable_table static (mute compilation warning)
- Add support for port_bridge flags (LEARNING, FLOOD)
- Reset fdb struct in fdb_dump
- Drop support_asym_pause in port_enable
- Add define for get_phy_flags
- Fix bug for port not inititially part of a bridge
  (in an8855_setup the port matrix was always cleared but
   the CPU port was never initially added)
- Disable learning and flood for user port by default
- Set CPU port to flood and learning by default
- Correctly AND force duplex and flow control in an8855_phylink_mac_link_up
- Drop RGMII from pcs_config
- Check ret in "Disable AN if not in autoneg"
- Use devm_mutex_init
- Fix typo for AN8855_PORT_CHECK_MODE
- Better define AN8855_STP_LISTENING = AN8855_STP_BLOCKING
- Fix typo in AN8855_PHY_EN_DOWN_SHIFT
- Use paged helper for PHY
- Skip calibration in config_init if priv not defined
Changes v3:
- Out of RFC
- Switch PHY code to select_page API
- Better describe masks and bits in PHY driver for ADC register
- Drop raw values and use define for mii read/write
- Switch to absolute PHY address
- Replace raw values with mask and bits for pcs_config
- Fix typo for ext-surge property name
- Drop support for relocating Switch base PHY address on the bus
Changes v2:
- Drop mutex guard patch
- Drop guard usage in DSA driver
- Use __mdiobus_write/read
- Check return condition and return errors for mii read/write
- Fix wrong logic for EEE
- Fix link_down (don't force link down with autoneg)
- Fix forcing speed on sgmii autoneg
- Better document link speed for sgmii reg
- Use standard define for sgmii reg
- Imlement nvmem support to expose switch EFUSE
- Rework PHY calibration with the use of NVMEM producer/consumer
- Update DT with new NVMEM property
- Move aneg validation for 2500-basex in pcs_config
- Move r50Ohm table and function to PHY driver

Christian Marangi (9):
  dt-bindings: nvmem: Document support for Airoha AN8855 Switch EFUSE
  dt-bindings: net: Document support for Airoha AN8855 Switch Virtual
    MDIO
  dt-bindings: net: dsa: Document support for Airoha AN8855 DSA Switch
  dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC
  mfd: an8855: Add support for Airoha AN8855 Switch MFD
  net: mdio: Add Airoha AN8855 Switch MDIO Passtrough
  nvmem: an8855: Add support for Airoha AN8855 Switch EFUSE
  net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
  net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY

 .../bindings/mfd/airoha,an8855-mfd.yaml       |  178 ++
 .../bindings/net/airoha,an8855-mdio.yaml      |   56 +
 .../net/dsa/airoha,an8855-switch.yaml         |  105 +
 .../bindings/nvmem/airoha,an8855-efuse.yaml   |  123 +
 MAINTAINERS                                   |   17 +
 drivers/mfd/Kconfig                           |   10 +
 drivers/mfd/Makefile                          |    1 +
 drivers/mfd/airoha-an8855.c                   |  278 ++
 drivers/net/dsa/Kconfig                       |    9 +
 drivers/net/dsa/Makefile                      |    1 +
 drivers/net/dsa/an8855.c                      | 2310 +++++++++++++++++
 drivers/net/dsa/an8855.h                      |  783 ++++++
 drivers/net/mdio/Kconfig                      |    9 +
 drivers/net/mdio/Makefile                     |    1 +
 drivers/net/mdio/mdio-an8855.c                |  113 +
 drivers/net/phy/Kconfig                       |    5 +
 drivers/net/phy/Makefile                      |    1 +
 drivers/net/phy/air_an8855.c                  |  267 ++
 drivers/nvmem/Kconfig                         |   11 +
 drivers/nvmem/Makefile                        |    2 +
 drivers/nvmem/an8855-efuse.c                  |   63 +
 include/linux/mfd/airoha-an8855-mfd.h         |   41 +
 22 files changed, 4384 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
 create mode 100644 Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 create mode 100644 Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 create mode 100644 drivers/mfd/airoha-an8855.c
 create mode 100644 drivers/net/dsa/an8855.c
 create mode 100644 drivers/net/dsa/an8855.h
 create mode 100644 drivers/net/mdio/mdio-an8855.c
 create mode 100644 drivers/net/phy/air_an8855.c
 create mode 100644 drivers/nvmem/an8855-efuse.c
 create mode 100644 include/linux/mfd/airoha-an8855-mfd.h

-- 
2.45.2



From ansuelsmth at gmail.com  Mon Dec  9 05:44:18 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:18 +0100
Subject: [net-next PATCH v11 1/9] dt-bindings: nvmem: Document support for Airoha AN8855 Switch EFUSE
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241209134459.27110-2-ansuelsmth@gmail.com>

Document support for Airoha AN8855 Switch EFUSE used to calibrate
internal PHYs and store additional configuration info.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 .../bindings/nvmem/airoha,an8855-efuse.yaml   | 123 ++++++++++++++++++
 MAINTAINERS                                   |   8 ++
 2 files changed, 131 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml b/Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
new file mode 100644
index 000000000000..9802d9ea2176
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
@@ -0,0 +1,123 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/airoha,an8855-efuse.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 Switch EFUSE
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description:
+  Airoha AN8855 EFUSE used to calibrate internal PHYs and store additional
+  configuration info.
+
+$ref: nvmem.yaml#
+
+properties:
+  compatible:
+    const: airoha,an8855-efuse
+
+  '#nvmem-cell-cells':
+    const: 0
+
+required:
+  - compatible
+  - '#nvmem-cell-cells'
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    efuse {
+        compatible = "airoha,an8855-efuse";
+
+        #nvmem-cell-cells = <0>;
+
+        nvmem-layout {
+            compatible = "fixed-layout";
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            shift_sel_port0_tx_a: shift-sel-port0-tx-a at c {
+               reg = <0xc 0x4>;
+            };
+
+            shift_sel_port0_tx_b: shift-sel-port0-tx-b at 10 {
+                reg = <0x10 0x4>;
+            };
+
+            shift_sel_port0_tx_c: shift-sel-port0-tx-c at 14 {
+                reg = <0x14 0x4>;
+            };
+
+            shift_sel_port0_tx_d: shift-sel-port0-tx-d at 18 {
+               reg = <0x18 0x4>;
+            };
+
+            shift_sel_port1_tx_a: shift-sel-port1-tx-a at 1c {
+               reg = <0x1c 0x4>;
+            };
+
+            shift_sel_port1_tx_b: shift-sel-port1-tx-b at 20 {
+               reg = <0x20 0x4>;
+            };
+
+            shift_sel_port1_tx_c: shift-sel-port1-tx-c at 24 {
+               reg = <0x24 0x4>;
+            };
+
+            shift_sel_port1_tx_d: shift-sel-port1-tx-d at 28 {
+               reg = <0x28 0x4>;
+            };
+
+            shift_sel_port2_tx_a: shift-sel-port2-tx-a at 2c {
+                reg = <0x2c 0x4>;
+            };
+
+            shift_sel_port2_tx_b: shift-sel-port2-tx-b at 30 {
+                reg = <0x30 0x4>;
+            };
+
+            shift_sel_port2_tx_c: shift-sel-port2-tx-c at 34 {
+                reg = <0x34 0x4>;
+            };
+
+            shift_sel_port2_tx_d: shift-sel-port2-tx-d at 38 {
+                reg = <0x38 0x4>;
+            };
+
+            shift_sel_port3_tx_a: shift-sel-port3-tx-a at 4c {
+                reg = <0x4c 0x4>;
+            };
+
+            shift_sel_port3_tx_b: shift-sel-port3-tx-b at 50 {
+                reg = <0x50 0x4>;
+            };
+
+            shift_sel_port3_tx_c: shift-sel-port3-tx-c at 54 {
+               reg = <0x54 0x4>;
+            };
+
+            shift_sel_port3_tx_d: shift-sel-port3-tx-d at 58 {
+               reg = <0x58 0x4>;
+            };
+
+            shift_sel_port4_tx_a: shift-sel-port4-tx-a at 5c {
+                reg = <0x5c 0x4>;
+            };
+
+            shift_sel_port4_tx_b: shift-sel-port4-tx-b at 60 {
+                reg = <0x60 0x4>;
+            };
+
+            shift_sel_port4_tx_c: shift-sel-port4-tx-c at 64 {
+                reg = <0x64 0x4>;
+            };
+
+            shift_sel_port4_tx_d: shift-sel-port4-tx-d at 68 {
+                reg = <0x68 0x4>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 79756f2100e0..53ef66eef473 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -711,6 +711,14 @@ S:	Supported
 F:	fs/aio.c
 F:	include/linux/*aio*.h
 
+AIROHA DSA DRIVER
+M:	Christian Marangi <ansuelsmth at gmail.com>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
+L:	netdev at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
+
 AIROHA ETHERNET DRIVER
 M:	Lorenzo Bianconi <lorenzo at kernel.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
-- 
2.45.2



From ansuelsmth at gmail.com  Mon Dec  9 05:44:19 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:19 +0100
Subject: [net-next PATCH v11 2/9] dt-bindings: net: Document support for Airoha AN8855 Switch Virtual MDIO
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241209134459.27110-3-ansuelsmth@gmail.com>

Document support for Airoha AN8855 Virtual MDIO Passtrough. This is needed
as AN8855 require special handling as the same address on the MDIO bus is
shared for both Switch and PHY and special handling for the page
configuration is needed to switch accessing to Switch address space
or PHY.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 .../bindings/net/airoha,an8855-mdio.yaml      | 56 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml

diff --git a/Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml b/Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
new file mode 100644
index 000000000000..3078277bf478
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/airoha,an8855-mdio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 MDIO Passtrough
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description:
+  Airoha AN8855 Virtual MDIO Passtrough. This is needed as AN8855
+  require special handling as the same address on the MDIO bus is
+  shared for both Switch and PHY and special handling for the page
+  configuration is needed to switch accessing to Switch address space
+  or PHY.
+
+$ref: /schemas/net/mdio.yaml#
+
+properties:
+  compatible:
+    const: airoha,an8855-mdio
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    mdio {
+        compatible = "airoha,an8855-mdio";
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        internal_phy1: phy at 1 {
+            reg = <1>;
+        };
+
+        internal_phy2: phy at 2 {
+            reg = <2>;
+        };
+
+        internal_phy3: phy at 3 {
+            reg = <3>;
+        };
+
+        internal_phy4: phy at 4 {
+            reg = <4>;
+        };
+
+        internal_phy5: phy at 5 {
+            reg = <5>;
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 53ef66eef473..e3569fe5f3de 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -717,6 +717,7 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
 L:	netdev at vger.kernel.org
 S:	Maintained
+F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 
 AIROHA ETHERNET DRIVER
-- 
2.45.2



From ansuelsmth at gmail.com  Mon Dec  9 05:44:20 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Mon,  9 Dec 2024 14:44:20 +0100
Subject: [net-next PATCH v11 3/9] dt-bindings: net: dsa: Document support for Airoha AN8855 DSA Switch
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241209134459.27110-4-ansuelsmth@gmail.com>

Document support for Airoha AN8855 5-port Gigabit Switch.

It does expose the 5 Internal PHYs on the MDIO bus and each port
can access the Switch register space by configurting the PHY page.

Each internal PHY might require calibration with the fused EFUSE on
the switch exposed by the Airoha AN8855 SoC NVMEM.

Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 .../net/dsa/airoha,an8855-switch.yaml         | 105 ++++++++++++++++++
 MAINTAINERS                                   |   1 +
 2 files changed, 106 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml

diff --git a/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml b/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
new file mode 100644
index 000000000000..63bcbebd6a29
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/dsa/airoha,an8855-switch.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 Gigabit Switch
+
+maintainers:
+  - Christian Marangi <ansuelsmth at gmail.com>
+
+description: >
+  Airoha AN8855 is a 5-port Gigabit Switch.
+
+  It does expose the 5 Internal PHYs on the MDIO bus and each port
+  can access the Switch register space by configurting the PHY page.
+
+  Each internal PHY might require calibration with the fused EFUSE on
+  the switch exposed by the Airoha AN8855 SoC NVMEM.
+
+$ref: dsa.yaml#
+
+properties:
+  compatible:
+    const: airoha,an8855-switch
+
+  reset-gpios:
+    description:
+      GPIO to be used to reset the whole device
+    maxItems: 1
+
+  airoha,ext-surge:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Calibrate the internal PHY with the calibration values stored in EFUSE
+      for the r50Ohm values.
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    ethernet-switch {
+        compatible = "airoha,an8855-switch";
+        reset-gpios = <&pio 39 0>;
+
+        airoha,ext-surge;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+                label = "lan1";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy1>;
+            };
+
+            port at 1 {
+                reg = <1>;
+                label = "lan2";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy2>;
+            };
+
+            port at 2 {
+                reg = <2>;
+                label = "lan3";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy3>;
+            };
+
+            port at 3 {
+                reg = <3>;
+                label = "lan4";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy4>;
+            };
+
+            port at 4 {
+                reg = <4>;
+                label = "wan";
+                phy-mode = "internal";
+                phy-handle = <&internal_phy5>;
+            };
+
+            port at 5 {
+                reg = <5>;
+                label = "cpu";
+                ethernet = <&gmac0>;
+                phy-mode = "2500base-x";
+
+                fixed-link {
+                    speed = <2500>;
+                    full-duplex;
+                    pause;
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index e3569fe5f3de..fd37e829fab5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -718,6 +718,7 @@ L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
 L:	netdev at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
+F:	Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
 F:	Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
 
 AIROHA ETHERNET DRIVER
-- 
2.45.2



From o451686892 at gmail.com  Mon Dec  9 06:04:08 2024
From: o451686892 at gmail.com (Weizhao Ouyang)
Date: Mon, 9 Dec 2024 22:04:08 +0800
Subject: [PATCH] kselftest/arm64: abi: fix SVCR detection
In-Reply-To: <678a223f-c4c7-4752-84b0-609acaa33ad6@sirena.org.uk>
References: <20241209105237.10498-1-o451686892@gmail.com> <3279e669-1ee2-4792-9e10-8b40928de6b4@sirena.org.uk>
 <CAHk0Hov5k37=MtTBLWTj+Dwm4EXE0xGJS1Uc8xgyLtJxusqsww@mail.gmail.com>
 <c05f6ad8-2dc1-4ddb-b9c1-b2cddfe78819@sirena.org.uk> <CAHk0HotQ-=s+-FHh8pAOg10ivcRwqChG735qgDvuQd=4B1QQNA@mail.gmail.com>
 <678a223f-c4c7-4752-84b0-609acaa33ad6@sirena.org.uk>
Message-ID: <CAHk0Hour4i92j70+C-x7BNGFoLhDEYW-1prU=R6rAX9T9T7auA@mail.gmail.com>

On Mon, Dec 9, 2024 at 9:51?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Mon, Dec 09, 2024 at 09:26:01PM +0800, Weizhao Ouyang wrote:
>
> > > If we don't have SME we should be skipping over all the SME code and
> > > never even looking at the value of SVCR.  Looking at the current version
> > > of the code it does that, it branches to check_sve_in if SME is not
> > > enabled.
>
> > Yes we should skip it, this is just a minor tweak based on the
> > current implementation, after all, we manually passed its value by
> > svcr_in.
>
> It's a fairly trivial tweak to make...  in any case, it looks like we
> also need the same change in the save path.

Yeah. I have encountered this issue with both QEMU and FVP. I can
help to add a check_sve_in similar to the fp testcase for the abi
testcase.

BR,
Weizhao

>
> > Which latest code version are you referring to? I think check_sve_in
> > is in fp testcase, not in the abi testcase. (checked the -next tree)
>
> Ah, yes sorry.


From broonie at kernel.org  Mon Dec  9 06:05:51 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 9 Dec 2024 14:05:51 +0000
Subject: [PATCH 1/4] arm64/sysreg: Allow a 'Mapping' descriptor for
 system registers
In-Reply-To: <20241207190740.2607673-2-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
 <20241207190740.2607673-2-maz@kernel.org>
Message-ID: <06726aa6-3be0-434c-9870-3d40a5ff24f9@sirena.org.uk>

On Sat, Dec 07, 2024 at 07:07:37PM +0000, Marc Zyngier wrote:
> *EL02 and *_EL12 system registers are actually only accessors for
> EL0 and EL1 registers accessed from EL2 when HCR_EL2.E2H==1. They
> do not have fields of their own.
> 
> To that effect, introduce a 'Mapping' entry, describing which
> system register an _EL12 register maps to.
> 
> Implementation wise, this is handled the same was as Fields,
> which ls only a comment.

With Mark Rutland's suggested clarifications

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/20241209/010505b1/attachment.sig>

From anshuman.khandual at arm.com  Mon Dec  9 06:13:32 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 9 Dec 2024 19:43:32 +0530
Subject: [PATCH] mm/execmem: Make ARCH_WANTS_EXECMEM_LATE depend on
 EXECMEM
In-Reply-To: <202412092048.tTzJ5szH-lkp@intel.com>
References: <20241209031251.515903-1-anshuman.khandual@arm.com>
 <202412092048.tTzJ5szH-lkp@intel.com>
Message-ID: <f492ac51-9dad-4b18-8cd4-81dc236b3162@arm.com>



On 12/9/24 18:06, kernel test robot wrote:
> Hi Anshuman,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on akpm-mm/mm-everything]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Anshuman-Khandual/mm-execmem-Make-ARCH_WANTS_EXECMEM_LATE-depend-on-EXECMEM/20241209-111533
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
> patch link:    https://lore.kernel.org/r/20241209031251.515903-1-anshuman.khandual%40arm.com
> patch subject: [PATCH] mm/execmem: Make ARCH_WANTS_EXECMEM_LATE depend on EXECMEM
> config: arm64-kismet-CONFIG_ARCH_WANTS_EXECMEM_LATE-CONFIG_ARM64-0-0 (https://download.01.org/0day-ci/archive/20241209/202412092048.tTzJ5szH-lkp at intel.com/config)
> reproduce: (https://download.01.org/0day-ci/archive/20241209/202412092048.tTzJ5szH-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/202412092048.tTzJ5szH-lkp at intel.com/
> 
> kismet warnings: (new ones prefixed by >>)
>>> kismet: WARNING: unmet direct dependencies detected for ARCH_WANTS_EXECMEM_LATE when selected by ARM64
>    WARNING: unmet direct dependencies detected for ARCH_WANTS_EXECMEM_LATE
>      Depends on [n]: EXECMEM [=n]
>      Selected by [y]:
>      - ARM64 [=y]

Although above mentioned config here has CONFIG_ARCH_WANTS_EXECMEM_LATE=y
and CONFIG_EXECMEM=n (actually absent), could that really happen though ?

Tried making CONFIG_EXECMEM=n (rather deselecting) but that did now allow
setting CONFIG_EXECMEM=n, it always remained set. Reverting this patch i.e
the current behaviour is also the same (CONFIG_EXECMEM always remains set).

select ARCH_WANTS_EXECMEM_LATE if EXECMEM

Above statement seems to be selecting EXECMEM as well but the intent seems
to be a dependency check instead! OR arch selection for a config brings in
all its dependencies as well.

If the selection is always, should this change be like the following ?

config ARCH_WANTS_EXECMEM_LATE
 	bool
	selects EXECMEM

Although a similar config ARCH_WANTS_EXECMEM_ROX is dependent on MMU and
!HIGHMEM at the generic memory level.


From tudor.ambarus at linaro.org  Mon Dec  9 06:19:13 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 9 Dec 2024 14:19:13 +0000
Subject: [PATCH v3 1/3] dt-bindings: mailbox: add bindings for
 samsung,exynos
In-Reply-To: <58d62506-de89-40e4-a3c2-bd27da515a45@kernel.org>
References: <20241205174137.190545-1-tudor.ambarus@linaro.org>
 <20241205174137.190545-2-tudor.ambarus@linaro.org>
 <2lkowhldq5i4otniijfw7cb3jm6ttatwji3npw5w7c5fyevnn5@ynojupmdyqy4>
 <9886429b-1bf3-4dc3-b0d4-294a98e44ff2@linaro.org>
 <58d62506-de89-40e4-a3c2-bd27da515a45@kernel.org>
Message-ID: <38e6687e-c2ee-414b-bba5-483150ba7baa@linaro.org>



On 12/9/24 8:33 AM, Krzysztof Kozlowski wrote:
>> I'm thinking of using the same driver for both cases, and differentiate
>> between the two by compatible and `of_device_id.data`. Thus I propose to
>> have a "google,gs101-acpm-mbox" compatible for the ACPM SRAM case and in
>> the future we may add a "google,gs101-mbox" compatible for the messages
>> passed via the controller's data register case.
> Good that you pointed it out, I was indeed wondering why this is
> "acpm-mbox", not "mbox in compatible.
> 
> This needs to be fixed - you cannot have two compatibles for the same
> device.

Will fix. I followed arm,mhu, which differentiates the transfer mode,
data or doorbell, via compatible.

For the fix I'll use "#mbox-cells" as <&phandle type channel>, where
type specifies doorbel or data type. Clients will use:
	mboxes = <&ap2apm_mailbox DOORBELL 2>;
or
	mboxes = <&ap2apm_mailbox DATA 3>;

arm,mhu3 and fsl,mu pass the transfer mode in a similar way.


>> Given this, I shall use the more generic name for the bindings, thus
>> maybe "google,gs101-mbox.yaml"? But then exynos850 has the same
>> controller, shouldn't we just use "samsung,exynos.yaml"?
> If exynos850 has the same controller, then add it to the binding. Anyway
> then use samsung,exynos850-mbox, because samsung,exynos is way too generic.

Looks the same, yes, it differs by the number of how many data registers
each has. But I'll stick to "google,gs101-mbox.yaml", as I can't test
exynos850 and I assume we can rename the file when we'll need it.


From jgg at ziepe.ca  Mon Dec  9 06:20:13 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Mon, 9 Dec 2024 10:20:13 -0400
Subject: [PATCH v2] iommu/tegra241-cmdqv: do not use smp_processor_id in
 preemptible context
In-Reply-To: <Z1L1mja3nXzsJ0Pk@uudg.org>
References: <Z1L1mja3nXzsJ0Pk@uudg.org>
Message-ID: <20241209142013.GC1888283@ziepe.ca>

On Fri, Dec 06, 2024 at 10:01:14AM -0300, Luis Claudio R. Goncalves wrote:
> During boot some of the calls to tegra241_cmdqv_get_cmdq() will happen
> in preemptible context. As this function calls smp_processor_id(), if
> CONFIG_DEBUG_PREEMPT is enabled, these calls will trigger a series of
> "BUG: using smp_processor_id() in preemptible" backtraces.
> 
> As tegra241_cmdqv_get_cmdq() only calls smp_processor_id() to use the
> CPU number as a factor to balance out traffic on cmdq usage, it is safe
> to use raw_smp_processor_id() here.
> 
> v2: Sebastian helped identify that the problem was not exclusive to kernels
>     with PREEMPT_RT enabled. The delta between v1 and v2 is the description.
> 
> Signed-off-by: Luis Claudio R. Goncalves <lgoncalv at redhat.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Makes sense

Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>

Jason


From broonie at kernel.org  Mon Dec  9 06:22:24 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 9 Dec 2024 14:22:24 +0000
Subject: [PATCH 3/4] arm64/sysreg: Convert *_EL12 accessors to Mapping
In-Reply-To: <20241207190740.2607673-4-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
 <20241207190740.2607673-4-maz@kernel.org>
Message-ID: <49a35d0c-7ed6-4b87-bbc2-02a35b5a9604@sirena.org.uk>

On Sat, Dec 07, 2024 at 07:07:39PM +0000, Marc Zyngier wrote:
> Perform a bulk convert of the remaining EL12 accessors to use the
> Mapping qualifier, which meakes things a bit clearer.

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/20241209/8e226070/attachment.sig>

From chase.conklin at arm.com  Mon Dec  9 06:24:29 2024
From: chase.conklin at arm.com (Chase Conklin)
Date: Mon,  9 Dec 2024 08:24:29 -0600
Subject: [PATCH 00/11] KVM: arm64: Add NV timer support
In-Reply-To: <20241202172134.384923-1-maz@kernel.org>
References: <20241202172134.384923-1-maz@kernel.org>
Message-ID: <20241209142429.882-1-chase.conklin@arm.com>

Hi Marc,

On Mon, 2 Dec 2024 17:21:23 +0000, Marc Zyngier <maz at kernel.org> wrote: 
> Here's another batch of NV-related patches, this time bringing in most
> of the timer support for EL2 as well as nested guests.
> 
> The code is pretty convoluted for a bunch of reasons:
> 
> - FEAT_NV2 breaks the timer semantics by redirecting HW controls to
>   memory, meaning that a guest could setup a timer and never see it
>   firing until the next exit
> 
> - We go try hard to reflect the timer state in memory, but that's not
>   great.
> 
> - With FEAT_ECV, we can finally correctly emulate the virtual timer,
>   but this emulation is pretty costly
> 
> - As a way to make things suck less, we handle timer reads as early as
>   possible, and only defer writes to the normal trap handling
> 
> - Finally, some implementations are badly broken, and require some
>   hand-holding, irrespective of NV support. So we try and reuse the NV
>   infrastructure to make them usable. This could be further optimised,
>   but I'm running out of patience for this sort of HW.
> 
> What this is not implementing is support for CNTPOFF_EL2. It appears
> that the architecture doesn't let you correctly emulate it, so I guess
> this will be trap/emulate for the foreseeable future.
> 
> This series is on top of v6.13-rc1, and has been tested on my usual M2
> setup, but also on a Snapdragon X1 Elite devkit. I would like to thank
> Qualcomm for the free hardware with no strings (nor support) attached!
> 
> If you are feeling brave, you can run the whole thing from [1].
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/nv-next
>

I was feeling brave, and I think I see an issue in the cpufeature change
in the kvm-arm64/nv-e2h-select branch that's a part of
kvm-arm64/nv-next. In d75a4820a897 ("arm64: cpufeature: Handle NV_frac as a synonym of NV2"),
I don't see NV_frac being added to the FTR bits. I believe that means it
will get sanitized out and consequently not seen by the NV feature
detection code. Does that commit also need:

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 9fa8bd77ae0..f97459e160b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -480,6 +480,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr3[] = {

 static const struct arm64_ftr_bits ftr_id_aa64mmfr4[] = {
        S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR4_EL1_E2H0_SHIFT, 4, 0),
+       S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR4_EL1_NV_frac_SHIFT, 4, 0),
        ARM64_FTR_END,
 };

Thanks,
Chase


From mkl at pengutronix.de  Mon Dec  9 06:30:54 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Mon, 9 Dec 2024 15:30:54 +0100
Subject: [PATCH 0/6] ARM: dts: stm32: lxa-tac: fix gen{1,2} boards and
 add gen3 board
In-Reply-To: <20241119-lxa-tac-gen3-v1-0-e0ab0a369372@pengutronix.de>
References: <20241119-lxa-tac-gen3-v1-0-e0ab0a369372@pengutronix.de>
Message-ID: <20241209-magenta-boobook-of-respect-14ec68-mkl@pengutronix.de>

Hello Alexandre,

On 19.11.2024 12:34:57, Marc Kleine-Budde wrote:
> Hello,
> 
> this series fixes some problems found in the lxa-tac generation 1 and
> 2 boards and add support for the generation 3 board. It's based on an
> STM32MP153c, while the generation 1 and 2 are based on the
> STM32MP157c.
> 
> regards,
> Marc
> 
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
> Leonard G?hrs (6):
>       ARM: dts: stm32: lxa-tac: disable the real time clock
>       ARM: dts: stm32: lxa-tac: extend the alias table
>       ARM: dts: stm32: lxa-tac: adjust USB gadget fifo sizes for multi function
>       dt-bindings: arm: stm32: add compatible strings for Linux Automation LXA TAC gen 3
>       ARM: dts: stm32: lxa-tac: move adc and gpio{e,g} to gen{1,2} boards
>       ARM: dts: stm32: lxa-tac: Add support for generation 3 devices
> 
>  .../devicetree/bindings/arm/stm32/stm32.yaml       |   7 +
>  arch/arm/boot/dts/st/Makefile                      |   1 +
>  arch/arm/boot/dts/st/stm32mp153c-lxa-tac-gen3.dts  | 267 +++++++++++++++++++++
>  arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen1.dts  |  84 +++++++
>  arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen2.dts  |  84 +++++++
>  arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi      | 100 +-------
>  6 files changed, 455 insertions(+), 88 deletions(-)

since the merge window is open, can you merge this series please.

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/20241209/255d46b5/attachment.sig>

From krzk at kernel.org  Mon Dec  9 06:32:31 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 9 Dec 2024 15:32:31 +0100
Subject: [PATCH v3 1/3] dt-bindings: mailbox: add bindings for
 samsung,exynos
In-Reply-To: <38e6687e-c2ee-414b-bba5-483150ba7baa@linaro.org>
References: <20241205174137.190545-1-tudor.ambarus@linaro.org>
 <20241205174137.190545-2-tudor.ambarus@linaro.org>
 <2lkowhldq5i4otniijfw7cb3jm6ttatwji3npw5w7c5fyevnn5@ynojupmdyqy4>
 <9886429b-1bf3-4dc3-b0d4-294a98e44ff2@linaro.org>
 <58d62506-de89-40e4-a3c2-bd27da515a45@kernel.org>
 <38e6687e-c2ee-414b-bba5-483150ba7baa@linaro.org>
Message-ID: <8698ccfc-9c16-4b4e-b526-66efd39c0134@kernel.org>

On 09/12/2024 15:19, Tudor Ambarus wrote:
> 
> 
> On 12/9/24 8:33 AM, Krzysztof Kozlowski wrote:
>>> I'm thinking of using the same driver for both cases, and differentiate
>>> between the two by compatible and `of_device_id.data`. Thus I propose to
>>> have a "google,gs101-acpm-mbox" compatible for the ACPM SRAM case and in
>>> the future we may add a "google,gs101-mbox" compatible for the messages
>>> passed via the controller's data register case.
>> Good that you pointed it out, I was indeed wondering why this is
>> "acpm-mbox", not "mbox in compatible.
>>
>> This needs to be fixed - you cannot have two compatibles for the same
>> device.
> 
> Will fix. I followed arm,mhu, which differentiates the transfer mode,
> data or doorbell, via compatible.

There was a reasoning behind: different firmware.

Best regards,
Krzysztof


From l.stach at pengutronix.de  Mon Dec  9 06:37:01 2024
From: l.stach at pengutronix.de (Lucas Stach)
Date: Mon, 09 Dec 2024 15:37:01 +0100
Subject: [PATCH] serial: imx: Use uart_port_lock_irqsave() instead of
 uart_port_lock()
In-Reply-To: <20241209124732.693834-1-xiaolei.wang@windriver.com>
References: <20241209124732.693834-1-xiaolei.wang@windriver.com>
Message-ID: <ea1ca102ab0ec5068d82935623fd9ffb0b9aade1.camel@pengutronix.de>

Am Montag, dem 09.12.2024 um 20:47 +0800 schrieb Xiaolei Wang:
> When executing 'ehco mem > /sys/power/state', the following
> deadlock occurs. Since there is output during the serial
> port entering the suspend process, the suspend will be
> interrupted, resulting in the nesting of locks. Therefore,
> use uart_port_lock_irqsave instead of uart_port_unlock.
> 
> WARNING: inconsistent lock state
> 6.12.0-rc2-00002-g3c199ed5bd64-dirty #23 Not tainted
> --------------------------------
> inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
> sh/494 [HC0[0]:SC0[0]:HE1:SE1] takes:
> c4db5850 (&port_lock_key){?.-.}-{3:3}, at: imx_uart_enable_wakeup+0x14/0x254
> {IN-HARDIRQ-W} state was registered at:
>   lock_acquire+0x104/0x348
>   _raw_spin_lock+0x48/0x84
>   imx_uart_int+0x14/0x4dc
>   __handle_irq_event_percpu+0xac/0x2fc
>   handle_irq_event_percpu+0xc/0x40
>   handle_irq_event+0x38/0x8c
>   handle_fasteoi_irq+0xb4/0x1b8
>   handle_irq_desc+0x1c/0x2c
>   gic_handle_irq+0x6c/0xa0
>   generic_handle_arch_irq+0x2c/0x64
>   call_with_stack+0x18/0x20
>   __irq_svc+0x9c/0xbc
>   _raw_spin_unlock_irqrestore+0x2c/0x48
>   uart_write+0xd8/0x3a0
>   do_output_char+0x1a8/0x1e4
>   n_tty_write+0x224/0x440
>   file_tty_write.constprop.0+0x124/0x250
>   do_iter_readv_writev+0x100/0x1e0
>   vfs_writev+0xc4/0x448
>   do_writev+0x68/0xf8
>   ret_fast_syscall+0x0/0x1c
> irq event stamp: 31593
> hardirqs last  enabled at (31593): [<c1150e48>] _raw_spin_unlock_irqrestore+0x44/0x48
> hardirqs last disabled at (31592): [<c07f32f0>] clk_enable_lock+0x60/0x120
> softirqs last  enabled at (30334): [<c012d1d4>] handle_softirqs+0x2cc/0x478
> softirqs last disabled at (30325): [<c012d510>] __irq_exit_rcu+0x120/0x15c
> 
> other info that might help us debug this:
>  Possible unsafe locking scenario:
> 
>        CPU0
>        ----
>   lock(&port_lock_key);
>   <Interrupt>
>     lock(&port_lock_key);
> 
> Fixes: 3c199ed5bd64 ("serial: imx: Grab port lock in imx_uart_enable_wakeup()")
> Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>
> ---
>  drivers/tty/serial/imx.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 17f70e4bee43..4470bcb3ef19 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -2691,8 +2691,9 @@ static void imx_uart_save_context(struct imx_port *sport)
>  static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
>  {
>  	u32 ucr3;
> +	unsigned long flags;
>  
> -	uart_port_lock(&sport->port);
> +	uart_port_lock_irqsave(&sport->port, &flags);

This function is only called from process context, so it should be fine
to use uart_port_lock_irq().

Regards,
Lucas

>  
>  	ucr3 = imx_uart_readl(sport, UCR3);
>  	if (on) {
> @@ -2714,7 +2715,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
>  		imx_uart_writel(sport, ucr1, UCR1);
>  	}
>  
> -	uart_port_unlock(&sport->port);
> +	uart_port_unlock_irqrestore(&sport->port, flags);
>  }
>  
>  static int imx_uart_suspend_noirq(struct device *dev)



From andrew at lunn.ch  Mon Dec  9 06:42:52 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 9 Dec 2024 15:42:52 +0100
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and
 MBa62xx carrier board Device Trees
In-Reply-To: <c902a56cf34838f60cee67624bb923e91d74e9e0.camel@ew.tq-group.com>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>
 <c902a56cf34838f60cee67624bb923e91d74e9e0.camel@ew.tq-group.com>
Message-ID: <d25b1447-c28b-4998-b238-92672434dc28@lunn.ch>

On Mon, Dec 09, 2024 at 02:55:31PM +0100, Matthias Schiffer wrote:
> On Mon, 2024-12-09 at 14:24 +0100, Andrew Lunn wrote:
> > 
> > > +&cpsw_port1 {
> > > +	phy-mode = "rgmii-rxid";
> > > +	phy-handle = <&cpsw3g_phy0>;
> > > +};
> > > +
> > > +&cpsw_port2 {
> > > +	phy-mode = "rgmii-rxid";
> > > +	phy-handle = <&cpsw3g_phy3>;
> > > +};
> > 
> > rgmii-rxid is very odd.
> > 
> > > +
> > > +&cpsw3g_mdio {
> > > +	status = "okay";
> > > +	pinctrl-names = "default";
> > > +	pinctrl-0 = <&main_mdio1_pins>;
> > > +
> > > +	cpsw3g_phy0: ethernet-phy at 0 {
> > > +		compatible = "ethernet-phy-ieee802.3-c22";
> > > +		reg = <0x0>;
> > > +		reset-gpios = <&main_gpio1 11 GPIO_ACTIVE_LOW>;
> > > +		reset-assert-us = <1000>;
> > > +		reset-deassert-us = <1000>;
> > > +		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
> > 
> > I guess this is the explanation.
> > 
> > What happens when you use rgmii-id, and don't have this delay here?
> > That would be normal.
> > 
> > 	Andrew
> 
> 
> This is normal for AM62-based boards, see the DTSI of the TI reference
> starterkit for example:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi#n451
> 
> With rgmii-id, both ti,rx-internal-delay and ti,tx-internal-delay should be set.
> As ti,*-internal-delay sets the delay on the PHY side, phy-mode "rgmii" is the
> one that would not use either:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/net/ti,dp83867.yaml#n78
> 
> At the end of the day, does it really matter as long as MAC and PHY agree on the
> used mode? We copied this part of the hardware design from the TI reference
> board, and did our hardware qualification with these settings, so I think it
> makes sense to use the same phy-mode configuration.

What i try to achieve is every board uses the same configuration. The
PHY adds the delays, not the MAC. There are a few exceptions, because
a few cheap PHYs don't support delays, and so the MAC needs to add
them. But in general, any board i review, i always ask that the PHY
does the delay.

Also, don't put too much value in vendor code. Vendors don't care
about Linux has a whole, being uniform across all systems. Many
vendors do the minimum to get their stuff working, sometimes Monkeys
typing Shakespeare, and not a lot more.

I also find a lot of developers don't really understand what phy-mode
and PHY_INTERFACE_MODE_RGMII_* actually mean. phy-mode = 'rgmii' means
the board has extra long clock lines, so the MAC/PHY does not need to
add delays. rgmii-rxid means the board has an extra long rx clock
line, but a normal length tx clock line. Now, i doubt your board is
actually like this?

You want to correctly describe your hardware in DT, which i guess is
"rgmii-id". That means something, either the MAC or the PHY needs to
add delays. PHY_INTERFACE_MODE_RGMII_* is what is passed to the
PHY. To get it to add the 2ns delays, you pass
PHY_INTERFACE_MODE_RGMII_ID, and you should not need any additional
properties in DT, it should default to 2ns. If you need to tune the
delay, 2ns does not work, but you actually need 1.8ns etc, then you
can add additional parameters. But given you have
DP83867_RGMIIDCTL_2_00_NS, i doubt you need this.

	Andrew


From diogo.ivo at siemens.com  Mon Dec  9 06:44:56 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Mon, 9 Dec 2024 14:44:56 +0000
Subject: [PATCH net v3 1/2] net: ti: icssg-prueth: Fix firmware load
 sequence.
In-Reply-To: <64621290-2488-474d-b2ed-597a1f4ac85f@ti.com>
References: <20241205082831.777868-1-m-malladi@ti.com>
 <20241205082831.777868-2-m-malladi@ti.com>
 <a86bc0b1-8bb4-477e-b7e1-13921bf47b53@kernel.org>
 <64621290-2488-474d-b2ed-597a1f4ac85f@ti.com>
Message-ID: <320d8f96-fcff-48e7-9814-6586f7f642ca@siemens.com>

Hi all,

On 12/9/24 10:34 AM, Meghana Malladi wrote:
> 
> 
> On 05/12/24 18:38, Roger Quadros wrote:
>> Hi,
>>
>> On 05/12/2024 10:28, Meghana Malladi wrote:
>>> From: MD Danish Anwar <danishanwar at ti.com>
>>>
>>> Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
>>> and SLICE1. Currently whenever any ICSSG interface comes up we load the
>>> respective firmwares to PRU cores and whenever interface goes down, we
>>> stop the resective cores. Due to this, when SLICE0 goes down while
>>> SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
>>> stopped. This results in clock jump for SLICE1 interface as the timesync
>>> related operations are no longer running.
>>>
>>> As there are interdependencies between SLICE0 and SLICE1 firmwares,
>>> fix this by running both PRU0 and PRU1 firmwares as long as at least 1
>>> ICSSG interface is up. Add new flag in prueth struct to check if all
>>> firmwares are running.
>>>
>>> Use emacs_initialized as reference count to load the firmwares for the
>>> first and last interface up/down. Moving init_emac_mode and 
>>> fw_offload_mode
>>> API outside of icssg_config to icssg_common_start API as they need
>>> to be called only once per firmware boot.
>>>
>>> Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
>>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>>> Signed-off-by: Meghana Malladi <m-malladi at ti.com>
>>> ---
>>>
>>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/ 
>>> net/ethernet/ti/icssg/icssg_prueth.h
>>> index f5c1d473e9f9..b30f2e9a73d8 100644
>>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>>> @@ -257,6 +257,7 @@ struct icssg_firmwares {
>>> ?? * @is_switchmode_supported: indicates platform support for switch 
>>> mode
>>> ?? * @switch_id: ID for mapping switch ports to bridge
>>> ?? * @default_vlan: Default VLAN for host
>>> + * @prus_running: flag to indicate if all pru cores are running
>>> ?? */
>>> ? struct prueth {
>>> ????? struct device *dev;
>>> @@ -298,6 +299,7 @@ struct prueth {
>>> ????? int default_vlan;
>>> ????? /** @vtbl_lock: Lock for vtbl in shared memory */
>>> ????? spinlock_t vtbl_lock;
>>> +??? bool prus_running;
>>
>> I think you don't need fw_running flag anymore. Could you please 
>> remove it
>> from struct prueth_emac?
>>
> 
> This flag is still being used by SR1, for which this patch doesn't 
> apply. So I prefer not touching this flag for the sake of SR1.

Currently for SR1.0 this flag is set but not used anywhere in the code, 
so it can be removed.

Best regards,
Diogo


From igor.belwon at mentallysanemainliners.org  Mon Dec  9 06:45:21 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Mon, 09 Dec 2024 15:45:21 +0100
Subject: [PATCH v4 1/3] dt-bindings: clock: Add Exynos990 SoC CMU bindings
In-Reply-To: <20241209-exynos990-cmu-v4-0-57f07080f9e4@mentallysanemainliners.org>
References: <20241209-exynos990-cmu-v4-0-57f07080f9e4@mentallysanemainliners.org>
Message-ID: <20241209-exynos990-cmu-v4-1-57f07080f9e4@mentallysanemainliners.org>

Add dt-schema documentation for the Exynos990 SoC CMU.

This clock management unit has a topmost block (CMU_TOP)
that generates top clocks for other blocks. Currently the
only other block implemented is CMU_HSI0, which provides
clocks for the USB part of the SoC.

Also, device-tree binding definitions added for these blocks:
- CMU_TOP
- CMU_HSI0

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 .../bindings/clock/samsung,exynos990-clock.yaml    | 121 +++++++++++
 include/dt-bindings/clock/samsung,exynos990.h      | 236 +++++++++++++++++++++
 2 files changed, 357 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9e7944b5f13b1df98ff8c2f409a3120fa43aaaa4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos990-clock.yaml
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos990-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos990 SoC clock controller
+
+maintainers:
+  - Igor Belwon <igor.belwon at mentallysanemainliners.org>
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzk at kernel.org>
+
+description: |
+  Exynos990 clock controller is comprised of several CMU units, generating
+  clocks for different domains. Those CMU units are modeled as separate device
+  tree nodes, and might depend on each other. The root clock in that root tree
+  is an external clock: OSCCLK (26 MHz). This external clock must be defined
+  as a fixed-rate clock in dts.
+
+  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
+  dividers; all other clocks of function blocks (other CMUs) are usually
+  derived from CMU_TOP.
+
+  Each clock is assigned an identifier and client nodes can use this identifier
+  to specify the clock which they consume. All clocks available for usage
+  in clock consumer nodes are defined as preprocessor macros in
+  'include/dt-bindings/clock/samsung,exynos990.h' header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos990-cmu-hsi0
+      - samsung,exynos990-cmu-top
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos990-cmu-hsi0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_HSI0 BUS clock (from CMU_TOP)
+            - description: CMU_HSI0 USB31DRD clock (from CMU_TOP)
+            - description: CMU_HSI0 USBDP_DEBUG clock (from CMU_TOP)
+            - description: CMU_HSI0 DPGTC clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: bus
+            - const: usb31drd
+            - const: usbdp_debug
+            - const: dpgtc
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos990-cmu-top
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+
+        clock-names:
+          items:
+            - const: oscclk
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/samsung,exynos990.h>
+
+    cmu_hsi0: clock-controller at 10a00000 {
+        compatible = "samsung,exynos990-cmu-hsi0";
+        reg = <0x10a00000 0x8000>;
+        #clock-cells = <1>;
+
+        clocks = <&oscclk>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
+                 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
+        clock-names = "oscclk",
+                      "bus",
+                      "usb31drd",
+                      "usbdp_debug",
+                      "dpgtc";
+    };
+
+...
diff --git a/include/dt-bindings/clock/samsung,exynos990.h b/include/dt-bindings/clock/samsung,exynos990.h
new file mode 100644
index 0000000000000000000000000000000000000000..307215a3f3eddd579e6733b51a777fb45398bb92
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,exynos990.h
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2024 Igor Belwon <igor.belwon at mentallysanemainliners.org>
+ *
+ * Device Tree binding constants for Exynos990 clock controller.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_EXYNOS_990_H
+#define _DT_BINDINGS_CLOCK_EXYNOS_990_H
+
+/* CMU_TOP */
+#define CLK_FOUT_SHARED0_PLL		1
+#define CLK_FOUT_SHARED1_PLL		2
+#define CLK_FOUT_SHARED2_PLL		3
+#define CLK_FOUT_SHARED3_PLL		4
+#define CLK_FOUT_SHARED4_PLL		5
+#define CLK_FOUT_G3D_PLL		6
+#define CLK_FOUT_MMC_PLL		7
+#define CLK_MOUT_PLL_SHARED0		8
+#define CLK_MOUT_PLL_SHARED1		9
+#define CLK_MOUT_PLL_SHARED2		10
+#define CLK_MOUT_PLL_SHARED3		11
+#define CLK_MOUT_PLL_SHARED4		12
+#define CLK_MOUT_PLL_MMC		13
+#define CLK_MOUT_PLL_G3D		14
+#define CLK_MOUT_CMU_APM_BUS		15
+#define CLK_MOUT_CMU_AUD_CPU		16
+#define CLK_MOUT_CMU_BUS0_BUS		17
+#define CLK_MOUT_CMU_BUS1_BUS		18
+#define CLK_MOUT_CMU_BUS1_SSS		19
+#define CLK_MOUT_CMU_CIS_CLK0		20
+#define CLK_MOUT_CMU_CIS_CLK1		21
+#define CLK_MOUT_CMU_CIS_CLK2		22
+#define CLK_MOUT_CMU_CIS_CLK3		23
+#define CLK_MOUT_CMU_CIS_CLK4		24
+#define CLK_MOUT_CMU_CIS_CLK5		25
+#define CLK_MOUT_CMU_CMU_BOOST		26
+#define CLK_MOUT_CMU_CORE_BUS		27
+#define CLK_MOUT_CMU_CPUCL0_DBG_BUS	28
+#define CLK_MOUT_CMU_CPUCL0_SWITCH	29
+#define CLK_MOUT_CMU_CPUCL1_SWITCH	30
+#define CLK_MOUT_CMU_CPUCL2_BUSP	31
+#define CLK_MOUT_CMU_CPUCL2_SWITCH	32
+#define CLK_MOUT_CMU_CSIS_BUS		33
+#define CLK_MOUT_CMU_CSIS_OIS_MCU	34
+#define CLK_MOUT_CMU_DNC_BUS		35
+#define CLK_MOUT_CMU_DNC_BUSM		36
+#define CLK_MOUT_CMU_DNS_BUS		37
+#define CLK_MOUT_CMU_DPU		38
+#define CLK_MOUT_CMU_DPU_ALT		39
+#define CLK_MOUT_CMU_DSP_BUS		40
+#define CLK_MOUT_CMU_G2D_G2D		41
+#define CLK_MOUT_CMU_G2D_MSCL		42
+#define CLK_MOUT_CMU_HPM		43
+#define CLK_MOUT_CMU_HSI0_BUS		44
+#define CLK_MOUT_CMU_HSI0_DPGTC		45
+#define CLK_MOUT_CMU_HSI0_USB31DRD	46
+#define CLK_MOUT_CMU_HSI0_USBDP_DEBUG	47
+#define CLK_MOUT_CMU_HSI1_BUS		48
+#define CLK_MOUT_CMU_HSI1_MMC_CARD	49
+#define CLK_MOUT_CMU_HSI1_PCIE		50
+#define CLK_MOUT_CMU_HSI1_UFS_CARD	51
+#define CLK_MOUT_CMU_HSI1_UFS_EMBD	52
+#define CLK_MOUT_CMU_HSI2_BUS		53
+#define CLK_MOUT_CMU_HSI2_PCIE		54
+#define CLK_MOUT_CMU_IPP_BUS		55
+#define CLK_MOUT_CMU_ITP_BUS		56
+#define CLK_MOUT_CMU_MCSC_BUS		57
+#define CLK_MOUT_CMU_MCSC_GDC		58
+#define CLK_MOUT_CMU_CMU_BOOST_CPU	59
+#define CLK_MOUT_CMU_MFC0_MFC0		60
+#define CLK_MOUT_CMU_MFC0_WFD		61
+#define CLK_MOUT_CMU_MIF_BUSP		62
+#define CLK_MOUT_CMU_MIF_SWITCH		63
+#define CLK_MOUT_CMU_NPU_BUS		64
+#define CLK_MOUT_CMU_PERIC0_BUS		65
+#define CLK_MOUT_CMU_PERIC0_IP		66
+#define CLK_MOUT_CMU_PERIC1_BUS		67
+#define CLK_MOUT_CMU_PERIC1_IP		68
+#define CLK_MOUT_CMU_PERIS_BUS		69
+#define CLK_MOUT_CMU_SSP_BUS		70
+#define CLK_MOUT_CMU_TNR_BUS		71
+#define CLK_MOUT_CMU_VRA_BUS		72
+#define CLK_DOUT_CMU_APM_BUS		73
+#define CLK_DOUT_CMU_AUD_CPU		74
+#define CLK_DOUT_CMU_BUS0_BUS		75
+#define CLK_DOUT_CMU_BUS1_BUS		76
+#define CLK_DOUT_CMU_BUS1_SSS		77
+#define CLK_DOUT_CMU_CIS_CLK0		78
+#define CLK_DOUT_CMU_CIS_CLK1		79
+#define CLK_DOUT_CMU_CIS_CLK2		80
+#define CLK_DOUT_CMU_CIS_CLK3		81
+#define CLK_DOUT_CMU_CIS_CLK4		82
+#define CLK_DOUT_CMU_CIS_CLK5		83
+#define CLK_DOUT_CMU_CMU_BOOST		84
+#define CLK_DOUT_CMU_CORE_BUS		85
+#define CLK_DOUT_CMU_CPUCL0_DBG_BUS	86
+#define CLK_DOUT_CMU_CPUCL0_SWITCH	87
+#define CLK_DOUT_CMU_CPUCL1_SWITCH	88
+#define CLK_DOUT_CMU_CPUCL2_BUSP	89
+#define CLK_DOUT_CMU_CPUCL2_SWITCH	90
+#define CLK_DOUT_CMU_CSIS_BUS		91
+#define CLK_DOUT_CMU_CSIS_OIS_MCU	92
+#define CLK_DOUT_CMU_DNC_BUS		93
+#define CLK_DOUT_CMU_DNC_BUSM		94
+#define CLK_DOUT_CMU_DNS_BUS		95
+#define CLK_DOUT_CMU_DSP_BUS		96
+#define CLK_DOUT_CMU_G2D_G2D		97
+#define CLK_DOUT_CMU_G2D_MSCL		98
+#define CLK_DOUT_CMU_G3D_SWITCH		99
+#define CLK_DOUT_CMU_HPM		100
+#define CLK_DOUT_CMU_HSI0_BUS		101
+#define CLK_DOUT_CMU_HSI0_DPGTC		102
+#define CLK_DOUT_CMU_HSI0_USB31DRD	103
+#define CLK_DOUT_CMU_HSI0_USBDP_DEBUG	104
+#define CLK_DOUT_CMU_HSI1_BUS		105
+#define CLK_DOUT_CMU_HSI1_MMC_CARD	106
+#define CLK_DOUT_CMU_HSI1_PCIE		107
+#define CLK_DOUT_CMU_HSI1_UFS_CARD	108
+#define CLK_DOUT_CMU_HSI1_UFS_EMBD	109
+#define CLK_DOUT_CMU_HSI2_BUS		110
+#define CLK_DOUT_CMU_HSI2_PCIE		111
+#define CLK_DOUT_CMU_IPP_BUS		112
+#define CLK_DOUT_CMU_ITP_BUS		113
+#define CLK_DOUT_CMU_MCSC_BUS		114
+#define CLK_DOUT_CMU_MCSC_GDC		115
+#define CLK_DOUT_CMU_CMU_BOOST_CPU	116
+#define CLK_DOUT_CMU_MFC0_MFC0		117
+#define CLK_DOUT_CMU_MFC0_WFD		118
+#define CLK_DOUT_CMU_MIF_BUSP		119
+#define CLK_DOUT_CMU_NPU_BUS		120
+#define CLK_DOUT_CMU_OTP		121
+#define CLK_DOUT_CMU_PERIC0_BUS		122
+#define CLK_DOUT_CMU_PERIC0_IP		123
+#define CLK_DOUT_CMU_PERIC1_BUS		124
+#define CLK_DOUT_CMU_PERIC1_IP		125
+#define CLK_DOUT_CMU_PERIS_BUS		126
+#define CLK_DOUT_CMU_SSP_BUS		127
+#define CLK_DOUT_CMU_TNR_BUS		128
+#define CLK_DOUT_CMU_VRA_BUS		129
+#define CLK_DOUT_CMU_DPU		130
+#define CLK_DOUT_CMU_DPU_ALT		131
+#define CLK_DOUT_CMU_SHARED0_DIV2	132
+#define CLK_DOUT_CMU_SHARED0_DIV3	133
+#define CLK_DOUT_CMU_SHARED0_DIV4	134
+#define CLK_DOUT_CMU_SHARED1_DIV2	135
+#define CLK_DOUT_CMU_SHARED1_DIV3	136
+#define CLK_DOUT_CMU_SHARED1_DIV4	137
+#define CLK_DOUT_CMU_SHARED2_DIV2	138
+#define CLK_DOUT_CMU_SHARED4_DIV2	139
+#define CLK_DOUT_CMU_SHARED4_DIV3	140
+#define CLK_DOUT_CMU_SHARED4_DIV4	141
+#define CLK_GOUT_CMU_G3D_BUS		142
+#define CLK_GOUT_CMU_MIF_SWITCH		143
+#define CLK_GOUT_CMU_APM_BUS		144
+#define CLK_GOUT_CMU_AUD_CPU		145
+#define CLK_GOUT_CMU_BUS0_BUS		146
+#define CLK_GOUT_CMU_BUS1_BUS		147
+#define CLK_GOUT_CMU_BUS1_SSS		148
+#define CLK_GOUT_CMU_CIS_CLK0		149
+#define CLK_GOUT_CMU_CIS_CLK1		150
+#define CLK_GOUT_CMU_CIS_CLK2		151
+#define CLK_GOUT_CMU_CIS_CLK3		152
+#define CLK_GOUT_CMU_CIS_CLK4		153
+#define CLK_GOUT_CMU_CIS_CLK5		154
+#define CLK_GOUT_CMU_CORE_BUS		155
+#define CLK_GOUT_CMU_CPUCL0_DBG_BUS	156
+#define CLK_GOUT_CMU_CPUCL0_SWITCH	157
+#define CLK_GOUT_CMU_CPUCL1_SWITCH	158
+#define CLK_GOUT_CMU_CPUCL2_BUSP	159
+#define CLK_GOUT_CMU_CPUCL2_SWITCH	160
+#define CLK_GOUT_CMU_CSIS_BUS		161
+#define CLK_GOUT_CMU_CSIS_OIS_MCU	162
+#define CLK_GOUT_CMU_DNC_BUS		163
+#define CLK_GOUT_CMU_DNC_BUSM		164
+#define CLK_GOUT_CMU_DNS_BUS		165
+#define CLK_GOUT_CMU_DPU		166
+#define CLK_GOUT_CMU_DPU_BUS		167
+#define CLK_GOUT_CMU_DSP_BUS		168
+#define CLK_GOUT_CMU_G2D_G2D		169
+#define CLK_GOUT_CMU_G2D_MSCL		170
+#define CLK_GOUT_CMU_G3D_SWITCH		171
+#define CLK_GOUT_CMU_HPM		172
+#define CLK_GOUT_CMU_HSI0_BUS		173
+#define CLK_GOUT_CMU_HSI0_DPGTC		174
+#define CLK_GOUT_CMU_HSI0_USB31DRD	175
+#define CLK_GOUT_CMU_HSI0_USBDP_DEBUG	176
+#define CLK_GOUT_CMU_HSI1_BUS		177
+#define CLK_GOUT_CMU_HSI1_MMC_CARD	178
+#define CLK_GOUT_CMU_HSI1_PCIE		179
+#define CLK_GOUT_CMU_HSI1_UFS_CARD	180
+#define CLK_GOUT_CMU_HSI1_UFS_EMBD	181
+#define CLK_GOUT_CMU_HSI2_BUS		182
+#define CLK_GOUT_CMU_HSI2_PCIE		183
+#define CLK_GOUT_CMU_IPP_BUS		184
+#define CLK_GOUT_CMU_ITP_BUS		185
+#define CLK_GOUT_CMU_MCSC_BUS		186
+#define CLK_GOUT_CMU_MCSC_GDC		187
+#define CLK_GOUT_CMU_MFC0_MFC0		188
+#define CLK_GOUT_CMU_MFC0_WFD		189
+#define CLK_GOUT_CMU_MIF_BUSP		190
+#define CLK_GOUT_CMU_NPU_BUS		191
+#define CLK_GOUT_CMU_PERIC0_BUS		192
+#define CLK_GOUT_CMU_PERIC0_IP		193
+#define CLK_GOUT_CMU_PERIC1_BUS		194
+#define CLK_GOUT_CMU_PERIC1_IP		195
+#define CLK_GOUT_CMU_PERIS_BUS		196
+#define CLK_GOUT_CMU_SSP_BUS		197
+#define CLK_GOUT_CMU_TNR_BUS		198
+#define CLK_GOUT_CMU_VRA_BUS		199
+
+/* CMU_HSI0 */
+#define CLK_MOUT_HSI0_BUS_USER				1
+#define CLK_MOUT_HSI0_USB31DRD_USER			2
+#define CLK_MOUT_HSI0_USBDP_DEBUG_USER			3
+#define CLK_MOUT_HSI0_DPGTC_USER			4
+#define CLK_GOUT_HSI0_DP_LINK_DP_GTC_CLK		5
+#define CLK_GOUT_HSI0_DP_LINK_PCLK			6
+#define CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK			7
+#define CLK_GOUT_HSI0_LHM_AXI_P_HSI0_CLK		8
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_ACLK		9
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS1_PCLK		10
+#define CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK			11
+#define CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2			12
+#define CLK_GOUT_HSI0_SYSREG_HSI0_PCLK			13
+#define CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL		14
+#define CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY		15
+#define CLK_GOUT_HSI0_USB31DRD_USB31DRD_REF_CLK_40	16
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_REF_SOC_PLL	17
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_SCL_APB		18
+#define CLK_GOUT_HSI0_USB31DRD_USBPCS_APB_CLK		19
+#define CLK_GOUT_HSI0_VGEN_LITE_HSI0_CLK		20
+#define CLK_GOUT_HSI0_CMU_HSI0_PCLK			21
+#define CLK_GOUT_HSI0_XIU_D_HSI0_ACLK			22
+
+#endif

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Mon Dec  9 06:45:22 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Mon, 09 Dec 2024 15:45:22 +0100
Subject: [PATCH v4 2/3] clk: samsung: clk-pll: Add support for pll_{0717x,
 0718x, 0732x}
In-Reply-To: <20241209-exynos990-cmu-v4-0-57f07080f9e4@mentallysanemainliners.org>
References: <20241209-exynos990-cmu-v4-0-57f07080f9e4@mentallysanemainliners.org>
Message-ID: <20241209-exynos990-cmu-v4-2-57f07080f9e4@mentallysanemainliners.org>

These PLLs are found in the Exynos990 SoC. The PLLs are similar
to pll0822x.

pll0717x and pll0718x are an exception, and they use the mdiv
mask from 1718X (that is, one bit smaller).

Apart from that, the masks/shifts are identical to those of 0822x.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 drivers/clk/samsung/clk-pll.c | 14 ++++++++++++--
 drivers/clk/samsung/clk-pll.h |  3 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index be6b516949193f103696c814b5cffad5d4ea9a66..2e94bba6c3966b9470f0ef42ad101ee3da0519b9 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -430,7 +430,10 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {
 #define PLL0822X_LOCK_STAT_SHIFT	(29)
 #define PLL0822X_ENABLE_SHIFT		(31)
 
-/* PLL1418x is similar to PLL0822x, except that MDIV is one bit smaller */
+/*
+ * PLL1418x, PLL0717x and PLL0718x are similar
+ * to PLL0822x, except that MDIV is one bit smaller
+ */
 #define PLL1418X_MDIV_MASK		(0x1FF)
 
 static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
@@ -441,10 +444,14 @@ static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
 	u64 fvco = parent_rate;
 
 	pll_con3 = readl_relaxed(pll->con_reg);
-	if (pll->type != pll_1418x)
+
+	if (pll->type != pll_1418x &&
+	    pll->type != pll_0717x &&
+	    pll->type != pll_0718x)
 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
 	else
 		mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL1418X_MDIV_MASK;
+
 	pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
 	sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
 
@@ -1377,6 +1384,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_0516x:
 	case pll_0517x:
 	case pll_0518x:
+	case pll_0717x:
+	case pll_0718x:
+	case pll_0732x:
 		pll->enable_offs = PLL0822X_ENABLE_SHIFT;
 		pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
 		if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 858ab367eb6552bf880ef9d14cd89713b08960a4..6ddc54d173a01e201d93f1ed1679ca6a6ebfa939 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -45,6 +45,9 @@ enum samsung_pll_type {
 	pll_531x,
 	pll_1051x,
 	pll_1052x,
+	pll_0717x,
+	pll_0718x,
+	pll_0732x,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Mon Dec  9 06:45:23 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Mon, 09 Dec 2024 15:45:23 +0100
Subject: [PATCH v4 3/3] clk: samsung: Introduce Exynos990 clock controller
 driver
In-Reply-To: <20241209-exynos990-cmu-v4-0-57f07080f9e4@mentallysanemainliners.org>
References: <20241209-exynos990-cmu-v4-0-57f07080f9e4@mentallysanemainliners.org>
Message-ID: <20241209-exynos990-cmu-v4-3-57f07080f9e4@mentallysanemainliners.org>

The current implementation contains support for:
- CMU_TOP - which generates clocks for other blocks
- CMU_HSI0 - which generates clocks for USB31.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 drivers/clk/samsung/Makefile        |    1 +
 drivers/clk/samsung/clk-exynos990.c | 1343 +++++++++++++++++++++++++++++++++++
 2 files changed, 1344 insertions(+)

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 7a88331a658d5035c083eba910e37564915f9a46..90e5b114872c5057a9bd43fd1a16c2ad4630cc3f 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7885.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos8895.o
+obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos990.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov9.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov920.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-gs101.o
diff --git a/drivers/clk/samsung/clk-exynos990.c b/drivers/clk/samsung/clk-exynos990.c
new file mode 100644
index 0000000000000000000000000000000000000000..8e2a2e8eccee36dd7d4bc7099af2672d222f4abe
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos990.c
@@ -0,0 +1,1343 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Igor Belwon <igor.belwon at mentallysanemainliners.org>
+ *
+ * Common Clock Framework support for Exynos990.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/samsung,exynos990.h>
+
+#include "clk.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_GOUT_CMU_VRA_BUS + 1)
+#define CLKS_NR_HSI0 (CLK_GOUT_HSI0_XIU_D_HSI0_ACLK + 1)
+
+/* ---- CMU_TOP ------------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_TOP (0x1a330000) */
+#define PLL_LOCKTIME_PLL_G3D				0x0000
+#define PLL_LOCKTIME_PLL_MMC				0x0004
+#define PLL_LOCKTIME_PLL_SHARED0			0x0008
+#define PLL_LOCKTIME_PLL_SHARED1			0x000c
+#define PLL_LOCKTIME_PLL_SHARED2			0x0010
+#define PLL_LOCKTIME_PLL_SHARED3			0x0014
+#define PLL_LOCKTIME_PLL_SHARED4			0x0018
+#define PLL_CON0_PLL_G3D				0x0100
+#define PLL_CON3_PLL_G3D				0x010c
+#define PLL_CON0_PLL_MMC				0x0140
+#define PLL_CON3_PLL_MMC				0x014c
+#define PLL_CON0_PLL_SHARED0				0x0180
+#define PLL_CON3_PLL_SHARED0				0x018c
+#define PLL_CON0_PLL_SHARED1				0x01c0
+#define PLL_CON3_PLL_SHARED1				0x01cc
+#define PLL_CON0_PLL_SHARED2				0x0200
+#define PLL_CON3_PLL_SHARED2				0x020c
+#define PLL_CON0_PLL_SHARED3				0x0240
+#define PLL_CON3_PLL_SHARED3				0x024c
+#define PLL_CON0_PLL_SHARED4				0x0280
+#define PLL_CON3_PLL_SHARED4				0x028c
+#define CLK_CON_MUX_MUX_CLKCMU_APM_BUS			0x1004
+#define CLK_CON_MUX_MUX_CLKCMU_AUD_CPU			0x1008
+#define CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS			0x100c
+#define CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS			0x1010
+#define CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS			0x1014
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0			0x1018
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1			0x101c
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2			0x1020
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3			0x1024
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4			0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5			0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST		0x1030
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS			0x1034
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS		0x1038
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH		0x103c
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH		0x1040
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP		0x1044
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH		0x1048
+#define CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS			0x104c
+#define CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU		0x1050
+#define CLK_CON_MUX_MUX_CLKCMU_DNC_BUS			0x1054
+#define CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM			0x1058
+#define CLK_CON_MUX_MUX_CLKCMU_DNS_BUS			0x105c
+#define CLK_CON_MUX_MUX_CLKCMU_DPU			0x1060
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_ALT			0x1064
+#define CLK_CON_MUX_MUX_CLKCMU_DSP_BUS			0x1068
+#define CLK_CON_MUX_MUX_CLKCMU_G2D_G2D			0x106c
+#define CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL			0x1070
+#define CLK_CON_MUX_MUX_CLKCMU_HPM			0x1074
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS			0x1078
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC		0x107c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD		0x1080
+#define CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG		0x1084
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS			0x1088
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD		0x108c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE		0x1090
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD		0x1094
+#define CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD		0x1098
+#define CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS			0x109c
+#define CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE		0x10a0
+#define CLK_CON_MUX_MUX_CLKCMU_IPP_BUS			0x10a4
+#define CLK_CON_MUX_MUX_CLKCMU_ITP_BUS			0x10a8
+#define CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS			0x10ac
+#define CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC			0x10b0
+#define CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU		0x10b4
+#define CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0		0x10b8
+#define CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD			0x10bc
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP			0x10c0
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH		0x10c4
+#define CLK_CON_MUX_MUX_CLKCMU_NPU_BUS			0x10c8
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS		0x10cc
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP		0x10d0
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS		0x10d4
+#define CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP		0x10d8
+#define CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS		0x10dc
+#define CLK_CON_MUX_MUX_CLKCMU_SSP_BUS			0x10e0
+#define CLK_CON_MUX_MUX_CLKCMU_TNR_BUS			0x10e4
+#define CLK_CON_MUX_MUX_CLKCMU_VRA_BUS			0x10e8
+#define CLK_CON_DIV_CLKCMU_APM_BUS			0x1800
+#define CLK_CON_DIV_CLKCMU_AUD_CPU			0x1804
+#define CLK_CON_DIV_CLKCMU_BUS0_BUS			0x1808
+#define CLK_CON_DIV_CLKCMU_BUS1_BUS			0x180c
+#define CLK_CON_DIV_CLKCMU_BUS1_SSS			0x1810
+#define CLK_CON_DIV_CLKCMU_CIS_CLK0			0x1814
+#define CLK_CON_DIV_CLKCMU_CIS_CLK1			0x1818
+#define CLK_CON_DIV_CLKCMU_CIS_CLK2			0x181c
+#define CLK_CON_DIV_CLKCMU_CIS_CLK3			0x1820
+#define CLK_CON_DIV_CLKCMU_CIS_CLK4			0x1824
+#define CLK_CON_DIV_CLKCMU_CIS_CLK5			0x1828
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST			0x182c
+#define CLK_CON_DIV_CLKCMU_CORE_BUS			0x1830
+#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS		0x1834
+#define CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH		0x1838
+#define CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH		0x183c
+#define CLK_CON_DIV_CLKCMU_CPUCL2_BUSP			0x1840
+#define CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH		0x1844
+#define CLK_CON_DIV_CLKCMU_CSIS_BUS			0x1848
+#define CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU			0x184c
+#define CLK_CON_DIV_CLKCMU_DNC_BUS			0x1850
+#define CLK_CON_DIV_CLKCMU_DNC_BUSM			0x1854
+#define CLK_CON_DIV_CLKCMU_DNS_BUS			0x1858
+#define CLK_CON_DIV_CLKCMU_DSP_BUS			0x185c
+#define CLK_CON_DIV_CLKCMU_G2D_G2D			0x1860
+#define CLK_CON_DIV_CLKCMU_G2D_MSCL			0x1864
+#define CLK_CON_DIV_CLKCMU_G3D_SWITCH			0x1868
+#define CLK_CON_DIV_CLKCMU_HPM				0x186c
+#define CLK_CON_DIV_CLKCMU_HSI0_BUS			0x1870
+#define CLK_CON_DIV_CLKCMU_HSI0_DPGTC			0x1874
+#define CLK_CON_DIV_CLKCMU_HSI0_USB31DRD		0x1878
+#define CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG		0x187c
+#define CLK_CON_DIV_CLKCMU_HSI1_BUS			0x1880
+#define CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD		0x1884
+#define CLK_CON_DIV_CLKCMU_HSI1_PCIE			0x1888
+#define CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD		0x188c
+#define CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD		0x1890
+#define CLK_CON_DIV_CLKCMU_HSI2_BUS			0x1894
+#define CLK_CON_DIV_CLKCMU_HSI2_PCIE			0x1898
+#define CLK_CON_DIV_CLKCMU_IPP_BUS			0x189c
+#define CLK_CON_DIV_CLKCMU_ITP_BUS			0x18a0
+#define CLK_CON_DIV_CLKCMU_MCSC_BUS			0x18a4
+#define CLK_CON_DIV_CLKCMU_MCSC_GDC			0x18a8
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU		0x18ac
+#define CLK_CON_DIV_CLKCMU_MFC0_MFC0			0x18b0
+#define CLK_CON_DIV_CLKCMU_MFC0_WFD			0x18b4
+#define CLK_CON_DIV_CLKCMU_MIF_BUSP			0x18b8
+#define CLK_CON_DIV_CLKCMU_NPU_BUS			0x18bc
+#define CLK_CON_DIV_CLKCMU_OTP				0x18c0
+#define CLK_CON_DIV_CLKCMU_PERIC0_BUS			0x18c4
+#define CLK_CON_DIV_CLKCMU_PERIC0_IP			0x18c8
+#define CLK_CON_DIV_CLKCMU_PERIC1_BUS			0x18cc
+#define CLK_CON_DIV_CLKCMU_PERIC1_IP			0x18d0
+#define CLK_CON_DIV_CLKCMU_PERIS_BUS			0x18d4
+#define CLK_CON_DIV_CLKCMU_SSP_BUS			0x18d8
+#define CLK_CON_DIV_CLKCMU_TNR_BUS			0x18dc
+#define CLK_CON_DIV_CLKCMU_VRA_BUS			0x18e0
+#define CLK_CON_DIV_DIV_CLKCMU_DPU			0x18e8
+#define CLK_CON_DIV_DIV_CLKCMU_DPU_ALT			0x18ec
+#define CLK_CON_DIV_PLL_SHARED0_DIV2			0x18f4
+#define CLK_CON_DIV_PLL_SHARED0_DIV3			0x18f8
+#define CLK_CON_DIV_PLL_SHARED0_DIV4			0x18fc
+#define CLK_CON_DIV_PLL_SHARED1_DIV2			0x1900
+#define CLK_CON_DIV_PLL_SHARED1_DIV3			0x1904
+#define CLK_CON_DIV_PLL_SHARED1_DIV4			0x1908
+#define CLK_CON_DIV_PLL_SHARED2_DIV2			0x190c
+#define CLK_CON_DIV_PLL_SHARED4_DIV2			0x1910
+#define CLK_CON_DIV_PLL_SHARED4_DIV3			0x1914
+#define CLK_CON_DIV_PLL_SHARED4_DIV4			0x1918
+#define CLK_CON_GAT_CLKCMU_G3D_BUS			0x2000
+#define CLK_CON_GAT_CLKCMU_MIF_SWITCH			0x2004
+#define CLK_CON_GAT_GATE_CLKCMU_APM_BUS			0x2008
+#define CLK_CON_GAT_GATE_CLKCMU_AUD_CPU			0x200c
+#define CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS		0x2010
+#define CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS		0x2014
+#define CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS		0x2018
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0		0x201c
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1		0x2020
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2		0x2024
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3		0x2028
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4		0x202c
+#define CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5		0x2030
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS		0x2034
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS		0x2038
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH		0x203c
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH		0x2040
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP		0x2044
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH		0x2048
+#define CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS		0x204c
+#define CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU		0x2050
+#define CLK_CON_GAT_GATE_CLKCMU_DNC_BUS			0x2054
+#define CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM		0x2058
+#define CLK_CON_GAT_GATE_CLKCMU_DNS_BUS			0x205c
+#define CLK_CON_GAT_GATE_CLKCMU_DPU			0x2060
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_BUS			0x2064
+#define CLK_CON_GAT_GATE_CLKCMU_DSP_BUS			0x2068
+#define CLK_CON_GAT_GATE_CLKCMU_G2D_G2D			0x206c
+#define CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL		0x2070
+#define CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH		0x2074
+#define CLK_CON_GAT_GATE_CLKCMU_HPM			0x2078
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS		0x207c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC		0x2080
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD		0x2084
+#define CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG	0x2088
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS		0x208c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD		0x2090
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE		0x2094
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD		0x2098
+#define CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD		0x209c
+#define CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS		0x20a0
+#define CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE		0x20a4
+#define CLK_CON_GAT_GATE_CLKCMU_IPP_BUS			0x20a8
+#define CLK_CON_GAT_GATE_CLKCMU_ITP_BUS			0x20ac
+#define CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS		0x20b0
+#define CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC		0x20b4
+#define CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0		0x20bc
+#define CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD		0x20c0
+#define CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP		0x20c4
+#define CLK_CON_GAT_GATE_CLKCMU_NPU_BUS			0x20c8
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS		0x20cc
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP		0x20d0
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS		0x20d4
+#define CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP		0x20d8
+#define CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS		0x20dc
+#define CLK_CON_GAT_GATE_CLKCMU_SSP_BUS			0x20e0
+#define CLK_CON_GAT_GATE_CLKCMU_TNR_BUS			0x20e4
+#define CLK_CON_GAT_GATE_CLKCMU_VRA_BUS			0x20e8
+
+static const unsigned long top_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_G3D,
+	PLL_LOCKTIME_PLL_MMC,
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_LOCKTIME_PLL_SHARED2,
+	PLL_LOCKTIME_PLL_SHARED3,
+	PLL_LOCKTIME_PLL_SHARED4,
+	PLL_CON3_PLL_G3D,
+	PLL_CON3_PLL_MMC,
+	PLL_CON3_PLL_SHARED0,
+	PLL_CON3_PLL_SHARED1,
+	PLL_CON3_PLL_SHARED2,
+	PLL_CON3_PLL_SHARED3,
+	PLL_CON3_PLL_SHARED4,
+	CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_AUD_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4,
+	CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5,
+	CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST,
+	CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_MUX_MUX_CLKCMU_DNC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM,
+	CLK_CON_MUX_MUX_CLKCMU_DNS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DPU,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_ALT,
+	CLK_CON_MUX_MUX_CLKCMU_DSP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_G2D_G2D,
+	CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL,
+	CLK_CON_MUX_MUX_CLKCMU_HPM,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE,
+	CLK_CON_MUX_MUX_CLKCMU_IPP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_ITP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC,
+	CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0,
+	CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_NPU_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_SSP_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_TNR_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_VRA_BUS,
+	CLK_CON_DIV_CLKCMU_APM_BUS,
+	CLK_CON_DIV_CLKCMU_AUD_CPU,
+	CLK_CON_DIV_CLKCMU_BUS0_BUS,
+	CLK_CON_DIV_CLKCMU_BUS1_BUS,
+	CLK_CON_DIV_CLKCMU_BUS1_SSS,
+	CLK_CON_DIV_CLKCMU_CIS_CLK0,
+	CLK_CON_DIV_CLKCMU_CIS_CLK1,
+	CLK_CON_DIV_CLKCMU_CIS_CLK2,
+	CLK_CON_DIV_CLKCMU_CIS_CLK3,
+	CLK_CON_DIV_CLKCMU_CIS_CLK4,
+	CLK_CON_DIV_CLKCMU_CIS_CLK5,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST,
+	CLK_CON_DIV_CLKCMU_CORE_BUS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_DIV_CLKCMU_CSIS_BUS,
+	CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_DIV_CLKCMU_DNC_BUS,
+	CLK_CON_DIV_CLKCMU_DNC_BUSM,
+	CLK_CON_DIV_CLKCMU_DNS_BUS,
+	CLK_CON_DIV_CLKCMU_DSP_BUS,
+	CLK_CON_DIV_CLKCMU_G2D_G2D,
+	CLK_CON_DIV_CLKCMU_G2D_MSCL,
+	CLK_CON_DIV_CLKCMU_G3D_SWITCH,
+	CLK_CON_DIV_CLKCMU_HPM,
+	CLK_CON_DIV_CLKCMU_HSI0_BUS,
+	CLK_CON_DIV_CLKCMU_HSI0_DPGTC,
+	CLK_CON_DIV_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_DIV_CLKCMU_HSI1_BUS,
+	CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_DIV_CLKCMU_HSI1_PCIE,
+	CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_DIV_CLKCMU_HSI2_BUS,
+	CLK_CON_DIV_CLKCMU_HSI2_PCIE,
+	CLK_CON_DIV_CLKCMU_IPP_BUS,
+	CLK_CON_DIV_CLKCMU_ITP_BUS,
+	CLK_CON_DIV_CLKCMU_MCSC_BUS,
+	CLK_CON_DIV_CLKCMU_MCSC_GDC,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU,
+	CLK_CON_DIV_CLKCMU_MFC0_MFC0,
+	CLK_CON_DIV_CLKCMU_MFC0_WFD,
+	CLK_CON_DIV_CLKCMU_MIF_BUSP,
+	CLK_CON_DIV_CLKCMU_NPU_BUS,
+	CLK_CON_DIV_CLKCMU_OTP,
+	CLK_CON_DIV_CLKCMU_PERIC0_BUS,
+	CLK_CON_DIV_CLKCMU_PERIC0_IP,
+	CLK_CON_DIV_CLKCMU_PERIC1_BUS,
+	CLK_CON_DIV_CLKCMU_PERIC1_IP,
+	CLK_CON_DIV_CLKCMU_PERIS_BUS,
+	CLK_CON_DIV_CLKCMU_SSP_BUS,
+	CLK_CON_DIV_CLKCMU_TNR_BUS,
+	CLK_CON_DIV_CLKCMU_VRA_BUS,
+	CLK_CON_DIV_DIV_CLKCMU_DPU,
+	CLK_CON_DIV_DIV_CLKCMU_DPU_ALT,
+	CLK_CON_DIV_PLL_SHARED0_DIV2,
+	CLK_CON_DIV_PLL_SHARED0_DIV3,
+	CLK_CON_DIV_PLL_SHARED0_DIV4,
+	CLK_CON_DIV_PLL_SHARED1_DIV2,
+	CLK_CON_DIV_PLL_SHARED1_DIV3,
+	CLK_CON_DIV_PLL_SHARED1_DIV4,
+	CLK_CON_DIV_PLL_SHARED2_DIV2,
+	CLK_CON_DIV_PLL_SHARED4_DIV2,
+	CLK_CON_DIV_PLL_SHARED4_DIV3,
+	CLK_CON_DIV_PLL_SHARED4_DIV4,
+	CLK_CON_GAT_CLKCMU_G3D_BUS,
+	CLK_CON_GAT_CLKCMU_MIF_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_AUD_CPU,
+	CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4,
+	CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5,
+	CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU,
+	CLK_CON_GAT_GATE_CLKCMU_DNC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM,
+	CLK_CON_GAT_GATE_CLKCMU_DNS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DPU,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DSP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_G2D_G2D,
+	CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL,
+	CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_HPM,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD,
+	CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE,
+	CLK_CON_GAT_GATE_CLKCMU_IPP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_ITP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC,
+	CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0,
+	CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD,
+	CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_NPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_SSP_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_TNR_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_VRA_BUS,
+};
+
+static const struct samsung_pll_clock top_pll_clks[] __initconst = {
+	PLL(pll_0717x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, NULL),
+	PLL(pll_0717x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, NULL),
+	PLL(pll_0718x, CLK_FOUT_SHARED2_PLL, "fout_shared2_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED2, PLL_CON3_PLL_SHARED2, NULL),
+	PLL(pll_0718x, CLK_FOUT_SHARED3_PLL, "fout_shared3_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED3, PLL_CON3_PLL_SHARED3, NULL),
+	PLL(pll_0717x, CLK_FOUT_SHARED4_PLL, "fout_shared4_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED4, PLL_CON3_PLL_SHARED4, NULL),
+	PLL(pll_0732x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL),
+	PLL(pll_0718x, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_G3D, PLL_CON3_PLL_G3D, NULL),
+};
+
+/* Parent clock list for CMU_TOP muxes*/
+PNAME(mout_pll_shared0_p)		= { "oscclk", "fout_shared0_pll" };
+PNAME(mout_pll_shared1_p)		= { "oscclk", "fout_shared1_pll" };
+PNAME(mout_pll_shared2_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_pll_shared3_p)		= { "oscclk", "fout_shared3_pll" };
+PNAME(mout_pll_shared4_p)		= { "oscclk", "fout_shared4_pll" };
+PNAME(mout_pll_mmc_p)			= { "oscclk", "fout_mmc_pll" };
+PNAME(mout_pll_g3d_p)			= { "oscclk", "fout_g3d_pll" };
+PNAME(mout_cmu_apm_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_aud_cpu_p)		= { "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_bus0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_bus1_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_bus1_sss_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_cis_clk0_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk1_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk2_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk3_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk4_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cis_clk5_p)		= { "oscclk",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cmu_boost_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_core_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div3",
+					    "dout_cmu_shared1_div3",
+					    "dout_cmu_shared0_div4",
+					    "fout_shared3_pll", "oscclk" };
+PNAME(mout_cmu_cpucl0_dbg_bus_p)	= { "fout_shared2_pll",
+					    "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4",
+					    "oscclk" };
+PNAME(mout_cmu_cpucl0_switch_p)		= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_cpucl1_switch_p)	= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_cpucl2_busp_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_cpucl2_switch_p)		= { "fout_shared4_pll",
+					    "dout_cmu_shared0_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_csis_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3" };
+PNAME(mout_cmu_csis_ois_mcu_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_dnc_bus_p)		= { "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_dnc_busm_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "dout_cmu_shared4_div4" };
+PNAME(mout_cmu_dns_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_dpu_p)			= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_dpu_alt_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_dsp_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "fout_shared3_pll", "oscclk",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_g2d_g2d_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_g2d_mscl_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "dout_cmu_shared4_div4",
+					    "oscclk" };
+PNAME(mout_cmu_hpm_p)			= { "oscclk",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_hsi0_dpgtc_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_usb31drd_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi0_usbdp_debug_p)	= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_hsi1_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "fout_mmc_pll", "oscclk", "oscclk" };
+PNAME(mout_cmu_hsi1_mmc_card_p)	= { "oscclk", "fout_shared2_pll",
+					    "fout_mmc_pll",
+					    "dout_cmu_shared0_div4" };
+PNAME(mout_cmu_hsi1_pcie_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_hsi1_ufs_card_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi1_ufs_embd_p)		= { "oscclk", "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_hsi2_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_hsi2_pcie_p)		= { "oscclk", "fout_shared2_pll" };
+PNAME(mout_cmu_ipp_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "oscclk", "oscclk", "oscclk" };
+PNAME(mout_cmu_itp_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_mcsc_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_mcsc_gdc_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_cmu_boost_cpu_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_mfc0_mfc0_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_mfc0_wfd_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_mif_busp_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_mif_switch_p)		= { "fout_shared0_pll",
+					    "fout_shared1_pll",
+					    "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2",
+					    "oscclk" };
+PNAME(mout_cmu_npu_bus_p)		= { "dout_cmu_shared0_div2",
+					    "dout_cmu_shared1_div2",
+					    "fout_shared2_pll",
+					    "dout_cmu_shared4_div2",
+					    "fout_shared3_pll", "oscclk",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_peric0_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric0_ip_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric1_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peric1_ip_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_peris_bus_p)		= { "dout_cmu_shared0_div4",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_ssp_bus_p)		= { "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2" };
+PNAME(mout_cmu_tnr_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared1_div4",
+					    "dout_cmu_shared4_div3",
+					    "dout_cmu_shared2_div2",
+					    "oscclk", "oscclk" };
+PNAME(mout_cmu_vra_bus_p)		= { "dout_cmu_shared0_div3",
+					    "dout_cmu_shared4_div2",
+					    "dout_cmu_shared0_div4",
+					    "dout_cmu_shared4_div3" };
+
+/*
+ * Register name to clock name mangling strategy used in this file
+ *
+ * Replace PLL_CON{0,3}_PLL	   with CLK_MOUT_PLL and mout_pll
+ * Replace CLK_CON_MUX_MUX_CLKCMU  with CLK_MOUT_CMU and mout_cmu
+ * Replace CLK_CON_DIV_CLKCMU      with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_DIV_DIV_CLKCMU  with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_DIV_PLL_CLKCMU  with CLK_DOUT_CMU_CMU and dout_cmu_cmu
+ * Replace CLK_CON_GAT_CLKCMU      with CLK_GOUT_CMU and gout_cmu
+ * Replace CLK_CON_GAT_GATE_CLKCMU with CLK_GOUT_CMU and gout_cmu
+ *
+ * For gates remove _UID _BLK _IPCLKPORT, _I and _RSTNSYNC
+ */
+
+static const struct samsung_mux_clock top_mux_clks[] __initconst = {
+	MUX(CLK_MOUT_PLL_SHARED0, "mout_pll_shared0", mout_pll_shared0_p,
+	    PLL_CON3_PLL_SHARED0, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED1, "mout_pll_shared1", mout_pll_shared1_p,
+	    PLL_CON3_PLL_SHARED1, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED2, "mout_pll_shared2", mout_pll_shared2_p,
+	    PLL_CON3_PLL_SHARED2, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED3, "mout_pll_shared3", mout_pll_shared3_p,
+	    PLL_CON3_PLL_SHARED3, 4, 1),
+	MUX(CLK_MOUT_PLL_SHARED4, "mout_pll_shared4", mout_pll_shared4_p,
+	    PLL_CON0_PLL_SHARED4, 4, 1),
+	MUX(CLK_MOUT_PLL_MMC, "mout_pll_mmc", mout_pll_mmc_p,
+	    PLL_CON0_PLL_MMC, 4, 1),
+	MUX(CLK_MOUT_PLL_G3D, "mout_pll_g3d", mout_pll_g3d_p,
+	    PLL_CON0_PLL_G3D, 4, 1),
+	MUX(CLK_MOUT_CMU_APM_BUS, "mout_cmu_apm_bus",
+	    mout_cmu_apm_bus_p, CLK_CON_MUX_MUX_CLKCMU_APM_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_AUD_CPU, "mout_cmu_aud_cpu",
+	    mout_cmu_aud_cpu_p, CLK_CON_MUX_MUX_CLKCMU_AUD_CPU, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS0_BUS, "mout_cmu_bus0_bus",
+	    mout_cmu_bus0_bus_p, CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS1_BUS, "mout_cmu_bus1_bus",
+	    mout_cmu_bus1_bus_p, CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_BUS1_SSS, "mout_cmu_bus1_sss",
+	    mout_cmu_bus1_sss_p, CLK_CON_MUX_MUX_CLKCMU_BUS1_SSS, 0, 2),
+	MUX(CLK_MOUT_CMU_CIS_CLK0, "mout_cmu_cis_clk0",
+	    mout_cmu_cis_clk0_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK0, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK1, "mout_cmu_cis_clk1",
+	    mout_cmu_cis_clk1_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK1, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK2, "mout_cmu_cis_clk2",
+	    mout_cmu_cis_clk2_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK2, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK3, "mout_cmu_cis_clk3",
+	    mout_cmu_cis_clk3_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK3, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK4, "mout_cmu_cis_clk4",
+	    mout_cmu_cis_clk4_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK4, 0, 1),
+	MUX(CLK_MOUT_CMU_CIS_CLK5, "mout_cmu_cis_clk5",
+	    mout_cmu_cis_clk5_p, CLK_CON_MUX_MUX_CLKCMU_CIS_CLK5, 0, 1),
+	MUX(CLK_MOUT_CMU_CMU_BOOST, "mout_cmu_cmu_boost",
+	    mout_cmu_cmu_boost_p, CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST, 0, 2),
+	MUX(CLK_MOUT_CMU_CORE_BUS, "mout_cmu_core_bus",
+	    mout_cmu_core_bus_p, CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_CPUCL0_DBG_BUS, "mout_cmu_cpucl0_dbg_bus",
+	    mout_cmu_cpucl0_dbg_bus_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG_BUS,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL0_SWITCH, "mout_cmu_cpucl0_switch",
+	    mout_cmu_cpucl0_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL1_SWITCH, "mout_cmu_cpucl1_switch",
+	    mout_cmu_cpucl1_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CPUCL2_BUSP, "mout_cmu_cpucl2_busp",
+	    mout_cmu_cpucl2_busp_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL2_BUSP,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_CPUCL2_SWITCH, "mout_cmu_cpucl2_switch",
+	    mout_cmu_cpucl2_switch_p, CLK_CON_MUX_MUX_CLKCMU_CPUCL2_SWITCH,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CSIS_BUS, "mout_cmu_csis_bus",
+	    mout_cmu_csis_bus_p, CLK_CON_MUX_MUX_CLKCMU_CSIS_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_CSIS_OIS_MCU, "mout_cmu_csis_ois_mcu",
+	    mout_cmu_csis_ois_mcu_p, CLK_CON_MUX_MUX_CLKCMU_CSIS_OIS_MCU,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_DNC_BUS, "mout_cmu_dnc_bus",
+	    mout_cmu_dnc_bus_p, CLK_CON_MUX_MUX_CLKCMU_DNC_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_DNC_BUSM, "mout_cmu_dnc_busm",
+	    mout_cmu_dnc_busm_p, CLK_CON_MUX_MUX_CLKCMU_DNC_BUSM, 0, 2),
+	MUX(CLK_MOUT_CMU_DNS_BUS, "mout_cmu_dns_bus",
+	    mout_cmu_dns_bus_p, CLK_CON_MUX_MUX_CLKCMU_DNS_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_DPU, "mout_cmu_dpu",
+	    mout_cmu_dpu_p, CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 1),
+	MUX(CLK_MOUT_CMU_DPU_ALT, "mout_cmu_dpu_alt",
+	    mout_cmu_dpu_alt_p, CLK_CON_MUX_MUX_CLKCMU_DPU_ALT, 0, 2),
+	MUX(CLK_MOUT_CMU_DSP_BUS, "mout_cmu_dsp_bus",
+	    mout_cmu_dsp_bus_p, CLK_CON_MUX_MUX_CLKCMU_DSP_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_G2D_G2D, "mout_cmu_g2d_g2d",
+	    mout_cmu_g2d_g2d_p, CLK_CON_MUX_MUX_CLKCMU_G2D_G2D, 0, 2),
+	MUX(CLK_MOUT_CMU_G2D_MSCL, "mout_cmu_g2d_mscl",
+	    mout_cmu_g2d_mscl_p, CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL, 0, 1),
+	MUX(CLK_MOUT_CMU_HPM, "mout_cmu_hpm",
+	    mout_cmu_hpm_p, CLK_CON_MUX_MUX_CLKCMU_HPM, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_BUS, "mout_cmu_hsi0_bus",
+	    mout_cmu_hsi0_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI0_DPGTC, "mout_cmu_hsi0_dpgtc",
+	    mout_cmu_hsi0_dpgtc_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_DPGTC, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_USB31DRD, "mout_cmu_hsi0_usb31drd",
+	    mout_cmu_hsi0_usb31drd_p, CLK_CON_MUX_MUX_CLKCMU_HSI0_USB31DRD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI0_USBDP_DEBUG, "mout_cmu_hsi0_usbdp_debug",
+	    mout_cmu_hsi0_usbdp_debug_p,
+	    CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG, 0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_BUS, "mout_cmu_hsi1_bus",
+	    mout_cmu_hsi1_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_HSI1_MMC_CARD, "mout_cmu_hsi1_mmc_card",
+	    mout_cmu_hsi1_mmc_card_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_MMC_CARD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_PCIE, "mout_cmu_hsi1_pcie",
+	    mout_cmu_hsi1_pcie_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_PCIE, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI1_UFS_CARD, "mout_cmu_hsi1_ufs_card",
+	    mout_cmu_hsi1_ufs_card_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_CARD,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_HSI1_UFS_EMBD, "mout_cmu_hsi1_ufs_embd",
+	    mout_cmu_hsi1_ufs_embd_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_HSI2_BUS, "mout_cmu_hsi2_bus",
+	    mout_cmu_hsi2_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_HSI2_PCIE, "mout_cmu_hsi2_pcie",
+	    mout_cmu_hsi2_pcie_p, CLK_CON_MUX_MUX_CLKCMU_HSI2_PCIE, 0, 1),
+	MUX(CLK_MOUT_CMU_IPP_BUS, "mout_cmu_ipp_bus",
+	    mout_cmu_ipp_bus_p, CLK_CON_MUX_MUX_CLKCMU_IPP_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_ITP_BUS, "mout_cmu_itp_bus",
+	    mout_cmu_itp_bus_p, CLK_CON_MUX_MUX_CLKCMU_ITP_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_MCSC_BUS, "mout_cmu_mcsc_bus",
+	    mout_cmu_mcsc_bus_p, CLK_CON_MUX_MUX_CLKCMU_MCSC_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_MCSC_GDC, "mout_cmu_mcsc_gdc",
+	    mout_cmu_mcsc_gdc_p, CLK_CON_MUX_MUX_CLKCMU_MCSC_GDC, 0, 3),
+	MUX(CLK_MOUT_CMU_CMU_BOOST_CPU, "mout_cmu_cmu_boost_cpu",
+	    mout_cmu_cmu_boost_cpu_p, CLK_CON_MUX_MUX_CLKCMU_CMU_BOOST_CPU,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_MFC0_MFC0, "mout_cmu_mfc0_mfc0",
+	    mout_cmu_mfc0_mfc0_p, CLK_CON_MUX_MUX_CLKCMU_MFC0_MFC0, 0, 2),
+	MUX(CLK_MOUT_CMU_MFC0_WFD, "mout_cmu_mfc0_wfd",
+	    mout_cmu_mfc0_wfd_p, CLK_CON_MUX_MUX_CLKCMU_MFC0_WFD, 0, 2),
+	MUX(CLK_MOUT_CMU_MIF_BUSP, "mout_cmu_mif_busp",
+	    mout_cmu_mif_busp_p, CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP, 0, 2),
+	MUX(CLK_MOUT_CMU_MIF_SWITCH, "mout_cmu_mif_switch",
+	    mout_cmu_mif_switch_p, CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH, 0, 3),
+	MUX(CLK_MOUT_CMU_NPU_BUS, "mout_cmu_npu_bus",
+	    mout_cmu_npu_bus_p, CLK_CON_MUX_MUX_CLKCMU_NPU_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_PERIC0_BUS, "mout_cmu_peric0_bus",
+	    mout_cmu_peric0_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIC0_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC0_IP, "mout_cmu_peric0_ip",
+	    mout_cmu_peric0_ip_p, CLK_CON_MUX_MUX_CLKCMU_PERIC0_IP, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC1_BUS, "mout_cmu_peric1_bus",
+	    mout_cmu_peric1_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIC1_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIC1_IP, "mout_cmu_peric1_ip",
+	    mout_cmu_peric1_ip_p, CLK_CON_MUX_MUX_CLKCMU_PERIC1_IP, 0, 1),
+	MUX(CLK_MOUT_CMU_PERIS_BUS, "mout_cmu_peris_bus",
+	    mout_cmu_peris_bus_p, CLK_CON_MUX_MUX_CLKCMU_PERIS_BUS, 0, 1),
+	MUX(CLK_MOUT_CMU_SSP_BUS, "mout_cmu_ssp_bus",
+	    mout_cmu_ssp_bus_p, CLK_CON_MUX_MUX_CLKCMU_SSP_BUS, 0, 2),
+	MUX(CLK_MOUT_CMU_TNR_BUS, "mout_cmu_tnr_bus",
+	    mout_cmu_tnr_bus_p, CLK_CON_MUX_MUX_CLKCMU_TNR_BUS, 0, 3),
+	MUX(CLK_MOUT_CMU_VRA_BUS, "mout_cmu_vra_bus",
+	    mout_cmu_vra_bus_p, CLK_CON_MUX_MUX_CLKCMU_VRA_BUS, 0, 2),
+};
+
+static const struct samsung_div_clock top_div_clks[] __initconst = {
+	/* SHARED0 region*/
+	DIV(CLK_DOUT_CMU_SHARED0_DIV2, "dout_cmu_shared0_div2", "mout_pll_shared0",
+	    CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED0_DIV3, "dout_cmu_shared0_div3", "mout_pll_shared0",
+	    CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED0_DIV4, "dout_cmu_shared0_div4", "dout_cmu_shared0_div2",
+	    CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
+
+	/* SHARED1 region*/
+	DIV(CLK_DOUT_CMU_SHARED1_DIV2, "dout_cmu_shared1_div2", "mout_pll_shared1",
+	    CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED1_DIV3, "dout_cmu_shared1_div3", "mout_pll_shared1",
+	    CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED1_DIV4, "dout_cmu_shared1_div4", "dout_cmu_shared1_div2",
+	    CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
+
+	/* SHARED2 region */
+	DIV(CLK_DOUT_CMU_SHARED2_DIV2, "dout_cmu_shared2_div2", "mout_pll_shared2",
+	    CLK_CON_DIV_PLL_SHARED2_DIV2, 0, 1),
+
+	/* SHARED4 region*/
+	DIV(CLK_DOUT_CMU_SHARED4_DIV2, "dout_cmu_shared4_div2", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV2, 0, 1),
+	DIV(CLK_DOUT_CMU_SHARED4_DIV3, "dout_cmu_shared4_div3", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV3, 0, 2),
+	DIV(CLK_DOUT_CMU_SHARED4_DIV4, "dout_cmu_shared4_div4", "mout_pll_shared4",
+	    CLK_CON_DIV_PLL_SHARED4_DIV4, 0, 1),
+
+	DIV(CLK_DOUT_CMU_APM_BUS, "dout_cmu_apm_bus", "gout_cmu_apm_bus",
+	    CLK_CON_DIV_CLKCMU_APM_BUS, 0, 3),
+	DIV(CLK_DOUT_CMU_AUD_CPU, "dout_cmu_aud_cpu", "gout_cmu_aud_cpu",
+	    CLK_CON_DIV_CLKCMU_AUD_CPU, 0, 3),
+	DIV(CLK_DOUT_CMU_BUS0_BUS, "dout_cmu_bus0_bus", "gout_cmu_bus0_bus",
+	    CLK_CON_DIV_CLKCMU_BUS0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_BUS1_BUS, "dout_cmu_bus1_bus", "gout_cmu_bus1_bus",
+	    CLK_CON_DIV_CLKCMU_BUS1_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_BUS1_SSS, "dout_cmu_bus1_sss", "gout_cmu_bus1_sss",
+	    CLK_CON_DIV_CLKCMU_BUS1_SSS, 0, 4),
+	DIV(CLK_DOUT_CMU_CIS_CLK0, "dout_cmu_cis_clk0", "gout_cmu_cis_clk0",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK0, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK1, "dout_cmu_cis_clk1", "gout_cmu_cis_clk1",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK1, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK2, "dout_cmu_cis_clk2", "gout_cmu_cis_clk2",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK2, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK3, "dout_cmu_cis_clk3", "gout_cmu_cis_clk3",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK3, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK4, "dout_cmu_cis_clk4", "gout_cmu_cis_clk4",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK4, 0, 5),
+	DIV(CLK_DOUT_CMU_CIS_CLK5, "dout_cmu_cis_clk5", "gout_cmu_cis_clk5",
+	    CLK_CON_DIV_CLKCMU_CIS_CLK5, 0, 5),
+	DIV(CLK_DOUT_CMU_CMU_BOOST, "dout_cmu_cmu_boost", "mout_cmu_cmu_boost",
+	    CLK_CON_DIV_CLKCMU_CMU_BOOST, 0, 2),
+	DIV(CLK_DOUT_CMU_CORE_BUS, "dout_cmu_core_bus", "gout_cmu_core_bus",
+	    CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_CPUCL0_DBG_BUS, "dout_cmu_cpucl0_debug",
+	    "gout_cmu_cpucl0_dbg_bus", CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL0_SWITCH, "dout_cmu_cpucl0_switch",
+	    "gout_cmu_cpucl0_switch", CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL1_SWITCH, "dout_cmu_cpucl1_switch",
+	    "gout_cmu_cpucl1_switch", CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL2_BUSP, "dout_cmu_cpucl2_busp",
+	    "gout_cmu_cpucl2_busp", CLK_CON_DIV_CLKCMU_CPUCL2_BUSP, 0, 4),
+	DIV(CLK_DOUT_CMU_CPUCL2_SWITCH, "dout_cmu_cpucl2_switch",
+	    "gout_cmu_cpucl2_switch", CLK_CON_DIV_CLKCMU_CPUCL2_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_CSIS_BUS, "dout_cmu_csis_bus", "gout_cmu_csis_bus",
+	    CLK_CON_DIV_CLKCMU_CSIS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_CSIS_OIS_MCU, "dout_cmu_csis_ois_mcu",
+	    "gout_cmu_csis_ois_mcu", CLK_CON_DIV_CLKCMU_CSIS_OIS_MCU, 0, 4),
+	DIV(CLK_DOUT_CMU_DNC_BUS, "dout_cmu_dnc_bus", "gout_cmu_dnc_bus",
+	    CLK_CON_DIV_CLKCMU_DNC_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DNC_BUSM, "dout_cmu_dnc_busm", "gout_cmu_dnc_busm",
+	    CLK_CON_DIV_CLKCMU_DNC_BUSM, 0, 4),
+	DIV(CLK_DOUT_CMU_DNS_BUS, "dout_cmu_dns_bus", "gout_cmu_dns_bus",
+	    CLK_CON_DIV_CLKCMU_DNS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DSP_BUS, "dout_cmu_dsp_bus", "gout_cmu_dsp_bus",
+	    CLK_CON_DIV_CLKCMU_DSP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_G2D_G2D, "dout_cmu_g2d_g2d", "gout_cmu_g2d_g2d",
+	    CLK_CON_DIV_CLKCMU_G2D_G2D, 0, 4),
+	DIV(CLK_DOUT_CMU_G2D_MSCL, "dout_cmu_g2d_mscl", "gout_cmu_g2d_mscl",
+	    CLK_CON_DIV_CLKCMU_G2D_MSCL, 0, 4),
+	DIV(CLK_DOUT_CMU_G3D_SWITCH, "dout_cmu_g3d_switch",
+	    "gout_cmu_g3d_switch", CLK_CON_DIV_CLKCMU_G3D_SWITCH, 0, 3),
+	DIV(CLK_DOUT_CMU_HPM, "dout_cmu_hpm", "gout_cmu_hpm",
+	    CLK_CON_DIV_CLKCMU_HPM, 0, 2),
+	DIV(CLK_DOUT_CMU_HSI0_BUS, "dout_cmu_hsi0_bus", "gout_cmu_hsi0_bus",
+	    CLK_CON_DIV_CLKCMU_HSI0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI0_DPGTC, "dout_cmu_hsi0_dpgtc", "gout_cmu_hsi0_dpgtc",
+	    CLK_CON_DIV_CLKCMU_HSI0_DPGTC, 0, 3),
+	DIV(CLK_DOUT_CMU_HSI0_USB31DRD, "dout_cmu_hsi0_usb31drd",
+	    "gout_cmu_hsi0_usb31drd", CLK_CON_DIV_CLKCMU_HSI0_USB31DRD, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI0_USBDP_DEBUG, "dout_cmu_hsi0_usbdp_debug",
+	    "gout_cmu_hsi0_usbdp_debug", CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_HSI1_BUS, "dout_cmu_hsi1_bus", "gout_cmu_hsi1_bus",
+	    CLK_CON_DIV_CLKCMU_HSI1_BUS, 0, 3),
+	DIV(CLK_DOUT_CMU_HSI1_MMC_CARD, "dout_cmu_hsi1_mmc_card",
+	    "gout_cmu_hsi1_mmc_card", CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_HSI1_PCIE, "dout_cmu_hsi1_pcie", "gout_cmu_hsi1_pcie",
+	    CLK_CON_DIV_CLKCMU_HSI1_PCIE, 0, 7),
+	DIV(CLK_DOUT_CMU_HSI1_UFS_CARD, "dout_cmu_hsi1_ufs_card",
+	    "gout_cmu_hsi1_ufs_card", CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_HSI1_UFS_EMBD, "dout_cmu_hsi1_ufs_embd",
+	    "gout_cmu_hsi1_ufs_embd", CLK_CON_DIV_CLKCMU_HSI1_UFS_EMBD,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_HSI2_BUS, "dout_cmu_hsi2_bus", "gout_cmu_hsi2_bus",
+	    CLK_CON_DIV_CLKCMU_HSI2_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_HSI2_PCIE, "dout_cmu_hsi2_pcie", "gout_cmu_hsi2_pcie",
+	    CLK_CON_DIV_CLKCMU_HSI2_PCIE, 0, 7),
+	DIV(CLK_DOUT_CMU_IPP_BUS, "dout_cmu_ipp_bus", "gout_cmu_ipp_bus",
+	    CLK_CON_DIV_CLKCMU_IPP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_ITP_BUS, "dout_cmu_itp_bus", "gout_cmu_itp_bus",
+	    CLK_CON_DIV_CLKCMU_ITP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_MCSC_BUS, "dout_cmu_mcsc_bus", "gout_cmu_mcsc_bus",
+	    CLK_CON_DIV_CLKCMU_MCSC_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_MCSC_GDC, "dout_cmu_mcsc_gdc", "gout_cmu_mcsc_gdc",
+	    CLK_CON_DIV_CLKCMU_MCSC_GDC, 0, 4),
+	DIV(CLK_DOUT_CMU_CMU_BOOST_CPU, "dout_cmu_cmu_boost_cpu",
+	    "mout_cmu_cmu_boost_cpu", CLK_CON_DIV_CLKCMU_CMU_BOOST_CPU,
+	    0, 2),
+	DIV(CLK_DOUT_CMU_MFC0_MFC0, "dout_cmu_mfc0_mfc0", "gout_cmu_mfc0_mfc0",
+	    CLK_CON_DIV_CLKCMU_MFC0_MFC0, 0, 4),
+	DIV(CLK_DOUT_CMU_MFC0_WFD, "dout_cmu_mfc0_wfd", "gout_cmu_mfc0_wfd",
+	    CLK_CON_DIV_CLKCMU_MFC0_WFD, 0, 4),
+	DIV(CLK_DOUT_CMU_MIF_BUSP, "dout_cmu_mif_busp", "gout_cmu_mif_busp",
+	    CLK_CON_DIV_CLKCMU_MIF_BUSP, 0, 4),
+	DIV(CLK_DOUT_CMU_NPU_BUS, "dout_cmu_npu_bus", "gout_cmu_npu_bus",
+	    CLK_CON_DIV_CLKCMU_NPU_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC0_BUS, "dout_cmu_peric0_bus", "gout_cmu_peric0_bus",
+	    CLK_CON_DIV_CLKCMU_PERIC0_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC0_IP, "dout_cmu_peric0_ip", "gout_cmu_peric0_ip",
+	    CLK_CON_DIV_CLKCMU_PERIC0_IP, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC1_BUS, "dout_cmu_peric1_bus", "gout_cmu_peric1_bus",
+	    CLK_CON_DIV_CLKCMU_PERIC1_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIC1_IP, "dout_cmu_peric1_ip", "gout_cmu_peric1_ip",
+	    CLK_CON_DIV_CLKCMU_PERIC1_IP, 0, 4),
+	DIV(CLK_DOUT_CMU_PERIS_BUS, "dout_cmu_peris_bus", "gout_cmu_peris_bus",
+	    CLK_CON_DIV_CLKCMU_PERIS_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_SSP_BUS, "dout_cmu_ssp_bus", "gout_cmu_ssp_bus",
+	    CLK_CON_DIV_CLKCMU_SSP_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_TNR_BUS, "dout_cmu_tnr_bus", "gout_cmu_tnr_bus",
+	    CLK_CON_DIV_CLKCMU_TNR_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_VRA_BUS, "dout_cmu_vra_bus", "gout_cmu_vra_bus",
+	    CLK_CON_DIV_CLKCMU_VRA_BUS, 0, 4),
+	DIV(CLK_DOUT_CMU_DPU, "dout_cmu_clkcmu_dpu", "gout_cmu_dpu",
+	    CLK_CON_DIV_DIV_CLKCMU_DPU, 0, 4),
+};
+
+static const struct samsung_gate_clock top_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CMU_APM_BUS, "gout_cmu_apm_bus", "mout_cmu_apm_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_APM_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_AUD_CPU, "gout_cmu_aud_cpu", "mout_cmu_aud_cpu",
+	     CLK_CON_GAT_GATE_CLKCMU_AUD_CPU, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_BUS0_BUS, "gout_cmu_bus0_bus", "mout_cmu_bus0_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS0_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_BUS1_BUS, "gout_cmu_bus1_bus", "mout_cmu_bus1_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS1_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_BUS1_SSS, "gout_cmu_bus1_sss", "mout_cmu_bus1_sss",
+	     CLK_CON_GAT_GATE_CLKCMU_BUS1_SSS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK0, "gout_cmu_cis_clk0", "mout_cmu_cis_clk0",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK0, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK1, "gout_cmu_cis_clk1", "mout_cmu_cis_clk1",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK1, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK2, "gout_cmu_cis_clk2", "mout_cmu_cis_clk2",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK2, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK3, "gout_cmu_cis_clk3", "mout_cmu_cis_clk3",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK3, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK4, "gout_cmu_cis_clk4", "mout_cmu_cis_clk4",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK4, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CIS_CLK5, "gout_cmu_cis_clk5", "mout_cmu_cis_clk5",
+	     CLK_CON_GAT_GATE_CLKCMU_CIS_CLK5, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CORE_BUS, "gout_cmu_core_bus", "mout_cmu_core_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_DBG_BUS, "gout_cmu_cpucl0_dbg_bus",
+	     "mout_cmu_cpucl0_dbg_bus", CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_SWITCH, "gout_cmu_cpucl0_switch",
+	     "mout_cmu_cpucl0_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL1_SWITCH, "gout_cmu_cpucl1_switch",
+	     "mout_cmu_cpucl1_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL2_BUSP, "gout_cmu_cpucl2_busp",
+	     "mout_cmu_cpucl2_busp", CLK_CON_GAT_GATE_CLKCMU_CPUCL2_BUSP,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CPUCL2_SWITCH, "gout_cmu_cpucl2_switch",
+	     "mout_cmu_cpucl2_switch", CLK_CON_GAT_GATE_CLKCMU_CPUCL2_SWITCH,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_CSIS_BUS, "gout_cmu_csis_bus", "mout_cmu_csis_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CSIS_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_CSIS_OIS_MCU, "gout_cmu_csis_ois_mcu",
+	     "mout_cmu_csis_ois_mcu", CLK_CON_GAT_GATE_CLKCMU_CSIS_OIS_MCU,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNC_BUS, "gout_cmu_dnc_bus", "mout_cmu_dnc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DNC_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNC_BUSM, "gout_cmu_dnc_busm", "mout_cmu_dnc_busm",
+	     CLK_CON_GAT_GATE_CLKCMU_DNC_BUSM, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DNS_BUS, "gout_cmu_dns_bus", "mout_cmu_dns_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DNS_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU, "gout_cmu_dpu", "mout_cmu_dpu",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_BUS, "gout_cmu_dpu_bus", "mout_cmu_dpu_alt",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_DSP_BUS, "gout_cmu_dsp_bus", "mout_cmu_dsp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DSP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G2D_G2D, "gout_cmu_g2d_g2d", "mout_cmu_g2d_g2d",
+	     CLK_CON_GAT_GATE_CLKCMU_G2D_G2D, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G2D_MSCL, "gout_cmu_g2d_mscl", "mout_cmu_g2d_mscl",
+	     CLK_CON_GAT_GATE_CLKCMU_G2D_MSCL, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_G3D_SWITCH, "gout_cmu_g3d_switch",
+	     "fout_shared2_pll", CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HPM, "gout_cmu_hpm", "mout_cmu_hpm",
+	     CLK_CON_GAT_GATE_CLKCMU_HPM, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_BUS, "gout_cmu_hsi0_bus",
+	     "mout_cmu_hsi0_bus", CLK_CON_GAT_GATE_CLKCMU_HSI0_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_DPGTC, "gout_cmu_hsi0_dpgtc",
+	     "mout_cmu_hsi0_dpgtc", CLK_CON_GAT_GATE_CLKCMU_HSI0_DPGTC,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_USB31DRD, "gout_cmu_hsi0_usb31drd",
+	     "mout_cmu_hsi0_usb31drd", CLK_CON_GAT_GATE_CLKCMU_HSI0_USB31DRD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI0_USBDP_DEBUG, "gout_cmu_hsi0_usbdp_debug",
+	     "mout_cmu_hsi0_usbdp_debug", CLK_CON_GAT_GATE_CLKCMU_HSI0_USBDP_DEBUG,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_BUS, "gout_cmu_hsi1_bus", "mout_cmu_hsi1_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_HSI1_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_MMC_CARD, "gout_cmu_hsi1_mmc_card",
+	     "mout_cmu_hsi1_mmc_card", CLK_CON_GAT_GATE_CLKCMU_HSI1_MMC_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_PCIE, "gout_cmu_hsi1_pcie",
+	     "mout_cmu_hsi1_pcie", CLK_CON_GAT_GATE_CLKCMU_HSI1_PCIE,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_UFS_CARD, "gout_cmu_hsi1_ufs_card",
+	     "mout_cmu_hsi1_ufs_card", CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI1_UFS_EMBD, "gout_cmu_hsi1_ufs_embd",
+	     "mout_cmu_hsi1_ufs_embd", CLK_CON_GAT_GATE_CLKCMU_HSI1_UFS_EMBD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI2_BUS, "gout_cmu_hsi2_bus", "mout_cmu_hsi2_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_HSI2_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_HSI2_PCIE, "gout_cmu_hsi2_pcie",
+	     "mout_cmu_hsi2_pcie", CLK_CON_GAT_GATE_CLKCMU_HSI2_PCIE,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_IPP_BUS, "gout_cmu_ipp_bus", "mout_cmu_ipp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_IPP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_ITP_BUS, "gout_cmu_itp_bus", "mout_cmu_itp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_ITP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MCSC_BUS, "gout_cmu_mcsc_bus", "mout_cmu_mcsc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_MCSC_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MCSC_GDC, "gout_cmu_mcsc_gdc", "mout_cmu_mcsc_gdc",
+	     CLK_CON_GAT_GATE_CLKCMU_MCSC_GDC, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MFC0_MFC0, "gout_cmu_mfc0_mfc0",
+	     "mout_cmu_mfc0_mfc0", CLK_CON_GAT_GATE_CLKCMU_MFC0_MFC0,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MFC0_WFD, "gout_cmu_mfc0_wfd", "mout_cmu_mfc0_wfd",
+	     CLK_CON_GAT_GATE_CLKCMU_MFC0_WFD, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_MIF_BUSP, "gout_cmu_mif_busp", "mout_cmu_mif_busp",
+	     CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_NPU_BUS, "gout_cmu_npu_bus", "mout_cmu_npu_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_NPU_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC0_BUS, "gout_cmu_peric0_bus",
+	     "mout_cmu_peric0_bus", CLK_CON_GAT_GATE_CLKCMU_PERIC0_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC0_IP, "gout_cmu_peric0_ip",
+	     "mout_cmu_peric0_ip", CLK_CON_GAT_GATE_CLKCMU_PERIC0_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC1_BUS, "gout_cmu_peric1_bus",
+	     "mout_cmu_peric1_bus", CLK_CON_GAT_GATE_CLKCMU_PERIC1_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIC1_IP, "gout_cmu_peric1_ip",
+	     "mout_cmu_peric1_ip", CLK_CON_GAT_GATE_CLKCMU_PERIC1_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERIS_BUS, "gout_cmu_peris_bus",
+	     "mout_cmu_peris_bus", CLK_CON_GAT_GATE_CLKCMU_PERIS_BUS,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CMU_SSP_BUS, "gout_cmu_ssp_bus", "mout_cmu_ssp_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_SSP_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_TNR_BUS, "gout_cmu_tnr_bus", "mout_cmu_tnr_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_TNR_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_CMU_VRA_BUS, "gout_cmu_vra_bus", "mout_cmu_vra_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_VRA_BUS, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info top_cmu_info __initconst = {
+	.pll_clks = top_pll_clks,
+	.nr_pll_clks = ARRAY_SIZE(top_pll_clks),
+	.mux_clks = top_mux_clks,
+	.nr_mux_clks = ARRAY_SIZE(top_mux_clks),
+	.div_clks = top_div_clks,
+	.nr_div_clks = ARRAY_SIZE(top_div_clks),
+	.gate_clks = top_gate_clks,
+	.nr_gate_clks = ARRAY_SIZE(top_gate_clks),
+	.nr_clk_ids = CLKS_NR_TOP,
+	.clk_regs = top_clk_regs,
+	.nr_clk_regs = ARRAY_SIZE(top_clk_regs),
+};
+
+static void __init exynos990_cmu_top_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
+}
+
+/* Register CMU_TOP early, as it's a dependency for other early domains */
+CLK_OF_DECLARE(exynos990_cmu_top, "samsung,exynos990-cmu-top",
+	       exynos990_cmu_top_init);
+
+/* ---- CMU_HSI0 ------------------------------------------------------------ */
+
+/* Register Offset definitions for CMU_HSI0 (0x10a00000) */
+#define PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER						0x0600
+#define PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER						0x0620
+#define PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER					0x0630
+#define PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER						0x0610
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK			0x2004
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK			0x2018
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHS_ACEL_D_HSI0_IPCLKPORT_I_CLK			0x2014
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK		0x2020
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK			0x2044
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK				0x2008
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK			0x200c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK			0x2010
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK			0x201c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2			0x2024
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK			0x2028
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL			0x202c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40		0x2034
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK	0x203c
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK		0x2040
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY			0x2030
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK			0x2000
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK				0x2048
+#define CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL		0x2038
+
+static const unsigned long hsi0_clk_regs[] __initconst = {
+	PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER,
+	PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHS_ACEL_D_HSI0_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK,
+};
+
+PNAME(mout_hsi0_bus_user_p)		= { "oscclk", "dout_cmu_hsi0_bus" };
+PNAME(mout_hsi0_usb31drd_user_p)	= { "oscclk", "dout_cmu_hsi0_usb31drd" };
+PNAME(mout_hsi0_usbdp_debug_user_p)	= { "oscclk",
+					    "dout_cmu_hsi0_usbdp_debug" };
+PNAME(mout_hsi0_dpgtc_user_p)		= { "oscclk", "dout_cmu_hsi0_dpgtc" };
+
+static const struct samsung_mux_clock hsi0_mux_clks[] __initconst = {
+	MUX(CLK_MOUT_HSI0_BUS_USER, "mout_hsi0_bus_user",
+	    mout_hsi0_bus_user_p, PLL_CON0_MUX_CLKCMU_HSI0_BUS_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_USB31DRD_USER, "mout_hsi0_usb31drd_user",
+	    mout_hsi0_usb31drd_user_p, PLL_CON0_MUX_CLKCMU_HSI0_USB31DRD_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_USBDP_DEBUG_USER, "mout_hsi0_usbdp_debug_user",
+	    mout_hsi0_usbdp_debug_user_p,
+	    PLL_CON0_MUX_CLKCMU_HSI0_USBDP_DEBUG_USER,
+	    4, 1),
+	MUX(CLK_MOUT_HSI0_DPGTC_USER, "mout_hsi0_dpgtc_user",
+	    mout_hsi0_dpgtc_user_p, PLL_CON0_MUX_CLKCMU_HSI0_DPGTC_USER,
+	    4, 1),
+};
+
+static const struct samsung_gate_clock hsi0_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_HSI0_DP_LINK_DP_GTC_CLK,
+	     "gout_hsi0_dp_link_dp_gtc_clk", "mout_hsi0_dpgtc_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_DP_GTC_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_DP_LINK_PCLK,
+	     "gout_hsi0_dp_link_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_DP_LINK_IPCLKPORT_I_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK,
+	     "gout_hsi0_d_tzpc_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_D_TZPC_HSI0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_LHM_AXI_P_HSI0_CLK,
+	     "gout_hsi0_lhm_axi_p_hsi0_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHM_AXI_P_HSI0_IPCLKPORT_I_CLK,
+	     21, CLK_IS_CRITICAL, 0),
+	GATE(CLK_GOUT_HSI0_PPMU_HSI0_BUS1_ACLK,
+	     "gout_hsi0_ppmu_hsi0_bus1_aclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_PPMU_HSI0_BUS1_PCLK,
+	     "gout_hsi0_ppmu_hsi0_bus1_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_PPMU_HSI0_BUS1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK,
+	     "gout_hsi0_clk_hsi0_bus_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_RSTNSYNC_CLK_HSI0_BUS_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2,
+	     "gout_hsi0_sysmmu_usb_clk_s2", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_HSI0_SYSREG_HSI0_PCLK,
+	     "gout_hsi0_sysreg_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL,
+	     "gout_hsi0_usb31drd_aclk_phyctrl", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY,
+	     "gout_hsi0_usb31drd_bus_clk_early",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USB31DRD_REF_CLK_40,
+	     "gout_hsi0_usb31drd_usb31drd_ref_clk_40",
+	     "mout_hsi0_usb31drd_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBDPPHY_REF_SOC_PLL,
+	     "gout_hsi0_usb31drd_usbdpphy_ref_soc_pll",
+	     "mout_hsi0_usbdp_debug_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBDPPHY_SCL_APB,
+	     "gout_hsi0_usb31drd_ipclkport_i_usbdpphy_scl_apb_pclk",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_USB31DRD_USBPCS_APB_CLK,
+	     "gout_hsi0_usb31drd_usbpcs_apb_clk",
+	     "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_VGEN_LITE_HSI0_CLK,
+	     "gout_hsi0_vgen_lite_ipclkport_clk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_VGEN_LITE_HSI0_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_HSI0_CMU_HSI0_PCLK,
+	     "gout_hsi0_cmu_hsi0_pclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_HSI0_CMU_HSI0_IPCLKPORT_PCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_HSI0_XIU_D_HSI0_ACLK,
+	     "gout_hsi0_xiu_d_hsi0_aclk", "mout_hsi0_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info hsi0_cmu_info __initconst = {
+	.mux_clks = hsi0_mux_clks,
+	.nr_mux_clks = ARRAY_SIZE(hsi0_mux_clks),
+	.gate_clks = hsi0_gate_clks,
+	.nr_gate_clks = ARRAY_SIZE(hsi0_gate_clks),
+	.nr_clk_ids = CLKS_NR_HSI0,
+	.clk_regs = hsi0_clk_regs,
+	.nr_clk_regs = ARRAY_SIZE(hsi0_clk_regs),
+	.clk_name		= "bus",
+};
+
+/* ----- platform_driver ----- */
+
+static int __init exynos990_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+static const struct of_device_id exynos990_cmu_of_match[] = {
+	{
+		.compatible = "samsung,exynos990-cmu-hsi0",
+		.data = &hsi0_cmu_info,
+	},
+	{ },
+};
+
+static struct platform_driver exynos990_cmu_driver __refdata = {
+	.driver	= {
+		.name = "exynos990-cmu",
+		.of_match_table = exynos990_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = exynos990_cmu_probe,
+};
+
+static int __init exynos990_cmu_init(void)
+{
+	return platform_driver_register(&exynos990_cmu_driver);
+}
+
+core_initcall(exynos990_cmu_init);

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Mon Dec  9 06:45:20 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Mon, 09 Dec 2024 15:45:20 +0100
Subject: [PATCH v4 0/3] clk: samsung: Introduce Exynos990 clock support
Message-ID: <20241209-exynos990-cmu-v4-0-57f07080f9e4@mentallysanemainliners.org>

Hi all,

This patchset adds support for the Clock Management Unit found in the
Exynos990 SoC. This CMU allows for clocking peripherals such as USB, UFS,
MCT, et cetera.

Currently there are two blocks implemented, CMU_TOP which
generates clocks for other blocks, and CMU_HSI0, which generates clocks
for USB. More blocks will be added (hopefully soon), like HSI1 for UFS.

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
Changes in v4:
- bindings: Use one-per-line convention for clock names. (Thanks, Krzysztof!)

- Link to v3: https://lore.kernel.org/r/20241207-exynos990-cmu-v3-0-20c0f6ea02f0 at mentallysanemainliners.org

- Link to v2: https://lore.kernel.org/r/20241206-exynos990-cmu-v2-0-4666ff0a099b at mentallysanemainliners.org

---
Igor Belwon (3):
      dt-bindings: clock: Add Exynos990 SoC CMU bindings
      clk: samsung: clk-pll: Add support for pll_{0717x, 0718x, 0732x}
      clk: samsung: Introduce Exynos990 clock controller driver

 .../bindings/clock/samsung,exynos990-clock.yaml    |  121 ++
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-exynos990.c                | 1343 ++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c                      |   14 +-
 drivers/clk/samsung/clk-pll.h                      |    3 +
 include/dt-bindings/clock/samsung,exynos990.h      |  236 ++++
 6 files changed, 1716 insertions(+), 2 deletions(-)
---
base-commit: ed74808ae420a2ae611738c2d62800ab157a9ee8
change-id: 20241206-exynos990-cmu-58ada5056ad5

Best regards,
-- 
Igor Belwon <igor.belwon at mentallysanemainliners.org>



From broonie at kernel.org  Mon Dec  9 06:50:06 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 9 Dec 2024 14:50:06 +0000
Subject: [PATCH 4/4] arm64/sysreg: Get rid of CPACR_ELx SysregFields
In-Reply-To: <20241207190740.2607673-5-maz@kernel.org>
References: <20241207190740.2607673-1-maz@kernel.org>
 <20241207190740.2607673-5-maz@kernel.org>
Message-ID: <aa8a6c68-13d6-4311-8903-577cec91f8fa@sirena.org.uk>

On Sat, Dec 07, 2024 at 07:07:40PM +0000, Marc Zyngier wrote:
> There is no such thing as CPACR_ELx in the architecture.
> What we have is CPACR_EL1, for which CPTR_EL12 is an accessor.
> 
> Rename CPACR_ELx_* to CPACR_EL1_*, and fix the bit of code using
> these names.

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/20241209/3c525bd7/attachment.sig>

From konrad.dybcio at oss.qualcomm.com  Mon Dec  9 07:03:29 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Mon, 9 Dec 2024 16:03:29 +0100
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
Message-ID: <08440076-3c04-4bb1-b339-071b82d638d2@oss.qualcomm.com>

On 9.12.2024 9:19 AM, Akhil P Oommen wrote:
> When kernel is booted in EL2, SECVID registers are accessible to the
> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> on Zap firmware. Also, we can't load a secure firmware without a
> hypervisor that supports it.
> 
> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
> 
> 1. Gunyah (No KVM) - Loads zap shader based on DT
> 2. KVM in VHE - Skips zap shader load and programs SECVID register
> 3. KVM in nVHE - Loads zap shader based on DT
> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
> 	programs SECVID register
> 
> For (1) and (3) configuration, this patch doesn't have any impact.
> Driver loads secure firmware based on other existing hints.
> 
> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
> ---

[...]

> +
> +#ifdef CONFIG_ARM64
> +	/*
> +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> +	 * to switch the secure mode to avoid the dependency on zap shader.
> +	 */
> +	if (is_kernel_in_hyp_mode())
> +		goto direct_switch;

So I suppose this would ideally be like hv_is_hyperv_initialized()
but for QHEE/Gunyah, which is not going to happen, as we have
millions of devices with old unupstreamable-ABI-Gunyah running..

This looks like the next best things then, so no objections, but..

[...]

> +	ret = a6xx_switch_secure_mode(gpu);
> +	if (!ret)

this should definitely be a if (ret)

Konrad


From przemyslaw.kitszel at intel.com  Mon Dec  9 07:03:31 2024
From: przemyslaw.kitszel at intel.com (Przemek Kitszel)
Date: Mon, 9 Dec 2024 16:03:31 +0100
Subject: [PATCH v2 00/21] Converge on using secs_to_jiffies()
In-Reply-To: <95a461ca-3ed6-4380-ad1a-da12e1109675@csgroup.eu>
References: <20241115-converge-secs-to-jiffies-v2-0-911fb7595e79@linux.microsoft.com>
 <b9fcb12a-b7a4-4c33-836e-67109ce07deb@intel.com>
 <dab77729-682f-4182-9fb2-cd522ac29b5f@linux.microsoft.com>
 <72c8eb66-eb67-4f8b-b0c0-13f1aa001698@intel.com>
 <95a461ca-3ed6-4380-ad1a-da12e1109675@csgroup.eu>
Message-ID: <3113d4f4-4f8b-41d6-af89-f82cbc89da75@intel.com>

On 12/9/24 1:45 PM, Christophe Leroy wrote:
> 
> 
> Le 09/12/2024 ? 13:01, Przemek Kitszel a ?crit?:
>> On 12/6/24 9:58 PM, Easwar Hariharan wrote:
>>> On 11/29/2024 4:57 AM, Przemek Kitszel wrote:
>>>>
>>>> [removed most non-list recipients, it's just too much]
>>>>
>>>> On 11/15/24 10:26 PM, Easwar Hariharan wrote:
>>> <snip>
>>
>>>>
>>>> Regarding code - you could also convert msecs_to_jiffies(const * HZ),
>>>> there are 10 that are greppable.

Thanks to Christope, I re-examined those ~10 cases, and that should be
refactored by just dropping msec_to_jiffies() part, not replacing
by sec_to_jiffies().

>>>>
>>>
>>> Those seem to be mistakes. const*HZ is a seconds-denominated timeout,
>>> being passed to msecs_to_jiffies() which will treat it as a
>>> millisecond-denominated timeout resulting in an excessively long
>>> timeout. I suppose that's better than a too-short timeout, and
>>> apparently it's been working fine all along since hardware responds
>>> before the too-long timeout expires. Half of them are in
>>> drivers/scsi/arcmsr/arcmsr_hba.c and the pattern has apparently been
>>> there since 2010.
>>
>> my point was that, the default value of HZ is 1000, and most of the code
>> that is just `$value*HZ` was meant as "$value seconds, in ms unit".
> 
> I can't follow you here. The default value of HZ is 250 as far as I can 
> see.

as default I understand "the value that is effective for those that
don't tweak", not necessarily "the fallback that will be used when not
set by any other means". On my RedHat and Fedora boxes it's 1000.

> 
> Regardless, HZ is the number of jiffies per second, nothing else.

That is true. But the name is wrong.

> 
>>
>> Same for HZ/const, HZ/2 being 500ms.
>>
>> HZ is awful in that it is not 1s but 1/s, but it was easy to abuse the
>> value in simple context.
> 
> Why is that awful ?

so, 1Hertz = 1/1s == once per second,
something happening twice per second, with freq of 2Hz, repeats
each HZ/2 jiffies
https://en.wikipedia.org/wiki/Hertz

the #define name should be really JHZ -> JIFFIES_PER_SECOND

> 
> HZ is a nice macro that gives you the number of ticks per second, so 
> that you are able to easily calculate the number of ticks for a given 
> duration, regardless of the configured number of ticks per second.

Again, technically true, but default being eq to number of msec in sec,
causes it to bite.



From matthias.schiffer at ew.tq-group.com  Mon Dec  9 07:05:46 2024
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Mon, 09 Dec 2024 16:05:46 +0100
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and
 MBa62xx carrier board Device Trees
In-Reply-To: <d25b1447-c28b-4998-b238-92672434dc28@lunn.ch>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
	 <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
	 <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>
	 <c902a56cf34838f60cee67624bb923e91d74e9e0.camel@ew.tq-group.com>
	 <d25b1447-c28b-4998-b238-92672434dc28@lunn.ch>
Message-ID: <e16076d16349e929af82fa987a658bff1d9804c4.camel@ew.tq-group.com>

On Mon, 2024-12-09 at 15:42 +0100, Andrew Lunn wrote:
> 
> On Mon, Dec 09, 2024 at 02:55:31PM +0100, Matthias Schiffer wrote:
> > On Mon, 2024-12-09 at 14:24 +0100, Andrew Lunn wrote:
> > > 
> > > > +&cpsw_port1 {
> > > > +	phy-mode = "rgmii-rxid";
> > > > +	phy-handle = <&cpsw3g_phy0>;
> > > > +};
> > > > +
> > > > +&cpsw_port2 {
> > > > +	phy-mode = "rgmii-rxid";
> > > > +	phy-handle = <&cpsw3g_phy3>;
> > > > +};
> > > 
> > > rgmii-rxid is very odd.
> > > 
> > > > +
> > > > +&cpsw3g_mdio {
> > > > +	status = "okay";
> > > > +	pinctrl-names = "default";
> > > > +	pinctrl-0 = <&main_mdio1_pins>;
> > > > +
> > > > +	cpsw3g_phy0: ethernet-phy at 0 {
> > > > +		compatible = "ethernet-phy-ieee802.3-c22";
> > > > +		reg = <0x0>;
> > > > +		reset-gpios = <&main_gpio1 11 GPIO_ACTIVE_LOW>;
> > > > +		reset-assert-us = <1000>;
> > > > +		reset-deassert-us = <1000>;
> > > > +		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
> > > 
> > > I guess this is the explanation.
> > > 
> > > What happens when you use rgmii-id, and don't have this delay here?
> > > That would be normal.
> > > 
> > > 	Andrew
> > 
> > 
> > This is normal for AM62-based boards, see the DTSI of the TI reference
> > starterkit for example:
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi#n451
> > 
> > With rgmii-id, both ti,rx-internal-delay and ti,tx-internal-delay should be set.
> > As ti,*-internal-delay sets the delay on the PHY side, phy-mode "rgmii" is the
> > one that would not use either:
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/net/ti,dp83867.yaml#n78
> > 
> > At the end of the day, does it really matter as long as MAC and PHY agree on the
> > used mode? We copied this part of the hardware design from the TI reference
> > board, and did our hardware qualification with these settings, so I think it
> > makes sense to use the same phy-mode configuration.
> 
> What i try to achieve is every board uses the same configuration. The
> PHY adds the delays, not the MAC. There are a few exceptions, because
> a few cheap PHYs don't support delays, and so the MAC needs to add
> them. But in general, any board i review, i always ask that the PHY
> does the delay.
> 
> Also, don't put too much value in vendor code. Vendors don't care
> about Linux has a whole, being uniform across all systems. Many
> vendors do the minimum to get their stuff working, sometimes Monkeys
> typing Shakespeare, and not a lot more.
> 
> I also find a lot of developers don't really understand what phy-mode
> and PHY_INTERFACE_MODE_RGMII_* actually mean. phy-mode = 'rgmii' means
> the board has extra long clock lines, so the MAC/PHY does not need to
> add delays. rgmii-rxid means the board has an extra long rx clock
> line, but a normal length tx clock line. Now, i doubt your board is
> actually like this?

Not our board, but the AM62 SoC. From the datasheet:

"TXC is delayed internally before being driven to the RGMII[x]_TXC pin. This
internal delay is always enabled." So enabling the TX delay on the PHY side
would result in a double delay.

> 
> You want to correctly describe your hardware in DT, which i guess is
> "rgmii-id". That means something, either the MAC or the PHY needs to
> add delays. PHY_INTERFACE_MODE_RGMII_* is what is passed to the
> PHY. To get it to add the 2ns delays, you pass
> PHY_INTERFACE_MODE_RGMII_ID, and you should not need any additional
> properties in DT, it should default to 2ns. If you need to tune the
> delay, 2ns does not work, but you actually need 1.8ns etc, then you
> can add additional parameters. But given you have
> DP83867_RGMIIDCTL_2_00_NS, i doubt you need this.

No such defaults exist in the DP83867 driver. If any rgmii-*id mode is used, the
corresponding delays *must* be specified in the DTB:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/phy/dp83867.c#n532

Best regards,
Matthias


-- 
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
https://www.tq-group.com/


From dse at thaumatec.com  Mon Dec  9 07:06:08 2024
From: dse at thaumatec.com (Daniel Semkowicz)
Date: Mon,  9 Dec 2024 16:06:08 +0100
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2 controller
In-Reply-To: <20241203165450.1501219-1-heiko@sntech.de>
References: <20241203165450.1501219-1-heiko@sntech.de>
Message-ID: <20241209150619.33998-1-dse@thaumatec.com>

Hello Heiko,

On 03.12.24 21:54, Heiko Stuebner wrote:
> This series adds a bridge and glue driver for the DSI2 controller found
> in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
> 
> As the manual states:
> The Display Serial Interface 2 (DSI-2) is part of a group of communication
> protocols defined by the MIPI Alliance. The MIPI DSI-2 Host Controller is
> a digital core that implements all protocol functions defined in the
> MIPI DSI-2 Specification.
> 
> 
> While the driver structure is very similar to the previous DSI controller,
> the programming model of the core is quite different, with a completely
> new register set.
> 
> Another notable difference is that the phy interface is variable now too
> in its width and some other settings.
> 

I did more tests with different LVDS displays. I tested following
configurations with DSI/LVDS bridge:
- 1024x600 at 60.01
- 1024x768 at 60.02
- 1280x800 at 60.07
- 1366x768 at 60.06

All of them worked without issues, except 1366x768.
With this resolution, video is blurry, and offset incorrectly
to the left. There are also repeating errors on the console:

  rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3

In correct operation with other resolutions, there is no error.
I am not sure if this is a problem in your series or rather in VOP2
driver.

I tried to track down the problem, and it seems to be a generic issue
when horizontal line width is not divisible by 4.
Lowering line width to 1364px fixes the issue, but of course I have two
vertical lines of black pixels on the right.
I also made some tests with 720x1280 DSI display. Lowering horizontal
line to 718px shows the same problem. With 720px and 716px it works
correctly.

Kind regards
Daniel



From maz at kernel.org  Mon Dec  9 07:15:56 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Dec 2024 15:15:56 +0000
Subject: [PATCH 00/11] KVM: arm64: Add NV timer support
In-Reply-To: <20241209142429.882-1-chase.conklin@arm.com>
References: <20241202172134.384923-1-maz@kernel.org>
	<20241209142429.882-1-chase.conklin@arm.com>
Message-ID: <864j3cubtf.wl-maz@kernel.org>

Hi Chase,

On Mon, 09 Dec 2024 14:24:29 +0000,
Chase Conklin <chase.conklin at arm.com> wrote:
> 
> Hi Marc,
> 
> On Mon, 2 Dec 2024 17:21:23 +0000, Marc Zyngier <maz at kernel.org>
> wrote:
>
> > If you are feeling brave, you can run the whole thing from [1].
> > 
> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/nv-next
> >
> 
> I was feeling brave, and I think I see an issue in the cpufeature change
> in the kvm-arm64/nv-e2h-select branch that's a part of
> kvm-arm64/nv-next. In d75a4820a897 ("arm64: cpufeature: Handle NV_frac as a synonym of NV2"),
> I don't see NV_frac being added to the FTR bits. I believe that means it
> will get sanitized out and consequently not seen by the NV feature
> detection code. Does that commit also need:
> 
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 9fa8bd77ae0..f97459e160b 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -480,6 +480,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr3[] = {
> 
>  static const struct arm64_ftr_bits ftr_id_aa64mmfr4[] = {
>         S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR4_EL1_E2H0_SHIFT, 4, 0),
> +       S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR4_EL1_NV_frac_SHIFT, 4, 0),
>         ARM64_FTR_END,
>  };

Ah, I always get tripped by that one. You are absolutely correct, this
is needed. I'll fold that in.

Thanks again,

	M.

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


From maz at kernel.org  Mon Dec  9 07:23:27 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Dec 2024 15:23:27 +0000
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer expired
In-Reply-To: <865xntt2kv.wl-maz@kernel.org>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
	<867c89tc4q.wl-maz@kernel.org>
	<c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
	<865xntt2kv.wl-maz@kernel.org>
Message-ID: <8634iwubgw.wl-maz@kernel.org>

On Mon, 09 Dec 2024 13:20:48 +0000,
Marc Zyngier <maz at kernel.org> wrote:
> 
> So here's my current guess, since you don't give me the needed
> information. For what you describe to happen, I can only see two
> possibilities:
> 
> - either your HW doesn't have FEAT_ECV, in which case the guest
>   directly reads from memory
> 
> - or you are running with something like this patch [1], and we serve
>   the guest by reading from memory very early, without returning to
>   the bulk of the emulation code
> 
> In either case, we only publish the updated status if the current IRQ
> state is different from the computed output of the timer while
> performing the emulation.
> 
> So if you were writing back a status bit set to 0 while the interrupt
> was already pending, we'd deliver an interrupt, but not recompute the
> status. The guest would consider the interrupt as spurious, not touch
> the timer, and we'd never make forward progress. Rinse, repeat.
> 
> Assuming I got the analysis right, it would only be a matter of
> hoisting the publication of the status into timer_emulate(), so that
> it is made up to date on load.
> 
> Please give the fixup below a go.

Plus this on top for a good measure:

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 91bda986c344b..c71193a7bb9c5 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -968,9 +968,6 @@ void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
 	 * which allows trapping of the timer registers even with NV2.
 	 * Still, this is still worse than FEAT_NV on its own. Meh.
 	 */
-	if (cpus_have_final_cap(ARM64_HAS_ECV) || !is_hyp_ctxt(vcpu))
-		return;
-
 	if (!vcpu_el2_e2h_is_set(vcpu)) {
 		/*
 		 * A non-VHE guest hypervisor doesn't have any direct access
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index ff62b8b55b46e..1b8bb30dbb2ff 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1257,7 +1257,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
 			kvm_timer_sync_user(vcpu);
 
-		if (vcpu_has_nv(vcpu))
+		if (is_hyp_ctxt(vcpu))
 			kvm_timer_sync_nested(vcpu);
 
 		kvm_arch_vcpu_ctxsync_fp(vcpu);


	M.

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


From acme at kernel.org  Mon Dec  9 07:26:46 2024
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 9 Dec 2024 12:26:46 -0300
Subject: [PATCH v4 2/2] perf arm-spe: Add support for SPE Data Source
 packet on AmpereOne
In-Reply-To: <20241108145138.GF47850@e132581.arm.com>
References: <20241108010911.58412-1-ilkka@os.amperecomputing.com>
 <20241108010911.58412-3-ilkka@os.amperecomputing.com>
 <20241108145138.GF47850@e132581.arm.com>
Message-ID: <Z1cMNiWELdUJy2QH@x1>

On Fri, Nov 08, 2024 at 02:51:38PM +0000, Leo Yan wrote:
> On Fri, Nov 08, 2024 at 01:09:11AM +0000, Ilkka Koskinen wrote:
> > 
> > Decode SPE Data Source packets on AmpereOne. The field is IMPDEF.
> > 
> > Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> 
> Reviewed-by: Leo Yan <leo.yan at arm.com>

Thanks, applied to perf-tools-next,

- Arnaldo
 
> > ---
> >  .../util/arm-spe-decoder/arm-spe-decoder.h    |  9 ++++
> >  tools/perf/util/arm-spe.c                     | 44 +++++++++++++++++++
> >  2 files changed, 53 insertions(+)
> > 
> > diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
> > index 358c611eeddb..4bcd627e859f 100644
> > --- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
> > +++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
> > @@ -67,6 +67,15 @@ enum arm_spe_common_data_source {
> >         ARM_SPE_COMMON_DS_DRAM          = 0xe,
> >  };
> > 
> > +enum arm_spe_ampereone_data_source {
> > +       ARM_SPE_AMPEREONE_LOCAL_CHIP_CACHE_OR_DEVICE    = 0x0,
> > +       ARM_SPE_AMPEREONE_SLC                           = 0x3,
> > +       ARM_SPE_AMPEREONE_REMOTE_CHIP_CACHE             = 0x5,
> > +       ARM_SPE_AMPEREONE_DDR                           = 0x7,
> > +       ARM_SPE_AMPEREONE_L1D                           = 0x8,
> > +       ARM_SPE_AMPEREONE_L2D                           = 0x9,
> > +};
> > +
> >  struct arm_spe_record {
> >         enum arm_spe_sample_type type;
> >         int err;
> > diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
> > index dfb0c07cb7fe..df84933b673d 100644
> > --- a/tools/perf/util/arm-spe.c
> > +++ b/tools/perf/util/arm-spe.c
> > @@ -455,8 +455,14 @@ static const struct midr_range common_ds_encoding_cpus[] = {
> >         {},
> >  };
> > 
> > +static const struct midr_range ampereone_ds_encoding_cpus[] = {
> > +       MIDR_ALL_VERSIONS(MIDR_AMPERE1A),
> > +       {},
> > +};
> > +
> >  static const struct data_source_handle data_source_handles[] = {
> >         DS(common_ds_encoding_cpus, data_source_common),
> > +       DS(ampereone_ds_encoding_cpus, data_source_ampereone),
> >  };
> > 
> >  static void arm_spe__sample_flags(struct arm_spe_queue *speq)
> > @@ -548,6 +554,44 @@ static void arm_spe__synth_data_source_common(const struct arm_spe_record *recor
> >         }
> >  }
> > 
> > +/*
> > + * Source is IMPDEF. Here we convert the source code used on AmpereOne cores
> > + * to the common (Neoverse, Cortex) to avoid duplicating the decoding code.
> > + */
> > +static void arm_spe__synth_data_source_ampereone(const struct arm_spe_record *record,
> > +                                                union perf_mem_data_src *data_src)
> > +{
> > +       struct arm_spe_record common_record;
> > +
> > +       switch (record->source) {
> > +       case ARM_SPE_AMPEREONE_LOCAL_CHIP_CACHE_OR_DEVICE:
> > +               common_record.source = ARM_SPE_COMMON_DS_PEER_CORE;
> > +               break;
> > +       case ARM_SPE_AMPEREONE_SLC:
> > +               common_record.source = ARM_SPE_COMMON_DS_SYS_CACHE;
> > +               break;
> > +       case ARM_SPE_AMPEREONE_REMOTE_CHIP_CACHE:
> > +               common_record.source = ARM_SPE_COMMON_DS_REMOTE;
> > +               break;
> > +       case ARM_SPE_AMPEREONE_DDR:
> > +               common_record.source = ARM_SPE_COMMON_DS_DRAM;
> > +               break;
> > +       case ARM_SPE_AMPEREONE_L1D:
> > +               common_record.source = ARM_SPE_COMMON_DS_L1D;
> > +               break;
> > +       case ARM_SPE_AMPEREONE_L2D:
> > +               common_record.source = ARM_SPE_COMMON_DS_L2;
> > +               break;
> > +       default:
> > +               pr_warning_once("AmpereOne: Unknown data source (0x%x)\n",
> > +                               record->source);
> > +               return;
> > +       }
> > +
> > +       common_record.op = record->op;
> > +       arm_spe__synth_data_source_common(&common_record, data_src);
> > +}
> > +
> >  static void arm_spe__synth_memory_level(const struct arm_spe_record *record,
> >                                         union perf_mem_data_src *data_src)
> >  {
> > --
> > 2.47.0
> > 
> > 


From arnd at arndb.de  Mon Dec  9 07:27:14 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 09 Dec 2024 16:27:14 +0100
Subject: [PATCH v2 2/2] firmware/arm_ffa: remove __le64_to_cpu() when set uuid for
 direct msg v2
In-Reply-To: <20241203143109.1030514-3-yeoreum.yun@arm.com>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
 <20241203143109.1030514-3-yeoreum.yun@arm.com>
Message-ID: <9e60e996-070e-43a7-80e9-efdfda9f6223@app.fastmail.com>

On Tue, Dec 3, 2024, at 15:31, Yeoreum Yun wrote:
> From: Levi Yun <yeoreum.yun at arm.com>

I just saw this commit in the pull request, and I'm very
confused because the description does not match the
patch contents.

> Accoding to FF-A specification[0] 15.4 FFA_MSG_SEND_DRIECT_REQ2,
> then UUID is saved in register:
>     UUID Lo  x2  Bytes[0...7] of UUID with byte 0 in the low-order bits.
>     UUID Hi  x3  Bytes[8...15] of UUID with byte 8 in the low-order bits.

The specification you cite here clearly describes little-endian
format, i.e. the low-order byte corresponds to the first
memory address.

> That means, we don't need to swap the uuid when it send via direct
> message request version 2, just send it as saved in memory.

"As saved in memory" does not sound like a useful description
when passing arguments through registers, as the register
contents are not defined in terms of byte offsets.

Can you describe what bug you found? If the byteorder on
big-endian kernels is wrong in the current version and your
patch fixes it, it sounds like the specification needs to
be updated describe both big-endian and little-endian
byte-order, and how the firmware detects which one is used.

> Remove le64_to_cpu() for uuid in direct message request version 2,
> and change uuid_regs' type to unsigned long.

'unsigned long' makes the code unnecessarily incompatible
with 32-bit builds.

     Arnd


From gankulkarni at os.amperecomputing.com  Mon Dec  9 07:39:28 2024
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Mon, 9 Dec 2024 21:09:28 +0530
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer
 expired
In-Reply-To: <865xntt2kv.wl-maz@kernel.org>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
 <867c89tc4q.wl-maz@kernel.org>
 <c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
 <865xntt2kv.wl-maz@kernel.org>
Message-ID: <8be59ff3-6a68-48e1-8181-0ce4b2e7180f@os.amperecomputing.com>



On 09-12-2024 06:50 pm, Marc Zyngier wrote:
> On Mon, 09 Dec 2024 12:25:34 +0000,
> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
>>>>
>>>> During automated testing of Nested Virtualization using avocado-vt,
>>>
>>> Which is not merged upstream. So what branch are you using? Based on
>>> what kernel version? On what HW? With which virtualisation features?
>>>
>>
>> Testing is done on Ampere's AmpereOne platform using 6.10 based kernel
>> with NV patches from your repo.
> 
> Grmbl... *Which* patches? At least give me the SHA1 of the branch,
> because I have no idea what you are running. And 6.10 is definitely
> not something I care about. If you're using the NV patches, the
> *minimum* you should run is 6.13-rc1, because that's what the current
> code is based on.
> 

I tried 6.13-rc1 based nv-next branch today, which failed to boot
UEFI as L1. Yet to debug this.


QEMU from Eric's repo is used for the testing.
https://github.com/eauger/qemu/tree/v9.0-nv-rfcv3

> Also, does this machine have FEAT_ECV?

Yes!
> 
>>
>>>> it has been observed that during some boot test iterations,
>>>> the Guest-Hypervisor boot was getting crashed with a
>>>> synchronous exception while it is still booting EDK2.
>>>>
>>>> The test is launching Multiple instances of Guest-Hypervisor boot
>>>
>>> Is the multiple instance aspect really relevant to the reproduction of
>>> the problem?
>>
>> Not really, but it requires multiple attempts/iterations to hit the
>> issue. Even with automated test, it was seen at some iteration out of
>> 10 to 15 iterations.
>>
>>>
>>>> and while booting, QEMU monitor issued the command "info register"
>>>> at regular intervals to take a register dump. To execute this
>>>> command, QEMU stops the run and does the register read of various
>>>> registers. While resuming the run, the function kvm_arm_timer_write()
>>>> writes back the saved CNTV_CTL_EL0 register with ISTATUS cleared always
>>>
>>> It is userspace that causes this write-back, right? AFAICT, KVM never
>>> does that on its own.
>>>
>>>> and resulting in the loss of pending interrupt for emulated timers.
>>>
>>> How does a missing interrupt result in a synchronous exception in
>>> EDK2? In my experience, EDK2 panics if it sees spurious interrupts,
>>> not when it is missing interrupts (it just locks up, which is
>>> expected).
>>
>> Not sure, why it is hitting exception, rather than hang at EDK2.
>> However, EDK2 timer handler code is ignoring the interrupt since
>> ISTATUS is not set and not moving CVAL forward.
> 
> How is EDK2 getting this exception? Is this injected by KVM? Or is
> that some EDK2 bug?
> 
>>
>>>
>>>> In hardware based timers, ISTATUS is a RO/WI bit and gets set by the
>>>> h/w, if the condition is still met. However, in Nested-Virtualization
>>>> case, the Guest-Hypervisor's?EDK2 is using an emulated virtual timer
>>>> and losing ISTATUS state and the interrupt forever.
>>>
>>> Why is this specific to NV? Can't the same thing happen to the
>>> physical timer in a non-VHE configuration?
>>>
>>
>> You mean, emulated v-timer in non-VHE boot?
> 
> Emulated *physical* timer.
> 
>> It might impact non-VHE case as well, not tried though.
> 
> Can you please try?

Sure, I will try non-VHE as well.
> 
> [...]
> 
>>> But overall, this very much looks like it is only papering over the
>>> real issue, which is that the *emulation* should regenerate the
>>> pending bit, and not rely on the userspace interface.
>>>
>>> As far as I can tell, we already correctly compute the status bit on
>>> read (read_timer_ctl()), so the guest should always observe something
>>> consistent when it traps. We also *never* use the status bit as an
>>> input to the emulation, and always recompute it from scratch (it is
>>> only there for the benefit of the guest or userspace).
>>>
>>
>> For emulated timers, we are not asserting again by calling
>> kvm_timer_update_irq in timer_emulate() until the level is down and
>> ready for trigger again. This was done to fix high rate of spurious
>> interrupts getting generated to V-Timer. Hence we are not able to
>> recover, if once ISTATUS is lost.
> 
> Again, a trapping read should see the correct value, since we populate
> that bit at read time.
> 
>>> So I can't see how upstream is broken in at the moment, and you need
>>> to explain how this actually triggers. Ideally, with a standalone
>>> reproducer or a selftest.
>>
>> We could reproduce the issue with the simple test/script.
>> On one shell, launch L1 using qemu with add-on option
>>
>> "-monitor unix:gh_monitor,server,nowait
>>
>> On another shell, while L1 boots and still in UEFI, run repeatedly the
>> command (or put in a while 1 loop script)
>>
>> "echo "info registers" | socat - unix-connect:gh_monitor >
>> /tmp/info_registers"
>>
>> With above steps we were able to hit the issue within few attempts.
> 
> That's not a standalone reproducer. QEMU doesn't support NV, and
> kvmtool doesn't have this sort of interface. I was asking for a bit of
> C code that I could run directly, not something that requires me to
> drag even more experimental code.
> 
> So here's my current guess, since you don't give me the needed
> information. For what you describe to happen, I can only see two
> possibilities:
> 
> - either your HW doesn't have FEAT_ECV, in which case the guest
>    directly reads from memory
> 

We do have the FEAT_ECV on AmpereOne, I was the one reported/fixed bug 
with FEAT_ECV(CNTPOFF offset issue) in the past.

> - or you are running with something like this patch [1], and we serve
>    the guest by reading from memory very early, without returning to
>    the bulk of the emulation code

I see the kernel I am testing has this patch[1].
> 
> In either case, we only publish the updated status if the current IRQ
> state is different from the computed output of the timer while
> performing the emulation.
> 
> So if you were writing back a status bit set to 0 while the interrupt
> was already pending, we'd deliver an interrupt, but not recompute the
> status. The guest would consider the interrupt as spurious, not touch
> the timer, and we'd never make forward progress. Rinse, repeat.
> 
> Assuming I got the analysis right, 

Yes, this is what I tried to explain. LR shows pending, but UEFI is not 
consuming and treating it as spurious since ISTATUS is not set.

it would only be a matter of
> hoisting the publication of the status into timer_emulate(), so that
> it is made up to date on load.
> 
> Please give the fixup below a go.
> 

Sure, I will give a try with below diff and let you know tomorrow.
This should work, I remember, this was the one of the option/fix that we 
tried as fix while debugging.

> 
> [1] https://lore.kernel.org/all/20241202172134.384923-6-maz at kernel.org/
> 
>  From 2bbd6f9b41a20ad573376c20c158ff3c12db5009 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <maz at kernel.org>
> Date: Mon, 9 Dec 2024 10:58:08 +0000
> Subject: [PATCH] fixup! KVM: arm64: nv: Publish emulated timer interrupt state
>   in the in-memory state
> 
> ---
>   arch/arm64/kvm/arch_timer.c | 32 +++++++++++++-------------------
>   1 file changed, 13 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 895f09658ef83..91bda986c344b 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -432,25 +432,6 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
>   {
>   	int ret;
>   
> -	/*
> -	 * Paper over NV2 brokenness by publishing the interrupt status
> -	 * bit. This still results in a poor quality of emulation (guest
> -	 * writes will have no effect until the next exit).
> -	 *
> -	 * But hey, it's fast, right?
> -	 */
> -	if (is_hyp_ctxt(vcpu) &&
> -	    (timer_ctx == vcpu_vtimer(vcpu) || timer_ctx == vcpu_ptimer(vcpu))) {
> -		u32 ctl = timer_get_ctl(timer_ctx);
> -
> -		if (new_level)
> -			ctl |= ARCH_TIMER_CTRL_IT_STAT;
> -		else
> -			ctl &= ~ARCH_TIMER_CTRL_IT_STAT;
> -
> -		timer_set_ctl(timer_ctx, ctl);
> -	}
> -
>   	timer_ctx->irq.level = new_level;
>   	trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_irq(timer_ctx),
>   				   timer_ctx->irq.level);
> @@ -471,6 +452,19 @@ static void timer_emulate(struct arch_timer_context *ctx)
>   
>   	trace_kvm_timer_emulate(ctx, should_fire);
>   
> +	/*
> +	 * Paper over NV2 brokenness by publishing the interrupt status
> +	 * bit. This still results in a poor quality of emulation (guest
> +	 * writes will have no effect until the next exit).
> +	 *
> +	 * But hey, it's fast, right?
> +	 */
> +	if (is_hyp_ctxt(ctx->vcpu)) {
> +		unsigned long val = timer_get_ctl(ctx);
> +		__assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &val, should_fire);
> +		timer_set_ctl(ctx, val);
> +	}
> +
>   	if (should_fire != ctx->irq.level) {
>   		kvm_timer_update_irq(ctx->vcpu, should_fire, ctx);
>   		return;

-- 
Thanks,
Ganapat/GK



From will at kernel.org  Mon Dec  9 07:40:16 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Dec 2024 15:40:16 +0000
Subject: [PATCH v12 4/5] drivers/perf: add DesignWare PCIe PMU driver
In-Reply-To: <20241206165457.GA3101599@bhelgaas>
References: <20231208025652.87192-5-xueshuai@linux.alibaba.com>
 <20241206165457.GA3101599@bhelgaas>
Message-ID: <20241209154015.GA12428@willie-the-truck>

Hi Bjorn,

On Fri, Dec 06, 2024 at 10:54:57AM -0600, Bjorn Helgaas wrote:
> On Fri, Dec 08, 2023 at 10:56:51AM +0800, Shuai Xue wrote:
> > This commit adds the PCIe Performance Monitoring Unit (PMU) driver support
> > for T-Head Yitian SoC chip. Yitian is based on the Synopsys PCI Express
> > Core controller IP which provides statistics feature. The PMU is a PCIe
> > configuration space register block provided by each PCIe Root Port in a
> > Vendor-Specific Extended Capability named RAS D.E.S (Debug, Error
> > injection, and Statistics).
> 
> > +#define DWC_PCIE_VSEC_RAS_DES_ID		0x02
> 
> > +static const struct dwc_pcie_vendor_id dwc_pcie_vendor_ids[] = {
> > +	{.vendor_id = PCI_VENDOR_ID_ALIBABA },
> > +	{} /* terminator */
> > +};
> 
> > +static bool dwc_pcie_match_des_cap(struct pci_dev *pdev)
> > +{
> > +	const struct dwc_pcie_vendor_id *vid;
> > +	u16 vsec;
> > +	u32 val;
> > +
> > +	if (!pci_is_pcie(pdev) || !(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT))
> > +		return false;
> > +
> > +	for (vid = dwc_pcie_vendor_ids; vid->vendor_id; vid++) {
> > +		vsec = pci_find_vsec_capability(pdev, vid->vendor_id,
> > +						DWC_PCIE_VSEC_RAS_DES_ID);
> 
> This looks wrong to me, and it promotes a misunderstanding of how VSEC
> Capabilities work.  The VSEC ID is defined by the vendor, so we have
> to check both the Vendor ID and the VSEC ID before we know what this
> VSEC Capability is.

Thanks for pointing this out! The code's been merged for a while now,
so we'll need to fix what we have rather than revert it, I think.

[...]

> I think the table should be extended to contain the Vendor ID, *and*
> the VSEC ID, *and* the VSEC Rev used by that vendor, i.e., it should
> look like this:
> 
>   struct dwc_pcie_pmu_vsec {
>     u16 vendor_id;
>     u16 vsec_id;
>     u8 vsec_rev;
>   };
> 
>   struct dwc_pcie_pmu_vsec dwc_pcie_pmu_vsec_ids[] = {
>     { .vendor_id = PCI_VENDOR_ID_ALIBABA,
>       .vsec_id = DWC_PCIE_VSEC_RAS_DES_ID, .vsec_rev = 0x4 },
>     { .vendor_id = PCI_VENDOR_ID_AMPERE,
>       .vsec_id = DWC_PCIE_VSEC_RAS_DES_ID, .vsec_rev = 0x4 },
>     { .vendor_id = PCI_VENDOR_ID_QCOM,
>       .vsec_id = DWC_PCIE_VSEC_RAS_DES_ID, .vsec_rev = 0x4 },
>     {}
>   };
> 
> This *looks* the same, but it's not, because it makes it obvious that
> the VSEC ID and VSEC Rev are defined separately by each vendor.  It's
> just a lucky coincidence that they happen to be the same for these
> vendors.

[...]

> I suggest updating dwc_pcie_match_des_cap() to iterate through the
> dwc_pcie_pmu_vsec_ids[] table and return the capability offset so you
> can call it from here.

Any chance you could send a patch with those, please? I'm also not able
to test this stuff, but I'm sure Ilkka would help us out.

Cheers,

Will


From will at kernel.org  Mon Dec  9 07:44:20 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Dec 2024 15:44:20 +0000
Subject: [PATCH v2] perf: imx9_perf: Introduce AXI filter version to
 refactor the driver and better extension
In-Reply-To: <20241125104338.2433339-1-xu.yang_2@nxp.com>
References: <20241125104338.2433339-1-xu.yang_2@nxp.com>
Message-ID: <20241209154419.GB12428@willie-the-truck>

On Mon, Nov 25, 2024 at 06:43:38PM +0800, Xu Yang wrote:
> The imx93 is the first supported DDR PMU that supports read transaction,
> write transaction and read beats events which corresponding respecitively
> to counter 2, 3 and 4.
> 
> However, transaction-based AXI match has low accuracy when get total bits
> compared to beats-based. And imx93 doesn't assign AXI_ID to each master.
> So axi filter is not used widely on imx93. This could be regards as AXI
> filter version 1.
> 
> To improve the AXI filter capability, imx95 supports 1 read beats and 3
> write beats event which corresponding respecitively to counter 2-5. imx95
> also detailed AXI_ID allocation so that most of the master could be count
> individually. This could be regards as AXI filter version 2.
> 
> This will introduce AXI filter version to refactor the driver and support
> better extension, such as coming imx943.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v2:
>  - modify subject
>  - add comments for AXI_FILTER version
>  - type -> filter_ver
> ---
>  drivers/perf/fsl_imx9_ddr_perf.c | 33 ++++++++++++++++++++++++--------
>  1 file changed, 25 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
> index 3c856d9a4e97..e2c2c674b6d2 100644
> --- a/drivers/perf/fsl_imx9_ddr_perf.c
> +++ b/drivers/perf/fsl_imx9_ddr_perf.c
> @@ -63,8 +63,21 @@
>  
>  static DEFINE_IDA(ddr_ida);
>  
> +/*
> + * V1 support 1 read transaction, 1 write transaction and 1 read beats
> + * event which corresponding respecitively to counter 2, 3 and 4.
> + */
> +#define DDR_PERF_AXI_FILTER_V1		0x1
> +
> +/*
> + * V2 support 1 read beats and 3 write beats events which corresponding
> + * respecitively to counter 2-5.
> + */
> +#define DDR_PERF_AXI_FILTER_V2		0x2
> +
>  struct imx_ddr_devtype_data {
>  	const char *identifier;		/* system PMU identifier for userspace */
> +	unsigned int filter_ver;	/* AXI filter version */
>  };
>  
>  struct ddr_pmu {
> @@ -83,24 +96,27 @@ struct ddr_pmu {
>  
>  static const struct imx_ddr_devtype_data imx91_devtype_data = {
>  	.identifier = "imx91",
> +	.filter_ver = DDR_PERF_AXI_FILTER_V1
>  };

[...]

> -static inline bool is_imx93(struct ddr_pmu *pmu)
> +static inline bool axi_filter_v1(struct ddr_pmu *pmu)
>  {
> -	return pmu->devtype_data == &imx93_devtype_data;
> +	return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V1;
>  }

[...]

> @@ -624,11 +641,11 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
>  	hwc->idx = counter;
>  	hwc->state |= PERF_HES_STOPPED;
>  
> -	if (is_imx93(pmu))
> +	if (axi_filter_v1(pmu))
>  		/* read trans, write trans, read beat */
>  		imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);

Hmm, doesn't this change mean we now enable this for imx91 as well? My
reading of the commit message is that imx93 was the first chip which
supports this.

Will


From maz at kernel.org  Mon Dec  9 07:45:43 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Dec 2024 15:45:43 +0000
Subject: [PATCH v3 3/3] arm64: paravirt: Enable errata based on implementation CPUs
In-Reply-To: <d92ea2dcc3b04ebb8bc5ba71bff448bc@huawei.com>
References: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com>
	<20241209115311.40496-4-shameerali.kolothum.thodi@huawei.com>
	<875xnt10oj.fsf@redhat.com>
	<d92ea2dcc3b04ebb8bc5ba71bff448bc@huawei.com>
Message-ID: <861pyguafs.wl-maz@kernel.org>

On Mon, 09 Dec 2024 13:49:07 +0000,
Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com> wrote:
> 
> 
> 
> > -----Original Message-----
> > From: Cornelia Huck <cohuck at redhat.com>
> > Sent: Monday, December 9, 2024 12:49 PM
> > To: Shameerali Kolothum Thodi
> > <shameerali.kolothum.thodi at huawei.com>; kvmarm at lists.linux.dev;
> > maz at kernel.org; oliver.upton at linux.dev
> > Cc: catalin.marinas at arm.com; will at kernel.org; mark.rutland at arm.com;
> > eric.auger at redhat.com; yuzenghui <yuzenghui at huawei.com>; Wangzhou
> > (B) <wangzhou1 at hisilicon.com>; jiangkunkun <jiangkunkun at huawei.com>;
> > Jonathan Cameron <jonathan.cameron at huawei.com>; Anthony Jebson
> > <anthony.jebson at huawei.com>; linux-arm-kernel at lists.infradead.org;
> > Linuxarm <linuxarm at huawei.com>
> > Subject: Re: [PATCH v3 3/3] arm64: paravirt: Enable errata based on
> > implementation CPUs
> > 
> > On Mon, Dec 09 2024, Shameer Kolothum
> > <shameerali.kolothum.thodi at huawei.com> wrote:
> > 
> > > Retrieve any migration target implementation CPUs using the hypercall
> > > and enable associated errata.
> > >
> > > Signed-off-by: Shameer Kolothum
> > <shameerali.kolothum.thodi at huawei.com>
> > > ---
> > > Note:
> > >
> > > One thing I am not sure here is how to handle the hypercall error.
> > > Do we need to fail the Guest boot or just carry on without any
> > > target implementation CPU support? At the moment it just carries on.
> > >
> > > Thanks,
> > > Shameer
> > > ---
> > >  arch/arm64/include/asm/cputype.h  | 25 +++++++++++++++++++++++--
> > >  arch/arm64/include/asm/paravirt.h |  3 +++
> > >  arch/arm64/kernel/cpu_errata.c    | 20 +++++++++++++++++---
> > >  arch/arm64/kernel/cpufeature.c    |  2 ++
> > >  arch/arm64/kernel/image-vars.h    |  2 ++
> > >  arch/arm64/kernel/paravirt.c      | 31
> > +++++++++++++++++++++++++++++++
> > >  6 files changed, 78 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/arch/arm64/include/asm/cputype.h
> > b/arch/arm64/include/asm/cputype.h
> > > index dcf0e1ce892d..9e466f3ae9c6 100644
> > > --- a/arch/arm64/include/asm/cputype.h
> > > +++ b/arch/arm64/include/asm/cputype.h
> > > @@ -265,6 +265,16 @@ struct midr_range {
> > >  #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r)
> > >  #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
> > >
> > > +#define MAX_TARGET_IMPL_CPUS 64
> > > +
> > > +struct target_impl_cpu {
> > > +	u32 midr;
> > > +	u32 revidr;
> > > +};
> > 
> > Doesn't this need to be u64 for both (even if the upper bits for
> > MIDR_EL1 are reserved?)
> 
> Yes, both are u64 as per specification with upper bits reserved. And the 
> external hypercall interface has uint64.
> 
> But in kernel, AFAICS, at present all the _midr_range_() functions expect u32.
> So not sure we gain much now by changing to u64.

For MIDR_EL1, I don't think that's a problem as long as we make sure
this is a kernel-private representation, and that it doesn't leak to
userspace or the PV interface.

For REVIDR_EL1, it *is* a problem, as the whole register is IMPDEF,
and an implementation could legitimately use the top bits.

So at this stage, it probably makes sense to keep both as 64bit
values.

Thanks,

	M.

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


From will at kernel.org  Mon Dec  9 07:48:30 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Dec 2024 15:48:30 +0000
Subject: [PATCH v4 08/10] drivers/perf: hisi: Export associated CPUs of
 each PMU through sysfs
In-Reply-To: <20241203125049.39458-9-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
 <20241203125049.39458-9-yangyicong@huawei.com>
Message-ID: <20241209154830.GC12428@willie-the-truck>

On Tue, Dec 03, 2024 at 08:50:47PM +0800, Yicong Yang wrote:
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> Although the event of the uncore PMU can only be opened on a single
> CPU, some PMU does have the affinity on a range of CPUs. For example
> the L3C PMU is associated to the CPUs sharing the L3T it monitors.
> Users may infer this affinity by the PMU name which may have SCCL ID
> and CCL ID encoded (for L3C etc), but it's not that straightforward.
> So export this information by adding an "associated_cpus" sysfs
> attribute then user can get this directly.
> 
> Reviewed-by: Jonathan Cameron <Joanthan.Cameron at huawei.com>
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>  Documentation/admin-guide/perf/hisi-pmu.rst |  5 ++++-
>  drivers/perf/hisilicon/hisi_uncore_pmu.c    | 10 ++++++++++
>  2 files changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
> index 5cc248d18c63..48992a0b8e94 100644
> --- a/Documentation/admin-guide/perf/hisi-pmu.rst
> +++ b/Documentation/admin-guide/perf/hisi-pmu.rst
> @@ -35,7 +35,10 @@ e.g. hisi_sccl1_hha0/rx_operations is RX_OPERATIONS event of HHA index #0 in
>  SCCL ID #1.
>  
>  The driver also provides a "cpumask" sysfs attribute, which shows the CPU core
> -ID used to count the uncore PMU event.
> +ID used to count the uncore PMU event. An "associated_cpus" sysfs attribute is
> +also provided to show the CPUs associated with this PMU. The "cpumask" indicates
> +the CPUs to open the events, usually as a hint for userspaces tools like perf.
> +It only contains one associated CPU from the "associated_cpus".

What is userspace expected to do with this information? Can you point me
to patches that add the corresponding support to the 'perf' tool, please?

Will


From cki-project at redhat.com  Mon Dec  9 07:53:03 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Mon, 09 Dec 2024 15:53:03 -0000
Subject: =?utf-8?b?4p2M?= FAIL (MISSED 1 of 69): Test report for for-kernelci
 (6.13.0-rc2, upstream-arm-next, fac04efc)
Message-ID: <71532.124120910530600980@us-mta-669.us.mimecast.lan>

Hi, we tested your kernel and here are the results:

    Overall result: FAILED
             Merge: OK
           Compile: OK
              Test: FAILED


Kernel information:
    Commit message: Linux 6.13-rc2

You can find all the details about the test run at
    https://datawarehouse.cki-project.org/kcidb/checkouts/redhat:1580192248

One or more kernel tests failed:
    Unrecognized or new issues:
        Reboot test
             aarch64
                   Logs: https://datawarehouse.cki-project.org/kcidb/tests/redhat:1580192248-aarch64-kernel_upt_53
                   Non-passing ran subtests:
                       ? FAIL /10_avc_check


Tests that were not ran because of internal issues: 
    machineinfo [aarch64]


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 maz at kernel.org  Mon Dec  9 07:52:19 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Dec 2024 15:52:19 +0000
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer expired
In-Reply-To: <8be59ff3-6a68-48e1-8181-0ce4b2e7180f@os.amperecomputing.com>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
	<867c89tc4q.wl-maz@kernel.org>
	<c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
	<865xntt2kv.wl-maz@kernel.org>
	<8be59ff3-6a68-48e1-8181-0ce4b2e7180f@os.amperecomputing.com>
Message-ID: <86zfl4svkc.wl-maz@kernel.org>

On Mon, 09 Dec 2024 15:39:28 +0000,
Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> 
> 
> 
> On 09-12-2024 06:50 pm, Marc Zyngier wrote:
> > On Mon, 09 Dec 2024 12:25:34 +0000,
> > Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> >>>> 
> >>>> During automated testing of Nested Virtualization using avocado-vt,
> >>> 
> >>> Which is not merged upstream. So what branch are you using? Based on
> >>> what kernel version? On what HW? With which virtualisation features?
> >>> 
> >> 
> >> Testing is done on Ampere's AmpereOne platform using 6.10 based kernel
> >> with NV patches from your repo.
> > 
> > Grmbl... *Which* patches? At least give me the SHA1 of the branch,
> > because I have no idea what you are running. And 6.10 is definitely
> > not something I care about. If you're using the NV patches, the
> > *minimum* you should run is 6.13-rc1, because that's what the current
> > code is based on.
> > 
> 
> I tried 6.13-rc1 based nv-next branch today, which failed to boot
> UEFI as L1. Yet to debug this.

Works nicely here with kvmtool as the VMM. From what I understand,
EDK2 needs some surgery to correctly boot at EL2 without FEAT_E2H0.

> We do have the FEAT_ECV on AmpereOne, I was the one reported/fixed bug
> with FEAT_ECV(CNTPOFF offset issue) in the past.

Sorry, I don't keep track of the feature set for machines I don't have
access to.

	M.

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


From tglx at linutronix.de  Mon Dec  9 07:53:29 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 09 Dec 2024 16:53:29 +0100
Subject: [PATCH 1/4] irqchip/riscv-imsic: Handle non-atomic MSI updates
 for device
In-Reply-To: <CAK9=C2VqU2mdLL-R20bdgvDHi0WcuNyUSqRo7Pztsu-8X1wVvw@mail.gmail.com>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
 <20241208150711.297624-2-apatel@ventanamicro.com> <875xnuq6dc.ffs@tglx>
 <CAK9=C2VqU2mdLL-R20bdgvDHi0WcuNyUSqRo7Pztsu-8X1wVvw@mail.gmail.com>
Message-ID: <87r06gq2di.ffs@tglx>

Anup!

On Mon, Dec 09 2024 at 17:38, Anup Patel wrote:
> On Mon, Dec 9, 2024 at 1:44?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>> There is no guarantee that set_affinity() runs on the original target
>> CPU (CPU 1). Your scheme only works, when CPU1 vector 0x20 is not used
>> by some other device. If it's used, you lost as CPU1 will consume the
>> vector and your pending check is not seeing anything.
>>
>> x86 ensures CPU locality by deferring the affinity move to the next
>> device interrupt on the original target CPU (CPU1 in the above
>> example). See CONFIG_GENERIC_IRQ_PENDING.
>
> I agree with you.
>
> The IMSIC driver must do the affinity move upon the next device
> interrupt on the old CPU. I will update this patch in the next revision.
>
> BTW, I did not find CONFIG_GENERIC_IRQ_PENDING. Is the
> name correct ?

CONFIG_GENERIC_PENDING_IRQ is close enough :)

>> The interrupt domains which are not affected (remap) set the
>> IRQ_MOVE_PCNTXT flag to avoid that dance and don't use that affinity
>> setter code path at all.
>
> Yes, setting the IRQ_MOVE_PCNTXT flag in the remap domain
> makes perfect sense.
>
> I suggest adding IRQ_MOVE_PCNTXT usage as part of Drew's
> irqbypass series which adds a remap domain in the IOMMU
> driver. Unless you insist on having it as part of this series ?

You need to look at the other RISC-V controllers. Those which do not
need this should set it. That's historically backwards.

I think we can reverse the logic here. As this needs backporting, I
can't make a full cleanup of this, but for your problem the patch below
should just work.

Select GENERIC_PENDING_IRQ and GENERIC_PENDING_IRQ_CHIPFLAGS and set the
IRQCHIP_MOVE_DEFERRED flag on your interrrupt chip and the core logic
takes care of the PCNTXT bits.

I'll convert x86 in a seperate step and remove the PCNTXT leftovers and
the new config knob once the dust has settled.

Thanks,

        tglx
---
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -567,6 +567,7 @@ struct irq_chip {
  *                                    in the suspend path if they are in disabled state
  * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
  * IRQCHIP_IMMUTABLE:		      Don't ever change anything in this chip
+ * IRQCHIP_MOVE_DEFERRED:	      Move the interrupt in actual interrupt context
  */
 enum {
 	IRQCHIP_SET_TYPE_MASKED			= (1 <<  0),
@@ -581,6 +582,7 @@ enum {
 	IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND	= (1 <<  9),
 	IRQCHIP_AFFINITY_PRE_STARTUP		= (1 << 10),
 	IRQCHIP_IMMUTABLE			= (1 << 11),
+	IRQCHIP_MOVE_DEFERRED			= (1 << 12),
 };
 
 #include <linux/irqdesc.h>
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -31,6 +31,10 @@ config GENERIC_IRQ_EFFECTIVE_AFF_MASK
 config GENERIC_PENDING_IRQ
 	bool
 
+# Deduce delayed migration from top-level interrupt chip flags
+config GENERIC_PENDING_IRQ_CHIPFLAGS
+	bool
+
 # Support for generic irq migrating off cpu before the cpu is offline.
 config GENERIC_IRQ_MIGRATION
 	bool
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -47,6 +47,13 @@ int irq_set_chip(unsigned int irq, const
 		return -EINVAL;
 
 	desc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
+
+	if (IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS) && chip) {
+		if (chip->flags & IRQCHIP_MOVE_DEFERRED)
+			irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
+		else
+			irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
+	}
 	irq_put_desc_unlock(desc, flags);
 	/*
 	 * For !CONFIG_SPARSE_IRQ make the irq show up in
@@ -1114,16 +1121,21 @@ void irq_modify_status(unsigned int irq,
 	trigger = irqd_get_trigger_type(&desc->irq_data);
 
 	irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
-		   IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT);
+		   IRQD_TRIGGER_MASK | IRQD_LEVEL);
 	if (irq_settings_has_no_balance_set(desc))
 		irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
 	if (irq_settings_is_per_cpu(desc))
 		irqd_set(&desc->irq_data, IRQD_PER_CPU);
-	if (irq_settings_can_move_pcntxt(desc))
-		irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
 	if (irq_settings_is_level(desc))
 		irqd_set(&desc->irq_data, IRQD_LEVEL);
 
+	/* Keep this around until x86 is converted over */
+	if (!IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS)) {
+		irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
+		if (irq_settings_can_move_pcntxt(desc))
+			irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
+	}
+
 	tmp = irq_settings_get_trigger_mask(desc);
 	if (tmp != IRQ_TYPE_NONE)
 		trigger = tmp;





From alexandre.torgue at foss.st.com  Mon Dec  9 07:54:20 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Mon, 9 Dec 2024 16:54:20 +0100
Subject: [PATCH 0/6] ARM: dts: stm32: lxa-tac: fix gen{1,2} boards and add
 gen3 board
In-Reply-To: <20241209-magenta-boobook-of-respect-14ec68-mkl@pengutronix.de>
References: <20241119-lxa-tac-gen3-v1-0-e0ab0a369372@pengutronix.de>
 <20241209-magenta-boobook-of-respect-14ec68-mkl@pengutronix.de>
Message-ID: <feca2ea8-38f9-41c8-b4c4-1a6cbeec73a4@foss.st.com>

Hi Marc

On 12/9/24 15:30, Marc Kleine-Budde wrote:
> Hello Alexandre,
> 
> On 19.11.2024 12:34:57, Marc Kleine-Budde wrote:
>> Hello,
>>
>> this series fixes some problems found in the lxa-tac generation 1 and
>> 2 boards and add support for the generation 3 board. It's based on an
>> STM32MP153c, while the generation 1 and 2 are based on the
>> STM32MP157c.
>>
>> regards,
>> Marc
>>
>> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
>> ---
>> Leonard G?hrs (6):
>>        ARM: dts: stm32: lxa-tac: disable the real time clock
>>        ARM: dts: stm32: lxa-tac: extend the alias table
>>        ARM: dts: stm32: lxa-tac: adjust USB gadget fifo sizes for multi function
>>        dt-bindings: arm: stm32: add compatible strings for Linux Automation LXA TAC gen 3
>>        ARM: dts: stm32: lxa-tac: move adc and gpio{e,g} to gen{1,2} boards
>>        ARM: dts: stm32: lxa-tac: Add support for generation 3 devices
>>
>>   .../devicetree/bindings/arm/stm32/stm32.yaml       |   7 +
>>   arch/arm/boot/dts/st/Makefile                      |   1 +
>>   arch/arm/boot/dts/st/stm32mp153c-lxa-tac-gen3.dts  | 267 +++++++++++++++++++++
>>   arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen1.dts  |  84 +++++++
>>   arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen2.dts  |  84 +++++++
>>   arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi      | 100 +-------
>>   6 files changed, 455 insertions(+), 88 deletions(-)
> 
> since the merge window is open, can you merge this series please.

Yes sure. It will be in my PR for v6.14.

regards
Alex



> regards,
> Marc
> 


From kvalo at kernel.org  Mon Dec  9 07:58:50 2024
From: kvalo at kernel.org (Kalle Valo)
Date: Mon,  9 Dec 2024 15:58:50 +0000 (UTC)
Subject: wifi: wlcore: testmode: Constify strutc nla_policy
In-Reply-To: <78810e3ebb74ddbd3a4538f182bf1143b89baba7.1731332414.git.christophe.jaillet@wanadoo.fr>
References: <78810e3ebb74ddbd3a4538f182bf1143b89baba7.1731332414.git.christophe.jaillet@wanadoo.fr>
Message-ID: <173375992872.157598.4366313738760552668.kvalo@kernel.org>

Christophe JAILLET <christophe.jaillet at wanadoo.fr> wrote:

> 'struct nla_policy' is not modified in this driver.
> 
> Constifying this structure moves some data to a read-only section, so
> increase overall security, especially when the structure holds some
> function pointers.
> 
> On a x86_64, with allmodconfig:
> Before:
> ======
>    text	   data	    bss	    dec	    hex	filename
>    5062	    528	      0	   5590	   15d6	drivers/net/wireless/ti/wlcore/testmode.o
> 
> After:
> =====
>    text	   data	    bss	    dec	    hex	filename
>    5178	    404	      0	   5582	   15ce	drivers/net/wireless/ti/wlcore/testmode.o
> 
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> Reviewed-by: Jeff Johnson <quic_jjohnson at quicinc.com>

Patch applied to wireless-next.git, thanks.

01e767d6f783 wifi: wlcore: testmode: Constify strutc nla_policy

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/78810e3ebb74ddbd3a4538f182bf1143b89baba7.1731332414.git.christophe.jaillet at wanadoo.fr/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches



From mark.rutland at arm.com  Mon Dec  9 07:59:48 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  9 Dec 2024 15:59:48 +0000
Subject: [PATCH] arm64: cpufeature: Add HAFT to cpucap_is_possible()
Message-ID: <20241209155948.2124393-1-mark.rutland@arm.com>

For consistency with other cpucaps, handle the configuration check for
ARM64_HAFT in cpucap_is_possible() rather than this being explicit in
system_supports_haft(). The configuration check will now happen
implicitly as cpus_have_final_cap() uses cpucap_is_possible() via
alternative_has_cap_unlikely().

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>
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/arm64/include/asm/cpucaps.h    | 2 ++
 arch/arm64/include/asm/cpufeature.h | 3 +--
 2 files changed, 3 insertions(+), 2 deletions(-)

This is a cleanup as with the recent GCS cpucap:

  https://lore.kernel.org/linux-arm-kernel/Z1G3Z9C9efBkVKjR at J2N7QTR9R3/

Mark.

diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index cbbf70e0f2048..0b5ca6e0eb093 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -46,6 +46,8 @@ cpucap_is_possible(const unsigned int cap)
 		return IS_ENABLED(CONFIG_ARM64_POE);
 	case ARM64_HAS_GCS:
 		return IS_ENABLED(CONFIG_ARM64_GCS);
+	case ARM64_HAFT:
+		return IS_ENABLED(CONFIG_ARM64_HAFT);
 	case ARM64_UNMAP_KERNEL_AT_EL0:
 		return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0);
 	case ARM64_WORKAROUND_843419:
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 8b4e5a3cd24c8..a4d0b77a68d95 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -852,8 +852,7 @@ static inline bool system_supports_gcs(void)
 
 static inline bool system_supports_haft(void)
 {
-	return IS_ENABLED(CONFIG_ARM64_HAFT) &&
-		cpus_have_final_cap(ARM64_HAFT);
+	return cpus_have_final_cap(ARM64_HAFT);
 }
 
 static __always_inline bool system_supports_mpam(void)
-- 
2.30.2



From jbrunet at baylibre.com  Mon Dec  9 08:04:33 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 09 Dec 2024 17:04:33 +0100
Subject: [PATCH 0/2] reset: amlogic: rework auxiliary reset support
Message-ID: <20241209-meson-rst-aux-rework-v1-0-d2afb69cc72e@baylibre.com>

The current implementation of auxiliary reset controller, with the
registration helper in the same module as the driver code, does not
allow to properly decouple the registered auxiliary driver from
the registering one.

This patchset removes the registration helper from the auxiliary reset
driver and changes how regmap is passed, to simplify the interface a bit.

This patcheset depends on:
commit 5ae1a43486fb ("clk: amlogic: axg-audio: revert reset implementation")

The above removes the only user of the auxiliary reset controller, restoring
old implementation as a temporary solution, while it is reworked.

The commit has been applied to clock fixes [1] branch and will eventually
make its way to an rc release.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/commit/?h=clk-fixes&id=5ae1a43486fb3febd5ce78da13eb354f16d049e0

Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
Jerome Brunet (2):
      reset: amlogic: aux: get regmap through parent device
      reset: amlogic: aux: drop aux registration helper

 drivers/reset/amlogic/reset-meson-aux.c | 85 +++------------------------------
 include/soc/amlogic/reset-meson-aux.h   | 23 ---------
 2 files changed, 6 insertions(+), 102 deletions(-)
---
base-commit: 3d99f9231bedcf9acfb965a97645a8ecfa93a40d
change-id: 20241209-meson-rst-aux-rework-e26c716c6762
prerequisite-change-id: 20241127-clk-audio-fix-rst-missing-0b80628d934b:v2
prerequisite-patch-id: 8bf55ab8ba9db1abea5df2554864a2f4f9c72e77

Best regards,
-- 
Jerome



From jbrunet at baylibre.com  Mon Dec  9 08:04:34 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 09 Dec 2024 17:04:34 +0100
Subject: [PATCH 1/2] reset: amlogic: aux: get regmap through parent device
In-Reply-To: <20241209-meson-rst-aux-rework-v1-0-d2afb69cc72e@baylibre.com>
References: <20241209-meson-rst-aux-rework-v1-0-d2afb69cc72e@baylibre.com>
Message-ID: <20241209-meson-rst-aux-rework-v1-1-d2afb69cc72e@baylibre.com>

Get regmap directly from the parent device registering the
auxiliary reset driver, instead of using device data attached
to the auxiliary device.

This simplifies the registration a bit.

Suggested-by: Stephen Boyd <sboyd at kernel.org>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/reset/amlogic/reset-meson-aux.c | 36 +++++++++++----------------------
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/drivers/reset/amlogic/reset-meson-aux.c b/drivers/reset/amlogic/reset-meson-aux.c
index 4b422ae5fcd209e1041e9a793d980627203d00b0..0fc1788eb7a83810ac524facfe09b5fa032573c3 100644
--- a/drivers/reset/amlogic/reset-meson-aux.c
+++ b/drivers/reset/amlogic/reset-meson-aux.c
@@ -18,14 +18,6 @@
 
 static DEFINE_IDA(meson_rst_aux_ida);
 
-struct meson_reset_adev {
-	struct auxiliary_device adev;
-	struct regmap *map;
-};
-
-#define to_meson_reset_adev(_adev) \
-	container_of((_adev), struct meson_reset_adev, adev)
-
 static const struct meson_reset_param meson_a1_audio_param = {
 	.reset_ops	= &meson_reset_toggle_ops,
 	.reset_num	= 32,
@@ -72,10 +64,13 @@ static int meson_reset_aux_probe(struct auxiliary_device *adev,
 {
 	const struct meson_reset_param *param =
 		(const struct meson_reset_param *)(id->driver_data);
-	struct meson_reset_adev *raux =
-		to_meson_reset_adev(adev);
+	struct regmap *map;
+
+	map = dev_get_regmap(adev->dev.parent, NULL);
+	if (!map)
+		return -EINVAL;
 
-	return meson_reset_controller_register(&adev->dev, raux->map, param);
+	return meson_reset_controller_register(&adev->dev, map, param);
 }
 
 static struct auxiliary_driver meson_reset_aux_driver = {
@@ -87,11 +82,9 @@ module_auxiliary_driver(meson_reset_aux_driver);
 static void meson_rst_aux_release(struct device *dev)
 {
 	struct auxiliary_device *adev = to_auxiliary_dev(dev);
-	struct meson_reset_adev *raux =
-		to_meson_reset_adev(adev);
 
 	ida_free(&meson_rst_aux_ida, adev->id);
-	kfree(raux);
+	kfree(adev);
 }
 
 static void meson_rst_aux_unregister_adev(void *_adev)
@@ -103,24 +96,19 @@ static void meson_rst_aux_unregister_adev(void *_adev)
 }
 
 int devm_meson_rst_aux_register(struct device *dev,
-				struct regmap *map,
 				const char *adev_name)
 {
-	struct meson_reset_adev *raux;
 	struct auxiliary_device *adev;
 	int ret;
 
-	raux = kzalloc(sizeof(*raux), GFP_KERNEL);
-	if (!raux)
+	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+	if (!adev)
 		return -ENOMEM;
 
 	ret = ida_alloc(&meson_rst_aux_ida, GFP_KERNEL);
 	if (ret < 0)
-		goto raux_free;
-
-	raux->map = map;
+		goto adev_free;
 
-	adev = &raux->adev;
 	adev->id = ret;
 	adev->name = adev_name;
 	adev->dev.parent = dev;
@@ -142,8 +130,8 @@ int devm_meson_rst_aux_register(struct device *dev,
 
 ida_free:
 	ida_free(&meson_rst_aux_ida, adev->id);
-raux_free:
-	kfree(raux);
+adev_free:
+	kfree(adev);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(devm_meson_rst_aux_register);

-- 
2.45.2



From jbrunet at baylibre.com  Mon Dec  9 08:04:35 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 09 Dec 2024 17:04:35 +0100
Subject: [PATCH 2/2] reset: amlogic: aux: drop aux registration helper
In-Reply-To: <20241209-meson-rst-aux-rework-v1-0-d2afb69cc72e@baylibre.com>
References: <20241209-meson-rst-aux-rework-v1-0-d2afb69cc72e@baylibre.com>
Message-ID: <20241209-meson-rst-aux-rework-v1-2-d2afb69cc72e@baylibre.com>

Having the aux registration helper along with the registered driver is not
great dependency wise. It does not allow the registering driver to be
properly decoupled from the registered auxiliary driver.

Drop the registration helper from the amlogic auxiliary reset driver.
This will be handled in the registering clock driver to start with while
a more generic solution is worked on.

Suggested-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/reset/amlogic/reset-meson-aux.c | 61 ---------------------------------
 include/soc/amlogic/reset-meson-aux.h   | 23 -------------
 2 files changed, 84 deletions(-)

diff --git a/drivers/reset/amlogic/reset-meson-aux.c b/drivers/reset/amlogic/reset-meson-aux.c
index 0fc1788eb7a83810ac524facfe09b5fa032573c3..1a2024afa056ea4d9404f6444476e48265ac8da4 100644
--- a/drivers/reset/amlogic/reset-meson-aux.c
+++ b/drivers/reset/amlogic/reset-meson-aux.c
@@ -11,12 +11,8 @@
 #include <linux/auxiliary_bus.h>
 #include <linux/regmap.h>
 #include <linux/reset-controller.h>
-#include <linux/slab.h>
 
 #include "reset-meson.h"
-#include <soc/amlogic/reset-meson-aux.h>
-
-static DEFINE_IDA(meson_rst_aux_ida);
 
 static const struct meson_reset_param meson_a1_audio_param = {
 	.reset_ops	= &meson_reset_toggle_ops,
@@ -79,63 +75,6 @@ static struct auxiliary_driver meson_reset_aux_driver = {
 };
 module_auxiliary_driver(meson_reset_aux_driver);
 
-static void meson_rst_aux_release(struct device *dev)
-{
-	struct auxiliary_device *adev = to_auxiliary_dev(dev);
-
-	ida_free(&meson_rst_aux_ida, adev->id);
-	kfree(adev);
-}
-
-static void meson_rst_aux_unregister_adev(void *_adev)
-{
-	struct auxiliary_device *adev = _adev;
-
-	auxiliary_device_delete(adev);
-	auxiliary_device_uninit(adev);
-}
-
-int devm_meson_rst_aux_register(struct device *dev,
-				const char *adev_name)
-{
-	struct auxiliary_device *adev;
-	int ret;
-
-	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
-	if (!adev)
-		return -ENOMEM;
-
-	ret = ida_alloc(&meson_rst_aux_ida, GFP_KERNEL);
-	if (ret < 0)
-		goto adev_free;
-
-	adev->id = ret;
-	adev->name = adev_name;
-	adev->dev.parent = dev;
-	adev->dev.release = meson_rst_aux_release;
-	device_set_of_node_from_dev(&adev->dev, dev);
-
-	ret = auxiliary_device_init(adev);
-	if (ret)
-		goto ida_free;
-
-	ret = __auxiliary_device_add(adev, dev->driver->name);
-	if (ret) {
-		auxiliary_device_uninit(adev);
-		return ret;
-	}
-
-	return devm_add_action_or_reset(dev, meson_rst_aux_unregister_adev,
-					adev);
-
-ida_free:
-	ida_free(&meson_rst_aux_ida, adev->id);
-adev_free:
-	kfree(adev);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(devm_meson_rst_aux_register);
-
 MODULE_DESCRIPTION("Amlogic Meson Reset Auxiliary driver");
 MODULE_AUTHOR("Jerome Brunet <jbrunet at baylibre.com>");
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/include/soc/amlogic/reset-meson-aux.h b/include/soc/amlogic/reset-meson-aux.h
deleted file mode 100644
index d8a15d48c98494c45c6e3d7e88fa714f770f12e3..0000000000000000000000000000000000000000
--- a/include/soc/amlogic/reset-meson-aux.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __SOC_RESET_MESON_AUX_H
-#define __SOC_RESET_MESON_AUX_H
-
-#include <linux/err.h>
-
-struct device;
-struct regmap;
-
-#if IS_ENABLED(CONFIG_RESET_MESON_AUX)
-int devm_meson_rst_aux_register(struct device *dev,
-				struct regmap *map,
-				const char *adev_name);
-#else
-static inline int devm_meson_rst_aux_register(struct device *dev,
-					      struct regmap *map,
-					      const char *adev_name)
-{
-	return 0;
-}
-#endif
-
-#endif /* __SOC_RESET_MESON_AUX_H */

-- 
2.45.2



From arnd at arndb.de  Mon Dec  9 08:07:50 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 09 Dec 2024 17:07:50 +0100
Subject: [PATCH 0/2] reset: amlogic: rework auxiliary reset support
In-Reply-To: <20241209-meson-rst-aux-rework-v1-0-d2afb69cc72e@baylibre.com>
References: <20241209-meson-rst-aux-rework-v1-0-d2afb69cc72e@baylibre.com>
Message-ID: <5519bdc5-4056-417f-a89e-26f9ae426922@app.fastmail.com>

On Mon, Dec 9, 2024, at 17:04, Jerome Brunet wrote:
> The current implementation of auxiliary reset controller, with the
> registration helper in the same module as the driver code, does not
> allow to properly decouple the registered auxiliary driver from
> the registering one.
>
> This patchset removes the registration helper from the auxiliary reset
> driver and changes how regmap is passed, to simplify the interface a bit.
>

Looks good to me,

Acked-by: Arnd Bergmann <arnd at arndb.de>


From didi.debian at cknow.org  Mon Dec  9 08:11:03 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Mon, 09 Dec 2024 17:11:03 +0100
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2
 controller
In-Reply-To: <20241209150619.33998-1-dse@thaumatec.com>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241209150619.33998-1-dse@thaumatec.com>
Message-ID: <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org>

Hi,

On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
> On 03.12.24 21:54, Heiko Stuebner wrote:
> > This series adds a bridge and glue driver for the DSI2 controller found
> > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
> > 
>
> I did more tests with different LVDS displays. I tested following
> configurations with DSI/LVDS bridge:
> - 1024x600 at 60.01
> - 1024x768 at 60.02
> - 1280x800 at 60.07
> - 1366x768 at 60.06
>
> All of them worked without issues, except 1366x768.
> With this resolution, video is blurry, and offset incorrectly
> to the left. There are also repeating errors on the console:
>
>   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
>
> In correct operation with other resolutions, there is no error.
> I am not sure if this is a problem in your series or rather in VOP2
> driver.

On my PineTab2 I got similar messages about 2 weeks ago:
rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp1

Preceding those, I got several panfrost related errors:

panfrost fde60000.gpu: get clock failed -517
panfrost fde60000.gpu: clk init failed -517
platform fde60000.gpu: deferred probe pending: (reason unknown)
platform cpufreq-dt: deferred probe pending: (reason unknown)
vdd_gpu_npu: disabling

But can also be that the PineTab2 (likely) needs regulator-always-on
and regulator-boot-on in its vdd_gpu_npu node.

> I tried to track down the problem, and it seems to be a generic issue
> when horizontal line width is not divisible by 4.
> Lowering line width to 1364px fixes the issue, but of course I have two
> vertical lines of black pixels on the right.
> I also made some tests with 720x1280 DSI display. Lowering horizontal
> line to 718px shows the same problem. With 720px and 716px it works
> correctly.

I haven't look further into it, but the PT2 has a 1280x800 resolution.

HTH,
  Diederik
-------------- 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/20241209/886485a6/attachment.sig>

From andrew at lunn.ch  Mon Dec  9 08:14:57 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 9 Dec 2024 17:14:57 +0100
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and
 MBa62xx carrier board Device Trees
In-Reply-To: <e16076d16349e929af82fa987a658bff1d9804c4.camel@ew.tq-group.com>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>
 <c902a56cf34838f60cee67624bb923e91d74e9e0.camel@ew.tq-group.com>
 <d25b1447-c28b-4998-b238-92672434dc28@lunn.ch>
 <e16076d16349e929af82fa987a658bff1d9804c4.camel@ew.tq-group.com>
Message-ID: <a2a2f201-73a4-4a99-baef-0d593a88c872@lunn.ch>

> Not our board, but the AM62 SoC. From the datasheet:
> 
> "TXC is delayed internally before being driven to the RGMII[x]_TXC pin. This
> internal delay is always enabled." So enabling the TX delay on the PHY side
> would result in a double delay.

phy-mode describes the board. If the board does not have extra long
clock lines, phy-mode should be rgmii-id.

The fact the MAC is doing something which no other MAC does should be
hidden away in the MAC driver, as much as possible.

The MAC driver should return -EINVAL with phy-mode rgmii, or
rmgii-rxid, because the MAC driver is physically incapable of being
used on a board which has extra long TX clock lines, which 'rmgii' or
rgmii-rxid would indicate.

Since the MAC driver is forcing the TX delay, it needs to take the
value returned from of_get_phy_mode() and mask out the TX bit before
passing it to the PHY.

Now, it could be that history has got in the way. There are boards out
there which have broken DT but work. Fixing the MAC driver to do the
correct thing will break those boards. Vendors with low quality code
which works, but not really.

~/linux/arch/arm64/boot/dts/ti$ grep rgmii k3-am625-*
k3-am625-beagleplay.dts:	phy-mode = "rgmii-rxid";
k3-am625-sk.dts:	phy-mode = "rgmii-rxid";

Yep, these two have broken DT, they don't describe the board
correctly.

O.K. Can we fix this for you board? Yes, i think we can. If you take
rmgii-rxid, aka PHY_INTERFACE_MODE_RGMII_RXID, and mask out the TX,
you still get PHY_INTERFACE_MODE_RGMII_RXID. If you take rgmii-id,
a.k.a. PHY_INTERFACE_MODE_RGMII_ID and mask out the TX, you get
PHY_INTERFACE_MODE_RGMII_RXID, which is what you want.

Please produce a patch to the MAC driver, explaining the horrible mess
the vendor made, and how this fixes it, but should also not break
other boards.

> No such defaults exist in the DP83867 driver. If any rgmii-*id mode is used, the
> corresponding delays *must* be specified in the DTB:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/phy/dp83867.c#n532

That is bad, different to pretty every other PHY driver :-(

If you want, you could patch this driver as well, make it default to
2ns if delays are asked for.

    Andrew

---
pw-bot: cr


From alexandre.torgue at foss.st.com  Mon Dec  9 08:15:21 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Mon, 9 Dec 2024 17:15:21 +0100
Subject: [PATCH] arm64: dts: st: add sai support on stm32mp251
In-Reply-To: <20241113092047.2359487-1-olivier.moysan@foss.st.com>
References: <20241113092047.2359487-1-olivier.moysan@foss.st.com>
Message-ID: <543e0df6-5719-41b7-a986-724f6fe6557d@foss.st.com>

Hi Olivier

On 11/13/24 10:20, Olivier Moysan wrote:
> Add SAI support to STM32MP25 SoC family.
> 
> Signed-off-by: Olivier Moysan <olivier.moysan at foss.st.com>
> ---
>   arch/arm64/boot/dts/st/stm32mp251.dtsi | 136 +++++++++++++++++++++++++
>   1 file changed, 136 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
> index 6fe12e3bd7dd..e9db486b988a 100644
> --- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
> +++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
> @@ -484,6 +484,108 @@ spi5: spi at 40280000 {
>   				status = "disabled";
>   			};


Applied on stm32-next.

Cheers!
Alex


From louis.chauvet at bootlin.com  Mon Dec  9 08:17:27 2024
From: louis.chauvet at bootlin.com (Louis Chauvet)
Date: Mon, 9 Dec 2024 17:17:27 +0100
Subject: [PATCH v2 3/3] drm: remove driver date from struct drm_driver
 and all drivers
In-Reply-To: <1f2bf2543aed270a06f6c707fd6ed1b78bf16712.1733322525.git.jani.nikula@intel.com>
References: <cover.1733322525.git.jani.nikula@intel.com>
 <1f2bf2543aed270a06f6c707fd6ed1b78bf16712.1733322525.git.jani.nikula@intel.com>
Message-ID: <Z1cYFxDjDTEBtz_C@louis-chauvet-laptop>

On 04/12/24 - 16:31, Jani Nikula wrote:
> We stopped using the driver initialized date in commit 7fb8af6798e8
> ("drm: deprecate driver date") and (eventually) started returning "0"
> for drm_version ioctl instead.
> 
> Finish the job, and remove the unused date member from struct
> drm_driver, its initialization from drivers, along with the common
> DRIVER_DATE macros.
> 
> v2: Also update drivers/accel (kernel test robot)
> 
> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com>
> Acked-by: Alex Deucher <alexander.deucher at amd.com>
> Acked-by: Simon Ser <contact at emersion.fr>
> Acked-by: Jeffrey Hugo <quic_jhugo at quicinc.com>
> Signed-off-by: Jani Nikula <jani.nikula at intel.com>

Reviewed-by: Louis Chauvet <louis.chauvet at bootlin.com>
 
> ---
> 
> Cc: David Airlie <airlied at gmail.com>
> Cc: Hamza Mahfooz <hamza.mahfooz at amd.com>
> Cc: Javier Martinez Canillas <javierm at redhat.com>
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko at epam.com>
> Cc: Simon Ser <contact at emersion.fr>
> Cc: Simona Vetter <simona at ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann at suse.de>
> Cc: Ville Syrj?l? <ville.syrjala at linux.intel.com>
> Cc: amd-gfx at lists.freedesktop.org
> Cc: dri-devel at lists.freedesktop.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: nouveau at lists.freedesktop.org
> Cc: xen-devel at lists.xenproject.org
> ---
>  drivers/accel/habanalabs/common/habanalabs_drv.c | 1 -
>  drivers/accel/ivpu/ivpu_drv.c                    | 1 -
>  drivers/accel/qaic/qaic_drv.c                    | 1 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c          | 2 --
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h          | 1 -
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.c  | 1 -
>  drivers/gpu/drm/arm/hdlcd_drv.c                  | 1 -
>  drivers/gpu/drm/arm/malidp_drv.c                 | 1 -
>  drivers/gpu/drm/armada/armada_drv.c              | 1 -
>  drivers/gpu/drm/aspeed/aspeed_gfx_drv.c          | 1 -
>  drivers/gpu/drm/ast/ast_drv.c                    | 1 -
>  drivers/gpu/drm/ast/ast_drv.h                    | 1 -
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c     | 1 -
>  drivers/gpu/drm/etnaviv/etnaviv_drv.c            | 1 -
>  drivers/gpu/drm/exynos/exynos_drm_drv.c          | 2 --
>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c        | 1 -
>  drivers/gpu/drm/gma500/psb_drv.c                 | 1 -
>  drivers/gpu/drm/gma500/psb_drv.h                 | 1 -
>  drivers/gpu/drm/gud/gud_drv.c                    | 1 -
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c  | 1 -
>  drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c  | 1 -
>  drivers/gpu/drm/hyperv/hyperv_drm_drv.c          | 2 --
>  drivers/gpu/drm/i915/i915_driver.c               | 1 -
>  drivers/gpu/drm/i915/i915_driver.h               | 1 -
>  drivers/gpu/drm/i915/i915_gpu_error.c            | 1 -
>  drivers/gpu/drm/imagination/pvr_drv.c            | 1 -
>  drivers/gpu/drm/imagination/pvr_drv.h            | 1 -
>  drivers/gpu/drm/imx/dcss/dcss-kms.c              | 1 -
>  drivers/gpu/drm/imx/ipuv3/imx-drm-core.c         | 1 -
>  drivers/gpu/drm/imx/lcdc/imx-lcdc.c              | 1 -
>  drivers/gpu/drm/ingenic/ingenic-drm-drv.c        | 1 -
>  drivers/gpu/drm/kmb/kmb_drv.c                    | 1 -
>  drivers/gpu/drm/kmb/kmb_drv.h                    | 1 -
>  drivers/gpu/drm/lima/lima_drv.c                  | 1 -
>  drivers/gpu/drm/logicvc/logicvc_drm.c            | 1 -
>  drivers/gpu/drm/loongson/lsdc_drv.c              | 2 --
>  drivers/gpu/drm/mcde/mcde_drv.c                  | 1 -
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c           | 2 --
>  drivers/gpu/drm/meson/meson_drv.c                | 1 -
>  drivers/gpu/drm/mgag200/mgag200_drv.c            | 1 -
>  drivers/gpu/drm/mgag200/mgag200_drv.h            | 1 -
>  drivers/gpu/drm/msm/msm_drv.c                    | 1 -
>  drivers/gpu/drm/mxsfb/lcdif_drv.c                | 1 -
>  drivers/gpu/drm/mxsfb/mxsfb_drv.c                | 1 -
>  drivers/gpu/drm/nouveau/nouveau_drm.c            | 5 -----
>  drivers/gpu/drm/nouveau/nouveau_drv.h            | 1 -
>  drivers/gpu/drm/omapdrm/omap_drv.c               | 2 --
>  drivers/gpu/drm/panfrost/panfrost_drv.c          | 1 -
>  drivers/gpu/drm/panthor/panthor_drv.c            | 1 -
>  drivers/gpu/drm/pl111/pl111_drv.c                | 1 -
>  drivers/gpu/drm/qxl/qxl_drv.c                    | 1 -
>  drivers/gpu/drm/qxl/qxl_drv.h                    | 1 -
>  drivers/gpu/drm/radeon/radeon_drv.c              | 1 -
>  drivers/gpu/drm/radeon/radeon_drv.h              | 1 -
>  drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c    | 1 -
>  drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c     | 1 -
>  drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 1 -
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.c      | 2 --
>  drivers/gpu/drm/solomon/ssd130x.c                | 2 --
>  drivers/gpu/drm/sprd/sprd_drm.c                  | 2 --
>  drivers/gpu/drm/sti/sti_drv.c                    | 2 --
>  drivers/gpu/drm/stm/drv.c                        | 1 -
>  drivers/gpu/drm/sun4i/sun4i_drv.c                | 1 -
>  drivers/gpu/drm/tegra/drm.c                      | 2 --
>  drivers/gpu/drm/tidss/tidss_drv.c                | 1 -
>  drivers/gpu/drm/tilcdc/tilcdc_drv.c              | 1 -
>  drivers/gpu/drm/tiny/arcpgu.c                    | 1 -
>  drivers/gpu/drm/tiny/bochs.c                     | 1 -
>  drivers/gpu/drm/tiny/cirrus-qemu.c               | 2 --
>  drivers/gpu/drm/tiny/gm12u320.c                  | 2 --
>  drivers/gpu/drm/tiny/hx8357d.c                   | 1 -
>  drivers/gpu/drm/tiny/ili9163.c                   | 1 -
>  drivers/gpu/drm/tiny/ili9225.c                   | 1 -
>  drivers/gpu/drm/tiny/ili9341.c                   | 1 -
>  drivers/gpu/drm/tiny/ili9486.c                   | 1 -
>  drivers/gpu/drm/tiny/mi0283qt.c                  | 1 -
>  drivers/gpu/drm/tiny/ofdrm.c                     | 2 --
>  drivers/gpu/drm/tiny/panel-mipi-dbi.c            | 1 -
>  drivers/gpu/drm/tiny/repaper.c                   | 1 -
>  drivers/gpu/drm/tiny/sharp-memory.c              | 1 -
>  drivers/gpu/drm/tiny/simpledrm.c                 | 2 --
>  drivers/gpu/drm/tiny/st7586.c                    | 1 -
>  drivers/gpu/drm/tiny/st7735r.c                   | 1 -
>  drivers/gpu/drm/tve200/tve200_drv.c              | 1 -
>  drivers/gpu/drm/udl/udl_drv.c                    | 1 -
>  drivers/gpu/drm/udl/udl_drv.h                    | 1 -
>  drivers/gpu/drm/v3d/v3d_drv.c                    | 2 --
>  drivers/gpu/drm/vboxvideo/vbox_drv.c             | 1 -
>  drivers/gpu/drm/vboxvideo/vbox_drv.h             | 1 -
>  drivers/gpu/drm/vc4/vc4_drv.c                    | 3 ---
>  drivers/gpu/drm/vgem/vgem_drv.c                  | 2 --
>  drivers/gpu/drm/virtio/virtgpu_drv.c             | 1 -
>  drivers/gpu/drm/virtio/virtgpu_drv.h             | 1 -
>  drivers/gpu/drm/vkms/vkms_drv.c                  | 2 --
>  drivers/gpu/drm/vmwgfx/vmwgfx_drv.c              | 1 -
>  drivers/gpu/drm/vmwgfx/vmwgfx_drv.h              | 1 -
>  drivers/gpu/drm/xe/xe_device.c                   | 1 -
>  drivers/gpu/drm/xe/xe_drv.h                      | 1 -
>  drivers/gpu/drm/xen/xen_drm_front.c              | 1 -
>  drivers/gpu/drm/xlnx/zynqmp_kms.c                | 1 -
>  include/drm/drm_drv.h                            | 2 --
>  101 files changed, 126 deletions(-)
> 
> diff --git a/drivers/accel/habanalabs/common/habanalabs_drv.c b/drivers/accel/habanalabs/common/habanalabs_drv.c
> index 708dfd10f39c..5409b2c656c8 100644
> --- a/drivers/accel/habanalabs/common/habanalabs_drv.c
> +++ b/drivers/accel/habanalabs/common/habanalabs_drv.c
> @@ -101,7 +101,6 @@ static const struct drm_driver hl_driver = {
>  	.major = LINUX_VERSION_MAJOR,
>  	.minor = LINUX_VERSION_PATCHLEVEL,
>  	.patchlevel = LINUX_VERSION_SUBLEVEL,
> -	.date = "20190505",
>  
>  	.fops = &hl_fops,
>  	.open = hl_device_open,
> diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
> index 1f359dbe5150..1e8ffbe25eee 100644
> --- a/drivers/accel/ivpu/ivpu_drv.c
> +++ b/drivers/accel/ivpu/ivpu_drv.c
> @@ -458,7 +458,6 @@ static const struct drm_driver driver = {
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
>  
> -	.date = UTS_RELEASE,
>  	.major = 1,
>  };
>  
> diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c
> index 3575e0c984d6..542c5d24e499 100644
> --- a/drivers/accel/qaic/qaic_drv.c
> +++ b/drivers/accel/qaic/qaic_drv.c
> @@ -208,7 +208,6 @@ static const struct drm_driver qaic_accel_driver = {
>  
>  	.name			= QAIC_NAME,
>  	.desc			= QAIC_DESC,
> -	.date			= "20190618",
>  
>  	.fops			= &qaic_accel_fops,
>  	.open			= qaic_open,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 346746d6c233..eaeaaddb32cd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -2916,7 +2916,6 @@ static const struct drm_driver amdgpu_kms_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = KMS_DRIVER_MAJOR,
>  	.minor = KMS_DRIVER_MINOR,
>  	.patchlevel = KMS_DRIVER_PATCHLEVEL,
> @@ -2940,7 +2939,6 @@ const struct drm_driver amdgpu_partition_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = KMS_DRIVER_MAJOR,
>  	.minor = KMS_DRIVER_MINOR,
>  	.patchlevel = KMS_DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h
> index 5bc2cb661af7..2d86cc6f7f4d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h
> @@ -40,7 +40,6 @@
>  
>  #define DRIVER_NAME		"amdgpu"
>  #define DRIVER_DESC		"AMD GPU"
> -#define DRIVER_DATE		"20150101"
>  
>  extern const struct drm_driver amdgpu_partition_driver;
>  
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> index 1e7b1fcb2848..6ed504099188 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> @@ -63,7 +63,6 @@ static const struct drm_driver komeda_kms_driver = {
>  	.fops = &komeda_cma_fops,
>  	.name = "komeda",
>  	.desc = "Arm Komeda Display Processor driver",
> -	.date = "20181101",
>  	.major = 0,
>  	.minor = 1,
>  };
> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> index 4af8fce7dab7..8617d10940d8 100644
> --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> @@ -233,7 +233,6 @@ static const struct drm_driver hdlcd_driver = {
>  	.fops = &fops,
>  	.name = "hdlcd",
>  	.desc = "ARM HDLCD Controller DRM",
> -	.date = "20151021",
>  	.major = 1,
>  	.minor = 0,
>  };
> diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
> index 38b1b5b6bf69..3abc9339464b 100644
> --- a/drivers/gpu/drm/arm/malidp_drv.c
> +++ b/drivers/gpu/drm/arm/malidp_drv.c
> @@ -570,7 +570,6 @@ static const struct drm_driver malidp_driver = {
>  	.fops = &fops,
>  	.name = "mali-dp",
>  	.desc = "ARM Mali Display Processor driver",
> -	.date = "20160106",
>  	.major = 1,
>  	.minor = 0,
>  };
> diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
> index ddf0eaf546a6..5d5b7435970a 100644
> --- a/drivers/gpu/drm/armada/armada_drv.c
> +++ b/drivers/gpu/drm/armada/armada_drv.c
> @@ -45,7 +45,6 @@ static const struct drm_driver armada_drm_driver = {
>  	.minor			= 0,
>  	.name			= "armada-drm",
>  	.desc			= "Armada SoC DRM",
> -	.date			= "20120730",
>  	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
>  	.ioctls			= armada_ioctls,
>  	.num_ioctls = ARRAY_SIZE(armada_ioctls),
> diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
> index 55e90ab9b231..90189a3cf886 100644
> --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
> +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
> @@ -252,7 +252,6 @@ static const struct drm_driver aspeed_gfx_driver = {
>  	.fops = &fops,
>  	.name = "aspeed-gfx-drm",
>  	.desc = "ASPEED GFX DRM",
> -	.date = "20180319",
>  	.major = 1,
>  	.minor = 0,
>  };
> diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
> index 8e9c9cb89a50..ff3bcdd1cff2 100644
> --- a/drivers/gpu/drm/ast/ast_drv.c
> +++ b/drivers/gpu/drm/ast/ast_drv.c
> @@ -60,7 +60,6 @@ static const struct drm_driver ast_driver = {
>  	.fops = &ast_fops,
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
> index 21ce3769bf0d..6b4305ac07d4 100644
> --- a/drivers/gpu/drm/ast/ast_drv.h
> +++ b/drivers/gpu/drm/ast/ast_drv.h
> @@ -43,7 +43,6 @@
>  
>  #define DRIVER_NAME		"ast"
>  #define DRIVER_DESC		"AST"
> -#define DRIVER_DATE		"20120228"
>  
>  #define DRIVER_MAJOR		0
>  #define DRIVER_MINOR		1
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index 506289a937e2..b51528b2166c 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -846,7 +846,6 @@ static const struct drm_driver atmel_hlcdc_dc_driver = {
>  	.fops = &fops,
>  	.name = "atmel-hlcdc",
>  	.desc = "Atmel HLCD Controller DRM",
> -	.date = "20141504",
>  	.major = 1,
>  	.minor = 0,
>  };
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> index 9b4e2f4b1bc7..c4ddabe3cabd 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> @@ -503,7 +503,6 @@ static const struct drm_driver etnaviv_drm_driver = {
>  	.fops               = &fops,
>  	.name               = "etnaviv",
>  	.desc               = "etnaviv DRM",
> -	.date               = "20151214",
>  	.major              = 1,
>  	.minor              = 4,
>  };
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 7e517a2ec681..91ab42b56716 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -35,7 +35,6 @@
>  
>  #define DRIVER_NAME	"exynos"
>  #define DRIVER_DESC	"Samsung SoC DRM"
> -#define DRIVER_DATE	"20180330"
>  
>  /*
>   * Interface history:
> @@ -118,7 +117,6 @@ static const struct drm_driver exynos_drm_driver = {
>  	.fops			= &exynos_drm_driver_fops,
>  	.name	= DRIVER_NAME,
>  	.desc	= DRIVER_DESC,
> -	.date	= DRIVER_DATE,
>  	.major	= DRIVER_MAJOR,
>  	.minor	= DRIVER_MINOR,
>  };
> diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
> index 12b2096b6c9d..e1183644ec39 100644
> --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
> +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
> @@ -174,7 +174,6 @@ static const struct drm_driver fsl_dcu_drm_driver = {
>  	.fops			= &fsl_dcu_drm_fops,
>  	.name			= "fsl-dcu-drm",
>  	.desc			= "Freescale DCU DRM",
> -	.date			= "20160425",
>  	.major			= 1,
>  	.minor			= 1,
>  };
> diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
> index 2c56ece17d71..85d3557c2eb9 100644
> --- a/drivers/gpu/drm/gma500/psb_drv.c
> +++ b/drivers/gpu/drm/gma500/psb_drv.c
> @@ -513,7 +513,6 @@ static const struct drm_driver driver = {
>  	.fops = &psb_gem_fops,
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL
> diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
> index de62cbfcdc72..7f77cb2b2751 100644
> --- a/drivers/gpu/drm/gma500/psb_drv.h
> +++ b/drivers/gpu/drm/gma500/psb_drv.h
> @@ -26,7 +26,6 @@
>  
>  #define DRIVER_NAME "gma500"
>  #define DRIVER_DESC "DRM driver for the Intel GMA500, GMA600, GMA3600, GMA3650"
> -#define DRIVER_DATE "20140314"
>  
>  #define DRIVER_MAJOR 1
>  #define DRIVER_MINOR 0
> diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
> index 65a16f009ea6..cb405771d6e2 100644
> --- a/drivers/gpu/drm/gud/gud_drv.c
> +++ b/drivers/gpu/drm/gud/gud_drv.c
> @@ -381,7 +381,6 @@ static const struct drm_driver gud_drm_driver = {
>  
>  	.name			= "gud",
>  	.desc			= "Generic USB Display",
> -	.date			= "20200422",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> index 69bdae604982..7f814c32ed34 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> @@ -57,7 +57,6 @@ static const struct drm_driver hibmc_driver = {
>  	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
>  	.fops			= &hibmc_fops,
>  	.name			= "hibmc",
> -	.date			= "20160828",
>  	.desc			= "hibmc drm driver",
>  	.major			= 1,
>  	.minor			= 0,
> diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> index 5616c3917c03..2eb49177ac42 100644
> --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> @@ -929,7 +929,6 @@ static const struct drm_driver ade_driver = {
>  	DRM_FBDEV_DMA_DRIVER_OPS,
>  	.name = "kirin",
>  	.desc = "Hisilicon Kirin620 SoC DRM Driver",
> -	.date = "20150718",
>  	.major = 1,
>  	.minor = 0,
>  };
> diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> index c5ac240f7a7a..f59abfa7622a 100644
> --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> @@ -20,7 +20,6 @@
>  
>  #define DRIVER_NAME "hyperv_drm"
>  #define DRIVER_DESC "DRM driver for Hyper-V synthetic video device"
> -#define DRIVER_DATE "2020"
>  #define DRIVER_MAJOR 1
>  #define DRIVER_MINOR 0
>  
> @@ -31,7 +30,6 @@ static struct drm_driver hyperv_driver = {
>  
>  	.name		 = DRIVER_NAME,
>  	.desc		 = DRIVER_DESC,
> -	.date		 = DRIVER_DATE,
>  	.major		 = DRIVER_MAJOR,
>  	.minor		 = DRIVER_MINOR,
>  
> diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
> index c1edf5e1f61e..e35aa0274d76 100644
> --- a/drivers/gpu/drm/i915/i915_driver.c
> +++ b/drivers/gpu/drm/i915/i915_driver.c
> @@ -1797,7 +1797,6 @@ static const struct drm_driver i915_drm_driver = {
>  	.fops = &i915_driver_fops,
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/i915/i915_driver.h b/drivers/gpu/drm/i915/i915_driver.h
> index 94a70d8ec5d5..4b67ad9a61cd 100644
> --- a/drivers/gpu/drm/i915/i915_driver.h
> +++ b/drivers/gpu/drm/i915/i915_driver.h
> @@ -15,7 +15,6 @@ struct drm_printer;
>  
>  #define DRIVER_NAME		"i915"
>  #define DRIVER_DESC		"Intel Graphics"
> -#define DRIVER_DATE		"20230929"
>  #define DRIVER_TIMESTAMP	1695980603
>  
>  extern const struct dev_pm_ops i915_pm_ops;
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 4eb58887819a..eb975b3815df 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -841,7 +841,6 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
>  	err_printf(m, "Kernel: %s %s\n",
>  		   init_utsname()->release,
>  		   init_utsname()->machine);
> -	err_printf(m, "Driver: %s\n", DRIVER_DATE);
>  	ts = ktime_to_timespec64(error->time);
>  	err_printf(m, "Time: %lld s %ld us\n",
>  		   (s64)ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC);
> diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c
> index 36c0e768698e..6ab023593476 100644
> --- a/drivers/gpu/drm/imagination/pvr_drv.c
> +++ b/drivers/gpu/drm/imagination/pvr_drv.c
> @@ -1387,7 +1387,6 @@ static struct drm_driver pvr_drm_driver = {
>  
>  	.name = PVR_DRIVER_NAME,
>  	.desc = PVR_DRIVER_DESC,
> -	.date = PVR_DRIVER_DATE,
>  	.major = PVR_DRIVER_MAJOR,
>  	.minor = PVR_DRIVER_MINOR,
>  	.patchlevel = PVR_DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/imagination/pvr_drv.h b/drivers/gpu/drm/imagination/pvr_drv.h
> index 378fe477b759..7fa147312dd1 100644
> --- a/drivers/gpu/drm/imagination/pvr_drv.h
> +++ b/drivers/gpu/drm/imagination/pvr_drv.h
> @@ -9,7 +9,6 @@
>  
>  #define PVR_DRIVER_NAME "powervr"
>  #define PVR_DRIVER_DESC "Imagination PowerVR (Series 6 and later) & IMG Graphics"
> -#define PVR_DRIVER_DATE "20230904"
>  
>  /*
>   * Driver interface version:
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c
> index 490b5c269f39..3633e8f3aff6 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-kms.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c
> @@ -34,7 +34,6 @@ static const struct drm_driver dcss_kms_driver = {
>  	.fops			= &dcss_cma_fops,
>  	.name			= "imx-dcss",
>  	.desc			= "i.MX8MQ Display Subsystem",
> -	.date			= "20190917",
>  	.major			= 1,
>  	.minor			= 0,
>  	.patchlevel		= 0,
> diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> index 6b84429735d6..bcb35ba670fc 100644
> --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> @@ -163,7 +163,6 @@ static const struct drm_driver imx_drm_driver = {
>  	.fops			= &imx_drm_driver_fops,
>  	.name			= "imx-drm",
>  	.desc			= "i.MX DRM graphics",
> -	.date			= "20120507",
>  	.major			= 1,
>  	.minor			= 0,
>  	.patchlevel		= 0,
> diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
> index c5121fed80fd..d70981295f88 100644
> --- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
> +++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
> @@ -352,7 +352,6 @@ static struct drm_driver imx_lcdc_drm_driver = {
>  	DRM_FBDEV_DMA_DRIVER_OPS,
>  	.name = "imx-lcdc",
>  	.desc = "i.MX LCDC driver",
> -	.date = "20200716",
>  };
>  
>  static const struct of_device_id imx_lcdc_of_dev_id[] = {
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> index 0a4eb3994cd6..6546d9ec410a 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> @@ -953,7 +953,6 @@ static const struct drm_driver ingenic_drm_driver_data = {
>  	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
>  	.name			= "ingenic-drm",
>  	.desc			= "DRM module for Ingenic SoCs",
> -	.date			= "20200716",
>  	.major			= 1,
>  	.minor			= 1,
>  	.patchlevel		= 0,
> diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c
> index 4173344ba32c..c340b4c6a74b 100644
> --- a/drivers/gpu/drm/kmb/kmb_drv.c
> +++ b/drivers/gpu/drm/kmb/kmb_drv.c
> @@ -445,7 +445,6 @@ static const struct drm_driver kmb_driver = {
>  	DRM_FBDEV_DMA_DRIVER_OPS,
>  	.name = "kmb-drm",
>  	.desc = "KEEMBAY DISPLAY DRIVER",
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  };
> diff --git a/drivers/gpu/drm/kmb/kmb_drv.h b/drivers/gpu/drm/kmb/kmb_drv.h
> index bf085e95b28f..1f0c10d317fe 100644
> --- a/drivers/gpu/drm/kmb/kmb_drv.h
> +++ b/drivers/gpu/drm/kmb/kmb_drv.h
> @@ -16,7 +16,6 @@
>  #define KMB_MIN_WIDTH                   1920 /*Max width in pixels */
>  #define KMB_MIN_HEIGHT                  1080 /*Max height in pixels */
>  
> -#define DRIVER_DATE			"20210223"
>  #define DRIVER_MAJOR			1
>  #define DRIVER_MINOR			1
>  
> diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
> index 10bce18b7c31..4b70c5189f7c 100644
> --- a/drivers/gpu/drm/lima/lima_drv.c
> +++ b/drivers/gpu/drm/lima/lima_drv.c
> @@ -271,7 +271,6 @@ static const struct drm_driver lima_drm_driver = {
>  	.fops               = &lima_drm_driver_fops,
>  	.name               = "lima",
>  	.desc               = "lima DRM",
> -	.date               = "20191231",
>  	.major              = 1,
>  	.minor              = 1,
>  	.patchlevel         = 0,
> diff --git a/drivers/gpu/drm/logicvc/logicvc_drm.c b/drivers/gpu/drm/logicvc/logicvc_drm.c
> index 9152034e54a3..bda2a689d928 100644
> --- a/drivers/gpu/drm/logicvc/logicvc_drm.c
> +++ b/drivers/gpu/drm/logicvc/logicvc_drm.c
> @@ -52,7 +52,6 @@ static struct drm_driver logicvc_drm_driver = {
>  	.fops				= &logicvc_drm_fops,
>  	.name				= "logicvc-drm",
>  	.desc				= "Xylon LogiCVC DRM driver",
> -	.date				= "20200403",
>  	.major				= 1,
>  	.minor				= 0,
>  
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
> index a55aa1fe2c21..12193d2a301a 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.c
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.c
> @@ -26,7 +26,6 @@
>  #define DRIVER_AUTHOR               "Sui Jingfeng <suijingfeng at loongson.cn>"
>  #define DRIVER_NAME                 "loongson"
>  #define DRIVER_DESC                 "drm driver for loongson graphics"
> -#define DRIVER_DATE                 "20220701"
>  #define DRIVER_MAJOR                1
>  #define DRIVER_MINOR                0
>  #define DRIVER_PATCHLEVEL           0
> @@ -39,7 +38,6 @@ static const struct drm_driver lsdc_drm_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
> index f8c7aa9d7f33..324a95d7f15b 100644
> --- a/drivers/gpu/drm/mcde/mcde_drv.c
> +++ b/drivers/gpu/drm/mcde/mcde_drv.c
> @@ -208,7 +208,6 @@ static const struct drm_driver mcde_drm_driver = {
>  	.fops = &drm_fops,
>  	.name = "mcde",
>  	.desc = DRIVER_DESC,
> -	.date = "20180529",
>  	.major = 1,
>  	.minor = 0,
>  	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 38297d705df6..723782e75c55 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -33,7 +33,6 @@
>  
>  #define DRIVER_NAME "mediatek"
>  #define DRIVER_DESC "Mediatek SoC DRM"
> -#define DRIVER_DATE "20150513"
>  #define DRIVER_MAJOR 1
>  #define DRIVER_MINOR 0
>  
> @@ -615,7 +614,6 @@ static const struct drm_driver mtk_drm_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  };
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index 83ee18024682..64c8c4bb60f1 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -105,7 +105,6 @@ static const struct drm_driver meson_driver = {
>  	.fops			= &fops,
>  	.name			= DRIVER_NAME,
>  	.desc			= DRIVER_DESC,
> -	.date			= "20161109",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
> index b7ed763addfa..069fdd2dc8f6 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_drv.c
> +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
> @@ -97,7 +97,6 @@ static const struct drm_driver mgag200_driver = {
>  	.fops = &mgag200_driver_fops,
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
> index 988967eafbf2..0608fc63e588 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_drv.h
> +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
> @@ -25,7 +25,6 @@
>  
>  #define DRIVER_NAME		"mgag200"
>  #define DRIVER_DESC		"MGA G200 SE"
> -#define DRIVER_DATE		"20110418"
>  
>  #define DRIVER_MAJOR		1
>  #define DRIVER_MINOR		0
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index b5fa715cbfb0..73e72aee6ec5 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -910,7 +910,6 @@ static const struct drm_driver msm_driver = {
>  	.fops               = &fops,
>  	.name               = "msm",
>  	.desc               = "MSM Snapdragon DRM",
> -	.date               = "20130625",
>  	.major              = MSM_VERSION_MAJOR,
>  	.minor              = MSM_VERSION_MINOR,
>  	.patchlevel         = MSM_VERSION_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> index 81ec91cef66c..02fe6b89f3aa 100644
> --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> @@ -248,7 +248,6 @@ static const struct drm_driver lcdif_driver = {
>  	.fops	= &fops,
>  	.name	= "imx-lcdif",
>  	.desc	= "i.MX LCDIF Controller DRM",
> -	.date	= "20220417",
>  	.major	= 1,
>  	.minor	= 0,
>  };
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> index 1c27a97dce03..129cc3fb4448 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> @@ -336,7 +336,6 @@ static const struct drm_driver mxsfb_driver = {
>  	.fops	= &fops,
>  	.name	= "mxsfb-drm",
>  	.desc	= "MXSFB Controller DRM",
> -	.date	= "20160824",
>  	.major	= 1,
>  	.minor	= 0,
>  };
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
> index a99c1d9855c9..744ae9d3305d 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> @@ -1326,11 +1326,6 @@ driver_stub = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -#ifdef GIT_REVISION
> -	.date = GIT_REVISION,
> -#else
> -	.date = DRIVER_DATE,
> -#endif
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
> index 685d6ca3d8aa..55abc510067b 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drv.h
> +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
> @@ -7,7 +7,6 @@
>  
>  #define DRIVER_NAME		"nouveau"
>  #define DRIVER_DESC		"nVidia Riva/TNT/GeForce/Quadro/Tesla/Tegra K1+"
> -#define DRIVER_DATE		"20120801"
>  
>  #define DRIVER_MAJOR		1
>  #define DRIVER_MINOR		4
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> index 1796cd20a877..a80e0f375a0e 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -28,7 +28,6 @@
>  
>  #define DRIVER_NAME		MODULE_NAME
>  #define DRIVER_DESC		"OMAP DRM"
> -#define DRIVER_DATE		"20110917"
>  #define DRIVER_MAJOR		1
>  #define DRIVER_MINOR		0
>  #define DRIVER_PATCHLEVEL	0
> @@ -653,7 +652,6 @@ static const struct drm_driver omap_drm_driver = {
>  	.fops = &omapdriver_fops,
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
> index 04d615df5259..fbaef3afcd66 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> @@ -636,7 +636,6 @@ static const struct drm_driver panfrost_drm_driver = {
>  	.fops			= &panfrost_drm_driver_fops,
>  	.name			= "panfrost",
>  	.desc			= "panfrost DRM",
> -	.date			= "20180908",
>  	.major			= 1,
>  	.minor			= 3,
>  
> diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
> index ac7e53f6e3f0..ad46a40ed9e1 100644
> --- a/drivers/gpu/drm/panthor/panthor_drv.c
> +++ b/drivers/gpu/drm/panthor/panthor_drv.c
> @@ -1505,7 +1505,6 @@ static const struct drm_driver panthor_drm_driver = {
>  	.fops = &panthor_drm_driver_fops,
>  	.name = "panthor",
>  	.desc = "Panthor DRM driver",
> -	.date = "20230801",
>  	.major = 1,
>  	.minor = 2,
>  
> diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
> index 4b96f48cf630..56ff6a3fb483 100644
> --- a/drivers/gpu/drm/pl111/pl111_drv.c
> +++ b/drivers/gpu/drm/pl111/pl111_drv.c
> @@ -220,7 +220,6 @@ static const struct drm_driver pl111_drm_driver = {
>  	.fops = &drm_fops,
>  	.name = "pl111",
>  	.desc = DRIVER_DESC,
> -	.date = "20170317",
>  	.major = 1,
>  	.minor = 0,
>  	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
> index f15e9583b098..417061ae59eb 100644
> --- a/drivers/gpu/drm/qxl/qxl_drv.c
> +++ b/drivers/gpu/drm/qxl/qxl_drv.c
> @@ -300,7 +300,6 @@ static struct drm_driver qxl_driver = {
>  	.num_ioctls = ARRAY_SIZE(qxl_ioctls),
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = 0,
>  	.minor = 1,
>  	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
> index b5fc14c9525d..cc02b5f10ad9 100644
> --- a/drivers/gpu/drm/qxl/qxl_drv.h
> +++ b/drivers/gpu/drm/qxl/qxl_drv.h
> @@ -54,7 +54,6 @@ struct iosys_map;
>  
>  #define DRIVER_NAME		"qxl"
>  #define DRIVER_DESC		"RH QXL"
> -#define DRIVER_DATE		"20120117"
>  
>  #define DRIVER_MAJOR 0
>  #define DRIVER_MINOR 1
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
> index 5ce7e91bedad..267f082bc430 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -603,7 +603,6 @@ static const struct drm_driver kms_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = KMS_DRIVER_MAJOR,
>  	.minor = KMS_DRIVER_MINOR,
>  	.patchlevel = KMS_DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
> index 02a65971d140..0f3dbffc492d 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.h
> +++ b/drivers/gpu/drm/radeon/radeon_drv.h
> @@ -43,7 +43,6 @@
>  
>  #define DRIVER_NAME		"radeon"
>  #define DRIVER_DESC		"ATI Radeon"
> -#define DRIVER_DATE		"20080528"
>  
>  /* Interface history:
>   *
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
> index 0f5204ef996e..be39b107b98c 100644
> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
> @@ -611,7 +611,6 @@ static const struct drm_driver rcar_du_driver = {
>  	.fops			= &rcar_du_fops,
>  	.name			= "rcar-du",
>  	.desc			= "Renesas R-Car Display Unit",
> -	.date			= "20130110",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
> index 0a03a20f663b..9bbdc4d63d88 100644
> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
> @@ -84,7 +84,6 @@ static const struct drm_driver rzg2l_du_driver = {
>  	.fops			= &rzg2l_du_fops,
>  	.name			= "rzg2l-du",
>  	.desc			= "Renesas RZ/G2L Display Unit",
> -	.date			= "20230410",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> index 40b582ee178e..387eb602dadf 100644
> --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> @@ -107,7 +107,6 @@ static const struct drm_driver shmob_drm_driver = {
>  	.fops			= &shmob_drm_fops,
>  	.name			= "shmob-drm",
>  	.desc			= "Renesas SH Mobile DRM",
> -	.date			= "20120424",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index 0393b48ad65b..1fe4399d6901 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -39,7 +39,6 @@
>  
>  #define DRIVER_NAME	"rockchip"
>  #define DRIVER_DESC	"RockChip Soc DRM"
> -#define DRIVER_DATE	"20140818"
>  #define DRIVER_MAJOR	1
>  #define DRIVER_MINOR	0
>  
> @@ -235,7 +234,6 @@ static const struct drm_driver rockchip_drm_driver = {
>  	.fops			= &rockchip_drm_driver_fops,
>  	.name	= DRIVER_NAME,
>  	.desc	= DRIVER_DESC,
> -	.date	= DRIVER_DATE,
>  	.major	= DRIVER_MAJOR,
>  	.minor	= DRIVER_MINOR,
>  };
> diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
> index a737f650c2bc..7b9f8fc193ac 100644
> --- a/drivers/gpu/drm/solomon/ssd130x.c
> +++ b/drivers/gpu/drm/solomon/ssd130x.c
> @@ -39,7 +39,6 @@
>  
>  #define DRIVER_NAME	"ssd130x"
>  #define DRIVER_DESC	"DRM driver for Solomon SSD13xx OLED displays"
> -#define DRIVER_DATE	"20220131"
>  #define DRIVER_MAJOR	1
>  #define DRIVER_MINOR	0
>  
> @@ -1784,7 +1783,6 @@ static const struct drm_driver ssd130x_drm_driver = {
>  	DRM_FBDEV_SHMEM_DRIVER_OPS,
>  	.name			= DRIVER_NAME,
>  	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>  	.major			= DRIVER_MAJOR,
>  	.minor			= DRIVER_MINOR,
>  	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> diff --git a/drivers/gpu/drm/sprd/sprd_drm.c b/drivers/gpu/drm/sprd/sprd_drm.c
> index a74cd0caf645..867ee2d8997f 100644
> --- a/drivers/gpu/drm/sprd/sprd_drm.c
> +++ b/drivers/gpu/drm/sprd/sprd_drm.c
> @@ -23,7 +23,6 @@
>  
>  #define DRIVER_NAME	"sprd"
>  #define DRIVER_DESC	"Spreadtrum SoCs' DRM Driver"
> -#define DRIVER_DATE	"20200201"
>  #define DRIVER_MAJOR	1
>  #define DRIVER_MINOR	0
>  
> @@ -59,7 +58,6 @@ static struct drm_driver sprd_drm_drv = {
>  
>  	.name			= DRIVER_NAME,
>  	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>  	.major			= DRIVER_MAJOR,
>  	.minor			= DRIVER_MINOR,
>  };
> diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
> index a6c13318aa0b..46e6b674fa54 100644
> --- a/drivers/gpu/drm/sti/sti_drv.c
> +++ b/drivers/gpu/drm/sti/sti_drv.c
> @@ -29,7 +29,6 @@
>  
>  #define DRIVER_NAME	"sti"
>  #define DRIVER_DESC	"STMicroelectronics SoC DRM"
> -#define DRIVER_DATE	"20140601"
>  #define DRIVER_MAJOR	1
>  #define DRIVER_MINOR	0
>  
> @@ -143,7 +142,6 @@ static const struct drm_driver sti_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  };
> diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
> index d181d11b277b..40a62c57e04c 100644
> --- a/drivers/gpu/drm/stm/drv.c
> +++ b/drivers/gpu/drm/stm/drv.c
> @@ -62,7 +62,6 @@ static const struct drm_driver drv_driver = {
>  	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
>  	.name = "stm",
>  	.desc = "STMicroelectronics SoC DRM",
> -	.date = "20170330",
>  	.major = 1,
>  	.minor = 0,
>  	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
> index a7c11b795e98..025b0bdcbfd9 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -50,7 +50,6 @@ static const struct drm_driver sun4i_drv_driver = {
>  	.fops			= &sun4i_drv_fops,
>  	.name			= "sun4i-drm",
>  	.desc			= "Allwinner sun4i Display Engine",
> -	.date			= "20150629",
>  	.major			= 1,
>  	.minor			= 0,
>  
> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
> index 34878f5d2918..4596073fe28f 100644
> --- a/drivers/gpu/drm/tegra/drm.c
> +++ b/drivers/gpu/drm/tegra/drm.c
> @@ -35,7 +35,6 @@
>  
>  #define DRIVER_NAME "tegra"
>  #define DRIVER_DESC "NVIDIA Tegra graphics"
> -#define DRIVER_DATE "20120330"
>  #define DRIVER_MAJOR 1
>  #define DRIVER_MINOR 0
>  #define DRIVER_PATCHLEVEL 0
> @@ -901,7 +900,6 @@ static const struct drm_driver tegra_drm_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
> index 53bc219c097f..ee1132d581f5 100644
> --- a/drivers/gpu/drm/tidss/tidss_drv.c
> +++ b/drivers/gpu/drm/tidss/tidss_drv.c
> @@ -113,7 +113,6 @@ static const struct drm_driver tidss_driver = {
>  	DRM_FBDEV_DMA_DRIVER_OPS,
>  	.name			= "tidss",
>  	.desc			= "TI Keystone DSS",
> -	.date			= "20180215",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> index 821d0ba26287..8013f01dbdf0 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> @@ -481,7 +481,6 @@ static const struct drm_driver tilcdc_driver = {
>  	.fops               = &fops,
>  	.name               = "tilcdc",
>  	.desc               = "TI LCD Controller DRM",
> -	.date               = "20121205",
>  	.major              = 1,
>  	.minor              = 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c
> index 5a0c8a874421..1e570f6f639f 100644
> --- a/drivers/gpu/drm/tiny/arcpgu.c
> +++ b/drivers/gpu/drm/tiny/arcpgu.c
> @@ -367,7 +367,6 @@ static const struct drm_driver arcpgu_drm_driver = {
>  	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
>  	.name = "arcpgu",
>  	.desc = "ARC PGU Controller",
> -	.date = "20160219",
>  	.major = 1,
>  	.minor = 0,
>  	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
> index 71a1f15d6ac9..89a699370a59 100644
> --- a/drivers/gpu/drm/tiny/bochs.c
> +++ b/drivers/gpu/drm/tiny/bochs.c
> @@ -680,7 +680,6 @@ static const struct drm_driver bochs_driver = {
>  	.fops			= &bochs_fops,
>  	.name			= "bochs-drm",
>  	.desc			= "bochs dispi vga interface (qemu stdvga)",
> -	.date			= "20130925",
>  	.major			= 1,
>  	.minor			= 0,
>  	DRM_GEM_SHMEM_DRIVER_OPS,
> diff --git a/drivers/gpu/drm/tiny/cirrus-qemu.c b/drivers/gpu/drm/tiny/cirrus-qemu.c
> index c0ae316888e2..52ec1e4ea9e5 100644
> --- a/drivers/gpu/drm/tiny/cirrus-qemu.c
> +++ b/drivers/gpu/drm/tiny/cirrus-qemu.c
> @@ -48,7 +48,6 @@
>  
>  #define DRIVER_NAME "cirrus-qemu"
>  #define DRIVER_DESC "qemu cirrus vga"
> -#define DRIVER_DATE "2019"
>  #define DRIVER_MAJOR 2
>  #define DRIVER_MINOR 0
>  
> @@ -659,7 +658,6 @@ static const struct drm_driver cirrus_driver = {
>  
>  	.name		 = DRIVER_NAME,
>  	.desc		 = DRIVER_DESC,
> -	.date		 = DRIVER_DATE,
>  	.major		 = DRIVER_MAJOR,
>  	.minor		 = DRIVER_MINOR,
>  
> diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
> index 47dbee84d58b..41e9bfb2e2ff 100644
> --- a/drivers/gpu/drm/tiny/gm12u320.c
> +++ b/drivers/gpu/drm/tiny/gm12u320.c
> @@ -34,7 +34,6 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
>  
>  #define DRIVER_NAME		"gm12u320"
>  #define DRIVER_DESC		"Grain Media GM12U320 USB projector display"
> -#define DRIVER_DATE		"2019"
>  #define DRIVER_MAJOR		1
>  #define DRIVER_MINOR		0
>  
> @@ -626,7 +625,6 @@ static const struct drm_driver gm12u320_drm_driver = {
>  
>  	.name		 = DRIVER_NAME,
>  	.desc		 = DRIVER_DESC,
> -	.date		 = DRIVER_DATE,
>  	.major		 = DRIVER_MAJOR,
>  	.minor		 = DRIVER_MINOR,
>  
> diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c
> index 910279ebbbaa..df263818f45f 100644
> --- a/drivers/gpu/drm/tiny/hx8357d.c
> +++ b/drivers/gpu/drm/tiny/hx8357d.c
> @@ -199,7 +199,6 @@ static const struct drm_driver hx8357d_driver = {
>  	.debugfs_init		= mipi_dbi_debugfs_init,
>  	.name			= "hx8357d",
>  	.desc			= "HX8357D",
> -	.date			= "20181023",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c
> index e54ce120692f..62cadf5e033d 100644
> --- a/drivers/gpu/drm/tiny/ili9163.c
> +++ b/drivers/gpu/drm/tiny/ili9163.c
> @@ -118,7 +118,6 @@ static struct drm_driver ili9163_driver = {
>  	.debugfs_init		= mipi_dbi_debugfs_init,
>  	.name			= "ili9163",
>  	.desc			= "Ilitek ILI9163",
> -	.date			= "20210208",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
> index f322e67f473a..6de44ff69b51 100644
> --- a/drivers/gpu/drm/tiny/ili9225.c
> +++ b/drivers/gpu/drm/tiny/ili9225.c
> @@ -364,7 +364,6 @@ static const struct drm_driver ili9225_driver = {
>  	DRM_FBDEV_DMA_DRIVER_OPS,
>  	.name			= "ili9225",
>  	.desc			= "Ilitek ILI9225",
> -	.date			= "20171106",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c
> index 356c7f107c3e..e55029433509 100644
> --- a/drivers/gpu/drm/tiny/ili9341.c
> +++ b/drivers/gpu/drm/tiny/ili9341.c
> @@ -155,7 +155,6 @@ static const struct drm_driver ili9341_driver = {
>  	.debugfs_init		= mipi_dbi_debugfs_init,
>  	.name			= "ili9341",
>  	.desc			= "Ilitek ILI9341",
> -	.date			= "20180514",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
> index f5b1d21f7109..093661c771a0 100644
> --- a/drivers/gpu/drm/tiny/ili9486.c
> +++ b/drivers/gpu/drm/tiny/ili9486.c
> @@ -177,7 +177,6 @@ static const struct drm_driver ili9486_driver = {
>  	.debugfs_init		= mipi_dbi_debugfs_init,
>  	.name			= "ili9486",
>  	.desc			= "Ilitek ILI9486",
> -	.date			= "20200118",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
> index 61e33376fbc9..b6b4664908ae 100644
> --- a/drivers/gpu/drm/tiny/mi0283qt.c
> +++ b/drivers/gpu/drm/tiny/mi0283qt.c
> @@ -159,7 +159,6 @@ static const struct drm_driver mi0283qt_driver = {
>  	.debugfs_init		= mipi_dbi_debugfs_init,
>  	.name			= "mi0283qt",
>  	.desc			= "Multi-Inno MI0283QT",
> -	.date			= "20160614",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c
> index b27ed3677bfd..cd5916752507 100644
> --- a/drivers/gpu/drm/tiny/ofdrm.c
> +++ b/drivers/gpu/drm/tiny/ofdrm.c
> @@ -25,7 +25,6 @@
>  
>  #define DRIVER_NAME	"ofdrm"
>  #define DRIVER_DESC	"DRM driver for OF platform devices"
> -#define DRIVER_DATE	"20220501"
>  #define DRIVER_MAJOR	1
>  #define DRIVER_MINOR	0
>  
> @@ -1348,7 +1347,6 @@ static struct drm_driver ofdrm_driver = {
>  	DRM_FBDEV_SHMEM_DRIVER_OPS,
>  	.name			= DRIVER_NAME,
>  	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>  	.major			= DRIVER_MAJOR,
>  	.minor			= DRIVER_MINOR,
>  	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
> index 79d5818cbbe6..4786b8144a9f 100644
> --- a/drivers/gpu/drm/tiny/panel-mipi-dbi.c
> +++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
> @@ -269,7 +269,6 @@ static const struct drm_driver panel_mipi_dbi_driver = {
>  	.debugfs_init		= mipi_dbi_debugfs_init,
>  	.name			= "panel-mipi-dbi",
>  	.desc			= "MIPI DBI compatible display panel",
> -	.date			= "20220103",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
> index 9373063a13fc..52ba6c699bc8 100644
> --- a/drivers/gpu/drm/tiny/repaper.c
> +++ b/drivers/gpu/drm/tiny/repaper.c
> @@ -917,7 +917,6 @@ static const struct drm_driver repaper_driver = {
>  	DRM_FBDEV_DMA_DRIVER_OPS,
>  	.name			= "repaper",
>  	.desc			= "Pervasive Displays RePaper e-ink panels",
> -	.date			= "20170405",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/sharp-memory.c b/drivers/gpu/drm/tiny/sharp-memory.c
> index d87068126f9b..03d2850310c4 100644
> --- a/drivers/gpu/drm/tiny/sharp-memory.c
> +++ b/drivers/gpu/drm/tiny/sharp-memory.c
> @@ -107,7 +107,6 @@ static const struct drm_driver sharp_memory_drm_driver = {
>  	DRM_FBDEV_DMA_DRIVER_OPS,
>  	.name			= "sharp_memory_display",
>  	.desc			= "Sharp Display Memory LCD",
> -	.date			= "20231129",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
> index b3a2fc11dcf0..b47ca2d902d9 100644
> --- a/drivers/gpu/drm/tiny/simpledrm.c
> +++ b/drivers/gpu/drm/tiny/simpledrm.c
> @@ -31,7 +31,6 @@
>  
>  #define DRIVER_NAME	"simpledrm"
>  #define DRIVER_DESC	"DRM driver for simple-framebuffer platform devices"
> -#define DRIVER_DATE	"20200625"
>  #define DRIVER_MAJOR	1
>  #define DRIVER_MINOR	0
>  
> @@ -1015,7 +1014,6 @@ static struct drm_driver simpledrm_driver = {
>  	DRM_FBDEV_SHMEM_DRIVER_OPS,
>  	.name			= DRIVER_NAME,
>  	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>  	.major			= DRIVER_MAJOR,
>  	.minor			= DRIVER_MINOR,
>  	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
> index 7bfd4296c1c9..a29672d84ede 100644
> --- a/drivers/gpu/drm/tiny/st7586.c
> +++ b/drivers/gpu/drm/tiny/st7586.c
> @@ -295,7 +295,6 @@ static const struct drm_driver st7586_driver = {
>  	.debugfs_init		= mipi_dbi_debugfs_init,
>  	.name			= "st7586",
>  	.desc			= "Sitronix ST7586",
> -	.date			= "20170801",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
> index 6832ca590127..1d60f6e5b3bc 100644
> --- a/drivers/gpu/drm/tiny/st7735r.c
> +++ b/drivers/gpu/drm/tiny/st7735r.c
> @@ -160,7 +160,6 @@ static const struct drm_driver st7735r_driver = {
>  	.debugfs_init		= mipi_dbi_debugfs_init,
>  	.name			= "st7735r",
>  	.desc			= "Sitronix ST7735R",
> -	.date			= "20171128",
>  	.major			= 1,
>  	.minor			= 0,
>  };
> diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c
> index cb66dbbe2801..65a0d4301160 100644
> --- a/drivers/gpu/drm/tve200/tve200_drv.c
> +++ b/drivers/gpu/drm/tve200/tve200_drv.c
> @@ -146,7 +146,6 @@ static const struct drm_driver tve200_drm_driver = {
>  	.fops = &drm_fops,
>  	.name = "tve200",
>  	.desc = DRIVER_DESC,
> -	.date = "20170703",
>  	.major = 1,
>  	.minor = 0,
>  	.patchlevel = 0,
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index 6c182b21028e..05b3a152cc33 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -78,7 +78,6 @@ static const struct drm_driver driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
> index 1eb716d9dad5..be00dc1d87a1 100644
> --- a/drivers/gpu/drm/udl/udl_drv.h
> +++ b/drivers/gpu/drm/udl/udl_drv.h
> @@ -26,7 +26,6 @@ struct drm_mode_create_dumb;
>  
>  #define DRIVER_NAME		"udl"
>  #define DRIVER_DESC		"DisplayLink"
> -#define DRIVER_DATE		"20120220"
>  
>  #define DRIVER_MAJOR		0
>  #define DRIVER_MINOR		0
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
> index fb35c5c3f1a7..9d8de9146cb0 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.c
> +++ b/drivers/gpu/drm/v3d/v3d_drv.c
> @@ -31,7 +31,6 @@
>  
>  #define DRIVER_NAME "v3d"
>  #define DRIVER_DESC "Broadcom V3D graphics"
> -#define DRIVER_DATE "20180419"
>  #define DRIVER_MAJOR 1
>  #define DRIVER_MINOR 0
>  #define DRIVER_PATCHLEVEL 0
> @@ -248,7 +247,6 @@ static const struct drm_driver v3d_drm_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> index d9d884aad97f..bb861f0a0a31 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> @@ -189,7 +189,6 @@ static const struct drm_driver driver = {
>  	.fops = &vbox_fops,
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> index e77bd6512eb1..dfa935f381a6 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> @@ -25,7 +25,6 @@
>  
>  #define DRIVER_NAME         "vboxvideo"
>  #define DRIVER_DESC         "Oracle VM VirtualBox Graphics Card"
> -#define DRIVER_DATE         "20130823"
>  
>  #define DRIVER_MAJOR        1
>  #define DRIVER_MINOR        0
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> index ee5df153c2a6..e88a7ee486c6 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.c
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -47,7 +47,6 @@
>  
>  #define DRIVER_NAME "vc4"
>  #define DRIVER_DESC "Broadcom VC4 graphics"
> -#define DRIVER_DATE "20140616"
>  #define DRIVER_MAJOR 0
>  #define DRIVER_MINOR 0
>  #define DRIVER_PATCHLEVEL 0
> @@ -222,7 +221,6 @@ const struct drm_driver vc4_drm_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> @@ -244,7 +242,6 @@ const struct drm_driver vc5_drm_driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
> index c5e3e5457737..2752ab4f1c97 100644
> --- a/drivers/gpu/drm/vgem/vgem_drv.c
> +++ b/drivers/gpu/drm/vgem/vgem_drv.c
> @@ -47,7 +47,6 @@
>  
>  #define DRIVER_NAME	"vgem"
>  #define DRIVER_DESC	"Virtual GEM provider"
> -#define DRIVER_DATE	"20120112"
>  #define DRIVER_MAJOR	1
>  #define DRIVER_MINOR	0
>  
> @@ -121,7 +120,6 @@ static const struct drm_driver vgem_driver = {
>  
>  	.name	= DRIVER_NAME,
>  	.desc	= DRIVER_DESC,
> -	.date	= DRIVER_DATE,
>  	.major	= DRIVER_MAJOR,
>  	.minor	= DRIVER_MINOR,
>  };
> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
> index e216123ce6a5..6a67c6297d58 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_drv.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
> @@ -201,7 +201,6 @@ static const struct drm_driver driver = {
>  
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
> index 8328107edf78..f42ca9d8ed10 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
> @@ -45,7 +45,6 @@
>  
>  #define DRIVER_NAME "virtio_gpu"
>  #define DRIVER_DESC "virtio GPU"
> -#define DRIVER_DATE "0"
>  
>  #define DRIVER_MAJOR 0
>  #define DRIVER_MINOR 1
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
> index fa3331f612e3..e0409aba9349 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.c
> +++ b/drivers/gpu/drm/vkms/vkms_drv.c
> @@ -34,7 +34,6 @@
>  
>  #define DRIVER_NAME	"vkms"
>  #define DRIVER_DESC	"Virtual Kernel Mode Setting"
> -#define DRIVER_DATE	"20180514"
>  #define DRIVER_MAJOR	1
>  #define DRIVER_MINOR	0
>  
> @@ -116,7 +115,6 @@ static const struct drm_driver vkms_driver = {
>  
>  	.name			= DRIVER_NAME,
>  	.desc			= DRIVER_DESC,
> -	.date			= DRIVER_DATE,
>  	.major			= DRIVER_MAJOR,
>  	.minor			= DRIVER_MINOR,
>  };
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> index ded48554568a..1699236fca5a 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> @@ -1634,7 +1634,6 @@ static const struct drm_driver driver = {
>  	.fops = &vmwgfx_driver_fops,
>  	.name = VMWGFX_DRIVER_NAME,
>  	.desc = VMWGFX_DRIVER_DESC,
> -	.date = VMWGFX_DRIVER_DATE,
>  	.major = VMWGFX_DRIVER_MAJOR,
>  	.minor = VMWGFX_DRIVER_MINOR,
>  	.patchlevel = VMWGFX_DRIVER_PATCHLEVEL
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> index b21831ef214a..5275ef632d4b 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> @@ -57,7 +57,6 @@
>  
>  
>  #define VMWGFX_DRIVER_NAME "vmwgfx"
> -#define VMWGFX_DRIVER_DATE "20211206"
>  #define VMWGFX_DRIVER_MAJOR 2
>  #define VMWGFX_DRIVER_MINOR 20
>  #define VMWGFX_DRIVER_PATCHLEVEL 0
> diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
> index d6fccea1e083..56d4ffb650da 100644
> --- a/drivers/gpu/drm/xe/xe_device.c
> +++ b/drivers/gpu/drm/xe/xe_device.c
> @@ -271,7 +271,6 @@ static struct drm_driver driver = {
>  	.fops = &xe_driver_fops,
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> -	.date = DRIVER_DATE,
>  	.major = DRIVER_MAJOR,
>  	.minor = DRIVER_MINOR,
>  	.patchlevel = DRIVER_PATCHLEVEL,
> diff --git a/drivers/gpu/drm/xe/xe_drv.h b/drivers/gpu/drm/xe/xe_drv.h
> index d45b71426cc8..d61650d4aa0b 100644
> --- a/drivers/gpu/drm/xe/xe_drv.h
> +++ b/drivers/gpu/drm/xe/xe_drv.h
> @@ -10,7 +10,6 @@
>  
>  #define DRIVER_NAME		"xe"
>  #define DRIVER_DESC		"Intel Xe Graphics"
> -#define DRIVER_DATE		"20201103"
>  
>  /* Interface history:
>   *
> diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
> index 931d855bfbe8..1bda7ef606cc 100644
> --- a/drivers/gpu/drm/xen/xen_drm_front.c
> +++ b/drivers/gpu/drm/xen/xen_drm_front.c
> @@ -478,7 +478,6 @@ static const struct drm_driver xen_drm_driver = {
>  	.fops                      = &xen_drm_dev_fops,
>  	.name                      = "xendrm-du",
>  	.desc                      = "Xen PV DRM Display Unit",
> -	.date                      = "20180221",
>  	.major                     = 1,
>  	.minor                     = 0,
>  
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c
> index e272ecbce78d..b47463473472 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_kms.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c
> @@ -409,7 +409,6 @@ static const struct drm_driver zynqmp_dpsub_drm_driver = {
>  
>  	.name				= "zynqmp-dpsub",
>  	.desc				= "Xilinx DisplayPort Subsystem Driver",
> -	.date				= "20130509",
>  	.major				= 1,
>  	.minor				= 0,
>  };
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index 1bbbcb8e2d23..1b6e59139e6c 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -401,8 +401,6 @@ struct drm_driver {
>  	char *name;
>  	/** @desc: driver description */
>  	char *desc;
> -	/** @date: driver date, unused, to be removed */
> -	char *date;
>  
>  	/**
>  	 * @driver_features:
> -- 
> 2.39.5
> 


From dmitry.baryshkov at linaro.org  Mon Dec  9 08:17:23 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 9 Dec 2024 18:17:23 +0200
Subject: [PATCH v6 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <20241209033923.3009629-13-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
 <20241209033923.3009629-13-victor.liu@nxp.com>
Message-ID: <3j4fguv4oienfaj4fghpiqpmnq3aczu4azhdo5jzvywc5mawm5@hh33p3dhf6xa>

On Mon, Dec 09, 2024 at 11:39:16AM +0800, Liu Ying wrote:
> i.MX8qxp Display Controller(DC) is comprised of three main components that
> include a blit engine for 2D graphics accelerations, display controller for
> display output processing, as well as a command sequencer.  Add kernel
> mode setting support for the display controller part with two CRTCs and
> two primary planes(backed by FetchLayer and FetchWarp respectively).  The
> registers of the display controller are accessed without command sequencer
> involved, instead just by using CPU.  The command sequencer is supposed to
> be used by the blit engine.
> 
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v6:
> * No change.
> 
> v5:
> * Replace .remove_new with .remove in dc-drv.c. (Uwe)
> 
> v4:
> * Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
>   function calls from KMS routine to initialization stage. (Dmitry)
> * Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
>   appropriate .h header files or .c source files. (Dmitry)
> * Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
> * Drop dc_drm->pe_rpm_count. (Dmitry)
> * Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
> * Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
>   Instead, put it in struct dc_crtc.  (Dmitry)
> * Call devm_request_irq() to request IRQs, instead of using drmm action.
>   (Dmitry)
> * Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
> * Select DRM_CLIENT_SELECTION due to rebase.
> * Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
> * Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
> * Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
>   rebase.
> * Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
>   register dc_drm_component_unbind_all() action.
> * Request interrupts in dc_crtc_post_init() after encoder initialization to
>   make sure next bridge is found first.
> 
> v3:
> * No change.
> 
> v2:
> * Find next bridge from TCon's port.
> * Drop drm/drm_module.h include from dc-drv.c.
> 
>  drivers/gpu/drm/imx/dc/Kconfig    |   5 +
>  drivers/gpu/drm/imx/dc/Makefile   |   5 +-
>  drivers/gpu/drm/imx/dc/dc-crtc.c  | 558 ++++++++++++++++++++++++++++++
>  drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
>  drivers/gpu/drm/imx/dc/dc-drv.c   | 244 +++++++++++++
>  drivers/gpu/drm/imx/dc/dc-drv.h   |  19 +
>  drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
>  drivers/gpu/drm/imx/dc/dc-kms.h   |  58 ++++
>  drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
>  9 files changed, 1274 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
>  create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
> 
> diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
> index 1fc84c7475de..415993207f2e 100644
> --- a/drivers/gpu/drm/imx/dc/Kconfig
> +++ b/drivers/gpu/drm/imx/dc/Kconfig
> @@ -1,6 +1,11 @@
>  config DRM_IMX8_DC
>  	tristate "Freescale i.MX8 Display Controller Graphics"
>  	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
> +	select DRM_CLIENT_SELECTION
> +	select DRM_GEM_DMA_HELPER
> +	select DRM_KMS_HELPER
> +	select DRM_DISPLAY_HELPER
> +	select DRM_BRIDGE_CONNECTOR
>  	select GENERIC_IRQ_CHIP
>  	select REGMAP
>  	select REGMAP_MMIO
> diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
> index 1ce3e8a8db22..b9d33c074984 100644
> --- a/drivers/gpu/drm/imx/dc/Makefile
> +++ b/drivers/gpu/drm/imx/dc/Makefile
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
>  
> -imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
> -		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
> +imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
> +		    dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
> +		    dc-plane.o dc-tc.o
>  
>  obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
> diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
> new file mode 100644
> index 000000000000..fd6daa1807d8
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
> @@ -0,0 +1,558 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#include <linux/completion.h>
> +#include <linux/container_of.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqreturn.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/spinlock.h>
> +
> +#include <drm/drm_atomic.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_atomic_state_helper.h>
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_device.h>
> +#include <drm/drm_drv.h>
> +#include <drm/drm_modes.h>
> +#include <drm/drm_modeset_helper_vtables.h>
> +#include <drm/drm_plane.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_vblank.h>
> +
> +#include "dc-de.h"
> +#include "dc-drv.h"
> +#include "dc-kms.h"
> +#include "dc-pe.h"
> +
> +#define dc_crtc_dbg(crtc, fmt, ...)					\
> +do {									\
> +	typeof(crtc) _crtc = (crtc);					\

Use exact type instead of typeof.

> +	drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
> +		    _crtc->base.id, _crtc->name, ##__VA_ARGS__);	\
> +} while (0)
> +
> +#define dc_crtc_err(crtc, fmt, ...)					\
> +do {									\
> +	typeof(crtc) _crtc = (crtc);					\
> +	drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
> +		_crtc->base.id, _crtc->name, ##__VA_ARGS__);		\
> +} while (0)
> +
> +#define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c)				\
> +do {									\
> +	unsigned long ret;						\
> +	ret = wait_for_completion_timeout(&dc_crtc->c, HZ);		\
> +	if (ret == 0)							\
> +		dc_crtc_err(crtc, "%s: wait for " #c " timeout\n",	\
> +							__func__);	\
> +} while (0)
> +
> +#define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg)					\
> +do {									\
> +	typeof(fg) _fg = (fg);						\
> +	if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) {		\
> +		dc_fg_secondary_clear_channel_status(_fg);		\
> +		dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n",		\
> +							__func__);	\
> +	}								\
> +} while (0)
> +
> +#define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg)			\
> +do {									\
> +	if (dc_fg_wait_for_secondary_syncup(fg))			\
> +		dc_crtc_err(crtc,					\
> +			"%s: FrameGen secondary channel isn't syncup\n",\
> +							__func__);	\
> +} while (0)
> +
> +static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
> +{
> +	return container_of(crtc, struct dc_crtc, base);
> +}
> +
> +static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
> +{
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +
> +	return dc_fg_get_frame_index(dc_crtc->fg);
> +}
> +
> +static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
> +{
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +
> +	enable_irq(dc_crtc->irq_dec_framecomplete);
> +
> +	return 0;
> +}
> +
> +static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
> +{
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +
> +	disable_irq_nosync(dc_crtc->irq_dec_framecomplete);

Why is it _nosync?

> +}
> +
> +static irqreturn_t
> +dc_crtc_dec_framecomplete_irq_handler(int irq, void *dev_id)
> +{
> +	struct dc_crtc *dc_crtc = dev_id;
> +	struct drm_crtc *crtc = &dc_crtc->base;
> +	unsigned long flags;
> +
> +	drm_crtc_handle_vblank(crtc);
> +
> +	spin_lock_irqsave(&crtc->dev->event_lock, flags);
> +	if (dc_crtc->event) {
> +		drm_crtc_send_vblank_event(crtc, dc_crtc->event);
> +		dc_crtc->event = NULL;
> +		drm_crtc_vblank_put(crtc);
> +	}
> +	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t dc_crtc_common_irq_handler(int irq, void *dev_id)
> +{
> +	struct dc_crtc *dc_crtc = dev_id;
> +
> +	if (irq == dc_crtc->irq_dec_seqcomplete)
> +		complete(&dc_crtc->dec_seqcomplete_done);
> +	else if (irq == dc_crtc->irq_dec_shdld)
> +		complete(&dc_crtc->dec_shdld_done);
> +	else if (irq == dc_crtc->irq_ed_cont_shdld)
> +		complete(&dc_crtc->ed_cont_shdld_done);
> +	else if (irq == dc_crtc->irq_ed_safe_shdld)
> +		complete(&dc_crtc->ed_safe_shdld_done);

Is there any reason to have a single multiplex handler instead of having
4 separate handlers, each doing one simple thing?

> +
> +	return IRQ_HANDLED;
> +}
> +
> +static const struct drm_crtc_funcs dc_crtc_funcs = {
> +	.reset			= drm_atomic_helper_crtc_reset,
> +	.destroy		= drm_crtc_cleanup,
> +	.set_config		= drm_atomic_helper_set_config,
> +	.page_flip		= drm_atomic_helper_page_flip,
> +	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
> +	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
> +	.get_vblank_counter	= dc_crtc_get_vblank_counter,
> +	.enable_vblank		= dc_crtc_enable_vblank,
> +	.disable_vblank		= dc_crtc_disable_vblank,
> +	.get_vblank_timestamp	= drm_crtc_vblank_helper_get_vblank_timestamp,
> +};
> +
> +static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
> +{
> +	struct drm_crtc *crtc = crtc_state->crtc;
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +
> +	spin_lock_irq(&crtc->dev->event_lock);
> +	if (crtc_state->event) {
> +		WARN_ON(drm_crtc_vblank_get(crtc));
> +		WARN_ON(dc_crtc->event);
> +		dc_crtc->event = crtc_state->event;
> +		crtc_state->event = NULL;
> +	}
> +	spin_unlock_irq(&crtc->dev->event_lock);
> +}
> +
> +static enum drm_mode_status
> +dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
> +{
> +	return dc_fg_check_clock(dc_crtc->fg, clk_khz);
> +}

inline

> +
> +static enum drm_mode_status
> +dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
> +{
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +	enum drm_mode_status status;
> +
> +	status = dc_crtc_check_clock(dc_crtc, mode->clock);
> +	if (status != MODE_OK)
> +		return status;
> +
> +	if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
> +		return MODE_CLOCK_HIGH;
> +
> +	return MODE_OK;
> +}
> +
> +static int
> +dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
> +{
> +	struct drm_crtc_state *new_crtc_state =
> +				drm_atomic_get_new_crtc_state(state, crtc);
> +	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +	enum drm_mode_status status;
> +
> +	status = dc_crtc_check_clock(dc_crtc, adj->clock);
> +	if (status != MODE_OK)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static void
> +dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
> +{
> +	struct drm_crtc_state *new_crtc_state =
> +				drm_atomic_get_new_crtc_state(state, crtc);
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +	int idx, ret;
> +
> +	if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
> +	    !new_crtc_state->active)
> +		return;
> +
> +	if (!drm_dev_enter(crtc->dev, &idx))
> +		return;
> +
> +	/* request pixel engine power-on when CRTC starts to be active */
> +	ret = pm_runtime_resume_and_get(dc_crtc->pe->dev);
> +	if (ret)
> +		dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
> +			    ret);
> +
> +	drm_dev_exit(idx);
> +}
> +
> +static void
> +dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
> +{
> +	struct drm_crtc_state *old_crtc_state =
> +				drm_atomic_get_old_crtc_state(state, crtc);
> +	struct drm_crtc_state *new_crtc_state =
> +				drm_atomic_get_new_crtc_state(state, crtc);
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +	int idx;
> +
> +	if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
> +	    (!old_crtc_state->active && !new_crtc_state->active))
> +		return;
> +
> +	if (!drm_dev_enter(crtc->dev, &idx))
> +		goto out;
> +
> +	enable_irq(dc_crtc->irq_ed_cont_shdld);
> +
> +	/* flush plane update out to display */
> +	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
> +
> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
> +
> +	disable_irq(dc_crtc->irq_ed_cont_shdld);
> +
> +	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
> +
> +	drm_dev_exit(idx);
> +
> +out:
> +	dc_crtc_queue_state_event(new_crtc_state);
> +}
> +
> +static void
> +dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
> +{
> +	struct drm_crtc_state *new_crtc_state =
> +				drm_atomic_get_new_crtc_state(state, crtc);
> +	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +	enum dc_link_id cf_link;
> +	int idx, ret;
> +
> +	dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
> +
> +	drm_crtc_vblank_on(crtc);
> +
> +	if (!drm_dev_enter(crtc->dev, &idx))
> +		goto out;
> +
> +	/* request display engine power-on when CRTC is enabled */
> +	ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
> +	if (ret < 0)
> +		dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
> +			    ret);
> +
> +	enable_irq(dc_crtc->irq_dec_shdld);
> +	enable_irq(dc_crtc->irq_ed_cont_shdld);
> +	enable_irq(dc_crtc->irq_ed_safe_shdld);
> +
> +	dc_fg_cfg_videomode(dc_crtc->fg, adj);
> +
> +	dc_cf_framedimensions(dc_crtc->cf_cont,
> +			      adj->crtc_hdisplay, adj->crtc_vdisplay);
> +	dc_cf_framedimensions(dc_crtc->cf_safe,
> +			      adj->crtc_hdisplay, adj->crtc_vdisplay);
> +
> +	/* constframe in safety stream shows blue frame */
> +	dc_cf_constantcolor_blue(dc_crtc->cf_safe);
> +	cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
> +	dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
> +
> +	/* show CRTC background if no plane is enabled */
> +	if (new_crtc_state->plane_mask == 0) {
> +		/* constframe in content stream shows black frame */
> +		dc_cf_constantcolor_black(dc_crtc->cf_cont);
> +
> +		cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
> +		dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
> +	}
> +
> +	dc_fg_enable_clock(dc_crtc->fg);
> +	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
> +	dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
> +	dc_fg_shdtokgen(dc_crtc->fg);
> +	dc_fg_enable(dc_crtc->fg);
> +
> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdld_done);
> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdld_done);
> +
> +	disable_irq(dc_crtc->irq_ed_safe_shdld);
> +	disable_irq(dc_crtc->irq_ed_cont_shdld);
> +	disable_irq(dc_crtc->irq_dec_shdld);
> +
> +	DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
> +
> +	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
> +
> +	drm_dev_exit(idx);
> +
> +out:
> +	dc_crtc_queue_state_event(new_crtc_state);
> +}
> +
> +static void
> +dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
> +{
> +	struct drm_crtc_state *new_crtc_state =
> +				drm_atomic_get_new_crtc_state(state, crtc);
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +	int idx, ret;
> +
> +	if (!drm_dev_enter(crtc->dev, &idx))
> +		goto out;
> +
> +	enable_irq(dc_crtc->irq_dec_seqcomplete);
> +	dc_fg_disable(dc_crtc->fg);
> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
> +	disable_irq(dc_crtc->irq_dec_seqcomplete);
> +
> +	dc_fg_disable_clock(dc_crtc->fg);
> +
> +	/* request pixel engine power-off as plane is off too */
> +	ret = pm_runtime_put(dc_crtc->pe->dev);
> +	if (ret)
> +		dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
> +			    ret);
> +
> +	/* request display engine power-off when CRTC is disabled */
> +	ret = pm_runtime_put(dc_crtc->de->dev);

Can this be expressed as a devlink between PE and DE?

> +	if (ret < 0)
> +		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
> +			    ret);
> +
> +	drm_dev_exit(idx);
> +
> +out:
> +	drm_crtc_vblank_off(crtc);
> +
> +	spin_lock_irq(&crtc->dev->event_lock);
> +	if (new_crtc_state->event && !new_crtc_state->active) {
> +		drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
> +		new_crtc_state->event = NULL;
> +	}
> +	spin_unlock_irq(&crtc->dev->event_lock);
> +}
> +
> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc)
> +{
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +	int ret;
> +
> +	if (!dc_fg_wait_for_frame_index_moving(dc_crtc->fg))
> +		return;
> +
> +	dc_fg_disable_clock(dc_crtc->fg);
> +
> +	if (pm_runtime_active(dc_crtc->pe->dev)) {
> +		ret = pm_runtime_put_sync(dc_crtc->pe->dev);
> +		if (ret)
> +			dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
> +				    ret);
> +	}
> +
> +	ret = pm_runtime_put_sync(dc_crtc->de->dev);
> +	if (ret < 0)
> +		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
> +			    ret);
> +}
> +
> +static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
> +					 bool in_vblank_irq,
> +					 int *vpos, int *hpos,
> +					 ktime_t *stime, ktime_t *etime,
> +					 const struct drm_display_mode *mode)
> +{
> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> +	int vdisplay = mode->crtc_vdisplay;
> +	int vtotal = mode->crtc_vtotal;
> +	bool reliable;
> +	int line;
> +	int idx;
> +
> +	if (stime)
> +		*stime = ktime_get();
> +
> +	if (!drm_dev_enter(crtc->dev, &idx)) {
> +		reliable = false;
> +		*vpos = 0;
> +		*hpos = 0;
> +		goto out;
> +	}
> +
> +	/* line index starts with 0 for the first active output line */
> +	line = dc_fg_get_line_index(dc_crtc->fg);
> +
> +	if (line < vdisplay)
> +		/* active scanout area - positive */
> +		*vpos = line + 1;
> +	else
> +		/* inside vblank - negative */
> +		*vpos = line - (vtotal - 1);
> +
> +	*hpos = 0;
> +
> +	reliable = true;
> +
> +	drm_dev_exit(idx);
> +out:
> +	if (etime)
> +		*etime = ktime_get();
> +
> +	return reliable;
> +}
> +
> +static const struct drm_crtc_helper_funcs dc_helper_funcs = {
> +	.mode_valid		= dc_crtc_mode_valid,
> +	.atomic_check		= dc_crtc_atomic_check,
> +	.atomic_begin		= dc_crtc_atomic_begin,
> +	.atomic_flush		= dc_crtc_atomic_flush,
> +	.atomic_enable		= dc_crtc_atomic_enable,
> +	.atomic_disable		= dc_crtc_atomic_disable,
> +	.get_scanout_position	= dc_crtc_get_scanout_position,
> +};
> +
> +static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
> +{
> +	struct {
> +		struct device *dev;
> +		unsigned int irq;
> +		irqreturn_t (*irq_handler)(int irq, void *dev_id);
> +	} irqs[DC_CRTC_IRQS] = {
> +		{
> +			dc_crtc->de->dev,
> +			dc_crtc->irq_dec_framecomplete,
> +			dc_crtc_dec_framecomplete_irq_handler,
> +		}, {
> +			dc_crtc->de->dev,
> +			dc_crtc->irq_dec_seqcomplete,
> +			dc_crtc_common_irq_handler,
> +		}, {
> +			dc_crtc->de->dev,
> +			dc_crtc->irq_dec_shdld,
> +			dc_crtc_common_irq_handler,
> +		}, {
> +			dc_crtc->ed_cont->dev,
> +			dc_crtc->irq_ed_cont_shdld,
> +			dc_crtc_common_irq_handler,
> +		}, {
> +			dc_crtc->ed_safe->dev,
> +			dc_crtc->irq_ed_safe_shdld,
> +			dc_crtc_common_irq_handler,
> +		},
> +	};
> +	int i, ret;
> +
> +	for (i = 0; i < DC_CRTC_IRQS; i++) {
> +		struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
> +
> +		ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
> +				       irqs[i].irq_handler, IRQF_NO_AUTOEN,
> +				       dev_name(irqs[i].dev), dc_crtc);
> +		if (ret) {
> +			dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
> +				irqs[i].irq, ret);
> +			return ret;
> +		}
> +
> +		irq->dc_crtc = dc_crtc;
> +		irq->irq = irqs[i].irq;
> +	}
> +
> +	return 0;
> +}
> +
> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
> +{
> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> +	struct drm_device *drm = &dc_drm->base;
> +	struct dc_de *de = dc_drm->de[crtc_index];
> +	struct dc_pe *pe = dc_drm->pe;
> +	struct dc_plane *dc_primary;
> +	int ret;
> +
> +	dc_crtc->de = de;
> +	dc_crtc->pe = pe;
> +
> +	init_completion(&dc_crtc->dec_seqcomplete_done);
> +	init_completion(&dc_crtc->dec_shdld_done);
> +	init_completion(&dc_crtc->ed_cont_shdld_done);
> +	init_completion(&dc_crtc->ed_safe_shdld_done);
> +
> +	dc_crtc->cf_cont = pe->cf_cont[crtc_index];
> +	dc_crtc->cf_safe = pe->cf_safe[crtc_index];
> +	dc_crtc->ed_cont = pe->ed_cont[crtc_index];
> +	dc_crtc->ed_safe = pe->ed_safe[crtc_index];
> +	dc_crtc->fg = de->fg;
> +
> +	dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
> +	dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
> +	dc_crtc->irq_dec_shdld = de->irq_shdld;
> +	dc_crtc->irq_ed_safe_shdld = dc_crtc->ed_safe->irq_shdld;
> +	dc_crtc->irq_ed_cont_shdld = dc_crtc->ed_cont->irq_shdld;
> +
> +	dc_primary = &dc_drm->dc_primary[crtc_index];
> +	ret = dc_plane_init(dc_drm, dc_primary);
> +	if (ret) {
> +		dev_err(drm->dev,
> +			"failed to init primary plane for display engine%u: %d\n",
> +			de->id, ret);
> +		return ret;
> +	}
> +
> +	drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
> +
> +	ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
> +					NULL, &dc_crtc_funcs, NULL);
> +	if (ret)
> +		dev_err(drm->dev,
> +			"failed to add CRTC for display engine%u: %d\n",
> +			de->id, ret);
> +
> +	return ret;
> +}
> +
> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
> +{
> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> +	struct drm_device *drm = &dc_drm->base;
> +
> +	return dc_crtc_request_irqs(drm, dc_crtc);
> +}
> diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
> index 17a44362118e..8a7b6c03a222 100644
> --- a/drivers/gpu/drm/imx/dc/dc-de.h
> +++ b/drivers/gpu/drm/imx/dc/dc-de.h
> @@ -13,6 +13,9 @@
>  
>  #define DC_DISPLAYS	2
>  
> +#define DC_FRAMEGEN_MAX_FRAME_INDEX	0x3ffff
> +#define DC_FRAMEGEN_MAX_CLOCK_KHZ	300000
> +
>  struct dc_fg {
>  	struct device *dev;
>  	struct regmap *reg;
> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
> index fd68861f770a..1e4b8afa3eec 100644
> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
> @@ -3,11 +3,254 @@
>   * Copyright 2024 NXP
>   */
>  
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/device.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/mod_devicetable.h>
>  #include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm.h>
> +#include <linux/pm_runtime.h>
>  
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_client_setup.h>
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_drv.h>
> +#include <drm/drm_fbdev_dma.h>
> +#include <drm/drm_fourcc.h>
> +#include <drm/drm_gem_dma_helper.h>
> +#include <drm/drm_managed.h>
> +#include <drm/drm_modeset_helper.h>
> +#include <drm/drm_of.h>
> +
> +#include "dc-de.h"
>  #include "dc-drv.h"
>  
> +struct dc_priv {
> +	struct drm_device *drm;
> +	struct clk *clk_cfg;
> +};
> +
> +DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
> +
> +static struct drm_driver dc_drm_driver = {
> +	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
> +	DRM_GEM_DMA_DRIVER_OPS,
> +	DRM_FBDEV_DMA_DRIVER_OPS,
> +	.fops = &dc_drm_driver_fops,
> +	.name = "imx8-dc",
> +	.desc = "i.MX8 DC DRM graphics",
> +	.date = "20240530",
> +	.major = 1,
> +	.minor = 0,
> +	.patchlevel = 0,
> +};
> +
> +static void
> +dc_add_components(struct device *dev, struct component_match **matchptr)
> +{
> +	struct device_node *child, *grandchild;
> +
> +	for_each_available_child_of_node(dev->of_node, child) {
> +		/* The interrupt controller is not a component. */
> +		if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
> +			continue;
> +
> +		drm_of_component_match_add(dev, matchptr, component_compare_of,
> +					   child);
> +
> +		for_each_available_child_of_node(child, grandchild)
> +			drm_of_component_match_add(dev, matchptr,
> +						   component_compare_of,
> +						   grandchild);
> +	}
> +}
> +
> +static void dc_drm_component_unbind_all(void *ptr)
> +{
> +	struct dc_drm_device *dc_drm = ptr;
> +	struct drm_device *drm = &dc_drm->base;
> +
> +	component_unbind_all(drm->dev, dc_drm);
> +}
> +
> +static int dc_drm_bind(struct device *dev)
> +{
> +	struct dc_priv *priv = dev_get_drvdata(dev);
> +	struct dc_drm_device *dc_drm;
> +	struct drm_device *drm;
> +	int ret;
> +
> +	dc_drm = devm_drm_dev_alloc(dev, &dc_drm_driver, struct dc_drm_device,
> +				    base);
> +	if (IS_ERR(dc_drm))
> +		return PTR_ERR(dc_drm);
> +
> +	drm = &dc_drm->base;
> +
> +	ret = component_bind_all(dev, dc_drm);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_add_action_or_reset(dev, dc_drm_component_unbind_all,
> +				       dc_drm);
> +	if (ret)
> +		return ret;
> +
> +	ret = dc_kms_init(dc_drm);
> +	if (ret)
> +		return ret;
> +
> +	ret = drm_dev_register(drm, 0);
> +	if (ret) {
> +		dev_err(dev, "failed to register drm device: %d\n", ret);
> +		goto err;
> +	}
> +
> +	drm_client_setup_with_fourcc(drm, DRM_FORMAT_XRGB8888);
> +
> +	priv->drm = drm;
> +
> +	return 0;
> +
> +err:
> +	dc_kms_uninit(dc_drm);
> +
> +	return ret;
> +}
> +
> +static void dc_drm_unbind(struct device *dev)
> +{
> +	struct dc_priv *priv = dev_get_drvdata(dev);
> +	struct dc_drm_device *dc_drm = to_dc_drm_device(priv->drm);
> +	struct drm_device *drm = &dc_drm->base;
> +	struct drm_crtc *crtc;
> +
> +	priv->drm = NULL;
> +	drm_dev_unplug(drm);
> +	dc_kms_uninit(dc_drm);
> +	drm_atomic_helper_shutdown(drm);
> +
> +	drm_for_each_crtc(crtc, drm)
> +		dc_crtc_disable_at_unbind(crtc);

There should be no need for that. drm_atomic_helper_shutdown() should
disable all the CRTCs.

Also, who is going to do drm_dev_unregister()? I don't see it in the
code.

> +}
> +
> +static const struct component_master_ops dc_drm_ops = {
> +	.bind = dc_drm_bind,
> +	.unbind = dc_drm_unbind,
> +};
> +
> +static int dc_probe(struct platform_device *pdev)
> +{
> +	struct component_match *match = NULL;
> +	struct dc_priv *priv;
> +	int ret;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(priv->clk_cfg))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
> +				     "failed to get cfg clock\n");
> +
> +	dev_set_drvdata(&pdev->dev, priv);
> +
> +	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_pm_runtime_enable(&pdev->dev);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_of_platform_populate(&pdev->dev);
> +	if (ret)
> +		return ret;
> +
> +	dc_add_components(&pdev->dev, &match);
> +
> +	ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret,
> +				     "failed to add component master\n");
> +
> +	return 0;
> +}
> +
> +static void dc_remove(struct platform_device *pdev)
> +{
> +	component_master_del(&pdev->dev, &dc_drm_ops);
> +}
> +
> +static int dc_runtime_suspend(struct device *dev)
> +{
> +	struct dc_priv *priv = dev_get_drvdata(dev);
> +
> +	clk_disable_unprepare(priv->clk_cfg);
> +
> +	return 0;
> +}
> +
> +static int dc_runtime_resume(struct device *dev)
> +{
> +	struct dc_priv *priv = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = clk_prepare_enable(priv->clk_cfg);
> +	if (ret)
> +		dev_err(dev, "failed to enable cfg clock: %d\n", ret);
> +
> +	return ret;
> +}
> +
> +static int dc_suspend(struct device *dev)
> +{
> +	struct dc_priv *priv = dev_get_drvdata(dev);
> +
> +	return drm_mode_config_helper_suspend(priv->drm);
> +}
> +
> +static int dc_resume(struct device *dev)
> +{
> +	struct dc_priv *priv = dev_get_drvdata(dev);
> +
> +	return drm_mode_config_helper_resume(priv->drm);
> +}
> +
> +static void dc_shutdown(struct platform_device *pdev)
> +{
> +	struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
> +
> +	drm_atomic_helper_shutdown(priv->drm);
> +}
> +
> +static const struct dev_pm_ops dc_pm_ops = {
> +	RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
> +	SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
> +};
> +
> +static const struct of_device_id dc_dt_ids[] = {
> +	{ .compatible = "fsl,imx8qxp-dc", },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, dc_dt_ids);
> +
> +static struct platform_driver dc_driver = {
> +	.probe = dc_probe,
> +	.remove = dc_remove,
> +	.shutdown = dc_shutdown,
> +	.driver = {
> +		.name = "imx8-dc",
> +		.of_match_table	= dc_dt_ids,
> +		.pm = pm_sleep_ptr(&dc_pm_ops),
> +	},
> +};
> +
>  static struct platform_driver * const dc_drivers[] = {
>  	&dc_cf_driver,
>  	&dc_de_driver,
> @@ -19,6 +262,7 @@ static struct platform_driver * const dc_drivers[] = {
>  	&dc_lb_driver,
>  	&dc_pe_driver,
>  	&dc_tc_driver,
> +	&dc_driver,
>  };
>  
>  static int __init dc_drm_init(void)
> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
> index 3b11f4862c6c..39a771a13933 100644
> --- a/drivers/gpu/drm/imx/dc/dc-drv.h
> +++ b/drivers/gpu/drm/imx/dc/dc-drv.h
> @@ -6,19 +6,38 @@
>  #ifndef __DC_DRV_H__
>  #define __DC_DRV_H__
>  
> +#include <linux/container_of.h>
>  #include <linux/platform_device.h>
>  
>  #include <drm/drm_device.h>
> +#include <drm/drm_encoder.h>
>  
>  #include "dc-de.h"
> +#include "dc-kms.h"
>  #include "dc-pe.h"
>  
>  struct dc_drm_device {
>  	struct drm_device base;
> +	struct dc_crtc dc_crtc[DC_DISPLAYS];
> +	struct dc_plane dc_primary[DC_DISPLAYS];
> +	struct drm_encoder encoder[DC_DISPLAYS];
>  	struct dc_de *de[DC_DISPLAYS];
>  	struct dc_pe *pe;
>  };
>  
> +static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
> +{
> +	return container_of(drm, struct dc_drm_device, base);
> +}
> +
> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
> +
> +int dc_kms_init(struct dc_drm_device *dc_drm);
> +void dc_kms_uninit(struct dc_drm_device *dc_drm);
> +
> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
> +
>  extern struct platform_driver dc_cf_driver;
>  extern struct platform_driver dc_ed_driver;
>  extern struct platform_driver dc_de_driver;
> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
> new file mode 100644
> index 000000000000..2b18aa37a4a8
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dc/dc-kms.c
> @@ -0,0 +1,143 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#include <linux/of.h>
> +#include <linux/of_graph.h>
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_bridge_connector.h>
> +#include <drm/drm_connector.h>
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_device.h>
> +#include <drm/drm_encoder.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
> +#include <drm/drm_mode_config.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_probe_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
> +#include <drm/drm_vblank.h>
> +
> +#include "dc-de.h"
> +#include "dc-drv.h"
> +#include "dc-kms.h"
> +
> +static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
> +	.fb_create = drm_gem_fb_create,
> +	.atomic_check = drm_atomic_helper_check,
> +	.atomic_commit = drm_atomic_helper_commit,
> +};
> +
> +static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
> +					int crtc_index)
> +{
> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> +	struct drm_device *drm = &dc_drm->base;
> +	struct drm_crtc *crtc = &dc_crtc->base;
> +	struct drm_connector *connector;
> +	struct device *dev = drm->dev;
> +	struct drm_encoder *encoder;
> +	struct drm_bridge *bridge;
> +	int ret;
> +
> +	bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
> +					0, 0);
> +	if (IS_ERR(bridge)) {
> +		ret = PTR_ERR(bridge);
> +		if (ret == -ENODEV)
> +			return 0;
> +
> +		return dev_err_probe(dev, ret,
> +				     "failed to find bridge for CRTC%u\n",
> +				     crtc->index);
> +	}
> +
> +	encoder = &dc_drm->encoder[crtc_index];
> +	ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
> +	if (ret) {
> +		dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
> +			crtc->index, ret);
> +		return ret;
> +	}
> +
> +	encoder->possible_crtcs = drm_crtc_mask(crtc);
> +
> +	ret = drm_bridge_attach(encoder, bridge, NULL,
> +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +	if (ret) {
> +		dev_err(dev,
> +			"failed to attach bridge to encoder for CRTC%u: %d\n",
> +			crtc->index, ret);
> +		return ret;
> +	}
> +
> +	connector = drm_bridge_connector_init(drm, encoder);
> +	if (IS_ERR(connector)) {
> +		ret = PTR_ERR(connector);
> +		dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
> +			crtc->index, ret);
> +		return ret;
> +	}
> +
> +	ret = drm_connector_attach_encoder(connector, encoder);
> +	if (ret)
> +		dev_err(dev,
> +			"failed to attach encoder to connector for CRTC%u: %d\n",
> +			crtc->index, ret);
> +
> +	return ret;
> +}
> +
> +int dc_kms_init(struct dc_drm_device *dc_drm)
> +{
> +	struct drm_device *drm = &dc_drm->base;
> +	int ret, i;
> +
> +	ret = drmm_mode_config_init(drm);
> +	if (ret)
> +		return ret;
> +
> +	drm->mode_config.min_width = 60;
> +	drm->mode_config.min_height = 60;
> +	drm->mode_config.max_width = 8192;
> +	drm->mode_config.max_height = 8192;
> +	drm->mode_config.funcs = &dc_drm_mode_config_funcs;
> +
> +	drm->vblank_disable_immediate = true;
> +	drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
> +
> +	for (i = 0; i < DC_DISPLAYS; i++) {
> +		ret = dc_crtc_init(dc_drm, i);
> +		if (ret)
> +			return ret;
> +
> +		ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	for (i = 0; i < DC_DISPLAYS; i++) {
> +		ret = dc_crtc_post_init(dc_drm, i);

Can you use .late_register for this?

> +		if (ret)
> +			return ret;
> +	}
> +
> +	ret = drm_vblank_init(drm, DC_DISPLAYS);
> +	if (ret) {
> +		dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
> +		return ret;
> +	}
> +
> +	drm_mode_config_reset(drm);
> +
> +	drm_kms_helper_poll_init(drm);
> +
> +	return 0;
> +}
> +
> +void dc_kms_uninit(struct dc_drm_device *dc_drm)
> +{
> +	drm_kms_helper_poll_fini(&dc_drm->base);
> +}
> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
> new file mode 100644
> index 000000000000..57f6e0c15f57
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dc/dc-kms.h
> @@ -0,0 +1,58 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#ifndef __DC_KMS_H__
> +#define __DC_KMS_H__
> +
> +#include <linux/completion.h>
> +
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_plane.h>
> +#include <drm/drm_vblank.h>
> +
> +#include "dc-de.h"
> +#include "dc-fu.h"
> +#include "dc-pe.h"
> +
> +#define DC_CRTC_IRQS	5
> +
> +struct dc_crtc_irq {
> +	struct dc_crtc *dc_crtc;
> +	unsigned int irq;
> +};
> +

Please provide some documentation for the structure in the form of the
kerneldoc. E.g. what is the difference between ed_cont and ed_safe?
The de and fg pointers are global, please don't cache them
unnecessarily.

> +struct dc_crtc {
> +	struct drm_crtc base;
> +	struct dc_de *de;
> +	struct dc_pe *pe;
> +	struct dc_cf *cf_cont;
> +	struct dc_cf *cf_safe;
> +	struct dc_ed *ed_cont;
> +	struct dc_ed *ed_safe;
> +	struct dc_fg *fg;
> +	unsigned int irq_dec_framecomplete;
> +	unsigned int irq_dec_seqcomplete;
> +	unsigned int irq_dec_shdld;
> +	unsigned int irq_ed_cont_shdld;
> +	unsigned int irq_ed_safe_shdld;
> +	struct completion dec_seqcomplete_done;
> +	struct completion dec_shdld_done;
> +	struct completion ed_safe_shdld_done;
> +	struct completion ed_cont_shdld_done;
> +	struct drm_pending_vblank_event *event;
> +	struct dc_crtc_irq irqs[DC_CRTC_IRQS];
> +};
> +
> +struct dc_plane {
> +	struct drm_plane base;
> +	struct dc_fu *fu;
> +	struct dc_cf *cf;
> +	struct dc_lb *lb;
> +	struct dc_ed *ed;
> +};
> +
> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc);
> +
> +#endif /* __DC_KMS_H__ */
> diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
> new file mode 100644
> index 000000000000..78d0d2cd3451
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dc/dc-plane.c
> @@ -0,0 +1,241 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#include <linux/container_of.h>
> +
> +#include <drm/drm_atomic.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_atomic_state_helper.h>
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_drv.h>
> +#include <drm/drm_fb_dma_helper.h>
> +#include <drm/drm_fourcc.h>
> +#include <drm/drm_framebuffer.h>
> +#include <drm/drm_gem_atomic_helper.h>
> +#include <drm/drm_plane_helper.h>
> +#include <drm/drm_print.h>
> +
> +#include "dc-drv.h"
> +#include "dc-fu.h"
> +#include "dc-kms.h"
> +
> +#define DC_PLANE_MAX_PITCH	0x10000
> +#define DC_PLANE_MAX_PIX_CNT	8192
> +
> +#define dc_plane_dbg(plane, fmt, ...)					\
> +do {									\
> +	typeof(plane) _plane = (plane);					\
> +	drm_dbg_kms(_plane->dev, "[PLANE:%d:%s] " fmt,			\
> +		    _plane->base.id, _plane->name, ##__VA_ARGS__);	\
> +} while (0)
> +
> +static const uint32_t dc_plane_formats[] = {
> +	DRM_FORMAT_XRGB8888,
> +};
> +
> +static const struct drm_plane_funcs dc_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,
> +};
> +
> +static inline struct dc_plane *to_dc_plane(struct drm_plane *plane)
> +{
> +	return container_of(plane, struct dc_plane, base);
> +}
> +
> +static int dc_plane_check_no_off_screen(struct drm_plane_state *state,
> +					struct drm_crtc_state *crtc_state)
> +{
> +	if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
> +	    state->dst.x2 > crtc_state->adjusted_mode.hdisplay ||
> +	    state->dst.y2 > crtc_state->adjusted_mode.vdisplay) {
> +		dc_plane_dbg(state->plane, "no off screen\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int dc_plane_check_max_source_resolution(struct drm_plane_state *state)
> +{
> +	int src_h = drm_rect_height(&state->src) >> 16;
> +	int src_w = drm_rect_width(&state->src) >> 16;
> +
> +	if (src_w > DC_PLANE_MAX_PIX_CNT || src_h > DC_PLANE_MAX_PIX_CNT) {
> +		dc_plane_dbg(state->plane, "invalid source resolution\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int dc_plane_check_fb(struct drm_plane_state *state)
> +{
> +	struct drm_framebuffer *fb = state->fb;
> +	dma_addr_t baseaddr = drm_fb_dma_get_gem_addr(fb, state, 0);
> +
> +	/* base address alignment */
> +	if (baseaddr & 0x3) {
> +		dc_plane_dbg(state->plane, "fb bad baddr alignment\n");
> +		return -EINVAL;
> +	}
> +
> +	/* pitches[0] range */
> +	if (fb->pitches[0] > DC_PLANE_MAX_PITCH) {
> +		dc_plane_dbg(state->plane, "fb pitches[0] is out of range\n");
> +		return -EINVAL;
> +	}
> +
> +	/* pitches[0] alignment */
> +	if (fb->pitches[0] & 0x3) {
> +		dc_plane_dbg(state->plane, "fb bad pitches[0] alignment\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +dc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
> +{
> +	struct drm_plane_state *plane_state =
> +				drm_atomic_get_new_plane_state(state, plane);
> +	struct drm_crtc_state *crtc_state;
> +	int ret;
> +
> +	/* ok to disable */
> +	if (!plane_state->fb)
> +		return 0;
> +
> +	if (!plane_state->crtc) {
> +		dc_plane_dbg(plane, "no CRTC in plane state\n");
> +		return -EINVAL;
> +	}
> +
> +	crtc_state =
> +		drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
> +	if (WARN_ON(!crtc_state))
> +		return -EINVAL;
> +
> +	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
> +						  DRM_PLANE_NO_SCALING,
> +						  DRM_PLANE_NO_SCALING,
> +						  true, false);
> +	if (ret) {
> +		dc_plane_dbg(plane, "failed to check plane state: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = dc_plane_check_no_off_screen(plane_state, crtc_state);
> +	if (ret)
> +		return ret;
> +
> +	ret = dc_plane_check_max_source_resolution(plane_state);
> +	if (ret)
> +		return ret;
> +
> +	return dc_plane_check_fb(plane_state);
> +}
> +
> +static void
> +dc_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state)
> +{
> +	struct drm_plane_state *new_state =
> +				drm_atomic_get_new_plane_state(state, plane);
> +	struct dc_plane *dplane = to_dc_plane(plane);
> +	struct drm_framebuffer *fb = new_state->fb;
> +	const struct dc_fu_ops *fu_ops;
> +	struct dc_lb *lb = dplane->lb;
> +	struct dc_fu *fu = dplane->fu;
> +	dma_addr_t baseaddr;
> +	int src_w, src_h;
> +	int idx;
> +
> +	if (!drm_dev_enter(plane->dev, &idx))
> +		return;
> +
> +	src_w = drm_rect_width(&new_state->src) >> 16;
> +	src_h = drm_rect_height(&new_state->src) >> 16;
> +
> +	baseaddr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
> +
> +	fu_ops = dc_fu_get_ops(dplane->fu);
> +
> +	fu_ops->set_layerblend(fu, lb);
> +	fu_ops->set_burstlength(fu, baseaddr);
> +	fu_ops->set_src_stride(fu, DC_FETCHUNIT_FRAC0, fb->pitches[0]);
> +	fu_ops->set_src_buf_dimensions(fu, DC_FETCHUNIT_FRAC0, src_w, src_h);
> +	fu_ops->set_fmt(fu, DC_FETCHUNIT_FRAC0, fb->format);
> +	fu_ops->set_framedimensions(fu, src_w, src_h);
> +	fu_ops->set_baseaddress(fu, DC_FETCHUNIT_FRAC0, baseaddr);
> +	fu_ops->enable_src_buf(fu, DC_FETCHUNIT_FRAC0);
> +
> +	dc_plane_dbg(plane, "uses %s\n", fu_ops->get_name(fu));
> +
> +	dc_lb_pec_dynamic_prim_sel(lb, dc_cf_get_link_id(dplane->cf));
> +	dc_lb_pec_dynamic_sec_sel(lb, fu_ops->get_link_id(fu));
> +	dc_lb_mode(lb, LB_BLEND);
> +	dc_lb_position(lb, new_state->dst.x1, new_state->dst.y1);
> +	dc_lb_pec_clken(lb, CLKEN_AUTOMATIC);
> +
> +	dc_plane_dbg(plane, "uses LayerBlend%u\n", dc_lb_get_id(lb));
> +
> +	/* set ExtDst's source to LayerBlend */
> +	dc_ed_pec_src_sel(dplane->ed, dc_lb_get_link_id(lb));
> +
> +	drm_dev_exit(idx);
> +}
> +
> +static void dc_plane_atomic_disable(struct drm_plane *plane,
> +				    struct drm_atomic_state *state)
> +{
> +	struct dc_plane *dplane = to_dc_plane(plane);
> +	const struct dc_fu_ops *fu_ops;
> +	int idx;
> +
> +	if (!drm_dev_enter(plane->dev, &idx))
> +		return;
> +
> +	/* disable fetchunit in shadow */
> +	fu_ops = dc_fu_get_ops(dplane->fu);
> +	fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
> +
> +	/* set ExtDst's source to ConstFrame */
> +	dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
> +
> +	drm_dev_exit(idx);
> +}
> +
> +static const struct drm_plane_helper_funcs dc_plane_helper_funcs = {
> +	.atomic_check = dc_plane_atomic_check,
> +	.atomic_update = dc_plane_atomic_update,
> +	.atomic_disable = dc_plane_atomic_disable,
> +};
> +
> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
> +{
> +	struct drm_plane *plane = &dc_plane->base;
> +	int ret;
> +
> +	ret = drm_universal_plane_init(&dc_drm->base, plane, 0, &dc_plane_funcs,
> +				       dc_plane_formats,
> +				       ARRAY_SIZE(dc_plane_formats),
> +				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
> +	if (ret)
> +		return ret;
> +
> +	drm_plane_helper_add(plane, &dc_plane_helper_funcs);
> +
> +	dc_plane->fu = dc_drm->pe->fu_disp[plane->index];
> +	dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
> +	dc_plane->lb = dc_drm->pe->lb[plane->index];
> +	dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
> +
> +	return 0;
> +}
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From alexandre.torgue at foss.st.com  Mon Dec  9 08:14:29 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Mon, 9 Dec 2024 17:14:29 +0100
Subject: [PATCH] arm64: dts: st: add i2s support to stm32mp251
In-Reply-To: <20241113082510.2354924-1-olivier.moysan@foss.st.com>
References: <20241113082510.2354924-1-olivier.moysan@foss.st.com>
Message-ID: <d38f2ea1-17c3-466c-9537-0a5e31a5225e@foss.st.com>

Hi Olivier

On 11/13/24 09:25, Olivier Moysan wrote:
> Add I2S support to STM32MP25 SoCs.
> 
> Signed-off-by: Olivier Moysan <olivier.moysan at foss.st.com>
> ---
>   arch/arm64/boot/dts/st/stm32mp251.dtsi | 45 ++++++++++++++++++++++++++
>   1 file changed, 45 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
> index 6fe12e3bd7dd..8cc0b64e6a16 100644
> --- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
> +++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
> @@ -237,6 +237,21 @@ rifsc: bus at 42080000 {
>   			#access-controller-cells = <1>;

Applied on stm32-next.

Thanks!
Alex


From will at kernel.org  Mon Dec  9 08:20:29 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Dec 2024 16:20:29 +0000
Subject: [PATCH v2] arm64: Allow CONFIG_AUTOFDO_CLANG to be selected
In-Reply-To: <20241118222540.27495-1-yabinc@google.com>
References: <20241118222540.27495-1-yabinc@google.com>
Message-ID: <20241209162028.GD12428@willie-the-truck>

On Mon, Nov 18, 2024 at 02:25:40PM -0800, Yabin Cui wrote:
> Select ARCH_SUPPORTS_AUTOFDO_CLANG to allow AUTOFDO_CLANG to be
> selected.
> 
> On ARM64, ETM traces can be recorded and converted to AutoFDO profiles.
> Experiments on Android show 4% improvement in cold app startup time
> and 13% improvement in binder benchmarks.
> 
> Signed-off-by: Yabin Cui <yabinc at google.com>
> ---
> 
> Change-Logs in V2:
> 
> 1. Use "For ARM platforms with ETM trace" in autofdo.rst.
> 2. Create an issue and a change to use extbinary format in instructions:
>    https://github.com/Linaro/OpenCSD/issues/65
>    https://android-review.googlesource.com/c/platform/system/extras/+/3362107
> 
>  Documentation/dev-tools/autofdo.rst | 18 +++++++++++++++++-
>  arch/arm64/Kconfig                  |  1 +
>  2 files changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/dev-tools/autofdo.rst b/Documentation/dev-tools/autofdo.rst
> index 1f0a451e9ccd..a890e84a2fdd 100644
> --- a/Documentation/dev-tools/autofdo.rst
> +++ b/Documentation/dev-tools/autofdo.rst
> @@ -55,7 +55,7 @@ process consists of the following steps:
>     workload to gather execution frequency data. This data is
>     collected using hardware sampling, via perf. AutoFDO is most
>     effective on platforms supporting advanced PMU features like
> -   LBR on Intel machines.
> +   LBR on Intel machines, ETM traces on ARM machines.
>  
>  #. AutoFDO profile generation: Perf output file is converted to
>     the AutoFDO profile via offline tools.
> @@ -141,6 +141,22 @@ Here is an example workflow for AutoFDO kernel:
>  
>        $ perf record --pfm-events RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a -N -b -c <count> -o <perf_file> -- <loadtest>
>  
> +   - For ARM platforms with ETM trace:
> +
> +     Follow the instructions in the `Linaro OpenCSD document
> +     https://github.com/Linaro/OpenCSD/blob/master/decoder/tests/auto-fdo/autofdo.md`_
> +     to record ETM traces for AutoFDO::
> +
> +      $ perf record -e cs_etm/@tmc_etr0/k -a -o <etm_perf_file> -- <loadtest>
> +      $ perf inject -i <etm_perf_file> -o <perf_file> --itrace=i500009il
> +
> +     For ARM platforms running Android, follow the instructions in the
> +     `Android simpleperf document
> +     <https://android.googlesource.com/platform/system/extras/+/main/simpleperf/doc/collect_etm_data_for_autofdo.md>`_
> +     to record ETM traces for AutoFDO::
> +
> +      $ simpleperf record -e cs-etm:k -a -o <perf_file> -- <loadtest>
> +
>  4) (Optional) Download the raw perf file to the host machine.
>  
>  5) To generate an AutoFDO profile, two offline tools are available:
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index fd9df6dcc593..c3814df5e391 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -103,6 +103,7 @@ config ARM64
>  	select ARCH_SUPPORTS_PER_VMA_LOCK
>  	select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
>  	select ARCH_SUPPORTS_RT
> +	select ARCH_SUPPORTS_AUTOFDO_CLANG
>  	select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
>  	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
>  	select ARCH_WANT_DEFAULT_BPF_JIT

After this change, both arm64 and x86 select this option unconditionally
and with no apparent support code being added. So what is actually
required in order to select ARCH_SUPPORTS_AUTOFDO_CLANG and why isn't
it just available for all architectures instead?

Will


From alexandre.torgue at foss.st.com  Mon Dec  9 08:18:22 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Mon, 9 Dec 2024 17:18:22 +0100
Subject: [PATCH 1/1] arm64: dts: st: add spdifrx support on stm32mp251
In-Reply-To: <20241105162141.712073-1-olivier.moysan@foss.st.com>
References: <20241105162141.712073-1-olivier.moysan@foss.st.com>
Message-ID: <4075e04d-dab3-40f2-9a64-760081cf47ee@foss.st.com>

Hi Oliver

On 11/5/24 17:21, Olivier Moysan wrote:
> Add S/PDIFRX support to STM32MP25 SoC family.
> 
> Signed-off-by: Olivier Moysan <olivier.moysan at foss.st.com>
> ---
>   arch/arm64/boot/dts/st/stm32mp251.dtsi | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
> index 6fe12e3bd7dd..34970be2e0b3 100644
> --- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
> +++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
> @@ -267,6 +267,20 @@ spi3: spi at 400c0000 {
>   				status = "disabled";
>   			};
>   
> +			spdifrx: audio-controller at 400d0000 {
> +				compatible = "st,stm32h7-spdifrx";
> +				#sound-dai-cells = <0>;
> +				reg = <0x400d0000 0x400>;
> +				clocks = <&rcc CK_KER_SPDIFRX>;
> +				clock-names = "kclk";
> +				interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
> +				dmas = <&hpdma 71 0x43 0x212>,
> +				       <&hpdma 72 0x43 0x212>;
> +				dma-names = "rx", "rx-ctrl";
> +				access-controllers = <&rifsc 30>;
> +				status = "disabled";
> +			};
> +
>   			usart2: serial at 400e0000 {
>   				compatible = "st,stm32h7-uart";
>   				reg = <0x400e0000 0x400>;

Applied on stm32-next.

Thanks!!
Alex


From alexandre.torgue at foss.st.com  Mon Dec  9 08:24:05 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Mon, 9 Dec 2024 17:24:05 +0100
Subject: [PATCH v9 0/5] Add STM32MP25 USB3/PCIE COMBOPHY driver
In-Reply-To: <20240930170847.948779-1-christian.bruel@foss.st.com>
References: <20240930170847.948779-1-christian.bruel@foss.st.com>
Message-ID: <6bbb3044-4c1f-4ff1-a503-ef8392e023ae@foss.st.com>

Hi Christian

On 9/30/24 19:08, Christian Bruel wrote:
> Changes in v9:
>     - Fix bot clang warnings: uninitialized variables and
>       include bitfield.h for FIELD_GET
> 
> Changes in v7/v8:
>     - MAINTAINERS: Reorder STM32MP25 DRIVER entry
> 
> Changes in v6:
>     - stm32_combophy_pll_init: merge combophy_cr1 accesses and error path.
>     - Use devm_reset_control_get_exclusive
> 
> Changes in v5:
>     - Drop syscfg phandle and change driver to use lookup_by_compatible
>     - Use clk_bulk API and drop stm32_combophy_enable/disable_clocks
>     - Reorder required: list.
>     - Fix access-controllers maxItems
> 
> Changes in v4:
>     - "#phy-cells": Drop type item description since it is specified
>       by user node phandle.
>     - Rename stm32-combophy.yaml to match compatible
>     - Drop wakeup-source from bindings (should be generic)
>     - Alphabetically reorder required: list.
>     - Drop "Reviewed-by" since those previous changes
> 
> Changes in v3:
>     - Reorder MAINTAINERS patch
> 
> Changes in v2:
>     - Reorder entries
>     - Rename clock_names and reset_names bindings
>     - Rename and clarify rx-equalizer binding
> 
> Christian Bruel (5):
>    dt-bindings: phy: Add STM32MP25 COMBOPHY bindings
>    phy: stm32: Add support for STM32MP25 COMBOPHY.
>    MAINTAINERS: add entry for ST STM32MP25 COMBOPHY driver
>    arm64: dts: st: Add combophy node on stm32mp251
>    arm64: dts: st: Enable COMBOPHY on the stm32mp257f-ev1 board
> 
>   .../bindings/phy/st,stm32mp25-combophy.yaml   | 119 ++++
>   MAINTAINERS                                   |   6 +
>   arch/arm64/boot/dts/st/stm32mp251.dtsi        |  16 +
>   arch/arm64/boot/dts/st/stm32mp257f-ev1.dts    |  14 +
>   drivers/phy/st/Kconfig                        |  11 +
>   drivers/phy/st/Makefile                       |   1 +
>   drivers/phy/st/phy-stm32-combophy.c           | 598 ++++++++++++++++++
>   7 files changed, 765 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
>   create mode 100644 drivers/phy/st/phy-stm32-combophy.c
> 
> 
> base-commit: 9bd8e1ba97b1f2d0410db9ff182d677992084770

DT patches ([4] & [5]) applied on stm32-next.

Thanks
Alex


From linux at armlinux.org.uk  Mon Dec  9 08:35:40 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 9 Dec 2024 16:35:40 +0000
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and
 MBa62xx carrier board Device Trees
In-Reply-To: <d25b1447-c28b-4998-b238-92672434dc28@lunn.ch>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>
 <c902a56cf34838f60cee67624bb923e91d74e9e0.camel@ew.tq-group.com>
 <d25b1447-c28b-4998-b238-92672434dc28@lunn.ch>
Message-ID: <Z1ccXClgTg5Guq6R@shell.armlinux.org.uk>

On Mon, Dec 09, 2024 at 03:42:52PM +0100, Andrew Lunn wrote:
> I also find a lot of developers don't really understand what phy-mode
> and PHY_INTERFACE_MODE_RGMII_* actually mean.

... which is why we documented it in Documentation/networking/phy.rst,
but it seems folk who run into RGMII stuff don't read that document.

I'm wondering if we can come up with some kernel-doc compatible way to
document them in linux/phy.h instead, which may stand an improved
chance of being read?

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


From Frank.li at nxp.com  Mon Dec  9 08:42:13 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 9 Dec 2024 11:42:13 -0500
Subject: [PATCH] spi: mxs: support effective_speed_hz
In-Reply-To: <20241209111316.4767-1-wahrenst@gmx.net>
References: <20241209111316.4767-1-wahrenst@gmx.net>
Message-ID: <Z1cd5ZcU2xTeemZH@lizhi-Precision-Tower-5810>

On Mon, Dec 09, 2024 at 12:13:16PM +0100, Stefan Wahren wrote:
> Setting spi_transfer->effective_speed_hz in transfer_one_message so that
> SPI client driver can use it.

Nit:
s/Setting/Set/

Reviewed-by: Frank Li <Frank.Li at nxp.com>

>
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
> ---
>  drivers/spi/spi-mxs.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
> index e6d955d964f4..43455305fdf4 100644
> --- a/drivers/spi/spi-mxs.c
> +++ b/drivers/spi/spi-mxs.c
> @@ -381,6 +381,8 @@ static int mxs_spi_transfer_one(struct spi_controller *host,
>  		if (status)
>  			break;
>
> +		t->effective_speed_hz = ssp->clk_rate;
> +
>  		/* De-assert on last transfer, inverted by cs_change flag */
>  		flag = (&t->transfer_list == m->transfers.prev) ^ t->cs_change ?
>  		       TXRX_DEASSERT_CS : 0;
> --
> 2.34.1
>


From tony.luck at intel.com  Mon Dec  9 08:43:22 2024
From: tony.luck at intel.com (Luck, Tony)
Date: Mon, 9 Dec 2024 16:43:22 +0000
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and
 MBa62xx carrier board Device Trees
In-Reply-To: <Z1ccXClgTg5Guq6R@shell.armlinux.org.uk>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>
 <c902a56cf34838f60cee67624bb923e91d74e9e0.camel@ew.tq-group.com>
 <d25b1447-c28b-4998-b238-92672434dc28@lunn.ch>
 <Z1ccXClgTg5Guq6R@shell.armlinux.org.uk>
Message-ID: <SJ1PR11MB60839F37610CEEC55F9E9B4FFC3C2@SJ1PR11MB6083.namprd11.prod.outlook.com>

> ... which is why we documented it in Documentation/networking/phy.rst,
> but it seems folk who run into RGMII stuff don't read that document.
>
> I'm wondering if we can come up with some kernel-doc compatible way to
> document them in linux/phy.h instead, which may stand an improved
> chance of being read?

Move the relevant text from Documentation/networking/phy.rst into
linux/phy.h as a linux doc format comment. 

"include" that header file into Documentation/networking/phy.rst
with

.. kernel-doc:: include/linux/phy.h

-Tony



From eauger at redhat.com  Mon Dec  9 08:46:30 2024
From: eauger at redhat.com (Eric Auger)
Date: Mon, 9 Dec 2024 17:46:30 +0100
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer
 expired
In-Reply-To: <8be59ff3-6a68-48e1-8181-0ce4b2e7180f@os.amperecomputing.com>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
 <867c89tc4q.wl-maz@kernel.org>
 <c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
 <865xntt2kv.wl-maz@kernel.org>
 <8be59ff3-6a68-48e1-8181-0ce4b2e7180f@os.amperecomputing.com>
Message-ID: <bcb4289b-507c-4ea1-afc7-6febd34d88db@redhat.com>

Hi,

On 12/9/24 16:39, Ganapatrao Kulkarni wrote:
> 
> 
> On 09-12-2024 06:50 pm, Marc Zyngier wrote:
>> On Mon, 09 Dec 2024 12:25:34 +0000,
>> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
>>>>>
>>>>> During automated testing of Nested Virtualization using avocado-vt,
>>>>
>>>> Which is not merged upstream. So what branch are you using? Based on
>>>> what kernel version? On what HW? With which virtualisation features?
>>>>
>>>
>>> Testing is done on Ampere's AmpereOne platform using 6.10 based kernel
>>> with NV patches from your repo.
>>
>> Grmbl... *Which* patches? At least give me the SHA1 of the branch,
>> because I have no idea what you are running. And 6.10 is definitely
>> not something I care about. If you're using the NV patches, the
>> *minimum* you should run is 6.13-rc1, because that's what the current
>> code is based on.
>>
> 
> I tried 6.13-rc1 based nv-next branch today, which failed to boot
> UEFI as L1. Yet to debug this.

I confirm am stuck with the same issue with nv-next on AmpereOne.

Thanks

Eric

> 
> 
> QEMU from Eric's repo is used for the testing.
> https://github.com/eauger/qemu/tree/v9.0-nv-rfcv3
> 
>> Also, does this machine have FEAT_ECV?
> 
> Yes!
>>
>>>
>>>>> it has been observed that during some boot test iterations,
>>>>> the Guest-Hypervisor boot was getting crashed with a
>>>>> synchronous exception while it is still booting EDK2.
>>>>>
>>>>> The test is launching Multiple instances of Guest-Hypervisor boot
>>>>
>>>> Is the multiple instance aspect really relevant to the reproduction of
>>>> the problem?
>>>
>>> Not really, but it requires multiple attempts/iterations to hit the
>>> issue. Even with automated test, it was seen at some iteration out of
>>> 10 to 15 iterations.
>>>
>>>>
>>>>> and while booting, QEMU monitor issued the command "info register"
>>>>> at regular intervals to take a register dump. To execute this
>>>>> command, QEMU stops the run and does the register read of various
>>>>> registers. While resuming the run, the function kvm_arm_timer_write()
>>>>> writes back the saved CNTV_CTL_EL0 register with ISTATUS cleared
>>>>> always
>>>>
>>>> It is userspace that causes this write-back, right? AFAICT, KVM never
>>>> does that on its own.
>>>>
>>>>> and resulting in the loss of pending interrupt for emulated timers.
>>>>
>>>> How does a missing interrupt result in a synchronous exception in
>>>> EDK2? In my experience, EDK2 panics if it sees spurious interrupts,
>>>> not when it is missing interrupts (it just locks up, which is
>>>> expected).
>>>
>>> Not sure, why it is hitting exception, rather than hang at EDK2.
>>> However, EDK2 timer handler code is ignoring the interrupt since
>>> ISTATUS is not set and not moving CVAL forward.
>>
>> How is EDK2 getting this exception? Is this injected by KVM? Or is
>> that some EDK2 bug?
>>
>>>
>>>>
>>>>> In hardware based timers, ISTATUS is a RO/WI bit and gets set by the
>>>>> h/w, if the condition is still met. However, in Nested-Virtualization
>>>>> case, the Guest-Hypervisor's?EDK2 is using an emulated virtual timer
>>>>> and losing ISTATUS state and the interrupt forever.
>>>>
>>>> Why is this specific to NV? Can't the same thing happen to the
>>>> physical timer in a non-VHE configuration?
>>>>
>>>
>>> You mean, emulated v-timer in non-VHE boot?
>>
>> Emulated *physical* timer.
>>
>>> It might impact non-VHE case as well, not tried though.
>>
>> Can you please try?
> 
> Sure, I will try non-VHE as well.
>>
>> [...]
>>
>>>> But overall, this very much looks like it is only papering over the
>>>> real issue, which is that the *emulation* should regenerate the
>>>> pending bit, and not rely on the userspace interface.
>>>>
>>>> As far as I can tell, we already correctly compute the status bit on
>>>> read (read_timer_ctl()), so the guest should always observe something
>>>> consistent when it traps. We also *never* use the status bit as an
>>>> input to the emulation, and always recompute it from scratch (it is
>>>> only there for the benefit of the guest or userspace).
>>>>
>>>
>>> For emulated timers, we are not asserting again by calling
>>> kvm_timer_update_irq in timer_emulate() until the level is down and
>>> ready for trigger again. This was done to fix high rate of spurious
>>> interrupts getting generated to V-Timer. Hence we are not able to
>>> recover, if once ISTATUS is lost.
>>
>> Again, a trapping read should see the correct value, since we populate
>> that bit at read time.
>>
>>>> So I can't see how upstream is broken in at the moment, and you need
>>>> to explain how this actually triggers. Ideally, with a standalone
>>>> reproducer or a selftest.
>>>
>>> We could reproduce the issue with the simple test/script.
>>> On one shell, launch L1 using qemu with add-on option
>>>
>>> "-monitor unix:gh_monitor,server,nowait
>>>
>>> On another shell, while L1 boots and still in UEFI, run repeatedly the
>>> command (or put in a while 1 loop script)
>>>
>>> "echo "info registers" | socat - unix-connect:gh_monitor >
>>> /tmp/info_registers"
>>>
>>> With above steps we were able to hit the issue within few attempts.
>>
>> That's not a standalone reproducer. QEMU doesn't support NV, and
>> kvmtool doesn't have this sort of interface. I was asking for a bit of
>> C code that I could run directly, not something that requires me to
>> drag even more experimental code.
>>
>> So here's my current guess, since you don't give me the needed
>> information. For what you describe to happen, I can only see two
>> possibilities:
>>
>> - either your HW doesn't have FEAT_ECV, in which case the guest
>> ?? directly reads from memory
>>
> 
> We do have the FEAT_ECV on AmpereOne, I was the one reported/fixed bug
> with FEAT_ECV(CNTPOFF offset issue) in the past.
> 
>> - or you are running with something like this patch [1], and we serve
>> ?? the guest by reading from memory very early, without returning to
>> ?? the bulk of the emulation code
> 
> I see the kernel I am testing has this patch[1].
>>
>> In either case, we only publish the updated status if the current IRQ
>> state is different from the computed output of the timer while
>> performing the emulation.
>>
>> So if you were writing back a status bit set to 0 while the interrupt
>> was already pending, we'd deliver an interrupt, but not recompute the
>> status. The guest would consider the interrupt as spurious, not touch
>> the timer, and we'd never make forward progress. Rinse, repeat.
>>
>> Assuming I got the analysis right, 
> 
> Yes, this is what I tried to explain. LR shows pending, but UEFI is not
> consuming and treating it as spurious since ISTATUS is not set.
> 
> it would only be a matter of
>> hoisting the publication of the status into timer_emulate(), so that
>> it is made up to date on load.
>>
>> Please give the fixup below a go.
>>
> 
> Sure, I will give a try with below diff and let you know tomorrow.
> This should work, I remember, this was the one of the option/fix that we
> tried as fix while debugging.
> 
>>
>> [1] https://lore.kernel.org/all/20241202172134.384923-6-maz at kernel.org/
>>
>> ?From 2bbd6f9b41a20ad573376c20c158ff3c12db5009 Mon Sep 17 00:00:00 2001
>> From: Marc Zyngier <maz at kernel.org>
>> Date: Mon, 9 Dec 2024 10:58:08 +0000
>> Subject: [PATCH] fixup! KVM: arm64: nv: Publish emulated timer
>> interrupt state
>> ? in the in-memory state
>>
>> ---
>> ? arch/arm64/kvm/arch_timer.c | 32 +++++++++++++-------------------
>> ? 1 file changed, 13 insertions(+), 19 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
>> index 895f09658ef83..91bda986c344b 100644
>> --- a/arch/arm64/kvm/arch_timer.c
>> +++ b/arch/arm64/kvm/arch_timer.c
>> @@ -432,25 +432,6 @@ static void kvm_timer_update_irq(struct kvm_vcpu
>> *vcpu, bool new_level,
>> ? {
>> ????? int ret;
>> ? -??? /*
>> -???? * Paper over NV2 brokenness by publishing the interrupt status
>> -???? * bit. This still results in a poor quality of emulation (guest
>> -???? * writes will have no effect until the next exit).
>> -???? *
>> -???? * But hey, it's fast, right?
>> -???? */
>> -??? if (is_hyp_ctxt(vcpu) &&
>> -??????? (timer_ctx == vcpu_vtimer(vcpu) || timer_ctx ==
>> vcpu_ptimer(vcpu))) {
>> -??????? u32 ctl = timer_get_ctl(timer_ctx);
>> -
>> -??????? if (new_level)
>> -??????????? ctl |= ARCH_TIMER_CTRL_IT_STAT;
>> -??????? else
>> -??????????? ctl &= ~ARCH_TIMER_CTRL_IT_STAT;
>> -
>> -??????? timer_set_ctl(timer_ctx, ctl);
>> -??? }
>> -
>> ????? timer_ctx->irq.level = new_level;
>> ????? trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_irq(timer_ctx),
>> ???????????????????? timer_ctx->irq.level);
>> @@ -471,6 +452,19 @@ static void timer_emulate(struct
>> arch_timer_context *ctx)
>> ? ????? trace_kvm_timer_emulate(ctx, should_fire);
>> ? +??? /*
>> +???? * Paper over NV2 brokenness by publishing the interrupt status
>> +???? * bit. This still results in a poor quality of emulation (guest
>> +???? * writes will have no effect until the next exit).
>> +???? *
>> +???? * But hey, it's fast, right?
>> +???? */
>> +??? if (is_hyp_ctxt(ctx->vcpu)) {
>> +??????? unsigned long val = timer_get_ctl(ctx);
>> +??????? __assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &val, should_fire);
>> +??????? timer_set_ctl(ctx, val);
>> +??? }
>> +
>> ????? if (should_fire != ctx->irq.level) {
>> ????????? kvm_timer_update_irq(ctx->vcpu, should_fire, ctx);
>> ????????? return;
> 



From cristian.marussi at arm.com  Mon Dec  9 08:49:56 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon,  9 Dec 2024 16:49:56 +0000
Subject: [PATCH v2 2/3] firmware: arm_scmi: Add module aliases to i.MX vendor protocols
In-Reply-To: <20241209164957.1801886-1-cristian.marussi@arm.com>
References: <20241209164957.1801886-1-cristian.marussi@arm.com>
Message-ID: <20241209164957.1801886-3-cristian.marussi@arm.com>

Using the pattern 'scmi-protocol-0x<PROTO_ID>-<VEND_ID>' as MODULE_ALIAS
allows the SCMI core to autoload this protocol, if built as a module, when
its protocol operations are requested by an SCMI driver.

Cc: Peng Fan <peng.fan at nxp.com>
Acked-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c  | 5 +++--
 drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c | 5 +++--
 include/linux/scmi_imx_protocol.h                   | 9 +++++----
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c
index 17799eacf06c..aa176c1a5eef 100644
--- a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c
+++ b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-bbm.c
@@ -374,10 +374,11 @@ static const struct scmi_protocol scmi_imx_bbm = {
 	.ops = &scmi_imx_bbm_proto_ops,
 	.events = &scmi_imx_bbm_protocol_events,
 	.supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,
-	.vendor_id = "NXP",
-	.sub_vendor_id = "IMX",
+	.vendor_id = SCMI_IMX_VENDOR,
+	.sub_vendor_id = SCMI_IMX_SUBVENDOR,
 };
 module_scmi_protocol(scmi_imx_bbm);
 
+MODULE_ALIAS("scmi-protocol-" __stringify(SCMI_PROTOCOL_IMX_BBM) "-" SCMI_IMX_VENDOR);
 MODULE_DESCRIPTION("i.MX SCMI BBM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c
index a86ab9b35953..83b69fc4fba5 100644
--- a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c
+++ b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c
@@ -309,10 +309,11 @@ static const struct scmi_protocol scmi_imx_misc = {
 	.ops = &scmi_imx_misc_proto_ops,
 	.events = &scmi_imx_misc_protocol_events,
 	.supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,
-	.vendor_id = "NXP",
-	.sub_vendor_id = "IMX",
+	.vendor_id = SCMI_IMX_VENDOR,
+	.sub_vendor_id = SCMI_IMX_SUBVENDOR,
 };
 module_scmi_protocol(scmi_imx_misc);
 
+MODULE_ALIAS("scmi-protocol-" __stringify(SCMI_PROTOCOL_IMX_MISC) "-" SCMI_IMX_VENDOR);
 MODULE_DESCRIPTION("i.MX SCMI MISC driver");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/scmi_imx_protocol.h b/include/linux/scmi_imx_protocol.h
index 066216f1357a..53b356a26414 100644
--- a/include/linux/scmi_imx_protocol.h
+++ b/include/linux/scmi_imx_protocol.h
@@ -13,10 +13,11 @@
 #include <linux/notifier.h>
 #include <linux/types.h>
 
-enum scmi_nxp_protocol {
-	SCMI_PROTOCOL_IMX_BBM = 0x81,
-	SCMI_PROTOCOL_IMX_MISC = 0x84,
-};
+#define	SCMI_PROTOCOL_IMX_BBM	0x81
+#define	SCMI_PROTOCOL_IMX_MISC	0x84
+
+#define SCMI_IMX_VENDOR		"NXP"
+#define SCMI_IMX_SUBVENDOR	"IMX"
 
 struct scmi_imx_bbm_proto_ops {
 	int (*rtc_time_set)(const struct scmi_protocol_handle *ph, u32 id,
-- 
2.47.0



From cristian.marussi at arm.com  Mon Dec  9 08:49:54 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon,  9 Dec 2024 16:49:54 +0000
Subject: [PATCH 0/3] Add SCMI Vendor module autoload support
Message-ID: <20241209164957.1801886-1-cristian.marussi@arm.com>

Hi,

a tiny series to add the capability to automatically load the proper
vendor protocol module when an SCMI driver tries to use it; while proper
vendor protocol selection is already provided by the SCMI core, automatic
loading of vendor protocols was not.

Lookup is now based on module aliases following the pattern:

	scmi-protocol-0x<PROTO_ID_NN>-<VENDOR_ID>

In [2/2] proper aliases are added to existing i.MX Vendor protocols...
...could not find a better way to build the alias string automagically...
...any advice is welcome in these regards...and any feedback too !

In V2, an additional patch is added to simply add the proper/required
MODULE_DEVICE_TABLE to SCMI transport driver to enable autoloading also
for those.

Thanks,
Cristian

V1 --> V2
- added tags
- added Transport aliases patch via MODULE_DEVICE_TABLE

Cristian Marussi (3):
  firmware: arm_scmi: Support vendor protocol modules autoloading
  firmware: arm_scmi: Add module aliases to i.MX vendor protocols
  firmware: arm_scmi: Add aliases to transport modules

 drivers/firmware/arm_scmi/driver.c            | 56 +++++++++++++++----
 .../firmware/arm_scmi/transports/mailbox.c    |  1 +
 drivers/firmware/arm_scmi/transports/smc.c    |  1 +
 drivers/firmware/arm_scmi/transports/virtio.c |  1 +
 .../arm_scmi/vendors/imx/imx-sm-bbm.c         |  5 +-
 .../arm_scmi/vendors/imx/imx-sm-misc.c        |  5 +-
 include/linux/scmi_imx_protocol.h             |  9 +--
 7 files changed, 60 insertions(+), 18 deletions(-)

-- 
2.47.0



From cristian.marussi at arm.com  Mon Dec  9 08:49:55 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon,  9 Dec 2024 16:49:55 +0000
Subject: [PATCH v2 1/3] firmware: arm_scmi: Support vendor protocol modules autoloading
In-Reply-To: <20241209164957.1801886-1-cristian.marussi@arm.com>
References: <20241209164957.1801886-1-cristian.marussi@arm.com>
Message-ID: <20241209164957.1801886-2-cristian.marussi@arm.com>

SCMI vendor protocols namespace is shared amongst all vendors so that there
can be multiple implementation for the same protocol ID by different
vendors, exposing completely different functionalities and used by distinct
SCMI vendor drivers.

For these reasons, at runtime, when some driver asks for a protocol, the
proper implementation to use is chosen based on the SCMI vendor/subvendor/
impl_version data as advertised by the platform SCMI server and gathered
from the SCMI core during stack initialization: this enables proper runtime
selection of vendor protocols even when many different protocols from
different vendors are built into the same image via a common defconfig.

This same selection mechanism works similarly well even when all the vendor
protocols are compiled as loadable modules, as long as all such required
protocol modules have been previously loaded by some other means.

Add support for the automatic loading of vendor protocol modules, based on
protocol/vendor IDs, when an SCMI driver attempts to use such a protocol.

Reported-by: Johan Hovold <johan+linaro at kernel.org>
Closes: https://lore.kernel.org/lkml/ZytnRc94iKUfMYH0 at hovoldconsulting.com/
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c | 56 ++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index eeed1689b208..60050da54bf2 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/io-64-nonatomic-hi-lo.h>
 #include <linux/kernel.h>
+#include <linux/kmod.h>
 #include <linux/ktime.h>
 #include <linux/hashtable.h>
 #include <linux/list.h>
@@ -43,6 +44,8 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/scmi.h>
 
+#define SCMI_VENDOR_MODULE_ALIAS_FMT	"scmi-protocol-0x%02x-%s"
+
 static DEFINE_IDA(scmi_id);
 
 static DEFINE_XARRAY(scmi_protocols);
@@ -275,6 +278,44 @@ scmi_vendor_protocol_lookup(int protocol_id, char *vendor_id,
 	return proto;
 }
 
+static const struct scmi_protocol *
+scmi_vendor_protocol_get(int protocol_id, struct scmi_revision_info *version)
+{
+	const struct scmi_protocol *proto;
+
+	proto = scmi_vendor_protocol_lookup(protocol_id, version->vendor_id,
+					    version->sub_vendor_id,
+					    version->impl_ver);
+	if (!proto) {
+		int ret;
+
+		pr_debug("Looking for '" SCMI_VENDOR_MODULE_ALIAS_FMT "'\n",
+			 protocol_id, version->vendor_id);
+
+		/* Note that vendor_id is mandatory for vendor protocols */
+		ret = request_module(SCMI_VENDOR_MODULE_ALIAS_FMT,
+				     protocol_id, version->vendor_id);
+		if (ret) {
+			pr_warn("Problem loading module for protocol 0x%x\n",
+				protocol_id);
+			return NULL;
+		}
+
+		/* Lookup again, once modules loaded */
+		proto = scmi_vendor_protocol_lookup(protocol_id,
+						    version->vendor_id,
+						    version->sub_vendor_id,
+						    version->impl_ver);
+	}
+
+	if (proto)
+		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 const struct scmi_protocol *
 scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
 {
@@ -283,10 +324,8 @@ scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
 	if (protocol_id < SCMI_PROTOCOL_VENDOR_BASE)
 		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);
+		proto = scmi_vendor_protocol_get(protocol_id, version);
+
 	if (!proto || !try_module_get(proto->owner)) {
 		pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
 		return NULL;
@@ -294,11 +333,6 @@ scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
 
 	pr_debug("Found SCMI Protocol 0x%x\n", protocol_id);
 
-	if (protocol_id >= SCMI_PROTOCOL_VENDOR_BASE)
-		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;
 }
 
@@ -366,7 +400,9 @@ int scmi_protocol_register(const struct scmi_protocol *proto)
 		return ret;
 	}
 
-	pr_debug("Registered SCMI Protocol 0x%x\n", proto->id);
+	pr_debug("Registered SCMI Protocol 0x%x - %s  %s  0x%08X\n",
+		 proto->id, proto->vendor_id, proto->sub_vendor_id,
+		 proto->impl_ver);
 
 	return 0;
 }
-- 
2.47.0



From cristian.marussi at arm.com  Mon Dec  9 08:49:57 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon,  9 Dec 2024 16:49:57 +0000
Subject: [PATCH v2 3/3] firmware: arm_scmi: Add aliases to transport modules
In-Reply-To: <20241209164957.1801886-1-cristian.marussi@arm.com>
References: <20241209164957.1801886-1-cristian.marussi@arm.com>
Message-ID: <20241209164957.1801886-4-cristian.marussi@arm.com>

SCMI transports when built as loadable modules should be loaded by the
subsystem they plug into, based on the related subsystem specific aliases.

Add, where missing, the MODULE_DEVICE_TABLE() directives needed to generate
the aliases required to enable autoloading for SCMI transports.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/transports/mailbox.c | 1 +
 drivers/firmware/arm_scmi/transports/smc.c     | 1 +
 drivers/firmware/arm_scmi/transports/virtio.c  | 1 +
 3 files changed, 3 insertions(+)

diff --git a/drivers/firmware/arm_scmi/transports/mailbox.c b/drivers/firmware/arm_scmi/transports/mailbox.c
index b66df2981456..bd041c99b92b 100644
--- a/drivers/firmware/arm_scmi/transports/mailbox.c
+++ b/drivers/firmware/arm_scmi/transports/mailbox.c
@@ -378,6 +378,7 @@ static const struct of_device_id scmi_of_match[] = {
 	{ .compatible = "arm,scmi" },
 	{ /* Sentinel */ },
 };
+MODULE_DEVICE_TABLE(of, scmi_of_match);
 
 DEFINE_SCMI_TRANSPORT_DRIVER(scmi_mailbox, scmi_mailbox_driver,
 			     scmi_mailbox_desc, scmi_of_match, core);
diff --git a/drivers/firmware/arm_scmi/transports/smc.c b/drivers/firmware/arm_scmi/transports/smc.c
index f632a62cfb3e..21abb571e4f2 100644
--- a/drivers/firmware/arm_scmi/transports/smc.c
+++ b/drivers/firmware/arm_scmi/transports/smc.c
@@ -301,6 +301,7 @@ static const struct of_device_id scmi_of_match[] = {
 	{ .compatible = "qcom,scmi-smc" },
 	{ /* Sentinel */ },
 };
+MODULE_DEVICE_TABLE(of, scmi_of_match);
 
 DEFINE_SCMI_TRANSPORT_DRIVER(scmi_smc, scmi_smc_driver, scmi_smc_desc,
 			     scmi_of_match, core);
diff --git a/drivers/firmware/arm_scmi/transports/virtio.c b/drivers/firmware/arm_scmi/transports/virtio.c
index 41aea33776a9..cb934db9b2b4 100644
--- a/drivers/firmware/arm_scmi/transports/virtio.c
+++ b/drivers/firmware/arm_scmi/transports/virtio.c
@@ -921,6 +921,7 @@ static const struct virtio_device_id id_table[] = {
 	{ VIRTIO_ID_SCMI, VIRTIO_DEV_ANY_ID },
 	{ 0 }
 };
+MODULE_DEVICE_TABLE(virtio, id_table);
 
 static struct virtio_driver virtio_scmi_driver = {
 	.driver.name = "scmi-virtio",
-- 
2.47.0



From ciprianmarian.costea at oss.nxp.com  Mon Dec  9 08:54:59 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Marian Costea)
Date: Mon, 9 Dec 2024 18:54:59 +0200
Subject: [PATCH] arm64: dts: s32g: add I2C support
In-Reply-To: <Z1MwkyWka3yDm8Ez@lizhi-Precision-Tower-5810>
References: <20241206123119.1688712-1-ciprianmarian.costea@oss.nxp.com>
 <Z1MwkyWka3yDm8Ez@lizhi-Precision-Tower-5810>
Message-ID: <64332634-751c-400c-9f46-7903ec85fe03@oss.nxp.com>

On 12/6/2024 7:12 PM, Frank Li wrote:
> On Fri, Dec 06, 2024 at 02:31:19PM +0200, Ciprian Costea wrote:
>> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>>
>> Add the I2C Devicetree nodes and pinmux for S32G2 and S32G3 SoCs.
>>
>> With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
>> (rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
>> are quite similar. The common part for the EVB revisions will be
>> centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
>> be placed in 's32gxxa-rdb.dtsi' file.
>>
>> This refactor will also serve for other modules in the future, such as
>> FlexCAN, DSPI.
>>
>> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>> ---
>>   arch/arm64/boot/dts/freescale/s32g2.dtsi      |  45 ++++++
>>   .../arm64/boot/dts/freescale/s32g274a-evb.dts |   1 +
>>   .../boot/dts/freescale/s32g274a-rdb2.dts      |   1 +
>>   arch/arm64/boot/dts/freescale/s32g3.dtsi      |  50 ++++++
>>   .../boot/dts/freescale/s32g399a-rdb3.dts      |  12 ++
>>   .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
>>   .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 124 +++++++++++++++
>>   7 files changed, 383 insertions(+)
>>   create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>>   create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>>
>> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>> index 7be430b78c83..0e6c847ab0c3 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
>> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>> @@ -333,6 +333,33 @@ uart1: serial at 401cc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c0: i2c at 401e4000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x401e4000 0x1000>;
>> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
> 
> hardcode 40? can you use macro for clock index? Many place use it.
> 
> Frank
> 

Hello Frank,

Thank you for your review on this patch.

A discussion regarding clock indexes for S32G SoC Modules has already 
taken place on the mailing list [1]. The conclusion was to directly use 
the clock index numbers.

[1] 
https://lore.kernel.org/all/f54d947c-58dc-498f-8871-b472f97be4a8 at oss.nxp.com/

>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c1: i2c at 401e8000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x401e8000 0x1000>;
>> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c2: i2c at 401ec000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x401ec000 0x1000>;
>> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		uart2: serial at 402bc000 {
>>   			compatible = "nxp,s32g2-linflexuart",
>>   				     "fsl,s32v234-linflexuart";
>> @@ -341,6 +368,24 @@ uart2: serial at 402bc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c3: i2c at 402d8000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x402d8000 0x1000>;
>> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c4: i2c at 402dc000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x402dc000 0x1000>;
>> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		usdhc0: mmc at 402f0000 {
>>   			compatible = "nxp,s32g2-usdhc";
>>   			reg = <0x402f0000 0x1000>;
>> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>> index b9a119eea2b7..c4a195dd67bf 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>> +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>> @@ -7,6 +7,7 @@
>>   /dts-v1/;
>>
>>   #include "s32g2.dtsi"
>> +#include "s32gxxxa-evb.dtsi"
>>
>>   / {
>>   	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
>> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
>> index aaa61a8ad0da..b5ba51696f43 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
>> +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
>> @@ -7,6 +7,7 @@
>>   /dts-v1/;
>>
>>   #include "s32g2.dtsi"
>> +#include "s32gxxxa-rdb.dtsi"
>>
>>   / {
>>   	model = "NXP S32G2 Reference Design Board 2 (S32G-VNP-RDB2)";
>> diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
>> index 6c572ffe37ca..666e4029e588 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
>> +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
>> @@ -390,6 +390,36 @@ uart1: serial at 401cc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c0: i2c at 401e4000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x401e4000 0x1000>;
>> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c1: i2c at 401e8000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x401e8000 0x1000>;
>> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c2: i2c at 401ec000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x401ec000 0x1000>;
>> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		uart2: serial at 402bc000 {
>>   			compatible = "nxp,s32g3-linflexuart",
>>   				     "fsl,s32v234-linflexuart";
>> @@ -398,6 +428,26 @@ uart2: serial at 402bc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c3: i2c at 402d8000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x402d8000 0x1000>;
>> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c4: i2c at 402dc000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x402dc000 0x1000>;
>> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		usdhc0: mmc at 402f0000 {
>>   			compatible = "nxp,s32g3-usdhc",
>>   				     "nxp,s32g2-usdhc";
>> diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
>> index 828e353455b5..eb73a5dcebe7 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
>> +++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
>> @@ -8,6 +8,7 @@
>>   /dts-v1/;
>>
>>   #include "s32g3.dtsi"
>> +#include "s32gxxxa-rdb.dtsi"
>>
>>   / {
>>   	model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
>> @@ -39,6 +40,17 @@ &uart1 {
>>   	status = "okay";
>>   };
>>
>> +&i2c4 {
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
>> +
>> +	ina231 at 40 {
>> +		compatible = "ti,ina231";
>> +		reg = <0x40>;
>> +		shunt-resistor = <1000>;
>> +	};
>> +};
>> +
>>   &usdhc0 {
>>   	pinctrl-names = "default", "state_100mhz", "state_200mhz";
>>   	pinctrl-0 = <&pinctrl_usdhc0>;
>> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>> new file mode 100644
>> index 000000000000..a44eff28073a
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>> @@ -0,0 +1,150 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
>> +/*
>> + * Copyright 2024 NXP
>> + *
>> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
>> + *          Larisa Grigore <larisa.grigore at nxp.com>
>> + */
>> +
>> +&pinctrl {
>> +	i2c0_pins: i2c0-pins {
>> +		i2c0-grp0 {
>> +			pinmux = <0x101>, <0x111>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c0-grp1 {
>> +			pinmux = <0x2352>, <0x2362>;
>> +		};
>> +	};
>> +
>> +	i2c0_gpio_pins: i2c0-gpio-pins {
>> +		i2c0-gpio-grp0 {
>> +			pinmux = <0x100>, <0x110>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c0-gpio-grp1 {
>> +			pinmux = <0x2350>, <0x2360>;
>> +		};
>> +	};
>> +
>> +	i2c1_pins: i2c1-pins {
>> +		i2c1-grp0 {
>> +			pinmux = <0x131>, <0x141>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c1-grp1 {
>> +			pinmux = <0x2cd2>, <0x2ce2>;
>> +		};
>> +	};
>> +
>> +	i2c1_gpio_pins: i2c1-gpio-pins {
>> +		i2c1-gpio-grp0 {
>> +			pinmux = <0x130>, <0x140>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c1-gpio-grp1 {
>> +			pinmux = <0x2cd0>, <0x2ce0>;
>> +		};
>> +	};
>> +
>> +	i2c2_pins: i2c2-pins {
>> +		i2c2-grp0 {
>> +			pinmux = <0x151>, <0x161>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c2-grp1 {
>> +			pinmux = <0x2cf2>, <0x2d02>;
>> +		};
>> +	};
>> +
>> +	i2c2_gpio_pins: i2c2-gpio-pins {
>> +		i2c2-gpio-grp0 {
>> +			pinmux = <0x150>, <0x160>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c2-gpio-grp1 {
>> +			pinmux = <0x2cf0>, <0x2d00>;
>> +		};
>> +	};
>> +
>> +	i2c4_pins: i2c4-pins {
>> +		i2c4-grp0 {
>> +			pinmux = <0x211>, <0x222>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c4-grp1 {
>> +			pinmux = <0x2d43>, <0x2d33>;
>> +		};
>> +	};
>> +
>> +	i2c4_gpio_pins: i2c4-gpio-pins {
>> +		i2c4-gpio-grp0 {
>> +			pinmux = <0x210>, <0x220>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c4-gpio-grp1 {
>> +			pinmux = <0x2d40>, <0x2d30>;
>> +		};
>> +	};
>> +};
>> +
>> +&i2c0 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c0_pins>;
>> +	pinctrl-1 = <&i2c0_gpio_pins>;
>> +	status = "okay";
>> +};
>> +
>> +&i2c1 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c1_pins>;
>> +	pinctrl-1 = <&i2c1_gpio_pins>;
>> +	status = "okay";
>> +};
>> +
>> +&i2c2 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c2_pins>;
>> +	pinctrl-1 = <&i2c2_gpio_pins>;
>> +	status = "okay";
>> +};
>> +
>> +&i2c4 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c4_pins>;
>> +	pinctrl-1 = <&i2c4_gpio_pins>;
>> +	status = "okay";
>> +};
>> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>> new file mode 100644
>> index 000000000000..d992c0c9e695
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>> @@ -0,0 +1,124 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
>> +/*
>> + * Copyright 2024 NXP
>> + *
>> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
>> + *          Larisa Grigore <larisa.grigore at nxp.com>
>> + */
>> +
>> +&pinctrl {
>> +	i2c0_pins: i2c0-pins {
>> +		i2c0-grp0 {
>> +			pinmux = <0x1f2>, <0x201>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c0-grp1 {
>> +			pinmux = <0x2353>, <0x2363>;
>> +		};
>> +	};
>> +
>> +	i2c0_gpio_pins: i2c0-gpio-pins {
>> +		i2c0-gpio-grp0 {
>> +			pinmux = <0x1f0>, <0x200>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c0-gpio-grp1 {
>> +			pinmux = <0x2350>, <0x2360>;
>> +		};
>> +	};
>> +
>> +	i2c2_pins: i2c2-pins {
>> +		i2c2-grp0 {
>> +			pinmux = <0x151>, <0x161>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c2-grp1 {
>> +			pinmux = <0x2cf2>, <0x2d02>;
>> +		};
>> +	};
>> +
>> +	i2c2_gpio_pins: i2c2-gpio-pins {
>> +		i2c2-gpio-grp0 {
>> +			pinmux = <0x2cf0>, <0x2d00>;
>> +		};
>> +
>> +		i2c2-gpio-grp1 {
>> +			pinmux = <0x150>, <0x160>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +	};
>> +
>> +	i2c4_pins: i2c4-pins {
>> +		i2c4-grp0 {
>> +			pinmux = <0x211>, <0x222>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c4-grp1 {
>> +			pinmux = <0x2d43>, <0x2d33>;
>> +		};
>> +	};
>> +
>> +	i2c4_gpio_pins: i2c4-gpio-pins {
>> +		i2c4-gpio-grp0 {
>> +			pinmux = <0x210>, <0x220>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c4-gpio-grp1 {
>> +			pinmux = <0x2d40>, <0x2d30>;
>> +		};
>> +	};
>> +};
>> +
>> +&i2c0 {
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
> 
> #address-cells and size-cells should be common dts to avoid set it in
> board file.
> 
> Other i2c2\i2c4 have not it. I suppose you can remove it here.
> 
> Frank
> 

Correct. I will move those in the associated 's32gxxxa-rdb.dtsi' file.

Best Regards,
Ciprian

>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c0_pins>;
>> +	pinctrl-1 = <&i2c0_gpio_pins>;
>> +	status = "okay";
>> +
>> +	pcal6524: gpio-expander at 22 {
>> +		compatible = "nxp,pcal6524";
>> +		reg = <0x22>;
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +	};
>> +};
>> +
>> +&i2c2 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c2_pins>;
>> +	pinctrl-1 = <&i2c2_gpio_pins>;
>> +	status = "okay";
>> +};
>> +
>> +&i2c4 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c4_pins>;
>> +	pinctrl-1 = <&i2c4_gpio_pins>;
>> +	status = "okay";
>> +};
>> --
>> 2.45.2
>>



From nfraprado at collabora.com  Mon Dec  9 09:00:02 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 09 Dec 2024 14:00:02 -0300
Subject: [PATCH v2 1/5] thermal/drivers/mediatek/lvts: Disable monitor mode
 during suspend
In-Reply-To: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
References: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
Message-ID: <20241209-mt8192-lvts-filtered-suspend-fix-v2-1-5b046a99baa9@collabora.com>

When configured in filtered mode, the LVTS thermal controller will
monitor the temperature from the sensors and trigger an interrupt once a
thermal threshold is crossed.

Currently this is true even during suspend and resume. The problem with
that is that when enabling the internal clock of the LVTS controller in
lvts_ctrl_set_enable() during resume, the temperature reading can glitch
and appear much higher than the real one, resulting in a spurious
interrupt getting generated.

Disable the temperature monitoring and give some time for the signals to
stabilize during suspend in order to prevent such spurious interrupts.

Cc: stable at vger.kernel.org
Reported-by: Hsin-Te Yuan <yuanhsinte at chromium.org>
Closes: https://lore.kernel.org/all/20241108-lvts-v1-1-eee339c6ca20 at chromium.org/
Fixes: 8137bb90600d ("thermal/drivers/mediatek/lvts_thermal: Add suspend and resume")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 drivers/thermal/mediatek/lvts_thermal.c | 36 +++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
index 07f7f3b7a2fb569cfc300dc2126ea426e161adff..a1a438ebad33c1fff8ca9781e12ef9e278eef785 100644
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -860,6 +860,32 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
 	return 0;
 }
 
+static void lvts_ctrl_monitor_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl, bool enable)
+{
+	/*
+	 * Bitmaps to enable each sensor on filtered mode in the MONCTL0
+	 * register.
+	 */
+	static const u8 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) };
+	u32 sensor_map = 0;
+	int i;
+
+	if (lvts_ctrl->mode != LVTS_MSR_FILTERED_MODE)
+		return;
+
+	if (enable) {
+		lvts_for_each_valid_sensor(i, lvts_ctrl)
+			sensor_map |= sensor_filt_bitmap[i];
+	}
+
+	/*
+	 * Bits:
+	 *      9: Single point access flow
+	 *    0-3: Enable sensing point 0-3
+	 */
+	writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
+}
+
 /*
  * At this point the configuration register is the only place in the
  * driver where we write multiple values. Per hardware constraint,
@@ -1381,8 +1407,11 @@ static int lvts_suspend(struct device *dev)
 
 	lvts_td = dev_get_drvdata(dev);
 
-	for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+		lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], false);
+		usleep_range(100, 200);
 		lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
+	}
 
 	clk_disable_unprepare(lvts_td->clk);
 
@@ -1400,8 +1429,11 @@ static int lvts_resume(struct device *dev)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
 		lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], true);
+		usleep_range(100, 200);
+		lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], true);
+	}
 
 	return 0;
 }

-- 
2.47.0



From nfraprado at collabora.com  Mon Dec  9 09:00:03 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 09 Dec 2024 14:00:03 -0300
Subject: [PATCH v2 2/5] thermal/drivers/mediatek/lvts: Disable Stage 3
 thermal threshold
In-Reply-To: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
References: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
Message-ID: <20241209-mt8192-lvts-filtered-suspend-fix-v2-2-5b046a99baa9@collabora.com>

The Stage 3 thermal threshold is currently configured during
the controller initialization to 105 Celsius. From the kernel
perspective, this configuration is harmful because:
* The stage 3 interrupt that gets triggered when the threshold is
  crossed is not handled in any way by the IRQ handler, it just gets
  cleared. Besides, the temperature used for stage 3 comes from the
  sensors, and the critical thermal trip points described in the
  Devicetree will already cause a shutdown when crossed (at a lower
  temperature, of 100 Celsius, for all SoCs currently using this
  driver).
* The only effect of crossing the stage 3 threshold that has been
  observed is that it causes the machine to no longer be able to enter
  suspend. Even if that was a result of a momentary glitch in the
  temperature reading of a sensor (as has been observed on the
  MT8192-based Chromebooks).

For those reasons, disable the Stage 3 thermal threshold configuration.

Cc: stable at vger.kernel.org
Reported-by: Hsin-Te Yuan <yuanhsinte at chromium.org>
Closes: https://lore.kernel.org/all/20241108-lvts-v1-1-eee339c6ca20 at chromium.org/
Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 drivers/thermal/mediatek/lvts_thermal.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
index a1a438ebad33c1fff8ca9781e12ef9e278eef785..0aaa44b734ca43e6abfd97b2ca4ce34dc6f15826 100644
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -65,7 +65,7 @@
 #define LVTS_HW_FILTER				0x0
 #define LVTS_TSSEL_CONF				0x13121110
 #define LVTS_CALSCALE_CONF			0x300
-#define LVTS_MONINT_CONF			0x8300318C
+#define LVTS_MONINT_CONF			0x0300318C
 
 #define LVTS_MONINT_OFFSET_SENSOR0		0xC
 #define LVTS_MONINT_OFFSET_SENSOR1		0x180
@@ -91,8 +91,6 @@
 #define LVTS_MSR_READ_TIMEOUT_US	400
 #define LVTS_MSR_READ_WAIT_US		(LVTS_MSR_READ_TIMEOUT_US / 2)
 
-#define LVTS_HW_TSHUT_TEMP		105000
-
 #define LVTS_MINIMUM_THRESHOLD		20000
 
 static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
@@ -145,7 +143,6 @@ struct lvts_ctrl {
 	struct lvts_sensor sensors[LVTS_SENSOR_MAX];
 	const struct lvts_data *lvts_data;
 	u32 calibration[LVTS_SENSOR_MAX];
-	u32 hw_tshut_raw_temp;
 	u8 valid_sensor_mask;
 	int mode;
 	void __iomem *base;
@@ -837,14 +834,6 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
 		 */
 		lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode;
 
-		/*
-		 * The temperature to raw temperature must be done
-		 * after initializing the calibration.
-		 */
-		lvts_ctrl[i].hw_tshut_raw_temp =
-			lvts_temp_to_raw(LVTS_HW_TSHUT_TEMP,
-					 lvts_data->temp_factor);
-
 		lvts_ctrl[i].low_thresh = INT_MIN;
 		lvts_ctrl[i].high_thresh = INT_MIN;
 	}
@@ -919,7 +908,6 @@ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
 	 *         10 : Selected sensor with bits 19-18
 	 *         11 : Reserved
 	 */
-	writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));
 
 	/*
 	 * LVTS_PROTTA : Stage 1 temperature threshold
@@ -932,8 +920,8 @@ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
 	 *
 	 * writel(0x0, LVTS_PROTTA(lvts_ctrl->base));
 	 * writel(0x0, LVTS_PROTTB(lvts_ctrl->base));
+	 * writel(0x0, LVTS_PROTTC(lvts_ctrl->base));
 	 */
-	writel(lvts_ctrl->hw_tshut_raw_temp, LVTS_PROTTC(lvts_ctrl->base));
 
 	/*
 	 * LVTS_MONINT : Interrupt configuration register

-- 
2.47.0



From nfraprado at collabora.com  Mon Dec  9 09:00:04 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 09 Dec 2024 14:00:04 -0300
Subject: [PATCH v2 3/5] thermal/drivers/mediatek/lvts: Disable low offset
 IRQ for minimum threshold
In-Reply-To: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
References: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
Message-ID: <20241209-mt8192-lvts-filtered-suspend-fix-v2-3-5b046a99baa9@collabora.com>

In order to get working interrupts, a low offset value needs to be
configured. The minimum value for it is 20 Celsius, which is what is
configured when there's no lower thermal trip (ie the thermal core
passes -INT_MAX as low trip temperature). However, when the temperature
gets that low and fluctuates around that value it causes an interrupt
storm.

Prevent that interrupt storm by not enabling the low offset interrupt if
the low threshold is the minimum one.

Cc: stable at vger.kernel.org
Fixes: 77354eaef821 ("thermal/drivers/mediatek/lvts_thermal: Don't leave threshold zeroed")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 drivers/thermal/mediatek/lvts_thermal.c | 48 ++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
index 0aaa44b734ca43e6abfd97b2ca4ce34dc6f15826..04bfbfe93a71ee9e3428bfd7f8bd359fe9446e88 100644
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -67,10 +67,14 @@
 #define LVTS_CALSCALE_CONF			0x300
 #define LVTS_MONINT_CONF			0x0300318C
 
-#define LVTS_MONINT_OFFSET_SENSOR0		0xC
-#define LVTS_MONINT_OFFSET_SENSOR1		0x180
-#define LVTS_MONINT_OFFSET_SENSOR2		0x3000
-#define LVTS_MONINT_OFFSET_SENSOR3		0x3000000
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR0		BIT(3)
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR1		BIT(8)
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR2		BIT(13)
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR3		BIT(25)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR0		BIT(2)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR1		BIT(7)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR2		BIT(12)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR3		BIT(24)
 
 #define LVTS_INT_SENSOR0			0x0009001F
 #define LVTS_INT_SENSOR1			0x001203E0
@@ -326,11 +330,17 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
 
 static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
 {
-	static const u32 masks[] = {
-		LVTS_MONINT_OFFSET_SENSOR0,
-		LVTS_MONINT_OFFSET_SENSOR1,
-		LVTS_MONINT_OFFSET_SENSOR2,
-		LVTS_MONINT_OFFSET_SENSOR3,
+	static const u32 high_offset_inten_masks[] = {
+		LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR0,
+		LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR1,
+		LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR2,
+		LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR3,
+	};
+	static const u32 low_offset_inten_masks[] = {
+		LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR0,
+		LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR1,
+		LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR2,
+		LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR3,
 	};
 	u32 value = 0;
 	int i;
@@ -339,10 +349,22 @@ static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
 
 	for (i = 0; i < ARRAY_SIZE(masks); i++) {
 		if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
-		    && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
-			value |= masks[i];
-		else
-			value &= ~masks[i];
+		    && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh) {
+			/*
+			 * The minimum threshold needs to be configured in the
+			 * OFFSETL register to get working interrupts, but we
+			 * don't actually want to generate interrupts when
+			 * crossing it.
+			 */
+			if (lvts_ctrl->low_thresh == -INT_MAX) {
+				value &= ~low_offset_inten_masks[i];
+				value |= high_offset_inten_masks[i];
+			} else {
+				value |= low_offset_inten_masks[i] | high_offset_inten_masks[i];
+			}
+		} else {
+			value &= ~(low_offset_inten_masks[i] | high_offset_inten_masks[i]);
+		}
 	}
 
 	writel(value, LVTS_MONINT(lvts_ctrl->base));

-- 
2.47.0



From nfraprado at collabora.com  Mon Dec  9 09:00:05 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 09 Dec 2024 14:00:05 -0300
Subject: [PATCH v2 4/5] thermal/drivers/mediatek/lvts: Start sensor
 interrupts disabled
In-Reply-To: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
References: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
Message-ID: <20241209-mt8192-lvts-filtered-suspend-fix-v2-4-5b046a99baa9@collabora.com>

Interrupts are enabled per sensor in lvts_update_irq_mask() as needed,
there's no point in enabling all of them during initialization. Change
the MONINT register initial value so all sensor interrupts start
disabled.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 drivers/thermal/mediatek/lvts_thermal.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
index 04bfbfe93a71ee9e3428bfd7f8bd359fe9446e88..38668b5b34c7375d3a3b0dcf8dcc965a254776cc 100644
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -65,7 +65,6 @@
 #define LVTS_HW_FILTER				0x0
 #define LVTS_TSSEL_CONF				0x13121110
 #define LVTS_CALSCALE_CONF			0x300
-#define LVTS_MONINT_CONF			0x0300318C
 
 #define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR0		BIT(3)
 #define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR1		BIT(8)
@@ -951,7 +950,7 @@ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
 	 * The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS
 	 * register, except we set the bits to enable the interrupt.
 	 */
-	writel(LVTS_MONINT_CONF, LVTS_MONINT(lvts_ctrl->base));
+	writel(0, LVTS_MONINT(lvts_ctrl->base));
 
 	return 0;
 }

-- 
2.47.0



From nfraprado at collabora.com  Mon Dec  9 09:00:06 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 09 Dec 2024 14:00:06 -0300
Subject: [PATCH v2 5/5] thermal/drivers/mediatek/lvts: Only update IRQ
 enable for valid sensors
In-Reply-To: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
References: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>
Message-ID: <20241209-mt8192-lvts-filtered-suspend-fix-v2-5-5b046a99baa9@collabora.com>

Only sensors that are valid need to have their interrupts enable status
updated based on their thresholds. Use the lvts_for_each_valid_sensor()
helper in lvts_update_irq_mask() to ignore invalid sensors.

Currently, since the invalid sensors will always contain zeroed out
thresholds (from kzalloc), they will always get their interrupts
disabled on this loop. So this commit doesn't change the resulting
interrupts configuration, but it slightly optimizes the loop by skipping
the invalid sensors, avoids potential future surprises if at some point
memory is no longer allocated for invalid sensors, as well as makes the
code more obvious.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 drivers/thermal/mediatek/lvts_thermal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
index 38668b5b34c7375d3a3b0dcf8dcc965a254776cc..088481d91e6e294a31fac7ceed7f3ff62ee3a98d 100644
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -346,7 +346,7 @@ static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
 
 	value = readl(LVTS_MONINT(lvts_ctrl->base));
 
-	for (i = 0; i < ARRAY_SIZE(masks); i++) {
+	lvts_for_each_valid_sensor(i, lvts_ctrl) {
 		if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
 		    && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh) {
 			/*

-- 
2.47.0



From suzuki.poulose at arm.com  Mon Dec  9 09:04:11 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 9 Dec 2024 17:04:11 +0000
Subject: [PATCH v6 3/4] coresight: Add support for trace filtering by
 source
In-Reply-To: <20241125130555.19924-4-quic_taozha@quicinc.com>
References: <20241125130555.19924-1-quic_taozha@quicinc.com>
 <20241125130555.19924-4-quic_taozha@quicinc.com>
Message-ID: <87dc3d73-7f92-4b7e-97e1-94e3bb27198c@arm.com>

On 25/11/2024 13:05, Tao Zhang wrote:
> Some replicators have hard coded filtering of "trace" data, based on the
> source device. This is different from the trace filtering based on
> TraceID, available in the standard programmable replicators. e.g.,
> Qualcomm replicators have filtering based on custom trace protocol
> format and is not programmable.
> 
> The source device could be connected to the replicator via intermediate
> components (e.g., a funnel). Thus we need platform information from
> the firmware tables to decide the source device corresponding to a
> given output port from the replicator. Given this affects "trace
> path building" and traversing the path back from the sink to source,
> add the concept of "filtering by source" to the generic coresight
> connection.
> 
> The specified source will be marked like below in the Devicetree.
> test-replicator {
>      ... ... ... ...
>      out-ports {
>          ... ... ... ...
>          port at 0 {
>              reg = <0>;
>              xyz: endpoint {
>                  remote-endpoint = <&zyx>;
>                  filter-source = <&source_1>; <-- To specify the source to
>              };                           be filtered out here.
>          };
> 
>          port at 1 {
>              reg = <1>;
>              abc: endpoint {
>                  remote-endpoint = <&cba>;
>                  filter-source = <&source_2>; <-- To specify the source to
>              };                           be filtered out here.
>          };
>      };
> };
> 
> Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
> ---
>   drivers/hwtracing/coresight/coresight-core.c  | 113 +++++++++++++++---
>   .../hwtracing/coresight/coresight-platform.c  |  21 ++++
>   include/linux/coresight.h                     |   5 +
>   3 files changed, 120 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index ea38ecf26fcb..0a9380350fb5 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -75,22 +75,54 @@ struct coresight_device *coresight_get_percpu_sink(int cpu)
>   }
>   EXPORT_SYMBOL_GPL(coresight_get_percpu_sink);
>   
> +static struct coresight_device *coresight_get_source(struct list_head *path)
> +{
> +	struct coresight_device *csdev;
> +
> +	if (!path)
> +		return NULL;
> +
> +	csdev = list_first_entry(path, struct coresight_node, link)->csdev;
> +	if (!coresight_is_device_source(csdev))
> +		return NULL;
> +
> +	return csdev;
> +}
> +
> +/**
> + * coresight_blocks_source - checks whether the connection matches the source
> + * of path if connection is bound to specific source.
> + * @src:	The source device of the trace path
> + * @conn:	The connection of one outport
> + *
> + * Return false if the connection doesn't have a source binded or source of the
> + * path matches the source binds to connection.
> + */
> +static bool coresight_blocks_source(struct coresight_device *src,
> +				    struct coresight_connection *conn)
> +{
> +	return conn->filter_src_fwnode && (conn->filter_src_dev != src);
> +}
> +
>   static struct coresight_connection *
> -coresight_find_out_connection(struct coresight_device *src_dev,
> -			      struct coresight_device *dest_dev)
> +coresight_find_out_connection(struct coresight_device *csdev,
> +			      struct coresight_device *out_dev,
> +			      struct coresight_device *trace_src)
>   {
>   	int i;
>   	struct coresight_connection *conn;
>   
> -	for (i = 0; i < src_dev->pdata->nr_outconns; i++) {
> -		conn = src_dev->pdata->out_conns[i];
> -		if (conn->dest_dev == dest_dev)
> +	for (i = 0; i < csdev->pdata->nr_outconns; i++) {
> +		conn = csdev->pdata->out_conns[i];
> +		if (coresight_blocks_source(trace_src, conn))
> +			continue;
> +		if (conn->dest_dev == out_dev)
>   			return conn;
>   	}
>   
> -	dev_err(&src_dev->dev,
> -		"couldn't find output connection, src_dev: %s, dest_dev: %s\n",
> -		dev_name(&src_dev->dev), dev_name(&dest_dev->dev));
> +	dev_err(&csdev->dev,
> +		"couldn't find output connection, csdev: %s, out_dev: %s\n",
> +		dev_name(&csdev->dev), dev_name(&out_dev->dev));
>   
>   	return ERR_PTR(-ENODEV);
>   }
> @@ -251,7 +283,8 @@ static void coresight_disable_sink(struct coresight_device *csdev)
>   
>   static int coresight_enable_link(struct coresight_device *csdev,
>   				 struct coresight_device *parent,
> -				 struct coresight_device *child)
> +				 struct coresight_device *child,
> +				 struct coresight_device *source)
>   {
>   	int link_subtype;
>   	struct coresight_connection *inconn, *outconn;
> @@ -259,8 +292,8 @@ static int coresight_enable_link(struct coresight_device *csdev,
>   	if (!parent || !child)
>   		return -EINVAL;
>   
> -	inconn = coresight_find_out_connection(parent, csdev);
> -	outconn = coresight_find_out_connection(csdev, child);
> +	inconn = coresight_find_out_connection(parent, csdev, source);
> +	outconn = coresight_find_out_connection(csdev, child, source);
>   	link_subtype = csdev->subtype.link_subtype;
>   
>   	if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && IS_ERR(inconn))
> @@ -273,15 +306,16 @@ static int coresight_enable_link(struct coresight_device *csdev,
>   
>   static void coresight_disable_link(struct coresight_device *csdev,
>   				   struct coresight_device *parent,
> -				   struct coresight_device *child)
> +				   struct coresight_device *child,
> +				   struct coresight_device *source)
>   {
>   	struct coresight_connection *inconn, *outconn;
>   
>   	if (!parent || !child)
>   		return;
>   
> -	inconn = coresight_find_out_connection(parent, csdev);
> -	outconn = coresight_find_out_connection(csdev, child);
> +	inconn = coresight_find_out_connection(parent, csdev, source);
> +	outconn = coresight_find_out_connection(csdev, child, source);
>   
>   	link_ops(csdev)->disable(csdev, inconn, outconn);
>   }
> @@ -375,7 +409,8 @@ static void coresight_disable_path_from(struct list_head *path,
>   		case CORESIGHT_DEV_TYPE_LINK:
>   			parent = list_prev_entry(nd, link)->csdev;
>   			child = list_next_entry(nd, link)->csdev;
> -			coresight_disable_link(csdev, parent, child);
> +			coresight_disable_link(csdev, parent, child,
> +					       coresight_get_source(path));
>   			break;
>   		default:
>   			break;
> @@ -418,7 +453,9 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
>   	u32 type;
>   	struct coresight_node *nd;
>   	struct coresight_device *csdev, *parent, *child;
> +	struct coresight_device *source;
>   
> +	source = coresight_get_source(path);
>   	list_for_each_entry_reverse(nd, path, link) {
>   		csdev = nd->csdev;
>   		type = csdev->type;
> @@ -456,7 +493,7 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
>   		case CORESIGHT_DEV_TYPE_LINK:
>   			parent = list_prev_entry(nd, link)->csdev;
>   			child = list_next_entry(nd, link)->csdev;
> -			ret = coresight_enable_link(csdev, parent, child);
> +			ret = coresight_enable_link(csdev, parent, child, source);
>   			if (ret)
>   				goto err;
>   			break;
> @@ -619,6 +656,7 @@ static void coresight_drop_device(struct coresight_device *csdev)
>   /**
>    * _coresight_build_path - recursively build a path from a @csdev to a sink.
>    * @csdev:	The device to start from.
> + * @source:	The trace source device of the path.
>    * @sink:	The final sink we want in this path.
>    * @path:	The list to add devices to.
>    *
> @@ -628,6 +666,7 @@ static void coresight_drop_device(struct coresight_device *csdev)
>    * the source is the first device and the sink the last one.
>    */
>   static int _coresight_build_path(struct coresight_device *csdev,
> +				 struct coresight_device *source,
>   				 struct coresight_device *sink,
>   				 struct list_head *path)
>   {
> @@ -641,7 +680,7 @@ static int _coresight_build_path(struct coresight_device *csdev,
>   
>   	if (coresight_is_percpu_source(csdev) && coresight_is_percpu_sink(sink) &&
>   	    sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) {
> -		if (_coresight_build_path(sink, sink, path) == 0) {
> +		if (_coresight_build_path(sink, source, sink, path) == 0) {
>   			found = true;
>   			goto out;
>   		}
> @@ -652,8 +691,12 @@ static int _coresight_build_path(struct coresight_device *csdev,
>   		struct coresight_device *child_dev;
>   
>   		child_dev = csdev->pdata->out_conns[i]->dest_dev;
> +
> +		if (coresight_blocks_source(source, csdev->pdata->out_conns[i]))
> +			continue;
> +
>   		if (child_dev &&
> -		    _coresight_build_path(child_dev, sink, path) == 0) {
> +		    _coresight_build_path(child_dev, source, sink, path) == 0) {
>   			found = true;
>   			break;
>   		}
> @@ -698,7 +741,7 @@ struct list_head *coresight_build_path(struct coresight_device *source,
>   
>   	INIT_LIST_HEAD(path);
>   
> -	rc = _coresight_build_path(source, sink, path);
> +	rc = _coresight_build_path(source, source, sink, path);
>   	if (rc) {
>   		kfree(path);
>   		return ERR_PTR(rc);
> @@ -927,6 +970,16 @@ static int coresight_orphan_match(struct device *dev, void *data)
>   	for (i = 0; i < src_csdev->pdata->nr_outconns; i++) {
>   		conn = src_csdev->pdata->out_conns[i];
>   
> +		/* Fix filter source device before skip the port */
> +		if (conn->filter_src_fwnode && !conn->filter_src_dev) {
> +			if (dst_csdev &&
> +			    (conn->filter_src_fwnode == dst_csdev->dev.fwnode) &&
> +			    !WARN_ON_ONCE(!coresight_is_device_source(dst_csdev)))
> +				conn->filter_src_dev = dst_csdev;
> +			else
> +				still_orphan = true;
> +		}
> +
>   		/* Skip the port if it's already connected. */
>   		if (conn->dest_dev)
>   			continue;
> @@ -977,18 +1030,40 @@ static int coresight_fixup_orphan_conns(struct coresight_device *csdev)
>   			 csdev, coresight_orphan_match);
>   }
>   
> +static int coresight_clear_filter_source(struct device *dev, void *data)
> +{
> +	int i;
> +	struct coresight_device *source = data;
> +	struct coresight_device *csdev = to_coresight_device(dev);
> +
> +	for (i = 0; i < csdev->pdata->nr_outconns; ++i) {
> +		if (csdev->pdata->out_conns[i]->filter_src_dev == source)
> +			csdev->pdata->out_conns[i]->filter_src_dev = NULL;
> +	}
> +	return 0;
> +}
> +
>   /* coresight_remove_conns - Remove other device's references to this device */
>   static void coresight_remove_conns(struct coresight_device *csdev)
>   {
>   	int i, j;
>   	struct coresight_connection *conn;
>   
> +	if (coresight_is_device_source(csdev))
> +		bus_for_each_dev(&coresight_bustype, NULL, csdev,
> +				 coresight_clear_filter_source);
> +
>   	/*
>   	 * Remove the input connection references from the destination device
>   	 * for each output connection.
>   	 */
>   	for (i = 0; i < csdev->pdata->nr_outconns; i++) {
>   		conn = csdev->pdata->out_conns[i];
> +		if (conn->filter_src_fwnode) {
> +			conn->filter_src_dev = NULL;
> +			fwnode_handle_put(conn->filter_src_fwnode);
> +		}
> +
>   		if (!conn->dest_dev)
>   			continue;
>   
> diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
> index 64e171eaad82..a04bd80492b9 100644
> --- a/drivers/hwtracing/coresight/coresight-platform.c
> +++ b/drivers/hwtracing/coresight/coresight-platform.c
> @@ -243,6 +243,27 @@ static int of_coresight_parse_endpoint(struct device *dev,
>   		conn.dest_fwnode = fwnode_handle_get(rdev_fwnode);
>   		conn.dest_port = rendpoint.port;
>   
> +		/*
> +		 * Get the firmware node of the filter source through the
> +		 * reference. This could be used to filter the source in
> +		 * building path.
> +		 */
> +		conn.filter_src_fwnode =
> +			fwnode_find_reference(&ep->fwnode, "filter-source", 0);
> +		if (IS_ERR(conn.filter_src_fwnode)) {
> +			conn.filter_src_fwnode = NULL;
> +		} else {
> +			conn.filter_src_dev =
> +			 coresight_find_csdev_by_fwnode(conn.filter_src_fwnode);
> +			if (conn.filter_src_dev &&
> +			    !coresight_is_device_source(conn.filter_src_dev)) {
> +				dev_warn(dev, "port %d: Filter handle is not a trace source : %s\n",
> +					 conn.src_port, dev_name(&conn.filter_src_dev->dev));
> +				conn.filter_src_dev = NULL?

The line above generates build errors for me !

drivers/hwtracing/coresight/coresight-platform.c:262:27: error: ?NULL?? 
undeclared (first use in this function); did you mean ?NULL??
   262 |     conn.filter_src_dev = NULL?
       |                           ^~~~~~


Because the ";" in the line is not really ASCII ? Please fix up , rebase 
the series on v6.13-rc1 and resend it

Suzuki



From sudeep.holla at arm.com  Mon Dec  9 08:59:19 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 9 Dec 2024 16:59:19 +0000
Subject: [PATCH v2 2/2] firmware/arm_ffa: remove __le64_to_cpu() when set
 uuid for direct msg v2
In-Reply-To: <9e60e996-070e-43a7-80e9-efdfda9f6223@app.fastmail.com>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
 <20241203143109.1030514-3-yeoreum.yun@arm.com>
 <9e60e996-070e-43a7-80e9-efdfda9f6223@app.fastmail.com>
Message-ID: <Z1ch52AthTYVhtH4@bogus>

On Mon, Dec 09, 2024 at 04:27:14PM +0100, Arnd Bergmann wrote:
> On Tue, Dec 3, 2024, at 15:31, Yeoreum Yun wrote:
> > From: Levi Yun <yeoreum.yun at arm.com>
> 
> I just saw this commit in the pull request, and I'm very
> confused because the description does not match the
> patch contents.
>

Sorry for that, I tried to reword to improve it but it is obvious now that I
didn't do a good job there.

> > Accoding to FF-A specification[0] 15.4 FFA_MSG_SEND_DRIECT_REQ2,
> > then UUID is saved in register:
> >     UUID Lo  x2  Bytes[0...7] of UUID with byte 0 in the low-order bits.
> >     UUID Hi  x3  Bytes[8...15] of UUID with byte 8 in the low-order bits.
>
> The specification you cite here clearly describes little-endian
> format, i.e. the low-order byte corresponds to the first
> memory address.
>


> > That means, we don't need to swap the uuid when it send via direct
> > message request version 2, just send it as saved in memory.
>
> "As saved in memory" does not sound like a useful description
> when passing arguments through registers, as the register
> contents are not defined in terms of byte offsets.
>

Well I didn't know how to term it. The structure UUID is a raw buffer
and it provide helpers to import/export the data in/out of it. So in LE
kernel IIUC, it is stored in LE format itself which was my initial
confusion and hence though what you fixed was correct previously.

> Can you describe what bug you found? If the byteorder on
> big-endian kernels is wrong in the current version and your
> patch fixes it, it sounds like the specification needs to
> be updated describe both big-endian and little-endian
> byte-order, and how the firmware detects which one is used.
>

The firmware interface understands only LE format. And by default UUID
is stored in LE format itself in the structure which I got confused
initially. We may need endian conversion at places(found few when trying
to get it working with BE kernel).

I wanted to check with you about this. The current driver doesn't
work with BE. I tried to cook up patches but then the upstream user
of this driver OPTEE doesn't work in BE, so I hit a roadblock to fully
validate my changes. I don't see any driver adding endianness dependency
in the Kconfig if they can't work with BE, not sure if that is intentional
or just don't care. I was thinking if we can disable it to build in BE
kernel until the actual support was added.

So the current FF-A driver just supports LE and the bug was found just
in LE kernel itself.

> > Remove le64_to_cpu() for uuid in direct message request version 2,
> > and change uuid_regs' type to unsigned long.
>
> 'unsigned long' makes the code unnecessarily incompatible
> with 32-bit builds.
>

Understood we may need some typecasting to avoid compiler warnings.

Just a note not related to your comment though: FFA_MSG_SEND_DIRECT_REQ2
is 64-bit only as it uses full 64-bit register to pass UUID.

--
Regards,
Sudeep


From nfraprado at collabora.com  Mon Dec  9 09:00:01 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 09 Dec 2024 14:00:01 -0300
Subject: [PATCH v2 0/5] thermal/drivers/mediatek/lvts: Fixes for suspend
 and IRQ storm, and cleanups
Message-ID: <20241209-mt8192-lvts-filtered-suspend-fix-v2-0-5b046a99baa9@collabora.com>

Patches 1 and 2 of this series fix the issue reported by Hsin-Te Yuan
[1] where MT8192-based Chromebooks are not able to suspend/resume 10
times in a row. Either one of those patches on its own is enough to fix
the issue, but I believe both are desirable, so I've included them both
here.

Patches 3-5 fix unrelated issues that I've noticed while debugging.
Patch 3 fixes IRQ storms when the temperature sensors drop to 20
Celsius. Patches 4 and 5 are cleanups to prevent future issues.

To test this series, I've run 'rtcwake -m mem -d 60' 10 times in a row
on a MT8192-Asurada-Spherion-rev3 Chromebook and checked that the wakeup
happened 60 seconds later (+-5 seconds). I've repeated that test on 10
separate runs. Not once did the chromebook wake up early with the series
applied.

I've also checked that during those runs, the LVTS interrupt didn't
trigger even once, while before the series it would trigger a few times
per run, generally during boot or resume.

Finally, as a sanity check I've verified that the interrupts still work
by lowering the thermal trip point to 45 Celsius and running 'stress -c
8'. Indeed they still do, and the temperature showed by the
thermal_temperature ftrace event matched the expected value.

[1] https://lore.kernel.org/all/20241108-lvts-v1-1-eee339c6ca20 at chromium.org/

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
Changes in v2:
- Renamed bitmasks for interrupt enable (added "INTEN" to the name)
- Made read-only arrays static const
- Changed sensor_filt_bitmap array from u32 to u8 to save memory
- Rebased on next-20241209
- Link to v1: https://lore.kernel.org/r/20241125-mt8192-lvts-filtered-suspend-fix-v1-0-42e3c0528c6c at collabora.com

---
N?colas F. R. A. Prado (5):
      thermal/drivers/mediatek/lvts: Disable monitor mode during suspend
      thermal/drivers/mediatek/lvts: Disable Stage 3 thermal threshold
      thermal/drivers/mediatek/lvts: Disable low offset IRQ for minimum threshold
      thermal/drivers/mediatek/lvts: Start sensor interrupts disabled
      thermal/drivers/mediatek/lvts: Only update IRQ enable for valid sensors

 drivers/thermal/mediatek/lvts_thermal.c | 103 ++++++++++++++++++++++----------
 1 file changed, 72 insertions(+), 31 deletions(-)
---
base-commit: d1486dca38afd08ca279ae94eb3a397f10737824
change-id: 20241121-mt8192-lvts-filtered-suspend-fix-a5032ca8eceb

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From daniel at fooishbar.org  Mon Dec  9 09:06:05 2024
From: daniel at fooishbar.org (Daniel Stone)
Date: Mon, 9 Dec 2024 17:06:05 +0000
Subject: [PATCH v5 08/18] drm/rockchip: vop2: Add check for 32 bpp format
In-Reply-To: <20241209123215.2781721-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com> <20241209123215.2781721-1-andyshrk@163.com>
Message-ID: <CAPj87rO0MG2yE_NTndbxQ77rW-p6-ht5kx5vsaOZikQfVmwrgg@mail.gmail.com>

Hi Andy,

On Mon, 9 Dec 2024 at 12:32, Andy Yan <andyshrk at 163.com> wrote:
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> index bd8db45eeba6..1f101a3c3942 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> @@ -1224,7 +1224,15 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
>                                 return -EINVAL;
>                         }
>                 }
> +       }
>
> +       if (fb->format->format == DRM_FORMAT_XRGB2101010 || fb->format->format == DRM_FORMAT_XBGR2101010) {
> +               if (vop2->data->soc_id == 3588) {
> +                       if (!rockchip_afbc(plane, fb->modifier)) {
> +                               drm_err(vop2->drm, "Unsupported linear 32 bpp for %s\n", win->data->name);
> +                               return -EINVAL;
> +                       }
> +               }

Please do this in the format_mod_supported() hook, so userspace can
see the true support of each format/modifier per plane. This will then
be checked in drm_atomic_plane_check() so you don't need to open-code
it here.

Cheers,
Daniel


From catalin.marinas at arm.com  Mon Dec  9 09:09:14 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 9 Dec 2024 17:09:14 +0000
Subject: [PATCH] mm/execmem: Make ARCH_WANTS_EXECMEM_LATE depend on
 EXECMEM
In-Reply-To: <f492ac51-9dad-4b18-8cd4-81dc236b3162@arm.com>
References: <20241209031251.515903-1-anshuman.khandual@arm.com>
 <202412092048.tTzJ5szH-lkp@intel.com>
 <f492ac51-9dad-4b18-8cd4-81dc236b3162@arm.com>
Message-ID: <Z1ckOoPMSXfNdrXd@arm.com>

On Mon, Dec 09, 2024 at 07:43:32PM +0530, Anshuman Khandual wrote:
> On 12/9/24 18:06, kernel test robot wrote:
> > kernel test robot noticed the following build warnings:
> > 
> > [auto build test WARNING on akpm-mm/mm-everything]
> > 
> > url:    https://github.com/intel-lab-lkp/linux/commits/Anshuman-Khandual/mm-execmem-Make-ARCH_WANTS_EXECMEM_LATE-depend-on-EXECMEM/20241209-111533
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
> > patch link:    https://lore.kernel.org/r/20241209031251.515903-1-anshuman.khandual%40arm.com
> > patch subject: [PATCH] mm/execmem: Make ARCH_WANTS_EXECMEM_LATE depend on EXECMEM
> > config: arm64-kismet-CONFIG_ARCH_WANTS_EXECMEM_LATE-CONFIG_ARM64-0-0 (https://download.01.org/0day-ci/archive/20241209/202412092048.tTzJ5szH-lkp at intel.com/config)
> > reproduce: (https://download.01.org/0day-ci/archive/20241209/202412092048.tTzJ5szH-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/202412092048.tTzJ5szH-lkp at intel.com/
> > 
> > kismet warnings: (new ones prefixed by >>)
> >>> kismet: WARNING: unmet direct dependencies detected for ARCH_WANTS_EXECMEM_LATE when selected by ARM64
> >    WARNING: unmet direct dependencies detected for ARCH_WANTS_EXECMEM_LATE
> >      Depends on [n]: EXECMEM [=n]
> >      Selected by [y]:
> >      - ARM64 [=y]
> 
> Although above mentioned config here has CONFIG_ARCH_WANTS_EXECMEM_LATE=y
> and CONFIG_EXECMEM=n (actually absent), could that really happen though ?
> 
> Tried making CONFIG_EXECMEM=n (rather deselecting) but that did now allow
> setting CONFIG_EXECMEM=n, it always remained set. Reverting this patch i.e
> the current behaviour is also the same (CONFIG_EXECMEM always remains set).
> 
> select ARCH_WANTS_EXECMEM_LATE if EXECMEM
> 
> Above statement seems to be selecting EXECMEM as well but the intent seems
> to be a dependency check instead! OR arch selection for a config brings in
> all its dependencies as well.
> 
> If the selection is always, should this change be like the following ?
> 
> config ARCH_WANTS_EXECMEM_LATE
>  	bool
> 	selects EXECMEM

This is wrong. What ARCH_WANTS_EXECMEM_LATE means is that, _if_ EXECMEM
is enabled, the arch code require its late initialisation. Currently for
arm64 EXECMEM is selected by KPROBES, BPF_JIT and MODULES. So if you
don't have any of these on, you don't need EXECMEM either, no point in
selecting it above just because arm64 wants a specific behaviour (late
initialisation) for EXECMEM.

If you do want a patch for this, I think for arm64 we simply need to
select ARCH_WANTS_EXECMEM_LATE unconditionally. Not much use in having
any dependencies really, it just adds to the clutter. And don't change
the core Kconfig either.

-- 
Catalin


From apatel at ventanamicro.com  Mon Dec  9 09:09:16 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 9 Dec 2024 22:39:16 +0530
Subject: [PATCH 1/4] irqchip/riscv-imsic: Handle non-atomic MSI updates
 for device
In-Reply-To: <87r06gq2di.ffs@tglx>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
 <20241208150711.297624-2-apatel@ventanamicro.com> <875xnuq6dc.ffs@tglx>
 <CAK9=C2VqU2mdLL-R20bdgvDHi0WcuNyUSqRo7Pztsu-8X1wVvw@mail.gmail.com> <87r06gq2di.ffs@tglx>
Message-ID: <CAK9=C2UZKgkA_xZPs2=RBo7bUDKpeY2gBA2j3+S4i4xSLqC5BQ@mail.gmail.com>

On Mon, Dec 9, 2024 at 9:23?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> Anup!
>
> On Mon, Dec 09 2024 at 17:38, Anup Patel wrote:
> > On Mon, Dec 9, 2024 at 1:44?AM Thomas Gleixner <tglx at linutronix.de> wrote:
> >> There is no guarantee that set_affinity() runs on the original target
> >> CPU (CPU 1). Your scheme only works, when CPU1 vector 0x20 is not used
> >> by some other device. If it's used, you lost as CPU1 will consume the
> >> vector and your pending check is not seeing anything.
> >>
> >> x86 ensures CPU locality by deferring the affinity move to the next
> >> device interrupt on the original target CPU (CPU1 in the above
> >> example). See CONFIG_GENERIC_IRQ_PENDING.
> >
> > I agree with you.
> >
> > The IMSIC driver must do the affinity move upon the next device
> > interrupt on the old CPU. I will update this patch in the next revision.
> >
> > BTW, I did not find CONFIG_GENERIC_IRQ_PENDING. Is the
> > name correct ?
>
> CONFIG_GENERIC_PENDING_IRQ is close enough :)
>
> >> The interrupt domains which are not affected (remap) set the
> >> IRQ_MOVE_PCNTXT flag to avoid that dance and don't use that affinity
> >> setter code path at all.
> >
> > Yes, setting the IRQ_MOVE_PCNTXT flag in the remap domain
> > makes perfect sense.
> >
> > I suggest adding IRQ_MOVE_PCNTXT usage as part of Drew's
> > irqbypass series which adds a remap domain in the IOMMU
> > driver. Unless you insist on having it as part of this series ?
>
> You need to look at the other RISC-V controllers. Those which do not
> need this should set it. That's historically backwards.

I will update the RISC-V APLIC MSI-mode driver in the next revision.
This driver is a good candidate to use IRQ_MOVE_PCNTXT and
IRQCHIP_MOVE_DEFERRED.

>
> I think we can reverse the logic here. As this needs backporting, I
> can't make a full cleanup of this, but for your problem the patch below
> should just work.
>
> Select GENERIC_PENDING_IRQ and GENERIC_PENDING_IRQ_CHIPFLAGS and set the
> IRQCHIP_MOVE_DEFERRED flag on your interrrupt chip and the core logic
> takes care of the PCNTXT bits.

Sure, I will update.

Thanks,
Anup


>
> I'll convert x86 in a seperate step and remove the PCNTXT leftovers and
> the new config knob once the dust has settled.
>
> Thanks,
>
>         tglx
> ---
> --- a/include/linux/irq.h
> +++ b/include/linux/irq.h
> @@ -567,6 +567,7 @@ struct irq_chip {
>   *                                    in the suspend path if they are in disabled state
>   * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
>   * IRQCHIP_IMMUTABLE:                Don't ever change anything in this chip
> + * IRQCHIP_MOVE_DEFERRED:            Move the interrupt in actual interrupt context
>   */
>  enum {
>         IRQCHIP_SET_TYPE_MASKED                 = (1 <<  0),
> @@ -581,6 +582,7 @@ enum {
>         IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND        = (1 <<  9),
>         IRQCHIP_AFFINITY_PRE_STARTUP            = (1 << 10),
>         IRQCHIP_IMMUTABLE                       = (1 << 11),
> +       IRQCHIP_MOVE_DEFERRED                   = (1 << 12),
>  };
>
>  #include <linux/irqdesc.h>
> --- a/kernel/irq/Kconfig
> +++ b/kernel/irq/Kconfig
> @@ -31,6 +31,10 @@ config GENERIC_IRQ_EFFECTIVE_AFF_MASK
>  config GENERIC_PENDING_IRQ
>         bool
>
> +# Deduce delayed migration from top-level interrupt chip flags
> +config GENERIC_PENDING_IRQ_CHIPFLAGS
> +       bool
> +
>  # Support for generic irq migrating off cpu before the cpu is offline.
>  config GENERIC_IRQ_MIGRATION
>         bool
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -47,6 +47,13 @@ int irq_set_chip(unsigned int irq, const
>                 return -EINVAL;
>
>         desc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
> +
> +       if (IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS) && chip) {
> +               if (chip->flags & IRQCHIP_MOVE_DEFERRED)
> +                       irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
> +               else
> +                       irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
> +       }
>         irq_put_desc_unlock(desc, flags);
>         /*
>          * For !CONFIG_SPARSE_IRQ make the irq show up in
> @@ -1114,16 +1121,21 @@ void irq_modify_status(unsigned int irq,
>         trigger = irqd_get_trigger_type(&desc->irq_data);
>
>         irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
> -                  IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT);
> +                  IRQD_TRIGGER_MASK | IRQD_LEVEL);
>         if (irq_settings_has_no_balance_set(desc))
>                 irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
>         if (irq_settings_is_per_cpu(desc))
>                 irqd_set(&desc->irq_data, IRQD_PER_CPU);
> -       if (irq_settings_can_move_pcntxt(desc))
> -               irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
>         if (irq_settings_is_level(desc))
>                 irqd_set(&desc->irq_data, IRQD_LEVEL);
>
> +       /* Keep this around until x86 is converted over */
> +       if (!IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS)) {
> +               irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
> +               if (irq_settings_can_move_pcntxt(desc))
> +                       irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
> +       }
> +
>         tmp = irq_settings_get_trigger_mask(desc);
>         if (tmp != IRQ_TYPE_NONE)
>                 trigger = tmp;
>
>
>


From sudeep.holla at arm.com  Mon Dec  9 09:12:06 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 9 Dec 2024 17:12:06 +0000
Subject: [PATCH v2 2/2] firmware: arm_scmi: round rate bisecting in
 discrete rates
In-Reply-To: <ed164b6704ab4086b2fb22ae51658f31@foss.st.com>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-3-etienne.carriere@foss.st.com>
 <Z1bKlOeHJFHpe9ZU@bogus>
 <ed164b6704ab4086b2fb22ae51658f31@foss.st.com>
Message-ID: <Z1ck5tFkb41wReZP@bogus>

On Mon, Dec 09, 2024 at 12:59:58PM +0000, Etienne CARRIERE - foss wrote:
> Hello Sudeep,
> 
>  On Monday, December 9, 2024 11:46 AM, Sudeep Holla wrote: 
> > On Tue, Dec 03, 2024 at 06:39:08PM +0100, Etienne Carriere wrote:
> > > Implement clock round_rate operation for SCMI clocks that describe a
> > > discrete rates list. Bisect into the supported rates when using SCMI
> > > message CLOCK_DESCRIBE_RATES to optimize SCMI communication transfers.
> > 
> > Let me stop here and try to understand the requirement here. So you do
> > communicate with the firmware to arrive at this round_rate ? Does the
> > list of discreet clock rates changes at the run-time that enables the
> > need for it. Or will the initial list just include max and min ?
> 
> I don't expect the list to change at run-time. The initial list is
> expected to describe all supported rates. But because this list may
> be big, I don't think arm_scmi/clock.c driver should store the full list
> of all supported rates for each of the SCMI clocks. It would cost to
> much memory. Therefore I propose to query it at runtime, when
> needed, and bisect to lower the number of required transactions
> between the agent and the firmware.
>

Ah so, this is nothing to do with set_parent, but just an optimisation.
This change optimises for space but some other platform may have all the
space but the communication with SCMI platform is not good enough to make
runtime calls like this change. How do we cater that then ?

We need some spec-ed way or a unique way to identify what is best for
the platform IMO. We can change the way you have done in this change set
as someone else may complain in the future that it is costly to send
such command every time a clock needs to be set. I am just guessing here
may not be true.

> > 
> > > Parse the rate list array when the target rate fit in the bounds
> > > of the command response for simplicity.
> > >
> > 
> > I don't understand what you mean by this.
> 
> I meant here that we bisect into supported rates when communicating
> with the firmware but once the firmware response provides list portion
> when target rate fits into, we just scan into that array instead of bisecting
> into. We could also bisect into that array but it is likely quite small
> (<128 byte in existing SCMI transport drivers) and that would add a bit
> more code for no much gain IMHO.
> 
> 
> > 
> > > If so some reason the sequence fails or if the SCMI driver has no
> > > round_rate SCMI clock handler, then fallback to the legacy strategy that
> > > returned the target rate value.
> > >
> > 
> > Hmm, so we perform some extra dance but we are okay to fallback to default.
> > I am more confused.
> 
> Here, I propose to preserve the exiting sequence in clk/clk-scmi.c in case
> arm_scmi/clock.c does not implement this new round_rate SCMI clock 
> operation (it can be the case if these 2 drivers are .ko modules, not
> well known built-in drivers).
>

I don't think it would work if it is not built on the same kernel anyways.
I don't work much about this use-case.

> > 
> > > Operation handle scmi_clk_determine_rate() is change to get the effective
> > > supported rounded rate when there is no clock re-parenting operation
> > > supported. Otherwise, preserve the implementation that assumed any
> > > clock rate could be obtained.
> > >
> > 
> > OK, no I think I am getting some idea. Is this case where the parent has
> > changed and the describe rates can give a different result at run-time.
> 
> This does not deal with whether parent has changed or not. I would expect
> the same request sent multiple times to provide the very same result. But
> as I said above, I don't think arm_scmi/clock.c should consume a possibly
> large array of memory to store all supported rate each of the SCMI clocks
> (that describe discrete rates).
>

Right, my assumption was totally wrong. Thanks for confirming.

> An alternate way could be to add an SCMI Clock protocol command in the
> spec allowing agent to query a closest supported rate, in 1 shot. Maybe
> this new command could return both rounded rate and the SCMI parent
> clock needed to reach that rounded rate, better fitting clk_determine_rate()
> expectations.
>

May be that would be ideal but you need to make a case for such a spec change.

> > 
> > I need to re-read the part of the spec, but we may need some clarity so
> > that this implementation is not vendor specific. I am yet to understand this
> > fully. I just need to make sure spec covers this aspect and anything we
> > add here is generic solution.
> > 
> > I would like to avoid this extra query if not required which you seem to
> > have made an attempt but I just want to be thorough and make sure that's
> > what we need w.r.t the specification.
> 
> Sure, I indeed prefer clear and robust implementation in the long term,
> being the one I propose here or another one.
> 

Good then, we can work towards achieving that. If you can specify how slow
or memory hungry is it without these changes and how much this change helps
your platform, we can take it up with spec authors and see if they are happy
to provide some alternative to deal with this in a generic way.

--
Regards,
Sudeep


From cl at gentwo.org  Mon Dec  9 09:05:04 2024
From: cl at gentwo.org (Christoph Lameter (Ampere))
Date: Mon, 9 Dec 2024 09:05:04 -0800 (PST)
Subject: [PATCH v3 1/2] arm64: refactor the rodata=xxx
In-Reply-To: <20241209072020.4743-2-shijie@os.amperecomputing.com>
References: <20241209072020.4743-1-shijie@os.amperecomputing.com> <20241209072020.4743-2-shijie@os.amperecomputing.com>
Message-ID: <83d01335-c6be-d17b-511a-378ce3ad0663@gentwo.org>

On Mon, 9 Dec 2024, Huang Shijie wrote:

> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -5901,7 +5901,7 @@
>  	rodata=		[KNL,EARLY]
>  		on	Mark read-only kernel memory as read-only (default).
>  		off	Leave read-only kernel memory writable for debugging.
> -		full	Mark read-only kernel memory and aliases as read-only
> +		noalias	Use more block mappings,may have better performance.
>  		        [arm64]

Maybe use
		noalias Do not check aliases in order to allow larger kernel page
                        sizes on a platforms without FEAT_BBM2 support[arm64])

instead?

>
>  	rockchip.usb_uart
> diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
> index ba269a7a3201..b3063326b79a 100644
> --- a/arch/arm64/include/asm/setup.h
> +++ b/arch/arm64/include/asm/setup.h
> @@ -13,6 +13,27 @@
>  extern phys_addr_t __fdt_pointer __initdata;
>  extern u64 __cacheline_aligned boot_args[4];
>
> +/*
> + * rodata=on (default):
> + *    Apply read-only attributes of VM areas to the linear alias of
> + *    the backing pages as well. This prevents code or read-only data
> + *    from being modified (inadvertently or intentionally) via another
> + *    mapping of the same memory page.
> + *
> + *    This requires the linear region to be mapped down to pages,
> + *    which may adversely affect performance in some cases.
> + *
> + * rodata=off:
> + *    It provides us more block mappings and contiguous hits
> + *    to map the linear region which minimize the TLB footprint.
> + *    Leave read-only kernel memory writable for debugging.
> + *
> + * rodata=noalias:
> + *    It provides us more block mappings and contiguous hits
> + *    to map the linear region which minimize the TLB footprint.
> + *    And the linear aliases of pages belonging to read-only mappings
> + *    in vmalloc region are also marked as read-only.
> + */
>  static inline bool arch_parse_debug_rodata(char *arg)
>  {
>  	extern bool rodata_enabled;
> @@ -21,7 +42,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
>  	if (!arg)
>  		return false;
>
> -	if (!strcmp(arg, "full")) {
> +	if (!strcmp(arg, "on")) {
>  		rodata_enabled = rodata_full = true;
>  		return true;
>  	}
> @@ -31,7 +52,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
>  		return true;
>  	}
>
> -	if (!strcmp(arg, "on")) {
> +	if (!strcmp(arg, "noalias")) {
>  		rodata_enabled = true;
>  		rodata_full = false;
>  		return true;
>


From ciprianmarian.costea at oss.nxp.com  Mon Dec  9 09:17:42 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Marian Costea)
Date: Mon, 9 Dec 2024 19:17:42 +0200
Subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <94cba886-86cb-41f1-96ee-501623add7db@app.fastmail.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
 <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
 <2005af5d-bdb7-4675-8f0e-82cb817801af@app.fastmail.com>
 <6f4a0be8-4def-4066-9b44-d43059b7a90d@oss.nxp.com>
 <94cba886-86cb-41f1-96ee-501623add7db@app.fastmail.com>
Message-ID: <42d39f8e-0b59-4185-af1f-f778522608d2@oss.nxp.com>

On 12/6/2024 2:41 PM, Arnd Bergmann wrote:
> [You don't often get email from arnd at arndb.de. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> On Fri, Dec 6, 2024, at 13:05, Ciprian Marian Costea wrote:
>> On 12/6/2024 10:04 AM, Arnd Bergmann wrote:
>>>
>>> However, the range of the register value is only 32 bits,
>>> which means there is no need to ever divide it by a 64-bit
>>> number, and with the 32kHz clock in the binding example,
>>> you only have about 37 hours worth of range here.
>>>
>>
>> I am not sure what is the suggestion here. To cast 'cycles' variable to
>> 32-bit ?
>> If yes, indeed 'div_u64' converts 'cycles' (the divisor) to 32-bit so I
>> agree it should be u32 instead of u64.
>> If not, I would prefer to keep using a 64-by-32 division and avoid
>> casting 'hz' to 32-bit.
> 
> The confusing bit here is that the extra function just serves to
> the dividend 'cycles' from 32-bit to 64-bit, and then calling
> div_u64() implicitly casts the dividend 'hz' from 64-bit to
> 32-bit, so you definitely get a 32-by-32 division already
> if the function is inlined properly.
> 
> I think storing 'rtc_hz' as a u32 variable and adding a range
> check when filling it would help, mainly to save the next reader
> from having to understand what is going on.
> 

The confusion on my end is that I cannot see where 'div_u64() implicitly 
casts the dividend 'hz' from 64-bit to 32-bit' by following the method's 
implementation [1]

But I agree that 'rtc_hz' can be stored into a 32-bit variable with a 
range check added when it is taken from the Linux clock API to avoid any
unneeded abstractions.

[1] 
https://elixir.bootlin.com/linux/v6.12.4/source/include/linux/math64.h#L127

>>> It would appear that this makes the rtc unsuitable for
>>> storing absolute time across reboots, and only serve during
>>> runtime, which is a limitation you should probably document.
>>>
>>
>> Actually there is the option to use DIV512 and/or DIV32 hardware
>> divisors for the RTC clock. The driver uses a DIV512 divisor by default
>> in order to achieve higher RTC count ranges (by achieving a smaller RTC
>> freq). Therefore, the 37 hours become 37 * 512 => ~ 2 years.
> 
> Ah, makes sense. Can you add comments in an appropriate place in
> the code about this?
> 

Sure. I will add such comment in the S32G RTC driver in V7.

>> However, the rtc limitation of not being persistent during reboot
>> remains, due to hardware RTC module registers present of NXP S32G2/S32G3
>> SoCs being reset during system reboot. On the other hand, during system
>> suspend, the RTC module will keep counting if a clock source is available.
>>
>> Currently, this limittion is documented as follows:
>> "RTC tracks clock time during system suspend. It can be a wakeup source
>> for the S32G2/S32G3 SoC based boards.
>>
>> The RTC module from S32G2/S32G3 is not battery-powered and it is not
>> kept alive during system reset."
> 
> My bad, I really should not have skipped the patch
> description ;-)
> 
>>> If 'counter' wraps every 37 hours, this will inevitably fail,
>>> right? E.g. if priv->base.cycles was already at a large
>>> 32-bit number, even reading it shortly later will produce
>>> a small value after the wraparound.
>>>
>>> Using something like time_before() should address this,
>>> but I think you may need a custom version that works on
>>> 32-bit numbers.
>>>
>>
>> This is correct. Would the following change be acceptable ?
>>
>> -       if (counter < priv->base.cycles)
>> -               return -EINVAL;
>> -
>> -       counter -= priv->base.cycles;
>> +       if (counter < priv->base.cycles) {
>> +               /* A rollover on RTCCTN has occurred */
>> +               counter += RTCCNT_MAX_VAL - priv->base.cycles;
>> +               priv->base.cycles = 0;
>> +       } else {
>> +               counter -= priv->base.cycles;
>> +       }
> 
> This is the same as just removing the error handling and
> relying on unsigned integer overflow semantics.
> 
> The usual check we do in time_before()/time_after instead
> checks if the elapsed time is less than half the available
> range:
> 
> #define time_after(a,b)         \
>          (typecheck(unsigned long, a) && \
>           typecheck(unsigned long, b) && \
>           ((long)((b) - (a)) < 0))
> 

Ok. Thanks for the suggestion. I will look into using 
'time_before()/time_after()' API instead of directly checking via 
comparison operators.

>>>> +static int s32g_rtc_resume(struct device *dev)
>>>> +{
>>>> +     struct rtc_priv *priv = dev_get_drvdata(dev);
>>>> +     int ret;
>>>> +
>>>> +     if (!device_may_wakeup(dev))
>>>> +             return 0;
>>>> +
>>>> +     /* Disable wake-up interrupts */
>>>> +     s32g_enable_api_irq(dev, 0);
>>>> +
>>>> +     ret = rtc_clk_src_setup(priv);
>>>> +     if (ret)
>>>> +             return ret;
>>>> +
>>>> +     /*
>>>> +      * Now RTCCNT has just been reset, and is out of sync with priv->base;
>>>> +      * reapply the saved time settings.
>>>> +      */
>>>> +     return s32g_rtc_set_time(dev, &priv->base.tm);
>>>> +}
>>>
>>> This also fails if the system has been suspended for more than
>>> 37 hours, right?
>>
>> Actually, the system would not go into suspend (returning with error) if
>> the alarm setting passes the 32-bit / clk_freq range.
>> The check is added in 'sec_to_rtcval' which is called from the suspend
>> routine.
> 
> Who sets that alarm though? Are you relying on custom userspace
> for this, or is that something that the kernel already does
> that I'm missing?
> 
>         Arnd

The test usage is via 'rtcwake' [2] userspace tool.
I've detailed a bit the testing scenario in the cover letter for this 
patchset [3]:

"
Following is an example of Suspend to RAM trigger on S32G2/S32G3 SoCs,
using userspace tools such as rtcwake:
# rtcwake -s 2 -m mem
# rtcwake: assuming RTC uses UTC ...
# rtcwake: wakeup from "mem" using /dev/rtc0 at Wed Feb  6 06:28:36 2036
#
"

[2] https://man7.org/linux/man-pages/man8/rtcwake.8.html
[3] 
https://lore.kernel.org/all/20241206070955.1503412-1-ciprianmarian.costea at oss.nxp.com/

Best Regards,
Ciprian



From maz at kernel.org  Mon Dec  9 09:30:10 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Dec 2024 17:30:10 +0000
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer expired
In-Reply-To: <bcb4289b-507c-4ea1-afc7-6febd34d88db@redhat.com>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
	<867c89tc4q.wl-maz@kernel.org>
	<c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
	<865xntt2kv.wl-maz@kernel.org>
	<8be59ff3-6a68-48e1-8181-0ce4b2e7180f@os.amperecomputing.com>
	<bcb4289b-507c-4ea1-afc7-6febd34d88db@redhat.com>
Message-ID: <86y10osr19.wl-maz@kernel.org>

On Mon, 09 Dec 2024 16:46:30 +0000,
Eric Auger <eauger at redhat.com> wrote:
> 
> Hi,
> 
> On 12/9/24 16:39, Ganapatrao Kulkarni wrote:
> > 
> > 
> > On 09-12-2024 06:50 pm, Marc Zyngier wrote:
> >> On Mon, 09 Dec 2024 12:25:34 +0000,
> >> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> >>>>>
> >>>>> During automated testing of Nested Virtualization using avocado-vt,
> >>>>
> >>>> Which is not merged upstream. So what branch are you using? Based on
> >>>> what kernel version? On what HW? With which virtualisation features?
> >>>>
> >>>
> >>> Testing is done on Ampere's AmpereOne platform using 6.10 based kernel
> >>> with NV patches from your repo.
> >>
> >> Grmbl... *Which* patches? At least give me the SHA1 of the branch,
> >> because I have no idea what you are running. And 6.10 is definitely
> >> not something I care about. If you're using the NV patches, the
> >> *minimum* you should run is 6.13-rc1, because that's what the current
> >> code is based on.
> >>
> > 
> > I tried 6.13-rc1 based nv-next branch today, which failed to boot
> > UEFI as L1. Yet to debug this.
> 
> I confirm am stuck with the same issue with nv-next on AmpereOne.

All I can say is that it Works For Me (TM) on M2 and Snapdragon, using
kvmtool, a fresh EDK2 built by Ard, and with the guest running purely
VHE (FEAT_E2H0 not implemented).

I haven't tried QEMU, I don't have an AmpereOne. I have also spent way
too much time on this recently. So I'm afraid people interested in
making this particular combination work will have to debug it.

	M.

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


From xur at google.com  Mon Dec  9 09:30:50 2024
From: xur at google.com (Rong Xu)
Date: Mon, 9 Dec 2024 09:30:50 -0800
Subject: [PATCH v2] arm64: Allow CONFIG_AUTOFDO_CLANG to be selected
In-Reply-To: <20241209162028.GD12428@willie-the-truck>
References: <20241118222540.27495-1-yabinc@google.com> <20241209162028.GD12428@willie-the-truck>
Message-ID: <CAF1bQ=SiHi8oCyo5YnXGpQGofM1zAsnBdqSEet1mS-BYNKVU8A@mail.gmail.com>

Enabling an AutoFDO build requires users to explicitly set CONFIG_AUTOFDO_CLANG.
The support code is in Commit 315ad8780a129e82 (kbuild: Add AutoFDO
support for Clang build).

The CONFIG_AUTOFDO_CLANG config, even if selected by the user, will
not be enabled
unless ARCH_SUPPORTS_AUTOFDO_CLANG is present.

We are not enabling this for all architectures because AutoFDO's optimized build
relies on Last Branch Records (LBR) which aren't available on all architectures.

-Rong


On Mon, Dec 9, 2024 at 8:20?AM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Nov 18, 2024 at 02:25:40PM -0800, Yabin Cui wrote:
> > Select ARCH_SUPPORTS_AUTOFDO_CLANG to allow AUTOFDO_CLANG to be
> > selected.
> >
> > On ARM64, ETM traces can be recorded and converted to AutoFDO profiles.
> > Experiments on Android show 4% improvement in cold app startup time
> > and 13% improvement in binder benchmarks.
> >
> > Signed-off-by: Yabin Cui <yabinc at google.com>
> > ---
> >
> > Change-Logs in V2:
> >
> > 1. Use "For ARM platforms with ETM trace" in autofdo.rst.
> > 2. Create an issue and a change to use extbinary format in instructions:
> >    https://github.com/Linaro/OpenCSD/issues/65
> >    https://android-review.googlesource.com/c/platform/system/extras/+/3362107
> >
> >  Documentation/dev-tools/autofdo.rst | 18 +++++++++++++++++-
> >  arch/arm64/Kconfig                  |  1 +
> >  2 files changed, 18 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/dev-tools/autofdo.rst b/Documentation/dev-tools/autofdo.rst
> > index 1f0a451e9ccd..a890e84a2fdd 100644
> > --- a/Documentation/dev-tools/autofdo.rst
> > +++ b/Documentation/dev-tools/autofdo.rst
> > @@ -55,7 +55,7 @@ process consists of the following steps:
> >     workload to gather execution frequency data. This data is
> >     collected using hardware sampling, via perf. AutoFDO is most
> >     effective on platforms supporting advanced PMU features like
> > -   LBR on Intel machines.
> > +   LBR on Intel machines, ETM traces on ARM machines.
> >
> >  #. AutoFDO profile generation: Perf output file is converted to
> >     the AutoFDO profile via offline tools.
> > @@ -141,6 +141,22 @@ Here is an example workflow for AutoFDO kernel:
> >
> >        $ perf record --pfm-events RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a -N -b -c <count> -o <perf_file> -- <loadtest>
> >
> > +   - For ARM platforms with ETM trace:
> > +
> > +     Follow the instructions in the `Linaro OpenCSD document
> > +     https://github.com/Linaro/OpenCSD/blob/master/decoder/tests/auto-fdo/autofdo.md`_
> > +     to record ETM traces for AutoFDO::
> > +
> > +      $ perf record -e cs_etm/@tmc_etr0/k -a -o <etm_perf_file> -- <loadtest>
> > +      $ perf inject -i <etm_perf_file> -o <perf_file> --itrace=i500009il
> > +
> > +     For ARM platforms running Android, follow the instructions in the
> > +     `Android simpleperf document
> > +     <https://android.googlesource.com/platform/system/extras/+/main/simpleperf/doc/collect_etm_data_for_autofdo.md>`_
> > +     to record ETM traces for AutoFDO::
> > +
> > +      $ simpleperf record -e cs-etm:k -a -o <perf_file> -- <loadtest>
> > +
> >  4) (Optional) Download the raw perf file to the host machine.
> >
> >  5) To generate an AutoFDO profile, two offline tools are available:
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index fd9df6dcc593..c3814df5e391 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -103,6 +103,7 @@ config ARM64
> >       select ARCH_SUPPORTS_PER_VMA_LOCK
> >       select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
> >       select ARCH_SUPPORTS_RT
> > +     select ARCH_SUPPORTS_AUTOFDO_CLANG
> >       select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
> >       select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
> >       select ARCH_WANT_DEFAULT_BPF_JIT
>
> After this change, both arm64 and x86 select this option unconditionally
> and with no apparent support code being added. So what is actually
> required in order to select ARCH_SUPPORTS_AUTOFDO_CLANG and why isn't
> it just available for all architectures instead?
>
> Will


From eauger at redhat.com  Mon Dec  9 09:34:18 2024
From: eauger at redhat.com (Eric Auger)
Date: Mon, 9 Dec 2024 18:34:18 +0100
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer
 expired
In-Reply-To: <86y10osr19.wl-maz@kernel.org>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
 <867c89tc4q.wl-maz@kernel.org>
 <c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
 <865xntt2kv.wl-maz@kernel.org>
 <8be59ff3-6a68-48e1-8181-0ce4b2e7180f@os.amperecomputing.com>
 <bcb4289b-507c-4ea1-afc7-6febd34d88db@redhat.com>
 <86y10osr19.wl-maz@kernel.org>
Message-ID: <4d443db1-85b1-4071-acd5-3187deb9cb17@redhat.com>

Hi Marc,

On 12/9/24 18:30, Marc Zyngier wrote:
> On Mon, 09 Dec 2024 16:46:30 +0000,
> Eric Auger <eauger at redhat.com> wrote:
>>
>> Hi,
>>
>> On 12/9/24 16:39, Ganapatrao Kulkarni wrote:
>>>
>>>
>>> On 09-12-2024 06:50 pm, Marc Zyngier wrote:
>>>> On Mon, 09 Dec 2024 12:25:34 +0000,
>>>> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
>>>>>>>
>>>>>>> During automated testing of Nested Virtualization using avocado-vt,
>>>>>>
>>>>>> Which is not merged upstream. So what branch are you using? Based on
>>>>>> what kernel version? On what HW? With which virtualisation features?
>>>>>>
>>>>>
>>>>> Testing is done on Ampere's AmpereOne platform using 6.10 based kernel
>>>>> with NV patches from your repo.
>>>>
>>>> Grmbl... *Which* patches? At least give me the SHA1 of the branch,
>>>> because I have no idea what you are running. And 6.10 is definitely
>>>> not something I care about. If you're using the NV patches, the
>>>> *minimum* you should run is 6.13-rc1, because that's what the current
>>>> code is based on.
>>>>
>>>
>>> I tried 6.13-rc1 based nv-next branch today, which failed to boot
>>> UEFI as L1. Yet to debug this.
>>
>> I confirm am stuck with the same issue with nv-next on AmpereOne.
> 
> All I can say is that it Works For Me (TM) on M2 and Snapdragon, using
> kvmtool, a fresh EDK2 built by Ard, and with the guest running purely
> VHE (FEAT_E2H0 not implemented).
> 
> I haven't tried QEMU, I don't have an AmpereOne. I have also spent way
> too much time on this recently. So I'm afraid people interested in
> making this particular combination work will have to debug it.

yes I do agree. I am currently setting up kvmtool to double check and I
will debug the qemu issue.

Thanks

Eric
> 
> 	M.
> 



From alexandre.torgue at foss.st.com  Mon Dec  9 09:40:23 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Mon, 9 Dec 2024 18:40:23 +0100
Subject: [PATCH] ARM: dts: stm32: Sort M24256E write-lockable page in DH
 STM32MP13xx DHCOR SoM DT
In-Reply-To: <20241105234106.162610-1-marex@denx.de>
References: <20241105234106.162610-1-marex@denx.de>
Message-ID: <b7152e15-105a-4a49-860f-b408cd5c3349@foss.st.com>



On 11/6/24 00:40, Marek Vasut wrote:
> Move the M24256E write-lockable page subnode after RTC subnode in
> DH STM32MP13xx DHCOR SoM DT to keep the list of nodes sorted by I2C
> address. No functional change.
> 
> Fixes: 3f2e7d167307 ("ARM: dts: stm32: Describe M24256E write-lockable page in DH STM32MP13xx DHCOR SoM DT")
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzk+dt at kernel.org>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Rob Herring <robh at kernel.org>
> Cc: devicetree at vger.kernel.org
> Cc: kernel at dh-electronics.com
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> ---
>   arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi | 12 ++++++------
>   1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi b/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi
> index 5edbc790d1d27..a181d5a816f69 100644
> --- a/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi
> +++ b/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi
> @@ -201,17 +201,17 @@ eeprom0: eeprom at 50 {
>   		pagesize = <64>;
>   	};
>   
> -	eeprom0wl: eeprom at 58 {
> -		compatible = "st,24256e-wl";	/* ST M24256E WL page of 0x50 */
> -		pagesize = <64>;
> -		reg = <0x58>;
> -	};
> -
>   	rv3032: rtc at 51 {
>   		compatible = "microcrystal,rv3032";
>   		reg = <0x51>;
>   		interrupts-extended = <&gpioi 0 IRQ_TYPE_EDGE_FALLING>;
>   	};
> +
> +	eeprom0wl: eeprom at 58 {
> +		compatible = "st,24256e-wl";	/* ST M24256E WL page of 0x50 */
> +		pagesize = <64>;
> +		reg = <0x58>;
> +	};
>   };
>   
>   &iwdg2 {


Applied on stm32-next.

Cheers
Alex


From alexandre.torgue at foss.st.com  Mon Dec  9 09:39:30 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Mon, 9 Dec 2024 18:39:30 +0100
Subject: [PATCH] ARM: dts: stm32: Deduplicate serial aliases and chosen
 node for STM32MP15xx DHCOM SoM
In-Reply-To: <20241105233026.161463-1-marex@denx.de>
References: <20241105233026.161463-1-marex@denx.de>
Message-ID: <4a5ce71f-bdb1-473d-8fea-9c07389b47ca@foss.st.com>

Hi Marek

On 11/6/24 00:29, Marek Vasut wrote:
> Deduplicate /aliases { serialN = ... } and /chosen node into
> stm32mp15xx-dhcom-som.dtsi , since the content is identical
> on all carrier boards using the STM32MP15xx DHCOM SoM. No
> functional change.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzk+dt at kernel.org>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Rob Herring <robh at kernel.org>
> Cc: devicetree at vger.kernel.org
> Cc: kernel at dh-electronics.com
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> ---
>   arch/arm/boot/dts/st/stm32mp15xx-dhcom-drc02.dtsi   | 12 ------------
>   arch/arm/boot/dts/st/stm32mp15xx-dhcom-pdk2.dtsi    | 10 ----------
>   arch/arm/boot/dts/st/stm32mp15xx-dhcom-picoitx.dtsi | 10 ----------
>   arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi     |  7 +++++++
>   4 files changed, 7 insertions(+), 32 deletions(-)
> 

Applied on stm32-next.

Thanks!

Alex


From alexandre.torgue at foss.st.com  Mon Dec  9 09:41:02 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Mon, 9 Dec 2024 18:41:02 +0100
Subject: [PATCH] ARM: dts: stm32: Increase CPU core voltage on STM32MP13xx
 DHCOR SoM
In-Reply-To: <20241105224728.147384-1-marex@denx.de>
References: <20241105224728.147384-1-marex@denx.de>
Message-ID: <7b0b43c8-0396-4a61-b8fc-6bb277f3a63b@foss.st.com>

Hi Marek

On 11/5/24 23:46, Marek Vasut wrote:
> The STM32MP13xx DHCOR DHSBC is populated with STM32MP13xx part capable
> of 1 GHz operation, increase the CPU core voltage to 1.35 V to make
> sure the SoC is stable even if the blobs unconditionally force the CPU
> to 1 GHz operation.
> 
> It is not possible to make use of CPUfreq on the STM32MP13xx because
> the SCMI protocol 0x13 is not implemented by upstream OpTee-OS which
> is the SCMI provider.
> 
> Fixes: 6331bddce649 ("ARM: dts: stm32: Add support for STM32MP13xx DHCOR SoM and DHSBC board")
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzk+dt at kernel.org>
> Cc: Marek Vasut <marex at denx.de>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Rob Herring <robh at kernel.org>
> Cc: devicetree at vger.kernel.org
> Cc: kernel at dh-electronics.com
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> ---
>   arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi b/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi
> index 07133bd82efa6..8630de147a52b 100644
> --- a/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi
> +++ b/arch/arm/boot/dts/st/stm32mp13xx-dhcor-som.dtsi
> @@ -85,8 +85,8 @@ regulators {
>   
>   			vddcpu: buck1 { /* VDD_CPU_1V2 */
>   				regulator-name = "vddcpu";
> -				regulator-min-microvolt = <1250000>;
> -				regulator-max-microvolt = <1250000>;
> +				regulator-min-microvolt = <1350000>;
> +				regulator-max-microvolt = <1350000>;
>   				regulator-always-on;
>   				regulator-initial-mode = <0>;
>   				regulator-over-current-protection;


Applied on stm32-next.

Thanks!!
Alex


From dianders at chromium.org  Mon Dec  9 09:43:15 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Mon,  9 Dec 2024 09:43:15 -0800
Subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the spectre_bhb_k24_list
In-Reply-To: <20241209174430.2904353-1-dianders@chromium.org>
References: <20241209174430.2904353-1-dianders@chromium.org>
Message-ID: <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>

Qualcomm Kryo 500-series Gold cores appear to have a derivative of an
ARM Cortex A77 in them. Since A77 needs Spectre mitigation then the
Kyro 500-series Gold cores also should need Spectre mitigation.

Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
Yes. I know. This patch DOESN'T COMPILE because
MIDR_QCOM_KRYO_5XX_GOLD is not defined. That value needs to come from
Qualcomm or from testing on hardware, which I don't have. Qualcomm
needs to chime in to confirm that this Spectre mitigation is correct
anyway, though. I'm including this patch so it's obvious that I think
these cores also need the mitigation.

 arch/arm64/kernel/proton-pack.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index b1881964e304..212481726f04 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -867,6 +867,7 @@ u8 spectre_bhb_loop_affected(int scope)
 			MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
 			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
 			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
+			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
 			{},
 		};
 		static const struct midr_range spectre_bhb_k11_list[] = {
-- 
2.47.0.338.g60cca15819-goog



From dianders at chromium.org  Mon Dec  9 09:43:16 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Mon,  9 Dec 2024 09:43:16 -0800
Subject: [PATCH 6/6] arm64: errata: Add QCOM_KRYO_6XX_GOLD/PRIME to the spectre_bhb_k32_list
In-Reply-To: <20241209174430.2904353-1-dianders@chromium.org>
References: <20241209174430.2904353-1-dianders@chromium.org>
Message-ID: <20241209094310.6.I722621804be859e4ae4b7479ce191c5e3367b37c@changeid>

Qualcomm Kryo 600-series Gold cores appear to have a derivative of an
ARM Cortex A78 / ARM Cortex X1 in them. Since these need Spectre
mitigation then the Kyro 600-series Gold/Prime cores also should need
Spectre mitigation.

Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
Yes. I know. This patch DOESN'T COMPILE because
MIDR_QCOM_KRYO_6XX_GOLD and MIDR_QCOM_KRYO_6XX_PRIME are not
defined. Those value needs to come from Qualcomm or from testing on
hardware, which I don't have. Qualcomm needs to chime in to confirm
that this Spectre mitigation is correct anyway, though. I'm including
this patch so it's obvious that I think these cores also need the
mitigation.

 arch/arm64/kernel/proton-pack.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 212481726f04..67aa54017dea 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -860,6 +860,8 @@ u8 spectre_bhb_loop_affected(int scope)
 			MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
 			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
 			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
+			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_GOLD),
+			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_PRIME),
 			{},
 		};
 		static const struct midr_range spectre_bhb_k24_list[] = {
-- 
2.47.0.338.g60cca15819-goog



From Frank.Li at nxp.com  Mon Dec  9 09:48:13 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 12:48:13 -0500
Subject: [PATCH v11 0/7] PCI: EP: Add RC-to-EP doorbell with platform MSI
 controller
Message-ID: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>

??????????????   ?????????????????????????????????????   ??????????????????
?            ?   ?                                   ?   ?                ?
?            ?   ? PCI Endpoint                      ?   ? PCI Host       ?
?            ?   ?                                   ?   ?                ?
?            ????? 1.platform_msi_domain_alloc_irqs()?   ?                ?
?            ?   ?                                   ?   ?                ?
? MSI        ????? 2.write_msi_msg()                 ??????BAR<n>         ?
? Controller ?   ?   update doorbell register address?   ?                ?
?            ?   ?   for BAR                         ?   ?                ?
?            ?   ?                                   ?   ? 3. Write BAR<n>?
?            ?????????????????????????????????????????????                ?
?            ?   ?                                   ?   ?                ?
?            ????? 4.Irq Handle                      ?   ?                ?
?            ?   ?                                   ?   ?                ?
?            ?   ?                                   ?   ?                ?
??????????????   ?????????????????????????????????????   ??????????????????

This patches based on old https://lore.kernel.org/imx/20221124055036.1630573-1-Frank.Li at nxp.com/

Original patch only target to vntb driver. But actually it is common
method.

This patches add new API to pci-epf-core, so any EP driver can use it.

Previous v2 discussion here.
https://lore.kernel.org/imx/20230911220920.1817033-1-Frank.Li at nxp.com/

Changes in v11:
- Change to use MSI_FLAG_MSG_IMMUTABLE
- Link to v10: https://lore.kernel.org/r/20241204-ep-msi-v10-0-87c378dbcd6d at nxp.com

Changes in v10:

Thomas Gleixner:
	There are big change in pci-ep-msi.c. I am sure if go on the
corrent path. The key improvement is remove only 1 function devices's
limitation.

	I use new patch for imutable check, which relative additional
feature compared to base enablement patch.

- Remove patch Add msi_remove_device_irq_domain() in platform_device_msi_free_irqs_all()
- Add new patch irqchip/gic-v3-its: Avoid overwriting msi_prepare callback if provided by msi_domain_info
- Remove only support 1 endpoint function limiation.
- Create one MSI domain for each endpoint function devices.
- Use "msi-map" in pci ep controler node, instead of of msi-parent. first
argument is
	(func_no << 8 | vfunc_no)

- Link to v9: https://lore.kernel.org/r/20241203-ep-msi-v9-0-a60dbc3f15dd at nxp.com

Changes in v9
- Add patch platform-msi: Add msi_remove_device_irq_domain() in platform_device_msi_free_irqs_all()
- Remove patch PCI: endpoint: Add pci_epc_get_fn() API for customizable filtering
- Remove API pci_epf_align_inbound_addr_lo_hi
- Move doorbell_alloc in to doorbell_enable function.
- Link to v8: https://lore.kernel.org/r/20241116-ep-msi-v8-0-6f1f68ffd1bb at nxp.com

Changes in v8:
- update helper function name to pci_epf_align_inbound_addr()
- Link to v7: https://lore.kernel.org/r/20241114-ep-msi-v7-0-d4ac7aafbd2c at nxp.com

Changes in v7:
- Add helper function pci_epf_align_addr();
- Link to v6: https://lore.kernel.org/r/20241112-ep-msi-v6-0-45f9722e3c2a at nxp.com

Changes in v6:
- change doorbell_addr to doorbell_offset
- use round_down()
- add Niklas's test by tag
- rebase to pci/endpoint
- Link to v5: https://lore.kernel.org/r/20241108-ep-msi-v5-0-a14951c0d007 at nxp.com

Changes in v5:
- Move request_irq to epf test function driver for more flexiable user case
- Add fixed size bar handler
- Some minor improvememtn to see each patches's changelog.
- Link to v4: https://lore.kernel.org/r/20241031-ep-msi-v4-0-717da2d99b28 at nxp.com

Changes in v4:
- Remove patch genirq/msi: Add cleanup guard define for msi_lock_descs()/msi_unlock_descs()
- Use new method to avoid compatible problem.
  Add new command DOORBELL_ENABLE and DOORBELL_DISABLE.
  pcitest -B send DOORBELL_ENABLE first, EP test function driver try to
remap one of BAR_N (except test register bar) to ITS MSI MMIO space. Old
driver don't support new command, so failure return, not side effect.
  After test, DOORBELL_DISABLE command send out to recover original map, so
pcitest bar test can pass as normal.
- Other detail change see each patches's change log
- Link to v3: https://lore.kernel.org/r/20241015-ep-msi-v3-0-cedc89a16c1a at nxp.com

Change from v2 to v3
- Fixed manivannan's comments
- Move common part to pci-ep-msi.c and pci-ep-msi.h
- rebase to 6.12-rc1
- use RevID to distingiush old version

mkdir /sys/kernel/config/pci_ep/functions/pci_epf_test/func1
echo 16 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/msi_interrupts
echo 0x080c > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/deviceid
echo 0x1957 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/vendorid
echo 1 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/revid
^^^^^^ to enable platform msi support.
ln -s /sys/kernel/config/pci_ep/functions/pci_epf_test/func1 /sys/kernel/config/pci_ep/controllers/4c380000.pcie-ep

- use new device ID, which identify support doorbell to avoid broken
compatility.

    Enable doorbell support only for PCI_DEVICE_ID_IMX8_DB, while other devices
    keep the same behavior as before.

           EP side             RC with old driver      RC with new driver
    PCI_DEVICE_ID_IMX8_DB          no probe              doorbell enabled
    Other device ID             doorbell disabled*       doorbell disabled*

    * Behavior remains unchanged.

Change from v1 to v2
- Add missed patch for endpont/pci-epf-test.c
- Move alloc and free to epc driver from epf.
- Provide general help function for EPC driver to alloc platform msi irq.
- Fixed manivannan's comments.

To: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
To: Krzysztof Wilczy?ski <kw at linux.com>
To: Kishon Vijay Abraham I <kishon at kernel.org>
To: Bjorn Helgaas <bhelgaas at google.com>
To: Arnd Bergmann <arnd at arndb.de>
To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: linux-kernel at vger.kernel.org
Cc: linux-pci at vger.kernel.org
Cc: imx at lists.linux.dev
Cc: Niklas Cassel <cassel at kernel.org>
Cc: dlemoal at kernel.org
Cc: jdmason at kudzu.us
To: Rafael J. Wysocki <rafael at kernel.org>
To: Thomas Gleixner <tglx at linutronix.de>
To: Anup Patel <apatel at ventanamicro.com>
To: Kishon Vijay Abraham I <kishon at kernel.org>
To: Marc Zyngier <maz at kernel.org>
To: Thomas Gleixner <tglx at linutronix.de>
Cc: linux-arm-kernel at lists.infradead.org

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Frank Li (7):
      irqchip/gic-v3-its: Avoid overwriting msi_prepare callback if provided by msi_domain_info
      PCI: endpoint: Add RC-to-EP doorbell support using platform MSI controller
      PCI: endpoint: pci-ep-msi: Add MSI address/data pair mutable check
      PCI: endpoint: Add pci_epf_align_inbound_addr() helper for address alignment
      PCI: endpoint: pci-epf-test: Add doorbell test support
      misc: pci_endpoint_test: Add doorbell test case
      tools: PCI: Add 'B' option for test doorbell

 drivers/irqchip/irq-gic-v3-its-msi-parent.c   |   4 +-
 drivers/misc/pci_endpoint_test.c              |  80 +++++++++++++
 drivers/pci/endpoint/Makefile                 |   2 +-
 drivers/pci/endpoint/functions/pci-epf-test.c | 132 ++++++++++++++++++++++
 drivers/pci/endpoint/pci-ep-msi.c             | 156 ++++++++++++++++++++++++++
 drivers/pci/endpoint/pci-epf-core.c           |  44 ++++++++
 include/linux/msi.h                           |   2 +
 include/linux/pci-ep-msi.h                    |  15 +++
 include/linux/pci-epf.h                       |  19 ++++
 include/uapi/linux/pcitest.h                  |   1 +
 tools/pci/pcitest.c                           |  16 ++-
 11 files changed, 468 insertions(+), 3 deletions(-)
---
base-commit: b66d92bfe0a9e86a622e77a12e420b69af633d1d
change-id: 20241010-ep-msi-8b4cab33b1be

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Mon Dec  9 09:48:14 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 12:48:14 -0500
Subject: [PATCH v11 1/7] irqchip/gic-v3-its: Avoid overwriting msi_prepare
 callback if provided by msi_domain_info
In-Reply-To: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
Message-ID: <20241209-ep-msi-v11-1-7434fa8397bd@nxp.com>

  ?????????????????????????????????    ?????????
  ?                               ?    ?       ?
  ? PCI Endpoint Controller (1)   ?????? ITS   ?
  ?                               ?    ?       ?
  ?????????????????????????????????    ?????????
      ?        ?
      ?        ?
  ????????  ????????
  ?      ?  ?      ?
  ?Func1 ?  ?Func2 ?
  ? (2)  ?  ?      ?
  ????????  ????????
     ?         ?
     ?         ?
     ?????????????????????????? PCIe Bus

(1) is platform device, which is generally descripted by Device Tree(DT).
(2) Func1 and Func2 is created by configfs

The current platform MSI API supports only a single device. For instance,
a platform device (e.g., PCI Endpoint Controller) calls
platform_device_msi_init_and_alloc_irqs() to allocate MSI IRQs.

Child devices (e.g., function devices created by configfs) require
individual MSI domains, with the same MSI parent domain as the parent
device. These individual domains need specialized msi_prepare callbacks to
set  msi_alloc_info_t. However, the current ITS implementation overwrites
the msi_prepare callback with its_pmsi_prepare().

Modify the implementation to assign its_pmsi_prepare() only if
msi_domain_info::msi_prepare is NULL, allowing customized callbacks where
needed.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v11
- new patch
---
 drivers/irqchip/irq-gic-v3-its-msi-parent.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
index 75aa0d4bd1346..33e94cfc4d506 100644
--- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
@@ -195,7 +195,8 @@ static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 		 * FIXME: See the above PCI prepare comment. The domain
 		 * size is also known at domain creation time.
 		 */
-		info->ops->msi_prepare = its_pmsi_prepare;
+		if (!info->ops->msi_prepare)
+			info->ops->msi_prepare = its_pmsi_prepare;
 		break;
 	default:
 		/* Confused. How did the lib return true? */

-- 
2.34.1



From Frank.Li at nxp.com  Mon Dec  9 09:48:15 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 12:48:15 -0500
Subject: [PATCH v11 2/7] PCI: endpoint: Add RC-to-EP doorbell support using
 platform MSI controller
In-Reply-To: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
Message-ID: <20241209-ep-msi-v11-2-7434fa8397bd@nxp.com>

Doorbell feature is implemented by mapping the EP's MSI interrupt
controller message address to a dedicated BAR in the EPC core. It is the
responsibility of the EPF driver to pass the actual message data to be
written by the host to the doorbell BAR region through its own logic.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v10 to v11
- none

Change from v9 to v10
- Create msi domain for each function device.
- Remove only function support limiation. My hardware only support one
function, so not test more than one case.
- use "msi-map" descript msi information

  msi-map = <func_no << 8  | vfunc_no, &its, start_stream_id,  size>;

Chagne from v8 to v9
- sort header file
- use pci_epc_get(dev_name(msi_desc_to_dev(desc)));
- check epf number at pci_epf_alloc_doorbell
- Add comments for miss msi-parent case

change from v5 to v8
-none

Change from v4 to v5
- Remove request_irq() in pci_epc_alloc_doorbell() and leave to EP function
driver, so ep function driver can register differece call back function for
difference doorbell events and set irq affinity to differece CPU core.
- Improve error message when MSI allocate failure.

Change from v3 to v4
- msi change to use msi_get_virq() avoid use msi_for_each_desc().
- add new struct for pci_epf_doorbell_msg to msi msg,virq and irq name.
- move mutex lock to epc function
- initialize variable at declear place.
- passdown epf to epc*() function to simplify code.
---
 drivers/pci/endpoint/Makefile     |   2 +-
 drivers/pci/endpoint/pci-ep-msi.c | 148 ++++++++++++++++++++++++++++++++++++++
 include/linux/pci-ep-msi.h        |  15 ++++
 include/linux/pci-epf.h           |  16 +++++
 4 files changed, 180 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/endpoint/Makefile b/drivers/pci/endpoint/Makefile
index 95b2fe47e3b06..a1ccce440c2c5 100644
--- a/drivers/pci/endpoint/Makefile
+++ b/drivers/pci/endpoint/Makefile
@@ -5,4 +5,4 @@
 
 obj-$(CONFIG_PCI_ENDPOINT_CONFIGFS)	+= pci-ep-cfs.o
 obj-$(CONFIG_PCI_ENDPOINT)		+= pci-epc-core.o pci-epf-core.o\
-					   pci-epc-mem.o functions/
+					   pci-epc-mem.o pci-ep-msi.o functions/
diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
new file mode 100644
index 0000000000000..b0a91fde202f3
--- /dev/null
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCI Endpoint *Controller* (EPC) MSI library
+ *
+ * Copyright (C) 2024 NXP
+ * Author: Frank Li <Frank.Li at nxp.com>
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/pci-epc.h>
+#include <linux/pci-epf.h>
+#include <linux/pci-ep-cfs.h>
+#include <linux/pci-ep-msi.h>
+#include <linux/slab.h>
+
+static void pci_epf_write_msi_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	struct msi_desc *desc = irq_data_get_msi_desc(d);
+	struct pci_epf *epf = to_pci_epf(desc->dev);
+
+	if (epf && epf->db_msg && desc->msi_index < epf->num_db)
+		memcpy(&epf->db_msg[desc->msi_index].msg, msg, sizeof(*msg));
+}
+
+static void pci_epf_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+	arg->desc = desc;
+	arg->hwirq = desc->msi_index;
+}
+
+static int pci_epf_msi_prepare(struct irq_domain *domain, struct device *dev,
+			       int nvec, msi_alloc_info_t *arg)
+{
+	struct pci_epf *epf = to_pci_epf(dev);
+	struct msi_domain_info *msi_info;
+	struct pci_epc *epc = epf->epc;
+
+	memset(arg, 0, sizeof(*arg));
+	arg->scratchpad[0].ul = of_msi_map_id(epc->dev.parent, NULL,
+					      (epf->func_no << 8) | epf->vfunc_no);
+
+	/*
+	 * @domain->msi_domain_info->hwsize contains the size of the device
+	 * domain, but vector allocation happens one by one.
+	 */
+	msi_info = msi_get_domain_info(domain);
+	if (msi_info->hwsize > nvec)
+		nvec = msi_info->hwsize;
+
+	/* Allocate at least 32 MSIs, and always as a power of 2 */
+	nvec = max_t(int, 32, roundup_pow_of_two(nvec));
+
+	msi_info = msi_get_domain_info(domain->parent);
+	return msi_info->ops->msi_prepare(domain->parent, dev, nvec, arg);
+}
+
+static const struct msi_domain_template pci_epf_msi_template = {
+	.chip = {
+		.name			= "EP-MSI",
+		.irq_mask		= irq_chip_mask_parent,
+		.irq_unmask		= irq_chip_unmask_parent,
+		.irq_write_msi_msg	= pci_epf_write_msi_msg,
+		/* The rest is filled in by the MSI parent */
+	},
+
+	.ops = {
+		.msi_prepare		= pci_epf_msi_prepare,
+		.set_desc		= pci_epf_msi_set_desc,
+	},
+
+	.info = {
+		.bus_token		= DOMAIN_BUS_DEVICE_MSI,
+	},
+};
+
+static int pci_epf_device_msi_init_and_alloc_irqs(struct device *dev, unsigned int nvec)
+{
+	struct irq_domain *domain = dev->msi.domain;
+
+	if (!domain)
+		return -EINVAL;
+
+	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN,
+					  &pci_epf_msi_template, nvec, NULL, NULL))
+		return -ENODEV;
+
+	return msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, nvec - 1);
+}
+
+int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
+{
+	struct pci_epc *epc = epf->epc;
+	struct device *dev = &epf->dev;
+	struct irq_domain *dom;
+	void *msg;
+	u32 rid;
+	int ret;
+	int i;
+
+	rid = (epf->func_no << 8) | epf->vfunc_no;
+	dom = of_msi_map_get_device_domain(epc->dev.parent, rid, DOMAIN_BUS_PLATFORM_MSI);
+	if (!dom) {
+		dev_err(dev, "Can't find msi domain\n");
+		return -EINVAL;
+	}
+
+	dev_set_msi_domain(dev, dom);
+
+	msg = kcalloc(num_db, sizeof(struct pci_epf_doorbell_msg), GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	epf->num_db = num_db;
+	epf->db_msg = msg;
+
+	ret = pci_epf_device_msi_init_and_alloc_irqs(dev, num_db);
+	if (ret) {
+		/*
+		 * The pcie_ep DT node has to specify 'msi-parent' for EP
+		 * doorbell support to work. Right now only GIC ITS is
+		 * supported. If you have GIC ITS and reached this print,
+		 * perhaps you are missing 'msi-map' in DT.
+		 */
+		dev_err(dev, "Failed to allocate MSI\n");
+		kfree(msg);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < num_db; i++)
+		epf->db_msg[i].virq = msi_get_virq(dev, i);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epf_alloc_doorbell);
+
+void pci_epf_free_doorbell(struct pci_epf *epf)
+{
+	msi_domain_free_irqs_all(&epf->dev, MSI_DEFAULT_DOMAIN);
+	msi_remove_device_irq_domain(&epf->dev, MSI_DEFAULT_DOMAIN);
+
+	kfree(epf->db_msg);
+	epf->db_msg = NULL;
+	epf->num_db = 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_free_doorbell);
diff --git a/include/linux/pci-ep-msi.h b/include/linux/pci-ep-msi.h
new file mode 100644
index 0000000000000..f0cfecf491199
--- /dev/null
+++ b/include/linux/pci-ep-msi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PCI Endpoint *Function* side MSI header file
+ *
+ * Copyright (C) 2024 NXP
+ * Author: Frank Li <Frank.Li at nxp.com>
+ */
+
+#ifndef __PCI_EP_MSI__
+#define __PCI_EP_MSI__
+
+int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 nums);
+void pci_epf_free_doorbell(struct pci_epf *epf);
+
+#endif /* __PCI_EP_MSI__ */
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 18a3aeb62ae4e..5374e6515ffa0 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -12,6 +12,7 @@
 #include <linux/configfs.h>
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <linux/msi.h>
 #include <linux/pci.h>
 
 struct pci_epf;
@@ -125,6 +126,17 @@ struct pci_epf_bar {
 	int		flags;
 };
 
+/**
+ * struct pci_epf_doorbell_msg - represents doorbell message
+ * @msi_msg: MSI message
+ * @virq: irq number of this doorbell MSI message
+ * @name: irq name for doorbell interrupt
+ */
+struct pci_epf_doorbell_msg {
+	struct msi_msg msg;
+	int virq;
+};
+
 /**
  * struct pci_epf - represents the PCI EPF device
  * @dev: the PCI EPF device
@@ -152,6 +164,8 @@ struct pci_epf_bar {
  * @vfunction_num_map: bitmap to manage virtual function number
  * @pci_vepf: list of virtual endpoint functions associated with this function
  * @event_ops: Callbacks for capturing the EPC events
+ * @db_msg: data for MSI from RC side
+ * @num_db: number of doorbells
  */
 struct pci_epf {
 	struct device		dev;
@@ -182,6 +196,8 @@ struct pci_epf {
 	unsigned long		vfunction_num_map;
 	struct list_head	pci_vepf;
 	const struct pci_epc_event_ops *event_ops;
+	struct pci_epf_doorbell_msg *db_msg;
+	u16 num_db;
 };
 
 /**

-- 
2.34.1



From Frank.Li at nxp.com  Mon Dec  9 09:48:16 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 12:48:16 -0500
Subject: [PATCH v11 3/7] PCI: endpoint: pci-ep-msi: Add MSI address/data
 pair mutable check
In-Reply-To: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
Message-ID: <20241209-ep-msi-v11-3-7434fa8397bd@nxp.com>

Some MSI controller change address/data pair when irq_set_affinity().
Current PCI endpoint can't support this type MSI controller. So add flag
MSI_FLAG_MSG_IMMUTABLE in include/linux/msi.h, set this flags in ARM GIC
ITS MSI controller and check it when allocate doorbell.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v11
- new patch
---
 drivers/irqchip/irq-gic-v3-its-msi-parent.c | 1 +
 drivers/pci/endpoint/pci-ep-msi.c           | 8 ++++++++
 include/linux/msi.h                         | 2 ++
 3 files changed, 11 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
index 33e94cfc4d506..a34e9bf93f991 100644
--- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
@@ -16,6 +16,7 @@
 
 #define ITS_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK |	\
 				 MSI_FLAG_PCI_MSIX      |	\
+				 MSI_FLAG_MSG_IMMUTABLE |	\
 				 MSI_FLAG_MULTI_PCI_MSI)
 
 #ifdef CONFIG_PCI_MSI
diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
index b0a91fde202f3..1c157e0a81456 100644
--- a/drivers/pci/endpoint/pci-ep-msi.c
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -107,6 +107,14 @@ int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
 		return -EINVAL;
 	}
 
+	if (!dom->msi_parent_ops)
+		return -EINVAL;
+
+	if (!(dom->msi_parent_ops->supported_flags & MSI_FLAG_MSG_IMMUTABLE)) {
+		dev_err(dev, "Can't support mutable address/data pair MSI controller\n");
+		return -EINVAL;
+	}
+
 	dev_set_msi_domain(dev, dom);
 
 	msg = kcalloc(num_db, sizeof(struct pci_epf_doorbell_msg), GFP_KERNEL);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index b10093c4d00ea..d95d979e4747a 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -556,6 +556,8 @@ enum {
 	MSI_FLAG_PCI_MSIX_ALLOC_DYN	= (1 << 20),
 	/* PCI MSIs cannot be steered separately to CPU cores */
 	MSI_FLAG_NO_AFFINITY		= (1 << 21),
+	/* Address and data pair is mutable when irq_set_affinity() */
+	MSI_FLAG_MSG_IMMUTABLE		= (1 << 22),
 };
 
 /**

-- 
2.34.1



From Frank.Li at nxp.com  Mon Dec  9 09:48:17 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 12:48:17 -0500
Subject: [PATCH v11 4/7] PCI: endpoint: Add pci_epf_align_inbound_addr()
 helper for address alignment
In-Reply-To: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
Message-ID: <20241209-ep-msi-v11-4-7434fa8397bd@nxp.com>

Introduce the helper function pci_epf_align_inbound_addr() to adjust
addresses according to PCI BAR alignment requirements, converting addresses
into base and offset values.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change form v9 to v11
- none

change from v8 to v9
- pci_epf_align_inbound_addr(), base and off must be not NULL
- rm pci_epf_align_inbound_addr_lo_hi()

change from v7 to v8
- change name to pci_epf_align_inbound_addr()
- update comment said only need for memory, which not allocated by
pci_epf_alloc_space().

change from v6 to v7
- new patch
---
 drivers/pci/endpoint/pci-epf-core.c | 44 +++++++++++++++++++++++++++++++++++++
 include/linux/pci-epf.h             |  3 +++
 2 files changed, 47 insertions(+)

diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 8fa2797d4169a..d7a80f9c1e661 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -464,6 +464,50 @@ struct pci_epf *pci_epf_create(const char *name)
 }
 EXPORT_SYMBOL_GPL(pci_epf_create);
 
+/**
+ * pci_epf_align_inbound_addr() - Get base address and offset that match BAR's
+ *			  alignment requirement
+ * @epf: the EPF device
+ * @addr: the address of the memory
+ * @bar: the BAR number corresponding to map addr
+ * @base: return base address, which match BAR's alignment requirement.
+ * @off: return offset.
+ *
+ * Helper function to convert input 'addr' to base and offset, which match
+ * BAR's alignment requirement.
+ *
+ * The pci_epf_alloc_space() function already accounts for alignment. This is
+ * primarily intended for use with other memory regions not allocated by
+ * pci_epf_alloc_space(), such as peripheral register spaces or the trigger
+ * address for a platform MSI controller.
+ */
+int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
+			       u64 addr, u64 *base, size_t *off)
+{
+	const struct pci_epc_features *epc_features;
+	u64 align;
+
+	if (!base || !off)
+		return -EINVAL;
+
+	epc_features = pci_epc_get_features(epf->epc, epf->func_no, epf->vfunc_no);
+	if (!epc_features) {
+		dev_err(&epf->dev, "epc_features not implemented\n");
+		return -EOPNOTSUPP;
+	}
+
+	align = epc_features->align;
+	align = align ? align : 128;
+	if (epc_features->bar[bar].type == BAR_FIXED)
+		align = max(epc_features->bar[bar].fixed_size, align);
+
+	*base = round_down(addr, align);
+	*off = addr & (align - 1);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_align_inbound_addr);
+
 static void pci_epf_dev_release(struct device *dev)
 {
 	struct pci_epf *epf = to_pci_epf(dev);
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 5374e6515ffa0..2847d195433bf 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -238,6 +238,9 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
 			  enum pci_epc_interface_type type);
 void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
 			enum pci_epc_interface_type type);
+
+int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
+			       u64 addr, u64 *base, size_t *off);
 int pci_epf_bind(struct pci_epf *epf);
 void pci_epf_unbind(struct pci_epf *epf);
 int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);

-- 
2.34.1



From Frank.Li at nxp.com  Mon Dec  9 09:48:18 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 12:48:18 -0500
Subject: [PATCH v11 5/7] PCI: endpoint: pci-epf-test: Add doorbell test
 support
In-Reply-To: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
Message-ID: <20241209-ep-msi-v11-5-7434fa8397bd@nxp.com>

Add three registers: doorbell_bar, doorbell_addr, and doorbell_data. Use
pci_epf_alloc_doorbell() to allocate a doorbell address space.

Enable the Root Complex (RC) side driver to trigger pci-epc-test's doorbell
callback handler by writing doorbell_data to the mapped doorbell_bar's
address space.

Set STATUS_DOORBELL_SUCCESS in the doorbell callback to indicate
completion.

Avoid breaking compatibility between host and endpoint, add new command
COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL. Host side need send
COMMAND_ENABLE_DOORBELL to map one bar's inbound address to MSI space.
the command COMMAND_DISABLE_DOORBELL to recovery original inbound address
mapping.

	 	Host side new driver	Host side old driver

EP: new driver      S				F
EP: old driver      F				F

S: If EP side support MSI, 'pcitest -B' return success.
   If EP side doesn't support MSI, the same to 'F'.

F: 'pcitest -B' return failure, other case as usual.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v11
- none

Change from v8 to v9
- move pci_epf_alloc_doorbell() into pci_epf_{enable/disable}_doorbell().
- remove doorbell_done in commit message.
- rename pci_epf_{enable/disable}_doorbell() to
pci_epf_test_{enable/disable}_doorbell() to align corrent code style.

Change from v7 to v8
- rename to pci_epf_align_inbound_addr_lo_hi()

Change from v6 to v7
- use help function pci_epf_align_addr_lo_hi()

Change from v5 to v6
- rename doorbell_addr to doorbell_offset

Chagne from v4 to v5
- Add doorbell free at unbind function.
- Move msi irq handler to here to more complex user case, such as differece
doorbell can use difference handler function.
- Add Niklas's code to handle fixed bar's case. If need add your signed-off
tag or co-developer tag, please let me know.

change from v3 to v4
- remove revid requirement
- Add command COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL.
- call pci_epc_set_bar() to map inbound address to MSI space only at
COMMAND_ENABLE_DOORBELL.
---
 drivers/pci/endpoint/functions/pci-epf-test.c | 132 ++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index ef6677f34116e..a0a0e86a081cb 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -11,12 +11,14 @@
 #include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/msi.h>
 #include <linux/slab.h>
 #include <linux/pci_ids.h>
 #include <linux/random.h>
 
 #include <linux/pci-epc.h>
 #include <linux/pci-epf.h>
+#include <linux/pci-ep-msi.h>
 #include <linux/pci_regs.h>
 
 #define IRQ_TYPE_INTX			0
@@ -29,6 +31,8 @@
 #define COMMAND_READ			BIT(3)
 #define COMMAND_WRITE			BIT(4)
 #define COMMAND_COPY			BIT(5)
+#define COMMAND_ENABLE_DOORBELL		BIT(6)
+#define COMMAND_DISABLE_DOORBELL	BIT(7)
 
 #define STATUS_READ_SUCCESS		BIT(0)
 #define STATUS_READ_FAIL		BIT(1)
@@ -39,6 +43,11 @@
 #define STATUS_IRQ_RAISED		BIT(6)
 #define STATUS_SRC_ADDR_INVALID		BIT(7)
 #define STATUS_DST_ADDR_INVALID		BIT(8)
+#define STATUS_DOORBELL_SUCCESS		BIT(9)
+#define STATUS_DOORBELL_ENABLE_SUCCESS	BIT(10)
+#define STATUS_DOORBELL_ENABLE_FAIL	BIT(11)
+#define STATUS_DOORBELL_DISABLE_SUCCESS BIT(12)
+#define STATUS_DOORBELL_DISABLE_FAIL	BIT(13)
 
 #define FLAG_USE_DMA			BIT(0)
 
@@ -74,6 +83,9 @@ struct pci_epf_test_reg {
 	u32	irq_type;
 	u32	irq_number;
 	u32	flags;
+	u32	doorbell_bar;
+	u32	doorbell_offset;
+	u32	doorbell_data;
 } __packed;
 
 static struct pci_epf_header test_header = {
@@ -642,6 +654,117 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test,
 	}
 }
 
+static irqreturn_t pci_epf_test_doorbell_handler(int irq, void *data)
+{
+	struct pci_epf_test *epf_test = data;
+	enum pci_barno test_reg_bar = epf_test->test_reg_bar;
+	struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
+
+	reg->status |= STATUS_DOORBELL_SUCCESS;
+	pci_epf_test_raise_irq(epf_test, reg);
+
+	return IRQ_HANDLED;
+}
+
+static void pci_epf_test_doorbell_cleanup(struct pci_epf_test *epf_test)
+{
+	struct pci_epf_test_reg *reg = epf_test->reg[epf_test->test_reg_bar];
+	struct pci_epf *epf = epf_test->epf;
+
+	if (reg->doorbell_bar > 0) {
+		free_irq(epf->db_msg[0].virq, epf_test);
+		reg->doorbell_bar = NO_BAR;
+	}
+
+	if (epf->db_msg)
+		pci_epf_free_doorbell(epf);
+}
+
+static void pci_epf_test_enable_doorbell(struct pci_epf_test *epf_test,
+					 struct pci_epf_test_reg *reg)
+{
+	struct pci_epf *epf = epf_test->epf;
+	struct pci_epf_bar db_bar = {};
+	struct pci_epc *epc = epf->epc;
+	struct msi_msg *msg;
+	enum pci_barno bar;
+	size_t offset;
+	int ret;
+
+	ret = pci_epf_alloc_doorbell(epf, 1);
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		return;
+	}
+
+	msg = &epf->db_msg[0].msg;
+	bar = pci_epc_get_next_free_bar(epf_test->epc_features, epf_test->test_reg_bar + 1);
+	if (bar < BAR_0 || bar == epf_test->test_reg_bar || !epf->db_msg) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		return;
+	}
+
+	ret = request_irq(epf->db_msg[0].virq, pci_epf_test_doorbell_handler, 0,
+			  "pci-test-doorbell", epf_test);
+	if (ret) {
+		dev_err(&epf->dev,
+			"Failed to request irq %d, doorbell feature is not supported\n",
+			epf->db_msg[0].virq);
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+		return;
+	}
+
+	reg->doorbell_data = msg->data;
+	reg->doorbell_bar = bar;
+
+	msg = &epf->db_msg[0].msg;
+	ret = pci_epf_align_inbound_addr(epf, bar, ((u64)msg->address_hi << 32) | msg->address_lo,
+					 &db_bar.phys_addr, &offset);
+
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+		return;
+	}
+
+	reg->doorbell_offset = offset;
+
+	db_bar.barno = bar;
+	db_bar.size = epf->bar[bar].size;
+	db_bar.flags = epf->bar[bar].flags;
+
+	ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &db_bar);
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+	} else {
+		reg->status |= STATUS_DOORBELL_ENABLE_SUCCESS;
+	}
+}
+
+static void pci_epf_test_disable_doorbell(struct pci_epf_test *epf_test,
+					  struct pci_epf_test_reg *reg)
+{
+	enum pci_barno bar = reg->doorbell_bar;
+	struct pci_epf *epf = epf_test->epf;
+	struct pci_epc *epc = epf->epc;
+	int ret;
+
+	if (bar < BAR_0 || bar == epf_test->test_reg_bar || !epf->db_msg) {
+		reg->status |= STATUS_DOORBELL_DISABLE_FAIL;
+		return;
+	}
+
+	ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &epf->bar[bar]);
+	if (ret)
+		reg->status |= STATUS_DOORBELL_DISABLE_FAIL;
+	else
+		reg->status |= STATUS_DOORBELL_DISABLE_SUCCESS;
+
+	pci_epf_test_doorbell_cleanup(epf_test);
+}
+
 static void pci_epf_test_cmd_handler(struct work_struct *work)
 {
 	u32 command;
@@ -688,6 +811,14 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 		pci_epf_test_copy(epf_test, reg);
 		pci_epf_test_raise_irq(epf_test, reg);
 		break;
+	case COMMAND_ENABLE_DOORBELL:
+		pci_epf_test_enable_doorbell(epf_test, reg);
+		pci_epf_test_raise_irq(epf_test, reg);
+		break;
+	case COMMAND_DISABLE_DOORBELL:
+		pci_epf_test_disable_doorbell(epf_test, reg);
+		pci_epf_test_raise_irq(epf_test, reg);
+		break;
 	default:
 		dev_err(dev, "Invalid command 0x%x\n", command);
 		break;
@@ -934,6 +1065,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
 		pci_epf_test_clean_dma_chan(epf_test);
 		pci_epf_test_clear_bar(epf);
 	}
+	pci_epf_test_doorbell_cleanup(epf_test);
 	pci_epf_test_free_space(epf);
 }
 

-- 
2.34.1



From Frank.Li at nxp.com  Mon Dec  9 09:48:19 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 12:48:19 -0500
Subject: [PATCH v11 6/7] misc: pci_endpoint_test: Add doorbell test case
In-Reply-To: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
Message-ID: <20241209-ep-msi-v11-6-7434fa8397bd@nxp.com>

Add three registers: PCIE_ENDPOINT_TEST_DB_BAR, PCIE_ENDPOINT_TEST_DB_ADDR,
and PCIE_ENDPOINT_TEST_DB_DATA.

Trigger the doorbell by writing data from PCI_ENDPOINT_TEST_DB_DATA to the
address provided by PCI_ENDPOINT_TEST_DB_OFFSET and wait for endpoint
feedback.

Add two command to COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL
to enable EP side's doorbell support and avoid compatible problem, which
host side driver miss-match with endpoint side function driver. See below
table:

		Host side new driver	Host side old driver
EP: new driver		S			F
EP: old driver		F			F

S: If EP side support MSI, 'pcitest -B' return success.
   If EP side doesn't support MSI, the same to 'F'.

F: 'pcitest -B' return failure, other case as usual.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v11
- none

Change from v8 to v9
- change PCITEST_DOORBELL to 0xa

Change form v6 to v8
- none

Change from v5 to v6
- %s/PCI_ENDPOINT_TEST_DB_ADDR/PCI_ENDPOINT_TEST_DB_OFFSET/g

Change from v4 to v5
- remove unused varible
- add irq_type at pci_endpoint_test_doorbell();

change from v3 to v4
- Add COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL.
- Remove new DID requirement.
---
 drivers/misc/pci_endpoint_test.c | 80 ++++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/pcitest.h     |  1 +
 2 files changed, 81 insertions(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 3aaaf47fa4ee2..b3f36b6ba8ba2 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -42,6 +42,8 @@
 #define COMMAND_READ				BIT(3)
 #define COMMAND_WRITE				BIT(4)
 #define COMMAND_COPY				BIT(5)
+#define COMMAND_ENABLE_DOORBELL			BIT(6)
+#define COMMAND_DISABLE_DOORBELL		BIT(7)
 
 #define PCI_ENDPOINT_TEST_STATUS		0x8
 #define STATUS_READ_SUCCESS			BIT(0)
@@ -53,6 +55,11 @@
 #define STATUS_IRQ_RAISED			BIT(6)
 #define STATUS_SRC_ADDR_INVALID			BIT(7)
 #define STATUS_DST_ADDR_INVALID			BIT(8)
+#define STATUS_DOORBELL_SUCCESS			BIT(9)
+#define STATUS_DOORBELL_ENABLE_SUCCESS		BIT(10)
+#define STATUS_DOORBELL_ENABLE_FAIL		BIT(11)
+#define STATUS_DOORBELL_DISABLE_SUCCESS		BIT(12)
+#define STATUS_DOORBELL_DISABLE_FAIL		BIT(13)
 
 #define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR	0x0c
 #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR	0x10
@@ -67,6 +74,10 @@
 #define PCI_ENDPOINT_TEST_IRQ_NUMBER		0x28
 
 #define PCI_ENDPOINT_TEST_FLAGS			0x2c
+#define PCI_ENDPOINT_TEST_DB_BAR		0x30
+#define PCI_ENDPOINT_TEST_DB_OFFSET		0x34
+#define PCI_ENDPOINT_TEST_DB_DATA		0x38
+
 #define FLAG_USE_DMA				BIT(0)
 
 #define PCI_DEVICE_ID_TI_AM654			0xb00c
@@ -108,6 +119,7 @@ enum pci_barno {
 	BAR_3,
 	BAR_4,
 	BAR_5,
+	NO_BAR = -1,
 };
 
 struct pci_endpoint_test {
@@ -746,6 +758,71 @@ static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
 	return false;
 }
 
+static bool pci_endpoint_test_doorbell(struct pci_endpoint_test *test)
+{
+	struct pci_dev *pdev = test->pdev;
+	struct device *dev = &pdev->dev;
+	int irq_type = test->irq_type;
+	enum pci_barno bar;
+	u32 data, status;
+	u32 addr;
+
+	if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
+		dev_err(dev, "Invalid IRQ type option\n");
+		return false;
+	}
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
+				 COMMAND_ENABLE_DOORBELL);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+	if (status & STATUS_DOORBELL_ENABLE_FAIL) {
+		dev_err(dev, "Failed to enable doorbell\n");
+		return false;
+	}
+
+	data = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_DATA);
+	addr = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_OFFSET);
+	bar = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_BAR);
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS, 0);
+
+	bar = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_BAR);
+
+	writel(data, test->bar[bar] + addr);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+
+	if (!(status & STATUS_DOORBELL_SUCCESS))
+		dev_err(dev, "Endpoint have not received Doorbell\n");
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
+				 COMMAND_DISABLE_DOORBELL);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status |= pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+
+	if (status & STATUS_DOORBELL_DISABLE_FAIL) {
+		dev_err(dev, "Failed to disable doorbell\n");
+		return false;
+	}
+
+	if (!(status & STATUS_DOORBELL_SUCCESS))
+		return false;
+
+	return true;
+}
+
 static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 				    unsigned long arg)
 {
@@ -793,6 +870,9 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 	case PCITEST_CLEAR_IRQ:
 		ret = pci_endpoint_test_clear_irq(test);
 		break;
+	case PCITEST_DOORBELL:
+		ret = pci_endpoint_test_doorbell(test);
+		break;
 	}
 
 ret:
diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h
index 94b46b043b536..b82e7f2ed937d 100644
--- a/include/uapi/linux/pcitest.h
+++ b/include/uapi/linux/pcitest.h
@@ -20,6 +20,7 @@
 #define PCITEST_MSIX		_IOW('P', 0x7, int)
 #define PCITEST_SET_IRQTYPE	_IOW('P', 0x8, int)
 #define PCITEST_GET_IRQTYPE	_IO('P', 0x9)
+#define PCITEST_DOORBELL	_IO('P', 0xa)
 #define PCITEST_CLEAR_IRQ	_IO('P', 0x10)
 
 #define PCITEST_FLAGS_USE_DMA	0x00000001

-- 
2.34.1



From Frank.Li at nxp.com  Mon Dec  9 09:48:20 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 12:48:20 -0500
Subject: [PATCH v11 7/7] tools: PCI: Add 'B' option for test doorbell
In-Reply-To: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
Message-ID: <20241209-ep-msi-v11-7-7434fa8397bd@nxp.com>

Add doorbell test support.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v3 to v11
- none
---
 tools/pci/pcitest.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 7b530d838d408..fcff0224a3381 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -34,6 +34,7 @@ struct pci_test {
 	bool		copy;
 	unsigned long	size;
 	bool		use_dma;
+	bool		doorbell;
 };
 
 static int run_test(struct pci_test *test)
@@ -147,6 +148,15 @@ static int run_test(struct pci_test *test)
 			fprintf(stdout, "%s\n", result[ret]);
 	}
 
+	if (test->doorbell) {
+		ret = ioctl(fd, PCITEST_DOORBELL, 0);
+		fprintf(stdout, "Ringing doorbell on the EP\t\t");
+		if (ret < 0)
+			fprintf(stdout, "TEST FAILED\n");
+		else
+			fprintf(stdout, "%s\n", result[ret]);
+	}
+
 	fflush(stdout);
 	close(fd);
 	return (ret < 0) ? ret : 1 - ret; /* return 0 if test succeeded */
@@ -172,7 +182,7 @@ int main(int argc, char **argv)
 	/* set default endpoint device */
 	test->device = "/dev/pci-endpoint-test.0";
 
-	while ((c = getopt(argc, argv, "D:b:m:x:i:deIlhrwcs:")) != EOF)
+	while ((c = getopt(argc, argv, "D:b:m:x:i:BdeIlhrwcs:")) != EOF)
 	switch (c) {
 	case 'D':
 		test->device = optarg;
@@ -222,6 +232,9 @@ int main(int argc, char **argv)
 	case 'd':
 		test->use_dma = true;
 		continue;
+	case 'B':
+		test->doorbell = true;
+		continue;
 	case 'h':
 	default:
 usage:
@@ -241,6 +254,7 @@ int main(int argc, char **argv)
 			"\t-w			Write buffer test\n"
 			"\t-c			Copy buffer test\n"
 			"\t-s <size>		Size of buffer {default: 100KB}\n"
+			"\t-B			Doorbell test\n"
 			"\t-h			Print this help message\n",
 			argv[0]);
 		return -EINVAL;

-- 
2.34.1



From andre.przywara at arm.com  Mon Dec  9 09:56:37 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 9 Dec 2024 17:56:37 +0000
Subject: [PATCH 1/3] ARM: dts: suniv: f1c100s: Add support for DMA
In-Reply-To: <20241205000137.187450-2-csokas.bence@prolan.hu>
References: <20241205000137.187450-1-csokas.bence@prolan.hu>
	<20241205000137.187450-2-csokas.bence@prolan.hu>
Message-ID: <20241209175637.283312fa@donnerap.manchester.arm.com>

On Thu, 5 Dec 2024 01:01:36 +0100
"Cs?k?s, Bence" <csokas.bence at prolan.hu> wrote:

> From: Mesih Kilinc <mesihkilinc at gmail.com>
> 
> Allwinner suniv F1C100s now has DMA support. Enable it under device
> tree.
> 
> Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>
> [ csokas.bence: Rebased on current master ]
> Signed-off-by: Cs?k?s, Bence <csokas.bence at prolan.hu>

Compared against the manual:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
> index 3c61d59ab5f8..290efe026ceb 100644
> --- a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
> +++ b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
> @@ -6,6 +6,7 @@
>  
>  #include <dt-bindings/clock/suniv-ccu-f1c100s.h>
>  #include <dt-bindings/reset/suniv-ccu-f1c100s.h>
> +#include <dt-bindings/dma/sun4i-a10.h>
>  
>  / {
>  	#address-cells = <1>;
> @@ -159,6 +160,15 @@ usbphy: phy at 1c13400 {
>  			status = "disabled";
>  		};
>  
> +		dma: dma-controller at 1c02000 {
> +			compatible = "allwinner,suniv-f1c100s-dma";
> +			reg = <0x01c02000 0x1000>;
> +			interrupts = <18>;
> +			clocks = <&ccu CLK_BUS_DMA>;
> +			resets = <&ccu RST_BUS_DMA>;
> +			#dma-cells = <2>;
> +		};
> +
>  		ccu: clock at 1c20000 {
>  			compatible = "allwinner,suniv-f1c100s-ccu";
>  			reg = <0x01c20000 0x400>;



From andre.przywara at arm.com  Mon Dec  9 09:56:54 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 9 Dec 2024 17:56:54 +0000
Subject: [PATCH 2/3] ARM: dts: suniv: f1c100s: Add support for Audio
 Codec
In-Reply-To: <20241205000137.187450-3-csokas.bence@prolan.hu>
References: <20241205000137.187450-1-csokas.bence@prolan.hu>
	<20241205000137.187450-3-csokas.bence@prolan.hu>
Message-ID: <20241209175654.673cf172@donnerap.manchester.arm.com>

On Thu, 5 Dec 2024 01:01:37 +0100
"Cs?k?s, Bence" <csokas.bence at prolan.hu> wrote:

> From: Mesih Kilinc <mesihkilinc at gmail.com>
> 
> Allwinner suniv F1C100s now has basic audio codec support. Enable it
> under device tree.
> 
> Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>
> [ csokas.bence: Rebased on current master ]
> Signed-off-by: Cs?k?s, Bence <csokas.bence at prolan.hu>

Compared against the F1C200s user manual:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
> index 290efe026ceb..e4b41bc93852 100644
> --- a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
> +++ b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
> @@ -336,5 +336,19 @@ uart2: serial at 1c25800 {
>  			resets = <&ccu RST_BUS_UART2>;
>  			status = "disabled";
>  		};
> +
> +		codec: codec at 1c23c00 {
> +			#sound-dai-cells = <0>;
> +			compatible = "allwinner,suniv-f1c100s-codec";
> +			reg = <0x01c23c00 0x400>;
> +			interrupts = <21>;
> +			clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_CODEC>;
> +			clock-names = "apb", "codec";
> +			dmas = <&dma SUN4I_DMA_NORMAL 12>,
> +			       <&dma SUN4I_DMA_NORMAL 12>;
> +			dma-names = "rx", "tx";
> +			resets = <&ccu RST_BUS_CODEC>;
> +			status = "disabled";
> +		};
>  	};
>  };



From dianders at chromium.org  Mon Dec  9 09:43:10 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Mon,  9 Dec 2024 09:43:10 -0800
Subject: [PATCH 0/6] arm64: errata: Add Qualcomm CPUs to the Spectre mitigation lists
Message-ID: <20241209174430.2904353-1-dianders@chromium.org>


Since Qualcomm CPUs are all derivatives of ARM cores they all have
unique MIDR values. This means that the tables listing necessary
Spectre mitigations need special entries for them. However, those
entries are not present and that means that some Spectre mitigations
are lacking for Qualcomm CPUs.

I've made an attempt at **GUESSING** what the right patches should be
to enable mitigations for Qualcomm CPUs. This is mostly me searching
the web to figure out what ARM cores various Qualcomm cores are based
off of.

These patches get more and more sketchy as the series progresses and I
have noted that the later patces DON'T EVEN COMPILE. I have included
them to make it obvious that I think these cores are affected even if
I don't have all the right information to mitigate them. Hopefully
Qualcomm can come and fix this mess for me.

I'll note that I am certainly no expert on Spectre. Mostly I ended up
here running `lscpu` on a device and noticing that it thought that it
wasn't affected by Spectre v2 when I thought it was.


Douglas Anderson (6):
  arm64: errata: Add QCOM_KRYO_4XX_GOLD to the spectre_bhb_k24_list
  arm64: errata: Add QCOM_KRYO_2XX_GOLD to the
    spectre_bhb_firmware_mitigated_list
  arm64: cputype: Add QCOM_CPU_PART_KRYO_3XX_GOLD
  arm64: errata: Add QCOM_KRYO_3XX_GOLD to the
    spectre_bhb_firmware_mitigated_list
  arm64: errata: Add QCOM_KRYO_5XX_GOLD to the spectre_bhb_k24_list
  arm64: errata: Add QCOM_KRYO_6XX_GOLD/PRIME to the
    spectre_bhb_k32_list

 arch/arm64/include/asm/cputype.h | 2 ++
 arch/arm64/kernel/proton-pack.c  | 6 ++++++
 2 files changed, 8 insertions(+)

-- 
2.47.0.338.g60cca15819-goog



From dianders at chromium.org  Mon Dec  9 09:43:11 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Mon,  9 Dec 2024 09:43:11 -0800
Subject: [PATCH 1/6] arm64: errata: Add QCOM_KRYO_4XX_GOLD to the spectre_bhb_k24_list
In-Reply-To: <20241209174430.2904353-1-dianders@chromium.org>
References: <20241209174430.2904353-1-dianders@chromium.org>
Message-ID: <20241209094310.1.Ie4ef54abe02e7eb0eee50f830575719bf23bda48@changeid>

Qualcomm Kryo 400-series Gold cores appear to have a derivative of an
ARM Cortex A76 in them. Since A76 needs Spectre mitigation then the
Kyro 400-series Gold cores also should need Spectre mitigation.

Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
The "k" value here really should come from analysis by Qualcomm, but
until we can get that analysis let's choose the same value as A76: 24.

Ideally someone from Qualcomm can confirm that this mitigation is
needed and confirm / provide the proper "k" value.

 arch/arm64/kernel/proton-pack.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index da53722f95d4..e149efadff20 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -866,6 +866,7 @@ u8 spectre_bhb_loop_affected(int scope)
 			MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
 			MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
 			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
 			{},
 		};
 		static const struct midr_range spectre_bhb_k11_list[] = {
-- 
2.47.0.338.g60cca15819-goog



From dianders at chromium.org  Mon Dec  9 09:43:12 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Mon,  9 Dec 2024 09:43:12 -0800
Subject: [PATCH 2/6] arm64: errata: Add QCOM_KRYO_2XX_GOLD to the spectre_bhb_firmware_mitigated_list
In-Reply-To: <20241209174430.2904353-1-dianders@chromium.org>
References: <20241209174430.2904353-1-dianders@chromium.org>
Message-ID: <20241209094310.2.Ia3dfc0afadbfbee81bb2efb0672262470973dd08@changeid>

Qualcomm Kryo 200-series Gold cores appear to have a derivative of an
ARM Cortex A73 in them. Since A73 needs Spectre mitigation then the
Kyro 200-series Gold cores also should need Spectre mitigation.

Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
I don't really have any good way to test this patch but it seems
likely it's needed. If nothing else the claim is that that Qualcomm
Kyro 280 CPU is vulnerable [1] but I don't see any mitigations in the
kernel for it.

NOTE: presumably this patch won't actually do much on its own because
(I believe) it requires a firmware update to go with it.

[1] https://spectreattack.com/spectre.pdf

 arch/arm64/kernel/proton-pack.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index e149efadff20..0437be7c83bc 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -925,6 +925,7 @@ static bool is_spectre_bhb_fw_affected(int scope)
 	static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
+		MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_GOLD),
 		{},
 	};
 	bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
-- 
2.47.0.338.g60cca15819-goog



From dianders at chromium.org  Mon Dec  9 09:43:13 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Mon,  9 Dec 2024 09:43:13 -0800
Subject: [PATCH 3/6] arm64: cputype: Add QCOM_CPU_PART_KRYO_3XX_GOLD
In-Reply-To: <20241209174430.2904353-1-dianders@chromium.org>
References: <20241209174430.2904353-1-dianders@chromium.org>
Message-ID: <20241209094310.3.I18e0288742871393228249a768e5d56ea65d93dc@changeid>

Add a definition for the Qualcomm Kryo 300-series Gold cores.

Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
I have no idea if this is actually right and no way to test it, but it
fits the pattern of the other definitions. Someone from Qualcomm ought
to confirm this.

 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 488f8e751349..c8058f91a5bd 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -119,6 +119,7 @@
 #define QCOM_CPU_PART_KRYO		0x200
 #define QCOM_CPU_PART_KRYO_2XX_GOLD	0x800
 #define QCOM_CPU_PART_KRYO_2XX_SILVER	0x801
+#define QCOM_CPU_PART_KRYO_3XX_GOLD	0x802
 #define QCOM_CPU_PART_KRYO_3XX_SILVER	0x803
 #define QCOM_CPU_PART_KRYO_4XX_GOLD	0x804
 #define QCOM_CPU_PART_KRYO_4XX_SILVER	0x805
@@ -195,6 +196,7 @@
 #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO)
 #define MIDR_QCOM_KRYO_2XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_GOLD)
 #define MIDR_QCOM_KRYO_2XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_SILVER)
+#define MIDR_QCOM_KRYO_3XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_GOLD)
 #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER)
 #define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD)
 #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
-- 
2.47.0.338.g60cca15819-goog



From dianders at chromium.org  Mon Dec  9 09:43:14 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Mon,  9 Dec 2024 09:43:14 -0800
Subject: [PATCH 4/6] arm64: errata: Add QCOM_KRYO_3XX_GOLD to the spectre_bhb_firmware_mitigated_list
In-Reply-To: <20241209174430.2904353-1-dianders@chromium.org>
References: <20241209174430.2904353-1-dianders@chromium.org>
Message-ID: <20241209094310.4.Ic6fdf0e43851269d10596da7e6ceae959431f9fa@changeid>

Qualcomm Kryo 300-series Gold cores appear to have a derivative of an
ARM Cortex A75 in them. Since A75 needs Spectre mitigation then the
Kyro 300-series Gold cores also should need Spectre mitigation.

Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
I have no idea if this is actually needed and this patch is purely
speculative. Given that A75 needs some sort of Spectre mitigation it
seem hard to believe that the Qualcomm Kryo 300-series Gold cores
wouldn't need it.

NOTE: presumably this patch won't actually do much on its own because
(I believe) it requires a firmware update to go with it.

 arch/arm64/kernel/proton-pack.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 0437be7c83bc..b1881964e304 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -926,6 +926,7 @@ static bool is_spectre_bhb_fw_affected(int scope)
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
 		MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_GOLD),
+		MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_GOLD),
 		{},
 	};
 	bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
-- 
2.47.0.338.g60cca15819-goog



From cristian.marussi at arm.com  Mon Dec  9 10:01:00 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 9 Dec 2024 18:01:00 +0000
Subject: [PATCH v2 1/2] firmware: arm_scmi: get only min/max clock rates
In-Reply-To: <22ff786d1e034169be21ef7dc32c4a3a@foss.st.com>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-2-etienne.carriere@foss.st.com>
 <Z1bHgf_4qqZgSnDt@bogus>
 <22ff786d1e034169be21ef7dc32c4a3a@foss.st.com>
Message-ID: <Z1cwTWQWamv3lywB@pluto>

On Mon, Dec 09, 2024 at 01:48:48PM +0000, Etienne CARRIERE - foss wrote:
> On Monday, December 9, 2024, Sudeep Holla wrote:
> > On Tue, Dec 03, 2024 at 06:39:07PM +0100, Etienne Carriere wrote:
> > > Remove limitation of 16 clock rates max for discrete clock rates
> > > description when the SCMI firmware supports SCMI Clock protocol v2.0
> > > or later.
> > >
> > > Driver clk-scmi.c is only interested in the min and max clock rates.
> > > Get these by querying the first and last discrete rates with SCMI
> > > clock protocol message ID CLOCK_DESCRIBE_RATES since the SCMI
> > > specification v2.0 and later states that rates enumerated by this
> > > command are to be enumerated in "numeric ascending order" [1].
> > >
> > > Preserve the implementation that queries all discrete rates (16 rates
> > > max) to support SCMI firmware built on SCMI specification v1.0 [2]
> > > where SCMI Clock protocol v1.0 does not explicitly require rates
> > > described with CLOCK_DESCRIBE_RATES to be in ascending order.
> > >
> > > Link: https://developer.arm.com/documentation/den0056 [1]
> > > Link: https://developer.arm.com/documentation/den0056/a [2]
> > > Signed-off-by: Etienne Carriere <etienne.carriere at foss.st.com>
> > > ---

Hi,

> > 
> > [...]
> > 
> > > +
> > > +static int scmi_clock_get_rates_bound(const struct scmi_protocol_handle *ph,
> > > +                                   u32 clk_id, struct scmi_clock_info *clk)
> > > +{
> > 
> > This new function seem to have unwraped the scmi_iterator_ops(namely
> > prepare_message, update_state and process_response instead of reusing them.
> > Can you please explain why it wasn't possible to reuse them ?
> 
> Since we're interested here only in min and max rates, let's query the
> first and last rates only. This can save a bit of useless transactions between
> agent and firmware in case there are many clocks with somewhat large
> the discrete rate lists.
> 
> I though using the iterator for this specific case would add a bit more
> complexity: it's expected to iterate (st->desc_index incremented from the
> common scmi_iterator_run() function) whereas here I propose to send
> only 2 messages.

Yes, indeed the core iterator helpers are meant to issue a 'full scan'
retrievieng all the resources that are returned while handling in a
common way the underlying machinery common to all messages that, like
DESCRIBE_RATES, could possibly return their results in chunks as a
multi-part reply...

...having said that I can certainly extend the iterators to be configurable
enough to fit this new usecase and retrieve only the desired part of the
'scan' so that can be used for this kind of max/min query or for the
bisection case.

I would avoid to re-introduce ad-hoc code to handle these new usecases
that do not fit into the existing iterator logic, since iterators
were introduced to remove duplication and unify under common
methods...and this new iterator scenario seems to me that has already 2
usecases and certainly more protocol could want to perform similar 'lazy
partial queries' in the future, so I'd prefer to address this in a more
general way upfront if possible...I will think about it and post something
next week in the form of some new iterator extensions, if it's fine for you.

Thanks,
Cristian


From wens at csie.org  Mon Dec  9 10:03:08 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 10 Dec 2024 02:03:08 +0800
Subject: [PATCH 1/3] ARM: dts: suniv: f1c100s: Add support for DMA
In-Reply-To: <20241209175637.283312fa@donnerap.manchester.arm.com>
References: <20241205000137.187450-1-csokas.bence@prolan.hu>
 <20241205000137.187450-2-csokas.bence@prolan.hu> <20241209175637.283312fa@donnerap.manchester.arm.com>
Message-ID: <CAGb2v644AgZvuOmvQCUXGWyJWYCgVnCkVohNdD-Z0FhgOrp1cQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 1:56?AM Andre Przywara <andre.przywara at arm.com> wrote:
>
> On Thu, 5 Dec 2024 01:01:36 +0100
> "Cs?k?s, Bence" <csokas.bence at prolan.hu> wrote:
>
> > From: Mesih Kilinc <mesihkilinc at gmail.com>
> >
> > Allwinner suniv F1C100s now has DMA support. Enable it under device
> > tree.
> >
> > Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>
> > [ csokas.bence: Rebased on current master ]
> > Signed-off-by: Cs?k?s, Bence <csokas.bence at prolan.hu>
>
> Compared against the manual:
>
> Reviewed-by: Andre Przywara <andre.przywara at arm.com>

These have already been merged. I picked them from their original
series.

ChenYu

> Cheers,
> Andre
>
> > ---
> >  arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
> > index 3c61d59ab5f8..290efe026ceb 100644
> > --- a/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
> > +++ b/arch/arm/boot/dts/allwinner/suniv-f1c100s.dtsi
> > @@ -6,6 +6,7 @@
> >
> >  #include <dt-bindings/clock/suniv-ccu-f1c100s.h>
> >  #include <dt-bindings/reset/suniv-ccu-f1c100s.h>
> > +#include <dt-bindings/dma/sun4i-a10.h>
> >
> >  / {
> >       #address-cells = <1>;
> > @@ -159,6 +160,15 @@ usbphy: phy at 1c13400 {
> >                       status = "disabled";
> >               };
> >
> > +             dma: dma-controller at 1c02000 {
> > +                     compatible = "allwinner,suniv-f1c100s-dma";
> > +                     reg = <0x01c02000 0x1000>;
> > +                     interrupts = <18>;
> > +                     clocks = <&ccu CLK_BUS_DMA>;
> > +                     resets = <&ccu RST_BUS_DMA>;
> > +                     #dma-cells = <2>;
> > +             };
> > +
> >               ccu: clock at 1c20000 {
> >                       compatible = "allwinner,suniv-f1c100s-ccu";
> >                       reg = <0x01c20000 0x400>;
>
>


From quic_msavaliy at quicinc.com  Mon Dec  9 10:16:31 2024
From: quic_msavaliy at quicinc.com (Mukesh Kumar Savaliya)
Date: Mon, 9 Dec 2024 23:46:31 +0530
Subject: [PATCH] i3c: master: Improve initialization of numbered I2C
 adapters
In-Reply-To: <20241205132934.12110-1-defa.li@mediatek.com>
References: <20241205132934.12110-1-defa.li@mediatek.com>
Message-ID: <54ac6a4f-5ae0-409f-8401-d6e1326d4358@quicinc.com>



On 12/5/2024 6:59 PM, Defa Li wrote:
> Add logic to initialize I2C adapters with a specific ID if available,
> improving device identification and configuration.
> 
Could you also provide how exactly to define this into DT to have 
numbering while registering the adapter ? Kind of sample to which can be 
defined in DTSI.
> Signed-off-by: Defa Li <defa.li at mediatek.com>
> ---
>   drivers/i3c/master.c | 11 +++++++++--
>   1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 42310c9a00c2..a838cdbb897b 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -2486,7 +2486,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
>   	struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master);
>   	struct i2c_dev_desc *i2cdev;
>   	struct i2c_dev_boardinfo *i2cboardinfo;
> -	int ret;
> +	int ret, id = -ENODEV;
>   
>   	adap->dev.parent = master->dev.parent;
>   	adap->owner = master->dev.parent->driver->owner;
> @@ -2497,7 +2497,14 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
>   	adap->timeout = 1000;
>   	adap->retries = 3;
>   
> -	ret = i2c_add_adapter(adap);
> +	if (master->dev.of_node)
> +		id = of_alias_get_id(master->dev.of_node, "i2c");
> +
> +	if (id >= 0) {
> +		adap->nr = id;
> +		ret = i2c_add_numbered_adapter(adap);
> +	} else
> +		ret = i2c_add_adapter(adap);
Please provide braces for else too.
>   	if (ret)
>   		return ret;
>   



From will at kernel.org  Mon Dec  9 10:43:02 2024
From: will at kernel.org (Will Deacon)
Date: Mon,  9 Dec 2024 18:43:02 +0000
Subject: [PATCH v10 0/5] Marvell Odyssey uncore performance monitor support
In-Reply-To: <20241108040619.753343-1-gthiagarajan@marvell.com>
References: <20241108040619.753343-1-gthiagarajan@marvell.com>
Message-ID: <173375975929.1126639.3014797293095005520.b4-ty@kernel.org>

On Fri, 08 Nov 2024 09:36:14 +0530, Gowthami Thiagarajan wrote:
> Odyssey is a 64 bit ARM based SoC with multiple performance monitor
> units for various blocks.
> 
> This series of patches introduces support for uncore performance monitor
> units (PMUs) on the Marvell Odyssey platform. The PMUs covered in this
> series include the DDR PMU and LLC-TAD PMU.
> 
> [...]

Applied to will (for-next/perf), thanks!

[1/5] perf/marvell: Refactor to extract platform data - no functional change
      https://git.kernel.org/will/c/349f77e10952
[2/5] perf/marvell: Refactor to extract PMU operations
      https://git.kernel.org/will/c/0045de7e8713
[3/5] perf/marvell: Odyssey DDR Performance monitor support
      https://git.kernel.org/will/c/d950c381dce1
[4/5] perf/marvell : Refactor to extract platform data - no functional change
      https://git.kernel.org/will/c/59731e231c6f
[5/5] perf/marvell : Odyssey LLC-TAD performance monitor support
      https://git.kernel.org/will/c/5fcccba11833

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Mon Dec  9 10:43:01 2024
From: will at kernel.org (Will Deacon)
Date: Mon,  9 Dec 2024 18:43:01 +0000
Subject: [PATCH v2 0/4] perf: arm_cspmu: nvidia: update event list and filter
In-Reply-To: <20241031142118.1865965-1-bwicaksono@nvidia.com>
References: <20241031142118.1865965-1-bwicaksono@nvidia.com>
Message-ID: <173375687020.3268682.2167190065642330868.b4-ty@kernel.org>

On Thu, 31 Oct 2024 14:21:14 +0000, Besar Wicaksono wrote:
> This series update the list of supported events and filters in NVIDIA Grace
> CoreSight PMUs.
> 
> Changes from v1:
>  * Split the change for setting default filter value.
>  * Add new patch to fix NVIDIA PMU sysfs path in kernel doc.
>  * Drop the patch for CNVLINK PMU events renaming from this series.
> v1: https://lore.kernel.org/linux-arm-kernel/20240918215846.1424282-1-bwicaksono at nvidia.com/T/
> 
> [...]

Applied to will (for-next/perf), thanks!

[1/4] perf: arm_cspmu: nvidia: remove unsupported SCF events
      https://git.kernel.org/will/c/ac4c52956f62
[2/4] perf: arm_cspmu: nvidia: fix sysfs path in the kernel doc
      https://git.kernel.org/will/c/5f7cd0dc98a6
[3/4] perf: arm_cspmu: nvidia: enable NVLINK-C2C port filtering
      https://git.kernel.org/will/c/ca26df4b1036
[4/4] perf: arm_cspmu: nvidia: monitor all ports by default
      https://git.kernel.org/will/c/bce61d5c5764

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Mon Dec  9 10:43:03 2024
From: will at kernel.org (Will Deacon)
Date: Mon,  9 Dec 2024 18:43:03 +0000
Subject: [PATCH 0/2] perf/dwc_pcie: Fix the swapped event numbers as well as the documentation
In-Reply-To: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
References: <20241205061914.5568-1-ilkka@os.amperecomputing.com>
Message-ID: <173375912254.1125785.1872820731502163004.b4-ty@kernel.org>

On Thu, 05 Dec 2024 06:19:12 +0000, Ilkka Koskinen wrote:
> According to the versions of Designware Cores PCI Express Controller Databook
> I found, the eventid for "L1 aux" is 0x08 and "TX L0s and RX L0S" is 0x09.
> 
> Shuai and Jing, could you verify that your document matches ours and the events
> are indeed swapped in the driver at the moment?
> 
> Cheers, Ilkka
> 
> [...]

Applied to will (for-next/perf), thanks!

[1/2] perf/dwc_pcie: Fix the event numbers
      https://git.kernel.org/will/c/e64c22cc2e61
[2/2] Documentation: dwc_pcie_pmu: Fix the mnemonics and eventid
      https://git.kernel.org/will/c/8632306e093c

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From atishp at rivosinc.com  Mon Dec  9 10:52:06 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Mon, 9 Dec 2024 10:52:06 -0800
Subject: [PATCH 3/8] drivers/perf: riscv: Add raw event v2 support
In-Reply-To: <b48c4319-1fbc-4703-88d2-6f495af9c24e@sifive.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-3-a4f9691421f8@rivosinc.com> <e124c532-7a08-4788-843d-345827e35f5f@sifive.com>
 <CAHBxVyEwkPUcut0L7K9eewcmhOOidU16WnGRiPiP3D7-OS7HvQ@mail.gmail.com> <b48c4319-1fbc-4703-88d2-6f495af9c24e@sifive.com>
Message-ID: <CAHBxVyFrsF0jwwFwKsg_6=c5ewFZG12iz3owzHEv6GxpA+hB1w@mail.gmail.com>

On Mon, Dec 2, 2024 at 6:39?PM Samuel Holland <samuel.holland at sifive.com> wrote:
>
> Hi Atish,
>
> On 2024-12-02 6:15 PM, Atish Kumar Patra wrote:
> > On Mon, Dec 2, 2024 at 2:37?PM Samuel Holland <samuel.holland at sifive.com> wrote:
> >> On 2024-11-19 2:29 PM, Atish Patra wrote:
> >>> SBI v3.0 introduced a new raw event type that allows wider
> >>> mhpmeventX width to be programmed via CFG_MATCH.
> >>>
> >>> Use the raw event v2 if SBI v3.0 is available.
> >>>
> >>> Signed-off-by: Atish Patra <atishp at rivosinc.com>
> >>> ---
> >>>  arch/riscv/include/asm/sbi.h |  4 ++++
> >>>  drivers/perf/riscv_pmu_sbi.c | 18 ++++++++++++------
> >>>  2 files changed, 16 insertions(+), 6 deletions(-)
> >>>
> >>> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> >>> index 9be38b05f4ad..3ee9bfa5e77c 100644
> >>> --- a/arch/riscv/include/asm/sbi.h
> >>> +++ b/arch/riscv/include/asm/sbi.h
> >>> @@ -159,7 +159,10 @@ struct riscv_pmu_snapshot_data {
> >>>
> >>>  #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
> >>>  #define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
> >>> +/* SBI v3.0 allows extended hpmeventX width value */
> >>> +#define RISCV_PMU_RAW_EVENT_V2_MASK GENMASK_ULL(55, 0)
> >>>  #define RISCV_PMU_RAW_EVENT_IDX 0x20000
> >>> +#define RISCV_PMU_RAW_EVENT_V2_IDX 0x30000
> >>>  #define RISCV_PLAT_FW_EVENT  0xFFFF
> >>>
> >>>  /** General pmu event codes specified in SBI PMU extension */
> >>> @@ -217,6 +220,7 @@ enum sbi_pmu_event_type {
> >>>       SBI_PMU_EVENT_TYPE_HW = 0x0,
> >>>       SBI_PMU_EVENT_TYPE_CACHE = 0x1,
> >>>       SBI_PMU_EVENT_TYPE_RAW = 0x2,
> >>> +     SBI_PMU_EVENT_TYPE_RAW_V2 = 0x3,
> >>>       SBI_PMU_EVENT_TYPE_FW = 0xf,
> >>>  };
> >>>
> >>> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> >>> index 50cbdbf66bb7..f0e845ff6b79 100644
> >>> --- a/drivers/perf/riscv_pmu_sbi.c
> >>> +++ b/drivers/perf/riscv_pmu_sbi.c
> >>> @@ -59,7 +59,7 @@ asm volatile(ALTERNATIVE(                                           \
> >>>  #define PERF_EVENT_FLAG_USER_ACCESS  BIT(SYSCTL_USER_ACCESS)
> >>>  #define PERF_EVENT_FLAG_LEGACY               BIT(SYSCTL_LEGACY)
> >>>
> >>> -PMU_FORMAT_ATTR(event, "config:0-47");
> >>> +PMU_FORMAT_ATTR(event, "config:0-55");
> >>>  PMU_FORMAT_ATTR(firmware, "config:62-63");
> >>>
> >>>  static bool sbi_v2_available;
> >>> @@ -527,18 +527,24 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
> >>>               break;
> >>>       case PERF_TYPE_RAW:
> >>>               /*
> >>> -              * As per SBI specification, the upper 16 bits must be unused
> >>> -              * for a hardware raw event.
> >>> +              * As per SBI v0.3 specification,
> >>> +              *  -- the upper 16 bits must be unused for a hardware raw event.
> >>> +              * As per SBI v3.0 specification,
> >>> +              *  -- the upper 8 bits must be unused for a hardware raw event.
> >>>                * Bits 63:62 are used to distinguish between raw events
> >>>                * 00 - Hardware raw event
> >>>                * 10 - SBI firmware events
> >>>                * 11 - Risc-V platform specific firmware event
> >>>                */
> >>> -
> >>>               switch (config >> 62) {
> >>>               case 0:
> >>> -                     ret = RISCV_PMU_RAW_EVENT_IDX;
> >>> -                     *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
> >>> +                     if (sbi_v3_available) {
> >>> +                             *econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
> >>> +                             ret = RISCV_PMU_RAW_EVENT_V2_IDX;
> >>> +                     } else {
> >>> +                             *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
> >>> +                             ret = RISCV_PMU_RAW_EVENT_IDX;
> >>
> >> Shouldn't we check to see if any of bits 48-55 are set and return an error,
> >> instead of silently requesting the wrong event?
> >>
> >
> > We can. I did not add it originally as we can't do much validation for
> > the raw events for anyways.
> > If the encoding is not supported the user will get the error anyways
> > as it can't find a counter.
> > We will just save 1 SBI call if the kernel doesn't allow requesting an
> > event if bits 48-55 are set.
>
> The scenario I'm concerned about is where masking off bits 48-55 results in a
> valid, supported encoding for a different event. For example, in the HPM event
> encoding scheme used by Rocket and inherited by SiFive cores, bits 8-55 are a
> bitmap. So masking off some of those bits will exclude some events, but will not
> create an invalid encoding. This could be very confusing for users.
>

Ahh yes. That is problematic if the vendor implements that type of
event encoding.
I will send the fix patch with an error if bits 48-55 are set.

> Regards,
> Samuel
>


From will at kernel.org  Mon Dec  9 10:56:24 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Dec 2024 18:56:24 +0000
Subject: [PATCH v2] arm64: Allow CONFIG_AUTOFDO_CLANG to be selected
In-Reply-To: <CAF1bQ=SiHi8oCyo5YnXGpQGofM1zAsnBdqSEet1mS-BYNKVU8A@mail.gmail.com>
References: <20241118222540.27495-1-yabinc@google.com>
 <20241209162028.GD12428@willie-the-truck>
 <CAF1bQ=SiHi8oCyo5YnXGpQGofM1zAsnBdqSEet1mS-BYNKVU8A@mail.gmail.com>
Message-ID: <20241209185623.GA13084@willie-the-truck>

(Aside: please try to avoid top-posting on the public lists as it messes up
the flow of conversation; I'll try to piece this back together.)

On Mon, Dec 09, 2024 at 09:30:50AM -0800, Rong Xu wrote:
> On Mon, Dec 9, 2024 at 8:20?AM Will Deacon <will at kernel.org> wrote:
> > On Mon, Nov 18, 2024 at 02:25:40PM -0800, Yabin Cui wrote:
> > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > > index fd9df6dcc593..c3814df5e391 100644
> > > --- a/arch/arm64/Kconfig
> > > +++ b/arch/arm64/Kconfig
> > > @@ -103,6 +103,7 @@ config ARM64
> > >       select ARCH_SUPPORTS_PER_VMA_LOCK
> > >       select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
> > >       select ARCH_SUPPORTS_RT
> > > +     select ARCH_SUPPORTS_AUTOFDO_CLANG
> > >       select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
> > >       select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
> > >       select ARCH_WANT_DEFAULT_BPF_JIT
> >
> > After this change, both arm64 and x86 select this option unconditionally
> > and with no apparent support code being added. So what is actually
> > required in order to select ARCH_SUPPORTS_AUTOFDO_CLANG and why isn't
> > it just available for all architectures instead?

> Enabling an AutoFDO build requires users to explicitly set CONFIG_AUTOFDO_CLANG.
> The support code is in Commit 315ad8780a129e82 (kbuild: Add AutoFDO
> support for Clang build).

Yes, that is precisely my point. The user has to enable
CONFIG_AUTOFDO_CLANG anyway, so what is the point in having
ARCH_SUPPORTS_AUTOFDO_CLANG. Why would an architecture _not_ want to
select that?

> We are not enabling this for all architectures because AutoFDO's optimized build
> relies on Last Branch Records (LBR) which aren't available on all architectures.

So? ETM isn't available on all arm64 machines and I doubt whether LBR is
available on _all_ x86 machines either. So there's a runtime failure
mode that needs to be handled anyway and I don't think the arch-specific
Kconfig option is really doing anything useful.

Will


From nicolinc at nvidia.com  Mon Dec  9 11:03:01 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 9 Dec 2024 11:03:01 -0800
Subject: [PATCH v2] iommu/tegra241-cmdqv: do not use smp_processor_id in
 preemptible context
In-Reply-To: <Z1L1mja3nXzsJ0Pk@uudg.org>
References: <Z1L1mja3nXzsJ0Pk@uudg.org>
Message-ID: <Z1c+5dI7fibEZZ/h@Asurada-Nvidia>

On Fri, Dec 06, 2024 at 10:01:14AM -0300, Luis Claudio R. Goncalves wrote:
> During boot some of the calls to tegra241_cmdqv_get_cmdq() will happen
> in preemptible context. As this function calls smp_processor_id(), if
> CONFIG_DEBUG_PREEMPT is enabled, these calls will trigger a series of
> "BUG: using smp_processor_id() in preemptible" backtraces.

Confirmed the BUG prints. Should we CC stable tree?

> As tegra241_cmdqv_get_cmdq() only calls smp_processor_id() to use the
> CPU number as a factor to balance out traffic on cmdq usage, it is safe
> to use raw_smp_processor_id() here.
> 
> v2: Sebastian helped identify that the problem was not exclusive to kernels
>     with PREEMPT_RT enabled. The delta between v1 and v2 is the description.
> 
> Signed-off-by: Luis Claudio R. Goncalves <lgoncalv at redhat.com>

Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>

Thanks
Nicolin


From nunodasneves at linux.microsoft.com  Mon Dec  9 11:19:23 2024
From: nunodasneves at linux.microsoft.com (Nuno Das Neves)
Date: Mon, 9 Dec 2024 11:19:23 -0800
Subject: [PATCH v3 1/5] hyperv: Move hv_connection_id to hyperv-tlfs.h
In-Reply-To: <Z1Y0uJlVn-86KHE8@liuwe-devbox-debian-v2>
References: <1732577084-2122-1-git-send-email-nunodasneves@linux.microsoft.com>
 <1732577084-2122-2-git-send-email-nunodasneves@linux.microsoft.com>
 <Z1Y0uJlVn-86KHE8@liuwe-devbox-debian-v2>
Message-ID: <a76d129c-2956-4bbc-bd14-cb12737b64df@linux.microsoft.com>

On 12/8/2024 4:07 PM, Wei Liu wrote:
> On Mon, Nov 25, 2024 at 03:24:40PM -0800, Nuno Das Neves wrote:
>> This definition is in the wrong file; it is part of the TLFS doc.
>>
>> Acked-by: Wei Liu <wei.liu at kernel.org>
>> Reviewed-by: Easwar Hariharan <eahariha at linux.microsoft.com>
>> Reviewed-by: Michael Kelley <mhklinux at outlook.com>
>> Signed-off-by: Nuno Das Neves <nunodasneves at linux.microsoft.com>
> 
> One comment about the ordering of the tags. It is better to organize
> them in the following order:
> 
> Signed-off-by: Nuno Das Neves <nunodasneves at linux.microsoft.com>
> Acked-by: Wei Liu <wei.liu at kernel.org>
> Reviewed-by: Easwar Hariharan <eahariha at linux.microsoft.com>
> Reviewed-by: Michael Kelley <mhklinux at outlook.com>
> 
> I've made the change for you while applying the patch.
> 

Thank you, noted for next time.

> Thanks,
> Wei.



From will at kernel.org  Mon Dec  9 11:28:25 2024
From: will at kernel.org (Will Deacon)
Date: Mon,  9 Dec 2024 19:28:25 +0000
Subject: [PATCH RESEND v2] dt-bindings: arm-smmu: Document SM8750 SMMU
In-Reply-To: <20241204-sm8750_master_smmu-v2-1-9e73e3fc15f2@quicinc.com>
References: <20241204-sm8750_master_smmu-v2-1-9e73e3fc15f2@quicinc.com>
Message-ID: <173377196863.3924800.3062631537742309660.b4-ty@kernel.org>

On Wed, 04 Dec 2024 14:27:25 -0800, Melody Olvera wrote:
> Document the SM8750 SMMU block.
> 
> 

Applied to will (for-joerg/arm-smmu/bindings), thanks!

[1/1] dt-bindings: arm-smmu: Document SM8750 SMMU
      https://git.kernel.org/will/c/2593988fd00e

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Mon Dec  9 11:28:24 2024
From: will at kernel.org (Will Deacon)
Date: Mon,  9 Dec 2024 19:28:24 +0000
Subject: [PATCH v2 0/2] iommu/arm-smmu-qcom: Add SDM670 SMMU v2
In-Reply-To: <20241114004713.42404-4-mailingradian@gmail.com>
References: <20241114004713.42404-4-mailingradian@gmail.com>
Message-ID: <173377135109.3922978.5202199234250494714.b4-ty@kernel.org>

On Wed, 13 Nov 2024 19:47:14 -0500, Richard Acayan wrote:
> This adds the SMMU v2 for the Snapdragon 670, used for the Adreno GPU.
> 
> Changes since v1 (20240730013820.41702-4-mailingradian at gmail.com):
> - explain need for specific compatible in iommu driver patch (2/2)
> 
> Richard Acayan (2):
>   dt-bindings: iommu: arm,smmu: add sdm670 adreno iommu compatible
>   iommu/arm-smmu-qcom: add sdm670 adreno iommu compatible
> 
> [...]

I applied the bindings change to will (for-joerg/arm-smmu/bindings)

[1/2] dt-bindings: iommu: arm,smmu: add sdm670 adreno iommu compatible
      https://git.kernel.org/will/c/87cafa082ce3

and the driver change to will (for-joerg/arm-smmu/updates), thanks!

[2/2] iommu/arm-smmu-qcom: add sdm670 adreno iommu compatible
      https://git.kernel.org/will/c/423147389063

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From krzysztof.kozlowski at linaro.org  Mon Dec  9 11:28:45 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon,  9 Dec 2024 20:28:45 +0100
Subject: (subset) [PATCH v2 0/5] Google Pixel 6 (oriole): TCPCI enablement & USB updates
In-Reply-To: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
References: <20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01@linaro.org>
Message-ID: <173377246177.140612.3507892014297013464.b4-ty@linaro.org>


On Tue, 03 Dec 2024 12:40:23 +0000, Andr? Draszik wrote:
> This series adds and enables the Maxim MAX77759 TCPCI for Google Pixel
> 6 (Oriole).
> 
> It relies on the bindings updates proposed as part of
> https://lore.kernel.org/all/20241203-dtbinding-max77759-v3-1-e1a1d86aca8e at linaro.org/
> and
> https://lore.kernel.org/all/20241203-gs101-phy-lanes-orientation-phy-v2-2-40dcf1b7670d at linaro.org/
> 
> [...]

Applied, thanks!

[1/5] applied (but b4 lost rack)
[2/5] arm64: dts: exynos: gs101: phy region for exynos5-usbdrd is larger
      https://git.kernel.org/krzk/linux/c/527c9640e4f04044afa98f3ce18f8af89ac4a322
[3/5] arm64: dts: exynos: gs101: allow stable USB phy Vbus detection
      https://git.kernel.org/krzk/linux/c/95350c0ec27d906cd95375084ce343bc65421e70

!!! NOT applied - waiting for bindings to be picked up:

[4/5] arm64: dts: exynos: gs101-oriole: enable Maxim max77759 TCPCi
[5/5] arm64: dts: exynos: gs101-oriole: add pd-disable and typec-power-opmode

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


From lkp at intel.com  Mon Dec  9 11:36:09 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 10 Dec 2024 03:36:09 +0800
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If
 timer expired
In-Reply-To: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
Message-ID: <202412100311.HEYAT0bx-lkp@intel.com>

Hi Ganapatrao,

kernel test robot noticed the following build warnings:

[auto build test WARNING on kvmarm/next]
[also build test WARNING on arm64/for-next/core soc/for-next linus/master arm/for-next arm/fixes v6.13-rc2 next-20241209]
[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/Ganapatrao-Kulkarni/KVM-arm64-nv-Set-ISTATUS-for-emulated-timers-If-timer-expired/20241209-133651
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git next
patch link:    https://lore.kernel.org/r/20241209053201.339939-1-gankulkarni%40os.amperecomputing.com
patch subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer expired
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20241210/202412100311.HEYAT0bx-lkp at intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241210/202412100311.HEYAT0bx-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/202412100311.HEYAT0bx-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> arch/arm64/kvm/arch_timer.c:1202:3: warning: label followed by a declaration is a C23 extension [-Wc23-extensions]
    1202 |                 struct timer_map map;
         |                 ^
   1 warning generated.


vim +1202 arch/arm64/kvm/arch_timer.c

  1190	
  1191	static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
  1192					struct arch_timer_context *timer,
  1193					enum kvm_arch_timer_regs treg,
  1194					u64 val)
  1195	{
  1196		switch (treg) {
  1197		case TIMER_REG_TVAL:
  1198			timer_set_cval(timer, kvm_phys_timer_read() - timer_get_offset(timer) + (s32)val);
  1199			break;
  1200	
  1201		case TIMER_REG_CTL:
> 1202			struct timer_map map;
  1203	
  1204			val &= ~ARCH_TIMER_CTRL_IT_STAT;
  1205			get_timer_map(vcpu, &map);
  1206			/* Set ISTATUS bit for emulated timers, if timer expired. */
  1207			if (timer == map.emul_vtimer || timer == map.emul_ptimer) {
  1208				if (!kvm_timer_compute_delta(timer))
  1209					val |= ARCH_TIMER_CTRL_IT_STAT;
  1210			}
  1211			timer_set_ctl(timer, val);
  1212			break;
  1213	
  1214		case TIMER_REG_CVAL:
  1215			timer_set_cval(timer, val);
  1216			break;
  1217	
  1218		case TIMER_REG_VOFF:
  1219			*timer->offset.vcpu_offset = val;
  1220			break;
  1221	
  1222		default:
  1223			BUG();
  1224		}
  1225	}
  1226	

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


From tglx at linutronix.de  Mon Dec  9 11:51:52 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 09 Dec 2024 20:51:52 +0100
Subject: [PATCH v11 3/7] PCI: endpoint: pci-ep-msi: Add MSI address/data
 pair mutable check
In-Reply-To: <20241209-ep-msi-v11-3-7434fa8397bd@nxp.com>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
 <20241209-ep-msi-v11-3-7434fa8397bd@nxp.com>
Message-ID: <87h67cprc7.ffs@tglx>

Frank!

On Mon, Dec 09 2024 at 12:48, Frank Li wrote:

> Some MSI controller change address/data pair when irq_set_affinity().
> Current PCI endpoint can't support this type MSI controller. So add flag
> MSI_FLAG_MSG_IMMUTABLE in include/linux/msi.h, set this flags in ARM GIC
> ITS MSI controller and check it when allocate doorbell.
>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> Change from v9 to v11
> - new patch
> ---
>  drivers/irqchip/irq-gic-v3-its-msi-parent.c | 1 +
>  drivers/pci/endpoint/pci-ep-msi.c           | 8 ++++++++
>  include/linux/msi.h                         | 2 ++

This is not how it works and I explained that you to more than once in
the past.

The change to the interrupt code is standalone and has nothing to do
with PCI endpoint. The latter is just a user of this.

So this want's to be split into several patches:

   1) add the new flag and a helper function which checks for the flag.

   2) add the flag to GICv3 ITS with a proper explanation

   3) Check for it in the PCI endpoint code

>  
> +	if (!dom->msi_parent_ops)
> +		return -EINVAL;

irq_domain_is_msi_parent()

> +	if (!(dom->msi_parent_ops->supported_flags & MSI_FLAG_MSG_IMMUTABLE)) {

Want's a helper.

Thanks,

        tglx


From krzysztof.kozlowski at linaro.org  Mon Dec  9 11:51:57 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 09 Dec 2024 20:51:57 +0100
Subject: [PATCH v7 0/4] Add minimal Samsung Galaxy S20 Series board,
 SM-G981B and SM-G980F support
In-Reply-To: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
References: <20241209080059.11891-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <173377391743.160715.4680965991151574957.b4-ty@linaro.org>


On Mon, 09 Dec 2024 08:00:55 +0000, Umer Uddin wrote:
> This series adds initial support for the Samsung Galaxy S20 Series and also
> initial board support for the Samsung Galaxy S20 5G (SM-G981B)
> codenamed x1s and the Samsung Galaxy S20 (SM-G980F).
> 
> The S20 Series feature a lot of similarities in their configuration
> and internally Samsung named the common devicetrees in their
> downstream kernel 'hubble', please note hubble excludes the
> S20 FE series and Note20 series. To accommodate this, I've
> now named the device tree common's matching the codenames
> (x1s-common).
> The device trees have been tested with dtbs_check W=1
> and results in no warnings.
> 
> [...]

Applied, thanks!

[1/4] dt-bindings: arm: samsung: samsung-boards: Add bindings for SM-G981B and SM-G980F board
      https://git.kernel.org/krzk/linux/c/2e342a80b02c64d2bae6f1070c473a8a9c7a5b9d
[2/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 Series boards (x1s-common)
      https://git.kernel.org/krzk/linux/c/38794a41be2bacc698fc520d75d3aea88c727a01
[3/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 5G (x1s)
      https://git.kernel.org/krzk/linux/c/e7c075846d0be40f6238ea9c784c5d553135c1ae
[4/4] arm64: dts: exynos: Add initial support for Samsung Galaxy S20 (x1slte)
      https://git.kernel.org/krzk/linux/c/4ccb27d48a73d8be0e532353d0d9445cb52587c9

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



From robdclark at gmail.com  Mon Dec  9 11:54:50 2024
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 9 Dec 2024 11:54:50 -0800
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
Message-ID: <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>

On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
>
> When kernel is booted in EL2, SECVID registers are accessible to the
> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> on Zap firmware. Also, we can't load a secure firmware without a
> hypervisor that supports it.

Shouldn't we do this based on whether zap node is in dtb (and not disabled)?

slbounce applies some dtb overlays to disable the zap node when
booting in EL2 (and make some other changes due to kernel being in
control of the pci smmuv3, or something along those lines).

BR,
-R

>
> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
>
> 1. Gunyah (No KVM) - Loads zap shader based on DT
> 2. KVM in VHE - Skips zap shader load and programs SECVID register
> 3. KVM in nVHE - Loads zap shader based on DT
> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
>         programs SECVID register
>
> For (1) and (3) configuration, this patch doesn't have any impact.
> Driver loads secure firmware based on other existing hints.
>
> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
> ---
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 +++++++++++++++++++++++------------
>  1 file changed, 54 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index 019610341df1..9dcaa8472430 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -14,6 +14,10 @@
>  #include <linux/pm_domain.h>
>  #include <linux/soc/qcom/llcc-qcom.h>
>
> +#ifdef CONFIG_ARM64
> +#include <asm/virt.h>
> +#endif
> +
>  #define GPU_PAS_ID 13
>
>  static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
> @@ -998,6 +1002,54 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
>         return ret;
>  }
>
> +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> +{
> +       int ret;
> +
> +#ifdef CONFIG_ARM64
> +       /*
> +        * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> +        * to switch the secure mode to avoid the dependency on zap shader.
> +        */
> +       if (is_kernel_in_hyp_mode())
> +               goto direct_switch;
> +#endif
> +
> +       /*
> +        * Try to load a zap shader into the secure world. If successful
> +        * we can use the CP to switch out of secure mode. If not then we
> +        * have no resource but to try to switch ourselves out manually. If we
> +        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
> +        * be blocked and a permissions violation will soon follow.
> +        */
> +       ret = a6xx_zap_shader_init(gpu);
> +       if (ret == -ENODEV) {
> +               /*
> +                * This device does not use zap shader (but print a warning
> +                * just in case someone got their dt wrong.. hopefully they
> +                * have a debug UART to realize the error of their ways...
> +                * if you mess this up you are about to crash horribly)
> +                */
> +               dev_warn_once(gpu->dev->dev,
> +                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
> +               goto direct_switch;
> +       } else if (ret)
> +               return ret;
> +
> +       OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
> +       OUT_RING(gpu->rb[0], 0x00000000);
> +
> +       a6xx_flush(gpu, gpu->rb[0]);
> +       if (!a6xx_idle(gpu, gpu->rb[0]))
> +               return -EINVAL;
> +
> +       return 0;
> +
> +direct_switch:
> +       gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
> +       return 0;
> +}
> +
>  #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
>                        A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
>                        A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
> @@ -1341,35 +1393,9 @@ static int hw_init(struct msm_gpu *gpu)
>         if (ret)
>                 goto out;
>
> -       /*
> -        * Try to load a zap shader into the secure world. If successful
> -        * we can use the CP to switch out of secure mode. If not then we
> -        * have no resource but to try to switch ourselves out manually. If we
> -        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
> -        * be blocked and a permissions violation will soon follow.
> -        */
> -       ret = a6xx_zap_shader_init(gpu);
> -       if (!ret) {
> -               OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
> -               OUT_RING(gpu->rb[0], 0x00000000);
> -
> -               a6xx_flush(gpu, gpu->rb[0]);
> -               if (!a6xx_idle(gpu, gpu->rb[0]))
> -                       return -EINVAL;
> -       } else if (ret == -ENODEV) {
> -               /*
> -                * This device does not use zap shader (but print a warning
> -                * just in case someone got their dt wrong.. hopefully they
> -                * have a debug UART to realize the error of their ways...
> -                * if you mess this up you are about to crash horribly)
> -                */
> -               dev_warn_once(gpu->dev->dev,
> -                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
> -               gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
> -               ret = 0;
> -       } else {
> +       ret = a6xx_switch_secure_mode(gpu);
> +       if (!ret)
>                 return ret;
> -       }
>
>  out:
>         if (adreno_has_gmu_wrapper(adreno_gpu))
>
> ---
> base-commit: f4a867a46862c1743501bbe8c813238456ec8699
> change-id: 20241120-drm-msm-kvm-support-cd6e6744ced6
>
> Best regards,
> --
> Akhil P Oommen <quic_akhilpo at quicinc.com>
>


From shreeya.patel at collabora.com  Mon Dec  9 12:02:21 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Mon, 9 Dec 2024 20:02:21 +0000
Subject: [PATCH v5 2/4] dt-bindings: media: Document bindings for HDMI RX Controller
In-Reply-To: <20241209200120.3228643-1-shreeya.patel@collabora.com>
References: <20241209200120.3228643-1-shreeya.patel@collabora.com>
Message-ID: <01020193ad040150-e0cf3371-115b-469e-840e-4fa97af5b207-000000@eu-west-1.amazonses.com>

Document bindings for the Synopsys DesignWare HDMI RX Controller.

Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
---

Changes in v5 :-
- Correct the interrupt IRQ number

Changes in v4 :-
- No change

Changes in v3 :-
- Rename hdmirx_cma to hdmi_receiver_cma
- Add a Reviewed-by tag

Changes in v2 :-
- Add a description for the hardware
- Rename resets, vo1 grf and HPD properties
- Add a proper description for grf and vo1-grf phandles
- Rename the HDMI Input node name to hdmi-receiver
- Improve the subject line
- Include gpio header file in example to fix dt_binding_check failure

 .../bindings/media/snps,dw-hdmi-rx.yaml       | 132 ++++++++++++++++++
 1 file changed, 132 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..510e94e9ca3a
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
@@ -0,0 +1,132 @@
+# SPDX-License-Identifier: (GPL-2.0-only 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>
+
+description:
+  Synopsys DesignWare HDMI Input Controller preset on RK3588 SoCs
+  allowing devices to receive and decode high-resolution video streams
+  from external sources like media players, cameras, laptops, etc.
+
+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: axi
+      - const: apb
+      - const: ref
+      - const: biu
+
+  memory-region:
+    maxItems: 1
+
+  hpd-gpios:
+    description: GPIO specifier for HPD.
+    maxItems: 1
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the general register file
+      containing HDMIRX PHY status bits.
+
+  rockchip,vo1-grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the Video Output GRF register
+      to enable EDID transfer through SDAIN and SCLIN.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - clocks
+  - clock-names
+  - power-domains
+  - resets
+  - pinctrl-0
+  - hpd-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/rk3588-power.h>
+    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+    hdmi_receiver: hdmi-receiver at fdee0000 {
+      compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx";
+      reg = <0xfdee0000 0x6000>;
+      interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>,
+                   <GIC_SPI 178 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 = "axi", "apb", "ref", "biu";
+      memory-region = <&hdmi_receiver_cma>;
+      pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_5v_detection>;
+      pinctrl-names = "default";
+      hpd-gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
+    };
-- 
2.39.2



From shreeya.patel at collabora.com  Mon Dec  9 12:00:30 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Mon, 9 Dec 2024 20:00:30 +0000
Subject: [PATCH v5 0/4] Add Synopsys DesignWare HDMI RX Controller
Message-ID: <01020193ad025176-f2e8e4fd-41a6-42ef-b3d0-dfa87a6d0abd-000000@eu-west-1.amazonses.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 :-
* HDMIRX driver now only works with the opensource TF-A.
* We have tested the working of OBS studio with HDMIRX driver and
there were no issues seen.
* We also tested and verified the support for interlaced video.

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

CEC compliance test results :-

* https://gitlab.collabora.com/-/snippets/380
* https://gitlab.collabora.com/-/snippets/381

Following is the v4l2-compliance test result :-

root at debian-rockchip-rock5b-rk3588:~# v4l2-compliance -d /dev/video0 
v4l2-compliance 1.29.0-5278, 64 bits, 64-bit time_t
v4l2-compliance SHA: 791da13728d9 2024-11-25 10:01:57

Compliance test for snps_hdmirx device /dev/video0:

Driver Info:
	Driver name      : snps_hdmirx
	Card type        : snps_hdmirx
	Bus info         : platform:fdee0000.hdmi_receiver
	Driver version   : 6.12.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: 4 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_REMOVE_BUFS: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)
	test blocking wait: OK

Total for snps_hdmirx device /dev/video0: 48, Succeeded: 48, Failed: 0, Warnings: 0


Changes in v5 :-
- Fix the interrupt IRQ number in the dt-bindings and device tree
- Add alignment property to ensure hdmi-receiver-cma
  starts at a 64KB-aligned address
- Change the MODULE_DESCRIPTION
- Add VIDEO_SYNOPSYS_HDMIRX as prefix to the default edid config
- Drop the enabling of default edid in the Kconfig
- Replace the default EDID with hdmi-4k-300mhz EDID produced
  by v4l2-ctl tool for better compatibility with various HDMI
  cables and adapters
- Rework the write_edid and set_edid functions
- During format change, retrieve the current pixel format,
  color depth, and AVI infoframe details instead of only
  detecting the format
- Improve the logging mechanism and delays in the
  hdmirx_wait_signal_lock function
- Fix the 4K at 60 capturing for RGB format
- Document what hdmirx_check_timing_valid function does
- Rework the hdmirx_get_detected_timings function
- Fix the NV16/24 size image value
- Add the implementation from Benjamin Hoff to expose the
  ITC type to v4l2
- Remove all the firmware related code

Changes in v4 :-
- Remove DTS changes included in the device tree patch
- Remove the hdmi rx pin info as it's already present
in the rk3588-base-pinctrl.dtsi
- Create a separate config option for selecting the EDID
and enable it by default
- Improve the comment related to DV timings and move it
to the side of hdmirx_get_detected_timings
- Add 100ms delay before pulling the HPD high
- Do not return the detected timings from VIDIOC_G_DV_TIMINGS
- Drop the bus info from hdmirx_querycap
- If *num_planes != 0 then return 0 in hdmirx_queue_setup
- Set queue->min_queued_buffers to 1
- Drop q->allow_cache_hints = 0; as it's always 0 by default
- Add a comment for q->dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
- Drop .read = vb2_fop_read as it's not supported by driver
- Remove redundant edid_init_data_600M
- Make HPD low when driver is loaded
- Add support for reading AVI Infoframe
- Remove msg_len checks from hdmirx_cec_transmit
- Add info about the CEC compliance test in the cover letter
- Add arbitration lost status
- Validate the physical address inside the EDID

Changes in v3 :-
- Use v4l2-common helpers in the HDMIRX driver
- Rename cma node and phandle names
- Elaborate the comment to explain 160MiB calculation
- Move &hdmi_receiver_cma to the rock5b dts file
- Add information about interlaced video testing in the
cover-letter

Changes in v2 :-
- Fix checkpatch --strict warnings
- Move the dt-binding include file changes in a separate patch
- Add a description for the hardware in the dt-bindings file
- Rename resets, vo1 grf and HPD properties
- Add a proper description for grf and vo1-grf phandles in the
bindings
- Rename the HDMI RX node name to hdmi-receiver
- Include gpio header file in binding example to fix the
dt_binding_check failure
- Move hdmirx_cma node to the rk3588.dtsi file
- Add an entry to MAINTAINERS file for the HDMIRX driver

Shreeya Patel (4):
  MAINTAINERS: Add entry for Synopsys DesignWare HDMI RX Driver
  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       |  132 +
 MAINTAINERS                                   |    8 +
 .../dts/rockchip/rk3588-base-pinctrl.dtsi     |   14 +
 .../arm64/boot/dts/rockchip/rk3588-extra.dtsi |   57 +
 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    |   27 +
 .../media/platform/synopsys/hdmirx/Makefile   |    4 +
 .../platform/synopsys/hdmirx/snps_hdmirx.c    | 2662 +++++++++++++++++
 .../platform/synopsys/hdmirx/snps_hdmirx.h    |  394 +++
 .../synopsys/hdmirx/snps_hdmirx_cec.c         |  283 ++
 .../synopsys/hdmirx/snps_hdmirx_cec.h         |   44 +
 14 files changed, 3633 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 shreeya.patel at collabora.com  Mon Dec  9 12:02:02 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Mon, 9 Dec 2024 20:02:02 +0000
Subject: [PATCH v5 1/4] MAINTAINERS: Add entry for Synopsys DesignWare HDMI RX Driver
Message-ID: <01020193ad03b755-9daf2dc6-b077-4f66-af12-8a7ad4b2ae13-000000@eu-west-1.amazonses.com>

Add an entry for Synopsys DesignWare HDMI Receiver Controller
Driver.

Reviewed-by: Christopher Obbard <chris.obbard at collabora.com>
Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
---

Changes in v5 :-
- Added a missing closing bracket for the email

Changes in v4 :-
- No change

Changes in v3 :-
- No change

Changes in v2 :-
- Add a patch for MAINTAINERS file changes

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7700208f6ccf..3960c3ca1849 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22768,6 +22768,14 @@ F:	drivers/net/pcs/pcs-xpcs.c
 F:	drivers/net/pcs/pcs-xpcs.h
 F:	include/linux/pcs/pcs-xpcs.h
 
+SYNOPSYS DESIGNWARE HDMI RX CONTROLLER DRIVER
+M:	Shreeya Patel <shreeya.patel at collabora.com>
+L:	linux-media at vger.kernel.org
+L:	kernel at collabora.com
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
+F:	drivers/media/platform/synopsys/hdmirx/*
+
 SYNOPSYS DESIGNWARE I2C DRIVER
 M:	Jarkko Nikula <jarkko.nikula at linux.intel.com>
 R:	Andy Shevchenko <andriy.shevchenko at linux.intel.com>
-- 
2.39.2



From shreeya.patel at collabora.com  Mon Dec  9 12:02:42 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Mon, 9 Dec 2024 20:02:42 +0000
Subject: [PATCH v5 3/4] arm64: dts: rockchip: Add device tree support for HDMI RX Controller
In-Reply-To: <20241209200120.3228643-1-shreeya.patel@collabora.com>
References: <20241209200120.3228643-1-shreeya.patel@collabora.com>
Message-ID: <01020193ad045582-afdad76d-ab76-4e3e-bf93-6951ed6219a8-000000@eu-west-1.amazonses.com>

Add device tree support for Synopsys DesignWare HDMI RX
Controller.

Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
Tested-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
Co-developed-by: Dingxian Wen <shawn.wen at rock-chips.com>
Signed-off-by: Dingxian Wen <shawn.wen at rock-chips.com>
Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
---

Changes in v5 :-
- Add alignment property to ensure hdmi-receiver-cma
  starts at a 64KB-aligned address
- Correct one of the interrupt IRQ number

Changes in v4 :-
- Remove DTS changes added to this patch
- Remove the HDMI RX pin nodes as it's already present
  in the rk3588-base-pinctrl.dtsi

Changes in v3 :-
- Rename cma node and phandle names
- Elaborate the comment to explain 160MiB calculation
- Move &hdmi_receiver_cma to the rock5b dts file

Changes in v2 :-
- Fix some of the checkpatch errors and warnings
- Rename resets, vo1-grf and HPD
- Move hdmirx_cma node to the rk3588.dtsi file

 .../dts/rockchip/rk3588-base-pinctrl.dtsi     | 14 +++++
 .../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 57 +++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
index 7f874c77410c..2d4b9986a177 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
@@ -594,6 +594,20 @@ hdmim0_tx1_hpd: hdmim0-tx1-hpd {
 				/* hdmim0_tx1_hpd */
 				<1 RK_PA6 5 &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 =
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
index ead151941e84..bde1efdf1824 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -7,6 +7,30 @@
 #include "rk3588-extra-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.
+		 * The size of 160MB was determined as follows:
+		 * (3840 * 2160 pixels) * (4 bytes/pixel) * (2 frames/buffer) / 10^6 = 66MB
+		 * To ensure sufficient support for practical use-cases,
+		 * we doubled the 66MB value.
+		 */
+		hdmi_receiver_cma: hdmi-receiver-cma {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x0 0x0 0xffffffff>;
+			size = <0x0 (160 * 0x100000)>; /* 160MiB */
+			alignment = <0x0 0x40000>; /* 64K */
+			no-map;
+			status = "disabled";
+		};
+	};
+
 	usb_host1_xhci: usb at fc400000 {
 		compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
 		reg = <0x0 0xfc400000 0x0 0x400000>;
@@ -135,6 +159,39 @@ i2s10_8ch: i2s at fde00000 {
 		status = "disabled";
 	};
 
+	hdmi_receiver: hdmi_receiver 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 178 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 = "axi", "apb", "ref", "biu";
+		memory-region = <&hdmi_receiver_cma>;
+		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 arnd at arndb.de  Mon Dec  9 12:04:30 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 09 Dec 2024 21:04:30 +0100
Subject: [PATCH v2 2/2] firmware/arm_ffa: remove __le64_to_cpu() when set uuid for
 direct msg v2
In-Reply-To: <Z1ch52AthTYVhtH4@bogus>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
 <20241203143109.1030514-3-yeoreum.yun@arm.com>
 <9e60e996-070e-43a7-80e9-efdfda9f6223@app.fastmail.com>
 <Z1ch52AthTYVhtH4@bogus>
Message-ID: <0cb655ee-9401-41bb-b9cd-580e0aeef2be@app.fastmail.com>

On Mon, Dec 9, 2024, at 17:59, Sudeep Holla wrote:
> On Mon, Dec 09, 2024 at 04:27:14PM +0100, Arnd Bergmann wrote:
>
>> > That means, we don't need to swap the uuid when it send via direct
>> > message request version 2, just send it as saved in memory.
>>
>> "As saved in memory" does not sound like a useful description
>> when passing arguments through registers, as the register
>> contents are not defined in terms of byte offsets.
>>
>
> Well I didn't know how to term it. The structure UUID is a raw buffer
> and it provide helpers to import/export the data in/out of it. So in LE
> kernel IIUC, it is stored in LE format itself which was my initial
> confusion and hence though what you fixed was correct previously.

The way I would phrase it, the UUID is never "stored" in
big-endian or little-endian format, it's just remains a string
of bytes. The endianess becomes a choice only when loading it
into registers for passing the argument to firmware, and it's
the firmware that mandates little-endian in the specification.

>> Can you describe what bug you found? If the byteorder on
>> big-endian kernels is wrong in the current version and your
>> patch fixes it, it sounds like the specification needs to
>> be updated describe both big-endian and little-endian
>> byte-order, and how the firmware detects which one is used.
>>
>
> The firmware interface understands only LE format. And by default UUID
> is stored in LE format itself in the structure which I got confused
> initially. We may need endian conversion at places(found few when trying
> to get it working with BE kernel).
>
> I wanted to check with you about this. The current driver doesn't
> work with BE. I tried to cook up patches but then the upstream user
> of this driver OPTEE doesn't work in BE, so I hit a roadblock to fully
> validate my changes. I don't see any driver adding endianness dependency
> in the Kconfig if they can't work with BE, not sure if that
> is intentional or just don't care. I was thinking if we can disable
> it to build in BE kernel until the actual support was added.

I think as long big-endian kernels remain an option on arm64, we
should try to to write portable code and implement the specification
The reality of course is that very few people care these days, and
it's getting harder to test over time.

> So the current FF-A driver just supports LE and the bug was found just
> in LE kernel itself.

What is the bug and how was it found? The only thing I see in
the patch here is to change the code from portable to nonportable,
but not actually change behavior on little-endian 64-bit.

Looking through the other functions in drivers/firmware/arm_ffa/driver.c,
I see that most of them just match the specification. One exception
is ffa_notification_info_get(), which incorrectly casts the
argument response arguments to an array of 'u16' values. Using
the correct bit shifts according to the specification would
make that work on big-endian and also more readable and
robust. Another one is __ffa_partition_info_get_regs(), which
does an incorrect memcpy() instead of decoding the values.


     Arnd


From nfraprado at collabora.com  Mon Dec  9 12:07:07 2024
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Mon, 9 Dec 2024 17:07:07 -0300
Subject: [PATCH] ASoC: mediatek: mt8188: Enable apll1 clock during reg rw
 to prevent hang
In-Reply-To: <1d2ee55dde84bcab6f777525042c6789b9f2c1fc.camel@mediatek.com>
References: <20241203-mt8188-afe-fix-hang-disabled-apll1-clk-v1-1-07cdd7760834@collabora.com>
 <a10dbdf265194e77a69b6e40afa3df9636b3ab14.camel@mediatek.com>
 <a70a0521-985d-43a4-a1fa-36eb733d5ca9@collabora.com>
 <1d2ee55dde84bcab6f777525042c6789b9f2c1fc.camel@mediatek.com>
Message-ID: <108d4187-26af-43f6-8b1e-0e48516524a4@notapiano>

On Fri, Dec 06, 2024 at 06:57:00AM +0000, Trevor Wu (???) wrote:
> On Thu, 2024-12-05 at 13:51 +0100, AngeloGioacchino Del Regno wrote:
> > 
> > 
> > Il 04/12/24 13:17, Trevor Wu (???) ha scritto:
> > > On Tue, 2024-12-03 at 17:07 -0300, N?colas F. R. A. Prado wrote:
> > > 
> > > > 
> > > > Currently, booting the Genio 700 EVK board with the MT8188 sound
> > > > platform driver configured as a module (CONFIG_SND_SOC_MT8188=m)
> > > > results
> > > > in a system hang right when the HW registers for the audio
> > > > controller
> > > > are read:
> > > > 
> > > >    mt8188-audio 10b10000.audio-controller: No cache defaults,
> > > > reading
> > > > back from HW
> > > > 
> > > > The hang doesn't occur with the driver configured as builtin as
> > > > then
> > > > the
> > > > unused clocks are still enabled.
> > > > 
> > > > Enable the apll1 clock during register read/write to prevent the
> > > > hang.
> > > > 
> > > > Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> > > > ---
> > > >   sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 4 ++++
> > > >   1 file changed, 4 insertions(+)
> > > > 
> > > > diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > index
> > > > e69c1bb2cb239596dee50b166c20192d5408be10..fb8cf286df3f02ac076528b
> > > > 898f
> > > > d0d7a708ec1ea 100644
> > > > --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > @@ -587,6 +587,8 @@ int mt8188_afe_enable_reg_rw_clk(struct
> > > > mtk_base_afe *afe)
> > > >          mt8188_afe_enable_clk(afe, afe_priv-
> > > > > clk[MT8188_CLK_AUD_A1SYS_HP]);
> > > > 
> > > >          mt8188_afe_enable_clk(afe, afe_priv-
> > > > > clk[MT8188_CLK_AUD_A1SYS]);
> > > > 
> > > > +       mt8188_afe_enable_clk(afe, afe_priv-
> > > > > clk[MT8188_CLK_APMIXED_APLL1]);
> > > > 
> > > > +
> > > >          return 0;
> > > >   }
> > > 
> > > Hi Nicolas,
> > > 
> > > If I understand correctly, APLL1 should be the parent clock of
> > > AUD_A1SYS_HP and AUD_A1SYS, so it should be enabled automatically
> > > by
> > > CCF.
> > > 
> > > I'm not sure why you resolved the hang issue after enabling APLL1.
> > > Could you share more details about the solution?
> > > 
> > 
> > Hmm. Now I see what's happening here...
> > 
> > Nicolas, Trevor,
> > 
> > Possible parents for top_a1sys_hp are:
> >   - clk26m
> >   - apll1_d4
> > 
> > ...what's happening here most probably is that after the clock gets
> > disabled as
> > unused, it gets parented to clk26m by default as that is parent index
> > 0... and
> > something else in AFE needs APLL1 to feed a clock to .. something ..
> > to allow
> > register access.
> > 
> > Trevor, do you know why is this IP unaccessible when A1SYS is
> > parented to clk26m?
> 
> Hi Angelo,
> 
> As far as I know, it should work even though the clock is parented to
> clk26m.
> 
> Unfortunately, I have no idea about why APLL1 enabling can resolve the
> hang issue. I'm also curious about how Nicolas found the solution to
> resolve the problem.
> 
> From the description, it seems that the problem is related to register
> r/w hang. If I remembered correctly, when the mtcmos of ADSP_INFRA is
> ON, register r/w won't cause the cpu to hang. However, ADSP_INFRA has
> been configured as ALWAYS_ON in the driver. I'm not sure if it doesn't
> work correctly when the driver is configured as a module. Maybe Nicolas
> can also check this.

Indeed, as suggested by Angelo, adding 

  assigned-clocks = <&topckgen CLK_TOP_A1SYS_HP>;
  assigned-clock-parents = <&topckgen CLK_TOP_APLL1_D4>;

to the afe node also fixes this issue. 

In mt8188.dtsi, we currently have

  afe: audio-controller at 10b10000 {
  	...
  	assigned-clocks = <&topckgen CLK_TOP_A1SYS_HP>;
  	assigned-clock-parents =  <&clk26m>;

So the question is, do other MT8188 platforms need clk26m to be the parent of
a1sys_hp? Depending on that I can either update the parent on the common
mt8188.dtsi or on the genio700-evk.dts, which is where I observed the issue. I
don't have access to other mt8188 platforms. Trevor, do you know?

As for how I identified this issue, I noticed that when booting with the
platform driver as a module the system would hang, and that passing
clk_ignore_unused avoided the issue. Then I selectively ignored some unused
clocks until I narrowed down to ignoring unused only the apll1 clock, meaning
the apll1 clock needed to be left on during the platform driver probe for the
system to not hang.

Thanks,
N?colas

> 
> Thanks,
> Trevor
> 
> > 
> > That might give Nicolas a definitive hint about how to resolve this
> > issue.
> > 
> > Cheers,
> > Angelo
> > 
> > > Thanks,
> > > Trevor
> > > 
> > > > 
> > > > @@ -594,6 +596,8 @@ int mt8188_afe_disable_reg_rw_clk(struct
> > > > mtk_base_afe *afe)
> > > >   {
> > > >          struct mt8188_afe_private *afe_priv = afe-
> > > > >platform_priv;
> > > > 
> > > > +       mt8188_afe_disable_clk(afe, afe_priv-
> > > > > clk[MT8188_CLK_APMIXED_APLL1]);
> > > > 
> > > > +
> > > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > > clk[MT8188_CLK_AUD_A1SYS]);
> > > > 
> > > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > > clk[MT8188_CLK_AUD_A1SYS_HP]);
> > > > 
> > > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > > clk[MT8188_CLK_AUD_AFE]);
> > > > 
> > > > ---
> > > > base-commit: b852e1e7a0389ed6168ef1d38eb0bad71a6b11e8
> > > > change-id: 20241203-mt8188-afe-fix-hang-disabled-apll1-clk-
> > > > b3c11782cbaf
> > > > 
> > > > Best regards,
> > > > --
> > > > N?colas F. R. A. Prado <nfraprado at collabora.com>
> > > > 
> > > > 
> > 
> > 


From nunodasneves at linux.microsoft.com  Mon Dec  9 12:20:14 2024
From: nunodasneves at linux.microsoft.com (Nuno Das Neves)
Date: Mon, 9 Dec 2024 12:20:14 -0800
Subject: [PATCH 0/2] hyperv: Move some features to common code
In-Reply-To: <SN6PR02MB41573F55DBAAF124CFD92840D4332@SN6PR02MB4157.namprd02.prod.outlook.com>
References: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
 <SN6PR02MB41573F55DBAAF124CFD92840D4332@SN6PR02MB4157.namprd02.prod.outlook.com>
Message-ID: <6cf69fbd-b6a0-4e88-85a6-749a4e2dbdaa@linux.microsoft.com>

On 12/7/2024 6:59 PM, Michael Kelley wrote:
> From: Nuno Das Neves <nunodasneves at linux.microsoft.com> Sent: Friday, December 6, 2024 2:22 PM
>>
>> There are several bits of Hyper-V-related code that today live in
>> arch/x86 but are not really specific to x86_64 and will work on arm64
>> too.
>>
>> Some of these will be needed in the upcoming mshv driver code (for
>> Linux as root partition on Hyper-V).
> 
> Previously, Linux as the root partition on Hyper-V was x86 only, which is
> why the code is currently under arch/x86. So evidently the mshv driver
> is being expanded to support both x86 and arm64, correct? Assuming
> that's the case, I have some thoughts about how the source code should
> be organized and built. It's probably best to get this right to start with so
> it doesn't need to be changed again.

Yes, we plan on supporting both architectures (eventually). I completely agree
that it's better to sort out these issues now rather than later.

> 
> * Patch 2 of this series moves hv_call_deposit_pages() and
>    hv_call_create_vp() to common code, but does not move
>    hv_call_add_logical_proc(). All three are used together, so
>    I'm wondering why hv_call_add_logical_proc() isn't moved.
> 

The only reason is that in our internal tree there's no common or arm64 code
yet that uses it - there is no reason it can't also become common code!

> * These three functions were originally put in a separate source
>    code file because of being specific to running in the root partition,
>    and not needed for generic Linux guest support. I think there's
>    value in keeping them in a separate file, rather than merging them
>    into hv_common.c. Maybe just move the entire hv_proc.c file?

Agreed. I think it should be renamed too - this file will eventually
contain some additional hypercall helper functions, some of which may also be
shared by the driver code. Something like "hv_call_common.c"?

>    And then later, perhaps move the entire irqdomain.c file as well?
Yes, may as well move it too.

>    There's also an interesting question of whether to move them into
>    drivers/hv, or create a new directory virt/hyperv. Hyper-V support
>    started out 15 years ago structured as a driver, hence "drivers/hv".
>    But over the time, the support has become significantly more than
>    just a driver, so "virt/hyperv" might be a better location for
>    non-driver code that had previously been under arch/x86 but is
>    now common to all architectures.
> 
I'd be fine with using "virt/hyperv", but I thought "virt" was only for
KVM.

Another option would be to create subdirectories in "drivers/hv" to
organize the different modules more cleanly (i.e. when the /dev/mshv
driver code is introduced).

> * Today, the code for running in the root partition is built along
>    with the rest of the Hyper-V support, and so is present in kernels
>    built for normal Linux guests on Hyper-V. I haven't thought about
>    all the implications, but perhaps there's value in having a CONFIG
>    option to build for the root partition, so that code can be dropped
>    from normal kernels. There's a significant amount of new code still
>    to come for mshv that could be excluded from normal guests in this
>    way. Also, the tests of the hv_root_partition variable could be
>    changed to a function the compiler detects is always "false" in a
>    kernel built without the CONFIG option, in which case it can drop
>    the code for where hv_root_partition is "true".
> 
Using hv_root_partition is a good way to do it, since it won't require
many #ifdefs or moving the existing code around too much.

I can certainly give it a try, and create a separate patch series
introducing the option. I suppose "CONFIG_HYPERV_ROOT" makes sense as a
name?

> * The code currently in hv_proc.c is built for x86 only, and validly
>    assumes the page size is 4K. But when the code moves to be
>    common across architectures, that assumption is no longer
>    valid in the general case. Perhaps the intent is that kernels for
>    the root partition should always be built with page size 4K on
>    arm64, but nothing enforces that intent. Personally, I think the code
>    should be made to work with page sizes other than 4K so as to not
>    leave technical debt. But I realize you may have other priorities. If
>    there were a CONFIG option for building for the root partition,
>    that option could be setup to enforce the 4K page size on arm64.
> 
That makes sense. I suppose this can be done by selecting PAGE_SIZE_4KB
under HYPERV in drivers/hv/Kconfig?

I'm not how easy it will be to make the code work with different page
sizes, since we use alloc_page() and similar in a few places, assuming 4k.

Thanks
Nuno

> Anyway, thinking through these decisions up front could avoid
> the need for additional moves later on.
> 
> Michael
> 
>> So this is a good time to move
>> them to hv_common.c.
>>
>> Signed-off-by: Nuno Das Neves <nudasnev at microsoft.com>
>>
>> Nuno Das Neves (2):
>>   hyperv: Move hv_current_partition_id to arch-generic code
>>   hyperv: Move create_vp and deposit_pages hvcalls to hv_common.c
>>
>>  arch/arm64/hyperv/mshyperv.c    |   3 +
>>  arch/x86/hyperv/hv_init.c       |  25 +----
>>  arch/x86/hyperv/hv_proc.c       | 144 ---------------------------
>>  arch/x86/include/asm/mshyperv.h |   4 -
>>  drivers/hv/hv_common.c          | 168 ++++++++++++++++++++++++++++++++
>>  include/asm-generic/mshyperv.h  |   4 +
>>  6 files changed, 176 insertions(+), 172 deletions(-)
>>
>> --
>> 2.34.1



From festevam at gmail.com  Mon Dec  9 12:40:02 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Mon,  9 Dec 2024 17:40:02 -0300
Subject: [PATCH] dt-bindings: display: panel-lvds: Add compatible for AUO G084SN05 V9
Message-ID: <20241209204003.1295503-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

The AUO G084SN05 V9 is a 8.4" 800x600 LVDS display.

Add a compatible entry for this LVDS display model.

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 Documentation/devicetree/bindings/display/panel/panel-lvds.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
index 5af2d6930075..fcb5834f799a 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
@@ -42,6 +42,8 @@ properties:
           # Admatec 9904379 10.1" 1024x600 LVDS panel
           - admatec,9904379
           - auo,b101ew05
+          # AUO G084SN05 V9 8.4" 800x600 LVDS panel
+          - auo,g084sn05
           # Chunghwa Picture Tubes Ltd. 7" WXGA (800x1280) TFT LCD LVDS panel
           - chunghwa,claa070wp03xg
           # EDT ETML0700Z9NDHA 7.0" WSVGA (1024x600) color TFT LCD LVDS panel
-- 
2.34.1



From festevam at gmail.com  Mon Dec  9 12:40:03 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Mon,  9 Dec 2024 17:40:03 -0300
Subject: [PATCH 2/2] arm64: dts: imx8mm-phg: Add LVDS compatible string
In-Reply-To: <20241209204003.1295503-1-festevam@gmail.com>
References: <20241209204003.1295503-1-festevam@gmail.com>
Message-ID: <20241209204003.1295503-2-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

The imx8mm-phg board has an AUO G084SN05 V9 8.4" 800x600 LVDS panel.

Improve the devicetree description by passing the LVDS compatible
string to fix the following dt-schema warning:

imx8mm-phg.dtb: panel: compatible:0: 'panel-lvds' is not one of
['admatec,9904379', 'auo,b101ew05', 'auo,g084sn05',
'chunghwa,claa070wp03xg','edt,etml0700z9ndha', 'hannstar,hsd101pww2',
'hydis,hv070wx2-1e0', 'jenson,bl-jt60050-01a', 'tbs,a711-panel']
...

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 arch/arm64/boot/dts/freescale/imx8mm-phg.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phg.dts b/arch/arm64/boot/dts/freescale/imx8mm-phg.dts
index 75bbedc6164c..a134b1833649 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phg.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phg.dts
@@ -82,7 +82,7 @@ reg_usdhc2_vmmc: regulator-vmmc {
 	};
 
 	panel {
-		compatible = "panel-lvds";
+		compatible = "auo,g084sn05", "panel-lvds";
 		width-mm = <170>;
 		height-mm = <28>;
 		data-mapping = "jeida-18";
-- 
2.34.1



From quic_akhilpo at quicinc.com  Mon Dec  9 12:52:27 2024
From: quic_akhilpo at quicinc.com (Akhil P Oommen)
Date: Tue, 10 Dec 2024 02:22:27 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>
Message-ID: <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>

On 12/10/2024 1:24 AM, Rob Clark wrote:
> On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
>>
>> When kernel is booted in EL2, SECVID registers are accessible to the
>> KMD. So we can use that to switch GPU's secure mode to avoid dependency
>> on Zap firmware. Also, we can't load a secure firmware without a
>> hypervisor that supports it.
> 
> Shouldn't we do this based on whether zap node is in dtb (and not disabled)?

This is better, isn't it? Otherwise, multiple overlays should be
maintained for each soc/board since EL2 can be toggled from bootloader.
And this feature is likely going to be more widely available.

-Akhil.

> 
> slbounce applies some dtb overlays to disable the zap node when
> booting in EL2 (and make some other changes due to kernel being in
> control of the pci smmuv3, or something along those lines).
> 
> BR,
> -R
> 
>>
>> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
>>
>> 1. Gunyah (No KVM) - Loads zap shader based on DT
>> 2. KVM in VHE - Skips zap shader load and programs SECVID register
>> 3. KVM in nVHE - Loads zap shader based on DT
>> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
>>         programs SECVID register
>>
>> For (1) and (3) configuration, this patch doesn't have any impact.
>> Driver loads secure firmware based on other existing hints.
>>
>> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
>> ---
>> ---
>>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 +++++++++++++++++++++++------------
>>  1 file changed, 54 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> index 019610341df1..9dcaa8472430 100644
>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> @@ -14,6 +14,10 @@
>>  #include <linux/pm_domain.h>
>>  #include <linux/soc/qcom/llcc-qcom.h>
>>
>> +#ifdef CONFIG_ARM64
>> +#include <asm/virt.h>
>> +#endif
>> +
>>  #define GPU_PAS_ID 13
>>
>>  static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
>> @@ -998,6 +1002,54 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
>>         return ret;
>>  }
>>
>> +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
>> +{
>> +       int ret;
>> +
>> +#ifdef CONFIG_ARM64
>> +       /*
>> +        * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
>> +        * to switch the secure mode to avoid the dependency on zap shader.
>> +        */
>> +       if (is_kernel_in_hyp_mode())
>> +               goto direct_switch;
>> +#endif
>> +
>> +       /*
>> +        * Try to load a zap shader into the secure world. If successful
>> +        * we can use the CP to switch out of secure mode. If not then we
>> +        * have no resource but to try to switch ourselves out manually. If we
>> +        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
>> +        * be blocked and a permissions violation will soon follow.
>> +        */
>> +       ret = a6xx_zap_shader_init(gpu);
>> +       if (ret == -ENODEV) {
>> +               /*
>> +                * This device does not use zap shader (but print a warning
>> +                * just in case someone got their dt wrong.. hopefully they
>> +                * have a debug UART to realize the error of their ways...
>> +                * if you mess this up you are about to crash horribly)
>> +                */
>> +               dev_warn_once(gpu->dev->dev,
>> +                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
>> +               goto direct_switch;
>> +       } else if (ret)
>> +               return ret;
>> +
>> +       OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
>> +       OUT_RING(gpu->rb[0], 0x00000000);
>> +
>> +       a6xx_flush(gpu, gpu->rb[0]);
>> +       if (!a6xx_idle(gpu, gpu->rb[0]))
>> +               return -EINVAL;
>> +
>> +       return 0;
>> +
>> +direct_switch:
>> +       gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
>> +       return 0;
>> +}
>> +
>>  #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
>>                        A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
>>                        A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
>> @@ -1341,35 +1393,9 @@ static int hw_init(struct msm_gpu *gpu)
>>         if (ret)
>>                 goto out;
>>
>> -       /*
>> -        * Try to load a zap shader into the secure world. If successful
>> -        * we can use the CP to switch out of secure mode. If not then we
>> -        * have no resource but to try to switch ourselves out manually. If we
>> -        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
>> -        * be blocked and a permissions violation will soon follow.
>> -        */
>> -       ret = a6xx_zap_shader_init(gpu);
>> -       if (!ret) {
>> -               OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
>> -               OUT_RING(gpu->rb[0], 0x00000000);
>> -
>> -               a6xx_flush(gpu, gpu->rb[0]);
>> -               if (!a6xx_idle(gpu, gpu->rb[0]))
>> -                       return -EINVAL;
>> -       } else if (ret == -ENODEV) {
>> -               /*
>> -                * This device does not use zap shader (but print a warning
>> -                * just in case someone got their dt wrong.. hopefully they
>> -                * have a debug UART to realize the error of their ways...
>> -                * if you mess this up you are about to crash horribly)
>> -                */
>> -               dev_warn_once(gpu->dev->dev,
>> -                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
>> -               gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
>> -               ret = 0;
>> -       } else {
>> +       ret = a6xx_switch_secure_mode(gpu);
>> +       if (!ret)
>>                 return ret;
>> -       }
>>
>>  out:
>>         if (adreno_has_gmu_wrapper(adreno_gpu))
>>
>> ---
>> base-commit: f4a867a46862c1743501bbe8c813238456ec8699
>> change-id: 20241120-drm-msm-kvm-support-cd6e6744ced6
>>
>> Best regards,
>> --
>> Akhil P Oommen <quic_akhilpo at quicinc.com>
>>



From quic_akhilpo at quicinc.com  Mon Dec  9 12:54:27 2024
From: quic_akhilpo at quicinc.com (Akhil P Oommen)
Date: Tue, 10 Dec 2024 02:24:27 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <08440076-3c04-4bb1-b339-071b82d638d2@oss.qualcomm.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <08440076-3c04-4bb1-b339-071b82d638d2@oss.qualcomm.com>
Message-ID: <a3f39ee2-cdb6-4d54-a5db-6208e435972c@quicinc.com>

On 12/9/2024 8:33 PM, Konrad Dybcio wrote:
> On 9.12.2024 9:19 AM, Akhil P Oommen wrote:
>> When kernel is booted in EL2, SECVID registers are accessible to the
>> KMD. So we can use that to switch GPU's secure mode to avoid dependency
>> on Zap firmware. Also, we can't load a secure firmware without a
>> hypervisor that supports it.
>>
>> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
>>
>> 1. Gunyah (No KVM) - Loads zap shader based on DT
>> 2. KVM in VHE - Skips zap shader load and programs SECVID register
>> 3. KVM in nVHE - Loads zap shader based on DT
>> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
>> 	programs SECVID register
>>
>> For (1) and (3) configuration, this patch doesn't have any impact.
>> Driver loads secure firmware based on other existing hints.
>>
>> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
>> ---
> 
> [...]
> 
>> +
>> +#ifdef CONFIG_ARM64
>> +	/*
>> +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
>> +	 * to switch the secure mode to avoid the dependency on zap shader.
>> +	 */
>> +	if (is_kernel_in_hyp_mode())
>> +		goto direct_switch;
> 
> So I suppose this would ideally be like hv_is_hyperv_initialized()
> but for QHEE/Gunyah, which is not going to happen, as we have
> millions of devices with old unupstreamable-ABI-Gunyah running..
> 
> This looks like the next best things then, so no objections, but..
> 
> [...]
> 
>> +	ret = a6xx_switch_secure_mode(gpu);
>> +	if (!ret)
> 
> this should definitely be a if (ret)

My bad! Thanks.

-Akhil.
> 
> Konrad



From heiko at sntech.de  Mon Dec  9 13:13:47 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 09 Dec 2024 22:13:47 +0100
Subject: [PATCH v5 0/4] Add Synopsys DesignWare HDMI RX Controller
In-Reply-To: <01020193ad025176-f2e8e4fd-41a6-42ef-b3d0-dfa87a6d0abd-000000@eu-west-1.amazonses.com>
References: <01020193ad025176-f2e8e4fd-41a6-42ef-b3d0-dfa87a6d0abd-000000@eu-west-1.amazonses.com>
Message-ID: <7197326.aoefvbuG5b@diego>

Hi Shreeya,

Am Montag, 9. Dezember 2024, 21:00:30 CET schrieb Shreeya Patel:
> This series implements support for the Synopsys DesignWare
> HDMI RX Controller, being compliant with standard HDMI 1.4b
> and HDMI 2.0.

could you take a look at your mail-setup please?

This cover-letter came with a message-id of 
01020193ad025176-f2e8e4fd-41a6-42ef-b3d0-dfa87a6d0abd-000000 at eu-west-1.amazonses.com

same for patch1 that also got an amazon-message-id and lost its
in-reply-to reference,

while the patches  2-4 have correct message-ids and reference
20241209200120.3228643-1-shreeya.patel at collabora.com

as their parent. So it looks like some amazon service did some
rewriting and broke threading :-( .

Thanks a lot
Heiko

> 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 :-
> * HDMIRX driver now only works with the opensource TF-A.
> * We have tested the working of OBS studio with HDMIRX driver and
> there were no issues seen.
> * We also tested and verified the support for interlaced video.
> 
> 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
> 
> CEC compliance test results :-
> 
> * https://gitlab.collabora.com/-/snippets/380
> * https://gitlab.collabora.com/-/snippets/381
> 
> Following is the v4l2-compliance test result :-
> 
> root at debian-rockchip-rock5b-rk3588:~# v4l2-compliance -d /dev/video0 
> v4l2-compliance 1.29.0-5278, 64 bits, 64-bit time_t
> v4l2-compliance SHA: 791da13728d9 2024-11-25 10:01:57
> 
> Compliance test for snps_hdmirx device /dev/video0:
> 
> Driver Info:
> 	Driver name      : snps_hdmirx
> 	Card type        : snps_hdmirx
> 	Bus info         : platform:fdee0000.hdmi_receiver
> 	Driver version   : 6.12.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: 4 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_REMOVE_BUFS: OK
> 	test VIDIOC_EXPBUF: OK
> 	test Requests: OK (Not Supported)
> 	test blocking wait: OK
> 
> Total for snps_hdmirx device /dev/video0: 48, Succeeded: 48, Failed: 0, Warnings: 0
> 
> 
> Changes in v5 :-
> - Fix the interrupt IRQ number in the dt-bindings and device tree
> - Add alignment property to ensure hdmi-receiver-cma
>   starts at a 64KB-aligned address
> - Change the MODULE_DESCRIPTION
> - Add VIDEO_SYNOPSYS_HDMIRX as prefix to the default edid config
> - Drop the enabling of default edid in the Kconfig
> - Replace the default EDID with hdmi-4k-300mhz EDID produced
>   by v4l2-ctl tool for better compatibility with various HDMI
>   cables and adapters
> - Rework the write_edid and set_edid functions
> - During format change, retrieve the current pixel format,
>   color depth, and AVI infoframe details instead of only
>   detecting the format
> - Improve the logging mechanism and delays in the
>   hdmirx_wait_signal_lock function
> - Fix the 4K at 60 capturing for RGB format
> - Document what hdmirx_check_timing_valid function does
> - Rework the hdmirx_get_detected_timings function
> - Fix the NV16/24 size image value
> - Add the implementation from Benjamin Hoff to expose the
>   ITC type to v4l2
> - Remove all the firmware related code
> 
> Changes in v4 :-
> - Remove DTS changes included in the device tree patch
> - Remove the hdmi rx pin info as it's already present
> in the rk3588-base-pinctrl.dtsi
> - Create a separate config option for selecting the EDID
> and enable it by default
> - Improve the comment related to DV timings and move it
> to the side of hdmirx_get_detected_timings
> - Add 100ms delay before pulling the HPD high
> - Do not return the detected timings from VIDIOC_G_DV_TIMINGS
> - Drop the bus info from hdmirx_querycap
> - If *num_planes != 0 then return 0 in hdmirx_queue_setup
> - Set queue->min_queued_buffers to 1
> - Drop q->allow_cache_hints = 0; as it's always 0 by default
> - Add a comment for q->dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
> - Drop .read = vb2_fop_read as it's not supported by driver
> - Remove redundant edid_init_data_600M
> - Make HPD low when driver is loaded
> - Add support for reading AVI Infoframe
> - Remove msg_len checks from hdmirx_cec_transmit
> - Add info about the CEC compliance test in the cover letter
> - Add arbitration lost status
> - Validate the physical address inside the EDID
> 
> Changes in v3 :-
> - Use v4l2-common helpers in the HDMIRX driver
> - Rename cma node and phandle names
> - Elaborate the comment to explain 160MiB calculation
> - Move &hdmi_receiver_cma to the rock5b dts file
> - Add information about interlaced video testing in the
> cover-letter
> 
> Changes in v2 :-
> - Fix checkpatch --strict warnings
> - Move the dt-binding include file changes in a separate patch
> - Add a description for the hardware in the dt-bindings file
> - Rename resets, vo1 grf and HPD properties
> - Add a proper description for grf and vo1-grf phandles in the
> bindings
> - Rename the HDMI RX node name to hdmi-receiver
> - Include gpio header file in binding example to fix the
> dt_binding_check failure
> - Move hdmirx_cma node to the rk3588.dtsi file
> - Add an entry to MAINTAINERS file for the HDMIRX driver
> 
> Shreeya Patel (4):
>   MAINTAINERS: Add entry for Synopsys DesignWare HDMI RX Driver
>   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       |  132 +
>  MAINTAINERS                                   |    8 +
>  .../dts/rockchip/rk3588-base-pinctrl.dtsi     |   14 +
>  .../arm64/boot/dts/rockchip/rk3588-extra.dtsi |   57 +
>  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    |   27 +
>  .../media/platform/synopsys/hdmirx/Makefile   |    4 +
>  .../platform/synopsys/hdmirx/snps_hdmirx.c    | 2662 +++++++++++++++++
>  .../platform/synopsys/hdmirx/snps_hdmirx.h    |  394 +++
>  .../synopsys/hdmirx/snps_hdmirx_cec.c         |  283 ++
>  .../synopsys/hdmirx/snps_hdmirx_cec.h         |   44 +
>  14 files changed, 3633 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
> 
> 






From Frank.Li at nxp.com  Mon Dec  9 13:53:03 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 16:53:03 -0500
Subject: [PATCH 0/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
Message-ID: <20241209-imx91tmu-v1-0-7859c5387f31@nxp.com>

- Add binding doc
- Add imx91 thermal driver
- dts part wait for https://lore.kernel.org/imx/Z04W5chGq5TitB9f at lizhi-Precision-Tower-5810/
merged, so not in this serial.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Pengfei Li (2):
      dt-bindings: thermal: fsl,imx91-tmu: add bindings for NXP i.MX91 thermal module
      thermal: imx91: Add support for i.MX91 thermal monitoring unit

 .../devicetree/bindings/thermal/fsl,imx91-tmu.yaml |  65 +++++
 drivers/thermal/Kconfig                            |  10 +
 drivers/thermal/Makefile                           |   1 +
 drivers/thermal/imx91_thermal.c                    | 281 +++++++++++++++++++++
 4 files changed, 357 insertions(+)
---
base-commit: d07c576946b2bc440d6d2073998023e8a0bd7568
change-id: 20241209-imx91tmu-af2a7c042d8d

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Mon Dec  9 13:53:04 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 16:53:04 -0500
Subject: [PATCH 1/2] dt-bindings: thermal: fsl,imx91-tmu: add bindings for
 NXP i.MX91 thermal module
In-Reply-To: <20241209-imx91tmu-v1-0-7859c5387f31@nxp.com>
References: <20241209-imx91tmu-v1-0-7859c5387f31@nxp.com>
Message-ID: <20241209-imx91tmu-v1-1-7859c5387f31@nxp.com>

From: Pengfei Li <pengfei.li_1 at nxp.com>

Add bindings documentation for i.MX91 thermal modules.

Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 .../devicetree/bindings/thermal/fsl,imx91-tmu.yaml | 65 ++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml b/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml
new file mode 100644
index 0000000000000..f5898db1006c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/fsl,imx91-tmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX91 Thermal
+
+maintainers:
+  - Pengfei Li <pengfei.li_1 at nxp.com>
+
+description:
+  i.MX91 features a new temperature sensor. It includes programmable
+  temperature threshold comparators for both normal and privileged
+  accesses and allows a programmable measurement frequency for the
+  Periodic One-Shot Measurement mode. Additionally, it provides
+  status registers for indicating the end of measurement and threshold
+  violation events.
+
+properties:
+  compatible:
+    items:
+      - const: fsl,imx91-tmu
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  nvmem-cells:
+    items:
+      - description: Phandle to the trim control 1 provided by ocotp
+      - description: Phandle to the trim control 2 provided by ocotp
+
+  nvmem-cell-names:
+    items:
+      - const: trim1
+      - const: trim2
+
+  "#thermal-sensor-cells":
+    enum: [0, 1]
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#thermal-sensor-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx93-clock.h>
+
+    thermal-sensor at 44482000 {
+        compatible = "fsl,imx91-tmu";
+        reg = <0x44482000 0x1000>;
+        #thermal-sensor-cells = <0>;
+        clocks = <&clk IMX93_CLK_TMC_GATE>;
+        nvmem-cells = <&tmu_trim1>, <&tmu_trim2>;
+        nvmem-cell-names = "trim1", "trim2";
+    };
+
+...

-- 
2.34.1



From Frank.Li at nxp.com  Mon Dec  9 13:53:05 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 09 Dec 2024 16:53:05 -0500
Subject: [PATCH 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241209-imx91tmu-v1-0-7859c5387f31@nxp.com>
References: <20241209-imx91tmu-v1-0-7859c5387f31@nxp.com>
Message-ID: <20241209-imx91tmu-v1-2-7859c5387f31@nxp.com>

From: Pengfei Li <pengfei.li_1 at nxp.com>

Introduce support for the i.MX91 thermal monitoring unit, which features a
single sensor for the CPU. The register layout differs from other chips,
necessitating the creation of a dedicated file for this.

Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/thermal/Kconfig         |  10 ++
 drivers/thermal/Makefile        |   1 +
 drivers/thermal/imx91_thermal.c | 281 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 292 insertions(+)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index d3f9686e26e71..da403ed86aeb1 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -296,6 +296,16 @@ config IMX8MM_THERMAL
 	  cpufreq is used as the cooling device to throttle CPUs when the passive
 	  trip is crossed.
 
+config IMX91_THERMAL
+	tristate "Temperature sensor driver for NXP i.MX91 SoC"
+	depends on ARCH_MXC || COMPILE_TEST
+	depends on OF
+	help
+	  Support for Temperature sensor found on NXP i.MX91 SoC.
+	  It supports one critical trip point and one passive trip point. The
+	  cpufreq is used as the cooling device to throttle CPUs when the passive
+	  trip is crossed.
+
 config K3_THERMAL
 	tristate "Texas Instruments K3 thermal support"
 	depends on ARCH_K3 || COMPILE_TEST
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 9abf43a74f2bb..08da241e6a598 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
 obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
 obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
 obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
+obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
 obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
 obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
 obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
new file mode 100644
index 0000000000000..19c4dafe9c7a9
--- /dev/null
+++ b/drivers/thermal/imx91_thermal.c
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2024 NXP.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/thermal.h>
+
+#define CTRL0			0x0
+
+#define STAT0			0x10
+#define STAT0_DRDY0_IF_MASK	BIT(16)
+
+#define DATA0			0x20
+#define DATA_INT_MASK		GENMASK(14, 7)
+#define DATA_FRAC_MASK		GENMASK(6, 0)
+
+#define THR_CTRL01		0x30
+#define THR_CTRL23		0x40
+
+#define CTRL1			0x200
+#define CTRL1_SET		0x204
+#define CTRL1_CLR		0x208
+#define CTRL1_EN		BIT(31)
+#define CTRL1_START		BIT(30)
+#define CTRL1_STOP		BIT(29)
+#define CTRL1_RES_MASK		GENMASK(19, 18)
+#define CTRL1_MEAS_MODE_MASK	GENMASK(25, 24)
+
+#define PERIOD_CTRL		0x270
+#define MEAS_FREQ_MASK		GENMASK(23, 0)
+
+#define REF_DIV			0x280
+#define DIV_EN			BIT(31)
+#define DIV_MASK		GENMASK(23, 16)
+
+#define PUD_ST_CTRL		0x2B0
+#define PUDL_MASK		GENMASK(23, 16)
+
+#define TRIM1			0x2E0
+#define TRIM2			0x2F0
+
+#define TMU_TEMP_LOW_LIMIT	-40000
+#define TMU_TEMP_HIGH_LIMIT	125000
+
+#define DEFAULT_TRIM1_CONFIG 0xB561BC2DU
+#define DEFAULT_TRIM2_CONFIG 0x65D4U
+
+struct tmu_sensor {
+	struct imx91_tmu *priv;
+	struct thermal_zone_device *tzd;
+};
+
+struct imx91_tmu {
+	void __iomem *base;
+	struct clk *clk;
+	struct device *dev;
+	struct tmu_sensor sensors;
+};
+
+static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
+{
+	if (start)
+		writel_relaxed(CTRL1_START, tmu->base + CTRL1_SET);
+	else
+		writel_relaxed(CTRL1_STOP, tmu->base + CTRL1_SET);
+}
+
+static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
+{
+	if (enable)
+		writel_relaxed(CTRL1_EN, tmu->base + CTRL1_SET);
+	else
+		writel_relaxed(CTRL1_EN, tmu->base + CTRL1_CLR);
+}
+
+static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+	struct tmu_sensor *sensor = thermal_zone_device_priv(tz);
+	struct imx91_tmu *tmu = sensor->priv;
+	int val;
+	int ret;
+
+	ret = readl_relaxed_poll_timeout(tmu->base + STAT0, val,
+					 val & STAT0_DRDY0_IF_MASK, 1000,
+					 40000);
+	if (ret)
+		return -EAGAIN;
+
+	val = readl_relaxed(tmu->base + DATA0) & 0xffffU;
+	*temp = val * 1000L / 64L;
+	if (*temp < TMU_TEMP_LOW_LIMIT || *temp > TMU_TEMP_HIGH_LIMIT)
+		return -EAGAIN;
+
+	return 0;
+}
+
+static struct thermal_zone_device_ops tmu_tz_ops = {
+	.get_temp = imx91_tmu_get_temp,
+};
+
+static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
+{
+	struct device *dev = tmu->dev;
+	int ret;
+	u32 trim1, trim2;
+
+	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
+	if (ret)
+		return ret;
+
+	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
+	if (ret)
+		return ret;
+
+	if (trim1 == 0 || trim2 == 0)
+		return -EINVAL;
+
+	writel_relaxed(trim1, tmu->base + TRIM1);
+	writel_relaxed(trim2, tmu->base + TRIM2);
+
+	return 0;
+}
+
+static int imx91_tmu_probe(struct platform_device *pdev)
+{
+	struct imx91_tmu *tmu;
+	unsigned long rate;
+	u32 div;
+	int ret;
+	int i = 0;
+
+	tmu = devm_kzalloc(&pdev->dev, sizeof(struct imx91_tmu), GFP_KERNEL);
+	if (!tmu)
+		return -ENOMEM;
+
+	tmu->dev = &pdev->dev;
+
+	tmu->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(tmu->base))
+		return PTR_ERR(tmu->base);
+
+	tmu->clk = devm_clk_get_prepared(&pdev->dev, NULL);
+	if (IS_ERR(tmu->clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
+
+	tmu->sensors.priv = tmu;
+	tmu->sensors.tzd = devm_thermal_of_zone_register(&pdev->dev, i, &tmu->sensors, &tmu_tz_ops);
+	if (IS_ERR(tmu->sensors.tzd))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tmu->sensors.tzd),
+				     "failed to register thermal zone sensor\n");
+
+	platform_set_drvdata(pdev, tmu);
+
+	/* disable the monitor during initialization */
+	imx91_tmu_enable(tmu, false);
+	imx91_tmu_start(tmu, false);
+
+	ret = imx91_init_from_nvmem_cells(tmu);
+	if (ret) {
+		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
+		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
+	}
+
+	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
+	rate = clk_get_rate(tmu->clk);
+	div = (rate / 4000000) - 1;
+
+	/* Set divider value and enable divider */
+	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
+
+	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
+	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
+
+	/*
+	 * Set resolution mode
+	 * 00b - Conversion time = 0.59325 ms
+	 * 01b - Conversion time = 1.10525 ms
+	 * 10b - Conversion time = 2.12925 ms
+	 * 11b - Conversion time = 4.17725 ms
+	 */
+	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
+	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);
+
+	/*
+	 * Set measure mode
+	 * 00b - Single oneshot measurement
+	 * 01b - Continuous measurement
+	 * 10b - Periodic oneshot measurement
+	 */
+	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, 0x3), tmu->base + CTRL1_CLR);
+	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, 0x1), tmu->base + CTRL1_SET);
+
+	/*
+	 * Set Periodic Measurement Frequency to 25Hz:
+	 * tMEAS_FREQ = tCONV_CLK * PERIOD_CTRL[MEAS_FREQ]. ->
+	 * PERIOD_CTRL(MEAS_FREQ) = (1000 / 25) / (1000 / 4000000);
+	 * Where tMEAS_FREQ = Measurement period and tCONV_CLK = 1/fCONV_CLK.
+	 * This field should have value greater than count corresponds
+	 * to time greater than summation of conversion time, power up
+	 * delay, and six times of conversion clock time.
+	 * tMEAS_FREQ > (tCONV + tPUD + 6 * tCONV_CLK).
+	 * tCONV is conversion time determined by CTRL1[RESOLUTION].
+	 */
+	writel_relaxed(FIELD_PREP(MEAS_FREQ_MASK, 0x27100), tmu->base + PERIOD_CTRL);
+
+	/* enable the monitor */
+	imx91_tmu_enable(tmu, true);
+	imx91_tmu_start(tmu, true);
+
+	return 0;
+}
+
+static void imx91_tmu_remove(struct platform_device *pdev)
+{
+	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
+
+	/* disable tmu */
+	imx91_tmu_start(tmu, false);
+	imx91_tmu_enable(tmu, false);
+}
+
+static int __maybe_unused imx91_tmu_suspend(struct device *dev)
+{
+	struct imx91_tmu *tmu = dev_get_drvdata(dev);
+
+	/* disable tmu */
+	imx91_tmu_start(tmu, false);
+	imx91_tmu_enable(tmu, false);
+
+	clk_disable_unprepare(tmu->clk);
+
+	return 0;
+}
+
+static int __maybe_unused imx91_tmu_resume(struct device *dev)
+{
+	struct imx91_tmu *tmu = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(tmu->clk);
+	if (ret)
+		return ret;
+
+	imx91_tmu_enable(tmu, true);
+	imx91_tmu_start(tmu, true);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(imx91_tmu_pm_ops,
+			 imx91_tmu_suspend, imx91_tmu_resume);
+
+static const struct of_device_id imx91_tmu_table[] = {
+	{ .compatible = "fsl,imx91-tmu", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, imx91_tmu_table);
+
+static struct platform_driver imx91_tmu = {
+	.driver = {
+		.name	= "i.MX91_thermal",
+		.pm	= pm_ptr(&imx91_tmu_pm_ops),
+		.of_match_table = imx91_tmu_table,
+	},
+	.probe = imx91_tmu_probe,
+	.remove = imx91_tmu_remove,
+};
+module_platform_driver(imx91_tmu);
+
+MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
+MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From robdclark at gmail.com  Mon Dec  9 13:56:44 2024
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 9 Dec 2024 13:56:44 -0800
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com> <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>
Message-ID: <CAF6AEGvBU8mB5HHNK4nP5h9ouKfLNhCMFgF+PhrC77ZMfSOTkQ@mail.gmail.com>

On Mon, Dec 9, 2024 at 12:52?PM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
>
> On 12/10/2024 1:24 AM, Rob Clark wrote:
> > On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> >>
> >> When kernel is booted in EL2, SECVID registers are accessible to the
> >> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> >> on Zap firmware. Also, we can't load a secure firmware without a
> >> hypervisor that supports it.
> >
> > Shouldn't we do this based on whether zap node is in dtb (and not disabled)?
>
> This is better, isn't it? Otherwise, multiple overlays should be
> maintained for each soc/board since EL2 can be toggled from bootloader.
> And this feature is likely going to be more widely available.

I guess the first question is what the dt should look like.  I think
it makes sense to not have a zap node when booting in EL2 (or at least
disabling it) because that describes the hw+fw situation.  And in any
case, so far it seems like we often need unrelated changes[1].  But
maybe others have differing opinions.

And depending on how much cooperation we get from the bootloader, it
could be that our hand is forced.  I figured I should at least point
out how we currently handle this.

A further point, I suppose it is in theory possible that a device
could have no secure playback support, despite booting in EL1?  So
tying this to EL2 seems a bit contrived.

BR,
-R

[1] https://github.com/TravMurav/slbounce/blob/main/dtbo/x1e-el2.dtso

> -Akhil.
>
> >
> > slbounce applies some dtb overlays to disable the zap node when
> > booting in EL2 (and make some other changes due to kernel being in
> > control of the pci smmuv3, or something along those lines).
> >
> > BR,
> > -R
> >
> >>
> >> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
> >>
> >> 1. Gunyah (No KVM) - Loads zap shader based on DT
> >> 2. KVM in VHE - Skips zap shader load and programs SECVID register
> >> 3. KVM in nVHE - Loads zap shader based on DT
> >> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
> >>         programs SECVID register
> >>
> >> For (1) and (3) configuration, this patch doesn't have any impact.
> >> Driver loads secure firmware based on other existing hints.
> >>
> >> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
> >> ---
> >> ---
> >>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 +++++++++++++++++++++++------------
> >>  1 file changed, 54 insertions(+), 28 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> >> index 019610341df1..9dcaa8472430 100644
> >> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> >> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> >> @@ -14,6 +14,10 @@
> >>  #include <linux/pm_domain.h>
> >>  #include <linux/soc/qcom/llcc-qcom.h>
> >>
> >> +#ifdef CONFIG_ARM64
> >> +#include <asm/virt.h>
> >> +#endif
> >> +
> >>  #define GPU_PAS_ID 13
> >>
> >>  static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
> >> @@ -998,6 +1002,54 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
> >>         return ret;
> >>  }
> >>
> >> +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> >> +{
> >> +       int ret;
> >> +
> >> +#ifdef CONFIG_ARM64
> >> +       /*
> >> +        * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> >> +        * to switch the secure mode to avoid the dependency on zap shader.
> >> +        */
> >> +       if (is_kernel_in_hyp_mode())
> >> +               goto direct_switch;
> >> +#endif
> >> +
> >> +       /*
> >> +        * Try to load a zap shader into the secure world. If successful
> >> +        * we can use the CP to switch out of secure mode. If not then we
> >> +        * have no resource but to try to switch ourselves out manually. If we
> >> +        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
> >> +        * be blocked and a permissions violation will soon follow.
> >> +        */
> >> +       ret = a6xx_zap_shader_init(gpu);
> >> +       if (ret == -ENODEV) {
> >> +               /*
> >> +                * This device does not use zap shader (but print a warning
> >> +                * just in case someone got their dt wrong.. hopefully they
> >> +                * have a debug UART to realize the error of their ways...
> >> +                * if you mess this up you are about to crash horribly)
> >> +                */
> >> +               dev_warn_once(gpu->dev->dev,
> >> +                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
> >> +               goto direct_switch;
> >> +       } else if (ret)
> >> +               return ret;
> >> +
> >> +       OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
> >> +       OUT_RING(gpu->rb[0], 0x00000000);
> >> +
> >> +       a6xx_flush(gpu, gpu->rb[0]);
> >> +       if (!a6xx_idle(gpu, gpu->rb[0]))
> >> +               return -EINVAL;
> >> +
> >> +       return 0;
> >> +
> >> +direct_switch:
> >> +       gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
> >> +       return 0;
> >> +}
> >> +
> >>  #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
> >>                        A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
> >>                        A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
> >> @@ -1341,35 +1393,9 @@ static int hw_init(struct msm_gpu *gpu)
> >>         if (ret)
> >>                 goto out;
> >>
> >> -       /*
> >> -        * Try to load a zap shader into the secure world. If successful
> >> -        * we can use the CP to switch out of secure mode. If not then we
> >> -        * have no resource but to try to switch ourselves out manually. If we
> >> -        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
> >> -        * be blocked and a permissions violation will soon follow.
> >> -        */
> >> -       ret = a6xx_zap_shader_init(gpu);
> >> -       if (!ret) {
> >> -               OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
> >> -               OUT_RING(gpu->rb[0], 0x00000000);
> >> -
> >> -               a6xx_flush(gpu, gpu->rb[0]);
> >> -               if (!a6xx_idle(gpu, gpu->rb[0]))
> >> -                       return -EINVAL;
> >> -       } else if (ret == -ENODEV) {
> >> -               /*
> >> -                * This device does not use zap shader (but print a warning
> >> -                * just in case someone got their dt wrong.. hopefully they
> >> -                * have a debug UART to realize the error of their ways...
> >> -                * if you mess this up you are about to crash horribly)
> >> -                */
> >> -               dev_warn_once(gpu->dev->dev,
> >> -                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
> >> -               gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
> >> -               ret = 0;
> >> -       } else {
> >> +       ret = a6xx_switch_secure_mode(gpu);
> >> +       if (!ret)
> >>                 return ret;
> >> -       }
> >>
> >>  out:
> >>         if (adreno_has_gmu_wrapper(adreno_gpu))
> >>
> >> ---
> >> base-commit: f4a867a46862c1743501bbe8c813238456ec8699
> >> change-id: 20241120-drm-msm-kvm-support-cd6e6744ced6
> >>
> >> Best regards,
> >> --
> >> Akhil P Oommen <quic_akhilpo at quicinc.com>
> >>
>


From Frank.li at nxp.com  Mon Dec  9 14:16:21 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 9 Dec 2024 17:16:21 -0500
Subject: [PATCH v11 3/7] PCI: endpoint: pci-ep-msi: Add MSI address/data
 pair mutable check
In-Reply-To: <87h67cprc7.ffs@tglx>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
 <20241209-ep-msi-v11-3-7434fa8397bd@nxp.com>
 <87h67cprc7.ffs@tglx>
Message-ID: <Z1dsNbJxLA4NK8Us@lizhi-Precision-Tower-5810>

On Mon, Dec 09, 2024 at 08:51:52PM +0100, Thomas Gleixner wrote:
> Frank!
>
> On Mon, Dec 09 2024 at 12:48, Frank Li wrote:
>
> > Some MSI controller change address/data pair when irq_set_affinity().
> > Current PCI endpoint can't support this type MSI controller. So add flag
> > MSI_FLAG_MSG_IMMUTABLE in include/linux/msi.h, set this flags in ARM GIC
> > ITS MSI controller and check it when allocate doorbell.
> >
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > Change from v9 to v11
> > - new patch
> > ---
> >  drivers/irqchip/irq-gic-v3-its-msi-parent.c | 1 +
> >  drivers/pci/endpoint/pci-ep-msi.c           | 8 ++++++++
> >  include/linux/msi.h                         | 2 ++
>
> This is not how it works and I explained that you to more than once in
> the past.

The below suggest is great and I will update at next version. But I want to
know where I lost this.

v10: https://lore.kernel.org/imx/20241204-ep-msi-v10-0-87c378dbcd6d at nxp.com/T/#m3060eeab5d5bac931db685d21755a827dfc7a8c7
Talk about MUTABLE or IMPUTABLE
v9: https://lore.kernel.org/imx/87v7w0s9a8.ffs at tglx/
Talk about need add a imputable flags

v8: https://lore.kernel.org/imx/20241116-ep-msi-v8-0-6f1f68ffd1bb at nxp.com/
v7: https://lore.kernel.org/imx/20241114-ep-msi-v7-0-d4ac7aafbd2c at nxp.com/
v6: https://lore.kernel.org/all/20241112-ep-msi-v6-0-45f9722e3c2a at nxp.com/
v5: https://lore.kernel.org/all/20241108-ep-msi-v5-0-a14951c0d007 at nxp.com/
v4: https://lore.kernel.org/all/20241031-ep-msi-v4-0-717da2d99b28 at nxp.com/
Have not found your comments at v4 - v8

v3: https://lore.kernel.org/all/20241015-ep-msi-v3-0-cedc89a16c1a at nxp.com/
Talk about
msi_get_virq()

Frank

>
> The change to the interrupt code is standalone and has nothing to do
> with PCI endpoint. The latter is just a user of this.
>
> So this want's to be split into several patches:
>
>    1) add the new flag and a helper function which checks for the flag.
>
>    2) add the flag to GICv3 ITS with a proper explanation
>
>    3) Check for it in the PCI endpoint code
>
> >
> > +	if (!dom->msi_parent_ops)
> > +		return -EINVAL;
>
> irq_domain_is_msi_parent()
>
> > +	if (!(dom->msi_parent_ops->supported_flags & MSI_FLAG_MSG_IMMUTABLE)) {
>
> Want's a helper.
>
> Thanks,
>
>         tglx


From helgaas at kernel.org  Mon Dec  9 14:29:38 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon,  9 Dec 2024 16:29:38 -0600
Subject: [PATCH] perf/dwc_pcie: Qualify RAS DES VSEC Capability by Vendor, Revision
Message-ID: <20241209222938.3219364-1-helgaas@kernel.org>

From: Bjorn Helgaas <bhelgaas at google.com>

PCI Vendor-Specific (VSEC) Capabilities are defined by each vendor.
Devices from different vendors may advertise a VSEC Capability with the DWC
RAS DES functionality, but the vendors may assign different VSEC IDs.

Search for the DWC RAS DES Capability using the VSEC ID and VSEC Rev
chosen by the vendor.

This does not fix a current problem because Alibaba, Ampere, and Qualcomm
all assigned the same VSEC ID and VSEC Rev for the DWC RAS DES Capability.

The potential issue is that we may add support for a device from another
vendor, where the vendor has already assigned DWC_PCIE_VSEC_RAS_DES_ID
(0x02) for an unrelated VSEC.  In that event, dwc_pcie_des_cap() would find
the unrelated VSEC and mistakenly assume it was a DWC RAS DES Capability.

Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
Sample devices that advertise VSEC Capabilities with VSEC ID=0x02 that are
unrelated to the DWC RAS DES functionality:

  https://community.nxp.com/t5/S32G/S32G3-PCIe-compliance-mode-set-speed-to-5-8Gbit-s/m-p/1875346#M7024
    00:00.0 PCI bridge: Freescale Semiconductor Inc Device 4300 (prog-if 00 [Normal decode])
      Capabilities: [70] Express (v2) Root Port (Slot-), MSI 00
      Capabilities: [158 v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>

  https://github.com/google-coral/edgetpu/issues/743
    0000:00:00.0 PCI bridge: NVIDIA Corporation Device 1ad0 (rev a1) (prog-if 00 [Normal decode])
      Capabilities: [70] Express (v2) Root Port (Slot-), MSI 00
      Capabilities: [1d0 v1] Vendor Specific Information: ID=0002 Rev=4 Len=100

  https://www.linuxquestions.org/questions/linux-kernel-70/differences-in-'lspci-v'-output-4175495550/
    00:01.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 1 (rev 13) (prog-if 00 [Normal decode])
      Capabilities: [90] Express Root Port (Slot+), MSI 00
      Capabilities: [160] Vendor Specific Information: ID=0002 Rev=0 Len=00c <?>

  https://www.reddit.com/r/linuxhardware/comments/187u87b/the_correct_way_to_identify_the_kernel_driver/
    04:00.0 Network controller: Realtek Semiconductor Co., Ltd. Device c852 (rev 01)
      Capabilities: [70] Express Endpoint, MSI 00
      Capabilities: [170] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
---
 drivers/perf/dwc_pcie_pmu.c | 68 ++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 31 deletions(-)

diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
index 9cbea9675e21..d022f498fa1a 100644
--- a/drivers/perf/dwc_pcie_pmu.c
+++ b/drivers/perf/dwc_pcie_pmu.c
@@ -20,7 +20,6 @@
 #include <linux/sysfs.h>
 #include <linux/types.h>
 
-#define DWC_PCIE_VSEC_RAS_DES_ID		0x02
 #define DWC_PCIE_EVENT_CNT_CTL			0x8
 
 /*
@@ -100,14 +99,23 @@ struct dwc_pcie_dev_info {
 	struct list_head dev_node;
 };
 
-struct dwc_pcie_vendor_id {
-	int vendor_id;
+struct dwc_pcie_pmu_vsec_id {
+	u16 vendor_id;
+	u16 vsec_id;
+	u8 vsec_rev;
 };
 
-static const struct dwc_pcie_vendor_id dwc_pcie_vendor_ids[] = {
-	{.vendor_id = PCI_VENDOR_ID_ALIBABA },
-	{.vendor_id = PCI_VENDOR_ID_AMPERE },
-	{.vendor_id = PCI_VENDOR_ID_QCOM },
+/*
+ * VSEC IDs are allocated by the vendor, so a given ID may mean different
+ * things to different vendors.  See PCIe r6.0, sec 7.9.5.2.
+ */
+static const struct dwc_pcie_pmu_vsec_id dwc_pcie_pmu_vsec_ids[] = {
+	{ .vendor_id = PCI_VENDOR_ID_ALIBABA,
+	  .vsec_id = 0x02, .vsec_rev = 0x4 },
+	{ .vendor_id = PCI_VENDOR_ID_AMPERE,
+	  .vsec_id = 0x02, .vsec_rev = 0x4 },
+	{ .vendor_id = PCI_VENDOR_ID_QCOM,
+	  .vsec_id = 0x02, .vsec_rev = 0x4 },
 	{} /* terminator */
 };
 
@@ -519,31 +527,28 @@ static void dwc_pcie_unregister_pmu(void *data)
 	perf_pmu_unregister(&pcie_pmu->pmu);
 }
 
-static bool dwc_pcie_match_des_cap(struct pci_dev *pdev)
+static u16 dwc_pcie_des_cap(struct pci_dev *pdev)
 {
-	const struct dwc_pcie_vendor_id *vid;
-	u16 vsec = 0;
+	const struct dwc_pcie_pmu_vsec_id *vid;
+	u16 vsec;
 	u32 val;
 
 	if (!pci_is_pcie(pdev) || !(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT))
-		return false;
+		return 0;
 
-	for (vid = dwc_pcie_vendor_ids; vid->vendor_id; vid++) {
+	for (vid = dwc_pcie_pmu_vsec_ids; vid->vendor_id; vid++) {
 		vsec = pci_find_vsec_capability(pdev, vid->vendor_id,
-						DWC_PCIE_VSEC_RAS_DES_ID);
-		if (vsec)
-			break;
+						vid->vsec_id);
+		if (vsec) {
+			pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER,
+					      &val);
+			if (PCI_VNDR_HEADER_REV(val) == vid->vsec_rev) {
+				pci_dbg(pdev, "Detected PCIe Vendor-Specific Extended Capability RAS DES\n");
+				return vsec;
+			}
+		}
 	}
-	if (!vsec)
-		return false;
-
-	pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER, &val);
-	if (PCI_VNDR_HEADER_REV(val) != 0x04)
-		return false;
-
-	pci_dbg(pdev,
-		"Detected PCIe Vendor-Specific Extended Capability RAS DES\n");
-	return true;
+	return 0;
 }
 
 static void dwc_pcie_unregister_dev(struct dwc_pcie_dev_info *dev_info)
@@ -587,7 +592,7 @@ static int dwc_pcie_pmu_notifier(struct notifier_block *nb,
 
 	switch (action) {
 	case BUS_NOTIFY_ADD_DEVICE:
-		if (!dwc_pcie_match_des_cap(pdev))
+		if (!dwc_pcie_des_cap(pdev))
 			return NOTIFY_DONE;
 		if (dwc_pcie_register_dev(pdev))
 			return NOTIFY_BAD;
@@ -612,13 +617,14 @@ static int dwc_pcie_pmu_probe(struct platform_device *plat_dev)
 	struct pci_dev *pdev = plat_dev->dev.platform_data;
 	struct dwc_pcie_pmu *pcie_pmu;
 	char *name;
-	u32 sbdf, val;
+	u32 sbdf;
 	u16 vsec;
 	int ret;
 
-	vsec = pci_find_vsec_capability(pdev, pdev->vendor,
-					DWC_PCIE_VSEC_RAS_DES_ID);
-	pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER, &val);
+	vsec = dwc_pcie_des_cap(pdev);
+	if (!vsec)
+		return -ENODEV;
+
 	sbdf = plat_dev->id;
 	name = devm_kasprintf(&plat_dev->dev, GFP_KERNEL, "dwc_rootport_%x", sbdf);
 	if (!name)
@@ -730,7 +736,7 @@ static int __init dwc_pcie_pmu_init(void)
 	int ret;
 
 	for_each_pci_dev(pdev) {
-		if (!dwc_pcie_match_des_cap(pdev))
+		if (!dwc_pcie_des_cap(pdev))
 			continue;
 
 		ret = dwc_pcie_register_dev(pdev);
-- 
2.34.1



From helgaas at kernel.org  Mon Dec  9 14:47:41 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 9 Dec 2024 16:47:41 -0600
Subject: [PATCH v12 4/5] drivers/perf: add DesignWare PCIe PMU driver
In-Reply-To: <20241209154015.GA12428@willie-the-truck>
Message-ID: <20241209224741.GA3206765@bhelgaas>

On Mon, Dec 09, 2024 at 03:40:16PM +0000, Will Deacon wrote:
> On Fri, Dec 06, 2024 at 10:54:57AM -0600, Bjorn Helgaas wrote:
> > On Fri, Dec 08, 2023 at 10:56:51AM +0800, Shuai Xue wrote:
> > > This commit adds the PCIe Performance Monitoring Unit (PMU) driver support
> > > for T-Head Yitian SoC chip. Yitian is based on the Synopsys PCI Express
> > > Core controller IP which provides statistics feature. The PMU is a PCIe
> > > configuration space register block provided by each PCIe Root Port in a
> > > Vendor-Specific Extended Capability named RAS D.E.S (Debug, Error
> > > injection, and Statistics).
> > 
> > > +#define DWC_PCIE_VSEC_RAS_DES_ID		0x02
> > 
> > > +static const struct dwc_pcie_vendor_id dwc_pcie_vendor_ids[] = {
> > > +	{.vendor_id = PCI_VENDOR_ID_ALIBABA },
> > > +	{} /* terminator */
> > > +};
> > 
> > > +static bool dwc_pcie_match_des_cap(struct pci_dev *pdev)
> > > +{
> > > +	const struct dwc_pcie_vendor_id *vid;
> > > +	u16 vsec;
> > > +	u32 val;
> > > +
> > > +	if (!pci_is_pcie(pdev) || !(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT))
> > > +		return false;
> > > +
> > > +	for (vid = dwc_pcie_vendor_ids; vid->vendor_id; vid++) {
> > > +		vsec = pci_find_vsec_capability(pdev, vid->vendor_id,
> > > +						DWC_PCIE_VSEC_RAS_DES_ID);
> > 
> > This looks wrong to me, and it promotes a misunderstanding of how VSEC
> > Capabilities work.  The VSEC ID is defined by the vendor, so we have
> > to check both the Vendor ID and the VSEC ID before we know what this
> > VSEC Capability is.
> 
> Thanks for pointing this out! The code's been merged for a while now,
> so we'll need to fix what we have rather than revert it, I think.

Yep, for sure.

> Any chance you could send a patch with those, please? I'm also not able
> to test this stuff, but I'm sure Ilkka would help us out.

Posted at https://lore.kernel.org/linux-pci/20241209222938.3219364-1-helgaas at kernel.org

Bjorn


From james.quinlan at broadcom.com  Mon Dec  9 14:52:56 2024
From: james.quinlan at broadcom.com (James Quinlan)
Date: Mon, 9 Dec 2024 17:52:56 -0500
Subject: [PATCH v4 08/10] PCI: brcmstb: Adjust PHY PLL setup to use a
 54MHz input refclk
In-Reply-To: <20241025124515.14066-9-svarbanov@suse.de>
References: <20241025124515.14066-1-svarbanov@suse.de>
 <20241025124515.14066-9-svarbanov@suse.de>
Message-ID: <4bbdf9ed-f429-411b-8f5f-e51857f0f9d0@broadcom.com>

On 10/25/24 08:45, Stanimir Varbanov wrote:
> The default input reference clock for the PHY PLL is 100Mhz, except for
> some devices where it is 54Mhz like bcm2712C1 and bcm2712D0.
>
> To implement this adjustments introduce a new .post_setup op in
> pcie_cfg_data and call it at the end of brcm_pcie_setup function.
>
> The bcm2712 .post_setup callback implements the required MDIO writes that
> switch the PLL refclk and also change PHY PM clock period.
>
> Without this RPi5 PCIex1 is unable to enumerate endpoint devices on
> the expansion connector.
>
> Signed-off-by: Stanimir Varbanov <svarbanov at suse.de>
> ---
> v3 -> v4:
>   - Improved patch description (Florian)
>
>   drivers/pci/controller/pcie-brcmstb.c | 42 +++++++++++++++++++++++++++
>   1 file changed, 42 insertions(+)
>
> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
> index d970a76aa9ef..2571dcc14560 100644
> --- a/drivers/pci/controller/pcie-brcmstb.c
> +++ b/drivers/pci/controller/pcie-brcmstb.c
> @@ -55,6 +55,10 @@
>   #define PCIE_RC_DL_MDIO_WR_DATA				0x1104
>   #define PCIE_RC_DL_MDIO_RD_DATA				0x1108
>   
> +#define PCIE_RC_PL_PHY_CTL_15				0x184c
> +#define  PCIE_RC_PL_PHY_CTL_15_DIS_PLL_PD_MASK		0x400000
> +#define  PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK	0xff
> +
>   #define PCIE_MISC_MISC_CTRL				0x4008
>   #define  PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE_MASK	0x80
>   #define  PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE_MASK	0x400
> @@ -251,6 +255,7 @@ struct pcie_cfg_data {
>   	u8 num_inbound_wins;
>   	int (*perst_set)(struct brcm_pcie *pcie, u32 val);
>   	int (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
> +	int (*post_setup)(struct brcm_pcie *pcie);
>   };
>   
>   struct subdev_regulators {
> @@ -826,6 +831,36 @@ static int brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val)
>   	return 0;
>   }
>   
> +static int brcm_pcie_post_setup_bcm2712(struct brcm_pcie *pcie)
> +{
> +	const u16 data[] = { 0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030, 0x5030, 0x0007 };
> +	const u8 regs[] = { 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e };
> +	int ret, i;
> +	u32 tmp;
> +
> +	/* Allow a 54MHz (xosc) refclk source */
> +	ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, SET_ADDR_OFFSET, 0x1600);
> +	if (ret < 0)
> +		return ret;
> +
> +	for (i = 0; i < ARRAY_SIZE(regs); i++) {
> +		ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, regs[i], data[i]);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	usleep_range(100, 200);
> +
> +	/* Fix for L1SS errata */
> +	tmp = readl(pcie->base + PCIE_RC_PL_PHY_CTL_15);
> +	tmp &= ~PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK;
> +	/* PM clock period is 18.52ns (round down) */
> +	tmp |= 0x12;
> +	writel(tmp, pcie->base + PCIE_RC_PL_PHY_CTL_15);

Hi Stan,

Can you please say more about where this errata came from?? I asked the 
7712 PCIe HW folks and they said that there best guess was that it was a 
old workaround for a particular Broadcom Wifi endpoint.? Do you know its 
origin?

Thanks,

Jim Quinlan

Broadcom STB/CM

> +
> +	return 0;
> +}
> +
>   static void add_inbound_win(struct inbound_win *b, u8 *count, u64 size,
>   			    u64 cpu_addr, u64 pci_offset)
>   {
> @@ -1189,6 +1224,12 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
>   		PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK);
>   	writel(tmp, base + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1);
>   
> +	if (pcie->cfg->post_setup) {
> +		ret = pcie->cfg->post_setup(pcie);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
>   	return 0;
>   }
>   
> @@ -1761,6 +1802,7 @@ static const struct pcie_cfg_data bcm2712_cfg = {
>   	.soc_base	= BCM7712,
>   	.perst_set	= brcm_pcie_perst_set_7278,
>   	.bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic,
> +	.post_setup	= brcm_pcie_post_setup_bcm2712,
>   	.quirks		= CFG_QUIRK_AVOID_BRIDGE_SHUTDOWN,
>   	.num_inbound_wins = 10,
>   };




From dmitry.baryshkov at linaro.org  Mon Dec  9 15:02:01 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 01:02:01 +0200
Subject: [PATCH 3/6] arm64: cputype: Add QCOM_CPU_PART_KRYO_3XX_GOLD
In-Reply-To: <20241209094310.3.I18e0288742871393228249a768e5d56ea65d93dc@changeid>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.3.I18e0288742871393228249a768e5d56ea65d93dc@changeid>
Message-ID: <k64saaxnipegp4ot636apzewrs7dz2j7xdpqxg6iotbaderuia@hxqf63bwwztf>

On Mon, Dec 09, 2024 at 09:43:13AM -0800, Douglas Anderson wrote:
> Add a definition for the Qualcomm Kryo 300-series Gold cores.
> 
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---
> I have no idea if this is actually right and no way to test it, but it
> fits the pattern of the other definitions. Someone from Qualcomm ought
> to confirm this.

This matches what I see on SDM845.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>


> 
>  arch/arm64/include/asm/cputype.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 488f8e751349..c8058f91a5bd 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -119,6 +119,7 @@
>  #define QCOM_CPU_PART_KRYO		0x200
>  #define QCOM_CPU_PART_KRYO_2XX_GOLD	0x800
>  #define QCOM_CPU_PART_KRYO_2XX_SILVER	0x801
> +#define QCOM_CPU_PART_KRYO_3XX_GOLD	0x802
>  #define QCOM_CPU_PART_KRYO_3XX_SILVER	0x803
>  #define QCOM_CPU_PART_KRYO_4XX_GOLD	0x804
>  #define QCOM_CPU_PART_KRYO_4XX_SILVER	0x805
> @@ -195,6 +196,7 @@
>  #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO)
>  #define MIDR_QCOM_KRYO_2XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_GOLD)
>  #define MIDR_QCOM_KRYO_2XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_SILVER)
> +#define MIDR_QCOM_KRYO_3XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_GOLD)
>  #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER)
>  #define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD)
>  #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
> -- 
> 2.47.0.338.g60cca15819-goog
> 

-- 
With best wishes
Dmitry


From will at kernel.org  Mon Dec  9 15:06:12 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Dec 2024 23:06:12 +0000
Subject: [PATCH 3/3] iommu/arm-smmu-v3: Remove domain_alloc_paging()
In-Reply-To: <3-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
References: <0-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
 <3-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
Message-ID: <20241209230611.GA13790@willie-the-truck>

On Thu, Dec 05, 2024 at 11:43:29AM -0400, Jason Gunthorpe wrote:
> arm_smmu_domain_alloc_paging_flags() with a flags = 0 now does the same
> thing as arm_smmu_domain_alloc_paging(), remove
> arm_smmu_domain_alloc_paging().
> 
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 31 ---------------------
>  1 file changed, 31 deletions(-)

Ha! I was reviewing the previous patch and about to reply asking why we
couldn't just implement arm_smmu_domain_alloc_paging() as a wrapper
around arm_smmu_domain_alloc_paging() with flags of 0.

Good thing I read ahead :)

Will


From dmitry.baryshkov at linaro.org  Mon Dec  9 15:07:38 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 01:07:38 +0200
Subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the
 spectre_bhb_k24_list
In-Reply-To: <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>
Message-ID: <l5rqbbxn6hktlcxooolkvi5n3arkht6zzhrvdjf6kis322nsup@5hsrak4cgteq>

On Mon, Dec 09, 2024 at 09:43:15AM -0800, Douglas Anderson wrote:
> Qualcomm Kryo 500-series Gold cores appear to have a derivative of an
> ARM Cortex A77 in them. Since A77 needs Spectre mitigation then the
> Kyro 500-series Gold cores also should need Spectre mitigation.
> 
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---
> Yes. I know. This patch DOESN'T COMPILE because
> MIDR_QCOM_KRYO_5XX_GOLD is not defined. That value needs to come from
> Qualcomm or from testing on hardware, which I don't have. Qualcomm
> needs to chime in to confirm that this Spectre mitigation is correct
> anyway, though. I'm including this patch so it's obvious that I think
> these cores also need the mitigation.

Kryo 5xx (SM8250) identify themselves as 0x41/0xd0d (Gold, Prime) and
0x51/0x805 (Silver)

> 
>  arch/arm64/kernel/proton-pack.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
> index b1881964e304..212481726f04 100644
> --- a/arch/arm64/kernel/proton-pack.c
> +++ b/arch/arm64/kernel/proton-pack.c
> @@ -867,6 +867,7 @@ u8 spectre_bhb_loop_affected(int scope)
>  			MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
>  			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
>  			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
> +			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
>  			{},
>  		};
>  		static const struct midr_range spectre_bhb_k11_list[] = {
> -- 
> 2.47.0.338.g60cca15819-goog
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Mon Dec  9 15:09:50 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 01:09:50 +0200
Subject: [PATCH 6/6] arm64: errata: Add QCOM_KRYO_6XX_GOLD/PRIME to the
 spectre_bhb_k32_list
In-Reply-To: <20241209094310.6.I722621804be859e4ae4b7479ce191c5e3367b37c@changeid>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.6.I722621804be859e4ae4b7479ce191c5e3367b37c@changeid>
Message-ID: <tx7vtur7yea6ruefrkpkccqptahgmxnsrudwdz5uzcfxnng25b@afrr5bmdk2xa>

On Mon, Dec 09, 2024 at 09:43:16AM -0800, Douglas Anderson wrote:
> Qualcomm Kryo 600-series Gold cores appear to have a derivative of an
> ARM Cortex A78 / ARM Cortex X1 in them. Since these need Spectre
> mitigation then the Kyro 600-series Gold/Prime cores also should need
> Spectre mitigation.
> 
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---
> Yes. I know. This patch DOESN'T COMPILE because
> MIDR_QCOM_KRYO_6XX_GOLD and MIDR_QCOM_KRYO_6XX_PRIME are not
> defined. Those value needs to come from Qualcomm or from testing on
> hardware, which I don't have. Qualcomm needs to chime in to confirm
> that this Spectre mitigation is correct anyway, though. I'm including
> this patch so it's obvious that I think these cores also need the
> mitigation.

SM8350 (Kryo 680) identifies itself as 0x41/0xd44 (Prime), 0x41/0xd41
(Gold) and 0x41/0xd05 (Silver)

> 
>  arch/arm64/kernel/proton-pack.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
> index 212481726f04..67aa54017dea 100644
> --- a/arch/arm64/kernel/proton-pack.c
> +++ b/arch/arm64/kernel/proton-pack.c
> @@ -860,6 +860,8 @@ u8 spectre_bhb_loop_affected(int scope)
>  			MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
>  			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
>  			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
> +			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_GOLD),
> +			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_PRIME),
>  			{},
>  		};
>  		static const struct midr_range spectre_bhb_k24_list[] = {
> -- 
> 2.47.0.338.g60cca15819-goog
> 

-- 
With best wishes
Dmitry


From heiko at sntech.de  Mon Dec  9 15:10:21 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 10 Dec 2024 00:10:21 +0100
Subject: [PATCH v4 3/3] drm/rockchip: Add MIPI DSI2 glue driver for RK3588
In-Reply-To: <20241209231021.2180582-1-heiko@sntech.de>
References: <20241209231021.2180582-1-heiko@sntech.de>
Message-ID: <20241209231021.2180582-4-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

This adds the glue code for the MIPI DSI2 bridge on Rockchip SoCs and
enables its use on the RK3588.

Right now the DSI2 controller is always paired with a DC-phy based on a
Samsung IP, so the interface values are set statically for now.
This stays true for the upcoming RK3576 as well.

Tested-by: Daniel Semkowicz <dse at thaumatec.com>
Tested-by: Dmitry Yashin <dmt.yashin at gmail.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 drivers/gpu/drm/rockchip/Kconfig              |  10 +
 drivers/gpu/drm/rockchip/Makefile             |   1 +
 .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c  | 487 ++++++++++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |   2 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |   1 +
 5 files changed, 501 insertions(+)
 create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 448fadd4ba15..adee24b4e7bc 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -10,6 +10,7 @@ config DRM_ROCKCHIP
 	select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
 	select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP
 	select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
+	select DRM_DW_MIPI_DSI2 if ROCKCHIP_DW_MIPI_DSI2
 	select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
 	select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
 	select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
@@ -81,6 +82,15 @@ config ROCKCHIP_DW_MIPI_DSI
 	  enable MIPI DSI on RK3288 or RK3399 based SoC, you should
 	  select this option.
 
+config ROCKCHIP_DW_MIPI_DSI2
+	bool "Rockchip specific extensions for Synopsys DW MIPI DSI2"
+	select GENERIC_PHY_MIPI_DPHY
+	help
+	  This selects support for Rockchip SoC specific extensions
+	  for the Synopsys DesignWare DSI2 driver. If you want to
+	  enable MIPI DSI on RK3576 or RK3588 based SoC, you should
+	  select this option.
+
 config ROCKCHIP_INNO_HDMI
 	bool "Rockchip specific extensions for Innosilicon HDMI"
 	select DRM_DISPLAY_HDMI_HELPER
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index 3eab662a5a1d..2b867cebbc12 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -13,6 +13,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o
+rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI2) += dw-mipi-dsi2-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
 rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
 rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
new file mode 100644
index 000000000000..cdd490778756
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
@@ -0,0 +1,487 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Rockchip Electronics Co., Ltd.
+ * Author:
+ *      Guochun Huang <hero.huang at rock-chips.com>
+ *      Heiko Stuebner <heiko.stuebner at cherry.de>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/media-bus-format.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/mfd/syscon.h>
+#include <linux/phy/phy.h>
+
+#include <drm/bridge/dw_mipi_dsi2.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
+#include <drm/drm_simple_kms_helper.h>
+
+#include <uapi/linux/videodev2.h>
+
+#include "rockchip_drm_drv.h"
+
+#define PSEC_PER_SEC			1000000000000LL
+
+struct dsigrf_reg {
+	u16 offset;
+	u16 lsb;
+	u16 msb;
+};
+
+enum grf_reg_fields {
+	TXREQCLKHS_EN,
+	GATING_EN,
+	IPI_SHUTDN,
+	IPI_COLORM,
+	IPI_COLOR_DEPTH,
+	IPI_FORMAT,
+	MAX_FIELDS,
+};
+
+#define IPI_DEPTH_5_6_5_BITS		0x02
+#define IPI_DEPTH_6_BITS		0x03
+#define IPI_DEPTH_8_BITS		0x05
+#define IPI_DEPTH_10_BITS		0x06
+
+struct rockchip_dw_dsi2_chip_data {
+	u32 reg;
+	const struct dsigrf_reg *grf_regs;
+	unsigned long long max_bit_rate_per_lane;
+};
+
+struct dw_mipi_dsi2_rockchip {
+	struct device *dev;
+	struct rockchip_encoder encoder;
+	struct regmap *regmap;
+
+	unsigned int lane_mbps; /* per lane */
+	u32 format;
+
+	struct regmap *grf_regmap;
+	struct phy *phy;
+	union phy_configure_opts phy_opts;
+
+	struct dw_mipi_dsi2 *dmd;
+	struct dw_mipi_dsi2_plat_data pdata;
+	const struct rockchip_dw_dsi2_chip_data *cdata;
+};
+
+static inline struct dw_mipi_dsi2_rockchip *to_dsi2(struct drm_encoder *encoder)
+{
+	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
+
+	return container_of(rkencoder, struct dw_mipi_dsi2_rockchip, encoder);
+}
+
+static void grf_field_write(struct dw_mipi_dsi2_rockchip *dsi2, enum grf_reg_fields index,
+			    unsigned int val)
+{
+	const struct dsigrf_reg *field = &dsi2->cdata->grf_regs[index];
+
+	if (!field)
+		return;
+
+	regmap_write(dsi2->grf_regmap, field->offset,
+		     (val << field->lsb) | (GENMASK(field->msb, field->lsb) << 16));
+}
+
+static int dw_mipi_dsi2_phy_init(void *priv_data)
+{
+	return 0;
+}
+
+static void dw_mipi_dsi2_phy_power_on(void *priv_data)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+	int ret;
+
+	ret = phy_set_mode(dsi2->phy, PHY_MODE_MIPI_DPHY);
+	if (ret) {
+		dev_err(dsi2->dev, "Failed to set phy mode: %d\n", ret);
+		return;
+	}
+
+	phy_configure(dsi2->phy, &dsi2->phy_opts);
+	phy_power_on(dsi2->phy);
+}
+
+static void dw_mipi_dsi2_phy_power_off(void *priv_data)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+
+	phy_power_off(dsi2->phy);
+}
+
+static int
+dw_mipi_dsi2_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
+			   unsigned long mode_flags, u32 lanes, u32 format,
+			   unsigned int *lane_mbps)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+	u64 max_lane_rate, target_phyclk;
+	unsigned int lane_rate_kbps;
+	int bpp;
+
+	max_lane_rate = dsi2->cdata->max_bit_rate_per_lane;
+
+	dsi2->format = format;
+	bpp = mipi_dsi_pixel_format_to_bpp(format);
+	if (bpp < 0) {
+		dev_err(dsi2->dev, "failed to get bpp for pixel format %d\n", format);
+		return bpp;
+	}
+
+	lane_rate_kbps = mode->clock * bpp / lanes;
+
+	/*
+	 * Set BW a little larger only in video burst mode in
+	 * consideration of the protocol overhead and HS mode
+	 * switching to BLLP mode, take 1 / 0.9, since Mbps must
+	 * big than bandwidth of RGB
+	 */
+	if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+		lane_rate_kbps = (lane_rate_kbps * 10) / 9;
+
+	if (lane_rate_kbps > max_lane_rate) {
+		dev_err(dsi2->dev, "DPHY clock frequency is out of range\n");
+		return -ERANGE;
+	}
+
+	dsi2->lane_mbps = lane_rate_kbps / 1000;
+	*lane_mbps = dsi2->lane_mbps;
+
+	if (dsi2->phy) {
+		target_phyclk = DIV_ROUND_CLOSEST_ULL(lane_rate_kbps * lanes * 1000, bpp);
+		phy_mipi_dphy_get_default_config(target_phyclk, bpp, lanes,
+						 &dsi2->phy_opts.mipi_dphy);
+	}
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_phy_get_iface(void *priv_data, struct dw_mipi_dsi2_phy_iface *iface)
+{
+	/* PPI width is fixed to 16 bits in DCPHY */
+	iface->ppi_width = 16;
+	iface->phy_type = DW_MIPI_DSI2_DPHY;
+}
+
+static int
+dw_mipi_dsi2_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+			    struct dw_mipi_dsi2_phy_timing *timing)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+	struct phy_configure_opts_mipi_dphy *cfg = &dsi2->phy_opts.mipi_dphy;
+	unsigned long long tmp, ui;
+	unsigned long long hstx_clk;
+
+	hstx_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
+
+	ui = ALIGN(PSEC_PER_SEC, hstx_clk);
+	do_div(ui, hstx_clk);
+
+	/* PHY_LP2HS_TIME = (TLPX + THS-PREPARE + THS-ZERO) / Tphy_hstx_clk */
+	tmp = cfg->lpx + cfg->hs_prepare + cfg->hs_zero;
+	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
+	timing->data_lp2hs = tmp;
+
+	/* PHY_HS2LP_TIME = (THS-TRAIL + THS-EXIT) / Tphy_hstx_clk */
+	tmp = cfg->hs_trail + cfg->hs_exit;
+	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
+	timing->data_hs2lp = tmp;
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi2_phy_ops dw_mipi_dsi2_rockchip_phy_ops = {
+	.init = dw_mipi_dsi2_phy_init,
+	.power_on = dw_mipi_dsi2_phy_power_on,
+	.power_off = dw_mipi_dsi2_phy_power_off,
+	.get_interface = dw_mipi_dsi2_phy_get_iface,
+	.get_lane_mbps = dw_mipi_dsi2_get_lane_mbps,
+	.get_timing = dw_mipi_dsi2_phy_get_timing,
+};
+
+static void dw_mipi_dsi2_encoder_atomic_enable(struct drm_encoder *encoder,
+					       struct drm_atomic_state *state)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
+	u32 color_depth;
+
+	switch (dsi2->format) {
+	case MIPI_DSI_FMT_RGB666:
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		color_depth = IPI_DEPTH_6_BITS;
+		break;
+	case MIPI_DSI_FMT_RGB565:
+		color_depth = IPI_DEPTH_5_6_5_BITS;
+		break;
+	case MIPI_DSI_FMT_RGB888:
+		color_depth = IPI_DEPTH_8_BITS;
+		break;
+	default:
+		/* Should've been caught by atomic_check */
+		WARN_ON(1);
+		return;
+	}
+
+	grf_field_write(dsi2, IPI_COLOR_DEPTH, color_depth);
+}
+
+static int
+dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder,
+				  struct drm_crtc_state *crtc_state,
+				  struct drm_connector_state *conn_state)
+{
+	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
+	struct drm_connector *connector = conn_state->connector;
+	struct drm_display_info *info = &connector->display_info;
+
+	switch (dsi2->format) {
+	case MIPI_DSI_FMT_RGB666:
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		s->output_mode = ROCKCHIP_OUT_MODE_P666;
+		break;
+	case MIPI_DSI_FMT_RGB565:
+		s->output_mode = ROCKCHIP_OUT_MODE_P565;
+		break;
+	case MIPI_DSI_FMT_RGB888:
+		s->output_mode = ROCKCHIP_OUT_MODE_P888;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	if (info->num_bus_formats)
+		s->bus_format = info->bus_formats[0];
+	else
+		s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+
+	s->output_type = DRM_MODE_CONNECTOR_DSI;
+	s->bus_flags = info->bus_flags;
+	s->color_space = V4L2_COLORSPACE_DEFAULT;
+
+	return 0;
+}
+
+static const struct drm_encoder_helper_funcs
+dw_mipi_dsi2_encoder_helper_funcs = {
+	.atomic_enable = dw_mipi_dsi2_encoder_atomic_enable,
+	.atomic_check = dw_mipi_dsi2_encoder_atomic_check,
+};
+
+static int rockchip_dsi2_drm_create_encoder(struct dw_mipi_dsi2_rockchip *dsi2,
+					    struct drm_device *drm_dev)
+{
+	struct drm_encoder *encoder = &dsi2->encoder.encoder;
+	int ret;
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
+							     dsi2->dev->of_node);
+
+	ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		dev_err(dsi2->dev, "Failed to initialize encoder with drm\n");
+		return ret;
+	}
+
+	drm_encoder_helper_add(encoder, &dw_mipi_dsi2_encoder_helper_funcs);
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_rockchip_bind(struct device *dev, struct device *master,
+				      void *data)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
+	struct drm_device *drm_dev = data;
+	int ret;
+
+	ret = rockchip_dsi2_drm_create_encoder(dsi2, drm_dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to create drm encoder\n");
+
+	rockchip_drm_encoder_set_crtc_endpoint_id(&dsi2->encoder,
+						  dev->of_node, 0, 0);
+
+	ret = dw_mipi_dsi2_bind(dsi2->dmd, &dsi2->encoder.encoder);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to bind\n");
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_rockchip_unbind(struct device *dev, struct device *master,
+					 void *data)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
+
+	dw_mipi_dsi2_unbind(dsi2->dmd);
+}
+
+static const struct component_ops dw_mipi_dsi2_rockchip_ops = {
+	.bind	= dw_mipi_dsi2_rockchip_bind,
+	.unbind	= dw_mipi_dsi2_rockchip_unbind,
+};
+
+static int dw_mipi_dsi2_rockchip_host_attach(void *priv_data,
+					     struct mipi_dsi_device *device)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+	int ret;
+
+	ret = component_add(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
+	if (ret)
+		return dev_err_probe(dsi2->dev, ret, "Failed to register component\n");
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_rockchip_host_detach(void *priv_data,
+					     struct mipi_dsi_device *device)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
+
+	component_del(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi2_host_ops dw_mipi_dsi2_rockchip_host_ops = {
+	.attach = dw_mipi_dsi2_rockchip_host_attach,
+	.detach = dw_mipi_dsi2_rockchip_host_detach,
+};
+
+static const struct regmap_config dw_mipi_dsi2_rockchip_regmap_config = {
+	.name = "dsi2-host",
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.fast_io = true,
+};
+
+static int dw_mipi_dsi2_rockchip_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	const struct rockchip_dw_dsi2_chip_data *cdata =
+						of_device_get_match_data(dev);
+	struct dw_mipi_dsi2_rockchip *dsi2;
+	struct resource *res;
+	void __iomem *base;
+	int i;
+
+	dsi2 = devm_kzalloc(dev, sizeof(*dsi2), GFP_KERNEL);
+	if (!dsi2)
+		return -ENOMEM;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(base))
+		return dev_err_probe(dev, PTR_ERR(base), "Unable to get dsi registers\n");
+
+	dsi2->regmap = devm_regmap_init_mmio(dev, base, &dw_mipi_dsi2_rockchip_regmap_config);
+	if (IS_ERR(dsi2->regmap))
+		return dev_err_probe(dev, PTR_ERR(dsi2->regmap), "failed to init register map\n");
+
+	i = 0;
+	while (cdata[i].reg) {
+		if (cdata[i].reg == res->start) {
+			dsi2->cdata = &cdata[i];
+			break;
+		}
+
+		i++;
+	}
+
+	if (!dsi2->cdata)
+		return dev_err_probe(dev, -EINVAL, "No dsi-config for %s node\n", np->name);
+
+	dsi2->grf_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
+	if (IS_ERR(dsi2->grf_regmap))
+		return dev_err_probe(dsi2->dev, PTR_ERR(dsi2->grf_regmap), "Unable to get grf\n");
+
+	dsi2->phy = devm_phy_optional_get(dev, "dcphy");
+	if (IS_ERR(dsi2->phy))
+		return dev_err_probe(dev, PTR_ERR(dsi2->phy), "failed to get mipi phy\n");
+
+	dsi2->dev = dev;
+	dsi2->pdata.regmap = dsi2->regmap;
+	dsi2->pdata.max_data_lanes = 4;
+	dsi2->pdata.phy_ops = &dw_mipi_dsi2_rockchip_phy_ops;
+	dsi2->pdata.host_ops = &dw_mipi_dsi2_rockchip_host_ops;
+	dsi2->pdata.priv_data = dsi2;
+	platform_set_drvdata(pdev, dsi2);
+
+	dsi2->dmd = dw_mipi_dsi2_probe(pdev, &dsi2->pdata);
+	if (IS_ERR(dsi2->dmd))
+		return dev_err_probe(dev, PTR_ERR(dsi2->dmd), "Failed to probe dw_mipi_dsi2\n");
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_rockchip_remove(struct platform_device *pdev)
+{
+	struct dw_mipi_dsi2_rockchip *dsi2 = platform_get_drvdata(pdev);
+
+	dw_mipi_dsi2_remove(dsi2->dmd);
+}
+
+static const struct dsigrf_reg rk3588_dsi0_grf_reg_fields[MAX_FIELDS] = {
+	[TXREQCLKHS_EN]		= { 0x0000, 11, 11 },
+	[GATING_EN]		= { 0x0000, 10, 10 },
+	[IPI_SHUTDN]		= { 0x0000,  9,  9 },
+	[IPI_COLORM]		= { 0x0000,  8,  8 },
+	[IPI_COLOR_DEPTH]	= { 0x0000,  4,  7 },
+	[IPI_FORMAT]		= { 0x0000,  0,  3 },
+};
+
+static const struct dsigrf_reg rk3588_dsi1_grf_reg_fields[MAX_FIELDS] = {
+	[TXREQCLKHS_EN]		= { 0x0004, 11, 11 },
+	[GATING_EN]		= { 0x0004, 10, 10 },
+	[IPI_SHUTDN]		= { 0x0004,  9,  9 },
+	[IPI_COLORM]		= { 0x0004,  8,  8 },
+	[IPI_COLOR_DEPTH]	= { 0x0004,  4,  7 },
+	[IPI_FORMAT]		= { 0x0004,  0,  3 },
+};
+
+static const struct rockchip_dw_dsi2_chip_data rk3588_chip_data[] = {
+	{
+		.reg = 0xfde20000,
+		.grf_regs = rk3588_dsi0_grf_reg_fields,
+		.max_bit_rate_per_lane = 4500000ULL,
+	},
+	{
+		.reg = 0xfde30000,
+		.grf_regs = rk3588_dsi1_grf_reg_fields,
+		.max_bit_rate_per_lane = 4500000ULL,
+	}
+};
+
+static const struct of_device_id dw_mipi_dsi2_rockchip_dt_ids[] = {
+	{
+		.compatible = "rockchip,rk3588-mipi-dsi2",
+		.data = &rk3588_chip_data,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, dw_mipi_dsi2_rockchip_dt_ids);
+
+struct platform_driver dw_mipi_dsi2_rockchip_driver = {
+	.probe	= dw_mipi_dsi2_rockchip_probe,
+	.remove = dw_mipi_dsi2_rockchip_remove,
+	.driver = {
+		.of_match_table = dw_mipi_dsi2_rockchip_dt_ids,
+		.name = "dw-mipi-dsi2",
+	},
+};
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index ddf0be331c0a..5327ce035003 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -511,6 +511,8 @@ static int __init rockchip_drm_init(void)
 				CONFIG_ROCKCHIP_DW_HDMI_QP);
 	ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver,
 				CONFIG_ROCKCHIP_DW_MIPI_DSI);
+	ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi2_rockchip_driver,
+				CONFIG_ROCKCHIP_DW_MIPI_DSI2);
 	ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI);
 	ADD_ROCKCHIP_SUB_DRIVER(rk3066_hdmi_driver,
 				CONFIG_ROCKCHIP_RK3066_HDMI);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 24b4ce5ceaf1..9c9d38a06cdf 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -90,6 +90,7 @@ extern struct platform_driver cdn_dp_driver;
 extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
 extern struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver;
 extern struct platform_driver dw_mipi_dsi_rockchip_driver;
+extern struct platform_driver dw_mipi_dsi2_rockchip_driver;
 extern struct platform_driver inno_hdmi_driver;
 extern struct platform_driver rockchip_dp_driver;
 extern struct platform_driver rockchip_lvds_driver;
-- 
2.45.2



From heiko at sntech.de  Mon Dec  9 15:10:19 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 10 Dec 2024 00:10:19 +0100
Subject: [PATCH v4 1/3] drm/bridge/synopsys: Add MIPI DSI2 host controller bridge
In-Reply-To: <20241209231021.2180582-1-heiko@sntech.de>
References: <20241209231021.2180582-1-heiko@sntech.de>
Message-ID: <20241209231021.2180582-2-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

Add a Synopsys Designware MIPI DSI host DRM bridge driver for their
DSI2 host controller, based on the Rockchip version from the driver
rockchip/dw-mipi-dsi2.c in their vendor-kernel with phy & bridge APIs.

While the driver is heavily modelled after the previous IP, the register
set of this DSI2 controller is completely different and there are also
additional properties like the variable-width phy interface.

Tested-by: Daniel Semkowicz <dse at thaumatec.com>
Tested-by: Dmitry Yashin <dmt.yashin at gmail.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 drivers/gpu/drm/bridge/synopsys/Kconfig       |    6 +
 drivers/gpu/drm/bridge/synopsys/Makefile      |    1 +
 .../gpu/drm/bridge/synopsys/dw-mipi-dsi2.c    | 1030 +++++++++++++++++
 include/drm/bridge/dw_mipi_dsi2.h             |   95 ++
 4 files changed, 1132 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
 create mode 100644 include/drm/bridge/dw_mipi_dsi2.h

diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
index ca416dab156d..f3ab2f985f8c 100644
--- a/drivers/gpu/drm/bridge/synopsys/Kconfig
+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
@@ -59,3 +59,9 @@ config DRM_DW_MIPI_DSI
 	select DRM_KMS_HELPER
 	select DRM_MIPI_DSI
 	select DRM_PANEL_BRIDGE
+
+config DRM_DW_MIPI_DSI2
+	tristate
+	select DRM_KMS_HELPER
+	select DRM_MIPI_DSI
+	select DRM_PANEL_BRIDGE
diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
index 9869d9651ed1..9dc376d220ad 100644
--- a/drivers/gpu/drm/bridge/synopsys/Makefile
+++ b/drivers/gpu/drm/bridge/synopsys/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
 obj-$(CONFIG_DRM_DW_HDMI_QP) += dw-hdmi-qp.o
 
 obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
+obj-$(CONFIG_DRM_DW_MIPI_DSI2) += dw-mipi-dsi2.o
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
new file mode 100644
index 000000000000..054ad39c451b
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
@@ -0,0 +1,1030 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Modified by Heiko Stuebner <heiko.stuebner at cherry.de>
+ * This generic Synopsys DesignWare MIPI DSI2 host driver is based on the
+ * Rockchip version from rockchip/dw-mipi-dsi2.c converted to use bridge APIs.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/bridge/dw_mipi_dsi2.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
+#include <drm/drm_print.h>
+
+#define DSI2_PWR_UP			0x000c
+#define RESET				0
+#define POWER_UP			BIT(0)
+#define CMD_TX_MODE(x)			FIELD_PREP(BIT(24), x)
+#define DSI2_SOFT_RESET			0x0010
+#define SYS_RSTN			BIT(2)
+#define PHY_RSTN			BIT(1)
+#define IPI_RSTN			BIT(0)
+#define INT_ST_MAIN			0x0014
+#define DSI2_MODE_CTRL			0x0018
+#define DSI2_MODE_STATUS		0x001c
+#define DSI2_CORE_STATUS		0x0020
+#define PRI_RD_DATA_AVAIL		BIT(26)
+#define PRI_FIFOS_NOT_EMPTY		BIT(25)
+#define PRI_BUSY			BIT(24)
+#define CRI_RD_DATA_AVAIL		BIT(18)
+#define CRT_FIFOS_NOT_EMPTY		BIT(17)
+#define CRI_BUSY			BIT(16)
+#define IPI_FIFOS_NOT_EMPTY		BIT(9)
+#define IPI_BUSY			BIT(8)
+#define CORE_FIFOS_NOT_EMPTY		BIT(1)
+#define CORE_BUSY			BIT(0)
+#define MANUAL_MODE_CFG			0x0024
+#define MANUAL_MODE_EN			BIT(0)
+#define DSI2_TIMEOUT_HSTX_CFG		0x0048
+#define TO_HSTX(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_HSTXRDY_CFG	0x004c
+#define TO_HSTXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_LPRX_CFG		0x0050
+#define TO_LPRXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_LPTXRDY_CFG	0x0054
+#define TO_LPTXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_LPTXTRIG_CFG	0x0058
+#define TO_LPTXTRIG(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_LPTXULPS_CFG	0x005c
+#define TO_LPTXULPS(x)			FIELD_PREP(GENMASK(15, 0), x)
+#define DSI2_TIMEOUT_BTA_CFG		0x60
+#define TO_BTA(x)			FIELD_PREP(GENMASK(15, 0), x)
+
+#define DSI2_PHY_MODE_CFG		0x0100
+#define PPI_WIDTH(x)			FIELD_PREP(GENMASK(9, 8), x)
+#define PHY_LANES(x)			FIELD_PREP(GENMASK(5, 4), (x) - 1)
+#define PHY_TYPE(x)			FIELD_PREP(BIT(0), x)
+#define DSI2_PHY_CLK_CFG		0X0104
+#define PHY_LPTX_CLK_DIV(x)		FIELD_PREP(GENMASK(12, 8), x)
+#define CLK_TYPE_MASK			BIT(0)
+#define NON_CONTINUOUS_CLK		BIT(0)
+#define CONTINUOUS_CLK			0
+#define DSI2_PHY_LP2HS_MAN_CFG		0x010c
+#define PHY_LP2HS_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
+#define DSI2_PHY_HS2LP_MAN_CFG		0x0114
+#define PHY_HS2LP_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
+#define DSI2_PHY_MAX_RD_T_MAN_CFG	0x011c
+#define PHY_MAX_RD_TIME(x)		FIELD_PREP(GENMASK(26, 0), x)
+#define DSI2_PHY_ESC_CMD_T_MAN_CFG	0x0124
+#define PHY_ESC_CMD_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
+#define DSI2_PHY_ESC_BYTE_T_MAN_CFG	0x012c
+#define PHY_ESC_BYTE_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
+
+#define DSI2_PHY_IPI_RATIO_MAN_CFG	0x0134
+#define PHY_IPI_RATIO(x)		FIELD_PREP(GENMASK(21, 0), x)
+#define DSI2_PHY_SYS_RATIO_MAN_CFG	0x013C
+#define PHY_SYS_RATIO(x)		FIELD_PREP(GENMASK(16, 0), x)
+
+#define DSI2_DSI_GENERAL_CFG		0x0200
+#define BTA_EN				BIT(1)
+#define EOTP_TX_EN			BIT(0)
+#define DSI2_DSI_VCID_CFG		0x0204
+#define TX_VCID(x)			FIELD_PREP(GENMASK(1, 0), x)
+#define DSI2_DSI_SCRAMBLING_CFG		0x0208
+#define SCRAMBLING_SEED(x)		FIELD_PREP(GENMASK(31, 16), x)
+#define SCRAMBLING_EN			BIT(0)
+#define DSI2_DSI_VID_TX_CFG		0x020c
+#define LPDT_DISPLAY_CMD_EN		BIT(20)
+#define BLK_VFP_HS_EN			BIT(14)
+#define BLK_VBP_HS_EN			BIT(13)
+#define BLK_VSA_HS_EN			BIT(12)
+#define BLK_HFP_HS_EN			BIT(6)
+#define BLK_HBP_HS_EN			BIT(5)
+#define BLK_HSA_HS_EN			BIT(4)
+#define VID_MODE_TYPE(x)		FIELD_PREP(GENMASK(1, 0), x)
+#define DSI2_CRI_TX_HDR			0x02c0
+#define CMD_TX_MODE(x)			FIELD_PREP(BIT(24), x)
+#define DSI2_CRI_TX_PLD			0x02c4
+#define DSI2_CRI_RX_HDR			0x02c8
+#define DSI2_CRI_RX_PLD			0x02cc
+
+#define DSI2_IPI_COLOR_MAN_CFG		0x0300
+#define IPI_DEPTH(x)			FIELD_PREP(GENMASK(7, 4), x)
+#define IPI_DEPTH_5_6_5_BITS		0x02
+#define IPI_DEPTH_6_BITS		0x03
+#define IPI_DEPTH_8_BITS		0x05
+#define IPI_DEPTH_10_BITS		0x06
+#define IPI_FORMAT(x)			FIELD_PREP(GENMASK(3, 0), x)
+#define IPI_FORMAT_RGB			0x0
+#define IPI_FORMAT_DSC			0x0b
+#define DSI2_IPI_VID_HSA_MAN_CFG	0x0304
+#define VID_HSA_TIME(x)			FIELD_PREP(GENMASK(29, 0), x)
+#define DSI2_IPI_VID_HBP_MAN_CFG	0x030c
+#define VID_HBP_TIME(x)			FIELD_PREP(GENMASK(29, 0), x)
+#define DSI2_IPI_VID_HACT_MAN_CFG	0x0314
+#define VID_HACT_TIME(x)		FIELD_PREP(GENMASK(29, 0), x)
+#define DSI2_IPI_VID_HLINE_MAN_CFG	0x031c
+#define VID_HLINE_TIME(x)		FIELD_PREP(GENMASK(29, 0), x)
+#define DSI2_IPI_VID_VSA_MAN_CFG	0x0324
+#define VID_VSA_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
+#define DSI2_IPI_VID_VBP_MAN_CFG	0X032C
+#define VID_VBP_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
+#define DSI2_IPI_VID_VACT_MAN_CFG	0X0334
+#define VID_VACT_LINES(x)		FIELD_PREP(GENMASK(13, 0), x)
+#define DSI2_IPI_VID_VFP_MAN_CFG	0X033C
+#define VID_VFP_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
+#define DSI2_IPI_PIX_PKT_CFG		0x0344
+#define MAX_PIX_PKT(x)			FIELD_PREP(GENMASK(15, 0), x)
+
+#define DSI2_INT_ST_PHY			0x0400
+#define DSI2_INT_MASK_PHY		0x0404
+#define DSI2_INT_ST_TO			0x0410
+#define DSI2_INT_MASK_TO		0x0414
+#define DSI2_INT_ST_ACK			0x0420
+#define DSI2_INT_MASK_ACK		0x0424
+#define DSI2_INT_ST_IPI			0x0430
+#define DSI2_INT_MASK_IPI		0x0434
+#define DSI2_INT_ST_FIFO		0x0440
+#define DSI2_INT_MASK_FIFO		0x0444
+#define DSI2_INT_ST_PRI			0x0450
+#define DSI2_INT_MASK_PRI		0x0454
+#define DSI2_INT_ST_CRI			0x0460
+#define DSI2_INT_MASK_CRI		0x0464
+#define DSI2_INT_FORCE_CRI		0x0468
+#define DSI2_MAX_REGISGER		DSI2_INT_FORCE_CRI
+
+#define MODE_STATUS_TIMEOUT_US		10000
+#define CMD_PKT_STATUS_TIMEOUT_US	20000
+
+enum vid_mode_type {
+	VID_MODE_TYPE_NON_BURST_SYNC_PULSES,
+	VID_MODE_TYPE_NON_BURST_SYNC_EVENTS,
+	VID_MODE_TYPE_BURST,
+};
+
+enum mode_ctrl {
+	IDLE_MODE,
+	AUTOCALC_MODE,
+	COMMAND_MODE,
+	VIDEO_MODE,
+	DATA_STREAM_MODE,
+	VIDEO_TEST_MODE,
+	DATA_STREAM_TEST_MODE,
+};
+
+enum ppi_width {
+	PPI_WIDTH_8_BITS,
+	PPI_WIDTH_16_BITS,
+	PPI_WIDTH_32_BITS,
+};
+
+struct cmd_header {
+	u8 cmd_type;
+	u8 delay;
+	u8 payload_length;
+};
+
+struct dw_mipi_dsi2 {
+	struct drm_bridge bridge;
+	struct mipi_dsi_host dsi_host;
+	struct drm_bridge *panel_bridge;
+	struct device *dev;
+	struct regmap *regmap;
+	struct clk *pclk;
+	struct clk *sys_clk;
+
+	unsigned int lane_mbps; /* per lane */
+	u32 channel;
+	u32 lanes;
+	u32 format;
+	unsigned long mode_flags;
+
+	struct drm_display_mode mode;
+	const struct dw_mipi_dsi2_plat_data *plat_data;
+};
+
+static inline struct dw_mipi_dsi2 *host_to_dsi2(struct mipi_dsi_host *host)
+{
+	return container_of(host, struct dw_mipi_dsi2, dsi_host);
+}
+
+static inline struct dw_mipi_dsi2 *bridge_to_dsi2(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct dw_mipi_dsi2, bridge);
+}
+
+static int cri_fifos_wait_avail(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 sts, mask;
+	int ret;
+
+	mask = CRI_BUSY | CRT_FIFOS_NOT_EMPTY;
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS, sts,
+				       !(sts & mask), 0, CMD_PKT_STATUS_TIMEOUT_US);
+	if (ret < 0) {
+		dev_err(dsi2->dev, "command interface is busy\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_set_vid_mode(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 val = 0, mode;
+	int ret;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP)
+		val |= BLK_HFP_HS_EN;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP)
+		val |= BLK_HBP_HS_EN;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HSA)
+		val |= BLK_HSA_HS_EN;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+		val |= VID_MODE_TYPE_BURST;
+	else if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+		val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES;
+	else
+		val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
+
+	regmap_write(dsi2->regmap, DSI2_DSI_VID_TX_CFG, val);
+
+	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, VIDEO_MODE);
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
+				       mode, mode & VIDEO_MODE,
+				       1000, MODE_STATUS_TIMEOUT_US);
+	if (ret < 0)
+		dev_err(dsi2->dev, "failed to enter video mode\n");
+}
+
+static void dw_mipi_dsi2_set_data_stream_mode(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 mode;
+	int ret;
+
+	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, DATA_STREAM_MODE);
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
+				       mode, mode & DATA_STREAM_MODE,
+				       1000, MODE_STATUS_TIMEOUT_US);
+	if (ret < 0)
+		dev_err(dsi2->dev, "failed to enter data stream mode\n");
+}
+
+static void dw_mipi_dsi2_set_cmd_mode(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 mode;
+	int ret;
+
+	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, COMMAND_MODE);
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
+				       mode, mode & COMMAND_MODE,
+				       1000, MODE_STATUS_TIMEOUT_US);
+	if (ret < 0)
+		dev_err(dsi2->dev, "failed to enter data stream mode\n");
+}
+
+static void dw_mipi_dsi2_host_softrst(struct dw_mipi_dsi2 *dsi2)
+{
+	regmap_write(dsi2->regmap, DSI2_SOFT_RESET, 0x0);
+	usleep_range(50, 100);
+	regmap_write(dsi2->regmap, DSI2_SOFT_RESET,
+		   SYS_RSTN | PHY_RSTN | IPI_RSTN);
+}
+
+static void dw_mipi_dsi2_phy_clk_mode_cfg(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 sys_clk, esc_clk_div;
+	u32 val = 0;
+
+	/*
+	 * clk_type should be NON_CONTINUOUS_CLK before
+	 * initial deskew calibration be sent.
+	 */
+	val |= NON_CONTINUOUS_CLK;
+
+	/* The maximum value of the escape clock frequency is 20MHz */
+	sys_clk = clk_get_rate(dsi2->sys_clk) / USEC_PER_SEC;
+	esc_clk_div = DIV_ROUND_UP(sys_clk, 20 * 2);
+	val |= PHY_LPTX_CLK_DIV(esc_clk_div);
+
+	regmap_write(dsi2->regmap, DSI2_PHY_CLK_CFG, val);
+}
+
+static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2)
+{
+	struct drm_display_mode *mode = &dsi2->mode;
+	u64 sys_clk = clk_get_rate(dsi2->sys_clk);
+	u64 pixel_clk, ipi_clk, phy_hsclk;
+	u64 tmp;
+
+	/*
+	 * in DPHY mode, the phy_hstx_clk is exactly 1/16 the Lane high-speed
+	 * data rate; In CPHY mode, the phy_hstx_clk is exactly 1/7 the trio
+	 * high speed symbol rate.
+	 */
+	phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
+
+	/* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */
+	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
+	ipi_clk = pixel_clk / 4;
+
+	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, ipi_clk);
+	regmap_write(dsi2->regmap, DSI2_PHY_IPI_RATIO_MAN_CFG,
+		   PHY_IPI_RATIO(tmp));
+
+	/*
+	 * SYS_RATIO_MAN_CFG = MIPI_DCPHY_HSCLK_Freq / MIPI_DCPHY_HSCLK_Freq
+	 */
+	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, sys_clk);
+	regmap_write(dsi2->regmap, DSI2_PHY_SYS_RATIO_MAN_CFG,
+		   PHY_SYS_RATIO(tmp));
+}
+
+static void dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(struct dw_mipi_dsi2 *dsi2)
+{
+	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
+	struct dw_mipi_dsi2_phy_timing timing;
+	int ret;
+
+	ret = phy_ops->get_timing(dsi2->plat_data->priv_data,
+				  dsi2->lane_mbps, &timing);
+	if (ret)
+		dev_err(dsi2->dev, "Retrieving phy timings failed\n");
+
+	regmap_write(dsi2->regmap, DSI2_PHY_LP2HS_MAN_CFG, PHY_LP2HS_TIME(timing.data_lp2hs));
+	regmap_write(dsi2->regmap, DSI2_PHY_HS2LP_MAN_CFG, PHY_HS2LP_TIME(timing.data_hs2lp));
+}
+
+static void dw_mipi_dsi2_phy_init(struct dw_mipi_dsi2 *dsi2)
+{
+	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
+	struct dw_mipi_dsi2_phy_iface iface;
+	u32 val = 0;
+
+	phy_ops->get_interface(dsi2->plat_data->priv_data, &iface);
+
+	switch (iface.ppi_width) {
+	case 8:
+		val |= PPI_WIDTH(PPI_WIDTH_8_BITS);
+		break;
+	case 16:
+		val |= PPI_WIDTH(PPI_WIDTH_16_BITS);
+		break;
+	case 32:
+		val |= PPI_WIDTH(PPI_WIDTH_32_BITS);
+		break;
+	default:
+		/* Caught in probe */
+		break;
+	}
+
+	val |= PHY_LANES(dsi2->lanes);
+	val |= PHY_TYPE(DW_MIPI_DSI2_DPHY);
+	regmap_write(dsi2->regmap, DSI2_PHY_MODE_CFG, val);
+
+	dw_mipi_dsi2_phy_clk_mode_cfg(dsi2);
+	dw_mipi_dsi2_phy_ratio_cfg(dsi2);
+	dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2);
+
+	/* phy configuration 8 - 10 */
+}
+
+static void dw_mipi_dsi2_tx_option_set(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 val;
+
+	val = BTA_EN | EOTP_TX_EN;
+
+	if (dsi2->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
+		val &= ~EOTP_TX_EN;
+
+	regmap_write(dsi2->regmap, DSI2_DSI_GENERAL_CFG, val);
+	regmap_write(dsi2->regmap, DSI2_DSI_VCID_CFG, TX_VCID(dsi2->channel));
+}
+
+static void dw_mipi_dsi2_ipi_color_coding_cfg(struct dw_mipi_dsi2 *dsi2)
+{
+	u32 val, color_depth;
+
+	switch (dsi2->format) {
+	case MIPI_DSI_FMT_RGB666:
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		color_depth = IPI_DEPTH_6_BITS;
+		break;
+	case MIPI_DSI_FMT_RGB565:
+		color_depth = IPI_DEPTH_5_6_5_BITS;
+		break;
+	case MIPI_DSI_FMT_RGB888:
+	default:
+		color_depth = IPI_DEPTH_8_BITS;
+		break;
+	}
+
+	val = IPI_DEPTH(color_depth) |
+	      IPI_FORMAT(IPI_FORMAT_RGB);
+	regmap_write(dsi2->regmap, DSI2_IPI_COLOR_MAN_CFG, val);
+}
+
+static void dw_mipi_dsi2_vertical_timing_config(struct dw_mipi_dsi2 *dsi2,
+						const struct drm_display_mode *mode)
+{
+	u32 vactive, vsa, vfp, vbp;
+
+	vactive = mode->vdisplay;
+	vsa = mode->vsync_end - mode->vsync_start;
+	vfp = mode->vsync_start - mode->vdisplay;
+	vbp = mode->vtotal - mode->vsync_end;
+
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_VSA_MAN_CFG, VID_VSA_LINES(vsa));
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_VBP_MAN_CFG, VID_VBP_LINES(vbp));
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_VACT_MAN_CFG, VID_VACT_LINES(vactive));
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_VFP_MAN_CFG, VID_VFP_LINES(vfp));
+}
+
+static void dw_mipi_dsi2_ipi_set(struct dw_mipi_dsi2 *dsi2)
+{
+	struct drm_display_mode *mode = &dsi2->mode;
+	u32 hline, hsa, hbp, hact;
+	u64 hline_time, hsa_time, hbp_time, hact_time, tmp;
+	u64 pixel_clk, phy_hs_clk;
+	u16 val;
+
+	val = mode->hdisplay;
+
+	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, MAX_PIX_PKT(val));
+
+	dw_mipi_dsi2_ipi_color_coding_cfg(dsi2);
+
+	/*
+	 * if the controller is intended to operate in data stream mode,
+	 * no more steps are required.
+	 */
+	if (!(dsi2->mode_flags & MIPI_DSI_MODE_VIDEO))
+		return;
+
+	hact = mode->hdisplay;
+	hsa = mode->hsync_end - mode->hsync_start;
+	hbp = mode->htotal - mode->hsync_end;
+	hline = mode->htotal;
+
+	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
+
+	phy_hs_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
+
+	tmp = hsa * phy_hs_clk;
+	hsa_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_HSA_MAN_CFG, VID_HSA_TIME(hsa_time));
+
+	tmp = hbp * phy_hs_clk;
+	hbp_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_HBP_MAN_CFG, VID_HBP_TIME(hbp_time));
+
+	tmp = hact * phy_hs_clk;
+	hact_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_HACT_MAN_CFG, VID_HACT_TIME(hact_time));
+
+	tmp = hline * phy_hs_clk;
+	hline_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
+	regmap_write(dsi2->regmap, DSI2_IPI_VID_HLINE_MAN_CFG, VID_HLINE_TIME(hline_time));
+
+	dw_mipi_dsi2_vertical_timing_config(dsi2, mode);
+}
+
+static void
+dw_mipi_dsi2_work_mode(struct dw_mipi_dsi2 *dsi2, u32 mode)
+{
+	/*
+	 * select controller work in Manual mode
+	 * Manual: MANUAL_MODE_EN
+	 * Automatic: 0
+	 */
+	regmap_write(dsi2->regmap, MANUAL_MODE_CFG, mode);
+}
+
+static int dw_mipi_dsi2_host_attach(struct mipi_dsi_host *host,
+				    struct mipi_dsi_device *device)
+{
+	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	struct drm_bridge *bridge;
+	int ret;
+
+	if (device->lanes > dsi2->plat_data->max_data_lanes) {
+		dev_err(dsi2->dev, "the number of data lanes(%u) is too many\n",
+			device->lanes);
+		return -EINVAL;
+	}
+
+	dsi2->lanes = device->lanes;
+	dsi2->channel = device->channel;
+	dsi2->format = device->format;
+	dsi2->mode_flags = device->mode_flags;
+
+	bridge = devm_drm_of_get_bridge(dsi2->dev, dsi2->dev->of_node, 1, 0);
+	if (IS_ERR(bridge))
+		return PTR_ERR(bridge);
+
+	bridge->pre_enable_prev_first = true;
+	dsi2->panel_bridge = bridge;
+
+	drm_bridge_add(&dsi2->bridge);
+
+	if (pdata->host_ops && pdata->host_ops->attach) {
+		ret = pdata->host_ops->attach(pdata->priv_data, device);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_host_detach(struct mipi_dsi_host *host,
+				    struct mipi_dsi_device *device)
+{
+	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	int ret;
+
+	if (pdata->host_ops && pdata->host_ops->detach) {
+		ret = pdata->host_ops->detach(pdata->priv_data, device);
+		if (ret < 0)
+			return ret;
+	}
+
+	drm_bridge_remove(&dsi2->bridge);
+
+	drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_gen_pkt_hdr_write(struct dw_mipi_dsi2 *dsi2,
+					  u32 hdr_val, bool lpm)
+{
+	int ret;
+
+	regmap_write(dsi2->regmap, DSI2_CRI_TX_HDR, hdr_val | CMD_TX_MODE(lpm));
+
+	ret = cri_fifos_wait_avail(dsi2);
+	if (ret) {
+		dev_err(dsi2->dev, "failed to write command header\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int dw_mipi_dsi2_write(struct dw_mipi_dsi2 *dsi2,
+			      const struct mipi_dsi_packet *packet, bool lpm)
+{
+	const u8 *tx_buf = packet->payload;
+	int len = packet->payload_length, pld_data_bytes = sizeof(u32);
+	__le32 word;
+
+	/* Send payload */
+	while (len) {
+		if (len < pld_data_bytes) {
+			word = 0;
+			memcpy(&word, tx_buf, len);
+			regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, le32_to_cpu(word));
+			len = 0;
+		} else {
+			memcpy(&word, tx_buf, pld_data_bytes);
+			regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, le32_to_cpu(word));
+			tx_buf += pld_data_bytes;
+			len -= pld_data_bytes;
+		}
+	}
+
+	word = 0;
+	memcpy(&word, packet->header, sizeof(packet->header));
+	return dw_mipi_dsi2_gen_pkt_hdr_write(dsi2, le32_to_cpu(word), lpm);
+}
+
+static int dw_mipi_dsi2_read(struct dw_mipi_dsi2 *dsi2,
+			     const struct mipi_dsi_msg *msg)
+{
+	u8 *payload = msg->rx_buf;
+	int i, j, ret, len = msg->rx_len;
+	u8 data_type;
+	u16 wc;
+	u32 val;
+
+	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS,
+				       val, val & CRI_RD_DATA_AVAIL,
+				       100, CMD_PKT_STATUS_TIMEOUT_US);
+	if (ret) {
+		dev_err(dsi2->dev, "CRI has no available read data\n");
+		return ret;
+	}
+
+	regmap_read(dsi2->regmap, DSI2_CRI_RX_HDR, &val);
+	data_type = val & 0x3f;
+
+	if (mipi_dsi_packet_format_is_short(data_type)) {
+		for (i = 0; i < len && i < 2; i++)
+			payload[i] = (val >> (8 * (i + 1))) & 0xff;
+
+		return 0;
+	}
+
+	wc = (val >> 8) & 0xffff;
+	/* Receive payload */
+	for (i = 0; i < len && i < wc; i += 4) {
+		regmap_read(dsi2->regmap, DSI2_CRI_RX_PLD, &val);
+		for (j = 0; j < 4 && j + i < len && j + i < wc; j++)
+			payload[i + j] = val >> (8 * j);
+	}
+
+	return 0;
+}
+
+static ssize_t dw_mipi_dsi2_host_transfer(struct mipi_dsi_host *host,
+					  const struct mipi_dsi_msg *msg)
+{
+	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
+	bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM;
+	struct mipi_dsi_packet packet;
+	int ret, nb_bytes;
+
+	regmap_update_bits(dsi2->regmap, DSI2_DSI_VID_TX_CFG,
+			   LPDT_DISPLAY_CMD_EN,
+			   lpm ? LPDT_DISPLAY_CMD_EN : 0);
+
+	/* create a packet to the DSI protocol */
+	ret = mipi_dsi_create_packet(&packet, msg);
+	if (ret) {
+		dev_err(dsi2->dev, "failed to create packet: %d\n", ret);
+		return ret;
+	}
+
+	ret = cri_fifos_wait_avail(dsi2);
+	if (ret)
+		return ret;
+
+	ret = dw_mipi_dsi2_write(dsi2, &packet, lpm);
+	if (ret)
+		return ret;
+
+	if (msg->rx_buf && msg->rx_len) {
+		ret = dw_mipi_dsi2_read(dsi2, msg);
+		if (ret < 0)
+			return ret;
+		nb_bytes = msg->rx_len;
+	} else {
+		nb_bytes = packet.size;
+	}
+
+	return nb_bytes;
+}
+
+static const struct mipi_dsi_host_ops dw_mipi_dsi2_host_ops = {
+	.attach = dw_mipi_dsi2_host_attach,
+	.detach = dw_mipi_dsi2_host_detach,
+	.transfer = dw_mipi_dsi2_host_transfer,
+};
+
+static u32 *
+dw_mipi_dsi2_bridge_atomic_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 dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	u32 *input_fmts;
+
+	if (pdata->get_input_bus_fmts)
+		return pdata->get_input_bus_fmts(pdata->priv_data,
+						 bridge, bridge_state,
+						 crtc_state, conn_state,
+						 output_fmt, num_input_fmts);
+
+	/* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */
+	input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
+	if (!input_fmts)
+		return NULL;
+	input_fmts[0] = MEDIA_BUS_FMT_FIXED;
+	*num_input_fmts = 1;
+
+	return input_fmts;
+}
+
+static int dw_mipi_dsi2_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 dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	bool ret;
+
+	bridge_state->input_bus_cfg.flags =
+		DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE;
+
+	if (pdata->mode_fixup) {
+		ret = pdata->mode_fixup(pdata->priv_data, &crtc_state->mode,
+					&crtc_state->adjusted_mode);
+		if (!ret) {
+			DRM_DEBUG_DRIVER("failed to fixup mode " DRM_MODE_FMT "\n",
+					 DRM_MODE_ARG(&crtc_state->mode));
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void dw_mipi_dsi2_bridge_post_atomic_disable(struct drm_bridge *bridge,
+						    struct drm_bridge_state *old_bridge_state)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
+
+	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, 0);
+
+	/*
+	 * Switch to command mode before panel-bridge post_disable &
+	 * panel unprepare.
+	 * Note: panel-bridge disable & panel disable has been called
+	 * before by the drm framework.
+	 */
+	dw_mipi_dsi2_set_cmd_mode(dsi2);
+
+	regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET);
+
+	if (phy_ops->power_off)
+		phy_ops->power_off(dsi2->plat_data->priv_data);
+
+	clk_disable_unprepare(dsi2->sys_clk);
+	clk_disable_unprepare(dsi2->pclk);
+	pm_runtime_put(dsi2->dev);
+}
+
+static unsigned int dw_mipi_dsi2_get_lanes(struct dw_mipi_dsi2 *dsi2)
+{
+	/* single-dsi, so no other instance to consider */
+	return dsi2->lanes;
+}
+
+static void dw_mipi_dsi2_mode_set(struct dw_mipi_dsi2 *dsi2,
+				  const struct drm_display_mode *adjusted_mode)
+{
+	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
+	void *priv_data = dsi2->plat_data->priv_data;
+	u32 lanes = dw_mipi_dsi2_get_lanes(dsi2);
+	int ret;
+
+	clk_prepare_enable(dsi2->pclk);
+	clk_prepare_enable(dsi2->sys_clk);
+
+	ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi2->mode_flags,
+				     lanes, dsi2->format, &dsi2->lane_mbps);
+	if (ret)
+		DRM_DEBUG_DRIVER("Phy get_lane_mbps() failed\n");
+
+	pm_runtime_get_sync(dsi2->dev);
+
+	dw_mipi_dsi2_host_softrst(dsi2);
+	regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET);
+
+	dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN);
+	dw_mipi_dsi2_phy_init(dsi2);
+
+	if (phy_ops->power_on)
+		phy_ops->power_on(dsi2->plat_data->priv_data);
+
+	dw_mipi_dsi2_tx_option_set(dsi2);
+
+	/*
+	 * initial deskew calibration is send after phy_power_on,
+	 * then we can configure clk_type.
+	 */
+
+	regmap_update_bits(dsi2->regmap, DSI2_PHY_CLK_CFG, CLK_TYPE_MASK,
+			   dsi2->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS ? NON_CONTINUOUS_CLK :
+									      CONTINUOUS_CLK);
+
+	regmap_write(dsi2->regmap, DSI2_PWR_UP, POWER_UP);
+	dw_mipi_dsi2_set_cmd_mode(dsi2);
+
+	dw_mipi_dsi2_ipi_set(dsi2);
+}
+
+static void dw_mipi_dsi2_bridge_atomic_pre_enable(struct drm_bridge *bridge,
+						  struct drm_bridge_state *old_bridge_state)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+
+	/* Power up the dsi ctl into a command mode */
+	dw_mipi_dsi2_mode_set(dsi2, &dsi2->mode);
+}
+
+static void dw_mipi_dsi2_bridge_mode_set(struct drm_bridge *bridge,
+					 const struct drm_display_mode *mode,
+					 const struct drm_display_mode *adjusted_mode)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+
+	/* Store the display mode for later use in pre_enable callback */
+	drm_mode_copy(&dsi2->mode, adjusted_mode);
+}
+
+static void dw_mipi_dsi2_bridge_atomic_enable(struct drm_bridge *bridge,
+					      struct drm_bridge_state *old_bridge_state)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+
+	/* Switch to video mode for panel-bridge enable & panel enable */
+	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)
+		dw_mipi_dsi2_set_vid_mode(dsi2);
+	else
+		dw_mipi_dsi2_set_data_stream_mode(dsi2);
+}
+
+static enum drm_mode_status
+dw_mipi_dsi2_bridge_mode_valid(struct drm_bridge *bridge,
+			       const struct drm_display_info *info,
+			       const struct drm_display_mode *mode)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
+	enum drm_mode_status mode_status = MODE_OK;
+
+	if (pdata->mode_valid)
+		mode_status = pdata->mode_valid(pdata->priv_data, mode,
+						dsi2->mode_flags,
+						dw_mipi_dsi2_get_lanes(dsi2),
+						dsi2->format);
+
+	return mode_status;
+}
+
+static int dw_mipi_dsi2_bridge_attach(struct drm_bridge *bridge,
+				      enum drm_bridge_attach_flags flags)
+{
+	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
+
+	/* Set the encoder type as caller does not know it */
+	bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
+
+	/* Attach the panel-bridge to the dsi bridge */
+	return drm_bridge_attach(bridge->encoder, dsi2->panel_bridge, bridge,
+				 flags);
+}
+
+static const struct drm_bridge_funcs dw_mipi_dsi2_bridge_funcs = {
+	.atomic_duplicate_state	= drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state,
+	.atomic_get_input_bus_fmts = dw_mipi_dsi2_bridge_atomic_get_input_bus_fmts,
+	.atomic_check		= dw_mipi_dsi2_bridge_atomic_check,
+	.atomic_reset		= drm_atomic_helper_bridge_reset,
+	.atomic_pre_enable	= dw_mipi_dsi2_bridge_atomic_pre_enable,
+	.atomic_enable		= dw_mipi_dsi2_bridge_atomic_enable,
+	.atomic_post_disable	= dw_mipi_dsi2_bridge_post_atomic_disable,
+	.mode_set		= dw_mipi_dsi2_bridge_mode_set,
+	.mode_valid		= dw_mipi_dsi2_bridge_mode_valid,
+	.attach			= dw_mipi_dsi2_bridge_attach,
+};
+
+static const struct regmap_config dw_mipi_dsi2_regmap_config = {
+	.name = "dsi2-host",
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.fast_io = true,
+};
+
+static struct dw_mipi_dsi2 *
+__dw_mipi_dsi2_probe(struct platform_device *pdev,
+		     const struct dw_mipi_dsi2_plat_data *plat_data)
+{
+	struct device *dev = &pdev->dev;
+	struct reset_control *apb_rst;
+	struct dw_mipi_dsi2 *dsi2;
+	int ret;
+
+	dsi2 = devm_kzalloc(dev, sizeof(*dsi2), GFP_KERNEL);
+	if (!dsi2)
+		return ERR_PTR(-ENOMEM);
+
+	dsi2->dev = dev;
+	dsi2->plat_data = plat_data;
+
+	if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps ||
+	    !plat_data->phy_ops->get_timing)
+		return dev_err_ptr_probe(dev, -ENODEV, "Phy not properly configured\n");
+
+	if (!plat_data->regmap) {
+		void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
+
+		if (IS_ERR(base))
+			return dev_err_cast_probe(dev, base, "failed to registers\n");
+
+		dsi2->regmap = devm_regmap_init_mmio(dev, base,
+						     &dw_mipi_dsi2_regmap_config);
+		if (IS_ERR(dsi2->regmap))
+			return dev_err_cast_probe(dev, dsi2->regmap, "failed to init regmap\n");
+	} else {
+		dsi2->regmap = plat_data->regmap;
+	}
+
+	dsi2->pclk = devm_clk_get(dev, "pclk");
+	if (IS_ERR(dsi2->pclk))
+		return dev_err_cast_probe(dev, dsi2->pclk, "Unable to get pclk\n");
+
+	dsi2->sys_clk = devm_clk_get(dev, "sys");
+	if (IS_ERR(dsi2->sys_clk))
+		return dev_err_cast_probe(dev, dsi2->sys_clk, "Unable to get sys_clk\n");
+
+	/*
+	 * Note that the reset was not defined in the initial device tree, so
+	 * we have to be prepared for it not being found.
+	 */
+	apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb");
+	if (IS_ERR(apb_rst))
+		return dev_err_cast_probe(dev, apb_rst, "Unable to get reset control\n");
+
+	if (apb_rst) {
+		ret = clk_prepare_enable(dsi2->pclk);
+		if (ret) {
+			dev_err(dev, "%s: Failed to enable pclk\n", __func__);
+			return ERR_PTR(ret);
+		}
+
+		reset_control_assert(apb_rst);
+		usleep_range(10, 20);
+		reset_control_deassert(apb_rst);
+
+		clk_disable_unprepare(dsi2->pclk);
+	}
+
+	devm_pm_runtime_enable(dev);
+
+	dsi2->dsi_host.ops = &dw_mipi_dsi2_host_ops;
+	dsi2->dsi_host.dev = dev;
+	ret = mipi_dsi_host_register(&dsi2->dsi_host);
+	if (ret) {
+		dev_err(dev, "Failed to register MIPI host: %d\n", ret);
+		pm_runtime_disable(dev);
+		return ERR_PTR(ret);
+	}
+
+	dsi2->bridge.driver_private = dsi2;
+	dsi2->bridge.funcs = &dw_mipi_dsi2_bridge_funcs;
+	dsi2->bridge.of_node = pdev->dev.of_node;
+
+	return dsi2;
+}
+
+static void __dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2)
+{
+	mipi_dsi_host_unregister(&dsi2->dsi_host);
+}
+
+/*
+ * Probe/remove API, used to create the bridge instance.
+ */
+struct dw_mipi_dsi2 *
+dw_mipi_dsi2_probe(struct platform_device *pdev,
+		   const struct dw_mipi_dsi2_plat_data *plat_data)
+{
+	return __dw_mipi_dsi2_probe(pdev, plat_data);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi2_probe);
+
+void dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2)
+{
+	__dw_mipi_dsi2_remove(dsi2);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi2_remove);
+
+/*
+ * Bind/unbind API, used from platforms based on the component framework
+ * to attach the bridge to an encoder.
+ */
+int dw_mipi_dsi2_bind(struct dw_mipi_dsi2 *dsi2, struct drm_encoder *encoder)
+{
+	return drm_bridge_attach(encoder, &dsi2->bridge, NULL, 0);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi2_bind);
+
+void dw_mipi_dsi2_unbind(struct dw_mipi_dsi2 *dsi2)
+{
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi2_unbind);
+
+MODULE_AUTHOR("Guochun Huang <hero.huang at rock-chips.com>");
+MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner at cherry.de>");
+MODULE_DESCRIPTION("DW MIPI DSI2 host controller driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dw-mipi-dsi2");
diff --git a/include/drm/bridge/dw_mipi_dsi2.h b/include/drm/bridge/dw_mipi_dsi2.h
new file mode 100644
index 000000000000..c18c49379247
--- /dev/null
+++ b/include/drm/bridge/dw_mipi_dsi2.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Authors: Guochun Huang <hero.huang at rock-chips.com>
+ *          Heiko Stuebner <heiko.stuebner at cherry.de>
+ */
+
+#ifndef __DW_MIPI_DSI2__
+#define __DW_MIPI_DSI2__
+
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_modes.h>
+
+struct drm_display_mode;
+struct drm_encoder;
+struct dw_mipi_dsi2;
+struct mipi_dsi_device;
+struct platform_device;
+
+enum dw_mipi_dsi2_phy_type {
+	DW_MIPI_DSI2_DPHY,
+	DW_MIPI_DSI2_CPHY,
+};
+
+struct dw_mipi_dsi2_phy_iface {
+	int ppi_width;
+	enum dw_mipi_dsi2_phy_type phy_type;
+};
+
+struct dw_mipi_dsi2_phy_timing {
+	u32 data_hs2lp;
+	u32 data_lp2hs;
+};
+
+struct dw_mipi_dsi2_phy_ops {
+	int (*init)(void *priv_data);
+	void (*power_on)(void *priv_data);
+	void (*power_off)(void *priv_data);
+	void (*get_interface)(void *priv_data, struct dw_mipi_dsi2_phy_iface *iface);
+	int (*get_lane_mbps)(void *priv_data,
+			     const struct drm_display_mode *mode,
+			     unsigned long mode_flags, u32 lanes, u32 format,
+			     unsigned int *lane_mbps);
+	int (*get_timing)(void *priv_data, unsigned int lane_mbps,
+			  struct dw_mipi_dsi2_phy_timing *timing);
+	int (*get_esc_clk_rate)(void *priv_data, unsigned int *esc_clk_rate);
+};
+
+struct dw_mipi_dsi2_host_ops {
+	int (*attach)(void *priv_data,
+		      struct mipi_dsi_device *dsi);
+	int (*detach)(void *priv_data,
+		      struct mipi_dsi_device *dsi);
+};
+
+struct dw_mipi_dsi2_plat_data {
+	struct regmap *regmap;
+	unsigned int max_data_lanes;
+
+	enum drm_mode_status (*mode_valid)(void *priv_data,
+					   const struct drm_display_mode *mode,
+					   unsigned long mode_flags,
+					   u32 lanes, u32 format);
+
+	bool (*mode_fixup)(void *priv_data, const struct drm_display_mode *mode,
+			   struct drm_display_mode *adjusted_mode);
+
+	u32 *(*get_input_bus_fmts)(void *priv_data,
+				   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);
+
+	const struct dw_mipi_dsi2_phy_ops *phy_ops;
+	const struct dw_mipi_dsi2_host_ops *host_ops;
+
+	void *priv_data;
+};
+
+struct dw_mipi_dsi2 *dw_mipi_dsi2_probe(struct platform_device *pdev,
+					const struct dw_mipi_dsi2_plat_data *plat_data);
+void dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2);
+int dw_mipi_dsi2_bind(struct dw_mipi_dsi2 *dsi2, struct drm_encoder *encoder);
+void dw_mipi_dsi2_unbind(struct dw_mipi_dsi2 *dsi2);
+
+#endif /* __DW_MIPI_DSI2__ */
-- 
2.45.2



From heiko at sntech.de  Mon Dec  9 15:12:26 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 10 Dec 2024 00:12:26 +0100
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2 controller
In-Reply-To: <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241209150619.33998-1-dse@thaumatec.com>
 <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org>
Message-ID: <2203458.KiezcSG77Q@diego>

Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
> Hi,
> 
> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
> > On 03.12.24 21:54, Heiko Stuebner wrote:
> > > This series adds a bridge and glue driver for the DSI2 controller found
> > > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
> > > 
> >
> > I did more tests with different LVDS displays. I tested following
> > configurations with DSI/LVDS bridge:
> > - 1024x600 at 60.01
> > - 1024x768 at 60.02
> > - 1280x800 at 60.07
> > - 1366x768 at 60.06
> >
> > All of them worked without issues, except 1366x768.
> > With this resolution, video is blurry, and offset incorrectly
> > to the left. There are also repeating errors on the console:
> >
> >   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
> >
> > In correct operation with other resolutions, there is no error.
> > I am not sure if this is a problem in your series or rather in VOP2
> > driver.

This really sounds like something is wrong on the vop side.
The interrupt is part of the vop, the divisable by 4 things likely too.


Heiko


> 
> On my PineTab2 I got similar messages about 2 weeks ago:
> rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp1
> 
> Preceding those, I got several panfrost related errors:
> 
> panfrost fde60000.gpu: get clock failed -517
> panfrost fde60000.gpu: clk init failed -517
> platform fde60000.gpu: deferred probe pending: (reason unknown)
> platform cpufreq-dt: deferred probe pending: (reason unknown)
> vdd_gpu_npu: disabling
> 
> But can also be that the PineTab2 (likely) needs regulator-always-on
> and regulator-boot-on in its vdd_gpu_npu node.
> 
> > I tried to track down the problem, and it seems to be a generic issue
> > when horizontal line width is not divisible by 4.
> > Lowering line width to 1364px fixes the issue, but of course I have two
> > vertical lines of black pixels on the right.
> > I also made some tests with 720x1280 DSI display. Lowering horizontal
> > line to 718px shows the same problem. With 720px and 716px it works
> > correctly.
> 
> I haven't look further into it, but the PT2 has a 1280x800 resolution.
> 
> HTH,
>   Diederik
> 






From dmitry.baryshkov at linaro.org  Mon Dec  9 15:13:19 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 01:13:19 +0200
Subject: [PATCH 2/6] arm64: errata: Add QCOM_KRYO_2XX_GOLD to the
 spectre_bhb_firmware_mitigated_list
In-Reply-To: <20241209094310.2.Ia3dfc0afadbfbee81bb2efb0672262470973dd08@changeid>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.2.Ia3dfc0afadbfbee81bb2efb0672262470973dd08@changeid>
Message-ID: <wx6qbdbcrvbq34snzkxawlbpxm6vogt5ccjmdqqyazukfbjy7t@qkvax7tr27bs>

On Mon, Dec 09, 2024 at 09:43:12AM -0800, Douglas Anderson wrote:
> Qualcomm Kryo 200-series Gold cores appear to have a derivative of an
> ARM Cortex A73 in them. Since A73 needs Spectre mitigation then the
> Kyro 200-series Gold cores also should need Spectre mitigation.
> 
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---
> I don't really have any good way to test this patch but it seems
> likely it's needed. If nothing else the claim is that that Qualcomm
> Kyro 280 CPU is vulnerable [1] but I don't see any mitigations in the
> kernel for it.
> 
> NOTE: presumably this patch won't actually do much on its own because
> (I believe) it requires a firmware update to go with it.

Why? is_spectre_bhb_fw_affected() returns true if (cpu in list OR fw
mitigated)

> 
> [1] https://spectreattack.com/spectre.pdf
> 
>  arch/arm64/kernel/proton-pack.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
> index e149efadff20..0437be7c83bc 100644
> --- a/arch/arm64/kernel/proton-pack.c
> +++ b/arch/arm64/kernel/proton-pack.c
> @@ -925,6 +925,7 @@ static bool is_spectre_bhb_fw_affected(int scope)
>  	static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
>  		MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
>  		MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
> +		MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_GOLD),
>  		{},
>  	};
>  	bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
> -- 
> 2.47.0.338.g60cca15819-goog
> 

-- 
With best wishes
Dmitry


From xiaolei.wang at windriver.com  Mon Dec  9 15:14:12 2024
From: xiaolei.wang at windriver.com (wang xiaolei)
Date: Tue, 10 Dec 2024 10:14:12 +1100
Subject: [PATCH] serial: imx: Use uart_port_lock_irqsave() instead of
 uart_port_lock()
In-Reply-To: <ea1ca102ab0ec5068d82935623fd9ffb0b9aade1.camel@pengutronix.de>
References: <20241209124732.693834-1-xiaolei.wang@windriver.com>
 <ea1ca102ab0ec5068d82935623fd9ffb0b9aade1.camel@pengutronix.de>
Message-ID: <c12f933e-d749-4fde-90c4-8fa46744c680@windriver.com>


On 12/10/24 1:37 AM, Lucas Stach wrote:
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> Am Montag, dem 09.12.2024 um 20:47 +0800 schrieb Xiaolei Wang:
>> When executing 'ehco mem > /sys/power/state', the following
>> deadlock occurs. Since there is output during the serial
>> port entering the suspend process, the suspend will be
>> interrupted, resulting in the nesting of locks. Therefore,
>> use uart_port_lock_irqsave instead of uart_port_unlock.
>>
>> WARNING: inconsistent lock state
>> 6.12.0-rc2-00002-g3c199ed5bd64-dirty #23 Not tainted
>> --------------------------------
>> inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
>> sh/494 [HC0[0]:SC0[0]:HE1:SE1] takes:
>> c4db5850 (&port_lock_key){?.-.}-{3:3}, at: imx_uart_enable_wakeup+0x14/0x254
>> {IN-HARDIRQ-W} state was registered at:
>>    lock_acquire+0x104/0x348
>>    _raw_spin_lock+0x48/0x84
>>    imx_uart_int+0x14/0x4dc
>>    __handle_irq_event_percpu+0xac/0x2fc
>>    handle_irq_event_percpu+0xc/0x40
>>    handle_irq_event+0x38/0x8c
>>    handle_fasteoi_irq+0xb4/0x1b8
>>    handle_irq_desc+0x1c/0x2c
>>    gic_handle_irq+0x6c/0xa0
>>    generic_handle_arch_irq+0x2c/0x64
>>    call_with_stack+0x18/0x20
>>    __irq_svc+0x9c/0xbc
>>    _raw_spin_unlock_irqrestore+0x2c/0x48
>>    uart_write+0xd8/0x3a0
>>    do_output_char+0x1a8/0x1e4
>>    n_tty_write+0x224/0x440
>>    file_tty_write.constprop.0+0x124/0x250
>>    do_iter_readv_writev+0x100/0x1e0
>>    vfs_writev+0xc4/0x448
>>    do_writev+0x68/0xf8
>>    ret_fast_syscall+0x0/0x1c
>> irq event stamp: 31593
>> hardirqs last  enabled at (31593): [<c1150e48>] _raw_spin_unlock_irqrestore+0x44/0x48
>> hardirqs last disabled at (31592): [<c07f32f0>] clk_enable_lock+0x60/0x120
>> softirqs last  enabled at (30334): [<c012d1d4>] handle_softirqs+0x2cc/0x478
>> softirqs last disabled at (30325): [<c012d510>] __irq_exit_rcu+0x120/0x15c
>>
>> other info that might help us debug this:
>>   Possible unsafe locking scenario:
>>
>>         CPU0
>>         ----
>>    lock(&port_lock_key);
>>    <Interrupt>
>>      lock(&port_lock_key);
>>
>> Fixes: 3c199ed5bd64 ("serial: imx: Grab port lock in imx_uart_enable_wakeup()")
>> Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>
>> ---
>>   drivers/tty/serial/imx.c | 5 +++--
>>   1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
>> index 17f70e4bee43..4470bcb3ef19 100644
>> --- a/drivers/tty/serial/imx.c
>> +++ b/drivers/tty/serial/imx.c
>> @@ -2691,8 +2691,9 @@ static void imx_uart_save_context(struct imx_port *sport)
>>   static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
>>   {
>>        u32 ucr3;
>> +     unsigned long flags;
>>
>> -     uart_port_lock(&sport->port);
>> +     uart_port_lock_irqsave(&sport->port, &flags);
> This function is only called from process context, so it should be fine
> to use uart_port_lock_irq().
Thank you for your reminder, Lucas, I will send a new version

thanks
xiaolei
>
> Regards,
> Lucas
>
>>        ucr3 = imx_uart_readl(sport, UCR3);
>>        if (on) {
>> @@ -2714,7 +2715,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
>>                imx_uart_writel(sport, ucr1, UCR1);
>>        }
>>
>> -     uart_port_unlock(&sport->port);
>> +     uart_port_unlock_irqrestore(&sport->port, flags);
>>   }
>>
>>   static int imx_uart_suspend_noirq(struct device *dev)


From kuba at kernel.org  Mon Dec  9 15:18:13 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 9 Dec 2024 15:18:13 -0800
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <20241209134459.27110-6-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
	<20241209134459.27110-6-ansuelsmth@gmail.com>
Message-ID: <20241209151813.106eda03@kernel.org>

On Mon,  9 Dec 2024 14:44:22 +0100 Christian Marangi wrote:
> +	regmap = devm_regmap_init(priv->dev, NULL, priv,
> +				  &an8855_regmap_config);
> +	if (IS_ERR(regmap))
            ^^^^^^^^^^^^^^
> +		dev_err_probe(priv->dev, PTR_ERR(priv->dev),
                                         ^^^^^^^^^^^^^^^^^^
> +			      "regmap initialization failed\n");

wrong ptr?
-- 
pw-bot: cr


From heiko at sntech.de  Mon Dec  9 15:10:18 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 10 Dec 2024 00:10:18 +0100
Subject: [PATCH v4 0/3] drm/rockchip: Add driver for the new DSI2 controller
Message-ID: <20241209231021.2180582-1-heiko@sntech.de>

This series adds a bridge and glue driver for the DSI2 controller found
in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.

As the manual states:
The Display Serial Interface 2 (DSI-2) is part of a group of communication
protocols defined by the MIPI Alliance. The MIPI DSI-2 Host Controller is
a digital core that implements all protocol functions defined in the
MIPI DSI-2 Specification.


While the driver structure is very similar to the previous DSI controller,
the programming model of the core is quite different, with a completely
new register set.

Another notable difference is that the phy interface is variable now too
in its width and some other settings.

changes in v4:
- Update binding example to use phy-type argument
- Update commit description to use correctly spelled Synopsys
- use devm_pm_runtime_enable()
- drop pclk+sys_clk handling from the Rockchip glue-driver
  (the bridge does that for us already)

changes in v3:
- remove double-empty line in bridge part (Neil)
- add bitfield.h to both bridge and glue for FIELD_PROP
  (reported by kernel test robot)
- add Neil's Reviewed-by to bridge part
- add Rob's Reviewed-by to binding

changes in v2:
- clean up includes (Diederik)
- fix Kconfig description (Diederik)
- constant naming (Diederik)
- binding fixes (paths, sorting, labels) (Rob)
- move to use regmap
- drop custom UPDATE macro and use FIELD_PREP instead
- use dev_err instead of DRM_DEV_ERROR

Heiko Stuebner (3):
  drm/bridge/synopsys: Add MIPI DSI2 host controller bridge
  dt-bindings: display: rockchip: Add schema for RK3588 DW DSI2
    controller
  drm/rockchip: Add MIPI DSI2 glue driver for RK3588

 .../rockchip/rockchip,rk3588-mipi-dsi2.yaml   |  120 ++
 drivers/gpu/drm/bridge/synopsys/Kconfig       |    6 +
 drivers/gpu/drm/bridge/synopsys/Makefile      |    1 +
 .../gpu/drm/bridge/synopsys/dw-mipi-dsi2.c    | 1030 +++++++++++++++++
 drivers/gpu/drm/rockchip/Kconfig              |   10 +
 drivers/gpu/drm/rockchip/Makefile             |    1 +
 .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c  |  487 ++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |    2 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |    1 +
 include/drm/bridge/dw_mipi_dsi2.h             |   95 ++
 10 files changed, 1753 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml
 create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
 create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
 create mode 100644 include/drm/bridge/dw_mipi_dsi2.h

-- 
2.45.2



From heiko at sntech.de  Mon Dec  9 15:10:20 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 10 Dec 2024 00:10:20 +0100
Subject: [PATCH v4 2/3] dt-bindings: display: rockchip: Add schema for RK3588 DW DSI2 controller
In-Reply-To: <20241209231021.2180582-1-heiko@sntech.de>
References: <20241209231021.2180582-1-heiko@sntech.de>
Message-ID: <20241209231021.2180582-3-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

The Display Serial Interface 2 (DSI-2) is part of a group of communication
protocols defined by the MIPI Alliance. The RK3588 implements this
specification in its two MIPI DSI-2 Host Controllers that are based on a
new Synopsys IP.

Tested-by: Dmitry Yashin <dmt.yashin at gmail.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 .../rockchip/rockchip,rk3588-mipi-dsi2.yaml   | 120 ++++++++++++++++++
 1 file changed, 120 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml
new file mode 100644
index 000000000000..53384e47b507
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/rockchip/rockchip,rk3588-mipi-dsi2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip specific extensions to the Synopsys Designware MIPI DSI2
+
+maintainers:
+  - Heiko Stuebner <heiko at sntech.de>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3588-mipi-dsi2
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: sys
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      This SoC uses GRF regs to switch between vopl/vopb.
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: dcphy
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: apb
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Input node to receive pixel data.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: DSI output node to panel.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - rockchip,grf
+  - phys
+  - phy-names
+  - ports
+  - reg
+
+allOf:
+  - $ref: /schemas/display/dsi-controller.yaml#
+
+unevaluatedProperties: 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/phy/phy.h>
+    #include <dt-bindings/power/rk3588-power.h>
+    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      dsi at fde20000 {
+        compatible = "rockchip,rk3588-mipi-dsi2";
+        reg = <0x0 0xfde20000 0x0 0x10000>;
+        interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&cru PCLK_DSIHOST0>, <&cru CLK_DSIHOST0>;
+        clock-names = "pclk", "sys";
+        resets = <&cru SRST_P_DSIHOST0>;
+        reset-names = "apb";
+        power-domains = <&power RK3588_PD_VOP>;
+        phys = <&mipidcphy0 PHY_TYPE_DPHY>;
+        phy-names = "dcphy";
+        rockchip,grf = <&vop_grf>;
+
+        ports {
+          #address-cells = <1>;
+          #size-cells = <0>;
+          dsi0_in: port at 0 {
+            reg = <0>;
+          };
+
+          dsi0_out: port at 1 {
+            reg = <1>;
+          };
+        };
+      };
+    };
-- 
2.45.2



From Frank.li at nxp.com  Mon Dec  9 15:19:08 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 9 Dec 2024 18:19:08 -0500
Subject: [PATCH v11 3/7] PCI: endpoint: pci-ep-msi: Add MSI address/data
 pair mutable check
In-Reply-To: <87h67cprc7.ffs@tglx>
References: <20241209-ep-msi-v11-0-7434fa8397bd@nxp.com>
 <20241209-ep-msi-v11-3-7434fa8397bd@nxp.com>
 <87h67cprc7.ffs@tglx>
Message-ID: <Z1d67E7y2MOZ5tTi@lizhi-Precision-Tower-5810>

On Mon, Dec 09, 2024 at 08:51:52PM +0100, Thomas Gleixner wrote:
> Frank!
>
> On Mon, Dec 09 2024 at 12:48, Frank Li wrote:
>
> > Some MSI controller change address/data pair when irq_set_affinity().
> > Current PCI endpoint can't support this type MSI controller. So add flag
> > MSI_FLAG_MSG_IMMUTABLE in include/linux/msi.h, set this flags in ARM GIC
> > ITS MSI controller and check it when allocate doorbell.
> >
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > Change from v9 to v11
> > - new patch
> > ---
> >  drivers/irqchip/irq-gic-v3-its-msi-parent.c | 1 +
> >  drivers/pci/endpoint/pci-ep-msi.c           | 8 ++++++++
> >  include/linux/msi.h                         | 2 ++
>
> This is not how it works and I explained that you to more than once in
> the past.
>
> The change to the interrupt code is standalone and has nothing to do
> with PCI endpoint. The latter is just a user of this.
>
> So this want's to be split into several patches:
>
>    1) add the new flag and a helper function which checks for the flag.

msi.h have not included irqdomain.h. It needs a API in msi.c

+bool msi_domain_is_immutable(struct irq_domain *domain)
+{
+        if (!irq_domain_is_msi_parent(domain))
+                return false;
+
+        return domain->msi_parent_ops->supported_flags & MSI_FLAG_MSG_IMMUTABLE;
+}
+EXPORT_SYMBOL_GPL(msi_domain_is_immutable);

Is it okay?

Frank

>
>    2) add the flag to GICv3 ITS with a proper explanation
>
>    3) Check for it in the PCI endpoint code
>
> >
> > +	if (!dom->msi_parent_ops)
> > +		return -EINVAL;
>
> irq_domain_is_msi_parent()
>
> > +	if (!(dom->msi_parent_ops->supported_flags & MSI_FLAG_MSG_IMMUTABLE)) {
>
> Want's a helper.
>
> Thanks,
>
>         tglx


From jgg at nvidia.com  Mon Dec  9 15:21:57 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Mon, 9 Dec 2024 19:21:57 -0400
Subject: [PATCH 3/3] iommu/arm-smmu-v3: Remove domain_alloc_paging()
In-Reply-To: <20241209230611.GA13790@willie-the-truck>
References: <0-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
 <3-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
 <20241209230611.GA13790@willie-the-truck>
Message-ID: <20241209232157.GE2347147@nvidia.com>

On Mon, Dec 09, 2024 at 11:06:12PM +0000, Will Deacon wrote:
> On Thu, Dec 05, 2024 at 11:43:29AM -0400, Jason Gunthorpe wrote:
> > arm_smmu_domain_alloc_paging_flags() with a flags = 0 now does the same
> > thing as arm_smmu_domain_alloc_paging(), remove
> > arm_smmu_domain_alloc_paging().
> > 
> > Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> > ---
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 31 ---------------------
> >  1 file changed, 31 deletions(-)
> 
> Ha! I was reviewing the previous patch and about to reply asking why we
> couldn't just implement arm_smmu_domain_alloc_paging() as a wrapper
> around arm_smmu_domain_alloc_paging() with flags of 0.
> 
> Good thing I read ahead :)

Yes, the main point of the prior patch was to make this patch
possible :)

Jason


From ansuelsmth at gmail.com  Mon Dec  9 15:22:59 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Tue, 10 Dec 2024 00:22:59 +0100
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <20241209151813.106eda03@kernel.org>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209151813.106eda03@kernel.org>
Message-ID: <67577bd7.7b0a0220.1ce6b5.fe93@mx.google.com>

On Mon, Dec 09, 2024 at 03:18:13PM -0800, Jakub Kicinski wrote:
> On Mon,  9 Dec 2024 14:44:22 +0100 Christian Marangi wrote:
> > +	regmap = devm_regmap_init(priv->dev, NULL, priv,
> > +				  &an8855_regmap_config);
> > +	if (IS_ERR(regmap))
>             ^^^^^^^^^^^^^^
> > +		dev_err_probe(priv->dev, PTR_ERR(priv->dev),
>                                          ^^^^^^^^^^^^^^^^^^
> > +			      "regmap initialization failed\n");
> 
> wrong ptr?

yes wth... I'm sorry for all these stupid mistake for this series...
Also hope we won't have to request multiple stable tag for this multi
subsystem patch. Any hint on that?

-- 
	Ansuel


From jwerner at chromium.org  Mon Dec  9 15:34:59 2024
From: jwerner at chromium.org (Julius Werner)
Date: Mon, 9 Dec 2024 15:34:59 -0800
Subject: [PATCH 2/6] arm64: errata: Add QCOM_KRYO_2XX_GOLD to the spectre_bhb_firmware_mitigated_list
In-Reply-To: <wx6qbdbcrvbq34snzkxawlbpxm6vogt5ccjmdqqyazukfbjy7t@qkvax7tr27bs>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.2.Ia3dfc0afadbfbee81bb2efb0672262470973dd08@changeid> <wx6qbdbcrvbq34snzkxawlbpxm6vogt5ccjmdqqyazukfbjy7t@qkvax7tr27bs>
Message-ID: <CAODwPW8mq-saJuTYnMhA6bCopcjQwBxEoyWhQB60Jg1m7wUZkw@mail.gmail.com>

> > NOTE: presumably this patch won't actually do much on its own because
> > (I believe) it requires a firmware update to go with it.
>
> Why? is_spectre_bhb_fw_affected() returns true if (cpu in list OR fw
> mitigated)

That affects reporting, but the mitigation works by making an
ARM_SMCCC_ARCH_WORKAROUND_3 Secure Monitor Call to firmware, and that
only works if that call is implemented in firmware. Trusted-Firmware-A
is currently the only open source firmware I'm aware of that
implements this call, and it only supports Kryo 4 and 6 upstream (not
2 or 3).

So in order for this patch to actually be able to do anything other
than report that the mitigation is missing, it would need to run on
devices that either use a downstream fork of TF-A with added Kryo 2/3
support (I doubt this exists because AFAIK Kryo 4 was Qualcomm's first
attempt to use TF-A) or use some other proprietary kind of Secure
Monitor firmware that has this SMC and mitigation implemented
separately. (It seems unlikely that Qualcomm did this in their QTEE
firmware, since if they had they would have probably also added the
MIDRs here to Linux to activate it.)


From kuba at kernel.org  Mon Dec  9 15:40:30 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 9 Dec 2024 15:40:30 -0800
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <67577bd7.7b0a0220.1ce6b5.fe93@mx.google.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
	<20241209134459.27110-6-ansuelsmth@gmail.com>
	<20241209151813.106eda03@kernel.org>
	<67577bd7.7b0a0220.1ce6b5.fe93@mx.google.com>
Message-ID: <20241209154030.0f34d5dd@kernel.org>

On Tue, 10 Dec 2024 00:22:59 +0100 Christian Marangi wrote:
> Also hope we won't have to request multiple stable tag for this multi
> subsystem patch. Any hint on that?

Sorry I haven't payed much attention to earlier discussions.
Why multiple stable tags? AFAICT all trees will need patches 
4 and 5, so we can put that on a stable tag / branch, the rest 
can go directly into respective trees (assuming the table tag
has been merged in). No?


From ansuelsmth at gmail.com  Mon Dec  9 15:48:50 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Tue, 10 Dec 2024 00:48:50 +0100
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <20241209154030.0f34d5dd@kernel.org>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209151813.106eda03@kernel.org>
 <67577bd7.7b0a0220.1ce6b5.fe93@mx.google.com>
 <20241209154030.0f34d5dd@kernel.org>
Message-ID: <675781e6.df0a0220.3c3d71.7a51@mx.google.com>

On Mon, Dec 09, 2024 at 03:40:30PM -0800, Jakub Kicinski wrote:
> On Tue, 10 Dec 2024 00:22:59 +0100 Christian Marangi wrote:
> > Also hope we won't have to request multiple stable tag for this multi
> > subsystem patch. Any hint on that?
> 
> Sorry I haven't payed much attention to earlier discussions.
> Why multiple stable tags? AFAICT all trees will need patches 
> 4 and 5, so we can put that on a stable tag / branch, the rest 
> can go directly into respective trees (assuming the table tag
> has been merged in). No?

Yes in theory only MFD is really needed (as it does export the page
symbol)

- NVMEM can go in his own tree. (no need for stable tag)
- mdio (require stable tag to correctly compile)
- dsa/phy (no need for stable tag)

So you are right, only one tag needed.

-- 
	Ansuel


From yabinc at google.com  Mon Dec  9 15:51:34 2024
From: yabinc at google.com (Yabin Cui)
Date: Mon, 9 Dec 2024 15:51:34 -0800
Subject: [PATCH v2] arm64: Allow CONFIG_AUTOFDO_CLANG to be selected
In-Reply-To: <20241209185623.GA13084@willie-the-truck>
References: <20241118222540.27495-1-yabinc@google.com> <20241209162028.GD12428@willie-the-truck>
 <CAF1bQ=SiHi8oCyo5YnXGpQGofM1zAsnBdqSEet1mS-BYNKVU8A@mail.gmail.com> <20241209185623.GA13084@willie-the-truck>
Message-ID: <CALJ9ZPNfUFF8OrpvziTnTvGU7OxEgyy9ZTc3aF-NhZ5hMbp7RQ@mail.gmail.com>

 On Mon, Dec 9, 2024 at 10:56?AM Will Deacon <will at kernel.org> wrote:
>
> (Aside: please try to avoid top-posting on the public lists as it messes up
> the flow of conversation; I'll try to piece this back together.)
>
> On Mon, Dec 09, 2024 at 09:30:50AM -0800, Rong Xu wrote:
> > On Mon, Dec 9, 2024 at 8:20?AM Will Deacon <will at kernel.org> wrote:
> > > On Mon, Nov 18, 2024 at 02:25:40PM -0800, Yabin Cui wrote:
> > > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > > > index fd9df6dcc593..c3814df5e391 100644
> > > > --- a/arch/arm64/Kconfig
> > > > +++ b/arch/arm64/Kconfig
> > > > @@ -103,6 +103,7 @@ config ARM64
> > > >       select ARCH_SUPPORTS_PER_VMA_LOCK
> > > >       select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
> > > >       select ARCH_SUPPORTS_RT
> > > > +     select ARCH_SUPPORTS_AUTOFDO_CLANG
> > > >       select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
> > > >       select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
> > > >       select ARCH_WANT_DEFAULT_BPF_JIT
> > >
> > > After this change, both arm64 and x86 select this option unconditionally
> > > and with no apparent support code being added. So what is actually
> > > required in order to select ARCH_SUPPORTS_AUTOFDO_CLANG and why isn't
> > > it just available for all architectures instead?

I think it's similar to ARCH_SUPPORTS_LTO_CLANG, which also doesn't need any
support code but requires testing to ensure it works on a specific architecture.

>
> > Enabling an AutoFDO build requires users to explicitly set CONFIG_AUTOFDO_CLANG.
> > The support code is in Commit 315ad8780a129e82 (kbuild: Add AutoFDO
> > support for Clang build).
>
> Yes, that is precisely my point. The user has to enable
> CONFIG_AUTOFDO_CLANG anyway, so what is the point in having
> ARCH_SUPPORTS_AUTOFDO_CLANG. Why would an architecture _not_ want to
> select that?
>
> > We are not enabling this for all architectures because AutoFDO's optimized build
> > relies on Last Branch Records (LBR) which aren't available on all architectures.
>
> So? ETM isn't available on all arm64 machines and I doubt whether LBR is
> available on _all_ x86 machines either. So there's a runtime failure
> mode that needs to be handled anyway and I don't think the arch-specific
> Kconfig option is really doing anything useful.

My understanding of the benefits of ARCH_SUPPORTS_AUTOFDO_CLANG is:
1. Generally, we don't prefer to collect an AutoFDO profile on one
architecture and use it to build the kernel for another architecture.
This is because the profile misses data for architecture-dependent
code. ARCH_SUPPORTS_AUTOFDO_CLANG can partially prevent this from
happening.

2. Building a kernel with an AutoFDO profile involves using new
optimization flags for clang.  Having ARCH_SUPPORTS_AUTOFDO_CLANG=y
for one architecture means someone has tested building a kernel with
an AutoFDO profile on this architecture.
>
> Will


From dmitry.baryshkov at linaro.org  Mon Dec  9 15:52:43 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 01:52:43 +0200
Subject: [PATCH 2/6] arm64: errata: Add QCOM_KRYO_2XX_GOLD to the
 spectre_bhb_firmware_mitigated_list
In-Reply-To: <CAODwPW8mq-saJuTYnMhA6bCopcjQwBxEoyWhQB60Jg1m7wUZkw@mail.gmail.com>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.2.Ia3dfc0afadbfbee81bb2efb0672262470973dd08@changeid>
 <wx6qbdbcrvbq34snzkxawlbpxm6vogt5ccjmdqqyazukfbjy7t@qkvax7tr27bs>
 <CAODwPW8mq-saJuTYnMhA6bCopcjQwBxEoyWhQB60Jg1m7wUZkw@mail.gmail.com>
Message-ID: <w725lby34vpavm3knq3ikz2wb4tzlfr4elbgf25mjbvgamtq5t@zgc52dc2wvsy>

On Mon, Dec 09, 2024 at 03:34:59PM -0800, Julius Werner wrote:
> > > NOTE: presumably this patch won't actually do much on its own because
> > > (I believe) it requires a firmware update to go with it.
> >
> > Why? is_spectre_bhb_fw_affected() returns true if (cpu in list OR fw
> > mitigated)
> 
> That affects reporting, but the mitigation works by making an
> ARM_SMCCC_ARCH_WORKAROUND_3 Secure Monitor Call to firmware, and that
> only works if that call is implemented in firmware. Trusted-Firmware-A
> is currently the only open source firmware I'm aware of that
> implements this call, and it only supports Kryo 4 and 6 upstream (not
> 2 or 3).
> 
> So in order for this patch to actually be able to do anything other
> than report that the mitigation is missing, it would need to run on
> devices that either use a downstream fork of TF-A with added Kryo 2/3
> support (I doubt this exists because AFAIK Kryo 4 was Qualcomm's first
> attempt to use TF-A) or use some other proprietary kind of Secure
> Monitor firmware that has this SMC and mitigation implemented
> separately. (It seems unlikely that Qualcomm did this in their QTEE
> firmware, since if they had they would have probably also added the
> MIDRs here to Linux to activate it.)

Ack, thanks for the detailed explanation.

-- 
With best wishes
Dmitry


From will at kernel.org  Mon Dec  9 15:58:05 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Dec 2024 23:58:05 +0000
Subject: [PATCH v2 1/2] iommu/io-pgtable-arm: Fix stage-2 concatenation
 with 16K
In-Reply-To: <20241202140604.422235-2-smostafa@google.com>
References: <20241202140604.422235-1-smostafa@google.com>
 <20241202140604.422235-2-smostafa@google.com>
Message-ID: <20241209235804.GA14069@willie-the-truck>

On Mon, Dec 02, 2024 at 02:06:03PM +0000, Mostafa Saleh wrote:
> At the moment, io-pgtable-arm uses concatenation only if it is
> possible at level 0, which misses a case where concatenation is
> mandatory at level 1 according to R_SRKBC in Arm spec DDI0487 K.a.
> 
> Also, that means concatenation can be used when not mandated,
> contradicting the comment on the code. However, these cases can only
> happen if the SMMUv3 driver is changed to use ias != oas for stage-2.
> 
> This patch re-writes the code to use concatenation only if mandatory,
> fixing the missing case for level-1 and granule 16K with PA = 40 bits.
> 
> Signed-off-by: Mostafa Saleh <smostafa at google.com>
> ---
>  drivers/iommu/io-pgtable-arm.c | 45 +++++++++++++++++++++++++---------
>  1 file changed, 33 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 6b9bb58a414f..0055876b3527 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -223,6 +223,33 @@ static inline int arm_lpae_max_entries(int i, struct arm_lpae_io_pgtable *data)
>  	return ptes_per_table - (i & (ptes_per_table - 1));
>  }
>  
> +/*
> + * Check if concatenated PGDs are mandatory according to Arm DDI0487 (K.a)
> + * 1) R_DXBSH: For 16KB, and 48-bit input size, use level 1 instead of 0.
> + * 2) R_SRKBC: After de-ciphering the table for PA size and valid initial lookup
> + *   a) 40 bits PA size with 4K: use level 1 instead of level 0 (2 tables for ias = oas)
> + *   b) 40 bits PA size with 16K: use level 2 instead of level 1 (16 tables for ias = oas)
> + *   c) 42 bits PA size with 4K: use level 1 instead of level 0 (8 tables for ias = oas)
> + *   d) 48 bits PA size with 16K: use level 1 instead of level 0 (2 tables for ias = oas)
> + */
> +static inline bool arm_lpae_concat_mandatory(struct arm_lpae_io_pgtable *data)
> +{
> +	unsigned int ias = data->iop.cfg.ias;
> +	unsigned int oas = data->iop.cfg.oas;
> +
> +	/* Covers 1  and 2.d */
> +	if ((ARM_LPAE_GRANULE(data) == SZ_16K) && (data->start_level == 0))
> +		return (oas == 48) || (ias = 48);

I'm guessing the second disjunct here should be:

	(ias == 48);

I'll make that change when applying...

Will


From will at kernel.org  Mon Dec  9 16:17:30 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 00:17:30 +0000
Subject: [PATCH 1/2] iommu/arm-smmu-v3: Document SVA interaction with new pagetable features
In-Reply-To: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
References: <68a37b00a720f0827cac0e4f40e4d3a688924054.1733406275.git.robin.murphy@arm.com>
Message-ID: <173378456062.4186718.3662609391353650164.b4-ty@kernel.org>

On Thu, 05 Dec 2024 13:48:09 +0000, Robin Murphy wrote:
> Process pagetables may now be using new permission-indirection-based
> features which an SMMU may not understand when given such a table for
> SVA. Although SMMUv3.4 does add its own S1PIE feature, realistically
> we're still going to have to cope with feature mismatches between CPUs
> and SMMUs, so let's start simple and essentially just document the
> expectations for what falls out as-is. Although it seems unlikely for
> SVA applications to also depend on memory-hardening features, or
> vice-versa, the relative lifecycles make it tricky to enforce mutual
> exclusivity. Thankfully our PIE index allocation makes it relatively
> benign for an SMMU to keep interpreting them as direct permissions, the
> only real implication is that an SVA application cannot harden itself
> against its own devices with these features. Thus, inform the user about
> that just in case they have other expectations.
> 
> [...]

Applied SMMU change to will (for-joerg/arm-smmu/updates), thanks!

[1/2] iommu/arm-smmu-v3: Document SVA interaction with new pagetable features
      https://git.kernel.org/will/c/6e192214c6c8

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Mon Dec  9 16:17:31 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 00:17:31 +0000
Subject: [PATCH v2 0/4] iommu/arm-smmu: Minor probe_device related improvements
In-Reply-To: <cover.1733406914.git.robin.murphy@arm.com>
References: <cover.1733406914.git.robin.murphy@arm.com>
Message-ID: <173378441488.4186336.14522482976618451984.b4-ty@kernel.org>

On Thu, 05 Dec 2024 16:33:54 +0000, Robin Murphy wrote:
> v1: https://lore.kernel.org/linux-iommu/cover.1731088789.git.robin.murphy at arm.com
> 
> Hi all,
> 
> Here's what I probably should have sent instead of rushing v1 out
> earlier, now rebased and polished :)
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/4] iommu/arm-smmu: Make instance lookup robust
      https://git.kernel.org/will/c/7d835134d4e1
[2/4] iommu/arm-smmu: Retire probe deferral workaround
      https://git.kernel.org/will/c/97cb1fa02726
[3/4] iommu/arm-smmu-v3: Clean up more on probe failure
      https://git.kernel.org/will/c/fcbd62156742
[4/4] iommu: Manage driver probe deferral better
      https://git.kernel.org/will/c/46b3df8eb9bd

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Mon Dec  9 16:17:32 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 00:17:32 +0000
Subject: [PATCH v2 0/2] Fix missing case for concatenation
In-Reply-To: <20241202140604.422235-1-smostafa@google.com>
References: <20241202140604.422235-1-smostafa@google.com>
Message-ID: <173378764988.2164600.15198070609246396646.b4-ty@kernel.org>

On Mon, 02 Dec 2024 14:06:02 +0000, Mostafa Saleh wrote:
> First patch fixes a missing case for 16K granule and 40 bits SMMUs
> where concatenation is mandatory but ignored.
> 
> Second patch, imporves coverage of OAS in selftests to make it
> possible to test all concatenation cases.
> 
> Cc: Daniel Mentz <danielmentz at google.com>
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/2] iommu/io-pgtable-arm: Fix stage-2 concatenation with 16K
      https://git.kernel.org/will/c/4dcac8407fe1
[2/2] iommu/io-pgtable-arm: Add coverage for different OAS in selftest
      https://git.kernel.org/will/c/376ce8b35ed1

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From fujita.tomonori at gmail.com  Mon Dec  9 16:17:56 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Tue, 10 Dec 2024 09:17:56 +0900
Subject: [PATCH v1 0/5] rust: Add bug/warn abstractions
Message-ID: <20241210001802.228725-1-fujita.tomonori@gmail.com>

This patchset adds warn_on and warn_on_once macros with the bug/warn
abstraction.

Wrapping C's BUG/WARN macros does not work the same way on
architectures that support Rust (x86, RISC-V, ARM64, LoongArch). Rust
code needs to directly execute the same assembly code used on the C
side. To avoid duplicating the assembly code, this approach mirrors
what the static branch code does: it dynamically generates the
assembly code for Rust using the C preprocessor.

The 1st to 4th patches export the BUG/WARN assembly code for Rust on
each architecture, with no functional changes on the C side. The
changes for x86 and RISC-V are straightforward. However, the ARM64 and
LoongArch assembly code are designed differently; they are used by
both C inline assembly and assembly code. As a result, sharing this
code with Rust is complicated.

The last patch adds the bug abstraction. Seems that an unused named
argument in Rust inline assembly can't be allowed so we need multiple
#[cfg].

This has been tested on x86, ARM64, and RISC-V (QEMU), with only a
compile test performed for LoongArch.

The assembly code can be used for both BUG and WARN, but currently
only supports warn_on and warn_on_once. I will work on the remaining
functionality after this abstraction is merged.


FUJITA Tomonori (5):
  x86/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with
    Rust
  riscv/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with
    Rust
  arm64/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with
    Rust
  loongarch/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing
    with Rust
  rust: Add warn_on and warn_on_once

 arch/arm64/include/asm/asm-bug.h              |  31 ++++-
 arch/loongarch/include/asm/bug.h              |  31 ++++-
 arch/riscv/include/asm/bug.h                  |  35 +++--
 arch/x86/include/asm/bug.h                    |  51 ++++---
 rust/Makefile                                 |   8 ++
 rust/kernel/.gitignore                        |   2 +
 rust/kernel/bug.rs                            | 131 ++++++++++++++++++
 rust/kernel/generated_arch_reachable_asm.rs.S |   7 +
 rust/kernel/generated_arch_warn_asm.rs.S      |   7 +
 rust/kernel/lib.rs                            |   1 +
 10 files changed, 255 insertions(+), 49 deletions(-)
 create mode 100644 rust/kernel/bug.rs
 create mode 100644 rust/kernel/generated_arch_reachable_asm.rs.S
 create mode 100644 rust/kernel/generated_arch_warn_asm.rs.S


base-commit: 7503345ac5f5e82fd9a36d6e6b447c016376403a
-- 
2.43.0



From fujita.tomonori at gmail.com  Mon Dec  9 16:17:57 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Tue, 10 Dec 2024 09:17:57 +0900
Subject: [PATCH v1 1/5] x86/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust
In-Reply-To: <20241210001802.228725-1-fujita.tomonori@gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com>
Message-ID: <20241210001802.228725-2-fujita.tomonori@gmail.com>

Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
Rust to avoid the duplication.

No functional changes.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 arch/x86/include/asm/bug.h | 51 ++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 27 deletions(-)

diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index 806649c7f23d..71df68e2a731 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -28,45 +28,42 @@
 #ifdef CONFIG_GENERIC_BUG
 
 #ifdef CONFIG_X86_32
-# define __BUG_REL(val)	".long " __stringify(val)
+# define __BUG_REL(val)	".long " val
 #else
-# define __BUG_REL(val)	".long " __stringify(val) " - ."
+# define __BUG_REL(val)	".long " val " - ."
 #endif
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+#define __BUG_ENTRY(file, line, flags)					\
+	"2:\t" __BUG_REL("1b") "\t# bug_entry::bug_addr\n"		\
+	"\t" __BUG_REL(file)   "\t# bug_entry::file\n"			\
+	"\t.word " line        "\t# bug_entry::line\n"			\
+	"\t.word " flags       "\t# bug_entry::flags\n"
+#else
+#define __BUG_ENTRY(file, ine, flags)					\
+	"2:\t" __BUG_REL("1b") "\t# bug_entry::bug_addr\n"		\
+	"\t.word " flags       "\t# bug_entry::flags\n"
+#endif
+
+#define _BUG_FLAGS_ASM(ins, file, line, flags, size, extra)		\
+	"1:\t" ins "\n"							\
+	".pushsection __bug_table,\"aw\"\n"				\
+	__BUG_ENTRY(file, line, flags)					\
+	"\t.org 2b + " size "\n"					\
+	".popsection\n"							\
+	extra
 
 #define _BUG_FLAGS(ins, flags, extra)					\
 do {									\
-	asm_inline volatile("1:\t" ins "\n"				\
-		     ".pushsection __bug_table,\"aw\"\n"		\
-		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
-		     "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"	\
-		     "\t.word %c1"        "\t# bug_entry::line\n"	\
-		     "\t.word %c2"        "\t# bug_entry::flags\n"	\
-		     "\t.org 2b+%c3\n"					\
-		     ".popsection\n"					\
-		     extra						\
+	asm_inline volatile(_BUG_FLAGS_ASM(ins, "%c0",			\
+					   "%c1", "%c2", "%c3", extra)	\
 		     : : "i" (__FILE__), "i" (__LINE__),		\
 			 "i" (flags),					\
 			 "i" (sizeof(struct bug_entry)));		\
 } while (0)
 
-#else /* !CONFIG_DEBUG_BUGVERBOSE */
-
-#define _BUG_FLAGS(ins, flags, extra)					\
-do {									\
-	asm_inline volatile("1:\t" ins "\n"				\
-		     ".pushsection __bug_table,\"aw\"\n"		\
-		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
-		     "\t.word %c0"        "\t# bug_entry::flags\n"	\
-		     "\t.org 2b+%c1\n"					\
-		     ".popsection\n"					\
-		     extra						\
-		     : : "i" (flags),					\
-			 "i" (sizeof(struct bug_entry)));		\
-} while (0)
-
-#endif /* CONFIG_DEBUG_BUGVERBOSE */
+#define ARCH_WARN_ASM(file, line, flags, size)				\
+	_BUG_FLAGS_ASM(ASM_UD2, file, line, flags, size, "")
 
 #else
 
-- 
2.43.0



From fujita.tomonori at gmail.com  Mon Dec  9 16:17:58 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Tue, 10 Dec 2024 09:17:58 +0900
Subject: [PATCH v1 2/5] riscv/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust
In-Reply-To: <20241210001802.228725-1-fujita.tomonori@gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com>
Message-ID: <20241210001802.228725-3-fujita.tomonori@gmail.com>

Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
Rust to avoid the duplication.

No functional changes.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 arch/riscv/include/asm/bug.h | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h
index 1aaea81fb141..ee6b9b787e46 100644
--- a/arch/riscv/include/asm/bug.h
+++ b/arch/riscv/include/asm/bug.h
@@ -31,40 +31,45 @@ typedef u32 bug_insn_t;
 
 #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 #define __BUG_ENTRY_ADDR	RISCV_INT " 1b - ."
-#define __BUG_ENTRY_FILE	RISCV_INT " %0 - ."
+#define __BUG_ENTRY_FILE(file)	RISCV_INT " " file " - ."
 #else
 #define __BUG_ENTRY_ADDR	RISCV_PTR " 1b"
-#define __BUG_ENTRY_FILE	RISCV_PTR " %0"
+#define __BUG_ENTRY_FILE(file)	RISCV_PTR " " file
 #endif
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
-#define __BUG_ENTRY			\
+#define __BUG_ENTRY(file, line, flags)	\
 	__BUG_ENTRY_ADDR "\n\t"		\
-	__BUG_ENTRY_FILE "\n\t"		\
-	RISCV_SHORT " %1\n\t"		\
-	RISCV_SHORT " %2"
+	__BUG_ENTRY_FILE(file) "\n\t"	\
+	RISCV_SHORT " " line "\n\t"	\
+	RISCV_SHORT " " flags
 #else
-#define __BUG_ENTRY			\
-	__BUG_ENTRY_ADDR "\n\t"		\
-	RISCV_SHORT " %2"
+#define __BUG_ENTRY(file, line, flags)		\
+	__BUG_ENTRY_ADDR "\n\t"			\
+	RISCV_SHORT " " flags
 #endif
 
 #ifdef CONFIG_GENERIC_BUG
-#define __BUG_FLAGS(flags)					\
-do {								\
-	__asm__ __volatile__ (					\
+
+#define ARCH_WARN_ASM(file, line, flags, size)			\
 		"1:\n\t"					\
 			"ebreak\n"				\
 			".pushsection __bug_table,\"aw\"\n\t"	\
 		"2:\n\t"					\
-			__BUG_ENTRY "\n\t"			\
-			".org 2b + %3\n\t"                      \
-			".popsection"				\
+		__BUG_ENTRY(file, line, flags) "\n\t"		\
+			".org 2b + " size "\n\t"                \
+			".popsection\n"				\
+
+#define __BUG_FLAGS(flags)					\
+do {								\
+	__asm__ __volatile__ (					\
+		ARCH_WARN_ASM("%0", "%1", "%2", "%3")		\
 		:						\
 		: "i" (__FILE__), "i" (__LINE__),		\
 		  "i" (flags),					\
 		  "i" (sizeof(struct bug_entry)));              \
 } while (0)
+
 #else /* CONFIG_GENERIC_BUG */
 #define __BUG_FLAGS(flags) do {					\
 	__asm__ __volatile__ ("ebreak\n");			\
-- 
2.43.0



From fujita.tomonori at gmail.com  Mon Dec  9 16:17:59 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Tue, 10 Dec 2024 09:17:59 +0900
Subject: [PATCH v1 3/5] arm64/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust
In-Reply-To: <20241210001802.228725-1-fujita.tomonori@gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com>
Message-ID: <20241210001802.228725-4-fujita.tomonori@gmail.com>

Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
Rust to avoid the duplication.

No functional changes.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 arch/arm64/include/asm/asm-bug.h | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/asm-bug.h b/arch/arm64/include/asm/asm-bug.h
index 6e73809f6492..822e9d51d3e9 100644
--- a/arch/arm64/include/asm/asm-bug.h
+++ b/arch/arm64/include/asm/asm-bug.h
@@ -21,16 +21,21 @@
 #endif
 
 #ifdef CONFIG_GENERIC_BUG
-
-#define __BUG_ENTRY(flags) 				\
+#define __BUG_ENTRY_START				\
 		.pushsection __bug_table,"aw";		\
 		.align 2;				\
 	14470:	.long 14471f - .;			\
-_BUGVERBOSE_LOCATION(__FILE__, __LINE__)		\
-		.short flags; 				\
+
+#define __BUG_ENTRY_END					\
 		.align 2;				\
 		.popsection;				\
 	14471:
+
+#define __BUG_ENTRY(flags)				\
+		__BUG_ENTRY_START			\
+_BUGVERBOSE_LOCATION(__FILE__, __LINE__)		\
+		.short flags;				\
+		__BUG_ENTRY_END
 #else
 #define __BUG_ENTRY(flags)
 #endif
@@ -41,4 +46,22 @@ _BUGVERBOSE_LOCATION(__FILE__, __LINE__)		\
 
 #define ASM_BUG()	ASM_BUG_FLAGS(0)
 
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#define __BUG_LOCATION_STRING(file, line)		\
+		".long " file "- .;"			\
+		".short " line ";"
+#else
+#define __BUG_LOCATION_STRING(file, line)
+#endif
+
+#define __BUG_ENTRY_STRING(file, line, flags)		\
+		__stringify(__BUG_ENTRY_START)		\
+		__BUG_LOCATION_STRING(file, line)	\
+		".short " flags ";"			\
+		__stringify(__BUG_ENTRY_END)
+
+#define ARCH_WARN_ASM(file, line, flags, size)		\
+	__BUG_ENTRY_STRING(file, line, flags)		\
+	__stringify(brk BUG_BRK_IMM)
+
 #endif /* __ASM_ASM_BUG_H */
-- 
2.43.0



From fujita.tomonori at gmail.com  Mon Dec  9 16:18:00 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Tue, 10 Dec 2024 09:18:00 +0900
Subject: [PATCH v1 4/5] loongarch/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust
In-Reply-To: <20241210001802.228725-1-fujita.tomonori@gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com>
Message-ID: <20241210001802.228725-5-fujita.tomonori@gmail.com>

Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
Rust to avoid the duplication.

No functional changes.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 arch/loongarch/include/asm/bug.h | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/arch/loongarch/include/asm/bug.h b/arch/loongarch/include/asm/bug.h
index 08388876ade4..2343c4226595 100644
--- a/arch/loongarch/include/asm/bug.h
+++ b/arch/loongarch/include/asm/bug.h
@@ -21,14 +21,21 @@
 #ifndef CONFIG_GENERIC_BUG
 #define __BUG_ENTRY(flags)
 #else
-#define __BUG_ENTRY(flags) 					\
+
+#define __BUG_ENTRY_START					\
 		.pushsection __bug_table, "aw";			\
 		.align 2;					\
 	10000:	.long 10001f - .;				\
-		_BUGVERBOSE_LOCATION(__FILE__, __LINE__)	\
-		.short flags; 					\
+
+#define __BUG_ENTRY_END						\
 		.popsection;					\
 	10001:
+
+#define __BUG_ENTRY(flags)					\
+		__BUG_ENTRY_START			\
+		_BUGVERBOSE_LOCATION(__FILE__, __LINE__)	\
+		.short flags;					\
+		__BUG_ENTRY_END
 #endif
 
 #define ASM_BUG_FLAGS(flags)					\
@@ -55,6 +62,24 @@ do {								\
 	unreachable();						\
 } while (0)
 
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#define __BUG_LOCATION_STRING(file, line)		\
+		".long " file "- .;"			\
+		".short " line ";"
+#else
+#define __BUG_LOCATION_STRING(_file, _line)
+#endif
+
+#define __BUG_ENTRY_STRING(file, line, flags)		\
+		__stringify(__BUG_ENTRY_START)		\
+		__BUG_LOCATION_STRING(file, line)	\
+		".short " flags ";"			\
+		__stringify(__BUG_ENTRY_END)
+
+#define ARCH_WARN_ASM(file, line, flags, size)		\
+	__BUG_ENTRY_STRING(file, line, flags)		\
+	__stringify(break BRK_BUG) ";"
+
 #define HAVE_ARCH_BUG
 
 #include <asm-generic/bug.h>
-- 
2.43.0



From will at kernel.org  Mon Dec  9 16:17:26 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 00:17:26 +0000
Subject: [PATCH 0/3] iommu/arm-smmuv3: Update domain_alloc_paging_flags()
In-Reply-To: <0-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
References: <0-v1-0bb8d5313a27+27b-smmuv3_paging_flags_jgg@nvidia.com>
Message-ID: <173378567932.4189360.5507988351679593105.b4-ty@kernel.org>

On Thu, 05 Dec 2024 11:43:26 -0400, Jason Gunthorpe wrote:
> The last cycle saw the removal of the NULL device during domain allocation
> and the introduction of domain_alloc_paging_flags(). Update smmuv3 to this
> new design.
> 
> Jason Gunthorpe (3):
>   iommu/arm-smmu-v3: Remove arm_smmu_domain_finalise() during attach
>   iommu/arm-smmu-v3: Make domain_alloc_paging_flags() directly determine
>     the S1/S2
>   iommu/arm-smmu-v3: Remove domain_alloc_paging()
> 
> [...]

Applied to arm64 (for-joerg/arm-smmu/updates), thanks!

[1/3] iommu/arm-smmu-v3: Remove arm_smmu_domain_finalise() during attach
      https://git.kernel.org/arm64/c/48e7b8e284e5
[2/3] iommu/arm-smmu-v3: Make domain_alloc_paging_flags() directly determine the S1/S2
      https://git.kernel.org/arm64/c/bb857c5c0150
[3/3] iommu/arm-smmu-v3: Remove domain_alloc_paging()
      https://git.kernel.org/arm64/c/cdfb9840fcc6

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Mon Dec  9 16:17:27 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 00:17:27 +0000
Subject: [PATCH] iommu/arm-smmuv3: Update comments about ATS and bypass
In-Reply-To: <0-v1-f27174f44f39+27a33-smmuv3_ats_note_jgg@nvidia.com>
References: <0-v1-f27174f44f39+27a33-smmuv3_ats_note_jgg@nvidia.com>
Message-ID: <173378410349.4185561.4875058023954953472.b4-ty@kernel.org>

On Thu, 05 Dec 2024 11:40:15 -0400, Jason Gunthorpe wrote:
> The SMMUv3 spec has a note that BYPASS and ATS don't work together under
> the STE EATS field definition. However there is another section "13.6.4
> Full ATS skipping stage 1" that explains under certain conditions BYPASS
> and ATS do work together if the STE is using S1DSS to select BYPASS and
> the CD table has the possibility for a substream.
> 
> When these comments were written the understanding was that all forms of
> BYPASS just didn't work and this was to be a future problem to solve.
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/1] iommu/arm-smmuv3: Update comments about ATS and bypass
      https://git.kernel.org/will/c/9b640ae7fbba

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Mon Dec  9 16:17:28 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 00:17:28 +0000
Subject: [PATCH v2] iommu/tegra241-cmdqv: do not use smp_processor_id in preemptible context
In-Reply-To: <Z1L1mja3nXzsJ0Pk@uudg.org>
References: <Z1L1mja3nXzsJ0Pk@uudg.org>
Message-ID: <173378751166.2164111.11293401851587446576.b4-ty@kernel.org>

On Fri, 06 Dec 2024 10:01:14 -0300, Luis Claudio R. Goncalves wrote:
> During boot some of the calls to tegra241_cmdqv_get_cmdq() will happen
> in preemptible context. As this function calls smp_processor_id(), if
> CONFIG_DEBUG_PREEMPT is enabled, these calls will trigger a series of
> "BUG: using smp_processor_id() in preemptible" backtraces.
> 
> As tegra241_cmdqv_get_cmdq() only calls smp_processor_id() to use the
> CPU number as a factor to balance out traffic on cmdq usage, it is safe
> to use raw_smp_processor_id() here.
> 
> [...]

Applied to will (for-joerg/arm-smmu/fixes), thanks!

[1/1] iommu/tegra241-cmdqv: do not use smp_processor_id in preemptible context
      https://git.kernel.org/will/c/1f806218164d

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From fujita.tomonori at gmail.com  Mon Dec  9 16:18:01 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Tue, 10 Dec 2024 09:18:01 +0900
Subject: [PATCH v1 5/5] rust: Add warn_on and warn_on_once
In-Reply-To: <20241210001802.228725-1-fujita.tomonori@gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com>
Message-ID: <20241210001802.228725-6-fujita.tomonori@gmail.com>

Add warn_on and warn_on_once macros. Wrapping the C's WARN_* and BUG_*
macros doesn't work so this uses the assembly code exported by the C
side via ARCH_WARN_ASM macro. Like the static branch code, this
generates the assembly code for rust dynamically by using the C
preprocessor.

file()! macro doesn't work for the Rust inline assembly in the same
way as __FILE__ for the C inline assembly. So the code to handle a
file name is different from the C assembly code (similar to the
arm64/loongarch assembly).

ASM_REACHABLE definition works in the same way to get objtool's
reachable asm code. The architectures which use objtool (x86 and
loongarch) needs it.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 rust/Makefile                                 |   8 ++
 rust/kernel/.gitignore                        |   2 +
 rust/kernel/bug.rs                            | 131 ++++++++++++++++++
 rust/kernel/generated_arch_reachable_asm.rs.S |   7 +
 rust/kernel/generated_arch_warn_asm.rs.S      |   7 +
 rust/kernel/lib.rs                            |   1 +
 6 files changed, 156 insertions(+)
 create mode 100644 rust/kernel/bug.rs
 create mode 100644 rust/kernel/generated_arch_reachable_asm.rs.S
 create mode 100644 rust/kernel/generated_arch_warn_asm.rs.S

diff --git a/rust/Makefile b/rust/Makefile
index 9da9042fd627..80c9c6b3e491 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -37,6 +37,9 @@ obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.o
 obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.o
 
 always-$(subst y,$(CONFIG_RUST),$(CONFIG_JUMP_LABEL)) += kernel/generated_arch_static_branch_asm.rs
+ifndef CONFIG_UML
+always-$(subst y,$(CONFIG_RUST),$(CONFIG_BUG)) += kernel/generated_arch_warn_asm.rs kernel/generated_arch_reachable_asm.rs
+endif
 
 # Avoids running `$(RUSTC)` for the sysroot when it may not be available.
 ifdef CONFIG_RUST
@@ -436,5 +439,10 @@ $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \
 ifdef CONFIG_JUMP_LABEL
 $(obj)/kernel.o: $(obj)/kernel/generated_arch_static_branch_asm.rs
 endif
+ifndef CONFIG_UML
+ifdef CONFIG_BUG
+$(obj)/kernel.o: $(obj)/kernel/generated_arch_warn_asm.rs $(obj)/kernel/generated_arch_reachable_asm.rs
+endif
+endif
 
 endif # CONFIG_RUST
diff --git a/rust/kernel/.gitignore b/rust/kernel/.gitignore
index 6ba39a178f30..f1d7f4225332 100644
--- a/rust/kernel/.gitignore
+++ b/rust/kernel/.gitignore
@@ -1,3 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
 /generated_arch_static_branch_asm.rs
+/generated_arch_warn_asm.rs
+/generated_arch_reachable_asm.rs
\ No newline at end of file
diff --git a/rust/kernel/bug.rs b/rust/kernel/bug.rs
new file mode 100644
index 000000000000..8959a2e94971
--- /dev/null
+++ b/rust/kernel/bug.rs
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0
+
+// Copyright (C) 2024 FUJITA Tomonori
+
+//! Support for BUG_* and WARN_* functionality.
+//!
+//! C header: [`include/asm-generic/bug.h`](srctree/include/asm-generic/bug.h)
+
+#[macro_export]
+#[doc(hidden)]
+#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
+#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
+macro_rules! warn_flags {
+    ($flags:expr) => {
+        const FLAGS: u32 = $crate::bindings::BUGFLAG_WARNING | $flags;
+        // SAFETY: Just an FFI call.
+        #[cfg(CONFIG_DEBUG_BUGVERBOSE)]
+        unsafe {
+            $crate::asm!(concat!(
+                ".pushsection .rodata.str1.1, \"aMS\", at progbits, 1\n",
+                "111:\t .string ", "\"", file!(), "\"\n",
+                ".popsection\n",
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
+            line = const line!(),
+            flags = const FLAGS,
+            size = const ::core::mem::size_of::<$crate::bindings::bug_entry>(),
+            );
+        }
+        // SAFETY: Just an FFI call.
+        #[cfg(not(CONFIG_DEBUG_BUGVERBOSE))]
+        unsafe {
+            $crate::asm!(
+            concat!(
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
+            flags = const FLAGS,
+            size = const ::core::mem::size_of::<$crate::bindings::bug_entry>(),
+            );
+        }
+    }
+}
+
+#[macro_export]
+#[doc(hidden)]
+#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
+#[cfg(any(target_arch = "aarch64", target_arch = "loongarch64"))]
+macro_rules! warn_flags {
+    ($flags:expr) => {
+        const FLAGS: u32 = $crate::bindings::BUGFLAG_WARNING | $flags;
+        // SAFETY: Just an FFI call.
+        #[cfg(CONFIG_DEBUG_BUGVERBOSE)]
+        unsafe {
+            $crate::asm!(concat!(
+                ".pushsection .rodata.str1.1, \"aMS\", at progbits, 1\n",
+                "111:\t .string ", "\"", file!(), "\"\n",
+                ".popsection\n",
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
+            line = const line!(),
+            flags = const FLAGS,
+            );
+        }
+        // SAFETY: Just an FFI call.
+        #[cfg(not(CONFIG_DEBUG_BUGVERBOSE))]
+        unsafe {
+            $crate::asm!(concat!(
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
+            flags = const FLAGS,
+            );
+        }
+    }
+}
+
+#[macro_export]
+#[doc(hidden)]
+#[cfg(all(CONFIG_BUG, CONFIG_UML))]
+macro_rules! warn_flags {
+    ($flags:expr) => {
+        // SAFETY: Just an FFI call.
+        unsafe {
+            $crate::bindings::warn_slowpath_fmt(
+                $crate::c_str!(::core::file!()).as_ptr() as *const ::core::ffi::c_char,
+                line!() as i32,
+                $flags as u32,
+                ::core::ptr::null() as *const ::core::ffi::c_char,
+            );
+        }
+    };
+}
+
+#[macro_export]
+#[doc(hidden)]
+#[cfg(not(CONFIG_BUG))]
+macro_rules! warn_flags {
+    ($flags:expr) => {};
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! bugflag_taint {
+    ($taint:expr) => {
+        $taint << 8
+    };
+}
+
+/// Report a warning only once.
+#[macro_export]
+macro_rules! warn_on_once {
+    ($cond:expr) => {
+        if $cond {
+            $crate::warn_flags!(
+                $crate::bindings::BUGFLAG_ONCE
+                    | $crate::bugflag_taint!($crate::bindings::TAINT_WARN)
+            );
+        }
+        $cond
+    };
+}
+
+/// Report a warning.
+#[macro_export]
+macro_rules! warn_on {
+    ($cond:expr) => {
+        if $cond {
+            $crate::warn_flags!($crate::bugflag_taint!($crate::bindings::TAINT_WARN));
+        }
+        $cond
+    };
+}
diff --git a/rust/kernel/generated_arch_reachable_asm.rs.S b/rust/kernel/generated_arch_reachable_asm.rs.S
new file mode 100644
index 000000000000..4e65525e4464
--- /dev/null
+++ b/rust/kernel/generated_arch_reachable_asm.rs.S
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/objtool.h>
+
+// Cut here.
+
+::kernel::concat_literals!(ASM_REACHABLE)
diff --git a/rust/kernel/generated_arch_warn_asm.rs.S b/rust/kernel/generated_arch_warn_asm.rs.S
new file mode 100644
index 000000000000..8f239b431aa4
--- /dev/null
+++ b/rust/kernel/generated_arch_warn_asm.rs.S
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/bug.h>
+
+// Cut here.
+
+::kernel::concat_literals!(ARCH_WARN_ASM("111b", "{line}",  "{flags}", "{size}"))
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index e1065a7551a3..913f3a5b2a98 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -32,6 +32,7 @@
 pub mod alloc;
 #[cfg(CONFIG_BLOCK)]
 pub mod block;
+pub mod bug;
 mod build_assert;
 pub mod cred;
 pub mod device;
-- 
2.43.0



From broonie at kernel.org  Mon Dec  9 16:42:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 00:42:53 +0000
Subject: [PATCH] arm64/signal: Silence spurious sparse warning storing
 GCSPR_EL0
Message-ID: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>

We are seeing a false postive sparse warning in gcs_restore_signal()

arch/arm64/kernel/signal.c:1054:9: sparse: sparse: cast removes address space '__user' of expression

when storing the final GCSPR_EL0 value back into the register, caused by
the fact that write_sysreg_s() casts the value it writes to a u64 which
sparse sees as discarding the __userness of the pointer. The magic for
handling such situations with sparse is to cast the value to an unsigned
long which sparse sees as a valid thing to do with __user pointers so add
such a cast.

While we're at it also remove spurious casts of the gcspr_el0 value as we
manipulate it which were the result of bitrot as the code was tweaked in
the long period it was out of tree.

Reported-by: kernel test robot <lkp at intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202412082005.OBJ0BbWs-lkp at intel.com/
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/signal.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 14ac6fdb872b9672e4b16a097f1b577aae8dec50..83ea7e5fd2b54566c6649b82b8570657a5711dd4 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -39,7 +39,7 @@
 #ifdef CONFIG_ARM64_GCS
 #define GCS_SIGNAL_CAP(addr) (((unsigned long)addr) & GCS_CAP_ADDR_MASK)
 
-static bool gcs_signal_cap_valid(u64 addr, u64 val)
+static bool gcs_signal_cap_valid(unsigned long __user *addr, u64 val)
 {
 	return val == GCS_SIGNAL_CAP(addr);
 }
@@ -1094,15 +1094,15 @@ static int gcs_restore_signal(void)
 	/*
 	 * Check that the cap is the actual GCS before replacing it.
 	 */
-	if (!gcs_signal_cap_valid((u64)gcspr_el0, cap))
+	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);
+	put_user_gcs(0, gcspr_el0, &ret);
 	if (ret != 0)
 		return -EFAULT;
 
-	write_sysreg_s(gcspr_el0 + 1, SYS_GCSPR_EL0);
+	write_sysreg_s((unsigned long)(gcspr_el0 + 1), SYS_GCSPR_EL0);
 
 	return 0;
 }

---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241209-arm64-gcs-signal-sparse-53fa9cad67f7

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From andyshrk at 163.com  Mon Dec  9 16:50:51 2024
From: andyshrk at 163.com (Andy Yan)
Date: Tue, 10 Dec 2024 08:50:51 +0800 (CST)
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2
 controller
In-Reply-To: <2203458.KiezcSG77Q@diego>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241209150619.33998-1-dse@thaumatec.com>
 <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org> <2203458.KiezcSG77Q@diego>
Message-ID: <4e015ea9.960.193ae0c236a.Coremail.andyshrk@163.com>



Hi,

At 2024-12-10 07:12:26, "Heiko St?bner" <heiko at sntech.de> wrote:
>Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
>> Hi,
>> 
>> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
>> > On 03.12.24 21:54, Heiko Stuebner wrote:
>> > > This series adds a bridge and glue driver for the DSI2 controller found
>> > > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
>> > > 
>> >
>> > I did more tests with different LVDS displays. I tested following
>> > configurations with DSI/LVDS bridge:
>> > - 1024x600 at 60.01
>> > - 1024x768 at 60.02
>> > - 1280x800 at 60.07
>> > - 1366x768 at 60.06
>> >
>> > All of them worked without issues, except 1366x768.
>> > With this resolution, video is blurry, and offset incorrectly
>> > to the left. There are also repeating errors on the console:
>> >
>> >   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
>> >
>> > In correct operation with other resolutions, there is no error.
>> > I am not sure if this is a problem in your series or rather in VOP2
>> > driver.
>
>This really sounds like something is wrong on the vop side.
>The interrupt is part of the vop, the divisable by 4 things likely too.

This is a hardware limitation on vop side:
The horizontal resolution must be 4 pixel aligned.



>
>
>Heiko
>
>
>> 
>> On my PineTab2 I got similar messages about 2 weeks ago:
>> rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp1
>> 
>> Preceding those, I got several panfrost related errors:
>> 
>> panfrost fde60000.gpu: get clock failed -517
>> panfrost fde60000.gpu: clk init failed -517
>> platform fde60000.gpu: deferred probe pending: (reason unknown)
>> platform cpufreq-dt: deferred probe pending: (reason unknown)
>> vdd_gpu_npu: disabling
>> 
>> But can also be that the PineTab2 (likely) needs regulator-always-on
>> and regulator-boot-on in its vdd_gpu_npu node.
>> 
>> > I tried to track down the problem, and it seems to be a generic issue
>> > when horizontal line width is not divisible by 4.
>> > Lowering line width to 1364px fixes the issue, but of course I have two
>> > vertical lines of black pixels on the right.
>> > I also made some tests with 720x1280 DSI display. Lowering horizontal
>> > line to 718px shows the same problem. With 720px and 716px it works
>> > correctly.
>> 
>> I haven't look further into it, but the PT2 has a 1280x800 resolution.
>> 
>> HTH,
>>   Diederik
>> 
>
>
>

From dmitry.baryshkov at linaro.org  Mon Dec  9 17:01:38 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 03:01:38 +0200
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2
 controller
In-Reply-To: <4e015ea9.960.193ae0c236a.Coremail.andyshrk@163.com>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241209150619.33998-1-dse@thaumatec.com>
 <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org>
 <2203458.KiezcSG77Q@diego>
 <4e015ea9.960.193ae0c236a.Coremail.andyshrk@163.com>
Message-ID: <ay5hbnqqjhopaqof6z7j2rzm2bc6xa2vbzan2ak3if6wzmyip2@kqh7gtrajnm2>

On Tue, Dec 10, 2024 at 08:50:51AM +0800, Andy Yan wrote:
> 
> 
> Hi,
> 
> At 2024-12-10 07:12:26, "Heiko St?bner" <heiko at sntech.de> wrote:
> >Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
> >> Hi,
> >> 
> >> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
> >> > On 03.12.24 21:54, Heiko Stuebner wrote:
> >> > > This series adds a bridge and glue driver for the DSI2 controller found
> >> > > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
> >> > > 
> >> >
> >> > I did more tests with different LVDS displays. I tested following
> >> > configurations with DSI/LVDS bridge:
> >> > - 1024x600 at 60.01
> >> > - 1024x768 at 60.02
> >> > - 1280x800 at 60.07
> >> > - 1366x768 at 60.06
> >> >
> >> > All of them worked without issues, except 1366x768.
> >> > With this resolution, video is blurry, and offset incorrectly
> >> > to the left. There are also repeating errors on the console:
> >> >
> >> >   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
> >> >
> >> > In correct operation with other resolutions, there is no error.
> >> > I am not sure if this is a problem in your series or rather in VOP2
> >> > driver.
> >
> >This really sounds like something is wrong on the vop side.
> >The interrupt is part of the vop, the divisable by 4 things likely too.
> 
> This is a hardware limitation on vop side:
> The horizontal resolution must be 4 pixel aligned.

Then mode_valid() and atomic_check() must reject modes that don't fit.

> 
> 
> 

-- 
With best wishes
Dmitry


From atishp at rivosinc.com  Mon Dec  9 17:16:29 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Mon, 9 Dec 2024 17:16:29 -0800
Subject: [PATCH 7/8] RISC-V: KVM: Implement get event info function
In-Reply-To: <8dc7e94c-4bf2-4367-8561-166bec6ec315@sifive.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-7-a4f9691421f8@rivosinc.com> <8dc7e94c-4bf2-4367-8561-166bec6ec315@sifive.com>
Message-ID: <CAHBxVyF73ZEuPk+skhr6jJbdUYWS6cm4=vneV8jrd=7Lh0H6vQ@mail.gmail.com>

On Mon, Dec 2, 2024 at 3:02?PM Samuel Holland <samuel.holland at sifive.com> wrote:
>
> Hi Atish,
>
> On 2024-11-19 2:29 PM, Atish Patra wrote:
> > The new get_event_info funciton allows the guest to query the presence
> > of multiple events with single SBI call. Currently, the perf driver
> > in linux guest invokes it for all the standard SBI PMU events. Support
> > the SBI function implementation in KVM as well.
> >
> > Signed-off-by: Atish Patra <atishp at rivosinc.com>
> > ---
> >  arch/riscv/include/asm/kvm_vcpu_pmu.h |  3 ++
> >  arch/riscv/kvm/vcpu_pmu.c             | 67 +++++++++++++++++++++++++++++++++++
> >  arch/riscv/kvm/vcpu_sbi_pmu.c         |  3 ++
> >  3 files changed, 73 insertions(+)
> >
> > diff --git a/arch/riscv/include/asm/kvm_vcpu_pmu.h b/arch/riscv/include/asm/kvm_vcpu_pmu.h
> > index 1d85b6617508..9a930afc8f57 100644
> > --- a/arch/riscv/include/asm/kvm_vcpu_pmu.h
> > +++ b/arch/riscv/include/asm/kvm_vcpu_pmu.h
> > @@ -98,6 +98,9 @@ void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu);
> >  int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long saddr_low,
> >                                     unsigned long saddr_high, unsigned long flags,
> >                                     struct kvm_vcpu_sbi_return *retdata);
> > +int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low,
> > +                               unsigned long saddr_high, unsigned long num_events,
> > +                               unsigned long flags, struct kvm_vcpu_sbi_return *retdata);
> >  void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu);
> >  void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu);
> >
> > diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
> > index efd66835c2b8..a30f7ec31479 100644
> > --- a/arch/riscv/kvm/vcpu_pmu.c
> > +++ b/arch/riscv/kvm/vcpu_pmu.c
> > @@ -456,6 +456,73 @@ int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long s
> >       return 0;
> >  }
> >
> > +int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low,
> > +                               unsigned long saddr_high, unsigned long num_events,
> > +                               unsigned long flags, struct kvm_vcpu_sbi_return *retdata)
> > +{
> > +     unsigned long hva;
> > +     struct riscv_pmu_event_info *einfo;
> > +     int shmem_size = num_events * sizeof(*einfo);
> > +     bool writable;
> > +     gpa_t shmem;
> > +     u32 eidx, etype;
> > +     u64 econfig;
> > +     int ret;
> > +
> > +     if (flags != 0 || (saddr_low & (SZ_16 - 1))) {
> > +             ret = SBI_ERR_INVALID_PARAM;
> > +             goto out;
> > +     }
> > +
> > +     shmem = saddr_low;
> > +     if (saddr_high != 0) {
> > +             if (IS_ENABLED(CONFIG_32BIT)) {
> > +                     shmem |= ((gpa_t)saddr_high << 32);
> > +             } else {
> > +                     ret = SBI_ERR_INVALID_ADDRESS;
> > +                     goto out;
> > +             }
> > +     }
> > +
> > +     hva = kvm_vcpu_gfn_to_hva_prot(vcpu, shmem >> PAGE_SHIFT, &writable);
> > +     if (kvm_is_error_hva(hva) || !writable) {
> > +             ret = SBI_ERR_INVALID_ADDRESS;
>
> This only checks the first page if the address crosses a page boundary. Maybe
> that is okay since kvm_vcpu_read_guest()/kvm_vcpu_write_guest() will fail if a
> later page is inaccessible?
>

That's my assumption as well.
We can invoke kvm_vcpu_gfn_to_hva_prot in a loop to validate all the
pages starting with shmem though.
The difference would be the error code returned
(SBI_ERR_INVALID_ADDRESS vs SBI_ERR_FAILURE)
which the specification allows anyways.

Let me know if you think KVM must validate the entire range. I can add in v2.

> > +             goto out;
> > +     }
> > +
> > +     einfo = kzalloc(shmem_size, GFP_KERNEL);
> > +     if (!einfo)
> > +             return -ENOMEM;
> > +
> > +     ret = kvm_vcpu_read_guest(vcpu, shmem, einfo, shmem_size);
> > +     if (ret) {
> > +             ret = SBI_ERR_FAILURE;
> > +             goto free_mem;
> > +     }
> > +
> > +     for (int i = 0; i < num_events; i++) {
> > +             eidx = einfo[i].event_idx;
> > +             etype = kvm_pmu_get_perf_event_type(eidx);
> > +             econfig = kvm_pmu_get_perf_event_config(eidx, einfo[i].event_data);
> > +             ret = riscv_pmu_get_event_info(etype, econfig, NULL);
> > +             if (ret > 0)
> > +                     einfo[i].output = 1;
>
> This also needs to write `output` in the else case to indicate that the event is
> not supported; the spec does not require the caller to initialize bit 0 of
> output to zero.
>

Sure. Added.

> Regards,
> Samuel
>
> > +     }
> > +
> > +     kvm_vcpu_write_guest(vcpu, shmem, einfo, shmem_size);
> > +     if (ret) {
> > +             ret = SBI_ERR_FAILURE;
> > +             goto free_mem;
> > +     }
> > +
> > +free_mem:
> > +     kfree(einfo);
> > +out:
> > +     retdata->err_val = ret;
> > +
> > +     return 0;
> > +}
> > +
> >  int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu,
> >                               struct kvm_vcpu_sbi_return *retdata)
> >  {
> > diff --git a/arch/riscv/kvm/vcpu_sbi_pmu.c b/arch/riscv/kvm/vcpu_sbi_pmu.c
> > index e4be34e03e83..a020d979d179 100644
> > --- a/arch/riscv/kvm/vcpu_sbi_pmu.c
> > +++ b/arch/riscv/kvm/vcpu_sbi_pmu.c
> > @@ -73,6 +73,9 @@ static int kvm_sbi_ext_pmu_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
> >       case SBI_EXT_PMU_SNAPSHOT_SET_SHMEM:
> >               ret = kvm_riscv_vcpu_pmu_snapshot_set_shmem(vcpu, cp->a0, cp->a1, cp->a2, retdata);
> >               break;
> > +     case SBI_EXT_PMU_EVENT_GET_INFO:
> > +             ret = kvm_riscv_vcpu_pmu_event_info(vcpu, cp->a0, cp->a1, cp->a2, cp->a3, retdata);
> > +             break;
> >       default:
> >               retdata->err_val = SBI_ERR_NOT_SUPPORTED;
> >       }
> >
>


From atishp at rivosinc.com  Mon Dec  9 17:16:43 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Mon, 9 Dec 2024 17:16:43 -0800
Subject: [PATCH 5/8] drivers/perf: riscv: Implement PMU event info function
In-Reply-To: <0a4a569e-dfab-4aed-90df-2fe9719a3803@sifive.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-5-a4f9691421f8@rivosinc.com> <0a4a569e-dfab-4aed-90df-2fe9719a3803@sifive.com>
Message-ID: <CAHBxVyGSxMVm5QO9TmSy6MBVtc6zX0ju6n2+PK-RXuX5=KLLjA@mail.gmail.com>

On Mon, Dec 2, 2024 at 2:49?PM Samuel Holland <samuel.holland at sifive.com> wrote:
>
> Hi Atish,
>
> On 2024-11-19 2:29 PM, Atish Patra wrote:
> > With the new SBI PMU event info function, we can query the availability
> > of the all standard SBI PMU events at boot time with a single ecall.
> > This improves the bootime by avoiding making an SBI call for each
> > standard PMU event. Since this function is defined only in SBI v3.0,
> > invoke this only if the underlying SBI implementation is v3.0 or higher.
> >
> > Signed-off-by: Atish Patra <atishp at rivosinc.com>
> > ---
> >  arch/riscv/include/asm/sbi.h |  7 +++++
> >  drivers/perf/riscv_pmu_sbi.c | 71 ++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 78 insertions(+)
> >
> > diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> > index 3ee9bfa5e77c..c04f64fbc01d 100644
> > --- a/arch/riscv/include/asm/sbi.h
> > +++ b/arch/riscv/include/asm/sbi.h
> > @@ -134,6 +134,7 @@ enum sbi_ext_pmu_fid {
> >       SBI_EXT_PMU_COUNTER_FW_READ,
> >       SBI_EXT_PMU_COUNTER_FW_READ_HI,
> >       SBI_EXT_PMU_SNAPSHOT_SET_SHMEM,
> > +     SBI_EXT_PMU_EVENT_GET_INFO,
> >  };
> >
> >  union sbi_pmu_ctr_info {
> > @@ -157,6 +158,12 @@ struct riscv_pmu_snapshot_data {
> >       u64 reserved[447];
> >  };
> >
> > +struct riscv_pmu_event_info {
> > +     u32 event_idx;
> > +     u32 output;
> > +     u64 event_data;
> > +};
> > +
> >  #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
> >  #define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
> >  /* SBI v3.0 allows extended hpmeventX width value */
> > diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> > index f0e845ff6b79..2a6527cc9d97 100644
> > --- a/drivers/perf/riscv_pmu_sbi.c
> > +++ b/drivers/perf/riscv_pmu_sbi.c
> > @@ -100,6 +100,7 @@ static unsigned int riscv_pmu_irq;
> >  /* Cache the available counters in a bitmask */
> >  static unsigned long cmask;
> >
> > +static int pmu_event_find_cache(u64 config);
>
> This new declaration does not appear to be used.
>

This is a forward declaration as  pmu_event_find_cache but it should
be in the next patch instead of this patch.
I have moved it to that patch.

> >  struct sbi_pmu_event_data {
> >       union {
> >               union {
> > @@ -299,6 +300,68 @@ static struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
> >       },
> >  };
> >
> > +static int pmu_sbi_check_event_info(void)
> > +{
> > +     int num_events = ARRAY_SIZE(pmu_hw_event_map) + PERF_COUNT_HW_CACHE_MAX *
> > +                      PERF_COUNT_HW_CACHE_OP_MAX * PERF_COUNT_HW_CACHE_RESULT_MAX;
> > +     struct riscv_pmu_event_info *event_info_shmem;
> > +     phys_addr_t base_addr;
> > +     int i, j, k, result = 0, count = 0;
> > +     struct sbiret ret;
> > +
> > +     event_info_shmem = (struct riscv_pmu_event_info *)
> > +                        kcalloc(num_events, sizeof(*event_info_shmem), GFP_KERNEL);
>
> Please drop the unnecessary cast.
>

Done.

> > +     if (!event_info_shmem) {
> > +             pr_err("Can not allocate memory for event info query\n");
>
> Usually there's no need to print an error for allocation failure, since the
> allocator already warns. And this isn't really an error, since we can (and do)
> fall back to the existing way of checking for events.
>

Fixed.

> > +             return -ENOMEM;
> > +     }
> > +
> > +     for (i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
> > +             event_info_shmem[count++].event_idx = pmu_hw_event_map[i].event_idx;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) {
> > +             for (int j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) {
> > +                     for (int k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++)
> > +                             event_info_shmem[count++].event_idx =
> > +                                                     pmu_cache_event_map[i][j][k].event_idx;
> > +             }
> > +     }
> > +
> > +     base_addr = __pa(event_info_shmem);
> > +     if (IS_ENABLED(CONFIG_32BIT))
> > +             ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_EVENT_GET_INFO, lower_32_bits(base_addr),
> > +                             upper_32_bits(base_addr), count, 0, 0, 0);
> > +     else
> > +             ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_EVENT_GET_INFO, base_addr, 0,
> > +                             count, 0, 0, 0);
> > +     if (ret.error) {
> > +             result = -EOPNOTSUPP;
> > +             goto free_mem;
> > +     }
> > +     /* Do we need some barriers here or priv mode transition will ensure that */
>
> No barrier is needed -- the SBI implementation is running on the same hart, so
> coherency isn't even a consideration.
>
> > +     for (i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++) {
> > +             if (!(event_info_shmem[i].output & 0x01))
>
> This bit mask should probably use a macro.
>
> > +                     pmu_hw_event_map[i].event_idx = -ENOENT;
> > +     }
> > +
> > +     count = ARRAY_SIZE(pmu_hw_event_map);
> > +
> > +     for (i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) {
> > +             for (j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) {
> > +                     for (k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++) {
> > +                             if (!(event_info_shmem[count].output & 0x01))
>
> Same comment applies here.
>

Done.


> Regards,
> Samuel
>
> > +                                     pmu_cache_event_map[i][j][k].event_idx = -ENOENT;
> > +                             count++;
> > +                     }
> > +             }
> > +     }
> > +
> > +free_mem:
> > +     kfree(event_info_shmem);
> > +
> > +     return result;
> > +}
> > +
> >  static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
> >  {
> >       struct sbiret ret;
> > @@ -316,6 +379,14 @@ static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
> >
> >  static void pmu_sbi_check_std_events(struct work_struct *work)
> >  {
> > +     int ret;
> > +
> > +     if (sbi_v3_available) {
> > +             ret = pmu_sbi_check_event_info();
> > +             if (!ret)
> > +                     return;
> > +     }
> > +
> >       for (int i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
> >               pmu_sbi_check_event(&pmu_hw_event_map[i]);
> >
> >
>


From dmitry.baryshkov at linaro.org  Mon Dec  9 17:18:56 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 03:18:56 +0200
Subject: [PATCH v4 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <e420579f-25b2-41ca-9627-130d67c51541@norik.com>
References: <20241205134021.2592013-1-andrej.picej@norik.com>
 <20241205134021.2592013-3-andrej.picej@norik.com>
 <nbumcptoi5hwehjbrynf6dh2wrz7a4ugqblrjxyswvj7udkf3u@6qikclizqfjr>
 <e420579f-25b2-41ca-9627-130d67c51541@norik.com>
Message-ID: <xkrk3vdw7yhj22ornqog7wovqctgrolfcxbl43u7ddgstjqsbl@h22hxlld6zqg>

On Mon, Dec 09, 2024 at 08:56:29AM +0100, Andrej Picej wrote:
> Hi Dmitry,
> 
> On 5. 12. 24 23:48, Dmitry Baryshkov wrote:
> > On Thu, Dec 05, 2024 at 02:40:20PM +0100, Andrej Picej wrote:
> > > Add a optional properties to change LVDS output voltage. This should not
> > > be static as this depends mainly on the connected display voltage
> > > requirement. We have three properties:
> > > - "ti,lvds-termination-ohms", which sets near end termination,
> > > - "ti,lvds-vod-swing-data-microvolt" and
> > > - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> > > output voltage for data and clock lanes. They are defined as an array
> > > with min and max values. The appropriate bitfield will be set if
> > > selected constraints can be met.
> > > 
> > > If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> > > end termination will be used. Selecting only one:
> > > "ti,lvds-vod-swing-data-microvolt" or
> > > "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> > > constraint for only data/clock lanes will be met. Setting both is
> > > recommended.
> > > 
> > > Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> > > ---
> > > Changes in v4:
> > > - fix typo in commit message bitfiled -> bitfield
> > > - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
> > > of separate variables for channel A/B
> > > - add more checks on return value of "of_property_read_u32_array"
> > > Changes in v3:
> > > - use microvolts for default array values 1000 mV -> 1000000 uV.
> > > Changes in v2:
> > > - use datasheet tables to get the proper configuration
> > > - since major change was done change the authorship to myself
> > > ---
> > >   drivers/gpu/drm/bridge/ti-sn65dsi83.c | 147 +++++++++++++++++++++++++-
> > >   1 file changed, 144 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > index 57a7ed13f996..f724d2a6777b 100644
> > > --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > @@ -132,6 +132,16 @@
> > >   #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
> > >   #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
> > > +enum sn65dsi83_channel {
> > > +	CHANNEL_A,
> > > +	CHANNEL_B
> > > +};
> > > +
> > > +enum sn65dsi83_lvds_term {
> > > +	OHM_100,
> > > +	OHM_200
> > > +};
> > > +
> > >   enum sn65dsi83_model {
> > >   	MODEL_SN65DSI83,
> > >   	MODEL_SN65DSI84,
> > > @@ -147,6 +157,8 @@ struct sn65dsi83 {
> > >   	struct regulator		*vcc;
> > >   	bool				lvds_dual_link;
> > >   	bool				lvds_dual_link_even_odd_swap;
> > > +	int				lvds_vod_swing_conf[2];
> > > +	int				lvds_term_conf[2];
> > >   };
> > >   static const struct regmap_range sn65dsi83_readable_ranges[] = {
> > > @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
> > >   	.max_register = REG_IRQ_STAT,
> > >   };
> > > +static const int lvds_vod_swing_data_table[2][4][2] = {
> > > +	{	/* 100 Ohm */
> > > +		{ 180000, 313000 },
> > > +		{ 215000, 372000 },
> > > +		{ 250000, 430000 },
> > > +		{ 290000, 488000 },
> > > +	},
> > > +	{	/* 200 Ohm */
> > > +		{ 150000, 261000 },
> > > +		{ 200000, 346000 },
> > > +		{ 250000, 428000 },
> > > +		{ 300000, 511000 },
> > > +	},
> > > +};
> > > +
> > > +static const int lvds_vod_swing_clock_table[2][4][2] = {
> > > +	{	/* 100 Ohm */
> > > +		{ 140000, 244000 },
> > > +		{ 168000, 290000 },
> > > +		{ 195000, 335000 },
> > > +		{ 226000, 381000 },
> > > +	},
> > > +	{	/* 200 Ohm */
> > > +		{ 117000, 204000 },
> > > +		{ 156000, 270000 },
> > > +		{ 195000, 334000 },
> > > +		{ 234000, 399000 },
> > > +	},
> > > +};
> > > +
> > >   static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
> > >   {
> > >   	return container_of(bridge, struct sn65dsi83, bridge);
> > > @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
> > >   		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
> > >   	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
> > > -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
> > > +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
> > > +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
> > > +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
> > >   	regmap_write(ctx->regmap, REG_LVDS_LANE,
> > >   		     (ctx->lvds_dual_link_even_odd_swap ?
> > >   		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
> > > -		     REG_LVDS_LANE_CHA_LVDS_TERM |
> > > -		     REG_LVDS_LANE_CHB_LVDS_TERM);
> > > +		     (ctx->lvds_term_conf[CHANNEL_A] ?
> > > +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
> > > +		     (ctx->lvds_term_conf[CHANNEL_B] ?
> > > +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
> > >   	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
> > >   	le16val = cpu_to_le16(mode->hdisplay);
> > > @@ -576,10 +622,101 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
> > >   	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
> > >   };
> > > +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
> > > +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
> > > +{
> > > +	int i;
> > > +
> > > +	for (i = 0; i <= 3; i++) {
> > > +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
> > > +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
> > > +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> > > +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
> > > +			return i;
> > > +	}
> > > +
> > > +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
> > > +	return -EINVAL;
> > > +}
> > > +
> > > +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> > > +{
> > > +	struct device *dev = ctx->dev;
> > > +	struct device_node *endpoint;
> > > +	/* Set so the property can be freely selected if not defined */
> > > +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
> > > +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
> > > +	u32 lvds_term = 200;
> > > +	u8 lvds_term_conf;
> > > +	int endpoint_reg;
> > > +	int lvds_vod_swing_conf;
> > > +	int ret = 0;
> > > +	int ret_data;
> > > +	int ret_clock;
> > > +
> > > +	if (channel == CHANNEL_A)
> > > +		endpoint_reg = 2;
> > > +	else
> > > +		endpoint_reg = 3;
> > > +
> > > +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
> > > +	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
> > > +
> > > +	if (lvds_term == 200)
> > > +		lvds_term_conf = OHM_200;
> > > +	else
> > > +		lvds_term_conf = OHM_100;
> > > +
> > > +	ctx->lvds_term_conf[channel] = lvds_term_conf;
> > > +
> > > +	ret_data = of_property_read_u32_array(endpoint,
> > > +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
> > > +			ARRAY_SIZE(lvds_vod_swing_data));
> > > +	if (ret_data != 0 && ret_data != -EINVAL) {
> > > +		ret = ret_data;
> > > +		goto exit;
> > > +	}
> > > +
> > > +	ret_clock = of_property_read_u32_array(endpoint,
> > > +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
> > > +			ARRAY_SIZE(lvds_vod_swing_clk));
> > > +	if (ret_clock != 0 && ret_clock != -EINVAL) {
> > > +		ret = ret_clock;
> > > +		goto exit;
> > > +	}
> > > +
> > > +	/* If any of the two properties is defined. */
> > > +	if (!ret_data || !ret_clock) {
> > > +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
> > > +			lvds_vod_swing_data, lvds_vod_swing_clk,
> > > +			lvds_term_conf);
> > > +		if (lvds_vod_swing_conf < 0) {
> > > +			ret = lvds_vod_swing_conf;
> > > +			goto exit;
> > > +		}
> > > +
> > > +		ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
> > > +	}
> > > +	ret = 0;
> > > +exit:
> > > +	of_node_put(endpoint);
> > > +	return ret;
> > > +}
> > > +
> > >   static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
> > >   {
> > >   	struct drm_bridge *panel_bridge;
> > >   	struct device *dev = ctx->dev;
> > > +	int ret;
> > > +
> > > +	ctx->lvds_vod_swing_conf[CHANNEL_A] = 0x1;
> > > +	ctx->lvds_vod_swing_conf[CHANNEL_B] = 0x1;
> > > +	ctx->lvds_term_conf[CHANNEL_A] = 0x1;
> > > +	ctx->lvds_term_conf[CHANNEL_B] = 0x1;
> > 
> > These match the defaults in sn65dsi83_parse_lvds_endpoint(). Do we
> > really need those?
> 
> Yes, I think we do. This ensures that defaults are used even when property
> is not defined/LVDS channel is not used. So also LVDS channel B defaults are
> set even for sn65dsi83 (single LVDS output). Keeping the same reg values as
> before these changes.

You can move sn65dsi83_parse_lvds_endpoint() out of the if() and get the
same result. Duplicating data (or code) is a bad idea, because it's easy
to update one point and miss another point. And then usually one has a
nice debugging session, trying to understand why their changes didn't
work out.

> 
> Best regards,
> Andrej
> 
> 
> > 
> > > +
> > > +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
> > > +	if (ret < 0)
> > > +		return ret;
> > >   	ctx->lvds_dual_link = false;
> > >   	ctx->lvds_dual_link_even_odd_swap = false;
> > > @@ -587,6 +724,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
> > >   		struct device_node *port2, *port3;
> > >   		int dual_link;
> > > +		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
> > > +		if (ret < 0)
> > > +			return ret;
> > > +
> > >   		port2 = of_graph_get_port_by_id(dev->of_node, 2);
> > >   		port3 = of_graph_get_port_by_id(dev->of_node, 3);
> > >   		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
> > > -- 
> > > 2.34.1
> > > 
> > 

-- 
With best wishes
Dmitry


From andyshrk at 163.com  Mon Dec  9 17:21:36 2024
From: andyshrk at 163.com (Andy Yan)
Date: Tue, 10 Dec 2024 09:21:36 +0800 (CST)
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2
 controller
In-Reply-To: <ay5hbnqqjhopaqof6z7j2rzm2bc6xa2vbzan2ak3if6wzmyip2@kqh7gtrajnm2>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241209150619.33998-1-dse@thaumatec.com>
 <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org> <2203458.KiezcSG77Q@diego>
 <4e015ea9.960.193ae0c236a.Coremail.andyshrk@163.com>
 <ay5hbnqqjhopaqof6z7j2rzm2bc6xa2vbzan2ak3if6wzmyip2@kqh7gtrajnm2>
Message-ID: <33e2c5db.1300.193ae284b6d.Coremail.andyshrk@163.com>


Hi Dmitry,

? 2024-12-10 09:01:38?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
>On Tue, Dec 10, 2024 at 08:50:51AM +0800, Andy Yan wrote:
>> 
>> 
>> Hi,
>> 
>> At 2024-12-10 07:12:26, "Heiko St?bner" <heiko at sntech.de> wrote:
>> >Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
>> >> Hi,
>> >> 
>> >> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
>> >> > On 03.12.24 21:54, Heiko Stuebner wrote:
>> >> > > This series adds a bridge and glue driver for the DSI2 controller found
>> >> > > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
>> >> > > 
>> >> >
>> >> > I did more tests with different LVDS displays. I tested following
>> >> > configurations with DSI/LVDS bridge:
>> >> > - 1024x600 at 60.01
>> >> > - 1024x768 at 60.02
>> >> > - 1280x800 at 60.07
>> >> > - 1366x768 at 60.06
>> >> >
>> >> > All of them worked without issues, except 1366x768.
>> >> > With this resolution, video is blurry, and offset incorrectly
>> >> > to the left. There are also repeating errors on the console:
>> >> >
>> >> >   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
>> >> >
>> >> > In correct operation with other resolutions, there is no error.
>> >> > I am not sure if this is a problem in your series or rather in VOP2
>> >> > driver.
>> >
>> >This really sounds like something is wrong on the vop side.
>> >The interrupt is part of the vop, the divisable by 4 things likely too.
>> 
>> This is a hardware limitation on vop side:
>> The horizontal resolution must be 4 pixel aligned.
>
>Then mode_valid() and atomic_check() must reject modes that don't fit.

We round down to 4 pixel aligned in mode_fixup in our bsp kernel, 
because sometimes, some boards do indeed choose a screen that is not 4 pixel aligned
>
>> 
>> 
>> 
>
>-- 
>With best wishes
>Dmitry

From ck.hu at mediatek.com  Mon Dec  9 17:22:49 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 10 Dec 2024 01:22:49 +0000
Subject: [PATCH v2 14/15] drm/mediatek: mtk_hdmi_common: Add OP_HDMI,
 vendor and product strings
In-Reply-To: <7a4f8b11-e840-4e33-a6e7-4f58601ed31c@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-15-angelogioacchino.delregno@collabora.com>
	 <6697eef88677950d36fbfbd6676f82f291621159.camel@mediatek.com>
	 <7a4f8b11-e840-4e33-a6e7-4f58601ed31c@collabora.com>
Message-ID: <bbbfd8df7673b170ceb24a22238230dc2b35b0f2.camel@mediatek.com>

On Mon, 2024-12-09 at 10:56 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Il 09/12/24 10:09, CK Hu (???) ha scritto:
> > Hi, Angelo:
> > 
> > On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> > > External email : Please do not click links or open attachments until you have verified the sender or the content.
> > > 
> > > 
> > > In preparation for adding the HDMI TX v2 driver, and to allow
> > > a future modernization of the HDMI v1 one, perform changes
> > > that enable the usage of the HDMI Helpers provided by DRM.
> > > 
> > > Check if the HDMI driver provides the function pointers to
> > > hdmi_{clear,write}_infoframe used by the HDMI Helper API and,
> > > if present, add DRM_BRIDGE_OP_HDMI to the drm_bridge ops,
> > > enabling the drm API to register the bridge as HDMI and to use
> > > the HDMI Helper functions.
> > > 
> > > Moreover, as part of data exclusively used (in the context of
> > > HDMI bridges) by the helpers, assign the vendor "MediaTek" and
> > > product "On-Chip HDMI" strings to the drm_bridge struct.
> > > 
> > > If the hdmi_{write,clear}_infoframe pointers are not assigned,
> > > vendor and product strings and HDMI helpers will not be used,
> > > hence this commit brings no functional changes to drivers that
> > > have not been refactored to use the new helpers.
> > > 
> > > This also means that, in the current state, there is effectively
> > > no functional change to mtk_hdmi and its other components.
> > 
> > OP_HDMI is for v2.
> > vendor and product strings is for both v1 and v2.
> > So separate this patch to two patches.
> > 
> 
> They're both for v2, because only v2 uses the HDMI helpers, while v1 does not.

Sorry, these two is required by DRM_BRIDGE_OP_HDMI.

  /**
         * @vendor: Vendor of the product to be used for the SPD InfoFrame
         * generation. This is required if @DRM_BRIDGE_OP_HDMI is set.
         */
        const char *vendor;
 
        /**
         * @product: Name of the product to be used for the SPD InfoFrame
         * generation. This is required if @DRM_BRIDGE_OP_HDMI is set.
         */
        const char *product;

So,

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

> 
> Cheers,
> Angelo
> 
> > Regards,
> > CK
> > 
> > > 
> > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > > ---
> > >   drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 7 +++++++
> > >   1 file changed, 7 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> > > index 4f708b04f5e8..0f60842462b0 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> > > @@ -408,9 +408,16 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
> > > 
> > >          hdmi->bridge.funcs = ver_conf->bridge_funcs;
> > >          hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
> > > +
> > > +       if (ver_conf->bridge_funcs->hdmi_write_infoframe &&
> > > +           ver_conf->bridge_funcs->hdmi_clear_infoframe)
> > > +               hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI;
> > > +
> > >          hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
> > >          hdmi->bridge.of_node = pdev->dev.of_node;
> > >          hdmi->bridge.ddc = hdmi->ddc_adpt;
> > > +       hdmi->bridge.vendor = "MediaTek";
> > > +       hdmi->bridge.product = "On-Chip HDMI";
> > > 
> > >          ret = devm_drm_bridge_add(dev, &hdmi->bridge);
> > >          if (ret)
> > > --
> > > 2.47.0
> > > 
> > 
> 
> 


From pgwipeout at gmail.com  Mon Dec  9 17:30:07 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 01:30:07 +0000
Subject: [PATCH 3/6] arm64: dts: rockchip: remove ethernet alias from rk3328-roc
In-Reply-To: <20241210013010.81257-1-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
Message-ID: <20241210013010.81257-4-pgwipeout@gmail.com>

Remove the ethernet alias added back in during the rk3328-roc dtsi
conversion.

Fixes: f3c6526d6fb2 ("arm64: dts: rockchip: Convert dts files used as parents to dtsi files")
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---

 arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
index b5bd5e7d5748..f782c8220dd3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
@@ -9,7 +9,6 @@
 
 / {
 	aliases {
-		ethernet0 = &gmac2io;
 		mmc0 = &sdmmc;
 		mmc1 = &emmc;
 	};
-- 
2.39.5



From pgwipeout at gmail.com  Mon Dec  9 17:30:08 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 01:30:08 +0000
Subject: [PATCH 4/6] arm64: dts: rockchip: add hevc power domain clock to rk3328
In-Reply-To: <20241210013010.81257-1-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
Message-ID: <20241210013010.81257-5-pgwipeout@gmail.com>

There is a race condition at startup between disabling power domains not
used and disabling clocks not used on the rk3328. When the clocks are
disabled first, the hevc power domain fails to shut off leading to a
splat of failures. Add the hevc core clock to the rk3328 power domain
node to prevent this condition.

rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-.... }
1087 jiffies s: 89 root: 0x8/.
rcu: blocking rcu_node structures (internal RCU debug):
Sending NMI from CPU 0 to CPUs 3:
NMI backtrace for cpu 3
CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53
Hardware name: Firefly ROC-RK3328-CC (DT)
Workqueue: pm genpd_power_off_work_fn
pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : regmap_unlock_spinlock+0x18/0x30
lr : regmap_read+0x60/0x88
sp : ffff800081123c00
x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000
x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040
x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74
x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000
x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d
x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431
x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0
x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b
x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40
x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000
Call trace:
regmap_unlock_spinlock+0x18/0x30
rockchip_pmu_set_idle_request+0xac/0x2c0
rockchip_pd_power+0x144/0x5f8
rockchip_pd_power_off+0x1c/0x30
_genpd_power_off+0x9c/0x180
genpd_power_off.part.0.isra.0+0x130/0x2a8
genpd_power_off_work_fn+0x6c/0x98
process_one_work+0x170/0x3f0
worker_thread+0x290/0x4a8
kthread+0xec/0xf8
ret_from_fork+0x10/0x20
rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack on
domain 'hevc', val=0x88220

Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for RK3328 SoCs")
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---

 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0597de415fe0..7d992c3c01ce 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -333,6 +333,7 @@ power: power-controller {
 
 			power-domain at RK3328_PD_HEVC {
 				reg = <RK3328_PD_HEVC>;
+				clocks = <&cru SCLK_VENC_CORE>;
 				#power-domain-cells = <0>;
 			};
 			power-domain at RK3328_PD_VIDEO {
-- 
2.39.5



From pgwipeout at gmail.com  Mon Dec  9 17:30:09 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 01:30:09 +0000
Subject: [PATCH 5/6] arm64: dts: rockchip: correct rk3328-roc regulator map
In-Reply-To: <20241210013010.81257-1-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
Message-ID: <20241210013010.81257-6-pgwipeout@gmail.com>

The rk3328-roc-cc input power is sourced from a micro-usb port, while
the rk3328-roc-pc input power is sourced from a usb-c port. Both inputs
are 5vdc only. Remove the 12v input from the device tree.

While we are at it, add missing voltages and supply to vcc_phy, missing
voltages to vcc_host1_5v, and standardize the order of regulator
properties among the fixed regulators.

Fixes: 2171f4fdac06 ("arm64: dts: rockchip: add roc-rk3328-cc board")
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---

 arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 23 +++++++++++++-------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
index f782c8220dd3..6984387ff8b3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
@@ -24,22 +24,23 @@ gmac_clkin: external-gmac-clock {
 		#clock-cells = <0>;
 	};
 
-	dc_12v: regulator-dc-12v {
+	/* fed from passive usb input connector */
+	dc_5v: regulator-dc-5v {
 		compatible = "regulator-fixed";
-		regulator-name = "dc_12v";
+		regulator-name = "dc_5v";
 		regulator-always-on;
 		regulator-boot-on;
-		regulator-min-microvolt = <12000000>;
-		regulator-max-microvolt = <12000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
 	};
 
 	vcc_sd: regulator-sdmmc {
 		compatible = "regulator-fixed";
+		regulator-name = "vcc_sd";
 		gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&sdmmc0m1_pin>;
 		regulator-boot-on;
-		regulator-name = "vcc_sd";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_io>;
@@ -50,22 +51,25 @@ vcc_sdio: regulator-sdmmcio {
 		states = <1800000 0x1>, <3300000 0x0>;
 		regulator-name = "vcc_sdio";
 		regulator-type = "voltage";
+		regulator-always-on;
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <3300000>;
-		regulator-always-on;
 		vin-supply = <&vcc_sys>;
 	};
 
 	vcc_host1_5v: vcc_otg_5v: regulator-vcc-host1-5v {
 		compatible = "regulator-fixed";
+		regulator-name = "vcc_host1_5v";
 		enable-active-high;
 		pinctrl-names = "default";
 		pinctrl-0 = <&usb20_host_drv>;
-		regulator-name = "vcc_host1_5v";
 		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
 		vin-supply = <&vcc_sys>;
 	};
 
+	/* sourced from usb input through 3A fuse */
 	vcc_sys: regulator-vcc-sys {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_sys";
@@ -73,7 +77,7 @@ vcc_sys: regulator-vcc-sys {
 		regulator-boot-on;
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
-		vin-supply = <&dc_12v>;
+		vin-supply = <&dc_5v>;
 	};
 
 	vcc_phy: regulator-vcc-phy {
@@ -81,6 +85,9 @@ vcc_phy: regulator-vcc-phy {
 		regulator-name = "vcc_phy";
 		regulator-always-on;
 		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_io>;
 	};
 
 	leds {
-- 
2.39.5



From pgwipeout at gmail.com  Mon Dec  9 17:30:10 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 01:30:10 +0000
Subject: [PATCH 6/6] arm64: dts: rockchip: Remove address aligned beats from rk3328-roc
In-Reply-To: <20241210013010.81257-1-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
Message-ID: <20241210013010.81257-7-pgwipeout@gmail.com>

Since commit 8a469ee35606 ("arm64: dts: rockchip: Add txpbl node for
RK3399/RK3328"), the snps,aal, snps,txpbl, and snps,rxpbl nodes have
been unnecessary in the separate device trees. There is also a
performance loss to using snps,aal. Remove these from the rk3328-roc
device tree.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>

---

 arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
index 6984387ff8b3..0d476cc2144d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
@@ -155,12 +155,9 @@ &gmac2io {
 	phy-mode = "rgmii";
 	pinctrl-names = "default";
 	pinctrl-0 = <&rgmiim1_pins>;
-	snps,aal;
 	snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
 	snps,reset-active-low;
 	snps,reset-delays-us = <0 10000 50000>;
-	snps,rxpbl = <0x4>;
-	snps,txpbl = <0x4>;
 	tx_delay = <0x24>;
 	rx_delay = <0x18>;
 	status = "okay";
-- 
2.39.5



From pgwipeout at gmail.com  Mon Dec  9 17:30:04 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 01:30:04 +0000
Subject: [PATCH 0/6] rockchip: rk3328 fixes in preparation for usb3-phy
Message-ID: <20241210013010.81257-1-pgwipeout@gmail.com>


This is a series of fixes I uncovered during my work on the next
generation rk3328 usb3 phy driver.

The first patch fixes the error handling of the pm-domain driver. I
don't expect this to break anything, but it is entirely possible some
driver code makes some bad assumptions on the fact that this has been
broken from the very beginning.

The second patch fixes the ref_usb3otg clock parent. This was preventing
correct reclocking of the usb3 phy.

The third patch fixes the ethernet alias that was accidentlly readded
during the rk3328-roc dtsi conversion.

The fourth patch fixes a race condition between power domains and clocks
being shut off during boot, which would cause an ugly splat on rk3328
during boot on recent kernels.

The fifth patch corrects the rk3328-roc fixed regulators and power input
map. It also cleans up the fixed regulator flags to be consistent.

The sixth patch removes address aligned beats and the redundant rxpbl
and txpbl flags from the rk3328-roc, which are unnecessary now.

Please examine and test these as necessary, especially the pm-domain fix
patch.

Very Respectfully,
Peter Geis


Peter Geis (6):
  pmdomain: rockchip: fix rockchip_pd_power error handling
  clk: rockchip: fix wrong clk_ref_usb3otg parent for rk3328
  arm64: dts: rockchip: remove ethernet alias from rk3328-roc
  arm64: dts: rockchip: add hevc power domain clock to rk3328
  arm64: dts: rockchip: correct rk3328-roc regulator map
  arm64: dts: rockchip: Remove address aligned beats from rk3328-roc

 arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 27 +++++++++++---------
 arch/arm64/boot/dts/rockchip/rk3328.dtsi     |  1 +
 drivers/clk/rockchip/clk-rk3328.c            |  2 +-
 drivers/pmdomain/rockchip/pm-domains.c       |  8 ++++--
 4 files changed, 23 insertions(+), 15 deletions(-)

-- 
2.39.5



From pgwipeout at gmail.com  Mon Dec  9 17:30:05 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 01:30:05 +0000
Subject: [PATCH 1/6] pmdomain: rockchip: fix rockchip_pd_power error handling
In-Reply-To: <20241210013010.81257-1-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
Message-ID: <20241210013010.81257-2-pgwipeout@gmail.com>

The calls rockchip_pd_power makes to rockchip_pmu_set_idle_request lack
any return error handling, causing device drivers to incorrectly believe
the hardware idle requests succeed when they may have failed. This leads
to software possibly accessing hardware that is powered off and the
subsequent SError panic that follows.

Add error checking and return errors to the calling function to prevent
such crashes.

gst-launch-1.0 videotestsrc num-buffers=2000 ! v4l2jpegenc ! fakesink
Setting pipeline to PAUSED ...er-x64
Pipeline is PREROLLING ...
Redistribute latency...
rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack on
domain 'hevc', val=0x98260, idle = 0
SError Interrupt on CPU2, code 0x00000000bf000002 -- SError
CPU: 2 UID: 0 PID: 804 Comm: videotestsrc0:s Not tainted 6.12.0-rc5+ #54
Hardware name: Firefly roc-rk3328-cc (DT)
pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : rockchip_vpu2_jpeg_enc_run+0x168/0xbc8
lr : device_run+0xb0/0x128
sp : ffff800082143a20
x29: ffff800082143a20 x28: 0000000000000140 x27: 0000000000000000
x26: ffff582c47a313e8 x25: ffff582c53e95000 x24: ffff582c53e92800
x23: ffff582c5bbe0000 x22: 0000000000000000 x21: ffff582c47a31080
x20: ffffa0d78cfa4168 x19: ffffa0d78cfa4168 x18: ffffb755b0519000
x17: 000000040044ffff x16: 00500072b5503510 x15: a7a6a5a4a3a29a99
x14: 989796959493928a x13: 0000000051eb851f x12: 00000000000000ff
x11: ffffa0d78d812880 x10: ffffa0d78d7fbca0 x9 : 000000000000003f
x8 : 0000000000000063 x7 : 000000000000003f x6 : 0000000000000040
x5 : ffff80008010d000 x4 : ffffa0d78cfa4168 x3 : ffffa0d78cfbfdd8
x2 : ffff80008010d0f4 x1 : 0000000000000020 x0 : 0000000000000140
Kernel panic - not syncing: Asynchronous SError Interrupt
CPU: 2 UID: 0 PID: 804 Comm: videotestsrc0:s Not tainted 6.12.0-rc5+ #54
Hardware name: Firefly roc-rk3328-cc (DT)
Call trace:
dump_backtrace+0xa0/0x128
show_stack+0x20/0x38
dump_stack_lvl+0xc8/0xf8
dump_stack+0x18/0x28
panic+0x3ec/0x428
nmi_panic+0x48/0xa0
arm64_serror_panic+0x6c/0x88
do_serror+0x30/0x70
el1h_64_error_handler+0x38/0x60
el1h_64_error+0x7c/0x80
rockchip_vpu2_jpeg_enc_run+0x168/0xbc8
device_run+0xb0/0x128
v4l2_m2m_try_run+0xac/0x230
v4l2_m2m_ioctl_streamon+0x70/0x90
v4l_streamon+0x2c/0x40
__video_do_ioctl+0x194/0x400
video_usercopy+0x10c/0x808
video_ioctl2+0x20/0x80
v4l2_ioctl+0x48/0x70
__arm64_sys_ioctl+0xb0/0x100
invoke_syscall+0x50/0x120
el0_svc_common.constprop.0+0x48/0xf0
do_el0_svc+0x24/0x38
el0_svc+0x38/0x100
el0t_64_sync_handler+0xc0/0xc8
el0t_64_sync+0x1a8/0x1b0
SMP: stopping secondary CPUs
Kernel Offset: 0x20d70c000000 from 0xffff800080000000
PHYS_OFFSET: 0xffffa7d3c0000000
CPU features: 0x00,00000090,00200000,0200421b
Memory Limit: none
---[ end Kernel panic - not syncing: Asynchronous SError Interrupt ]---

Fixes: 7c696693a4f5 ("soc: rockchip: power-domain: Add power domain driver")
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---

 drivers/pmdomain/rockchip/pm-domains.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
index cb0f93800138..57e8fa25d2bd 100644
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -590,14 +590,18 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
 			rockchip_pmu_save_qos(pd);
 
 			/* if powering down, idle request to NIU first */
-			rockchip_pmu_set_idle_request(pd, true);
+			ret = rockchip_pmu_set_idle_request(pd, true);
+			if (ret < 0)
+				return ret;
 		}
 
 		rockchip_do_pmu_set_power_domain(pd, power_on);
 
 		if (power_on) {
 			/* if powering up, leave idle mode */
-			rockchip_pmu_set_idle_request(pd, false);
+			ret = rockchip_pmu_set_idle_request(pd, false);
+			if (ret < 0)
+				return ret;
 
 			rockchip_pmu_restore_qos(pd);
 		}
-- 
2.39.5



From pgwipeout at gmail.com  Mon Dec  9 17:30:06 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 01:30:06 +0000
Subject: [PATCH 2/6] clk: rockchip: fix wrong clk_ref_usb3otg parent for rk3328
In-Reply-To: <20241210013010.81257-1-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
Message-ID: <20241210013010.81257-3-pgwipeout@gmail.com>

Correct the clk_ref_usb3otg parent to fix clock control for the usb3
controller on rk3328. Verified against the rk3328 trm and usb3 clock tree
documentation.

Fixes: fe3511ad8a1c ("clk: rockchip: add clock controller for rk3328")
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---

 drivers/clk/rockchip/clk-rk3328.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
index 3bb87b27b662..cf60fcf2fa5c 100644
--- a/drivers/clk/rockchip/clk-rk3328.c
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -201,7 +201,7 @@ PNAME(mux_aclk_peri_pre_p)	= { "cpll_peri",
 				    "gpll_peri",
 				    "hdmiphy_peri" };
 PNAME(mux_ref_usb3otg_src_p)	= { "xin24m",
-				    "clk_usb3otg_ref" };
+				    "clk_ref_usb3otg_src" };
 PNAME(mux_xin24m_32k_p)		= { "xin24m",
 				    "clk_rtc32k" };
 PNAME(mux_mac2io_src_p)		= { "clk_mac2io_src",
-- 
2.39.5



From andrew at lunn.ch  Mon Dec  9 17:36:29 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 10 Dec 2024 02:36:29 +0100
Subject: [net-next PATCH v11 9/9] net: phy: Add Airoha AN8855 Internal
 Switch Gigabit PHY
In-Reply-To: <20241209134459.27110-10-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-10-ansuelsmth@gmail.com>
Message-ID: <b3b79c80-ac7c-456b-a3b5-eee61f671694@lunn.ch>

> +config AIR_AN8855_PHY
> +	tristate "Airoha AN8855 Internal Gigabit PHY"
> +	help
> +	  Currently supports the internal Airoha AN8855 Switch PHY.
> +
>  config AIR_EN8811H_PHY
>  	tristate "Airoha EN8811H 2.5 Gigabit PHY"
>  	help

Do you have any idea why the new one is AN, and previous one is EN?  I
just like consistent naming, or an explanation why it is not
consistent.

> +#define AN8855_PHY_ID				0xc0ff0410
> +static struct phy_driver an8855_driver[] = {
> +{
> +	PHY_ID_MATCH_EXACT(AN8855_PHY_ID),

Is there any documentation about the ID, and the lower nibble. Given
it is 0, i'm wondering if PHY_ID_MATCH_EXACT() is correct.

	Andrew


From xueshuai at linux.alibaba.com  Mon Dec  9 17:38:54 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Tue, 10 Dec 2024 09:38:54 +0800
Subject: [PATCH v12 4/5] drivers/perf: add DesignWare PCIe PMU driver
In-Reply-To: <20241209224741.GA3206765@bhelgaas>
References: <20241209224741.GA3206765@bhelgaas>
Message-ID: <5139818d-8e1b-44ff-bfb4-18a1aca8afed@linux.alibaba.com>



? 2024/12/10 06:47, Bjorn Helgaas ??:
> On Mon, Dec 09, 2024 at 03:40:16PM +0000, Will Deacon wrote:
>> On Fri, Dec 06, 2024 at 10:54:57AM -0600, Bjorn Helgaas wrote:
>>> On Fri, Dec 08, 2023 at 10:56:51AM +0800, Shuai Xue wrote:
>>>> This commit adds the PCIe Performance Monitoring Unit (PMU) driver support
>>>> for T-Head Yitian SoC chip. Yitian is based on the Synopsys PCI Express
>>>> Core controller IP which provides statistics feature. The PMU is a PCIe
>>>> configuration space register block provided by each PCIe Root Port in a
>>>> Vendor-Specific Extended Capability named RAS D.E.S (Debug, Error
>>>> injection, and Statistics).
>>>
>>>> +#define DWC_PCIE_VSEC_RAS_DES_ID		0x02
>>>
>>>> +static const struct dwc_pcie_vendor_id dwc_pcie_vendor_ids[] = {
>>>> +	{.vendor_id = PCI_VENDOR_ID_ALIBABA },
>>>> +	{} /* terminator */
>>>> +};
>>>
>>>> +static bool dwc_pcie_match_des_cap(struct pci_dev *pdev)
>>>> +{
>>>> +	const struct dwc_pcie_vendor_id *vid;
>>>> +	u16 vsec;
>>>> +	u32 val;
>>>> +
>>>> +	if (!pci_is_pcie(pdev) || !(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT))
>>>> +		return false;
>>>> +
>>>> +	for (vid = dwc_pcie_vendor_ids; vid->vendor_id; vid++) {
>>>> +		vsec = pci_find_vsec_capability(pdev, vid->vendor_id,
>>>> +						DWC_PCIE_VSEC_RAS_DES_ID);
>>>
>>> This looks wrong to me, and it promotes a misunderstanding of how VSEC
>>> Capabilities work.  The VSEC ID is defined by the vendor, so we have
>>> to check both the Vendor ID and the VSEC ID before we know what this
>>> VSEC Capability is.
>>
>> Thanks for pointing this out! The code's been merged for a while now,
>> so we'll need to fix what we have rather than revert it, I think.
> 
> Yep, for sure.
> 
>> Any chance you could send a patch with those, please? I'm also not able
>> to test this stuff, but I'm sure Ilkka would help us out.
> 
> Posted at https://lore.kernel.org/linux-pci/20241209222938.3219364-1-helgaas at kernel.org
> 
> Bjorn

Hi, Bjorn and Will,

Thanks for pointing this out and fix it so quickly, I will also test this patch
on our platform later.

Best Regards,
Shuai




From dmitry.baryshkov at linaro.org  Mon Dec  9 17:45:11 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 03:45:11 +0200
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2 controller
In-Reply-To: <33e2c5db.1300.193ae284b6d.Coremail.andyshrk@163.com>
References: <20241203165450.1501219-1-heiko@sntech.de> <20241209150619.33998-1-dse@thaumatec.com>
 <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org> <2203458.KiezcSG77Q@diego>
 <4e015ea9.960.193ae0c236a.Coremail.andyshrk@163.com> <ay5hbnqqjhopaqof6z7j2rzm2bc6xa2vbzan2ak3if6wzmyip2@kqh7gtrajnm2>
 <33e2c5db.1300.193ae284b6d.Coremail.andyshrk@163.com>
Message-ID: <CAA8EJprLA09NP0KAztc5eoAMkGcrom84jg_pcbNcwN0FAaSLrw@mail.gmail.com>

On Tue, 10 Dec 2024 at 03:22, Andy Yan <andyshrk at 163.com> wrote:
>
>
> Hi Dmitry,
>
> ? 2024-12-10 09:01:38?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
> >On Tue, Dec 10, 2024 at 08:50:51AM +0800, Andy Yan wrote:
> >>
> >>
> >> Hi,
> >>
> >> At 2024-12-10 07:12:26, "Heiko St?bner" <heiko at sntech.de> wrote:
> >> >Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
> >> >> Hi,
> >> >>
> >> >> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
> >> >> > On 03.12.24 21:54, Heiko Stuebner wrote:
> >> >> > > This series adds a bridge and glue driver for the DSI2 controller found
> >> >> > > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
> >> >> > >
> >> >> >
> >> >> > I did more tests with different LVDS displays. I tested following
> >> >> > configurations with DSI/LVDS bridge:
> >> >> > - 1024x600 at 60.01
> >> >> > - 1024x768 at 60.02
> >> >> > - 1280x800 at 60.07
> >> >> > - 1366x768 at 60.06
> >> >> >
> >> >> > All of them worked without issues, except 1366x768.
> >> >> > With this resolution, video is blurry, and offset incorrectly
> >> >> > to the left. There are also repeating errors on the console:
> >> >> >
> >> >> >   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
> >> >> >
> >> >> > In correct operation with other resolutions, there is no error.
> >> >> > I am not sure if this is a problem in your series or rather in VOP2
> >> >> > driver.
> >> >
> >> >This really sounds like something is wrong on the vop side.
> >> >The interrupt is part of the vop, the divisable by 4 things likely too.
> >>
> >> This is a hardware limitation on vop side:
> >> The horizontal resolution must be 4 pixel aligned.
> >
> >Then mode_valid() and atomic_check() must reject modes that don't fit.
>
> We round down to 4 pixel aligned in mode_fixup in our bsp kernel,

What is meant by the "bsp kernel" here? I don't see it being present
in the mainline kernel. So, if the mode is unsupported, it should be
rejected.

> because sometimes, some boards do indeed choose a screen that is not 4 pixel aligned
> >
> >>
> >>
> >>
> >
> >--
> >With best wishes
> >Dmitry



-- 
With best wishes
Dmitry


From Jason-JH.Lin at mediatek.com  Mon Dec  9 17:45:45 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Tue, 10 Dec 2024 01:45:45 +0000
Subject: [PATCH v2] drm/mediatek: Move mtk_crtc_finish_page_flip() to
 ddp_cmdq_cb()
In-Reply-To: <c0092a07a9e6d0bc9b2dc85f379e6cddfa095ef7.camel@mediatek.com>
References: <20241119163658.31405-1-jason-jh.lin@mediatek.com>
	 <c0092a07a9e6d0bc9b2dc85f379e6cddfa095ef7.camel@mediatek.com>
Message-ID: <b7398d1fb0d5ee96acf3587c44379b3f639a9a38.camel@mediatek.com>

Hi CK,

Thanks for the review.

[snip]

> >  static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
> >  {
> >  	unsigned long flags;
> > +	struct drm_crtc *crtc = &mtk_crtc->base;
> > +	struct mtk_drm_private *priv = crtc->dev->dev_private;
> >  
> >  	drm_crtc_handle_vblank(&mtk_crtc->base);
> >  
> > -	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> > -	if (!mtk_crtc->config_updating && mtk_crtc-
> > >pending_needs_vblank) {
> > -		mtk_crtc_finish_page_flip(mtk_crtc);
> > -		mtk_crtc->pending_needs_vblank = false;
> > +	if (priv->data->shadow_register) {
> 
> if (!priv->data->shadow_register)
> 	return;
> 
> And this would reduce the indent.
> 

OK, I'll adjust this.

> > +		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> > +		if (!mtk_crtc->config_updating && mtk_crtc-
> > >pending_needs_vblank) {
> > +			mtk_crtc_finish_page_flip(mtk_crtc);
> > +			mtk_crtc->pending_needs_vblank = false;
> > +		}
> > +		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> >  	}
> > -	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> >  }
> >  
> >  static void mtk_crtc_destroy(struct drm_crtc *crtc)
> > @@ -284,10 +288,8 @@ static void ddp_cmdq_cb(struct mbox_client
> > *cl, void *mssg)
> >  	state = to_mtk_crtc_state(mtk_crtc->base.state);
> >  
> >  	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> > -	if (mtk_crtc->config_updating) {
> > -		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> > +	if (mtk_crtc->config_updating)
> >  		goto ddp_cmdq_cb_out;
> > -	}
> >  
> >  	state->pending_config = false;
> >  
> > @@ -315,10 +317,15 @@ static void ddp_cmdq_cb(struct mbox_client
> > *cl, void *mssg)
> >  		mtk_crtc->pending_async_planes = false;
> >  	}
> >  
> > -	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> > -
> >  ddp_cmdq_cb_out:
> >  
> > +	if (mtk_crtc->pending_needs_vblank) {
> > +		mtk_crtc_finish_page_flip(mtk_crtc);
> > +		mtk_crtc->pending_needs_vblank = false;
> 
> In mtk_crtc_update_config(), after mbox_client_txdone() and before
> mtk_crtc->config_updating = false;
> cmdq may have finish the command and callback ddp_cmdq_cb().
> Because mtk_crtc->config_updating is true, so this page flip would be
> skipped.
> But if there is no next mtk_crtc_update_config() exist, this page
> flip would never happen.
> This may cause some deadlock.
> 

OK, I'll move the mtk_crtc->config_updating = false; earlier than 
mbox_client_txdone() to avoid skipping the page flip.

Regards,
Jason-JH.Lin

> Regards,
> CK

From andrew at lunn.ch  Mon Dec  9 17:53:34 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 10 Dec 2024 02:53:34 +0100
Subject: [net-next PATCH v11 6/9] net: mdio: Add Airoha AN8855 Switch
 MDIO Passtrough
In-Reply-To: <20241209134459.27110-7-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-7-ansuelsmth@gmail.com>
Message-ID: <5aec4a94-3cea-41a4-8500-71472fae51d4@lunn.ch>

> +static int an855_phy_restore_page(struct an8855_mfd_priv *priv,
> +				  int phy) __must_hold(&priv->bus->mdio_lock)
> +{
> +	/* Check PHY page only for addr shared with switch */
> +	if (phy != priv->switch_addr)
> +		return 0;
> +
> +	/* Don't restore page if it's not set to switch page */
> +	if (priv->current_page != FIELD_GET(AN8855_PHY_PAGE,
> +					    AN8855_PHY_PAGE_EXTENDED_4))
> +		return 0;
> +
> +	/* Restore page to 0, PHY might change page right after but that
> +	 * will be ignored as it won't be a switch page.
> +	 */
> +	return an8855_mii_set_page(priv, phy, AN8855_PHY_PAGE_STANDARD);
> +}

I don't really understand what is going on here. Maybe the commit
message needs expanding, or the function names changing.

Generally, i would expect a save/restore action. Save the current
page, swap to the PHY page, do the PHY access, and then restore to the
saved page.

	Andrew


From andyshrk at 163.com  Mon Dec  9 17:54:09 2024
From: andyshrk at 163.com (Andy Yan)
Date: Tue, 10 Dec 2024 09:54:09 +0800 (CST)
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2
 controller
In-Reply-To: <CAA8EJprLA09NP0KAztc5eoAMkGcrom84jg_pcbNcwN0FAaSLrw@mail.gmail.com>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241209150619.33998-1-dse@thaumatec.com>
 <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org> <2203458.KiezcSG77Q@diego>
 <4e015ea9.960.193ae0c236a.Coremail.andyshrk@163.com>
 <ay5hbnqqjhopaqof6z7j2rzm2bc6xa2vbzan2ak3if6wzmyip2@kqh7gtrajnm2>
 <33e2c5db.1300.193ae284b6d.Coremail.andyshrk@163.com>
 <CAA8EJprLA09NP0KAztc5eoAMkGcrom84jg_pcbNcwN0FAaSLrw@mail.gmail.com>
Message-ID: <2d68155e.1e5b.193ae4616b9.Coremail.andyshrk@163.com>


Hi Dmitry,

? 2024-12-10 09:45:11?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
>On Tue, 10 Dec 2024 at 03:22, Andy Yan <andyshrk at 163.com> wrote:
>>
>>
>> Hi Dmitry,
>>
>> ? 2024-12-10 09:01:38?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
>> >On Tue, Dec 10, 2024 at 08:50:51AM +0800, Andy Yan wrote:
>> >>
>> >>
>> >> Hi,
>> >>
>> >> At 2024-12-10 07:12:26, "Heiko St?bner" <heiko at sntech.de> wrote:
>> >> >Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
>> >> >> Hi,
>> >> >>
>> >> >> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
>> >> >> > On 03.12.24 21:54, Heiko Stuebner wrote:
>> >> >> > > This series adds a bridge and glue driver for the DSI2 controller found
>> >> >> > > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
>> >> >> > >
>> >> >> >
>> >> >> > I did more tests with different LVDS displays. I tested following
>> >> >> > configurations with DSI/LVDS bridge:
>> >> >> > - 1024x600 at 60.01
>> >> >> > - 1024x768 at 60.02
>> >> >> > - 1280x800 at 60.07
>> >> >> > - 1366x768 at 60.06
>> >> >> >
>> >> >> > All of them worked without issues, except 1366x768.
>> >> >> > With this resolution, video is blurry, and offset incorrectly
>> >> >> > to the left. There are also repeating errors on the console:
>> >> >> >
>> >> >> >   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
>> >> >> >
>> >> >> > In correct operation with other resolutions, there is no error.
>> >> >> > I am not sure if this is a problem in your series or rather in VOP2
>> >> >> > driver.
>> >> >
>> >> >This really sounds like something is wrong on the vop side.
>> >> >The interrupt is part of the vop, the divisable by 4 things likely too.
>> >>
>> >> This is a hardware limitation on vop side:
>> >> The horizontal resolution must be 4 pixel aligned.
>> >
>> >Then mode_valid() and atomic_check() must reject modes that don't fit.
>>
>> We round down to 4 pixel aligned in mode_fixup in our bsp kernel,
>
>What is meant by the "bsp kernel" here? I don't see it being present

bsp kernel means downstream vendor kernel.

>in the mainline kernel. So, if the mode is unsupported, it should be

Will it be acceptable to add this round down in the mainline mode_fixup?

>rejected.
>
>> because sometimes, some boards do indeed choose a screen that is not 4 pixel aligned
>> >
>> >>
>> >>
>> >>
>> >
>> >--
>> >With best wishes
>> >Dmitry
>
>
>
>-- 
>With best wishes
>Dmitry

From xu.yang_2 at nxp.com  Mon Dec  9 18:02:12 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Tue, 10 Dec 2024 10:02:12 +0800
Subject: [PATCH v2] perf: imx9_perf: Introduce AXI filter version to
 refactor the driver and better extension
In-Reply-To: <20241209154419.GB12428@willie-the-truck>
References: <20241125104338.2433339-1-xu.yang_2@nxp.com>
 <20241209154419.GB12428@willie-the-truck>
Message-ID: <20241210020212.yz3xowvdk27zmgsl@hippo>

Hi Will,

On Mon, Dec 09, 2024 at 03:44:20PM +0000, Will Deacon wrote:
> On Mon, Nov 25, 2024 at 06:43:38PM +0800, Xu Yang wrote:
> > The imx93 is the first supported DDR PMU that supports read transaction,
> > write transaction and read beats events which corresponding respecitively
> > to counter 2, 3 and 4.
> > 
> > However, transaction-based AXI match has low accuracy when get total bits
> > compared to beats-based. And imx93 doesn't assign AXI_ID to each master.
> > So axi filter is not used widely on imx93. This could be regards as AXI
> > filter version 1.
> > 
> > To improve the AXI filter capability, imx95 supports 1 read beats and 3
> > write beats event which corresponding respecitively to counter 2-5. imx95
> > also detailed AXI_ID allocation so that most of the master could be count
> > individually. This could be regards as AXI filter version 2.
> > 
> > This will introduce AXI filter version to refactor the driver and support
> > better extension, such as coming imx943.
> > 
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > 
> > ---
> > Changes in v2:
> >  - modify subject
> >  - add comments for AXI_FILTER version
> >  - type -> filter_ver
> > ---
> >  drivers/perf/fsl_imx9_ddr_perf.c | 33 ++++++++++++++++++++++++--------
> >  1 file changed, 25 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
> > index 3c856d9a4e97..e2c2c674b6d2 100644
> > --- a/drivers/perf/fsl_imx9_ddr_perf.c
> > +++ b/drivers/perf/fsl_imx9_ddr_perf.c
> > @@ -63,8 +63,21 @@
> >  
> >  static DEFINE_IDA(ddr_ida);
> >  
> > +/*
> > + * V1 support 1 read transaction, 1 write transaction and 1 read beats
> > + * event which corresponding respecitively to counter 2, 3 and 4.
> > + */
> > +#define DDR_PERF_AXI_FILTER_V1		0x1
> > +
> > +/*
> > + * V2 support 1 read beats and 3 write beats events which corresponding
> > + * respecitively to counter 2-5.
> > + */
> > +#define DDR_PERF_AXI_FILTER_V2		0x2
> > +
> >  struct imx_ddr_devtype_data {
> >  	const char *identifier;		/* system PMU identifier for userspace */
> > +	unsigned int filter_ver;	/* AXI filter version */
> >  };
> >  
> >  struct ddr_pmu {
> > @@ -83,24 +96,27 @@ struct ddr_pmu {
> >  
> >  static const struct imx_ddr_devtype_data imx91_devtype_data = {
> >  	.identifier = "imx91",
> > +	.filter_ver = DDR_PERF_AXI_FILTER_V1
> >  };
> 
> [...]
> 
> > -static inline bool is_imx93(struct ddr_pmu *pmu)
> > +static inline bool axi_filter_v1(struct ddr_pmu *pmu)
> >  {
> > -	return pmu->devtype_data == &imx93_devtype_data;
> > +	return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V1;
> >  }
> 
> [...]
> 
> > @@ -624,11 +641,11 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
> >  	hwc->idx = counter;
> >  	hwc->state |= PERF_HES_STOPPED;
> >  
> > -	if (is_imx93(pmu))
> > +	if (axi_filter_v1(pmu))
> >  		/* read trans, write trans, read beat */
> >  		imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
> 
> Hmm, doesn't this change mean we now enable this for imx91 as well? My
> reading of the commit message is that imx93 was the first chip which
> supports this.

Yes, it's enabled for imx91 too. In fact, imx91 is compatible with imx93.
They use same configuration for axi filter.

Thanks,
Xu Yang

> 
> Will


From kaleshsingh at google.com  Mon Dec  9 18:41:08 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:08 -0800
Subject: [PATCH mm-unstable 06/17] mm: csky: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-7-kaleshsingh@google.com>

Introduce csky arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/csky/abiv1/inc/abi/pgtable-bits.h |  1 +
 arch/csky/abiv1/mmap.c                 | 38 ++++++++++++++++++--------
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/arch/csky/abiv1/inc/abi/pgtable-bits.h b/arch/csky/abiv1/inc/abi/pgtable-bits.h
index ae7a2f76dd42..c346a9fcb522 100644
--- a/arch/csky/abiv1/inc/abi/pgtable-bits.h
+++ b/arch/csky/abiv1/inc/abi/pgtable-bits.h
@@ -51,5 +51,6 @@
 					((offset) << 10)})
 
 #define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* __ASM_CSKY_PGTABLE_BITS_H */
diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c
index 1047865e82a9..184921a73856 100644
--- a/arch/csky/abiv1/mmap.c
+++ b/arch/csky/abiv1/mmap.c
@@ -13,6 +13,29 @@
 	((((addr)+SHMLBA-1)&~(SHMLBA-1)) +	\
 	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	int do_align = 0;
+
+	if (!addr)
+		return 0;
+
+	/*
+	 * We only need to do colour alignment if either the I or D
+	 * caches alias.
+	 */
+	do_align = filp || (flags & MAP_SHARED);
+
+	if (do_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 /*
  * We need to ensure that shared mappings are correctly aligned to
  * avoid aliasing issues with VIPT caches.  We need to ensure that
@@ -27,7 +50,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	int do_align = 0;
 	struct vm_unmapped_area_info info = {
 		.length = len,
@@ -55,17 +77,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	if (len > TASK_SIZE)
 		return -ENOMEM;
 
-	if (addr) {
-		if (do_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
 	return vm_unmapped_area(&info);
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:09 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:09 -0800
Subject: [PATCH mm-unstable 07/17] mm: loongarch: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-8-kaleshsingh@google.com>

Introduce loongarch arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/loongarch/include/asm/pgtable.h |  1 +
 arch/loongarch/mm/mmap.c             | 40 ++++++++++++++++++----------
 2 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
index da346733a1da..326a6c4b7488 100644
--- a/arch/loongarch/include/asm/pgtable.h
+++ b/arch/loongarch/include/asm/pgtable.h
@@ -624,6 +624,7 @@ static inline long pmd_protnone(pmd_t pmd)
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/loongarch/mm/mmap.c b/arch/loongarch/mm/mmap.c
index 914e82ff3f65..b7db43fabca1 100644
--- a/arch/loongarch/mm/mmap.c
+++ b/arch/loongarch/mm/mmap.c
@@ -17,12 +17,32 @@
 
 enum mmap_allocation_direction {UP, DOWN};
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	int do_color_align = 0;
+
+	if (!addr)
+		return 0;
+
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
+
 static unsigned long arch_get_unmapped_area_common(struct file *filp,
 	unsigned long addr0, unsigned long len, unsigned long pgoff,
 	unsigned long flags, enum mmap_allocation_direction dir)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	unsigned long addr = addr0;
 	int do_color_align;
 	struct vm_unmapped_area_info info = {};
@@ -45,23 +65,15 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
 		return addr;
 	}
 
+	/* requesting a specific address */
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
+
 	do_color_align = 0;
 	if (filp || (flags & MAP_SHARED))
 		do_color_align = 1;
 
-	/* requesting a specific address */
-	if (addr) {
-		if (do_color_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
-
 	info.length = len;
 	info.align_mask = do_color_align ? (PAGE_MASK & SHM_ALIGN_MASK) : 0;
 	info.align_offset = pgoff << PAGE_SHIFT;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:10 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:10 -0800
Subject: [PATCH mm-unstable 08/17] mm: mips: Introduce arch_align_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-9-kaleshsingh@google.com>

Introduce mips arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/mips/include/asm/pgtable.h |  1 +
 arch/mips/mm/mmap.c             | 39 +++++++++++++++++++++------------
 2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index c29a551eb0ca..837f25624369 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -766,5 +766,6 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* _ASM_PGTABLE_H */
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 5d2a1225785b..cd09a933aad6 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -26,12 +26,31 @@ EXPORT_SYMBOL(shm_align_mask);
 
 enum mmap_allocation_direction {UP, DOWN};
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	int do_color_align = 0;
+
+	if (!addr)
+		return 0;
+
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 static unsigned long arch_get_unmapped_area_common(struct file *filp,
 	unsigned long addr0, unsigned long len, unsigned long pgoff,
 	unsigned long flags, enum mmap_allocation_direction dir)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	unsigned long addr = addr0;
 	int do_color_align;
 	struct vm_unmapped_area_info info = {};
@@ -54,23 +73,15 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
 		return addr;
 	}
 
+	/* requesting a specific address */
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
+
 	do_color_align = 0;
 	if (filp || (flags & MAP_SHARED))
 		do_color_align = 1;
 
-	/* requesting a specific address */
-	if (addr) {
-		if (do_color_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
-
 	info.length = len;
 	info.align_mask = do_color_align ? (PAGE_MASK & shm_align_mask) : 0;
 	info.align_offset = pgoff << PAGE_SHIFT;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:11 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:11 -0800
Subject: [PATCH mm-unstable 09/17] mm: parisc: Introduce arch_align_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-10-kaleshsingh@google.com>

Introduce parisc arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/parisc/include/asm/pgtable.h |  1 +
 arch/parisc/kernel/sys_parisc.c   | 37 ++++++++++++++++++++-----------
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index babf65751e81..73987357c78e 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -505,6 +505,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index f852fe274abe..8ab05b29c505 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -96,12 +96,32 @@ unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
 
 enum mmap_allocation_direction {UP, DOWN};
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	unsigned long filp_pgoff = GET_FILP_PGOFF(filp);
+	int do_color_align = 0;
+
+	if (!addr)
+		return 0;
+
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+
+	if (do_color_align)
+		addr = COLOR_ALIGN(addr, filp_pgoff, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 static unsigned long arch_get_unmapped_area_common(struct file *filp,
 	unsigned long addr, unsigned long len, unsigned long pgoff,
 	unsigned long flags, enum mmap_allocation_direction dir)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma, *prev;
 	unsigned long filp_pgoff;
 	int do_color_align;
 	struct vm_unmapped_area_info info = {
@@ -128,18 +148,9 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
 		return addr;
 	}
 
-	if (addr) {
-		if (do_color_align)
-			addr = COLOR_ALIGN(addr, filp_pgoff, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma_prev(mm, addr, &prev);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)) &&
-		    (!prev || addr >= vm_end_gap(prev)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.align_mask = do_color_align ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
 	info.align_offset = shared_align_offset(filp_pgoff, pgoff);
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:13 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:13 -0800
Subject: [PATCH mm-unstable 11/17] mm: sh: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-12-kaleshsingh@google.com>

Introduce sh arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/sh/include/asm/pgtable.h |  1 +
 arch/sh/mm/mmap.c             | 48 +++++++++++++++++++----------------
 2 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index 729f5c6225fb..072dbe038808 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -149,5 +149,6 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
 /* arch/sh/mm/mmap.c */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* __ASM_SH_PGTABLE_H */
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index c442734d9b0c..5c96055dd5f5 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -51,6 +51,26 @@ static inline unsigned long COLOUR_ALIGN(unsigned long addr,
 	return base + off;
 }
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	int do_color_align = 0;
+
+	if (!addr)
+		return 0;
+
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	unsigned long len, unsigned long pgoff, unsigned long flags,
 	vm_flags_t vm_flags)
@@ -77,17 +97,9 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	if (filp || (flags & MAP_SHARED))
 		do_colour_align = 1;
 
-	if (addr) {
-		if (do_colour_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.length = len;
 	info.low_limit = TASK_UNMAPPED_BASE;
@@ -126,17 +138,9 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 		do_colour_align = 1;
 
 	/* requesting a specific address */
-	if (addr) {
-		if (do_colour_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:14 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:14 -0800
Subject: [PATCH mm-unstable 12/17] mm: sparc32: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-13-kaleshsingh@google.com>

Introduce sparc32 arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.

If a sufficiently sized hole doesn't exist at the hint address,
fallback to searching the entire valid VA space instead of only
the VA space above the hint address.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/sparc/include/asm/pgtable_32.h |  1 +
 arch/sparc/kernel/sys_sparc_32.c    | 21 ++++++++++++++++++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 62bcafe38b1f..95084c4d0b01 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -437,6 +437,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
 
 /* We provide our own get_unmapped_area to cope with VA holes for userland */
 #define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_MMAP_HINT
 
 #define pmd_pgtable(pmd)	((pgtable_t)__pmd_page(pmd))
 
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index fb31bc0c5b48..2d5065ee1a94 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -40,6 +40,19 @@ SYSCALL_DEFINE0(getpagesize)
 	return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */
 }
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	if (!addr)
+		return 0;
+
+	if (len > TASK_SIZE - PAGE_SIZE)
+		return 0;
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
 {
 	struct vm_unmapped_area_info info = {};
@@ -61,11 +74,13 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
 	/* See asm-sparc/uaccess.h */
 	if (len > TASK_SIZE - PAGE_SIZE)
 		return -ENOMEM;
-	if (!addr)
-		addr = TASK_UNMAPPED_BASE;
+
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.length = len;
-	info.low_limit = addr;
+	info.low_limit = TASK_UNMAPPED_BASE;
 	info.high_limit = TASK_SIZE;
 	if (!file_hugepage) {
 		info.align_mask = (flags & MAP_SHARED) ?
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:15 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:15 -0800
Subject: [PATCH mm-unstable 13/17] mm: sparc64: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-14-kaleshsingh@google.com>

Introduce sparc64 arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/sparc/include/asm/pgtable_64.h |  1 +
 arch/sparc/kernel/sys_sparc_64.c    | 47 +++++++++++++++++++++--------
 2 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 2b7f358762c1..f24a4eb2777b 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -1148,6 +1148,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 /* We provide a special get_unmapped_area for framebuffer mmaps to try and use
  * the largest alignment possible such that larget PTEs can be used.
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index c5a284df7b41..a782696e98e0 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -98,10 +98,39 @@ static unsigned long get_align_mask(struct file *filp, unsigned long flags)
 	return 0;
 }
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	unsigned long task_size = TASK_SIZE;
+	bool file_hugepage = false;
+	int do_color_align = 0;
+
+	if (!addr)
+		return 0;
+
+	if (filp && is_file_hugepages(filp))
+		file_hugepage = true;
+
+	if ((filp || (flags & MAP_SHARED)) && !file_hugepage)
+		do_color_align = 1;
+
+	if (test_thread_flag(TIF_32BIT))
+		task_size = STACK_TOP32;
+
+	if (unlikely(len > task_size || len >= VA_EXCLUDE_START))
+		return 0;
+
+	if (do_color_align)
+		addr = COLOR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
 {
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct * vma;
 	unsigned long task_size = TASK_SIZE;
 	int do_color_align;
 	struct vm_unmapped_area_info info = {};
@@ -129,17 +158,9 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
 	if ((filp || (flags & MAP_SHARED)) && !file_hugepage)
 		do_color_align = 1;
 
-	if (addr) {
-		if (do_color_align)
-			addr = COLOR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (task_size - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.length = len;
 	info.low_limit = TASK_UNMAPPED_BASE;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:16 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:16 -0800
Subject: [PATCH mm-unstable 14/17] mm: xtensa: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-15-kaleshsingh@google.com>

Introduce xtensa arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.

If a sufficiently sized hole doesn't exist at the hint address,
fallback to searching the entire valid VA space instead of only
the VA space above the hint address.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/xtensa/include/asm/pgtable.h |  1 +
 arch/xtensa/kernel/syscall.c      | 26 ++++++++++++++++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 1647a7cc3fbf..31b7da0805ec 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -425,5 +425,6 @@ void update_mmu_tlb_range(struct vm_area_struct *vma,
  * SHM area cache aliasing for userland.
  */
 #define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* _XTENSA_PGTABLE_H */
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c
index dc54f854c2f5..353cce1ac9f1 100644
--- a/arch/xtensa/kernel/syscall.c
+++ b/arch/xtensa/kernel/syscall.c
@@ -54,6 +54,24 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice,
 }
 
 #ifdef CONFIG_MMU
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	if (!addr)
+		return 0;
+
+	if (len > TASK_SIZE)
+		return 0;
+
+	if (flags & MAP_SHARED)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		unsigned long len, unsigned long pgoff, unsigned long flags,
 		vm_flags_t vm_flags)
@@ -73,8 +91,12 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 
 	if (len > TASK_SIZE)
 		return -ENOMEM;
-	if (!addr)
-		addr = TASK_UNMAPPED_BASE;
+
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
+
+	addr = TASK_UNMAPPED_BASE;
 
 	if (flags & MAP_SHARED)
 		addr = COLOUR_ALIGN(addr, pgoff);
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:17 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:17 -0800
Subject: [PATCH mm-unstable 15/17] mm: powerpc: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-16-kaleshsingh@google.com>

Introduce powerpc arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/powerpc/include/asm/book3s/64/slice.h |  1 +
 arch/powerpc/mm/book3s64/slice.c           | 31 ++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/arch/powerpc/include/asm/book3s/64/slice.h b/arch/powerpc/include/asm/book3s/64/slice.h
index 5fbe18544cbd..89f629080e90 100644
--- a/arch/powerpc/include/asm/book3s/64/slice.h
+++ b/arch/powerpc/include/asm/book3s/64/slice.h
@@ -10,6 +10,7 @@
 #endif
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 #endif
 
 #define SLICE_LOW_SHIFT		28
diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c
index bc9a39821d1c..70b95968301a 100644
--- a/arch/powerpc/mm/book3s64/slice.c
+++ b/arch/powerpc/mm/book3s64/slice.c
@@ -647,6 +647,37 @@ static int file_to_psize(struct file *file)
 }
 #endif
 
+static unsigned long slice_mmap_hint(unsigned long addr, unsigned long len,
+				     unsigned long flags, unsigned int psize)
+{
+	unsigned long hint_addr = slice_get_unmapped_area(addr, len, flags, psize, 0);
+
+	if (IS_ERR_VALUE(hint_addr) || hint_addr != PAGE_ALIGN(addr))
+		return 0;
+
+	return hint_addr;
+}
+
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	unsigned int psize;
+
+	if (!addr)
+		return 0;
+
+	if (radix_enabled())
+		return generic_mmap_hint(filp, addr, len, pgoff, flags);
+
+	if (filp && is_file_hugepages(filp))
+		psize = file_to_psize(filp);
+	else
+		psize = mm_ctx_user_psize(&current->mm->context);
+
+	return slice_mmap_hint(addr, len, flags, psize);
+}
+
 unsigned long arch_get_unmapped_area(struct file *filp,
 				     unsigned long addr,
 				     unsigned long len,
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:18 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:18 -0800
Subject: [PATCH mm-unstable 16/17] mm: Fallback to generic_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-17-kaleshsingh@google.com>

If an architecture doesn't provide arch_mmap_hint() fallback to
generic_mmap_hint().

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 mm/mmap.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/mm/mmap.c b/mm/mmap.c
index e97eb8bf4889..59bf7d127aa1 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -691,6 +691,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 }
 #endif
 
+#ifndef HAVE_ARCH_MMAP_HINT
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+#endif
+
 /*
  * This mmap-allocator allocates new areas top-down from below the
  * stack's low limit (the base):
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:19 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:19 -0800
Subject: [PATCH mm-unstable 17/17] mm: Respect mmap hint before THP alignment
 if allocation is possible
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-18-kaleshsingh@google.com>

Commit 249608ee4713 ("mm: respect mmap hint address when aligning for THP")
fallsback to PAGE_SIZE alignment instead of THP alignment
for anonymous mapping as long as a hint address is provided by the user
-- even if we weren't able to allocate the unmapped area at the hint
address in the end.

This was done to address the immediate regression in anonymous mappings
where the hint address were being ignored in some cases; due to commit
efa7df3e3bb5 ("mm: align larger anonymous mappings on THP boundaries").

It was later pointed out that this issue also existed for file-backed
mappings from file systems that use thp_get_unmapped_area() for their
.get_unmapped_area() file operation.

The same fix was not applied for file-backed mappings since it would
mean any mmap requests that provide a hint address would be only
PAGE_SIZE-aligned regardless of whether allocation was successful at
the hint address or not.

Instead, use arch_mmap_hint() to first attempt allocation at the hint
address and fallback to THP alignment if that fails.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 mm/huge_memory.c | 15 ++++++++-------
 mm/mmap.c        |  1 -
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 137abeda8602..f070c89dafc9 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1097,6 +1097,14 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
 	loff_t off_align = round_up(off, size);
 	unsigned long len_pad, ret, off_sub;
 
+	/*
+	 * If allocation at the address hint succeeds; respect the hint and
+	 * don't try to align to THP boundary.
+	 */
+	addr = arch_mmap_hint(filp, addr, len, off, flags);
+	if (addr)
+		return addr;
+
 	if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall())
 		return 0;
 
@@ -1117,13 +1125,6 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
 	if (IS_ERR_VALUE(ret))
 		return 0;
 
-	/*
-	 * Do not try to align to THP boundary if allocation at the address
-	 * hint succeeds.
-	 */
-	if (ret == addr)
-		return addr;
-
 	off_sub = (off - ret) & (size - 1);
 
 	if (test_bit(MMF_TOPDOWN, &current->mm->flags) && !off_sub)
diff --git a/mm/mmap.c b/mm/mmap.c
index 59bf7d127aa1..6bfeec80152a 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -807,7 +807,6 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
 	if (get_area) {
 		addr = get_area(file, addr, len, pgoff, flags);
 	} else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && !file
-		   && !addr /* no hint */
 		   && IS_ALIGNED(len, PMD_SIZE)) {
 		/* Ensures that larger anonymous mappings are THP aligned. */
 		addr = thp_get_unmapped_area_vmflags(file, addr, len,
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:02 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:02 -0800
Subject: [PATCH mm-unstable 00/17] mm: Introduce arch_mmap_hint()
Message-ID: <20241210024119.2488608-1-kaleshsingh@google.com>

Hi all,

This series introduces aarch_mmap_hint() to handle allocating VA space
for the hint address.

Patches 1-16 introduce this new helper and Patch 17 uses it to fix the
issue of mmap hint being ignored in some cases due to THP alignment [1]

[1] https://lore.kernel.org/r/20241118214650.3667577-1-kaleshsingh at google.com/

Thanks,
Kalesh

Kalesh Singh (17):
  mm: Introduce generic_mmap_hint()
  mm: x86: Introduce arch_mmap_hint()
  mm: arm: Introduce arch_mmap_hint()
  mm: alpha: Introduce arch_mmap_hint()
  mm: arc: Use generic_mmap_hint()
  mm: csky: Introduce arch_mmap_hint()
  mm: loongarch: Introduce arch_mmap_hint()
  mm: mips: Introduce arch_align_mmap_hint()
  mm: parisc: Introduce arch_align_mmap_hint()
  mm: s390: Introduce arch_mmap_hint()
  mm: sh: Introduce arch_mmap_hint()
  mm: sparc32: Introduce arch_mmap_hint()
  mm: sparc64: Introduce arch_mmap_hint()
  mm: xtensa: Introduce arch_mmap_hint()
  mm: powerpc: Introduce arch_mmap_hint()
  mm: Fallback to generic_mmap_hint()
  mm: Respect mmap hint before THP alignment if allocation is possible

 arch/alpha/include/asm/pgtable.h           |  1 +
 arch/alpha/kernel/osf_sys.c                | 29 ++++++++++--
 arch/arc/mm/mmap.c                         | 12 ++---
 arch/arm/include/asm/pgtable.h             |  1 +
 arch/arm/mm/mmap.c                         | 54 ++++++++++++---------
 arch/csky/abiv1/inc/abi/pgtable-bits.h     |  1 +
 arch/csky/abiv1/mmap.c                     | 38 ++++++++++-----
 arch/loongarch/include/asm/pgtable.h       |  1 +
 arch/loongarch/mm/mmap.c                   | 40 ++++++++++------
 arch/mips/include/asm/pgtable.h            |  1 +
 arch/mips/mm/mmap.c                        | 39 +++++++++------
 arch/parisc/include/asm/pgtable.h          |  1 +
 arch/parisc/kernel/sys_parisc.c            | 37 ++++++++++-----
 arch/powerpc/include/asm/book3s/64/slice.h |  1 +
 arch/powerpc/mm/book3s64/slice.c           | 31 ++++++++++++
 arch/s390/include/asm/pgtable.h            |  1 +
 arch/s390/mm/mmap.c                        | 32 ++++++-------
 arch/sh/include/asm/pgtable.h              |  1 +
 arch/sh/mm/mmap.c                          | 48 ++++++++++---------
 arch/sparc/include/asm/pgtable_32.h        |  1 +
 arch/sparc/include/asm/pgtable_64.h        |  1 +
 arch/sparc/kernel/sys_sparc_32.c           | 21 +++++++--
 arch/sparc/kernel/sys_sparc_64.c           | 47 +++++++++++++-----
 arch/x86/include/asm/pgtable_64.h          |  1 +
 arch/x86/kernel/sys_x86_64.c               | 49 ++++++++++---------
 arch/xtensa/include/asm/pgtable.h          |  1 +
 arch/xtensa/kernel/syscall.c               | 26 +++++++++-
 include/linux/sched/mm.h                   |  8 ++++
 mm/huge_memory.c                           | 15 +++---
 mm/mmap.c                                  | 55 ++++++++++++++--------
 30 files changed, 401 insertions(+), 193 deletions(-)

-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:03 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:03 -0800
Subject: [PATCH mm-unstable 01/17] mm: Introduce generic_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-2-kaleshsingh@google.com>

Consolidate the hint searches from both direcitons (topdown and
bottomup) into generic_mmap_hint().

No functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 include/linux/sched/mm.h |  4 ++++
 mm/mmap.c                | 45 ++++++++++++++++++++++++----------------
 2 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index 928a626725e6..edeec19d1708 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -201,6 +201,10 @@ unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm,
 					   unsigned long flags,
 					   vm_flags_t vm_flags);
 
+unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
+				unsigned long len, unsigned long pgoff,
+				unsigned long flags);
+
 unsigned long
 generic_get_unmapped_area(struct file *filp, unsigned long addr,
 			  unsigned long len, unsigned long pgoff,
diff --git a/mm/mmap.c b/mm/mmap.c
index df9154b15ef9..e97eb8bf4889 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -620,6 +620,27 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)
 	return addr;
 }
 
+unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
+				unsigned long len, unsigned long pgoff,
+				unsigned long flags)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma, *prev;
+	const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
+
+	if (!addr)
+		return 0;
+
+	addr = PAGE_ALIGN(addr);
+	vma = find_vma_prev(mm, addr, &prev);
+	if (mmap_end - len >= addr && addr >= mmap_min_addr &&
+	    (!vma || addr + len <= vm_start_gap(vma)) &&
+	    (!prev || addr >= vm_end_gap(prev)))
+		return addr;
+
+	return 0;
+}
+
 /* Get an address range which is currently unmapped.
  * For shmat() with addr=0.
  *
@@ -637,7 +658,6 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
 			  unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma, *prev;
 	struct vm_unmapped_area_info info = {};
 	const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
 
@@ -647,14 +667,9 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
 	if (flags & MAP_FIXED)
 		return addr;
 
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma_prev(mm, addr, &prev);
-		if (mmap_end - len >= addr && addr >= mmap_min_addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)) &&
-		    (!prev || addr >= vm_end_gap(prev)))
-			return addr;
-	}
+	addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.length = len;
 	info.low_limit = mm->mmap_base;
@@ -685,7 +700,6 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 				  unsigned long len, unsigned long pgoff,
 				  unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma, *prev;
 	struct mm_struct *mm = current->mm;
 	struct vm_unmapped_area_info info = {};
 	const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
@@ -698,14 +712,9 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 		return addr;
 
 	/* requesting a specific address */
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma_prev(mm, addr, &prev);
-		if (mmap_end - len >= addr && addr >= mmap_min_addr &&
-				(!vma || addr + len <= vm_start_gap(vma)) &&
-				(!prev || addr >= vm_end_gap(prev)))
-			return addr;
-	}
+	addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:04 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:04 -0800
Subject: [PATCH mm-unstable 02/17] mm: x86: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-3-kaleshsingh@google.com>

Introduce x86 arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/x86/include/asm/pgtable_64.h |  1 +
 arch/x86/kernel/sys_x86_64.c      | 49 ++++++++++++++++++-------------
 include/linux/sched/mm.h          |  4 +++
 3 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index d1426b64c1b9..4472fd0040c3 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -245,6 +245,7 @@ extern void cleanup_highmap(void);
 
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #define PAGE_AGP    PAGE_KERNEL_NOCACHE
 #define HAVE_PAGE_AGP 1
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 776ae6fa7f2d..95a39ef915b7 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -123,12 +123,32 @@ static inline unsigned long stack_guard_placement(vm_flags_t vm_flags)
 	return 0;
 }
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	unsigned long begin, end;
+
+	if (!addr)
+		return 0;
+
+	find_start_end(addr, flags, &begin, &end);
+
+	addr = PAGE_ALIGN(addr);
+
+	if (!mmap_address_hint_valid(addr, len))
+		return 0;
+
+	if (len > end)
+		return 0;
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 unsigned long
 arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
 		       unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
 {
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	struct vm_unmapped_area_info info = {};
 	unsigned long begin, end;
 
@@ -140,13 +160,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
 	if (len > end)
 		return -ENOMEM;
 
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (end - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.length = len;
 	info.low_limit = begin;
@@ -168,8 +184,6 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
 			  unsigned long len, unsigned long pgoff,
 			  unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma;
-	struct mm_struct *mm = current->mm;
 	unsigned long addr = addr0;
 	struct vm_unmapped_area_info info = {};
 
@@ -186,16 +200,9 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
 		goto bottomup;
 
 	/* requesting a specific address */
-	if (addr) {
-		addr &= PAGE_MASK;
-		if (!mmap_address_hint_valid(addr, len))
-			goto get_unmapped_area;
-
-		vma = find_vma(mm, addr);
-		if (!vma || addr + len <= vm_start_gap(vma))
-			return addr;
-	}
-get_unmapped_area:
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index edeec19d1708..f12d094649f7 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -205,6 +205,10 @@ unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
 				unsigned long len, unsigned long pgoff,
 				unsigned long flags);
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags);
+
 unsigned long
 generic_get_unmapped_area(struct file *filp, unsigned long addr,
 			  unsigned long len, unsigned long pgoff,
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:05 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:05 -0800
Subject: [PATCH mm-unstable 03/17] mm: arm: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-4-kaleshsingh@google.com>

Introduce arm arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/arm/include/asm/pgtable.h |  1 +
 arch/arm/mm/mmap.c             | 54 +++++++++++++++++++---------------
 2 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index be91e376df79..1433b3ff4caa 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -330,6 +330,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 3dbb383c26d5..c415410eb64a 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -17,6 +17,31 @@
 	((((addr)+SHMLBA-1)&~(SHMLBA-1)) +	\
 	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	int aliasing = cache_is_vipt_aliasing();
+	int do_align = 0;
+
+	if (!addr)
+		return 0;
+
+	/*
+	 * We only need to do colour alignment if either the I or D
+	 * caches alias.
+	 */
+	if (aliasing)
+		do_align = filp || (flags & MAP_SHARED);
+
+	if (do_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 /*
  * We need to ensure that shared mappings are correctly aligned to
  * avoid aliasing issues with VIPT caches.  We need to ensure that
@@ -32,7 +57,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	int do_align = 0;
 	int aliasing = cache_is_vipt_aliasing();
 	struct vm_unmapped_area_info info = {};
@@ -57,17 +81,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	if (len > TASK_SIZE)
 		return -ENOMEM;
 
-	if (addr) {
-		if (do_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.length = len;
 	info.low_limit = mm->mmap_base;
@@ -82,7 +98,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 		        const unsigned long len, const unsigned long pgoff,
 		        const unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
 	unsigned long addr = addr0;
 	int do_align = 0;
@@ -108,16 +123,9 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 	}
 
 	/* requesting a specific address */
-	if (addr) {
-		if (do_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-				(!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:06 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:06 -0800
Subject: [PATCH mm-unstable 04/17] mm: alpha: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-5-kaleshsingh@google.com>

Introduce alpha arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/alpha/include/asm/pgtable.h |  1 +
 arch/alpha/kernel/osf_sys.c      | 29 ++++++++++++++++++++++++-----
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h
index 635f0a5f5bbd..372885a01abd 100644
--- a/arch/alpha/include/asm/pgtable.h
+++ b/arch/alpha/include/asm/pgtable.h
@@ -362,5 +362,6 @@ extern void paging_init(void);
 
 /* We have our own get_unmapped_area to cope with ADDR_LIMIT_32BIT.  */
 #define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* _ALPHA_PGTABLE_H */
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 86185021f75a..68e61dece537 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -1225,6 +1225,27 @@ arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
 	return vm_unmapped_area(&info);
 }
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	unsigned long limit;
+
+	if (!addr)
+		return 0;
+
+	/* "32 bit" actually means 31 bit, since pointers sign extend.  */
+	if (current->personality & ADDR_LIMIT_32BIT)
+		limit = 0x80000000;
+	else
+		limit = TASK_SIZE;
+
+	if (limit - len < addr)
+		return 0;
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 unsigned long
 arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		       unsigned long len, unsigned long pgoff,
@@ -1254,11 +1275,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	   merely specific addresses, but regions of memory -- perhaps
 	   this feature should be incorporated into all ports?  */
 
-	if (addr) {
-		addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
-		if (addr != (unsigned long) -ENOMEM)
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return hint;
 
 	/* Next, try allocating at TASK_UNMAPPED_BASE.  */
 	addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:07 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:07 -0800
Subject: [PATCH mm-unstable 05/17] mm: arc: Use generic_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-6-kaleshsingh@google.com>

Use generic_mmap_hint() in arch arch_get_unmapped_area().

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/arc/mm/mmap.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c
index 2185afe8d59f..6b1fcea06779 100644
--- a/arch/arc/mm/mmap.c
+++ b/arch/arc/mm/mmap.c
@@ -27,7 +27,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	struct vm_unmapped_area_info info = {};
 
 	/*
@@ -43,14 +42,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	if (len > TASK_SIZE)
 		return -ENOMEM;
 
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.length = len;
 	info.low_limit = mm->mmap_base;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Mon Dec  9 18:41:12 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Mon,  9 Dec 2024 18:41:12 -0800
Subject: [PATCH mm-unstable 10/17] mm: s390: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-1-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
Message-ID: <20241210024119.2488608-11-kaleshsingh@google.com>

Introduce s390 arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/s390/include/asm/pgtable.h |  1 +
 arch/s390/mm/mmap.c             | 32 ++++++++++++++++----------------
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 48268095b0a3..eaecb558ab9b 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -1997,6 +1997,7 @@ extern void s390_reset_cmma(struct mm_struct *mm);
 /* s390 has a private copy of get unmapped area to deal with cache synonyms */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #define pmd_pgtable(pmd) \
 	((pgtable_t)__va(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE))
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index 33f3504be90b..3f82401b77cd 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -83,12 +83,21 @@ static int get_align_mask(struct file *filp, unsigned long flags)
 	return 0;
 }
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	if (len > TASK_SIZE - mmap_min_addr)
+		return 0;
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 				     unsigned long len, unsigned long pgoff,
 				     unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	struct vm_unmapped_area_info info = {};
 
 	if (len > TASK_SIZE - mmap_min_addr)
@@ -97,13 +106,9 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	if (flags & MAP_FIXED)
 		goto check_asce_limit;
 
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			goto check_asce_limit;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		goto check_asce_limit;
 
 	info.length = len;
 	info.low_limit = mm->mmap_base;
@@ -123,7 +128,6 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad
 					     unsigned long len, unsigned long pgoff,
 					     unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
 	struct vm_unmapped_area_info info = {};
 
@@ -135,13 +139,9 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad
 		goto check_asce_limit;
 
 	/* requesting a specific address */
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
-				(!vma || addr + len <= vm_start_gap(vma)))
-			goto check_asce_limit;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		goto check_asce_limit;
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-- 
2.47.0.338.g60cca15819-goog



From vt at altlinux.org  Mon Dec  9 18:51:27 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Tue, 10 Dec 2024 05:51:27 +0300
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction:
 0000000002000000 [#1] SMP
In-Reply-To: <20241206205602.7phcrxqsv4c6oul4@altlinux.org>
References: <20241202153618.GA6834@willie-the-truck>
 <86ttbmt71k.wl-maz@kernel.org>
 <20241202155940.p267a3tz5ypj4sog@altlinux.org>
 <86ser6t6fs.wl-maz@kernel.org>
 <20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
 <20241203092721.j473dthkbq6wzez7@altlinux.org>
 <1847e34fa7724d28aeb22d93752f64f2@huawei.com>
 <20241203221453.mwh6sozyczi4ec2k@altlinux.org>
 <87jzcfsuep.wl-maz@kernel.org>
 <20241206205602.7phcrxqsv4c6oul4@altlinux.org>
Message-ID: <20241210025127.jmkcpw7ixu4r7hxl@altlinux.org>

On Fri, Dec 06, 2024 at 11:56:02PM +0300, Vitaly Chikunov wrote:
> On Wed, Dec 04, 2024 at 08:51:26AM +0000, Marc Zyngier wrote:
> > On Tue, 03 Dec 2024 22:14:53 +0000,
> > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > On Tue, Dec 03, 2024 at 10:03:11AM +0000, Shameerali Kolothum Thodi wrote:
> > 
> > Mark has described what the problem is likely to be. 6.6-stable needs
> > to have 6685f5d572c22e10 backported, and it probably should have been
> > Cc: to stable. Can you please apply the following patch to your *host*
> > machine and retest?
> 
> We tested the host with this patch applied over 6.6.63 and 6.13-rc1
> guest does not Oops anymore.
> 
> I'd suggest this is also get backported to 6.12.y branch.

Please, can someone backport this patch to v6.12 and send to stable? This
would be really useful to have this fixed and it's noted this is a
critical bug.

Thanks,

> 
> Thanks,
> 
> > 
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index 370a1a7bd369..258a39bcd3c7 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -1330,6 +1330,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
> >  			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
> >  
> >  		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
> > +		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MPAM_frac);
> >  		break;
> >  	case SYS_ID_AA64ISAR1_EL1:
> >  		if (!vcpu_has_ptrauth(vcpu))
> > @@ -1472,6 +1473,13 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> >  
> >  	val &= ~ID_AA64PFR0_EL1_AMU_MASK;
> >  
> > +	/*
> > +	 * MPAM is disabled by default as KVM also needs a set of PARTID to
> > +	 * program the MPAMVPMx_EL2 PARTID remapping registers with. But some
> > +	 * older kernels let the guest see the ID bit.
> > +	 */
> > +	val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
> > +
> >  	return val;
> >  }
> >  
> > @@ -1560,6 +1568,29 @@ static int set_id_dfr0_el1(struct kvm_vcpu *vcpu,
> >  	return set_id_reg(vcpu, rd, val);
> >  }
> >  
> > +static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> > +			       const struct sys_reg_desc *rd, u64 user_val)
> > +{
> > +	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> > +	u64 mpam_mask = ID_AA64PFR0_EL1_MPAM_MASK;
> > +
> > +	/*
> > +	 * Commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits
> > +	 * in ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to
> > +	 * guests, but didn't add trap handling. KVM doesn't support MPAM and
> > +	 * always returns an UNDEF for these registers. The guest must see 0
> > +	 * for this field.
> > +	 *
> > +	 * But KVM must also accept values from user-space that were provided
> > +	 * by KVM. On CPUs that support MPAM, permit user-space to write
> > +	 * the sanitizied value to ID_AA64PFR0_EL1.MPAM, but ignore this field.
> > +	 */
> > +	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
> > +		user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
> > +
> > +	return set_id_reg(vcpu, rd, user_val);
> > +}
> > +
> >  /*
> >   * cpufeature ID register user accessors
> >   *
> > @@ -2018,7 +2049,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> >  	{ SYS_DESC(SYS_ID_AA64PFR0_EL1),
> >  	  .access = access_id_reg,
> >  	  .get_user = get_id_reg,
> > -	  .set_user = set_id_reg,
> > +	  .set_user = set_id_aa64pfr0_el1,
> >  	  .reset = read_sanitised_id_aa64pfr0_el1,
> >  	  .val = ID_AA64PFR0_EL1_CSV2_MASK | ID_AA64PFR0_EL1_CSV3_MASK, },
> >  	ID_SANITISED(ID_AA64PFR1_EL1),
> > 


From quic_jiegan at quicinc.com  Mon Dec  9 19:15:44 2024
From: quic_jiegan at quicinc.com (Jie Gan)
Date: Tue, 10 Dec 2024 11:15:44 +0800
Subject: [PATCH v7 5/5] arm64: dts: qcom: Add CTCU and ETR nodes for SA8775p
In-Reply-To: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
References: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
Message-ID: <20241210031545.3468561-6-quic_jiegan@quicinc.com>

Add CTCU and ETR nodes in DT to enable related functions.

Signed-off-by: Jie Gan <quic_jiegan at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sa8775p.dtsi | 153 ++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
index 368bcf7c9802..05acf93cf8e2 100644
--- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi
+++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
@@ -2412,6 +2412,35 @@ crypto: crypto at 1dfa000 {
 			interconnect-names = "memory";
 		};
 
+		ctcu at 4001000 {
+			compatible = "qcom,sa8775p-ctcu";
+			reg = <0x0 0x04001000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					ctcu_in0: endpoint {
+						remote-endpoint = <&etr0_out>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					ctcu_in1: endpoint {
+						remote-endpoint = <&etr1_out>;
+					};
+				};
+			};
+		};
+
 		stm: stm at 4002000 {
 			compatible = "arm,coresight-stm", "arm,primecell";
 			reg = <0x0 0x4002000 0x0 0x1000>,
@@ -2615,6 +2644,122 @@ qdss_funnel_in1: endpoint {
 			};
 		};
 
+		replicator at 4046000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x04046000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					qdss_rep_in: endpoint {
+						remote-endpoint = <&swao_rep_out0>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					qdss_rep_out0: endpoint {
+						remote-endpoint = <&etr_rep_in>;
+					};
+				};
+			};
+		};
+
+		tmc_etr: tmc at 4048000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x04048000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			iommus = <&apps_smmu 0x04c0 0x00>;
+
+			arm,scatter-gather;
+
+			in-ports {
+				port {
+					etr0_in: endpoint {
+						remote-endpoint = <&etr_rep_out0>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					etr0_out: endpoint {
+						remote-endpoint = <&ctcu_in0>;
+					};
+				};
+			};
+		};
+
+		replicator at 404e000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x0404e000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					etr_rep_in: endpoint {
+						remote-endpoint = <&qdss_rep_out0>;
+					};
+				};
+			};
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					etr_rep_out0: endpoint {
+						remote-endpoint = <&etr0_in>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					etr_rep_out1: endpoint {
+						remote-endpoint = <&etr1_in>;
+					};
+				};
+			};
+		};
+
+		tmc_etr1: tmc at 404f000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x0404f000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			iommus = <&apps_smmu 0x04a0 0x40>;
+
+			arm,scatter-gather;
+			arm,buffer-size = <0x400000>;
+
+			in-ports {
+				port {
+					etr1_in: endpoint {
+						remote-endpoint = <&etr_rep_out1>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					etr1_out: endpoint {
+						remote-endpoint = <&ctcu_in1>;
+					};
+				};
+			};
+		};
+
 		funnel at 4b04000 {
 			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
 			reg = <0x0 0x4b04000 0x0 0x1000>;
@@ -2690,6 +2835,14 @@ out-ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
 
+				port at 0 {
+					reg = <0>;
+
+					swao_rep_out0: endpoint {
+						remote-endpoint = <&qdss_rep_in>;
+					};
+				};
+
 				port at 1 {
 					reg = <1>;
 					swao_rep_out1: endpoint {
-- 
2.34.1



From quic_jiegan at quicinc.com  Mon Dec  9 19:15:41 2024
From: quic_jiegan at quicinc.com (Jie Gan)
Date: Tue, 10 Dec 2024 11:15:41 +0800
Subject: [PATCH v7 2/5] Coresight: Add trace_id function to retrieving the trace ID
In-Reply-To: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
References: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
Message-ID: <20241210031545.3468561-3-quic_jiegan@quicinc.com>

Add 'trace_id' function pointer in ops. It's responsible for
retrieving the device's trace ID.

Add 'struct cs_sink_data' to store the data that is needed by
coresight_enable_path/coresight_disable_path. The structure
will be transmitted to the helper and sink device to enable
related funcationalities.

Signed-off-by: Jie Gan <quic_jiegan at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-core.c  | 59 +++++++++++++++----
 drivers/hwtracing/coresight/coresight-etb10.c |  3 +-
 .../hwtracing/coresight/coresight-etm-perf.c  | 37 ++++++++++--
 .../coresight/coresight-etm3x-core.c          | 30 ++++++++++
 .../coresight/coresight-etm4x-core.c          | 29 +++++++++
 drivers/hwtracing/coresight/coresight-priv.h  | 13 +++-
 drivers/hwtracing/coresight/coresight-stm.c   | 22 +++++++
 drivers/hwtracing/coresight/coresight-sysfs.c | 24 +++++++-
 .../hwtracing/coresight/coresight-tmc-etf.c   |  3 +-
 .../hwtracing/coresight/coresight-tmc-etr.c   |  6 +-
 drivers/hwtracing/coresight/coresight-tpda.c  | 20 +++++++
 drivers/hwtracing/coresight/coresight-trbe.c  |  4 +-
 drivers/hwtracing/coresight/ultrasoc-smb.c    |  3 +-
 include/linux/coresight.h                     |  6 ++
 14 files changed, 234 insertions(+), 25 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index ea38ecf26fcb..ac5dd4a43798 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -23,6 +23,7 @@
 #include "coresight-etm-perf.h"
 #include "coresight-priv.h"
 #include "coresight-syscfg.h"
+#include "coresight-trace-id.h"
 
 /*
  * Mutex used to lock all sysfs enable and disable actions and loading and
@@ -297,12 +298,12 @@ static int coresight_enable_helper(struct coresight_device *csdev,
 	return helper_ops(csdev)->enable(csdev, mode, data);
 }
 
-static void coresight_disable_helper(struct coresight_device *csdev)
+static void coresight_disable_helper(struct coresight_device *csdev, void *data)
 {
-	helper_ops(csdev)->disable(csdev, NULL);
+	helper_ops(csdev)->disable(csdev, data);
 }
 
-static void coresight_disable_helpers(struct coresight_device *csdev)
+static void coresight_disable_helpers(struct coresight_device *csdev, void *data)
 {
 	int i;
 	struct coresight_device *helper;
@@ -310,7 +311,7 @@ static void coresight_disable_helpers(struct coresight_device *csdev)
 	for (i = 0; i < csdev->pdata->nr_outconns; ++i) {
 		helper = csdev->pdata->out_conns[i]->dest_dev;
 		if (helper && coresight_is_helper(helper))
-			coresight_disable_helper(helper);
+			coresight_disable_helper(helper, data);
 	}
 }
 
@@ -327,7 +328,7 @@ static void coresight_disable_helpers(struct coresight_device *csdev)
 void coresight_disable_source(struct coresight_device *csdev, void *data)
 {
 	source_ops(csdev)->disable(csdev, data);
-	coresight_disable_helpers(csdev);
+	coresight_disable_helpers(csdev, NULL);
 }
 EXPORT_SYMBOL_GPL(coresight_disable_source);
 
@@ -337,7 +338,8 @@ EXPORT_SYMBOL_GPL(coresight_disable_source);
  * disabled.
  */
 static void coresight_disable_path_from(struct list_head *path,
-					struct coresight_node *nd)
+					struct coresight_node *nd,
+					void *sink_data)
 {
 	u32 type;
 	struct coresight_device *csdev, *parent, *child;
@@ -382,13 +384,13 @@ static void coresight_disable_path_from(struct list_head *path,
 		}
 
 		/* Disable all helpers adjacent along the path last */
-		coresight_disable_helpers(csdev);
+		coresight_disable_helpers(csdev, sink_data);
 	}
 }
 
-void coresight_disable_path(struct list_head *path)
+void coresight_disable_path(struct list_head *path, void *sink_data)
 {
-	coresight_disable_path_from(path, NULL);
+	coresight_disable_path_from(path, NULL, sink_data);
 }
 EXPORT_SYMBOL_GPL(coresight_disable_path);
 
@@ -468,10 +470,47 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
 out:
 	return ret;
 err:
-	coresight_disable_path_from(path, nd);
+	coresight_disable_path_from(path, nd, sink_data);
 	goto out;
 }
 
+int coresight_read_traceid(struct list_head *path, enum cs_mode mode,
+			   struct coresight_trace_id_map *id_map)
+{
+	int trace_id, type;
+	struct coresight_device *csdev;
+	struct coresight_node *nd;
+
+	list_for_each_entry(nd, path, link) {
+		csdev = nd->csdev;
+		type = csdev->type;
+
+		switch (type) {
+		case CORESIGHT_DEV_TYPE_SOURCE:
+			if (source_ops(csdev)->trace_id != NULL) {
+				trace_id = source_ops(csdev)->trace_id(csdev,
+								       mode,
+								       id_map);
+				if (IS_VALID_CS_TRACE_ID(trace_id))
+					goto out;
+			}
+			break;
+		case CORESIGHT_DEV_TYPE_LINK:
+			if (link_ops(csdev)->trace_id != NULL) {
+				trace_id = link_ops(csdev)->trace_id(csdev);
+				if (IS_VALID_CS_TRACE_ID(trace_id))
+					goto out;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	return -EINVAL;
+out:
+	return trace_id;
+}
+
 struct coresight_device *coresight_get_sink(struct list_head *path)
 {
 	struct coresight_device *csdev;
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index aea9ac9c4bd0..904b5531c256 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -173,7 +173,8 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
 	pid_t pid;
 	unsigned long flags;
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct perf_output_handle *handle = data;
+	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
+	struct perf_output_handle *handle = sink_data->handle;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index ad6a8f4b70b6..e676edd42ddc 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -459,6 +459,7 @@ static void etm_event_start(struct perf_event *event, int flags)
 	struct perf_output_handle *handle = &ctxt->handle;
 	struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
 	struct list_head *path;
+	struct cs_sink_data *sink_data = NULL;
 	u64 hw_id;
 	u8 trace_id;
 
@@ -498,9 +499,20 @@ static void etm_event_start(struct perf_event *event, int flags)
 	if (WARN_ON_ONCE(!sink))
 		goto fail_end_stop;
 
+	sink_data = kzalloc(sizeof(*sink_data), GFP_KERNEL);
+	if (!sink_data)
+		goto fail_end_stop;
+
+	sink_data->sink = sink;
+	sink_data->traceid = coresight_read_traceid(path, CS_MODE_PERF,
+						    &sink->perf_sink_id_map);
+	sink_data->handle = handle;
+
 	/* Nothing will happen without a path */
-	if (coresight_enable_path(path, CS_MODE_PERF, handle))
+	if (coresight_enable_path(path, CS_MODE_PERF, sink_data)) {
+		kfree(sink_data);
 		goto fail_end_stop;
+	}
 
 	/* Finally enable the tracer */
 	if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF,
@@ -526,6 +538,7 @@ static void etm_event_start(struct perf_event *event, int flags)
 		perf_report_aux_output_id(event, hw_id);
 	}
 
+	kfree(sink_data);
 out:
 	/* Tell the perf core the event is alive */
 	event->hw.state = 0;
@@ -534,7 +547,8 @@ static void etm_event_start(struct perf_event *event, int flags)
 	return;
 
 fail_disable_path:
-	coresight_disable_path(path);
+	coresight_disable_path(path, sink_data);
+	kfree(sink_data);
 fail_end_stop:
 	/*
 	 * Check if the handle is still associated with the event,
@@ -559,6 +573,7 @@ static void etm_event_stop(struct perf_event *event, int mode)
 	struct perf_output_handle *handle = &ctxt->handle;
 	struct etm_event_data *event_data;
 	struct list_head *path;
+	struct cs_sink_data *sink_data = NULL;
 
 	/*
 	 * If we still have access to the event_data via handle,
@@ -603,6 +618,10 @@ static void etm_event_stop(struct perf_event *event, int mode)
 	if (!sink)
 		return;
 
+	sink_data = kzalloc(sizeof(*sink_data), GFP_KERNEL);
+	if (!sink_data)
+		return;
+
 	/* stop tracer */
 	coresight_disable_source(csdev, event);
 
@@ -616,12 +635,16 @@ static void etm_event_stop(struct perf_event *event, int mode)
 	 * have to do anything here.
 	 */
 	if (handle->event && (mode & PERF_EF_UPDATE)) {
-		if (WARN_ON_ONCE(handle->event != event))
+		if (WARN_ON_ONCE(handle->event != event)) {
+			kfree(sink_data);
 			return;
+		}
 
 		/* update trace information */
-		if (!sink_ops(sink)->update_buffer)
+		if (!sink_ops(sink)->update_buffer) {
+			kfree(sink_data);
 			return;
+		}
 
 		size = sink_ops(sink)->update_buffer(sink, handle,
 					      event_data->snk_config);
@@ -642,8 +665,12 @@ static void etm_event_stop(struct perf_event *event, int mode)
 			WARN_ON(size);
 	}
 
+	sink_data->sink = sink;
+	sink_data->traceid = coresight_read_traceid(path, CS_MODE_PERF,
+						    &sink->perf_sink_id_map);
 	/* Disabling the path make its elements available to other sessions */
-	coresight_disable_path(path);
+	coresight_disable_path(path, sink_data);
+	kfree(sink_data);
 }
 
 static int etm_event_add(struct perf_event *event, int mode)
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index c103f4c70f5d..0f095fab7e0a 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -697,10 +697,40 @@ static void etm_disable(struct coresight_device *csdev,
 		coresight_set_mode(csdev, CS_MODE_DISABLED);
 }
 
+static int etm_trace_id(struct coresight_device *csdev,
+			enum cs_mode mode,
+			struct coresight_trace_id_map *id_map)
+{
+	int trace_id;
+	struct etm_drvdata *drvdata;
+
+	if (csdev == NULL)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	switch (mode) {
+	case CS_MODE_SYSFS:
+		trace_id = etm_read_alloc_trace_id(drvdata);
+		break;
+	case CS_MODE_PERF:
+		trace_id = coresight_trace_id_read_cpu_id_map(drvdata->cpu, id_map);
+		if (IS_VALID_CS_TRACE_ID(trace_id))
+			drvdata->traceid = (u8)trace_id;
+		break;
+	default:
+		trace_id = -EINVAL;
+		break;
+	}
+
+	return trace_id;
+}
+
+
 static const struct coresight_ops_source etm_source_ops = {
 	.cpu_id		= etm_cpu_id,
 	.enable		= etm_enable,
 	.disable	= etm_disable,
+	.trace_id	= etm_trace_id,
 };
 
 static const struct coresight_ops etm_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index dd8c74f893db..bac9ea371688 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -1025,10 +1025,39 @@ static void etm4_disable(struct coresight_device *csdev,
 		coresight_set_mode(csdev, CS_MODE_DISABLED);
 }
 
+static int etm4_trace_id(struct coresight_device *csdev,
+			 enum cs_mode mode,
+			 struct coresight_trace_id_map *id_map)
+{
+	int trace_id;
+	struct etmv4_drvdata *drvdata;
+
+	if (csdev == NULL)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	switch (mode) {
+	case CS_MODE_SYSFS:
+		trace_id = etm4_read_alloc_trace_id(drvdata);
+		break;
+	case CS_MODE_PERF:
+		trace_id = coresight_trace_id_read_cpu_id_map(drvdata->cpu, id_map);
+		if (IS_VALID_CS_TRACE_ID(trace_id))
+			drvdata->trcid = (u8)trace_id;
+		break;
+	default:
+		trace_id = -EINVAL;
+		break;
+	}
+
+	return trace_id;
+}
+
 static const struct coresight_ops_source etm4_source_ops = {
 	.cpu_id		= etm4_cpu_id,
 	.enable		= etm4_enable,
 	.disable	= etm4_disable,
+	.trace_id	= etm4_trace_id,
 };
 
 static const struct coresight_ops etm4_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 05f891ca6b5c..6a95a3ba9339 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -105,6 +105,15 @@ struct cs_buffers {
 	void			**data_pages;
 };
 
+/**
+ * struct cs_sink_data - data used by coresight_enable_path/coresight_disable_path
+ */
+struct cs_sink_data {
+	struct perf_output_handle	*handle;
+	struct coresight_device		*sink;
+	u8				traceid;
+};
+
 static inline void coresight_insert_barrier_packet(void *buf)
 {
 	if (buf)
@@ -129,9 +138,11 @@ static inline void CS_UNLOCK(void __iomem *addr)
 	} while (0);
 }
 
-void coresight_disable_path(struct list_head *path);
+void coresight_disable_path(struct list_head *path, void *sink_data);
 int coresight_enable_path(struct list_head *path, enum cs_mode mode,
 			  void *sink_data);
+int coresight_read_traceid(struct list_head *path, enum cs_mode mode,
+			   struct coresight_trace_id_map *id_map);
 struct coresight_device *coresight_get_sink(struct list_head *path);
 struct coresight_device *coresight_get_sink_by_id(u32 id);
 struct coresight_device *
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index b581a30a1cd9..5709eda77d9b 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -281,9 +281,31 @@ static void stm_disable(struct coresight_device *csdev,
 	}
 }
 
+static int stm_trace_id(struct coresight_device *csdev,
+			enum cs_mode mode,
+			struct coresight_trace_id_map *id_map)
+{
+	int trace_id;
+	struct stm_drvdata *drvdata;
+
+	if (csdev == NULL)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	trace_id = drvdata->traceid;
+	if (!IS_VALID_CS_TRACE_ID(trace_id)) {
+		trace_id = coresight_trace_id_get_system_id();
+		if (IS_VALID_CS_TRACE_ID(trace_id))
+			drvdata->traceid = (u8)trace_id;
+	}
+
+	return trace_id;
+}
+
 static const struct coresight_ops_source stm_source_ops = {
 	.enable		= stm_enable,
 	.disable	= stm_disable,
+	.trace_id	= stm_trace_id,
 };
 
 static const struct coresight_ops stm_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
index a01c9e54e2ed..8816bccba374 100644
--- a/drivers/hwtracing/coresight/coresight-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-sysfs.c
@@ -168,6 +168,7 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 	int cpu, ret = 0;
 	struct coresight_device *sink;
 	struct list_head *path;
+	struct cs_sink_data *sink_data;
 	enum coresight_dev_subtype_source subtype;
 	u32 hash;
 
@@ -209,7 +210,14 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 		goto out;
 	}
 
-	ret = coresight_enable_path(path, CS_MODE_SYSFS, NULL);
+	sink_data = kzalloc(sizeof(*sink_data), GFP_KERNEL);
+	if (!sink_data) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	sink_data->traceid = coresight_read_traceid(path, CS_MODE_SYSFS, NULL);
+	sink_data->sink = sink;
+	ret = coresight_enable_path(path, CS_MODE_SYSFS, sink_data);
 	if (ret)
 		goto err_path;
 
@@ -246,15 +254,17 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 		break;
 	}
 
+	kfree(sink_data);
 out:
 	mutex_unlock(&coresight_mutex);
 	return ret;
 
 err_source:
-	coresight_disable_path(path);
+	coresight_disable_path(path, sink_data);
 
 err_path:
 	coresight_release_path(path);
+	kfree(sink_data);
 	goto out;
 }
 EXPORT_SYMBOL_GPL(coresight_enable_sysfs);
@@ -263,6 +273,7 @@ void coresight_disable_sysfs(struct coresight_device *csdev)
 {
 	int cpu, ret;
 	struct list_head *path = NULL;
+	struct cs_sink_data *sink_data = NULL;
 	u32 hash;
 
 	mutex_lock(&coresight_mutex);
@@ -274,6 +285,10 @@ void coresight_disable_sysfs(struct coresight_device *csdev)
 	if (!coresight_disable_source_sysfs(csdev, NULL))
 		goto out;
 
+	sink_data = kzalloc(sizeof(*sink_data), GFP_KERNEL);
+	if (!sink_data)
+		goto out;
+
 	switch (csdev->subtype.source_subtype) {
 	case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
 		cpu = source_ops(csdev)->cpu_id(csdev);
@@ -297,8 +312,11 @@ void coresight_disable_sysfs(struct coresight_device *csdev)
 		break;
 	}
 
-	coresight_disable_path(path);
+	sink_data->sink = coresight_find_activated_sysfs_sink(csdev);
+	sink_data->traceid = coresight_read_traceid(path, CS_MODE_SYSFS, NULL);
+	coresight_disable_path(path, sink_data);
 	coresight_release_path(path);
+	kfree(sink_data);
 
 out:
 	mutex_unlock(&coresight_mutex);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index d4f641cd9de6..7dc536eba3e2 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -250,7 +250,8 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
 	pid_t pid;
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct perf_output_handle *handle = data;
+	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
+	struct perf_output_handle *handle = sink_data->handle;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..90a4058c9959 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1254,7 +1254,8 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
 				   enum cs_mode mode, void *data)
 {
-	struct perf_output_handle *handle = data;
+	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
+	struct perf_output_handle *handle = sink_data->handle;
 	struct etr_perf_buffer *etr_perf;
 
 	switch (mode) {
@@ -1648,7 +1649,8 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 	pid_t pid;
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct perf_output_handle *handle = data;
+	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
+	struct perf_output_handle *handle = sink_data->handle;
 	struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index bfca103f9f84..0f47f85811f4 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -232,9 +232,29 @@ static void tpda_disable(struct coresight_device *csdev,
 	dev_dbg(drvdata->dev, "TPDA inport %d disabled\n", in->dest_port);
 }
 
+static int tpda_trace_id(struct coresight_device *csdev)
+{
+	int trace_id;
+	struct tpda_drvdata *drvdata;
+
+	if (csdev == NULL)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	trace_id = drvdata->atid;
+	if (!IS_VALID_CS_TRACE_ID(trace_id)) {
+		trace_id = coresight_trace_id_get_system_id();
+		if (IS_VALID_CS_TRACE_ID(trace_id))
+			drvdata->atid = (u8)trace_id;
+	}
+
+	return trace_id;
+}
+
 static const struct coresight_ops_link tpda_link_ops = {
 	.enable		= tpda_enable,
 	.disable	= tpda_disable,
+	.trace_id	= tpda_trace_id,
 };
 
 static const struct coresight_ops tpda_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 919804b12a67..6680d3c69906 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -21,6 +21,7 @@
 
 #include "coresight-self-hosted-trace.h"
 #include "coresight-trbe.h"
+#include "coresight-priv.h"
 
 #define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT))
 
@@ -1012,7 +1013,8 @@ static int arm_trbe_enable(struct coresight_device *csdev, enum cs_mode mode,
 {
 	struct trbe_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	struct trbe_cpudata *cpudata = dev_get_drvdata(&csdev->dev);
-	struct perf_output_handle *handle = data;
+	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
+	struct perf_output_handle *handle = sink_data->handle;
 	struct trbe_buf *buf = etm_perf_sink_config(handle);
 
 	WARN_ON(cpudata->cpu != smp_processor_id());
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index dc3c9504dd7c..99e0eb33c01f 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -216,7 +216,8 @@ static void smb_enable_sysfs(struct coresight_device *csdev)
 static int smb_enable_perf(struct coresight_device *csdev, void *data)
 {
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct perf_output_handle *handle = data;
+	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
+	struct perf_output_handle *handle = sink_data->handle;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 	pid_t pid;
 
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 497d2206419d..22b977908f4f 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -363,6 +363,7 @@ struct coresight_ops_sink {
  * Operations available for links.
  * @enable:	enables flow between iport and oport.
  * @disable:	disables flow between iport and oport.
+ * @trace_id:	Collect the traceid.
  */
 struct coresight_ops_link {
 	int (*enable)(struct coresight_device *csdev,
@@ -371,6 +372,7 @@ struct coresight_ops_link {
 	void (*disable)(struct coresight_device *csdev,
 			struct coresight_connection *in,
 			struct coresight_connection *out);
+	int (*trace_id)(struct coresight_device *csdev);
 };
 
 /**
@@ -380,6 +382,7 @@ struct coresight_ops_link {
  *		is associated to.
  * @enable:	enables tracing for a source.
  * @disable:	disables tracing for a source.
+ * @trace_id:	collect the traceid.
  */
 struct coresight_ops_source {
 	int (*cpu_id)(struct coresight_device *csdev);
@@ -387,6 +390,9 @@ struct coresight_ops_source {
 		      enum cs_mode mode, struct coresight_trace_id_map *id_map);
 	void (*disable)(struct coresight_device *csdev,
 			struct perf_event *event);
+	int (*trace_id)(struct coresight_device *csdev,
+			enum cs_mode mode,
+			struct coresight_trace_id_map *id_map);
 };
 
 /**
-- 
2.34.1



From quic_jiegan at quicinc.com  Mon Dec  9 19:15:39 2024
From: quic_jiegan at quicinc.com (Jie Gan)
Date: Tue, 10 Dec 2024 11:15:39 +0800
Subject: [PATCH v7 0/5] Coresight: Add Coresight TMC Control Unit driver
Message-ID: <20241210031545.3468561-1-quic_jiegan@quicinc.com>

The Coresight TMC Control Unit(CTCU) device hosts miscellaneous configuration
registers to control various features related to TMC ETR device.

The CTCU device works as a helper device physically connected to the TMC ETR device.
---------------------------------------------------------
             |ETR0|             |ETR1|
              . \                 / .
              .  \               /  .
              .   \             /   .
              .    \           /    .
---------------------------------------------------
ETR0ATID0-ETR0ATID3     CTCU    ETR1ATID0-ETR1ATID3
---------------------------------------------------
Each ETR has four ATID registers with 128 bits long in total.
e.g. ETR0ATID0-ETR0ATID3 registers are used by ETR0 device.

Based on the trace id which is programed in CTCU ATID register of
specific ETR, trace data with that trace id can get into ETR's buffer
while other trace data gets ignored. The number of CTCU ATID registers
depends on the number of defined TMC ETR devices. For example, two TMC
ETR devices need eight ATID registers. ETR0 with ETR0ATID0-ETR0ATID3
and ETR1 with ETR1ATID0-ETRATID3.

The significant challenge in enabling the data filter function is how
to collect the trace ID of the source device. The introduction of
trace_id callback function addresses this challenge. The callback function
collects trace ID of the device and return it back. The trace ID will be
stored in the structure called cs_sink_data and transmitted to helper
and sink devices.

The cs_sink_data structure is created to address how to transmit
parameters needs by coresight_enable_path/coresight_disbale_path
functions.

Here is an example of the struct cs_sink_data:
struct cs_sink_data {
        struct perf_output_handle  *handle; //used by perf mode
        struct coresight_device    *sink;   //used to retrieve atid_offset
        u32                        traceid; //traceid needed by CTCU
};

The atid_offset mentioned before is the offset to ATID register in CTCU
device.

Enabling the source device will configure one bit in the ATID register based
on its trace ID.
Disabling the source devices will reset the bit in the AITD register
based on its trace ID.

Useage:
Enable:
STM device with trace ID 5 and ETR0 is activated.
Bitmap before the enablement:
ETR0ATID0:
31..................543210
==========================
0000000000000000000000...0
==========================

Bitmap after the enablement:
31..................543210
==========================
0000000000000...0000100000
==========================

The bit 5 of the ETR0ATID0 register is configured to 1 when enabling the
STM device.

Disable:
STM device with trace ID 5 and ETR0 is activated.
Bitmap before the disablement:
ETR0ATID0:
31................6543210
=========================
000000000010111...0100000
=========================

Bitmap after the disablement
ETR0ATID0:
31................6543210
=========================
000000000010111...0000000
=========================

The bit 5 of the ETR0ATID0 register is reset to 0 when disabling the STM
device.

---
Changes in V2:
1. Rename the device to Coresight Control Unit.
2. Introduce the trace_id function pointer to address the challeng how to
   properly collect the trace ID of the device.
3. Introduce a new way to define the qcom,ccu-atid-offset property in
device tree.
4. Disabling the filter function blocked on acquiring the ATID-offset,
   which will be addressed in a separate patch once it?s ready.
Link to V1 - https://lore.kernel.org/lkml/20240618072726.3767974-1-quic_jiegan at quicinc.com/T/#t

Changes in V3:
1. Rename the device to Coresight TMC Control Unit(CTCU).
2. Introduce a new way to define the platform related configs. The new
   structure, qcom_ctcu_config, is used to store configurations specific
   to a platform. Each platform should have its own qcom_ctcu_config structure.
3. In perf mode, the ETM devices allocate their trace IDs using the
   perf_sink_id_map. In sysfs mode, the ETM devices allocate their trace
   IDs using the id_map_default.
4. Considering the scenario where both ETR devices might be enabled simultaneously
   with multiple sources, retrieving and using trace IDs instead of id_map is more effective
   for the CTCU device in sysfs mode. For example, We can configure one ETR as sink for high
   throughput trace data like ETM and another ETR for low throughput trace data like STM.
   In this case, STM data won?t be flushed out by ETM data quickly. However, if we use id_map to
   manage the trace IDs, we need to create a separate id_map for each ETR device. Addtionally, We
   would need to iterate through the entire id_map for each configuration.
5. Add support for apb's clock name "apb". If the function fails to obtain the clock with
   the name "apb_pclk", it will attempt to acquire the clock with the name "apb".
Link to V2 - https://lore.kernel.org/linux-arm-msm/20240705090049.1656986-1-quic_jiegan at quicinc.com/T/#t

Changes in V4:
1. Add TMC description in binding file.
2. Restrict the number of ports for the CTCU device to a range of 0 to 1 in the binding file,
   because the maximum number of CTCU devices is 2 for existing projects.
Link to V3 - https://lore.kernel.org/linux-arm-kernel/20240812024141.2867655-1-quic_jiegan at quicinc.com/

Changes in V5:
1. Fix the format issue for description paragrah in dt binding file.
2. Previous discussion for why use "in-ports" property instead of "ports".
Link to V4 - https://lore.kernel.org/linux-arm-msm/20240828012706.543605-1-quic_jiegan at quicinc.com/

Changes in V6:
1. Collected reviewed-by tag from Rob for dt-binding patch.
2. Rebased on tag next-20241008.
3. Dropped all depends-on tags.
Link to V5 - https://lore.kernel.org/linux-arm-msm/20240909033458.3118238-1-quic_jiegan at quicinc.com/

Changes in V7:
1. Rebased on tag next-20241204.
2. Fix format issue for dts patch.
   - Padding the address part to 8 digits
Link to V6 - https://lore.kernel.org/linux-arm-msm/20241009112503.1851585-1-quic_jiegan at quicinc.com/

Jie Gan (5):
  Coresight: Add support for new APB clock name
  Coresight: Add trace_id function to retrieving the trace ID
  dt-bindings: arm: Add Coresight TMC Control Unit hardware
  Coresight: Add Coresight TMC Control Unit driver
  arm64: dts: qcom: Add CTCU and ETR nodes for SA8775p

 .../bindings/arm/qcom,coresight-ctcu.yaml     |  84 +++++
 arch/arm64/boot/dts/qcom/sa8775p.dtsi         | 153 +++++++++
 drivers/hwtracing/coresight/Kconfig           |   8 +
 drivers/hwtracing/coresight/Makefile          |   1 +
 drivers/hwtracing/coresight/coresight-core.c  |  59 +++-
 drivers/hwtracing/coresight/coresight-ctcu.c  | 292 ++++++++++++++++++
 drivers/hwtracing/coresight/coresight-ctcu.h  |  21 ++
 drivers/hwtracing/coresight/coresight-etb10.c |   3 +-
 .../hwtracing/coresight/coresight-etm-perf.c  |  37 ++-
 .../coresight/coresight-etm3x-core.c          |  30 ++
 .../coresight/coresight-etm4x-core.c          |  29 ++
 drivers/hwtracing/coresight/coresight-priv.h  |  13 +-
 drivers/hwtracing/coresight/coresight-stm.c   |  22 ++
 drivers/hwtracing/coresight/coresight-sysfs.c |  24 +-
 .../hwtracing/coresight/coresight-tmc-etf.c   |   3 +-
 .../hwtracing/coresight/coresight-tmc-etr.c   |   6 +-
 drivers/hwtracing/coresight/coresight-tpda.c  |  20 ++
 drivers/hwtracing/coresight/coresight-trbe.c  |   4 +-
 drivers/hwtracing/coresight/ultrasoc-smb.c    |   3 +-
 include/linux/coresight.h                     |  16 +-
 20 files changed, 800 insertions(+), 28 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
 create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.c
 create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.h

-- 
2.34.1



From quic_jiegan at quicinc.com  Mon Dec  9 19:15:40 2024
From: quic_jiegan at quicinc.com (Jie Gan)
Date: Tue, 10 Dec 2024 11:15:40 +0800
Subject: [PATCH v7 1/5] Coresight: Add support for new APB clock name
In-Reply-To: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
References: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
Message-ID: <20241210031545.3468561-2-quic_jiegan@quicinc.com>

Add support for new APB clock-name. If the function fails
to obtain the clock with the name "apb_pclk", it will
attempt to acquire the clock with the name "apb".

Signed-off-by: Jie Gan <quic_jiegan at quicinc.com>
---
 include/linux/coresight.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index c13342594278..497d2206419d 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -454,8 +454,11 @@ static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
 	int ret;
 
 	pclk = clk_get(dev, "apb_pclk");
-	if (IS_ERR(pclk))
-		return NULL;
+	if (IS_ERR(pclk)) {
+		pclk = clk_get(dev, "apb");
+		if (IS_ERR(pclk))
+			return NULL;
+	}
 
 	ret = clk_prepare_enable(pclk);
 	if (ret) {
-- 
2.34.1



From quic_jiegan at quicinc.com  Mon Dec  9 19:15:42 2024
From: quic_jiegan at quicinc.com (Jie Gan)
Date: Tue, 10 Dec 2024 11:15:42 +0800
Subject: [PATCH v7 3/5] dt-bindings: arm: Add Coresight TMC Control Unit hardware
In-Reply-To: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
References: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
Message-ID: <20241210031545.3468561-4-quic_jiegan@quicinc.com>

Add binding file to specify how to define a Coresight TMC
Control Unit device in device tree.

It is responsible for controlling the data filter function
based on the source device's Trace ID for TMC ETR device.
The trace data with that Trace id can get into ETR's buffer
while other trace data gets ignored.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Jie Gan <quic_jiegan at quicinc.com>
---
 .../bindings/arm/qcom,coresight-ctcu.yaml     | 84 +++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
new file mode 100644
index 000000000000..843b52eaf872
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/qcom,coresight-ctcu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: CoreSight TMC Control Unit
+
+maintainers:
+  - Yuanfang Zhang <quic_yuanfang at quicinc.com>
+  - Mao Jinlong <quic_jinlmao at quicinc.com>
+  - Jie Gan <quic_jiegan at quicinc.com>
+
+description: |
+  The Trace Memory Controller(TMC) is used for Embedded Trace Buffer(ETB),
+  Embedded Trace FIFO(ETF) and Embedded Trace Router(ETR) configurations.
+  The configuration mode (ETB, ETF, ETR) is discovered at boot time when
+  the device is probed.
+
+  The Coresight TMC Control unit controls various Coresight behaviors.
+  It works as a helper device when connected to TMC ETR device.
+  It is responsible for controlling the data filter function based on
+  the source device's Trace ID for TMC ETR device. The trace data with
+  that Trace id can get into ETR's buffer while other trace data gets
+  ignored.
+
+properties:
+  compatible:
+    enum:
+      - qcom,sa8775p-ctcu
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: apb
+
+  in-ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    patternProperties:
+      '^port(@[0-1])?$':
+        description: Input connections from CoreSight Trace bus
+        $ref: /schemas/graph.yaml#/properties/port
+
+required:
+  - compatible
+  - reg
+  - in-ports
+
+additionalProperties: false
+
+examples:
+  - |
+    ctcu at 1001000 {
+        compatible = "qcom,sa8775p-ctcu";
+        reg = <0x1001000 0x1000>;
+
+        clocks = <&aoss_qmp>;
+        clock-names = "apb";
+
+        in-ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+                ctcu_in_port0: endpoint {
+                    remote-endpoint = <&etr0_out_port>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+                ctcu_in_port1: endpoint {
+                    remote-endpoint = <&etr1_out_port>;
+                };
+            };
+        };
+    };
-- 
2.34.1



From quic_jiegan at quicinc.com  Mon Dec  9 19:15:43 2024
From: quic_jiegan at quicinc.com (Jie Gan)
Date: Tue, 10 Dec 2024 11:15:43 +0800
Subject: [PATCH v7 4/5] Coresight: Add Coresight TMC Control Unit driver
In-Reply-To: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
References: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
Message-ID: <20241210031545.3468561-5-quic_jiegan@quicinc.com>

The Coresight TMC Control Unit hosts miscellaneous configuration registers
which control various features related to TMC ETR sink.

Based on the trace ID, which is programmed in the related CTCU ATID
register of a specific ETR, trace data with that trace ID gets into
the ETR buffer, while other trace data gets dropped.

Enabling source device sets one bit of the ATID register based on
source device's trace ID.
Disabling source device resets the bit according to the source
device's trace ID.

Signed-off-by: Jie Gan <quic_jiegan at quicinc.com>
---
 drivers/hwtracing/coresight/Kconfig          |   8 +
 drivers/hwtracing/coresight/Makefile         |   1 +
 drivers/hwtracing/coresight/coresight-ctcu.c | 292 +++++++++++++++++++
 drivers/hwtracing/coresight/coresight-ctcu.h |  21 ++
 include/linux/coresight.h                    |   3 +-
 5 files changed, 324 insertions(+), 1 deletion(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.c
 create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.h

diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 06f0a7594169..152eab0b9b2a 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -133,6 +133,14 @@ config CORESIGHT_STM
 	  To compile this driver as a module, choose M here: the
 	  module will be called coresight-stm.
 
+config CORESIGHT_CTCU
+	tristate "CoreSight TMC Control Unit driver"
+	help
+	  This driver provides support for CoreSight TMC Control Unit
+	  that hosts miscellaneous configuration registers. This is
+	  primarily used for controlling the behaviors of the TMC
+	  ETR device.
+
 config CORESIGHT_CPU_DEBUG
 	tristate "CoreSight CPU Debug driver"
 	depends on ARM || ARM64
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 4ba478211b31..1b7869910a12 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -51,3 +51,4 @@ coresight-cti-y := coresight-cti-core.o	coresight-cti-platform.o \
 		   coresight-cti-sysfs.o
 obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o
 obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o
+obj-$(CONFIG_CORESIGHT_CTCU) += coresight-ctcu.o
diff --git a/drivers/hwtracing/coresight/coresight-ctcu.c b/drivers/hwtracing/coresight/coresight-ctcu.c
new file mode 100644
index 000000000000..e3a8259a2412
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-ctcu.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/coresight.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "coresight-ctcu.h"
+#include "coresight-priv.h"
+#include "coresight-trace-id.h"
+
+DEFINE_CORESIGHT_DEVLIST(ctcu_devs, "ctcu");
+
+#define ctcu_writel(drvdata, val, offset)	__raw_writel((val), drvdata->base + offset)
+#define ctcu_readl(drvdata, offset)		__raw_readl(drvdata->base + offset)
+
+/* The TMC Coresight Control Unit uses four ATID registers to control the data filter function based
+ * on the trace ID for each TMC ETR sink. The length of each ATID register is 32 bits. Therefore,
+ * the ETR has a related field in CTCU that is 128 bits long. Each trace ID is represented by one
+ * bit in that filed.
+ * e.g. ETR0ATID0 layout, set bit 5 for traceid 5
+ *                                           bit5
+ * ------------------------------------------------------
+ * |   |28|   |24|   |20|   |16|   |12|   |8|  1|4|   |0|
+ * ------------------------------------------------------
+ *
+ * e.g. ETR0:
+ * 127                     0 from ATID_offset for ETR0ATID0
+ * -------------------------
+ * |ATID3|ATID2|ATID1|ATID0|
+ *
+ */
+#define CTCU_ATID_REG_OFFSET(traceid, atid_offset) \
+		((traceid / 32) * 4 + atid_offset)
+
+#define CTCU_ATID_REG_BIT(traceid)	(traceid % 32)
+#define CTCU_ATID_REG_SIZE		0x10
+
+struct ctcu_atid_config {
+	const int atid_offset;
+	const int port_num;
+};
+
+struct ctcu_config {
+	const struct ctcu_atid_config *atid_config;
+	int num_atid_config;
+};
+
+static const struct ctcu_atid_config sa8775p_atid_cfgs[] = {
+	{0xf8,  0},
+	{0x108, 1},
+};
+
+static const struct ctcu_config sa8775p_cfgs = {
+	.atid_config		= sa8775p_atid_cfgs,
+	.num_atid_config	= ARRAY_SIZE(sa8775p_atid_cfgs),
+};
+
+/*
+ * __ctcu_set_etr_traceid: Set bit in the ATID register based on trace ID when enable is true.
+ * Reset the bit of the ATID register based on trace ID when enable is false.
+ *
+ * @csdev:	coresight_device struct related to the device
+ * @traceid:	trace ID of the source tracer.
+ * @enable:	True for set bit and false for reset bit.
+ *
+ * Returns 0 indicates success. Non-zero result means failure.
+ */
+static int __ctcu_set_etr_traceid(struct coresight_device *csdev,
+				  u8 traceid,
+				  int port_num,
+				  bool enable)
+{
+	uint32_t atid_offset;
+	struct ctcu_drvdata *drvdata;
+	unsigned long flags;
+	uint32_t reg_offset;
+	int bit;
+	uint32_t val;
+
+	if (!IS_VALID_CS_TRACE_ID(traceid) || port_num < 0)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	if (IS_ERR_OR_NULL(drvdata))
+		return -EINVAL;
+
+	atid_offset = drvdata->atid_offset[port_num];
+	if (atid_offset == 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CS_UNLOCK(drvdata->base);
+
+	reg_offset = CTCU_ATID_REG_OFFSET(traceid, atid_offset);
+	bit = CTCU_ATID_REG_BIT(traceid);
+	if (reg_offset - atid_offset >= CTCU_ATID_REG_SIZE ||
+	    bit >= CORESIGHT_TRACE_IDS_MAX) {
+		CS_LOCK(drvdata);
+		spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+		return -EINVAL;
+	}
+
+	val = ctcu_readl(drvdata, reg_offset);
+	if (enable)
+		val = val | BIT(bit);
+	else
+		val = val & ~BIT(bit);
+	ctcu_writel(drvdata, val, reg_offset);
+
+	CS_LOCK(drvdata->base);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+
+	return 0;
+}
+
+static int ctcu_get_active_port(struct coresight_device *sink, struct coresight_device *helper)
+{
+	int port, i;
+
+	for (i = 0; i < sink->pdata->nr_outconns; ++i) {
+		if (sink->pdata->out_conns[i]->dest_dev) {
+			port = sink->pdata->out_conns[i]->dest_port;
+			return port;
+		}
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * ctcu_set_etr_traceid: Retrieve the ATID offset and trace ID.
+ *
+ * Returns 0 indicates success. None-zero result means failure.
+ */
+static int ctcu_set_etr_traceid(struct coresight_device *csdev,
+				struct cs_sink_data *sink_data,
+				bool enable)
+{
+	int port_num;
+
+	if (!IS_VALID_CS_TRACE_ID(sink_data->traceid) ||
+	    (csdev == NULL) ||
+	    (sink_data->sink == NULL)) {
+		dev_dbg(&csdev->dev, "Invalid parameters\n");
+		return -EINVAL;
+	}
+
+	port_num = ctcu_get_active_port(sink_data->sink, csdev);
+	if (port_num < 0)
+		return -EINVAL;
+
+	dev_dbg(&csdev->dev, "traceid is %d\n", sink_data->traceid);
+
+	return __ctcu_set_etr_traceid(csdev, sink_data->traceid, port_num, enable);
+}
+
+static int ctcu_enable(struct coresight_device *csdev, enum cs_mode mode,
+		       void *data)
+{
+	int ret = 0;
+	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
+
+	ret = ctcu_set_etr_traceid(csdev, sink_data, true);
+	if (ret)
+		dev_dbg(&csdev->dev, "enable data filter failed\n");
+
+	return 0;
+}
+
+static int ctcu_disable(struct coresight_device *csdev, void *data)
+{
+	int ret = 0;
+	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
+
+	ret = ctcu_set_etr_traceid(csdev, sink_data, false);
+	if (ret)
+		dev_dbg(&csdev->dev, "disable data filter failed\n");
+
+	return 0;
+}
+
+static const struct coresight_ops_helper ctcu_helper_ops = {
+	.enable = ctcu_enable,
+	.disable = ctcu_disable,
+};
+
+static const struct coresight_ops ctcu_ops = {
+	.helper_ops = &ctcu_helper_ops,
+};
+
+static int ctcu_probe(struct platform_device *pdev)
+{
+	int i;
+	void __iomem *base;
+	struct device *dev = &pdev->dev;
+	struct coresight_platform_data *pdata;
+	struct ctcu_drvdata *drvdata;
+	struct coresight_desc desc = { 0 };
+	const struct ctcu_config *cfgs;
+	const struct ctcu_atid_config *atid_cfg;
+
+	desc.name = coresight_alloc_device_name(&ctcu_devs, dev);
+	if (!desc.name)
+		return -ENOMEM;
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	pdata = coresight_get_platform_data(dev);
+	if (IS_ERR(pdata))
+		return PTR_ERR(pdata);
+	dev->platform_data = pdata;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+	if (!base)
+		return -ENOMEM;
+
+	drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
+	if (IS_ERR(drvdata->apb_clk))
+		return -ENODEV;
+
+	cfgs = of_device_get_match_data(dev);
+	if (cfgs) {
+		if (cfgs->num_atid_config <= ATID_MAX_NUM) {
+			for (i = 0; i < cfgs->num_atid_config; i++) {
+				atid_cfg = &cfgs->atid_config[i];
+				drvdata->atid_offset[i] = atid_cfg->atid_offset;
+			}
+		}
+	}
+
+	drvdata->base = base;
+	drvdata->dev = dev;
+	platform_set_drvdata(pdev, drvdata);
+
+	desc.type = CORESIGHT_DEV_TYPE_HELPER;
+	desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CTCU;
+	desc.pdata = pdata;
+	desc.dev = dev;
+	desc.ops = &ctcu_ops;
+
+	drvdata->csdev = coresight_register(&desc);
+	if (IS_ERR(drvdata->csdev)) {
+		if (!IS_ERR_OR_NULL(drvdata->apb_clk))
+			clk_put(drvdata->apb_clk);
+
+		return PTR_ERR(drvdata->csdev);
+	}
+
+	return 0;
+}
+
+static void ctcu_remove(struct platform_device *pdev)
+{
+	struct ctcu_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	coresight_unregister(drvdata->csdev);
+	if (!IS_ERR_OR_NULL(drvdata->apb_clk))
+		clk_put(drvdata->apb_clk);
+}
+
+static const struct of_device_id ctcu_match[] = {
+	{.compatible = "qcom,sa8775p-ctcu", .data = &sa8775p_cfgs},
+	{}
+};
+
+static struct platform_driver ctcu_driver = {
+	.probe          = ctcu_probe,
+	.remove         = ctcu_remove,
+	.driver         = {
+		.name   = "coresight-ctcu",
+		.of_match_table = ctcu_match,
+		.suppress_bind_attrs = true,
+	},
+};
+module_platform_driver(ctcu_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CoreSight TMC Control Unit driver");
diff --git a/drivers/hwtracing/coresight/coresight-ctcu.h b/drivers/hwtracing/coresight/coresight-ctcu.h
new file mode 100644
index 000000000000..ce5c9661623a
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-ctcu.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _CORESIGHT_CTCU_H
+#define _CORESIGHT_CTCU_H
+
+#define ATID_MAX_NUM 5
+
+struct ctcu_drvdata {
+	void __iomem		*base;
+	struct clk		*apb_clk;
+	phys_addr_t		pbase;
+	struct device		*dev;
+	struct coresight_device	*csdev;
+	spinlock_t		spin_lock;
+	uint32_t		atid_offset[ATID_MAX_NUM];
+};
+
+#endif
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 22b977908f4f..d92530b3fa57 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -71,7 +71,8 @@ enum coresight_dev_subtype_source {
 
 enum coresight_dev_subtype_helper {
 	CORESIGHT_DEV_SUBTYPE_HELPER_CATU,
-	CORESIGHT_DEV_SUBTYPE_HELPER_ECT_CTI
+	CORESIGHT_DEV_SUBTYPE_HELPER_ECT_CTI,
+	CORESIGHT_DEV_SUBTYPE_HELPER_CTCU
 };
 
 /**
-- 
2.34.1



From shijie at amperemail.onmicrosoft.com  Mon Dec  9 19:22:09 2024
From: shijie at amperemail.onmicrosoft.com (Shijie Huang)
Date: Tue, 10 Dec 2024 11:22:09 +0800
Subject: [PATCH v3 1/2] arm64: refactor the rodata=xxx
In-Reply-To: <83d01335-c6be-d17b-511a-378ce3ad0663@gentwo.org>
References: <20241209072020.4743-1-shijie@os.amperecomputing.com>
 <20241209072020.4743-2-shijie@os.amperecomputing.com>
 <83d01335-c6be-d17b-511a-378ce3ad0663@gentwo.org>
Message-ID: <7e89f00b-0b7a-4ef6-90e6-bb5f1b7946e2@amperemail.onmicrosoft.com>


On 2024/12/10 1:05, Christoph Lameter (Ampere) wrote:
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -5901,7 +5901,7 @@
>>   	rodata=		[KNL,EARLY]
>>   		on	Mark read-only kernel memory as read-only (default).
>>   		off	Leave read-only kernel memory writable for debugging.
>> -		full	Mark read-only kernel memory and aliases as read-only
>> +		noalias	Use more block mappings,may have better performance.
>>   		        [arm64]
> Maybe use
> 		noalias Do not check aliases in order to allow larger kernel page
>                          sizes on a platforms without FEAT_BBM2 support[arm64])
>
> instead?

The "rodata=noalias" here is equal to original "rodata=on".

But Yang Shi's patch set works with original "rodata=full" :

https://lists.infradead.org/pipermail/linux-arm-kernel/2024-November/979770.html


IMHO, it's not proper to mention the FEAT_BBM in "rodata=noalias".



Thanks

Huang Shijie





From anshuman.khandual at arm.com  Mon Dec  9 19:25:14 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 08:55:14 +0530
Subject: [PATCH] mm/execmem: Make ARCH_WANTS_EXECMEM_LATE depend on
 EXECMEM
In-Reply-To: <Z1ckOoPMSXfNdrXd@arm.com>
References: <20241209031251.515903-1-anshuman.khandual@arm.com>
 <202412092048.tTzJ5szH-lkp@intel.com>
 <f492ac51-9dad-4b18-8cd4-81dc236b3162@arm.com> <Z1ckOoPMSXfNdrXd@arm.com>
Message-ID: <c17a45b9-a3a2-4f9d-8243-399f65fc1a52@arm.com>



On 12/9/24 22:39, Catalin Marinas wrote:
> On Mon, Dec 09, 2024 at 07:43:32PM +0530, Anshuman Khandual wrote:
>> On 12/9/24 18:06, kernel test robot wrote:
>>> kernel test robot noticed the following build warnings:
>>>
>>> [auto build test WARNING on akpm-mm/mm-everything]
>>>
>>> url:    https://github.com/intel-lab-lkp/linux/commits/Anshuman-Khandual/mm-execmem-Make-ARCH_WANTS_EXECMEM_LATE-depend-on-EXECMEM/20241209-111533
>>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
>>> patch link:    https://lore.kernel.org/r/20241209031251.515903-1-anshuman.khandual%40arm.com
>>> patch subject: [PATCH] mm/execmem: Make ARCH_WANTS_EXECMEM_LATE depend on EXECMEM
>>> config: arm64-kismet-CONFIG_ARCH_WANTS_EXECMEM_LATE-CONFIG_ARM64-0-0 (https://download.01.org/0day-ci/archive/20241209/202412092048.tTzJ5szH-lkp at intel.com/config)
>>> reproduce: (https://download.01.org/0day-ci/archive/20241209/202412092048.tTzJ5szH-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/202412092048.tTzJ5szH-lkp at intel.com/
>>>
>>> kismet warnings: (new ones prefixed by >>)
>>>>> kismet: WARNING: unmet direct dependencies detected for ARCH_WANTS_EXECMEM_LATE when selected by ARM64
>>>    WARNING: unmet direct dependencies detected for ARCH_WANTS_EXECMEM_LATE
>>>      Depends on [n]: EXECMEM [=n]
>>>      Selected by [y]:
>>>      - ARM64 [=y]
>>
>> Although above mentioned config here has CONFIG_ARCH_WANTS_EXECMEM_LATE=y
>> and CONFIG_EXECMEM=n (actually absent), could that really happen though ?
>>
>> Tried making CONFIG_EXECMEM=n (rather deselecting) but that did now allow
>> setting CONFIG_EXECMEM=n, it always remained set. Reverting this patch i.e
>> the current behaviour is also the same (CONFIG_EXECMEM always remains set).
>>
>> select ARCH_WANTS_EXECMEM_LATE if EXECMEM
>>
>> Above statement seems to be selecting EXECMEM as well but the intent seems
>> to be a dependency check instead! OR arch selection for a config brings in
>> all its dependencies as well.
>>
>> If the selection is always, should this change be like the following ?
>>
>> config ARCH_WANTS_EXECMEM_LATE
>>  	bool
>> 	selects EXECMEM
> 
> This is wrong. What ARCH_WANTS_EXECMEM_LATE means is that, _if_ EXECMEM
> is enabled, the arch code require its late initialisation. Currently for

Which implies that even if ARCH_WANTS_EXECMEM_LATE is only applicable when
EXECMEM is enabled, there is no real dependence on the later for platforms
that need a certain init behaviour.

> arm64 EXECMEM is selected by KPROBES, BPF_JIT and MODULES. So if you

EXECMEM gets enabled from the above, not via ARCH_WANTS_EXECMEM_LATE as I
had anticipated earlier.

> don't have any of these on, you don't need EXECMEM either, no point in
> selecting it above just because arm64 wants a specific behaviour (late
> initialisation) for EXECMEM.

Right, specific behaviour preference for a function on a platform should
not necessarily pull in that function itself.

> 
> If you do want a patch for this, I think for arm64 we simply need to
> select ARCH_WANTS_EXECMEM_LATE unconditionally. Not much use in having
> any dependencies really, it just adds to the clutter. And don't change
> the core Kconfig either.

Sure, will do.


From shy828301 at gmail.com  Mon Dec  9 19:27:04 2024
From: shy828301 at gmail.com (Yang Shi)
Date: Mon, 9 Dec 2024 19:27:04 -0800
Subject: [PATCH mm-unstable 01/17] mm: Introduce generic_mmap_hint()
In-Reply-To: <20241210024119.2488608-2-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com> <20241210024119.2488608-2-kaleshsingh@google.com>
Message-ID: <CAHbLzkpCRGF+-WXkHVEutkEGHSWydmpb1CwkvHZRTH-f773J-w@mail.gmail.com>

On Mon, Dec 9, 2024 at 6:41?PM Kalesh Singh <kaleshsingh at google.com> wrote:
>
> Consolidate the hint searches from both direcitons (topdown and
> bottomup) into generic_mmap_hint().
>
> No functional change is introduced.
>
> Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
> ---
>  include/linux/sched/mm.h |  4 ++++
>  mm/mmap.c                | 45 ++++++++++++++++++++++++----------------
>  2 files changed, 31 insertions(+), 18 deletions(-)
>
> diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
> index 928a626725e6..edeec19d1708 100644
> --- a/include/linux/sched/mm.h
> +++ b/include/linux/sched/mm.h
> @@ -201,6 +201,10 @@ unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm,
>                                            unsigned long flags,
>                                            vm_flags_t vm_flags);
>
> +unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
> +                               unsigned long len, unsigned long pgoff,
> +                               unsigned long flags);
> +
>  unsigned long
>  generic_get_unmapped_area(struct file *filp, unsigned long addr,
>                           unsigned long len, unsigned long pgoff,
> diff --git a/mm/mmap.c b/mm/mmap.c
> index df9154b15ef9..e97eb8bf4889 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -620,6 +620,27 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)
>         return addr;
>  }
>
> +unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
> +                               unsigned long len, unsigned long pgoff,
> +                               unsigned long flags)
> +{
> +       struct mm_struct *mm = current->mm;
> +       struct vm_area_struct *vma, *prev;
> +       const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
> +
> +       if (!addr)
> +               return 0;
> +
> +       addr = PAGE_ALIGN(addr);
> +       vma = find_vma_prev(mm, addr, &prev);
> +       if (mmap_end - len >= addr && addr >= mmap_min_addr &&
> +           (!vma || addr + len <= vm_start_gap(vma)) &&
> +           (!prev || addr >= vm_end_gap(prev)))
> +               return addr;
> +
> +       return 0;
> +}
> +
>  /* Get an address range which is currently unmapped.
>   * For shmat() with addr=0.
>   *
> @@ -637,7 +658,6 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
>                           unsigned long flags, vm_flags_t vm_flags)
>  {
>         struct mm_struct *mm = current->mm;
> -       struct vm_area_struct *vma, *prev;
>         struct vm_unmapped_area_info info = {};
>         const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
>
> @@ -647,14 +667,9 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
>         if (flags & MAP_FIXED)
>                 return addr;

It seems you also can move the MAP_FIXED case into generic_mmap_hint(), right?

>
> -       if (addr) {
> -               addr = PAGE_ALIGN(addr);
> -               vma = find_vma_prev(mm, addr, &prev);
> -               if (mmap_end - len >= addr && addr >= mmap_min_addr &&
> -                   (!vma || addr + len <= vm_start_gap(vma)) &&
> -                   (!prev || addr >= vm_end_gap(prev)))
> -                       return addr;
> -       }
> +       addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
> +       if (addr)
> +               return addr;
>
>         info.length = len;
>         info.low_limit = mm->mmap_base;
> @@ -685,7 +700,6 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
>                                   unsigned long len, unsigned long pgoff,
>                                   unsigned long flags, vm_flags_t vm_flags)
>  {
> -       struct vm_area_struct *vma, *prev;
>         struct mm_struct *mm = current->mm;
>         struct vm_unmapped_area_info info = {};
>         const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
> @@ -698,14 +712,9 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
>                 return addr;
>
>         /* requesting a specific address */
> -       if (addr) {
> -               addr = PAGE_ALIGN(addr);
> -               vma = find_vma_prev(mm, addr, &prev);
> -               if (mmap_end - len >= addr && addr >= mmap_min_addr &&
> -                               (!vma || addr + len <= vm_start_gap(vma)) &&
> -                               (!prev || addr >= vm_end_gap(prev)))
> -                       return addr;
> -       }
> +       addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
> +       if (addr)
> +               return addr;
>
>         info.flags = VM_UNMAPPED_AREA_TOPDOWN;
>         info.length = len;
> --
> 2.47.0.338.g60cca15819-goog
>
>


From jason-jh.lin at mediatek.com  Mon Dec  9 19:28:20 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Tue, 10 Dec 2024 11:28:20 +0800
Subject: [PATCH v3] drm/mediatek: Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb()
Message-ID: <20241210032820.10958-1-jason-jh.lin@mediatek.com>

mtk_crtc_finish_page_flip() is used to notify userspace that a
page flip has been completed, allowing userspace to free the frame
buffer of the last frame and commit the next frame.

In MediaTek's hardware design for configuring display hardware by using
GCE, `DRM_EVENT_FLIP_COMPLETE` should be notified to userspace after
GCE has finished configuring all display hardware settings for each
atomic_commit().

Currently, mtk_crtc_finish_page_flip() cannot guarantee that GCE has
configured all the display hardware settings of the last frame.
Therefore, to increase the accuracy of the timing for notifying
`DRM_EVENT_FLIP_COMPLETE` to userspace, mtk_crtc_finish_page_flip()
should be moved to ddp_cmdq_cb().

Fixes: 7f82d9c43879 ("drm/mediatek: Clear pending flag when cmdq packet is done")
Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_crtc.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
index eb0e1233ad04..dabc2f8086b6 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
@@ -109,9 +109,14 @@ static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc)
 static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
 {
 	unsigned long flags;
+	struct drm_crtc *crtc = &mtk_crtc->base;
+	struct mtk_drm_private *priv = crtc->dev->dev_private;
 
 	drm_crtc_handle_vblank(&mtk_crtc->base);
 
+	if (!priv->data->shadow_register)
+		return;
+
 	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
 	if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
 		mtk_crtc_finish_page_flip(mtk_crtc);
@@ -284,10 +289,8 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 	state = to_mtk_crtc_state(mtk_crtc->base.state);
 
 	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
-	if (mtk_crtc->config_updating) {
-		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+	if (mtk_crtc->config_updating)
 		goto ddp_cmdq_cb_out;
-	}
 
 	state->pending_config = false;
 
@@ -315,10 +318,15 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 		mtk_crtc->pending_async_planes = false;
 	}
 
-	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
-
 ddp_cmdq_cb_out:
 
+	if (mtk_crtc->pending_needs_vblank) {
+		mtk_crtc_finish_page_flip(mtk_crtc);
+		mtk_crtc->pending_needs_vblank = false;
+	}
+
+	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+
 	mtk_crtc->cmdq_vblank_cnt = 0;
 	wake_up(&mtk_crtc->cb_blocking_queue);
 }
@@ -584,6 +592,10 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
 		mtk_mutex_acquire(mtk_crtc->mutex);
 		mtk_crtc_ddp_config(crtc, NULL);
 		mtk_mutex_release(mtk_crtc->mutex);
+
+		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
+		mtk_crtc->config_updating = false;
+		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
 	}
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (mtk_crtc->cmdq_client.chan) {
@@ -606,13 +618,14 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
 		 */
 		mtk_crtc->cmdq_vblank_cnt = 3;
 
+		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
+		mtk_crtc->config_updating = false;
+		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+
 		mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
 		mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
 	}
 #endif
-	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
-	mtk_crtc->config_updating = false;
-	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
 
 	mutex_unlock(&mtk_crtc->hw_lock);
 }
-- 
2.43.0



From ck.hu at mediatek.com  Mon Dec  9 19:28:39 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 10 Dec 2024 03:28:39 +0000
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
Message-ID: <631fdcdfd44e0d401e62df67acc206b0762248c7.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit and that also poses a slight
> difference between the V2 and V1 controllers in how they handle
> Hotplug Detection (HPD).
> 
> While the v1 controller was using the CEC controller to check
> HDMI cable connection and disconnection, in this driver the v2
> one does not.
> 
> This is due to the fact that on parts with v2 designs, like the
> MT8195 SoC, there is one CEC controller shared between the HDMI
> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> adding support to use the CEC HW to wake up the HDMI controllers
> it is necessary to have support for one TX, one RX *and* for both
> at the same time.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
> +                                     struct drm_bridge_state *old_state)
> +{
> +       struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +       struct drm_atomic_state *state = old_state->base.state;
> +       int ret;
> +
> +       ret = drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
> +       if (ret)
> +               dev_err(hdmi->dev, "Could not update infoframes: %d\n", ret);
> +
> +       mtk_hdmi_v2_hw_vid_mute(hdmi, false);
> +       mtk_hdmi_v2_hw_aud_mute(hdmi, false);

In v1, it does not unmute when bridge enable.
I would like v1 and v2 has the same behavior.
If possible, remove these code.
If remove thee code would result in some problem,
add comment to describe why need these code.

Regards,
CK

> +
> +       /* signal the connect event to audio codec */
> +       mtk_hdmi_v2_handle_plugged_change(hdmi, true);
> +
> +       hdmi->enabled = true;
> +}
> +


From shy828301 at gmail.com  Mon Dec  9 19:37:27 2024
From: shy828301 at gmail.com (Yang Shi)
Date: Mon, 9 Dec 2024 19:37:27 -0800
Subject: [PATCH mm-unstable 17/17] mm: Respect mmap hint before THP
 alignment if allocation is possible
In-Reply-To: <20241210024119.2488608-18-kaleshsingh@google.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com> <20241210024119.2488608-18-kaleshsingh@google.com>
Message-ID: <CAHbLzkq2SNaqzx4d981H2QfQvtObS3X0pPL8=oqFsFbMditWPA@mail.gmail.com>

On Mon, Dec 9, 2024 at 6:45?PM Kalesh Singh <kaleshsingh at google.com> wrote:
>
> Commit 249608ee4713 ("mm: respect mmap hint address when aligning for THP")
> fallsback to PAGE_SIZE alignment instead of THP alignment
> for anonymous mapping as long as a hint address is provided by the user
> -- even if we weren't able to allocate the unmapped area at the hint
> address in the end.
>
> This was done to address the immediate regression in anonymous mappings
> where the hint address were being ignored in some cases; due to commit
> efa7df3e3bb5 ("mm: align larger anonymous mappings on THP boundaries").
>
> It was later pointed out that this issue also existed for file-backed
> mappings from file systems that use thp_get_unmapped_area() for their
> .get_unmapped_area() file operation.
>
> The same fix was not applied for file-backed mappings since it would
> mean any mmap requests that provide a hint address would be only
> PAGE_SIZE-aligned regardless of whether allocation was successful at
> the hint address or not.
>
> Instead, use arch_mmap_hint() to first attempt allocation at the hint
> address and fallback to THP alignment if that fails.

Thanks for taking time to try to fix this.

>
> Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
> ---
>  mm/huge_memory.c | 15 ++++++++-------
>  mm/mmap.c        |  1 -
>  2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 137abeda8602..f070c89dafc9 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -1097,6 +1097,14 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
>         loff_t off_align = round_up(off, size);
>         unsigned long len_pad, ret, off_sub;
>
> +       /*
> +        * If allocation at the address hint succeeds; respect the hint and
> +        * don't try to align to THP boundary.
> +        */
> +       addr = arch_mmap_hint(filp, addr, len, off, flags);
> +       if (addr)
> +               return addr;
> +

IIUC, arch_mmap_hint() will be called in arch_get_unmapped_area() and
arch_get_unmapped_area_topdown() again. So we will actually look up
maple tree twice. It sounds like the second hint address search is
pointless. You should be able to set addr to 0 before calling
mm_get_unmapped_area_vmflags() in order to skip the second hint
address search.

>         if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall())
>                 return 0;
>
> @@ -1117,13 +1125,6 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
>         if (IS_ERR_VALUE(ret))
>                 return 0;
>
> -       /*
> -        * Do not try to align to THP boundary if allocation at the address
> -        * hint succeeds.
> -        */
> -       if (ret == addr)
> -               return addr;
> -
>         off_sub = (off - ret) & (size - 1);
>
>         if (test_bit(MMF_TOPDOWN, &current->mm->flags) && !off_sub)
> diff --git a/mm/mmap.c b/mm/mmap.c
> index 59bf7d127aa1..6bfeec80152a 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -807,7 +807,6 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
>         if (get_area) {
>                 addr = get_area(file, addr, len, pgoff, flags);
>         } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && !file
> -                  && !addr /* no hint */
>                    && IS_ALIGNED(len, PMD_SIZE)) {
>                 /* Ensures that larger anonymous mappings are THP aligned. */
>                 addr = thp_get_unmapped_area_vmflags(file, addr, len,
> --
> 2.47.0.338.g60cca15819-goog
>
>


From xiaolei.wang at windriver.com  Mon Dec  9 19:42:23 2024
From: xiaolei.wang at windriver.com (Xiaolei Wang)
Date: Tue, 10 Dec 2024 11:42:23 +0800
Subject: [PATCH v2] serial: imx: Use uart_port_lock_irq() instead of uart_port_lock()
Message-ID: <20241210034223.1493522-1-xiaolei.wang@windriver.com>

When executing 'ehco mem > /sys/power/state', the following
deadlock occurs. Since there is output during the serial
port entering the suspend process, the suspend will be
interrupted, resulting in the nesting of locks. Therefore,
use uart_port_lock_irq() instead of uart_port_unlock().

WARNING: inconsistent lock state
6.12.0-rc2-00002-g3c199ed5bd64-dirty #23 Not tainted
--------------------------------
inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
sh/494 [HC0[0]:SC0[0]:HE1:SE1] takes:
c4db5850 (&port_lock_key){?.-.}-{3:3}, at: imx_uart_enable_wakeup+0x14/0x254
{IN-HARDIRQ-W} state was registered at:
  lock_acquire+0x104/0x348
  _raw_spin_lock+0x48/0x84
  imx_uart_int+0x14/0x4dc
  __handle_irq_event_percpu+0xac/0x2fc
  handle_irq_event_percpu+0xc/0x40
  handle_irq_event+0x38/0x8c
  handle_fasteoi_irq+0xb4/0x1b8
  handle_irq_desc+0x1c/0x2c
  gic_handle_irq+0x6c/0xa0
  generic_handle_arch_irq+0x2c/0x64
  call_with_stack+0x18/0x20
  __irq_svc+0x9c/0xbc
  _raw_spin_unlock_irqrestore+0x2c/0x48
  uart_write+0xd8/0x3a0
  do_output_char+0x1a8/0x1e4
  n_tty_write+0x224/0x440
  file_tty_write.constprop.0+0x124/0x250
  do_iter_readv_writev+0x100/0x1e0
  vfs_writev+0xc4/0x448
  do_writev+0x68/0xf8
  ret_fast_syscall+0x0/0x1c
irq event stamp: 31593
hardirqs last  enabled at (31593): [<c1150e48>] _raw_spin_unlock_irqrestore+0x44/0x48
hardirqs last disabled at (31592): [<c07f32f0>] clk_enable_lock+0x60/0x120
softirqs last  enabled at (30334): [<c012d1d4>] handle_softirqs+0x2cc/0x478
softirqs last disabled at (30325): [<c012d510>] __irq_exit_rcu+0x120/0x15c

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&port_lock_key);
  <Interrupt>
    lock(&port_lock_key);

Fixes: 3c199ed5bd64 ("serial: imx: Grab port lock in imx_uart_enable_wakeup()")
Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>
---

v1:
  https://patchwork.kernel.org/project/linux-arm-kernel/patch/20241209124732.693834-1-xiaolei.wang at windriver.com/
v2:
  use uart_port_lock_irq() instead of uart_port_lock_irqsave()

 drivers/tty/serial/imx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 17f70e4bee43..9c59ec128bb4 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2692,7 +2692,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
 {
 	u32 ucr3;
 
-	uart_port_lock(&sport->port);
+	uart_port_lock_irq(&sport->port);
 
 	ucr3 = imx_uart_readl(sport, UCR3);
 	if (on) {
@@ -2714,7 +2714,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
 		imx_uart_writel(sport, ucr1, UCR1);
 	}
 
-	uart_port_unlock(&sport->port);
+	uart_port_unlock_irq(&sport->port);
 }
 
 static int imx_uart_suspend_noirq(struct device *dev)
-- 
2.25.1



From wenst at chromium.org  Mon Dec  9 20:16:13 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 10 Dec 2024 12:16:13 +0800
Subject: [PATCH] ASoC: mediatek: mt8188: Enable apll1 clock during reg rw
 to prevent hang
In-Reply-To: <108d4187-26af-43f6-8b1e-0e48516524a4@notapiano>
References: <20241203-mt8188-afe-fix-hang-disabled-apll1-clk-v1-1-07cdd7760834@collabora.com>
 <a10dbdf265194e77a69b6e40afa3df9636b3ab14.camel@mediatek.com>
 <a70a0521-985d-43a4-a1fa-36eb733d5ca9@collabora.com> <1d2ee55dde84bcab6f777525042c6789b9f2c1fc.camel@mediatek.com>
 <108d4187-26af-43f6-8b1e-0e48516524a4@notapiano>
Message-ID: <CAGXv+5Gi30-GSy_D+DHS_wz-A3F4qxuc7-6KpfBQ-iJwr3POtQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 4:08?AM N?colas F. R. A. Prado
<nfraprado at collabora.com> wrote:
>
> On Fri, Dec 06, 2024 at 06:57:00AM +0000, Trevor Wu (???) wrote:
> > On Thu, 2024-12-05 at 13:51 +0100, AngeloGioacchino Del Regno wrote:
> > >
> > >
> > > Il 04/12/24 13:17, Trevor Wu (???) ha scritto:
> > > > On Tue, 2024-12-03 at 17:07 -0300, N?colas F. R. A. Prado wrote:
> > > >
> > > > >
> > > > > Currently, booting the Genio 700 EVK board with the MT8188 sound
> > > > > platform driver configured as a module (CONFIG_SND_SOC_MT8188=m)
> > > > > results
> > > > > in a system hang right when the HW registers for the audio
> > > > > controller
> > > > > are read:
> > > > >
> > > > >    mt8188-audio 10b10000.audio-controller: No cache defaults,
> > > > > reading
> > > > > back from HW
> > > > >
> > > > > The hang doesn't occur with the driver configured as builtin as
> > > > > then
> > > > > the
> > > > > unused clocks are still enabled.
> > > > >
> > > > > Enable the apll1 clock during register read/write to prevent the
> > > > > hang.
> > > > >
> > > > > Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> > > > > ---
> > > > >   sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 4 ++++
> > > > >   1 file changed, 4 insertions(+)
> > > > >
> > > > > diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > > b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > > index
> > > > > e69c1bb2cb239596dee50b166c20192d5408be10..fb8cf286df3f02ac076528b
> > > > > 898f
> > > > > d0d7a708ec1ea 100644
> > > > > --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > > +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > > @@ -587,6 +587,8 @@ int mt8188_afe_enable_reg_rw_clk(struct
> > > > > mtk_base_afe *afe)
> > > > >          mt8188_afe_enable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_A1SYS_HP]);
> > > > >
> > > > >          mt8188_afe_enable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_A1SYS]);
> > > > >
> > > > > +       mt8188_afe_enable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_APMIXED_APLL1]);
> > > > >
> > > > > +
> > > > >          return 0;
> > > > >   }
> > > >
> > > > Hi Nicolas,
> > > >
> > > > If I understand correctly, APLL1 should be the parent clock of
> > > > AUD_A1SYS_HP and AUD_A1SYS, so it should be enabled automatically
> > > > by
> > > > CCF.
> > > >
> > > > I'm not sure why you resolved the hang issue after enabling APLL1.
> > > > Could you share more details about the solution?
> > > >
> > >
> > > Hmm. Now I see what's happening here...
> > >
> > > Nicolas, Trevor,
> > >
> > > Possible parents for top_a1sys_hp are:
> > >   - clk26m
> > >   - apll1_d4
> > >
> > > ...what's happening here most probably is that after the clock gets
> > > disabled as
> > > unused, it gets parented to clk26m by default as that is parent index
> > > 0... and
> > > something else in AFE needs APLL1 to feed a clock to .. something ..
> > > to allow
> > > register access.
> > >
> > > Trevor, do you know why is this IP unaccessible when A1SYS is
> > > parented to clk26m?
> >
> > Hi Angelo,
> >
> > As far as I know, it should work even though the clock is parented to
> > clk26m.
> >
> > Unfortunately, I have no idea about why APLL1 enabling can resolve the
> > hang issue. I'm also curious about how Nicolas found the solution to
> > resolve the problem.
> >
> > From the description, it seems that the problem is related to register
> > r/w hang. If I remembered correctly, when the mtcmos of ADSP_INFRA is
> > ON, register r/w won't cause the cpu to hang. However, ADSP_INFRA has
> > been configured as ALWAYS_ON in the driver. I'm not sure if it doesn't
> > work correctly when the driver is configured as a module. Maybe Nicolas
> > can also check this.
>
> Indeed, as suggested by Angelo, adding
>
>   assigned-clocks = <&topckgen CLK_TOP_A1SYS_HP>;
>   assigned-clock-parents = <&topckgen CLK_TOP_APLL1_D4>;
>
> to the afe node also fixes this issue.
>
> In mt8188.dtsi, we currently have
>
>   afe: audio-controller at 10b10000 {
>         ...
>         assigned-clocks = <&topckgen CLK_TOP_A1SYS_HP>;
>         assigned-clock-parents =  <&clk26m>;
>
> So the question is, do other MT8188 platforms need clk26m to be the parent of
> a1sys_hp? Depending on that I can either update the parent on the common
> mt8188.dtsi or on the genio700-evk.dts, which is where I observed the issue. I
> don't have access to other mt8188 platforms. Trevor, do you know?
>
> As for how I identified this issue, I noticed that when booting with the
> platform driver as a module the system would hang, and that passing
> clk_ignore_unused avoided the issue. Then I selectively ignored some unused
> clocks until I narrowed down to ignoring unused only the apll1 clock, meaning
> the apll1 clock needed to be left on during the platform driver probe for the
> system to not hang.

I don't know. The AFE driver supposedly enables all clocks that are
required for register access on runtime PM resume using
mt8188_afe_enable_reg_rw_clk().

Maybe try enabling debug printk in sound/soc/mediatek/mt8188/mt8188-afe-clk.c
and see what that gives you? There are already debug messages around the
clk enable/disable calls.

Either there's a bug or incorrect description of the clock tree,
or the AFE device node is referencing the wrong clocks.


ChenYu

> Thanks,
> N?colas
>
> >
> > Thanks,
> > Trevor
> >
> > >
> > > That might give Nicolas a definitive hint about how to resolve this
> > > issue.
> > >
> > > Cheers,
> > > Angelo
> > >
> > > > Thanks,
> > > > Trevor
> > > >
> > > > >
> > > > > @@ -594,6 +596,8 @@ int mt8188_afe_disable_reg_rw_clk(struct
> > > > > mtk_base_afe *afe)
> > > > >   {
> > > > >          struct mt8188_afe_private *afe_priv = afe-
> > > > > >platform_priv;
> > > > >
> > > > > +       mt8188_afe_disable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_APMIXED_APLL1]);
> > > > >
> > > > > +
> > > > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_A1SYS]);
> > > > >
> > > > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_A1SYS_HP]);
> > > > >
> > > > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_AFE]);
> > > > >
> > > > > ---
> > > > > base-commit: b852e1e7a0389ed6168ef1d38eb0bad71a6b11e8
> > > > > change-id: 20241203-mt8188-afe-fix-hang-disabled-apll1-clk-
> > > > > b3c11782cbaf
> > > > >
> > > > > Best regards,
> > > > > --
> > > > > N?colas F. R. A. Prado <nfraprado at collabora.com>
> > > > >
> > > > >
> > >
> > >
>


From anshuman.khandual at arm.com  Mon Dec  9 20:32:57 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 10:02:57 +0530
Subject: [PATCH v2] arm64/Kconfig: Drop EXECMEM dependency from ARCH_WANTS_EXECMEM_LATE
Message-ID: <20241210043257.715822-1-anshuman.khandual@arm.com>

ARCH_WANTS_EXECMEM_LATE indicates subscribing platform's preference for
EXECMEM late initialisation without creating a new dependency. Hence this
just drops EXECMEM dependency while selecting ARCH_WANTS_EXECMEM_LATE.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: linux-arm-kernel at lists.infradead.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 patch applies on v6.13-rc1

Changes in V2:

- Dropped generic EXECMEM config changes per Catalin
- Updated the commit message as required

Changes in V1:

https://lore.kernel.org/all/20241209031251.515903-1-anshuman.khandual at arm.com/

 arch/arm64/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5479c8b454c..b146372bc365 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -113,7 +113,7 @@ config ARM64
 	select ARCH_WANT_FRAME_POINTERS
 	select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
 	select ARCH_WANT_LD_ORPHAN_WARN
-	select ARCH_WANTS_EXECMEM_LATE if EXECMEM
+	select ARCH_WANTS_EXECMEM_LATE
 	select ARCH_WANTS_NO_INSTR
 	select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
 	select ARCH_HAS_UBSAN
-- 
2.30.2



From hchauhan at ventanamicro.com  Mon Dec  9 20:51:38 2024
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Tue, 10 Dec 2024 10:21:38 +0530
Subject: [PATCH v3 2/4] riscv: add support for SBI Supervisor Software
 Events extension
In-Reply-To: <20241206163102.843505-3-cleger@rivosinc.com>
References: <20241206163102.843505-1-cleger@rivosinc.com>
 <20241206163102.843505-3-cleger@rivosinc.com>
Message-ID: <CDD40494-D31E-46E5-89C6-0B2A50C1B953@ventanamicro.com>

Hi Clement,

> On 6 Dec 2024, at 22:00, Cl?ment L?ger <cleger at rivosinc.com> wrote:
> 
> The SBI SSE extension allows the supervisor software to be notified by
> the SBI of specific events that are not maskable. The context switch is
> handled partially by the firmware which will save registers a6 and a7.
> When entering kernel we can rely on these 2 registers to setup the stack
> and save all the registers.
> 
> Since SSE events can be delivered at any time to the kernel (including
> during exception handling, we need a way to locate the current_task for
> context tracking. On RISC-V, it is sotred in scratch when in user space
> or tp when in kernel space (in which case SSCRATCH is zero). But at a
> at the beginning of exception handling, SSCRATCH is used to swap tp and
> check the origin of the exception. If interrupted at that point, then,
> there is no way to reliably know were is located the current
> task_struct. Even checking the interruption location won't work as SSE
> event can be nested on top of each other so the original interruption
> site might be lost at some point. In order to retrieve it reliably,
> store the current task in an additionnal __sse_entry_task per_cpu array.
> This array is then used to retrieve the current task based on the
> hart ID that is passed to the SSE event handler in a6.
> 
> That being said, the way the current task struct is stored should
> probably be reworked to find a better reliable alternative.
> 
> Since each events (and each CPU for local events) have their own
> context and can preempt each other, allocate a stack (and a shadow stack
> if needed for each of them (and for each cpu for local events).
> 
> When completing the event, if we were coming from kernel with interrupts
> disabled, simply return there. If coming from userspace or kernel with
> interrupts enabled, simulate an interrupt exception by setting IE_SIE in
> CSR_IP to allow delivery of signals to user task. For instance this can
> happen, when a RAS event has been generated by a user application and a
> SIGBUS has been sent to a task.
> 
> Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
> ---
> arch/riscv/include/asm/asm.h         |  14 ++-
> arch/riscv/include/asm/scs.h         |   7 ++
> arch/riscv/include/asm/sse.h         |  38 ++++++
> arch/riscv/include/asm/switch_to.h   |  14 +++
> arch/riscv/include/asm/thread_info.h |   1 +
> arch/riscv/kernel/Makefile           |   1 +
> arch/riscv/kernel/asm-offsets.c      |  12 ++
> arch/riscv/kernel/sse.c              | 134 +++++++++++++++++++++
> arch/riscv/kernel/sse_entry.S        | 171 +++++++++++++++++++++++++++
> 9 files changed, 389 insertions(+), 3 deletions(-)
> create mode 100644 arch/riscv/include/asm/sse.h
> create mode 100644 arch/riscv/kernel/sse.c
> create mode 100644 arch/riscv/kernel/sse_entry.S
> 
> diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
> index 776354895b81..de8427c58f02 100644
> --- a/arch/riscv/include/asm/asm.h
> +++ b/arch/riscv/include/asm/asm.h
> @@ -89,16 +89,24 @@
> #define PER_CPU_OFFSET_SHIFT 3
> #endif
> 
> -.macro asm_per_cpu dst sym tmp
> - REG_L \tmp, TASK_TI_CPU_NUM(tp)
> - slli  \tmp, \tmp, PER_CPU_OFFSET_SHIFT
> +.macro asm_per_cpu_with_cpu dst sym tmp cpu
> + slli  \tmp, \cpu, PER_CPU_OFFSET_SHIFT
> la    \dst, __per_cpu_offset
> add   \dst, \dst, \tmp
> REG_L \tmp, 0(\dst)
> la    \dst, \sym
> add   \dst, \dst, \tmp
> .endm
> +
> +.macro asm_per_cpu dst sym tmp
> + REG_L \tmp, TASK_TI_CPU_NUM(tp)
> + asm_per_cpu_with_cpu \dst \sym \tmp \tmp
> +.endm
> #else /* CONFIG_SMP */
> +.macro asm_per_cpu_with_cpu dst sym tmp cpu
> + la    \dst, \sym
> +.endm
> +
> .macro asm_per_cpu dst sym tmp
> la    \dst, \sym
> .endm
> diff --git a/arch/riscv/include/asm/scs.h b/arch/riscv/include/asm/scs.h
> index 0e45db78b24b..62344daad73d 100644
> --- a/arch/riscv/include/asm/scs.h
> +++ b/arch/riscv/include/asm/scs.h
> @@ -18,6 +18,11 @@
> load_per_cpu gp, irq_shadow_call_stack_ptr, \tmp
> .endm
> 
> +/* Load the per-CPU IRQ shadow call stack to gp. */
> +.macro scs_load_sse_stack reg_evt
> + REG_L gp, SSE_REG_EVT_SHADOW_STACK(\reg_evt)
> +.endm
> +
> /* Load task_scs_sp(current) to gp. */
> .macro scs_load_current
> REG_L gp, TASK_TI_SCS_SP(tp)
> @@ -41,6 +46,8 @@
> .endm
> .macro scs_load_irq_stack tmp
> .endm
> +.macro scs_load_sse_stack reg_evt
> +.endm
> .macro scs_load_current
> .endm
> .macro scs_load_current_if_task_changed prev
> diff --git a/arch/riscv/include/asm/sse.h b/arch/riscv/include/asm/sse.h
> new file mode 100644
> index 000000000000..431a19d4cd9c
> --- /dev/null
> +++ b/arch/riscv/include/asm/sse.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2024 Rivos Inc.
> + */
> +#ifndef __ASM_SSE_H
> +#define __ASM_SSE_H
> +
> +#ifdef CONFIG_RISCV_SSE
> +
> +struct sse_event_interrupted_state {
> + unsigned long a6;
> + unsigned long a7;
> +};
> +
> +struct sse_event_arch_data {
> + void *stack;
> + void *shadow_stack;
> + unsigned long tmp;
> + struct sse_event_interrupted_state interrupted;
> + unsigned long interrupted_state_phys;
> + u32 evt_id;
> +};
> +
> +struct sse_registered_event;
> +int arch_sse_init_event(struct sse_event_arch_data *arch_evt, u32 evt_id,
> + int cpu);
> +void arch_sse_free_event(struct sse_event_arch_data *arch_evt);
> +int arch_sse_register_event(struct sse_event_arch_data *arch_evt);
> +
> +void sse_handle_event(struct sse_event_arch_data *arch_evt,
> +      struct pt_regs *regs);
> +asmlinkage void handle_sse(void);
> +asmlinkage void do_sse(struct sse_event_arch_data *arch_evt,
> + struct pt_regs *reg);
> +
> +#endif
> +
> +#endif
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index 94e33216b2d9..e166fabe04ab 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -88,6 +88,19 @@ static inline void __switch_to_envcfg(struct task_struct *next)
> :: "r" (next->thread.envcfg) : "memory");
> }
> 
> +#ifdef CONFIG_RISCV_SSE
> +DECLARE_PER_CPU(struct task_struct *, __sse_entry_task);
> +
> +static inline void __switch_sse_entry_task(struct task_struct *next)
> +{
> + __this_cpu_write(__sse_entry_task, next);
> +}
> +#else
> +static inline void __switch_sse_entry_task(struct task_struct *next)
> +{
> +}
> +#endif
> +
> extern struct task_struct *__switch_to(struct task_struct *,
>       struct task_struct *);
> 
> @@ -122,6 +135,7 @@ do { \
> if (switch_to_should_flush_icache(__next)) \
> local_flush_icache_all(); \
> __switch_to_envcfg(__next); \
> + __switch_sse_entry_task(__next); \
> ((last) = __switch_to(__prev, __next)); \
> } while (0)
> 
> diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
> index f5916a70879a..28e9805e61fc 100644
> --- a/arch/riscv/include/asm/thread_info.h
> +++ b/arch/riscv/include/asm/thread_info.h
> @@ -36,6 +36,7 @@
> #define OVERFLOW_STACK_SIZE     SZ_4K
> 
> #define IRQ_STACK_SIZE THREAD_SIZE
> +#define SSE_STACK_SIZE THREAD_SIZE
> 
> #ifndef __ASSEMBLY__
> 
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 063d1faf5a53..1e8fb83b1162 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -99,6 +99,7 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o
> obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
> obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o
> obj-$(CONFIG_RISCV_SBI) += sbi.o sbi_ecall.o
> +obj-$(CONFIG_RISCV_SSE) += sse.o sse_entry.o
> ifeq ($(CONFIG_RISCV_SBI), y)
> obj-$(CONFIG_SMP) += sbi-ipi.o
> obj-$(CONFIG_SMP) += cpu_ops_sbi.o
> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> index e89455a6a0e5..60590a3d9519 100644
> --- a/arch/riscv/kernel/asm-offsets.c
> +++ b/arch/riscv/kernel/asm-offsets.c
> @@ -14,6 +14,8 @@
> #include <asm/ptrace.h>
> #include <asm/cpu_ops_sbi.h>
> #include <asm/stacktrace.h>
> +#include <asm/sbi.h>
> +#include <asm/sse.h>
> #include <asm/suspend.h>
> 
> void asm_offsets(void);
> @@ -511,4 +513,14 @@ void asm_offsets(void)
> DEFINE(FREGS_A6,    offsetof(struct __arch_ftrace_regs, a6));
> DEFINE(FREGS_A7,    offsetof(struct __arch_ftrace_regs, a7));
> #endif
> +
> +#ifdef CONFIG_RISCV_SSE
> + OFFSET(SSE_REG_EVT_STACK, sse_event_arch_data, stack);
> + OFFSET(SSE_REG_EVT_SHADOW_STACK, sse_event_arch_data, shadow_stack);
> + OFFSET(SSE_REG_EVT_TMP, sse_event_arch_data, tmp);
> +
> + DEFINE(SBI_EXT_SSE, SBI_EXT_SSE);
> + DEFINE(SBI_SSE_EVENT_COMPLETE, SBI_SSE_EVENT_COMPLETE);
> + DEFINE(NR_CPUS, NR_CPUS);
> +#endif
> }
> diff --git a/arch/riscv/kernel/sse.c b/arch/riscv/kernel/sse.c
> new file mode 100644
> index 000000000000..b48ae69dad8d
> --- /dev/null
> +++ b/arch/riscv/kernel/sse.c
> @@ -0,0 +1,134 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2024 Rivos Inc.
> + */
> +#include <linux/nmi.h>
> +#include <linux/scs.h>
> +#include <linux/bitfield.h>
> +#include <linux/riscv_sse.h>
> +#include <linux/percpu-defs.h>
> +
> +#include <asm/asm-prototypes.h>
> +#include <asm/switch_to.h>
> +#include <asm/irq_stack.h>
> +#include <asm/sbi.h>
> +#include <asm/sse.h>
> +
> +DEFINE_PER_CPU(struct task_struct *, __sse_entry_task);
> +
> +void __weak sse_handle_event(struct sse_event_arch_data *arch_evt, struct pt_regs *regs)
> +{
> +}
> +
> +void do_sse(struct sse_event_arch_data *arch_evt, struct pt_regs *regs)
> +{
> + nmi_enter();
> +
> + /* Retrieve missing GPRs from SBI */
> + sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_ATTR_READ, arch_evt->evt_id,
> +  SBI_SSE_ATTR_INTERRUPTED_A6,
> +  (SBI_SSE_ATTR_INTERRUPTED_A7 - SBI_SSE_ATTR_INTERRUPTED_A6) + 1,
> +  arch_evt->interrupted_state_phys, 0, 0);
> +
> + memcpy(&regs->a6, &arch_evt->interrupted, sizeof(arch_evt->interrupted));
> +
> + sse_handle_event(arch_evt, regs);
> +
> + /*
> + * The SSE delivery path does not uses the "standard" exception path and
> + * thus does not process any pending signal/softirqs. Some drivers might
> + * enqueue pending work that needs to be handled as soon as possible.
> + * For that purpose, set the software interrupt pending bit which will
> + * be serviced once interrupts are reenabled
> + */
> + csr_set(CSR_IP, IE_SIE);
> +
> + nmi_exit();
> +}
> +
> +#ifdef CONFIG_VMAP_STACK
> +static unsigned long *sse_stack_alloc(unsigned int cpu, unsigned int size)
> +{
> + return arch_alloc_vmap_stack(size, cpu_to_node(cpu));
> +}
> +
> +static void sse_stack_free(unsigned long *stack)
> +{
> + vfree(stack);
> +}
> +#else /* CONFIG_VMAP_STACK */
> +
> +static unsigned long *sse_stack_alloc(unsigned int cpu, unsigned int size)
> +{
> + return kmalloc(size, GFP_KERNEL);
> +}
> +
> +static void sse_stack_free(unsigned long *stack)
> +{
> + kfree(stack);
> +}
> +
> +#endif /* CONFIG_VMAP_STACK */
> +
> +static int sse_init_scs(int cpu, struct sse_event_arch_data *arch_evt)
> +{
> + void *stack;
> +
> + if (!scs_is_enabled())
> + return 0;
> +
> + stack = scs_alloc(cpu_to_node(cpu));
> + if (!stack)
> + return 1;
> +
> + arch_evt->shadow_stack = stack;
> +
> + return 0;
> +}
> +
> +int arch_sse_init_event(struct sse_event_arch_data *arch_evt, u32 evt_id, int cpu)
> +{
> + void *stack;
> +
> + arch_evt->evt_id = evt_id;
> + stack = sse_stack_alloc(cpu, SSE_STACK_SIZE);
> + if (!stack)
> + return -ENOMEM;
> +
> + arch_evt->stack = stack + SSE_STACK_SIZE;
> +
> + if (sse_init_scs(cpu, arch_evt))
> + goto free_stack;
> +
> + if (is_kernel_percpu_address((unsigned long)&arch_evt->interrupted)) {
> + arch_evt->interrupted_state_phys =
> + per_cpu_ptr_to_phys(&arch_evt->interrupted);
> + } else {
> + arch_evt->interrupted_state_phys =
> + virt_to_phys(&arch_evt->interrupted);
> + }
> +
> + return 0;
> +
> +free_stack:
> + sse_stack_free(arch_evt->stack - SSE_STACK_SIZE);
> +
> + return -ENOMEM;
> +}
> +
> +void arch_sse_free_event(struct sse_event_arch_data *arch_evt)
> +{
> + scs_free(arch_evt->shadow_stack);
> + sse_stack_free(arch_evt->stack - SSE_STACK_SIZE);
> +}
> +
> +int arch_sse_register_event(struct sse_event_arch_data *arch_evt)
> +{
> + struct sbiret sret;
> +
> + sret = sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_REGISTER, arch_evt->evt_id,
> + (unsigned long) handle_sse, (unsigned long) arch_evt,
> + 0, 0, 0);
> +
> + return sbi_err_map_linux_errno(sret.error);
> +}
> diff --git a/arch/riscv/kernel/sse_entry.S b/arch/riscv/kernel/sse_entry.S
> new file mode 100644
> index 000000000000..0b2f890edd89
> --- /dev/null
> +++ b/arch/riscv/kernel/sse_entry.S
> @@ -0,0 +1,171 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2024 Rivos Inc.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/linkage.h>
> +
> +#include <asm/asm.h>
> +#include <asm/csr.h>
> +#include <asm/scs.h>
> +
> +/* When entering handle_sse, the following registers are set:
> + * a6: contains the hartid
> + * a6: contains struct sse_registered_event pointer

Please fix this comment.

Regards
Himanshu

> + */
> +SYM_CODE_START(handle_sse)
> + /* Save stack temporarily */
> + REG_S sp, SSE_REG_EVT_TMP(a7)
> + /* Set entry stack */
> + REG_L sp, SSE_REG_EVT_STACK(a7)
> +
> + addi sp, sp, -(PT_SIZE_ON_STACK)
> + REG_S ra, PT_RA(sp)
> + REG_S s0, PT_S0(sp)
> + REG_S s1, PT_S1(sp)
> + REG_S s2, PT_S2(sp)
> + REG_S s3, PT_S3(sp)
> + REG_S s4, PT_S4(sp)
> + REG_S s5, PT_S5(sp)
> + REG_S s6, PT_S6(sp)
> + REG_S s7, PT_S7(sp)
> + REG_S s8, PT_S8(sp)
> + REG_S s9, PT_S9(sp)
> + REG_S s10, PT_S10(sp)
> + REG_S s11, PT_S11(sp)
> + REG_S tp, PT_TP(sp)
> + REG_S t0, PT_T0(sp)
> + REG_S t1, PT_T1(sp)
> + REG_S t2, PT_T2(sp)
> + REG_S t3, PT_T3(sp)
> + REG_S t4, PT_T4(sp)
> + REG_S t5, PT_T5(sp)
> + REG_S t6, PT_T6(sp)
> + REG_S gp, PT_GP(sp)
> + REG_S a0, PT_A0(sp)
> + REG_S a1, PT_A1(sp)
> + REG_S a2, PT_A2(sp)
> + REG_S a3, PT_A3(sp)
> + REG_S a4, PT_A4(sp)
> + REG_S a5, PT_A5(sp)
> +
> + /* Retrieve entry sp */
> + REG_L a4, SSE_REG_EVT_TMP(a7)
> + /* Save CSRs */
> + csrr a0, CSR_EPC
> + csrr a1, CSR_SSTATUS
> + csrr a2, CSR_STVAL
> + csrr a3, CSR_SCAUSE
> +
> + REG_S a0, PT_EPC(sp)
> + REG_S a1, PT_STATUS(sp)
> + REG_S a2, PT_BADADDR(sp)
> + REG_S a3, PT_CAUSE(sp)
> + REG_S a4, PT_SP(sp)
> +
> + /* Disable user memory access and floating/vector computing */
> + li t0, SR_SUM | SR_FS_VS
> + csrc CSR_STATUS, t0
> +
> + load_global_pointer
> + scs_load_sse_stack a7
> +
> + /* Restore current task struct from __sse_entry_task */
> + li t1, NR_CPUS
> + move t3, zero
> +
> +#ifdef CONFIG_SMP
> + /* Find the CPU id associated to the hart id */
> + la t0, __cpuid_to_hartid_map
> +.Lhart_id_loop:
> + REG_L t2, 0(t0)
> + beq t2, a6, .Lcpu_id_found
> +
> + /* Increment pointer and CPU number */
> + addi t3, t3, 1
> + addi t0, t0, RISCV_SZPTR
> + bltu t3, t1, .Lhart_id_loop
> +
> + /*
> + * This should never happen since we expect the hart_id to match one
> + * of our CPU, but better be safe than sorry
> + */
> + la tp, init_task
> + la a0, sse_hart_id_panic_string
> + la t0, panic
> + jalr t0
> +
> +.Lcpu_id_found:
> +#endif
> + asm_per_cpu_with_cpu t2 __sse_entry_task t1 t3
> + REG_L tp, 0(t2)
> +
> + move a1, sp /* pt_regs on stack */
> + /* Kernel was interrupted, create stack frame */
> + beqz s1, .Lcall_do_sse
> +
> +.Lcall_do_sse:
> + /*
> + * Save sscratch for restoration since we might have interrupted the
> + * kernel in early exception path and thus, we don't know the content of
> + * sscratch.
> + */
> + csrr s4, CSR_SSCRATCH
> + /* In-kernel scratch is 0 */
> + csrw CSR_SCRATCH, x0
> +
> + move a0, a7
> +
> + call do_sse
> +
> + csrw CSR_SSCRATCH, s4
> +
> + REG_L a0, PT_EPC(sp)
> + REG_L a1, PT_STATUS(sp)
> + REG_L a2, PT_BADADDR(sp)
> + REG_L a3, PT_CAUSE(sp)
> + csrw CSR_EPC, a0
> + csrw CSR_SSTATUS, a1
> + csrw CSR_STVAL, a2
> + csrw CSR_SCAUSE, a3
> +
> + REG_L ra, PT_RA(sp)
> + REG_L s0, PT_S0(sp)
> + REG_L s1, PT_S1(sp)
> + REG_L s2, PT_S2(sp)
> + REG_L s3, PT_S3(sp)
> + REG_L s4, PT_S4(sp)
> + REG_L s5, PT_S5(sp)
> + REG_L s6, PT_S6(sp)
> + REG_L s7, PT_S7(sp)
> + REG_L s8, PT_S8(sp)
> + REG_L s9, PT_S9(sp)
> + REG_L s10, PT_S10(sp)
> + REG_L s11, PT_S11(sp)
> + REG_L tp, PT_TP(sp)
> + REG_L t0, PT_T0(sp)
> + REG_L t1, PT_T1(sp)
> + REG_L t2, PT_T2(sp)
> + REG_L t3, PT_T3(sp)
> + REG_L t4, PT_T4(sp)
> + REG_L t5, PT_T5(sp)
> + REG_L t6, PT_T6(sp)
> + REG_L gp, PT_GP(sp)
> + REG_L a0, PT_A0(sp)
> + REG_L a1, PT_A1(sp)
> + REG_L a2, PT_A2(sp)
> + REG_L a3, PT_A3(sp)
> + REG_L a4, PT_A4(sp)
> + REG_L a5, PT_A5(sp)
> +
> + REG_L sp, PT_SP(sp)
> +
> + li a7, SBI_EXT_SSE
> + li a6, SBI_SSE_EVENT_COMPLETE
> + ecall
> +
> +SYM_CODE_END(handle_sse)
> +
> +sse_hart_id_panic_string:
> +    .ascii "Unable to match hart_id with cpu\0"
> -- 
> 2.45.2
> 



From hchauhan at ventanamicro.com  Mon Dec  9 20:51:38 2024
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Tue, 10 Dec 2024 10:21:38 +0530
Subject: [PATCH v3 2/4] riscv: add support for SBI Supervisor Software
 Events extension
In-Reply-To: <20241206163102.843505-3-cleger@rivosinc.com>
References: <20241206163102.843505-1-cleger@rivosinc.com>
 <20241206163102.843505-3-cleger@rivosinc.com>
Message-ID: <CDD40494-D31E-46E5-89C6-0B2A50C1B953@ventanamicro.com>

Hi Clement,

> On 6 Dec 2024, at 22:00, Cl?ment L?ger <cleger at rivosinc.com> wrote:
> 
> The SBI SSE extension allows the supervisor software to be notified by
> the SBI of specific events that are not maskable. The context switch is
> handled partially by the firmware which will save registers a6 and a7.
> When entering kernel we can rely on these 2 registers to setup the stack
> and save all the registers.
> 
> Since SSE events can be delivered at any time to the kernel (including
> during exception handling, we need a way to locate the current_task for
> context tracking. On RISC-V, it is sotred in scratch when in user space
> or tp when in kernel space (in which case SSCRATCH is zero). But at a
> at the beginning of exception handling, SSCRATCH is used to swap tp and
> check the origin of the exception. If interrupted at that point, then,
> there is no way to reliably know were is located the current
> task_struct. Even checking the interruption location won't work as SSE
> event can be nested on top of each other so the original interruption
> site might be lost at some point. In order to retrieve it reliably,
> store the current task in an additionnal __sse_entry_task per_cpu array.
> This array is then used to retrieve the current task based on the
> hart ID that is passed to the SSE event handler in a6.
> 
> That being said, the way the current task struct is stored should
> probably be reworked to find a better reliable alternative.
> 
> Since each events (and each CPU for local events) have their own
> context and can preempt each other, allocate a stack (and a shadow stack
> if needed for each of them (and for each cpu for local events).
> 
> When completing the event, if we were coming from kernel with interrupts
> disabled, simply return there. If coming from userspace or kernel with
> interrupts enabled, simulate an interrupt exception by setting IE_SIE in
> CSR_IP to allow delivery of signals to user task. For instance this can
> happen, when a RAS event has been generated by a user application and a
> SIGBUS has been sent to a task.
> 
> Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
> ---
> arch/riscv/include/asm/asm.h         |  14 ++-
> arch/riscv/include/asm/scs.h         |   7 ++
> arch/riscv/include/asm/sse.h         |  38 ++++++
> arch/riscv/include/asm/switch_to.h   |  14 +++
> arch/riscv/include/asm/thread_info.h |   1 +
> arch/riscv/kernel/Makefile           |   1 +
> arch/riscv/kernel/asm-offsets.c      |  12 ++
> arch/riscv/kernel/sse.c              | 134 +++++++++++++++++++++
> arch/riscv/kernel/sse_entry.S        | 171 +++++++++++++++++++++++++++
> 9 files changed, 389 insertions(+), 3 deletions(-)
> create mode 100644 arch/riscv/include/asm/sse.h
> create mode 100644 arch/riscv/kernel/sse.c
> create mode 100644 arch/riscv/kernel/sse_entry.S
> 
> diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
> index 776354895b81..de8427c58f02 100644
> --- a/arch/riscv/include/asm/asm.h
> +++ b/arch/riscv/include/asm/asm.h
> @@ -89,16 +89,24 @@
> #define PER_CPU_OFFSET_SHIFT 3
> #endif
> 
> -.macro asm_per_cpu dst sym tmp
> - REG_L \tmp, TASK_TI_CPU_NUM(tp)
> - slli  \tmp, \tmp, PER_CPU_OFFSET_SHIFT
> +.macro asm_per_cpu_with_cpu dst sym tmp cpu
> + slli  \tmp, \cpu, PER_CPU_OFFSET_SHIFT
> la    \dst, __per_cpu_offset
> add   \dst, \dst, \tmp
> REG_L \tmp, 0(\dst)
> la    \dst, \sym
> add   \dst, \dst, \tmp
> .endm
> +
> +.macro asm_per_cpu dst sym tmp
> + REG_L \tmp, TASK_TI_CPU_NUM(tp)
> + asm_per_cpu_with_cpu \dst \sym \tmp \tmp
> +.endm
> #else /* CONFIG_SMP */
> +.macro asm_per_cpu_with_cpu dst sym tmp cpu
> + la    \dst, \sym
> +.endm
> +
> .macro asm_per_cpu dst sym tmp
> la    \dst, \sym
> .endm
> diff --git a/arch/riscv/include/asm/scs.h b/arch/riscv/include/asm/scs.h
> index 0e45db78b24b..62344daad73d 100644
> --- a/arch/riscv/include/asm/scs.h
> +++ b/arch/riscv/include/asm/scs.h
> @@ -18,6 +18,11 @@
> load_per_cpu gp, irq_shadow_call_stack_ptr, \tmp
> .endm
> 
> +/* Load the per-CPU IRQ shadow call stack to gp. */
> +.macro scs_load_sse_stack reg_evt
> + REG_L gp, SSE_REG_EVT_SHADOW_STACK(\reg_evt)
> +.endm
> +
> /* Load task_scs_sp(current) to gp. */
> .macro scs_load_current
> REG_L gp, TASK_TI_SCS_SP(tp)
> @@ -41,6 +46,8 @@
> .endm
> .macro scs_load_irq_stack tmp
> .endm
> +.macro scs_load_sse_stack reg_evt
> +.endm
> .macro scs_load_current
> .endm
> .macro scs_load_current_if_task_changed prev
> diff --git a/arch/riscv/include/asm/sse.h b/arch/riscv/include/asm/sse.h
> new file mode 100644
> index 000000000000..431a19d4cd9c
> --- /dev/null
> +++ b/arch/riscv/include/asm/sse.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2024 Rivos Inc.
> + */
> +#ifndef __ASM_SSE_H
> +#define __ASM_SSE_H
> +
> +#ifdef CONFIG_RISCV_SSE
> +
> +struct sse_event_interrupted_state {
> + unsigned long a6;
> + unsigned long a7;
> +};
> +
> +struct sse_event_arch_data {
> + void *stack;
> + void *shadow_stack;
> + unsigned long tmp;
> + struct sse_event_interrupted_state interrupted;
> + unsigned long interrupted_state_phys;
> + u32 evt_id;
> +};
> +
> +struct sse_registered_event;
> +int arch_sse_init_event(struct sse_event_arch_data *arch_evt, u32 evt_id,
> + int cpu);
> +void arch_sse_free_event(struct sse_event_arch_data *arch_evt);
> +int arch_sse_register_event(struct sse_event_arch_data *arch_evt);
> +
> +void sse_handle_event(struct sse_event_arch_data *arch_evt,
> +      struct pt_regs *regs);
> +asmlinkage void handle_sse(void);
> +asmlinkage void do_sse(struct sse_event_arch_data *arch_evt,
> + struct pt_regs *reg);
> +
> +#endif
> +
> +#endif
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index 94e33216b2d9..e166fabe04ab 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -88,6 +88,19 @@ static inline void __switch_to_envcfg(struct task_struct *next)
> :: "r" (next->thread.envcfg) : "memory");
> }
> 
> +#ifdef CONFIG_RISCV_SSE
> +DECLARE_PER_CPU(struct task_struct *, __sse_entry_task);
> +
> +static inline void __switch_sse_entry_task(struct task_struct *next)
> +{
> + __this_cpu_write(__sse_entry_task, next);
> +}
> +#else
> +static inline void __switch_sse_entry_task(struct task_struct *next)
> +{
> +}
> +#endif
> +
> extern struct task_struct *__switch_to(struct task_struct *,
>       struct task_struct *);
> 
> @@ -122,6 +135,7 @@ do { \
> if (switch_to_should_flush_icache(__next)) \
> local_flush_icache_all(); \
> __switch_to_envcfg(__next); \
> + __switch_sse_entry_task(__next); \
> ((last) = __switch_to(__prev, __next)); \
> } while (0)
> 
> diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
> index f5916a70879a..28e9805e61fc 100644
> --- a/arch/riscv/include/asm/thread_info.h
> +++ b/arch/riscv/include/asm/thread_info.h
> @@ -36,6 +36,7 @@
> #define OVERFLOW_STACK_SIZE     SZ_4K
> 
> #define IRQ_STACK_SIZE THREAD_SIZE
> +#define SSE_STACK_SIZE THREAD_SIZE
> 
> #ifndef __ASSEMBLY__
> 
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 063d1faf5a53..1e8fb83b1162 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -99,6 +99,7 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o
> obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
> obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o
> obj-$(CONFIG_RISCV_SBI) += sbi.o sbi_ecall.o
> +obj-$(CONFIG_RISCV_SSE) += sse.o sse_entry.o
> ifeq ($(CONFIG_RISCV_SBI), y)
> obj-$(CONFIG_SMP) += sbi-ipi.o
> obj-$(CONFIG_SMP) += cpu_ops_sbi.o
> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> index e89455a6a0e5..60590a3d9519 100644
> --- a/arch/riscv/kernel/asm-offsets.c
> +++ b/arch/riscv/kernel/asm-offsets.c
> @@ -14,6 +14,8 @@
> #include <asm/ptrace.h>
> #include <asm/cpu_ops_sbi.h>
> #include <asm/stacktrace.h>
> +#include <asm/sbi.h>
> +#include <asm/sse.h>
> #include <asm/suspend.h>
> 
> void asm_offsets(void);
> @@ -511,4 +513,14 @@ void asm_offsets(void)
> DEFINE(FREGS_A6,    offsetof(struct __arch_ftrace_regs, a6));
> DEFINE(FREGS_A7,    offsetof(struct __arch_ftrace_regs, a7));
> #endif
> +
> +#ifdef CONFIG_RISCV_SSE
> + OFFSET(SSE_REG_EVT_STACK, sse_event_arch_data, stack);
> + OFFSET(SSE_REG_EVT_SHADOW_STACK, sse_event_arch_data, shadow_stack);
> + OFFSET(SSE_REG_EVT_TMP, sse_event_arch_data, tmp);
> +
> + DEFINE(SBI_EXT_SSE, SBI_EXT_SSE);
> + DEFINE(SBI_SSE_EVENT_COMPLETE, SBI_SSE_EVENT_COMPLETE);
> + DEFINE(NR_CPUS, NR_CPUS);
> +#endif
> }
> diff --git a/arch/riscv/kernel/sse.c b/arch/riscv/kernel/sse.c
> new file mode 100644
> index 000000000000..b48ae69dad8d
> --- /dev/null
> +++ b/arch/riscv/kernel/sse.c
> @@ -0,0 +1,134 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2024 Rivos Inc.
> + */
> +#include <linux/nmi.h>
> +#include <linux/scs.h>
> +#include <linux/bitfield.h>
> +#include <linux/riscv_sse.h>
> +#include <linux/percpu-defs.h>
> +
> +#include <asm/asm-prototypes.h>
> +#include <asm/switch_to.h>
> +#include <asm/irq_stack.h>
> +#include <asm/sbi.h>
> +#include <asm/sse.h>
> +
> +DEFINE_PER_CPU(struct task_struct *, __sse_entry_task);
> +
> +void __weak sse_handle_event(struct sse_event_arch_data *arch_evt, struct pt_regs *regs)
> +{
> +}
> +
> +void do_sse(struct sse_event_arch_data *arch_evt, struct pt_regs *regs)
> +{
> + nmi_enter();
> +
> + /* Retrieve missing GPRs from SBI */
> + sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_ATTR_READ, arch_evt->evt_id,
> +  SBI_SSE_ATTR_INTERRUPTED_A6,
> +  (SBI_SSE_ATTR_INTERRUPTED_A7 - SBI_SSE_ATTR_INTERRUPTED_A6) + 1,
> +  arch_evt->interrupted_state_phys, 0, 0);
> +
> + memcpy(&regs->a6, &arch_evt->interrupted, sizeof(arch_evt->interrupted));
> +
> + sse_handle_event(arch_evt, regs);
> +
> + /*
> + * The SSE delivery path does not uses the "standard" exception path and
> + * thus does not process any pending signal/softirqs. Some drivers might
> + * enqueue pending work that needs to be handled as soon as possible.
> + * For that purpose, set the software interrupt pending bit which will
> + * be serviced once interrupts are reenabled
> + */
> + csr_set(CSR_IP, IE_SIE);
> +
> + nmi_exit();
> +}
> +
> +#ifdef CONFIG_VMAP_STACK
> +static unsigned long *sse_stack_alloc(unsigned int cpu, unsigned int size)
> +{
> + return arch_alloc_vmap_stack(size, cpu_to_node(cpu));
> +}
> +
> +static void sse_stack_free(unsigned long *stack)
> +{
> + vfree(stack);
> +}
> +#else /* CONFIG_VMAP_STACK */
> +
> +static unsigned long *sse_stack_alloc(unsigned int cpu, unsigned int size)
> +{
> + return kmalloc(size, GFP_KERNEL);
> +}
> +
> +static void sse_stack_free(unsigned long *stack)
> +{
> + kfree(stack);
> +}
> +
> +#endif /* CONFIG_VMAP_STACK */
> +
> +static int sse_init_scs(int cpu, struct sse_event_arch_data *arch_evt)
> +{
> + void *stack;
> +
> + if (!scs_is_enabled())
> + return 0;
> +
> + stack = scs_alloc(cpu_to_node(cpu));
> + if (!stack)
> + return 1;
> +
> + arch_evt->shadow_stack = stack;
> +
> + return 0;
> +}
> +
> +int arch_sse_init_event(struct sse_event_arch_data *arch_evt, u32 evt_id, int cpu)
> +{
> + void *stack;
> +
> + arch_evt->evt_id = evt_id;
> + stack = sse_stack_alloc(cpu, SSE_STACK_SIZE);
> + if (!stack)
> + return -ENOMEM;
> +
> + arch_evt->stack = stack + SSE_STACK_SIZE;
> +
> + if (sse_init_scs(cpu, arch_evt))
> + goto free_stack;
> +
> + if (is_kernel_percpu_address((unsigned long)&arch_evt->interrupted)) {
> + arch_evt->interrupted_state_phys =
> + per_cpu_ptr_to_phys(&arch_evt->interrupted);
> + } else {
> + arch_evt->interrupted_state_phys =
> + virt_to_phys(&arch_evt->interrupted);
> + }
> +
> + return 0;
> +
> +free_stack:
> + sse_stack_free(arch_evt->stack - SSE_STACK_SIZE);
> +
> + return -ENOMEM;
> +}
> +
> +void arch_sse_free_event(struct sse_event_arch_data *arch_evt)
> +{
> + scs_free(arch_evt->shadow_stack);
> + sse_stack_free(arch_evt->stack - SSE_STACK_SIZE);
> +}
> +
> +int arch_sse_register_event(struct sse_event_arch_data *arch_evt)
> +{
> + struct sbiret sret;
> +
> + sret = sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_REGISTER, arch_evt->evt_id,
> + (unsigned long) handle_sse, (unsigned long) arch_evt,
> + 0, 0, 0);
> +
> + return sbi_err_map_linux_errno(sret.error);
> +}
> diff --git a/arch/riscv/kernel/sse_entry.S b/arch/riscv/kernel/sse_entry.S
> new file mode 100644
> index 000000000000..0b2f890edd89
> --- /dev/null
> +++ b/arch/riscv/kernel/sse_entry.S
> @@ -0,0 +1,171 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2024 Rivos Inc.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/linkage.h>
> +
> +#include <asm/asm.h>
> +#include <asm/csr.h>
> +#include <asm/scs.h>
> +
> +/* When entering handle_sse, the following registers are set:
> + * a6: contains the hartid
> + * a6: contains struct sse_registered_event pointer

Please fix this comment.

Regards
Himanshu

> + */
> +SYM_CODE_START(handle_sse)
> + /* Save stack temporarily */
> + REG_S sp, SSE_REG_EVT_TMP(a7)
> + /* Set entry stack */
> + REG_L sp, SSE_REG_EVT_STACK(a7)
> +
> + addi sp, sp, -(PT_SIZE_ON_STACK)
> + REG_S ra, PT_RA(sp)
> + REG_S s0, PT_S0(sp)
> + REG_S s1, PT_S1(sp)
> + REG_S s2, PT_S2(sp)
> + REG_S s3, PT_S3(sp)
> + REG_S s4, PT_S4(sp)
> + REG_S s5, PT_S5(sp)
> + REG_S s6, PT_S6(sp)
> + REG_S s7, PT_S7(sp)
> + REG_S s8, PT_S8(sp)
> + REG_S s9, PT_S9(sp)
> + REG_S s10, PT_S10(sp)
> + REG_S s11, PT_S11(sp)
> + REG_S tp, PT_TP(sp)
> + REG_S t0, PT_T0(sp)
> + REG_S t1, PT_T1(sp)
> + REG_S t2, PT_T2(sp)
> + REG_S t3, PT_T3(sp)
> + REG_S t4, PT_T4(sp)
> + REG_S t5, PT_T5(sp)
> + REG_S t6, PT_T6(sp)
> + REG_S gp, PT_GP(sp)
> + REG_S a0, PT_A0(sp)
> + REG_S a1, PT_A1(sp)
> + REG_S a2, PT_A2(sp)
> + REG_S a3, PT_A3(sp)
> + REG_S a4, PT_A4(sp)
> + REG_S a5, PT_A5(sp)
> +
> + /* Retrieve entry sp */
> + REG_L a4, SSE_REG_EVT_TMP(a7)
> + /* Save CSRs */
> + csrr a0, CSR_EPC
> + csrr a1, CSR_SSTATUS
> + csrr a2, CSR_STVAL
> + csrr a3, CSR_SCAUSE
> +
> + REG_S a0, PT_EPC(sp)
> + REG_S a1, PT_STATUS(sp)
> + REG_S a2, PT_BADADDR(sp)
> + REG_S a3, PT_CAUSE(sp)
> + REG_S a4, PT_SP(sp)
> +
> + /* Disable user memory access and floating/vector computing */
> + li t0, SR_SUM | SR_FS_VS
> + csrc CSR_STATUS, t0
> +
> + load_global_pointer
> + scs_load_sse_stack a7
> +
> + /* Restore current task struct from __sse_entry_task */
> + li t1, NR_CPUS
> + move t3, zero
> +
> +#ifdef CONFIG_SMP
> + /* Find the CPU id associated to the hart id */
> + la t0, __cpuid_to_hartid_map
> +.Lhart_id_loop:
> + REG_L t2, 0(t0)
> + beq t2, a6, .Lcpu_id_found
> +
> + /* Increment pointer and CPU number */
> + addi t3, t3, 1
> + addi t0, t0, RISCV_SZPTR
> + bltu t3, t1, .Lhart_id_loop
> +
> + /*
> + * This should never happen since we expect the hart_id to match one
> + * of our CPU, but better be safe than sorry
> + */
> + la tp, init_task
> + la a0, sse_hart_id_panic_string
> + la t0, panic
> + jalr t0
> +
> +.Lcpu_id_found:
> +#endif
> + asm_per_cpu_with_cpu t2 __sse_entry_task t1 t3
> + REG_L tp, 0(t2)
> +
> + move a1, sp /* pt_regs on stack */
> + /* Kernel was interrupted, create stack frame */
> + beqz s1, .Lcall_do_sse
> +
> +.Lcall_do_sse:
> + /*
> + * Save sscratch for restoration since we might have interrupted the
> + * kernel in early exception path and thus, we don't know the content of
> + * sscratch.
> + */
> + csrr s4, CSR_SSCRATCH
> + /* In-kernel scratch is 0 */
> + csrw CSR_SCRATCH, x0
> +
> + move a0, a7
> +
> + call do_sse
> +
> + csrw CSR_SSCRATCH, s4
> +
> + REG_L a0, PT_EPC(sp)
> + REG_L a1, PT_STATUS(sp)
> + REG_L a2, PT_BADADDR(sp)
> + REG_L a3, PT_CAUSE(sp)
> + csrw CSR_EPC, a0
> + csrw CSR_SSTATUS, a1
> + csrw CSR_STVAL, a2
> + csrw CSR_SCAUSE, a3
> +
> + REG_L ra, PT_RA(sp)
> + REG_L s0, PT_S0(sp)
> + REG_L s1, PT_S1(sp)
> + REG_L s2, PT_S2(sp)
> + REG_L s3, PT_S3(sp)
> + REG_L s4, PT_S4(sp)
> + REG_L s5, PT_S5(sp)
> + REG_L s6, PT_S6(sp)
> + REG_L s7, PT_S7(sp)
> + REG_L s8, PT_S8(sp)
> + REG_L s9, PT_S9(sp)
> + REG_L s10, PT_S10(sp)
> + REG_L s11, PT_S11(sp)
> + REG_L tp, PT_TP(sp)
> + REG_L t0, PT_T0(sp)
> + REG_L t1, PT_T1(sp)
> + REG_L t2, PT_T2(sp)
> + REG_L t3, PT_T3(sp)
> + REG_L t4, PT_T4(sp)
> + REG_L t5, PT_T5(sp)
> + REG_L t6, PT_T6(sp)
> + REG_L gp, PT_GP(sp)
> + REG_L a0, PT_A0(sp)
> + REG_L a1, PT_A1(sp)
> + REG_L a2, PT_A2(sp)
> + REG_L a3, PT_A3(sp)
> + REG_L a4, PT_A4(sp)
> + REG_L a5, PT_A5(sp)
> +
> + REG_L sp, PT_SP(sp)
> +
> + li a7, SBI_EXT_SSE
> + li a6, SBI_SSE_EVENT_COMPLETE
> + ecall
> +
> +SYM_CODE_END(handle_sse)
> +
> +sse_hart_id_panic_string:
> +    .ascii "Unable to match hart_id with cpu\0"
> -- 
> 2.45.2
> 



From patchwork-bot+netdevbpf at kernel.org  Mon Dec  9 21:10:37 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Tue, 10 Dec 2024 05:10:37 +0000
Subject: [PATCH net-next v8 00/15] Add support for Synopsis DWMAC IP on NXP
 Automotive SoCs S32G2xx/S32G3xx/S32R45
In-Reply-To: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
References: <20241205-upstream_s32cc_gmac-v8-0-ec1d180df815@oss.nxp.com>
Message-ID: <173380743727.355055.17303486442146316315.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, 05 Dec 2024 17:42:57 +0100 you wrote:
> The SoC series S32G2xx and S32G3xx feature one DWMAC instance,
> the SoC S32R45 has two instances. The devices can use RGMII/RMII/MII
> interface over Pinctrl device or the output can be routed
> to the embedded SerDes for SGMII connectivity.
> 
> The provided stmmac glue code implements only basic functionality,
> interface support is restricted to RGMII only. More, including
> SGMII/SerDes support will come later.
> 
> [...]

Here is the summary with links:
  - [net-next,v8,01/15] net: stmmac: Fix CSR divider comment
    https://git.kernel.org/netdev/net-next/c/31cdd8418234
  - [net-next,v8,02/15] net: stmmac: Extend CSR calc support
    https://git.kernel.org/netdev/net-next/c/c8fab05d021d
  - [net-next,v8,03/15] net: stmmac: Fix clock rate variables size
    https://git.kernel.org/netdev/net-next/c/cb09f61a9ab8
  - [net-next,v8,04/15] net: phy: Add helper for mapping RGMII link speed to clock rate
    https://git.kernel.org/netdev/net-next/c/386aa60abdb6
  - [net-next,v8,05/15] net: dwmac-dwc-qos-eth: Use helper rgmii_clock
    https://git.kernel.org/netdev/net-next/c/37b66c483e4c
  - [net-next,v8,06/15] net: dwmac-imx: Use helper rgmii_clock
    https://git.kernel.org/netdev/net-next/c/839b75ea4d94
  - [net-next,v8,07/15] net: dwmac-intel-plat: Use helper rgmii_clock
    https://git.kernel.org/netdev/net-next/c/8470bfc83515
  - [net-next,v8,08/15] net: dwmac-rk: Use helper rgmii_clock
    https://git.kernel.org/netdev/net-next/c/30b4a9b5c335
  - [net-next,v8,09/15] net: dwmac-starfive: Use helper rgmii_clock
    https://git.kernel.org/netdev/net-next/c/b561d717a799
  - [net-next,v8,10/15] net: macb: Use helper rgmii_clock
    https://git.kernel.org/netdev/net-next/c/04207d28f468
  - [net-next,v8,11/15] net: xgene_enet: Use helper rgmii_clock
    https://git.kernel.org/netdev/net-next/c/fd59bca4d5ea
  - [net-next,v8,12/15] net: dwmac-sti: Use helper rgmii_clock
    https://git.kernel.org/netdev/net-next/c/1ead57775507
  - [net-next,v8,13/15] dt-bindings: net: Add DT bindings for DWMAC on NXP S32G/R SoCs
    https://git.kernel.org/netdev/net-next/c/91f10e589520
  - [net-next,v8,14/15] net: stmmac: dwmac-s32: add basic NXP S32G/S32R glue driver
    https://git.kernel.org/netdev/net-next/c/cd197ac5d661
  - [net-next,v8,15/15] MAINTAINERS: Add Jan Petrous as the NXP S32G/R DWMAC driver maintainer
    https://git.kernel.org/netdev/net-next/c/6bc6234cbd5e

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From mjchen0829 at gmail.com  Mon Dec  9 21:23:39 2024
From: mjchen0829 at gmail.com (Ming-Jen Chen)
Date: Tue, 10 Dec 2024 13:23:39 +0800
Subject: [PATCH v4 2/2] dt-bindings: input: Add Nuvoton MA35D1 keypad
In-Reply-To: <2a47hwrbl3r6h5umwikt7bd7rp3njj6wnlo5e67f5kl6zhaq7g@cnolynoswb37>
References: <20241204021014.5083-1-mjchen0829@gmail.com>
 <20241204021014.5083-3-mjchen0829@gmail.com>
 <2a47hwrbl3r6h5umwikt7bd7rp3njj6wnlo5e67f5kl6zhaq7g@cnolynoswb37>
Message-ID: <274c7ba7-dd7a-4981-95a8-38ed953a7dbc@gmail.com>



On 2024/12/4 ?? 03:49, Krzysztof Kozlowski wrote:
> On Wed, Dec 04, 2024 at 02:10:14AM +0000, Ming-Jen Chen wrote:
>> Add YAML bindings for MA35D1 SoC keypad.
>>
>> Signed-off-by: Ming-Jen Chen <mjchen0829 at gmail.com>
> 
> 
> Repeating same comment third or fourth time is a waste of my time.
> 
> NAK.
> 
> It seems my or other reviewer's previous comments were not fully
> addressed. Maybe the feedback got lost between the quotes, maybe you
> just forgot to apply it. Please go back to the previous discussion and
> either implement all requested changes or keep discussing them.
> 
> Best regards,
> Krzysztof
> 

I will carefully review the v3 discussion thread to ensure that all
feedback is properly implemented. Once I?ve addressed the issues, I?d
like to confirm the next steps with you:

1. Should I drop v4 entirely and submit a revised patch as v5?
2. Alternatively, would you prefer me to resend v4 with the necessary
corrections?

Please let me know your preference so I can proceed accordingly and
ensure a smoother review process.

Thank you again for your guidance and understanding.

Best regards,
Ming-Jen Chen






From lkp at intel.com  Mon Dec  9 21:22:44 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 10 Dec 2024 13:22:44 +0800
Subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
References: <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
Message-ID: <202412101248.CBSpbBCZ-lkp@intel.com>

Hi Ciprian,

kernel test robot noticed the following build errors:

[auto build test ERROR on abelloni/rtc-next]
[also build test ERROR on robh/for-next linus/master v6.13-rc2 next-20241209]
[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/Ciprian-Costea/dt-bindings-rtc-add-schema-for-NXP-S32G2-S32G3-SoCs/20241206-151308
base:   https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-next
patch link:    https://lore.kernel.org/r/20241206070955.1503412-3-ciprianmarian.costea%40oss.nxp.com
patch subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
config: i386-allmodconfig (https://download.01.org/0day-ci/archive/20241210/202412101248.CBSpbBCZ-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/20241210/202412101248.CBSpbBCZ-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/202412101248.CBSpbBCZ-lkp at intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

ERROR: modpost: "__udivdi3" [drivers/rtc/rtc-s32g.ko] undefined!
>> ERROR: modpost: "__divdi3" [drivers/rtc/rtc-s32g.ko] undefined!

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for MODVERSIONS
   Depends on [n]: MODULES [=y] && !COMPILE_TEST [=y]
   Selected by [y]:
   - RANDSTRUCT_FULL [=y] && (CC_HAS_RANDSTRUCT [=n] || GCC_PLUGINS [=y]) && MODULES [=y]
   WARNING: unmet direct dependencies detected for GET_FREE_REGION
   Depends on [n]: SPARSEMEM [=n]
   Selected by [m]:
   - RESOURCE_KUNIT_TEST [=m] && RUNTIME_TESTING_MENU [=y] && KUNIT [=m]

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


From anshuman.khandual at arm.com  Mon Dec  9 21:52:37 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:37 +0530
Subject: [PATCH V2 12/46] arm64/sysreg: Add register fields for TRBMPAM_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-13-anshuman.khandual@arm.com>

This adds register fields for TRBMPAM_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a5e31e4c4474..78564b24b187 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -3413,6 +3413,19 @@ EndEnum
 Field	7:0	Attr
 EndSysreg
 
+Sysreg	TRBMPAM_EL1	3	0	9	11	5
+Res0	63:27
+Field 	26	EN
+UnsignedEnum	25:24	MPAM_SP
+	0b00	SECURE_PARTID
+	0b01	NON_SECURE_PARTID
+	0b10	ROOT_PARTID
+	0b11	REALM_PARTID
+EndEnum
+Field	23:16	PMG
+Field	15:0	PARTID
+EndSysreg
+
 Sysreg	TRBTRG_EL1	3	0	9	11	6
 Res0	63:32
 Field	31:0	TRG
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:38 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:38 +0530
Subject: [PATCH V2 13/46] arm64/sysreg: Add register fields for PMSDSFR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-14-anshuman.khandual@arm.com>

This adds register fields for PMSDSFR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 78564b24b187..fcb4ecd85d35 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2245,6 +2245,73 @@ Field	16	COLL
 Field	15:0	MSS
 EndSysreg
 
+Sysreg	PMSDSFR_EL1	3	0	9	10	4
+Field	63	S63
+Field	62	S62
+Field	61	S61
+Field	60	S60
+Field	59	S59
+Field	58	S58
+Field	57	S57
+Field	56	S56
+Field	55	S55
+Field	54	S54
+Field	53	S53
+Field	52	S52
+Field	51	S51
+Field	50	S50
+Field	49	S49
+Field	48	S48
+Field	47	S47
+Field	46	S46
+Field	45	S45
+Field	44	S44
+Field	43	S43
+Field	42	S42
+Field	41	S41
+Field	40	S40
+Field	39	S39
+Field	38	S38
+Field	37	S37
+Field	36	S36
+Field	35	S35
+Field	34	S34
+Field	33	S33
+Field	32	S32
+Field	31	S31
+Field	30	S30
+Field	29	S29
+Field	28	S28
+Field	27	S27
+Field	26	S26
+Field	25	S25
+Field	24	S24
+Field	23	S23
+Field	22	S22
+Field	21	S21
+Field	20	S20
+Field	19	S19
+Field	18	S18
+Field	17	S17
+Field	16	S16
+Field	15	S15
+Field	14	S14
+Field	13	S13
+Field	12	S12
+Field	11	S11
+Field	10	S10
+Field	9	S9
+Field	8	S8
+Field	7	S7
+Field	6	S6
+Field	5	S5
+Field	4	S4
+Field	3	S3
+Field	2	S2
+Field	1	S1
+Field	0	S0
+EndSysreg
+
 Sysreg	PMBIDR_EL1	3	0	9	10	7
 Res0	63:12
 Enum	11:8	EA
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:39 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:39 +0530
Subject: [PATCH V2 14/46] arm64/sysreg: Add register fields for SPMDEVAFF_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-15-anshuman.khandual@arm.com>

This adds register fields for SPMDEVAFF_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index fcb4ecd85d35..18b814ff2c41 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -114,6 +114,18 @@ Res0	63:1
 Field	0	OSLK
 EndSysreg
 
+Sysreg	SPMDEVAFF_EL1	2	0	9	13	6
+Res0	63:40
+Field	39:32	Aff3
+Field	31	F0V
+Field	30	U
+Res0	29:25
+Field	24	MT
+Field	23:16	Aff2
+Field	15:8	Aff1
+Field	7:0	Aff0
+EndSysreg
+
 Sysreg ID_PFR0_EL1	3	0	0	1	0
 Res0	63:32
 UnsignedEnum	31:28	RAS
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:40 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:40 +0530
Subject: [PATCH V2 15/46] arm64/sysreg: Add register fields for PFAR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-16-anshuman.khandual@arm.com>

This adds register fields for PFAR_EL1 as per the definitions based on
DDI0601 2024-09.

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 | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 18b814ff2c41..e33edb41721a 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -3533,3 +3533,10 @@ Field	5	F
 Field	4	P
 Field	3:0	Align
 EndSysreg
+
+Sysreg	PFAR_EL1	3	0	6	0	5
+Field	63	NS
+Field	62	NSE
+Res0	61:56
+Field	55:0	PA
+EndSysreg
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:41 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:41 +0530
Subject: [PATCH V2 16/46] arm64/sysreg: Add register fields for PMIAR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-17-anshuman.khandual@arm.com>

This adds register fields for PMIAR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index e33edb41721a..ff09da6c0b1e 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2349,6 +2349,10 @@ Res0	63:5
 Field	4:0	SEL
 EndSysreg
 
+Sysreg	PMIAR_EL1	3	0	9	14	7
+Field	63:0 ADDRESS
+EndSysreg
+
 SysregFields	CONTEXTIDR_ELx
 Res0	63:32
 Field	31:0	PROCID
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:42 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:42 +0530
Subject: [PATCH V2 17/46] arm64/sysreg: Add register fields for PMECR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-18-anshuman.khandual@arm.com>

This adds register fields for PMECR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index ff09da6c0b1e..214ad6da1dff 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2349,6 +2349,21 @@ Res0	63:5
 Field	4:0	SEL
 EndSysreg
 
+Sysreg	PMECR_EL1	3	0	9	14	5
+Res0	63:5
+UnsignedEnum	4:3	SSE
+	0b00	DISABLED
+	0b10	ENABLED_PROHIBITED
+	0b11	ENABLED_ALLOWED
+EndEnum
+Field	2	KPME
+UnsignedEnum	1:0	PMEE
+	0b00	PMUIRQ_E_PMU_D
+	0b10	PMUIRQ_D_PMU_D
+	0b11	PMUIRQ_D_PMU_E
+EndEnum
+EndSysreg
+
 Sysreg	PMIAR_EL1	3	0	9	14	7
 Field	63:0 ADDRESS
 EndSysreg
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:43 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:43 +0530
Subject: [PATCH V2 18/46] arm64/sysreg: Add register fields for PMUACR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-19-anshuman.khandual@arm.com>

This adds register fields for PMUACR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 214ad6da1dff..462adb8031ca 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2349,6 +2349,43 @@ Res0	63:5
 Field	4:0	SEL
 EndSysreg
 
+Sysreg	PMUACR_EL1	3	0	9	14	4
+Res0	63:33
+Field	32	FM
+Field	31	C
+Field	30	P30
+Field	29	P29
+Field	28	P28
+Field	27	P27
+Field	26	P26
+Field	25	P25
+Field	24	P24
+Field	23	P23
+Field	22	P22
+Field	21	P21
+Field	20	P20
+Field	19	P19
+Field	18	P18
+Field	17	P17
+Field	16	P16
+Field	15	P15
+Field	14	P14
+Field	13	P13
+Field	12	P12
+Field	11	P11
+Field	10	P10
+Field	9	P9
+Field	8	P8
+Field	7	P7
+Field	6	P6
+Field	5	P5
+Field	4	P4
+Field	3	P3
+Field	2	P2
+Field	1	P1
+Field	0	P0
+EndSysreg
+
 Sysreg	PMECR_EL1	3	0	9	14	5
 Res0	63:5
 UnsignedEnum	4:3	SSE
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:44 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:44 +0530
Subject: [PATCH V2 19/46] arm64/sysreg: Add register fields for PMCCNTSVR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-20-anshuman.khandual@arm.com>

This adds register fields for PMCCNTSVR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 462adb8031ca..00d0015d7df4 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -126,6 +126,10 @@ Field	15:8	Aff1
 Field	7:0	Aff0
 EndSysreg
 
+Sysreg	PMCCNTSVR_EL1	2	0	14	11	7
+Field	63:0	CCNT
+EndSysreg
+
 Sysreg ID_PFR0_EL1	3	0	0	1	0
 Res0	63:32
 UnsignedEnum	31:28	RAS
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:45 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:45 +0530
Subject: [PATCH V2 20/46] arm64/sysreg: Add register fields for SPMSCR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-21-anshuman.khandual@arm.com>

This adds register fields for SPMSCR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 00d0015d7df4..22d2ba231059 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -130,6 +130,15 @@ Sysreg	PMCCNTSVR_EL1	2	0	14	11	7
 Field	63:0	CCNT
 EndSysreg
 
+Sysreg	SPMSCR_EL1	2	7	9	14	7
+Field	63:32	IMP_DEF
+Field	31	RAO
+Res0	30:5
+Field	4	NAO
+Res0	3:1
+Field	0	SO
+EndSysreg
+
 Sysreg ID_PFR0_EL1	3	0	0	1	0
 Res0	63:32
 UnsignedEnum	31:28	RAS
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:46 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:46 +0530
Subject: [PATCH V2 21/46] arm64/sysreg: Add register fields for SPMACCESSR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-22-anshuman.khandual@arm.com>

This adds register fields for SPMACCESSR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 22d2ba231059..ff833f6f7f6d 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -114,6 +114,41 @@ Res0	63:1
 Field	0	OSLK
 EndSysreg
 
+Sysreg	SPMACCESSR_EL1	2	0	9	13	3
+Field	63:62	P31
+Field	61:60	P30
+Field	59:58	P29
+Field	57:56	P28
+Field	55:54	P27
+Field	53:52	P26
+Field	51:50	P25
+Field	49:48	P24
+Field	47:46	P23
+Field	45:44	P22
+Field	43:42	P21
+Field	41:40	P20
+Field	39:38	P19
+Field	37:36	P18
+Field	35:34	P17
+Field	33:32	P16
+Field	31:30	P15
+Field	29:28	P14
+Field	27:26	P13
+Field	25:24	P12
+Field	23:22	P11
+Field	21:20	P10
+Field	19:18	P9
+Field	17:16	P8
+Field	15:14	P7
+Field	13:12	P6
+Field	11:10	P5
+Field	9:8	P4
+Field	7:6	P3
+Field	5:4	P2
+Field	3:2	P1
+Field	1:0	P0
+EndSysreg
+
 Sysreg	SPMDEVAFF_EL1	2	0	9	13	6
 Res0	63:40
 Field	39:32	Aff3
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:47 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:47 +0530
Subject: [PATCH V2 22/46] arm64/sysreg: Add register fields for PMICNTR_EL0
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-23-anshuman.khandual@arm.com>

This adds register fields for PMICNTR_EL0 as per the definitions based
on DDI0601 2024-09.

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 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index ff833f6f7f6d..8baf57c06dbd 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2591,6 +2591,10 @@ UnsignedEnum	2:0	F8S1
 EndEnum
 EndSysreg
 
+Sysreg	PMICNTR_EL0	3	3	9	4	0
+Field	63:0	ICNT
+EndSysreg
+
 SysregFields	HFGxTR_EL2
 Field	63	nAMAIR2_EL1
 Field	62	nMAIR2_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:48 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:48 +0530
Subject: [PATCH V2 23/46] arm64/sysreg: Add register fields for PMICFILTR_EL0
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-24-anshuman.khandual@arm.com>

This adds register fields for PMICFILTR_EL0 as per the definitions based
on DDI0601 2024-09.

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 | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 8baf57c06dbd..7db912a81bbd 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2595,6 +2595,27 @@ Sysreg	PMICNTR_EL0	3	3	9	4	0
 Field	63:0	ICNT
 EndSysreg
 
+Sysreg	PMICFILTR_EL0	3	3	9	6	0
+Res0	63:59
+Field	58	SYNC
+Field	57:56	VS
+Res0	55:32
+Field	31	P
+Field	30	U
+Field	29	NSK
+Field	28	NSU
+Field	27	NSH
+Field	26	M
+Res0	25
+Field	24	SH
+Field	23	T
+Field	22	RLK
+Field	21	RLU
+Field	20	RLH
+Res0	19:16
+Field	15:0	evtCount
+EndSysreg
+
 SysregFields	HFGxTR_EL2
 Field	63	nAMAIR2_EL1
 Field	62	nMAIR2_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:49 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:49 +0530
Subject: [PATCH V2 24/46] arm64/sysreg: Add register fields for SPMCR_EL0
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-25-anshuman.khandual@arm.com>

This adds register fields for SPMCR_EL0 as per the definitions based
on DDI0601 2024-09.

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 | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 7db912a81bbd..34323fe73188 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -165,6 +165,19 @@ Sysreg	PMCCNTSVR_EL1	2	0	14	11	7
 Field	63:0	CCNT
 EndSysreg
 
+Sysreg	SPMCR_EL0	2	3	9	12	0
+Res0	63:12
+Field	11	TR0
+Field	10	HDBG
+Field	9	FZ0
+Field	8	NA
+Res0	7:5
+Field	4	EX
+Res0	3:2
+Field	1	P
+Field	0	E
+EndSysreg
+
 Sysreg	SPMSCR_EL1	2	7	9	14	7
 Field	63:32	IMP_DEF
 Field	31	RAO
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:50 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:50 +0530
Subject: [PATCH V2 25/46] arm64/sysreg: Add register fields for SPMOVSCLR_EL0
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-26-anshuman.khandual@arm.com>

This adds register fields for SPMOVSCLR_EL0 as per the definitions based
on DDI0601 2024-09.

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 | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 34323fe73188..40de71614af7 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -178,6 +178,73 @@ Field	1	P
 Field	0	E
 EndSysreg
 
+Sysreg	SPMOVSCLR_EL0	2	3	9	12	3
+Field	63	P63
+Field	62	P62
+Field	61	P61
+Field	60	P60
+Field	59	P59
+Field	58	P58
+Field	57	P57
+Field	56	P56
+Field	55	P55
+Field	54	P54
+Field	53	P53
+Field	52	P52
+Field	51	P51
+Field	50	P50
+Field	49	P49
+Field	48	P48
+Field	47	P47
+Field	46	P46
+Field	45	P45
+Field	44	P44
+Field	43	P43
+Field	42	P42
+Field	41	P41
+Field	40	P40
+Field	39	P39
+Field	38	P38
+Field	37	P37
+Field	36	P36
+Field	35	P35
+Field	34	P34
+Field	33	P33
+Field	32	P32
+Field	31	P31
+Field	30	P30
+Field	29	P29
+Field	28	P28
+Field	27	P27
+Field	26	P26
+Field	25	P25
+Field	24	P24
+Field	23	P23
+Field	22	P22
+Field	21	P21
+Field	20	P20
+Field	19	P19
+Field	18	P18
+Field	17	P17
+Field	16	P16
+Field	15	P15
+Field	14	P14
+Field	13	P13
+Field	12	P12
+Field	11	P11
+Field	10	P10
+Field	9	P9
+Field	8	P8
+Field	7	P7
+Field	6	P6
+Field	5	P5
+Field	4	P4
+Field	3	P3
+Field	2	P2
+Field	1	P1
+Field	0	P0
+EndSysreg
+
 Sysreg	SPMSCR_EL1	2	7	9	14	7
 Field	63:32	IMP_DEF
 Field	31	RAO
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:51 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:51 +0530
Subject: [PATCH V2 26/46] arm64/sysreg: Add register fields for SPMOVSSET_EL0
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-27-anshuman.khandual@arm.com>

This adds register fields for SPMOVSSET_EL0 as per the definitions based
on DDI0601 2024-09.

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 | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 40de71614af7..c983c1360908 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -245,6 +245,73 @@ Field	1	P1
 Field	0	P0
 EndSysreg
 
+Sysreg	SPMOVSSET_EL0	2	3	9	14	3
+Field	63	P63
+Field	62	P62
+Field	61	P61
+Field	60	P60
+Field	59	P59
+Field	58	P58
+Field	57	P57
+Field	56	P56
+Field	55	P55
+Field	54	P54
+Field	53	P53
+Field	52	P52
+Field	51	P51
+Field	50	P50
+Field	49	P49
+Field	48	P48
+Field	47	P47
+Field	46	P46
+Field	45	P45
+Field	44	P44
+Field	43	P43
+Field	42	P42
+Field	41	P41
+Field	40	P40
+Field	39	P39
+Field	38	P38
+Field	37	P37
+Field	36	P36
+Field	35	P35
+Field	34	P34
+Field	33	P33
+Field	32	P32
+Field	31	P31
+Field	30	P30
+Field	29	P29
+Field	28	P28
+Field	27	P27
+Field	26	P26
+Field	25	P25
+Field	24	P24
+Field	23	P23
+Field	22	P22
+Field	21	P21
+Field	20	P20
+Field	19	P19
+Field	18	P18
+Field	17	P17
+Field	16	P16
+Field	15	P15
+Field	14	P14
+Field	13	P13
+Field	12	P12
+Field	11	P11
+Field	10	P10
+Field	9	P9
+Field	8	P8
+Field	7	P7
+Field	6	P6
+Field	5	P5
+Field	4	P4
+Field	3	P3
+Field	2	P2
+Field	1	P1
+Field	0	P0
+EndSysreg
+
 Sysreg	SPMSCR_EL1	2	7	9	14	7
 Field	63:32	IMP_DEF
 Field	31	RAO
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:52 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:52 +0530
Subject: [PATCH V2 27/46] arm64/sysreg: Add register fields for SPMINTENCLR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-28-anshuman.khandual@arm.com>

This adds register fields for SPMINTENCLR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index c983c1360908..0942cd16a942 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -161,6 +161,73 @@ Field	15:8	Aff1
 Field	7:0	Aff0
 EndSysreg
 
+Sysreg	SPMINTENCLR_EL1	2	0	9	14	2
+Field	63	P63
+Field	62	P62
+Field	61	P61
+Field	60	P60
+Field	59	P59
+Field	58	P58
+Field	57	P57
+Field	56	P56
+Field	55	P55
+Field	54	P54
+Field	53	P53
+Field	52	P52
+Field	51	P51
+Field	50	P50
+Field	49	P49
+Field	48	P48
+Field	47	P47
+Field	46	P46
+Field	45	P45
+Field	44	P44
+Field	43	P43
+Field	42	P42
+Field	41	P41
+Field	40	P40
+Field	39	P39
+Field	38	P38
+Field	37	P37
+Field	36	P36
+Field	35	P35
+Field	34	P34
+Field	33	P33
+Field	32	P32
+Field	31	P31
+Field	30	P30
+Field	29	P29
+Field	28	P28
+Field	27	P27
+Field	26	P26
+Field	25	P25
+Field	24	P24
+Field	23	P23
+Field	22	P22
+Field	21	P21
+Field	20	P20
+Field	19	P19
+Field	18	P18
+Field	17	P17
+Field	16	P16
+Field	15	P15
+Field	14	P14
+Field	13	P13
+Field	12	P12
+Field	11	P11
+Field	10	P10
+Field	9	P9
+Field	8	P8
+Field	7	P7
+Field	6	P6
+Field	5	P5
+Field	4	P4
+Field	3	P3
+Field	2	P2
+Field	1	P1
+Field	0	P0
+EndSysreg
+
 Sysreg	PMCCNTSVR_EL1	2	0	14	11	7
 Field	63:0	CCNT
 EndSysreg
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:53 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:53 +0530
Subject: [PATCH V2 28/46] arm64/sysreg: Add register fields for SPMINTENSET_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-29-anshuman.khandual@arm.com>

This adds register fields for SPMINTENSET_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 0942cd16a942..82fe720472cc 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -161,6 +161,73 @@ Field	15:8	Aff1
 Field	7:0	Aff0
 EndSysreg
 
+Sysreg	SPMINTENSET_EL1	2	0	9	14	1
+Field	63	P63
+Field	62	P62
+Field	61	P61
+Field	60	P60
+Field	59	P59
+Field	58	P58
+Field	57	P57
+Field	56	P56
+Field	55	P55
+Field	54	P54
+Field	53	P53
+Field	52	P52
+Field	51	P51
+Field	50	P50
+Field	49	P49
+Field	48	P48
+Field	47	P47
+Field	46	P46
+Field	45	P45
+Field	44	P44
+Field	43	P43
+Field	42	P42
+Field	41	P41
+Field	40	P40
+Field	39	P39
+Field	38	P38
+Field	37	P37
+Field	36	P36
+Field	35	P35
+Field	34	P34
+Field	33	P33
+Field	32	P32
+Field	31	P31
+Field	30	P30
+Field	29	P29
+Field	28	P28
+Field	27	P27
+Field	26	P26
+Field	25	P25
+Field	24	P24
+Field	23	P23
+Field	22	P22
+Field	21	P21
+Field	20	P20
+Field	19	P19
+Field	18	P18
+Field	17	P17
+Field	16	P16
+Field	15	P15
+Field	14	P14
+Field	13	P13
+Field	12	P12
+Field	11	P11
+Field	10	P10
+Field	9	P9
+Field	8	P8
+Field	7	P7
+Field	6	P6
+Field	5	P5
+Field	4	P4
+Field	3	P3
+Field	2	P2
+Field	1	P1
+Field	0	P0
+EndSysreg
+
 Sysreg	SPMINTENCLR_EL1	2	0	9	14	2
 Field	63	P63
 Field	62	P62
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:54 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:54 +0530
Subject: [PATCH V2 29/46] arm64/sysreg: Add register fields for SPMCNTENCLR_EL0
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-30-anshuman.khandual@arm.com>

This adds register fields for SPMCNTENCLR_EL0 as per the definitions based
on DDI0601 2024-09.

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 | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 82fe720472cc..9f278055fe77 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -312,6 +312,73 @@ Field	1	P
 Field	0	E
 EndSysreg
 
+Sysreg	SPMCNTENCLR_EL0	2	3	9	12	2
+Field	63	P63
+Field	62	P62
+Field	61	P61
+Field	60	P60
+Field	59	P59
+Field	58	P58
+Field	57	P57
+Field	56	P56
+Field	55	P55
+Field	54	P54
+Field	53	P53
+Field	52	P52
+Field	51	P51
+Field	50	P50
+Field	49	P49
+Field	48	P48
+Field	47	P47
+Field	46	P46
+Field	45	P45
+Field	44	P44
+Field	43	P43
+Field	42	P42
+Field	41	P41
+Field	40	P40
+Field	39	P39
+Field	38	P38
+Field	37	P37
+Field	36	P36
+Field	35	P35
+Field	34	P34
+Field	33	P33
+Field	32	P32
+Field	31	P31
+Field	30	P30
+Field	29	P29
+Field	28	P28
+Field	27	P27
+Field	26	P26
+Field	25	P25
+Field	24	P24
+Field	23	P23
+Field	22	P22
+Field	21	P21
+Field	20	P20
+Field	19	P19
+Field	18	P18
+Field	17	P17
+Field	16	P16
+Field	15	P15
+Field	14	P14
+Field	13	P13
+Field	12	P12
+Field	11	P11
+Field	10	P10
+Field	9	P9
+Field	8	P8
+Field	7	P7
+Field	6	P6
+Field	5	P5
+Field	4	P4
+Field	3	P3
+Field	2	P2
+Field	1	P1
+Field	0	P0
+EndSysreg
+
 Sysreg	SPMOVSCLR_EL0	2	3	9	12	3
 Field	63	P63
 Field	62	P62
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:55 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:55 +0530
Subject: [PATCH V2 30/46] arm64/sysreg: Add register fields for SPMCNTENSET_EL0
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-31-anshuman.khandual@arm.com>

This adds register fields for SPMCNTENSET_EL0 as per the definitions based
on DDI0601 2024-09.

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 | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 9f278055fe77..a7b8f5602163 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -312,6 +312,73 @@ Field	1	P
 Field	0	E
 EndSysreg
 
+Sysreg	SPMCNTENSET_EL0	2	3	9	12	1
+Field	63	P63
+Field	62	P62
+Field	61	P61
+Field	60	P60
+Field	59	P59
+Field	58	P58
+Field	57	P57
+Field	56	P56
+Field	55	P55
+Field	54	P54
+Field	53	P53
+Field	52	P52
+Field	51	P51
+Field	50	P50
+Field	49	P49
+Field	48	P48
+Field	47	P47
+Field	46	P46
+Field	45	P45
+Field	44	P44
+Field	43	P43
+Field	42	P42
+Field	41	P41
+Field	40	P40
+Field	39	P39
+Field	38	P38
+Field	37	P37
+Field	36	P36
+Field	35	P35
+Field	34	P34
+Field	33	P33
+Field	32	P32
+Field	31	P31
+Field	30	P30
+Field	29	P29
+Field	28	P28
+Field	27	P27
+Field	26	P26
+Field	25	P25
+Field	24	P24
+Field	23	P23
+Field	22	P22
+Field	21	P21
+Field	20	P20
+Field	19	P19
+Field	18	P18
+Field	17	P17
+Field	16	P16
+Field	15	P15
+Field	14	P14
+Field	13	P13
+Field	12	P12
+Field	11	P11
+Field	10	P10
+Field	9	P9
+Field	8	P8
+Field	7	P7
+Field	6	P6
+Field	5	P5
+Field	4	P4
+Field	3	P3
+Field	2	P2
+Field	1	P1
+Field	0	P0
+EndSysreg
+
 Sysreg	SPMCNTENCLR_EL0	2	3	9	12	2
 Field	63	P63
 Field	62	P62
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:56 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:56 +0530
Subject: [PATCH V2 31/46] arm64/sysreg: Add register fields for SPMSELR_EL0
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-32-anshuman.khandual@arm.com>

This adds register fields for SPMSELR_EL0 as per the definitions based
on DDI0601 2024-09.

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 | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a7b8f5602163..e57973b27e9c 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -513,6 +513,18 @@ Field	1	P1
 Field	0	P0
 EndSysreg
 
+Sysreg	SPMSELR_EL0	2	3	9	12	5
+Res0	63:10
+Field	9:4	SYSPMUSEL
+Res0	3:2
+UnsignedEnum	1:0	BANK
+	0b00	BANK_0
+	0b01	BANK_1
+	0b10	BANK_2
+	0b11	BANK_3
+EndEnum
+EndSysreg
+
 Sysreg	SPMOVSSET_EL0	2	3	9	14	3
 Field	63	P63
 Field	62	P62
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:57 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:57 +0530
Subject: [PATCH V2 32/46] arm64/sysreg: Add register fields for PMICNTSVR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-33-anshuman.khandual@arm.com>

This adds register fields for PMICNTSVR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index e57973b27e9c..b19b8e594524 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -299,6 +299,10 @@ Sysreg	PMCCNTSVR_EL1	2	0	14	11	7
 Field	63:0	CCNT
 EndSysreg
 
+Sysreg	PMICNTSVR_EL1	2	0	14	12	0
+Field	63:0	ICNT
+EndSysreg
+
 Sysreg	SPMCR_EL0	2	3	9	12	0
 Res0	63:12
 Field	11	TR0
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:58 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:58 +0530
Subject: [PATCH V2 33/46] arm64/sysreg: Add register fields for SPMIIDR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-34-anshuman.khandual@arm.com>

This adds register fields for SPMIIDR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index b19b8e594524..3b217ce3fe28 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -149,6 +149,14 @@ Field	3:2	P1
 Field	1:0	P0
 EndSysreg
 
+Sysreg	SPMIIDR_EL1	2	0	9	13	4
+Res0	63:32
+Field	31:20	ProductID
+Field	19:16	Variant
+Field	15:12	Revision
+Field	11:0	Implementer
+EndSysreg
+
 Sysreg	SPMDEVAFF_EL1	2	0	9	13	6
 Res0	63:40
 Field	39:32	Aff3
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:59 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:59 +0530
Subject: [PATCH V2 34/46] arm64/sysreg: Add register fields for SPMDEVARCH_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-35-anshuman.khandual@arm.com>

This adds register fields for SPMDEVARCH_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 3b217ce3fe28..d423bb218a9f 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -157,6 +157,15 @@ Field	15:12	Revision
 Field	11:0	Implementer
 EndSysreg
 
+Sysreg	SPMDEVARCH_EL1	2	0	9	13	5
+Res0	63:32
+Field	31:21	ARCHITECT
+Field	20	PRESENT
+Field	19:16	REVISION
+Field	15:12	ARCHVER
+Field	11:0	ARCHPART
+EndSysreg
+
 Sysreg	SPMDEVAFF_EL1	2	0	9	13	6
 Res0	63:40
 Field	39:32	Aff3
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:00 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:00 +0530
Subject: [PATCH V2 35/46] arm64/sysreg: Add register fields for SPMCFGR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-36-anshuman.khandual@arm.com>

This adds register fields for SPMCFGR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index d423bb218a9f..f4f5d22948ad 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -178,6 +178,24 @@ Field	15:8	Aff1
 Field	7:0	Aff0
 EndSysreg
 
+Sysreg	SPMCFGR_EL1	2	0	9	13	7
+Res0	63:32
+Field	31:28	NCG
+Res0	27:25
+Field	24	HDBG
+Field	23	TR0
+Field	22	SS
+Field	21	FZ0
+Field	20	MSI
+Field	19	RAO
+Res0	18
+Field	17	NA
+Field	16	EX
+Field	15:14	RAZ
+Field	13:8	SIZE
+Field	7:0	N
+EndSysreg
+
 Sysreg	SPMINTENSET_EL1	2	0	9	14	1
 Field	63	P63
 Field	62	P62
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:01 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:01 +0530
Subject: [PATCH V2 36/46] arm64/sysreg: Add register fields for PMSSCR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-37-anshuman.khandual@arm.com>

This adds register fields for PMSSCR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index f4f5d22948ad..c87017e69be1 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2863,6 +2863,13 @@ Res0	63:5
 Field	4:0	SEL
 EndSysreg
 
+Sysreg	PMSSCR_EL1	3	0	9	13	3
+Res0	63:33
+Field	32	NC
+Res0	31:1
+Field	0	SS
+EndSysreg
+
 Sysreg	PMUACR_EL1	3	0	9	14	4
 Res0	63:33
 Field	32	FM
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:02 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:02 +0530
Subject: [PATCH V2 37/46] arm64/sysreg: Add register fields for PMZR_EL0
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-38-anshuman.khandual@arm.com>

This adds register fields for PMZR_EL0 as per the definitions based
on DDI0601 2024-09.

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 | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index c87017e69be1..05f548b11470 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -3089,6 +3089,43 @@ Res0	19:16
 Field	15:0	evtCount
 EndSysreg
 
+Sysreg	PMZR_EL0	3	3	9	13	4
+Res0	63:33
+Field	32	FM
+Field	31	C
+Field	30	P30
+Field	29	P29
+Field	28	P28
+Field	27	P27
+Field	26	P26
+Field	25	P25
+Field	24	P24
+Field	23	P23
+Field	22	P22
+Field	21	P21
+Field	20	P20
+Field	19	P19
+Field	18	P18
+Field	17	P17
+Field	16	P16
+Field	15	P15
+Field	14	P14
+Field	13	P13
+Field	12	P12
+Field	11	P11
+Field	10	P10
+Field	9	P9
+Field	8	P8
+Field	7	P7
+Field	6	P6
+Field	5	P5
+Field	4	P4
+Field	3	P3
+Field	2	P2
+Field	1	P1
+Field	0	P0
+EndSysreg
+
 SysregFields	HFGxTR_EL2
 Field	63	nAMAIR2_EL1
 Field	62	nMAIR2_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:03 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:03 +0530
Subject: [PATCH V2 38/46] arm64/sysreg: Add register fields for SPMCGCR0_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-39-anshuman.khandual@arm.com>

This adds register fields for SPMCGCR0_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 05f548b11470..e97572c4f370 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -114,6 +114,21 @@ Res0	63:1
 Field	0	OSLK
 EndSysreg
 
+SysregFields	SPMCGCRx_EL1
+Field	63:56	N7
+Field	55:48	N6
+Field	47:40	N5
+Field	39:32	N4
+Field	31:24	N3
+Field	23:16	N2
+Field	15:8	N1
+Field	7:0	N0
+EndSysregFields
+
+Sysreg	SPMCGCR0_EL1	2	0	9	13	0
+Fields	SPMCGCRx_EL1
+EndSysreg
+
 Sysreg	SPMACCESSR_EL1	2	0	9	13	3
 Field	63:62	P31
 Field	61:60	P30
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:04 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:04 +0530
Subject: [PATCH V2 39/46] arm64/sysreg: Add register fields for SPMCGCR1_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-40-anshuman.khandual@arm.com>

This adds register fields for SPMCGCR1_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index e97572c4f370..819163d1c673 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -129,6 +129,10 @@ Sysreg	SPMCGCR0_EL1	2	0	9	13	0
 Fields	SPMCGCRx_EL1
 EndSysreg
 
+Sysreg	SPMCGCR1_EL1    2       0       9       13      1
+Fields	SPMCGCRx_EL1
+EndSysreg
+
 Sysreg	SPMACCESSR_EL1	2	0	9	13	3
 Field	63:62	P31
 Field	61:60	P30
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:05 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:05 +0530
Subject: [PATCH V2 40/46] arm64/sysreg: Add register fields for MDSTEPOP_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-41-anshuman.khandual@arm.com>

This adds register fields for MDSTEPOP_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 819163d1c673..68dee898743e 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -104,6 +104,11 @@ EndEnum
 Res0	3:0
 EndSysreg
 
+Sysreg	MDSTEPOP_EL1	2	0	0	5	2
+Res0	63:32
+Field	31:0	OPCODE
+EndSysreg
+
 Sysreg	OSECCR_EL1	2	0	0	6	2
 Res0	63:32
 Field	31:0	EDECCR
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:06 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:06 +0530
Subject: [PATCH V2 41/46] arm64/sysreg: Add register fields for ERXGSR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-42-anshuman.khandual@arm.com>

This adds register fields for ERXGSR_EL1 as per the definitions based on
DDI0601 2024-09.

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 | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 68dee898743e..2e732ea1dfb1 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -3928,6 +3928,73 @@ Field	15:8	Attr1
 Field	7:0	Attr0
 EndSysregFields
 
+Sysreg ERXGSR_EL1	3	0	5	3	2
+Field	63	S63
+Field	62	S62
+Field	61	S61
+Field	60	S60
+Field	59	S59
+Field	58	S58
+Field	57	S57
+Field	56	S56
+Field	55	S55
+Field	54	S54
+Field	53	S53
+Field	52	S52
+Field	51	S51
+Field	50	S50
+Field	49	S49
+Field	48	S48
+Field	47	S47
+Field	46	S46
+Field	45	S45
+Field	44	S44
+Field	43	S43
+Field	42	S42
+Field	41	S41
+Field	40	S40
+Field	39	S39
+Field	38	S38
+Field	37	S37
+Field	36	S36
+Field	35	S35
+Field	34	S34
+Field	33	S33
+Field	32	S32
+Field	31	S31
+Field	30	S30
+Field	29	S29
+Field	28	S28
+Field	27	S27
+Field	26	S26
+Field	25	S25
+Field	24	S24
+Field	23	S23
+Field	22	S22
+Field	21	S21
+Field	20	S20
+Field	19	S19
+Field	18	S18
+Field	17	S17
+Field	16	S16
+Field	15	S15
+Field	14	S14
+Field	13	S13
+Field	12	S12
+Field	11	S11
+Field	10	S10
+Field	9	S9
+Field	8	S8
+Field	7	S7
+Field	6	S6
+Field	5	S5
+Field	4	S4
+Field	3	S3
+Field	2	S2
+Field	1	S1
+Field	0	S0
+EndSysreg
+
 Sysreg	MAIR2_EL1	3	0	10	2	1
 Fields	MAIR2_ELx
 EndSysreg
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:07 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:07 +0530
Subject: [PATCH V2 42/46] arm64/sysreg: Add register fields for SPMACCESSR_EL2
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-43-anshuman.khandual@arm.com>

This adds register fields for SPMACCESSR_EL2 as per the definitions based
on DDI0601 2024-09.

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 | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 2e732ea1dfb1..8a6957cfa0e4 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -655,6 +655,41 @@ Field	1	P1
 Field	0	P0
 EndSysreg
 
+Sysreg	SPMACCESSR_EL2	2	4	9	13	3
+Field	63:62	P31
+Field	61:60	P30
+Field	59:58	P29
+Field	57:56	P28
+Field	55:54	P27
+Field	53:52	P26
+Field	51:50	P25
+Field	49:48	P24
+Field	47:46	P23
+Field	45:44	P22
+Field	43:42	P21
+Field	41:40	P20
+Field	39:38	P19
+Field	37:36	P18
+Field	35:34	P17
+Field	33:32	P16
+Field	31:30	P15
+Field	29:28	P14
+Field	27:26	P13
+Field	25:24	P12
+Field	23:22	P11
+Field	21:20	P10
+Field	19:18	P9
+Field	17:16	P8
+Field	15:14	P7
+Field	13:12	P6
+Field	11:10	P5
+Field	9:8	P4
+Field	7:6	P3
+Field	5:4	P2
+Field	3:2	P1
+Field	1:0	P0
+EndSysreg
+
 Sysreg	SPMSCR_EL1	2	7	9	14	7
 Field	63:32	IMP_DEF
 Field	31	RAO
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:08 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:08 +0530
Subject: [PATCH V2 43/46] arm64/sysreg: Add remaining debug registers affected by HDFGxTR2_EL2
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-44-anshuman.khandual@arm.com>

The HDFGxTR2_EL2 registers trap a set of debug and trace related registers.
Almost all of those register encodings have been added in the tools sysreg
format. Let's also add all the remaining encodings which are formula based
(and only that, because we really don't care about what these registers
actually do at this stage).

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/include/asm/sysreg.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index b8303a83c0bf..d1e3737a8ff8 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -270,6 +270,12 @@
 #define SYS_TRCVMIDCCTLR1		sys_reg(2, 1, 3, 3, 2)
 #define SYS_TRCVMIDCVR(m)		sys_reg(2, 1, 3, ((m & 7) << 1), 1)
 
+#define SYS_SPMEVCNTR_EL0(m)		sys_reg(2, 3, 14, (0 | (m >> 3)), (m & 7))
+#define SYS_SPMEVTYPER_EL0(m)		sys_reg(2, 3, 14, (2 | (m >> 3)), (m & 7))
+#define SYS_SPMEVFILTR_EL0(m)		sys_reg(2, 3, 14, (4 | (m >> 3)), (m & 7))
+#define SYS_SPMEVFILT2R_EL0(m)		sys_reg(2, 3, 14, (6 | (m >> 3)), (m & 7))
+#define SYS_PMEVCNTSVR_EL1(m)		sys_reg(2, 0, 14, (8 | (m >> 3)), (m & 7))
+
 /* ETM */
 #define SYS_TRCOSLAR			sys_reg(2, 1, 1, 0, 4)
 
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:25 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:25 +0530
Subject: [PATCH V2 00/46] KVM: arm64: Enable FGU (Fine Grained Undefined) for FEAT_FGT2 registers
Message-ID: <20241210055311.780688-1-anshuman.khandual@arm.com>

This series enables fine grained undefined for FEAT_FGT2 managed registers
via adding their respective FGT and CGT trap configuration. But first this
adds many system register definitions in tools/sysreg, which are required
there after.

patches 1-43: define system registers in tools/sysreg format
patch     44: enables FEAT_FGT2 registers access from virtual EL2
patch     45: enables FGT for FEAT_FGT2
patch     46: enables CGT for FEAT_FGT2

Some notes:

As kvm_has_feat() does not support non-ID registers following replacements
have been made for validating presence of correspnding features

- ID_AA64DFR0_EL1.ExtTrcBuff is tested for HDFGRTR2_EL2.nPMSDSFR_EL1
- ID_AA64DFR0_EL1.PMSVer is tested for HDFGRTR2_EL2.nPMSDSFR_EL1

Following FGT enabled registers don't have corresponding CGT requirements

- TRCITECR_EL1
- PMSSCR_EL1
- PMCCNTSVR_EL1
- PMICNTSVR_EL1
- RCWSMASK_EL1
- ERXGSR_EL1
- PFAR_EL1

This series applies on v6.13-rc1

Changes in V2:

- Dropped patches for ID_AA64DFR0_EL1 and ID_AA64DFR2_EL1 (changes merged mainline)
- Added patch for ID_AA64MMFR4_EL1
- Updated all tools sysreg definitions as per DDI0601 2024-09
- Added HFGITR2_EL2 register based fields in encoding_to_fgt[]
- Updated HFGITR2_EL2_[nDCCIVAPS|TSBCSYNC] in kvm_init_nv_sysregs()
- Updated HFGITR2_EL2_[nDCCIVAPS|TSBCSYNC] in kvm_calculate_traps()
- Dropped check_cntr_accessible_N and CGT_CNTR_ACCESSIBLE_N constructs
- SYS_PMEVCNTSVR_EL1(N) access traps have been forwarded to CGT_MDCR_HPMN
- Updated check_mdcr_hpmn() to handle SYS_PMEVCNTSVR_EL1(N) registers
- Changed behaviour as BEHAVE_FORWARD_RW for CGT_MDCR_EnSPM

Changes in V1:

https://lore.kernel.org/all/20241001024356.1096072-1-anshuman.khandual at arm.com/

- Added all system register definitions required for FEAT_FGT2 traps
- Added all system register access traps managed with new FEAT_FGT2
  i.e HDFGRTR2_EL2, HDFGWTR2_EL2, HFGRTR2_GROUP, HFGWTR2_GROUP and
  HFGITR2_GROUP for their VNCR access, FGT and CGT
- Added all FGT for all register accesses managed with FEAT_FGT2
- Added all CGT for all register accesses managed with FEAT_FGT2

Changes in RFC V1:

https://lore.kernel.org/linux-arm-kernel/20240620065807.151540-1-anshuman.khandual at arm.com/

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: Mark Brown <broonie at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.linux.dev
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (46):
  arm64/sysreg: Update register fields for ID_AA64MMFR0_EL1
  arm64/sysreg: Update register fields for ID_AA64MMFR4_EL1
  arm64/sysreg: Update register fields for ID_AA64PFR0_EL1
  arm64/sysreg: Update register fields for TRBIDR_EL1
  arm64/sysreg: Add register fields for HDFGRTR2_EL2
  arm64/sysreg: Add register fields for HDFGWTR2_EL2
  arm64/sysreg: Add register fields for HFGITR2_EL2
  arm64/sysreg: Add register fields for HFGRTR2_EL2
  arm64/sysreg: Add register fields for HFGWTR2_EL2
  arm64/sysreg: Add register fields for MDSELR_EL1
  arm64/sysreg: Add register fields for PMSIDR_EL1
  arm64/sysreg: Add register fields for TRBMPAM_EL1
  arm64/sysreg: Add register fields for PMSDSFR_EL1
  arm64/sysreg: Add register fields for SPMDEVAFF_EL1
  arm64/sysreg: Add register fields for PFAR_EL1
  arm64/sysreg: Add register fields for PMIAR_EL1
  arm64/sysreg: Add register fields for PMECR_EL1
  arm64/sysreg: Add register fields for PMUACR_EL1
  arm64/sysreg: Add register fields for PMCCNTSVR_EL1
  arm64/sysreg: Add register fields for SPMSCR_EL1
  arm64/sysreg: Add register fields for SPMACCESSR_EL1
  arm64/sysreg: Add register fields for PMICNTR_EL0
  arm64/sysreg: Add register fields for PMICFILTR_EL0
  arm64/sysreg: Add register fields for SPMCR_EL0
  arm64/sysreg: Add register fields for SPMOVSCLR_EL0
  arm64/sysreg: Add register fields for SPMOVSSET_EL0
  arm64/sysreg: Add register fields for SPMINTENCLR_EL1
  arm64/sysreg: Add register fields for SPMINTENSET_EL1
  arm64/sysreg: Add register fields for SPMCNTENCLR_EL0
  arm64/sysreg: Add register fields for SPMCNTENSET_EL0
  arm64/sysreg: Add register fields for SPMSELR_EL0
  arm64/sysreg: Add register fields for PMICNTSVR_EL1
  arm64/sysreg: Add register fields for SPMIIDR_EL1
  arm64/sysreg: Add register fields for SPMDEVARCH_EL1
  arm64/sysreg: Add register fields for SPMCFGR_EL1
  arm64/sysreg: Add register fields for PMSSCR_EL1
  arm64/sysreg: Add register fields for PMZR_EL0
  arm64/sysreg: Add register fields for SPMCGCR0_EL1
  arm64/sysreg: Add register fields for SPMCGCR1_EL1
  arm64/sysreg: Add register fields for MDSTEPOP_EL1
  arm64/sysreg: Add register fields for ERXGSR_EL1
  arm64/sysreg: Add register fields for SPMACCESSR_EL2
  arm64/sysreg: Add remaining debug registers affected by HDFGxTR2_EL2
  KVM: arm64: nv: Add FEAT_FGT2 registers access from virtual EL2
  KVM: arm64: nv: Add FEAT_FGT2 registers based FGU handling
  KVM: arm64: nv: Add trap forwarding for FEAT_FGT2 described registers

 arch/arm64/include/asm/kvm_arm.h        |   20 +
 arch/arm64/include/asm/kvm_host.h       |   12 +
 arch/arm64/include/asm/sysreg.h         |   10 +
 arch/arm64/include/asm/vncr_mapping.h   |    5 +
 arch/arm64/kvm/emulate-nested.c         |  345 ++++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h |   26 +
 arch/arm64/kvm/nested.c                 |   58 ++
 arch/arm64/kvm/sys_regs.c               |   70 ++
 arch/arm64/tools/sysreg                 | 1031 ++++++++++++++++++++++-
 9 files changed, 1570 insertions(+), 7 deletions(-)

-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:26 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:26 +0530
Subject: [PATCH V2 01/46] arm64/sysreg: Update register fields for ID_AA64MMFR0_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-2-anshuman.khandual@arm.com>

This updates ID_AA64MMFR0_EL1.FGT and ID_AA64MMFR0_EL1.PARANGE register
fields as per the definitions based on DDI0601 2024-09.

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
Reviewed-by: Mark Brown <broonie at 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 b081b54d6d22..a6cbe0dcd63b 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1591,6 +1591,7 @@ EndEnum
 UnsignedEnum	59:56	FGT
 	0b0000	NI
 	0b0001	IMP
+	0b0010	FGT2
 EndEnum
 Res0	55:48
 UnsignedEnum	47:44	EXS
@@ -1652,6 +1653,7 @@ Enum	3:0	PARANGE
 	0b0100	44
 	0b0101	48
 	0b0110	52
+	0b0111	56
 EndEnum
 EndSysreg
 
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:27 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:27 +0530
Subject: [PATCH V2 02/46] arm64/sysreg: Update register fields for ID_AA64MMFR4_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-3-anshuman.khandual@arm.com>

This updates ID_AA64MMFR4_EL1 register as per the definitions based on
DDI0601 2024-09.

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 | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a6cbe0dcd63b..b5bda7c94689 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1872,12 +1872,21 @@ EndEnum
 EndSysreg
 
 Sysreg	ID_AA64MMFR4_EL1	3	0	0	7	4
-Res0	63:40
+Res0	63:48
+UnsignedEnum	47:44	SRMASK
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+Res0	43:40
 UnsignedEnum	39:36	E3DSE
 	0b0000	NI
 	0b0001	IMP
 EndEnum
-Res0	35:28
+Res0	35:32
+UnsignedEnum	31:28	RMEGDI
+	0b0000	NI
+	0b0001	IMP
+EndEnum
 SignedEnum	27:24	E2H0
 	0b0000	IMP
 	0b1110	NI_NV1
@@ -1886,6 +1895,7 @@ EndEnum
 UnsignedEnum	23:20	NV_frac
 	0b0000	NV_NV2
 	0b0001	NV2_ONLY
+	0b0010	SOFTWARE
 EndEnum
 UnsignedEnum	19:16	FGWTE3
 	0b0000	NI
@@ -1905,7 +1915,10 @@ SignedEnum	7:4	EIESB
 	0b0010	ToELx
 	0b1111	ANY
 EndEnum
-Res0	3:0
+UnsignedEnum	3:0	PoPS
+	0b0000	NI
+	0b0001	IMP
+EndEnum
 EndSysreg
 
 Sysreg	SCTLR_EL1	3	0	1	0	0
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:28 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:28 +0530
Subject: [PATCH V2 03/46] arm64/sysreg: Update register fields for ID_AA64PFR0_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-4-anshuman.khandual@arm.com>

This updates ID_AA64PFR0_EL1.RAS and ID_AA64PFR0_EL1.RME register fields as
per the definitions based on DDI0601 2024-09.

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 | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index b5bda7c94689..59351931d907 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -873,6 +873,8 @@ EndEnum
 UnsignedEnum	55:52	RME
 	0b0000	NI
 	0b0001	IMP
+	0b0010	GPC2
+	0b0011	GPC3
 EndEnum
 UnsignedEnum	51:48	DIT
 	0b0000	NI
@@ -899,6 +901,7 @@ UnsignedEnum	31:28	RAS
 	0b0000	NI
 	0b0001	IMP
 	0b0010	V1P1
+	0b0011	V2
 EndEnum
 UnsignedEnum	27:24	GIC
 	0b0000	NI
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:29 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:29 +0530
Subject: [PATCH V2 04/46] arm64/sysreg: Update register fields for TRBIDR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-5-anshuman.khandual@arm.com>

This adds register fields for TRBIDR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 59351931d907..10b1a0998d99 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -3295,13 +3295,24 @@ Field	31:0	TRG
 EndSysreg
 
 Sysreg	TRBIDR_EL1	3	0	9	11	7
-Res0	63:12
+Res0	63:48
+Field	47:32	MaxBuffSize
+Res0	31:16
+UnsignedEnum	15:12	MPAM
+	0b0000	NI
+	0b0001	PMG
+	0b0010	IMP
+EndEnum
 Enum	11:8	EA
 	0b0000	NON_DESC
 	0b0001	IGNORE
 	0b0010	SERROR
 EndEnum
-Res0	7:6
+UnsignedEnum 7:6	AddrMode
+	0b00	VIRT_PHYS
+	0b01	VIRT_ONLY
+	0b10	PHYS_ONLY
+EndEnum
 Field	5	F
 Field	4	P
 Field	3:0	Align
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:30 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:30 +0530
Subject: [PATCH V2 05/46] arm64/sysreg: Add register fields for HDFGRTR2_EL2
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-6-anshuman.khandual@arm.com>

This adds register fields for HDFGRTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 10b1a0998d99..a56f7384d0db 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2562,6 +2562,35 @@ Field	1	ICIALLU
 Field	0	ICIALLUIS
 EndSysreg
 
+Sysreg HDFGRTR2_EL2	3	4	3	1	0
+Res0	63:25
+Field	24	nPMBMAR_EL1
+Field	23	nMDSTEPOP_EL1
+Field	22	nTRBMPAM_EL1
+Res0	21
+Field	20	nTRCITECR_EL1
+Field	19	nPMSDSFR_EL1
+Field	18	nSPMDEVAFF_EL1
+Field	17	nSPMID
+Field	16	nSPMSCR_EL1
+Field	15	nSPMACCESSR_EL1
+Field	14	nSPMCR_EL0
+Field	13	nSPMOVS
+Field	12	nSPMINTEN
+Field	11	nSPMCNTEN
+Field	10	nSPMSELR_EL0
+Field	9	nSPMEVTYPERn_EL0
+Field	8	nSPMEVCNTRn_EL0
+Field	7	nPMSSCR_EL1
+Field	6	nPMSSDATA
+Field	5	nMDSELR_EL1
+Field	4	nPMUACR_EL1
+Field	3	nPMICFILTR_EL0
+Field	2	nPMICNTR_EL0
+Field	1	nPMIAR_EL1
+Field	0	nPMECR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:31 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:31 +0530
Subject: [PATCH V2 06/46] arm64/sysreg: Add register fields for HDFGWTR2_EL2
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-7-anshuman.khandual@arm.com>

This adds register fields for HDFGWTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a56f7384d0db..1a7d8c03f844 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2591,6 +2591,34 @@ Field	1	nPMIAR_EL1
 Field	0	nPMECR_EL1
 EndSysreg
 
+Sysreg HDFGWTR2_EL2	3	4	3	1	1
+Res0	63:25
+Field	24	nPMBMAR_EL1
+Field	23	nMDSTEPOP_EL1
+Field	22	nTRBMPAM_EL1
+Field	21	nPMZR_EL0
+Field	20	nTRCITECR_EL1
+Field	19	nPMSDSFR_EL1
+Res0	18:17
+Field	16	nSPMSCR_EL1
+Field	15	nSPMACCESSR_EL1
+Field	14	nSPMCR_EL0
+Field	13	nSPMOVS
+Field	12	nSPMINTEN
+Field	11	nSPMCNTEN
+Field	10	nSPMSELR_EL0
+Field	9	nSPMEVTYPERn_EL0
+Field	8	nSPMEVCNTRn_EL0
+Field	7	nPMSSCR_EL1
+Res0	6
+Field	5	nMDSELR_EL1
+Field	4	nPMUACR_EL1
+Field	3	nPMICFILTR_EL0
+Field	2	nPMICNTR_EL0
+Field	1	nPMIAR_EL1
+Field	0	nPMECR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:32 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:32 +0530
Subject: [PATCH V2 07/46] arm64/sysreg: Add register fields for HFGITR2_EL2
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-8-anshuman.khandual@arm.com>

This adds register fields for HFGITR2_EL2 as per the definitions based
on DDI0601 2024-09.

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 | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 1a7d8c03f844..9d339f735648 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2791,6 +2791,12 @@ Field	1	AMEVCNTR00_EL0
 Field	0	AMCNTEN0
 EndSysreg
 
+Sysreg	HFGITR2_EL2	3	4	3	1	7
+Res0	63:2
+Field	1	nDCCIVAPS
+Field	0	TSBCSYNC
+EndSysreg
+
 Sysreg	ZCR_EL2	3	4	1	2	0
 Fields	ZCR_ELx
 EndSysreg
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:33 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:33 +0530
Subject: [PATCH V2 08/46] arm64/sysreg: Add register fields for HFGRTR2_EL2
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-9-anshuman.khandual@arm.com>

This adds register fields for HFGRTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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 | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 9d339f735648..9513ae05dc93 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2619,6 +2619,25 @@ Field	1	nPMIAR_EL1
 Field	0	nPMECR_EL1
 EndSysreg
 
+Sysreg	HFGRTR2_EL2	3	4	3	1	2
+Res0	63:15
+Field	14	nACTLRALIAS_EL1
+Field	13	nACTLRMASK_EL1
+Field	12	nTCR2ALIAS_EL1
+Field	11	nTCRALIAS_EL1
+Field	10	nSCTLRALIAS2_EL1
+Field	9	nSCTLRALIAS_EL1
+Field	8	nCPACRALIAS_EL1
+Field	7	nTCR2MASK_EL1
+Field	6	nTCRMASK_EL1
+Field	5	nSCTLR2MASK_EL1
+Field	4	nSCTLRMASK_EL1
+Field	3	nCPACRMASK_EL1
+Field	2	nRCWSMASK_EL1
+Field	1	nERXGSR_EL1
+Field	0	nPFAR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:34 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:34 +0530
Subject: [PATCH V2 09/46] arm64/sysreg: Add register fields for HFGWTR2_EL2
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-10-anshuman.khandual@arm.com>

This adds register fields for HFGWTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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 | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 9513ae05dc93..30a0d3ee71a7 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2638,6 +2638,25 @@ Field	1	nERXGSR_EL1
 Field	0	nPFAR_EL1
 EndSysreg
 
+Sysreg	HFGWTR2_EL2	3	4	3	1	3
+Res0	63:15
+Field	14	nACTLRALIAS_EL1
+Field	13	nACTLRMASK_EL1
+Field	12	nTCR2ALIAS_EL1
+Field	11	nTCRALIAS_EL1
+Field	10	nSCTLRALIAS2_EL1
+Field	9	nSCTLRALIAS_EL1
+Field	8	nCPACRALIAS_EL1
+Field	7	nTCR2MASK_EL1
+Field	6	nTCRMASK_EL1
+Field	5	nSCTLR2MASK_EL1
+Field	4	nSCTLRMASK_EL1
+Field	3	nCPACRMASK_EL1
+Field	2	nRCWSMASK_EL1
+Res0	1
+Field	0	nPFAR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:35 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:35 +0530
Subject: [PATCH V2 10/46] arm64/sysreg: Add register fields for MDSELR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-11-anshuman.khandual@arm.com>

This adds register fields for MDSELR_EL1 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 30a0d3ee71a7..be0091060350 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -93,6 +93,17 @@ Res0	63:32
 Field	31:0	DTRTX
 EndSysreg
 
+Sysreg	MDSELR_EL1	2	0	0	4	2
+Res0	63:6
+Enum	5:4	BANK
+	0b00	BANK_0
+	0b01	BANK_1
+	0b10	BANK_2
+	0b11	BANK_3
+EndEnum
+Res0	3:0
+EndSysreg
+
 Sysreg	OSECCR_EL1	2	0	0	6	2
 Res0	63:32
 Field	31:0	EDECCR
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:52:36 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:22:36 +0530
Subject: [PATCH V2 11/46] arm64/sysreg: Add register fields for PMSIDR_EL1
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-12-anshuman.khandual@arm.com>

This adds register fields for PMSIDR_EL1 as per the definitions based
on DDI0601 2024-09.

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 | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index be0091060350..a5e31e4c4474 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2172,7 +2172,16 @@ Field	15:0	MINLAT
 EndSysreg
 
 Sysreg	PMSIDR_EL1	3	0	9	9	7
-Res0	63:25
+Res0	63:33
+Field	32	SME
+UnsignedEnum	31:28	ALTCLK
+	0b0000	NI
+	0b0001	IMP
+	0b1111	IMP_DEF
+EndEnum
+Field	27	FPF
+Field	26	EFT
+Field	25	CRR
 Field	24	PBT
 Field	23:20	FORMAT
 Enum	19:16	COUNTSIZE
@@ -2190,7 +2199,10 @@ Enum	11:8	INTERVAL
 	0b0111	3072
 	0b1000	4096
 EndEnum
-Res0	7
+UnsignedEnum	7	FDS
+	0b0	NI
+	0b1	IMP
+EndEnum
 Field	6	FnE
 Field	5	ERND
 Field	4	LDS
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:09 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:09 +0530
Subject: [PATCH V2 44/46] KVM: arm64: nv: Add FEAT_FGT2 registers access from virtual EL2
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-45-anshuman.khandual@arm.com>

This adds VNCR-capable HDFGRTR2_EL2, HDFGWTR2_EL2, HFGRTR2_EL2, HFGWTR2_EL2
and HFGITR2_EL2 FEAT_FGT2 registers into enum vcpu_sysreg, and also enables
their access from virtual EL2 environment.

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: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.linux.dev
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/kvm_host.h     | 5 +++++
 arch/arm64/include/asm/vncr_mapping.h | 5 +++++
 arch/arm64/kvm/sys_regs.c             | 5 +++++
 3 files changed, 15 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e18e9244d17a..73ff8772ac22 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -548,6 +548,11 @@ enum vcpu_sysreg {
 	VNCR(HDFGWTR_EL2),
 	VNCR(HAFGRTR_EL2),
 
+	VNCR(HDFGRTR2_EL2),
+	VNCR(HDFGWTR2_EL2),
+	VNCR(HFGITR2_EL2),
+	VNCR(HFGRTR2_EL2),
+	VNCR(HFGWTR2_EL2),
 	VNCR(CNTVOFF_EL2),
 	VNCR(CNTV_CVAL_EL0),
 	VNCR(CNTV_CTL_EL0),
diff --git a/arch/arm64/include/asm/vncr_mapping.h b/arch/arm64/include/asm/vncr_mapping.h
index 4f9bbd4d6c26..d6110d7c36e2 100644
--- a/arch/arm64/include/asm/vncr_mapping.h
+++ b/arch/arm64/include/asm/vncr_mapping.h
@@ -38,6 +38,8 @@
 #define VNCR_HFGRTR_EL2		0x1B8
 #define VNCR_HFGWTR_EL2		0x1C0
 #define VNCR_HFGITR_EL2		0x1C8
+#define VNCR_HDFGRTR2_EL2	0x1A0
+#define VNCR_HDFGWTR2_EL2	0x1B0
 #define VNCR_HDFGRTR_EL2	0x1D0
 #define VNCR_HDFGWTR_EL2	0x1D8
 #define VNCR_ZCR_EL1            0x1E0
@@ -52,6 +54,9 @@
 #define VNCR_PIRE0_EL1		0x290
 #define VNCR_PIR_EL1		0x2A0
 #define VNCR_POR_EL1		0x2A8
+#define VNCR_HFGRTR2_EL2	0x2C0
+#define VNCR_HFGWTR2_EL2	0x2C8
+#define VNCR_HFGITR2_EL2	0x310
 #define VNCR_ICH_LR0_EL2        0x400
 #define VNCR_ICH_LR1_EL2        0x408
 #define VNCR_ICH_LR2_EL2        0x410
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 83c6b4a07ef5..c9e0e9322bd3 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3004,9 +3004,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG_VNCR(VTCR_EL2, reset_val, 0),
 
 	{ SYS_DESC(SYS_DACR32_EL2), undef_access, reset_unknown, DACR32_EL2 },
+	EL2_REG_VNCR(HDFGRTR2_EL2, reset_val, 0),
+	EL2_REG_VNCR(HDFGWTR2_EL2, reset_val, 0),
+	EL2_REG_VNCR(HFGRTR2_EL2, reset_val, 0),
+	EL2_REG_VNCR(HFGWTR2_EL2, reset_val, 0),
 	EL2_REG_VNCR(HDFGRTR_EL2, reset_val, 0),
 	EL2_REG_VNCR(HDFGWTR_EL2, reset_val, 0),
 	EL2_REG_VNCR(HAFGRTR_EL2, reset_val, 0),
+	EL2_REG_VNCR(HFGITR2_EL2, reset_val, 0),
 	EL2_REG_REDIR(SPSR_EL2, reset_val, 0),
 	EL2_REG_REDIR(ELR_EL2, reset_val, 0),
 	{ SYS_DESC(SYS_SP_EL1), access_sp_el1},
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:10 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:10 +0530
Subject: [PATCH V2 45/46] KVM: arm64: nv: Add FEAT_FGT2 registers based FGU handling
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-46-anshuman.khandual@arm.com>

This enables FEAT_FGT2 registers based FGU handling by adding the following
new groups in 'enum fgt_group_id' for all respective FGT control registers
and also adding FGU behaviour for their individual managed registers access
traps.

1. HDFGRTR2_GROUP
2. HDFGWTR2_GROUP
3. HFGRTR2_GROUP
4. HFGWTR2_GROUP
5. HFGITR2_GROUP

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: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.linux.dev
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V2:

- Added HFGITR2_EL2 register based fields in encoding_to_fgt[]
- Updated HFGITR2_EL2_[nDCCIVAPS|TSBCSYNC] in kvm_init_nv_sysregs()
- Updated HFGITR2_EL2_[nDCCIVAPS|TSBCSYNC] in kvm_calculate_traps()

 arch/arm64/include/asm/kvm_arm.h        |  20 +++
 arch/arm64/include/asm/kvm_host.h       |   5 +
 arch/arm64/include/asm/sysreg.h         |   4 +
 arch/arm64/kvm/emulate-nested.c         | 187 ++++++++++++++++++++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h |  26 ++++
 arch/arm64/kvm/nested.c                 |  58 ++++++++
 arch/arm64/kvm/sys_regs.c               |  65 ++++++++
 7 files changed, 365 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3e0f0de1d2da..5f725b7c9114 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -326,6 +326,26 @@
 #define __HFGRTR_EL2_MASK	GENMASK(49, 0)
 #define __HFGRTR_EL2_nMASK	~(__HFGRTR_EL2_RES0 | __HFGRTR_EL2_MASK)
 
+#define __HDFGRTR2_EL2_RES0	HDFGRTR2_EL2_RES0
+#define __HDFGRTR2_EL2_MASK	0
+#define __HDFGRTR2_EL2_nMASK	~(__HDFGRTR2_EL2_RES0 | __HDFGRTR2_EL2_MASK)
+
+#define __HDFGWTR2_EL2_RES0	HDFGWTR2_EL2_RES0
+#define __HDFGWTR2_EL2_MASK	0
+#define __HDFGWTR2_EL2_nMASK	~(__HDFGWTR2_EL2_RES0 | __HDFGWTR2_EL2_MASK)
+
+#define __HFGITR2_EL2_RES0	HFGITR2_EL2_RES0
+#define __HFGITR2_EL2_MASK	BIT(0)
+#define __HFGITR2_EL2_nMASK	~(__HFGITR2_EL2_RES0 | __HFGITR2_EL2_MASK)
+
+#define __HFGRTR2_EL2_RES0	HFGRTR2_EL2_RES0
+#define __HFGRTR2_EL2_MASK	0
+#define __HFGRTR2_EL2_nMASK	~(HFGRTR2_EL2_RES0 | __HFGRTR2_EL2_MASK)
+
+#define __HFGWTR2_EL2_RES0	HFGWTR2_EL2_RES0
+#define __HFGWTR2_EL2_MASK	0
+#define __HFGWTR2_EL2_nMASK	~(HFGWTR2_EL2_RES0 | __HFGWTR2_EL2_MASK)
+
 /*
  * The HFGWTR bits are a subset of HFGRTR bits. To ensure we don't miss any
  * future additions, define __HFGWTR* macros relative to __HFGRTR* ones.
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 73ff8772ac22..c80c07be3358 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -271,6 +271,11 @@ enum fgt_group_id {
 	HDFGWTR_GROUP = HDFGRTR_GROUP,
 	HFGITR_GROUP,
 	HAFGRTR_GROUP,
+	HDFGRTR2_GROUP,
+	HDFGWTR2_GROUP = HDFGRTR2_GROUP,
+	HFGRTR2_GROUP,
+	HFGWTR2_GROUP = HFGRTR2_GROUP,
+	HFGITR2_GROUP,
 
 	/* Must be last */
 	__NR_FGT_GROUP_IDS__
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index d1e3737a8ff8..2c10c56dea84 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -686,6 +686,10 @@
 #define TLBI_CRm_RNS	6	/* Range, Non-Sharable */
 #define TLBI_CRm_nRNS	7	/* non-Range, Non-Sharable */
 
+#define OP_TSB_CSYNC			0xD503225F
+#define OP_DC_CIVAPS			sys_insn(2, 0, 7, 15, 1)
+#define OP_DC_CIGDVAPS			sys_insn(2, 0, 7, 15, 5)
+
 #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)
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 1ffbfd1c3cf2..6c63cbfc11ea 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1933,6 +1933,163 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
 	SR_FGT(SYS_AMEVCNTR0_EL0(2),	HAFGRTR, AMEVCNTR02_EL0, 1),
 	SR_FGT(SYS_AMEVCNTR0_EL0(1),	HAFGRTR, AMEVCNTR01_EL0, 1),
 	SR_FGT(SYS_AMEVCNTR0_EL0(0),	HAFGRTR, AMEVCNTR00_EL0, 1),
+
+	/* HDFGRTR2_EL2 */
+	SR_FGT(SYS_MDSTEPOP_EL1,	HDFGRTR2, nMDSTEPOP_EL1, 0),
+	SR_FGT(SYS_TRBMPAM_EL1,		HDFGRTR2, nTRBMPAM_EL1, 0),
+	SR_FGT(SYS_TRCITECR_EL1,	HDFGRTR2, nTRCITECR_EL1, 0),
+	SR_FGT(SYS_PMSDSFR_EL1,		HDFGRTR2, nPMSDSFR_EL1, 0),
+	SR_FGT(SYS_SPMDEVAFF_EL1,	HDFGRTR2, nSPMDEVAFF_EL1, 0),
+
+	SR_FGT(SYS_SPMCGCR0_EL1,	HDFGRTR2, nSPMID, 0),
+	SR_FGT(SYS_SPMCGCR1_EL1,	HDFGRTR2, nSPMID, 0),
+	SR_FGT(SYS_SPMIIDR_EL1,		HDFGRTR2, nSPMID, 0),
+	SR_FGT(SYS_SPMDEVARCH_EL1,	HDFGRTR2, nSPMID, 0),
+	SR_FGT(SYS_SPMCFGR_EL1,		HDFGRTR2, nSPMID, 0),
+
+	SR_FGT(SYS_SPMSCR_EL1,		HDFGRTR2, nSPMSCR_EL1, 0),
+	SR_FGT(SYS_SPMACCESSR_EL1,	HDFGRTR2, nSPMACCESSR_EL1, 0),
+	SR_FGT(SYS_SPMCR_EL0,		HDFGRTR2, nSPMCR_EL0, 0),
+	SR_FGT(SYS_SPMOVSCLR_EL0,	HDFGRTR2, nSPMOVS, 0),
+	SR_FGT(SYS_SPMOVSSET_EL0,	HDFGRTR2, nSPMOVS, 0),
+	SR_FGT(SYS_SPMINTENCLR_EL1,	HDFGRTR2, nSPMINTEN, 0),
+	SR_FGT(SYS_SPMINTENSET_EL1,	HDFGRTR2, nSPMINTEN, 0),
+	SR_FGT(SYS_SPMCNTENCLR_EL0,	HDFGRTR2, nSPMCNTEN, 0),
+	SR_FGT(SYS_SPMCNTENSET_EL0,	HDFGRTR2, nSPMCNTEN, 0),
+	SR_FGT(SYS_SPMSELR_EL0,		HDFGRTR2, nSPMSELR_EL0, 0),
+
+	SR_FGT(SYS_SPMEVTYPER_EL0(0),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(1),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(2),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(3),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(4),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(5),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(6),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(7),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(8),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(9),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(10),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(11),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(12),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(13),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(14),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVTYPER_EL0(15),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+
+	SR_FGT(SYS_SPMEVFILTR_EL0(0),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(1),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(2),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(3),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(4),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(5),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(6),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(7),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(8),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(9),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(10),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(11),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(12),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(13),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(14),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILTR_EL0(15),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+
+	SR_FGT(SYS_SPMEVFILT2R_EL0(0),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(1),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(2),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(3),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(4),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(5),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(6),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(7),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(8),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(9),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(10),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(11),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(12),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(13),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(14),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+	SR_FGT(SYS_SPMEVFILT2R_EL0(15),	HDFGRTR2, nSPMEVTYPERn_EL0, 0),
+
+	SR_FGT(SYS_SPMEVCNTR_EL0(0),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(1),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(2),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(3),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(4),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(5),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(6),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(7),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(8),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(9),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(10),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(11),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(12),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(13),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(14),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+	SR_FGT(SYS_SPMEVCNTR_EL0(15),	HDFGRTR2, nSPMEVCNTRn_EL0, 0),
+
+	SR_FGT(SYS_PMSSCR_EL1,		HDFGRTR2, nPMSSCR_EL1, 0),
+	SR_FGT(SYS_PMCCNTSVR_EL1,	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMICNTSVR_EL1,	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(0),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(1),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(2),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(3),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(4),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(5),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(6),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(7),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(8),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(9),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(10),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(11),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(12),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(13),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(14),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(15),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(16),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(17),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(18),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(19),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(20),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(21),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(22),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(23),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(24),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(25),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(26),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(27),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(28),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(29),	HDFGRTR2, nPMSSDATA, 0),
+	SR_FGT(SYS_PMEVCNTSVR_EL1(30),	HDFGRTR2, nPMSSDATA, 0),
+
+	SR_FGT(SYS_MDSELR_EL1,		HDFGRTR2, nMDSELR_EL1, 0),
+	SR_FGT(SYS_PMUACR_EL1,		HDFGRTR2, nPMUACR_EL1, 0),
+	SR_FGT(SYS_PMICFILTR_EL0,	HDFGRTR2, nPMICFILTR_EL0, 0),
+	SR_FGT(SYS_PMICNTR_EL0,		HDFGRTR2, nPMICNTR_EL0, 0),
+	SR_FGT(SYS_PMIAR_EL1,		HDFGRTR2, nPMIAR_EL1, 0),
+	SR_FGT(SYS_PMECR_EL1,		HDFGRTR2, nPMECR_EL1, 0),
+
+	/*
+	 * HDFGWTR2_EL2
+	 *
+	 * Although HDFGRTR2_EL2 and HDFGWTR2_EL2 registers largely
+	 * overlap in their bit assignment, there are a number of bits
+	 * that are RES0 on one side, and an actual trap bit on the
+	 * other.  The policy chosen here is to describe all the
+	 * read-side mappings, and only the write-side mappings that
+	 * differ from the read side, and the trap handler will pick
+	 * the correct shadow register based on the access type.
+	 */
+	SR_FGT(SYS_PMZR_EL0,		HDFGWTR2, nPMZR_EL0, 0),
+
+	/* HFGRTR2_EL2 */
+	SR_FGT(SYS_RCWSMASK_EL1,	HFGRTR2, nRCWSMASK_EL1, 0),
+	SR_FGT(SYS_ERXGSR_EL1,		HFGRTR2, nERXGSR_EL1, 0),
+	SR_FGT(SYS_PFAR_EL1,		HFGRTR2, nPFAR_EL1, 0),
+
+	/* HFGITR2_EL2 */
+	SR_FGT(OP_DC_CIVAPS,		HFGITR2, nDCCIVAPS, 0),
+	SR_FGT(OP_DC_CIGDVAPS,		HFGITR2, nDCCIVAPS, 0),
+	SR_FGT(OP_TSB_CSYNC,		HFGITR2, TSBCSYNC, 1),
 };
 
 static union trap_config get_trap_config(u32 sysreg)
@@ -2197,6 +2354,14 @@ static bool check_fgt_bit(struct kvm_vcpu *vcpu, bool is_read,
 		sr = is_read ? HDFGRTR_EL2 : HDFGWTR_EL2;
 		break;
 
+	case HDFGRTR2_GROUP:
+		sr = is_read ? HDFGRTR2_EL2 : HDFGWTR2_EL2;
+		break;
+
+	case HFGRTR2_GROUP:
+		sr = is_read ? HFGRTR2_EL2 : HFGWTR2_EL2;
+		break;
+
 	case HAFGRTR_GROUP:
 		sr = HAFGRTR_EL2;
 		break;
@@ -2205,6 +2370,10 @@ static bool check_fgt_bit(struct kvm_vcpu *vcpu, bool is_read,
 		sr = HFGITR_EL2;
 		break;
 
+	case HFGITR2_GROUP:
+		sr = HFGITR2_EL2;
+		break;
+
 	default:
 		WARN_ONCE(1, "Unhandled FGT group");
 		return false;
@@ -2279,6 +2448,20 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
 			val = __vcpu_sys_reg(vcpu, HDFGWTR_EL2);
 		break;
 
+	case HDFGRTR2_GROUP:
+		if (is_read)
+			val = __vcpu_sys_reg(vcpu, HDFGRTR2_EL2);
+		else
+			val = __vcpu_sys_reg(vcpu, HDFGWTR2_EL2);
+		break;
+
+	case HFGRTR2_GROUP:
+		if (is_read)
+			val = __vcpu_sys_reg(vcpu, HFGRTR2_EL2);
+		else
+			val = __vcpu_sys_reg(vcpu, HFGWTR2_EL2);
+		break;
+
 	case HAFGRTR_GROUP:
 		val = __vcpu_sys_reg(vcpu, HAFGRTR_EL2);
 		break;
@@ -2298,6 +2481,10 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
 		}
 		break;
 
+	case HFGITR2_GROUP:
+		val = __vcpu_sys_reg(vcpu, HFGITR2_EL2);
+		break;
+
 	case __NR_FGT_GROUP_IDS__:
 		/* Something is really wrong, bail out */
 		WARN_ONCE(1, "__NR_FGT_GROUP_IDS__");
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 34f53707892d..e0da9f45acde 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -84,10 +84,21 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
 		case HFGITR_EL2:					\
 			id = HFGITR_GROUP;				\
 			break;						\
+		case HFGITR2_EL2:					\
+			id = HFGITR2_GROUP;				\
+			break;						\
 		case HDFGRTR_EL2:					\
 		case HDFGWTR_EL2:					\
 			id = HDFGRTR_GROUP;				\
 			break;						\
+		case HDFGRTR2_EL2:					\
+		case HDFGWTR2_EL2:					\
+			id = HDFGRTR2_GROUP;				\
+			break;						\
+		case HFGRTR2_EL2:					\
+		case HFGWTR2_EL2:					\
+			id = HFGRTR2_GROUP;				\
+			break;						\
 		case HAFGRTR_EL2:					\
 			id = HAFGRTR_GROUP;				\
 			break;						\
@@ -159,6 +170,11 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	CHECK_FGT_MASKS(HDFGWTR_EL2);
 	CHECK_FGT_MASKS(HAFGRTR_EL2);
 	CHECK_FGT_MASKS(HCRX_EL2);
+	CHECK_FGT_MASKS(HDFGRTR2_EL2);
+	CHECK_FGT_MASKS(HDFGWTR2_EL2);
+	CHECK_FGT_MASKS(HFGITR2_EL2);
+	CHECK_FGT_MASKS(HFGRTR2_EL2);
+	CHECK_FGT_MASKS(HFGWTR2_EL2);
 
 	if (!cpus_have_final_cap(ARM64_HAS_FGT))
 		return;
@@ -170,6 +186,11 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	update_fgt_traps(hctxt, vcpu, kvm, HFGITR_EL2);
 	update_fgt_traps(hctxt, vcpu, kvm, HDFGRTR_EL2);
 	update_fgt_traps(hctxt, vcpu, kvm, HDFGWTR_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HDFGRTR2_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HDFGWTR2_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HFGITR2_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HFGRTR2_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HFGWTR2_EL2);
 
 	if (cpu_has_amu())
 		update_fgt_traps(hctxt, vcpu, kvm, HAFGRTR_EL2);
@@ -199,6 +220,11 @@ static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	__deactivate_fgt(hctxt, vcpu, kvm, HFGITR_EL2);
 	__deactivate_fgt(hctxt, vcpu, kvm, HDFGRTR_EL2);
 	__deactivate_fgt(hctxt, vcpu, kvm, HDFGWTR_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HDFGRTR2_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HDFGWTR2_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HFGITR2_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HFGRTR2_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HFGWTR2_EL2);
 
 	if (cpu_has_amu())
 		__deactivate_fgt(hctxt, vcpu, kvm, HAFGRTR_EL2);
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 9b36218b48de..c208354aa929 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1155,6 +1155,52 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		res0 |= HDFGRTR_EL2_nPMSNEVFR_EL1;
 	set_sysreg_masks(kvm, HDFGRTR_EL2, res0 | HDFGRTR_EL2_RES0, res1);
 
+	/* HDFG[RW]TR2_EL2 */
+	res0 = res1 = 0;
+	if (!kvm_has_feat_enum(kvm, ID_AA64DFR2_EL1, STEP, IMP))
+		res0 |= HDFGRTR2_EL2_nMDSTEPOP_EL1;
+	if (!kvm_has_feat_enum(kvm, ID_AA64DFR0_EL1, ExtTrcBuff, IMP))
+		res0 |= HDFGRTR2_EL2_nTRBMPAM_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, ITE, IMP))
+		res0 |= HDFGRTR2_EL2_nTRCITECR_EL1;
+	if (!kvm_has_feat_enum(kvm, ID_AA64DFR0_EL1, PMSVer, V1P4))
+		res0 |= HDFGRTR2_EL2_nPMSDSFR_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, SPMU, IMP))
+		res0 |= (HDFGRTR2_EL2_nSPMDEVAFF_EL1 | HDFGRTR2_EL2_nSPMID |
+			 HDFGRTR2_EL2_nSPMSCR_EL1 | HDFGRTR2_EL2_nSPMACCESSR_EL1 |
+			 HDFGRTR2_EL2_nSPMCR_EL0 | HDFGRTR2_EL2_nSPMOVS |
+			 HDFGRTR2_EL2_nSPMINTEN | HDFGRTR2_EL2_nSPMCNTEN |
+			 HDFGRTR2_EL2_nSPMSELR_EL0 | HDFGRTR2_EL2_nSPMEVTYPERn_EL0 |
+			 HDFGRTR2_EL2_nSPMEVCNTRn_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSS, IMP))
+		res0 |=	(HDFGRTR2_EL2_nPMSSCR_EL1 | HDFGRTR2_EL2_nPMSSDATA);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DebugVer, V8P9))
+		res0 |= HDFGRTR2_EL2_nMDSELR_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, V3P9))
+		res0 |= HDFGRTR2_EL2_nPMUACR_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, PMICNTR, IMP))
+		res0 |= (HDFGRTR2_EL2_nPMICFILTR_EL0 | HDFGRTR2_EL2_nPMICNTR_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, SEBEP, IMP))
+		res0 |= HDFGRTR2_EL2_nPMIAR_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, EBEP, IMP) &&
+	    !kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSS, IMP))
+		res0 |= HDFGRTR2_EL2_nPMECR_EL1;
+	set_sysreg_masks(kvm, HDFGRTR2_EL2, res0 | HDFGRTR2_EL2_RES0, res1 | HDFGRTR2_EL2_RES1);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, V3P9))
+		res0 |= HDFGWTR2_EL2_nPMZR_EL0;
+	set_sysreg_masks(kvm, HDFGWTR2_EL2, res0 | HDFGWTR2_EL2_RES0, res1 | HDFGWTR2_EL2_RES1);
+
+	/* HFG[R|W]TR2_EL2 */
+	res0 = res1 = 0;
+	if (!kvm_has_feat_enum(kvm, ID_AA64PFR1_EL1, THE, IMP))
+		res0 |= HFGRTR2_EL2_nRCWSMASK_EL1;
+	if (!kvm_has_feat_enum(kvm, ID_AA64PFR0_EL1, RAS, V2))
+		res0 |= HFGRTR2_EL2_nERXGSR_EL1;
+	if (!kvm_has_feat_enum(kvm, ID_AA64PFR1_EL1, PFAR, IMP))
+		res0 |= HFGRTR2_EL2_nPFAR_EL1;
+	set_sysreg_masks(kvm, HFGRTR2_EL2, res0 | HFGRTR2_EL2_RES0, res1 | HFGRTR2_EL2_RES1);
+	set_sysreg_masks(kvm, HFGWTR2_EL2, res0 | HFGWTR2_EL2_RES0, res1 | HFGWTR2_EL2_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);
@@ -1198,6 +1244,18 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		res0 |= HFGITR_EL2_ATS1E1A;
 	set_sysreg_masks(kvm, HFGITR_EL2, res0, res1);
 
+	/* HFGITR2_EL2 */
+	res0 = HFGITR2_EL2_RES0;
+	res1 = HFGITR2_EL2_RES1;
+	if (!kvm_has_feat_enum(kvm, ID_AA64MMFR4_EL1, PoPS, IMP))
+		res0 |= HFGITR2_EL2_nDCCIVAPS;
+
+	if (!kvm_has_feat_enum(kvm, ID_AA64DFR0_EL1, TraceBuffer, TRBE_V1P1))
+		res0 |= HFGITR2_EL2_TSBCSYNC;
+
+	set_sysreg_masks(kvm, HFGITR2_EL2, res0 | HFGITR2_EL2_RES0, res1 | HFGITR2_EL2_RES1);
+	set_sysreg_masks(kvm, HFGITR2_EL2, res0 | HFGITR2_EL2_RES0, res1 | HFGITR2_EL2_RES1);
+
 	/* HAFGRTR_EL2 - not a lot to see here */
 	res0 = HAFGRTR_EL2_RES0;
 	res1 = HAFGRTR_EL2_RES1;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index c9e0e9322bd3..b6d34023729c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -4977,6 +4977,71 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
 		kvm->arch.fgu[HAFGRTR_GROUP] |= ~(HAFGRTR_EL2_RES0 |
 						  HAFGRTR_EL2_RES1);
 
+	if (!kvm_has_feat_enum(kvm, ID_AA64DFR2_EL1, STEP, IMP))
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nMDSTEPOP_EL1;
+
+	if (!kvm_has_feat_enum(kvm, ID_AA64DFR0_EL1, ExtTrcBuff, IMP))
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nTRBMPAM_EL1;
+
+	if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, ITE, IMP))
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nTRCITECR_EL1;
+
+	if (!kvm_has_feat_enum(kvm, ID_AA64DFR0_EL1, PMSVer, V1P4))
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nPMSDSFR_EL1;
+
+	if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, SPMU, IMP))
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nSPMDEVAFF_EL1	|
+						 HDFGRTR2_EL2_nSPMID		|
+						 HDFGRTR2_EL2_nSPMSCR_EL1	|
+						 HDFGRTR2_EL2_nSPMACCESSR_EL1	|
+						 HDFGRTR2_EL2_nSPMCR_EL0	|
+						 HDFGRTR2_EL2_nSPMOVS		|
+						 HDFGRTR2_EL2_nSPMINTEN		|
+						 HDFGRTR2_EL2_nSPMCNTEN		|
+						 HDFGRTR2_EL2_nSPMSELR_EL0	|
+						 HDFGRTR2_EL2_nSPMEVTYPERn_EL0	|
+						 HDFGRTR2_EL2_nSPMEVCNTRn_EL0;
+
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSS, IMP)) {
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nPMSSCR_EL1;
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nPMSSDATA;
+	}
+
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DebugVer, V8P9))
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nMDSELR_EL1;
+
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, V3P9)) {
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nPMUACR_EL1;
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGWTR2_EL2_nPMZR_EL0;
+	}
+
+	if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, PMICNTR, IMP)) {
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nPMICFILTR_EL0;
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nPMICNTR_EL0;
+	}
+
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, SEBEP, IMP))
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nPMIAR_EL1;
+
+	if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, EBEP, IMP) &&
+	    !kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSS, IMP))
+		kvm->arch.fgu[HDFGRTR2_GROUP] |= HDFGRTR2_EL2_nPMECR_EL1;
+
+	if (!kvm_has_feat_enum(kvm, ID_AA64PFR1_EL1, THE, IMP))
+		kvm->arch.fgu[HFGRTR2_GROUP] |= HFGRTR2_EL2_nRCWSMASK_EL1;
+
+	if (!kvm_has_feat_enum(kvm, ID_AA64PFR0_EL1, RAS, V2))
+		kvm->arch.fgu[HFGRTR2_GROUP] |= HFGRTR2_EL2_nERXGSR_EL1;
+
+	if (!kvm_has_feat_enum(kvm, ID_AA64PFR1_EL1, PFAR, IMP))
+		kvm->arch.fgu[HFGRTR2_GROUP] |= HFGRTR2_EL2_nPFAR_EL1;
+
+	if (!kvm_has_feat_enum(kvm, ID_AA64MMFR4_EL1, PoPS, IMP))
+		kvm->arch.fgu[HFGITR2_GROUP] |= HFGITR2_EL2_nDCCIVAPS;
+
+	if (!kvm_has_feat_enum(kvm, ID_AA64DFR0_EL1, TraceBuffer, TRBE_V1P1))
+		kvm->arch.fgu[HFGITR2_GROUP] |= HFGITR2_EL2_TSBCSYNC;
+
 	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Dec  9 21:53:11 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 11:23:11 +0530
Subject: [PATCH V2 46/46] KVM: arm64: nv: Add trap forwarding for FEAT_FGT2 described registers
In-Reply-To: <20241210055311.780688-1-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
Message-ID: <20241210055311.780688-47-anshuman.khandual@arm.com>

Describe remaining MDCR_EL2 register, and associate that with all FEAT_FGT2
exposed system registers it allows to trap.

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: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.linux.dev
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V2:

- Dropped check_cntr_accessible_N and CGT_CNTR_ACCESSIBLE_N constructs
- SYS_PMEVCNTSVR_EL1(N) access traps have been forwarded to CGT_MDCR_HPMN
- Updated check_mdcr_hpmn() to handle SYS_PMEVCNTSVR_EL1(N) registers
- Changed behaviour as BEHAVE_FORWARD_RW for CGT_MDCR_EnSPM

 arch/arm64/include/asm/kvm_host.h |   2 +
 arch/arm64/kvm/emulate-nested.c   | 158 ++++++++++++++++++++++++++++++
 2 files changed, 160 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index c80c07be3358..4cdce62642d1 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -441,6 +441,7 @@ enum vcpu_sysreg {
 	PMINTENSET_EL1,	/* Interrupt Enable Set Register */
 	PMOVSSET_EL0,	/* Overflow Flag Status Set Register */
 	PMUSERENR_EL0,	/* User Enable Register */
+	SPMSELR_EL0,	/* System PMU Select Register */
 
 	/* Pointer Authentication Registers in a strict increasing order. */
 	APIAKEYLO_EL1,
@@ -501,6 +502,7 @@ enum vcpu_sysreg {
 	CNTHP_CVAL_EL2,
 	CNTHV_CTL_EL2,
 	CNTHV_CVAL_EL2,
+	SPMACCESSR_EL2, /* System PMU Access Register */
 
 	/* Anything from this can be RES0/RES1 sanitised */
 	MARKER(__SANITISED_REG_START__),
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 6c63cbfc11ea..c7d6d2034f27 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -79,6 +79,7 @@ enum cgt_group_id {
 	CGT_MDCR_TDRA,
 	CGT_MDCR_E2PB,
 	CGT_MDCR_TPMS,
+	CGT_MDCR_EnSPM,
 	CGT_MDCR_TTRF,
 	CGT_MDCR_E2TB,
 	CGT_MDCR_TDCC,
@@ -125,6 +126,7 @@ enum cgt_group_id {
 	CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
 	CGT_CNTHCTL_EL1PTEN,
 
+	CGT_SPMSEL_SPMACCESS,
 	CGT_CPTR_TTA,
 	CGT_MDCR_HPMN,
 
@@ -351,6 +353,12 @@ static const struct trap_bits coarse_trap_bits[] = {
 		.mask		= MDCR_EL2_TPMS,
 		.behaviour	= BEHAVE_FORWARD_RW,
 	},
+	[CGT_MDCR_EnSPM] = {
+		.index		= MDCR_EL2,
+		.value		= MDCR_EL2_EnSPM,
+		.mask		= MDCR_EL2_EnSPM,
+		.behaviour	= BEHAVE_FORWARD_RW,
+	},
 	[CGT_MDCR_TTRF] = {
 		.index		= MDCR_EL2,
 		.value		= MDCR_EL2_TTRF,
@@ -509,6 +517,7 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
 	switch (sysreg) {
 	case SYS_PMEVTYPERn_EL0(0) ... SYS_PMEVTYPERn_EL0(30):
 	case SYS_PMEVCNTRn_EL0(0) ... SYS_PMEVCNTRn_EL0(30):
+	case SYS_PMEVCNTSVR_EL1(0) ... SYS_PMEVCNTSVR_EL1(30):
 		idx = (sys_reg_CRm(sysreg) & 0x3) << 3 | sys_reg_Op2(sysreg);
 		break;
 	case SYS_PMXEVTYPER_EL0:
@@ -528,6 +537,22 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
 	return BEHAVE_HANDLE_LOCALLY;
 }
 
+static enum trap_behaviour check_spmsel_spmaccess(struct kvm_vcpu *vcpu)
+{
+	u64 spmaccessr_el2, spmselr_el2;
+	int syspmusel;
+
+	if (__vcpu_sys_reg(vcpu, MDCR_EL2) & MDCR_EL2_EnSPM) {
+		spmselr_el2 = __vcpu_sys_reg(vcpu, SPMSELR_EL0);
+		spmaccessr_el2 = __vcpu_sys_reg(vcpu, SPMACCESSR_EL2);
+		syspmusel = FIELD_GET(SPMSELR_EL0_SYSPMUSEL_MASK, spmselr_el2);
+
+		if (((spmaccessr_el2 >> (syspmusel * 2)) & 0x3) == 0x0)
+			return BEHAVE_FORWARD_RW;
+	}
+	return BEHAVE_HANDLE_LOCALLY;
+}
+
 #define CCC(id, fn)				\
 	[id - __COMPLEX_CONDITIONS__] = fn
 
@@ -536,6 +561,7 @@ static const complex_condition_check ccc[] = {
 	CCC(CGT_CNTHCTL_EL1PTEN, check_cnthctl_el1pten),
 	CCC(CGT_CPTR_TTA, check_cptr_tta),
 	CCC(CGT_MDCR_HPMN, check_mdcr_hpmn),
+	CCC(CGT_SPMSEL_SPMACCESS, check_spmsel_spmaccess),
 };
 
 /*
@@ -947,6 +973,7 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
 	SR_TRAP(SYS_ERXPFGF_EL1,	CGT_HCR_nFIEN),
 	SR_TRAP(SYS_ERXPFGCTL_EL1,	CGT_HCR_nFIEN),
 	SR_TRAP(SYS_ERXPFGCDN_EL1,	CGT_HCR_nFIEN),
+
 	SR_TRAP(SYS_PMCR_EL0,		CGT_MDCR_TPM_TPMCR),
 	SR_TRAP(SYS_PMCNTENSET_EL0,	CGT_MDCR_TPM),
 	SR_TRAP(SYS_PMCNTENCLR_EL0,	CGT_MDCR_TPM),
@@ -1120,6 +1147,7 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
 	SR_TRAP(SYS_PMSIRR_EL1,		CGT_MDCR_TPMS),
 	SR_TRAP(SYS_PMSLATFR_EL1,	CGT_MDCR_TPMS),
 	SR_TRAP(SYS_PMSNEVFR_EL1,	CGT_MDCR_TPMS),
+
 	SR_TRAP(SYS_TRFCR_EL1,		CGT_MDCR_TTRF),
 	SR_TRAP(SYS_TRBBASER_EL1,	CGT_MDCR_E2TB),
 	SR_TRAP(SYS_TRBLIMITR_EL1,	CGT_MDCR_E2TB),
@@ -1127,6 +1155,136 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
 	SR_TRAP(SYS_TRBPTR_EL1, 	CGT_MDCR_E2TB),
 	SR_TRAP(SYS_TRBSR_EL1, 		CGT_MDCR_E2TB),
 	SR_TRAP(SYS_TRBTRG_EL1,		CGT_MDCR_E2TB),
+
+	SR_TRAP(SYS_MDSTEPOP_EL1,	CGT_MDCR_TDE_TDA),
+	SR_TRAP(SYS_TRBMPAM_EL1,	CGT_MDCR_E2TB),
+	SR_TRAP(SYS_PMSDSFR_EL1,	CGT_MDCR_TPMS),
+
+	SR_TRAP(SYS_SPMDEVAFF_EL1,	CGT_MDCR_EnSPM),
+	SR_TRAP(SYS_SPMCGCR0_EL1,	CGT_MDCR_EnSPM),
+	SR_TRAP(SYS_SPMCGCR1_EL1,	CGT_MDCR_EnSPM),
+	SR_TRAP(SYS_SPMIIDR_EL1,	CGT_MDCR_EnSPM),
+	SR_TRAP(SYS_SPMDEVARCH_EL1,	CGT_MDCR_EnSPM),
+	SR_TRAP(SYS_SPMCFGR_EL1,	CGT_MDCR_EnSPM),
+	SR_TRAP(SYS_SPMSCR_EL1,		CGT_MDCR_EnSPM),
+	SR_TRAP(SYS_SPMACCESSR_EL1,	CGT_MDCR_EnSPM),
+	SR_TRAP(SYS_SPMCR_EL0,		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMOVSCLR_EL0,	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMOVSSET_EL0,	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMINTENCLR_EL1,	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMINTENSET_EL1,	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMCNTENCLR_EL0,	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMCNTENSET_EL0,	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMSELR_EL0,	CGT_MDCR_EnSPM),
+
+	SR_TRAP(SYS_SPMEVTYPER_EL0(0),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(1),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(2),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(3),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(4),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(5),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(6),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(7),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(8),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(9),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(10),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(11),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(12),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(13),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(14),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVTYPER_EL0(15),	CGT_SPMSEL_SPMACCESS),
+
+	SR_TRAP(SYS_SPMEVFILTR_EL0(0),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(1),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(2),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(3),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(4),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(5),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(6),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(7),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(8),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(9),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(10), CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(11),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(12),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(13),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(14),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILTR_EL0(15),	CGT_SPMSEL_SPMACCESS),
+
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(0),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(1),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(2),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(3),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(4),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(5),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(6),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(7),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(8),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(9),		CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(10),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(11),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(12),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(13),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(14),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVFILT2R_EL0(15),	CGT_SPMSEL_SPMACCESS),
+
+	SR_TRAP(SYS_SPMEVCNTR_EL0(0),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(1),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(2),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(3),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(4),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(5),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(6),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(7),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(8),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(9),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(10),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(11),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(12),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(13),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(14),	CGT_SPMSEL_SPMACCESS),
+	SR_TRAP(SYS_SPMEVCNTR_EL0(15),	CGT_SPMSEL_SPMACCESS),
+
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(0),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(1),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(2),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(3),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(4),  CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(5),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(6),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(7),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(8),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(9),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(10),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(11),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(12),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(13),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(14),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(15),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(16),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(17),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(18),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(19),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(20),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(21),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(22),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(23),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(24),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(25),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(26),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(27),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(28),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(29),	CGT_MDCR_HPMN),
+	SR_TRAP(SYS_PMEVCNTSVR_EL1(30),	CGT_MDCR_HPMN),
+
+	SR_TRAP(SYS_MDSELR_EL1,		CGT_MDCR_TDE_TDA),
+	SR_TRAP(SYS_PMUACR_EL1,		CGT_MDCR_TPM),
+	SR_TRAP(SYS_PMICFILTR_EL0,	CGT_MDCR_TPM),
+	SR_TRAP(SYS_PMICNTR_EL0,	CGT_MDCR_TPM),
+	SR_TRAP(SYS_PMIAR_EL1,		CGT_MDCR_TPM),
+	SR_TRAP(SYS_PMECR_EL1,		CGT_MDCR_TPM),
+	SR_TRAP(SYS_PMZR_EL0,		CGT_MDCR_TPM),
+
 	SR_TRAP(SYS_CPACR_EL1,		CGT_CPTR_TCPAC),
 	SR_TRAP(SYS_AMUSERENR_EL0,	CGT_CPTR_TAM),
 	SR_TRAP(SYS_AMCFGR_EL0,		CGT_CPTR_TAM),
-- 
2.25.1



From ck.hu at mediatek.com  Mon Dec  9 22:47:48 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 10 Dec 2024 06:47:48 +0000
Subject: [PATCH v3] drm/mediatek: Move mtk_crtc_finish_page_flip() to
 ddp_cmdq_cb()
In-Reply-To: <20241210032820.10958-1-jason-jh.lin@mediatek.com>
References: <20241210032820.10958-1-jason-jh.lin@mediatek.com>
Message-ID: <1e953fb5a4e4965ba509a1bb45e7c8336102ff29.camel@mediatek.com>

Hi, Jason:

On Tue, 2024-12-10 at 11:28 +0800, Jason-JH.Lin wrote:
> mtk_crtc_finish_page_flip() is used to notify userspace that a
> page flip has been completed, allowing userspace to free the frame
> buffer of the last frame and commit the next frame.
> 
> In MediaTek's hardware design for configuring display hardware by using
> GCE, `DRM_EVENT_FLIP_COMPLETE` should be notified to userspace after
> GCE has finished configuring all display hardware settings for each
> atomic_commit().
> 
> Currently, mtk_crtc_finish_page_flip() cannot guarantee that GCE has
> configured all the display hardware settings of the last frame.
> Therefore, to increase the accuracy of the timing for notifying
> `DRM_EVENT_FLIP_COMPLETE` to userspace, mtk_crtc_finish_page_flip()
> should be moved to ddp_cmdq_cb().
> 
> Fixes: 7f82d9c43879 ("drm/mediatek: Clear pending flag when cmdq packet is done")
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_crtc.c | 29 +++++++++++++++++++++--------
>  1 file changed, 21 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
> index eb0e1233ad04..dabc2f8086b6 100644
> --- a/drivers/gpu/drm/mediatek/mtk_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
> @@ -109,9 +109,14 @@ static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc)
>  static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
>  {
>  	unsigned long flags;
> +	struct drm_crtc *crtc = &mtk_crtc->base;
> +	struct mtk_drm_private *priv = crtc->dev->dev_private;
>  
>  	drm_crtc_handle_vblank(&mtk_crtc->base);
>  
> +	if (!priv->data->shadow_register)
> +		return;
> +

I forget one case.
For the CPU case (SoC has no shadow register and CONFIG_MTK_CMDQ is not enable),
this driver should still work.
CPU case is not a usual case, but it could be used in some verification case.
So the condition may be

#if IS_REACHABLE(CONFIG_MTK_CMDQ)
	if (mtk_crtc->cmdq_client.chan)
		return;
#endif

>  	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
>  	if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
>  		mtk_crtc_finish_page_flip(mtk_crtc);
> @@ -284,10 +289,8 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  	state = to_mtk_crtc_state(mtk_crtc->base.state);
>  
>  	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> -	if (mtk_crtc->config_updating) {
> -		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> +	if (mtk_crtc->config_updating)
>  		goto ddp_cmdq_cb_out;
> -	}
>  
>  	state->pending_config = false;
>  
> @@ -315,10 +318,15 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  		mtk_crtc->pending_async_planes = false;
>  	}
>  
> -	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> -
>  ddp_cmdq_cb_out:
>  
> +	if (mtk_crtc->pending_needs_vblank) {
> +		mtk_crtc_finish_page_flip(mtk_crtc);
> +		mtk_crtc->pending_needs_vblank = false;
> +	}
> +
> +	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> +
>  	mtk_crtc->cmdq_vblank_cnt = 0;
>  	wake_up(&mtk_crtc->cb_blocking_queue);
>  }
> @@ -584,6 +592,10 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
>  		mtk_mutex_acquire(mtk_crtc->mutex);
>  		mtk_crtc_ddp_config(crtc, NULL);
>  		mtk_mutex_release(mtk_crtc->mutex);
> +
> +		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> +		mtk_crtc->config_updating = false;
> +		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
>  	}
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
>  	if (mtk_crtc->cmdq_client.chan) {
> @@ -606,13 +618,14 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
>  		 */
>  		mtk_crtc->cmdq_vblank_cnt = 3;
>  
> +		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> +		mtk_crtc->config_updating = false;
> +		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> +
>  		mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
>  		mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
>  	}
>  #endif
> -	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> -	mtk_crtc->config_updating = false;
> -	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);

For the CPU case (SoC has no shadow register and CONFIG_MTK_CMDQ is not enable),
This code is necessary.
Maybe keep these code or some modification for CPU case.

Regards,
CK

>  
>  	mutex_unlock(&mtk_crtc->hw_lock);
>  }


From andyshrk at 163.com  Mon Dec  9 23:01:50 2024
From: andyshrk at 163.com (Andy Yan)
Date: Tue, 10 Dec 2024 15:01:50 +0800 (CST)
Subject: [PATCH v5 08/18] drm/rockchip: vop2: Add check for 32 bpp
 format
In-Reply-To: <CAPj87rO0MG2yE_NTndbxQ77rW-p6-ht5kx5vsaOZikQfVmwrgg@mail.gmail.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209123215.2781721-1-andyshrk@163.com>
 <CAPj87rO0MG2yE_NTndbxQ77rW-p6-ht5kx5vsaOZikQfVmwrgg@mail.gmail.com>
Message-ID: <3576a3c5.6d72.193af5fcafb.Coremail.andyshrk@163.com>


Hi Daniel,

At 2024-12-10 01:06:05, "Daniel Stone" <daniel at fooishbar.org> wrote:
>Hi Andy,
>
>On Mon, 9 Dec 2024 at 12:32, Andy Yan <andyshrk at 163.com> wrote:
>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> index bd8db45eeba6..1f101a3c3942 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> @@ -1224,7 +1224,15 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
>>                                 return -EINVAL;
>>                         }
>>                 }
>> +       }
>>
>> +       if (fb->format->format == DRM_FORMAT_XRGB2101010 || fb->format->format == DRM_FORMAT_XBGR2101010) {
>> +               if (vop2->data->soc_id == 3588) {
>> +                       if (!rockchip_afbc(plane, fb->modifier)) {
>> +                               drm_err(vop2->drm, "Unsupported linear 32 bpp for %s\n", win->data->name);
>> +                               return -EINVAL;
>> +                       }
>> +               }
>
>Please do this in the format_mod_supported() hook, so userspace can
>see the true support of each format/modifier per plane. This will then
>be checked in drm_atomic_plane_check() so you don't need to open-code
>it here.

Thanks, will do in V6.

>
>Cheers,
>Daniel

From fj5100bi at fujitsu.com  Mon Dec  9 23:05:15 2024
From: fj5100bi at fujitsu.com (Yoshihiro Furudera (Fujitsu))
Date: Tue, 10 Dec 2024 07:05:15 +0000
Subject: [PATCH v2] perf vendor events arm64: Add FUJITSU-MONAKA pmu event
In-Reply-To: <ee89c235-a126-4874-994d-b2489eb1c00f@linaro.org>
References: <20241111064843.3003093-1-fj5100bi@fujitsu.com>
 <ee89c235-a126-4874-994d-b2489eb1c00f@linaro.org>
Message-ID: <OS3PR01MB690303F6D0FAF71ADDE7AA4BD43D2@OS3PR01MB6903.jpnprd01.prod.outlook.com>

Hi, James
Thanks for you review/comments.

> On 11/11/2024 6:48 am, Yoshihiro Furudera wrote:
> >      Add pmu events for FUJITSU-MONAKA.
> >      And, also updated common-and-microarch.json and recommended.json.
> >
> >      FUJITSU-MONAKA Specification URL:
> >      https://github.com/fujitsu/FUJITSU-MONAKA
> >
> > Signed-off-by: Akio Kakuno <fj3333bs at aa.jp.fujitsu.com>
> > Signed-off-by: Yoshihiro Furudera <fj5100bi at fujitsu.com>
> > ---
> > Changes in v2:
> > - Change "SVE_INT64_DIV_SPEC" to "SVE_INT_DIV64_SPEC" in
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/sve.json.
> > - Link to v1:
> > https://lore.kernel.org/all/20241111024529.2985894-1-fj5100bi at fujitsu.
> > com/
> >
> >   .../arch/arm64/common-and-microarch.json      | 858
> ++++++++++++++++++
> >   .../fujitsu/monaka/cycle_accounting.json      | 146 +++
> >   .../arch/arm64/fujitsu/monaka/energy.json     |  20 +
> >   .../arch/arm64/fujitsu/monaka/exception.json  |  32 +
> >   .../arm64/fujitsu/monaka/fp_operation.json    | 194 ++++
> >   .../arch/arm64/fujitsu/monaka/gcycle.json     | 116 +++
> >   .../arch/arm64/fujitsu/monaka/general.json    |   8 +
> >   .../arch/arm64/fujitsu/monaka/hwpf.json       |  62 ++
> >   .../arch/arm64/fujitsu/monaka/l1d_cache.json  | 101 +++
> >   .../arch/arm64/fujitsu/monaka/l1i_cache.json  |  47 +
> >   .../arch/arm64/fujitsu/monaka/l2_cache.json   | 146 +++
> >   .../arch/arm64/fujitsu/monaka/l3_cache.json   | 185 ++++
> >   .../arch/arm64/fujitsu/monaka/ll_cache.json   |   8 +
> >   .../arch/arm64/fujitsu/monaka/memory.json     |   8 +
> >   .../arch/arm64/fujitsu/monaka/pipeline.json   | 230 +++++
> >   .../arch/arm64/fujitsu/monaka/retired.json    |  29 +
> >   .../arm64/fujitsu/monaka/spec_operation.json  | 158 ++++
> >   .../arch/arm64/fujitsu/monaka/stall.json      |  83 ++
> >   .../arch/arm64/fujitsu/monaka/sve.json        | 146 +++
> >   .../arch/arm64/fujitsu/monaka/tlb.json        | 404 +++++++++
> >   .../arch/arm64/fujitsu/monaka/trace.json      |  20 +
> >   tools/perf/pmu-events/arch/arm64/mapfile.csv  |   1 +
> >   .../pmu-events/arch/arm64/recommended.json    |   6 +
> >   23 files changed, 3008 insertions(+)
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/cycle_accounting.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/energy.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/exception.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/fp_operation.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/gcycle.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/hwpf.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/l1d_cache.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/l1i_cache.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/l2_cache.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/l3_cache.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/ll_cache.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/memory.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/pipeline.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/retired.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/spec_operation.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/stall.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/sve.json
> >   create mode 100644
> tools/perf/pmu-events/arch/arm64/fujitsu/monaka/tlb.json
> >   create mode 100644
> > tools/perf/pmu-events/arch/arm64/fujitsu/monaka/trace.json
> >
> > diff --git
> > a/tools/perf/pmu-events/arch/arm64/common-and-microarch.json
> > b/tools/perf/pmu-events/arch/arm64/common-and-microarch.json
> > index 492083b99256..50fc4b2df361 100644
> > --- a/tools/perf/pmu-events/arch/arm64/common-and-microarch.json
> > +++ b/tools/perf/pmu-events/arch/arm64/common-and-microarch.json
> > @@ -533,6 +533,12 @@
> >           "EventName": "SVE_INST_SPEC",
> >           "BriefDescription": "SVE operations speculatively executed"
> >       },
> > +    {
> > +        "PublicDescription": "This event counts architecturally executed
> Advanced SIMD and SVE operations.",
> > +        "EventCode": "0x8007",
> > +        "EventName": "ASE_SVE_INST_SPEC",
> > +        "BriefDescription": "This event counts architecturally executed
> Advanced SIMD and SVE operations."
> > +    },
> 
> Hi Yoshihiro,
> 
> You don't need to duplicate the descriptions if they are the same. Just
> BriefDescription is enough and it will show for both normal and verbose mode.

All of the events added this time have the same BriefDescription and PublicDescription,
so we will delete the PublicDescription for each event.

> 
> Also in the common files, we're using the description strings from the Arm ARM. I
> noticed that the ones from your spec are slightly different.
> This is ok for now, but if we add any new Arm cores that use the same events this
> description may get overwritten. For example ASE_SVE_INST_SPEC in the Arm
> ARM is currently "Operation speculatively executed, Advanced SIMD or SVE".
> 
> If you have any actual relevant details that are different from the common string,
> you should put them in .../arch/arm64/fujitsu/monaka. But if you are ok with the
> potential overwrite (which looks like it should be ok) then you can leave them as
> is.

I think it's okay to overwrite it, but I'll check the specs.

> 
> [...]
> 
> > diff --git
> > a/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
> > b/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
> > new file mode 100644
> > index 000000000000..80bf17fb8f4c
> > --- /dev/null
> > +++ b/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
> > @@ -0,0 +1,8 @@
> > +[
> > +    {
> > +        "ArchStdEvent": "CPU_CYCLES"
> > +    },
> 
> Other cores put CPU_CYCLES in bus.json. For user friendlyness I would put the
> common ones into the same existing groups. The same issue applies for some
> other common events.
> 

I will update as suggested.

> 
> Thanks
> James

Best Regards,
Yoshihiro Furudera

From krzk at kernel.org  Mon Dec  9 23:16:12 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 10 Dec 2024 08:16:12 +0100
Subject: [PATCH] dt-bindings: display: panel-lvds: Add compatible for AUO
 G084SN05 V9
In-Reply-To: <20241209204003.1295503-1-festevam@gmail.com>
References: <20241209204003.1295503-1-festevam@gmail.com>
Message-ID: <6c2624c4-4835-48f4-a27c-81e570219292@kernel.org>

On 09/12/2024 21:40, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> The AUO G084SN05 V9 is a 8.4" 800x600 LVDS display.
> 
> Add a compatible entry for this LVDS display model.
> 
<form letter>
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) or work on fork of kernel
(don't, instead use mainline). 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.
</form letter>

Best regards,
Krzysztof


From anshuman.khandual at arm.com  Mon Dec  9 23:17:32 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 12:47:32 +0530
Subject: [PATCH v3 1/2] arm64: refactor the rodata=xxx
In-Reply-To: <20241209072020.4743-2-shijie@os.amperecomputing.com>
References: <20241209072020.4743-1-shijie@os.amperecomputing.com>
 <20241209072020.4743-2-shijie@os.amperecomputing.com>
Message-ID: <d13f1879-7fbc-458d-8fd3-4340b51165fd@arm.com>

Hello Huang,

On 12/9/24 12:50, Huang Shijie wrote:
>>From Documentation/admin-guide/kernel-parameters.txt:
> 	rodata=		[KNL,EARLY]
> 		on	Mark read-only kernel memory as read-only (default).
> 
> So "rodata=on" is the default.
> 
> But the current code does not follow the document, it makes "rodata=full"
> as the default.
> 
> This patch refactors the "rodata=xxx" :
>       1.) Make rodata=on behaviour be the original rodata=full.
>           (Drop the original rodata=full.)
>       2.) Introduce "rodata=noalias" which is the original "rodata=on"
>       3.) Add more comment for arch_parse_debug_rodata(),
>           update kernel-parameters.txt.
> 
> After this patch, the rodata=on will be the default.

Could this commit message be reworded/reformatted something like the
following instead ? Although feel free to improve this as required.

-----------------------------------------------------------------------
As per admin guide documentation, "rodata=on" should be the default on
platforms. Documentation/admin-guide/kernel-parameters.txt describes
these options as

        rodata=         [KNL,EARLY]
                on      Mark read-only kernel memory as read-only (default).
                off     Leave read-only kernel memory writable for debugging.
                full    Mark read-only kernel memory and aliases as read-only
                        [arm64]

But on arm64 platform, "rodata=full" is the default instead. This patch
implements the following changes.

- Make "rodata=on" behaviour same as the original "rodata=full"
- Make "rodata=noalias" (new) behaviour same as the original "rodata=on"
- Drop the original "rodata=full"
- Add comment for arch_parse_debug_rodata()
- Update kernel-parameters.txt as required

After this patch, the "rodata=on" will be the default on arm64 platform
as well.
-----------------------------------------------------------------------


> 
> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
> ---
>  .../admin-guide/kernel-parameters.txt         |  2 +-
>  arch/arm64/include/asm/setup.h                | 25 +++++++++++++++++--
>  2 files changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index a22b7e621007..51bce7b9d805 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -5901,7 +5901,7 @@
>  	rodata=		[KNL,EARLY]
>  		on	Mark read-only kernel memory as read-only (default).
>  		off	Leave read-only kernel memory writable for debugging.
> -		full	Mark read-only kernel memory and aliases as read-only
> +		noalias	Use more block mappings,may have better performance.
>  		        [arm64]
>  
>  	rockchip.usb_uart
> diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
> index ba269a7a3201..b3063326b79a 100644
> --- a/arch/arm64/include/asm/setup.h
> +++ b/arch/arm64/include/asm/setup.h
> @@ -13,6 +13,27 @@
>  extern phys_addr_t __fdt_pointer __initdata;
>  extern u64 __cacheline_aligned boot_args[4];
>  
> +/*
> + * rodata=on (default):
> + *    Apply read-only attributes of VM areas to the linear alias of
> + *    the backing pages as well. This prevents code or read-only data
> + *    from being modified (inadvertently or intentionally) via another
> + *    mapping of the same memory page.
> + *
> + *    This requires the linear region to be mapped down to pages,
> + *    which may adversely affect performance in some cases.
> + *
> + * rodata=off:
> + *    It provides us more block mappings and contiguous hits
> + *    to map the linear region which minimize the TLB footprint.
> + *    Leave read-only kernel memory writable for debugging.
> + *
> + * rodata=noalias:
> + *    It provides us more block mappings and contiguous hits
> + *    to map the linear region which minimize the TLB footprint.
> + *    And the linear aliases of pages belonging to read-only mappings
> + *    in vmalloc region are also marked as read-only.
> + */

Reformatted and cleaned up the above comment a bit but feel free to
improve it further.

/*
 * rodata=on (default)
 *
 *    This applies read-only attributes to VM areas and to the linear
 *    alias of the backing pages as well. This prevents code or read-
 *    only data from being modified (inadvertently or intentionally),
 *    via another mapping for the same memory page.
 *
 *    But this might cause linear map region to be mapped down to base
 *    pages, which may adversely affect performance in some cases.
 *
 * rodata=off
 *
 *    This provides more block mappings and contiguous hints for linear
 *    map region which would minimize TLB footprint. This also leaves
 *    read-only kernel memory writable for debugging.
 *
 * rodata=noalias
 *
 *    This provides more block mappings and contiguous hints for linear
 *    map region which would minimize TLB footprint. Linear aliases of
 *    pages belonging to read-only mappings in vmalloc region are also
 *    marked as read-only.


>  static inline bool arch_parse_debug_rodata(char *arg)
>  {
>  	extern bool rodata_enabled;
> @@ -21,7 +42,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
>  	if (!arg)
>  		return false;
>  
> -	if (!strcmp(arg, "full")) {
> +	if (!strcmp(arg, "on")) {
>  		rodata_enabled = rodata_full = true;
>  		return true;
>  	}
> @@ -31,7 +52,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
>  		return true;
>  	}
>  
> -	if (!strcmp(arg, "on")) {
> +	if (!strcmp(arg, "noalias")) {
>  		rodata_enabled = true;
>  		rodata_full = false;
>  		return true;


From ardb at kernel.org  Mon Dec  9 23:21:56 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 10 Dec 2024 08:21:56 +0100
Subject: [PATCH v3 1/2] arm64: refactor the rodata=xxx
In-Reply-To: <d13f1879-7fbc-458d-8fd3-4340b51165fd@arm.com>
References: <20241209072020.4743-1-shijie@os.amperecomputing.com>
 <20241209072020.4743-2-shijie@os.amperecomputing.com> <d13f1879-7fbc-458d-8fd3-4340b51165fd@arm.com>
Message-ID: <CAMj1kXFJhFfhy=Gwm=QrdN6XPUd=7SKNKFBF_Z4eQ30r509BCg@mail.gmail.com>

On Tue, 10 Dec 2024 at 08:17, Anshuman Khandual
<anshuman.khandual at arm.com> wrote:
>
...
>
> Reformatted and cleaned up the above comment a bit but feel free to
> improve it further.
>
> /*
>  * rodata=on (default)
>  *
>  *    This applies read-only attributes to VM areas and to the linear
>  *    alias of the backing pages as well. This prevents code or read-
>  *    only data from being modified (inadvertently or intentionally),
>  *    via another mapping for the same memory page.
>  *
>  *    But this might cause linear map region to be mapped down to base
>  *    pages, which may adversely affect performance in some cases.
>  *
>  * rodata=off
>  *
>  *    This provides more block mappings and contiguous hints for linear
>  *    map region which would minimize TLB footprint. This also leaves
>  *    read-only kernel memory writable for debugging.
>  *
>  * rodata=noalias
>  *
>  *    This provides more block mappings and contiguous hints for linear
>  *    map region which would minimize TLB footprint. Linear aliases of
>  *    pages belonging to read-only mappings in vmalloc region are also
>  *    marked as read-only.
>

If linear aliases are marked as read-only, how does 'noalias' differ from 'on'?


From kevin_chen at aspeedtech.com  Mon Dec  9 23:24:09 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Tue, 10 Dec 2024 15:24:09 +0800
Subject: [PATCH] dt-bindings: interrupt-controller: Fix the size-cells in ast2700-intc
Message-ID: <20241210072409.1429725-1-kevin_chen@aspeedtech.com>

It is no need to let size-cells to 2 for the ASPEED AST27XX INTC. Modify
the ast2700-intc example usage.

Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
---
 .../bindings/interrupt-controller/aspeed,ast2700-intc.yaml    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
index 55636d06a674..69503aa638fb 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
@@ -69,11 +69,11 @@ examples:
 
     bus {
         #address-cells = <2>;
-        #size-cells = <2>;
+        #size-cells = <1>;
 
         interrupt-controller at 12101b00 {
             compatible = "aspeed,ast2700-intc-ic";
-            reg = <0 0x12101b00 0 0x10>;
+            reg = <0 0x12101b00 0x10>;
             #interrupt-cells = <2>;
             interrupt-controller;
             interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.34.1



From anshuman.khandual at arm.com  Mon Dec  9 23:27:04 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 12:57:04 +0530
Subject: [PATCH v3 2/2] arm64: remove CONFIG_RODATA_FULL_DEFAULT_ENABLED
In-Reply-To: <20241209072020.4743-3-shijie@os.amperecomputing.com>
References: <20241209072020.4743-1-shijie@os.amperecomputing.com>
 <20241209072020.4743-3-shijie@os.amperecomputing.com>
Message-ID: <767de5f8-a650-4acf-966e-528fd08b09bb@arm.com>

A small nit:

arm64/Kconfig: Remove CONFIG_RODATA_FULL_DEFAULT_ENABLED

On 12/9/24 12:50, Huang Shijie wrote:
> After patch "arm64: refacotr the rodata=xxx",
> the "rodata=on" becomes the default.
> 
>      ......................................
> 	if (!strcmp(arg, "on")) {
> 		rodata_enabled = rodata_full = true;
> 		return true;
> 	}
>      ......................................
> 
> The rodata_full is always "true" via "rodata=on" and does not
> depend on the config RODATA_FULL_DEFAULT_ENABLED anymore,
> so it can be dropped.
> 
> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
> ---
>  arch/arm64/Kconfig       | 14 --------------
>  arch/arm64/mm/pageattr.c |  2 +-
>  2 files changed, 1 insertion(+), 15 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index cbfd357f94a6..1c69982302ed 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1666,20 +1666,6 @@ config MITIGATE_SPECTRE_BRANCH_HISTORY
>  	  When taking an exception from user-space, a sequence of branches
>  	  or a firmware call overwrites the branch history.
>  
> -config RODATA_FULL_DEFAULT_ENABLED
> -	bool "Apply r/o permissions of VM areas also to their linear aliases"
> -	default y
> -	help
> -	  Apply read-only attributes of VM areas to the linear alias of
> -	  the backing pages as well. This prevents code or read-only data
> -	  from being modified (inadvertently or intentionally) via another
> -	  mapping of the same memory page. This additional enhancement can
> -	  be turned off at runtime by passing rodata=[off|on] (and turned on
> -	  with rodata=full if this option is set to 'n')
> -
> -	  This requires the linear region to be mapped down to pages,
> -	  which may adversely affect performance in some cases.
> -
>  config ARM64_SW_TTBR0_PAN
>  	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
>  	depends on !KCSAN
> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> index 39fd1f7ff02a..6eef08d8451e 100644
> --- a/arch/arm64/mm/pageattr.c
> +++ b/arch/arm64/mm/pageattr.c
> @@ -20,7 +20,7 @@ struct page_change_data {
>  	pgprot_t clear_mask;
>  };
>  
> -bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED);
> +bool rodata_full __ro_after_init = true;
>  
>  bool can_set_direct_map(void)
>  {

Otherwise LGTM

Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>


From wenst at chromium.org  Mon Dec  9 23:32:10 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 10 Dec 2024 15:32:10 +0800
Subject: [PATCH v2 1/2] dt-bindings: mmc: mtk-sd: Document compatibles that need two register ranges
In-Reply-To: <20241210073212.3917912-1-wenst@chromium.org>
References: <20241210073212.3917912-1-wenst@chromium.org>
Message-ID: <20241210073212.3917912-2-wenst@chromium.org>

Besides the MT8183's MMC controller and all its compatible derivatives,
the recently added MT7986 and MT8196 also require two register ranges.
This is based on the actual device trees.

Properly enforce this in the binding.

Fixes: 4a8bd2b07d88 ("dt-bindings: mmc: mtk-sd: Add mt7988 SoC")
Fixes: 58927c9dc4ab ("dt-bindings: mmc: mtk-sd: Add support for MT8196")
Cc: Frank Wunderlich <frank-w at public-files.de>
Cc: Andy-ld Lu <andy-ld.lu at mediatek.com>
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
index f86ebd81f5a5..0debccbd6519 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
@@ -235,11 +235,19 @@ allOf:
       properties:
         compatible:
           contains:
-            const: mediatek,mt8183-mmc
+            enum:
+              - mediatek,mt7986-mmc
+              - mediatek,mt7988-mmc
+              - mediatek,mt8183-mmc
+              - mediatek,mt8196-mmc
     then:
       properties:
         reg:
           minItems: 2
+    else:
+      properties:
+        reg:
+          maxItems: 1
 
   - if:
       properties:
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Mon Dec  9 23:32:09 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 10 Dec 2024 15:32:09 +0800
Subject: [PATCH v2 0/2] mmc: mtk-sd: Limit second register range to SoCs requiring it
Message-ID: <20241210073212.3917912-1-wenst@chromium.org>

Changes since v1:
- Added MT7988 compatible string to list that needs second register
  range
- Dropped comment about uncertainty of MT6779 from commit message
- Picked up Angelo's Reviewed-by

Currently the usage of a second register range for MediaTek's MMC
controller is seen only on a few platforms. However the driver tries
to grab the register base regardless, and then ignores any errors.
This makes all the other platforms that don't need it produce confusing
error messages.

Instead, make the driver only grab the register range for platforms that
actually require it, and correctly handle the error. Also fix up the
binding so that validation of the "reg" property is as strict as
possible.

Please take a look.


Thanks
ChenYu

Chen-Yu Tsai (2):
  dt-bindings: mmc: mtk-sd: Document compatibles that need two register
    ranges
  mmc: mtk-sd: Limit getting top_base to SoCs that require it

 Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 10 +++++++++-
 drivers/mmc/host/mtk-sd.c                         | 15 +++++++++++----
 2 files changed, 20 insertions(+), 5 deletions(-)

-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Mon Dec  9 23:32:11 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 10 Dec 2024 15:32:11 +0800
Subject: [PATCH v2 2/2] mmc: mtk-sd: Limit getting top_base to SoCs that require it
In-Reply-To: <20241210073212.3917912-1-wenst@chromium.org>
References: <20241210073212.3917912-1-wenst@chromium.org>
Message-ID: <20241210073212.3917912-3-wenst@chromium.org>

Currently the mtk-sd driver tries to get and map the second register
base, named top_base in the code, regardless of whether the SoC model
actually has it or not. This produces confusing big error messages on
the platforms that don't need it:

    mtk-msdc 11260000.mmc: error -EINVAL: invalid resource (null)

Limit it to the platforms that actually require it, based on their
device tree entries, and properly fail if it is missing.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/mmc/host/mtk-sd.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index e2c385853eef..1bb7044f4ca1 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -414,6 +414,7 @@ struct mtk_mmc_compatible {
 	u8 clk_div_bits;
 	bool recheck_sdio_irq;
 	bool hs400_tune; /* only used for MT8173 */
+	bool needs_top_base;
 	u32 pad_tune_reg;
 	bool async_fifo;
 	bool data_tune;
@@ -587,6 +588,7 @@ static const struct mtk_mmc_compatible mt7986_compat = {
 	.clk_div_bits = 12,
 	.recheck_sdio_irq = true,
 	.hs400_tune = false,
+	.needs_top_base = true,
 	.pad_tune_reg = MSDC_PAD_TUNE0,
 	.async_fifo = true,
 	.data_tune = true,
@@ -627,6 +629,7 @@ static const struct mtk_mmc_compatible mt8183_compat = {
 	.clk_div_bits = 12,
 	.recheck_sdio_irq = false,
 	.hs400_tune = false,
+	.needs_top_base = true,
 	.pad_tune_reg = MSDC_PAD_TUNE0,
 	.async_fifo = true,
 	.data_tune = true,
@@ -653,6 +656,7 @@ static const struct mtk_mmc_compatible mt8196_compat = {
 	.clk_div_bits = 12,
 	.recheck_sdio_irq = false,
 	.hs400_tune = false,
+	.needs_top_base = true,
 	.pad_tune_reg = MSDC_PAD_TUNE0,
 	.async_fifo = true,
 	.data_tune = true,
@@ -2887,9 +2891,13 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	if (IS_ERR(host->base))
 		return PTR_ERR(host->base);
 
-	host->top_base = devm_platform_ioremap_resource(pdev, 1);
-	if (IS_ERR(host->top_base))
-		host->top_base = NULL;
+	host->dev_comp = of_device_get_match_data(&pdev->dev);
+
+	if (host->dev_comp->needs_top_base) {
+		host->top_base = devm_platform_ioremap_resource(pdev, 1);
+		if (IS_ERR(host->top_base))
+			return PTR_ERR(host->top_base);
+	}
 
 	ret = mmc_regulator_get_supply(mmc);
 	if (ret)
@@ -2951,7 +2959,6 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	msdc_of_property_parse(pdev, host);
 
 	host->dev = &pdev->dev;
-	host->dev_comp = of_device_get_match_data(&pdev->dev);
 	host->src_clk_freq = clk_get_rate(host->src_clk);
 	/* Set host parameters to mmc */
 	mmc->ops = &mt_msdc_ops;
-- 
2.47.0.338.g60cca15819-goog



From yeoreum.yun at arm.com  Mon Dec  9 23:36:50 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Tue, 10 Dec 2024 07:36:50 +0000
Subject: [PATCH v2 2/2] firmware/arm_ffa: remove __le64_to_cpu() when set
 uuid for direct msg v2
In-Reply-To: <0cb655ee-9401-41bb-b9cd-580e0aeef2be@app.fastmail.com>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
 <20241203143109.1030514-3-yeoreum.yun@arm.com>
 <9e60e996-070e-43a7-80e9-efdfda9f6223@app.fastmail.com>
 <Z1ch52AthTYVhtH4@bogus>
 <0cb655ee-9401-41bb-b9cd-580e0aeef2be@app.fastmail.com>
Message-ID: <Z1fvkpYvqpnjPZA8@e129823.arm.com>

Hi Arnd,

> On Mon, Dec 9, 2024, at 17:59, Sudeep Holla wrote:
> > On Mon, Dec 09, 2024 at 04:27:14PM +0100, Arnd Bergmann wrote:
> >
> >> > That means, we don't need to swap the uuid when it send via direct
> >> > message request version 2, just send it as saved in memory.
> >>
> >> "As saved in memory" does not sound like a useful description
> >> when passing arguments through registers, as the register
> >> contents are not defined in terms of byte offsets.
> >>
> >
> > Well I didn't know how to term it. The structure UUID is a raw buffer
> > and it provide helpers to import/export the data in/out of it. So in LE
> > kernel IIUC, it is stored in LE format itself which was my initial
> > confusion and hence though what you fixed was correct previously.
>
> The way I would phrase it, the UUID is never "stored" in
> big-endian or little-endian format, it's just remains a string
> of bytes. The endianess becomes a choice only when loading it
> into registers for passing the argument to firmware, and it's
> the firmware that mandates little-endian in the specification.

> >> Can you describe what bug you found? If the byteorder on
> >> big-endian kernels is wrong in the current version and your
> >> patch fixes it, it sounds like the specification needs to
> >> be updated describe both big-endian and little-endian
> >> byte-order, and how the firmware detects which one is used.
> >>
> >
> > The firmware interface understands only LE format. And by default UUID
> > is stored in LE format itself in the structure which I got confused
> > initially. We may need endian conversion at places(found few when trying
> > to get it working with BE kernel).
> >
> > I wanted to check with you about this. The current driver doesn't
> > work with BE. I tried to cook up patches but then the upstream user
> > of this driver OPTEE doesn't work in BE, so I hit a roadblock to fully
> > validate my changes. I don't see any driver adding endianness dependency
> > in the Kconfig if they can't work with BE, not sure if that
> > is intentional or just don't care. I was thinking if we can disable
> > it to build in BE kernel until the actual support was added.
>
> I think as long big-endian kernels remain an option on arm64, we
> should try to to write portable code and implement the specification
> The reality of course is that very few people care these days, and
> it's getting harder to test over time.
>
> > So the current FF-A driver just supports LE and the bug was found just
> > in LE kernel itself.
>
> What is the bug and how was it found? The only thing I see in
> the patch here is to change the code from portable to nonportable,
> but not actually change behavior on little-endian 64-bit.
>
> Looking through the other functions in drivers/firmware/arm_ffa/driver.c,
> I see that most of them just match the specification. One exception
> is ffa_notification_info_get(), which incorrectly casts the
> argument response arguments to an array of 'u16' values. Using
> the correct bit shifts according to the specification would
> make that work on big-endian and also more readable and
> robust. Another one is __ffa_partition_info_get_regs(), which
> does an incorrect memcpy() instead of decoding the values.
>
Conclusionly, Yes. But the RFC 4122 said with network byte order.
to describe how uuid is saved.

but I think the endianess to load the register is not a choice.
because the spec says:

    UUID Lo  x2  Bytes[0...7] of UUID with byte 0 in the low-order bits.
    UUID Hi  x3  Bytes[8...15] of UUID with byte 8 in the low-order bits.

this means UUID.bytes[0] should be loaded to x2.bytes[0].
           UUID.bytes[1] should be loaded to x2,bytes[1]
           ...

That's why other software spec (i.e tf-a) doesn't loads UUID from register
wihtout swapping byte with endianess but just copy it.

The bug is "not send UUID according to spec" in kernel side
That's why it fails when I send message  with direct message version 2.
So, it''s not change code unportable to portable but it fixes according
to spec (load UUID as it is in register wihtout endianess).

> > > 'unsigned long' makes the code unnecessarily incompatible
> > > with 32-bit builds.

I don't think it should care about 32-bit for direct message 2,
Since direct message v2 is  64-bit ABI only.
that means ffa_msg_send_direct_req2() should return error before it calls smc.

Thanks.


From dsimic at manjaro.org  Tue Dec 10 00:01:53 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 10 Dec 2024 09:01:53 +0100
Subject: [PATCH 3/6] arm64: dts: rockchip: remove ethernet alias from
 rk3328-roc
In-Reply-To: <20241210013010.81257-4-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-4-pgwipeout@gmail.com>
Message-ID: <20693a7b7cb1aaed2c21b84fd57c4b72@manjaro.org>

Hello Peter,

On 2024-12-10 02:30, Peter Geis wrote:
> Remove the ethernet alias added back in during the rk3328-roc dtsi
> conversion.

I just checked again the dtsi parent conversion I performed in
the commit f3c6526d6fb2 ("arm64: dts: rockchip: Convert dts files
used as parents to dtsi files"), and both rk3328-roc-cc.dts and
rk3328-roc-pc.dts had the ethernet0 alias defined before the
conversion.  Thus, the alias wasn't added back by mistake during
the conversion, it was there before.

Moreover, I don't see why would we want to delete the ethernet0
alias(es) in the first place?  It's usual for Rockchip board dts
files to have ethernetX aliases defined, and both ROC-RK3328-CC
and ROC-RK3328-PC have their gmac2io DT nodes enabled, and the
boards have wired Ethernet ports, so they should also have the
ethernet0 alias(es) defined.

Am I missing something?

> Fixes: f3c6526d6fb2 ("arm64: dts: rockchip: Convert dts files used as
> parents to dtsi files")
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
> 
>  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> index b5bd5e7d5748..f782c8220dd3 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> @@ -9,7 +9,6 @@
> 
>  / {
>  	aliases {
> -		ethernet0 = &gmac2io;
>  		mmc0 = &sdmmc;
>  		mmc1 = &emmc;
>  	};


From andrej.picej at norik.com  Tue Dec 10 00:06:07 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue, 10 Dec 2024 09:06:07 +0100
Subject: [PATCH v4 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <xkrk3vdw7yhj22ornqog7wovqctgrolfcxbl43u7ddgstjqsbl@h22hxlld6zqg>
References: <20241205134021.2592013-1-andrej.picej@norik.com>
 <20241205134021.2592013-3-andrej.picej@norik.com>
 <nbumcptoi5hwehjbrynf6dh2wrz7a4ugqblrjxyswvj7udkf3u@6qikclizqfjr>
 <e420579f-25b2-41ca-9627-130d67c51541@norik.com>
 <xkrk3vdw7yhj22ornqog7wovqctgrolfcxbl43u7ddgstjqsbl@h22hxlld6zqg>
Message-ID: <4a0b3e4e-c791-43cd-8f82-8d25fae71d64@norik.com>



On 10. 12. 24 02:18, Dmitry Baryshkov wrote:
> On Mon, Dec 09, 2024 at 08:56:29AM +0100, Andrej Picej wrote:
>> Hi Dmitry,
>>
>> On 5. 12. 24 23:48, Dmitry Baryshkov wrote:
>>> On Thu, Dec 05, 2024 at 02:40:20PM +0100, Andrej Picej wrote:
>>>> Add a optional properties to change LVDS output voltage. This should not
>>>> be static as this depends mainly on the connected display voltage
>>>> requirement. We have three properties:
>>>> - "ti,lvds-termination-ohms", which sets near end termination,
>>>> - "ti,lvds-vod-swing-data-microvolt" and
>>>> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
>>>> output voltage for data and clock lanes. They are defined as an array
>>>> with min and max values. The appropriate bitfield will be set if
>>>> selected constraints can be met.
>>>>
>>>> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
>>>> end termination will be used. Selecting only one:
>>>> "ti,lvds-vod-swing-data-microvolt" or
>>>> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
>>>> constraint for only data/clock lanes will be met. Setting both is
>>>> recommended.
>>>>
>>>> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
>>>> ---
>>>> Changes in v4:
>>>> - fix typo in commit message bitfiled -> bitfield
>>>> - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
>>>> of separate variables for channel A/B
>>>> - add more checks on return value of "of_property_read_u32_array"
>>>> Changes in v3:
>>>> - use microvolts for default array values 1000 mV -> 1000000 uV.
>>>> Changes in v2:
>>>> - use datasheet tables to get the proper configuration
>>>> - since major change was done change the authorship to myself
>>>> ---
>>>>    drivers/gpu/drm/bridge/ti-sn65dsi83.c | 147 +++++++++++++++++++++++++-
>>>>    1 file changed, 144 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>> index 57a7ed13f996..f724d2a6777b 100644
>>>> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>> @@ -132,6 +132,16 @@
>>>>    #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>>>>    #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>>>> +enum sn65dsi83_channel {
>>>> +	CHANNEL_A,
>>>> +	CHANNEL_B
>>>> +};
>>>> +
>>>> +enum sn65dsi83_lvds_term {
>>>> +	OHM_100,
>>>> +	OHM_200
>>>> +};
>>>> +
>>>>    enum sn65dsi83_model {
>>>>    	MODEL_SN65DSI83,
>>>>    	MODEL_SN65DSI84,
>>>> @@ -147,6 +157,8 @@ struct sn65dsi83 {
>>>>    	struct regulator		*vcc;
>>>>    	bool				lvds_dual_link;
>>>>    	bool				lvds_dual_link_even_odd_swap;
>>>> +	int				lvds_vod_swing_conf[2];
>>>> +	int				lvds_term_conf[2];
>>>>    };
>>>>    static const struct regmap_range sn65dsi83_readable_ranges[] = {
>>>> @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>>>>    	.max_register = REG_IRQ_STAT,
>>>>    };
>>>> +static const int lvds_vod_swing_data_table[2][4][2] = {
>>>> +	{	/* 100 Ohm */
>>>> +		{ 180000, 313000 },
>>>> +		{ 215000, 372000 },
>>>> +		{ 250000, 430000 },
>>>> +		{ 290000, 488000 },
>>>> +	},
>>>> +	{	/* 200 Ohm */
>>>> +		{ 150000, 261000 },
>>>> +		{ 200000, 346000 },
>>>> +		{ 250000, 428000 },
>>>> +		{ 300000, 511000 },
>>>> +	},
>>>> +};
>>>> +
>>>> +static const int lvds_vod_swing_clock_table[2][4][2] = {
>>>> +	{	/* 100 Ohm */
>>>> +		{ 140000, 244000 },
>>>> +		{ 168000, 290000 },
>>>> +		{ 195000, 335000 },
>>>> +		{ 226000, 381000 },
>>>> +	},
>>>> +	{	/* 200 Ohm */
>>>> +		{ 117000, 204000 },
>>>> +		{ 156000, 270000 },
>>>> +		{ 195000, 334000 },
>>>> +		{ 234000, 399000 },
>>>> +	},
>>>> +};
>>>> +
>>>>    static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>>>>    {
>>>>    	return container_of(bridge, struct sn65dsi83, bridge);
>>>> @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>>>>    		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>>>>    	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
>>>> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
>>>> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
>>>> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
>>>> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
>>>>    	regmap_write(ctx->regmap, REG_LVDS_LANE,
>>>>    		     (ctx->lvds_dual_link_even_odd_swap ?
>>>>    		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
>>>> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
>>>> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
>>>> +		     (ctx->lvds_term_conf[CHANNEL_A] ?
>>>> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
>>>> +		     (ctx->lvds_term_conf[CHANNEL_B] ?
>>>> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>>>>    	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>>>>    	le16val = cpu_to_le16(mode->hdisplay);
>>>> @@ -576,10 +622,101 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>>>>    	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>>>>    };
>>>> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
>>>> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
>>>> +{
>>>> +	int i;
>>>> +
>>>> +	for (i = 0; i <= 3; i++) {
>>>> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
>>>> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
>>>> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
>>>> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
>>>> +			return i;
>>>> +	}
>>>> +
>>>> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
>>>> +	return -EINVAL;
>>>> +}
>>>> +
>>>> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
>>>> +{
>>>> +	struct device *dev = ctx->dev;
>>>> +	struct device_node *endpoint;
>>>> +	/* Set so the property can be freely selected if not defined */
>>>> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
>>>> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
>>>> +	u32 lvds_term = 200;
>>>> +	u8 lvds_term_conf;
>>>> +	int endpoint_reg;
>>>> +	int lvds_vod_swing_conf;
>>>> +	int ret = 0;
>>>> +	int ret_data;
>>>> +	int ret_clock;
>>>> +
>>>> +	if (channel == CHANNEL_A)
>>>> +		endpoint_reg = 2;
>>>> +	else
>>>> +		endpoint_reg = 3;
>>>> +
>>>> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
>>>> +	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
>>>> +
>>>> +	if (lvds_term == 200)
>>>> +		lvds_term_conf = OHM_200;
>>>> +	else
>>>> +		lvds_term_conf = OHM_100;
>>>> +
>>>> +	ctx->lvds_term_conf[channel] = lvds_term_conf;
>>>> +
>>>> +	ret_data = of_property_read_u32_array(endpoint,
>>>> +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
>>>> +			ARRAY_SIZE(lvds_vod_swing_data));
>>>> +	if (ret_data != 0 && ret_data != -EINVAL) {
>>>> +		ret = ret_data;
>>>> +		goto exit;
>>>> +	}
>>>> +
>>>> +	ret_clock = of_property_read_u32_array(endpoint,
>>>> +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
>>>> +			ARRAY_SIZE(lvds_vod_swing_clk));
>>>> +	if (ret_clock != 0 && ret_clock != -EINVAL) {
>>>> +		ret = ret_clock;
>>>> +		goto exit;
>>>> +	}
>>>> +
>>>> +	/* If any of the two properties is defined. */
>>>> +	if (!ret_data || !ret_clock) {
>>>> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
>>>> +			lvds_vod_swing_data, lvds_vod_swing_clk,
>>>> +			lvds_term_conf);
>>>> +		if (lvds_vod_swing_conf < 0) {
>>>> +			ret = lvds_vod_swing_conf;
>>>> +			goto exit;
>>>> +		}
>>>> +
>>>> +		ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
>>>> +	}
>>>> +	ret = 0;
>>>> +exit:
>>>> +	of_node_put(endpoint);
>>>> +	return ret;
>>>> +}
>>>> +
>>>>    static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>>>>    {
>>>>    	struct drm_bridge *panel_bridge;
>>>>    	struct device *dev = ctx->dev;
>>>> +	int ret;
>>>> +
>>>> +	ctx->lvds_vod_swing_conf[CHANNEL_A] = 0x1;
>>>> +	ctx->lvds_vod_swing_conf[CHANNEL_B] = 0x1;
>>>> +	ctx->lvds_term_conf[CHANNEL_A] = 0x1;
>>>> +	ctx->lvds_term_conf[CHANNEL_B] = 0x1;
>>>
>>> These match the defaults in sn65dsi83_parse_lvds_endpoint(). Do we
>>> really need those?
>>
>> Yes, I think we do. This ensures that defaults are used even when property
>> is not defined/LVDS channel is not used. So also LVDS channel B defaults are
>> set even for sn65dsi83 (single LVDS output). Keeping the same reg values as
>> before these changes.
> 
> You can move sn65dsi83_parse_lvds_endpoint() out of the if() and get the
> same result. Duplicating data (or code) is a bad idea, because it's easy
> to update one point and miss another point. And then usually one has a
> nice debugging session, trying to understand why their changes didn't
> work out.

Ok I see what you are trying to accomplish. I'll set default values in 
sn65dsi83_parse_lvds_endpoint() in v5 like you suggested. Thanks.

Best regards,
Andrej

> 
>>
>> Best regards,
>> Andrej
>>
>>
>>>
>>>> +
>>>> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
>>>> +	if (ret < 0)
>>>> +		return ret;
>>>>    	ctx->lvds_dual_link = false;
>>>>    	ctx->lvds_dual_link_even_odd_swap = false;
>>>> @@ -587,6 +724,10 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>>>>    		struct device_node *port2, *port3;
>>>>    		int dual_link;
>>>> +		ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
>>>> +		if (ret < 0)
>>>> +			return ret;
>>>> +
>>>>    		port2 = of_graph_get_port_by_id(dev->of_node, 2);
>>>>    		port3 = of_graph_get_port_by_id(dev->of_node, 3);
>>>>    		dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
>>>> -- 
>>>> 2.34.1
>>>>
>>>
> 


From ck.hu at mediatek.com  Tue Dec 10 00:09:16 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 10 Dec 2024 08:09:16 +0000
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
Message-ID: <ae0a17c93131c22c18f0722c43d4770a652e2923.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit and that also poses a slight
> difference between the V2 and V1 controllers in how they handle
> Hotplug Detection (HPD).
> 
> While the v1 controller was using the CEC controller to check
> HDMI cable connection and disconnection, in this driver the v2
> one does not.
> 
> This is due to the fact that on parts with v2 designs, like the
> MT8195 SoC, there is one CEC controller shared between the HDMI
> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> adding support to use the CEC HW to wake up the HDMI controllers
> it is necessary to have support for one TX, one RX *and* for both
> at the same time.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static u8 mtk_hdmi_v2_get_i2s_ch_mapping(struct mtk_hdmi *hdmi, u8 channel_type)

parameter hdmi is redundant, so drop it.

Regards,
CK

> +{
> +       switch (channel_type) {
> +       case HDMI_AUD_CHAN_TYPE_1_1:
> +       case HDMI_AUD_CHAN_TYPE_2_1:
> +               return 0x01;
> +       case HDMI_AUD_CHAN_TYPE_3_0:
> +               return 0x02;
> +       case HDMI_AUD_CHAN_TYPE_3_1:
> +               return 0x03;
> +       case HDMI_AUD_CHAN_TYPE_3_0_LRS:
> +       case HDMI_AUD_CHAN_TYPE_4_0:
> +               return 0x08;
> +       case HDMI_AUD_CHAN_TYPE_5_1:
> +               return 0x0b;
> +       case HDMI_AUD_CHAN_TYPE_4_1_CLRS:
> +       case HDMI_AUD_CHAN_TYPE_6_0:
> +       case HDMI_AUD_CHAN_TYPE_6_0_CS:
> +       case HDMI_AUD_CHAN_TYPE_6_0_CH:
> +       case HDMI_AUD_CHAN_TYPE_6_0_OH:
> +       case HDMI_AUD_CHAN_TYPE_6_0_CHR:
> +               return 0x0e;
> +       case HDMI_AUD_CHAN_TYPE_1_0:
> +       case HDMI_AUD_CHAN_TYPE_2_0:
> +       case HDMI_AUD_CHAN_TYPE_3_1_LRS:
> +       case HDMI_AUD_CHAN_TYPE_4_1:
> +       case HDMI_AUD_CHAN_TYPE_5_0:
> +       case HDMI_AUD_CHAN_TYPE_4_0_CLRS:
> +       case HDMI_AUD_CHAN_TYPE_6_1:
> +       case HDMI_AUD_CHAN_TYPE_6_1_CS:
> +       case HDMI_AUD_CHAN_TYPE_6_1_CH:
> +       case HDMI_AUD_CHAN_TYPE_6_1_OH:
> +       case HDMI_AUD_CHAN_TYPE_6_1_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_0:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LH_RH:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LC_RC:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LW_RW:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CS_CH:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CS_OH:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CS_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CH_OH:
> +       case HDMI_AUD_CHAN_TYPE_7_0_CH_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_0_OH_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR:
> +       case HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS:
> +       case HDMI_AUD_CHAN_TYPE_7_1:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LH_RH:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LC_RC:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LW_RW:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CS_CH:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CS_OH:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CS_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CH_OH:
> +       case HDMI_AUD_CHAN_TYPE_7_1_CH_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_1_OH_CHR:
> +       case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR:
> +       default:
> +               return 0;
> +       }
> +
> +       return 0;
> +}
> +



From dsimic at manjaro.org  Tue Dec 10 00:18:25 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 10 Dec 2024 09:18:25 +0100
Subject: [PATCH 1/6] pmdomain: rockchip: fix rockchip_pd_power error
 handling
In-Reply-To: <20241210013010.81257-2-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-2-pgwipeout@gmail.com>
Message-ID: <1b323d6e9ef873bfc770e9d54b7a3a64@manjaro.org>

Hello Peter,

On 2024-12-10 02:30, Peter Geis wrote:
> The calls rockchip_pd_power makes to rockchip_pmu_set_idle_request lack
> any return error handling, causing device drivers to incorrectly 
> believe
> the hardware idle requests succeed when they may have failed. This 
> leads
> to software possibly accessing hardware that is powered off and the
> subsequent SError panic that follows.
> 
> Add error checking and return errors to the calling function to prevent
> such crashes.
> 
> gst-launch-1.0 videotestsrc num-buffers=2000 ! v4l2jpegenc ! fakesink
> Setting pipeline to PAUSED ...er-x64
> Pipeline is PREROLLING ...
> Redistribute latency...
> rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack 
> on
> domain 'hevc', val=0x98260, idle = 0
> SError Interrupt on CPU2, code 0x00000000bf000002 -- SError
> CPU: 2 UID: 0 PID: 804 Comm: videotestsrc0:s Not tainted 6.12.0-rc5+ 
> #54
> Hardware name: Firefly roc-rk3328-cc (DT)
> pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : rockchip_vpu2_jpeg_enc_run+0x168/0xbc8
> lr : device_run+0xb0/0x128
> sp : ffff800082143a20
> x29: ffff800082143a20 x28: 0000000000000140 x27: 0000000000000000
> x26: ffff582c47a313e8 x25: ffff582c53e95000 x24: ffff582c53e92800
> x23: ffff582c5bbe0000 x22: 0000000000000000 x21: ffff582c47a31080
> x20: ffffa0d78cfa4168 x19: ffffa0d78cfa4168 x18: ffffb755b0519000
> x17: 000000040044ffff x16: 00500072b5503510 x15: a7a6a5a4a3a29a99
> x14: 989796959493928a x13: 0000000051eb851f x12: 00000000000000ff
> x11: ffffa0d78d812880 x10: ffffa0d78d7fbca0 x9 : 000000000000003f
> x8 : 0000000000000063 x7 : 000000000000003f x6 : 0000000000000040
> x5 : ffff80008010d000 x4 : ffffa0d78cfa4168 x3 : ffffa0d78cfbfdd8
> x2 : ffff80008010d0f4 x1 : 0000000000000020 x0 : 0000000000000140
> Kernel panic - not syncing: Asynchronous SError Interrupt
> CPU: 2 UID: 0 PID: 804 Comm: videotestsrc0:s Not tainted 6.12.0-rc5+ 
> #54
> Hardware name: Firefly roc-rk3328-cc (DT)
> Call trace:
> dump_backtrace+0xa0/0x128
> show_stack+0x20/0x38
> dump_stack_lvl+0xc8/0xf8
> dump_stack+0x18/0x28
> panic+0x3ec/0x428
> nmi_panic+0x48/0xa0
> arm64_serror_panic+0x6c/0x88
> do_serror+0x30/0x70
> el1h_64_error_handler+0x38/0x60
> el1h_64_error+0x7c/0x80
> rockchip_vpu2_jpeg_enc_run+0x168/0xbc8
> device_run+0xb0/0x128
> v4l2_m2m_try_run+0xac/0x230
> v4l2_m2m_ioctl_streamon+0x70/0x90
> v4l_streamon+0x2c/0x40
> __video_do_ioctl+0x194/0x400
> video_usercopy+0x10c/0x808
> video_ioctl2+0x20/0x80
> v4l2_ioctl+0x48/0x70
> __arm64_sys_ioctl+0xb0/0x100
> invoke_syscall+0x50/0x120
> el0_svc_common.constprop.0+0x48/0xf0
> do_el0_svc+0x24/0x38
> el0_svc+0x38/0x100
> el0t_64_sync_handler+0xc0/0xc8
> el0t_64_sync+0x1a8/0x1b0
> SMP: stopping secondary CPUs
> Kernel Offset: 0x20d70c000000 from 0xffff800080000000
> PHYS_OFFSET: 0xffffa7d3c0000000
> CPU features: 0x00,00000090,00200000,0200421b
> Memory Limit: none
> ---[ end Kernel panic - not syncing: Asynchronous SError Interrupt ]---
> 
> Fixes: 7c696693a4f5 ("soc: rockchip: power-domain: Add power domain 
> driver")
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>

This patch is obviously correct, because not checking what
rockchip_pmu_set_idle_request() returns was simply wrong.
Thanks for the patch!

Though, shouldn't we improve further the way proper error
handling is performed in rockchip_do_pmu_set_power_domain(),
by "rolling back" what rockchip_do_pmu_set_power_domain()
did after powering up fails?

> ---
> 
>  drivers/pmdomain/rockchip/pm-domains.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pmdomain/rockchip/pm-domains.c
> b/drivers/pmdomain/rockchip/pm-domains.c
> index cb0f93800138..57e8fa25d2bd 100644
> --- a/drivers/pmdomain/rockchip/pm-domains.c
> +++ b/drivers/pmdomain/rockchip/pm-domains.c
> @@ -590,14 +590,18 @@ static int rockchip_pd_power(struct
> rockchip_pm_domain *pd, bool power_on)
>  			rockchip_pmu_save_qos(pd);
> 
>  			/* if powering down, idle request to NIU first */
> -			rockchip_pmu_set_idle_request(pd, true);
> +			ret = rockchip_pmu_set_idle_request(pd, true);
> +			if (ret < 0)
> +				return ret;
>  		}
> 
>  		rockchip_do_pmu_set_power_domain(pd, power_on);
> 
>  		if (power_on) {
>  			/* if powering up, leave idle mode */
> -			rockchip_pmu_set_idle_request(pd, false);
> +			ret = rockchip_pmu_set_idle_request(pd, false);
> +			if (ret < 0)
> +				return ret;
> 
>  			rockchip_pmu_restore_qos(pd);
>  		}


From alexandre.torgue at foss.st.com  Tue Dec 10 00:15:59 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Tue, 10 Dec 2024 09:15:59 +0100
Subject: [PATCH] ARM: dts: stm32: Fix IPCC EXTI declaration on stm32mp151
In-Reply-To: <20241206171759.135342-1-arnaud.pouliquen@foss.st.com>
References: <20241206171759.135342-1-arnaud.pouliquen@foss.st.com>
Message-ID: <ce05c6db-7baa-4268-96c5-fbefeee2e77f@foss.st.com>

Hi Arnaud

On 12/6/24 18:17, Arnaud Pouliquen wrote:
> The GIC IRQ type used for IPCC RX should be IRQ_TYPE_LEVEL_HIGH.
> Replacing the interrupt with the EXTI event changes the type to
> the numeric value 1, meaning IRQ_TYPE_EDGE_RISING.
> 
> The issue is that EXTI event 61 is a direct event.The IRQ type of
> direct events is not used by EXTI and is propagated to the parent
> IRQ controller of EXTI, the GIC.
> 
> Align the IRQ type to the value expected by the GIC by replacing
> the second parameter "1" with IRQ_TYPE_LEVEL_HIGH.
> 
> Fixes: 7d9802bb0e34 ("ARM: dts: stm32: remove the IPCC "wakeup" IRQ on stm32mp151")
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
> ---
>   arch/arm/boot/dts/st/stm32mp151.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/st/stm32mp151.dtsi b/arch/arm/boot/dts/st/stm32mp151.dtsi
> index b28dc90926bd..e7e3ce8066ec 100644
> --- a/arch/arm/boot/dts/st/stm32mp151.dtsi
> +++ b/arch/arm/boot/dts/st/stm32mp151.dtsi
> @@ -129,7 +129,7 @@ ipcc: mailbox at 4c001000 {
>   			reg = <0x4c001000 0x400>;
>   			st,proc-id = <0>;
>   			interrupts-extended =
> -				<&exti 61 1>,
> +				<&exti 61 IRQ_TYPE_LEVEL_HIGH>,
>   				<&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
>   			interrupt-names = "rx", "tx";
>   			clocks = <&rcc IPCC>;

Applied on stm32-next.

Alex


From arnd at arndb.de  Tue Dec 10 00:22:51 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 10 Dec 2024 09:22:51 +0100
Subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <42d39f8e-0b59-4185-af1f-f778522608d2@oss.nxp.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
 <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
 <2005af5d-bdb7-4675-8f0e-82cb817801af@app.fastmail.com>
 <6f4a0be8-4def-4066-9b44-d43059b7a90d@oss.nxp.com>
 <94cba886-86cb-41f1-96ee-501623add7db@app.fastmail.com>
 <42d39f8e-0b59-4185-af1f-f778522608d2@oss.nxp.com>
Message-ID: <fc50d8a7-cc59-42dd-aafd-7da49fadee45@app.fastmail.com>

On Mon, Dec 9, 2024, at 18:17, Ciprian Marian Costea wrote:
> On 12/6/2024 2:41 PM, Arnd Bergmann wrote:

>> I think storing 'rtc_hz' as a u32 variable and adding a range
>> check when filling it would help, mainly to save the next reader
>> from having to understand what is going on.
>> 
>
> The confusion on my end is that I cannot see where 'div_u64() implicitly 
> casts the dividend 'hz' from 64-bit to 32-bit' by following the method's 
> implementation [1]

I mean passing a 64-bit variable into a function that takes a
32-bit argument truncates the range.

> But I agree that 'rtc_hz' can be stored into a 32-bit variable with a 
> range check added when it is taken from the Linux clock API to avoid any
> unneeded abstractions.

ok

>> 
>> This is the same as just removing the error handling and
>> relying on unsigned integer overflow semantics.
>> 
>> The usual check we do in time_before()/time_after instead
>> checks if the elapsed time is less than half the available
>> range:
>> 
>> #define time_after(a,b)         \
>>          (typecheck(unsigned long, a) && \
>>           typecheck(unsigned long, b) && \
>>           ((long)((b) - (a)) < 0))
>> 
>
> Ok. Thanks for the suggestion. I will look into using 
> 'time_before()/time_after()' API instead of directly checking via 
> comparison operators.

To be clear: you can't directly use time_before() here because
that takes an 'unsigned long' argument, so you want the
same logic, but for u32 values. I have not found an existing
helper for that, but it's possible I missed it.

>> Who sets that alarm though? Are you relying on custom userspace
>> for this, or is that something that the kernel already does
>> that I'm missing?
>
> The test usage is via 'rtcwake' [2] userspace tool.
> I've detailed a bit the testing scenario in the cover letter for this 
> patchset [3]:
>
> "
> Following is an example of Suspend to RAM trigger on S32G2/S32G3 SoCs,
> using userspace tools such as rtcwake:
> # rtcwake -s 2 -m mem
> # rtcwake: assuming RTC uses UTC ...
> # rtcwake: wakeup from "mem" using /dev/rtc0 at Wed Feb  6 06:28:36 2036

Got it. I feel this also needs either some documentation in
the source code, or some infrastructure in the rtc layer if
this is a common problem in other drivers as well. If there
is a maximum time that the system can be suspended for without
a wakeup, why not just set an earlier wakeup in the kernel
when you have all the information for it?

Or maybe this should not actually be an 'rtc' driver at all?
In the old days, we used drivers like
arch/arm/mach-omap1/timer32k.c to register a handler
for read_persistent_clock64(), which completely bypasses
the RTC layer and provides both automatic wakeup and more
accurate accounting of sleep time. 

Another example was the tegra clocksource driver, which used
to use read_persistent_clock64() but changed to being
a CLOCK_SOURCE_SUSPEND_NONSTOP source in 95170f0708f2
("clocksource/drivers/tegra: Rework for compensation of
suspend time"). The same seems true for timer-ti-32k.c and
timer-sprd.c.

Alexandre, Daniel, any recommendations here?

     Arnd


From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:27:02 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:27:02 +0100
Subject: [PATCH 1/4] arm64: dts: mediatek: mt8183-kukui-jacuzzi: Drop
 pp3300_panel voltage settings
In-Reply-To: <CAGXv+5GHP1M1rKwR8j+bN8GmpxWtpkfLTnvBdkg5wOvWanc-kw@mail.gmail.com>
References: <20241030070224.1006331-1-wenst@chromium.org>
 <20241030070224.1006331-2-wenst@chromium.org>
 <CAGXv+5HVy41qee6kwVUeLV_DfA0=wk2X77kv81rBKAZDGE6mww@mail.gmail.com>
 <bbaa0c8f-9702-4252-a674-e46fb51f0a2a@collabora.com>
 <CAGXv+5GHP1M1rKwR8j+bN8GmpxWtpkfLTnvBdkg5wOvWanc-kw@mail.gmail.com>
Message-ID: <35392d9d-56a3-4db8-b500-6272d0bd275c@collabora.com>

Il 04/11/24 14:47, Chen-Yu Tsai ha scritto:
> On Mon, Nov 4, 2024 at 9:19?PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno at collabora.com> wrote:
>>
>> Il 04/11/24 14:00, Chen-Yu Tsai ha scritto:
>>> On Wed, Oct 30, 2024 at 3:02?PM Chen-Yu Tsai <wenst at chromium.org> wrote:
>>>>
>>>> The pp3300_panel fixed regulator is just a load switch. It does not have
>>>> any regulating capabilities. Thus having voltage constraints on it is
>>>> wrong.
>>>>
>>>> Remove the voltage constraints.
>>>>
>>>> Fixes: cabc71b08eb5 ("arm64: dts: mt8183: Add kukui-jacuzzi-damu board")
>>>> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>>>
>>> I see that the other three patches were merged and included in the pull
>>> request, but not this one. Were there any concerns?
>>>
>>
>> Sorry I forgot to actually provide an explanation for that - yes, I do have some
>> comment about this one.
>>
>> Despite this being a load switch, it's still switching power from regulator A to
>> target device X, so this is technically still providing 3.3V to device X.
>>
>> Think about how a "regular" full-fledged regulator works: you can (sometimes) set
>> a voltage, and then you can ENABLE the VOUT for said regulator (/rail): this kind
>> of "load switch" does exactly the same as the ENABLE switch for a full-fledged
>> regulator.
> 
> But it does not provide regulation. One cannot "set" the voltage on a load
> switch; one can only set it on its upstream supply, if that supply provides
> regulation.
> 
> IIRC Mark said some years ago that if a regulator doesn't regulate the
> voltage, then the voltage constraints should not be given. The constraints
> are then derived from its upstream supply.
> 
> That's the guideline I've followed for all the regulator related changes
> I've done over the years. Does that work for you?
> 

Ok, let's go with that then.

There's only one problem - patches 2 to 4 don't apply for whatever reason, is there
any dependency?

Cheers,
Angelo

>> So, this is switching on and off a power rail that is derived from a source rail,
>> practically creating... well, a "new" rail, with...
>>
>>    VIN=somewhere-3.3v,
>>    VOUT=somewhere-still-3.3v
>>
>> Any objections/doubts/etc? :-)
> 
> I agree with most of it, except the part that I laid out above about the
> load switch not providing regulation.
> 
>> P.S.: I'm writing fast, sorry if anything appears unclear, feel free to shoot more
>>         questions in case :-)
> 
> No, it's pretty clear, and I believe one of the common interpretations
> I see. Thank you for the quick response.
> 
> 
> Thanks
> ChenYu
> 
>> Cheers,
>> Angelo
>>
>>>
>>> ChenYu
>>>
>>>> ---
>>>>    arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi | 2 --
>>>>    1 file changed, 2 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
>>>> index 783c333107bc..7bbafe926558 100644
>>>> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
>>>> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
>>>> @@ -35,8 +35,6 @@ pp1800_mipibrdg: pp1800-mipibrdg {
>>>>           pp3300_panel: pp3300-panel {
>>>>                   compatible = "regulator-fixed";
>>>>                   regulator-name = "pp3300_panel";
>>>> -               regulator-min-microvolt = <3300000>;
>>>> -               regulator-max-microvolt = <3300000>;
>>>>                   pinctrl-names = "default";
>>>>                   pinctrl-0 = <&pp3300_panel_pins>;
>>>>
>>>> --
>>>> 2.47.0.163.g1226f6d8fa-goog
>>>>
>>




From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:33:22 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:33:22 +0100
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <631fdcdfd44e0d401e62df67acc206b0762248c7.camel@mediatek.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
 <631fdcdfd44e0d401e62df67acc206b0762248c7.camel@mediatek.com>
Message-ID: <50757699-aca2-423a-b463-5a4d74d63447@collabora.com>

Il 10/12/24 04:28, CK Hu (???) ha scritto:
> Hi, Angelo:
> 
> On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>
>>
>> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
>> found in MediaTek's MT8195, MT8188 SoC and their variants, and
>> including support for display modes up to 4k60 and for HDMI
>> Audio, as per the HDMI 2.0 spec.
>>
>> HDCP and CEC functionalities are also supported by this hardware,
>> but are not included in this commit and that also poses a slight
>> difference between the V2 and V1 controllers in how they handle
>> Hotplug Detection (HPD).
>>
>> While the v1 controller was using the CEC controller to check
>> HDMI cable connection and disconnection, in this driver the v2
>> one does not.
>>
>> This is due to the fact that on parts with v2 designs, like the
>> MT8195 SoC, there is one CEC controller shared between the HDMI
>> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
>> adding support to use the CEC HW to wake up the HDMI controllers
>> it is necessary to have support for one TX, one RX *and* for both
>> at the same time.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
> 
> [snip]
> 
>> +static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
>> +                                     struct drm_bridge_state *old_state)
>> +{
>> +       struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>> +       struct drm_atomic_state *state = old_state->base.state;
>> +       int ret;
>> +
>> +       ret = drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
>> +       if (ret)
>> +               dev_err(hdmi->dev, "Could not update infoframes: %d\n", ret);
>> +
>> +       mtk_hdmi_v2_hw_vid_mute(hdmi, false);
>> +       mtk_hdmi_v2_hw_aud_mute(hdmi, false);
> 
> In v1, it does not unmute when bridge enable.
> I would like v1 and v2 has the same behavior.
> If possible, remove these code.
> If remove thee code would result in some problem,
> add comment to describe why need these code.
> 

I think you even said that in the first review...

Thanks for repeating, and sorry for missing that in v2, will be done
for v3

Cheers,
Angelo

> Regards,
> CK
> 
>> +
>> +       /* signal the connect event to audio codec */
>> +       mtk_hdmi_v2_handle_plugged_change(hdmi, true);
>> +
>> +       hdmi->enabled = true;
>> +}
>> +
> 





From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:28:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:28:21 +0100
Subject: [PATCH RESEND v4] arm64: dts: mt8183: set DMIC one-wire mode
 on Damu
In-Reply-To: <20241113-damu-v4-1-6911b69610dd@chromium.org>
References: <20241113-damu-v4-1-6911b69610dd@chromium.org>
Message-ID: <173381930175.18469.11487989790886879423.b4-ty@collabora.com>

On Wed, 13 Nov 2024 16:16:53 +0800, Hsin-Te Yuan wrote:
> Sets DMIC one-wire mode on Damu.
> 
> 

Applied to v6.13-next/dts64, thanks!

[1/1] arm64: dts: mt8183: set DMIC one-wire mode on Damu
      commit: 6c379e8b984815fc8f876e4bc78c4d563f13ddae

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:28:22 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:28:22 +0100
Subject: [PATCH v3 0/2] Add device tree for MT8188-based Chromebook
 "Ciri"
In-Reply-To: <20241124085739.290556-1-fshao@chromium.org>
References: <20241124085739.290556-1-fshao@chromium.org>
Message-ID: <173381930242.18469.18254539260828193661.b4-ty@collabora.com>

On Sun, 24 Nov 2024 16:52:36 +0800, Fei Shao wrote:
> This is the v3 series to introduce the device trees for Ciri. Please
> refer to [v1] and [v2] cover letter for the detail introduction of Ciri
> if needed.
> 
> Note that there are patches for some known dtbs_check warnings:
> - sound: Unevaluated 'mediatek,adsp' property
>   https://lore.kernel.org/all/20241105091246.3944946-1-fshao at chromium.org/
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/2] dt-bindings: arm: mediatek: Add MT8188 Lenovo Chromebook Duet (11", 9)
      commit: 3a11be8938aa7294719c0cf2a4758ed0cf88ab84
[2/2] arm64: dts: mediatek: Introduce MT8188 Geralt platform based Ciri
      commit: 5e6af7f5418950d77eb2193ddfb8557458a070b0

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:28:20 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:28:20 +0100
Subject: [PATCH] arm64: dts: mediatek: mt8186: Move wakeup to MTU3 to
 get working suspend
In-Reply-To: <20241106-mt8186-suspend-with-usb-wakeup-v1-1-07734a4c8236@collabora.com>
References: <20241106-mt8186-suspend-with-usb-wakeup-v1-1-07734a4c8236@collabora.com>
Message-ID: <173381930097.18469.1229889611395701191.b4-ty@collabora.com>

On Wed, 06 Nov 2024 16:01:45 -0500, N?colas F. R. A. Prado wrote:
> The current DT has the wakeup-source and mediatek,syscon-wakeup
> properties in the XHCI nodes, which configures USB wakeup after powering
> down the XHCI hardware block. However, since the XHCI controller is
> behind an MTU3 (USB3 DRD controller), the MTU3 only gets powered down
> after USB wakeup has been configured, causing the system to detect a
> wakeup, and results in broken suspend support as the system resumes
> immediately.
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/1] arm64: dts: mediatek: mt8186: Move wakeup to MTU3 to get working suspend
      commit: 253b4e96f5783fddede1b82274a7b4e0aa57d761

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:28:22 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:28:22 +0100
Subject: [PATCH v4 0/2] Add support for Starmie Chromebooks
In-Reply-To: <20241129055720.3328681-1-wmacek@chromium.org>
References: <20241129055720.3328681-1-wmacek@chromium.org>
Message-ID: <173381930291.18469.3166957495661734495.b4-ty@collabora.com>

On Fri, 29 Nov 2024 05:57:18 +0000, Wojciech Macek wrote:
> Add an entry for the MT8186 based Starmie Chromebooks, also known as the
> ASUS Chromebook Enterprise CM30 Detachable (CM3001). The device is
> a tablet style chromebook.
> 
> Wojciech Macek (2):
>   dt-bindings: arm: mediatek: Add MT8186 Starmie Chromebooks
>   arm64: dts: mediatek: mt8186: Add Starmie device
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/2] dt-bindings: arm: mediatek: Add MT8186 Starmie Chromebooks
      commit: c31f6c2f25586557bc586a9b3713bd7473e0cac3
[2/2] arm64: dts: mediatek: mt8186: Add Starmie device
      commit: d926d78bc93b1bfe18bc1cf80e66e1a0e38297ce

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:28:23 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:28:23 +0100
Subject: (subset) [PATCH 0/5] MT8516/MT8167 dtsi fixes
In-Reply-To: <20241204190524.21862-1-val@packett.cool>
References: <20241204190524.21862-1-val@packett.cool>
Message-ID: <173381930371.18469.6086866397447453685.b4-ty@collabora.com>

On Wed, 04 Dec 2024 16:05:03 -0300, Val Packett wrote:
> I've been working on mainline bringup on an MT8167 tablet I found at a
> junkyard sale (lenovo,tb7304f) for postmarketOS :3
> 
> This first series consists of basic device tree fixes for the MT8516
> dtsi that the MT8167 one inherits from.
> 
> The changes that follow add support for the MT6392 PMIC, and that's
> mostly been implemented by Fabien Parent back in 2020 and not merged:
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/5] arm64: dts: mediatek: mt8516: fix GICv2 range
      commit: e3ee31e4409f051c021a30122f3c470f093a7386
[2/5] arm64: dts: mediatek: mt8516: fix wdt irq type
      commit: 03a80442030e7147391738fb6cbe5fa0b3b91bb1
[3/5] arm64: dts: mediatek: mt8516: add i2c clock-div property
      commit: eb72341fd92b7af510d236e5a8554d855ed38d3c
[4/5] arm64: dts: mediatek: mt8516: reserve 192 KiB for TF-A
      commit: 2561c7d5d497b988deccc36fe5eac7fd50b937f8

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:28:24 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:28:24 +0100
Subject: [PATCH 1/2] arm64: dts: mediatek: mt8183: Disable DPI display
 output by default
In-Reply-To: <20241025075630.3917458-1-wenst@chromium.org>
References: <20241025075630.3917458-1-wenst@chromium.org>
Message-ID: <173381930438.18469.15845444123528821647.b4-ty@collabora.com>

On Fri, 25 Oct 2024 15:56:27 +0800, Chen-Yu Tsai wrote:
> This reverts commit 377548f05bd0905db52a1d50e5b328b9b4eb049d.
> 
> Most SoC dtsi files have the display output interfaces disabled by
> default, and only enabled on boards that utilize them. The MT8183
> has it backwards: the display outputs are left enabled by default,
> and only disabled at the board level.
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/2] arm64: dts: mediatek: mt8183: Disable DPI display output by default
      commit: 93a680af46436780fd64f4e856a4cfa8b393be6e
[2/2] arm64: dts: mediatek: mt8183: Disable DSI display output by default
      commit: 26f6e91fa29a58fdc76b47f94f8f6027944a490c

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:30:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:30:21 +0100
Subject: [PATCH v2 1/1] soc: mediatek: Add command for APU SMC call
In-Reply-To: <20241030013533.855696-2-karl.li@mediatek.com>
References: <20241030013533.855696-1-karl.li@mediatek.com>
 <20241030013533.855696-2-karl.li@mediatek.com>
Message-ID: <ad1ac38c-6a04-4f84-a8fc-998d97c542e5@collabora.com>

Il 30/10/24 02:35, Karl.Li ha scritto:
> From: Karl Li <karl.li at mediatek.com>
> 
> Add command for APU SMC call.
> The APU microprocess's start and stop sequence will process in ATF.
> 
> Signed-off-by: Karl Li <karl.li at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From krzk at kernel.org  Tue Dec 10 00:31:38 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 10 Dec 2024 09:31:38 +0100
Subject: [PATCH v3 1/3] dt-bindings: leds: backlight: apple,dwi-bl: Add
 bindings for Apple DWI backlight
In-Reply-To: <20241209075908.140014-2-towinchenmi@gmail.com>
References: <20241209075908.140014-1-towinchenmi@gmail.com>
 <20241209075908.140014-2-towinchenmi@gmail.com>
Message-ID: <okhsrlpr6qu6crzzhqzbvgwoqwcxefynceje6pyttb3x57vrsf@hyilj6xo23t7>

On Mon, Dec 09, 2024 at 03:58:33PM +0800, Nick Chan wrote:
> Add the device tree bindings for backlight controllers attached via Apple
> DWI 2-wire interface.
> 
> Signed-off-by: Nick Chan <towinchenmi at gmail.com>
> ---
>  .../bindings/leds/backlight/apple,dwi-bl.yaml | 54 +++++++++++++++++++
>  1 file changed, 54 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
> 

<form letter>
This is a friendly reminder during the review process.

It seems my or other reviewer's previous comments were not fully
addressed. Maybe the feedback got lost between the quotes, maybe you
just forgot to apply it. Please go back to the previous discussion and
either implement all requested changes or keep discussing them.

Thank you.
</form letter>

Best regards,
Krzysztof



From angelogioacchino.delregno at collabora.com  Tue Dec 10 00:32:09 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 10 Dec 2024 09:32:09 +0100
Subject: [PATCH 3/3] mailbox: mediatek: Add mtk-apu-mailbox driver
In-Reply-To: <cf75f3c3932ddc50f5697bc4f394bd77fc16cd39.camel@mediatek.com>
References: <20241024092608.431581-1-karl.li@mediatek.com>
 <20241024092608.431581-4-karl.li@mediatek.com>
 <083c8f7b-0969-4ca3-8a91-35f5767c5f32@collabora.com>
 <CAGXv+5Fw+qZhTTgJq0QdiQHgiQP2ByR1tgae2+k4erx+0fp61g@mail.gmail.com>
 <a3c3280478bf86eb97a422782ce60ec4eaa35224.camel@mediatek.com>
 <0f98405c40530d81c342af06dea593e7babedeac.camel@mediatek.com>
 <cf75f3c3932ddc50f5697bc4f394bd77fc16cd39.camel@mediatek.com>
Message-ID: <d65fc527-5919-4454-865c-4731944e48a7@collabora.com>

Il 05/12/24 08:32, Karl Li (???) ha scritto:
> On Thu, 2024-12-05 at 07:05 +0000, Karl Li (???) wrote:
>> Dead maintainers,

LOL :-D

> "Dear" maintainers. Really sorry for the typo...
>>
>> I hope you're doing well. Just a warm reminder that we're following
>> up
>> on these patch and really appreciate any feedback you might have.

I already gave you feedback on this patch.

Cheers,
Angelo

>>
>> Thanks you in advance for your review.
>>
>> Regards,
>> Karl
>>


From krzk at kernel.org  Tue Dec 10 00:32:16 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 10 Dec 2024 09:32:16 +0100
Subject: [PATCH v3 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <20241209075908.140014-3-towinchenmi@gmail.com>
References: <20241209075908.140014-1-towinchenmi@gmail.com>
 <20241209075908.140014-3-towinchenmi@gmail.com>
Message-ID: <w5niokvjfwajnzz3muccb45jsvqzg7lql7g5tg5s6iat3mtqkk@qu2a5zcp3rs7>

On Mon, Dec 09, 2024 at 03:58:34PM +0800, Nick Chan wrote:
> Add driver for backlight controllers attached via Apple DWI 2-wire
> interface, which is found on some Apple iPhones, iPads and iPod touches
> with a LCD display.
> 

Nothing improved here.

> Signed-off-by: Nick Chan <towinchenmi at gmail.com>
> ---
>  drivers/video/backlight/Kconfig  |  12 +++
>  drivers/video/backlight/Makefile |   1 +
>  drivers/video/backlight/dwi_bl.c | 126 +++++++++++++++++++++++++++++++
>  3 files changed, 139 insertions(+)
>  create mode 100644 drivers/video/backlight/dwi_bl.c
> 
> diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
> index 3614a5d29c71..e64cc3d51ac5 100644
> --- a/drivers/video/backlight/Kconfig
> +++ b/drivers/video/backlight/Kconfig
> @@ -166,6 +166,18 @@ config BACKLIGHT_EP93XX
>  	  To compile this driver as a module, choose M here: the module will
>  	  be called ep93xx_bl.
>  
> +config BACKLIGHT_APPLE_DWI
> +	tristate "Apple DWI 2-Wire Interface Backlight Driver"
> +	depends on ARCH_APPLE || COMPILE_TEST
> +	default y
> +	help
> +          Say Y to enable the backlight driver for backlight controllers
> +          attached via the Apple DWI 2-wire interface which is found in some
> +          Apple iPhones, iPads and iPod touches.
> +
> +	  To compile this driver as a module, choose M here: the module will
> +	  be called dwi_bl.
> +
>  config BACKLIGHT_IPAQ_MICRO
>  	tristate "iPAQ microcontroller backlight driver"
>  	depends on MFD_IPAQ_MICRO
> diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
> index 8fc98f760a8a..0a569d7f0210 100644
> --- a/drivers/video/backlight/Makefile
> +++ b/drivers/video/backlight/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_BACKLIGHT_BD6107)		+= bd6107.o
>  obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE)	+= backlight.o
>  obj-$(CONFIG_BACKLIGHT_DA903X)		+= da903x_bl.o
>  obj-$(CONFIG_BACKLIGHT_DA9052)		+= da9052_bl.o
> +obj-$(CONFIG_BACKLIGHT_APPLE_DWI)	+= dwi_bl.o

Nothing improved here.

Best regards,
Krzysztof



From anshuman.khandual at arm.com  Tue Dec 10 00:38:19 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Dec 2024 14:08:19 +0530
Subject: [PATCH v3 1/2] arm64: refactor the rodata=xxx
In-Reply-To: <CAMj1kXFJhFfhy=Gwm=QrdN6XPUd=7SKNKFBF_Z4eQ30r509BCg@mail.gmail.com>
References: <20241209072020.4743-1-shijie@os.amperecomputing.com>
 <20241209072020.4743-2-shijie@os.amperecomputing.com>
 <d13f1879-7fbc-458d-8fd3-4340b51165fd@arm.com>
 <CAMj1kXFJhFfhy=Gwm=QrdN6XPUd=7SKNKFBF_Z4eQ30r509BCg@mail.gmail.com>
Message-ID: <0224b253-5eae-4921-a066-308033396a73@arm.com>



On 12/10/24 12:51, Ard Biesheuvel wrote:
> On Tue, 10 Dec 2024 at 08:17, Anshuman Khandual
> <anshuman.khandual at arm.com> wrote:
>>
> ...
>>
>> Reformatted and cleaned up the above comment a bit but feel free to
>> improve it further.
>>
>> /*
>>  * rodata=on (default)
>>  *
>>  *    This applies read-only attributes to VM areas and to the linear
>>  *    alias of the backing pages as well. This prevents code or read-
>>  *    only data from being modified (inadvertently or intentionally),
>>  *    via another mapping for the same memory page.
>>  *
>>  *    But this might cause linear map region to be mapped down to base
>>  *    pages, which may adversely affect performance in some cases.
>>  *
>>  * rodata=off
>>  *
>>  *    This provides more block mappings and contiguous hints for linear
>>  *    map region which would minimize TLB footprint. This also leaves
>>  *    read-only kernel memory writable for debugging.
>>  *
>>  * rodata=noalias
>>  *
>>  *    This provides more block mappings and contiguous hints for linear
>>  *    map region which would minimize TLB footprint. Linear aliases of
>>  *    pages belonging to read-only mappings in vmalloc region are also
>>  *    marked as read-only.
>>
> 
> If linear aliases are marked as read-only, how does 'noalias' differ from 'on'?

Right, the last sentence can be can dropped.


From wenst at chromium.org  Tue Dec 10 00:40:08 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 10 Dec 2024 16:40:08 +0800
Subject: [PATCH 1/4] arm64: dts: mediatek: mt8183-kukui-jacuzzi: Drop
 pp3300_panel voltage settings
In-Reply-To: <35392d9d-56a3-4db8-b500-6272d0bd275c@collabora.com>
References: <20241030070224.1006331-1-wenst@chromium.org> <20241030070224.1006331-2-wenst@chromium.org>
 <CAGXv+5HVy41qee6kwVUeLV_DfA0=wk2X77kv81rBKAZDGE6mww@mail.gmail.com>
 <bbaa0c8f-9702-4252-a674-e46fb51f0a2a@collabora.com> <CAGXv+5GHP1M1rKwR8j+bN8GmpxWtpkfLTnvBdkg5wOvWanc-kw@mail.gmail.com>
 <35392d9d-56a3-4db8-b500-6272d0bd275c@collabora.com>
Message-ID: <CAGXv+5H_=He4+vBcaoVbtO05c6hPWV46OTRfR+S8XVuvk_EaYg@mail.gmail.com>

On Tue, Dec 10, 2024 at 4:27?PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Il 04/11/24 14:47, Chen-Yu Tsai ha scritto:
> > On Mon, Nov 4, 2024 at 9:19?PM AngeloGioacchino Del Regno
> > <angelogioacchino.delregno at collabora.com> wrote:
> >>
> >> Il 04/11/24 14:00, Chen-Yu Tsai ha scritto:
> >>> On Wed, Oct 30, 2024 at 3:02?PM Chen-Yu Tsai <wenst at chromium.org> wrote:
> >>>>
> >>>> The pp3300_panel fixed regulator is just a load switch. It does not have
> >>>> any regulating capabilities. Thus having voltage constraints on it is
> >>>> wrong.
> >>>>
> >>>> Remove the voltage constraints.
> >>>>
> >>>> Fixes: cabc71b08eb5 ("arm64: dts: mt8183: Add kukui-jacuzzi-damu board")
> >>>> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> >>>
> >>> I see that the other three patches were merged and included in the pull
> >>> request, but not this one. Were there any concerns?
> >>>
> >>
> >> Sorry I forgot to actually provide an explanation for that - yes, I do have some
> >> comment about this one.
> >>
> >> Despite this being a load switch, it's still switching power from regulator A to
> >> target device X, so this is technically still providing 3.3V to device X.
> >>
> >> Think about how a "regular" full-fledged regulator works: you can (sometimes) set
> >> a voltage, and then you can ENABLE the VOUT for said regulator (/rail): this kind
> >> of "load switch" does exactly the same as the ENABLE switch for a full-fledged
> >> regulator.
> >
> > But it does not provide regulation. One cannot "set" the voltage on a load
> > switch; one can only set it on its upstream supply, if that supply provides
> > regulation.
> >
> > IIRC Mark said some years ago that if a regulator doesn't regulate the
> > voltage, then the voltage constraints should not be given. The constraints
> > are then derived from its upstream supply.
> >
> > That's the guideline I've followed for all the regulator related changes
> > I've done over the years. Does that work for you?
> >
>
> Ok, let's go with that then.
>
> There's only one problem - patches 2 to 4 don't apply for whatever reason, is there
> any dependency?

I believe they were already applied in the previous cycle? At least
they were dropped from my branch automatically after a recent rebase.

ChenYu

> Cheers,
> Angelo
>
> >> So, this is switching on and off a power rail that is derived from a source rail,
> >> practically creating... well, a "new" rail, with...
> >>
> >>    VIN=somewhere-3.3v,
> >>    VOUT=somewhere-still-3.3v
> >>
> >> Any objections/doubts/etc? :-)
> >
> > I agree with most of it, except the part that I laid out above about the
> > load switch not providing regulation.
> >
> >> P.S.: I'm writing fast, sorry if anything appears unclear, feel free to shoot more
> >>         questions in case :-)
> >
> > No, it's pretty clear, and I believe one of the common interpretations
> > I see. Thank you for the quick response.
> >
> >
> > Thanks
> > ChenYu
> >
> >> Cheers,
> >> Angelo
> >>
> >>>
> >>> ChenYu
> >>>
> >>>> ---
> >>>>    arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi | 2 --
> >>>>    1 file changed, 2 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
> >>>> index 783c333107bc..7bbafe926558 100644
> >>>> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
> >>>> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
> >>>> @@ -35,8 +35,6 @@ pp1800_mipibrdg: pp1800-mipibrdg {
> >>>>           pp3300_panel: pp3300-panel {
> >>>>                   compatible = "regulator-fixed";
> >>>>                   regulator-name = "pp3300_panel";
> >>>> -               regulator-min-microvolt = <3300000>;
> >>>> -               regulator-max-microvolt = <3300000>;
> >>>>                   pinctrl-names = "default";
> >>>>                   pinctrl-0 = <&pp3300_panel_pins>;
> >>>>
> >>>> --
> >>>> 2.47.0.163.g1226f6d8fa-goog
> >>>>
> >>
>
>


From krzysztof.kozlowski at linaro.org  Tue Dec 10 00:44:23 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 10 Dec 2024 09:44:23 +0100
Subject: [PATCH 3/3] mailbox: mediatek: Add mtk-apu-mailbox driver
In-Reply-To: <cf75f3c3932ddc50f5697bc4f394bd77fc16cd39.camel@mediatek.com>
References: <20241024092608.431581-1-karl.li@mediatek.com>
 <20241024092608.431581-4-karl.li@mediatek.com>
 <083c8f7b-0969-4ca3-8a91-35f5767c5f32@collabora.com>
 <CAGXv+5Fw+qZhTTgJq0QdiQHgiQP2ByR1tgae2+k4erx+0fp61g@mail.gmail.com>
 <a3c3280478bf86eb97a422782ce60ec4eaa35224.camel@mediatek.com>
 <0f98405c40530d81c342af06dea593e7babedeac.camel@mediatek.com>
 <cf75f3c3932ddc50f5697bc4f394bd77fc16cd39.camel@mediatek.com>
Message-ID: <0d23ccf9-3420-45bf-aac7-5c1a075e031f@linaro.org>

On 05/12/2024 08:32, Karl Li (???) wrote:
> On Thu, 2024-12-05 at 07:05 +0000, Karl Li (???) wrote:
>> Dead maintainers,
> "Dear" maintainers. Really sorry for the typo...
>>
>> I hope you're doing well. Just a warm reminder that we're following
>> up
>> on these patch and really appreciate any feedback you might have.
>>

You received like 6 or 7 reviews/replies for your patchset. What are you
implying here if feedback was not enough?

Respond and implement the feedback instead ignoring it.

NAK

Best regards,
Krzysztof


From arnd at arndb.de  Tue Dec 10 00:45:51 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 10 Dec 2024 09:45:51 +0100
Subject: [PATCH v2 2/2] firmware/arm_ffa: remove __le64_to_cpu() when set uuid for
 direct msg v2
In-Reply-To: <Z1fvkpYvqpnjPZA8@e129823.arm.com>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
 <20241203143109.1030514-3-yeoreum.yun@arm.com>
 <9e60e996-070e-43a7-80e9-efdfda9f6223@app.fastmail.com>
 <Z1ch52AthTYVhtH4@bogus>
 <0cb655ee-9401-41bb-b9cd-580e0aeef2be@app.fastmail.com>
 <Z1fvkpYvqpnjPZA8@e129823.arm.com>
Message-ID: <d750f114-8a25-4c84-912e-b6fb407a5150@app.fastmail.com>

On Tue, Dec 10, 2024, at 08:36, Yeoreum Yun wrote:
>> On Mon, Dec 9, 2024, at 17:59, Sudeep Holla wrote:
>> > On Mon, Dec 09, 2024 at 04:27:14PM +0100, Arnd Bergmann wrote:
>>
>> Looking through the other functions in drivers/firmware/arm_ffa/driver.c,
>> I see that most of them just match the specification. One exception
>> is ffa_notification_info_get(), which incorrectly casts the
>> argument response arguments to an array of 'u16' values. Using
>> the correct bit shifts according to the specification would
>> make that work on big-endian and also more readable and
>> robust. Another one is __ffa_partition_info_get_regs(), which
>> does an incorrect memcpy() instead of decoding the values.
>>
> Conclusionly, Yes. But the RFC 4122 said with network byte order.
> to describe how uuid is saved.
>
> but I think the endianess to load the register is not a choice.
> because the spec says:
>
>     UUID Lo  x2  Bytes[0...7] of UUID with byte 0 in the low-order bits.
>     UUID Hi  x3  Bytes[8...15] of UUID with byte 8 in the low-order bits.
>
> this means UUID.bytes[0] should be loaded to x2.bytes[0].
>            UUID.bytes[1] should be loaded to x2,bytes[1]
>            ...

I meant they had the choice and chose to specify little-endian
64-bit word to encode the sequence of bytes of the standard
in-memory representation of UUIDs. 

> That's why other software spec (i.e tf-a) doesn't loads UUID from register
> wihtout swapping byte with endianess but just copy it.

If the uuid is transferred in memory, you obviously don't want to
swap it. If they pass it in registers across different endianess
code without specifying the byteorder in the caller, then they
would have the same bug.

> The bug is "not send UUID according to spec" in kernel side
> That's why it fails when I send message  with direct message version 2.
> So, it''s not change code unportable to portable but it fixes according
> to spec (load UUID as it is in register wihtout endianess).

Sorry, but you are not making sense here.

Sudeep, should I just cherry-pick your other fix from the pull
request and ignore this patch?

      Arnd


From krzysztof.kozlowski at linaro.org  Tue Dec 10 00:45:04 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 10 Dec 2024 09:45:04 +0100
Subject: [PATCH 3/3] mailbox: mediatek: Add mtk-apu-mailbox driver
In-Reply-To: <0d23ccf9-3420-45bf-aac7-5c1a075e031f@linaro.org>
References: <20241024092608.431581-1-karl.li@mediatek.com>
 <20241024092608.431581-4-karl.li@mediatek.com>
 <083c8f7b-0969-4ca3-8a91-35f5767c5f32@collabora.com>
 <CAGXv+5Fw+qZhTTgJq0QdiQHgiQP2ByR1tgae2+k4erx+0fp61g@mail.gmail.com>
 <a3c3280478bf86eb97a422782ce60ec4eaa35224.camel@mediatek.com>
 <0f98405c40530d81c342af06dea593e7babedeac.camel@mediatek.com>
 <cf75f3c3932ddc50f5697bc4f394bd77fc16cd39.camel@mediatek.com>
 <0d23ccf9-3420-45bf-aac7-5c1a075e031f@linaro.org>
Message-ID: <b8c1c4d9-3234-4184-b57c-8cd5cb18f815@linaro.org>

On 10/12/2024 09:44, Krzysztof Kozlowski wrote:
> On 05/12/2024 08:32, Karl Li (???) wrote:
>> On Thu, 2024-12-05 at 07:05 +0000, Karl Li (???) wrote:
>>> Dead maintainers,
>> "Dear" maintainers. Really sorry for the typo...
>>>
>>> I hope you're doing well. Just a warm reminder that we're following
>>> up
>>> on these patch and really appreciate any feedback you might have.
>>>
> 
> You received like 6 or 7 reviews/replies for your patchset. What are you
> implying here if feedback was not enough?
> 
> Respond and implement the feedback instead ignoring it.
> 

Ah - and obvious static check warnings as well!

Please run standard kernel tools for static analysis, like coccinelle,
smatch and sparse, and fix reported warnings. Also please check for
warnings when building with W=1. Most of these commands (checks or W=1
build) can build specific targets, like some directory, to narrow the
scope to only your code. The code here looks like it needs a fix. Feel
free to get in touch if the warning is not clear.

Best regards,
Krzysztof



From towinchenmi at gmail.com  Tue Dec 10 00:47:11 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Tue, 10 Dec 2024 16:47:11 +0800
Subject: [PATCH v3 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <w5niokvjfwajnzz3muccb45jsvqzg7lql7g5tg5s6iat3mtqkk@qu2a5zcp3rs7>
References: <20241209075908.140014-1-towinchenmi@gmail.com>
 <20241209075908.140014-3-towinchenmi@gmail.com>
 <w5niokvjfwajnzz3muccb45jsvqzg7lql7g5tg5s6iat3mtqkk@qu2a5zcp3rs7>
Message-ID: <23e6d9c0-c3d6-40c1-b933-01c5a9ef43f8@gmail.com>



Krzysztof Kozlowski ? 2024/12/10 ??4:32 ??:

> Nothing improved here.


This is sent before you left any review, v4 will have improvements

Nick Chan


From alexandre.torgue at foss.st.com  Tue Dec 10 00:46:33 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Tue, 10 Dec 2024 09:46:33 +0100
Subject: [PATCH 0/6] ARM: dts: stm32: lxa-tac: fix gen{1,2} boards and add
 gen3 board
In-Reply-To: <20241119-lxa-tac-gen3-v1-0-e0ab0a369372@pengutronix.de>
References: <20241119-lxa-tac-gen3-v1-0-e0ab0a369372@pengutronix.de>
Message-ID: <8cda7859-523c-4850-8b89-9d9c9bf07cb6@foss.st.com>

Hi Marc

On 11/19/24 12:34, Marc Kleine-Budde wrote:
> Hello,
> 
> this series fixes some problems found in the lxa-tac generation 1 and
> 2 boards and add support for the generation 3 board. It's based on an
> STM32MP153c, while the generation 1 and 2 are based on the
> STM32MP157c.
> 
> regards,
> Marc
> 
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
> Leonard G?hrs (6):
>        ARM: dts: stm32: lxa-tac: disable the real time clock
>        ARM: dts: stm32: lxa-tac: extend the alias table
>        ARM: dts: stm32: lxa-tac: adjust USB gadget fifo sizes for multi function
>        dt-bindings: arm: stm32: add compatible strings for Linux Automation LXA TAC gen 3
>        ARM: dts: stm32: lxa-tac: move adc and gpio{e,g} to gen{1,2} boards
>        ARM: dts: stm32: lxa-tac: Add support for generation 3 devices
> 
>   .../devicetree/bindings/arm/stm32/stm32.yaml       |   7 +
>   arch/arm/boot/dts/st/Makefile                      |   1 +
>   arch/arm/boot/dts/st/stm32mp153c-lxa-tac-gen3.dts  | 267 +++++++++++++++++++++
>   arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen1.dts  |  84 +++++++
>   arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen2.dts  |  84 +++++++
>   arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi      | 100 +-------
>   6 files changed, 455 insertions(+), 88 deletions(-)
> ---
> base-commit: b0191a5cbc222fc7af3f9511b44d1f330ef980e9
> change-id: 20241112-lxa-tac-gen3-8dbc3481ce7a
> 
> Best regards,

Series applied on stm32-next.

Thanks!
Alex


From frawang.cn at gmail.com  Tue Dec 10 00:50:53 2024
From: frawang.cn at gmail.com (Frank Wang)
Date: Tue, 10 Dec 2024 16:50:53 +0800
Subject: [PATCH] arm64: dts: rockchip: add usb related nodes for rk3576
Message-ID: <20241210085053.64294-1-frawang.cn@gmail.com>

From: Frank Wang <frank.wang at rock-chips.com>

This adds USB and USB-PHY related nodes for RK3576 SoC.

Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
---
The compatible string "rockchip,rk3576-naneng-combphy" in the patch
depends on the following commit which has not merged into this branch.
 - https://patchwork.kernel.org/project/linux-phy/patch/20241106021357.19782-1-frawang.cn at gmail.com/

 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 169 +++++++++++++++++++++++
 1 file changed, 169 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index 436232ffe4d1..70cfa099089a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -445,6 +445,58 @@ soc {
 		#size-cells = <2>;
 		ranges;
 
+		usb_drd0_dwc3: usb at 23000000 {
+			compatible = "rockchip,rk3576-dwc3", "snps,dwc3";
+			reg = <0x0 0x23000000 0x0 0x400000>;
+			clocks = <&cru CLK_REF_USB3OTG0>,
+				 <&cru CLK_SUSPEND_USB3OTG0>,
+				 <&cru ACLK_USB3OTG0>;
+			clock-names = "ref_clk", "suspend_clk", "bus_clk";
+			interrupts = <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&power RK3576_PD_USB>;
+			resets = <&cru SRST_A_USB3OTG0>;
+			dr_mode = "otg";
+			phys = <&u2phy0_otg>, <&usbdp_phy PHY_TYPE_USB3>;
+			phy-names = "usb2-phy", "usb3-phy";
+			phy_type = "utmi_wide";
+			snps,dis_enblslpm_quirk;
+			snps,dis-u1-entry-quirk;
+			snps,dis-u2-entry-quirk;
+			snps,dis-u2-freeclk-exists-quirk;
+			snps,dis-del-phy-power-chg-quirk;
+			snps,dis-tx-ipgap-linecheck-quirk;
+			snps,parkmode-disable-hs-quirk;
+			snps,parkmode-disable-ss-quirk;
+			status = "disabled";
+		};
+
+		usb_drd1_dwc3: usb at 23400000 {
+			compatible = "rockchip,rk3576-dwc3", "snps,dwc3";
+			reg = <0x0 0x23400000 0x0 0x400000>;
+			clocks = <&cru CLK_REF_USB3OTG1>,
+				 <&cru CLK_SUSPEND_USB3OTG1>,
+				 <&cru ACLK_USB3OTG1>;
+			clock-names = "ref_clk", "suspend_clk", "bus_clk";
+			interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&power RK3576_PD_PHP>;
+			resets = <&cru SRST_A_USB3OTG1>;
+			dr_mode = "otg";
+			phys = <&u2phy1_otg>, <&combphy1_psu PHY_TYPE_USB3>;
+			phy-names = "usb2-phy", "usb3-phy";
+			phy_type = "utmi_wide";
+			snps,dis_enblslpm_quirk;
+			snps,dis-u1-entry-quirk;
+			snps,dis-u2-entry-quirk;
+			snps,dis-u2-freeclk-exists-quirk;
+			snps,dis-del-phy-power-chg-quirk;
+			snps,dis-tx-ipgap-linecheck-quirk;
+			snps,dis_rxdet_inp3_quirk;
+			snps,parkmode-disable-hs-quirk;
+			snps,parkmode-disable-ss-quirk;
+			dma-coherent;
+			status = "disabled";
+		};
+
 		sys_grf: syscon at 2600a000 {
 			compatible = "rockchip,rk3576-sys-grf", "syscon";
 			reg = <0x0 0x2600a000 0x0 0x2000>;
@@ -515,6 +567,65 @@ usbdpphy_grf: syscon at 2602c000 {
 			reg = <0x0 0x2602c000 0x0 0x2000>;
 		};
 
+		usb2phy_grf: syscon at 2602e000 {
+			compatible = "rockchip,rk3576-usb2phy-grf", "syscon", "simple-mfd";
+			reg = <0x0 0x2602e000 0x0 0x4000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			u2phy0: usb2-phy at 0 {
+				compatible = "rockchip,rk3576-usb2phy";
+				reg = <0x0 0x10>;
+				resets = <&cru SRST_OTGPHY_0>, <&cru SRST_P_USBPHY_GRF_0>;
+				reset-names = "phy", "apb";
+				clocks = <&cru CLK_PHY_REF_SRC>,
+					 <&cru ACLK_MMU2>,
+					 <&cru ACLK_SLV_MMU2>;
+				clock-names = "phyclk", "aclk", "aclk_slv";
+				clock-output-names = "usb480m_phy0";
+				#clock-cells = <0>;
+				status = "disabled";
+
+				u2phy0_otg: otg-port {
+					#phy-cells = <0>;
+					interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH>,
+						     <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
+						     <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+					interrupt-names = "otg-bvalid", "otg-id", "linestate";
+					status = "disabled";
+				};
+			};
+
+			u2phy1: usb2-phy at 2000 {
+				compatible = "rockchip,rk3576-usb2phy";
+				reg = <0x2000 0x10>;
+				resets = <&cru SRST_OTGPHY_1>, <&cru SRST_P_USBPHY_GRF_1>;
+				reset-names = "phy", "apb";
+				clocks = <&cru CLK_PHY_REF_SRC>,
+					 <&cru ACLK_MMU1>,
+					 <&cru ACLK_SLV_MMU1>;
+				clock-names = "phyclk", "aclk", "aclk_slv";
+				clock-output-names = "usb480m_phy1";
+				#clock-cells = <0>;
+				status = "disabled";
+
+				u2phy1_otg: otg-port {
+					#phy-cells = <0>;
+					interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>,
+						     <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>,
+						     <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+					interrupt-names = "otg-bvalid", "otg-id", "linestate";
+					status = "disabled";
+				};
+			};
+		};
+
+		vo1_grf: syscon at 26036000 {
+			compatible = "rockchip,rk3576-vo1-grf", "syscon";
+			reg = <0x0 0x26036000 0x0 0x100>;
+			clocks = <&cru PCLK_VO1_ROOT>;
+		};
+
 		sdgmac_grf: syscon at 26038000 {
 			compatible = "rockchip,rk3576-sdgmac-grf", "syscon";
 			reg = <0x0 0x26038000 0x0 0x1000>;
@@ -1587,6 +1698,64 @@ uart11: serial at 2afd0000 {
 			status = "disabled";
 		};
 
+		usbdp_phy: phy at 2b010000 {
+			compatible = "rockchip,rk3576-usbdp-phy";
+			reg = <0x0 0x2b010000 0x0 0x10000>;
+			#phy-cells = <1>;
+			clocks = <&cru CLK_PHY_REF_SRC >,
+				 <&cru CLK_USBDP_COMBO_PHY_IMMORTAL>,
+				 <&cru PCLK_USBDPPHY>,
+				 <&u2phy0>;
+			clock-names = "refclk", "immortal", "pclk", "utmi";
+			resets = <&cru SRST_USBDP_COMBO_PHY_INIT>,
+				 <&cru SRST_USBDP_COMBO_PHY_CMN>,
+				 <&cru SRST_USBDP_COMBO_PHY_LANE>,
+				 <&cru SRST_USBDP_COMBO_PHY_PCS>,
+				 <&cru SRST_P_USBDPPHY>;
+			reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+			rockchip,u2phy-grf = <&usb2phy_grf>;
+			rockchip,usb-grf = <&usb_grf>;
+			rockchip,usbdpphy-grf = <&usbdpphy_grf>;
+			rockchip,vo-grf = <&vo1_grf>;
+			status = "disabled";
+		};
+
+		combphy0_ps: phy at 2b050000 {
+			compatible = "rockchip,rk3576-naneng-combphy";
+			reg = <0x0 0x2b050000 0x0 0x100>;
+			#phy-cells = <1>;
+			clocks = <&cru CLK_REF_PCIE0_PHY>,
+				 <&cru PCLK_PCIE2_COMBOPHY0>,
+				 <&cru PCLK_PCIE0>;
+			clock-names = "ref", "apb", "pipe";
+			assigned-clocks = <&cru CLK_REF_PCIE0_PHY>;
+			assigned-clock-rates = <100000000>;
+			resets = <&cru SRST_PCIE0_PIPE_PHY>,
+				 <&cru SRST_P_PCIE2_COMBOPHY0>;
+			reset-names = "phy", "apb";
+			rockchip,pipe-grf = <&php_grf>;
+			rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
+			status = "disabled";
+		};
+
+		combphy1_psu: phy at 2b060000 {
+			compatible = "rockchip,rk3576-naneng-combphy";
+			reg = <0x0 0x2b060000 0x0 0x100>;
+			#phy-cells = <1>;
+			clocks = <&cru CLK_REF_PCIE1_PHY>,
+				 <&cru PCLK_PCIE2_COMBOPHY1>,
+				 <&cru PCLK_PCIE1>;
+			clock-names = "ref", "apb", "pipe";
+			assigned-clocks = <&cru CLK_REF_PCIE1_PHY>;
+			assigned-clock-rates = <100000000>;
+			resets = <&cru SRST_PCIE1_PIPE_PHY>,
+				 <&cru SRST_P_PCIE2_COMBOPHY1>;
+			reset-names = "phy", "apb";
+			rockchip,pipe-grf = <&php_grf>;
+			rockchip,pipe-phy-grf = <&pipe_phy1_grf>;
+			status = "disabled";
+		};
+
 		sram: sram at 3ff88000 {
 			compatible = "mmio-sram";
 			reg = <0x0 0x3ff88000 0x0 0x78000>;
-- 
2.25.1



From andy.yan at rock-chips.com  Tue Dec 10 00:50:18 2024
From: andy.yan at rock-chips.com (Andy Yan)
Date: Tue, 10 Dec 2024 16:50:18 +0800
Subject: [PATCH v4 1/3] drm/bridge/synopsys: Add MIPI DSI2 host controller
 bridge
In-Reply-To: <20241209231021.2180582-2-heiko@sntech.de>
References: <20241209231021.2180582-1-heiko@sntech.de>
 <20241209231021.2180582-2-heiko@sntech.de>
Message-ID: <3facea6a-8229-465f-b17d-89daf7b4f856@rock-chips.com>

Hello Heiko,

On 12/10/24 07:10, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> Add a Synopsys Designware MIPI DSI host DRM bridge driver for their
> DSI2 host controller, based on the Rockchip version from the driver
> rockchip/dw-mipi-dsi2.c in their vendor-kernel with phy & bridge APIs.
> 
> While the driver is heavily modelled after the previous IP, the register
> set of this DSI2 controller is completely different and there are also
> additional properties like the variable-width phy interface.
> 
> Tested-by: Daniel Semkowicz <dse at thaumatec.com>
> Tested-by: Dmitry Yashin <dmt.yashin at gmail.com>
> Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>

   Reviewed-by: Andy Yan <andy.yan at rock-chips.com>
> ---
>   drivers/gpu/drm/bridge/synopsys/Kconfig       |    6 +
>   drivers/gpu/drm/bridge/synopsys/Makefile      |    1 +
>   .../gpu/drm/bridge/synopsys/dw-mipi-dsi2.c    | 1030 +++++++++++++++++
>   include/drm/bridge/dw_mipi_dsi2.h             |   95 ++
>   4 files changed, 1132 insertions(+)
>   create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
>   create mode 100644 include/drm/bridge/dw_mipi_dsi2.h
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> index ca416dab156d..f3ab2f985f8c 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> @@ -59,3 +59,9 @@ config DRM_DW_MIPI_DSI
>   	select DRM_KMS_HELPER
>   	select DRM_MIPI_DSI
>   	select DRM_PANEL_BRIDGE
> +
> +config DRM_DW_MIPI_DSI2
> +	tristate
> +	select DRM_KMS_HELPER
> +	select DRM_MIPI_DSI
> +	select DRM_PANEL_BRIDGE
> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
> index 9869d9651ed1..9dc376d220ad 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> @@ -8,3 +8,4 @@ obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
>   obj-$(CONFIG_DRM_DW_HDMI_QP) += dw-hdmi-qp.o
>   
>   obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
> +obj-$(CONFIG_DRM_DW_MIPI_DSI2) += dw-mipi-dsi2.o
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
> new file mode 100644
> index 000000000000..054ad39c451b
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
> @@ -0,0 +1,1030 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2024, Fuzhou Rockchip Electronics Co., Ltd
> + *
> + * Modified by Heiko Stuebner <heiko.stuebner at cherry.de>
> + * This generic Synopsys DesignWare MIPI DSI2 host driver is based on the
> + * Rockchip version from rockchip/dw-mipi-dsi2.c converted to use bridge APIs.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/iopoll.h>
> +#include <linux/media-bus-format.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/reset.h>
> +
> +#include <video/mipi_display.h>
> +
> +#include <drm/bridge/dw_mipi_dsi2.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_print.h>
> +
> +#define DSI2_PWR_UP			0x000c
> +#define RESET				0
> +#define POWER_UP			BIT(0)
> +#define CMD_TX_MODE(x)			FIELD_PREP(BIT(24), x)
> +#define DSI2_SOFT_RESET			0x0010
> +#define SYS_RSTN			BIT(2)
> +#define PHY_RSTN			BIT(1)
> +#define IPI_RSTN			BIT(0)
> +#define INT_ST_MAIN			0x0014
> +#define DSI2_MODE_CTRL			0x0018
> +#define DSI2_MODE_STATUS		0x001c
> +#define DSI2_CORE_STATUS		0x0020
> +#define PRI_RD_DATA_AVAIL		BIT(26)
> +#define PRI_FIFOS_NOT_EMPTY		BIT(25)
> +#define PRI_BUSY			BIT(24)
> +#define CRI_RD_DATA_AVAIL		BIT(18)
> +#define CRT_FIFOS_NOT_EMPTY		BIT(17)
> +#define CRI_BUSY			BIT(16)
> +#define IPI_FIFOS_NOT_EMPTY		BIT(9)
> +#define IPI_BUSY			BIT(8)
> +#define CORE_FIFOS_NOT_EMPTY		BIT(1)
> +#define CORE_BUSY			BIT(0)
> +#define MANUAL_MODE_CFG			0x0024
> +#define MANUAL_MODE_EN			BIT(0)
> +#define DSI2_TIMEOUT_HSTX_CFG		0x0048
> +#define TO_HSTX(x)			FIELD_PREP(GENMASK(15, 0), x)
> +#define DSI2_TIMEOUT_HSTXRDY_CFG	0x004c
> +#define TO_HSTXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
> +#define DSI2_TIMEOUT_LPRX_CFG		0x0050
> +#define TO_LPRXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
> +#define DSI2_TIMEOUT_LPTXRDY_CFG	0x0054
> +#define TO_LPTXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
> +#define DSI2_TIMEOUT_LPTXTRIG_CFG	0x0058
> +#define TO_LPTXTRIG(x)			FIELD_PREP(GENMASK(15, 0), x)
> +#define DSI2_TIMEOUT_LPTXULPS_CFG	0x005c
> +#define TO_LPTXULPS(x)			FIELD_PREP(GENMASK(15, 0), x)
> +#define DSI2_TIMEOUT_BTA_CFG		0x60
> +#define TO_BTA(x)			FIELD_PREP(GENMASK(15, 0), x)
> +
> +#define DSI2_PHY_MODE_CFG		0x0100
> +#define PPI_WIDTH(x)			FIELD_PREP(GENMASK(9, 8), x)
> +#define PHY_LANES(x)			FIELD_PREP(GENMASK(5, 4), (x) - 1)
> +#define PHY_TYPE(x)			FIELD_PREP(BIT(0), x)
> +#define DSI2_PHY_CLK_CFG		0X0104
> +#define PHY_LPTX_CLK_DIV(x)		FIELD_PREP(GENMASK(12, 8), x)
> +#define CLK_TYPE_MASK			BIT(0)
> +#define NON_CONTINUOUS_CLK		BIT(0)
> +#define CONTINUOUS_CLK			0
> +#define DSI2_PHY_LP2HS_MAN_CFG		0x010c
> +#define PHY_LP2HS_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
> +#define DSI2_PHY_HS2LP_MAN_CFG		0x0114
> +#define PHY_HS2LP_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
> +#define DSI2_PHY_MAX_RD_T_MAN_CFG	0x011c
> +#define PHY_MAX_RD_TIME(x)		FIELD_PREP(GENMASK(26, 0), x)
> +#define DSI2_PHY_ESC_CMD_T_MAN_CFG	0x0124
> +#define PHY_ESC_CMD_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
> +#define DSI2_PHY_ESC_BYTE_T_MAN_CFG	0x012c
> +#define PHY_ESC_BYTE_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
> +
> +#define DSI2_PHY_IPI_RATIO_MAN_CFG	0x0134
> +#define PHY_IPI_RATIO(x)		FIELD_PREP(GENMASK(21, 0), x)
> +#define DSI2_PHY_SYS_RATIO_MAN_CFG	0x013C
> +#define PHY_SYS_RATIO(x)		FIELD_PREP(GENMASK(16, 0), x)
> +
> +#define DSI2_DSI_GENERAL_CFG		0x0200
> +#define BTA_EN				BIT(1)
> +#define EOTP_TX_EN			BIT(0)
> +#define DSI2_DSI_VCID_CFG		0x0204
> +#define TX_VCID(x)			FIELD_PREP(GENMASK(1, 0), x)
> +#define DSI2_DSI_SCRAMBLING_CFG		0x0208
> +#define SCRAMBLING_SEED(x)		FIELD_PREP(GENMASK(31, 16), x)
> +#define SCRAMBLING_EN			BIT(0)
> +#define DSI2_DSI_VID_TX_CFG		0x020c
> +#define LPDT_DISPLAY_CMD_EN		BIT(20)
> +#define BLK_VFP_HS_EN			BIT(14)
> +#define BLK_VBP_HS_EN			BIT(13)
> +#define BLK_VSA_HS_EN			BIT(12)
> +#define BLK_HFP_HS_EN			BIT(6)
> +#define BLK_HBP_HS_EN			BIT(5)
> +#define BLK_HSA_HS_EN			BIT(4)
> +#define VID_MODE_TYPE(x)		FIELD_PREP(GENMASK(1, 0), x)
> +#define DSI2_CRI_TX_HDR			0x02c0
> +#define CMD_TX_MODE(x)			FIELD_PREP(BIT(24), x)
> +#define DSI2_CRI_TX_PLD			0x02c4
> +#define DSI2_CRI_RX_HDR			0x02c8
> +#define DSI2_CRI_RX_PLD			0x02cc
> +
> +#define DSI2_IPI_COLOR_MAN_CFG		0x0300
> +#define IPI_DEPTH(x)			FIELD_PREP(GENMASK(7, 4), x)
> +#define IPI_DEPTH_5_6_5_BITS		0x02
> +#define IPI_DEPTH_6_BITS		0x03
> +#define IPI_DEPTH_8_BITS		0x05
> +#define IPI_DEPTH_10_BITS		0x06
> +#define IPI_FORMAT(x)			FIELD_PREP(GENMASK(3, 0), x)
> +#define IPI_FORMAT_RGB			0x0
> +#define IPI_FORMAT_DSC			0x0b
> +#define DSI2_IPI_VID_HSA_MAN_CFG	0x0304
> +#define VID_HSA_TIME(x)			FIELD_PREP(GENMASK(29, 0), x)
> +#define DSI2_IPI_VID_HBP_MAN_CFG	0x030c
> +#define VID_HBP_TIME(x)			FIELD_PREP(GENMASK(29, 0), x)
> +#define DSI2_IPI_VID_HACT_MAN_CFG	0x0314
> +#define VID_HACT_TIME(x)		FIELD_PREP(GENMASK(29, 0), x)
> +#define DSI2_IPI_VID_HLINE_MAN_CFG	0x031c
> +#define VID_HLINE_TIME(x)		FIELD_PREP(GENMASK(29, 0), x)
> +#define DSI2_IPI_VID_VSA_MAN_CFG	0x0324
> +#define VID_VSA_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
> +#define DSI2_IPI_VID_VBP_MAN_CFG	0X032C
> +#define VID_VBP_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
> +#define DSI2_IPI_VID_VACT_MAN_CFG	0X0334
> +#define VID_VACT_LINES(x)		FIELD_PREP(GENMASK(13, 0), x)
> +#define DSI2_IPI_VID_VFP_MAN_CFG	0X033C
> +#define VID_VFP_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
> +#define DSI2_IPI_PIX_PKT_CFG		0x0344
> +#define MAX_PIX_PKT(x)			FIELD_PREP(GENMASK(15, 0), x)
> +
> +#define DSI2_INT_ST_PHY			0x0400
> +#define DSI2_INT_MASK_PHY		0x0404
> +#define DSI2_INT_ST_TO			0x0410
> +#define DSI2_INT_MASK_TO		0x0414
> +#define DSI2_INT_ST_ACK			0x0420
> +#define DSI2_INT_MASK_ACK		0x0424
> +#define DSI2_INT_ST_IPI			0x0430
> +#define DSI2_INT_MASK_IPI		0x0434
> +#define DSI2_INT_ST_FIFO		0x0440
> +#define DSI2_INT_MASK_FIFO		0x0444
> +#define DSI2_INT_ST_PRI			0x0450
> +#define DSI2_INT_MASK_PRI		0x0454
> +#define DSI2_INT_ST_CRI			0x0460
> +#define DSI2_INT_MASK_CRI		0x0464
> +#define DSI2_INT_FORCE_CRI		0x0468
> +#define DSI2_MAX_REGISGER		DSI2_INT_FORCE_CRI
> +
> +#define MODE_STATUS_TIMEOUT_US		10000
> +#define CMD_PKT_STATUS_TIMEOUT_US	20000
> +
> +enum vid_mode_type {
> +	VID_MODE_TYPE_NON_BURST_SYNC_PULSES,
> +	VID_MODE_TYPE_NON_BURST_SYNC_EVENTS,
> +	VID_MODE_TYPE_BURST,
> +};
> +
> +enum mode_ctrl {
> +	IDLE_MODE,
> +	AUTOCALC_MODE,
> +	COMMAND_MODE,
> +	VIDEO_MODE,
> +	DATA_STREAM_MODE,
> +	VIDEO_TEST_MODE,
> +	DATA_STREAM_TEST_MODE,
> +};
> +
> +enum ppi_width {
> +	PPI_WIDTH_8_BITS,
> +	PPI_WIDTH_16_BITS,
> +	PPI_WIDTH_32_BITS,
> +};
> +
> +struct cmd_header {
> +	u8 cmd_type;
> +	u8 delay;
> +	u8 payload_length;
> +};
> +
> +struct dw_mipi_dsi2 {
> +	struct drm_bridge bridge;
> +	struct mipi_dsi_host dsi_host;
> +	struct drm_bridge *panel_bridge;
> +	struct device *dev;
> +	struct regmap *regmap;
> +	struct clk *pclk;
> +	struct clk *sys_clk;
> +
> +	unsigned int lane_mbps; /* per lane */
> +	u32 channel;
> +	u32 lanes;
> +	u32 format;
> +	unsigned long mode_flags;
> +
> +	struct drm_display_mode mode;
> +	const struct dw_mipi_dsi2_plat_data *plat_data;
> +};
> +
> +static inline struct dw_mipi_dsi2 *host_to_dsi2(struct mipi_dsi_host *host)
> +{
> +	return container_of(host, struct dw_mipi_dsi2, dsi_host);
> +}
> +
> +static inline struct dw_mipi_dsi2 *bridge_to_dsi2(struct drm_bridge *bridge)
> +{
> +	return container_of(bridge, struct dw_mipi_dsi2, bridge);
> +}
> +
> +static int cri_fifos_wait_avail(struct dw_mipi_dsi2 *dsi2)
> +{
> +	u32 sts, mask;
> +	int ret;
> +
> +	mask = CRI_BUSY | CRT_FIFOS_NOT_EMPTY;
> +	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS, sts,
> +				       !(sts & mask), 0, CMD_PKT_STATUS_TIMEOUT_US);
> +	if (ret < 0) {
> +		dev_err(dsi2->dev, "command interface is busy\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_set_vid_mode(struct dw_mipi_dsi2 *dsi2)
> +{
> +	u32 val = 0, mode;
> +	int ret;
> +
> +	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP)
> +		val |= BLK_HFP_HS_EN;
> +
> +	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP)
> +		val |= BLK_HBP_HS_EN;
> +
> +	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HSA)
> +		val |= BLK_HSA_HS_EN;
> +
> +	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
> +		val |= VID_MODE_TYPE_BURST;
> +	else if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
> +		val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES;
> +	else
> +		val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
> +
> +	regmap_write(dsi2->regmap, DSI2_DSI_VID_TX_CFG, val);
> +
> +	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, VIDEO_MODE);
> +	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
> +				       mode, mode & VIDEO_MODE,
> +				       1000, MODE_STATUS_TIMEOUT_US);
> +	if (ret < 0)
> +		dev_err(dsi2->dev, "failed to enter video mode\n");
> +}
> +
> +static void dw_mipi_dsi2_set_data_stream_mode(struct dw_mipi_dsi2 *dsi2)
> +{
> +	u32 mode;
> +	int ret;
> +
> +	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, DATA_STREAM_MODE);
> +	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
> +				       mode, mode & DATA_STREAM_MODE,
> +				       1000, MODE_STATUS_TIMEOUT_US);
> +	if (ret < 0)
> +		dev_err(dsi2->dev, "failed to enter data stream mode\n");
> +}
> +
> +static void dw_mipi_dsi2_set_cmd_mode(struct dw_mipi_dsi2 *dsi2)
> +{
> +	u32 mode;
> +	int ret;
> +
> +	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, COMMAND_MODE);
> +	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
> +				       mode, mode & COMMAND_MODE,
> +				       1000, MODE_STATUS_TIMEOUT_US);
> +	if (ret < 0)
> +		dev_err(dsi2->dev, "failed to enter data stream mode\n");
> +}
> +
> +static void dw_mipi_dsi2_host_softrst(struct dw_mipi_dsi2 *dsi2)
> +{
> +	regmap_write(dsi2->regmap, DSI2_SOFT_RESET, 0x0);
> +	usleep_range(50, 100);
> +	regmap_write(dsi2->regmap, DSI2_SOFT_RESET,
> +		   SYS_RSTN | PHY_RSTN | IPI_RSTN);
> +}
> +
> +static void dw_mipi_dsi2_phy_clk_mode_cfg(struct dw_mipi_dsi2 *dsi2)
> +{
> +	u32 sys_clk, esc_clk_div;
> +	u32 val = 0;
> +
> +	/*
> +	 * clk_type should be NON_CONTINUOUS_CLK before
> +	 * initial deskew calibration be sent.
> +	 */
> +	val |= NON_CONTINUOUS_CLK;
> +
> +	/* The maximum value of the escape clock frequency is 20MHz */
> +	sys_clk = clk_get_rate(dsi2->sys_clk) / USEC_PER_SEC;
> +	esc_clk_div = DIV_ROUND_UP(sys_clk, 20 * 2);
> +	val |= PHY_LPTX_CLK_DIV(esc_clk_div);
> +
> +	regmap_write(dsi2->regmap, DSI2_PHY_CLK_CFG, val);
> +}
> +
> +static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2)
> +{
> +	struct drm_display_mode *mode = &dsi2->mode;
> +	u64 sys_clk = clk_get_rate(dsi2->sys_clk);
> +	u64 pixel_clk, ipi_clk, phy_hsclk;
> +	u64 tmp;
> +
> +	/*
> +	 * in DPHY mode, the phy_hstx_clk is exactly 1/16 the Lane high-speed
> +	 * data rate; In CPHY mode, the phy_hstx_clk is exactly 1/7 the trio
> +	 * high speed symbol rate.
> +	 */
> +	phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
> +
> +	/* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */
> +	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
> +	ipi_clk = pixel_clk / 4;
> +
> +	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, ipi_clk);
> +	regmap_write(dsi2->regmap, DSI2_PHY_IPI_RATIO_MAN_CFG,
> +		   PHY_IPI_RATIO(tmp));
> +
> +	/*
> +	 * SYS_RATIO_MAN_CFG = MIPI_DCPHY_HSCLK_Freq / MIPI_DCPHY_HSCLK_Freq
> +	 */
> +	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, sys_clk);
> +	regmap_write(dsi2->regmap, DSI2_PHY_SYS_RATIO_MAN_CFG,
> +		   PHY_SYS_RATIO(tmp));
> +}
> +
> +static void dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(struct dw_mipi_dsi2 *dsi2)
> +{
> +	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
> +	struct dw_mipi_dsi2_phy_timing timing;
> +	int ret;
> +
> +	ret = phy_ops->get_timing(dsi2->plat_data->priv_data,
> +				  dsi2->lane_mbps, &timing);
> +	if (ret)
> +		dev_err(dsi2->dev, "Retrieving phy timings failed\n");
> +
> +	regmap_write(dsi2->regmap, DSI2_PHY_LP2HS_MAN_CFG, PHY_LP2HS_TIME(timing.data_lp2hs));
> +	regmap_write(dsi2->regmap, DSI2_PHY_HS2LP_MAN_CFG, PHY_HS2LP_TIME(timing.data_hs2lp));
> +}
> +
> +static void dw_mipi_dsi2_phy_init(struct dw_mipi_dsi2 *dsi2)
> +{
> +	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
> +	struct dw_mipi_dsi2_phy_iface iface;
> +	u32 val = 0;
> +
> +	phy_ops->get_interface(dsi2->plat_data->priv_data, &iface);
> +
> +	switch (iface.ppi_width) {
> +	case 8:
> +		val |= PPI_WIDTH(PPI_WIDTH_8_BITS);
> +		break;
> +	case 16:
> +		val |= PPI_WIDTH(PPI_WIDTH_16_BITS);
> +		break;
> +	case 32:
> +		val |= PPI_WIDTH(PPI_WIDTH_32_BITS);
> +		break;
> +	default:
> +		/* Caught in probe */
> +		break;
> +	}
> +
> +	val |= PHY_LANES(dsi2->lanes);
> +	val |= PHY_TYPE(DW_MIPI_DSI2_DPHY);
> +	regmap_write(dsi2->regmap, DSI2_PHY_MODE_CFG, val);
> +
> +	dw_mipi_dsi2_phy_clk_mode_cfg(dsi2);
> +	dw_mipi_dsi2_phy_ratio_cfg(dsi2);
> +	dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2);
> +
> +	/* phy configuration 8 - 10 */
> +}
> +
> +static void dw_mipi_dsi2_tx_option_set(struct dw_mipi_dsi2 *dsi2)
> +{
> +	u32 val;
> +
> +	val = BTA_EN | EOTP_TX_EN;
> +
> +	if (dsi2->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
> +		val &= ~EOTP_TX_EN;
> +
> +	regmap_write(dsi2->regmap, DSI2_DSI_GENERAL_CFG, val);
> +	regmap_write(dsi2->regmap, DSI2_DSI_VCID_CFG, TX_VCID(dsi2->channel));
> +}
> +
> +static void dw_mipi_dsi2_ipi_color_coding_cfg(struct dw_mipi_dsi2 *dsi2)
> +{
> +	u32 val, color_depth;
> +
> +	switch (dsi2->format) {
> +	case MIPI_DSI_FMT_RGB666:
> +	case MIPI_DSI_FMT_RGB666_PACKED:
> +		color_depth = IPI_DEPTH_6_BITS;
> +		break;
> +	case MIPI_DSI_FMT_RGB565:
> +		color_depth = IPI_DEPTH_5_6_5_BITS;
> +		break;
> +	case MIPI_DSI_FMT_RGB888:
> +	default:
> +		color_depth = IPI_DEPTH_8_BITS;
> +		break;
> +	}
> +
> +	val = IPI_DEPTH(color_depth) |
> +	      IPI_FORMAT(IPI_FORMAT_RGB);
> +	regmap_write(dsi2->regmap, DSI2_IPI_COLOR_MAN_CFG, val);
> +}
> +
> +static void dw_mipi_dsi2_vertical_timing_config(struct dw_mipi_dsi2 *dsi2,
> +						const struct drm_display_mode *mode)
> +{
> +	u32 vactive, vsa, vfp, vbp;
> +
> +	vactive = mode->vdisplay;
> +	vsa = mode->vsync_end - mode->vsync_start;
> +	vfp = mode->vsync_start - mode->vdisplay;
> +	vbp = mode->vtotal - mode->vsync_end;
> +
> +	regmap_write(dsi2->regmap, DSI2_IPI_VID_VSA_MAN_CFG, VID_VSA_LINES(vsa));
> +	regmap_write(dsi2->regmap, DSI2_IPI_VID_VBP_MAN_CFG, VID_VBP_LINES(vbp));
> +	regmap_write(dsi2->regmap, DSI2_IPI_VID_VACT_MAN_CFG, VID_VACT_LINES(vactive));
> +	regmap_write(dsi2->regmap, DSI2_IPI_VID_VFP_MAN_CFG, VID_VFP_LINES(vfp));
> +}
> +
> +static void dw_mipi_dsi2_ipi_set(struct dw_mipi_dsi2 *dsi2)
> +{
> +	struct drm_display_mode *mode = &dsi2->mode;
> +	u32 hline, hsa, hbp, hact;
> +	u64 hline_time, hsa_time, hbp_time, hact_time, tmp;
> +	u64 pixel_clk, phy_hs_clk;
> +	u16 val;
> +
> +	val = mode->hdisplay;
> +
> +	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, MAX_PIX_PKT(val));
> +
> +	dw_mipi_dsi2_ipi_color_coding_cfg(dsi2);
> +
> +	/*
> +	 * if the controller is intended to operate in data stream mode,
> +	 * no more steps are required.
> +	 */
> +	if (!(dsi2->mode_flags & MIPI_DSI_MODE_VIDEO))
> +		return;
> +
> +	hact = mode->hdisplay;
> +	hsa = mode->hsync_end - mode->hsync_start;
> +	hbp = mode->htotal - mode->hsync_end;
> +	hline = mode->htotal;
> +
> +	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
> +
> +	phy_hs_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
> +
> +	tmp = hsa * phy_hs_clk;
> +	hsa_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
> +	regmap_write(dsi2->regmap, DSI2_IPI_VID_HSA_MAN_CFG, VID_HSA_TIME(hsa_time));
> +
> +	tmp = hbp * phy_hs_clk;
> +	hbp_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
> +	regmap_write(dsi2->regmap, DSI2_IPI_VID_HBP_MAN_CFG, VID_HBP_TIME(hbp_time));
> +
> +	tmp = hact * phy_hs_clk;
> +	hact_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
> +	regmap_write(dsi2->regmap, DSI2_IPI_VID_HACT_MAN_CFG, VID_HACT_TIME(hact_time));
> +
> +	tmp = hline * phy_hs_clk;
> +	hline_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
> +	regmap_write(dsi2->regmap, DSI2_IPI_VID_HLINE_MAN_CFG, VID_HLINE_TIME(hline_time));
> +
> +	dw_mipi_dsi2_vertical_timing_config(dsi2, mode);
> +}
> +
> +static void
> +dw_mipi_dsi2_work_mode(struct dw_mipi_dsi2 *dsi2, u32 mode)
> +{
> +	/*
> +	 * select controller work in Manual mode
> +	 * Manual: MANUAL_MODE_EN
> +	 * Automatic: 0
> +	 */
> +	regmap_write(dsi2->regmap, MANUAL_MODE_CFG, mode);
> +}
> +
> +static int dw_mipi_dsi2_host_attach(struct mipi_dsi_host *host,
> +				    struct mipi_dsi_device *device)
> +{
> +	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
> +	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
> +	struct drm_bridge *bridge;
> +	int ret;
> +
> +	if (device->lanes > dsi2->plat_data->max_data_lanes) {
> +		dev_err(dsi2->dev, "the number of data lanes(%u) is too many\n",
> +			device->lanes);
> +		return -EINVAL;
> +	}
> +
> +	dsi2->lanes = device->lanes;
> +	dsi2->channel = device->channel;
> +	dsi2->format = device->format;
> +	dsi2->mode_flags = device->mode_flags;
> +
> +	bridge = devm_drm_of_get_bridge(dsi2->dev, dsi2->dev->of_node, 1, 0);
> +	if (IS_ERR(bridge))
> +		return PTR_ERR(bridge);
> +
> +	bridge->pre_enable_prev_first = true;
> +	dsi2->panel_bridge = bridge;
> +
> +	drm_bridge_add(&dsi2->bridge);
> +
> +	if (pdata->host_ops && pdata->host_ops->attach) {
> +		ret = pdata->host_ops->attach(pdata->priv_data, device);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int dw_mipi_dsi2_host_detach(struct mipi_dsi_host *host,
> +				    struct mipi_dsi_device *device)
> +{
> +	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
> +	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
> +	int ret;
> +
> +	if (pdata->host_ops && pdata->host_ops->detach) {
> +		ret = pdata->host_ops->detach(pdata->priv_data, device);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	drm_bridge_remove(&dsi2->bridge);
> +
> +	drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
> +
> +	return 0;
> +}
> +
> +static int dw_mipi_dsi2_gen_pkt_hdr_write(struct dw_mipi_dsi2 *dsi2,
> +					  u32 hdr_val, bool lpm)
> +{
> +	int ret;
> +
> +	regmap_write(dsi2->regmap, DSI2_CRI_TX_HDR, hdr_val | CMD_TX_MODE(lpm));
> +
> +	ret = cri_fifos_wait_avail(dsi2);
> +	if (ret) {
> +		dev_err(dsi2->dev, "failed to write command header\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int dw_mipi_dsi2_write(struct dw_mipi_dsi2 *dsi2,
> +			      const struct mipi_dsi_packet *packet, bool lpm)
> +{
> +	const u8 *tx_buf = packet->payload;
> +	int len = packet->payload_length, pld_data_bytes = sizeof(u32);
> +	__le32 word;
> +
> +	/* Send payload */
> +	while (len) {
> +		if (len < pld_data_bytes) {
> +			word = 0;
> +			memcpy(&word, tx_buf, len);
> +			regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, le32_to_cpu(word));
> +			len = 0;
> +		} else {
> +			memcpy(&word, tx_buf, pld_data_bytes);
> +			regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, le32_to_cpu(word));
> +			tx_buf += pld_data_bytes;
> +			len -= pld_data_bytes;
> +		}
> +	}
> +
> +	word = 0;
> +	memcpy(&word, packet->header, sizeof(packet->header));
> +	return dw_mipi_dsi2_gen_pkt_hdr_write(dsi2, le32_to_cpu(word), lpm);
> +}
> +
> +static int dw_mipi_dsi2_read(struct dw_mipi_dsi2 *dsi2,
> +			     const struct mipi_dsi_msg *msg)
> +{
> +	u8 *payload = msg->rx_buf;
> +	int i, j, ret, len = msg->rx_len;
> +	u8 data_type;
> +	u16 wc;
> +	u32 val;
> +
> +	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS,
> +				       val, val & CRI_RD_DATA_AVAIL,
> +				       100, CMD_PKT_STATUS_TIMEOUT_US);
> +	if (ret) {
> +		dev_err(dsi2->dev, "CRI has no available read data\n");
> +		return ret;
> +	}
> +
> +	regmap_read(dsi2->regmap, DSI2_CRI_RX_HDR, &val);
> +	data_type = val & 0x3f;
> +
> +	if (mipi_dsi_packet_format_is_short(data_type)) {
> +		for (i = 0; i < len && i < 2; i++)
> +			payload[i] = (val >> (8 * (i + 1))) & 0xff;
> +
> +		return 0;
> +	}
> +
> +	wc = (val >> 8) & 0xffff;
> +	/* Receive payload */
> +	for (i = 0; i < len && i < wc; i += 4) {
> +		regmap_read(dsi2->regmap, DSI2_CRI_RX_PLD, &val);
> +		for (j = 0; j < 4 && j + i < len && j + i < wc; j++)
> +			payload[i + j] = val >> (8 * j);
> +	}
> +
> +	return 0;
> +}
> +
> +static ssize_t dw_mipi_dsi2_host_transfer(struct mipi_dsi_host *host,
> +					  const struct mipi_dsi_msg *msg)
> +{
> +	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
> +	bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM;
> +	struct mipi_dsi_packet packet;
> +	int ret, nb_bytes;
> +
> +	regmap_update_bits(dsi2->regmap, DSI2_DSI_VID_TX_CFG,
> +			   LPDT_DISPLAY_CMD_EN,
> +			   lpm ? LPDT_DISPLAY_CMD_EN : 0);
> +
> +	/* create a packet to the DSI protocol */
> +	ret = mipi_dsi_create_packet(&packet, msg);
> +	if (ret) {
> +		dev_err(dsi2->dev, "failed to create packet: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = cri_fifos_wait_avail(dsi2);
> +	if (ret)
> +		return ret;
> +
> +	ret = dw_mipi_dsi2_write(dsi2, &packet, lpm);
> +	if (ret)
> +		return ret;
> +
> +	if (msg->rx_buf && msg->rx_len) {
> +		ret = dw_mipi_dsi2_read(dsi2, msg);
> +		if (ret < 0)
> +			return ret;
> +		nb_bytes = msg->rx_len;
> +	} else {
> +		nb_bytes = packet.size;
> +	}
> +
> +	return nb_bytes;
> +}
> +
> +static const struct mipi_dsi_host_ops dw_mipi_dsi2_host_ops = {
> +	.attach = dw_mipi_dsi2_host_attach,
> +	.detach = dw_mipi_dsi2_host_detach,
> +	.transfer = dw_mipi_dsi2_host_transfer,
> +};
> +
> +static u32 *
> +dw_mipi_dsi2_bridge_atomic_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 dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
> +	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
> +	u32 *input_fmts;
> +
> +	if (pdata->get_input_bus_fmts)
> +		return pdata->get_input_bus_fmts(pdata->priv_data,
> +						 bridge, bridge_state,
> +						 crtc_state, conn_state,
> +						 output_fmt, num_input_fmts);
> +
> +	/* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */
> +	input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
> +	if (!input_fmts)
> +		return NULL;
> +	input_fmts[0] = MEDIA_BUS_FMT_FIXED;
> +	*num_input_fmts = 1;
> +
> +	return input_fmts;
> +}
> +
> +static int dw_mipi_dsi2_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 dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
> +	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
> +	bool ret;
> +
> +	bridge_state->input_bus_cfg.flags =
> +		DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE;
> +
> +	if (pdata->mode_fixup) {
> +		ret = pdata->mode_fixup(pdata->priv_data, &crtc_state->mode,
> +					&crtc_state->adjusted_mode);
> +		if (!ret) {
> +			DRM_DEBUG_DRIVER("failed to fixup mode " DRM_MODE_FMT "\n",
> +					 DRM_MODE_ARG(&crtc_state->mode));
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_bridge_post_atomic_disable(struct drm_bridge *bridge,
> +						    struct drm_bridge_state *old_bridge_state)
> +{
> +	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
> +	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
> +
> +	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, 0);
> +
> +	/*
> +	 * Switch to command mode before panel-bridge post_disable &
> +	 * panel unprepare.
> +	 * Note: panel-bridge disable & panel disable has been called
> +	 * before by the drm framework.
> +	 */
> +	dw_mipi_dsi2_set_cmd_mode(dsi2);
> +
> +	regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET);
> +
> +	if (phy_ops->power_off)
> +		phy_ops->power_off(dsi2->plat_data->priv_data);
> +
> +	clk_disable_unprepare(dsi2->sys_clk);
> +	clk_disable_unprepare(dsi2->pclk);
> +	pm_runtime_put(dsi2->dev);
> +}
> +
> +static unsigned int dw_mipi_dsi2_get_lanes(struct dw_mipi_dsi2 *dsi2)
> +{
> +	/* single-dsi, so no other instance to consider */
> +	return dsi2->lanes;
> +}
> +
> +static void dw_mipi_dsi2_mode_set(struct dw_mipi_dsi2 *dsi2,
> +				  const struct drm_display_mode *adjusted_mode)
> +{
> +	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
> +	void *priv_data = dsi2->plat_data->priv_data;
> +	u32 lanes = dw_mipi_dsi2_get_lanes(dsi2);
> +	int ret;
> +
> +	clk_prepare_enable(dsi2->pclk);
> +	clk_prepare_enable(dsi2->sys_clk);
> +
> +	ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi2->mode_flags,
> +				     lanes, dsi2->format, &dsi2->lane_mbps);
> +	if (ret)
> +		DRM_DEBUG_DRIVER("Phy get_lane_mbps() failed\n");
> +
> +	pm_runtime_get_sync(dsi2->dev);
> +
> +	dw_mipi_dsi2_host_softrst(dsi2);
> +	regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET);
> +
> +	dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN);
> +	dw_mipi_dsi2_phy_init(dsi2);
> +
> +	if (phy_ops->power_on)
> +		phy_ops->power_on(dsi2->plat_data->priv_data);
> +
> +	dw_mipi_dsi2_tx_option_set(dsi2);
> +
> +	/*
> +	 * initial deskew calibration is send after phy_power_on,
> +	 * then we can configure clk_type.
> +	 */
> +
> +	regmap_update_bits(dsi2->regmap, DSI2_PHY_CLK_CFG, CLK_TYPE_MASK,
> +			   dsi2->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS ? NON_CONTINUOUS_CLK :
> +									      CONTINUOUS_CLK);
> +
> +	regmap_write(dsi2->regmap, DSI2_PWR_UP, POWER_UP);
> +	dw_mipi_dsi2_set_cmd_mode(dsi2);
> +
> +	dw_mipi_dsi2_ipi_set(dsi2);
> +}
> +
> +static void dw_mipi_dsi2_bridge_atomic_pre_enable(struct drm_bridge *bridge,
> +						  struct drm_bridge_state *old_bridge_state)
> +{
> +	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
> +
> +	/* Power up the dsi ctl into a command mode */
> +	dw_mipi_dsi2_mode_set(dsi2, &dsi2->mode);
> +}
> +
> +static void dw_mipi_dsi2_bridge_mode_set(struct drm_bridge *bridge,
> +					 const struct drm_display_mode *mode,
> +					 const struct drm_display_mode *adjusted_mode)
> +{
> +	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
> +
> +	/* Store the display mode for later use in pre_enable callback */
> +	drm_mode_copy(&dsi2->mode, adjusted_mode);
> +}
> +
> +static void dw_mipi_dsi2_bridge_atomic_enable(struct drm_bridge *bridge,
> +					      struct drm_bridge_state *old_bridge_state)
> +{
> +	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
> +
> +	/* Switch to video mode for panel-bridge enable & panel enable */
> +	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)
> +		dw_mipi_dsi2_set_vid_mode(dsi2);
> +	else
> +		dw_mipi_dsi2_set_data_stream_mode(dsi2);
> +}
> +
> +static enum drm_mode_status
> +dw_mipi_dsi2_bridge_mode_valid(struct drm_bridge *bridge,
> +			       const struct drm_display_info *info,
> +			       const struct drm_display_mode *mode)
> +{
> +	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
> +	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
> +	enum drm_mode_status mode_status = MODE_OK;
> +
> +	if (pdata->mode_valid)
> +		mode_status = pdata->mode_valid(pdata->priv_data, mode,
> +						dsi2->mode_flags,
> +						dw_mipi_dsi2_get_lanes(dsi2),
> +						dsi2->format);
> +
> +	return mode_status;
> +}
> +
> +static int dw_mipi_dsi2_bridge_attach(struct drm_bridge *bridge,
> +				      enum drm_bridge_attach_flags flags)
> +{
> +	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
> +
> +	/* Set the encoder type as caller does not know it */
> +	bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
> +
> +	/* Attach the panel-bridge to the dsi bridge */
> +	return drm_bridge_attach(bridge->encoder, dsi2->panel_bridge, bridge,
> +				 flags);
> +}
> +
> +static const struct drm_bridge_funcs dw_mipi_dsi2_bridge_funcs = {
> +	.atomic_duplicate_state	= drm_atomic_helper_bridge_duplicate_state,
> +	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state,
> +	.atomic_get_input_bus_fmts = dw_mipi_dsi2_bridge_atomic_get_input_bus_fmts,
> +	.atomic_check		= dw_mipi_dsi2_bridge_atomic_check,
> +	.atomic_reset		= drm_atomic_helper_bridge_reset,
> +	.atomic_pre_enable	= dw_mipi_dsi2_bridge_atomic_pre_enable,
> +	.atomic_enable		= dw_mipi_dsi2_bridge_atomic_enable,
> +	.atomic_post_disable	= dw_mipi_dsi2_bridge_post_atomic_disable,
> +	.mode_set		= dw_mipi_dsi2_bridge_mode_set,
> +	.mode_valid		= dw_mipi_dsi2_bridge_mode_valid,
> +	.attach			= dw_mipi_dsi2_bridge_attach,
> +};
> +
> +static const struct regmap_config dw_mipi_dsi2_regmap_config = {
> +	.name = "dsi2-host",
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.fast_io = true,
> +};
> +
> +static struct dw_mipi_dsi2 *
> +__dw_mipi_dsi2_probe(struct platform_device *pdev,
> +		     const struct dw_mipi_dsi2_plat_data *plat_data)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct reset_control *apb_rst;
> +	struct dw_mipi_dsi2 *dsi2;
> +	int ret;
> +
> +	dsi2 = devm_kzalloc(dev, sizeof(*dsi2), GFP_KERNEL);
> +	if (!dsi2)
> +		return ERR_PTR(-ENOMEM);
> +
> +	dsi2->dev = dev;
> +	dsi2->plat_data = plat_data;
> +
> +	if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps ||
> +	    !plat_data->phy_ops->get_timing)
> +		return dev_err_ptr_probe(dev, -ENODEV, "Phy not properly configured\n");
> +
> +	if (!plat_data->regmap) {
> +		void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
> +
> +		if (IS_ERR(base))
> +			return dev_err_cast_probe(dev, base, "failed to registers\n");
> +
> +		dsi2->regmap = devm_regmap_init_mmio(dev, base,
> +						     &dw_mipi_dsi2_regmap_config);
> +		if (IS_ERR(dsi2->regmap))
> +			return dev_err_cast_probe(dev, dsi2->regmap, "failed to init regmap\n");
> +	} else {
> +		dsi2->regmap = plat_data->regmap;
> +	}
> +
> +	dsi2->pclk = devm_clk_get(dev, "pclk");
> +	if (IS_ERR(dsi2->pclk))
> +		return dev_err_cast_probe(dev, dsi2->pclk, "Unable to get pclk\n");
> +
> +	dsi2->sys_clk = devm_clk_get(dev, "sys");
> +	if (IS_ERR(dsi2->sys_clk))
> +		return dev_err_cast_probe(dev, dsi2->sys_clk, "Unable to get sys_clk\n");
> +
> +	/*
> +	 * Note that the reset was not defined in the initial device tree, so
> +	 * we have to be prepared for it not being found.
> +	 */
> +	apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb");
> +	if (IS_ERR(apb_rst))
> +		return dev_err_cast_probe(dev, apb_rst, "Unable to get reset control\n");
> +
> +	if (apb_rst) {
> +		ret = clk_prepare_enable(dsi2->pclk);
> +		if (ret) {
> +			dev_err(dev, "%s: Failed to enable pclk\n", __func__);
> +			return ERR_PTR(ret);
> +		}
> +
> +		reset_control_assert(apb_rst);
> +		usleep_range(10, 20);
> +		reset_control_deassert(apb_rst);
> +
> +		clk_disable_unprepare(dsi2->pclk);
> +	}
> +
> +	devm_pm_runtime_enable(dev);
> +
> +	dsi2->dsi_host.ops = &dw_mipi_dsi2_host_ops;
> +	dsi2->dsi_host.dev = dev;
> +	ret = mipi_dsi_host_register(&dsi2->dsi_host);
> +	if (ret) {
> +		dev_err(dev, "Failed to register MIPI host: %d\n", ret);
> +		pm_runtime_disable(dev);
> +		return ERR_PTR(ret);
> +	}
> +
> +	dsi2->bridge.driver_private = dsi2;
> +	dsi2->bridge.funcs = &dw_mipi_dsi2_bridge_funcs;
> +	dsi2->bridge.of_node = pdev->dev.of_node;
> +
> +	return dsi2;
> +}
> +
> +static void __dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2)
> +{
> +	mipi_dsi_host_unregister(&dsi2->dsi_host);
> +}
> +
> +/*
> + * Probe/remove API, used to create the bridge instance.
> + */
> +struct dw_mipi_dsi2 *
> +dw_mipi_dsi2_probe(struct platform_device *pdev,
> +		   const struct dw_mipi_dsi2_plat_data *plat_data)
> +{
> +	return __dw_mipi_dsi2_probe(pdev, plat_data);
> +}
> +EXPORT_SYMBOL_GPL(dw_mipi_dsi2_probe);
> +
> +void dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2)
> +{
> +	__dw_mipi_dsi2_remove(dsi2);
> +}
> +EXPORT_SYMBOL_GPL(dw_mipi_dsi2_remove);
> +
> +/*
> + * Bind/unbind API, used from platforms based on the component framework
> + * to attach the bridge to an encoder.
> + */
> +int dw_mipi_dsi2_bind(struct dw_mipi_dsi2 *dsi2, struct drm_encoder *encoder)
> +{
> +	return drm_bridge_attach(encoder, &dsi2->bridge, NULL, 0);
> +}
> +EXPORT_SYMBOL_GPL(dw_mipi_dsi2_bind);
> +
> +void dw_mipi_dsi2_unbind(struct dw_mipi_dsi2 *dsi2)
> +{
> +}
> +EXPORT_SYMBOL_GPL(dw_mipi_dsi2_unbind);
> +
> +MODULE_AUTHOR("Guochun Huang <hero.huang at rock-chips.com>");
> +MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner at cherry.de>");
> +MODULE_DESCRIPTION("DW MIPI DSI2 host controller driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:dw-mipi-dsi2");
> diff --git a/include/drm/bridge/dw_mipi_dsi2.h b/include/drm/bridge/dw_mipi_dsi2.h
> new file mode 100644
> index 000000000000..c18c49379247
> --- /dev/null
> +++ b/include/drm/bridge/dw_mipi_dsi2.h
> @@ -0,0 +1,95 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2024, Fuzhou Rockchip Electronics Co., Ltd
> + *
> + * Authors: Guochun Huang <hero.huang at rock-chips.com>
> + *          Heiko Stuebner <heiko.stuebner at cherry.de>
> + */
> +
> +#ifndef __DW_MIPI_DSI2__
> +#define __DW_MIPI_DSI2__
> +
> +#include <linux/regmap.h>
> +#include <linux/types.h>
> +
> +#include <drm/drm_atomic.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_connector.h>
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_modes.h>
> +
> +struct drm_display_mode;
> +struct drm_encoder;
> +struct dw_mipi_dsi2;
> +struct mipi_dsi_device;
> +struct platform_device;
> +
> +enum dw_mipi_dsi2_phy_type {
> +	DW_MIPI_DSI2_DPHY,
> +	DW_MIPI_DSI2_CPHY,
> +};
> +
> +struct dw_mipi_dsi2_phy_iface {
> +	int ppi_width;
> +	enum dw_mipi_dsi2_phy_type phy_type;
> +};
> +
> +struct dw_mipi_dsi2_phy_timing {
> +	u32 data_hs2lp;
> +	u32 data_lp2hs;
> +};
> +
> +struct dw_mipi_dsi2_phy_ops {
> +	int (*init)(void *priv_data);
> +	void (*power_on)(void *priv_data);
> +	void (*power_off)(void *priv_data);
> +	void (*get_interface)(void *priv_data, struct dw_mipi_dsi2_phy_iface *iface);
> +	int (*get_lane_mbps)(void *priv_data,
> +			     const struct drm_display_mode *mode,
> +			     unsigned long mode_flags, u32 lanes, u32 format,
> +			     unsigned int *lane_mbps);
> +	int (*get_timing)(void *priv_data, unsigned int lane_mbps,
> +			  struct dw_mipi_dsi2_phy_timing *timing);
> +	int (*get_esc_clk_rate)(void *priv_data, unsigned int *esc_clk_rate);
> +};
> +
> +struct dw_mipi_dsi2_host_ops {
> +	int (*attach)(void *priv_data,
> +		      struct mipi_dsi_device *dsi);
> +	int (*detach)(void *priv_data,
> +		      struct mipi_dsi_device *dsi);
> +};
> +
> +struct dw_mipi_dsi2_plat_data {
> +	struct regmap *regmap;
> +	unsigned int max_data_lanes;
> +
> +	enum drm_mode_status (*mode_valid)(void *priv_data,
> +					   const struct drm_display_mode *mode,
> +					   unsigned long mode_flags,
> +					   u32 lanes, u32 format);
> +
> +	bool (*mode_fixup)(void *priv_data, const struct drm_display_mode *mode,
> +			   struct drm_display_mode *adjusted_mode);
> +
> +	u32 *(*get_input_bus_fmts)(void *priv_data,
> +				   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);
> +
> +	const struct dw_mipi_dsi2_phy_ops *phy_ops;
> +	const struct dw_mipi_dsi2_host_ops *host_ops;
> +
> +	void *priv_data;
> +};
> +
> +struct dw_mipi_dsi2 *dw_mipi_dsi2_probe(struct platform_device *pdev,
> +					const struct dw_mipi_dsi2_plat_data *plat_data);
> +void dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2);
> +int dw_mipi_dsi2_bind(struct dw_mipi_dsi2 *dsi2, struct drm_encoder *encoder);
> +void dw_mipi_dsi2_unbind(struct dw_mipi_dsi2 *dsi2);
> +
> +#endif /* __DW_MIPI_DSI2__ */


From andy.yan at rock-chips.com  Tue Dec 10 00:51:21 2024
From: andy.yan at rock-chips.com (Andy Yan)
Date: Tue, 10 Dec 2024 16:51:21 +0800
Subject: [PATCH v4 3/3] drm/rockchip: Add MIPI DSI2 glue driver for RK3588
In-Reply-To: <20241209231021.2180582-4-heiko@sntech.de>
References: <20241209231021.2180582-1-heiko@sntech.de>
 <20241209231021.2180582-4-heiko@sntech.de>
Message-ID: <d941270c-a406-4fd6-9f42-b088d583e3f6@rock-chips.com>

Hello Heiko,

On 12/10/24 07:10, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> This adds the glue code for the MIPI DSI2 bridge on Rockchip SoCs and
> enables its use on the RK3588.
> 
> Right now the DSI2 controller is always paired with a DC-phy based on a
> Samsung IP, so the interface values are set statically for now.
> This stays true for the upcoming RK3576 as well.
> 
> Tested-by: Daniel Semkowicz <dse at thaumatec.com>
> Tested-by: Dmitry Yashin <dmt.yashin at gmail.com>
> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>

   Reviewed-by: Andy Yan <andy.yan at rock-chips.com>
> ---
>   drivers/gpu/drm/rockchip/Kconfig              |  10 +
>   drivers/gpu/drm/rockchip/Makefile             |   1 +
>   .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c  | 487 ++++++++++++++++++
>   drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |   2 +
>   drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |   1 +
>   5 files changed, 501 insertions(+)
>   create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> 
> diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
> index 448fadd4ba15..adee24b4e7bc 100644
> --- a/drivers/gpu/drm/rockchip/Kconfig
> +++ b/drivers/gpu/drm/rockchip/Kconfig
> @@ -10,6 +10,7 @@ config DRM_ROCKCHIP
>   	select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
>   	select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP
>   	select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
> +	select DRM_DW_MIPI_DSI2 if ROCKCHIP_DW_MIPI_DSI2
>   	select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
>   	select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
>   	select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
> @@ -81,6 +82,15 @@ config ROCKCHIP_DW_MIPI_DSI
>   	  enable MIPI DSI on RK3288 or RK3399 based SoC, you should
>   	  select this option.
>   
> +config ROCKCHIP_DW_MIPI_DSI2
> +	bool "Rockchip specific extensions for Synopsys DW MIPI DSI2"
> +	select GENERIC_PHY_MIPI_DPHY
> +	help
> +	  This selects support for Rockchip SoC specific extensions
> +	  for the Synopsys DesignWare DSI2 driver. If you want to
> +	  enable MIPI DSI on RK3576 or RK3588 based SoC, you should
> +	  select this option.
> +
>   config ROCKCHIP_INNO_HDMI
>   	bool "Rockchip specific extensions for Innosilicon HDMI"
>   	select DRM_DISPLAY_HDMI_HELPER
> diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
> index 3eab662a5a1d..2b867cebbc12 100644
> --- a/drivers/gpu/drm/rockchip/Makefile
> +++ b/drivers/gpu/drm/rockchip/Makefile
> @@ -13,6 +13,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o
> +rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI2) += dw-mipi-dsi2-rockchip.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
>   rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> new file mode 100644
> index 000000000000..cdd490778756
> --- /dev/null
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
> @@ -0,0 +1,487 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2024 Rockchip Electronics Co., Ltd.
> + * Author:
> + *      Guochun Huang <hero.huang at rock-chips.com>
> + *      Heiko Stuebner <heiko.stuebner at cherry.de>
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/media-bus-format.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/phy/phy.h>
> +
> +#include <drm/bridge/dw_mipi_dsi2.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_simple_kms_helper.h>
> +
> +#include <uapi/linux/videodev2.h>
> +
> +#include "rockchip_drm_drv.h"
> +
> +#define PSEC_PER_SEC			1000000000000LL
> +
> +struct dsigrf_reg {
> +	u16 offset;
> +	u16 lsb;
> +	u16 msb;
> +};
> +
> +enum grf_reg_fields {
> +	TXREQCLKHS_EN,
> +	GATING_EN,
> +	IPI_SHUTDN,
> +	IPI_COLORM,
> +	IPI_COLOR_DEPTH,
> +	IPI_FORMAT,
> +	MAX_FIELDS,
> +};
> +
> +#define IPI_DEPTH_5_6_5_BITS		0x02
> +#define IPI_DEPTH_6_BITS		0x03
> +#define IPI_DEPTH_8_BITS		0x05
> +#define IPI_DEPTH_10_BITS		0x06
> +
> +struct rockchip_dw_dsi2_chip_data {
> +	u32 reg;
> +	const struct dsigrf_reg *grf_regs;
> +	unsigned long long max_bit_rate_per_lane;
> +};
> +
> +struct dw_mipi_dsi2_rockchip {
> +	struct device *dev;
> +	struct rockchip_encoder encoder;
> +	struct regmap *regmap;
> +
> +	unsigned int lane_mbps; /* per lane */
> +	u32 format;
> +
> +	struct regmap *grf_regmap;
> +	struct phy *phy;
> +	union phy_configure_opts phy_opts;
> +
> +	struct dw_mipi_dsi2 *dmd;
> +	struct dw_mipi_dsi2_plat_data pdata;
> +	const struct rockchip_dw_dsi2_chip_data *cdata;
> +};
> +
> +static inline struct dw_mipi_dsi2_rockchip *to_dsi2(struct drm_encoder *encoder)
> +{
> +	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
> +
> +	return container_of(rkencoder, struct dw_mipi_dsi2_rockchip, encoder);
> +}
> +
> +static void grf_field_write(struct dw_mipi_dsi2_rockchip *dsi2, enum grf_reg_fields index,
> +			    unsigned int val)
> +{
> +	const struct dsigrf_reg *field = &dsi2->cdata->grf_regs[index];
> +
> +	if (!field)
> +		return;
> +
> +	regmap_write(dsi2->grf_regmap, field->offset,
> +		     (val << field->lsb) | (GENMASK(field->msb, field->lsb) << 16));
> +}
> +
> +static int dw_mipi_dsi2_phy_init(void *priv_data)
> +{
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_phy_power_on(void *priv_data)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +	int ret;
> +
> +	ret = phy_set_mode(dsi2->phy, PHY_MODE_MIPI_DPHY);
> +	if (ret) {
> +		dev_err(dsi2->dev, "Failed to set phy mode: %d\n", ret);
> +		return;
> +	}
> +
> +	phy_configure(dsi2->phy, &dsi2->phy_opts);
> +	phy_power_on(dsi2->phy);
> +}
> +
> +static void dw_mipi_dsi2_phy_power_off(void *priv_data)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +
> +	phy_power_off(dsi2->phy);
> +}
> +
> +static int
> +dw_mipi_dsi2_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
> +			   unsigned long mode_flags, u32 lanes, u32 format,
> +			   unsigned int *lane_mbps)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +	u64 max_lane_rate, target_phyclk;
> +	unsigned int lane_rate_kbps;
> +	int bpp;
> +
> +	max_lane_rate = dsi2->cdata->max_bit_rate_per_lane;
> +
> +	dsi2->format = format;
> +	bpp = mipi_dsi_pixel_format_to_bpp(format);
> +	if (bpp < 0) {
> +		dev_err(dsi2->dev, "failed to get bpp for pixel format %d\n", format);
> +		return bpp;
> +	}
> +
> +	lane_rate_kbps = mode->clock * bpp / lanes;
> +
> +	/*
> +	 * Set BW a little larger only in video burst mode in
> +	 * consideration of the protocol overhead and HS mode
> +	 * switching to BLLP mode, take 1 / 0.9, since Mbps must
> +	 * big than bandwidth of RGB
> +	 */
> +	if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
> +		lane_rate_kbps = (lane_rate_kbps * 10) / 9;
> +
> +	if (lane_rate_kbps > max_lane_rate) {
> +		dev_err(dsi2->dev, "DPHY clock frequency is out of range\n");
> +		return -ERANGE;
> +	}
> +
> +	dsi2->lane_mbps = lane_rate_kbps / 1000;
> +	*lane_mbps = dsi2->lane_mbps;
> +
> +	if (dsi2->phy) {
> +		target_phyclk = DIV_ROUND_CLOSEST_ULL(lane_rate_kbps * lanes * 1000, bpp);
> +		phy_mipi_dphy_get_default_config(target_phyclk, bpp, lanes,
> +						 &dsi2->phy_opts.mipi_dphy);
> +	}
> +
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_phy_get_iface(void *priv_data, struct dw_mipi_dsi2_phy_iface *iface)
> +{
> +	/* PPI width is fixed to 16 bits in DCPHY */
> +	iface->ppi_width = 16;
> +	iface->phy_type = DW_MIPI_DSI2_DPHY;
> +}
> +
> +static int
> +dw_mipi_dsi2_phy_get_timing(void *priv_data, unsigned int lane_mbps,
> +			    struct dw_mipi_dsi2_phy_timing *timing)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +	struct phy_configure_opts_mipi_dphy *cfg = &dsi2->phy_opts.mipi_dphy;
> +	unsigned long long tmp, ui;
> +	unsigned long long hstx_clk;
> +
> +	hstx_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
> +
> +	ui = ALIGN(PSEC_PER_SEC, hstx_clk);
> +	do_div(ui, hstx_clk);
> +
> +	/* PHY_LP2HS_TIME = (TLPX + THS-PREPARE + THS-ZERO) / Tphy_hstx_clk */
> +	tmp = cfg->lpx + cfg->hs_prepare + cfg->hs_zero;
> +	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
> +	timing->data_lp2hs = tmp;
> +
> +	/* PHY_HS2LP_TIME = (THS-TRAIL + THS-EXIT) / Tphy_hstx_clk */
> +	tmp = cfg->hs_trail + cfg->hs_exit;
> +	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
> +	timing->data_hs2lp = tmp;
> +
> +	return 0;
> +}
> +
> +static const struct dw_mipi_dsi2_phy_ops dw_mipi_dsi2_rockchip_phy_ops = {
> +	.init = dw_mipi_dsi2_phy_init,
> +	.power_on = dw_mipi_dsi2_phy_power_on,
> +	.power_off = dw_mipi_dsi2_phy_power_off,
> +	.get_interface = dw_mipi_dsi2_phy_get_iface,
> +	.get_lane_mbps = dw_mipi_dsi2_get_lane_mbps,
> +	.get_timing = dw_mipi_dsi2_phy_get_timing,
> +};
> +
> +static void dw_mipi_dsi2_encoder_atomic_enable(struct drm_encoder *encoder,
> +					       struct drm_atomic_state *state)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
> +	u32 color_depth;
> +
> +	switch (dsi2->format) {
> +	case MIPI_DSI_FMT_RGB666:
> +	case MIPI_DSI_FMT_RGB666_PACKED:
> +		color_depth = IPI_DEPTH_6_BITS;
> +		break;
> +	case MIPI_DSI_FMT_RGB565:
> +		color_depth = IPI_DEPTH_5_6_5_BITS;
> +		break;
> +	case MIPI_DSI_FMT_RGB888:
> +		color_depth = IPI_DEPTH_8_BITS;
> +		break;
> +	default:
> +		/* Should've been caught by atomic_check */
> +		WARN_ON(1);
> +		return;
> +	}
> +
> +	grf_field_write(dsi2, IPI_COLOR_DEPTH, color_depth);
> +}
> +
> +static int
> +dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder,
> +				  struct drm_crtc_state *crtc_state,
> +				  struct drm_connector_state *conn_state)
> +{
> +	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
> +	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
> +	struct drm_connector *connector = conn_state->connector;
> +	struct drm_display_info *info = &connector->display_info;
> +
> +	switch (dsi2->format) {
> +	case MIPI_DSI_FMT_RGB666:
> +	case MIPI_DSI_FMT_RGB666_PACKED:
> +		s->output_mode = ROCKCHIP_OUT_MODE_P666;
> +		break;
> +	case MIPI_DSI_FMT_RGB565:
> +		s->output_mode = ROCKCHIP_OUT_MODE_P565;
> +		break;
> +	case MIPI_DSI_FMT_RGB888:
> +		s->output_mode = ROCKCHIP_OUT_MODE_P888;
> +		break;
> +	default:
> +		WARN_ON(1);
> +		return -EINVAL;
> +	}
> +
> +	if (info->num_bus_formats)
> +		s->bus_format = info->bus_formats[0];
> +	else
> +		s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
> +
> +	s->output_type = DRM_MODE_CONNECTOR_DSI;
> +	s->bus_flags = info->bus_flags;
> +	s->color_space = V4L2_COLORSPACE_DEFAULT;
> +
> +	return 0;
> +}
> +
> +static const struct drm_encoder_helper_funcs
> +dw_mipi_dsi2_encoder_helper_funcs = {
> +	.atomic_enable = dw_mipi_dsi2_encoder_atomic_enable,
> +	.atomic_check = dw_mipi_dsi2_encoder_atomic_check,
> +};
> +
> +static int rockchip_dsi2_drm_create_encoder(struct dw_mipi_dsi2_rockchip *dsi2,
> +					    struct drm_device *drm_dev)
> +{
> +	struct drm_encoder *encoder = &dsi2->encoder.encoder;
> +	int ret;
> +
> +	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
> +							     dsi2->dev->of_node);
> +
> +	ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI);
> +	if (ret) {
> +		dev_err(dsi2->dev, "Failed to initialize encoder with drm\n");
> +		return ret;
> +	}
> +
> +	drm_encoder_helper_add(encoder, &dw_mipi_dsi2_encoder_helper_funcs);
> +
> +	return 0;
> +}
> +
> +static int dw_mipi_dsi2_rockchip_bind(struct device *dev, struct device *master,
> +				      void *data)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
> +	struct drm_device *drm_dev = data;
> +	int ret;
> +
> +	ret = rockchip_dsi2_drm_create_encoder(dsi2, drm_dev);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to create drm encoder\n");
> +
> +	rockchip_drm_encoder_set_crtc_endpoint_id(&dsi2->encoder,
> +						  dev->of_node, 0, 0);
> +
> +	ret = dw_mipi_dsi2_bind(dsi2->dmd, &dsi2->encoder.encoder);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to bind\n");
> +
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_rockchip_unbind(struct device *dev, struct device *master,
> +					 void *data)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
> +
> +	dw_mipi_dsi2_unbind(dsi2->dmd);
> +}
> +
> +static const struct component_ops dw_mipi_dsi2_rockchip_ops = {
> +	.bind	= dw_mipi_dsi2_rockchip_bind,
> +	.unbind	= dw_mipi_dsi2_rockchip_unbind,
> +};
> +
> +static int dw_mipi_dsi2_rockchip_host_attach(void *priv_data,
> +					     struct mipi_dsi_device *device)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +	int ret;
> +
> +	ret = component_add(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
> +	if (ret)
> +		return dev_err_probe(dsi2->dev, ret, "Failed to register component\n");
> +
> +	return 0;
> +}
> +
> +static int dw_mipi_dsi2_rockchip_host_detach(void *priv_data,
> +					     struct mipi_dsi_device *device)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
> +
> +	component_del(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
> +
> +	return 0;
> +}
> +
> +static const struct dw_mipi_dsi2_host_ops dw_mipi_dsi2_rockchip_host_ops = {
> +	.attach = dw_mipi_dsi2_rockchip_host_attach,
> +	.detach = dw_mipi_dsi2_rockchip_host_detach,
> +};
> +
> +static const struct regmap_config dw_mipi_dsi2_rockchip_regmap_config = {
> +	.name = "dsi2-host",
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.fast_io = true,
> +};
> +
> +static int dw_mipi_dsi2_rockchip_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	const struct rockchip_dw_dsi2_chip_data *cdata =
> +						of_device_get_match_data(dev);
> +	struct dw_mipi_dsi2_rockchip *dsi2;
> +	struct resource *res;
> +	void __iomem *base;
> +	int i;
> +
> +	dsi2 = devm_kzalloc(dev, sizeof(*dsi2), GFP_KERNEL);
> +	if (!dsi2)
> +		return -ENOMEM;
> +
> +	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> +	if (IS_ERR(base))
> +		return dev_err_probe(dev, PTR_ERR(base), "Unable to get dsi registers\n");
> +
> +	dsi2->regmap = devm_regmap_init_mmio(dev, base, &dw_mipi_dsi2_rockchip_regmap_config);
> +	if (IS_ERR(dsi2->regmap))
> +		return dev_err_probe(dev, PTR_ERR(dsi2->regmap), "failed to init register map\n");
> +
> +	i = 0;
> +	while (cdata[i].reg) {
> +		if (cdata[i].reg == res->start) {
> +			dsi2->cdata = &cdata[i];
> +			break;
> +		}
> +
> +		i++;
> +	}
> +
> +	if (!dsi2->cdata)
> +		return dev_err_probe(dev, -EINVAL, "No dsi-config for %s node\n", np->name);
> +
> +	dsi2->grf_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
> +	if (IS_ERR(dsi2->grf_regmap))
> +		return dev_err_probe(dsi2->dev, PTR_ERR(dsi2->grf_regmap), "Unable to get grf\n");
> +
> +	dsi2->phy = devm_phy_optional_get(dev, "dcphy");
> +	if (IS_ERR(dsi2->phy))
> +		return dev_err_probe(dev, PTR_ERR(dsi2->phy), "failed to get mipi phy\n");
> +
> +	dsi2->dev = dev;
> +	dsi2->pdata.regmap = dsi2->regmap;
> +	dsi2->pdata.max_data_lanes = 4;
> +	dsi2->pdata.phy_ops = &dw_mipi_dsi2_rockchip_phy_ops;
> +	dsi2->pdata.host_ops = &dw_mipi_dsi2_rockchip_host_ops;
> +	dsi2->pdata.priv_data = dsi2;
> +	platform_set_drvdata(pdev, dsi2);
> +
> +	dsi2->dmd = dw_mipi_dsi2_probe(pdev, &dsi2->pdata);
> +	if (IS_ERR(dsi2->dmd))
> +		return dev_err_probe(dev, PTR_ERR(dsi2->dmd), "Failed to probe dw_mipi_dsi2\n");
> +
> +	return 0;
> +}
> +
> +static void dw_mipi_dsi2_rockchip_remove(struct platform_device *pdev)
> +{
> +	struct dw_mipi_dsi2_rockchip *dsi2 = platform_get_drvdata(pdev);
> +
> +	dw_mipi_dsi2_remove(dsi2->dmd);
> +}
> +
> +static const struct dsigrf_reg rk3588_dsi0_grf_reg_fields[MAX_FIELDS] = {
> +	[TXREQCLKHS_EN]		= { 0x0000, 11, 11 },
> +	[GATING_EN]		= { 0x0000, 10, 10 },
> +	[IPI_SHUTDN]		= { 0x0000,  9,  9 },
> +	[IPI_COLORM]		= { 0x0000,  8,  8 },
> +	[IPI_COLOR_DEPTH]	= { 0x0000,  4,  7 },
> +	[IPI_FORMAT]		= { 0x0000,  0,  3 },
> +};
> +
> +static const struct dsigrf_reg rk3588_dsi1_grf_reg_fields[MAX_FIELDS] = {
> +	[TXREQCLKHS_EN]		= { 0x0004, 11, 11 },
> +	[GATING_EN]		= { 0x0004, 10, 10 },
> +	[IPI_SHUTDN]		= { 0x0004,  9,  9 },
> +	[IPI_COLORM]		= { 0x0004,  8,  8 },
> +	[IPI_COLOR_DEPTH]	= { 0x0004,  4,  7 },
> +	[IPI_FORMAT]		= { 0x0004,  0,  3 },
> +};
> +
> +static const struct rockchip_dw_dsi2_chip_data rk3588_chip_data[] = {
> +	{
> +		.reg = 0xfde20000,
> +		.grf_regs = rk3588_dsi0_grf_reg_fields,
> +		.max_bit_rate_per_lane = 4500000ULL,
> +	},
> +	{
> +		.reg = 0xfde30000,
> +		.grf_regs = rk3588_dsi1_grf_reg_fields,
> +		.max_bit_rate_per_lane = 4500000ULL,
> +	}
> +};
> +
> +static const struct of_device_id dw_mipi_dsi2_rockchip_dt_ids[] = {
> +	{
> +		.compatible = "rockchip,rk3588-mipi-dsi2",
> +		.data = &rk3588_chip_data,
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, dw_mipi_dsi2_rockchip_dt_ids);
> +
> +struct platform_driver dw_mipi_dsi2_rockchip_driver = {
> +	.probe	= dw_mipi_dsi2_rockchip_probe,
> +	.remove = dw_mipi_dsi2_rockchip_remove,
> +	.driver = {
> +		.of_match_table = dw_mipi_dsi2_rockchip_dt_ids,
> +		.name = "dw-mipi-dsi2",
> +	},
> +};
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index ddf0be331c0a..5327ce035003 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -511,6 +511,8 @@ static int __init rockchip_drm_init(void)
>   				CONFIG_ROCKCHIP_DW_HDMI_QP);
>   	ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver,
>   				CONFIG_ROCKCHIP_DW_MIPI_DSI);
> +	ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi2_rockchip_driver,
> +				CONFIG_ROCKCHIP_DW_MIPI_DSI2);
>   	ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI);
>   	ADD_ROCKCHIP_SUB_DRIVER(rk3066_hdmi_driver,
>   				CONFIG_ROCKCHIP_RK3066_HDMI);
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> index 24b4ce5ceaf1..9c9d38a06cdf 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> @@ -90,6 +90,7 @@ extern struct platform_driver cdn_dp_driver;
>   extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
>   extern struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver;
>   extern struct platform_driver dw_mipi_dsi_rockchip_driver;
> +extern struct platform_driver dw_mipi_dsi2_rockchip_driver;
>   extern struct platform_driver inno_hdmi_driver;
>   extern struct platform_driver rockchip_dp_driver;
>   extern struct platform_driver rockchip_lvds_driver;


From krzk at kernel.org  Tue Dec 10 00:53:54 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 10 Dec 2024 09:53:54 +0100
Subject: [PATCH v3 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <23e6d9c0-c3d6-40c1-b933-01c5a9ef43f8@gmail.com>
References: <20241209075908.140014-1-towinchenmi@gmail.com>
 <20241209075908.140014-3-towinchenmi@gmail.com>
 <w5niokvjfwajnzz3muccb45jsvqzg7lql7g5tg5s6iat3mtqkk@qu2a5zcp3rs7>
 <23e6d9c0-c3d6-40c1-b933-01c5a9ef43f8@gmail.com>
Message-ID: <0521227d-1607-4a3f-b307-4d799cf41c2c@kernel.org>

On 10/12/2024 09:47, Nick Chan wrote:
> 
> 
> Krzysztof Kozlowski ? 2024/12/10 ??4:32 ??:
> 
>> Nothing improved here.
> 
> 
> This is sent before you left any review, v4 will have improvements
> 
Ah, ok. Just popped in the patchwork.

In general rule is one patchset per 24h (some maintainers expect one per
48h), so reviewers will be able to respond.

Best regards,
Krzysztof


From l.stach at pengutronix.de  Tue Dec 10 01:00:57 2024
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 10 Dec 2024 10:00:57 +0100
Subject: [PATCH v2] serial: imx: Use uart_port_lock_irq() instead of
 uart_port_lock()
In-Reply-To: <20241210034223.1493522-1-xiaolei.wang@windriver.com>
References: <20241210034223.1493522-1-xiaolei.wang@windriver.com>
Message-ID: <b092fdec6fda26c56b4f2cc5927bbaa4a6d786f9.camel@pengutronix.de>

Am Dienstag, dem 10.12.2024 um 11:42 +0800 schrieb Xiaolei Wang:
> When executing 'ehco mem > /sys/power/state', the following
> deadlock occurs. Since there is output during the serial
> port entering the suspend process, the suspend will be
> interrupted, resulting in the nesting of locks. Therefore,
> use uart_port_lock_irq() instead of uart_port_unlock().
> 
> WARNING: inconsistent lock state
> 6.12.0-rc2-00002-g3c199ed5bd64-dirty #23 Not tainted
> --------------------------------
> inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
> sh/494 [HC0[0]:SC0[0]:HE1:SE1] takes:
> c4db5850 (&port_lock_key){?.-.}-{3:3}, at: imx_uart_enable_wakeup+0x14/0x254
> {IN-HARDIRQ-W} state was registered at:
>   lock_acquire+0x104/0x348
>   _raw_spin_lock+0x48/0x84
>   imx_uart_int+0x14/0x4dc
>   __handle_irq_event_percpu+0xac/0x2fc
>   handle_irq_event_percpu+0xc/0x40
>   handle_irq_event+0x38/0x8c
>   handle_fasteoi_irq+0xb4/0x1b8
>   handle_irq_desc+0x1c/0x2c
>   gic_handle_irq+0x6c/0xa0
>   generic_handle_arch_irq+0x2c/0x64
>   call_with_stack+0x18/0x20
>   __irq_svc+0x9c/0xbc
>   _raw_spin_unlock_irqrestore+0x2c/0x48
>   uart_write+0xd8/0x3a0
>   do_output_char+0x1a8/0x1e4
>   n_tty_write+0x224/0x440
>   file_tty_write.constprop.0+0x124/0x250
>   do_iter_readv_writev+0x100/0x1e0
>   vfs_writev+0xc4/0x448
>   do_writev+0x68/0xf8
>   ret_fast_syscall+0x0/0x1c
> irq event stamp: 31593
> hardirqs last  enabled at (31593): [<c1150e48>] _raw_spin_unlock_irqrestore+0x44/0x48
> hardirqs last disabled at (31592): [<c07f32f0>] clk_enable_lock+0x60/0x120
> softirqs last  enabled at (30334): [<c012d1d4>] handle_softirqs+0x2cc/0x478
> softirqs last disabled at (30325): [<c012d510>] __irq_exit_rcu+0x120/0x15c
> 
> other info that might help us debug this:
>  Possible unsafe locking scenario:
> 
>        CPU0
>        ----
>   lock(&port_lock_key);
>   <Interrupt>
>     lock(&port_lock_key);
> 
> Fixes: 3c199ed5bd64 ("serial: imx: Grab port lock in imx_uart_enable_wakeup()")
> Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>

Reviewed-by: Lucas Stach <l.stach at pengutronix.de>

> ---
> 
> v1:
>   https://patchwork.kernel.org/project/linux-arm-kernel/patch/20241209124732.693834-1-xiaolei.wang at windriver.com/
> v2:
>   use uart_port_lock_irq() instead of uart_port_lock_irqsave()
> 
>  drivers/tty/serial/imx.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 17f70e4bee43..9c59ec128bb4 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -2692,7 +2692,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
>  {
>  	u32 ucr3;
>  
> -	uart_port_lock(&sport->port);
> +	uart_port_lock_irq(&sport->port);
>  
>  	ucr3 = imx_uart_readl(sport, UCR3);
>  	if (on) {
> @@ -2714,7 +2714,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
>  		imx_uart_writel(sport, ucr1, UCR1);
>  	}
>  
> -	uart_port_unlock(&sport->port);
> +	uart_port_unlock_irq(&sport->port);
>  }
>  
>  static int imx_uart_suspend_noirq(struct device *dev)



From aliceryhl at google.com  Tue Dec 10 01:05:07 2024
From: aliceryhl at google.com (Alice Ryhl)
Date: Tue, 10 Dec 2024 10:05:07 +0100
Subject: [PATCH v1 5/5] rust: Add warn_on and warn_on_once
In-Reply-To: <20241210001802.228725-6-fujita.tomonori@gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com> <20241210001802.228725-6-fujita.tomonori@gmail.com>
Message-ID: <CAH5fLgiShKMGo6AYWM-4S8JK+iDA+tUfz9uxkns82g0nLW--NQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 1:19?AM FUJITA Tomonori
<fujita.tomonori at gmail.com> wrote:
>
> Add warn_on and warn_on_once macros. Wrapping the C's WARN_* and BUG_*
> macros doesn't work so this uses the assembly code exported by the C
> side via ARCH_WARN_ASM macro. Like the static branch code, this
> generates the assembly code for rust dynamically by using the C
> preprocessor.
>
> file()! macro doesn't work for the Rust inline assembly in the same
> way as __FILE__ for the C inline assembly. So the code to handle a
> file name is different from the C assembly code (similar to the
> arm64/loongarch assembly).
>
> ASM_REACHABLE definition works in the same way to get objtool's
> reachable asm code. The architectures which use objtool (x86 and
> loongarch) needs it.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>

> +#[macro_export]
> +#[doc(hidden)]
> +#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
> +#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]

> +#[macro_export]
> +#[doc(hidden)]
> +#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
> +#[cfg(any(target_arch = "aarch64", target_arch = "loongarch64"))]

What's the reason for this arch-specific code? The file!()/line!()
invocations? Could they be passed as an argument to the asm instead so
that we don't need target_arch cfgs? I understand that they don't work
exactly the same way, but maybe it could still work?

> +#[macro_export]
> +#[doc(hidden)]
> +#[cfg(all(CONFIG_BUG, CONFIG_UML))]
> +macro_rules! warn_flags {
> +    ($flags:expr) => {
> +        // SAFETY: Just an FFI call.
> +        unsafe {
> +            $crate::bindings::warn_slowpath_fmt(
> +                $crate::c_str!(::core::file!()).as_ptr() as *const ::core::ffi::c_char,
> +                line!() as i32,
> +                $flags as u32,
> +                ::core::ptr::null() as *const ::core::ffi::c_char,

I wonder if this could be written to utilize Location::caller()
instead so that `#[track_caller]` works?

Alice


From maz at kernel.org  Tue Dec 10 01:05:59 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Dec 2024 09:05:59 +0000
Subject: [PATCH V2 46/46] KVM: arm64: nv: Add trap forwarding for FEAT_FGT2 described registers
In-Reply-To: <20241210055311.780688-47-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
	<20241210055311.780688-47-anshuman.khandual@arm.com>
Message-ID: <87frmvsya0.wl-maz@kernel.org>

On Tue, 10 Dec 2024 05:53:11 +0000,
Anshuman Khandual <anshuman.khandual at arm.com> wrote:
> 
> Describe remaining MDCR_EL2 register, and associate that with all FEAT_FGT2
> exposed system registers it allows to trap.

MDCR_EL2 register *bits*? How is that related to FGT2 at all?

> 
> 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: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.linux.dev
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
> Changes in V2:
> 
> - Dropped check_cntr_accessible_N and CGT_CNTR_ACCESSIBLE_N constructs
> - SYS_PMEVCNTSVR_EL1(N) access traps have been forwarded to CGT_MDCR_HPMN
> - Updated check_mdcr_hpmn() to handle SYS_PMEVCNTSVR_EL1(N) registers
> - Changed behaviour as BEHAVE_FORWARD_RW for CGT_MDCR_EnSPM
> 
>  arch/arm64/include/asm/kvm_host.h |   2 +
>  arch/arm64/kvm/emulate-nested.c   | 158 ++++++++++++++++++++++++++++++
>  2 files changed, 160 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index c80c07be3358..4cdce62642d1 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -441,6 +441,7 @@ enum vcpu_sysreg {
>  	PMINTENSET_EL1,	/* Interrupt Enable Set Register */
>  	PMOVSSET_EL0,	/* Overflow Flag Status Set Register */
>  	PMUSERENR_EL0,	/* User Enable Register */
> +	SPMSELR_EL0,	/* System PMU Select Register */

How could a system PMU be relevant to a VM?  What is the point of
bloating the vcpu for something that we will hopefully *never* make
visible to guests?

>  
>  	/* Pointer Authentication Registers in a strict increasing order. */
>  	APIAKEYLO_EL1,
> @@ -501,6 +502,7 @@ enum vcpu_sysreg {
>  	CNTHP_CVAL_EL2,
>  	CNTHV_CTL_EL2,
>  	CNTHV_CVAL_EL2,
> +	SPMACCESSR_EL2, /* System PMU Access Register */

Same here. It is pretty striking that these registers are never
saved/restored or handled as traps, which is a good indication that
this is pretty pointless.

>  
>  	/* Anything from this can be RES0/RES1 sanitised */
>  	MARKER(__SANITISED_REG_START__),
> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> index 6c63cbfc11ea..c7d6d2034f27 100644
> --- a/arch/arm64/kvm/emulate-nested.c
> +++ b/arch/arm64/kvm/emulate-nested.c
> @@ -79,6 +79,7 @@ enum cgt_group_id {
>  	CGT_MDCR_TDRA,
>  	CGT_MDCR_E2PB,
>  	CGT_MDCR_TPMS,
> +	CGT_MDCR_EnSPM,
>  	CGT_MDCR_TTRF,
>  	CGT_MDCR_E2TB,
>  	CGT_MDCR_TDCC,
> @@ -125,6 +126,7 @@ enum cgt_group_id {
>  	CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
>  	CGT_CNTHCTL_EL1PTEN,
>  
> +	CGT_SPMSEL_SPMACCESS,
>  	CGT_CPTR_TTA,
>  	CGT_MDCR_HPMN,
>  
> @@ -351,6 +353,12 @@ static const struct trap_bits coarse_trap_bits[] = {
>  		.mask		= MDCR_EL2_TPMS,
>  		.behaviour	= BEHAVE_FORWARD_RW,
>  	},
> +	[CGT_MDCR_EnSPM] = {
> +		.index		= MDCR_EL2,
> +		.value		= MDCR_EL2_EnSPM,
> +		.mask		= MDCR_EL2_EnSPM,
> +		.behaviour	= BEHAVE_FORWARD_RW,
> +	},
>  	[CGT_MDCR_TTRF] = {
>  		.index		= MDCR_EL2,
>  		.value		= MDCR_EL2_TTRF,
> @@ -509,6 +517,7 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
>  	switch (sysreg) {
>  	case SYS_PMEVTYPERn_EL0(0) ... SYS_PMEVTYPERn_EL0(30):
>  	case SYS_PMEVCNTRn_EL0(0) ... SYS_PMEVCNTRn_EL0(30):
> +	case SYS_PMEVCNTSVR_EL1(0) ... SYS_PMEVCNTSVR_EL1(30):
>  		idx = (sys_reg_CRm(sysreg) & 0x3) << 3 | sys_reg_Op2(sysreg);
>  		break;
>  	case SYS_PMXEVTYPER_EL0:
> @@ -528,6 +537,22 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
>  	return BEHAVE_HANDLE_LOCALLY;
>  }
>  
> +static enum trap_behaviour check_spmsel_spmaccess(struct kvm_vcpu *vcpu)
> +{
> +	u64 spmaccessr_el2, spmselr_el2;
> +	int syspmusel;
> +
> +	if (__vcpu_sys_reg(vcpu, MDCR_EL2) & MDCR_EL2_EnSPM) {

I don't mind the test, but I don't see any sanitising of MDCR_EL2 to
make EnSPM as RES0 when FEAT_SPMU is not implemented, which will be
100% of the cases.

> +		spmselr_el2 = __vcpu_sys_reg(vcpu, SPMSELR_EL0);
> +		spmaccessr_el2 = __vcpu_sys_reg(vcpu, SPMACCESSR_EL2);

So these two values are *guaranteed* to be zero. At this stage, what
is the point?

> +		syspmusel = FIELD_GET(SPMSELR_EL0_SYSPMUSEL_MASK, spmselr_el2);
> +
> +		if (((spmaccessr_el2 >> (syspmusel * 2)) & 0x3) == 0x0)
> +			return BEHAVE_FORWARD_RW;

What about value 0b01, which causes *writes* to be trapped?

> +	}
> +	return BEHAVE_HANDLE_LOCALLY;

And then what? How do we handle this locally?

Honestly, short of any additional handling, we would be better off
just injecting an UNDEF back into the guest.

	M.

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


From quic_akhilpo at quicinc.com  Tue Dec 10 01:13:29 2024
From: quic_akhilpo at quicinc.com (Akhil P Oommen)
Date: Tue, 10 Dec 2024 14:43:29 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <CAF6AEGvBU8mB5HHNK4nP5h9ouKfLNhCMFgF+PhrC77ZMfSOTkQ@mail.gmail.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>
 <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>
 <CAF6AEGvBU8mB5HHNK4nP5h9ouKfLNhCMFgF+PhrC77ZMfSOTkQ@mail.gmail.com>
Message-ID: <eb467542-af20-4327-b4ea-c7eba56431ab@quicinc.com>

On 12/10/2024 3:26 AM, Rob Clark wrote:
> On Mon, Dec 9, 2024 at 12:52?PM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
>>
>> On 12/10/2024 1:24 AM, Rob Clark wrote:
>>> On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
>>>>
>>>> When kernel is booted in EL2, SECVID registers are accessible to the
>>>> KMD. So we can use that to switch GPU's secure mode to avoid dependency
>>>> on Zap firmware. Also, we can't load a secure firmware without a
>>>> hypervisor that supports it.
>>>
>>> Shouldn't we do this based on whether zap node is in dtb (and not disabled)?
>>
>> This is better, isn't it? Otherwise, multiple overlays should be
>> maintained for each soc/board since EL2 can be toggled from bootloader.
>> And this feature is likely going to be more widely available.
> 
> I guess the first question is what the dt should look like.  I think
> it makes sense to not have a zap node when booting in EL2 (or at least
> disabling it) because that describes the hw+fw situation.  And in any
> case, so far it seems like we often need unrelated changes[1].  But
> maybe others have differing opinions.
> 
> And depending on how much cooperation we get from the bootloader, it
> could be that our hand is forced.  I figured I should at least point
> out how we currently handle this.

At the moment, the bootloader we use on sa8775p doesn't have overlay
support. So I felt we could free GPU from that requirement and get it
enabled independently. At least to get the basic things working *out of
the box*. We have Display, GPU and Guest VM working with no extra changes.

> 
> A further point, I suppose it is in theory possible that a device
> could have no secure playback support, despite booting in EL1?  So
> tying this to EL2 seems a bit contrived.
> 

That is correct. But not sure how widely that configuration would be
used practically. OTOH, Kernel running at EL2 in qcom chipsets is going
to be more wider in usage. This is showing up as a common requirement
for non-handset chipsets, especially IoT. So a special case here in our
driver doesn't seem bad to me. Let software work out of the box, instead
of "disable GPU by default". ;)

-Akhil.

> BR,
> -R
> 
> [1] https://github.com/TravMurav/slbounce/blob/main/dtbo/x1e-el2.dtso
> 
>> -Akhil.
>>
>>>
>>> slbounce applies some dtb overlays to disable the zap node when
>>> booting in EL2 (and make some other changes due to kernel being in
>>> control of the pci smmuv3, or something along those lines).
>>>
>>> BR,
>>> -R
>>>
>>>>
>>>> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
>>>>
>>>> 1. Gunyah (No KVM) - Loads zap shader based on DT
>>>> 2. KVM in VHE - Skips zap shader load and programs SECVID register
>>>> 3. KVM in nVHE - Loads zap shader based on DT
>>>> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
>>>>         programs SECVID register
>>>>
>>>> For (1) and (3) configuration, this patch doesn't have any impact.
>>>> Driver loads secure firmware based on other existing hints.
>>>>
>>>> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
>>>> ---
>>>> ---
>>>>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 +++++++++++++++++++++++------------
>>>>  1 file changed, 54 insertions(+), 28 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>> index 019610341df1..9dcaa8472430 100644
>>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>> @@ -14,6 +14,10 @@
>>>>  #include <linux/pm_domain.h>
>>>>  #include <linux/soc/qcom/llcc-qcom.h>
>>>>
>>>> +#ifdef CONFIG_ARM64
>>>> +#include <asm/virt.h>
>>>> +#endif
>>>> +
>>>>  #define GPU_PAS_ID 13
>>>>
>>>>  static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
>>>> @@ -998,6 +1002,54 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
>>>>         return ret;
>>>>  }
>>>>
>>>> +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
>>>> +{
>>>> +       int ret;
>>>> +
>>>> +#ifdef CONFIG_ARM64
>>>> +       /*
>>>> +        * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
>>>> +        * to switch the secure mode to avoid the dependency on zap shader.
>>>> +        */
>>>> +       if (is_kernel_in_hyp_mode())
>>>> +               goto direct_switch;
>>>> +#endif
>>>> +
>>>> +       /*
>>>> +        * Try to load a zap shader into the secure world. If successful
>>>> +        * we can use the CP to switch out of secure mode. If not then we
>>>> +        * have no resource but to try to switch ourselves out manually. If we
>>>> +        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
>>>> +        * be blocked and a permissions violation will soon follow.
>>>> +        */
>>>> +       ret = a6xx_zap_shader_init(gpu);
>>>> +       if (ret == -ENODEV) {
>>>> +               /*
>>>> +                * This device does not use zap shader (but print a warning
>>>> +                * just in case someone got their dt wrong.. hopefully they
>>>> +                * have a debug UART to realize the error of their ways...
>>>> +                * if you mess this up you are about to crash horribly)
>>>> +                */
>>>> +               dev_warn_once(gpu->dev->dev,
>>>> +                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
>>>> +               goto direct_switch;
>>>> +       } else if (ret)
>>>> +               return ret;
>>>> +
>>>> +       OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
>>>> +       OUT_RING(gpu->rb[0], 0x00000000);
>>>> +
>>>> +       a6xx_flush(gpu, gpu->rb[0]);
>>>> +       if (!a6xx_idle(gpu, gpu->rb[0]))
>>>> +               return -EINVAL;
>>>> +
>>>> +       return 0;
>>>> +
>>>> +direct_switch:
>>>> +       gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
>>>> +       return 0;
>>>> +}
>>>> +
>>>>  #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
>>>>                        A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
>>>>                        A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
>>>> @@ -1341,35 +1393,9 @@ static int hw_init(struct msm_gpu *gpu)
>>>>         if (ret)
>>>>                 goto out;
>>>>
>>>> -       /*
>>>> -        * Try to load a zap shader into the secure world. If successful
>>>> -        * we can use the CP to switch out of secure mode. If not then we
>>>> -        * have no resource but to try to switch ourselves out manually. If we
>>>> -        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
>>>> -        * be blocked and a permissions violation will soon follow.
>>>> -        */
>>>> -       ret = a6xx_zap_shader_init(gpu);
>>>> -       if (!ret) {
>>>> -               OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
>>>> -               OUT_RING(gpu->rb[0], 0x00000000);
>>>> -
>>>> -               a6xx_flush(gpu, gpu->rb[0]);
>>>> -               if (!a6xx_idle(gpu, gpu->rb[0]))
>>>> -                       return -EINVAL;
>>>> -       } else if (ret == -ENODEV) {
>>>> -               /*
>>>> -                * This device does not use zap shader (but print a warning
>>>> -                * just in case someone got their dt wrong.. hopefully they
>>>> -                * have a debug UART to realize the error of their ways...
>>>> -                * if you mess this up you are about to crash horribly)
>>>> -                */
>>>> -               dev_warn_once(gpu->dev->dev,
>>>> -                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
>>>> -               gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
>>>> -               ret = 0;
>>>> -       } else {
>>>> +       ret = a6xx_switch_secure_mode(gpu);
>>>> +       if (!ret)
>>>>                 return ret;
>>>> -       }
>>>>
>>>>  out:
>>>>         if (adreno_has_gmu_wrapper(adreno_gpu))
>>>>
>>>> ---
>>>> base-commit: f4a867a46862c1743501bbe8c813238456ec8699
>>>> change-id: 20241120-drm-msm-kvm-support-cd6e6744ced6
>>>>
>>>> Best regards,
>>>> --
>>>> Akhil P Oommen <quic_akhilpo at quicinc.com>
>>>>
>>



From ck.hu at mediatek.com  Tue Dec 10 01:16:46 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 10 Dec 2024 09:16:46 +0000
Subject: [PATCH] drm/mediatek: Set private->all_drm_private[i]->drm to
 NULL if mtk_drm_bind returns err
In-Reply-To: <20241206135507.1274357-1-guoqing.jiang@canonical.com>
References: <20241206135507.1274357-1-guoqing.jiang@canonical.com>
Message-ID: <3670b4af699a1c12000f09d671e93e3ae7359724.camel@mediatek.com>

Hi, Guoqing:

On Fri, 2024-12-06 at 21:55 +0800, Guoqing Jiang wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> The pointer need to be set to NULL, otherwise KASAN complains about
> use-after-free. Because in mtk_drm_bind, all private's drm are set
> as follows.
> 
> private->all_drm_private[i]->drm = drm;
> 
> And drm will be released by drm_dev_put in case mtk_drm_kms_init returns
> failure. However, the shutdown path still accesses the previous allocated
> memory in drm_atomic_helper_shutdown.
> 
> [   84.874820] watchdog: watchdog0: watchdog did not stop!
> [   86.512054] ==================================================================
> [   86.513162] BUG: KASAN: use-after-free in drm_atomic_helper_shutdown+0x33c/0x378
> [   86.514258] Read of size 8 at addr ffff0000d46fc068 by task shutdown/1
> [   86.515213]
> [   86.515455] CPU: 1 UID: 0 PID: 1 Comm: shutdown Not tainted 6.13.0-rc1-mtk+gfa1a78e5d24b-dirty #55
> [   86.516752] Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10 10/01/2022
> [   86.517960] Call trace:
> [   86.518333]  show_stack+0x20/0x38 (C)
> [   86.518891]  dump_stack_lvl+0x90/0xd0
> [   86.519443]  print_report+0xf8/0x5b0
> [   86.519985]  kasan_report+0xb4/0x100
> [   86.520526]  __asan_report_load8_noabort+0x20/0x30
> [   86.521240]  drm_atomic_helper_shutdown+0x33c/0x378
> [   86.521966]  mtk_drm_shutdown+0x54/0x80
> [   86.522546]  platform_shutdown+0x64/0x90
> [   86.523137]  device_shutdown+0x260/0x5b8
> [   86.523728]  kernel_restart+0x78/0xf0
> [   86.524282]  __do_sys_reboot+0x258/0x2f0
> [   86.524871]  __arm64_sys_reboot+0x90/0xd8
> [   86.525473]  invoke_syscall+0x74/0x268
> [   86.526041]  el0_svc_common.constprop.0+0xb0/0x240
> [   86.526751]  do_el0_svc+0x4c/0x70
> [   86.527251]  el0_svc+0x4c/0xc0
> [   86.527719]  el0t_64_sync_handler+0x144/0x168
> [   86.528367]  el0t_64_sync+0x198/0x1a0
> [   86.528920]
> [   86.529157] The buggy address belongs to the physical page:
> [   86.529972] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff0000d46fd4d0 pfn:0x1146fc
> [   86.531319] flags: 0xbfffc0000000000(node=0|zone=2|lastcpupid=0xffff)
> [   86.532267] raw: 0bfffc0000000000 0000000000000000 dead000000000122 0000000000000000
> [   86.533390] raw: ffff0000d46fd4d0 0000000000000000 00000000ffffffff 0000000000000000
> [   86.534511] page dumped because: kasan: bad access detected
> [   86.535323]
> [   86.535559] Memory state around the buggy address:
> [   86.536265]  ffff0000d46fbf00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.537314]  ffff0000d46fbf80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.538363] >ffff0000d46fc000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.544733]                                                           ^
> [   86.551057]  ffff0000d46fc080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.557510]  ffff0000d46fc100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.563928] ==================================================================
> [   86.571093] Disabling lock debugging due to kernel taint
> [   86.577642] Unable to handle kernel paging request at virtual address e0e9c0920000000b
> [   86.581834] KASAN: maybe wild-memory-access in range [0x0752049000000058-0x075204900000005f]
> ...

Refer to [1] to add Fixes tag.

[1] https://www.kernel.org/doc/html/v6.12/process/submitting-patches.html

Regards,
CK

> 
> Signed-off-by: Guoqing Jiang <guoqing.jiang at canonical.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 9a8ef8558da9..0062374f75d5 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -673,6 +673,8 @@ static int mtk_drm_bind(struct device *dev)
>  err_free:
>         private->drm = NULL;
>         drm_dev_put(drm);
> +       for (i = 0; i < private->data->mmsys_dev_num; i++)
> +               private->all_drm_private[i]->drm = NULL;
>         return ret;
>  }
> 
> --
> 2.35.3
> 
> 


From andrej.picej at norik.com  Tue Dec 10 01:19:01 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue, 10 Dec 2024 10:19:01 +0100
Subject: [PATCH v5 3/3] arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing
In-Reply-To: <20241210091901.83028-1-andrej.picej@norik.com>
References: <20241210091901.83028-1-andrej.picej@norik.com>
Message-ID: <20241210091901.83028-4-andrej.picej@norik.com>

Set custom differential output voltage for LVDS, to fulfill requirements
of the connected display. LVDS differential voltage for data-lanes and
clock output has to be between 200 mV and 600 mV.
Driver sets 200 Ohm near-end termination by default.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v5:
- no change
Changes in v4:
- no change
Changes in v3:
- no change
Changes in v2:
- use new properties from previous patches
---
 .../boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso     | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
index a9de42cf14be..8bf9cc553bea 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
@@ -186,6 +186,8 @@ port at 2 {
 			reg = <2>;
 			bridge_out: endpoint {
 				remote-endpoint = <&panel_in>;
+				ti,lvds-vod-swing-clock-microvolt = <200000 600000>;
+				ti,lvds-vod-swing-data-microvolt = <200000 600000>;
 			};
 		};
 	};
-- 
2.34.1



From andrej.picej at norik.com  Tue Dec 10 01:19:00 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue, 10 Dec 2024 10:19:00 +0100
Subject: [PATCH v5 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
In-Reply-To: <20241210091901.83028-1-andrej.picej@norik.com>
References: <20241210091901.83028-1-andrej.picej@norik.com>
Message-ID: <20241210091901.83028-3-andrej.picej@norik.com>

Add a optional properties to change LVDS output voltage. This should not
be static as this depends mainly on the connected display voltage
requirement. We have three properties:
- "ti,lvds-termination-ohms", which sets near end termination,
- "ti,lvds-vod-swing-data-microvolt" and
- "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
output voltage for data and clock lanes. They are defined as an array
with min and max values. The appropriate bitfield will be set if
selected constraints can be met.

If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
end termination will be used. Selecting only one:
"ti,lvds-vod-swing-data-microvolt" or
"ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
constraint for only data/clock lanes will be met. Setting both is
recommended.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v5:
- specify default values in sn65dsi83_parse_lvds_endpoint,
- move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
Changes in v4:
- fix typo in commit message bitfiled -> bitfield
- use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
of separate variables for channel A/B
- add more checks on return value of "of_property_read_u32_array"
Changes in v3:
- use microvolts for default array values 1000 mV -> 1000000 uV.
Changes in v2:
- use datasheet tables to get the proper configuration
- since major change was done change the authorship to myself
---
 drivers/gpu/drm/bridge/ti-sn65dsi83.c | 142 +++++++++++++++++++++++++-
 1 file changed, 139 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 57a7ed13f996..f9578b38da28 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -132,6 +132,16 @@
 #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
 #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
 
+enum sn65dsi83_channel {
+	CHANNEL_A,
+	CHANNEL_B
+};
+
+enum sn65dsi83_lvds_term {
+	OHM_100,
+	OHM_200
+};
+
 enum sn65dsi83_model {
 	MODEL_SN65DSI83,
 	MODEL_SN65DSI84,
@@ -147,6 +157,8 @@ struct sn65dsi83 {
 	struct regulator		*vcc;
 	bool				lvds_dual_link;
 	bool				lvds_dual_link_even_odd_swap;
+	int				lvds_vod_swing_conf[2];
+	int				lvds_term_conf[2];
 };
 
 static const struct regmap_range sn65dsi83_readable_ranges[] = {
@@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
 	.max_register = REG_IRQ_STAT,
 };
 
+static const int lvds_vod_swing_data_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 180000, 313000 },
+		{ 215000, 372000 },
+		{ 250000, 430000 },
+		{ 290000, 488000 },
+	},
+	{	/* 200 Ohm */
+		{ 150000, 261000 },
+		{ 200000, 346000 },
+		{ 250000, 428000 },
+		{ 300000, 511000 },
+	},
+};
+
+static const int lvds_vod_swing_clock_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 140000, 244000 },
+		{ 168000, 290000 },
+		{ 195000, 335000 },
+		{ 226000, 381000 },
+	},
+	{	/* 200 Ohm */
+		{ 117000, 204000 },
+		{ 156000, 270000 },
+		{ 195000, 334000 },
+		{ 234000, 399000 },
+	},
+};
+
 static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
 {
 	return container_of(bridge, struct sn65dsi83, bridge);
@@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
 		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
 
 	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
-	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
+	regmap_write(ctx->regmap, REG_LVDS_VCOM,
+			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
+			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
 	regmap_write(ctx->regmap, REG_LVDS_LANE,
 		     (ctx->lvds_dual_link_even_odd_swap ?
 		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
-		     REG_LVDS_LANE_CHA_LVDS_TERM |
-		     REG_LVDS_LANE_CHB_LVDS_TERM);
+		     (ctx->lvds_term_conf[CHANNEL_A] ?
+			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
+		     (ctx->lvds_term_conf[CHANNEL_B] ?
+			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
 	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
 
 	le16val = cpu_to_le16(mode->hdisplay);
@@ -576,10 +622,100 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
 	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
 };
 
+static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
+	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
+{
+	int i;
+
+	for (i = 0; i <= 3; i++) {
+		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
+		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
+		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
+		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
+			return i;
+	}
+
+	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
+	return -EINVAL;
+}
+
+static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *endpoint;
+	int endpoint_reg;
+	/* Set so the property can be freely selected if not defined */
+	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
+	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
+	u32 lvds_term;
+	u8 lvds_term_conf = 0x1;
+	int lvds_vod_swing_conf = 0x1;
+	int ret = 0;
+	int ret_data;
+	int ret_clock;
+
+	if (channel == CHANNEL_A)
+		endpoint_reg = 2;
+	else
+		endpoint_reg = 3;
+
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
+	if (!of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term)) {
+		if (lvds_term == 100)
+			lvds_term_conf = OHM_100;
+		else
+			lvds_term_conf = OHM_200;
+	}
+
+	ctx->lvds_term_conf[channel] = lvds_term_conf;
+
+	ret_data = of_property_read_u32_array(endpoint,
+			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
+			ARRAY_SIZE(lvds_vod_swing_data));
+	if (ret_data != 0 && ret_data != -EINVAL) {
+		ret = ret_data;
+		goto exit;
+	}
+
+	ret_clock = of_property_read_u32_array(endpoint,
+			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
+			ARRAY_SIZE(lvds_vod_swing_clk));
+	if (ret_clock != 0 && ret_clock != -EINVAL) {
+		ret = ret_clock;
+		goto exit;
+	}
+
+	/* If any of the two properties is defined. */
+	if (!ret_data || !ret_clock) {
+		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
+			lvds_vod_swing_data, lvds_vod_swing_clk,
+			lvds_term_conf);
+		if (lvds_vod_swing_conf < 0) {
+			ret = lvds_vod_swing_conf;
+			goto exit;
+		}
+	}
+
+	ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
+	ret = 0;
+exit:
+	of_node_put(endpoint);
+	return ret;
+}
+
 static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
 {
 	struct drm_bridge *panel_bridge;
 	struct device *dev = ctx->dev;
+	int ret;
+
+	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
+	if (ret < 0)
+		return ret;
+
+	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
+	if (ret < 0)
+		return ret;
 
 	ctx->lvds_dual_link = false;
 	ctx->lvds_dual_link_even_odd_swap = false;
-- 
2.34.1



From andrej.picej at norik.com  Tue Dec 10 01:18:59 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue, 10 Dec 2024 10:18:59 +0100
Subject: [PATCH v5 1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for ti,lvds-vod-swing
In-Reply-To: <20241210091901.83028-1-andrej.picej@norik.com>
References: <20241210091901.83028-1-andrej.picej@norik.com>
Message-ID: <20241210091901.83028-2-andrej.picej@norik.com>

Add properties which can be used to specify LVDS differential output
voltage. Since this also depends on near-end signal termination also
include property which sets this. LVDS differential output voltage is
specified with an array (min, max), which should match the one from
connected device.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes in v5:
- added Krzysztof's reviewed-by tag
Changes in v4:
- removed "additionalProperties: true" from the patch as it is not needed
Changes in v3:
- no change
Changes in v2:
- move LVDS port schema to a $defs and reference it from there
- properties are now defined in microvolts/ohms
- use 1 property for data-lane and 1 for clock-lane LVDS voltage swing
- add 1 property which sets LVDS near-end termination
- since major change was done change the authorship to myself
---
 .../bindings/display/bridge/ti,sn65dsi83.yaml | 34 +++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
index 48a97bb3e2e0..bad6f5c81b06 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
@@ -80,12 +80,12 @@ properties:
                   - const: 4
 
       port at 2:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-A output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
       port at 3:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-B output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
     required:
       - port at 0
@@ -96,6 +96,36 @@ required:
   - reg
   - ports
 
+$defs:
+  lvds-port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    unevaluatedProperties: false
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          ti,lvds-termination-ohms:
+            description: The value of near end differential termination in ohms.
+            enum: [100, 200]
+            default: 200
+
+          ti,lvds-vod-swing-clock-microvolt:
+            description: LVDS diferential output voltage <min max> for clock
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
+          ti,lvds-vod-swing-data-microvolt:
+            description: LVDS diferential output voltage <min max> for data
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
 allOf:
   - if:
       properties:
-- 
2.34.1



From andrej.picej at norik.com  Tue Dec 10 01:18:58 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue, 10 Dec 2024 10:18:58 +0100
Subject: [PATCH v5 0/3] SN65DSI83/4 lvds_vod_swing properties
Message-ID: <20241210091901.83028-1-andrej.picej@norik.com>

Hi all,

The LVDS differential voltage swing can be specified as arrays of min, max
in microvolts. Two arrays, one for data-lanes and one for clock-lane can
be specified. Additionally, because LVDS voltage swing depends on near-end
termination this can now also be specified with separate property.

Driver goes through the tables, taken from datasheet [1] and selects the
appropriate configuration. If appropriate configuration can not be found
the probe fails. If these properties are not defined default values are
used as before.

This patch series depends on the patch
"[PATCH v2 11/15] arm64: dts: imx8mm-phyboard-polis: Add support for PEB-AV-10"
(https://lore.kernel.org/all/20241202072052.2195283-12-andrej.picej at norik.com/)
which is currently under review. Please apply the dependent series first before
applying this one.

v1 is at: https://lore.kernel.org/all/20241127103031.1007893-1-andrej.picej at norik.com/
v2 is at: https://lore.kernel.org/all/20241203085822.2475138-1-andrej.picej at norik.com/
v3 is at: https://lore.kernel.org/all/20241203110054.2506123-1-andrej.picej at norik.com/
v4 is at: https://lore.kernel.org/all/20241205134021.2592013-1-andrej.picej at norik.com/

[1] https://www.ti.com/lit/ds/symlink/sn65dsi83.pdf?ts=1732738773429&ref_url=https%253A%252F%252Fwww.mouser.co.uk%252F

Best regards,
Andrej

Andrej Picej (3):
  dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for
    ti,lvds-vod-swing
  drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
  arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing

 .../bindings/display/bridge/ti,sn65dsi83.yaml |  34 ++++-
 .../imx8mm-phyboard-polis-peb-av-10.dtso      |   2 +
 drivers/gpu/drm/bridge/ti-sn65dsi83.c         | 142 +++++++++++++++++-
 3 files changed, 173 insertions(+), 5 deletions(-)

-- 
2.34.1



From kevin.brodsky at arm.com  Tue Dec 10 01:27:56 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Tue, 10 Dec 2024 10:27:56 +0100
Subject: [RFC PATCH 12/16] arm64: mm: Map p4d/pgd with privileged pkey
In-Reply-To: <20241209102440.GI21636@noisy.programming.kicks-ass.net>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-13-kevin.brodsky@arm.com>
 <20241209102440.GI21636@noisy.programming.kicks-ass.net>
Message-ID: <75a345d4-78ea-4434-a4cd-3f2095ce2b31@arm.com>

On 09/12/2024 11:24, Peter Zijlstra wrote:
> On Fri, Dec 06, 2024 at 10:11:06AM +0000, Kevin Brodsky wrote:
>> If CONFIG_KPKEYS_HARDENED_PGTABLES is enabled, map p4d/pgd pages
>> using a privileged pkey (KPKEYS_PKEY_PGTABLES), so that they can
>> only be written under guard(kpkeys_hardened_pgtables).
>>
>> The case where pgd is not page-sized is not currently handled -
>> this is pending support for pkeys in kmem_cache.
>>
>> This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
>> (default).
> Should not this live in pagetable_*_[cd]tor() in generic code?

This would certainly be preferable but it doesn't look like such helpers
exist for p4d/pgd. For p4d, we could potentially handle this in the
generic __p4d_alloc(), but I'm not sure we can assume that
p4d_alloc_one() won't be called from somewhere else. pgd_alloc() is
entirely arch-specific so not much we can do there.

- Kevin


From wenst at chromium.org  Tue Dec 10 01:26:12 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 10 Dec 2024 17:26:12 +0800
Subject: [PATCH 1/2] arm64: dts: mediatek: mt8173-elm: Fix MT6397 PMIC sub-node names
Message-ID: <20241210092614.3951748-1-wenst@chromium.org>

The MT6397 PMIC bindings specify exact names for its sub-nodes. The
names used in the current dts don't match, causing a validation error.

Fix up the names. Also drop the label for the regulators node, since
any reference should be against the individual regulator sub-nodes.

Fixes: 689b937bedde ("arm64: dts: mediatek: add mt8173 elm and hana board")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
index b91072f4723f..b5d4b5baf478 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
@@ -931,7 +931,7 @@ pmic: pmic {
 		interrupt-controller;
 		#interrupt-cells = <2>;
 
-		clock: mt6397clock {
+		clock: clocks {
 			compatible = "mediatek,mt6397-clk";
 			#clock-cells = <1>;
 		};
@@ -942,7 +942,7 @@ pio6397: pinctrl {
 			#gpio-cells = <2>;
 		};
 
-		regulator: mt6397regulator {
+		regulators {
 			compatible = "mediatek,mt6397-regulator";
 
 			mt6397_vpca15_reg: buck_vpca15 {
@@ -1108,7 +1108,7 @@ mt6397_vibr_reg: ldo_vibr {
 			};
 		};
 
-		rtc: mt6397rtc {
+		rtc: rtc {
 			compatible = "mediatek,mt6397-rtc";
 		};
 	};
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Tue Dec 10 01:26:13 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 10 Dec 2024 17:26:13 +0800
Subject: [PATCH 2/2] arm64: dts: mediatek: mt8173-evb: Fix MT6397 PMIC sub-node names
In-Reply-To: <20241210092614.3951748-1-wenst@chromium.org>
References: <20241210092614.3951748-1-wenst@chromium.org>
Message-ID: <20241210092614.3951748-2-wenst@chromium.org>

The MT6397 PMIC bindings specify exact names for its sub-nodes. The
names used in the current dts don't match, causing a validation error.

Fix up the names. Also drop the label for the regulators node, since
any reference should be against the individual regulator sub-nodes.

Fixes: 16ea61fc5614 ("arm64: dts: mt8173-evb: Add PMIC support")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 511c16cb1d59..9fffed0ef4bf 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -307,7 +307,7 @@ pmic: pmic {
 		interrupt-controller;
 		#interrupt-cells = <2>;
 
-		mt6397regulator: mt6397regulator {
+		regulators {
 			compatible = "mediatek,mt6397-regulator";
 
 			mt6397_vpca15_reg: buck_vpca15 {
-- 
2.47.0.338.g60cca15819-goog



From kevin.brodsky at arm.com  Tue Dec 10 01:27:35 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Tue, 10 Dec 2024 10:27:35 +0100
Subject: [RFC PATCH 08/16] mm: Introduce kernel_pgtables_set_pkey()
In-Reply-To: <20241209100335.GH21636@noisy.programming.kicks-ass.net>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-9-kevin.brodsky@arm.com>
 <20241209100335.GH21636@noisy.programming.kicks-ass.net>
Message-ID: <accd59bd-27ff-4a22-b3a5-c2705a0db075@arm.com>

On 09/12/2024 11:03, Peter Zijlstra wrote:
> On Fri, Dec 06, 2024 at 10:11:02AM +0000, Kevin Brodsky wrote:
>> kernel_pgtables_set_pkey() allows setting the pkey of all page table
>> pages in swapper_pg_dir, recursively. This will be needed by
>> kpkeys_hardened_pgtables, as it relies on all PTPs being mapped with
>> a non-default pkey. Those initial kernel page tables cannot
>> practically be assigned a non-default pkey right when they are
>> allocated, so mutating them during (early) boot is required.
>>
>> Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
>> ---
>>
>> It feels that some sort of locking is called for in
>> kernel_pgtables_set_pkey(), but I couldn't figure out what would be
>> appropriate.
> init_mm.page_table_lock is typically the one used to serialize kernel
> page tables IIRC.

That does seem to be the case, thanks! Hopefully holding that spinlock
for the entire duration of the loop in kernel_pgtables_set_pkey() won't
be an issue.

- Kevin


From kevin.brodsky at arm.com  Tue Dec 10 01:28:44 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Tue, 10 Dec 2024 10:28:44 +0100
Subject: [RFC PATCH 13/16] arm64: mm: Reset pkey in __tlb_remove_table()
In-Reply-To: <20241209102913.GJ21636@noisy.programming.kicks-ass.net>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-14-kevin.brodsky@arm.com>
 <20241209102913.GJ21636@noisy.programming.kicks-ass.net>
Message-ID: <7124d7f4-1d4c-4497-94d8-243af2ed071a@arm.com>

On 09/12/2024 11:29, Peter Zijlstra wrote:
> On Fri, Dec 06, 2024 at 10:11:07AM +0000, Kevin Brodsky wrote:
>> [...]
>>
>> diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
>> index a947c6e784ed..d1611ffa6d91 100644
>> --- a/arch/arm64/include/asm/tlb.h
>> +++ b/arch/arm64/include/asm/tlb.h
>> @@ -10,10 +10,14 @@
>>  
>>  #include <linux/pagemap.h>
>>  #include <linux/swap.h>
>> +#include <linux/kpkeys.h>
>>  
>>  static inline void __tlb_remove_table(void *_table)
>>  {
>> -	free_page_and_swap_cache((struct page *)_table);
>> +	struct page *page = (struct page *)_table;
>> +
>> +	kpkeys_unprotect_pgtable_memory((unsigned long)page_address(page), 1);
>> +	free_page_and_swap_cache(page);
>>  }
> Same as for the others, perhaps stick this in generic code instead of in
> the arch code?

This should be doable, with some refactoring. __tlb_remove_table() is
currently called from two functions in mm/mmu_gather.c, I suppose I
could create a wrapper there that calls
kpkeys_unprotect_pgtable_memory() and then __tlb_remove_table(). Like in
the p4d case I do however wonder how robust this is, as
__tlb_remove_table() could end up being called from other places.

- Kevin


From ming.qian at oss.nxp.com  Tue Dec 10 01:33:37 2024
From: ming.qian at oss.nxp.com (Ming Qian)
Date: Tue, 10 Dec 2024 18:33:37 +0900
Subject: [PATCH v2] media: amphion: Add H264 and HEVC profile and level control
Message-ID: <20241210093337.3779686-1-ming.qian@oss.nxp.com>

From: Ming Qian <ming.qian at nxp.com>

For format H264 and HEVC, the firmware can report the parsed profile idc
and level idc to driver, the information may be useful.
Implement the H264 and HEVC profile and level control to report them.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
---
v2
-- add support for V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE

 drivers/media/platform/amphion/vdec.c        | 61 +++++++++++++
 drivers/media/platform/amphion/vpu_defs.h    |  1 +
 drivers/media/platform/amphion/vpu_helpers.c | 93 ++++++++++++++++++++
 drivers/media/platform/amphion/vpu_helpers.h |  5 ++
 drivers/media/platform/amphion/vpu_malone.c  |  3 +-
 5 files changed, 162 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
index ca8f7319503a..61d5598ee6a1 100644
--- a/drivers/media/platform/amphion/vdec.c
+++ b/drivers/media/platform/amphion/vdec.c
@@ -232,6 +232,37 @@ static int vdec_ctrl_init(struct vpu_inst *inst)
 			  V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE,
 			  0, 1, 1, 0);
 
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL,
+			       V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+			       V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
+			       ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH)),
+			       V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL,
+			       V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+			       V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
+			       0,
+			       V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL,
+			       V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
+			       V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
+			       ~((1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
+				 (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)),
+			       V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL,
+			       V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+			       V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
+			       0,
+			       V4L2_MPEG_VIDEO_HEVC_LEVEL_4);
+
 	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
 				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
 	if (ctrl)
@@ -1166,6 +1197,35 @@ static void vdec_clear_slots(struct vpu_inst *inst)
 	}
 }
 
+static void vdec_update_v4l2_ctrl(struct vpu_inst *inst, u32 id, u32 val)
+{
+	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id);
+
+	if (ctrl)
+		v4l2_ctrl_s_ctrl(ctrl, val);
+}
+
+static void vdec_update_v4l2_profile_level(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr)
+{
+	switch (inst->out_format.pixfmt) {
+	case V4L2_PIX_FMT_H264:
+	case V4L2_PIX_FMT_H264_MVC:
+		vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+				      vpu_get_h264_v4l2_profile(hdr->profile_idc));
+		vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+				      vpu_get_h264_v4l2_level(hdr->level_idc));
+		break;
+	case V4L2_PIX_FMT_HEVC:
+		vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
+				      vpu_get_hevc_v4l2_profile(hdr->profile_idc));
+		vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+				      vpu_get_hevc_v4l2_level(hdr->level_idc));
+		break;
+	default:
+		return;
+	}
+}
+
 static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr)
 {
 	struct vdec_t *vdec = inst->priv;
@@ -1189,6 +1249,7 @@ static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info
 	vdec_init_crop(inst);
 	vdec_init_mbi(inst);
 	vdec_init_dcp(inst);
+	vdec_update_v4l2_profile_level(inst, hdr);
 	if (!vdec->seq_hdr_found) {
 		vdec->seq_tag = vdec->codec_info.tag;
 		if (vdec->is_source_changed) {
diff --git a/drivers/media/platform/amphion/vpu_defs.h b/drivers/media/platform/amphion/vpu_defs.h
index 428d988cf2f7..606f9d61a265 100644
--- a/drivers/media/platform/amphion/vpu_defs.h
+++ b/drivers/media/platform/amphion/vpu_defs.h
@@ -134,6 +134,7 @@ struct vpu_dec_codec_info {
 	u32 decoded_height;
 	struct v4l2_fract frame_rate;
 	u32 dsp_asp_ratio;
+	u32 profile_idc;
 	u32 level_idc;
 	u32 bit_depth_luma;
 	u32 bit_depth_chroma;
diff --git a/drivers/media/platform/amphion/vpu_helpers.c b/drivers/media/platform/amphion/vpu_helpers.c
index d12310af9ebc..108b75ceb4ae 100644
--- a/drivers/media/platform/amphion/vpu_helpers.c
+++ b/drivers/media/platform/amphion/vpu_helpers.c
@@ -509,3 +509,96 @@ const char *vpu_codec_state_name(enum vpu_codec_state state)
 	}
 	return "<unknown>";
 }
+
+struct codec_id_mapping {
+	u32 id;
+	u32 v4l2_id;
+};
+
+static struct codec_id_mapping h264_profiles[] = {
+	{66,  V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE},
+	{77,  V4L2_MPEG_VIDEO_H264_PROFILE_MAIN},
+	{88,  V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED},
+	{100, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH},
+	{118, V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH},
+	{128, V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH}
+};
+
+static struct codec_id_mapping h264_levels[] = {
+	{10,  V4L2_MPEG_VIDEO_H264_LEVEL_1_0},
+	{9,   V4L2_MPEG_VIDEO_H264_LEVEL_1B},
+	{11,  V4L2_MPEG_VIDEO_H264_LEVEL_1_1},
+	{12,  V4L2_MPEG_VIDEO_H264_LEVEL_1_2},
+	{13,  V4L2_MPEG_VIDEO_H264_LEVEL_1_3},
+	{20,  V4L2_MPEG_VIDEO_H264_LEVEL_2_0},
+	{21,  V4L2_MPEG_VIDEO_H264_LEVEL_2_1},
+	{22,  V4L2_MPEG_VIDEO_H264_LEVEL_2_2},
+	{30,  V4L2_MPEG_VIDEO_H264_LEVEL_3_0},
+	{31,  V4L2_MPEG_VIDEO_H264_LEVEL_3_1},
+	{32,  V4L2_MPEG_VIDEO_H264_LEVEL_3_2},
+	{40,  V4L2_MPEG_VIDEO_H264_LEVEL_4_0},
+	{41,  V4L2_MPEG_VIDEO_H264_LEVEL_4_1},
+	{42,  V4L2_MPEG_VIDEO_H264_LEVEL_4_2},
+	{50,  V4L2_MPEG_VIDEO_H264_LEVEL_5_0},
+	{51,  V4L2_MPEG_VIDEO_H264_LEVEL_5_1},
+	{52,  V4L2_MPEG_VIDEO_H264_LEVEL_5_2},
+	{60,  V4L2_MPEG_VIDEO_H264_LEVEL_6_0},
+	{61,  V4L2_MPEG_VIDEO_H264_LEVEL_6_1},
+	{62,  V4L2_MPEG_VIDEO_H264_LEVEL_6_2}
+};
+
+static struct codec_id_mapping hevc_profiles[] = {
+	{1,   V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN},
+	{2,   V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10}
+};
+
+static struct codec_id_mapping hevc_levels[] = {
+	{30,  V4L2_MPEG_VIDEO_HEVC_LEVEL_1},
+	{60,  V4L2_MPEG_VIDEO_HEVC_LEVEL_2},
+	{63,  V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1},
+	{90,  V4L2_MPEG_VIDEO_HEVC_LEVEL_3},
+	{93,  V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1},
+	{120, V4L2_MPEG_VIDEO_HEVC_LEVEL_4},
+	{123, V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1},
+	{150, V4L2_MPEG_VIDEO_HEVC_LEVEL_5},
+	{153, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1},
+	{156, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2},
+	{180, V4L2_MPEG_VIDEO_HEVC_LEVEL_6},
+	{183, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1},
+	{186, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2}
+};
+
+static u32 vpu_find_v4l2_id(u32 id, struct codec_id_mapping *array, u32 array_sz)
+{
+	u32 i;
+
+	if (!array || !array_sz)
+		return 0;
+
+	for (i = 0; i < array_sz; i++) {
+		if (id == array[i].id)
+			return array[i].v4l2_id;
+	}
+
+	return 0;
+}
+
+u32 vpu_get_h264_v4l2_profile(u32 idc)
+{
+	return vpu_find_v4l2_id(idc, h264_profiles, ARRAY_SIZE(h264_profiles));
+}
+
+u32 vpu_get_h264_v4l2_level(u32 idc)
+{
+	return vpu_find_v4l2_id(idc, h264_levels, ARRAY_SIZE(h264_levels));
+}
+
+u32 vpu_get_hevc_v4l2_profile(u32 idc)
+{
+	return vpu_find_v4l2_id(idc, hevc_profiles, ARRAY_SIZE(hevc_profiles));
+}
+
+u32 vpu_get_hevc_v4l2_level(u32 idc)
+{
+	return vpu_find_v4l2_id(idc, hevc_levels, ARRAY_SIZE(hevc_levels));
+}
diff --git a/drivers/media/platform/amphion/vpu_helpers.h b/drivers/media/platform/amphion/vpu_helpers.h
index 0eaddb07190d..dc5fb1ca2d33 100644
--- a/drivers/media/platform/amphion/vpu_helpers.h
+++ b/drivers/media/platform/amphion/vpu_helpers.h
@@ -70,4 +70,9 @@ int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfu
 
 int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src);
 int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst);
+
+u32 vpu_get_h264_v4l2_profile(u32 idc);
+u32 vpu_get_h264_v4l2_level(u32 idc);
+u32 vpu_get_hevc_v4l2_profile(u32 idc);
+u32 vpu_get_hevc_v4l2_level(u32 idc);
 #endif
diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
index 4769c053c6c2..5c6b2a841b6f 100644
--- a/drivers/media/platform/amphion/vpu_malone.c
+++ b/drivers/media/platform/amphion/vpu_malone.c
@@ -889,7 +889,8 @@ static void vpu_malone_unpack_seq_hdr(struct vpu_rpc_event *pkt,
 	info->frame_rate.numerator = 1000;
 	info->frame_rate.denominator = pkt->data[8];
 	info->dsp_asp_ratio = pkt->data[9];
-	info->level_idc = pkt->data[10];
+	info->profile_idc = (pkt->data[10] >> 8) & 0xff;
+	info->level_idc = pkt->data[10] & 0xff;
 	info->bit_depth_luma = pkt->data[13];
 	info->bit_depth_chroma = pkt->data[14];
 	info->chroma_fmt = pkt->data[15];
-- 
2.43.0-rc1



From ck.hu at mediatek.com  Tue Dec 10 01:32:15 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 10 Dec 2024 09:32:15 +0000
Subject: [PATCH v4 1/1] drm/mediatek: dp: Add sdp path reset
In-Reply-To: <20241128023733.16294-1-liankun.yang@mediatek.com>
References: <20241128023733.16294-1-liankun.yang@mediatek.com>
Message-ID: <9663eb0cc9a4105774547108c30675dc4a8fbb91.camel@mediatek.com>

Hi, Liankun:

On Thu, 2024-11-28 at 10:37 +0800, Liankun Yang wrote:
> When using type-c to type-c to connect to the monitor,
> the sound plays normally. If you unplug the type-c and
> connect the type-c to hdmi dongle to the monitor, there will be noise.
> 
> By capturing the audio data, it is found that
> the data position is messy, and there is no error in the data.
> 
> Through experiments, it can be restored by resetting the SDP path
> when unplugging it.

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

> 
> Signed-off-by: Liankun Yang <liankun.yang at mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
> Changes in V4:
> - Fix align to the right of '('.
> Per suggestion from the previous thread:
> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20240925064854.23065-1-liankun.yang at mediatek.com/__;!!CTRNKA9wMg0ARbw!moBIboZU1a4UlCJ0PNdls-Wyg8zCbx_60VUFdSkCnk5IXzWsiAnF1DpO_4qFz0xvDoTsAKkDVd38PvIu2EFntv4$ 
> 
> Changes in V3:
> - No change.
> Per suggestion from the previous thread:
> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20240923132521.22785-1-liankun.yang at mediatek.com/__;!!CTRNKA9wMg0ARbw!moBIboZU1a4UlCJ0PNdls-Wyg8zCbx_60VUFdSkCnk5IXzWsiAnF1DpO_4qFz0xvDoTsAKkDVd38PvIusbUGckk$ 
> 
> Changes in V2:
> - Fix build error.
> Per suggestion from the previous thread:
> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20240923133610.23728-1-liankun.yang at mediatek.com/__;!!CTRNKA9wMg0ARbw!moBIboZU1a4UlCJ0PNdls-Wyg8zCbx_60VUFdSkCnk5IXzWsiAnF1DpO_4qFz0xvDoTsAKkDVd38PvIutNJ46WI$ 
> ---
>  drivers/gpu/drm/mediatek/mtk_dp.c     | 15 +++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h |  1 +
>  2 files changed, 16 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
> index 1cc916b16471..4f4233bd83f7 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dp.c
> @@ -1135,6 +1135,18 @@ static void mtk_dp_digital_sw_reset(struct mtk_dp *mtk_dp)
>  			   0, DP_TX_TRANSMITTER_4P_RESET_SW_DP_TRANS_P0);
>  }
>  
> +static void mtk_dp_sdp_path_reset(struct mtk_dp *mtk_dp)
> +{
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
> +			   SDP_RESET_SW_DP_ENC0_P0,
> +			   SDP_RESET_SW_DP_ENC0_P0);
> +
> +	/* Wait for sdp path reset to complete */
> +	usleep_range(1000, 5000);
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
> +			   0, SDP_RESET_SW_DP_ENC0_P0);
> +}
> +
>  static void mtk_dp_set_lanes(struct mtk_dp *mtk_dp, int lanes)
>  {
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35F0,
> @@ -2397,6 +2409,9 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
>  			   DP_PWR_STATE_BANDGAP_TPLL,
>  			   DP_PWR_STATE_MASK);
>  
> +	/* SDP path reset sw*/
> +	mtk_dp_sdp_path_reset(mtk_dp);
> +
>  	/* Ensure the sink is muted */
>  	msleep(20);
>  }
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp_reg.h b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> index 709b79480693..8ad7a9cc259e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> @@ -86,6 +86,7 @@
>  #define MTK_DP_ENC0_P0_3004			0x3004
>  #define VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK		BIT(8)
>  #define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0		BIT(9)
> +#define SDP_RESET_SW_DP_ENC0_P0				BIT(13)
>  #define MTK_DP_ENC0_P0_3010			0x3010
>  #define HTOTAL_SW_DP_ENC0_P0_MASK			GENMASK(15, 0)
>  #define MTK_DP_ENC0_P0_3014			0x3014


From mkl at pengutronix.de  Tue Dec 10 01:32:27 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 10 Dec 2024 10:32:27 +0100
Subject: [PATCH stm32-next 1/2] dt-bindings: arm: stm32: add compatible
 strings for Linux Automation GmbH LXA FairyTux 2
In-Reply-To: <20241210-lxa-fairytux-v1-0-9aea01cdb83e@pengutronix.de>
References: <20241210-lxa-fairytux-v1-0-9aea01cdb83e@pengutronix.de>
Message-ID: <20241210-lxa-fairytux-v1-1-9aea01cdb83e@pengutronix.de>

From: Leonard G?hrs <l.goehrs at pengutronix.de>

The Linux Automation GmbH FairyTux2 is a small Linux device based on
an Octavo Systems OSD32MP153c SiP, that occupies just two slots on a
DIN rail.

Add compatible for the generation 1 and 2 based on the STM32MP153c.

Signed-off-by: Leonard G?hrs <l.goehrs at pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 Documentation/devicetree/bindings/arm/stm32/stm32.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/stm32/stm32.yaml b/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
index b6c56d4ce6b9515565fc05348896ba9f400643f0..6825d965da3daf2b508fbd88e8c9d40e20ba1f59 100644
--- a/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
+++ b/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
@@ -94,6 +94,8 @@ properties:
       - description: Octavo OSD32MP153 System-in-Package based boards
         items:
           - enum:
+              - lxa,stm32mp153c-fairytux2-gen1 # Linux Automation FairyTux 2 (Generation 1)
+              - lxa,stm32mp153c-fairytux2-gen2 # Linux Automation FairyTux 2 (Generation 2)
               - lxa,stm32mp153c-tac-gen3 # Linux Automation TAC (Generation 3)
           - const: oct,stm32mp153x-osd32
           - const: st,stm32mp153

-- 
2.45.2




From mkl at pengutronix.de  Tue Dec 10 01:32:28 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 10 Dec 2024 10:32:28 +0100
Subject: [PATCH stm32-next 2/2] ARM: dts: stm32: lxa-fairytux2: add Linux
 Automation GmbH FairyTux 2
In-Reply-To: <20241210-lxa-fairytux-v1-0-9aea01cdb83e@pengutronix.de>
References: <20241210-lxa-fairytux-v1-0-9aea01cdb83e@pengutronix.de>
Message-ID: <20241210-lxa-fairytux-v1-2-9aea01cdb83e@pengutronix.de>

From: Leonard G?hrs <l.goehrs at pengutronix.de>

The Linux Automation GmbH FairyTux2 is a small Linux device based on
an Octavo Systems OSD32MP153c SiP, that occupies just two slots on a
DIN rail.

The device contains an eMMC for storage, a gigabit Ethernet
connection, a CAN bus and a RS485 transceiver.

Add support for the lxa-fairytux2 generation 1 and 2 boards based on
the STM32MP153c.

Signed-off-by: Leonard G?hrs <l.goehrs at pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 arch/arm/boot/dts/st/Makefile                      |   2 +
 .../boot/dts/st/stm32mp153c-lxa-fairytux2-gen1.dts | 101 ++++++
 .../boot/dts/st/stm32mp153c-lxa-fairytux2-gen2.dts | 146 ++++++++
 .../arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi | 394 +++++++++++++++++++++
 4 files changed, 643 insertions(+)

diff --git a/arch/arm/boot/dts/st/Makefile b/arch/arm/boot/dts/st/Makefile
index b7d5d305cbbeb78cfae9fab05271992959f6fa56..f68da19d7cbf33fc5424e4900d301b2706d03e5e 100644
--- a/arch/arm/boot/dts/st/Makefile
+++ b/arch/arm/boot/dts/st/Makefile
@@ -39,6 +39,8 @@ dtb-$(CONFIG_ARCH_STM32) += \
 	stm32mp151c-mect1s.dtb \
 	stm32mp153c-dhcom-drc02.dtb \
 	stm32mp153c-dhcor-drc-compact.dtb \
+	stm32mp153c-lxa-fairytux2-gen1.dtb \
+	stm32mp153c-lxa-fairytux2-gen2.dtb \
 	stm32mp153c-lxa-tac-gen3.dtb \
 	stm32mp153c-mecio1r1.dtb \
 	stm32mp157a-avenger96.dtb \
diff --git a/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2-gen1.dts b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2-gen1.dts
new file mode 100644
index 0000000000000000000000000000000000000000..a70de0f47afb21f36bf4c74a928910b10adc762f
--- /dev/null
+++ b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2-gen1.dts
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
+/*
+ * Copyright (C) 2024 Leonard G?hrs, Pengutronix
+ */
+
+/dts-v1/;
+
+#include "stm32mp153c-lxa-fairytux2.dtsi"
+
+/ {
+	model = "Linux Automation GmbH FairyTux 2 Gen 1";
+	compatible = "lxa,stm32mp153c-fairytux2-gen1", "oct,stm32mp153x-osd32", "st,stm32mp153";
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		button-left {
+			label = "USER_BTN1";
+			linux,code = <KEY_ESC>;
+			gpios = <&gpioi 11 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+		};
+
+		button-right {
+			label = "USER_BTN2";
+			linux,code = <KEY_HOME>;
+			gpios = <&gpioe 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+		};
+	};
+};
+
+&gpiof {
+	gpio-line-names = "GPIO1", "GPIO2", "", "", "", /*  0 */
+	"", "", "", "", "",                             /*  5 */
+	"", "", "", "", "",                             /* 10 */
+	"";                                             /* 15 */
+};
+
+&gpioh {
+	gpio-line-names = "", "", "", "", "LCD_RESET", /*  0 */
+	"", "", "", "", "",                            /*  5 */
+	"", "", "", "GPIO3", "",                       /* 10 */
+	"";                                            /* 15 */
+};
+
+&gpioi {
+	gpio-line-names = "", "", "", "", "", /*  0 */
+	"", "", "", "ETH_", "",               /*  5 */
+	"", "USER_BTN1";                      /* 10 */
+};
+
+&i2c1 {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&i2c1_pins_b>;
+	pinctrl-1 = <&i2c1_sleep_pins_b>;
+	status = "okay";
+
+	io_board_gpio: tca6408 at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		vcc-supply = <&v3v3_hdmi>;
+		gpio-line-names = "LED1_GA_YK", "LED2_GA_YK", "LED1_GK_YA", "LED2_GK_YA",
+		"RS485_EN", "RS485_120R", "", "CAN_120R";
+	};
+};
+
+&led_controller_io {
+	/*
+	 * led-2 and led-3 are internally connected antiparallel to one
+	 * another inside the ethernet jack like this:
+	 * GPIO1 ---+---|led-2|>--+--- GPIO3
+	 *          +--<|led-3|---+
+	 * E.g. only one of the LEDs can be illuminated at a time while
+	 * the other output must be driven low.
+	 * This should likely be implemented using a multi color LED
+	 * driver for antiparallel LEDs.
+	 */
+	led-2 {
+		label = "fairytux2:green:act";
+		gpios = <&io_board_gpio 1 GPIO_ACTIVE_HIGH>;
+	};
+
+	led-3 {
+		label = "fairytux2:orange:act";
+		gpios = <&io_board_gpio 3 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&usart3 {
+	/*
+	 * On Gen 1 FairyTux 2 only RTS can be used and not CTS as well,
+	 * Because pins PD11 (CTS) and PI11 (USER_BTN1) share the same
+	 * interrupt and only one of them can be used at a time.
+	 */
+	rts-gpios = <&gpiod 12 GPIO_ACTIVE_LOW>;
+};
+
+&usbotg_hs {
+	dr_mode = "peripheral";
+};
diff --git a/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2-gen2.dts b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2-gen2.dts
new file mode 100644
index 0000000000000000000000000000000000000000..c84f83a75731f70165c240812f7f4230bf9bfbb0
--- /dev/null
+++ b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2-gen2.dts
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
+/*
+ * Copyright (C) 2024 Leonard G?hrs, Pengutronix
+ */
+
+/dts-v1/;
+
+#include "stm32mp153c-lxa-fairytux2.dtsi"
+
+/ {
+	model = "Linux Automation GmbH FairyTux 2 Gen 2";
+	compatible = "lxa,stm32mp153c-fairytux2-gen2", "oct,stm32mp153x-osd32", "st,stm32mp153";
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		button-left {
+			label = "USER_BTN1";
+			linux,code = <KEY_ESC>;
+			gpios = <&gpioi 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+		};
+
+		button-right {
+			label = "USER_BTN2";
+			linux,code = <KEY_HOME>;
+			gpios = <&gpioe 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+		};
+	};
+};
+
+&gpiof {
+	gpio-line-names = "", "", "", "", "", /*  0 */
+	"", "", "", "", "",                   /*  5 */
+	"", "", "", "", "",                   /* 10 */
+	"";                                   /* 15 */
+};
+
+&gpioh {
+	gpio-line-names = "", "", "", "", "LCD_RESET", /*  0 */
+	"", "", "", "", "",                            /*  5 */
+	"", "", "GPIO1", "GPIO_INT", "",               /* 10 */
+	"";                                            /* 15 */
+};
+
+&gpioi {
+	gpio-line-names = "GPIO2", "", "", "", "", /*  0 */
+	"", "", "", "ETH_", "",                    /*  5 */
+	"", "USER_BTN1";                           /* 10 */
+};
+
+&i2c1 {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&i2c1_pins_b>;
+	pinctrl-1 = <&i2c1_sleep_pins_b>;
+	status = "okay";
+
+	io_board_gpio: tca6408 at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&gpioh>;
+		interrupts = <13 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+		pinctrl-names = "default";
+		pinctrl-0 = <&board_tca6408_pins>;
+		#interrupt-cells = <2>;
+		vcc-supply = <&v3v3_hdmi>;
+		gpio-line-names = "LED1_GA_YK", "LED2_GA_YK", "LED1_GK_YA", "USB_CC_ALERT",
+		"RS485_EN", "RS485_120R", "USB_CC_RESET", "CAN_120R";
+	};
+
+	usb_c: stusb1600 at 28 {
+		compatible = "st,stusb1600";
+		reg = <0x28>;
+		interrupt-parent = <&io_board_gpio>;
+		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+		vdd-supply = <&reg_5v>;
+		vsys-supply = <&v3v3_hdmi>;
+
+		connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			power-role = "dual";
+			typec-power-opmode = "default";
+
+			port {
+				con_usbotg_hs_ep: endpoint {
+					remote-endpoint = <&usbotg_hs_ep>;
+				};
+			};
+		};
+	};
+
+	io_board_eeprom: eeprom at 56 {
+		compatible = "atmel,24c04";
+		reg = <0x56>;
+		vcc-supply = <&v3v3_hdmi>;
+	};
+
+	temperature-sensor at 48 {
+		compatible = "national,lm75a";
+		reg = <0x48>;
+		/*
+		 * The sensor itself is powered by a voltage divider from the
+		 * always-on 5V supply.
+		 * The required pull-up resistors however are on v3v3_hdmi.
+		 */
+		vs-supply = <&v3v3_hdmi>;
+	};
+};
+
+&rtc {
+	status = "okay";
+};
+
+&led_controller_io {
+	led-2 {
+		label = "fairytux2:orange:act";
+		gpios = <&io_board_gpio 1 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&usart3 {
+	rts-gpios = <&gpiod 12 GPIO_ACTIVE_LOW>;
+	cts-gpios = <&gpiod 11 GPIO_ACTIVE_LOW>;
+};
+
+&usbotg_hs {
+	usb-role-switch;
+
+	port {
+		usbotg_hs_ep: endpoint {
+			remote-endpoint = <&con_usbotg_hs_ep>;
+		};
+	};
+};
+
+&pinctrl {
+	board_tca6408_pins: stusb1600-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 13, GPIO)>;
+			bias-pull-up;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..0e0e1b36cb087dfbfb47e383094c6044786a2c6a
--- /dev/null
+++ b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi
@@ -0,0 +1,394 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
+/*
+ * Copyright (C) 2020 STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2021 Rouven Czerwinski, Pengutronix
+ * Copyright (C) 2023, 2024 Leonard G?hrs, Pengutronix
+ */
+
+#include "stm32mp153.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15xx-osd32.dtsi"
+#include "stm32mp15xxac-pinctrl.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+	aliases {
+		can0 = &m_can1;
+		ethernet0 = &ethernet0;
+		i2c0 = &i2c1;
+		i2c1 = &i2c4;
+		mmc1 = &sdmmc2;
+		serial0 = &uart4;
+		serial1 = &usart3;
+		spi0 = &spi4;
+	};
+
+	chosen {
+		stdout-path = &uart4;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		power-supply = <&v3v3>;
+
+		brightness-levels = <0 31 63 95 127 159 191 223 255>;
+		default-brightness-level = <7>;
+		pwms = <&led_pwm 3 1000000 0>;
+	};
+
+	led-controller-cpu {
+		compatible = "gpio-leds";
+
+		led-0 {
+			label = "fairytux2:green:status";
+			gpios = <&gpioa 13 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	led_controller_io: led-controller-io {
+		compatible = "gpio-leds";
+
+		/*
+		 * led-0 and led-1 are internally connected antiparallel to one
+		 * another inside the ethernet jack like this:
+		 * GPIO0 ---+---|led-0|>--+--- GPIO2
+		 *          +--<|led-1|---+
+		 * E.g. only one of the LEDs can be illuminated at a time while
+		 * the other output must be driven low.
+		 * This should likely be implemented using a multi color LED
+		 * driver for antiparallel LEDs.
+		 */
+		led-0 {
+			label = "fairytux2:green:link";
+			gpios = <&io_board_gpio 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		led-1 {
+			label = "fairytux2:orange:link";
+			gpios = <&io_board_gpio 2 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	reg_5v: regulator-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	reg_1v2: regulator-1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "1V2";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-always-on;
+		vin-supply = <&reg_5v>;
+	};
+};
+
+baseboard_eeprom: &sip_eeprom {
+};
+
+&crc1 {
+	status = "okay";
+};
+
+&cryp1 {
+	status = "okay";
+};
+
+&dts {
+	status = "okay";
+};
+
+&ethernet0 {
+	assigned-clocks = <&rcc ETHCK_K>, <&rcc PLL4_P>;
+	assigned-clock-parents = <&rcc PLL4_P>;
+	assigned-clock-rates = <125000000>; /* Clock PLL4 to 750Mhz in ATF */
+
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&ethernet0_rgmii_pins_b>;
+	pinctrl-1 = <&ethernet0_rgmii_sleep_pins_b>;
+
+	st,eth-clk-sel;
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethphy>;
+	status = "okay";
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy: ethernet-phy at 3 { /* KSZ9031RN */
+			reg = <3>;
+			reset-gpios = <&gpioe 11 GPIO_ACTIVE_LOW>; /* ETH_RST# */
+			interrupt-parent = <&gpioa>;
+			interrupts = <6 IRQ_TYPE_EDGE_FALLING>; /* ETH_MDINT# */
+			reset-assert-us = <10000>;
+			reset-deassert-us = <300>;
+			micrel,force-master;
+		};
+	};
+};
+
+&gpioa {
+	gpio-line-names = "", "", "", "", "", /*  0 */
+	"", "ETH_INT", "", "", "",            /*  5 */
+	"", "", "", "BOOTROM_LED", "",        /* 10 */
+	"";                                   /* 15 */
+};
+
+&gpiob {
+	gpio-line-names = "", "", "", "", "", /*  0 */
+	"", "", "", "", "",                   /*  5 */
+	"", "", "", "", "",                   /* 10 */
+	"";                                   /* 15 */
+};
+
+&gpioc {
+	gpio-line-names = "", "", "", "", "", /*  0 */
+	"", "", "", "", "",                   /*  5 */
+	"", "";                               /* 10 */
+};
+
+&gpiod {
+	gpio-line-names = "", "", "", "", "", /*  0 */
+	"", "", "LCD_TE", "", "",             /*  5 */
+	"LCD_DC", "", "", "", "",             /* 10 */
+	"";                                   /* 15 */
+};
+
+&gpioe {
+	gpio-line-names = "LCD_CS", "", "", "", "", /*  0 */
+	"", "", "", "", "",                         /*  5 */
+	"", "", "", "", "",                         /* 10 */
+	"";                                         /* 15 */
+};
+
+&gpiof {
+	gpio-line-names = "GPIO1", "GPIO2", "", "", "", /*  0 */
+	"", "", "", "", "",                             /*  5 */
+	"", "", "", "", "",                             /* 10 */
+	"";                                             /* 15 */
+};
+
+&gpiog {
+	gpio-line-names = "", "", "", "", "", /*  0 */
+	"", "", "", "", "",                   /*  5 */
+	"", "", "", "", "",                   /* 10 */
+	"";                                   /* 15 */
+};
+
+&gpioz {
+	gpio-line-names = "HWID0", "HWID1", "HWID2", "HWID3", "", /*  0 */
+	"", "HWID4", "HWID5";                                     /*  5 */
+};
+
+&hash1 {
+	status = "okay";
+};
+
+&iwdg2 {
+	timeout-sec = <8>;
+	status = "okay";
+};
+
+&m_can1 {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&m_can1_pins_b>;
+	pinctrl-1 = <&m_can1_sleep_pins_b>;
+	status = "okay";
+	termination-gpios = <&io_board_gpio 7 GPIO_ACTIVE_HIGH>;
+	termination-ohms = <120>;
+};
+
+&pmic {
+	regulators {
+		buck1-supply = <&reg_5v>;	/* VIN */
+		buck2-supply = <&reg_5v>;	/* VIN */
+		buck3-supply = <&reg_5v>;	/* VIN */
+		buck4-supply = <&reg_5v>;	/* VIN */
+		ldo2-supply = <&reg_5v>;	/* PMIC_LDO25IN */
+		ldo4-supply = <&reg_5v>;	/* VIN */
+		ldo5-supply = <&reg_5v>;	/* PMIC_LDO25IN */
+		vref_ddr-supply = <&reg_5v>;	/* VIN */
+		boost-supply = <&reg_5v>;	/* PMIC_BSTIN */
+		pwr_sw2-supply = <&bst_out>;	/* PMIC_SWIN */
+	};
+};
+
+&pwr_regulators {
+	vdd-supply = <&vdd>;
+	vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&sdmmc2 {
+	pinctrl-names = "default", "opendrain", "sleep";
+	pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_b>;
+	pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_b>;
+	pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_b>;
+	vmmc-supply = <&v3v3>;
+
+	bus-width = <8>;
+	mmc-ddr-3_3v;
+	no-1-8-v;
+	non-removable;
+	no-sd;
+	no-sdio;
+	st,neg-edge;
+
+	status = "okay";
+};
+
+&spi4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi4_pins_a>;
+	cs-gpios = <&gpioe 0 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	lcd: display at 0 {
+		compatible = "shineworld,lh133k", "panel-mipi-dbi-spi";
+		reg = <0>;
+		power-supply = <&v3v3>;
+		io-supply = <&v3v3>;
+		backlight = <&backlight>;
+		dc-gpios = <&gpiod 10 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpioh 4 GPIO_ACTIVE_HIGH>;
+		spi-3wire;
+		spi-max-frequency = <32000000>;
+
+		width-mm = <23>;
+		height-mm = <23>;
+		rotation = <180>;
+
+		panel-timing {
+			hactive = <240>;
+			vactive = <240>;
+			hback-porch = <0>;
+			vback-porch = <0>;
+
+			clock-frequency = <0>;
+			hfront-porch = <0>;
+			hsync-len = <0>;
+			vfront-porch = <0>;
+			vsync-len = <0>;
+		};
+	};
+};
+
+&timers2 {
+	/* spare dmas for other usage */
+	/delete-property/dmas;
+	/delete-property/dma-names;
+
+	status = "okay";
+
+	timer at 1 {
+		status = "okay";
+	};
+};
+
+&timers3 {
+	/* spare dmas for other usage */
+	/delete-property/dmas;
+	/delete-property/dma-names;
+
+	status = "okay";
+
+	timer at 2 {
+		status = "okay";
+	};
+};
+
+&timers4 {
+	/* spare dmas for other usage */
+	/delete-property/dmas;
+	/delete-property/dma-names;
+
+	status = "okay";
+
+	timer at 3 {
+		status = "okay";
+	};
+};
+
+&timers8 {
+	/* spare dmas for other usage */
+	/delete-property/dmas;
+	/delete-property/dma-names;
+
+	status = "okay";
+
+	led_pwm: pwm {
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&pwm8_pins_b>;
+		pinctrl-1 = <&pwm8_sleep_pins_b>;
+		status = "okay";
+	};
+};
+
+&uart4 {
+	label = "debug";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins_a>;
+
+	/* spare dmas for other usage */
+	/delete-property/dmas;
+	/delete-property/dma-names;
+
+	status = "okay";
+};
+
+&usart3 {
+	label = "external";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&usart3_pins_a>;
+
+	/* spare dmas for other usage */
+	/delete-property/dmas;
+	/delete-property/dma-names;
+
+	status = "okay";
+};
+
+&usbh_ehci {
+	phys = <&usbphyc_port0>;
+	phy-names = "usb";
+
+	status = "okay";
+};
+
+&usbotg_hs {
+	phys = <&usbphyc_port1 0>;
+	phy-names = "usb2-phy";
+
+	vusb_d-supply = <&vdd_usb>;
+	vusb_a-supply = <&reg18>;
+
+	status = "okay";
+};
+
+&usbphyc {
+	status = "okay";
+};
+
+&usbphyc_port0 {
+	phy-supply = <&vdd_usb>;
+};
+
+&usbphyc_port1 {
+	phy-supply = <&vdd_usb>;
+};
+
+&v3v3_hdmi {
+	regulator-enable-ramp-delay = <1000>;
+};

-- 
2.45.2




From mkl at pengutronix.de  Tue Dec 10 01:32:26 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 10 Dec 2024 10:32:26 +0100
Subject: [PATCH stm32-next 0/2] ARM: dts: stm32: lxa-fairytux2: add
 gen{1,2} boards
Message-ID: <20241210-lxa-fairytux-v1-0-9aea01cdb83e@pengutronix.de>

Hello,

this series adds support for the Linux Automation GmbH FairyTux2
boards generation 1 and 2.

The FairyTux2 is a small Linux device based on an Octavo Systems
OSD32MP153c SiP, that occupies just two slots on a DIN rail.

regards,
Marc

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
Leonard G?hrs (2):
      dt-bindings: arm: stm32: add compatible strings for Linux Automation GmbH LXA FairyTux 2
      ARM: dts: stm32: lxa-fairytux2: add Linux Automation GmbH FairyTux 2

 .../devicetree/bindings/arm/stm32/stm32.yaml       |   2 +
 arch/arm/boot/dts/st/Makefile                      |   2 +
 .../boot/dts/st/stm32mp153c-lxa-fairytux2-gen1.dts | 101 ++++++
 .../boot/dts/st/stm32mp153c-lxa-fairytux2-gen2.dts | 146 ++++++++
 .../arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi | 394 +++++++++++++++++++++
 5 files changed, 645 insertions(+)
---
base-commit: 08d312c944095df2b73e9959c2bb16073820ecdd
change-id: 20241210-lxa-fairytux-e730979d3d3f

Best regards,
-- 
Marc Kleine-Budde <mkl at pengutronix.de>




From luis.machado at arm.com  Tue Dec 10 01:35:51 2024
From: luis.machado at arm.com (Luis Machado)
Date: Tue, 10 Dec 2024 09:35:51 +0000
Subject: [PATCH v2 5/6] arm64/sme: Reenable SME
In-Reply-To: <20241204-arm64-sme-reenable-v2-5-bae87728251d@kernel.org>
References: <20241204-arm64-sme-reenable-v2-0-bae87728251d@kernel.org>
 <20241204-arm64-sme-reenable-v2-5-bae87728251d@kernel.org>
Message-ID: <7e62661d-03bb-43c9-b15a-fda0a379497a@arm.com>

On 12/4/24 15:20, Mark Brown wrote:
> Now that fixes for all the known issues with SME have been applied
> remove the BROKEN dependency from it so it's generally available again.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/Kconfig | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 100570a048c5e8892c0112704f9ca74c4fc55b27..7e3182dd6fa0dadd961c352f88484cff0e520eaa 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -2270,7 +2270,6 @@ config ARM64_SME
>  	bool "ARM Scalable Matrix Extension support"
>  	default y
>  	depends on ARM64_SVE
> -	depends on BROKEN
>  	help
>  	  The Scalable Matrix Extension (SME) is an extension to the AArch64
>  	  execution state which utilises a substantial subset of the SVE
> 

FYI, I gave this series a try with the emulator and GDB's SME/SVE testsuite and
it still looks good from userspace's perspective.

Tested-By: Luis Machado <luis.machado at arm.com>


From smostafa at google.com  Tue Dec 10 01:40:00 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 10 Dec 2024 09:40:00 +0000
Subject: [PATCH v2 1/2] iommu/io-pgtable-arm: Fix stage-2 concatenation
 with 16K
In-Reply-To: <20241209235804.GA14069@willie-the-truck>
References: <20241202140604.422235-1-smostafa@google.com> <20241202140604.422235-2-smostafa@google.com>
 <20241209235804.GA14069@willie-the-truck>
Message-ID: <CAFgf54peN1fGOpr4Q4eihRTYFi1prT3LaQvH-K5x5KO50gmacw@mail.gmail.com>

On Mon, Dec 9, 2024 at 11:58?PM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Dec 02, 2024 at 02:06:03PM +0000, Mostafa Saleh wrote:
> > At the moment, io-pgtable-arm uses concatenation only if it is
> > possible at level 0, which misses a case where concatenation is
> > mandatory at level 1 according to R_SRKBC in Arm spec DDI0487 K.a.
> >
> > Also, that means concatenation can be used when not mandated,
> > contradicting the comment on the code. However, these cases can only
> > happen if the SMMUv3 driver is changed to use ias != oas for stage-2.
> >
> > This patch re-writes the code to use concatenation only if mandatory,
> > fixing the missing case for level-1 and granule 16K with PA = 40 bits.
> >
> > Signed-off-by: Mostafa Saleh <smostafa at google.com>
> > ---
> >  drivers/iommu/io-pgtable-arm.c | 45 +++++++++++++++++++++++++---------
> >  1 file changed, 33 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> > index 6b9bb58a414f..0055876b3527 100644
> > --- a/drivers/iommu/io-pgtable-arm.c
> > +++ b/drivers/iommu/io-pgtable-arm.c
> > @@ -223,6 +223,33 @@ static inline int arm_lpae_max_entries(int i, struct arm_lpae_io_pgtable *data)
> >       return ptes_per_table - (i & (ptes_per_table - 1));
> >  }
> >
> > +/*
> > + * Check if concatenated PGDs are mandatory according to Arm DDI0487 (K.a)
> > + * 1) R_DXBSH: For 16KB, and 48-bit input size, use level 1 instead of 0.
> > + * 2) R_SRKBC: After de-ciphering the table for PA size and valid initial lookup
> > + *   a) 40 bits PA size with 4K: use level 1 instead of level 0 (2 tables for ias = oas)
> > + *   b) 40 bits PA size with 16K: use level 2 instead of level 1 (16 tables for ias = oas)
> > + *   c) 42 bits PA size with 4K: use level 1 instead of level 0 (8 tables for ias = oas)
> > + *   d) 48 bits PA size with 16K: use level 1 instead of level 0 (2 tables for ias = oas)
> > + */
> > +static inline bool arm_lpae_concat_mandatory(struct arm_lpae_io_pgtable *data)
> > +{
> > +     unsigned int ias = data->iop.cfg.ias;
> > +     unsigned int oas = data->iop.cfg.oas;
> > +
> > +     /* Covers 1  and 2.d */
> > +     if ((ARM_LPAE_GRANULE(data) == SZ_16K) && (data->start_level == 0))
> > +             return (oas == 48) || (ias = 48);
>
> I'm guessing the second disjunct here should be:
>
>         (ias == 48);
>

Ouch, my bad.

> I'll make that change when applying...
>
> Will


From dsimic at manjaro.org  Tue Dec 10 01:44:40 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 10 Dec 2024 10:44:40 +0100
Subject: [PATCH 2/6] clk: rockchip: fix wrong clk_ref_usb3otg parent for
 rk3328
In-Reply-To: <20241210013010.81257-3-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-3-pgwipeout@gmail.com>
Message-ID: <0d11705121f29ccfb7cfa342505a6e35@manjaro.org>

Hello Peter,

On 2024-12-10 02:30, Peter Geis wrote:
> Correct the clk_ref_usb3otg parent to fix clock control for the usb3
> controller on rk3328. Verified against the rk3328 trm and usb3 clock 
> tree
> documentation.
> 
> Fixes: fe3511ad8a1c ("clk: rockchip: add clock controller for rk3328")
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
> 
>  drivers/clk/rockchip/clk-rk3328.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3328.c
> b/drivers/clk/rockchip/clk-rk3328.c
> index 3bb87b27b662..cf60fcf2fa5c 100644
> --- a/drivers/clk/rockchip/clk-rk3328.c
> +++ b/drivers/clk/rockchip/clk-rk3328.c
> @@ -201,7 +201,7 @@ PNAME(mux_aclk_peri_pre_p)	= { "cpll_peri",
>  				    "gpll_peri",
>  				    "hdmiphy_peri" };
>  PNAME(mux_ref_usb3otg_src_p)	= { "xin24m",
> -				    "clk_usb3otg_ref" };
> +				    "clk_ref_usb3otg_src" };
>  PNAME(mux_xin24m_32k_p)		= { "xin24m",
>  				    "clk_rtc32k" };
>  PNAME(mux_mac2io_src_p)		= { "clk_mac2io_src",

Sorry, but I was unable to verify this in the part 1 of the
RK3328 TRM, in both versions 1.1 and 1.2, which is all I have
when it comes to the RK3328 TRM.  Is that maybe described in
the part 2, which I've been unable to locate for years?

Moreover, the downstream kernel source from Rockchip does it
the way [1] it's currently done in the mainline kernel, which
makes me confused a bit?  Could you, please, provide more
details about the two references you mentioned in the patch
description, or maybe even you could provide the links to
those two references?

[1] 
https://raw.githubusercontent.com/rockchip-linux/kernel/refs/heads/develop-4.4/drivers/clk/rockchip/clk-rk3328.c


From ericwouds at gmail.com  Tue Dec 10 01:44:59 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:59 +0100
Subject: [PATCH RFC v3 net-next 11/13] bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-12-ericwouds@gmail.com>

In network setup as below:

             fastpath bypass
 .----------------------------------------.
/                                          \
|                        IP - forwarding    |
|                       /                \  v
|                      /                  wan ...
|                     /
|                     |
|                     |
|                   brlan.1
|                     |
|    +-------------------------------+
|    |           vlan 1              |
|    |                               |
|    |     brlan (vlan-filtering)    |
|    |               +---------------+
|    |               |  DSA-SWITCH   |
|    |    vlan 1     |               |
|    |      to       |               |
|    |   untagged    1     vlan 1    |
|    +---------------+---------------+
.         /                   \
 ----->wlan1                 lan0
       .                       .
       .                       ^
       ^                     vlan 1 tagged packets
     untagged packets

br_vlan_fill_forward_path_mode() sets DEV_PATH_BR_VLAN_UNTAG_HW when
filling in from brlan.1 towards wlan1. But it should be set to
DEV_PATH_BR_VLAN_UNTAG in this case. Using BR_VLFLAG_ADDED_BY_SWITCHDEV
is not correct. The dsa switchdev adds it as a foreign port.

The same problem for all foreignly added dsa vlans on the bridge.

First add the vlan, trying only native devices.
If this fails, we know this may be a vlan from a foreign device.

Use BR_VLFLAG_TAGGING_BY_SWITCHDEV to make sure DEV_PATH_BR_VLAN_UNTAG_HW
is set only when there if no foreign device involved.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 include/net/switchdev.h   |  1 +
 net/bridge/br_private.h   |  3 +++
 net/bridge/br_switchdev.c | 15 +++++++++++++++
 net/bridge/br_vlan.c      |  7 ++++++-
 net/switchdev/switchdev.c |  2 +-
 5 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 8346b0d29542..ee500706496b 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -15,6 +15,7 @@
 #define SWITCHDEV_F_NO_RECURSE		BIT(0)
 #define SWITCHDEV_F_SKIP_EOPNOTSUPP	BIT(1)
 #define SWITCHDEV_F_DEFER		BIT(2)
+#define SWITCHDEV_F_NO_FOREIGN		BIT(3)
 
 enum switchdev_attr_id {
 	SWITCHDEV_ATTR_ID_UNDEFINED,
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 046d7b04771f..977285925422 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -180,6 +180,7 @@ enum {
 	BR_VLFLAG_MCAST_ENABLED = BIT(2),
 	BR_VLFLAG_GLOBAL_MCAST_ENABLED = BIT(3),
 	BR_VLFLAG_NEIGH_SUPPRESS_ENABLED = BIT(4),
+	BR_VLFLAG_TAGGING_BY_SWITCHDEV = BIT(5),
 };
 
 /**
@@ -2175,6 +2176,8 @@ void br_switchdev_mdb_notify(struct net_device *dev,
 			     int type);
 int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
 			       bool changed, struct netlink_ext_ack *extack);
+int br_switchdev_port_vlan_no_foreign_add(struct net_device *dev, u16 vid, u16 flags,
+					  bool changed, struct netlink_ext_ack *extack);
 int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid);
 void br_switchdev_init(struct net_bridge *br);
 
diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index 7b41ee8740cb..efa7a055b8f9 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -187,6 +187,21 @@ int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
 	return switchdev_port_obj_add(dev, &v.obj, extack);
 }
 
+int br_switchdev_port_vlan_no_foreign_add(struct net_device *dev, u16 vid, u16 flags,
+					  bool changed, struct netlink_ext_ack *extack)
+{
+	struct switchdev_obj_port_vlan v = {
+		.obj.orig_dev = dev,
+		.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
+		.obj.flags = SWITCHDEV_F_NO_FOREIGN,
+		.flags = flags,
+		.vid = vid,
+		.changed = changed,
+	};
+
+	return switchdev_port_obj_add(dev, &v.obj, extack);
+}
+
 int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)
 {
 	struct switchdev_obj_port_vlan v = {
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 2ea1e2ff4676..0decce5d586a 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -109,6 +109,11 @@ static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br,
 	/* Try switchdev op first. In case it is not supported, fallback to
 	 * 8021q add.
 	 */
+	err = br_switchdev_port_vlan_no_foreign_add(dev, v->vid, flags, false, extack);
+	if (err != -EOPNOTSUPP) {
+		v->priv_flags |= BR_VLFLAG_ADDED_BY_SWITCHDEV | BR_VLFLAG_TAGGING_BY_SWITCHDEV;
+		return err;
+	}
 	err = br_switchdev_port_vlan_add(dev, v->vid, flags, false, extack);
 	if (err == -EOPNOTSUPP)
 		return vlan_vid_add(dev, br->vlan_proto, v->vid);
@@ -1491,7 +1496,7 @@ int br_vlan_fill_forward_path_mode(struct net_bridge *br,
 
 	if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
 		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
-	else if (v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
+	else if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
 		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
 	else
 		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 6488ead9e464..c48f66643e99 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -749,7 +749,7 @@ static int __switchdev_handle_port_obj_add(struct net_device *dev,
 	/* Event is neither on a bridge nor a LAG. Check whether it is on an
 	 * interface that is in a bridge with us.
 	 */
-	if (!foreign_dev_check_cb)
+	if (!foreign_dev_check_cb || port_obj_info->obj->flags & SWITCHDEV_F_NO_FOREIGN)
 		return err;
 
 	br = netdev_master_upper_dev_get(dev);
-- 
2.47.1



From manikanta.guntupalli at amd.com  Tue Dec 10 01:52:40 2024
From: manikanta.guntupalli at amd.com (Manikanta Guntupalli)
Date: Tue, 10 Dec 2024 15:22:40 +0530
Subject: [PATCH V2 0/2] Add atomic transfer support to i2c-xiic
Message-ID: <20241210095242.1982770-1-manikanta.guntupalli@amd.com>

This patch series adds atomic transfer support to the i2c-xiic
controller.
---
Changes for V2:
Remove NULL checks for tx_msg and rx_msg, as __xiic_start_xfer() already
has checks.

Manikanta Guntupalli (2):
  i2c: xiic: Relocate xiic_i2c_runtime_suspend and
    xiic_i2c_runtime_resume to facilitate atomic mode
  i2c: xiic: Add atomic transfer support

 drivers/i2c/busses/i2c-xiic.c | 281 +++++++++++++++++++++++++++-------
 1 file changed, 227 insertions(+), 54 deletions(-)

-- 
2.25.1



From manikanta.guntupalli at amd.com  Tue Dec 10 01:52:41 2024
From: manikanta.guntupalli at amd.com (Manikanta Guntupalli)
Date: Tue, 10 Dec 2024 15:22:41 +0530
Subject: [PATCH V2 1/2] i2c: xiic: Relocate xiic_i2c_runtime_suspend and xiic_i2c_runtime_resume to facilitate atomic mode
In-Reply-To: <20241210095242.1982770-1-manikanta.guntupalli@amd.com>
References: <20241210095242.1982770-1-manikanta.guntupalli@amd.com>
Message-ID: <20241210095242.1982770-2-manikanta.guntupalli@amd.com>

Relocate xiic_i2c_runtime_suspend and xiic_i2c_runtime_resume functions
to avoid prototype statements in atomic mode changes.

Signed-off-by: Manikanta Guntupalli <manikanta.guntupalli at amd.com>
---
Changes for V2:
None.
---
 drivers/i2c/busses/i2c-xiic.c | 46 +++++++++++++++++------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index c4d3eb02da09..f48e73f905e5 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -238,6 +238,29 @@ static const struct timing_regs timing_reg_values[] = {
 static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num);
 static void __xiic_start_xfer(struct xiic_i2c *i2c);
 
+static int __maybe_unused xiic_i2c_runtime_suspend(struct device *dev)
+{
+	struct xiic_i2c *i2c = dev_get_drvdata(dev);
+
+	clk_disable(i2c->clk);
+
+	return 0;
+}
+
+static int __maybe_unused xiic_i2c_runtime_resume(struct device *dev)
+{
+	struct xiic_i2c *i2c = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_enable(i2c->clk);
+	if (ret) {
+		dev_err(dev, "Cannot enable clock.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * For the register read and write functions, a little-endian and big-endian
  * version are necessary. Endianness is detected during the probe function.
@@ -1365,29 +1388,6 @@ static void xiic_i2c_remove(struct platform_device *pdev)
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
 }
 
-static int __maybe_unused xiic_i2c_runtime_suspend(struct device *dev)
-{
-	struct xiic_i2c *i2c = dev_get_drvdata(dev);
-
-	clk_disable(i2c->clk);
-
-	return 0;
-}
-
-static int __maybe_unused xiic_i2c_runtime_resume(struct device *dev)
-{
-	struct xiic_i2c *i2c = dev_get_drvdata(dev);
-	int ret;
-
-	ret = clk_enable(i2c->clk);
-	if (ret) {
-		dev_err(dev, "Cannot enable clock.\n");
-		return ret;
-	}
-
-	return 0;
-}
-
 static const struct dev_pm_ops xiic_dev_pm_ops = {
 	SET_RUNTIME_PM_OPS(xiic_i2c_runtime_suspend,
 			   xiic_i2c_runtime_resume, NULL)
-- 
2.25.1



From manikanta.guntupalli at amd.com  Tue Dec 10 01:52:42 2024
From: manikanta.guntupalli at amd.com (Manikanta Guntupalli)
Date: Tue, 10 Dec 2024 15:22:42 +0530
Subject: [PATCH V2 2/2] i2c: xiic: Add atomic transfer support
In-Reply-To: <20241210095242.1982770-1-manikanta.guntupalli@amd.com>
References: <20241210095242.1982770-1-manikanta.guntupalli@amd.com>
Message-ID: <20241210095242.1982770-3-manikanta.guntupalli@amd.com>

Rework the read and write code paths in the driver to support operation
in atomic contexts.

Similar changes have been implemented in other drivers, including:
commit 3a5ee18d2a32 ("i2c: imx: implement master_xfer_atomic callback")
commit 445094c8a9fb ("i2c: exynos5: add support for atomic transfers")
commit ede2299f7101 ("i2c: tegra: Support atomic transfers")
commit fe402bd09049 ("i2c: meson: implement the master_xfer_atomic
callback")

Signed-off-by: Manikanta Guntupalli <manikanta.guntupalli at amd.com>
---
Changes for V2:
Remove NULL checks for tx_msg and rx_msg, as __xiic_start_xfer() already
has checks.
---
 drivers/i2c/busses/i2c-xiic.c | 239 +++++++++++++++++++++++++++++-----
 1 file changed, 206 insertions(+), 33 deletions(-)

diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index f48e73f905e5..dc1e46d834dc 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -30,6 +30,8 @@
 #include <linux/of.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
+#include <linux/iopoll.h>
+#include <linux/spinlock.h>
 
 #define DRIVER_NAME "xiic-i2c"
 #define DYNAMIC_MODE_READ_BROKEN_BIT	BIT(0)
@@ -74,6 +76,9 @@ enum i2c_scl_freq {
  * @smbus_block_read: Flag to handle block read
  * @input_clk: Input clock to I2C controller
  * @i2c_clk: I2C SCL frequency
+ * @atomic: Mode of transfer
+ * @atomic_lock: Lock for atomic transfer mode
+ * @atomic_xfer_state: See STATE_
  */
 struct xiic_i2c {
 	struct device *dev;
@@ -96,6 +101,9 @@ struct xiic_i2c {
 	bool smbus_block_read;
 	unsigned long input_clk;
 	unsigned int i2c_clk;
+	bool atomic;
+	spinlock_t atomic_lock;		/* Lock for atomic transfer mode */
+	enum xilinx_i2c_state atomic_xfer_state;
 };
 
 struct xiic_version_data {
@@ -224,6 +232,8 @@ static const struct timing_regs timing_reg_values[] = {
 #define XIIC_I2C_TIMEOUT	(msecs_to_jiffies(1000))
 /* timeout waiting for the controller finish transfers */
 #define XIIC_XFER_TIMEOUT	(msecs_to_jiffies(10000))
+/* timeout waiting for the controller finish transfers in micro seconds */
+#define XIIC_XFER_TIMEOUT_US	10000000
 
 /*
  * The following constant is used for the device global interrupt enable
@@ -238,7 +248,7 @@ static const struct timing_regs timing_reg_values[] = {
 static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num);
 static void __xiic_start_xfer(struct xiic_i2c *i2c);
 
-static int __maybe_unused xiic_i2c_runtime_suspend(struct device *dev)
+static int xiic_i2c_runtime_suspend(struct device *dev)
 {
 	struct xiic_i2c *i2c = dev_get_drvdata(dev);
 
@@ -247,7 +257,7 @@ static int __maybe_unused xiic_i2c_runtime_suspend(struct device *dev)
 	return 0;
 }
 
-static int __maybe_unused xiic_i2c_runtime_resume(struct device *dev)
+static int xiic_i2c_runtime_resume(struct device *dev)
 {
 	struct xiic_i2c *i2c = dev_get_drvdata(dev);
 	int ret;
@@ -397,9 +407,10 @@ static int xiic_setclk(struct xiic_i2c *i2c)
 	unsigned int index = 0;
 	u32 reg_val;
 
-	dev_dbg(i2c->adap.dev.parent,
-		"%s entry, i2c->input_clk: %ld, i2c->i2c_clk: %d\n",
-		__func__, i2c->input_clk, i2c->i2c_clk);
+	if (!i2c->atomic)
+		dev_dbg(i2c->adap.dev.parent,
+			"%s entry, i2c->input_clk: %ld, i2c->i2c_clk: %d\n",
+			__func__, i2c->input_clk, i2c->i2c_clk);
 
 	/* If not specified in DT, do not configure in SW. Rely only on Vivado design */
 	if (!i2c->i2c_clk || !i2c->input_clk)
@@ -490,7 +501,8 @@ static int xiic_reinit(struct xiic_i2c *i2c)
 		return ret;
 
 	/* Enable interrupts */
-	xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+	if (!i2c->atomic)
+		xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
 
 	xiic_irq_clr_en(i2c, XIIC_INTR_ARB_LOST_MASK);
 
@@ -572,11 +584,12 @@ static void xiic_read_rx(struct xiic_i2c *i2c)
 
 	bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1;
 
-	dev_dbg(i2c->adap.dev.parent,
-		"%s entry, bytes in fifo: %d, rem: %d, SR: 0x%x, CR: 0x%x\n",
-		__func__, bytes_in_fifo, xiic_rx_space(i2c),
-		xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
-		xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+	if (!i2c->atomic)
+		dev_dbg(i2c->adap.dev.parent,
+			"%s entry, bytes in fifo: %d, rem: %d, SR: 0x%x, CR: 0x%x\n",
+			__func__, bytes_in_fifo, xiic_rx_space(i2c),
+			xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
+			xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
 
 	if (bytes_in_fifo > xiic_rx_space(i2c))
 		bytes_in_fifo = xiic_rx_space(i2c);
@@ -635,6 +648,26 @@ static void xiic_read_rx(struct xiic_i2c *i2c)
 	}
 }
 
+static bool xiic_error_check(struct xiic_i2c *i2c)
+{
+	bool status = false;
+	u32 pend, isr, ier;
+
+	isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
+	ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
+	pend = isr & ier;
+
+	if ((pend & XIIC_INTR_ARB_LOST_MASK) ||
+	    ((pend & XIIC_INTR_TX_ERROR_MASK) &&
+	    !(pend & XIIC_INTR_RX_FULL_MASK))) {
+		xiic_reinit(i2c);
+		status = true;
+		if (i2c->tx_msg || i2c->rx_msg)
+			i2c->atomic_xfer_state = STATE_ERROR;
+	}
+	return status;
+}
+
 static int xiic_tx_fifo_space(struct xiic_i2c *i2c)
 {
 	/* return the actual space left in the FIFO */
@@ -648,8 +681,9 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
 
 	len = (len > fifo_space) ? fifo_space : len;
 
-	dev_dbg(i2c->adap.dev.parent, "%s entry, len: %d, fifo space: %d\n",
-		__func__, len, fifo_space);
+	if (!i2c->atomic)
+		dev_dbg(i2c->adap.dev.parent, "%s entry, len: %d, fifo space: %d\n",
+			__func__, len, fifo_space);
 
 	while (len--) {
 		u16 data = i2c->tx_msg->buf[i2c->tx_pos++];
@@ -672,9 +706,13 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
 				xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, cr &
 					     ~XIIC_CR_MSMS_MASK);
 			}
-			dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__);
+			if (!i2c->atomic)
+				dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__);
 		}
 		xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
+
+		if (i2c->atomic && xiic_error_check(i2c))
+			return;
 	}
 }
 
@@ -877,22 +915,51 @@ static int xiic_wait_not_busy(struct xiic_i2c *i2c)
 	 */
 	err = xiic_bus_busy(i2c);
 	while (err && tries--) {
-		msleep(1);
+		if (i2c->atomic)
+			udelay(1000);
+		else
+			usleep_range(1000, 1100);
 		err = xiic_bus_busy(i2c);
 	}
 
 	return err;
 }
 
+static void xiic_recv_atomic(struct xiic_i2c *i2c)
+{
+	while (xiic_rx_space(i2c)) {
+		if (xiic_getreg32(i2c, XIIC_IISR_OFFSET) & XIIC_INTR_RX_FULL_MASK) {
+			xiic_read_rx(i2c);
+
+			/* Clear Rx full and Tx error interrupts. */
+			xiic_irq_clr_en(i2c, XIIC_INTR_RX_FULL_MASK |
+					XIIC_INTR_TX_ERROR_MASK);
+		}
+		if (xiic_error_check(i2c))
+			return;
+	}
+
+	i2c->rx_msg = NULL;
+	xiic_irq_clr_en(i2c, XIIC_INTR_TX_ERROR_MASK);
+
+	/* send next message if this wasn't the last. */
+	if (i2c->nmsgs > 1) {
+		i2c->nmsgs--;
+		i2c->tx_msg++;
+		__xiic_start_xfer(i2c);
+	}
+}
+
 static void xiic_start_recv(struct xiic_i2c *i2c)
 {
 	u16 rx_watermark;
 	u8 cr = 0, rfd_set = 0;
 	struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg;
 
-	dev_dbg(i2c->adap.dev.parent, "%s entry, ISR: 0x%x, CR: 0x%x\n",
-		__func__, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
-		xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+	if (!i2c->atomic)
+		dev_dbg(i2c->adap.dev.parent, "%s entry, ISR: 0x%x, CR: 0x%x\n",
+			__func__, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
+			xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
 
 	/* Disable Tx interrupts */
 	xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK | XIIC_INTR_TX_EMPTY_MASK);
@@ -990,9 +1057,10 @@ static void xiic_start_recv(struct xiic_i2c *i2c)
 					XIIC_CR_MSMS_MASK)
 					& ~(XIIC_CR_DIR_IS_TX_MASK));
 		}
-		dev_dbg(i2c->adap.dev.parent, "%s end, ISR: 0x%x, CR: 0x%x\n",
-			__func__, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
-			xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+		if (!i2c->atomic)
+			dev_dbg(i2c->adap.dev.parent, "%s end, ISR: 0x%x, CR: 0x%x\n",
+				__func__, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
+				xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
 	}
 
 	if (i2c->nmsgs == 1)
@@ -1002,10 +1070,55 @@ static void xiic_start_recv(struct xiic_i2c *i2c)
 	/* the message is tx:ed */
 	i2c->tx_pos = msg->len;
 
+	i2c->prev_msg_tx = false;
+
 	/* Enable interrupts */
-	xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+	if (!i2c->atomic)
+		xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+	else
+		xiic_recv_atomic(i2c);
+}
 
-	i2c->prev_msg_tx = false;
+static void xiic_send_rem_atomic(struct xiic_i2c *i2c)
+{
+	while (xiic_tx_space(i2c)) {
+		if (xiic_tx_fifo_space(i2c)) {
+			u16 data;
+
+			data = i2c->tx_msg->buf[i2c->tx_pos];
+			i2c->tx_pos++;
+			if (!xiic_tx_space(i2c) && i2c->nmsgs == 1) {
+				/* last message in transfer -> STOP */
+				if (i2c->dynamic) {
+					data |= XIIC_TX_DYN_STOP_MASK;
+				} else {
+					u8 cr;
+					int status;
+
+					/* Wait till FIFO is empty so STOP is sent last */
+					status = xiic_wait_tx_empty(i2c);
+					if (status)
+						return;
+
+					/* Write to CR to stop */
+					cr = xiic_getreg8(i2c, XIIC_CR_REG_OFFSET);
+					xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, cr &
+						     ~XIIC_CR_MSMS_MASK);
+				}
+			}
+			xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
+		}
+		if (xiic_error_check(i2c))
+			return;
+	}
+
+	if (i2c->nmsgs > 1) {
+		i2c->nmsgs--;
+		i2c->tx_msg++;
+		__xiic_start_xfer(i2c);
+	} else {
+		xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
+	}
 }
 
 static void xiic_start_send(struct xiic_i2c *i2c)
@@ -1014,11 +1127,13 @@ static void xiic_start_send(struct xiic_i2c *i2c)
 	u16 data;
 	struct i2c_msg *msg = i2c->tx_msg;
 
-	dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d",
-		__func__, msg, msg->len);
-	dev_dbg(i2c->adap.dev.parent, "%s entry, ISR: 0x%x, CR: 0x%x\n",
-		__func__, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
-		xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+	if (!i2c->atomic) {
+		dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d",
+			__func__, msg, msg->len);
+		dev_dbg(i2c->adap.dev.parent, "%s entry, ISR: 0x%x, CR: 0x%x\n",
+			__func__, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
+			xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+	}
 
 	if (i2c->dynamic) {
 		/* write the address */
@@ -1083,19 +1198,27 @@ static void xiic_start_send(struct xiic_i2c *i2c)
 				XIIC_INTR_TX_ERROR_MASK |
 				XIIC_INTR_BNB_MASK);
 	}
+
 	i2c->prev_msg_tx = true;
+
+	if (i2c->atomic && !i2c->atomic_xfer_state)
+		xiic_send_rem_atomic(i2c);
 }
 
 static void __xiic_start_xfer(struct xiic_i2c *i2c)
 {
 	int fifo_space = xiic_tx_fifo_space(i2c);
 
-	dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, fifos space: %d\n",
-		__func__, i2c->tx_msg, fifo_space);
+	if (!i2c->atomic)
+		dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, fifos space: %d\n",
+			__func__, i2c->tx_msg, fifo_space);
 
 	if (!i2c->tx_msg)
 		return;
 
+	if (i2c->atomic && xiic_error_check(i2c))
+		return;
+
 	i2c->rx_pos = 0;
 	i2c->tx_pos = 0;
 	i2c->state = STATE_START;
@@ -1112,7 +1235,10 @@ static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num)
 	bool broken_read, max_read_len, smbus_blk_read;
 	int ret, count;
 
-	mutex_lock(&i2c->lock);
+	if (i2c->atomic)
+		spin_lock(&i2c->atomic_lock);
+	else
+		mutex_lock(&i2c->lock);
 
 	if (i2c->tx_msg || i2c->rx_msg) {
 		dev_err(i2c->adap.dev.parent,
@@ -1121,6 +1247,8 @@ static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num)
 		goto out;
 	}
 
+	i2c->atomic_xfer_state = STATE_DONE;
+
 	/* In single master mode bus can only be busy, when in use by this
 	 * driver. If the register indicates bus being busy for some reason we
 	 * should ignore it, since bus will never be released and i2c will be
@@ -1147,7 +1275,9 @@ static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num)
 	i2c->tx_msg = msgs;
 	i2c->rx_msg = NULL;
 	i2c->nmsgs = num;
-	init_completion(&i2c->completion);
+
+	if (!i2c->atomic)
+		init_completion(&i2c->completion);
 
 	/* Decide standard mode or Dynamic mode */
 	i2c->dynamic = true;
@@ -1182,7 +1312,10 @@ static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num)
 		__xiic_start_xfer(i2c);
 
 out:
-	mutex_unlock(&i2c->lock);
+	if (i2c->atomic)
+		spin_unlock(&i2c->atomic_lock);
+	else
+		mutex_unlock(&i2c->lock);
 
 	return ret;
 }
@@ -1221,6 +1354,44 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 	return err;
 }
 
+static int xiic_xfer_atomic(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct xiic_i2c *i2c = i2c_get_adapdata(adap);
+	u32 status_reg;
+	int err;
+
+	err = xiic_i2c_runtime_resume(i2c->dev);
+	if (err)
+		return err;
+
+	i2c->atomic = true;
+	err = xiic_start_xfer(i2c, msgs, num);
+	if (err < 0)
+		return err;
+
+	err = readl_poll_timeout_atomic(i2c->base + XIIC_SR_REG_OFFSET,
+					status_reg, !(status_reg & XIIC_SR_BUS_BUSY_MASK),
+					1, XIIC_XFER_TIMEOUT_US);
+
+	if (err) /* Timeout */
+		err = -ETIMEDOUT;
+
+	spin_lock(&i2c->atomic_lock);
+	if (err || i2c->state) {
+		i2c->tx_msg = NULL;
+		i2c->rx_msg = NULL;
+		i2c->nmsgs = 0;
+	}
+
+	err = (i2c->atomic_xfer_state == STATE_DONE) ? num : -EIO;
+	spin_unlock(&i2c->atomic_lock);
+
+	i2c->atomic = false;
+	xiic_i2c_runtime_suspend(i2c->dev);
+
+	return err;
+}
+
 static u32 xiic_func(struct i2c_adapter *adap)
 {
 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA;
@@ -1228,6 +1399,7 @@ static u32 xiic_func(struct i2c_adapter *adap)
 
 static const struct i2c_algorithm xiic_algorithm = {
 	.master_xfer = xiic_xfer,
+	.master_xfer_atomic = xiic_xfer_atomic,
 	.functionality = xiic_func,
 };
 
@@ -1291,6 +1463,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
 		 DRIVER_NAME " %s", pdev->name);
 
 	mutex_init(&i2c->lock);
+	spin_lock_init(&i2c->atomic_lock);
 
 	i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(i2c->clk))
-- 
2.25.1



From maz at kernel.org  Tue Dec 10 01:55:30 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Dec 2024 09:55:30 +0000
Subject: v6.13-rc1: Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP
In-Reply-To: <20241210025127.jmkcpw7ixu4r7hxl@altlinux.org>
References: <20241202153618.GA6834@willie-the-truck>
	<86ttbmt71k.wl-maz@kernel.org>
	<20241202155940.p267a3tz5ypj4sog@altlinux.org>
	<86ser6t6fs.wl-maz@kernel.org>
	<20241202223119.k3uod4ksnlf7gqh2@altlinux.org>
	<20241203092721.j473dthkbq6wzez7@altlinux.org>
	<1847e34fa7724d28aeb22d93752f64f2@huawei.com>
	<20241203221453.mwh6sozyczi4ec2k@altlinux.org>
	<87jzcfsuep.wl-maz@kernel.org>
	<20241206205602.7phcrxqsv4c6oul4@altlinux.org>
	<20241210025127.jmkcpw7ixu4r7hxl@altlinux.org>
Message-ID: <86v7vrsvzh.wl-maz@kernel.org>

On Tue, 10 Dec 2024 02:51:27 +0000,
Vitaly Chikunov <vt at altlinux.org> wrote:
> 
> On Fri, Dec 06, 2024 at 11:56:02PM +0300, Vitaly Chikunov wrote:
> > On Wed, Dec 04, 2024 at 08:51:26AM +0000, Marc Zyngier wrote:
> > > On Tue, 03 Dec 2024 22:14:53 +0000,
> > > Vitaly Chikunov <vt at altlinux.org> wrote:
> > > > On Tue, Dec 03, 2024 at 10:03:11AM +0000, Shameerali Kolothum Thodi wrote:
> > > 
> > > Mark has described what the problem is likely to be. 6.6-stable needs
> > > to have 6685f5d572c22e10 backported, and it probably should have been
> > > Cc: to stable. Can you please apply the following patch to your *host*
> > > machine and retest?
> > 
> > We tested the host with this patch applied over 6.6.63 and 6.13-rc1
> > guest does not Oops anymore.
> > 
> > I'd suggest this is also get backported to 6.12.y branch.
> 
> Please, can someone backport this patch to v6.12 and send to stable? This
> would be really useful to have this fixed and it's noted this is a
> critical bug.

Look: it took you a few good days to simply *report* that the hack I
gave you was helping. Surely you can similarly wait for a few days for
the interested parties to spin proper patches and *test* them?

And if you really cannot wait, feel free to backport this change to
whatever stable release you feel needs to be fixed and post the
result.  I promise that I will review it. After all, you are so far
the only person with both the HW and the problem.

Thanks,

	M.

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


From matthias.schiffer at ew.tq-group.com  Tue Dec 10 01:56:41 2024
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Tue, 10 Dec 2024 10:56:41 +0100
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and
 MBa62xx carrier board Device Trees
In-Reply-To: <a2a2f201-73a4-4a99-baef-0d593a88c872@lunn.ch>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
	 <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
	 <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>
	 <c902a56cf34838f60cee67624bb923e91d74e9e0.camel@ew.tq-group.com>
	 <d25b1447-c28b-4998-b238-92672434dc28@lunn.ch>
	 <e16076d16349e929af82fa987a658bff1d9804c4.camel@ew.tq-group.com>
	 <a2a2f201-73a4-4a99-baef-0d593a88c872@lunn.ch>
Message-ID: <309052f3f69950fe43390505cc7254aee8c8f5c6.camel@ew.tq-group.com>

On Mon, 2024-12-09 at 17:14 +0100, Andrew Lunn wrote:
> 
> > Not our board, but the AM62 SoC. From the datasheet:
> > 
> > "TXC is delayed internally before being driven to the RGMII[x]_TXC pin. This
> > internal delay is always enabled." So enabling the TX delay on the PHY side
> > would result in a double delay.
> 
> phy-mode describes the board. If the board does not have extra long
> clock lines, phy-mode should be rgmii-id.
> 
> The fact the MAC is doing something which no other MAC does should be
> hidden away in the MAC driver, as much as possible.

Isn't it kind of a philosophical question whether a delay added by the SoC
integration is part of the MAC or not? One could also argue that the MAC IP core
is always the same, with some SoCs adding the delay and others not. (I don't
know if there are actually SoCs with the same IP core that don't add a delay;
I'm just not a big fan of hiding details in the driver that could easily be
described by the Device Tree, thus making the driver more generic)


> 
> The MAC driver should return -EINVAL with phy-mode rgmii, or
> rmgii-rxid, because the MAC driver is physically incapable of being
> used on a board which has extra long TX clock lines, which 'rmgii' or
> rgmii-rxid would indicate.
> 
> Since the MAC driver is forcing the TX delay, it needs to take the
> value returned from of_get_phy_mode() and mask out the TX bit before
> passing it to the PHY.

Hmm okay, this is what the similar ICSSG/PRUETH driver does. I've always found
that solution to be particularly confusing, but if that's how it's supposed to
work, I'll have to accept that.

In my opinion the documentation Documentation/networking/phy.rst is not very
clear on this matter - the whole section "(RG)MII/electrical interface
considerations" talks about whether the PHY inserts the delay or not, so my
assumption was that phy-mode describes the PHY side of things and only that.

It gets even more confusing when taking into account
Documentation/devicetree/bindings/net/ethernet-controller.yaml, which contains
comments like "RGMII with internal RX delay provided by the PHY, the MAC should
not add an RX delay in this case", which sounds like there are only the cases
"delay is added by the PHY" and "delay is added by the MAC" - the case "delay is
part of the board design, neither MAC nor PHY add it" doesn't even appear.

> 
> Now, it could be that history has got in the way. There are boards out
> there which have broken DT but work. Fixing the MAC driver to do the
> correct thing will break those boards. Vendors with low quality code
> which works, but not really.
> 
> ~/linux/arch/arm64/boot/dts/ti$ grep rgmii k3-am625-*
> k3-am625-beagleplay.dts:	phy-mode = "rgmii-rxid";
> k3-am625-sk.dts:	phy-mode = "rgmii-rxid";
> 
> Yep, these two have broken DT, they don't describe the board
> correctly.
> 
> O.K. Can we fix this for you board? Yes, i think we can. If you take
> rmgii-rxid, aka PHY_INTERFACE_MODE_RGMII_RXID, and mask out the TX,
> you still get PHY_INTERFACE_MODE_RGMII_RXID. If you take rgmii-id,
> a.k.a. PHY_INTERFACE_MODE_RGMII_ID and mask out the TX, you get
> PHY_INTERFACE_MODE_RGMII_RXID, which is what you want.
> 
> Please produce a patch to the MAC driver, explaining the horrible mess
> the vendor made, and how this fixes it, but should also not break
> other boards.

I can make this change, but "am65-cpsw-nuss" currently supports 6 different
compatible strings, many of which are used for multiple SoC families.

Maybe someone from TI could chime in and say whether all of these have the fixed
TXC delay, or at least the current compatible strings are already specific
enough to tell whether the SoC adds a delay?


> 
> > No such defaults exist in the DP83867 driver. If any rgmii-*id mode is used, the
> > corresponding delays *must* be specified in the DTB:
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/phy/dp83867.c#n532
> 
> That is bad, different to pretty every other PHY driver :-(
> 
> If you want, you could patch this driver as well, make it default to
> 2ns if delays are asked for.

Makes sense, I'll write a patch for that as well.

Best regards,
Matthias


> 
>     Andrew
> 
> ---
> pw-bot: cr

-- 
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
https://www.tq-group.com/


From lkp at intel.com  Tue Dec 10 02:00:47 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 10 Dec 2024 18:00:47 +0800
Subject: [arm-platforms:pci/xgene-fixes-6.13 8/18]
 drivers/iommu/amd/iommu.c:3810:3: error: field designator 'bus_token' does
 not refer to any field in type 'const struct msi_parent_ops'
Message-ID: <202412101701.Uu0dEEE7-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git pci/xgene-fixes-6.13
head:   32627e010975ae9817552c5e21d1860ce9c9bdfa
commit: 3c9773aab9b801ba71766b264e859785309b13ba [8/18] iommu/amd: Convert to msi_create_parent_irq_domain() helper
config: x86_64-rhel-9.4-rust (https://download.01.org/0day-ci/archive/20241210/202412101701.Uu0dEEE7-lkp at intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241210/202412101701.Uu0dEEE7-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/202412101701.Uu0dEEE7-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/iommu/amd/iommu.c:12:
   In file included from include/linux/pci.h:1644:
   In file included from include/linux/dmapool.h:14:
   In file included from include/linux/scatterlist.h:8:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iommu/amd/iommu.c:3810:3: error: field designator 'bus_token' does not refer to any field in type 'const struct msi_parent_ops'
    3810 |         .bus_token              = DOMAIN_BUS_AMDVI,
         |         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   4 warnings and 1 error generated.


vim +3810 drivers/iommu/amd/iommu.c

  3807	
  3808	static const struct msi_parent_ops amdvi_msi_parent_ops = {
  3809		.supported_flags	= X86_VECTOR_MSI_FLAGS_SUPPORTED | MSI_FLAG_MULTI_PCI_MSI,
> 3810		.bus_token		= DOMAIN_BUS_AMDVI,
  3811		.prefix			= "IR-",
  3812		.init_dev_msi_info	= msi_parent_init_dev_msi_info,
  3813	};
  3814	

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


From heiko at sntech.de  Tue Dec 10 02:01:34 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 10 Dec 2024 11:01:34 +0100
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2 controller
In-Reply-To: <2d68155e.1e5b.193ae4616b9.Coremail.andyshrk@163.com>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <CAA8EJprLA09NP0KAztc5eoAMkGcrom84jg_pcbNcwN0FAaSLrw@mail.gmail.com>
 <2d68155e.1e5b.193ae4616b9.Coremail.andyshrk@163.com>
Message-ID: <2117643.K71DO8KEF6@diego>

Am Dienstag, 10. Dezember 2024, 02:54:09 CET schrieb Andy Yan:
> 
> Hi Dmitry,
> 
> ? 2024-12-10 09:45:11?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
> >On Tue, 10 Dec 2024 at 03:22, Andy Yan <andyshrk at 163.com> wrote:
> >>
> >>
> >> Hi Dmitry,
> >>
> >> ? 2024-12-10 09:01:38?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
> >> >On Tue, Dec 10, 2024 at 08:50:51AM +0800, Andy Yan wrote:
> >> >>
> >> >>
> >> >> Hi,
> >> >>
> >> >> At 2024-12-10 07:12:26, "Heiko St?bner" <heiko at sntech.de> wrote:
> >> >> >Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
> >> >> >> Hi,
> >> >> >>
> >> >> >> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
> >> >> >> > On 03.12.24 21:54, Heiko Stuebner wrote:
> >> >> >> > > This series adds a bridge and glue driver for the DSI2 controller found
> >> >> >> > > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
> >> >> >> > >
> >> >> >> >
> >> >> >> > I did more tests with different LVDS displays. I tested following
> >> >> >> > configurations with DSI/LVDS bridge:
> >> >> >> > - 1024x600 at 60.01
> >> >> >> > - 1024x768 at 60.02
> >> >> >> > - 1280x800 at 60.07
> >> >> >> > - 1366x768 at 60.06
> >> >> >> >
> >> >> >> > All of them worked without issues, except 1366x768.
> >> >> >> > With this resolution, video is blurry, and offset incorrectly
> >> >> >> > to the left. There are also repeating errors on the console:
> >> >> >> >
> >> >> >> >   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
> >> >> >> >
> >> >> >> > In correct operation with other resolutions, there is no error.
> >> >> >> > I am not sure if this is a problem in your series or rather in VOP2
> >> >> >> > driver.
> >> >> >
> >> >> >This really sounds like something is wrong on the vop side.
> >> >> >The interrupt is part of the vop, the divisable by 4 things likely too.
> >> >>
> >> >> This is a hardware limitation on vop side:
> >> >> The horizontal resolution must be 4 pixel aligned.
> >> >
> >> >Then mode_valid() and atomic_check() must reject modes that don't fit.
> >>
> >> We round down to 4 pixel aligned in mode_fixup in our bsp kernel,
> >
> >What is meant by the "bsp kernel" here? I don't see it being present
> 
> bsp kernel means downstream vendor kernel.
> 
> >in the mainline kernel. So, if the mode is unsupported, it should be
> 
> Will it be acceptable to add this round down in the mainline mode_fixup?

personally I'd like that.

I.e. the thing in the examoke above is an LVDS display, so has essentially
fixed resolution. So adapting the resolution may or may not be possible
(some for DSI or whatever) .

Doing that rounding-down AND emitting a dev_warn about that fact would
be preferrable to me personally, though I don't know if there is some
different precedent in other parts of DRM.


Heiko




From geert at linux-m68k.org  Tue Dec 10 02:04:25 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 10 Dec 2024 11:04:25 +0100
Subject: [PATCH 0/5] arm64: renesas: Add R8A779G3 White Hawk Single support
In-Reply-To: <87y10pmjd6.wl-kuninori.morimoto.gx@renesas.com>
References: <cover.1733156661.git.geert+renesas@glider.be> <87jzcg1d2f.wl-kuninori.morimoto.gx@renesas.com>
 <CAMuHMdWF7NcmKYzvF4Dfjh3S5MccbJrpSphK5BhxXNnhxgtmYQ@mail.gmail.com>
 <87y10tvhw1.wl-kuninori.morimoto.gx@renesas.com> <87y10pmjd6.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <CAMuHMdVEdLvSRRUOwZR_jzpvjAM_zr++Bbxph21QzXLLsjY7mw@mail.gmail.com>

Hi Morimoto-san,

On Mon, Dec 9, 2024 at 8:00?AM Kuninori Morimoto
<kuninori.morimoto.gx at renesas.com> wrote:
> > > -              - renesas,r8a779g2
> > > -              - renesas,r8a779g3
> > > +              - renesas,r8a779g2 # ES2.x
> > > +              - renesas,r8a779g3 # ES3.0
> > >
> > > but decided against doing so, as "ES3.0" would become stale as soon
> > > as Renesas releases "ES3.1". Alternatively, I could use "ES3.x"
> > > immediately.
>
> It seems using "ES3.x" is a good idea.

Thanks for checking, I'll add these comments while applying.

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 dsimic at manjaro.org  Tue Dec 10 02:04:45 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 10 Dec 2024 11:04:45 +0100
Subject: [PATCH 4/6] arm64: dts: rockchip: add hevc power domain clock to
 rk3328
In-Reply-To: <20241210013010.81257-5-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-5-pgwipeout@gmail.com>
Message-ID: <e32fa593abfa6d08202b4f929e0b4bdb@manjaro.org>

Hello Peter,

On 2024-12-10 02:30, Peter Geis wrote:
> There is a race condition at startup between disabling power domains 
> not
> used and disabling clocks not used on the rk3328. When the clocks are
> disabled first, the hevc power domain fails to shut off leading to a
> splat of failures. Add the hevc core clock to the rk3328 power domain
> node to prevent this condition.
> 
> rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-.... 
> }
> 1087 jiffies s: 89 root: 0x8/.
> rcu: blocking rcu_node structures (internal RCU debug):
> Sending NMI from CPU 0 to CPUs 3:
> NMI backtrace for cpu 3
> CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53
> Hardware name: Firefly ROC-RK3328-CC (DT)
> Workqueue: pm genpd_power_off_work_fn
> pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : regmap_unlock_spinlock+0x18/0x30
> lr : regmap_read+0x60/0x88
> sp : ffff800081123c00
> x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000
> x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040
> x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74
> x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000
> x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d
> x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431
> x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0
> x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b
> x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40
> x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000
> Call trace:
> regmap_unlock_spinlock+0x18/0x30
> rockchip_pmu_set_idle_request+0xac/0x2c0
> rockchip_pd_power+0x144/0x5f8
> rockchip_pd_power_off+0x1c/0x30
> _genpd_power_off+0x9c/0x180
> genpd_power_off.part.0.isra.0+0x130/0x2a8
> genpd_power_off_work_fn+0x6c/0x98
> process_one_work+0x170/0x3f0
> worker_thread+0x290/0x4a8
> kthread+0xec/0xf8
> ret_from_fork+0x10/0x20
> rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack 
> on
> domain 'hevc', val=0x88220
> 
> Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for 
> RK3328 SoCs")
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>

While I was unable to formally verify this clock assignment,
i.e. by using the RK3328 TRM or the downstream kernel source
from Rockchip, it makes perfect sense to me.  Thanks for the
patch, and please feel free to include:

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

> ---
> 
>  arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> index 0597de415fe0..7d992c3c01ce 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> @@ -333,6 +333,7 @@ power: power-controller {
> 
>  			power-domain at RK3328_PD_HEVC {
>  				reg = <RK3328_PD_HEVC>;
> +				clocks = <&cru SCLK_VENC_CORE>;
>  				#power-domain-cells = <0>;
>  			};
>  			power-domain at RK3328_PD_VIDEO {


From ericwouds at gmail.com  Tue Dec 10 01:44:48 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:48 +0100
Subject: [PATCH RFC v3 net-next 00/13] bridge-fastpath and related improvements
Message-ID: <20241210094501.3069-1-ericwouds@gmail.com>

This patchset makes it possible to set up a software fastpath between
bridged interfaces. This also creates the possibility to have a hardware
offloaded fastpath between bridged interfaces.

To set up the fastpath with offloading, add this extra flowtable:

table bridge filter {
        flowtable fb {
                hook ingress priority filter
                devices = { lan0, lan1, lan2, lan3, lan4, wlan0, wlan1 }
                flags offload
        }
        chain forward {
                type filter hook forward priority filter; policy accept;
		ct state established flow add @fb
        }
}

Creating a separate fastpath for bridges.

         forward fastpath bypass
 .----------------------------------------.
/                                          \
|                        IP - forwarding    |
|                       /                \  v
|                      /                  wan ...
|                     /
|                     |
|                     |
|                   brlan.1
|                     |
|    +-------------------------------+
|    |           vlan 1              |
|    |                               |
|    |     brlan (vlan-filtering)    |
|    +---------------+               |
|    |  DSA-SWITCH   |               |
|    |               |    vlan 1     |
|    |               |      to       |
|    |   vlan 1      |   untagged    |
|    +---------------+---------------+
.         /                   \
 ------>lan0                 wlan1
        .  ^                 ^
        .  |                 |
        .  \_________________/
        .  bridge fastpath bypass
        .
        ^
     vlan 1 tagged packets

While testing direct transmit in the software forward-fastpath, it is
useful to enslave the wan interface to another bridge, brwan. This will
make sure both directions of the software forward-fastpath use direct
transmit.

To have the ability to handle xmit direct with outgoing encaps in the
bridge fastpass bypass, we need to be able to handle them without going
through vlan/pppoe devices. So I've applied, amended and squashed wenxu's
patchset. This patch also makes it possible to egress from vlan-filtering
brlan to lan0 with vlan tagged packets, if the bridge master port is doing
the vlan tagging, instead of the vlan-device. Without this patch, this is
not possible in the bridge-fastpath and also not in the forward-fastpath,
as seen in the figure above.

There are also some more fixes for filling in the forward path. These
fixes also apply to for the forward-fastpath. They include handling
DEV_PATH_MTK_WDMA in nft_dev_path_info(). There are now 2 patches for
avoiding ingress_vlans bit set for bridged dsa user ports and foreign
(dsa) ports.

Another patch introduces DEV_PATH_BR_VLAN_KEEP_HW, needed for the
bridge-fastpath only.

Conntrack bridge only tracks untagged and 802.1q. To make the bridge
fastpath experience more similar to the forward fastpath experience,
I've added double vlan, pppoe and pppoe-in-q tagged packets to bridge
conntrack and to bridge filter chain.

Note: While testing direct transmit in the software forward-fastpath,
without the capability of setting the offload flag, it is sometimes useful
to enslave the wan interface to another bridge, brwan. This will make
sure both directions of the software forward-fastpath use direct transmit,
which also happens when the offload flag is set.

I have send RFC v2 as I previously only owned a dsa device. I now have
obtained a switchdev supporting SWITCHDEV_OBJ_ID_PORT_VLAN, and found
there was more to do to handle the ingress_vlans bit and corresponding
vlan encap.

I am now sending RFC v3 as the previous RFC did not get any comment.

Changes in v3:
- Squashed the two 'port to port' patches to avoid build errors when only
   one of the two commits is applied.

Changes in v2:
- Introduce DEV_PATH_BR_VLAN_KEEP_HW for use in the bridge-fastpath only.
   It is needed for switchdevs supporting SWITCHDEV_OBJ_ID_PORT_VLAN.
- Different approach for handling BR_VLFLAG_ADDED_BY_SWITCHDEV in
   br_vlan_fill_forward_path_mode() for foreign devices. Introduce
   SWITCHDEV_F_NO_FOREIGN, BR_VLFLAG_TAGGING_BY_SWITCHDEV and
   br_switchdev_port_vlan_no_foreign_add(). The latter function can be
   used to make sure the vlan was added to a switchdev native device.
   When that fails, adding the vlan with br_switchdev_port_vlan_add()
   means it was added to a switchdev foreign device.
- Clear ingress_vlans bit and corresponding encap for dsa user ports.
- Add check for ingress_vlans bit to nft_dev_fill_bridge_path().
- Adapted cover letter description to make clear the patches apply
   to software fastpath, making hardware-offloaded fastpath possible.
- Fixed clang error for vlan_hdr * and struct ppp_hdr * by adding block.
- Updated !CONFIG_BRIDGE_VLAN_FILTERING version of
   br_vlan_fill_forward_path_pvid().
- Removed erroneous check netif_is_bridge_master(ctx->dev) from
   dev_fill_bridge_path().
- Cosmetic changes.

Eric Woudstra (13):
  netfilter: nf_flow_table_offload: Add nf_flow_encap_push() for xmit
    direct
  netfilter: bridge: Add conntrack double vlan and pppoe
  netfilter: nft_chain_filter: Add bridge double vlan and pppoe
  bridge: Add filling forward path from port to port
  net: core: dev: Add dev_fill_bridge_path()
  netfilter :nf_flow_table_offload: Add nf_flow_rule_bridge()
  netfilter: nf_flow_table_inet: Add nf_flowtable_type flowtable_bridge
  netfilter: nft_flow_offload: Add NFPROTO_BRIDGE to validate
  netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to
    nft_dev_path_info()
  netfilter: nft_flow_offload: No ingress_vlan forward info for dsa user
    port
  bridge: No DEV_PATH_BR_VLAN_UNTAG_HW for dsa foreign
  bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW for bridge-fastpath
  netfilter: nft_flow_offload: Add bridgeflow to nft_flow_offload_eval()

 include/linux/netdevice.h                  |   3 +
 include/net/netfilter/nf_flow_table.h      |   3 +
 include/net/switchdev.h                    |   1 +
 net/bridge/br_device.c                     |  23 ++-
 net/bridge/br_private.h                    |   5 +
 net/bridge/br_switchdev.c                  |  15 ++
 net/bridge/br_vlan.c                       |  29 +++-
 net/bridge/netfilter/nf_conntrack_bridge.c |  88 +++++++++--
 net/core/dev.c                             |  66 ++++++--
 net/netfilter/nf_flow_table_inet.c         |  13 ++
 net/netfilter/nf_flow_table_ip.c           |  96 +++++++++++-
 net/netfilter/nf_flow_table_offload.c      |  13 ++
 net/netfilter/nft_chain_filter.c           |  20 ++-
 net/netfilter/nft_flow_offload.c           | 166 +++++++++++++++++++--
 net/switchdev/switchdev.c                  |   2 +-
 15 files changed, 490 insertions(+), 53 deletions(-)

-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:49 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:49 +0100
Subject: [PATCH RFC v3 net-next 01/13] netfilter: nf_flow_table_offload: Add nf_flow_encap_push() for xmit direct
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-2-ericwouds@gmail.com>

Loosely based on wenxu's patches:

"nf_flow_table_offload: offload the vlan/PPPoE encap in the flowtable".

Fixed double vlan and pppoe packets, almost entirely rewriting the patch.

After this patch, it is possible to transmit packets in the fastpath with
outgoing encaps, without using vlan- and/or pppoe-devices.

This makes it possible to use more different kinds of network setups.
For example, when bridge tagging is used to egress vlan tagged
packets using the forward fastpath. Another example is passing 802.1q
tagged packets through a bridge using the bridge fastpath.

This also makes the software fastpath process more similar to the
hardware offloaded fastpath process, where encaps are also pushed.

After applying this patch, always info->outdev = info->hw_outdev,
so the netfilter code can be further cleaned up by removing:
 * hw_outdev from struct nft_forward_info
 * out.hw_ifindex from struct nf_flow_route
 * out.hw_ifidx from struct flow_offload_tuple

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 net/netfilter/nf_flow_table_ip.c | 96 +++++++++++++++++++++++++++++++-
 net/netfilter/nft_flow_offload.c |  6 +-
 2 files changed, 96 insertions(+), 6 deletions(-)

diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c
index 98edcaa37b38..290d8e10d85b 100644
--- a/net/netfilter/nf_flow_table_ip.c
+++ b/net/netfilter/nf_flow_table_ip.c
@@ -302,6 +302,92 @@ static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto,
 	return false;
 }
 
+static int nf_flow_vlan_inner_push(struct sk_buff *skb, __be16 proto, u16 id)
+{
+	struct vlan_hdr *vhdr;
+
+	if (skb_cow_head(skb, VLAN_HLEN))
+		return -1;
+
+	__skb_push(skb, VLAN_HLEN);
+	skb_reset_network_header(skb);
+
+	vhdr = (struct vlan_hdr *)(skb->data);
+	vhdr->h_vlan_TCI = htons(id);
+	vhdr->h_vlan_encapsulated_proto = skb->protocol;
+	skb->protocol = proto;
+
+	return 0;
+}
+
+static int nf_flow_ppoe_push(struct sk_buff *skb, u16 id)
+{
+	struct ppp_hdr {
+		struct pppoe_hdr hdr;
+		__be16 proto;
+	} *ph;
+	int data_len = skb->len + 2;
+	__be16 proto;
+
+	if (skb_cow_head(skb, PPPOE_SES_HLEN))
+		return -1;
+
+	if (skb->protocol == htons(ETH_P_IP))
+		proto = htons(PPP_IP);
+	else if (skb->protocol == htons(ETH_P_IPV6))
+		proto = htons(PPP_IPV6);
+	else
+		return -1;
+
+	__skb_push(skb, PPPOE_SES_HLEN);
+	skb_reset_network_header(skb);
+
+	ph = (struct ppp_hdr *)(skb->data);
+	ph->hdr.ver  = 1;
+	ph->hdr.type = 1;
+	ph->hdr.code = 0;
+	ph->hdr.sid  = htons(id);
+	ph->hdr.length = htons(data_len);
+	ph->proto = proto;
+	skb->protocol = htons(ETH_P_PPP_SES);
+
+	return 0;
+}
+
+static int nf_flow_encap_push(struct sk_buff *skb,
+			      struct flow_offload_tuple_rhash *tuplehash,
+			      unsigned short *type)
+{
+	int i = 0, ret = 0;
+
+	if (!tuplehash->tuple.encap_num)
+		return 0;
+
+	if (tuplehash->tuple.encap[i].proto == htons(ETH_P_8021Q) ||
+	    tuplehash->tuple.encap[i].proto == htons(ETH_P_8021AD)) {
+		__vlan_hwaccel_put_tag(skb, tuplehash->tuple.encap[i].proto,
+				       tuplehash->tuple.encap[i].id);
+		i++;
+		if (i >= tuplehash->tuple.encap_num)
+			return 0;
+	}
+
+	switch (tuplehash->tuple.encap[i].proto) {
+	case htons(ETH_P_8021Q):
+		*type = ETH_P_8021Q;
+		ret = nf_flow_vlan_inner_push(skb,
+					      tuplehash->tuple.encap[i].proto,
+					      tuplehash->tuple.encap[i].id);
+		break;
+	case htons(ETH_P_PPP_SES):
+		*type = ETH_P_PPP_SES;
+		ret = nf_flow_ppoe_push(skb,
+					tuplehash->tuple.encap[i].id);
+		break;
+	}
+	return ret;
+}
+
 static void nf_flow_encap_pop(struct sk_buff *skb,
 			      struct flow_offload_tuple_rhash *tuplehash)
 {
@@ -331,6 +417,7 @@ static void nf_flow_encap_pop(struct sk_buff *skb,
 
 static unsigned int nf_flow_queue_xmit(struct net *net, struct sk_buff *skb,
 				       const struct flow_offload_tuple_rhash *tuplehash,
+				       struct flow_offload_tuple_rhash *other_tuplehash,
 				       unsigned short type)
 {
 	struct net_device *outdev;
@@ -339,6 +426,9 @@ static unsigned int nf_flow_queue_xmit(struct net *net, struct sk_buff *skb,
 	if (!outdev)
 		return NF_DROP;
 
+	if (nf_flow_encap_push(skb, other_tuplehash, &type) < 0)
+		return NF_DROP;
+
 	skb->dev = outdev;
 	dev_hard_header(skb, skb->dev, type, tuplehash->tuple.out.h_dest,
 			tuplehash->tuple.out.h_source, skb->len);
@@ -458,7 +548,8 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 		ret = NF_STOLEN;
 		break;
 	case FLOW_OFFLOAD_XMIT_DIRECT:
-		ret = nf_flow_queue_xmit(state->net, skb, tuplehash, ETH_P_IP);
+		ret = nf_flow_queue_xmit(state->net, skb, tuplehash,
+					 &flow->tuplehash[!dir], ETH_P_IP);
 		if (ret == NF_DROP)
 			flow_offload_teardown(flow);
 		break;
@@ -753,7 +844,8 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
 		ret = NF_STOLEN;
 		break;
 	case FLOW_OFFLOAD_XMIT_DIRECT:
-		ret = nf_flow_queue_xmit(state->net, skb, tuplehash, ETH_P_IPV6);
+		ret = nf_flow_queue_xmit(state->net, skb, tuplehash,
+					 &flow->tuplehash[!dir], ETH_P_IPV6);
 		if (ret == NF_DROP)
 			flow_offload_teardown(flow);
 		break;
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index 7b84d8d3469c..cdf1771906b8 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -124,13 +124,12 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 				info->indev = NULL;
 				break;
 			}
-			if (!info->outdev)
-				info->outdev = path->dev;
 			info->encap[info->num_encaps].id = path->encap.id;
 			info->encap[info->num_encaps].proto = path->encap.proto;
 			info->num_encaps++;
 			if (path->type == DEV_PATH_PPPOE)
 				memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
+			info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
 			break;
 		case DEV_PATH_BRIDGE:
 			if (is_zero_ether_addr(info->h_source))
@@ -158,8 +157,7 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 			break;
 		}
 	}
-	if (!info->outdev)
-		info->outdev = info->indev;
+	info->outdev = info->indev;
 
 	info->hw_outdev = info->indev;
 
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:50 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:50 +0100
Subject: [PATCH RFC v3 net-next 02/13] netfilter: bridge: Add conntrack double vlan and pppoe
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-3-ericwouds@gmail.com>

This adds the capability to conntrack 802.1ad, QinQ, PPPoE and PPPoE-in-Q
packets that are passing a bridge.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 net/bridge/netfilter/nf_conntrack_bridge.c | 88 ++++++++++++++++++----
 1 file changed, 75 insertions(+), 13 deletions(-)

diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c
index 816bb0fde718..31e2bcd71735 100644
--- a/net/bridge/netfilter/nf_conntrack_bridge.c
+++ b/net/bridge/netfilter/nf_conntrack_bridge.c
@@ -241,56 +241,118 @@ static unsigned int nf_ct_bridge_pre(void *priv, struct sk_buff *skb,
 				     const struct nf_hook_state *state)
 {
 	struct nf_hook_state bridge_state = *state;
+	__be16 outer_proto, inner_proto;
 	enum ip_conntrack_info ctinfo;
+	int ret, offset = 0;
 	struct nf_conn *ct;
-	u32 len;
-	int ret;
+	u32 len, data_len;
 
 	ct = nf_ct_get(skb, &ctinfo);
 	if ((ct && !nf_ct_is_template(ct)) ||
 	    ctinfo == IP_CT_UNTRACKED)
 		return NF_ACCEPT;
 
+	switch (skb->protocol) {
+	case htons(ETH_P_PPP_SES): {
+		struct ppp_hdr {
+			struct pppoe_hdr hdr;
+			__be16 proto;
+		} *ph = (struct ppp_hdr *)(skb->data);
+
+		data_len = ntohs(ph->hdr.length) - 2;
+		offset = PPPOE_SES_HLEN;
+		outer_proto = skb->protocol;
+		switch (ph->proto) {
+		case htons(PPP_IP):
+			inner_proto = htons(ETH_P_IP);
+			break;
+		case htons(PPP_IPV6):
+			inner_proto = htons(ETH_P_IPV6);
+			break;
+		default:
+			return NF_ACCEPT;
+		}
+		break;
+	}
+	case htons(ETH_P_8021Q): {
+		struct vlan_hdr *vhdr = (struct vlan_hdr *)(skb->data);
+
+		data_len = 0xffffffff;
+		offset = VLAN_HLEN;
+		outer_proto = skb->protocol;
+		inner_proto = vhdr->h_vlan_encapsulated_proto;
+		break;
+	}
+	default:
+		data_len = 0xffffffff;
+		break;
+	}
+
+	if (offset) {
+		switch (inner_proto) {
+		case htons(ETH_P_IP):
+		case htons(ETH_P_IPV6):
+			if (!pskb_may_pull(skb, offset))
+				return NF_ACCEPT;
+			skb_pull_rcsum(skb, offset);
+			skb_reset_network_header(skb);
+			skb->protocol = inner_proto;
+			break;
+		default:
+			return NF_ACCEPT;
+		}
+	}
+
+	ret = NF_ACCEPT;
 	switch (skb->protocol) {
 	case htons(ETH_P_IP):
 		if (!pskb_may_pull(skb, sizeof(struct iphdr)))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		len = skb_ip_totlen(skb);
+		if (data_len < len)
+			len = data_len;
 		if (pskb_trim_rcsum(skb, len))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		if (nf_ct_br_ip_check(skb))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		bridge_state.pf = NFPROTO_IPV4;
 		ret = nf_ct_br_defrag4(skb, &bridge_state);
 		break;
 	case htons(ETH_P_IPV6):
 		if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len);
+		if (data_len < len)
+			len = data_len;
 		if (pskb_trim_rcsum(skb, len))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		if (nf_ct_br_ipv6_check(skb))
-			return NF_ACCEPT;
+			goto do_not_track;
 
 		bridge_state.pf = NFPROTO_IPV6;
 		ret = nf_ct_br_defrag6(skb, &bridge_state);
 		break;
 	default:
 		nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
-		return NF_ACCEPT;
+		goto do_not_track;
 	}
 
-	if (ret != NF_ACCEPT)
-		return ret;
+	if (ret == NF_ACCEPT)
+		ret = nf_conntrack_in(skb, &bridge_state);
 
-	return nf_conntrack_in(skb, &bridge_state);
+do_not_track:
+	if (offset) {
+		skb_push_rcsum(skb, offset);
+		skb_reset_network_header(skb);
+		skb->protocol = outer_proto;
+	}
+	return ret;
 }
-
 static unsigned int nf_ct_bridge_in(void *priv, struct sk_buff *skb,
 				    const struct nf_hook_state *state)
 {
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:51 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:51 +0100
Subject: [PATCH RFC v3 net-next 03/13] netfilter: nft_chain_filter: Add bridge double vlan and pppoe
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-4-ericwouds@gmail.com>

This adds the capability to evaluate 802.1ad, QinQ, PPPoE and PPPoE-in-Q
packets in the bridge filter chain.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 net/netfilter/nft_chain_filter.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c
index 7010541fcca6..91aa3fa43d31 100644
--- a/net/netfilter/nft_chain_filter.c
+++ b/net/netfilter/nft_chain_filter.c
@@ -232,11 +232,27 @@ nft_do_chain_bridge(void *priv,
 		    struct sk_buff *skb,
 		    const struct nf_hook_state *state)
 {
+	struct ethhdr *ethh = eth_hdr(skb);
 	struct nft_pktinfo pkt;
+	int thoff;
 
 	nft_set_pktinfo(&pkt, skb, state);
 
-	switch (eth_hdr(skb)->h_proto) {
+	switch (ethh->h_proto) {
+	case htons(ETH_P_PPP_SES):
+		thoff = PPPOE_SES_HLEN;
+		ethh += thoff;
+		break;
+	case htons(ETH_P_8021Q):
+		thoff = VLAN_HLEN;
+		ethh += thoff;
+		break;
+	default:
+		thoff = 0;
+		break;
+	}
+
+	switch (ethh->h_proto) {
 	case htons(ETH_P_IP):
 		nft_set_pktinfo_ipv4_validate(&pkt);
 		break;
@@ -248,6 +264,8 @@ nft_do_chain_bridge(void *priv,
 		break;
 	}
 
+	pkt.thoff += thoff;
+
 	return nft_do_chain(&pkt, priv);
 }
 
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:52 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:52 +0100
Subject: [PATCH RFC v3 net-next 04/13] bridge: Add filling forward path from port to port
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-5-ericwouds@gmail.com>

If a port is passed as argument instead of the master, then:

At br_fill_forward_path(): find the master and use it to fill the
forward path.

At br_vlan_fill_forward_path_pvid(): lookup vlan group from port
instead.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 net/bridge/br_device.c  | 19 ++++++++++++++-----
 net/bridge/br_private.h |  2 ++
 net/bridge/br_vlan.c    |  6 +++++-
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 0ab4613aa07a..c7646afc8b96 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -383,16 +383,25 @@ static int br_del_slave(struct net_device *dev, struct net_device *slave_dev)
 static int br_fill_forward_path(struct net_device_path_ctx *ctx,
 				struct net_device_path *path)
 {
+	struct net_bridge_port *src, *dst;
 	struct net_bridge_fdb_entry *f;
-	struct net_bridge_port *dst;
 	struct net_bridge *br;
 
-	if (netif_is_bridge_port(ctx->dev))
-		return -1;
+	if (netif_is_bridge_port(ctx->dev)) {
+		struct net_device *br_dev;
+
+		br_dev = netdev_master_upper_dev_get_rcu((struct net_device *)ctx->dev);
+		if (!br_dev)
+			return -1;
 
-	br = netdev_priv(ctx->dev);
+		src = br_port_get_rcu(ctx->dev);
+		br = netdev_priv(br_dev);
+	} else {
+		src = NULL;
+		br = netdev_priv(ctx->dev);
+	}
 
-	br_vlan_fill_forward_path_pvid(br, ctx, path);
+	br_vlan_fill_forward_path_pvid(br, src, ctx, path);
 
 	f = br_fdb_find_rcu(br, ctx->daddr, path->bridge.vlan_id);
 	if (!f)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 9853cfbb9d14..046d7b04771f 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1581,6 +1581,7 @@ bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr,
 			     const struct net_bridge_vlan *range_end);
 
 void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
+				    struct net_bridge_port *p,
 				    struct net_device_path_ctx *ctx,
 				    struct net_device_path *path);
 int br_vlan_fill_forward_path_mode(struct net_bridge *br,
@@ -1750,6 +1751,7 @@ static inline int nbp_get_num_vlan_infos(struct net_bridge_port *p,
 }
 
 static inline void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
+						  struct net_bridge_port *p,
 						  struct net_device_path_ctx *ctx,
 						  struct net_device_path *path)
 {
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 89f51ea4cabe..2ea1e2ff4676 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -1441,6 +1441,7 @@ int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid)
 EXPORT_SYMBOL_GPL(br_vlan_get_pvid_rcu);
 
 void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
+				    struct net_bridge_port *p,
 				    struct net_device_path_ctx *ctx,
 				    struct net_device_path *path)
 {
@@ -1453,7 +1454,10 @@ void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
 	if (!br_opt_get(br, BROPT_VLAN_ENABLED))
 		return;
 
-	vg = br_vlan_group(br);
+	if (p)
+		vg = nbp_vlan_group(p);
+	else
+		vg = br_vlan_group(br);
 
 	if (idx >= 0 &&
 	    ctx->vlan[idx].proto == br->vlan_proto) {
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:53 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:53 +0100
Subject: [PATCH RFC v3 net-next 05/13] net: core: dev: Add dev_fill_bridge_path()
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-6-ericwouds@gmail.com>

New function dev_fill_bridge_path(), similar to dev_fill_forward_path().
It handles starting from a bridge port instead of the bridge master.
The structures ctx and nft_forward_info need to be already filled in with
the (vlan) encaps.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 include/linux/netdevice.h |  2 ++
 net/core/dev.c            | 66 +++++++++++++++++++++++++++++++--------
 2 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 135105441681..6dbc442f9706 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3183,6 +3183,8 @@ void dev_remove_offload(struct packet_offload *po);
 
 int dev_get_iflink(const struct net_device *dev);
 int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb);
+int dev_fill_bridge_path(struct net_device_path_ctx *ctx,
+			 struct net_device_path_stack *stack);
 int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
 			  struct net_device_path_stack *stack);
 struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags,
diff --git a/net/core/dev.c b/net/core/dev.c
index c7f3dea3e0eb..01dc51abe7e8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -713,44 +713,84 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
 	return &stack->path[k];
 }
 
-int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
-			  struct net_device_path_stack *stack)
+static int dev_fill_forward_path_common(struct net_device_path_ctx *ctx,
+					struct net_device_path_stack *stack)
 {
 	const struct net_device *last_dev;
-	struct net_device_path_ctx ctx = {
-		.dev	= dev,
-	};
 	struct net_device_path *path;
 	int ret = 0;
 
-	memcpy(ctx.daddr, daddr, sizeof(ctx.daddr));
-	stack->num_paths = 0;
-	while (ctx.dev && ctx.dev->netdev_ops->ndo_fill_forward_path) {
-		last_dev = ctx.dev;
+	while (ctx->dev && ctx->dev->netdev_ops->ndo_fill_forward_path) {
+		last_dev = ctx->dev;
 		path = dev_fwd_path(stack);
 		if (!path)
 			return -1;
 
 		memset(path, 0, sizeof(struct net_device_path));
-		ret = ctx.dev->netdev_ops->ndo_fill_forward_path(&ctx, path);
+		ret = ctx->dev->netdev_ops->ndo_fill_forward_path(ctx, path);
 		if (ret < 0)
 			return -1;
 
-		if (WARN_ON_ONCE(last_dev == ctx.dev))
+		if (WARN_ON_ONCE(last_dev == ctx->dev))
 			return -1;
 	}
 
-	if (!ctx.dev)
+	if (!ctx->dev)
 		return ret;
 
 	path = dev_fwd_path(stack);
 	if (!path)
 		return -1;
 	path->type = DEV_PATH_ETHERNET;
-	path->dev = ctx.dev;
+	path->dev = ctx->dev;
 
 	return ret;
 }
+
+int dev_fill_bridge_path(struct net_device_path_ctx *ctx,
+			 struct net_device_path_stack *stack)
+{
+	const struct net_device *last_dev, *br_dev;
+	struct net_device_path *path;
+
+	stack->num_paths = 0;
+
+	if (!ctx->dev || !netif_is_bridge_port(ctx->dev))
+		return -1;
+
+	br_dev = netdev_master_upper_dev_get_rcu((struct net_device *)ctx->dev);
+	if (!br_dev || !br_dev->netdev_ops->ndo_fill_forward_path)
+		return -1;
+
+	last_dev = ctx->dev;
+	path = dev_fwd_path(stack);
+	if (!path)
+		return -1;
+
+	memset(path, 0, sizeof(struct net_device_path));
+	if (br_dev->netdev_ops->ndo_fill_forward_path(ctx, path) < 0)
+		return -1;
+
+	if (!ctx->dev || WARN_ON_ONCE(last_dev == ctx->dev))
+		return -1;
+
+	return dev_fill_forward_path_common(ctx, stack);
+}
+EXPORT_SYMBOL_GPL(dev_fill_bridge_path);
+
+int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
+			  struct net_device_path_stack *stack)
+{
+	struct net_device_path_ctx ctx = {
+		.dev	= dev,
+	};
+
+	memcpy(ctx.daddr, daddr, sizeof(ctx.daddr));
+
+	stack->num_paths = 0;
+
+	return dev_fill_forward_path_common(&ctx, stack);
+}
 EXPORT_SYMBOL_GPL(dev_fill_forward_path);
 
 /**
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:54 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:54 +0100
Subject: [PATCH RFC v3 net-next 06/13] netfilter :nf_flow_table_offload: Add nf_flow_rule_bridge()
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-7-ericwouds@gmail.com>

Add nf_flow_rule_bridge().

It only calls the common rule and adds the redirect.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 include/net/netfilter/nf_flow_table.h |  3 +++
 net/netfilter/nf_flow_table_offload.c | 13 +++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
index b63d53bb9dd6..568019a3898a 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -341,6 +341,9 @@ void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable);
 int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
 				struct net_device *dev,
 				enum flow_block_command cmd);
+int nf_flow_rule_bridge(struct net *net, struct flow_offload *flow,
+			enum flow_offload_tuple_dir dir,
+			struct nf_flow_rule *flow_rule);
 int nf_flow_rule_route_ipv4(struct net *net, struct flow_offload *flow,
 			    enum flow_offload_tuple_dir dir,
 			    struct nf_flow_rule *flow_rule);
diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index e06bc36f49fe..5543ce03a196 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -679,6 +679,19 @@ nf_flow_rule_route_common(struct net *net, const struct flow_offload *flow,
 	return 0;
 }
 
+int nf_flow_rule_bridge(struct net *net, struct flow_offload *flow,
+			enum flow_offload_tuple_dir dir,
+			struct nf_flow_rule *flow_rule)
+{
+	if (nf_flow_rule_route_common(net, flow, dir, flow_rule) < 0)
+		return -1;
+
+	flow_offload_redirect(net, flow, dir, flow_rule);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nf_flow_rule_bridge);
+
 int nf_flow_rule_route_ipv4(struct net *net, struct flow_offload *flow,
 			    enum flow_offload_tuple_dir dir,
 			    struct nf_flow_rule *flow_rule)
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:55 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:55 +0100
Subject: [PATCH RFC v3 net-next 07/13] netfilter: nf_flow_table_inet: Add nf_flowtable_type flowtable_bridge
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-8-ericwouds@gmail.com>

This will allow a flowtable to be added to the nft bridge family.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 net/netfilter/nf_flow_table_inet.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/net/netfilter/nf_flow_table_inet.c b/net/netfilter/nf_flow_table_inet.c
index b0f199171932..80b238196f29 100644
--- a/net/netfilter/nf_flow_table_inet.c
+++ b/net/netfilter/nf_flow_table_inet.c
@@ -65,6 +65,16 @@ static int nf_flow_rule_route_inet(struct net *net,
 	return err;
 }
 
+static struct nf_flowtable_type flowtable_bridge = {
+	.family		= NFPROTO_BRIDGE,
+	.init		= nf_flow_table_init,
+	.setup		= nf_flow_table_offload_setup,
+	.action		= nf_flow_rule_bridge,
+	.free		= nf_flow_table_free,
+	.hook		= nf_flow_offload_inet_hook,
+	.owner		= THIS_MODULE,
+};
+
 static struct nf_flowtable_type flowtable_inet = {
 	.family		= NFPROTO_INET,
 	.init		= nf_flow_table_init,
@@ -97,6 +107,7 @@ static struct nf_flowtable_type flowtable_ipv6 = {
 
 static int __init nf_flow_inet_module_init(void)
 {
+	nft_register_flowtable_type(&flowtable_bridge);
 	nft_register_flowtable_type(&flowtable_ipv4);
 	nft_register_flowtable_type(&flowtable_ipv6);
 	nft_register_flowtable_type(&flowtable_inet);
@@ -109,6 +120,7 @@ static void __exit nf_flow_inet_module_exit(void)
 	nft_unregister_flowtable_type(&flowtable_inet);
 	nft_unregister_flowtable_type(&flowtable_ipv6);
 	nft_unregister_flowtable_type(&flowtable_ipv4);
+	nft_unregister_flowtable_type(&flowtable_bridge);
 }
 
 module_init(nf_flow_inet_module_init);
@@ -118,5 +130,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Pablo Neira Ayuso <pablo at netfilter.org>");
 MODULE_ALIAS_NF_FLOWTABLE(AF_INET);
 MODULE_ALIAS_NF_FLOWTABLE(AF_INET6);
+MODULE_ALIAS_NF_FLOWTABLE(AF_BRIDGE);
 MODULE_ALIAS_NF_FLOWTABLE(1); /* NFPROTO_INET */
 MODULE_DESCRIPTION("Netfilter flow table mixed IPv4/IPv6 module");
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:56 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:56 +0100
Subject: [PATCH RFC v3 net-next 08/13] netfilter: nft_flow_offload: Add NFPROTO_BRIDGE to validate
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-9-ericwouds@gmail.com>

Need to add NFPROTO_BRIDGE to nft_flow_offload_validate() to support
the bridge-fastpath.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 net/netfilter/nft_flow_offload.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index cdf1771906b8..cce4c5980ed5 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -421,7 +421,8 @@ static int nft_flow_offload_validate(const struct nft_ctx *ctx,
 
 	if (ctx->family != NFPROTO_IPV4 &&
 	    ctx->family != NFPROTO_IPV6 &&
-	    ctx->family != NFPROTO_INET)
+	    ctx->family != NFPROTO_INET &&
+	    ctx->family != NFPROTO_BRIDGE)
 		return -EOPNOTSUPP;
 
 	return nft_chain_validate_hooks(ctx->chain, hook_mask);
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:57 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:57 +0100
Subject: [PATCH RFC v3 net-next 09/13] netfilter: nft_flow_offload: Add DEV_PATH_MTK_WDMA to nft_dev_path_info()
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-10-ericwouds@gmail.com>

In case of using mediatek wireless, in nft_dev_fill_forward_path(), the
forward path is filled, ending with mediatek wlan1.

Because DEV_PATH_MTK_WDMA is unknown inside nft_dev_path_info() it returns
with info.indev = NULL. Then nft_dev_forward_path() returns without
setting the direct transmit parameters.

This results in a neighbor transmit, and direct transmit not possible.
But we want to use it for flow between bridged interfaces.

So this patch adds DEV_PATH_MTK_WDMA to nft_dev_path_info() and makes
direct transmission possible.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 net/netfilter/nft_flow_offload.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index cce4c5980ed5..f7c2692ff3f2 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -106,6 +106,7 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 		switch (path->type) {
 		case DEV_PATH_ETHERNET:
 		case DEV_PATH_DSA:
+		case DEV_PATH_MTK_WDMA:
 		case DEV_PATH_VLAN:
 		case DEV_PATH_PPPOE:
 			info->indev = path->dev;
@@ -118,6 +119,10 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 				i = stack->num_paths;
 				break;
 			}
+			if (path->type == DEV_PATH_MTK_WDMA) {
+				i = stack->num_paths;
+				break;
+			}
 
 			/* DEV_PATH_VLAN and DEV_PATH_PPPOE */
 			if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:44:58 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:44:58 +0100
Subject: [PATCH RFC v3 net-next 10/13] netfilter: nft_flow_offload: No ingress_vlan forward info for dsa user port
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-11-ericwouds@gmail.com>

The bitfield info->ingress_vlans and correcponding vlan encap are used for
a switchdev user port. However, they should not be set for a dsa user port.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 net/netfilter/nft_flow_offload.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index f7c2692ff3f2..387e5574c31f 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -117,6 +117,11 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 				break;
 			if (path->type == DEV_PATH_DSA) {
 				i = stack->num_paths;
+				if (!info->num_encaps ||
+				    !(info->ingress_vlans & BIT(info->num_encaps - 1)))
+					break;
+				info->num_encaps--;
+				info->ingress_vlans &= ~BIT(info->num_encaps - 1);
 				break;
 			}
 			if (path->type == DEV_PATH_MTK_WDMA) {
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:45:00 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:45:00 +0100
Subject: [PATCH RFC v3 net-next 12/13] bridge: Introduce DEV_PATH_BR_VLAN_KEEP_HW for bridge-fastpath
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-13-ericwouds@gmail.com>

This patch introduces DEV_PATH_BR_VLAN_KEEP_HW. It is needed in the
bridge fastpath for switchdevs supporting SWITCHDEV_OBJ_ID_PORT_VLAN.

It is similar to DEV_PATH_BR_VLAN_TAG, with the correcponding bit in
ingress_vlans set.

In the forward fastpath it is not needed.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 include/linux/netdevice.h        |  1 +
 net/bridge/br_device.c           |  4 ++++
 net/bridge/br_vlan.c             | 18 +++++++++++-------
 net/netfilter/nft_flow_offload.c |  3 +++
 4 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 6dbc442f9706..8be40145c1d9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -870,6 +870,7 @@ struct net_device_path {
 				DEV_PATH_BR_VLAN_TAG,
 				DEV_PATH_BR_VLAN_UNTAG,
 				DEV_PATH_BR_VLAN_UNTAG_HW,
+				DEV_PATH_BR_VLAN_KEEP_HW,
 			}		vlan_mode;
 			u16		vlan_id;
 			__be16		vlan_proto;
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index c7646afc8b96..112fd8556217 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -430,6 +430,10 @@ static int br_fill_forward_path(struct net_device_path_ctx *ctx,
 	case DEV_PATH_BR_VLAN_UNTAG:
 		ctx->num_vlans--;
 		break;
+	case DEV_PATH_BR_VLAN_KEEP_HW:
+		if (!src)
+			path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
+		break;
 	case DEV_PATH_BR_VLAN_KEEP:
 		break;
 	}
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 0decce5d586a..6a2ca7a5854d 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -1494,13 +1494,17 @@ int br_vlan_fill_forward_path_mode(struct net_bridge *br,
 	if (!(v->flags & BRIDGE_VLAN_INFO_UNTAGGED))
 		return 0;
 
-	if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
-		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
-	else if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
-		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
-	else
-		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
-
+	if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG) {
+		if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
+			path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP_HW;
+		else
+			path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
+	} else {
+		if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV)
+			path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
+		else
+			path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
+	}
 	return 0;
 }
 
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index 387e5574c31f..ed0e9b499971 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -149,6 +149,9 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
 			case DEV_PATH_BR_VLAN_UNTAG_HW:
 				info->ingress_vlans |= BIT(info->num_encaps - 1);
 				break;
+			case DEV_PATH_BR_VLAN_KEEP_HW:
+				info->ingress_vlans |= BIT(info->num_encaps);
+				fallthrough;
 			case DEV_PATH_BR_VLAN_TAG:
 				info->encap[info->num_encaps].id = path->bridge.vlan_id;
 				info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
-- 
2.47.1



From ericwouds at gmail.com  Tue Dec 10 01:45:01 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 10 Dec 2024 10:45:01 +0100
Subject: [PATCH RFC v3 net-next 13/13] netfilter: nft_flow_offload: Add bridgeflow to nft_flow_offload_eval()
In-Reply-To: <20241210094501.3069-1-ericwouds@gmail.com>
References: <20241210094501.3069-1-ericwouds@gmail.com>
Message-ID: <20241210094501.3069-14-ericwouds@gmail.com>

Edit nft_flow_offload_eval() to make it possible to handle a flowtable of
the nft bridge family.

Use nft_flow_offload_bridge_init() to fill the flow tuples. It uses
nft_dev_fill_bridge_path() in each direction.

Signed-off-by: Eric Woudstra <ericwouds at gmail.com>
---
 net/netfilter/nft_flow_offload.c | 144 +++++++++++++++++++++++++++++--
 1 file changed, 139 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index ed0e9b499971..b17a3ef79852 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -196,6 +196,131 @@ static bool nft_flowtable_find_dev(const struct net_device *dev,
 	return found;
 }
 
+static int nft_dev_fill_bridge_path(struct flow_offload *flow,
+				    struct nft_flowtable *ft,
+				    const struct nft_pktinfo *pkt,
+				    enum ip_conntrack_dir dir,
+				    const struct net_device *src_dev,
+				    const struct net_device *dst_dev,
+				    unsigned char *src_ha,
+				    unsigned char *dst_ha)
+{
+	struct flow_offload_tuple_rhash *th = flow->tuplehash;
+	struct net_device_path_stack stack;
+	struct net_device_path_ctx ctx = {};
+	struct nft_forward_info info = {};
+	int i, j = 0;
+
+	for (i = th[dir].tuple.encap_num - 1; i >= 0 ; i--) {
+		if (info.num_encaps >= NF_FLOW_TABLE_ENCAP_MAX)
+			return -1;
+
+		if (th[dir].tuple.in_vlan_ingress & BIT(i))
+			continue;
+
+		info.encap[info.num_encaps].id = th[dir].tuple.encap[i].id;
+		info.encap[info.num_encaps].proto = th[dir].tuple.encap[i].proto;
+		info.num_encaps++;
+
+		if (th[dir].tuple.encap[i].proto == htons(ETH_P_PPP_SES))
+			continue;
+
+		if (ctx.num_vlans >= NET_DEVICE_PATH_VLAN_MAX)
+			return -1;
+		ctx.vlan[ctx.num_vlans].id = th[dir].tuple.encap[i].id;
+		ctx.vlan[ctx.num_vlans].proto = th[dir].tuple.encap[i].proto;
+		ctx.num_vlans++;
+	}
+	ctx.dev = src_dev;
+	ether_addr_copy(ctx.daddr, dst_ha);
+
+	if (dev_fill_bridge_path(&ctx, &stack) < 0)
+		return -1;
+
+	nft_dev_path_info(&stack, &info, dst_ha, &ft->data);
+
+	if (!info.indev || info.indev != dst_dev)
+		return -1;
+
+	th[!dir].tuple.iifidx = info.indev->ifindex;
+	for (i = info.num_encaps - 1; i >= 0; i--) {
+		th[!dir].tuple.encap[j].id = info.encap[i].id;
+		th[!dir].tuple.encap[j].proto = info.encap[i].proto;
+		if (info.ingress_vlans & BIT(i))
+			th[!dir].tuple.in_vlan_ingress |= BIT(j);
+		j++;
+	}
+	th[!dir].tuple.encap_num = info.num_encaps;
+
+	th[dir].tuple.mtu = dst_dev->mtu;
+	ether_addr_copy(th[dir].tuple.out.h_source, src_ha);
+	ether_addr_copy(th[dir].tuple.out.h_dest, dst_ha);
+	th[dir].tuple.out.ifidx = info.outdev->ifindex;
+	th[dir].tuple.out.hw_ifidx = info.hw_outdev->ifindex;
+	th[dir].tuple.xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
+
+	return 0;
+}
+
+static int nft_flow_offload_bridge_init(struct flow_offload *flow,
+					const struct nft_pktinfo *pkt,
+					enum ip_conntrack_dir dir,
+					struct nft_flowtable *ft)
+{
+	struct ethhdr *eth = eth_hdr(pkt->skb);
+	struct flow_offload_tuple *tuple;
+	const struct net_device *out_dev;
+	const struct net_device *in_dev;
+	struct pppoe_hdr *phdr;
+	struct vlan_hdr *vhdr;
+	int err, i = 0;
+
+	in_dev = nft_in(pkt);
+	if (!in_dev || !nft_flowtable_find_dev(in_dev, ft))
+		return -1;
+
+	out_dev = nft_out(pkt);
+	if (!out_dev || !nft_flowtable_find_dev(out_dev, ft))
+		return -1;
+
+	tuple =  &flow->tuplehash[!dir].tuple;
+
+	if (skb_vlan_tag_present(pkt->skb)) {
+		tuple->encap[i].id = skb_vlan_tag_get(pkt->skb);
+		tuple->encap[i].proto = pkt->skb->vlan_proto;
+		i++;
+	}
+	switch (pkt->skb->protocol) {
+	case htons(ETH_P_8021Q):
+		vhdr = (struct vlan_hdr *)skb_network_header(pkt->skb);
+		tuple->encap[i].id = ntohs(vhdr->h_vlan_TCI);
+		tuple->encap[i].proto = pkt->skb->protocol;
+		i++;
+		break;
+	case htons(ETH_P_PPP_SES):
+		phdr = (struct pppoe_hdr *)skb_network_header(pkt->skb);
+		tuple->encap[i].id = ntohs(phdr->sid);
+		tuple->encap[i].proto = pkt->skb->protocol;
+		i++;
+		break;
+	}
+	tuple->encap_num = i;
+
+	err = nft_dev_fill_bridge_path(flow, ft, pkt, !dir, out_dev, in_dev,
+				       eth->h_dest, eth->h_source);
+	if (err < 0)
+		return err;
+
+	memset(tuple->encap, 0, sizeof(tuple->encap));
+
+	err = nft_dev_fill_bridge_path(flow, ft, pkt, dir, in_dev, out_dev,
+				       eth->h_source, eth->h_dest);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 static void nft_dev_forward_path(struct nf_flow_route *route,
 				 const struct nf_conn *ct,
 				 enum ip_conntrack_dir dir,
@@ -306,6 +431,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
 {
 	struct nft_flow_offload *priv = nft_expr_priv(expr);
 	struct nf_flowtable *flowtable = &priv->flowtable->data;
+	bool routing = (flowtable->type->family != NFPROTO_BRIDGE);
 	struct tcphdr _tcph, *tcph = NULL;
 	struct nf_flow_route route = {};
 	enum ip_conntrack_info ctinfo;
@@ -359,14 +485,20 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
 		goto out;
 
 	dir = CTINFO2DIR(ctinfo);
-	if (nft_flow_route(pkt, ct, &route, dir, priv->flowtable) < 0)
-		goto err_flow_route;
+	if (routing) {
+		if (nft_flow_route(pkt, ct, &route, dir, priv->flowtable) < 0)
+			goto err_flow_route;
+	}
 
 	flow = flow_offload_alloc(ct);
 	if (!flow)
 		goto err_flow_alloc;
 
-	flow_offload_route_init(flow, &route);
+	if (routing)
+		flow_offload_route_init(flow, &route);
+	else
+		if (nft_flow_offload_bridge_init(flow, pkt, dir, priv->flowtable) < 0)
+			goto err_flow_route;
 
 	if (tcph) {
 		ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
@@ -419,8 +551,10 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
 err_flow_add:
 	flow_offload_free(flow);
 err_flow_alloc:
-	dst_release(route.tuple[dir].dst);
-	dst_release(route.tuple[!dir].dst);
+	if (routing) {
+		dst_release(route.tuple[dir].dst);
+		dst_release(route.tuple[!dir].dst);
+	}
 err_flow_route:
 	clear_bit(IPS_OFFLOAD_BIT, &ct->status);
 out:
-- 
2.47.1



From shijie at amperemail.onmicrosoft.com  Tue Dec 10 01:47:05 2024
From: shijie at amperemail.onmicrosoft.com (Shijie Huang)
Date: Tue, 10 Dec 2024 17:47:05 +0800
Subject: [PATCH v3 1/2] arm64: refactor the rodata=xxx
In-Reply-To: <0224b253-5eae-4921-a066-308033396a73@arm.com>
References: <20241209072020.4743-1-shijie@os.amperecomputing.com>
 <20241209072020.4743-2-shijie@os.amperecomputing.com>
 <d13f1879-7fbc-458d-8fd3-4340b51165fd@arm.com>
 <CAMj1kXFJhFfhy=Gwm=QrdN6XPUd=7SKNKFBF_Z4eQ30r509BCg@mail.gmail.com>
 <0224b253-5eae-4921-a066-308033396a73@arm.com>
Message-ID: <808ed933-fbc6-4ace-812c-08170b51d699@amperemail.onmicrosoft.com>


On 2024/12/10 16:38, Anshuman Khandual wrote:
>
> On 12/10/24 12:51, Ard Biesheuvel wrote:
>> On Tue, 10 Dec 2024 at 08:17, Anshuman Khandual
>> <anshuman.khandual at arm.com> wrote:
>> ...
>>> Reformatted and cleaned up the above comment a bit but feel free to
>>> improve it further.
>>>
>>> /*
>>>   * rodata=on (default)
>>>   *
>>>   *    This applies read-only attributes to VM areas and to the linear
>>>   *    alias of the backing pages as well. This prevents code or read-
>>>   *    only data from being modified (inadvertently or intentionally),
>>>   *    via another mapping for the same memory page.
>>>   *
>>>   *    But this might cause linear map region to be mapped down to base
>>>   *    pages, which may adversely affect performance in some cases.
>>>   *
>>>   * rodata=off
>>>   *
>>>   *    This provides more block mappings and contiguous hints for linear
>>>   *    map region which would minimize TLB footprint. This also leaves
>>>   *    read-only kernel memory writable for debugging.
>>>   *
>>>   * rodata=noalias
>>>   *
>>>   *    This provides more block mappings and contiguous hints for linear
>>>   *    map region which would minimize TLB footprint. Linear aliases of
>>>   *    pages belonging to read-only mappings in vmalloc region are also
>>>   *    marked as read-only.
>>>
>> If linear aliases are marked as read-only, how does 'noalias' differ from 'on'?
> Right, the last sentence can be can dropped.

Okay, no problem.


Thanks

Huang Shijie



From maz at kernel.org  Tue Dec 10 01:49:37 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Dec 2024 09:49:37 +0000
Subject: [RFC PATCH 05/14] KVM: arm64: Always allow fixed cycle counter
In-Reply-To: <Z1DQKg02tebLmGsO@linux.dev>
References: <20241203193220.1070811-1-oliver.upton@linux.dev>
	<20241203193220.1070811-6-oliver.upton@linux.dev>
	<87ldwwsbad.wl-maz@kernel.org>
	<Z0-HBsBgf6WB7x4R@linux.dev>
	<87ikrzstt1.wl-maz@kernel.org>
	<Z1DQKg02tebLmGsO@linux.dev>
Message-ID: <86wmg7sw9a.wl-maz@kernel.org>

On Wed, 04 Dec 2024 21:56:58 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Wed, Dec 04, 2024 at 09:04:26AM +0000, Marc Zyngier wrote:
> > On Tue, 03 Dec 2024 22:32:38 +0000,
> > Oliver Upton <oliver.upton at linux.dev> wrote:
> > > > More importantly, the current filtering works in terms of events, and
> > > > not in terms of counters.
> > > > 
> > > > Instead of changing the ABI, how about simply not supporting filtering
> > > > on such non-compliant HW? Surely that would simplify a few things.
> > > 
> > > Yeah, that sounds reasonable. Especially if we allow programmable event
> > > counters where the event ID space doesn't match the architecture.
> > 
> > Another thing I have been wondering is if a slightly better approach
> > would be to move some of the handling to the PMU driver itself, and
> > let it emulate PMUv3 if it can. This would allow conversion of event
> > numbers in situ rather than polluting the PMUv3 code in KVM.
> 
> Sure, but I think the actual event fed into perf_event_create_kernel_counter()
> should be the correct hardware event, not a PMUv3 event reinterpreted
> behind the scenes. Otherwise, we'd need to devise an alternate config encoding
> for PMUv3-like events since the event ID spaces overlap.
> 
> I'm thinking this could be a helper in the arm_pmu struct that takes a
> PMUv3 event and spits out (in this case) an M1 event. The resulting KVM
> code would be miniscule, like:
> 
> u64 kvm_map_pmu_event(struct kvm *kvm, u64 eventsel)
> {
> 	struct arm_pmu *pmu = kvm->arch.arm_pmu;
> 
> 	if (!pmu->map_pmuv3_event)
> 		return eventsel;
> 
> 	return pmu->map_pmuv3_event(eventsel);
> }
> 
> static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc)
> {
> 
> 	[...]
> 
> 	attr.config = kvm_map_pmu_event(vcpu->kvm, eventsel);
> 	event = perf_event_create_kernel_counter(&attr, ...);
> }
> 
> We could even have the M1 PMU driver populate arm_pmu->pmceid_bitmap
> with the events it knows about and get PMCEID emulation for free.

CONFIG_PMUv3_COMPAT? ;-)

I think this is probably the less intrusive thing to do for KVM
(outside of the butt-ugly trap decoding thingy), and it squarely puts
the responsibility on the PMU driver to expose something that makes
sense in a given context.

Thanks,

	M.

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


From guoqing.jiang at canonical.com  Tue Dec 10 01:49:41 2024
From: guoqing.jiang at canonical.com (Guoqing Jiang)
Date: Tue, 10 Dec 2024 17:49:41 +0800
Subject: [PATCH] drm/mediatek: Set private->all_drm_private[i]->drm to
 NULL if mtk_drm_bind returns err
In-Reply-To: <3670b4af699a1c12000f09d671e93e3ae7359724.camel@mediatek.com>
References: <20241206135507.1274357-1-guoqing.jiang@canonical.com>
 <3670b4af699a1c12000f09d671e93e3ae7359724.camel@mediatek.com>
Message-ID: <0ba499c2-5f59-4a27-98ae-aa118b7f130c@canonical.com>

Hi,

On 12/10/24 17:16, CK Hu (???) wrote:
> Hi, Guoqing:
>
> On Fri, 2024-12-06 at 21:55 +0800, Guoqing Jiang wrote:
>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>
>>
>> The pointer need to be set to NULL, otherwise KASAN complains about
>> use-after-free. Because in mtk_drm_bind, all private's drm are set
>> as follows.
>>
>> private->all_drm_private[i]->drm = drm;
>>
>> And drm will be released by drm_dev_put in case mtk_drm_kms_init returns
>> failure. However, the shutdown path still accesses the previous allocated
>> memory in drm_atomic_helper_shutdown.
>>
>> [   84.874820] watchdog: watchdog0: watchdog did not stop!
>> [   86.512054] ==================================================================
>> [   86.513162] BUG: KASAN: use-after-free in drm_atomic_helper_shutdown+0x33c/0x378
>> [   86.514258] Read of size 8 at addr ffff0000d46fc068 by task shutdown/1
>> [   86.515213]
>> [   86.515455] CPU: 1 UID: 0 PID: 1 Comm: shutdown Not tainted 6.13.0-rc1-mtk+gfa1a78e5d24b-dirty #55
>> [   86.516752] Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10 10/01/2022
>> [   86.517960] Call trace:
>> [   86.518333]  show_stack+0x20/0x38 (C)
>> [   86.518891]  dump_stack_lvl+0x90/0xd0
>> [   86.519443]  print_report+0xf8/0x5b0
>> [   86.519985]  kasan_report+0xb4/0x100
>> [   86.520526]  __asan_report_load8_noabort+0x20/0x30
>> [   86.521240]  drm_atomic_helper_shutdown+0x33c/0x378
>> [   86.521966]  mtk_drm_shutdown+0x54/0x80
>> [   86.522546]  platform_shutdown+0x64/0x90
>> [   86.523137]  device_shutdown+0x260/0x5b8
>> [   86.523728]  kernel_restart+0x78/0xf0
>> [   86.524282]  __do_sys_reboot+0x258/0x2f0
>> [   86.524871]  __arm64_sys_reboot+0x90/0xd8
>> [   86.525473]  invoke_syscall+0x74/0x268
>> [   86.526041]  el0_svc_common.constprop.0+0xb0/0x240
>> [   86.526751]  do_el0_svc+0x4c/0x70
>> [   86.527251]  el0_svc+0x4c/0xc0
>> [   86.527719]  el0t_64_sync_handler+0x144/0x168
>> [   86.528367]  el0t_64_sync+0x198/0x1a0
>> [   86.528920]
>> [   86.529157] The buggy address belongs to the physical page:
>> [   86.529972] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff0000d46fd4d0 pfn:0x1146fc
>> [   86.531319] flags: 0xbfffc0000000000(node=0|zone=2|lastcpupid=0xffff)
>> [   86.532267] raw: 0bfffc0000000000 0000000000000000 dead000000000122 0000000000000000
>> [   86.533390] raw: ffff0000d46fd4d0 0000000000000000 00000000ffffffff 0000000000000000
>> [   86.534511] page dumped because: kasan: bad access detected
>> [   86.535323]
>> [   86.535559] Memory state around the buggy address:
>> [   86.536265]  ffff0000d46fbf00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>> [   86.537314]  ffff0000d46fbf80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>> [   86.538363] >ffff0000d46fc000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>> [   86.544733]                                                           ^
>> [   86.551057]  ffff0000d46fc080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>> [   86.557510]  ffff0000d46fc100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>> [   86.563928] ==================================================================
>> [   86.571093] Disabling lock debugging due to kernel taint
>> [   86.577642] Unable to handle kernel paging request at virtual address e0e9c0920000000b
>> [   86.581834] KASAN: maybe wild-memory-access in range [0x0752049000000058-0x075204900000005f]
>> ...
> Refer to [1] to add Fixes tag.
>
> [1] https://www.kernel.org/doc/html/v6.12/process/submitting-patches.html

Thanks for reminder! I think the problem is caused by commit 
1ef7ed48356c, so

Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi 
mmsys support")

And before send a new version with the tag, I will wait a few days for 
other comments.

Thanks,
Guoqing


From sudeep.holla at arm.com  Tue Dec 10 01:49:58 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 10 Dec 2024 09:49:58 +0000
Subject: [PATCH v2 2/2] firmware/arm_ffa: remove __le64_to_cpu() when set
 uuid for direct msg v2
In-Reply-To: <0cb655ee-9401-41bb-b9cd-580e0aeef2be@app.fastmail.com>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
 <20241203143109.1030514-3-yeoreum.yun@arm.com>
 <9e60e996-070e-43a7-80e9-efdfda9f6223@app.fastmail.com>
 <Z1ch52AthTYVhtH4@bogus>
 <0cb655ee-9401-41bb-b9cd-580e0aeef2be@app.fastmail.com>
Message-ID: <Z1gOxjyEajxkyHnT@bogus>

On Mon, Dec 09, 2024 at 09:04:30PM +0100, Arnd Bergmann wrote:
> On Mon, Dec 9, 2024, at 17:59, Sudeep Holla wrote:
> > On Mon, Dec 09, 2024 at 04:27:14PM +0100, Arnd Bergmann wrote:
> >
> >> > That means, we don't need to swap the uuid when it send via direct
> >> > message request version 2, just send it as saved in memory.
> >>
> >> "As saved in memory" does not sound like a useful description
> >> when passing arguments through registers, as the register
> >> contents are not defined in terms of byte offsets.
> >>
> >
> > Well I didn't know how to term it. The structure UUID is a raw buffer
> > and it provide helpers to import/export the data in/out of it. So in LE
> > kernel IIUC, it is stored in LE format itself which was my initial
> > confusion and hence though what you fixed was correct previously.
> 
> The way I would phrase it, the UUID is never "stored" in
> big-endian or little-endian format, it's just remains a string
> of bytes. The endianess becomes a choice only when loading it
> into registers for passing the argument to firmware, and it's
> the firmware that mandates little-endian in the specification.
>

Thanks, I will add such a note when I get BE support fixed so that it is
clear.

> >> Can you describe what bug you found? If the byteorder on
> >> big-endian kernels is wrong in the current version and your
> >> patch fixes it, it sounds like the specification needs to
> >> be updated describe both big-endian and little-endian
> >> byte-order, and how the firmware detects which one is used.
> >>
> >
> > The firmware interface understands only LE format. And by default UUID
> > is stored in LE format itself in the structure which I got confused
> > initially. We may need endian conversion at places(found few when trying
> > to get it working with BE kernel).
> >
> > I wanted to check with you about this. The current driver doesn't
> > work with BE. I tried to cook up patches but then the upstream user
> > of this driver OPTEE doesn't work in BE, so I hit a roadblock to fully
> > validate my changes. I don't see any driver adding endianness dependency
> > in the Kconfig if they can't work with BE, not sure if that
> > is intentional or just don't care. I was thinking if we can disable
> > it to build in BE kernel until the actual support was added.
> 
> I think as long big-endian kernels remain an option on arm64, we
> should try to to write portable code and implement the specification
> The reality of course is that very few people care these days, and
> it's getting harder to test over time.
>

Indeed. I do run SCMI once in a while but hadn't tried FF-A so far for no
particular reasons. I will get that sorted this time.

> > So the current FF-A driver just supports LE and the bug was found just
> > in LE kernel itself.
> 
> What is the bug and how was it found? The only thing I see in
> the patch here is to change the code from portable to nonportable,
> but not actually change behavior on little-endian 64-bit.
>

OK you are right, I clearly got confused. There should be something
else messed up in the setup. I think fixing BE support will avoid such
things in the future, I will get on that ASAP. Sorry for the confusion.

I just dumped the buffers and UUID and it works as expected, so I blindly
assumed the firmware setup is correct and there is a bug.

> Looking through the other functions in drivers/firmware/arm_ffa/driver.c,
> I see that most of them just match the specification. One exception
> is ffa_notification_info_get(), which incorrectly casts the
> argument response arguments to an array of 'u16' values. Using
> the correct bit shifts according to the specification would
> make that work on big-endian and also more readable and
> robust. Another one is __ffa_partition_info_get_regs(), which
> does an incorrect memcpy() instead of decoding the values.

Yes these are 2 main changes I have. I think I had one more but I need to
go back and check. I plan to post them once I have done the testing with
OPTEE. I just want to run xtest they have and see if everything works for
which I may need to spend sometime.

-- 
Regards,
Sudeep


From sudeep.holla at arm.com  Tue Dec 10 02:08:41 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 10 Dec 2024 10:08:41 +0000
Subject: [PATCH v2 2/2] firmware/arm_ffa: remove __le64_to_cpu() when set
 uuid for direct msg v2
In-Reply-To: <d750f114-8a25-4c84-912e-b6fb407a5150@app.fastmail.com>
References: <20241203143109.1030514-1-yeoreum.yun@arm.com>
 <20241203143109.1030514-3-yeoreum.yun@arm.com>
 <9e60e996-070e-43a7-80e9-efdfda9f6223@app.fastmail.com>
 <Z1ch52AthTYVhtH4@bogus>
 <0cb655ee-9401-41bb-b9cd-580e0aeef2be@app.fastmail.com>
 <Z1fvkpYvqpnjPZA8@e129823.arm.com>
 <d750f114-8a25-4c84-912e-b6fb407a5150@app.fastmail.com>
Message-ID: <Z1gTKRZGyE7VuJo0@bogus>

On Tue, Dec 10, 2024 at 09:45:51AM +0100, Arnd Bergmann wrote:
> On Tue, Dec 10, 2024, at 08:36, Yeoreum Yun wrote:
> >> On Mon, Dec 9, 2024, at 17:59, Sudeep Holla wrote:
> >> > On Mon, Dec 09, 2024 at 04:27:14PM +0100, Arnd Bergmann wrote:
> >>
> >> Looking through the other functions in drivers/firmware/arm_ffa/driver.c,
> >> I see that most of them just match the specification. One exception
> >> is ffa_notification_info_get(), which incorrectly casts the
> >> argument response arguments to an array of 'u16' values. Using
> >> the correct bit shifts according to the specification would
> >> make that work on big-endian and also more readable and
> >> robust. Another one is __ffa_partition_info_get_regs(), which
> >> does an incorrect memcpy() instead of decoding the values.
> >>
> > Conclusionly, Yes. But the RFC 4122 said with network byte order.
> > to describe how uuid is saved.
> >
> > but I think the endianess to load the register is not a choice.
> > because the spec says:
> >
> >     UUID Lo  x2  Bytes[0...7] of UUID with byte 0 in the low-order bits.
> >     UUID Hi  x3  Bytes[8...15] of UUID with byte 8 in the low-order bits.
> >
> > this means UUID.bytes[0] should be loaded to x2.bytes[0].
> >            UUID.bytes[1] should be loaded to x2,bytes[1]
> >            ...
> 
> I meant they had the choice and chose to specify little-endian
> 64-bit word to encode the sequence of bytes of the standard
> in-memory representation of UUIDs. 
> 
> > That's why other software spec (i.e tf-a) doesn't loads UUID from register
> > wihtout swapping byte with endianess but just copy it.
> 
> If the uuid is transferred in memory, you obviously don't want to
> swap it. If they pass it in registers across different endianess
> code without specifying the byteorder in the caller, then they
> would have the same bug.
> 
> > The bug is "not send UUID according to spec" in kernel side
> > That's why it fails when I send message  with direct message version 2.
> > So, it''s not change code unportable to portable but it fixes according
> > to spec (load UUID as it is in register wihtout endianess).
> 
> Sorry, but you are not making sense here.
>

Agreed. The patch is clearly wrong. Thanks for refreshing my knowledge and
helping me to clear my confusion.

> Sudeep, should I just cherry-pick your other fix from the pull
> request and ignore this patch?
>

I will remove the wrong patch and retag and send PR if that helps. It should
be quick.

-- 
Regards,
Sudeep


From sudeep.holla at arm.com  Tue Dec 10 02:11:13 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 10 Dec 2024 10:11:13 +0000
Subject: [GIT PULL v2] firmware: arm_ffa: Fix for v6.13
Message-ID: <20241210101113.3232602-1-sudeep.holla@arm.com>

Hi ARM SoC Team,

Please pull ! Sorry for the confusion, this is updated PR with wrong patch
dropped.

Regards,
Sudeep

-->8

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/ffa-fix-6.13

for you to fetch changes up to 6fe437cfe2cdc797b03f63b338a13fac96ed6a08:

  firmware: arm_ffa: Fix the race around setting ffa_dev->properties (2024-12-04 09:59:54 +0000)

----------------------------------------------------------------
Arm FF-A fix for v6.13

A single fix to address a possible race around setting ffa_dev->properties
in ffa_device_register() by updating ffa_device_register() to take all
the partition information received from the firmware and updating the
struct ffa_device accordingly before registering the device to the
bus/driver model in the kernel.

----------------------------------------------------------------
Levi Yun (1):
      firmware: arm_ffa: Fix the race around setting ffa_dev->properties

 drivers/firmware/arm_ffa/bus.c    | 15 +++++++++++----
 drivers/firmware/arm_ffa/driver.c |  7 +------
 include/linux/arm_ffa.h           | 13 ++++++++-----
 3 files changed, 20 insertions(+), 15 deletions(-)


From didi.debian at cknow.org  Tue Dec 10 02:11:09 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Tue, 10 Dec 2024 11:11:09 +0100
Subject: [PATCH v5 2/4] dt-bindings: media: Document bindings for HDMI
 RX Controller
In-Reply-To: <01020193ad040150-e0cf3371-115b-469e-840e-4fa97af5b207-000000@eu-west-1.amazonses.com>
References: <20241209200120.3228643-1-shreeya.patel@collabora.com>
 <01020193ad040150-e0cf3371-115b-469e-840e-4fa97af5b207-000000@eu-west-1.amazonses.com>
Message-ID: <D67XU0SO4U6D.2GTDZE4V7RK0J@cknow.org>

Hi,

On Mon Dec 9, 2024 at 9:02 PM CET, Shreeya Patel wrote:
> Document bindings for the Synopsys DesignWare HDMI RX Controller.
>
> Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
> Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
> ---
>
> Changes in v5 :-
> - Correct the interrupt IRQ number
>
> Changes in v4 :-
> - No change
>
> Changes in v3 :-
> - Rename hdmirx_cma to hdmi_receiver_cma
> - Add a Reviewed-by tag
>
> Changes in v2 :-
> - Add a description for the hardware
> - Rename resets, vo1 grf and HPD properties
> - Add a proper description for grf and vo1-grf phandles
> - Rename the HDMI Input node name to hdmi-receiver
> - Improve the subject line
> - Include gpio header file in example to fix dt_binding_check failure
>
>  .../bindings/media/snps,dw-hdmi-rx.yaml       | 132 ++++++++++++++++++
>  1 file changed, 132 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..510e94e9ca3a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
> @@ -0,0 +1,132 @@
> +# SPDX-License-Identifier: (GPL-2.0-only 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>
> +
> +description:
> +  Synopsys DesignWare HDMI Input Controller preset on RK3588 SoCs

s/preset/present/ ?

> +  allowing devices to receive and decode high-resolution video streams
> +  from external sources like media players, cameras, laptops, etc.
> +
> +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: axi
> +      - const: apb
> +      - const: ref
> +      - const: biu
> +
> +  memory-region:
> +    maxItems: 1
> +
> +  hpd-gpios:
> +    description: GPIO specifier for HPD.
> +    maxItems: 1
> +
> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the general register file
> +      containing HDMIRX PHY status bits.
> +
> +  rockchip,vo1-grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the Video Output GRF register
> +      to enable EDID transfer through SDAIN and SCLIN.
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - interrupt-names
> +  - clocks
> +  - clock-names
> +  - power-domains
> +  - resets
> +  - pinctrl-0
> +  - hpd-gpios
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/power/rk3588-power.h>
> +    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
> +    hdmi_receiver: hdmi-receiver at fdee0000 {
> +      compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx";
> +      reg = <0xfdee0000 0x6000>;
> +      interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>,
> +                   <GIC_SPI 178 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 = "axi", "apb", "ref", "biu";
> +      memory-region = <&hdmi_receiver_cma>;
> +      pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_5v_detection>;
> +      pinctrl-names = "default";
> +      hpd-gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;

I just found out it isn't documented in the DTS coding style and that
the binding is technically not specifically for a Rockchip based
component, but there is a convention to sort the node properties
alpha-numerically by property name, with some exceptions.

So would it be useful to apply that convention to the example?
And possibly to the list of required properties as well?

Cheers,
  Diederik

> +    };

-------------- 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/20241210/50c93505/attachment.sig>

From sudeep.holla at arm.com  Tue Dec 10 02:13:39 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 10 Dec 2024 10:13:39 +0000
Subject: [GIT PULL] firmware: arm_ffa: Fixes for v6.13
In-Reply-To: <20241205114406.708710-1-sudeep.holla@arm.com>
References: <20241205114406.708710-1-sudeep.holla@arm.com>
Message-ID: <Z1gUUz-I3HCQ7rNV@bogus>

On Thu, Dec 05, 2024 at 11:44:06AM +0000, Sudeep Holla wrote:
> Hi ARM SoC Team,
> 
> Please pull !
> 

Ignore this one, update v2 sent [1].

-- 
Regards,
Sudeep

[1] https://lore.kernel.org/all/20241210101113.3232602-1-sudeep.holla at arm.com/


From m.felsch at pengutronix.de  Tue Dec 10 02:36:46 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Tue, 10 Dec 2024 11:36:46 +0100
Subject: [PATCH 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241209-imx91tmu-v1-2-7859c5387f31@nxp.com>
References: <20241209-imx91tmu-v1-0-7859c5387f31@nxp.com>
 <20241209-imx91tmu-v1-2-7859c5387f31@nxp.com>
Message-ID: <20241210103646.7gblp7mzxbna5gas@pengutronix.de>

Hi,

On 24-12-09, Frank Li wrote:
> From: Pengfei Li <pengfei.li_1 at nxp.com>
> 
> Introduce support for the i.MX91 thermal monitoring unit, which features a
> single sensor for the CPU. The register layout differs from other chips,
> necessitating the creation of a dedicated file for this.
> 
> Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
>  drivers/thermal/Kconfig         |  10 ++
>  drivers/thermal/Makefile        |   1 +
>  drivers/thermal/imx91_thermal.c | 281 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 292 insertions(+)
> 
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index d3f9686e26e71..da403ed86aeb1 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -296,6 +296,16 @@ config IMX8MM_THERMAL
>  	  cpufreq is used as the cooling device to throttle CPUs when the passive
>  	  trip is crossed.
>  
> +config IMX91_THERMAL
> +	tristate "Temperature sensor driver for NXP i.MX91 SoC"
> +	depends on ARCH_MXC || COMPILE_TEST
> +	depends on OF
> +	help
> +	  Support for Temperature sensor found on NXP i.MX91 SoC.
> +	  It supports one critical trip point and one passive trip point. The
> +	  cpufreq is used as the cooling device to throttle CPUs when the passive
> +	  trip is crossed.
> +
>  config K3_THERMAL
>  	tristate "Texas Instruments K3 thermal support"
>  	depends on ARCH_K3 || COMPILE_TEST
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index 9abf43a74f2bb..08da241e6a598 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
>  obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
>  obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
>  obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
> +obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
>  obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
>  obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
>  obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
> diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
> new file mode 100644
> index 0000000000000..19c4dafe9c7a9
> --- /dev/null
> +++ b/drivers/thermal/imx91_thermal.c
> @@ -0,0 +1,281 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2024 NXP.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/iopoll.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/thermal.h>
> +
> +#define CTRL0			0x0
> +
> +#define STAT0			0x10
> +#define STAT0_DRDY0_IF_MASK	BIT(16)
> +
> +#define DATA0			0x20
> +#define DATA_INT_MASK		GENMASK(14, 7)
> +#define DATA_FRAC_MASK		GENMASK(6, 0)
> +
> +#define THR_CTRL01		0x30
> +#define THR_CTRL23		0x40
> +
> +#define CTRL1			0x200
> +#define CTRL1_SET		0x204
> +#define CTRL1_CLR		0x208
> +#define CTRL1_EN		BIT(31)
> +#define CTRL1_START		BIT(30)
> +#define CTRL1_STOP		BIT(29)
> +#define CTRL1_RES_MASK		GENMASK(19, 18)
> +#define CTRL1_MEAS_MODE_MASK	GENMASK(25, 24)
> +
> +#define PERIOD_CTRL		0x270
> +#define MEAS_FREQ_MASK		GENMASK(23, 0)
> +
> +#define REF_DIV			0x280
> +#define DIV_EN			BIT(31)
> +#define DIV_MASK		GENMASK(23, 16)
> +
> +#define PUD_ST_CTRL		0x2B0
> +#define PUDL_MASK		GENMASK(23, 16)
> +
> +#define TRIM1			0x2E0
> +#define TRIM2			0x2F0
> +
> +#define TMU_TEMP_LOW_LIMIT	-40000
> +#define TMU_TEMP_HIGH_LIMIT	125000
> +
> +#define DEFAULT_TRIM1_CONFIG 0xB561BC2DU
> +#define DEFAULT_TRIM2_CONFIG 0x65D4U

please align the defines and use lower-case for the hex values.

> +struct tmu_sensor {
> +	struct imx91_tmu *priv;
> +	struct thermal_zone_device *tzd;
> +};

This can be part of imx91_tmu right?

> +struct imx91_tmu {
> +	void __iomem *base;
> +	struct clk *clk;
> +	struct device *dev;
> +	struct tmu_sensor sensors;
> +};
> +
> +static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
> +{
> +	if (start)
> +		writel_relaxed(CTRL1_START, tmu->base + CTRL1_SET);
> +	else
> +		writel_relaxed(CTRL1_STOP, tmu->base + CTRL1_SET);

Nit:
	unsigned int val = start ? CTRL1_START : CTRL1_STOP;

	writel_relaxed(val, tmu->base + CTRL1_SET);

Aside the nit, why do you use *_relaxed() accessors in you whole code?
Is the order not strictly required?

> +}
> +
> +static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
> +{
> +	if (enable)
> +		writel_relaxed(CTRL1_EN, tmu->base + CTRL1_SET);
> +	else
> +		writel_relaxed(CTRL1_EN, tmu->base + CTRL1_CLR);

Same here:

	unsigned int reg = enable ? CTRL1_SET : CTRL1_CLR;

	writel_relaxed(CTRL1_EN, tmu->base + reg);
> +}
> +
> +static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
> +{
> +	struct tmu_sensor *sensor = thermal_zone_device_priv(tz);
> +	struct imx91_tmu *tmu = sensor->priv;

With tmu_sensor merged into imx91_tmu you don't need this reverse
pointer logic.

> +	int val;
> +	int ret;
> +
> +	ret = readl_relaxed_poll_timeout(tmu->base + STAT0, val,
> +					 val & STAT0_DRDY0_IF_MASK, 1000,
> +					 40000);
> +	if (ret)
> +		return -EAGAIN;
> +
> +	val = readl_relaxed(tmu->base + DATA0) & 0xffffU;
						   ^
				Please use a MASK define for it, also no
				need to use the U suffix.

Also according the TRM 58.3.4 this doesn't seem right. According the TRM
this is a s16 (two's-complement) value. You won't get negative values if
store it within a int.

> +	*temp = val * 1000L / 64L;
			  ^     ^
You don't need to specify the type here explicit since all params would
be converted to int and no overflow happens.

> +	if (*temp < TMU_TEMP_LOW_LIMIT || *temp > TMU_TEMP_HIGH_LIMIT)
> +		return -EAGAIN;
> +
> +	return 0;
> +}
> +
> +static struct thermal_zone_device_ops tmu_tz_ops = {
> +	.get_temp = imx91_tmu_get_temp,
> +};
> +
> +static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
> +{
> +	struct device *dev = tmu->dev;
> +	int ret;
> +	u32 trim1, trim2;

Please use the reverse christmas tree style.

> +	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
> +	if (ret)
> +		return ret;
> +
> +	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
> +	if (ret)
> +		return ret;
> +
> +	if (trim1 == 0 || trim2 == 0)
> +		return -EINVAL;
> +
> +	writel_relaxed(trim1, tmu->base + TRIM1);
> +	writel_relaxed(trim2, tmu->base + TRIM2);
> +
> +	return 0;
> +}
> +
> +static int imx91_tmu_probe(struct platform_device *pdev)
> +{
> +	struct imx91_tmu *tmu;
> +	unsigned long rate;
> +	u32 div;
> +	int ret;
> +	int i = 0;

Same here.

> +	tmu = devm_kzalloc(&pdev->dev, sizeof(struct imx91_tmu), GFP_KERNEL);
> +	if (!tmu)
> +		return -ENOMEM;
> +
> +	tmu->dev = &pdev->dev;
> +
> +	tmu->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(tmu->base))
> +		return PTR_ERR(tmu->base);
> +
> +	tmu->clk = devm_clk_get_prepared(&pdev->dev, NULL);
> +	if (IS_ERR(tmu->clk))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
> +
> +	tmu->sensors.priv = tmu;

As said, no need for the sensors container.

> +	tmu->sensors.tzd = devm_thermal_of_zone_register(&pdev->dev, i, &tmu->sensors, &tmu_tz_ops);
> +	if (IS_ERR(tmu->sensors.tzd))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(tmu->sensors.tzd),
> +				     "failed to register thermal zone sensor\n");
> +
> +	platform_set_drvdata(pdev, tmu);
> +
> +	/* disable the monitor during initialization */
> +	imx91_tmu_enable(tmu, false);
> +	imx91_tmu_start(tmu, false);

Make use of pm_runtime?

> +	ret = imx91_init_from_nvmem_cells(tmu);
> +	if (ret) {
> +		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
> +		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
> +	}
> +
> +	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
> +	rate = clk_get_rate(tmu->clk);
> +	div = (rate / 4000000) - 1;

Would be nice to validate the div value before passing to the HW and if
the target rate of 4MHz can't be reached by the div you you should
return -EINVAL.

> +
> +	/* Set divider value and enable divider */
> +	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
> +
> +	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
> +	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
> +
> +	/*
> +	 * Set resolution mode
> +	 * 00b - Conversion time = 0.59325 ms
> +	 * 01b - Conversion time = 1.10525 ms
> +	 * 10b - Conversion time = 2.12925 ms
> +	 * 11b - Conversion time = 4.17725 ms
> +	 */
> +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
> +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);
> +
> +	/*
> +	 * Set measure mode
> +	 * 00b - Single oneshot measurement
> +	 * 01b - Continuous measurement
> +	 * 10b - Periodic oneshot measurement
> +	 */

For the resolution it's fine to have the values directly coded without a
define, but here we can definitly use a define and drop the comment.

> +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, 0x3), tmu->base + CTRL1_CLR);
> +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, 0x1), tmu->base + CTRL1_SET);

Why do we set it to periodic mode instead of the single-shot? At the
moment the device doesn't have IRQ support, and so there is no need to
run the measurements in background.

> +
> +	/*
> +	 * Set Periodic Measurement Frequency to 25Hz:
> +	 * tMEAS_FREQ = tCONV_CLK * PERIOD_CTRL[MEAS_FREQ]. ->
> +	 * PERIOD_CTRL(MEAS_FREQ) = (1000 / 25) / (1000 / 4000000);
> +	 * Where tMEAS_FREQ = Measurement period and tCONV_CLK = 1/fCONV_CLK.
> +	 * This field should have value greater than count corresponds
> +	 * to time greater than summation of conversion time, power up
> +	 * delay, and six times of conversion clock time.
> +	 * tMEAS_FREQ > (tCONV + tPUD + 6 * tCONV_CLK).
> +	 * tCONV is conversion time determined by CTRL1[RESOLUTION].
> +	 */
> +	writel_relaxed(FIELD_PREP(MEAS_FREQ_MASK, 0x27100), tmu->base + PERIOD_CTRL);

With the single-shot measurements we could remove this part and..

> +
> +	/* enable the monitor */
> +	imx91_tmu_enable(tmu, true);
> +	imx91_tmu_start(tmu, true);

this part as well.

Regards,
  Marco

> +
> +	return 0;
> +}
> +
> +static void imx91_tmu_remove(struct platform_device *pdev)
> +{
> +	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
> +
> +	/* disable tmu */
> +	imx91_tmu_start(tmu, false);
> +	imx91_tmu_enable(tmu, false);
> +}
> +
> +static int __maybe_unused imx91_tmu_suspend(struct device *dev)
> +{
> +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> +
> +	/* disable tmu */
> +	imx91_tmu_start(tmu, false);
> +	imx91_tmu_enable(tmu, false);
> +
> +	clk_disable_unprepare(tmu->clk);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused imx91_tmu_resume(struct device *dev)
> +{
> +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = clk_prepare_enable(tmu->clk);
> +	if (ret)
> +		return ret;
> +
> +	imx91_tmu_enable(tmu, true);
> +	imx91_tmu_start(tmu, true);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(imx91_tmu_pm_ops,
> +			 imx91_tmu_suspend, imx91_tmu_resume);
> +
> +static const struct of_device_id imx91_tmu_table[] = {
> +	{ .compatible = "fsl,imx91-tmu", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, imx91_tmu_table);
> +
> +static struct platform_driver imx91_tmu = {
> +	.driver = {
> +		.name	= "i.MX91_thermal",
> +		.pm	= pm_ptr(&imx91_tmu_pm_ops),
> +		.of_match_table = imx91_tmu_table,
> +	},
> +	.probe = imx91_tmu_probe,
> +	.remove = imx91_tmu_remove,
> +};
> +module_platform_driver(imx91_tmu);
> +
> +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> +MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
> +MODULE_LICENSE("GPL");
> 
> -- 
> 2.34.1
> 
> 
> 


From festevam at gmail.com  Tue Dec 10 02:37:31 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 10 Dec 2024 07:37:31 -0300
Subject: [PATCH v2] serial: imx: Use uart_port_lock_irq() instead of uart_port_lock()
In-Reply-To: <20241210034223.1493522-1-xiaolei.wang@windriver.com>
References: <20241210034223.1493522-1-xiaolei.wang@windriver.com>
Message-ID: <CAOMZO5AzNVd_xut2wBBHeyccFdC+1c4p50Uhzo=+BDbV=mEP2g@mail.gmail.com>

On Tue, Dec 10, 2024 at 12:43?AM Xiaolei Wang
<xiaolei.wang at windriver.com> wrote:
>
> When executing 'ehco mem > /sys/power/state', the following

ehco --> echo

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From dsimic at manjaro.org  Tue Dec 10 02:45:49 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 10 Dec 2024 11:45:49 +0100
Subject: [PATCH 6/6] arm64: dts: rockchip: Remove address aligned beats
 from rk3328-roc
In-Reply-To: <20241210013010.81257-7-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-7-pgwipeout@gmail.com>
Message-ID: <2b68c2dd3618e5904a4eac1ec87d29a7@manjaro.org>

Hello Peter,

Thanks for the patch.  Please, see some comments below.

On 2024-12-10 02:30, Peter Geis wrote:
> Since commit 8a469ee35606 ("arm64: dts: rockchip: Add txpbl node for
> RK3399/RK3328"), the snps,aal, snps,txpbl, and snps,rxpbl nodes have
> been unnecessary in the separate device trees. There is also a
> performance loss to using snps,aal. Remove these from the rk3328-roc
> device tree.
> 
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> 
> ---
> 
>  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> index 6984387ff8b3..0d476cc2144d 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> @@ -155,12 +155,9 @@ &gmac2io {
>  	phy-mode = "rgmii";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&rgmiim1_pins>;
> -	snps,aal;

Huh, I see that quite a few RK3328 board dts files specify
the snps,aal node.  I wonder was it a "cargo cult" approach
at play, :) or was there some real need for it?

Actually, I see now that you added snps,aal to rk3328-roc-
cc.dts in the commit 393f3875c385 ("arm64: dts: rockchip:
improve rk3328-roc-cc rgmii performance."), so I guess that
your further research and testing showed that it actually
isn't needed for Ethernet stability?

>  	snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
>  	snps,reset-active-low;
>  	snps,reset-delays-us = <0 10000 50000>;
> -	snps,rxpbl = <0x4>;
> -	snps,txpbl = <0x4>;

Unless I'm missing something, the commit 8a469ee35606 ("arm64:
dts: rockchip: Add txpbl node for RK3399/RK3328") doesn't add
the snps,rxpbl node to the RK3328 SoC dtsi, and the respective
driver does nothing about it when the snps,txpbl node is found.

Though, I see that rk3328-rock-pi-e.dts is the only other
RK3328 board dts file that specifies the snps,rxpbl node, so
it seems that removing the snps,rxpbl node here should be safe,
especially because it was you who added it in the same commit
mentioned above.  If there were some SoC-level issues, all
RK3328 boards would've needed it.

>  	tx_delay = <0x24>;
>  	rx_delay = <0x18>;
>  	status = "okay";


From d-gole at ti.com  Tue Dec 10 02:47:35 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Tue, 10 Dec 2024 16:17:35 +0530
Subject: [PATCH v6 1/3] pmdomain: ti_sci: add per-device latency
 constraint management
In-Reply-To: <20241206-lpm-v6-10-constraints-pmdomain-v6-1-833980158c68@baylibre.com>
References: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
 <20241206-lpm-v6-10-constraints-pmdomain-v6-1-833980158c68@baylibre.com>
Message-ID: <20241210104735.dtzdhdds6l7yjvgk@lcpd911>

On Dec 06, 2024 at 14:12:50 -0800, Kevin Hilman wrote:
> For each device in a TI SCI PM domain, check whether the device has
> any resume latency constraints set via per-device PM QoS.  If
> constraints are set, send them to DM via the new SCI constraints API.
> 
> Checking for constraints happen for each device before system-wide
> suspend (via ->suspend() hook.)
> 
> An important detail here is that the PM domain driver inserts itself
> into the path of both the ->suspend() and ->resume() hook path
> of *all* devices in the PM domain.  This allows generic PM domain code
> to handle the constraint management and communication with TI SCI.
> 
> Further, this allows device drivers to use existing PM QoS APIs to
> add/update constraints.
> 
> DM firmware clears constraints during its resume, so Linux has
> to check/update/send constraints each time system suspends.
> 
> Also note that the PM QoS framework uses usecs as the units for
> latency whereas the TI SCI firmware uses msecs, so a conversion is
> needed before passing to TI SCI.
> 
> Co-developed-by: Vibhore Vardhan <vibhore at ti.com>
> Signed-off-by: Vibhore Vardhan <vibhore at ti.com>
> Reviewed-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
> Tested-by: Dhruva Gole <d-gole at ti.com>
> Signed-off-by: Kevin Hilman <khilman at baylibre.com>
> ---
>  drivers/pmdomain/ti/ti_sci_pm_domains.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 55 insertions(+)
> 
> diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
> index 0e4bd749d067309654307484c5bb98711bf06daf..963fe1901c959197d5d8b5d34fd8420dfb180087 100644
> --- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
> +++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
> @@ -13,6 +13,8 @@
>  #include <linux/platform_device.h>
>  #include <linux/pm_domain.h>
>  #include <linux/slab.h>
> +#include <linux/pm_qos.h>
> +#include <linux/pm_runtime.h>

nit: Do we not need to sort these includes alphabetically?

>  #include <linux/soc/ti/ti_sci_protocol.h>
>  #include <dt-bindings/soc/ti,sci_pm_domain.h>
>  
> @@ -51,6 +53,32 @@ struct ti_sci_pm_domain {
>  
>  #define genpd_to_ti_sci_pd(gpd) container_of(gpd, struct ti_sci_pm_domain, pd)
>  
> +static inline bool ti_sci_pd_is_valid_constraint(s32 val)
> +{
> +	return val != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static void ti_sci_pd_set_lat_constraint(struct device *dev, s32 val)
> +{
> +	struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
> +	struct ti_sci_pm_domain *pd = genpd_to_ti_sci_pd(genpd);
> +	const struct ti_sci_handle *ti_sci = pd->parent->ti_sci;
> +	u16 val_ms;
> +	int ret;
> +
> +	/* PM QoS latency unit is usecs, TI SCI uses msecs */
> +	val_ms = val / USEC_PER_MSEC;
> +	ret = ti_sci->ops.pm_ops.set_latency_constraint(ti_sci, val_ms, TISCI_MSG_CONSTRAINT_SET);
> +	if (ret)
> +		dev_err(dev, "ti_sci_pd: set latency constraint failed: ret=%d\n",
> +			ret);
> +	else
> +		dev_dbg(dev, "ti_sci_pd: ID:%d set latency constraint %d\n",
> +			pd->idx, val);
> +}
> +#endif
> +
>  /*
>   * ti_sci_pd_power_off(): genpd power down hook
>   * @domain: pointer to the powerdomain to power off
> @@ -79,6 +107,26 @@ static int ti_sci_pd_power_on(struct generic_pm_domain *domain)
>  		return ti_sci->ops.dev_ops.get_device(ti_sci, pd->idx);
>  }
>  
> +#ifdef CONFIG_PM_SLEEP
> +static int ti_sci_pd_suspend(struct device *dev)
> +{
> +	int ret;
> +	s32 val;
> +
> +	ret = pm_generic_suspend(dev);
> +	if (ret)
> +		return ret;
> +
> +	val = dev_pm_qos_read_value(dev, DEV_PM_QOS_RESUME_LATENCY);
> +	if (ti_sci_pd_is_valid_constraint(val))
> +		ti_sci_pd_set_lat_constraint(dev, val);
> +
> +	return 0;
> +}
> +#else
> +#define ti_sci_pd_suspend		NULL
> +#endif
> +
>  /*
>   * ti_sci_pd_xlate(): translation service for TI SCI genpds
>   * @genpdspec: DT identification data for the genpd
> @@ -182,6 +230,13 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
>  				pd->pd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
>  				pd->idx = args.args[0];
>  				pd->parent = pd_provider;
> +				/*
> +				 * If SCI constraint functions are present, then firmware
> +				 * supports the constraints API.
> +				 */
> +				if (pd_provider->ti_sci->ops.pm_ops.set_device_constraint &&
> +				    pd_provider->ti_sci->ops.pm_ops.set_latency_constraint)
> +					pd->pd.domain.ops.suspend = ti_sci_pd_suspend;

Rest looks good.
Reviewed-by: Dhruva Gole <d-gole at ti.com>

-- 
Best regards,
Dhruva Gole
Texas Instruments Incorporated


From yangyicong at huawei.com  Tue Dec 10 02:49:15 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 18:49:15 +0800
Subject: [PATCH v4 08/10] drivers/perf: hisi: Export associated CPUs of
 each PMU through sysfs
In-Reply-To: <20241209154830.GC12428@willie-the-truck>
References: <20241203125049.39458-1-yangyicong@huawei.com>
 <20241203125049.39458-9-yangyicong@huawei.com>
 <20241209154830.GC12428@willie-the-truck>
Message-ID: <22a35ead-0f0b-39a8-16bd-333143081ea8@huawei.com>

On 2024/12/9 23:48, Will Deacon wrote:
> On Tue, Dec 03, 2024 at 08:50:47PM +0800, Yicong Yang wrote:
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> Although the event of the uncore PMU can only be opened on a single
>> CPU, some PMU does have the affinity on a range of CPUs. For example
>> the L3C PMU is associated to the CPUs sharing the L3T it monitors.
>> Users may infer this affinity by the PMU name which may have SCCL ID
>> and CCL ID encoded (for L3C etc), but it's not that straightforward.
>> So export this information by adding an "associated_cpus" sysfs
>> attribute then user can get this directly.
>>
>> Reviewed-by: Jonathan Cameron <Joanthan.Cameron at huawei.com>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> ---
>>  Documentation/admin-guide/perf/hisi-pmu.rst |  5 ++++-
>>  drivers/perf/hisilicon/hisi_uncore_pmu.c    | 10 ++++++++++
>>  2 files changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
>> index 5cc248d18c63..48992a0b8e94 100644
>> --- a/Documentation/admin-guide/perf/hisi-pmu.rst
>> +++ b/Documentation/admin-guide/perf/hisi-pmu.rst
>> @@ -35,7 +35,10 @@ e.g. hisi_sccl1_hha0/rx_operations is RX_OPERATIONS event of HHA index #0 in
>>  SCCL ID #1.
>>  
>>  The driver also provides a "cpumask" sysfs attribute, which shows the CPU core
>> -ID used to count the uncore PMU event.
>> +ID used to count the uncore PMU event. An "associated_cpus" sysfs attribute is
>> +also provided to show the CPUs associated with this PMU. The "cpumask" indicates
>> +the CPUs to open the events, usually as a hint for userspaces tools like perf.
>> +It only contains one associated CPU from the "associated_cpus".
> 
> What is userspace expected to do with this information? Can you point me
> to patches that add the corresponding support to the 'perf' tool, please?
> 

two attributes here, "cpumask" and "associated_cpus". For "cpumask" it's used in
perf [1], this patch does no change to this attribute but only update the
description in the doc.

I think you're questioning about the "associated_cpus" introduced by this patch,
which is not intended to be used by the perf tools but provides a hint for the
user to know the CPUs monitored by which uncore PMU, for example which uncore
L3C PMU's monitoring the events by the CPU(s) the application's running on, or
if the counts is imbalanced among the L3C PMUs user can figure out what's running
on the CPUs provided by the "associated_cpus". As described in the commit this
can also inferred by the PMU name to map SICL ID and CCL ID to certain CPU cluster,
but these ID's aren't readable enough and it'll be more straightforward and
friendly to provide an "associated_cpus" information, considering we've already
maintain it in the drvier.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/util/pmu.c?h=v6.13-rc2#n748

Thanks.


From festevam at gmail.com  Tue Dec 10 02:57:04 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 10 Dec 2024 07:57:04 -0300
Subject: [PATCH v2 1/2] dt-bindings: display: panel-lvds: Add compatible for AUO G084SN05 V9
Message-ID: <20241210105705.116116-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

The AUO G084SN05 V9 is an 8.4" 800x600 LVDS display.

Add a compatible entry for this LVDS display model.

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
Changes since v1:
- Added devicetree at vger.kernel.org on Cc.

 Documentation/devicetree/bindings/display/panel/panel-lvds.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
index 5af2d6930075..fcb5834f799a 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
@@ -42,6 +42,8 @@ properties:
           # Admatec 9904379 10.1" 1024x600 LVDS panel
           - admatec,9904379
           - auo,b101ew05
+          # AUO G084SN05 V9 8.4" 800x600 LVDS panel
+          - auo,g084sn05
           # Chunghwa Picture Tubes Ltd. 7" WXGA (800x1280) TFT LCD LVDS panel
           - chunghwa,claa070wp03xg
           # EDT ETML0700Z9NDHA 7.0" WSVGA (1024x600) color TFT LCD LVDS panel
-- 
2.34.1



From festevam at gmail.com  Tue Dec 10 02:57:05 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 10 Dec 2024 07:57:05 -0300
Subject: [PATCH v2 2/2] arm64: dts: imx8mm-phg: Add LVDS compatible string
In-Reply-To: <20241210105705.116116-1-festevam@gmail.com>
References: <20241210105705.116116-1-festevam@gmail.com>
Message-ID: <20241210105705.116116-2-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

The imx8mm-phg board has an AUO G084SN05 V9 8.4" 800x600 LVDS panel.

Improve the devicetree description by passing the LVDS compatible
string to fix the following dt-schema warning:

imx8mm-phg.dtb: panel: compatible:0: 'panel-lvds' is not one of
['admatec,9904379', 'auo,b101ew05', 'auo,g084sn05',
'chunghwa,claa070wp03xg','edt,etml0700z9ndha', 'hannstar,hsd101pww2',
'hydis,hv070wx2-1e0', 'jenson,bl-jt60050-01a', 'tbs,a711-panel']
...

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
Changes since v1:
- Added devicetree at vger.kernel.org on Cc.

 arch/arm64/boot/dts/freescale/imx8mm-phg.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phg.dts b/arch/arm64/boot/dts/freescale/imx8mm-phg.dts
index 75bbedc6164c..a134b1833649 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phg.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phg.dts
@@ -82,7 +82,7 @@ reg_usdhc2_vmmc: regulator-vmmc {
 	};
 
 	panel {
-		compatible = "panel-lvds";
+		compatible = "auo,g084sn05", "panel-lvds";
 		width-mm = <170>;
 		height-mm = <28>;
 		data-mapping = "jeida-18";
-- 
2.34.1



From d-gole at ti.com  Tue Dec 10 02:54:41 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Tue, 10 Dec 2024 16:24:41 +0530
Subject: [PATCH v6 2/3] pmdomain: ti_sci: add wakeup constraint management
In-Reply-To: <20241206-lpm-v6-10-constraints-pmdomain-v6-2-833980158c68@baylibre.com>
References: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
 <20241206-lpm-v6-10-constraints-pmdomain-v6-2-833980158c68@baylibre.com>
Message-ID: <20241210105441.wav23zfv25es2jld@lcpd911>

On Dec 06, 2024 at 14:12:51 -0800, Kevin Hilman wrote:
> During system-wide suspend, check all devices connected to PM domain
> to see if they are wakeup-enabled.  If so, set a TI SCI device
> constraint.
> 
> Note: DM firmware clears all constraints on resume.
> 
> Co-developed-by: Vibhore Vardhan <vibhore at ti.com>
> Signed-off-by: Vibhore Vardhan <vibhore at ti.com>
> Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
> Tested-by: Dhruva Gole <d-gole at ti.com>
> Signed-off-by: Kevin Hilman <khilman at baylibre.com>
> ---

Reviewed-by: Dhruva Gole <d-gole at ti.com>


-- 
Best regards,
Dhruva Gole
Texas Instruments Incorporated


From etienne.carriere at foss.st.com  Tue Dec 10 02:52:15 2024
From: etienne.carriere at foss.st.com (Etienne CARRIERE - foss)
Date: Tue, 10 Dec 2024 10:52:15 +0000
Subject: [PATCH v2 2/2] firmware: arm_scmi: round rate bisecting in
 discrete rates
In-Reply-To: <Z1ck5tFkb41wReZP@bogus>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-3-etienne.carriere@foss.st.com>
 <Z1bKlOeHJFHpe9ZU@bogus>
 <ed164b6704ab4086b2fb22ae51658f31@foss.st.com>,<Z1ck5tFkb41wReZP@bogus>
Message-ID: <aac4c00dc3ba4599aaa91392dac71d6d@foss.st.com>

On Monday, December 9, 2024, Sudeep Holla wrote:
> On Mon, Dec 09, 2024 at 12:59:58PM +0000, Etienne CARRIERE - foss wrote:
> > Hello Sudeep,
> >
> >  On Monday, December 9, 2024 11:46 AM, Sudeep Holla wrote:
> > > On Tue, Dec 03, 2024 at 06:39:08PM +0100, Etienne Carriere wrote:
> > > > Implement clock round_rate operation for SCMI clocks that describe a
> > > > discrete rates list. Bisect into the supported rates when using SCMI
> > > > message CLOCK_DESCRIBE_RATES to optimize SCMI communication transfers.
> > >
> > > Let me stop here and try to understand the requirement here. So you do
> > > communicate with the firmware to arrive at this round_rate ? Does the
> > > list of discreet clock rates changes at the run-time that enables the
> > > need for it. Or will the initial list just include max and min ?
> >
> > I don't expect the list to change at run-time. The initial list is
> > expected to describe all supported rates. But because this list may
> > be big, I don't think arm_scmi/clock.c driver should store the full list
> > of all supported rates for each of the SCMI clocks. It would cost to
> > much memory. Therefore I propose to query it at runtime, when
> > needed, and bisect to lower the number of required transactions
> > between the agent and the firmware.
> >
> 
> Ah so, this is nothing to do with set_parent, but just an optimisation.
> This change optimises for space but some other platform may have all the
> space but the communication with SCMI platform is not good enough to make
> runtime calls like this change. How do we cater that then ?

This change does not optimize memory. It implements a real clk_round_rate()
operation for SCMI clocks that have a discrete supported rates list. The
existing implementation does not support it, it behaves as if the
requested clock is supported and let caller change the clock rate to
find out which rounded rate it effectively gets. This does not suit 
audio and video clock constraints.

How to deal between platforms with large memory/slow SCMI 
communication and those with the opposite? I think the easiest way
would be to have a dedicated SCMI Clock protocol command.

> 
> We need some spec-ed way or a unique way to identify what is best for
> the platform IMO. We can change the way you have done in this change set
> as someone else may complain in the future that it is costly to send
> such command every time a clock needs to be set. I am just guessing here
> may not be true.
> 
> > >
> > > > Parse the rate list array when the target rate fit in the bounds
> > > > of the command response for simplicity.
> > > >
> > >
> > > I don't understand what you mean by this.
> >
> > I meant here that we bisect into supported rates when communicating
> > with the firmware but once the firmware response provides list portion
> > when target rate fits into, we just scan into that array instead of bisecting
> > into. We could also bisect into that array but it is likely quite small
> > (<128 byte in existing SCMI transport drivers) and that would add a bit
> > more code for no much gain IMHO.
> >
> >
> > >
> > > > If so some reason the sequence fails or if the SCMI driver has no
> > > > round_rate SCMI clock handler, then fallback to the legacy strategy that
> > > > returned the target rate value.
> > > >
> > >
> > > Hmm, so we perform some extra dance but we are okay to fallback to default.
> > > I am more confused.
> >
> > Here, I propose to preserve the exiting sequence in clk/clk-scmi.c in case
> > arm_scmi/clock.c does not implement this new round_rate SCMI clock
> > operation (it can be the case if these 2 drivers are .ko modules, not
> > well known built-in drivers).
> >
> 
> I don't think it would work if it is not built on the same kernel anyways.
> I don't work much about this use-case.

Using the same kernel will not enforce the driver was not modified regarding
the vanilla upstream version. This may be also true for built-in modules
I guess.

> 
> > >
> > > > Operation handle scmi_clk_determine_rate() is change to get the effective
> > > > supported rounded rate when there is no clock re-parenting operation
> > > > supported. Otherwise, preserve the implementation that assumed any
> > > > clock rate could be obtained.
> > > >
> > >
> > > OK, no I think I am getting some idea. Is this case where the parent has
> > > changed and the describe rates can give a different result at run-time.
> >
> > This does not deal with whether parent has changed or not. I would expect
> > the same request sent multiple times to provide the very same result. But
> > as I said above, I don't think arm_scmi/clock.c should consume a possibly
> > large array of memory to store all supported rate each of the SCMI clocks
> > (that describe discrete rates).
> >
> 
> Right, my assumption was totally wrong. Thanks for confirming.
> 
> > An alternate way could be to add an SCMI Clock protocol command in the
> > spec allowing agent to query a closest supported rate, in 1 shot. Maybe
> > this new command could return both rounded rate and the SCMI parent
> > clock needed to reach that rounded rate, better fitting clk_determine_rate()
> > expectations.
> >
> 
> May be that would be ideal but you need to make a case for such a spec change.

We need effective round_rate support for STM32MP2 platforms where audio
and video clocks are provided by a clock exposed by the SCMI server. These
drivers detect the (possibly external) device needs at runtime and need
to select an input clock that fits some constraints for quality reason.
Audio quality is the most sensible to clock rate inaccuracy.

> 
> > >
> > > I need to re-read the part of the spec, but we may need some clarity so
> > > that this implementation is not vendor specific. I am yet to understand this
> > > fully. I just need to make sure spec covers this aspect and anything we
> > > add here is generic solution.
> > >
> > > I would like to avoid this extra query if not required which you seem to
> > > have made an attempt but I just want to be thorough and make sure that's
> > > what we need w.r.t the specification.
> >
> > Sure, I indeed prefer clear and robust implementation in the long term,
> > being the one I propose here or another one.
> >
> 
> Good then, we can work towards achieving that. If you can specify how slow
> or memory hungry is it without these changes and how much this change helps
> your platform, we can take it up with spec authors and see if they are happy
> to provide some alternative to deal with this in a generic way.

The platforms we target usually have plenty of RAM, lets say hundreds of MBytes.
Not that much for some system but enough I guess to store a few hundreds of
clock rates for a few dozen of clocks (few kByte of RAM).

That said, thinking more and more about this, I really belive a dedicate SCMI
clock protocol command would better fit platform needs in the long term.

BR,
Etienne

> 
> --
> Regards,
> Sudeep
> 


From heiko at sntech.de  Tue Dec 10 02:54:39 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 10 Dec 2024 11:54:39 +0100
Subject: [PATCH 5/6] arm64: dts: rockchip: correct rk3328-roc regulator map
In-Reply-To: <20241210013010.81257-6-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-6-pgwipeout@gmail.com>
Message-ID: <14451790.lVVuGzaMjS@diego>

Am Dienstag, 10. Dezember 2024, 02:30:09 CET schrieb Peter Geis:
> The rk3328-roc-cc input power is sourced from a micro-usb port, while
> the rk3328-roc-pc input power is sourced from a usb-c port. Both inputs
> are 5vdc only. Remove the 12v input from the device tree.

full stop. Please don't do "While we are at it" commits.

> While we are at it, add missing voltages and supply to vcc_phy, missing
> voltages to vcc_host1_5v, and standardize the order of regulator
> properties among the fixed regulators.

This second part wants to be its own commit :-) .

Thanks
Heiko

> Fixes: 2171f4fdac06 ("arm64: dts: rockchip: add roc-rk3328-cc board")
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
> 
>  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 23 +++++++++++++-------
>  1 file changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> index f782c8220dd3..6984387ff8b3 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> @@ -24,22 +24,23 @@ gmac_clkin: external-gmac-clock {
>  		#clock-cells = <0>;
>  	};
>  
> -	dc_12v: regulator-dc-12v {
> +	/* fed from passive usb input connector */
> +	dc_5v: regulator-dc-5v {
>  		compatible = "regulator-fixed";
> -		regulator-name = "dc_12v";
> +		regulator-name = "dc_5v";
>  		regulator-always-on;
>  		regulator-boot-on;
> -		regulator-min-microvolt = <12000000>;
> -		regulator-max-microvolt = <12000000>;
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
>  	};
>  
>  	vcc_sd: regulator-sdmmc {
>  		compatible = "regulator-fixed";
> +		regulator-name = "vcc_sd";
>  		gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&sdmmc0m1_pin>;
>  		regulator-boot-on;
> -		regulator-name = "vcc_sd";
>  		regulator-min-microvolt = <3300000>;
>  		regulator-max-microvolt = <3300000>;
>  		vin-supply = <&vcc_io>;
> @@ -50,22 +51,25 @@ vcc_sdio: regulator-sdmmcio {
>  		states = <1800000 0x1>, <3300000 0x0>;
>  		regulator-name = "vcc_sdio";
>  		regulator-type = "voltage";
> +		regulator-always-on;
>  		regulator-min-microvolt = <1800000>;
>  		regulator-max-microvolt = <3300000>;
> -		regulator-always-on;
>  		vin-supply = <&vcc_sys>;
>  	};
>  
>  	vcc_host1_5v: vcc_otg_5v: regulator-vcc-host1-5v {
>  		compatible = "regulator-fixed";
> +		regulator-name = "vcc_host1_5v";
>  		enable-active-high;
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&usb20_host_drv>;
> -		regulator-name = "vcc_host1_5v";
>  		regulator-always-on;
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
>  		vin-supply = <&vcc_sys>;
>  	};
>  
> +	/* sourced from usb input through 3A fuse */
>  	vcc_sys: regulator-vcc-sys {
>  		compatible = "regulator-fixed";
>  		regulator-name = "vcc_sys";
> @@ -73,7 +77,7 @@ vcc_sys: regulator-vcc-sys {
>  		regulator-boot-on;
>  		regulator-min-microvolt = <5000000>;
>  		regulator-max-microvolt = <5000000>;
> -		vin-supply = <&dc_12v>;
> +		vin-supply = <&dc_5v>;
>  	};
>  
>  	vcc_phy: regulator-vcc-phy {
> @@ -81,6 +85,9 @@ vcc_phy: regulator-vcc-phy {
>  		regulator-name = "vcc_phy";
>  		regulator-always-on;
>  		regulator-boot-on;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&vcc_io>;
>  	};
>  
>  	leds {
> 






From d-gole at ti.com  Tue Dec 10 02:55:17 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Tue, 10 Dec 2024 16:25:17 +0530
Subject: [PATCH v6 3/3] pmdomain: ti_sci: handle wake IRQs for IO daisy
 chain wakeups
In-Reply-To: <20241206-lpm-v6-10-constraints-pmdomain-v6-3-833980158c68@baylibre.com>
References: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
 <20241206-lpm-v6-10-constraints-pmdomain-v6-3-833980158c68@baylibre.com>
Message-ID: <20241210105517.ms7twggosr2rs72m@lcpd911>

On Dec 06, 2024 at 14:12:52 -0800, Kevin Hilman wrote:
> When a device supports IO daisy-chain wakeups, it uses a dedicated
> wake IRQ.  Devices with IO daisy-chain wakeups enabled should not set
> wakeup constraints since these can happen even from deep power states,
> so should not prevent the DM from picking deep power states.
> 
> Wake IRQs are set with dev_pm_set_wake_irq() or
> dev_pm_set_dedicated_wake_irq().  The latter is used by the serial
> driver used on K3 platforms (drivers/tty/serial/8250/8250_omap.c)
> when the interrupts-extended property is used to describe the
> dedicated wakeup interrupt.
> 
> Detect these wake IRQs in the suspend path, and if set, skip sending
> constraint.
> 
> Tested-by: Dhruva Gole <d-gole at ti.com>
> Signed-off-by: Kevin Hilman <khilman at baylibre.com>
> ---

Reviewed-by: Dhruva Gole <d-gole at ti.com>


-- 
Best regards,
Dhruva Gole
Texas Instruments Incorporated


From etienne.carriere at foss.st.com  Tue Dec 10 02:58:05 2024
From: etienne.carriere at foss.st.com (Etienne CARRIERE - foss)
Date: Tue, 10 Dec 2024 10:58:05 +0000
Subject: [PATCH v2 1/2] firmware: arm_scmi: get only min/max clock rates
In-Reply-To: <Z1cwTWQWamv3lywB@pluto>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-2-etienne.carriere@foss.st.com>
 <Z1bHgf_4qqZgSnDt@bogus>
 <22ff786d1e034169be21ef7dc32c4a3a@foss.st.com>,<Z1cwTWQWamv3lywB@pluto>
Message-ID: <80ea462fbe044781bb4b1e7a80ab8b80@foss.st.com>

On Monday, December 9, 2024, Cristian Marussi wrote:
> On Mon, Dec 09, 2024 at 01:48:48PM +0000, Etienne CARRIERE - foss wrote:
> > On Monday, December 9, 2024, Sudeep Holla wrote:
> > > On Tue, Dec 03, 2024 at 06:39:07PM +0100, Etienne Carriere wrote:
> > > > Remove limitation of 16 clock rates max for discrete clock rates
> > > > description when the SCMI firmware supports SCMI Clock protocol v2.0
> > > > or later.
> > > >
> > > > Driver clk-scmi.c is only interested in the min and max clock rates.
> > > > Get these by querying the first and last discrete rates with SCMI
> > > > clock protocol message ID CLOCK_DESCRIBE_RATES since the SCMI
> > > > specification v2.0 and later states that rates enumerated by this
> > > > command are to be enumerated in "numeric ascending order" [1].
> > > >
> > > > Preserve the implementation that queries all discrete rates (16 rates
> > > > max) to support SCMI firmware built on SCMI specification v1.0 [2]
> > > > where SCMI Clock protocol v1.0 does not explicitly require rates
> > > > described with CLOCK_DESCRIBE_RATES to be in ascending order.
> > > >
> > > > Link: https://developer.arm.com/documentation/den0056 [1]
> > > > Link: https://developer.arm.com/documentation/den0056/a [2]
> > > > Signed-off-by: Etienne Carriere <etienne.carriere at foss.st.com>
> > > > ---
> 
> Hi,
> 
> > >
> > > [...]
> > >
> > > > +
> > > > +static int scmi_clock_get_rates_bound(const struct scmi_protocol_handle *ph,
> > > > +                                   u32 clk_id, struct scmi_clock_info *clk)
> > > > +{
> > >
> > > This new function seem to have unwraped the scmi_iterator_ops(namely
> > > prepare_message, update_state and process_response instead of reusing them.
> > > Can you please explain why it wasn't possible to reuse them ?
> >
> > Since we're interested here only in min and max rates, let's query the
> > first and last rates only. This can save a bit of useless transactions between
> > agent and firmware in case there are many clocks with somewhat large
> > the discrete rate lists.
> >
> > I though using the iterator for this specific case would add a bit more
> > complexity: it's expected to iterate (st->desc_index incremented from the
> > common scmi_iterator_run() function) whereas here I propose to send
> > only 2 messages.
> 
> Yes, indeed the core iterator helpers are meant to issue a 'full scan'
> retrievieng all the resources that are returned while handling in a
> common way the underlying machinery common to all messages that, like
> DESCRIBE_RATES, could possibly return their results in chunks as a
> multi-part reply...
> 
> ...having said that I can certainly extend the iterators to be configurable
> enough to fit this new usecase and retrieve only the desired part of the
> 'scan' so that can be used for this kind of max/min query or for the
> bisection case.
> 
> I would avoid to re-introduce ad-hoc code to handle these new usecases
> that do not fit into the existing iterator logic, since iterators
> were introduced to remove duplication and unify under common
> methods...and this new iterator scenario seems to me that has already 2
> usecases and certainly more protocol could want to perform similar 'lazy
> partial queries' in the future, so I'd prefer to address this in a more
> general way upfront if possible...I will think about it and post something
> next week in the form of some new iterator extensions, if it's fine for you.
> 

Hi Cristian,
Thanks for looking at this. Any help here is very welcome.

BR,
Etienne


> Thanks,
> Cristian
> 


From will at kernel.org  Tue Dec 10 03:14:51 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 11:14:51 +0000
Subject: [PATCH v10 0/4] io-pgtable-arm + drm/msm: Extend iova fault
 debugging
In-Reply-To: <20241028213146.238941-1-robdclark@gmail.com>
References: <20241028213146.238941-1-robdclark@gmail.com>
Message-ID: <20241210111450.GA14735@willie-the-truck>

Hi Rob,

On Mon, Oct 28, 2024 at 02:31:36PM -0700, Rob Clark wrote:
> From: Rob Clark <robdclark at chromium.org>
> 
> This series extends io-pgtable-arm with a method to retrieve the page
> table entries traversed in the process of address translation, and then
> beefs up drm/msm gpu devcore dump to include this (and additional info)
> in the devcore dump.
> 
> This is a respin of https://patchwork.freedesktop.org/series/94968/
> (minus a patch that was already merged)
> 
> v2:  Fix an armv7/32b build error in the last patch
> v3:  Incorperate Will Deacon's suggestion to make the interface
>      callback based.
> v4:  Actually wire up the callback
> v5:  Drop the callback approach
> v6:  Make walk-data struct pgtable specific and rename
>      io_pgtable_walk_data to arm_lpae_io_pgtable_walk_data
> v7:  Re-use the pgtable walker added for arm_lpae_read_and_clear_dirty()
> v8:  Pass pte pointer to callback so it can modify the actual pte
> v9:  Fix selftests_running case
> v10: Call visit cb for all nodes traversed, leave the decision about
>      whether to care about non-leaf nodes to the callback

Do you plan to respin this? I see Mostafa left a proposal on patch 3.

Thanks,

Will


From mark.rutland at arm.com  Tue Dec 10 03:27:19 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Dec 2024 11:27:19 +0000
Subject: arm64: stacktrace: unwind exception boundaries
In-Reply-To: <Z1bWaGCvUrwrj2fZ@J2N7QTR9R3>
References: <36kx57aw46vwykgckr5cm4fafhw54tjuj4cqljrdnpfwvjl7if@a7znuhpfu54o>
 <zbwbgkuvvciezpmigcp6gaahfxwm7cwhpzus7gtbfnbzsjb2n3@kfbdppbd74o4>
 <Z1bWaGCvUrwrj2fZ@J2N7QTR9R3>
Message-ID: <Z1gll87-TkAqFwUz@J2N7QTR9R3>

On Mon, Dec 09, 2024 at 11:37:12AM +0000, Mark Rutland wrote:
> Hi Kent,
> 
> On Thu, Dec 05, 2024 at 01:04:59PM -0500, Kent Overstreet wrote:
> > On 6.13-rc1, I'm now seeing a ton of test failures due to this warning -
> > what gives?
> 
> Sorry about this; I just sent what I *thought* was a fix for this:
> 
>   https://lore.kernel.org/linux-arm-kernel/20241209110351.1876804-1-mark.rutland at arm.com/
> 
> ... but re-reading the below I see you're actually hitting a different
> issue.
> 
> > 00104 ========= TEST   generic/017
> > 00104        run fstests generic/017 at 2024-12-05 11:47:43
> > 00104 spectre-v4 mitigation disabled by command-line option
> > 00106 bcachefs (vdc): starting version 1.13: inode_has_child_snapshots
> > 00106 bcachefs (vdc): initializing new filesystem
> > 00106 bcachefs (vdc): going read-write
> > 00106 bcachefs (vdc): marking superblocks
> > 00106 bcachefs (vdc): initializing freespace
> > 00106 bcachefs (vdc): done initializing freespace
> > 00106 bcachefs (vdc): reading snapshots table
> > 00106 bcachefs (vdc): reading snapshots done
> > 00106 bcachefs (vdc): done starting filesystem
> > 00200 ------------[ cut here ]------------
> > 00200 WARNING: CPU: 8 PID: 12571 at arch/arm64/kernel/stacktrace.c:223 arch_stack_walk+0x2c0/0x388
> 
> Looking at v6.13-rc1, that's the warning in
> kunwind_next_frame_record_meta() for when the frame_record_meta::type is
> not a valid value, which likely implies one of the following:
> 
> (a) The logic to identify a frame_record_meta is wrong.
> 
> (b) The entry logic has failed to initilialize pt_regs::stackframe::meta
>     on an entry path somehow.
> 
> (c) The stack has been corrupted, and some frame record has been
>     clobbered to look like a frame_record_meta.

Looking some more, I see that bch2_btree_transactions_read() is trying
to unwind other tasks, and I believe what's happening here is that the
unwindee isn't actually blocked for the duration of the unwind, leading
to the unwinder encountering junk and consequently producing the
warning.

As a test case, it's possible to trigger similar with a few parallel
instances of:

	while true; do cat /proc/*/stack > /dev/null

The only thing we can do on the arm64 side is remove the WARN_ON_ONCE(),
which'll get rid of the splat. It seems we've never been unlucky enough
to hit a stale fgraph entry, or that would've blown up also.

Regardless of the way arm64 behaves here, the unwind performed by
bch2_btree_transactions_read() is going to contain garbage unless the
task is pinned in a blocked state. AFAICT the way
btree_trans::locking_wait::task is used is here is racy, and there's no
guarantee that the unwindee is actually blocked.

Mark.


From pgwipeout at gmail.com  Tue Dec 10 03:29:02 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 06:29:02 -0500
Subject: [PATCH 6/6] arm64: dts: rockchip: Remove address aligned beats
 from rk3328-roc
In-Reply-To: <2b68c2dd3618e5904a4eac1ec87d29a7@manjaro.org>
References: <20241210013010.81257-1-pgwipeout@gmail.com> <20241210013010.81257-7-pgwipeout@gmail.com>
 <2b68c2dd3618e5904a4eac1ec87d29a7@manjaro.org>
Message-ID: <CAMdYzYpj3d7Rq0O0QjV4r6HEf_e07R0QAhPT2NheZdQV3TnQ6g@mail.gmail.com>

On Tue, Dec 10, 2024 at 5:45?AM Dragan Simic <dsimic at manjaro.org> wrote:
>
> Hello Peter,
>
> Thanks for the patch.  Please, see some comments below.
>
> On 2024-12-10 02:30, Peter Geis wrote:
> > Since commit 8a469ee35606 ("arm64: dts: rockchip: Add txpbl node for
> > RK3399/RK3328"), the snps,aal, snps,txpbl, and snps,rxpbl nodes have
> > been unnecessary in the separate device trees. There is also a
> > performance loss to using snps,aal. Remove these from the rk3328-roc
> > device tree.
> >
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> >
> > ---
> >
> >  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 3 ---
> >  1 file changed, 3 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > index 6984387ff8b3..0d476cc2144d 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > @@ -155,12 +155,9 @@ &gmac2io {
> >       phy-mode = "rgmii";
> >       pinctrl-names = "default";
> >       pinctrl-0 = <&rgmiim1_pins>;
> > -     snps,aal;
>
> Huh, I see that quite a few RK3328 board dts files specify
> the snps,aal node.  I wonder was it a "cargo cult" approach
> at play, :) or was there some real need for it?
>
> Actually, I see now that you added snps,aal to rk3328-roc-
> cc.dts in the commit 393f3875c385 ("arm64: dts: rockchip:
> improve rk3328-roc-cc rgmii performance."), so I guess that
> your further research and testing showed that it actually
> isn't needed for Ethernet stability?
>
> >       snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
> >       snps,reset-active-low;
> >       snps,reset-delays-us = <0 10000 50000>;
> > -     snps,rxpbl = <0x4>;
> > -     snps,txpbl = <0x4>;
>
> Unless I'm missing something, the commit 8a469ee35606 ("arm64:
> dts: rockchip: Add txpbl node for RK3399/RK3328") doesn't add
> the snps,rxpbl node to the RK3328 SoC dtsi, and the respective
> driver does nothing about it when the snps,txpbl node is found.
>
> Though, I see that rk3328-rock-pi-e.dts is the only other
> RK3328 board dts file that specifies the snps,rxpbl node, so
> it seems that removing the snps,rxpbl node here should be safe,
> especially because it was you who added it in the same commit
> mentioned above.  If there were some SoC-level issues, all
> RK3328 boards would've needed it.

Good Morning,

You'll notice the author of that patch was me. Setting aal, txpbl, and
rxpbl was the original fix I came up with for the rk3328, which I
applied to the only board I had. Someone else later on isolated it
specifically isolated it to just the txpbl and applied it to both the
rk3328 and rk3399 directly.

This was just something that was left hanging after that result.

Looking at how rk356x was done, I suspect there's an even more elegant
solution. However I don't have the deep level knowledge nor
documentation to implement it.

Very Respectfully,
Peter Geis
>
> >       tx_delay = <0x24>;
> >       rx_delay = <0x18>;
> >       status = "okay";


From will at kernel.org  Tue Dec 10 03:31:31 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 11:31:31 +0000
Subject: [PATCH v2] arm64: Allow CONFIG_AUTOFDO_CLANG to be selected
In-Reply-To: <CALJ9ZPNfUFF8OrpvziTnTvGU7OxEgyy9ZTc3aF-NhZ5hMbp7RQ@mail.gmail.com>
References: <20241118222540.27495-1-yabinc@google.com>
 <20241209162028.GD12428@willie-the-truck>
 <CAF1bQ=SiHi8oCyo5YnXGpQGofM1zAsnBdqSEet1mS-BYNKVU8A@mail.gmail.com>
 <20241209185623.GA13084@willie-the-truck>
 <CALJ9ZPNfUFF8OrpvziTnTvGU7OxEgyy9ZTc3aF-NhZ5hMbp7RQ@mail.gmail.com>
Message-ID: <20241210113129.GB14735@willie-the-truck>

On Mon, Dec 09, 2024 at 03:51:34PM -0800, Yabin Cui wrote:
>  On Mon, Dec 9, 2024 at 10:56?AM Will Deacon <will at kernel.org> wrote:
> >
> > (Aside: please try to avoid top-posting on the public lists as it messes up
> > the flow of conversation; I'll try to piece this back together.)
> >
> > On Mon, Dec 09, 2024 at 09:30:50AM -0800, Rong Xu wrote:
> > > On Mon, Dec 9, 2024 at 8:20?AM Will Deacon <will at kernel.org> wrote:
> > > > On Mon, Nov 18, 2024 at 02:25:40PM -0800, Yabin Cui wrote:
> > > > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > > > > index fd9df6dcc593..c3814df5e391 100644
> > > > > --- a/arch/arm64/Kconfig
> > > > > +++ b/arch/arm64/Kconfig
> > > > > @@ -103,6 +103,7 @@ config ARM64
> > > > >       select ARCH_SUPPORTS_PER_VMA_LOCK
> > > > >       select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
> > > > >       select ARCH_SUPPORTS_RT
> > > > > +     select ARCH_SUPPORTS_AUTOFDO_CLANG
> > > > >       select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
> > > > >       select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
> > > > >       select ARCH_WANT_DEFAULT_BPF_JIT
> > > >
> > > > After this change, both arm64 and x86 select this option unconditionally
> > > > and with no apparent support code being added. So what is actually
> > > > required in order to select ARCH_SUPPORTS_AUTOFDO_CLANG and why isn't
> > > > it just available for all architectures instead?
> 
> I think it's similar to ARCH_SUPPORTS_LTO_CLANG, which also doesn't need any
> support code but requires testing to ensure it works on a specific architecture.
> 
> >
> > > Enabling an AutoFDO build requires users to explicitly set CONFIG_AUTOFDO_CLANG.
> > > The support code is in Commit 315ad8780a129e82 (kbuild: Add AutoFDO
> > > support for Clang build).
> >
> > Yes, that is precisely my point. The user has to enable
> > CONFIG_AUTOFDO_CLANG anyway, so what is the point in having
> > ARCH_SUPPORTS_AUTOFDO_CLANG. Why would an architecture _not_ want to
> > select that?
> >
> > > We are not enabling this for all architectures because AutoFDO's optimized build
> > > relies on Last Branch Records (LBR) which aren't available on all architectures.
> >
> > So? ETM isn't available on all arm64 machines and I doubt whether LBR is
> > available on _all_ x86 machines either. So there's a runtime failure
> > mode that needs to be handled anyway and I don't think the arch-specific
> > Kconfig option is really doing anything useful.
> 
> My understanding of the benefits of ARCH_SUPPORTS_AUTOFDO_CLANG is:
> 1. Generally, we don't prefer to collect an AutoFDO profile on one
> architecture and use it to build the kernel for another architecture.
> This is because the profile misses data for architecture-dependent
> code. ARCH_SUPPORTS_AUTOFDO_CLANG can partially prevent this from
> happening.

Hmm, not really. Once more than one architecture selects the option, you
have the possibility of the mismatch you're trying to avoid.

> 2. Building a kernel with an AutoFDO profile involves using new
> optimization flags for clang.  Having ARCH_SUPPORTS_AUTOFDO_CLANG=y
> for one architecture means someone has tested building a kernel with
> an AutoFDO profile on this architecture.

On the flip side, allowing all architectures to select the option
actually increases your test coverage.

Will


From didi.debian at cknow.org  Tue Dec 10 03:31:02 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Tue, 10 Dec 2024 12:31:02 +0100
Subject: [PATCH 5/6] arm64: dts: rockchip: correct rk3328-roc regulator
 map
In-Reply-To: <20241210013010.81257-6-pgwipeout@gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-6-pgwipeout@gmail.com>
Message-ID: <D67ZJ6MOM5TH.2WBYCCU20DDJO@cknow.org>

Hi Peter,

Thanks for this series, I already saw some familiar error msgs
mentioned, so will try this series out soon (tm).

On Tue Dec 10, 2024 at 2:30 AM CET, Peter Geis wrote:
> The rk3328-roc-cc input power is sourced from a micro-usb port, while
> the rk3328-roc-pc input power is sourced from a usb-c port. Both inputs
> are 5vdc only. Remove the 12v input from the device tree.
>
> While we are at it, add missing voltages and supply to vcc_phy, missing
> voltages to vcc_host1_5v, and standardize the order of regulator
> properties among the fixed regulators.

Big fan of standardization :-) ...

>
> Fixes: 2171f4fdac06 ("arm64: dts: rockchip: add roc-rk3328-cc board")
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
>
>  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 23 +++++++++++++-------
>  1 file changed, 15 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> index f782c8220dd3..6984387ff8b3 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> @@ -24,22 +24,23 @@ gmac_clkin: external-gmac-clock {
>  		#clock-cells = <0>;
>  	};
>  
> -	dc_12v: regulator-dc-12v {
> +	/* fed from passive usb input connector */
> +	dc_5v: regulator-dc-5v {
>  		compatible = "regulator-fixed";
> -		regulator-name = "dc_12v";
> +		regulator-name = "dc_5v";
>  		regulator-always-on;
>  		regulator-boot-on;
> -		regulator-min-microvolt = <12000000>;
> -		regulator-max-microvolt = <12000000>;
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
>  	};
>  
>  	vcc_sd: regulator-sdmmc {
>  		compatible = "regulator-fixed";
> +		regulator-name = "vcc_sd";
>  		gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&sdmmc0m1_pin>;
>  		regulator-boot-on;
> -		regulator-name = "vcc_sd";
>  		regulator-min-microvolt = <3300000>;
>  		regulator-max-microvolt = <3300000>;
>  		vin-supply = <&vcc_io>;

... but why not put regulator-name as the first of the regulator
properties as is done in the rk3328-rock64.dts ...

> @@ -50,22 +51,25 @@ vcc_sdio: regulator-sdmmcio {
>  		states = <1800000 0x1>, <3300000 0x0>;
>  		regulator-name = "vcc_sdio";
>  		regulator-type = "voltage";
> +		regulator-always-on;
>  		regulator-min-microvolt = <1800000>;
>  		regulator-max-microvolt = <3300000>;
> -		regulator-always-on;
>  		vin-supply = <&vcc_sys>;
>  	};
>  
>  	vcc_host1_5v: vcc_otg_5v: regulator-vcc-host1-5v {
>  		compatible = "regulator-fixed";
> +		regulator-name = "vcc_host1_5v";
>  		enable-active-high;
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&usb20_host_drv>;
> -		regulator-name = "vcc_host1_5v";
>  		regulator-always-on;
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
>  		vin-supply = <&vcc_sys>;
>  	};

... and was the case here?

Cheers,
  Diederik

>  
> +	/* sourced from usb input through 3A fuse */
>  	vcc_sys: regulator-vcc-sys {
>  		compatible = "regulator-fixed";
>  		regulator-name = "vcc_sys";
> @@ -73,7 +77,7 @@ vcc_sys: regulator-vcc-sys {
>  		regulator-boot-on;
>  		regulator-min-microvolt = <5000000>;
>  		regulator-max-microvolt = <5000000>;
> -		vin-supply = <&dc_12v>;
> +		vin-supply = <&dc_5v>;
>  	};
>  
>  	vcc_phy: regulator-vcc-phy {
> @@ -81,6 +85,9 @@ vcc_phy: regulator-vcc-phy {
>  		regulator-name = "vcc_phy";
>  		regulator-always-on;
>  		regulator-boot-on;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&vcc_io>;
>  	};
>  
>  	leds {

-------------- 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/20241210/d549fba0/attachment.sig>

From will at kernel.org  Tue Dec 10 03:31:52 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 11:31:52 +0000
Subject: [RFC PATCH 0/3] arm64: support FEAT_BBM level 2 and large block
 mapping when rodata=full
In-Reply-To: <20241118181711.962576-1-yang@os.amperecomputing.com>
References: <20241118181711.962576-1-yang@os.amperecomputing.com>
Message-ID: <20241210113151.GC14735@willie-the-truck>

On Mon, Nov 18, 2024 at 10:16:07AM -0800, Yang Shi wrote:
> 
> When rodata=full kernel linear mapping is mapped by PTE due to arm's
> break-before-make rule.
> 
> This resulted in a couple of problems:
>   - performance degradation
>   - more TLB pressure
>   - memory waste for kernel page table
> 
> There are some workarounds to mitigate the problems, for example, using
> rodata=on, but this compromises the security measurement.
> 
> With FEAT_BBM level 2 support, splitting large block page table to
> smaller ones doesn't need to make the page table entry invalid anymore.
> This allows kernel split large block mapping on the fly.

I think you can still get TLB conflict aborts in this case, so this
doesn't work. Hopefully the architecture can strengthen this in the
future to give you what you need.

Will


From lkp at intel.com  Tue Dec 10 03:35:09 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 10 Dec 2024 19:35:09 +0800
Subject: [PATCH mm-unstable 04/17] mm: alpha: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-5-kaleshsingh@google.com>
References: <20241210024119.2488608-5-kaleshsingh@google.com>
Message-ID: <202412102123.Db7EAmhx-lkp@intel.com>

Hi Kalesh,

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/Kalesh-Singh/mm-Introduce-generic_mmap_hint/20241210-104424
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20241210024119.2488608-5-kaleshsingh%40google.com
patch subject: [PATCH mm-unstable 04/17] mm: alpha: Introduce arch_mmap_hint()
config: alpha-allmodconfig (https://download.01.org/0day-ci/archive/20241210/202412102123.Db7EAmhx-lkp at intel.com/config)
compiler: alpha-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241210/202412102123.Db7EAmhx-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/202412102123.Db7EAmhx-lkp at intel.com/

All errors (new ones prefixed by >>):

   arch/alpha/kernel/osf_sys.c: In function 'arch_get_unmapped_area':
>> arch/alpha/kernel/osf_sys.c:1280:24: error: 'hint' undeclared (first use in this function); did you mean 'uint'?
    1280 |                 return hint;
         |                        ^~~~
         |                        uint
   arch/alpha/kernel/osf_sys.c:1280:24: note: each undeclared identifier is reported only once for each function it appears in


vim +1280 arch/alpha/kernel/osf_sys.c

  1248	
  1249	unsigned long
  1250	arch_get_unmapped_area(struct file *filp, unsigned long addr,
  1251			       unsigned long len, unsigned long pgoff,
  1252			       unsigned long flags, vm_flags_t vm_flags)
  1253	{
  1254		unsigned long limit;
  1255	
  1256		/* "32 bit" actually means 31 bit, since pointers sign extend.  */
  1257		if (current->personality & ADDR_LIMIT_32BIT)
  1258			limit = 0x80000000;
  1259		else
  1260			limit = TASK_SIZE;
  1261	
  1262		if (len > limit)
  1263			return -ENOMEM;
  1264	
  1265		if (flags & MAP_FIXED)
  1266			return addr;
  1267	
  1268		/* First, see if the given suggestion fits.
  1269	
  1270		   The OSF/1 loader (/sbin/loader) relies on us returning an
  1271		   address larger than the requested if one exists, which is
  1272		   a terribly broken way to program.
  1273	
  1274		   That said, I can see the use in being able to suggest not
  1275		   merely specific addresses, but regions of memory -- perhaps
  1276		   this feature should be incorporated into all ports?  */
  1277	
  1278		addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
  1279		if (addr)
> 1280			return hint;
  1281	
  1282		/* Next, try allocating at TASK_UNMAPPED_BASE.  */
  1283		addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
  1284						 len, limit);
  1285		if (addr != (unsigned long) -ENOMEM)
  1286			return addr;
  1287	
  1288		/* Finally, try allocating in low memory.  */
  1289		addr = arch_get_unmapped_area_1 (PAGE_SIZE, len, limit);
  1290	
  1291		return addr;
  1292	}
  1293	

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


From will at kernel.org  Tue Dec 10 03:39:50 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 11:39:50 +0000
Subject: [PATCH v4 08/10] drivers/perf: hisi: Export associated CPUs of
 each PMU through sysfs
In-Reply-To: <22a35ead-0f0b-39a8-16bd-333143081ea8@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
 <20241203125049.39458-9-yangyicong@huawei.com>
 <20241209154830.GC12428@willie-the-truck>
 <22a35ead-0f0b-39a8-16bd-333143081ea8@huawei.com>
Message-ID: <20241210113949.GE14735@willie-the-truck>

On Tue, Dec 10, 2024 at 06:49:15PM +0800, Yicong Yang wrote:
> On 2024/12/9 23:48, Will Deacon wrote:
> > On Tue, Dec 03, 2024 at 08:50:47PM +0800, Yicong Yang wrote:
> >> From: Yicong Yang <yangyicong at hisilicon.com>
> >>
> >> Although the event of the uncore PMU can only be opened on a single
> >> CPU, some PMU does have the affinity on a range of CPUs. For example
> >> the L3C PMU is associated to the CPUs sharing the L3T it monitors.
> >> Users may infer this affinity by the PMU name which may have SCCL ID
> >> and CCL ID encoded (for L3C etc), but it's not that straightforward.
> >> So export this information by adding an "associated_cpus" sysfs
> >> attribute then user can get this directly.
> >>
> >> Reviewed-by: Jonathan Cameron <Joanthan.Cameron at huawei.com>
> >> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> >> ---
> >>  Documentation/admin-guide/perf/hisi-pmu.rst |  5 ++++-
> >>  drivers/perf/hisilicon/hisi_uncore_pmu.c    | 10 ++++++++++
> >>  2 files changed, 14 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
> >> index 5cc248d18c63..48992a0b8e94 100644
> >> --- a/Documentation/admin-guide/perf/hisi-pmu.rst
> >> +++ b/Documentation/admin-guide/perf/hisi-pmu.rst
> >> @@ -35,7 +35,10 @@ e.g. hisi_sccl1_hha0/rx_operations is RX_OPERATIONS event of HHA index #0 in
> >>  SCCL ID #1.
> >>  
> >>  The driver also provides a "cpumask" sysfs attribute, which shows the CPU core
> >> -ID used to count the uncore PMU event.
> >> +ID used to count the uncore PMU event. An "associated_cpus" sysfs attribute is
> >> +also provided to show the CPUs associated with this PMU. The "cpumask" indicates
> >> +the CPUs to open the events, usually as a hint for userspaces tools like perf.
> >> +It only contains one associated CPU from the "associated_cpus".
> > 
> > What is userspace expected to do with this information? Can you point me
> > to patches that add the corresponding support to the 'perf' tool, please?
> > 
> 
> two attributes here, "cpumask" and "associated_cpus". For "cpumask" it's used in
> perf [1], this patch does no change to this attribute but only update the
> description in the doc.
> 
> I think you're questioning about the "associated_cpus" introduced by this patch,
> which is not intended to be used by the perf tools but provides a hint for the
> user to know the CPUs monitored by which uncore PMU, for example which uncore
> L3C PMU's monitoring the events by the CPU(s) the application's running on, or
> if the counts is imbalanced among the L3C PMUs user can figure out what's running
> on the CPUs provided by the "associated_cpus". As described in the commit this
> can also inferred by the PMU name to map SICL ID and CCL ID to certain CPU cluster,
> but these ID's aren't readable enough and it'll be more straightforward and
> friendly to provide an "associated_cpus" information, considering we've already
> maintain it in the drvier.

Bah. I just noticed that there's precedent for this in the Arm CSPMU driver,
so I don't really have a leg to stand on despite my objections to funneling
firmware information through to userspace without a confirmed user.

Will


From dmitry.baryshkov at linaro.org  Tue Dec 10 03:43:19 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 13:43:19 +0200
Subject: [PATCH v5 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <20241210091901.83028-3-andrej.picej@norik.com>
References: <20241210091901.83028-1-andrej.picej@norik.com>
 <20241210091901.83028-3-andrej.picej@norik.com>
Message-ID: <irpmhq7vxjra6vhmdh7p63ajj57n3h2c4br3ija2jmwtoewist@zyxfmx6k5m4e>

On Tue, Dec 10, 2024 at 10:19:00AM +0100, Andrej Picej wrote:
> Add a optional properties to change LVDS output voltage. This should not
> be static as this depends mainly on the connected display voltage
> requirement. We have three properties:
> - "ti,lvds-termination-ohms", which sets near end termination,
> - "ti,lvds-vod-swing-data-microvolt" and
> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> output voltage for data and clock lanes. They are defined as an array
> with min and max values. The appropriate bitfield will be set if
> selected constraints can be met.
> 
> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> end termination will be used. Selecting only one:
> "ti,lvds-vod-swing-data-microvolt" or
> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> constraint for only data/clock lanes will be met. Setting both is
> recommended.
> 
> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> ---
> Changes in v5:
> - specify default values in sn65dsi83_parse_lvds_endpoint,
> - move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
> Changes in v4:
> - fix typo in commit message bitfiled -> bitfield
> - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
> of separate variables for channel A/B
> - add more checks on return value of "of_property_read_u32_array"
> Changes in v3:
> - use microvolts for default array values 1000 mV -> 1000000 uV.
> Changes in v2:
> - use datasheet tables to get the proper configuration
> - since major change was done change the authorship to myself
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi83.c | 142 +++++++++++++++++++++++++-
>  1 file changed, 139 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> index 57a7ed13f996..f9578b38da28 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> @@ -132,6 +132,16 @@
>  #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>  #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>  
> +enum sn65dsi83_channel {
> +	CHANNEL_A,
> +	CHANNEL_B
> +};
> +
> +enum sn65dsi83_lvds_term {
> +	OHM_100,
> +	OHM_200
> +};
> +
>  enum sn65dsi83_model {
>  	MODEL_SN65DSI83,
>  	MODEL_SN65DSI84,
> @@ -147,6 +157,8 @@ struct sn65dsi83 {
>  	struct regulator		*vcc;
>  	bool				lvds_dual_link;
>  	bool				lvds_dual_link_even_odd_swap;
> +	int				lvds_vod_swing_conf[2];
> +	int				lvds_term_conf[2];
>  };
>  
>  static const struct regmap_range sn65dsi83_readable_ranges[] = {
> @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>  	.max_register = REG_IRQ_STAT,
>  };
>  
> +static const int lvds_vod_swing_data_table[2][4][2] = {
> +	{	/* 100 Ohm */
> +		{ 180000, 313000 },
> +		{ 215000, 372000 },
> +		{ 250000, 430000 },
> +		{ 290000, 488000 },
> +	},
> +	{	/* 200 Ohm */
> +		{ 150000, 261000 },
> +		{ 200000, 346000 },
> +		{ 250000, 428000 },
> +		{ 300000, 511000 },
> +	},
> +};
> +
> +static const int lvds_vod_swing_clock_table[2][4][2] = {
> +	{	/* 100 Ohm */
> +		{ 140000, 244000 },
> +		{ 168000, 290000 },
> +		{ 195000, 335000 },
> +		{ 226000, 381000 },
> +	},
> +	{	/* 200 Ohm */
> +		{ 117000, 204000 },
> +		{ 156000, 270000 },
> +		{ 195000, 334000 },
> +		{ 234000, 399000 },
> +	},
> +};
> +
>  static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>  {
>  	return container_of(bridge, struct sn65dsi83, bridge);
> @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>  		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>  
>  	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
>  	regmap_write(ctx->regmap, REG_LVDS_LANE,
>  		     (ctx->lvds_dual_link_even_odd_swap ?
>  		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
> +		     (ctx->lvds_term_conf[CHANNEL_A] ?
> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
> +		     (ctx->lvds_term_conf[CHANNEL_B] ?
> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>  	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>  
>  	le16val = cpu_to_le16(mode->hdisplay);
> @@ -576,10 +622,100 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>  	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>  };
>  
> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
> +{
> +	int i;
> +
> +	for (i = 0; i <= 3; i++) {
> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
> +			return i;
> +	}
> +
> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
> +	return -EINVAL;
> +}
> +
> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> +{
> +	struct device *dev = ctx->dev;
> +	struct device_node *endpoint;
> +	int endpoint_reg;
> +	/* Set so the property can be freely selected if not defined */
> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
> +	u32 lvds_term;
> +	u8 lvds_term_conf = 0x1;
> +	int lvds_vod_swing_conf = 0x1;

Magic values

> +	int ret = 0;
> +	int ret_data;
> +	int ret_clock;
> +
> +	if (channel == CHANNEL_A)
> +		endpoint_reg = 2;
> +	else
> +		endpoint_reg = 3;
> +
> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
> +	if (!of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term)) {

The code has been better before:
provide default for lvds_term, read the property (keeping the default in
case of an error), then use the lvds_term to set up lvds_term_conf, as
expected.

> +		if (lvds_term == 100)
> +			lvds_term_conf = OHM_100;
> +		else
> +			lvds_term_conf = OHM_200;
> +	}
> +
> +	ctx->lvds_term_conf[channel] = lvds_term_conf;
> +
> +	ret_data = of_property_read_u32_array(endpoint,
> +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
> +			ARRAY_SIZE(lvds_vod_swing_data));
> +	if (ret_data != 0 && ret_data != -EINVAL) {
> +		ret = ret_data;
> +		goto exit;
> +	}
> +
> +	ret_clock = of_property_read_u32_array(endpoint,
> +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
> +			ARRAY_SIZE(lvds_vod_swing_clk));
> +	if (ret_clock != 0 && ret_clock != -EINVAL) {
> +		ret = ret_clock;
> +		goto exit;
> +	}
> +
> +	/* If any of the two properties is defined. */
> +	if (!ret_data || !ret_clock) {
> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
> +			lvds_vod_swing_data, lvds_vod_swing_clk,
> +			lvds_term_conf);
> +		if (lvds_vod_swing_conf < 0) {
> +			ret = lvds_vod_swing_conf;
> +			goto exit;
> +		}
> +	}
> +
> +	ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
> +	ret = 0;
> +exit:
> +	of_node_put(endpoint);
> +	return ret;
> +}
> +
>  static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>  {
>  	struct drm_bridge *panel_bridge;
>  	struct device *dev = ctx->dev;
> +	int ret;
> +
> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
> +	if (ret < 0)
> +		return ret;
>  
>  	ctx->lvds_dual_link = false;
>  	ctx->lvds_dual_link_even_odd_swap = false;
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From heiko at sntech.de  Tue Dec 10 03:57:44 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 10 Dec 2024 12:57:44 +0100
Subject: [PATCH v5 01/18] drm/rockchip: vop2: Add debugfs support
In-Reply-To: <20241209122943.2781431-4-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209122943.2781431-4-andyshrk@163.com>
Message-ID: <4471861.MSiuQNM8U4@diego>

Hi Andy,

Am Montag, 9. Dezember 2024, 13:29:13 CET schrieb Andy Yan:
> From: Andy Yan <andy.yan at rock-chips.com>
> 
> /sys/kernel/debug/dri/vop2/summary:  dump vop display state
> /sys/kernel/debug/dri/vop2/regs: dump whole vop registers
> /sys/kernel/debug/dri/vop2/active_regs: only dump the registers of
> activated modules
> 
> Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
> Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
> Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
> ---

> +static void __vop2_regs_dump(struct seq_file *s, bool active_only)
> +{
> +	struct drm_info_node *node = s->private;
> +	struct vop2 *vop2 = node->info_ent->data;
> +	struct drm_minor *minor = node->minor;
> +	struct drm_device *drm_dev = minor->dev;
> +	const struct vop2_regs_dump *dump;
> +	unsigned int i;
> +
> +	drm_modeset_lock_all(drm_dev);
> +
> +	regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
> +
> +	if (vop2->enable_count) {
> +		for (i = 0; i < vop2->data->regs_dump_size; i++) {
> +			dump = &vop2->data->regs_dump[i];
> +			vop2_regs_print(vop2, s, dump, active_only);
> +		}
> +	} else {
> +		seq_printf(s, "VOP disabled\n");
> +	}
> +	drm_modeset_unlock_all(drm_dev);
> +

nit: not needed empty line at the end of the function

> +}
> +

> +static void vop2_debugfs_init(struct vop2 *vop2, struct drm_minor *minor)
> +{
> +	struct dentry *root;
> +	unsigned int i;
> +
> +	root = debugfs_create_dir("vop2", minor->debugfs_root);
> +	if (!IS_ERR(root)) {
> +		for (i = 0; i < ARRAY_SIZE(vop2_debugfs_list); i++)
> +			vop2_debugfs_list[i].data = vop2;
> +
> +		drm_debugfs_create_files(vop2_debugfs_list,
> +					 ARRAY_SIZE(vop2_debugfs_list),
> +					 root, minor);
> +	}
> +}
> +
> +static int vop2_crtc_late_register(struct drm_crtc *crtc)
> +{
> +	struct vop2_video_port *vp = to_vop2_video_port(crtc);
> +	struct vop2 *vop2 = vp->vop2;
> +
> +	if (drm_crtc_index(crtc) == 0)
> +		vop2_debugfs_init(vop2, crtc->dev->primary);
> +
> +	return 0;
> +}

I'm wondering about, shoudln't there be an unregister step too?
I.e. the late_register callback says:
"should be unregistered in the early_unregister callback" [0].

And there exists drm_debugfs_remove_files(), though it doesn't
seem t be used much - just by tegra.

I haven't managed to find drm code handling that automatically though?


Heiko


[0] https://elixir.bootlin.com/linux/v6.12.4/source/include/drm/drm_crtc.h#L737
[1] https://elixir.bootlin.com/linux/v6.12.4/source/drivers/gpu/drm/drm_debugfs.c#L265




From faraz.ata at samsung.com  Tue Dec 10 03:53:09 2024
From: faraz.ata at samsung.com (Faraz Ata)
Date: Tue, 10 Dec 2024 17:23:09 +0530
Subject: [PATCH] arm64: dts: exynosautov920: add DMA nodes
In-Reply-To: <0bac139b-c89c-43a7-978a-e5fe001d3dd2@kernel.org>
References: <CGME20241204122402epcas5p2412733eb46d495fadfa30e5af3c5ce83@epcas5p2.samsung.com>
	<20241204122335.1578-1-faraz.ata@samsung.com>
	<0bac139b-c89c-43a7-978a-e5fe001d3dd2@kernel.org>
Message-ID: <030f01db4afa$1cb672c0$56235840$@samsung.com>

Hi Krzysztof,

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk at kernel.org>
> Sent: Monday, December 9, 2024 1:04 PM
> To: Faraz Ata <faraz.ata at samsung.com>; devicetree at vger.kernel.org; linux-
> samsung-soc at vger.kernel.org; krzk+dt at kernel.org; robh at kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; alim.akhtar at samsung.com;
> rosa.pila at samsung.com
> Subject: Re: [PATCH] arm64: dts: exynosautov920: add DMA nodes
> 
> On 04/12/2024 13:23, Faraz Ata wrote:
> > +
> > +		spdma1: dma-controller at 10190000 {
> > +			compatible = "arm,pl330", "arm,primecell";
> > +			reg = <0x10190000 0x1000>;
> > +			interrupts = <GIC_SPI 917 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&cmu_misc
> CLK_MOUT_MISC_NOC_USER>;
> > +			clock-names = "apb_pclk";
> > +			#dma-cells = <1>;
> > +		};
> > +
> > +		pdma0: dma-controller at 101A0000 {
> 
> Please do not send downstream code directly, but fix it to match upstream.
> Lowercase hex everywhere.
> 
Thanks for your review,  will takecare in future patches. 

> Best regards,
> Krzysztof



From xueshuai at linux.alibaba.com  Tue Dec 10 04:04:17 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Tue, 10 Dec 2024 20:04:17 +0800
Subject: [PATCH] perf/dwc_pcie: Qualify RAS DES VSEC Capability by Vendor,
 Revision
In-Reply-To: <20241209222938.3219364-1-helgaas@kernel.org>
References: <20241209222938.3219364-1-helgaas@kernel.org>
Message-ID: <5a1ef0d2-be24-4865-8e23-159d001ac6d6@linux.alibaba.com>

Hi, Bjorn,

? 2024/12/10 06:29, Bjorn Helgaas ??:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> PCI Vendor-Specific (VSEC) Capabilities are defined by each vendor.
> Devices from different vendors may advertise a VSEC Capability with the DWC
> RAS DES functionality, but the vendors may assign different VSEC IDs.
> 
> Search for the DWC RAS DES Capability using the VSEC ID and VSEC Rev
> chosen by the vendor.
> 
> This does not fix a current problem because Alibaba, Ampere, and Qualcomm
> all assigned the same VSEC ID and VSEC Rev for the DWC RAS DES Capability.
> 
> The potential issue is that we may add support for a device from another
> vendor, where the vendor has already assigned DWC_PCIE_VSEC_RAS_DES_ID
> (0x02) for an unrelated VSEC.  In that event, dwc_pcie_des_cap() would find
> the unrelated VSEC and mistakenly assume it was a DWC RAS DES Capability.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
> Sample devices that advertise VSEC Capabilities with VSEC ID=0x02 that are
> unrelated to the DWC RAS DES functionality:
> 
>    https://community.nxp.com/t5/S32G/S32G3-PCIe-compliance-mode-set-speed-to-5-8Gbit-s/m-p/1875346#M7024
>      00:00.0 PCI bridge: Freescale Semiconductor Inc Device 4300 (prog-if 00 [Normal decode])
>        Capabilities: [70] Express (v2) Root Port (Slot-), MSI 00
>        Capabilities: [158 v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
> 
>    https://github.com/google-coral/edgetpu/issues/743
>      0000:00:00.0 PCI bridge: NVIDIA Corporation Device 1ad0 (rev a1) (prog-if 00 [Normal decode])
>        Capabilities: [70] Express (v2) Root Port (Slot-), MSI 00
>        Capabilities: [1d0 v1] Vendor Specific Information: ID=0002 Rev=4 Len=100
> 
>    https://www.linuxquestions.org/questions/linux-kernel-70/differences-in-'lspci-v'-output-4175495550/
>      00:01.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 1 (rev 13) (prog-if 00 [Normal decode])
>        Capabilities: [90] Express Root Port (Slot+), MSI 00
>        Capabilities: [160] Vendor Specific Information: ID=0002 Rev=0 Len=00c <?>
> 
>    https://www.reddit.com/r/linuxhardware/comments/187u87b/the_correct_way_to_identify_the_kernel_driver/
>      04:00.0 Network controller: Realtek Semiconductor Co., Ltd. Device c852 (rev 01)
>        Capabilities: [70] Express Endpoint, MSI 00
>        Capabilities: [170] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
> ---
>   drivers/perf/dwc_pcie_pmu.c | 68 ++++++++++++++++++++-----------------
>   1 file changed, 37 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
> index 9cbea9675e21..d022f498fa1a 100644
> --- a/drivers/perf/dwc_pcie_pmu.c
> +++ b/drivers/perf/dwc_pcie_pmu.c
> @@ -20,7 +20,6 @@
>   #include <linux/sysfs.h>
>   #include <linux/types.h>
>   
> -#define DWC_PCIE_VSEC_RAS_DES_ID		0x02
>   #define DWC_PCIE_EVENT_CNT_CTL			0x8
>   
>   /*
> @@ -100,14 +99,23 @@ struct dwc_pcie_dev_info {
>   	struct list_head dev_node;
>   };
>   
> -struct dwc_pcie_vendor_id {
> -	int vendor_id;
> +struct dwc_pcie_pmu_vsec_id {
> +	u16 vendor_id;
> +	u16 vsec_id;
> +	u8 vsec_rev;
>   };
>   
> -static const struct dwc_pcie_vendor_id dwc_pcie_vendor_ids[] = {
> -	{.vendor_id = PCI_VENDOR_ID_ALIBABA },
> -	{.vendor_id = PCI_VENDOR_ID_AMPERE },
> -	{.vendor_id = PCI_VENDOR_ID_QCOM },
> +/*
> + * VSEC IDs are allocated by the vendor, so a given ID may mean different
> + * things to different vendors.  See PCIe r6.0, sec 7.9.5.2.
> + */
> +static const struct dwc_pcie_pmu_vsec_id dwc_pcie_pmu_vsec_ids[] = {
> +	{ .vendor_id = PCI_VENDOR_ID_ALIBABA,
> +	  .vsec_id = 0x02, .vsec_rev = 0x4 },
> +	{ .vendor_id = PCI_VENDOR_ID_AMPERE,
> +	  .vsec_id = 0x02, .vsec_rev = 0x4 },
> +	{ .vendor_id = PCI_VENDOR_ID_QCOM,
> +	  .vsec_id = 0x02, .vsec_rev = 0x4 },
>   	{} /* terminator */
>   };
>   
> @@ -519,31 +527,28 @@ static void dwc_pcie_unregister_pmu(void *data)
>   	perf_pmu_unregister(&pcie_pmu->pmu);
>   }
>   
> -static bool dwc_pcie_match_des_cap(struct pci_dev *pdev)
> +static u16 dwc_pcie_des_cap(struct pci_dev *pdev)
>   {
> -	const struct dwc_pcie_vendor_id *vid;
> -	u16 vsec = 0;
> +	const struct dwc_pcie_pmu_vsec_id *vid;
> +	u16 vsec;
>   	u32 val;
>   
>   	if (!pci_is_pcie(pdev) || !(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT))
> -		return false;
> +		return 0;
>   
> -	for (vid = dwc_pcie_vendor_ids; vid->vendor_id; vid++) {
> +	for (vid = dwc_pcie_pmu_vsec_ids; vid->vendor_id; vid++) {

How about checking the pdev->vendor with vid->vendor_id before search the vesc cap?

+		if (pdev->vendor != vid->vendor_id)
+			continue;

>   		vsec = pci_find_vsec_capability(pdev, vid->vendor_id,
> -						DWC_PCIE_VSEC_RAS_DES_ID);
> -		if (vsec)
> -			break;
> +						vid->vsec_id);
> +		if (vsec) {
> +			pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER,
> +					      &val);
> +			if (PCI_VNDR_HEADER_REV(val) == vid->vsec_rev) {
> +				pci_dbg(pdev, "Detected PCIe Vendor-Specific Extended Capability RAS DES\n");
> +				return vsec;
> +			}
> +		}
>   	}
> -	if (!vsec)
> -		return false;
> -
> -	pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER, &val);
> -	if (PCI_VNDR_HEADER_REV(val) != 0x04)
> -		return false;
> -
> -	pci_dbg(pdev,
> -		"Detected PCIe Vendor-Specific Extended Capability RAS DES\n");
> -	return true;
> +	return 0;
>   }

Best Regards,
Shuai


From ansuelsmth at gmail.com  Tue Dec 10 04:06:29 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Tue, 10 Dec 2024 13:06:29 +0100
Subject: [net-next PATCH v11 6/9] net: mdio: Add Airoha AN8855 Switch
 MDIO Passtrough
In-Reply-To: <5aec4a94-3cea-41a4-8500-71472fae51d4@lunn.ch>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-7-ansuelsmth@gmail.com>
 <5aec4a94-3cea-41a4-8500-71472fae51d4@lunn.ch>
Message-ID: <67582eca.050a0220.3b9b85.2de4@mx.google.com>

On Tue, Dec 10, 2024 at 02:53:34AM +0100, Andrew Lunn wrote:
> > +static int an855_phy_restore_page(struct an8855_mfd_priv *priv,
> > +				  int phy) __must_hold(&priv->bus->mdio_lock)
> > +{
> > +	/* Check PHY page only for addr shared with switch */
> > +	if (phy != priv->switch_addr)
> > +		return 0;
> > +
> > +	/* Don't restore page if it's not set to switch page */
> > +	if (priv->current_page != FIELD_GET(AN8855_PHY_PAGE,
> > +					    AN8855_PHY_PAGE_EXTENDED_4))
> > +		return 0;
> > +
> > +	/* Restore page to 0, PHY might change page right after but that
> > +	 * will be ignored as it won't be a switch page.
> > +	 */
> > +	return an8855_mii_set_page(priv, phy, AN8855_PHY_PAGE_STANDARD);
> > +}
> 
> I don't really understand what is going on here. Maybe the commit
> message needs expanding, or the function names changing.
> 
> Generally, i would expect a save/restore action. Save the current
> page, swap to the PHY page, do the PHY access, and then restore to the
> saved page.
>

Idea is to save on extra read/write on subsequent write on the same
page.

Idea here is that PHY will receive most of the read (for status
poll) hence in 90% of the time page will be 0.

And switch will receive read/write only on setup or fdb/vlan access on
configuration so it will receive subsequent write on the same page.
(page 4)

PHY might also need to write on page 1 on setup but never on page 4 as
that is reserved for switch.

Making the read/swap/write/restore adds 2 additional operation that can
really be skipped 90% of the time.

Also curret_page cache is indirectly protected by the mdio lock.

So in short this function makes sure PHY for port 0 is configured on the
right page based on the prev page set.

An alternative way might be assume PHY is always on page 0 and any
switch operation save and restore the page.

Hope it's clear now why this is needed. Is this ok or you prefer the
alternative way? 

-- 
	Ansuel


From will at kernel.org  Tue Dec 10 04:05:57 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 12:05:57 +0000
Subject: [PATCH v4 00/10] Refactor the common parts to the HiSilicon
 Uncore PMU core and cleanups
In-Reply-To: <20241203125049.39458-1-yangyicong@huawei.com>
References: <20241203125049.39458-1-yangyicong@huawei.com>
Message-ID: <20241210120556.GA15398@willie-the-truck>

On Tue, Dec 03, 2024 at 08:50:39PM +0800, Yicong Yang wrote:
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> This series mainly contains the refactor of the HiSilicon Uncore PMU by
> extracting the common parts from each drivers into the core:
> - the retrieving of the PMU topology ID
> - the common sysfs attributes like cpumask and identifier
> 
> In order to achieve this, we need to do below preparation:
> - refactor the detection of associated CPUs for PMUs locates on a SICL
> - maintain the topology information in a dedicated data structure
> - provides a generic implementation of cpumask/identifier attributes
> 
> Besides also include below changes/cleanups in this patchset
> - add one new sysfs attributes for better describing the topology information
>   of the associated CPUs of the PMU.
> - define a symbol namespace for HiSilicon Uncore PMUs to avoid pollute the
>   common ones
> - two minor nonfunctional cleanups of DDRC PMU
> 
> Change since v3:
> - Split the associated_cpus refactor patches according to the functions, hope
>   will be easier to review
> - Drop the use of cpu_online_mask out of cpuhp
> Link: https://lore.kernel.org/linux-arm-kernel/20241026072424.29887-1-yangyicong at huawei.com/

This doesn't build on top of -rc2 (see log below). I suspect this is because
of the recent MODULE_IMPORT_NS() changes to use string literals [1].

Please can you send a v5?

Will

[1] cdd30ebb1b9f ("module: Convert symbol namespace to string literal")

--->8

In file included from ./include/linux/module.h:22,
                 from ./include/linux/device/driver.h:21,
                 from ./include/linux/device.h:32,
                 from ./include/linux/acpi.h:14,
                 from drivers/perf/hisilicon/hisi_uncore_hha_pmu.c:11:
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c:559:18: error: expected ?,? or ?;? before ?HISI_PMU?
  559 | MODULE_IMPORT_NS(HISI_PMU);
      |                  ^~~~~~~~
./include/linux/moduleparam.h:26:47: note: in definition of macro ?__MODULE_INFO?
   26 |   = __MODULE_INFO_PREFIX __stringify(tag) "=" info
      |                                               ^~~~
./include/linux/module.h:299:30: note: in expansion of macro ?MODULE_INFO?
  299 | #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, ns)
      |                              ^~~~~~~~~~~
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c:559:1: note: in expansion of macro ?MODULE_IMPORT_NS?
  559 | MODULE_IMPORT_NS(HISI_PMU);
      | ^~~~~~~~~~~~~~~~
make[5]: *** [scripts/Makefile.build:194: drivers/perf/hisilicon/hisi_uncore_hha_pmu.o] Error 1
make[5]: *** Waiting for unfinished jobs....
In file included from ./include/linux/module.h:22,
                 from ./include/linux/device/driver.h:21,
                 from ./include/linux/device.h:32,
                 from ./include/linux/acpi.h:14,
                 from drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c:11:
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c:595:18: error: expected ?,? or ?;? before ?HISI_PMU?
  595 | MODULE_IMPORT_NS(HISI_PMU);
      |                  ^~~~~~~~
./include/linux/moduleparam.h:26:47: note: in definition of macro ?__MODULE_INFO?
   26 |   = __MODULE_INFO_PREFIX __stringify(tag) "=" info
      |                                               ^~~~
./include/linux/module.h:299:30: note: in expansion of macro ?MODULE_INFO?
  299 | #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, ns)
      |                              ^~~~~~~~~~~
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c:595:1: note: in expansion of macro ?MODULE_IMPORT_NS?
  595 | MODULE_IMPORT_NS(HISI_PMU);
      | ^~~~~~~~~~~~~~~~
make[5]: *** [scripts/Makefile.build:194: drivers/perf/hisilicon/hisi_uncore_l3c_pmu.o] Error 1
/tmp/ccKFrDMm.s: Assembler messages:
/tmp/ccKFrDMm.s:7: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:8: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:9: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:10: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:11: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:12: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:13: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:14: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:15: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:16: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:17: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:18: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:19: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:20: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:21: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:22: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:23: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:24: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:25: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:26: Error: junk at end of line, first unrecognized character is `H'
/tmp/ccKFrDMm.s:27: Error: junk at end of line, first unrecognized character is `H'
make[5]: *** [scripts/Makefile.build:194: drivers/perf/hisilicon/hisi_uncore_pmu.o] Error 1
In file included from ./include/linux/module.h:22,
                 from ./include/linux/device/driver.h:21,
                 from ./include/linux/device.h:32,
                 from ./include/linux/acpi.h:14,
                 from drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c:11:
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c:556:18: error: expected ?,? or ?;? before ?HISI_PMU?
  556 | MODULE_IMPORT_NS(HISI_PMU);
      |                  ^~~~~~~~
./include/linux/moduleparam.h:26:47: note: in definition of macro ?__MODULE_INFO?
   26 |   = __MODULE_INFO_PREFIX __stringify(tag) "=" info
      |                                               ^~~~
./include/linux/module.h:299:30: note: in expansion of macro ?MODULE_INFO?
  299 | #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, ns)
      |                              ^~~~~~~~~~~
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c:556:1: note: in expansion of macro ?MODULE_IMPORT_NS?
  556 | MODULE_IMPORT_NS(HISI_PMU);
      | ^~~~~~~~~~~~~~~~
make[5]: *** [scripts/Makefile.build:194: drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.o] Error 1
make[4]: *** [scripts/Makefile.build:440: drivers/perf/hisilicon] Error 2
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [scripts/Makefile.build:440: drivers/perf] Error 2
make[3]: *** Waiting for unfinished jobs....
make[2]: *** [scripts/Makefile.build:440: drivers] Error 2


From faraz.ata at samsung.com  Tue Dec 10 03:59:13 2024
From: faraz.ata at samsung.com (Faraz Ata)
Date: Tue, 10 Dec 2024 17:29:13 +0530
Subject: [PATCH] arm64: dts: exynosautov920: add DMA nodes
In-Reply-To: <07a4942c-023f-495e-a4b0-e451c949ad80@linaro.org>
References: <CGME20241204122402epcas5p2412733eb46d495fadfa30e5af3c5ce83@epcas5p2.samsung.com>
	<20241204122335.1578-1-faraz.ata@samsung.com>
	<07a4942c-023f-495e-a4b0-e451c949ad80@linaro.org>
Message-ID: <031001db4afa$f01614e0$d0423ea0$@samsung.com>

Hi Tudor

> -----Original Message-----
> From: Tudor Ambarus <tudor.ambarus at linaro.org>
> Sent: Monday, December 9, 2024 1:13 PM
> To: Faraz Ata <faraz.ata at samsung.com>; devicetree at vger.kernel.org; linux-
> samsung-soc at vger.kernel.org; krzk+dt at kernel.org; robh at kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; alim.akhtar at samsung.com;
> rosa.pila at samsung.com; Peter Griffin <peter.griffin at linaro.org>; Andr?
> Draszik <andre.draszik at linaro.org>; William McVicker
> <willmcvicker at google.com>; kernel-team at android.com
> Subject: Re: [PATCH] arm64: dts: exynosautov920: add DMA nodes
> 
> 
> 
> On 12/4/24 12:23 PM, Faraz Ata wrote:
> > ExynosAutov920 SoC has 7 DMA controllers. Two secure DMAC
> > (SPDMA0 & SPDMA1) and five non-secure DMAC (PDMA0 to PDMA4).
> > Adds the required dt node for the same.
> 
> typos: s/adds/add, s/node/nodes
> 
Thanks for your review, will correct in the v2

> Hi, Faraz!
> 
> Have you tested DMA on ExynosAutov920, did it work with the upstream
> driver code?
> 
Yes, I tested with dmatest for M2M for all channel, it is working as expected with mainline PL330 driver. 

> I tried enabling it for GS101 and I had some questions that I couldn't answer,
> and I moved forward in the meantime. Would you mind taking a look at:
> 
> https://lore.kernel.org/linux-arm-kernel/e4089855-aca9-4993-bac6-
> e59370cf7954 at linaro.org/
> 
I am not sure about GS101 architecture, will try to reachout internally to people who might be aware of this.

> Thanks a ton!
> ta




From ansuelsmth at gmail.com  Tue Dec 10 04:10:45 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Tue, 10 Dec 2024 13:10:45 +0100
Subject: [net-next PATCH v11 9/9] net: phy: Add Airoha AN8855 Internal
 Switch Gigabit PHY
In-Reply-To: <b3b79c80-ac7c-456b-a3b5-eee61f671694@lunn.ch>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-10-ansuelsmth@gmail.com>
 <b3b79c80-ac7c-456b-a3b5-eee61f671694@lunn.ch>
Message-ID: <67582fca.050a0220.2d187a.9e01@mx.google.com>

On Tue, Dec 10, 2024 at 02:36:29AM +0100, Andrew Lunn wrote:
> > +config AIR_AN8855_PHY
> > +	tristate "Airoha AN8855 Internal Gigabit PHY"
> > +	help
> > +	  Currently supports the internal Airoha AN8855 Switch PHY.
> > +
> >  config AIR_EN8811H_PHY
> >  	tristate "Airoha EN8811H 2.5 Gigabit PHY"
> >  	help
> 
> Do you have any idea why the new one is AN, and previous one is EN?  I
> just like consistent naming, or an explanation why it is not
> consistent.
>

EN EcoNet that was then absorbed by Airoha (AN). Hence it's the same
thing. Airoha is suggesting to use AN for new submission. So it's just
about timing.

> > +#define AN8855_PHY_ID				0xc0ff0410
> > +static struct phy_driver an8855_driver[] = {
> > +{
> > +	PHY_ID_MATCH_EXACT(AN8855_PHY_ID),
> 
> Is there any documentation about the ID, and the lower nibble. Given
> it is 0, i'm wondering if PHY_ID_MATCH_EXACT() is correct.
>

I will check this but I doubt there is any explaination. These are internal
to the switch so my theory is that no exact logic was applied.

-- 
	Ansuel


From wahrenst at gmx.net  Tue Dec 10 04:11:05 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Tue, 10 Dec 2024 13:11:05 +0100
Subject: [PATCH V2] spi: mxs: support effective_speed_hz
Message-ID: <20241210121105.5314-1-wahrenst@gmx.net>

Set spi_transfer->effective_speed_hz in transfer_one_message so that
SPI client driver can use it.

Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
Reviewed-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/spi/spi-mxs.c | 2 ++
 1 file changed, 2 insertions(+)

Changes in V2:
- fix grammar in patch description
- add Frank's Reviewed-by

diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index e6d955d964f4..43455305fdf4 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -381,6 +381,8 @@ static int mxs_spi_transfer_one(struct spi_controller *host,
 		if (status)
 			break;

+		t->effective_speed_hz = ssp->clk_rate;
+
 		/* De-assert on last transfer, inverted by cs_change flag */
 		flag = (&t->transfer_list == m->transfers.prev) ^ t->cs_change ?
 		       TXRX_DEASSERT_CS : 0;
--
2.34.1



From will at kernel.org  Tue Dec 10 04:13:37 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 12:13:37 +0000
Subject: [PATCH] arm64: remove duplicate word
In-Reply-To: <20241120045406.21537-1-RuffaloLavoisier@gmail.com>
References: <20241120045406.21537-1-RuffaloLavoisier@gmail.com>
Message-ID: <20241210121336.GA15428@willie-the-truck>

On Wed, Nov 20, 2024 at 01:54:04PM +0900, Ruffalo Lavoisier wrote:
> - Remove duplicate word, 'to'.
> ---
>  arch/arm64/include/asm/pgtable-prot.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Please include a Signed-off-by line so that this can be applied.
More details are available in:

	Documentation/process/submitting-patches.rst

Will


From quic_jinlmao at quicinc.com  Tue Dec 10 04:22:51 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Tue, 10 Dec 2024 20:22:51 +0800
Subject: [PATCH v5 0/2] coresight: Add label sysfs node support
Message-ID: <20241210122253.31926-1-quic_jinlmao@quicinc.com>

With current design, the name of the non-cpu bounded coresight
component is the device type with the number. And with 'ls' command
we can get the register address of the component. But from these
information, we can't know what the HW or system the component belongs
to. Add label in DT and show the hw information by reading label sysfs
node.

cti_sys0 -> ../../../devices/platform/soc at 0/138f0000.cti/cti_sys0
cti_sys1 -> ../../../devices/platform/soc at 0/13900000.cti/cti_sys1
tpdm0 -> ../../../devices/platform/soc at 0/10b0d000.tpdm/tpdm0
tpdm1 -> ../../../devices/platform/soc at 0/10c28000.tpdm/tpdm1
tpdm2 -> ../../../devices/platform/soc at 0/10c29000.tpdm/tpdm2

/sys/bus/coresight/devices # cat cti*/label
cti_dlct_0
cti_dlct_1
cti_apss_0
cti_apss_1
cti_apss_2

Change since V4:
1. Add label in DT and add label sysfs node for each coresight device. 

Change since V3:
1. Change device-name to arm,cs-dev-name.
2. Add arm,cs-dev-name to only CTI and sources' dt-binding.

Change since V2:
1. Fix the error in coresight core.
drivers/hwtracing/coresight/coresight-core.c:1775:7: error: assigning to 'char *' from 'const char *' discards qualifiers

2. Fix the warning when run dtbinding check.
Documentation/devicetree/bindings/arm/arm,coresight-cpu-debug.yaml: device-name: missing type definition

Change since V1:
1. Change coresight-name to device name.
2. Add the device-name in coresight dt bindings.

Mao Jinlong (2):
  dt-bindings: arm: Add label in the coresight components
  coresight: Add label sysfs node support

 .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
 .../sysfs-bus-coresight-devices-funnel        |  6 ++++
 .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
 .../bindings/arm/arm,coresight-cti.yaml       |  6 ++++
 .../arm/arm,coresight-dummy-sink.yaml         |  6 ++++
 .../arm/arm,coresight-dummy-source.yaml       |  6 ++++
 .../arm/arm,coresight-dynamic-funnel.yaml     |  6 ++++
 .../arm/arm,coresight-dynamic-replicator.yaml |  6 ++++
 .../arm/arm,coresight-static-funnel.yaml      |  6 ++++
 .../arm/arm,coresight-static-replicator.yaml  |  6 ++++
 .../bindings/arm/arm,coresight-tmc.yaml       |  6 ++++
 .../bindings/arm/qcom,coresight-tpda.yaml     |  6 ++++
 .../bindings/arm/qcom,coresight-tpdm.yaml     |  6 ++++
 drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++++++++++++++++++
 14 files changed, 110 insertions(+)

-- 
2.17.1



From quic_jinlmao at quicinc.com  Tue Dec 10 04:22:52 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Tue, 10 Dec 2024 20:22:52 +0800
Subject: [PATCH v5 1/2] dt-bindings: arm: Add label in the coresight components
In-Reply-To: <20241210122253.31926-1-quic_jinlmao@quicinc.com>
References: <20241210122253.31926-1-quic_jinlmao@quicinc.com>
Message-ID: <20241210122253.31926-2-quic_jinlmao@quicinc.com>

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 label to show hardware context information of each coresight
device. There will be a sysfs node label in each device folder.

cat /sys/bus/coresight/devices/cti_sys0/label

Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../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 ++++++
 .../bindings/arm/arm,coresight-static-funnel.yaml           | 6 ++++++
 .../bindings/arm/arm,coresight-static-replicator.yaml       | 6 ++++++
 .../devicetree/bindings/arm/arm,coresight-tmc.yaml          | 6 ++++++
 .../devicetree/bindings/arm/qcom,coresight-tpda.yaml        | 6 ++++++
 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml        | 6 ++++++
 10 files changed, 60 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml
index 2d5545a2b49c..5ca6d3d313a3 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml
@@ -98,6 +98,12 @@ properties:
   power-domains:
     maxItems: 1
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   arm,cti-ctm-id:
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml
index 08b89b62c505..bc82cd1f3595 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml
@@ -39,6 +39,12 @@ properties:
     enum:
       - arm,coresight-dummy-sink
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   in-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml
index 04a8c37b4aff..245929c36357 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml
@@ -38,6 +38,12 @@ properties:
     enum:
       - arm,coresight-dummy-source
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   out-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml
index 44a1041cb0fc..30776610d4b4 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml
@@ -57,6 +57,12 @@ properties:
   power-domains:
     maxItems: 1
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   in-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml
index 03792e9bd97a..178a3861ee29 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml
@@ -54,6 +54,12 @@ properties:
       - const: apb_pclk
       - const: atclk
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   power-domains:
     maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml
index cc8c3baa79b4..39b291909cc4 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml
@@ -30,6 +30,12 @@ properties:
   power-domains:
     maxItems: 1
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   in-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
index 1892a091ac35..ba10897043cf 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
@@ -39,6 +39,12 @@ properties:
         description: Input connection from CoreSight Trace bus
         $ref: /schemas/graph.yaml#/properties/port
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   out-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
index cb8dceaca70e..8d952150d7b9 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
@@ -55,6 +55,12 @@ properties:
       - const: apb_pclk
       - const: atclk
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   iommus:
     maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml
index 76163abed655..986b9b4f360d 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml
@@ -65,6 +65,12 @@ properties:
     items:
       - const: apb_pclk
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   in-ports:
     description: |
       Input connections from TPDM to TPDA
diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index 8eec07d9d454..59e533720bdd 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -77,6 +77,12 @@ properties:
     minimum: 0
     maximum: 32
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   clocks:
     maxItems: 1
 
-- 
2.17.1



From quic_jinlmao at quicinc.com  Tue Dec 10 04:22:53 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Tue, 10 Dec 2024 20:22:53 +0800
Subject: [PATCH v5 2/2] coresight: Add label sysfs node support
In-Reply-To: <20241210122253.31926-1-quic_jinlmao@quicinc.com>
References: <20241210122253.31926-1-quic_jinlmao@quicinc.com>
Message-ID: <20241210122253.31926-3-quic_jinlmao@quicinc.com>

For some coresight components like CTI and TPDM, there could be
numerous of them. From the node name, we can only get the type and
register address of the component. We can't identify the HW or the
system the component belongs to. Add label sysfs node support for
showing the intuitive name of the device.

Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
 .../sysfs-bus-coresight-devices-funnel        |  6 ++++
 .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
 drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++++++++++++++++++
 4 files changed, 50 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
index bf2869c413e7..631999571197 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
@@ -239,3 +239,9 @@ Date:		March 2020
 KernelVersion	5.7
 Contact:	Mike Leach or Mathieu Poirier
 Description:	(Write) Clear all channel / trigger programming.
+
+What:           /sys/bus/coresight/devices/<cti-name>/label
+Date:           Dec 2024
+KernelVersion   6.13
+Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
+Description:    (Read) Show hardware context information of device.
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
index d75acda5e1b3..6497756a5ced 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
@@ -10,3 +10,9 @@ Date:		November 2014
 KernelVersion:	3.19
 Contact:	Mathieu Poirier <mathieu.poirier at linaro.org>
 Description:	(RW) Defines input port priority order.
+
+What:           /sys/bus/coresight/devices/<memory_map>.funnel/label
+Date:           Dec 2024
+KernelVersion   6.13
+Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
+Description:    (Read) Show hardware context information of device.
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index bf710ea6e0ef..31dbf37a8754 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -257,3 +257,9 @@ 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 CMB subunit
 		TPDM.
+
+What:           /sys/bus/coresight/devices/<tpdm-name>/label
+Date:           Dec 2024
+KernelVersion   6.13
+Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
+Description:    (Read) Show hardware context information of device.
diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
index a01c9e54e2ed..4af40cd7d75a 100644
--- a/drivers/hwtracing/coresight/coresight-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-sysfs.c
@@ -7,6 +7,7 @@
 #include <linux/device.h>
 #include <linux/idr.h>
 #include <linux/kernel.h>
+#include <linux/property.h>
 
 #include "coresight-priv.h"
 #include "coresight-trace-id.h"
@@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(enable_source);
 
+static ssize_t label_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+
+	const char *str;
+	int ret = 0;
+
+	ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
+	if (ret == 0)
+		return scnprintf(buf, PAGE_SIZE, "%s\n", str);
+	else
+		return ret;
+}
+static DEVICE_ATTR_RO(label);
+
 static struct attribute *coresight_sink_attrs[] = {
 	&dev_attr_enable_sink.attr,
+	&dev_attr_label.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(coresight_sink);
 
 static struct attribute *coresight_source_attrs[] = {
 	&dev_attr_enable_source.attr,
+	&dev_attr_label.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(coresight_source);
 
+static struct attribute *coresight_link_attrs[] = {
+	&dev_attr_label.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(coresight_link);
+
+static struct attribute *coresight_helper_attrs[] = {
+	&dev_attr_label.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(coresight_helper);
+
 const struct device_type coresight_dev_type[] = {
 	[CORESIGHT_DEV_TYPE_SINK] = {
 		.name = "sink",
@@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
 	},
 	[CORESIGHT_DEV_TYPE_LINK] = {
 		.name = "link",
+		.groups = coresight_link_groups,
 	},
 	[CORESIGHT_DEV_TYPE_LINKSINK] = {
 		.name = "linksink",
@@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
 	},
 	[CORESIGHT_DEV_TYPE_HELPER] = {
 		.name = "helper",
+		.groups = coresight_helper_groups,
 	}
 };
 /* Ensure the enum matches the names and groups */
-- 
2.17.1



From peterz at infradead.org  Tue Dec 10 04:23:55 2024
From: peterz at infradead.org (Peter Zijlstra)
Date: Tue, 10 Dec 2024 13:23:55 +0100
Subject: [RFC PATCH 12/16] arm64: mm: Map p4d/pgd with privileged pkey
In-Reply-To: <75a345d4-78ea-4434-a4cd-3f2095ce2b31@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-13-kevin.brodsky@arm.com>
 <20241209102440.GI21636@noisy.programming.kicks-ass.net>
 <75a345d4-78ea-4434-a4cd-3f2095ce2b31@arm.com>
Message-ID: <20241210122355.GN8562@noisy.programming.kicks-ass.net>

On Tue, Dec 10, 2024 at 10:27:56AM +0100, Kevin Brodsky wrote:
> On 09/12/2024 11:24, Peter Zijlstra wrote:
> > On Fri, Dec 06, 2024 at 10:11:06AM +0000, Kevin Brodsky wrote:
> >> If CONFIG_KPKEYS_HARDENED_PGTABLES is enabled, map p4d/pgd pages
> >> using a privileged pkey (KPKEYS_PKEY_PGTABLES), so that they can
> >> only be written under guard(kpkeys_hardened_pgtables).
> >>
> >> The case where pgd is not page-sized is not currently handled -
> >> this is pending support for pkeys in kmem_cache.
> >>
> >> This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
> >> (default).
> > Should not this live in pagetable_*_[cd]tor() in generic code?
> 
> This would certainly be preferable but it doesn't look like such helpers
> exist for p4d/pgd. For p4d, we could potentially handle this in the
> generic __p4d_alloc(), but I'm not sure we can assume that
> p4d_alloc_one() won't be called from somewhere else. pgd_alloc() is
> entirely arch-specific so not much we can do there.

Can't we add the missing pagetable_{p4d,pgd}_[cd]tor() functions. Yes,
it will mean touching a bunch of arch code, but it shouldn't be hard.


From peterz at infradead.org  Tue Dec 10 04:27:06 2024
From: peterz at infradead.org (Peter Zijlstra)
Date: Tue, 10 Dec 2024 13:27:06 +0100
Subject: [RFC PATCH 13/16] arm64: mm: Reset pkey in __tlb_remove_table()
In-Reply-To: <7124d7f4-1d4c-4497-94d8-243af2ed071a@arm.com>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-14-kevin.brodsky@arm.com>
 <20241209102913.GJ21636@noisy.programming.kicks-ass.net>
 <7124d7f4-1d4c-4497-94d8-243af2ed071a@arm.com>
Message-ID: <20241210122706.GO8562@noisy.programming.kicks-ass.net>

On Tue, Dec 10, 2024 at 10:28:44AM +0100, Kevin Brodsky wrote:
> On 09/12/2024 11:29, Peter Zijlstra wrote:
> > On Fri, Dec 06, 2024 at 10:11:07AM +0000, Kevin Brodsky wrote:
> >> [...]
> >>
> >> diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
> >> index a947c6e784ed..d1611ffa6d91 100644
> >> --- a/arch/arm64/include/asm/tlb.h
> >> +++ b/arch/arm64/include/asm/tlb.h
> >> @@ -10,10 +10,14 @@
> >>  
> >>  #include <linux/pagemap.h>
> >>  #include <linux/swap.h>
> >> +#include <linux/kpkeys.h>
> >>  
> >>  static inline void __tlb_remove_table(void *_table)
> >>  {
> >> -	free_page_and_swap_cache((struct page *)_table);
> >> +	struct page *page = (struct page *)_table;
> >> +
> >> +	kpkeys_unprotect_pgtable_memory((unsigned long)page_address(page), 1);
> >> +	free_page_and_swap_cache(page);
> >>  }
> > Same as for the others, perhaps stick this in generic code instead of in
> > the arch code?
> 
> This should be doable, with some refactoring. __tlb_remove_table() is
> currently called from two functions in mm/mmu_gather.c, I suppose I
> could create a wrapper there that calls
> kpkeys_unprotect_pgtable_memory() and then __tlb_remove_table(). Like in
> the p4d case I do however wonder how robust this is, as
> __tlb_remove_table() could end up being called from other places.

I don't foresee other __tlb_remove_table() users, this is all rather
speicific code. But if there ever were to be new users, it is something
they would have to take into consideration.


From dmitry.baryshkov at linaro.org  Tue Dec 10 04:32:03 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 14:32:03 +0200
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2
 controller
In-Reply-To: <2d68155e.1e5b.193ae4616b9.Coremail.andyshrk@163.com>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241209150619.33998-1-dse@thaumatec.com>
 <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org>
 <2203458.KiezcSG77Q@diego>
 <4e015ea9.960.193ae0c236a.Coremail.andyshrk@163.com>
 <ay5hbnqqjhopaqof6z7j2rzm2bc6xa2vbzan2ak3if6wzmyip2@kqh7gtrajnm2>
 <33e2c5db.1300.193ae284b6d.Coremail.andyshrk@163.com>
 <CAA8EJprLA09NP0KAztc5eoAMkGcrom84jg_pcbNcwN0FAaSLrw@mail.gmail.com>
 <2d68155e.1e5b.193ae4616b9.Coremail.andyshrk@163.com>
Message-ID: <jl5obi7rd4h6ywozeqruxq2vx62sx5yf4wwpksrq3prdleps2k@d3zbr5ttquvn>

On Tue, Dec 10, 2024 at 09:54:09AM +0800, Andy Yan wrote:
> 
> Hi Dmitry,
> 
> ? 2024-12-10 09:45:11?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
> >On Tue, 10 Dec 2024 at 03:22, Andy Yan <andyshrk at 163.com> wrote:
> >>
> >>
> >> Hi Dmitry,
> >>
> >> ? 2024-12-10 09:01:38?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
> >> >On Tue, Dec 10, 2024 at 08:50:51AM +0800, Andy Yan wrote:
> >> >>
> >> >>
> >> >> Hi,
> >> >>
> >> >> At 2024-12-10 07:12:26, "Heiko St?bner" <heiko at sntech.de> wrote:
> >> >> >Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
> >> >> >> Hi,
> >> >> >>
> >> >> >> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
> >> >> >> > On 03.12.24 21:54, Heiko Stuebner wrote:
> >> >> >> > > This series adds a bridge and glue driver for the DSI2 controller found
> >> >> >> > > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
> >> >> >> > >
> >> >> >> >
> >> >> >> > I did more tests with different LVDS displays. I tested following
> >> >> >> > configurations with DSI/LVDS bridge:
> >> >> >> > - 1024x600 at 60.01
> >> >> >> > - 1024x768 at 60.02
> >> >> >> > - 1280x800 at 60.07
> >> >> >> > - 1366x768 at 60.06
> >> >> >> >
> >> >> >> > All of them worked without issues, except 1366x768.
> >> >> >> > With this resolution, video is blurry, and offset incorrectly
> >> >> >> > to the left. There are also repeating errors on the console:
> >> >> >> >
> >> >> >> >   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
> >> >> >> >
> >> >> >> > In correct operation with other resolutions, there is no error.
> >> >> >> > I am not sure if this is a problem in your series or rather in VOP2
> >> >> >> > driver.
> >> >> >
> >> >> >This really sounds like something is wrong on the vop side.
> >> >> >The interrupt is part of the vop, the divisable by 4 things likely too.
> >> >>
> >> >> This is a hardware limitation on vop side:
> >> >> The horizontal resolution must be 4 pixel aligned.
> >> >
> >> >Then mode_valid() and atomic_check() must reject modes that don't fit.
> >>
> >> We round down to 4 pixel aligned in mode_fixup in our bsp kernel,
> >
> >What is meant by the "bsp kernel" here? I don't see it being present
> 
> bsp kernel means downstream vendor kernel.
> 
> >in the mainline kernel. So, if the mode is unsupported, it should be
> 
> Will it be acceptable to add this round down in the mainline mode_fixup?

I think so.

> 
> >rejected.
> >
> >> because sometimes, some boards do indeed choose a screen that is not 4 pixel aligned

-- 
With best wishes
Dmitry


From kent.overstreet at linux.dev  Tue Dec 10 04:40:04 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Tue, 10 Dec 2024 07:40:04 -0500
Subject: arm64: stacktrace: unwind exception boundaries
In-Reply-To: <Z1gll87-TkAqFwUz@J2N7QTR9R3>
References: <36kx57aw46vwykgckr5cm4fafhw54tjuj4cqljrdnpfwvjl7if@a7znuhpfu54o>
 <zbwbgkuvvciezpmigcp6gaahfxwm7cwhpzus7gtbfnbzsjb2n3@kfbdppbd74o4>
 <Z1bWaGCvUrwrj2fZ@J2N7QTR9R3>
 <Z1gll87-TkAqFwUz@J2N7QTR9R3>
Message-ID: <rxc57eg65sg4iayhj7gc7yl24w524lviedxnydl2mggqnatglq@iairj2ci7ioj>

On Tue, Dec 10, 2024 at 11:27:19AM +0000, Mark Rutland wrote:
> On Mon, Dec 09, 2024 at 11:37:12AM +0000, Mark Rutland wrote:
> > Hi Kent,
> > 
> > On Thu, Dec 05, 2024 at 01:04:59PM -0500, Kent Overstreet wrote:
> > > On 6.13-rc1, I'm now seeing a ton of test failures due to this warning -
> > > what gives?
> > 
> > Sorry about this; I just sent what I *thought* was a fix for this:
> > 
> >   https://lore.kernel.org/linux-arm-kernel/20241209110351.1876804-1-mark.rutland at arm.com/
> > 
> > ... but re-reading the below I see you're actually hitting a different
> > issue.
> > 
> > > 00104 ========= TEST   generic/017
> > > 00104        run fstests generic/017 at 2024-12-05 11:47:43
> > > 00104 spectre-v4 mitigation disabled by command-line option
> > > 00106 bcachefs (vdc): starting version 1.13: inode_has_child_snapshots
> > > 00106 bcachefs (vdc): initializing new filesystem
> > > 00106 bcachefs (vdc): going read-write
> > > 00106 bcachefs (vdc): marking superblocks
> > > 00106 bcachefs (vdc): initializing freespace
> > > 00106 bcachefs (vdc): done initializing freespace
> > > 00106 bcachefs (vdc): reading snapshots table
> > > 00106 bcachefs (vdc): reading snapshots done
> > > 00106 bcachefs (vdc): done starting filesystem
> > > 00200 ------------[ cut here ]------------
> > > 00200 WARNING: CPU: 8 PID: 12571 at arch/arm64/kernel/stacktrace.c:223 arch_stack_walk+0x2c0/0x388
> > 
> > Looking at v6.13-rc1, that's the warning in
> > kunwind_next_frame_record_meta() for when the frame_record_meta::type is
> > not a valid value, which likely implies one of the following:
> > 
> > (a) The logic to identify a frame_record_meta is wrong.
> > 
> > (b) The entry logic has failed to initilialize pt_regs::stackframe::meta
> >     on an entry path somehow.
> > 
> > (c) The stack has been corrupted, and some frame record has been
> >     clobbered to look like a frame_record_meta.
> 
> Looking some more, I see that bch2_btree_transactions_read() is trying
> to unwind other tasks, and I believe what's happening here is that the
> unwindee isn't actually blocked for the duration of the unwind, leading
> to the unwinder encountering junk and consequently producing the
> warning.
> 
> As a test case, it's possible to trigger similar with a few parallel
> instances of:
> 
> 	while true; do cat /proc/*/stack > /dev/null
> 
> The only thing we can do on the arm64 side is remove the WARN_ON_ONCE(),
> which'll get rid of the splat. It seems we've never been unlucky enough
> to hit a stale fgraph entry, or that would've blown up also.
> 
> Regardless of the way arm64 behaves here, the unwind performed by
> bch2_btree_transactions_read() is going to contain garbage unless the
> task is pinned in a blocked state. AFAICT the way
> btree_trans::locking_wait::task is used is here is racy, and there's no
> guarantee that the unwindee is actually blocked.

Occasionally returning garbage is completely fine, as long as the
interface is otherwise safe. This is debug info; it's important that it
be available and we can't impose additional synchronization for it.


From lkp at intel.com  Tue Dec 10 04:41:53 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 10 Dec 2024 20:41:53 +0800
Subject: [PATCH mm-unstable 11/17] mm: sh: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-12-kaleshsingh@google.com>
References: <20241210024119.2488608-12-kaleshsingh@google.com>
Message-ID: <202412102044.uIAN0clk-lkp@intel.com>

Hi Kalesh,

kernel test robot noticed the following build warnings:

[auto build test WARNING on akpm-mm/mm-everything]

url:    https://github.com/intel-lab-lkp/linux/commits/Kalesh-Singh/mm-Introduce-generic_mmap_hint/20241210-104424
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20241210024119.2488608-12-kaleshsingh%40google.com
patch subject: [PATCH mm-unstable 11/17] mm: sh: Introduce arch_mmap_hint()
config: sh-randconfig-001-20241210 (https://download.01.org/0day-ci/archive/20241210/202412102044.uIAN0clk-lkp at intel.com/config)
compiler: sh4-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241210/202412102044.uIAN0clk-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/202412102044.uIAN0clk-lkp at intel.com/

All warnings (new ones prefixed by >>):

   arch/sh/mm/mmap.c: In function 'arch_get_unmapped_area':
>> arch/sh/mm/mmap.c:79:32: warning: unused variable 'vma' [-Wunused-variable]
      79 |         struct vm_area_struct *vma;
         |                                ^~~
>> arch/sh/mm/mmap.c:78:27: warning: unused variable 'mm' [-Wunused-variable]
      78 |         struct mm_struct *mm = current->mm;
         |                           ^~
   arch/sh/mm/mmap.c: In function 'arch_get_unmapped_area_topdown':
   arch/sh/mm/mmap.c:117:32: warning: unused variable 'vma' [-Wunused-variable]
     117 |         struct vm_area_struct *vma;
         |                                ^~~


vim +/vma +79 arch/sh/mm/mmap.c

2261b9c7c2357a0 Kalesh Singh      2024-12-09   73  
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   74  unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
25d4054cc97484f Mark Brown        2024-09-04   75  	unsigned long len, unsigned long pgoff, unsigned long flags,
25d4054cc97484f Mark Brown        2024-09-04   76  	vm_flags_t vm_flags)
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   77  {
4a4a9be3ebdbf17 Paul Mundt        2008-11-12  @78  	struct mm_struct *mm = current->mm;
4a4a9be3ebdbf17 Paul Mundt        2008-11-12  @79  	struct vm_area_struct *vma;
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   80  	int do_colour_align;
b80fa3cbb78c0fb Rick Edgecombe    2024-03-25   81  	struct vm_unmapped_area_info info = {};
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   82  
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   83  	if (flags & MAP_FIXED) {
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   84  		/* We do not accept a shared mapping if it would violate
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   85  		 * cache aliasing constraints.
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   86  		 */
e77414e0aad6a1b Al Viro           2009-12-05   87  		if ((flags & MAP_SHARED) &&
e77414e0aad6a1b Al Viro           2009-12-05   88  		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   89  			return -EINVAL;
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   90  		return addr;
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   91  	}
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   92  
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   93  	if (unlikely(len > TASK_SIZE))
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   94  		return -ENOMEM;
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   95  
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   96  	do_colour_align = 0;
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   97  	if (filp || (flags & MAP_SHARED))
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   98  		do_colour_align = 1;
4a4a9be3ebdbf17 Paul Mundt        2008-11-12   99  
2261b9c7c2357a0 Kalesh Singh      2024-12-09  100  	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
2261b9c7c2357a0 Kalesh Singh      2024-12-09  101  	if (addr)
4a4a9be3ebdbf17 Paul Mundt        2008-11-12  102  		return addr;
4a4a9be3ebdbf17 Paul Mundt        2008-11-12  103  
b4265f12340f809 Michel Lespinasse 2012-12-11  104  	info.length = len;
b4265f12340f809 Michel Lespinasse 2012-12-11  105  	info.low_limit = TASK_UNMAPPED_BASE;
b4265f12340f809 Michel Lespinasse 2012-12-11  106  	info.high_limit = TASK_SIZE;
b4265f12340f809 Michel Lespinasse 2012-12-11  107  	info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
b4265f12340f809 Michel Lespinasse 2012-12-11  108  	info.align_offset = pgoff << PAGE_SHIFT;
b4265f12340f809 Michel Lespinasse 2012-12-11  109  	return vm_unmapped_area(&info);
4a4a9be3ebdbf17 Paul Mundt        2008-11-12  110  }
ee1acbfabd5270b Paul Mundt        2009-05-07  111  

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


From gankulkarni at os.amperecomputing.com  Tue Dec 10 04:48:04 2024
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Tue, 10 Dec 2024 18:18:04 +0530
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer
 expired
In-Reply-To: <865xntt2kv.wl-maz@kernel.org>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
 <867c89tc4q.wl-maz@kernel.org>
 <c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
 <865xntt2kv.wl-maz@kernel.org>
Message-ID: <20a6d0d5-2733-4959-a9a1-bc6c2e64111f@os.amperecomputing.com>

> Please give the fixup below a go.
> 
> 	M.
> 
> [1] https://lore.kernel.org/all/20241202172134.384923-6-maz at kernel.org/
> 
>  From 2bbd6f9b41a20ad573376c20c158ff3c12db5009 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <maz at kernel.org>
> Date: Mon, 9 Dec 2024 10:58:08 +0000
> Subject: [PATCH] fixup! KVM: arm64: nv: Publish emulated timer interrupt state
>   in the in-memory state
> 
> ---
>   arch/arm64/kvm/arch_timer.c | 32 +++++++++++++-------------------
>   1 file changed, 13 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 895f09658ef83..91bda986c344b 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -432,25 +432,6 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
>   {
>   	int ret;
>   
> -	/*
> -	 * Paper over NV2 brokenness by publishing the interrupt status
> -	 * bit. This still results in a poor quality of emulation (guest
> -	 * writes will have no effect until the next exit).
> -	 *
> -	 * But hey, it's fast, right?
> -	 */
> -	if (is_hyp_ctxt(vcpu) &&
> -	    (timer_ctx == vcpu_vtimer(vcpu) || timer_ctx == vcpu_ptimer(vcpu))) {
> -		u32 ctl = timer_get_ctl(timer_ctx);
> -
> -		if (new_level)
> -			ctl |= ARCH_TIMER_CTRL_IT_STAT;
> -		else
> -			ctl &= ~ARCH_TIMER_CTRL_IT_STAT;
> -
> -		timer_set_ctl(timer_ctx, ctl);
> -	}
> -
>   	timer_ctx->irq.level = new_level;
>   	trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_irq(timer_ctx),
>   				   timer_ctx->irq.level);
> @@ -471,6 +452,19 @@ static void timer_emulate(struct arch_timer_context *ctx)
>   
>   	trace_kvm_timer_emulate(ctx, should_fire);
>   
> +	/*
> +	 * Paper over NV2 brokenness by publishing the interrupt status
> +	 * bit. This still results in a poor quality of emulation (guest
> +	 * writes will have no effect until the next exit).
> +	 *
> +	 * But hey, it's fast, right?
> +	 */
> +	if (is_hyp_ctxt(ctx->vcpu)) {
> +		unsigned long val = timer_get_ctl(ctx);
> +		__assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &val, should_fire);
> +		timer_set_ctl(ctx, val);
> +	}
> +
>   	if (should_fire != ctx->irq.level) {
>   		kvm_timer_update_irq(ctx->vcpu, should_fire, ctx);
>   		return;

I tried this patch and it did not work, looks like there are some 
exit/entry paths which updates timer interrupt without going though 
timer_emulate (like kvm_hrtimer_expire). If I undo the deleted lines in 
above diff in the function kvm_timer_update_irq, then it is working.

below is the diff which is working.

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index dd038d62e99b..a54bdb6dc566 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -432,23 +432,11 @@ static void kvm_timer_update_irq(struct kvm_vcpu 
*vcpu, bool new_level,
  {
         int ret;

-       /*
-        * Paper over NV2 brokenness by publishing the interrupt status
-        * bit. This still results in a poor quality of emulation (guest
-        * writes will have no effect until the next exit).
-        *
-        * But hey, it's fast, right?
-        */
         if (is_hyp_ctxt(vcpu) &&
             (timer_ctx == vcpu_vtimer(vcpu) || timer_ctx == 
vcpu_ptimer(vcpu))) {
-               u32 ctl = timer_get_ctl(timer_ctx);
-
-               if (new_level)
-                       ctl |= ARCH_TIMER_CTRL_IT_STAT;
-               else
-                       ctl &= ~ARCH_TIMER_CTRL_IT_STAT;
-
-               timer_set_ctl(timer_ctx, ctl);
+               unsigned long val = timer_get_ctl(timer_ctx);
+               __assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &val, 
new_level);
+               timer_set_ctl(timer_ctx, val);
         }

         timer_ctx->irq.level = new_level;
@@ -471,6 +459,19 @@ static void timer_emulate(struct arch_timer_context 
*ctx)

         trace_kvm_timer_emulate(ctx, should_fire);

+       /*
+        * Paper over NV2 brokenness by publishing the interrupt status
+        * bit. This still results in a poor quality of emulation (guest
+        * writes will have no effect until the next exit).
+        *
+        * But hey, it's fast, right?
+        */
+       if (is_hyp_ctxt(ctx->vcpu)) {
+               unsigned long val = timer_get_ctl(ctx);
+               __assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &val, 
should_fire);
+               timer_set_ctl(ctx, val);
+       }
+
         if (should_fire != ctx->irq.level) {
                 kvm_timer_update_irq(ctx->vcpu, should_fire, ctx);
                 return;
@@ -948,9 +949,6 @@ void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
          * which allows trapping of the timer registers even with NV2.
          * Still, this is still worse than FEAT_NV on its own. Meh.
          */
-       if (cpus_have_final_cap(ARM64_HAS_ECV) || !is_hyp_ctxt(vcpu))
-               return;
-
         if (!vcpu_el2_e2h_is_set(vcpu)) {
                 /*
                  * A non-VHE guest hypervisor doesn't have any direct 
access
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 2c35e1f8193e..52a263e7dcca 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1238,7 +1238,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
                 if (static_branch_unlikely(&userspace_irqchip_in_use))
                         kvm_timer_sync_user(vcpu);

-               if (vcpu_has_nv(vcpu))
+               if (is_hyp_ctxt(vcpu))
                         kvm_timer_sync_nested(vcpu);

                 kvm_arch_vcpu_ctxsync_fp(vcpu);


-- 
Thanks,
Ganapat/GK



From andyshrk at 163.com  Tue Dec 10 04:48:12 2024
From: andyshrk at 163.com (Andy Yan)
Date: Tue, 10 Dec 2024 20:48:12 +0800 (CST)
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2
 controller
In-Reply-To: <jl5obi7rd4h6ywozeqruxq2vx62sx5yf4wwpksrq3prdleps2k@d3zbr5ttquvn>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <20241209150619.33998-1-dse@thaumatec.com>
 <D67AV178CEBD.3QA9VD4ZPRNQ1@cknow.org> <2203458.KiezcSG77Q@diego>
 <4e015ea9.960.193ae0c236a.Coremail.andyshrk@163.com>
 <ay5hbnqqjhopaqof6z7j2rzm2bc6xa2vbzan2ak3if6wzmyip2@kqh7gtrajnm2>
 <33e2c5db.1300.193ae284b6d.Coremail.andyshrk@163.com>
 <CAA8EJprLA09NP0KAztc5eoAMkGcrom84jg_pcbNcwN0FAaSLrw@mail.gmail.com>
 <2d68155e.1e5b.193ae4616b9.Coremail.andyshrk@163.com>
 <jl5obi7rd4h6ywozeqruxq2vx62sx5yf4wwpksrq3prdleps2k@d3zbr5ttquvn>
Message-ID: <78e7b8e.b5ee.193b09ce46d.Coremail.andyshrk@163.com>


Hi All,
? 2024-12-10 20:32:03?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
>On Tue, Dec 10, 2024 at 09:54:09AM +0800, Andy Yan wrote:
>> 
>> Hi Dmitry,
>> 
>> ? 2024-12-10 09:45:11?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
>> >On Tue, 10 Dec 2024 at 03:22, Andy Yan <andyshrk at 163.com> wrote:
>> >>
>> >>
>> >> Hi Dmitry,
>> >>
>> >> ? 2024-12-10 09:01:38?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
>> >> >On Tue, Dec 10, 2024 at 08:50:51AM +0800, Andy Yan wrote:
>> >> >>
>> >> >>
>> >> >> Hi,
>> >> >>
>> >> >> At 2024-12-10 07:12:26, "Heiko St?bner" <heiko at sntech.de> wrote:
>> >> >> >Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
>> >> >> >> Hi,
>> >> >> >>
>> >> >> >> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
>> >> >> >> > On 03.12.24 21:54, Heiko Stuebner wrote:
>> >> >> >> > > This series adds a bridge and glue driver for the DSI2 controller found
>> >> >> >> > > in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
>> >> >> >> > >
>> >> >> >> >
>> >> >> >> > I did more tests with different LVDS displays. I tested following
>> >> >> >> > configurations with DSI/LVDS bridge:
>> >> >> >> > - 1024x600 at 60.01
>> >> >> >> > - 1024x768 at 60.02
>> >> >> >> > - 1280x800 at 60.07
>> >> >> >> > - 1366x768 at 60.06
>> >> >> >> >
>> >> >> >> > All of them worked without issues, except 1366x768.
>> >> >> >> > With this resolution, video is blurry, and offset incorrectly
>> >> >> >> > to the left. There are also repeating errors on the console:
>> >> >> >> >
>> >> >> >> >   rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at vp3
>> >> >> >> >
>> >> >> >> > In correct operation with other resolutions, there is no error.
>> >> >> >> > I am not sure if this is a problem in your series or rather in VOP2
>> >> >> >> > driver.
>> >> >> >
>> >> >> >This really sounds like something is wrong on the vop side.
>> >> >> >The interrupt is part of the vop, the divisable by 4 things likely too.
>> >> >>
>> >> >> This is a hardware limitation on vop side:
>> >> >> The horizontal resolution must be 4 pixel aligned.
>> >> >
>> >> >Then mode_valid() and atomic_check() must reject modes that don't fit.
>> >>
>> >> We round down to 4 pixel aligned in mode_fixup in our bsp kernel,
>> >
>> >What is meant by the "bsp kernel" here? I don't see it being present
>> 
>> bsp kernel means downstream vendor kernel.
>> 
>> >in the mainline kernel. So, if the mode is unsupported, it should be
>> 
>> Will it be acceptable to add this round down in the mainline mode_fixup?
>
>I think so.

Then I can write a patch for it.

>
>> 
>> >rejected.
>> >
>> >> because sometimes, some boards do indeed choose a screen that is not 4 pixel aligned
>
>-- 
>With best wishes
>Dmitry

From broonie at kernel.org  Tue Dec 10 05:00:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 13:00:57 +0000
Subject: [PATCH v2] spi: zynq-qspi: Add check for clk_enable()
In-Reply-To: <20241207015206.3689364-1-zmw12306@gmail.com>
References: <20241207015206.3689364-1-zmw12306@gmail.com>
Message-ID: <173383565712.34030.16922746389125728063.b4-ty@kernel.org>

On Fri, 06 Dec 2024 20:52:06 -0500, Mingwei Zheng wrote:
> Add check for the return value of clk_enable() to catch the potential
> error.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: zynq-qspi: Add check for clk_enable()
      commit: 8332e667099712e05ec87ba2058af394b51ebdc9

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 pgwipeout at gmail.com  Tue Dec 10 05:01:19 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 08:01:19 -0500
Subject: [PATCH 5/6] arm64: dts: rockchip: correct rk3328-roc regulator map
In-Reply-To: <14451790.lVVuGzaMjS@diego>
References: <20241210013010.81257-1-pgwipeout@gmail.com> <20241210013010.81257-6-pgwipeout@gmail.com>
 <14451790.lVVuGzaMjS@diego>
Message-ID: <CAMdYzYquzAnwbUidBjif3OXOcLaGD+3GdB79Op94BCno2ZtBAQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 5:54?AM Heiko St?bner <heiko at sntech.de> wrote:
>
> Am Dienstag, 10. Dezember 2024, 02:30:09 CET schrieb Peter Geis:
> > The rk3328-roc-cc input power is sourced from a micro-usb port, while
> > the rk3328-roc-pc input power is sourced from a usb-c port. Both inputs
> > are 5vdc only. Remove the 12v input from the device tree.
>
> full stop. Please don't do "While we are at it" commits.
>
> > While we are at it, add missing voltages and supply to vcc_phy, missing
> > voltages to vcc_host1_5v, and standardize the order of regulator
> > properties among the fixed regulators.
>
> This second part wants to be its own commit :-) .

Thank you, you're right I was torn between doing not enough and doing
too much and ended up doing both. Thinking about it now this should be
at least three patches:
- Power input
- Drop the phy regulator (it's directly tied to vcc_io, not a separate device)
- Cosmetic changes.

Thanks again!
Peter

>
> Thanks
> Heiko
>
> > Fixes: 2171f4fdac06 ("arm64: dts: rockchip: add roc-rk3328-cc board")
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> >
> >  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 23 +++++++++++++-------
> >  1 file changed, 15 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > index f782c8220dd3..6984387ff8b3 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > @@ -24,22 +24,23 @@ gmac_clkin: external-gmac-clock {
> >               #clock-cells = <0>;
> >       };
> >
> > -     dc_12v: regulator-dc-12v {
> > +     /* fed from passive usb input connector */
> > +     dc_5v: regulator-dc-5v {
> >               compatible = "regulator-fixed";
> > -             regulator-name = "dc_12v";
> > +             regulator-name = "dc_5v";
> >               regulator-always-on;
> >               regulator-boot-on;
> > -             regulator-min-microvolt = <12000000>;
> > -             regulator-max-microvolt = <12000000>;
> > +             regulator-min-microvolt = <5000000>;
> > +             regulator-max-microvolt = <5000000>;
> >       };
> >
> >       vcc_sd: regulator-sdmmc {
> >               compatible = "regulator-fixed";
> > +             regulator-name = "vcc_sd";
> >               gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
> >               pinctrl-names = "default";
> >               pinctrl-0 = <&sdmmc0m1_pin>;
> >               regulator-boot-on;
> > -             regulator-name = "vcc_sd";
> >               regulator-min-microvolt = <3300000>;
> >               regulator-max-microvolt = <3300000>;
> >               vin-supply = <&vcc_io>;
> > @@ -50,22 +51,25 @@ vcc_sdio: regulator-sdmmcio {
> >               states = <1800000 0x1>, <3300000 0x0>;
> >               regulator-name = "vcc_sdio";
> >               regulator-type = "voltage";
> > +             regulator-always-on;
> >               regulator-min-microvolt = <1800000>;
> >               regulator-max-microvolt = <3300000>;
> > -             regulator-always-on;
> >               vin-supply = <&vcc_sys>;
> >       };
> >
> >       vcc_host1_5v: vcc_otg_5v: regulator-vcc-host1-5v {
> >               compatible = "regulator-fixed";
> > +             regulator-name = "vcc_host1_5v";
> >               enable-active-high;
> >               pinctrl-names = "default";
> >               pinctrl-0 = <&usb20_host_drv>;
> > -             regulator-name = "vcc_host1_5v";
> >               regulator-always-on;
> > +             regulator-min-microvolt = <5000000>;
> > +             regulator-max-microvolt = <5000000>;
> >               vin-supply = <&vcc_sys>;
> >       };
> >
> > +     /* sourced from usb input through 3A fuse */
> >       vcc_sys: regulator-vcc-sys {
> >               compatible = "regulator-fixed";
> >               regulator-name = "vcc_sys";
> > @@ -73,7 +77,7 @@ vcc_sys: regulator-vcc-sys {
> >               regulator-boot-on;
> >               regulator-min-microvolt = <5000000>;
> >               regulator-max-microvolt = <5000000>;
> > -             vin-supply = <&dc_12v>;
> > +             vin-supply = <&dc_5v>;
> >       };
> >
> >       vcc_phy: regulator-vcc-phy {
> > @@ -81,6 +85,9 @@ vcc_phy: regulator-vcc-phy {
> >               regulator-name = "vcc_phy";
> >               regulator-always-on;
> >               regulator-boot-on;
> > +             regulator-min-microvolt = <3300000>;
> > +             regulator-max-microvolt = <3300000>;
> > +             vin-supply = <&vcc_io>;
> >       };
> >
> >       leds {
> >
>
>
>
>


From yangyicong at huawei.com  Tue Dec 10 05:02:20 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 21:02:20 +0800
Subject: [PATCH v4 08/10] drivers/perf: hisi: Export associated CPUs of
 each PMU through sysfs
In-Reply-To: <20241210113949.GE14735@willie-the-truck>
References: <20241203125049.39458-1-yangyicong@huawei.com>
 <20241203125049.39458-9-yangyicong@huawei.com>
 <20241209154830.GC12428@willie-the-truck>
 <22a35ead-0f0b-39a8-16bd-333143081ea8@huawei.com>
 <20241210113949.GE14735@willie-the-truck>
Message-ID: <b9f1eeef-e3db-415a-e8a2-0604ca1d6519@huawei.com>

On 2024/12/10 19:39, Will Deacon wrote:
> On Tue, Dec 10, 2024 at 06:49:15PM +0800, Yicong Yang wrote:
>> On 2024/12/9 23:48, Will Deacon wrote:
>>> On Tue, Dec 03, 2024 at 08:50:47PM +0800, Yicong Yang wrote:
>>>> From: Yicong Yang <yangyicong at hisilicon.com>
>>>>
>>>> Although the event of the uncore PMU can only be opened on a single
>>>> CPU, some PMU does have the affinity on a range of CPUs. For example
>>>> the L3C PMU is associated to the CPUs sharing the L3T it monitors.
>>>> Users may infer this affinity by the PMU name which may have SCCL ID
>>>> and CCL ID encoded (for L3C etc), but it's not that straightforward.
>>>> So export this information by adding an "associated_cpus" sysfs
>>>> attribute then user can get this directly.
>>>>
>>>> Reviewed-by: Jonathan Cameron <Joanthan.Cameron at huawei.com>
>>>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>>>> ---
>>>>  Documentation/admin-guide/perf/hisi-pmu.rst |  5 ++++-
>>>>  drivers/perf/hisilicon/hisi_uncore_pmu.c    | 10 ++++++++++
>>>>  2 files changed, 14 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
>>>> index 5cc248d18c63..48992a0b8e94 100644
>>>> --- a/Documentation/admin-guide/perf/hisi-pmu.rst
>>>> +++ b/Documentation/admin-guide/perf/hisi-pmu.rst
>>>> @@ -35,7 +35,10 @@ e.g. hisi_sccl1_hha0/rx_operations is RX_OPERATIONS event of HHA index #0 in
>>>>  SCCL ID #1.
>>>>  
>>>>  The driver also provides a "cpumask" sysfs attribute, which shows the CPU core
>>>> -ID used to count the uncore PMU event.
>>>> +ID used to count the uncore PMU event. An "associated_cpus" sysfs attribute is
>>>> +also provided to show the CPUs associated with this PMU. The "cpumask" indicates
>>>> +the CPUs to open the events, usually as a hint for userspaces tools like perf.
>>>> +It only contains one associated CPU from the "associated_cpus".
>>>
>>> What is userspace expected to do with this information? Can you point me
>>> to patches that add the corresponding support to the 'perf' tool, please?
>>>
>>
>> two attributes here, "cpumask" and "associated_cpus". For "cpumask" it's used in
>> perf [1], this patch does no change to this attribute but only update the
>> description in the doc.
>>
>> I think you're questioning about the "associated_cpus" introduced by this patch,
>> which is not intended to be used by the perf tools but provides a hint for the
>> user to know the CPUs monitored by which uncore PMU, for example which uncore
>> L3C PMU's monitoring the events by the CPU(s) the application's running on, or
>> if the counts is imbalanced among the L3C PMUs user can figure out what's running
>> on the CPUs provided by the "associated_cpus". As described in the commit this
>> can also inferred by the PMU name to map SICL ID and CCL ID to certain CPU cluster,
>> but these ID's aren't readable enough and it'll be more straightforward and
>> friendly to provide an "associated_cpus" information, considering we've already
>> maintain it in the drvier.
> 
> Bah. I just noticed that there's precedent for this in the Arm CSPMU driver,
> so I don't really have a leg to stand on despite my objections to funneling
> firmware information through to userspace without a confirmed user.
> 

it's bit complex to identify the uncore PMU in the system for better usage
of monitoring or performance analyzing since there are many instances like L3C
and DDRC PMU in the system. So this maybe an easier and cheaper way for the
user to map the PMU to the CPUs where interested tasks' running on without
much knowledge/documentation of the platform specific information like ID
mapping which may varies from different products.

Thanks.



From broonie at kernel.org  Tue Dec 10 05:02:31 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 13:02:31 +0000
Subject: (subset) [PATCH 0/5] regulator: pca9450: collect some
 improvement patches
In-Reply-To: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
References: <20241205-pca9450-v1-0-aab448b74e78@nxp.com>
Message-ID: <173383575122.36957.4079934608520923537.b4-ty@kernel.org>

On Thu, 05 Dec 2024 11:51:08 -0500, Frank Li wrote:
> Add pca9452 support
> Use dev_err_probe() to simple code
> add pca9452 support in imx93-14x14 dts
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[1/5] regulator: pca9450: add enable_value for all bucks
      commit: 229773f90b1f886e8fd542f98b495c66e43be5ba
[2/5] regulator: pca9450: Use dev_err_probe() to simplify code
      commit: 0f5c601098bd3c9cdfea3e01aacdd9d0c4010ea7
[3/5] regulator: dt-bindings: pca9450: Add pca9452 support
      commit: 17b531c162e5dbdce9a184ccd1c730ae3f31576b
[4/5] regulator: pca9450: Add PMIC pca9452 support
      commit: 017b76fb8e5b6066f6791e7ad2387deb2c9c9a14

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 tabba at google.com  Tue Dec 10 05:02:45 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 13:02:45 +0000
Subject: [PATCH v2 04/18] KVM: arm64: Move host page ownership tracking to
 the hyp vmemmap
In-Reply-To: <20241203103735.2267589-5-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-5-qperret@google.com>
Message-ID: <CA+EHjTx13V1BcyWEAjNSC0JCxr+dSUvutC7z2KSRu_8jwV_Vxw@mail.gmail.com>

Hi Quentin,

On Tue, 3 Dec 2024 at 10:37, Quentin Perret <qperret at google.com> wrote:
>
> We currently store part of the page-tracking state in PTE software bits
> for the host, guests and the hypervisor. This is sub-optimal when e.g.
> sharing pages as this forces to break block mappings purely to support
> this software tracking. This causes an unnecessarily fragmented stage-2
> page-table for the host in particular when it shares pages with Secure,
> which can lead to measurable regressions. Moreover, having this state
> stored in the page-table forces us to do multiple costly walks on the
> page transition path, hence causing overhead.
>
> In order to work around these problems, move the host-side page-tracking
> logic from SW bits in its stage-2 PTEs to the hypervisor's vmemmap.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/memory.h |  6 +-
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 94 ++++++++++++++++--------
>  arch/arm64/kvm/hyp/nvhe/setup.c          |  7 +-
>  3 files changed, 71 insertions(+), 36 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> index 88cb8ff9e769..08f3a0416d4c 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> @@ -8,7 +8,7 @@
>  #include <linux/types.h>
>
>  /*
> - * SW bits 0-1 are reserved to track the memory ownership state of each page:
> + * Bits 0-1 are reserved to track the memory ownership state of each page:
>   *   00: The page is owned exclusively by the page-table owner.
>   *   01: The page is owned by the page-table owner, but is shared
>   *       with another entity.

Not shown in this patch, but a couple of lines below, you might want
to update the comment on PKVM_NOPAGE to fix the reference to "PTE's SW
bits":

> /* Meta-states which aren't encoded directly in the PTE's SW bits */
> PKVM_NOPAGE = BIT(2),

> @@ -44,7 +44,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
>  struct hyp_page {
>         u16 refcount;
>         u8 order;
> -       u8 reserved;
> +
> +       /* Host (non-meta) state. Guarded by the host stage-2 lock. */
> +       enum pkvm_page_state host_state : 8;
>  };
>
>  extern u64 __hyp_vmemmap;
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index caba3e4bd09e..1595081c4f6b 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -201,8 +201,8 @@ static void *guest_s2_zalloc_page(void *mc)
>
>         memset(addr, 0, PAGE_SIZE);
>         p = hyp_virt_to_page(addr);
> -       memset(p, 0, sizeof(*p));
>         p->refcount = 1;
> +       p->order = 0;
>
>         return addr;
>  }
> @@ -268,6 +268,7 @@ int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd)
>
>  void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
>  {
> +       struct hyp_page *page;
>         void *addr;
>
>         /* Dump all pgtable pages in the hyp_pool */
> @@ -279,7 +280,9 @@ void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
>         /* Drain the hyp_pool into the memcache */
>         addr = hyp_alloc_pages(&vm->pool, 0);
>         while (addr) {
> -               memset(hyp_virt_to_page(addr), 0, sizeof(struct hyp_page));
> +               page = hyp_virt_to_page(addr);
> +               page->refcount = 0;
> +               page->order = 0;
>                 push_hyp_memcache(mc, addr, hyp_virt_to_phys);
>                 WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1));
>                 addr = hyp_alloc_pages(&vm->pool, 0);
> @@ -382,19 +385,25 @@ bool addr_is_memory(phys_addr_t phys)
>         return !!find_mem_range(phys, &range);
>  }
>
> -static bool addr_is_allowed_memory(phys_addr_t phys)
> +static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
> +{
> +       return range->start <= addr && addr < range->end;
> +}
> +
> +static int range_is_allowed_memory(u64 start, u64 end)

The name of this function "range_*is*_..." implies that it returns a
boolean, which other functions in this file (and patch) with similar
names do, but it returns an error instead. Maybe
check_range_allowed_memory)?

>  {
>         struct memblock_region *reg;
>         struct kvm_mem_range range;
>
> -       reg = find_mem_range(phys, &range);
> +       /* Can't check the state of both MMIO and memory regions at once */

I don't understand this comment in relation to the code. Could you
explain it to me please?

> +       reg = find_mem_range(start, &range);
> +       if (!is_in_mem_range(end - 1, &range))
> +               return -EINVAL;
>
> -       return reg && !(reg->flags & MEMBLOCK_NOMAP);
> -}
> +       if (!reg || reg->flags & MEMBLOCK_NOMAP)
> +               return -EPERM;
>
> -static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
> -{
> -       return range->start <= addr && addr < range->end;
> +       return 0;
>  }
>
>  static bool range_is_memory(u64 start, u64 end)
> @@ -454,8 +463,11 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
>         if (kvm_pte_valid(pte))
>                 return -EAGAIN;
>
> -       if (pte)
> +       if (pte) {
> +               WARN_ON(addr_is_memory(addr) &&
> +                       !(hyp_phys_to_page(addr)->host_state & PKVM_NOPAGE));

nit: since the host state is now an enum, should this just be an
equality check rather than an &? This makes it consistent with other
checks of pkvm_page_state in this patch too.

>                 return -EPERM;
> +       }
>
>         do {
>                 u64 granule = kvm_granule_size(level);
> @@ -477,10 +489,29 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
>         return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
>  }
>
> +static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm_page_state state)
> +{
> +       phys_addr_t end = addr + size;

nit: newline

> +       for (; addr < end; addr += PAGE_SIZE)
> +               hyp_phys_to_page(addr)->host_state = state;
> +}
> +
>  int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
>  {
> -       return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
> -                              addr, size, &host_s2_pool, owner_id);
> +       int ret;
> +
> +       ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
> +                             addr, size, &host_s2_pool, owner_id);
> +       if (ret || !addr_is_memory(addr))
> +               return ret;

Can hyp set an owner for an address that isn't memory? Trying to
understand why we need to update the host stage2 pagetable but not the
hypervisor's vmemmap in that case.

> +
> +       /* Don't forget to update the vmemmap tracking for the host */
> +       if (owner_id == PKVM_ID_HOST)
> +               __host_update_page_state(addr, size, PKVM_PAGE_OWNED);
> +       else
> +               __host_update_page_state(addr, size, PKVM_NOPAGE);
> +
> +       return 0;
>  }
>
>  static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
> @@ -604,35 +635,38 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size,
>         return kvm_pgtable_walk(pgt, addr, size, &walker);
>  }
>
> -static enum pkvm_page_state host_get_page_state(kvm_pte_t pte, u64 addr)
> -{
> -       if (!addr_is_allowed_memory(addr))
> -               return PKVM_NOPAGE;
> -
> -       if (!kvm_pte_valid(pte) && pte)
> -               return PKVM_NOPAGE;
> -
> -       return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
> -}
> -
>  static int __host_check_page_state_range(u64 addr, u64 size,
>                                          enum pkvm_page_state state)
>  {
> -       struct check_walk_data d = {
> -               .desired        = state,
> -               .get_page_state = host_get_page_state,
> -       };
> +       u64 end = addr + size;
> +       int ret;
> +
> +       ret = range_is_allowed_memory(addr, end);
> +       if (ret)
> +               return ret;
>
>         hyp_assert_lock_held(&host_mmu.lock);
> -       return check_page_state_range(&host_mmu.pgt, addr, size, &d);
> +       for (; addr < end; addr += PAGE_SIZE) {
> +               if (hyp_phys_to_page(addr)->host_state != state)
> +                       return -EPERM;
> +       }
> +
> +       return 0;
>  }
>
>  static int __host_set_page_state_range(u64 addr, u64 size,
>                                        enum pkvm_page_state state)
>  {
> -       enum kvm_pgtable_prot prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, state);
> +       if (hyp_phys_to_page(addr)->host_state & PKVM_NOPAGE) {

Same nit as above regarding checking for PKVM_NOPAGE

Cheers,
/fuad


> +               int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT);
>
> -       return host_stage2_idmap_locked(addr, size, prot);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       __host_update_page_state(addr, size, state);
> +
> +       return 0;
>  }
>
>  static int host_request_owned_transition(u64 *completer_addr,
> diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> index cbdd18cd3f98..7e04d1c2a03d 100644
> --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> @@ -180,7 +180,6 @@ static void hpool_put_page(void *addr)
>  static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
>                                      enum kvm_pgtable_walk_flags visit)
>  {
> -       enum kvm_pgtable_prot prot;
>         enum pkvm_page_state state;
>         phys_addr_t phys;
>
> @@ -203,16 +202,16 @@ static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
>         case PKVM_PAGE_OWNED:
>                 return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP);
>         case PKVM_PAGE_SHARED_OWNED:
> -               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED);
> +               hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_BORROWED;
>                 break;
>         case PKVM_PAGE_SHARED_BORROWED:
> -               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
> +               hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_OWNED;
>                 break;
>         default:
>                 return -EINVAL;
>         }
>
> -       return host_stage2_idmap_locked(phys, PAGE_SIZE, prot);
> +       return 0;
>  }
>
>  static int fix_hyp_pgtable_refcnt_walker(const struct kvm_pgtable_visit_ctx *ctx,
> --
> 2.47.0.338.g60cca15819-goog
>


From daniel.baluta at nxp.com  Tue Dec 10 04:53:32 2024
From: daniel.baluta at nxp.com (Daniel Baluta)
Date: Tue, 10 Dec 2024 14:53:32 +0200
Subject: [PATCH v3 0/6] Configure imx8mp dsp node for rproc usage
Message-ID: <20241210125338.104959-1-daniel.baluta@nxp.com>

DSP found in i.MX8MP SOC can be used by multiple frameworks in order to
enable various applications:
        - rproc/rpmsg framework, used to load for example Zephyr samples
        - Sound Open Firmware, used to enable various audio processing
          pipelines.

Current dsp node was configured with SOF in mind but it doesn't work
well with imx8mp-evk dts. SOF controls audio IPs from firmware side
while imx8mp-evk preffers to control audio IPs from Linux side.

So, configure 'dsp' node to be used with rproc scenario and later will
add a separate dts or an overlay to configure the node for SOF.

This patch series configures and enables dsp node to be used with rproc.

Changes since v1:
        - document syscon compatible as pointed by Peng Fan
        - do not disable dsp_reserved node in the dtsi file as pointed
          by Ahmad Fatoum.
Changes since v2:
        - Fix dts example in patch 4/6
        - Frank Li commented that we should handle the reset using the reset
        interface. I have two objections on this: we are using some bits from audiomix
        for reset together some other bits from DAP region. Also, the implementation is already upstream!
        Frank Li agreed that it's up to Rob opinion on this.

Daniel Baluta (6):
  arm64: dts: imx8mp: Add mu2 root clock
  arm64: dts: imx8mp: Configure dsp node for rproc usage
  arm64: dts: imx8mp: Add DSP clocks
  dt-bindings: clock: imx8mp: Add syscon compatible
  arm64: dts: imx8mp: Add fsl,dsp-ctrl property for dsp
  arm64: dts: Add dsp rproc related mem regions

 .../bindings/clock/imx8mp-audiomix.yaml       |  6 +++--
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts  | 10 +++++++++
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     | 22 ++++++++++++-------
 3 files changed, 28 insertions(+), 10 deletions(-)

-- 
2.25.1



From daniel.baluta at nxp.com  Tue Dec 10 04:53:33 2024
From: daniel.baluta at nxp.com (Daniel Baluta)
Date: Tue, 10 Dec 2024 14:53:33 +0200
Subject: [PATCH v3 1/6] arm64: dts: imx8mp: Add mu2 root clock
In-Reply-To: <20241210125338.104959-1-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
Message-ID: <20241210125338.104959-2-daniel.baluta@nxp.com>

Enable MU2 node and add mu2 root clock.
MU2 is used to communicate with DSP core.

Signed-off-by: Daniel Baluta <daniel.baluta 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 e0d3b8cba221..00924e0836db 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1252,7 +1252,7 @@ mu2: mailbox at 30e60000 {
 				reg = <0x30e60000 0x10000>;
 				interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
 				#mbox-cells = <2>;
-				status = "disabled";
+				clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_MU2_ROOT>;
 			};
 
 			i2c5: i2c at 30ad0000 {
-- 
2.25.1



From daniel.baluta at nxp.com  Tue Dec 10 04:53:34 2024
From: daniel.baluta at nxp.com (Daniel Baluta)
Date: Tue, 10 Dec 2024 14:53:34 +0200
Subject: [PATCH v3 2/6] arm64: dts: imx8mp: Configure dsp node for rproc usage
In-Reply-To: <20241210125338.104959-1-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
Message-ID: <20241210125338.104959-3-daniel.baluta@nxp.com>

DSP can be used with various frameworks (e.g audio firmware, rproc).
Currently 'dsp' configuration is intended for audio firmware but it
doesn't work well with board level DTs (e.g imx8mp-evk) because
board level DT enables audio related IPs (e.g SAI) while audio firmware
needs this IPs disabled (because firmware will configure them).

So, configure 'dsp' node to be used with rproc. This way users will be
able to use board DT to use the DSP as long as they don't clash with
Audio IP configurations.

More comples usage of 'dsp' node (e.g by audio firmware) will need to
create a separate dts file (or an overlay).

This change follows the approach taken for other i.MX8 boards
in commit 391a319c81f6d7 ("arm64: dts: imx8-ss-audio: configure dsp node
for rproc usage")

Signed-off-by: Daniel Baluta <daniel.baluta at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 00924e0836db..2f94c55e4999 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -280,7 +280,7 @@ reserved-memory {
 		ranges;
 
 		dsp_reserved: dsp at 92400000 {
-			reg = <0 0x92400000 0 0x2000000>;
+			reg = <0 0x92400000 0 0x1000000>;
 			no-map;
 			status = "disabled";
 		};
@@ -2414,12 +2414,12 @@ usb_dwc3_1: usb at 38200000 {
 		};
 
 		dsp: dsp at 3b6e8000 {
-			compatible = "fsl,imx8mp-dsp";
+			compatible = "fsl,imx8mp-hifi4";
 			reg = <0x3b6e8000 0x88000>;
-			mbox-names = "txdb0", "txdb1",
-				"rxdb0", "rxdb1";
-			mboxes = <&mu2 2 0>, <&mu2 2 1>,
-				<&mu2 3 0>, <&mu2 3 1>;
+			power-domains = <&pgc_audio>;
+			mbox-names = "tx", "rx", "rxdb";
+			mboxes = <&mu2 0 0>, <&mu2 1 0>, <&mu2 3 0>;
+			firmware-name = "imx/dsp/hifi4.bin";
 			memory-region = <&dsp_reserved>;
 			status = "disabled";
 		};
-- 
2.25.1



From daniel.baluta at nxp.com  Tue Dec 10 04:53:35 2024
From: daniel.baluta at nxp.com (Daniel Baluta)
Date: Tue, 10 Dec 2024 14:53:35 +0200
Subject: [PATCH v3 3/6] arm64: dts: imx8mp: Add DSP clocks
In-Reply-To: <20241210125338.104959-1-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
Message-ID: <20241210125338.104959-4-daniel.baluta@nxp.com>

DSP core needs ocram, core and debug clocks.

Signed-off-by: Daniel Baluta <daniel.baluta at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 2f94c55e4999..b42e6430123f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -2416,6 +2416,11 @@ usb_dwc3_1: usb at 38200000 {
 		dsp: dsp at 3b6e8000 {
 			compatible = "fsl,imx8mp-hifi4";
 			reg = <0x3b6e8000 0x88000>;
+			clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG>,
+				<&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG>,
+				<&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSP_ROOT>,
+				<&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT>;
+			clock-names = "ipg", "ocram", "core", "debug";
 			power-domains = <&pgc_audio>;
 			mbox-names = "tx", "rx", "rxdb";
 			mboxes = <&mu2 0 0>, <&mu2 1 0>, <&mu2 3 0>;
-- 
2.25.1



From daniel.baluta at nxp.com  Tue Dec 10 04:53:36 2024
From: daniel.baluta at nxp.com (Daniel Baluta)
Date: Tue, 10 Dec 2024 14:53:36 +0200
Subject: [PATCH v3 4/6] dt-bindings: clock: imx8mp: Add syscon compatible
In-Reply-To: <20241210125338.104959-1-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
Message-ID: <20241210125338.104959-5-daniel.baluta@nxp.com>

imx8mp audiomix contains a set of registers used to control
the DSP.

The dsp will use this to acquire o reference to audiomix registers
and handle the registers to control the dsp.

Signed-off-by: Daniel Baluta <daniel.baluta at nxp.com>
---
 .../devicetree/bindings/clock/imx8mp-audiomix.yaml          | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/imx8mp-audiomix.yaml b/Documentation/devicetree/bindings/clock/imx8mp-audiomix.yaml
index 6588a17a7d9a..0f870aaadba2 100644
--- a/Documentation/devicetree/bindings/clock/imx8mp-audiomix.yaml
+++ b/Documentation/devicetree/bindings/clock/imx8mp-audiomix.yaml
@@ -15,7 +15,9 @@ description: |
 
 properties:
   compatible:
-    const: fsl,imx8mp-audio-blk-ctrl
+    items:
+      - const: fsl,imx8mp-audio-blk-ctrl
+      - const: syscon
 
   reg:
     maxItems: 1
@@ -63,7 +65,7 @@ examples:
     #include <dt-bindings/clock/imx8mp-clock.h>
 
     clock-controller at 30e20000 {
-        compatible = "fsl,imx8mp-audio-blk-ctrl";
+        compatible = "fsl,imx8mp-audio-blk-ctrl", "syscon";
         reg = <0x30e20000 0x10000>;
         #clock-cells = <1>;
         clocks = <&clk IMX8MP_CLK_AUDIO_ROOT>,
-- 
2.25.1



From daniel.baluta at nxp.com  Tue Dec 10 04:53:37 2024
From: daniel.baluta at nxp.com (Daniel Baluta)
Date: Tue, 10 Dec 2024 14:53:37 +0200
Subject: [PATCH v3 5/6] arm64: dts: imx8mp: Add fsl,dsp-ctrl property for dsp
In-Reply-To: <20241210125338.104959-1-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
Message-ID: <20241210125338.104959-6-daniel.baluta@nxp.com>

Audio block control contains a set of registers some of them used for
DSP configuration.

Drivers (rproc, SOF) are using fsl,dsp-ctrl property to access those
registers in order to control the operations of the DSP (e.g for
start, reset, etc).

Signed-off-by: Daniel Baluta <daniel.baluta at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index b42e6430123f..c8f9347d602c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1609,7 +1609,7 @@ sdma2: dma-controller at 30e10000 {
 			};
 
 			audio_blk_ctrl: clock-controller at 30e20000 {
-				compatible = "fsl,imx8mp-audio-blk-ctrl";
+				compatible = "fsl,imx8mp-audio-blk-ctrl", "syscon";
 				reg = <0x30e20000 0x10000>;
 				#clock-cells = <1>;
 				#reset-cells = <1>;
@@ -2426,6 +2426,7 @@ dsp: dsp at 3b6e8000 {
 			mboxes = <&mu2 0 0>, <&mu2 1 0>, <&mu2 3 0>;
 			firmware-name = "imx/dsp/hifi4.bin";
 			memory-region = <&dsp_reserved>;
+			fsl,dsp-ctrl = <&audio_blk_ctrl>;
 			status = "disabled";
 		};
 	};
-- 
2.25.1



From daniel.baluta at nxp.com  Tue Dec 10 04:53:38 2024
From: daniel.baluta at nxp.com (Daniel Baluta)
Date: Tue, 10 Dec 2024 14:53:38 +0200
Subject: [PATCH v3 6/6] arm64: dts: Add dsp rproc related mem regions
In-Reply-To: <20241210125338.104959-1-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
Message-ID: <20241210125338.104959-7-daniel.baluta@nxp.com>

With imx8mp-evk board we are now configuring 'dsp' node for rproc usage,
so add rproc specific memory regions.

Also, enable dsp node because it is ready to be used.

Signed-off-by: Daniel Baluta <daniel.baluta at nxp.com>
Reviewed-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index d26930f1a9e9..c732ee79772d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -291,6 +291,16 @@ &aud2htx {
 	status = "okay";
 };
 
+&dsp_reserved {
+	status = "okay";
+};
+
+&dsp {
+	memory-region = <&dsp_vdev0buffer>, <&dsp_vdev0vring0>,
+			<&dsp_vdev0vring1>, <&dsp_reserved>;
+	status = "okay";
+};
+
 &eqos {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_eqos>;
-- 
2.25.1



From tabba at google.com  Tue Dec 10 04:59:44 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 12:59:44 +0000
Subject: [PATCH v2 01/18] KVM: arm64: Change the layout of enum pkvm_page_state
In-Reply-To: <20241203103735.2267589-2-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-2-qperret@google.com>
Message-ID: <CA+EHjTxfchr+ggO_z_zrrFTrFpS3oTJXt13t-854xWxYY=oSQQ@mail.gmail.com>

Hi Quentin,

On Tue, 3 Dec 2024 at 10:37, Quentin Perret <qperret at google.com> wrote:
>
> The 'concrete' (a.k.a non-meta) page states are currently encoded using
> software bits in PTEs. For performance reasons, the abstract
> pkvm_page_state enum uses the same bits to encode these states as that
> makes conversions from and to PTEs easy.
>
> In order to prepare the ground for moving the 'concrete' state storage
> to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this
> purpose.
>
> No functional changes intended.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 17 ++++++++++-------
>  1 file changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 0972faccc2af..ca3177481b78 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -24,25 +24,28 @@
>   */
>  enum pkvm_page_state {
>         PKVM_PAGE_OWNED                 = 0ULL,
> -       PKVM_PAGE_SHARED_OWNED          = KVM_PGTABLE_PROT_SW0,
> -       PKVM_PAGE_SHARED_BORROWED       = KVM_PGTABLE_PROT_SW1,
> -       __PKVM_PAGE_RESERVED            = KVM_PGTABLE_PROT_SW0 |
> -                                         KVM_PGTABLE_PROT_SW1,
> +       PKVM_PAGE_SHARED_OWNED          = BIT(0),
> +       PKVM_PAGE_SHARED_BORROWED       = BIT(1),
> +       __PKVM_PAGE_RESERVED            = BIT(0) | BIT(1),
>
>         /* Meta-states which aren't encoded directly in the PTE's SW bits */
> -       PKVM_NOPAGE,
> +       PKVM_NOPAGE                     = BIT(2),
>  };
> +#define PKVM_PAGE_META_STATES_MASK     (~(BIT(0) | BIT(1)))
>
>  #define PKVM_PAGE_STATE_PROT_MASK      (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
>  static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
>                                                  enum pkvm_page_state state)
>  {
> -       return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
> +       BUG_ON(state & PKVM_PAGE_META_STATES_MASK);

This is a slight change in functionality, having a BUG_ON instead of
just masking out illegal states. Is it necessary?

Cheers,
/fuad


> +       prot &= ~PKVM_PAGE_STATE_PROT_MASK;
> +       prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
> +       return prot;
>  }
>
>  static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
>  {
> -       return prot & PKVM_PAGE_STATE_PROT_MASK;
> +       return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
>  }
>
>  struct host_mmu {
> --
> 2.47.0.338.g60cca15819-goog
>


From broonie at kernel.org  Tue Dec 10 05:00:49 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 13:00:49 +0000
Subject: [PATCH] spi: aspeed: Fix an error handling path in
 aspeed_spi_[read|write]_user()
In-Reply-To: <4052aa2f9a9ea342fa6af83fa991b55ce5d5819e.1732051814.git.christophe.jaillet@wanadoo.fr>
References: <4052aa2f9a9ea342fa6af83fa991b55ce5d5819e.1732051814.git.christophe.jaillet@wanadoo.fr>
Message-ID: <173383564913.34030.1229101307217258864.b4-ty@kernel.org>

On Tue, 19 Nov 2024 22:30:29 +0100, Christophe JAILLET wrote:
> A aspeed_spi_start_user() is not balanced by a corresponding
> aspeed_spi_stop_user().
> Add the missing call.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: aspeed: Fix an error handling path in aspeed_spi_[read|write]_user()
      commit: c84dda3751e945a67d71cbe3af4474aad24a5794

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 Dec 10 05:00:51 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 13:00:51 +0000
Subject: [PATCH] spi: rockchip: Fix PM runtime count on no-op cs
In-Reply-To: <1f2b3af4-2b7a-4ac8-ab95-c80120ebf44c@arm.com>
References: <1f2b3af4-2b7a-4ac8-ab95-c80120ebf44c@arm.com>
Message-ID: <173383565160.34030.9711673452793299443.b4-ty@kernel.org>

On Fri, 06 Dec 2024 19:50:55 +0000, Christian Loehle wrote:
> The early bail out that caused an out-of-bounds write was removed with
> commit 5c018e378f91 ("spi: spi-rockchip: Fix out of bounds array
> access")
> Unfortunately that caused the PM runtime count to be unbalanced and
> underflowed on the first call. To fix that reintroduce a no-op check
> by reading the register directly.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: rockchip: Fix PM runtime count on no-op cs
      commit: 0bb394067a792e7119abc9e0b7158ef19381f456

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 Dec 10 05:00:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 13:00:53 +0000
Subject: [PATCH] spi: mxs: support effective_speed_hz
In-Reply-To: <20241209111316.4767-1-wahrenst@gmx.net>
References: <20241209111316.4767-1-wahrenst@gmx.net>
Message-ID: <173383565340.34030.7139873956151908430.b4-ty@kernel.org>

On Mon, 09 Dec 2024 12:13:16 +0100, Stefan Wahren wrote:
> Setting spi_transfer->effective_speed_hz in transfer_one_message so that
> SPI client driver can use it.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: mxs: support effective_speed_hz
      commit: a17162f0b2dc97aa2dedfde8a7226fb9b5210534

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 Dec 10 05:00:55 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 13:00:55 +0000
Subject: [PATCH] spi: zynq-qspi: Add check for clk_enable()
In-Reply-To: <20241207013258.3615645-1-zmw12306@gmail.com>
References: <20241207013258.3615645-1-zmw12306@gmail.com>
Message-ID: <173383565535.34030.14188162384074341857.b4-ty@kernel.org>

On Fri, 06 Dec 2024 20:32:58 -0500, Mingwei Zheng wrote:
> Add check for the return value of clk_enable() to catch the potential
> error.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: zynq-qspi: Add check for clk_enable()
      commit: 8332e667099712e05ec87ba2058af394b51ebdc9

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 Dec 10 05:04:23 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 21:04:23 +0800
Subject: [PATCH v4 00/10] Refactor the common parts to the HiSilicon
 Uncore PMU core and cleanups
In-Reply-To: <20241210120556.GA15398@willie-the-truck>
References: <20241203125049.39458-1-yangyicong@huawei.com>
 <20241210120556.GA15398@willie-the-truck>
Message-ID: <beb248e7-9872-914a-c705-e65317955c3f@huawei.com>

On 2024/12/10 20:05, Will Deacon wrote:
> On Tue, Dec 03, 2024 at 08:50:39PM +0800, Yicong Yang wrote:
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> This series mainly contains the refactor of the HiSilicon Uncore PMU by
>> extracting the common parts from each drivers into the core:
>> - the retrieving of the PMU topology ID
>> - the common sysfs attributes like cpumask and identifier
>>
>> In order to achieve this, we need to do below preparation:
>> - refactor the detection of associated CPUs for PMUs locates on a SICL
>> - maintain the topology information in a dedicated data structure
>> - provides a generic implementation of cpumask/identifier attributes
>>
>> Besides also include below changes/cleanups in this patchset
>> - add one new sysfs attributes for better describing the topology information
>>   of the associated CPUs of the PMU.
>> - define a symbol namespace for HiSilicon Uncore PMUs to avoid pollute the
>>   common ones
>> - two minor nonfunctional cleanups of DDRC PMU
>>
>> Change since v3:
>> - Split the associated_cpus refactor patches according to the functions, hope
>>   will be easier to review
>> - Drop the use of cpu_online_mask out of cpuhp
>> Link: https://lore.kernel.org/linux-arm-kernel/20241026072424.29887-1-yangyicong at huawei.com/
> 
> This doesn't build on top of -rc2 (see log below). I suspect this is because
> of the recent MODULE_IMPORT_NS() changes to use string literals [1].
> 
> Please can you send a v5?

sure, will rebase on -rc2 and address this.

Thanks.

> 
> Will
> 
> [1] cdd30ebb1b9f ("module: Convert symbol namespace to string literal")
> 
> --->8
> 
> In file included from ./include/linux/module.h:22,
>                  from ./include/linux/device/driver.h:21,
>                  from ./include/linux/device.h:32,
>                  from ./include/linux/acpi.h:14,
>                  from drivers/perf/hisilicon/hisi_uncore_hha_pmu.c:11:
> drivers/perf/hisilicon/hisi_uncore_hha_pmu.c:559:18: error: expected ?,? or ?;? before ?HISI_PMU?
>   559 | MODULE_IMPORT_NS(HISI_PMU);
>       |                  ^~~~~~~~
> ./include/linux/moduleparam.h:26:47: note: in definition of macro ?__MODULE_INFO?
>    26 |   = __MODULE_INFO_PREFIX __stringify(tag) "=" info
>       |                                               ^~~~
> ./include/linux/module.h:299:30: note: in expansion of macro ?MODULE_INFO?
>   299 | #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, ns)
>       |                              ^~~~~~~~~~~
> drivers/perf/hisilicon/hisi_uncore_hha_pmu.c:559:1: note: in expansion of macro ?MODULE_IMPORT_NS?
>   559 | MODULE_IMPORT_NS(HISI_PMU);
>       | ^~~~~~~~~~~~~~~~
> make[5]: *** [scripts/Makefile.build:194: drivers/perf/hisilicon/hisi_uncore_hha_pmu.o] Error 1
> make[5]: *** Waiting for unfinished jobs....
> In file included from ./include/linux/module.h:22,
>                  from ./include/linux/device/driver.h:21,
>                  from ./include/linux/device.h:32,
>                  from ./include/linux/acpi.h:14,
>                  from drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c:11:
> drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c:595:18: error: expected ?,? or ?;? before ?HISI_PMU?
>   595 | MODULE_IMPORT_NS(HISI_PMU);
>       |                  ^~~~~~~~
> ./include/linux/moduleparam.h:26:47: note: in definition of macro ?__MODULE_INFO?
>    26 |   = __MODULE_INFO_PREFIX __stringify(tag) "=" info
>       |                                               ^~~~
> ./include/linux/module.h:299:30: note: in expansion of macro ?MODULE_INFO?
>   299 | #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, ns)
>       |                              ^~~~~~~~~~~
> drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c:595:1: note: in expansion of macro ?MODULE_IMPORT_NS?
>   595 | MODULE_IMPORT_NS(HISI_PMU);
>       | ^~~~~~~~~~~~~~~~
> make[5]: *** [scripts/Makefile.build:194: drivers/perf/hisilicon/hisi_uncore_l3c_pmu.o] Error 1
> /tmp/ccKFrDMm.s: Assembler messages:
> /tmp/ccKFrDMm.s:7: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:8: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:9: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:10: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:11: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:12: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:13: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:14: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:15: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:16: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:17: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:18: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:19: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:20: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:21: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:22: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:23: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:24: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:25: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:26: Error: junk at end of line, first unrecognized character is `H'
> /tmp/ccKFrDMm.s:27: Error: junk at end of line, first unrecognized character is `H'
> make[5]: *** [scripts/Makefile.build:194: drivers/perf/hisilicon/hisi_uncore_pmu.o] Error 1
> In file included from ./include/linux/module.h:22,
>                  from ./include/linux/device/driver.h:21,
>                  from ./include/linux/device.h:32,
>                  from ./include/linux/acpi.h:14,
>                  from drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c:11:
> drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c:556:18: error: expected ?,? or ?;? before ?HISI_PMU?
>   556 | MODULE_IMPORT_NS(HISI_PMU);
>       |                  ^~~~~~~~
> ./include/linux/moduleparam.h:26:47: note: in definition of macro ?__MODULE_INFO?
>    26 |   = __MODULE_INFO_PREFIX __stringify(tag) "=" info
>       |                                               ^~~~
> ./include/linux/module.h:299:30: note: in expansion of macro ?MODULE_INFO?
>   299 | #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, ns)
>       |                              ^~~~~~~~~~~
> drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c:556:1: note: in expansion of macro ?MODULE_IMPORT_NS?
>   556 | MODULE_IMPORT_NS(HISI_PMU);
>       | ^~~~~~~~~~~~~~~~
> make[5]: *** [scripts/Makefile.build:194: drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.o] Error 1
> make[4]: *** [scripts/Makefile.build:440: drivers/perf/hisilicon] Error 2
> make[4]: *** Waiting for unfinished jobs....
> make[3]: *** [scripts/Makefile.build:440: drivers/perf] Error 2
> make[3]: *** Waiting for unfinished jobs....
> make[2]: *** [scripts/Makefile.build:440: drivers] Error 2
> .
> 


From pgwipeout at gmail.com  Tue Dec 10 05:04:42 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 08:04:42 -0500
Subject: [PATCH 5/6] arm64: dts: rockchip: correct rk3328-roc regulator map
In-Reply-To: <D67ZJ6MOM5TH.2WBYCCU20DDJO@cknow.org>
References: <20241210013010.81257-1-pgwipeout@gmail.com> <20241210013010.81257-6-pgwipeout@gmail.com>
 <D67ZJ6MOM5TH.2WBYCCU20DDJO@cknow.org>
Message-ID: <CAMdYzYorTNiAybGhPu0u_YPj2J7qxCO72KBU1ozTde+2zK9Hxg@mail.gmail.com>

On Tue, Dec 10, 2024 at 6:31?AM Diederik de Haas <didi.debian at cknow.org> wrote:
>
> Hi Peter,
>
> Thanks for this series, I already saw some familiar error msgs
> mentioned, so will try this series out soon (tm).
>
> On Tue Dec 10, 2024 at 2:30 AM CET, Peter Geis wrote:
> > The rk3328-roc-cc input power is sourced from a micro-usb port, while
> > the rk3328-roc-pc input power is sourced from a usb-c port. Both inputs
> > are 5vdc only. Remove the 12v input from the device tree.
> >
> > While we are at it, add missing voltages and supply to vcc_phy, missing
> > voltages to vcc_host1_5v, and standardize the order of regulator
> > properties among the fixed regulators.
>
> Big fan of standardization :-) ...
>
> >
> > Fixes: 2171f4fdac06 ("arm64: dts: rockchip: add roc-rk3328-cc board")
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> >
> >  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 23 +++++++++++++-------
> >  1 file changed, 15 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > index f782c8220dd3..6984387ff8b3 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > @@ -24,22 +24,23 @@ gmac_clkin: external-gmac-clock {
> >               #clock-cells = <0>;
> >       };
> >
> > -     dc_12v: regulator-dc-12v {
> > +     /* fed from passive usb input connector */
> > +     dc_5v: regulator-dc-5v {
> >               compatible = "regulator-fixed";
> > -             regulator-name = "dc_12v";
> > +             regulator-name = "dc_5v";
> >               regulator-always-on;
> >               regulator-boot-on;
> > -             regulator-min-microvolt = <12000000>;
> > -             regulator-max-microvolt = <12000000>;
> > +             regulator-min-microvolt = <5000000>;
> > +             regulator-max-microvolt = <5000000>;
> >       };
> >
> >       vcc_sd: regulator-sdmmc {
> >               compatible = "regulator-fixed";
> > +             regulator-name = "vcc_sd";
> >               gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
> >               pinctrl-names = "default";
> >               pinctrl-0 = <&sdmmc0m1_pin>;
> >               regulator-boot-on;
> > -             regulator-name = "vcc_sd";
> >               regulator-min-microvolt = <3300000>;
> >               regulator-max-microvolt = <3300000>;
> >               vin-supply = <&vcc_io>;
>
> ... but why not put regulator-name as the first of the regulator
> properties as is done in the rk3328-rock64.dts ...
>
> > @@ -50,22 +51,25 @@ vcc_sdio: regulator-sdmmcio {
> >               states = <1800000 0x1>, <3300000 0x0>;
> >               regulator-name = "vcc_sdio";
> >               regulator-type = "voltage";
> > +             regulator-always-on;
> >               regulator-min-microvolt = <1800000>;
> >               regulator-max-microvolt = <3300000>;
> > -             regulator-always-on;
> >               vin-supply = <&vcc_sys>;
> >       };
> >
> >       vcc_host1_5v: vcc_otg_5v: regulator-vcc-host1-5v {
> >               compatible = "regulator-fixed";
> > +             regulator-name = "vcc_host1_5v";
> >               enable-active-high;
> >               pinctrl-names = "default";
> >               pinctrl-0 = <&usb20_host_drv>;
> > -             regulator-name = "vcc_host1_5v";
> >               regulator-always-on;
> > +             regulator-min-microvolt = <5000000>;
> > +             regulator-max-microvolt = <5000000>;
> >               vin-supply = <&vcc_sys>;
> >       };
>
> ... and was the case here?

That's fair, thank you. I like the alphabetical approach, I'll go that
way when I split this out.

>
> Cheers,
>   Diederik
>
> >
> > +     /* sourced from usb input through 3A fuse */
> >       vcc_sys: regulator-vcc-sys {
> >               compatible = "regulator-fixed";
> >               regulator-name = "vcc_sys";
> > @@ -73,7 +77,7 @@ vcc_sys: regulator-vcc-sys {
> >               regulator-boot-on;
> >               regulator-min-microvolt = <5000000>;
> >               regulator-max-microvolt = <5000000>;
> > -             vin-supply = <&dc_12v>;
> > +             vin-supply = <&dc_5v>;
> >       };
> >
> >       vcc_phy: regulator-vcc-phy {
> > @@ -81,6 +85,9 @@ vcc_phy: regulator-vcc-phy {
> >               regulator-name = "vcc_phy";
> >               regulator-always-on;
> >               regulator-boot-on;
> > +             regulator-min-microvolt = <3300000>;
> > +             regulator-max-microvolt = <3300000>;
> > +             vin-supply = <&vcc_io>;
> >       };
> >
> >       leds {
>


From pgwipeout at gmail.com  Tue Dec 10 05:13:59 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 08:13:59 -0500
Subject: [PATCH 4/6] arm64: dts: rockchip: add hevc power domain clock to rk3328
In-Reply-To: <e32fa593abfa6d08202b4f929e0b4bdb@manjaro.org>
References: <20241210013010.81257-1-pgwipeout@gmail.com> <20241210013010.81257-5-pgwipeout@gmail.com>
 <e32fa593abfa6d08202b4f929e0b4bdb@manjaro.org>
Message-ID: <CAMdYzYp+MQVYr1tOMEOn62vXZGVEYrtd1p9vn6YQzXdrJgSdyA@mail.gmail.com>

On Tue, Dec 10, 2024 at 5:04?AM Dragan Simic <dsimic at manjaro.org> wrote:
>
> Hello Peter,
>
> On 2024-12-10 02:30, Peter Geis wrote:
> > There is a race condition at startup between disabling power domains
> > not
> > used and disabling clocks not used on the rk3328. When the clocks are
> > disabled first, the hevc power domain fails to shut off leading to a
> > splat of failures. Add the hevc core clock to the rk3328 power domain
> > node to prevent this condition.
> >
> > rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-....
> > }
> > 1087 jiffies s: 89 root: 0x8/.
> > rcu: blocking rcu_node structures (internal RCU debug):
> > Sending NMI from CPU 0 to CPUs 3:
> > NMI backtrace for cpu 3
> > CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53
> > Hardware name: Firefly ROC-RK3328-CC (DT)
> > Workqueue: pm genpd_power_off_work_fn
> > pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > pc : regmap_unlock_spinlock+0x18/0x30
> > lr : regmap_read+0x60/0x88
> > sp : ffff800081123c00
> > x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000
> > x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040
> > x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74
> > x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000
> > x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d
> > x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431
> > x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0
> > x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b
> > x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40
> > x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000
> > Call trace:
> > regmap_unlock_spinlock+0x18/0x30
> > rockchip_pmu_set_idle_request+0xac/0x2c0
> > rockchip_pd_power+0x144/0x5f8
> > rockchip_pd_power_off+0x1c/0x30
> > _genpd_power_off+0x9c/0x180
> > genpd_power_off.part.0.isra.0+0x130/0x2a8
> > genpd_power_off_work_fn+0x6c/0x98
> > process_one_work+0x170/0x3f0
> > worker_thread+0x290/0x4a8
> > kthread+0xec/0xf8
> > ret_from_fork+0x10/0x20
> > rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack
> > on
> > domain 'hevc', val=0x88220
> >
> > Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for
> > RK3328 SoCs")
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>
> While I was unable to formally verify this clock assignment,
> i.e. by using the RK3328 TRM or the downstream kernel source
> from Rockchip, it makes perfect sense to me.  Thanks for the
> patch, and please feel free to include:
>
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>

It is unfortunate the TRM doesn't include the clock maps, because they
are extremely helpful when one can acquire them. It also doesn't help
that the TRM register definition only referred to this as "pll". I was
sent specifically the usb3 phy clock map for my work on the driver,
which had the location of each switch and divider along with the
register and bit that controlled it. That combined with the TRM
register map allowed me to find this error.

Thanks!
Peter

>
> > ---
> >
> >  arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > index 0597de415fe0..7d992c3c01ce 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > @@ -333,6 +333,7 @@ power: power-controller {
> >
> >                       power-domain at RK3328_PD_HEVC {
> >                               reg = <RK3328_PD_HEVC>;
> > +                             clocks = <&cru SCLK_VENC_CORE>;
> >                               #power-domain-cells = <0>;
> >                       };
> >                       power-domain at RK3328_PD_VIDEO {


From pgwipeout at gmail.com  Tue Dec 10 05:23:22 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 08:23:22 -0500
Subject: [PATCH 4/6] arm64: dts: rockchip: add hevc power domain clock to rk3328
In-Reply-To: <CAMdYzYp+MQVYr1tOMEOn62vXZGVEYrtd1p9vn6YQzXdrJgSdyA@mail.gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com> <20241210013010.81257-5-pgwipeout@gmail.com>
 <e32fa593abfa6d08202b4f929e0b4bdb@manjaro.org> <CAMdYzYp+MQVYr1tOMEOn62vXZGVEYrtd1p9vn6YQzXdrJgSdyA@mail.gmail.com>
Message-ID: <CAMdYzYquvGBzfWqvUOku7m1sM9qxmBHAL95cANDViUCT1oEEhQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 8:13?AM Peter Geis <pgwipeout at gmail.com> wrote:
>
> On Tue, Dec 10, 2024 at 5:04?AM Dragan Simic <dsimic at manjaro.org> wrote:
> >
> > Hello Peter,
> >
> > On 2024-12-10 02:30, Peter Geis wrote:
> > > There is a race condition at startup between disabling power domains
> > > not
> > > used and disabling clocks not used on the rk3328. When the clocks are
> > > disabled first, the hevc power domain fails to shut off leading to a
> > > splat of failures. Add the hevc core clock to the rk3328 power domain
> > > node to prevent this condition.
> > >
> > > rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-....
> > > }
> > > 1087 jiffies s: 89 root: 0x8/.
> > > rcu: blocking rcu_node structures (internal RCU debug):
> > > Sending NMI from CPU 0 to CPUs 3:
> > > NMI backtrace for cpu 3
> > > CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53
> > > Hardware name: Firefly ROC-RK3328-CC (DT)
> > > Workqueue: pm genpd_power_off_work_fn
> > > pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > > pc : regmap_unlock_spinlock+0x18/0x30
> > > lr : regmap_read+0x60/0x88
> > > sp : ffff800081123c00
> > > x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000
> > > x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040
> > > x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74
> > > x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000
> > > x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d
> > > x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431
> > > x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0
> > > x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b
> > > x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40
> > > x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000
> > > Call trace:
> > > regmap_unlock_spinlock+0x18/0x30
> > > rockchip_pmu_set_idle_request+0xac/0x2c0
> > > rockchip_pd_power+0x144/0x5f8
> > > rockchip_pd_power_off+0x1c/0x30
> > > _genpd_power_off+0x9c/0x180
> > > genpd_power_off.part.0.isra.0+0x130/0x2a8
> > > genpd_power_off_work_fn+0x6c/0x98
> > > process_one_work+0x170/0x3f0
> > > worker_thread+0x290/0x4a8
> > > kthread+0xec/0xf8
> > > ret_from_fork+0x10/0x20
> > > rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack
> > > on
> > > domain 'hevc', val=0x88220
> > >
> > > Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for
> > > RK3328 SoCs")
> > > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> >
> > While I was unable to formally verify this clock assignment,
> > i.e. by using the RK3328 TRM or the downstream kernel source
> > from Rockchip, it makes perfect sense to me.  Thanks for the
> > patch, and please feel free to include:
> >
> > Reviewed-by: Dragan Simic <dsimic at manjaro.org>
>
> It is unfortunate the TRM doesn't include the clock maps, because they
> are extremely helpful when one can acquire them. It also doesn't help
> that the TRM register definition only referred to this as "pll". I was
> sent specifically the usb3 phy clock map for my work on the driver,
> which had the location of each switch and divider along with the
> register and bit that controlled it. That combined with the TRM
> register map allowed me to find this error.
>
> Thanks!
> Peter

Apologies, that's the wrong response for this one.
This patch was the result of educated guess combined with testing. I
grabbed all of the clocks that looked like they could affect things,
then tested them one at a time until I isolated them to this clock. It
lives alone with cpll as the parent and has no children according to
the clock summary. (Though the writeup i mistakenly included above
proves the clock map isn't always accurate).

Thanks,
Peter
>
> >
> > > ---
> > >
> > >  arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > > b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > > index 0597de415fe0..7d992c3c01ce 100644
> > > --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > > +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > > @@ -333,6 +333,7 @@ power: power-controller {
> > >
> > >                       power-domain at RK3328_PD_HEVC {
> > >                               reg = <RK3328_PD_HEVC>;
> > > +                             clocks = <&cru SCLK_VENC_CORE>;
> > >                               #power-domain-cells = <0>;
> > >                       };
> > >                       power-domain at RK3328_PD_VIDEO {


From kirill.shutemov at linux.intel.com  Tue Dec 10 05:26:40 2024
From: kirill.shutemov at linux.intel.com (Kirill A. Shutemov)
Date: Tue, 10 Dec 2024 15:26:40 +0200
Subject: [PATCHv2 2/2] x86/mm: Make memremap(MEMREMAP_WB) map memory as
 encrypted by default
In-Reply-To: <20241121114952.GCZz8eYEVa3yubYQzO@fat_crate.local>
References: <20241021105723.2707507-1-kirill.shutemov@linux.intel.com>
 <20241021105723.2707507-3-kirill.shutemov@linux.intel.com>
 <20241118164616.GAZztvWGs9cOV8t20_@fat_crate.local>
 <s4frmqwtuvclinuu7ttyzfpe7bj7hju5xgt6sxzy3gyt3prr62@rrgvhkv4lgwv>
 <20241121114952.GCZz8eYEVa3yubYQzO@fat_crate.local>
Message-ID: <bz3vlh3lri7yfckdkddopwhsgvkmizhw5q6ecomgeba7q22ufp@ntu2kugiho4o>

On Thu, Nov 21, 2024 at 12:49:52PM +0100, Borislav Petkov wrote:
> On Tue, Nov 19, 2024 at 10:21:05AM +0200, Kirill A. Shutemov wrote:
> > Sure, we can workaround every place that touches such ranges.
> 
> Every place? Which every place? I thought this is only an EISA issue?

I looked at other places where we call memremap(MEMREMAP_WB) such as
acpi_wakeup_cpu(). We actually get encrypted/private mapping for this
callsite despite __ioremap_caller() being called encrypted == false.
This happens because of IORES_MAP_ENCRYPTED check in __ioremap_caller().

So we depend on the BIOS here. The EISA problem happens because the
target memory is in !IORES_MAP_ENCRYPTED memory.

It's hard to say if any other memremap(MEMREMAP_WB) would trigger the
issue. And what will happen after next BIOS update.

> Then clearly your changelogs need to expand considerably more what we're
> *really* addressing here.
> 
> > Or we can address problem at the root and make creating decrypted/shared
> > mappings explicit.
> 
> What is the problem? That KVM implicitly converts memory to shared? Why does
> KVM do that an can it be fixed not to?
> 
> Doesn't sound like the guest's problem.

Well, the problem is on the both sides.

VMM behaviour on such accesses is not specified in any spec. AFAIK all
current VMM implementations do this implicit conversion.

I think it has to be fixed. VMMs (not only KVM) should not silently
convert memory to shared. But VMMs cannot make memory access to go away.
The only option they have is to inject #VE instead indicating bogus
access. At this point it becomes a guest problem.

It will get fixed in VMMs naturally when TDX Connect gets enabled.
With a secure device assigned to a TD, VMM would loose the ability to
convert memory on its own. The guest would have to unlock the memory
first. This will make implicit conversion impossible.

But it also means guest should never initiate shared access without
explicit conversion. Otherwise #VE will crash it.

> Or maybe this needs a lot more explanation what we're fixing here.
> 
> > Such mappings have both functional (as we see here) and security
> > implications (VMM can manipulate the guest memory range). We should not
> > create decrypted mappings by default on legacy interfaces.
> 
> So we're getting closer.
> 
> The changes themselves are fine but your text is missing a lot about what
> we're fixing here. When I asked, I barely scratched the surface. So can we
> elaborate here pls?

What about this:

x86/mm: Make memremap(MEMREMAP_WB) map memory as encrypted by default

Currently memremap(MEMREMAP_WB) can produce decrypted/shared mapping:

memremap(MEMREMAP_WB)
  arch_memremap_wb()
    ioremap_cache()
      __ioremap_caller(.encrytped = false)

In such cases, the IORES_MAP_ENCRYPTED flag on the memory will determine
if the resulting mapping is encrypted or decrypted.

Creating a decrypted mapping without explicit request from the caller is
risky:

  - It can inadvertently expose the guest's data and compromise the
    guest.

  - Accessing private memory via shared/decrypted mapping on TDX will
    either trigger implicit conversion to shared or #VE (depending on
    VMM implementation).

    Implicit conversion is destructive: subsequent access to the same
    memory via private mapping will trigger a hard-to-debug #VE crash.

The kernel already provides a way to request decrypted mapping
explicitly via the MEMREMAP_DEC flag.

Modify memremap(MEMREMAP_WB) to produce encrypted/private mapping by
default unless MEMREMAP_DEC is specified.

This change fixes the crash on kexec in TDX guests if CONFIG_EISA is
enabled.
 
-- 
  Kiryl Shutsemau / Kirill A. Shutemov


From pgwipeout at gmail.com  Tue Dec 10 05:27:13 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 08:27:13 -0500
Subject: [PATCH 2/6] clk: rockchip: fix wrong clk_ref_usb3otg parent for rk3328
In-Reply-To: <0d11705121f29ccfb7cfa342505a6e35@manjaro.org>
References: <20241210013010.81257-1-pgwipeout@gmail.com> <20241210013010.81257-3-pgwipeout@gmail.com>
 <0d11705121f29ccfb7cfa342505a6e35@manjaro.org>
Message-ID: <CAMdYzYqJLK6oJHCUVztth6mtJsYrRQSPzNYpR-ZmR7rNprZXfg@mail.gmail.com>

On Tue, Dec 10, 2024 at 4:44?AM Dragan Simic <dsimic at manjaro.org> wrote:
>
> Hello Peter,
>
> On 2024-12-10 02:30, Peter Geis wrote:
> > Correct the clk_ref_usb3otg parent to fix clock control for the usb3
> > controller on rk3328. Verified against the rk3328 trm and usb3 clock
> > tree
> > documentation.
> >
> > Fixes: fe3511ad8a1c ("clk: rockchip: add clock controller for rk3328")
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> >
> >  drivers/clk/rockchip/clk-rk3328.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/clk/rockchip/clk-rk3328.c
> > b/drivers/clk/rockchip/clk-rk3328.c
> > index 3bb87b27b662..cf60fcf2fa5c 100644
> > --- a/drivers/clk/rockchip/clk-rk3328.c
> > +++ b/drivers/clk/rockchip/clk-rk3328.c
> > @@ -201,7 +201,7 @@ PNAME(mux_aclk_peri_pre_p)        = { "cpll_peri",
> >                                   "gpll_peri",
> >                                   "hdmiphy_peri" };
> >  PNAME(mux_ref_usb3otg_src_p) = { "xin24m",
> > -                                 "clk_usb3otg_ref" };
> > +                                 "clk_ref_usb3otg_src" };
> >  PNAME(mux_xin24m_32k_p)              = { "xin24m",
> >                                   "clk_rtc32k" };
> >  PNAME(mux_mac2io_src_p)              = { "clk_mac2io_src",
>
> Sorry, but I was unable to verify this in the part 1 of the
> RK3328 TRM, in both versions 1.1 and 1.2, which is all I have
> when it comes to the RK3328 TRM.  Is that maybe described in
> the part 2, which I've been unable to locate for years?
>
> Moreover, the downstream kernel source from Rockchip does it
> the way [1] it's currently done in the mainline kernel, which
> makes me confused a bit?  Could you, please, provide more
> details about the two references you mentioned in the patch
> description, or maybe even you could provide the links to
> those two references?
>
> [1]
> https://raw.githubusercontent.com/rockchip-linux/kernel/refs/heads/develop-4.4/drivers/clk/rockchip/clk-rk3328.c

It is unfortunate the TRM doesn't include the clock maps, because they
are extremely helpful when one can acquire them. It also doesn't help
that the TRM register definition only referred to this as "pll". I was
sent specifically the usb3 phy clock map for my work on the driver,
which had the location of each switch and divider along with the
register and bit that controlled it. That combined with the TRM
register map allowed me to find this error.

Thanks!
Peter


From mark.rutland at arm.com  Tue Dec 10 05:33:16 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Dec 2024 13:33:16 +0000
Subject: [PATCH] arm64: stacktrace: skip reporting LR at exception
 boundaries
In-Reply-To: <20241209110351.1876804-1-mark.rutland@arm.com>
References: <20241209110351.1876804-1-mark.rutland@arm.com>
Message-ID: <Z1hDHLbvNZDTDlTk@J2N7QTR9R3>

Hi Catalin, Will,

Please disregard this patch for now -- there are some related issues
with unwinding distinct tasks, and I will send a new parch/series
shortly which will supersede this.

Mark.

On Mon, Dec 09, 2024 at 11:03:51AM +0000, Mark Rutland wrote:
> Recently the arm64 stacktrace code was modified to report the LR at
> exception boundaries, which interacts poorly with fgraph tracing. It is
> possible for the LR to contain the start address of return_to_handler()
> even when the LR is not live, and in such cases attempts to recover the
> return address via ftrace_graph_ret_addr() may fail, triggering a
> WARN_ON_ONCE() in kunwind_recover_return_address() and aborting the
> unwind. This has resulted in test failures and unexpected warnings, as
> reported by Aishwarya and Kent.
> 
> Handling unreliable LR values in these cases is likely to require some
> larger rework, so for the moment avoid this problem by restoring the old
> behaviour of skipping the LR at exception boundaries, as we did prior to
> commit:
> 
>   c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")
> 
> This commit is effectively a partial revert, keeping the structures and
> logic to explicitly identify exception boundaries while still skipping
> reporting of the LR. The logic to explicitly identify exception
> boundaries is still useful for general robustness and as a building
> block for future support for reliably stacktracing.
> 
> Fixes: c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Reported-by: Aishwarya TCV <aishwarya.tcv at arm.com>
> Reported-by: Kent Overstreet <kent.overstreet at linux.dev>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/kernel/stacktrace.c | 24 ++----------------------
>  1 file changed, 2 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index caef85462acb6..4a08ad8158380 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -26,7 +26,6 @@ enum kunwind_source {
>  	KUNWIND_SOURCE_CALLER,
>  	KUNWIND_SOURCE_TASK,
>  	KUNWIND_SOURCE_REGS_PC,
> -	KUNWIND_SOURCE_REGS_LR,
>  };
>  
>  union unwind_flags {
> @@ -178,23 +177,8 @@ int kunwind_next_regs_pc(struct kunwind_state *state)
>  	state->regs = regs;
>  	state->common.pc = regs->pc;
>  	state->common.fp = regs->regs[29];
> -	state->source = KUNWIND_SOURCE_REGS_PC;
> -	return 0;
> -}
> -
> -static __always_inline int
> -kunwind_next_regs_lr(struct kunwind_state *state)
> -{
> -	/*
> -	 * The stack for the regs was consumed by kunwind_next_regs_pc(), so we
> -	 * cannot consume that again here, but we know the regs are safe to
> -	 * access.
> -	 */
> -	state->common.pc = state->regs->regs[30];
> -	state->common.fp = state->regs->regs[29];
>  	state->regs = NULL;
> -	state->source = KUNWIND_SOURCE_REGS_LR;
> -
> +	state->source = KUNWIND_SOURCE_REGS_PC;
>  	return 0;
>  }
>  
> @@ -274,11 +258,8 @@ kunwind_next(struct kunwind_state *state)
>  	case KUNWIND_SOURCE_FRAME:
>  	case KUNWIND_SOURCE_CALLER:
>  	case KUNWIND_SOURCE_TASK:
> -	case KUNWIND_SOURCE_REGS_LR:
> -		err = kunwind_next_frame_record(state);
> -		break;
>  	case KUNWIND_SOURCE_REGS_PC:
> -		err = kunwind_next_regs_lr(state);
> +		err = kunwind_next_frame_record(state);
>  		break;
>  	default:
>  		err = -EINVAL;
> @@ -436,7 +417,6 @@ static const char *state_source_string(const struct kunwind_state *state)
>  	case KUNWIND_SOURCE_CALLER:	return "C";
>  	case KUNWIND_SOURCE_TASK:	return "T";
>  	case KUNWIND_SOURCE_REGS_PC:	return "P";
> -	case KUNWIND_SOURCE_REGS_LR:	return "L";
>  	default:			return "U";
>  	}
>  }
> -- 
> 2.30.2
> 


From will at kernel.org  Tue Dec 10 05:37:32 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 13:37:32 +0000
Subject: [PATCH v2] perf: imx9_perf: Introduce AXI filter version to
 refactor the driver and better extension
In-Reply-To: <20241210020212.yz3xowvdk27zmgsl@hippo>
References: <20241125104338.2433339-1-xu.yang_2@nxp.com>
 <20241209154419.GB12428@willie-the-truck>
 <20241210020212.yz3xowvdk27zmgsl@hippo>
Message-ID: <20241210133732.GA15607@willie-the-truck>

On Tue, Dec 10, 2024 at 10:02:12AM +0800, Xu Yang wrote:
> On Mon, Dec 09, 2024 at 03:44:20PM +0000, Will Deacon wrote:
> > On Mon, Nov 25, 2024 at 06:43:38PM +0800, Xu Yang wrote:
> > > The imx93 is the first supported DDR PMU that supports read transaction,
> > > write transaction and read beats events which corresponding respecitively
> > > to counter 2, 3 and 4.
> > > 
> > > However, transaction-based AXI match has low accuracy when get total bits
> > > compared to beats-based. And imx93 doesn't assign AXI_ID to each master.
> > > So axi filter is not used widely on imx93. This could be regards as AXI
> > > filter version 1.
> > > 
> > > To improve the AXI filter capability, imx95 supports 1 read beats and 3
> > > write beats event which corresponding respecitively to counter 2-5. imx95
> > > also detailed AXI_ID allocation so that most of the master could be count
> > > individually. This could be regards as AXI filter version 2.
> > > 
> > > This will introduce AXI filter version to refactor the driver and support
> > > better extension, such as coming imx943.
> > > 
> > > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > > 
> > > ---
> > > Changes in v2:
> > >  - modify subject
> > >  - add comments for AXI_FILTER version
> > >  - type -> filter_ver
> > > ---
> > >  drivers/perf/fsl_imx9_ddr_perf.c | 33 ++++++++++++++++++++++++--------
> > >  1 file changed, 25 insertions(+), 8 deletions(-)

[...]

> > > @@ -624,11 +641,11 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
> > >  	hwc->idx = counter;
> > >  	hwc->state |= PERF_HES_STOPPED;
> > >  
> > > -	if (is_imx93(pmu))
> > > +	if (axi_filter_v1(pmu))
> > >  		/* read trans, write trans, read beat */
> > >  		imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
> > 
> > Hmm, doesn't this change mean we now enable this for imx91 as well? My
> > reading of the commit message is that imx93 was the first chip which
> > supports this.
> 
> Yes, it's enabled for imx91 too. In fact, imx91 is compatible with imx93.
> They use same configuration for axi filter.

Ok, but my worry is that the above code looks like userspace now _must_
provide valid values for the config1 (axi_id) and config2 (axi_mask)
fields on imx91, whereas before I think they were ignored by the driver.

In fact, without this change, how were the PMCFGn registers configured
on imx91? It looks to me like they were left uninitialised...

Will


From andrew at lunn.ch  Tue Dec 10 05:38:21 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 10 Dec 2024 14:38:21 +0100
Subject: [net-next PATCH v11 6/9] net: mdio: Add Airoha AN8855 Switch
 MDIO Passtrough
In-Reply-To: <67582eca.050a0220.3b9b85.2de4@mx.google.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-7-ansuelsmth@gmail.com>
 <5aec4a94-3cea-41a4-8500-71472fae51d4@lunn.ch>
 <67582eca.050a0220.3b9b85.2de4@mx.google.com>
Message-ID: <0523b9a2-0d77-4bb8-ac1e-f28b96eb36b2@lunn.ch>

On Tue, Dec 10, 2024 at 01:06:29PM +0100, Christian Marangi wrote:
> On Tue, Dec 10, 2024 at 02:53:34AM +0100, Andrew Lunn wrote:
> > > +static int an855_phy_restore_page(struct an8855_mfd_priv *priv,
> > > +				  int phy) __must_hold(&priv->bus->mdio_lock)
> > > +{
> > > +	/* Check PHY page only for addr shared with switch */
> > > +	if (phy != priv->switch_addr)
> > > +		return 0;
> > > +
> > > +	/* Don't restore page if it's not set to switch page */
> > > +	if (priv->current_page != FIELD_GET(AN8855_PHY_PAGE,
> > > +					    AN8855_PHY_PAGE_EXTENDED_4))
> > > +		return 0;
> > > +
> > > +	/* Restore page to 0, PHY might change page right after but that
> > > +	 * will be ignored as it won't be a switch page.
> > > +	 */
> > > +	return an8855_mii_set_page(priv, phy, AN8855_PHY_PAGE_STANDARD);
> > > +}
> > 
> > I don't really understand what is going on here. Maybe the commit
> > message needs expanding, or the function names changing.
> > 
> > Generally, i would expect a save/restore action. Save the current
> > page, swap to the PHY page, do the PHY access, and then restore to the
> > saved page.
> >
> 
> Idea is to save on extra read/write on subsequent write on the same
> page.
> 
> Idea here is that PHY will receive most of the read (for status
> poll) hence in 90% of the time page will be 0.
> 
> And switch will receive read/write only on setup or fdb/vlan access on
> configuration so it will receive subsequent write on the same page.
> (page 4)
> 
> PHY might also need to write on page 1 on setup but never on page 4 as
> that is reserved for switch.
> 
> Making the read/swap/write/restore adds 2 additional operation that can
> really be skipped 90% of the time.
> 
> Also curret_page cache is indirectly protected by the mdio lock.
> 
> So in short this function makes sure PHY for port 0 is configured on the
> right page based on the prev page set.
> 
> An alternative way might be assume PHY is always on page 0 and any
> switch operation save and restore the page.
> 
> Hope it's clear now why this is needed. Is this ok or you prefer the
> alternative way? 

Please think about naming. I'm not sure _restore_ is the correct name
for the function. Maybe select. And i suggest adding some comments to
explain what is going on, since it is not obvious from the code in
this file, you probably need to cross reference it with code in the
DSA driver as well.

	Andrew


From andrew at lunn.ch  Tue Dec 10 05:39:50 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 10 Dec 2024 14:39:50 +0100
Subject: [net-next PATCH v11 9/9] net: phy: Add Airoha AN8855 Internal
 Switch Gigabit PHY
In-Reply-To: <67582fca.050a0220.2d187a.9e01@mx.google.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-10-ansuelsmth@gmail.com>
 <b3b79c80-ac7c-456b-a3b5-eee61f671694@lunn.ch>
 <67582fca.050a0220.2d187a.9e01@mx.google.com>
Message-ID: <ca20895b-9223-4af6-b49c-e405b69e5f08@lunn.ch>

On Tue, Dec 10, 2024 at 01:10:45PM +0100, Christian Marangi wrote:
> On Tue, Dec 10, 2024 at 02:36:29AM +0100, Andrew Lunn wrote:
> > > +config AIR_AN8855_PHY
> > > +	tristate "Airoha AN8855 Internal Gigabit PHY"
> > > +	help
> > > +	  Currently supports the internal Airoha AN8855 Switch PHY.
> > > +
> > >  config AIR_EN8811H_PHY
> > >  	tristate "Airoha EN8811H 2.5 Gigabit PHY"
> > >  	help
> > 
> > Do you have any idea why the new one is AN, and previous one is EN?  I
> > just like consistent naming, or an explanation why it is not
> > consistent.
> >
> 
> EN EcoNet that was then absorbed by Airoha (AN). Hence it's the same
> thing. Airoha is suggesting to use AN for new submission. So it's just
> about timing.

Thanks for the explanation.

> 
> > > +#define AN8855_PHY_ID				0xc0ff0410
> > > +static struct phy_driver an8855_driver[] = {
> > > +{
> > > +	PHY_ID_MATCH_EXACT(AN8855_PHY_ID),
> > 
> > Is there any documentation about the ID, and the lower nibble. Given
> > it is 0, i'm wondering if PHY_ID_MATCH_EXACT() is correct.
> >
> 
> I will check this but I doubt there is any explaination. These are internal
> to the switch so my theory is that no exact logic was applied.

O.K. It can always be changed later, if a different revision of the
PHY appears.

	Andrew


From andrej.picej at norik.com  Tue Dec 10 05:41:01 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Tue, 10 Dec 2024 14:41:01 +0100
Subject: [PATCH v5 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <irpmhq7vxjra6vhmdh7p63ajj57n3h2c4br3ija2jmwtoewist@zyxfmx6k5m4e>
References: <20241210091901.83028-1-andrej.picej@norik.com>
 <20241210091901.83028-3-andrej.picej@norik.com>
 <irpmhq7vxjra6vhmdh7p63ajj57n3h2c4br3ija2jmwtoewist@zyxfmx6k5m4e>
Message-ID: <aa2de99d-21f4-4843-83b7-5d2db78be86f@norik.com>



On 10. 12. 24 12:43, Dmitry Baryshkov wrote:
> On Tue, Dec 10, 2024 at 10:19:00AM +0100, Andrej Picej wrote:
>> Add a optional properties to change LVDS output voltage. This should not
>> be static as this depends mainly on the connected display voltage
>> requirement. We have three properties:
>> - "ti,lvds-termination-ohms", which sets near end termination,
>> - "ti,lvds-vod-swing-data-microvolt" and
>> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
>> output voltage for data and clock lanes. They are defined as an array
>> with min and max values. The appropriate bitfield will be set if
>> selected constraints can be met.
>>
>> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
>> end termination will be used. Selecting only one:
>> "ti,lvds-vod-swing-data-microvolt" or
>> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
>> constraint for only data/clock lanes will be met. Setting both is
>> recommended.
>>
>> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
>> ---
>> Changes in v5:
>> - specify default values in sn65dsi83_parse_lvds_endpoint,
>> - move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
>> Changes in v4:
>> - fix typo in commit message bitfiled -> bitfield
>> - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
>> of separate variables for channel A/B
>> - add more checks on return value of "of_property_read_u32_array"
>> Changes in v3:
>> - use microvolts for default array values 1000 mV -> 1000000 uV.
>> Changes in v2:
>> - use datasheet tables to get the proper configuration
>> - since major change was done change the authorship to myself
>> ---
>>   drivers/gpu/drm/bridge/ti-sn65dsi83.c | 142 +++++++++++++++++++++++++-
>>   1 file changed, 139 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>> index 57a7ed13f996..f9578b38da28 100644
>> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>> @@ -132,6 +132,16 @@
>>   #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>>   #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>>   
>> +enum sn65dsi83_channel {
>> +	CHANNEL_A,
>> +	CHANNEL_B
>> +};
>> +
>> +enum sn65dsi83_lvds_term {
>> +	OHM_100,
>> +	OHM_200
>> +};
>> +
>>   enum sn65dsi83_model {
>>   	MODEL_SN65DSI83,
>>   	MODEL_SN65DSI84,
>> @@ -147,6 +157,8 @@ struct sn65dsi83 {
>>   	struct regulator		*vcc;
>>   	bool				lvds_dual_link;
>>   	bool				lvds_dual_link_even_odd_swap;
>> +	int				lvds_vod_swing_conf[2];
>> +	int				lvds_term_conf[2];
>>   };
>>   
>>   static const struct regmap_range sn65dsi83_readable_ranges[] = {
>> @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>>   	.max_register = REG_IRQ_STAT,
>>   };
>>   
>> +static const int lvds_vod_swing_data_table[2][4][2] = {
>> +	{	/* 100 Ohm */
>> +		{ 180000, 313000 },
>> +		{ 215000, 372000 },
>> +		{ 250000, 430000 },
>> +		{ 290000, 488000 },
>> +	},
>> +	{	/* 200 Ohm */
>> +		{ 150000, 261000 },
>> +		{ 200000, 346000 },
>> +		{ 250000, 428000 },
>> +		{ 300000, 511000 },
>> +	},
>> +};
>> +
>> +static const int lvds_vod_swing_clock_table[2][4][2] = {
>> +	{	/* 100 Ohm */
>> +		{ 140000, 244000 },
>> +		{ 168000, 290000 },
>> +		{ 195000, 335000 },
>> +		{ 226000, 381000 },
>> +	},
>> +	{	/* 200 Ohm */
>> +		{ 117000, 204000 },
>> +		{ 156000, 270000 },
>> +		{ 195000, 334000 },
>> +		{ 234000, 399000 },
>> +	},
>> +};
>> +
>>   static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>>   {
>>   	return container_of(bridge, struct sn65dsi83, bridge);
>> @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>>   		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>>   
>>   	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
>> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
>> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
>> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
>> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
>>   	regmap_write(ctx->regmap, REG_LVDS_LANE,
>>   		     (ctx->lvds_dual_link_even_odd_swap ?
>>   		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
>> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
>> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
>> +		     (ctx->lvds_term_conf[CHANNEL_A] ?
>> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
>> +		     (ctx->lvds_term_conf[CHANNEL_B] ?
>> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>>   	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>>   
>>   	le16val = cpu_to_le16(mode->hdisplay);
>> @@ -576,10 +622,100 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>>   	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>>   };
>>   
>> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
>> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i <= 3; i++) {
>> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
>> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
>> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
>> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
>> +			return i;
>> +	}
>> +
>> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
>> +	return -EINVAL;
>> +}
>> +
>> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
>> +{
>> +	struct device *dev = ctx->dev;
>> +	struct device_node *endpoint;
>> +	int endpoint_reg;
>> +	/* Set so the property can be freely selected if not defined */
>> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
>> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
>> +	u32 lvds_term;
>> +	u8 lvds_term_conf = 0x1;
>> +	int lvds_vod_swing_conf = 0x1;
> 
> Magic values

Can you please elaborate.

I can use:
u8 lvds_term_conf = OHM_200;

What about lvds_vod_swing_conf? Should I create additional define for 
it? But this doesn't solve a hidden meaning? Maybe additional comment 
above? Would like to avoid using voltages for it, since then we are 
reverse engineering the table in datasheet to match the default reg value.

> 
>> +	int ret = 0;
>> +	int ret_data;
>> +	int ret_clock;
>> +
>> +	if (channel == CHANNEL_A)
>> +		endpoint_reg = 2;
>> +	else
>> +		endpoint_reg = 3;
>> +
>> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
>> +	if (!of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term)) {
> 
> The code has been better before:
> provide default for lvds_term, read the property (keeping the default in
> case of an error), then use the lvds_term to set up lvds_term_conf, as
> expected.

Ok, will revert back.

> 
>> +		if (lvds_term == 100)
>> +			lvds_term_conf = OHM_100;
>> +		else
>> +			lvds_term_conf = OHM_200;
>> +	}
>> +
>> +	ctx->lvds_term_conf[channel] = lvds_term_conf;
>> +
>> +	ret_data = of_property_read_u32_array(endpoint,
>> +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
>> +			ARRAY_SIZE(lvds_vod_swing_data));
>> +	if (ret_data != 0 && ret_data != -EINVAL) {
>> +		ret = ret_data;
>> +		goto exit;
>> +	}
>> +
>> +	ret_clock = of_property_read_u32_array(endpoint,
>> +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
>> +			ARRAY_SIZE(lvds_vod_swing_clk));
>> +	if (ret_clock != 0 && ret_clock != -EINVAL) {
>> +		ret = ret_clock;
>> +		goto exit;
>> +	}
>> +
>> +	/* If any of the two properties is defined. */
>> +	if (!ret_data || !ret_clock) {
>> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
>> +			lvds_vod_swing_data, lvds_vod_swing_clk,
>> +			lvds_term_conf);
>> +		if (lvds_vod_swing_conf < 0) {
>> +			ret = lvds_vod_swing_conf;
>> +			goto exit;
>> +		}
>> +	}
>> +
>> +	ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
>> +	ret = 0;
>> +exit:
>> +	of_node_put(endpoint);
>> +	return ret;
>> +}
>> +
>>   static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>>   {
>>   	struct drm_bridge *panel_bridge;
>>   	struct device *dev = ctx->dev;
>> +	int ret;
>> +
>> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
>> +	if (ret < 0)
>> +		return ret;
>>   
>>   	ctx->lvds_dual_link = false;
>>   	ctx->lvds_dual_link_even_odd_swap = false;
>> -- 
>> 2.34.1
>>
> 


From svarbanov at suse.de  Tue Dec 10 05:42:21 2024
From: svarbanov at suse.de (Stanimir Varbanov)
Date: Tue, 10 Dec 2024 15:42:21 +0200
Subject: [PATCH v4 08/10] PCI: brcmstb: Adjust PHY PLL setup to use a
 54MHz input refclk
In-Reply-To: <4bbdf9ed-f429-411b-8f5f-e51857f0f9d0@broadcom.com>
References: <20241025124515.14066-1-svarbanov@suse.de>
 <20241025124515.14066-9-svarbanov@suse.de>
 <4bbdf9ed-f429-411b-8f5f-e51857f0f9d0@broadcom.com>
Message-ID: <f9f49030-0518-4e30-91a7-3c088c31180b@suse.de>

Hi Jim

On 12/10/24 12:52 AM, James Quinlan wrote:
> On 10/25/24 08:45, Stanimir Varbanov wrote:
>> The default input reference clock for the PHY PLL is 100Mhz, except for
>> some devices where it is 54Mhz like bcm2712C1 and bcm2712D0.
>>
>> To implement this adjustments introduce a new .post_setup op in
>> pcie_cfg_data and call it at the end of brcm_pcie_setup function.
>>
>> The bcm2712 .post_setup callback implements the required MDIO writes that
>> switch the PLL refclk and also change PHY PM clock period.
>>
>> Without this RPi5 PCIex1 is unable to enumerate endpoint devices on
>> the expansion connector.
>>
>> Signed-off-by: Stanimir Varbanov <svarbanov at suse.de>
>> ---
>> v3 -> v4:
>> ? - Improved patch description (Florian)
>>
>> ? drivers/pci/controller/pcie-brcmstb.c | 42 +++++++++++++++++++++++++++
>> ? 1 file changed, 42 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/
>> controller/pcie-brcmstb.c
>> index d970a76aa9ef..2571dcc14560 100644
>> --- a/drivers/pci/controller/pcie-brcmstb.c
>> +++ b/drivers/pci/controller/pcie-brcmstb.c
>> @@ -55,6 +55,10 @@
>> ? #define PCIE_RC_DL_MDIO_WR_DATA??????????????? 0x1104
>> ? #define PCIE_RC_DL_MDIO_RD_DATA??????????????? 0x1108
>> ? +#define PCIE_RC_PL_PHY_CTL_15??????????????? 0x184c
>> +#define? PCIE_RC_PL_PHY_CTL_15_DIS_PLL_PD_MASK??????? 0x400000
>> +#define? PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK??? 0xff
>> +
>> ? #define PCIE_MISC_MISC_CTRL??????????????? 0x4008
>> ? #define? PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE_MASK??? 0x80
>> ? #define? PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE_MASK??? 0x400
>> @@ -251,6 +255,7 @@ struct pcie_cfg_data {
>> ????? u8 num_inbound_wins;
>> ????? int (*perst_set)(struct brcm_pcie *pcie, u32 val);
>> ????? int (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
>> +??? int (*post_setup)(struct brcm_pcie *pcie);
>> ? };
>> ? ? struct subdev_regulators {
>> @@ -826,6 +831,36 @@ static int brcm_pcie_perst_set_generic(struct
>> brcm_pcie *pcie, u32 val)
>> ????? return 0;
>> ? }
>> ? +static int brcm_pcie_post_setup_bcm2712(struct brcm_pcie *pcie)
>> +{
>> +??? const u16 data[] = { 0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030,
>> 0x5030, 0x0007 };
>> +??? const u8 regs[] = { 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e };
>> +??? int ret, i;
>> +??? u32 tmp;
>> +
>> +??? /* Allow a 54MHz (xosc) refclk source */
>> +??? ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0,
>> SET_ADDR_OFFSET, 0x1600);
>> +??? if (ret < 0)
>> +??????? return ret;
>> +
>> +??? for (i = 0; i < ARRAY_SIZE(regs); i++) {
>> +??????? ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, regs[i],
>> data[i]);
>> +??????? if (ret < 0)
>> +??????????? return ret;
>> +??? }
>> +
>> +??? usleep_range(100, 200);
>> +
>> +??? /* Fix for L1SS errata */
>> +??? tmp = readl(pcie->base + PCIE_RC_PL_PHY_CTL_15);
>> +??? tmp &= ~PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK;
>> +??? /* PM clock period is 18.52ns (round down) */
>> +??? tmp |= 0x12;
>> +??? writel(tmp, pcie->base + PCIE_RC_PL_PHY_CTL_15);
> 
> Hi Stan,
> 
> Can you please say more about where this errata came from?? I asked the
> 7712 PCIe HW folks and they said that there best guess was that it was a
> old workaround for a particular Broadcom Wifi endpoint.? Do you know its
> origin?

Unfortunately, I don't know the details. See the comments on previous
series version [1]. My observation shows that MDIO writes are
implemented in RPi platform firmware only for pcie2 (where RP1 south
bridge is connected) but not for pcie1 expansion connector.

~Stan

[1] https://www.spinics.net/lists/linux-pci/msg160842.html



From dsimic at manjaro.org  Tue Dec 10 05:44:14 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 10 Dec 2024 14:44:14 +0100
Subject: [PATCH 6/6] arm64: dts: rockchip: Remove address aligned beats
 from rk3328-roc
In-Reply-To: <CAMdYzYpj3d7Rq0O0QjV4r6HEf_e07R0QAhPT2NheZdQV3TnQ6g@mail.gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-7-pgwipeout@gmail.com>
 <2b68c2dd3618e5904a4eac1ec87d29a7@manjaro.org>
 <CAMdYzYpj3d7Rq0O0QjV4r6HEf_e07R0QAhPT2NheZdQV3TnQ6g@mail.gmail.com>
Message-ID: <6453e714b2a48572ff1e57cd74b0f6d3@manjaro.org>

Hello Peter,

On 2024-12-10 12:29, Peter Geis wrote:
> On Tue, Dec 10, 2024 at 5:45?AM Dragan Simic <dsimic at manjaro.org> 
> wrote:
>> Thanks for the patch.  Please, see some comments below.
>> 
>> On 2024-12-10 02:30, Peter Geis wrote:
>> > Since commit 8a469ee35606 ("arm64: dts: rockchip: Add txpbl node for
>> > RK3399/RK3328"), the snps,aal, snps,txpbl, and snps,rxpbl nodes have
>> > been unnecessary in the separate device trees. There is also a
>> > performance loss to using snps,aal. Remove these from the rk3328-roc
>> > device tree.
>> >
>> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>> >
>> > ---
>> >
>> >  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 3 ---
>> >  1 file changed, 3 deletions(-)
>> >
>> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
>> > b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
>> > index 6984387ff8b3..0d476cc2144d 100644
>> > --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
>> > +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
>> > @@ -155,12 +155,9 @@ &gmac2io {
>> >       phy-mode = "rgmii";
>> >       pinctrl-names = "default";
>> >       pinctrl-0 = <&rgmiim1_pins>;
>> > -     snps,aal;
>> 
>> Huh, I see that quite a few RK3328 board dts files specify
>> the snps,aal node.  I wonder was it a "cargo cult" approach
>> at play, :) or was there some real need for it?
>> 
>> Actually, I see now that you added snps,aal to rk3328-roc-
>> cc.dts in the commit 393f3875c385 ("arm64: dts: rockchip:
>> improve rk3328-roc-cc rgmii performance."), so I guess that
>> your further research and testing showed that it actually
>> isn't needed for Ethernet stability?
>> 
>> >       snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
>> >       snps,reset-active-low;
>> >       snps,reset-delays-us = <0 10000 50000>;
>> > -     snps,rxpbl = <0x4>;
>> > -     snps,txpbl = <0x4>;
>> 
>> Unless I'm missing something, the commit 8a469ee35606 ("arm64:
>> dts: rockchip: Add txpbl node for RK3399/RK3328") doesn't add
>> the snps,rxpbl node to the RK3328 SoC dtsi, and the respective
>> driver does nothing about it when the snps,txpbl node is found.
>> 
>> Though, I see that rk3328-rock-pi-e.dts is the only other
>> RK3328 board dts file that specifies the snps,rxpbl node, so
>> it seems that removing the snps,rxpbl node here should be safe,
>> especially because it was you who added it in the same commit
>> mentioned above.  If there were some SoC-level issues, all
>> RK3328 boards would've needed it.
> 
> Good Morning,
> 
> You'll notice the author of that patch was me. Setting aal, txpbl, and
> rxpbl was the original fix I came up with for the rk3328, which I
> applied to the only board I had. Someone else later on isolated it
> specifically isolated it to just the txpbl and applied it to both the
> rk3328 and rk3399 directly.
> 
> This was just something that was left hanging after that result.
> 
> Looking at how rk356x was done, I suspect there's an even more elegant
> solution. However I don't have the deep level knowledge nor
> documentation to implement it.

Sure, I noticed that you authored the original Ethernet stability
fix. :)  With all this in mind, please feel free to include

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

and I'll prepare a patch or two that clean up any and all leftovers
in other board dts(i) files.


From will at kernel.org  Tue Dec 10 05:50:52 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 13:50:52 +0000
Subject: [PATCH v9 05/15] arm64: barrier: add support for
 smp_cond_relaxed_timeout()
In-Reply-To: <20241107190818.522639-6-ankur.a.arora@oracle.com>
References: <20241107190818.522639-1-ankur.a.arora@oracle.com>
 <20241107190818.522639-6-ankur.a.arora@oracle.com>
Message-ID: <20241210135052.GB15607@willie-the-truck>

On Thu, Nov 07, 2024 at 11:08:08AM -0800, Ankur Arora wrote:
> Support a waited variant of polling on a conditional variable
> via smp_cond_relaxed_timeout().
> 
> This uses the __cmpwait_relaxed() primitive to do the actual
> waiting, when the wait can be guaranteed to not block forever
> (in case there are no stores to the waited for cacheline.)
> For this we depend on the availability of the event-stream.
> 
> For cases when the event-stream is unavailable, we fallback to
> a spin-waited implementation which is identical to the generic
> variant.
> 
> Signed-off-by: Ankur Arora <ankur.a.arora at oracle.com>
> ---
>  arch/arm64/include/asm/barrier.h | 54 ++++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
> index 1ca947d5c939..ab2515ecd6ca 100644
> --- a/arch/arm64/include/asm/barrier.h
> +++ b/arch/arm64/include/asm/barrier.h
> @@ -216,6 +216,60 @@ do {									\
>  	(typeof(*ptr))VAL;						\
>  })
>  
> +#define __smp_cond_load_timeout_spin(ptr, cond_expr,			\
> +				     time_expr_ns, time_limit_ns)	\
> +({									\
> +	typeof(ptr) __PTR = (ptr);					\
> +	__unqual_scalar_typeof(*ptr) VAL;				\
> +	unsigned int __count = 0;					\
> +	for (;;) {							\
> +		VAL = READ_ONCE(*__PTR);				\
> +		if (cond_expr)						\
> +			break;						\
> +		cpu_relax();						\
> +		if (__count++ < smp_cond_time_check_count)		\
> +			continue;					\
> +		if ((time_expr_ns) >= time_limit_ns)			\
> +			break;						\
> +		__count = 0;						\
> +	}								\
> +	(typeof(*ptr))VAL;						\
> +})

This is a carbon-copy of the asm-generic timeout implementation. Please
can you avoid duplicating that in the arch code?

Will


From srinivas.kandagatla at linaro.org  Tue Dec 10 05:52:14 2024
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 10 Dec 2024 13:52:14 +0000
Subject: [PATCH v2 0/4] nvmem: imx-ocotp-ele: fix reading from ELE OCOTP
In-Reply-To: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
References: <20241202-imx-ele-ocotp-fixes-v2-0-3c021a97eb5d@pengutronix.de>
Message-ID: <3e16b2f5-5aeb-4988-bf6f-63c7309f53a4@linaro.org>



On 02/12/2024 11:22, Sascha Hauer wrote:
> Commits b2ab0edaf484 ("arm64: dts: imx93: add nvmem property for fec1")
> and 0d4fbaffbdca ("arm64: dts: imx93: add nvmem property for eqos")
> introduced NVMEM cell bindings for reading MAC addresses from the ELE
> OCOTP. This doesn't work as expected due to bugs in the driver:
> 
> - imx_ocotp_reg_read() interprets the incoming offset as 32bit word
>    offset, but it really is in bytes which means the driver reads bogus
>    values whenever the offset is non zero
> - imx_ocotp_reg_read() reads wrong results when the offset is not 32bit
>    word aligned
> - MAC addresses are stored in reverse byte order in the ELE OCOTP, we
>    have to swap the order before passing them to the upper layer
> 
> This likely went through unnoticed because the bootloader normally adds
> the MAC addresses to the ethernet nodes and in this case they are
> preferred over the NVMEM addresses.
> 
> This series fixes these issues.
> 
> Sascha
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
> Changes in v2:
> - Add Fixes: and Cc: stable tag as requested by Fabio
> - Link to v1: https://lore.kernel.org/r/20241023-imx-ele-ocotp-fixes-v1-0-4adc00ce288f at pengutronix.de
> 
> ---
> Sascha Hauer (4):
>        nvmem: imx-ocotp-ele: simplify read beyond device check
>        nvmem: imx-ocotp-ele: fix reading from non zero offset
>        nvmem: imx-ocotp-ele: fix MAC address byte order
>        nvmem: imx-ocotp-ele: set word length to 1


Applied thanks,

--srini
> 
>   drivers/nvmem/imx-ocotp-ele.c | 38 +++++++++++++++++++++++++++++++-------
>   1 file changed, 31 insertions(+), 7 deletions(-)
> ---
> base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
> change-id: 20241023-imx-ele-ocotp-fixes-f7b216171e1e
> 
> Best regards,


From dsimic at manjaro.org  Tue Dec 10 05:53:00 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 10 Dec 2024 14:53:00 +0100
Subject: [PATCH 4/6] arm64: dts: rockchip: add hevc power domain clock to
 rk3328
In-Reply-To: <CAMdYzYquvGBzfWqvUOku7m1sM9qxmBHAL95cANDViUCT1oEEhQ@mail.gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-5-pgwipeout@gmail.com>
 <e32fa593abfa6d08202b4f929e0b4bdb@manjaro.org>
 <CAMdYzYp+MQVYr1tOMEOn62vXZGVEYrtd1p9vn6YQzXdrJgSdyA@mail.gmail.com>
 <CAMdYzYquvGBzfWqvUOku7m1sM9qxmBHAL95cANDViUCT1oEEhQ@mail.gmail.com>
Message-ID: <8c604ada27457698ad6d33d22a39b45a@manjaro.org>

Hello Peter,

On 2024-12-10 14:23, Peter Geis wrote:
> On Tue, Dec 10, 2024 at 8:13?AM Peter Geis <pgwipeout at gmail.com> wrote:
>> On Tue, Dec 10, 2024 at 5:04?AM Dragan Simic <dsimic at manjaro.org> 
>> wrote:
>> > On 2024-12-10 02:30, Peter Geis wrote:
>> > > There is a race condition at startup between disabling power domains
>> > > not
>> > > used and disabling clocks not used on the rk3328. When the clocks are
>> > > disabled first, the hevc power domain fails to shut off leading to a
>> > > splat of failures. Add the hevc core clock to the rk3328 power domain
>> > > node to prevent this condition.
>> > >
>> > > rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-....
>> > > }
>> > > 1087 jiffies s: 89 root: 0x8/.
>> > > rcu: blocking rcu_node structures (internal RCU debug):
>> > > Sending NMI from CPU 0 to CPUs 3:
>> > > NMI backtrace for cpu 3
>> > > CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53
>> > > Hardware name: Firefly ROC-RK3328-CC (DT)
>> > > Workqueue: pm genpd_power_off_work_fn
>> > > pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>> > > pc : regmap_unlock_spinlock+0x18/0x30
>> > > lr : regmap_read+0x60/0x88
>> > > sp : ffff800081123c00
>> > > x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000
>> > > x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040
>> > > x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74
>> > > x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000
>> > > x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d
>> > > x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431
>> > > x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0
>> > > x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b
>> > > x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40
>> > > x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000
>> > > Call trace:
>> > > regmap_unlock_spinlock+0x18/0x30
>> > > rockchip_pmu_set_idle_request+0xac/0x2c0
>> > > rockchip_pd_power+0x144/0x5f8
>> > > rockchip_pd_power_off+0x1c/0x30
>> > > _genpd_power_off+0x9c/0x180
>> > > genpd_power_off.part.0.isra.0+0x130/0x2a8
>> > > genpd_power_off_work_fn+0x6c/0x98
>> > > process_one_work+0x170/0x3f0
>> > > worker_thread+0x290/0x4a8
>> > > kthread+0xec/0xf8
>> > > ret_from_fork+0x10/0x20
>> > > rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack
>> > > on
>> > > domain 'hevc', val=0x88220
>> > >
>> > > Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for
>> > > RK3328 SoCs")
>> > > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>> >
>> > While I was unable to formally verify this clock assignment,
>> > i.e. by using the RK3328 TRM or the downstream kernel source
>> > from Rockchip, it makes perfect sense to me.  Thanks for the
>> > patch, and please feel free to include:
>> >
>> > Reviewed-by: Dragan Simic <dsimic at manjaro.org>
>> 
>> It is unfortunate the TRM doesn't include the clock maps, because they
>> are extremely helpful when one can acquire them. It also doesn't help
>> that the TRM register definition only referred to this as "pll". I was
>> sent specifically the usb3 phy clock map for my work on the driver,
>> which had the location of each switch and divider along with the
>> register and bit that controlled it. That combined with the TRM
>> register map allowed me to find this error.
> 
> Apologies, that's the wrong response for this one.

No worries.

> This patch was the result of educated guess combined with testing. I
> grabbed all of the clocks that looked like they could affect things,
> then tested them one at a time until I isolated them to this clock. It
> lives alone with cpll as the parent and has no children according to
> the clock summary. (Though the writeup i mistakenly included above
> proves the clock map isn't always accurate).

I see, thanks for all your work on this patch!  It surely took quite
a lot of time to perform all the testing.

>> > > ---
>> > >
>> > >  arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 +
>> > >  1 file changed, 1 insertion(+)
>> > >
>> > > diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>> > > b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>> > > index 0597de415fe0..7d992c3c01ce 100644
>> > > --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>> > > +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>> > > @@ -333,6 +333,7 @@ power: power-controller {
>> > >
>> > >                       power-domain at RK3328_PD_HEVC {
>> > >                               reg = <RK3328_PD_HEVC>;
>> > > +                             clocks = <&cru SCLK_VENC_CORE>;
>> > >                               #power-domain-cells = <0>;
>> > >                       };
>> > >                       power-domain at RK3328_PD_VIDEO {


From ulf.hansson at linaro.org  Tue Dec 10 06:01:58 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 10 Dec 2024 15:01:58 +0100
Subject: [PATCH 1/2] pmdomain: imx8m[p]-blk-ctrl: Suppress bind attrs
In-Reply-To: <20241206112731.98244-1-peng.fan@oss.nxp.com>
References: <20241206112731.98244-1-peng.fan@oss.nxp.com>
Message-ID: <CAPDyKFrM6wX5uWY8g0pgZNEZn8uG5hbD4JsAijBenOMWkEgD4w@mail.gmail.com>

On Fri, 6 Dec 2024 at 12:28, Peng Fan (OSS) <peng.fan at oss.nxp.com> wrote:
>
> From: Peng Fan <peng.fan at nxp.com>
>
> The blk ctrl drivers on imx8m series are registered as platform
> devices and this opens the possibility of reloading the driver
> at runtime.
>
> But this doesn't actually work. There are some hardware sequence
> dependecy between blk ctrl and gpc, also power domains are used
> by other peripherals, so fix this by explicitly suppressing bind
> attrs.
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/pmdomain/imx/imx8m-blk-ctrl.c  | 1 +
>  drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 1 +
>  2 files changed, 2 insertions(+)
>
> diff --git a/drivers/pmdomain/imx/imx8m-blk-ctrl.c b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
> index 23db85b7aa9e..912802b5215b 100644
> --- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c
> +++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
> @@ -894,6 +894,7 @@ static struct platform_driver imx8m_blk_ctrl_driver = {
>                 .name = "imx8m-blk-ctrl",
>                 .pm = &imx8m_blk_ctrl_pm_ops,
>                 .of_match_table = imx8m_blk_ctrl_of_match,
> +               .suppress_bind_attrs = true,
>         },
>  };
>  module_platform_driver(imx8m_blk_ctrl_driver);
> diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> index e3a0f64c144c..411dd548c67c 100644
> --- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> +++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> @@ -862,6 +862,7 @@ static struct platform_driver imx8mp_blk_ctrl_driver = {
>                 .name = "imx8mp-blk-ctrl",
>                 .pm = &imx8mp_blk_ctrl_pm_ops,
>                 .of_match_table = imx8mp_blk_ctrl_of_match,
> +               .suppress_bind_attrs = true,
>         },
>  };
>  module_platform_driver(imx8mp_blk_ctrl_driver);
> --
> 2.37.1
>


From ulf.hansson at linaro.org  Tue Dec 10 06:02:01 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 10 Dec 2024 15:02:01 +0100
Subject: [PATCH 2/2] pmdomain: gpcv2: Suppress bind attrs
In-Reply-To: <20241206112731.98244-2-peng.fan@oss.nxp.com>
References: <20241206112731.98244-1-peng.fan@oss.nxp.com> <20241206112731.98244-2-peng.fan@oss.nxp.com>
Message-ID: <CAPDyKFpWfqpgmMpuq+69ee2FU7wOSgHUmfEcLpS1Dy2vx8c-MA@mail.gmail.com>

On Fri, 6 Dec 2024 at 12:28, Peng Fan (OSS) <peng.fan at oss.nxp.com> wrote:
>
> From: Peng Fan <peng.fan at nxp.com>
>
> The gpcv2 drivers on imx8m series are registered as platform
> devices and this opens the possibility of reloading the driver
> at runtime.
>
> But this doesn't actually work. There are some hardware sequence
> dependecy between blk ctrl and gpc, also power domains are used
> by other peripherals, so fix this by explicitly suppressing bind
> attrs.
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/pmdomain/imx/gpcv2.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c
> index e67ecf99ef84..4db4d666f5bf 100644
> --- a/drivers/pmdomain/imx/gpcv2.c
> +++ b/drivers/pmdomain/imx/gpcv2.c
> @@ -1437,6 +1437,7 @@ static struct platform_driver imx_pgc_domain_driver = {
>         .driver = {
>                 .name = "imx-pgc",
>                 .pm = &imx_pgc_domain_pm_ops,
> +               .suppress_bind_attrs = true,
>         },
>         .probe    = imx_pgc_domain_probe,
>         .remove = imx_pgc_domain_remove,
> @@ -1549,6 +1550,7 @@ static struct platform_driver imx_gpc_driver = {
>         .driver = {
>                 .name = "imx-gpcv2",
>                 .of_match_table = imx_gpcv2_dt_ids,
> +               .suppress_bind_attrs = true,
>         },
>         .probe = imx_gpcv2_probe,
>  };
> --
> 2.37.1
>


From tabba at google.com  Tue Dec 10 05:58:42 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 13:58:42 +0000
Subject: [PATCH v2 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <20241203103735.2267589-11-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-11-qperret@google.com>
Message-ID: <CA+EHjTwHSyQ1FJc7axbLNuBxSWpRVE6brb34nO+F59=QRmfQEg@mail.gmail.com>

Hi Quentin,

On Tue, 3 Dec 2024 at 10:37, Quentin Perret <qperret at google.com> wrote:
>
> In preparation for handling guest stage-2 mappings at EL2, introduce a
> new pKVM hypercall allowing to share pages with non-protected guests.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/include/asm/kvm_host.h             |  3 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/memory.h      |  2 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 34 +++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 70 +++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/pkvm.c                |  7 ++
>  7 files changed, 118 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 89c0fac69551..449337f5b2a3 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -65,6 +65,7 @@ enum __kvm_host_smccc_func {
>         /* Hypercalls available after pKVM finalisation */
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index e18e9244d17a..f75988e3515b 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -771,6 +771,9 @@ struct kvm_vcpu_arch {
>         /* Cache some mmu pages needed inside spinlock regions */
>         struct kvm_mmu_memory_cache mmu_page_cache;
>
> +       /* Pages to be donated to pkvm/EL2 if it runs out */

Runs out of what? :) I'm being facetious, it's just that the comment
is a bit unclear.

> +       struct kvm_hyp_memcache pkvm_memcache;
> +
>         /* Virtual SError ESR to restore when HCR_EL2.VSE is set */
>         u64 vsesr_el2;
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 25038ac705d8..a7976e50f556 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -39,6 +39,7 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages);
>  int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
> +int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> index 08f3a0416d4c..457318215155 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> @@ -47,6 +47,8 @@ struct hyp_page {
>
>         /* Host (non-meta) state. Guarded by the host stage-2 lock. */
>         enum pkvm_page_state host_state : 8;
> +
> +       u32 host_share_guest_count;
>  };
>
>  extern u64 __hyp_vmemmap;
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 95d78db315b3..d659462fbf5d 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -211,6 +211,39 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) =  ret;
>  }
>
> +static int pkvm_refill_memcache(struct pkvm_hyp_vcpu *hyp_vcpu)
> +{
> +       struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
> +
> +       return refill_memcache(&hyp_vcpu->vcpu.arch.pkvm_memcache,
> +                              host_vcpu->arch.pkvm_memcache.nr_pages,
> +                              &host_vcpu->arch.pkvm_memcache);
> +}
> +
> +static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(u64, pfn, host_ctxt, 1);
> +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> +       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 3);
> +       struct pkvm_hyp_vcpu *hyp_vcpu;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> +       if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> +               goto out;
> +
> +       ret = pkvm_refill_memcache(hyp_vcpu);
> +       if (ret)
> +               goto out;
> +
> +       ret = __pkvm_host_share_guest(pfn, gfn, hyp_vcpu, prot);
> +out:
> +       cpu_reg(host_ctxt, 1) =  ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -420,6 +453,7 @@ static const hcall_t host_hcall[] = {
>
>         HANDLE_FUNC(__pkvm_host_share_hyp),
>         HANDLE_FUNC(__pkvm_host_unshare_hyp),
> +       HANDLE_FUNC(__pkvm_host_share_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 1595081c4f6b..a69d7212b64c 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -861,6 +861,27 @@ static int hyp_complete_donation(u64 addr,
>         return pkvm_create_mappings_locked(start, end, prot);
>  }
>
> +static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr)
> +{
> +       if (!kvm_pte_valid(pte))
> +               return PKVM_NOPAGE;
> +
> +       return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
> +}
> +
> +static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
> +                                         u64 size, enum pkvm_page_state state)
> +{
> +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> +       struct check_walk_data d = {
> +               .desired        = state,
> +               .get_page_state = guest_get_page_state,
> +       };
> +
> +       hyp_assert_lock_held(&vm->lock);
> +       return check_page_state_range(&vm->pgt, addr, size, &d);
> +}
> +
>  static int check_share(struct pkvm_mem_share *share)
>  {
>         const struct pkvm_mem_transition *tx = &share->tx;
> @@ -1343,3 +1364,52 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
>
>         return ret;
>  }
> +
> +int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
> +                           enum kvm_pgtable_prot prot)
> +{
> +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> +       u64 phys = hyp_pfn_to_phys(pfn);
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       struct hyp_page *page;
> +       int ret;
> +
> +       if (prot & ~KVM_PGTABLE_PROT_RWX)
> +               return -EINVAL;
> +
> +       ret = range_is_allowed_memory(phys, phys + PAGE_SIZE);
> +       if (ret)
> +               return ret;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __guest_check_page_state_range(vcpu, ipa, PAGE_SIZE, PKVM_NOPAGE);
> +       if (ret)
> +               goto unlock;
> +
> +       page = hyp_phys_to_page(phys);
> +       switch (page->host_state) {
> +       case PKVM_PAGE_OWNED:
> +               WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_OWNED));
> +               break;
> +       case PKVM_PAGE_SHARED_OWNED:
> +               /* Only host to np-guest multi-sharing is tolerated */

Initially I thought the comment was related to the warning below,
which confused me. Now I think what you're trying to say is that we'll
allow the share, and the (unrelated to the comment) warning is to
ensure that the PKVM_PAGE_SHARED_OWNED is consistent with the share
count.

I think what you should have here, which would work better with the
comment, is something like:

                /* Only host to np-guest multi-sharing is tolerated */
+               if (pkvm_hyp_vcpu_is_protected(vcpu))
+                       return -EPERM;

That would even make the comment unnecessary.


> +               WARN_ON(!page->host_share_guest_count);
> +               break;
> +       default:
> +               ret = -EPERM;
> +               goto unlock;
> +       }
> +
> +       WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys,
> +                                      pkvm_mkstate(prot, PKVM_PAGE_SHARED_BORROWED),
> +                                      &vcpu->vcpu.arch.pkvm_memcache, 0));
> +       page->host_share_guest_count++;
> +
> +unlock:
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index d5c23449a64c..d6c61a5e7b6e 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -795,6 +795,13 @@ int __pkvm_teardown_vm(pkvm_handle_t handle)
>         /* Push the metadata pages to the teardown memcache */
>         for (idx = 0; idx < hyp_vm->nr_vcpus; ++idx) {
>                 struct pkvm_hyp_vcpu *hyp_vcpu = hyp_vm->vcpus[idx];
> +               struct kvm_hyp_memcache *vcpu_mc = &hyp_vcpu->vcpu.arch.pkvm_memcache;
> +
> +               while (vcpu_mc->nr_pages) {
> +                       void *addr = pop_hyp_memcache(vcpu_mc, hyp_phys_to_virt);

nit: newline

Cheers,
/fuad



> +                       push_hyp_memcache(mc, addr, hyp_virt_to_phys);
> +                       unmap_donated_memory_noclear(addr, PAGE_SIZE);
> +               }
>
>                 teardown_donated_memory(mc, hyp_vcpu, sizeof(*hyp_vcpu));
>         }
> --
> 2.47.0.338.g60cca15819-goog
>


From dsimic at manjaro.org  Tue Dec 10 05:59:23 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 10 Dec 2024 14:59:23 +0100
Subject: [PATCH 2/6] clk: rockchip: fix wrong clk_ref_usb3otg parent for
 rk3328
In-Reply-To: <CAMdYzYqJLK6oJHCUVztth6mtJsYrRQSPzNYpR-ZmR7rNprZXfg@mail.gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-3-pgwipeout@gmail.com>
 <0d11705121f29ccfb7cfa342505a6e35@manjaro.org>
 <CAMdYzYqJLK6oJHCUVztth6mtJsYrRQSPzNYpR-ZmR7rNprZXfg@mail.gmail.com>
Message-ID: <bcc296ea8c15eddce62a8d3ef3a509b7@manjaro.org>

Hello Peter,

On 2024-12-10 14:27, Peter Geis wrote:
> On Tue, Dec 10, 2024 at 4:44?AM Dragan Simic <dsimic at manjaro.org> 
> wrote:
>> On 2024-12-10 02:30, Peter Geis wrote:
>> > Correct the clk_ref_usb3otg parent to fix clock control for the usb3
>> > controller on rk3328. Verified against the rk3328 trm and usb3 clock
>> > tree
>> > documentation.
>> >
>> > Fixes: fe3511ad8a1c ("clk: rockchip: add clock controller for rk3328")
>> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>> > ---
>> >
>> >  drivers/clk/rockchip/clk-rk3328.c | 2 +-
>> >  1 file changed, 1 insertion(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/clk/rockchip/clk-rk3328.c
>> > b/drivers/clk/rockchip/clk-rk3328.c
>> > index 3bb87b27b662..cf60fcf2fa5c 100644
>> > --- a/drivers/clk/rockchip/clk-rk3328.c
>> > +++ b/drivers/clk/rockchip/clk-rk3328.c
>> > @@ -201,7 +201,7 @@ PNAME(mux_aclk_peri_pre_p)        = { "cpll_peri",
>> >                                   "gpll_peri",
>> >                                   "hdmiphy_peri" };
>> >  PNAME(mux_ref_usb3otg_src_p) = { "xin24m",
>> > -                                 "clk_usb3otg_ref" };
>> > +                                 "clk_ref_usb3otg_src" };
>> >  PNAME(mux_xin24m_32k_p)              = { "xin24m",
>> >                                   "clk_rtc32k" };
>> >  PNAME(mux_mac2io_src_p)              = { "clk_mac2io_src",
>> 
>> Sorry, but I was unable to verify this in the part 1 of the
>> RK3328 TRM, in both versions 1.1 and 1.2, which is all I have
>> when it comes to the RK3328 TRM.  Is that maybe described in
>> the part 2, which I've been unable to locate for years?
>> 
>> Moreover, the downstream kernel source from Rockchip does it
>> the way [1] it's currently done in the mainline kernel, which
>> makes me confused a bit?  Could you, please, provide more
>> details about the two references you mentioned in the patch
>> description, or maybe even you could provide the links to
>> those two references?
>> 
>> [1] 
>> https://raw.githubusercontent.com/rockchip-linux/kernel/refs/heads/develop-4.4/drivers/clk/rockchip/clk-rk3328.c
> 
> It is unfortunate the TRM doesn't include the clock maps, because they
> are extremely helpful when one can acquire them. It also doesn't help
> that the TRM register definition only referred to this as "pll". I was
> sent specifically the usb3 phy clock map for my work on the driver,
> which had the location of each switch and divider along with the
> register and bit that controlled it. That combined with the TRM
> register map allowed me to find this error.

I see, thanks for the clarification.  I'd assume that you aren't allowed
to share the additional documentation you've got, which is unfortunate,
but it is what it is.  We should be happy that at least you got it, and
were able to put it into good use.

Thanks for fixing this!


From dmitry.baryshkov at linaro.org  Tue Dec 10 05:59:24 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 15:59:24 +0200
Subject: [PATCH v5 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <aa2de99d-21f4-4843-83b7-5d2db78be86f@norik.com>
References: <20241210091901.83028-1-andrej.picej@norik.com>
 <20241210091901.83028-3-andrej.picej@norik.com>
 <irpmhq7vxjra6vhmdh7p63ajj57n3h2c4br3ija2jmwtoewist@zyxfmx6k5m4e>
 <aa2de99d-21f4-4843-83b7-5d2db78be86f@norik.com>
Message-ID: <qhmsobin3fsmoc7ic2jtancowfscoauyroruxdpwhmqwlogtkz@6by3s2ruwzwp>

On Tue, Dec 10, 2024 at 02:41:01PM +0100, Andrej Picej wrote:
> 
> 
> On 10. 12. 24 12:43, Dmitry Baryshkov wrote:
> > On Tue, Dec 10, 2024 at 10:19:00AM +0100, Andrej Picej wrote:
> > > Add a optional properties to change LVDS output voltage. This should not
> > > be static as this depends mainly on the connected display voltage
> > > requirement. We have three properties:
> > > - "ti,lvds-termination-ohms", which sets near end termination,
> > > - "ti,lvds-vod-swing-data-microvolt" and
> > > - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> > > output voltage for data and clock lanes. They are defined as an array
> > > with min and max values. The appropriate bitfield will be set if
> > > selected constraints can be met.
> > > 
> > > If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> > > end termination will be used. Selecting only one:
> > > "ti,lvds-vod-swing-data-microvolt" or
> > > "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> > > constraint for only data/clock lanes will be met. Setting both is
> > > recommended.
> > > 
> > > Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> > > ---
> > > Changes in v5:
> > > - specify default values in sn65dsi83_parse_lvds_endpoint,
> > > - move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
> > > Changes in v4:
> > > - fix typo in commit message bitfiled -> bitfield
> > > - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
> > > of separate variables for channel A/B
> > > - add more checks on return value of "of_property_read_u32_array"
> > > Changes in v3:
> > > - use microvolts for default array values 1000 mV -> 1000000 uV.
> > > Changes in v2:
> > > - use datasheet tables to get the proper configuration
> > > - since major change was done change the authorship to myself
> > > ---
> > >   drivers/gpu/drm/bridge/ti-sn65dsi83.c | 142 +++++++++++++++++++++++++-
> > >   1 file changed, 139 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > index 57a7ed13f996..f9578b38da28 100644
> > > --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > @@ -132,6 +132,16 @@
> > >   #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
> > >   #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
> > > +enum sn65dsi83_channel {
> > > +	CHANNEL_A,
> > > +	CHANNEL_B
> > > +};
> > > +
> > > +enum sn65dsi83_lvds_term {
> > > +	OHM_100,
> > > +	OHM_200
> > > +};
> > > +
> > >   enum sn65dsi83_model {
> > >   	MODEL_SN65DSI83,
> > >   	MODEL_SN65DSI84,
> > > @@ -147,6 +157,8 @@ struct sn65dsi83 {
> > >   	struct regulator		*vcc;
> > >   	bool				lvds_dual_link;
> > >   	bool				lvds_dual_link_even_odd_swap;
> > > +	int				lvds_vod_swing_conf[2];
> > > +	int				lvds_term_conf[2];
> > >   };
> > >   static const struct regmap_range sn65dsi83_readable_ranges[] = {
> > > @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
> > >   	.max_register = REG_IRQ_STAT,
> > >   };
> > > +static const int lvds_vod_swing_data_table[2][4][2] = {
> > > +	{	/* 100 Ohm */
> > > +		{ 180000, 313000 },
> > > +		{ 215000, 372000 },
> > > +		{ 250000, 430000 },
> > > +		{ 290000, 488000 },
> > > +	},
> > > +	{	/* 200 Ohm */
> > > +		{ 150000, 261000 },
> > > +		{ 200000, 346000 },
> > > +		{ 250000, 428000 },
> > > +		{ 300000, 511000 },
> > > +	},
> > > +};
> > > +
> > > +static const int lvds_vod_swing_clock_table[2][4][2] = {
> > > +	{	/* 100 Ohm */
> > > +		{ 140000, 244000 },
> > > +		{ 168000, 290000 },
> > > +		{ 195000, 335000 },
> > > +		{ 226000, 381000 },
> > > +	},
> > > +	{	/* 200 Ohm */
> > > +		{ 117000, 204000 },
> > > +		{ 156000, 270000 },
> > > +		{ 195000, 334000 },
> > > +		{ 234000, 399000 },
> > > +	},
> > > +};
> > > +
> > >   static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
> > >   {
> > >   	return container_of(bridge, struct sn65dsi83, bridge);
> > > @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
> > >   		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
> > >   	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
> > > -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
> > > +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
> > > +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
> > > +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
> > >   	regmap_write(ctx->regmap, REG_LVDS_LANE,
> > >   		     (ctx->lvds_dual_link_even_odd_swap ?
> > >   		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
> > > -		     REG_LVDS_LANE_CHA_LVDS_TERM |
> > > -		     REG_LVDS_LANE_CHB_LVDS_TERM);
> > > +		     (ctx->lvds_term_conf[CHANNEL_A] ?
> > > +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
> > > +		     (ctx->lvds_term_conf[CHANNEL_B] ?
> > > +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
> > >   	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
> > >   	le16val = cpu_to_le16(mode->hdisplay);
> > > @@ -576,10 +622,100 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
> > >   	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
> > >   };
> > > +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
> > > +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
> > > +{
> > > +	int i;
> > > +
> > > +	for (i = 0; i <= 3; i++) {
> > > +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
> > > +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
> > > +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> > > +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
> > > +			return i;
> > > +	}
> > > +
> > > +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
> > > +	return -EINVAL;
> > > +}
> > > +
> > > +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> > > +{
> > > +	struct device *dev = ctx->dev;
> > > +	struct device_node *endpoint;
> > > +	int endpoint_reg;
> > > +	/* Set so the property can be freely selected if not defined */
> > > +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
> > > +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
> > > +	u32 lvds_term;
> > > +	u8 lvds_term_conf = 0x1;
> > > +	int lvds_vod_swing_conf = 0x1;
> > 
> > Magic values
> 
> Can you please elaborate.
> 
> I can use:
> u8 lvds_term_conf = OHM_200;
> 
> What about lvds_vod_swing_conf? Should I create additional define for it?
> But this doesn't solve a hidden meaning? Maybe additional comment above?
> Would like to avoid using voltages for it, since then we are reverse
> engineering the table in datasheet to match the default reg value.

I think the following example solves both problems:

lvds_term = 200;
of_property_read_u32(..., &lvds_term);

if (lvds_term == 100)
	ctx->lvds_term_conf[channel] = OHM_100;
else if (lvds_term == 200)
	ctx->lvds_term_conf[channel] = OHM_200;
else
	return -EINVAL;

The same approach can be applied to lvds_vod_swing_conf, resulting in
removal of magic values.

> 
> > 
> > > +	int ret = 0;
> > > +	int ret_data;
> > > +	int ret_clock;
> > > +
> > > +	if (channel == CHANNEL_A)
> > > +		endpoint_reg = 2;
> > > +	else
> > > +		endpoint_reg = 3;
> > > +
> > > +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
> > > +	if (!of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term)) {
> > 
> > The code has been better before:
> > provide default for lvds_term, read the property (keeping the default in
> > case of an error), then use the lvds_term to set up lvds_term_conf, as
> > expected.
> 
> Ok, will revert back.
> 
> > 
> > > +		if (lvds_term == 100)
> > > +			lvds_term_conf = OHM_100;
> > > +		else
> > > +			lvds_term_conf = OHM_200;
> > > +	}
> > > +
> > > +	ctx->lvds_term_conf[channel] = lvds_term_conf;
> > > +
> > > +	ret_data = of_property_read_u32_array(endpoint,
> > > +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
> > > +			ARRAY_SIZE(lvds_vod_swing_data));
> > > +	if (ret_data != 0 && ret_data != -EINVAL) {
> > > +		ret = ret_data;
> > > +		goto exit;
> > > +	}
> > > +
> > > +	ret_clock = of_property_read_u32_array(endpoint,
> > > +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
> > > +			ARRAY_SIZE(lvds_vod_swing_clk));
> > > +	if (ret_clock != 0 && ret_clock != -EINVAL) {
> > > +		ret = ret_clock;
> > > +		goto exit;
> > > +	}
> > > +
> > > +	/* If any of the two properties is defined. */
> > > +	if (!ret_data || !ret_clock) {
> > > +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
> > > +			lvds_vod_swing_data, lvds_vod_swing_clk,
> > > +			lvds_term_conf);
> > > +		if (lvds_vod_swing_conf < 0) {
> > > +			ret = lvds_vod_swing_conf;
> > > +			goto exit;
> > > +		}
> > > +	}
> > > +
> > > +	ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
> > > +	ret = 0;
> > > +exit:
> > > +	of_node_put(endpoint);
> > > +	return ret;
> > > +}
> > > +
> > >   static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
> > >   {
> > >   	struct drm_bridge *panel_bridge;
> > >   	struct device *dev = ctx->dev;
> > > +	int ret;
> > > +
> > > +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
> > > +	if (ret < 0)
> > > +		return ret;
> > >   	ctx->lvds_dual_link = false;
> > >   	ctx->lvds_dual_link_even_odd_swap = false;
> > > -- 
> > > 2.34.1
> > > 
> > 

-- 
With best wishes
Dmitry


From ulf.hansson at linaro.org  Tue Dec 10 06:01:45 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 10 Dec 2024 15:01:45 +0100
Subject: [PATCH] cpuidle: psci: Activate GENPD_FLAG_ACTIVE_WAKEUP with OSI
In-Reply-To: <20241119141827.1.I6129b16ec6b558efc1707861db87e55bf7022f62@changeid>
References: <20241119141827.1.I6129b16ec6b558efc1707861db87e55bf7022f62@changeid>
Message-ID: <CAPDyKFoghwa+x0Dc8RfWWdDpP-mD4qUBZKpXjy4pK0mQwf6gGg@mail.gmail.com>

On Tue, 19 Nov 2024 at 14:21, Patrick Delaunay
<patrick.delaunay at foss.st.com> wrote:
>
> Set GENPD_FLAG_ACTIVE_WAKEUP flag for domain psci cpuidle when OSI
> is activated, then when a device is set as the wake-up source using
> device_set_wakeup_path, the PSCI power domain could be retained to allow
> so that the associated device can wake up the system.
>
> With this flag, for S2IDLE system-wide suspend, the wake-up path is
> managed in each device driver and is tested in the power framework:
> a PSCI domain is only turned off when GENPD_FLAG_ACTIVE_WAKEUP is enabled
> and the associated device is not in the wake-up path, so PSCI CPUIdle
> selects the lowest level in the PSCI topology according to the wake-up
> path.
>
> This patch is a preliminary step to support PSCI OSI on the STM32MP25
> platform with the D1 domain (power-domain-cluster) for the A35 cortex
> cluster and for the associated peripherals including EXTI1 which manages
> the wake-up interrupts for domain D1.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay at foss.st.com>

Makes perfect sense to me - so applied for next, thanks!

Kind regards
Uffe


> ---
>
>  drivers/cpuidle/cpuidle-psci-domain.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
> index 146f97068022..5fb5228f6bf1 100644
> --- a/drivers/cpuidle/cpuidle-psci-domain.c
> +++ b/drivers/cpuidle/cpuidle-psci-domain.c
> @@ -72,6 +72,7 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
>          */
>         if (use_osi) {
>                 pd->power_off = psci_pd_power_off;
> +               pd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
>                 if (IS_ENABLED(CONFIG_PREEMPT_RT))
>                         pd->flags |= GENPD_FLAG_RPM_ALWAYS_ON;
>         } else {
> --
> 2.25.1
>


From ulf.hansson at linaro.org  Tue Dec 10 06:02:04 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 10 Dec 2024 15:02:04 +0100
Subject: [PATCH v6 0/3] pmdomain: ti_sci: collect and send low-power mode constraints
In-Reply-To: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
References: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
Message-ID: <CAPDyKFo9N8M73Z6Ltsbnd-WR-jYAqBedAHndViSD7YaKKYgBsA@mail.gmail.com>

On Fri, 6 Dec 2024 at 23:13, Kevin Hilman <khilman at baylibre.com> wrote:
>
> The latest (10.x) version of the firmware for the PM co-processor (aka
> device manager, or DM) adds support for a "managed" mode, where the DM
> firmware will select the specific low power state which is entered
> when Linux requests a system-wide suspend.
>
> In this mode, the DM will always attempt the deepest low-power state
> available for the SoC.
>
> However, Linux (or OSes running on other cores) may want to constrain
> the DM for certain use cases.  For example, the deepest state may have
> a wakeup/resume latency that is too long for certain use cases.  Or,
> some wakeup-capable devices may potentially be powered off in deep
> low-power states, but if one of those devices is enabled as a wakeup
> source, it should not be powered off.
>
> These kinds of constraints are are already known in Linux by the use
> of existing APIs such as per-device PM QoS and device wakeup APIs, but
> now we need to communicate these constraints to the DM.
>
> For TI SoCs with TI SCI support, all DM-managed devices will be
> connected to a TI SCI PM domain.  So the goal of this series is to use
> the PM domain driver for TI SCI devices to collect constraints, and
> communicate them to the DM via the new TI SCI APIs.
>
> This is all managed by TI SCI PM domain code.  No new APIs are needed
> by Linux drivers.  Any device that is managed by TI SCI will be
> checked for QoS constraints or wakeup capability and the constraints
> will be collected and sent to the DM.
>
> This series depends on the support for the new TI SCI APIs (v10) and
> was also tested with this series to update 8250_omap serial support
> for AM62x[2].
>
> [1] https://lore.kernel.org/all/20240801195422.2296347-1-msp at baylibre.com
> [2] https://lore.kernel.org/all/20240807141227.1093006-1-msp at baylibre.com/
>
> Signed-off-by: Kevin Hilman <khilman at baylibre.com>
> ---
> Changes in v6:
> - fix build warning on arm32 when building with W=1 and CONFIG_PM_SLEEP=n
> - rebase onto v6.13-rc1
> - fix latency units: convert usecs (PM QoS) to msecs (TI SCI)
> - all dependencies are now merged in v6.13-rc1
> - Link to v5: https://lore.kernel.org/r/20241101-lpm-v6-10-constraints-pmdomain-v5-0-3011aa04622f at baylibre.com

v6 applied for next and by amending patch1 to deal with the sorting of
include files, thanks!

[...]

Kind regards
Uffe


From didi.debian at cknow.org  Tue Dec 10 06:08:29 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Tue, 10 Dec 2024 15:08:29 +0100
Subject: [PATCH 5/6] arm64: dts: rockchip: correct rk3328-roc regulator
 map
In-Reply-To: <CAMdYzYorTNiAybGhPu0u_YPj2J7qxCO72KBU1ozTde+2zK9Hxg@mail.gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-6-pgwipeout@gmail.com>
 <D67ZJ6MOM5TH.2WBYCCU20DDJO@cknow.org>
 <CAMdYzYorTNiAybGhPu0u_YPj2J7qxCO72KBU1ozTde+2zK9Hxg@mail.gmail.com>
Message-ID: <D682VQLD81Y8.1K8OD4ECAOSW3@cknow.org>

On Tue Dec 10, 2024 at 2:04 PM CET, Peter Geis wrote:
> On Tue, Dec 10, 2024 at 6:31?AM Diederik de Haas <didi.debian at cknow.org> wrote:
> > On Tue Dec 10, 2024 at 2:30 AM CET, Peter Geis wrote:
> > > voltages to vcc_host1_5v, and standardize the order of regulator
> > > properties among the fixed regulators.
> >
> > Big fan of standardization :-) ...
> >
> > >
> > > Fixes: 2171f4fdac06 ("arm64: dts: rockchip: add roc-rk3328-cc board")
> > > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > > ---
> > >
> > >  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 23 +++++++++++++-------
> > >  1 file changed, 15 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > > index f782c8220dd3..6984387ff8b3 100644
> > > --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > > +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > > @@ -24,22 +24,23 @@ gmac_clkin: external-gmac-clock {
> > >               #clock-cells = <0>;
> > >       };
> > >
> > > -     dc_12v: regulator-dc-12v {
> > > +     /* fed from passive usb input connector */
> > > +     dc_5v: regulator-dc-5v {
> > >               compatible = "regulator-fixed";
> > > -             regulator-name = "dc_12v";
> > > +             regulator-name = "dc_5v";
> > >               regulator-always-on;
> > >               regulator-boot-on;
> > > -             regulator-min-microvolt = <12000000>;
> > > -             regulator-max-microvolt = <12000000>;
> > > +             regulator-min-microvolt = <5000000>;
> > > +             regulator-max-microvolt = <5000000>;
> > >       };
> > >
> > >       vcc_sd: regulator-sdmmc {
> > >               compatible = "regulator-fixed";
> > > +             regulator-name = "vcc_sd";
> > >               gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
> > >               pinctrl-names = "default";
> > >               pinctrl-0 = <&sdmmc0m1_pin>;
> > >               regulator-boot-on;
> > > -             regulator-name = "vcc_sd";
> > >               regulator-min-microvolt = <3300000>;
> > >               regulator-max-microvolt = <3300000>;
> > >               vin-supply = <&vcc_io>;
> >
> > ... but why not put regulator-name as the first of the regulator
> > properties as is done in the rk3328-rock64.dts ...
> >
> > > @@ -50,22 +51,25 @@ vcc_sdio: regulator-sdmmcio {
> > >               states = <1800000 0x1>, <3300000 0x0>;
> > >               regulator-name = "vcc_sdio";
> > >               regulator-type = "voltage";
> > > +             regulator-always-on;
> > >               regulator-min-microvolt = <1800000>;
> > >               regulator-max-microvolt = <3300000>;
> > > -             regulator-always-on;
> > >               vin-supply = <&vcc_sys>;
> > >       };
> > >
> > >       vcc_host1_5v: vcc_otg_5v: regulator-vcc-host1-5v {
> > >               compatible = "regulator-fixed";
> > > +             regulator-name = "vcc_host1_5v";
> > >               enable-active-high;
> > >               pinctrl-names = "default";
> > >               pinctrl-0 = <&usb20_host_drv>;
> > > -             regulator-name = "vcc_host1_5v";
> > >               regulator-always-on;
> > > +             regulator-min-microvolt = <5000000>;
> > > +             regulator-max-microvolt = <5000000>;
> > >               vin-supply = <&vcc_sys>;
> > >       };
> >
> > ... and was the case here?
>
> That's fair, thank you. I like the alphabetical approach, I'll go that
> way when I split this out.

FWIW, I'm fine when regulator-name and regulator-type would be put on
the top of the regulator-* properties, also because that's currently
the case for the rk3328-rock64.dts.
And a strict alphabetical order would look weird anyway as then
-max-microvolt should be ordered above -min-microvolt.

Cheers,
  Diederik
-------------- 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/20241210/dbfc7250/attachment.sig>

From will at kernel.org  Tue Dec 10 06:07:40 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 14:07:40 +0000
Subject: [PATCH v2 0/1] KVM: arm64: Map GPU memory with no struct pages
In-Reply-To: <20241118131958.4609-1-ankita@nvidia.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
Message-ID: <20241210140739.GC15607@willie-the-truck>

On Mon, Nov 18, 2024 at 01:19:57PM +0000, ankita at nvidia.com wrote:
> The changes are heavily influenced by the insightful discussions between
> Catalin Marinas and Jason Gunthorpe [1] on v1. Many thanks for their
> valuable suggestions.
> 
> Link: https://lore.kernel.org/lkml/20230907181459.18145-2-ankita at nvidia.com [1]

That's a different series, no? It got merged at v9:

https://lore.kernel.org/all/20240224150546.368-1-ankita at nvidia.com/

Will


From Frank.li at nxp.com  Tue Dec 10 06:09:26 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 10 Dec 2024 09:09:26 -0500
Subject: [PATCH 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241210103646.7gblp7mzxbna5gas@pengutronix.de>
References: <20241209-imx91tmu-v1-0-7859c5387f31@nxp.com>
 <20241209-imx91tmu-v1-2-7859c5387f31@nxp.com>
 <20241210103646.7gblp7mzxbna5gas@pengutronix.de>
Message-ID: <Z1hLlm75iGMogltc@lizhi-Precision-Tower-5810>

On Tue, Dec 10, 2024 at 11:36:46AM +0100, Marco Felsch wrote:
> Hi,
>
> On 24-12-09, Frank Li wrote:
> > From: Pengfei Li <pengfei.li_1 at nxp.com>
> >
> > Introduce support for the i.MX91 thermal monitoring unit, which features a
> > single sensor for the CPU. The register layout differs from other chips,
> > necessitating the creation of a dedicated file for this.
> >
> > Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> >  drivers/thermal/Kconfig         |  10 ++
> >  drivers/thermal/Makefile        |   1 +
> >  drivers/thermal/imx91_thermal.c | 281 ++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 292 insertions(+)
> >
> > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > index d3f9686e26e71..da403ed86aeb1 100644
> > --- a/drivers/thermal/Kconfig
> > +++ b/drivers/thermal/Kconfig
> > @@ -296,6 +296,16 @@ config IMX8MM_THERMAL
> >  	  cpufreq is used as the cooling device to throttle CPUs when the passive
> >  	  trip is crossed.
> >
> > +config IMX91_THERMAL
> > +	tristate "Temperature sensor driver for NXP i.MX91 SoC"
> > +	depends on ARCH_MXC || COMPILE_TEST
> > +	depends on OF
> > +	help
> > +	  Support for Temperature sensor found on NXP i.MX91 SoC.
> > +	  It supports one critical trip point and one passive trip point. The
> > +	  cpufreq is used as the cooling device to throttle CPUs when the passive
> > +	  trip is crossed.
> > +
> >  config K3_THERMAL
> >  	tristate "Texas Instruments K3 thermal support"
> >  	depends on ARCH_K3 || COMPILE_TEST
> > diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> > index 9abf43a74f2bb..08da241e6a598 100644
> > --- a/drivers/thermal/Makefile
> > +++ b/drivers/thermal/Makefile
> > @@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
> >  obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
> >  obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
> >  obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
> > +obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
> >  obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
> >  obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
> >  obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
> > diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
> > new file mode 100644
> > index 0000000000000..19c4dafe9c7a9
> > --- /dev/null
> > +++ b/drivers/thermal/imx91_thermal.c
> > @@ -0,0 +1,281 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2024 NXP.
> > + */
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/clk.h>
> > +#include <linux/err.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/nvmem-consumer.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/thermal.h>
> > +
> > +#define CTRL0			0x0
> > +
> > +#define STAT0			0x10
> > +#define STAT0_DRDY0_IF_MASK	BIT(16)
> > +
> > +#define DATA0			0x20
> > +#define DATA_INT_MASK		GENMASK(14, 7)
> > +#define DATA_FRAC_MASK		GENMASK(6, 0)
> > +
> > +#define THR_CTRL01		0x30
> > +#define THR_CTRL23		0x40
> > +
> > +#define CTRL1			0x200
> > +#define CTRL1_SET		0x204
> > +#define CTRL1_CLR		0x208
> > +#define CTRL1_EN		BIT(31)
> > +#define CTRL1_START		BIT(30)
> > +#define CTRL1_STOP		BIT(29)
> > +#define CTRL1_RES_MASK		GENMASK(19, 18)
> > +#define CTRL1_MEAS_MODE_MASK	GENMASK(25, 24)
> > +
> > +#define PERIOD_CTRL		0x270
> > +#define MEAS_FREQ_MASK		GENMASK(23, 0)
> > +
> > +#define REF_DIV			0x280
> > +#define DIV_EN			BIT(31)
> > +#define DIV_MASK		GENMASK(23, 16)
> > +
> > +#define PUD_ST_CTRL		0x2B0
> > +#define PUDL_MASK		GENMASK(23, 16)
> > +
> > +#define TRIM1			0x2E0
> > +#define TRIM2			0x2F0
> > +
> > +#define TMU_TEMP_LOW_LIMIT	-40000
> > +#define TMU_TEMP_HIGH_LIMIT	125000
> > +
> > +#define DEFAULT_TRIM1_CONFIG 0xB561BC2DU
> > +#define DEFAULT_TRIM2_CONFIG 0x65D4U
>
> please align the defines and use lower-case for the hex values.
>
> > +struct tmu_sensor {
> > +	struct imx91_tmu *priv;
> > +	struct thermal_zone_device *tzd;
> > +};
>
> This can be part of imx91_tmu right?
>
> > +struct imx91_tmu {
> > +	void __iomem *base;
> > +	struct clk *clk;
> > +	struct device *dev;
> > +	struct tmu_sensor sensors;
> > +};
> > +
> > +static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
> > +{
> > +	if (start)
> > +		writel_relaxed(CTRL1_START, tmu->base + CTRL1_SET);
> > +	else
> > +		writel_relaxed(CTRL1_STOP, tmu->base + CTRL1_SET);
>
> Nit:
> 	unsigned int val = start ? CTRL1_START : CTRL1_STOP;
>
> 	writel_relaxed(val, tmu->base + CTRL1_SET);
>
> Aside the nit, why do you use *_relaxed() accessors in you whole code?
> Is the order not strictly required?
>
> > +}
> > +
> > +static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
> > +{
> > +	if (enable)
> > +		writel_relaxed(CTRL1_EN, tmu->base + CTRL1_SET);
> > +	else
> > +		writel_relaxed(CTRL1_EN, tmu->base + CTRL1_CLR);
>
> Same here:
>
> 	unsigned int reg = enable ? CTRL1_SET : CTRL1_CLR;
>
> 	writel_relaxed(CTRL1_EN, tmu->base + reg);
> > +}
> > +
> > +static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
> > +{
> > +	struct tmu_sensor *sensor = thermal_zone_device_priv(tz);
> > +	struct imx91_tmu *tmu = sensor->priv;
>
> With tmu_sensor merged into imx91_tmu you don't need this reverse
> pointer logic.
>
> > +	int val;
> > +	int ret;
> > +
> > +	ret = readl_relaxed_poll_timeout(tmu->base + STAT0, val,
> > +					 val & STAT0_DRDY0_IF_MASK, 1000,
> > +					 40000);
> > +	if (ret)
> > +		return -EAGAIN;
> > +
> > +	val = readl_relaxed(tmu->base + DATA0) & 0xffffU;
> 						   ^
> 				Please use a MASK define for it, also no
> 				need to use the U suffix.
>
> Also according the TRM 58.3.4 this doesn't seem right. According the TRM
> this is a s16 (two's-complement) value. You won't get negative values if
> store it within a int.
>
> > +	*temp = val * 1000L / 64L;
> 			  ^     ^
> You don't need to specify the type here explicit since all params would
> be converted to int and no overflow happens.
>
> > +	if (*temp < TMU_TEMP_LOW_LIMIT || *temp > TMU_TEMP_HIGH_LIMIT)
> > +		return -EAGAIN;
> > +
> > +	return 0;
> > +}
> > +
> > +static struct thermal_zone_device_ops tmu_tz_ops = {
> > +	.get_temp = imx91_tmu_get_temp,
> > +};
> > +
> > +static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
> > +{
> > +	struct device *dev = tmu->dev;
> > +	int ret;
> > +	u32 trim1, trim2;
>
> Please use the reverse christmas tree style.
>
> > +	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (trim1 == 0 || trim2 == 0)
> > +		return -EINVAL;
> > +
> > +	writel_relaxed(trim1, tmu->base + TRIM1);
> > +	writel_relaxed(trim2, tmu->base + TRIM2);
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx91_tmu_probe(struct platform_device *pdev)
> > +{
> > +	struct imx91_tmu *tmu;
> > +	unsigned long rate;
> > +	u32 div;
> > +	int ret;
> > +	int i = 0;
>
> Same here.
>
> > +	tmu = devm_kzalloc(&pdev->dev, sizeof(struct imx91_tmu), GFP_KERNEL);
> > +	if (!tmu)
> > +		return -ENOMEM;
> > +
> > +	tmu->dev = &pdev->dev;
> > +
> > +	tmu->base = devm_platform_ioremap_resource(pdev, 0);
> > +	if (IS_ERR(tmu->base))
> > +		return PTR_ERR(tmu->base);
> > +
> > +	tmu->clk = devm_clk_get_prepared(&pdev->dev, NULL);
> > +	if (IS_ERR(tmu->clk))
> > +		return dev_err_probe(&pdev->dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
> > +
> > +	tmu->sensors.priv = tmu;
>
> As said, no need for the sensors container.
>
> > +	tmu->sensors.tzd = devm_thermal_of_zone_register(&pdev->dev, i, &tmu->sensors, &tmu_tz_ops);
> > +	if (IS_ERR(tmu->sensors.tzd))
> > +		return dev_err_probe(&pdev->dev, PTR_ERR(tmu->sensors.tzd),
> > +				     "failed to register thermal zone sensor\n");
> > +
> > +	platform_set_drvdata(pdev, tmu);
> > +
> > +	/* disable the monitor during initialization */
> > +	imx91_tmu_enable(tmu, false);
> > +	imx91_tmu_start(tmu, false);
>
> Make use of pm_runtime?

thermal is always on after probe. continue measure tempature. So pm_runtime
is not suitable for this case.

>
> > +	ret = imx91_init_from_nvmem_cells(tmu);
> > +	if (ret) {
> > +		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
> > +		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
> > +	}
> > +
> > +	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
> > +	rate = clk_get_rate(tmu->clk);
> > +	div = (rate / 4000000) - 1;
>
> Would be nice to validate the div value before passing to the HW and if
> the target rate of 4MHz can't be reached by the div you you should
> return -EINVAL.
>
> > +
> > +	/* Set divider value and enable divider */
> > +	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
> > +
> > +	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
> > +	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
> > +
> > +	/*
> > +	 * Set resolution mode
> > +	 * 00b - Conversion time = 0.59325 ms
> > +	 * 01b - Conversion time = 1.10525 ms
> > +	 * 10b - Conversion time = 2.12925 ms
> > +	 * 11b - Conversion time = 4.17725 ms
> > +	 */
> > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
> > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);
> > +
> > +	/*
> > +	 * Set measure mode
> > +	 * 00b - Single oneshot measurement
> > +	 * 01b - Continuous measurement
> > +	 * 10b - Periodic oneshot measurement
> > +	 */
>
> For the resolution it's fine to have the values directly coded without a
> define, but here we can definitly use a define and drop the comment.
>
> > +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, 0x3), tmu->base + CTRL1_CLR);
> > +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, 0x1), tmu->base + CTRL1_SET);
>
> Why do we set it to periodic mode instead of the single-shot? At the
> moment the device doesn't have IRQ support, and so there is no need to
> run the measurements in background.

It is "continous measurement".  first clean MODE_MASK, then then 01.

_CLR means clean bits according to mask
_SET means set bits according to mask.

Frank

>
> > +
> > +	/*
> > +	 * Set Periodic Measurement Frequency to 25Hz:
> > +	 * tMEAS_FREQ = tCONV_CLK * PERIOD_CTRL[MEAS_FREQ]. ->
> > +	 * PERIOD_CTRL(MEAS_FREQ) = (1000 / 25) / (1000 / 4000000);
> > +	 * Where tMEAS_FREQ = Measurement period and tCONV_CLK = 1/fCONV_CLK.
> > +	 * This field should have value greater than count corresponds
> > +	 * to time greater than summation of conversion time, power up
> > +	 * delay, and six times of conversion clock time.
> > +	 * tMEAS_FREQ > (tCONV + tPUD + 6 * tCONV_CLK).
> > +	 * tCONV is conversion time determined by CTRL1[RESOLUTION].
> > +	 */
> > +	writel_relaxed(FIELD_PREP(MEAS_FREQ_MASK, 0x27100), tmu->base + PERIOD_CTRL);
>
> With the single-shot measurements we could remove this part and..
>
> > +
> > +	/* enable the monitor */
> > +	imx91_tmu_enable(tmu, true);
> > +	imx91_tmu_start(tmu, true);
>
> this part as well.
>
> Regards,
>   Marco
>
> > +
> > +	return 0;
> > +}
> > +
> > +static void imx91_tmu_remove(struct platform_device *pdev)
> > +{
> > +	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
> > +
> > +	/* disable tmu */
> > +	imx91_tmu_start(tmu, false);
> > +	imx91_tmu_enable(tmu, false);
> > +}
> > +
> > +static int __maybe_unused imx91_tmu_suspend(struct device *dev)
> > +{
> > +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> > +
> > +	/* disable tmu */
> > +	imx91_tmu_start(tmu, false);
> > +	imx91_tmu_enable(tmu, false);
> > +
> > +	clk_disable_unprepare(tmu->clk);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused imx91_tmu_resume(struct device *dev)
> > +{
> > +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> > +	int ret;
> > +
> > +	ret = clk_prepare_enable(tmu->clk);
> > +	if (ret)
> > +		return ret;
> > +
> > +	imx91_tmu_enable(tmu, true);
> > +	imx91_tmu_start(tmu, true);
> > +
> > +	return 0;
> > +}
> > +
> > +static SIMPLE_DEV_PM_OPS(imx91_tmu_pm_ops,
> > +			 imx91_tmu_suspend, imx91_tmu_resume);
> > +
> > +static const struct of_device_id imx91_tmu_table[] = {
> > +	{ .compatible = "fsl,imx91-tmu", },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(of, imx91_tmu_table);
> > +
> > +static struct platform_driver imx91_tmu = {
> > +	.driver = {
> > +		.name	= "i.MX91_thermal",
> > +		.pm	= pm_ptr(&imx91_tmu_pm_ops),
> > +		.of_match_table = imx91_tmu_table,
> > +	},
> > +	.probe = imx91_tmu_probe,
> > +	.remove = imx91_tmu_remove,
> > +};
> > +module_platform_driver(imx91_tmu);
> > +
> > +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> > +MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
> > +MODULE_LICENSE("GPL");
> >
> > --
> > 2.34.1
> >
> >
> >


From will at kernel.org  Tue Dec 10 06:13:35 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 14:13:35 +0000
Subject: [PATCH v2 1/1] KVM: arm64: Allow cacheable stage 2 mapping using
 VMA flags
In-Reply-To: <20241118131958.4609-2-ankita@nvidia.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241118131958.4609-2-ankita@nvidia.com>
Message-ID: <20241210141334.GD15607@willie-the-truck>

On Mon, Nov 18, 2024 at 01:19:58PM +0000, ankita at nvidia.com wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> Currently KVM determines if a VMA is pointing at IO memory by checking
> pfn_is_map_memory(). However, the MM already gives us a way to tell what
> kind of memory it is by inspecting the VMA.
> 
> This patch solves the problems where it is possible for the kernel to
> have VMAs pointing at cachable memory without causing
> pfn_is_map_memory() to be true, eg DAX memremap cases and CXL/pre-CXL
> devices. This memory is now properly marked as cachable in KVM.
> 
> The pfn_is_map_memory() is restrictive and allows only for the memory
> that is added to the kernel to be marked as cacheable. In most cases
> the code needs to know if there is a struct page, or if the memory is
> in the kernel map and pfn_valid() is an appropriate API for this.
> Extend the umbrella with pfn_valid() to include memory with no struct
> pages for consideration to be mapped cacheable in stage 2. A !pfn_valid()
> implies that the memory is unsafe to be mapped as cacheable.
> 
> Moreover take account of the mapping type in the VMA to make a decision
> on the mapping. The VMA's pgprot is tested to determine the memory type
> with the following mapping:
>  pgprot_noncached    MT_DEVICE_nGnRnE   device (or Normal_NC)
>  pgprot_writecombine MT_NORMAL_NC       device (or Normal_NC)
>  pgprot_device       MT_DEVICE_nGnRE    device (or Normal_NC)
>  pgprot_tagged       MT_NORMAL_TAGGED   RAM / Normal
>  -                   MT_NORMAL          RAM / Normal
> 
> Also take care of the following two cases that prevents the memory to
> be safely mapped as cacheable:
> 1. The VMA pgprot have VM_IO set alongwith MT_NORMAL or
>    MT_NORMAL_TAGGED. Although unexpected and wrong, presence of such
>    configuration cannot be ruled out.
> 2. Configurations where VM_MTE_ALLOWED is not set and KVM_CAP_ARM_MTE
>    is enabled. Otherwise a malicious guest can enable MTE at stage 1
>    without the hypervisor being able to tell. This could cause external
>    aborts.
> 
> Introduce a new variable noncacheable to represent whether the memory
> should not be mapped as cacheable. The noncacheable as false implies
> the memory is safe to be mapped cacheable. Use this to handle the
> aforementioned potentially unsafe cases for cacheable mapping.
> 
> Note when FWB is not enabled, the kernel expects to trivially do
> cache management by flushing the memory by linearly converting a
> kvm_pte to phys_addr to a KVA, see kvm_flush_dcache_to_poc(). This is
> only possibile for struct page backed memory. Do not allow non-struct
> page memory to be cachable without FWB.
> 
> The device memory such as on the Grace Hopper systems is interchangeable
> with DDR memory and retains its properties. Allow executable faults
> on the memory determined as Normal cacheable.

Sorry, but a change this subtle to the arch code is going to need a _much_
better explanation than the rambling text above.

I also suspect that you're trying to do too many things in one patch.
In particular, the changes to execute permission handling absolutely
need to be discussed as a single patch in the series.

Please can you split this up in to a set of changes with useful commit
messages so that we can review them?

Jason knows how to do this so you could ask him for help if you're stuck.
Otherwise, there are plenty of examples of well-written commit messages
on the mailing list and in the git history.

Thanks,

Will


From linux at armlinux.org.uk  Tue Dec 10 06:17:52 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:17:52 +0000
Subject: [PATCH net-next 0/9] net: dsa: cleanup EEE (part 1)
Message-ID: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>

Hi,

First part of DSA EEE cleanups.

Patch 1 removes a useless test that is always false. dp->pl will always
be set for user ports, so !dp->pl in the EEE methods will always be
false.

Patch 2 adds support for a new DSA support_eee() method, which tells
DSA whether the DSA driver supports EEE, and thus whether the ethtool
set_eee() and get_eee() methods should return -EOPNOTSUPP.

Patch 3 adds a trivial implementation for this new method which
indicates that EEE is supported.

Patches 4..8 adds implementations for .supports_eee() to all drivers
that support EEE in some form.

Patch 9 switches the core DSA code to require a .supports_eee()
implementation if DSA is supported. Any DSA driver that doesn't
implement this method after this patch will not support the ethtool
EEE methods.

Part 2 will remove the (now) useless .get_mac_eee() DSA operation.

 drivers/net/dsa/b53/b53_common.c       | 13 +++++++------
 drivers/net/dsa/b53/b53_priv.h         |  1 +
 drivers/net/dsa/bcm_sf2.c              |  1 +
 drivers/net/dsa/microchip/ksz_common.c | 20 +++++---------------
 drivers/net/dsa/mt7530.c               |  1 +
 drivers/net/dsa/mv88e6xxx/chip.c       |  1 +
 drivers/net/dsa/qca/qca8k-8xxx.c       |  1 +
 include/net/dsa.h                      |  2 ++
 net/dsa/port.c                         | 16 ++++++++++++++++
 net/dsa/user.c                         | 12 ++++++++++--
 10 files changed, 45 insertions(+), 23 deletions(-)

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


From jgg at nvidia.com  Tue Dec 10 06:18:06 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 10 Dec 2024 10:18:06 -0400
Subject: [PATCH v2 0/1] KVM: arm64: Map GPU memory with no struct pages
In-Reply-To: <20241210140739.GC15607@willie-the-truck>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241210140739.GC15607@willie-the-truck>
Message-ID: <20241210141806.GI2347147@nvidia.com>

On Tue, Dec 10, 2024 at 02:07:40PM +0000, Will Deacon wrote:
> On Mon, Nov 18, 2024 at 01:19:57PM +0000, ankita at nvidia.com wrote:
> > The changes are heavily influenced by the insightful discussions between
> > Catalin Marinas and Jason Gunthorpe [1] on v1. Many thanks for their
> > valuable suggestions.
> > 
> > Link: https://lore.kernel.org/lkml/20230907181459.18145-2-ankita at nvidia.com [1]
> 
> That's a different series, no? It got merged at v9:

I was confused by this too. v1 of that series included this patch, as
that series went along it became focused only on enabling WC
(Normal-NC) in a VM for device MMIO and this patch for device cachable
memory was dropped off.

There are two related things:
 1) Device MMIO memory should be able to be Normal-NC in a VM. Already
    merged
 2) Device Cachable memory (ie CXL and pre-CXL coherently attached
    memory) should be Normal Cachable in a VM, even if it doesn't have
    struct page/etc. (this patch)

IIRC this part was dropped off because of the MTE complexity that
Catalin raised.

Jason


From rmk+kernel at armlinux.org.uk  Tue Dec 10 06:18:11 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:18:11 +0000
Subject: [PATCH net-next 1/9] net: dsa: remove check for dp->pl in EEE methods
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <E1tL13z-006cZ7-BZ@rmk-PC.armlinux.org.uk>

When user ports are initialised, a phylink instance is always created,
and so dp->pl will always be non-NULL. The EEE methods are only used
for user ports, so checking for dp->pl to be NULL makes no sense. No
other phylink-calling method implements similar checks in DSA. Remove
this unnecessary check.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 net/dsa/user.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/dsa/user.c b/net/dsa/user.c
index 06c30a9e29ff..0640247b8f0a 100644
--- a/net/dsa/user.c
+++ b/net/dsa/user.c
@@ -1229,7 +1229,7 @@ static int dsa_user_set_eee(struct net_device *dev, struct ethtool_keee *e)
 	int ret;
 
 	/* Port's PHY and MAC both need to be EEE capable */
-	if (!dev->phydev || !dp->pl)
+	if (!dev->phydev)
 		return -ENODEV;
 
 	if (!ds->ops->set_mac_eee)
@@ -1249,7 +1249,7 @@ static int dsa_user_get_eee(struct net_device *dev, struct ethtool_keee *e)
 	int ret;
 
 	/* Port's PHY and MAC both need to be EEE capable */
-	if (!dev->phydev || !dp->pl)
+	if (!dev->phydev)
 		return -ENODEV;
 
 	if (!ds->ops->get_mac_eee)
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Dec 10 06:18:16 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:18:16 +0000
Subject: [PATCH net-next 2/9] net: dsa: add hook to determine whether EEE is
 supported
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <E1tL144-006cZD-El@rmk-PC.armlinux.org.uk>

Add a hook to determine whether the switch supports EEE. This will
return false if the switch does not, or true if it does. If the
method is not implemented, we assume (currently) that the switch
supports EEE.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 include/net/dsa.h | 1 +
 net/dsa/user.c    | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 72ae65e7246a..aaa75bbaa0ea 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -988,6 +988,7 @@ struct dsa_switch_ops {
 	/*
 	 * Port's MAC EEE settings
 	 */
+	bool	(*support_eee)(struct dsa_switch *ds, int port);
 	int	(*set_mac_eee)(struct dsa_switch *ds, int port,
 			       struct ethtool_keee *e);
 	int	(*get_mac_eee)(struct dsa_switch *ds, int port,
diff --git a/net/dsa/user.c b/net/dsa/user.c
index 0640247b8f0a..b54f61605a57 100644
--- a/net/dsa/user.c
+++ b/net/dsa/user.c
@@ -1228,6 +1228,10 @@ static int dsa_user_set_eee(struct net_device *dev, struct ethtool_keee *e)
 	struct dsa_switch *ds = dp->ds;
 	int ret;
 
+	/* Check whether the switch supports EEE */
+	if (ds->ops->support_eee && !ds->ops->support_eee(ds, dp->index))
+		return -EOPNOTSUPP;
+
 	/* Port's PHY and MAC both need to be EEE capable */
 	if (!dev->phydev)
 		return -ENODEV;
@@ -1248,6 +1252,10 @@ static int dsa_user_get_eee(struct net_device *dev, struct ethtool_keee *e)
 	struct dsa_switch *ds = dp->ds;
 	int ret;
 
+	/* Check whether the switch supports EEE */
+	if (ds->ops->support_eee && !ds->ops->support_eee(ds, dp->index))
+		return -EOPNOTSUPP;
+
 	/* Port's PHY and MAC both need to be EEE capable */
 	if (!dev->phydev)
 		return -ENODEV;
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Dec 10 06:18:21 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:18:21 +0000
Subject: [PATCH net-next 3/9] net: dsa: provide implementation of
 .support_eee()
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <E1tL149-006cZJ-JJ@rmk-PC.armlinux.org.uk>

Provide a trivial implementation for the .support_eee() method which
switch drivers can use to simply indicate that they support EEE on
all their user ports.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 include/net/dsa.h |  1 +
 net/dsa/port.c    | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index aaa75bbaa0ea..4aeedb296d67 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -1384,5 +1384,6 @@ static inline bool dsa_user_dev_check(const struct net_device *dev)
 
 netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev);
 void dsa_port_phylink_mac_change(struct dsa_switch *ds, int port, bool up);
+bool dsa_supports_eee(struct dsa_switch *ds, int port);
 
 #endif
diff --git a/net/dsa/port.c b/net/dsa/port.c
index ee0aaec4c8e0..5c9d1798e830 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1575,6 +1575,22 @@ void dsa_port_set_tag_protocol(struct dsa_port *cpu_dp,
 	cpu_dp->tag_ops = tag_ops;
 }
 
+/* dsa_supports_eee - indicate that EEE is supported
+ * @ds: pointer to &struct dsa_switch
+ * @port: port index
+ *
+ * A default implementation for the .support_eee() DSA operations member,
+ * which drivers can use to indicate that they support EEE on all of their
+ * user ports.
+ *
+ * Returns: true
+ */
+bool dsa_supports_eee(struct dsa_switch *ds, int port)
+{
+	return true;
+}
+EXPORT_SYMBOL_GPL(dsa_supports_eee);
+
 static void dsa_port_phylink_mac_config(struct phylink_config *config,
 					unsigned int mode,
 					const struct phylink_link_state *state)
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Dec 10 06:18:26 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:18:26 +0000
Subject: [PATCH net-next 4/9] net: dsa: b53/bcm_sf2: implement .support_eee()
 method
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <E1tL14E-006cZU-Nc@rmk-PC.armlinux.org.uk>

Implement the .support_eee() method to indicate that EEE is not
supported by two switch variants, rather than making these checks in
the .set_mac_eee() and .get_mac_eee() methods.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/dsa/b53/b53_common.c | 13 +++++++------
 drivers/net/dsa/b53/b53_priv.h   |  1 +
 drivers/net/dsa/bcm_sf2.c        |  1 +
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 285785c942b0..0561b60f668f 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -2224,13 +2224,16 @@ int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy)
 }
 EXPORT_SYMBOL(b53_eee_init);
 
-int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
+bool b53_support_eee(struct dsa_switch *ds, int port)
 {
 	struct b53_device *dev = ds->priv;
 
-	if (is5325(dev) || is5365(dev))
-		return -EOPNOTSUPP;
+	return !is5325(dev) && !is5365(dev);
+}
+EXPORT_SYMBOL(b53_support_eee);
 
+int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
+{
 	return 0;
 }
 EXPORT_SYMBOL(b53_get_mac_eee);
@@ -2240,9 +2243,6 @@ int b53_set_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;
 
-	if (is5325(dev) || is5365(dev))
-		return -EOPNOTSUPP;
-
 	p->eee_enabled = e->eee_enabled;
 	b53_eee_enable_set(ds, port, e->eee_enabled);
 
@@ -2298,6 +2298,7 @@ static const struct dsa_switch_ops b53_switch_ops = {
 	.phylink_get_caps	= b53_phylink_get_caps,
 	.port_enable		= b53_enable_port,
 	.port_disable		= b53_disable_port,
+	.support_eee		= b53_support_eee,
 	.get_mac_eee		= b53_get_mac_eee,
 	.set_mac_eee		= b53_set_mac_eee,
 	.port_bridge_join	= b53_br_join,
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index 05141176daf5..99e5cfc98ae8 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -384,6 +384,7 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
 void b53_disable_port(struct dsa_switch *ds, int port);
 void b53_brcm_hdr_setup(struct dsa_switch *ds, int port);
 int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy);
+bool b53_support_eee(struct dsa_switch *ds, int port);
 int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e);
 int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e);
 
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 43bde1f583ff..a53fb6191e6b 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -1232,6 +1232,7 @@ static const struct dsa_switch_ops bcm_sf2_ops = {
 	.set_wol		= bcm_sf2_sw_set_wol,
 	.port_enable		= bcm_sf2_port_setup,
 	.port_disable		= bcm_sf2_port_disable,
+	.support_eee		= b53_support_eee,
 	.get_mac_eee		= b53_get_mac_eee,
 	.set_mac_eee		= b53_set_mac_eee,
 	.port_bridge_join	= b53_br_join,
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Dec 10 06:18:31 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:18:31 +0000
Subject: [PATCH net-next 5/9] net: dsa: mt753x: implement .support_eee()
 method
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <E1tL14J-006cZa-Rh@rmk-PC.armlinux.org.uk>

Implement the .support_eee() method by using the generic helper as all
user ports support EEE.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/dsa/mt7530.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 086b8b3d5b40..9605febd3573 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3238,6 +3238,7 @@ const struct dsa_switch_ops mt7530_switch_ops = {
 	.port_mirror_add	= mt753x_port_mirror_add,
 	.port_mirror_del	= mt753x_port_mirror_del,
 	.phylink_get_caps	= mt753x_phylink_get_caps,
+	.support_eee		= dsa_supports_eee,
 	.get_mac_eee		= mt753x_get_mac_eee,
 	.set_mac_eee		= mt753x_set_mac_eee,
 	.conduit_state_change	= mt753x_conduit_state_change,
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Dec 10 06:18:36 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:18:36 +0000
Subject: [PATCH net-next 6/9] net: dsa: qca8k: implement .support_eee() method
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <E1tL14O-006cZg-VM@rmk-PC.armlinux.org.uk>

Implement the .support_eee() method by using the generic helper as all
user ports support EEE.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/dsa/qca/qca8k-8xxx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
index 59b4a7240b58..ec74e3c2b0e9 100644
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -2016,6 +2016,7 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
 	.get_ethtool_stats	= qca8k_get_ethtool_stats,
 	.get_sset_count		= qca8k_get_sset_count,
 	.set_ageing_time	= qca8k_set_ageing_time,
+	.support_eee		= dsa_supports_eee,
 	.get_mac_eee		= qca8k_get_mac_eee,
 	.set_mac_eee		= qca8k_set_mac_eee,
 	.port_enable		= qca8k_port_enable,
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Dec 10 06:18:42 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:18:42 +0000
Subject: [PATCH net-next 7/9] net: dsa: mv88e6xxx: implement .support_eee()
 method
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <E1tL14U-006cZm-2K@rmk-PC.armlinux.org.uk>

Implement the .support_eee() method by using the generic helper as all
user ports support EEE.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 3a792f79270d..1d78974ea2a3 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -7074,6 +7074,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
 	.get_sset_count		= mv88e6xxx_get_sset_count,
 	.port_max_mtu		= mv88e6xxx_get_max_mtu,
 	.port_change_mtu	= mv88e6xxx_change_mtu,
+	.support_eee		= dsa_supports_eee,
 	.get_mac_eee		= mv88e6xxx_get_mac_eee,
 	.set_mac_eee		= mv88e6xxx_set_mac_eee,
 	.get_eeprom_len		= mv88e6xxx_get_eeprom_len,
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Dec 10 06:18:47 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:18:47 +0000
Subject: [PATCH net-next 8/9] net: dsa: ksz: implement .support_eee() method
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <E1tL14Z-006cZs-6o@rmk-PC.armlinux.org.uk>

Implement the .support_eee() method by reusing the ksz_validate_eee()
method as a template, renaming the function, changing the return type
and values, and removing it from the ksz_set_mac_eee() and
ksz_get_mac_eee() methods.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/dsa/microchip/ksz_common.c | 20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index f5822c57be32..94f9aa983ff6 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3454,12 +3454,12 @@ static int ksz_max_mtu(struct dsa_switch *ds, int port)
 	return -EOPNOTSUPP;
 }
 
-static int ksz_validate_eee(struct dsa_switch *ds, int port)
+static bool ksz_support_eee(struct dsa_switch *ds, int port)
 {
 	struct ksz_device *dev = ds->priv;
 
 	if (!dev->info->internal_phy[port])
-		return -EOPNOTSUPP;
+		return false;
 
 	switch (dev->chip_id) {
 	case KSZ8563_CHIP_ID:
@@ -3471,21 +3471,15 @@ static int ksz_validate_eee(struct dsa_switch *ds, int port)
 	case KSZ9896_CHIP_ID:
 	case KSZ9897_CHIP_ID:
 	case LAN9646_CHIP_ID:
-		return 0;
+		return true;
 	}
 
-	return -EOPNOTSUPP;
+	return false;
 }
 
 static int ksz_get_mac_eee(struct dsa_switch *ds, int port,
 			   struct ethtool_keee *e)
 {
-	int ret;
-
-	ret = ksz_validate_eee(ds, port);
-	if (ret)
-		return ret;
-
 	/* There is no documented control of Tx LPI configuration. */
 	e->tx_lpi_enabled = true;
 
@@ -3501,11 +3495,6 @@ static int ksz_set_mac_eee(struct dsa_switch *ds, int port,
 			   struct ethtool_keee *e)
 {
 	struct ksz_device *dev = ds->priv;
-	int ret;
-
-	ret = ksz_validate_eee(ds, port);
-	if (ret)
-		return ret;
 
 	if (!e->tx_lpi_enabled) {
 		dev_err(dev->dev, "Disabling EEE Tx LPI is not supported\n");
@@ -4651,6 +4640,7 @@ static const struct dsa_switch_ops ksz_switch_ops = {
 	.cls_flower_add		= ksz_cls_flower_add,
 	.cls_flower_del		= ksz_cls_flower_del,
 	.port_setup_tc		= ksz_setup_tc,
+	.support_eee		= ksz_support_eee,
 	.get_mac_eee		= ksz_get_mac_eee,
 	.set_mac_eee		= ksz_set_mac_eee,
 	.port_get_default_prio	= ksz_port_get_default_prio,
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Dec 10 06:18:52 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 10 Dec 2024 14:18:52 +0000
Subject: [PATCH net-next 9/9] net: dsa: require .support_eee() method to be
 implemented
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <E1tL14e-006cZy-AT@rmk-PC.armlinux.org.uk>

Now that we have updated all drivers, switch DSA to require an
implementation of the .support_eee() method for EEE to be usable,
rather than defaulting to being permissive when not implemented.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 net/dsa/user.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/dsa/user.c b/net/dsa/user.c
index b54f61605a57..4239083c18bf 100644
--- a/net/dsa/user.c
+++ b/net/dsa/user.c
@@ -1229,7 +1229,7 @@ static int dsa_user_set_eee(struct net_device *dev, struct ethtool_keee *e)
 	int ret;
 
 	/* Check whether the switch supports EEE */
-	if (ds->ops->support_eee && !ds->ops->support_eee(ds, dp->index))
+	if (!ds->ops->support_eee || !ds->ops->support_eee(ds, dp->index))
 		return -EOPNOTSUPP;
 
 	/* Port's PHY and MAC both need to be EEE capable */
@@ -1253,7 +1253,7 @@ static int dsa_user_get_eee(struct net_device *dev, struct ethtool_keee *e)
 	int ret;
 
 	/* Check whether the switch supports EEE */
-	if (ds->ops->support_eee && !ds->ops->support_eee(ds, dp->index))
+	if (!ds->ops->support_eee || !ds->ops->support_eee(ds, dp->index))
 		return -EOPNOTSUPP;
 
 	/* Port's PHY and MAC both need to be EEE capable */
-- 
2.30.2



From yangyicong at huawei.com  Tue Dec 10 06:15:17 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:17 +0800
Subject: [PATCH v5 02/10] drivers/perf: hisi: Don't update the associated_cpus on CPU offline
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-3-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Event will be scheduled on CPU of hisi_pmu::on_cpu which is selected
from the intersection of hisi_pmu::associated_cpus and online CPUs.
So the associated_cpus don't need to be maintained with online CPUs.
This will save one update operation if one associated CPU is offlined.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 749d33625980..8c404f8b3f39 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -492,9 +492,6 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 						     node);
 	unsigned int target;
 
-	if (!cpumask_test_and_clear_cpu(cpu, &hisi_pmu->associated_cpus))
-		return 0;
-
 	/* Nothing to do if this CPU doesn't own the PMU */
 	if (hisi_pmu->on_cpu != cpu)
 		return 0;
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:18 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:18 +0800
Subject: [PATCH v5 03/10] drivers/perf: hisi: Migrate to one online CPU if no associated one online
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-4-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

If the selected CPU hisi_pmu::on_cpu goes offline, driver will select
a new online CPU from hisi_pmu::associated_cpus, or if no online CPU
found the PMU context won't be migrated. However for uncore PMUs the
associated CPUs are just a peference and it also works to schedule
the events on any online CPUs. So add a fallback to choose an online
CPU if no associated CPUs found.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 8c404f8b3f39..c775e4722dac 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -499,9 +499,16 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 	/* Give up ownership of the PMU */
 	hisi_pmu->on_cpu = -1;
 
-	/* Choose a new CPU to migrate ownership of the PMU to */
+	/*
+	 * Migrate ownership of the PMU to a new CPU chosen from PMU's online
+	 * associated CPUs if possible, if no associated CPU online then
+	 * migrate to one online CPU.
+	 */
 	target = cpumask_any_and_but(&hisi_pmu->associated_cpus,
 				     cpu_online_mask, cpu);
+	if (target >= nr_cpu_ids)
+		target = cpumask_any_but(cpu_online_mask, cpu);
+
 	if (target >= nr_cpu_ids)
 		return 0;
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:21 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:21 +0800
Subject: [PATCH v5 06/10] drivers/perf: hisi: Add a common function to retrieve topology from firmware
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-7-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Currently each type of uncore PMU driver uses almost the same routine
and the same firmware interface (or properties) to retrieve the topology
information, then reset the unused IDs to -1. Extract the common parts
to the framework in hisi_uncore_pmu_init_topology().

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  | 10 +++----
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 10 +++----
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  | 10 +++----
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  |  8 ++---
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   | 11 +++----
 drivers/perf/hisilicon/hisi_uncore_pmu.c      | 30 +++++++++++++++++++
 drivers/perf/hisilicon/hisi_uncore_pmu.h      |  1 +
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 11 +++----
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   | 12 ++++----
 9 files changed, 60 insertions(+), 43 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
index 1a5c3fc26493..e3a619ea6831 100644
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
@@ -180,20 +180,18 @@ MODULE_DEVICE_TABLE(acpi, hisi_cpa_pmu_acpi_match);
 static int hisi_cpa_pmu_init_data(struct platform_device *pdev,
 				  struct hisi_pmu *cpa_pmu)
 {
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &cpa_pmu->topo.sicl_id)) {
+	hisi_uncore_pmu_init_topology(cpa_pmu, &pdev->dev);
+
+	if (cpa_pmu->topo.sicl_id < 0) {
 		dev_err(&pdev->dev, "Can not read sicl-id\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &cpa_pmu->topo.index_id)) {
+	if (cpa_pmu->topo.index_id < 0) {
 		dev_err(&pdev->dev, "Cannot read idx-id\n");
 		return -EINVAL;
 	}
 
-	cpa_pmu->topo.ccl_id = -1;
-	cpa_pmu->topo.sccl_id = -1;
 	cpa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(cpa_pmu->base))
 		return PTR_ERR(cpa_pmu->base);
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index 01aab39c0c66..1d12384fef8f 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -297,6 +297,8 @@ MODULE_DEVICE_TABLE(acpi, hisi_ddrc_pmu_acpi_match);
 static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 				   struct hisi_pmu *ddrc_pmu)
 {
+	hisi_uncore_pmu_init_topology(ddrc_pmu, &pdev->dev);
+
 	/*
 	 * Use the SCCL_ID and DDRC channel ID to identify the
 	 * DDRC PMU, while SCCL_ID is in MPIDR[aff2].
@@ -307,13 +309,10 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &ddrc_pmu->topo.sccl_id)) {
+	if (ddrc_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read ddrc sccl-id!\n");
 		return -EINVAL;
 	}
-	/* DDRC PMUs only share the same SCCL */
-	ddrc_pmu->topo.ccl_id = -1;
 
 	ddrc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ddrc_pmu->base)) {
@@ -323,8 +322,7 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 
 	ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
 	if (ddrc_pmu->identifier >= HISI_PMU_V2) {
-		if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-					     &ddrc_pmu->topo.sub_id)) {
+		if (ddrc_pmu->topo.sub_id < 0) {
 			dev_err(&pdev->dev, "Can not read sub-id!\n");
 			return -EINVAL;
 		}
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index c96fcc919e3d..a2b9629a6081 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -295,12 +295,13 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 	unsigned long long id;
 	acpi_status status;
 
+	hisi_uncore_pmu_init_topology(hha_pmu, &pdev->dev);
+
 	/*
 	 * Use SCCL_ID and UID to identify the HHA PMU, while
 	 * SCCL_ID is in MPIDR[aff2].
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &hha_pmu->topo.sccl_id)) {
+	if (hha_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read hha sccl-id!\n");
 		return -EINVAL;
 	}
@@ -309,8 +310,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 	 * Early versions of BIOS support _UID by mistake, so we support
 	 * both "hisilicon, idx-id" as preference, if available.
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &hha_pmu->topo.index_id)) {
+	if (hha_pmu->topo.index_id < 0) {
 		status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
 					       "_UID", NULL, &id);
 		if (ACPI_FAILURE(status)) {
@@ -320,8 +320,6 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 
 		hha_pmu->topo.index_id = id;
 	}
-	/* HHA PMUs only share the same SCCL */
-	hha_pmu->topo.ccl_id = -1;
 
 	hha_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hha_pmu->base)) {
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index d9773edf542a..5ba49e902535 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -355,18 +355,18 @@ MODULE_DEVICE_TABLE(acpi, hisi_l3c_pmu_acpi_match);
 static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
 				  struct hisi_pmu *l3c_pmu)
 {
+	hisi_uncore_pmu_init_topology(l3c_pmu, &pdev->dev);
+
 	/*
 	 * Use the SCCL_ID and CCL_ID to identify the L3C PMU, while
 	 * SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &l3c_pmu->topo.sccl_id)) {
+	if (l3c_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read l3c sccl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-				     &l3c_pmu->topo.ccl_id)) {
+	if (l3c_pmu->topo.ccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read l3c ccl-id!\n");
 		return -EINVAL;
 	}
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
index 648de8355b3f..48c5357666d0 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
@@ -269,25 +269,22 @@ static void hisi_pa_pmu_clear_int_status(struct hisi_pmu *pa_pmu, int idx)
 static int hisi_pa_pmu_init_data(struct platform_device *pdev,
 				   struct hisi_pmu *pa_pmu)
 {
+	hisi_uncore_pmu_init_topology(pa_pmu, &pdev->dev);
+
 	/*
 	 * As PA PMU is in a SICL, use the SICL_ID and the index ID
 	 * to identify the PA PMU.
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &pa_pmu->topo.sicl_id)) {
+	if (pa_pmu->topo.sicl_id < 0) {
 		dev_err(&pdev->dev, "Cannot read sicl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &pa_pmu->topo.index_id)) {
+	if (pa_pmu->topo.index_id < 0) {
 		dev_err(&pdev->dev, "Cannot read idx-id!\n");
 		return -EINVAL;
 	}
 
-	pa_pmu->topo.ccl_id = -1;
-	pa_pmu->topo.sccl_id = -1;
-
 	pa_pmu->dev_info = device_get_match_data(&pdev->dev);
 	if (!pa_pmu->dev_info)
 		return -ENODEV;
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index b01852a710ad..5f581327a71f 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -14,6 +14,7 @@
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/property.h>
 
 #include <asm/cputype.h>
 #include <asm/local64.h>
@@ -530,6 +531,35 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 }
 EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_offline_cpu, "HISI_PMU");
 
+/*
+ * Retrieve the topology information from the firmware for the hisi_pmu device.
+ * The topology ID will be -1 if we cannot initialize it, it may either due to
+ * the PMU doesn't locate on this certain topology or the firmware needs to be
+ * fixed.
+ */
+void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct device *dev)
+{
+	struct hisi_pmu_topology *topo = &hisi_pmu->topo;
+
+	topo->sccl_id = -1;
+	topo->ccl_id = -1;
+	topo->index_id = -1;
+	topo->sub_id = -1;
+
+	if (device_property_read_u32(dev, "hisilicon,scl-id", &topo->sccl_id))
+		dev_dbg(dev, "no scl-id present\n");
+
+	if (device_property_read_u32(dev, "hisilicon,ccl-id", &topo->ccl_id))
+		dev_dbg(dev, "no ccl-id present\n");
+
+	if (device_property_read_u32(dev, "hisilicon,idx-id", &topo->index_id))
+		dev_dbg(dev, "no idx-id present\n");
+
+	if (device_property_read_u32(dev, "hisilicon,sub-id", &topo->sub_id))
+		dev_dbg(dev, "no sub-id present\n");
+}
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_init_topology, "HISI_PMU");
+
 void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 {
 	struct pmu *pmu = &hisi_pmu->pmu;
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
index f162a1b6c6d1..53b1331b8565 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
@@ -160,6 +160,7 @@ ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
 					     char *page);
 int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
 			     struct platform_device *pdev);
+void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct device *dev);
 
 void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module);
 #endif /* __HISI_UNCORE_PMU_H__ */
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
index 32cb23a7cf5d..ba6af0d3cb22 100644
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
@@ -288,25 +288,22 @@ MODULE_DEVICE_TABLE(acpi, hisi_sllc_pmu_acpi_match);
 static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
 				   struct hisi_pmu *sllc_pmu)
 {
+	hisi_uncore_pmu_init_topology(sllc_pmu, &pdev->dev);
+
 	/*
 	 * Use the SCCL_ID and the index ID to identify the SLLC PMU,
 	 * while SCCL_ID is from MPIDR_EL1 by CPU.
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &sllc_pmu->topo.sccl_id)) {
+	if (sllc_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Cannot read sccl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &sllc_pmu->topo.index_id)) {
+	if (sllc_pmu->topo.index_id < 0) {
 		dev_err(&pdev->dev, "Cannot read idx-id!\n");
 		return -EINVAL;
 	}
 
-	/* SLLC PMUs only share the same SCCL */
-	sllc_pmu->topo.ccl_id = -1;
-
 	sllc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(sllc_pmu->base)) {
 		dev_err(&pdev->dev, "ioremap failed for sllc_pmu resource.\n");
diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
index bc51d45c8ef9..ba35c9476340 100644
--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
@@ -11,7 +11,6 @@
 #include <linux/irq.h>
 #include <linux/list.h>
 #include <linux/mod_devicetable.h>
-#include <linux/property.h>
 
 #include "hisi_uncore_pmu.h"
 
@@ -366,25 +365,24 @@ static void hisi_uc_pmu_clear_int_status(struct hisi_pmu *uc_pmu, int idx)
 static int hisi_uc_pmu_init_data(struct platform_device *pdev,
 				 struct hisi_pmu *uc_pmu)
 {
+	hisi_uncore_pmu_init_topology(uc_pmu, &pdev->dev);
+
 	/*
 	 * Use SCCL (Super CPU Cluster) ID and CCL (CPU Cluster) ID to
 	 * identify the topology information of UC PMU devices in the chip.
 	 * They have some CCLs per SCCL and then 4 UC PMU per CCL.
 	 */
-	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &uc_pmu->topo.sccl_id)) {
+	if (uc_pmu->topo.sccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read uc sccl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-				     &uc_pmu->topo.ccl_id)) {
+	if (uc_pmu->topo.ccl_id < 0) {
 		dev_err(&pdev->dev, "Can not read uc ccl-id!\n");
 		return -EINVAL;
 	}
 
-	if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-				     &uc_pmu->topo.sub_id)) {
+	if (uc_pmu->topo.sub_id < 0) {
 		dev_err(&pdev->dev, "Can not read sub-id!\n");
 		return -EINVAL;
 	}
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:23 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:23 +0800
Subject: [PATCH v5 08/10] drivers/perf: hisi: Export associated CPUs of each PMU through sysfs
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-9-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Although the event of the uncore PMU can only be opened on a single
CPU, some PMU does have the affinity on a range of CPUs. For example
the L3C PMU is associated to the CPUs sharing the L3T it monitors.
Users may infer this affinity by the PMU name which may have SCCL ID
and CCL ID encoded (for L3C etc), but it's not that straightforward.
So export this information by adding an "associated_cpus" sysfs
attribute then user can get this directly.

Reviewed-by: Jonathan Cameron <Joanthan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 Documentation/admin-guide/perf/hisi-pmu.rst |  5 ++++-
 drivers/perf/hisilicon/hisi_uncore_pmu.c    | 10 ++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
index 5cc248d18c63..48992a0b8e94 100644
--- a/Documentation/admin-guide/perf/hisi-pmu.rst
+++ b/Documentation/admin-guide/perf/hisi-pmu.rst
@@ -35,7 +35,10 @@ e.g. hisi_sccl1_hha0/rx_operations is RX_OPERATIONS event of HHA index #0 in
 SCCL ID #1.
 
 The driver also provides a "cpumask" sysfs attribute, which shows the CPU core
-ID used to count the uncore PMU event.
+ID used to count the uncore PMU event. An "associated_cpus" sysfs attribute is
+also provided to show the CPUs associated with this PMU. The "cpumask" indicates
+the CPUs to open the events, usually as a hint for userspaces tools like perf.
+It only contains one associated CPU from the "associated_cpus".
 
 Example usage of perf::
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 075aaa8eaeaa..83bdc9c31367 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -51,8 +51,18 @@ EXPORT_SYMBOL_NS_GPL(hisi_cpumask_sysfs_show, "HISI_PMU");
 
 static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
 
+static ssize_t hisi_associated_cpus_sysfs_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
+
+	return cpumap_print_to_pagebuf(true, buf, &hisi_pmu->associated_cpus);
+}
+static DEVICE_ATTR(associated_cpus, 0444, hisi_associated_cpus_sysfs_show, NULL);
+
 static struct attribute *hisi_pmu_cpumask_attrs[] = {
 	&dev_attr_cpumask.attr,
+	&dev_attr_associated_cpus.attr,
 	NULL
 };
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:16 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:16 +0800
Subject: [PATCH v5 01/10] drivers/perf: hisi: Define a symbol namespace for HiSilicon Uncore PMUs
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-2-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

The HiSilicon Uncore PMU framework implements some common functions
and exported them to the drivers. Use a specific HISI_PMU namespace
for the exported symbols to avoid pollute the generic ones.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  |  1 +
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c |  1 +
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  |  1 +
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  |  1 +
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   |  1 +
 drivers/perf/hisilicon/hisi_uncore_pmu.c      | 36 +++++++++----------
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c |  1 +
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   |  1 +
 8 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
index 3f3fb1de11f5..052509213c51 100644
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
@@ -389,6 +389,7 @@ static void __exit hisi_cpa_pmu_module_exit(void)
 }
 module_exit(hisi_cpa_pmu_module_exit);
 
+MODULE_IMPORT_NS("HISI_PMU");
 MODULE_DESCRIPTION("HiSilicon SoC CPA PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Qi Liu <liuqi115 at huawei.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index a6ebf2ec99d3..049aa4b47e57 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -579,6 +579,7 @@ static void __exit hisi_ddrc_pmu_module_exit(void)
 }
 module_exit(hisi_ddrc_pmu_module_exit);
 
+MODULE_IMPORT_NS("HISI_PMU");
 MODULE_DESCRIPTION("HiSilicon SoC DDRC uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Shaokun Zhang <zhangshaokun at hisilicon.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index 32624872596f..e26e50b3278d 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -581,6 +581,7 @@ static void __exit hisi_hha_pmu_module_exit(void)
 }
 module_exit(hisi_hha_pmu_module_exit);
 
+MODULE_IMPORT_NS("HISI_PMU");
 MODULE_DESCRIPTION("HiSilicon SoC HHA uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Shaokun Zhang <zhangshaokun at hisilicon.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index c235b46ce873..aa3d51dd5d21 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -615,6 +615,7 @@ static void __exit hisi_l3c_pmu_module_exit(void)
 }
 module_exit(hisi_l3c_pmu_module_exit);
 
+MODULE_IMPORT_NS("HISI_PMU");
 MODULE_DESCRIPTION("HiSilicon SoC L3C uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Anurup M <anurup.m at huawei.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
index c0f5d7c73e06..29dd77943233 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
@@ -569,6 +569,7 @@ static void __exit hisi_pa_pmu_module_exit(void)
 }
 module_exit(hisi_pa_pmu_module_exit);
 
+MODULE_IMPORT_NS("HISI_PMU");
 MODULE_DESCRIPTION("HiSilicon Protocol Adapter uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Shaokun Zhang <zhangshaokun at hisilicon.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 918cdc31de57..749d33625980 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -34,7 +34,7 @@ ssize_t hisi_event_sysfs_show(struct device *dev,
 
 	return sysfs_emit(page, "config=0x%lx\n", (unsigned long)eattr->var);
 }
-EXPORT_SYMBOL_GPL(hisi_event_sysfs_show);
+EXPORT_SYMBOL_NS_GPL(hisi_event_sysfs_show, "HISI_PMU");
 
 /*
  * sysfs cpumask attributes. For uncore PMU, we only have a single CPU to show
@@ -46,7 +46,7 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
 
 	return sysfs_emit(buf, "%d\n", hisi_pmu->on_cpu);
 }
-EXPORT_SYMBOL_GPL(hisi_cpumask_sysfs_show);
+EXPORT_SYMBOL_NS_GPL(hisi_cpumask_sysfs_show, "HISI_PMU");
 
 static bool hisi_validate_event_group(struct perf_event *event)
 {
@@ -96,7 +96,7 @@ int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
 
 	return idx;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_get_event_idx);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_get_event_idx, "HISI_PMU");
 
 ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
 					     struct device_attribute *attr,
@@ -106,7 +106,7 @@ ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
 
 	return sysfs_emit(page, "0x%08x\n", hisi_pmu->identifier);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_identifier_attr_show);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_identifier_attr_show, "HISI_PMU");
 
 static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
 {
@@ -165,7 +165,7 @@ int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_init_irq);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_init_irq, "HISI_PMU");
 
 int hisi_uncore_pmu_event_init(struct perf_event *event)
 {
@@ -219,7 +219,7 @@ int hisi_uncore_pmu_event_init(struct perf_event *event)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_init);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_event_init, "HISI_PMU");
 
 /*
  * Set the counter to count the event that we're interested in,
@@ -273,7 +273,7 @@ void hisi_uncore_pmu_set_event_period(struct perf_event *event)
 	/* Write start value to the hardware event counter */
 	hisi_pmu->ops->write_counter(hisi_pmu, hwc, val);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_set_event_period);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_set_event_period, "HISI_PMU");
 
 void hisi_uncore_pmu_event_update(struct perf_event *event)
 {
@@ -294,7 +294,7 @@ void hisi_uncore_pmu_event_update(struct perf_event *event)
 		HISI_MAX_PERIOD(hisi_pmu->counter_bits);
 	local64_add(delta, &event->count);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_update);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_event_update, "HISI_PMU");
 
 void hisi_uncore_pmu_start(struct perf_event *event, int flags)
 {
@@ -317,7 +317,7 @@ void hisi_uncore_pmu_start(struct perf_event *event, int flags)
 	hisi_uncore_pmu_enable_event(event);
 	perf_event_update_userpage(event);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_start);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_start, "HISI_PMU");
 
 void hisi_uncore_pmu_stop(struct perf_event *event, int flags)
 {
@@ -334,7 +334,7 @@ void hisi_uncore_pmu_stop(struct perf_event *event, int flags)
 	hisi_uncore_pmu_event_update(event);
 	hwc->state |= PERF_HES_UPTODATE;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_stop);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_stop, "HISI_PMU");
 
 int hisi_uncore_pmu_add(struct perf_event *event, int flags)
 {
@@ -357,7 +357,7 @@ int hisi_uncore_pmu_add(struct perf_event *event, int flags)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_add);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_add, "HISI_PMU");
 
 void hisi_uncore_pmu_del(struct perf_event *event, int flags)
 {
@@ -369,14 +369,14 @@ void hisi_uncore_pmu_del(struct perf_event *event, int flags)
 	perf_event_update_userpage(event);
 	hisi_pmu->pmu_events.hw_events[hwc->idx] = NULL;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_del);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_del, "HISI_PMU");
 
 void hisi_uncore_pmu_read(struct perf_event *event)
 {
 	/* Read hardware counter and update the perf counter statistics */
 	hisi_uncore_pmu_event_update(event);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_read);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_read, "HISI_PMU");
 
 void hisi_uncore_pmu_enable(struct pmu *pmu)
 {
@@ -389,7 +389,7 @@ void hisi_uncore_pmu_enable(struct pmu *pmu)
 
 	hisi_pmu->ops->start_counters(hisi_pmu);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_enable);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_enable, "HISI_PMU");
 
 void hisi_uncore_pmu_disable(struct pmu *pmu)
 {
@@ -397,7 +397,7 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
 
 	hisi_pmu->ops->stop_counters(hisi_pmu);
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_disable);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_disable, "HISI_PMU");
 
 
 /*
@@ -484,7 +484,7 @@ int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_online_cpu);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_online_cpu, "HISI_PMU");
 
 int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 {
@@ -515,7 +515,7 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_offline_cpu);
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_offline_cpu, "HISI_PMU");
 
 void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 {
@@ -535,7 +535,7 @@ void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 	pmu->attr_groups        = hisi_pmu->pmu_events.attr_groups;
 	pmu->capabilities       = PERF_PMU_CAP_NO_EXCLUDE;
 }
-EXPORT_SYMBOL_GPL(hisi_pmu_init);
+EXPORT_SYMBOL_NS_GPL(hisi_pmu_init, "HISI_PMU");
 
 MODULE_DESCRIPTION("HiSilicon SoC uncore Performance Monitor driver framework");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
index c5f4764ee888..d39aee31ca42 100644
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
@@ -507,6 +507,7 @@ static void __exit hisi_sllc_pmu_module_exit(void)
 }
 module_exit(hisi_sllc_pmu_module_exit);
 
+MODULE_IMPORT_NS("HISI_PMU");
 MODULE_DESCRIPTION("HiSilicon SLLC uncore PMU driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Shaokun Zhang <zhangshaokun at hisilicon.com>");
diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
index 481dcc9e8fbf..2233d288ccf5 100644
--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
@@ -613,6 +613,7 @@ static void __exit hisi_uc_pmu_module_exit(void)
 }
 module_exit(hisi_uc_pmu_module_exit);
 
+MODULE_IMPORT_NS("HISI_PMU");
 MODULE_DESCRIPTION("HiSilicon SoC UC uncore PMU driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Junhao He <hejunhao3 at huawei.com>");
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:25 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:25 +0800
Subject: [PATCH v5 10/10] drivers/perf: hisi: Delete redundant blank line of DDRC PMU
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-11-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

Do not add blank line at the end of a code block defined by braces.

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index fb309b8d5301..7e490f8868f2 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -550,7 +550,6 @@ static void __exit hisi_ddrc_pmu_module_exit(void)
 {
 	platform_driver_unregister(&hisi_ddrc_pmu_driver);
 	cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE);
-
 }
 module_exit(hisi_ddrc_pmu_module_exit);
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:15 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:15 +0800
Subject: [PATCH v5 00/10] Refactor the common parts to the HiSilicon Uncore PMU core and cleanups
Message-ID: <20241210141525.37788-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

This series mainly contains the refactor of the HiSilicon Uncore PMU by
extracting the common parts from each drivers into the core:
- the retrieving of the PMU topology ID
- the common sysfs attributes like cpumask and identifier

In order to achieve this, we need to do below preparation:
- refactor the detection of associated CPUs for PMUs locates on a SICL
- maintain the topology information in a dedicated data structure
- provides a generic implementation of cpumask/identifier attributes

Besides also include below changes/cleanups in this patchset
- add one new sysfs attributes for better describing the topology information
  of the associated CPUs of the PMU.
- define a symbol namespace for HiSilicon Uncore PMUs to avoid pollute the
  common ones
- two minor nonfunctional cleanups of DDRC PMU

Change since v4:
- rebase on 6.13-rc2 to meet the change of EXPORT_SYMBOL_NS_GPL/MODULE_IMPORT_NS
Link: https://lore.kernel.org/linux-arm-kernel/20241210113949.GE14735 at willie-the-truck/T/#me0ffafc1259a39604103dee13a5607be8a96ce72

Change since v3:
- Split the associated_cpus refactor patches according to the functions, hope
  will be easier to review
- Drop the use of cpu_online_mask out of cpuhp
Link: https://lore.kernel.org/linux-arm-kernel/20241026072424.29887-1-yangyicong at huawei.com/

Change since v2:
- remove one redundant newline and add Jonathan's tag for Patch 1 and 5
Link: https://lore.kernel.org/linux-arm-kernel/20241022145305.47056-1-yangyicong at huawei.com/

Changes since v1:
Address Jonathan's comments and add tags for some patches
- Provide a generic cpumask/identifier attribute group
- refine the comments/commit as suggested
Link: https://lore.kernel.org/linux-arm-kernel/20241018095745.57057-1-yangyicong at huawei.com/

Junhao He (2):
  drivers/perf: hisi: Fix incorrect variable name "hha_pmu" in DDRC PMU
    driver
  drivers/perf: hisi: Delete redundant blank line of DDRC PMU

Yicong Yang (8):
  drivers/perf: hisi: Define a symbol namespace for HiSilicon Uncore
    PMUs
  drivers/perf: hisi: Don't update the associated_cpus on CPU offline
  drivers/perf: hisi: Migrate to one online CPU if no associated one
    online
  drivers/perf: hisi: Refactor the detection of associated CPUs
  drivers/perf: hisi: Extract topology information to a separate
    structure
  drivers/perf: hisi: Add a common function to retrieve topology from
    firmware
  drivers/perf: hisi: Provide a generic implementation of
    cpumask/identifier
  drivers/perf: hisi: Export associated CPUs of each PMU through sysfs

 Documentation/admin-guide/perf/hisi-pmu.rst   |   5 +-
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  |  42 +----
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c |  61 ++-----
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  |  48 ++----
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  |  44 ++---
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   |  53 ++----
 drivers/perf/hisilicon/hisi_uncore_pmu.c      | 160 +++++++++++++-----
 drivers/perf/hisilicon/hisi_uncore_pmu.h      |  49 +++++-
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c |  43 +----
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   |  45 ++---
 10 files changed, 248 insertions(+), 302 deletions(-)

-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:19 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:19 +0800
Subject: [PATCH v5 04/10] drivers/perf: hisi: Refactor the detection of associated CPUs
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-5-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

There are two type of PMUs supported currently:
1) PMUs locate on SCCL (Super CPU Cluster [1]), associated with certain
   CCL (CPU cluster [1])(e.g. L3C PMU) or not (e.g. DDRC PMU)
2) PMUs locate on the SICL (Super IO Cluster [1]), which has no
   association with certain CPU topology (e.g. CPA PMU)

Currently the associated CPUs of the PMU is detected in the cpuhp online
callback as below:
- for type 1) the CPUs match PMU's sccl_id and ccl_id
- for type 2) PMU's sccl_id is -1 and all online CPUs will be associated

Since uncore PMUs are not bound to certain CPU context and event could be
counting started by any online CPU, the associated CPUs are just a
preference. Below disadvantages are observed in current implementation:
- the PMU cannot be used if its associated CPUs are offline
- SICL PMUs are associated to all the online CPUs implicitly without
  the consideration of locality

So refactor the way we detect the associated CPUs in below aspects:
- add a clear definition of hisi_pmu::associated_cpus
- initialize hisi_pmu::on_cpu based on locality if no associated CPU
  found, otherwise update it from associated CPUs
- drop the detection with a sccl_id of -1 for SICL PMUs

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/perf/hisi-pmu.rst?h=v6.12-rc1

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 22 +++++++++++++++-------
 drivers/perf/hisilicon/hisi_uncore_pmu.h |  6 +++++-
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index c775e4722dac..e0f5fefcfee9 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -446,10 +446,6 @@ static bool hisi_pmu_cpu_is_associated_pmu(struct hisi_pmu *hisi_pmu)
 {
 	int sccl_id, ccl_id;
 
-	/* If SCCL_ID is -1, the PMU is in a SICL and has no CPU affinity */
-	if (hisi_pmu->sccl_id == -1)
-		return true;
-
 	if (hisi_pmu->ccl_id == -1) {
 		/* If CCL_ID is -1, the PMU only shares the same SCCL */
 		hisi_read_sccl_and_ccl_id(&sccl_id, NULL);
@@ -467,13 +463,25 @@ int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
 	struct hisi_pmu *hisi_pmu = hlist_entry_safe(node, struct hisi_pmu,
 						     node);
 
-	if (!hisi_pmu_cpu_is_associated_pmu(hisi_pmu))
+	/*
+	 * If the CPU is not associated to PMU, initialize the hisi_pmu->on_cpu
+	 * based on the locality if it hasn't been initialized yet. For PMUs
+	 * do have associated CPUs, it'll be updated later.
+	 */
+	if (!hisi_pmu_cpu_is_associated_pmu(hisi_pmu)) {
+		if (hisi_pmu->on_cpu != -1)
+			return 0;
+
+		hisi_pmu->on_cpu = cpumask_local_spread(0, dev_to_node(hisi_pmu->dev));
+		WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(cpu)));
 		return 0;
+	}
 
 	cpumask_set_cpu(cpu, &hisi_pmu->associated_cpus);
 
-	/* If another CPU is already managing this PMU, simply return. */
-	if (hisi_pmu->on_cpu != -1)
+	/* If another associated CPU is already managing this PMU, simply return. */
+	if (hisi_pmu->on_cpu != -1 &&
+	    cpumask_test_cpu(hisi_pmu->on_cpu, &hisi_pmu->associated_cpus))
 		return 0;
 
 	/* Use this CPU in cpumask for event counting */
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
index 25b2d43b72bf..bd48338ce937 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
@@ -87,7 +87,11 @@ struct hisi_pmu {
 	const struct hisi_uncore_ops *ops;
 	const struct hisi_pmu_dev_info *dev_info;
 	struct hisi_pmu_hwevents pmu_events;
-	/* associated_cpus: All CPUs associated with the PMU */
+	/*
+	 * CPUs associated to the PMU and are preferred to use for counting.
+	 * Could be empty if PMU has no association (e.g. PMU on SICL), in
+	 * which case any online CPU will be used.
+	 */
 	cpumask_t associated_cpus;
 	/* CPU used for counting */
 	int on_cpu;
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:20 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:20 +0800
Subject: [PATCH v5 05/10] drivers/perf: hisi: Extract topology information to a separate structure
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-6-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

HiSilicon Uncore PMUs are identified by the IDs of the topology element
on which the PMUs are located. Add a new separate struct hisi_pmu_toplogy
to encapsulate this information. Add additional documentation on the
meaning of each ID.

- make sccl_id and sicl_id into a union since they're exclusive. It can
  also be accessed by scl_id if the SICL/SCCL distinction is not
  relevant
- make index_id and sub_id signed so -1 may be used to indicate the PMU
  doesn't have this topology element or it could not be retrieved.

This patch should have no functional changes.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  | 12 +++---
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 18 ++++-----
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  | 12 +++---
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  |  8 ++--
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   | 14 +++----
 drivers/perf/hisilicon/hisi_uncore_pmu.c      |  7 ++--
 drivers/perf/hisilicon/hisi_uncore_pmu.h      | 38 +++++++++++++++----
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 10 ++---
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   | 11 +++---
 9 files changed, 78 insertions(+), 52 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
index 052509213c51..1a5c3fc26493 100644
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
@@ -181,19 +181,19 @@ static int hisi_cpa_pmu_init_data(struct platform_device *pdev,
 				  struct hisi_pmu *cpa_pmu)
 {
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &cpa_pmu->sicl_id)) {
+				     &cpa_pmu->topo.sicl_id)) {
 		dev_err(&pdev->dev, "Can not read sicl-id\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &cpa_pmu->index_id)) {
+				     &cpa_pmu->topo.index_id)) {
 		dev_err(&pdev->dev, "Cannot read idx-id\n");
 		return -EINVAL;
 	}
 
-	cpa_pmu->ccl_id = -1;
-	cpa_pmu->sccl_id = -1;
+	cpa_pmu->topo.ccl_id = -1;
+	cpa_pmu->topo.sccl_id = -1;
 	cpa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(cpa_pmu->base))
 		return PTR_ERR(cpa_pmu->base);
@@ -311,8 +311,8 @@ static int hisi_cpa_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%d_cpa%u",
-			      cpa_pmu->sicl_id, cpa_pmu->index_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%d_cpa%d",
+			      cpa_pmu->topo.sicl_id, cpa_pmu->topo.index_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index 049aa4b47e57..01aab39c0c66 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -302,18 +302,18 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 	 * DDRC PMU, while SCCL_ID is in MPIDR[aff2].
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,ch-id",
-				     &ddrc_pmu->index_id)) {
+				     &ddrc_pmu->topo.index_id)) {
 		dev_err(&pdev->dev, "Can not read ddrc channel-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &ddrc_pmu->sccl_id)) {
+				     &ddrc_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Can not read ddrc sccl-id!\n");
 		return -EINVAL;
 	}
 	/* DDRC PMUs only share the same SCCL */
-	ddrc_pmu->ccl_id = -1;
+	ddrc_pmu->topo.ccl_id = -1;
 
 	ddrc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ddrc_pmu->base)) {
@@ -324,7 +324,7 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 	ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
 	if (ddrc_pmu->identifier >= HISI_PMU_V2) {
 		if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-					     &ddrc_pmu->sub_id)) {
+					     &ddrc_pmu->topo.sub_id)) {
 			dev_err(&pdev->dev, "Can not read sub-id!\n");
 			return -EINVAL;
 		}
@@ -501,13 +501,13 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
 
 	if (ddrc_pmu->identifier >= HISI_PMU_V2)
 		name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
-				      "hisi_sccl%u_ddrc%u_%u",
-				      ddrc_pmu->sccl_id, ddrc_pmu->index_id,
-				      ddrc_pmu->sub_id);
+				      "hisi_sccl%d_ddrc%d_%d",
+				      ddrc_pmu->topo.sccl_id, ddrc_pmu->topo.index_id,
+				      ddrc_pmu->topo.sub_id);
 	else
 		name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
-				      "hisi_sccl%u_ddrc%u", ddrc_pmu->sccl_id,
-				      ddrc_pmu->index_id);
+				      "hisi_sccl%d_ddrc%d", ddrc_pmu->topo.sccl_id,
+				      ddrc_pmu->topo.index_id);
 
 	if (!name)
 		return -ENOMEM;
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index e26e50b3278d..c96fcc919e3d 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -300,7 +300,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 	 * SCCL_ID is in MPIDR[aff2].
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &hha_pmu->sccl_id)) {
+				     &hha_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Can not read hha sccl-id!\n");
 		return -EINVAL;
 	}
@@ -310,7 +310,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 	 * both "hisilicon, idx-id" as preference, if available.
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &hha_pmu->index_id)) {
+				     &hha_pmu->topo.index_id)) {
 		status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
 					       "_UID", NULL, &id);
 		if (ACPI_FAILURE(status)) {
@@ -318,10 +318,10 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 			return -EINVAL;
 		}
 
-		hha_pmu->index_id = id;
+		hha_pmu->topo.index_id = id;
 	}
 	/* HHA PMUs only share the same SCCL */
-	hha_pmu->ccl_id = -1;
+	hha_pmu->topo.ccl_id = -1;
 
 	hha_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hha_pmu->base)) {
@@ -510,8 +510,8 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u",
-			      hha_pmu->sccl_id, hha_pmu->index_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_hha%d",
+			      hha_pmu->topo.sccl_id, hha_pmu->topo.index_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index aa3d51dd5d21..d9773edf542a 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -360,13 +360,13 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
 	 * SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &l3c_pmu->sccl_id)) {
+				     &l3c_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Can not read l3c sccl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-				     &l3c_pmu->ccl_id)) {
+				     &l3c_pmu->topo.ccl_id)) {
 		dev_err(&pdev->dev, "Can not read l3c ccl-id!\n");
 		return -EINVAL;
 	}
@@ -544,8 +544,8 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
-			      l3c_pmu->sccl_id, l3c_pmu->ccl_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_l3c%d",
+			      l3c_pmu->topo.sccl_id, l3c_pmu->topo.ccl_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
index 29dd77943233..648de8355b3f 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
@@ -274,19 +274,19 @@ static int hisi_pa_pmu_init_data(struct platform_device *pdev,
 	 * to identify the PA PMU.
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &pa_pmu->sicl_id)) {
+				     &pa_pmu->topo.sicl_id)) {
 		dev_err(&pdev->dev, "Cannot read sicl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &pa_pmu->index_id)) {
+				     &pa_pmu->topo.index_id)) {
 		dev_err(&pdev->dev, "Cannot read idx-id!\n");
 		return -EINVAL;
 	}
 
-	pa_pmu->ccl_id = -1;
-	pa_pmu->sccl_id = -1;
+	pa_pmu->topo.ccl_id = -1;
+	pa_pmu->topo.sccl_id = -1;
 
 	pa_pmu->dev_info = device_get_match_data(&pdev->dev);
 	if (!pa_pmu->dev_info)
@@ -488,9 +488,9 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%d_%s%u",
-			      pa_pmu->sicl_id, pa_pmu->dev_info->name,
-			      pa_pmu->index_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%d_%s%d",
+			      pa_pmu->topo.sicl_id, pa_pmu->dev_info->name,
+			      pa_pmu->topo.index_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index e0f5fefcfee9..b01852a710ad 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -444,18 +444,19 @@ static void hisi_read_sccl_and_ccl_id(int *scclp, int *cclp)
  */
 static bool hisi_pmu_cpu_is_associated_pmu(struct hisi_pmu *hisi_pmu)
 {
+	struct hisi_pmu_topology *topo = &hisi_pmu->topo;
 	int sccl_id, ccl_id;
 
-	if (hisi_pmu->ccl_id == -1) {
+	if (topo->ccl_id == -1) {
 		/* If CCL_ID is -1, the PMU only shares the same SCCL */
 		hisi_read_sccl_and_ccl_id(&sccl_id, NULL);
 
-		return sccl_id == hisi_pmu->sccl_id;
+		return sccl_id == topo->sccl_id;
 	}
 
 	hisi_read_sccl_and_ccl_id(&sccl_id, &ccl_id);
 
-	return sccl_id == hisi_pmu->sccl_id && ccl_id == hisi_pmu->ccl_id;
+	return sccl_id == topo->sccl_id && ccl_id == topo->ccl_id;
 }
 
 int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
index bd48338ce937..f162a1b6c6d1 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
@@ -81,12 +81,43 @@ struct hisi_pmu_hwevents {
 	const struct attribute_group **attr_groups;
 };
 
+/**
+ * struct hisi_pmu_topology - Describe the topology hierarchy on which the PMU
+ *                            is located.
+ * @sccl_id: ID of the SCCL on which the PMU locate is located.
+ * @sicl_id: ID of the SICL on which the PMU locate is located.
+ * @scl_id:  ID used by the core which is unaware of the SCCL/SICL.
+ * @ccl_id: ID of the CCL (CPU cluster) on which the PMU is located.
+ * @index_id: the ID of the PMU module if there're several PMUs at a
+ *            particularly location in the topology.
+ * @sub_id: submodule ID of the PMU. For example we use this for DDRC PMU v2
+ *          since each DDRC has more than one DMC
+ *
+ * The ID will be -1 if the PMU isn't located on a certain topology.
+ */
+struct hisi_pmu_topology {
+	/*
+	 * SCCL (Super CPU CLuster) and SICL (Super I/O Cluster) are parallel
+	 * so a PMU cannot locate on a SCCL and a SICL. If the SCCL/SICL
+	 * distinction is not relevant, use scl_id instead.
+	 */
+	union {
+		int sccl_id;
+		int sicl_id;
+		int scl_id;
+	};
+	int ccl_id;
+	int index_id;
+	int sub_id;
+};
+
 /* Generic pmu struct for different pmu types */
 struct hisi_pmu {
 	struct pmu pmu;
 	const struct hisi_uncore_ops *ops;
 	const struct hisi_pmu_dev_info *dev_info;
 	struct hisi_pmu_hwevents pmu_events;
+	struct hisi_pmu_topology topo;
 	/*
 	 * CPUs associated to the PMU and are preferred to use for counting.
 	 * Could be empty if PMU has no association (e.g. PMU on SICL), in
@@ -98,14 +129,7 @@ struct hisi_pmu {
 	int irq;
 	struct device *dev;
 	struct hlist_node node;
-	int sccl_id;
-	int sicl_id;
-	int ccl_id;
 	void __iomem *base;
-	/* the ID of the PMU modules */
-	u32 index_id;
-	/* For DDRC PMU v2: each DDRC has more than one DMC */
-	u32 sub_id;
 	int num_counters;
 	int counter_bits;
 	/* check event code range */
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
index d39aee31ca42..32cb23a7cf5d 100644
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
@@ -293,19 +293,19 @@ static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
 	 * while SCCL_ID is from MPIDR_EL1 by CPU.
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &sllc_pmu->sccl_id)) {
+				     &sllc_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Cannot read sccl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-				     &sllc_pmu->index_id)) {
+				     &sllc_pmu->topo.index_id)) {
 		dev_err(&pdev->dev, "Cannot read idx-id!\n");
 		return -EINVAL;
 	}
 
 	/* SLLC PMUs only share the same SCCL */
-	sllc_pmu->ccl_id = -1;
+	sllc_pmu->topo.ccl_id = -1;
 
 	sllc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(sllc_pmu->base)) {
@@ -433,8 +433,8 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_sllc%u",
-			      sllc_pmu->sccl_id, sllc_pmu->index_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_sllc%d",
+			      sllc_pmu->topo.sccl_id, sllc_pmu->topo.index_id);
 	if (!name)
 		return -ENOMEM;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
index 2233d288ccf5..bc51d45c8ef9 100644
--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
@@ -372,19 +372,19 @@ static int hisi_uc_pmu_init_data(struct platform_device *pdev,
 	 * They have some CCLs per SCCL and then 4 UC PMU per CCL.
 	 */
 	if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-				     &uc_pmu->sccl_id)) {
+				     &uc_pmu->topo.sccl_id)) {
 		dev_err(&pdev->dev, "Can not read uc sccl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-				     &uc_pmu->ccl_id)) {
+				     &uc_pmu->topo.ccl_id)) {
 		dev_err(&pdev->dev, "Can not read uc ccl-id!\n");
 		return -EINVAL;
 	}
 
 	if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-				     &uc_pmu->sub_id)) {
+				     &uc_pmu->topo.sub_id)) {
 		dev_err(&pdev->dev, "Can not read sub-id!\n");
 		return -EINVAL;
 	}
@@ -538,8 +538,9 @@ static int hisi_uc_pmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_uc%d_%u",
-			      uc_pmu->sccl_id, uc_pmu->ccl_id, uc_pmu->sub_id);
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%d_uc%d_%d",
+			      uc_pmu->topo.sccl_id, uc_pmu->topo.ccl_id,
+			      uc_pmu->topo.sub_id);
 	if (!name)
 		return -ENOMEM;
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:22 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:22 +0800
Subject: [PATCH v5 07/10] drivers/perf: hisi: Provide a generic implementation of cpumask/identifier
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-8-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Each type of HiSilicon Uncore PMU has the following sysfs attributes:

- format: bitmask in perf_event_attr::config[012] of corresponding
  attribute
- event: events name and corresponding event code
- cpumask: range of CPUs the events can be opened on
- identifier: the version of this PMU

Different types of PMU have different implementations of the "format"
and "event" but all share the same implementation of the "cpumask"
and "identifier". Thus we can move cpumask and identifier to the
hisi_uncore_pmu framework and drivers can use the generic
implementation.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c  | 27 +----------
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 31 ++-----------
 drivers/perf/hisilicon/hisi_uncore_hha_pmu.c  | 31 ++-----------
 drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c  | 31 ++-----------
 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   | 35 +++------------
 drivers/perf/hisilicon/hisi_uncore_pmu.c      | 45 ++++++++++++++-----
 drivers/perf/hisilicon/hisi_uncore_pmu.h      |  4 ++
 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 27 +----------
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c   | 27 +----------
 9 files changed, 63 insertions(+), 195 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
index e3a619ea6831..b879b81adfdd 100644
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
@@ -225,34 +225,11 @@ static const struct attribute_group hisi_cpa_pmu_events_group = {
 	.attrs = hisi_cpa_pmu_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_cpa_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_cpa_pmu_cpumask_attr_group = {
-	.attrs = hisi_cpa_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_cpa_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_cpa_pmu_identifier_attrs[] = {
-	&hisi_cpa_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_cpa_pmu_identifier_group = {
-	.attrs = hisi_cpa_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_cpa_pmu_attr_groups[] = {
 	&hisi_cpa_pmu_format_group,
 	&hisi_cpa_pmu_events_group,
-	&hisi_cpa_pmu_cpumask_attr_group,
-	&hisi_cpa_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index 1d12384fef8f..75f251a7b30c 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -380,42 +380,19 @@ static const struct attribute_group hisi_ddrc_pmu_v2_events_group = {
 	.attrs = hisi_ddrc_pmu_v2_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_ddrc_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static const struct attribute_group hisi_ddrc_pmu_cpumask_attr_group = {
-	.attrs = hisi_ddrc_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_ddrc_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_ddrc_pmu_identifier_attrs[] = {
-	&hisi_ddrc_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_ddrc_pmu_identifier_group = {
-	.attrs = hisi_ddrc_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_ddrc_pmu_v1_attr_groups[] = {
 	&hisi_ddrc_pmu_v1_format_group,
 	&hisi_ddrc_pmu_v1_events_group,
-	&hisi_ddrc_pmu_cpumask_attr_group,
-	&hisi_ddrc_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL,
 };
 
 static const struct attribute_group *hisi_ddrc_pmu_v2_attr_groups[] = {
 	&hisi_ddrc_pmu_v2_format_group,
 	&hisi_ddrc_pmu_v2_events_group,
-	&hisi_ddrc_pmu_cpumask_attr_group,
-	&hisi_ddrc_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
index a2b9629a6081..ca609db86046 100644
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
@@ -405,42 +405,19 @@ static const struct attribute_group hisi_hha_pmu_v2_events_group = {
 	.attrs = hisi_hha_pmu_v2_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_hha_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static const struct attribute_group hisi_hha_pmu_cpumask_attr_group = {
-	.attrs = hisi_hha_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_hha_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_hha_pmu_identifier_attrs[] = {
-	&hisi_hha_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_hha_pmu_identifier_group = {
-	.attrs = hisi_hha_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_hha_pmu_v1_attr_groups[] = {
 	&hisi_hha_pmu_v1_format_group,
 	&hisi_hha_pmu_v1_events_group,
-	&hisi_hha_pmu_cpumask_attr_group,
-	&hisi_hha_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL,
 };
 
 static const struct attribute_group *hisi_hha_pmu_v2_attr_groups[] = {
 	&hisi_hha_pmu_v2_format_group,
 	&hisi_hha_pmu_v2_events_group,
-	&hisi_hha_pmu_cpumask_attr_group,
-	&hisi_hha_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index 5ba49e902535..412fc3a97963 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -441,42 +441,19 @@ static const struct attribute_group hisi_l3c_pmu_v2_events_group = {
 	.attrs = hisi_l3c_pmu_v2_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_l3c_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static const struct attribute_group hisi_l3c_pmu_cpumask_attr_group = {
-	.attrs = hisi_l3c_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_l3c_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_l3c_pmu_identifier_attrs[] = {
-	&hisi_l3c_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_l3c_pmu_identifier_group = {
-	.attrs = hisi_l3c_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_l3c_pmu_v1_attr_groups[] = {
 	&hisi_l3c_pmu_v1_format_group,
 	&hisi_l3c_pmu_v1_events_group,
-	&hisi_l3c_pmu_cpumask_attr_group,
-	&hisi_l3c_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL,
 };
 
 static const struct attribute_group *hisi_l3c_pmu_v2_attr_groups[] = {
 	&hisi_l3c_pmu_v2_format_group,
 	&hisi_l3c_pmu_v2_events_group,
-	&hisi_l3c_pmu_cpumask_attr_group,
-	&hisi_l3c_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
index 48c5357666d0..a0142684e379 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
@@ -353,29 +353,6 @@ static const struct attribute_group hisi_h60pa_pmu_events_group = {
 	.attrs = hisi_h60pa_pmu_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_pa_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_pa_pmu_cpumask_attr_group = {
-	.attrs = hisi_pa_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_pa_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_pa_pmu_identifier_attrs[] = {
-	&hisi_pa_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_pa_pmu_identifier_group = {
-	.attrs = hisi_pa_pmu_identifier_attrs,
-};
-
 static struct hisi_pa_pmu_int_regs hisi_pa_pmu_regs = {
 	.mask_offset = PA_INT_MASK,
 	.clear_offset = PA_INT_CLEAR,
@@ -385,8 +362,8 @@ static struct hisi_pa_pmu_int_regs hisi_pa_pmu_regs = {
 static const struct attribute_group *hisi_pa_pmu_v2_attr_groups[] = {
 	&hisi_pa_pmu_v2_format_group,
 	&hisi_pa_pmu_v2_events_group,
-	&hisi_pa_pmu_cpumask_attr_group,
-	&hisi_pa_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
@@ -399,8 +376,8 @@ static const struct hisi_pmu_dev_info hisi_h32pa_v2 = {
 static const struct attribute_group *hisi_pa_pmu_v3_attr_groups[] = {
 	&hisi_pa_pmu_v2_format_group,
 	&hisi_pa_pmu_v3_events_group,
-	&hisi_pa_pmu_cpumask_attr_group,
-	&hisi_pa_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
@@ -419,8 +396,8 @@ static struct hisi_pa_pmu_int_regs hisi_h60pa_pmu_regs = {
 static const struct attribute_group *hisi_h60pa_pmu_attr_groups[] = {
 	&hisi_pa_pmu_v2_format_group,
 	&hisi_h60pa_pmu_events_group,
-	&hisi_pa_pmu_cpumask_attr_group,
-	&hisi_pa_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 5f581327a71f..075aaa8eaeaa 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -49,6 +49,41 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
 }
 EXPORT_SYMBOL_NS_GPL(hisi_cpumask_sysfs_show, "HISI_PMU");
 
+static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
+
+static struct attribute *hisi_pmu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL
+};
+
+const struct attribute_group hisi_pmu_cpumask_attr_group = {
+	.attrs = hisi_pmu_cpumask_attrs,
+};
+EXPORT_SYMBOL_NS_GPL(hisi_pmu_cpumask_attr_group, "HISI_PMU");
+
+ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
+					     struct device_attribute *attr,
+					     char *page)
+{
+	struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
+
+	return sysfs_emit(page, "0x%08x\n", hisi_pmu->identifier);
+}
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_identifier_attr_show, "HISI_PMU");
+
+static struct device_attribute hisi_pmu_identifier_attr =
+	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
+
+static struct attribute *hisi_pmu_identifier_attrs[] = {
+	&hisi_pmu_identifier_attr.attr,
+	NULL
+};
+
+const struct attribute_group hisi_pmu_identifier_group = {
+	.attrs = hisi_pmu_identifier_attrs,
+};
+EXPORT_SYMBOL_NS_GPL(hisi_pmu_identifier_group, "HISI_PMU");
+
 static bool hisi_validate_event_group(struct perf_event *event)
 {
 	struct perf_event *sibling, *leader = event->group_leader;
@@ -99,16 +134,6 @@ int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
 }
 EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_get_event_idx, "HISI_PMU");
 
-ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
-					     struct device_attribute *attr,
-					     char *page)
-{
-	struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
-
-	return sysfs_emit(page, "0x%08x\n", hisi_pmu->identifier);
-}
-EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_identifier_attr_show, "HISI_PMU");
-
 static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
 {
 	clear_bit(idx, hisi_pmu->pmu_events.used_mask);
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
index 53b1331b8565..f4fed2544877 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
@@ -137,6 +137,10 @@ struct hisi_pmu {
 	u32 identifier;
 };
 
+/* Generic implementation of cpumask/identifier group */
+extern const struct attribute_group hisi_pmu_cpumask_attr_group;
+extern const struct attribute_group hisi_pmu_identifier_group;
+
 int hisi_uncore_pmu_get_event_idx(struct perf_event *event);
 void hisi_uncore_pmu_read(struct perf_event *event);
 int hisi_uncore_pmu_add(struct perf_event *event, int flags);
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
index ba6af0d3cb22..dbd079016fc4 100644
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
@@ -344,34 +344,11 @@ static const struct attribute_group hisi_sllc_pmu_v2_events_group = {
 	.attrs = hisi_sllc_pmu_v2_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_sllc_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_sllc_pmu_cpumask_attr_group = {
-	.attrs = hisi_sllc_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_sllc_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_sllc_pmu_identifier_attrs[] = {
-	&hisi_sllc_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_sllc_pmu_identifier_group = {
-	.attrs = hisi_sllc_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_sllc_pmu_v2_attr_groups[] = {
 	&hisi_sllc_pmu_v2_format_group,
 	&hisi_sllc_pmu_v2_events_group,
-	&hisi_sllc_pmu_cpumask_attr_group,
-	&hisi_sllc_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
index ba35c9476340..03cb9b564b99 100644
--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
@@ -437,34 +437,11 @@ static const struct attribute_group hisi_uc_pmu_events_group = {
 	.attrs = hisi_uc_pmu_events_attr,
 };
 
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
-
-static struct attribute *hisi_uc_pmu_cpumask_attrs[] = {
-	&dev_attr_cpumask.attr,
-	NULL,
-};
-
-static const struct attribute_group hisi_uc_pmu_cpumask_attr_group = {
-	.attrs = hisi_uc_pmu_cpumask_attrs,
-};
-
-static struct device_attribute hisi_uc_pmu_identifier_attr =
-	__ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
-
-static struct attribute *hisi_uc_pmu_identifier_attrs[] = {
-	&hisi_uc_pmu_identifier_attr.attr,
-	NULL
-};
-
-static const struct attribute_group hisi_uc_pmu_identifier_group = {
-	.attrs = hisi_uc_pmu_identifier_attrs,
-};
-
 static const struct attribute_group *hisi_uc_pmu_attr_groups[] = {
 	&hisi_uc_pmu_format_group,
 	&hisi_uc_pmu_events_group,
-	&hisi_uc_pmu_cpumask_attr_group,
-	&hisi_uc_pmu_identifier_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
 	NULL
 };
 
-- 
2.24.0



From yangyicong at huawei.com  Tue Dec 10 06:15:24 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 10 Dec 2024 22:15:24 +0800
Subject: [PATCH v5 09/10] drivers/perf: hisi: Fix incorrect variable name "hha_pmu" in DDRC PMU driver
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <20241210141525.37788-10-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

In the callback function write_evtype(), the variable name of struct
hisi_pmu should be "ddrc_pmu" instead of "hha_pmu".

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
index 75f251a7b30c..fb309b8d5301 100644
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
@@ -111,14 +111,14 @@ static void hisi_ddrc_pmu_v2_write_counter(struct hisi_pmu *ddrc_pmu,
  * so there is no need to write event type, while it is programmable counter in
  * PMU v2.
  */
-static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
+static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *ddrc_pmu, int idx,
 				       u32 type)
 {
 	u32 offset;
 
-	if (hha_pmu->identifier >= HISI_PMU_V2) {
+	if (ddrc_pmu->identifier >= HISI_PMU_V2) {
 		offset = DDRC_V2_EVENT_TYPE + 4 * idx;
-		writel(type, hha_pmu->base + offset);
+		writel(type, ddrc_pmu->base + offset);
 	}
 }
 
-- 
2.24.0



From catalin.marinas at arm.com  Tue Dec 10 06:17:58 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 10 Dec 2024 14:17:58 +0000
Subject: [PATCH] arm64/signal: Silence spurious sparse warning storing
 GCSPR_EL0
In-Reply-To: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
References: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
Message-ID: <Z1hNllCWa4u-IxrH@arm.com>

On Tue, Dec 10, 2024 at 12:42:53AM +0000, Mark Brown wrote:
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 14ac6fdb872b9672e4b16a097f1b577aae8dec50..83ea7e5fd2b54566c6649b82b8570657a5711dd4 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -39,7 +39,7 @@
>  #ifdef CONFIG_ARM64_GCS
>  #define GCS_SIGNAL_CAP(addr) (((unsigned long)addr) & GCS_CAP_ADDR_MASK)
>  
> -static bool gcs_signal_cap_valid(u64 addr, u64 val)
> +static bool gcs_signal_cap_valid(unsigned long __user *addr, u64 val)
>  {
>  	return val == GCS_SIGNAL_CAP(addr);
>  }
> @@ -1094,15 +1094,15 @@ static int gcs_restore_signal(void)
>  	/*
>  	 * Check that the cap is the actual GCS before replacing it.
>  	 */
> -	if (!gcs_signal_cap_valid((u64)gcspr_el0, cap))
> +	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);
> +	put_user_gcs(0, gcspr_el0, &ret);
>  	if (ret != 0)
>  		return -EFAULT;
>  
> -	write_sysreg_s(gcspr_el0 + 1, SYS_GCSPR_EL0);
> +	write_sysreg_s((unsigned long)(gcspr_el0 + 1), SYS_GCSPR_EL0);

Would we now get a warning here?

-- 
Catalin


From robdclark at gmail.com  Tue Dec 10 06:30:44 2024
From: robdclark at gmail.com (Rob Clark)
Date: Tue, 10 Dec 2024 06:30:44 -0800
Subject: [PATCH v10 0/4] io-pgtable-arm + drm/msm: Extend iova fault debugging
In-Reply-To: <20241210111450.GA14735@willie-the-truck>
References: <20241028213146.238941-1-robdclark@gmail.com> <20241210111450.GA14735@willie-the-truck>
Message-ID: <CAF6AEGs72rxvguSYbALWPL2FrO5coyijQXY4HEQdwvr8Fj4XKQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 3:14?AM Will Deacon <will at kernel.org> wrote:
>
> Hi Rob,
>
> On Mon, Oct 28, 2024 at 02:31:36PM -0700, Rob Clark wrote:
> > From: Rob Clark <robdclark at chromium.org>
> >
> > This series extends io-pgtable-arm with a method to retrieve the page
> > table entries traversed in the process of address translation, and then
> > beefs up drm/msm gpu devcore dump to include this (and additional info)
> > in the devcore dump.
> >
> > This is a respin of https://patchwork.freedesktop.org/series/94968/
> > (minus a patch that was already merged)
> >
> > v2:  Fix an armv7/32b build error in the last patch
> > v3:  Incorperate Will Deacon's suggestion to make the interface
> >      callback based.
> > v4:  Actually wire up the callback
> > v5:  Drop the callback approach
> > v6:  Make walk-data struct pgtable specific and rename
> >      io_pgtable_walk_data to arm_lpae_io_pgtable_walk_data
> > v7:  Re-use the pgtable walker added for arm_lpae_read_and_clear_dirty()
> > v8:  Pass pte pointer to callback so it can modify the actual pte
> > v9:  Fix selftests_running case
> > v10: Call visit cb for all nodes traversed, leave the decision about
> >      whether to care about non-leaf nodes to the callback
>
> Do you plan to respin this? I see Mostafa left a proposal on patch 3.

Yeah, his suggestion looked reasonable.  I'll try to get back to this
patchset today.

BR,
-R


From heiko at sntech.de  Tue Dec 10 06:36:31 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 10 Dec 2024 15:36:31 +0100
Subject: [PATCH v3 0/3] drm/rockchip: Add driver for the new DSI2 controller
In-Reply-To: <78e7b8e.b5ee.193b09ce46d.Coremail.andyshrk@163.com>
References: <20241203165450.1501219-1-heiko@sntech.de>
 <jl5obi7rd4h6ywozeqruxq2vx62sx5yf4wwpksrq3prdleps2k@d3zbr5ttquvn>
 <78e7b8e.b5ee.193b09ce46d.Coremail.andyshrk@163.com>
Message-ID: <3104907.xgJ6IN8ObU@diego>

Hi Andy,

Am Dienstag, 10. Dezember 2024, 13:48:12 CET schrieb Andy Yan:
> ? 2024-12-10 20:32:03?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
> >On Tue, Dec 10, 2024 at 09:54:09AM +0800, Andy Yan wrote:
> >> ? 2024-12-10 09:45:11?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
> >> >On Tue, 10 Dec 2024 at 03:22, Andy Yan <andyshrk at 163.com> wrote:
> >> >> ? 2024-12-10 09:01:38?"Dmitry Baryshkov" <dmitry.baryshkov at linaro.org> ???
> >> >> >On Tue, Dec 10, 2024 at 08:50:51AM +0800, Andy Yan wrote:
> >> >> >> At 2024-12-10 07:12:26, "Heiko St?bner" <heiko at sntech.de> wrote:
> >> >> >> >Am Montag, 9. Dezember 2024, 17:11:03 CET schrieb Diederik de Haas:
> >> >> >> >> On Mon Dec 9, 2024 at 4:06 PM CET, Daniel Semkowicz wrote:
> >> >> >> >> > On 03.12.24 21:54, Heiko Stuebner wrote:
> >> >> >> >This really sounds like something is wrong on the vop side.
> >> >> >> >The interrupt is part of the vop, the divisable by 4 things likely too.
> >> >> >>
> >> >> >> This is a hardware limitation on vop side:
> >> >> >> The horizontal resolution must be 4 pixel aligned.
> >> >> >
> >> >> >Then mode_valid() and atomic_check() must reject modes that don't fit.
> >> >>
> >> >> We round down to 4 pixel aligned in mode_fixup in our bsp kernel,
> >> >
> >> >What is meant by the "bsp kernel" here? I don't see it being present
> >> 
> >> bsp kernel means downstream vendor kernel.
> >> 
> >> >in the mainline kernel. So, if the mode is unsupported, it should be
> >> 
> >> Will it be acceptable to add this round down in the mainline mode_fixup?
> >
> >I think so.
> 
> Then I can write a patch for it.

thanks a lot for looking into that :-)


Heiko




From tabba at google.com  Tue Dec 10 06:41:12 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 14:41:12 +0000
Subject: [PATCH v2 11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
In-Reply-To: <20241203103735.2267589-12-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-12-qperret@google.com>
Message-ID: <CA+EHjTw48LTFt=sKtPwS1rmA=ma6Sj9O-D=17FXoMybqZ7+g5g@mail.gmail.com>

Hi Quentin,

On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
>
> In preparation for letting the host unmap pages from non-protected
> guests, introduce a new hypercall implementing the host-unshare-guest
> transition.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  5 ++
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 24 +++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 67 +++++++++++++++++++
>  5 files changed, 98 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 449337f5b2a3..0b6c4d325134 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -66,6 +66,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index a7976e50f556..e528a42ed60e 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -40,6 +40,7 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
> +int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);

The parameters of share_guest and unshare_guest are quite different. I
think that the unshare makes more sense, that it uses the hyp_vm as
opposed to the hyp_vcpu. Still, I think that one of the two should
change.

>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> index be52c5b15e21..5dfc9ece9aa5 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> @@ -64,6 +64,11 @@ static inline bool pkvm_hyp_vcpu_is_protected(struct pkvm_hyp_vcpu *hyp_vcpu)
>         return vcpu_is_protected(&hyp_vcpu->vcpu);
>  }
>
> +static inline bool pkvm_hyp_vm_is_protected(struct pkvm_hyp_vm *hyp_vm)
> +{
> +       return kvm_vm_is_protected(&hyp_vm->kvm);
> +}
> +
>  void pkvm_hyp_vm_table_init(void *tbl);
>
>  int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index d659462fbf5d..04a9053ae1d5 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -244,6 +244,29 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) =  ret;
>  }
>
> +static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> +       struct pkvm_hyp_vm *hyp_vm;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vm = get_pkvm_hyp_vm(handle);
> +       if (!hyp_vm)
> +               goto out;
> +       if (pkvm_hyp_vm_is_protected(hyp_vm))
> +               goto put_hyp_vm;

bikeshedding: is -EINVAL the best return value, or might -EPERM be
better if the VM is protected?

> +
> +       ret = __pkvm_host_unshare_guest(gfn, hyp_vm);
> +put_hyp_vm:
> +       put_pkvm_hyp_vm(hyp_vm);
> +out:
> +       cpu_reg(host_ctxt, 1) =  ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -454,6 +477,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_share_hyp),
>         HANDLE_FUNC(__pkvm_host_unshare_hyp),
>         HANDLE_FUNC(__pkvm_host_share_guest),
> +       HANDLE_FUNC(__pkvm_host_unshare_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index a69d7212b64c..aa27a3e42e5e 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1413,3 +1413,70 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
>
>         return ret;
>  }
> +
> +static int __check_host_unshare_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)

nit: sometimes (in this and other patches) you use vm to refer to
pkvm_hyp_vm, and other times you use hyp_vm. Makes grepping/searching
a bit more tricky.

Cheers,
/fuad


> +{
> +       enum pkvm_page_state state;
> +       struct hyp_page *page;
> +       kvm_pte_t pte;
> +       u64 phys;
> +       s8 level;
> +       int ret;
> +
> +       ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
> +       if (ret)
> +               return ret;
> +       if (level != KVM_PGTABLE_LAST_LEVEL)
> +               return -E2BIG;
> +       if (!kvm_pte_valid(pte))
> +               return -ENOENT;
> +
> +       state = guest_get_page_state(pte, ipa);
> +       if (state != PKVM_PAGE_SHARED_BORROWED)
> +               return -EPERM;
> +
> +       phys = kvm_pte_to_phys(pte);
> +       ret = range_is_allowed_memory(phys, phys + PAGE_SIZE);
> +       if (WARN_ON(ret))
> +               return ret;
> +
> +       page = hyp_phys_to_page(phys);
> +       if (page->host_state != PKVM_PAGE_SHARED_OWNED)
> +               return -EPERM;
> +       if (WARN_ON(!page->host_share_guest_count))
> +               return -EINVAL;
> +
> +       *__phys = phys;
> +
> +       return 0;
> +}
> +
> +int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm)
> +{
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       struct hyp_page *page;
> +       u64 phys;
> +       int ret;
> +
> +       host_lock_component();
> +       guest_lock_component(hyp_vm);
> +
> +       ret = __check_host_unshare_guest(hyp_vm, &phys, ipa);
> +       if (ret)
> +               goto unlock;
> +
> +       ret = kvm_pgtable_stage2_unmap(&hyp_vm->pgt, ipa, PAGE_SIZE);
> +       if (ret)
> +               goto unlock;
> +
> +       page = hyp_phys_to_page(phys);
> +       page->host_share_guest_count--;
> +       if (!page->host_share_guest_count)
> +               WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_OWNED));
> +
> +unlock:
> +       guest_unlock_component(hyp_vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> --
> 2.47.0.338.g60cca15819-goog
>


From broonie at kernel.org  Tue Dec 10 06:45:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 14:45:53 +0000
Subject: [PATCH] arm64/signal: Silence spurious sparse warning storing
 GCSPR_EL0
In-Reply-To: <Z1hNllCWa4u-IxrH@arm.com>
References: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
 <Z1hNllCWa4u-IxrH@arm.com>
Message-ID: <755660a1-0536-4520-8c01-9c254b02fae0@sirena.org.uk>

On Tue, Dec 10, 2024 at 02:17:58PM +0000, Catalin Marinas wrote:
> On Tue, Dec 10, 2024 at 12:42:53AM +0000, Mark Brown wrote:

> > -	write_sysreg_s(gcspr_el0 + 1, SYS_GCSPR_EL0);
> > +	write_sysreg_s((unsigned long)(gcspr_el0 + 1), SYS_GCSPR_EL0);

> Would we now get a warning here?

No, like the changelog mentions converting to an unsigned long is
regarded by sparse as a (the AFAICT) valid way of discarding the
__userness of a pointer so it's that change that silences the warning.
It does the right thing with whatever sparse I have 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/20241210/10d41d1d/attachment.sig>

From catalin.marinas at arm.com  Tue Dec 10 06:45:01 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 10 Dec 2024 14:45:01 +0000
Subject: [PATCH v2 0/1] KVM: arm64: Map GPU memory with no struct pages
In-Reply-To: <20241210141806.GI2347147@nvidia.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241210140739.GC15607@willie-the-truck>
 <20241210141806.GI2347147@nvidia.com>
Message-ID: <Z1hT7Z1sp_6Qv6Me@arm.com>

On Tue, Dec 10, 2024 at 10:18:06AM -0400, Jason Gunthorpe wrote:
> On Tue, Dec 10, 2024 at 02:07:40PM +0000, Will Deacon wrote:
> > On Mon, Nov 18, 2024 at 01:19:57PM +0000, ankita at nvidia.com wrote:
> > > The changes are heavily influenced by the insightful discussions between
> > > Catalin Marinas and Jason Gunthorpe [1] on v1. Many thanks for their
> > > valuable suggestions.
> > > 
> > > Link: https://lore.kernel.org/lkml/20230907181459.18145-2-ankita at nvidia.com [1]
> > 
> > That's a different series, no? It got merged at v9:
> 
> I was confused by this too. v1 of that series included this patch, as
> that series went along it became focused only on enabling WC
> (Normal-NC) in a VM for device MMIO and this patch for device cachable
> memory was dropped off.
> 
> There are two related things:
>  1) Device MMIO memory should be able to be Normal-NC in a VM. Already
>     merged
>  2) Device Cachable memory (ie CXL and pre-CXL coherently attached
>     memory) should be Normal Cachable in a VM, even if it doesn't have
>     struct page/etc. (this patch)
> 
> IIRC this part was dropped off because of the MTE complexity that
> Catalin raised.

Indeed, we only merged the Normal NC part at the time. I asked Ankit to
drop the cacheable attributes and only focus on getting the other part
merged.

-- 
Catalin


From lkp at intel.com  Tue Dec 10 06:45:17 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 10 Dec 2024 22:45:17 +0800
Subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the
 spectre_bhb_k24_list
In-Reply-To: <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>
References: <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>
Message-ID: <202412102250.hPlsx2c8-lkp@intel.com>

Hi Douglas,

kernel test robot noticed the following build errors:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on arm-perf/for-next/perf kvmarm/next soc/for-next arm/for-next arm/fixes linus/master v6.13-rc2 next-20241210]
[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/Douglas-Anderson/arm64-errata-Add-QCOM_KRYO_4XX_GOLD-to-the-spectre_bhb_k24_list/20241210-014833
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
patch link:    https://lore.kernel.org/r/20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384%40changeid
patch subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the spectre_bhb_k24_list
config: arm64-allnoconfig (https://download.01.org/0day-ci/archive/20241210/202412102250.hPlsx2c8-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241210/202412102250.hPlsx2c8-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/202412102250.hPlsx2c8-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from arch/arm64/include/asm/cache.h:43,
                    from include/linux/cache.h:6,
                    from include/linux/jiffies.h:5,
                    from include/linux/ktime.h:25,
                    from include/linux/timer.h:6,
                    from include/linux/workqueue.h:9,
                    from include/linux/bpf.h:10,
                    from arch/arm64/kernel/proton-pack.c:21:
   arch/arm64/kernel/proton-pack.c: In function 'spectre_bhb_loop_affected':
>> arch/arm64/kernel/proton-pack.c:870:43: error: 'MIDR_QCOM_KRYO_5XX_GOLD' undeclared (first use in this function); did you mean 'MIDR_QCOM_KRYO_4XX_GOLD'?
     870 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
         |                                           ^~~~~~~~~~~~~~~~~~~~~~~
   arch/arm64/include/asm/cputype.h:251:26: note: in definition of macro 'MIDR_RANGE'
     251 |                 .model = m,                                     \
         |                          ^
   arch/arm64/kernel/proton-pack.c:870:25: note: in expansion of macro 'MIDR_ALL_VERSIONS'
     870 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
         |                         ^~~~~~~~~~~~~~~~~
   arch/arm64/kernel/proton-pack.c:870:43: note: each undeclared identifier is reported only once for each function it appears in
     870 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
         |                                           ^~~~~~~~~~~~~~~~~~~~~~~
   arch/arm64/include/asm/cputype.h:251:26: note: in definition of macro 'MIDR_RANGE'
     251 |                 .model = m,                                     \
         |                          ^
   arch/arm64/kernel/proton-pack.c:870:25: note: in expansion of macro 'MIDR_ALL_VERSIONS'
     870 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
         |                         ^~~~~~~~~~~~~~~~~


vim +870 arch/arm64/kernel/proton-pack.c

   843	
   844	/*
   845	 * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
   846	 * SCOPE_SYSTEM call will give the right answer.
   847	 */
   848	u8 spectre_bhb_loop_affected(int scope)
   849	{
   850		u8 k = 0;
   851		static u8 max_bhb_k;
   852	
   853		if (scope == SCOPE_LOCAL_CPU) {
   854			static const struct midr_range spectre_bhb_k32_list[] = {
   855				MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
   856				MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
   857				MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
   858				MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
   859				MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
   860				MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
   861				MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
   862				MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
   863				{},
   864			};
   865			static const struct midr_range spectre_bhb_k24_list[] = {
   866				MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
   867				MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
   868				MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
   869				MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
 > 870				MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
   871				{},
   872			};
   873			static const struct midr_range spectre_bhb_k11_list[] = {
   874				MIDR_ALL_VERSIONS(MIDR_AMPERE1),
   875				{},
   876			};
   877			static const struct midr_range spectre_bhb_k8_list[] = {
   878				MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
   879				MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
   880				{},
   881			};
   882	
   883			if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
   884				k = 32;
   885			else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
   886				k = 24;
   887			else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
   888				k = 11;
   889			else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
   890				k =  8;
   891	
   892			max_bhb_k = max(max_bhb_k, k);
   893		} else {
   894			k = max_bhb_k;
   895		}
   896	
   897		return k;
   898	}
   899	

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


From lkp at intel.com  Tue Dec 10 06:45:42 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 10 Dec 2024 22:45:42 +0800
Subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the
 spectre_bhb_k24_list
In-Reply-To: <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>
References: <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>
Message-ID: <202412102224.bmEeK15u-lkp@intel.com>

Hi Douglas,

kernel test robot noticed the following build errors:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on arm-perf/for-next/perf kvmarm/next soc/for-next arm/for-next arm/fixes linus/master v6.13-rc2 next-20241210]
[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/Douglas-Anderson/arm64-errata-Add-QCOM_KRYO_4XX_GOLD-to-the-spectre_bhb_k24_list/20241210-014833
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
patch link:    https://lore.kernel.org/r/20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384%40changeid
patch subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the spectre_bhb_k24_list
config: arm64-randconfig-002-20241210 (https://download.01.org/0day-ci/archive/20241210/202412102224.bmEeK15u-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241210/202412102224.bmEeK15u-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/202412102224.bmEeK15u-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from arch/arm64/kernel/proton-pack.c:21:
   In file included from include/linux/bpf.h:21:
   In file included from include/linux/kallsyms.h:13:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> arch/arm64/kernel/proton-pack.c:870:22: error: use of undeclared identifier 'MIDR_QCOM_KRYO_5XX_GOLD'
     870 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
         |                                           ^
   4 warnings and 1 error generated.


vim +/MIDR_QCOM_KRYO_5XX_GOLD +870 arch/arm64/kernel/proton-pack.c

   843	
   844	/*
   845	 * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
   846	 * SCOPE_SYSTEM call will give the right answer.
   847	 */
   848	u8 spectre_bhb_loop_affected(int scope)
   849	{
   850		u8 k = 0;
   851		static u8 max_bhb_k;
   852	
   853		if (scope == SCOPE_LOCAL_CPU) {
   854			static const struct midr_range spectre_bhb_k32_list[] = {
   855				MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
   856				MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
   857				MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
   858				MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
   859				MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
   860				MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
   861				MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
   862				MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
   863				{},
   864			};
   865			static const struct midr_range spectre_bhb_k24_list[] = {
   866				MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
   867				MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
   868				MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
   869				MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
 > 870				MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
   871				{},
   872			};
   873			static const struct midr_range spectre_bhb_k11_list[] = {
   874				MIDR_ALL_VERSIONS(MIDR_AMPERE1),
   875				{},
   876			};
   877			static const struct midr_range spectre_bhb_k8_list[] = {
   878				MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
   879				MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
   880				{},
   881			};
   882	
   883			if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
   884				k = 32;
   885			else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
   886				k = 24;
   887			else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
   888				k = 11;
   889			else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
   890				k =  8;
   891	
   892			max_bhb_k = max(max_bhb_k, k);
   893		} else {
   894			k = max_bhb_k;
   895		}
   896	
   897		return k;
   898	}
   899	

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


From james.clark at linaro.org  Tue Dec 10 06:49:28 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 10 Dec 2024 14:49:28 +0000
Subject: [PATCH] coresight: docs: Remove target sink from examples
Message-ID: <20241210144933.295798-1-james.clark@linaro.org>

Previously the sink had to be specified, but now it auto selects one by
default. Including a sink in the examples causes issues when copy
pasting the command because it might not work if that sink isn't
present. Remove the sink from all the basic examples and create a new
section specifically about overriding the default one.

Make the text a but more concise now that it's in the advanced section,
and similarly for removing the old kernel advice.

Signed-off-by: James Clark <james.clark at linaro.org>
---
 Documentation/trace/coresight/coresight.rst   | 41 ++++++++-----------
 .../userspace-api/perf_ring_buffer.rst        |  4 +-
 2 files changed, 18 insertions(+), 27 deletions(-)

diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst
index d4f93d6a2d63..806699871b80 100644
--- a/Documentation/trace/coresight/coresight.rst
+++ b/Documentation/trace/coresight/coresight.rst
@@ -462,44 +462,35 @@ queried by the perf command line tool:
 
 		cs_etm//                                    [Kernel PMU event]
 
-	linaro at linaro-nano:~$
-
 Regardless of the number of tracers available in a system (usually equal to the
 amount of processor cores), the "cs_etm" PMU will be listed only once.
 
 A Coresight PMU works the same way as any other PMU, i.e the name of the PMU is
-listed along with configuration options within forward slashes '/'.  Since a
-Coresight system will typically have more than one sink, the name of the sink to
-work with needs to be specified as an event option.
-On newer kernels the available sinks are listed in sysFS under
+provided along with configuration options within forward slashes '/' (see
+`Config option formats`_).
+
+Advanced Perf framework usage
+-----------------------------
+
+Sink selection
+~~~~~~~~~~~~~~
+
+An appropriate sink will be selected automatically for use with Perf, but since
+there will typically be more than one sink, the name of the sink to use may be
+specified as a special config option prefixed with '@'.
+
+The available sinks are listed in sysFS under
 ($SYSFS)/bus/event_source/devices/cs_etm/sinks/::
 
 	root at localhost:/sys/bus/event_source/devices/cs_etm/sinks# ls
 	tmc_etf0  tmc_etr0  tpiu0
 
-On older kernels, this may need to be found from the list of coresight devices,
-available under ($SYSFS)/bus/coresight/devices/::
-
-	root:~# ls /sys/bus/coresight/devices/
-	 etm0     etm1     etm2         etm3  etm4      etm5      funnel0
-	 funnel1  funnel2  replicator0  stm0  tmc_etf0  tmc_etr0  tpiu0
 	root at linaro-nano:~# perf record -e cs_etm/@tmc_etr0/u --per-thread program
 
-As mentioned above in section "Device Naming scheme", the names of the devices could
-look different from what is used in the example above. One must use the device names
-as it appears under the sysFS.
-
-The syntax within the forward slashes '/' is important.  The '@' character
-tells the parser that a sink is about to be specified and that this is the sink
-to use for the trace session.
-
 More information on the above and other example on how to use Coresight with
 the perf tools can be found in the "HOWTO.md" file of the openCSD gitHub
 repository [#third]_.
 
-Advanced perf framework usage
------------------------------
-
 AutoFDO analysis using the perf tools
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -508,7 +499,7 @@ perf can be used to record and analyze trace of programs.
 Execution can be recorded using 'perf record' with the cs_etm event,
 specifying the name of the sink to record to, e.g::
 
-    perf record -e cs_etm/@tmc_etr0/u --per-thread
+    perf record -e cs_etm//u --per-thread
 
 The 'perf report' and 'perf script' commands can be used to analyze execution,
 synthesizing instruction and branch events from the instruction trace.
@@ -572,7 +563,7 @@ sort example is from the AutoFDO tutorial (https://gcc.gnu.org/wiki/AutoFDO/Tuto
 	Bubble sorting array of 30000 elements
 	5910 ms
 
-	$ perf record -e cs_etm/@tmc_etr0/u --per-thread taskset -c 2 ./sort
+	$ perf record -e cs_etm//u --per-thread taskset -c 2 ./sort
 	Bubble sorting array of 30000 elements
 	12543 ms
 	[ perf record: Woken up 35 times to write data ]
diff --git a/Documentation/userspace-api/perf_ring_buffer.rst b/Documentation/userspace-api/perf_ring_buffer.rst
index bde9d8cbc106..dc71544532ce 100644
--- a/Documentation/userspace-api/perf_ring_buffer.rst
+++ b/Documentation/userspace-api/perf_ring_buffer.rst
@@ -627,7 +627,7 @@ regular ring buffer.
 AUX events and AUX trace data are two different things.  Let's see an
 example::
 
-        perf record -a -e cycles -e cs_etm/@tmc_etr0/ -- sleep 2
+        perf record -a -e cycles -e cs_etm// -- sleep 2
 
 The above command enables two events: one is the event *cycles* from PMU
 and another is the AUX event *cs_etm* from Arm CoreSight, both are saved
@@ -766,7 +766,7 @@ only record AUX trace data at a specific time point which users are
 interested in.  E.g. below gives an example of how to take snapshots
 with 1 second interval with Arm CoreSight::
 
-  perf record -e cs_etm/@tmc_etr0/u -S -a program &
+  perf record -e cs_etm//u -S -a program &
   PERFPID=$!
   while true; do
       kill -USR2 $PERFPID
-- 
2.34.1



From andi.shyti at kernel.org  Tue Dec 10 06:51:25 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Tue, 10 Dec 2024 15:51:25 +0100
Subject: [PATCH] i2c: pnx: Fix timeout in wait functions
In-Reply-To: <20241206231937.86408-1-ferr.lambarginio@gmail.com>
References: <20241206231937.86408-1-ferr.lambarginio@gmail.com>
Message-ID: <6vxpcoqf3npp46cajdsvrhaoiarprhfoyzb7k6qj32dwwot6ad@udg5sq3o3klh>

Hi Vladimir,

On Sat, Dec 07, 2024 at 12:19:34AM +0100, Vladimir Riabchun wrote:
> Since commit f63b94be6942 ("i2c: pnx: Fix potential deadlock warning
> from del_timer_sync() call in isr") jiffies are stored in
> i2c_pnx_algo_data.timeout, but wait_timeout and wait_reset are still
> using it as milliseconds. Convert jiffies back to milliseconds to wait
> for the expected amount of time.
> 
> Fixes: f63b94be6942 ("i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr")
> Signed-off-by: Vladimir Riabchun <ferr.lambarginio at gmail.com>

good catch! Merged to i2c/i2c-host-fixes.

Thanks,
Andi


From lkp at intel.com  Tue Dec 10 06:45:54 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 10 Dec 2024 22:45:54 +0800
Subject: [PATCH mm-unstable 13/17] mm: sparc64: Introduce arch_mmap_hint()
In-Reply-To: <20241210024119.2488608-14-kaleshsingh@google.com>
References: <20241210024119.2488608-14-kaleshsingh@google.com>
Message-ID: <202412102215.fF34r4Uo-lkp@intel.com>

Hi Kalesh,

kernel test robot noticed the following build warnings:

[auto build test WARNING on akpm-mm/mm-everything]

url:    https://github.com/intel-lab-lkp/linux/commits/Kalesh-Singh/mm-Introduce-generic_mmap_hint/20241210-104424
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20241210024119.2488608-14-kaleshsingh%40google.com
patch subject: [PATCH mm-unstable 13/17] mm: sparc64: Introduce arch_mmap_hint()
config: sparc-randconfig-002-20241210 (https://download.01.org/0day-ci/archive/20241210/202412102215.fF34r4Uo-lkp at intel.com/config)
compiler: sparc64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241210/202412102215.fF34r4Uo-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/202412102215.fF34r4Uo-lkp at intel.com/

All warnings (new ones prefixed by >>):

   arch/sparc/kernel/sys_sparc_64.c: In function 'arch_get_unmapped_area':
>> arch/sparc/kernel/sys_sparc_64.c:135:13: warning: variable 'do_color_align' set but not used [-Wunused-but-set-variable]
     135 |         int do_color_align;
         |             ^~~~~~~~~~~~~~


vim +/do_color_align +135 arch/sparc/kernel/sys_sparc_64.c

aef9ae8eac4116 arch/sparc/kernel/sys_sparc_64.c Kalesh Singh      2024-12-09  131  
25d4054cc97484 arch/sparc/kernel/sys_sparc_64.c Mark Brown        2024-09-04  132  unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  133  {
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  134  	unsigned long task_size = TASK_SIZE;
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16 @135  	int do_color_align;
b80fa3cbb78c0f arch/sparc/kernel/sys_sparc_64.c Rick Edgecombe    2024-03-25  136  	struct vm_unmapped_area_info info = {};
a8d457b29b017a arch/sparc/kernel/sys_sparc_64.c Oscar Salvador    2024-10-07  137  	bool file_hugepage = false;
a8d457b29b017a arch/sparc/kernel/sys_sparc_64.c Oscar Salvador    2024-10-07  138  
a8d457b29b017a arch/sparc/kernel/sys_sparc_64.c Oscar Salvador    2024-10-07  139  	if (filp && is_file_hugepages(filp))
a8d457b29b017a arch/sparc/kernel/sys_sparc_64.c Oscar Salvador    2024-10-07  140  		file_hugepage = true;
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  141  
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  142  	if (flags & MAP_FIXED) {
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  143  		/* We do not accept a shared mapping if it would violate
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  144  		 * cache aliasing constraints.
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  145  		 */
a8d457b29b017a arch/sparc/kernel/sys_sparc_64.c Oscar Salvador    2024-10-07  146  		if (!file_hugepage && (flags & MAP_SHARED) &&
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  147  		    ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  148  			return -EINVAL;
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  149  		return addr;
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  150  	}
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  151  
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  152  	if (test_thread_flag(TIF_32BIT))
d61e16df940e02 arch/sparc64/kernel/sys_sparc.c  David S. Miller   2006-03-17  153  		task_size = STACK_TOP32;
a91690ddd05ab0 arch/sparc64/kernel/sys_sparc.c  David S. Miller   2006-03-17  154  	if (unlikely(len > task_size || len >= VA_EXCLUDE_START))
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  155  		return -ENOMEM;
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  156  
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  157  	do_color_align = 0;
a8d457b29b017a arch/sparc/kernel/sys_sparc_64.c Oscar Salvador    2024-10-07  158  	if ((filp || (flags & MAP_SHARED)) && !file_hugepage)
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  159  		do_color_align = 1;
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  160  
aef9ae8eac4116 arch/sparc/kernel/sys_sparc_64.c Kalesh Singh      2024-12-09  161  	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
aef9ae8eac4116 arch/sparc/kernel/sys_sparc_64.c Kalesh Singh      2024-12-09  162  	if (addr)
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  163  		return addr;
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  164  
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  165  	info.length = len;
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  166  	info.low_limit = TASK_UNMAPPED_BASE;
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  167  	info.high_limit = min(task_size, VA_EXCLUDE_START);
a8d457b29b017a arch/sparc/kernel/sys_sparc_64.c Oscar Salvador    2024-10-07  168  	info.align_mask = get_align_mask(filp, flags);
a8d457b29b017a arch/sparc/kernel/sys_sparc_64.c Oscar Salvador    2024-10-07  169  	if (!file_hugepage)
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  170  		info.align_offset = pgoff << PAGE_SHIFT;
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  171  	addr = vm_unmapped_area(&info);
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  172  
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  173  	if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  174  		VM_BUG_ON(addr != -ENOMEM);
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  175  		info.low_limit = VA_EXCLUDE_END;
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  176  		info.high_limit = task_size;
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  177  		addr = vm_unmapped_area(&info);
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  178  	}
1363c3cd8603a9 arch/sparc64/kernel/sys_sparc.c  Wolfgang Wander   2005-06-21  179  
bb64f55019c7b0 arch/sparc/kernel/sys_sparc_64.c Michel Lespinasse 2012-12-11  180  	return addr;
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  181  }
^1da177e4c3f41 arch/sparc64/kernel/sys_sparc.c  Linus Torvalds    2005-04-16  182  

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


From mark.rutland at arm.com  Tue Dec 10 06:48:48 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Dec 2024 14:48:48 +0000
Subject: [PATCH] arm64/signal: Silence spurious sparse warning storing
 GCSPR_EL0
In-Reply-To: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
References: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
Message-ID: <Z1hU0Ii-Sm9NHnhj@J2N7QTR9R3>

On Tue, Dec 10, 2024 at 12:42:53AM +0000, Mark Brown wrote:
> We are seeing a false postive sparse warning in gcs_restore_signal()
> 
> arch/arm64/kernel/signal.c:1054:9: sparse: sparse: cast removes address space '__user' of expression

This isn't a false positive; this is a cross-address space cast that
sparse is accurately warning about. That might be *benign*, but the tool
is doing exactly what it is supposed to.

> when storing the final GCSPR_EL0 value back into the register, caused by
> the fact that write_sysreg_s() casts the value it writes to a u64 which
> sparse sees as discarding the __userness of the pointer. The magic for
> handling such situations with sparse is to cast the value to an unsigned
> long which sparse sees as a valid thing to do with __user pointers so add
> such a cast.

As a general note, casting to/from unsigned long or uintptr_t is a
special-case in sparse, and in general you should use __force to cast
across address spaces or to/from bitwise types, e.g.

	some_type *foo = ...;
	some_type __user *user_foo;

	user_foo = (__force some_type __user *)foo;

> While we're at it also remove spurious casts of the gcspr_el0 value as we
> manipulate it which were the result of bitrot as the code was tweaked in
> the long period it was out of tree.
> 
> Reported-by: kernel test robot <lkp at intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202412082005.OBJ0BbWs-lkp at intel.com/
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/kernel/signal.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 14ac6fdb872b9672e4b16a097f1b577aae8dec50..83ea7e5fd2b54566c6649b82b8570657a5711dd4 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -39,7 +39,7 @@
>  #ifdef CONFIG_ARM64_GCS
>  #define GCS_SIGNAL_CAP(addr) (((unsigned long)addr) & GCS_CAP_ADDR_MASK)
>  
> -static bool gcs_signal_cap_valid(u64 addr, u64 val)
> +static bool gcs_signal_cap_valid(unsigned long __user *addr, u64 val)
>  {
>  	return val == GCS_SIGNAL_CAP(addr);
>  }
> @@ -1094,15 +1094,15 @@ static int gcs_restore_signal(void)
>  	/*
>  	 * Check that the cap is the actual GCS before replacing it.
>  	 */
> -	if (!gcs_signal_cap_valid((u64)gcspr_el0, cap))
> +	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);
> +	put_user_gcs(0, gcspr_el0, &ret);
>  	if (ret != 0)
>  		return -EFAULT;
>  
> -	write_sysreg_s(gcspr_el0 + 1, SYS_GCSPR_EL0);
> +	write_sysreg_s((unsigned long)(gcspr_el0 + 1), SYS_GCSPR_EL0);

Only one line here wants a __user pointer, so wouldn't it be simpler to
pass 'gcspr_el0' as an integer type, and cast it at the point it's used
as an actual pointer, rather than the other way around?

Then you could also simplify gcs_restore_signal(), etc.

Similarly in map_shadow_stack(), it'd be simpler to treat cap_ptr as an
integer type.

Mark.

>  
>  	return 0;
>  }
> 
> ---
> base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
> change-id: 20241209-arm64-gcs-signal-sparse-53fa9cad67f7
> 
> Best regards,
> -- 
> Mark Brown <broonie at kernel.org>
> 
> 


From m.felsch at pengutronix.de  Tue Dec 10 06:49:38 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Tue, 10 Dec 2024 15:49:38 +0100
Subject: [PATCH 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <Z1hLlm75iGMogltc@lizhi-Precision-Tower-5810>
References: <20241209-imx91tmu-v1-0-7859c5387f31@nxp.com>
 <20241209-imx91tmu-v1-2-7859c5387f31@nxp.com>
 <20241210103646.7gblp7mzxbna5gas@pengutronix.de>
 <Z1hLlm75iGMogltc@lizhi-Precision-Tower-5810>
Message-ID: <20241210144938.zf3dkiubqhcxguqv@pengutronix.de>

On 24-12-10, Frank Li wrote:
> On Tue, Dec 10, 2024 at 11:36:46AM +0100, Marco Felsch wrote:
> > Hi,
> >
> > On 24-12-09, Frank Li wrote:

...

> > > +	/* disable the monitor during initialization */
> > > +	imx91_tmu_enable(tmu, false);
> > > +	imx91_tmu_start(tmu, false);
> >
> > Make use of pm_runtime?
> 
> thermal is always on after probe. continue measure tempature. So pm_runtime
> is not suitable for this case.

There are at least 3 drivers which use pm-runtime including the i.MX6/7
imx_thermal.c driver.

> > > +	ret = imx91_init_from_nvmem_cells(tmu);
> > > +	if (ret) {
> > > +		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
> > > +		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
> > > +	}
> > > +
> > > +	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
> > > +	rate = clk_get_rate(tmu->clk);
> > > +	div = (rate / 4000000) - 1;
> >
> > Would be nice to validate the div value before passing to the HW and if
> > the target rate of 4MHz can't be reached by the div you you should
> > return -EINVAL.
> >
> > > +
> > > +	/* Set divider value and enable divider */
> > > +	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
> > > +
> > > +	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
> > > +	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
> > > +
> > > +	/*
> > > +	 * Set resolution mode
> > > +	 * 00b - Conversion time = 0.59325 ms
> > > +	 * 01b - Conversion time = 1.10525 ms
> > > +	 * 10b - Conversion time = 2.12925 ms
> > > +	 * 11b - Conversion time = 4.17725 ms
> > > +	 */
> > > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
> > > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);
> > > +
> > > +	/*
> > > +	 * Set measure mode
> > > +	 * 00b - Single oneshot measurement
> > > +	 * 01b - Continuous measurement
> > > +	 * 10b - Periodic oneshot measurement
> > > +	 */
> >
> > For the resolution it's fine to have the values directly coded without a
> > define, but here we can definitly use a define and drop the comment.
> >
> > > +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, 0x3), tmu->base + CTRL1_CLR);
> > > +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, 0x1), tmu->base + CTRL1_SET);
> >
> > Why do we set it to periodic mode instead of the single-shot? At the
> > moment the device doesn't have IRQ support, and so there is no need to
> > run the measurements in background.
> 
> It is "continous measurement".  first clean MODE_MASK, then then 01.

Still, why? You return the temp value upon a request (get_temp). There
is no async notification from this driver to others. So it can be left
to single-shot and do the measurement on request (get_temp).

> _CLR means clean bits according to mask
> _SET means set bits according to mask.

I know.

Regards,
  Marco

> 
> Frank
> 
> >
> > > +
> > > +	/*
> > > +	 * Set Periodic Measurement Frequency to 25Hz:
> > > +	 * tMEAS_FREQ = tCONV_CLK * PERIOD_CTRL[MEAS_FREQ]. ->
> > > +	 * PERIOD_CTRL(MEAS_FREQ) = (1000 / 25) / (1000 / 4000000);
> > > +	 * Where tMEAS_FREQ = Measurement period and tCONV_CLK = 1/fCONV_CLK.
> > > +	 * This field should have value greater than count corresponds
> > > +	 * to time greater than summation of conversion time, power up
> > > +	 * delay, and six times of conversion clock time.
> > > +	 * tMEAS_FREQ > (tCONV + tPUD + 6 * tCONV_CLK).
> > > +	 * tCONV is conversion time determined by CTRL1[RESOLUTION].
> > > +	 */
> > > +	writel_relaxed(FIELD_PREP(MEAS_FREQ_MASK, 0x27100), tmu->base + PERIOD_CTRL);
> >
> > With the single-shot measurements we could remove this part and..
> >
> > > +
> > > +	/* enable the monitor */
> > > +	imx91_tmu_enable(tmu, true);
> > > +	imx91_tmu_start(tmu, true);
> >
> > this part as well.
> >
> > Regards,
> >   Marco
> >
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static void imx91_tmu_remove(struct platform_device *pdev)
> > > +{
> > > +	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
> > > +
> > > +	/* disable tmu */
> > > +	imx91_tmu_start(tmu, false);
> > > +	imx91_tmu_enable(tmu, false);
> > > +}
> > > +
> > > +static int __maybe_unused imx91_tmu_suspend(struct device *dev)
> > > +{
> > > +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> > > +
> > > +	/* disable tmu */
> > > +	imx91_tmu_start(tmu, false);
> > > +	imx91_tmu_enable(tmu, false);
> > > +
> > > +	clk_disable_unprepare(tmu->clk);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int __maybe_unused imx91_tmu_resume(struct device *dev)
> > > +{
> > > +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> > > +	int ret;
> > > +
> > > +	ret = clk_prepare_enable(tmu->clk);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	imx91_tmu_enable(tmu, true);
> > > +	imx91_tmu_start(tmu, true);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static SIMPLE_DEV_PM_OPS(imx91_tmu_pm_ops,
> > > +			 imx91_tmu_suspend, imx91_tmu_resume);
> > > +
> > > +static const struct of_device_id imx91_tmu_table[] = {
> > > +	{ .compatible = "fsl,imx91-tmu", },
> > > +	{ },
> > > +};
> > > +MODULE_DEVICE_TABLE(of, imx91_tmu_table);
> > > +
> > > +static struct platform_driver imx91_tmu = {
> > > +	.driver = {
> > > +		.name	= "i.MX91_thermal",
> > > +		.pm	= pm_ptr(&imx91_tmu_pm_ops),
> > > +		.of_match_table = imx91_tmu_table,
> > > +	},
> > > +	.probe = imx91_tmu_probe,
> > > +	.remove = imx91_tmu_remove,
> > > +};
> > > +module_platform_driver(imx91_tmu);
> > > +
> > > +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> > > +MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
> > > +MODULE_LICENSE("GPL");
> > >
> > > --
> > > 2.34.1
> > >
> > >
> > >
> 


From helgaas at kernel.org  Tue Dec 10 06:53:35 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 10 Dec 2024 08:53:35 -0600
Subject: [PATCH] perf/dwc_pcie: Qualify RAS DES VSEC Capability by
 Vendor, Revision
In-Reply-To: <5a1ef0d2-be24-4865-8e23-159d001ac6d6@linux.alibaba.com>
Message-ID: <20241210145335.GA3239578@bhelgaas>

On Tue, Dec 10, 2024 at 08:04:17PM +0800, Shuai Xue wrote:
> ? 2024/12/10 06:29, Bjorn Helgaas ??:
> > From: Bjorn Helgaas <bhelgaas at google.com>
> > 
> > PCI Vendor-Specific (VSEC) Capabilities are defined by each vendor.
> > Devices from different vendors may advertise a VSEC Capability with the DWC
> > RAS DES functionality, but the vendors may assign different VSEC IDs.
> > 
> > Search for the DWC RAS DES Capability using the VSEC ID and VSEC Rev
> > chosen by the vendor.

> > -	for (vid = dwc_pcie_vendor_ids; vid->vendor_id; vid++) {
> > +	for (vid = dwc_pcie_pmu_vsec_ids; vid->vendor_id; vid++) {
> 
> How about checking the pdev->vendor with vid->vendor_id before
> search the vesc cap?
> 
> +		if (pdev->vendor != vid->vendor_id)
> +			continue;

Every user of VSEC needs to specify the (Vendor ID, VSEC ID) and
verify that the Vendor ID matches the device Vendor ID, so
pci_find_vsec_capability() does this check internally, so I don't
think we need to do it here.

> >   		vsec = pci_find_vsec_capability(pdev, vid->vendor_id,
> > -						DWC_PCIE_VSEC_RAS_DES_ID);
> > -		if (vsec)
> > -			break;
> > +						vid->vsec_id);



From tabba at google.com  Tue Dec 10 06:56:05 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 14:56:05 +0000
Subject: [PATCH v2 12/18] KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
In-Reply-To: <20241203103735.2267589-13-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-13-qperret@google.com>
Message-ID: <CA+EHjTwNgf5fPuWMaPaN4mcdd5y4uydJsXi-zEBatFnbwoaLLQ@mail.gmail.com>

Hi Quentin,

On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
>
> Introduce a new hypercall allowing the host to relax the stage-2
> permissions of mappings in a non-protected guest page-table. It will be
> used later once we start allowing RO memslots and dirty logging.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 20 ++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 23 +++++++++++++++++++
>  4 files changed, 45 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 0b6c4d325134..5d51933e44fb 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -67,6 +67,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_guest_perms,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index e528a42ed60e..db0dd83c2457 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -41,6 +41,7 @@ int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
>  int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
> +int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);

The parameters are the same as __pkvm_host_share_guest, but in a
different order. I looked ahead at later patches in the series, and similar
issues regarding parameter type and ordering, so I won't mention it
for the later patches.


>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 04a9053ae1d5..60dd56bbd743 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -267,6 +267,25 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) =  ret;
>  }
>
> +static void handle___pkvm_host_relax_guest_perms(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(u64, gfn, host_ctxt, 1);
> +       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 2);
> +       struct pkvm_hyp_vcpu *hyp_vcpu;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> +       if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> +               goto out;
> +
> +       ret = __pkvm_host_relax_guest_perms(gfn, prot, hyp_vcpu);
> +out:
> +       cpu_reg(host_ctxt, 1) = ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -478,6 +497,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_unshare_hyp),
>         HANDLE_FUNC(__pkvm_host_share_guest),
>         HANDLE_FUNC(__pkvm_host_unshare_guest),
> +       HANDLE_FUNC(__pkvm_host_relax_guest_perms),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index aa27a3e42e5e..d4b28e93e790 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1480,3 +1480,26 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm)
>
>         return ret;
>  }
> +
> +int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu)
> +{
> +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       u64 phys;
> +       int ret;
> +
> +       if ((prot & KVM_PGTABLE_PROT_RWX) != prot)
> +               return -EPERM;

Why not

+       if (prot & ~KVM_PGTABLE_PROT_RWX)

Simpler and consistent with similar checks in the file (e.g.,
__pkvm_host_share_guest)

Cheers,
/fuad


> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __check_host_unshare_guest(vm, &phys, ipa);
> +       if (!ret)
> +               ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0);
> +
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> --
> 2.47.0.338.g60cca15819-goog
>


From heiko at sntech.de  Tue Dec 10 07:03:06 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 10 Dec 2024 16:03:06 +0100
Subject: [PATCH v5 13/18] drm/rockchip: vop2: Introduce vop hardware version
In-Reply-To: <20241209123330.2781991-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209123330.2781991-1-andyshrk@163.com>
Message-ID: <8259618.JRmrKFJ9eK@diego>

Am Montag, 9. Dezember 2024, 13:33:29 CET schrieb Andy Yan:
> From: Andy Yan <andy.yan at rock-chips.com>
> 
> There is a version number hardcoded in the VOP VERSION_INFO
> register, and the version number increments sequentially based
> on the production order of the SOC.
> 
> So using this version number to distinguish different VOP features
> will simplify the code.
> 
> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
> Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
> Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

> @@ -798,6 +798,7 @@ static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
>  static void vop2_enable(struct vop2 *vop2)
>  {
>  	int ret;
> +	u32 version;
>  
>  	ret = pm_runtime_resume_and_get(vop2->dev);
>  	if (ret < 0) {
> @@ -817,10 +818,19 @@ static void vop2_enable(struct vop2 *vop2)
>  		return;
>  	}
>  
> +	version = vop2_readl(vop2, RK3568_VERSION_INFO);
> +	if (version != vop2->version) {
> +		drm_err(vop2->drm, "Hardware version(0x%08x) mismatch\n", version);
> +		return;
> +	}

style-nit: please add a blank line here.

> +	/*
> +	 * rk3566 share the same vop version with rk3568, so
> +	 * wen need to use soc_id for identification here.
> +	 */
>  	if (vop2->data->soc_id == 3566)
>  		vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
>  

otherwise, looks good.

Thanks
Heiko




From tabba at google.com  Tue Dec 10 07:06:53 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 15:06:53 +0000
Subject: [PATCH v2 13/18] KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
In-Reply-To: <20241203103735.2267589-14-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-14-qperret@google.com>
Message-ID: <CA+EHjTx-MZHKwkGYPU+yN-CDkNh1kxTXN8FWTeaPfM95OSkjcQ@mail.gmail.com>

Hi Quentin,

On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
>
> Introduce a new hypercall to remove the write permission from a
> non-protected guest stage-2 mapping. This will be used for e.g. enabling
> dirty logging.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 24 +++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 +++++++++++++++
>  4 files changed, 45 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 5d51933e44fb..4d7d20ea03df 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -68,6 +68,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_guest_perms,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index db0dd83c2457..8658b5932473 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -42,6 +42,7 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
>  int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>  int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);
> +int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 60dd56bbd743..3feaf2119e51 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -286,6 +286,29 @@ static void handle___pkvm_host_relax_guest_perms(struct kvm_cpu_context *host_ct
>         cpu_reg(host_ctxt, 1) = ret;
>  }
>
> +static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> +       struct pkvm_hyp_vm *hyp_vm;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vm = get_pkvm_hyp_vm(handle);
> +       if (!hyp_vm)
> +               goto out;
> +       if (pkvm_hyp_vm_is_protected(hyp_vm))
> +               goto put_hyp_vm;

These checks are (unsurprisingly) the same for all these functions.
Does it make sense to have a helper do these checks?

Cheers,
/fuad

> +       ret = __pkvm_host_wrprotect_guest(gfn, hyp_vm);
> +put_hyp_vm:
> +       put_pkvm_hyp_vm(hyp_vm);
> +out:
> +       cpu_reg(host_ctxt, 1) = ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -498,6 +521,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_share_guest),
>         HANDLE_FUNC(__pkvm_host_unshare_guest),
>         HANDLE_FUNC(__pkvm_host_relax_guest_perms),
> +       HANDLE_FUNC(__pkvm_host_wrprotect_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index d4b28e93e790..89312d7cde2a 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1503,3 +1503,22 @@ int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pk
>
>         return ret;
>  }
> +
> +int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
> +{
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       u64 phys;
> +       int ret;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __check_host_unshare_guest(vm, &phys, ipa);
> +       if (!ret)
> +               ret = kvm_pgtable_stage2_wrprotect(&vm->pgt, ipa, PAGE_SIZE);
> +
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> --
> 2.47.0.338.g60cca15819-goog
>


From tabba at google.com  Tue Dec 10 07:11:53 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 15:11:53 +0000
Subject: [PATCH v2 14/18] KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
In-Reply-To: <20241203103735.2267589-15-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-15-qperret@google.com>
Message-ID: <CA+EHjTwV2mXOXMF7u+pVaSqvJ2c-iPGMxPBhrj7oZrm+oaAi3A@mail.gmail.com>

Hi Quentin,

On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
>
> Plumb the kvm_stage2_test_clear_young() callback into pKVM for
> non-protected guest. It will be later be called from MMU notifiers.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 25 +++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 ++++++++++++++
>  4 files changed, 46 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 4d7d20ea03df..cb676017d591 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -69,6 +69,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_guest_perms,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 8658b5932473..554ce31882e6 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -43,6 +43,7 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum k
>  int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>  int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);
>  int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
> +int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);

While I'm piling on the function names/parameters, some functions have
_guest as a postfix at the end (e.g., this one), others have it in the
middle (__pkvm_host_relax_guest_perms). I guess
__pkvm_host_relax_guest_perms is the odd one out. Could you rename it?

Cheers,
/fuad


>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 3feaf2119e51..67cb6e284180 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -309,6 +309,30 @@ static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt
>         cpu_reg(host_ctxt, 1) = ret;
>  }
>
> +static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> +       DECLARE_REG(bool, mkold, host_ctxt, 3);
> +       struct pkvm_hyp_vm *hyp_vm;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vm = get_pkvm_hyp_vm(handle);
> +       if (!hyp_vm)
> +               goto out;
> +       if (pkvm_hyp_vm_is_protected(hyp_vm))
> +               goto put_hyp_vm;
> +
> +       ret = __pkvm_host_test_clear_young_guest(gfn, mkold, hyp_vm);
> +put_hyp_vm:
> +       put_pkvm_hyp_vm(hyp_vm);
> +out:
> +       cpu_reg(host_ctxt, 1) = ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -522,6 +546,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_unshare_guest),
>         HANDLE_FUNC(__pkvm_host_relax_guest_perms),
>         HANDLE_FUNC(__pkvm_host_wrprotect_guest),
> +       HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 89312d7cde2a..0e064a7ed7c4 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1522,3 +1522,22 @@ int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
>
>         return ret;
>  }
> +
> +int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm)
> +{
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       u64 phys;
> +       int ret;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __check_host_unshare_guest(vm, &phys, ipa);
> +       if (!ret)
> +               ret = kvm_pgtable_stage2_test_clear_young(&vm->pgt, ipa, PAGE_SIZE, mkold);
> +
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> --
> 2.47.0.338.g60cca15819-goog
>


From tabba at google.com  Tue Dec 10 07:14:03 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 15:14:03 +0000
Subject: [PATCH v2 15/18] KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
In-Reply-To: <20241203103735.2267589-16-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-16-qperret@google.com>
Message-ID: <CA+EHjTzOjwNyUkS5_zSUiAbiCauLKKgkKU6TM_-+Wsh9A0FdRQ@mail.gmail.com>

Hi Quentin,

On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
>
> Plumb the kvm_pgtable_stage2_mkyoung() callback into pKVM for
> non-protected guests. It will be called later from the fault handling
> path.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 19 ++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 20 +++++++++++++++++++
>  4 files changed, 41 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index cb676017d591..6178e12a0dbc 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -70,6 +70,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_guest_perms,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_mkyoung_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 554ce31882e6..3ae0c3ecff48 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -44,6 +44,7 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>  int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);
>  int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>  int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
> +int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 67cb6e284180..de0012a75827 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -333,6 +333,24 @@ static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *ho
>         cpu_reg(host_ctxt, 1) = ret;
>  }
>
> +static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(u64, gfn, host_ctxt, 1);
> +       struct pkvm_hyp_vcpu *hyp_vcpu;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> +       if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> +               goto out;
> +
> +       ret = __pkvm_host_mkyoung_guest(gfn, hyp_vcpu);
> +out:
> +       cpu_reg(host_ctxt, 1) =  ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -547,6 +565,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_relax_guest_perms),
>         HANDLE_FUNC(__pkvm_host_wrprotect_guest),
>         HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
> +       HANDLE_FUNC(__pkvm_host_mkyoung_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 0e064a7ed7c4..7605bd7f80b5 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1541,3 +1541,23 @@ int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *
>
>         return ret;
>  }
> +
> +int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu)
> +{
> +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       u64 phys;
> +       int ret;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __check_host_unshare_guest(vm, &phys, ipa);

While I'm bikeshedding some more, does the name
__check_host_unshare_guest() make sense? Should it be something like
__check_host_changeperm_guest(), or something along those lines? (feel
free to ignore this :) )

Thanks,
/fuad

> +       if (!ret)
> +               kvm_pgtable_stage2_mkyoung(&vm->pgt, ipa, 0);
> +
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> --
> 2.47.0.338.g60cca15819-goog
>


From qperret at google.com  Tue Dec 10 07:15:54 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 10 Dec 2024 15:15:54 +0000
Subject: [PATCH v2 01/18] KVM: arm64: Change the layout of enum
 pkvm_page_state
In-Reply-To: <CA+EHjTxfchr+ggO_z_zrrFTrFpS3oTJXt13t-854xWxYY=oSQQ@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-2-qperret@google.com>
 <CA+EHjTxfchr+ggO_z_zrrFTrFpS3oTJXt13t-854xWxYY=oSQQ@mail.gmail.com>
Message-ID: <Z1hbKrUPXdEokXpP@google.com>

Hey Fuad,

On Tuesday 10 Dec 2024 at 12:59:44 (+0000), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Tue, 3 Dec 2024 at 10:37, Quentin Perret <qperret at google.com> wrote:
> >
> > The 'concrete' (a.k.a non-meta) page states are currently encoded using
> > software bits in PTEs. For performance reasons, the abstract
> > pkvm_page_state enum uses the same bits to encode these states as that
> > makes conversions from and to PTEs easy.
> >
> > In order to prepare the ground for moving the 'concrete' state storage
> > to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this
> > purpose.
> >
> > No functional changes intended.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 17 ++++++++++-------
> >  1 file changed, 10 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > index 0972faccc2af..ca3177481b78 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > @@ -24,25 +24,28 @@
> >   */
> >  enum pkvm_page_state {
> >         PKVM_PAGE_OWNED                 = 0ULL,
> > -       PKVM_PAGE_SHARED_OWNED          = KVM_PGTABLE_PROT_SW0,
> > -       PKVM_PAGE_SHARED_BORROWED       = KVM_PGTABLE_PROT_SW1,
> > -       __PKVM_PAGE_RESERVED            = KVM_PGTABLE_PROT_SW0 |
> > -                                         KVM_PGTABLE_PROT_SW1,
> > +       PKVM_PAGE_SHARED_OWNED          = BIT(0),
> > +       PKVM_PAGE_SHARED_BORROWED       = BIT(1),
> > +       __PKVM_PAGE_RESERVED            = BIT(0) | BIT(1),
> >
> >         /* Meta-states which aren't encoded directly in the PTE's SW bits */
> > -       PKVM_NOPAGE,
> > +       PKVM_NOPAGE                     = BIT(2),
> >  };
> > +#define PKVM_PAGE_META_STATES_MASK     (~(BIT(0) | BIT(1)))
> >
> >  #define PKVM_PAGE_STATE_PROT_MASK      (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
> >  static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
> >                                                  enum pkvm_page_state state)
> >  {
> > -       return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
> > +       BUG_ON(state & PKVM_PAGE_META_STATES_MASK);
> 
> This is a slight change in functionality, having a BUG_ON instead of
> just masking out illegal states. Is it necessary?

Yep, this is arguably a bit zealous. Passing e.g. PKVM_NOPAGE to
pkvm_mkstate() would be properly bogus, so having a WARN_ON() or
BUG_ON() in there is still a good thing, but it should be done in a
separate patch.

I'll rework in v3.

> > +       prot &= ~PKVM_PAGE_STATE_PROT_MASK;
> > +       prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
> > +       return prot;
> >  }
> >
> >  static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
> >  {
> > -       return prot & PKVM_PAGE_STATE_PROT_MASK;
> > +       return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
> >  }
> >
> >  struct host_mmu {
> > --
> > 2.47.0.338.g60cca15819-goog
> >


From tabba at google.com  Tue Dec 10 07:23:02 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 15:23:02 +0000
Subject: [PATCH v2 16/18] KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
In-Reply-To: <20241203103735.2267589-17-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-17-qperret@google.com>
Message-ID: <CA+EHjTw_e_q5TFkgxvVDKxwj-C5S0Hd1OfVO4_FitrB8_J2Rpw@mail.gmail.com>

Hi Quentin,

On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
>
> Introduce a new hypercall to flush the TLBs of non-protected guests. The
> host kernel will be responsible for issuing this hypercall after changing
> stage-2 permissions using the __pkvm_host_relax_guest_perms() or
> __pkvm_host_wrprotect_guest() paths. This is left under the host's
> responsibility for performance reasons.
>
> Note however that the TLB maintenance for all *unmap* operations still
> remains entirely under the hypervisor's responsibility for security
> reasons -- an unmapped page may be donated to another entity, so a stale
> TLB entry could be used to leak private data.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h   |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c | 17 +++++++++++++++++
>  2 files changed, 18 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 6178e12a0dbc..df6237d0459c 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -87,6 +87,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
>         __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
>         __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
>  };
>
>  #define DECLARE_KVM_VHE_SYM(sym)       extern char sym[]
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index de0012a75827..219d7fb850ec 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -398,6 +398,22 @@ static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
>         __kvm_tlb_flush_vmid(kern_hyp_va(mmu));
>  }
>
> +static void handle___pkvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +       struct pkvm_hyp_vm *hyp_vm;
> +
> +       if (!is_protected_kvm_enabled())
> +               return;
> +
> +       hyp_vm = get_pkvm_hyp_vm(handle);
> +       if (!hyp_vm)
> +               return;
> +
> +       __kvm_tlb_flush_vmid(&hyp_vm->kvm.arch.mmu);
> +       put_pkvm_hyp_vm(hyp_vm);
> +}

Since this is practically the same as kvm_tlb_flush_vmid(), does it
make sense to modify that instead (handle___kvm_tlb_flush_vmid()) to
do the right thing depending on whether pkvm is enabled? Thinking as
well for the future in case we want to support the rest of the
kvm_tlb_flush_vmid_*().

Cheers,
/fuad

> +
>  static void handle___kvm_flush_cpu_context(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1);
> @@ -582,6 +598,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_teardown_vm),
>         HANDLE_FUNC(__pkvm_vcpu_load),
>         HANDLE_FUNC(__pkvm_vcpu_put),
> +       HANDLE_FUNC(__pkvm_tlb_flush_vmid),
>  };
>
>  static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> --
> 2.47.0.338.g60cca15819-goog
>


From qperret at google.com  Tue Dec 10 07:29:54 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 10 Dec 2024 15:29:54 +0000
Subject: [PATCH v2 04/18] KVM: arm64: Move host page ownership tracking
 to the hyp vmemmap
In-Reply-To: <CA+EHjTx13V1BcyWEAjNSC0JCxr+dSUvutC7z2KSRu_8jwV_Vxw@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-5-qperret@google.com>
 <CA+EHjTx13V1BcyWEAjNSC0JCxr+dSUvutC7z2KSRu_8jwV_Vxw@mail.gmail.com>
Message-ID: <Z1heckLsqrCBF6Nw@google.com>

Hey Fuad,

On Tuesday 10 Dec 2024 at 13:02:45 (+0000), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Tue, 3 Dec 2024 at 10:37, Quentin Perret <qperret at google.com> wrote:
> >
> > We currently store part of the page-tracking state in PTE software bits
> > for the host, guests and the hypervisor. This is sub-optimal when e.g.
> > sharing pages as this forces to break block mappings purely to support
> > this software tracking. This causes an unnecessarily fragmented stage-2
> > page-table for the host in particular when it shares pages with Secure,
> > which can lead to measurable regressions. Moreover, having this state
> > stored in the page-table forces us to do multiple costly walks on the
> > page transition path, hence causing overhead.
> >
> > In order to work around these problems, move the host-side page-tracking
> > logic from SW bits in its stage-2 PTEs to the hypervisor's vmemmap.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/nvhe/memory.h |  6 +-
> >  arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 94 ++++++++++++++++--------
> >  arch/arm64/kvm/hyp/nvhe/setup.c          |  7 +-
> >  3 files changed, 71 insertions(+), 36 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > index 88cb8ff9e769..08f3a0416d4c 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > @@ -8,7 +8,7 @@
> >  #include <linux/types.h>
> >
> >  /*
> > - * SW bits 0-1 are reserved to track the memory ownership state of each page:
> > + * Bits 0-1 are reserved to track the memory ownership state of each page:
> >   *   00: The page is owned exclusively by the page-table owner.
> >   *   01: The page is owned by the page-table owner, but is shared
> >   *       with another entity.
> 
> Not shown in this patch, but a couple of lines below, you might want
> to update the comment on PKVM_NOPAGE to fix the reference to "PTE's SW
> bits":

I actually think the comment is still correct -- PKVM_NOPAGE never goes
in the software bits, with or without this patch, so I figured we could
leave it as-is. But happy to reword if you have a good idea :)

> > /* Meta-states which aren't encoded directly in the PTE's SW bits */
> > PKVM_NOPAGE = BIT(2),
> 
> > @@ -44,7 +44,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
> >  struct hyp_page {
> >         u16 refcount;
> >         u8 order;
> > -       u8 reserved;
> > +
> > +       /* Host (non-meta) state. Guarded by the host stage-2 lock. */
> > +       enum pkvm_page_state host_state : 8;
> >  };
> >
> >  extern u64 __hyp_vmemmap;
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > index caba3e4bd09e..1595081c4f6b 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > @@ -201,8 +201,8 @@ static void *guest_s2_zalloc_page(void *mc)
> >
> >         memset(addr, 0, PAGE_SIZE);
> >         p = hyp_virt_to_page(addr);
> > -       memset(p, 0, sizeof(*p));
> >         p->refcount = 1;
> > +       p->order = 0;
> >
> >         return addr;
> >  }
> > @@ -268,6 +268,7 @@ int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd)
> >
> >  void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
> >  {
> > +       struct hyp_page *page;
> >         void *addr;
> >
> >         /* Dump all pgtable pages in the hyp_pool */
> > @@ -279,7 +280,9 @@ void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
> >         /* Drain the hyp_pool into the memcache */
> >         addr = hyp_alloc_pages(&vm->pool, 0);
> >         while (addr) {
> > -               memset(hyp_virt_to_page(addr), 0, sizeof(struct hyp_page));
> > +               page = hyp_virt_to_page(addr);
> > +               page->refcount = 0;
> > +               page->order = 0;
> >                 push_hyp_memcache(mc, addr, hyp_virt_to_phys);
> >                 WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1));
> >                 addr = hyp_alloc_pages(&vm->pool, 0);
> > @@ -382,19 +385,25 @@ bool addr_is_memory(phys_addr_t phys)
> >         return !!find_mem_range(phys, &range);
> >  }
> >
> > -static bool addr_is_allowed_memory(phys_addr_t phys)
> > +static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
> > +{
> > +       return range->start <= addr && addr < range->end;
> > +}
> > +
> > +static int range_is_allowed_memory(u64 start, u64 end)
> 
> The name of this function "range_*is*_..." implies that it returns a
> boolean, which other functions in this file (and patch) with similar
> names do, but it returns an error instead. Maybe
> check_range_allowed_memory)?

Ack, I'll rename in v3.

> >  {
> >         struct memblock_region *reg;
> >         struct kvm_mem_range range;
> >
> > -       reg = find_mem_range(phys, &range);
> > +       /* Can't check the state of both MMIO and memory regions at once */
> 
> I don't understand this comment in relation to the code. Could you
> explain it to me please?

find_mem_range() will iterate the list of memblocks to find the 'range'
in which @start falls. That might either be in a memblock (so @addr is
memory, and @reg != NULL) or outside of one (so @addr is mmio, and
@reg == NULL). The check right after ensures that @end is in the same
PA range as @start. IOW, this checks that [start, end[ doesn't overlap
memory and MMIO, because the following logic wouldn't work for a mixed
case like that.

> > +       reg = find_mem_range(start, &range);
> > +       if (!is_in_mem_range(end - 1, &range))
> > +               return -EINVAL;
> >
> > -       return reg && !(reg->flags & MEMBLOCK_NOMAP);
> > -}
> > +       if (!reg || reg->flags & MEMBLOCK_NOMAP)
> > +               return -EPERM;
> >
> > -static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
> > -{
> > -       return range->start <= addr && addr < range->end;
> > +       return 0;
> >  }
> >
> >  static bool range_is_memory(u64 start, u64 end)
> > @@ -454,8 +463,11 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
> >         if (kvm_pte_valid(pte))
> >                 return -EAGAIN;
> >
> > -       if (pte)
> > +       if (pte) {
> > +               WARN_ON(addr_is_memory(addr) &&
> > +                       !(hyp_phys_to_page(addr)->host_state & PKVM_NOPAGE));
> 
> nit: since the host state is now an enum, should this just be an
> equality check rather than an &? This makes it consistent with other
> checks of pkvm_page_state in this patch too.

We don't currently have a state that is additive to PKVM_NOPAGE, so no
objection from me.

> >                 return -EPERM;
> > +       }
> >
> >         do {
> >                 u64 granule = kvm_granule_size(level);
> > @@ -477,10 +489,29 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
> >         return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
> >  }
> >
> > +static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm_page_state state)
> > +{
> > +       phys_addr_t end = addr + size;
> 
> nit: newline
> 
> > +       for (; addr < end; addr += PAGE_SIZE)
> > +               hyp_phys_to_page(addr)->host_state = state;
> > +}
> > +
> >  int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
> >  {
> > -       return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
> > -                              addr, size, &host_s2_pool, owner_id);
> > +       int ret;
> > +
> > +       ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
> > +                             addr, size, &host_s2_pool, owner_id);
> > +       if (ret || !addr_is_memory(addr))
> > +               return ret;
> 
> Can hyp set an owner for an address that isn't memory? Trying to
> understand why we need to update the host stage2 pagetable but not the
> hypervisor's vmemmap in that case.

I think the answer is not currently, but we will when we'll have to e.g.
donate IOMMU registers to EL2 and things of that nature. Note that this
does require an extension to __host_check_page_state_range() to go query
the page-table 'the old way' for MMIO addresses, though that isn't done
in this series. If you think strongly that this is confusing, I'm happy
to drop that check and we'll add it back with the IOMMU series or
something like that.

> > +
> > +       /* Don't forget to update the vmemmap tracking for the host */
> > +       if (owner_id == PKVM_ID_HOST)
> > +               __host_update_page_state(addr, size, PKVM_PAGE_OWNED);
> > +       else
> > +               __host_update_page_state(addr, size, PKVM_NOPAGE);
> > +
> > +       return 0;
> >  }
> >
> >  static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
> > @@ -604,35 +635,38 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size,
> >         return kvm_pgtable_walk(pgt, addr, size, &walker);
> >  }
> >
> > -static enum pkvm_page_state host_get_page_state(kvm_pte_t pte, u64 addr)
> > -{
> > -       if (!addr_is_allowed_memory(addr))
> > -               return PKVM_NOPAGE;
> > -
> > -       if (!kvm_pte_valid(pte) && pte)
> > -               return PKVM_NOPAGE;
> > -
> > -       return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
> > -}
> > -
> >  static int __host_check_page_state_range(u64 addr, u64 size,
> >                                          enum pkvm_page_state state)
> >  {
> > -       struct check_walk_data d = {
> > -               .desired        = state,
> > -               .get_page_state = host_get_page_state,
> > -       };
> > +       u64 end = addr + size;
> > +       int ret;
> > +
> > +       ret = range_is_allowed_memory(addr, end);
> > +       if (ret)
> > +               return ret;
> >
> >         hyp_assert_lock_held(&host_mmu.lock);
> > -       return check_page_state_range(&host_mmu.pgt, addr, size, &d);
> > +       for (; addr < end; addr += PAGE_SIZE) {
> > +               if (hyp_phys_to_page(addr)->host_state != state)
> > +                       return -EPERM;
> > +       }
> > +
> > +       return 0;
> >  }
> >
> >  static int __host_set_page_state_range(u64 addr, u64 size,
> >                                        enum pkvm_page_state state)
> >  {
> > -       enum kvm_pgtable_prot prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, state);
> > +       if (hyp_phys_to_page(addr)->host_state & PKVM_NOPAGE) {
> 
> Same nit as above regarding checking for PKVM_NOPAGE
> 
> Cheers,
> /fuad
> 
> 
> > +               int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT);
> >
> > -       return host_stage2_idmap_locked(addr, size, prot);
> > +               if (ret)
> > +                       return ret;
> > +       }
> > +
> > +       __host_update_page_state(addr, size, state);
> > +
> > +       return 0;
> >  }
> >
> >  static int host_request_owned_transition(u64 *completer_addr,
> > diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> > index cbdd18cd3f98..7e04d1c2a03d 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> > @@ -180,7 +180,6 @@ static void hpool_put_page(void *addr)
> >  static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
> >                                      enum kvm_pgtable_walk_flags visit)
> >  {
> > -       enum kvm_pgtable_prot prot;
> >         enum pkvm_page_state state;
> >         phys_addr_t phys;
> >
> > @@ -203,16 +202,16 @@ static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
> >         case PKVM_PAGE_OWNED:
> >                 return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP);
> >         case PKVM_PAGE_SHARED_OWNED:
> > -               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED);
> > +               hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_BORROWED;
> >                 break;
> >         case PKVM_PAGE_SHARED_BORROWED:
> > -               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
> > +               hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_OWNED;
> >                 break;
> >         default:
> >                 return -EINVAL;
> >         }
> >
> > -       return host_stage2_idmap_locked(phys, PAGE_SIZE, prot);
> > +       return 0;
> >  }
> >
> >  static int fix_hyp_pgtable_refcnt_walker(const struct kvm_pgtable_visit_ctx *ctx,
> > --
> > 2.47.0.338.g60cca15819-goog
> >


From frieder.schrempf at kontron.de  Tue Dec 10 07:36:41 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Tue, 10 Dec 2024 16:36:41 +0100
Subject: [PATCH v2 03/11] dt-bindings: regulator: pca9450: Document
 nxp,sd-vsel-fixed-low property for LDO5
In-Reply-To: <20241128-endanger-envy-d1b19f650b38@spud>
References: <20241127164337.613915-1-frieder@fris.de>
 <20241127164337.613915-4-frieder@fris.de>
 <20241128-endanger-envy-d1b19f650b38@spud>
Message-ID: <9276fad1-0e3c-4935-a62a-1580af2e0a4b@kontron.de>

On 28.11.24 6:33 PM, Conor Dooley wrote:
> On Wed, Nov 27, 2024 at 05:42:19PM +0100, Frieder Schrempf wrote:
>> From: Frieder Schrempf <frieder.schrempf at kontron.de>
>>
>> This new property can be used for boards which have the SD_VSEL tied
>> to a fixed low level. The voltage of LDO5 is therefore only controlled
>> by writing to the LDO5CTRL_L register.
>>
>> Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
>> ---
>> Changes for v2:
>> * new patch
>> ---
>>  .../bindings/regulator/nxp,pca9450-regulator.yaml           | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
>> index 5d0d684186c96..0e19c54aa5f8a 100644
>> --- a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
>> +++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
>> @@ -49,6 +49,12 @@ properties:
>>            Properties for single LDO5 regulator.
>>  
>>          properties:
>> +          nxp,sd-vsel-fixed-low:
>> +            type: boolean
>> +            description:
>> +              Let the driver know that SD_VSEL is hardwired to low level and
>> +              there is no GPIO to get the actual value from.
> 
> Does this mean that if you don't provide the property or a GPIO it is tied
> high or High-Z? If so, please mention it here. More likely, given the
> context of this patch, no gpio and no tied low property means the driver
> should handle things as they used to be - but you should call that out
> in your commit message to be clear.

Providing neither 'sd-vsel-gpios', nor 'nxp,sd-vsel-fixed-low' means the
driver has to assume that SD_VSEL is tied high and it has to use the
LDO5CTRL_H for voltage control.

I will make this more clear in the commit message.

This is the original/current behavior of the driver, though it doesn't
match the actual hardware as all known boards actually have the SD_VSEL
connected to the USDHC_VSELECT (which changes state whenever the USDHC
controller wants to switch IO voltage).

Getting rid of this mismatch is one of the main motivations for this series.

> 
>> +
>>            sd-vsel-gpios:
>>              description:
>>                GPIO that can be used to read the current status of the SD_VSEL
>> -- 
>> 2.46.1
>>



From helgaas at kernel.org  Tue Dec 10 07:42:56 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 10 Dec 2024 09:42:56 -0600
Subject: [PATCH] PCI: j721e: In j721e_pcie_suspend_noirq() check
 reset_gpio before to use it
In-Reply-To: <20241209112321.65320-1-thomas.richard@bootlin.com>
Message-ID: <20241210154256.GA3242512@bhelgaas>

On Mon, Dec 09, 2024 at 12:23:21PM +0100, Thomas Richard wrote:
> The reset_gpio is optional, so in j721e_pcie_suspend_noirq() check if it is
> not NULL before to use it.

If you have occasion to post a v2, update subject to:

  PCI: j721e: Check reset_gpio for NULL before using it

s/before to use it/before using it/

Did you trip over a NULL pointer dereference here?  Or maybe found via
inspection?

It looks like gpiod_set_value_cansleep(desc) *should* be a no-op if
desc is NULL, based on this comment [1]:

 * This descriptor validation needs to be inserted verbatim into each
 * function taking a descriptor, so we need to use a preprocessor
 * macro to avoid endless duplication. If the desc is NULL it is an
 * optional GPIO and calls should just bail out.

and the fact that the VALIDATE_DESC_VOID() macro looks like it would
return early in that case.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpio/gpiolib.c?id=v6.12#n2316

> Fixes: c538d40f365b ("PCI: j721e: Add suspend and resume support")
> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
> ---
>  drivers/pci/controller/cadence/pci-j721e.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
> index 0341d51d6aed..5bc14dd70811 100644
> --- a/drivers/pci/controller/cadence/pci-j721e.c
> +++ b/drivers/pci/controller/cadence/pci-j721e.c
> @@ -644,7 +644,9 @@ 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);
> +		if (pcie->reset_gpio)
> +			gpiod_set_value_cansleep(pcie->reset_gpio, 0);
> +
>  		clk_disable_unprepare(pcie->refclk);
>  	}
>  
> -- 
> 2.39.5
> 


From qperret at google.com  Tue Dec 10 07:41:17 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 10 Dec 2024 15:41:17 +0000
Subject: [PATCH v2 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <CA+EHjTwHSyQ1FJc7axbLNuBxSWpRVE6brb34nO+F59=QRmfQEg@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-11-qperret@google.com>
 <CA+EHjTwHSyQ1FJc7axbLNuBxSWpRVE6brb34nO+F59=QRmfQEg@mail.gmail.com>
Message-ID: <Z1hhHRdpCZcLs046@google.com>

On Tuesday 10 Dec 2024 at 13:58:42 (+0000), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Tue, 3 Dec 2024 at 10:37, Quentin Perret <qperret at google.com> wrote:
> >
> > In preparation for handling guest stage-2 mappings at EL2, introduce a
> > new pKVM hypercall allowing to share pages with non-protected guests.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_asm.h              |  1 +
> >  arch/arm64/include/asm/kvm_host.h             |  3 +
> >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
> >  arch/arm64/kvm/hyp/include/nvhe/memory.h      |  2 +
> >  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 34 +++++++++
> >  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 70 +++++++++++++++++++
> >  arch/arm64/kvm/hyp/nvhe/pkvm.c                |  7 ++
> >  7 files changed, 118 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > index 89c0fac69551..449337f5b2a3 100644
> > --- a/arch/arm64/include/asm/kvm_asm.h
> > +++ b/arch/arm64/include/asm/kvm_asm.h
> > @@ -65,6 +65,7 @@ enum __kvm_host_smccc_func {
> >         /* Hypercalls available after pKVM finalisation */
> >         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
> >         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
> > +       __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> >         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
> >         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
> >         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index e18e9244d17a..f75988e3515b 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -771,6 +771,9 @@ struct kvm_vcpu_arch {
> >         /* Cache some mmu pages needed inside spinlock regions */
> >         struct kvm_mmu_memory_cache mmu_page_cache;
> >
> > +       /* Pages to be donated to pkvm/EL2 if it runs out */
> 
> Runs out of what? :) I'm being facetious, it's just that the comment
> is a bit unclear.

	/* Pages to top-up the pKVM/EL2 guest pool */

Is that any better?

> > +       struct kvm_hyp_memcache pkvm_memcache;
> > +
> >         /* Virtual SError ESR to restore when HCR_EL2.VSE is set */
> >         u64 vsesr_el2;
> >
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > index 25038ac705d8..a7976e50f556 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > @@ -39,6 +39,7 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages);
> >  int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
> >  int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
> >  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
> > +int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
> >
> >  bool addr_is_memory(phys_addr_t phys);
> >  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > index 08f3a0416d4c..457318215155 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > @@ -47,6 +47,8 @@ struct hyp_page {
> >
> >         /* Host (non-meta) state. Guarded by the host stage-2 lock. */
> >         enum pkvm_page_state host_state : 8;
> > +
> > +       u32 host_share_guest_count;
> >  };
> >
> >  extern u64 __hyp_vmemmap;
> > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > index 95d78db315b3..d659462fbf5d 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > @@ -211,6 +211,39 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
> >         cpu_reg(host_ctxt, 1) =  ret;
> >  }
> >
> > +static int pkvm_refill_memcache(struct pkvm_hyp_vcpu *hyp_vcpu)
> > +{
> > +       struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
> > +
> > +       return refill_memcache(&hyp_vcpu->vcpu.arch.pkvm_memcache,
> > +                              host_vcpu->arch.pkvm_memcache.nr_pages,
> > +                              &host_vcpu->arch.pkvm_memcache);
> > +}
> > +
> > +static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
> > +{
> > +       DECLARE_REG(u64, pfn, host_ctxt, 1);
> > +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> > +       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 3);
> > +       struct pkvm_hyp_vcpu *hyp_vcpu;
> > +       int ret = -EINVAL;
> > +
> > +       if (!is_protected_kvm_enabled())
> > +               goto out;
> > +
> > +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> > +       if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> > +               goto out;
> > +
> > +       ret = pkvm_refill_memcache(hyp_vcpu);
> > +       if (ret)
> > +               goto out;
> > +
> > +       ret = __pkvm_host_share_guest(pfn, gfn, hyp_vcpu, prot);
> > +out:
> > +       cpu_reg(host_ctxt, 1) =  ret;
> > +}
> > +
> >  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
> >  {
> >         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> > @@ -420,6 +453,7 @@ static const hcall_t host_hcall[] = {
> >
> >         HANDLE_FUNC(__pkvm_host_share_hyp),
> >         HANDLE_FUNC(__pkvm_host_unshare_hyp),
> > +       HANDLE_FUNC(__pkvm_host_share_guest),
> >         HANDLE_FUNC(__kvm_adjust_pc),
> >         HANDLE_FUNC(__kvm_vcpu_run),
> >         HANDLE_FUNC(__kvm_flush_vm_context),
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > index 1595081c4f6b..a69d7212b64c 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > @@ -861,6 +861,27 @@ static int hyp_complete_donation(u64 addr,
> >         return pkvm_create_mappings_locked(start, end, prot);
> >  }
> >
> > +static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr)
> > +{
> > +       if (!kvm_pte_valid(pte))
> > +               return PKVM_NOPAGE;
> > +
> > +       return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
> > +}
> > +
> > +static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
> > +                                         u64 size, enum pkvm_page_state state)
> > +{
> > +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> > +       struct check_walk_data d = {
> > +               .desired        = state,
> > +               .get_page_state = guest_get_page_state,
> > +       };
> > +
> > +       hyp_assert_lock_held(&vm->lock);
> > +       return check_page_state_range(&vm->pgt, addr, size, &d);
> > +}
> > +
> >  static int check_share(struct pkvm_mem_share *share)
> >  {
> >         const struct pkvm_mem_transition *tx = &share->tx;
> > @@ -1343,3 +1364,52 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
> >
> >         return ret;
> >  }
> > +
> > +int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
> > +                           enum kvm_pgtable_prot prot)
> > +{
> > +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> > +       u64 phys = hyp_pfn_to_phys(pfn);
> > +       u64 ipa = hyp_pfn_to_phys(gfn);
> > +       struct hyp_page *page;
> > +       int ret;
> > +
> > +       if (prot & ~KVM_PGTABLE_PROT_RWX)
> > +               return -EINVAL;
> > +
> > +       ret = range_is_allowed_memory(phys, phys + PAGE_SIZE);
> > +       if (ret)
> > +               return ret;
> > +
> > +       host_lock_component();
> > +       guest_lock_component(vm);
> > +
> > +       ret = __guest_check_page_state_range(vcpu, ipa, PAGE_SIZE, PKVM_NOPAGE);
> > +       if (ret)
> > +               goto unlock;
> > +
> > +       page = hyp_phys_to_page(phys);
> > +       switch (page->host_state) {
> > +       case PKVM_PAGE_OWNED:
> > +               WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_OWNED));
> > +               break;
> > +       case PKVM_PAGE_SHARED_OWNED:
> > +               /* Only host to np-guest multi-sharing is tolerated */
> 
> Initially I thought the comment was related to the warning below,
> which confused me.

It actually is about the warning below :-)

> Now I think what you're trying to say is that we'll
> allow the share, and the (unrelated to the comment) warning is to
> ensure that the PKVM_PAGE_SHARED_OWNED is consistent with the share
> count.

So, the only case where the host should ever attempt do use
__pkvm_host_share_guest() on a page that is already shared is for a page
already shared *with an np-guest*. The page->host_share_guest_count being
elevated is the easiest way to check that the page is indeed in that
state, hence the warning.

If for example the host was trying to share with an np-guest a page that
is currently shared with the hypervisor, that check would fail. We can
discuss whether or not we would want to allow it, but for now there is
strictly no need for it so I went with the restrictive option. We can
relax that constraint later if need be.

> I think what you should have here, which would work better with the
> comment, is something like:
> 
>                 /* Only host to np-guest multi-sharing is tolerated */
> +               if (pkvm_hyp_vcpu_is_protected(vcpu))
> +                       return -EPERM;
> 
> That would even make the comment unnecessary.

I would prefer not adding this here, handle___pkvm_host_share_guest() in
hyp-main.c already does that for us.

> 
> > +               WARN_ON(!page->host_share_guest_count);
> > +               break;
> > +       default:
> > +               ret = -EPERM;
> > +               goto unlock;
> > +       }
> > +
> > +       WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys,
> > +                                      pkvm_mkstate(prot, PKVM_PAGE_SHARED_BORROWED),
> > +                                      &vcpu->vcpu.arch.pkvm_memcache, 0));
> > +       page->host_share_guest_count++;
> > +
> > +unlock:
> > +       guest_unlock_component(vm);
> > +       host_unlock_component();
> > +
> > +       return ret;
> > +}
> > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > index d5c23449a64c..d6c61a5e7b6e 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > @@ -795,6 +795,13 @@ int __pkvm_teardown_vm(pkvm_handle_t handle)
> >         /* Push the metadata pages to the teardown memcache */
> >         for (idx = 0; idx < hyp_vm->nr_vcpus; ++idx) {
> >                 struct pkvm_hyp_vcpu *hyp_vcpu = hyp_vm->vcpus[idx];
> > +               struct kvm_hyp_memcache *vcpu_mc = &hyp_vcpu->vcpu.arch.pkvm_memcache;
> > +
> > +               while (vcpu_mc->nr_pages) {
> > +                       void *addr = pop_hyp_memcache(vcpu_mc, hyp_phys_to_virt);
> 
> nit: newline
> 
> Cheers,
> /fuad
> 
> 
> 
> > +                       push_hyp_memcache(mc, addr, hyp_virt_to_phys);
> > +                       unmap_donated_memory_noclear(addr, PAGE_SIZE);
> > +               }
> >
> >                 teardown_donated_memory(mc, hyp_vcpu, sizeof(*hyp_vcpu));
> >         }
> > --
> > 2.47.0.338.g60cca15819-goog
> >


From xiaolei.wang at windriver.com  Tue Dec 10 07:40:39 2024
From: xiaolei.wang at windriver.com (wang xiaolei)
Date: Wed, 11 Dec 2024 02:40:39 +1100
Subject: [PATCH v2] serial: imx: Use uart_port_lock_irq() instead of
 uart_port_lock()
In-Reply-To: <CAOMZO5AzNVd_xut2wBBHeyccFdC+1c4p50Uhzo=+BDbV=mEP2g@mail.gmail.com>
References: <20241210034223.1493522-1-xiaolei.wang@windriver.com>
 <CAOMZO5AzNVd_xut2wBBHeyccFdC+1c4p50Uhzo=+BDbV=mEP2g@mail.gmail.com>
Message-ID: <6ecc80c1-8422-48d5-97f7-dcc0f8d49466@windriver.com>


On 12/10/24 9:37 PM, Fabio Estevam wrote:
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> On Tue, Dec 10, 2024 at 12:43?AM Xiaolei Wang
> <xiaolei.wang at windriver.com> wrote:
>> When executing 'ehco mem > /sys/power/state', the following
> ehco --> echo

Thanks, I will update the commit log in the next version


thanks

xiaolei

>
> Reviewed-by: Fabio Estevam <festevam at gmail.com>


From broonie at kernel.org  Tue Dec 10 07:44:29 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 15:44:29 +0000
Subject: [PATCH] arm64/signal: Silence spurious sparse warning storing
 GCSPR_EL0
In-Reply-To: <Z1hU0Ii-Sm9NHnhj@J2N7QTR9R3>
References: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
 <Z1hU0Ii-Sm9NHnhj@J2N7QTR9R3>
Message-ID: <20c12aac-193e-43ae-9418-39db1af4ede9@sirena.org.uk>

On Tue, Dec 10, 2024 at 02:48:48PM +0000, Mark Rutland wrote:
> On Tue, Dec 10, 2024 at 12:42:53AM +0000, Mark Brown wrote:
> > We are seeing a false postive sparse warning in gcs_restore_signal()
> > 
> > arch/arm64/kernel/signal.c:1054:9: sparse: sparse: cast removes address space '__user' of expression

> This isn't a false positive; this is a cross-address space cast that
> sparse is accurately warning about. That might be *benign*, but the tool
> is doing exactly what it is supposed to.

The spuriousness is arguable, from my point of view it's spurious in
that we don't have the type of the system register we're writing to.

> > +	write_sysreg_s((unsigned long)(gcspr_el0 + 1), SYS_GCSPR_EL0);

> Only one line here wants a __user pointer, so wouldn't it be simpler to
> pass 'gcspr_el0' as an integer type, and cast it at the point it's used
> as an actual pointer, rather than the other way around?

> Then you could also simplify gcs_restore_signal(), etc.

I find it both safer and clearer to keep values which are userspace
pointers as userspace pointers rather than working with them as
integers, using integers just sets off alarm bells.  

> Similarly in map_shadow_stack(), it'd be simpler to treat cap_ptr as an
> integer type.

With map_shadow_stack() it's a bit of an issue with letting users
specify a size but yeah, we could do better 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/20241210/2dba754c/attachment.sig>

From tabba at google.com  Tue Dec 10 07:46:57 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 15:46:57 +0000
Subject: [PATCH v2 04/18] KVM: arm64: Move host page ownership tracking to
 the hyp vmemmap
In-Reply-To: <Z1heckLsqrCBF6Nw@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-5-qperret@google.com>
 <CA+EHjTx13V1BcyWEAjNSC0JCxr+dSUvutC7z2KSRu_8jwV_Vxw@mail.gmail.com> <Z1heckLsqrCBF6Nw@google.com>
Message-ID: <CA+EHjTxiDiZ4P2AVSDErUfr612Ov0UZira+9qQkRQJK_Ki7uug@mail.gmail.com>

Hi Quentin,

On Tue, 10 Dec 2024 at 15:29, Quentin Perret <qperret at google.com> wrote:
>
> Hey Fuad,
>
> On Tuesday 10 Dec 2024 at 13:02:45 (+0000), Fuad Tabba wrote:
> > Hi Quentin,
> >
> > On Tue, 3 Dec 2024 at 10:37, Quentin Perret <qperret at google.com> wrote:
> > >
> > > We currently store part of the page-tracking state in PTE software bits
> > > for the host, guests and the hypervisor. This is sub-optimal when e.g.
> > > sharing pages as this forces to break block mappings purely to support
> > > this software tracking. This causes an unnecessarily fragmented stage-2
> > > page-table for the host in particular when it shares pages with Secure,
> > > which can lead to measurable regressions. Moreover, having this state
> > > stored in the page-table forces us to do multiple costly walks on the
> > > page transition path, hence causing overhead.
> > >
> > > In order to work around these problems, move the host-side page-tracking
> > > logic from SW bits in its stage-2 PTEs to the hypervisor's vmemmap.
> > >
> > > Signed-off-by: Quentin Perret <qperret at google.com>
> > > ---
> > >  arch/arm64/kvm/hyp/include/nvhe/memory.h |  6 +-
> > >  arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 94 ++++++++++++++++--------
> > >  arch/arm64/kvm/hyp/nvhe/setup.c          |  7 +-
> > >  3 files changed, 71 insertions(+), 36 deletions(-)
> > >
> > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > > index 88cb8ff9e769..08f3a0416d4c 100644
> > > --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > > +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > > @@ -8,7 +8,7 @@
> > >  #include <linux/types.h>
> > >
> > >  /*
> > > - * SW bits 0-1 are reserved to track the memory ownership state of each page:
> > > + * Bits 0-1 are reserved to track the memory ownership state of each page:
> > >   *   00: The page is owned exclusively by the page-table owner.
> > >   *   01: The page is owned by the page-table owner, but is shared
> > >   *       with another entity.
> >
> > Not shown in this patch, but a couple of lines below, you might want
> > to update the comment on PKVM_NOPAGE to fix the reference to "PTE's SW
> > bits":
>
> I actually think the comment is still correct -- PKVM_NOPAGE never goes
> in the software bits, with or without this patch, so I figured we could
> leave it as-is. But happy to reword if you have a good idea :)

I see, no, that's fine.

> > > /* Meta-states which aren't encoded directly in the PTE's SW bits */
> > > PKVM_NOPAGE = BIT(2),
> >
> > > @@ -44,7 +44,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
> > >  struct hyp_page {
> > >         u16 refcount;
> > >         u8 order;
> > > -       u8 reserved;
> > > +
> > > +       /* Host (non-meta) state. Guarded by the host stage-2 lock. */
> > > +       enum pkvm_page_state host_state : 8;
> > >  };
> > >
> > >  extern u64 __hyp_vmemmap;
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > index caba3e4bd09e..1595081c4f6b 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > @@ -201,8 +201,8 @@ static void *guest_s2_zalloc_page(void *mc)
> > >
> > >         memset(addr, 0, PAGE_SIZE);
> > >         p = hyp_virt_to_page(addr);
> > > -       memset(p, 0, sizeof(*p));
> > >         p->refcount = 1;
> > > +       p->order = 0;
> > >
> > >         return addr;
> > >  }
> > > @@ -268,6 +268,7 @@ int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd)
> > >
> > >  void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
> > >  {
> > > +       struct hyp_page *page;
> > >         void *addr;
> > >
> > >         /* Dump all pgtable pages in the hyp_pool */
> > > @@ -279,7 +280,9 @@ void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
> > >         /* Drain the hyp_pool into the memcache */
> > >         addr = hyp_alloc_pages(&vm->pool, 0);
> > >         while (addr) {
> > > -               memset(hyp_virt_to_page(addr), 0, sizeof(struct hyp_page));
> > > +               page = hyp_virt_to_page(addr);
> > > +               page->refcount = 0;
> > > +               page->order = 0;
> > >                 push_hyp_memcache(mc, addr, hyp_virt_to_phys);
> > >                 WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1));
> > >                 addr = hyp_alloc_pages(&vm->pool, 0);
> > > @@ -382,19 +385,25 @@ bool addr_is_memory(phys_addr_t phys)
> > >         return !!find_mem_range(phys, &range);
> > >  }
> > >
> > > -static bool addr_is_allowed_memory(phys_addr_t phys)
> > > +static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
> > > +{
> > > +       return range->start <= addr && addr < range->end;
> > > +}
> > > +
> > > +static int range_is_allowed_memory(u64 start, u64 end)
> >
> > The name of this function "range_*is*_..." implies that it returns a
> > boolean, which other functions in this file (and patch) with similar
> > names do, but it returns an error instead. Maybe
> > check_range_allowed_memory)?
>
> Ack, I'll rename in v3.
>
> > >  {
> > >         struct memblock_region *reg;
> > >         struct kvm_mem_range range;
> > >
> > > -       reg = find_mem_range(phys, &range);
> > > +       /* Can't check the state of both MMIO and memory regions at once */
> >
> > I don't understand this comment in relation to the code. Could you
> > explain it to me please?
>
> find_mem_range() will iterate the list of memblocks to find the 'range'
> in which @start falls. That might either be in a memblock (so @addr is
> memory, and @reg != NULL) or outside of one (so @addr is mmio, and
> @reg == NULL). The check right after ensures that @end is in the same
> PA range as @start. IOW, this checks that [start, end[ doesn't overlap
> memory and MMIO, because the following logic wouldn't work for a mixed
> case like that.

I understand now. I think it might be worth elaborating a bit on the
comment to clarify that. What is confusing to me was that the comment
refers to checking state, but it's in a function that does not care
about page state, i.e., it's not immediately obvious that its primary
callers/users are __host_check_page_state_range(), and other functions
that check the state of a range.

> > > +       reg = find_mem_range(start, &range);
> > > +       if (!is_in_mem_range(end - 1, &range))
> > > +               return -EINVAL;
> > >
> > > -       return reg && !(reg->flags & MEMBLOCK_NOMAP);
> > > -}
> > > +       if (!reg || reg->flags & MEMBLOCK_NOMAP)
> > > +               return -EPERM;
> > >
> > > -static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
> > > -{
> > > -       return range->start <= addr && addr < range->end;
> > > +       return 0;
> > >  }
> > >
> > >  static bool range_is_memory(u64 start, u64 end)
> > > @@ -454,8 +463,11 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
> > >         if (kvm_pte_valid(pte))
> > >                 return -EAGAIN;
> > >
> > > -       if (pte)
> > > +       if (pte) {
> > > +               WARN_ON(addr_is_memory(addr) &&
> > > +                       !(hyp_phys_to_page(addr)->host_state & PKVM_NOPAGE));
> >
> > nit: since the host state is now an enum, should this just be an
> > equality check rather than an &? This makes it consistent with other
> > checks of pkvm_page_state in this patch too.
>
> We don't currently have a state that is additive to PKVM_NOPAGE, so no
> objection from me.
>
> > >                 return -EPERM;
> > > +       }
> > >
> > >         do {
> > >                 u64 granule = kvm_granule_size(level);
> > > @@ -477,10 +489,29 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
> > >         return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
> > >  }
> > >
> > > +static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm_page_state state)
> > > +{
> > > +       phys_addr_t end = addr + size;
> >
> > nit: newline
> >
> > > +       for (; addr < end; addr += PAGE_SIZE)
> > > +               hyp_phys_to_page(addr)->host_state = state;
> > > +}
> > > +
> > >  int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
> > >  {
> > > -       return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
> > > -                              addr, size, &host_s2_pool, owner_id);
> > > +       int ret;
> > > +
> > > +       ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
> > > +                             addr, size, &host_s2_pool, owner_id);
> > > +       if (ret || !addr_is_memory(addr))
> > > +               return ret;
> >
> > Can hyp set an owner for an address that isn't memory? Trying to
> > understand why we need to update the host stage2 pagetable but not the
> > hypervisor's vmemmap in that case.
>
> I think the answer is not currently, but we will when we'll have to e.g.
> donate IOMMU registers to EL2 and things of that nature. Note that this
> does require an extension to __host_check_page_state_range() to go query
> the page-table 'the old way' for MMIO addresses, though that isn't done
> in this series. If you think strongly that this is confusing, I'm happy
> to drop that check and we'll add it back with the IOMMU series or
> something like that.

I think it's worth a comment if you're not dropping the check..

>
> > > +
> > > +       /* Don't forget to update the vmemmap tracking for the host */
> > > +       if (owner_id == PKVM_ID_HOST)
> > > +               __host_update_page_state(addr, size, PKVM_PAGE_OWNED);
> > > +       else
> > > +               __host_update_page_state(addr, size, PKVM_NOPAGE);
> > > +
> > > +       return 0;
> > >  }
> > >
> > >  static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
> > > @@ -604,35 +635,38 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size,
> > >         return kvm_pgtable_walk(pgt, addr, size, &walker);
> > >  }
> > >
> > > -static enum pkvm_page_state host_get_page_state(kvm_pte_t pte, u64 addr)
> > > -{
> > > -       if (!addr_is_allowed_memory(addr))
> > > -               return PKVM_NOPAGE;
> > > -
> > > -       if (!kvm_pte_valid(pte) && pte)
> > > -               return PKVM_NOPAGE;
> > > -
> > > -       return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
> > > -}
> > > -
> > >  static int __host_check_page_state_range(u64 addr, u64 size,
> > >                                          enum pkvm_page_state state)
> > >  {
> > > -       struct check_walk_data d = {
> > > -               .desired        = state,
> > > -               .get_page_state = host_get_page_state,
> > > -       };
> > > +       u64 end = addr + size;
> > > +       int ret;
> > > +
> > > +       ret = range_is_allowed_memory(addr, end);
> > > +       if (ret)
> > > +               return ret;
> > >
> > >         hyp_assert_lock_held(&host_mmu.lock);
> > > -       return check_page_state_range(&host_mmu.pgt, addr, size, &d);
> > > +       for (; addr < end; addr += PAGE_SIZE) {
> > > +               if (hyp_phys_to_page(addr)->host_state != state)
> > > +                       return -EPERM;
> > > +       }
> > > +
> > > +       return 0;
> > >  }
> > >
> > >  static int __host_set_page_state_range(u64 addr, u64 size,
> > >                                        enum pkvm_page_state state)
> > >  {
> > > -       enum kvm_pgtable_prot prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, state);
> > > +       if (hyp_phys_to_page(addr)->host_state & PKVM_NOPAGE) {
> >
> > Same nit as above regarding checking for PKVM_NOPAGE
> >
> > Cheers,
> > /fuad
> >
> >
> > > +               int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT);
> > >
> > > -       return host_stage2_idmap_locked(addr, size, prot);
> > > +               if (ret)
> > > +                       return ret;
> > > +       }
> > > +
> > > +       __host_update_page_state(addr, size, state);
> > > +
> > > +       return 0;
> > >  }
> > >
> > >  static int host_request_owned_transition(u64 *completer_addr,
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> > > index cbdd18cd3f98..7e04d1c2a03d 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> > > @@ -180,7 +180,6 @@ static void hpool_put_page(void *addr)
> > >  static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
> > >                                      enum kvm_pgtable_walk_flags visit)
> > >  {
> > > -       enum kvm_pgtable_prot prot;
> > >         enum pkvm_page_state state;
> > >         phys_addr_t phys;
> > >
> > > @@ -203,16 +202,16 @@ static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
> > >         case PKVM_PAGE_OWNED:
> > >                 return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP);
> > >         case PKVM_PAGE_SHARED_OWNED:
> > > -               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED);
> > > +               hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_BORROWED;
> > >                 break;
> > >         case PKVM_PAGE_SHARED_BORROWED:
> > > -               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
> > > +               hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_OWNED;
> > >                 break;
> > >         default:
> > >                 return -EINVAL;
> > >         }
> > >
> > > -       return host_stage2_idmap_locked(phys, PAGE_SIZE, prot);
> > > +       return 0;
> > >  }
> > >
> > >  static int fix_hyp_pgtable_refcnt_walker(const struct kvm_pgtable_visit_ctx *ctx,
> > > --
> > > 2.47.0.338.g60cca15819-goog
> > >


From tabba at google.com  Tue Dec 10 07:51:01 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 15:51:01 +0000
Subject: [PATCH v2 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <Z1hhHRdpCZcLs046@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-11-qperret@google.com>
 <CA+EHjTwHSyQ1FJc7axbLNuBxSWpRVE6brb34nO+F59=QRmfQEg@mail.gmail.com> <Z1hhHRdpCZcLs046@google.com>
Message-ID: <CA+EHjTw4GX3j_ssN-tWnf780xkvyKO5mBN6fnvXeWvQcBDmcNg@mail.gmail.com>

On Tue, 10 Dec 2024 at 15:41, Quentin Perret <qperret at google.com> wrote:
>
> On Tuesday 10 Dec 2024 at 13:58:42 (+0000), Fuad Tabba wrote:
> > Hi Quentin,
> >
> > On Tue, 3 Dec 2024 at 10:37, Quentin Perret <qperret at google.com> wrote:
> > >
> > > In preparation for handling guest stage-2 mappings at EL2, introduce a
> > > new pKVM hypercall allowing to share pages with non-protected guests.
> > >
> > > Signed-off-by: Quentin Perret <qperret at google.com>
> > > ---
> > >  arch/arm64/include/asm/kvm_asm.h              |  1 +
> > >  arch/arm64/include/asm/kvm_host.h             |  3 +
> > >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
> > >  arch/arm64/kvm/hyp/include/nvhe/memory.h      |  2 +
> > >  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 34 +++++++++
> > >  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 70 +++++++++++++++++++
> > >  arch/arm64/kvm/hyp/nvhe/pkvm.c                |  7 ++
> > >  7 files changed, 118 insertions(+)
> > >
> > > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > > index 89c0fac69551..449337f5b2a3 100644
> > > --- a/arch/arm64/include/asm/kvm_asm.h
> > > +++ b/arch/arm64/include/asm/kvm_asm.h
> > > @@ -65,6 +65,7 @@ enum __kvm_host_smccc_func {
> > >         /* Hypercalls available after pKVM finalisation */
> > >         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
> > >         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
> > > +       __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> > >         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
> > >         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
> > >         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > > index e18e9244d17a..f75988e3515b 100644
> > > --- a/arch/arm64/include/asm/kvm_host.h
> > > +++ b/arch/arm64/include/asm/kvm_host.h
> > > @@ -771,6 +771,9 @@ struct kvm_vcpu_arch {
> > >         /* Cache some mmu pages needed inside spinlock regions */
> > >         struct kvm_mmu_memory_cache mmu_page_cache;
> > >
> > > +       /* Pages to be donated to pkvm/EL2 if it runs out */
> >
> > Runs out of what? :) I'm being facetious, it's just that the comment
> > is a bit unclear.
>
>         /* Pages to top-up the pKVM/EL2 guest pool */
>
> Is that any better?
>
> > > +       struct kvm_hyp_memcache pkvm_memcache;
> > > +
> > >         /* Virtual SError ESR to restore when HCR_EL2.VSE is set */
> > >         u64 vsesr_el2;
> > >
> > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > > index 25038ac705d8..a7976e50f556 100644
> > > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > > @@ -39,6 +39,7 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages);
> > >  int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
> > >  int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
> > >  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
> > > +int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
> > >
> > >  bool addr_is_memory(phys_addr_t phys);
> > >  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > > index 08f3a0416d4c..457318215155 100644
> > > --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > > +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > > @@ -47,6 +47,8 @@ struct hyp_page {
> > >
> > >         /* Host (non-meta) state. Guarded by the host stage-2 lock. */
> > >         enum pkvm_page_state host_state : 8;
> > > +
> > > +       u32 host_share_guest_count;
> > >  };
> > >
> > >  extern u64 __hyp_vmemmap;
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > > index 95d78db315b3..d659462fbf5d 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > > @@ -211,6 +211,39 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
> > >         cpu_reg(host_ctxt, 1) =  ret;
> > >  }
> > >
> > > +static int pkvm_refill_memcache(struct pkvm_hyp_vcpu *hyp_vcpu)
> > > +{
> > > +       struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
> > > +
> > > +       return refill_memcache(&hyp_vcpu->vcpu.arch.pkvm_memcache,
> > > +                              host_vcpu->arch.pkvm_memcache.nr_pages,
> > > +                              &host_vcpu->arch.pkvm_memcache);
> > > +}
> > > +
> > > +static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
> > > +{
> > > +       DECLARE_REG(u64, pfn, host_ctxt, 1);
> > > +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> > > +       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 3);
> > > +       struct pkvm_hyp_vcpu *hyp_vcpu;
> > > +       int ret = -EINVAL;
> > > +
> > > +       if (!is_protected_kvm_enabled())
> > > +               goto out;
> > > +
> > > +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> > > +       if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> > > +               goto out;
> > > +
> > > +       ret = pkvm_refill_memcache(hyp_vcpu);
> > > +       if (ret)
> > > +               goto out;
> > > +
> > > +       ret = __pkvm_host_share_guest(pfn, gfn, hyp_vcpu, prot);
> > > +out:
> > > +       cpu_reg(host_ctxt, 1) =  ret;
> > > +}
> > > +
> > >  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
> > >  {
> > >         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> > > @@ -420,6 +453,7 @@ static const hcall_t host_hcall[] = {
> > >
> > >         HANDLE_FUNC(__pkvm_host_share_hyp),
> > >         HANDLE_FUNC(__pkvm_host_unshare_hyp),
> > > +       HANDLE_FUNC(__pkvm_host_share_guest),
> > >         HANDLE_FUNC(__kvm_adjust_pc),
> > >         HANDLE_FUNC(__kvm_vcpu_run),
> > >         HANDLE_FUNC(__kvm_flush_vm_context),
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > index 1595081c4f6b..a69d7212b64c 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > @@ -861,6 +861,27 @@ static int hyp_complete_donation(u64 addr,
> > >         return pkvm_create_mappings_locked(start, end, prot);
> > >  }
> > >
> > > +static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr)
> > > +{
> > > +       if (!kvm_pte_valid(pte))
> > > +               return PKVM_NOPAGE;
> > > +
> > > +       return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
> > > +}
> > > +
> > > +static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
> > > +                                         u64 size, enum pkvm_page_state state)
> > > +{
> > > +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> > > +       struct check_walk_data d = {
> > > +               .desired        = state,
> > > +               .get_page_state = guest_get_page_state,
> > > +       };
> > > +
> > > +       hyp_assert_lock_held(&vm->lock);
> > > +       return check_page_state_range(&vm->pgt, addr, size, &d);
> > > +}
> > > +
> > >  static int check_share(struct pkvm_mem_share *share)
> > >  {
> > >         const struct pkvm_mem_transition *tx = &share->tx;
> > > @@ -1343,3 +1364,52 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
> > >
> > >         return ret;
> > >  }
> > > +
> > > +int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
> > > +                           enum kvm_pgtable_prot prot)
> > > +{
> > > +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> > > +       u64 phys = hyp_pfn_to_phys(pfn);
> > > +       u64 ipa = hyp_pfn_to_phys(gfn);
> > > +       struct hyp_page *page;
> > > +       int ret;
> > > +
> > > +       if (prot & ~KVM_PGTABLE_PROT_RWX)
> > > +               return -EINVAL;
> > > +
> > > +       ret = range_is_allowed_memory(phys, phys + PAGE_SIZE);
> > > +       if (ret)
> > > +               return ret;
> > > +
> > > +       host_lock_component();
> > > +       guest_lock_component(vm);
> > > +
> > > +       ret = __guest_check_page_state_range(vcpu, ipa, PAGE_SIZE, PKVM_NOPAGE);
> > > +       if (ret)
> > > +               goto unlock;
> > > +
> > > +       page = hyp_phys_to_page(phys);
> > > +       switch (page->host_state) {
> > > +       case PKVM_PAGE_OWNED:
> > > +               WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_OWNED));
> > > +               break;
> > > +       case PKVM_PAGE_SHARED_OWNED:
> > > +               /* Only host to np-guest multi-sharing is tolerated */
> >
> > Initially I thought the comment was related to the warning below,
> > which confused me.
>
> It actually is about the warning below :-)
>
> > Now I think what you're trying to say is that we'll
> > allow the share, and the (unrelated to the comment) warning is to
> > ensure that the PKVM_PAGE_SHARED_OWNED is consistent with the share
> > count.
>
> So, the only case where the host should ever attempt do use
> __pkvm_host_share_guest() on a page that is already shared is for a page
> already shared *with an np-guest*. The page->host_share_guest_count being
> elevated is the easiest way to check that the page is indeed in that
> state, hence the warning.
>
> If for example the host was trying to share with an np-guest a page that
> is currently shared with the hypervisor, that check would fail. We can
> discuss whether or not we would want to allow it, but for now there is
> strictly no need for it so I went with the restrictive option. We can
> relax that constraint later if need be.
>
> > I think what you should have here, which would work better with the
> > comment, is something like:
> >
> >                 /* Only host to np-guest multi-sharing is tolerated */
> > +               if (pkvm_hyp_vcpu_is_protected(vcpu))
> > +                       return -EPERM;
> >
> > That would even make the comment unnecessary.
>
> I would prefer not adding this here, handle___pkvm_host_share_guest() in
> hyp-main.c already does that for us.

I understand now, and I agree that an additional check isn't
necessary. Could you clarify the comment though? It's the word "only"
that threw me off, since to me it implied that the check was enforcing
the word "only". Maybe:

>                 /* Tolerate host to np-guest multi-sharing. */


Thanks,
/fuad

> >
> > > +               WARN_ON(!page->host_share_guest_count);
> > > +               break;
> > > +       default:
> > > +               ret = -EPERM;
> > > +               goto unlock;
> > > +       }
> > > +
> > > +       WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys,
> > > +                                      pkvm_mkstate(prot, PKVM_PAGE_SHARED_BORROWED),
> > > +                                      &vcpu->vcpu.arch.pkvm_memcache, 0));
> > > +       page->host_share_guest_count++;
> > > +
> > > +unlock:
> > > +       guest_unlock_component(vm);
> > > +       host_unlock_component();
> > > +
> > > +       return ret;
> > > +}
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > index d5c23449a64c..d6c61a5e7b6e 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > @@ -795,6 +795,13 @@ int __pkvm_teardown_vm(pkvm_handle_t handle)
> > >         /* Push the metadata pages to the teardown memcache */
> > >         for (idx = 0; idx < hyp_vm->nr_vcpus; ++idx) {
> > >                 struct pkvm_hyp_vcpu *hyp_vcpu = hyp_vm->vcpus[idx];
> > > +               struct kvm_hyp_memcache *vcpu_mc = &hyp_vcpu->vcpu.arch.pkvm_memcache;
> > > +
> > > +               while (vcpu_mc->nr_pages) {
> > > +                       void *addr = pop_hyp_memcache(vcpu_mc, hyp_phys_to_virt);
> >
> > nit: newline
> >
> > Cheers,
> > /fuad
> >
> >
> >
> > > +                       push_hyp_memcache(mc, addr, hyp_virt_to_phys);
> > > +                       unmap_donated_memory_noclear(addr, PAGE_SIZE);
> > > +               }
> > >
> > >                 teardown_donated_memory(mc, hyp_vcpu, sizeof(*hyp_vcpu));
> > >         }
> > > --
> > > 2.47.0.338.g60cca15819-goog
> > >


From qperret at google.com  Tue Dec 10 07:53:07 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 10 Dec 2024 15:53:07 +0000
Subject: [PATCH v2 11/18] KVM: arm64: Introduce
 __pkvm_host_unshare_guest()
In-Reply-To: <CA+EHjTw48LTFt=sKtPwS1rmA=ma6Sj9O-D=17FXoMybqZ7+g5g@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-12-qperret@google.com>
 <CA+EHjTw48LTFt=sKtPwS1rmA=ma6Sj9O-D=17FXoMybqZ7+g5g@mail.gmail.com>
Message-ID: <Z1hj49tuma2zZ1zv@google.com>

On Tuesday 10 Dec 2024 at 14:41:12 (+0000), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
> >
> > In preparation for letting the host unmap pages from non-protected
> > guests, introduce a new hypercall implementing the host-unshare-guest
> > transition.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_asm.h              |  1 +
> >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
> >  arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  5 ++
> >  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 24 +++++++
> >  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 67 +++++++++++++++++++
> >  5 files changed, 98 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > index 449337f5b2a3..0b6c4d325134 100644
> > --- a/arch/arm64/include/asm/kvm_asm.h
> > +++ b/arch/arm64/include/asm/kvm_asm.h
> > @@ -66,6 +66,7 @@ enum __kvm_host_smccc_func {
> >         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
> >         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
> >         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> > +       __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
> >         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
> >         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
> >         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > index a7976e50f556..e528a42ed60e 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > @@ -40,6 +40,7 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
> >  int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
> >  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
> >  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
> > +int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
> 
> The parameters of share_guest and unshare_guest are quite different. I
> think that the unshare makes more sense, that it uses the hyp_vm as
> opposed to the hyp_vcpu. Still, I think that one of the two should
> change.

Hmm, so that is actually a bit difficult. __pkvm_host_share_guest() is
guaranteed to always be called when a vCPU is loaded, and it needs to
use the per-vCPU memcache so we can't just give it the pkvm_hyp_vm as
is.

And on the other hand, __pkvm_host_unshare_guest() can end up being
called from MMU notifier where no vCPU is loaded, so it's not clear
which vCPU it should be using. We also just don't need to access
per-vCPU data-structures on that path (the unmap call can only free
page-table pages, which are always put back into the per-guest pool
directly, not in a memcache).

> >  bool addr_is_memory(phys_addr_t phys);
> >  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> > index be52c5b15e21..5dfc9ece9aa5 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> > @@ -64,6 +64,11 @@ static inline bool pkvm_hyp_vcpu_is_protected(struct pkvm_hyp_vcpu *hyp_vcpu)
> >         return vcpu_is_protected(&hyp_vcpu->vcpu);
> >  }
> >
> > +static inline bool pkvm_hyp_vm_is_protected(struct pkvm_hyp_vm *hyp_vm)
> > +{
> > +       return kvm_vm_is_protected(&hyp_vm->kvm);
> > +}
> > +
> >  void pkvm_hyp_vm_table_init(void *tbl);
> >
> >  int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
> > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > index d659462fbf5d..04a9053ae1d5 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > @@ -244,6 +244,29 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
> >         cpu_reg(host_ctxt, 1) =  ret;
> >  }
> >
> > +static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
> > +{
> > +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> > +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> > +       struct pkvm_hyp_vm *hyp_vm;
> > +       int ret = -EINVAL;
> > +
> > +       if (!is_protected_kvm_enabled())
> > +               goto out;
> > +
> > +       hyp_vm = get_pkvm_hyp_vm(handle);
> > +       if (!hyp_vm)
> > +               goto out;
> > +       if (pkvm_hyp_vm_is_protected(hyp_vm))
> > +               goto put_hyp_vm;
> 
> bikeshedding: is -EINVAL the best return value, or might -EPERM be
> better if the VM is protected?

-EINVAL makes the code marginally simpler, especially given that we have
this pattern all across hyp-main.c, so I have a minor personal
preference for keeping it as-is, but no strong opinion really. This
really shouldn't ever hit at run-time, modulo major bugs or a malicious
host, so probably not a huge deal if EINVAL isn't particularly accurate.

> > +
> > +       ret = __pkvm_host_unshare_guest(gfn, hyp_vm);
> > +put_hyp_vm:
> > +       put_pkvm_hyp_vm(hyp_vm);
> > +out:
> > +       cpu_reg(host_ctxt, 1) =  ret;
> > +}
> > +
> >  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
> >  {
> >         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> > @@ -454,6 +477,7 @@ static const hcall_t host_hcall[] = {
> >         HANDLE_FUNC(__pkvm_host_share_hyp),
> >         HANDLE_FUNC(__pkvm_host_unshare_hyp),
> >         HANDLE_FUNC(__pkvm_host_share_guest),
> > +       HANDLE_FUNC(__pkvm_host_unshare_guest),
> >         HANDLE_FUNC(__kvm_adjust_pc),
> >         HANDLE_FUNC(__kvm_vcpu_run),
> >         HANDLE_FUNC(__kvm_flush_vm_context),
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > index a69d7212b64c..aa27a3e42e5e 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > @@ -1413,3 +1413,70 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
> >
> >         return ret;
> >  }
> > +
> > +static int __check_host_unshare_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)
> 
> nit: sometimes (in this and other patches) you use vm to refer to
> pkvm_hyp_vm, and other times you use hyp_vm. Makes grepping/searching
> a bit more tricky.

Ack, I'll do a pass on the series to improve the consistency.

> > +{
> > +       enum pkvm_page_state state;
> > +       struct hyp_page *page;
> > +       kvm_pte_t pte;
> > +       u64 phys;
> > +       s8 level;
> > +       int ret;
> > +
> > +       ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
> > +       if (ret)
> > +               return ret;
> > +       if (level != KVM_PGTABLE_LAST_LEVEL)
> > +               return -E2BIG;
> > +       if (!kvm_pte_valid(pte))
> > +               return -ENOENT;
> > +
> > +       state = guest_get_page_state(pte, ipa);
> > +       if (state != PKVM_PAGE_SHARED_BORROWED)
> > +               return -EPERM;
> > +
> > +       phys = kvm_pte_to_phys(pte);
> > +       ret = range_is_allowed_memory(phys, phys + PAGE_SIZE);
> > +       if (WARN_ON(ret))
> > +               return ret;
> > +
> > +       page = hyp_phys_to_page(phys);
> > +       if (page->host_state != PKVM_PAGE_SHARED_OWNED)
> > +               return -EPERM;
> > +       if (WARN_ON(!page->host_share_guest_count))
> > +               return -EINVAL;
> > +
> > +       *__phys = phys;
> > +
> > +       return 0;
> > +}
> > +
> > +int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm)
> > +{
> > +       u64 ipa = hyp_pfn_to_phys(gfn);
> > +       struct hyp_page *page;
> > +       u64 phys;
> > +       int ret;
> > +
> > +       host_lock_component();
> > +       guest_lock_component(hyp_vm);
> > +
> > +       ret = __check_host_unshare_guest(hyp_vm, &phys, ipa);
> > +       if (ret)
> > +               goto unlock;
> > +
> > +       ret = kvm_pgtable_stage2_unmap(&hyp_vm->pgt, ipa, PAGE_SIZE);
> > +       if (ret)
> > +               goto unlock;
> > +
> > +       page = hyp_phys_to_page(phys);
> > +       page->host_share_guest_count--;
> > +       if (!page->host_share_guest_count)
> > +               WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_OWNED));
> > +
> > +unlock:
> > +       guest_unlock_component(hyp_vm);
> > +       host_unlock_component();
> > +
> > +       return ret;
> > +}
> > --
> > 2.47.0.338.g60cca15819-goog
> >


From will at kernel.org  Tue Dec 10 07:56:04 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 15:56:04 +0000
Subject: [PATCH 0/6] arm64: errata: Add Qualcomm CPUs to the Spectre
 mitigation lists
In-Reply-To: <20241209174430.2904353-1-dianders@chromium.org>
References: <20241209174430.2904353-1-dianders@chromium.org>
Message-ID: <20241210155604.GA15918@willie-the-truck>

Hi Doug,

On Mon, Dec 09, 2024 at 09:43:10AM -0800, Douglas Anderson wrote:
> 
> Since Qualcomm CPUs are all derivatives of ARM cores they all have
> unique MIDR values. This means that the tables listing necessary
> Spectre mitigations need special entries for them. However, those
> entries are not present and that means that some Spectre mitigations
> are lacking for Qualcomm CPUs.
> 
> I've made an attempt at **GUESSING** what the right patches should be
> to enable mitigations for Qualcomm CPUs. This is mostly me searching
> the web to figure out what ARM cores various Qualcomm cores are based
> off of.
> 
> These patches get more and more sketchy as the series progresses and I
> have noted that the later patces DON'T EVEN COMPILE. I have included
> them to make it obvious that I think these cores are affected even if
> I don't have all the right information to mitigate them. Hopefully
> Qualcomm can come and fix this mess for me.
> 
> I'll note that I am certainly no expert on Spectre. Mostly I ended up
> here running `lscpu` on a device and noticing that it thought that it
> wasn't affected by Spectre v2 when I thought it was.

Whilst only Qualcomm can say definitively whether or not they are
affected (and what values of 'k' are required for the loop-based
workarounds), I can't help but wonder whether the current mitigation
code is structured the wrong way around in this case.

It looks to me like we don't have a way to identify a "vulnerable" CPU
for Spectre-BHB; either a CPU has some sort of mitigation or it's
unaffected. That means that there's very little incentive for vendors
to add their CPUs to one of the lists -- if they do nothing, userspace
is told that everything is golden and they don't pay the performance
hit of a workaround!

So I think we should consider turning this on its head and assume that
CPUs we don't know about are vulnerable, having a list of unaffected
cores that predate the introduction of CSV2.3 which can be queried by
is_spectre_bhb_affected(). We can do that without the assistance of the
CPU vendors.

Does that make sense, or did I miss something?

Will


From ddutile at redhat.com  Tue Dec 10 07:56:43 2024
From: ddutile at redhat.com (Donald Dutile)
Date: Tue, 10 Dec 2024 10:56:43 -0500
Subject: [PATCH v2 0/1] KVM: arm64: Map GPU memory with no struct pages
In-Reply-To: <20241210141806.GI2347147@nvidia.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241210140739.GC15607@willie-the-truck>
 <20241210141806.GI2347147@nvidia.com>
Message-ID: <0723d890-1f90-463b-a814-9f7bb7e2200b@redhat.com>



On 12/10/24 9:18 AM, Jason Gunthorpe wrote:
> On Tue, Dec 10, 2024 at 02:07:40PM +0000, Will Deacon wrote:
>> On Mon, Nov 18, 2024 at 01:19:57PM +0000, ankita at nvidia.com wrote:
>>> The changes are heavily influenced by the insightful discussions between
>>> Catalin Marinas and Jason Gunthorpe [1] on v1. Many thanks for their
>>> valuable suggestions.
>>>
>>> Link: https://lore.kernel.org/lkml/20230907181459.18145-2-ankita at nvidia.com [1]
>>
>> That's a different series, no? It got merged at v9:
> 
> I was confused by this too. v1 of that series included this patch, as
> that series went along it became focused only on enabling WC
> (Normal-NC) in a VM for device MMIO and this patch for device cachable
> memory was dropped off.
> 
> There are two related things:
>   1) Device MMIO memory should be able to be Normal-NC in a VM. Already
>      merged
>   2) Device Cachable memory (ie CXL and pre-CXL coherently attached
>      memory) should be Normal Cachable in a VM, even if it doesn't have
>      struct page/etc. (this patch)
> 
> IIRC this part was dropped off because of the MTE complexity that
> Catalin raised.
> 
> Jason
> 
Jason & Catalin: Thanks for the filler for the splitting.

So, I'm not sure I read what is needed to resolve this patch.
I read Will's reply to split it further and basically along what logical lines of functionality;
is there still an MTE complexity that has to be resolved/included in the series?

IOW, I'm looking for a complete, clear (set of) statement(s) that Ankit can implement to get this (requested) series moving forward, sooner than later;
it's already been a year+ to get to this point, and I don't want further ambiguity/uncertainty to drag it out more than needed.

Thanks... Don



From tabba at google.com  Tue Dec 10 07:57:59 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Dec 2024 15:57:59 +0000
Subject: [PATCH v2 11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
In-Reply-To: <Z1hj49tuma2zZ1zv@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-12-qperret@google.com>
 <CA+EHjTw48LTFt=sKtPwS1rmA=ma6Sj9O-D=17FXoMybqZ7+g5g@mail.gmail.com> <Z1hj49tuma2zZ1zv@google.com>
Message-ID: <CA+EHjTxWQJYWjjcagqwZ2_B7yoUq7OJNwfWkvB_mX35bJLPJXQ@mail.gmail.com>

Hi Quentin,

On Tue, 10 Dec 2024 at 15:53, Quentin Perret <qperret at google.com> wrote:
>
> On Tuesday 10 Dec 2024 at 14:41:12 (+0000), Fuad Tabba wrote:
> > Hi Quentin,
> >
> > On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
> > >
> > > In preparation for letting the host unmap pages from non-protected
> > > guests, introduce a new hypercall implementing the host-unshare-guest
> > > transition.
> > >
> > > Signed-off-by: Quentin Perret <qperret at google.com>
> > > ---
> > >  arch/arm64/include/asm/kvm_asm.h              |  1 +
> > >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
> > >  arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  5 ++
> > >  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 24 +++++++
> > >  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 67 +++++++++++++++++++
> > >  5 files changed, 98 insertions(+)
> > >
> > > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > > index 449337f5b2a3..0b6c4d325134 100644
> > > --- a/arch/arm64/include/asm/kvm_asm.h
> > > +++ b/arch/arm64/include/asm/kvm_asm.h
> > > @@ -66,6 +66,7 @@ enum __kvm_host_smccc_func {
> > >         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
> > >         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
> > >         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> > > +       __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
> > >         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
> > >         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
> > >         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > > index a7976e50f556..e528a42ed60e 100644
> > > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > > @@ -40,6 +40,7 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
> > >  int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
> > >  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
> > >  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
> > > +int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
> >
> > The parameters of share_guest and unshare_guest are quite different. I
> > think that the unshare makes more sense, that it uses the hyp_vm as
> > opposed to the hyp_vcpu. Still, I think that one of the two should
> > change.
>
> Hmm, so that is actually a bit difficult. __pkvm_host_share_guest() is
> guaranteed to always be called when a vCPU is loaded, and it needs to
> use the per-vCPU memcache so we can't just give it the pkvm_hyp_vm as
> is.
>
> And on the other hand, __pkvm_host_unshare_guest() can end up being
> called from MMU notifier where no vCPU is loaded, so it's not clear
> which vCPU it should be using. We also just don't need to access
> per-vCPU data-structures on that path (the unmap call can only free
> page-table pages, which are always put back into the per-guest pool
> directly, not in a memcache).

I understand. That makes sense.

> > >  bool addr_is_memory(phys_addr_t phys);
> > >  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> > > index be52c5b15e21..5dfc9ece9aa5 100644
> > > --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> > > +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> > > @@ -64,6 +64,11 @@ static inline bool pkvm_hyp_vcpu_is_protected(struct pkvm_hyp_vcpu *hyp_vcpu)
> > >         return vcpu_is_protected(&hyp_vcpu->vcpu);
> > >  }
> > >
> > > +static inline bool pkvm_hyp_vm_is_protected(struct pkvm_hyp_vm *hyp_vm)
> > > +{
> > > +       return kvm_vm_is_protected(&hyp_vm->kvm);
> > > +}
> > > +
> > >  void pkvm_hyp_vm_table_init(void *tbl);
> > >
> > >  int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > > index d659462fbf5d..04a9053ae1d5 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > > @@ -244,6 +244,29 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
> > >         cpu_reg(host_ctxt, 1) =  ret;
> > >  }
> > >
> > > +static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
> > > +{
> > > +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> > > +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> > > +       struct pkvm_hyp_vm *hyp_vm;
> > > +       int ret = -EINVAL;
> > > +
> > > +       if (!is_protected_kvm_enabled())
> > > +               goto out;
> > > +
> > > +       hyp_vm = get_pkvm_hyp_vm(handle);
> > > +       if (!hyp_vm)
> > > +               goto out;
> > > +       if (pkvm_hyp_vm_is_protected(hyp_vm))
> > > +               goto put_hyp_vm;
> >
> > bikeshedding: is -EINVAL the best return value, or might -EPERM be
> > better if the VM is protected?
>
> -EINVAL makes the code marginally simpler, especially given that we have
> this pattern all across hyp-main.c, so I have a minor personal
> preference for keeping it as-is, but no strong opinion really. This
> really shouldn't ever hit at run-time, modulo major bugs or a malicious
> host, so probably not a huge deal if EINVAL isn't particularly accurate.

That's fine.

> > > +
> > > +       ret = __pkvm_host_unshare_guest(gfn, hyp_vm);
> > > +put_hyp_vm:
> > > +       put_pkvm_hyp_vm(hyp_vm);
> > > +out:
> > > +       cpu_reg(host_ctxt, 1) =  ret;
> > > +}
> > > +
> > >  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
> > >  {
> > >         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> > > @@ -454,6 +477,7 @@ static const hcall_t host_hcall[] = {
> > >         HANDLE_FUNC(__pkvm_host_share_hyp),
> > >         HANDLE_FUNC(__pkvm_host_unshare_hyp),
> > >         HANDLE_FUNC(__pkvm_host_share_guest),
> > > +       HANDLE_FUNC(__pkvm_host_unshare_guest),
> > >         HANDLE_FUNC(__kvm_adjust_pc),
> > >         HANDLE_FUNC(__kvm_vcpu_run),
> > >         HANDLE_FUNC(__kvm_flush_vm_context),
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > index a69d7212b64c..aa27a3e42e5e 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > @@ -1413,3 +1413,70 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
> > >
> > >         return ret;
> > >  }
> > > +
> > > +static int __check_host_unshare_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)
> >
> > nit: sometimes (in this and other patches) you use vm to refer to
> > pkvm_hyp_vm, and other times you use hyp_vm. Makes grepping/searching
> > a bit more tricky.
>
> Ack, I'll do a pass on the series to improve the consistency.

Thanks!
/fuad

> > > +{
> > > +       enum pkvm_page_state state;
> > > +       struct hyp_page *page;
> > > +       kvm_pte_t pte;
> > > +       u64 phys;
> > > +       s8 level;
> > > +       int ret;
> > > +
> > > +       ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
> > > +       if (ret)
> > > +               return ret;
> > > +       if (level != KVM_PGTABLE_LAST_LEVEL)
> > > +               return -E2BIG;
> > > +       if (!kvm_pte_valid(pte))
> > > +               return -ENOENT;
> > > +
> > > +       state = guest_get_page_state(pte, ipa);
> > > +       if (state != PKVM_PAGE_SHARED_BORROWED)
> > > +               return -EPERM;
> > > +
> > > +       phys = kvm_pte_to_phys(pte);
> > > +       ret = range_is_allowed_memory(phys, phys + PAGE_SIZE);
> > > +       if (WARN_ON(ret))
> > > +               return ret;
> > > +
> > > +       page = hyp_phys_to_page(phys);
> > > +       if (page->host_state != PKVM_PAGE_SHARED_OWNED)
> > > +               return -EPERM;
> > > +       if (WARN_ON(!page->host_share_guest_count))
> > > +               return -EINVAL;
> > > +
> > > +       *__phys = phys;
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm)
> > > +{
> > > +       u64 ipa = hyp_pfn_to_phys(gfn);
> > > +       struct hyp_page *page;
> > > +       u64 phys;
> > > +       int ret;
> > > +
> > > +       host_lock_component();
> > > +       guest_lock_component(hyp_vm);
> > > +
> > > +       ret = __check_host_unshare_guest(hyp_vm, &phys, ipa);
> > > +       if (ret)
> > > +               goto unlock;
> > > +
> > > +       ret = kvm_pgtable_stage2_unmap(&hyp_vm->pgt, ipa, PAGE_SIZE);
> > > +       if (ret)
> > > +               goto unlock;
> > > +
> > > +       page = hyp_phys_to_page(phys);
> > > +       page->host_share_guest_count--;
> > > +       if (!page->host_share_guest_count)
> > > +               WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_OWNED));
> > > +
> > > +unlock:
> > > +       guest_unlock_component(hyp_vm);
> > > +       host_unlock_component();
> > > +
> > > +       return ret;
> > > +}
> > > --
> > > 2.47.0.338.g60cca15819-goog
> > >


From frieder.schrempf at kontron.de  Tue Dec 10 07:59:06 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Tue, 10 Dec 2024 16:59:06 +0100
Subject: [PATCH v2 01/11] Revert "regulator: pca9450: Add sd-vsel GPIO"
In-Reply-To: <20241128-candle-guzzler-b7ea4e5ce643@spud>
References: <20241127164337.613915-1-frieder@fris.de>
 <20241127164337.613915-2-frieder@fris.de>
 <20241128-candle-guzzler-b7ea4e5ce643@spud>
Message-ID: <b5456480-a68f-4e71-831b-f145453e2646@kontron.de>

On 28.11.24 6:37 PM, Conor Dooley wrote:
> On Wed, Nov 27, 2024 at 05:42:17PM +0100, Frieder Schrempf wrote:
>> From: Frieder Schrempf <frieder.schrempf at kontron.de>
>>
>> This reverts commit 27866e3e8a7e93494f8374f48061aa73ee46ceb2.
>>
>> It turned out that this feature was implemented based on
>> the wrong assumption that the SD_VSEL signal needs to be
>> controlled as GPIO in any case.
>>
>> In fact the straight-forward approach is to mux the signal
>> as USDHC_VSELECT and let the USDHC controller do the job.
>>
>> Most users never even used this property and the few who
>> did have been or are getting migrated to the alternative
>> approach.
>>
>> Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
>> ---
>> Changes for v2:
>> * split revert into separate patch
>> ---
>>  .../devicetree/bindings/regulator/nxp,pca9450-regulator.yaml | 5 -----
>>  1 file changed, 5 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
>> index f8057bba747a5..79fc0baf5fa2f 100644
>> --- a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
>> +++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
>> @@ -77,11 +77,6 @@ properties:
>>  
>>      additionalProperties: false
>>  
>> -  sd-vsel-gpios:
>> -    description: GPIO that is used to switch LDO5 between being configured by
>> -      LDO5CTRL_L or LDO5CTRL_H register. Use this if the SD_VSEL signal is
>> -      connected to a host GPIO.
> 
> Your driver side of this, that I wasn't sent and cba downloading an
> mbox of is not backwards compatible. The code has been there for a few
> years, are you sure that there are no out of tree users or other OSes
> that use the property?

Yes, this is not backwards compatible. I introduced the original meaning
for the sd-vsel-gpios property based on some misunderstanding of how the
hardware actually works. Therefore I'm quite sure that except for the
cases where someone copied my erroneous implementation into their
devicetree, nobody has really any reason to actually use this.

In-tree all users have been removed (one fix still included in this
series). Of course we can't be fully sure that there isn't someone out
there having non-standard hardware (SD_VSEL not connected to
USDHC_VSELECT but to GPIO only) and using the old sd-vsel-gpios, but the
probability is very, very low.

IMHO taking the small risk here is better than keeping the misleading
implementation which will likely cause confusion and failures in the
future. But of course that's not up to me to decide.

> 
> tbh, I think all 3 of your dt-binding patches should be squashed rather
> than drip-feeding the conversion. It makes more sense as a single
> change, rather than splitting the rationales across 3 patches.

Ok, if you like this better in one change I can squash these for the
next version.

Thanks!


From jonas at kwiboo.se  Tue Dec 10 08:05:22 2024
From: jonas at kwiboo.se (Jonas Karlman)
Date: Tue, 10 Dec 2024 17:05:22 +0100
Subject: [PATCH 4/6] arm64: dts: rockchip: add hevc power domain clock to
 rk3328
In-Reply-To: <8c604ada27457698ad6d33d22a39b45a@manjaro.org>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-5-pgwipeout@gmail.com>
 <e32fa593abfa6d08202b4f929e0b4bdb@manjaro.org>
 <CAMdYzYp+MQVYr1tOMEOn62vXZGVEYrtd1p9vn6YQzXdrJgSdyA@mail.gmail.com>
 <CAMdYzYquvGBzfWqvUOku7m1sM9qxmBHAL95cANDViUCT1oEEhQ@mail.gmail.com>
 <8c604ada27457698ad6d33d22a39b45a@manjaro.org>
Message-ID: <f16b3688-91e1-4760-ac2b-ce53db98ed68@kwiboo.se>

Hi Peter,

On 2024-12-10 14:53, Dragan Simic wrote:
> Hello Peter,
> 
> On 2024-12-10 14:23, Peter Geis wrote:
>> On Tue, Dec 10, 2024 at 8:13?AM Peter Geis <pgwipeout at gmail.com> wrote:
>>> On Tue, Dec 10, 2024 at 5:04?AM Dragan Simic <dsimic at manjaro.org> 
>>> wrote:
>>>> On 2024-12-10 02:30, Peter Geis wrote:
>>>>> There is a race condition at startup between disabling power domains
>>>>> not
>>>>> used and disabling clocks not used on the rk3328. When the clocks are
>>>>> disabled first, the hevc power domain fails to shut off leading to a
>>>>> splat of failures. Add the hevc core clock to the rk3328 power domain
>>>>> node to prevent this condition.
>>>>>
>>>>> rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-....
>>>>> }
>>>>> 1087 jiffies s: 89 root: 0x8/.
>>>>> rcu: blocking rcu_node structures (internal RCU debug):
>>>>> Sending NMI from CPU 0 to CPUs 3:
>>>>> NMI backtrace for cpu 3
>>>>> CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53
>>>>> Hardware name: Firefly ROC-RK3328-CC (DT)
>>>>> Workqueue: pm genpd_power_off_work_fn
>>>>> pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>>>>> pc : regmap_unlock_spinlock+0x18/0x30
>>>>> lr : regmap_read+0x60/0x88
>>>>> sp : ffff800081123c00
>>>>> x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000
>>>>> x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040
>>>>> x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74
>>>>> x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000
>>>>> x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d
>>>>> x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431
>>>>> x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0
>>>>> x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b
>>>>> x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40
>>>>> x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000
>>>>> Call trace:
>>>>> regmap_unlock_spinlock+0x18/0x30
>>>>> rockchip_pmu_set_idle_request+0xac/0x2c0
>>>>> rockchip_pd_power+0x144/0x5f8
>>>>> rockchip_pd_power_off+0x1c/0x30
>>>>> _genpd_power_off+0x9c/0x180
>>>>> genpd_power_off.part.0.isra.0+0x130/0x2a8
>>>>> genpd_power_off_work_fn+0x6c/0x98
>>>>> process_one_work+0x170/0x3f0
>>>>> worker_thread+0x290/0x4a8
>>>>> kthread+0xec/0xf8
>>>>> ret_from_fork+0x10/0x20
>>>>> rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack
>>>>> on
>>>>> domain 'hevc', val=0x88220
>>>>>
>>>>> Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for
>>>>> RK3328 SoCs")
>>>>> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>>>>
>>>> While I was unable to formally verify this clock assignment,
>>>> i.e. by using the RK3328 TRM or the downstream kernel source
>>>> from Rockchip, it makes perfect sense to me.  Thanks for the
>>>> patch, and please feel free to include:
>>>>
>>>> Reviewed-by: Dragan Simic <dsimic at manjaro.org>
>>>
>>> It is unfortunate the TRM doesn't include the clock maps, because they
>>> are extremely helpful when one can acquire them. It also doesn't help
>>> that the TRM register definition only referred to this as "pll". I was
>>> sent specifically the usb3 phy clock map for my work on the driver,
>>> which had the location of each switch and divider along with the
>>> register and bit that controlled it. That combined with the TRM
>>> register map allowed me to find this error.
>>
>> Apologies, that's the wrong response for this one.
> 
> No worries.
> 
>> This patch was the result of educated guess combined with testing. I
>> grabbed all of the clocks that looked like they could affect things,
>> then tested them one at a time until I isolated them to this clock. It
>> lives alone with cpll as the parent and has no children according to
>> the clock summary. (Though the writeup i mistakenly included above
>> proves the clock map isn't always accurate).
> 
> I see, thanks for all your work on this patch!  It surely took quite
> a lot of time to perform all the testing.
> 
>>>>> ---
>>>>>
>>>>>  arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 +
>>>>>  1 file changed, 1 insertion(+)
>>>>>
>>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> index 0597de415fe0..7d992c3c01ce 100644
>>>>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
>>>>> @@ -333,6 +333,7 @@ power: power-controller {
>>>>>
>>>>>                       power-domain at RK3328_PD_HEVC {
>>>>>                               reg = <RK3328_PD_HEVC>;
>>>>> +                             clocks = <&cru SCLK_VENC_CORE>;

Do we also need to include one or all of the following clocks?

According to Fig. 3-6 RK3228H Clock Architecture Diagram 5 following
clocks point to the H265 block:

S51_6 (4PLL) / G6_3 / S51_0 (DivFree 1~32) / D4 ---- aclk_h265
                                                 \-- pclk_h265
S51_14 (4PLL) / G6_4 / S51_8 (DivFree 1~32) / D4 - clk_venc_core
S52_14 (4PLL) / G6_7 / S52_8 (DivFree 1~32) / D4 - clk_venc_dsp

Regards,
Jonas

>>>>>                               #power-domain-cells = <0>;
>>>>>                       };
>>>>>                       power-domain at RK3328_PD_VIDEO {



From arnd at kernel.org  Tue Dec 10 08:05:52 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 10 Dec 2024 17:05:52 +0100
Subject: [PATCH 0/4] ARM: towards 32-bit preempt-rt support
Message-ID: <20241210160556.2341497-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Linux-6.13 contains a few patches required as preparation for
CONFIG_PREEMPT_RT, there are three more left, out of which I have reworked
two slightly:

 - The jump-label patch from Thomas get a little more background
   information, and an improvement for non-SMP kernels

 - The HIGHPTE patch from Sebastian now has the reverse dependency,
   turning HIGHPTE off instead of PREEMPT_RT.

As Matthew Wilcox noted, we can probably remove HIGHPTE support entirely,
so I include two more patches for review here that do just that, with
linux-mm added to Cc.

The final RT patch for the entry path is not included here as I'm waiting
on some work from Linus Walleij. Hopefully it will no longer be needed
after then next version of his generic entry series, see
https://lore.kernel.org/lkml/20241029-arm-generic-entry-v2-0-573519abef38 at linaro.org/

      Arnd

Arnd Bergmann (2):
  ARM: drop CONFIG_HIGHPTE support
  mm: drop HIGHPTE support altogether

Sebastian Andrzej Siewior (1):
  ARM: Disable HIGHPTE on PREEMPT_RT kernels

Thomas Gleixner (1):
  ARM: Disable jump-label on PREEMPT_RT

 arch/arm/Kconfig               | 13 +------------
 arch/arm/include/asm/pgalloc.h |  8 +-------
 include/linux/hugetlb.h        |  5 +----
 include/linux/mm.h             |  1 -
 include/linux/pgtable.h        |  9 ---------
 5 files changed, 3 insertions(+), 33 deletions(-)

-- 
2.39.5

Cc: linux-mm at kvack.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-rt-devel at lists.linux.dev
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Clark Williams <clrkwllms at kernel.org>
Cc: Jason Baron <jbaron at akamai.com>
Cc: Josh Poimboeuf <jpoimboe at kernel.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Matthew Wilcox <willy at infradead.org>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Russell King <linux at armlinux.org.uk>
Cc: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
Cc: Steven Rostedt <rostedt at goodmis.org>


From arnd at kernel.org  Tue Dec 10 08:05:53 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 10 Dec 2024 17:05:53 +0100
Subject: [PATCH 1/4] ARM: Disable jump-label on PREEMPT_RT
In-Reply-To: <20241210160556.2341497-1-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org>
Message-ID: <20241210160556.2341497-2-arnd@kernel.org>

From: Thomas Gleixner <tglx at linutronix.de>

jump-labels are used to efficiently switch between two possible code
paths. To achieve this, stop_machine() is used to keep the CPU in a
known state while the opcode is modified. The usage of stop_machine()
here leads to large latency spikes which can be observed on PREEMPT_RT.

Jump labels may change the target during runtime and are not restricted
to debug or "configuration/ setup" part of a PREEMPT_RT system where
high latencies could be defined as acceptable.

On 64-bit Arm, it is possible to use jump labels without the
stop_machine() call, which architecturally provides a way to atomically
change one 32-bit instruction word while keeping maintaining consistency,
but this is not generally the case on 32-bit, in particular in thumb2
mode.

Disable jump-label support on a PREEMPT_RT system when SMP is enabled.

[bigeasy: Patch description.]
[arnd: add !SMP case, extend changelog]

Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Link: https://lkml.kernel.org/r/20220613182447.112191-2-bigeasy at linutronix.de
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
I slightly changed the patch from the version currently in linux-rt.git
to leave jump labels enabled on single-CPU kernels that are still
fairly common on 32-bit arm.

If there are no additional concerns about this version, I will
forward it to Russell's patch system
---
 arch/arm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fb4e1da3bb98..ed850cc0ed3c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -80,7 +80,7 @@ config ARM
 	select HAS_IOPORT if PCI || PCMCIA || ISA || ARCH_FOOTBRIDGE || ARCH_RPC
 	select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
 	select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
-	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
+	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU && (!PREEMPT_RT || !SMP)
 	select HAVE_ARCH_KFENCE if MMU && !XIP_KERNEL
 	select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
 	select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
-- 
2.39.5



From arnd at kernel.org  Tue Dec 10 08:05:54 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 10 Dec 2024 17:05:54 +0100
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <20241210160556.2341497-1-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org>
Message-ID: <20241210160556.2341497-3-arnd@kernel.org>

From: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

gup_pgd_range() is invoked with disabled interrupts and invokes
__kmap_local_page_prot() via pte_offset_map(), gup_p4d_range().
With HIGHPTE enabled, __kmap_local_page_prot() invokes kmap_high_get()
which uses a spinlock_t via lock_kmap_any(). This leads to an
sleeping-while-atomic error on PREEMPT_RT because spinlock_t becomes a
sleeping lock and must not be acquired in atomic context.

The loop in map_new_virtual() uses wait_queue_head_t for wake up which
also is using a spinlock_t.

Since HIGHPTE is rarely needed at all, turn it off for PREEMPT_RT
to allow the use of get_user_pages_fast().

[arnd: rework patch to turn off HIGHPTE instead of HAVE_PAST_GUP]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
---
There is an open question about whether HIGHPTE is still needed
at all, given how rare 32-bit machines with more than 4GB
are on any architecture. If we instead decide to remove HIGHPTE
altogether, this patch is no longer needed.
---
 arch/arm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ed850cc0ed3c..4de4e5697bdf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1231,7 +1231,7 @@ config HIGHMEM
 
 config HIGHPTE
 	bool "Allocate 2nd-level pagetables from highmem" if EXPERT
-	depends on HIGHMEM
+	depends on HIGHMEM && !PREEMPT_RT
 	default y
 	help
 	  The VM uses one page of physical memory for each page table.
-- 
2.39.5



From arnd at kernel.org  Tue Dec 10 08:05:55 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 10 Dec 2024 17:05:55 +0100
Subject: [PATCH 3/4] ARM: drop CONFIG_HIGHPTE support
In-Reply-To: <20241210160556.2341497-1-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org>
Message-ID: <20241210160556.2341497-4-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

CONFIG_HIGHPTE was added in linux-2.6.32, a few years before 64-bit
support. At the time it made sense, as the CONFIG_ARM_LPAE option allowed
systems with 16GB of memory that made lowmem a particularly scarce
resource, and the HIGHPTE implementation gave feature parity with 32-bit
x86 and frv machines.

Since Arm is the last architecture remaining that uses this, and almost
no 32-bit machines support more than 4GB of RAM, the cost of continuing
to maintain HIGHPTE seems unjustified, so remove it here to allow
simplifying the generic page table handling.

Link: https://lore.kernel.org/lkml/20241204103042.1904639-8-arnd at kernel.org/T/#u
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
I sent a patch to drop HIGHPTE support on x86 today, see
https://lore.kernel.org/lkml/20241210144945.2325330-9-arnd at kernel.org/T/#u

If that one gets merged, we can merge this one instead of the one
that makes HIGHPTE depend on !PREEMPT_RT, but if we decide against
the x86 change, then we probably don't want this one either.
---
 arch/arm/Kconfig               | 11 -----------
 arch/arm/include/asm/pgalloc.h |  8 +-------
 2 files changed, 1 insertion(+), 18 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4de4e5697bdf..e132effafd8b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1229,17 +1229,6 @@ config HIGHMEM
 
 	  If unsure, say n.
 
-config HIGHPTE
-	bool "Allocate 2nd-level pagetables from highmem" if EXPERT
-	depends on HIGHMEM && !PREEMPT_RT
-	default y
-	help
-	  The VM uses one page of physical memory for each page table.
-	  For systems with a lot of processes, this can use a lot of
-	  precious low memory, eventually leading to low memory being
-	  consumed by page tables.  Setting this option will allow
-	  user-space 2nd level page tables to reside in high memory.
-
 config ARM_PAN
 	bool "Enable privileged no-access"
 	depends on MMU
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index a17f01235c29..ef6cb3e6d179 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -85,18 +85,12 @@ pte_alloc_one_kernel(struct mm_struct *mm)
 	return pte;
 }
 
-#ifdef CONFIG_HIGHPTE
-#define PGTABLE_HIGHMEM __GFP_HIGHMEM
-#else
-#define PGTABLE_HIGHMEM 0
-#endif
-
 static inline pgtable_t
 pte_alloc_one(struct mm_struct *mm)
 {
 	struct page *pte;
 
-	pte = __pte_alloc_one(mm, GFP_PGTABLE_USER | PGTABLE_HIGHMEM);
+	pte = __pte_alloc_one(mm, GFP_PGTABLE_USER);
 	if (!pte)
 		return NULL;
 	if (!PageHighMem(pte))
-- 
2.39.5



From arnd at kernel.org  Tue Dec 10 08:05:56 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 10 Dec 2024 17:05:56 +0100
Subject: [PATCH 4/4] mm: drop HIGHPTE support altogether
In-Reply-To: <20241210160556.2341497-1-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org>
Message-ID: <20241210160556.2341497-5-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

With both x86 and arm having dropped CONFIG_HIGHPTE support, no
architecture is left using it, so remove the remnants in common code.

It is likely that further cleanups are possible in the page table
code but those are not obvious from the config options.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 include/linux/hugetlb.h | 5 +----
 include/linux/mm.h      | 1 -
 include/linux/pgtable.h | 9 ---------
 3 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index ae4fe8615bb6..5369a269dd39 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -176,7 +176,6 @@ extern struct list_head huge_boot_pages[MAX_NUMNODES];
 
 /* arch callbacks */
 
-#ifndef CONFIG_HIGHPTE
 /*
  * pte_offset_huge() and pte_alloc_huge() are helpers for those architectures
  * which may go down to the lowest PTE level in their huge_pte_offset() and
@@ -191,7 +190,6 @@ static inline pte_t *pte_alloc_huge(struct mm_struct *mm, pmd_t *pmd,
 {
 	return pte_alloc(mm, pmd) ? NULL : pte_offset_huge(pmd, address);
 }
-#endif
 
 pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 			unsigned long addr, unsigned long sz);
@@ -966,9 +964,8 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 	 */
 	if (size >= PUD_SIZE)
 		return pud_lockptr(mm, (pud_t *) pte);
-	else if (size >= PMD_SIZE || IS_ENABLED(CONFIG_HIGHPTE))
+	else if (size >= PMD_SIZE)
 		return pmd_lockptr(mm, (pmd_t *) pte);
-	/* pte_alloc_huge() only applies with !CONFIG_HIGHPTE */
 	return ptep_lockptr(mm, pte);
 }
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index f56f81d5e244..6353fd939702 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2954,7 +2954,6 @@ static inline spinlock_t *pte_lockptr(struct mm_struct *mm, pmd_t *pmd)
 
 static inline spinlock_t *ptep_lockptr(struct mm_struct *mm, pte_t *pte)
 {
-	BUILD_BUG_ON(IS_ENABLED(CONFIG_HIGHPTE));
 	BUILD_BUG_ON(MAX_PTRS_PER_PTE * sizeof(pte_t) > PAGE_SIZE);
 	return ptlock_ptr(virt_to_ptdesc(pte));
 }
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index adef9d6e9b1b..23be8776bd5e 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -119,14 +119,6 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
 #define pte_offset_kernel pte_offset_kernel
 #endif
 
-#ifdef CONFIG_HIGHPTE
-#define __pte_map(pmd, address) \
-	((pte_t *)kmap_local_page(pmd_page(*(pmd))) + pte_index((address)))
-#define pte_unmap(pte)	do {	\
-	kunmap_local((pte));	\
-	rcu_read_unlock();	\
-} while (0)
-#else
 static inline pte_t *__pte_map(pmd_t *pmd, unsigned long address)
 {
 	return pte_offset_kernel(pmd, address);
@@ -135,7 +127,6 @@ static inline void pte_unmap(pte_t *pte)
 {
 	rcu_read_unlock();
 }
-#endif
 
 void pte_free_defer(struct mm_struct *mm, pgtable_t pgtable);
 
-- 
2.39.5



From catalin.marinas at arm.com  Tue Dec 10 08:08:07 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 10 Dec 2024 16:08:07 +0000
Subject: [PATCH v2 0/1] KVM: arm64: Map GPU memory with no struct pages
In-Reply-To: <0723d890-1f90-463b-a814-9f7bb7e2200b@redhat.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241210140739.GC15607@willie-the-truck>
 <20241210141806.GI2347147@nvidia.com>
 <0723d890-1f90-463b-a814-9f7bb7e2200b@redhat.com>
Message-ID: <Z1hnZ0H13Pst5sKF@arm.com>

On Tue, Dec 10, 2024 at 10:56:43AM -0500, Donald Dutile wrote:
> So, I'm not sure I read what is needed to resolve this patch. I read
> Will's reply to split it further and basically along what logical
> lines of functionality; is there still an MTE complexity that has to
> be resolved/included in the series?

Since MTE is still around, the complexity did not go away. But I need to
properly read the patch and Will's comment and page in the whole
discussion from last year.

There's now FEAT_MTE_PERM as well but we don't have those patches in
yet:

https://lore.kernel.org/r/20241028094014.2596619-1-aneesh.kumar at kernel.org/

-- 
Catalin


From kevin.brodsky at arm.com  Tue Dec 10 08:09:40 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Tue, 10 Dec 2024 16:09:40 +0000
Subject: [PATCH v2] arm64: signal: Ensure signal delivery failure is recoverable
Message-ID: <20241210160940.2031997-1-kevin.brodsky@arm.com>

Commit eaf62ce1563b ("arm64/signal: Set up and restore the GCS
context for signal handlers") introduced a potential failure point
at the end of setup_return(). This is unfortunate as it is too late
to deliver a SIGSEGV: if that SIGSEGV is handled, the subsequent
sigreturn will end up returning to the original handler, which is
not the intention (since we failed to deliver that signal).

Make sure this does not happen by calling gcs_signal_entry()
at the very beginning of setup_return(), and add a comment just
after to discourage error cases being introduced from that point
onwards.

While at it, also take care of copy_siginfo_to_user(): since it may
fail, we shouldn't be calling it after setup_return() either. Call
it before setup_return() instead, and move the setting of X1/X2
inside setup_return() where it belongs (after the "point of no
failure").

Background: the first part of setup_rt_frame(), including
setup_sigframe(), has no impact on the execution of the interrupted
thread. The signal frame is written to the stack, but the stack
pointer remains unchanged. Failure at this stage can be recovered by
a SIGSEGV handler, and sigreturn will restore the original context,
at the point where the original signal occurred. On the other hand,
once setup_return() has updated registers including SP, the thread's
control flow has been modified and we must deliver the original
signal.

Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")
Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
v1..v2:
* Added a short comment in setup_rt_frame() after the call to
  setup_return() to discourage adding failure points there.
  [Dave's suggestion]

Cc: broonie at kernel.org
Cc: catalin.marinas at arm.com
Cc: Dave.Martin at arm.com
Cc: will at kernel.org
---
 arch/arm64/kernel/signal.c | 48 ++++++++++++++++++++++++++------------
 1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 14ac6fdb872b..37e24f1bd227 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -1462,10 +1462,33 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
 			 struct rt_sigframe_user_layout *user, int usig)
 {
 	__sigrestore_t sigtramp;
+	int err;
+
+	if (ksig->ka.sa.sa_flags & SA_RESTORER)
+		sigtramp = ksig->ka.sa.sa_restorer;
+	else
+		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
+
+	err = gcs_signal_entry(sigtramp, ksig);
+	if (err)
+		return err;
+
+	/*
+	 * We must not fail from this point onwards. We are going to update
+	 * registers, including SP, in order to invoke the signal handler. If
+	 * we failed and attempted to deliver a nested SIGSEGV to a handler
+	 * after that point, the subsequent sigreturn would end up restoring
+	 * the (partial) state for the original signal handler.
+	 */
 
 	regs->regs[0] = usig;
+	if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+		regs->regs[1] = (unsigned long)&user->sigframe->info;
+		regs->regs[2] = (unsigned long)&user->sigframe->uc;
+	}
 	regs->sp = (unsigned long)user->sigframe;
 	regs->regs[29] = (unsigned long)&user->next_frame->fp;
+	regs->regs[30] = (unsigned long)sigtramp;
 	regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
 
 	/*
@@ -1506,14 +1529,7 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
 		sme_smstop();
 	}
 
-	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);
+	return 0;
 }
 
 static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
@@ -1537,14 +1553,16 @@ 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, &ua_state);
-	if (err == 0) {
+	if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+		err |= copy_siginfo_to_user(&frame->info, &ksig->info);
+
+	if (err == 0)
 		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;
-			regs->regs[2] = (unsigned long)&frame->uc;
-		}
-	}
+
+	/*
+	 * We must not fail if setup_return() succeeded - see comment at the
+	 * beginning of setup_return().
+	 */
 
 	if (err == 0)
 		set_handler_user_access_state();

base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
-- 
2.47.0



From ulf.hansson at linaro.org  Tue Dec 10 08:09:37 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 10 Dec 2024 17:09:37 +0100
Subject: [PATCH v4 0/5] dt-bindings: mmc: document mmc-slot and convert
 amlogic,meson-mx-sdio.txt to dtschema
In-Reply-To: <20241128-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v4-0-11d9f9200a59@linaro.org>
References: <20241128-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v4-0-11d9f9200a59@linaro.org>
Message-ID: <CAPDyKFon9-3U5Vn2i+WtarSAYQHnA_ho8CGQmiVoboq1tnt4fw@mail.gmail.com>

On Thu, 28 Nov 2024 at 16:16, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>
> Document mmc-slot because used by amlogic,meson-mx-sdio.txt and
> cavium-mmc.txt, so make it common.
>
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>

Applied for next, thanks!

Kind regards
Uffe


> ---
> Changes in v4:
> - Fixed address-cells description of mmc controller
> - Cleanup '|' when not needed
> - Added review tags
> - Link to v3: https://lore.kernel.org/r/20241007-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v3-0-ad4eb22c2a8d at linaro.org
>
> Changes in v3:
> - Revert and insteads move common properties between slot and controller into mmc-controller-common.yaml
> - Fix other comments on patch 2 & 3
> - Link to v2: https://lore.kernel.org/r/20240920-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v2-0-5aa8bdfe01af at linaro.org
>
> Changes in v2:
> - Fixed description, limited to 3 slots
> - Moved out mmc-slot in a separate common schema
> - Link to v1: https://lore.kernel.org/r/20240911-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-v1-1-b7bfae886211 at linaro.org
>
> ---
> Neil Armstrong (5):
>       dt-bindings: mmc: controller: clarify the address-cells description
>       dt-bindings: mmc: controller: move properties common with slot out to mmc-controller-common
>       dt-bindings: mmc: controller: remove '|' when not needed
>       dt-bindings: mmc: document mmc-slot
>       dt-bindings: mmc: convert amlogic,meson-mx-sdio.txt to dtschema
>
>  .../bindings/mmc/amlogic,meson-mx-sdio.txt         |  54 ----
>  .../bindings/mmc/amlogic,meson-mx-sdio.yaml        |  94 ++++++
>  .../bindings/mmc/mmc-controller-common.yaml        | 357 +++++++++++++++++++++
>  .../devicetree/bindings/mmc/mmc-controller.yaml    | 346 +-------------------
>  .../devicetree/bindings/mmc/mmc-slot.yaml          |  49 +++
>  5 files changed, 504 insertions(+), 396 deletions(-)
> ---
> base-commit: f486c8aa16b8172f63bddc70116a0c897a7f3f02
> change-id: 20240911-topic-amlogic-arm32-upstream-bindings-fixes-convert-meson-mx-sdio-6fa70546ebb8
>
> Best regards,
> --
> Neil Armstrong <neil.armstrong at linaro.org>
>


From sashal at kernel.org  Tue Dec 10 08:12:30 2024
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Dec 2024 11:12:30 -0500
Subject: [PATCH AUTOSEL 6.11 08/15] drm: display: Set fwnode for aux bus
 devices
In-Reply-To: <CAGETcx-6yHV5xr1j7krY8LShCF5JATX0NSwjeRUL9+3TLCMq9w@mail.gmail.com>
References: <20241204221726.2247988-1-sashal@kernel.org>
 <20241204221726.2247988-8-sashal@kernel.org>
 <CAGETcx8bhzGZKge4qfpNR8FaTWqbo0-5J9c7whc3pn-RECJs3Q@mail.gmail.com>
 <CAGETcx-6yHV5xr1j7krY8LShCF5JATX0NSwjeRUL9+3TLCMq9w@mail.gmail.com>
Message-ID: <Z1hobuvz2S03L9TF@sashalap>

On Thu, Dec 05, 2024 at 04:07:45PM -0800, Saravana Kannan wrote:
>On Thu, Dec 5, 2024 at 4:06?PM Saravana Kannan <saravanak at google.com> wrote:
>>
>> On Wed, Dec 4, 2024 at 3:29?PM Sasha Levin <sashal at kernel.org> wrote:
>> >
>> > From: Saravana Kannan <saravanak at google.com>
>> >
>> > [ Upstream commit fe2e59aa5d7077c5c564d55b7e2997e83710c314 ]
>> >
>> > fwnode needs to be set for a device for fw_devlink to be able to
>> > track/enforce its dependencies correctly. Without this, you'll see error
>> > messages like this when the supplier has probed and tries to make sure
>> > all its fwnode consumers are linked to it using device links:
>> >
>> > mediatek-drm-dp 1c500000.edp-tx: Failed to create device link (0x180) with backlight-lcd0
>> >
>> > Reported-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
>> > Closes: https://lore.kernel.org/all/7b995947-4540-4b17-872e-e107adca4598 at notapiano/
>> > Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
>> > Signed-off-by: Saravana Kannan <saravanak at google.com>
>> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>> > Reviewed-by: Thierry Reding <treding at nvidia.com>
>> > Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> > Link: https://lore.kernel.org/r/20241024061347.1771063-2-saravanak at google.com
>> > Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
>> > Signed-off-by: Sasha Levin <sashal at kernel.org>
>>
>> As mentioned in the original cover letter:
>>
>> PSA: Do not pull any of these patches into stable kernels. fw_devlink
>> had a lot of changes that landed in the last year. It's hard to ensure
>> cherry-picks have picked up all the dependencies correctly. If any of
>> these really need to get cherry-picked into stable kernels, cc me and
>> wait for my explicit Ack.
>>
>> Is there a pressing need for this in 4.19?
>
>I copy pasted this into several replies. In all those cases I meant
>the kernel version mentioned in the subject.

I'll drop this and the other patch you've pointed out, thanks!

-- 
Thanks,
Sasha


From jonas at kwiboo.se  Tue Dec 10 08:25:34 2024
From: jonas at kwiboo.se (Jonas Karlman)
Date: Tue, 10 Dec 2024 17:25:34 +0100
Subject: [PATCH 2/6] clk: rockchip: fix wrong clk_ref_usb3otg parent for
 rk3328
In-Reply-To: <CAMdYzYqJLK6oJHCUVztth6mtJsYrRQSPzNYpR-ZmR7rNprZXfg@mail.gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-3-pgwipeout@gmail.com>
 <0d11705121f29ccfb7cfa342505a6e35@manjaro.org>
 <CAMdYzYqJLK6oJHCUVztth6mtJsYrRQSPzNYpR-ZmR7rNprZXfg@mail.gmail.com>
Message-ID: <304fd668-0e61-4f5e-a12c-36fd7e54ab6e@kwiboo.se>

On 2024-12-10 14:27, Peter Geis wrote:
> On Tue, Dec 10, 2024 at 4:44?AM Dragan Simic <dsimic at manjaro.org> wrote:
>>
>> Hello Peter,
>>
>> On 2024-12-10 02:30, Peter Geis wrote:
>>> Correct the clk_ref_usb3otg parent to fix clock control for the usb3
>>> controller on rk3328. Verified against the rk3328 trm and usb3 clock
>>> tree
>>> documentation.
>>>
>>> Fixes: fe3511ad8a1c ("clk: rockchip: add clock controller for rk3328")
>>> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>>> ---
>>>
>>>  drivers/clk/rockchip/clk-rk3328.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/clk/rockchip/clk-rk3328.c
>>> b/drivers/clk/rockchip/clk-rk3328.c
>>> index 3bb87b27b662..cf60fcf2fa5c 100644
>>> --- a/drivers/clk/rockchip/clk-rk3328.c
>>> +++ b/drivers/clk/rockchip/clk-rk3328.c
>>> @@ -201,7 +201,7 @@ PNAME(mux_aclk_peri_pre_p)        = { "cpll_peri",
>>>                                   "gpll_peri",
>>>                                   "hdmiphy_peri" };
>>>  PNAME(mux_ref_usb3otg_src_p) = { "xin24m",
>>> -                                 "clk_usb3otg_ref" };
>>> +                                 "clk_ref_usb3otg_src" };
>>>  PNAME(mux_xin24m_32k_p)              = { "xin24m",
>>>                                   "clk_rtc32k" };
>>>  PNAME(mux_mac2io_src_p)              = { "clk_mac2io_src",
>>
>> Sorry, but I was unable to verify this in the part 1 of the
>> RK3328 TRM, in both versions 1.1 and 1.2, which is all I have
>> when it comes to the RK3328 TRM.  Is that maybe described in
>> the part 2, which I've been unable to locate for years?
>>
>> Moreover, the downstream kernel source from Rockchip does it
>> the way [1] it's currently done in the mainline kernel, which
>> makes me confused a bit?  Could you, please, provide more
>> details about the two references you mentioned in the patch
>> description, or maybe even you could provide the links to
>> those two references?
>>
>> [1]
>> https://raw.githubusercontent.com/rockchip-linux/kernel/refs/heads/develop-4.4/drivers/clk/rockchip/clk-rk3328.c
> 
> It is unfortunate the TRM doesn't include the clock maps, because they
> are extremely helpful when one can acquire them. It also doesn't help
> that the TRM register definition only referred to this as "pll". I was
> sent specifically the usb3 phy clock map for my work on the driver,
> which had the location of each switch and divider along with the
> register and bit that controlled it. That combined with the TRM
> register map allowed me to find this error.

I can also confirm that the changes in this patch matches Fig. 3-8
RK3228H Clock Architecture Diagram 7 for the USB3OTG block.

                                    XIN24M -\
                                             S45_8 - ref_clk_usb3otg
S45_7 (2PLL) / G4_9 / S45_0 (DivFree 1~64) -/

Regards,
Jonas

> 
> Thanks!
> Peter
> 



From sebastian.reichel at collabora.com  Tue Dec 10 08:24:04 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Tue, 10 Dec 2024 17:24:04 +0100
Subject: [PATCH v2 1/1] arm64: dts: rockchip: rk3588-evb1: add WLAN controller
Message-ID: <20241210162452.116767-1-sebastian.reichel@collabora.com>

The RK3588 EVB1 has an onboard AP6275P WLAN/BT module. This adds
support for the WLAN side, which is connected to the second
PCIe bus. The Bluetooth side is connected to UART and handled
separately.

Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
---
Changes since PATCHv1:
 * rebase to latest for-next branch from Heiko
 * add regulator- prefix to regulator nodes
 * sort properties alphabetically in regulator nodes
 * sort regulator nodes alphabetically
---
 .../boot/dts/rockchip/rk3588-evb1-v10.dts     | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
index d6e464cdc536..ba49f0bbaac6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
@@ -206,6 +206,28 @@ vcc3v3_pcie30: regulator-vcc3v3-pcie30 {
 		pinctrl-0 = <&vcc3v3_pcie30_en>;
 	};
 
+	vcc3v3_pciewl_vbat: regulator-vcc3v3-pciewl-vbat {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-name = "wlan-vbat";
+		vin-supply = <&vcc_3v3_s0>;
+	};
+
+	vcc3v3_wlan: regulator-vcc3v3-wlan {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_pwren>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-name = "wlan-en";
+		vin-supply = <&vcc3v3_pciewl_vbat>;
+	};
+
 	vcc5v0_host: regulator-vcc5v0-host {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc5v0_host";
@@ -249,12 +271,26 @@ vcc5v0_usb: regulator-vcc5v0-usb {
 		regulator-max-microvolt = <5000000>;
 		vin-supply = <&vcc5v0_usbdcin>;
 	};
+
+	vccio_wl: regulator-vccio-wl {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-name = "wlan-vddio";
+		vin-supply = <&vcc_1v8_s0>;
+	};
 };
 
 &combphy0_ps {
 	status = "okay";
 };
 
+&combphy1_ps {
+	status = "okay";
+};
+
 &combphy2_psu {
 	status = "okay";
 };
@@ -440,6 +476,30 @@ rgmii_phy: ethernet-phy at 1 {
 	};
 };
 
+&pcie2x1l0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2_0_rst>, <&pcie2_0_wake>, <&pcie2_0_clkreq>, <&wifi_host_wake_irq>;
+	reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_wlan>;
+	status = "okay";
+
+	pcie at 0,0 {
+		reg = <0x200000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		ranges;
+		device_type = "pci";
+		bus-range = <0x20 0x2f>;
+
+		wifi: wifi at 0,0 {
+			compatible = "pci14e4,449d";
+			reg = <0x210000 0 0 0 0>;
+			clocks = <&hym8563>;
+			clock-names = "lpo";
+		};
+	};
+};
+
 &pcie2x1l1 {
 	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
 	pinctrl-names = "default";
@@ -494,6 +554,18 @@ hym8563_int: hym8563-int {
 	};
 
 	pcie2 {
+		pcie2_0_rst: pcie2-0-rst {
+			rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		pcie2_0_wake: pcie2-0-wake {
+			rockchip,pins = <4 RK_PA4 4 &pcfg_pull_none>;
+		};
+
+		pcie2_0_clkreq: pcie2-0-clkreq {
+			rockchip,pins = <4 RK_PA3 4 &pcfg_pull_none>;
+		};
+
 		pcie2_1_rst: pcie2-1-rst {
 			rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
@@ -524,6 +596,16 @@ usbc0_int: usbc0-int {
 			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 	};
+
+	wlan {
+		wifi_host_wake_irq: wifi-host-wake-irq {
+			rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		wifi_pwren: wifi-pwren {
+			rockchip,pins = <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
 };
 
 &pwm2 {
-- 
2.45.2



From mark.rutland at arm.com  Tue Dec 10 08:35:57 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Dec 2024 16:35:57 +0000
Subject: [PATCH] arm64/signal: Silence spurious sparse warning storing
 GCSPR_EL0
In-Reply-To: <20c12aac-193e-43ae-9418-39db1af4ede9@sirena.org.uk>
References: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
 <Z1hU0Ii-Sm9NHnhj@J2N7QTR9R3>
 <20c12aac-193e-43ae-9418-39db1af4ede9@sirena.org.uk>
Message-ID: <Z1ht7X2LRw34pMJK@J2N7QTR9R3>

On Tue, Dec 10, 2024 at 03:44:29PM +0000, Mark Brown wrote:
> On Tue, Dec 10, 2024 at 02:48:48PM +0000, Mark Rutland wrote:
> > On Tue, Dec 10, 2024 at 12:42:53AM +0000, Mark Brown wrote:
> > > We are seeing a false postive sparse warning in gcs_restore_signal()
> > > 
> > > arch/arm64/kernel/signal.c:1054:9: sparse: sparse: cast removes address space '__user' of expression
> 
> > This isn't a false positive; this is a cross-address space cast that
> > sparse is accurately warning about. That might be *benign*, but the tool
> > is doing exactly what it is supposed to.
> 
> The spuriousness is arguable, from my point of view it's spurious in
> that we don't have the type of the system register we're writing to.

All that I'm asking for here is a trivial rewording; make the title say
something like:

  arm64/signal: Avoid sparse warning when manipulating GCSPR_EL0

... and in the commit message, say something like:

  Sparse complains about the manipulation of the GCSPR_EL0 value in
  gcs_restore_signal(), because we cast to/from the __user address space
  without a __force cast. Silence this warning by ${DOING_THING}.

... which clearly explains what's actually going wrong, rather than
making spurious complaints about the tool that may mislead a reader of
the commit message.

> > > +	write_sysreg_s((unsigned long)(gcspr_el0 + 1), SYS_GCSPR_EL0);
> 
> > Only one line here wants a __user pointer, so wouldn't it be simpler to
> > pass 'gcspr_el0' as an integer type, and cast it at the point it's used
> > as an actual pointer, rather than the other way around?
> 
> > Then you could also simplify gcs_restore_signal(), etc.
> 
> I find it both safer and clearer to keep values which are userspace
> pointers as userspace pointers rather than working with them as
> integers, using integers just sets off alarm bells.  

Having casts strewn throughout the code sets off more alarm bells for
me.

> > Similarly in map_shadow_stack(), it'd be simpler to treat cap_ptr as an
> > integer type.
> 
> With map_shadow_stack() it's a bit of an issue with letting users
> specify a size but yeah, we could do better there.

I don't follow. The only place where size interacts with cap_ptr is when
we initialize cap_ptr, and there we're adding size to an integer type:

	cap_ptr = (unsigned long __user *)(addr + size -
					   (cap_offset * sizeof(unsigned long)));

I was suggesting something along the lines of the diff below.

Mark.

diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c
index 5c46ec527b1cd..096add5f2ddb2 100644
--- a/arch/arm64/mm/gcs.c
+++ b/arch/arm64/mm/gcs.c
@@ -71,10 +71,7 @@ unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
 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;
@@ -106,17 +103,16 @@ SYSCALL_DEFINE3(map_shadow_stack, unsigned long, addr, unsigned long, size, unsi
         * can be switched to.
         */
        if (flags & SHADOW_STACK_SET_TOKEN) {
+               unsigned long cap_addr = addr + size - sizeof(unsigned long);
+               unsigned long cap_val;
+
                /* 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_addr -= sizeof(unsigned long)
 
-               cap_ptr = (unsigned long __user *)(addr + size -
-                                                  (cap_offset * sizeof(unsigned long)));
-               cap_val = GCS_CAP(cap_ptr);
+               cap_val = GCS_CAP(cap_addr);
 
-               put_user_gcs(cap_val, cap_ptr, &ret);
+               put_user_gcs(cap_val, (unsigned long __user *)cap_addr, &ret);
                if (ret != 0) {
                        vm_munmap(addr, size);
                        return -EFAULT;


From sebastian.reichel at collabora.com  Tue Dec 10 08:36:01 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Tue, 10 Dec 2024 17:36:01 +0100
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add USB-C support to ROCK 5B
Message-ID: <20241210163615.120594-1-sebastian.reichel@collabora.com>

Add hardware description for the USB-C port in the Radxa Rock 5 Model B.
This describes the OHCI, EHCI and XHCI USB parts, but not yet the
DisplayPort AltMode (bindings are not yet upstream).

The fusb302 node is marked with status "fail", since the board is usually
powered through the USB-C port. Handling of errors can result in hard
resets, which removed the bus power for some time resulting in a board
reset.

The main problem is that devices are supposed to interact with the
power-supply within 5 seconds after the plug event according to the
USB PD specification. This is more or less impossible to achieve when
the kernel is the first software communicating with the power-supply.

Recent U-Boot (v2025.01) will start doing USB-PD communication, which
solves this issue. Upstream U-Boot doing USB-PD communication will also
set the fusb302 node status to "okay". That way booting a kernel with
the updated DT on an old U-Boot avoids a reset loop.

Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
---
 .../boot/dts/rockchip/rk3588-rock-5b.dts      | 121 ++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index d597112f1d5b..cb5990df6ccb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -5,6 +5,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/soc/rockchip,vop2.h>
+#include <dt-bindings/usb/pd.h>
 #include "rk3588.dtsi"
 
 / {
@@ -84,6 +85,15 @@ rfkill-bt {
 		shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 	};
 
+	vcc12v_dcin: regulator-vcc12v-dcin {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
 	vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -142,6 +152,7 @@ vcc5v0_sys: regulator-vcc5v0-sys {
 		regulator-boot-on;
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
 	};
 
 	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
@@ -264,6 +275,67 @@ regulator-state-mem {
 	};
 };
 
+&i2c4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4m1_xfer>;
+	status = "okay";
+
+	usbc0: usb-typec at 22 {
+		compatible = "fcs,fusb302";
+		reg = <0x22>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbc0_int>;
+		vbus-supply = <&vcc12v_dcin>;
+		/*
+		 * When the board is starting to send power-delivery messages
+		 * too late (5 seconds according to the specification), the
+		 * power-supply reacts with a hard-reset. That removes the
+		 * power from VBUS for some time, which resets te whole board.
+		 */
+		status = "fail";
+
+		usb_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "sink";
+			try-power-role = "sink";
+			op-sink-microwatt = <1000000>;
+			sink-pdos =
+				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>,
+				<PDO_VAR(5000, 20000, 5000)>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					usbc0_role_sw: endpoint {
+						remote-endpoint = <&dwc3_0_role_switch>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+					usbc0_orien_sw: endpoint {
+						remote-endpoint = <&usbdp_phy0_orientation_switch>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+					dp_altmode_mux: endpoint {
+						remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &i2c6 {
 	status = "okay";
 
@@ -423,6 +495,10 @@ usb {
 		vcc5v0_host_en: vcc5v0-host-en {
 			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
+
+		usbc0_int: usbc0-int {
+			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
 	};
 };
 
@@ -835,6 +911,14 @@ &uart2 {
 	status = "okay";
 };
 
+&u2phy0 {
+	status = "okay";
+};
+
+&u2phy0_otg {
+	status = "okay";
+};
+
 &u2phy1 {
 	status = "okay";
 };
@@ -866,6 +950,29 @@ &usbdp_phy1 {
 	status = "okay";
 };
 
+&usbdp_phy0 {
+	mode-switch;
+	orientation-switch;
+	sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
+	sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usbdp_phy0_orientation_switch: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&usbc0_orien_sw>;
+		};
+
+		usbdp_phy0_dp_altmode_mux: endpoint at 1 {
+			reg = <1>;
+			remote-endpoint = <&dp_altmode_mux>;
+		};
+	};
+};
+
 &usb_host0_ehci {
 	status = "okay";
 };
@@ -874,6 +981,20 @@ &usb_host0_ohci {
 	status = "okay";
 };
 
+&usb_host0_xhci {
+	usb-role-switch;
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dwc3_0_role_switch: endpoint {
+			remote-endpoint = <&usbc0_role_sw>;
+		};
+	};
+};
+
 &usb_host1_ehci {
 	status = "okay";
 };
-- 
2.45.2



From nunodasneves at linux.microsoft.com  Tue Dec 10 08:40:49 2024
From: nunodasneves at linux.microsoft.com (Nuno Das Neves)
Date: Tue, 10 Dec 2024 08:40:49 -0800
Subject: [PATCH 1/2] hyperv: Move hv_current_partition_id to arch-generic
 code
In-Reply-To: <SN6PR02MB4157E39FBEFB18EB9A695EECD4332@SN6PR02MB4157.namprd02.prod.outlook.com>
References: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
 <1733523707-15954-2-git-send-email-nunodasneves@linux.microsoft.com>
 <SN6PR02MB4157E39FBEFB18EB9A695EECD4332@SN6PR02MB4157.namprd02.prod.outlook.com>
Message-ID: <fec1aeb7-ea07-4363-9e6a-50b0c778e855@linux.microsoft.com>

On 12/7/2024 7:01 PM, Michael Kelley wrote:
> From: Nuno Das Neves <nunodasneves at linux.microsoft.com> Sent: Friday, December 6, 2024 2:22 PM
>>
>> Make hv_current_partition_id available in both x86_64 and arm64.
>> This feature isn't specific to x86_64 and will be needed by common
>> code.
>>
>> While at it, replace the BUG()s with WARN()s. Failing to get the id
>> need not crash the machine (although it is a very bad sign).
>>
>> Signed-off-by: Nuno Das Neves <nudasnev at microsoft.com>
>> ---
>>  arch/arm64/hyperv/mshyperv.c    |  3 +++
>>  arch/x86/hyperv/hv_init.c       | 25 +------------------------
>>  arch/x86/include/asm/mshyperv.h |  2 --
>>  drivers/hv/hv_common.c          | 23 +++++++++++++++++++++++
>>  include/asm-generic/mshyperv.h  |  2 ++
>>  5 files changed, 29 insertions(+), 26 deletions(-)
>>
>> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
>> index b1a4de4eee29..5050e748d266 100644
>> --- a/arch/arm64/hyperv/mshyperv.c
>> +++ b/arch/arm64/hyperv/mshyperv.c
>> @@ -19,6 +19,9 @@
>>
>>  static bool hyperv_initialized;
>>
>> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
>> +EXPORT_SYMBOL_GPL(hv_current_partition_id);
>> +
> 
> Instead of adding a definition of hv_current_partition_id on
> the arm64 side, couldn't the definition on the x86 side in
> hv_init.c be moved to hv_common.c (or maybe somewhere
> else that is specific to running in the root partition, per my
> comments in the cover letter), so there is only one definition
> shared by both architectures?
> 
Yes, that's a better idea.

>>  int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
>>  {
>>  	hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
>> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
>> index 95eada2994e1..950f5ccdb9d9 100644
>> --- a/arch/x86/hyperv/hv_init.c
>> +++ b/arch/x86/hyperv/hv_init.c
>> @@ -35,7 +35,7 @@
>>  #include <clocksource/hyperv_timer.h>
>>  #include <linux/highmem.h>
>>
>> -u64 hv_current_partition_id = ~0ull;
>> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
>>  EXPORT_SYMBOL_GPL(hv_current_partition_id);
>>
>>  void *hv_hypercall_pg;
>> @@ -394,24 +394,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
>>  		old_setup_percpu_clockev();
>>  }
>>
>> -static void __init hv_get_partition_id(void)
>> -{
>> -	struct hv_get_partition_id *output_page;
>> -	u64 status;
>> -	unsigned long flags;
>> -
>> -	local_irq_save(flags);
>> -	output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
>> -	status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
>> -	if (!hv_result_success(status)) {
>> -		/* No point in proceeding if this failed */
>> -		pr_err("Failed to get partition ID: %lld\n", status);
>> -		BUG();
>> -	}
>> -	hv_current_partition_id = output_page->partition_id;
>> -	local_irq_restore(flags);
>> -}
>> -
>>  #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
>>  static u8 __init get_vtl(void)
>>  {
>> @@ -606,11 +588,6 @@ void __init hyperv_init(void)
>>
>>  	register_syscore_ops(&hv_syscore_ops);
>>
>> -	if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
>> -		hv_get_partition_id();
>> -
>> -	BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);
>> -
>>  #ifdef CONFIG_PCI_MSI
>>  	/*
>>  	 * If we're running as root, we want to create our own PCI MSI domain.
>> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
>> index 5f0bc6a6d025..9eeca2a6d047 100644
>> --- a/arch/x86/include/asm/mshyperv.h
>> +++ b/arch/x86/include/asm/mshyperv.h
>> @@ -44,8 +44,6 @@ extern bool hyperv_paravisor_present;
>>
>>  extern void *hv_hypercall_pg;
>>
>> -extern u64 hv_current_partition_id;
>> -
>>  extern union hv_ghcb * __percpu *hv_ghcb_pg;
>>
>>  bool hv_isolation_type_snp(void);
>> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
>> index 7a35c82976e0..819bcfd2b149 100644
>> --- a/drivers/hv/hv_common.c
>> +++ b/drivers/hv/hv_common.c
>> @@ -278,11 +278,34 @@ static void hv_kmsg_dump_register(void)
>>  	}
>>  }
>>
>> +static void __init hv_get_partition_id(void)
>> +{
>> +	struct hv_get_partition_id *output_page;
>> +	u64 status;
>> +	unsigned long flags;
>> +
>> +	local_irq_save(flags);
>> +	output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
>> +	status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
>> +	if (!hv_result_success(status)) {
>> +		local_irq_restore(flags);
>> +		WARN(true, "Failed to get partition ID: %lld\n", status);
>> +		return;
>> +	}
>> +	hv_current_partition_id = output_page->partition_id;
>> +	local_irq_restore(flags);
>> +}
>> +
>>  int __init hv_common_init(void)
>>  {
>>  	int i;
>>  	union hv_hypervisor_version_info version;
>>
>> +	if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
>> +		hv_get_partition_id();
> 
> hv_get_partition_id() uses the hyperv_pcpu_output_arg, and at
> this point, hyperv_pcpu_output_arg isn't set. That setup
> is done later in hv_common_init().
> 
>> +
>> +	WARN_ON(hv_root_partition && hv_current_partition_id == HV_PARTITION_ID_SELF);
>> +
> 
> Since the hypercall will fail cleanly if the calling VM doesn't
> have the HV_ACCESS_PARTITION_ID privilege, could the
> above be simplified to just this?
> 
> 	if (hv_root_partition)
> 		hv_get_partition_id():
> 
> A non-root partition VM doesn't need to get the partition ID, while a
> root partition should have the privilege. If the hypercall fails, there's
> already a WARN, so there's no value in doing another WARN. Also if
> the hypercall succeeds, it presumably returns a specific partitionID, not
> HV_PARTITION_ID_SELF, so we know we have what we want.
> 
> There's already an "if (hv_root_partition)" statement for setting up
> the hyperv_pcpu_output_arg. The call to hv_get_partition_id() could
> go under that existing "if" *after* the hyperv_pcpu_output_arg is
> set. :-)
> 
Thank you, that makes sense. I'll make the changes you suggested for v2.

Nuno

> Michael
> 
>>  	/* Get information about the Hyper-V host version */
>>  	if (!hv_get_hypervisor_version(&version))
>>  		pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
>> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
>> index 8fe7aaab2599..8c4ff6e9aae7 100644
>> --- a/include/asm-generic/mshyperv.h
>> +++ b/include/asm-generic/mshyperv.h
>> @@ -60,6 +60,8 @@ struct ms_hyperv_info {
>>  extern struct ms_hyperv_info ms_hyperv;
>>  extern bool hv_nested;
>>
>> +extern u64 hv_current_partition_id;
>> +
>>  extern void * __percpu *hyperv_pcpu_input_arg;
>>  extern void * __percpu *hyperv_pcpu_output_arg;
>>
>> --
>> 2.34.1



From will at kernel.org  Tue Dec 10 08:41:44 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 16:41:44 +0000
Subject: [PATCH V2 5/7] arm64/cpufeature: Add field details for
 ID_AA64DFR1_EL1 register
In-Reply-To: <20241028053426.2486633-6-anshuman.khandual@arm.com>
References: <20241028053426.2486633-1-anshuman.khandual@arm.com>
 <20241028053426.2486633-6-anshuman.khandual@arm.com>
Message-ID: <20241210164144.GA16039@willie-the-truck>

On Mon, Oct 28, 2024 at 11:04:24AM +0530, Anshuman Khandual wrote:
> This adds required field details for ID_AA64DFR1_EL1, and also drops dummy
> ftr_raz[] array which is now redundant. These register fields will be used
> to enable increased breakpoint and watchpoint registers via FEAT_Debugv8p9
> later.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> cc: Mark Brown <broonie at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/kernel/cpufeature.c | 21 ++++++++++++++++-----
>  1 file changed, 16 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 718728a85430..bd4d85f5dd92 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -530,6 +530,21 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
>  	ARM64_FTR_END,
>  };
>  
> +static const struct arm64_ftr_bits ftr_id_aa64dfr1[] = {
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABL_CMPs_SHIFT, 8, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_DPFZS_SHIFT, 4, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_EBEP_SHIFT, 4, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ITE_SHIFT, 4, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABLE_SHIFT, 4, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_PMICNTR_SHIFT, 4, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SPMU_SHIFT, 4, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_CTX_CMPs_SHIFT, 8, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_WRPs_SHIFT, 8, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_BRPs_SHIFT, 8, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SYSPMUID_SHIFT, 8, 0),
> +	ARM64_FTR_END,
> +};

I think I mentioned this on an earlier series, but it would be useful to
see some justification in the commit message as to why some of these
features are considered STRICT vs NONSTRICT and why LOWER_SAFE is
preferred over EXACT.

For example, why is EBEP strict whereas other PMU-related fields aren't?
Why is the CTX_CMPs field treated differently to the same field in DFR0?

I'm not saying the above table is wrong, it just looks arbitrary without
the justification.

Will


From robh at kernel.org  Tue Dec 10 08:46:38 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 10 Dec 2024 10:46:38 -0600
Subject: [PATCH v3 07/13] dt-bindings: clock: Add SAMA7D65 PMC compatible
 string
In-Reply-To: <5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <20241210164638.GA3770349-robh@kernel.org>

On Fri, Dec 06, 2024 at 12:59:52PM -0700, Ryan.Wanner at microchip.com wrote:
> From: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Add the `microchip,sama7d65-pmc` compatible string to the existing binding,
> since the SAMA7D65 PMC shares the same properties and clock requirements
> as the SAMA7G5.
> 
> Export MCK3 and MCK5 to be accessed and referenced in DT to assign to
> the clocks property for sama7d65 SoC.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>

Missing Conor's ack.


From broonie at kernel.org  Tue Dec 10 08:52:49 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 16:52:49 +0000
Subject: [PATCH] arm64/signal: Silence spurious sparse warning storing
 GCSPR_EL0
In-Reply-To: <Z1ht7X2LRw34pMJK@J2N7QTR9R3>
References: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
 <Z1hU0Ii-Sm9NHnhj@J2N7QTR9R3>
 <20c12aac-193e-43ae-9418-39db1af4ede9@sirena.org.uk>
 <Z1ht7X2LRw34pMJK@J2N7QTR9R3>
Message-ID: <6d839dfb-0a85-44c5-90cc-2b2426353a5f@sirena.org.uk>

On Tue, Dec 10, 2024 at 04:35:57PM +0000, Mark Rutland wrote:
> On Tue, Dec 10, 2024 at 03:44:29PM +0000, Mark Brown wrote:

> > The spuriousness is arguable, from my point of view it's spurious in
> > that we don't have the type of the system register we're writing to.

> All that I'm asking for here is a trivial rewording; make the title say
> something like:

Yes, I had already removed the references to spurious and false positive
locally and changed the unsigned long cast to a __force u64 cast.

> > I find it both safer and clearer to keep values which are userspace
> > pointers as userspace pointers rather than working with them as
> > integers, using integers just sets off alarm bells.  

> Having casts strewn throughout the code sets off more alarm bells for
> me.

With the new code there's only a cast when we store the value to the
register, which is the point where we're discarding the type safety.

> > > Similarly in map_shadow_stack(), it'd be simpler to treat cap_ptr as an
> > > integer type.

> > With map_shadow_stack() it's a bit of an issue with letting users
> > specify a size but yeah, we could do better there.

> I don't follow. The only place where size interacts with cap_ptr is when
> we initialize cap_ptr, and there we're adding size to an integer type:

> 	cap_ptr = (unsigned long __user *)(addr + size -
> 					   (cap_offset * sizeof(unsigned long)));

Ugh, addr is also not a pointer which I'd not noticed but still.  My
main thought there was to move the cap_offset change to a second step so
it was done type safely.

> I was suggesting something along the lines of the diff below.

Yes, I know.
-------------- 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/20241210/a85cc0c3/attachment.sig>

From dianders at chromium.org  Tue Dec 10 08:53:46 2024
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 10 Dec 2024 08:53:46 -0800
Subject: [PATCH 0/6] arm64: errata: Add Qualcomm CPUs to the Spectre
 mitigation lists
In-Reply-To: <20241210155604.GA15918@willie-the-truck>
References: <20241209174430.2904353-1-dianders@chromium.org> <20241210155604.GA15918@willie-the-truck>
Message-ID: <CAD=FV=U5xraosVuDGXxBN5Ajo0n=s50JZqtgQGPs1C9jM3YaFw@mail.gmail.com>

Hi,

On Tue, Dec 10, 2024 at 7:56?AM Will Deacon <will at kernel.org> wrote:
>
> Hi Doug,
>
> On Mon, Dec 09, 2024 at 09:43:10AM -0800, Douglas Anderson wrote:
> >
> > Since Qualcomm CPUs are all derivatives of ARM cores they all have
> > unique MIDR values. This means that the tables listing necessary
> > Spectre mitigations need special entries for them. However, those
> > entries are not present and that means that some Spectre mitigations
> > are lacking for Qualcomm CPUs.
> >
> > I've made an attempt at **GUESSING** what the right patches should be
> > to enable mitigations for Qualcomm CPUs. This is mostly me searching
> > the web to figure out what ARM cores various Qualcomm cores are based
> > off of.
> >
> > These patches get more and more sketchy as the series progresses and I
> > have noted that the later patces DON'T EVEN COMPILE. I have included
> > them to make it obvious that I think these cores are affected even if
> > I don't have all the right information to mitigate them. Hopefully
> > Qualcomm can come and fix this mess for me.
> >
> > I'll note that I am certainly no expert on Spectre. Mostly I ended up
> > here running `lscpu` on a device and noticing that it thought that it
> > wasn't affected by Spectre v2 when I thought it was.
>
> Whilst only Qualcomm can say definitively whether or not they are
> affected (and what values of 'k' are required for the loop-based
> workarounds), I can't help but wonder whether the current mitigation
> code is structured the wrong way around in this case.
>
> It looks to me like we don't have a way to identify a "vulnerable" CPU
> for Spectre-BHB; either a CPU has some sort of mitigation or it's
> unaffected. That means that there's very little incentive for vendors
> to add their CPUs to one of the lists -- if they do nothing, userspace
> is told that everything is golden and they don't pay the performance
> hit of a workaround!
>
> So I think we should consider turning this on its head and assume that
> CPUs we don't know about are vulnerable, having a list of unaffected
> cores that predate the introduction of CSV2.3 which can be queried by
> is_spectre_bhb_affected(). We can do that without the assistance of the
> CPU vendors.
>
> Does that make sense, or did I miss something?

It makes sense to me. I'm not sure I'd be the best person to actually
implement that, though. Maybe someone CCed on this thread could take a
stab at it? It seems like folks from ARM would know the most about the
various mitigations and which pre-CSV2.3 cores were safe.

-Doug


From robdclark at gmail.com  Tue Dec 10 08:51:18 2024
From: robdclark at gmail.com (Rob Clark)
Date: Tue, 10 Dec 2024 08:51:18 -0800
Subject: [PATCH v11 0/4] io-pgtable-arm + drm/msm: Extend iova fault debugging
Message-ID: <20241210165127.600817-1-robdclark@gmail.com>

From: Rob Clark <robdclark at chromium.org>

This series extends io-pgtable-arm with a method to retrieve the page
table entries traversed in the process of address translation, and then
beefs up drm/msm gpu devcore dump to include this (and additional info)
in the devcore dump.

This is a respin of https://patchwork.freedesktop.org/series/94968/
(minus a patch that was already merged)

v2:  Fix an armv7/32b build error in the last patch
v3:  Incorperate Will Deacon's suggestion to make the interface
     callback based.
v4:  Actually wire up the callback
v5:  Drop the callback approach
v6:  Make walk-data struct pgtable specific and rename
     io_pgtable_walk_data to arm_lpae_io_pgtable_walk_data
v7:  Re-use the pgtable walker added for arm_lpae_read_and_clear_dirty()
v8:  Pass pte pointer to callback so it can modify the actual pte
v9:  Fix selftests_running case
v10: Call visit cb for all nodes traversed, leave the decision about
     whether to care about non-leaf nodes to the callback
v11: Adjust logic in 3/4 [smostafa@]

Rob Clark (4):
  iommu/io-pgtable-arm: Make pgtable walker more generic
  iommu/io-pgtable-arm: Re-use the pgtable walk for iova_to_phys
  iommu/io-pgtable-arm: Add way to debug pgtable walk
  drm/msm: Extend gpu devcore dumps with pgtbl info

 drivers/gpu/drm/msm/adreno/adreno_gpu.c |  10 ++
 drivers/gpu/drm/msm/msm_gpu.c           |   9 ++
 drivers/gpu/drm/msm/msm_gpu.h           |   8 ++
 drivers/gpu/drm/msm/msm_iommu.c         |  22 ++++
 drivers/gpu/drm/msm/msm_mmu.h           |   3 +-
 drivers/iommu/io-pgtable-arm.c          | 157 +++++++++++++++---------
 include/linux/io-pgtable.h              |  15 +++
 7 files changed, 167 insertions(+), 57 deletions(-)

-- 
2.47.1



From robdclark at gmail.com  Tue Dec 10 08:51:19 2024
From: robdclark at gmail.com (Rob Clark)
Date: Tue, 10 Dec 2024 08:51:19 -0800
Subject: [PATCH v11 1/4] iommu/io-pgtable-arm: Make pgtable walker more generic
In-Reply-To: <20241210165127.600817-1-robdclark@gmail.com>
References: <20241210165127.600817-1-robdclark@gmail.com>
Message-ID: <20241210165127.600817-2-robdclark@gmail.com>

From: Rob Clark <robdclark at chromium.org>

We can re-use this basic pgtable walk logic in a few places.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Reviewed-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/io-pgtable-arm.c | 67 ++++++++++++++++++++++------------
 1 file changed, 43 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 0e67f1721a3d..7e9c0f8ae138 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -749,33 +749,33 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
 }
 
 struct io_pgtable_walk_data {
-	struct iommu_dirty_bitmap	*dirty;
+	struct io_pgtable		*iop;
+	void				*data;
+	int (*visit)(struct io_pgtable_walk_data *walk_data, int lvl,
+		     arm_lpae_iopte *ptep, size_t size);
 	unsigned long			flags;
 	u64				addr;
 	const u64			end;
 };
 
-static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
-				       struct io_pgtable_walk_data *walk_data,
-				       arm_lpae_iopte *ptep,
-				       int lvl);
+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 io_pgtable_visit_dirty(struct arm_lpae_io_pgtable *data,
-				  struct io_pgtable_walk_data *walk_data,
-				  arm_lpae_iopte *ptep, int lvl)
+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 (iopte_leaf(pte, lvl, iop->fmt)) {
-		size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
+	size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
+	int ret = walk_data->visit(walk_data, lvl, ptep, size);
+	if (ret)
+		return ret;
 
-		if (iopte_writeable_dirty(pte)) {
-			iommu_dirty_bitmap_record(walk_data->dirty,
-						  walk_data->addr, size);
-			if (!(walk_data->flags & IOMMU_DIRTY_NO_CLEAR))
-				iopte_set_writeable_clean(ptep);
-		}
+	if (iopte_leaf(pte, lvl, iop->fmt)) {
 		walk_data->addr += size;
 		return 0;
 	}
@@ -784,13 +784,13 @@ static int io_pgtable_visit_dirty(struct arm_lpae_io_pgtable *data,
 		return -EINVAL;
 
 	ptep = iopte_deref(pte, data);
-	return __arm_lpae_iopte_walk_dirty(data, walk_data, ptep, lvl + 1);
+	return __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);
 }
 
-static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
-				       struct io_pgtable_walk_data *walk_data,
-				       arm_lpae_iopte *ptep,
-				       int lvl)
+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;
@@ -805,7 +805,7 @@ static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
 
 	for (idx = ARM_LPAE_LVL_IDX(walk_data->addr, lvl, data);
 	     (idx < max_entries) && (walk_data->addr < walk_data->end); ++idx) {
-		ret = io_pgtable_visit_dirty(data, walk_data, ptep + idx, lvl);
+		ret = io_pgtable_visit(data, walk_data, ptep + idx, lvl);
 		if (ret)
 			return ret;
 	}
@@ -813,6 +813,23 @@ static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
 	return 0;
 }
 
+static int visit_dirty(struct io_pgtable_walk_data *walk_data, int lvl,
+		       arm_lpae_iopte *ptep, size_t size)
+{
+	struct iommu_dirty_bitmap *dirty = walk_data->data;
+
+	if (!iopte_leaf(*ptep, lvl, walk_data->iop->fmt))
+		return 0;
+
+	if (iopte_writeable_dirty(*ptep)) {
+		iommu_dirty_bitmap_record(dirty, walk_data->addr, size);
+		if (!(walk_data->flags & IOMMU_DIRTY_NO_CLEAR))
+			iopte_set_writeable_clean(ptep);
+	}
+
+	return 0;
+}
+
 static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
 					 unsigned long iova, size_t size,
 					 unsigned long flags,
@@ -821,7 +838,9 @@ static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	struct io_pgtable_cfg *cfg = &data->iop.cfg;
 	struct io_pgtable_walk_data walk_data = {
-		.dirty = dirty,
+		.iop = &data->iop,
+		.data = dirty,
+		.visit = visit_dirty,
 		.flags = flags,
 		.addr = iova,
 		.end = iova + size,
@@ -836,7 +855,7 @@ static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
 	if (data->iop.fmt != ARM_64_LPAE_S1)
 		return -EINVAL;
 
-	return __arm_lpae_iopte_walk_dirty(data, &walk_data, ptep, lvl);
+	return __arm_lpae_iopte_walk(data, &walk_data, ptep, lvl);
 }
 
 static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
-- 
2.47.1



From robdclark at gmail.com  Tue Dec 10 08:51:20 2024
From: robdclark at gmail.com (Rob Clark)
Date: Tue, 10 Dec 2024 08:51:20 -0800
Subject: [PATCH v11 2/4] iommu/io-pgtable-arm: Re-use the pgtable walk for iova_to_phys
In-Reply-To: <20241210165127.600817-1-robdclark@gmail.com>
References: <20241210165127.600817-1-robdclark@gmail.com>
Message-ID: <20241210165127.600817-3-robdclark@gmail.com>

From: Rob Clark <robdclark at chromium.org>

Re-use the generic pgtable walk path.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Reviewed-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/io-pgtable-arm.c | 74 +++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 7e9c0f8ae138..88b128c77893 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -712,42 +712,6 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
 				data->start_level, ptep);
 }
 
-static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
-					 unsigned long iova)
-{
-	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
-	arm_lpae_iopte pte, *ptep = data->pgd;
-	int lvl = data->start_level;
-
-	do {
-		/* Valid IOPTE pointer? */
-		if (!ptep)
-			return 0;
-
-		/* Grab the IOPTE we're interested in */
-		ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
-		pte = READ_ONCE(*ptep);
-
-		/* Valid entry? */
-		if (!pte)
-			return 0;
-
-		/* Leaf entry? */
-		if (iopte_leaf(pte, lvl, data->iop.fmt))
-			goto found_translation;
-
-		/* Take it to the next level */
-		ptep = iopte_deref(pte, data);
-	} while (++lvl < ARM_LPAE_MAX_LEVELS);
-
-	/* Ran out of page tables to walk */
-	return 0;
-
-found_translation:
-	iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1);
-	return iopte_to_paddr(pte, data) | iova;
-}
-
 struct io_pgtable_walk_data {
 	struct io_pgtable		*iop;
 	void				*data;
@@ -763,6 +727,41 @@ static int __arm_lpae_iopte_walk(struct arm_lpae_io_pgtable *data,
 				 arm_lpae_iopte *ptep,
 				 int lvl);
 
+struct iova_to_phys_data {
+	arm_lpae_iopte pte;
+	int lvl;
+};
+
+static int visit_iova_to_phys(struct io_pgtable_walk_data *walk_data, int lvl,
+			      arm_lpae_iopte *ptep, size_t size)
+{
+	struct iova_to_phys_data *data = walk_data->data;
+	data->pte = *ptep;
+	data->lvl = lvl;
+	return 0;
+}
+
+static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
+					 unsigned long iova)
+{
+	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	struct iova_to_phys_data d;
+	struct io_pgtable_walk_data walk_data = {
+		.data = &d,
+		.visit = visit_iova_to_phys,
+		.addr = iova,
+		.end = iova + 1,
+	};
+	int ret;
+
+	ret = __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
+	if (ret)
+		return 0;
+
+	iova &= (ARM_LPAE_BLOCK_SIZE(d.lvl, data) - 1);
+	return iopte_to_paddr(d.pte, data) | iova;
+}
+
 static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
 			    struct io_pgtable_walk_data *walk_data,
 			    arm_lpae_iopte *ptep, int lvl)
@@ -780,8 +779,9 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
 		return 0;
 	}
 
-	if (WARN_ON(!iopte_table(pte, lvl)))
+	if (!iopte_table(pte, lvl)) {
 		return -EINVAL;
+	}
 
 	ptep = iopte_deref(pte, data);
 	return __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);
-- 
2.47.1



From robdclark at gmail.com  Tue Dec 10 08:51:21 2024
From: robdclark at gmail.com (Rob Clark)
Date: Tue, 10 Dec 2024 08:51:21 -0800
Subject: [PATCH v11 3/4] iommu/io-pgtable-arm: Add way to debug pgtable walk
In-Reply-To: <20241210165127.600817-1-robdclark@gmail.com>
References: <20241210165127.600817-1-robdclark@gmail.com>
Message-ID: <20241210165127.600817-4-robdclark@gmail.com>

From: Rob Clark <robdclark at chromium.org>

Add an io-pgtable method to walk the pgtable returning the raw PTEs that
would be traversed for a given iova access.

Signed-off-by: Rob Clark <robdclark at chromium.org>
---
 drivers/iommu/io-pgtable-arm.c | 26 ++++++++++++++++++++++++++
 include/linux/io-pgtable.h     | 15 +++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 88b128c77893..c51c48851f9f 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -762,6 +762,31 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
 	return iopte_to_paddr(d.pte, data) | iova;
 }
 
+static int visit_pgtable_walk(struct io_pgtable_walk_data *walk_data, int lvl,
+			      arm_lpae_iopte *ptep, size_t size)
+{
+	struct arm_lpae_io_pgtable_walk_data *data = walk_data->data;
+	data->ptes[lvl] = *ptep;
+	data->level = lvl + 1;
+	return 0;
+}
+
+static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
+				 void *wd)
+{
+	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	struct io_pgtable_walk_data walk_data = {
+		.data = wd,
+		.visit = visit_pgtable_walk,
+		.addr = iova,
+		.end = iova + 1,
+	};
+
+	((struct arm_lpae_io_pgtable_walk_data *)wd)->level = 0;
+
+	return __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
+}
+
 static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
 			    struct io_pgtable_walk_data *walk_data,
 			    arm_lpae_iopte *ptep, int lvl)
@@ -937,6 +962,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
 		.unmap_pages	= arm_lpae_unmap_pages,
 		.iova_to_phys	= arm_lpae_iova_to_phys,
 		.read_and_clear_dirty = arm_lpae_read_and_clear_dirty,
+		.pgtable_walk	= arm_lpae_pgtable_walk,
 	};
 
 	return data;
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index b1ecfc3cd5bc..d7bfbf351975 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -178,12 +178,26 @@ struct io_pgtable_cfg {
 	};
 };
 
+/**
+ * struct arm_lpae_io_pgtable_walk_data - information from a pgtable walk
+ *
+ * @ptes:     The recorded PTE values from the walk
+ * @level:    The level of the last PTE
+ *
+ * @level also specifies the last valid index in @ptes
+ */
+struct arm_lpae_io_pgtable_walk_data {
+	u64 ptes[4];
+	int level;
+};
+
 /**
  * struct io_pgtable_ops - Page table manipulation API for IOMMU drivers.
  *
  * @map_pages:    Map a physically contiguous range of pages of the same size.
  * @unmap_pages:  Unmap a range of virtually contiguous pages of the same size.
  * @iova_to_phys: Translate iova to physical address.
+ * @pgtable_walk: (optional) Perform a page table walk for a given iova.
  *
  * These functions map directly onto the iommu_ops member functions with
  * the same names.
@@ -197,6 +211,7 @@ struct io_pgtable_ops {
 			      struct iommu_iotlb_gather *gather);
 	phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops,
 				    unsigned long iova);
+	int (*pgtable_walk)(struct io_pgtable_ops *ops, unsigned long iova, void *wd);
 	int (*read_and_clear_dirty)(struct io_pgtable_ops *ops,
 				    unsigned long iova, size_t size,
 				    unsigned long flags,
-- 
2.47.1



From mark.rutland at arm.com  Tue Dec 10 08:56:25 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Dec 2024 16:56:25 +0000
Subject: [PATCH V2 5/7] arm64/cpufeature: Add field details for
 ID_AA64DFR1_EL1 register
In-Reply-To: <20241210164144.GA16039@willie-the-truck>
References: <20241028053426.2486633-1-anshuman.khandual@arm.com>
 <20241028053426.2486633-6-anshuman.khandual@arm.com>
 <20241210164144.GA16039@willie-the-truck>
Message-ID: <Z1hyueAQJTroNIRW@J2N7QTR9R3>

On Tue, Dec 10, 2024 at 04:41:44PM +0000, Will Deacon wrote:
> On Mon, Oct 28, 2024 at 11:04:24AM +0530, Anshuman Khandual wrote:
> > +static const struct arm64_ftr_bits ftr_id_aa64dfr1[] = {
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABL_CMPs_SHIFT, 8, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_DPFZS_SHIFT, 4, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_EBEP_SHIFT, 4, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ITE_SHIFT, 4, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABLE_SHIFT, 4, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_PMICNTR_SHIFT, 4, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SPMU_SHIFT, 4, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_CTX_CMPs_SHIFT, 8, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_WRPs_SHIFT, 8, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_BRPs_SHIFT, 8, 0),
> > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SYSPMUID_SHIFT, 8, 0),
> > +	ARM64_FTR_END,
> > +};
> 
> I think I mentioned this on an earlier series, but it would be useful to
> see some justification in the commit message as to why some of these
> features are considered STRICT vs NONSTRICT and why LOWER_SAFE is
> preferred over EXACT.
> 
> For example, why is EBEP strict whereas other PMU-related fields aren't?
> Why is the CTX_CMPs field treated differently to the same field in DFR0?
> 
> I'm not saying the above table is wrong, it just looks arbitrary without
> the justification.

FWIW, Anshuman and I discussed that on the v1 thread, after this v2
thread was posted. Anshuman promised to provide some rationale and make
some updates in the next version (i.e. v3):

  https://lore.kernel.org/linux-arm-kernel/8efe902c-8b9f-494a-b9da-430d8ced32ef at arm.com/

Mark.


From mark.rutland at arm.com  Tue Dec 10 08:59:32 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Dec 2024 16:59:32 +0000
Subject: [PATCH V2 0/7] arm64/hw_breakpoint: Enable FEAT_Debugv8p9
In-Reply-To: <20241028053426.2486633-1-anshuman.khandual@arm.com>
References: <20241028053426.2486633-1-anshuman.khandual@arm.com>
Message-ID: <Z1hzdLQLlIPg7eV5@J2N7QTR9R3>

On Mon, Oct 28, 2024 at 11:04:19AM +0530, Anshuman Khandual wrote:
> This series enables FEAT_Debugv8p9 thus extending breakpoint and watchpoint
> support upto 64. This series is based on v6.12-rc5 although this depends on
> FEAT_FGT2 FGU series posted earlier, for MDSELR_EL1 handling in various KVM
> guest configurations.
> 
> https://lore.kernel.org/all/20241001024356.1096072-1-anshuman.khandual at arm.com/

To avoid further confusion: since we discussed things further on the v1
thread after this v2 thread was posted, I'm waiting for a v3 to be
posted which addresses the comments there (e.g. ID reg field handling,
mutual exclusion for breakpoint manipulation).

Mark.

> Cc: Jonathan Corbet <corbet at lwn.net>
> 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: Mark Brown <broonie at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.linux.dev
> Cc: linux-kernel at vger.kernel.org
> 
> Changes in V2:
> 
> Following changes have been made per review comments from Mark Rutland
> 
> - Orr MDCR_EL2_EBWE directly without an intermittent register
> - Alphabetically order header files in debug-monitors.c
> - Dropped embwe_ref_count mechanism
> - Dropped preempt_enable() from AARCH64_DBG_READ
> - Dropped preempt_disable() from AARCH64_DBG_WRITE
> - Dropped set_bank_index()
> - Renamed read/write_wb_reg() as __read/__write_wb_reg()
> - Modified read/write_wb_reg() to have MDSELR_E1 based banked read/write
> - Added required sysreg tools patches from KVM FEAT_FGT2 series for build
> 
> Changes in V1:
> 
> https://lore.kernel.org/all/20241001043602.1116991-1-anshuman.khandual at arm.com/
> 
> - Changed FTR_STRICT to FTR_NONSTRICT for the following ID_AA64DFR1_EL1
>   register fields - ABL_CMPs, DPFZS, PMICNTR, CTX_CMPs, WRPs and BRPs
> 
> Changes in RFC V2:
> 
> https://lore.kernel.org/linux-arm-kernel/20240620092607.267132-1-anshuman.khandual at arm.com/
> 
> - This series has been split from RFC V1 dealing only with arm64 breakpoints
> - Restored back DBG_MDSCR_MASK definition (unrelated change)
> - Added preempt_disable()/enable() blocks between selecting banks and registers
> 
> Changes in RFC:
> 
> https://lore.kernel.org/all/20240405080008.1225223-1-anshuman.khandual at arm.com/
> 
> Anshuman Khandual (7):
>   arm64/sysreg: Update register fields for ID_AA64MMFR0_EL1
>   arm64/sysreg: Add register fields for MDSELR_EL1
>   arm64/sysreg: Add register fields for HDFGRTR2_EL2
>   arm64/sysreg: Add register fields for HDFGWTR2_EL2
>   arm64/cpufeature: Add field details for ID_AA64DFR1_EL1 register
>   arm64/boot: Enable EL2 requirements for FEAT_Debugv8p9
>   arm64/hw_breakpoint: Enable FEAT_Debugv8p9
> 
>  Documentation/arch/arm64/booting.rst    | 19 +++++++
>  arch/arm64/include/asm/debug-monitors.h |  1 +
>  arch/arm64/include/asm/el2_setup.h      | 26 +++++++++
>  arch/arm64/include/asm/hw_breakpoint.h  | 46 ++++++++++++----
>  arch/arm64/include/asm/kvm_arm.h        |  1 +
>  arch/arm64/kernel/cpufeature.c          | 21 ++++++--
>  arch/arm64/kernel/debug-monitors.c      | 15 ++++--
>  arch/arm64/kernel/hw_breakpoint.c       | 38 +++++++++++++-
>  arch/arm64/tools/sysreg                 | 70 +++++++++++++++++++++++++
>  9 files changed, 216 insertions(+), 21 deletions(-)
> 
> -- 
> 2.25.1
> 


From lkp at intel.com  Tue Dec 10 09:02:12 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 11 Dec 2024 01:02:12 +0800
Subject: [PATCH 6/6] arm64: errata: Add QCOM_KRYO_6XX_GOLD/PRIME to the
 spectre_bhb_k32_list
In-Reply-To: <20241209094310.6.I722621804be859e4ae4b7479ce191c5e3367b37c@changeid>
References: <20241209094310.6.I722621804be859e4ae4b7479ce191c5e3367b37c@changeid>
Message-ID: <202412110032.Sku0iZvD-lkp@intel.com>

Hi Douglas,

kernel test robot noticed the following build errors:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on arm-perf/for-next/perf kvmarm/next soc/for-next arm/for-next arm/fixes linus/master v6.13-rc2 next-20241210]
[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/Douglas-Anderson/arm64-errata-Add-QCOM_KRYO_4XX_GOLD-to-the-spectre_bhb_k24_list/20241210-014833
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
patch link:    https://lore.kernel.org/r/20241209094310.6.I722621804be859e4ae4b7479ce191c5e3367b37c%40changeid
patch subject: [PATCH 6/6] arm64: errata: Add QCOM_KRYO_6XX_GOLD/PRIME to the spectre_bhb_k32_list
config: arm64-allnoconfig (https://download.01.org/0day-ci/archive/20241211/202412110032.Sku0iZvD-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241211/202412110032.Sku0iZvD-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/202412110032.Sku0iZvD-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from arch/arm64/include/asm/cache.h:43,
                    from include/linux/cache.h:6,
                    from include/linux/jiffies.h:5,
                    from include/linux/ktime.h:25,
                    from include/linux/timer.h:6,
                    from include/linux/workqueue.h:9,
                    from include/linux/bpf.h:10,
                    from arch/arm64/kernel/proton-pack.c:21:
   arch/arm64/kernel/proton-pack.c: In function 'spectre_bhb_loop_affected':
>> arch/arm64/kernel/proton-pack.c:863:43: error: 'MIDR_QCOM_KRYO_6XX_GOLD' undeclared (first use in this function); did you mean 'MIDR_QCOM_KRYO_4XX_GOLD'?
     863 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_GOLD),
         |                                           ^~~~~~~~~~~~~~~~~~~~~~~
   arch/arm64/include/asm/cputype.h:251:26: note: in definition of macro 'MIDR_RANGE'
     251 |                 .model = m,                                     \
         |                          ^
   arch/arm64/kernel/proton-pack.c:863:25: note: in expansion of macro 'MIDR_ALL_VERSIONS'
     863 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_GOLD),
         |                         ^~~~~~~~~~~~~~~~~
   arch/arm64/kernel/proton-pack.c:863:43: note: each undeclared identifier is reported only once for each function it appears in
     863 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_GOLD),
         |                                           ^~~~~~~~~~~~~~~~~~~~~~~
   arch/arm64/include/asm/cputype.h:251:26: note: in definition of macro 'MIDR_RANGE'
     251 |                 .model = m,                                     \
         |                          ^
   arch/arm64/kernel/proton-pack.c:863:25: note: in expansion of macro 'MIDR_ALL_VERSIONS'
     863 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_GOLD),
         |                         ^~~~~~~~~~~~~~~~~
>> arch/arm64/kernel/proton-pack.c:864:43: error: 'MIDR_QCOM_KRYO_6XX_PRIME' undeclared (first use in this function); did you mean 'MIDR_QCOM_KRYO_3XX_SILVER'?
     864 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_PRIME),
         |                                           ^~~~~~~~~~~~~~~~~~~~~~~~
   arch/arm64/include/asm/cputype.h:251:26: note: in definition of macro 'MIDR_RANGE'
     251 |                 .model = m,                                     \
         |                          ^
   arch/arm64/kernel/proton-pack.c:864:25: note: in expansion of macro 'MIDR_ALL_VERSIONS'
     864 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_PRIME),
         |                         ^~~~~~~~~~~~~~~~~
   arch/arm64/kernel/proton-pack.c:872:43: error: 'MIDR_QCOM_KRYO_5XX_GOLD' undeclared (first use in this function); did you mean 'MIDR_QCOM_KRYO_4XX_GOLD'?
     872 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
         |                                           ^~~~~~~~~~~~~~~~~~~~~~~
   arch/arm64/include/asm/cputype.h:251:26: note: in definition of macro 'MIDR_RANGE'
     251 |                 .model = m,                                     \
         |                          ^
   arch/arm64/kernel/proton-pack.c:872:25: note: in expansion of macro 'MIDR_ALL_VERSIONS'
     872 |                         MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
         |                         ^~~~~~~~~~~~~~~~~


vim +863 arch/arm64/kernel/proton-pack.c

   843	
   844	/*
   845	 * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
   846	 * SCOPE_SYSTEM call will give the right answer.
   847	 */
   848	u8 spectre_bhb_loop_affected(int scope)
   849	{
   850		u8 k = 0;
   851		static u8 max_bhb_k;
   852	
   853		if (scope == SCOPE_LOCAL_CPU) {
   854			static const struct midr_range spectre_bhb_k32_list[] = {
   855				MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
   856				MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
   857				MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
   858				MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
   859				MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
   860				MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
   861				MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
   862				MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
 > 863				MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_GOLD),
 > 864				MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_6XX_PRIME),
   865				{},
   866			};
   867			static const struct midr_range spectre_bhb_k24_list[] = {
   868				MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
   869				MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
   870				MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
   871				MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
   872				MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_5XX_GOLD),
   873				{},
   874			};
   875			static const struct midr_range spectre_bhb_k11_list[] = {
   876				MIDR_ALL_VERSIONS(MIDR_AMPERE1),
   877				{},
   878			};
   879			static const struct midr_range spectre_bhb_k8_list[] = {
   880				MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
   881				MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
   882				{},
   883			};
   884	
   885			if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
   886				k = 32;
   887			else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
   888				k = 24;
   889			else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
   890				k = 11;
   891			else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
   892				k =  8;
   893	
   894			max_bhb_k = max(max_bhb_k, k);
   895		} else {
   896			k = max_bhb_k;
   897		}
   898	
   899		return k;
   900	}
   901	

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


From will at kernel.org  Tue Dec 10 09:05:20 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 17:05:20 +0000
Subject: [PATCH V2 5/7] arm64/cpufeature: Add field details for
 ID_AA64DFR1_EL1 register
In-Reply-To: <Z1hyueAQJTroNIRW@J2N7QTR9R3>
References: <20241028053426.2486633-1-anshuman.khandual@arm.com>
 <20241028053426.2486633-6-anshuman.khandual@arm.com>
 <20241210164144.GA16039@willie-the-truck>
 <Z1hyueAQJTroNIRW@J2N7QTR9R3>
Message-ID: <20241210170519.GA16075@willie-the-truck>

On Tue, Dec 10, 2024 at 04:56:25PM +0000, Mark Rutland wrote:
> On Tue, Dec 10, 2024 at 04:41:44PM +0000, Will Deacon wrote:
> > On Mon, Oct 28, 2024 at 11:04:24AM +0530, Anshuman Khandual wrote:
> > > +static const struct arm64_ftr_bits ftr_id_aa64dfr1[] = {
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABL_CMPs_SHIFT, 8, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_DPFZS_SHIFT, 4, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_EBEP_SHIFT, 4, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ITE_SHIFT, 4, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABLE_SHIFT, 4, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_PMICNTR_SHIFT, 4, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SPMU_SHIFT, 4, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_CTX_CMPs_SHIFT, 8, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_WRPs_SHIFT, 8, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_BRPs_SHIFT, 8, 0),
> > > +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SYSPMUID_SHIFT, 8, 0),
> > > +	ARM64_FTR_END,
> > > +};
> > 
> > I think I mentioned this on an earlier series, but it would be useful to
> > see some justification in the commit message as to why some of these
> > features are considered STRICT vs NONSTRICT and why LOWER_SAFE is
> > preferred over EXACT.
> > 
> > For example, why is EBEP strict whereas other PMU-related fields aren't?
> > Why is the CTX_CMPs field treated differently to the same field in DFR0?
> > 
> > I'm not saying the above table is wrong, it just looks arbitrary without
> > the justification.
> 
> FWIW, Anshuman and I discussed that on the v1 thread, after this v2
> thread was posted. Anshuman promised to provide some rationale and make
> some updates in the next version (i.e. v3):
> 
>   https://lore.kernel.org/linux-arm-kernel/8efe902c-8b9f-494a-b9da-430d8ced32ef at arm.com/

Perfect! I'll wait for the v3, then.

Will


From will at kernel.org  Tue Dec 10 09:09:55 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 17:09:55 +0000
Subject: [PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
 <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>
Message-ID: <20241210170953.GB16075@willie-the-truck>

On Tue, Dec 03, 2024 at 12:39:21PM +0000, Mark Brown wrote:
> DDI0601 2024-09 defines several new feature flags in ID_AA64ISAR3_EL1,
> update our description in sysreg to reflect these.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/tools/sysreg | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 911f16c82ebd3ee98ffed965b02a5c6b153bc50c..c5af604eda6a721cedf5c9c68d6f7038156de651 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -1566,7 +1566,23 @@ EndEnum
>  EndSysreg
>  
>  Sysreg	ID_AA64ISAR3_EL1	3	0	0	6	3
> -Res0	63:16
> +Res0	63:32
> +UnsignedEnum	31:28	FPRCVT
> +	0b0000	NI
> +	0b0010	IMP
> +EndEnum
> +UnsignedEnum	27:24	LSUI
> +	0b0000	NI
> +	0b0010	IMP
> +EndEnum
> +UnsignedEnum	23:20	OCCMO
> +	0b0000	NI
> +	0b0010	IMP
> +EndEnum
> +UnsignedEnum	19:16	LSFE
> +	0b0000	NI
> +	0b0010	IMP

These IMP encodings look wrong to me -- the document you reference in
the commit message uses 0b0001 for the "implemented" cases.

Can we _please_ just generate this stuff. It feels like we've been
making silly typos over and over again with the current approach so
either it's hard or we're not very good at it. Either way, it should be
automated.

Others have managed it [1], so it's clearly do-able.

Will

[1] https://github.com/ashwio/arm64-sysreg-lib


From florian.fainelli at broadcom.com  Tue Dec 10 09:30:11 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 10 Dec 2024 09:30:11 -0800
Subject: [PATCH net-next 5/9] net: dsa: mt753x: implement .support_eee()
 method
In-Reply-To: <E1tL14J-006cZa-Rh@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL14J-006cZa-Rh@rmk-PC.armlinux.org.uk>
Message-ID: <ad11506a-3b11-4584-8efb-8075158527b2@broadcom.com>

On 12/10/24 06:18, Russell King (Oracle) wrote:
> Implement the .support_eee() method by using the generic helper as all
> user ports support EEE.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From florian.fainelli at broadcom.com  Tue Dec 10 09:30:21 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 10 Dec 2024 09:30:21 -0800
Subject: [PATCH net-next 6/9] net: dsa: qca8k: implement .support_eee()
 method
In-Reply-To: <E1tL14O-006cZg-VM@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL14O-006cZg-VM@rmk-PC.armlinux.org.uk>
Message-ID: <d806f833-1801-4d99-8e35-7eb09108d549@broadcom.com>

On 12/10/24 06:18, Russell King (Oracle) wrote:
> Implement the .support_eee() method by using the generic helper as all
> user ports support EEE.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From florian.fainelli at broadcom.com  Tue Dec 10 09:30:31 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 10 Dec 2024 09:30:31 -0800
Subject: [PATCH net-next 7/9] net: dsa: mv88e6xxx: implement
 .support_eee() method
In-Reply-To: <E1tL14U-006cZm-2K@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL14U-006cZm-2K@rmk-PC.armlinux.org.uk>
Message-ID: <572fb811-c42f-45c5-9c76-2a25601192e2@broadcom.com>

On 12/10/24 06:18, Russell King (Oracle) wrote:
> Implement the .support_eee() method by using the generic helper as all
> user ports support EEE.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From florian.fainelli at broadcom.com  Tue Dec 10 09:30:54 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 10 Dec 2024 09:30:54 -0800
Subject: [PATCH net-next 8/9] net: dsa: ksz: implement .support_eee()
 method
In-Reply-To: <E1tL14Z-006cZs-6o@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL14Z-006cZs-6o@rmk-PC.armlinux.org.uk>
Message-ID: <e92574b2-3698-4eeb-834b-fac780a6308c@broadcom.com>

On 12/10/24 06:18, Russell King (Oracle) wrote:
> Implement the .support_eee() method by reusing the ksz_validate_eee()
> method as a template, renaming the function, changing the return type
> and values, and removing it from the ksz_set_mac_eee() and
> ksz_get_mac_eee() methods.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From florian.fainelli at broadcom.com  Tue Dec 10 09:31:11 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 10 Dec 2024 09:31:11 -0800
Subject: [PATCH net-next 9/9] net: dsa: require .support_eee() method to
 be implemented
In-Reply-To: <E1tL14e-006cZy-AT@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL14e-006cZy-AT@rmk-PC.armlinux.org.uk>
Message-ID: <5531df46-8997-4d1f-8ddd-7ae9d5e56689@broadcom.com>

On 12/10/24 06:18, Russell King (Oracle) wrote:
> Now that we have updated all drivers, switch DSA to require an
> implementation of the .support_eee() method for EEE to be usable,
> rather than defaulting to being permissive when not implemented.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From florian.fainelli at broadcom.com  Tue Dec 10 09:29:05 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 10 Dec 2024 09:29:05 -0800
Subject: [PATCH net-next 1/9] net: dsa: remove check for dp->pl in EEE
 methods
In-Reply-To: <E1tL13z-006cZ7-BZ@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL13z-006cZ7-BZ@rmk-PC.armlinux.org.uk>
Message-ID: <26fb01e6-a735-4bdc-a074-5dd141d9db48@broadcom.com>

On 12/10/24 06:18, Russell King (Oracle) wrote:
> When user ports are initialised, a phylink instance is always created,
> and so dp->pl will always be non-NULL. The EEE methods are only used
> for user ports, so checking for dp->pl to be NULL makes no sense. No
> other phylink-calling method implements similar checks in DSA. Remove
> this unnecessary check.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From florian.fainelli at broadcom.com  Tue Dec 10 09:29:39 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 10 Dec 2024 09:29:39 -0800
Subject: [PATCH net-next 3/9] net: dsa: provide implementation of
 .support_eee()
In-Reply-To: <E1tL149-006cZJ-JJ@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL149-006cZJ-JJ@rmk-PC.armlinux.org.uk>
Message-ID: <fafda63f-687a-4a3e-99f9-2a6abfbb5d59@broadcom.com>

On 12/10/24 06:18, Russell King (Oracle) wrote:
> Provide a trivial implementation for the .support_eee() method which
> switch drivers can use to simply indicate that they support EEE on
> all their user ports.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From florian.fainelli at broadcom.com  Tue Dec 10 09:30:00 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 10 Dec 2024 09:30:00 -0800
Subject: [PATCH net-next 4/9] net: dsa: b53/bcm_sf2: implement
 .support_eee() method
In-Reply-To: <E1tL14E-006cZU-Nc@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL14E-006cZU-Nc@rmk-PC.armlinux.org.uk>
Message-ID: <bc03a1e5-b67c-42da-9856-7c77d6858138@broadcom.com>

On 12/10/24 06:18, Russell King (Oracle) wrote:
> Implement the .support_eee() method to indicate that EEE is not
> supported by two switch variants, rather than making these checks in
> the .set_mac_eee() and .get_mac_eee() methods.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From kaleshsingh at google.com  Tue Dec 10 09:34:01 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Tue, 10 Dec 2024 09:34:01 -0800
Subject: [PATCH mm-unstable 17/17] mm: Respect mmap hint before THP
 alignment if allocation is possible
In-Reply-To: <CAHbLzkq2SNaqzx4d981H2QfQvtObS3X0pPL8=oqFsFbMditWPA@mail.gmail.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
 <20241210024119.2488608-18-kaleshsingh@google.com> <CAHbLzkq2SNaqzx4d981H2QfQvtObS3X0pPL8=oqFsFbMditWPA@mail.gmail.com>
Message-ID: <CAC_TJvdReRHzBSgg2iqOw3Kw6BBOtwGE=8nB2Hsw-nsmkxN0+g@mail.gmail.com>

On Mon, Dec 9, 2024 at 7:37?PM Yang Shi <shy828301 at gmail.com> wrote:
>
> On Mon, Dec 9, 2024 at 6:45?PM Kalesh Singh <kaleshsingh at google.com> wrote:
> >
> > Commit 249608ee4713 ("mm: respect mmap hint address when aligning for THP")
> > fallsback to PAGE_SIZE alignment instead of THP alignment
> > for anonymous mapping as long as a hint address is provided by the user
> > -- even if we weren't able to allocate the unmapped area at the hint
> > address in the end.
> >
> > This was done to address the immediate regression in anonymous mappings
> > where the hint address were being ignored in some cases; due to commit
> > efa7df3e3bb5 ("mm: align larger anonymous mappings on THP boundaries").
> >
> > It was later pointed out that this issue also existed for file-backed
> > mappings from file systems that use thp_get_unmapped_area() for their
> > .get_unmapped_area() file operation.
> >
> > The same fix was not applied for file-backed mappings since it would
> > mean any mmap requests that provide a hint address would be only
> > PAGE_SIZE-aligned regardless of whether allocation was successful at
> > the hint address or not.
> >
> > Instead, use arch_mmap_hint() to first attempt allocation at the hint
> > address and fallback to THP alignment if that fails.
>
> Thanks for taking time to try to fix this.
>
> >
> > Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
> > ---
> >  mm/huge_memory.c | 15 ++++++++-------
> >  mm/mmap.c        |  1 -
> >  2 files changed, 8 insertions(+), 8 deletions(-)
> >
> > diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> > index 137abeda8602..f070c89dafc9 100644
> > --- a/mm/huge_memory.c
> > +++ b/mm/huge_memory.c
> > @@ -1097,6 +1097,14 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
> >         loff_t off_align = round_up(off, size);
> >         unsigned long len_pad, ret, off_sub;
> >
> > +       /*
> > +        * If allocation at the address hint succeeds; respect the hint and
> > +        * don't try to align to THP boundary.
> > +        */
> > +       addr = arch_mmap_hint(filp, addr, len, off, flags);
> > +       if (addr)
> > +               return addr;
> > +

Hi Yang,

Thanks for the comments.

>
> IIUC, arch_mmap_hint() will be called in arch_get_unmapped_area() and
> arch_get_unmapped_area_topdown() again. So we will actually look up
> maple tree twice. It sounds like the second hint address search is
> pointless. You should be able to set addr to 0 before calling
> mm_get_unmapped_area_vmflags() in order to skip the second hint
> address search.

You are right that it would call into arch_mmap_hint() twice but it
only attempts the lookup once since on the second attempt addr == 0.

Thanks,
Kalesh
>
> >         if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall())
> >                 return 0;
> >
> > @@ -1117,13 +1125,6 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
> >         if (IS_ERR_VALUE(ret))
> >                 return 0;
> >
> > -       /*
> > -        * Do not try to align to THP boundary if allocation at the address
> > -        * hint succeeds.
> > -        */
> > -       if (ret == addr)
> > -               return addr;
> > -
> >         off_sub = (off - ret) & (size - 1);
> >
> >         if (test_bit(MMF_TOPDOWN, &current->mm->flags) && !off_sub)
> > diff --git a/mm/mmap.c b/mm/mmap.c
> > index 59bf7d127aa1..6bfeec80152a 100644
> > --- a/mm/mmap.c
> > +++ b/mm/mmap.c
> > @@ -807,7 +807,6 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
> >         if (get_area) {
> >                 addr = get_area(file, addr, len, pgoff, flags);
> >         } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && !file
> > -                  && !addr /* no hint */
> >                    && IS_ALIGNED(len, PMD_SIZE)) {
> >                 /* Ensures that larger anonymous mappings are THP aligned. */
> >                 addr = thp_get_unmapped_area_vmflags(file, addr, len,
> > --
> > 2.47.0.338.g60cca15819-goog
> >
> >


From kaleshsingh at google.com  Tue Dec 10 09:55:27 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Tue, 10 Dec 2024 09:55:27 -0800
Subject: [PATCH mm-unstable 01/17] mm: Introduce generic_mmap_hint()
In-Reply-To: <CAHbLzkpCRGF+-WXkHVEutkEGHSWydmpb1CwkvHZRTH-f773J-w@mail.gmail.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
 <20241210024119.2488608-2-kaleshsingh@google.com> <CAHbLzkpCRGF+-WXkHVEutkEGHSWydmpb1CwkvHZRTH-f773J-w@mail.gmail.com>
Message-ID: <CAC_TJvc5SU_khaBf7NS1VvD+d5PJ4X1DwKWbO92j-dZ+rEuc9A@mail.gmail.com>

On Mon, Dec 9, 2024 at 7:27?PM Yang Shi <shy828301 at gmail.com> wrote:
>
> On Mon, Dec 9, 2024 at 6:41?PM Kalesh Singh <kaleshsingh at google.com> wrote:
> >
> > Consolidate the hint searches from both direcitons (topdown and
> > bottomup) into generic_mmap_hint().
> >
> > No functional change is introduced.
> >
> > Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
> > ---
> >  include/linux/sched/mm.h |  4 ++++
> >  mm/mmap.c                | 45 ++++++++++++++++++++++++----------------
> >  2 files changed, 31 insertions(+), 18 deletions(-)
> >
> > diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
> > index 928a626725e6..edeec19d1708 100644
> > --- a/include/linux/sched/mm.h
> > +++ b/include/linux/sched/mm.h
> > @@ -201,6 +201,10 @@ unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm,
> >                                            unsigned long flags,
> >                                            vm_flags_t vm_flags);
> >
> > +unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
> > +                               unsigned long len, unsigned long pgoff,
> > +                               unsigned long flags);
> > +
> >  unsigned long
> >  generic_get_unmapped_area(struct file *filp, unsigned long addr,
> >                           unsigned long len, unsigned long pgoff,
> > diff --git a/mm/mmap.c b/mm/mmap.c
> > index df9154b15ef9..e97eb8bf4889 100644
> > --- a/mm/mmap.c
> > +++ b/mm/mmap.c
> > @@ -620,6 +620,27 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)
> >         return addr;
> >  }
> >
> > +unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
> > +                               unsigned long len, unsigned long pgoff,
> > +                               unsigned long flags)
> > +{
> > +       struct mm_struct *mm = current->mm;
> > +       struct vm_area_struct *vma, *prev;
> > +       const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
> > +
> > +       if (!addr)
> > +               return 0;
> > +
> > +       addr = PAGE_ALIGN(addr);
> > +       vma = find_vma_prev(mm, addr, &prev);
> > +       if (mmap_end - len >= addr && addr >= mmap_min_addr &&
> > +           (!vma || addr + len <= vm_start_gap(vma)) &&
> > +           (!prev || addr >= vm_end_gap(prev)))
> > +               return addr;
> > +
> > +       return 0;
> > +}
> > +
> >  /* Get an address range which is currently unmapped.
> >   * For shmat() with addr=0.
> >   *
> > @@ -637,7 +658,6 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
> >                           unsigned long flags, vm_flags_t vm_flags)
> >  {
> >         struct mm_struct *mm = current->mm;
> > -       struct vm_area_struct *vma, *prev;
> >         struct vm_unmapped_area_info info = {};
> >         const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
> >
> > @@ -647,14 +667,9 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
> >         if (flags & MAP_FIXED)
> >                 return addr;
>
> It seems you also can move the MAP_FIXED case into generic_mmap_hint(), right?

I think that could be done too. we'll need a new name :) Let me take a
look at it ...

-- Kalesh

>
> >
> > -       if (addr) {
> > -               addr = PAGE_ALIGN(addr);
> > -               vma = find_vma_prev(mm, addr, &prev);
> > -               if (mmap_end - len >= addr && addr >= mmap_min_addr &&
> > -                   (!vma || addr + len <= vm_start_gap(vma)) &&
> > -                   (!prev || addr >= vm_end_gap(prev)))
> > -                       return addr;
> > -       }
> > +       addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
> > +       if (addr)
> > +               return addr;
> >
> >         info.length = len;
> >         info.low_limit = mm->mmap_base;
> > @@ -685,7 +700,6 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
> >                                   unsigned long len, unsigned long pgoff,
> >                                   unsigned long flags, vm_flags_t vm_flags)
> >  {
> > -       struct vm_area_struct *vma, *prev;
> >         struct mm_struct *mm = current->mm;
> >         struct vm_unmapped_area_info info = {};
> >         const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
> > @@ -698,14 +712,9 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
> >                 return addr;
> >
> >         /* requesting a specific address */
> > -       if (addr) {
> > -               addr = PAGE_ALIGN(addr);
> > -               vma = find_vma_prev(mm, addr, &prev);
> > -               if (mmap_end - len >= addr && addr >= mmap_min_addr &&
> > -                               (!vma || addr + len <= vm_start_gap(vma)) &&
> > -                               (!prev || addr >= vm_end_gap(prev)))
> > -                       return addr;
> > -       }
> > +       addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
> > +       if (addr)
> > +               return addr;
> >
> >         info.flags = VM_UNMAPPED_AREA_TOPDOWN;
> >         info.length = len;
> > --
> > 2.47.0.338.g60cca15819-goog
> >
> >


From ivo.ivanov.ivanov1 at gmail.com  Tue Dec 10 10:02:15 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Tue, 10 Dec 2024 20:02:15 +0200
Subject: [PATCH v1 1/2] arm64: dts: exynos8895: Add a PMU node for the second cluster
In-Reply-To: <20241210180216.398165-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241210180216.398165-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <20241210180216.398165-2-ivo.ivanov.ivanov1@gmail.com>

Since we have a PMU compatible for Samsung's Mongoose cores now, drop
the comment that explains the lack of it and define the node.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
---
 arch/arm64/boot/dts/exynos/exynos8895.dtsi | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos8895.dtsi b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
index ee393f4f0..90b318b2f 100644
--- a/arch/arm64/boot/dts/exynos/exynos8895.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
@@ -38,7 +38,17 @@ arm-a53-pmu {
 				     <&cpu3>;
 	};
 
-	/* There's no PMU model for the Mongoose cores */
+	mongoose-m2-pmu {
+		compatible = "samsung,mongoose-pmu";
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu4>,
+				     <&cpu5>,
+				     <&cpu6>,
+				     <&cpu7>;
+	};
 
 	cpus {
 		#address-cells = <1>;
-- 
2.43.0



From ivo.ivanov.ivanov1 at gmail.com  Tue Dec 10 10:02:14 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Tue, 10 Dec 2024 20:02:14 +0200
Subject: [PATCH v1 0/2] arm64: dts: exynos8895: Add m2-pmu, poweroff and reboot
Message-ID: <20241210180216.398165-1-ivo.ivanov.ivanov1@gmail.com>

Hey folks,

This series adds support for syscon-reboot and syscon-poweroff to
exynos8895, as well as support for the mongoose cluster PMU in DT hence
a compatible for that was recently added.

The new syscon nodes have been tested with reboot and poweroff commands
respectively.

Kind regards,
Ivo

Ivaylo Ivanov (2):
  arm64: dts: exynos8895: Add a PMU node for the second cluster
  arm64: dts: exynos8895: Add syscon-poweroff and syscon-reboot nodes

 arch/arm64/boot/dts/exynos/exynos8895.dtsi | 27 +++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

-- 
2.43.0



From ivo.ivanov.ivanov1 at gmail.com  Tue Dec 10 10:02:16 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Tue, 10 Dec 2024 20:02:16 +0200
Subject: [PATCH v1 2/2] arm64: dts: exynos8895: Add syscon-poweroff and syscon-reboot nodes
In-Reply-To: <20241210180216.398165-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241210180216.398165-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <20241210180216.398165-3-ivo.ivanov.ivanov1@gmail.com>

For Exynos8895, a reboot is handled by setting the bit(SWRESET_SYSTEM[1])
of SWRESET register(PMU + 0x400) and power-off is handled by setting
bit(DATA[8]) of PS_HOLD_CONTROL register (PMU + 0x330c).

Tested using "reboot" and "poweroff -p" commands.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
---
 arch/arm64/boot/dts/exynos/exynos8895.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos8895.dtsi b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
index 90b318b2f..9eb89dd19 100644
--- a/arch/arm64/boot/dts/exynos/exynos8895.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
@@ -388,6 +388,21 @@ pmu_system_controller: system-controller at 16480000 {
 			compatible = "samsung,exynos8895-pmu",
 				     "samsung,exynos7-pmu", "syscon";
 			reg = <0x16480000 0x10000>;
+
+			poweroff: syscon-poweroff {
+				compatible = "syscon-poweroff";
+				regmap = <&pmu_system_controller>;
+				offset = <0x330c>; /* PS_HOLD_CONTROL */
+				mask = <0x100>; /* reset value */
+			};
+
+			reboot: syscon-reboot {
+				compatible = "syscon-reboot";
+				regmap = <&pmu_system_controller>;
+				offset = <0x400>; /* SWRESET */
+				mask = <0x1>; /* SWRESET_SYSTEM */
+				value = <0x1>; /* reset value */
+			};
 		};
 
 		pinctrl_alive: pinctrl at 164b0000 {
-- 
2.43.0



From will at kernel.org  Tue Dec 10 10:34:45 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 18:34:45 +0000
Subject: [PATCH v4] arm64/cpufeature: Refactor conditional logic in init_cpu_ftr_reg()
In-Reply-To: <20241115053740.20523-1-hardevsinh.palaniya@siliconsignals.io>
References: <20241115053740.20523-1-hardevsinh.palaniya@siliconsignals.io>
Message-ID: <173383298019.2041619.15466719029042277892.b4-ty@kernel.org>

On Fri, 15 Nov 2024 11:06:35 +0530, Hardevsinh Palaniya wrote:
> Unnecessarily checks ftr_ovr == tmp in an extra else if, which is not
> needed because that condition would already be true by default if the
> previous conditions are not satisfied.
> 
> 		if (ftr_ovr != tmp) {
> 		} else if (ftr_new != tmp) {
> 		} else if (ftr_ovr == tmp) {
> 
> [...]

Applied to arm64 (for-next/cpufeature), thanks!

[1/1] arm64/cpufeature: Refactor conditional logic in init_cpu_ftr_reg()
      https://git.kernel.org/arm64/c/e52163df7721

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Dec 10 10:34:46 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 18:34:46 +0000
Subject: [PATCH] arm64: cpufeature: Add HAFT to cpucap_is_possible()
In-Reply-To: <20241209155948.2124393-1-mark.rutland@arm.com>
References: <20241209155948.2124393-1-mark.rutland@arm.com>
Message-ID: <173383261011.2040857.1973906693856719881.b4-ty@kernel.org>

On Mon, 09 Dec 2024 15:59:48 +0000, Mark Rutland wrote:
> For consistency with other cpucaps, handle the configuration check for
> ARM64_HAFT in cpucap_is_possible() rather than this being explicit in
> system_supports_haft(). The configuration check will now happen
> implicitly as cpus_have_final_cap() uses cpucap_is_possible() via
> alternative_has_cap_unlikely().
> 
> 
> [...]

A patch so good, you signed it off twice! I dropped one of them.

Applied to arm64 (for-next/cpufeature), thanks!

[1/1] arm64: cpufeature: Add HAFT to cpucap_is_possible()
      https://git.kernel.org/arm64/c/264a593da60b

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Dec 10 10:34:47 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 18:34:47 +0000
Subject: [PATCH v5 00/10] Refactor the common parts to the HiSilicon Uncore PMU core and cleanups
In-Reply-To: <20241210141525.37788-1-yangyicong@huawei.com>
References: <20241210141525.37788-1-yangyicong@huawei.com>
Message-ID: <173384624655.550105.13843617535853493217.b4-ty@kernel.org>

On Tue, 10 Dec 2024 22:15:15 +0800, Yicong Yang wrote:
> This series mainly contains the refactor of the HiSilicon Uncore PMU by
> extracting the common parts from each drivers into the core:
> - the retrieving of the PMU topology ID
> - the common sysfs attributes like cpumask and identifier
> 
> In order to achieve this, we need to do below preparation:
> - refactor the detection of associated CPUs for PMUs locates on a SICL
> - maintain the topology information in a dedicated data structure
> - provides a generic implementation of cpumask/identifier attributes
> 
> [...]

Applied to will (for-next/perf), thanks!

[01/10] drivers/perf: hisi: Define a symbol namespace for HiSilicon Uncore PMUs
        https://git.kernel.org/will/c/41729809ac85
[02/10] drivers/perf: hisi: Don't update the associated_cpus on CPU offline
        https://git.kernel.org/will/c/f2368a209a71
[03/10] drivers/perf: hisi: Migrate to one online CPU if no associated one online
        https://git.kernel.org/will/c/83037a47d3aa
[04/10] drivers/perf: hisi: Refactor the detection of associated CPUs
        https://git.kernel.org/will/c/6cd137088fdf
[05/10] drivers/perf: hisi: Extract topology information to a separate structure
        https://git.kernel.org/will/c/c192026ceea7
[06/10] drivers/perf: hisi: Add a common function to retrieve topology from firmware
        https://git.kernel.org/will/c/32528b165ea1
[07/10] drivers/perf: hisi: Provide a generic implementation of cpumask/identifier
        https://git.kernel.org/will/c/8688c01e313d
[08/10] drivers/perf: hisi: Export associated CPUs of each PMU through sysfs
        https://git.kernel.org/will/c/3b051bb7cb43
[09/10] drivers/perf: hisi: Fix incorrect variable name "hha_pmu" in DDRC PMU driver
        https://git.kernel.org/will/c/4e15bcffa19a
[10/10] drivers/perf: hisi: Delete redundant blank line of DDRC PMU
        https://git.kernel.org/will/c/f03241fbebdf

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Dec 10 10:34:48 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 18:34:48 +0000
Subject: [RESEND] arm64: asm: Fix typo in pgtable.h
In-Reply-To: <20241203093323.7831-1-zhujun2@cmss.chinamobile.com>
References: <20241203093323.7831-1-zhujun2@cmss.chinamobile.com>
Message-ID: <173383048640.3808253.4005904648913144834.b4-ty@kernel.org>

On Tue, 03 Dec 2024 01:33:23 -0800, Zhu Jun wrote:
> The word 'trasferring' is wrong, so fix it.
> 
> 

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: asm: Fix typo in pgtable.h
      https://git.kernel.org/arm64/c/e281bd22998b

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From detlev.casanova at collabora.com  Tue Dec 10 10:40:14 2024
From: detlev.casanova at collabora.com (Detlev Casanova)
Date: Tue, 10 Dec 2024 13:40:14 -0500
Subject: [PATCH v5 05/18] drm/rockchip: vop2: Set AXI id for rk3588
In-Reply-To: <20241209122943.2781431-9-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209122943.2781431-9-andyshrk@163.com>
Message-ID: <5839604.DvuYhMxLoT@trenzalore>

Hi Andy,

On Monday, 9 December 2024 07:29:18 EST Andy Yan wrote:
> From: Andy Yan <andy.yan at rock-chips.com>
> 
> There are two AXI bus in vop2, windows attached on the same bus must
> have a unique channel YUV and RGB channel ID.
> 
> The default IDs will conflict with each other on the rk3588, so they
> need to be reassigned.
> 
> Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
> Tested-by: Derek Foreman <derek.foreman at collabora.com>
> 
> ---
> 
> Changes in v5:
> - Added in V5
> 
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 14 +++++++++++
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  9 +++++++
>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 26 +++++++++++++++++++-
>  3 files changed, 48 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index
> dc4edd65bc9e..8b9ca046eeeb 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> @@ -1426,6 +1426,12 @@ static void vop2_plane_atomic_update(struct drm_plane
> *plane, &fb->format->format,
>  		afbc_en ? "AFBC" : "", &yrgb_mst);
> 
> +	if (vop2->data->soc_id > 3568) {

Shouldn't this be done only for rk3588, as specified in the comments below ? 
The test we did before showed that it is failing on rk3576 and 3576 is > 3588.

I suggest

	if (vop2->data->soc_id == 3588) {

Regards,
Detlev

> +		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data-
>axi_bus_id);
> +		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data-
>axi_yrgb_r_id);
> +		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data-
>axi_uv_r_id);
> +	}
> +
>  	if (vop2_cluster_window(win))
>  		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 
half_block_en);
> 
> @@ -3354,6 +3360,10 @@ static struct reg_field
> vop2_cluster_regs[VOP2_WIN_MAX_REG] = { [VOP2_WIN_Y2R_EN] =
> REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
>  	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
>  	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
> +	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 
3),
> +	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
> +	/* RK3588 only, reserved bit on rk3568*/
> +	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
> 
>  	/* Scale */
>  	[VOP2_WIN_SCALE_YRGB_X] = 
REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0,
> 15), @@ -3446,6 +3456,10 @@ static struct reg_field
> vop2_esmart_regs[VOP2_WIN_MAX_REG] = { [VOP2_WIN_YMIRROR] =
> REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
>  	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 
29),
>  	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 
31, 31),
> +	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
> +	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
> +	/* RK3588 only, reserved register on rk3568 */
> +	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
> 
>  	/* Scale */
>  	[VOP2_WIN_SCALE_YRGB_X] = 
REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB,
> 0, 15), diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h index
> 8786c2ba48df..0a3b22e8d14e 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> @@ -78,6 +78,9 @@ enum vop2_win_regs {
>  	VOP2_WIN_COLOR_KEY,
>  	VOP2_WIN_COLOR_KEY_EN,
>  	VOP2_WIN_DITHER_UP,
> +	VOP2_WIN_AXI_BUS_ID,
> +	VOP2_WIN_AXI_YRGB_R_ID,
> +	VOP2_WIN_AXI_UV_R_ID,
> 
>  	/* scale regs */
>  	VOP2_WIN_SCALE_YRGB_X,
> @@ -149,6 +152,10 @@ struct vop2_win_data {
>  	unsigned int layer_sel_id;
>  	uint64_t feature;
> 
> +	uint8_t axi_bus_id;
> +	uint8_t axi_yrgb_r_id;
> +	uint8_t axi_uv_r_id;
> +
>  	unsigned int max_upscale_factor;
>  	unsigned int max_downscale_factor;
>  	const u8 dly[VOP2_DLY_MODE_MAX];
> @@ -319,6 +326,7 @@ enum dst_factor_mode {
> 
>  #define RK3568_CLUSTER_WIN_CTRL0		0x00
>  #define RK3568_CLUSTER_WIN_CTRL1		0x04
> +#define RK3568_CLUSTER_WIN_CTRL2		0x08
>  #define RK3568_CLUSTER_WIN_YRGB_MST		0x10
>  #define RK3568_CLUSTER_WIN_CBR_MST		0x14
>  #define RK3568_CLUSTER_WIN_VIR			0x18
> @@ -341,6 +349,7 @@ enum dst_factor_mode {
>  /* (E)smart register definition, offset relative to window base */
>  #define RK3568_SMART_CTRL0			0x00
>  #define RK3568_SMART_CTRL1			0x04
> +#define RK3588_SMART_AXI_CTRL			0x08
>  #define RK3568_SMART_REGION0_CTRL		0x10
>  #define RK3568_SMART_REGION0_YRGB_MST		0x14
>  #define RK3568_SMART_REGION0_CBR_MST		0x18
> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index
> f7d3350594fa..37c65138012d 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> @@ -395,7 +395,7 @@ static const struct vop2_video_port_data
> rk3588_vop_video_ports[] = { * AXI1 is a read only bus.
>   *
>   * Every window on a AXI bus must assigned two unique
> - * read id(yrgb_id/uv_id, valid id are 0x1~0xe).
> + * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe).
>   *
>   * AXI0:
>   * Cluster0/1, Esmart0/1, WriteBack
> @@ -415,6 +415,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
> = { .layer_sel_id = 0,
>  		.supported_rotations = DRM_MODE_ROTATE_90 | 
DRM_MODE_ROTATE_270 |
>  				       DRM_MODE_REFLECT_X | 
DRM_MODE_REFLECT_Y,
> +		.axi_bus_id = 0,
> +		.axi_yrgb_r_id = 2,
> +		.axi_uv_r_id = 3,
>  		.max_upscale_factor = 4,
>  		.max_downscale_factor = 4,
>  		.dly = { 4, 26, 29 },
> @@ -431,6 +434,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
> = { .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
> DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
>  		.type = DRM_PLANE_TYPE_PRIMARY,
> +		.axi_bus_id = 0,
> +		.axi_yrgb_r_id = 6,
> +		.axi_uv_r_id = 7,
>  		.max_upscale_factor = 4,
>  		.max_downscale_factor = 4,
>  		.dly = { 4, 26, 29 },
> @@ -446,6 +452,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
> = { .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
> DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
>  		.type = DRM_PLANE_TYPE_PRIMARY,
> +		.axi_bus_id = 1,
> +		.axi_yrgb_r_id = 2,
> +		.axi_uv_r_id = 3,
>  		.max_upscale_factor = 4,
>  		.max_downscale_factor = 4,
>  		.dly = { 4, 26, 29 },
> @@ -461,6 +470,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
> = { .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
> DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
>  		.type = DRM_PLANE_TYPE_PRIMARY,
> +		.axi_bus_id = 1,
> +		.axi_yrgb_r_id = 6,
> +		.axi_uv_r_id = 7,
>  		.max_upscale_factor = 4,
>  		.max_downscale_factor = 4,
>  		.dly = { 4, 26, 29 },
> @@ -475,6 +487,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
> = { .layer_sel_id = 2,
>  		.supported_rotations = DRM_MODE_REFLECT_Y,
>  		.type = DRM_PLANE_TYPE_OVERLAY,
> +		.axi_bus_id = 0,
> +		.axi_yrgb_r_id = 0x0a,
> +		.axi_uv_r_id = 0x0b,
>  		.max_upscale_factor = 8,
>  		.max_downscale_factor = 8,
>  		.dly = { 23, 45, 48 },
> @@ -488,6 +503,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
> = { .layer_sel_id = 3,
>  		.supported_rotations = DRM_MODE_REFLECT_Y,
>  		.type = DRM_PLANE_TYPE_OVERLAY,
> +		.axi_bus_id = 0,
> +		.axi_yrgb_r_id = 0x0c,
> +		.axi_uv_r_id = 0x01,
>  		.max_upscale_factor = 8,
>  		.max_downscale_factor = 8,
>  		.dly = { 23, 45, 48 },
> @@ -501,6 +519,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
> = { .layer_sel_id = 6,
>  		.supported_rotations = DRM_MODE_REFLECT_Y,
>  		.type = DRM_PLANE_TYPE_OVERLAY,
> +		.axi_bus_id = 1,
> +		.axi_yrgb_r_id = 0x0a,
> +		.axi_uv_r_id = 0x0b,
>  		.max_upscale_factor = 8,
>  		.max_downscale_factor = 8,
>  		.dly = { 23, 45, 48 },
> @@ -514,6 +535,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
> = { .layer_sel_id = 7,
>  		.supported_rotations = DRM_MODE_REFLECT_Y,
>  		.type = DRM_PLANE_TYPE_OVERLAY,
> +		.axi_bus_id = 1,
> +		.axi_yrgb_r_id = 0x0c,
> +		.axi_uv_r_id = 0x0d,
>  		.max_upscale_factor = 8,
>  		.max_downscale_factor = 8,
>  		.dly = { 23, 45, 48 },






From will at kernel.org  Tue Dec 10 10:34:42 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 18:34:42 +0000
Subject: [PATCH] arm64/mm: Drop INIT_MM_CONTEXT()
In-Reply-To: <20241202043553.29592-1-anshuman.khandual@arm.com>
References: <20241202043553.29592-1-anshuman.khandual@arm.com>
Message-ID: <173383034723.3807515.1598046188677105190.b4-ty@kernel.org>

On Mon, 02 Dec 2024 10:05:53 +0530, Anshuman Khandual wrote:
> Platform override for INIT_MM_CONTEXT() is redundant because swapper_pg_dir
> always gets assigned as the pgd during init_mm initialization. So just drop
> this override on arm64.
> 
> Originally this override was added via the 'commit 2b5548b68199 ("arm64/mm:
> Separate boot-time page tables from swapper_pg_dir")' because non standard
> init_pg_dir was assigned as the pgd. Subsequently it was changed as default
> swapper_pg_dir by the 'commit ba5b0333a847 ("arm64: mm: omit redundant
> remap of kernel image")', which might have also just dropped this override.
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/mm: Drop INIT_MM_CONTEXT()
      https://git.kernel.org/arm64/c/5f882f4aa8aa

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Dec 10 10:34:43 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 18:34:43 +0000
Subject: [PATCH] arm64/mm: Ensure adequate HUGE_MAX_HSTATE
In-Reply-To: <20241202064407.53807-1-anshuman.khandual@arm.com>
References: <20241202064407.53807-1-anshuman.khandual@arm.com>
Message-ID: <173383046649.3808051.6059989869125290793.b4-ty@kernel.org>

On Mon, 02 Dec 2024 12:14:07 +0530, Anshuman Khandual wrote:
> This asserts that HUGE_MAX_HSTATE is sufficient enough preventing potential
> hugetlb_max_hstate runtime overflow in hugetlb_add_hstate() thus triggering
> a BUG_ON() there after.
> 
> 

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/mm: Ensure adequate HUGE_MAX_HSTATE
      https://git.kernel.org/arm64/c/1e5823c8e86d

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Dec 10 10:34:44 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Dec 2024 18:34:44 +0000
Subject: [PATCH] arm64/mm: Replace open encodings with PXD_TABLE_BIT
In-Reply-To: <20241202083850.73207-1-anshuman.khandual@arm.com>
References: <20241202083850.73207-1-anshuman.khandual@arm.com>
Message-ID: <173383037764.3807705.806887970785893565.b4-ty@kernel.org>

On Mon, 02 Dec 2024 14:08:50 +0530, Anshuman Khandual wrote:
> [pgd|p4d]_bad() helpers have open encodings for their respective table bits
> which can be replaced with corresponding macros. This makes things clearer,
> thus improving their readability as well.
> 
> 

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/mm: Replace open encodings with PXD_TABLE_BIT
      https://git.kernel.org/arm64/c/a0e33f528e09

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From broonie at kernel.org  Tue Dec 10 10:43:05 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 18:43:05 +0000
Subject: [PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <20241210170953.GB16075@willie-the-truck>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
 <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>
 <20241210170953.GB16075@willie-the-truck>
Message-ID: <b859bdcd-7343-4d53-9f3a-f374deca725a@sirena.org.uk>

On Tue, Dec 10, 2024 at 05:09:55PM +0000, Will Deacon wrote:

> Can we _please_ just generate this stuff. It feels like we've been
> making silly typos over and over again with the current approach so
> either it's hard or we're not very good at it. Either way, it should be
> automated.

> Others have managed it [1], so it's clearly do-able.

Yes, the issues here are not technical ones.  Though there are some
complications -  eg, IIRC the XML doesn't encode the signedness of
fields like we do and there's areas where we've deliberately diverged.
Given the amount of review I end up having to do of sysreg changes your
reasoning is especially apparent to me.  I've passed this feedback on
(again).
-------------- 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/20241210/05bca426/attachment.sig>

From christophe.jaillet at wanadoo.fr  Tue Dec 10 10:45:33 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Tue, 10 Dec 2024 19:45:33 +0100
Subject: [PATCH v5 2/5] pinctrl: mediatek: add MT7988 pinctrl driver
In-Reply-To: <20241202110045.22084-3-linux@fw-web.de>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-3-linux@fw-web.de>
Message-ID: <32201aec-f3d2-49a7-b0ca-2ede10fec103@wanadoo.fr>

Le 02/12/2024 ? 12:00, Frank Wunderlich a ?crit?:
> From: Daniel Golle <daniel at makrotopia.org>
> 
> Add pinctrl driver for the MediaTek MT7988 SoC.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> [correctly initialise for the function_desc structure]
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> 
> ---

...

> +/* flash */
> +static int mt7988_snfi_pins[] = { 22, 23, 24, 25, 26, 27 };
> +static int mt7988_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
> +
> +static int mt7988_emmc_45_pins[] = {
> +	21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
> +};
> +static int mt7988_emmc_45_funcs[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
> +
> +static int mt7988_sdcard_pins[] = { 32, 33, 34, 35, 36, 37 };
> +static int mt7988_sdcard_funcs[] = { 5, 5, 5, 5, 5, 5 };
> +
> +static int mt7988_emmc_51_pins[] = { 38, 39, 40, 41, 42, 43,
> +				     44, 45, 46, 47, 48, 49 };
> +static int mt7988_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };

At least all the _pins arrays could be const.
Maybe we could also make it possible to have _funcs const as well.

...

> +static struct mtk_pin_soc mt7988_data = {

const?

> +	.reg_cal = mt7988_reg_cals,
> +	.pins = mt7988_pins,
> +	.npins = ARRAY_SIZE(mt7988_pins),
> +	.grps = mt7988_groups,
> +	.ngrps = ARRAY_SIZE(mt7988_groups),
> +	.funcs = mt7988_functions,
> +	.nfuncs = ARRAY_SIZE(mt7988_functions),
> +	.eint_hw = &mt7988_eint_hw,
> +	.gpio_m = 0,
> +	.ies_present = false,
> +	.base_names = mt7988_pinctrl_register_base_names,
> +	.nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
> +	.bias_disable_set = mtk_pinconf_bias_disable_set,
> +	.bias_disable_get = mtk_pinconf_bias_disable_get,
> +	.bias_set = mtk_pinconf_bias_set,
> +	.bias_get = mtk_pinconf_bias_get,
> +	.pull_type = mt7988_pull_type,
> +	.bias_set_combo = mtk_pinconf_bias_set_combo,
> +	.bias_get_combo = mtk_pinconf_bias_get_combo,
> +	.drive_set = mtk_pinconf_drive_set_rev1,
> +	.drive_get = mtk_pinconf_drive_get_rev1,
> +	.adv_pull_get = mtk_pinconf_adv_pull_get,
> +	.adv_pull_set = mtk_pinconf_adv_pull_set,
> +};

...

CJ


From parker at finest.io  Tue Dec 10 10:49:30 2024
From: parker at finest.io (Parker Newman)
Date: Tue, 10 Dec 2024 13:49:30 -0500
Subject: [PATCH v1 1/1] net: stmmac: dwmac-tegra: Read iommu stream id
 from device tree
In-Reply-To: <vyzrfrkvwwbi66zemgjywdzpk75mebr47vxaon5jwnn2vprahl@ndzjlez3ywgv>
References: <bb52bdc1-df2e-493d-a58f-df3143715150@lunn.ch>
	<20241118084400.35f4697a.parker@finest.io>
	<984a8471-7e49-4549-9d8a-48e1a29950f6@lunn.ch>
	<20241119131336.371af397.parker@finest.io>
	<f00bccd3-62d5-46a9-b448-051894267c7a@lunn.ch>
	<20241119144729.72e048a5.parker@finest.io>
	<mpgilwqb5zg5kb4n7r6zwbhy4uutdh6rq5s2yc6ndhcj6gqgri@qkfr4qwjj3ym>
	<20241204115317.008f497c.parker@finest.io>
	<uad6id6omswjm7e4eqwd75c52sy5pddtxru3bcuxlukhecvj4u@klzgrws24r2q>
	<20241206084203.2502ab95.parker@finest.io>
	<vyzrfrkvwwbi66zemgjywdzpk75mebr47vxaon5jwnn2vprahl@ndzjlez3ywgv>
Message-ID: <20241210134930.0f963709.parker@finest.io>

On Fri, 6 Dec 2024 17:01:01 +0100
Thierry Reding <thierry.reding at gmail.com> wrote:

> On Fri, Dec 06, 2024 at 08:42:03AM -0500, Parker Newman wrote:
> > On Wed, 4 Dec 2024 19:06:30 +0100
> > Thierry Reding <thierry.reding at gmail.com> wrote:
> >
> > > On Wed, Dec 04, 2024 at 11:53:17AM -0500, Parker Newman wrote:
> > > > On Wed, 4 Dec 2024 17:23:53 +0100
> > > > Thierry Reding <thierry.reding at gmail.com> wrote:
> > > >
> > > > > On Tue, Nov 19, 2024 at 02:47:29PM -0500, Parker Newman wrote:
> > > > > > On Tue, 19 Nov 2024 20:18:00 +0100
> > > > > > Andrew Lunn <andrew at lunn.ch> wrote:
> > > > > >
> > > > > > > > I think there is some confusion here. I will try to summarize:
> > > > > > > > - Ihe iommu is supported by the Tegra SOC.
> > > > > > > > - The way the mgbe driver is written the iommu DT property is REQUIRED.
> > > > > > >
> > > > > > > If it is required, please also include a patch to
> > > > > > > nvidia,tegra234-mgbe.yaml and make iommus required.
> > > > > > >
> > > > > >
> > > > > > I will add this when I submit a v2 of the patch.
> > > > > >
> > > > > > > > - "iommus" is a SOC DT property and is defined in tegra234.dtsi.
> > > > > > > > - The mgbe device tree nodes in tegra234.dtsi DO have the iommus property.
> > > > > > > > - There are no device tree changes required to to make this patch work.
> > > > > > > > - This patch works fine with existing device trees.
> > > > > > > >
> > > > > > > > I will add the fallback however in case there is changes made to the iommu
> > > > > > > > subsystem in the future.
> > > > > > >
> > > > > > > I would suggest you make iommus a required property and run the tests
> > > > > > > over the existing .dts files.
> > > > > > >
> > > > > > > I looked at the history of tegra234.dtsi. The ethernet nodes were
> > > > > > > added in:
> > > > > > >
> > > > > > > 610cdf3186bc604961bf04851e300deefd318038
> > > > > > > Author: Thierry Reding <treding at nvidia.com>
> > > > > > > Date:   Thu Jul 7 09:48:15 2022 +0200
> > > > > > >
> > > > > > >     arm64: tegra: Add MGBE nodes on Tegra234
> > > > > > >
> > > > > > > and the iommus property is present. So the requires is safe.
> > > > > > >
> > > > > > > Please expand the commit message. It is clear from all the questions
> > > > > > > and backwards and forwards, it does not provide enough details.
> > > > > > >
> > > > > >
> > > > > > I will add more details when I submit V2.
> > > > > >
> > > > > > > I just have one open issue. The code has been like this for over 2
> > > > > > > years. Why has it only now started crashing?
> > > > > > >
> > > > > >
> > > > > > It is rare for Nvidia Jetson users to use the mainline kernel. Nvidia
> > > > > > provides a custom kernel package with many out of tree drivers including a
> > > > > > driver for the mgbe controllers.
> > > > > >
> > > > > > Also, while the Orin AGX SOC (tegra234) has 4 instances of the mgbe controller,
> > > > > > the Nvidia Orin AGX devkit only uses mgbe0. Connect Tech has carrier boards
> > > > > > that use 2 or more of the mgbe controllers which is why we found the bug.
> > > > >
> > > > > Correct. Also, this was a really stupid thing that I overlooked. I don't
> > > > > recall the exact circumstances, but I vaguely recall there had been
> > > > > discussions about adding the tegra_dev_iommu_get_stream_id() helper
> > > > > (that this patch uses) around the time that this driver was created. In
> > > > > the midst of all of this I likely forgot to update the driver after the
> > > > > discussions had settled.
> > > > >
> > > > > Anyway, I agree with the conclusion that we don't need a compatibility
> > > > > fallback for this, both because it would be actively wrong to do it and
> > > > > we've had the required IOMMU properties in device tree since the start,
> > > > > so there can't be any regressions caused by this.
> > > > >
> > > > > I don't think it's necessary to make the iommus property required,
> > > > > though, because there's technically no requirement for these devices to
> > > > > be attached to an IOMMU. They usually are, and it's better if they are,
> > > > > but they should be able to work correctly without an IOMMU.
> > > > >
> > > > Thanks for confirming from the Nvidia side! I wasn't sure if they would
> > > > work without the iommu. That said, if you did NOT want to use the iommu
> > > > and removed the iommu DT property then the probe will fail after my patch.
> > > > Would we not need a guard around the writes to MGBE_WRAP_AXI_ASID0_CTRL as well?
> > >
> > > Well... frankly, I don't know. There's an override in the memory
> > > controller which we set when a device is attached to an IOMMU. That's
> > > usually how the stream ID is programmed. If we don't do that it will
> > > typically default to a special passthrough stream ID (technically the
> > > firmware can lock down those register and force them to a specific
> > > stream ID all the time). I'm not sure what exactly the impact is of
> > > these ASID registers (there's a few other instances where those are
> > > needed). They are required if you want to use the IOMMU, but I don't
> > > know what their meaning is if the IOMMU is not enabled.
> > >
> > > There's also different cases: the IOMMU can be disabled altogether, in
> > > which case no page tables and such exist for any device and no
> > > translation should happen whatsoever. But there's also the case where an
> > > IOMMU is enabled, but certain devices shouldn't attach to them. I should
> > > make it very clear that both of these are not recommended setups and I
> > > don't know if they'll work. And they are mostly untested. I've been
> > > meaning, but haven't found the time, to test some of these cases.
> > >
> >
> > Yes I agree, all of those situations are very niche and not recommended for
> > a Tegra platform that should always have the iommu enabled anyways. Adding an
> > iommu bypass would probably be outside of the scope of this patch.
> >
> > I will not add a patch marking the iommu as required in the device tree
> > bindings when I submit v2 unless anyone else feels different.
>
> I was able to find a bit more information on this. Starting with
> Tegra234 it's usually no longer possible to even enable bypass. It can
> still be done, but it needs to be carefully coordinated between the
> secure bootloader/firmware and the OS. Basically the secure firmware
> can lock down the ability to bypass the IOMMU. If the firmware was
> configured to allow bypass, the driver can then do so by writing the
> special stream ID 0x7f into the stream ID register.
>
> On these newer chips the memory controller override no longer has any
> effect and writing the per-device stream ID registers is the only way to
> attach to the IOMMU.
>
> There's still the case where you can disable the IOMMU altogether, in
> which case the IOMMU will still be bypassed, no matter what the firmware
> did. My understanding is that it doesn't matter in those cases whether
> we write the stream ID registers or not, they will simply get ignored.
> With one exception perhaps being the bypass SID. If you write that, then
> there's a protection mechanism that kicks in.
>
> Well, after all this this still isn't entirely clear to me, but I think
> what it means in a nutshell is that a) we'll want to keep the IOMMU
> always on for security and because the firmware is by default configured
> to not allow bypassing, b) IOMMU isn't strictly required because the
> IOMMU might be completely disabled and c) we shouldn't need to
> conditionalize the stream ID register writes.
>
> That said, the tegra_dev_iommu_get_stream_id() function returns a bool
> specifically to support the latter case. So the intention with the
> design was that drivers would call that function and only need to write
> the stream ID register if it returns true. That's not always great
> because you may want (or need) to rewrite the register after suspend/
> resume, in which case you probably want to resort to a cached value
> rather than call that API. On the other hand the API is quite simple, so
> it could serve as a cache as well.
>

I guess I could add an IS_ENABLED(CONFIG_IOMMU_API) check if
tegra_dev_iommu_get_stream_id() returns false in probe?

That would cover if the IOMMU_API is not enabled but not if the Tegra's
iommu is disabled in other ways.

-Parker


From andi.shyti at kernel.org  Tue Dec 10 10:59:54 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Tue, 10 Dec 2024 19:59:54 +0100
Subject: [PATCH] i2c: nomadik: Add missing sentinel to match table
In-Reply-To: <34b6ee90437fe19526d9388f2f304d175596cb1f.1733473582.git.geert+renesas@glider.be>
References: <34b6ee90437fe19526d9388f2f304d175596cb1f.1733473582.git.geert+renesas@glider.be>
Message-ID: <6gfa3lvgmdqsr4kjaojphlxiu6soxiri7xjcttdpljcd5btbl3@xboan7zamrfp>

Hi Geert,

On Fri, Dec 06, 2024 at 09:28:06AM +0100, Geert Uytterhoeven wrote:
> The OF match table is not NULL-terminated.
> Fix this by adding a sentinel to nmk_i2c_eyeq_match_table[].
> 
> Fixes: a0d15cc47f29be6d ("i2c: nomadik: switch from of_device_is_compatible() to of_match_device()")
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

merged to i2c/i2c-host-fixes.

Thanks,
Andi


From broonie at kernel.org  Tue Dec 10 11:12:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 10 Dec 2024 19:12:58 +0000
Subject: [PATCH v5] KVM: arm64: Fix confusion in documentation for pKVM SME
 assert
Message-ID: <20241210-kvm-arm64-sme-assert-v5-1-995c8dd1025b@kernel.org>

As raised in the review comments for the original patch the assert and
comment added in afb91f5f8ad7 ("KVM: arm64: Ensure that SME controls are
disabled in protected mode") are bogus. The comments says that we check
that we do not have SME enabled for a pKVM guest but the assert actually
checks to see if the host has anything set in SVCR which is unrelated to
the guest features or state, regardless of if those guests are protected
or not. This check is also made in the hypervisor, it will refuse to run
a guest if the check fails, so it appears that the assert here is
intended to improve diagnostics.

Update the comment to reflect the check in the code, and to clarify that
we do actually enforce this in the hypervisor. While we're here also
update to use a WARN_ON_ONCE() to avoid log spam if this triggers.

Fixes: afb91f5f8ad7 ("KVM: arm64: Ensure that SME controls are disabled in protected mode")
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
This has been sent with v6.10 with only positive review comments after
the first revision, if there is some issue with the change please share
it.
---
Changes in v5:
- Rebase onto v6.13-rc1.
- Link to v4: https://lore.kernel.org/r/20240930-kvm-arm64-sme-assert-v4-1-3c9df71db688 at kernel.org

Changes in v4:
- Rebase onto v6.12-rc1
- Link to v3: https://lore.kernel.org/r/20240730-kvm-arm64-sme-assert-v3-1-8699454e5cb8 at kernel.org

Changes in v3:
- Rebase onto v6.11-rc1.
- Link to v2: https://lore.kernel.org/r/20240605-kvm-arm64-sme-assert-v2-1-54391b0032f4 at kernel.org

Changes in v2:
- Commit message tweaks.
- Change the assert to WARN_ON_ONCE().
- Link to v1: https://lore.kernel.org/r/20240604-kvm-arm64-sme-assert-v1-1-5d98348d00f8 at kernel.org
---
 arch/arm64/kvm/fpsimd.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index ea5484ce1f3ba3121b6938bda15f7a8057d49051..5fb9b3fc61ec7a53641d7a34a5d39a334a8f5f5a 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -93,11 +93,14 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
 	}
 
 	/*
-	 * If normal guests gain SME support, maintain this behavior for pKVM
-	 * guests, which don't support SME.
+	 * The pKVM hypervisor does not yet understand how to save or
+	 * restore SME state for the host so double check that if we
+	 * are running with pKVM we have disabled SME.  The hypervisor
+	 * enforces this when the guest is run, this check is for
+	 * clearer diagnostics.
 	 */
-	WARN_ON(is_protected_kvm_enabled() && system_supports_sme() &&
-		read_sysreg_s(SYS_SVCR));
+	WARN_ON_ONCE(is_protected_kvm_enabled() && system_supports_sme() &&
+		     read_sysreg_s(SYS_SVCR));
 }
 
 /*

---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20240604-kvm-arm64-sme-assert-5ad755d4e8a6

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From mark.rutland at arm.com  Tue Dec 10 11:17:36 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Dec 2024 19:17:36 +0000
Subject: arm64: stacktrace: unwind exception boundaries
In-Reply-To: <rxc57eg65sg4iayhj7gc7yl24w524lviedxnydl2mggqnatglq@iairj2ci7ioj>
References: <36kx57aw46vwykgckr5cm4fafhw54tjuj4cqljrdnpfwvjl7if@a7znuhpfu54o>
 <zbwbgkuvvciezpmigcp6gaahfxwm7cwhpzus7gtbfnbzsjb2n3@kfbdppbd74o4>
 <Z1bWaGCvUrwrj2fZ@J2N7QTR9R3>
 <Z1gll87-TkAqFwUz@J2N7QTR9R3>
 <rxc57eg65sg4iayhj7gc7yl24w524lviedxnydl2mggqnatglq@iairj2ci7ioj>
Message-ID: <Z1iT0AQqu5dqdCSg@J2N7QTR9R3>

On Tue, Dec 10, 2024 at 07:40:04AM -0500, Kent Overstreet wrote:
> On Tue, Dec 10, 2024 at 11:27:19AM +0000, Mark Rutland wrote:
> > On Mon, Dec 09, 2024 at 11:37:12AM +0000, Mark Rutland wrote:
> > > On Thu, Dec 05, 2024 at 01:04:59PM -0500, Kent Overstreet wrote:

> > Looking some more, I see that bch2_btree_transactions_read() is trying
> > to unwind other tasks, and I believe what's happening here is that the
> > unwindee isn't actually blocked for the duration of the unwind, leading
> > to the unwinder encountering junk and consequently producing the
> > warning.
> > 
> > As a test case, it's possible to trigger similar with a few parallel
> > instances of:
> > 
> > 	while true; do cat /proc/*/stack > /dev/null
> > 
> > The only thing we can do on the arm64 side is remove the WARN_ON_ONCE(),
> > which'll get rid of the splat. It seems we've never been unlucky enough
> > to hit a stale fgraph entry, or that would've blown up also.
> > 
> > Regardless of the way arm64 behaves here, the unwind performed by
> > bch2_btree_transactions_read() is going to contain garbage unless the
> > task is pinned in a blocked state. AFAICT the way
> > btree_trans::locking_wait::task is used is here is racy, and there's no
> > guarantee that the unwindee is actually blocked.
> 
> Occasionally returning garbage is completely fine, as long as the
> interface is otherwise safe. This is debug info; it's important that it
> be available and we can't impose additional synchronization for it.

Sure thing; just note that there's no guarantee that this is only
"occasionally" garbage -- this could be wrong 1% of the time or 99% of
the time depending on the specific scenario, HW it's running on, etc. As
long as you're happy to hold the pieces when that happens, that's fine.

I've pushed out fixes to the arm64/stacktrace/fixes branch on my
kernel.org git repo:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/stacktrace/fixes
  git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64/stacktrace/fixes

... and I'll get that out as a series on the list tomorrow.

Mark.


From kent.overstreet at linux.dev  Tue Dec 10 11:31:17 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Tue, 10 Dec 2024 14:31:17 -0500
Subject: arm64: stacktrace: unwind exception boundaries
In-Reply-To: <Z1iT0AQqu5dqdCSg@J2N7QTR9R3>
References: <36kx57aw46vwykgckr5cm4fafhw54tjuj4cqljrdnpfwvjl7if@a7znuhpfu54o>
 <zbwbgkuvvciezpmigcp6gaahfxwm7cwhpzus7gtbfnbzsjb2n3@kfbdppbd74o4>
 <Z1bWaGCvUrwrj2fZ@J2N7QTR9R3>
 <Z1gll87-TkAqFwUz@J2N7QTR9R3>
 <rxc57eg65sg4iayhj7gc7yl24w524lviedxnydl2mggqnatglq@iairj2ci7ioj>
 <Z1iT0AQqu5dqdCSg@J2N7QTR9R3>
Message-ID: <aieiy7cowkk7ygkhpquggbkpzn5w4prlr5ujjuawpsw4re6467@iwuu4r32lr7r>

On Tue, Dec 10, 2024 at 07:17:36PM +0000, Mark Rutland wrote:
> On Tue, Dec 10, 2024 at 07:40:04AM -0500, Kent Overstreet wrote:
> > On Tue, Dec 10, 2024 at 11:27:19AM +0000, Mark Rutland wrote:
> > > On Mon, Dec 09, 2024 at 11:37:12AM +0000, Mark Rutland wrote:
> > > > On Thu, Dec 05, 2024 at 01:04:59PM -0500, Kent Overstreet wrote:
> 
> > > Looking some more, I see that bch2_btree_transactions_read() is trying
> > > to unwind other tasks, and I believe what's happening here is that the
> > > unwindee isn't actually blocked for the duration of the unwind, leading
> > > to the unwinder encountering junk and consequently producing the
> > > warning.
> > > 
> > > As a test case, it's possible to trigger similar with a few parallel
> > > instances of:
> > > 
> > > 	while true; do cat /proc/*/stack > /dev/null
> > > 
> > > The only thing we can do on the arm64 side is remove the WARN_ON_ONCE(),
> > > which'll get rid of the splat. It seems we've never been unlucky enough
> > > to hit a stale fgraph entry, or that would've blown up also.
> > > 
> > > Regardless of the way arm64 behaves here, the unwind performed by
> > > bch2_btree_transactions_read() is going to contain garbage unless the
> > > task is pinned in a blocked state. AFAICT the way
> > > btree_trans::locking_wait::task is used is here is racy, and there's no
> > > guarantee that the unwindee is actually blocked.
> > 
> > Occasionally returning garbage is completely fine, as long as the
> > interface is otherwise safe. This is debug info; it's important that it
> > be available and we can't impose additional synchronization for it.
> 
> Sure thing; just note that there's no guarantee that this is only
> "occasionally" garbage -- this could be wrong 1% of the time or 99% of
> the time depending on the specific scenario, HW it's running on, etc. As
> long as you're happy to hold the pieces when that happens, that's fine.
> 
> I've pushed out fixes to the arm64/stacktrace/fixes branch on my
> kernel.org git repo:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/stacktrace/fixes
>   git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64/stacktrace/fixes
> 
> ... and I'll get that out as a series on the list tomorrow.

Wonderful

The fact that /proc/pid/stack doesn't give anything if the process is in
TASK_RUNNING has been a problem in the past, yet this is something we're
not consistent on in the kernel; sysrq-trigger backtraces do give
backtraces for running processes (which then may require sorting through
everything).

So thanks for this :)


From yang at os.amperecomputing.com  Tue Dec 10 11:33:16 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Tue, 10 Dec 2024 11:33:16 -0800
Subject: [RFC PATCH 0/3] arm64: support FEAT_BBM level 2 and large block
 mapping when rodata=full
In-Reply-To: <20241210113151.GC14735@willie-the-truck>
References: <20241118181711.962576-1-yang@os.amperecomputing.com>
 <20241210113151.GC14735@willie-the-truck>
Message-ID: <414b3388-c2e5-45ae-9f1d-c35310fdbf8b@os.amperecomputing.com>



On 12/10/24 3:31 AM, Will Deacon wrote:
> On Mon, Nov 18, 2024 at 10:16:07AM -0800, Yang Shi wrote:
>> When rodata=full kernel linear mapping is mapped by PTE due to arm's
>> break-before-make rule.
>>
>> This resulted in a couple of problems:
>>    - performance degradation
>>    - more TLB pressure
>>    - memory waste for kernel page table
>>
>> There are some workarounds to mitigate the problems, for example, using
>> rodata=on, but this compromises the security measurement.
>>
>> With FEAT_BBM level 2 support, splitting large block page table to
>> smaller ones doesn't need to make the page table entry invalid anymore.
>> This allows kernel split large block mapping on the fly.
> I think you can still get TLB conflict aborts in this case, so this
> doesn't work. Hopefully the architecture can strengthen this in the
> future to give you what you need.

Hi Will,

Thanks for responding. This is a little bit surprising. I thought 
FEAT_BBM level 2 can handle the TLB conflict gracefully. At least its 
description made me assume so. And Catalin also mentioned FEAT_BBM level 
2 can be used to split vmemmap page table in HVO patch discussion 
(https://lore.kernel.org/all/Zo68DP6siXfb6ZBR at arm.com/).

It sounds a little bit contradicting if the TLB conflict still can 
happen with FEAT_BBM level 2. It makes the benefit of FEAT_BBM level 2 
much less than expected.

Is it out of question to handle the TLB conflict aborts? IIUC we should 
just need flush TLB then resume, and it doesn't require to hold any 
locks as well.

And I chatted with our architects, I was told the TLB conflict abort 
doesn't happen on AmpereOne. Maybe this is why I didn't see the problem 
when I tested the patches.

Thanks,
Yang


>
> Will



From florian.fainelli at broadcom.com  Tue Dec 10 11:34:51 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 10 Dec 2024 11:34:51 -0800
Subject: [PATCH net-next 2/9] net: dsa: add hook to determine whether EEE
 is supported
In-Reply-To: <E1tL144-006cZD-El@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL144-006cZD-El@rmk-PC.armlinux.org.uk>
Message-ID: <8a7bd584-d4e7-4a68-a562-08f2603ff49c@broadcom.com>

On 12/10/24 06:18, Russell King (Oracle) wrote:
> Add a hook to determine whether the switch supports EEE. This will
> return false if the switch does not, or true if it does. If the
> method is not implemented, we assume (currently) that the switch
> supports EEE.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From qperret at google.com  Tue Dec 10 11:38:25 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 10 Dec 2024 19:38:25 +0000
Subject: [PATCH v2 13/18] KVM: arm64: Introduce
 __pkvm_host_wrprotect_guest()
In-Reply-To: <CA+EHjTx-MZHKwkGYPU+yN-CDkNh1kxTXN8FWTeaPfM95OSkjcQ@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-14-qperret@google.com>
 <CA+EHjTx-MZHKwkGYPU+yN-CDkNh1kxTXN8FWTeaPfM95OSkjcQ@mail.gmail.com>
Message-ID: <Z1iYsVFgs1Cjwp2x@google.com>

On Tuesday 10 Dec 2024 at 15:06:53 (+0000), Fuad Tabba wrote:
> > +static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt)
> > +{
> > +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> > +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> > +       struct pkvm_hyp_vm *hyp_vm;
> > +       int ret = -EINVAL;
> > +
> > +       if (!is_protected_kvm_enabled())
> > +               goto out;
> > +
> > +       hyp_vm = get_pkvm_hyp_vm(handle);
> > +       if (!hyp_vm)
> > +               goto out;
> > +       if (pkvm_hyp_vm_is_protected(hyp_vm))
> > +               goto put_hyp_vm;
> 
> These checks are (unsurprisingly) the same for all these functions.
> Does it make sense to have a helper do these checks?

Yup, that makes sense and should simplify the error handling on all the
call sites. I'll probably call that get_np_pkvm_hyp_vm() or something
along those lines and shove in pkvm.c in v3.


From shreeya.patel at collabora.com  Tue Dec 10 11:39:01 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Wed, 11 Dec 2024 01:09:01 +0530
Subject: [RESEND PATCH v5 1/4] MAINTAINERS: Add entry for Synopsys DesignWare HDMI RX Driver
In-Reply-To: <20241210193904.883225-1-shreeya.patel@collabora.com>
References: <20241210193904.883225-1-shreeya.patel@collabora.com>
Message-ID: <20241210193904.883225-2-shreeya.patel@collabora.com>

Add an entry for Synopsys DesignWare HDMI Receiver Controller
Driver.

Reviewed-by: Christopher Obbard <chris.obbard at collabora.com>
Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
---

Changes in v5 :-
- Added a missing closing bracket for the email

Changes in v4 :-
- No change

Changes in v3 :-
- No change

Changes in v2 :-
- Add a patch for MAINTAINERS file changes

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7700208f6ccf..3960c3ca1849 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22768,6 +22768,14 @@ F:	drivers/net/pcs/pcs-xpcs.c
 F:	drivers/net/pcs/pcs-xpcs.h
 F:	include/linux/pcs/pcs-xpcs.h
 
+SYNOPSYS DESIGNWARE HDMI RX CONTROLLER DRIVER
+M:	Shreeya Patel <shreeya.patel at collabora.com>
+L:	linux-media at vger.kernel.org
+L:	kernel at collabora.com
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
+F:	drivers/media/platform/synopsys/hdmirx/*
+
 SYNOPSYS DESIGNWARE I2C DRIVER
 M:	Jarkko Nikula <jarkko.nikula at linux.intel.com>
 R:	Andy Shevchenko <andriy.shevchenko at linux.intel.com>
-- 
2.39.2



From shreeya.patel at collabora.com  Tue Dec 10 11:39:02 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Wed, 11 Dec 2024 01:09:02 +0530
Subject: [RESEND PATCH v5 2/4] dt-bindings: media: Document bindings for HDMI RX Controller
In-Reply-To: <20241210193904.883225-1-shreeya.patel@collabora.com>
References: <20241210193904.883225-1-shreeya.patel@collabora.com>
Message-ID: <20241210193904.883225-3-shreeya.patel@collabora.com>

Document bindings for the Synopsys DesignWare HDMI RX Controller.

Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
---

Changes in v5 :-
- Correct the interrupt IRQ number

Changes in v4 :-
- No change

Changes in v3 :-
- Rename hdmirx_cma to hdmi_receiver_cma
- Add a Reviewed-by tag

Changes in v2 :-
- Add a description for the hardware
- Rename resets, vo1 grf and HPD properties
- Add a proper description for grf and vo1-grf phandles
- Rename the HDMI Input node name to hdmi-receiver
- Improve the subject line
- Include gpio header file in example to fix dt_binding_check failure

 .../bindings/media/snps,dw-hdmi-rx.yaml       | 132 ++++++++++++++++++
 1 file changed, 132 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..510e94e9ca3a
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
@@ -0,0 +1,132 @@
+# SPDX-License-Identifier: (GPL-2.0-only 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>
+
+description:
+  Synopsys DesignWare HDMI Input Controller preset on RK3588 SoCs
+  allowing devices to receive and decode high-resolution video streams
+  from external sources like media players, cameras, laptops, etc.
+
+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: axi
+      - const: apb
+      - const: ref
+      - const: biu
+
+  memory-region:
+    maxItems: 1
+
+  hpd-gpios:
+    description: GPIO specifier for HPD.
+    maxItems: 1
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the general register file
+      containing HDMIRX PHY status bits.
+
+  rockchip,vo1-grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the Video Output GRF register
+      to enable EDID transfer through SDAIN and SCLIN.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - clocks
+  - clock-names
+  - power-domains
+  - resets
+  - pinctrl-0
+  - hpd-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/rk3588-power.h>
+    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+    hdmi_receiver: hdmi-receiver at fdee0000 {
+      compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx";
+      reg = <0xfdee0000 0x6000>;
+      interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>,
+                   <GIC_SPI 178 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 = "axi", "apb", "ref", "biu";
+      memory-region = <&hdmi_receiver_cma>;
+      pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_5v_detection>;
+      pinctrl-names = "default";
+      hpd-gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
+    };
-- 
2.39.2



From shy828301 at gmail.com  Tue Dec 10 11:39:48 2024
From: shy828301 at gmail.com (Yang Shi)
Date: Tue, 10 Dec 2024 11:39:48 -0800
Subject: [PATCH mm-unstable 17/17] mm: Respect mmap hint before THP
 alignment if allocation is possible
In-Reply-To: <CAC_TJvdReRHzBSgg2iqOw3Kw6BBOtwGE=8nB2Hsw-nsmkxN0+g@mail.gmail.com>
References: <20241210024119.2488608-1-kaleshsingh@google.com>
 <20241210024119.2488608-18-kaleshsingh@google.com> <CAHbLzkq2SNaqzx4d981H2QfQvtObS3X0pPL8=oqFsFbMditWPA@mail.gmail.com>
 <CAC_TJvdReRHzBSgg2iqOw3Kw6BBOtwGE=8nB2Hsw-nsmkxN0+g@mail.gmail.com>
Message-ID: <CAHbLzkqbH_AR2jy_6LZ7KSh6bcf4L5B51Mq9DwYtdBcVz1Lu6w@mail.gmail.com>

On Tue, Dec 10, 2024 at 9:34?AM Kalesh Singh <kaleshsingh at google.com> wrote:
>
> On Mon, Dec 9, 2024 at 7:37?PM Yang Shi <shy828301 at gmail.com> wrote:
> >
> > On Mon, Dec 9, 2024 at 6:45?PM Kalesh Singh <kaleshsingh at google.com> wrote:
> > >
> > > Commit 249608ee4713 ("mm: respect mmap hint address when aligning for THP")
> > > fallsback to PAGE_SIZE alignment instead of THP alignment
> > > for anonymous mapping as long as a hint address is provided by the user
> > > -- even if we weren't able to allocate the unmapped area at the hint
> > > address in the end.
> > >
> > > This was done to address the immediate regression in anonymous mappings
> > > where the hint address were being ignored in some cases; due to commit
> > > efa7df3e3bb5 ("mm: align larger anonymous mappings on THP boundaries").
> > >
> > > It was later pointed out that this issue also existed for file-backed
> > > mappings from file systems that use thp_get_unmapped_area() for their
> > > .get_unmapped_area() file operation.
> > >
> > > The same fix was not applied for file-backed mappings since it would
> > > mean any mmap requests that provide a hint address would be only
> > > PAGE_SIZE-aligned regardless of whether allocation was successful at
> > > the hint address or not.
> > >
> > > Instead, use arch_mmap_hint() to first attempt allocation at the hint
> > > address and fallback to THP alignment if that fails.
> >
> > Thanks for taking time to try to fix this.
> >
> > >
> > > Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
> > > ---
> > >  mm/huge_memory.c | 15 ++++++++-------
> > >  mm/mmap.c        |  1 -
> > >  2 files changed, 8 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> > > index 137abeda8602..f070c89dafc9 100644
> > > --- a/mm/huge_memory.c
> > > +++ b/mm/huge_memory.c
> > > @@ -1097,6 +1097,14 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
> > >         loff_t off_align = round_up(off, size);
> > >         unsigned long len_pad, ret, off_sub;
> > >
> > > +       /*
> > > +        * If allocation at the address hint succeeds; respect the hint and
> > > +        * don't try to align to THP boundary.
> > > +        */
> > > +       addr = arch_mmap_hint(filp, addr, len, off, flags);
> > > +       if (addr)
> > > +               return addr;
> > > +
>
> Hi Yang,
>
> Thanks for the comments.
>
> >
> > IIUC, arch_mmap_hint() will be called in arch_get_unmapped_area() and
> > arch_get_unmapped_area_topdown() again. So we will actually look up
> > maple tree twice. It sounds like the second hint address search is
> > pointless. You should be able to set addr to 0 before calling
> > mm_get_unmapped_area_vmflags() in order to skip the second hint
> > address search.
>
> You are right that it would call into arch_mmap_hint() twice but it
> only attempts the lookup once since on the second attempt addr == 0.

Aha, yeah, I missed addr is going to be reset if arch_mmap_hint()
fails to find a suitable area.

>
> Thanks,
> Kalesh
> >
> > >         if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall())
> > >                 return 0;
> > >
> > > @@ -1117,13 +1125,6 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
> > >         if (IS_ERR_VALUE(ret))
> > >                 return 0;
> > >
> > > -       /*
> > > -        * Do not try to align to THP boundary if allocation at the address
> > > -        * hint succeeds.
> > > -        */
> > > -       if (ret == addr)
> > > -               return addr;
> > > -
> > >         off_sub = (off - ret) & (size - 1);
> > >
> > >         if (test_bit(MMF_TOPDOWN, &current->mm->flags) && !off_sub)
> > > diff --git a/mm/mmap.c b/mm/mmap.c
> > > index 59bf7d127aa1..6bfeec80152a 100644
> > > --- a/mm/mmap.c
> > > +++ b/mm/mmap.c
> > > @@ -807,7 +807,6 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
> > >         if (get_area) {
> > >                 addr = get_area(file, addr, len, pgoff, flags);
> > >         } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && !file
> > > -                  && !addr /* no hint */
> > >                    && IS_ALIGNED(len, PMD_SIZE)) {
> > >                 /* Ensures that larger anonymous mappings are THP aligned. */
> > >                 addr = thp_get_unmapped_area_vmflags(file, addr, len,
> > > --
> > > 2.47.0.338.g60cca15819-goog
> > >
> > >


From qperret at google.com  Tue Dec 10 11:39:59 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 10 Dec 2024 19:39:59 +0000
Subject: [PATCH v2 14/18] KVM: arm64: Introduce
 __pkvm_host_test_clear_young_guest()
In-Reply-To: <CA+EHjTwV2mXOXMF7u+pVaSqvJ2c-iPGMxPBhrj7oZrm+oaAi3A@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-15-qperret@google.com>
 <CA+EHjTwV2mXOXMF7u+pVaSqvJ2c-iPGMxPBhrj7oZrm+oaAi3A@mail.gmail.com>
Message-ID: <Z1iZD54EdpvbpW7I@google.com>

On Tuesday 10 Dec 2024 at 15:11:53 (+0000), Fuad Tabba wrote:
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > index 8658b5932473..554ce31882e6 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > @@ -43,6 +43,7 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum k
> >  int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
> >  int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);
> >  int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
> > +int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
> 
> While I'm piling on the function names/parameters, some functions have
> _guest as a postfix at the end (e.g., this one), others have it in the
> middle (__pkvm_host_relax_guest_perms). I guess
> __pkvm_host_relax_guest_perms is the odd one out. Could you rename it?

Right, 'relax_guest_perms' felt more natural to me, but consistency
should take precedence, so I'll rename :-)


From shreeya.patel at collabora.com  Tue Dec 10 11:39:00 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Wed, 11 Dec 2024 01:09:00 +0530
Subject: [RESEND PATCH v5 0/4] Add Synopsys DesignWare HDMI RX Controller
Message-ID: <20241210193904.883225-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 :-
* HDMIRX driver now only works with the opensource TF-A.
* We have tested the working of OBS studio with HDMIRX driver and
there were no issues seen.
* We also tested and verified the support for interlaced video.

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

CEC compliance test results :-

* https://gitlab.collabora.com/-/snippets/380
* https://gitlab.collabora.com/-/snippets/381

Following is the v4l2-compliance test result :-

root at debian-rockchip-rock5b-rk3588:~# v4l2-compliance -d /dev/video0 
v4l2-compliance 1.29.0-5278, 64 bits, 64-bit time_t
v4l2-compliance SHA: 791da13728d9 2024-11-25 10:01:57

Compliance test for snps_hdmirx device /dev/video0:

Driver Info:
	Driver name      : snps_hdmirx
	Card type        : snps_hdmirx
	Bus info         : platform:fdee0000.hdmi_receiver
	Driver version   : 6.12.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: 4 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_REMOVE_BUFS: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)
	test blocking wait: OK

Total for snps_hdmirx device /dev/video0: 48, Succeeded: 48, Failed: 0, Warnings: 0

---

Resending the patch series due to mail server timeout issue
when sending v5 patchset

Changes in v5 :-
- Fix the interrupt IRQ number in the dt-bindings and device tree
- Add alignment property to ensure hdmi-receiver-cma
  starts at a 64KB-aligned address
- Change the MODULE_DESCRIPTION
- Add VIDEO_SYNOPSYS_HDMIRX as prefix to the default edid config
- Drop the enabling of default edid in the Kconfig
- Replace the default EDID with hdmi-4k-300mhz EDID produced
  by v4l2-ctl tool for better compatibility with various HDMI
  cables and adapters
- Rework the write_edid and set_edid functions
- During format change, retrieve the current pixel format,
  color depth, and AVI infoframe details instead of only
  detecting the format
- Improve the logging mechanism and delays in the
  hdmirx_wait_signal_lock function
- Fix the 4K at 60 capturing for RGB format
- Document what hdmirx_check_timing_valid function does
- Rework the hdmirx_get_detected_timings function
- Fix the NV16/24 size image value
- Add the implementation from Benjamin Hoff to expose the
  ITC type to v4l2
- Remove all the firmware related code

Changes in v4 :-
- Remove DTS changes included in the device tree patch
- Remove the hdmi rx pin info as it's already present
in the rk3588-base-pinctrl.dtsi
- Create a separate config option for selecting the EDID
and enable it by default
- Improve the comment related to DV timings and move it
to the side of hdmirx_get_detected_timings
- Add 100ms delay before pulling the HPD high
- Do not return the detected timings from VIDIOC_G_DV_TIMINGS
- Drop the bus info from hdmirx_querycap
- If *num_planes != 0 then return 0 in hdmirx_queue_setup
- Set queue->min_queued_buffers to 1
- Drop q->allow_cache_hints = 0; as it's always 0 by default
- Add a comment for q->dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
- Drop .read = vb2_fop_read as it's not supported by driver
- Remove redundant edid_init_data_600M
- Make HPD low when driver is loaded
- Add support for reading AVI Infoframe
- Remove msg_len checks from hdmirx_cec_transmit
- Add info about the CEC compliance test in the cover letter
- Add arbitration lost status
- Validate the physical address inside the EDID

Changes in v3 :-
- Use v4l2-common helpers in the HDMIRX driver
- Rename cma node and phandle names
- Elaborate the comment to explain 160MiB calculation
- Move &hdmi_receiver_cma to the rock5b dts file
- Add information about interlaced video testing in the
cover-letter

Changes in v2 :-
- Fix checkpatch --strict warnings
- Move the dt-binding include file changes in a separate patch
- Add a description for the hardware in the dt-bindings file
- Rename resets, vo1 grf and HPD properties
- Add a proper description for grf and vo1-grf phandles in the
bindings
- Rename the HDMI RX node name to hdmi-receiver
- Include gpio header file in binding example to fix the
dt_binding_check failure
- Move hdmirx_cma node to the rk3588.dtsi file
- Add an entry to MAINTAINERS file for the HDMIRX driver

Shreeya Patel (4):
  MAINTAINERS: Add entry for Synopsys DesignWare HDMI RX Driver
  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       |  132 +
 MAINTAINERS                                   |    8 +
 .../dts/rockchip/rk3588-base-pinctrl.dtsi     |   14 +
 .../arm64/boot/dts/rockchip/rk3588-extra.dtsi |   57 +
 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    |   27 +
 .../media/platform/synopsys/hdmirx/Makefile   |    4 +
 .../platform/synopsys/hdmirx/snps_hdmirx.c    | 2662 +++++++++++++++++
 .../platform/synopsys/hdmirx/snps_hdmirx.h    |  394 +++
 .../synopsys/hdmirx/snps_hdmirx_cec.c         |  283 ++
 .../synopsys/hdmirx/snps_hdmirx_cec.h         |   44 +
 14 files changed, 3633 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 shreeya.patel at collabora.com  Tue Dec 10 11:39:03 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Wed, 11 Dec 2024 01:09:03 +0530
Subject: [RESEND PATCH v5 3/4] arm64: dts: rockchip: Add device tree support for HDMI RX Controller
In-Reply-To: <20241210193904.883225-1-shreeya.patel@collabora.com>
References: <20241210193904.883225-1-shreeya.patel@collabora.com>
Message-ID: <20241210193904.883225-4-shreeya.patel@collabora.com>

Add device tree support for Synopsys DesignWare HDMI RX
Controller.

Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
Tested-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
Co-developed-by: Dingxian Wen <shawn.wen at rock-chips.com>
Signed-off-by: Dingxian Wen <shawn.wen at rock-chips.com>
Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
---

Changes in v5 :-
- Add alignment property to ensure hdmi-receiver-cma
  starts at a 64KB-aligned address
- Correct one of the interrupt IRQ number

Changes in v4 :-
- Remove DTS changes added to this patch
- Remove the HDMI RX pin nodes as it's already present
  in the rk3588-base-pinctrl.dtsi

Changes in v3 :-
- Rename cma node and phandle names
- Elaborate the comment to explain 160MiB calculation
- Move &hdmi_receiver_cma to the rock5b dts file

Changes in v2 :-
- Fix some of the checkpatch errors and warnings
- Rename resets, vo1-grf and HPD
- Move hdmirx_cma node to the rk3588.dtsi file

 .../dts/rockchip/rk3588-base-pinctrl.dtsi     | 14 +++++
 .../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 57 +++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
index 7f874c77410c..2d4b9986a177 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
@@ -594,6 +594,20 @@ hdmim0_tx1_hpd: hdmim0-tx1-hpd {
 				/* hdmim0_tx1_hpd */
 				<1 RK_PA6 5 &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 =
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
index ead151941e84..bde1efdf1824 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -7,6 +7,30 @@
 #include "rk3588-extra-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.
+		 * The size of 160MB was determined as follows:
+		 * (3840 * 2160 pixels) * (4 bytes/pixel) * (2 frames/buffer) / 10^6 = 66MB
+		 * To ensure sufficient support for practical use-cases,
+		 * we doubled the 66MB value.
+		 */
+		hdmi_receiver_cma: hdmi-receiver-cma {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x0 0x0 0xffffffff>;
+			size = <0x0 (160 * 0x100000)>; /* 160MiB */
+			alignment = <0x0 0x40000>; /* 64K */
+			no-map;
+			status = "disabled";
+		};
+	};
+
 	usb_host1_xhci: usb at fc400000 {
 		compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
 		reg = <0x0 0xfc400000 0x0 0x400000>;
@@ -135,6 +159,39 @@ i2s10_8ch: i2s at fde00000 {
 		status = "disabled";
 	};
 
+	hdmi_receiver: hdmi_receiver 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 178 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 = "axi", "apb", "ref", "biu";
+		memory-region = <&hdmi_receiver_cma>;
+		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 shreeya.patel at collabora.com  Tue Dec 10 11:46:10 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Wed, 11 Dec 2024 01:16:10 +0530
Subject: [PATCH v5 0/4] Add Synopsys DesignWare HDMI RX Controller
In-Reply-To: <7197326.aoefvbuG5b@diego>
References: <01020193ad025176-f2e8e4fd-41a6-42ef-b3d0-dfa87a6d0abd-000000@eu-west-1.amazonses.com> <7197326.aoefvbuG5b@diego>
Message-ID: <193b21b8ee6.1291091ad1750656.8123869056710701348@collabora.com>

 ---- On Tue, 10 Dec 2024 02:43:47 +0530  Heiko St?bner  wrote --- 
 > Hi Shreeya,
 > 

Hi Heiko,

 > Am Montag, 9. Dezember 2024, 21:00:30 CET schrieb Shreeya Patel:
 > > This series implements support for the Synopsys DesignWare
 > > HDMI RX Controller, being compliant with standard HDMI 1.4b
 > > and HDMI 2.0.
 > 
 > could you take a look at your mail-setup please?
 > 
 > This cover-letter came with a message-id of 
 > 01020193ad025176-f2e8e4fd-41a6-42ef-b3d0-dfa87a6d0abd-000000 at eu-west-1.amazonses.com
 > 
 > same for patch1 that also got an amazon-message-id and lost its
 > in-reply-to reference,
 > 
 > while the patches  2-4 have correct message-ids and reference
 > 20241209200120.3228643-1-shreeya.patel at collabora.com
 > 
 > as their parent. So it looks like some amazon service did some
 > rewriting and broke threading :-( .
 > 

Yes, unfortunately there was a server timeout error after sending the
first patch which broke the thread.
I've resent the patch series now.


Thanks,
Shreeya Patel

 > Thanks a lot
 > Heiko
 > 
 > > 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 :-
 > > * HDMIRX driver now only works with the opensource TF-A.
 > > * We have tested the working of OBS studio with HDMIRX driver and
 > > there were no issues seen.
 > > * We also tested and verified the support for interlaced video.
 > > 
 > > 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
 > > 
 > > CEC compliance test results :-
 > > 
 > > * https://gitlab.collabora.com/-/snippets/380
 > > * https://gitlab.collabora.com/-/snippets/381
 > > 
 > > Following is the v4l2-compliance test result :-
 > > 
 > > root at debian-rockchip-rock5b-rk3588:~# v4l2-compliance -d /dev/video0 
 > > v4l2-compliance 1.29.0-5278, 64 bits, 64-bit time_t
 > > v4l2-compliance SHA: 791da13728d9 2024-11-25 10:01:57
 > > 
 > > Compliance test for snps_hdmirx device /dev/video0:
 > > 
 > > Driver Info:
 > > ????Driver name      : snps_hdmirx
 > > ????Card type        : snps_hdmirx
 > > ????Bus info         : platform:fdee0000.hdmi_receiver
 > > ????Driver version   : 6.12.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: 4 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_REMOVE_BUFS: OK
 > > ????test VIDIOC_EXPBUF: OK
 > > ????test Requests: OK (Not Supported)
 > > ????test blocking wait: OK
 > > 
 > > Total for snps_hdmirx device /dev/video0: 48, Succeeded: 48, Failed: 0, Warnings: 0
 > > 
 > > 
 > > Changes in v5 :-
 > > - Fix the interrupt IRQ number in the dt-bindings and device tree
 > > - Add alignment property to ensure hdmi-receiver-cma
 > >   starts at a 64KB-aligned address
 > > - Change the MODULE_DESCRIPTION
 > > - Add VIDEO_SYNOPSYS_HDMIRX as prefix to the default edid config
 > > - Drop the enabling of default edid in the Kconfig
 > > - Replace the default EDID with hdmi-4k-300mhz EDID produced
 > >   by v4l2-ctl tool for better compatibility with various HDMI
 > >   cables and adapters
 > > - Rework the write_edid and set_edid functions
 > > - During format change, retrieve the current pixel format,
 > >   color depth, and AVI infoframe details instead of only
 > >   detecting the format
 > > - Improve the logging mechanism and delays in the
 > >   hdmirx_wait_signal_lock function
 > > - Fix the 4K at 60 capturing for RGB format
 > > - Document what hdmirx_check_timing_valid function does
 > > - Rework the hdmirx_get_detected_timings function
 > > - Fix the NV16/24 size image value
 > > - Add the implementation from Benjamin Hoff to expose the
 > >   ITC type to v4l2
 > > - Remove all the firmware related code
 > > 
 > > Changes in v4 :-
 > > - Remove DTS changes included in the device tree patch
 > > - Remove the hdmi rx pin info as it's already present
 > > in the rk3588-base-pinctrl.dtsi
 > > - Create a separate config option for selecting the EDID
 > > and enable it by default
 > > - Improve the comment related to DV timings and move it
 > > to the side of hdmirx_get_detected_timings
 > > - Add 100ms delay before pulling the HPD high
 > > - Do not return the detected timings from VIDIOC_G_DV_TIMINGS
 > > - Drop the bus info from hdmirx_querycap
 > > - If *num_planes != 0 then return 0 in hdmirx_queue_setup
 > > - Set queue->min_queued_buffers to 1
 > > - Drop q->allow_cache_hints = 0; as it's always 0 by default
 > > - Add a comment for q->dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
 > > - Drop .read = vb2_fop_read as it's not supported by driver
 > > - Remove redundant edid_init_data_600M
 > > - Make HPD low when driver is loaded
 > > - Add support for reading AVI Infoframe
 > > - Remove msg_len checks from hdmirx_cec_transmit
 > > - Add info about the CEC compliance test in the cover letter
 > > - Add arbitration lost status
 > > - Validate the physical address inside the EDID
 > > 
 > > Changes in v3 :-
 > > - Use v4l2-common helpers in the HDMIRX driver
 > > - Rename cma node and phandle names
 > > - Elaborate the comment to explain 160MiB calculation
 > > - Move &hdmi_receiver_cma to the rock5b dts file
 > > - Add information about interlaced video testing in the
 > > cover-letter
 > > 
 > > Changes in v2 :-
 > > - Fix checkpatch --strict warnings
 > > - Move the dt-binding include file changes in a separate patch
 > > - Add a description for the hardware in the dt-bindings file
 > > - Rename resets, vo1 grf and HPD properties
 > > - Add a proper description for grf and vo1-grf phandles in the
 > > bindings
 > > - Rename the HDMI RX node name to hdmi-receiver
 > > - Include gpio header file in binding example to fix the
 > > dt_binding_check failure
 > > - Move hdmirx_cma node to the rk3588.dtsi file
 > > - Add an entry to MAINTAINERS file for the HDMIRX driver
 > > 
 > > Shreeya Patel (4):
 > >   MAINTAINERS: Add entry for Synopsys DesignWare HDMI RX Driver
 > >   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       |  132 +
 > >  MAINTAINERS                                   |    8 +
 > >  .../dts/rockchip/rk3588-base-pinctrl.dtsi     |   14 +
 > >  .../arm64/boot/dts/rockchip/rk3588-extra.dtsi |   57 +
 > >  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    |   27 +
 > >  .../media/platform/synopsys/hdmirx/Makefile   |    4 +
 > >  .../platform/synopsys/hdmirx/snps_hdmirx.c    | 2662 +++++++++++++++++
 > >  .../platform/synopsys/hdmirx/snps_hdmirx.h    |  394 +++
 > >  .../synopsys/hdmirx/snps_hdmirx_cec.c         |  283 ++
 > >  .../synopsys/hdmirx/snps_hdmirx_cec.h         |   44 +
 > >  14 files changed, 3633 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
 > > 
 > > 
 > 
 > 
 > 
 > 
 > 



From qperret at google.com  Tue Dec 10 11:46:41 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 10 Dec 2024 19:46:41 +0000
Subject: [PATCH v2 15/18] KVM: arm64: Introduce
 __pkvm_host_mkyoung_guest()
In-Reply-To: <CA+EHjTzOjwNyUkS5_zSUiAbiCauLKKgkKU6TM_-+Wsh9A0FdRQ@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-16-qperret@google.com>
 <CA+EHjTzOjwNyUkS5_zSUiAbiCauLKKgkKU6TM_-+Wsh9A0FdRQ@mail.gmail.com>
Message-ID: <Z1iaof2DgZfZxc4l@google.com>

On Tuesday 10 Dec 2024 at 15:14:03 (+0000), Fuad Tabba wrote:
> > +int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu)
> > +{
> > +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> > +       u64 ipa = hyp_pfn_to_phys(gfn);
> > +       u64 phys;
> > +       int ret;
> > +
> > +       host_lock_component();
> > +       guest_lock_component(vm);
> > +
> > +       ret = __check_host_unshare_guest(vm, &phys, ipa);
> 
> While I'm bikeshedding some more, does the name
> __check_host_unshare_guest() make sense? Should it be something like
> __check_host_changeperm_guest(), or something along those lines? (feel
> free to ignore this :) )

I understand the comment, but not a huge fan of 'changeperm' as that
sounds like we're only allowing permission changes while we use this
all over the place. Maybe __check_host_is_shared_guest()? Naming is
hard, so happy to take suggestions :-)


From andrew at lunn.ch  Tue Dec 10 11:54:19 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 10 Dec 2024 20:54:19 +0100
Subject: [PATCH v2 5/5] arm64: dts: ti: Add TQ-Systems TQMa62xx SoM and
 MBa62xx carrier board Device Trees
In-Reply-To: <309052f3f69950fe43390505cc7254aee8c8f5c6.camel@ew.tq-group.com>
References: <cover.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <95ff66ca2c89f69d893c2ce9eed9a0c677633c7b.1733737487.git.matthias.schiffer@ew.tq-group.com>
 <a9c5cfda-e3e3-436a-8d05-b2f096157cfe@lunn.ch>
 <c902a56cf34838f60cee67624bb923e91d74e9e0.camel@ew.tq-group.com>
 <d25b1447-c28b-4998-b238-92672434dc28@lunn.ch>
 <e16076d16349e929af82fa987a658bff1d9804c4.camel@ew.tq-group.com>
 <a2a2f201-73a4-4a99-baef-0d593a88c872@lunn.ch>
 <309052f3f69950fe43390505cc7254aee8c8f5c6.camel@ew.tq-group.com>
Message-ID: <2953e10c-0a57-4d49-b831-3864a07eefd5@lunn.ch>

On Tue, Dec 10, 2024 at 10:56:41AM +0100, Matthias Schiffer wrote:
> On Mon, 2024-12-09 at 17:14 +0100, Andrew Lunn wrote:
> > 
> > > Not our board, but the AM62 SoC. From the datasheet:
> > > 
> > > "TXC is delayed internally before being driven to the RGMII[x]_TXC pin. This
> > > internal delay is always enabled." So enabling the TX delay on the PHY side
> > > would result in a double delay.
> > 
> > phy-mode describes the board. If the board does not have extra long
> > clock lines, phy-mode should be rgmii-id.
> > 
> > The fact the MAC is doing something which no other MAC does should be
> > hidden away in the MAC driver, as much as possible.
> 
> Isn't it kind of a philosophical question whether a delay added by the SoC
> integration is part of the MAC or not? One could also argue that the MAC IP core
> is always the same, with some SoCs adding the delay and others not. (I don't
> know if there are actually SoCs with the same IP core that don't add a delay;
> I'm just not a big fan of hiding details in the driver that could easily be
> described by the Device Tree, thus making the driver more generic)

It is more about, what does phy-mode = "rgmii"; mean? It means the
board provides the delay via extra long clock lines. Except for when
some random MAC driver has a completely different meaning, it is not
documented it means something else, you have to read the sources and
the mailing lists, to find out what this particularly MAC driver is
doing for phy-mode = "rgmii".

Do we really want that. Or should we define that phy-mode = "rgmii"
means the PCB provides the delay. End of story, no exceptions. And
that "rgmii-id" means the MAC/PHY pair need to provide the delay? End
of story, no exceptions.

> > Since the MAC driver is forcing the TX delay, it needs to take the
> > value returned from of_get_phy_mode() and mask out the TX bit before
> > passing it to the PHY.
> 
> Hmm okay, this is what the similar ICSSG/PRUETH driver does. I've always found
> that solution to be particularly confusing, but if that's how it's supposed to
> work, I'll have to accept that.

It has to be that why. If the MAC does the delay, the MAC needs to
ensure the PHY does not do the delays and well, and it achieves that
by setting PHY_INTERFACE_MODE to indicate the PHY should not add
delays. Do you have a better idea how this can be done?

> In my opinion the documentation Documentation/networking/phy.rst is not very
> clear on this matter - the whole section "(RG)MII/electrical interface
> considerations" talks about whether the PHY inserts the delay or not, so my
> assumption was that phy-mode describes the PHY side of things and only that.
> 
> It gets even more confusing when taking into account
> Documentation/devicetree/bindings/net/ethernet-controller.yaml, which contains
> comments like "RGMII with internal RX delay provided by the PHY, the MAC should
> not add an RX delay in this case", which sounds like there are only the cases
> "delay is added by the PHY" and "delay is added by the MAC" - the case "delay is
> part of the board design, neither MAC nor PHY add it" doesn't even appear.

We have tried to improve the documentation. We have also been very
rigid in reviewing DT bindings, and what these things mean. But it
seems like many developers don't read reviews other developers get. Go
search the email archive. How many times have i had this very same
conversation?

Everybody gets pause wrong. Everybody gets EEE wrong. Everybody gets
RGMII delays wrong, not matter how many times we tell developers they
are getting it wrong.... phylink is helping with this, it takes it out
of developers hands so they cannot get pause or soon EEE wrong.

	Andrew


From pgwipeout at gmail.com  Tue Dec 10 12:05:06 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 15:05:06 -0500
Subject: [PATCH 4/6] arm64: dts: rockchip: add hevc power domain clock to rk3328
In-Reply-To: <f16b3688-91e1-4760-ac2b-ce53db98ed68@kwiboo.se>
References: <20241210013010.81257-1-pgwipeout@gmail.com> <20241210013010.81257-5-pgwipeout@gmail.com>
 <e32fa593abfa6d08202b4f929e0b4bdb@manjaro.org> <CAMdYzYp+MQVYr1tOMEOn62vXZGVEYrtd1p9vn6YQzXdrJgSdyA@mail.gmail.com>
 <CAMdYzYquvGBzfWqvUOku7m1sM9qxmBHAL95cANDViUCT1oEEhQ@mail.gmail.com>
 <8c604ada27457698ad6d33d22a39b45a@manjaro.org> <f16b3688-91e1-4760-ac2b-ce53db98ed68@kwiboo.se>
Message-ID: <CAMdYzYoGo=dLag30Dp3p8xzrqvb0peB7Oke=zKR-9qbaTns+zQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 11:05?AM Jonas Karlman <jonas at kwiboo.se> wrote:
>
> Hi Peter,
>
> On 2024-12-10 14:53, Dragan Simic wrote:
> > Hello Peter,
> >
> > On 2024-12-10 14:23, Peter Geis wrote:
> >> On Tue, Dec 10, 2024 at 8:13?AM Peter Geis <pgwipeout at gmail.com> wrote:
> >>> On Tue, Dec 10, 2024 at 5:04?AM Dragan Simic <dsimic at manjaro.org>
> >>> wrote:
> >>>> On 2024-12-10 02:30, Peter Geis wrote:
> >>>>> There is a race condition at startup between disabling power domains
> >>>>> not
> >>>>> used and disabling clocks not used on the rk3328. When the clocks are
> >>>>> disabled first, the hevc power domain fails to shut off leading to a
> >>>>> splat of failures. Add the hevc core clock to the rk3328 power domain
> >>>>> node to prevent this condition.
> >>>>>
> >>>>> rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-....
> >>>>> }
> >>>>> 1087 jiffies s: 89 root: 0x8/.
> >>>>> rcu: blocking rcu_node structures (internal RCU debug):
> >>>>> Sending NMI from CPU 0 to CPUs 3:
> >>>>> NMI backtrace for cpu 3
> >>>>> CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53
> >>>>> Hardware name: Firefly ROC-RK3328-CC (DT)
> >>>>> Workqueue: pm genpd_power_off_work_fn
> >>>>> pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> >>>>> pc : regmap_unlock_spinlock+0x18/0x30
> >>>>> lr : regmap_read+0x60/0x88
> >>>>> sp : ffff800081123c00
> >>>>> x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000
> >>>>> x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040
> >>>>> x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74
> >>>>> x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000
> >>>>> x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d
> >>>>> x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431
> >>>>> x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0
> >>>>> x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b
> >>>>> x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40
> >>>>> x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000
> >>>>> Call trace:
> >>>>> regmap_unlock_spinlock+0x18/0x30
> >>>>> rockchip_pmu_set_idle_request+0xac/0x2c0
> >>>>> rockchip_pd_power+0x144/0x5f8
> >>>>> rockchip_pd_power_off+0x1c/0x30
> >>>>> _genpd_power_off+0x9c/0x180
> >>>>> genpd_power_off.part.0.isra.0+0x130/0x2a8
> >>>>> genpd_power_off_work_fn+0x6c/0x98
> >>>>> process_one_work+0x170/0x3f0
> >>>>> worker_thread+0x290/0x4a8
> >>>>> kthread+0xec/0xf8
> >>>>> ret_from_fork+0x10/0x20
> >>>>> rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack
> >>>>> on
> >>>>> domain 'hevc', val=0x88220
> >>>>>
> >>>>> Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for
> >>>>> RK3328 SoCs")
> >>>>> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> >>>>
> >>>> While I was unable to formally verify this clock assignment,
> >>>> i.e. by using the RK3328 TRM or the downstream kernel source
> >>>> from Rockchip, it makes perfect sense to me.  Thanks for the
> >>>> patch, and please feel free to include:
> >>>>
> >>>> Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> >>>
> >>> It is unfortunate the TRM doesn't include the clock maps, because they
> >>> are extremely helpful when one can acquire them. It also doesn't help
> >>> that the TRM register definition only referred to this as "pll". I was
> >>> sent specifically the usb3 phy clock map for my work on the driver,
> >>> which had the location of each switch and divider along with the
> >>> register and bit that controlled it. That combined with the TRM
> >>> register map allowed me to find this error.
> >>
> >> Apologies, that's the wrong response for this one.
> >
> > No worries.
> >
> >> This patch was the result of educated guess combined with testing. I
> >> grabbed all of the clocks that looked like they could affect things,
> >> then tested them one at a time until I isolated them to this clock. It
> >> lives alone with cpll as the parent and has no children according to
> >> the clock summary. (Though the writeup i mistakenly included above
> >> proves the clock map isn't always accurate).
> >
> > I see, thanks for all your work on this patch!  It surely took quite
> > a lot of time to perform all the testing.
> >
> >>>>> ---
> >>>>>
> >>>>>  arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 +
> >>>>>  1 file changed, 1 insertion(+)
> >>>>>
> >>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> >>>>> b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> >>>>> index 0597de415fe0..7d992c3c01ce 100644
> >>>>> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> >>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> >>>>> @@ -333,6 +333,7 @@ power: power-controller {
> >>>>>
> >>>>>                       power-domain at RK3328_PD_HEVC {
> >>>>>                               reg = <RK3328_PD_HEVC>;
> >>>>> +                             clocks = <&cru SCLK_VENC_CORE>;
>
> Do we also need to include one or all of the following clocks?
>
> According to Fig. 3-6 RK3228H Clock Architecture Diagram 5 following
> clocks point to the H265 block:
>
> S51_6 (4PLL) / G6_3 / S51_0 (DivFree 1~32) / D4 ---- aclk_h265
>                                                  \-- pclk_h265
> S51_14 (4PLL) / G6_4 / S51_8 (DivFree 1~32) / D4 - clk_venc_core
> S52_14 (4PLL) / G6_7 / S52_8 (DivFree 1~32) / D4 - clk_venc_dsp

Good Afternoon,

Thanks for asking! If we were implementing the full encoder, probably.
However even with all the clocks enabled currently the encoder hard
locks the board if we touch it. For now adding just the SCLK_VENC_CORE
is enough to enable control of the power domain.

Very Respectfully,
Peter Geis

>
> Regards,
> Jonas
>
> >>>>>                               #power-domain-cells = <0>;
> >>>>>                       };
> >>>>>                       power-domain at RK3328_PD_VIDEO {
>


From pgwipeout at gmail.com  Tue Dec 10 12:13:29 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 15:13:29 -0500
Subject: [PATCH 3/6] arm64: dts: rockchip: remove ethernet alias from rk3328-roc
In-Reply-To: <20693a7b7cb1aaed2c21b84fd57c4b72@manjaro.org>
References: <20241210013010.81257-1-pgwipeout@gmail.com> <20241210013010.81257-4-pgwipeout@gmail.com>
 <20693a7b7cb1aaed2c21b84fd57c4b72@manjaro.org>
Message-ID: <CAMdYzYr-4mA703ZWGZnCoRtmmkS689XHk854j73M4pgJceeJcQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 3:01?AM Dragan Simic <dsimic at manjaro.org> wrote:
>
> Hello Peter,
>
> On 2024-12-10 02:30, Peter Geis wrote:
> > Remove the ethernet alias added back in during the rk3328-roc dtsi
> > conversion.
>
> I just checked again the dtsi parent conversion I performed in
> the commit f3c6526d6fb2 ("arm64: dts: rockchip: Convert dts files
> used as parents to dtsi files"), and both rk3328-roc-cc.dts and
> rk3328-roc-pc.dts had the ethernet0 alias defined before the
> conversion.  Thus, the alias wasn't added back by mistake during
> the conversion, it was there before.
>
> Moreover, I don't see why would we want to delete the ethernet0
> alias(es) in the first place?  It's usual for Rockchip board dts
> files to have ethernetX aliases defined, and both ROC-RK3328-CC
> and ROC-RK3328-PC have their gmac2io DT nodes enabled, and the
> boards have wired Ethernet ports, so they should also have the
> ethernet0 alias(es) defined.
>
> Am I missing something?

You aren't missing something, I just misunderstood what was happening
with your patch. I can safely drop this.

Thanks!
Peter

>
> > Fixes: f3c6526d6fb2 ("arm64: dts: rockchip: Convert dts files used as
> > parents to dtsi files")
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> >
> >  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 1 -
> >  1 file changed, 1 deletion(-)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > index b5bd5e7d5748..f782c8220dd3 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
> > @@ -9,7 +9,6 @@
> >
> >  / {
> >       aliases {
> > -             ethernet0 = &gmac2io;
> >               mmc0 = &sdmmc;
> >               mmc1 = &emmc;
> >       };


From pgwipeout at gmail.com  Tue Dec 10 12:12:36 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Dec 2024 15:12:36 -0500
Subject: [PATCH 1/6] pmdomain: rockchip: fix rockchip_pd_power error handling
In-Reply-To: <1b323d6e9ef873bfc770e9d54b7a3a64@manjaro.org>
References: <20241210013010.81257-1-pgwipeout@gmail.com> <20241210013010.81257-2-pgwipeout@gmail.com>
 <1b323d6e9ef873bfc770e9d54b7a3a64@manjaro.org>
Message-ID: <CAMdYzYqmn0UktNfz7L352zcjgmxf4tsRs2fwiFXF7NbfPY4zSg@mail.gmail.com>

On Tue, Dec 10, 2024 at 3:18?AM Dragan Simic <dsimic at manjaro.org> wrote:
>
> Hello Peter,
>
> On 2024-12-10 02:30, Peter Geis wrote:
> > The calls rockchip_pd_power makes to rockchip_pmu_set_idle_request lack
> > any return error handling, causing device drivers to incorrectly
> > believe
> > the hardware idle requests succeed when they may have failed. This
> > leads
> > to software possibly accessing hardware that is powered off and the
> > subsequent SError panic that follows.
> >
> > Add error checking and return errors to the calling function to prevent
> > such crashes.
> >
> > gst-launch-1.0 videotestsrc num-buffers=2000 ! v4l2jpegenc ! fakesink
> > Setting pipeline to PAUSED ...er-x64
> > Pipeline is PREROLLING ...
> > Redistribute latency...
> > rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack
> > on
> > domain 'hevc', val=0x98260, idle = 0
> > SError Interrupt on CPU2, code 0x00000000bf000002 -- SError
> > CPU: 2 UID: 0 PID: 804 Comm: videotestsrc0:s Not tainted 6.12.0-rc5+
> > #54
> > Hardware name: Firefly roc-rk3328-cc (DT)
> > pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > pc : rockchip_vpu2_jpeg_enc_run+0x168/0xbc8
> > lr : device_run+0xb0/0x128
> > sp : ffff800082143a20
> > x29: ffff800082143a20 x28: 0000000000000140 x27: 0000000000000000
> > x26: ffff582c47a313e8 x25: ffff582c53e95000 x24: ffff582c53e92800
> > x23: ffff582c5bbe0000 x22: 0000000000000000 x21: ffff582c47a31080
> > x20: ffffa0d78cfa4168 x19: ffffa0d78cfa4168 x18: ffffb755b0519000
> > x17: 000000040044ffff x16: 00500072b5503510 x15: a7a6a5a4a3a29a99
> > x14: 989796959493928a x13: 0000000051eb851f x12: 00000000000000ff
> > x11: ffffa0d78d812880 x10: ffffa0d78d7fbca0 x9 : 000000000000003f
> > x8 : 0000000000000063 x7 : 000000000000003f x6 : 0000000000000040
> > x5 : ffff80008010d000 x4 : ffffa0d78cfa4168 x3 : ffffa0d78cfbfdd8
> > x2 : ffff80008010d0f4 x1 : 0000000000000020 x0 : 0000000000000140
> > Kernel panic - not syncing: Asynchronous SError Interrupt
> > CPU: 2 UID: 0 PID: 804 Comm: videotestsrc0:s Not tainted 6.12.0-rc5+
> > #54
> > Hardware name: Firefly roc-rk3328-cc (DT)
> > Call trace:
> > dump_backtrace+0xa0/0x128
> > show_stack+0x20/0x38
> > dump_stack_lvl+0xc8/0xf8
> > dump_stack+0x18/0x28
> > panic+0x3ec/0x428
> > nmi_panic+0x48/0xa0
> > arm64_serror_panic+0x6c/0x88
> > do_serror+0x30/0x70
> > el1h_64_error_handler+0x38/0x60
> > el1h_64_error+0x7c/0x80
> > rockchip_vpu2_jpeg_enc_run+0x168/0xbc8
> > device_run+0xb0/0x128
> > v4l2_m2m_try_run+0xac/0x230
> > v4l2_m2m_ioctl_streamon+0x70/0x90
> > v4l_streamon+0x2c/0x40
> > __video_do_ioctl+0x194/0x400
> > video_usercopy+0x10c/0x808
> > video_ioctl2+0x20/0x80
> > v4l2_ioctl+0x48/0x70
> > __arm64_sys_ioctl+0xb0/0x100
> > invoke_syscall+0x50/0x120
> > el0_svc_common.constprop.0+0x48/0xf0
> > do_el0_svc+0x24/0x38
> > el0_svc+0x38/0x100
> > el0t_64_sync_handler+0xc0/0xc8
> > el0t_64_sync+0x1a8/0x1b0
> > SMP: stopping secondary CPUs
> > Kernel Offset: 0x20d70c000000 from 0xffff800080000000
> > PHYS_OFFSET: 0xffffa7d3c0000000
> > CPU features: 0x00,00000090,00200000,0200421b
> > Memory Limit: none
> > ---[ end Kernel panic - not syncing: Asynchronous SError Interrupt ]---
> >
> > Fixes: 7c696693a4f5 ("soc: rockchip: power-domain: Add power domain
> > driver")
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>
> This patch is obviously correct, because not checking what
> rockchip_pmu_set_idle_request() returns was simply wrong.
> Thanks for the patch!
>
> Though, shouldn't we improve further the way proper error
> handling is performed in rockchip_do_pmu_set_power_domain(),
> by "rolling back" what rockchip_do_pmu_set_power_domain()
> did after powering up fails?

Eventually, but the reality is if we hit this path the hardware is
already broken. I wanted to provide a fix with the least amount of
risk of breaking things further. I'm open to suggestions for further
improvements here.

Current behavior with this patch with the example above causes
gstreamer to wait indefinitely. I'll trace the return path and see if
returning an error other than -ETIMEDOUT triggers more robust
handling.

>
> > ---
> >
> >  drivers/pmdomain/rockchip/pm-domains.c | 8 ++++++--
> >  1 file changed, 6 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pmdomain/rockchip/pm-domains.c
> > b/drivers/pmdomain/rockchip/pm-domains.c
> > index cb0f93800138..57e8fa25d2bd 100644
> > --- a/drivers/pmdomain/rockchip/pm-domains.c
> > +++ b/drivers/pmdomain/rockchip/pm-domains.c
> > @@ -590,14 +590,18 @@ static int rockchip_pd_power(struct
> > rockchip_pm_domain *pd, bool power_on)
> >                       rockchip_pmu_save_qos(pd);
> >
> >                       /* if powering down, idle request to NIU first */
> > -                     rockchip_pmu_set_idle_request(pd, true);
> > +                     ret = rockchip_pmu_set_idle_request(pd, true);
> > +                     if (ret < 0)
> > +                             return ret;
> >               }
> >
> >               rockchip_do_pmu_set_power_domain(pd, power_on);
> >
> >               if (power_on) {
> >                       /* if powering up, leave idle mode */
> > -                     rockchip_pmu_set_idle_request(pd, false);
> > +                     ret = rockchip_pmu_set_idle_request(pd, false);
> > +                     if (ret < 0)
> > +                             return ret;
> >
> >                       rockchip_pmu_restore_qos(pd);
> >               }


From ankur.a.arora at oracle.com  Tue Dec 10 12:14:00 2024
From: ankur.a.arora at oracle.com (Ankur Arora)
Date: Tue, 10 Dec 2024 12:14:00 -0800
Subject: [PATCH v9 05/15] arm64: barrier: add support for
 smp_cond_relaxed_timeout()
In-Reply-To: <20241210135052.GB15607@willie-the-truck>
References: <20241107190818.522639-1-ankur.a.arora@oracle.com>
 <20241107190818.522639-6-ankur.a.arora@oracle.com>
 <20241210135052.GB15607@willie-the-truck>
Message-ID: <878qsn9tyv.fsf@oracle.com>


Will Deacon <will at kernel.org> writes:

> On Thu, Nov 07, 2024 at 11:08:08AM -0800, Ankur Arora wrote:
>> Support a waited variant of polling on a conditional variable
>> via smp_cond_relaxed_timeout().
>>
>> This uses the __cmpwait_relaxed() primitive to do the actual
>> waiting, when the wait can be guaranteed to not block forever
>> (in case there are no stores to the waited for cacheline.)
>> For this we depend on the availability of the event-stream.
>>
>> For cases when the event-stream is unavailable, we fallback to
>> a spin-waited implementation which is identical to the generic
>> variant.
>>
>> Signed-off-by: Ankur Arora <ankur.a.arora at oracle.com>
>> ---
>>  arch/arm64/include/asm/barrier.h | 54 ++++++++++++++++++++++++++++++++
>>  1 file changed, 54 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
>> index 1ca947d5c939..ab2515ecd6ca 100644
>> --- a/arch/arm64/include/asm/barrier.h
>> +++ b/arch/arm64/include/asm/barrier.h
>> @@ -216,6 +216,60 @@ do {									\
>>  	(typeof(*ptr))VAL;						\
>>  })
>>
>> +#define __smp_cond_load_timeout_spin(ptr, cond_expr,			\
>> +				     time_expr_ns, time_limit_ns)	\
>> +({									\
>> +	typeof(ptr) __PTR = (ptr);					\
>> +	__unqual_scalar_typeof(*ptr) VAL;				\
>> +	unsigned int __count = 0;					\
>> +	for (;;) {							\
>> +		VAL = READ_ONCE(*__PTR);				\
>> +		if (cond_expr)						\
>> +			break;						\
>> +		cpu_relax();						\
>> +		if (__count++ < smp_cond_time_check_count)		\
>> +			continue;					\
>> +		if ((time_expr_ns) >= time_limit_ns)			\
>> +			break;						\
>> +		__count = 0;						\
>> +	}								\
>> +	(typeof(*ptr))VAL;						\
>> +})
>
> This is a carbon-copy of the asm-generic timeout implementation. Please
> can you avoid duplicating that in the arch code?

Yeah I realized a bit late that I could avoid the duplication quite
simply. Will fix.

Thanks

--
ankur


From olteanv at gmail.com  Tue Dec 10 12:20:57 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 10 Dec 2024 22:20:57 +0200
Subject: [net-next PATCH v11 0/9] net: dsa: Add Airoha AN8855 support
In-Reply-To: <20241209134459.27110-1-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
Message-ID: <20241210202057.x2tds77popzdcak6@skbuf>

On Mon, Dec 09, 2024 at 02:44:17PM +0100, Christian Marangi wrote:
> TEST: lan2: 1588v2 over IPv4, Sync                                  [FAIL]
>         reception failed
> TEST: lan2: 1588v2 over IPv4, Follow-Up                             [FAIL]
>         reception failed
> TEST: lan2: 1588v2 over IPv4, Peer Delay Request                    [FAIL]
>         reception failed
> TEST: lan2: 1588v2 over IPv6, Sync                                  [FAIL]
>         reception failed
> TEST: lan2: 1588v2 over IPv6, Follow-Up                             [FAIL]
>         reception failed
> TEST: lan2: 1588v2 over IPv6, Peer Delay Request                    [FAIL]
>         reception failed
> TEST: VLAN upper: 1588v2 over L2 transport, Follow-Up               [FAIL]
>         reception failed
> TEST: VLAN upper: 1588v2 over IPv4, Sync                            [FAIL]
>         reception failed
> ;TEST: VLAN upper: 1588v2 over IPv4, Follow-Up                       [FAIL]
>         reception failed
> TEST: VLAN upper: 1588v2 over IPv4, Peer Delay Request              [FAIL]
>         reception failed
> TEST: VLAN upper: 1588v2 over IPv6, Sync                            [FAIL]
>         reception failed
> TEST: VLAN upper: 1588v2 over IPv6, Follow-Up                       [FAIL]
>         reception failed
> TEST: VLAN upper: 1588v2 over IPv6, Peer Delay Request              [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Sync   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Sync   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Sync   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Follow-Up   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Peer Delay Request   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Sync   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Follow-Up   [FAIL]
>         reception failed
> TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Peer Delay Request   [FAIL]
>         reception failed

Why do these fail? They are dropped on transmit? Could you see with
ethtool -S where they are dropped? (DSA conduit, CPU port or user port)

> TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address   [FAIL]
>         reception succeeded, but should have failed
> TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, allmulti   [FAIL]
>         reception succeeded, but should have failed

It is unexpected that these fail. The vlan_over_bridged_port() selftest
sets has_unicast_flt to true or false, depending on whether the driver
declares IFF_UNICAST_FLT, and depending on that, sets the expectation on
whether unknown packets should be received.

There may be a bug in the selftest, but I doubt it.

I haven't looked at the patches yet, but from this behavior, it looks
like you mechanically satisfied the requirements of dsa_switch_supports_uc_filtering()
such that DSA will set IFF_UNICAST_FLT, but host addresses aren't
actually correctly handled, or CPU flooding isn't turned off when it
should (ds->ops->port_set_host_flood?).

> TEST: FDB entry in PVID for VLAN-tagged with other TPID             [FAIL]
>         FDB entry was not learned when it should
> TEST: Reception of VLAN with other TPID as untagged                 [FAIL]
>         Packet was not forwarded when it should
> TEST: Reception of VLAN with other TPID as untagged (no PVID)       [FAIL]
>         Packet was forwarded when should not

We discussed off-list about this, a special configuration needs to exist
to consider as VLAN-tagged only those packets with TPID == bridge vlan_protocol
(i.e. 802.1Q).


From olteanv at gmail.com  Tue Dec 10 12:31:48 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 10 Dec 2024 22:31:48 +0200
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <67543b6f.df0a0220.3bd32.6d5d@mx.google.com>
References: <20241205145142.29278-4-ansuelsmth@gmail.com>
 <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <20241205180539.6t5iz2m3wjjwyxp3@skbuf>
 <6751f125.5d0a0220.255b79.7be0@mx.google.com>
 <20241205185037.g6cqejgad5jamj7r@skbuf>
 <675200c3.7b0a0220.236ac3.9edf@mx.google.com>
 <20241205235709.pa5shi7mh26cnjhn@skbuf>
 <67543b6f.df0a0220.3bd32.6d5d@mx.google.com>
Message-ID: <20241210203148.2lw5zwldazmwr2rn@skbuf>

On Sat, Dec 07, 2024 at 01:11:23PM +0100, Christian Marangi wrote:
> I finished testing and this works, I'm not using mdio-parent-bus tho as
> the mdio-mux driver seems overkill for the task and problematic for PAGE
> handling. (mdio-mux doesn't provide a way to give the current addr that
> is being accessed)

The use of mdio-parent-bus doesn't necessarily imply an mdio-mux. For
example, you'll also see it used in net/dsa/microchip,ksz.yaml.

You say this switch is also accessible over I2C. How are the internal
PHYs accessed in that case? Still over MDIO? If so, it would be nice to
have a unified scheme for both I2C-controlled switch and MDIO-controlled
switch, which is something that mdio-parent-bus would permit.


From olteanv at gmail.com  Tue Dec 10 12:48:55 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 10 Dec 2024 22:48:55 +0200
Subject: [net-next PATCH v11 3/9] dt-bindings: net: dsa: Document support
 for Airoha AN8855 DSA Switch
In-Reply-To: <20241209134459.27110-4-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-4-ansuelsmth@gmail.com>
Message-ID: <20241210204855.7pgvh74irualyxbn@skbuf>

On Mon, Dec 09, 2024 at 02:44:20PM +0100, Christian Marangi wrote:
> Document support for Airoha AN8855 5-port Gigabit Switch.
> 
> It does expose the 5 Internal PHYs on the MDIO bus and each port
> can access the Switch register space by configurting the PHY page.

typo: configuring
Also below.

> 
> Each internal PHY might require calibration with the fused EFUSE on
> the switch exposed by the Airoha AN8855 SoC NVMEM.

This paragraph should be irrelevant to the switch binding.

> 
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> ---
>  .../net/dsa/airoha,an8855-switch.yaml         | 105 ++++++++++++++++++
>  MAINTAINERS                                   |   1 +
>  2 files changed, 106 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml b/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
> new file mode 100644
> index 000000000000..63bcbebd6a29
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
> @@ -0,0 +1,105 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/dsa/airoha,an8855-switch.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Airoha AN8855 Gigabit Switch
> +
> +maintainers:
> +  - Christian Marangi <ansuelsmth at gmail.com>
> +
> +description: >
> +  Airoha AN8855 is a 5-port Gigabit Switch.
> +
> +  It does expose the 5 Internal PHYs on the MDIO bus and each port
> +  can access the Switch register space by configurting the PHY page.
> +
> +  Each internal PHY might require calibration with the fused EFUSE on
> +  the switch exposed by the Airoha AN8855 SoC NVMEM.
> +
> +$ref: dsa.yaml#
> +
> +properties:
> +  compatible:
> +    const: airoha,an8855-switch
> +
> +  reset-gpios:
> +    description:
> +      GPIO to be used to reset the whole device
> +    maxItems: 1

Since this affects the whole device, the SoC node (handled by the
MFD driver) should handle it. Otherwise you expose the code to weird
race conditions where one child MFD device resets the whole chip after
the other MFD children have probed, and this undoes their settings.

> +
> +  airoha,ext-surge:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description:
> +      Calibrate the internal PHY with the calibration values stored in EFUSE
> +      for the r50Ohm values.

Doesn't seem that this pertains to the switch.


From olteanv at gmail.com  Tue Dec 10 12:55:44 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 10 Dec 2024 22:55:44 +0200
Subject: [net-next PATCH v11 4/9] dt-bindings: mfd: Document support for
 Airoha AN8855 Switch SoC
In-Reply-To: <20241209134459.27110-5-ansuelsmth@gmail.com>
 <20241209134459.27110-5-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-5-ansuelsmth@gmail.com>
 <20241209134459.27110-5-ansuelsmth@gmail.com>
Message-ID: <20241210205544.g6y7vcyekyfebkoo@skbuf>

On Mon, Dec 09, 2024 at 02:44:21PM +0100, Christian Marangi wrote:
> +properties:
> +  compatible:
> +    const: airoha,an8855-mfd

After assisting dt-binding reviews in the past, I get the impression
that "mfd" in a compatible string name is not going to be accepted.
The bindings should be OS-independent, MFD is a Linux implementation.
In principle this could be just "airoha,an8855" for the entire SoC.

> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    mdio {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        mfd at 1 {

And the node name could be just "soc at 1".

> +            compatible = "airoha,an8855-mfd";
> +            reg = <1>;
> +
> +            efuse {
...
> +            };
> +
> +            ethernet-switch {
...
> +            };
> +
> +            mdio {
...
> +            };
> +        };
> +    };

I hope it's not mandatory to duplicate in the example also the bindings
of the children, especially since you link to their own schemas.


From ansuelsmth at gmail.com  Tue Dec 10 12:56:30 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Tue, 10 Dec 2024 21:56:30 +0100
Subject: [net-next PATCH v9 3/4] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241210203148.2lw5zwldazmwr2rn@skbuf>
References: <20241205162759.pm3iz42bhdsvukfm@skbuf>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <6751e023.5d0a0220.394b90.7bc9@mx.google.com>
 <20241205180539.6t5iz2m3wjjwyxp3@skbuf>
 <6751f125.5d0a0220.255b79.7be0@mx.google.com>
 <20241205185037.g6cqejgad5jamj7r@skbuf>
 <675200c3.7b0a0220.236ac3.9edf@mx.google.com>
 <20241205235709.pa5shi7mh26cnjhn@skbuf>
 <67543b6f.df0a0220.3bd32.6d5d@mx.google.com>
 <20241210203148.2lw5zwldazmwr2rn@skbuf>
Message-ID: <6758ab01.7b0a0220.b8716.380c@mx.google.com>

On Tue, Dec 10, 2024 at 10:31:48PM +0200, Vladimir Oltean wrote:
> On Sat, Dec 07, 2024 at 01:11:23PM +0100, Christian Marangi wrote:
> > I finished testing and this works, I'm not using mdio-parent-bus tho as
> > the mdio-mux driver seems overkill for the task and problematic for PAGE
> > handling. (mdio-mux doesn't provide a way to give the current addr that
> > is being accessed)
> 
> The use of mdio-parent-bus doesn't necessarily imply an mdio-mux. For
> example, you'll also see it used in net/dsa/microchip,ksz.yaml.
> 
> You say this switch is also accessible over I2C. How are the internal
> PHYs accessed in that case? Still over MDIO? If so, it would be nice to
> have a unified scheme for both I2C-controlled switch and MDIO-controlled
> switch, which is something that mdio-parent-bus would permit.

What is not clear to me is where that property should be used in the
code or it's just for reference in DT to describe what is the parent?

Given MFD implementation, I pass the bus by accessing the MFD priv
struct so having the parent property is redundant.

-- 
	Ansuel


From ansuelsmth at gmail.com  Tue Dec 10 12:59:04 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Tue, 10 Dec 2024 21:59:04 +0100
Subject: [net-next PATCH v11 3/9] dt-bindings: net: dsa: Document support
 for Airoha AN8855 DSA Switch
In-Reply-To: <20241210204855.7pgvh74irualyxbn@skbuf>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-4-ansuelsmth@gmail.com>
 <20241210204855.7pgvh74irualyxbn@skbuf>
Message-ID: <6758ab9b.7b0a0220.3347af.914a@mx.google.com>

On Tue, Dec 10, 2024 at 10:48:55PM +0200, Vladimir Oltean wrote:
> On Mon, Dec 09, 2024 at 02:44:20PM +0100, Christian Marangi wrote:
> > Document support for Airoha AN8855 5-port Gigabit Switch.
> > 
> > It does expose the 5 Internal PHYs on the MDIO bus and each port
> > can access the Switch register space by configurting the PHY page.
> 
> typo: configuring
> Also below.
> 
> > 
> > Each internal PHY might require calibration with the fused EFUSE on
> > the switch exposed by the Airoha AN8855 SoC NVMEM.
> 
> This paragraph should be irrelevant to the switch binding.
> 
> > 
> > Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> > ---
> >  .../net/dsa/airoha,an8855-switch.yaml         | 105 ++++++++++++++++++
> >  MAINTAINERS                                   |   1 +
> >  2 files changed, 106 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml b/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
> > new file mode 100644
> > index 000000000000..63bcbebd6a29
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
> > @@ -0,0 +1,105 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/dsa/airoha,an8855-switch.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Airoha AN8855 Gigabit Switch
> > +
> > +maintainers:
> > +  - Christian Marangi <ansuelsmth at gmail.com>
> > +
> > +description: >
> > +  Airoha AN8855 is a 5-port Gigabit Switch.
> > +
> > +  It does expose the 5 Internal PHYs on the MDIO bus and each port
> > +  can access the Switch register space by configurting the PHY page.
> > +
> > +  Each internal PHY might require calibration with the fused EFUSE on
> > +  the switch exposed by the Airoha AN8855 SoC NVMEM.
> > +
> > +$ref: dsa.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    const: airoha,an8855-switch
> > +
> > +  reset-gpios:
> > +    description:
> > +      GPIO to be used to reset the whole device
> > +    maxItems: 1
> 
> Since this affects the whole device, the SoC node (handled by the
> MFD driver) should handle it. Otherwise you expose the code to weird
> race conditions where one child MFD device resets the whole chip after
> the other MFD children have probed, and this undoes their settings.
>

OK.

> > +
> > +  airoha,ext-surge:
> > +    $ref: /schemas/types.yaml#/definitions/flag
> > +    description:
> > +      Calibrate the internal PHY with the calibration values stored in EFUSE
> > +      for the r50Ohm values.
> 
> Doesn't seem that this pertains to the switch.

Do you think this should be placed in each PHY node? I wanted to prevent
having to define a schema also for PHY if possible given how integrated
these are. (originally it was defined in DT node to follow how it was
done in Airoha SDK)

-- 
	Ansuel


From bb at ti.com  Tue Dec 10 12:59:23 2024
From: bb at ti.com (Bryan Brattlof)
Date: Tue, 10 Dec 2024 14:59:23 -0600
Subject: [PATCH 0/2] arm64: dts: ti: remove extra GIC redistributor ranges
Message-ID: <20241210-am62-gic-fixup-v1-0-758b4d5b4a0a@ti.com>

Hello Everyone!

While debugging an unrelated issue Bin noticed we've accidentally 
defined the redistributor range for the GIC-500 two times on the AM62x 
and AM62Ax. 

This simple series removes the extra copy :)

Happy Hacking
~Bryan

Signed-off-by: Bryan Brattlof <bb at ti.com>
---
Bryan Brattlof (2):
      arm64: dts: ti: k3-am62: remove duplicate GICR reg
      arm64: dts: ti: k3-am62a: remove duplicate GICR reg

 arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 1 -
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 1 -
 2 files changed, 2 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241206-am62-gic-fixup-3ebe19226225

Best regards,
-- 
Bryan Brattlof <bb at ti.com>



From bb at ti.com  Tue Dec 10 12:59:24 2024
From: bb at ti.com (Bryan Brattlof)
Date: Tue, 10 Dec 2024 14:59:24 -0600
Subject: [PATCH 1/2] arm64: dts: ti: k3-am62: remove duplicate GICR reg
In-Reply-To: <20241210-am62-gic-fixup-v1-0-758b4d5b4a0a@ti.com>
References: <20241210-am62-gic-fixup-v1-0-758b4d5b4a0a@ti.com>
Message-ID: <20241210-am62-gic-fixup-v1-1-758b4d5b4a0a@ti.com>

The GIC Redistributor control register range is mapped twice. Remove the
extra entry from the reg range.

Reported-by: Bin Liu <b-liu at ti.com>
Signed-off-by: Bryan Brattlof <bb at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 7cd727d10a5f2..7d355aa73ea21 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -23,7 +23,6 @@ gic500: interrupt-controller at 1800000 {
 		interrupt-controller;
 		reg = <0x00 0x01800000 0x00 0x10000>,	/* GICD */
 		      <0x00 0x01880000 0x00 0xc0000>,	/* GICR */
-		      <0x00 0x01880000 0x00 0xc0000>,   /* GICR */
 		      <0x01 0x00000000 0x00 0x2000>,    /* GICC */
 		      <0x01 0x00010000 0x00 0x1000>,    /* GICH */
 		      <0x01 0x00020000 0x00 0x2000>;    /* GICV */

-- 
2.47.1



From bb at ti.com  Tue Dec 10 12:59:25 2024
From: bb at ti.com (Bryan Brattlof)
Date: Tue, 10 Dec 2024 14:59:25 -0600
Subject: [PATCH 2/2] arm64: dts: ti: k3-am62a: remove duplicate GICR reg
In-Reply-To: <20241210-am62-gic-fixup-v1-0-758b4d5b4a0a@ti.com>
References: <20241210-am62-gic-fixup-v1-0-758b4d5b4a0a@ti.com>
Message-ID: <20241210-am62-gic-fixup-v1-2-758b4d5b4a0a@ti.com>

The GIC Redistributor control range is mapped twice. Remove the extra
entry from the reg range.

Reported-by: Bin Liu <b-liu at ti.com>
Signed-off-by: Bryan Brattlof <bb at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index a93e2cd7b8c74..a1daba7b1fad5 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -18,7 +18,6 @@ gic500: interrupt-controller at 1800000 {
 		compatible = "arm,gic-v3";
 		reg = <0x00 0x01800000 0x00 0x10000>,	/* GICD */
 		      <0x00 0x01880000 0x00 0xc0000>,	/* GICR */
-		      <0x00 0x01880000 0x00 0xc0000>,   /* GICR */
 		      <0x01 0x00000000 0x00 0x2000>,    /* GICC */
 		      <0x01 0x00010000 0x00 0x1000>,    /* GICH */
 		      <0x01 0x00020000 0x00 0x2000>;    /* GICV */

-- 
2.47.1



From ansuelsmth at gmail.com  Tue Dec 10 13:03:09 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Tue, 10 Dec 2024 22:03:09 +0100
Subject: [net-next PATCH v11 4/9] dt-bindings: mfd: Document support for
 Airoha AN8855 Switch SoC
In-Reply-To: <20241210205544.g6y7vcyekyfebkoo@skbuf>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-5-ansuelsmth@gmail.com>
 <20241209134459.27110-5-ansuelsmth@gmail.com>
 <20241210205544.g6y7vcyekyfebkoo@skbuf>
Message-ID: <6758ac90.df0a0220.20ca7f.df40@mx.google.com>

On Tue, Dec 10, 2024 at 10:55:44PM +0200, Vladimir Oltean wrote:
> On Mon, Dec 09, 2024 at 02:44:21PM +0100, Christian Marangi wrote:
> > +properties:
> > +  compatible:
> > +    const: airoha,an8855-mfd
> 
> After assisting dt-binding reviews in the past, I get the impression
> that "mfd" in a compatible string name is not going to be accepted.
> The bindings should be OS-independent, MFD is a Linux implementation.
> In principle this could be just "airoha,an8855" for the entire SoC.
>

Ok I will use an8855. The DSA switch has the suffix so it's not a
problem being that generic.

> > +examples:
> > +  - |
> > +    #include <dt-bindings/gpio/gpio.h>
> > +
> > +    mdio {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        mfd at 1 {
> 
> And the node name could be just "soc at 1".
> 

I tought there was a constraint with node name but this is not the case,
will change to soc.

> > +            compatible = "airoha,an8855-mfd";
> > +            reg = <1>;
> > +
> > +            efuse {
> ...
> > +            };
> > +
> > +            ethernet-switch {
> ...
> > +            };
> > +
> > +            mdio {
> ...
> > +            };
> > +        };
> > +    };
> 
> I hope it's not mandatory to duplicate in the example also the bindings
> of the children, especially since you link to their own schemas.

I checked other example and some duplicate the example and some
doesn't... My idea here is to try to add the most complete example
possible. Especially to how to define efuse and how phy makes use of it.

-- 
	Ansuel


From quic_eberman at quicinc.com  Tue Dec 10 12:54:28 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Tue, 10 Dec 2024 12:54:28 -0800
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
Message-ID: <20241210125012120-0800.eberman@hu-eberman-lv.qualcomm.com>

On Mon, Dec 09, 2024 at 01:49:15PM +0530, Akhil P Oommen wrote:
> When kernel is booted in EL2, SECVID registers are accessible to the
> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> on Zap firmware. Also, we can't load a secure firmware without a
> hypervisor that supports it.
> 
> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
> 
> 1. Gunyah (No KVM) - Loads zap shader based on DT
> 2. KVM in VHE - Skips zap shader load and programs SECVID register
> 3. KVM in nVHE - Loads zap shader based on DT

I think this might be misleading. As I understand, KVM in nVHE doesn't
support loading secure firmware. I'm not aware of any support added to
make it work. So, the driver will try to load zap shader and it fails
same as it does today.

> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
> 	programs SECVID register
> 
> For (1) and (3) configuration, this patch doesn't have any impact.
> Driver loads secure firmware based on other existing hints.
> 
> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
> ---
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 +++++++++++++++++++++++------------
>  1 file changed, 54 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index 019610341df1..9dcaa8472430 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -14,6 +14,10 @@
>  #include <linux/pm_domain.h>
>  #include <linux/soc/qcom/llcc-qcom.h>
>  
> +#ifdef CONFIG_ARM64
> +#include <asm/virt.h>
> +#endif
> +
>  #define GPU_PAS_ID 13
>  
>  static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
> @@ -998,6 +1002,54 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
>  	return ret;
>  }
>  
> +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> +{
> +	int ret;
> +
> +#ifdef CONFIG_ARM64
> +	/*
> +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> +	 * to switch the secure mode to avoid the dependency on zap shader.
> +	 */
> +	if (is_kernel_in_hyp_mode())
> +		goto direct_switch;
> +#endif
> +
> +	/*
> +	 * Try to load a zap shader into the secure world. If successful
> +	 * we can use the CP to switch out of secure mode. If not then we
> +	 * have no resource but to try to switch ourselves out manually. If we
> +	 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
> +	 * be blocked and a permissions violation will soon follow.
> +	 */
> +	ret = a6xx_zap_shader_init(gpu);
> +	if (ret == -ENODEV) {
> +		/*
> +		 * This device does not use zap shader (but print a warning
> +		 * just in case someone got their dt wrong.. hopefully they
> +		 * have a debug UART to realize the error of their ways...
> +		 * if you mess this up you are about to crash horribly)
> +		 */
> +		dev_warn_once(gpu->dev->dev,
> +			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
> +		goto direct_switch;
> +	} else if (ret)
> +		return ret;
> +
> +	OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
> +	OUT_RING(gpu->rb[0], 0x00000000);
> +
> +	a6xx_flush(gpu, gpu->rb[0]);
> +	if (!a6xx_idle(gpu, gpu->rb[0]))
> +		return -EINVAL;
> +
> +	return 0;
> +
> +direct_switch:
> +	gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
> +	return 0;
> +}
> +
>  #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
>  		       A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
>  		       A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
> @@ -1341,35 +1393,9 @@ static int hw_init(struct msm_gpu *gpu)
>  	if (ret)
>  		goto out;
>  
> -	/*
> -	 * Try to load a zap shader into the secure world. If successful
> -	 * we can use the CP to switch out of secure mode. If not then we
> -	 * have no resource but to try to switch ourselves out manually. If we
> -	 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
> -	 * be blocked and a permissions violation will soon follow.
> -	 */
> -	ret = a6xx_zap_shader_init(gpu);
> -	if (!ret) {
> -		OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
> -		OUT_RING(gpu->rb[0], 0x00000000);
> -
> -		a6xx_flush(gpu, gpu->rb[0]);
> -		if (!a6xx_idle(gpu, gpu->rb[0]))
> -			return -EINVAL;
> -	} else if (ret == -ENODEV) {
> -		/*
> -		 * This device does not use zap shader (but print a warning
> -		 * just in case someone got their dt wrong.. hopefully they
> -		 * have a debug UART to realize the error of their ways...
> -		 * if you mess this up you are about to crash horribly)
> -		 */
> -		dev_warn_once(gpu->dev->dev,
> -			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
> -		gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
> -		ret = 0;
> -	} else {
> +	ret = a6xx_switch_secure_mode(gpu);
> +	if (!ret)
>  		return ret;
> -	}
>  
>  out:
>  	if (adreno_has_gmu_wrapper(adreno_gpu))
> 
> ---
> base-commit: f4a867a46862c1743501bbe8c813238456ec8699
> change-id: 20241120-drm-msm-kvm-support-cd6e6744ced6
> 
> Best regards,
> -- 
> Akhil P Oommen <quic_akhilpo at quicinc.com>
> 


From nfraprado at collabora.com  Tue Dec 10 12:54:27 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Tue, 10 Dec 2024 17:54:27 -0300
Subject: [PATCH v2 0/2] Enable audio output for Genio 700 EVK board
Message-ID: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>

This series enables audio output support for the Genio 700 EVK board.
Patch 1 adds the missing #sound-dai-cells property in the MT6359 node as
a prerequisite, and patch 2 describes the audio DT nodes to get audio
output working on the two audio jacks, Earphone and Speaker, present on
the board.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
Changes in v2:
- Dropped merged/unnecessary patches (2, 3, 4)
- Removed unnecessary mediatek,dai-link property
- Link to v1: https://lore.kernel.org/r/20241205-genio700-audio-output-v1-0-0e955c78c29e at collabora.com

---
N?colas F. R. A. Prado (2):
      arm64: dts: mt6359: Add #sound-dai-cells property
      arm64: dts: mediatek: mt8390-genio-700-evk: Add sound output support

 arch/arm64/boot/dts/mediatek/mt6359.dtsi           |  1 +
 .../boot/dts/mediatek/mt8390-genio-700-evk.dts     | 48 ++++++++++++++++++++++
 2 files changed, 49 insertions(+)
---
base-commit: d1486dca38afd08ca279ae94eb3a397f10737824
change-id: 20241204-genio700-audio-output-fba8f2ebad10

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From nfraprado at collabora.com  Tue Dec 10 12:54:28 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Tue, 10 Dec 2024 17:54:28 -0300
Subject: [PATCH v2 1/2] arm64: dts: mt6359: Add #sound-dai-cells property
In-Reply-To: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>
References: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>
Message-ID: <20241210-genio700-audio-output-v2-1-c50886ae0be2@collabora.com>

MT6359 provides digital audio interfaces. Add a #sound-dai-cells
property for it to allow pointing to it from dai-link nodes.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt6359.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
index 8e1b8c85c6ede94a7beaefcdfc74ce47b3ab50fe..150ad84d5d2b30ab6064c71e1375ce5df5ae4b36 100644
--- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
@@ -8,6 +8,7 @@ pmic: pmic {
 		compatible = "mediatek,mt6359";
 		interrupt-controller;
 		#interrupt-cells = <2>;
+		#sound-dai-cells = <1>;
 
 		pmic_adc: adc {
 			compatible = "mediatek,mt6359-auxadc";

-- 
2.47.1



From nfraprado at collabora.com  Tue Dec 10 12:54:29 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Tue, 10 Dec 2024 17:54:29 -0300
Subject: [PATCH v2 2/2] arm64: dts: mediatek: mt8390-genio-700-evk: Add
 sound output support
In-Reply-To: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>
References: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>
Message-ID: <20241210-genio700-audio-output-v2-2-c50886ae0be2@collabora.com>

Describe all the components to get sound output working on the two audio
jacks, Earphone and Speaker, present on the Genio 700 EVK board with the
audio DSP enabled.

Co-developed-by: Aary Patil <aary.patil at mediatek.com>
Signed-off-by: Aary Patil <aary.patil at mediatek.com>
Co-developed-by: Suhrid Subramaniam <suhrid.subramaniam at mediatek.com>
Signed-off-by: Suhrid Subramaniam <suhrid.subramaniam at mediatek.com>
Co-developed-by: parkeryang <Parker.Yang at mediatek.com>
Signed-off-by: parkeryang <Parker.Yang at mediatek.com>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 .../boot/dts/mediatek/mt8390-genio-700-evk.dts     | 48 ++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
index 13f2e0e3fa8ab6679f843693230b9661d323a705..04e4a2f73799d04d50476eb1664b1afdbc66c124 100644
--- a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
@@ -93,6 +93,24 @@ vpu_mem: memory at 57000000 {
 			compatible = "shared-dma-pool";
 			reg = <0 0x57000000 0 0x1400000>; /* 20 MB */
 		};
+
+		adsp_mem: memory at 60000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x60000000 0 0xf00000>;
+			no-map;
+		};
+
+		afe_dma_mem: memory at 60f00000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x60f00000 0 0x100000>;
+			no-map;
+		};
+
+		adsp_dma_mem: memory at 61000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x61000000 0 0x100000>;
+			no-map;
+		};
 	};
 
 	common_fixed_5v: regulator-0 {
@@ -210,6 +228,16 @@ usb_p2_vbus: regulator-9 {
 	};
 };
 
+&adsp {
+	memory-region = <&adsp_dma_mem>, <&adsp_mem>;
+	status = "okay";
+};
+
+&afe {
+	memory-region = <&afe_dma_mem>;
+	status = "okay";
+};
+
 &gpu {
 	mali-supply = <&mt6359_vproc2_buck_reg>;
 	status = "okay";
@@ -932,6 +960,26 @@ &scp {
 	status = "okay";
 };
 
+&sound {
+	compatible = "mediatek,mt8390-mt6359-evk", "mediatek,mt8188-mt6359-evb";
+	model = "mt8390-evk";
+	pinctrl-names = "default";
+	pinctrl-0 = <&audio_default_pins>;
+	audio-routing =
+		"Headphone", "Headphone L",
+		"Headphone", "Headphone R";
+	mediatek,adsp = <&adsp>;
+	status = "okay";
+
+	dai-link-0 {
+		link-name = "DL_SRC_BE";
+
+		codec {
+			sound-dai = <&pmic 0>;
+		};
+	};
+};
+
 &spi2 {
 	pinctrl-0 = <&spi2_pins>;
 	pinctrl-names = "default";

-- 
2.47.1



From olteanv at gmail.com  Tue Dec 10 13:05:40 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 10 Dec 2024 23:05:40 +0200
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <20241209151813.106eda03@kernel.org>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209151813.106eda03@kernel.org>
Message-ID: <20241210210540.jxhni4p2lrvdwoop@skbuf>

On Mon, Dec 09, 2024 at 03:18:13PM -0800, Jakub Kicinski wrote:
> On Mon,  9 Dec 2024 14:44:22 +0100 Christian Marangi wrote:
> > +	regmap = devm_regmap_init(priv->dev, NULL, priv,
> > +				  &an8855_regmap_config);
> > +	if (IS_ERR(regmap))
>             ^^^^^^^^^^^^^^
> > +		dev_err_probe(priv->dev, PTR_ERR(priv->dev),
>                                          ^^^^^^^^^^^^^^^^^^
> > +			      "regmap initialization failed\n");
> 
> wrong ptr?
> -- 
> pw-bot: cr

Also, why continue execution if devm_regmap_init() failed?


From markuss.broks at gmail.com  Tue Dec 10 13:10:46 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Tue, 10 Dec 2024 23:10:46 +0200
Subject: [PATCH v1 2/2] arm64: dts: exynos8895: Add syscon-poweroff and
 syscon-reboot nodes
In-Reply-To: <20241210180216.398165-3-ivo.ivanov.ivanov1@gmail.com>
References: <20241210180216.398165-1-ivo.ivanov.ivanov1@gmail.com>
 <20241210180216.398165-3-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <768b70d3-910a-42f2-a61a-6338a41f41b1@gmail.com>

Hi,

On 12/10/24 8:02 PM, Ivaylo Ivanov wrote:
> For Exynos8895, a reboot is handled by setting the bit(SWRESET_SYSTEM[1])
> of SWRESET register(PMU + 0x400) and power-off is handled by setting
> bit(DATA[8]) of PS_HOLD_CONTROL register (PMU + 0x330c).
>
> Tested using "reboot" and "poweroff -p" commands.
>
> Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
> ---
>   arch/arm64/boot/dts/exynos/exynos8895.dtsi | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos8895.dtsi b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
> index 90b318b2f..9eb89dd19 100644
> --- a/arch/arm64/boot/dts/exynos/exynos8895.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
> @@ -388,6 +388,21 @@ pmu_system_controller: system-controller at 16480000 {
>   			compatible = "samsung,exynos8895-pmu",
>   				     "samsung,exynos7-pmu", "syscon";
>   			reg = <0x16480000 0x10000>;
> +
> +			poweroff: syscon-poweroff {
> +				compatible = "syscon-poweroff";
> +				regmap = <&pmu_system_controller>;
> +				offset = <0x330c>; /* PS_HOLD_CONTROL */
> +				mask = <0x100>; /* reset value */
> +			};
> +
> +			reboot: syscon-reboot {
> +				compatible = "syscon-reboot";
> +				regmap = <&pmu_system_controller>;
> +				offset = <0x400>; /* SWRESET */
> +				mask = <0x1>; /* SWRESET_SYSTEM */
> +				value = <0x1>; /* reset value */
> +			};
>   		};
Aren't those already included with 
arm/samsung/exynos-syscon-restart.dtsi? I can see that the values for 
poweroff are different here though, does it not work with the value from 
exynos-syscon-restart?
>   
>   		pinctrl_alive: pinctrl at 164b0000 {


- Markuss



From olteanv at gmail.com  Tue Dec 10 13:15:29 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 10 Dec 2024 23:15:29 +0200
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
Message-ID: <20241210211529.osgzd54flq646bcr@skbuf>

On Mon, Dec 09, 2024 at 02:44:22PM +0100, Christian Marangi wrote:
> +int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
> +			u8 page) __must_hold(&priv->bus->mdio_lock)
> +{
> +	struct mii_bus *bus = priv->bus;
> +	int ret;
> +
> +	ret = __mdiobus_write(bus, phy_id, AN8855_PHY_SELECT_PAGE, page);
> +	if (ret < 0)
> +		dev_err_ratelimited(&bus->dev,
> +				    "failed to set an8855 mii page\n");
> +
> +	/* Cache current page if next mii read/write is for switch */
> +	priv->current_page = page;
> +	return ret < 0 ? ret : 0;
> +}
> +EXPORT_SYMBOL_GPL(an8855_mii_set_page);

You could keep the implementation more contained, and you could avoid
exporting an8855_mii_set_page() and an8855_mfd_priv to the MDIO
passthrough driver, if you implement a virtual regmap and give it to the
MDIO passthrough child MFD device.

If this bus supports only clause 22 accesses (and it looks like it does),
you could expose a 16-bit regmap with a linear address space of 32 MDIO
addresses x 65536 registers. The bus->read() of the MDIO bus passthrough
just performs regmap_read(), and bus->write() just performs regmap_write().
The MFD driver decodes the regmap address into a PHY address and a regnum,
and performs the page switching locally, if needed.


From dmitry.baryshkov at linaro.org  Tue Dec 10 13:20:26 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 10 Dec 2024 23:20:26 +0200
Subject: [PATCH v2 04/10] drm/amd/display: use eld_mutex to protect
 access to connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-4-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
 <20241206-drm-connector-eld-mutex-v2-4-c9bce1ee8bea@linaro.org>
Message-ID: <pgi7p3aemxm3db2k27vi5euh6q6ppayrw6y7tcfeq4g5z23hzr@xousag2qhobp>

On Fri, Dec 06, 2024 at 11:43:07AM +0200, Dmitry Baryshkov wrote:
> Reading access to connector->eld can happen at the same time the
> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
> order to protect connector->eld from concurrent access.
> 
> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
>  1 file changed, 2 insertions(+)

Harry, Leo, Rodrigo, Alex, Christian, Xinhui, any response to this one
and to the radeon patches? I'd like to be able to pick the series for
drm-misc and these two are not reviewed by you.

> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 19a58630e774029767bf2a27eb4ddf17e3c21129..04c68c320252b5ce9647f0606fb86fe57f347639 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -1037,8 +1037,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port,
>  			continue;
>  
>  		*enabled = true;
> +		mutex_lock(&connector->eld_mutex);
>  		ret = drm_eld_size(connector->eld);
>  		memcpy(buf, connector->eld, min(max_bytes, ret));
> +		mutex_unlock(&connector->eld_mutex);
>  
>  		break;
>  	}
> 
> -- 
> 2.39.5
> 

-- 
With best wishes
Dmitry


From maz at kernel.org  Tue Dec 10 13:24:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Dec 2024 21:24:03 +0000
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
Message-ID: <87ed2fs03w.wl-maz@kernel.org>

On Mon, 09 Dec 2024 08:19:15 +0000,
Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> 
> When kernel is booted in EL2, SECVID registers are accessible to the
> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> on Zap firmware. Also, we can't load a secure firmware without a
> hypervisor that supports it.
> 
> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
> 
> 1. Gunyah (No KVM) - Loads zap shader based on DT
> 2. KVM in VHE - Skips zap shader load and programs SECVID register
> 3. KVM in nVHE - Loads zap shader based on DT
> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
> 	programs SECVID register
>
> For (1) and (3) configuration, this patch doesn't have any impact.
> Driver loads secure firmware based on other existing hints.

The moment the kernel is entered at EL2, this is a bare metal
situation, and everything is accessible. So your distinction between
VHE and nVHE (which would equally apply to hVHE and pKVM) makes no
sense at all. Same thing for KVM being disabled, which has no bearing
on what can be accessed.

> 
> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
> ---
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 +++++++++++++++++++++++------------
>  1 file changed, 54 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index 019610341df1..9dcaa8472430 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -14,6 +14,10 @@
>  #include <linux/pm_domain.h>
>  #include <linux/soc/qcom/llcc-qcom.h>
>  
> +#ifdef CONFIG_ARM64
> +#include <asm/virt.h>
> +#endif

How about 32bit ARM?

> +
>  #define GPU_PAS_ID 13
>  
>  static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
> @@ -998,6 +1002,54 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
>  	return ret;
>  }
>  
> +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> +{
> +	int ret;
> +
> +#ifdef CONFIG_ARM64
> +	/*
> +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> +	 * to switch the secure mode to avoid the dependency on zap shader.
> +	 */
> +	if (is_kernel_in_hyp_mode())
> +		goto direct_switch;

No, please. To check whether you are *booted* at EL2, you need to
check for is_hyp_available(). Whether the kernel runs at EL1 or EL2 is
none of the driver's business, really. This is still absolutely
disgusting from an abstraction perspective, but I guess we don't have
much choice here.

In the future, for anything involving KVM, please Cc the maintainers,
reviewers and mailing list listed in the MAINTAINERS file.

Thanks,

	M.

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


From Frank.Li at nxp.com  Tue Dec 10 13:27:03 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 10 Dec 2024 16:27:03 -0500
Subject: [PATCH v2 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
References: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
Message-ID: <20241210-imx91tmu-v2-2-5032aad4d88e@nxp.com>

From: Pengfei Li <pengfei.li_1 at nxp.com>

Introduce support for the i.MX91 thermal monitoring unit, which features a
single sensor for the CPU. The register layout differs from other chips,
necessitating the creation of a dedicated file for this.

Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
change from v1 to v2
- use low case for hexvalue
- combine struct imx91_tmu and tmu_sensor
- simplify imx91_tmu_start() and imx91_tmu_enable()
- use s16 for imx91_tmu_get_temp(), which may negative value
- use reverse christmas tree style
- use run time pm
- use oneshot to sample temp
- register thermal zone after hardware init
---
 drivers/thermal/Kconfig         |  10 ++
 drivers/thermal/Makefile        |   1 +
 drivers/thermal/imx91_thermal.c | 265 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 276 insertions(+)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index d3f9686e26e71..da403ed86aeb1 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -296,6 +296,16 @@ config IMX8MM_THERMAL
 	  cpufreq is used as the cooling device to throttle CPUs when the passive
 	  trip is crossed.
 
+config IMX91_THERMAL
+	tristate "Temperature sensor driver for NXP i.MX91 SoC"
+	depends on ARCH_MXC || COMPILE_TEST
+	depends on OF
+	help
+	  Support for Temperature sensor found on NXP i.MX91 SoC.
+	  It supports one critical trip point and one passive trip point. The
+	  cpufreq is used as the cooling device to throttle CPUs when the passive
+	  trip is crossed.
+
 config K3_THERMAL
 	tristate "Texas Instruments K3 thermal support"
 	depends on ARCH_K3 || COMPILE_TEST
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 9abf43a74f2bb..08da241e6a598 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
 obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
 obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
 obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
+obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
 obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
 obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
 obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
new file mode 100644
index 0000000000000..ebb59eda92951
--- /dev/null
+++ b/drivers/thermal/imx91_thermal.c
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2024 NXP.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/thermal.h>
+
+#define CTRL0			0x0
+
+#define STAT0			0x10
+#define STAT0_DRDY0_IF_MASK	BIT(16)
+
+#define DATA0			0x20
+
+#define THR_CTRL01		0x30
+#define THR_CTRL23		0x40
+
+#define CTRL1			0x200
+#define CTRL1_SET		0x204
+#define CTRL1_CLR		0x208
+#define CTRL1_EN		BIT(31)
+#define CTRL1_START		BIT(30)
+#define CTRL1_STOP		BIT(29)
+#define CTRL1_RES_MASK		GENMASK(19, 18)
+#define CTRL1_MEAS_MODE_MASK	GENMASK(25, 24)
+#define   CTRL1_MEAS_MODE_SINGLE	0
+#define   CTRL1_MEAS_MODE_CONTINUES	1
+#define   CTRL1_MEAS_MODE_PERIODIC	2
+
+#define REF_DIV			0x280
+#define DIV_EN			BIT(31)
+#define DIV_MASK		GENMASK(23, 16)
+
+#define PUD_ST_CTRL		0x2B0
+#define PUDL_MASK		GENMASK(23, 16)
+
+#define TRIM1			0x2E0
+#define TRIM2			0x2F0
+
+#define TMU_TEMP_LOW_LIMIT	-40000
+#define TMU_TEMP_HIGH_LIMIT	125000
+
+#define DEFAULT_TRIM1_CONFIG 0xb561bc2d
+#define DEFAULT_TRIM2_CONFIG 0x65d4
+
+struct imx91_tmu {
+	void __iomem *base;
+	struct clk *clk;
+	struct device *dev;
+	struct thermal_zone_device *tzd;
+};
+
+static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
+{
+	u32 val = start ? CTRL1_START : CTRL1_STOP;
+
+	writel_relaxed(val, tmu->base + CTRL1_SET);
+}
+
+static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
+{
+	u32 reg = enable ? CTRL1_SET : CTRL1_CLR;
+
+	writel_relaxed(CTRL1_EN, tmu->base + reg);
+}
+
+static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+	struct imx91_tmu *tmu = thermal_zone_device_priv(tz);
+	s16 data;
+	int ret;
+	u32 val;
+
+	ret = pm_runtime_resume_and_get(tmu->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = readl_relaxed_poll_timeout(tmu->base + STAT0, val,
+					 val & STAT0_DRDY0_IF_MASK, 1000,
+					 40000);
+	if (ret)
+		return -EAGAIN;
+
+	/* DATA0 is 16bit signed number */
+	data = readw_relaxed(tmu->base + DATA0);
+	*temp = data * 1000 / 64;
+	if (*temp < TMU_TEMP_LOW_LIMIT || *temp > TMU_TEMP_HIGH_LIMIT)
+		return -EAGAIN;
+
+	pm_runtime_put(tmu->dev);
+
+	return 0;
+}
+
+static struct thermal_zone_device_ops tmu_tz_ops = {
+	.get_temp = imx91_tmu_get_temp,
+};
+
+static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
+{
+	struct device *dev = tmu->dev;
+	u32 trim1, trim2;
+	int ret;
+
+	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
+	if (ret)
+		return ret;
+
+	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
+	if (ret)
+		return ret;
+
+	if (trim1 == 0 || trim2 == 0)
+		return -EINVAL;
+
+	writel_relaxed(trim1, tmu->base + TRIM1);
+	writel_relaxed(trim2, tmu->base + TRIM2);
+
+	return 0;
+}
+
+static int imx91_tmu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct imx91_tmu *tmu;
+	unsigned long rate;
+	u32 div;
+	int ret;
+
+	tmu = devm_kzalloc(&pdev->dev, sizeof(struct imx91_tmu), GFP_KERNEL);
+	if (!tmu)
+		return -ENOMEM;
+
+	tmu->dev = &pdev->dev;
+
+	tmu->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(tmu->base))
+		return PTR_ERR(tmu->base);
+
+	tmu->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(tmu->clk))
+		return dev_err_probe(dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
+
+	platform_set_drvdata(pdev, tmu);
+
+	/* disable the monitor during initialization */
+	imx91_tmu_enable(tmu, false);
+	imx91_tmu_start(tmu, false);
+
+	ret = imx91_init_from_nvmem_cells(tmu);
+	if (ret) {
+		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
+		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
+	}
+
+	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
+	rate = clk_get_rate(tmu->clk);
+	div = (rate / 4000000) - 1;
+	if (div > FIELD_GET(DIV_MASK, DIV_MASK))
+		return -EINVAL;
+
+	/* Set divider value and enable divider */
+	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
+
+	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
+	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
+
+	/*
+	 * Set resolution mode
+	 * 00b - Conversion time = 0.59325 ms
+	 * 01b - Conversion time = 1.10525 ms
+	 * 10b - Conversion time = 2.12925 ms
+	 * 11b - Conversion time = 4.17725 ms
+	 */
+	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
+	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);
+
+	writel_relaxed(CTRL1_MEAS_MODE_MASK, tmu->base + CTRL1_CLR);
+	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, CTRL1_MEAS_MODE_SINGLE),
+		       tmu->base + CTRL1_SET);
+
+	clk_disable_unprepare(tmu->clk);
+	pm_runtime_set_suspended(dev);
+	pm_runtime_enable(dev);
+
+	tmu->tzd = devm_thermal_of_zone_register(dev, 0, tmu, &tmu_tz_ops);
+	if (IS_ERR(tmu->tzd))
+		return dev_err_probe(dev, PTR_ERR(tmu->tzd),
+				     "failed to register thermal zone sensor\n");
+
+	return 0;
+}
+
+static void imx91_tmu_remove(struct platform_device *pdev)
+{
+	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
+
+	/* disable tmu */
+	imx91_tmu_start(tmu, false);
+	imx91_tmu_enable(tmu, false);
+}
+
+static int imx91_tmu_runtime_suspend(struct device *dev)
+{
+	struct imx91_tmu *tmu = dev_get_drvdata(dev);
+
+	/* disable tmu */
+	imx91_tmu_start(tmu, false);
+	imx91_tmu_enable(tmu, false);
+
+	clk_disable_unprepare(tmu->clk);
+
+	return 0;
+}
+
+static int imx91_tmu_runtime_resume(struct device *dev)
+{
+	struct imx91_tmu *tmu = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(tmu->clk);
+	if (ret)
+		return ret;
+
+	imx91_tmu_enable(tmu, true);
+	imx91_tmu_start(tmu, true);
+
+	return 0;
+}
+
+static const struct dev_pm_ops imx91_tmu_pm_ops = {
+	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+	RUNTIME_PM_OPS(imx91_tmu_runtime_suspend, imx91_tmu_runtime_resume, NULL)
+};
+
+static const struct of_device_id imx91_tmu_table[] = {
+	{ .compatible = "fsl,imx91-tmu", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, imx91_tmu_table);
+
+static struct platform_driver imx91_tmu = {
+	.driver = {
+		.name	= "i.MX91_thermal",
+		.pm	= pm_ptr(&imx91_tmu_pm_ops),
+		.of_match_table = imx91_tmu_table,
+	},
+	.probe = imx91_tmu_probe,
+	.remove = imx91_tmu_remove,
+};
+module_platform_driver(imx91_tmu);
+
+MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
+MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From Frank.Li at nxp.com  Tue Dec 10 13:27:01 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 10 Dec 2024 16:27:01 -0500
Subject: [PATCH v2 0/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
Message-ID: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>

- Add binding doc
- Add imx91 thermal driver
- dts part wait for https://lore.kernel.org/imx/Z04W5chGq5TitB9f at lizhi-Precision-Tower-5810/
merged, so not in this serial.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Changes in v2:
- use low case for hexvalue
- combine struct imx91_tmu and tmu_sensor
- simplify imx91_tmu_start() and imx91_tmu_enable()
- use s16 for imx91_tmu_get_temp(), which may negative value
- use reverse christmas tree style
- use run time pm
- use oneshot to sample temp
- register thermal zone after hardware init
- Link to v1: https://lore.kernel.org/r/20241209-imx91tmu-v1-0-7859c5387f31 at nxp.com

---
Pengfei Li (2):
      dt-bindings: thermal: fsl,imx91-tmu: add bindings for NXP i.MX91 thermal module
      thermal: imx91: Add support for i.MX91 thermal monitoring unit

 .../devicetree/bindings/thermal/fsl,imx91-tmu.yaml |  65 +++++
 drivers/thermal/Kconfig                            |  10 +
 drivers/thermal/Makefile                           |   1 +
 drivers/thermal/imx91_thermal.c                    | 265 +++++++++++++++++++++
 4 files changed, 341 insertions(+)
---
base-commit: d07c576946b2bc440d6d2073998023e8a0bd7568
change-id: 20241209-imx91tmu-af2a7c042d8d

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Tue Dec 10 13:27:02 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 10 Dec 2024 16:27:02 -0500
Subject: [PATCH v2 1/2] dt-bindings: thermal: fsl,imx91-tmu: add bindings
 for NXP i.MX91 thermal module
In-Reply-To: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
References: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
Message-ID: <20241210-imx91tmu-v2-1-5032aad4d88e@nxp.com>

From: Pengfei Li <pengfei.li_1 at nxp.com>

Add bindings documentation for i.MX91 thermal modules.

Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 .../devicetree/bindings/thermal/fsl,imx91-tmu.yaml | 65 ++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml b/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml
new file mode 100644
index 0000000000000..f5898db1006c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/fsl,imx91-tmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX91 Thermal
+
+maintainers:
+  - Pengfei Li <pengfei.li_1 at nxp.com>
+
+description:
+  i.MX91 features a new temperature sensor. It includes programmable
+  temperature threshold comparators for both normal and privileged
+  accesses and allows a programmable measurement frequency for the
+  Periodic One-Shot Measurement mode. Additionally, it provides
+  status registers for indicating the end of measurement and threshold
+  violation events.
+
+properties:
+  compatible:
+    items:
+      - const: fsl,imx91-tmu
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  nvmem-cells:
+    items:
+      - description: Phandle to the trim control 1 provided by ocotp
+      - description: Phandle to the trim control 2 provided by ocotp
+
+  nvmem-cell-names:
+    items:
+      - const: trim1
+      - const: trim2
+
+  "#thermal-sensor-cells":
+    enum: [0, 1]
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#thermal-sensor-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx93-clock.h>
+
+    thermal-sensor at 44482000 {
+        compatible = "fsl,imx91-tmu";
+        reg = <0x44482000 0x1000>;
+        #thermal-sensor-cells = <0>;
+        clocks = <&clk IMX93_CLK_TMC_GATE>;
+        nvmem-cells = <&tmu_trim1>, <&tmu_trim2>;
+        nvmem-cell-names = "trim1", "trim2";
+    };
+
+...

-- 
2.34.1



From ivo.ivanov.ivanov1 at gmail.com  Tue Dec 10 13:28:25 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Tue, 10 Dec 2024 23:28:25 +0200
Subject: [PATCH v1 2/2] arm64: dts: exynos8895: Add syscon-poweroff and
 syscon-reboot nodes
In-Reply-To: <768b70d3-910a-42f2-a61a-6338a41f41b1@gmail.com>
References: <20241210180216.398165-1-ivo.ivanov.ivanov1@gmail.com>
 <20241210180216.398165-3-ivo.ivanov.ivanov1@gmail.com>
 <768b70d3-910a-42f2-a61a-6338a41f41b1@gmail.com>
Message-ID: <e5a847f7-5e63-4860-8b4a-dfa378989c57@gmail.com>

On 12/10/24 23:10, Markuss Broks wrote:
> Hi,
>
> On 12/10/24 8:02 PM, Ivaylo Ivanov wrote:
>> For Exynos8895, a reboot is handled by setting the bit(SWRESET_SYSTEM[1])
>> of SWRESET register(PMU + 0x400) and power-off is handled by setting
>> bit(DATA[8]) of PS_HOLD_CONTROL register (PMU + 0x330c).
>>
>> Tested using "reboot" and "poweroff -p" commands.
>>
>> Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
>> ---
>> ? arch/arm64/boot/dts/exynos/exynos8895.dtsi | 15 +++++++++++++++
>> ? 1 file changed, 15 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/exynos/exynos8895.dtsi b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
>> index 90b318b2f..9eb89dd19 100644
>> --- a/arch/arm64/boot/dts/exynos/exynos8895.dtsi
>> +++ b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
>> @@ -388,6 +388,21 @@ pmu_system_controller: system-controller at 16480000 {
>> ????????????? compatible = "samsung,exynos8895-pmu",
>> ?????????????????????? "samsung,exynos7-pmu", "syscon";
>> ????????????? reg = <0x16480000 0x10000>;
>> +
>> +??????????? poweroff: syscon-poweroff {
>> +??????????????? compatible = "syscon-poweroff";
>> +??????????????? regmap = <&pmu_system_controller>;
>> +??????????????? offset = <0x330c>; /* PS_HOLD_CONTROL */
>> +??????????????? mask = <0x100>; /* reset value */
>> +??????????? };
>> +
>> +??????????? reboot: syscon-reboot {
>> +??????????????? compatible = "syscon-reboot";
>> +??????????????? regmap = <&pmu_system_controller>;
>> +??????????????? offset = <0x400>; /* SWRESET */
>> +??????????????? mask = <0x1>; /* SWRESET_SYSTEM */
>> +??????????????? value = <0x1>; /* reset value */
>> +??????????? };
>> ????????? };
> Aren't those already included with arm/samsung/exynos-syscon-restart.dtsi? I can see that the values for poweroff are different here though, does it not work with the value from exynos-syscon-restart?

Riiight... seems like I've completely omitted that during testing.
Although the poweroff mask should be different, it's meant to set
BIT 8. I'll check it tomorrow and send a v2.

Thanks!
Best regards, Ivo.

>> ? ????????? pinctrl_alive: pinctrl at 164b0000 {
>
>
> - Markuss
>



From robh at kernel.org  Tue Dec 10 13:42:05 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 10 Dec 2024 15:42:05 -0600
Subject: [PATCH 1/2] arm64: dts: mediatek: mt8173-elm: Fix MT6397 PMIC
 sub-node names
In-Reply-To: <20241210092614.3951748-1-wenst@chromium.org>
References: <20241210092614.3951748-1-wenst@chromium.org>
Message-ID: <173386568696.497617.3727087837255802552.robh@kernel.org>


On Tue, 10 Dec 2024 17:26:12 +0800, Chen-Yu Tsai wrote:
> The MT6397 PMIC bindings specify exact names for its sub-nodes. The
> names used in the current dts don't match, causing a validation error.
> 
> Fix up the names. Also drop the label for the regulators node, since
> any reference should be against the individual regulator sub-nodes.
> 
> Fixes: 689b937bedde ("arm64: dts: mediatek: add mt8173 elm and hana board")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y mediatek/mt8173-evb.dtb' for 20241210092614.3951748-1-wenst at chromium.org:

arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vpca15: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vpca7: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vsramca15: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vsramca7: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vcore: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vgpu: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vdrm: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vio18: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vtcxo: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_va28: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vio28: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vusb: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vcama: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vmc: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vmch: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vemc3v3: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp1: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp2: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp3: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp4: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp5: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp6: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vibr: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
	from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#







From arinc.unal at arinc9.com  Tue Dec 10 13:45:13 2024
From: arinc.unal at arinc9.com (arinc.unal at arinc9.com)
Date: Tue, 10 Dec 2024 21:45:13 +0000 (UTC)
Subject: [PATCH net-next 5/9] net: dsa: mt753x: implement .support_eee()
 method
In-Reply-To: <E1tL14J-006cZa-Rh@rmk-PC.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
 <E1tL14J-006cZa-Rh@rmk-PC.armlinux.org.uk>
Message-ID: <3b9218282c34a1a0e10c4bc80a588082@arinc9.com>

On 2024-12-10 16:18, Russell King (Oracle) wrote:
> Implement the .support_eee() method by using the generic helper as all
> user ports support EEE.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Ar?n? ?NAL <arinc.unal at arinc9.com>

Much love.

Ar?n?


From naoki at radxa.com  Tue Dec 10 14:10:55 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 11 Dec 2024 07:10:55 +0900
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add USB-C support to ROCK 5B
In-Reply-To: <20241210163615.120594-1-sebastian.reichel@collabora.com>
References: <20241210163615.120594-1-sebastian.reichel@collabora.com>
Message-ID: <6A24DF29AE2F3CDC+70602cc7-2c03-470d-955f-06b2db116e20@radxa.com>

Hi Sebastian,

Thank you very much for your work!

$ cat 
/sys/class/power_supply/tcpm-source-psy-4-0022/{current_max,current_now,online,type,usb_type,voltage_max,voltage_min,voltage_now}
1500000
1500000
1
USB
C [PD] PD_PPS
20000000
20000000
20000000

$ cat 
/sys/class/power_supply/tcpm-source-psy-4-0022/{current_max,current_now,online,type,usb_type,voltage_max,voltage_min,voltage_now}
5000000
5000000
1
USB
C PD [PD_PPS]
20000000
20000000
20000000

$ ls /sys/class/udc/
fc000000.usb

I can configure it as CDC-NCM and host detects it.
But I could not use it as a HOST port. How to use it?

some minor nitpick is below:

On 12/11/24 01:36, Sebastian Reichel wrote:
> Add hardware description for the USB-C port in the Radxa Rock 5 Model B.
> This describes the OHCI, EHCI and XHCI USB parts, but not yet the
> DisplayPort AltMode (bindings are not yet upstream).
> 
> The fusb302 node is marked with status "fail", since the board is usually
> powered through the USB-C port. Handling of errors can result in hard
> resets, which removed the bus power for some time resulting in a board
> reset.
> 
> The main problem is that devices are supposed to interact with the
> power-supply within 5 seconds after the plug event according to the
> USB PD specification. This is more or less impossible to achieve when
> the kernel is the first software communicating with the power-supply.
> 
> Recent U-Boot (v2025.01) will start doing USB-PD communication, which
> solves this issue. Upstream U-Boot doing USB-PD communication will also
> set the fusb302 node status to "okay". That way booting a kernel with
> the updated DT on an old U-Boot avoids a reset loop.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> ---
>   .../boot/dts/rockchip/rk3588-rock-5b.dts      | 121 ++++++++++++++++++
>   1 file changed, 121 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> index d597112f1d5b..cb5990df6ccb 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> @@ -5,6 +5,7 @@
>   #include <dt-bindings/gpio/gpio.h>
>   #include <dt-bindings/leds/common.h>
>   #include <dt-bindings/soc/rockchip,vop2.h>
> +#include <dt-bindings/usb/pd.h>
>   #include "rk3588.dtsi"
>   
>   / {
> @@ -84,6 +85,15 @@ rfkill-bt {
>   		shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>   	};
>   
> +	vcc12v_dcin: regulator-vcc12v-dcin {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc12v_dcin";

typec_vin by schematic.

> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <12000000>;
> +		regulator-max-microvolt = <12000000>;
> +	};
> +
>   	vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 {
>   		compatible = "regulator-fixed";
>   		enable-active-high;
> @@ -142,6 +152,7 @@ vcc5v0_sys: regulator-vcc5v0-sys {
>   		regulator-boot-on;
>   		regulator-min-microvolt = <5000000>;
>   		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&vcc12v_dcin>;

typec_vin.

>   	};
>   
>   	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
> @@ -264,6 +275,67 @@ regulator-state-mem {
>   	};
>   };
>   
> +&i2c4 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c4m1_xfer>;
> +	status = "okay";
> +
> +	usbc0: usb-typec at 22 {

Is "usbc0" label necessary?

> +		compatible = "fcs,fusb302";
> +		reg = <0x22>;
> +		interrupt-parent = <&gpio3>;
> +		interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&usbc0_int>;

cc_int_l by schematic.

> +		vbus-supply = <&vcc12v_dcin>;

typec_vin

> +		/*
> +		 * When the board is starting to send power-delivery messages
> +		 * too late (5 seconds according to the specification), the
> +		 * power-supply reacts with a hard-reset. That removes the
> +		 * power from VBUS for some time, which resets te whole board.

... resets "the" whole board.

> +		 */
> +		status = "fail";
> +
> +		usb_con: connector {

Is "usb_con" label necessary?

> +			compatible = "usb-c-connector";
> +			label = "USB-C";
> +			data-role = "dual";
> +			power-role = "sink";
> +			try-power-role = "sink";
> +			op-sink-microwatt = <1000000>;
> +			sink-pdos =
> +				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>,
> +				<PDO_VAR(5000, 20000, 5000)>;
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				port at 0 {
> +					reg = <0>;
> +					usbc0_role_sw: endpoint {
> +						remote-endpoint = <&dwc3_0_role_switch>;
> +					};
> +				};
> +
> +				port at 1 {
> +					reg = <1>;
> +					usbc0_orien_sw: endpoint {
> +						remote-endpoint = <&usbdp_phy0_orientation_switch>;
> +					};
> +				};
> +
> +				port at 2 {
> +					reg = <2>;
> +					dp_altmode_mux: endpoint {
> +						remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
> +					};
> +				};
> +			};
> +		};
> +	};
> +};
> +
>   &i2c6 {
>   	status = "okay";
>   
> @@ -423,6 +495,10 @@ usb {
>   		vcc5v0_host_en: vcc5v0-host-en {
>   			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
>   		};
> +
> +		usbc0_int: usbc0-int {

cc_int_l

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> +			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
>   	};
>   };
>   
> @@ -835,6 +911,14 @@ &uart2 {
>   	status = "okay";
>   };
>   
> +&u2phy0 {
> +	status = "okay";
> +};
> +
> +&u2phy0_otg {
> +	status = "okay";
> +};
> +
>   &u2phy1 {
>   	status = "okay";
>   };
> @@ -866,6 +950,29 @@ &usbdp_phy1 {
>   	status = "okay";
>   };
>   
> +&usbdp_phy0 {
> +	mode-switch;
> +	orientation-switch;
> +	sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
> +	sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
> +	status = "okay";
> +
> +	port {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		usbdp_phy0_orientation_switch: endpoint at 0 {
> +			reg = <0>;
> +			remote-endpoint = <&usbc0_orien_sw>;
> +		};
> +
> +		usbdp_phy0_dp_altmode_mux: endpoint at 1 {
> +			reg = <1>;
> +			remote-endpoint = <&dp_altmode_mux>;
> +		};
> +	};
> +};
> +
>   &usb_host0_ehci {
>   	status = "okay";
>   };
> @@ -874,6 +981,20 @@ &usb_host0_ohci {
>   	status = "okay";
>   };
>   
> +&usb_host0_xhci {
> +	usb-role-switch;
> +	status = "okay";
> +
> +	port {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		dwc3_0_role_switch: endpoint {
> +			remote-endpoint = <&usbc0_role_sw>;
> +		};
> +	};
> +};
> +
>   &usb_host1_ehci {
>   	status = "okay";
>   };



From olteanv at gmail.com  Tue Dec 10 14:12:39 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Wed, 11 Dec 2024 00:12:39 +0200
Subject: [net-next PATCH v11 8/9] net: dsa: Add Airoha AN8855 5-Port
 Gigabit DSA Switch driver
In-Reply-To: <20241209134459.27110-9-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-9-ansuelsmth@gmail.com>
Message-ID: <20241210221239.vtsnijge2qdblpyq@skbuf>

On Mon, Dec 09, 2024 at 02:44:25PM +0100, Christian Marangi wrote:
> Add Airoha AN8855 5-Port Gigabit DSA switch. Switch can support
> 10M, 100M, 1Gb, 2.5G and 5G Ethernet Speed but 5G is currently error out
> as it's not currently supported as requires additional configuration for
> the PCS.
> 
> The switch is also a nvmem-provider as it does have EFUSE to calibrate
> the internal PHYs.

This second paragraph is no longer actual.

> 
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> ---
> index 2d10b4d6cfbb..99b1569ba35b 100644
> --- a/drivers/net/dsa/Kconfig
> +++ b/drivers/net/dsa/Kconfig
> @@ -24,6 +24,15 @@ config NET_DSA_LOOP
>  	  This enables support for a fake mock-up switch chip which
>  	  exercises the DSA APIs.
>  
> +config NET_DSA_AN8855
> +	tristate "Airoha AN8855 Ethernet switch support"
> +	depends on MFD_AIROHA_AN8855 || COMPILE_TEST
> +	depends on NET_DSA
> +	select NET_DSA_TAG_MTK
> +	help
> +	  This enables support for the Airoha AN8855 Ethernet switch
> +	  chip.

Not chip anymore, but for the switch *inside* the chip.

> +
>  source "drivers/net/dsa/hirschmann/Kconfig"
>  
>  config NET_DSA_LANTIQ_GSWIP
> diff --git a/drivers/net/dsa/an8855.c b/drivers/net/dsa/an8855.c
> new file mode 100644
> index 000000000000..4a56a55945cd
> --- /dev/null
> +++ b/drivers/net/dsa/an8855.c
> @@ -0,0 +1,2310 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Airoha AN8855 DSA Switch driver
> + * Copyright (C) 2023 Min Yao <min.yao at airoha.com>
> + * Copyright (C) 2024 Christian Marangi <ansuelsmth at gmail.com>
> + */
> +#include <linux/bitfield.h>
> +#include <linux/ethtool.h>
> +#include <linux/etherdevice.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/if_bridge.h>
> +#include <linux/iopoll.h>
> +#include <linux/netdevice.h>
> +#include <linux/of_net.h>
> +#include <linux/of_platform.h>
> +#include <linux/phylink.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <net/dsa.h>
> +
> +#include "an8855.h"
> +
> +static const struct an8855_mib_desc an8855_mib[] = {
> +	MIB_DESC(1, AN8855_PORT_MIB_TX_DROP, "TxDrop"),
> +	MIB_DESC(1, AN8855_PORT_MIB_TX_CRC_ERR, "TxCrcErr"),
> +	MIB_DESC(1, AN8855_PORT_MIB_TX_COLLISION, "TxCollision"),
> +	MIB_DESC(1, AN8855_PORT_MIB_TX_OVERSIZE_DROP, "TxOversizeDrop"),
> +	MIB_DESC(2, AN8855_PORT_MIB_TX_BAD_PKT_BYTES, "TxBadPktBytes"),
> +	MIB_DESC(1, AN8855_PORT_MIB_RX_DROP, "RxDrop"),
> +	MIB_DESC(1, AN8855_PORT_MIB_RX_FILTERING, "RxFiltering"),
> +	MIB_DESC(1, AN8855_PORT_MIB_RX_CRC_ERR, "RxCrcErr"),
> +	MIB_DESC(1, AN8855_PORT_MIB_RX_CTRL_DROP, "RxCtrlDrop"),
> +	MIB_DESC(1, AN8855_PORT_MIB_RX_INGRESS_DROP, "RxIngressDrop"),
> +	MIB_DESC(1, AN8855_PORT_MIB_RX_ARL_DROP, "RxArlDrop"),
> +	MIB_DESC(1, AN8855_PORT_MIB_FLOW_CONTROL_DROP, "FlowControlDrop"),
> +	MIB_DESC(1, AN8855_PORT_MIB_WRED_DROP, "WredDrop"),
> +	MIB_DESC(1, AN8855_PORT_MIB_MIRROR_DROP, "MirrorDrop"),
> +	MIB_DESC(2, AN8855_PORT_MIB_RX_BAD_PKT_BYTES, "RxBadPktBytes"),
> +	MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP, "RxsFlowSamplingPktDrop"),
> +	MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP, "RxsFlowTotalPktDrop"),
> +	MIB_DESC(1, AN8855_PORT_MIB_PORT_CONTROL_DROP, "PortControlDrop"),

There isn't any standard counter to expose these leftover ethtool -S
unstructured counters?

@Andrew, @Jakub: the more we push developers to stop reporting standard
counters as unstructured, the harder it will be to debug packet loss
on the CPU port, since we don't report anything structure there (no
netdev). For ethtool -S, we append the CPU port counters to the conduit
counters. Any ideas for gaining introspection into the structured
counters of the CPU port?

> +};
> +
> +static int
> +an8855_mib_init(struct an8855_priv *priv)
> +{
> +	int ret;
> +
> +	ret = regmap_write(priv->regmap, AN8855_MIB_CCR,
> +			   AN8855_CCR_MIB_ENABLE);
> +	if (ret)
> +		return ret;
> +
> +	return regmap_write(priv->regmap, AN8855_MIB_CCR,
> +			    AN8855_CCR_MIB_ACTIVATE);
> +}
> +
> +static void an8855_fdb_write(struct an8855_priv *priv, u16 vid,
> +			     u8 port_mask, const u8 *mac,
> +			     bool add) __must_hold(&priv->reg_mutex)
> +{
> +	u32 mac_reg[2] = { };
> +	u32 reg;
> +
> +	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC0, mac[0]);
> +	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC1, mac[1]);
> +	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC2, mac[2]);
> +	mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC3, mac[3]);
> +	mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC4, mac[4]);
> +	mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC5, mac[5]);
> +
> +	regmap_bulk_write(priv->regmap, AN8855_ATA1, mac_reg,
> +			  ARRAY_SIZE(mac_reg));
> +
> +	reg = AN8855_ATWD_IVL;
> +	if (add)
> +		reg |= AN8855_ATWD_VLD;
> +	reg |= FIELD_PREP(AN8855_ATWD_VID, vid);
> +	reg |= FIELD_PREP(AN8855_ATWD_FID, AN8855_FID_BRIDGED);
> +	regmap_write(priv->regmap, AN8855_ATWD, reg);
> +	regmap_write(priv->regmap, AN8855_ATWD2,
> +		     FIELD_PREP(AN8855_ATWD2_PORT, port_mask));

I guess regmap failures here shouldn't fail silently.

> +}
> +
> +static void an8855_fdb_read(struct an8855_priv *priv, struct an8855_fdb *fdb)
> +{
> +	u32 reg[4];
> +
> +	regmap_bulk_read(priv->regmap, AN8855_ATRD0, reg,
> +			 ARRAY_SIZE(reg));
> +
> +	fdb->live = FIELD_GET(AN8855_ATRD0_LIVE, reg[0]);
> +	fdb->type = FIELD_GET(AN8855_ATRD0_TYPE, reg[0]);
> +	fdb->ivl = FIELD_GET(AN8855_ATRD0_IVL, reg[0]);
> +	fdb->vid = FIELD_GET(AN8855_ATRD0_VID, reg[0]);
> +	fdb->fid = FIELD_GET(AN8855_ATRD0_FID, reg[0]);
> +	fdb->aging = FIELD_GET(AN8855_ATRD1_AGING, reg[1]);
> +	fdb->port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, reg[3]);
> +	fdb->mac[0] = FIELD_GET(AN8855_ATRD2_MAC0, reg[2]);
> +	fdb->mac[1] = FIELD_GET(AN8855_ATRD2_MAC1, reg[2]);
> +	fdb->mac[2] = FIELD_GET(AN8855_ATRD2_MAC2, reg[2]);
> +	fdb->mac[3] = FIELD_GET(AN8855_ATRD2_MAC3, reg[2]);
> +	fdb->mac[4] = FIELD_GET(AN8855_ATRD1_MAC4, reg[1]);
> +	fdb->mac[5] = FIELD_GET(AN8855_ATRD1_MAC5, reg[1]);
> +	fdb->noarp = !!FIELD_GET(AN8855_ATRD0_ARP, reg[0]);
> +}
> +
> +static int an8855_fdb_cmd(struct an8855_priv *priv, u32 cmd,
> +			  u32 *rsp) __must_hold(&priv->reg_mutex)
> +{
> +	u32 val;
> +	int ret;
> +
> +	/* Set the command operating upon the MAC address entries */
> +	val = AN8855_ATC_BUSY | cmd;
> +	ret = regmap_write(priv->regmap, AN8855_ATC, val);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_read_poll_timeout(priv->regmap, AN8855_ATC, val,
> +				       !(val & AN8855_ATC_BUSY), 20, 200000);
> +	if (ret)
> +		return ret;
> +
> +	if (rsp)
> +		*rsp = val;
> +
> +	return 0;
> +}
> +
> +static void
> +an8855_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
> +{
> +	struct dsa_port *dp = dsa_to_port(ds, port);
> +	struct an8855_priv *priv = ds->priv;
> +	bool learning = false;
> +	u32 stp_state;
> +
> +	switch (state) {
> +	case BR_STATE_DISABLED:
> +		stp_state = AN8855_STP_DISABLED;
> +		break;
> +	case BR_STATE_BLOCKING:
> +		stp_state = AN8855_STP_BLOCKING;
> +		break;
> +	case BR_STATE_LISTENING:
> +		stp_state = AN8855_STP_LISTENING;
> +		break;
> +	case BR_STATE_LEARNING:
> +		stp_state = AN8855_STP_LEARNING;
> +		learning = dp->learning;
> +		break;
> +	case BR_STATE_FORWARDING:
> +		learning = dp->learning;
> +		fallthrough;
> +	default:
> +		stp_state = AN8855_STP_FORWARDING;
> +		break;
> +	}
> +
> +	regmap_update_bits(priv->regmap, AN8855_SSP_P(port),
> +			   AN8855_FID_PST_MASK(AN8855_FID_BRIDGED),
> +			   AN8855_FID_PST_VAL(AN8855_FID_BRIDGED, stp_state));
> +
> +	regmap_update_bits(priv->regmap, AN8855_PSC_P(port), AN8855_SA_DIS,
> +			   learning ? 0 : AN8855_SA_DIS);

Similar: please test the regmap return code and print an error if it fails.

> +}
> +
> +static void an8855_port_fast_age(struct dsa_switch *ds, int port)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	int ret;
> +
> +	/* Set to clean Dynamic entry */
> +	ret = regmap_write(priv->regmap, AN8855_ATA2, AN8855_ATA2_TYPE);
> +	if (ret)
> +		return;

Similar regarding silent failures. This should apply to the entire
driver, please review again, there are too many instances to note them
all.

> +
> +	/* Set Port */
> +	ret = regmap_write(priv->regmap, AN8855_ATWD2,
> +			   FIELD_PREP(AN8855_ATWD2_PORT, BIT(port)));
> +	if (ret)
> +		return;
> +
> +	/* Flush Dynamic entry at port */
> +	an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_TYPE_PORT) |
> +		       AN8855_FDB_FLUSH, NULL);
> +}
> +
> +static int an8855_port_set_pid(struct an8855_priv *priv, int port,
> +			       u16 pid)

s/pid/pvid/

> +{
> +	int ret;
> +
> +	ret = regmap_update_bits(priv->regmap, AN8855_PPBV1_P(port),
> +				 AN8855_PPBV_G0_PORT_VID,
> +				 FIELD_PREP(AN8855_PPBV_G0_PORT_VID, pid));
> +	if (ret)
> +		return ret;
> +
> +	return regmap_update_bits(priv->regmap, AN8855_PVID_P(port),
> +				  AN8855_G0_PORT_VID,
> +				  FIELD_PREP(AN8855_G0_PORT_VID, pid));
> +}
> +
> +static int an8855_port_vlan_filtering(struct dsa_switch *ds, int port,
> +				      bool vlan_filtering,
> +				      struct netlink_ext_ack *extack)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	u32 val;
> +	int ret;
> +
> +	/* The port is being kept as VLAN-unaware port when bridge is
> +	 * set up with vlan_filtering not being set, Otherwise, the
> +	 * port and the corresponding CPU port is required the setup
> +	 * for becoming a VLAN-aware port.
> +	 */
> +	if (vlan_filtering) {
> +		u32 acc_frm;
> +		/* CPU port is set to fallback mode to let untagged
> +		 * frames pass through.
> +		 */
> +		ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT,
> +						AN8855_PORT_FALLBACK_MODE,
> +						AN8855_VLAN_EG_CONSISTENT,
> +						AN8855_VLAN_USER,
> +						AN8855_VLAN_ACC_ALL);
> +		if (ret)
> +			return ret;
> +
> +		ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
> +		if (ret)
> +			return ret;
> +
> +		/* Only accept tagged frames if PVID is not set */
> +		if (FIELD_GET(AN8855_G0_PORT_VID, val) != AN8855_PORT_VID_DEFAULT)
> +			acc_frm = AN8855_VLAN_ACC_TAGGED;
> +		else
> +			acc_frm = AN8855_VLAN_ACC_ALL;
> +
> +		/* Trapped into security mode allows packet forwarding through VLAN
> +		 * table lookup.
> +		 * Set the port as a user port which is to be able to recognize VID
> +		 * from incoming packets before fetching entry within the VLAN table.
> +		 */
> +		ret = an8855_port_set_vlan_mode(priv, port,
> +						AN8855_PORT_SECURITY_MODE,
> +						AN8855_VLAN_EG_DISABLED,
> +						AN8855_VLAN_USER,
> +						acc_frm);
> +		if (ret)
> +			return ret;
> +	} else {
> +		bool disable_cpu_vlan = true;
> +		struct dsa_port *dp;
> +		u32 port_mode;
> +
> +		/* This is called after .port_bridge_leave when leaving a VLAN-aware
> +		 * bridge. Don't set standalone ports to fallback mode.
> +		 */
> +		if (dsa_port_bridge_dev_get(dsa_to_port(ds, port)))
> +			port_mode = AN8855_PORT_FALLBACK_MODE;
> +		else
> +			port_mode = AN8855_PORT_MATRIX_MODE;
> +
> +		/* When a port is removed from the bridge, the port would be set up
> +		 * back to the default as is at initial boot which is a VLAN-unaware
> +		 * port.
> +		 */
> +		ret = an8855_port_set_vlan_mode(priv, port, port_mode,
> +						AN8855_VLAN_EG_CONSISTENT,
> +						AN8855_VLAN_TRANSPARENT,
> +						AN8855_VLAN_ACC_ALL);
> +		if (ret)
> +			return ret;
> +
> +		/* Restore default PVID */
> +		ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
> +		if (ret)
> +			return ret;
> +
> +		dsa_switch_for_each_user_port(dp, ds) {
> +			if (dsa_port_is_vlan_filtering(dp)) {
> +				disable_cpu_vlan = false;
> +				break;
> +			}
> +		}
> +
> +		if (disable_cpu_vlan) {
> +			ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT,
> +							AN8855_PORT_MATRIX_MODE,
> +							AN8855_VLAN_EG_CONSISTENT,
> +							AN8855_VLAN_USER,
> +							AN8855_VLAN_ACC_ALL);
> +			if (ret)
> +				return ret;
> +		}
> +	}

I think this function would look less cluttered as two:

	if (vlan_filtering)
		return an8855_port_enable_vlan_filtering();

	return an8855_port_disable_vlan_filtering();

> +
> +	return 0;
> +}
> +
> +static int
> +an8855_port_mdb_add(struct dsa_switch *ds, int port,
> +		    const struct switchdev_obj_port_mdb *mdb,
> +		    struct dsa_db db)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	const u8 *addr = mdb->addr;
> +	u16 vid = mdb->vid;
> +	u8 port_mask = 0;
> +	u32 val;
> +	int ret;
> +
> +	/* Set the vid to the port vlan id if no vid is set */

The comment needs to not be wrong. "no vid is set" actually means this
is a VLAN-unaware entry (matches packets when the bridge is under
vlan_filtering=0, or when the port is standalone). This is why you set
it to AN8855_PORT_VID_DEFAULT, because

> +	if (!vid)
> +		vid = AN8855_PORT_VID_DEFAULT;
> +
> +	mutex_lock(&priv->reg_mutex);
> +
> +	an8855_fdb_write(priv, vid, 0, addr, false);
> +	if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) {
> +		ret = regmap_read(priv->regmap, AN8855_ATRD3, &val);
> +		if (ret)
> +			goto exit;
> +
> +		port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val);
> +	}
> +
> +	port_mask |= BIT(port);
> +	an8855_fdb_write(priv, vid, port_mask, addr, true);
> +	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
> +
> +exit:
> +	mutex_unlock(&priv->reg_mutex);
> +
> +	return ret;
> +}
> +
> +static int
> +an8855_port_mdb_del(struct dsa_switch *ds, int port,
> +		    const struct switchdev_obj_port_mdb *mdb,
> +		    struct dsa_db db)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	const u8 *addr = mdb->addr;
> +	u16 vid = mdb->vid;
> +	u8 port_mask = 0;
> +	u32 val;
> +	int ret;
> +
> +	/* Set the vid to the port vlan id if no vid is set */
> +	if (!vid)
> +		vid = AN8855_PORT_VID_DEFAULT;
> +
> +	mutex_lock(&priv->reg_mutex);
> +
> +	an8855_fdb_write(priv, vid, 0, addr, 0);
> +	if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) {
> +		ret = regmap_read(priv->regmap, AN8855_ATRD3, &val);
> +		if (ret)
> +			goto exit;
> +
> +		port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val);
> +	}
> +
> +	port_mask &= ~BIT(port);
> +	an8855_fdb_write(priv, vid, port_mask, addr, port_mask ? true : false);
> +	ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
> +
> +exit:
> +	mutex_unlock(&priv->reg_mutex);
> +
> +	return ret;
> +}
> +
> +static int
> +an8855_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	int length;
> +	u32 val;
> +
> +	/* When a new MTU is set, DSA always set the CPU port's MTU to the
> +	 * largest MTU of the slave ports. Because the switch only has a global
> +	 * RX length register, only allowing CPU port here is enough.
> +	 */
> +	if (!dsa_is_cpu_port(ds, port))
> +		return 0;
> +
> +	/* RX length also includes Ethernet header, MTK tag, and FCS length */
> +	length = new_mtu + ETH_HLEN + MTK_TAG_LEN + ETH_FCS_LEN;
> +	if (length <= 1522)
> +		val = AN8855_MAX_RX_PKT_1518_1522;
> +	else if (length <= 1536)
> +		val = AN8855_MAX_RX_PKT_1536;
> +	else if (length <= 1552)
> +		val = AN8855_MAX_RX_PKT_1552;
> +	else if (length <= 3072)
> +		val = AN8855_MAX_RX_JUMBO_3K;
> +	else if (length <= 4096)
> +		val = AN8855_MAX_RX_JUMBO_4K;
> +	else if (length <= 5120)
> +		val = AN8855_MAX_RX_JUMBO_5K;
> +	else if (length <= 6144)
> +		val = AN8855_MAX_RX_JUMBO_6K;
> +	else if (length <= 7168)
> +		val = AN8855_MAX_RX_JUMBO_7K;
> +	else if (length <= 8192)
> +		val = AN8855_MAX_RX_JUMBO_8K;
> +	else if (length <= 9216)
> +		val = AN8855_MAX_RX_JUMBO_9K;
> +	else if (length <= 12288)
> +		val = AN8855_MAX_RX_JUMBO_12K;
> +	else if (length <= 15360)
> +		val = AN8855_MAX_RX_JUMBO_15K;
> +	else
> +		val = AN8855_MAX_RX_JUMBO_16K;
> +
> +	/* Enable JUMBO packet */
> +	if (length > 1552)
> +		val |= AN8855_MAX_RX_PKT_JUMBO;
> +
> +	return regmap_update_bits(priv->regmap, AN8855_GMACCR,
> +				  AN8855_MAX_RX_JUMBO | AN8855_MAX_RX_PKT_LEN,
> +				  val);
> +}
> +
> +static int
> +an8855_port_max_mtu(struct dsa_switch *ds, int port)
> +{
> +	return AN8855_MAX_MTU;
> +}
> +
> +static void
> +an8855_get_strings(struct dsa_switch *ds, int port, u32 stringset,
> +		   uint8_t *data)
> +{
> +	int i;
> +
> +	if (stringset != ETH_SS_STATS)
> +		return;
> +
> +	for (i = 0; i < ARRAY_SIZE(an8855_mib); i++)
> +		ethtool_puts(&data, an8855_mib[i].name);
> +}
> +
> +static void
> +an8855_read_port_stats(struct an8855_priv *priv, int port, u32 offset, u8 size,
> +		       uint64_t *data)
> +{
> +	u32 val, reg = AN8855_PORT_MIB_COUNTER(port) + offset;
> +
> +	regmap_read(priv->regmap, reg, &val);
> +	*data = val;
> +
> +	if (size == 2) {
> +		regmap_read(priv->regmap, reg + 4, &val);
> +		*data |= (u64)val << 32;
> +	}
> +}
> +
> +static void
> +an8855_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	const struct an8855_mib_desc *mib;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(an8855_mib); i++) {
> +		mib = &an8855_mib[i];
> +
> +		an8855_read_port_stats(priv, port, mib->offset, mib->size,
> +				       data + i);
> +	}
> +}
> +
> +static int
> +an8855_get_sset_count(struct dsa_switch *ds, int port, int sset)
> +{
> +	if (sset != ETH_SS_STATS)
> +		return 0;
> +
> +	return ARRAY_SIZE(an8855_mib);
> +}
> +
> +static int an8855_port_mirror_add(struct dsa_switch *ds, int port,
> +				  struct dsa_mall_mirror_tc_entry *mirror,
> +				  bool ingress,
> +				  struct netlink_ext_ack *extack)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	int monitor_port;
> +	u32 val;
> +	int ret;
> +
> +	/* Check for existent entry */
> +	if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
> +		return -EEXIST;

Please set extack with an informational message, here and everywhere
else where it is available.

> +
> +	ret = regmap_read(priv->regmap, AN8855_MIR, &val);
> +	if (ret)
> +		return ret;
> +
> +	/* AN8855 supports 4 monitor port, but only use first group */
> +	monitor_port = FIELD_GET(AN8855_MIRROR_PORT, val);
> +	if (val & AN8855_MIRROR_EN && monitor_port != mirror->to_local_port)
> +		return -EEXIST;
> +
> +	val = AN8855_MIRROR_EN;
> +	val |= FIELD_PREP(AN8855_MIRROR_PORT, mirror->to_local_port);
> +	ret = regmap_update_bits(priv->regmap, AN8855_MIR,
> +				 AN8855_MIRROR_EN | AN8855_MIRROR_PORT,
> +				 val);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_set_bits(priv->regmap, AN8855_PCR_P(port),
> +			      ingress ? AN8855_PORT_RX_MIR : AN8855_PORT_TX_MIR);
> +	if (ret)
> +		return ret;
> +
> +	if (ingress)
> +		priv->mirror_rx |= BIT(port);
> +	else
> +		priv->mirror_tx |= BIT(port);
> +
> +	return 0;
> +}
> +
> +static void an8855_port_mirror_del(struct dsa_switch *ds, int port,
> +				   struct dsa_mall_mirror_tc_entry *mirror)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +
> +	if (mirror->ingress)
> +		priv->mirror_rx &= ~BIT(port);
> +	else
> +		priv->mirror_tx &= ~BIT(port);
> +
> +	regmap_clear_bits(priv->regmap, AN8855_PCR_P(port),
> +			  mirror->ingress ? AN8855_PORT_RX_MIR :
> +					    AN8855_PORT_TX_MIR);
> +
> +	if (!priv->mirror_rx && !priv->mirror_tx)
> +		regmap_clear_bits(priv->regmap, AN8855_MIR, AN8855_MIRROR_EN);
> +}
> +
> +static int an8855_port_set_status(struct an8855_priv *priv, int port,
> +				  bool enable)
> +{
> +	if (enable)
> +		return regmap_set_bits(priv->regmap, AN8855_PMCR_P(port),
> +				       AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
> +	else
> +		return regmap_clear_bits(priv->regmap, AN8855_PMCR_P(port),
> +					 AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
> +}
> +
> +static int an8855_port_enable(struct dsa_switch *ds, int port,
> +			      struct phy_device *phy)
> +{
> +	return an8855_port_set_status(ds->priv, port, true);
> +}
> +
> +static void an8855_port_disable(struct dsa_switch *ds, int port)
> +{
> +	an8855_port_set_status(ds->priv, port, false);
> +}

I'm tempted to suggest to just keep the implementations separate rather
than centralized in a single an8855_port_set_status() with no common code.
Then, the remaining an8855_port_set_status() call could be replaced with
an8855_port_enable(..., phy=NULL), since this driver doesn't use the last
argument anyway.

> +
> +static u32 en8855_get_phy_flags(struct dsa_switch *ds, int port)

Odd that this function name starts with en8855 when the rest of the
driver starts with an8855. I've seen your conversation with Andrew and I
understand why, but this is still unconventional.

Could this just go to the PHY driver completely?

> +{
> +	struct an8855_priv *priv = ds->priv;
> +
> +	/* PHY doesn't need calibration */
> +	if (!priv->phy_require_calib)
> +		return 0;
> +
> +	/* Use AN8855_PHY_FLAGS_EN_CALIBRATION to signal
> +	 * calibration needed.
> +	 */
> +	return AN8855_PHY_FLAGS_EN_CALIBRATION;
> +}
> +
> +static int
> +an8855_setup_pvid_vlan(struct an8855_priv *priv)
> +{
> +	u32 val;
> +	int ret;
> +
> +	/* Validate the entry with independent learning, keep the original
> +	 * ingress tag attribute.
> +	 */
> +	val = AN8855_VA0_IVL_MAC | AN8855_VA0_EG_CON |
> +	      FIELD_PREP(AN8855_VA0_FID, AN8855_FID_BRIDGED) |
> +	      AN8855_VA0_PORT | AN8855_VA0_VLAN_VALID;
> +	ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
> +	if (ret)
> +		return ret;
> +
> +	return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID,
> +			       AN8855_PORT_VID_DEFAULT);
> +}
> +
> +static int an8855_setup(struct dsa_switch *ds)
> +{
> +	struct an8855_priv *priv = ds->priv;
> +	struct dsa_port *dp;
> +	int ret;
> +
> +	/* Enable and reset MIB counters */
> +	ret = an8855_mib_init(priv);
> +	if (ret)
> +		return ret;
> +
> +	dsa_switch_for_each_user_port(dp, ds) {
> +		/* Disable MAC by default on all user ports */
> +		ret = an8855_port_set_status(priv, dp->index, false);
> +		if (ret)
> +			return ret;
> +
> +		/* Individual user ports get connected to CPU port only */
> +		ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(dp->index),
> +				   FIELD_PREP(AN8855_PORTMATRIX, BIT(AN8855_CPU_PORT)));
> +		if (ret)
> +			return ret;
> +
> +		/* Disable Broadcast Forward on user ports */
> +		ret = regmap_clear_bits(priv->regmap, AN8855_BCF, BIT(dp->index));
> +		if (ret)
> +			return ret;
> +
> +		/* Disable Unknown Unicast Forward on user ports */
> +		ret = regmap_clear_bits(priv->regmap, AN8855_UNUF, BIT(dp->index));
> +		if (ret)
> +			return ret;
> +
> +		/* Disable Unknown Multicast Forward on user ports */
> +		ret = regmap_clear_bits(priv->regmap, AN8855_UNMF, BIT(dp->index));
> +		if (ret)
> +			return ret;
> +
> +		ret = regmap_clear_bits(priv->regmap, AN8855_UNIPMF, BIT(dp->index));
> +		if (ret)
> +			return ret;
> +
> +		/* Set default PVID to on all user ports */
> +		ret = an8855_port_set_pid(priv, dp->index, AN8855_PORT_VID_DEFAULT);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	/* Enable Airoha header mode on the cpu port */
> +	ret = regmap_write(priv->regmap, AN8855_PVC_P(AN8855_CPU_PORT),
> +			   AN8855_PORT_SPEC_REPLACE_MODE | AN8855_PORT_SPEC_TAG);
> +	if (ret)
> +		return ret;
> +
> +	/* Unknown multicast frame forwarding to the cpu port */
> +	ret = regmap_write(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT));
> +	if (ret)
> +		return ret;
> +
> +	/* Set CPU port number */
> +	ret = regmap_update_bits(priv->regmap, AN8855_MFC,
> +				 AN8855_CPU_EN | AN8855_CPU_PORT_IDX,
> +				 AN8855_CPU_EN |
> +				 FIELD_PREP(AN8855_CPU_PORT_IDX, AN8855_CPU_PORT));
> +	if (ret)
> +		return ret;
> +
> +	/* CPU port gets connected to all user ports of
> +	 * the switch.
> +	 */
> +	ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(AN8855_CPU_PORT),
> +			   FIELD_PREP(AN8855_PORTMATRIX, dsa_user_ports(ds)));
> +	if (ret)
> +		return ret;
> +
> +	/* CPU port is set to fallback mode to let untagged
> +	 * frames pass through.
> +	 */
> +	ret = regmap_update_bits(priv->regmap, AN8855_PCR_P(AN8855_CPU_PORT),
> +				 AN8855_PORT_VLAN,
> +				 FIELD_PREP(AN8855_PORT_VLAN, AN8855_PORT_FALLBACK_MODE));
> +	if (ret)
> +		return ret;
> +
> +	/* Enable Broadcast Forward on CPU port */
> +	ret = regmap_set_bits(priv->regmap, AN8855_BCF, BIT(AN8855_CPU_PORT));
> +	if (ret)
> +		return ret;
> +
> +	/* Enable Unknown Unicast Forward on CPU port */
> +	ret = regmap_set_bits(priv->regmap, AN8855_UNUF, BIT(AN8855_CPU_PORT));
> +	if (ret)
> +		return ret;
> +
> +	/* Enable Unknown Multicast Forward on CPU port */
> +	ret = regmap_set_bits(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_set_bits(priv->regmap, AN8855_UNIPMF, BIT(AN8855_CPU_PORT));
> +	if (ret)
> +		return ret;
> +
> +	/* Setup Trap special frame to CPU rules */
> +	ret = an8855_trap_special_frames(priv);
> +	if (ret)
> +		return ret;
> +
> +	dsa_switch_for_each_port(dp, ds) {
> +		/* Disable Learning on all ports.
> +		 * Learning on CPU is disabled for fdb isolation and handled by
> +		 * assisted_learning_on_cpu_port.
> +		 */
> +		ret = regmap_set_bits(priv->regmap, AN8855_PSC_P(dp->index),
> +				      AN8855_SA_DIS);
> +		if (ret)
> +			return ret;
> +
> +		/* Enable consistent egress tag (for VLAN unware VLAN-passtrough) */

Throughout the patch set:
s/passtrough/passthrough/

> +		ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(dp->index),
> +					 AN8855_PVC_EG_TAG,
> +					 FIELD_PREP(AN8855_PVC_EG_TAG, AN8855_VLAN_EG_CONSISTENT));
> +		if (ret)
> +			return ret;
> +	}
> +
> +	/* Setup VLAN for Default PVID */
> +	ret = an8855_setup_pvid_vlan(priv);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_clear_bits(priv->regmap, AN8855_CKGCR,
> +				AN8855_CKG_LNKDN_GLB_STOP | AN8855_CKG_LNKDN_PORT_STOP);
> +	if (ret)
> +		return ret;
> +
> +	/* Release global PHY power down */
> +	ret = regmap_write(priv->regmap, AN8855_RG_GPHY_AFE_PWD, 0x0);
> +	if (ret)
> +		return ret;

>From the comment about PHY power handling, it sounds like this is
problematic to do in the switch driver now, since that runs in parallel
with the PHY drivers' probe sequence. Sounds like it should be moved to
the central MFD driver, at a stage where there is no parallel child
driver execution.

> +
> +	ds->configure_vlan_while_not_filtering = true;

Unnecessary, this is the default value, please remove.

> +
> +	/* Flush the FDB table */
> +	ret = an8855_fdb_cmd(priv, AN8855_FDB_FLUSH, NULL);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* Set min a max ageing value supported */
> +	ds->ageing_time_min = AN8855_L2_AGING_MS_CONSTANT;
> +	ds->ageing_time_max = FIELD_MAX(AN8855_AGE_CNT) *
> +			      FIELD_MAX(AN8855_AGE_UNIT) *
> +			      AN8855_L2_AGING_MS_CONSTANT;
> +
> +	/* Enable assisted learning for fdb isolation */
> +	ds->assisted_learning_on_cpu_port = true;

What FDB isolation? :)

> +
> +	return 0;
> +}
> +
> +static int an8855_switch_probe(struct platform_device *pdev)
> +{
> +	struct an8855_priv *priv;
> +	u32 val;
> +	int ret;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->dev = &pdev->dev;
> +	priv->phy_require_calib = of_property_read_bool(priv->dev->of_node,
> +							"airoha,ext-surge");

Can this be moved to the DT bindings of individual PHYs instead?
The switch is just a useless messenger here.

> +
> +	priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
> +						   GPIOD_OUT_LOW);
> +	if (IS_ERR(priv->reset_gpio))
> +		return PTR_ERR(priv->reset_gpio);
> +
> +	/* Get regmap from MFD */
> +	priv->regmap = dev_get_regmap(priv->dev->parent, NULL);
> +
> +	if (priv->reset_gpio) {
> +		usleep_range(100000, 150000);
> +		gpiod_set_value_cansleep(priv->reset_gpio, 0);
> +		usleep_range(100000, 150000);
> +		gpiod_set_value_cansleep(priv->reset_gpio, 1);
> +
> +		/* Poll HWTRAP reg to wait for Switch to fully Init */
> +		ret = regmap_read_poll_timeout(priv->regmap, AN8855_HWTRAP, val,
> +					       val, 20, 200000);
> +		if (ret)
> +			return ret;
> +	}

As mentioned in the dt-bindings comment: this sounds like the type of
thing which should only run from the context of the top-level MFD
driver, in a very controlled manner (child drivers have not started).

> +
> +	ret = an8855_read_switch_id(priv);
> +	if (ret)
> +		return ret;
> +
> +	priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
> +	if (!priv->ds)
> +		return -ENOMEM;
> +
> +	priv->ds->dev = priv->dev;
> +	priv->ds->num_ports = AN8855_NUM_PORTS;
> +	priv->ds->priv = priv;
> +	priv->ds->ops = &an8855_switch_ops;
> +	devm_mutex_init(priv->dev, &priv->reg_mutex);
> +	priv->ds->phylink_mac_ops = &an8855_phylink_mac_ops;
> +
> +	priv->pcs.ops = &an8855_pcs_ops;
> +	priv->pcs.neg_mode = true;
> +	priv->pcs.poll = true;
> +
> +	dev_set_drvdata(priv->dev, priv);
> +
> +	return dsa_register_switch(priv->ds);
> +}
> +
> +static void an8855_switch_remove(struct platform_device *pdev)
> +{
> +	struct an8855_priv *priv = dev_get_drvdata(&pdev->dev);
> +
> +	if (!priv)
> +		return;
> +
> +	dsa_unregister_switch(priv->ds);
> +}
> +
> +static const struct of_device_id an8855_switch_of_match[] = {
> +	{ .compatible = "airoha,an8855-switch" },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, an8855_switch_of_match);
> +
> +static struct platform_driver an8855_switch_driver = {
> +	.probe = an8855_switch_probe,
> +	.remove = an8855_switch_remove,

dsa_switch_shutdown() is non-optional - see commit 0650bf52b31f ("net:
dsa: be compatible with masters which unregister on shutdown") for more
details. As a discrete DSA switch, don't get to choose which conduit
interface this is paired with.

> +	.driver = {
> +		.name = "an8855-switch",
> +		.of_match_table = an8855_switch_of_match,
> +	},
> +};
> +module_platform_driver(an8855_switch_driver);
> +struct an8855_priv {
> +	struct device *dev;

Nitpick: can retrieve the device as priv->ds->dev already.

> +	struct dsa_switch *ds;
> +	struct regmap *regmap;
> +	struct gpio_desc *reset_gpio;
> +	/* Protect ATU or VLAN table access */
> +	struct mutex reg_mutex;
> +
> +	struct phylink_pcs pcs;
> +
> +	u8 mirror_rx;
> +	u8 mirror_tx;
> +	u8 port_isolated_map;
> +
> +	bool phy_require_calib;
> +};
> +
> +#endif /* __AN8855_H */
> -- 
> 2.45.2
> 

This doesn't look bad IMO (sure, still needs work), we should focus on
the selftests and make sure they pass.


From robh at kernel.org  Tue Dec 10 14:15:08 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 10 Dec 2024 16:15:08 -0600
Subject: [PATCH v6 01/19] dt-bindings: display: imx: Add i.MX8qxp Display
 Controller processing units
In-Reply-To: <20241209033923.3009629-2-victor.liu@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
 <20241209033923.3009629-2-victor.liu@nxp.com>
Message-ID: <20241210221508.GA550635-robh@kernel.org>

On Mon, Dec 09, 2024 at 11:39:05AM +0800, Liu Ying wrote:
> Freescale i.MX8qxp Display Controller is implemented as construction set of
> building blocks with unified concept and standardized interfaces.  Document
> all existing processing units.
> 
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v6:
> * No change.
> 
> v5:
> * Document aliases for processing units which have multiple instances in
>   the Display Controller.  Drop Rob's previous R-b tag. (Maxime)
> 
> v4:
> * Collect Rob's R-b tag.
> 
> v3:
> * Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
>   fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
>   into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
> * Document all processing units. (Rob)
> 
> v2:
> * Drop fsl,dc-*-id DT properties. (Krzysztof)
> * Add port property to fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
> * Fix register range sizes in examples.
> 
>  .../display/imx/fsl,imx8qxp-dc-blitblend.yaml |  46 ++++++
>  .../display/imx/fsl,imx8qxp-dc-clut.yaml      |  49 ++++++
>  .../imx/fsl,imx8qxp-dc-constframe.yaml        |  49 ++++++
>  .../display/imx/fsl,imx8qxp-dc-dither.yaml    |  49 ++++++
>  .../display/imx/fsl,imx8qxp-dc-extdst.yaml    |  77 +++++++++
>  .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 ++++++++++++++++++
>  .../display/imx/fsl,imx8qxp-dc-filter.yaml    |  47 ++++++
>  .../display/imx/fsl,imx8qxp-dc-framegen.yaml  |  68 ++++++++
>  .../display/imx/fsl,imx8qxp-dc-gammacor.yaml  |  38 +++++
>  .../imx/fsl,imx8qxp-dc-layerblend.yaml        |  45 ++++++
>  .../display/imx/fsl,imx8qxp-dc-matrix.yaml    |  48 ++++++
>  .../display/imx/fsl,imx8qxp-dc-rop.yaml       |  48 ++++++
>  .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++++
>  .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  89 +++++++++++
>  .../display/imx/fsl,imx8qxp-dc-signature.yaml |  58 +++++++
>  .../display/imx/fsl,imx8qxp-dc-store.yaml     | 100 ++++++++++++
>  .../display/imx/fsl,imx8qxp-dc-tcon.yaml      |  50 ++++++
>  17 files changed, 1042 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
> new file mode 100644
> index 000000000000..7f800e72c3f3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
> @@ -0,0 +1,46 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blitblend.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX8qxp Display Controller Blit Blend Unit
> +
> +description: |
> +  Combines two input frames to a single output frame, all frames having the
> +  same dimension.
> +
> +  Each Blit Blend Unit device should have an alias in the aliases node, in the
> +  form of dc<x>-blitblend<y>, where <x> is an integer specifying the Display
> +  Controller instance and <y> is an integer specifying the Blit Blend Unit
> +  device instance.

That's really an abuse of aliases. If you need to describe connections 
between components, use the graph binding like everyone else does for 
display path components.

Rob


From olteanv at gmail.com  Tue Dec 10 14:16:02 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Wed, 11 Dec 2024 00:16:02 +0200
Subject: [net-next PATCH v11 3/9] dt-bindings: net: dsa: Document support
 for Airoha AN8855 DSA Switch
In-Reply-To: <6758ab9b.7b0a0220.3347af.914a@mx.google.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-4-ansuelsmth@gmail.com>
 <20241210204855.7pgvh74irualyxbn@skbuf>
 <6758ab9b.7b0a0220.3347af.914a@mx.google.com>
Message-ID: <20241210221602.ohyzlic2x3pflmrg@skbuf>

On Tue, Dec 10, 2024 at 09:59:04PM +0100, Christian Marangi wrote:
> > > +  airoha,ext-surge:
> > > +    $ref: /schemas/types.yaml#/definitions/flag
> > > +    description:
> > > +      Calibrate the internal PHY with the calibration values stored in EFUSE
> > > +      for the r50Ohm values.
> > 
> > Doesn't seem that this pertains to the switch.
> 
> Do you think this should be placed in each PHY node?

Logically speaking, that's where it belongs.

> I wanted to prevent having to define a schema also for PHY if possible
> given how integrated these are. (originally it was defined in DT node
> to follow how it was done in Airoha SDK)

Does compatibility with the Airoha SDK dt-bindings matter in any way?


From Frank.li at nxp.com  Tue Dec 10 14:16:24 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 10 Dec 2024 17:16:24 -0500
Subject: [PATCH v8 0/7] PCI: dwc: opitimaze RC Host/EP pci_fixup_addr()
In-Reply-To: <20241124143839.hg2yj462h22rftqa@thinkpad>
References: <20241119-pci_fixup_addr-v8-0-c4bfa5193288@nxp.com>
 <20241124143839.hg2yj462h22rftqa@thinkpad>
Message-ID: <Z1i9uEGvsVACsF2r@lizhi-Precision-Tower-5810>

On Sun, Nov 24, 2024 at 08:08:39PM +0530, Manivannan Sadhasivam wrote:
> On Tue, Nov 19, 2024 at 02:44:18PM -0500, Frank Li wrote:
> > == RC side:
> >
> >             ???????????                    ??????????????
> >  ???????    ?         ? IA: 0x8ff8_0000    ?            ?
> >  ? CPU ??????   ?????????????????????????  ? PCI        ?
> >  ???????    ?   ?     ? IA: 0x8ff0_0000 ?  ?            ?
> >   CPU Addr  ?   ?  ??????????????????   ?  ? Controller ?
> > 0x7ff8_0000??????  ?  ?             ?   ?  ?            ?
> >             ?      ?  ?             ?   ?  ?            ?   PCI Addr
> > 0x7ff0_0000?????????  ?             ?   ???? IOSpace   ???????????????
> >             ?         ?             ?      ?            ?    0
> > 0x7000_0000??????????????????????   ?      ?            ?
> >             ???????????         ?   ???????? CfgSpace  ???????????????
> >              BUS Fabric         ?          ?            ?    0
> >                                 ?          ?            ?
> >                                 ???????????? MemSpace  ???????????????
> >                         IA: 0x8000_0000    ?            ?  0x8000_0000
> >                                            ??????????????
> >
> > Current dwc implimemnt, pci_fixup_addr() call back is needed when bus
> > fabric convert cpu address before send to PCIe controller.
> >
> >     bus at 5f000000 {
> >             compatible = "simple-bus";
> >             #address-cells = <1>;
> >             #size-cells = <1>;
> >             ranges = <0x80000000 0x0 0x70000000 0x10000000>;
> >
> >             pcie at 5f010000 {
> >                     compatible = "fsl,imx8q-pcie";
> >                     reg = <0x5f010000 0x10000>, <0x8ff00000 0x80000>;
> >                     reg-names = "dbi", "config";
> >                     #address-cells = <3>;
> >                     #size-cells = <2>;
> >                     device_type = "pci";
> >                     bus-range = <0x00 0xff>;
> >                     ranges = <0x81000000 0 0x00000000 0x8ff80000 0 0x00010000>,
> >                              <0x82000000 0 0x80000000 0x80000000 0 0x0ff00000>;
> >             ...
> >             };
> >     };
> >
> > Device tree already can descript all address translate. Some hardware
> > driver implement fixup function by mask some bits of cpu address. Last
> > pci-imx6.c are little bit better by fetch memory resource's offset to do
> > fixup.
> >
> > static u64 imx_pcie_cpu_addr_fixup(struct dw_pcie *pcie, u64 cpu_addr)
> > {
> > 	...
> > 	entry = resource_list_first_type(&pp->bridge->windows, IORESOURCE_MEM);
> > 	return cpu_addr - entry->offset;
> > }
> >
> > But it is not good by using IORESOURCE_MEM to fix up io/cfg address map
> > although address translate is the same as IORESOURCE_MEM.
> >
> > This patches to fetch untranslate range information for PCIe controller
> > (pcie at 5f010000: ranges). So current config ATU without cpu_fixup_addr().
> >
> > == EP side:
> >
> >                    Endpoint
> >   ?????????????????????????????????????????????????
> >   ?                             pcie-ep at 5f010000  ?
> >   ?                             ???????????????????
> >   ?                             ?   Endpoint     ??
> >   ?                             ?   PCIe         ??
> >   ?                             ?   Controller   ??
> >   ?           bus at 5f000000      ?                ??
> >   ?           ????????????      ?                ??
> >   ?           ?          ? Outbound Transfer     ??
> >   ????????    ?  Bus     ???????? ATU  ??????????????????
> >   ??     ?    ?  Fabric  ?Bus   ?                ??PCI Addr
> >   ?? CPU ??????          ?Addr  ?                ??0xA000_0000
> >   ??     ?CPU ?          ?0x8000_0000            ??
> >   ????????Addr????????????      ?                ??
> >   ?       0x7000_0000           ???????????????????
> >   ?????????????????????????????????????????????????
> >
> > bus at 5f000000 {
> >         compatible = "simple-bus";
> >         ranges = <0x80000000 0x0 0x70000000 0x10000000>;
> >
> >         pcie-ep at 5f010000 {
> >                 reg = <0x5f010000 0x00010000>,
> >                       <0x80000000 0x10000000>;
> >                 reg-names = "dbi", "addr_space";
> >                 ...                ^^^^
> >         };
> >         ...
> > };
> >
> > Add `bus_addr_base` to configure the outbound window address for CPU write.
> > The BUS fabric generally passes the same address to the PCIe EP controller,
> > but some BUS fabrics convert the address before sending it to the PCIe EP
> > controller.
> >
> > Above diagram, CPU write data to outbound windows address 0x7000_0000,
> > Bus fabric convert it to 0x8000_0000. ATU should use BUS address
> > 0x8000_0000 as input address and convert to PCI address 0xA000_0000.
> >
> > Previously, `cpu_addr_fixup()` was used to handle address conversion. Now,
> > the device tree provides this information.
> >
> > The both pave the road to eliminate ugle cpu_fixup_addr() callback function.
> >
>
> Series looks good to me. Thanks a lot for your persistence! But it missed 6.13
> cycle. So let's get it merged early once 6.13-rc1 is out.

Krzysztof Wilczy?ski:

	Could you please pick these? all reviewed by mani? It pave the
road to clean up ugle cpu_fixup_addr().

Frank

>
> - Mani
>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > Changes in v8:
> > - Add mani's review tages
> > - use rename use_dt_ranges to use_parent_dt_ranges
> > - Add dev_warn_once to reminder to fix their dt file and remove
> > cpu_fixup_addr() callback.
> > - rename dw_pcie_get_untranslate_addr() to dw_pcie_get_parent_addr()
> > - Link to v7: https://lore.kernel.org/r/20241029-pci_fixup_addr-v7-0-8310dc24fb7c at nxp.com
> >
> > Changes in v7:
> > - fix
> > | Reported-by: kernel test robot <lkp at intel.com>
> > | Closes: https://lore.kernel.org/oe-kbuild-all/202410291546.kvgEWJv7-lkp at intel.com/
> > - Link to v6: https://lore.kernel.org/r/20241028-pci_fixup_addr-v6-0-ebebcd8fd4ff at nxp.com
> >
> > Changes in v6:
> > - merge RC and EP to one thread!
> > - Link to v5: https://lore.kernel.org/r/20241015-pci_fixup_addr-v5-0-ced556c85270 at nxp.com
> >
> > Changes in v5:
> > - update address order in diagram patches.
> > - remove confused 0x5f00_0000 range
> > - update patch1's commit message.
> > - Link to v4: https://lore.kernel.org/r/20241008-pci_fixup_addr-v4-0-25e5200657bc at nxp.com
> >
> > Changes in v4:
> > - Improve commit message by add driver source code path.
> > - Link to v3: https://lore.kernel.org/r/20240930-pci_fixup_addr-v3-0-80ee70352fc7 at nxp.com
> >
> > Changes in v3:
> > - see each patch
> > - Link to v2: https://lore.kernel.org/r/20240926-pci_fixup_addr-v2-0-e4524541edf4 at nxp.com
> >
> > Changes in v2:
> > - see each patch
> > - Link to v1: https://lore.kernel.org/r/20240924-pci_fixup_addr-v1-0-57d14a91ec4f at nxp.com
> >
> > ---
> > Frank Li (7):
> >       of: address: Add parent_bus_addr to struct of_pci_range
> >       PCI: dwc: Use devicetree 'ranges' property to get rid of cpu_addr_fixup() callback
> >       PCI: dwc: ep: Add bus_addr_base for outbound window
> >       PCI: imx6: Remove cpu_addr_fixup()
> >       dt-bindings: PCI: fsl,imx6q-pcie-ep: Add compatible string fsl,imx8q-pcie-ep
> >       PCI: imx6: Pass correct sub mode when calling phy_set_mode_ext()
> >       PCI: imx6: Add i.MX8Q PCIe Endpoint (EP) support
> >
> >  .../devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml | 38 ++++++++++++++-
> >  drivers/of/address.c                               |  2 +
> >  drivers/pci/controller/dwc/pci-imx6.c              | 46 +++++++++--------
> >  drivers/pci/controller/dwc/pcie-designware-ep.c    | 18 ++++++-
> >  drivers/pci/controller/dwc/pcie-designware-host.c  | 57 +++++++++++++++++++++-
> >  drivers/pci/controller/dwc/pcie-designware.c       |  9 ++++
> >  drivers/pci/controller/dwc/pcie-designware.h       |  8 +++
> >  include/linux/of_address.h                         |  1 +
> >  8 files changed, 155 insertions(+), 24 deletions(-)
> > ---
> > base-commit: 9852d85ec9d492ebef56dc5f229416c925758edc
> > change-id: 20240924-pci_fixup_addr-a8568f9bbb34
> >
> > Best regards,
> > ---
> > Frank Li <Frank.Li at nxp.com>
> >
>
> --
> ????????? ????????


From ansuelsmth at gmail.com  Tue Dec 10 14:26:17 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Tue, 10 Dec 2024 23:26:17 +0100
Subject: [net-next PATCH v11 3/9] dt-bindings: net: dsa: Document support
 for Airoha AN8855 DSA Switch
In-Reply-To: <20241210221602.ohyzlic2x3pflmrg@skbuf>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-4-ansuelsmth@gmail.com>
 <20241210204855.7pgvh74irualyxbn@skbuf>
 <6758ab9b.7b0a0220.3347af.914a@mx.google.com>
 <20241210221602.ohyzlic2x3pflmrg@skbuf>
Message-ID: <6758c00c.050a0220.1dd14c.63cd@mx.google.com>

On Wed, Dec 11, 2024 at 12:16:02AM +0200, Vladimir Oltean wrote:
> On Tue, Dec 10, 2024 at 09:59:04PM +0100, Christian Marangi wrote:
> > > > +  airoha,ext-surge:
> > > > +    $ref: /schemas/types.yaml#/definitions/flag
> > > > +    description:
> > > > +      Calibrate the internal PHY with the calibration values stored in EFUSE
> > > > +      for the r50Ohm values.
> > > 
> > > Doesn't seem that this pertains to the switch.
> > 
> > Do you think this should be placed in each PHY node?
> 
> Logically speaking, that's where it belongs.
> 
> > I wanted to prevent having to define a schema also for PHY if possible
> > given how integrated these are. (originally it was defined in DT node
> > to follow how it was done in Airoha SDK)
> 
> Does compatibility with the Airoha SDK dt-bindings matter in any way?

No it doesn't, the requirement for nvmem already deviates a lot so changes
are needed anyway.

-- 
	Ansuel


From ansuelsmth at gmail.com  Tue Dec 10 14:32:17 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Tue, 10 Dec 2024 23:32:17 +0100
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <20241210211529.osgzd54flq646bcr@skbuf>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241210211529.osgzd54flq646bcr@skbuf>
Message-ID: <6758c174.050a0220.52a35.06bc@mx.google.com>

On Tue, Dec 10, 2024 at 11:15:29PM +0200, Vladimir Oltean wrote:
> On Mon, Dec 09, 2024 at 02:44:22PM +0100, Christian Marangi wrote:
> > +int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
> > +			u8 page) __must_hold(&priv->bus->mdio_lock)
> > +{
> > +	struct mii_bus *bus = priv->bus;
> > +	int ret;
> > +
> > +	ret = __mdiobus_write(bus, phy_id, AN8855_PHY_SELECT_PAGE, page);
> > +	if (ret < 0)
> > +		dev_err_ratelimited(&bus->dev,
> > +				    "failed to set an8855 mii page\n");
> > +
> > +	/* Cache current page if next mii read/write is for switch */
> > +	priv->current_page = page;
> > +	return ret < 0 ? ret : 0;
> > +}
> > +EXPORT_SYMBOL_GPL(an8855_mii_set_page);
> 
> You could keep the implementation more contained, and you could avoid
> exporting an8855_mii_set_page() and an8855_mfd_priv to the MDIO
> passthrough driver, if you implement a virtual regmap and give it to the
> MDIO passthrough child MFD device.
> 
> If this bus supports only clause 22 accesses (and it looks like it does),
> you could expose a 16-bit regmap with a linear address space of 32 MDIO
> addresses x 65536 registers. The bus->read() of the MDIO bus passthrough
> just performs regmap_read(), and bus->write() just performs regmap_write().
> The MFD driver decodes the regmap address into a PHY address and a regnum,
> and performs the page switching locally, if needed.

Doesn't regmap add lots of overhead tho? Maybe I should really change
the switch regmap to apply a save/restore logic?

With an implementation like that current_page is not needed anymore.
And I feel additional read/write are ok for switch OP.

On mdio I can use the parent-mdio-bus property to get the bus directly
without using MFD priv.

What do you think?

-- 
	Ansuel


From naoki at radxa.com  Tue Dec 10 14:41:24 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 11 Dec 2024 07:41:24 +0900
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add USB-C support to ROCK 5B
In-Reply-To: <6A24DF29AE2F3CDC+70602cc7-2c03-470d-955f-06b2db116e20@radxa.com>
References: <20241210163615.120594-1-sebastian.reichel@collabora.com>
 <6A24DF29AE2F3CDC+70602cc7-2c03-470d-955f-06b2db116e20@radxa.com>
Message-ID: <8ABA1DC12C12F3A8+89687fc8-25ed-4217-9df9-696c907b49b3@radxa.com>

Hi,

two correction,

On 12/11/24 07:10, FUKAUMI Naoki wrote:
> Hi Sebastian,
> 
> Thank you very much for your work!
> 
> $ cat /sys/class/power_supply/tcpm-source-psy-4-0022/ 
> {current_max,current_now,online,type,usb_type,voltage_max,voltage_min,voltage_now}
> 1500000
> 1500000
> 1
> USB
> C [PD] PD_PPS
> 20000000
> 20000000
> 20000000
> 
> $ cat /sys/class/power_supply/tcpm-source-psy-4-0022/ 
> {current_max,current_now,online,type,usb_type,voltage_max,voltage_min,voltage_now}
> 5000000
> 5000000
> 1
> USB
> C PD [PD_PPS]
> 20000000
> 20000000
> 20000000
> 
> $ ls /sys/class/udc/
> fc000000.usb
> 
> I can configure it as CDC-NCM and host detects it.
> But I could not use it as a HOST port. How to use it?
> 
> some minor nitpick is below:
> 
> On 12/11/24 01:36, Sebastian Reichel wrote:
>> Add hardware description for the USB-C port in the Radxa Rock 5 Model B.
>> This describes the OHCI, EHCI and XHCI USB parts, but not yet the
>> DisplayPort AltMode (bindings are not yet upstream).
>>
>> The fusb302 node is marked with status "fail", since the board is usually
>> powered through the USB-C port. Handling of errors can result in hard
>> resets, which removed the bus power for some time resulting in a board
>> reset.
>>
>> The main problem is that devices are supposed to interact with the
>> power-supply within 5 seconds after the plug event according to the
>> USB PD specification. This is more or less impossible to achieve when
>> the kernel is the first software communicating with the power-supply.
>>
>> Recent U-Boot (v2025.01) will start doing USB-PD communication, which
>> solves this issue. Upstream U-Boot doing USB-PD communication will also
>> set the fusb302 node status to "okay". That way booting a kernel with
>> the updated DT on an old U-Boot avoids a reset loop.
>>
>> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
>> ---
>> ? .../boot/dts/rockchip/rk3588-rock-5b.dts????? | 121 ++++++++++++++++++
>> ? 1 file changed, 121 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/ 
>> arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> index d597112f1d5b..cb5990df6ccb 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> @@ -5,6 +5,7 @@
>> ? #include <dt-bindings/gpio/gpio.h>
>> ? #include <dt-bindings/leds/common.h>
>> ? #include <dt-bindings/soc/rockchip,vop2.h>
>> +#include <dt-bindings/usb/pd.h>
>> ? #include "rk3588.dtsi"
>> ? / {
>> @@ -84,6 +85,15 @@ rfkill-bt {
>> ????????? shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>> ????? };
>> +??? vcc12v_dcin: regulator-vcc12v-dcin {
>> +??????? compatible = "regulator-fixed";
>> +??????? regulator-name = "vcc12v_dcin";
> 
> typec_vin by schematic.
> 
>> +??????? regulator-always-on;
>> +??????? regulator-boot-on;
>> +??????? regulator-min-microvolt = <12000000>;
>> +??????? regulator-max-microvolt = <12000000>;
>> +??? };
>> +
>> ????? vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 {
>> ????????? compatible = "regulator-fixed";
>> ????????? enable-active-high;
>> @@ -142,6 +152,7 @@ vcc5v0_sys: regulator-vcc5v0-sys {
>> ????????? regulator-boot-on;
>> ????????? regulator-min-microvolt = <5000000>;
>> ????????? regulator-max-microvolt = <5000000>;
>> +??????? vin-supply = <&vcc12v_dcin>;
> 
> typec_vin.
> 
>> ????? };
>> ????? vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
>> @@ -264,6 +275,67 @@ regulator-state-mem {
>> ????? };
>> ? };
>> +&i2c4 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&i2c4m1_xfer>;
>> +??? status = "okay";
>> +
>> +??? usbc0: usb-typec at 22 {
> 
> Is "usbc0" label necessary?

please ignore, I noticed it's necessary for my work ;)

> 
>> +??????? compatible = "fcs,fusb302";
>> +??????? reg = <0x22>;
>> +??????? interrupt-parent = <&gpio3>;
>> +??????? interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&usbc0_int>;
> 
> cc_int_l by schematic.
> 
>> +??????? vbus-supply = <&vcc12v_dcin>;
> 
> typec_vin
> 
>> +??????? /*
>> +???????? * When the board is starting to send power-delivery messages
>> +???????? * too late (5 seconds according to the specification), the
>> +???????? * power-supply reacts with a hard-reset. That removes the
>> +???????? * power from VBUS for some time, which resets te whole board.
> 
> ... resets "the" whole board.
> 
>> +???????? */
>> +??????? status = "fail";
>> +
>> +??????? usb_con: connector {
> 
> Is "usb_con" label necessary?

it's necessary for my work, but I think "usbc0_con" is consistent with 
others.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

>> +??????????? compatible = "usb-c-connector";
>> +??????????? label = "USB-C";
>> +??????????? data-role = "dual";
>> +??????????? power-role = "sink";
>> +??????????? try-power-role = "sink";
>> +??????????? op-sink-microwatt = <1000000>;
>> +??????????? sink-pdos =
>> +??????????????? <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>,
>> +??????????????? <PDO_VAR(5000, 20000, 5000)>;
>> +
>> +??????????? ports {
>> +??????????????? #address-cells = <1>;
>> +??????????????? #size-cells = <0>;
>> +
>> +??????????????? port at 0 {
>> +??????????????????? reg = <0>;
>> +??????????????????? usbc0_role_sw: endpoint {
>> +??????????????????????? remote-endpoint = <&dwc3_0_role_switch>;
>> +??????????????????? };
>> +??????????????? };
>> +
>> +??????????????? port at 1 {
>> +??????????????????? reg = <1>;
>> +??????????????????? usbc0_orien_sw: endpoint {
>> +??????????????????????? remote-endpoint = 
>> <&usbdp_phy0_orientation_switch>;
>> +??????????????????? };
>> +??????????????? };
>> +
>> +??????????????? port at 2 {
>> +??????????????????? reg = <2>;
>> +??????????????????? dp_altmode_mux: endpoint {
>> +??????????????????????? remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
>> +??????????????????? };
>> +??????????????? };
>> +??????????? };
>> +??????? };
>> +??? };
>> +};
>> +
>> ? &i2c6 {
>> ????? status = "okay";
>> @@ -423,6 +495,10 @@ usb {
>> ????????? vcc5v0_host_en: vcc5v0-host-en {
>> ????????????? rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
>> ????????? };
>> +
>> +??????? usbc0_int: usbc0-int {
> 
> cc_int_l
> 
> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>> +??????????? rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
>> +??????? };
>> ????? };
>> ? };
>> @@ -835,6 +911,14 @@ &uart2 {
>> ????? status = "okay";
>> ? };
>> +&u2phy0 {
>> +??? status = "okay";
>> +};
>> +
>> +&u2phy0_otg {
>> +??? status = "okay";
>> +};
>> +
>> ? &u2phy1 {
>> ????? status = "okay";
>> ? };
>> @@ -866,6 +950,29 @@ &usbdp_phy1 {
>> ????? status = "okay";
>> ? };
>> +&usbdp_phy0 {
>> +??? mode-switch;
>> +??? orientation-switch;
>> +??? sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
>> +??? sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
>> +??? status = "okay";
>> +
>> +??? port {
>> +??????? #address-cells = <1>;
>> +??????? #size-cells = <0>;
>> +
>> +??????? usbdp_phy0_orientation_switch: endpoint at 0 {
>> +??????????? reg = <0>;
>> +??????????? remote-endpoint = <&usbc0_orien_sw>;
>> +??????? };
>> +
>> +??????? usbdp_phy0_dp_altmode_mux: endpoint at 1 {
>> +??????????? reg = <1>;
>> +??????????? remote-endpoint = <&dp_altmode_mux>;
>> +??????? };
>> +??? };
>> +};
>> +
>> ? &usb_host0_ehci {
>> ????? status = "okay";
>> ? };
>> @@ -874,6 +981,20 @@ &usb_host0_ohci {
>> ????? status = "okay";
>> ? };
>> +&usb_host0_xhci {
>> +??? usb-role-switch;
>> +??? status = "okay";
>> +
>> +??? port {
>> +??????? #address-cells = <1>;
>> +??????? #size-cells = <0>;
>> +
>> +??????? dwc3_0_role_switch: endpoint {
>> +??????????? remote-endpoint = <&usbc0_role_sw>;
>> +??????? };
>> +??? };
>> +};
>> +
>> ? &usb_host1_ehci {
>> ????? status = "okay";
>> ? };
> 



From sboyd at kernel.org  Tue Dec 10 14:44:19 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 10 Dec 2024 14:44:19 -0800
Subject: [PATCH 4/5] clk: Add flag to prevent frequency changes when walking subtrees
In-Reply-To: <20241121-ge-ian-debug-imx8-clk-tree-v1-4-0f1b722588fe@bootlin.com>
References: <20241121-ge-ian-debug-imx8-clk-tree-v1-0-0f1b722588fe@bootlin.com> <20241121-ge-ian-debug-imx8-clk-tree-v1-4-0f1b722588fe@bootlin.com>
Message-ID: <fd2b473bc7c3c70ae0e85b2a6315d9e8.sboyd@kernel.org>

Quoting Miquel Raynal (2024-11-21 09:41:14)
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index adfc5bfb93b5a65b6f58c52ca2c432d651f7dd7d..94d93470479e77769e63e97462b176261103b552 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -1927,7 +1927,6 @@ long clk_get_accuracy(struct clk *clk)
>  }
>  EXPORT_SYMBOL_GPL(clk_get_accuracy);
>  
> -__maybe_unused
>  static unsigned long clk_determine(struct clk_core *core, unsigned long rate)
>  {
>         struct clk_rate_request req = {};

Please add functions in the same patch that uses them. It is hard to
review this patch when half the context is in another patch.

> @@ -2272,7 +2271,13 @@ static void clk_calc_subtree(struct clk_core *core)
>  {
>         struct clk_core *child;
>  
> -       core->new_rate = clk_recalc(core, core->parent->new_rate);
> +       if (core->flags & CLK_NO_RATE_CHANGE_DURING_PROPAGATION) {
> +               core->new_rate = clk_determine(core, core->rate);
> +               if (!core->new_rate)
> +                       core->new_rate = clk_recalc(core, core->parent->new_rate);
> +       } else {
> +               core->new_rate = clk_recalc(core, core->parent->new_rate);
> +       }
>  
>         hlist_for_each_entry(child, &core->children, child_node)
>                 clk_calc_subtree(child);
> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
> index 200135e0f6d00d48b10e843259333b9733c97f38..baef0b442ac1d36ee935cbcaaaa4e2d95fe7654c 100644
> --- a/include/linux/clk-provider.h
> +++ b/include/linux/clk-provider.h
> @@ -38,6 +38,8 @@
>  #define CLK_OPS_PARENT_ENABLE  BIT(12)
>  /* duty cycle call may be forwarded to the parent clock */
>  #define CLK_DUTY_CYCLE_PARENT  BIT(13)
> +/* do not passively change this clock rate during subtree rate propagation */
> +#define CLK_NO_RATE_CHANGE_DURING_PROPAGATION BIT(14)

Why doesn't rate locking work?


From cki-project at redhat.com  Tue Dec 10 14:52:04 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Tue, 10 Dec 2024 22:52:04 -0000
Subject: =?utf-8?b?4p2M?= FAIL (MISSED 10 of 69): Test report for for-kernelci
 (6.13.0-rc2, upstream-arm-next, 146ff2c2)
Message-ID: <09245.124121017520601116@us-mta-625.us.mimecast.lan>

Hi, we tested your kernel and here are the results:

    Overall result: FAILED
             Merge: OK
           Compile: OK
              Test: FAILED


Kernel information:
    Commit message: Merge branches 'for-next/cpufeature' and 'for-next/misc' into for-next/core

You can find all the details about the test run at
    https://datawarehouse.cki-project.org/kcidb/checkouts/redhat:1582704765

One or more kernel tests failed:
    Unrecognized or new issues:
        Reboot test
             aarch64
                   Logs: https://datawarehouse.cki-project.org/kcidb/tests/redhat:1582704765-aarch64-kernel_upt_53
                   Non-passing ran subtests:
                       ? FAIL /10_avc_check


Tests that were not ran because of internal issues: 
    Boot test [aarch64]
    CKI/restraint [aarch64]
    machineinfo [aarch64]
    Reboot test [aarch64]
    SELinux Custom Module Setup [aarch64]
    Storage - blktests - throtl [aarch64]
    Storage - blktests - ublk [aarch64]
    Storage - swraid scsi_raid [aarch64]
    stress: stress-ng - cpu-cache [aarch64]
    stress: stress-ng - memory [aarch64]


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 cwabbott0 at gmail.com  Tue Dec 10 14:52:27 2024
From: cwabbott0 at gmail.com (Connor Abbott)
Date: Tue, 10 Dec 2024 17:52:27 -0500
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
Message-ID: <CACu1E7H0-zzEPv8ytmx_9XRe1t-RCc7enshgwk2r9-0gWK44hw@mail.gmail.com>

On Mon, Dec 9, 2024 at 3:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
>
> When kernel is booted in EL2, SECVID registers are accessible to the
> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> on Zap firmware. Also, we can't load a secure firmware without a
> hypervisor that supports it.
>
> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
>
> 1. Gunyah (No KVM) - Loads zap shader based on DT
> 2. KVM in VHE - Skips zap shader load and programs SECVID register
> 3. KVM in nVHE - Loads zap shader based on DT
> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
>         programs SECVID register
>
> For (1) and (3) configuration, this patch doesn't have any impact.
> Driver loads secure firmware based on other existing hints.
>
> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>

For initializing CX_MISC_SW_FUSE_VALUE in a7xx_cx_mem_init(), we used
!qcom_scm_is_available() to assume that the register is writable
instead - can you just do that?

Connor

> ---
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 +++++++++++++++++++++++------------
>  1 file changed, 54 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index 019610341df1..9dcaa8472430 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -14,6 +14,10 @@
>  #include <linux/pm_domain.h>
>  #include <linux/soc/qcom/llcc-qcom.h>
>
> +#ifdef CONFIG_ARM64
> +#include <asm/virt.h>
> +#endif
> +
>  #define GPU_PAS_ID 13
>
>  static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
> @@ -998,6 +1002,54 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
>         return ret;
>  }
>
> +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> +{
> +       int ret;
> +
> +#ifdef CONFIG_ARM64
> +       /*
> +        * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> +        * to switch the secure mode to avoid the dependency on zap shader.
> +        */
> +       if (is_kernel_in_hyp_mode())
> +               goto direct_switch;
> +#endif
> +
> +       /*
> +        * Try to load a zap shader into the secure world. If successful
> +        * we can use the CP to switch out of secure mode. If not then we
> +        * have no resource but to try to switch ourselves out manually. If we
> +        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
> +        * be blocked and a permissions violation will soon follow.
> +        */
> +       ret = a6xx_zap_shader_init(gpu);
> +       if (ret == -ENODEV) {
> +               /*
> +                * This device does not use zap shader (but print a warning
> +                * just in case someone got their dt wrong.. hopefully they
> +                * have a debug UART to realize the error of their ways...
> +                * if you mess this up you are about to crash horribly)
> +                */
> +               dev_warn_once(gpu->dev->dev,
> +                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
> +               goto direct_switch;
> +       } else if (ret)
> +               return ret;
> +
> +       OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
> +       OUT_RING(gpu->rb[0], 0x00000000);
> +
> +       a6xx_flush(gpu, gpu->rb[0]);
> +       if (!a6xx_idle(gpu, gpu->rb[0]))
> +               return -EINVAL;
> +
> +       return 0;
> +
> +direct_switch:
> +       gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
> +       return 0;
> +}
> +
>  #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
>                        A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
>                        A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
> @@ -1341,35 +1393,9 @@ static int hw_init(struct msm_gpu *gpu)
>         if (ret)
>                 goto out;
>
> -       /*
> -        * Try to load a zap shader into the secure world. If successful
> -        * we can use the CP to switch out of secure mode. If not then we
> -        * have no resource but to try to switch ourselves out manually. If we
> -        * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
> -        * be blocked and a permissions violation will soon follow.
> -        */
> -       ret = a6xx_zap_shader_init(gpu);
> -       if (!ret) {
> -               OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
> -               OUT_RING(gpu->rb[0], 0x00000000);
> -
> -               a6xx_flush(gpu, gpu->rb[0]);
> -               if (!a6xx_idle(gpu, gpu->rb[0]))
> -                       return -EINVAL;
> -       } else if (ret == -ENODEV) {
> -               /*
> -                * This device does not use zap shader (but print a warning
> -                * just in case someone got their dt wrong.. hopefully they
> -                * have a debug UART to realize the error of their ways...
> -                * if you mess this up you are about to crash horribly)
> -                */
> -               dev_warn_once(gpu->dev->dev,
> -                       "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
> -               gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
> -               ret = 0;
> -       } else {
> +       ret = a6xx_switch_secure_mode(gpu);
> +       if (!ret)
>                 return ret;
> -       }
>
>  out:
>         if (adreno_has_gmu_wrapper(adreno_gpu))
>
> ---
> base-commit: f4a867a46862c1743501bbe8c813238456ec8699
> change-id: 20241120-drm-msm-kvm-support-cd6e6744ced6
>
> Best regards,
> --
> Akhil P Oommen <quic_akhilpo at quicinc.com>
>


From robh at kernel.org  Tue Dec 10 14:54:01 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 10 Dec 2024 16:54:01 -0600
Subject: [PATCH v5 03/10] dt-bindings: pci: Add common schema for devices
 accessible through PCI BARs
In-Reply-To: <92fe1c6eb3ae1e7e7c151423568be2d13f19b55a.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
 <92fe1c6eb3ae1e7e7c151423568be2d13f19b55a.1733136811.git.andrea.porta@suse.com>
Message-ID: <173387124038.751229.17185539657512592303.robh@kernel.org>


On Mon, 02 Dec 2024 12:19:27 +0100, Andrea della Porta wrote:
> Common YAML schema for devices that exports internal peripherals through
> PCI BARs. The BARs are exposed as simple-buses through which the
> peripherals can be accessed.
> 
> This is not intended to be used as a standalone binding, but should be
> included by device specific bindings.
> 
> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
> ---
>  .../devicetree/bindings/pci/pci-ep-bus.yaml   | 58 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 59 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From robh at kernel.org  Tue Dec 10 14:48:37 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 10 Dec 2024 16:48:37 -0600
Subject: [PATCH v5 08/10] misc: rp1: RaspberryPi RP1 misc driver
In-Reply-To: <28fe72eec1c08781770cee65032bb10a6d5994a9.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
 <28fe72eec1c08781770cee65032bb10a6d5994a9.1733136811.git.andrea.porta@suse.com>
Message-ID: <20241210224837.GA702616-robh@kernel.org>

On Mon, Dec 02, 2024 at 12:19:32PM +0100, Andrea della Porta wrote:
> The RaspberryPi RP1 is a PCI multi function device containing
> peripherals ranging from Ethernet to USB controller, I2C, SPI
> and others.
> 
> Implement a bare minimum driver to operate the RP1, leveraging
> actual OF based driver implementations for the on-board peripherals
> by loading a devicetree overlay during driver probe.
> 
> The peripherals are accessed by mapping MMIO registers starting
> from PCI BAR1 region.
> 
> With the overlay approach we can achieve more generic and agnostic
> approach to managing this chipset, being that it is a PCI endpoint
> and could possibly be reused in other hw implementations. The
> presented approach is also used by Bootlin's Microchip LAN966x
> patchset (see link) as well, for a similar chipset.
> 
> Since the gpio line names should be provided by the user, there
> is an interface through configfs that allows the userspace to
> load a DT overlay that will provide gpio-line-names property.
> The interface can be invoked like this:
> 
> cat rpi-rp1-gpios-5-b.dtbo > /sys/kernel/config/rp1-cfg/gpio_set_names

Where's the configfs support? This looks like a stale comment.

If this is the general purpose configfs interface for overlays, that's 
likely never going upstream. If you want this support, then you should 
load your overlay with the firmware loader instead of building it into 
the kernel. You can of course add that later.

> and is designed to be similar to what users are already used to
> from distro with downstream kernel.
> 
> For reasons why this driver is contained in drivers/misc, please
> check the links.
> 
> This driver is heavily based on downstream code from RaspberryPi
> Foundation, and the original author is Phil Elwell.
> 
> Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> Link: https://lore.kernel.org/all/20240612140208.GC1504919 at google.com/
> Link: https://lore.kernel.org/all/83f7fa09-d0e6-4f36-a27d-cee08979be2a at app.fastmail.com/
> Link: https://lore.kernel.org/all/2024081356-mutable-everyday-6f9d at gregkh/
> Link: https://lore.kernel.org/all/20240808154658.247873-1-herve.codina at bootlin.com/
> 
> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
> ---
>  MAINTAINERS                   |   1 +
>  drivers/misc/Kconfig          |   1 +
>  drivers/misc/Makefile         |   1 +
>  drivers/misc/rp1/Kconfig      |  21 ++
>  drivers/misc/rp1/Makefile     |   3 +
>  drivers/misc/rp1/rp1-pci.dtso |   8 +
>  drivers/misc/rp1/rp1_pci.c    | 366 ++++++++++++++++++++++++++++++++++
>  drivers/misc/rp1/rp1_pci.h    |  14 ++
>  drivers/pci/quirks.c          |   1 +
>  include/linux/pci_ids.h       |   3 +
>  10 files changed, 419 insertions(+)
>  create mode 100644 drivers/misc/rp1/Kconfig
>  create mode 100644 drivers/misc/rp1/Makefile
>  create mode 100644 drivers/misc/rp1/rp1-pci.dtso
>  create mode 100644 drivers/misc/rp1/rp1_pci.c
>  create mode 100644 drivers/misc/rp1/rp1_pci.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fbdd8594aa7e..d67ba6d10aa8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19583,6 +19583,7 @@ F:	Documentation/devicetree/bindings/misc/pci1de4,1.yaml
>  F:	Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
>  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
>  F:	drivers/clk/clk-rp1.c
> +F:	drivers/misc/rp1/
>  F:	drivers/pinctrl/pinctrl-rp1.c
>  F:	include/dt-bindings/clock/rp1.h
>  F:	include/dt-bindings/misc/rp1.h
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 09cbe3f0ab1e..ffa4d8315c35 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -651,4 +651,5 @@ source "drivers/misc/uacce/Kconfig"
>  source "drivers/misc/pvpanic/Kconfig"
>  source "drivers/misc/mchp_pci1xxxx/Kconfig"
>  source "drivers/misc/keba/Kconfig"
> +source "drivers/misc/rp1/Kconfig"
>  endmenu
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 40bf953185c7..3b6b07a23aac 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -74,3 +74,4 @@ lan966x-pci-objs		:= lan966x_pci.o
>  lan966x-pci-objs		+= lan966x_pci.dtbo.o
>  obj-$(CONFIG_MCHP_LAN966X_PCI)	+= lan966x-pci.o
>  obj-y				+= keba/
> +obj-$(CONFIG_MISC_RP1)		+= rp1/
> diff --git a/drivers/misc/rp1/Kconfig b/drivers/misc/rp1/Kconfig
> new file mode 100644
> index 000000000000..15c443e13389
> --- /dev/null
> +++ b/drivers/misc/rp1/Kconfig
> @@ -0,0 +1,21 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# RaspberryPi RP1 misc device
> +#
> +
> +config MISC_RP1
> +	tristate "RaspberryPi RP1 PCIe support"
> +	depends on OF_IRQ && PCI_MSI && PCI_QUIRKS
> +	select OF_OVERLAY
> +	select PCI_DYNAMIC_OF_NODES
> +	help
> +	  Support the RP1 peripheral chip found on Raspberry Pi 5 board.
> +
> +	  This device supports several sub-devices including e.g. Ethernet
> +	  controller, USB controller, I2C, SPI and UART.
> +
> +	  The driver is responsible for enabling the DT node once the PCIe
> +	  endpoint has been configured, and handling interrupts.
> +
> +	  This driver uses an overlay to load other drivers to support for
> +	  RP1 internal sub-devices.
> diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
> new file mode 100644
> index 000000000000..508b4cb05627
> --- /dev/null
> +++ b/drivers/misc/rp1/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
> +rp1-pci-objs			:= rp1_pci.o rp1-pci.dtbo.o
> diff --git a/drivers/misc/rp1/rp1-pci.dtso b/drivers/misc/rp1/rp1-pci.dtso
> new file mode 100644
> index 000000000000..0bf2f4bb18e6
> --- /dev/null
> +++ b/drivers/misc/rp1/rp1-pci.dtso
> @@ -0,0 +1,8 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +
> +/* the dts overlay is included from the dts directory so
> + * it can be possible to check it with CHECK_DTBS while
> + * also compile it from the driver source directory.

I haven't tried, but I think if you set CHECK_DTBS=y, then this file 
will get checked. Applying it to the base DT will not though.

> + */
> +
> +#include "arm64/broadcom/rp1.dtso"
> diff --git a/drivers/misc/rp1/rp1_pci.c b/drivers/misc/rp1/rp1_pci.c
> new file mode 100644
> index 000000000000..0dd345341c6f
> --- /dev/null
> +++ b/drivers/misc/rp1/rp1_pci.c
> @@ -0,0 +1,366 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018-24 Raspberry Pi Ltd.
> + * All rights reserved.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/module.h>
> +#include <linux/msi.h>
> +#include <linux/of_platform.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +
> +#include "rp1_pci.h"
> +
> +#define RP1_DRIVER_NAME		"rp1"
> +
> +#define RP1_HW_IRQ_MASK		GENMASK(5, 0)
> +
> +#define REG_SET			0x800
> +#define REG_CLR			0xc00
> +
> +/* MSI-X CFG registers start at 0x8 */
> +#define MSIX_CFG(x) (0x8 + (4 * (x)))
> +
> +#define MSIX_CFG_IACK_EN        BIT(3)
> +#define MSIX_CFG_IACK           BIT(2)
> +#define MSIX_CFG_ENABLE         BIT(0)
> +
> +/* Address map */
> +#define RP1_PCIE_APBS_BASE	0x108000
> +
> +/* Interrupts */
> +#define RP1_INT_IO_BANK0	0
> +#define RP1_INT_IO_BANK1	1
> +#define RP1_INT_IO_BANK2	2
> +#define RP1_INT_AUDIO_IN	3
> +#define RP1_INT_AUDIO_OUT	4
> +#define RP1_INT_PWM0		5
> +#define RP1_INT_ETH		6
> +#define RP1_INT_I2C0		7
> +#define RP1_INT_I2C1		8
> +#define RP1_INT_I2C2		9
> +#define RP1_INT_I2C3		10
> +#define RP1_INT_I2C4		11
> +#define RP1_INT_I2C5		12
> +#define RP1_INT_I2C6		13
> +#define RP1_INT_I2S0		14
> +#define RP1_INT_I2S1		15
> +#define RP1_INT_I2S2		16
> +#define RP1_INT_SDIO0		17
> +#define RP1_INT_SDIO1		18
> +#define RP1_INT_SPI0		19
> +#define RP1_INT_SPI1		20
> +#define RP1_INT_SPI2		21
> +#define RP1_INT_SPI3		22
> +#define RP1_INT_SPI4		23
> +#define RP1_INT_SPI5		24
> +#define RP1_INT_UART0		25
> +#define RP1_INT_TIMER_0		26
> +#define RP1_INT_TIMER_1		27
> +#define RP1_INT_TIMER_2		28
> +#define RP1_INT_TIMER_3		29
> +#define RP1_INT_USBHOST0	30
> +#define RP1_INT_USBHOST0_0	31
> +#define RP1_INT_USBHOST0_1	32
> +#define RP1_INT_USBHOST0_2	33
> +#define RP1_INT_USBHOST0_3	34
> +#define RP1_INT_USBHOST1	35
> +#define RP1_INT_USBHOST1_0	36
> +#define RP1_INT_USBHOST1_1	37
> +#define RP1_INT_USBHOST1_2	38
> +#define RP1_INT_USBHOST1_3	39
> +#define RP1_INT_DMA		40
> +#define RP1_INT_PWM1		41
> +#define RP1_INT_UART1		42
> +#define RP1_INT_UART2		43
> +#define RP1_INT_UART3		44
> +#define RP1_INT_UART4		45
> +#define RP1_INT_UART5		46
> +#define RP1_INT_MIPI0		47
> +#define RP1_INT_MIPI1		48
> +#define RP1_INT_VIDEO_OUT	49
> +#define RP1_INT_PIO_0		50
> +#define RP1_INT_PIO_1		51
> +#define RP1_INT_ADC_FIFO	52
> +#define RP1_INT_PCIE_OUT	53
> +#define RP1_INT_SPI6		54
> +#define RP1_INT_SPI7		55
> +#define RP1_INT_SPI8		56
> +#define RP1_INT_SYSCFG		58
> +#define RP1_INT_CLOCKS_DEFAULT	59
> +#define RP1_INT_VBUSCTRL	60
> +#define RP1_INT_PROC_MISC	57

Why all these defines which will never be used because they come from 
DT?

Rob


From Frank.Li at nxp.com  Tue Dec 10 14:48:57 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 10 Dec 2024 17:48:57 -0500
Subject: [PATCH v8 0/2] PCI: add enabe(disable)_device() hook for bridge
Message-ID: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>

Some system's IOMMU stream(master) ID bits(such as 6bits) less than
pci_device_id (16bit). It needs add hardware configuration to enable
pci_device_id to stream ID convert.

https://lore.kernel.org/imx/20240622173849.GA1432357 at bhelgaas/
This ways use pcie bus notifier (like apple pci controller), when new PCIe
device added, bus notifier will call register specific callback to handle
look up table (LUT) configuration.

https://lore.kernel.org/imx/20240429150842.GC1709920-robh at kernel.org/
which parse dt's 'msi-map' and 'iommu-map' property to static config LUT
table (qcom use this way). This way is rejected by DT maintainer Rob.

Above ways can resolve LUT take or stream id out of usage the problem. If
there are not enough stream id resource, not error return, EP hardware
still issue DMA to do transfer, which may transfer to wrong possition.

Add enable(disable)_device() hook for bridge can return error when not
enough resource, and PCI device can't enabled.

Basicallly this version can match Bjorn's requirement:
1: simple, because it is rare that there are no LUT resource.
2: EP driver probe failure when no LUT, but lspci can see such device.

[    2.164415] nvme nvme0: pci function 0000:01:00.0
[    2.169142] pci 0000:00:00.0: Error enabling bridge (-1), continuing
[    2.175654] nvme 0000:01:00.0: probe with driver nvme failed with error -12

> lspci
0000:00:00.0 PCI bridge: Philips Semiconductors Device 0000
0000:01:00.0 Non-Volatile memory controller: Micron Technology Inc 2100AI NVMe SSD [Nitro] (rev 03)

To: Bjorn Helgaas <bhelgaas at google.com>
To: Richard Zhu <hongxing.zhu at nxp.com>
To: Lucas Stach <l.stach at pengutronix.de>
To: Lorenzo Pieralisi <lpieralisi at kernel.org>
To: Krzysztof Wilczy?ski <kw at linux.com>
To: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
To: Rob Herring <robh 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>
Cc: linux-pci at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: imx at lists.linux.dev
Cc: Frank.li at nxp.com \
Cc: alyssa at rosenzweig.io \
Cc: bpf at vger.kernel.org \
Cc: broonie at kernel.org \
Cc: jgg at ziepe.ca \
Cc: joro at 8bytes.org \
Cc: l.stach at pengutronix.de \
Cc: lgirdwood at gmail.com \
Cc: maz at kernel.org \
Cc: p.zabel at pengutronix.de \
Cc: robin.murphy at arm.com \
Cc: will at kernel.org \
Cc: Robin Murphy <robin.murphy at arm.com>
Cc: Marc Zyngier <maz at kernel.org>

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Changes in v8:
- update comment message according to Lorenzo Pieralisi's suggestion.
- rework err target table
- improve err==0 && target ==NULL description, use 1:1 map RID to
stream ID.
- invalidate case -> unexisted case, never happen
- sid_i will not do mask, add comments said only MSI glue layer add
controller id.
- rework iommu map and msi map return value check logic according to
Lorenzo Pieralisi's suggestion
- Link to v7: https://lore.kernel.org/r/20241203-imx95_lut-v7-0-d0cd6293225e at nxp.com

Changes in v7:
- Rebase v6.13-rc1
- Update patch 2 according to mani's feedback
- Link to v6: https://lore.kernel.org/r/20241118-imx95_lut-v6-0-a2951ba13347 at nxp.com

Changes in v6:
- Bjorn give review tags at v4, but v5 have big change, drop Bjorn's review
tag.
- Add back Marc Zyngier't review and test tags
- Add mani's ack at first patch
- Mini change for patch 2 according to mani's feedback
- Link to v5: https://lore.kernel.org/r/20241104-imx95_lut-v5-0-feb972f3f13b at nxp.com

Changes in v5:
- Add help function of pci_bridge_enable(disable)_device
- Because big change, removed Bjorn's review tags and have not
added
Marc Zyngier't review and test tags
- Fix pci-imx6.c according to Mani's feedback
- Link to v4: https://lore.kernel.org/r/20241101-imx95_lut-v4-0-0fdf9a2fe754 at nxp.com

Changes in v4:
- Add Bjorn Helgaas review tag for patch1
- check 'target' value for patch2
- detail see each patches
- Link to v3: https://lore.kernel.org/r/20241024-imx95_lut-v3-0-7509c9bbab86 at nxp.com

Changes in v3:
- disable_device when error happen
- use target for of_map_id
- Check if rid already in lut table when enable deviced
- Link to v2: https://lore.kernel.org/r/20240930-imx95_lut-v2-0-3b6467ba539a at nxp.com

Changes in v2:
- see each patch
- Link to v1: https://lore.kernel.org/r/20240926-imx95_lut-v1-0-d0c62087dbab at nxp.com

---
Frank Li (2):
      PCI: Add enable_device() and disable_device() callbacks for bridges
      PCI: imx6: Add IOMMU and ITS MSI support for i.MX95

 drivers/pci/controller/dwc/pci-imx6.c | 186 +++++++++++++++++++++++++++++++++-
 drivers/pci/pci.c                     |  36 ++++++-
 include/linux/pci.h                   |   2 +
 3 files changed, 222 insertions(+), 2 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20240926-imx95_lut-1c68222e0944

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Tue Dec 10 14:48:58 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 10 Dec 2024 17:48:58 -0500
Subject: [PATCH v8 1/2] PCI: Add enable_device() and disable_device()
 callbacks for bridges
In-Reply-To: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
References: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
Message-ID: <20241210-imx95_lut-v8-1-2e730b2e5fde@nxp.com>

Some PCIe host bridges require special handling when enabling or disabling
PCIe Endpoints. For example, the i.MX95 platform has a lookup table to map
Requester IDs to StreamIDs, which are used by the SMMU and MSI controller
to identify the source of DMA accesses.

Without this mapping, DMA accesses may target unintended memory, which
would corrupt memory or read the wrong data.

Add a host bridge .enable_device() hook the imx6 driver can use to
configure the Requester ID to StreamID mapping. The hardware table isn't
big enough to map all possible Requester IDs, so this hook may fail if no
table space is available. In that case, return failure from
pci_enable_device().

It might make more sense to make pci_set_master() decline to enable bus
mastering and return failure, but it currently doesn't have a way to return
failure.

Reviewed-by: Marc Zyngier <maz at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v6 to v8
- none

Change from v5 to v6
- Add Marc testedby and Reviewed-by tag
- Add Mani's acked tag

Change from v4 to v5
- Add two static help functions
int pci_host_bridge_enable_device(dev);
void pci_host_bridge_disable_device(dev);
- remove tags because big change
Acked-by: Bjorn Helgaas <bhelgaas at google.com>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>

Change from v3 to v4
- Add Bjorn's ack tag

Change from v2 to v3
- use Bjorn suggest's commit message.
- call disable_device() when error happen.

Change from v1 to v2
- move enable(disable)device ops to pci_host_bridge
---
 drivers/pci/pci.c   | 36 +++++++++++++++++++++++++++++++++++-
 include/linux/pci.h |  2 ++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0b29ec6e8e5e2..773ca3cbd3221 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2059,6 +2059,28 @@ int __weak pcibios_enable_device(struct pci_dev *dev, int bars)
 	return pci_enable_resources(dev, bars);
 }
 
+static int pci_host_bridge_enable_device(struct pci_dev *dev)
+{
+	struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus);
+	int err;
+
+	if (host_bridge && host_bridge->enable_device) {
+		err = host_bridge->enable_device(host_bridge, dev);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static void pci_host_bridge_disable_device(struct pci_dev *dev)
+{
+	struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus);
+
+	if (host_bridge && host_bridge->disable_device)
+		host_bridge->disable_device(host_bridge, dev);
+}
+
 static int do_pci_enable_device(struct pci_dev *dev, int bars)
 {
 	int err;
@@ -2074,9 +2096,13 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
 	if (bridge)
 		pcie_aspm_powersave_config_link(bridge);
 
+	err = pci_host_bridge_enable_device(dev);
+	if (err)
+		return err;
+
 	err = pcibios_enable_device(dev, bars);
 	if (err < 0)
-		return err;
+		goto err_enable;
 	pci_fixup_device(pci_fixup_enable, dev);
 
 	if (dev->msi_enabled || dev->msix_enabled)
@@ -2091,6 +2117,12 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
 	}
 
 	return 0;
+
+err_enable:
+	pci_host_bridge_disable_device(dev);
+
+	return err;
+
 }
 
 /**
@@ -2274,6 +2306,8 @@ void pci_disable_device(struct pci_dev *dev)
 	if (atomic_dec_return(&dev->enable_cnt) != 0)
 		return;
 
+	pci_host_bridge_disable_device(dev);
+
 	do_pci_disable_device(dev);
 
 	dev->is_busmaster = 0;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index db9b47ce3eefd..bcbef004dd561 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -595,6 +595,8 @@ struct pci_host_bridge {
 	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
 	int (*map_irq)(const struct pci_dev *, u8, u8);
 	void (*release_fn)(struct pci_host_bridge *);
+	int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
+	void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
 	void		*release_data;
 	unsigned int	ignore_reset_delay:1;	/* For entire hierarchy */
 	unsigned int	no_ext_tags:1;		/* No Extended Tags */

-- 
2.34.1



From Frank.Li at nxp.com  Tue Dec 10 14:48:59 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 10 Dec 2024 17:48:59 -0500
Subject: [PATCH v8 2/2] PCI: imx6: Add IOMMU and ITS MSI support for i.MX95
In-Reply-To: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
References: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
Message-ID: <20241210-imx95_lut-v8-2-2e730b2e5fde@nxp.com>

For the i.MX95, configuration of a LUT is necessary to convert Bus Device
Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
This involves checking msi-map and iommu-map device tree properties to
ensure consistent mapping of PCI BDF to the same stream IDs. Subsequently,
LUT-related registers are configured. In the absence of an msi-map, the
built-in MSI controller is utilized as a fallback.

Register a PCI bus callback function to handle enable_device() and
disable_device() operations, setting up the LUT whenever a new PCI device
is enabled.

Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v7 to v8
- update comment message according to Lorenzo Pieralisi's suggestion.
- rework err target table
- improve err==0 && target ==NULL description, use 1:1 map RID to
stream ID.
- invalidate case -> unexisted case, never happen
- sid_i will not do mask, add comments said only MSI glue layer add
controller id.
- rework iommu map and msi map return value check logic according to
Lorenzo Pieralisi's suggestion

Change from v5 to v7
- change comment rid to RID
- some mini change according to mani's feedback

Change from v4 to v5
- rework commt message
- add comment for mutex
- s/reqid/rid/
- keep only one loop when enable lut
- add warning when try to add duplicate rid
- Replace hardcode 0xffff with IMX95_PE0_LUT_MASK
- Fix some error message

Change from v3 to v4
- Check target value at of_map_id().
- of_node_put() for target.
- add case for msi-map exist, but rid entry is not exist.

Change from v2 to v3
- Use the "target" argument of of_map_id()
- Check if rid already in lut table when enable device

change from v1 to v2
- set callback to pci_host_bridge instead pci->ops.
---
 drivers/pci/controller/dwc/pci-imx6.c | 186 +++++++++++++++++++++++++++++++++-
 1 file changed, 185 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index c8d5c90aa4d45..d325f4fb279c8 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -55,6 +55,22 @@
 #define IMX95_PE0_GEN_CTRL_3			0x1058
 #define IMX95_PCIE_LTSSM_EN			BIT(0)
 
+#define IMX95_PE0_LUT_ACSCTRL			0x1008
+#define IMX95_PEO_LUT_RWA			BIT(16)
+#define IMX95_PE0_LUT_ENLOC			GENMASK(4, 0)
+
+#define IMX95_PE0_LUT_DATA1			0x100c
+#define IMX95_PE0_LUT_VLD			BIT(31)
+#define IMX95_PE0_LUT_DAC_ID			GENMASK(10, 8)
+#define IMX95_PE0_LUT_STREAM_ID			GENMASK(5, 0)
+
+#define IMX95_PE0_LUT_DATA2			0x1010
+#define IMX95_PE0_LUT_REQID			GENMASK(31, 16)
+#define IMX95_PE0_LUT_MASK			GENMASK(15, 0)
+
+#define IMX95_SID_MASK				GENMASK(5, 0)
+#define IMX95_MAX_LUT				32
+
 #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
 
 enum imx_pcie_variants {
@@ -87,6 +103,7 @@ enum imx_pcie_variants {
  * workaround suspend resume on some devices which are affected by this errata.
  */
 #define IMX_PCIE_FLAG_BROKEN_SUSPEND		BIT(9)
+#define IMX_PCIE_FLAG_HAS_LUT			BIT(10)
 
 #define imx_check_flag(pci, val)	(pci->drvdata->flags & val)
 
@@ -139,6 +156,9 @@ struct imx_pcie {
 	struct device		*pd_pcie_phy;
 	struct phy		*phy;
 	const struct imx_pcie_drvdata *drvdata;
+
+	/* Ensure that only one device's LUT is configured at any given time */
+	struct mutex		lock;
 };
 
 /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -930,6 +950,162 @@ static void imx_pcie_stop_link(struct dw_pcie *pci)
 	imx_pcie_ltssm_disable(dev);
 }
 
+static int imx_pcie_add_lut(struct imx_pcie *imx_pcie, u16 rid, u8 sid)
+{
+	struct dw_pcie *pci = imx_pcie->pci;
+	struct device *dev = pci->dev;
+	u32 data1, data2;
+	int free = -1;
+	int i;
+
+	if (sid >= 64) {
+		dev_err(dev, "Invalid SID for index %d\n", sid);
+		return -EINVAL;
+	}
+
+	guard(mutex)(&imx_pcie->lock);
+
+	/*
+	 * Iterate through all LUT entries to check for duplicate RID and
+	 * identify the first available entry. Configure this available entry
+	 * immediately after verification to avoid rescanning it.
+	 */
+	for (i = 0; i < IMX95_MAX_LUT; i++) {
+		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
+		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, &data1);
+
+		if (!(data1 & IMX95_PE0_LUT_VLD)) {
+			if (free < 0)
+				free = i;
+			continue;
+		}
+
+		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
+
+		/* Do not add duplicate RID */
+		if (rid == FIELD_GET(IMX95_PE0_LUT_REQID, data2)) {
+			dev_warn(dev, "Existing LUT entry available for RID (%d)", rid);
+			return 0;
+		}
+	}
+
+	if (free < 0) {
+		dev_err(dev, "LUT entry is not available\n");
+		return -ENOSPC;
+	}
+
+	data1 = FIELD_PREP(IMX95_PE0_LUT_DAC_ID, 0);
+	data1 |= FIELD_PREP(IMX95_PE0_LUT_STREAM_ID, sid);
+	data1 |= IMX95_PE0_LUT_VLD;
+	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, data1);
+
+	data2 = IMX95_PE0_LUT_MASK; /* Match all bits of RID */
+	data2 |= FIELD_PREP(IMX95_PE0_LUT_REQID, rid);
+	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, data2);
+
+	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, free);
+
+	return 0;
+}
+
+static void imx_pcie_remove_lut(struct imx_pcie *imx_pcie, u16 rid)
+{
+	u32 data2;
+	int i;
+
+	guard(mutex)(&imx_pcie->lock);
+
+	for (i = 0; i < IMX95_MAX_LUT; i++) {
+		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
+		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
+		if (FIELD_GET(IMX95_PE0_LUT_REQID, data2) == rid) {
+			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, 0);
+			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, 0);
+			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i);
+
+			break;
+		}
+	}
+}
+
+static int imx_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
+{
+	struct imx_pcie *imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
+	u32 sid_i, sid_m, rid = pci_dev_id(pdev);
+	struct device_node *target;
+	struct device *dev;
+	int err_i, err_m;
+	u32 sid;
+
+	dev = imx_pcie->pci->dev;
+
+	target = NULL;
+	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
+	if (target) {
+		of_node_put(target);
+	} else {
+		/*
+		 * "target == NULL && err_i == 0" means use 1:1 map RID to
+		 * stream ID. Hardware can't support this because stream ID
+		 * only 5bits
+		 */
+		err_i = -EINVAL;
+	}
+
+	target = NULL;
+	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
+
+	/*
+	 *   err_m      target
+	 *	0	NULL		Use 1:1 map RID to stream ID,
+	 *				Current hardware can't support it,
+	 *				So return -EINVAL.
+	 *      != 0    NULL		msi-map not exist, use built-in MSI.
+	 *	0	!= NULL		Get correct streamID from RID.
+	 *	!= 0	!= NULL		Unexisted case, never happen.
+	 */
+	if (!err_m && !target)
+		return -EINVAL;
+	else if (target)
+		of_node_put(target); /* Find stream ID map entry for RID in msi-map */
+
+	/*
+	 * msi-map        iommu-map
+	 *   N                N            DWC MSI Ctrl
+	 *   Y                Y            ITS + SMMU, require the same sid
+	 *   Y                N            ITS
+	 *   N                Y            DWC MSI Ctrl + SMMU
+	 */
+	if (err_i && err_m)
+		return 0;
+
+	if (!err_i && !err_m) {
+		/*
+		 * MSI glue layer auto add 2 bits controller ID ahead of stream
+		 * ID, so mask this 2bits to get stream ID.
+		 * But IOMMU glue layer doesn't do that.
+		 */
+		if (sid_i != (sid_m & IMX95_SID_MASK)) {
+			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
+			return -EINVAL;
+		}
+	}
+
+	sid = sid_i;
+	if (!err_m)
+		sid = sid_m & IMX95_SID_MASK;
+
+	return imx_pcie_add_lut(imx_pcie, rid, sid);
+}
+
+static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
+{
+	struct imx_pcie *imx_pcie;
+
+	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
+	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
+}
+
 static int imx_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -946,6 +1122,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
 		}
 	}
 
+	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
+		pp->bridge->enable_device = imx_pcie_enable_device;
+		pp->bridge->disable_device = imx_pcie_disable_device;
+	}
+
 	imx_pcie_assert_core_reset(imx_pcie);
 
 	if (imx_pcie->drvdata->init_phy)
@@ -1330,6 +1511,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
 	imx_pcie->pci = pci;
 	imx_pcie->drvdata = of_device_get_match_data(dev);
 
+	mutex_init(&imx_pcie->lock);
+
 	/* Find the PHY if one is defined, only imx7d uses it */
 	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
 	if (np) {
@@ -1627,7 +1810,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
 	},
 	[IMX95] = {
 		.variant = IMX95,
-		.flags = IMX_PCIE_FLAG_HAS_SERDES,
+		.flags = IMX_PCIE_FLAG_HAS_SERDES |
+			 IMX_PCIE_FLAG_HAS_LUT,
 		.clk_names = imx8mq_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
 		.ltssm_off = IMX95_PE0_GEN_CTRL_3,

-- 
2.34.1



From robh at kernel.org  Tue Dec 10 14:55:06 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 10 Dec 2024 16:55:06 -0600
Subject: [PATCH v5 04/10] dt-bindings: misc: Add device specific bindings
 for RaspberryPi RP1
In-Reply-To: <99c23bd584d7b1b998d2cafb7807e0650db73f20.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com>
 <99c23bd584d7b1b998d2cafb7807e0650db73f20.1733136811.git.andrea.porta@suse.com>
Message-ID: <173387130632.752894.7048832305370106368.robh@kernel.org>


On Mon, 02 Dec 2024 12:19:28 +0100, Andrea della Porta wrote:
> The RP1 is a MFD that exposes its peripherals through PCI BARs. This
> schema is intended as minimal support for the clock generator and
> gpio controller peripherals which are accessible through BAR1.
> 
> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
> ---
>  .../devicetree/bindings/misc/pci1de4,1.yaml   | 73 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 74 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/misc/pci1de4,1.yaml
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From robh at kernel.org  Tue Dec 10 15:04:33 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 10 Dec 2024 17:04:33 -0600
Subject: [PATCH v6 1/4] dt-bindings: rtc: add schema for NXP S32G2/S32G3
 SoCs
In-Reply-To: <20241206070955.1503412-2-ciprianmarian.costea@oss.nxp.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
 <20241206070955.1503412-2-ciprianmarian.costea@oss.nxp.com>
Message-ID: <173387187278.766456.7689697615269440552.robh@kernel.org>


On Fri, 06 Dec 2024 09:09:52 +0200, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> 
> RTC tracks clock time during system suspend and it is used as a wakeup
> source on S32G2/S32G3 architecture.
> 
> RTC from S32G2/S32G3 is not battery-powered and it is not kept alive
> during system reset.
> 
> Co-developed-by: Bogdan-Gabriel Roman <bogdan-gabriel.roman at nxp.com>
> Signed-off-by: Bogdan-Gabriel Roman <bogdan-gabriel.roman at nxp.com>
> Co-developed-by: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> ---
>  .../devicetree/bindings/rtc/nxp,s32g-rtc.yaml | 72 +++++++++++++++++++
>  1 file changed, 72 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From cristian.ciocaltea at collabora.com  Tue Dec 10 15:06:13 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 01:06:13 +0200
Subject: [PATCH v2 0/4] Add support for HDMI1 output on RK3588 SoC
Message-ID: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>

The patches provide the basic support to handle the second HDMI output
port found on Rockchip RK3588 SoC.

For now I enabled it on Radxa ROCK 5B only, the board I've been using to
validate this.

** IMPORTANT **

The series has a runtime dependency on "phy: phy-rockchip-samsung-hdptx:
Don't use dt aliases to determine phy-id", a patch submitted recently by
Heiko [1].  Without applying it, the functionality on both HDMI TX ports
will break.

Furthermore, please note this is subject to the same limitations as
HDMI0 when it comes to the supported display modes.  The fixes provided
via [2] are not applicable to HDMI1, hence I will handle it separately
as soon as all dependencies are merged.

Thanks,
Cristian

[1] https://lore.kernel.org/lkml/20241206103401.1780416-3-heiko at sntech.de/
[2] https://lore.kernel.org/all/20241116-vop2-hdmi0-disp-modes-v1-0-2bca51db4898 at collabora.com/

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
Changes in v2:
- Override hdmi1 pinctrl-0 on rock-5b as it requires hdmim0_tx1_cec
  instead of hdmim2_tx1_cec (fixes a pin conflict when enabling
  CONFIG_SPI_ROCKCHIP_SFC)
- Link to v1: https://lore.kernel.org/r/20241207-rk3588-hdmi1-v1-0-ca3a99b46a40 at collabora.com

---
Cristian Ciocaltea (4):
      drm/rockchip: dw_hdmi_qp: Add support for RK3588 HDMI1 output
      arm64: dts: rockchip: Add PHY node for HDMI1 TX port on RK3588
      arm64: dts: rockchip: Add HDMI1 node on RK3588
      arm64: dts: rockchip: Enable HDMI1 on rock-5b

 arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi  |  62 ++++++++++++
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts |  44 ++++++++-
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c  | 119 +++++++++++++++++++-----
 3 files changed, 200 insertions(+), 25 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241207-rk3588-hdmi1-704cbb7cd75f



From alexandre.belloni at bootlin.com  Tue Dec 10 15:07:50 2024
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Wed, 11 Dec 2024 00:07:50 +0100
Subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <fc50d8a7-cc59-42dd-aafd-7da49fadee45@app.fastmail.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
 <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
 <2005af5d-bdb7-4675-8f0e-82cb817801af@app.fastmail.com>
 <6f4a0be8-4def-4066-9b44-d43059b7a90d@oss.nxp.com>
 <94cba886-86cb-41f1-96ee-501623add7db@app.fastmail.com>
 <42d39f8e-0b59-4185-af1f-f778522608d2@oss.nxp.com>
 <fc50d8a7-cc59-42dd-aafd-7da49fadee45@app.fastmail.com>
Message-ID: <20241210230750dc03a1d5@mail.local>

On 10/12/2024 09:22:51+0100, Arnd Bergmann wrote:
> On Mon, Dec 9, 2024, at 18:17, Ciprian Marian Costea wrote:
> > On 12/6/2024 2:41 PM, Arnd Bergmann wrote:
> 
> >> I think storing 'rtc_hz' as a u32 variable and adding a range
> >> check when filling it would help, mainly to save the next reader
> >> from having to understand what is going on.
> >> 
> >
> > The confusion on my end is that I cannot see where 'div_u64() implicitly 
> > casts the dividend 'hz' from 64-bit to 32-bit' by following the method's 
> > implementation [1]
> 
> I mean passing a 64-bit variable into a function that takes a
> 32-bit argument truncates the range.
> 
> > But I agree that 'rtc_hz' can be stored into a 32-bit variable with a 
> > range check added when it is taken from the Linux clock API to avoid any
> > unneeded abstractions.
> 
> ok
> 
> >> 
> >> This is the same as just removing the error handling and
> >> relying on unsigned integer overflow semantics.
> >> 
> >> The usual check we do in time_before()/time_after instead
> >> checks if the elapsed time is less than half the available
> >> range:
> >> 
> >> #define time_after(a,b)         \
> >>          (typecheck(unsigned long, a) && \
> >>           typecheck(unsigned long, b) && \
> >>           ((long)((b) - (a)) < 0))
> >> 
> >
> > Ok. Thanks for the suggestion. I will look into using 
> > 'time_before()/time_after()' API instead of directly checking via 
> > comparison operators.
> 
> To be clear: you can't directly use time_before() here because
> that takes an 'unsigned long' argument, so you want the
> same logic, but for u32 values. I have not found an existing
> helper for that, but it's possible I missed it.
> 
> >> Who sets that alarm though? Are you relying on custom userspace
> >> for this, or is that something that the kernel already does
> >> that I'm missing?
> >
> > The test usage is via 'rtcwake' [2] userspace tool.
> > I've detailed a bit the testing scenario in the cover letter for this 
> > patchset [3]:
> >
> > "
> > Following is an example of Suspend to RAM trigger on S32G2/S32G3 SoCs,
> > using userspace tools such as rtcwake:
> > # rtcwake -s 2 -m mem
> > # rtcwake: assuming RTC uses UTC ...
> > # rtcwake: wakeup from "mem" using /dev/rtc0 at Wed Feb  6 06:28:36 2036
> 
> Got it. I feel this also needs either some documentation in
> the source code, or some infrastructure in the rtc layer if
> this is a common problem in other drivers as well. If there
> is a maximum time that the system can be suspended for without
> a wakeup, why not just set an earlier wakeup in the kernel
> when you have all the information for it?
> 
> Or maybe this should not actually be an 'rtc' driver at all?
> In the old days, we used drivers like
> arch/arm/mach-omap1/timer32k.c to register a handler
> for read_persistent_clock64(), which completely bypasses
> the RTC layer and provides both automatic wakeup and more
> accurate accounting of sleep time. 
> 
> Another example was the tegra clocksource driver, which used
> to use read_persistent_clock64() but changed to being
> a CLOCK_SOURCE_SUSPEND_NONSTOP source in 95170f0708f2
> ("clocksource/drivers/tegra: Rework for compensation of
> suspend time"). The same seems true for timer-ti-32k.c and
> timer-sprd.c.
> 
> Alexandre, Daniel, any recommendations here?
>

We have a few driver for timers that are not actual RTCs but need the
common alarm and wakeup API so they can use alarmtimers for example.
The limitation is not super common as RTCs will generally have the same
range support for alarm as what they have for time and date.

However, I'm still super confused by how complex this driver is. There
are only 3 interesting registers in this IP, one of those being read
only...

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From sebastian.reichel at collabora.com  Tue Dec 10 15:08:40 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Wed, 11 Dec 2024 00:08:40 +0100
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add USB-C support to ROCK 5B
In-Reply-To: <6A24DF29AE2F3CDC+70602cc7-2c03-470d-955f-06b2db116e20@radxa.com>
References: <20241210163615.120594-1-sebastian.reichel@collabora.com>
 <6A24DF29AE2F3CDC+70602cc7-2c03-470d-955f-06b2db116e20@radxa.com>
Message-ID: <5mjjq3f3tqu4h2f7wbdcfon6csfsuxge5skr6mmgozvq65uods@66yx7yuefzqn>

Hello Naoki,

On Wed, Dec 11, 2024 at 07:10:55AM +0900, FUKAUMI Naoki wrote:
> Hi Sebastian,
> 
> Thank you very much for your work!
> 
> $ cat /sys/class/power_supply/tcpm-source-psy-4-0022/{current_max,current_now,online,type,usb_type,voltage_max,voltage_min,voltage_now}
> 1500000
> 1500000
> 1
> USB
> C [PD] PD_PPS
> 20000000
> 20000000
> 20000000
> 
> $ cat /sys/class/power_supply/tcpm-source-psy-4-0022/{current_max,current_now,online,type,usb_type,voltage_max,voltage_min,voltage_now}
> 5000000
> 5000000
> 1
> USB
> C PD [PD_PPS]
> 20000000
> 20000000
> 20000000
> 
> $ ls /sys/class/udc/
> fc000000.usb
> 
> I can configure it as CDC-NCM and host detects it.
> But I could not use it as a HOST port. How to use it?

You can switch between host and peripheral for Type-C ports like
this depending on the remote sides capabilities:

 * echo host > /sys/class/typec/<port>/data_role
 * echo device > /sys/class/typec/<port>/data_role

I tested this with a USB-C hub connected to the port, which works
in host mode.

> some minor nitpick is below:
> 
> On 12/11/24 01:36, Sebastian Reichel wrote:
> > Add hardware description for the USB-C port in the Radxa Rock 5 Model B.
> > This describes the OHCI, EHCI and XHCI USB parts, but not yet the
> > DisplayPort AltMode (bindings are not yet upstream).
> > 
> > The fusb302 node is marked with status "fail", since the board is usually
> > powered through the USB-C port. Handling of errors can result in hard
> > resets, which removed the bus power for some time resulting in a board
> > reset.
> > 
> > The main problem is that devices are supposed to interact with the
> > power-supply within 5 seconds after the plug event according to the
> > USB PD specification. This is more or less impossible to achieve when
> > the kernel is the first software communicating with the power-supply.
> > 
> > Recent U-Boot (v2025.01) will start doing USB-PD communication, which
> > solves this issue. Upstream U-Boot doing USB-PD communication will also
> > set the fusb302 node status to "okay". That way booting a kernel with
> > the updated DT on an old U-Boot avoids a reset loop.
> > 
> > Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> > ---
> >   .../boot/dts/rockchip/rk3588-rock-5b.dts      | 121 ++++++++++++++++++
> >   1 file changed, 121 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> > index d597112f1d5b..cb5990df6ccb 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> > @@ -5,6 +5,7 @@
> >   #include <dt-bindings/gpio/gpio.h>
> >   #include <dt-bindings/leds/common.h>
> >   #include <dt-bindings/soc/rockchip,vop2.h>
> > +#include <dt-bindings/usb/pd.h>
> >   #include "rk3588.dtsi"
> >   / {
> > @@ -84,6 +85,15 @@ rfkill-bt {
> >   		shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
> >   	};
> > +	vcc12v_dcin: regulator-vcc12v-dcin {
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "vcc12v_dcin";
> 
> typec_vin by schematic.

Ack. Will update in v2.

> > +		regulator-always-on;
> > +		regulator-boot-on;
> > +		regulator-min-microvolt = <12000000>;
> > +		regulator-max-microvolt = <12000000>;
> > +	};
> > +
> >   	vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 {
> >   		compatible = "regulator-fixed";
> >   		enable-active-high;
> > @@ -142,6 +152,7 @@ vcc5v0_sys: regulator-vcc5v0-sys {
> >   		regulator-boot-on;
> >   		regulator-min-microvolt = <5000000>;
> >   		regulator-max-microvolt = <5000000>;
> > +		vin-supply = <&vcc12v_dcin>;
> 
> typec_vin.
> 
> >   	};
> >   	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
> > @@ -264,6 +275,67 @@ regulator-state-mem {
> >   	};
> >   };
> > +&i2c4 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&i2c4m1_xfer>;
> > +	status = "okay";
> > +
> > +	usbc0: usb-typec at 22 {
> 
> Is "usbc0" label necessary?

no, but does it hurt?

> > +		compatible = "fcs,fusb302";
> > +		reg = <0x22>;
> > +		interrupt-parent = <&gpio3>;
> > +		interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&usbc0_int>;
> 
> cc_int_l by schematic.

Ack. I intentionally switched away from this naming, since cc prefix
is imho a way worse prefix than usbc0. The _l suffix just means
active low, which is already encoded in DT.

But I don't have a strong opinion and can fix this in v2.

> > +		vbus-supply = <&vcc12v_dcin>;
> 
> typec_vin
> 
> > +		/*
> > +		 * When the board is starting to send power-delivery messages
> > +		 * too late (5 seconds according to the specification), the
> > +		 * power-supply reacts with a hard-reset. That removes the
> > +		 * power from VBUS for some time, which resets te whole board.
> 
> ... resets "the" whole board.

Ack.

> 
> > +		 */
> > +		status = "fail";
> > +
> > +		usb_con: connector {
> 
> Is "usb_con" label necessary?

No. It should either be changed to "usbc0_con" or removed. In
general I tend to add some labels when they might be needed by
something in the future. They are more or less free anyways.

-- 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/20241211/76bf724d/attachment.sig>

From heiko at sntech.de  Tue Dec 10 15:09:13 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 11 Dec 2024 00:09:13 +0100
Subject: [PATCH v5 04/18] drm/rockchip: vop2: Fix the windows switch between
 different layers
In-Reply-To: <20241209122943.2781431-8-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209122943.2781431-8-andyshrk@163.com>
Message-ID: <5109751.mvXUDI8C0e@phil>

Hi Andy,

Am Montag, 9. Dezember 2024, 13:29:17 CET schrieb Andy Yan:
> From: Andy Yan <andy.yan at rock-chips.com>
> 
> Every layer of vop2 should bind a window, and we also need to make
> sure that this window is not used by other layer.
> 
> 0x5 is a reserved layer sel value on rk3568, but it will select
> Cluster3 on rk3588, configure unused layers to 0x5  will lead
> alpha blending error on rk3588.
> 
> When we bind a window from layerM to layerN, we move the old window
> on layerN to layerM.
> 
> Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
> Tested-by: Derek Foreman <derek.foreman at collabora.com>
> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>

> +		/*
> +		 * Find the win bind to this layer in old state
> +		 */
> +		for (i = 0; i < vop2->data->win_size; i++) {
> +			old_win = &vop2->win[i];
> +			layer_sel_id = (layer_sel >> (4 * (plane->state->normalized_zpos + ofs))) & 0xf;

checkpatch is unhappy about the length of this line (104 characters).
Could you please restructure it (helper var or line break)
so that it gets below the 100 character mark please?

Thanks a lot
Heiko




From andrew at lunn.ch  Tue Dec 10 15:11:10 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 11 Dec 2024 00:11:10 +0100
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <6758c174.050a0220.52a35.06bc@mx.google.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241210211529.osgzd54flq646bcr@skbuf>
 <6758c174.050a0220.52a35.06bc@mx.google.com>
Message-ID: <beb50a2b-1d3e-4c34-821c-e4f93767cb5d@lunn.ch>

> Doesn't regmap add lots of overhead tho?

Compared to what. MDIO operates over a 2.5MHz bus, assuming it is true
MDIO. The CPU overhead of regmap is probably negligible compared to
waiting for MDIO transactions to finish.

	Andrew


From heiko at sntech.de  Tue Dec 10 15:12:58 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 11 Dec 2024 00:12:58 +0100
Subject: (subset) [PATCH v5 00/18] VOP Support for rk3576
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <173387236508.2374456.8629854054013827389.b4-ty@sntech.de>


On Mon, 09 Dec 2024 20:29:10 +0800, Andy Yan wrote:
> Thanks for the basic work from Collabora, I can bringup a HDMI
> display out on rk3576.
> 
> PATCH 1 is a carryover from the working when add support for
>     rk3588[0], is very usefull when some people want me
>     help debug some issue online, so I really hope it can
>     be merged at this round.
> PATCH 2~8 are bugfix of rk3588 alpha blending which report and
>     test by Derek
> PATCH 9~13 are preparations for rk3576 support
> PATCH 17~18 are real support for rk376
> 
> [...]

Applied, thanks!

[02/18] drm/rockchip: vop2: Fix cluster windows alpha ctrl regsiters offset
        commit: 17b4b10a0df1a1421d5fbdc03bad0bd3799bc966
[03/18] drm/rockchip: vop2: Fix the mixer alpha setup for layer 0
        commit: 6b4dfdcde3573a12b72d2869dabd4ca37ad7e9c7

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Tue Dec 10 15:12:59 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 11 Dec 2024 00:12:59 +0100
Subject: [PATCH v4 0/3] drm/rockchip: Add driver for the new DSI2 controller
In-Reply-To: <20241209231021.2180582-1-heiko@sntech.de>
References: <20241209231021.2180582-1-heiko@sntech.de>
Message-ID: <173387236506.2374456.5462991780228290808.b4-ty@sntech.de>


On Tue, 10 Dec 2024 00:10:18 +0100, Heiko Stuebner wrote:
> This series adds a bridge and glue driver for the DSI2 controller found
> in the rk3588 soc from Rockchip, that is based on a Synopsis IP block.
> 
> As the manual states:
> The Display Serial Interface 2 (DSI-2) is part of a group of communication
> protocols defined by the MIPI Alliance. The MIPI DSI-2 Host Controller is
> a digital core that implements all protocol functions defined in the
> MIPI DSI-2 Specification.
> 
> [...]

Applied, thanks!

[1/3] drm/bridge/synopsys: Add MIPI DSI2 host controller bridge
      commit: 0d6d86253fef1e6b1e38a54db14bcbea9d0d9ca4
[2/3] dt-bindings: display: rockchip: Add schema for RK3588 DW DSI2 controller
      commit: 77889f2baadc856a26eef4ed601e5e277d0518b5
[3/3] drm/rockchip: Add MIPI DSI2 glue driver for RK3588
      commit: 9f1e1e14f59de8e5a62226840abecbcdbd50221a

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From cristian.ciocaltea at collabora.com  Tue Dec 10 15:06:15 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 01:06:15 +0200
Subject: [PATCH v2 2/4] arm64: dts: rockchip: Add PHY node for HDMI1 TX
 port on RK3588
In-Reply-To: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
Message-ID: <20241211-rk3588-hdmi1-v2-2-02cdca22ff68@collabora.com>

In preparation to enable the second HDMI output port found on RK3588
SoC, add the related PHY node.  This requires a GRF, hence add the
dependent node as well.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
index 0ce0934ec6b793af45585f67d5312434d80357de..68fa9806164776cef8732bb776e958003779ba28 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -67,6 +67,11 @@ u2phy1_otg: otg-port {
 		};
 	};
 
+	hdptxphy1_grf: syscon at fd5e4000 {
+		compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
+		reg = <0x0 0xfd5e4000 0x0 0x100>;
+	};
+
 	i2s8_8ch: i2s at fddc8000 {
 		compatible = "rockchip,rk3588-i2s-tdm";
 		reg = <0x0 0xfddc8000 0x0 0x1000>;
@@ -395,6 +400,22 @@ sata-port at 0 {
 		};
 	};
 
+	hdptxphy1: phy at fed70000 {
+		compatible = "rockchip,rk3588-hdptx-phy";
+		reg = <0x0 0xfed70000 0x0 0x2000>;
+		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>;
+		clock-names = "ref", "apb";
+		#phy-cells = <0>;
+		resets = <&cru SRST_HDPTX1>, <&cru SRST_P_HDPTX1>,
+			 <&cru SRST_HDPTX1_INIT>, <&cru SRST_HDPTX1_CMN>,
+			 <&cru SRST_HDPTX1_LANE>, <&cru SRST_HDPTX1_ROPLL>,
+			 <&cru SRST_HDPTX1_LCPLL>;
+		reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
+			      "lcpll";
+		rockchip,grf = <&hdptxphy1_grf>;
+		status = "disabled";
+	};
+
 	usbdp_phy1: phy at fed90000 {
 		compatible = "rockchip,rk3588-usbdp-phy";
 		reg = <0x0 0xfed90000 0x0 0x10000>;

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Tue Dec 10 15:06:14 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 01:06:14 +0200
Subject: [PATCH v2 1/4] drm/rockchip: dw_hdmi_qp: Add support for RK3588
 HDMI1 output
In-Reply-To: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
Message-ID: <20241211-rk3588-hdmi1-v2-1-02cdca22ff68@collabora.com>

Provide the basic support required to enable the second HDMI TX port
found on RK3588 SoC.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 119 ++++++++++++++++++++-----
 1 file changed, 96 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index c8b362cc2b95fd490029a9c0552ad9fbc5631d17..c36fc130b73440c9e3f2098f408a5cdd2f58e8ef 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -28,20 +28,26 @@
 #define RK3588_GRF_SOC_CON2		0x0308
 #define RK3588_HDMI0_HPD_INT_MSK	BIT(13)
 #define RK3588_HDMI0_HPD_INT_CLR	BIT(12)
+#define RK3588_HDMI1_HPD_INT_MSK	BIT(15)
+#define RK3588_HDMI1_HPD_INT_CLR	BIT(14)
 #define RK3588_GRF_SOC_CON7		0x031c
 #define RK3588_SET_HPD_PATH_MASK	GENMASK(13, 12)
 #define RK3588_GRF_SOC_STATUS1		0x0384
 #define RK3588_HDMI0_LEVEL_INT		BIT(16)
+#define RK3588_HDMI1_LEVEL_INT		BIT(24)
 #define RK3588_GRF_VO1_CON3		0x000c
+#define RK3588_GRF_VO1_CON6		0x0018
 #define RK3588_SCLIN_MASK		BIT(9)
 #define RK3588_SDAIN_MASK		BIT(10)
 #define RK3588_MODE_MASK		BIT(11)
 #define RK3588_I2S_SEL_MASK		BIT(13)
 #define RK3588_GRF_VO1_CON9		0x0024
 #define RK3588_HDMI0_GRANT_SEL		BIT(10)
+#define RK3588_HDMI1_GRANT_SEL		BIT(12)
 
 #define HIWORD_UPDATE(val, mask)	((val) | (mask) << 16)
 #define HOTPLUG_DEBOUNCE_MS		150
+#define MAX_HDMI_PORT_NUM		2
 
 struct rockchip_hdmi_qp {
 	struct device *dev;
@@ -53,6 +59,7 @@ struct rockchip_hdmi_qp {
 	struct phy *phy;
 	struct gpio_desc *enable_gpio;
 	struct delayed_work hpd_work;
+	int port_id;
 };
 
 static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder)
@@ -127,20 +134,24 @@ dw_hdmi_qp_rk3588_read_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
 	u32 val;
 
 	regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &val);
+	val &= hdmi->port_id ? RK3588_HDMI1_LEVEL_INT : RK3588_HDMI0_LEVEL_INT;
 
-	return val & RK3588_HDMI0_LEVEL_INT ?
-		connector_status_connected : connector_status_disconnected;
+	return val ? connector_status_connected : connector_status_disconnected;
 }
 
 static void dw_hdmi_qp_rk3588_setup_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
 {
 	struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data;
+	u32 val;
+
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR,
+				    RK3588_HDMI1_HPD_INT_CLR | RK3588_HDMI1_HPD_INT_MSK);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
+				    RK3588_HDMI0_HPD_INT_CLR | RK3588_HDMI0_HPD_INT_MSK);
 
-	regmap_write(hdmi->regmap,
-		     RK3588_GRF_SOC_CON2,
-		     HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
-				   RK3588_HDMI0_HPD_INT_CLR |
-				   RK3588_HDMI0_HPD_INT_MSK));
+	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 }
 
 static const struct dw_hdmi_qp_phy_ops rk3588_hdmi_phy_ops = {
@@ -173,8 +184,12 @@ static irqreturn_t dw_hdmi_qp_rk3588_hardirq(int irq, void *dev_id)
 	regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
 
 	if (intr_stat) {
-		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK,
-				    RK3588_HDMI0_HPD_INT_MSK);
+		if (hdmi->port_id)
+			val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK,
+					    RK3588_HDMI1_HPD_INT_MSK);
+		else
+			val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK,
+					    RK3588_HDMI0_HPD_INT_MSK);
 		regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 		return IRQ_WAKE_THREAD;
 	}
@@ -191,22 +206,44 @@ static irqreturn_t dw_hdmi_qp_rk3588_irq(int irq, void *dev_id)
 	if (!intr_stat)
 		return IRQ_NONE;
 
-	val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
-			    RK3588_HDMI0_HPD_INT_CLR);
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR,
+				    RK3588_HDMI1_HPD_INT_CLR);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
+				    RK3588_HDMI0_HPD_INT_CLR);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 
 	mod_delayed_work(system_wq, &hdmi->hpd_work,
 			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
 
-	val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK);
+	if (hdmi->port_id)
+		val |= HIWORD_UPDATE(0, RK3588_HDMI1_HPD_INT_MSK);
+	else
+		val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 
 	return IRQ_HANDLED;
 }
 
+struct rockchip_hdmi_qp_cfg {
+	unsigned int num_ports;
+	unsigned int port_ids[MAX_HDMI_PORT_NUM];
+	const struct dw_hdmi_qp_phy_ops *phy_ops;
+};
+
+static const struct rockchip_hdmi_qp_cfg rk3588_hdmi_cfg = {
+	.num_ports = 2,
+	.port_ids = {
+		0xfde80000,
+		0xfdea0000,
+	},
+	.phy_ops = &rk3588_hdmi_phy_ops,
+};
+
 static const struct of_device_id dw_hdmi_qp_rockchip_dt_ids[] = {
 	{ .compatible = "rockchip,rk3588-dw-hdmi-qp",
-	  .data = &rk3588_hdmi_phy_ops },
+	  .data = &rk3588_hdmi_cfg },
 	{},
 };
 MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids);
@@ -219,11 +256,13 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 		"ref" /* keep "ref" last */
 	};
 	struct platform_device *pdev = to_platform_device(dev);
+	const struct rockchip_hdmi_qp_cfg *cfg;
 	struct dw_hdmi_qp_plat_data plat_data;
 	struct drm_device *drm = data;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
 	struct rockchip_hdmi_qp *hdmi;
+	struct resource *res;
 	struct clk *clk;
 	int ret, irq, i;
 	u32 val;
@@ -235,12 +274,31 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 	if (!hdmi)
 		return -ENOMEM;
 
-	plat_data.phy_ops = of_device_get_match_data(dev);
-	if (!plat_data.phy_ops)
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
 		return -ENODEV;
 
-	plat_data.phy_data = hdmi;
 	hdmi->dev = &pdev->dev;
+	hdmi->port_id = -ENODEV;
+
+	/* Identify port ID by matching base IO address */
+	for (i = 0; i < cfg->num_ports; i++) {
+		if (res->start == cfg->port_ids[i]) {
+			hdmi->port_id = i;
+			break;
+		}
+	}
+	if (hdmi->port_id < 0) {
+		drm_err(hdmi, "Failed to match HDMI port ID\n");
+		return hdmi->port_id;
+	}
+
+	plat_data.phy_ops = cfg->phy_ops;
+	plat_data.phy_data = hdmi;
 
 	encoder = &hdmi->encoder.encoder;
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
@@ -303,17 +361,26 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 	      HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
 	      HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
 	      HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
-	regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON3, val);
+	regmap_write(hdmi->vo_regmap,
+		     hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
+		     val);
 
 	val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
 			    RK3588_SET_HPD_PATH_MASK);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
 
-	val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
-			    RK3588_HDMI0_GRANT_SEL);
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL,
+				    RK3588_HDMI1_GRANT_SEL);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
+				    RK3588_HDMI0_GRANT_SEL);
 	regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
 
-	val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK);
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK, RK3588_HDMI1_HPD_INT_MSK);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 
 	INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_qp_rk3588_hpd_work);
@@ -391,14 +458,20 @@ static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev)
 	      HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
 	      HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
 	      HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
-	regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON3, val);
+	regmap_write(hdmi->vo_regmap,
+		     hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
+		     val);
 
 	val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
 			    RK3588_SET_HPD_PATH_MASK);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
 
-	val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
-			    RK3588_HDMI0_GRANT_SEL);
+	if (hdmi->port_id)
+		val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL,
+				    RK3588_HDMI1_GRANT_SEL);
+	else
+		val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
+				    RK3588_HDMI0_GRANT_SEL);
 	regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
 
 	dw_hdmi_qp_resume(dev, hdmi->hdmi);

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Tue Dec 10 15:06:16 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 01:06:16 +0200
Subject: [PATCH v2 3/4] arm64: dts: rockchip: Add HDMI1 node on RK3588
In-Reply-To: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
Message-ID: <20241211-rk3588-hdmi1-v2-3-02cdca22ff68@collabora.com>

Add support for the second HDMI TX port found on RK3588 SoC.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi | 41 ++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
index 68fa9806164776cef8732bb776e958003779ba28..528319908247e90b33f9dbde0516f8bca849676f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -140,6 +140,47 @@ i2s10_8ch: i2s at fde00000 {
 		status = "disabled";
 	};
 
+	hdmi1: hdmi at fdea0000 {
+		compatible = "rockchip,rk3588-dw-hdmi-qp";
+		reg = <0x0 0xfdea0000 0x0 0x20000>;
+		clocks = <&cru PCLK_HDMITX1>,
+			 <&cru CLK_HDMITX1_EARC>,
+			 <&cru CLK_HDMITX1_REF>,
+			 <&cru MCLK_I2S6_8CH_TX>,
+			 <&cru CLK_HDMIHDP1>,
+			 <&cru HCLK_VO1>;
+		clock-names = "pclk", "earc", "ref", "aud", "hdp", "hclk_vo1";
+		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "avp", "cec", "earc", "main", "hpd";
+		phys = <&hdptxphy1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdmim2_tx1_cec &hdmim0_tx1_hpd
+			     &hdmim1_tx1_scl &hdmim1_tx1_sda>;
+		power-domains = <&power RK3588_PD_VO1>;
+		resets = <&cru SRST_HDMITX1_REF>, <&cru SRST_HDMIHDP1>;
+		reset-names = "ref", "hdp";
+		rockchip,grf = <&sys_grf>;
+		rockchip,vo-grf = <&vo1_grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi1_in: port at 0 {
+				reg = <0>;
+			};
+
+			hdmi1_out: port at 1 {
+				reg = <1>;
+			};
+		};
+	};
+
 	pcie3x4: pcie at fe150000 {
 		compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
 		#address-cells = <3>;

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Tue Dec 10 15:06:17 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 01:06:17 +0200
Subject: [PATCH v2 4/4] arm64: dts: rockchip: Enable HDMI1 on rock-5b
In-Reply-To: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
Message-ID: <20241211-rk3588-hdmi1-v2-4-02cdca22ff68@collabora.com>

Add the necessary DT changes to enable the second HDMI output port on
Radxa ROCK 5B.

While at it, switch the position of &vop_mmu and @vop to maintain the
alphabetical order.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 44 +++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index c44d001da16978bbbb8a93d652893a786e9ea79b..9c3793d394a6f226bbbd3a88381974ea01ca7069 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -49,6 +49,17 @@ hdmi0_con_in: endpoint {
 		};
 	};
 
+	hdmi1-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi1_con_in: endpoint {
+				remote-endpoint = <&hdmi1_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -220,10 +231,32 @@ hdmi0_out_con: endpoint {
 	};
 };
 
+&hdmi1 {
+	pinctrl-0 = <&hdmim0_tx1_cec &hdmim0_tx1_hpd
+		     &hdmim1_tx1_scl &hdmim1_tx1_sda>;
+	status = "okay";
+};
+
+&hdmi1_in {
+	hdmi1_in_vp1: endpoint {
+		remote-endpoint = <&vp1_out_hdmi1>;
+	};
+};
+
+&hdmi1_out {
+	hdmi1_out_con: endpoint {
+		remote-endpoint = <&hdmi1_con_in>;
+	};
+};
+
 &hdptxphy_hdmi0 {
 	status = "okay";
 };
 
+&hdptxphy1 {
+	status = "okay";
+};
+
 &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0m2_xfer>;
@@ -891,11 +924,11 @@ &usb_host2_xhci {
 	status = "okay";
 };
 
-&vop_mmu {
+&vop {
 	status = "okay";
 };
 
-&vop {
+&vop_mmu {
 	status = "okay";
 };
 
@@ -905,3 +938,10 @@ vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
 		remote-endpoint = <&hdmi0_in_vp0>;
 	};
 };
+
+&vp1 {
+	vp1_out_hdmi1: endpoint at ROCKCHIP_VOP2_EP_HDMI1 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI1>;
+		remote-endpoint = <&hdmi1_in_vp1>;
+	};
+};

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Tue Dec 10 15:18:22 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 01:18:22 +0200
Subject: [PATCH 0/4] Add support for HDMI1 output on RK3588 SoC
In-Reply-To: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
References: <20241207-rk3588-hdmi1-v1-0-ca3a99b46a40@collabora.com>
Message-ID: <b15c0a3b-36dc-49f8-9dfc-4bac5beece9a@collabora.com>

On 12/7/24 11:32 PM, Cristian Ciocaltea wrote:
> The patches provide the basic support to handle the second HDMI output
> port found on Rockchip RK3588 SoC.
> 
> For now I enabled it on Radxa ROCK 5B only, the board I've been using to
> validate this.

Please ignore this revision and use v2 [1] instead, as it fixes a pin 
conflict issue occurring when having CONFIG_SPI_ROCKCHIP_SFC enabled.

Thanks,
Cristian

[1] https://lore.kernel.org/all/20241211-rk3588-hdmi1-v2-0-02cdca22ff68 at collabora.com/


From alexandre.belloni at bootlin.com  Tue Dec 10 15:25:57 2024
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Wed, 11 Dec 2024 00:25:57 +0100
Subject: [PATCH v6 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support
In-Reply-To: <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
References: <20241206070955.1503412-1-ciprianmarian.costea@oss.nxp.com>
 <20241206070955.1503412-3-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241210232557fee4e108@mail.local>

On 06/12/2024 09:09:53+0200, Ciprian Costea wrote:
> +/*
> + * S32G2 and S32G3 SoCs have RTC clock source1 reserved and
> + * should not be used.
> + */
> +#define RTC_CLK_SRC1_RESERVED		BIT(1)
> +
> +enum {
> +	DIV1 = 1,
> +	DIV32 = 32,
> +	DIV512 = 512,
> +	DIV512_32 = 16384
> +};
> +
> +static const char *rtc_clk_src[RTC_CLK_MUX_SIZE] = {
> +	"source0",
> +	"source1",
> +	"source2",
> +	"source3"
> +};
> +
> +struct rtc_time_base {
> +	s64 sec;
> +	u64 cycles;
> +	struct rtc_time tm;

I don't think storing an rtc_time is necessary. I don't even think
cycles is necessary.

> +};
> +
> +struct rtc_priv {
> +	struct rtc_device *rdev;
> +	void __iomem *rtc_base;
> +	struct clk *ipg;
> +	struct clk *clk_src;
> +	const struct rtc_soc_data *rtc_data;
> +	struct rtc_time_base base;
> +	u64 rtc_hz;
> +	int irq;
> +	int clk_src_idx;
> +};
> +
> +struct rtc_soc_data {
> +	u32 clk_div;
> +	u32 reserved_clk_mask;
> +};
> +
> +static const struct rtc_soc_data rtc_s32g2_data = {
> +	.clk_div = DIV512,

If you input clock rate is higher that 16kHz, why don't you divide by
16384?

> +	.reserved_clk_mask = RTC_CLK_SRC1_RESERVED,
> +};
> +
> +static u64 cycles_to_sec(u64 hz, u64 cycles)
> +{
> +	return div_u64(cycles, hz);
> +}
> +
> +/**
> + * sec_to_rtcval - Convert a number of seconds to a value suitable for
> + * RTCVAL in our clock's
> + * current configuration.
> + * @priv: Pointer to the 'rtc_priv' structure
> + * @seconds: Number of seconds to convert
> + * @rtcval: The value to go into RTCVAL[RTCVAL]
> + *
> + * Return: 0 for success, -EINVAL if @seconds push the counter past the
> + *          32bit register range
> + */
> +static int sec_to_rtcval(const struct rtc_priv *priv,
> +			 unsigned long seconds, u32 *rtcval)
> +{
> +	u32 delta_cnt;
> +
> +	if (!seconds || seconds > cycles_to_sec(priv->rtc_hz, RTCCNT_MAX_VAL))
> +		return -EINVAL;
> +
> +	/*
> +	 * RTCCNT is read-only; we must return a value relative to the
> +	 * current value of the counter (and hope we don't linger around
> +	 * too much before we get to enable the interrupt)
> +	 */
> +	delta_cnt = seconds * priv->rtc_hz;
> +	*rtcval = delta_cnt + ioread32(priv->rtc_base + RTCCNT_OFFSET);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t s32g_rtc_handler(int irq, void *dev)
> +{
> +	struct rtc_priv *priv = platform_get_drvdata(dev);
> +	u32 status;
> +
> +	status = ioread32(priv->rtc_base + RTCS_OFFSET);
> +
> +	if (status & RTCS_RTCF) {
> +		iowrite32(0x0, priv->rtc_base + RTCVAL_OFFSET);
> +		iowrite32(status | RTCS_RTCF, priv->rtc_base + RTCS_OFFSET);
> +		rtc_update_irq(priv->rdev, 1, RTC_AF);
> +	}
> +
> +	if (status & RTCS_APIF) {
> +		iowrite32(status | RTCS_APIF, priv->rtc_base + RTCS_OFFSET);
> +		rtc_update_irq(priv->rdev, 1, RTC_PF);

I don't think you use APIF as a periodic interrupt so it doesn't really
make sense to use RTC_PF instead of RTC_AF.

> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static s64 s32g_rtc_get_time_or_alrm(struct rtc_priv *priv,
> +				     u32 offset)
> +{
> +	u32 counter;
> +
> +	counter = ioread32(priv->rtc_base + offset);
> +
> +	if (counter < priv->base.cycles)
> +		return -EINVAL;
> +
> +	counter -= priv->base.cycles;
> +
> +	return priv->base.sec + cycles_to_sec(priv->rtc_hz, counter);
> +}
> +
> +static int s32g_rtc_read_time(struct device *dev,
> +			      struct rtc_time *tm)
> +{
> +	struct rtc_priv *priv = dev_get_drvdata(dev);
> +	s64 sec;
> +
> +	sec = s32g_rtc_get_time_or_alrm(priv, RTCCNT_OFFSET);
> +	if (sec < 0)
> +		return -EINVAL;
> +
> +	rtc_time64_to_tm(sec, tm);
> +
> +	return 0;
> +}
> +
> +static int s32g_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct rtc_priv *priv = dev_get_drvdata(dev);
> +	u32 rtcc, rtccnt, rtcval;
> +	s64 sec;
> +
> +	sec = s32g_rtc_get_time_or_alrm(priv, RTCVAL_OFFSET);
> +	if (sec < 0)
> +		return -EINVAL;
> +
> +	rtc_time64_to_tm(sec, &alrm->time);
> +
> +	rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
> +	alrm->enabled = sec && (rtcc & RTCC_RTCIE);
> +
> +	alrm->pending = 0;
> +	if (alrm->enabled) {
> +		rtccnt = ioread32(priv->rtc_base + RTCCNT_OFFSET);
> +		rtcval = ioread32(priv->rtc_base + RTCVAL_OFFSET);
> +
> +		if (rtccnt < rtcval)
> +			alrm->pending = 1;

This limits the range of your alarm, why don't you simply check whether
RTCF is set?

> +	}
> +
> +	return 0;
> +}
> +
> +static int s32g_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
> +{
> +	struct rtc_priv *priv = dev_get_drvdata(dev);
> +	u32 rtcc;
> +
> +	if (!priv->irq)
> +		return -EIO;


This will never happen as you are not letting probe finish when you
can't request the irq.


> +
> +	rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
> +	if (enabled)
> +		rtcc |= RTCC_RTCIE;
> +
> +	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
> +
> +	return 0;
> +}
> +
> +static int s32g_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct rtc_priv *priv = dev_get_drvdata(dev);
> +	struct rtc_time time_crt;
> +	long long t_crt, t_alrm;
> +	u32 rtcval, rtcs;
> +	int ret = 0;
> +
> +	iowrite32(0x0, priv->rtc_base + RTCVAL_OFFSET);
> +
> +	t_alrm = rtc_tm_to_time64(&alrm->time);
> +
> +	/*
> +	 * Assuming the alarm is being set relative to the same time
> +	 * returned by our s32g_rtc_read_time callback
> +	 */
> +	ret = s32g_rtc_read_time(dev, &time_crt);
> +	if (ret)
> +		return ret;
> +
> +	t_crt = rtc_tm_to_time64(&time_crt);
> +	ret = sec_to_rtcval(priv, t_alrm - t_crt, &rtcval);
> +	if (ret) {
> +		dev_warn(dev, "Alarm is set too far in the future\n");
> +		return -ERANGE;
> +	}
> +
> +	ret = read_poll_timeout(ioread32, rtcs, !(rtcs & RTCS_INV_RTC),
> +				0, RTC_SYNCH_TIMEOUT, false, priv->rtc_base + RTCS_OFFSET);
> +	if (ret)
> +		return ret;
> +
> +	iowrite32(rtcval, priv->rtc_base + RTCVAL_OFFSET);
> +
> +	return 0;
> +}
> +
> +static int s32g_rtc_set_time(struct device *dev,
> +			     struct rtc_time *time)
> +{
> +	struct rtc_priv *priv = dev_get_drvdata(dev);
> +
> +	priv->base.cycles = ioread32(priv->rtc_base + RTCCNT_OFFSET);
> +	priv->base.sec = rtc_tm_to_time64(time);
> +

To simplify all the calculations you are doing, I suggest you reset
RTCCNT here and store the epoch of the rtc as a number of seconds.

This wll allow you to avoid having to read the counter in set_alarm
also, you then get a direct conversion for RTCVAL as this will simply be
rtc_tm_to_time64(&alrm->time) - epoch that you have to convert in cycles

You will also then know right away whether this is too large to fit in a
32bit register.


> +	return 0;
> +}
> +
> +/*
> + * Disable the 32-bit free running counter.
> + * This allows Clock Source and Divisors selection
> + * to be performed without causing synchronization issues.
> + */
> +static void s32g_rtc_disable(struct rtc_priv *priv)
> +{
> +	u32 rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
> +
> +	rtcc &= ~RTCC_CNTEN;
> +	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
> +}
> +
> +static void s32g_rtc_enable(struct rtc_priv *priv)
> +{
> +	u32 rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
> +
> +	rtcc |= RTCC_CNTEN;
> +	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
> +}
> +
> +static int rtc_clk_src_setup(struct rtc_priv *priv)
> +{
> +	u32 rtcc = 0;
> +
> +	if (priv->rtc_data->reserved_clk_mask & (1 << priv->clk_src_idx))
> +		return -EOPNOTSUPP;
> +
> +	rtcc = FIELD_PREP(RTCC_CLKSEL_MASK, priv->clk_src_idx);
> +
> +	switch (priv->rtc_data->clk_div) {
> +	case DIV512_32:
> +		rtcc |= RTCC_DIV512EN;
> +		rtcc |= RTCC_DIV32EN;
> +		break;
> +	case DIV512:
> +		rtcc |= RTCC_DIV512EN;
> +		break;
> +	case DIV32:
> +		rtcc |= RTCC_DIV32EN;
> +		break;
> +	case DIV1:
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	rtcc |= RTCC_RTCIE;
> +	/*
> +	 * Make sure the CNTEN is 0 before we configure
> +	 * the clock source and dividers.
> +	 */
> +	s32g_rtc_disable(priv);
> +	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
> +	s32g_rtc_enable(priv);
> +
> +	return 0;
> +}
> +
> +static const struct rtc_class_ops rtc_ops = {
> +	.read_time = s32g_rtc_read_time,
> +	.set_time = s32g_rtc_set_time,
> +	.read_alarm = s32g_rtc_read_alarm,
> +	.set_alarm = s32g_rtc_set_alarm,
> +	.alarm_irq_enable = s32g_rtc_alarm_irq_enable,
> +};
> +
> +static int rtc_clk_dts_setup(struct rtc_priv *priv,
> +			     struct device *dev)
> +{
> +	int i;
> +
> +	priv->ipg = devm_clk_get_enabled(dev, "ipg");
> +	if (IS_ERR(priv->ipg))
> +		return dev_err_probe(dev, PTR_ERR(priv->ipg),
> +				"Failed to get 'ipg' clock\n");
> +
> +	for (i = 0; i < RTC_CLK_MUX_SIZE; i++) {
> +		priv->clk_src = devm_clk_get_enabled(dev, rtc_clk_src[i]);
> +		if (!IS_ERR(priv->clk_src)) {
> +			priv->clk_src_idx = i;
> +			break;
> +		}
> +	}
> +
> +	if (IS_ERR(priv->clk_src))
> +		return dev_err_probe(dev, PTR_ERR(priv->clk_src),
> +				"Failed to get rtc module clock source\n");
> +
> +	return 0;
> +}
> +
> +static int s32g_rtc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct rtc_priv *priv;
> +	int ret = 0;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->rtc_data = of_device_get_match_data(dev);
> +	if (!priv->rtc_data)
> +		return -ENODEV;
> +
> +	priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(priv->rtc_base))
> +		return PTR_ERR(priv->rtc_base);
> +
> +	device_init_wakeup(dev, true);
> +
> +	ret = rtc_clk_dts_setup(priv, dev);
> +	if (ret)
> +		return ret;
> +
> +	priv->rdev = devm_rtc_allocate_device(dev);
> +	if (IS_ERR(priv->rdev))
> +		return PTR_ERR(priv->rdev);
> +
> +	ret = rtc_clk_src_setup(priv);
> +	if (ret)
> +		return ret;
> +
> +	priv->rtc_hz = clk_get_rate(priv->clk_src);
> +	if (!priv->rtc_hz) {
> +		dev_err(dev, "Failed to get RTC frequency\n");
> +		ret = -EINVAL;
> +		goto disable_rtc;
> +	}
> +
> +	priv->rtc_hz /= priv->rtc_data->clk_div;
> +
> +	platform_set_drvdata(pdev, priv);
> +	priv->rdev->ops = &rtc_ops;
> +
> +	priv->irq = platform_get_irq(pdev, 0);
> +	if (priv->irq < 0) {
> +		ret = priv->irq;
> +		goto disable_rtc;
> +	}
> +
> +	ret = devm_request_irq(dev, priv->irq,
> +			       s32g_rtc_handler, 0, dev_name(dev), pdev);
> +	if (ret) {
> +		dev_err(dev, "Request interrupt %d failed, error: %d\n",
> +			priv->irq, ret);
> +		goto disable_rtc;
> +	}
> +
> +	ret = devm_rtc_register_device(priv->rdev);
> +	if (ret)
> +		goto disable_rtc;
> +
> +	return 0;
> +
> +disable_rtc:
> +	s32g_rtc_disable(priv);
> +	return ret;
> +}
> +
> +static void s32g_enable_api_irq(struct device *dev, unsigned int enabled)
> +{
> +	struct rtc_priv *priv = dev_get_drvdata(dev);
> +	u32 api_irq = RTCC_APIEN | RTCC_APIIE;
> +	u32 rtcc;
> +
> +	rtcc = ioread32(priv->rtc_base + RTCC_OFFSET);
> +	if (enabled)
> +		rtcc |= api_irq;
> +	else
> +		rtcc &= ~api_irq;
> +	iowrite32(rtcc, priv->rtc_base + RTCC_OFFSET);
> +}
> +
> +static int s32g_rtc_suspend(struct device *dev)
> +{
> +	struct rtc_priv *init_priv = dev_get_drvdata(dev);
> +	struct rtc_priv priv;
> +	long long base_sec;
> +	u32 rtcval, rtccnt, offset;
> +	int ret = 0;
> +	u32 sec;
> +
> +	if (!device_may_wakeup(dev))
> +		return 0;
> +
> +	/* Save last known timestamp */
> +	ret = s32g_rtc_read_time(dev, &init_priv->base.tm);
> +	if (ret)
> +		return ret;

I don't think that whole calculation is necessary as you are never
actually resetting RTCCNT in suspend

> +
> +	/*
> +	 * Use a local copy of the RTC control block to
> +	 * avoid restoring it on resume path.
> +	 */
> +	memcpy(&priv, init_priv, sizeof(priv));
> +
> +	rtccnt = ioread32(init_priv->rtc_base + RTCCNT_OFFSET);
> +	rtcval = ioread32(init_priv->rtc_base + RTCVAL_OFFSET);
> +	offset = rtcval - rtccnt;
> +	sec = cycles_to_sec(init_priv->rtc_hz, offset);
> +
> +	/* Adjust for the number of seconds we'll be asleep */
> +	base_sec = rtc_tm_to_time64(&init_priv->base.tm);
> +	base_sec += sec;
> +	rtc_time64_to_tm(base_sec, &init_priv->base.tm);
> +
> +	ret = sec_to_rtcval(&priv, sec, &rtcval);
> +	if (ret) {
> +		dev_warn(dev, "Alarm is too far in the future\n");
> +		return -ERANGE;
> +	}
> +
> +	s32g_enable_api_irq(dev, 1);
> +	iowrite32(offset, priv.rtc_base + APIVAL_OFFSET);

What about always using APIVAL instead of RTCVAL so you don't have
anything to do in s32g_rtc_suspend.


> +
> +	return ret;
> +}
> +
> +static int s32g_rtc_resume(struct device *dev)
> +{
> +	struct rtc_priv *priv = dev_get_drvdata(dev);
> +	int ret;
> +
> +	if (!device_may_wakeup(dev))
> +		return 0;
> +
> +	/* Disable wake-up interrupts */
> +	s32g_enable_api_irq(dev, 0);
> +
> +	ret = rtc_clk_src_setup(priv);
> +	if (ret)
> +		return ret;

I don't think this is necessary.
> +
> +	/*
> +	 * Now RTCCNT has just been reset, and is out of sync with priv->base;
> +	 * reapply the saved time settings.
> +	 */
> +	return s32g_rtc_set_time(dev, &priv->base.tm);

And so this is useless too so yo udon't actually have anything to do in
s32g_rtc_resume.

> +}
> +
> +static const struct of_device_id rtc_dt_ids[] = {
> +	{ .compatible = "nxp,s32g2-rtc", .data = &rtc_s32g2_data},
> +	{ /* sentinel */ },
> +};
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(s32g_rtc_pm_ops,
> +			 s32g_rtc_suspend, s32g_rtc_resume);
> +
> +static struct platform_driver s32g_rtc_driver = {
> +	.driver		= {
> +		.name			= "s32g-rtc",
> +		.pm				= pm_sleep_ptr(&s32g_rtc_pm_ops),
> +		.of_match_table = rtc_dt_ids,
> +	},
> +	.probe		= s32g_rtc_probe,
> +};
> +module_platform_driver(s32g_rtc_driver);
> +
> +MODULE_AUTHOR("NXP");
> +MODULE_DESCRIPTION("NXP RTC driver for S32G2/S32G3");
> +MODULE_LICENSE("GPL");
> -- 
> 2.45.2
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From xiaolei.wang at windriver.com  Tue Dec 10 15:36:13 2024
From: xiaolei.wang at windriver.com (Xiaolei Wang)
Date: Wed, 11 Dec 2024 07:36:13 +0800
Subject: [PATCH v3] serial: imx: Use uart_port_lock_irq() instead of uart_port_lock()
Message-ID: <20241210233613.2881264-1-xiaolei.wang@windriver.com>

When executing 'echo mem > /sys/power/state', the following
deadlock occurs. Since there is output during the serial
port entering the suspend process, the suspend will be
interrupted, resulting in the nesting of locks. Therefore,
use uart_port_lock_irq() instead of uart_port_unlock().

WARNING: inconsistent lock state
6.12.0-rc2-00002-g3c199ed5bd64-dirty #23 Not tainted
--------------------------------
inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
sh/494 [HC0[0]:SC0[0]:HE1:SE1] takes:
c4db5850 (&port_lock_key){?.-.}-{3:3}, at: imx_uart_enable_wakeup+0x14/0x254
{IN-HARDIRQ-W} state was registered at:
  lock_acquire+0x104/0x348
  _raw_spin_lock+0x48/0x84
  imx_uart_int+0x14/0x4dc
  __handle_irq_event_percpu+0xac/0x2fc
  handle_irq_event_percpu+0xc/0x40
  handle_irq_event+0x38/0x8c
  handle_fasteoi_irq+0xb4/0x1b8
  handle_irq_desc+0x1c/0x2c
  gic_handle_irq+0x6c/0xa0
  generic_handle_arch_irq+0x2c/0x64
  call_with_stack+0x18/0x20
  __irq_svc+0x9c/0xbc
  _raw_spin_unlock_irqrestore+0x2c/0x48
  uart_write+0xd8/0x3a0
  do_output_char+0x1a8/0x1e4
  n_tty_write+0x224/0x440
  file_tty_write.constprop.0+0x124/0x250
  do_iter_readv_writev+0x100/0x1e0
  vfs_writev+0xc4/0x448
  do_writev+0x68/0xf8
  ret_fast_syscall+0x0/0x1c
irq event stamp: 31593
hardirqs last  enabled at (31593): [<c1150e48>] _raw_spin_unlock_irqrestore+0x44/0x48
hardirqs last disabled at (31592): [<c07f32f0>] clk_enable_lock+0x60/0x120
softirqs last  enabled at (30334): [<c012d1d4>] handle_softirqs+0x2cc/0x478
softirqs last disabled at (30325): [<c012d510>] __irq_exit_rcu+0x120/0x15c

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&port_lock_key);
  <Interrupt>
    lock(&port_lock_key);

Fixes: 3c199ed5bd64 ("serial: imx: Grab port lock in imx_uart_enable_wakeup()")
Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>
Reviewed-by: Lucas Stach <l.stach at pengutronix.de>
Reviewed-by: Fabio Estevam <festevam at gmail.com>
---

v1:
  https://patchwork.kernel.org/project/linux-arm-kernel/patch/20241209124732.693834-1-xiaolei.wang at windriver.com/
v2:
  use uart_port_lock_irq() instead of uart_port_lock_irqsave()
v3:
  update commit log 'ehco --> echo'

 drivers/tty/serial/imx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 17f70e4bee43..9c59ec128bb4 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2692,7 +2692,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
 {
 	u32 ucr3;
 
-	uart_port_lock(&sport->port);
+	uart_port_lock_irq(&sport->port);
 
 	ucr3 = imx_uart_readl(sport, UCR3);
 	if (on) {
@@ -2714,7 +2714,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
 		imx_uart_writel(sport, ucr1, UCR1);
 	}
 
-	uart_port_unlock(&sport->port);
+	uart_port_unlock_irq(&sport->port);
 }
 
 static int imx_uart_suspend_noirq(struct device *dev)
-- 
2.25.1



From olteanv at gmail.com  Tue Dec 10 15:48:03 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Wed, 11 Dec 2024 01:48:03 +0200
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <6758c174.050a0220.52a35.06bc@mx.google.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241210211529.osgzd54flq646bcr@skbuf>
 <6758c174.050a0220.52a35.06bc@mx.google.com>
Message-ID: <20241210234803.pzm7fxrve4dastth@skbuf>

On Tue, Dec 10, 2024 at 11:32:17PM +0100, Christian Marangi wrote:
> Doesn't regmap add lots of overhead tho? Maybe I should really change
> the switch regmap to apply a save/restore logic?
> 
> With an implementation like that current_page is not needed anymore.
> And I feel additional read/write are ok for switch OP.
> 
> On mdio I can use the parent-mdio-bus property to get the bus directly
> without using MFD priv.
> 
> What do you think?

If performance is a relevant factor at all, it will be hard to measure it, other
than with synthetic tests (various mixes of switch and PHY register access).
Though since you mention it, it would be interesting to see a comparison of the
3 arbitration methods. This could probably be all done from the an8855_mfd_probe()
calling context: read a switch register and a PHY register 100K times and see how
long it took, then read 2 switch registers and a PHY register 100K times, then
3 switch registers.... At some point, we should start seeing the penalty of the
page restoration in Andrew's proposal, because that will be done after each switch
register read. Just curious to put it into perspective and see how soon it starts
to make a difference. And this test will also answer the regmap overhead issue.


From dmitry.baryshkov at linaro.org  Tue Dec 10 15:55:35 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 11 Dec 2024 01:55:35 +0200
Subject: [PATCH v2 1/4] drm/rockchip: dw_hdmi_qp: Add support for RK3588
 HDMI1 output
In-Reply-To: <20241211-rk3588-hdmi1-v2-1-02cdca22ff68@collabora.com>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
 <20241211-rk3588-hdmi1-v2-1-02cdca22ff68@collabora.com>
Message-ID: <vpy4foezirdhci4nvl5j4e7gf5dey3swj7xxzuzazzj6uhqnls@iyyhkpukb7yo>

On Wed, Dec 11, 2024 at 01:06:14AM +0200, Cristian Ciocaltea wrote:
> Provide the basic support required to enable the second HDMI TX port
> found on RK3588 SoC.
> 
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
>  drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 119 ++++++++++++++++++++-----
>  1 file changed, 96 insertions(+), 23 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From naoki at radxa.com  Tue Dec 10 16:04:37 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 11 Dec 2024 09:04:37 +0900
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add USB-C support to ROCK 5B
In-Reply-To: <5mjjq3f3tqu4h2f7wbdcfon6csfsuxge5skr6mmgozvq65uods@66yx7yuefzqn>
References: <20241210163615.120594-1-sebastian.reichel@collabora.com>
 <6A24DF29AE2F3CDC+70602cc7-2c03-470d-955f-06b2db116e20@radxa.com>
 <5mjjq3f3tqu4h2f7wbdcfon6csfsuxge5skr6mmgozvq65uods@66yx7yuefzqn>
Message-ID: <9087FE0C88CD8335+4505c82a-33dd-45cf-941d-aa818068f19c@radxa.com>

Hi Sebastian,

On 12/11/24 08:08, Sebastian Reichel wrote:
> Hello Naoki,
> 
> On Wed, Dec 11, 2024 at 07:10:55AM +0900, FUKAUMI Naoki wrote:
>> Hi Sebastian,
>>
>> Thank you very much for your work!
>>
>> $ cat /sys/class/power_supply/tcpm-source-psy-4-0022/{current_max,current_now,online,type,usb_type,voltage_max,voltage_min,voltage_now}
>> 1500000
>> 1500000
>> 1
>> USB
>> C [PD] PD_PPS
>> 20000000
>> 20000000
>> 20000000
>>
>> $ cat /sys/class/power_supply/tcpm-source-psy-4-0022/{current_max,current_now,online,type,usb_type,voltage_max,voltage_min,voltage_now}
>> 5000000
>> 5000000
>> 1
>> USB
>> C PD [PD_PPS]
>> 20000000
>> 20000000
>> 20000000
>>
>> $ ls /sys/class/udc/
>> fc000000.usb
>>
>> I can configure it as CDC-NCM and host detects it.
>> But I could not use it as a HOST port. How to use it?
> 
> You can switch between host and peripheral for Type-C ports like
> this depending on the remote sides capabilities:
> 
>   * echo host > /sys/class/typec/<port>/data_role
>   * echo device > /sys/class/typec/<port>/data_role

thanks!

I tested both data_role and both orientation. all works.

> I tested this with a USB-C hub connected to the port, which works
> in host mode.
> 
>> some minor nitpick is below:
>>
>> On 12/11/24 01:36, Sebastian Reichel wrote:
>>> Add hardware description for the USB-C port in the Radxa Rock 5 Model B.
>>> This describes the OHCI, EHCI and XHCI USB parts, but not yet the
>>> DisplayPort AltMode (bindings are not yet upstream).
>>>
>>> The fusb302 node is marked with status "fail", since the board is usually
>>> powered through the USB-C port. Handling of errors can result in hard
>>> resets, which removed the bus power for some time resulting in a board
>>> reset.
>>>
>>> The main problem is that devices are supposed to interact with the
>>> power-supply within 5 seconds after the plug event according to the
>>> USB PD specification. This is more or less impossible to achieve when
>>> the kernel is the first software communicating with the power-supply.
>>>
>>> Recent U-Boot (v2025.01) will start doing USB-PD communication, which
>>> solves this issue. Upstream U-Boot doing USB-PD communication will also
>>> set the fusb302 node status to "okay". That way booting a kernel with
>>> the updated DT on an old U-Boot avoids a reset loop.
>>>
>>> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
>>> ---
>>>    .../boot/dts/rockchip/rk3588-rock-5b.dts      | 121 ++++++++++++++++++
>>>    1 file changed, 121 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>>> index d597112f1d5b..cb5990df6ccb 100644
>>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>>> @@ -5,6 +5,7 @@
>>>    #include <dt-bindings/gpio/gpio.h>
>>>    #include <dt-bindings/leds/common.h>
>>>    #include <dt-bindings/soc/rockchip,vop2.h>
>>> +#include <dt-bindings/usb/pd.h>
>>>    #include "rk3588.dtsi"
>>>    / {
>>> @@ -84,6 +85,15 @@ rfkill-bt {
>>>    		shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>>>    	};
>>> +	vcc12v_dcin: regulator-vcc12v-dcin {
>>> +		compatible = "regulator-fixed";
>>> +		regulator-name = "vcc12v_dcin";
>>
>> typec_vin by schematic.
> 
> Ack. Will update in v2.
> 
>>> +		regulator-always-on;
>>> +		regulator-boot-on;
>>> +		regulator-min-microvolt = <12000000>;
>>> +		regulator-max-microvolt = <12000000>;

both microvolt line can be removed.

>>> +	};
>>> +
>>>    	vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 {
>>>    		compatible = "regulator-fixed";
>>>    		enable-active-high;
>>> @@ -142,6 +152,7 @@ vcc5v0_sys: regulator-vcc5v0-sys {
>>>    		regulator-boot-on;
>>>    		regulator-min-microvolt = <5000000>;
>>>    		regulator-max-microvolt = <5000000>;
>>> +		vin-supply = <&vcc12v_dcin>;
>>
>> typec_vin.
>>
>>>    	};
>>>    	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
>>> @@ -264,6 +275,67 @@ regulator-state-mem {
>>>    	};
>>>    };
>>> +&i2c4 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&i2c4m1_xfer>;
>>> +	status = "okay";
>>> +
>>> +	usbc0: usb-typec at 22 {
>>
>> Is "usbc0" label necessary?
> 
> no, but does it hurt?

sorry, please keep it.

>>> +		compatible = "fcs,fusb302";
>>> +		reg = <0x22>;
>>> +		interrupt-parent = <&gpio3>;
>>> +		interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
>>> +		pinctrl-names = "default";
>>> +		pinctrl-0 = <&usbc0_int>;
>>
>> cc_int_l by schematic.
> 
> Ack. I intentionally switched away from this naming, since cc prefix
> is imho a way worse prefix than usbc0. The _l suffix just means
> active low, which is already encoded in DT.
> 
> But I don't have a strong opinion and can fix this in v2.
> 
>>> +		vbus-supply = <&vcc12v_dcin>;
>>
>> typec_vin
>>
>>> +		/*
>>> +		 * When the board is starting to send power-delivery messages
>>> +		 * too late (5 seconds according to the specification), the
>>> +		 * power-supply reacts with a hard-reset. That removes the
>>> +		 * power from VBUS for some time, which resets te whole board.
>>
>> ... resets "the" whole board.
> 
> Ack.
> 
>>
>>> +		 */
>>> +		status = "fail";
>>> +
>>> +		usb_con: connector {
>>
>> Is "usb_con" label necessary?
> 
> No. It should either be changed to "usbc0_con" or removed. In
> general I tend to add some labels when they might be needed by
> something in the future. They are more or less free anyways.

+1 for "usbc0_con".

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> -- Sebastian



From naoki at radxa.com  Tue Dec 10 16:06:40 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 11 Dec 2024 09:06:40 +0900
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add USB-C support to ROCK 5B
In-Reply-To: <20241210163615.120594-1-sebastian.reichel@collabora.com>
References: <20241210163615.120594-1-sebastian.reichel@collabora.com>
Message-ID: <FFD6E87BED20DB1B+38b8064e-9945-4cd8-a30e-7800a8c6f37b@radxa.com>

Sorry, I forgot to write one thing...

On 12/11/24 01:36, Sebastian Reichel wrote:
> Add hardware description for the USB-C port in the Radxa Rock 5 Model B.
> This describes the OHCI, EHCI and XHCI USB parts, but not yet the
> DisplayPort AltMode (bindings are not yet upstream).
> 
> The fusb302 node is marked with status "fail", since the board is usually
> powered through the USB-C port. Handling of errors can result in hard
> resets, which removed the bus power for some time resulting in a board
> reset.
> 
> The main problem is that devices are supposed to interact with the
> power-supply within 5 seconds after the plug event according to the
> USB PD specification. This is more or less impossible to achieve when
> the kernel is the first software communicating with the power-supply.
> 
> Recent U-Boot (v2025.01) will start doing USB-PD communication, which
> solves this issue. Upstream U-Boot doing USB-PD communication will also
> set the fusb302 node status to "okay". That way booting a kernel with
> the updated DT on an old U-Boot avoids a reset loop.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>

Tested-by: FUKAUMI Naoki <naoki at radxa.com>

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> ---
>   .../boot/dts/rockchip/rk3588-rock-5b.dts      | 121 ++++++++++++++++++
>   1 file changed, 121 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> index d597112f1d5b..cb5990df6ccb 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> @@ -5,6 +5,7 @@
>   #include <dt-bindings/gpio/gpio.h>
>   #include <dt-bindings/leds/common.h>
>   #include <dt-bindings/soc/rockchip,vop2.h>
> +#include <dt-bindings/usb/pd.h>
>   #include "rk3588.dtsi"
>   
>   / {
> @@ -84,6 +85,15 @@ rfkill-bt {
>   		shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>   	};
>   
> +	vcc12v_dcin: regulator-vcc12v-dcin {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc12v_dcin";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <12000000>;
> +		regulator-max-microvolt = <12000000>;
> +	};
> +
>   	vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 {
>   		compatible = "regulator-fixed";
>   		enable-active-high;
> @@ -142,6 +152,7 @@ vcc5v0_sys: regulator-vcc5v0-sys {
>   		regulator-boot-on;
>   		regulator-min-microvolt = <5000000>;
>   		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&vcc12v_dcin>;
>   	};
>   
>   	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
> @@ -264,6 +275,67 @@ regulator-state-mem {
>   	};
>   };
>   
> +&i2c4 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c4m1_xfer>;
> +	status = "okay";
> +
> +	usbc0: usb-typec at 22 {
> +		compatible = "fcs,fusb302";
> +		reg = <0x22>;
> +		interrupt-parent = <&gpio3>;
> +		interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&usbc0_int>;
> +		vbus-supply = <&vcc12v_dcin>;
> +		/*
> +		 * When the board is starting to send power-delivery messages
> +		 * too late (5 seconds according to the specification), the
> +		 * power-supply reacts with a hard-reset. That removes the
> +		 * power from VBUS for some time, which resets te whole board.
> +		 */
> +		status = "fail";
> +
> +		usb_con: connector {
> +			compatible = "usb-c-connector";
> +			label = "USB-C";
> +			data-role = "dual";
> +			power-role = "sink";
> +			try-power-role = "sink";
> +			op-sink-microwatt = <1000000>;
> +			sink-pdos =
> +				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>,
> +				<PDO_VAR(5000, 20000, 5000)>;
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				port at 0 {
> +					reg = <0>;
> +					usbc0_role_sw: endpoint {
> +						remote-endpoint = <&dwc3_0_role_switch>;
> +					};
> +				};
> +
> +				port at 1 {
> +					reg = <1>;
> +					usbc0_orien_sw: endpoint {
> +						remote-endpoint = <&usbdp_phy0_orientation_switch>;
> +					};
> +				};
> +
> +				port at 2 {
> +					reg = <2>;
> +					dp_altmode_mux: endpoint {
> +						remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
> +					};
> +				};
> +			};
> +		};
> +	};
> +};
> +
>   &i2c6 {
>   	status = "okay";
>   
> @@ -423,6 +495,10 @@ usb {
>   		vcc5v0_host_en: vcc5v0-host-en {
>   			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
>   		};
> +
> +		usbc0_int: usbc0-int {
> +			rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
>   	};
>   };
>   
> @@ -835,6 +911,14 @@ &uart2 {
>   	status = "okay";
>   };
>   
> +&u2phy0 {
> +	status = "okay";
> +};
> +
> +&u2phy0_otg {
> +	status = "okay";
> +};
> +
>   &u2phy1 {
>   	status = "okay";
>   };
> @@ -866,6 +950,29 @@ &usbdp_phy1 {
>   	status = "okay";
>   };
>   
> +&usbdp_phy0 {
> +	mode-switch;
> +	orientation-switch;
> +	sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
> +	sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
> +	status = "okay";
> +
> +	port {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		usbdp_phy0_orientation_switch: endpoint at 0 {
> +			reg = <0>;
> +			remote-endpoint = <&usbc0_orien_sw>;
> +		};
> +
> +		usbdp_phy0_dp_altmode_mux: endpoint at 1 {
> +			reg = <1>;
> +			remote-endpoint = <&dp_altmode_mux>;
> +		};
> +	};
> +};
> +
>   &usb_host0_ehci {
>   	status = "okay";
>   };
> @@ -874,6 +981,20 @@ &usb_host0_ohci {
>   	status = "okay";
>   };
>   
> +&usb_host0_xhci {
> +	usb-role-switch;
> +	status = "okay";
> +
> +	port {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		dwc3_0_role_switch: endpoint {
> +			remote-endpoint = <&usbc0_role_sw>;
> +		};
> +	};
> +};
> +
>   &usb_host1_ehci {
>   	status = "okay";
>   };



From quic_pkondeti at quicinc.com  Tue Dec 10 16:37:34 2024
From: quic_pkondeti at quicinc.com (Pavan Kondeti)
Date: Wed, 11 Dec 2024 06:07:34 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <87ed2fs03w.wl-maz@kernel.org>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <87ed2fs03w.wl-maz@kernel.org>
Message-ID: <92cee905-a505-4ce9-9bbc-6fba4cea1d80@quicinc.com>

On Tue, Dec 10, 2024 at 09:24:03PM +0000, Marc Zyngier wrote:
> > +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> > +{
> > +	int ret;
> > +
> > +#ifdef CONFIG_ARM64
> > +	/*
> > +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> > +	 * to switch the secure mode to avoid the dependency on zap shader.
> > +	 */
> > +	if (is_kernel_in_hyp_mode())
> > +		goto direct_switch;
> 
> No, please. To check whether you are *booted* at EL2, you need to
> check for is_hyp_available(). Whether the kernel runs at EL1 or EL2 is
> none of the driver's business, really. This is still absolutely
> disgusting from an abstraction perspective, but I guess we don't have
> much choice here.
> 

Thanks Marc. Any suggestions on how we can make is_hyp_mode_available()
available for modules? Do you prefer exporting
kvm_protected_mode_initialized and __boot_cpu_mode symbols directly or
try something like [1]?

[1]
https://lore.kernel.org/lkml/1443649252-10702-1-git-send-email-ralf at ramses-pyramidenbau.de/#t

Thanks,
Pavan


From naoki at radxa.com  Tue Dec 10 16:40:13 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 11 Dec 2024 09:40:13 +0900
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add USB-C support to ROCK 5B
In-Reply-To: <FFD6E87BED20DB1B+38b8064e-9945-4cd8-a30e-7800a8c6f37b@radxa.com>
References: <20241210163615.120594-1-sebastian.reichel@collabora.com>
 <FFD6E87BED20DB1B+38b8064e-9945-4cd8-a30e-7800a8c6f37b@radxa.com>
Message-ID: <3D830E407DCD15A2+de00ea1d-96d5-4766-9dc5-616fc76f404b@radxa.com>

Hi Sebastian,

Sorry for many emails...

I got random reboot during booting kernel/userland...

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 12/11/24 09:06, FUKAUMI Naoki wrote:
> Sorry, I forgot to write one thing...
> 
> On 12/11/24 01:36, Sebastian Reichel wrote:
>> Add hardware description for the USB-C port in the Radxa Rock 5 Model B.
>> This describes the OHCI, EHCI and XHCI USB parts, but not yet the
>> DisplayPort AltMode (bindings are not yet upstream).
>>
>> The fusb302 node is marked with status "fail", since the board is usually
>> powered through the USB-C port. Handling of errors can result in hard
>> resets, which removed the bus power for some time resulting in a board
>> reset.
>>
>> The main problem is that devices are supposed to interact with the
>> power-supply within 5 seconds after the plug event according to the
>> USB PD specification. This is more or less impossible to achieve when
>> the kernel is the first software communicating with the power-supply.
>>
>> Recent U-Boot (v2025.01) will start doing USB-PD communication, which
>> solves this issue. Upstream U-Boot doing USB-PD communication will also
>> set the fusb302 node status to "okay". That way booting a kernel with
>> the updated DT on an old U-Boot avoids a reset loop.
>>
>> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> 
> Tested-by: FUKAUMI Naoki <naoki at radxa.com>
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>> ---
>> ? .../boot/dts/rockchip/rk3588-rock-5b.dts????? | 121 ++++++++++++++++++
>> ? 1 file changed, 121 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/ 
>> arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> index d597112f1d5b..cb5990df6ccb 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> @@ -5,6 +5,7 @@
>> ? #include <dt-bindings/gpio/gpio.h>
>> ? #include <dt-bindings/leds/common.h>
>> ? #include <dt-bindings/soc/rockchip,vop2.h>
>> +#include <dt-bindings/usb/pd.h>
>> ? #include "rk3588.dtsi"
>> ? / {
>> @@ -84,6 +85,15 @@ rfkill-bt {
>> ????????? shutdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>> ????? };
>> +??? vcc12v_dcin: regulator-vcc12v-dcin {
>> +??????? compatible = "regulator-fixed";
>> +??????? regulator-name = "vcc12v_dcin";
>> +??????? regulator-always-on;
>> +??????? regulator-boot-on;
>> +??????? regulator-min-microvolt = <12000000>;
>> +??????? regulator-max-microvolt = <12000000>;
>> +??? };
>> +
>> ????? vcc3v3_pcie2x1l0: regulator-vcc3v3-pcie2x1l0 {
>> ????????? compatible = "regulator-fixed";
>> ????????? enable-active-high;
>> @@ -142,6 +152,7 @@ vcc5v0_sys: regulator-vcc5v0-sys {
>> ????????? regulator-boot-on;
>> ????????? regulator-min-microvolt = <5000000>;
>> ????????? regulator-max-microvolt = <5000000>;
>> +??????? vin-supply = <&vcc12v_dcin>;
>> ????? };
>> ????? vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
>> @@ -264,6 +275,67 @@ regulator-state-mem {
>> ????? };
>> ? };
>> +&i2c4 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&i2c4m1_xfer>;
>> +??? status = "okay";
>> +
>> +??? usbc0: usb-typec at 22 {
>> +??????? compatible = "fcs,fusb302";
>> +??????? reg = <0x22>;
>> +??????? interrupt-parent = <&gpio3>;
>> +??????? interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&usbc0_int>;
>> +??????? vbus-supply = <&vcc12v_dcin>;
>> +??????? /*
>> +???????? * When the board is starting to send power-delivery messages
>> +???????? * too late (5 seconds according to the specification), the
>> +???????? * power-supply reacts with a hard-reset. That removes the
>> +???????? * power from VBUS for some time, which resets te whole board.
>> +???????? */
>> +??????? status = "fail";
>> +
>> +??????? usb_con: connector {
>> +??????????? compatible = "usb-c-connector";
>> +??????????? label = "USB-C";
>> +??????????? data-role = "dual";
>> +??????????? power-role = "sink";
>> +??????????? try-power-role = "sink";
>> +??????????? op-sink-microwatt = <1000000>;
>> +??????????? sink-pdos =
>> +??????????????? <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>,
>> +??????????????? <PDO_VAR(5000, 20000, 5000)>;
>> +
>> +??????????? ports {
>> +??????????????? #address-cells = <1>;
>> +??????????????? #size-cells = <0>;
>> +
>> +??????????????? port at 0 {
>> +??????????????????? reg = <0>;
>> +??????????????????? usbc0_role_sw: endpoint {
>> +??????????????????????? remote-endpoint = <&dwc3_0_role_switch>;
>> +??????????????????? };
>> +??????????????? };
>> +
>> +??????????????? port at 1 {
>> +??????????????????? reg = <1>;
>> +??????????????????? usbc0_orien_sw: endpoint {
>> +??????????????????????? remote-endpoint = 
>> <&usbdp_phy0_orientation_switch>;
>> +??????????????????? };
>> +??????????????? };
>> +
>> +??????????????? port at 2 {
>> +??????????????????? reg = <2>;
>> +??????????????????? dp_altmode_mux: endpoint {
>> +??????????????????????? remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
>> +??????????????????? };
>> +??????????????? };
>> +??????????? };
>> +??????? };
>> +??? };
>> +};
>> +
>> ? &i2c6 {
>> ????? status = "okay";
>> @@ -423,6 +495,10 @@ usb {
>> ????????? vcc5v0_host_en: vcc5v0-host-en {
>> ????????????? rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
>> ????????? };
>> +
>> +??????? usbc0_int: usbc0-int {
>> +??????????? rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
>> +??????? };
>> ????? };
>> ? };
>> @@ -835,6 +911,14 @@ &uart2 {
>> ????? status = "okay";
>> ? };
>> +&u2phy0 {
>> +??? status = "okay";
>> +};
>> +
>> +&u2phy0_otg {
>> +??? status = "okay";
>> +};
>> +
>> ? &u2phy1 {
>> ????? status = "okay";
>> ? };
>> @@ -866,6 +950,29 @@ &usbdp_phy1 {
>> ????? status = "okay";
>> ? };
>> +&usbdp_phy0 {
>> +??? mode-switch;
>> +??? orientation-switch;
>> +??? sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
>> +??? sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
>> +??? status = "okay";
>> +
>> +??? port {
>> +??????? #address-cells = <1>;
>> +??????? #size-cells = <0>;
>> +
>> +??????? usbdp_phy0_orientation_switch: endpoint at 0 {
>> +??????????? reg = <0>;
>> +??????????? remote-endpoint = <&usbc0_orien_sw>;
>> +??????? };
>> +
>> +??????? usbdp_phy0_dp_altmode_mux: endpoint at 1 {
>> +??????????? reg = <1>;
>> +??????????? remote-endpoint = <&dp_altmode_mux>;
>> +??????? };
>> +??? };
>> +};
>> +
>> ? &usb_host0_ehci {
>> ????? status = "okay";
>> ? };
>> @@ -874,6 +981,20 @@ &usb_host0_ohci {
>> ????? status = "okay";
>> ? };
>> +&usb_host0_xhci {
>> +??? usb-role-switch;
>> +??? status = "okay";
>> +
>> +??? port {
>> +??????? #address-cells = <1>;
>> +??????? #size-cells = <0>;
>> +
>> +??????? dwc3_0_role_switch: endpoint {
>> +??????????? remote-endpoint = <&usbc0_role_sw>;
>> +??????? };
>> +??? };
>> +};
>> +
>> ? &usb_host1_ehci {
>> ????? status = "okay";
>> ? };
> 



From quic_pkondeti at quicinc.com  Tue Dec 10 16:40:06 2024
From: quic_pkondeti at quicinc.com (Pavan Kondeti)
Date: Wed, 11 Dec 2024 06:10:06 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <CACu1E7H0-zzEPv8ytmx_9XRe1t-RCc7enshgwk2r9-0gWK44hw@mail.gmail.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CACu1E7H0-zzEPv8ytmx_9XRe1t-RCc7enshgwk2r9-0gWK44hw@mail.gmail.com>
Message-ID: <8fc505a0-91ad-4188-8627-fa28fc73a2ae@quicinc.com>

On Tue, Dec 10, 2024 at 05:52:27PM -0500, Connor Abbott wrote:
> On Mon, Dec 9, 2024 at 3:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> >
> > When kernel is booted in EL2, SECVID registers are accessible to the
> > KMD. So we can use that to switch GPU's secure mode to avoid dependency
> > on Zap firmware. Also, we can't load a secure firmware without a
> > hypervisor that supports it.
> >
> > Tested following configurations on sa8775p chipset (Adreno 663 gpu):
> >
> > 1. Gunyah (No KVM) - Loads zap shader based on DT
> > 2. KVM in VHE - Skips zap shader load and programs SECVID register
> > 3. KVM in nVHE - Loads zap shader based on DT
> > 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
> >         programs SECVID register
> >
> > For (1) and (3) configuration, this patch doesn't have any impact.
> > Driver loads secure firmware based on other existing hints.
> >
> > Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
> 
> For initializing CX_MISC_SW_FUSE_VALUE in a7xx_cx_mem_init(), we used
> !qcom_scm_is_available() to assume that the register is writable
> instead - can you just do that?
> 

qcom_scm_is_avaialble() returns true as most of the QC TZ firmware API
works w/ kernel running as bare metal i.e booted with EL2. Any services
that assume QC firmware @ EL2 (QHEE) is absent.

Thanks,
Pavan


From fujita.tomonori at gmail.com  Tue Dec 10 16:40:54 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Wed, 11 Dec 2024 09:40:54 +0900 (JST)
Subject: [PATCH v1 5/5] rust: Add warn_on and warn_on_once
In-Reply-To: <CAH5fLgiShKMGo6AYWM-4S8JK+iDA+tUfz9uxkns82g0nLW--NQ@mail.gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com>
	<20241210001802.228725-6-fujita.tomonori@gmail.com>
	<CAH5fLgiShKMGo6AYWM-4S8JK+iDA+tUfz9uxkns82g0nLW--NQ@mail.gmail.com>
Message-ID: <20241211.094054.1429837669366274024.fujita.tomonori@gmail.com>

On Tue, 10 Dec 2024 10:05:07 +0100
Alice Ryhl <aliceryhl at google.com> wrote:

> On Tue, Dec 10, 2024 at 1:19?AM FUJITA Tomonori
> <fujita.tomonori at gmail.com> wrote:
>>
>> Add warn_on and warn_on_once macros. Wrapping the C's WARN_* and BUG_*
>> macros doesn't work so this uses the assembly code exported by the C
>> side via ARCH_WARN_ASM macro. Like the static branch code, this
>> generates the assembly code for rust dynamically by using the C
>> preprocessor.
>>
>> file()! macro doesn't work for the Rust inline assembly in the same
>> way as __FILE__ for the C inline assembly. So the code to handle a
>> file name is different from the C assembly code (similar to the
>> arm64/loongarch assembly).
>>
>> ASM_REACHABLE definition works in the same way to get objtool's
>> reachable asm code. The architectures which use objtool (x86 and
>> loongarch) needs it.
>>
>> Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
> 
>> +#[macro_export]
>> +#[doc(hidden)]
>> +#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
>> +#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
> 
>> +#[macro_export]
>> +#[doc(hidden)]
>> +#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
>> +#[cfg(any(target_arch = "aarch64", target_arch = "loongarch64"))]
> 
> What's the reason for this arch-specific code? The file!()/line!()
> invocations? Could they be passed as an argument to the asm instead so
> that we don't need target_arch cfgs? I understand that they don't work
> exactly the same way, but maybe it could still work?

Because of "error: named argument never used" in Rust inline assembly:

All the archs define ARCH_WARN_ASM macro in the same way:

#define ARCH_WARN_ASM(file, line, flags, size)

However, only x86 and risc-v asm code use the size argument. Without
the cfgs, I'll get the following on arm64/loongarch:

error: named argument never used
  --> /home/fujita/git/linux-rust/drivers/block/rnull.rs:54:9
   |
54 |         warn_on!(true);
   |         ^^^^^^^^^^^^^^ named argument never used
   |
   = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {size} */"`
   = note: this error originates in the macro `$crate::warn_flags` which comes from the expansion of the macro `warn_on` (in Nightly builds, run with -Z macro-backtrace for more info)


Any way to make the compiler to ignore this?


>> +#[macro_export]
>> +#[doc(hidden)]
>> +#[cfg(all(CONFIG_BUG, CONFIG_UML))]
>> +macro_rules! warn_flags {
>> +    ($flags:expr) => {
>> +        // SAFETY: Just an FFI call.
>> +        unsafe {
>> +            $crate::bindings::warn_slowpath_fmt(
>> +                $crate::c_str!(::core::file!()).as_ptr() as *const ::core::ffi::c_char,
>> +                line!() as i32,
>> +                $flags as u32,
>> +                ::core::ptr::null() as *const ::core::ffi::c_char,
> 
> I wonder if this could be written to utilize Location::caller()
> instead so that `#[track_caller]` works?

You meant that we could make warn_flags() function instead of macro
with Location::caller()?

If so, we need to add cfgs to warn_on and warn_on_once because both macro
and function of warn_flags are necessary?

From ilkka at os.amperecomputing.com  Tue Dec 10 16:55:00 2024
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Tue, 10 Dec 2024 16:55:00 -0800 (PST)
Subject: [PATCH] perf/dwc_pcie: Qualify RAS DES VSEC Capability by Vendor,
 Revision
In-Reply-To: <20241209222938.3219364-1-helgaas@kernel.org>
References: <20241209222938.3219364-1-helgaas@kernel.org>
Message-ID: <63442519-ae22-dbc2-debd-c4337463cde9@os.amperecomputing.com>


On Mon, 9 Dec 2024, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
>
> PCI Vendor-Specific (VSEC) Capabilities are defined by each vendor.
> Devices from different vendors may advertise a VSEC Capability with the DWC
> RAS DES functionality, but the vendors may assign different VSEC IDs.
>
> Search for the DWC RAS DES Capability using the VSEC ID and VSEC Rev
> chosen by the vendor.
>
> This does not fix a current problem because Alibaba, Ampere, and Qualcomm
> all assigned the same VSEC ID and VSEC Rev for the DWC RAS DES Capability.
>
> The potential issue is that we may add support for a device from another
> vendor, where the vendor has already assigned DWC_PCIE_VSEC_RAS_DES_ID
> (0x02) for an unrelated VSEC.  In that event, dwc_pcie_des_cap() would find
> the unrelated VSEC and mistakenly assume it was a DWC RAS DES Capability.
>
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>

Hi Bjorn,

Thanks for the patch. It looks good to me. Also, I quickly tested it on 
AmpereOne and everything seemed to be working as expected.

Reviewed-and-tested-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>

Cheers, Ilkka

> ---
> Sample devices that advertise VSEC Capabilities with VSEC ID=0x02 that are
> unrelated to the DWC RAS DES functionality:
>
>  https://community.nxp.com/t5/S32G/S32G3-PCIe-compliance-mode-set-speed-to-5-8Gbit-s/m-p/1875346#M7024
>    00:00.0 PCI bridge: Freescale Semiconductor Inc Device 4300 (prog-if 00 [Normal decode])
>      Capabilities: [70] Express (v2) Root Port (Slot-), MSI 00
>      Capabilities: [158 v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
>
>  https://github.com/google-coral/edgetpu/issues/743
>    0000:00:00.0 PCI bridge: NVIDIA Corporation Device 1ad0 (rev a1) (prog-if 00 [Normal decode])
>      Capabilities: [70] Express (v2) Root Port (Slot-), MSI 00
>      Capabilities: [1d0 v1] Vendor Specific Information: ID=0002 Rev=4 Len=100
>
>  https://www.linuxquestions.org/questions/linux-kernel-70/differences-in-'lspci-v'-output-4175495550/
>    00:01.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 1 (rev 13) (prog-if 00 [Normal decode])
>      Capabilities: [90] Express Root Port (Slot+), MSI 00
>      Capabilities: [160] Vendor Specific Information: ID=0002 Rev=0 Len=00c <?>
>
>  https://www.reddit.com/r/linuxhardware/comments/187u87b/the_correct_way_to_identify_the_kernel_driver/
>    04:00.0 Network controller: Realtek Semiconductor Co., Ltd. Device c852 (rev 01)
>      Capabilities: [70] Express Endpoint, MSI 00
>      Capabilities: [170] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
> ---
> drivers/perf/dwc_pcie_pmu.c | 68 ++++++++++++++++++++-----------------
> 1 file changed, 37 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
> index 9cbea9675e21..d022f498fa1a 100644
> --- a/drivers/perf/dwc_pcie_pmu.c
> +++ b/drivers/perf/dwc_pcie_pmu.c
> @@ -20,7 +20,6 @@
> #include <linux/sysfs.h>
> #include <linux/types.h>
>
> -#define DWC_PCIE_VSEC_RAS_DES_ID		0x02
> #define DWC_PCIE_EVENT_CNT_CTL			0x8
>
> /*
> @@ -100,14 +99,23 @@ struct dwc_pcie_dev_info {
> 	struct list_head dev_node;
> };
>
> -struct dwc_pcie_vendor_id {
> -	int vendor_id;
> +struct dwc_pcie_pmu_vsec_id {
> +	u16 vendor_id;
> +	u16 vsec_id;
> +	u8 vsec_rev;
> };
>
> -static const struct dwc_pcie_vendor_id dwc_pcie_vendor_ids[] = {
> -	{.vendor_id = PCI_VENDOR_ID_ALIBABA },
> -	{.vendor_id = PCI_VENDOR_ID_AMPERE },
> -	{.vendor_id = PCI_VENDOR_ID_QCOM },
> +/*
> + * VSEC IDs are allocated by the vendor, so a given ID may mean different
> + * things to different vendors.  See PCIe r6.0, sec 7.9.5.2.
> + */
> +static const struct dwc_pcie_pmu_vsec_id dwc_pcie_pmu_vsec_ids[] = {
> +	{ .vendor_id = PCI_VENDOR_ID_ALIBABA,
> +	  .vsec_id = 0x02, .vsec_rev = 0x4 },
> +	{ .vendor_id = PCI_VENDOR_ID_AMPERE,
> +	  .vsec_id = 0x02, .vsec_rev = 0x4 },
> +	{ .vendor_id = PCI_VENDOR_ID_QCOM,
> +	  .vsec_id = 0x02, .vsec_rev = 0x4 },
> 	{} /* terminator */
> };
>
> @@ -519,31 +527,28 @@ static void dwc_pcie_unregister_pmu(void *data)
> 	perf_pmu_unregister(&pcie_pmu->pmu);
> }
>
> -static bool dwc_pcie_match_des_cap(struct pci_dev *pdev)
> +static u16 dwc_pcie_des_cap(struct pci_dev *pdev)
> {
> -	const struct dwc_pcie_vendor_id *vid;
> -	u16 vsec = 0;
> +	const struct dwc_pcie_pmu_vsec_id *vid;
> +	u16 vsec;
> 	u32 val;
>
> 	if (!pci_is_pcie(pdev) || !(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT))
> -		return false;
> +		return 0;
>
> -	for (vid = dwc_pcie_vendor_ids; vid->vendor_id; vid++) {
> +	for (vid = dwc_pcie_pmu_vsec_ids; vid->vendor_id; vid++) {
> 		vsec = pci_find_vsec_capability(pdev, vid->vendor_id,
> -						DWC_PCIE_VSEC_RAS_DES_ID);
> -		if (vsec)
> -			break;
> +						vid->vsec_id);
> +		if (vsec) {
> +			pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER,
> +					      &val);
> +			if (PCI_VNDR_HEADER_REV(val) == vid->vsec_rev) {
> +				pci_dbg(pdev, "Detected PCIe Vendor-Specific Extended Capability RAS DES\n");
> +				return vsec;
> +			}
> +		}
> 	}
> -	if (!vsec)
> -		return false;
> -
> -	pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER, &val);
> -	if (PCI_VNDR_HEADER_REV(val) != 0x04)
> -		return false;
> -
> -	pci_dbg(pdev,
> -		"Detected PCIe Vendor-Specific Extended Capability RAS DES\n");
> -	return true;
> +	return 0;
> }
>
> static void dwc_pcie_unregister_dev(struct dwc_pcie_dev_info *dev_info)
> @@ -587,7 +592,7 @@ static int dwc_pcie_pmu_notifier(struct notifier_block *nb,
>
> 	switch (action) {
> 	case BUS_NOTIFY_ADD_DEVICE:
> -		if (!dwc_pcie_match_des_cap(pdev))
> +		if (!dwc_pcie_des_cap(pdev))
> 			return NOTIFY_DONE;
> 		if (dwc_pcie_register_dev(pdev))
> 			return NOTIFY_BAD;
> @@ -612,13 +617,14 @@ static int dwc_pcie_pmu_probe(struct platform_device *plat_dev)
> 	struct pci_dev *pdev = plat_dev->dev.platform_data;
> 	struct dwc_pcie_pmu *pcie_pmu;
> 	char *name;
> -	u32 sbdf, val;
> +	u32 sbdf;
> 	u16 vsec;
> 	int ret;
>
> -	vsec = pci_find_vsec_capability(pdev, pdev->vendor,
> -					DWC_PCIE_VSEC_RAS_DES_ID);
> -	pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER, &val);
> +	vsec = dwc_pcie_des_cap(pdev);
> +	if (!vsec)
> +		return -ENODEV;
> +
> 	sbdf = plat_dev->id;
> 	name = devm_kasprintf(&plat_dev->dev, GFP_KERNEL, "dwc_rootport_%x", sbdf);
> 	if (!name)
> @@ -730,7 +736,7 @@ static int __init dwc_pcie_pmu_init(void)
> 	int ret;
>
> 	for_each_pci_dev(pdev) {
> -		if (!dwc_pcie_match_des_cap(pdev))
> +		if (!dwc_pcie_des_cap(pdev))
> 			continue;
>
> 		ret = dwc_pcie_register_dev(pdev);
> -- 
> 2.34.1
>
>


From broonie at kernel.org  Tue Dec 10 17:00:35 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:00:35 +0000
Subject: [PATCH v2] arm64/signal: Silence sparse warning storing GCSPR_EL0
Message-ID: <20241211-arm64-gcs-signal-sparse-v2-1-c22f37216135@kernel.org>

We are seeing a sparse warning in gcs_restore_signal():

  arch/arm64/kernel/signal.c:1054:9: sparse: sparse: cast removes address space '__user' of expression

when storing the final GCSPR_EL0 value back into the register, caused by
the fact that write_sysreg_s() casts the value it writes to a u64 which
sparse sees as discarding the __userness of the pointer.  Add a __force
cast to tell sparse that this is intentional.

While we're at it also remove spurious casts of the gcspr_el0 value as we
manipulate it which were the result of bitrot as the code was tweaked in
the long period it was out of tree.

Reported-by: kernel test robot <lkp at intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202412082005.OBJ0BbWs-lkp at intel.com/
Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v2:
- Use __force u64 rather than unsigned long.
- Tweak commit message.
- Link to v1: https://lore.kernel.org/r/20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89 at kernel.org
---
 arch/arm64/kernel/signal.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 14ac6fdb872b9672e4b16a097f1b577aae8dec50..08d51fabdb9d47c848f14c9b25d6be04f109c2ee 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -39,7 +39,7 @@
 #ifdef CONFIG_ARM64_GCS
 #define GCS_SIGNAL_CAP(addr) (((unsigned long)addr) & GCS_CAP_ADDR_MASK)
 
-static bool gcs_signal_cap_valid(u64 addr, u64 val)
+static bool gcs_signal_cap_valid(unsigned long __user *addr, u64 val)
 {
 	return val == GCS_SIGNAL_CAP(addr);
 }
@@ -1094,15 +1094,15 @@ static int gcs_restore_signal(void)
 	/*
 	 * Check that the cap is the actual GCS before replacing it.
 	 */
-	if (!gcs_signal_cap_valid((u64)gcspr_el0, cap))
+	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);
+	put_user_gcs(0, gcspr_el0, &ret);
 	if (ret != 0)
 		return -EFAULT;
 
-	write_sysreg_s(gcspr_el0 + 1, SYS_GCSPR_EL0);
+	write_sysreg_s((__force u64)(gcspr_el0 + 1), SYS_GCSPR_EL0);
 
 	return 0;
 }

---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241209-arm64-gcs-signal-sparse-53fa9cad67f7

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Tue Dec 10 17:02:51 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:51 +0000
Subject: [PATCH v4 6/9] arm64/sysreg: Update ID_AA64ISAR2_EL1 to DDI0601
 2024-09
In-Reply-To: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
References: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
Message-ID: <20241211-arm64-2024-dpisa-v4-6-0fd403876df2@kernel.org>

DDI0601 2024-09 introduces new features which are enumerated via
ID_AA64ISAR2_EL1, update the sysreg file to reflect these updates.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index d78b12c59658b480739ae797f5ea2c2f14d8d765..724762f0c1db223b5772f4f1b27720facb428bf1 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1556,12 +1556,16 @@ EndEnum
 UnsignedEnum	55:52	CSSC
 	0b0000	NI
 	0b0001	IMP
+	0b0010	CMPBR
 EndEnum
 UnsignedEnum	51:48	RPRFM
 	0b0000	NI
 	0b0001	IMP
 EndEnum
-Res0	47:44
+UnsignedEnum	47:44	PCDPHINT
+	0b0000	NI
+	0b0001	IMP
+EndEnum
 UnsignedEnum	43:40	PRFMSLC
 	0b0000	NI
 	0b0001	IMP

-- 
2.39.5



From broonie at kernel.org  Tue Dec 10 17:02:52 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:52 +0000
Subject: [PATCH v4 7/9] arm64/hwcap: Describe 2024 dpISA extensions to
 userspace
In-Reply-To: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
References: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
Message-ID: <20241211-arm64-2024-dpisa-v4-7-0fd403876df2@kernel.org>

The 2024 dpISA introduces a number of architecture features all of which
only add new instructions so only require the addition of hwcaps and ID
register visibility.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arch/arm64/elf_hwcaps.rst | 51 +++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/hwcap.h          | 17 +++++++++++
 arch/arm64/include/uapi/asm/hwcap.h     | 17 +++++++++++
 arch/arm64/kernel/cpufeature.c          | 35 ++++++++++++++++++++++
 arch/arm64/kernel/cpuinfo.c             | 17 +++++++++++
 5 files changed, 137 insertions(+)

diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst
index 2ff922a406ad83d0dff8104a6e362ac6b02d0e1f..7c99894ca3e8f5433b1a0db6a4679395e5cd9ecc 100644
--- a/Documentation/arch/arm64/elf_hwcaps.rst
+++ b/Documentation/arch/arm64/elf_hwcaps.rst
@@ -174,6 +174,57 @@ HWCAP_GCS
     Functionality implied by ID_AA64PFR1_EL1.GCS == 0b1, as
     described by Documentation/arch/arm64/gcs.rst.
 
+HWCAP_CMPBR
+    Functionality implied by ID_AA64ISAR2_EL1.CSSC == 0b0010.
+
+HWCAP_FPRCVT
+    Functionality implied by ID_AA64ISAR3_EL1.FPRCVT == 0b0001.
+
+HWCAP_F8MM8
+    Functionality implied by ID_AA64FPFR0_EL1.F8MM8 == 0b0001.
+
+HWCAP_F8MM4
+    Functionality implied by ID_AA64FPFR0_EL1.F8MM4 == 0b0001.
+
+HWCAP_SVE_F16MM
+    Functionality implied by ID_AA64ZFR0_EL1.F16MM == 0b0001.
+
+HWCAP_SVE_ELTPERM
+    Functionality implied by ID_AA64ZFR0_EL1.ELTPERM == 0b0001.
+
+HWCAP_SVE_AES2
+    Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0011.
+
+HWCAP_SVE_BFSCALE
+    Functionality implied by ID_AA64ZFR0_EL1.B16B16 == 0b0010.
+
+HWCAP_SVE2P2
+    Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0011.
+
+HWCAP_SME2P2
+    Functionality implied by ID_AA64SMFR0_EL1.SMEver == 0b0011.
+
+HWCAP_SME_SF8MM8
+    Functionality implied by ID_AA64SMFR0_EL1.SF8MM8 == 0b1.
+
+HWCAP_SME_SF8MM4
+    Functionality implied by ID_AA64SMFR0_EL1.SF8MM4 == 0b1.
+
+HWCAP_SME_SBITPERM
+    Functionality implied by ID_AA64SMFR0_EL1.SBitPerm == 0b1.
+
+HWCAP_SME_AES
+    Functionality implied by ID_AA64SMFR0_EL1.AES == 0b1.
+
+HWCAP_SME_SFEXPA
+    Functionality implied by ID_AA64SMFR0_EL1.SFEXPA == 0b1.
+
+HWCAP_SME_STMOP
+    Functionality implied by ID_AA64SMFR0_EL1.STMOP == 0b1.
+
+HWCAP_SME_SMOP4
+    Functionality implied by ID_AA64SMFR0_EL1.SMOP4 == 0b1.
+
 HWCAP2_DCPODP
     Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010.
 
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 2b6c61c608e2cd107503b09aba5aaeab639b759a..dbec921ee39c8c897f3e1e1c84d522b5b57130bb 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -93,6 +93,23 @@
 #define KERNEL_HWCAP_PACA		__khwcap_feature(PACA)
 #define KERNEL_HWCAP_PACG		__khwcap_feature(PACG)
 #define KERNEL_HWCAP_GCS		__khwcap_feature(GCS)
+#define KERNEL_HWCAP_CMPBR		__khwcap_feature(CMPBR)
+#define KERNEL_HWCAP_FPRCVT		__khwcap_feature(FPRCVT)
+#define KERNEL_HWCAP_F8MM8		__khwcap_feature(F8MM8)
+#define KERNEL_HWCAP_F8MM4		__khwcap_feature(F8MM4)
+#define KERNEL_HWCAP_SVE_F16MM		__khwcap_feature(SVE_F16MM)
+#define KERNEL_HWCAP_SVE_ELTPERM	__khwcap_feature(SVE_ELTPERM)
+#define KERNEL_HWCAP_SVE_AES2		__khwcap_feature(SVE_AES2)
+#define KERNEL_HWCAP_SVE_BFSCALE	__khwcap_feature(SVE_BFSCALE)
+#define KERNEL_HWCAP_SVE2P2		__khwcap_feature(SVE2P2)
+#define KERNEL_HWCAP_SME2P2		__khwcap_feature(SME2P2)
+#define KERNEL_HWCAP_SME_SF8MM8		__khwcap_feature(SME_SF8MM8)
+#define KERNEL_HWCAP_SME_SF8MM4		__khwcap_feature(SME_SF8MM4)
+#define KERNEL_HWCAP_SME_SBITPERM	__khwcap_feature(SME_SBITPERM)
+#define KERNEL_HWCAP_SME_AES		__khwcap_feature(SME_AES)
+#define KERNEL_HWCAP_SME_SFEXPA		__khwcap_feature(SME_SFEXPA)
+#define KERNEL_HWCAP_SME_STMOP		__khwcap_feature(SME_STMOP)
+#define KERNEL_HWCAP_SME_SMOP4		__khwcap_feature(SME_SMOP4)
 
 #define __khwcap2_feature(x)		(const_ilog2(HWCAP2_ ## x) + 64)
 #define KERNEL_HWCAP_DCPODP		__khwcap2_feature(DCPODP)
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index 48d46b768eaec4c307360cd3bee8b564687f4b88..61fbc88d2bfb81d0bad639ed533ac67440ae2fc4 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -56,6 +56,23 @@
 #define HWCAP_PACA		(1 << 30)
 #define HWCAP_PACG		(1UL << 31)
 #define HWCAP_GCS		(1UL << 32)
+#define HWCAP_CMPBR		(1UL << 33)
+#define HWCAP_FPRCVT		(1UL << 34)
+#define HWCAP_F8MM8		(1UL << 35)
+#define HWCAP_F8MM4		(1UL << 36)
+#define HWCAP_SVE_F16MM		(1UL << 37)
+#define HWCAP_SVE_ELTPERM	(1UL << 38)
+#define HWCAP_SVE_AES2		(1UL << 39)
+#define HWCAP_SVE_BFSCALE	(1UL << 40)
+#define HWCAP_SVE2P2		(1UL << 41)
+#define HWCAP_SME2P2		(1UL << 42)
+#define HWCAP_SME_SF8MM8	(1UL << 43)
+#define HWCAP_SME_SF8MM4	(1UL << 44)
+#define HWCAP_SME_SBITPERM	(1UL << 45)
+#define HWCAP_SME_AES		(1UL << 46)
+#define HWCAP_SME_SFEXPA	(1UL << 47)
+#define HWCAP_SME_STMOP		(1UL << 48)
+#define HWCAP_SME_SMOP4		(1UL << 49)
 
 /*
  * HWCAP2 flags - for AT_HWCAP2
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed84f9056196bb21bbfac61c9687e30..7ba73fdee6deb57cd745ff684eeb97f66d2ea85f 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -268,6 +268,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64isar3[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR3_EL1_FPRCVT_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR3_EL1_FAMINMAX_SHIFT, 4, 0),
 	ARM64_FTR_END,
 };
@@ -317,6 +318,8 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_F64MM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_F32MM_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
+		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_F16MM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_I8MM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
@@ -329,6 +332,8 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_BF16_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_BitPerm_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
+		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_EltPerm_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_AES_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
@@ -373,6 +378,20 @@ static const struct arm64_ftr_bits ftr_id_aa64smfr0[] = {
 		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8DP4_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
 		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8DP2_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8MM8_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8MM4_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SBitPerm_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_AES_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SFEXPA_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_STMOP_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SMOP4_SHIFT, 1, 0),
 	ARM64_FTR_END,
 };
 
@@ -381,6 +400,8 @@ static const struct arm64_ftr_bits ftr_id_aa64fpfr0[] = {
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8FMA_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8DP4_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8DP2_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8MM8_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8MM4_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8E4M3_SHIFT, 1, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8E5M2_SHIFT, 1, 0),
 	ARM64_FTR_END,
@@ -3092,12 +3113,15 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64MMFR2_EL1, AT, IMP, CAP_HWCAP, KERNEL_HWCAP_USCAT),
 #ifdef CONFIG_ARM64_SVE
 	HWCAP_CAP(ID_AA64PFR0_EL1, SVE, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2p2, CAP_HWCAP, KERNEL_HWCAP_SVE2P2),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, AES, AES2, CAP_HWCAP, KERNEL_HWCAP_SVE_AES2),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_B16B16),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, B16B16, BFSCALE, CAP_HWCAP, KERNEL_HWCAP_SVE_BFSCALE),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
@@ -3105,6 +3129,8 @@ 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),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, F16MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_F16MM),
+	HWCAP_CAP(ID_AA64ZFR0_EL1, EltPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_ELTPERM),
 #endif
 #ifdef CONFIG_ARM64_GCS
 	HWCAP_CAP(ID_AA64PFR1_EL1, GCS, IMP, CAP_HWCAP, KERNEL_HWCAP_GCS),
@@ -3124,6 +3150,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64MMFR0_EL1, ECV, IMP, CAP_HWCAP, KERNEL_HWCAP_ECV),
 	HWCAP_CAP(ID_AA64MMFR1_EL1, AFP, IMP, CAP_HWCAP, KERNEL_HWCAP_AFP),
 	HWCAP_CAP(ID_AA64ISAR2_EL1, CSSC, IMP, CAP_HWCAP, KERNEL_HWCAP_CSSC),
+	HWCAP_CAP(ID_AA64ISAR2_EL1, CSSC, CMPBR, CAP_HWCAP, KERNEL_HWCAP_CMPBR),
 	HWCAP_CAP(ID_AA64ISAR2_EL1, RPRFM, IMP, CAP_HWCAP, KERNEL_HWCAP_RPRFM),
 	HWCAP_CAP(ID_AA64ISAR2_EL1, RPRES, IMP, CAP_HWCAP, KERNEL_HWCAP_RPRES),
 	HWCAP_CAP(ID_AA64ISAR2_EL1, WFxT, IMP, CAP_HWCAP, KERNEL_HWCAP_WFXT),
@@ -3133,6 +3160,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64PFR1_EL1, SME, IMP, CAP_HWCAP, KERNEL_HWCAP_SME),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, FA64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_FA64),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, LUTv2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_LUTV2),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2p2, CAP_HWCAP, KERNEL_HWCAP_SME2P2),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2p1, CAP_HWCAP, KERNEL_HWCAP_SME2P1),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2, CAP_HWCAP, KERNEL_HWCAP_SME2),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, I16I64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64),
@@ -3150,6 +3178,13 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8FMA),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP4),
 	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP2),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8MM8, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8MM8),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SF8MM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8MM4),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SBitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SBITPERM),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_AES),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SFEXPA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SFEXPA),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, STMOP, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_STMOP),
+	HWCAP_CAP(ID_AA64SMFR0_EL1, SMOP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SMOP4),
 #endif /* CONFIG_ARM64_SME */
 	HWCAP_CAP(ID_AA64FPFR0_EL1, F8CVT, IMP, CAP_HWCAP, KERNEL_HWCAP_F8CVT),
 	HWCAP_CAP(ID_AA64FPFR0_EL1, F8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_F8FMA),
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index d79e88fccdfce427507e7a34c5959ce6309cbd12..9861291843d8fbcc5f8e68e2b9eaac65a0b37c22 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -145,6 +145,23 @@ static const char *const hwcap_str[] = {
 	[KERNEL_HWCAP_SME_SF8DP4]	= "smesf8dp4",
 	[KERNEL_HWCAP_SME_SF8DP2]	= "smesf8dp2",
 	[KERNEL_HWCAP_POE]		= "poe",
+	[KERNEL_HWCAP_CMPBR]		= "cmpbr",
+	[KERNEL_HWCAP_FPRCVT]		= "fprcvt",
+	[KERNEL_HWCAP_F8MM8]		= "f8mm8",
+	[KERNEL_HWCAP_F8MM4]		= "f8mm4",
+	[KERNEL_HWCAP_SVE_F16MM]	= "svef16mm",
+	[KERNEL_HWCAP_SVE_ELTPERM]	= "sveeltperm",
+	[KERNEL_HWCAP_SVE_AES2]		= "sveaes2",
+	[KERNEL_HWCAP_SVE_BFSCALE]	= "svebfscale",
+	[KERNEL_HWCAP_SVE2P2]		= "sve2p2",
+	[KERNEL_HWCAP_SME2P2]		= "sme2p2",
+	[KERNEL_HWCAP_SME_SF8MM8]	= "smesf8mm8",
+	[KERNEL_HWCAP_SME_SF8MM4]	= "smesf8mm4",
+	[KERNEL_HWCAP_SME_SBITPERM]	= "smesbitperm",
+	[KERNEL_HWCAP_SME_AES]		= "smeaes",
+	[KERNEL_HWCAP_SME_SFEXPA]	= "smesfexpa",
+	[KERNEL_HWCAP_SME_STMOP]	= "smestmop",
+	[KERNEL_HWCAP_SME_SMOP4]	= "smesmop4",
 };
 
 #ifdef CONFIG_COMPAT

-- 
2.39.5



From broonie at kernel.org  Tue Dec 10 17:02:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:53 +0000
Subject: [PATCH v4 8/9] KVM: arm64: Allow control of dpISA extensions in
 ID_AA64ISAR3_EL1
In-Reply-To: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
References: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
Message-ID: <20241211-arm64-2024-dpisa-v4-8-0fd403876df2@kernel.org>

ID_AA64ISAR3_EL1 is currently marked as unallocated in KVM but does have a
number of bitfields defined in it. Expose FPRCVT and FAMINMAX, two simple
instruction only extensions to guests.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 83c6b4a07ef56cf0ed9c8751ec80686f45dca6b2..6efbe3f4a579afd1874c4cf844c1c1249ae8b942 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1604,6 +1604,9 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
 		if (!cpus_have_final_cap(ARM64_HAS_WFXT))
 			val &= ~ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_WFxT);
 		break;
+	case SYS_ID_AA64ISAR3_EL1:
+		val &= ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_FAMINMAX;
+		break;
 	case SYS_ID_AA64MMFR2_EL1:
 		val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK;
 		break;
@@ -2608,7 +2611,8 @@ 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_FPRCVT |
+				       ID_AA64ISAR3_EL1_FAMINMAX)),
 	ID_UNALLOCATED(6,4),
 	ID_UNALLOCATED(6,5),
 	ID_UNALLOCATED(6,6),

-- 
2.39.5



From broonie at kernel.org  Tue Dec 10 17:02:45 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:45 +0000
Subject: [PATCH v4 0/9] arm64: Support 2024 dpISA extensions
Message-ID: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>

The 2024 architecture release includes a number of data processing
extensions, mostly SVE and SME additions with a few others.  These are
all very straightforward extensions which add instructions but no
architectural state so only need hwcaps and exposing of the ID registers
to KVM guests and userspace.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v4:
- Fix encodings for ID_AA64ISAR3_EL1.
- Link to v3: https://lore.kernel.org/r/20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297 at kernel.org

Changes in v3:
- Commit log update for the hwcap test.
- Link to v2: https://lore.kernel.org/r/20241030-arm64-2024-dpisa-v2-0-b6601a15d2a5 at kernel.org

Changes in v2:
- Filter KVM guest visible bitfields in ID_AA64ISAR3_EL1 to only those
  we make writeable.
- Link to v1: https://lore.kernel.org/r/20241028-arm64-2024-dpisa-v1-0-a38d08b008a8 at kernel.org

---
Mark Brown (9):
      arm64/sysreg: Update ID_AA64PFR2_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64FPFR0_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64ZFR0_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64SMFR0_EL1 to DDI0601 2024-09
      arm64/sysreg: Update ID_AA64ISAR2_EL1 to DDI0601 2024-09
      arm64/hwcap: Describe 2024 dpISA extensions to userspace
      KVM: arm64: Allow control of dpISA extensions in ID_AA64ISAR3_EL1
      kselftest/arm64: Add 2024 dpISA extensions to hwcap test

 Documentation/arch/arm64/elf_hwcaps.rst   |  51 ++++++
 arch/arm64/include/asm/hwcap.h            |  17 ++
 arch/arm64/include/uapi/asm/hwcap.h       |  17 ++
 arch/arm64/kernel/cpufeature.c            |  35 ++++
 arch/arm64/kernel/cpuinfo.c               |  17 ++
 arch/arm64/kvm/sys_regs.c                 |   6 +-
 arch/arm64/tools/sysreg                   |  87 +++++++++-
 tools/testing/selftests/arm64/abi/hwcap.c | 273 +++++++++++++++++++++++++++++-
 8 files changed, 493 insertions(+), 10 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241008-arm64-2024-dpisa-8091074a7f48

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Tue Dec 10 17:02:46 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:46 +0000
Subject: [PATCH v4 1/9] arm64/sysreg: Update ID_AA64PFR2_EL1 to DDI0601
 2024-09
In-Reply-To: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
References: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
Message-ID: <20241211-arm64-2024-dpisa-v4-1-0fd403876df2@kernel.org>

DDI0601 2024-09 defines a new feature flags in ID_AA64PFR2_EL1
describing support for injecting UNDEF exceptions, update sysreg to
include this.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index b081b54d6d227ed8300a6f129896647316f0b673..911f16c82ebd3ee98ffed965b02a5c6b153bc50c 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1010,7 +1010,12 @@ UnsignedEnum	35:32	FPMR
 	0b0000	NI
 	0b0001	IMP
 EndEnum
-Res0	31:12
+Res0	31:20
+UnsignedEnum	19:16	UINJ
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+Res0	15:12
 UnsignedEnum	11:8	MTEFAR
 	0b0000	NI
 	0b0001	IMP

-- 
2.39.5



From broonie at kernel.org  Tue Dec 10 17:02:47 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:47 +0000
Subject: [PATCH v4 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
References: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
Message-ID: <20241211-arm64-2024-dpisa-v4-2-0fd403876df2@kernel.org>

DDI0601 2024-09 defines several new feature flags in ID_AA64ISAR3_EL1,
update our description in sysreg to reflect these.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 911f16c82ebd3ee98ffed965b02a5c6b153bc50c..6273068fd4fdef145cb7dd49e2d9bee4db467975 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1566,7 +1566,23 @@ EndEnum
 EndSysreg
 
 Sysreg	ID_AA64ISAR3_EL1	3	0	0	6	3
-Res0	63:16
+Res0	63:32
+UnsignedEnum	31:28	FPRCVT
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	27:24	LSUI
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	23:20	OCCMO
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	19:16	LSFE
+	0b0000	NI
+	0b0001	IMP
+EndEnum
 UnsignedEnum	15:12	PACM
 	0b0000	NI
 	0b0001	TRIVIAL_IMP

-- 
2.39.5



From broonie at kernel.org  Tue Dec 10 17:02:48 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:48 +0000
Subject: [PATCH v4 3/9] arm64/sysreg: Update ID_AA64FPFR0_EL1 to DDI0601
 2024-09
In-Reply-To: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
References: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
Message-ID: <20241211-arm64-2024-dpisa-v4-3-0fd403876df2@kernel.org>

DDI0601 2024-09 defines two new feature flags in ID_AA64FPFR0_EL1
describing new FP8 operations, describe them in sysreg.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 6273068fd4fdef145cb7dd49e2d9bee4db467975..14284a120a5796bb510a0382984236eba9bf73ab 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1180,7 +1180,15 @@ UnsignedEnum	28	F8DP2
 	0b0	NI
 	0b1	IMP
 EndEnum
-Res0	27:2
+UnsignedEnum	27	F8MM8
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	26	F8MM4
+	0b0	NI
+	0b1	IMP
+EndEnum
+Res0	25:2
 UnsignedEnum	1	F8E4M3
 	0b0	NI
 	0b1	IMP

-- 
2.39.5



From broonie at kernel.org  Tue Dec 10 17:02:49 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:49 +0000
Subject: [PATCH v4 4/9] arm64/sysreg: Update ID_AA64ZFR0_EL1 to DDI0601
 2024-09
In-Reply-To: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
References: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
Message-ID: <20241211-arm64-2024-dpisa-v4-4-0fd403876df2@kernel.org>

DDI0601 2024-09 introduces SVE 2.2 as well as a few new optional features,
update sysreg to reflect the changes in ID_AA64ZFR0_EL1 enumerating them.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 14284a120a5796bb510a0382984236eba9bf73ab..c792bd3b0afbb5fb7e438a4d760d9f2d15621eee 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1040,7 +1040,10 @@ UnsignedEnum	55:52	F32MM
 	0b0000	NI
 	0b0001	IMP
 EndEnum
-Res0	51:48
+UnsignedEnum	51:48	F16MM
+	0b0000	NI
+	0b0001	IMP
+EndEnum
 UnsignedEnum	47:44	I8MM
 	0b0000	NI
 	0b0001	IMP
@@ -1058,6 +1061,7 @@ Res0	31:28
 UnsignedEnum	27:24	B16B16
 	0b0000	NI
 	0b0001	IMP
+	0b0010	BFSCALE
 EndEnum
 UnsignedEnum	23:20	BF16
 	0b0000	NI
@@ -1068,16 +1072,22 @@ UnsignedEnum	19:16	BitPerm
 	0b0000	NI
 	0b0001	IMP
 EndEnum
-Res0	15:8
+UnsignedEnum	15:12	EltPerm
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+Res0	11:8
 UnsignedEnum	7:4	AES
 	0b0000	NI
 	0b0001	IMP
 	0b0010	PMULL128
+	0b0011	AES2
 EndEnum
 UnsignedEnum	3:0	SVEver
 	0b0000	IMP
 	0b0001	SVE2
 	0b0010	SVE2p1
+	0b0011	SVE2p2
 EndEnum
 EndSysreg
 

-- 
2.39.5



From broonie at kernel.org  Tue Dec 10 17:02:50 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:50 +0000
Subject: [PATCH v4 5/9] arm64/sysreg: Update ID_AA64SMFR0_EL1 to DDI0601
 2024-09
In-Reply-To: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
References: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
Message-ID: <20241211-arm64-2024-dpisa-v4-5-0fd403876df2@kernel.org>

DDI0601 2024-09 introduces SME 2.2 as well as a few new optional features,
update sysreg to reflect the changes in ID_AA64SMFR0_EL1 enumerating them.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/tools/sysreg | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index c792bd3b0afbb5fb7e438a4d760d9f2d15621eee..d78b12c59658b480739ae797f5ea2c2f14d8d765 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1105,6 +1105,7 @@ UnsignedEnum	59:56	SMEver
 	0b0000	SME
 	0b0001	SME2
 	0b0010	SME2p1
+	0b0011	SME2p2
 	0b0000	IMP
 EndEnum
 UnsignedEnum	55:52	I16I64
@@ -1169,7 +1170,36 @@ UnsignedEnum	28	SF8DP2
 	0b0	NI
 	0b1	IMP
 EndEnum
-Res0	27:0
+UnsignedEnum	27	SF8MM8
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	26	SF8MM4
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	25	SBitPerm
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	24	AES
+	0b0	NI
+	0b1	IMP
+EndEnum
+UnsignedEnum	23	SFEXPA
+	0b0	NI
+	0b1	IMP
+EndEnum
+Res0	22:17
+UnsignedEnum	16	STMOP
+	0b0	NI
+	0b1	IMP
+EndEnum
+Res0	15:1
+UnsignedEnum	0	SMOP4
+	0b0	NI
+	0b1	IMP
+EndEnum
 EndSysreg
 
 Sysreg	ID_AA64FPFR0_EL1	3	0	0	4	7

-- 
2.39.5



From broonie at kernel.org  Tue Dec 10 17:02:54 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 01:02:54 +0000
Subject: [PATCH v4 9/9] kselftest/arm64: Add 2024 dpISA extensions to hwcap
 test
In-Reply-To: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
References: <20241211-arm64-2024-dpisa-v4-0-0fd403876df2@kernel.org>
Message-ID: <20241211-arm64-2024-dpisa-v4-9-0fd403876df2@kernel.org>

Add coverage of the hwcaps for the 2024 dpISA extensions to the hwcap
test.

We don't actually test SIGILL generation for CMPBR since the need to
branch makes it a pain to generate and the SIGILL detection would be
unreliable anyway. Since this should be very unusual we provide a stub
function rather than supporting a missing test.

The sigill functions aren't well sorted in the file so the ordering is a
bit random.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/hwcap.c | 273 +++++++++++++++++++++++++++++-
 1 file changed, 271 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c
index 0029ed9c5c9aa4451f3d0573ee672eca993fb2f4..2a230cfa4cb4108580a16161e2df03a513710dbc 100644
--- a/tools/testing/selftests/arm64/abi/hwcap.c
+++ b/tools/testing/selftests/arm64/abi/hwcap.c
@@ -46,6 +46,12 @@ static void atomics_sigill(void)
 	asm volatile(".inst 0xb82003ff" : : : );
 }
 
+static void cmpbr_sigill(void)
+{
+	/* Not implemented, too complicated and unreliable anyway */
+}
+
+
 static void crc32_sigill(void)
 {
 	/* CRC32W W0, W0, W1 */
@@ -82,6 +88,18 @@ static void f8fma_sigill(void)
 	asm volatile(".inst 0xec0fc00");
 }
 
+static void f8mm4_sigill(void)
+{
+	/* FMMLA V0.4SH, V0.16B, V0.16B */
+	asm volatile(".inst 0x6e00ec00");
+}
+
+static void f8mm8_sigill(void)
+{
+	/* FMMLA V0.4S, V0.16B, V0.16B */
+	asm volatile(".inst 0x6e80ec00");
+}
+
 static void faminmax_sigill(void)
 {
 	/* FAMIN V0.4H, V0.4H, V0.4H */
@@ -98,6 +116,12 @@ static void fpmr_sigill(void)
 	asm volatile("mrs x0, S3_3_C4_C4_2" : : : "x0");
 }
 
+static void fprcvt_sigill(void)
+{
+	/* FCVTAS S0, H0 */
+	asm volatile(".inst 0x1efa0000");
+}
+
 static void gcs_sigill(void)
 {
 	unsigned long *gcspr;
@@ -226,6 +250,42 @@ static void sme2p1_sigill(void)
 	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
 }
 
+static void sme2p2_sigill(void)
+{
+	/* SMSTART SM */
+	asm volatile("msr S0_3_C4_C3_3, xzr" : : : );
+
+	/* UXTB Z0.D, P0/Z, Z0.D  */
+	asm volatile(".inst 0x4c1a000" : : : );
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void sme_aes_sigill(void)
+{
+	/* SMSTART SM */
+	asm volatile("msr S0_3_C4_C3_3, xzr" : : : );
+
+	/* AESD z0.b, z0.b, z0.b */
+	asm volatile(".inst 0x4522e400" : : : "z0");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void sme_sbitperm_sigill(void)
+{
+	/* SMSTART SM */
+	asm volatile("msr S0_3_C4_C3_3, xzr" : : : );
+
+	/* BDEP Z0.B, Z0.B, Z0.B */
+	asm volatile(".inst 0x4500b400" : : : "z0");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
 static void smei16i32_sigill(void)
 {
 	/* SMSTART */
@@ -334,13 +394,73 @@ static void smesf8dp4_sigill(void)
 	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
 }
 
+static void smesf8mm8_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* FMMLA V0.4S, V0.16B, V0.16B */
+	asm volatile(".inst 0x6e80ec00");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smesf8mm4_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* FMMLA V0.4SH, V0.16B, V0.16B */
+	asm volatile(".inst 0x6e00ec00");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
 static void smesf8fma_sigill(void)
 {
 	/* SMSTART */
 	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
 
-	/* FMLALB V0.8H, V0.16B, V0.16B */
-	asm volatile(".inst 0xec0fc00");
+	/* FMLALB Z0.8H, Z0.B, Z0.B */
+	asm volatile(".inst 0x64205000");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smesfexpa_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* FEXPA Z0.D, Z0.D */
+	asm volatile(".inst 0x04e0b800");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smesmop4_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* SMOP4A ZA0.S, Z0.B, { Z0.B - Z1.B } */
+	asm volatile(".inst 0x80108000");
+
+	/* SMSTOP */
+	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smestmop_sigill(void)
+{
+	/* SMSTART */
+	asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+	/* STMOPA ZA0.S, { Z0.H - Z1.H }, Z0.H, Z20[0] */
+	asm volatile(".inst 0x80408008");
 
 	/* SMSTOP */
 	asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
@@ -364,18 +484,42 @@ static void sve2p1_sigill(void)
 	asm volatile(".inst 0x65000000" : : : "z0");
 }
 
+static void sve2p2_sigill(void)
+{
+	/* NOT Z0.D, P0/Z, Z0.D */
+	asm volatile(".inst 0x4cea000" : : : "z0");
+}
+
 static void sveaes_sigill(void)
 {
 	/* AESD z0.b, z0.b, z0.b */
 	asm volatile(".inst 0x4522e400" : : : "z0");
 }
 
+static void sveaes2_sigill(void)
+{
+	/* AESD {Z0.B - Z1.B }, { Z0.B - Z1.B }, Z0.Q */
+	asm volatile(".inst 0x4522ec00" : : : "z0");
+}
+
 static void sveb16b16_sigill(void)
 {
 	/* BFADD Z0.H, Z0.H, Z0.H */
 	asm volatile(".inst 0x65000000" : : : );
 }
 
+static void svebfscale_sigill(void)
+{
+	/* BFSCALE Z0.H, P0/M, Z0.H, Z0.H */
+	asm volatile(".inst 0x65098000" : : : "z0");
+}
+
+static void svef16mm_sigill(void)
+{
+	/* FMMLA Z0.S, Z0.H, Z0.H */
+	asm volatile(".inst 0x6420e400");
+}
+
 static void svepmull_sigill(void)
 {
 	/* PMULLB Z0.Q, Z0.D, Z0.D */
@@ -394,6 +538,12 @@ static void svesha3_sigill(void)
 	asm volatile(".inst 0x4203800" : : : "z0");
 }
 
+static void sveeltperm_sigill(void)
+{
+	/* COMPACT Z0.B, P0, Z0.B */
+	asm volatile(".inst 0x5218000" : : : "x0");
+}
+
 static void svesm4_sigill(void)
 {
 	/* SM4E Z0.S, Z0.S, Z0.S */
@@ -469,6 +619,13 @@ static const struct hwcap_data {
 		.cpuinfo = "aes",
 		.sigill_fn = aes_sigill,
 	},
+	{
+		.name = "CMPBR",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_CMPBR,
+		.cpuinfo = "cmpbr",
+		.sigill_fn = cmpbr_sigill,
+	},
 	{
 		.name = "CRC32",
 		.at_hwcap = AT_HWCAP,
@@ -523,6 +680,20 @@ static const struct hwcap_data {
 		.cpuinfo = "f8fma",
 		.sigill_fn = f8fma_sigill,
 	},
+	{
+		.name = "F8MM8",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_F8MM8,
+		.cpuinfo = "f8mm8",
+		.sigill_fn = f8mm8_sigill,
+	},
+	{
+		.name = "F8MM4",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_F8MM4,
+		.cpuinfo = "f8mm4",
+		.sigill_fn = f8mm4_sigill,
+	},
 	{
 		.name = "FAMINMAX",
 		.at_hwcap = AT_HWCAP2,
@@ -545,6 +716,13 @@ static const struct hwcap_data {
 		.sigill_fn = fpmr_sigill,
 		.sigill_reliable = true,
 	},
+	{
+		.name = "FPRCVT",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_FPRCVT,
+		.cpuinfo = "fprcvt",
+		.sigill_fn = fprcvt_sigill,
+	},
 	{
 		.name = "GCS",
 		.at_hwcap = AT_HWCAP,
@@ -691,6 +869,20 @@ static const struct hwcap_data {
 		.cpuinfo = "sme2p1",
 		.sigill_fn = sme2p1_sigill,
 	},
+	{
+		.name = "SME 2.2",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME2P2,
+		.cpuinfo = "sme2p2",
+		.sigill_fn = sme2p2_sigill,
+	},
+	{
+		.name = "SME AES",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_AES,
+		.cpuinfo = "smeaes",
+		.sigill_fn = sme_aes_sigill,
+	},
 	{
 		.name = "SME I16I32",
 		.at_hwcap = AT_HWCAP2,
@@ -740,6 +932,13 @@ static const struct hwcap_data {
 		.cpuinfo = "smelutv2",
 		.sigill_fn = smelutv2_sigill,
 	},
+	{
+		.name = "SME SBITPERM",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SBITPERM,
+		.cpuinfo = "smesbitperm",
+		.sigill_fn = sme_sbitperm_sigill,
+	},
 	{
 		.name = "SME SF8FMA",
 		.at_hwcap = AT_HWCAP2,
@@ -747,6 +946,20 @@ static const struct hwcap_data {
 		.cpuinfo = "smesf8fma",
 		.sigill_fn = smesf8fma_sigill,
 	},
+	{
+		.name = "SME SF8MM8",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SF8MM8,
+		.cpuinfo = "smesf8mm8",
+		.sigill_fn = smesf8mm8_sigill,
+	},
+	{
+		.name = "SME SF8MM4",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SF8MM8,
+		.cpuinfo = "smesf8mm4",
+		.sigill_fn = smesf8mm4_sigill,
+	},
 	{
 		.name = "SME SF8DP2",
 		.at_hwcap = AT_HWCAP2,
@@ -761,6 +974,27 @@ static const struct hwcap_data {
 		.cpuinfo = "smesf8dp4",
 		.sigill_fn = smesf8dp4_sigill,
 	},
+	{
+		.name = "SME SFEXPA",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SFEXPA,
+		.cpuinfo = "smesfexpa",
+		.sigill_fn = smesfexpa_sigill,
+	},
+	{
+		.name = "SME SMOP4",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_SMOP4,
+		.cpuinfo = "smesmop4",
+		.sigill_fn = smesmop4_sigill,
+	},
+	{
+		.name = "SME STMOP",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SME_STMOP,
+		.cpuinfo = "smestmop",
+		.sigill_fn = smestmop_sigill,
+	},
 	{
 		.name = "SVE",
 		.at_hwcap = AT_HWCAP,
@@ -783,6 +1017,13 @@ static const struct hwcap_data {
 		.cpuinfo = "sve2p1",
 		.sigill_fn = sve2p1_sigill,
 	},
+	{
+		.name = "SVE 2.2",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE2P2,
+		.cpuinfo = "sve2p2",
+		.sigill_fn = sve2p2_sigill,
+	},
 	{
 		.name = "SVE AES",
 		.at_hwcap = AT_HWCAP2,
@@ -790,6 +1031,34 @@ static const struct hwcap_data {
 		.cpuinfo = "sveaes",
 		.sigill_fn = sveaes_sigill,
 	},
+	{
+		.name = "SVE AES2",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE_AES2,
+		.cpuinfo = "sveaes2",
+		.sigill_fn = sveaes2_sigill,
+	},
+	{
+		.name = "SVE BFSCALE",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE_BFSCALE,
+		.cpuinfo = "svebfscale",
+		.sigill_fn = svebfscale_sigill,
+	},
+	{
+		.name = "SVE ELTPERM",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE_ELTPERM,
+		.cpuinfo = "sveeltperm",
+		.sigill_fn = sveeltperm_sigill,
+	},
+	{
+		.name = "SVE F16MM",
+		.at_hwcap = AT_HWCAP,
+		.hwcap_bit = HWCAP_SVE_F16MM,
+		.cpuinfo = "svef16mm",
+		.sigill_fn = svef16mm_sigill,
+	},
 	{
 		.name = "SVE2 B16B16",
 		.at_hwcap = AT_HWCAP2,

-- 
2.39.5



From andersson at kernel.org  Tue Dec 10 17:13:52 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Tue, 10 Dec 2024 19:13:52 -0600
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>
 <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>
Message-ID: <iyknardi445n4h74am22arpgc4vlchh6z6cvkbff2xg76pd655@nozwz7snt476>

On Tue, Dec 10, 2024 at 02:22:27AM +0530, Akhil P Oommen wrote:
> On 12/10/2024 1:24 AM, Rob Clark wrote:
> > On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> >>
> >> When kernel is booted in EL2, SECVID registers are accessible to the
> >> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> >> on Zap firmware. Also, we can't load a secure firmware without a
> >> hypervisor that supports it.
> > 
> > Shouldn't we do this based on whether zap node is in dtb (and not disabled)?
> 
> This is better, isn't it? Otherwise, multiple overlays should be
> maintained for each soc/board since EL2 can be toggled from bootloader.
> And this feature is likely going to be more widely available.
> 

The DeviceTree passed to the OS needs to describe the world that said OS
is going to operate in. If you change the world you need to change the
description.
There are several other examples where this would be necessary
(remoteproc and watchdog to name two examples from the Qualcomm upstream
world).

So, if we can cover this by zap-shader being enabled or disabled, that
sounds like a clean and scaleable solution.

Regards,
Bjorn


From xueshuai at linux.alibaba.com  Tue Dec 10 17:24:09 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Wed, 11 Dec 2024 09:24:09 +0800
Subject: [PATCH] perf/dwc_pcie: Qualify RAS DES VSEC Capability by Vendor,
 Revision
In-Reply-To: <20241210145335.GA3239578@bhelgaas>
References: <20241210145335.GA3239578@bhelgaas>
Message-ID: <f8786f53-eff0-4fd7-9c4d-c5733f648c6e@linux.alibaba.com>



? 2024/12/10 22:53, Bjorn Helgaas ??:
> On Tue, Dec 10, 2024 at 08:04:17PM +0800, Shuai Xue wrote:
>> ? 2024/12/10 06:29, Bjorn Helgaas ??:
>>> From: Bjorn Helgaas <bhelgaas at google.com>
>>>
>>> PCI Vendor-Specific (VSEC) Capabilities are defined by each vendor.
>>> Devices from different vendors may advertise a VSEC Capability with the DWC
>>> RAS DES functionality, but the vendors may assign different VSEC IDs.
>>>
>>> Search for the DWC RAS DES Capability using the VSEC ID and VSEC Rev
>>> chosen by the vendor.
> 
>>> -	for (vid = dwc_pcie_vendor_ids; vid->vendor_id; vid++) {
>>> +	for (vid = dwc_pcie_pmu_vsec_ids; vid->vendor_id; vid++) {
>>
>> How about checking the pdev->vendor with vid->vendor_id before
>> search the vesc cap?
>>
>> +		if (pdev->vendor != vid->vendor_id)
>> +			continue;
> 
> Every user of VSEC needs to specify the (Vendor ID, VSEC ID) and
> verify that the Vendor ID matches the device Vendor ID, so
> pci_find_vsec_capability() does this check internally, so I don't
> think we need to do it here.


I see. LGTM. Also, I quickly tested it on Yitian 710 and it works as expected.

Reviewed-and-tested-by: Shuai Xue <xueshuai at linux.alibaba.com>

Thanks.

Best Regards,
Shuai


From trunixs.kim at samsung.com  Tue Dec 10 17:50:27 2024
From: trunixs.kim at samsung.com (=?utf-8?B?6rmA7YOc7JmE?=)
Date: Wed, 11 Dec 2024 10:50:27 +0900
Subject: [PATCH v4 1/1] arm64: dts: exynosautov920: add watchdog DT node
In-Reply-To: <510e826d-a434-437d-8d2e-3f2618c28b7f@kernel.org>
References: <20241206025139.2148833-1-trunixs.kim@samsung.com>
	<CGME20241206025156epcas2p4c55f230accc4354e6f4bf324ab9a5833@epcas2p4.samsung.com>
	<20241206025139.2148833-2-trunixs.kim@samsung.com>
	<510e826d-a434-437d-8d2e-3f2618c28b7f@kernel.org>
Message-ID: <000101db4b6f$0d31c460$27954d20$@samsung.com>

on 11/12/2024 01:50 UTC+09:00, Taewan Kim wrote:
>> From: Byoungtae Cho <bt.cho at samsung.com>
>>
>> Adds two watchdog devices for ExynosAutoV920 SoC.
>>
>> Signed-off-by: Byoungtae Cho <bt.cho at samsung.com>
>> Signed-off-by: Taewan Kim <trunixs.kim at samsung.com>
>> ---
>>  .../arm64/boot/dts/exynos/exynosautov920.dtsi | 20 +++++++++++++++++++
>>  1 file changed, 20 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
>b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
>> index c759134c909e..7b9591255e91 100644
>> --- a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
>> +++ b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
>> @@ -183,6 +183,26 @@ cmu_misc: clock-controller at 10020000 {
>>  				      "noc";
>>  		};
>>
>> +		watchdog_cl0: watchdog at 10060000 {
>
>You need to do careful rebase, not just accept whatever tools shown you.
>
>This is now placed in incorrect order - not keeping sorting by unit address.

I seems to me that the addresses are sorted correctly in order. 
Could you kindly check again?

        clock-controller at 1002_0000
                  watchdog at 1006_0000 
                  watchdog at 1007_0000
    interrupt-controller at 1040_0000

And if there are any rules I might not be aware of, please let me know.

Best regards,
Taewan Kim



From patchwork-bot+netdevbpf at kernel.org  Tue Dec 10 18:30:38 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 11 Dec 2024 02:30:38 +0000
Subject: [PATCH net-next v1] net: stmmac: Relocate extern declarations in
 common.h and hwif.h
In-Reply-To: <20241208070202.203931-1-0x1207@gmail.com>
References: <20241208070202.203931-1-0x1207@gmail.com>
Message-ID: <173388423806.1090195.16162842583087657883.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Sun,  8 Dec 2024 15:02:02 +0800 you wrote:
> The extern declarations should be in a header file that corresponds to
> their definition, move these extern declarations to its header file.
> Some of them have nowhere to go, so move them to hwif.h since they are
> referenced in hwif.c only.
> 
> dwmac100_* dwmac1000_* dwmac4_* dwmac410_* dwmac510_* stay in hwif.h,
> otherwise you will be flooded with name conflicts from dwmac100.h,
> dwmac1000.h and dwmac4.h if hwif.c try to #include these .h files.
> 
> [...]

Here is the summary with links:
  - [net-next,v1] net: stmmac: Relocate extern declarations in common.h and hwif.h
    https://git.kernel.org/netdev/net-next/c/46afe345ff18

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From ck.hu at mediatek.com  Tue Dec 10 18:46:43 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Wed, 11 Dec 2024 02:46:43 +0000
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
Message-ID: <a07fdebcad66bf85c30da1323e655b29df1ee108.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +enum hdmi_hpd_state {

This is used only by v2. So move to patch [15/15].

Regards,
CK

> +       HDMI_PLUG_OUT = 0,
> +       HDMI_PLUG_IN_AND_SINK_POWER_ON,
> +       HDMI_PLUG_IN_ONLY,
> +};
> +
> 2.47.0
> 


From dsimic at manjaro.org  Tue Dec 10 18:54:22 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 11 Dec 2024 03:54:22 +0100
Subject: [PATCH 1/6] pmdomain: rockchip: fix rockchip_pd_power error
 handling
In-Reply-To: <CAMdYzYqmn0UktNfz7L352zcjgmxf4tsRs2fwiFXF7NbfPY4zSg@mail.gmail.com>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-2-pgwipeout@gmail.com>
 <1b323d6e9ef873bfc770e9d54b7a3a64@manjaro.org>
 <CAMdYzYqmn0UktNfz7L352zcjgmxf4tsRs2fwiFXF7NbfPY4zSg@mail.gmail.com>
Message-ID: <821c348ef4b8e199e662d6a49430d1e7@manjaro.org>

Hello Peter,

On 2024-12-10 21:12, Peter Geis wrote:
> On Tue, Dec 10, 2024 at 3:18?AM Dragan Simic <dsimic at manjaro.org> 
> wrote:
>> On 2024-12-10 02:30, Peter Geis wrote:
>> > The calls rockchip_pd_power makes to rockchip_pmu_set_idle_request lack
>> > any return error handling, causing device drivers to incorrectly
>> > believe
>> > the hardware idle requests succeed when they may have failed. This
>> > leads
>> > to software possibly accessing hardware that is powered off and the
>> > subsequent SError panic that follows.
>> >
>> > Add error checking and return errors to the calling function to prevent
>> > such crashes.
>> >
>> > gst-launch-1.0 videotestsrc num-buffers=2000 ! v4l2jpegenc ! fakesink
>> > Setting pipeline to PAUSED ...er-x64
>> > Pipeline is PREROLLING ...
>> > Redistribute latency...
>> > rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack
>> > on
>> > domain 'hevc', val=0x98260, idle = 0
>> > SError Interrupt on CPU2, code 0x00000000bf000002 -- SError
>> > CPU: 2 UID: 0 PID: 804 Comm: videotestsrc0:s Not tainted 6.12.0-rc5+
>> > #54
>> > Hardware name: Firefly roc-rk3328-cc (DT)
>> > pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>> > pc : rockchip_vpu2_jpeg_enc_run+0x168/0xbc8
>> > lr : device_run+0xb0/0x128
>> > sp : ffff800082143a20
>> > x29: ffff800082143a20 x28: 0000000000000140 x27: 0000000000000000
>> > x26: ffff582c47a313e8 x25: ffff582c53e95000 x24: ffff582c53e92800
>> > x23: ffff582c5bbe0000 x22: 0000000000000000 x21: ffff582c47a31080
>> > x20: ffffa0d78cfa4168 x19: ffffa0d78cfa4168 x18: ffffb755b0519000
>> > x17: 000000040044ffff x16: 00500072b5503510 x15: a7a6a5a4a3a29a99
>> > x14: 989796959493928a x13: 0000000051eb851f x12: 00000000000000ff
>> > x11: ffffa0d78d812880 x10: ffffa0d78d7fbca0 x9 : 000000000000003f
>> > x8 : 0000000000000063 x7 : 000000000000003f x6 : 0000000000000040
>> > x5 : ffff80008010d000 x4 : ffffa0d78cfa4168 x3 : ffffa0d78cfbfdd8
>> > x2 : ffff80008010d0f4 x1 : 0000000000000020 x0 : 0000000000000140
>> > Kernel panic - not syncing: Asynchronous SError Interrupt
>> > CPU: 2 UID: 0 PID: 804 Comm: videotestsrc0:s Not tainted 6.12.0-rc5+
>> > #54
>> > Hardware name: Firefly roc-rk3328-cc (DT)
>> > Call trace:
>> > dump_backtrace+0xa0/0x128
>> > show_stack+0x20/0x38
>> > dump_stack_lvl+0xc8/0xf8
>> > dump_stack+0x18/0x28
>> > panic+0x3ec/0x428
>> > nmi_panic+0x48/0xa0
>> > arm64_serror_panic+0x6c/0x88
>> > do_serror+0x30/0x70
>> > el1h_64_error_handler+0x38/0x60
>> > el1h_64_error+0x7c/0x80
>> > rockchip_vpu2_jpeg_enc_run+0x168/0xbc8
>> > device_run+0xb0/0x128
>> > v4l2_m2m_try_run+0xac/0x230
>> > v4l2_m2m_ioctl_streamon+0x70/0x90
>> > v4l_streamon+0x2c/0x40
>> > __video_do_ioctl+0x194/0x400
>> > video_usercopy+0x10c/0x808
>> > video_ioctl2+0x20/0x80
>> > v4l2_ioctl+0x48/0x70
>> > __arm64_sys_ioctl+0xb0/0x100
>> > invoke_syscall+0x50/0x120
>> > el0_svc_common.constprop.0+0x48/0xf0
>> > do_el0_svc+0x24/0x38
>> > el0_svc+0x38/0x100
>> > el0t_64_sync_handler+0xc0/0xc8
>> > el0t_64_sync+0x1a8/0x1b0
>> > SMP: stopping secondary CPUs
>> > Kernel Offset: 0x20d70c000000 from 0xffff800080000000
>> > PHYS_OFFSET: 0xffffa7d3c0000000
>> > CPU features: 0x00,00000090,00200000,0200421b
>> > Memory Limit: none
>> > ---[ end Kernel panic - not syncing: Asynchronous SError Interrupt ]---
>> >
>> > Fixes: 7c696693a4f5 ("soc: rockchip: power-domain: Add power domain
>> > driver")
>> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>> 
>> This patch is obviously correct, because not checking what
>> rockchip_pmu_set_idle_request() returns was simply wrong.
>> Thanks for the patch!
>> 
>> Though, shouldn't we improve further the way proper error
>> handling is performed in rockchip_do_pmu_set_power_domain(),
>> by "rolling back" what rockchip_do_pmu_set_power_domain()
>> did after powering up fails?
> 
> Eventually, but the reality is if we hit this path the hardware is
> already broken. I wanted to provide a fix with the least amount of
> risk of breaking things further. I'm open to suggestions for further
> improvements here.

Perhaps a good approach, at the moment, would be to add no more
code for the "rollback", but to add a TODO note about the need for
that addition.  That way we'd keep the amount of changes at the
minimum, to hopefully not cause any regressions, while leaving
a note for the second round of improvements in the future.

> Current behavior with this patch with the example above causes
> gstreamer to wait indefinitely. I'll trace the return path and see if
> returning an error other than -ETIMEDOUT triggers more robust
> handling.

Sounds like a plan to me.  Thanks for working on this!

>> 
>> > ---
>> >
>> >  drivers/pmdomain/rockchip/pm-domains.c | 8 ++++++--
>> >  1 file changed, 6 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/pmdomain/rockchip/pm-domains.c
>> > b/drivers/pmdomain/rockchip/pm-domains.c
>> > index cb0f93800138..57e8fa25d2bd 100644
>> > --- a/drivers/pmdomain/rockchip/pm-domains.c
>> > +++ b/drivers/pmdomain/rockchip/pm-domains.c
>> > @@ -590,14 +590,18 @@ static int rockchip_pd_power(struct
>> > rockchip_pm_domain *pd, bool power_on)
>> >                       rockchip_pmu_save_qos(pd);
>> >
>> >                       /* if powering down, idle request to NIU first */
>> > -                     rockchip_pmu_set_idle_request(pd, true);
>> > +                     ret = rockchip_pmu_set_idle_request(pd, true);
>> > +                     if (ret < 0)
>> > +                             return ret;
>> >               }
>> >
>> >               rockchip_do_pmu_set_power_domain(pd, power_on);
>> >
>> >               if (power_on) {
>> >                       /* if powering up, leave idle mode */
>> > -                     rockchip_pmu_set_idle_request(pd, false);
>> > +                     ret = rockchip_pmu_set_idle_request(pd, false);
>> > +                     if (ret < 0)
>> > +                             return ret;
>> >
>> >                       rockchip_pmu_restore_qos(pd);
>> >               }


From ankita at nvidia.com  Tue Dec 10 18:58:38 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Wed, 11 Dec 2024 02:58:38 +0000
Subject: [PATCH v2 1/1] KVM: arm64: Allow cacheable stage 2 mapping using
 VMA flags
In-Reply-To: <20241210141334.GD15607@willie-the-truck>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241118131958.4609-2-ankita@nvidia.com>
 <20241210141334.GD15607@willie-the-truck>
Message-ID: <SA1PR12MB71991EC85E8EEDD1C5115886B03E2@SA1PR12MB7199.namprd12.prod.outlook.com>

Thanks Will for taking a look.

>> The device memory such as on the Grace Hopper systems is interchangeable
>> with DDR memory and retains its properties. Allow executable faults
>> on the memory determined as Normal cacheable.
>
> Sorry, but a change this subtle to the arch code is going to need a _much_
> better explanation than the rambling text above.

Understood, I'll work on the text and try to make it coherent.


> I also suspect that you're trying to do too many things in one patch.
> In particular, the changes to execute permission handling absolutely
> need to be discussed as a single patch in the series.
>
> Please can you split this up in to a set of changes with useful commit
> messages so that we can review them?

Yes. I'll take out the execute permission part to a separate patch.


> Jason knows how to do this so you could ask him for help if you're stuck.
> Otherwise, there are plenty of examples of well-written commit messages
> on the mailing list and in the git history.

Ack.



From victor.liu at nxp.com  Tue Dec 10 19:05:52 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Wed, 11 Dec 2024 11:05:52 +0800
Subject: [PATCH v6 01/19] dt-bindings: display: imx: Add i.MX8qxp Display
 Controller processing units
In-Reply-To: <20241210221508.GA550635-robh@kernel.org>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
 <20241209033923.3009629-2-victor.liu@nxp.com>
 <20241210221508.GA550635-robh@kernel.org>
Message-ID: <30924a9e-7d01-46f6-9e47-405c08acdde3@nxp.com>

On 12/11/2024, Rob Herring wrote:
> On Mon, Dec 09, 2024 at 11:39:05AM +0800, Liu Ying wrote:
>> Freescale i.MX8qxp Display Controller is implemented as construction set of
>> building blocks with unified concept and standardized interfaces.  Document
>> all existing processing units.
>>
>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>> ---
>> v6:
>> * No change.
>>
>> v5:
>> * Document aliases for processing units which have multiple instances in
>>   the Display Controller.  Drop Rob's previous R-b tag. (Maxime)
>>
>> v4:
>> * Collect Rob's R-b tag.
>>
>> v3:
>> * Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
>>   fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
>>   into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
>> * Document all processing units. (Rob)
>>
>> v2:
>> * Drop fsl,dc-*-id DT properties. (Krzysztof)
>> * Add port property to fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
>> * Fix register range sizes in examples.
>>
>>  .../display/imx/fsl,imx8qxp-dc-blitblend.yaml |  46 ++++++
>>  .../display/imx/fsl,imx8qxp-dc-clut.yaml      |  49 ++++++
>>  .../imx/fsl,imx8qxp-dc-constframe.yaml        |  49 ++++++
>>  .../display/imx/fsl,imx8qxp-dc-dither.yaml    |  49 ++++++
>>  .../display/imx/fsl,imx8qxp-dc-extdst.yaml    |  77 +++++++++
>>  .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 ++++++++++++++++++
>>  .../display/imx/fsl,imx8qxp-dc-filter.yaml    |  47 ++++++
>>  .../display/imx/fsl,imx8qxp-dc-framegen.yaml  |  68 ++++++++
>>  .../display/imx/fsl,imx8qxp-dc-gammacor.yaml  |  38 +++++
>>  .../imx/fsl,imx8qxp-dc-layerblend.yaml        |  45 ++++++
>>  .../display/imx/fsl,imx8qxp-dc-matrix.yaml    |  48 ++++++
>>  .../display/imx/fsl,imx8qxp-dc-rop.yaml       |  48 ++++++
>>  .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++++
>>  .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  89 +++++++++++
>>  .../display/imx/fsl,imx8qxp-dc-signature.yaml |  58 +++++++
>>  .../display/imx/fsl,imx8qxp-dc-store.yaml     | 100 ++++++++++++
>>  .../display/imx/fsl,imx8qxp-dc-tcon.yaml      |  50 ++++++
>>  17 files changed, 1042 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
>> new file mode 100644
>> index 000000000000..7f800e72c3f3
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
>> @@ -0,0 +1,46 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blitblend.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Freescale i.MX8qxp Display Controller Blit Blend Unit
>> +
>> +description: |
>> +  Combines two input frames to a single output frame, all frames having the
>> +  same dimension.
>> +
>> +  Each Blit Blend Unit device should have an alias in the aliases node, in the
>> +  form of dc<x>-blitblend<y>, where <x> is an integer specifying the Display
>> +  Controller instance and <y> is an integer specifying the Blit Blend Unit
>> +  device instance.
> 
> That's really an abuse of aliases. If you need to describe connections 
> between components, use the graph binding like everyone else does for 
> display path components.

I need to describe components' instance numbers which imply the connections
between components but not vice versa. If I use the graph binding, I cannot
get the instance numbers(0 or 1) of the two display engines(documented by
fsl,imx8qxp-dc-display-engine.yaml). If you have no objections, I may add the
instance numbers to compatible strings, like brcm,bcm2835-pixelvalve0.yaml.
What do you think?

> 
> Rob

-- 
Regards,
Liu Ying


From ankita at nvidia.com  Tue Dec 10 19:05:23 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Wed, 11 Dec 2024 03:05:23 +0000
Subject: [PATCH v2 0/1] KVM: arm64: Map GPU memory with no struct pages
In-Reply-To: <Z1hnZ0H13Pst5sKF@arm.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241210140739.GC15607@willie-the-truck>
 <20241210141806.GI2347147@nvidia.com>
 <0723d890-1f90-463b-a814-9f7bb7e2200b@redhat.com> <Z1hnZ0H13Pst5sKF@arm.com>
Message-ID: <SA1PR12MB7199357D481FF766F958DD34B03E2@SA1PR12MB7199.namprd12.prod.outlook.com>

> IOW, I'm looking for a complete, clear (set of) statement(s) that
> Ankit can implement to get this (requested) series moving forward,
> sooner than later; it's already been a year+ to get to this point, and
> I don't want further ambiguity/uncertainty to drag it out more than needed.

Yes, I'll be working on this series to get to conclusion. I'll fix the text and
split the patch as suggested. Moreover, I'll see what Catalin has to say on
the MTE part. Based on that I'll resend the patch series.

Thanks
Ankit

From quic_akhilpo at quicinc.com  Tue Dec 10 19:08:15 2024
From: quic_akhilpo at quicinc.com (Akhil P Oommen)
Date: Wed, 11 Dec 2024 08:38:15 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <iyknardi445n4h74am22arpgc4vlchh6z6cvkbff2xg76pd655@nozwz7snt476>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>
 <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>
 <iyknardi445n4h74am22arpgc4vlchh6z6cvkbff2xg76pd655@nozwz7snt476>
Message-ID: <1219b46d-2aea-4377-a8ca-024039ee1499@quicinc.com>

On 12/11/2024 6:43 AM, Bjorn Andersson wrote:
> On Tue, Dec 10, 2024 at 02:22:27AM +0530, Akhil P Oommen wrote:
>> On 12/10/2024 1:24 AM, Rob Clark wrote:
>>> On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
>>>>
>>>> When kernel is booted in EL2, SECVID registers are accessible to the
>>>> KMD. So we can use that to switch GPU's secure mode to avoid dependency
>>>> on Zap firmware. Also, we can't load a secure firmware without a
>>>> hypervisor that supports it.
>>>
>>> Shouldn't we do this based on whether zap node is in dtb (and not disabled)?
>>
>> This is better, isn't it? Otherwise, multiple overlays should be
>> maintained for each soc/board since EL2 can be toggled from bootloader.
>> And this feature is likely going to be more widely available.
>>
> 
> The DeviceTree passed to the OS needs to describe the world that said OS
> is going to operate in. If you change the world you need to change the
> description.
> There are several other examples where this would be necessary
> (remoteproc and watchdog to name two examples from the Qualcomm upstream
> world).

But basic things work without those changes, right? For eg: Desktop UI

> 
> So, if we can cover this by zap-shader being enabled or disabled, that
> sounds like a clean and scaleable solution.

I think we are focusing too much on zap shader. If the driver can
determine itself about access to its register, shouldn't it be allowed
to use that?

-Akhil

> 
> Regards,
> Bjorn



From quic_akhilpo at quicinc.com  Tue Dec 10 19:09:21 2024
From: quic_akhilpo at quicinc.com (Akhil P Oommen)
Date: Wed, 11 Dec 2024 08:39:21 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <20241210125012120-0800.eberman@hu-eberman-lv.qualcomm.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <20241210125012120-0800.eberman@hu-eberman-lv.qualcomm.com>
Message-ID: <0df78884-e734-4d34-adf0-c5cba2a0d9da@quicinc.com>

On 12/11/2024 2:24 AM, Elliot Berman wrote:
> On Mon, Dec 09, 2024 at 01:49:15PM +0530, Akhil P Oommen wrote:
>> When kernel is booted in EL2, SECVID registers are accessible to the
>> KMD. So we can use that to switch GPU's secure mode to avoid dependency
>> on Zap firmware. Also, we can't load a secure firmware without a
>> hypervisor that supports it.
>>
>> Tested following configurations on sa8775p chipset (Adreno 663 gpu):
>>
>> 1. Gunyah (No KVM) - Loads zap shader based on DT
>> 2. KVM in VHE - Skips zap shader load and programs SECVID register
>> 3. KVM in nVHE - Loads zap shader based on DT
> 
> I think this might be misleading. As I understand, KVM in nVHE doesn't
> support loading secure firmware. I'm not aware of any support added to
> make it work. So, the driver will try to load zap shader and it fails
> same as it does today.
>

I see that now. I was trying to document the decision logic in each case.

-Akhil.

>> 4. Kernel in EL2 with CONFIG_KVM=n - Skips zap shader load and
>> 	programs SECVID register
>>
>> For (1) and (3) configuration, this patch doesn't have any impact.
>> Driver loads secure firmware based on other existing hints.
>>
>> Signed-off-by: Akhil P Oommen <quic_akhilpo at quicinc.com>
>> ---
>> ---
>>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 +++++++++++++++++++++++------------
>>  1 file changed, 54 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> index 019610341df1..9dcaa8472430 100644
>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> @@ -14,6 +14,10 @@
>>  #include <linux/pm_domain.h>
>>  #include <linux/soc/qcom/llcc-qcom.h>
>>  
>> +#ifdef CONFIG_ARM64
>> +#include <asm/virt.h>
>> +#endif
>> +
>>  #define GPU_PAS_ID 13
>>  
>>  static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
>> @@ -998,6 +1002,54 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
>>  	return ret;
>>  }
>>  
>> +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
>> +{
>> +	int ret;
>> +
>> +#ifdef CONFIG_ARM64
>> +	/*
>> +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
>> +	 * to switch the secure mode to avoid the dependency on zap shader.
>> +	 */
>> +	if (is_kernel_in_hyp_mode())
>> +		goto direct_switch;
>> +#endif
>> +
>> +	/*
>> +	 * Try to load a zap shader into the secure world. If successful
>> +	 * we can use the CP to switch out of secure mode. If not then we
>> +	 * have no resource but to try to switch ourselves out manually. If we
>> +	 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
>> +	 * be blocked and a permissions violation will soon follow.
>> +	 */
>> +	ret = a6xx_zap_shader_init(gpu);
>> +	if (ret == -ENODEV) {
>> +		/*
>> +		 * This device does not use zap shader (but print a warning
>> +		 * just in case someone got their dt wrong.. hopefully they
>> +		 * have a debug UART to realize the error of their ways...
>> +		 * if you mess this up you are about to crash horribly)
>> +		 */
>> +		dev_warn_once(gpu->dev->dev,
>> +			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
>> +		goto direct_switch;
>> +	} else if (ret)
>> +		return ret;
>> +
>> +	OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
>> +	OUT_RING(gpu->rb[0], 0x00000000);
>> +
>> +	a6xx_flush(gpu, gpu->rb[0]);
>> +	if (!a6xx_idle(gpu, gpu->rb[0]))
>> +		return -EINVAL;
>> +
>> +	return 0;
>> +
>> +direct_switch:
>> +	gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
>> +	return 0;
>> +}
>> +
>>  #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
>>  		       A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
>>  		       A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
>> @@ -1341,35 +1393,9 @@ static int hw_init(struct msm_gpu *gpu)
>>  	if (ret)
>>  		goto out;
>>  
>> -	/*
>> -	 * Try to load a zap shader into the secure world. If successful
>> -	 * we can use the CP to switch out of secure mode. If not then we
>> -	 * have no resource but to try to switch ourselves out manually. If we
>> -	 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
>> -	 * be blocked and a permissions violation will soon follow.
>> -	 */
>> -	ret = a6xx_zap_shader_init(gpu);
>> -	if (!ret) {
>> -		OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
>> -		OUT_RING(gpu->rb[0], 0x00000000);
>> -
>> -		a6xx_flush(gpu, gpu->rb[0]);
>> -		if (!a6xx_idle(gpu, gpu->rb[0]))
>> -			return -EINVAL;
>> -	} else if (ret == -ENODEV) {
>> -		/*
>> -		 * This device does not use zap shader (but print a warning
>> -		 * just in case someone got their dt wrong.. hopefully they
>> -		 * have a debug UART to realize the error of their ways...
>> -		 * if you mess this up you are about to crash horribly)
>> -		 */
>> -		dev_warn_once(gpu->dev->dev,
>> -			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
>> -		gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
>> -		ret = 0;
>> -	} else {
>> +	ret = a6xx_switch_secure_mode(gpu);
>> +	if (!ret)
>>  		return ret;
>> -	}
>>  
>>  out:
>>  	if (adreno_has_gmu_wrapper(adreno_gpu))
>>
>> ---
>> base-commit: f4a867a46862c1743501bbe8c813238456ec8699
>> change-id: 20241120-drm-msm-kvm-support-cd6e6744ced6
>>
>> Best regards,
>> -- 
>> Akhil P Oommen <quic_akhilpo at quicinc.com>
>>



From jason-jh.lin at mediatek.com  Tue Dec 10 19:22:53 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:22:53 +0800
Subject: [PATCH v2 5/8] soc: mediatek: mtk-cmdq: Add mminfra_offset compatibility for DRAM address
In-Reply-To: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
Message-ID: <20241211032256.28494-6-jason-jh.lin@mediatek.com>

Since GCE has been moved to mminfra in MT8196, all transactions from
mminfra to DRAM will have their addresses adjusted by subtracting a
mminfra offset.
This information should be handled inside the CMDQ driver, allowing
CMDQ users to call CMDQ APIs as usual.

Therefore, CMDQ driver needs to use the mbox API to get the
mminfra_offset value of the SoC, and then add it to the DRAM address
when generating instructions to ensure GCE accesses the correct DRAM
address.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 35 ++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 87734639c37c..623f89cd7448 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -314,10 +314,22 @@ EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
 int cmdq_pkt_mem_move(struct cmdq_pkt *pkt, dma_addr_t src_addr, dma_addr_t dst_addr)
 {
+	struct cmdq_client *cl = (struct cmdq_client *)pkt->cl;
 	const u16 high_addr_reg_idx  = CMDQ_THR_SPR_IDX0;
 	const u16 value_reg_idx = CMDQ_THR_SPR_IDX1;
 	int ret;
 
+	if (!cl) {
+		pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	if (cmdq_addr_need_offset(cl->chan, src_addr))
+		src_addr += cmdq_get_offset_pa(cl->chan);
+
+	if (cmdq_addr_need_offset(cl->chan, dst_addr))
+		dst_addr += cmdq_get_offset_pa(cl->chan);
+
 	/* read the value of src_addr into high_addr_reg_idx */
 	ret = cmdq_pkt_assign(pkt, high_addr_reg_idx, CMDQ_ADDR_HIGH(src_addr));
 	if (ret < 0)
@@ -428,10 +440,19 @@ EXPORT_SYMBOL(cmdq_pkt_poll_mask);
 
 int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask)
 {
+	struct cmdq_client *cl = (struct cmdq_client *)pkt->cl;
 	struct cmdq_instruction inst = { {0} };
 	u8 use_mask = 0;
 	int ret;
 
+	if (!cl) {
+		pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	if (cmdq_addr_need_offset(cl->chan, addr))
+		addr += cmdq_get_offset_pa(cl->chan);
+
 	/*
 	 * Append an MASK instruction to set the mask for following POLL instruction
 	 * which enables use_mask bit.
@@ -509,11 +530,21 @@ EXPORT_SYMBOL(cmdq_pkt_assign);
 
 int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 {
+	struct cmdq_client *cl = (struct cmdq_client *)pkt->cl;
 	struct cmdq_instruction inst = {
 		.op = CMDQ_CODE_JUMP,
-		.offset = CMDQ_JUMP_ABSOLUTE,
-		.value = addr >> shift_pa
+		.offset = CMDQ_JUMP_ABSOLUTE
 	};
+
+	if (!cl) {
+		pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	if (cmdq_addr_need_offset(cl->chan, addr))
+		addr += cmdq_get_offset_pa(cl->chan);
+
+	inst.value = addr >> shift_pa;
 	return cmdq_pkt_append_command(pkt, inst);
 }
 EXPORT_SYMBOL(cmdq_pkt_jump_abs);
-- 
2.43.0



From jason-jh.lin at mediatek.com  Tue Dec 10 19:22:52 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:22:52 +0800
Subject: [PATCH v2 4/8] soc: mediatek: mtk-cmdq: Add pa_base parsing for unsupported subsys ID hardware
In-Reply-To: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
Message-ID: <20241211032256.28494-5-jason-jh.lin@mediatek.com>

When GCE executes instructions, the corresponding hardware register
can be found through the subsys ID. For hardware that does not support
subsys IDs, the physical address needs to be used to generate GCE
instructions.

This commit adds a pa_base parsing flow to the cmdq_client_reg structure
for these unsupported subsys ID hardware.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 18 ++++++++++++++++--
 include/linux/soc/mediatek/mtk-cmdq.h  |  1 +
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 0a05ee87a0fc..87734639c37c 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/mailbox_controller.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #define CMDQ_WRITE_ENABLE_MASK	BIT(0)
@@ -60,20 +61,30 @@ int cmdq_dev_get_client_reg(struct device *dev,
 			    struct cmdq_client_reg *client_reg, int idx)
 {
 	struct of_phandle_args spec;
+	struct resource res;
 	int err;
 
 	if (!client_reg)
 		return -ENOENT;
 
+	if (of_address_to_resource(dev->of_node, 0, &res) != 0) {
+		dev_err(dev, "Missing reg in %s node\n", dev->of_node->full_name);
+		return -EINVAL;
+	}
+	client_reg->pa_base = res.start;
+
 	err = of_parse_phandle_with_fixed_args(dev->of_node,
 					       "mediatek,gce-client-reg",
 					       3, idx, &spec);
 	if (err < 0) {
-		dev_warn(dev,
+		dev_dbg(dev,
 			"error %d can't parse gce-client-reg property (%d)",
 			err, idx);
 
-		return err;
+		/* make subsys invalid */
+		client_reg->subsys = U8_MAX;
+
+		return 0;
 	}
 
 	client_reg->subsys = (u8)spec.args[0];
@@ -130,6 +141,9 @@ int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t siz
 
 	pkt->buf_size = size;
 
+	/* need to use pkt->cl->chan later to call mbox APIs when generating instruction */
+	pkt->cl = (void *)client;
+
 	dev = client->chan->mbox->dev;
 	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
 				  DMA_TO_DEVICE);
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 5bee6f7fc400..d925f9dc7987 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -52,6 +52,7 @@ struct cmdq_operand {
 
 struct cmdq_client_reg {
 	u8 subsys;
+	u32 pa_base;
 	u16 offset;
 	u16 size;
 };
-- 
2.43.0



From jason-jh.lin at mediatek.com  Tue Dec 10 19:22:49 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:22:49 +0800
Subject: [PATCH v2 1/8] dt-bindings: mailbox: mediatek: Add GCE header file for MT8196
In-Reply-To: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
Message-ID: <20241211032256.28494-2-jason-jh.lin@mediatek.com>

Add the Global Command Engine (GCE) header file to define the GCE
thread priority, GCE subsys ID and GCE events for MT8196.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 .../dt-bindings/mailbox/mediatek,mt8196-gce.h | 1439 +++++++++++++++++
 1 file changed, 1439 insertions(+)
 create mode 100644 include/dt-bindings/mailbox/mediatek,mt8196-gce.h

diff --git a/include/dt-bindings/mailbox/mediatek,mt8196-gce.h b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h
new file mode 100644
index 000000000000..860d69100157
--- /dev/null
+++ b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h
@@ -0,0 +1,1439 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2024 MediaTek Inc.
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8196_H
+#define _DT_BINDINGS_GCE_MT8196_H
+
+/* GCE thread priority */
+#define CMDQ_THR_PRIO_LOWEST	0
+#define CMDQ_THR_PRIO_1		1
+#define CMDQ_THR_PRIO_2		2
+#define CMDQ_THR_PRIO_3		3
+#define CMDQ_THR_PRIO_4		4
+#define CMDQ_THR_PRIO_5		5
+#define CMDQ_THR_PRIO_6		6
+#define CMDQ_THR_PRIO_HIGHEST	7
+
+/* GCE subsys table */
+#define SUBSYS_1300XXXX		0
+#define SUBSYS_1400XXXX		1
+#define SUBSYS_1401XXXX		2
+#define SUBSYS_1402XXXX		3
+#define SUBSYS_1502XXXX		4
+#define SUBSYS_1880XXXX		5
+#define SUBSYS_1881XXXX		6
+#define SUBSYS_1882XXXX		7
+#define SUBSYS_1883XXXX		8
+#define SUBSYS_1884XXXX		9
+#define SUBSYS_1000XXXX		10
+#define SUBSYS_1001XXXX		11
+#define SUBSYS_1002XXXX		12
+#define SUBSYS_1003XXXX		13
+#define SUBSYS_1004XXXX		14
+#define SUBSYS_1005XXXX		15
+#define SUBSYS_1020XXXX		16
+#define SUBSYS_1028XXXX		17
+#define SUBSYS_1700XXXX		18
+#define SUBSYS_1701XXXX		19
+#define SUBSYS_1702XXXX		20
+#define SUBSYS_1703XXXX		21
+#define SUBSYS_1800XXXX		22
+#define SUBSYS_1801XXXX		23
+#define SUBSYS_1802XXXX		24
+#define SUBSYS_1804XXXX		25
+#define SUBSYS_1805XXXX		26
+#define SUBSYS_1808XXXX		27
+#define SUBSYS_180aXXXX		28
+#define SUBSYS_180bXXXX		29
+#define SUBSYS_NO_SUPPORT	99
+
+/*
+ * GCE General Purpose Register (GPR) support
+ * Leave note for scenario usage here
+ */
+/* GCE: write mask */
+#define GCE_GPR_R00		0x0
+#define GCE_GPR_R01		0x1
+/* Configurable GPR for hardware module */
+#define GCE_GPR_R02		0x2
+#define GCE_GPR_R03		0x3
+#define GCE_GPR_R04		0x4
+#define GCE_GPR_R05		0x5
+#define GCE_GPR_R06		0x6
+#define GCE_GPR_R07		0x7
+#define GCE_GPR_R08		0x8
+#define GCE_GPR_R09		0x9
+#define GCE_GPR_R10		0xa
+#define GCE_GPR_R11		0xb
+#define GCE_GPR_R12		0xc
+#define GCE_GPR_R13		0xd
+/* CMDQ: for generating instruction */
+#define GCE_GPR_R14		0xe
+#define GCE_GPR_R15		0xf
+
+/* GCE-D hardware events */
+#define CMDQ_EVENT_DISP0_STREAM_SOF0						0
+#define CMDQ_EVENT_DISP0_STREAM_SOF1						1
+#define CMDQ_EVENT_DISP0_STREAM_SOF2						2
+#define CMDQ_EVENT_DISP0_STREAM_SOF3						3
+#define CMDQ_EVENT_DISP0_STREAM_SOF4						4
+#define CMDQ_EVENT_DISP0_STREAM_SOF5						5
+#define CMDQ_EVENT_DISP0_STREAM_SOF6						6
+#define CMDQ_EVENT_DISP0_STREAM_SOF7						7
+#define CMDQ_EVENT_DISP0_STREAM_SOF8						8
+#define CMDQ_EVENT_DISP0_STREAM_SOF9						9
+#define CMDQ_EVENT_DISP0_STREAM_SOF10						10
+#define CMDQ_EVENT_DISP0_STREAM_SOF11						11
+#define CMDQ_EVENT_DISP0_STREAM_SOF12						12
+#define CMDQ_EVENT_DISP0_STREAM_SOF13						13
+#define CMDQ_EVENT_DISP0_STREAM_SOF14						14
+#define CMDQ_EVENT_DISP0_STREAM_SOF15						15
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL0					16
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL1					17
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL2					18
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL3					19
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL4					20
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL5					21
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL6					22
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL7					23
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL8					24
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL9					25
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL10					26
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL11					27
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL12					28
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL13					29
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL14					30
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL15					31
+#define CMDQ_EVENT_DISP0_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT			32
+#define CMDQ_EVENT_DISP0_DISP_WDMA0_SW_RST_DONE_ENG_EVENT			33
+#define CMDQ_EVENT_DISP0_DISP_POSTMASK1_RST_DONE_ENG_EVENT			34
+#define CMDQ_EVENT_DISP0_DISP_POSTMASK0_RST_DONE_ENG_EVENT			35
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_TIMEOUT_ENG_EVENT				36
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT0			37
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT1			38
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT2			39
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT3			40
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT4			41
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT5			42
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT6			43
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT7			44
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT8			45
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT9			46
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT10			47
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT11			48
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT12			49
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT13			50
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT14			51
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT15			52
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_GET_RELEASE_ENG_EVENT			53
+#define CMDQ_EVENT_DISP0_DISP_MDP_RDMA0_SW_RST_DONE_ENG_EVENT			54
+
+#define CMDQ_EVENT_DISP1_STREAM_SOF0						55
+#define CMDQ_EVENT_DISP1_STREAM_SOF1						56
+#define CMDQ_EVENT_DISP1_STREAM_SOF2						57
+#define CMDQ_EVENT_DISP1_STREAM_SOF3						58
+#define CMDQ_EVENT_DISP1_STREAM_SOF4						59
+#define CMDQ_EVENT_DISP1_STREAM_SOF5						60
+#define CMDQ_EVENT_DISP1_STREAM_SOF6						61
+#define CMDQ_EVENT_DISP1_STREAM_SOF7						62
+#define CMDQ_EVENT_DISP1_STREAM_SOF8						63
+#define CMDQ_EVENT_DISP1_STREAM_SOF9						64
+#define CMDQ_EVENT_DISP1_STREAM_SOF10						65
+#define CMDQ_EVENT_DISP1_STREAM_SOF11						66
+#define CMDQ_EVENT_DISP1_STREAM_SOF12						67
+#define CMDQ_EVENT_DISP1_STREAM_SOF13						68
+#define CMDQ_EVENT_DISP1_STREAM_SOF14						69
+#define CMDQ_EVENT_DISP1_STREAM_SOF15						70
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL0					71
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL1					72
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL2					73
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL3					74
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL4					75
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL5					76
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL6					77
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL7					78
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL8					79
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL9					80
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL10					81
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL11					82
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL12					83
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL13					84
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL14					85
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL15					86
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT0					87
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT1					88
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT2					89
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT3					90
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT4					91
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT5					92
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT6					93
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT7					94
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT8					95
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT9					96
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT10				97
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT11				98
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT12				99
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT13				100
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT14				101
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT15				102
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT0				103
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT1				104
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT2				105
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT3				106
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT4				107
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT5				108
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT6				109
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT7				110
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT8				111
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT9				112
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT10				113
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT11				114
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT12				115
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT13				116
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT14				117
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT15				118
+#define CMDQ_EVENT_DISP1_OCIP_SUBSYS_SRAM_ISOINT_ENG_EVENT			119
+#define CMDQ_EVENT_DISP1_DISP_WDMA4_TARGET_LINE_END_ENG_EVENT			120
+#define CMDQ_EVENT_DISP1_DISP_WDMA4_SW_RST_DONE_ENG_EVENT			121
+#define CMDQ_EVENT_DISP1_DISP_WDMA3_TARGET_LINE_END_ENG_EVENT			122
+#define CMDQ_EVENT_DISP1_DISP_WDMA3_SW_RST_DONE_ENG_EVENT			123
+#define CMDQ_EVENT_DISP1_DISP_WDMA2_TARGET_LINE_END_ENG_EVENT			124
+#define CMDQ_EVENT_DISP1_DISP_WDMA2_SW_RST_DONE_ENG_EVENT			125
+#define CMDQ_EVENT_DISP1_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT			126
+#define CMDQ_EVENT_DISP1_DISP_WDMA1_SW_RST_DONE_ENG_EVENT			127
+#define CMDQ_EVENT_DISP1_DISP_MUTEX0_TIMEOUT_ENG_EVENT				128
+#define CMDQ_EVENT_DISP1_DISP_MUTEX0_GET_RLZ_ENG_EVENT				129
+#define CMDQ_EVENT_DISP1_DISP_MDP_RDMA1_SW_RST_DONE_ENG_EVENT			130
+#define CMDQ_EVENT_DISP1_DISP_GDMA0_SW_RST_DONE_ENG_EVENT			131
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VSYNC_START_ENG_EVENT		132
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VSYNC_END_ENG_EVENT		133
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VRR_VFP_LAST_SAFE_BLANK_ENG_EVENT	134
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VFP_START_ENG_EVENT		135
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VFP_LAST_LINE_ENG_EVENT		136
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VDE_END_ENG_EVENT			137
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TRIGGER_LOOP_CLR_ENG_EVENT	138
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TARGET_LINE1_ENG_EVENT		139
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TARGET_LINE0_ENG_EVENT		140
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VSYNC_START_ENG_EVENT		141
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VSYNC_END_ENG_EVENT		142
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VDE_START_ENG_EVENT		143
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VDE_END_ENG_EVENT			144
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT0					145
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT1					146
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT2					147
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT3					148
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT4					149
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT5					150
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT6					151
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT7					152
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT8					153
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT9					154
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT10					155
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT0					156
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT1					157
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT2					158
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT3					159
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT4					160
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT5					161
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT6					162
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT7					163
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT8					164
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT9					165
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT10					166
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT11					167
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT12					168
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT13					169
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT14					170
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT15					171
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT16					172
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT17					173
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT18					174
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT19					175
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT20					176
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT21					177
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT0					178
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT1					179
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT2					180
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT3					181
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT4					182
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT5					183
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT6					184
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT7					185
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT8					186
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT9					187
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT10					188
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VSYNC_START_ENG_EVENT			189
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VSYNC_END_ENG_EVENT			190
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VDE_START_ENG_EVENT			191
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VDE_END_ENG_EVENT			192
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_TARGET_LINE_ENG_EVENT			193
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VSYNC_START_ENG_EVENT			194
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VSYNC_END_ENG_EVENT			195
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VDE_START_ENG_EVENT			196
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VDE_END_ENG_EVENT			197
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_TARGET_LINE_ENG_EVENT			198
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT0				199
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT1				200
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT2				201
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT3				202
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT4				203
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT5				204
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT6				205
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT7				206
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT8				207
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT9				208
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT10				209
+
+#define CMDQ_EVENT_MML0_STREAM_SOF0						210
+#define CMDQ_EVENT_MML0_STREAM_SOF1						211
+#define CMDQ_EVENT_MML0_STREAM_SOF2						212
+#define CMDQ_EVENT_MML0_STREAM_SOF3						213
+#define CMDQ_EVENT_MML0_STREAM_SOF4						214
+#define CMDQ_EVENT_MML0_STREAM_SOF5						215
+#define CMDQ_EVENT_MML0_STREAM_SOF6						216
+#define CMDQ_EVENT_MML0_STREAM_SOF7						217
+#define CMDQ_EVENT_MML0_STREAM_SOF8						218
+#define CMDQ_EVENT_MML0_STREAM_SOF9						219
+#define CMDQ_EVENT_MML0_STREAM_SOF10						220
+#define CMDQ_EVENT_MML0_STREAM_SOF11						221
+#define CMDQ_EVENT_MML0_STREAM_SOF12						222
+#define CMDQ_EVENT_MML0_STREAM_SOF13						223
+#define CMDQ_EVENT_MML0_STREAM_SOF14						224
+#define CMDQ_EVENT_MML0_STREAM_SOF15						225
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL0						226
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL1						227
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL2						228
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL3						229
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL4						230
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL5						231
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL6						232
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL7						233
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL8						234
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL9						235
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL10					236
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL11					237
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL12					238
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL13					239
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL14					240
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL15					241
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT0				242
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT1				243
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT2				244
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT3				245
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT4				246
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT5				247
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT6				248
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT7				249
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT8				250
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT9				251
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT10				252
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT11				253
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT12				254
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT13				255
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT14				256
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT15				257
+#define CMDQ_EVENT_MML0_MDP_WROT2_SW_RST_DONE_ENG_EVENT				258
+#define CMDQ_EVENT_MML0_MDP_WROT1_SW_RST_DONE_ENG_EVENT				259
+#define CMDQ_EVENT_MML0_MDP_WROT0_SW_RST_DONE_ENG_EVENT				260
+#define CMDQ_EVENT_MML0_MDP_RROT0_SW_RST_DONE_ENG_EVENT				261
+#define CMDQ_EVENT_MML0_MDP_RDMA2_SW_RST_DONE_ENG_EVENT				262
+#define CMDQ_EVENT_MML0_MDP_RDMA1_SW_RST_DONE_ENG_EVENT				263
+#define CMDQ_EVENT_MML0_MDP_RDMA0_SW_RST_DONE_ENG_EVENT				264
+#define CMDQ_EVENT_MML0_MDP_MERGE0_SW_RST_DONE_ENG_EVENT			265
+#define CMDQ_EVENT_MML0_DISP_MUTEX0_TIMEOUT_ENG_EVENT				266
+#define CMDQ_EVENT_MML0_DISP_MUTEX0_GET_RLZ_ENG_EVENT				267
+
+#define CMDQ_EVENT_MML1_STREAM_SOF0						268
+#define CMDQ_EVENT_MML1_STREAM_SOF1						269
+#define CMDQ_EVENT_MML1_STREAM_SOF2						270
+#define CMDQ_EVENT_MML1_STREAM_SOF3						271
+#define CMDQ_EVENT_MML1_STREAM_SOF4						272
+#define CMDQ_EVENT_MML1_STREAM_SOF5						273
+#define CMDQ_EVENT_MML1_STREAM_SOF6						274
+#define CMDQ_EVENT_MML1_STREAM_SOF7						275
+#define CMDQ_EVENT_MML1_STREAM_SOF8						276
+#define CMDQ_EVENT_MML1_STREAM_SOF9						277
+#define CMDQ_EVENT_MML1_STREAM_SOF10						278
+#define CMDQ_EVENT_MML1_STREAM_SOF11						279
+#define CMDQ_EVENT_MML1_STREAM_SOF12						280
+#define CMDQ_EVENT_MML1_STREAM_SOF13						281
+#define CMDQ_EVENT_MML1_STREAM_SOF14						282
+#define CMDQ_EVENT_MML1_STREAM_SOF15						283
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL0						284
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL1						285
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL2						286
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL3						287
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL4						288
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL5						289
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL6						290
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL7						291
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL8						292
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL9						293
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL10					294
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL11					295
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL12					296
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL13					297
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL14					298
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL15					299
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT0				300
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT1				301
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT2				302
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT3				303
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT4				304
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT5				305
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT6				306
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT7				307
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT8				308
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT9				309
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT10				310
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT11				311
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT12				312
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT13				313
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT14				314
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT15				315
+#define CMDQ_EVENT_MML1_MDP_WROT2_SW_RST_DONE_ENG_EVENT				316
+#define CMDQ_EVENT_MML1_MDP_WROT1_SW_RST_DONE_ENG_EVENT				317
+#define CMDQ_EVENT_MML1_MDP_WROT0_SW_RST_DONE_ENG_EVENT				318
+#define CMDQ_EVENT_MML1_MDP_RROT0_SW_RST_DONE_ENG_EVENT				319
+#define CMDQ_EVENT_MML1_MDP_RDMA2_SW_RST_DONE_ENG_EVENT				320
+#define CMDQ_EVENT_MML1_MDP_RDMA1_SW_RST_DONE_ENG_EVENT				321
+#define CMDQ_EVENT_MML1_MDP_RDMA0_SW_RST_DONE_ENG_EVENT				322
+#define CMDQ_EVENT_MML1_MDP_MERGE0_SW_RST_DONE_ENG_EVENT			323
+#define CMDQ_EVENT_MML1_DISP_MUTEX0_TIMEOUT_ENG_EVENT				324
+#define CMDQ_EVENT_MML1_DISP_MUTEX0_GET_RLZ_ENG_EVENT				325
+
+#define CMDQ_EVENT_OVL0_STREAM_SOF0						326
+#define CMDQ_EVENT_OVL0_STREAM_SOF1						327
+#define CMDQ_EVENT_OVL0_STREAM_SOF2						328
+#define CMDQ_EVENT_OVL0_STREAM_SOF3						329
+#define CMDQ_EVENT_OVL0_STREAM_SOF4						330
+#define CMDQ_EVENT_OVL0_STREAM_SOF5						331
+#define CMDQ_EVENT_OVL0_STREAM_SOF6						332
+#define CMDQ_EVENT_OVL0_STREAM_SOF7						333
+#define CMDQ_EVENT_OVL0_STREAM_SOF8						334
+#define CMDQ_EVENT_OVL0_STREAM_SOF9						335
+#define CMDQ_EVENT_OVL0_STREAM_SOF10						336
+#define CMDQ_EVENT_OVL0_STREAM_SOF11						337
+#define CMDQ_EVENT_OVL0_STREAM_SOF12						338
+#define CMDQ_EVENT_OVL0_STREAM_SOF13						339
+#define CMDQ_EVENT_OVL0_STREAM_SOF14						340
+#define CMDQ_EVENT_OVL0_STREAM_SOF15						341
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL0						342
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL1						343
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL2						344
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL3						345
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL4						346
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL5						347
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL6						348
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL7						349
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL8						350
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL9						351
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL10					352
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL11					353
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL12					354
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL13					355
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL14					356
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL15					357
+#define CMDQ_EVENT_OVL0_OVL_UFBC_WDMA0_TARGET_LINE_END_ENG_EVENT		358
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_TIMEOUT_ENG_EVENT				359
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT0			360
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT1			361
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT2			362
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT3			363
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT4			364
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT5			365
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT6			366
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT7			367
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT8			368
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT9			369
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT10			370
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT11			371
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT12			372
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT13			373
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT14			374
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT15			375
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_GET_RELEASE_ENG_EVENT			376
+#define CMDQ_EVENT_OVL0_OVL_MDP_RDMA1_SW_RST_DONE_ENG_EVENT			377
+#define CMDQ_EVENT_OVL0_OVL_MDP_RDMA0_SW_RST_DONE_ENG_EVENT			378
+#define CMDQ_EVENT_OVL0_OVL_EXDMA9_FRAME_RESET_DONE_ENG_EVENT			379
+#define CMDQ_EVENT_OVL0_OVL_EXDMA8_FRAME_RESET_DONE_ENG_EVENT			380
+#define CMDQ_EVENT_OVL0_OVL_EXDMA7_FRAME_RESET_DONE_ENG_EVENT			381
+#define CMDQ_EVENT_OVL0_OVL_EXDMA6_FRAME_RESET_DONE_ENG_EVENT			382
+#define CMDQ_EVENT_OVL0_OVL_EXDMA5_FRAME_RESET_DONE_ENG_EVENT			383
+#define CMDQ_EVENT_OVL0_OVL_EXDMA4_FRAME_RESET_DONE_ENG_EVENT			384
+#define CMDQ_EVENT_OVL0_OVL_EXDMA3_FRAME_RESET_DONE_ENG_EVENT			385
+#define CMDQ_EVENT_OVL0_OVL_EXDMA2_FRAME_RESET_DONE_ENG_EVENT			386
+#define CMDQ_EVENT_OVL0_OVL_EXDMA1_FRAME_RESET_DONE_ENG_EVENT			387
+#define CMDQ_EVENT_OVL0_OVL_EXDMA0_FRAME_RESET_DONE_ENG_EVENT			388
+#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT		389
+#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA1_SW_RST_DONE_END_ENG_EVENT		390
+#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT		391
+#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA0_SW_RST_DONE_END_ENG_EVENT		392
+#define CMDQ_EVENT_OVL0_OVL_BWM0_FRAME_RESET_DONE_ENG_EVENT			393
+#define CMDQ_EVENT_OVL1_STREAM_SOF0						394
+#define CMDQ_EVENT_OVL1_STREAM_SOF1						395
+#define CMDQ_EVENT_OVL1_STREAM_SOF2						396
+#define CMDQ_EVENT_OVL1_STREAM_SOF3						397
+#define CMDQ_EVENT_OVL1_STREAM_SOF4						398
+#define CMDQ_EVENT_OVL1_STREAM_SOF5						399
+#define CMDQ_EVENT_OVL1_STREAM_SOF6						400
+#define CMDQ_EVENT_OVL1_STREAM_SOF7						401
+#define CMDQ_EVENT_OVL1_STREAM_SOF8						402
+#define CMDQ_EVENT_OVL1_STREAM_SOF9						403
+#define CMDQ_EVENT_OVL1_STREAM_SOF10						404
+#define CMDQ_EVENT_OVL1_STREAM_SOF11						405
+#define CMDQ_EVENT_OVL1_STREAM_SOF12						406
+#define CMDQ_EVENT_OVL1_STREAM_SOF13						407
+#define CMDQ_EVENT_OVL1_STREAM_SOF14						408
+#define CMDQ_EVENT_OVL1_STREAM_SOF15						409
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL0						410
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL1						411
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL2						412
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL3						413
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL4						414
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL5						415
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL6						416
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL7						417
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL8						418
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL9						419
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL10					420
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL11					421
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL12					422
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL13					423
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL14					424
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL15					425
+#define CMDQ_EVENT_OVL1_OVL_UFBC_WDMA0_TARGET_LINE_END_ENG_EVENT		426
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_TIMEOUT_ENG_EVENT				427
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT0			428
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT1			429
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT2			430
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT3			431
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT4			432
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT5			433
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT6			434
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT7			435
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT8			436
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT9			437
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT10			438
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT11			439
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT12			440
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT13			441
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT14			442
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT15			443
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_GET_RELEASE_ENG_EVENT			444
+#define CMDQ_EVENT_OVL1_OVL_MDP_RDMA1_SW_RST_DONE_ENG_EVENT			445
+#define CMDQ_EVENT_OVL1_OVL_MDP_RDMA0_SW_RST_DONE_ENG_EVENT			446
+#define CMDQ_EVENT_OVL1_OVL_EXDMA9_FRAME_RESET_DONE_ENG_EVENT			447
+#define CMDQ_EVENT_OVL1_OVL_EXDMA8_FRAME_RESET_DONE_ENG_EVENT			448
+#define CMDQ_EVENT_OVL1_OVL_EXDMA7_FRAME_RESET_DONE_ENG_EVENT			449
+#define CMDQ_EVENT_OVL1_OVL_EXDMA6_FRAME_RESET_DONE_ENG_EVENT			450
+#define CMDQ_EVENT_OVL1_OVL_EXDMA5_FRAME_RESET_DONE_ENG_EVENT			451
+#define CMDQ_EVENT_OVL1_OVL_EXDMA4_FRAME_RESET_DONE_ENG_EVENT			452
+#define CMDQ_EVENT_OVL1_OVL_EXDMA3_FRAME_RESET_DONE_ENG_EVENT			453
+#define CMDQ_EVENT_OVL1_OVL_EXDMA2_FRAME_RESET_DONE_ENG_EVENT			454
+#define CMDQ_EVENT_OVL1_OVL_EXDMA1_FRAME_RESET_DONE_ENG_EVENT			455
+#define CMDQ_EVENT_OVL1_OVL_EXDMA0_FRAME_RESET_DONE_ENG_EVENT			456
+#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT		457
+#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA1_SW_RST_DONE_END_ENG_EVENT		458
+#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT		459
+#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA0_SW_RST_DONE_END_ENG_EVENT		460
+#define CMDQ_EVENT_OVL1_OVL_BWM0_FRAME_RESET_DONE_ENG_EVENT			461
+
+#define CMDQ_EVENT_DPC_DT_DONE0							462
+#define CMDQ_EVENT_DPC_DT_DONE1							463
+#define CMDQ_EVENT_DPC_DT_DONE2_0_MERGE						464
+#define CMDQ_EVENT_DPC_DT_DONE2_1_MERGE						465
+#define CMDQ_EVENT_DPC_DT_DONE2_2_MERGE						466
+#define CMDQ_EVENT_DPC_DT_DONE2_3_MERGE						467
+#define CMDQ_EVENT_DPC_DT_DONE3							468
+#define CMDQ_EVENT_DPC_DT_DONE4_MERGE						469
+#define CMDQ_EVENT_DPC_DT_DONE5							470
+#define CMDQ_EVENT_DPC_DT_DONE6_0_MERGE						471
+#define CMDQ_EVENT_DPC_DT_DONE6_1_MERGE						472
+#define CMDQ_EVENT_DPC_DT_DONE6_2_MERGE						473
+#define CMDQ_EVENT_DPC_DT_DONE6_3_MERGE						474
+#define CMDQ_EVENT_DPC_DT_DONE7							475
+#define CMDQ_EVENT_DPC_DT_DONE32_MERGE						476
+#define CMDQ_EVENT_DPC_DT_DONE33						477
+#define CMDQ_EVENT_DPC_DT_DONE34_0						478
+#define CMDQ_EVENT_DPC_DT_DONE35						479
+#define CMDQ_EVENT_DPC_DISP_SSYS_DT_ERR_ON_BEFORE_OFF				480
+#define CMDQ_EVENT_DPC_DISP_SSYS_DT_ERR_PRETE_BEFORE_ON				481
+#define CMDQ_EVENT_DPC_DISP_DVFS_DT_ERR_ON_BEFORE_OFF				482
+#define CMDQ_EVENT_DPC_DISP_DVFS_DT_ERR_PRETE_BEFORE_ON				483
+#define CMDQ_EVENT_DPC_DISP_SB_DT_ERR_ON_BEFORE_OFF				484
+#define CMDQ_EVENT_DPC_DISP_SB_DT_ERR_PRETE_BEFORE_ON				485
+#define CMDQ_EVENT_DPC_DISP_SW_CONFIG_WHEN_MTCMOS_OFF				486
+#define CMDQ_EVENT_DPC_MML_SSYS_DT_ERR_ON_BEFORE_OFF				487
+#define CMDQ_EVENT_DPC_MML_SSYS_DT_ERR_PRETE_BEFORE_ON				488
+#define CMDQ_EVENT_DPC_MML_DVFS_DT_ERR_ON_BEFORE_OFF				489
+#define CMDQ_EVENT_DPC_MML_DVFS_DT_ERR_PRETE_BEFORE_ON				490
+#define CMDQ_EVENT_DPC_MML_SB_DT_ERR_ON_BEFORE_OFF				491
+#define CMDQ_EVENT_DPC_MML_SB_DT_ERR_PRETE_BEFORE_ON				492
+#define CMDQ_EVENT_DPC_MML_SW_CONFIG_WHEN_MTCMOS_OFF				493
+#define CMDQ_EVENT_DPTX_DPTX_EVENT0						494
+#define CMDQ_EVENT_DPTX_DPTX_EVENT1						495
+#define CMDQ_EVENT_DPTX_DPTX_EVENT2						496
+#define CMDQ_EVENT_DPTX_DPTX_EVENT3						497
+#define CMDQ_EVENT_EDPTX_EDPTX_EVENT0						498
+#define CMDQ_EVENT_EDPTX_EDPTX_EVENT1						499
+
+#define CMDQ_EVENT_DSI0_TE_I_DSI0_TE_I						898
+#define CMDQ_EVENT_DSI1_TE_I_DSI1_TE_I						899
+#define CMDQ_EVENT_DSI2_TE_I_DSI2_TE_I						900
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_0			901
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_1			902
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_2			903
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_3			904
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_4			905
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_5			906
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_6			907
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_7			908
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_8			909
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_9			910
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_10			911
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_11			912
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_12			913
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_13			914
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_14			915
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_15			916
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_16			917
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_17			918
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_18			919
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_19			920
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_20			921
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_21			922
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_22			923
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_23			924
+#define CMDQ_EVENT_GCE_EVENT_DPTX_GCE_EVENT_DPTX_0				925
+#define CMDQ_EVENT_GCE_EVENT_DPTX_GCE_EVENT_DPTX_1				926
+#define CMDQ_EVENT_GCE_EVENT_DPTX_P1_GCE_EVENT_DPTX_P1_0			927
+#define CMDQ_EVENT_GCE_EVENT_DPTX_P1_GCE_EVENT_DPTX_P1_1			928
+#define CMDQ_EVENT_GCE_EVENT_EDPTX_GCE_EVENT_EDPTX_0				929
+#define CMDQ_EVENT_GCE_EVENT_EDPTX_GCE_EVENT_EDPTX_1				930
+#define CMDQ_EVENT_DSI3_TE_I_DSI3_TE_I						931
+#define CMDQ_EVENT_SPI0_FINISH_EVENT_DSI4_TE_I					932
+#define CMDQ_EVENT_SPI0_EVENT_EVENT_DSI5_TE_I					933
+
+/* GCE-M hardware events */
+#define CMDQ_EVENT_VENC3_VENC_RESERVED						0
+#define CMDQ_EVENT_VENC3_VENC_FRAME_DONE					1
+#define CMDQ_EVENT_VENC3_VENC_PAUSE_DONE					2
+#define CMDQ_EVENT_VENC3_JPGENC_DONE						3
+#define CMDQ_EVENT_VENC3_VENC_MB_DONE						4
+#define CMDQ_EVENT_VENC3_VENC_128BYTE_DONE					5
+#define CMDQ_EVENT_VENC3_JPGDEC_DONE						6
+#define CMDQ_EVENT_VENC3_JPGDEC_C1_DONE						7
+#define CMDQ_EVENT_VENC3_JPGDEC_INSUFF_DONE					8
+#define CMDQ_EVENT_VENC3_JPGDEC_C1_INSUFF_DONE					9
+#define CMDQ_EVENT_VENC3_WP_2ND_STAGE_DONE					10
+#define CMDQ_EVENT_VENC3_WP_3RD_STAGE_DONE					11
+#define CMDQ_EVENT_VENC3_PPS_HEADER_DONE					12
+#define CMDQ_EVENT_VENC3_SPS_HEADER_DONE					13
+#define CMDQ_EVENT_VENC3_VPS_HEADER_DONE					14
+#define CMDQ_EVENT_VENC3_VENC_SLICE_DONE					15
+#define CMDQ_EVENT_VENC3_VENC_SOC_SLICE_DONE					16
+#define CMDQ_EVENT_VENC3_VENC_SOC_FRAME_DONE					17
+
+#define CMDQ_EVENT_VENC2_VENC_FRAME_DONE					33
+#define CMDQ_EVENT_VENC2_VENC_PAUSE_DONE					34
+#define CMDQ_EVENT_VENC2_JPGENC_DONE						35
+#define CMDQ_EVENT_VENC2_VENC_MB_DONE						36
+#define CMDQ_EVENT_VENC2_VENC_128BYTE_DONE					37
+#define CMDQ_EVENT_VENC2_JPGDEC_DONE						38
+#define CMDQ_EVENT_VENC2_JPGDEC_C1_DONE						39
+#define CMDQ_EVENT_VENC2_JPGDEC_INSUFF_DONE					40
+#define CMDQ_EVENT_VENC2_JPGDEC_C1_INSUFF_DONE					41
+#define CMDQ_EVENT_VENC2_WP_2ND_STAGE_DONE					42
+#define CMDQ_EVENT_VENC2_WP_3RD_STAGE_DONE					43
+#define CMDQ_EVENT_VENC2_PPS_HEADER_DONE					44
+#define CMDQ_EVENT_VENC2_SPS_HEADER_DONE					45
+#define CMDQ_EVENT_VENC2_VPS_HEADER_DONE					46
+#define CMDQ_EVENT_VENC2_VENC_SLICE_DONE					47
+#define CMDQ_EVENT_VENC2_VENC_SOC_SLICE_DONE					48
+#define CMDQ_EVENT_VENC2_VENC_SOC_FRAME_DONE					49
+
+#define CMDQ_EVENT_VENC1_VENC_FRAME_DONE					65
+#define CMDQ_EVENT_VENC1_VENC_PAUSE_DONE					66
+#define CMDQ_EVENT_VENC1_JPGENC_DONE						67
+#define CMDQ_EVENT_VENC1_VENC_MB_DONE						68
+#define CMDQ_EVENT_VENC1_VENC_128BYTE_DONE					69
+#define CMDQ_EVENT_VENC1_JPGDEC_DONE						70
+#define CMDQ_EVENT_VENC1_JPGDEC_C1_DONE						71
+#define CMDQ_EVENT_VENC1_JPGDEC_INSUFF_DONE					72
+#define CMDQ_EVENT_VENC1_JPGDEC_C1_INSUFF_DONE					73
+#define CMDQ_EVENT_VENC1_WP_2ND_STAGE_DONE					74
+#define CMDQ_EVENT_VENC1_WP_3RD_STAGE_DONE					75
+#define CMDQ_EVENT_VENC1_PPS_HEADER_DONE					76
+#define CMDQ_EVENT_VENC1_SPS_HEADER_DONE					77
+#define CMDQ_EVENT_VENC1_VPS_HEADER_DONE					78
+#define CMDQ_EVENT_VENC1_VENC_SLICE_DONE					79
+#define CMDQ_EVENT_VENC1_VENC_SOC_SLICE_DONE					80
+#define CMDQ_EVENT_VENC1_VENC_SOC_FRAME_DONE					81
+
+#define CMDQ_EVENT_VDEC1_VDEC_LINE_CNT_INT					192
+#define CMDQ_EVENT_VDEC1_VDEC_INT						193
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_2						194
+#define CMDQ_EVENT_VDEC1_VDEC_DEC_ERR						195
+#define CMDQ_EVENT_VDEC1_VDEC_BUSY_OVERFLOW					196
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_5						197
+#define CMDQ_EVENT_VDEC1_VDEC_INI_FETCH_RDY					198
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_7						199
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_8						200
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_9						201
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_10						202
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_11						203
+
+#define CMDQ_EVENT_VDEC1_VDEC_GCE_CNT_OP_THR					207
+
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_32						224
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_INT						225
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_34						226
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_DEC_ERR					227
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_BUSY_OVERFLOW					228
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_37						229
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_INI_FETCH_RDY					230
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_39						231
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_40						232
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_41						233
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_42						234
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_43						235
+
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_GCE_CNT_OP_THR				239
+
+#define CMDQ_EVENT_IMG_IMG_EVENT_0						256
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_0				257
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_1				258
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_2				259
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_3				260
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_4				261
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_5				262
+#define CMDQ_EVENT_IMG_TRAW0_DMA_ERR_EVENT					263
+#define CMDQ_EVENT_IMG_TRAW0_DUMMY_0						264
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_0				265
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_1				266
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_2				267
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_3				268
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_4				269
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_5				270
+#define CMDQ_EVENT_IMG_TRAW1_DMA_ERR_EVENT					271
+#define CMDQ_EVENT_IMG_ADL_TILE_DONE_EVENT					272
+#define CMDQ_EVENT_IMG_ADLWR0_TILE_DONE_EVENT					273
+#define CMDQ_EVENT_IMG_ADLWR1_TILE_DONE_EVENT					274
+#define CMDQ_EVENT_IMG_IMGSYS_IPE_ME_DONE					275
+#define CMDQ_EVENT_IMG_IMGSYS_IPE_MMG_DONE					276
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_0						277
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_1						278
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_2						279
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_3						280
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_4						281
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_5						282
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_6						283
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_7						284
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_8						285
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_9						286
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_10						287
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_11						288
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_12						289
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_13						290
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_14						291
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_15						292
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_16						293
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_17						294
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_18						295
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_19						296
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_0						297
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_1						298
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_2						299
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_3						300
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_4						301
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_0						302
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_1						303
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_2						304
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_3						305
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_4						306
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_0						307
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_1						308
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_2						309
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_3						310
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_4						311
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_0					312
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_1					313
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_2					314
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_3					315
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_4					316
+
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_0					317
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_1					318
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_2					319
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_3					320
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_4					321
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_5					322
+#define CMDQ_EVENT_IMG_DIP_DMA_ERR_EVENT					323
+#define CMDQ_EVENT_IMG_DIP_NR_DMA_ERR_EVENT					324
+#define CMDQ_EVENT_IMG_DIP_DUMMY_0						325
+
+#define CMDQ_EVENT_IMG_WPE_EIS_GCE_FRAME_DONE					326
+#define CMDQ_EVENT_IMG_WPE_EIS_DONE_SYNC_OUT					327
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_0					328
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_1					329
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_2					330
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_3					331
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_4					332
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_5					333
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_0					334
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_1					335
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_2					336
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_3					337
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_4					338
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_5					339
+#define CMDQ_EVENT_IMG_PQA_DMA_ERR_EVENT					340
+#define CMDQ_EVENT_IMG_WPE0_DUMMY_0						341
+#define CMDQ_EVENT_IMG_WPE0_DUMMY_1						342
+#define CMDQ_EVENT_IMG_WPE0_DUMMY_2						343
+#define CMDQ_EVENT_IMG_OMC_TNR_GCE_FRAME_DONE					344
+#define CMDQ_EVENT_IMG_OMC_TNR_DONE_SYNC_OUT					345
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_0					346
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_1					347
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_2					348
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_3					349
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_4					350
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_5					351
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_0					352
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_1					353
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_2					354
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_3					355
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_4					356
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_5					357
+#define CMDQ_EVENT_IMG_PQB_DMA_ERR_EVENT					358
+#define CMDQ_EVENT_IMG_WPE1_DUMMY_0						359
+#define CMDQ_EVENT_IMG_WPE1_DUMMY_1						360
+#define CMDQ_EVENT_IMG_WPE1_DUMMY_2						361
+#define CMDQ_EVENT_IMG_WPE_LITE_GCE_FRAME_DONE					362
+#define CMDQ_EVENT_IMG_WPE_LITE_DONE_SYNC_OUT					363
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_0				364
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_1				365
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_2				366
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_3				367
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_4				368
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_5				369
+#define CMDQ_EVENT_IMG_OMC_LITE_GCE_FRAME_DONE					370
+#define CMDQ_EVENT_IMG_OMC_LITE_DONE_SYNC_OUT					371
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_0				372
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_1				373
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_2				374
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_3				375
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_4				376
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_5				377
+#define CMDQ_EVENT_IMG_WPE2_DUMMY_0						378
+#define CMDQ_EVENT_IMG_WPE2_DUMMY_1						379
+#define CMDQ_EVENT_IMG_WPE2_DUMMY_2						380
+#define CMDQ_EVENT_IMG_IMGSYS_IPE_FDVT0_DONE					381
+#define CMDQ_EVENT_IMG_IMG_EVENT_126						382
+#define CMDQ_EVENT_IMG_IMG_EVENT_127						383
+
+#define CMDQ_EVENT_CAM_CAM_EVENT_0						384
+#define CMDQ_EVENT_CAM_CAM_SUBA_SW_PASS1_DONE					385
+#define CMDQ_EVENT_CAM_CAM_SUBB_SW_PASS1_DONE					386
+#define CMDQ_EVENT_CAM_CAM_SUBC_SW_PASS1_DONE					387
+#define CMDQ_EVENT_CAM_CAM_SUBA_TFMR_PASS1_DONE					388
+#define CMDQ_EVENT_CAM_CAM_SUBB_TFMR_PASS1_DONE					389
+#define CMDQ_EVENT_CAM_CAM_SUBC_TFMR_PASS1_DONE					390
+#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_0					391
+#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_1					392
+#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_2					393
+#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_3					394
+#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_0					395
+#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_1					396
+#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_2					397
+#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_3					398
+#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_0					399
+#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_1					400
+#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_2					401
+#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_3					402
+#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_0					403
+#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_1					404
+#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_2					405
+#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_3					406
+#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_0					407
+#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_1					408
+#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_2					409
+#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_3					410
+#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_0					411
+#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_1					412
+#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_2					413
+#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_3					414
+#define CMDQ_EVENT_CAM_MRAW0_SW_PASS1_DONE					415
+#define CMDQ_EVENT_CAM_MRAW1_SW_PASS1_DONE					416
+#define CMDQ_EVENT_CAM_MRAW2_SW_PASS1_DONE					417
+#define CMDQ_EVENT_CAM_MRAW3_SW_PASS1_DONE					418
+#define CMDQ_EVENT_CAM_UISP_SW_PASS1_DONE					419
+#define CMDQ_EVENT_CAM_TG_MRAW0_OUT_SOF						420
+#define CMDQ_EVENT_CAM_TG_MRAW1_OUT_SOF						421
+#define CMDQ_EVENT_CAM_TG_MRAW2_OUT_SOF						422
+#define CMDQ_EVENT_CAM_TG_MRAW3_OUT_SOF						423
+#define CMDQ_EVENT_CAM_PDA0_IRQO_EVENT_DONE_D1					424
+#define CMDQ_EVENT_CAM_PDA1_IRQO_EVENT_DONE_D1					425
+
+#define CMDQ_EVENT_CAM_DPE_DVP_CMQ_EVENT					426
+#define CMDQ_EVENT_CAM_DPE_DVS_CMQ_EVENT					427
+#define CMDQ_EVENT_CAM_DPE_DVFG_CMQ_EVENT					428
+#define CMDQ_EVENT_CAM_CAM_EVENT_45						429
+#define CMDQ_EVENT_CAM_CAM_EVENT_46						430
+#define CMDQ_EVENT_CAM_CAM_EVENT_47						431
+#define CMDQ_EVENT_CAM_CAM_EVENT_48						432
+#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT1						433
+#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT2						434
+#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT3						435
+#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT4						436
+#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT1						437
+#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT2						438
+#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT3						439
+#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT4						440
+#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT1						441
+#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT2						442
+#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT3						443
+#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT4						444
+#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBA						445
+#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBB						446
+#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBC						447
+#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBA					448
+#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBB					449
+#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBC					450
+#define CMDQ_EVENT_CAM_RAW_SEL_SOF_UISP						451
+#define CMDQ_EVENT_CAM_CAM_SUBA_RING_BUFFER_OVERFLOW_INT_IN			452
+#define CMDQ_EVENT_CAM_CAM_SUBB_RING_BUFFER_OVERFLOW_INT_IN			453
+#define CMDQ_EVENT_CAM_CAM_SUBC_RING_BUFFER_OVERFLOW_INT_IN			454
+#define CMDQ_EVENT_CAM_CAM_EVENT_71						455
+#define CMDQ_EVENT_CAM_ADL_WR_FRAME_DONE					456
+#define CMDQ_EVENT_CAM_ADL_RD_FRAME_DONE					457
+#define CMDQ_EVENT_CAM_QOF_RAWA_POWER_ON_EVENT					458
+#define CMDQ_EVENT_CAM_QOF_RAWB_POWER_ON_EVENT					459
+#define CMDQ_EVENT_CAM_QOF_RAWC_POWER_ON_EVENT					460
+#define CMDQ_EVENT_CAM_QOF_RAWA_POWER_OFF_EVENT					461
+#define CMDQ_EVENT_CAM_QOF_RAWB_POWER_OFF_EVENT					462
+#define CMDQ_EVENT_CAM_QOF_RAWC_POWER_OFF_EVENT					463
+#define CMDQ_EVENT_CAM_QOF_RAWA_SAVE_EVENT					464
+#define CMDQ_EVENT_CAM_QOF_RAWB_SAVE_EVENT					465
+#define CMDQ_EVENT_CAM_QOF_RAWC_SAVE_EVENT					466
+#define CMDQ_EVENT_CAM_QOF_RAWA_RESTORE_EVENT					467
+#define CMDQ_EVENT_CAM_QOF_RAWB_RESTORE_EVENT					468
+#define CMDQ_EVENT_CAM_QOF_RAWC_RESTORE_EVENT					469
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_0						470
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_1						471
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_2						472
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_3						473
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_4						474
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_5						475
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_6						476
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_7						477
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_8						478
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_9						479
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_10						480
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_11						481
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_0					482
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_1					483
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_2					484
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_3					485
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_4					486
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_5					487
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_6					488
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_7					489
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_8					490
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_9					491
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_10					492
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_11					493
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_12					494
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_13					495
+#define CMDQ_EVENT_CAM_CCU0_TO_GCE_NON_SEC_IRQ					496
+#define CMDQ_EVENT_CAM_CCU0_TO_GCE_SEC_IRQ					497
+#define CMDQ_EVENT_CAM_CCU0_TO_GCE_VM_IRQ					498
+#define CMDQ_EVENT_CAM_CCU0_TO_GCE_EXCH_VM_IRQ					499
+#define CMDQ_EVENT_CAM_CCU1_TO_GCE_NON_SEC_IRQ					500
+#define CMDQ_EVENT_CAM_CCU1_TO_GCE_SEC_IRQ					501
+#define CMDQ_EVENT_CAM_CCU1_TO_GCE_VM_IRQ					502
+#define CMDQ_EVENT_CAM_CCU1_TO_GCE_EXCH_VM_IRQ					503
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_0						504
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_1						505
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_2						506
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_3						507
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_4						508
+#define CMDQ_EVENT_CAM_CAM_EVENT_125						509
+#define CMDQ_EVENT_CAM_CAM_EVENT_126						510
+#define CMDQ_EVENT_CAM_CAM_EVENT_127						511
+
+#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_MMSRAM_COMM_SMIASSER			898
+#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_MDP_COMM_SMIASSER			899
+#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_DISP_COMM_SMIASSER			900
+
+#define CMDQ_MAX_HW_EVENT							512
+/* End of hardware event and begin of software token */
+
+/*
+ * CMDQ software tokens:
+ * The following are GCE software tokens, which can be used by clients
+ * event to operate API.
+ */
+
+/* Begin of GCE-D software token */
+/* MML software tokens */
+#define CMDQ_SYNC_TOKEN_MML_BUFA			630
+#define CMDQ_SYNC_TOKEN_MML_BUFB			631
+#define CMDQ_SYNC_TOKEN_MML_BUF_NEXT			632
+#define CMDQ_SYNC_TOKEN_MML_IR_MML_READY		633
+#define CMDQ_SYNC_TOKEN_MML_IR_DISP_READY		634
+#define CMDQ_SYNC_TOKEN_MML_MML_STOP			635
+#define CMDQ_SYNC_TOKEN_MML_PIPE0			636
+#define CMDQ_SYNC_TOKEN_MML_PIPE1			637
+#define CMDQ_SYNC_TOKEN_MML_PIPE1_NEXT			638
+#define CMDQ_SYNC_TOKEN_MML_APU_START			639
+
+/* Config thread notify trigger thread */
+#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY			640
+/* Trigger thread notify config thread */
+#define CMDQ_SYNC_TOKEN_STREAM_EOF			641
+/* Block Trigger thread until the ESD check finishes */
+#define CMDQ_SYNC_TOKEN_ESD_EOF				642
+#define CMDQ_SYNC_TOKEN_STREAM_BLOCK			643
+/* Check CABC setup finish */
+#define CMDQ_SYNC_TOKEN_CABC_EOF			644
+
+/* VFP period token for Msync */
+#define CMDQ_SYNC_TOKEN_VFP_PERIOD			645
+/* Software sync token for dual display */
+#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY_1			694
+#define CMDQ_SYNC_TOKEN_STREAM_EOF_1			695
+#define CMDQ_SYNC_TOKEN_ESD_EOF_1			696
+#define CMDQ_SYNC_TOKEN_STREAM_BLOCK_1			697
+#define CMDQ_SYNC_TOKEN_CABC_EOF_1			698
+
+/*
+ * GPR access tokens (for HW register backup)
+ * There are 15 32-bit GPR, form 3 GPR as a set
+ * (64-bit for address, 32-bit for value)
+ */
+#define CMDQ_SYNC_TOKEN_GPR_SET_0			700
+#define CMDQ_SYNC_TOKEN_GPR_SET_1			701
+#define CMDQ_SYNC_TOKEN_GPR_SET_2			702
+#define CMDQ_SYNC_TOKEN_GPR_SET_3			703
+#define CMDQ_SYNC_TOKEN_GPR_SET_4			704
+
+#define CMDQ_SYNC_TOKEN_TE_0				705
+#define CMDQ_SYNC_TOKEN_PREFETCH_TE_0			706
+#define CMDQ_SYNC_TOKEN_VIDLE_POWER_ON			707
+#define CMDQ_SYNC_TOKEN_CHECK_TRIGGER_MERGE		708
+
+/* Resource lock event to control resource in GCE thread */
+#define CMDQ_SYNC_RESOURCE_WROT0			710
+#define CMDQ_SYNC_RESOURCE_WROT1			711
+
+/* Hardware TRACE software token */
+#define CMDQ_SYNC_TOKEN_HW_TRACE_WAIT			712
+#define CMDQ_SYNC_TOKEN_HW_TRACE_LOCK			713
+
+/* Software sync token for dual display */
+#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY_3			714
+#define CMDQ_SYNC_TOKEN_STREAM_EOF_3			715
+#define CMDQ_SYNC_TOKEN_ESD_EOF_3			716
+#define CMDQ_SYNC_TOKEN_STREAM_BLOCK_3			717
+#define CMDQ_SYNC_TOKEN_CABC_EOF_3			718
+/* End of GCE-D software token */
+
+/* Begin of GCE-M software token */
+/* IMGSYS_POOL */
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_1			514
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_2			515
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_3			516
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_4			517
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_5			518
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_6			519
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_7			520
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_8			521
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_9			522
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_10			523
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_11			524
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_12			525
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_13			526
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_14			527
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_15			528
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_16			529
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_17			530
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_18			531
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_19			532
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_20			533
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_21			534
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_22			535
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_23			536
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_24			537
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_25			538
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_26			539
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_27			540
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_28			541
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_29			542
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_30			543
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_31			544
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_32			545
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_33			546
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_34			547
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_35			548
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_36			549
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_37			550
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_38			551
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_39			552
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_40			553
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_41			554
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_42			555
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_43			556
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_44			557
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_45			558
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_46			559
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_47			560
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_48			561
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_49			562
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_50			563
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_51			564
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_52			565
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_53			566
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_54			567
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_55			568
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_56			569
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_57			570
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_58			571
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_59			572
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_60			573
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_61			574
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_62			575
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_63			576
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_64			577
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_65			578
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_66			579
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_67			580
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_68			581
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_69			582
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_70			583
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_71			584
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_72			585
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_73			586
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_74			587
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_75			588
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_76			589
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_77			590
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_78			591
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_79			592
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_80			593
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_81			594
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_82			595
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_83			596
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_84			597
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_85			598
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_86			599
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_87			600
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_88			601
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_89			602
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_90			603
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_91			604
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_92			605
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_93			606
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_94			607
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_95			608
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_96			609
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_97			610
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_98			611
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_99			612
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_100			613
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_101			614
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_102			615
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_103			616
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_104			617
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_105			618
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_106			619
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_107			620
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_108			621
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_109			622
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_110			623
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_111			624
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_112			625
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_113			626
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_114			627
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_115			628
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_116			629
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_117			630
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_118			631
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_119			632
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_120			633
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_121			634
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_122			635
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_123			636
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_124			637
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_125			638
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_126			639
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_127			640
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_128			641
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_129			642
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_130			643
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_131			644
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_132			645
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_133			646
+
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_134			694
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_135			695
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_136			696
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_137			697
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_138			698
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_139			699
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_140			700
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_141			701
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_142			702
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_143			703
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_144			704
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_145			705
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_146			706
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_147			707
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_148			708
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_149			709
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_150			710
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_151			711
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_152			714
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_153			715
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_154			716
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_155			717
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_156			718
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_157			719
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_158			720
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_159			721
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_160			722
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_161			723
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_162			724
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_163			725
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_164			726
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_165			727
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_166			728
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_167			729
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_168			730
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_169			731
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_170			732
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_171			733
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_172			734
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_173			735
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_174			736
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_175			737
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_176			738
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_177			739
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_178			740
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_179			741
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_180			742
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_181			743
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_182			744
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_183			745
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_184			746
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_185			747
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_186			748
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_187			749
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_188			750
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_189			751
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_190			752
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_191			753
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_192			754
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_193			755
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_194			756
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_195			757
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_196			758
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_197			759
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_198			760
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_199			761
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_200			762
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_201			763
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_202			764
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_203			765
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_204			766
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_205			767
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_206			784
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_207			785
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_208			786
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_209			787
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_210			788
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_211			789
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_212			790
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_213			791
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_214			792
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_215			793
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_216			794
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_217			795
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_218			796
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_219			797
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_220			798
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_221			799
+
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_222			833
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_223			834
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_224			835
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_225			836
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_226			837
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_227			838
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_228			839
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_229			840
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_230			841
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_231			842
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_232			843
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_233			844
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_234			845
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_235			846
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_236			847
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_237			848
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_238			849
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_239			850
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_240			851
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_241			852
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_242			853
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_243			854
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_244			855
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_245			856
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_246			857
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_247			858
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_248			859
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_249			860
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_250			861
+
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_251			901
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_252			902
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_253			903
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_254			904
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_255			905
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_256			906
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_257			907
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_258			908
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_259			909
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_260			910
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_261			911
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_262			912
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_263			913
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_264			914
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_265			915
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_266			916
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_267			917
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_268			918
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_269			919
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_270			920
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_271			921
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_272			922
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_273			923
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_274			924
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_275			925
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_276			926
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_277			927
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_278			928
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_279			929
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_280			930
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_281			931
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_282			932
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_283			933
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_284			934
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_285			935
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_286			936
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_287			937
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_288			938
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_289			939
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_290			940
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_291			941
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_292			942
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_293			943
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_294			944
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_295			945
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_296			946
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_297			947
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_298			948
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_299			949
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_300			950
+
+/* ISP software token */
+#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_EIS			665
+#define CMDQ_SYNC_TOKEN_IMGSYS_OMC_TNR			666
+#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_LITE			667
+#define CMDQ_SYNC_TOKEN_IMGSYS_TRAW			668
+#define CMDQ_SYNC_TOKEN_IMGSYS_LTRAW			669
+#define CMDQ_SYNC_TOKEN_IMGSYS_XTRAW			670
+#define CMDQ_SYNC_TOKEN_IMGSYS_DIP			671
+#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_A			672
+#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_B			673
+#define CMDQ_SYNC_TOKEN_IPESYS_ME			674
+#define CMDQ_SYNC_TOKEN_APUSYS_APU			675
+#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_TRAW			676
+#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_LTRAW		677
+#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_XTRAW		678
+#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_DIP			679
+#define CMDQ_SYNC_TOKEN_IMGSYS_OMC_LITE			680
+
+/* IMG software token for QoS */
+#define CMDQ_SYNC_TOKEN_IMGSYS_QOS_LOCK			800
+/* IMG software token for Qof */
+#define CMDQ_SYNC_TOKEN_DIP_POWER_CTRL			862
+#define CMDQ_SYNC_TOKEN_DIP_TRIG_PWR_ON			863
+#define CMDQ_SYNC_TOKEN_DIP_PWR_ON			864
+#define CMDQ_SYNC_TOKEN_DIP_TRIG_PWR_OFF		865
+#define CMDQ_SYNC_TOKEN_DIP_PWR_OFF			866
+#define CMDQ_SYNC_TOKEN_DIP_PWR_HAND_SHAKE		867
+
+#define CMDQ_SYNC_TOKEN_TRAW_POWER_CTRL			868
+#define CMDQ_SYNC_TOKEN_TRAW_TRIG_PWR_ON		869
+#define CMDQ_SYNC_TOKEN_TRAW_PWR_ON			870
+#define CMDQ_SYNC_TOKEN_TRAW_TRIG_PWR_OFF		871
+#define CMDQ_SYNC_TOKEN_TRAW_PWR_OFF			872
+#define CMDQ_SYNC_TOKEN_TRAW_PWR_HAND_SHAKE		873
+/* End of GCE-M software token */
+
+/* Begin of common software token */
+
+/*
+ * Notify normal CMDQ there are some secure task done
+ * MUST NOT CHANGE, this token sync with secure world
+ */
+#define CMDQ_SYNC_SECURE_THR_EOF			647
+
+/* CMDQ use software token */
+#define CMDQ_SYNC_TOKEN_USER_0				649
+#define CMDQ_SYNC_TOKEN_USER_1				650
+#define CMDQ_SYNC_TOKEN_POLL_MONITOR			651
+#define CMDQ_SYNC_TOKEN_TPR_LOCK			652
+
+/* TZMP software token */
+#define CMDQ_SYNC_TOKEN_TZMP_DISP_WAIT			653
+#define CMDQ_SYNC_TOKEN_TZMP_DISP_SET			654
+#define CMDQ_SYNC_TOKEN_TZMP_ISP_WAIT			655
+#define CMDQ_SYNC_TOKEN_TZMP_ISP_SET			656
+#define CMDQ_SYNC_TOKEN_TZMP_AIE_WAIT			657
+#define CMDQ_SYNC_TOKEN_TZMP_AIE_SET			658
+#define CMDQ_SYNC_TOKEN_TZMP_ADL_WAIT			659
+#define CMDQ_SYNC_TOKEN_TZMP_ADL_SET			660
+
+/* PREBUILT software token */
+#define CMDQ_SYNC_TOKEN_PREBUILT_MDP_LOCK		682
+#define CMDQ_SYNC_TOKEN_PREBUILT_MML_LOCK		685
+#define CMDQ_SYNC_TOKEN_PREBUILT_VFMT_LOCK		688
+#define CMDQ_SYNC_TOKEN_PREBUILT_DISP_LOCK		691
+#define CMDQ_SYNC_TOKEN_DISP_VA_START			692
+#define CMDQ_SYNC_TOKEN_DISP_VA_END			693
+
+/* Event for GPR timer, used in sleep and poll with timeout */
+#define CMDQ_TOKEN_GPR_TIMER_R0				994
+#define CMDQ_TOKEN_GPR_TIMER_R1				995
+#define CMDQ_TOKEN_GPR_TIMER_R2				996
+#define CMDQ_TOKEN_GPR_TIMER_R3				997
+#define CMDQ_TOKEN_GPR_TIMER_R4				998
+#define CMDQ_TOKEN_GPR_TIMER_R5				999
+#define CMDQ_TOKEN_GPR_TIMER_R6				1000
+#define CMDQ_TOKEN_GPR_TIMER_R7				1001
+#define CMDQ_TOKEN_GPR_TIMER_R8				1002
+#define CMDQ_TOKEN_GPR_TIMER_R9				1003
+#define CMDQ_TOKEN_GPR_TIMER_R10			1004
+#define CMDQ_TOKEN_GPR_TIMER_R11			1005
+#define CMDQ_TOKEN_GPR_TIMER_R12			1006
+#define CMDQ_TOKEN_GPR_TIMER_R13			1007
+#define CMDQ_TOKEN_GPR_TIMER_R14			1008
+#define CMDQ_TOKEN_GPR_TIMER_R15			1009
+/* End of common software token */
+/* CMDQ software tokens END */
+
+#endif
-- 
2.43.0



From jason-jh.lin at mediatek.com  Tue Dec 10 19:22:56 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:22:56 +0800
Subject: [PATCH v2 8/8] media: mediatek: mdp3: Add programming flow for unsupported subsys ID hardware
In-Reply-To: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
Message-ID: <20241211032256.28494-9-jason-jh.lin@mediatek.com>

To support hardware without subsys IDs on new SoCs, add a programming
flow that checks whether the subsys ID is valid. If the subsys ID is
invalid, the flow will call 2 alternative CMDQ APIs:
cmdq_pkt_assign() and cmdq_pkt_write_s_mask_value() to achieve the
same functionality.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c    | 26 ++++++++++--
 .../platform/mediatek/mdp3/mtk-mdp3-comp.h    | 41 +++++++++++++++----
 2 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
index df0ab338ef41..58beeffd3fdf 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
@@ -320,9 +320,18 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
 		return ret;
 	/* Enable mux settings */
 	for (index = 0; index < ctrl->num_sets; index++) {
+		struct cmdq_client *cl = (struct cmdq_client *)cmd->pkt.cl;
+
 		set = &ctrl->sets[index];
-		cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
-				    set->value, 0xFFFFFFFF);
+		if (cmdq_subsys_is_valid(cl->chan, set->subsys_id)) {
+			cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
+					    set->value, 0xFFFFFFFF);
+		} else {
+			/* only MMIO access, no need to check mminfro_offset */
+			cmdq_pkt_assign(&cmd->pkt, 0, CMDQ_ADDR_HIGH(set->reg));
+			cmdq_pkt_write_s_mask_value(&cmd->pkt, 0, CMDQ_ADDR_LOW(set->reg),
+						    set->value, 0xFFFFFFFF);
+		}
 	}
 	/* Config sub-frame information */
 	for (index = (num_comp - 1); index >= 0; index--) {
@@ -376,9 +385,18 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
 	}
 	/* Disable mux settings */
 	for (index = 0; index < ctrl->num_sets; index++) {
+		struct cmdq_client *cl = (struct cmdq_client *)cmd->pkt.cl;
+
 		set = &ctrl->sets[index];
-		cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
-				    0, 0xFFFFFFFF);
+		if (cmdq_subsys_is_valid(cl->chan, set->subsys_id)) {
+			cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
+					    0, 0xFFFFFFFF);
+		} else {
+			/* only MMIO access, no need to check mminfro_offset */
+			cmdq_pkt_assign(&cmd->pkt, 0, CMDQ_ADDR_HIGH(set->reg));
+			cmdq_pkt_write_s_mask_value(&cmd->pkt, 0, CMDQ_ADDR_LOW(set->reg),
+						    0, 0xFFFFFFFF);
+		}
 	}
 
 	return 0;
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
index 3e5d2da1c807..f6c041934779 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
@@ -9,9 +9,25 @@
 
 #include "mtk-mdp3-cmdq.h"
 
-#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask, ...)	\
-	cmdq_pkt_write_mask(&((cmd)->pkt), id,			\
-		(base) + (ofst), (val), (mask), ##__VA_ARGS__)
+#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask, ...)				\
+do {											\
+	typeof(cmd) (_cmd) = (cmd);							\
+	typeof(id) (_id) = (id);							\
+	typeof(base) (_base) = (base);							\
+	typeof(ofst) (_ofst) = (ofst);							\
+	typeof(val) (_val) = (val);							\
+	typeof(mask) (_mask) = (mask);							\
+	if (cmdq_subsys_is_valid(((struct cmdq_client *)_cmd->pkt.cl)->chan, _id)) {	\
+		cmdq_pkt_write_mask(&_cmd->pkt, _id, _base + _ofst, _val,		\
+				    _mask, ##__VA_ARGS__);				\
+	} else {									\
+		/* only MMIO access, no need to check mminfro_offset */			\
+		cmdq_pkt_assign(&_cmd->pkt, 0, CMDQ_ADDR_HIGH(_base));			\
+		cmdq_pkt_write_s_mask_value(&_cmd->pkt, 0,				\
+					    CMDQ_ADDR_LOW(_base + _ofst), _val,		\
+					    _mask, ##__VA_ARGS__);			\
+	}										\
+} while (0)
 
 #define MM_REG_WRITE(cmd, id, base, ofst, val, mask, ...)	\
 do {								\
@@ -49,11 +65,20 @@ do {								\
 	cmdq_pkt_set_event(&((c)->pkt), (e));			\
 } while (0)
 
-#define MM_REG_POLL_MASK(cmd, id, base, ofst, val, _mask, ...)	\
-do {								\
-	typeof(_mask) (_m) = (_mask);				\
-	cmdq_pkt_poll_mask(&((cmd)->pkt), id,			\
-		(base) + (ofst), (val), (_m), ##__VA_ARGS__);	\
+#define MM_REG_POLL_MASK(cmd, id, base, ofst, val, _mask, ...)				\
+do {											\
+	typeof(cmd) (_cmd) = (cmd);							\
+	typeof(id) (_id) = (id);							\
+	typeof(base) (_base) = (base);							\
+	typeof(ofst) (_ofst) = (ofst);							\
+	typeof(val) (_val) = (val);							\
+	typeof(_mask) (_m) = (_mask);							\
+	if (cmdq_subsys_is_valid(((struct cmdq_client *)_cmd->pkt.cl)->chan, _id))	\
+		cmdq_pkt_poll_mask(&_cmd->pkt, _id, _base + _ofst, _val,		\
+				   _m, ##__VA_ARGS__);					\
+	else										\
+		cmdq_pkt_poll_addr(&_cmd->pkt, _base + _ofst, _val,			\
+				   _m, ##__VA_ARGS__);					\
 } while (0)
 
 #define MM_REG_POLL(cmd, id, base, ofst, val, mask, ...)	\
-- 
2.43.0



From jason-jh.lin at mediatek.com  Tue Dec 10 19:22:54 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:22:54 +0800
Subject: [PATCH v2 6/8] soc: mediatek: Add programming flow for unsupported subsys ID hardware
In-Reply-To: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
Message-ID: <20241211032256.28494-7-jason-jh.lin@mediatek.com>

To support hardware without subsys IDs on new SoCs, add a programming
flow that checks whether the subsys ID is valid. If the subsys ID is
invalid, the flow will call 2 alternative CMDQ APIs:
cmdq_pkt_assign() and cmdq_pkt_write_s_value() to achieve the same
functionality.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mmsys.c | 16 +++++++++++++---
 drivers/soc/mediatek/mtk-mutex.c | 12 ++++++++++--
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index bb4639ca0b8c..fbf97ae9dc28 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -167,9 +167,19 @@ static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask,
 	u32 tmp;
 
 	if (mmsys->cmdq_base.size && cmdq_pkt) {
-		ret = cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
-					  mmsys->cmdq_base.offset + offset, val,
-					  mask);
+		struct cmdq_client *cl = (struct cmdq_client *)cmdq_pkt->cl;
+
+		offset += mmsys->cmdq_base.offset;
+		if (cmdq_subsys_is_valid(cl->chan, mmsys->cmdq_base.subsys)) {
+			ret = cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
+						  offset, val, mask);
+		} else {
+			/* only MMIO access, no need to check mminfro_offset */
+			ret = cmdq_pkt_assign(cmdq_pkt, 0,
+					      CMDQ_ADDR_HIGH(mmsys->cmdq_base.pa_base));
+			ret |= cmdq_pkt_write_s_mask_value(cmdq_pkt, 0,
+							   CMDQ_ADDR_LOW(offset), val, mask);
+		}
 		if (ret)
 			pr_debug("CMDQ unavailable: using CPU write\n");
 		else
diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 5250c1d702eb..e94df5b783ce 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -963,6 +963,8 @@ int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, void *pkt)
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
 						 mutex[mutex->id]);
 	struct cmdq_pkt *cmdq_pkt = (struct cmdq_pkt *)pkt;
+	struct cmdq_client *cl = (struct cmdq_client *)cmdq_pkt->cl;
+	dma_addr_t en_addr = mtx->addr + DISP_REG_MUTEX_EN(mutex->id);
 
 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
 
@@ -971,8 +973,14 @@ int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, void *pkt)
 		return -ENODEV;
 	}
 
-	cmdq_pkt_write(cmdq_pkt, mtx->cmdq_reg.subsys,
-		       mtx->addr + DISP_REG_MUTEX_EN(mutex->id), 1);
+	if (cmdq_subsys_is_valid(cl->chan, mtx->cmdq_reg.subsys)) {
+		cmdq_pkt_write(cmdq_pkt, mtx->cmdq_reg.subsys, en_addr, 1);
+	} else {
+		/* only MMIO access, no need to check mminfro_offset */
+		cmdq_pkt_assign(cmdq_pkt, 0, CMDQ_ADDR_HIGH(en_addr));
+		cmdq_pkt_write_s_value(cmdq_pkt, 0, CMDQ_ADDR_LOW(en_addr), 1);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq);
-- 
2.43.0



From jason-jh.lin at mediatek.com  Tue Dec 10 19:22:55 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:22:55 +0800
Subject: [PATCH v2 7/8] drm/mediatek: Add programming flow for unsupported subsys ID hardware
In-Reply-To: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
Message-ID: <20241211032256.28494-8-jason-jh.lin@mediatek.com>

To support hardware without subsys IDs on new SoCs, add a programming
flow that checks whether the subsys ID is valid. If the subsys ID is
invalid, the flow will call 2 alternative CMDQ APIs:
cmdq_pkt_assign() and cmdq_pkt_write_s_value() to achieve the same
functionality.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 34 ++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
index edc6417639e6..0792c895526f 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
@@ -66,14 +66,38 @@ struct mtk_ddp_comp_dev {
 	struct cmdq_client_reg cmdq_reg;
 };
 
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+static void mtk_ddp_write_cmdq_pkt(struct cmdq_pkt *cmdq_pkt, struct cmdq_client_reg *cmdq_reg,
+				   unsigned int offset, unsigned int value, unsigned int mask)
+{
+	struct cmdq_client *cl = (struct cmdq_client *)cmdq_pkt->cl;
+
+	offset += cmdq_reg->offset;
+
+	if (cmdq_subsys_is_valid(cl->chan, cmdq_reg->subsys)) {
+		if (mask == GENMASK(31, 0))
+			cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys, offset, value);
+		else
+			cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys, offset, value, mask);
+	} else {
+		/* only MMIO access, no need to check mminfro_offset */
+		cmdq_pkt_assign(cmdq_pkt, 0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
+		if (mask == GENMASK(31, 0))
+			cmdq_pkt_write_s_value(cmdq_pkt, 0, CMDQ_ADDR_LOW(offset), value);
+		else
+			cmdq_pkt_write_s_mask_value(cmdq_pkt, 0, CMDQ_ADDR_LOW(offset),
+						    value, mask);
+	}
+}
+#endif
+
 void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 		   struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
 		   unsigned int offset)
 {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (cmdq_pkt)
-		cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
-			       cmdq_reg->offset + offset, value);
+		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0));
 	else
 #endif
 		writel(value, regs + offset);
@@ -85,8 +109,7 @@ void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (cmdq_pkt)
-		cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
-			       cmdq_reg->offset + offset, value);
+		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0));
 	else
 #endif
 		writel_relaxed(value, regs + offset);
@@ -98,8 +121,7 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (cmdq_pkt) {
-		cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys,
-				    cmdq_reg->offset + offset, value, mask);
+		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, mask);
 	} else {
 #endif
 		u32 tmp = readl(regs + offset);
-- 
2.43.0



From jason-jh.lin at mediatek.com  Tue Dec 10 19:22:50 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:22:50 +0800
Subject: [PATCH v2 2/8] dt-bindings: mailbox: mediatek: Add MT8196 support for gce-mailbox
In-Reply-To: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
Message-ID: <20241211032256.28494-3-jason-jh.lin@mediatek.com>

Add compatible name and iommus property for MT8196.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 .../devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml     | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml
index cef9d7601398..73d6db34d64a 100644
--- a/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml
+++ b/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml
@@ -25,6 +25,7 @@ properties:
           - mediatek,mt8188-gce
           - mediatek,mt8192-gce
           - mediatek,mt8195-gce
+          - mediatek,mt8196-gce
       - items:
           - const: mediatek,mt6795-gce
           - const: mediatek,mt8173-gce
@@ -49,6 +50,9 @@ properties:
     items:
       - const: gce
 
+  iommus:
+    maxItems: 1
+
 required:
   - compatible
   - "#mbox-cells"
-- 
2.43.0



From jason-jh.lin at mediatek.com  Tue Dec 10 19:22:48 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:22:48 +0800
Subject: [PATCH v2 0/8] Add GCE support for MT8196
Message-ID: <20241211032256.28494-1-jason-jh.lin@mediatek.com>

From: Jason-jh Lin <jason-jh.lin at mediatek.corp-partner.google.com>

This patch series adds support for the MediaTek MT8196 SoC in the CMDQ
driver and related subsystems. The changes include adding compatible
names and properties, updating driver data to accommodate hardware
changes, and modifying the usage of CMDQ API to support non-subsys ID
hardware.

---

Change in v2:
1. Remove the constant and fix warning in dt-bindings.
2. Remove the pa_base parameter of CMDQ APIs and related modification.
3. Move subsys checking to client drivers and use 2 alternative
   CMDQ APIs to achieve the same functionality.

---

Jason-JH.Lin (8):
  dt-bindings: mailbox: mediatek: Add GCE header file for MT8196
  dt-bindings: mailbox: mediatek: Add MT8196 support for gce-mailbox
  mailbox: mtk-cmdq: Add driver data to support for MT8196
  soc: mediatek: mtk-cmdq: Add pa_base parsing for unsupported subsys ID
    hardware
  soc: mediatek: mtk-cmdq: Add mminfra_offset compatibility for DRAM
    address
  soc: mediatek: Add programming flow for unsupported subsys ID hardware
  drm/mediatek: Add programming flow for unsupported subsys ID hardware
  media: mediatek: mdp3: Add programming flow for unsupported subsys ID
    hardware

 .../mailbox/mediatek,gce-mailbox.yaml         |    4 +
 drivers/gpu/drm/mediatek/mtk_ddp_comp.c       |   34 +-
 drivers/mailbox/mtk-cmdq-mailbox.c            |  107 +-
 .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c    |   26 +-
 .../platform/mediatek/mdp3/mtk-mdp3-comp.h    |   41 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c        |   53 +-
 drivers/soc/mediatek/mtk-mmsys.c              |   16 +-
 drivers/soc/mediatek/mtk-mutex.c              |   12 +-
 .../dt-bindings/mailbox/mediatek,mt8196-gce.h | 1439 +++++++++++++++++
 include/linux/mailbox/mtk-cmdq-mailbox.h      |    3 +
 include/linux/soc/mediatek/mtk-cmdq.h         |    1 +
 11 files changed, 1701 insertions(+), 35 deletions(-)
 create mode 100644 include/dt-bindings/mailbox/mediatek,mt8196-gce.h

-- 
2.43.0



From jason-jh.lin at mediatek.com  Tue Dec 10 19:22:51 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:22:51 +0800
Subject: [PATCH v2 3/8] mailbox: mtk-cmdq: Add driver data to support for MT8196
In-Reply-To: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
Message-ID: <20241211032256.28494-4-jason-jh.lin@mediatek.com>

MT8196 has 4 hardware changes compared with the previous SoC,
which correspond to the 4 new driver data:

1. mminfra_offset: For GCE data plane control
   Since GCE has been moved into mminfra, GCE needs to append the
   mminfra offset to the DRAM address when accessing the DRAM.

2. gce_vm: For GCE hardware virtualization
   Currently, the first version of the mt8196 mailbox controller only
   requires setting the VM-related registers to enable the permissions
   of a host VM.

3. dma_mask_bit: For dma address bit control
   In order to avoid the hardware limitations of MT8196 accessing DRAM,
   GCE needs to configure the DMA address to be less than 35 bits.

4. subsys_num: For subsys ID validation
   In previous SoCs, most hardware supported the 5-bit GCE subsys ID.
   When GCE executed instructions, the corresponding hareware register
   could be found through the subsys ID.
   However, 8196 most hardware does not support subsys ID, so the
   subsys ID will be set to an invalid value that exceeds the max
   supported subsys ID.
   By defining subsys_num, which is the max supported subsys ID, to
   determine whether the subsys ID is supported.
   So that mtk-cmdq-helper can know how to program the command.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c       | 107 +++++++++++++++++++++--
 include/linux/mailbox/mtk-cmdq-mailbox.h |   3 +
 2 files changed, 102 insertions(+), 8 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index d186865b8dce..a01646ee28b2 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -43,6 +43,17 @@
 #define GCE_CTRL_BY_SW				GENMASK(2, 0)
 #define GCE_DDR_EN				GENMASK(18, 16)
 
+#define GCE_VM_ID_MAP0			0x5018
+#define GCE_VM_MAP0_ALL_HOST			GENMASK(29, 0)
+#define GCE_VM_ID_MAP1			0x501c
+#define GCE_VM_MAP1_ALL_HOST			GENMASK(29, 0)
+#define GCE_VM_ID_MAP2			0x5020
+#define GCE_VM_MAP2_ALL_HOST			GENMASK(29, 0)
+#define GCE_VM_ID_MAP3			0x5024
+#define GCE_VM_MAP3_ALL_HOST			GENMASK(5, 0)
+#define GCE_VM_CPR_GSIZE		0x50c4
+#define GCE_VM_CPR_GSIZE_HSOT			GENMASK(3, 0)
+
 #define CMDQ_THR_ACTIVE_SLOT_CYCLES	0x3200
 #define CMDQ_THR_ENABLED		0x1
 #define CMDQ_THR_DISABLED		0x0
@@ -87,11 +98,25 @@ struct cmdq {
 struct gce_plat {
 	u32 thread_nr;
 	u8 shift;
+	u64 mminfra_offset;
 	bool control_by_sw;
 	bool sw_ddr_en;
+	bool gce_vm;
+	u32 dma_mask_bit;
+	u8 subsys_num;
 	u32 gce_num;
 };
 
+static inline u32 cmdq_reg_shift_addr(u32 addr, const struct gce_plat *pdata)
+{
+	return ((addr + pdata->mminfra_offset) >> pdata->shift);
+}
+
+static inline u32 cmdq_reg_revert_addr(u32 addr, const struct gce_plat *pdata)
+{
+	return ((addr << pdata->shift) - pdata->mminfra_offset);
+}
+
 static void cmdq_sw_ddr_enable(struct cmdq *cmdq, bool enable)
 {
 	WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
@@ -112,6 +137,38 @@ u8 cmdq_get_shift_pa(struct mbox_chan *chan)
 }
 EXPORT_SYMBOL(cmdq_get_shift_pa);
 
+u64 cmdq_get_offset_pa(struct mbox_chan *chan)
+{
+	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+	return cmdq->pdata->mminfra_offset;
+}
+EXPORT_SYMBOL(cmdq_get_offset_pa);
+
+bool cmdq_subsys_is_valid(struct mbox_chan *chan, u8 subsys)
+{
+	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+	return (subsys < cmdq->pdata->subsys_num);
+}
+EXPORT_SYMBOL(cmdq_subsys_is_valid);
+
+bool cmdq_addr_need_offset(struct mbox_chan *chan, dma_addr_t addr)
+{
+	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+	if (cmdq->pdata->mminfra_offset == 0)
+		return false;
+
+	/*
+	 * mminfra will recognize the addr that greater than the mminfra_offset
+	 * as a transaction to DRAM.
+	 * So the caller needs to append mminfra_offset for the true case.
+	 */
+	return (addr >= cmdq->pdata->mminfra_offset);
+}
+EXPORT_SYMBOL(cmdq_addr_need_offset);
+
 static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
 {
 	u32 status;
@@ -143,6 +200,17 @@ static void cmdq_init(struct cmdq *cmdq)
 	u32 gctl_regval = 0;
 
 	WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
+
+	if (cmdq->pdata->gce_vm) {
+		/* config cpr size for host vm */
+		writel(GCE_VM_CPR_GSIZE_HSOT, cmdq->base + GCE_VM_CPR_GSIZE);
+		/* config CPR_GSIZE before setting VM_ID_MAP to avoid data leakage */
+		writel(GCE_VM_MAP0_ALL_HOST, cmdq->base + GCE_VM_ID_MAP0);
+		writel(GCE_VM_MAP1_ALL_HOST, cmdq->base + GCE_VM_ID_MAP1);
+		writel(GCE_VM_MAP2_ALL_HOST, cmdq->base + GCE_VM_ID_MAP2);
+		writel(GCE_VM_MAP3_ALL_HOST, cmdq->base + GCE_VM_ID_MAP3);
+	}
+
 	if (cmdq->pdata->control_by_sw)
 		gctl_regval = GCE_CTRL_BY_SW;
 	if (cmdq->pdata->sw_ddr_en)
@@ -199,7 +267,7 @@ static void cmdq_task_insert_into_thread(struct cmdq_task *task)
 				prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
 	prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] =
 		(u64)CMDQ_JUMP_BY_PA << 32 |
-		(task->pa_base >> task->cmdq->pdata->shift);
+		cmdq_reg_shift_addr(task->pa_base, task->cmdq->pdata);
 	dma_sync_single_for_device(dev, prev_task->pa_base,
 				   prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
 
@@ -264,7 +332,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
 	else
 		return;
 
-	curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->pdata->shift;
+	curr_pa = cmdq_reg_shift_addr(readl(thread->base + CMDQ_THR_CURR_ADDR), cmdq->pdata);
 
 	list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
 				 list_entry) {
@@ -416,9 +484,9 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
 		 */
 		WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
 
-		writel(task->pa_base >> cmdq->pdata->shift,
+		writel(cmdq_reg_shift_addr(task->pa_base, cmdq->pdata),
 		       thread->base + CMDQ_THR_CURR_ADDR);
-		writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->pdata->shift,
+		writel(cmdq_reg_shift_addr(task->pa_base + pkt->cmd_buf_size, cmdq->pdata),
 		       thread->base + CMDQ_THR_END_ADDR);
 
 		writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
@@ -426,10 +494,10 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
 		writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
 	} else {
 		WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
-		curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
-			cmdq->pdata->shift;
-		end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
-			cmdq->pdata->shift;
+		curr_pa = cmdq_reg_revert_addr(readl(thread->base + CMDQ_THR_CURR_ADDR),
+					       cmdq->pdata);
+		end_pa = cmdq_reg_revert_addr(readl(thread->base + CMDQ_THR_END_ADDR),
+					      cmdq->pdata);
 		/* check boundary */
 		if (curr_pa == end_pa - CMDQ_INST_SIZE ||
 		    curr_pa == end_pa) {
@@ -663,6 +731,9 @@ static int cmdq_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
+	if (cmdq->pdata->dma_mask_bit)
+		dma_set_coherent_mask(dev, DMA_BIT_MASK(cmdq->pdata->dma_mask_bit));
+
 	cmdq->mbox.dev = dev;
 	cmdq->mbox.chans = devm_kcalloc(dev, cmdq->pdata->thread_nr,
 					sizeof(*cmdq->mbox.chans), GFP_KERNEL);
@@ -736,6 +807,7 @@ static const struct gce_plat gce_plat_mt6779 = {
 	.thread_nr = 24,
 	.shift = 3,
 	.control_by_sw = false,
+	.subsys_num = 30,
 	.gce_num = 1
 };
 
@@ -743,6 +815,7 @@ static const struct gce_plat gce_plat_mt8173 = {
 	.thread_nr = 16,
 	.shift = 0,
 	.control_by_sw = false,
+	.subsys_num = 4,
 	.gce_num = 1
 };
 
@@ -750,6 +823,7 @@ static const struct gce_plat gce_plat_mt8183 = {
 	.thread_nr = 24,
 	.shift = 0,
 	.control_by_sw = false,
+	.subsys_num = 30,
 	.gce_num = 1
 };
 
@@ -758,6 +832,7 @@ static const struct gce_plat gce_plat_mt8186 = {
 	.shift = 3,
 	.control_by_sw = true,
 	.sw_ddr_en = true,
+	.subsys_num = 30,
 	.gce_num = 1
 };
 
@@ -765,6 +840,7 @@ static const struct gce_plat gce_plat_mt8188 = {
 	.thread_nr = 32,
 	.shift = 3,
 	.control_by_sw = true,
+	.subsys_num = 26,
 	.gce_num = 2
 };
 
@@ -772,6 +848,7 @@ static const struct gce_plat gce_plat_mt8192 = {
 	.thread_nr = 24,
 	.shift = 3,
 	.control_by_sw = true,
+	.subsys_num = 30,
 	.gce_num = 1
 };
 
@@ -779,6 +856,19 @@ static const struct gce_plat gce_plat_mt8195 = {
 	.thread_nr = 24,
 	.shift = 3,
 	.control_by_sw = true,
+	.subsys_num = 26,
+	.gce_num = 2
+};
+
+static const struct gce_plat gce_plat_mt8196 = {
+	.thread_nr = 32,
+	.shift = 3,
+	.mminfra_offset = 0x80000000, /* 2GB */
+	.control_by_sw = true,
+	.sw_ddr_en = true,
+	.gce_vm = true,
+	.dma_mask_bit = 35,
+	.subsys_num = 30,
 	.gce_num = 2
 };
 
@@ -790,6 +880,7 @@ static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt8188-gce", .data = (void *)&gce_plat_mt8188},
 	{.compatible = "mediatek,mt8192-gce", .data = (void *)&gce_plat_mt8192},
 	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_mt8195},
+	{.compatible = "mediatek,mt8196-gce", .data = (void *)&gce_plat_mt8196},
 	{}
 };
 MODULE_DEVICE_TABLE(of, cmdq_of_ids);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
index a8f0070c7aa9..3a675c970c21 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -79,5 +79,8 @@ struct cmdq_pkt {
 };
 
 u8 cmdq_get_shift_pa(struct mbox_chan *chan);
+u64 cmdq_get_offset_pa(struct mbox_chan *chan);
+bool cmdq_subsys_is_valid(struct mbox_chan *chan, u8 subsys);
+bool cmdq_addr_need_offset(struct mbox_chan *chan, dma_addr_t addr);
 
 #endif /* __MTK_CMDQ_MAILBOX_H__ */
-- 
2.43.0



From Jason-JH.Lin at mediatek.com  Tue Dec 10 19:27:59 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Wed, 11 Dec 2024 03:27:59 +0000
Subject: [PATCH v3] drm/mediatek: Move mtk_crtc_finish_page_flip() to
 ddp_cmdq_cb()
In-Reply-To: <1e953fb5a4e4965ba509a1bb45e7c8336102ff29.camel@mediatek.com>
References: <20241210032820.10958-1-jason-jh.lin@mediatek.com>
	 <1e953fb5a4e4965ba509a1bb45e7c8336102ff29.camel@mediatek.com>
Message-ID: <c3935ca3e990f6f608326cef1dd495d5913c227d.camel@mediatek.com>

Hi CK,

[snip]

> > @@ -109,9 +109,14 @@ static void mtk_crtc_finish_page_flip(struct
> > mtk_crtc *mtk_crtc)
> >  static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
> >  {
> >  	unsigned long flags;
> > +	struct drm_crtc *crtc = &mtk_crtc->base;
> > +	struct mtk_drm_private *priv = crtc->dev->dev_private;
> >  
> >  	drm_crtc_handle_vblank(&mtk_crtc->base);
> >  
> > +	if (!priv->data->shadow_register)
> > +		return;
> > +
> 
> I forget one case.
> For the CPU case (SoC has no shadow register and CONFIG_MTK_CMDQ is
> not enable),
> this driver should still work.
> CPU case is not a usual case, but it could be used in some
> verification case.
> So the condition may be
> 
> #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> 	if (mtk_crtc->cmdq_client.chan)
> 		return;
> #endif
> 

OK, I'll change the condition like this.

> >  	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> >  	if (!mtk_crtc->config_updating && mtk_crtc-
> > >pending_needs_vblank) {
> >  		mtk_crtc_finish_page_flip(mtk_crtc);

[snip]

> > @@ -584,6 +592,10 @@ static void mtk_crtc_update_config(struct
> > mtk_crtc *mtk_crtc, bool needs_vblank)
> >  		mtk_mutex_acquire(mtk_crtc->mutex);
> >  		mtk_crtc_ddp_config(crtc, NULL);
> >  		mtk_mutex_release(mtk_crtc->mutex);
> > +
> > +		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> > +		mtk_crtc->config_updating = false;
> > +		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> >  	}
> >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >  	if (mtk_crtc->cmdq_client.chan) {
> > @@ -606,13 +618,14 @@ static void mtk_crtc_update_config(struct
> > mtk_crtc *mtk_crtc, bool needs_vblank)
> >  		 */
> >  		mtk_crtc->cmdq_vblank_cnt = 3;
> >  
> > +		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> > +		mtk_crtc->config_updating = false;
> > +		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> > +
> >  		mbox_send_message(mtk_crtc->cmdq_client.chan,
> > cmdq_handle);
> >  		mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
> >  	}
> >  #endif
> > -	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
> > -	mtk_crtc->config_updating = false;
> > -	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
> 
> For the CPU case (SoC has no shadow register and CONFIG_MTK_CMDQ is
> not enable),
> This code is necessary.
> Maybe keep these code or some modification for CPU case.
> 

OK, I'll keep the original flow and only modify for
IS_REACHABLE(CONFIG_MTK_CMDQ) case.

Regards,
Jason-JH.lin

> Regards,
> CK

From semen.protsenko at linaro.org  Tue Dec 10 19:30:27 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 10 Dec 2024 21:30:27 -0600
Subject: [PATCH] arm64: dts: exynos: Specify reserved secure memory explicitly
Message-ID: <20241211033027.12985-1-semen.protsenko@linaro.org>

Instead of carving out the secure area in 'memory' node, let's describe
it in 'reserved-memory'. That makes it easier to understand both RAM
regions and particular secure world memory region. Originally the device
tree was created in a way to make sure it was well aligned with the way
LittleKernel bootloader modified it. But later it was found the
LittleKernel works fine with properly described reserved regions, so
it's possible now to define those in a cleaner way.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 arch/arm64/boot/dts/exynos/exynos850-e850-96.dts | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts b/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
index f074df8982b3..7d70a32e75b2 100644
--- a/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
+++ b/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
@@ -45,17 +45,9 @@ usb_dr_connector: endpoint {
 		};
 	};
 
-	/*
-	 * RAM: 4 GiB (eMCP):
-	 *   - 2 GiB at 0x80000000
-	 *   - 2 GiB at 0x880000000
-	 *
-	 * 0xbab00000..0xbfffffff: secure memory (85 MiB).
-	 */
 	memory at 80000000 {
 		device_type = "memory";
-		reg = <0x0 0x80000000 0x3ab00000>,
-		      <0x0 0xc0000000 0x40000000>,
+		reg = <0x0 0x80000000 0x80000000>,
 		      <0x8 0x80000000 0x80000000>;
 	};
 
@@ -146,6 +138,11 @@ reserved-memory {
 		#size-cells = <1>;
 		ranges;
 
+		secure_mem: memory at bab00000 {
+			reg = <0x0 0xbab00000 0x5500000>;
+			no-map;
+		};
+
 		ramoops at f0000000 {
 			compatible = "ramoops";
 			reg = <0x0 0xf0000000 0x200000>;
-- 
2.39.5



From robdclark at gmail.com  Tue Dec 10 19:43:19 2024
From: robdclark at gmail.com (Rob Clark)
Date: Tue, 10 Dec 2024 19:43:19 -0800
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <1219b46d-2aea-4377-a8ca-024039ee1499@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>
 <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com> <iyknardi445n4h74am22arpgc4vlchh6z6cvkbff2xg76pd655@nozwz7snt476>
 <1219b46d-2aea-4377-a8ca-024039ee1499@quicinc.com>
Message-ID: <CAF6AEGs4EebrwyQZviNXqB2=3h2wgZpmbrdGHuEU4z1D014GRA@mail.gmail.com>

On Tue, Dec 10, 2024 at 7:08?PM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
>
> On 12/11/2024 6:43 AM, Bjorn Andersson wrote:
> > On Tue, Dec 10, 2024 at 02:22:27AM +0530, Akhil P Oommen wrote:
> >> On 12/10/2024 1:24 AM, Rob Clark wrote:
> >>> On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> >>>>
> >>>> When kernel is booted in EL2, SECVID registers are accessible to the
> >>>> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> >>>> on Zap firmware. Also, we can't load a secure firmware without a
> >>>> hypervisor that supports it.
> >>>
> >>> Shouldn't we do this based on whether zap node is in dtb (and not disabled)?
> >>
> >> This is better, isn't it? Otherwise, multiple overlays should be
> >> maintained for each soc/board since EL2 can be toggled from bootloader.
> >> And this feature is likely going to be more widely available.
> >>
> >
> > The DeviceTree passed to the OS needs to describe the world that said OS
> > is going to operate in. If you change the world you need to change the
> > description.
> > There are several other examples where this would be necessary
> > (remoteproc and watchdog to name two examples from the Qualcomm upstream
> > world).
>
> But basic things work without those changes, right? For eg: Desktop UI

It isn't really so much about whether certain use-cases can work with
a sub-optimal description of the hw (where in this case "hw" really
means "hw plus how the fw allows things to look to the HLOS").. It is
more about the hw/fw/whatever providing an accurate description of
what things look like to the HLOS.

I'm leaning more towards the hw+fw providing HLOS an accurate view...
and the fact that that carries over into other areas of dtb (ie. it
isn't the only thing that slbounce needs to patch, as I previously
mentioned) reinforces my view there.  This seems like a thing to fix
in fw/bootloader tbh.

BR,
-R


>
> >
> > So, if we can cover this by zap-shader being enabled or disabled, that
> > sounds like a clean and scaleable solution.
>
> I think we are focusing too much on zap shader. If the driver can
> determine itself about access to its register, shouldn't it be allowed
> to use that?
>
> -Akhil
>
> >
> > Regards,
> > Bjorn
>


From ck.hu at mediatek.com  Tue Dec 10 19:46:26 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Wed, 11 Dec 2024 03:46:26 +0000
Subject: [PATCH v2 7/8] drm/mediatek: Add programming flow for unsupported
 subsys ID hardware
In-Reply-To: <20241211032256.28494-8-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
	 <20241211032256.28494-8-jason-jh.lin@mediatek.com>
Message-ID: <761ef6ecfe8298f945e6627aff29f864fcf7b9c0.camel@mediatek.com>

Hi, Jason:

On Wed, 2024-12-11 at 11:22 +0800, Jason-JH.Lin wrote:
> To support hardware without subsys IDs on new SoCs, add a programming
> flow that checks whether the subsys ID is valid. If the subsys ID is
> invalid, the flow will call 2 alternative CMDQ APIs:
> cmdq_pkt_assign() and cmdq_pkt_write_s_value() to achieve the same
> functionality.
> 
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 34 ++++++++++++++++++++-----
>  1 file changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> index edc6417639e6..0792c895526f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> @@ -66,14 +66,38 @@ struct mtk_ddp_comp_dev {
>  	struct cmdq_client_reg cmdq_reg;
>  };
>  
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +static void mtk_ddp_write_cmdq_pkt(struct cmdq_pkt *cmdq_pkt, struct cmdq_client_reg *cmdq_reg,
> +				   unsigned int offset, unsigned int value, unsigned int mask)

Drop this function.

> +{
> +	struct cmdq_client *cl = (struct cmdq_client *)cmdq_pkt->cl;
> +
> +	offset += cmdq_reg->offset;
> +
> +	if (cmdq_subsys_is_valid(cl->chan, cmdq_reg->subsys)) {
> +		if (mask == GENMASK(31, 0))
> +			cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys, offset, value);
> +		else
> +			cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys, offset, value, mask);
> +	} else {
> +		/* only MMIO access, no need to check mminfro_offset */
> +		cmdq_pkt_assign(cmdq_pkt, 0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
> +		if (mask == GENMASK(31, 0))
> +			cmdq_pkt_write_s_value(cmdq_pkt, 0, CMDQ_ADDR_LOW(offset), value);
> +		else
> +			cmdq_pkt_write_s_mask_value(cmdq_pkt, 0, CMDQ_ADDR_LOW(offset),
> +						    value, mask);
> +	}
> +}
> +#endif
> +
>  void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
>  		   struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
>  		   unsigned int offset)
>  {
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
>  	if (cmdq_pkt)
> -		cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
> -			       cmdq_reg->offset + offset, value);
> +		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0));

/* only MMIO access, no need to check mminfro_offset */
cmdq_pkt_assign(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
cmdq_pkt_write_s_value(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_LOW(offset), value);

>  	else
>  #endif
>  		writel(value, regs + offset);
> @@ -85,8 +109,7 @@ void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
>  {
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
>  	if (cmdq_pkt)
> -		cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
> -			       cmdq_reg->offset + offset, value);
> +		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0));

/* only MMIO access, no need to check mminfro_offset */
cmdq_pkt_assign(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
cmdq_pkt_write_s_value(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_LOW(offset), value);

>  	else
>  #endif
>  		writel_relaxed(value, regs + offset);
> @@ -98,8 +121,7 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
>  {
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
>  	if (cmdq_pkt) {
> -		cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys,
> -				    cmdq_reg->offset + offset, value, mask);
> +		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, mask);

/* only MMIO access, no need to check mminfro_offset */
cmdq_pkt_assign(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
cmdq_pkt_write_s_mask_value(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_LOW(offset),
			    value, mask);

CMDQ_XXXREG_0 is defined in cmdq header file.

Regards,
CK

>  	} else {
>  #endif
>  		u32 tmp = readl(regs + offset);


From jason-jh.lin at mediatek.com  Tue Dec 10 19:47:16 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Wed, 11 Dec 2024 11:47:16 +0800
Subject: [PATCH v4] drm/mediatek: Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb()
Message-ID: <20241211034716.29241-1-jason-jh.lin@mediatek.com>

mtk_crtc_finish_page_flip() is used to notify userspace that a
page flip has been completed, allowing userspace to free the frame
buffer of the last frame and commit the next frame.

In MediaTek's hardware design for configuring display hardware by using
GCE, `DRM_EVENT_FLIP_COMPLETE` should be notified to userspace after
GCE has finished configuring all display hardware settings for each
atomic_commit().

Currently, mtk_crtc_finish_page_flip() cannot guarantee that GCE has
configured all the display hardware settings of the last frame.
Therefore, to increase the accuracy of the timing for notifying
`DRM_EVENT_FLIP_COMPLETE` to userspace, mtk_crtc_finish_page_flip()
should be moved to ddp_cmdq_cb().

Fixes: 7f82d9c43879 ("drm/mediatek: Clear pending flag when cmdq packet is done")
Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_crtc.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
index eb0e1233ad04..5674f5707cca 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
@@ -112,6 +112,11 @@ static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
 
 	drm_crtc_handle_vblank(&mtk_crtc->base);
 
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	if (mtk_crtc->cmdq_client.chan)
+		return;
+#endif
+
 	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
 	if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
 		mtk_crtc_finish_page_flip(mtk_crtc);
@@ -284,10 +289,8 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 	state = to_mtk_crtc_state(mtk_crtc->base.state);
 
 	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
-	if (mtk_crtc->config_updating) {
-		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+	if (mtk_crtc->config_updating)
 		goto ddp_cmdq_cb_out;
-	}
 
 	state->pending_config = false;
 
@@ -315,10 +318,15 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 		mtk_crtc->pending_async_planes = false;
 	}
 
-	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
-
 ddp_cmdq_cb_out:
 
+	if (mtk_crtc->pending_needs_vblank) {
+		mtk_crtc_finish_page_flip(mtk_crtc);
+		mtk_crtc->pending_needs_vblank = false;
+	}
+
+	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+
 	mtk_crtc->cmdq_vblank_cnt = 0;
 	wake_up(&mtk_crtc->cb_blocking_queue);
 }
@@ -606,13 +614,18 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
 		 */
 		mtk_crtc->cmdq_vblank_cnt = 3;
 
+		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
+		mtk_crtc->config_updating = false;
+		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+
 		mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
 		mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
 	}
-#endif
+#else
 	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
 	mtk_crtc->config_updating = false;
 	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+#endif
 
 	mutex_unlock(&mtk_crtc->hw_lock);
 }
-- 
2.43.0



From ck.hu at mediatek.com  Tue Dec 10 20:04:53 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Wed, 11 Dec 2024 04:04:53 +0000
Subject: [PATCH v2 7/8] drm/mediatek: Add programming flow for unsupported
 subsys ID hardware
In-Reply-To: <761ef6ecfe8298f945e6627aff29f864fcf7b9c0.camel@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
	 <20241211032256.28494-8-jason-jh.lin@mediatek.com>
	 <761ef6ecfe8298f945e6627aff29f864fcf7b9c0.camel@mediatek.com>
Message-ID: <4e10e2cd5d58321bdd7e5dabf5fb70702f8afc92.camel@mediatek.com>

On Wed, 2024-12-11 at 11:46 +0800, CK Hu wrote:
> Hi, Jason:
> 
> On Wed, 2024-12-11 at 11:22 +0800, Jason-JH.Lin wrote:
> > To support hardware without subsys IDs on new SoCs, add a programming
> > flow that checks whether the subsys ID is valid. If the subsys ID is
> > invalid, the flow will call 2 alternative CMDQ APIs:
> > cmdq_pkt_assign() and cmdq_pkt_write_s_value() to achieve the same
> > functionality.
> > 
> > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 34 ++++++++++++++++++++-----
> >  1 file changed, 28 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > index edc6417639e6..0792c895526f 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > @@ -66,14 +66,38 @@ struct mtk_ddp_comp_dev {
> >  	struct cmdq_client_reg cmdq_reg;
> >  };
> >  
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +static void mtk_ddp_write_cmdq_pkt(struct cmdq_pkt *cmdq_pkt, struct cmdq_client_reg *cmdq_reg,
> > +				   unsigned int offset, unsigned int value, unsigned int mask)
> 
> Drop this function.

Sorry, it seems cmdq_subsys_is_valid() is used to check the SoC support new API or not.
But I would try to find out a way not to always check using new API or not.

Regards,
CK

> 
> > +{
> > +	struct cmdq_client *cl = (struct cmdq_client *)cmdq_pkt->cl;
> > +
> > +	offset += cmdq_reg->offset;
> > +
> > +	if (cmdq_subsys_is_valid(cl->chan, cmdq_reg->subsys)) {
> > +		if (mask == GENMASK(31, 0))
> > +			cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys, offset, value);
> > +		else
> > +			cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys, offset, value, mask);
> > +	} else {
> > +		/* only MMIO access, no need to check mminfro_offset */
> > +		cmdq_pkt_assign(cmdq_pkt, 0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
> > +		if (mask == GENMASK(31, 0))
> > +			cmdq_pkt_write_s_value(cmdq_pkt, 0, CMDQ_ADDR_LOW(offset), value);
> > +		else
> > +			cmdq_pkt_write_s_mask_value(cmdq_pkt, 0, CMDQ_ADDR_LOW(offset),
> > +						    value, mask);
> > +	}
> > +}
> > +#endif
> > +
> >  void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
> >  		   struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
> >  		   unsigned int offset)
> >  {
> >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >  	if (cmdq_pkt)
> > -		cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
> > -			       cmdq_reg->offset + offset, value);
> > +		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0));
> 
> /* only MMIO access, no need to check mminfro_offset */
> cmdq_pkt_assign(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
> cmdq_pkt_write_s_value(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_LOW(offset), value);
> 
> >  	else
> >  #endif
> >  		writel(value, regs + offset);
> > @@ -85,8 +109,7 @@ void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
> >  {
> >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >  	if (cmdq_pkt)
> > -		cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
> > -			       cmdq_reg->offset + offset, value);
> > +		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0));
> 
> /* only MMIO access, no need to check mminfro_offset */
> cmdq_pkt_assign(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
> cmdq_pkt_write_s_value(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_LOW(offset), value);
> 
> >  	else
> >  #endif
> >  		writel_relaxed(value, regs + offset);
> > @@ -98,8 +121,7 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
> >  {
> >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >  	if (cmdq_pkt) {
> > -		cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys,
> > -				    cmdq_reg->offset + offset, value, mask);
> > +		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, mask);
> 
> /* only MMIO access, no need to check mminfro_offset */
> cmdq_pkt_assign(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
> cmdq_pkt_write_s_mask_value(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_LOW(offset),
> 			    value, mask);
> 
> CMDQ_XXXREG_0 is defined in cmdq header file.
> 
> Regards,
> CK
> 
> >  	} else {
> >  #endif
> >  		u32 tmp = readl(regs + offset);
> 


From anshuman.khandual at arm.com  Tue Dec 10 20:32:42 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Dec 2024 10:02:42 +0530
Subject: [PATCH V2 5/7] arm64/cpufeature: Add field details for
 ID_AA64DFR1_EL1 register
In-Reply-To: <20241210164144.GA16039@willie-the-truck>
References: <20241028053426.2486633-1-anshuman.khandual@arm.com>
 <20241028053426.2486633-6-anshuman.khandual@arm.com>
 <20241210164144.GA16039@willie-the-truck>
Message-ID: <a382200e-00c4-405a-a417-f4c09bd91fb7@arm.com>



On 12/10/24 22:11, Will Deacon wrote:
> On Mon, Oct 28, 2024 at 11:04:24AM +0530, Anshuman Khandual wrote:
>> This adds required field details for ID_AA64DFR1_EL1, and also drops dummy
>> ftr_raz[] array which is now redundant. These register fields will be used
>> to enable increased breakpoint and watchpoint registers via FEAT_Debugv8p9
>> later.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> cc: Mark Brown <broonie at kernel.org>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/arm64/kernel/cpufeature.c | 21 ++++++++++++++++-----
>>  1 file changed, 16 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
>> index 718728a85430..bd4d85f5dd92 100644
>> --- a/arch/arm64/kernel/cpufeature.c
>> +++ b/arch/arm64/kernel/cpufeature.c
>> @@ -530,6 +530,21 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
>>  	ARM64_FTR_END,
>>  };
>>  
>> +static const struct arm64_ftr_bits ftr_id_aa64dfr1[] = {
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABL_CMPs_SHIFT, 8, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_DPFZS_SHIFT, 4, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_EBEP_SHIFT, 4, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ITE_SHIFT, 4, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABLE_SHIFT, 4, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_PMICNTR_SHIFT, 4, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SPMU_SHIFT, 4, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_CTX_CMPs_SHIFT, 8, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_WRPs_SHIFT, 8, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_BRPs_SHIFT, 8, 0),
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SYSPMUID_SHIFT, 8, 0),
>> +	ARM64_FTR_END,
>> +};
> 
> I think I mentioned this on an earlier series, but it would be useful to
> see some justification in the commit message as to why some of these
> features are considered STRICT vs NONSTRICT and why LOWER_SAFE is
> preferred over EXACT.

I have updated the commit message regarding STRICT vs NONSTRICT as Mark had
mentioned earlier (see below). But just wondering about FTR_LOWER_SAFE. All
similar fields have been marked as FTR_LOWER_SAFE.

> 
> For example, why is EBEP strict whereas other PMU-related fields aren't?

IIUC there are two types of fields here.

- Feature presence     (EBEP, ITE, ABLE etc)		---> FTR_STRICT
- Debug resource count (WRPs, BRPs, CTX_CMPs etc)	---> FTR_NONSTRICT

> Why is the CTX_CMPs field treated differently to the same field in DFR0?

There is mismatch not only for CTX_CMPs but for WRPs and BRPs as well. As
mentioned earlier, being resource count type, I believe these should be
marked as FTR_NONSTRICT in existing DFR0 as well. I could send a patch
fixing DFR0 first.

> 
> I'm not saying the above table is wrong, it just looks arbitrary without
> the justification.

Please find the updated version (v3) for this patch here for reference.

--------------
[PATCH] arm64/cpufeature: Add field details for ID_AA64DFR1_EL1 register

This adds required field details for ID_AA64DFR1_EL1, and also drops dummy
ftr_raz[] array which is now redundant. These register fields will be used
to enable increased breakpoint and watchpoint registers via FEAT_Debugv8p9
later. The register fields have been marked as FTR_STRICT, unless there is
a known variation in practice.

Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kernel/cpufeature.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed8..0dc22fde104e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -534,6 +534,21 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
 	ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_id_aa64dfr1[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABL_CMPs_SHIFT, 8, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_DPFZS_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_EBEP_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ITE_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABLE_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_PMICNTR_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SPMU_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_CTX_CMPs_SHIFT, 8, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_WRPs_SHIFT, 8, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_BRPs_SHIFT, 8, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SYSPMUID_SHIFT, 8, 0),
+	ARM64_FTR_END,
+};
+
 static const struct arm64_ftr_bits ftr_mvfr0[] = {
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_EL1_FPRound_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_EL1_FPShVec_SHIFT, 4, 0),
@@ -720,10 +735,6 @@ static const struct arm64_ftr_bits ftr_single32[] = {
 	ARM64_FTR_END,
 };
 
-static const struct arm64_ftr_bits ftr_raz[] = {
-	ARM64_FTR_END,
-};
-
 #define __ARM64_FTR_REG_OVERRIDE(id_str, id, table, ovr) {	\
 		.sys_id = id,					\
 		.reg = 	&(struct arm64_ftr_reg){		\
@@ -796,7 +807,7 @@ static const struct __ftr_reg_entry {
 
 	/* Op1 = 0, CRn = 0, CRm = 5 */
 	ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
-	ARM64_FTR_REG(SYS_ID_AA64DFR1_EL1, ftr_raz),
+	ARM64_FTR_REG(SYS_ID_AA64DFR1_EL1, ftr_id_aa64dfr1),
 
 	/* Op1 = 0, CRn = 0, CRm = 6 */
 	ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0),
-- 
2.25.1
--------------
Changes in V3:
 
- Updated commit message regarding FTR_STRICT
- Updated ID_AA64DFR1_EL1.ABLE as FTR_NONSTRICT


From wens at kernel.org  Tue Dec 10 21:09:54 2024
From: wens at kernel.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:09:54 +0800
Subject: [PATCH 1/2] arm64: dts: mediatek: mt8173-elm: Fix MT6397 PMIC
 sub-node names
In-Reply-To: <173386568696.497617.3727087837255802552.robh@kernel.org>
References: <20241210092614.3951748-1-wenst@chromium.org> <173386568696.497617.3727087837255802552.robh@kernel.org>
Message-ID: <CAGb2v65D9cdTRoEwwpTUcRZBnrdJ+6UZ-osN1vpUP_JxtJMr8Q@mail.gmail.com>

On Wed, Dec 11, 2024 at 5:43?AM Rob Herring (Arm) <robh at kernel.org> wrote:
>
>
> On Tue, 10 Dec 2024 17:26:12 +0800, Chen-Yu Tsai wrote:
> > The MT6397 PMIC bindings specify exact names for its sub-nodes. The
> > names used in the current dts don't match, causing a validation error.
> >
> > Fix up the names. Also drop the label for the regulators node, since
> > any reference should be against the individual regulator sub-nodes.
> >
> > Fixes: 689b937bedde ("arm64: dts: mediatek: add mt8173 elm and hana board")
> > Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> > ---
> >  arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
>
>
> My bot found new DTB warnings on the .dts files added or changed in this
> series.
>
> Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
> are fixed by another series. Ultimately, it is up to the platform
> maintainer whether these warnings are acceptable or not. No need to reply
> unless the platform maintainer has comments.
>
> If you already ran DT checks and didn't see these error(s), then
> make sure dt-schema is up to date:
>
>   pip3 install dtschema --upgrade
>
>
> New warnings running 'make CHECK_DTBS=y mediatek/mt8173-evb.dtb' for 20241210092614.3951748-1-wenst at chromium.org:
>
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vpca15: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vpca7: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vsramca15: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vsramca7: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vcore: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vgpu: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vdrm: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: buck_vio18: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vtcxo: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_va28: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vio28: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vusb: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vcama: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vmc: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vmch: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vemc3v3: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp1: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp2: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp3: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp4: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp5: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vgp6: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#
> arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: regulators: ldo_vibr: Unevaluated properties are not allowed ('regulator-compatible' was unexpected)
>         from schema $id: http://devicetree.org/schemas/regulator/mediatek,mt6397-regulator.yaml#

Ack. I already prepared another series to address these.

ChenYu


From wenst at chromium.org  Tue Dec 10 21:24:18 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:24:18 +0800
Subject: [PATCH 0/8] arm64: dts: mediatek: Drop regulator-compatible property
Message-ID: <20241211052427.4178367-1-wenst@chromium.org>

Hi folks,

This series drops usage of the long deprecated "regulator-compatible"
property from MediaTek device tree files. The property was introduced
in 2012, and then subsequently deprecated after two months. It was
never carried over during the binding YAML conversion.

Drop the property from the MT6315 regulator binding, and all MediaTek
device tree files. IMO it should never have been used to begin with.
This also gets rid of any validation errors [1] related to them.

Please have a look.


Thanks
ChenYu

[1] https://lore.kernel.org/all/173386568696.497617.3727087837255802552.robh at kernel.org/

Chen-Yu Tsai (8):
  regulator: dt-bindings: mt6315: Drop regulator-compatible property
  arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property
  arm64: dts: mediatek: mt8173-elm: Drop regulator-compatible property
  arm64: dts: mediatek: mt8192-asurada: Drop regulator-compatible
    property
  arm64: dts: mediatek: mt8195-cherry: Drop regulator-compatible
    property
  arm64: dts: mediatek: mt8195-demo: Drop regulator-compatible property
  arm64: dts: medaitek: mt8395-nio-12l: Drop regulator-compatible
    property
  arm64: dts: mediatek: mt8395-genio-1200-evk: Drop regulator-compatible
    property

 .../bindings/regulator/mt6315-regulator.yaml  |  6 -----
 arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi  | 23 -------------------
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts   | 23 -------------------
 .../boot/dts/mediatek/mt8192-asurada.dtsi     |  3 ---
 .../boot/dts/mediatek/mt8195-cherry.dtsi      |  2 --
 arch/arm64/boot/dts/mediatek/mt8195-demo.dts  |  9 --------
 .../dts/mediatek/mt8395-genio-1200-evk.dts    |  2 --
 .../dts/mediatek/mt8395-radxa-nio-12l.dts     |  2 --
 8 files changed, 70 deletions(-)

-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Tue Dec 10 21:24:19 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:24:19 +0800
Subject: [PATCH 1/8] regulator: dt-bindings: mt6315: Drop regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <20241211052427.4178367-2-wenst@chromium.org>

The "regulator-compatible" property has been deprecated since 2012 in
commit 13511def87b9 ("regulator: deprecate regulator-compatible DT
property"), which is so old it's not even mentioned in the converted
regulator bindings YAML file. It should not have been used for new
submissions such as the MT6315.

Drop the property from the MT6315 regulator binding and its examples.

Fixes: 977fb5b58469 ("regulator: document binding for MT6315 regulator")
Fixes: 6d435a94ba5b ("regulator: mt6315: Enforce regulator-compatible, not name")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 .../devicetree/bindings/regulator/mt6315-regulator.yaml     | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml
index cd4aa27218a1..fa6743bb269d 100644
--- a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml
@@ -35,10 +35,6 @@ properties:
         $ref: regulator.yaml#
         unevaluatedProperties: false
 
-        properties:
-          regulator-compatible:
-            pattern: "^vbuck[1-4]$"
-
     additionalProperties: false
 
 required:
@@ -56,7 +52,6 @@ examples:
 
       regulators {
         vbuck1 {
-          regulator-compatible = "vbuck1";
           regulator-min-microvolt = <300000>;
           regulator-max-microvolt = <1193750>;
           regulator-enable-ramp-delay = <256>;
@@ -64,7 +59,6 @@ examples:
         };
 
         vbuck3 {
-          regulator-compatible = "vbuck3";
           regulator-min-microvolt = <300000>;
           regulator-max-microvolt = <1193750>;
           regulator-enable-ramp-delay = <256>;
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Tue Dec 10 21:24:20 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:24:20 +0800
Subject: [PATCH 2/8] arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <20241211052427.4178367-3-wenst@chromium.org>

The "regulator-compatible" property has been deprecated since 2012 in
commit 13511def87b9 ("regulator: deprecate regulator-compatible DT
property"), which is so old it's not even mentioned in the converted
regulator bindings YAML file. It is also not listed in the MT6397
regulator bindings. Having them present produces a whole bunch of
validation errors:

    Unevaluated properties are not allowed ('regulator-compatible' was unexpected)

Drop the "regulator-compatible" property from the board dts. The
property values are the same as the node name, so everything should
continue to work.

Fixes: 16ea61fc5614 ("arm64: dts: mt8173-evb: Add PMIC support")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 23 ---------------------
 1 file changed, 23 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index bb4671c18e3b..511c16cb1d59 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -311,7 +311,6 @@ mt6397regulator: mt6397regulator {
 			compatible = "mediatek,mt6397-regulator";
 
 			mt6397_vpca15_reg: buck_vpca15 {
-				regulator-compatible = "buck_vpca15";
 				regulator-name = "vpca15";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -320,7 +319,6 @@ mt6397_vpca15_reg: buck_vpca15 {
 			};
 
 			mt6397_vpca7_reg: buck_vpca7 {
-				regulator-compatible = "buck_vpca7";
 				regulator-name = "vpca7";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -329,7 +327,6 @@ mt6397_vpca7_reg: buck_vpca7 {
 			};
 
 			mt6397_vsramca15_reg: buck_vsramca15 {
-				regulator-compatible = "buck_vsramca15";
 				regulator-name = "vsramca15";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -338,7 +335,6 @@ mt6397_vsramca15_reg: buck_vsramca15 {
 			};
 
 			mt6397_vsramca7_reg: buck_vsramca7 {
-				regulator-compatible = "buck_vsramca7";
 				regulator-name = "vsramca7";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -347,7 +343,6 @@ mt6397_vsramca7_reg: buck_vsramca7 {
 			};
 
 			mt6397_vcore_reg: buck_vcore {
-				regulator-compatible = "buck_vcore";
 				regulator-name = "vcore";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -356,7 +351,6 @@ mt6397_vcore_reg: buck_vcore {
 			};
 
 			mt6397_vgpu_reg: buck_vgpu {
-				regulator-compatible = "buck_vgpu";
 				regulator-name = "vgpu";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -365,7 +359,6 @@ mt6397_vgpu_reg: buck_vgpu {
 			};
 
 			mt6397_vdrm_reg: buck_vdrm {
-				regulator-compatible = "buck_vdrm";
 				regulator-name = "vdrm";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <1400000>;
@@ -374,7 +367,6 @@ mt6397_vdrm_reg: buck_vdrm {
 			};
 
 			mt6397_vio18_reg: buck_vio18 {
-				regulator-compatible = "buck_vio18";
 				regulator-name = "vio18";
 				regulator-min-microvolt = <1620000>;
 				regulator-max-microvolt = <1980000>;
@@ -383,19 +375,16 @@ mt6397_vio18_reg: buck_vio18 {
 			};
 
 			mt6397_vtcxo_reg: ldo_vtcxo {
-				regulator-compatible = "ldo_vtcxo";
 				regulator-name = "vtcxo";
 				regulator-always-on;
 			};
 
 			mt6397_va28_reg: ldo_va28 {
-				regulator-compatible = "ldo_va28";
 				regulator-name = "va28";
 				regulator-always-on;
 			};
 
 			mt6397_vcama_reg: ldo_vcama {
-				regulator-compatible = "ldo_vcama";
 				regulator-name = "vcama";
 				regulator-min-microvolt = <1500000>;
 				regulator-max-microvolt = <2800000>;
@@ -403,18 +392,15 @@ mt6397_vcama_reg: ldo_vcama {
 			};
 
 			mt6397_vio28_reg: ldo_vio28 {
-				regulator-compatible = "ldo_vio28";
 				regulator-name = "vio28";
 				regulator-always-on;
 			};
 
 			mt6397_vusb_reg: ldo_vusb {
-				regulator-compatible = "ldo_vusb";
 				regulator-name = "vusb";
 			};
 
 			mt6397_vmc_reg: ldo_vmc {
-				regulator-compatible = "ldo_vmc";
 				regulator-name = "vmc";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3300000>;
@@ -422,7 +408,6 @@ mt6397_vmc_reg: ldo_vmc {
 			};
 
 			mt6397_vmch_reg: ldo_vmch {
-				regulator-compatible = "ldo_vmch";
 				regulator-name = "vmch";
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3300000>;
@@ -430,7 +415,6 @@ mt6397_vmch_reg: ldo_vmch {
 			};
 
 			mt6397_vemc_3v3_reg: ldo_vemc3v3 {
-				regulator-compatible = "ldo_vemc3v3";
 				regulator-name = "vemc_3v3";
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3300000>;
@@ -438,7 +422,6 @@ mt6397_vemc_3v3_reg: ldo_vemc3v3 {
 			};
 
 			mt6397_vgp1_reg: ldo_vgp1 {
-				regulator-compatible = "ldo_vgp1";
 				regulator-name = "vcamd";
 				regulator-min-microvolt = <1220000>;
 				regulator-max-microvolt = <3300000>;
@@ -446,7 +429,6 @@ mt6397_vgp1_reg: ldo_vgp1 {
 			};
 
 			mt6397_vgp2_reg: ldo_vgp2 {
-				regulator-compatible = "ldo_vgp2";
 				regulator-name = "vcamio";
 				regulator-min-microvolt = <1000000>;
 				regulator-max-microvolt = <3300000>;
@@ -454,7 +436,6 @@ mt6397_vgp2_reg: ldo_vgp2 {
 			};
 
 			mt6397_vgp3_reg: ldo_vgp3 {
-				regulator-compatible = "ldo_vgp3";
 				regulator-name = "vcamaf";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3300000>;
@@ -462,7 +443,6 @@ mt6397_vgp3_reg: ldo_vgp3 {
 			};
 
 			mt6397_vgp4_reg: ldo_vgp4 {
-				regulator-compatible = "ldo_vgp4";
 				regulator-name = "vgp4";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3300000>;
@@ -470,7 +450,6 @@ mt6397_vgp4_reg: ldo_vgp4 {
 			};
 
 			mt6397_vgp5_reg: ldo_vgp5 {
-				regulator-compatible = "ldo_vgp5";
 				regulator-name = "vgp5";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3000000>;
@@ -478,7 +457,6 @@ mt6397_vgp5_reg: ldo_vgp5 {
 			};
 
 			mt6397_vgp6_reg: ldo_vgp6 {
-				regulator-compatible = "ldo_vgp6";
 				regulator-name = "vgp6";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3300000>;
@@ -486,7 +464,6 @@ mt6397_vgp6_reg: ldo_vgp6 {
 			};
 
 			mt6397_vibr_reg: ldo_vibr {
-				regulator-compatible = "ldo_vibr";
 				regulator-name = "vibr";
 				regulator-min-microvolt = <1300000>;
 				regulator-max-microvolt = <3300000>;
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Tue Dec 10 21:24:21 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:24:21 +0800
Subject: [PATCH 3/8] arm64: dts: mediatek: mt8173-elm: Drop regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <20241211052427.4178367-4-wenst@chromium.org>

The "regulator-compatible" property has been deprecated since 2012 in
commit 13511def87b9 ("regulator: deprecate regulator-compatible DT
property"), which is so old it's not even mentioned in the converted
regulator bindings YAML file. It is also not listed in the MT6397
regulator bindings. Having them present produces a whole bunch of
validation errors:

    Unevaluated properties are not allowed ('regulator-compatible' was unexpected)

Drop the "regulator-compatible" property from the board dts. The
property values are the same as the node name, so everything should
continue to work.

Fixes: 689b937bedde ("arm64: dts: mediatek: add mt8173 elm and hana board")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 23 --------------------
 1 file changed, 23 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
index eee64461421f..b91072f4723f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
@@ -946,7 +946,6 @@ regulator: mt6397regulator {
 			compatible = "mediatek,mt6397-regulator";
 
 			mt6397_vpca15_reg: buck_vpca15 {
-				regulator-compatible = "buck_vpca15";
 				regulator-name = "vpca15";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -956,7 +955,6 @@ mt6397_vpca15_reg: buck_vpca15 {
 			};
 
 			mt6397_vpca7_reg: buck_vpca7 {
-				regulator-compatible = "buck_vpca7";
 				regulator-name = "vpca7";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -966,7 +964,6 @@ mt6397_vpca7_reg: buck_vpca7 {
 			};
 
 			mt6397_vsramca15_reg: buck_vsramca15 {
-				regulator-compatible = "buck_vsramca15";
 				regulator-name = "vsramca15";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -975,7 +972,6 @@ mt6397_vsramca15_reg: buck_vsramca15 {
 			};
 
 			mt6397_vsramca7_reg: buck_vsramca7 {
-				regulator-compatible = "buck_vsramca7";
 				regulator-name = "vsramca7";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -984,7 +980,6 @@ mt6397_vsramca7_reg: buck_vsramca7 {
 			};
 
 			mt6397_vcore_reg: buck_vcore {
-				regulator-compatible = "buck_vcore";
 				regulator-name = "vcore";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -993,7 +988,6 @@ mt6397_vcore_reg: buck_vcore {
 			};
 
 			mt6397_vgpu_reg: buck_vgpu {
-				regulator-compatible = "buck_vgpu";
 				regulator-name = "vgpu";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -1002,7 +996,6 @@ mt6397_vgpu_reg: buck_vgpu {
 			};
 
 			mt6397_vdrm_reg: buck_vdrm {
-				regulator-compatible = "buck_vdrm";
 				regulator-name = "vdrm";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <1400000>;
@@ -1011,7 +1004,6 @@ mt6397_vdrm_reg: buck_vdrm {
 			};
 
 			mt6397_vio18_reg: buck_vio18 {
-				regulator-compatible = "buck_vio18";
 				regulator-name = "vio18";
 				regulator-min-microvolt = <1620000>;
 				regulator-max-microvolt = <1980000>;
@@ -1020,18 +1012,15 @@ mt6397_vio18_reg: buck_vio18 {
 			};
 
 			mt6397_vtcxo_reg: ldo_vtcxo {
-				regulator-compatible = "ldo_vtcxo";
 				regulator-name = "vtcxo";
 				regulator-always-on;
 			};
 
 			mt6397_va28_reg: ldo_va28 {
-				regulator-compatible = "ldo_va28";
 				regulator-name = "va28";
 			};
 
 			mt6397_vcama_reg: ldo_vcama {
-				regulator-compatible = "ldo_vcama";
 				regulator-name = "vcama";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
@@ -1039,18 +1028,15 @@ mt6397_vcama_reg: ldo_vcama {
 			};
 
 			mt6397_vio28_reg: ldo_vio28 {
-				regulator-compatible = "ldo_vio28";
 				regulator-name = "vio28";
 				regulator-always-on;
 			};
 
 			mt6397_vusb_reg: ldo_vusb {
-				regulator-compatible = "ldo_vusb";
 				regulator-name = "vusb";
 			};
 
 			mt6397_vmc_reg: ldo_vmc {
-				regulator-compatible = "ldo_vmc";
 				regulator-name = "vmc";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3300000>;
@@ -1058,7 +1044,6 @@ mt6397_vmc_reg: ldo_vmc {
 			};
 
 			mt6397_vmch_reg: ldo_vmch {
-				regulator-compatible = "ldo_vmch";
 				regulator-name = "vmch";
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3300000>;
@@ -1066,7 +1051,6 @@ mt6397_vmch_reg: ldo_vmch {
 			};
 
 			mt6397_vemc_3v3_reg: ldo_vemc3v3 {
-				regulator-compatible = "ldo_vemc3v3";
 				regulator-name = "vemc_3v3";
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3300000>;
@@ -1074,7 +1058,6 @@ mt6397_vemc_3v3_reg: ldo_vemc3v3 {
 			};
 
 			mt6397_vgp1_reg: ldo_vgp1 {
-				regulator-compatible = "ldo_vgp1";
 				regulator-name = "vcamd";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
@@ -1082,7 +1065,6 @@ mt6397_vgp1_reg: ldo_vgp1 {
 			};
 
 			mt6397_vgp2_reg: ldo_vgp2 {
-				regulator-compatible = "ldo_vgp2";
 				regulator-name = "vcamio";
 				regulator-min-microvolt = <3300000>;
 				regulator-max-microvolt = <3300000>;
@@ -1090,7 +1072,6 @@ mt6397_vgp2_reg: ldo_vgp2 {
 			};
 
 			mt6397_vgp3_reg: ldo_vgp3 {
-				regulator-compatible = "ldo_vgp3";
 				regulator-name = "vcamaf";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
@@ -1098,7 +1079,6 @@ mt6397_vgp3_reg: ldo_vgp3 {
 			};
 
 			mt6397_vgp4_reg: ldo_vgp4 {
-				regulator-compatible = "ldo_vgp4";
 				regulator-name = "vgp4";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3300000>;
@@ -1106,7 +1086,6 @@ mt6397_vgp4_reg: ldo_vgp4 {
 			};
 
 			mt6397_vgp5_reg: ldo_vgp5 {
-				regulator-compatible = "ldo_vgp5";
 				regulator-name = "vgp5";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3000000>;
@@ -1114,7 +1093,6 @@ mt6397_vgp5_reg: ldo_vgp5 {
 			};
 
 			mt6397_vgp6_reg: ldo_vgp6 {
-				regulator-compatible = "ldo_vgp6";
 				regulator-name = "vgp6";
 				regulator-min-microvolt = <3300000>;
 				regulator-max-microvolt = <3300000>;
@@ -1123,7 +1101,6 @@ mt6397_vgp6_reg: ldo_vgp6 {
 			};
 
 			mt6397_vibr_reg: ldo_vibr {
-				regulator-compatible = "ldo_vibr";
 				regulator-name = "vibr";
 				regulator-min-microvolt = <1300000>;
 				regulator-max-microvolt = <3300000>;
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Tue Dec 10 21:24:22 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:24:22 +0800
Subject: [PATCH 4/8] arm64: dts: mediatek: mt8192-asurada: Drop regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <20241211052427.4178367-5-wenst@chromium.org>

The "regulator-compatible" property has been deprecated since 2012 in
commit 13511def87b9 ("regulator: deprecate regulator-compatible DT
property"), which is so old it's not even mentioned in the converted
regulator bindings YAML file. It should not have been used for new
submissions such as the MT6315.

Drop the "regulator-compatible" property from the board dts. The
property values are the same as the node name, so everything should
continue to work.

Fixes: 3183cb62b033 ("arm64: dts: mediatek: asurada: Add SPMI regulators")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index 741af6a7f197..516fba9b3c6d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -1580,7 +1580,6 @@ mt6315_6: pmic at 6 {
 
 		regulators {
 			mt6315_6_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vbcpu";
 				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <1193750>;
@@ -1590,7 +1589,6 @@ mt6315_6_vbuck1: vbuck1 {
 			};
 
 			mt6315_6_vbuck3: vbuck3 {
-				regulator-compatible = "vbuck3";
 				regulator-name = "Vlcpu";
 				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <1193750>;
@@ -1607,7 +1605,6 @@ mt6315_7: pmic at 7 {
 
 		regulators {
 			mt6315_7_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vgpu";
 				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <800000>;
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Tue Dec 10 21:24:23 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:24:23 +0800
Subject: [PATCH 5/8] arm64: dts: mediatek: mt8195-cherry: Drop regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <20241211052427.4178367-6-wenst@chromium.org>

The "regulator-compatible" property has been deprecated since 2012 in
commit 13511def87b9 ("regulator: deprecate regulator-compatible DT
property"), which is so old it's not even mentioned in the converted
regulator bindings YAML file. It should not have been used for new
submissions such as the MT6315.

Drop the "regulator-compatible" property from the board dts. The
property values are the same as the node name, so everything should
continue to work.

Fixes: 260c04d425eb ("arm64: dts: mediatek: cherry: Enable MT6315 regulators on SPMI bus")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index 2c7b2223ee76..5056e07399e2 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -1285,7 +1285,6 @@ mt6315 at 6 {
 
 		regulators {
 			mt6315_6_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vbcpu";
 				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <1193750>;
@@ -1303,7 +1302,6 @@ mt6315 at 7 {
 
 		regulators {
 			mt6315_7_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vgpu";
 				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <1193750>;
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Tue Dec 10 21:24:24 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:24:24 +0800
Subject: [PATCH 6/8] arm64: dts: mediatek: mt8195-demo: Drop regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <20241211052427.4178367-7-wenst@chromium.org>

The "regulator-compatible" property has been deprecated since 2012 in
commit 13511def87b9 ("regulator: deprecate regulator-compatible DT
property"), which is so old it's not even mentioned in the converted
regulator bindings YAML file. It is also not listed in the MT6360
regulator and charger bindings.

Drop the "regulator-compatible" property from the board dts. The MT6360
bindings actually require the lowercase name, so with the property
present the regulators were likely not actually working.

Fixes: 6147314aeedc ("arm64: dts: mediatek: Add device-tree for MT8195 Demo board")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8195-demo.dts | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
index 31d424b8fc7c..bfb75296795c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
@@ -137,7 +137,6 @@ charger {
 			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>;
@@ -149,7 +148,6 @@ regulator {
 			LDO_VIN3-supply = <&mt6360_buck2>;
 
 			mt6360_buck1: buck1 {
-				regulator-compatible = "BUCK1";
 				regulator-name = "mt6360,buck1";
 				regulator-min-microvolt = <300000>;
 				regulator-max-microvolt = <1300000>;
@@ -160,7 +158,6 @@ MT6360_OPMODE_LP
 			};
 
 			mt6360_buck2: buck2 {
-				regulator-compatible = "BUCK2";
 				regulator-name = "mt6360,buck2";
 				regulator-min-microvolt = <300000>;
 				regulator-max-microvolt = <1300000>;
@@ -171,7 +168,6 @@ MT6360_OPMODE_LP
 			};
 
 			mt6360_ldo1: ldo1 {
-				regulator-compatible = "LDO1";
 				regulator-name = "mt6360,ldo1";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3600000>;
@@ -180,7 +176,6 @@ mt6360_ldo1: ldo1 {
 			};
 
 			mt6360_ldo2: ldo2 {
-				regulator-compatible = "LDO2";
 				regulator-name = "mt6360,ldo2";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3600000>;
@@ -189,7 +184,6 @@ mt6360_ldo2: ldo2 {
 			};
 
 			mt6360_ldo3: ldo3 {
-				regulator-compatible = "LDO3";
 				regulator-name = "mt6360,ldo3";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3600000>;
@@ -198,7 +192,6 @@ mt6360_ldo3: ldo3 {
 			};
 
 			mt6360_ldo5: ldo5 {
-				regulator-compatible = "LDO5";
 				regulator-name = "mt6360,ldo5";
 				regulator-min-microvolt = <2700000>;
 				regulator-max-microvolt = <3600000>;
@@ -207,7 +200,6 @@ mt6360_ldo5: ldo5 {
 			};
 
 			mt6360_ldo6: ldo6 {
-				regulator-compatible = "LDO6";
 				regulator-name = "mt6360,ldo6";
 				regulator-min-microvolt = <500000>;
 				regulator-max-microvolt = <2100000>;
@@ -216,7 +208,6 @@ mt6360_ldo6: ldo6 {
 			};
 
 			mt6360_ldo7: ldo7 {
-				regulator-compatible = "LDO7";
 				regulator-name = "mt6360,ldo7";
 				regulator-min-microvolt = <500000>;
 				regulator-max-microvolt = <2100000>;
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Tue Dec 10 21:24:25 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:24:25 +0800
Subject: [PATCH 7/8] arm64: dts: medaitek: mt8395-nio-12l: Drop regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <20241211052427.4178367-8-wenst@chromium.org>

The "regulator-compatible" property has been deprecated since 2012 in
commit 13511def87b9 ("regulator: deprecate regulator-compatible DT
property"), which is so old it's not even mentioned in the converted
regulator bindings YAML file. It should not have been used for new
submissions such as the MT6315.

Drop the "regulator-compatible" property from the board dts. The
property values are the same as the node name, so everything should
continue to work.

Fixes: 96564b1e2ea4 ("arm64: dts: mediatek: Introduce the MT8395 Radxa NIO 12L board")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts b/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts
index 14ec970c4e49..41dc34837b02 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts
@@ -812,7 +812,6 @@ mt6315_6: pmic at 6 {
 
 		regulators {
 			mt6315_6_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vbcpu";
 				regulator-min-microvolt = <300000>;
 				regulator-max-microvolt = <1193750>;
@@ -829,7 +828,6 @@ mt6315_7: pmic at 7 {
 
 		regulators {
 			mt6315_7_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vgpu";
 				regulator-min-microvolt = <300000>;
 				regulator-max-microvolt = <1193750>;
-- 
2.47.0.338.g60cca15819-goog



From wenst at chromium.org  Tue Dec 10 21:24:26 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 13:24:26 +0800
Subject: [PATCH 8/8] arm64: dts: mediatek: mt8395-genio-1200-evk: Drop regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <20241211052427.4178367-9-wenst@chromium.org>

The "regulator-compatible" property has been deprecated since 2012 in
commit 13511def87b9 ("regulator: deprecate regulator-compatible DT
property"), which is so old it's not even mentioned in the converted
regulator bindings YAML file. It should not have been used for new
submissions such as the MT6315.

Drop the "regulator-compatible" property from the board dts. The
property values are the same as the node name, so everything should
continue to work.

Fixes: f2b543a191b6 ("arm64: dts: mediatek: add device-tree for Genio 1200 EVK board")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts | 2 --
 1 file changed, 2 deletions(-)

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 5f16fb820580..5950194c9ccb 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
@@ -835,7 +835,6 @@ mt6315_6: pmic at 6 {
 
 		regulators {
 			mt6315_6_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vbcpu";
 				regulator-min-microvolt = <300000>;
 				regulator-max-microvolt = <1193750>;
@@ -852,7 +851,6 @@ mt6315_7: pmic at 7 {
 
 		regulators {
 			mt6315_7_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vgpu";
 				regulator-min-microvolt = <546000>;
 				regulator-max-microvolt = <787000>;
-- 
2.47.0.338.g60cca15819-goog



From manivannan.sadhasivam at linaro.org  Tue Dec 10 21:31:04 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 11 Dec 2024 11:01:04 +0530
Subject: [PATCH] PCI: dw-rockchip: Enumerate endpoints based on
 dll_link_up irq in the combined sys irq
In-Reply-To: <20241127145041.3531400-2-cassel@kernel.org>
References: <20241127145041.3531400-2-cassel@kernel.org>
Message-ID: <20241211053104.7sgo5bmmjnolwvhh@thinkpad>

On Wed, Nov 27, 2024 at 03:50:42PM +0100, Niklas Cassel wrote:
> Most boards using the pcie-dw-rockchip PCIe controller lack standard
> hotplug support.
> 
> Thus, when an endpoint is attached to the SoC, users have to rescan the bus
> manually to enumerate the device. This can be avoided by using the
> 'dll_link_up' interrupt in the combined system interrupt 'sys'.
> 
> Once the 'dll_link_up' irq is received, the bus underneath the host bridge
> is scanned to enumerate PCIe endpoint devices.
> 
> This commit implements the same functionality that was implemented in the
> DWC based pcie-qcom driver in commit 4581403f6792 ("PCI: qcom: Enumerate
> endpoints based on Link up event in 'global_irq' interrupt").
> 
> The Root Complex specific device tree binding for pcie-dw-rockchip already
> has the 'sys' interrupt marked as required, so there is no need to update
> the device tree binding. This also means that we can request the 'sys' IRQ
> unconditionally.
> 
> Signed-off-by: Niklas Cassel <cassel at kernel.org>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

- Mani

> ---
>  drivers/pci/controller/dwc/pcie-dw-rockchip.c | 62 +++++++++++++++++--
>  1 file changed, 58 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 1170e1107508..ce4b511bff9b 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -389,6 +389,34 @@ static const struct dw_pcie_ops dw_pcie_ops = {
>  	.stop_link = rockchip_pcie_stop_link,
>  };
>  
> +static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
> +{
> +	struct rockchip_pcie *rockchip = arg;
> +	struct dw_pcie *pci = &rockchip->pci;
> +	struct dw_pcie_rp *pp = &pci->pp;
> +	struct device *dev = pci->dev;
> +	u32 reg, val;
> +
> +	reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
> +	rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
> +
> +	dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
> +	dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm(rockchip));
> +
> +	if (reg & PCIE_RDLH_LINK_UP_CHGED) {
> +		val = rockchip_pcie_get_ltssm(rockchip);
> +		if ((val & PCIE_LINKUP) == PCIE_LINKUP) {
> +			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> +			/* Rescan the bus to enumerate endpoint devices */
> +			pci_lock_rescan_remove();
> +			pci_rescan_bus(pp->bridge->bus);
> +			pci_unlock_rescan_remove();
> +		}
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
>  {
>  	struct rockchip_pcie *rockchip = arg;
> @@ -418,14 +446,31 @@ static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
>  	return IRQ_HANDLED;
>  }
>  
> -static int rockchip_pcie_configure_rc(struct rockchip_pcie *rockchip)
> +static int rockchip_pcie_configure_rc(struct platform_device *pdev,
> +				      struct rockchip_pcie *rockchip)
>  {
> +	struct device *dev = &pdev->dev;
>  	struct dw_pcie_rp *pp;
> +	int irq, ret;
>  	u32 val;
>  
>  	if (!IS_ENABLED(CONFIG_PCIE_ROCKCHIP_DW_HOST))
>  		return -ENODEV;
>  
> +	irq = platform_get_irq_byname(pdev, "sys");
> +	if (irq < 0) {
> +		dev_err(dev, "missing sys IRQ resource\n");
> +		return irq;
> +	}
> +
> +	ret = devm_request_threaded_irq(dev, irq, NULL,
> +					rockchip_pcie_rc_sys_irq_thread,
> +					IRQF_ONESHOT, "pcie-sys-rc", rockchip);
> +	if (ret) {
> +		dev_err(dev, "failed to request PCIe sys IRQ\n");
> +		return ret;
> +	}
> +
>  	/* LTSSM enable control mode */
>  	val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE);
>  	rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
> @@ -436,7 +481,16 @@ static int rockchip_pcie_configure_rc(struct rockchip_pcie *rockchip)
>  	pp = &rockchip->pci.pp;
>  	pp->ops = &rockchip_pcie_host_ops;
>  
> -	return dw_pcie_host_init(pp);
> +	ret = dw_pcie_host_init(pp);
> +	if (ret) {
> +		dev_err(dev, "failed to initialize host\n");
> +		return ret;
> +	}
> +
> +	/* unmask DLL up/down indicator */
> +	rockchip_pcie_writel_apb(rockchip, 0x20000, PCIE_CLIENT_INTR_MASK_MISC);
> +
> +	return ret;
>  }
>  
>  static int rockchip_pcie_configure_ep(struct platform_device *pdev,
> @@ -457,7 +511,7 @@ static int rockchip_pcie_configure_ep(struct platform_device *pdev,
>  
>  	ret = devm_request_threaded_irq(dev, irq, NULL,
>  					rockchip_pcie_ep_sys_irq_thread,
> -					IRQF_ONESHOT, "pcie-sys", rockchip);
> +					IRQF_ONESHOT, "pcie-sys-ep", rockchip);
>  	if (ret) {
>  		dev_err(dev, "failed to request PCIe sys IRQ\n");
>  		return ret;
> @@ -553,7 +607,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
>  
>  	switch (data->mode) {
>  	case DW_PCIE_RC_TYPE:
> -		ret = rockchip_pcie_configure_rc(rockchip);
> +		ret = rockchip_pcie_configure_rc(pdev, rockchip);
>  		if (ret)
>  			goto deinit_clk;
>  		break;
> -- 
> 2.47.0
> 

-- 
????????? ????????


From xu.yang_2 at nxp.com  Tue Dec 10 21:35:16 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 11 Dec 2024 13:35:16 +0800
Subject: [PATCH v2] perf: imx9_perf: Introduce AXI filter version to
 refactor the driver and better extension
In-Reply-To: <20241210133732.GA15607@willie-the-truck>
References: <20241125104338.2433339-1-xu.yang_2@nxp.com>
 <20241209154419.GB12428@willie-the-truck>
 <20241210020212.yz3xowvdk27zmgsl@hippo>
 <20241210133732.GA15607@willie-the-truck>
Message-ID: <20241211053455.z5zzawfacpyv2dlt@hippo>

On Tue, Dec 10, 2024 at 01:37:32PM +0000, Will Deacon wrote:
> On Tue, Dec 10, 2024 at 10:02:12AM +0800, Xu Yang wrote:
> > On Mon, Dec 09, 2024 at 03:44:20PM +0000, Will Deacon wrote:
> > > On Mon, Nov 25, 2024 at 06:43:38PM +0800, Xu Yang wrote:
> > > > The imx93 is the first supported DDR PMU that supports read transaction,
> > > > write transaction and read beats events which corresponding respecitively
> > > > to counter 2, 3 and 4.
> > > > 
> > > > However, transaction-based AXI match has low accuracy when get total bits
> > > > compared to beats-based. And imx93 doesn't assign AXI_ID to each master.
> > > > So axi filter is not used widely on imx93. This could be regards as AXI
> > > > filter version 1.
> > > > 
> > > > To improve the AXI filter capability, imx95 supports 1 read beats and 3
> > > > write beats event which corresponding respecitively to counter 2-5. imx95
> > > > also detailed AXI_ID allocation so that most of the master could be count
> > > > individually. This could be regards as AXI filter version 2.
> > > > 
> > > > This will introduce AXI filter version to refactor the driver and support
> > > > better extension, such as coming imx943.
> > > > 
> > > > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > > > 
> > > > ---
> > > > Changes in v2:
> > > >  - modify subject
> > > >  - add comments for AXI_FILTER version
> > > >  - type -> filter_ver
> > > > ---
> > > >  drivers/perf/fsl_imx9_ddr_perf.c | 33 ++++++++++++++++++++++++--------
> > > >  1 file changed, 25 insertions(+), 8 deletions(-)
> 
> [...]
> 
> > > > @@ -624,11 +641,11 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
> > > >  	hwc->idx = counter;
> > > >  	hwc->state |= PERF_HES_STOPPED;
> > > >  
> > > > -	if (is_imx93(pmu))
> > > > +	if (axi_filter_v1(pmu))
> > > >  		/* read trans, write trans, read beat */
> > > >  		imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
> > > 
> > > Hmm, doesn't this change mean we now enable this for imx91 as well? My
> > > reading of the commit message is that imx93 was the first chip which
> > > supports this.
> > 
> > Yes, it's enabled for imx91 too. In fact, imx91 is compatible with imx93.
> > They use same configuration for axi filter.
> 
> Ok, but my worry is that the above code looks like userspace now _must_
> provide valid values for the config1 (axi_id) and config2 (axi_mask)
> fields on imx91, whereas before I think they were ignored by the driver.
> 
> In fact, without this change, how were the PMCFGn registers configured
> on imx91? It looks to me like they were left uninitialised...

Before this change, PMCFGn registers are indeed not configured on imx91.
However, they should be configured as imx93. I notice this thing when
make this patch. First thing I tried is to add is_imx91(), then check it
and is_imx93() by "||" operator. However, this way seems not scalable as
more imx9x Soc comes out. Basically, AXI filter version will keep at V2
unless big changes due to new features. However, perf tool need export
correct MetricName via identifier in sysfs. So I made this patch, then
PMCFGn will be configured based on axi filter version rather than pmu
name.

Thanks,
Xu Yang

> 
> Will


From d-gole at ti.com  Tue Dec 10 21:50:52 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Wed, 11 Dec 2024 11:20:52 +0530
Subject: Fwd: ARM64: CPUIdle driver is not select any Idle state other
 then WFI
In-Reply-To: <CAO6a-98cdSvyd7jgAyGNmsC2nxmRSyr3GppxvZU9yHU1xqwz3g@mail.gmail.com>
References: <CAO6a-9_aPLCx2CqecQBGbK78_=+-tT44RepPkrBjpkWSvjj4Tg@mail.gmail.com>
 <CAO6a-98cdSvyd7jgAyGNmsC2nxmRSyr3GppxvZU9yHU1xqwz3g@mail.gmail.com>
Message-ID: <20241211055052.gbxnyqpui3t3zpw5@lcpd911>

Hi Vivek,

On Oct 14, 2024 at 16:06:34 +0530, Vivek yadav wrote:
> ---------- Forwarded message ---------
> From: Vivek yadav <linux.ninja23 at gmail.com>
> Date: Fri, Oct 11, 2024 at 3:14?PM
> Subject: ARM64: CPUIdle driver is not select any Idle state other then WFI
> To: <linux-pm at vger.kernel.org>

+ Kevin, Vignesh and few colleagues at TI who have been working on this as
well.

> 
> 
> Hi @all,
> 
> I am working on one custom SoC. Where I add one CPUIdle state for
> ``arm,cortex-a55`` processor.

Any further luck on this?

I have also been working on something similar[1] but on an A53 core on
TI-K3 AM62x processor.

> 
> idle-states {
>       entry-method = "psci";
>        cpu_ret_l: cpu-retention-l {
>          compatible = "arm,idle-state";
>          arm,psci-suspend-param = <0x00010001>;
>          local-timer-stop;
>          entry-latency-us = <55>;
>           exit-latency-us = <140>;
>           min-residency-us = <780>;
>     };
> };
> 
> I am using ``Menu governor`` with the ``psci_idle driver`` in its original form.
> After booting Linux I find out that the CPUIdle core is never going
> inside the ``cpu-retention`` state.
> To check time spent by CPU in any state. I am using the below command.
> 
> ``cat /sys/devices/system/cpu/cpu*/cpuidle/state*/time``

What I was seeing is in a multi core system (2 or more) all cores don't
enter the idle-state simultaneously. There's something keeping atleast 1
core always busy. However I could definitely see entry into TF-A from 1
core at a time.
I then switched to a single core system to see if we were atall able to
enter TF-A when only 1 core was available for linux, it turned out that
with the "local-timer-stop" property that we have, this is never
possible.

See this chunk in the kernel cpuidle driver:
	if (broadcast && tick_broadcast_enter()) {

When I dug deeper into tick_broadcast_enter it always returns something
non zero and hence in my case it was entering the if block and tried to
find a deepest state. Then the deepest state would always return WFI and
not the idle-state I had added.

What we found out was on our kernel we end up using 

kernel/time/tick-broadcast-hrtimer.c 

This always seems to be keeping atleast 1 CPU busy and prevents idle.
If we remove the local-timer-stop it was helping us, but we still need
to dig into the full impact of what that entails and I am still
interested in finding out how so many other users of similar idle-state
implementation are able to do so without trouble.

Arm64 recommends to use arch_timer instead of external timers. Once we
enter el3, timer interrupts to el1 is blocked and hence it's equivalent
to local-timer-stop, so it does make sense to keep this property, but
then how are others able to enter idle-states for all plugged CPUs at
the same time?

> 
> OUTPUT:
> 0 ===>CPU0 state0 (WFI)
> 0 ===>CPU0 state1 (cpu-retention)
> 
> increasing some time value ===>CPU1 state0 (WFI)
> 0 ===>CPU1 state1 (cpu-retention)
> 
> increasing some time value
> 0
> 
> increasing some time value
> 0
> 
> What am I doing wrong? Why does ``cpu-retention`` state time not increase?
> Any pointer will be helpful.

I had asked a similar qn. on IRC [2], but didn't get much response. I
am still interested in finding out what the right thing to do here is.

[1] https://github.com/DhruvaG2000/v-linux/commit/0fd088d624276a2e72b8dc6660d261ab6d194f4b#diff-34369928f669d14776f8f5bdbe3fc3d75306196a2ac28b1a4d7e17402b9c3995R160
[2] https://libera.irclog.whitequark.org/armlinux/2024-08-23 

-- 
Best regards,
Dhruva Gole
Texas Instruments Incorporated


From manivannan.sadhasivam at linaro.org  Tue Dec 10 22:04:18 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 11 Dec 2024 11:34:18 +0530
Subject: [PATCH 0/2] PCI: Convert the Apple controller to host bridge
 hooks
In-Reply-To: <20241204150145.800408-1-maz@kernel.org>
References: <20241204150145.800408-1-maz@kernel.org>
Message-ID: <20241211060418.gpepptv6wlbv7fwt@thinkpad>

On Wed, Dec 04, 2024 at 03:01:43PM +0000, Marc Zyngier wrote:
> The Apple PCIe controller requires some additional attention when
> enabling an endpoint device, so that the RID gets correctly mapped to
> a SID on its way to the IOMMU.
> 
> So far, we have need relying on a custom bus notifier to perform this
> task, but Frank Li's series [1] is a better approach as it puts the
> complexity in the core code instead of the host controller driver, and
> this series builds on that:
> 
> - allow the new {en,dis}able_device() to be provided via pci_ecam_ops
> 
> - convert the Apple PCIe driver to that infrastructure
> 
> Patches on top of 6.13-rc1, plus Frank's v7 series.
> 
> [1] https://lore.kernel.org/r/20241203-imx95_lut-v7-0-d0cd6293225e at nxp.com
> 

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

- Mani

> Marc Zyngier (2):
>   PCI: host-generic: Allow {en,dis}able_device() to be provided via
>     pci_ecam_ops
>   PCI: apple: Convert to {en,dis}able_device() callbacks
> 
>  drivers/pci/controller/pci-host-common.c |  2 +
>  drivers/pci/controller/pcie-apple.c      | 75 +++++-------------------
>  include/linux/pci-ecam.h                 |  4 ++
>  3 files changed, 21 insertions(+), 60 deletions(-)
> 
> -- 
> 2.39.2
> 

-- 
????????? ????????


From andyshrk at 163.com  Tue Dec 10 22:34:34 2024
From: andyshrk at 163.com (Andy Yan)
Date: Wed, 11 Dec 2024 14:34:34 +0800 (CST)
Subject: [PATCH v5 05/18] drm/rockchip: vop2: Set AXI id for rk3588
In-Reply-To: <5839604.DvuYhMxLoT@trenzalore>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209122943.2781431-9-andyshrk@163.com> <5839604.DvuYhMxLoT@trenzalore>
Message-ID: <2d381563.5e54.193b46d2f30.Coremail.andyshrk@163.com>


Hi Detlev,

At 2024-12-11 02:40:14, "Detlev Casanova" <detlev.casanova at collabora.com> wrote:
>Hi Andy,
>
>On Monday, 9 December 2024 07:29:18 EST Andy Yan wrote:
>> From: Andy Yan <andy.yan at rock-chips.com>
>> 
>> There are two AXI bus in vop2, windows attached on the same bus must
>> have a unique channel YUV and RGB channel ID.
>> 
>> The default IDs will conflict with each other on the rk3588, so they
>> need to be reassigned.
>> 
>> Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
>> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>> Tested-by: Derek Foreman <derek.foreman at collabora.com>
>> 
>> ---
>> 
>> Changes in v5:
>> - Added in V5
>> 
>>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 14 +++++++++++
>>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  9 +++++++
>>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 26 +++++++++++++++++++-
>>  3 files changed, 48 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index
>> dc4edd65bc9e..8b9ca046eeeb 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> @@ -1426,6 +1426,12 @@ static void vop2_plane_atomic_update(struct drm_plane
>> *plane, &fb->format->format,
>>  		afbc_en ? "AFBC" : "", &yrgb_mst);
>> 
>> +	if (vop2->data->soc_id > 3568) {
>
>Shouldn't this be done only for rk3588, as specified in the comments below ? 
>The test we did before showed that it is failing on rk3576 and 3576 is > 3588.

I think this is because you tested before with the patch I gave Derek  without axi id 
assigned for rk3576.
I assigned axi id for rk3576 in this version 18/18?The new ID assignment can adapt to more application scenarios.?,
can you test it with the whole V5 version again?

>
>I suggest
>
>	if (vop2->data->soc_id == 3588) {
>
>Regards,
>Detlev
>
>> +		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data-
>>axi_bus_id);
>> +		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data-
>>axi_yrgb_r_id);
>> +		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data-
>>axi_uv_r_id);
>> +	}
>> +
>>  	if (vop2_cluster_window(win))
>>  		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 
>half_block_en);
>> 
>> @@ -3354,6 +3360,10 @@ static struct reg_field
>> vop2_cluster_regs[VOP2_WIN_MAX_REG] = { [VOP2_WIN_Y2R_EN] =
>> REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
>>  	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
>>  	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
>> +	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 
>3),
>> +	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
>> +	/* RK3588 only, reserved bit on rk3568*/
>> +	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
>> 
>>  	/* Scale */
>>  	[VOP2_WIN_SCALE_YRGB_X] = 
>REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0,
>> 15), @@ -3446,6 +3456,10 @@ static struct reg_field
>> vop2_esmart_regs[VOP2_WIN_MAX_REG] = { [VOP2_WIN_YMIRROR] =
>> REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
>>  	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 
>29),
>>  	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 
>31, 31),
>> +	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
>> +	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
>> +	/* RK3588 only, reserved register on rk3568 */
>> +	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
>> 
>>  	/* Scale */
>>  	[VOP2_WIN_SCALE_YRGB_X] = 
>REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB,
>> 0, 15), diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>> b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h index
>> 8786c2ba48df..0a3b22e8d14e 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>> @@ -78,6 +78,9 @@ enum vop2_win_regs {
>>  	VOP2_WIN_COLOR_KEY,
>>  	VOP2_WIN_COLOR_KEY_EN,
>>  	VOP2_WIN_DITHER_UP,
>> +	VOP2_WIN_AXI_BUS_ID,
>> +	VOP2_WIN_AXI_YRGB_R_ID,
>> +	VOP2_WIN_AXI_UV_R_ID,
>> 
>>  	/* scale regs */
>>  	VOP2_WIN_SCALE_YRGB_X,
>> @@ -149,6 +152,10 @@ struct vop2_win_data {
>>  	unsigned int layer_sel_id;
>>  	uint64_t feature;
>> 
>> +	uint8_t axi_bus_id;
>> +	uint8_t axi_yrgb_r_id;
>> +	uint8_t axi_uv_r_id;
>> +
>>  	unsigned int max_upscale_factor;
>>  	unsigned int max_downscale_factor;
>>  	const u8 dly[VOP2_DLY_MODE_MAX];
>> @@ -319,6 +326,7 @@ enum dst_factor_mode {
>> 
>>  #define RK3568_CLUSTER_WIN_CTRL0		0x00
>>  #define RK3568_CLUSTER_WIN_CTRL1		0x04
>> +#define RK3568_CLUSTER_WIN_CTRL2		0x08
>>  #define RK3568_CLUSTER_WIN_YRGB_MST		0x10
>>  #define RK3568_CLUSTER_WIN_CBR_MST		0x14
>>  #define RK3568_CLUSTER_WIN_VIR			0x18
>> @@ -341,6 +349,7 @@ enum dst_factor_mode {
>>  /* (E)smart register definition, offset relative to window base */
>>  #define RK3568_SMART_CTRL0			0x00
>>  #define RK3568_SMART_CTRL1			0x04
>> +#define RK3588_SMART_AXI_CTRL			0x08
>>  #define RK3568_SMART_REGION0_CTRL		0x10
>>  #define RK3568_SMART_REGION0_YRGB_MST		0x14
>>  #define RK3568_SMART_REGION0_CBR_MST		0x18
>> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>> b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index
>> f7d3350594fa..37c65138012d 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>> +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>> @@ -395,7 +395,7 @@ static const struct vop2_video_port_data
>> rk3588_vop_video_ports[] = { * AXI1 is a read only bus.
>>   *
>>   * Every window on a AXI bus must assigned two unique
>> - * read id(yrgb_id/uv_id, valid id are 0x1~0xe).
>> + * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe).
>>   *
>>   * AXI0:
>>   * Cluster0/1, Esmart0/1, WriteBack
>> @@ -415,6 +415,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
>> = { .layer_sel_id = 0,
>>  		.supported_rotations = DRM_MODE_ROTATE_90 | 
>DRM_MODE_ROTATE_270 |
>>  				       DRM_MODE_REFLECT_X | 
>DRM_MODE_REFLECT_Y,
>> +		.axi_bus_id = 0,
>> +		.axi_yrgb_r_id = 2,
>> +		.axi_uv_r_id = 3,
>>  		.max_upscale_factor = 4,
>>  		.max_downscale_factor = 4,
>>  		.dly = { 4, 26, 29 },
>> @@ -431,6 +434,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
>> = { .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
>> DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
>>  		.type = DRM_PLANE_TYPE_PRIMARY,
>> +		.axi_bus_id = 0,
>> +		.axi_yrgb_r_id = 6,
>> +		.axi_uv_r_id = 7,
>>  		.max_upscale_factor = 4,
>>  		.max_downscale_factor = 4,
>>  		.dly = { 4, 26, 29 },
>> @@ -446,6 +452,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
>> = { .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
>> DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
>>  		.type = DRM_PLANE_TYPE_PRIMARY,
>> +		.axi_bus_id = 1,
>> +		.axi_yrgb_r_id = 2,
>> +		.axi_uv_r_id = 3,
>>  		.max_upscale_factor = 4,
>>  		.max_downscale_factor = 4,
>>  		.dly = { 4, 26, 29 },
>> @@ -461,6 +470,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
>> = { .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
>> DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
>>  		.type = DRM_PLANE_TYPE_PRIMARY,
>> +		.axi_bus_id = 1,
>> +		.axi_yrgb_r_id = 6,
>> +		.axi_uv_r_id = 7,
>>  		.max_upscale_factor = 4,
>>  		.max_downscale_factor = 4,
>>  		.dly = { 4, 26, 29 },
>> @@ -475,6 +487,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
>> = { .layer_sel_id = 2,
>>  		.supported_rotations = DRM_MODE_REFLECT_Y,
>>  		.type = DRM_PLANE_TYPE_OVERLAY,
>> +		.axi_bus_id = 0,
>> +		.axi_yrgb_r_id = 0x0a,
>> +		.axi_uv_r_id = 0x0b,
>>  		.max_upscale_factor = 8,
>>  		.max_downscale_factor = 8,
>>  		.dly = { 23, 45, 48 },
>> @@ -488,6 +503,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
>> = { .layer_sel_id = 3,
>>  		.supported_rotations = DRM_MODE_REFLECT_Y,
>>  		.type = DRM_PLANE_TYPE_OVERLAY,
>> +		.axi_bus_id = 0,
>> +		.axi_yrgb_r_id = 0x0c,
>> +		.axi_uv_r_id = 0x01,
>>  		.max_upscale_factor = 8,
>>  		.max_downscale_factor = 8,
>>  		.dly = { 23, 45, 48 },
>> @@ -501,6 +519,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
>> = { .layer_sel_id = 6,
>>  		.supported_rotations = DRM_MODE_REFLECT_Y,
>>  		.type = DRM_PLANE_TYPE_OVERLAY,
>> +		.axi_bus_id = 1,
>> +		.axi_yrgb_r_id = 0x0a,
>> +		.axi_uv_r_id = 0x0b,
>>  		.max_upscale_factor = 8,
>>  		.max_downscale_factor = 8,
>>  		.dly = { 23, 45, 48 },
>> @@ -514,6 +535,9 @@ static const struct vop2_win_data rk3588_vop_win_data[]
>> = { .layer_sel_id = 7,
>>  		.supported_rotations = DRM_MODE_REFLECT_Y,
>>  		.type = DRM_PLANE_TYPE_OVERLAY,
>> +		.axi_bus_id = 1,
>> +		.axi_yrgb_r_id = 0x0c,
>> +		.axi_uv_r_id = 0x0d,
>>  		.max_upscale_factor = 8,
>>  		.max_downscale_factor = 8,
>>  		.dly = { 23, 45, 48 },
>
>
>
>

From devnull+xianwei.zhao.amlogic.com at kernel.org  Tue Dec 10 22:47:49 2024
From: devnull+xianwei.zhao.amlogic.com at kernel.org (Xianwei Zhao via B4 Relay)
Date: Wed, 11 Dec 2024 14:47:49 +0800
Subject: [PATCH RFC 1/3] dt-bindings: pinctrl: Add support for Amlogic SoCs
In-Reply-To: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
References: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
Message-ID: <20241211-amlogic-pinctrl-v1-1-410727335119@amlogic.com>

From: Xianwei Zhao <xianwei.zhao at amlogic.com>

Add the dt-bindings for Amlogic pin controller, and add a new
dt-binding header file which document the GPIO bank names and
alternative func value of all Amlogic subsequent SoCs.

Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
---
 .../bindings/pinctrl/amlogic,pinctrl.yaml          | 150 +++++++++++++++++++++
 include/dt-bindings/pinctrl/amlogic,pinctrl.h      |  68 ++++++++++
 2 files changed, 218 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/amlogic,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/amlogic,pinctrl.yaml
new file mode 100644
index 000000000000..b0c2ae585d7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/amlogic,pinctrl.yaml
@@ -0,0 +1,150 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/amlogic,pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic pinmux controller
+
+maintainers:
+  - Xianwei Zhao <xianwei.zhao at amlogic.com>
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+properties:
+  compatible:
+    const: amlogic,pinctrl
+
+  reg:
+    minItems: 2
+
+  reg-names:
+    items:
+      - const: mux
+      - const: gpio
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#address-cells"
+  - "#size-cells"
+
+patternProperties:
+  "^gpio[a-z]":
+    type: object
+
+    properties:
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      bank-name:
+        $ref: /schemas/types.yaml#/definitions/string
+
+      npins:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 1
+        maximum: 32
+
+      bank-index:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 0
+        maximum: 29
+
+      reg-mux-offset:
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+      bit-mux-offset:
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+      reg-gpio-offset:
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+    required:
+      - gpio-controller
+      - "#gpio-cells"
+      - npins
+      - bank-index
+      - reg-mux-offset
+      - reg-gpio-offset
+      - bank-name
+
+    additionalProperties: false
+    unevaluatedProperties: false
+
+  "^func-[0-9a-z]":
+    type: object
+    additionalProperties:
+      type: object
+      allOf:
+        - $ref: pincfg-node.yaml#
+        - $ref: pinmux-node.yaml#
+
+additionalProperties: false
+
+examples:
+  - |
+    apb {
+      #address-cells = <2>;
+      #size-cells = <2>;
+      periphs_pinctrl: pinctrl at 8e700 {
+        compatible = "amlogic,pinctrl";
+        #address-cells = <2>;
+        #size-cells = <2>;
+        reg = <0x0 0x8e700 0x0 0x04>,
+              <0x0 0x8e704 0x0 0x60>;
+        reg-names = "mux", "gpio";
+
+        gpiob {
+          gpio-controller;
+          #gpio-cells = <2>;
+          npins = <10>;
+          bank-index = <1>;
+          reg-mux-offset = <0x14>;
+          bit-mux-offset = <0x14>;
+          reg-gpio-offset = <0x30>;
+          bank-name = "GPIOB";
+        };
+
+        gpioe {
+          gpio-controller;
+          #gpio-cells = <2>;
+          npins = <10>;
+          bank-index = <5>;
+          reg-mux-offset = <0x14>;
+          reg-gpio-offset = <0x30>;
+          bank-name = "GPIOE";
+        };
+
+        func-uart-b {
+          uart-b-default{
+            pinmux = <3>;
+            bias-pull-up;
+            drive-strength-microamp = <4000>;
+          };
+
+          uart-c-default{
+            pinmux = <4>;
+            bias-pull-up;
+            drive-strength-microamp = <4000>;
+          };
+        };
+
+        func-uart-c {
+          uart-c-default{
+            pinmux = <3>;
+            bias-pull-up;
+            drive-strength-microamp = <4000>;
+          };
+        };
+      };
+    };
diff --git a/include/dt-bindings/pinctrl/amlogic,pinctrl.h b/include/dt-bindings/pinctrl/amlogic,pinctrl.h
new file mode 100644
index 000000000000..03db0a730e8b
--- /dev/null
+++ b/include/dt-bindings/pinctrl/amlogic,pinctrl.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ * Author: Xianwei Zhao <xianwei.zhao at amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_PINCTRL_H
+#define _DT_BINDINGS_AMLOGIC_PINCTRL_H
+
+/* define PIN modes */
+#define AF0	0x0
+#define AF1	0x1
+#define AF2	0x2
+#define AF3	0x3
+#define AF4	0x4
+#define AF5	0x5
+#define AF6	0x6
+#define AF7	0x7
+#define AF8	0x8
+#define AF9	0x9
+#define AF10	0xa
+#define AF11	0xb
+#define AF12	0xc
+#define AF13	0xd
+#define AF14	0xe
+#define AF15	0xf
+
+#define AML_PIN_ALT_FUNC_MASK	0xf
+
+/* Normal PIN bank */
+#define AMLOGIC_GPIO_A		0
+#define AMLOGIC_GPIO_B		1
+#define AMLOGIC_GPIO_C		2
+#define AMLOGIC_GPIO_D		3
+#define AMLOGIC_GPIO_E		4
+#define AMLOGIC_GPIO_F		5
+#define AMLOGIC_GPIO_G		6
+#define AMLOGIC_GPIO_H		7
+#define AMLOGIC_GPIO_I		8
+#define AMLOGIC_GPIO_J		9
+#define AMLOGIC_GPIO_K		10
+#define AMLOGIC_GPIO_L		11
+#define AMLOGIC_GPIO_M		12
+#define AMLOGIC_GPIO_N		13
+#define AMLOGIC_GPIO_O		14
+#define AMLOGIC_GPIO_P		15
+#define AMLOGIC_GPIO_Q		16
+#define AMLOGIC_GPIO_R		17
+#define AMLOGIC_GPIO_S		18
+#define AMLOGIC_GPIO_T		19
+#define AMLOGIC_GPIO_U		20
+#define AMLOGIC_GPIO_V		21
+#define AMLOGIC_GPIO_W		22
+#define AMLOGIC_GPIO_X		23
+#define AMLOGIC_GPIO_Y		24
+#define AMLOGIC_GPIO_Z		25
+
+/* Special PIN bank */
+#define AMLOGIC_GPIO_DV		26
+#define AMLOGIC_GPIO_AO		27
+#define AMLOGIC_GPIO_CC		28
+#define AMLOGIC_GPIO_TEST_N	29
+
+#define AML_PINMUX(bank, offset, mode)	(((((bank) << 8) + (offset)) << 8) | (mode))
+#define AML_PINMUX_TO_BANK(pinmux)	(((pinmux) >> 16) & 0xff)
+#define AML_PINMUX_TO_OFFSET(pinmux)	(((pinmux) >> 8) & 0xff)
+
+#endif /* _DT_BINDINGS_AMLOGIC_PINCTRL_H */

-- 
2.37.1




From devnull+xianwei.zhao.amlogic.com at kernel.org  Tue Dec 10 22:47:51 2024
From: devnull+xianwei.zhao.amlogic.com at kernel.org (Xianwei Zhao via B4 Relay)
Date: Wed, 11 Dec 2024 14:47:51 +0800
Subject: [PATCH RFC 3/3] arm64: dts: amlogic: a4: add pinctrl node
In-Reply-To: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
References: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
Message-ID: <20241211-amlogic-pinctrl-v1-3-410727335119@amlogic.com>

From: Xianwei Zhao <xianwei.zhao at amlogic.com>

Add pinctrl device to support Amlogic A4 and add uart pinconf.

Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
---
 arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi | 146 ++++++++++++++++++++++++++++
 1 file changed, 146 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi
index de10e7aebf21..fccae7c9758a 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi
@@ -5,6 +5,7 @@
 
 #include "amlogic-a4-common.dtsi"
 #include <dt-bindings/power/amlogic,a4-pwrc.h>
+#include <dt-bindings/pinctrl/amlogic,pinctrl.h>
 / {
 	cpus {
 		#address-cells = <2>;
@@ -48,3 +49,148 @@ pwrc: power-controller {
 		};
 	};
 };
+
+&apb {
+	periphs_pinctrl: pinctrl at 4000 {
+		compatible = "amlogic,pinctrl";
+		reg = <0x0 0x4000 0x0 0x0050>,
+		      <0x0 0x40c0 0x0 0x0220>;
+		reg-names = "mux", "gpio";
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		gpiob: gpiob {
+			gpio-controller;
+			#gpio-cells = <2>;
+			npins = <14>;
+			bank-index = <AMLOGIC_GPIO_B>;
+			reg-mux-offset = <0>;
+			reg-gpio-offset = <0x60>;
+			bank-name = "GPIOB";
+		};
+
+		gpiod: gpiod {
+			gpio-controller;
+			#gpio-cells = <2>;
+			npins = <16>;
+			bank-index = <AMLOGIC_GPIO_D>;
+			reg-mux-offset = <0x10>;
+			reg-gpio-offset = <0x30>;
+			bank-name = "GPIOD";
+		};
+
+		gpioe: gpioe {
+			gpio-controller;
+			#gpio-cells = <2>;
+			npins = <2>;
+			bank-index = <AMLOGIC_GPIO_E>;
+			reg-mux-offset = <0x12>;
+			reg-gpio-offset = <0x40>;
+			bank-name = "GPIOE";
+		};
+
+		gpiot: gpiot {
+			gpio-controller;
+			#gpio-cells = <2>;
+			npins = <23>;
+			bank-index = <AMLOGIC_GPIO_T>;
+			reg-mux-offset = <0xb>;
+			reg-gpio-offset = <0x20>;
+			bank-name = "GPIOT";
+		};
+
+		gpiox: gpiox {
+			gpio-controller;
+			#gpio-cells = <2>;
+			npins = <18>;
+			bank-index = <AMLOGIC_GPIO_X>;
+			reg-mux-offset = <0x3>;
+			reg-gpio-offset = <0x10>;
+			bank-name = "GPIOX";
+		};
+
+		func-uart-a {
+			uart_a_default: uart-a-pins1{
+				pinmux= <AML_PINMUX(AMLOGIC_GPIO_X, 11, AF1)>,
+					<AML_PINMUX(AMLOGIC_GPIO_X, 12, AF1)>,
+					<AML_PINMUX(AMLOGIC_GPIO_X, 13, AF1)>,
+					<AML_PINMUX(AMLOGIC_GPIO_X, 13, AF1)>;
+			};
+
+			uart-a-pins2{
+				pinmux= <AML_PINMUX(AMLOGIC_GPIO_D, 2, AF3)>,
+					<AML_PINMUX(AMLOGIC_GPIO_D, 3, AF3)>;
+				bias-pull-up;
+				drive-strength-microamp = <4000>;
+			};
+		};
+
+		func-uart-b {
+			uart_b_default: uart-b-default{
+				pinmux= <AML_PINMUX(AMLOGIC_GPIO_E, 0, AF3)>,
+					<AML_PINMUX(AMLOGIC_GPIO_E, 1, AF3)>;
+				bias-pull-up;
+				drive-strength-microamp = <4000>;
+			};
+		};
+
+		func-uart-d {
+			uart_d_default: uart-d-pins1{
+				pinmux= <AML_PINMUX(AMLOGIC_GPIO_T, 18, AF4)>,
+					<AML_PINMUX(AMLOGIC_GPIO_T, 19, AF4)>;
+				bias-pull-up;
+				drive-strength-microamp = <4000>;
+			};
+
+			uart-d-pins2{
+				pinmux= <AML_PINMUX(AMLOGIC_GPIO_T, 7, AF2)>,
+					<AML_PINMUX(AMLOGIC_GPIO_T, 8, AF2)>,
+					<AML_PINMUX(AMLOGIC_GPIO_T, 9, AF2)>,
+					<AML_PINMUX(AMLOGIC_GPIO_T, 10, AF2)>;
+				bias-pull-up;
+				drive-strength-microamp = <4000>;
+			};
+		};
+
+		func-uart-e {
+			uart_e_default: uart-e-pins{
+				pinmux= <AML_PINMUX(AMLOGIC_GPIO_T, 14, AF3)>,
+					<AML_PINMUX(AMLOGIC_GPIO_T, 15, AF3)>,
+					<AML_PINMUX(AMLOGIC_GPIO_T, 16, AF3)>,
+					<AML_PINMUX(AMLOGIC_GPIO_T, 17, AF3)>;
+				bias-pull-up;
+				drive-strength-microamp = <4000>;
+			};
+		};
+	};
+
+	aobus_pinctrl: pinctrl at 8e700 {
+		compatible = "amlogic,pinctrl";
+		reg = <0x0 0x8e700 0x0 0x04>,
+		      <0x0 0x8e704 0x0 0x60>;
+		reg-names = "mux", "gpio";
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		gpioao: gpioao {
+			gpio-controller;
+			#gpio-cells = <2>;
+			npins = <7>;
+			bank-index = <AMLOGIC_GPIO_AO>;
+			reg-mux-offset = <0>;
+			reg-gpio-offset = <0>;
+			bank-name = "GPIOAO";
+		};
+
+		test_n: gpiotestn {
+			gpio-controller;
+			#gpio-cells = <2>;
+			npins = <1>;
+			bank-index = <AMLOGIC_GPIO_TEST_N>;
+			reg-mux-offset = <0>;
+			bit-mux-offset = <28>;
+			reg-gpio-offset = <0x10>;
+			bank-name = "TEST_N";
+		};
+	};
+};

-- 
2.37.1




From devnull+xianwei.zhao.amlogic.com at kernel.org  Tue Dec 10 22:47:48 2024
From: devnull+xianwei.zhao.amlogic.com at kernel.org (Xianwei Zhao via B4 Relay)
Date: Wed, 11 Dec 2024 14:47:48 +0800
Subject: [PATCH RFC 0/3] Pinctrl: Add Amlogic pinctrl driver
Message-ID: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>

Add pinctrl driver support for Amloigc SoCs

Base on the previous discussion,
https://lore.kernel.org/r/20241113-a4_pinctrl-v6-0-35ba2401ee35 at amlogic.com
The existed meson driver failed to meet the requirement of the current dt-binding.
So we start this new pinctrl driver to solve problem.

The advantage of this version: Once the source file and binding document
are added, adding dts node will be only operation for subsequent Amlogic SoCs
(such as A4, A5).

The code in DTS file is also readable when using GPIO, as below:
reset-gpios = <&gpiob 6 GPIO_ACTIVE_LOW>;

Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
---
Xianwei Zhao (3):
      dt-bindings: pinctrl: Add support for Amlogic SoCs
      pinctrl: Add driver support for Amlogic SoCs
      arm64: dts: amlogic: a4: add pinctrl node

 .../bindings/pinctrl/amlogic,pinctrl.yaml          |  150 +++
 arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi        |  146 +++
 drivers/pinctrl/Kconfig                            |   18 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-amlogic.c                  | 1190 ++++++++++++++++++++
 include/dt-bindings/pinctrl/amlogic,pinctrl.h      |   68 ++
 6 files changed, 1573 insertions(+)
---
base-commit: 171aa289a6fe65faffeb92a1fda283c055435a62
change-id: 20241211-amlogic-pinctrl-22ea61820d0d

Best regards,
-- 
Xianwei Zhao <xianwei.zhao at amlogic.com>




From devnull+xianwei.zhao.amlogic.com at kernel.org  Tue Dec 10 22:47:50 2024
From: devnull+xianwei.zhao.amlogic.com at kernel.org (Xianwei Zhao via B4 Relay)
Date: Wed, 11 Dec 2024 14:47:50 +0800
Subject: [PATCH RFC 2/3] pinctrl: Add driver support for Amlogic SoCs
In-Reply-To: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
References: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
Message-ID: <20241211-amlogic-pinctrl-v1-2-410727335119@amlogic.com>

From: Xianwei Zhao <xianwei.zhao at amlogic.com>

Add a new pinctrl driver for Amlogic SoCs. All future Amlogic
SoCs pinctrl drives use this, such A4, A5, S6, S7 etc. To support
new Amlogic SoCs, only need to add the corresponding dts file.

Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
---
 drivers/pinctrl/Kconfig           |   18 +
 drivers/pinctrl/Makefile          |    1 +
 drivers/pinctrl/pinctrl-amlogic.c | 1190 +++++++++++++++++++++++++++++++++++++
 3 files changed, 1209 insertions(+)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 354536de564b..41bd85aa433d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -49,6 +49,24 @@ config PINCTRL_AMD
 	  Requires ACPI/FDT device enumeration code to set up a platform
 	  device.
 
+config PINCTRL_AMLOGIC
+	bool "AMLOGIC pincontrol"
+	depends on ARCH_MESON || COMPILE_TEST
+	depends on OF
+	default y
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+	select GPIOLIB
+	select OF_GPIO
+	select REGMAP_MMIO
+	help
+	  This is the driver for the pin controller found on Amlogic SoCs.
+
+	  This driver is simplify subsequent support for new amlogic SoCs,
+	  to support new Amlogic SoCs, only need to add the corresponding dts file,
+	  no additional binding header files or C file are added.
+
 config PINCTRL_APPLE_GPIO
 	tristate "Apple SoC GPIO pin controller driver"
 	depends on ARCH_APPLE
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 97823f52b972..f24c0b92a462 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_GENERIC_PINCONF)	+= pinconf-generic.o
 obj-$(CONFIG_OF)		+= devicetree.o
 
 obj-$(CONFIG_PINCTRL_AMD)	+= pinctrl-amd.o
+obj-$(CONFIG_PINCTRL_AMLOGIC) 	+= pinctrl-amlogic.o
 obj-$(CONFIG_PINCTRL_APPLE_GPIO) += pinctrl-apple-gpio.o
 obj-$(CONFIG_PINCTRL_ARTPEC6)	+= pinctrl-artpec6.o
 obj-$(CONFIG_PINCTRL_AS3722)	+= pinctrl-as3722.o
diff --git a/drivers/pinctrl/pinctrl-amlogic.c b/drivers/pinctrl/pinctrl-amlogic.c
new file mode 100644
index 000000000000..61351b0d8fb0
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-amlogic.c
@@ -0,0 +1,1190 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ * Author: Xianwei Zhao <xianwei.zhao at amlogic.com>
+ */
+
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/string_helpers.h>
+
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <dt-bindings/pinctrl/amlogic,pinctrl.h>
+
+#include "core.h"
+#include "pinconf.h"
+
+#define gpio_chip_to_bank(chip) \
+		container_of(chip, struct aml_gpio_bank, gpio_chip)
+/**
+ * enum aml_reg_type - type of registers encoded in @aml_reg_desc
+ */
+enum aml_reg_type {
+	REG_PULLEN,
+	REG_PULL,
+	REG_DIR,
+	REG_OUT,
+	REG_IN,
+	REG_DS,
+	NUM_REG,
+};
+
+static const unsigned int aml_bit_strides[NUM_REG] = {
+	1, 1, 1, 1, 1, 2
+};
+
+static const unsigned int aml_reg_type_offset[NUM_REG] = {
+	3, 4, 2, 1, 0, 7
+};
+
+enum aml_pinconf_drv {
+	PINCONF_DRV_500UA,
+	PINCONF_DRV_2500UA,
+	PINCONF_DRV_3000UA,
+	PINCONF_DRV_4000UA,
+};
+
+struct aml_pio_control {
+	int reg_mux_offset;
+	int bit_mux_offset;
+	int reg_gpio_offset;
+	int reg_offset[NUM_REG];
+};
+
+struct aml_pctl_data {
+};
+
+struct aml_pinconf {
+	int		pin;
+	int		altfunc;
+};
+
+struct aml_pmx_func {
+	const char	*name;
+	const char	**groups;
+	unsigned int	ngroups;
+};
+
+struct aml_pctl_group {
+	const char		*name;
+	unsigned short		npins;
+	unsigned int		*pins;
+	struct aml_pinconf	*pin_conf;
+	unsigned long           *configs;
+	unsigned int            num_configs;
+};
+
+struct aml_gpio_bank {
+	struct gpio_chip		gpio_chip;
+	struct aml_pio_control		pc;
+	unsigned int                    bank_idx;
+	unsigned int			pin_base;
+};
+
+struct aml_pinctrl {
+	struct device			*dev;
+	struct pinctrl_dev		*pctl;
+	struct aml_gpio_bank		*banks;
+	int				nbanks;
+	struct aml_pmx_func		*functions;
+	int				nfunctions;
+	struct aml_pctl_group		*groups;
+	int				ngroups;
+
+	struct regmap			*reg_mux;
+	struct regmap			*reg_gpio;
+	struct regmap			*reg_pullen;
+	struct regmap			*reg_pull;
+	struct regmap			*reg_ds;
+	const struct aml_pctl_data	*data;
+};
+
+static int aml_pmx_calc_reg_and_offset(struct pinctrl_gpio_range *range,
+				       unsigned int pin, unsigned int *reg,
+				       unsigned int *offset)
+{
+	struct aml_gpio_bank *bank = gpio_chip_to_bank(range->gc);
+	unsigned int shift;
+
+	shift = ((pin - range->pin_base) << 2) + bank->pc.bit_mux_offset;
+	*reg = (bank->pc.reg_mux_offset + (shift / 32)) * 4;
+	*offset = shift % 32;
+
+	return 0;
+}
+
+static int aml_pctl_set_function(struct aml_pinctrl *info,
+				 struct pinctrl_gpio_range *range,
+				 int pin_id, int func)
+{
+	int reg;
+	int offset;
+
+	aml_pmx_calc_reg_and_offset(range, pin_id, &reg, &offset);
+	return regmap_update_bits(info->reg_mux, reg,
+			0xf << offset, (func & 0xf) << offset);
+}
+
+static int aml_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->nfunctions;
+}
+
+static const char *aml_pmx_get_fname(struct pinctrl_dev *pctldev,
+				     unsigned int selector)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->functions[selector].name;
+}
+
+static int aml_pmx_get_groups(struct pinctrl_dev *pctldev,
+			      unsigned int selector,
+			      const char * const **grps,
+			      unsigned * const ngrps)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	*grps = info->functions[selector].groups;
+	*ngrps = info->functions[selector].ngroups;
+
+	return 0;
+}
+
+static int aml_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned int fselector,
+			   unsigned int group)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct aml_pinconf *conf = info->groups[group].pin_conf;
+	struct pinctrl_gpio_range *range;
+	int i;
+
+	for (i = 0; i < info->groups[group].npins; i++) {
+		range =  pinctrl_find_gpio_range_from_pin(pctldev, conf[i].pin);
+		aml_pctl_set_function(info, range, conf[i].pin, conf[i].altfunc);
+	}
+
+	return 0;
+}
+
+static int aml_pmx_request_gpio(struct pinctrl_dev *pctldev,
+				struct pinctrl_gpio_range *range,
+				unsigned int pin)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return aml_pctl_set_function(info, range, pin, 0);
+}
+
+static const struct pinmux_ops aml_pmx_ops = {
+	.set_mux		= aml_pmx_set_mux,
+	.get_functions_count	= aml_pmx_get_funcs_count,
+	.get_function_name	= aml_pmx_get_fname,
+	.get_function_groups	= aml_pmx_get_groups,
+	.gpio_request_enable	= aml_pmx_request_gpio,
+};
+
+static int aml_calc_reg_and_bit(struct pinctrl_dev *pctldev,
+				unsigned int pin,
+				enum aml_reg_type reg_type,
+				unsigned int *reg, unsigned int *bit)
+{
+	struct pinctrl_gpio_range *range =
+			 pinctrl_find_gpio_range_from_pin(pctldev, pin);
+	struct aml_gpio_bank *bank = gpio_chip_to_bank(range->gc);
+
+	*bit = (pin - range->pin_base) * aml_bit_strides[reg_type];
+	*reg = (bank->pc.reg_offset[reg_type] + (*bit / 32)) * 4;
+	*bit &= 0x1f;
+
+	return 0;
+}
+
+static int aml_pinconf_get_pull(struct aml_pinctrl *info, unsigned int pin)
+{
+	unsigned int reg, bit, val;
+	int ret, conf;
+
+	aml_calc_reg_and_bit(info->pctl, pin, REG_PULLEN, &reg, &bit);
+
+	ret = regmap_read(info->reg_pullen, reg, &val);
+	if (ret)
+		return ret;
+
+	if (!(val & BIT(bit))) {
+		conf = PIN_CONFIG_BIAS_DISABLE;
+	} else {
+		aml_calc_reg_and_bit(info->pctl, pin, REG_PULL, &reg, &bit);
+
+		ret = regmap_read(info->reg_pull, reg, &val);
+		if (ret)
+			return ret;
+
+		if (val & BIT(bit))
+			conf = PIN_CONFIG_BIAS_PULL_UP;
+		else
+			conf = PIN_CONFIG_BIAS_PULL_DOWN;
+	}
+
+	return conf;
+}
+
+static int aml_pinconf_get_drive_strength(struct aml_pinctrl *info,
+					  unsigned int pin,
+					  u16 *drive_strength_ua)
+{
+	unsigned int reg, bit;
+	unsigned int val;
+	int ret;
+
+	if (!info->reg_ds)
+		return -EOPNOTSUPP;
+
+	aml_calc_reg_and_bit(info->pctl, pin, REG_DS, &reg, &bit);
+	ret = regmap_read(info->reg_ds, reg, &val);
+	if (ret)
+		return ret;
+
+	switch ((val >> bit) & 0x3) {
+	case PINCONF_DRV_500UA:
+		*drive_strength_ua = 500;
+		break;
+	case PINCONF_DRV_2500UA:
+		*drive_strength_ua = 2500;
+		break;
+	case PINCONF_DRV_3000UA:
+		*drive_strength_ua = 3000;
+		break;
+	case PINCONF_DRV_4000UA:
+		*drive_strength_ua = 4000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int aml_pinconf_get_gpio_bit(struct aml_pinctrl *info,
+				    unsigned int pin,
+				    unsigned int reg_type)
+{
+	unsigned int reg, bit, val;
+	int ret;
+
+	aml_calc_reg_and_bit(info->pctl, pin, reg_type, &reg, &bit);
+	ret = regmap_read(info->reg_gpio, reg, &val);
+	if (ret)
+		return ret;
+
+	return BIT(bit) & val ? 1 : 0;
+}
+
+static int aml_pinconf_get_output(struct aml_pinctrl *info,
+				  unsigned int pin)
+{
+	int ret = aml_pinconf_get_gpio_bit(info, pin, REG_DIR);
+
+	if (ret < 0)
+		return ret;
+
+	return !ret;
+}
+
+static int aml_pinconf_get_drive(struct aml_pinctrl *info,
+				 unsigned int pin)
+{
+	return aml_pinconf_get_gpio_bit(info, pin, REG_OUT);
+}
+
+static int aml_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
+			   unsigned long *config)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pcdev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	u16 arg;
+	int ret;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (aml_pinconf_get_pull(info, pin) == param)
+			arg = 1;
+		else
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_DRIVE_STRENGTH_UA:
+		ret = aml_pinconf_get_drive_strength(info, pin, &arg);
+		if (ret)
+			return ret;
+		break;
+	case PIN_CONFIG_OUTPUT_ENABLE:
+		ret = aml_pinconf_get_output(info, pin);
+		if (ret <= 0)
+			return -EINVAL;
+		arg = 1;
+		break;
+	case PIN_CONFIG_OUTPUT:
+		ret = aml_pinconf_get_output(info, pin);
+		if (ret <= 0)
+			return -EINVAL;
+
+		ret = aml_pinconf_get_drive(info, pin);
+		if (ret < 0)
+			return -EINVAL;
+
+		arg = ret;
+		break;
+
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+	dev_dbg(info->dev, "pinconf for pin %u is %lu\n", pin, *config);
+
+	return 0;
+}
+
+static int aml_pinconf_disable_bias(struct aml_pinctrl *info,
+				    unsigned int pin)
+{
+	unsigned int reg, bit = 0;
+
+	aml_calc_reg_and_bit(info->pctl, pin, REG_PULLEN, &reg, &bit);
+
+	return regmap_update_bits(info->reg_pullen, reg, BIT(bit), 0);
+}
+
+static int aml_pinconf_enable_bias(struct aml_pinctrl *info, unsigned int pin,
+				   bool pull_up)
+{
+	unsigned int reg, bit, val = 0;
+	int ret;
+
+	aml_calc_reg_and_bit(info->pctl, pin, REG_PULL, &reg, &bit);
+	if (pull_up)
+		val = BIT(bit);
+
+	ret = regmap_update_bits(info->reg_pull, reg, BIT(bit), val);
+	if (ret)
+		return ret;
+
+	aml_calc_reg_and_bit(info->pctl, pin, REG_PULLEN, &reg, &bit);
+	return regmap_update_bits(info->reg_pullen, reg, BIT(bit), BIT(bit));
+}
+
+static int aml_pinconf_set_drive_strength(struct aml_pinctrl *info,
+					  unsigned int pin,
+					  u16 drive_strength_ua)
+{
+	unsigned int reg, bit, ds_val;
+
+	if (!info->reg_ds) {
+		dev_err(info->dev, "drive-strength not supported\n");
+		return -EOPNOTSUPP;
+	}
+
+	aml_calc_reg_and_bit(info->pctl, pin, REG_DS, &reg, &bit);
+
+	if (drive_strength_ua <= 500) {
+		ds_val = PINCONF_DRV_500UA;
+	} else if (drive_strength_ua <= 2500) {
+		ds_val = PINCONF_DRV_2500UA;
+	} else if (drive_strength_ua <= 3000) {
+		ds_val = PINCONF_DRV_3000UA;
+	} else if (drive_strength_ua <= 4000) {
+		ds_val = PINCONF_DRV_4000UA;
+	} else {
+		dev_warn_once(info->dev,
+			      "pin %u: invalid drive-strength : %d , default to 4mA\n",
+			      pin, drive_strength_ua);
+		ds_val = PINCONF_DRV_4000UA;
+	}
+
+	return regmap_update_bits(info->reg_ds, reg, 0x3 << bit, ds_val << bit);
+}
+
+static int aml_pinconf_set_gpio_bit(struct aml_pinctrl *info,
+				    unsigned int pin,
+				    unsigned int reg_type,
+				    bool arg)
+{
+	unsigned int reg, bit;
+
+	aml_calc_reg_and_bit(info->pctl, pin, reg_type, &reg, &bit);
+	return regmap_update_bits(info->reg_gpio, reg, BIT(bit),
+				  arg ? BIT(bit) : 0);
+}
+
+static int aml_pinconf_set_output(struct aml_pinctrl *info,
+				  unsigned int pin,
+				  bool out)
+{
+	return aml_pinconf_set_gpio_bit(info, pin, REG_DIR, !out);
+}
+
+static int aml_pinconf_set_drive(struct aml_pinctrl *info,
+				 unsigned int pin,
+				 bool high)
+{
+	return aml_pinconf_set_gpio_bit(info, pin, REG_OUT, high);
+}
+
+static int aml_pinconf_set_output_drive(struct aml_pinctrl *info,
+					unsigned int pin,
+					bool high)
+{
+	int ret;
+
+	ret = aml_pinconf_set_output(info, pin, true);
+	if (ret)
+		return ret;
+
+	return aml_pinconf_set_drive(info, pin, high);
+}
+
+static int aml_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
+			   unsigned long *configs, unsigned int num_configs)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pcdev);
+	enum pin_config_param param;
+	unsigned int arg = 0;
+	int i, ret;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_DRIVE_STRENGTH_UA:
+		case PIN_CONFIG_OUTPUT_ENABLE:
+		case PIN_CONFIG_OUTPUT:
+			arg = pinconf_to_config_argument(configs[i]);
+			break;
+
+		default:
+			break;
+		}
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+			ret = aml_pinconf_disable_bias(info, pin);
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			ret = aml_pinconf_enable_bias(info, pin, true);
+			break;
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			ret = aml_pinconf_enable_bias(info, pin, false);
+			break;
+		case PIN_CONFIG_DRIVE_STRENGTH_UA:
+			ret = aml_pinconf_set_drive_strength(info, pin, arg);
+			break;
+		case PIN_CONFIG_OUTPUT_ENABLE:
+			ret = aml_pinconf_set_output(info, pin, arg);
+			break;
+		case PIN_CONFIG_OUTPUT:
+			ret = aml_pinconf_set_output_drive(info, pin, arg);
+			break;
+		default:
+			ret = -ENOTSUPP;
+		}
+
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int aml_pinconf_group_set(struct pinctrl_dev *pcdev,
+				 unsigned int num_group,
+				 unsigned long *configs,
+				 unsigned int num_configs)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pcdev);
+	int i;
+
+	for (i = 0; i < info->groups[num_group].npins; i++) {
+		aml_pinconf_set(pcdev, info->groups[num_group].pins[i], configs,
+				num_configs);
+	}
+
+	return 0;
+}
+
+static int aml_pinconf_group_get(struct pinctrl_dev *pcdev,
+				 unsigned int group, unsigned long *config)
+{
+	return -EOPNOTSUPP;
+}
+
+static const struct pinconf_ops aml_pinconf_ops = {
+	.pin_config_get		= aml_pinconf_get,
+	.pin_config_set		= aml_pinconf_set,
+	.pin_config_group_get	= aml_pinconf_group_get,
+	.pin_config_group_set	= aml_pinconf_group_set,
+	.is_generic		= true,
+};
+
+static int aml_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->ngroups;
+}
+
+static const char *aml_get_group_name(struct pinctrl_dev *pctldev,
+				      unsigned int selector)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->groups[selector].name;
+}
+
+static int aml_get_group_pins(struct pinctrl_dev *pctldev,
+			      unsigned int selector, const unsigned int **pins,
+			      unsigned int *npins)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	*pins = info->groups[selector].pins;
+	*npins = info->groups[selector].npins;
+
+	return 0;
+}
+
+static inline const struct aml_pctl_group *
+	aml_pctl_find_group_by_name(const struct aml_pinctrl *info,
+				    const char *name)
+{
+	int i;
+
+	for (i = 0; i < info->ngroups; i++) {
+		if (!strcmp(info->groups[i].name, name))
+			return &info->groups[i];
+	}
+
+	return NULL;
+}
+
+static int aml_dt_node_to_map(struct pinctrl_dev *pctldev,
+			      struct device_node *np,
+			      struct pinctrl_map **map,
+			      unsigned int *num_maps)
+{
+	struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	const struct aml_pctl_group *grp;
+	struct device *dev = info->dev;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num, i;
+
+	grp = aml_pctl_find_group_by_name(info, np->name);
+	if (!grp) {
+		dev_err(dev, "unable to find group for node %pOFn\n", np);
+		return -EINVAL;
+	}
+
+	if (grp->num_configs)
+		map_num = grp->npins + 1;
+	else
+		map_num = 1;
+	new_map = devm_kcalloc(dev, map_num, sizeof(*new_map), GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	parent = of_get_parent(np);
+	if (!parent) {
+		devm_kfree(dev, new_map);
+		return -EINVAL;
+	}
+
+	*map = new_map;
+	*num_maps = map_num;
+	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);
+
+	if (grp->num_configs) {
+		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->configs;
+			new_map[i].data.configs.num_configs = grp->num_configs;
+		}
+	}
+
+	dev_info(dev, "maps: function %s group %s num %d\n",
+		 (*map)->data.mux.function, grp->name, map_num);
+
+	return 0;
+}
+
+static void aml_dt_free_map(struct pinctrl_dev *pctldev,
+			    struct pinctrl_map *map, unsigned int num_maps)
+{
+}
+
+static void aml_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
+			     unsigned int offset)
+{
+	seq_printf(s, " %s", dev_name(pcdev->dev));
+}
+
+static const struct pinctrl_ops aml_pctrl_ops = {
+	.get_groups_count	= aml_get_groups_count,
+	.get_group_name		= aml_get_group_name,
+	.get_group_pins		= aml_get_group_pins,
+	.dt_node_to_map		= aml_dt_node_to_map,
+	.dt_free_map		= aml_dt_free_map,
+	.pin_dbg_show		= aml_pin_dbg_show,
+};
+
+static int aml_pctl_dt_calculate_pin(struct aml_pinctrl *info,
+				     unsigned int bank_idx, unsigned int offset)
+{
+	struct aml_gpio_bank *bank;
+	int retval = -EINVAL;
+	int i;
+
+	for (i = 0; i < info->nbanks; i++) {
+		bank = &info->banks[i];
+		if (bank->bank_idx == bank_idx) {
+			if (offset < bank->gpio_chip.ngpio)
+				retval = bank->pin_base + offset;
+			break;
+		}
+	}
+	if (retval == -EINVAL)
+		dev_err(info->dev, "pin [bank:%d, offset:%d] is not present\n", bank_idx, offset);
+
+	return retval;
+}
+
+static int aml_pctl_dt_parse_groups(struct device_node *np,
+				    struct aml_pctl_group *grp,
+				    struct aml_pinctrl *info, int idx)
+{
+	struct device *dev = info->dev;
+	struct aml_pinconf *conf;
+	struct property *of_pins;
+	unsigned int bank_idx;
+	unsigned int offset, npins;
+	int i = 0;
+	int ret;
+
+	of_pins = of_find_property(np, "pinmux", NULL);
+	if (!of_pins) {
+		dev_info(dev, "Missing pinmux property\n");
+		return -ENOENT;
+	}
+
+	npins = of_pins->length / sizeof(u32);
+	grp->npins = npins;
+	grp->name = np->name;
+	grp->pins = devm_kcalloc(dev, npins, sizeof(*grp->pins), GFP_KERNEL);
+	grp->pin_conf = devm_kcalloc(dev, npins, sizeof(*grp->pin_conf), GFP_KERNEL);
+
+	if (!grp->pins || !grp->pin_conf)
+		return -ENOMEM;
+
+	ret = pinconf_generic_parse_dt_config(np, info->pctl, &grp->configs,
+					      &grp->num_configs);
+	if (ret < 0) {
+		dev_err(dev, "%pOF: could not parse node property\n", np);
+		return ret;
+	}
+
+	for (i = 0; i < npins; i++) {
+		u32 value;
+
+		ret = of_property_read_u32_index(np, "pinmux", i, &value);
+		if (ret)
+			return ret;
+
+		conf = &grp->pin_conf[i];
+
+		bank_idx = AML_PINMUX_TO_BANK(value);
+		offset = AML_PINMUX_TO_OFFSET(value);
+		conf->pin = aml_pctl_dt_calculate_pin(info, bank_idx, offset);
+		if (conf->pin < 0)
+			return dev_err_probe(dev, -EINVAL, "pinmux get pin failed\n");
+		conf->altfunc = value & AML_PIN_ALT_FUNC_MASK;
+
+		grp->pins[i] = conf->pin;
+	}
+
+	return 0;
+}
+
+static int aml_pctl_parse_functions(struct device_node *np,
+				    struct aml_pinctrl *info, u32 index,
+				    int *grp_index)
+{
+	struct device *dev = info->dev;
+	struct aml_pmx_func *func;
+	struct aml_pctl_group *grp;
+	int ret, i;
+
+	func = &info->functions[index];
+	func->name = np->name;
+	func->ngroups = of_get_child_count(np);
+	if (func->ngroups == 0)
+		return dev_err_probe(dev, -EINVAL, "No groups defined\n");
+
+	func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL);
+	if (!func->groups)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node_scoped(np, child) {
+		func->groups[i] = child->name;
+		grp = &info->groups[*grp_index];
+		*grp_index += 1;
+		ret = aml_pctl_dt_parse_groups(child, grp, info, i++);
+		if (ret)
+			return ret;
+	}
+	dev_info(dev, "Function[%d\t name:%s,\tgroups:%d]\n", index, func->name, func->ngroups);
+
+	return 0;
+}
+
+static u32 aml_bank_pins(struct device_node *np)
+{
+	u32 value;
+
+	if (of_property_read_u32(np, "npins", &value) < 0)
+		return 0;
+	else
+		return value;
+}
+
+static u32 aml_bank_reg_gpio_offset(struct device_node *np)
+{
+	u32 value;
+
+	if (of_property_read_u32(np, "reg-gpio-offset", &value) < 0)
+		return 0;
+	else
+		return value;
+}
+
+static u32 aml_bank_reg_mux_offset(struct device_node *np)
+{
+	u32 value;
+
+	if (of_property_read_u32(np, "reg-mux-offset", &value) < 0)
+		return 0;
+	else
+		return value;
+}
+
+static u32 aml_bank_bit_mux_offset(struct device_node *np)
+{
+	u32 value;
+
+	if (of_property_read_u32(np, "bit-mux-offset", &value) < 0)
+		return 0;
+	else
+		return value;
+}
+
+static u32 aml_bank_index(struct device_node *np)
+{
+	u32 value;
+
+	if (of_property_read_u32(np, "bank-index", &value) < 0)
+		return 0;
+	else
+		return value;
+}
+
+static unsigned int aml_count_pins(struct device_node *np)
+{
+	struct device_node *child;
+	unsigned int pins = 0;
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller"))
+			pins += aml_bank_pins(child);
+	}
+
+	return pins;
+}
+
+static void aml_pctl_dt_child_count(struct aml_pinctrl *info,
+				    struct device_node *np)
+{
+	struct device_node *child;
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller")) {
+			info->nbanks++;
+		} else {
+			info->nfunctions++;
+			info->ngroups += of_get_child_count(child);
+		}
+	}
+}
+
+static struct regmap_config aml_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+};
+
+static struct regmap *aml_map_resource(struct aml_pinctrl *info,
+				       struct device_node *node, char *name)
+{
+	struct resource res;
+	void __iomem *base;
+	int i;
+
+	i = of_property_match_string(node, "reg-names", name);
+	if (of_address_to_resource(node, i, &res))
+		return NULL;
+
+	base = devm_ioremap_resource(info->dev, &res);
+	if (IS_ERR(base))
+		return ERR_CAST(base);
+
+	aml_regmap_config.max_register = resource_size(&res) - 4;
+	aml_regmap_config.name = devm_kasprintf(info->dev, GFP_KERNEL,
+						"%pOFn-%s", node,
+						name);
+	if (!aml_regmap_config.name)
+		return ERR_PTR(-ENOMEM);
+
+	return devm_regmap_init_mmio(info->dev, base, &aml_regmap_config);
+}
+
+static inline int aml_gpio_calc_reg_and_bit(struct aml_gpio_bank *bank,
+					    enum aml_reg_type reg_type,
+					    unsigned int gpio,
+					    unsigned int *reg,
+					    unsigned int *bit)
+{
+	*bit = gpio * aml_bit_strides[reg_type];
+	*reg = (bank->pc.reg_offset[reg_type] + (*bit / 32)) * 4;
+	*bit &= 0x1f;
+
+	return 0;
+}
+
+static int aml_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
+{
+	struct aml_gpio_bank *bank = gpiochip_get_data(chip);
+	struct aml_pinctrl *info = dev_get_drvdata(chip->parent);
+	unsigned int bit, reg, val;
+	int ret;
+
+	aml_gpio_calc_reg_and_bit(bank, REG_DIR, gpio, &reg, &bit);
+
+	ret = regmap_read(info->reg_gpio, reg, &val);
+	if (ret)
+		return ret;
+
+	return BIT(bit) & val ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
+}
+
+static int aml_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
+{
+	struct aml_gpio_bank *bank = gpiochip_get_data(chip);
+	struct aml_pinctrl *info = dev_get_drvdata(chip->parent);
+	unsigned int bit, reg;
+
+	aml_gpio_calc_reg_and_bit(bank, REG_DIR, gpio, &reg, &bit);
+
+	return regmap_update_bits(info->reg_gpio, reg, BIT(bit), BIT(bit));
+}
+
+static int aml_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
+				     int value)
+{
+	struct aml_gpio_bank *bank = gpiochip_get_data(chip);
+	struct aml_pinctrl *info = dev_get_drvdata(chip->parent);
+	unsigned int bit, reg;
+	int ret;
+
+	aml_gpio_calc_reg_and_bit(bank, REG_DIR, gpio, &reg, &bit);
+	ret = regmap_update_bits(info->reg_gpio, reg, BIT(bit), BIT(bit));
+	if (ret < 0)
+		return ret;
+
+	aml_gpio_calc_reg_and_bit(bank, REG_OUT, gpio, &reg, &bit);
+
+	return regmap_update_bits(info->reg_gpio, reg, BIT(bit),
+				  value ? BIT(bit) : 0);
+}
+
+static void aml_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
+{
+	struct aml_gpio_bank *bank = gpiochip_get_data(chip);
+	struct aml_pinctrl *info = dev_get_drvdata(chip->parent);
+	unsigned int bit, reg;
+
+	aml_gpio_calc_reg_and_bit(bank, REG_OUT, gpio, &reg, &bit);
+
+	regmap_update_bits(info->reg_gpio, reg, BIT(bit),
+			   value ? BIT(bit) : 0);
+}
+
+static int aml_gpio_get(struct gpio_chip *chip, unsigned int gpio)
+{
+	struct aml_gpio_bank *bank = gpiochip_get_data(chip);
+	struct aml_pinctrl *info = dev_get_drvdata(chip->parent);
+	unsigned int reg, bit, val;
+
+	aml_gpio_calc_reg_and_bit(bank, REG_IN, gpio, &reg, &bit);
+	regmap_read(info->reg_gpio, reg, &val);
+
+	return !!(val & BIT(bit));
+}
+
+static const struct gpio_chip aml_gpio_template = {
+	.request		= gpiochip_generic_request,
+	.free			= gpiochip_generic_free,
+	.set_config		= gpiochip_generic_config,
+	.set			= aml_gpio_set,
+	.get			= aml_gpio_get,
+	.direction_input	= aml_gpio_direction_input,
+	.direction_output	= aml_gpio_direction_output,
+	.get_direction		= aml_gpio_get_direction,
+	.can_sleep		= false,
+};
+
+static int aml_gpiolib_register_bank(struct aml_pinctrl *info,
+				     int bank_nr, struct device_node *np,
+				     int pin_next_index)
+{
+	struct aml_gpio_bank *bank = &info->banks[bank_nr];
+	struct device *dev = info->dev;
+	int err;
+	int i;
+
+	bank->pc.reg_gpio_offset = aml_bank_reg_gpio_offset(np);
+	bank->pc.reg_mux_offset = aml_bank_reg_mux_offset(np);
+	bank->pc.bit_mux_offset = aml_bank_bit_mux_offset(np);
+	for (i = 0; i < NUM_REG; i++)
+		bank->pc.reg_offset[i] = bank->pc.reg_gpio_offset + aml_reg_type_offset[i];
+
+	bank->gpio_chip = aml_gpio_template;
+	bank->gpio_chip.base = -1;
+	bank->gpio_chip.ngpio = aml_bank_pins(np);
+	bank->gpio_chip.fwnode = of_fwnode_handle(np);
+	bank->gpio_chip.parent = dev;
+
+	of_property_read_string(np, "bank-name", &bank->gpio_chip.label);
+
+	bank->pin_base = pin_next_index;
+	bank->bank_idx = aml_bank_index(np);
+
+	err  = gpiochip_add_data(&bank->gpio_chip, bank);
+	if (err)
+		return dev_err_probe(dev, err, "Failed to add gpiochip(%d)!\n", bank_nr);
+
+	dev_dbg(dev, "%s bank added.\n", bank->gpio_chip.label);
+
+	return 0;
+}
+
+static void aml_pctl_reg_extra(struct aml_pinctrl *info)
+{
+	if (!info->reg_pull)
+		info->reg_pull = info->reg_gpio;
+	if (!info->reg_pullen)
+		info->reg_pullen = info->reg_gpio;
+	if (!info->reg_ds)
+		info->reg_ds = info->reg_gpio;
+}
+
+static int aml_pctl_probe_dt(struct platform_device *pdev,
+			     struct pinctrl_desc *pctl_desc,
+			     struct aml_pinctrl *info)
+{
+	struct device *dev = &pdev->dev;
+	struct pinctrl_pin_desc *pdesc;
+	struct device_node *np = dev->of_node;
+	int grp_index = 0;
+	int i = 0, j = 0, k = 0, bank;
+	int ret = 0;
+
+	aml_pctl_dt_child_count(info, np);
+	if (!info->nbanks)
+		return dev_err_probe(dev, -EINVAL, "you need at least one gpio bank\n");
+
+	dev_dbg(dev, "nbanks = %d\n", info->nbanks);
+	dev_dbg(dev, "nfunctions = %d\n", info->nfunctions);
+	dev_dbg(dev, "ngroups = %d\n", info->ngroups);
+
+	info->functions = devm_kcalloc(dev, info->nfunctions, sizeof(*info->functions), GFP_KERNEL);
+
+	info->groups = devm_kcalloc(dev, info->ngroups, sizeof(*info->groups), GFP_KERNEL);
+
+	info->banks = devm_kcalloc(dev, info->nbanks, sizeof(*info->banks), GFP_KERNEL);
+
+	if (!info->functions || !info->groups || !info->banks)
+		return -ENOMEM;
+
+	info->reg_mux = aml_map_resource(info, np, "mux");
+	if (IS_ERR_OR_NULL(info->reg_mux))
+		return dev_err_probe(dev, info->reg_mux ? PTR_ERR(info->reg_mux) : -ENOENT,
+				     "mux registers not found\n");
+
+	info->reg_gpio = aml_map_resource(info, np, "gpio");
+	if (IS_ERR_OR_NULL(info->reg_gpio))
+		return dev_err_probe(dev, info->reg_gpio ? PTR_ERR(info->reg_gpio) : -ENOENT,
+				     "gpio registers not found\n");
+
+	info->reg_pull = aml_map_resource(info, np, "pull");
+	if (IS_ERR(info->reg_pull))
+		info->reg_pull = NULL;
+
+	info->reg_pullen = aml_map_resource(info, np, "pull-enable");
+	if (IS_ERR(info->reg_pullen))
+		info->reg_pullen = NULL;
+
+	info->reg_ds = aml_map_resource(info, np, "ds");
+	if (IS_ERR(info->reg_ds)) {
+		dev_dbg(info->dev, "ds registers not found - skipping\n");
+		info->reg_ds = NULL;
+	}
+
+	aml_pctl_reg_extra(info);
+
+	info->data = (struct aml_pctl_data *)of_device_get_match_data(dev);
+
+	pctl_desc->npins = aml_count_pins(np);
+
+	pdesc =	devm_kcalloc(dev, pctl_desc->npins, sizeof(*pdesc), GFP_KERNEL);
+	if (!pdesc)
+		return -ENOMEM;
+
+	pctl_desc->pins = pdesc;
+
+	bank = 0;
+	for_each_child_of_node_scoped(np, child) {
+		if (of_property_read_bool(child, "gpio-controller")) {
+			const char *bank_name = NULL;
+			char **pin_names;
+
+			ret = aml_gpiolib_register_bank(info, bank, child, k);
+			if (ret)
+				return ret;
+
+			k = info->banks[bank].pin_base;
+			bank_name = info->banks[bank].gpio_chip.label;
+
+			pin_names = devm_kasprintf_strarray(dev, bank_name,
+							    info->banks[bank].gpio_chip.ngpio);
+			if (IS_ERR(pin_names))
+				return PTR_ERR(pin_names);
+
+			for (j = 0; j < info->banks[bank].gpio_chip.ngpio; j++, k++) {
+				pdesc->number = k;
+				pdesc->name = pin_names[j];
+				pdesc++;
+			}
+			bank++;
+		} else {
+			ret = aml_pctl_parse_functions(child, info,
+						       i++, &grp_index);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int aml_pctl_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct aml_pinctrl *info;
+	struct pinctrl_desc *pctl_desc;
+	int ret, i;
+
+	pctl_desc = devm_kzalloc(dev, sizeof(*pctl_desc), GFP_KERNEL);
+	if (!pctl_desc)
+		return -ENOMEM;
+
+	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->dev = dev;
+	platform_set_drvdata(pdev, info);
+	ret = aml_pctl_probe_dt(pdev, pctl_desc, info);
+	if (ret)
+		return ret;
+
+	pctl_desc->owner	= THIS_MODULE;
+	pctl_desc->pctlops	= &aml_pctrl_ops;
+	pctl_desc->pmxops	= &aml_pmx_ops;
+	pctl_desc->confops	= &aml_pinconf_ops;
+	pctl_desc->name		= dev_name(dev);
+
+	info->pctl = devm_pinctrl_register(dev, pctl_desc, info);
+	if (IS_ERR(info->pctl)) {
+		dev_err(dev, "Failed pinctrl registration\n");
+		ret = PTR_ERR(info->pctl);
+		goto error;
+	}
+
+	for (i = 0; i < info->nbanks; i++) {
+		ret = gpiochip_add_pin_range(&info->banks[i].gpio_chip, dev_name(dev), 0,
+					     info->banks[i].pin_base,
+					     info->banks[i].gpio_chip.ngpio);
+		if (ret < 0) {
+			dev_err(dev, "Failed add pin range\n");
+			goto error;
+		}
+	}
+
+	return 0;
+error:
+	for (i = 0; i < info->nbanks; i++)
+		gpiochip_remove(&info->banks[i].gpio_chip);
+	return ret;
+}
+
+static const struct of_device_id aml_pctl_of_match[] = {
+	{ .compatible = "amlogic,pinctrl", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, aml_pctl_dt_match);
+
+static struct platform_driver aml_pctl_driver = {
+	.driver = {
+		.name = "amlogic-pinctrl",
+		.of_match_table = aml_pctl_of_match,
+	},
+	.probe = aml_pctl_probe,
+};
+module_platform_driver(aml_pctl_driver);
+
+MODULE_AUTHOR("Xianwei Zhao <xianwei.zhao at amlogic.com>");
+MODULE_DESCRIPTION("Pin controller and GPIO driver for Amlogic SoC");
+MODULE_LICENSE("Dual BSD/GPL");

-- 
2.37.1




From anshuman.khandual at arm.com  Tue Dec 10 22:54:24 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Dec 2024 12:24:24 +0530
Subject: [PATCH 1/2] docs: arm64: Document EL3 requirements for cpu debug architecture
In-Reply-To: <20241211065425.1106683-1-anshuman.khandual@arm.com>
References: <20241211065425.1106683-1-anshuman.khandual@arm.com>
Message-ID: <20241211065425.1106683-2-anshuman.khandual@arm.com>

This documents EL3 requirements for debug architecture. The register field
MDCR_EL3.TDA needs to be cleared for accesses into debug registers without
any trap being generated into EL3. CPU debug registers like DBGBCR<n>_EL1,
DBGBVR<n>_EL1, DBGWCR<n>_EL1, DBGWVR<n>_EL1 and MDSCR_EL1 are already being
accessed for HW breakpoint, watchpoint and debug monitor implementations on
the platform.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Jonathan Corbet <corbet at lwn.net>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arch/arm64/booting.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
index 3278fb4bf219..1b3ac1394e5f 100644
--- a/Documentation/arch/arm64/booting.rst
+++ b/Documentation/arch/arm64/booting.rst
@@ -449,6 +449,12 @@ Before jumping into the kernel, the following conditions must be met:
 
     - HFGWTR_EL2.nGCS_EL0 (bit 52) must be initialised to 0b1.
 
+ - For CPUs with debug architecture i.e FEAT_Debugv8pN (all versions):
+
+ - If EL3 is present:
+
+   - MDCR_EL3.TDA (bit 9) must be initialized to 0b0
+
 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 anshuman.khandual at arm.com  Tue Dec 10 22:54:23 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Dec 2024 12:24:23 +0530
Subject: [PATCH 0/2] docs: arm64: Document MDCR_EL3 boot requirements
Message-ID: <20241211065425.1106683-1-anshuman.khandual@arm.com>

This series adds missing MDCR_EL3 boot requirements for debug and pmu
registers that are currently being accessed in the kernel. Please refer
the following link for some earlier discussions on this.

https://lore.kernel.org/all/ZxfOeqyb3RvsdYbU at J2N7QTR9R3/

This series applies on v6.13-rc1

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Jonathan Corbet <corbet at lwn.net>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (2):
  docs: arm64: Document EL3 requirements for cpu debug architecture
  docs: arm64: Document EL3 requirements for FEAT_PMUv3

 Documentation/arch/arm64/booting.rst | 12 ++++++++++++
 1 file changed, 12 insertions(+)

-- 
2.30.2



From anshuman.khandual at arm.com  Tue Dec 10 22:54:25 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Dec 2024 12:24:25 +0530
Subject: [PATCH 2/2] docs: arm64: Document EL3 requirements for FEAT_PMUv3
In-Reply-To: <20241211065425.1106683-1-anshuman.khandual@arm.com>
References: <20241211065425.1106683-1-anshuman.khandual@arm.com>
Message-ID: <20241211065425.1106683-3-anshuman.khandual@arm.com>

This documents EL3 requirements for FEAT_PMUv3. The register field MDCR_EL3
.TPM needs to be cleared for accesses into PMU registers without any trap
being generated into EL3. PMUv3 registers like PMCCFILTR_EL0, PMCCNTR_EL0
PMCNTENCLR_EL0, PMCNTENSET_EL0, PMCR_EL0, PMEVCNTR<n>_EL0, PMEVTYPER<n>_EL0
etc are already being accessed for perf HW PMU implementation.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Jonathan Corbet <corbet at lwn.net>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arch/arm64/booting.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
index 1b3ac1394e5f..60b16f00d0a8 100644
--- a/Documentation/arch/arm64/booting.rst
+++ b/Documentation/arch/arm64/booting.rst
@@ -455,6 +455,12 @@ Before jumping into the kernel, the following conditions must be met:
 
    - MDCR_EL3.TDA (bit 9) must be initialized to 0b0
 
+ - For CPUs with FEAT_PMUv3:
+
+ - If EL3 is present:
+
+   - MDCR_EL3.TPM (bit 6) must be initialized to 0b0
+
 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 a.fatoum at pengutronix.de  Tue Dec 10 23:06:48 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Wed, 11 Dec 2024 08:06:48 +0100
Subject: [PATCH v4] i2c: imx: support DMA defer probing
In-Reply-To: <AM0PR0402MB39378417A496F13B201A1907E8312@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <20241127083818.2108201-1-carlos.song@nxp.com>
 <153e8e36-7b0e-4379-9cc3-6dacb5d705be@pengutronix.de>
 <AM0PR0402MB39370E69BC4B71C761EE8377E8282@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <6b39268b-7487-427d-aff5-f3ca3b2afd42@pengutronix.de>
 <AM0PR0402MB39378417A496F13B201A1907E8312@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <ff7b4769-245c-4c3b-9b15-b8f2c032d3c1@pengutronix.de>

Hi,

On 06.12.24 10:07, Carlos Song wrote:
>> -----Original Message-----
>> From: Ahmad Fatoum <a.fatoum at pengutronix.de>
>> Sent: Friday, December 6, 2024 2:50 AM
> Refer previous history:
> https://lore.kernel.org/linux-arm-kernel/6b39268b-7487-427d-aff5-f3ca3b2afd42 at pengutronix.de/


> Before replying to your question, I think we should synchronize SDMA and eDMA firstly.

[snip]

> SDMA initialization in i2c-imx driver:
> 
> +       dma->chan_tx = dma_request_chan(dev, "rx-tx");
> +       if (IS_ERR(dma->chan_tx)) {
> +               ret = PTR_ERR(dma->chan_tx);
> +               goto fail_dma;
> +       }
> +
> +       dma->chan_rx = dma->chan_tx;
> +       i2c_imx->dma = dma;
> 
> eDMA initialization in i2c-imx driver:
> 
> ...
> +       dma->chan_tx = dma_request_chan(dev, "tx");
> ....
> +       dma->chan_rx = dma_request_chan(dev, "rx");
> ....
>         i2c_imx->dma = dma;

Thanks for the clarification, I missed that.

> So if need to enable SDMA, should define a separate dma_request function and should not reuse the current i2c_imx_dma_request function.
> Also according to different platforms i2c-imx driver need to choose to use eDMA or SDMA.

Understood.

> So now we start to discuss about your confusion:
> 
>> My concern is this configuration:
>>
>>   - A user has eDMA/SDMA module or disabled, but enabled in DT
> [Carlos]:
> I delete edma channel at dts to disable eDMA before. It works in PIO mode.
> I also test your case : when enable dma channel in DT but disable eDMA module. It will meet error:
> 
> +++ b/arch/arm64/configs/defconfig
> ....
> -CONFIG_FSL_EDMA=y
> ....
> 
> root at ls1043ardb:~# dmesg | grep i2c
> [    4.697392] i2c_dev: i2c /dev entries driver
> [   18.357685] platform 2180000.i2c: deferred probe pending: (reason unknown)
> root at ls1043ardb:~# i2cdetect -y -l
> 
> The case you mentioned is completely inconsistent with the actual usage. Since you have defined the dma channel in dts, it means that you need to
> use DMA mode in i2c, but you disabled the eDMA module when building the Image. This makes no sense at all. I think this is a usage error.
> And the deferred probe pending error is predictable. Since there is no DMA driver loaded, I2C will keep defer probe and be hanged.

I (or rather the user) didn't knowingly define anything though. They just
used the upstream DT, which always enables the DMA nodes and it worked
fine without DMA support enabled in the config for years.
Now they update the kernel after your patches are merged and then the
I2C driver is no longer being probed.

> 
>>   - The I2C has a PMIC, which is needed for eMMC VCC
> [Carlos]:
> PMIC is critical for the whole board, so PMIC will finish all critical system power-on configuration(include eMMC VCC) in the uboot not at kernel.
> So pmic driver probe in kernel won't and shouldn't effect system boot.
> 
>>   - System startup is stuck or considerably delayed
>>
> The purpose of defer probe is to solve the problem of interdependence of module loading, and to try to load again after a while is to ensure that the required functions
> will not be unavailable because the resources are not ready. This delay is unavoidable. If a defer probe occurs, the first consideration should be to reasonably adjust the
> loading order of each module, rather than directly giving up the functions that should be enabled.

If I2C is a critical dependency, the system becomes unbootable instead of the
user just having to wait a little longer. To me that is a regression.

You clarified though that this is only for Layerscape, so the breakage is
more limited, because e.g. on LS1046A-RDB only EEPROM/sensors/RTC won't be
available and system should still be able to boot.

So while I am not yet convinced an equivalent of this change to be a good
idea for i.MX, which tends to have critical peripherals like PMIC on the
I2C, I don't object to it being done for Layerscape. You may add my:

Acked-by: Ahmad Fatoum <a.fatoum at pengutronix.de>

Cheers,
Ahmad

-- 
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 andyshrk at 163.com  Tue Dec 10 23:07:21 2024
From: andyshrk at 163.com (Andy Yan)
Date: Wed, 11 Dec 2024 15:07:21 +0800 (CST)
Subject: [PATCH v5 01/18] drm/rockchip: vop2: Add debugfs support
In-Reply-To: <4471861.MSiuQNM8U4@diego>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241209122943.2781431-4-andyshrk@163.com> <4471861.MSiuQNM8U4@diego>
Message-ID: <121ab3c0.68d0.193b48b32ed.Coremail.andyshrk@163.com>


Hi Heiko,

At 2024-12-10 19:57:44, "Heiko St?bner" <heiko at sntech.de> wrote:
>Hi Andy,
>
>Am Montag, 9. Dezember 2024, 13:29:13 CET schrieb Andy Yan:
>> From: Andy Yan <andy.yan at rock-chips.com>
>> 
>> /sys/kernel/debug/dri/vop2/summary:  dump vop display state
>> /sys/kernel/debug/dri/vop2/regs: dump whole vop registers
>> /sys/kernel/debug/dri/vop2/active_regs: only dump the registers of
>> activated modules
>> 
>> Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
>> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>> Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
>> Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
>> ---
>
>> +static void __vop2_regs_dump(struct seq_file *s, bool active_only)
>> +{
>> +	struct drm_info_node *node = s->private;
>> +	struct vop2 *vop2 = node->info_ent->data;
>> +	struct drm_minor *minor = node->minor;
>> +	struct drm_device *drm_dev = minor->dev;
>> +	const struct vop2_regs_dump *dump;
>> +	unsigned int i;
>> +
>> +	drm_modeset_lock_all(drm_dev);
>> +
>> +	regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
>> +
>> +	if (vop2->enable_count) {
>> +		for (i = 0; i < vop2->data->regs_dump_size; i++) {
>> +			dump = &vop2->data->regs_dump[i];
>> +			vop2_regs_print(vop2, s, dump, active_only);
>> +		}
>> +	} else {
>> +		seq_printf(s, "VOP disabled\n");
>> +	}
>> +	drm_modeset_unlock_all(drm_dev);
>> +
>
>nit: not needed empty line at the end of the function

Will fixed in V6.

>
>> +}
>> +
>
>> +static void vop2_debugfs_init(struct vop2 *vop2, struct drm_minor *minor)
>> +{
>> +	struct dentry *root;
>> +	unsigned int i;
>> +
>> +	root = debugfs_create_dir("vop2", minor->debugfs_root);
>> +	if (!IS_ERR(root)) {
>> +		for (i = 0; i < ARRAY_SIZE(vop2_debugfs_list); i++)
>> +			vop2_debugfs_list[i].data = vop2;
>> +
>> +		drm_debugfs_create_files(vop2_debugfs_list,
>> +					 ARRAY_SIZE(vop2_debugfs_list),
>> +					 root, minor);
>> +	}
>> +}
>> +
>> +static int vop2_crtc_late_register(struct drm_crtc *crtc)
>> +{
>> +	struct vop2_video_port *vp = to_vop2_video_port(crtc);
>> +	struct vop2 *vop2 = vp->vop2;
>> +
>> +	if (drm_crtc_index(crtc) == 0)
>> +		vop2_debugfs_init(vop2, crtc->dev->primary);
>> +
>> +	return 0;
>> +}
>
>I'm wondering about, shoudln't there be an unregister step too?
>I.e. the late_register callback says:
>"should be unregistered in the early_unregister callback" [0].
>
>And there exists drm_debugfs_remove_files(), though it doesn't
>seem t be used much - just by tegra.
>
>I haven't managed to find drm code handling that automatically though?

Did a little digging?
 rockchip_drm_unbind --?drm_dev_unregister(drm_dev)--?drm_debugfs_dev_fini
--?debugfs_remove_recursive(dev->debugfs_root);
This will remove all the debugfs file under /dri/0-->display-subsystem  when we
remove rockchipdrm when it build as module.
If it is builtin, whether we remove them seems to make no difference when we
reboot or thutdown the system ?
I also searched for other platforms using similar late register hook, and it seems they haven't remove debugfs  either.

>
>
>Heiko
>
>
>[0] https://elixir.bootlin.com/linux/v6.12.4/source/include/drm/drm_crtc.h#L737
>[1] https://elixir.bootlin.com/linux/v6.12.4/source/drivers/gpu/drm/drm_debugfs.c#L265
>

From peng.fan at nxp.com  Tue Dec 10 23:16:28 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 11 Dec 2024 07:16:28 +0000
Subject: [PATCH v3 0/6] Configure imx8mp dsp node for rproc usage
In-Reply-To: <20241210125338.104959-1-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
Message-ID: <PAXPR04MB8459FE7FA7114C0F272E3FD1883E2@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: [PATCH v3 0/6] Configure imx8mp dsp node for rproc usage
> 
> DSP found in i.MX8MP SOC can be used by multiple frameworks in
> order to enable various applications:
>         - rproc/rpmsg framework, used to load for example Zephyr
> samples
>         - Sound Open Firmware, used to enable various audio processing
>           pipelines.
> 
> Current dsp node was configured with SOF in mind but it doesn't work
> well with imx8mp-evk dts. SOF controls audio IPs from firmware side
> while imx8mp-evk preffers to control audio IPs from Linux side.
> 
> So, configure 'dsp' node to be used with rproc scenario and later will
> add a separate dts or an overlay to configure the node for SOF.
> 
> This patch series configures and enables dsp node to be used with
> rproc.
> 
> Changes since v1:
>         - document syscon compatible as pointed by Peng Fan
>         - do not disable dsp_reserved node in the dtsi file as pointed
>           by Ahmad Fatoum.
> Changes since v2:
>         - Fix dts example in patch 4/6
>         - Frank Li commented that we should handle the reset using the
> reset
>         interface. I have two objections on this: we are using some bits
> from audiomix
>         for reset together some other bits from DAP region. Also, the
> implementation is already upstream!
>         Frank Li agreed that it's up to Rob opinion on this.
> 
> Daniel Baluta (6):
>   arm64: dts: imx8mp: Add mu2 root clock
>   arm64: dts: imx8mp: Configure dsp node for rproc usage
>   arm64: dts: imx8mp: Add DSP clocks
>   dt-bindings: clock: imx8mp: Add syscon compatible
>   arm64: dts: imx8mp: Add fsl,dsp-ctrl property for dsp
>   arm64: dts: Add dsp rproc related mem regions
> 
>  .../bindings/clock/imx8mp-audiomix.yaml       |  6 +++--
>  arch/arm64/boot/dts/freescale/imx8mp-evk.dts  | 10 +++++++++
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi     | 22 ++++++++++++------
> -
>  3 files changed, 28 insertions(+), 10 deletions(-)
> 

Patchset looks good to me:

Reviewed-by: Peng Fan <peng.fan at nxp.com>


From wenst at chromium.org  Tue Dec 10 23:20:07 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 15:20:07 +0800
Subject: [PATCH v2] remoteproc: mtk_scp: Only populate devices for SCP cores
Message-ID: <20241211072009.120511-1-wenst@chromium.org>

When multi-core SCP support was added, the driver was made to populate
platform devices for all the sub-nodes. This ended up adding platform
devices for the rpmsg sub-nodes as well, which never actually get used,
since rpmsg devices are registered through the rpmsg interface.

Limit of_platform_populate() to just populating the SCP cores with a
compatible string match list.

Fixes: 1fdbf0cdde98 ("remoteproc: mediatek: Probe SCP cluster on multi-core SCP")
Cc: Tinghan Shen <tinghan.shen at mediatek.com>
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
Changes since v1:
- Fix commit subject: populate devices *for* SCP cores
---
 drivers/remoteproc/mtk_scp.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 0f4a7065d0bd..8206a1766481 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -1326,6 +1326,11 @@ static int scp_cluster_init(struct platform_device *pdev, struct mtk_scp_of_clus
 	return ret;
 }
 
+static const struct of_device_id scp_core_match[] = {
+	{ .compatible = "mediatek,scp-core" },
+	{}
+};
+
 static int scp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1357,13 +1362,15 @@ static int scp_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&scp_cluster->mtk_scp_list);
 	mutex_init(&scp_cluster->cluster_lock);
 
-	ret = devm_of_platform_populate(dev);
+	ret = of_platform_populate(dev_of_node(dev), scp_core_match, NULL, dev);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to populate platform devices\n");
 
 	ret = scp_cluster_init(pdev, scp_cluster);
-	if (ret)
+	if (ret) {
+		of_platform_depopulate(dev);
 		return ret;
+	}
 
 	return 0;
 }
@@ -1379,6 +1386,7 @@ static void scp_remove(struct platform_device *pdev)
 		rproc_del(scp->rproc);
 		scp_free(scp);
 	}
+	of_platform_depopulate(&pdev->dev);
 	mutex_destroy(&scp_cluster->cluster_lock);
 }
 
-- 
2.47.0.338.g60cca15819-goog



From kevin.tian at intel.com  Tue Dec 10 23:27:40 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 07:27:40 +0000
Subject: [PATCH v2 01/13] iommufd/fault: Add an iommufd_fault_init()
 helper
In-Reply-To: <3bc49512a42b88130cf447a7ac10acf5c02e056c.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <3bc49512a42b88130cf447a7ac10acf5c02e056c.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB5276A65935F9E6339FBA49918C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> 
> +static int iommufd_fault_init(struct iommufd_fault *fault, char *name,
> +			      struct iommufd_ctx *ictx)
> +{
> +	struct file *filep;
> +	int fdno;
> +
> +	fault->ictx = ictx;

while at it could you move this line behind iommufd_ctx_get(fault->ictx).
usually we want the two together.

Reviewed-by: Kevin Tian <kevin.tian at intel.com>


From dsimic at manjaro.org  Tue Dec 10 23:29:32 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 11 Dec 2024 08:29:32 +0100
Subject: [PATCH] arm64: dts: rockchip: Delete redundant RK3328 GMAC stability fixes
Message-ID: <e00f08d2351e82d6acd56271a68c7ed05b3362e8.1733901896.git.dsimic@manjaro.org>

Since the commit 8a469ee35606 ("arm64: dts: rockchip: Add txpbl node for
RK3399/RK3328"), having "snps,txpbl" properties defined as Ethernet stability
fixes in RK3328-based board dts(i) files is redundant, because that commit
added the required fix to the RK3328 SoC dtsi, so let's delete them.

It has been determined that the Ethernet stability fixes no longer require
the "snps,rxpbl" and "snps,aal" properties, [1] out of which the latter also
induces performance penalties, so let's delete these properties from the
relevant RK3328-based board dts(i) files.

This commit completes the removal of these redundant "snps,*" properties
that was started by a patch from Peter Geis. [2]

[1] https://lore.kernel.org/linux-rockchip/CAMdYzYpj3d7Rq0O0QjV4r6HEf_e07R0QAhPT2NheZdQV3TnQ6g at mail.gmail.com/
[2] https://lore.kernel.org/linux-rockchip/20241210013010.81257-7-pgwipeout at gmail.com/

Cc: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Dragan Simic <dsimic at manjaro.org>
---
 arch/arm64/boot/dts/rockchip/rk3328-a1.dts                | 1 -
 arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi        | 1 -
 arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 1 -
 arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts         | 3 ---
 4 files changed, 6 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
index 824183e515da..24baaa7f1d8c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
@@ -110,7 +110,6 @@ &gmac2io {
 	phy-supply = <&vcc_io>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&rgmiim1_pins>;
-	snps,aal;
 	snps,pbl = <0x4>;
 	tx_delay = <0x26>;
 	rx_delay = <0x11>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
index f9fab35aed23..d5f129e304e5 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
@@ -142,7 +142,6 @@ &gmac2io {
 	phy-supply = <&vcc_io_33>;
 	pinctrl-0 = <&rgmiim1_pins>;
 	pinctrl-names = "default";
-	snps,aal;
 
 	mdio {
 		compatible = "snps,dwmac-mdio";
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
index 181ec6de0019..9ec93f61433e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
@@ -113,7 +113,6 @@ &gmac2io {
 	phy-supply = <&vcc_io>;
 	pinctrl-0 = <&rgmiim1_pins>;
 	pinctrl-names = "default";
-	snps,aal;
 
 	mdio {
 		compatible = "snps,dwmac-mdio";
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
index 3e08e2fd0a78..59dead1cc503 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
@@ -153,9 +153,6 @@ &gmac2io {
 	phy-supply = <&vcc_io>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&rgmiim1_pins>;
-	snps,aal;
-	snps,rxpbl = <0x4>;
-	snps,txpbl = <0x4>;
 	tx_delay = <0x26>;
 	rx_delay = <0x11>;
 	status = "okay";


From kevin.tian at intel.com  Tue Dec 10 23:30:31 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 07:30:31 +0000
Subject: [PATCH v2 02/13] iommufd/fault: Move iommufd_fault_iopf_handler()
 to header
In-Reply-To: <137e3357f00b30a08c2b49c00b968a88af8cb5d1.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <137e3357f00b30a08c2b49c00b968a88af8cb5d1.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB5276473A92C8EA6C973415628C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> 
> The new vIRQ object will need a similar function for drivers to report the
> vIOMMU related interrupts. Split the common part out to a smaller helper,
> and place it in the header so that CONFIG_IOMMUFD_DRIVER_CORE can
> include
> that in the driver.c file for drivers to use.
> 
> Then keep iommufd_fault_iopf_handler() in the header too, since it's quite
> simple after all.
> 
> Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>

Reviewed-by: Kevin Tian <kevin.tian at intel.com>


From dsimic at manjaro.org  Tue Dec 10 23:33:00 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 11 Dec 2024 08:33:00 +0100
Subject: [PATCH 6/6] arm64: dts: rockchip: Remove address aligned beats
 from rk3328-roc
In-Reply-To: <6453e714b2a48572ff1e57cd74b0f6d3@manjaro.org>
References: <20241210013010.81257-1-pgwipeout@gmail.com>
 <20241210013010.81257-7-pgwipeout@gmail.com>
 <2b68c2dd3618e5904a4eac1ec87d29a7@manjaro.org>
 <CAMdYzYpj3d7Rq0O0QjV4r6HEf_e07R0QAhPT2NheZdQV3TnQ6g@mail.gmail.com>
 <6453e714b2a48572ff1e57cd74b0f6d3@manjaro.org>
Message-ID: <e30217fec525af2a3b0e9752b0d1ea31@manjaro.org>

On 2024-12-10 14:44, Dragan Simic wrote:
> On 2024-12-10 12:29, Peter Geis wrote:
>> On Tue, Dec 10, 2024 at 5:45?AM Dragan Simic <dsimic at manjaro.org> 
>> wrote:
>>> Thanks for the patch.  Please, see some comments below.
>>> 
>>> On 2024-12-10 02:30, Peter Geis wrote:
>>> > Since commit 8a469ee35606 ("arm64: dts: rockchip: Add txpbl node for
>>> > RK3399/RK3328"), the snps,aal, snps,txpbl, and snps,rxpbl nodes have
>>> > been unnecessary in the separate device trees. There is also a
>>> > performance loss to using snps,aal. Remove these from the rk3328-roc
>>> > device tree.
>>> >
>>> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>>> >
>>> > ---
>>> >
>>> >  arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi | 3 ---
>>> >  1 file changed, 3 deletions(-)
>>> >
>>> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
>>> > b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
>>> > index 6984387ff8b3..0d476cc2144d 100644
>>> > --- a/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
>>> > +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc.dtsi
>>> > @@ -155,12 +155,9 @@ &gmac2io {
>>> >       phy-mode = "rgmii";
>>> >       pinctrl-names = "default";
>>> >       pinctrl-0 = <&rgmiim1_pins>;
>>> > -     snps,aal;
>>> 
>>> Huh, I see that quite a few RK3328 board dts files specify
>>> the snps,aal node.  I wonder was it a "cargo cult" approach
>>> at play, :) or was there some real need for it?
>>> 
>>> Actually, I see now that you added snps,aal to rk3328-roc-
>>> cc.dts in the commit 393f3875c385 ("arm64: dts: rockchip:
>>> improve rk3328-roc-cc rgmii performance."), so I guess that
>>> your further research and testing showed that it actually
>>> isn't needed for Ethernet stability?
>>> 
>>> >       snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
>>> >       snps,reset-active-low;
>>> >       snps,reset-delays-us = <0 10000 50000>;
>>> > -     snps,rxpbl = <0x4>;
>>> > -     snps,txpbl = <0x4>;
>>> 
>>> Unless I'm missing something, the commit 8a469ee35606 ("arm64:
>>> dts: rockchip: Add txpbl node for RK3399/RK3328") doesn't add
>>> the snps,rxpbl node to the RK3328 SoC dtsi, and the respective
>>> driver does nothing about it when the snps,txpbl node is found.
>>> 
>>> Though, I see that rk3328-rock-pi-e.dts is the only other
>>> RK3328 board dts file that specifies the snps,rxpbl node, so
>>> it seems that removing the snps,rxpbl node here should be safe,
>>> especially because it was you who added it in the same commit
>>> mentioned above.  If there were some SoC-level issues, all
>>> RK3328 boards would've needed it.
>> 
>> Good Morning,
>> 
>> You'll notice the author of that patch was me. Setting aal, txpbl, and
>> rxpbl was the original fix I came up with for the rk3328, which I
>> applied to the only board I had. Someone else later on isolated it
>> specifically isolated it to just the txpbl and applied it to both the
>> rk3328 and rk3399 directly.
>> 
>> This was just something that was left hanging after that result.
>> 
>> Looking at how rk356x was done, I suspect there's an even more elegant
>> solution. However I don't have the deep level knowledge nor
>> documentation to implement it.
> 
> Sure, I noticed that you authored the original Ethernet stability
> fix. :)  With all this in mind, please feel free to include
> 
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> 
> and I'll prepare a patch or two that clean up any and all leftovers
> in other board dts(i) files.

For future reference, to help anyone going through the mailing-list
archive, here's a link to the above-mentioned cleanup patch:

https://lore.kernel.org/linux-rockchip/e00f08d2351e82d6acd56271a68c7ed05b3362e8.1733901896.git.dsimic at manjaro.org/T/#u


From quic_pkondeti at quicinc.com  Tue Dec 10 23:36:58 2024
From: quic_pkondeti at quicinc.com (Pavan Kondeti)
Date: Wed, 11 Dec 2024 13:06:58 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <CAF6AEGs4EebrwyQZviNXqB2=3h2wgZpmbrdGHuEU4z1D014GRA@mail.gmail.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>
 <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>
 <iyknardi445n4h74am22arpgc4vlchh6z6cvkbff2xg76pd655@nozwz7snt476>
 <1219b46d-2aea-4377-a8ca-024039ee1499@quicinc.com>
 <CAF6AEGs4EebrwyQZviNXqB2=3h2wgZpmbrdGHuEU4z1D014GRA@mail.gmail.com>
Message-ID: <b47d44cc-77b7-4137-97e3-b245e1394580@quicinc.com>

+devicetree

On Tue, Dec 10, 2024 at 07:43:19PM -0800, Rob Clark wrote:
> On Tue, Dec 10, 2024 at 7:08?PM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> >
> > On 12/11/2024 6:43 AM, Bjorn Andersson wrote:
> > > On Tue, Dec 10, 2024 at 02:22:27AM +0530, Akhil P Oommen wrote:
> > >> On 12/10/2024 1:24 AM, Rob Clark wrote:
> > >>> On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> > >>>>
> > >>>> When kernel is booted in EL2, SECVID registers are accessible to the
> > >>>> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> > >>>> on Zap firmware. Also, we can't load a secure firmware without a
> > >>>> hypervisor that supports it.
> > >>>
> > >>> Shouldn't we do this based on whether zap node is in dtb (and not disabled)?
> > >>
> > >> This is better, isn't it? Otherwise, multiple overlays should be
> > >> maintained for each soc/board since EL2 can be toggled from bootloader.
> > >> And this feature is likely going to be more widely available.
> > >>
> > >
> > > The DeviceTree passed to the OS needs to describe the world that said OS
> > > is going to operate in. If you change the world you need to change the
> > > description.
> > > There are several other examples where this would be necessary
> > > (remoteproc and watchdog to name two examples from the Qualcomm upstream
> > > world).
> >
> > But basic things work without those changes, right? For eg: Desktop UI
> 
> It isn't really so much about whether certain use-cases can work with
> a sub-optimal description of the hw (where in this case "hw" really
> means "hw plus how the fw allows things to look to the HLOS").. It is
> more about the hw/fw/whatever providing an accurate description of
> what things look like to the HLOS.
> 
> I'm leaning more towards the hw+fw providing HLOS an accurate view...
> and the fact that that carries over into other areas of dtb (ie. it
> isn't the only thing that slbounce needs to patch, as I previously
> mentioned) reinforces my view there.  This seems like a thing to fix
> in fw/bootloader tbh.
> 

Thanks Rob and Bjorn for your inputs. At the moment, we don't have
capability in our bootloader to apply a *specific* overlay when Linux
kernel is starteed in EL, this is making GPU non-functional. This patch
from Akhil fixes the problem without depending on the bootloader.

>From this discussion, I understand that it is recommended to provide
HW+FW view in dT correctly instead of doing runtime checks in the
kernel. We can take this as a requirement to the bootloader.

I would like to check how we should proceed with overlay. Should we
submit dtso upstream and let bootloader apply the overlay at runtime or
this whole overlay needs to be maintained in the bootloader. Also,
Should we build all board dtb for EL2 as well or just leave it at compiling
the EL2 dtbo (one per SoC)?

Thanks,
Pavan


From kevin.tian at intel.com  Tue Dec 10 23:40:52 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 07:40:52 +0000
Subject: [PATCH v2 03/13] iommufd: Rename IOMMUFD_OBJ_FAULT to
 IOMMUFD_OBJ_EVENTQ_IOPF
In-Reply-To: <2e2dc5c9cd8013147d4a8ee0d6c9d59c9ebe1954.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <2e2dc5c9cd8013147d4a8ee0d6c9d59c9ebe1954.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB5276F92171A516C2A17839458C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> 
> The fault object was designed exclusively for hwpt's IO page faults (PRI).
> But its implementation can actually be reused for other purposes too, such
> as hardware IRQ and event injections to user space.
> 
> Meanwhile, a fault object holds a list of faults. So it's more accurate to
> call it a "fault queue". Combining the reusing idea above, a "fault queue"
> can further rephrase to an "Event Queue for IOPF".
> 
> Rename the struct iommufd_fault to struct iommufd_eventq_iopf that holds
> a
> common Event Queue struct, similar to hwpt_paging holding a common
> hwpt.
> 
> Roll out a minimal level of renamings to all the related functions.

could we keep iommufd_fault? Internally it will use the new eventq
common struct but external facing names are all still around fault.
the size of changed lines will be much smaller.

Then later for virq it could be iommufd_viommu_virq instead of
iommufd_eventq_virq to explicitly draw its connection to viommu.

this is unlike hwpt where 'paging' or 'nested' is just decorative while
'fault' or 'virq' is noun on its own. 

> +static ssize_t iommufd_eventq_fops_read(struct file *filep, char __user *buf,
> +					size_t count, loff_t *ppos)
> +{
> +	struct iommufd_eventq *eventq = filep->private_data;
> +
> +	if (!eventq->ops || !eventq->ops->read)
> +		return -EOPNOTSUPP;
> +	return eventq->ops->read(eventq, buf, count, ppos);
> +}

the check on ops can be done in iommufd_eventq_init()


From victor.liu at nxp.com  Tue Dec 10 23:43:20 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Wed, 11 Dec 2024 15:43:20 +0800
Subject: [PATCH v6 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <3j4fguv4oienfaj4fghpiqpmnq3aczu4azhdo5jzvywc5mawm5@hh33p3dhf6xa>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
 <20241209033923.3009629-13-victor.liu@nxp.com>
 <3j4fguv4oienfaj4fghpiqpmnq3aczu4azhdo5jzvywc5mawm5@hh33p3dhf6xa>
Message-ID: <db4d9d4e-855f-4647-9b93-ccc5ec0202b3@nxp.com>

On 12/10/2024, Dmitry Baryshkov wrote:
> On Mon, Dec 09, 2024 at 11:39:16AM +0800, Liu Ying wrote:
>> i.MX8qxp Display Controller(DC) is comprised of three main components that
>> include a blit engine for 2D graphics accelerations, display controller for
>> display output processing, as well as a command sequencer.  Add kernel
>> mode setting support for the display controller part with two CRTCs and
>> two primary planes(backed by FetchLayer and FetchWarp respectively).  The
>> registers of the display controller are accessed without command sequencer
>> involved, instead just by using CPU.  The command sequencer is supposed to
>> be used by the blit engine.
>>
>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>> ---
>> v6:
>> * No change.
>>
>> v5:
>> * Replace .remove_new with .remove in dc-drv.c. (Uwe)
>>
>> v4:
>> * Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
>>   function calls from KMS routine to initialization stage. (Dmitry)
>> * Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
>>   appropriate .h header files or .c source files. (Dmitry)
>> * Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
>> * Drop dc_drm->pe_rpm_count. (Dmitry)
>> * Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
>> * Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
>>   Instead, put it in struct dc_crtc.  (Dmitry)
>> * Call devm_request_irq() to request IRQs, instead of using drmm action.
>>   (Dmitry)
>> * Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
>> * Select DRM_CLIENT_SELECTION due to rebase.
>> * Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
>> * Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
>> * Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
>>   rebase.
>> * Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
>>   register dc_drm_component_unbind_all() action.
>> * Request interrupts in dc_crtc_post_init() after encoder initialization to
>>   make sure next bridge is found first.
>>
>> v3:
>> * No change.
>>
>> v2:
>> * Find next bridge from TCon's port.
>> * Drop drm/drm_module.h include from dc-drv.c.
>>
>>  drivers/gpu/drm/imx/dc/Kconfig    |   5 +
>>  drivers/gpu/drm/imx/dc/Makefile   |   5 +-
>>  drivers/gpu/drm/imx/dc/dc-crtc.c  | 558 ++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
>>  drivers/gpu/drm/imx/dc/dc-drv.c   | 244 +++++++++++++
>>  drivers/gpu/drm/imx/dc/dc-drv.h   |  19 +
>>  drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
>>  drivers/gpu/drm/imx/dc/dc-kms.h   |  58 ++++
>>  drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
>>  9 files changed, 1274 insertions(+), 2 deletions(-)
>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
>>
>> diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
>> index 1fc84c7475de..415993207f2e 100644
>> --- a/drivers/gpu/drm/imx/dc/Kconfig
>> +++ b/drivers/gpu/drm/imx/dc/Kconfig
>> @@ -1,6 +1,11 @@
>>  config DRM_IMX8_DC
>>  	tristate "Freescale i.MX8 Display Controller Graphics"
>>  	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
>> +	select DRM_CLIENT_SELECTION
>> +	select DRM_GEM_DMA_HELPER
>> +	select DRM_KMS_HELPER
>> +	select DRM_DISPLAY_HELPER
>> +	select DRM_BRIDGE_CONNECTOR
>>  	select GENERIC_IRQ_CHIP
>>  	select REGMAP
>>  	select REGMAP_MMIO
>> diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
>> index 1ce3e8a8db22..b9d33c074984 100644
>> --- a/drivers/gpu/drm/imx/dc/Makefile
>> +++ b/drivers/gpu/drm/imx/dc/Makefile
>> @@ -1,6 +1,7 @@
>>  # SPDX-License-Identifier: GPL-2.0
>>  
>> -imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
>> -		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
>> +imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
>> +		    dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
>> +		    dc-plane.o dc-tc.o
>>  
>>  obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
>> diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
>> new file mode 100644
>> index 000000000000..fd6daa1807d8
>> --- /dev/null
>> +++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
>> @@ -0,0 +1,558 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright 2024 NXP
>> + */
>> +
>> +#include <linux/completion.h>
>> +#include <linux/container_of.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/irqreturn.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/spinlock.h>
>> +
>> +#include <drm/drm_atomic.h>
>> +#include <drm/drm_atomic_helper.h>
>> +#include <drm/drm_atomic_state_helper.h>
>> +#include <drm/drm_crtc.h>
>> +#include <drm/drm_device.h>
>> +#include <drm/drm_drv.h>
>> +#include <drm/drm_modes.h>
>> +#include <drm/drm_modeset_helper_vtables.h>
>> +#include <drm/drm_plane.h>
>> +#include <drm/drm_print.h>
>> +#include <drm/drm_vblank.h>
>> +
>> +#include "dc-de.h"
>> +#include "dc-drv.h"
>> +#include "dc-kms.h"
>> +#include "dc-pe.h"
>> +
>> +#define dc_crtc_dbg(crtc, fmt, ...)					\
>> +do {									\
>> +	typeof(crtc) _crtc = (crtc);					\
> 
> Use exact type instead of typeof.

Will do.

> 
>> +	drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
>> +		    _crtc->base.id, _crtc->name, ##__VA_ARGS__);	\
>> +} while (0)
>> +
>> +#define dc_crtc_err(crtc, fmt, ...)					\
>> +do {									\
>> +	typeof(crtc) _crtc = (crtc);					\
>> +	drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
>> +		_crtc->base.id, _crtc->name, ##__VA_ARGS__);		\
>> +} while (0)
>> +
>> +#define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c)				\
>> +do {									\
>> +	unsigned long ret;						\
>> +	ret = wait_for_completion_timeout(&dc_crtc->c, HZ);		\
>> +	if (ret == 0)							\
>> +		dc_crtc_err(crtc, "%s: wait for " #c " timeout\n",	\
>> +							__func__);	\
>> +} while (0)
>> +
>> +#define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg)					\
>> +do {									\
>> +	typeof(fg) _fg = (fg);						\
>> +	if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) {		\
>> +		dc_fg_secondary_clear_channel_status(_fg);		\
>> +		dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n",		\
>> +							__func__);	\
>> +	}								\
>> +} while (0)
>> +
>> +#define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg)			\
>> +do {									\
>> +	if (dc_fg_wait_for_secondary_syncup(fg))			\
>> +		dc_crtc_err(crtc,					\
>> +			"%s: FrameGen secondary channel isn't syncup\n",\
>> +							__func__);	\
>> +} while (0)
>> +
>> +static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
>> +{
>> +	return container_of(crtc, struct dc_crtc, base);
>> +}
>> +
>> +static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
>> +{
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +
>> +	return dc_fg_get_frame_index(dc_crtc->fg);
>> +}
>> +
>> +static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
>> +{
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +
>> +	enable_irq(dc_crtc->irq_dec_framecomplete);
>> +
>> +	return 0;
>> +}
>> +
>> +static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
>> +{
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +
>> +	disable_irq_nosync(dc_crtc->irq_dec_framecomplete);
> 
> Why is it _nosync?

Because disable_irq() can only be called from preemptible code according to
it's kerneldoc. If I use disable_irq() here, I get this with
CONFIG_DEBUG_ATOMIC_SLEEP enabled:

[   50.607503] BUG: sleeping function called from invalid context at kernel/irq/manage.c:738
[   50.615691] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/0
[   50.623527] preempt_count: 10003, expected: 0
[   50.627888] RCU nest depth: 0, expected: 0
[   50.631993] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.13.0-rc2-next-20241209-00026-g800cb5b7df74 #1407
[   50.642092] Hardware name: Freescale i.MX8QXP MEK (DT)
[   50.647237] Call trace:
[   50.649687]  show_stack+0x18/0x24 (C)
[   50.653369]  dump_stack_lvl+0x80/0xb4
[   50.657043]  dump_stack+0x18/0x24
[   50.660370]  __might_resched+0x114/0x170
[   50.664306]  __might_sleep+0x48/0x98
[   50.667894]  disable_irq+0x24/0x60
[   50.671308]  dc_crtc_disable_vblank+0x14/0x20 [imx8_dc_drm]
[   50.676912]  drm_vblank_disable_and_save+0xc0/0x108 [drm]
[   50.682533]  vblank_disable_fn+0x78/0x9c [drm]
[   50.687146]  drm_handle_vblank+0x238/0x2e8 [drm]
[   50.691932]  drm_crtc_handle_vblank+0x1c/0x28 [drm]
[   50.696980]  dc_crtc_irq_handler_dec_framecomplete+0x1c/0x6c [imx8_dc_drm]
[   50.703886]  __handle_irq_event_percpu+0x60/0x14c
[   50.708604]  handle_irq_event+0x4c/0xac
[   50.712443]  handle_level_irq+0xc0/0x1b0
[   50.716379]  generic_handle_irq+0x34/0x4c
[   50.720392]  dc_ic_irq_handler+0x128/0x160 [imx8_dc_drm]
[   50.725727]  generic_handle_domain_irq+0x2c/0x44
[   50.730357]  imx_irqsteer_irq_handler+0xc0/0x1a0
[   50.734987]  generic_handle_domain_irq+0x2c/0x44
[   50.739609]  gic_handle_irq+0x4c/0x114
[   50.743362]  call_on_irq_stack+0x24/0x4c
[   50.747298]  do_interrupt_handler+0x80/0x84
[   50.751494]  el1_interrupt+0x34/0x68
[   50.755082]  el1h_64_irq_handler+0x18/0x24
[   50.759191]  el1h_64_irq+0x6c/0x70
[   50.762597]  default_idle_call+0x28/0x3c (P)
[   50.766879]  default_idle_call+0x24/0x3c (L)
[   50.771163]  do_idle+0x200/0x25c
[   50.774403]  cpu_startup_entry+0x34/0x3c
[   50.778338]  kernel_init+0x0/0x1d8
[   50.781752]  start_kernel+0x5c4/0x70c
[   50.785427]  __primary_switched+0x88/0x90

> 
>> +}
>> +
>> +static irqreturn_t
>> +dc_crtc_dec_framecomplete_irq_handler(int irq, void *dev_id)
>> +{
>> +	struct dc_crtc *dc_crtc = dev_id;
>> +	struct drm_crtc *crtc = &dc_crtc->base;
>> +	unsigned long flags;
>> +
>> +	drm_crtc_handle_vblank(crtc);
>> +
>> +	spin_lock_irqsave(&crtc->dev->event_lock, flags);
>> +	if (dc_crtc->event) {
>> +		drm_crtc_send_vblank_event(crtc, dc_crtc->event);
>> +		dc_crtc->event = NULL;
>> +		drm_crtc_vblank_put(crtc);
>> +	}
>> +	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>> +static irqreturn_t dc_crtc_common_irq_handler(int irq, void *dev_id)
>> +{
>> +	struct dc_crtc *dc_crtc = dev_id;
>> +
>> +	if (irq == dc_crtc->irq_dec_seqcomplete)
>> +		complete(&dc_crtc->dec_seqcomplete_done);
>> +	else if (irq == dc_crtc->irq_dec_shdld)
>> +		complete(&dc_crtc->dec_shdld_done);
>> +	else if (irq == dc_crtc->irq_ed_cont_shdld)
>> +		complete(&dc_crtc->ed_cont_shdld_done);
>> +	else if (irq == dc_crtc->irq_ed_safe_shdld)
>> +		complete(&dc_crtc->ed_safe_shdld_done);
> 
> Is there any reason to have a single multiplex handler instead of having
> 4 separate handlers, each doing one simple thing?

Just thought that one irq handler is feasible to implement the common
handling logic. It's also ok to use 4 separate handlers with a little
performance improvement. I may change to use 4 separate handlers by
introducing a DEFINE_DC_CRTC_IRQ_HANDLER() marco.

> 
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>> +static const struct drm_crtc_funcs dc_crtc_funcs = {
>> +	.reset			= drm_atomic_helper_crtc_reset,
>> +	.destroy		= drm_crtc_cleanup,
>> +	.set_config		= drm_atomic_helper_set_config,
>> +	.page_flip		= drm_atomic_helper_page_flip,
>> +	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
>> +	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
>> +	.get_vblank_counter	= dc_crtc_get_vblank_counter,
>> +	.enable_vblank		= dc_crtc_enable_vblank,
>> +	.disable_vblank		= dc_crtc_disable_vblank,
>> +	.get_vblank_timestamp	= drm_crtc_vblank_helper_get_vblank_timestamp,
>> +};
>> +
>> +static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
>> +{
>> +	struct drm_crtc *crtc = crtc_state->crtc;
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +
>> +	spin_lock_irq(&crtc->dev->event_lock);
>> +	if (crtc_state->event) {
>> +		WARN_ON(drm_crtc_vblank_get(crtc));
>> +		WARN_ON(dc_crtc->event);
>> +		dc_crtc->event = crtc_state->event;
>> +		crtc_state->event = NULL;
>> +	}
>> +	spin_unlock_irq(&crtc->dev->event_lock);
>> +}
>> +
>> +static enum drm_mode_status
>> +dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
>> +{
>> +	return dc_fg_check_clock(dc_crtc->fg, clk_khz);
>> +}
> 
> inline

Will do.

> 
>> +
>> +static enum drm_mode_status
>> +dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
>> +{
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +	enum drm_mode_status status;
>> +
>> +	status = dc_crtc_check_clock(dc_crtc, mode->clock);
>> +	if (status != MODE_OK)
>> +		return status;
>> +
>> +	if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
>> +		return MODE_CLOCK_HIGH;
>> +
>> +	return MODE_OK;
>> +}
>> +
>> +static int
>> +dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
>> +{
>> +	struct drm_crtc_state *new_crtc_state =
>> +				drm_atomic_get_new_crtc_state(state, crtc);
>> +	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +	enum drm_mode_status status;
>> +
>> +	status = dc_crtc_check_clock(dc_crtc, adj->clock);
>> +	if (status != MODE_OK)
>> +		return -EINVAL;
>> +
>> +	return 0;
>> +}
>> +
>> +static void
>> +dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
>> +{
>> +	struct drm_crtc_state *new_crtc_state =
>> +				drm_atomic_get_new_crtc_state(state, crtc);
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +	int idx, ret;
>> +
>> +	if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
>> +	    !new_crtc_state->active)
>> +		return;
>> +
>> +	if (!drm_dev_enter(crtc->dev, &idx))
>> +		return;
>> +
>> +	/* request pixel engine power-on when CRTC starts to be active */
>> +	ret = pm_runtime_resume_and_get(dc_crtc->pe->dev);
>> +	if (ret)
>> +		dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
>> +			    ret);
>> +
>> +	drm_dev_exit(idx);
>> +}
>> +
>> +static void
>> +dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
>> +{
>> +	struct drm_crtc_state *old_crtc_state =
>> +				drm_atomic_get_old_crtc_state(state, crtc);
>> +	struct drm_crtc_state *new_crtc_state =
>> +				drm_atomic_get_new_crtc_state(state, crtc);
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +	int idx;
>> +
>> +	if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
>> +	    (!old_crtc_state->active && !new_crtc_state->active))
>> +		return;
>> +
>> +	if (!drm_dev_enter(crtc->dev, &idx))
>> +		goto out;
>> +
>> +	enable_irq(dc_crtc->irq_ed_cont_shdld);
>> +
>> +	/* flush plane update out to display */
>> +	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
>> +
>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
>> +
>> +	disable_irq(dc_crtc->irq_ed_cont_shdld);
>> +
>> +	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
>> +
>> +	drm_dev_exit(idx);
>> +
>> +out:
>> +	dc_crtc_queue_state_event(new_crtc_state);
>> +}
>> +
>> +static void
>> +dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
>> +{
>> +	struct drm_crtc_state *new_crtc_state =
>> +				drm_atomic_get_new_crtc_state(state, crtc);
>> +	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +	enum dc_link_id cf_link;
>> +	int idx, ret;
>> +
>> +	dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
>> +
>> +	drm_crtc_vblank_on(crtc);
>> +
>> +	if (!drm_dev_enter(crtc->dev, &idx))
>> +		goto out;
>> +
>> +	/* request display engine power-on when CRTC is enabled */
>> +	ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
>> +	if (ret < 0)
>> +		dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
>> +			    ret);
>> +
>> +	enable_irq(dc_crtc->irq_dec_shdld);
>> +	enable_irq(dc_crtc->irq_ed_cont_shdld);
>> +	enable_irq(dc_crtc->irq_ed_safe_shdld);
>> +
>> +	dc_fg_cfg_videomode(dc_crtc->fg, adj);
>> +
>> +	dc_cf_framedimensions(dc_crtc->cf_cont,
>> +			      adj->crtc_hdisplay, adj->crtc_vdisplay);
>> +	dc_cf_framedimensions(dc_crtc->cf_safe,
>> +			      adj->crtc_hdisplay, adj->crtc_vdisplay);
>> +
>> +	/* constframe in safety stream shows blue frame */
>> +	dc_cf_constantcolor_blue(dc_crtc->cf_safe);
>> +	cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
>> +	dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
>> +
>> +	/* show CRTC background if no plane is enabled */
>> +	if (new_crtc_state->plane_mask == 0) {
>> +		/* constframe in content stream shows black frame */
>> +		dc_cf_constantcolor_black(dc_crtc->cf_cont);
>> +
>> +		cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
>> +		dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
>> +	}
>> +
>> +	dc_fg_enable_clock(dc_crtc->fg);
>> +	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
>> +	dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
>> +	dc_fg_shdtokgen(dc_crtc->fg);
>> +	dc_fg_enable(dc_crtc->fg);
>> +
>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdld_done);
>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdld_done);
>> +
>> +	disable_irq(dc_crtc->irq_ed_safe_shdld);
>> +	disable_irq(dc_crtc->irq_ed_cont_shdld);
>> +	disable_irq(dc_crtc->irq_dec_shdld);
>> +
>> +	DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
>> +
>> +	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
>> +
>> +	drm_dev_exit(idx);
>> +
>> +out:
>> +	dc_crtc_queue_state_event(new_crtc_state);
>> +}
>> +
>> +static void
>> +dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
>> +{
>> +	struct drm_crtc_state *new_crtc_state =
>> +				drm_atomic_get_new_crtc_state(state, crtc);
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +	int idx, ret;
>> +
>> +	if (!drm_dev_enter(crtc->dev, &idx))
>> +		goto out;
>> +
>> +	enable_irq(dc_crtc->irq_dec_seqcomplete);
>> +	dc_fg_disable(dc_crtc->fg);
>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
>> +	disable_irq(dc_crtc->irq_dec_seqcomplete);
>> +
>> +	dc_fg_disable_clock(dc_crtc->fg);
>> +
>> +	/* request pixel engine power-off as plane is off too */
>> +	ret = pm_runtime_put(dc_crtc->pe->dev);
>> +	if (ret)
>> +		dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
>> +			    ret);
>> +
>> +	/* request display engine power-off when CRTC is disabled */
>> +	ret = pm_runtime_put(dc_crtc->de->dev);
> 
> Can this be expressed as a devlink between PE and DE?

Looking at struct dc_{pe,de}, PE and DE are not dependent with each other,
i.e., no consumer/supplier relationship(note that blit engine in PE can work
by itself without DE) between them. So, it doesn't look right to link the two
devices.

> 
>> +	if (ret < 0)
>> +		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
>> +			    ret);
>> +
>> +	drm_dev_exit(idx);
>> +
>> +out:
>> +	drm_crtc_vblank_off(crtc);
>> +
>> +	spin_lock_irq(&crtc->dev->event_lock);
>> +	if (new_crtc_state->event && !new_crtc_state->active) {
>> +		drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
>> +		new_crtc_state->event = NULL;
>> +	}
>> +	spin_unlock_irq(&crtc->dev->event_lock);
>> +}
>> +
>> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc)
>> +{
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +	int ret;
>> +
>> +	if (!dc_fg_wait_for_frame_index_moving(dc_crtc->fg))
>> +		return;
>> +
>> +	dc_fg_disable_clock(dc_crtc->fg);
>> +
>> +	if (pm_runtime_active(dc_crtc->pe->dev)) {
>> +		ret = pm_runtime_put_sync(dc_crtc->pe->dev);
>> +		if (ret)
>> +			dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
>> +				    ret);
>> +	}
>> +
>> +	ret = pm_runtime_put_sync(dc_crtc->de->dev);
>> +	if (ret < 0)
>> +		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
>> +			    ret);
>> +}
>> +
>> +static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
>> +					 bool in_vblank_irq,
>> +					 int *vpos, int *hpos,
>> +					 ktime_t *stime, ktime_t *etime,
>> +					 const struct drm_display_mode *mode)
>> +{
>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> +	int vdisplay = mode->crtc_vdisplay;
>> +	int vtotal = mode->crtc_vtotal;
>> +	bool reliable;
>> +	int line;
>> +	int idx;
>> +
>> +	if (stime)
>> +		*stime = ktime_get();
>> +
>> +	if (!drm_dev_enter(crtc->dev, &idx)) {
>> +		reliable = false;
>> +		*vpos = 0;
>> +		*hpos = 0;
>> +		goto out;
>> +	}
>> +
>> +	/* line index starts with 0 for the first active output line */
>> +	line = dc_fg_get_line_index(dc_crtc->fg);
>> +
>> +	if (line < vdisplay)
>> +		/* active scanout area - positive */
>> +		*vpos = line + 1;
>> +	else
>> +		/* inside vblank - negative */
>> +		*vpos = line - (vtotal - 1);
>> +
>> +	*hpos = 0;
>> +
>> +	reliable = true;
>> +
>> +	drm_dev_exit(idx);
>> +out:
>> +	if (etime)
>> +		*etime = ktime_get();
>> +
>> +	return reliable;
>> +}
>> +
>> +static const struct drm_crtc_helper_funcs dc_helper_funcs = {
>> +	.mode_valid		= dc_crtc_mode_valid,
>> +	.atomic_check		= dc_crtc_atomic_check,
>> +	.atomic_begin		= dc_crtc_atomic_begin,
>> +	.atomic_flush		= dc_crtc_atomic_flush,
>> +	.atomic_enable		= dc_crtc_atomic_enable,
>> +	.atomic_disable		= dc_crtc_atomic_disable,
>> +	.get_scanout_position	= dc_crtc_get_scanout_position,
>> +};
>> +
>> +static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
>> +{
>> +	struct {
>> +		struct device *dev;
>> +		unsigned int irq;
>> +		irqreturn_t (*irq_handler)(int irq, void *dev_id);
>> +	} irqs[DC_CRTC_IRQS] = {
>> +		{
>> +			dc_crtc->de->dev,
>> +			dc_crtc->irq_dec_framecomplete,
>> +			dc_crtc_dec_framecomplete_irq_handler,
>> +		}, {
>> +			dc_crtc->de->dev,
>> +			dc_crtc->irq_dec_seqcomplete,
>> +			dc_crtc_common_irq_handler,
>> +		}, {
>> +			dc_crtc->de->dev,
>> +			dc_crtc->irq_dec_shdld,
>> +			dc_crtc_common_irq_handler,
>> +		}, {
>> +			dc_crtc->ed_cont->dev,
>> +			dc_crtc->irq_ed_cont_shdld,
>> +			dc_crtc_common_irq_handler,
>> +		}, {
>> +			dc_crtc->ed_safe->dev,
>> +			dc_crtc->irq_ed_safe_shdld,
>> +			dc_crtc_common_irq_handler,
>> +		},
>> +	};
>> +	int i, ret;
>> +
>> +	for (i = 0; i < DC_CRTC_IRQS; i++) {
>> +		struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
>> +
>> +		ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
>> +				       irqs[i].irq_handler, IRQF_NO_AUTOEN,
>> +				       dev_name(irqs[i].dev), dc_crtc);
>> +		if (ret) {
>> +			dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
>> +				irqs[i].irq, ret);
>> +			return ret;
>> +		}
>> +
>> +		irq->dc_crtc = dc_crtc;
>> +		irq->irq = irqs[i].irq;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
>> +{
>> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
>> +	struct drm_device *drm = &dc_drm->base;
>> +	struct dc_de *de = dc_drm->de[crtc_index];
>> +	struct dc_pe *pe = dc_drm->pe;
>> +	struct dc_plane *dc_primary;
>> +	int ret;
>> +
>> +	dc_crtc->de = de;
>> +	dc_crtc->pe = pe;
>> +
>> +	init_completion(&dc_crtc->dec_seqcomplete_done);
>> +	init_completion(&dc_crtc->dec_shdld_done);
>> +	init_completion(&dc_crtc->ed_cont_shdld_done);
>> +	init_completion(&dc_crtc->ed_safe_shdld_done);
>> +
>> +	dc_crtc->cf_cont = pe->cf_cont[crtc_index];
>> +	dc_crtc->cf_safe = pe->cf_safe[crtc_index];
>> +	dc_crtc->ed_cont = pe->ed_cont[crtc_index];
>> +	dc_crtc->ed_safe = pe->ed_safe[crtc_index];
>> +	dc_crtc->fg = de->fg;
>> +
>> +	dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
>> +	dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
>> +	dc_crtc->irq_dec_shdld = de->irq_shdld;
>> +	dc_crtc->irq_ed_safe_shdld = dc_crtc->ed_safe->irq_shdld;
>> +	dc_crtc->irq_ed_cont_shdld = dc_crtc->ed_cont->irq_shdld;
>> +
>> +	dc_primary = &dc_drm->dc_primary[crtc_index];
>> +	ret = dc_plane_init(dc_drm, dc_primary);
>> +	if (ret) {
>> +		dev_err(drm->dev,
>> +			"failed to init primary plane for display engine%u: %d\n",
>> +			de->id, ret);
>> +		return ret;
>> +	}
>> +
>> +	drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
>> +
>> +	ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
>> +					NULL, &dc_crtc_funcs, NULL);
>> +	if (ret)
>> +		dev_err(drm->dev,
>> +			"failed to add CRTC for display engine%u: %d\n",
>> +			de->id, ret);
>> +
>> +	return ret;
>> +}
>> +
>> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
>> +{
>> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
>> +	struct drm_device *drm = &dc_drm->base;
>> +
>> +	return dc_crtc_request_irqs(drm, dc_crtc);
>> +}
>> diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
>> index 17a44362118e..8a7b6c03a222 100644
>> --- a/drivers/gpu/drm/imx/dc/dc-de.h
>> +++ b/drivers/gpu/drm/imx/dc/dc-de.h
>> @@ -13,6 +13,9 @@
>>  
>>  #define DC_DISPLAYS	2
>>  
>> +#define DC_FRAMEGEN_MAX_FRAME_INDEX	0x3ffff
>> +#define DC_FRAMEGEN_MAX_CLOCK_KHZ	300000
>> +
>>  struct dc_fg {
>>  	struct device *dev;
>>  	struct regmap *reg;
>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
>> index fd68861f770a..1e4b8afa3eec 100644
>> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
>> @@ -3,11 +3,254 @@
>>   * Copyright 2024 NXP
>>   */
>>  
>> +#include <linux/clk.h>
>> +#include <linux/component.h>
>> +#include <linux/device.h>
>> +#include <linux/dma-mapping.h>
>> +#include <linux/mod_devicetable.h>
>>  #include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_platform.h>
>>  #include <linux/platform_device.h>
>> +#include <linux/pm.h>
>> +#include <linux/pm_runtime.h>
>>  
>> +#include <drm/drm_atomic_helper.h>
>> +#include <drm/drm_client_setup.h>
>> +#include <drm/drm_crtc.h>
>> +#include <drm/drm_drv.h>
>> +#include <drm/drm_fbdev_dma.h>
>> +#include <drm/drm_fourcc.h>
>> +#include <drm/drm_gem_dma_helper.h>
>> +#include <drm/drm_managed.h>
>> +#include <drm/drm_modeset_helper.h>
>> +#include <drm/drm_of.h>
>> +
>> +#include "dc-de.h"
>>  #include "dc-drv.h"
>>  
>> +struct dc_priv {
>> +	struct drm_device *drm;
>> +	struct clk *clk_cfg;
>> +};
>> +
>> +DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
>> +
>> +static struct drm_driver dc_drm_driver = {
>> +	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
>> +	DRM_GEM_DMA_DRIVER_OPS,
>> +	DRM_FBDEV_DMA_DRIVER_OPS,
>> +	.fops = &dc_drm_driver_fops,
>> +	.name = "imx8-dc",
>> +	.desc = "i.MX8 DC DRM graphics",
>> +	.date = "20240530",
>> +	.major = 1,
>> +	.minor = 0,
>> +	.patchlevel = 0,
>> +};
>> +
>> +static void
>> +dc_add_components(struct device *dev, struct component_match **matchptr)
>> +{
>> +	struct device_node *child, *grandchild;
>> +
>> +	for_each_available_child_of_node(dev->of_node, child) {
>> +		/* The interrupt controller is not a component. */
>> +		if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
>> +			continue;
>> +
>> +		drm_of_component_match_add(dev, matchptr, component_compare_of,
>> +					   child);
>> +
>> +		for_each_available_child_of_node(child, grandchild)
>> +			drm_of_component_match_add(dev, matchptr,
>> +						   component_compare_of,
>> +						   grandchild);
>> +	}
>> +}
>> +
>> +static void dc_drm_component_unbind_all(void *ptr)
>> +{
>> +	struct dc_drm_device *dc_drm = ptr;
>> +	struct drm_device *drm = &dc_drm->base;
>> +
>> +	component_unbind_all(drm->dev, dc_drm);
>> +}
>> +
>> +static int dc_drm_bind(struct device *dev)
>> +{
>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>> +	struct dc_drm_device *dc_drm;
>> +	struct drm_device *drm;
>> +	int ret;
>> +
>> +	dc_drm = devm_drm_dev_alloc(dev, &dc_drm_driver, struct dc_drm_device,
>> +				    base);
>> +	if (IS_ERR(dc_drm))
>> +		return PTR_ERR(dc_drm);
>> +
>> +	drm = &dc_drm->base;
>> +
>> +	ret = component_bind_all(dev, dc_drm);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = devm_add_action_or_reset(dev, dc_drm_component_unbind_all,
>> +				       dc_drm);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = dc_kms_init(dc_drm);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = drm_dev_register(drm, 0);
>> +	if (ret) {
>> +		dev_err(dev, "failed to register drm device: %d\n", ret);
>> +		goto err;
>> +	}
>> +
>> +	drm_client_setup_with_fourcc(drm, DRM_FORMAT_XRGB8888);
>> +
>> +	priv->drm = drm;
>> +
>> +	return 0;
>> +
>> +err:
>> +	dc_kms_uninit(dc_drm);
>> +
>> +	return ret;
>> +}
>> +
>> +static void dc_drm_unbind(struct device *dev)
>> +{
>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>> +	struct dc_drm_device *dc_drm = to_dc_drm_device(priv->drm);
>> +	struct drm_device *drm = &dc_drm->base;
>> +	struct drm_crtc *crtc;
>> +
>> +	priv->drm = NULL;
>> +	drm_dev_unplug(drm);
>> +	dc_kms_uninit(dc_drm);
>> +	drm_atomic_helper_shutdown(drm);
>> +
>> +	drm_for_each_crtc(crtc, drm)
>> +		dc_crtc_disable_at_unbind(crtc);
> 
> There should be no need for that. drm_atomic_helper_shutdown() should
> disable all the CRTCs.

In case DRM device is unplugged, drm_atomic_helper_shutdown does not
effectively disable the CRTCs due to the bypassed logics wrapped by
drm_dev_{enter,exit}.  That's why dc_crtc_disable_at_unbind() is called
here to effectively disable the CRTCs.

> 
> Also, who is going to do drm_dev_unregister()? I don't see it in the
> code.

drm_dev_unplug() right above calls drm_dev_unregister().

> 
>> +}
>> +
>> +static const struct component_master_ops dc_drm_ops = {
>> +	.bind = dc_drm_bind,
>> +	.unbind = dc_drm_unbind,
>> +};
>> +
>> +static int dc_probe(struct platform_device *pdev)
>> +{
>> +	struct component_match *match = NULL;
>> +	struct dc_priv *priv;
>> +	int ret;
>> +
>> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>> +	if (!priv)
>> +		return -ENOMEM;
>> +
>> +	priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
>> +	if (IS_ERR(priv->clk_cfg))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
>> +				     "failed to get cfg clock\n");
>> +
>> +	dev_set_drvdata(&pdev->dev, priv);
>> +
>> +	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = devm_pm_runtime_enable(&pdev->dev);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = devm_of_platform_populate(&pdev->dev);
>> +	if (ret)
>> +		return ret;
>> +
>> +	dc_add_components(&pdev->dev, &match);
>> +
>> +	ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
>> +	if (ret)
>> +		return dev_err_probe(&pdev->dev, ret,
>> +				     "failed to add component master\n");
>> +
>> +	return 0;
>> +}
>> +
>> +static void dc_remove(struct platform_device *pdev)
>> +{
>> +	component_master_del(&pdev->dev, &dc_drm_ops);
>> +}
>> +
>> +static int dc_runtime_suspend(struct device *dev)
>> +{
>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>> +
>> +	clk_disable_unprepare(priv->clk_cfg);
>> +
>> +	return 0;
>> +}
>> +
>> +static int dc_runtime_resume(struct device *dev)
>> +{
>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>> +	int ret;
>> +
>> +	ret = clk_prepare_enable(priv->clk_cfg);
>> +	if (ret)
>> +		dev_err(dev, "failed to enable cfg clock: %d\n", ret);
>> +
>> +	return ret;
>> +}
>> +
>> +static int dc_suspend(struct device *dev)
>> +{
>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>> +
>> +	return drm_mode_config_helper_suspend(priv->drm);
>> +}
>> +
>> +static int dc_resume(struct device *dev)
>> +{
>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>> +
>> +	return drm_mode_config_helper_resume(priv->drm);
>> +}
>> +
>> +static void dc_shutdown(struct platform_device *pdev)
>> +{
>> +	struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
>> +
>> +	drm_atomic_helper_shutdown(priv->drm);
>> +}
>> +
>> +static const struct dev_pm_ops dc_pm_ops = {
>> +	RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
>> +	SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
>> +};
>> +
>> +static const struct of_device_id dc_dt_ids[] = {
>> +	{ .compatible = "fsl,imx8qxp-dc", },
>> +	{ /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, dc_dt_ids);
>> +
>> +static struct platform_driver dc_driver = {
>> +	.probe = dc_probe,
>> +	.remove = dc_remove,
>> +	.shutdown = dc_shutdown,
>> +	.driver = {
>> +		.name = "imx8-dc",
>> +		.of_match_table	= dc_dt_ids,
>> +		.pm = pm_sleep_ptr(&dc_pm_ops),
>> +	},
>> +};
>> +
>>  static struct platform_driver * const dc_drivers[] = {
>>  	&dc_cf_driver,
>>  	&dc_de_driver,
>> @@ -19,6 +262,7 @@ static struct platform_driver * const dc_drivers[] = {
>>  	&dc_lb_driver,
>>  	&dc_pe_driver,
>>  	&dc_tc_driver,
>> +	&dc_driver,
>>  };
>>  
>>  static int __init dc_drm_init(void)
>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
>> index 3b11f4862c6c..39a771a13933 100644
>> --- a/drivers/gpu/drm/imx/dc/dc-drv.h
>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.h
>> @@ -6,19 +6,38 @@
>>  #ifndef __DC_DRV_H__
>>  #define __DC_DRV_H__
>>  
>> +#include <linux/container_of.h>
>>  #include <linux/platform_device.h>
>>  
>>  #include <drm/drm_device.h>
>> +#include <drm/drm_encoder.h>
>>  
>>  #include "dc-de.h"
>> +#include "dc-kms.h"
>>  #include "dc-pe.h"
>>  
>>  struct dc_drm_device {
>>  	struct drm_device base;
>> +	struct dc_crtc dc_crtc[DC_DISPLAYS];
>> +	struct dc_plane dc_primary[DC_DISPLAYS];
>> +	struct drm_encoder encoder[DC_DISPLAYS];
>>  	struct dc_de *de[DC_DISPLAYS];
>>  	struct dc_pe *pe;
>>  };
>>  
>> +static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
>> +{
>> +	return container_of(drm, struct dc_drm_device, base);
>> +}
>> +
>> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
>> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
>> +
>> +int dc_kms_init(struct dc_drm_device *dc_drm);
>> +void dc_kms_uninit(struct dc_drm_device *dc_drm);
>> +
>> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
>> +
>>  extern struct platform_driver dc_cf_driver;
>>  extern struct platform_driver dc_ed_driver;
>>  extern struct platform_driver dc_de_driver;
>> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
>> new file mode 100644
>> index 000000000000..2b18aa37a4a8
>> --- /dev/null
>> +++ b/drivers/gpu/drm/imx/dc/dc-kms.c
>> @@ -0,0 +1,143 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright 2024 NXP
>> + */
>> +
>> +#include <linux/of.h>
>> +#include <linux/of_graph.h>
>> +
>> +#include <drm/drm_atomic_helper.h>
>> +#include <drm/drm_bridge.h>
>> +#include <drm/drm_bridge_connector.h>
>> +#include <drm/drm_connector.h>
>> +#include <drm/drm_crtc.h>
>> +#include <drm/drm_device.h>
>> +#include <drm/drm_encoder.h>
>> +#include <drm/drm_gem_framebuffer_helper.h>
>> +#include <drm/drm_mode_config.h>
>> +#include <drm/drm_print.h>
>> +#include <drm/drm_probe_helper.h>
>> +#include <drm/drm_simple_kms_helper.h>
>> +#include <drm/drm_vblank.h>
>> +
>> +#include "dc-de.h"
>> +#include "dc-drv.h"
>> +#include "dc-kms.h"
>> +
>> +static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
>> +	.fb_create = drm_gem_fb_create,
>> +	.atomic_check = drm_atomic_helper_check,
>> +	.atomic_commit = drm_atomic_helper_commit,
>> +};
>> +
>> +static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
>> +					int crtc_index)
>> +{
>> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
>> +	struct drm_device *drm = &dc_drm->base;
>> +	struct drm_crtc *crtc = &dc_crtc->base;
>> +	struct drm_connector *connector;
>> +	struct device *dev = drm->dev;
>> +	struct drm_encoder *encoder;
>> +	struct drm_bridge *bridge;
>> +	int ret;
>> +
>> +	bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
>> +					0, 0);
>> +	if (IS_ERR(bridge)) {
>> +		ret = PTR_ERR(bridge);
>> +		if (ret == -ENODEV)
>> +			return 0;
>> +
>> +		return dev_err_probe(dev, ret,
>> +				     "failed to find bridge for CRTC%u\n",
>> +				     crtc->index);
>> +	}
>> +
>> +	encoder = &dc_drm->encoder[crtc_index];
>> +	ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
>> +	if (ret) {
>> +		dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
>> +			crtc->index, ret);
>> +		return ret;
>> +	}
>> +
>> +	encoder->possible_crtcs = drm_crtc_mask(crtc);
>> +
>> +	ret = drm_bridge_attach(encoder, bridge, NULL,
>> +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +	if (ret) {
>> +		dev_err(dev,
>> +			"failed to attach bridge to encoder for CRTC%u: %d\n",
>> +			crtc->index, ret);
>> +		return ret;
>> +	}
>> +
>> +	connector = drm_bridge_connector_init(drm, encoder);
>> +	if (IS_ERR(connector)) {
>> +		ret = PTR_ERR(connector);
>> +		dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
>> +			crtc->index, ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = drm_connector_attach_encoder(connector, encoder);
>> +	if (ret)
>> +		dev_err(dev,
>> +			"failed to attach encoder to connector for CRTC%u: %d\n",
>> +			crtc->index, ret);
>> +
>> +	return ret;
>> +}
>> +
>> +int dc_kms_init(struct dc_drm_device *dc_drm)
>> +{
>> +	struct drm_device *drm = &dc_drm->base;
>> +	int ret, i;
>> +
>> +	ret = drmm_mode_config_init(drm);
>> +	if (ret)
>> +		return ret;
>> +
>> +	drm->mode_config.min_width = 60;
>> +	drm->mode_config.min_height = 60;
>> +	drm->mode_config.max_width = 8192;
>> +	drm->mode_config.max_height = 8192;
>> +	drm->mode_config.funcs = &dc_drm_mode_config_funcs;
>> +
>> +	drm->vblank_disable_immediate = true;
>> +	drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
>> +
>> +	for (i = 0; i < DC_DISPLAYS; i++) {
>> +		ret = dc_crtc_init(dc_drm, i);
>> +		if (ret)
>> +			return ret;
>> +
>> +		ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	for (i = 0; i < DC_DISPLAYS; i++) {
>> +		ret = dc_crtc_post_init(dc_drm, i);
> 
> Can you use .late_register for this?

Kerneldoc of struct drm_crtc_funcs::late_register says it's used to register
additional userspace interfaces like debugfs interfaces. And, it seems that
everyone implementing this uses it to add debugfs interfaces. So, it will
kind of abuse it to do CRTC post initialization.

> 
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	ret = drm_vblank_init(drm, DC_DISPLAYS);
>> +	if (ret) {
>> +		dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	drm_mode_config_reset(drm);
>> +
>> +	drm_kms_helper_poll_init(drm);
>> +
>> +	return 0;
>> +}
>> +
>> +void dc_kms_uninit(struct dc_drm_device *dc_drm)
>> +{
>> +	drm_kms_helper_poll_fini(&dc_drm->base);
>> +}
>> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
>> new file mode 100644
>> index 000000000000..57f6e0c15f57
>> --- /dev/null
>> +++ b/drivers/gpu/drm/imx/dc/dc-kms.h
>> @@ -0,0 +1,58 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright 2024 NXP
>> + */
>> +
>> +#ifndef __DC_KMS_H__
>> +#define __DC_KMS_H__
>> +
>> +#include <linux/completion.h>
>> +
>> +#include <drm/drm_crtc.h>
>> +#include <drm/drm_plane.h>
>> +#include <drm/drm_vblank.h>
>> +
>> +#include "dc-de.h"
>> +#include "dc-fu.h"
>> +#include "dc-pe.h"
>> +
>> +#define DC_CRTC_IRQS	5
>> +
>> +struct dc_crtc_irq {
>> +	struct dc_crtc *dc_crtc;
>> +	unsigned int irq;
>> +};
>> +
> 
> Please provide some documentation for the structure in the form of the
> kerneldoc. E.g. what is the difference between ed_cont and ed_safe?

Will add kerneldoc for struct dc_{crtc,plane,drm_device} and tell the
difference between ed_cont(content stream) and ed_safe(safety stream).

> The de and fg pointers are global, please don't cache them
> unnecessarily.

Global? I don't catch your meaning, sorry. To me, it's handy to access de
and fg via the two pointers in struct dc_crtc.

> 
>> +struct dc_crtc {
>> +	struct drm_crtc base;
>> +	struct dc_de *de;
>> +	struct dc_pe *pe;
>> +	struct dc_cf *cf_cont;
>> +	struct dc_cf *cf_safe;
>> +	struct dc_ed *ed_cont;
>> +	struct dc_ed *ed_safe;
>> +	struct dc_fg *fg;
>> +	unsigned int irq_dec_framecomplete;
>> +	unsigned int irq_dec_seqcomplete;
>> +	unsigned int irq_dec_shdld;
>> +	unsigned int irq_ed_cont_shdld;
>> +	unsigned int irq_ed_safe_shdld;
>> +	struct completion dec_seqcomplete_done;
>> +	struct completion dec_shdld_done;
>> +	struct completion ed_safe_shdld_done;
>> +	struct completion ed_cont_shdld_done;
>> +	struct drm_pending_vblank_event *event;
>> +	struct dc_crtc_irq irqs[DC_CRTC_IRQS];
>> +};
>> +
>> +struct dc_plane {
>> +	struct drm_plane base;
>> +	struct dc_fu *fu;
>> +	struct dc_cf *cf;
>> +	struct dc_lb *lb;
>> +	struct dc_ed *ed;
>> +};
>> +
>> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc);
>> +
>> +#endif /* __DC_KMS_H__ */
>> diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
>> new file mode 100644
>> index 000000000000..78d0d2cd3451
>> --- /dev/null
>> +++ b/drivers/gpu/drm/imx/dc/dc-plane.c
>> @@ -0,0 +1,241 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright 2024 NXP
>> + */
>> +
>> +#include <linux/container_of.h>
>> +
>> +#include <drm/drm_atomic.h>
>> +#include <drm/drm_atomic_helper.h>
>> +#include <drm/drm_atomic_state_helper.h>
>> +#include <drm/drm_crtc.h>
>> +#include <drm/drm_drv.h>
>> +#include <drm/drm_fb_dma_helper.h>
>> +#include <drm/drm_fourcc.h>
>> +#include <drm/drm_framebuffer.h>
>> +#include <drm/drm_gem_atomic_helper.h>
>> +#include <drm/drm_plane_helper.h>
>> +#include <drm/drm_print.h>
>> +
>> +#include "dc-drv.h"
>> +#include "dc-fu.h"
>> +#include "dc-kms.h"
>> +
>> +#define DC_PLANE_MAX_PITCH	0x10000
>> +#define DC_PLANE_MAX_PIX_CNT	8192
>> +
>> +#define dc_plane_dbg(plane, fmt, ...)					\
>> +do {									\
>> +	typeof(plane) _plane = (plane);					\
>> +	drm_dbg_kms(_plane->dev, "[PLANE:%d:%s] " fmt,			\
>> +		    _plane->base.id, _plane->name, ##__VA_ARGS__);	\
>> +} while (0)
>> +
>> +static const uint32_t dc_plane_formats[] = {
>> +	DRM_FORMAT_XRGB8888,
>> +};
>> +
>> +static const struct drm_plane_funcs dc_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,
>> +};
>> +
>> +static inline struct dc_plane *to_dc_plane(struct drm_plane *plane)
>> +{
>> +	return container_of(plane, struct dc_plane, base);
>> +}
>> +
>> +static int dc_plane_check_no_off_screen(struct drm_plane_state *state,
>> +					struct drm_crtc_state *crtc_state)
>> +{
>> +	if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
>> +	    state->dst.x2 > crtc_state->adjusted_mode.hdisplay ||
>> +	    state->dst.y2 > crtc_state->adjusted_mode.vdisplay) {
>> +		dc_plane_dbg(state->plane, "no off screen\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int dc_plane_check_max_source_resolution(struct drm_plane_state *state)
>> +{
>> +	int src_h = drm_rect_height(&state->src) >> 16;
>> +	int src_w = drm_rect_width(&state->src) >> 16;
>> +
>> +	if (src_w > DC_PLANE_MAX_PIX_CNT || src_h > DC_PLANE_MAX_PIX_CNT) {
>> +		dc_plane_dbg(state->plane, "invalid source resolution\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int dc_plane_check_fb(struct drm_plane_state *state)
>> +{
>> +	struct drm_framebuffer *fb = state->fb;
>> +	dma_addr_t baseaddr = drm_fb_dma_get_gem_addr(fb, state, 0);
>> +
>> +	/* base address alignment */
>> +	if (baseaddr & 0x3) {
>> +		dc_plane_dbg(state->plane, "fb bad baddr alignment\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* pitches[0] range */
>> +	if (fb->pitches[0] > DC_PLANE_MAX_PITCH) {
>> +		dc_plane_dbg(state->plane, "fb pitches[0] is out of range\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* pitches[0] alignment */
>> +	if (fb->pitches[0] & 0x3) {
>> +		dc_plane_dbg(state->plane, "fb bad pitches[0] alignment\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int
>> +dc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
>> +{
>> +	struct drm_plane_state *plane_state =
>> +				drm_atomic_get_new_plane_state(state, plane);
>> +	struct drm_crtc_state *crtc_state;
>> +	int ret;
>> +
>> +	/* ok to disable */
>> +	if (!plane_state->fb)
>> +		return 0;
>> +
>> +	if (!plane_state->crtc) {
>> +		dc_plane_dbg(plane, "no CRTC in plane state\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	crtc_state =
>> +		drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
>> +	if (WARN_ON(!crtc_state))
>> +		return -EINVAL;
>> +
>> +	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
>> +						  DRM_PLANE_NO_SCALING,
>> +						  DRM_PLANE_NO_SCALING,
>> +						  true, false);
>> +	if (ret) {
>> +		dc_plane_dbg(plane, "failed to check plane state: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = dc_plane_check_no_off_screen(plane_state, crtc_state);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = dc_plane_check_max_source_resolution(plane_state);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return dc_plane_check_fb(plane_state);
>> +}
>> +
>> +static void
>> +dc_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state)
>> +{
>> +	struct drm_plane_state *new_state =
>> +				drm_atomic_get_new_plane_state(state, plane);
>> +	struct dc_plane *dplane = to_dc_plane(plane);
>> +	struct drm_framebuffer *fb = new_state->fb;
>> +	const struct dc_fu_ops *fu_ops;
>> +	struct dc_lb *lb = dplane->lb;
>> +	struct dc_fu *fu = dplane->fu;
>> +	dma_addr_t baseaddr;
>> +	int src_w, src_h;
>> +	int idx;
>> +
>> +	if (!drm_dev_enter(plane->dev, &idx))
>> +		return;
>> +
>> +	src_w = drm_rect_width(&new_state->src) >> 16;
>> +	src_h = drm_rect_height(&new_state->src) >> 16;
>> +
>> +	baseaddr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
>> +
>> +	fu_ops = dc_fu_get_ops(dplane->fu);
>> +
>> +	fu_ops->set_layerblend(fu, lb);
>> +	fu_ops->set_burstlength(fu, baseaddr);
>> +	fu_ops->set_src_stride(fu, DC_FETCHUNIT_FRAC0, fb->pitches[0]);
>> +	fu_ops->set_src_buf_dimensions(fu, DC_FETCHUNIT_FRAC0, src_w, src_h);
>> +	fu_ops->set_fmt(fu, DC_FETCHUNIT_FRAC0, fb->format);
>> +	fu_ops->set_framedimensions(fu, src_w, src_h);
>> +	fu_ops->set_baseaddress(fu, DC_FETCHUNIT_FRAC0, baseaddr);
>> +	fu_ops->enable_src_buf(fu, DC_FETCHUNIT_FRAC0);
>> +
>> +	dc_plane_dbg(plane, "uses %s\n", fu_ops->get_name(fu));
>> +
>> +	dc_lb_pec_dynamic_prim_sel(lb, dc_cf_get_link_id(dplane->cf));
>> +	dc_lb_pec_dynamic_sec_sel(lb, fu_ops->get_link_id(fu));
>> +	dc_lb_mode(lb, LB_BLEND);
>> +	dc_lb_position(lb, new_state->dst.x1, new_state->dst.y1);
>> +	dc_lb_pec_clken(lb, CLKEN_AUTOMATIC);
>> +
>> +	dc_plane_dbg(plane, "uses LayerBlend%u\n", dc_lb_get_id(lb));
>> +
>> +	/* set ExtDst's source to LayerBlend */
>> +	dc_ed_pec_src_sel(dplane->ed, dc_lb_get_link_id(lb));
>> +
>> +	drm_dev_exit(idx);
>> +}
>> +
>> +static void dc_plane_atomic_disable(struct drm_plane *plane,
>> +				    struct drm_atomic_state *state)
>> +{
>> +	struct dc_plane *dplane = to_dc_plane(plane);
>> +	const struct dc_fu_ops *fu_ops;
>> +	int idx;
>> +
>> +	if (!drm_dev_enter(plane->dev, &idx))
>> +		return;
>> +
>> +	/* disable fetchunit in shadow */
>> +	fu_ops = dc_fu_get_ops(dplane->fu);
>> +	fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
>> +
>> +	/* set ExtDst's source to ConstFrame */
>> +	dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
>> +
>> +	drm_dev_exit(idx);
>> +}
>> +
>> +static const struct drm_plane_helper_funcs dc_plane_helper_funcs = {
>> +	.atomic_check = dc_plane_atomic_check,
>> +	.atomic_update = dc_plane_atomic_update,
>> +	.atomic_disable = dc_plane_atomic_disable,
>> +};
>> +
>> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
>> +{
>> +	struct drm_plane *plane = &dc_plane->base;
>> +	int ret;
>> +
>> +	ret = drm_universal_plane_init(&dc_drm->base, plane, 0, &dc_plane_funcs,
>> +				       dc_plane_formats,
>> +				       ARRAY_SIZE(dc_plane_formats),
>> +				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
>> +	if (ret)
>> +		return ret;
>> +
>> +	drm_plane_helper_add(plane, &dc_plane_helper_funcs);
>> +
>> +	dc_plane->fu = dc_drm->pe->fu_disp[plane->index];
>> +	dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
>> +	dc_plane->lb = dc_drm->pe->lb[plane->index];
>> +	dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
>> +
>> +	return 0;
>> +}
>> -- 
>> 2.34.1
>>
> 

-- 
Regards,
Liu Ying


From kevin.tian at intel.com  Tue Dec 10 23:43:11 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 07:43:11 +0000
Subject: [PATCH v2 04/13] iommufd: Rename fault.c to eventq.c
In-Reply-To: <9e37e420e46844d5a10b055e512e7d94f1446a0b.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <9e37e420e46844d5a10b055e512e7d94f1446a0b.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB52760723207F5DEB1D81E4B18C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> 
> Rename the file, aligning with the new eventq object.
> 
> Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>

Reviewed-by: Kevin Tian <kevin.tian at intel.com>


From krzysztof.kozlowski at linaro.org  Tue Dec 10 23:50:01 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 08:50:01 +0100
Subject: [PATCH v4 0/1] support watchdog for exynosautov920
In-Reply-To: <20241206025139.2148833-1-trunixs.kim@samsung.com>
References: <CGME20241206025156epcas2p3e1ce9ff35589d821735a7c038b9ac9da@epcas2p3.samsung.com>
 <20241206025139.2148833-1-trunixs.kim@samsung.com>
Message-ID: <173390340180.16989.11837691973342827218.b4-ty@linaro.org>


On Fri, 06 Dec 2024 11:51:37 +0900, Taewan Kim wrote:
> Add support for the ExynosAutoV920 SoC. Basically this is almost
> similar to ExynosAuto V9 or Exynos850 such as two watchdog instance for
> each cluster but some CPU configuration are quite different.
> Therefore device tree, compatibles and drvdata should be added.
> 
> In v3, the first and second patches were approved by watchdog maintainer and added as next-git.
> - Link: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/log/?qt=grep&q=bt.cho
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: exynosautov920: add watchdog DT node
      https://git.kernel.org/krzk/linux/c/41979b81b22a35322817733b15407167164be58e

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



From krzk at kernel.org  Tue Dec 10 23:50:20 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 08:50:20 +0100
Subject: [PATCH v4 1/1] arm64: dts: exynosautov920: add watchdog DT node
In-Reply-To: <000101db4b6f$0d31c460$27954d20$@samsung.com>
References: <20241206025139.2148833-1-trunixs.kim@samsung.com>
 <CGME20241206025156epcas2p4c55f230accc4354e6f4bf324ab9a5833@epcas2p4.samsung.com>
 <20241206025139.2148833-2-trunixs.kim@samsung.com>
 <510e826d-a434-437d-8d2e-3f2618c28b7f@kernel.org>
 <000101db4b6f$0d31c460$27954d20$@samsung.com>
Message-ID: <5ac02c0e-d245-4c05-a4df-2cd2ba9065ad@kernel.org>

On 11/12/2024 02:50, ??? wrote:
> on 11/12/2024 01:50 UTC+09:00, Taewan Kim wrote:
>>> From: Byoungtae Cho <bt.cho at samsung.com>
>>>
>>> Adds two watchdog devices for ExynosAutoV920 SoC.
>>>
>>> Signed-off-by: Byoungtae Cho <bt.cho at samsung.com>
>>> Signed-off-by: Taewan Kim <trunixs.kim at samsung.com>
>>> ---
>>>  .../arm64/boot/dts/exynos/exynosautov920.dtsi | 20 +++++++++++++++++++
>>>  1 file changed, 20 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
>> b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
>>> index c759134c909e..7b9591255e91 100644
>>> --- a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
>>> +++ b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
>>> @@ -183,6 +183,26 @@ cmu_misc: clock-controller at 10020000 {
>>>  				      "noc";
>>>  		};
>>>
>>> +		watchdog_cl0: watchdog at 10060000 {
>>
>> You need to do careful rebase, not just accept whatever tools shown you.
>>
>> This is now placed in incorrect order - not keeping sorting by unit address.
> 
> I seems to me that the addresses are sorted correctly in order. 
> Could you kindly check again?
> 
>         clock-controller at 1002_0000
>                   watchdog at 1006_0000 
>                   watchdog at 1007_0000
>     interrupt-controller at 1040_0000
> 
> And if there are any rules I might not be aware of, please let me know.


You are right, I got impression last was 1004, but that's 1040. Thanks
for correcting me. I applied now.


Best regards,
Krzysztof


From xianwei.zhao at amlogic.com  Tue Dec 10 23:53:57 2024
From: xianwei.zhao at amlogic.com (Xianwei Zhao)
Date: Wed, 11 Dec 2024 15:53:57 +0800
Subject: [PATCH v2 4/5] clk: meson: add support for the A5 SoC PLL clock
In-Reply-To: <1jttbvtfxv.fsf@starbuckisacylon.baylibre.com>
References: <20241120-a5-clk-v2-0-1208621e961d@amlogic.com>
 <20241120-a5-clk-v2-4-1208621e961d@amlogic.com>
 <1jttbvtfxv.fsf@starbuckisacylon.baylibre.com>
Message-ID: <e5085ed9-191d-47b2-9728-22962673af02@amlogic.com>

Hi Jerome,
    Thanks for your reply.

On 2024/11/26 00:51, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> On Wed 20 Nov 2024 at 15:01, Xianwei Zhao via B4 Relay <devnull+xianwei.zhao.amlogic.com at kernel.org> wrote:
> 
>> From: Chuan Liu <chuan.liu at amlogic.com>
>>
>> Add the PLL clock controller driver for the Amlogic A5 SoC family.
>>
>> Signed-off-by: Chuan Liu <chuan.liu at amlogic.com>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
>> ---
>>   drivers/clk/meson/Kconfig  |  14 ++
>>   drivers/clk/meson/Makefile |   1 +
>>   drivers/clk/meson/a5-pll.c | 543 +++++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 558 insertions(+)
>>
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index 78f648c9c97d..3c97b3a1649d 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -132,6 +132,20 @@ config COMMON_CLK_A1_PERIPHERALS
>>          device, A1 SoC Family. Say Y if you want A1 Peripherals clock
>>          controller to work.
>>
>> +config COMMON_CLK_A5_PLL
>> +     tristate "Amlogic A5 PLL clock controller"
>> +     depends on ARM64
>> +     default y
>> +     imply COMMON_CLK_SCMI
>> +     select COMMON_CLK_MESON_REGMAP
>> +     select COMMON_CLK_MESON_PLL
>> +     select COMMON_CLK_MESON_MPLL
>> +     select COMMON_CLK_MESON_CLKC_UTILS
>> +     help
>> +       Support for the PLL clock controller on Amlogic AV40x device, AKA A5.
> 
> What is an AV40x ? if it is a SoC that's alright.
> If it is a board, then it is not Ok. The driver does not support a
> single board, does it ?
> 

It is a board, Will modify.

>> +       Say Y if you want the board to work, because PLLs are the parent
>> +       of most peripherals.
>> +
>>   config COMMON_CLK_C3_PLL
>>        tristate "Amlogic C3 PLL clock controller"
>>        depends on ARM64
>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>> index bc56a47931c1..fc4b8a723145 100644
>> --- a/drivers/clk/meson/Makefile
>> +++ b/drivers/clk/meson/Makefile
>> @@ -20,6 +20,7 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
>>   obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
>>   obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
>>   obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
>> +obj-$(CONFIG_COMMON_CLK_A5_PLL) += a5-pll.o
>>   obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
>>   obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>>   obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>> diff --git a/drivers/clk/meson/a5-pll.c b/drivers/clk/meson/a5-pll.c
>> new file mode 100644
>> index 000000000000..f18700dfd055
>> --- /dev/null
>> +++ b/drivers/clk/meson/a5-pll.c
>> @@ -0,0 +1,543 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Amlogic A5 PLL Controller Driver
>> + *
>> + * Copyright (c) 2024 Amlogic, inc.
>> + * Author: Chuan Liu <chuan.liu at amlogic.com>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/platform_device.h>
>> +#include "clk-regmap.h"
>> +#include "clk-pll.h"
>> +#include "clk-mpll.h"
>> +#include "meson-clkc-utils.h"
>> +#include <dt-bindings/clock/amlogic,a5-pll-clkc.h>
>> +
>> +#define ANACTRL_GP0PLL_CTRL0                 0x80
>> +#define ANACTRL_GP0PLL_CTRL1                 0x84
>> +#define ANACTRL_GP0PLL_CTRL2                 0x88
>> +#define ANACTRL_GP0PLL_CTRL3                 0x8c
>> +#define ANACTRL_GP0PLL_CTRL4                 0x90
>> +#define ANACTRL_GP0PLL_CTRL5                 0x94
>> +#define ANACTRL_GP0PLL_CTRL6                 0x98
>> +#define ANACTRL_HIFIPLL_CTRL0                        0x100
>> +#define ANACTRL_HIFIPLL_CTRL1                        0x104
>> +#define ANACTRL_HIFIPLL_CTRL2                        0x108
>> +#define ANACTRL_HIFIPLL_CTRL3                        0x10c
>> +#define ANACTRL_HIFIPLL_CTRL4                        0x110
>> +#define ANACTRL_HIFIPLL_CTRL5                        0x114
>> +#define ANACTRL_HIFIPLL_CTRL6                        0x118
>> +#define ANACTRL_MPLL_CTRL0                   0x180
>> +#define ANACTRL_MPLL_CTRL1                   0x184
>> +#define ANACTRL_MPLL_CTRL2                   0x188
>> +#define ANACTRL_MPLL_CTRL3                   0x18c
>> +#define ANACTRL_MPLL_CTRL4                   0x190
>> +#define ANACTRL_MPLL_CTRL5                   0x194
>> +#define ANACTRL_MPLL_CTRL6                   0x198
>> +#define ANACTRL_MPLL_CTRL7                   0x19c
>> +#define ANACTRL_MPLL_CTRL8                   0x1a0
> 
> Same question as usual, is there clocks and *ONLY* clock between 0x0 and
> 0x1a0 ?
> 
> If you can guarantee that, you'll need to split the controller into
> multiple devices.
> 

Between 0x0 and 0x5c are fix_pll and sys_pll. These two plls are
processed in bl31 due to security restrictions. Besides, there are
no registers of other modules interspersed in it.

>> +
>> +static struct clk_fixed_factor mpll_prediv = {
>> +     .mult = 1,
>> +     .div = 2,
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mpll_prediv",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "fix_dco"
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct reg_sequence mpll0_init_regs[] = {
>> +     { .reg = ANACTRL_MPLL_CTRL2,    .def = 0x40000033 },
>> +};
>> +
>> +static struct clk_regmap mpll0_div = {
>> +     .data = &(struct meson_clk_mpll_data){
>> +             .sdm = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL1,
>> +                     .shift   = 0,
>> +                     .width   = 14,
>> +             },
>> +             .sdm_en = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL1,
>> +                     .shift   = 30,
>> +                     .width   = 1,
>> +             },
>> +             .n2 = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL1,
>> +                     .shift   = 20,
>> +                     .width   = 9,
>> +             },
>> +             .ssen = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL1,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +             .init_regs = mpll0_init_regs,
>> +             .init_count = ARRAY_SIZE(mpll0_init_regs),
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mpll0_div",
>> +             .ops = &meson_clk_mpll_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mpll_prediv.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mpll0 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_MPLL_CTRL1,
>> +             .bit_idx = 31,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mpll0",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) { &mpll0_div.hw },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct reg_sequence mpll1_init_regs[] = {
>> +     { .reg = ANACTRL_MPLL_CTRL4,    .def = 0x40000033 },
>> +};
>> +
>> +static struct clk_regmap mpll1_div = {
>> +     .data = &(struct meson_clk_mpll_data){
>> +             .sdm = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL3,
>> +                     .shift   = 0,
>> +                     .width   = 14,
>> +             },
>> +             .sdm_en = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL3,
>> +                     .shift   = 30,
>> +                     .width   = 1,
>> +             },
>> +             .n2 = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL3,
>> +                     .shift   = 20,
>> +                     .width   = 9,
>> +             },
>> +             .ssen = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL3,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +             .init_regs = mpll1_init_regs,
>> +             .init_count = ARRAY_SIZE(mpll1_init_regs),
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mpll1_div",
>> +             .ops = &meson_clk_mpll_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mpll_prediv.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mpll1 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_MPLL_CTRL3,
>> +             .bit_idx = 31,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mpll1",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) { &mpll1_div.hw },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct reg_sequence mpll2_init_regs[] = {
>> +     { .reg = ANACTRL_MPLL_CTRL6,    .def = 0x40000033 },
>> +};
>> +
>> +static struct clk_regmap mpll2_div = {
>> +     .data = &(struct meson_clk_mpll_data){
>> +             .sdm = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL5,
>> +                     .shift   = 0,
>> +                     .width   = 14,
>> +             },
>> +             .sdm_en = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL5,
>> +                     .shift   = 30,
>> +                     .width   = 1,
>> +             },
>> +             .n2 = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL5,
>> +                     .shift   = 20,
>> +                     .width   = 9,
>> +             },
>> +             .ssen = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL5,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +             .init_regs = mpll2_init_regs,
>> +             .init_count = ARRAY_SIZE(mpll2_init_regs),
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mpll2_div",
>> +             .ops = &meson_clk_mpll_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mpll_prediv.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mpll2 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_MPLL_CTRL5,
>> +             .bit_idx = 31,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mpll2",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) { &mpll2_div.hw },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct reg_sequence mpll3_init_regs[] = {
>> +     { .reg = ANACTRL_MPLL_CTRL8,    .def = 0x40000033 },
>> +};
>> +
>> +static struct clk_regmap mpll3_div = {
>> +     .data = &(struct meson_clk_mpll_data){
>> +             .sdm = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL7,
>> +                     .shift   = 0,
>> +                     .width   = 14,
>> +             },
>> +             .sdm_en = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL7,
>> +                     .shift   = 30,
>> +                     .width   = 1,
>> +             },
>> +             .n2 = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL7,
>> +                     .shift   = 20,
>> +                     .width   = 9,
>> +             },
>> +             .ssen = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL7,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +             .init_regs = mpll3_init_regs,
>> +             .init_count = ARRAY_SIZE(mpll3_init_regs),
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mpll3_div",
>> +             .ops = &meson_clk_mpll_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mpll_prediv.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mpll3 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_MPLL_CTRL7,
>> +             .bit_idx = 31,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mpll3",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) { &mpll3_div.hw },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct reg_sequence gp0_init_regs[] = {
>> +     { .reg = ANACTRL_GP0PLL_CTRL2, .def = 0x00000000 },
>> +     { .reg = ANACTRL_GP0PLL_CTRL3, .def = 0x6a295c00 },
>> +     { .reg = ANACTRL_GP0PLL_CTRL4, .def = 0x65771290 },
>> +     { .reg = ANACTRL_GP0PLL_CTRL5, .def = 0x3927200a },
>> +     { .reg = ANACTRL_GP0PLL_CTRL6, .def = 0x54540000 }
>> +};
>> +
>> +static const struct pll_mult_range gp0_pll_mult_range = {
>> +     .min = 125,
>> +     .max = 250,
>> +};
>> +
>> +static struct clk_regmap gp0_pll_dco = {
>> +     .data = &(struct meson_clk_pll_data) {
>> +             .en = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 28,
>> +                     .width   = 1,
>> +             },
>> +             .m = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 0,
>> +                     .width   = 8,
>> +             },
>> +             .frac = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL1,
>> +                     .shift   = 0,
>> +                     .width   = 17,
>> +             },
>> +             .n = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 10,
>> +                     .width   = 5,
>> +             },
>> +             .l = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 31,
>> +                     .width   = 1,
>> +             },
>> +             .rst = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +             .range = &gp0_pll_mult_range,
>> +             .init_regs = gp0_init_regs,
>> +             .init_count = ARRAY_SIZE(gp0_init_regs),
>> +             .frac_max = 100000,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "gp0_pll_dco",
>> +             .ops = &meson_clk_pll_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "xtal_24m",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +/* The maximum frequency divider supports is 32, not 128(2^7) */
>> +static const struct clk_div_table gp0_pll_od_table[] = {
>> +     { 0,  1 },
>> +     { 1,  2 },
>> +     { 2,  4 },
>> +     { 3,  8 },
>> +     { 4, 16 },
>> +     { 5, 32 },
>> +     { /* sentinel */ }
>> +};
>> +
>> +static struct clk_regmap gp0_pll = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = ANACTRL_GP0PLL_CTRL0,
>> +             .shift = 16,
>> +             .width = 3,
>> +             .table = gp0_pll_od_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "gp0_pll",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &gp0_pll_dco.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct reg_sequence hifi_init_regs[] = {
>> +     { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00000000 },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a295c00 },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x54540000 }
>> +};
>> +
>> +static const struct pll_mult_range hifi_pll_mult_range = {
>> +     .min = 125,
>> +     .max = 250,
>> +};
>> +
>> +static struct clk_regmap hifi_pll_dco = {
>> +     .data = &(struct meson_clk_pll_data) {
>> +             .en = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 28,
>> +                     .width   = 1,
>> +             },
>> +             .m = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 0,
>> +                     .width   = 8,
>> +             },
>> +             .frac = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL1,
>> +                     .shift   = 0,
>> +                     .width   = 17,
>> +             },
>> +             .n = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 10,
>> +                     .width   = 5,
>> +             },
>> +             .l = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 31,
>> +                     .width   = 1,
>> +             },
>> +             .rst = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +             .range = &hifi_pll_mult_range,
>> +             .init_regs = hifi_init_regs,
>> +             .init_count = ARRAY_SIZE(hifi_init_regs),
>> +             .frac_max = 100000,
>> +             /* NOTE: The original design of hifi_pll is to provide
>> +              * clock for audio, which requires clock accuracy.
>> +              * Therefore, flag CLK_MESON_PLL_ROUND_CLOSEST is added
>> +              * to make the output frequency of hifi_pll closer to
>> +              * the target frequency.
>> +              */
> 
> The comment format is incorrect. not quite sure the commnet itself is useful.
> 

Delete this comment in the next version.

>> +             .flags = CLK_MESON_PLL_ROUND_CLOSEST,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "hifi_pll_dco",
>> +             .ops = &meson_clk_pll_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "xtal_24m",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap hifi_pll = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = ANACTRL_HIFIPLL_CTRL0,
>> +             .shift = 16,
>> +             /* NOTE: The actual reserved bit width of the od (output
>> +              * divider) of hifi_pll is 3 bit, but its actual maximum
>> +              * effective divider factor is 8. It can just use 2 bit and add
>> +              * flag CLK_DIVIDER_POWER_OF_TWO (max_div = 2^3 = 8).
>> +              */
> 
> Same here

Delete this comment in the next version.

> 
>> +             .width = 2,
> 
> ... yet the width is 2 ??
> 
>> +             .flags = CLK_DIVIDER_POWER_OF_TWO,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "hifi_pll",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &hifi_pll_dco.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_hw *a5_pll_hw_clks[] = {
>> +     [CLKID_MPLL_PREDIV]     = &mpll_prediv.hw,
>> +     [CLKID_MPLL0_DIV]       = &mpll0_div.hw,
>> +     [CLKID_MPLL0]           = &mpll0.hw,
>> +     [CLKID_MPLL1_DIV]       = &mpll1_div.hw,
>> +     [CLKID_MPLL1]           = &mpll1.hw,
>> +     [CLKID_MPLL2_DIV]       = &mpll2_div.hw,
>> +     [CLKID_MPLL2]           = &mpll2.hw,
>> +     [CLKID_MPLL3_DIV]       = &mpll3_div.hw,
>> +     [CLKID_MPLL3]           = &mpll3.hw,
>> +     [CLKID_GP0_PLL_DCO]     = &gp0_pll_dco.hw,
>> +     [CLKID_GP0_PLL]         = &gp0_pll.hw,
>> +     [CLKID_HIFI_PLL_DCO]    = &hifi_pll_dco.hw,
>> +     [CLKID_HIFI_PLL]        = &hifi_pll.hw
>> +};
>> +
>> +/* Convenience table to populate regmap in .probe */
>> +static struct clk_regmap *const a5_pll_clk_regmaps[] = {
>> +     &mpll0_div,
>> +     &mpll0,
>> +     &mpll1_div,
>> +     &mpll1,
>> +     &mpll2_div,
>> +     &mpll2,
>> +     &mpll3_div,
>> +     &mpll3,
>> +     &gp0_pll_dco,
>> +     &gp0_pll,
>> +     &hifi_pll_dco,
>> +     &hifi_pll
>> +};
>> +
>> +static const struct regmap_config clkc_regmap_config = {
>> +     .reg_bits       = 32,
>> +     .val_bits       = 32,
>> +     .reg_stride     = 4,
>> +     .max_register   = ANACTRL_MPLL_CTRL8,
>> +};
>> +
>> +static struct meson_clk_hw_data a5_pll_clks = {
>> +     .hws = a5_pll_hw_clks,
>> +     .num = ARRAY_SIZE(a5_pll_hw_clks),
>> +};
>> +
>> +static int aml_a5_pll_probe(struct platform_device *pdev)
>> +{
>> +     struct device *dev = &pdev->dev;
>> +     struct regmap *regmap;
>> +     void __iomem *base;
>> +     int clkid, ret, i;
>> +
>> +     base = devm_platform_ioremap_resource(pdev, 0);
>> +     if (IS_ERR(base))
>> +             return PTR_ERR(base);
>> +
>> +     regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
>> +     if (IS_ERR(regmap))
>> +             return PTR_ERR(regmap);
>> +
>> +     /* Populate regmap for the regmap backed clocks */
>> +     for (i = 0; i < ARRAY_SIZE(a5_pll_clk_regmaps); i++)
>> +             a5_pll_clk_regmaps[i]->map = regmap;
>> +
>> +     for (clkid = 0; clkid < a5_pll_clks.num; clkid++) {
>> +             /* array might be sparse */
>> +             if (!a5_pll_clks.hws[clkid])
>> +                     continue;
>> +
>> +             ret = devm_clk_hw_register(dev, a5_pll_clks.hws[clkid]);
>> +             if (ret) {
>> +                     dev_err(dev, "Clock registration failed\n");
>> +                     return ret;
>> +             }
>> +     }
>> +
>> +     return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
>> +                                        &a5_pll_clks);
>> +}
>> +
>> +static const struct of_device_id a5_pll_clkc_match_table[] = {
>> +     {
>> +             .compatible = "amlogic,a5-pll-clkc",
>> +     },
>> +     {}
>> +};
>> +MODULE_DEVICE_TABLE(of, a5_pll_clkc_match_table);
>> +
>> +static struct platform_driver a5_pll_driver = {
>> +     .probe          = aml_a5_pll_probe,
>> +     .driver         = {
>> +             .name   = "a5-pll-clkc",
>> +             .of_match_table = a5_pll_clkc_match_table,
>> +     },
>> +};
>> +module_platform_driver(a5_pll_driver);
>> +
>> +MODULE_DESCRIPTION("Amlogic A5 PLL Clock Controller driver");
>> +MODULE_AUTHOR("Chuan Liu <chuan.liu at amlogic.com>");
>> +MODULE_LICENSE("GPL");
> 
> --
> Jerome


From krzk at kernel.org  Tue Dec 10 23:56:34 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 08:56:34 +0100
Subject: [PATCH] pinctrl: mediatek: Add support for MT8196
In-Reply-To: <20241211055454.17120-3-ot_cathy.xu@mediatek.com>
References: <20241211055454.17120-3-ot_cathy.xu@mediatek.com>
Message-ID: <2a773ddb-2836-40cf-a08b-ac47430aeb78@kernel.org>

On 11/12/2024 06:54, ot907280 wrote:
> From: Guodong Liu <guodong.liu at mediatek.corp-partner.google.com>
> 
> Add pinctrl driver for mt8196
> 
> Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>
> Signed-off-by: ot907280 <ot_cathy.xu at mediatek.com>


Please use real names, not logins.

<form letter>
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) or work on fork of kernel
(don't, instead use mainline). 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.
</form letter>


> ---
>  drivers/pinctrl/mediatek/Kconfig              |   12 +
>  drivers/pinctrl/mediatek/Makefile             |    1 +
>  drivers/pinctrl/mediatek/pinctrl-mt8196.c     | 1757 +++++++++++
>  drivers/pinctrl/mediatek/pinctrl-mtk-mt8196.h | 2791 +++++++++++++++++
>  include/dt-bindings/pinctrl/mt8196-pinfunc.h  | 1572 ++++++++++
>  5 files changed, 6133 insertions(+)
>  create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt8196.c
>  create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt8196.h
>  create mode 100644 include/dt-bindings/pinctrl/mt8196-pinfunc.h

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.



> +static const char * const mt8196_pinctrl_register_base_names[] = {
> +	"iocfg0", "iocfg_rt", "iocfg_rm1", "iocfg_rm2",
> +	"iocfg_rb", "iocfg_bm1", "iocfg_bm2", "iocfg_bm3",
> +	"iocfg_lt", "iocfg_lm1", "iocfg_lm2", "iocfg_lb1",
> +	"iocfg_lb2", "iocfg_tm1", "iocfg_tm2", "iocfg_tm3",
> +};
> +
> +static const struct mtk_pin_soc mt8196_data = {
> +	.reg_cal	= mt8196_reg_cals,
> +	.pins	= mtk_pins_mt8196,
> +	.npins	= ARRAY_SIZE(mtk_pins_mt8196),
> +	.ngrps	= ARRAY_SIZE(mtk_pins_mt8196),
> +	.nfuncs	= 8,
> +	.gpio_m	= 0,
> +	.base_names	= mt8196_pinctrl_register_base_names,
> +	.nbase_names	= ARRAY_SIZE(mt8196_pinctrl_register_base_names),
> +	.pull_type = mt8196_pull_type,
> +	.bias_set_combo	= mtk_pinconf_bias_set_combo,
> +	.bias_get_combo	= mtk_pinconf_bias_get_combo,
> +	.drive_set	= mtk_pinconf_drive_set_rev1,
> +	.drive_get	= mtk_pinconf_drive_get_rev1,
> +	.adv_drive_get	= mtk_pinconf_adv_drive_get_raw,
> +	.adv_drive_set	= mtk_pinconf_adv_drive_set_raw,
> +};
> +
> +static const struct of_device_id mt8196_pinctrl_of_match[] = {
> +	{ .compatible = "mediatek,mt8196-pinctrl", .data = &mt8196_data },


Please run scripts/checkpatch.pl and fix reported warnings. Then please
run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

> +	{ }
> +};
> +
> +static struct platform_driver mt8196_pinctrl_driver = {
> +	.driver = {
> +		.name = "mt8196-pinctrl",
> +		.of_match_table = mt8196_pinctrl_of_match,
> +		.pm = &mtk_paris_pinctrl_pm_ops,
> +	},
> +	.probe = mtk_paris_pinctrl_probe,
> +};
> +
> +static int __init mt8196_pinctrl_init(void)
> +{
> +	return platform_driver_register(&mt8196_pinctrl_driver);
> +}
> +arch_initcall(mt8196_pinctrl_init);
> +
> +MODULE_LICENSE("GPL");


...

> +#endif /* __PINCTRL_MTK_MT8196_H */
> diff --git a/include/dt-bindings/pinctrl/mt8196-pinfunc.h b/include/dt-bindings/pinctrl/mt8196-pinfunc.h
> new file mode 100644
> index 000000000000..717351b12255
> --- /dev/null
> +++ b/include/dt-bindings/pinctrl/mt8196-pinfunc.h
> @@ -0,0 +1,1572 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +/*
> + * Copyright (C) 2024 Mediatek Inc.
> + * Author: Guodong Liu <Guodong.Liu at mediatek.com>
> + */
> +
> +#ifndef __MT8196_PINFUNC_H
> +#define __MT8196_PINFUNC_H
> +
> +#include <dt-bindings/pinctrl/mt65xx.h>
> +
> +#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
> +#define PINMUX_GPIO0__FUNC_DMIC1_CLK (MTK_PIN_NO(0) | 1)
> +#define PINMUX_GPIO0__FUNC_SPI3_A_MO (MTK_PIN_NO(0) | 3)
> +#define PINMUX_GPIO0__FUNC_FMI2S_B_LRCK (MTK_PIN_NO(0) | 4)
> +#define PINMUX_GPIO0__FUNC_SCP_DMIC1_CLK (MTK_PIN_NO(0) | 5)
> +#define PINMUX_GPIO0__FUNC_TP_GPIO14_AO (MTK_PIN_NO(0) | 6)


These aren't really bindings. If you disagree, point me to the usage in
the driver.



Best regards,
Krzysztof


From kevin.tian at intel.com  Tue Dec 10 23:55:53 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 07:55:53 +0000
Subject: [PATCH v2 05/13] iommufd: Add IOMMUFD_OBJ_EVENTQ_VIRQ and
 IOMMUFD_CMD_VIRQ_ALLOC
In-Reply-To: <7f5f7adc2493c7bca7edf76ca15b377c8dc0d397.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <7f5f7adc2493c7bca7edf76ca15b377c8dc0d397.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB52767F481C7D05EB1BDFD7D48C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> +
> +/* An iommufd_virq represents a vIOMMU interrupt in an eventq_virq
> queue */
> +struct iommufd_virq {
> +	struct iommufd_eventq_virq *eventq_virq;
> +	struct list_head node;
> +	ssize_t irq_len;
> +	void *irq_data;
> +};

looks the only use of eventq_virq is in below:

> +
> +static inline int iommufd_eventq_virq_handler(struct iommufd_virq *virq)
> +{
> +	return iommufd_eventq_notify(&virq->eventq_virq->common,
> &virq->node);
> +}

If there is no other intended usages upon that field, it's simpler to
remove it and directly pass the pointer in when the handler is 
called. Anyway iommufd_viommu_report_irq() needs to find the
eventq first before calling it.

> +/**
> + * struct iommu_virq_alloc - ioctl(IOMMU_VIRQ_ALLOC)
> + * @size: sizeof(struct iommu_virq_alloc)
> + * @flags: Must be 0
> + * @viommu: virtual IOMMU ID to associate the virtual IRQ with
> + * @type: Type of the virtual IRQ. Must be defined in enum
> iommu_virq_type
> + * @out_virq_id: The ID of the new virtual IRQ
> + * @out_fault_fd: The fd of the new virtual IRQ. User space must close the
> + *                successfully returned fd after using it

s/out_fault_fd/out_virq_fd/

> + *
> + * Explicitly allocate a virtual IRQ handler for a vIOMMU. A vIOMMU can
> have
> + * multiple FDs for different @type, but is confined to one FD per @type.
> + */

s/handler/interface/

> +
> +	eventq_virq->irq_wq = alloc_workqueue("viommu_irq/%d",
> WQ_UNBOUND, 0,
> +					      eventq_virq->common.obj.id);
> +	if (!eventq_virq->irq_wq) {
> +		rc = -ENOMEM;
> +		goto out_put_fdno;
> +	}

there is no use of this wq

> @@ -335,6 +335,8 @@ static const struct iommufd_ioctl_op
> iommufd_ioctl_ops[] = {
>  	IOCTL_OP(IOMMU_DESTROY, iommufd_destroy, struct
> iommu_destroy, id),
>  	IOCTL_OP(IOMMU_FAULT_QUEUE_ALLOC,
> iommufd_eventq_iopf_alloc,
>  		 struct iommu_fault_alloc, out_fault_fd),
> +	IOCTL_OP(IOMMU_VIRQ_ALLOC, iommufd_eventq_virq_alloc,
> +		 struct iommu_virq_alloc, out_virq_fd),

sort it in alphabetical order. 



From andrej.picej at norik.com  Tue Dec 10 23:57:17 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Wed, 11 Dec 2024 08:57:17 +0100
Subject: [PATCH v5 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <qhmsobin3fsmoc7ic2jtancowfscoauyroruxdpwhmqwlogtkz@6by3s2ruwzwp>
References: <20241210091901.83028-1-andrej.picej@norik.com>
 <20241210091901.83028-3-andrej.picej@norik.com>
 <irpmhq7vxjra6vhmdh7p63ajj57n3h2c4br3ija2jmwtoewist@zyxfmx6k5m4e>
 <aa2de99d-21f4-4843-83b7-5d2db78be86f@norik.com>
 <qhmsobin3fsmoc7ic2jtancowfscoauyroruxdpwhmqwlogtkz@6by3s2ruwzwp>
Message-ID: <519cc025-0782-4f96-a169-1fe87b280173@norik.com>



On 10. 12. 24 14:59, Dmitry Baryshkov wrote:
> On Tue, Dec 10, 2024 at 02:41:01PM +0100, Andrej Picej wrote:
>>
>>
>> On 10. 12. 24 12:43, Dmitry Baryshkov wrote:
>>> On Tue, Dec 10, 2024 at 10:19:00AM +0100, Andrej Picej wrote:
>>>> Add a optional properties to change LVDS output voltage. This should not
>>>> be static as this depends mainly on the connected display voltage
>>>> requirement. We have three properties:
>>>> - "ti,lvds-termination-ohms", which sets near end termination,
>>>> - "ti,lvds-vod-swing-data-microvolt" and
>>>> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
>>>> output voltage for data and clock lanes. They are defined as an array
>>>> with min and max values. The appropriate bitfield will be set if
>>>> selected constraints can be met.
>>>>
>>>> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
>>>> end termination will be used. Selecting only one:
>>>> "ti,lvds-vod-swing-data-microvolt" or
>>>> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
>>>> constraint for only data/clock lanes will be met. Setting both is
>>>> recommended.
>>>>
>>>> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
>>>> ---
>>>> Changes in v5:
>>>> - specify default values in sn65dsi83_parse_lvds_endpoint,
>>>> - move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
>>>> Changes in v4:
>>>> - fix typo in commit message bitfiled -> bitfield
>>>> - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
>>>> of separate variables for channel A/B
>>>> - add more checks on return value of "of_property_read_u32_array"
>>>> Changes in v3:
>>>> - use microvolts for default array values 1000 mV -> 1000000 uV.
>>>> Changes in v2:
>>>> - use datasheet tables to get the proper configuration
>>>> - since major change was done change the authorship to myself
>>>> ---
>>>>    drivers/gpu/drm/bridge/ti-sn65dsi83.c | 142 +++++++++++++++++++++++++-
>>>>    1 file changed, 139 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>> index 57a7ed13f996..f9578b38da28 100644
>>>> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>> @@ -132,6 +132,16 @@
>>>>    #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>>>>    #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>>>> +enum sn65dsi83_channel {
>>>> +	CHANNEL_A,
>>>> +	CHANNEL_B
>>>> +};
>>>> +
>>>> +enum sn65dsi83_lvds_term {
>>>> +	OHM_100,
>>>> +	OHM_200
>>>> +};
>>>> +
>>>>    enum sn65dsi83_model {
>>>>    	MODEL_SN65DSI83,
>>>>    	MODEL_SN65DSI84,
>>>> @@ -147,6 +157,8 @@ struct sn65dsi83 {
>>>>    	struct regulator		*vcc;
>>>>    	bool				lvds_dual_link;
>>>>    	bool				lvds_dual_link_even_odd_swap;
>>>> +	int				lvds_vod_swing_conf[2];
>>>> +	int				lvds_term_conf[2];
>>>>    };
>>>>    static const struct regmap_range sn65dsi83_readable_ranges[] = {
>>>> @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>>>>    	.max_register = REG_IRQ_STAT,
>>>>    };
>>>> +static const int lvds_vod_swing_data_table[2][4][2] = {
>>>> +	{	/* 100 Ohm */
>>>> +		{ 180000, 313000 },
>>>> +		{ 215000, 372000 },
>>>> +		{ 250000, 430000 },
>>>> +		{ 290000, 488000 },
>>>> +	},
>>>> +	{	/* 200 Ohm */
>>>> +		{ 150000, 261000 },
>>>> +		{ 200000, 346000 },
>>>> +		{ 250000, 428000 },
>>>> +		{ 300000, 511000 },
>>>> +	},
>>>> +};
>>>> +
>>>> +static const int lvds_vod_swing_clock_table[2][4][2] = {
>>>> +	{	/* 100 Ohm */
>>>> +		{ 140000, 244000 },
>>>> +		{ 168000, 290000 },
>>>> +		{ 195000, 335000 },
>>>> +		{ 226000, 381000 },
>>>> +	},
>>>> +	{	/* 200 Ohm */
>>>> +		{ 117000, 204000 },
>>>> +		{ 156000, 270000 },
>>>> +		{ 195000, 334000 },
>>>> +		{ 234000, 399000 },
>>>> +	},
>>>> +};
>>>> +
>>>>    static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>>>>    {
>>>>    	return container_of(bridge, struct sn65dsi83, bridge);
>>>> @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>>>>    		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>>>>    	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
>>>> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
>>>> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
>>>> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
>>>> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
>>>>    	regmap_write(ctx->regmap, REG_LVDS_LANE,
>>>>    		     (ctx->lvds_dual_link_even_odd_swap ?
>>>>    		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
>>>> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
>>>> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
>>>> +		     (ctx->lvds_term_conf[CHANNEL_A] ?
>>>> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
>>>> +		     (ctx->lvds_term_conf[CHANNEL_B] ?
>>>> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>>>>    	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>>>>    	le16val = cpu_to_le16(mode->hdisplay);
>>>> @@ -576,10 +622,100 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>>>>    	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>>>>    };
>>>> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
>>>> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
>>>> +{
>>>> +	int i;
>>>> +
>>>> +	for (i = 0; i <= 3; i++) {
>>>> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
>>>> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
>>>> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
>>>> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
>>>> +			return i;
>>>> +	}
>>>> +
>>>> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
>>>> +	return -EINVAL;
>>>> +}
>>>> +
>>>> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
>>>> +{
>>>> +	struct device *dev = ctx->dev;
>>>> +	struct device_node *endpoint;
>>>> +	int endpoint_reg;
>>>> +	/* Set so the property can be freely selected if not defined */
>>>> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
>>>> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
>>>> +	u32 lvds_term;
>>>> +	u8 lvds_term_conf = 0x1;
>>>> +	int lvds_vod_swing_conf = 0x1;
>>>
>>> Magic values
>>
>> Can you please elaborate.
>>
>> I can use:
>> u8 lvds_term_conf = OHM_200;
>>
>> What about lvds_vod_swing_conf? Should I create additional define for it?
>> But this doesn't solve a hidden meaning? Maybe additional comment above?
>> Would like to avoid using voltages for it, since then we are reverse
>> engineering the table in datasheet to match the default reg value.
> 
> I think the following example solves both problems:
> 
> lvds_term = 200;
> of_property_read_u32(..., &lvds_term);
> 
> if (lvds_term == 100)
> 	ctx->lvds_term_conf[channel] = OHM_100;
> else if (lvds_term == 200)
> 	ctx->lvds_term_conf[channel] = OHM_200;
> else
> 	return -EINVAL;
> 
> The same approach can be applied to lvds_vod_swing_conf, resulting in
> removal of magic values.

Sorry, but I think it is not that easy when it comes to the 
lvds_vod_swing_conf. We should assign default value if 
"ti,lvds-vod-swing-data-microvolt" and 
"ti,lvds-vod-swing-clock-microvolt" are not defined. Default value of 
the lvds_vod_swing_conf is 0x1, but this doesn't have any straight 
forward meaning like OHM_200 for example.

What we can do in that case is that we copy the values from defined 
datasheet tables to the "lvds_vod_swing_data[2]" and 
"lvds_vod_swing_clk[2]" arrays and then run the
sn65dsi83_select_lvds_vod_swing with it, which will return the default 
value (0x1).

/* If both properties are not defined assign default limits */
if (ret_data && ret_clock) {
	memcpy(lvds_vod_swing_data,
	     lvds_vod_swing_data_table[ctx->lvds_term_conf[channel]][1],
	     sizeof(lvds_vod_swing_data));
	memcpy(lvds_vod_swing_clk,
	    lvds_vod_swing_clock_table[ctx->lvds_term_conf[channel]][1],
	    sizeof(lvds_vod_swing_clk));
}
lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
	lvds_vod_swing_data, lvds_vod_swing_clk,
	ctx->lvds_term_conf[channel]);
if (lvds_vod_swing_conf < 0) {
	ret = lvds_vod_swing_conf;
	goto exit;
}

ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;

I'm not sure if using this approach gets rid of the problem with magic 
values.
Or maybe I'm not seeing the obvious solution so please bear with me.

> 
>>
>>>
>>>> +	int ret = 0;
>>>> +	int ret_data;
>>>> +	int ret_clock;
>>>> +
>>>> +	if (channel == CHANNEL_A)
>>>> +		endpoint_reg = 2;
>>>> +	else
>>>> +		endpoint_reg = 3;
>>>> +
>>>> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
>>>> +	if (!of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term)) {
>>>
>>> The code has been better before:
>>> provide default for lvds_term, read the property (keeping the default in
>>> case of an error), then use the lvds_term to set up lvds_term_conf, as
>>> expected.
>>
>> Ok, will revert back.
>>
>>>
>>>> +		if (lvds_term == 100)
>>>> +			lvds_term_conf = OHM_100;
>>>> +		else
>>>> +			lvds_term_conf = OHM_200;
>>>> +	}
>>>> +
>>>> +	ctx->lvds_term_conf[channel] = lvds_term_conf;
>>>> +
>>>> +	ret_data = of_property_read_u32_array(endpoint,
>>>> +			"ti,lvds-vod-swing-data-microvolt", lvds_vod_swing_data,
>>>> +			ARRAY_SIZE(lvds_vod_swing_data));
>>>> +	if (ret_data != 0 && ret_data != -EINVAL) {
>>>> +		ret = ret_data;
>>>> +		goto exit;
>>>> +	}
>>>> +
>>>> +	ret_clock = of_property_read_u32_array(endpoint,
>>>> +			"ti,lvds-vod-swing-clock-microvolt", lvds_vod_swing_clk,
>>>> +			ARRAY_SIZE(lvds_vod_swing_clk));
>>>> +	if (ret_clock != 0 && ret_clock != -EINVAL) {
>>>> +		ret = ret_clock;
>>>> +		goto exit;
>>>> +	}
>>>> +
>>>> +	/* If any of the two properties is defined. */
>>>> +	if (!ret_data || !ret_clock) {
>>>> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
>>>> +			lvds_vod_swing_data, lvds_vod_swing_clk,
>>>> +			lvds_term_conf);
>>>> +		if (lvds_vod_swing_conf < 0) {
>>>> +			ret = lvds_vod_swing_conf;
>>>> +			goto exit;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
>>>> +	ret = 0;
>>>> +exit:
>>>> +	of_node_put(endpoint);
>>>> +	return ret;
>>>> +}
>>>> +
>>>>    static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
>>>>    {
>>>>    	struct drm_bridge *panel_bridge;
>>>>    	struct device *dev = ctx->dev;
>>>> +	int ret;
>>>> +
>>>> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
>>>> +	if (ret < 0)
>>>> +		return ret;
>>>> +
>>>> +	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
>>>> +	if (ret < 0)
>>>> +		return ret;
>>>>    	ctx->lvds_dual_link = false;
>>>>    	ctx->lvds_dual_link_even_odd_swap = false;
>>>> -- 
>>>> 2.34.1
>>>>
>>>
> 


From kevin.tian at intel.com  Wed Dec 11 00:02:48 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 08:02:48 +0000
Subject: [PATCH v2 06/13] iommufd/viommu: Add iommufd_viommu_get_vdev_id
 helper
In-Reply-To: <d1e5f16d2fa4e9950e9caa93c5f98a5115c1580f.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <d1e5f16d2fa4e9950e9caa93c5f98a5115c1580f.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB52769AB45C92A820CC5233068C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> 
> +/* Return 0 if device is not associated to the vIOMMU */
> +unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu
> *viommu,
> +					 struct device *dev)
> +{
> +	struct iommufd_vdevice *vdev;
> +	unsigned long vdev_id = 0;
> +	unsigned long index;
> +
> +	xa_lock(&viommu->vdevs);
> +	xa_for_each(&viommu->vdevs, index, vdev) {
> +		if (vdev && vdev->dev == dev)

xa_for_each only find valid entries, so if (vdev) is redundant?

> +			vdev_id = (unsigned long)vdev->id;

break out of the loop if hit.

> +	}
> +	xa_unlock(&viommu->vdevs);
> +	return vdev_id;
> +}
> +EXPORT_SYMBOL_NS_GPL(iommufd_viommu_get_vdev_id, IOMMUFD);
> +
>  MODULE_DESCRIPTION("iommufd code shared with builtin modules");
>  MODULE_LICENSE("GPL");
> --
> 2.43.0



From kevin.tian at intel.com  Wed Dec 11 00:05:45 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 08:05:45 +0000
Subject: [PATCH v2 07/13] iommufd/viommu: Add iommufd_viommu_report_irq
 helper
In-Reply-To: <7e9842376e6235d9e3471356d035afe2bfe8f33b.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <7e9842376e6235d9e3471356d035afe2bfe8f33b.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB52768F3CBE04513D1536EB9B8C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> 
> +/* Typically called in driver's threaded IRQ handler */
> +int iommufd_viommu_report_irq(struct iommufd_viommu *viommu,
> unsigned int type,
> +			      void *irq_ptr, size_t irq_len)
> +{
> +	struct iommufd_eventq_virq *eventq_virq;
> +	struct iommufd_virq *virq;
> +	int rc = 0;
> +
> +	might_sleep();

why is it required here but not in the iopf path?

> +
> +	if (!viommu)
> +		return -ENODEV;
> +	if (WARN_ON_ONCE(!irq_len || !irq_ptr))
> +		return -EINVAL;
> +
> +	down_read(&viommu->virqs_rwsem);
> +
> +	eventq_virq = iommufd_viommu_find_eventq_virq(viommu, type);
> +	if (!eventq_virq) {
> +		rc = -EOPNOTSUPP;
> +		goto out_unlock_vdev_ids;

s/out_unlock_vdev_ids/out_unlock_virqs/

> +	}
> +
> +	virq = kzalloc(sizeof(*virq) + irq_len, GFP_KERNEL);
> +	if (!virq) {
> +		rc = -ENOMEM;
> +		goto out_unlock_vdev_ids;
> +	}
> +	virq->irq_data = (void *)virq + sizeof(*virq);
> +	memcpy(virq->irq_data, irq_ptr, irq_len);
> +
> +	virq->eventq_virq = eventq_virq;
> +	virq->irq_len = irq_len;
> +
> +	iommufd_eventq_virq_handler(virq);
> +out_unlock_vdev_ids:
> +	up_read(&viommu->virqs_rwsem);
> +	return rc;
> +}
> +EXPORT_SYMBOL_NS_GPL(iommufd_viommu_report_irq, IOMMUFD);
> +
>  MODULE_DESCRIPTION("iommufd code shared with builtin modules");
>  MODULE_LICENSE("GPL");
> --
> 2.43.0



From xianwei.zhao at amlogic.com  Wed Dec 11 00:08:19 2024
From: xianwei.zhao at amlogic.com (Xianwei Zhao)
Date: Wed, 11 Dec 2024 16:08:19 +0800
Subject: [PATCH v2 5/5] clk: meson: add A5 clock peripherals controller
 driver
In-Reply-To: <1jldx7tffh.fsf@starbuckisacylon.baylibre.com>
References: <20241120-a5-clk-v2-0-1208621e961d@amlogic.com>
 <20241120-a5-clk-v2-5-1208621e961d@amlogic.com>
 <1jldx7tffh.fsf@starbuckisacylon.baylibre.com>
Message-ID: <d0cb6c31-aebf-4662-93ca-274ee1bf4f98@amlogic.com>

Hi Jerome,
    Thanks for your reply.

On 2024/11/26 01:02, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> On Wed 20 Nov 2024 at 15:01, Xianwei Zhao via B4 Relay <devnull+xianwei.zhao.amlogic.com at kernel.org> wrote:
> 
>> From: Chuan Liu <chuan.liu at amlogic.com>
>>
>> Add the peripherals clock controller driver in the A5 SoC family.
>>
>> Signed-off-by: Chuan Liu <chuan.liu at amlogic.com>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
>> ---
>>   drivers/clk/meson/Kconfig          |   13 +
>>   drivers/clk/meson/Makefile         |    1 +
>>   drivers/clk/meson/a5-peripherals.c | 1387 ++++++++++++++++++++++++++++++++++++
>>   drivers/clk/meson/clk-regmap.h     |   17 +
>>   4 files changed, 1418 insertions(+)
>>
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index 3c97b3a1649d..79ec72156cee 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -146,6 +146,19 @@ config COMMON_CLK_A5_PLL
>>          Say Y if you want the board to work, because PLLs are the parent
>>          of most peripherals.
>>
>> +config COMMON_CLK_A5_PERIPHERALS
>> +     tristate "Amlogic A5 peripherals clock controller"
>> +     depends on ARM64
>> +     default y
>> +     imply COMMON_CLK_SCMI
>> +     imply COMMON_CLK_A5_PLL
>> +     select COMMON_CLK_MESON_REGMAP
>> +     select COMMON_CLK_MESON_DUALDIV
>> +     select COMMON_CLK_MESON_CLKC_UTILS
>> +     help
>> +       Support for the Peripherals clock controller on Amlogic AV40x device,
> 
> Same
Will remove it.
> 
>> +       AKA A5. Say Y if you want the peripherals clock to work.
>> +
>>   config COMMON_CLK_C3_PLL
>>        tristate "Amlogic C3 PLL clock controller"
>>        depends on ARM64
>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>> index fc4b8a723145..58236c6e8377 100644
>> --- a/drivers/clk/meson/Makefile
>> +++ b/drivers/clk/meson/Makefile
>> @@ -21,6 +21,7 @@ obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
>>   obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
>>   obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
>>   obj-$(CONFIG_COMMON_CLK_A5_PLL) += a5-pll.o
>> +obj-$(CONFIG_COMMON_CLK_A5_PERIPHERALS) += a5-peripherals.o
>>   obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
>>   obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>>   obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>> diff --git a/drivers/clk/meson/a5-peripherals.c b/drivers/clk/meson/a5-peripherals.c
>> new file mode 100644
>> index 000000000000..ed408f1c5b1f
>> --- /dev/null
>> +++ b/drivers/clk/meson/a5-peripherals.c
>> @@ -0,0 +1,1387 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Amlogic A5 Peripherals Clock Controller Driver
>> + *
>> + * Copyright (c) 2024 Amlogic, inc.
>> + * Author: Chuan Liu <chuan.liu at amlogic.com>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/platform_device.h>
>> +#include "clk-regmap.h"
>> +#include "clk-dualdiv.h"
>> +#include "meson-clkc-utils.h"
>> +#include <dt-bindings/clock/amlogic,a5-peripherals-clkc.h>
>> +
>> +#define CLKCTRL_RTC_BY_OSCIN_CTRL0           0x8
>> +#define CLKCTRL_RTC_BY_OSCIN_CTRL1           0xc
>> +#define CLKCTRL_RTC_CTRL                     0x10
>> +#define CLKCTRL_SYS_CLK_EN0_REG0             0x44
>> +#define CLKCTRL_SYS_CLK_EN0_REG1             0x48
>> +#define CLKCTRL_DSPA_CLK_CTRL0                       0x9c
>> +#define CLKCTRL_CLK12_24_CTRL                        0xa8
>> +#define CLKCTRL_AXI_CLK_EN0                  0xac
>> +#define CLKCTRL_TS_CLK_CTRL                  0x158
>> +#define CLKCTRL_ETH_CLK_CTRL                 0x164
>> +#define CLKCTRL_NAND_CLK_CTRL                        0x168
>> +#define CLKCTRL_SD_EMMC_CLK_CTRL             0x16c
>> +#define CLKCTRL_SPICC_CLK_CTRL                       0x174
>> +#define CLKCTRL_GEN_CLK_CTRL                 0x178
>> +#define CLKCTRL_SAR_CLK_CTRL0                        0x17c
>> +#define CLKCTRL_PWM_CLK_AB_CTRL                      0x180
>> +#define CLKCTRL_PWM_CLK_CD_CTRL                      0x184
>> +#define CLKCTRL_PWM_CLK_EF_CTRL                      0x188
>> +#define CLKCTRL_PWM_CLK_GH_CTRL                      0x18c
>> +#define CLKCTRL_NNA_CLK_CNTL                 0x220
> 
> Same comment as previous patches
>

there are no registers of other modules interspersed in it.

>> +
>> +static struct clk_regmap rtc_xtal_clkin = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0,
>> +             .bit_idx = 31,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_xtal_clkin",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "oscin",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct meson_clk_dualdiv_param rtc_32k_div_table[] = {
>> +     { 733, 732, 8, 11, 1 },
>> +     { /* sentinel */ }
>> +};
>> +
>> +static struct clk_regmap rtc_32k_div = {
>> +     .data = &(struct meson_clk_dualdiv_data) {
>> +             .n1 = {
>> +                     .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0,
>> +                     .shift   = 0,
>> +                     .width   = 12,
>> +             },
>> +             .n2 = {
>> +                     .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0,
>> +                     .shift   = 12,
>> +                     .width   = 12,
>> +             },
>> +             .m1 = {
>> +                     .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1,
>> +                     .shift   = 0,
>> +                     .width   = 12,
>> +             },
>> +             .m2 = {
>> +                     .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1,
>> +                     .shift   = 12,
>> +                     .width   = 12,
>> +             },
>> +             .dual = {
>> +                     .reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0,
>> +                     .shift   = 28,
>> +                     .width   = 1,
>> +             },
>> +             .table = rtc_32k_div_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_32k_div",
>> +             .ops = &meson_clk_dualdiv_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &rtc_xtal_clkin.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data rtc_32k_mux_parent_data[] = {
>> +     { .hw = &rtc_32k_div.hw },
>> +     { .hw = &rtc_xtal_clkin.hw }
>> +};
>> +
>> +static struct clk_regmap rtc_32k_mux = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_RTC_BY_OSCIN_CTRL1,
>> +             .mask = 0x1,
>> +             .shift = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_32k_mux",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = rtc_32k_mux_parent_data,
>> +             .num_parents = ARRAY_SIZE(rtc_32k_mux_parent_data),
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap rtc_32k = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0,
>> +             .bit_idx = 30,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_32k",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &rtc_32k_mux.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data rtc_clk_mux_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .hw = &rtc_32k.hw },
>> +     { .fw_name = "pad_osc" }
>> +};
>> +
>> +static struct clk_regmap rtc_clk = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_RTC_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 0,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_clk",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = rtc_clk_mux_parent_data,
>> +             .num_parents = ARRAY_SIZE(rtc_clk_mux_parent_data),
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +#define A5_SYS_GATE(_name, _reg, _bit, _flags)                               \
>> +     MESON_CLK_GATE_FW(_name, _reg, _bit, sysclk,                    \
>> +                     &clk_regmap_gate_ops, _flags)
>> +
>> +static A5_SYS_GATE(sys_reset_ctrl,   CLKCTRL_SYS_CLK_EN0_REG0, 1, 0);
>> +static A5_SYS_GATE(sys_pwr_ctrl,     CLKCTRL_SYS_CLK_EN0_REG0, 3, 0);
>> +static A5_SYS_GATE(sys_pad_ctrl,     CLKCTRL_SYS_CLK_EN0_REG0, 4, 0);
>> +static A5_SYS_GATE(sys_ctrl,         CLKCTRL_SYS_CLK_EN0_REG0, 5, 0);
>> +static A5_SYS_GATE(sys_ts_pll,               CLKCTRL_SYS_CLK_EN0_REG0, 6, 0);
>> +
>> +/*
>> + * NOTE: sys_dev_arb provides the clock to the ETH and SPICC arbiters that
>> + * access the AXI bus.
>> + */
>> +static A5_SYS_GATE(sys_dev_arb,              CLKCTRL_SYS_CLK_EN0_REG0, 7, 0);
>> +static A5_SYS_GATE(sys_mailbox,              CLKCTRL_SYS_CLK_EN0_REG0, 10, 0);
>> +static A5_SYS_GATE(sys_jtag_ctrl,    CLKCTRL_SYS_CLK_EN0_REG0, 12, 0);
>> +static A5_SYS_GATE(sys_ir_ctrl,              CLKCTRL_SYS_CLK_EN0_REG0, 13, 0);
>> +static A5_SYS_GATE(sys_msr_clk,              CLKCTRL_SYS_CLK_EN0_REG0, 15, 0);
>> +static A5_SYS_GATE(sys_rom,          CLKCTRL_SYS_CLK_EN0_REG0, 16, 0);
>> +static A5_SYS_GATE(sys_cpu_apb,              CLKCTRL_SYS_CLK_EN0_REG0, 18, 0);
>> +static A5_SYS_GATE(sys_rsa,          CLKCTRL_SYS_CLK_EN0_REG0, 19, 0);
>> +static A5_SYS_GATE(sys_sar_adc,              CLKCTRL_SYS_CLK_EN0_REG0, 20, 0);
>> +static A5_SYS_GATE(sys_startup,              CLKCTRL_SYS_CLK_EN0_REG0, 21, 0);
>> +static A5_SYS_GATE(sys_secure,               CLKCTRL_SYS_CLK_EN0_REG0, 22, 0);
>> +static A5_SYS_GATE(sys_spifc,                CLKCTRL_SYS_CLK_EN0_REG0, 23, 0);
>> +static A5_SYS_GATE(sys_dspa,         CLKCTRL_SYS_CLK_EN0_REG0, 24, 0);
>> +static A5_SYS_GATE(sys_nna,          CLKCTRL_SYS_CLK_EN0_REG0, 25, 0);
>> +static A5_SYS_GATE(sys_eth_mac,              CLKCTRL_SYS_CLK_EN0_REG0, 26, 0);
>> +static A5_SYS_GATE(sys_rama,         CLKCTRL_SYS_CLK_EN0_REG0, 28, 0);
>> +static A5_SYS_GATE(sys_ramb,         CLKCTRL_SYS_CLK_EN0_REG0, 30, 0);
>> +static A5_SYS_GATE(sys_audio_top,    CLKCTRL_SYS_CLK_EN0_REG1, 0, 0);
>> +static A5_SYS_GATE(sys_audio_vad,    CLKCTRL_SYS_CLK_EN0_REG1, 1, 0);
>> +static A5_SYS_GATE(sys_usb,          CLKCTRL_SYS_CLK_EN0_REG1, 2, 0);
>> +static A5_SYS_GATE(sys_sd_emmc_a,    CLKCTRL_SYS_CLK_EN0_REG1, 3, 0);
>> +static A5_SYS_GATE(sys_sd_emmc_c,    CLKCTRL_SYS_CLK_EN0_REG1, 4, 0);
>> +static A5_SYS_GATE(sys_pwm_ab,               CLKCTRL_SYS_CLK_EN0_REG1, 5, 0);
>> +static A5_SYS_GATE(sys_pwm_cd,               CLKCTRL_SYS_CLK_EN0_REG1, 6, 0);
>> +static A5_SYS_GATE(sys_pwm_ef,               CLKCTRL_SYS_CLK_EN0_REG1, 7, 0);
>> +static A5_SYS_GATE(sys_pwm_gh,               CLKCTRL_SYS_CLK_EN0_REG1, 8, 0);
>> +static A5_SYS_GATE(sys_spicc_1,              CLKCTRL_SYS_CLK_EN0_REG1, 9, 0);
>> +static A5_SYS_GATE(sys_spicc_0,              CLKCTRL_SYS_CLK_EN0_REG1, 10, 0);
>> +static A5_SYS_GATE(sys_uart_a,               CLKCTRL_SYS_CLK_EN0_REG1, 11, 0);
>> +static A5_SYS_GATE(sys_uart_b,               CLKCTRL_SYS_CLK_EN0_REG1, 12, 0);
>> +static A5_SYS_GATE(sys_uart_c,               CLKCTRL_SYS_CLK_EN0_REG1, 13, 0);
>> +static A5_SYS_GATE(sys_uart_d,               CLKCTRL_SYS_CLK_EN0_REG1, 14, 0);
>> +static A5_SYS_GATE(sys_uart_e,               CLKCTRL_SYS_CLK_EN0_REG1, 15, 0);
>> +static A5_SYS_GATE(sys_i2c_m_a,              CLKCTRL_SYS_CLK_EN0_REG1, 16, 0);
>> +static A5_SYS_GATE(sys_i2c_m_b,              CLKCTRL_SYS_CLK_EN0_REG1, 17, 0);
>> +static A5_SYS_GATE(sys_i2c_m_c,              CLKCTRL_SYS_CLK_EN0_REG1, 18, 0);
>> +static A5_SYS_GATE(sys_i2c_m_d,              CLKCTRL_SYS_CLK_EN0_REG1, 19, 0);
>> +static A5_SYS_GATE(sys_rtc,          CLKCTRL_SYS_CLK_EN0_REG1, 21, 0);
>> +
>> +#define A5_AXI_GATE(_name, _reg, _bit, _flags)                               \
>> +     MESON_CLK_GATE_FW(_name, _reg, _bit, axiclk,                    \
>> +                     &clk_regmap_gate_ops, _flags)
>> +
>> +static A5_AXI_GATE(axi_audio_vad,    CLKCTRL_AXI_CLK_EN0, 0, 0);
>> +static A5_AXI_GATE(axi_audio_top,    CLKCTRL_AXI_CLK_EN0, 1, 0);
>> +static A5_AXI_GATE(axi_ramb,         CLKCTRL_AXI_CLK_EN0, 5, 0);
>> +static A5_AXI_GATE(axi_rama,         CLKCTRL_AXI_CLK_EN0, 6, 0);
>> +static A5_AXI_GATE(axi_nna,          CLKCTRL_AXI_CLK_EN0, 12, 0);
>> +
>> +/*
>> + * NOTE: axi_dev1_dmc provides the clock for the peripherals(EMMC, SDIO,
>> + * sec_top, USB, Audio) to access the AXI bus of the DDR.
>> + */
>> +static A5_AXI_GATE(axi_dev1_dmc,     CLKCTRL_AXI_CLK_EN0, 13, 0);
>> +
>> +/*
>> + * NOTE: axi_dev0_dmc provides the clock for the peripherals(ETH and SPICC)
>> + * to access the AXI bus of the DDR.
>> + */
>> +static A5_AXI_GATE(axi_dev0_dmc,     CLKCTRL_AXI_CLK_EN0, 14, 0);
>> +static A5_AXI_GATE(axi_dsp_dmc,              CLKCTRL_AXI_CLK_EN0, 15, 0);
>> +
>> +static struct clk_regmap clk_12_24m_in = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_CLK12_24_CTRL,
>> +             .bit_idx = 11,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "clk_12_24m_in",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "xtal_24m",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap clk_12_24m = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_CLK12_24_CTRL,
>> +             .shift = 10,
>> +             .width = 1,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "clk_12_24m",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &clk_12_24m_in.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap fclk_25m_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_CLK12_24_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_25m_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "fix",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap fclk_25m = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_CLK12_24_CTRL,
>> +             .bit_idx = 12,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_25m",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fclk_25m_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +/*
>> + * Channel 4 5 8 9 10 11 13 14 15 16 18 are not connected.
>> + *
>> + * gp1 is designed for DSU (DynamIQ Shared Unit) alone. It cannot be changed
>> + * arbitrarily. gp1 is read-only in the kernel and is only open for debug
>> + * purposes.
>> + */
>> +static u32 gen_parent_table[] = { 0, 1, 2, 3, 6, 7, 12, 17, 19, 20, 21, 22, 23,
>> +                               24, 25, 26, 27, 28};
>> +
>> +static const struct clk_parent_data gen_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .hw = &rtc_clk.hw },
>> +     { .fw_name = "sysplldiv16" },
>> +     { .fw_name = "ddr" },
>> +     { .fw_name = "gp1" },
>> +     { .fw_name = "hifi" },
>> +     { .fw_name = "clkmsr" },
>> +     { .fw_name = "cpudiv16" },
>> +     { .fw_name = "fdiv2" },
>> +     { .fw_name = "fdiv2p5" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "fdiv4" },
>> +     { .fw_name = "fdiv5" },
>> +     { .fw_name = "fdiv7" },
>> +     { .fw_name = "mpll0" },
>> +     { .fw_name = "mpll1" },
>> +     { .fw_name = "mpll2" },
>> +     { .fw_name = "mpll3" }
>> +};
>> +
>> +static struct clk_regmap gen_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_GEN_CLK_CTRL,
>> +             .mask = 0x1f,
>> +             .shift = 12,
>> +             .table = gen_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "gen_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = gen_parent_data,
>> +             .num_parents = ARRAY_SIZE(gen_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap gen_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_GEN_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 11,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "gen_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &gen_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap gen = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_GEN_CLK_CTRL,
>> +             .bit_idx = 11,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "gen",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &gen_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data saradc_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "sysclk" }
>> +};
>> +
>> +static struct clk_regmap saradc_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_SAR_CLK_CTRL0,
>> +             .mask = 0x1,
>> +             .shift = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "saradc_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = saradc_parent_data,
>> +             .num_parents = ARRAY_SIZE(saradc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap saradc_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_SAR_CLK_CTRL0,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "saradc_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &saradc_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap saradc = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_SAR_CLK_CTRL0,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "saradc",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &saradc_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data pwm_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .hw = &rtc_clk.hw },
>> +     { .fw_name = "fdiv4" },
>> +     { .fw_name = "fdiv3" }
>> +};
>> +
>> +#define AML_PWM_CLK_MUX(_name, _reg, _shift) {                       \
>> +     .data = &(struct clk_regmap_mux_data) {                 \
>> +             .offset = _reg,                                 \
>> +             .mask = 0x3,                                    \
>> +             .shift = _shift,                                \
>> +     },                                                      \
>> +     .hw.init = &(struct clk_init_data) {                    \
>> +             .name = #_name "_sel",                          \
>> +             .ops = &clk_regmap_mux_ops,                     \
>> +             .parent_data = pwm_parent_data,                 \
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),     \
>> +     },                                                      \
>> +}
>> +
>> +#define AML_PWM_CLK_DIV(_name, _reg, _shift) {                       \
>> +     .data = &(struct clk_regmap_div_data) {                 \
>> +             .offset = _reg,                                 \
>> +             .shift = _shift,                                \
>> +             .width = 8,                                     \
>> +     },                                                      \
>> +     .hw.init = &(struct clk_init_data) {                    \
>> +             .name = #_name "_div",                          \
>> +             .ops = &clk_regmap_divider_ops,                 \
>> +             .parent_names = (const char *[]) { #_name "_sel" },\
>> +             .num_parents = 1,                               \
>> +             .flags = CLK_SET_RATE_PARENT,                   \
>> +     },                                                      \
>> +}
>> +
>> +#define AML_PWM_CLK_GATE(_name, _reg, _bit) {                        \
>> +     .data = &(struct clk_regmap_gate_data) {                \
>> +             .offset = _reg,                                 \
>> +             .bit_idx = _bit,                                \
>> +     },                                                      \
>> +     .hw.init = &(struct clk_init_data) {                    \
>> +             .name = #_name,                                 \
>> +             .ops = &clk_regmap_gate_ops,                    \
>> +             .parent_names = (const char *[]) { #_name "_div" },\
>> +             .num_parents = 1,                               \
>> +             .flags = CLK_SET_RATE_PARENT,                   \
>> +     },                                                      \
>> +}
>> +
>> +static struct clk_regmap pwm_a_sel =
>> +     AML_PWM_CLK_MUX(pwm_a, CLKCTRL_PWM_CLK_AB_CTRL, 9);
>> +static struct clk_regmap pwm_a_div =
>> +     AML_PWM_CLK_DIV(pwm_a, CLKCTRL_PWM_CLK_AB_CTRL, 0);
>> +static struct clk_regmap pwm_a =
>> +     AML_PWM_CLK_GATE(pwm_a, CLKCTRL_PWM_CLK_AB_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_b_sel =
>> +     AML_PWM_CLK_MUX(pwm_b, CLKCTRL_PWM_CLK_AB_CTRL, 25);
>> +static struct clk_regmap pwm_b_div =
>> +     AML_PWM_CLK_DIV(pwm_b, CLKCTRL_PWM_CLK_AB_CTRL, 16);
>> +static struct clk_regmap pwm_b =
>> +     AML_PWM_CLK_GATE(pwm_b, CLKCTRL_PWM_CLK_AB_CTRL, 24);
>> +
>> +static struct clk_regmap pwm_c_sel =
>> +     AML_PWM_CLK_MUX(pwm_c, CLKCTRL_PWM_CLK_CD_CTRL, 9);
>> +static struct clk_regmap pwm_c_div =
>> +     AML_PWM_CLK_DIV(pwm_c, CLKCTRL_PWM_CLK_CD_CTRL, 0);
>> +static struct clk_regmap pwm_c =
>> +     AML_PWM_CLK_GATE(pwm_c, CLKCTRL_PWM_CLK_CD_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_d_sel =
>> +     AML_PWM_CLK_MUX(pwm_d, CLKCTRL_PWM_CLK_CD_CTRL, 25);
>> +static struct clk_regmap pwm_d_div =
>> +     AML_PWM_CLK_DIV(pwm_d, CLKCTRL_PWM_CLK_CD_CTRL, 16);
>> +static struct clk_regmap pwm_d =
>> +     AML_PWM_CLK_GATE(pwm_d, CLKCTRL_PWM_CLK_CD_CTRL, 24);
>> +
>> +static struct clk_regmap pwm_e_sel =
>> +     AML_PWM_CLK_MUX(pwm_e, CLKCTRL_PWM_CLK_EF_CTRL, 9);
>> +static struct clk_regmap pwm_e_div =
>> +     AML_PWM_CLK_DIV(pwm_e, CLKCTRL_PWM_CLK_EF_CTRL, 0);
>> +static struct clk_regmap pwm_e =
>> +     AML_PWM_CLK_GATE(pwm_e, CLKCTRL_PWM_CLK_EF_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_f_sel =
>> +     AML_PWM_CLK_MUX(pwm_f, CLKCTRL_PWM_CLK_EF_CTRL, 25);
>> +static struct clk_regmap pwm_f_div =
>> +     AML_PWM_CLK_DIV(pwm_f, CLKCTRL_PWM_CLK_EF_CTRL, 16);
>> +static struct clk_regmap pwm_f =
>> +     AML_PWM_CLK_GATE(pwm_f, CLKCTRL_PWM_CLK_EF_CTRL, 24);
>> +
>> +static struct clk_regmap pwm_g_sel =
>> +     AML_PWM_CLK_MUX(pwm_g, CLKCTRL_PWM_CLK_GH_CTRL, 9);
>> +static struct clk_regmap pwm_g_div =
>> +     AML_PWM_CLK_DIV(pwm_g, CLKCTRL_PWM_CLK_GH_CTRL, 0);
>> +static struct clk_regmap pwm_g =
>> +     AML_PWM_CLK_GATE(pwm_g, CLKCTRL_PWM_CLK_GH_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_h_sel =
>> +     AML_PWM_CLK_MUX(pwm_h, CLKCTRL_PWM_CLK_GH_CTRL, 25);
>> +static struct clk_regmap pwm_h_div =
>> +     AML_PWM_CLK_DIV(pwm_h, CLKCTRL_PWM_CLK_GH_CTRL, 16);
>> +static struct clk_regmap pwm_h =
>> +     AML_PWM_CLK_GATE(pwm_h, CLKCTRL_PWM_CLK_GH_CTRL, 24);
>> +
>> +static const struct clk_parent_data spicc_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "sysclk" },
>> +     { .fw_name = "fdiv4" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "fdiv2" },
>> +     { .fw_name = "fdiv5" },
>> +     { .fw_name = "fdiv7" }
>> +};
>> +
>> +static struct clk_regmap spicc_0_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_SPICC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "spicc_0_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = spicc_parent_data,
>> +             .num_parents = ARRAY_SIZE(spicc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_0_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_SPICC_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 6,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "spicc_0_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spicc_0_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_0 = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_SPICC_CLK_CTRL,
>> +             .bit_idx = 6,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "spicc_0",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spicc_0_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_1_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_SPICC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 23,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "spicc_1_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = spicc_parent_data,
>> +             .num_parents = ARRAY_SIZE(spicc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_1_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_SPICC_CLK_CTRL,
>> +             .shift = 16,
>> +             .width = 6,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "spicc_1_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spicc_1_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_1 = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_SPICC_CLK_CTRL,
>> +             .bit_idx = 22,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "spicc_1",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spicc_1_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data emmc_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "fdiv2" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "hifi" },
>> +     { .fw_name = "fdiv2p5" },
>> +     { .fw_name = "mpll2" },
>> +     { .fw_name = "mpll3" },
>> +     { .fw_name = "gp0" }
>> +};
>> +
>> +static struct clk_regmap sd_emmc_a_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_SD_EMMC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sd_emmc_a_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = emmc_parent_data,
>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_a_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_SD_EMMC_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sd_emmc_a_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_a_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_a = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_SD_EMMC_CLK_CTRL,
>> +             .bit_idx = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sd_emmc_a",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_a_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_c_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_NAND_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sd_emmc_c_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = emmc_parent_data,
>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_c_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_NAND_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sd_emmc_c_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_c_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_c = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_NAND_CLK_CTRL,
>> +             .bit_idx = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sd_emmc_c",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_c_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap ts_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_TS_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "ts_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "oscin",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap ts = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_TS_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "ts",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &ts_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_fixed_factor eth_125m_div = {
>> +     .mult = 1,
>> +     .div = 8,
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "eth_125m_div",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "fdiv2",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap eth_125m = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_ETH_CLK_CTRL,
>> +             .bit_idx = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "eth_125m",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &eth_125m_div.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap eth_rmii_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_ETH_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "eth_rmii_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "fdiv2",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap eth_rmii = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_ETH_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "eth_rmii",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &eth_rmii_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +/* Channel 6 is gp1. */
>> +static u32 dspa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7};
>> +
>> +static const struct clk_parent_data dspa_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "fdiv2p5" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "rtc" },
>> +     { .fw_name = "hifi" },
>> +     { .fw_name = "fdiv4" },
>> +     { .hw = &rtc_clk.hw }
>> +};
>> +
>> +static struct clk_regmap dspa_0_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_DSPA_CLK_CTRL0,
>> +             .mask = 0x7,
>> +             .shift = 10,
>> +             .table = dspa_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_0_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = dspa_parent_data,
>> +             .num_parents = ARRAY_SIZE(dspa_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap dspa_0_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_DSPA_CLK_CTRL0,
>> +             .shift = 0,
>> +             .width = 10,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_0_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &dspa_0_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap dspa_0 = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_DSPA_CLK_CTRL0,
>> +             .bit_idx = 13,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_0",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &dspa_0_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap dspa_1_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_DSPA_CLK_CTRL0,
>> +             .mask = 0x7,
>> +             .shift = 26,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_1_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = dspa_parent_data,
>> +             .num_parents = ARRAY_SIZE(dspa_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap dspa_1_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_DSPA_CLK_CTRL0,
>> +             .shift = 16,
>> +             .width = 10,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_1_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &dspa_1_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap dspa_1 = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_DSPA_CLK_CTRL0,
>> +             .bit_idx = 29,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_1",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &dspa_1_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap dspa = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = CLKCTRL_DSPA_CLK_CTRL0,
>> +             .mask = 0x1,
>> +             .shift = 15,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &dspa_0.hw,
>> +                     &dspa_1.hw
>> +             },
>> +             .num_parents = 2,
>> +             /*
>> +              * NOTE: This level of mux is "no glitch mux", and mux_0
>> +              * (here dspa_0) is not only the clock source for mux, but also
>> +              * provides a working clock for "no glitch mux". "no glitch mux"
>> +              * can be switched only when mux_0 has a clock input. Therefore,
>> +              * add flag CLK_OPS_PARENT_ENABLE to ensure that mux_0 has clock
>> +              * when "no glitch mux" works.
>> +              */
>> +             .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
>> +     },
>> +};
>> +
>> +/* Channel 6 is gp1. */
>> +static u32 nna_parent_table[] = { 0, 1, 2, 3, 4, 5, 7};
>> +
>> +static const struct clk_parent_data nna_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "fdiv2p5" },
>> +     { .fw_name = "fdiv4" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "fdiv5" },
>> +     { .fw_name = "fdiv2" },
>> +     { .fw_name = "hifi" }
>> +};
>> +
>> +static struct clk_regmap nna_core_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_NNA_CLK_CNTL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +             .table = nna_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "nna_core_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = nna_parent_data,
>> +             .num_parents = ARRAY_SIZE(nna_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap nna_core_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_NNA_CLK_CNTL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "nna_core_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &nna_core_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap nna_core = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_NNA_CLK_CNTL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "nna_core",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &nna_core_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap nna_axi_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = CLKCTRL_NNA_CLK_CNTL,
>> +             .mask = 0x7,
>> +             .shift = 25,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "nna_axi_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = nna_parent_data,
>> +             .num_parents = ARRAY_SIZE(nna_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap nna_axi_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLKCTRL_NNA_CLK_CNTL,
>> +             .shift = 16,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "nna_axi_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &nna_axi_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap nna_axi = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLKCTRL_NNA_CLK_CNTL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "nna_axi",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &nna_axi_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_hw *a5_periphs_hw_clks[] = {
>> +     [CLKID_RTC_XTAL_CLKIN]          = &rtc_xtal_clkin.hw,
>> +     [CLKID_RTC_32K_DIV]             = &rtc_32k_div.hw,
>> +     [CLKID_RTC_32K_MUX]             = &rtc_32k_mux.hw,
>> +     [CLKID_RTC_32K]                 = &rtc_32k.hw,
>> +     [CLKID_RTC_CLK]                 = &rtc_clk.hw,
>> +     [CLKID_SYS_RESET_CTRL]          = &sys_reset_ctrl.hw,
>> +     [CLKID_SYS_PWR_CTRL]            = &sys_pwr_ctrl.hw,
>> +     [CLKID_SYS_PAD_CTRL]            = &sys_pad_ctrl.hw,
>> +     [CLKID_SYS_CTRL]                = &sys_ctrl.hw,
>> +     [CLKID_SYS_TS_PLL]              = &sys_ts_pll.hw,
>> +     [CLKID_SYS_DEV_ARB]             = &sys_dev_arb.hw,
>> +     [CLKID_SYS_MAILBOX]             = &sys_mailbox.hw,
>> +     [CLKID_SYS_JTAG_CTRL]           = &sys_jtag_ctrl.hw,
>> +     [CLKID_SYS_IR_CTRL]             = &sys_ir_ctrl.hw,
>> +     [CLKID_SYS_MSR_CLK]             = &sys_msr_clk.hw,
>> +     [CLKID_SYS_ROM]                 = &sys_rom.hw,
>> +     [CLKID_SYS_CPU_ARB]             = &sys_cpu_apb.hw,
>> +     [CLKID_SYS_RSA]                 = &sys_rsa.hw,
>> +     [CLKID_SYS_SAR_ADC]             = &sys_sar_adc.hw,
>> +     [CLKID_SYS_STARTUP]             = &sys_startup.hw,
>> +     [CLKID_SYS_SECURE]              = &sys_secure.hw,
>> +     [CLKID_SYS_SPIFC]               = &sys_spifc.hw,
>> +     [CLKID_SYS_DSPA]                = &sys_dspa.hw,
>> +     [CLKID_SYS_NNA]                 = &sys_nna.hw,
>> +     [CLKID_SYS_ETH_MAC]             = &sys_eth_mac.hw,
>> +     [CLKID_SYS_RAMA]                = &sys_rama.hw,
>> +     [CLKID_SYS_RAMB]                = &sys_ramb.hw,
>> +     [CLKID_SYS_AUDIO_TOP]           = &sys_audio_top.hw,
>> +     [CLKID_SYS_AUDIO_VAD]           = &sys_audio_vad.hw,
>> +     [CLKID_SYS_USB]                 = &sys_usb.hw,
>> +     [CLKID_SYS_SD_EMMC_A]           = &sys_sd_emmc_a.hw,
>> +     [CLKID_SYS_SD_EMMC_C]           = &sys_sd_emmc_c.hw,
>> +     [CLKID_SYS_PWM_AB]              = &sys_pwm_ab.hw,
>> +     [CLKID_SYS_PWM_CD]              = &sys_pwm_cd.hw,
>> +     [CLKID_SYS_PWM_EF]              = &sys_pwm_ef.hw,
>> +     [CLKID_SYS_PWM_GH]              = &sys_pwm_gh.hw,
>> +     [CLKID_SYS_SPICC_1]             = &sys_spicc_1.hw,
>> +     [CLKID_SYS_SPICC_0]             = &sys_spicc_0.hw,
>> +     [CLKID_SYS_UART_A]              = &sys_uart_a.hw,
>> +     [CLKID_SYS_UART_B]              = &sys_uart_b.hw,
>> +     [CLKID_SYS_UART_C]              = &sys_uart_c.hw,
>> +     [CLKID_SYS_UART_D]              = &sys_uart_d.hw,
>> +     [CLKID_SYS_UART_E]              = &sys_uart_e.hw,
>> +     [CLKID_SYS_I2C_M_A]             = &sys_i2c_m_a.hw,
>> +     [CLKID_SYS_I2C_M_B]             = &sys_i2c_m_b.hw,
>> +     [CLKID_SYS_I2C_M_C]             = &sys_i2c_m_c.hw,
>> +     [CLKID_SYS_I2C_M_D]             = &sys_i2c_m_d.hw,
>> +     [CLKID_SYS_RTC]                 = &sys_rtc.hw,
>> +     [CLKID_AXI_AUDIO_VAD]           = &axi_audio_vad.hw,
>> +     [CLKID_AXI_AUDIO_TOP]           = &axi_audio_top.hw,
>> +     [CLKID_AXI_RAMB]                = &axi_ramb.hw,
>> +     [CLKID_AXI_RAMA]                = &axi_rama.hw,
>> +     [CLKID_AXI_NNA]                 = &axi_nna.hw,
>> +     [CLKID_AXI_DEV1_DMC]            = &axi_dev1_dmc.hw,
>> +     [CLKID_AXI_DEV0_DMC]            = &axi_dev0_dmc.hw,
>> +     [CLKID_AXI_DSP_DMC]             = &axi_dsp_dmc.hw,
>> +     [CLKID_12_24M_IN]               = &clk_12_24m_in.hw,
>> +     [CLKID_12M_24M]                 = &clk_12_24m.hw,
>> +     [CLKID_FCLK_25M_DIV]            = &fclk_25m_div.hw,
>> +     [CLKID_FCLK_25M]                = &fclk_25m.hw,
>> +     [CLKID_GEN_SEL]                 = &gen_sel.hw,
>> +     [CLKID_GEN_DIV]                 = &gen_div.hw,
>> +     [CLKID_GEN]                     = &gen.hw,
>> +     [CLKID_SARADC_SEL]              = &saradc_sel.hw,
>> +     [CLKID_SARADC_DIV]              = &saradc_div.hw,
>> +     [CLKID_SARADC]                  = &saradc.hw,
>> +     [CLKID_PWM_A_SEL]               = &pwm_a_sel.hw,
>> +     [CLKID_PWM_A_DIV]               = &pwm_a_div.hw,
>> +     [CLKID_PWM_A]                   = &pwm_a.hw,
>> +     [CLKID_PWM_B_SEL]               = &pwm_b_sel.hw,
>> +     [CLKID_PWM_B_DIV]               = &pwm_b_div.hw,
>> +     [CLKID_PWM_B]                   = &pwm_b.hw,
>> +     [CLKID_PWM_C_SEL]               = &pwm_c_sel.hw,
>> +     [CLKID_PWM_C_DIV]               = &pwm_c_div.hw,
>> +     [CLKID_PWM_C]                   = &pwm_c.hw,
>> +     [CLKID_PWM_D_SEL]               = &pwm_d_sel.hw,
>> +     [CLKID_PWM_D_DIV]               = &pwm_d_div.hw,
>> +     [CLKID_PWM_D]                   = &pwm_d.hw,
>> +     [CLKID_PWM_E_SEL]               = &pwm_e_sel.hw,
>> +     [CLKID_PWM_E_DIV]               = &pwm_e_div.hw,
>> +     [CLKID_PWM_E]                   = &pwm_e.hw,
>> +     [CLKID_PWM_F_SEL]               = &pwm_f_sel.hw,
>> +     [CLKID_PWM_F_DIV]               = &pwm_f_div.hw,
>> +     [CLKID_PWM_F]                   = &pwm_f.hw,
>> +     [CLKID_PWM_G_SEL]               = &pwm_g_sel.hw,
>> +     [CLKID_PWM_G_DIV]               = &pwm_g_div.hw,
>> +     [CLKID_PWM_G]                   = &pwm_g.hw,
>> +     [CLKID_PWM_H_SEL]               = &pwm_h_sel.hw,
>> +     [CLKID_PWM_H_DIV]               = &pwm_h_div.hw,
>> +     [CLKID_PWM_H]                   = &pwm_h.hw,
>> +     [CLKID_SPICC_0_SEL]             = &spicc_0_sel.hw,
>> +     [CLKID_SPICC_0_DIV]             = &spicc_0_div.hw,
>> +     [CLKID_SPICC_0]                 = &spicc_0.hw,
>> +     [CLKID_SPICC_1_SEL]             = &spicc_1_sel.hw,
>> +     [CLKID_SPICC_1_DIV]             = &spicc_1_div.hw,
>> +     [CLKID_SPICC_1]                 = &spicc_1.hw,
>> +     [CLKID_SD_EMMC_A_SEL]           = &sd_emmc_a_sel.hw,
>> +     [CLKID_SD_EMMC_A_DIV]           = &sd_emmc_a_div.hw,
>> +     [CLKID_SD_EMMC_A]               = &sd_emmc_a.hw,
>> +     [CLKID_SD_EMMC_C_SEL]           = &sd_emmc_c_sel.hw,
>> +     [CLKID_SD_EMMC_C_DIV]           = &sd_emmc_c_div.hw,
>> +     [CLKID_SD_EMMC_C]               = &sd_emmc_c.hw,
>> +     [CLKID_TS_DIV]                  = &ts_div.hw,
>> +     [CLKID_TS]                      = &ts.hw,
>> +     [CLKID_ETH_125M_DIV]            = &eth_125m_div.hw,
>> +     [CLKID_ETH_125M]                = &eth_125m.hw,
>> +     [CLKID_ETH_RMII_DIV]            = &eth_rmii_div.hw,
>> +     [CLKID_ETH_RMII]                = &eth_rmii.hw,
>> +     [CLKID_DSPA_0_SEL]              = &dspa_0_sel.hw,
>> +     [CLKID_DSPA_0_DIV]              = &dspa_0_div.hw,
>> +     [CLKID_DSPA_0]                  = &dspa_0.hw,
>> +     [CLKID_DSPA_1_SEL]              = &dspa_1_sel.hw,
>> +     [CLKID_DSPA_1_DIV]              = &dspa_1_div.hw,
>> +     [CLKID_DSPA_1]                  = &dspa_1.hw,
>> +     [CLKID_DSPA]                    = &dspa.hw,
>> +     [CLKID_NNA_CORE_SEL]            = &nna_core_sel.hw,
>> +     [CLKID_NNA_CORE_DIV]            = &nna_core_div.hw,
>> +     [CLKID_NNA_CORE]                = &nna_core.hw,
>> +     [CLKID_NNA_AXI_SEL]             = &nna_axi_sel.hw,
>> +     [CLKID_NNA_AXI_DIV]             = &nna_axi_div.hw,
>> +     [CLKID_NNA_AXI]                 = &nna_axi.hw,
>> +};
>> +
>> +/* Convenience table to populate regmap in .probe */
>> +static struct clk_regmap *const a5_periphs_clk_regmaps[] = {
>> +     &rtc_xtal_clkin,
>> +     &rtc_32k_div,
>> +     &rtc_32k_mux,
>> +     &rtc_32k,
>> +     &rtc_clk,
>> +     &sys_reset_ctrl,
>> +     &sys_pwr_ctrl,
>> +     &sys_pad_ctrl,
>> +     &sys_ctrl,
>> +     &sys_ts_pll,
>> +     &sys_dev_arb,
>> +     &sys_mailbox,
>> +     &sys_jtag_ctrl,
>> +     &sys_ir_ctrl,
>> +     &sys_msr_clk,
>> +     &sys_rom,
>> +     &sys_cpu_apb,
>> +     &sys_rsa,
>> +     &sys_sar_adc,
>> +     &sys_startup,
>> +     &sys_secure,
>> +     &sys_spifc,
>> +     &sys_dspa,
>> +     &sys_nna,
>> +     &sys_eth_mac,
>> +     &sys_rama,
>> +     &sys_ramb,
>> +     &sys_audio_top,
>> +     &sys_audio_vad,
>> +     &sys_usb,
>> +     &sys_sd_emmc_a,
>> +     &sys_sd_emmc_c,
>> +     &sys_pwm_ab,
>> +     &sys_pwm_cd,
>> +     &sys_pwm_ef,
>> +     &sys_pwm_gh,
>> +     &sys_spicc_1,
>> +     &sys_spicc_0,
>> +     &sys_uart_a,
>> +     &sys_uart_b,
>> +     &sys_uart_c,
>> +     &sys_uart_d,
>> +     &sys_uart_e,
>> +     &sys_i2c_m_a,
>> +     &sys_i2c_m_b,
>> +     &sys_i2c_m_c,
>> +     &sys_i2c_m_d,
>> +     &sys_rtc,
>> +     &axi_audio_vad,
>> +     &axi_audio_top,
>> +     &axi_ramb,
>> +     &axi_rama,
>> +     &axi_nna,
>> +     &axi_dev1_dmc,
>> +     &axi_dev0_dmc,
>> +     &axi_dsp_dmc,
>> +     &clk_12_24m_in,
>> +     &clk_12_24m,
>> +     &fclk_25m_div,
>> +     &fclk_25m,
>> +     &gen_sel,
>> +     &gen_div,
>> +     &gen,
>> +     &saradc_sel,
>> +     &saradc_div,
>> +     &saradc,
>> +     &pwm_a_sel,
>> +     &pwm_a_div,
>> +     &pwm_a,
>> +     &pwm_b_sel,
>> +     &pwm_b_div,
>> +     &pwm_b,
>> +     &pwm_c_sel,
>> +     &pwm_c_div,
>> +     &pwm_c,
>> +     &pwm_d_sel,
>> +     &pwm_d_div,
>> +     &pwm_d,
>> +     &pwm_e_sel,
>> +     &pwm_e_div,
>> +     &pwm_e,
>> +     &pwm_f_sel,
>> +     &pwm_f_div,
>> +     &pwm_f,
>> +     &pwm_g_sel,
>> +     &pwm_g_div,
>> +     &pwm_g,
>> +     &pwm_h_sel,
>> +     &pwm_h_div,
>> +     &pwm_h,
>> +     &spicc_0_sel,
>> +     &spicc_0_div,
>> +     &spicc_0,
>> +     &spicc_1_sel,
>> +     &spicc_1_div,
>> +     &spicc_1,
>> +     &sd_emmc_a_sel,
>> +     &sd_emmc_a_div,
>> +     &sd_emmc_a,
>> +     &sd_emmc_c_sel,
>> +     &sd_emmc_c_div,
>> +     &sd_emmc_c,
>> +     &ts_div,
>> +     &ts,
>> +     &eth_125m,
>> +     &eth_rmii_div,
>> +     &eth_rmii,
>> +     &dspa_0_sel,
>> +     &dspa_0_div,
>> +     &dspa_0,
>> +     &dspa_1_sel,
>> +     &dspa_1_div,
>> +     &dspa_1,
>> +     &dspa,
>> +     &nna_core_sel,
>> +     &nna_core_div,
>> +     &nna_core,
>> +     &nna_axi_sel,
>> +     &nna_axi_div,
>> +     &nna_axi
>> +};
>> +
>> +static const struct regmap_config clkc_regmap_config = {
>> +     .reg_bits       = 32,
>> +     .val_bits       = 32,
>> +     .reg_stride     = 4,
>> +     .max_register   = CLKCTRL_NNA_CLK_CNTL,
>> +};
>> +
>> +static struct meson_clk_hw_data a5_periphs_clks = {
>> +     .hws = a5_periphs_hw_clks,
>> +     .num = ARRAY_SIZE(a5_periphs_hw_clks),
>> +};
>> +
>> +static int aml_a5_peripherals_probe(struct platform_device *pdev)
>> +{
>> +     struct device *dev = &pdev->dev;
>> +     struct regmap *regmap;
>> +     void __iomem *base;
>> +     int clkid, ret, i;
>> +
>> +     base = devm_platform_ioremap_resource(pdev, 0);
>> +     if (IS_ERR(base))
>> +             return PTR_ERR(base);
>> +
>> +     regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
>> +     if (IS_ERR(regmap))
>> +             return PTR_ERR(regmap);
>> +
>> +     /* Populate regmap for the regmap backed clocks */
>> +     for (i = 0; i < ARRAY_SIZE(a5_periphs_clk_regmaps); i++)
>> +             a5_periphs_clk_regmaps[i]->map = regmap;
>> +
>> +     for (clkid = 0; clkid < a5_periphs_clks.num; clkid++) {
>> +             /* array might be sparse */
>> +             if (!a5_periphs_clks.hws[clkid])
>> +                     continue;
>> +
>> +             ret = devm_clk_hw_register(dev, a5_periphs_clks.hws[clkid]);
>> +             if (ret) {
>> +                     dev_err(dev, "Clock registration failed\n");
>> +                     return ret;
>> +             }
>> +     }
>> +
>> +     return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
>> +                                        &a5_periphs_clks);
>> +}
>> +
>> +static const struct of_device_id a5_peripherals_clkc_match_table[] = {
>> +     {
>> +             .compatible = "amlogic,a5-peripherals-clkc",
>> +     },
>> +     { /* sentinel */ }
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, a5_peripherals_clkc_match_table);
>> +
>> +static struct platform_driver a5_peripherals_driver = {
>> +     .probe          = aml_a5_peripherals_probe,
>> +     .driver         = {
>> +             .name   = "a5-peripherals-clkc",
>> +             .of_match_table = a5_peripherals_clkc_match_table,
>> +     },
>> +};
>> +module_platform_driver(a5_peripherals_driver);
>> +
>> +MODULE_DESCRIPTION("Amlogic A5 Peripherals Clock Controller driver");
>> +MODULE_AUTHOR("Chuan Liu <chuan.liu at amlogic.com>");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h
>> index e365312da54e..1e592d809bfd 100644
>> --- a/drivers/clk/meson/clk-regmap.h
>> +++ b/drivers/clk/meson/clk-regmap.h
>> @@ -134,4 +134,21 @@ struct clk_regmap _name = {                                              \
>>
>>   #define MESON_PCLK_RO(_name, _reg, _bit, _pname)     \
>>        __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname)
>> +
> 
> No Amlogic specific clocks should be added to this header.
> This was meant to be generic.
> 
>> +#define MESON_CLK_GATE_FW(_name, _reg, _bit, _fw_name, _ops, _flags) \
>> +struct clk_regmap _name = {                                          \
>> +     .data = &(struct clk_regmap_gate_data){                         \
>> +             .offset = (_reg),                                       \
>> +             .bit_idx = (_bit),                                      \
>> +     },                                                              \
>> +     .hw.init = &(struct clk_init_data) {                            \
>> +             .name = #_name,                                         \
>> +             .ops = _ops,                                            \
>> +             .parent_data = &(const struct clk_parent_data) {        \
>> +                     .fw_name = #_fw_name,                           \
> 
> I think is making the macro difficult to read when used. Pass a string,
> that will be a lot more clear and will not look like a weird identitier.
> 
Will do.

>> +             },                                                      \
>> +             .num_parents = 1,                                       \
>> +             .flags = (_flags),                                      \
>> +     },                                                              \
>> +}
> 
> Given that this is used in A5 only for now, I don't think this needs to
> be in a header just yet. You'll modify this when needed.
> 
OK, I will place it to source file now.
>>   #endif /* __CLK_REGMAP_H */
> 
> --
> Jerome


From xianwei.zhao at amlogic.com  Wed Dec 11 00:09:31 2024
From: xianwei.zhao at amlogic.com (Xianwei Zhao)
Date: Wed, 11 Dec 2024 16:09:31 +0800
Subject: [PATCH v2 3/5] dt-bindings: clock: add Amlogic A5 peripherals
 clock controller
In-Reply-To: <1jmshntfty.fsf@starbuckisacylon.baylibre.com>
References: <20241120-a5-clk-v2-0-1208621e961d@amlogic.com>
 <20241120-a5-clk-v2-3-1208621e961d@amlogic.com>
 <1jmshntfty.fsf@starbuckisacylon.baylibre.com>
Message-ID: <e32950ba-001e-4cb2-82f0-7a498644bdae@amlogic.com>

Hi Jerome,
    Thanks for your reply.

On 2024/11/26 00:53, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> On Wed 20 Nov 2024 at 15:01, Xianwei Zhao via B4 Relay <devnull+xianwei.zhao.amlogic.com at kernel.org> wrote:
> 
>> From: Chuan Liu <chuan.liu at amlogic.com>
>>
>> Add the peripherals clock controller dt-bindings for Amlogic A5 SoC family.
>>
>> Signed-off-by: Chuan Liu <chuan.liu at amlogic.com>
>> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
>> ---
>>   .../clock/amlogic,a5-peripherals-clkc.yaml         | 130 ++++++++++++++++++++
>>   .../clock/amlogic,a5-peripherals-clkc.h            | 132 +++++++++++++++++++++
>>   2 files changed, 262 insertions(+)
>>
>> diff --git
>> a/Documentation/devicetree/bindings/clock/amlogic,a5-peripherals-clkc.yaml
>> b/Documentation/devicetree/bindings/clock/amlogic,a5-peripherals-clkc.yaml
>> new file mode 100644
>> index 000000000000..0f15e104fd12
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/amlogic,a5-peripherals-clkc.yaml
>> @@ -0,0 +1,130 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +# Copyright (C) 2024 Amlogic, Inc. All rights reserved
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/amlogic,a5-peripherals-clkc.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Amlogic A5 series Peripheral Clock Controller
>> +
>> +maintainers:
>> +  - Xianwei Zhao <xianwei.zhao at amlogic.com>
>> +  - Chuan Liu <chuan.liu at amlogic.com>
>> +
>> +properties:
>> +  compatible:
>> +    const: amlogic,a5-peripherals-clkc
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    minItems: 18
>> +    items:
>> +      - description: input oscillator (usually at 24MHz)
>> +      - description: input oscillators multiplexer
>> +      - description: input fix pll
>> +      - description: input fclk div 2
>> +      - description: input fclk div 2p5
>> +      - description: input fclk div 3
>> +      - description: input fclk div 4
>> +      - description: input fclk div 5
>> +      - description: input fclk div 7
>> +      - description: input mpll2
>> +      - description: input mpll3
>> +      - description: input gp0 pll
>> +      - description: input gp1 pll
>> +      - description: input hifi pll
>> +      - description: input sys clk
>> +      - description: input axi clk
>> +      - description: input sys pll div 16
>> +      - description: input cpu clk div 16
>> +      - description: input pad clock for rtc clk (optional)
>> +      - description: input ddr pll (optional)
>> +      - description: input source from clk-measure (optional)
>> +
>> +  clock-names:
>> +    minItems: 18
>> +    items:
>> +      - const: xtal_24m
> 
> You should not mention the rate here. xtal is fine.
> 
Will do.
>> +      - const: oscin
>> +      - const: fix
>> +      - const: fdiv2
>> +      - const: fdiv2p5
>> +      - const: fdiv3
>> +      - const: fdiv4
>> +      - const: fdiv5
>> +      - const: fdiv7
>> +      - const: mpll2
>> +      - const: mpll3
>> +      - const: gp0
>> +      - const: gp1
>> +      - const: hifi
>> +      - const: sysclk
>> +      - const: axiclk
>> +      - const: sysplldiv16
>> +      - const: cpudiv16
>> +      - const: pad_osc
>> +      - const: ddr
>> +      - const: clkmsr
>> +
>> +  "#clock-cells":
>> +    const: 1
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-names
>> +  - "#clock-cells"
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    apb {
>> +        #address-cells = <2>;
>> +        #size-cells = <2>;
>> +
>> +        clock-controller at 0 {
>> +            compatible = "amlogic,a5-peripherals-clkc";
>> +            reg = <0x0 0x0 0x0 0x224>;
>> +            #clock-cells = <1>;
>> +            clocks = <&xtal_24m>,
>> +                     <&scmi_clk 0>,
>> +                     <&scmi_clk 7>,
>> +                     <&scmi_clk 15>,
>> +                     <&scmi_clk 17>,
>> +                     <&scmi_clk 19>,
>> +                     <&scmi_clk 21>,
>> +                     <&scmi_clk 23>,
>> +                     <&scmi_clk 25>,
>> +                     <&clkc_pll 6>,
>> +                     <&clkc_pll 8>,
>> +                     <&clkc_pll 10>,
>> +                     <&scmi_clk 5>,
>> +                     <&clkc_pll 12>,
>> +                     <&scmi_clk 1>,
>> +                     <&scmi_clk 2>,
>> +                     <&scmi_clk 9>,
>> +                     <&scmi_clk 10>;
>> +            clock-names = "xtal_24m",
>> +                          "oscin",
>> +                          "fix",
>> +                          "fdiv2",
>> +                          "fdiv2p5",
>> +                          "fdiv3",
>> +                          "fdiv4",
>> +                          "fdiv5",
>> +                          "fdiv7",
>> +                          "mpll2",
>> +                          "mpll3",
>> +                          "gp0",
>> +                          "gp1",
>> +                          "hifi",
>> +                          "sysclk",
>> +                          "axiclk",
>> +                          "sysplldiv16",
>> +                          "cpudiv16";
>> +        };
>> +    };
>> diff --git a/include/dt-bindings/clock/amlogic,a5-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a5-peripherals-clkc.h
>> new file mode 100644
>> index 000000000000..74e740ebe6bd
>> --- /dev/null
>> +++ b/include/dt-bindings/clock/amlogic,a5-peripherals-clkc.h
>> @@ -0,0 +1,132 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>> +/*
>> + * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
>> + * Author: Chuan Liu <chuan.liu at amlogic.com>
>> + */
>> +
>> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_A5_PERIPHERALS_CLKC_H
>> +#define _DT_BINDINGS_CLOCK_AMLOGIC_A5_PERIPHERALS_CLKC_H
>> +
>> +#define CLKID_RTC_XTAL_CLKIN                 0
>> +#define CLKID_RTC_32K_DIV                    1
>> +#define CLKID_RTC_32K_MUX                    2
>> +#define CLKID_RTC_32K                                3
>> +#define CLKID_RTC_CLK                                4
>> +#define CLKID_SYS_RESET_CTRL                 5
>> +#define CLKID_SYS_PWR_CTRL                   6
>> +#define CLKID_SYS_PAD_CTRL                   7
>> +#define CLKID_SYS_CTRL                               8
>> +#define CLKID_SYS_TS_PLL                     9
>> +#define CLKID_SYS_DEV_ARB                    10
>> +#define CLKID_SYS_MAILBOX                    11
>> +#define CLKID_SYS_JTAG_CTRL                  12
>> +#define CLKID_SYS_IR_CTRL                    13
>> +#define CLKID_SYS_MSR_CLK                    14
>> +#define CLKID_SYS_ROM                                15
>> +#define CLKID_SYS_CPU_ARB                    16
>> +#define CLKID_SYS_RSA                                17
>> +#define CLKID_SYS_SAR_ADC                    18
>> +#define CLKID_SYS_STARTUP                    19
>> +#define CLKID_SYS_SECURE                     20
>> +#define CLKID_SYS_SPIFC                              21
>> +#define CLKID_SYS_DSPA                               22
>> +#define CLKID_SYS_NNA                                23
>> +#define CLKID_SYS_ETH_MAC                    24
>> +#define CLKID_SYS_RAMA                               25
>> +#define CLKID_SYS_RAMB                               26
>> +#define CLKID_SYS_AUDIO_TOP                  27
>> +#define CLKID_SYS_AUDIO_VAD                  28
>> +#define CLKID_SYS_USB                                29
>> +#define CLKID_SYS_SD_EMMC_A                  30
>> +#define CLKID_SYS_SD_EMMC_C                  31
>> +#define CLKID_SYS_PWM_AB                     32
>> +#define CLKID_SYS_PWM_CD                     33
>> +#define CLKID_SYS_PWM_EF                     34
>> +#define CLKID_SYS_PWM_GH                     35
>> +#define CLKID_SYS_SPICC_1                    36
>> +#define CLKID_SYS_SPICC_0                    37
>> +#define CLKID_SYS_UART_A                     38
>> +#define CLKID_SYS_UART_B                     39
>> +#define CLKID_SYS_UART_C                     40
>> +#define CLKID_SYS_UART_D                     41
>> +#define CLKID_SYS_UART_E                     42
>> +#define CLKID_SYS_I2C_M_A                    43
>> +#define CLKID_SYS_I2C_M_B                    44
>> +#define CLKID_SYS_I2C_M_C                    45
>> +#define CLKID_SYS_I2C_M_D                    46
>> +#define CLKID_SYS_RTC                                47
>> +#define CLKID_AXI_AUDIO_VAD                  48
>> +#define CLKID_AXI_AUDIO_TOP                  49
>> +#define CLKID_AXI_RAMB                               50
>> +#define CLKID_AXI_RAMA                               51
>> +#define CLKID_AXI_NNA                                52
>> +#define CLKID_AXI_DEV1_DMC                   53
>> +#define CLKID_AXI_DEV0_DMC                   54
>> +#define CLKID_AXI_DSP_DMC                    55
>> +#define CLKID_12_24M_IN                              56
>> +#define CLKID_12M_24M                                57
>> +#define CLKID_FCLK_25M_DIV                   58
>> +#define CLKID_FCLK_25M                               59
>> +#define CLKID_GEN_SEL                                60
>> +#define CLKID_GEN_DIV                                61
>> +#define CLKID_GEN                            62
>> +#define CLKID_SARADC_SEL                     63
>> +#define CLKID_SARADC_DIV                     64
>> +#define CLKID_SARADC                         65
>> +#define CLKID_PWM_A_SEL                              66
>> +#define CLKID_PWM_A_DIV                              67
>> +#define CLKID_PWM_A                          68
>> +#define CLKID_PWM_B_SEL                              69
>> +#define CLKID_PWM_B_DIV                              70
>> +#define CLKID_PWM_B                          71
>> +#define CLKID_PWM_C_SEL                              72
>> +#define CLKID_PWM_C_DIV                              73
>> +#define CLKID_PWM_C                          74
>> +#define CLKID_PWM_D_SEL                              75
>> +#define CLKID_PWM_D_DIV                              76
>> +#define CLKID_PWM_D                          77
>> +#define CLKID_PWM_E_SEL                              78
>> +#define CLKID_PWM_E_DIV                              79
>> +#define CLKID_PWM_E                          80
>> +#define CLKID_PWM_F_SEL                              81
>> +#define CLKID_PWM_F_DIV                              82
>> +#define CLKID_PWM_F                          83
>> +#define CLKID_PWM_G_SEL                              84
>> +#define CLKID_PWM_G_DIV                              85
>> +#define CLKID_PWM_G                          86
>> +#define CLKID_PWM_H_SEL                              87
>> +#define CLKID_PWM_H_DIV                              88
>> +#define CLKID_PWM_H                          89
>> +#define CLKID_SPICC_0_SEL                    90
>> +#define CLKID_SPICC_0_DIV                    91
>> +#define CLKID_SPICC_0                                92
>> +#define CLKID_SPICC_1_SEL                    93
>> +#define CLKID_SPICC_1_DIV                    94
>> +#define CLKID_SPICC_1                                95
>> +#define CLKID_SD_EMMC_A_SEL                  96
>> +#define CLKID_SD_EMMC_A_DIV                  97
>> +#define CLKID_SD_EMMC_A                              98
>> +#define CLKID_SD_EMMC_C_SEL                  99
>> +#define CLKID_SD_EMMC_C_DIV                  100
>> +#define CLKID_SD_EMMC_C                              101
>> +#define CLKID_TS_DIV                         102
>> +#define CLKID_TS                             103
>> +#define CLKID_ETH_125M_DIV                   104
>> +#define CLKID_ETH_125M                               105
>> +#define CLKID_ETH_RMII_DIV                   106
>> +#define CLKID_ETH_RMII                               107
>> +#define CLKID_DSPA_0_SEL                     108
>> +#define CLKID_DSPA_0_DIV                     109
>> +#define CLKID_DSPA_0                         110
>> +#define CLKID_DSPA_1_SEL                     111
>> +#define CLKID_DSPA_1_DIV                     112
>> +#define CLKID_DSPA_1                         113
>> +#define CLKID_DSPA                           114
>> +#define CLKID_NNA_CORE_SEL                   115
>> +#define CLKID_NNA_CORE_DIV                   116
>> +#define CLKID_NNA_CORE                               117
>> +#define CLKID_NNA_AXI_SEL                    118
>> +#define CLKID_NNA_AXI_DIV                    119
>> +#define CLKID_NNA_AXI                                120
>> +
>> +#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_A5_PERIPHERALS_CLKC_H */
> 
> --
> Jerome


From kevin.tian at intel.com  Wed Dec 11 00:11:03 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 08:11:03 +0000
Subject: [PATCH v2 11/13] Documentation: userspace-api: iommufd: Update
 EVENTQ_IOPF and EVENTQ_VIRQ
In-Reply-To: <a5025cbbd16f9c12dcaae7a14868419f17ce1d16.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <a5025cbbd16f9c12dcaae7a14868419f17ce1d16.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB5276E09D5F2206804A7C15968C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> 
> With the introduction of the new objects, update the doc to reflect that.
> 
> Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
> ---
>  Documentation/userspace-api/iommufd.rst | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/Documentation/userspace-api/iommufd.rst
> b/Documentation/userspace-api/iommufd.rst
> index 70289d6815d2..798520d9344d 100644
> --- a/Documentation/userspace-api/iommufd.rst
> +++ b/Documentation/userspace-api/iommufd.rst
> @@ -63,6 +63,14 @@ Following IOMMUFD objects are exposed to userspace:
>    space usually has mappings from guest-level I/O virtual addresses to guest-
>    level physical addresses.
> 
> +- IOMMUFD_OBJ_EVENTQ_IOPF, representing a software queue for an
> HWPT_NESTED

now it can be used on paging hwpt too

> +  reporting IO Page Fault using the IOMMU HW's PRI (Page Request
> Interface).
> +  This queue object provides user space an FD to poll the page fault events
> +  and also to respond to those events. An EVENTQ_IOPF object must be
> created
> +  first to get a fault_id that could be then used to allocate an HWPT_NESTED
> +  via the IOMMU_HWPT_ALLOC command setting
> IOMMU_HWPT_FAULT_ID_VALID set in
> +  its flags field.
> +
>  - IOMMUFD_OBJ_VIOMMU, representing a slice of the physical IOMMU
> instance,
>    passed to or shared with a VM. It may be some HW-accelerated
> virtualization
>    features and some SW resources used by the VM. For examples:
> @@ -109,6 +117,15 @@ Following IOMMUFD objects are exposed to
> userspace:
>    vIOMMU, which is a separate ioctl call from attaching the same device to an
>    HWPT_PAGING that the vIOMMU holds.
> 
> +- IOMMUFD_OBJ_EVENTQ_VIRQ, representing a software queue for
> IOMMUFD_OBJ_VIOMMU
> +  reporting its non-affiliated events, such as translation faults occurred to a

non-affiliated is only mentioned here. It's not a standard term in this
area. Sticking to the later examples in 'such as' is straightforward.

> +  nested stage-1 and HW-specific events/irqs e.g. events to invalidation
> queues
> +  that are assigned to VMs via vIOMMUs. This queue object provides user

vcmdq is not supported yet. add it later.

> space an
> +  FD to poll the vIOMMU events. A vIOMMU object must be created first to
> get its
> +  viommu_id that could be then used to allocate an EVENTQ_VIRQ. Each
> vIOMMU can
> +  support multiple types of EVENTQ_VIRQs, but is confined to one
> EVENTQ_VIRQ per
> +  vIRQ type.
> +
>  All user-visible objects are destroyed via the IOMMU_DESTROY uAPI.
> 
>  The diagrams below show relationships between user-visible objects and
> kernel
> @@ -251,8 +268,10 @@ User visible objects are backed by following
> datastructures:
>  - iommufd_device for IOMMUFD_OBJ_DEVICE.
>  - iommufd_hwpt_paging for IOMMUFD_OBJ_HWPT_PAGING.
>  - iommufd_hwpt_nested for IOMMUFD_OBJ_HWPT_NESTED.
> +- iommufd_eventq_iopf for IOMMUFD_OBJ_EVENTQ_IOPF.
>  - iommufd_viommu for IOMMUFD_OBJ_VIOMMU.
>  - iommufd_vdevice for IOMMUFD_OBJ_VDEVICE.
> +- iommufd_eventq_virq for IOMMUFD_OBJ_EVENTQ_VIRQ.
> 
>  Several terminologies when looking at these datastructures:
> 
> --
> 2.43.0



From kevin.tian at intel.com  Wed Dec 11 00:15:35 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 08:15:35 +0000
Subject: [PATCH v2 12/13] iommu/arm-smmu-v3: Introduce struct
 arm_smmu_vmaster
In-Reply-To: <6270c905fc8537ffc51f6f2ab2db0601c9f08a8d.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <6270c905fc8537ffc51f6f2ab2db0601c9f08a8d.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB527669503B30B7C67907DE398C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> 
> Use it to store all vSMMU-related data. The vsid (Virtual Stream ID) will
> be the first use case. Then, add a rw_semaphore to protect it.
> 
> Also add a pair of arm_smmu_attach_prepare/commit_vmaster helpers and
> put
> them in the existing arm_smmu_attach_prepare/commit(). Note that identity
> and blocked ops don't call arm_smmu_attach_prepare/commit(), thus
> simply
> call the new helpers at the top.

Probably a dumb question. viommu is tied to a nested parent domain
which cannot be identity or blocked. Why do we need to change them
too?



From kevin.tian at intel.com  Wed Dec 11 00:21:42 2024
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 11 Dec 2024 08:21:42 +0000
Subject: [PATCH v2 13/13] iommu/arm-smmu-v3: Report IRQs that belong to
 devices attached to vIOMMU
In-Reply-To: <d335936fdeccfcf785589800b7e5d9b1b26a766d.1733263737.git.nicolinc@nvidia.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <d335936fdeccfcf785589800b7e5d9b1b26a766d.1733263737.git.nicolinc@nvidia.com>
Message-ID: <BN9PR11MB5276EE81D21EC5E4156EB7D58C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Nicolin Chen <nicolinc at nvidia.com>
> Sent: Wednesday, December 4, 2024 6:10 AM
> 
> +
> +/**
> + * struct iommu_virq_arm_smmuv3 - ARM SMMUv3 Virtual IRQ
> + *                                (IOMMU_VIRQ_TYPE_ARM_SMMUV3)
> + * @evt: 256-bit ARM SMMUv3 Event record, little-endian.
> + *
> + * StreamID field reports a virtual device ID. To receive a virtual IRQ for a
> + * device, a vDEVICE must be allocated via IOMMU_VDEVICE_ALLOC.
> + */

similar to what's provided for iommu_hw_info_arm_smmuv3, it'd be
good to refer to a section in smmu spec for bit definitions.

> @@ -1779,33 +1779,6 @@ static int arm_smmu_handle_evt(struct
> arm_smmu_device *smmu, u64 *evt)
>  		return -EOPNOTSUPP;
>  	}
> 
> -	if (!(evt[1] & EVTQ_1_STALL))
> -		return -EOPNOTSUPP;
> -
> -	if (evt[1] & EVTQ_1_RnW)
> -		perm |= IOMMU_FAULT_PERM_READ;
> -	else
> -		perm |= IOMMU_FAULT_PERM_WRITE;
> -
> -	if (evt[1] & EVTQ_1_InD)
> -		perm |= IOMMU_FAULT_PERM_EXEC;
> -
> -	if (evt[1] & EVTQ_1_PnU)
> -		perm |= IOMMU_FAULT_PERM_PRIV;
> -
> -	flt->type = IOMMU_FAULT_PAGE_REQ;
> -	flt->prm = (struct iommu_fault_page_request) {
> -		.flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
> -		.grpid = FIELD_GET(EVTQ_1_STAG, evt[1]),
> -		.perm = perm,
> -		.addr = FIELD_GET(EVTQ_2_ADDR, evt[2]),
> -	};
> -
> -	if (ssid_valid) {
> -		flt->prm.flags |=
> IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
> -		flt->prm.pasid = FIELD_GET(EVTQ_0_SSID, evt[0]);
> -	}
> -
>  	mutex_lock(&smmu->streams_mutex);
>  	master = arm_smmu_find_master(smmu, sid);
>  	if (!master) {
> @@ -1813,7 +1786,40 @@ static int arm_smmu_handle_evt(struct
> arm_smmu_device *smmu, u64 *evt)
>  		goto out_unlock;
>  	}
> 
> -	ret = iommu_report_device_fault(master->dev, &fault_evt);
> +	down_read(&master->vmaster_rwsem);

this lock is not required if event is EVTQ_1_STALL?

> +	if (evt[1] & EVTQ_1_STALL) {
> +		if (evt[1] & EVTQ_1_RnW)
> +			perm |= IOMMU_FAULT_PERM_READ;
> +		else
> +			perm |= IOMMU_FAULT_PERM_WRITE;
> +
> +		if (evt[1] & EVTQ_1_InD)
> +			perm |= IOMMU_FAULT_PERM_EXEC;
> +
> +		if (evt[1] & EVTQ_1_PnU)
> +			perm |= IOMMU_FAULT_PERM_PRIV;
> +
> +		flt->type = IOMMU_FAULT_PAGE_REQ;
> +		flt->prm = (struct iommu_fault_page_request){
> +			.flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
> +			.grpid = FIELD_GET(EVTQ_1_STAG, evt[1]),
> +			.perm = perm,
> +			.addr = FIELD_GET(EVTQ_2_ADDR, evt[2]),
> +		};
> +
> +		if (ssid_valid) {
> +			flt->prm.flags |=
> IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
> +			flt->prm.pasid = FIELD_GET(EVTQ_0_SSID, evt[0]);
> +		}
> +
> +		ret = iommu_report_device_fault(master->dev, &fault_evt);
> +	} else if (master->vmaster && !(evt[1] & EVTQ_1_S2)) {
> +		ret = arm_vmaster_report_event(master->vmaster, evt);
> +	} else {
> +		/* Unhandled events should be pinned */
> +		ret = -EFAULT;
> +	}
> +	up_read(&master->vmaster_rwsem);
>  out_unlock:
>  	mutex_unlock(&smmu->streams_mutex);
>  	return ret;
> --
> 2.43.0



From anshuman.khandual at arm.com  Wed Dec 11 00:34:12 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Dec 2024 14:04:12 +0530
Subject: [PATCH V2 0/7] arm64/hw_breakpoint: Enable FEAT_Debugv8p9
In-Reply-To: <Z1hzdLQLlIPg7eV5@J2N7QTR9R3>
References: <20241028053426.2486633-1-anshuman.khandual@arm.com>
 <Z1hzdLQLlIPg7eV5@J2N7QTR9R3>
Message-ID: <86ad5edc-ad57-43c3-86d2-0bd854a479c5@arm.com>



On 12/10/24 22:29, Mark Rutland wrote:
> On Mon, Oct 28, 2024 at 11:04:19AM +0530, Anshuman Khandual wrote:
>> This series enables FEAT_Debugv8p9 thus extending breakpoint and watchpoint
>> support upto 64. This series is based on v6.12-rc5 although this depends on
>> FEAT_FGT2 FGU series posted earlier, for MDSELR_EL1 handling in various KVM
>> guest configurations.
>>
>> https://lore.kernel.org/all/20241001024356.1096072-1-anshuman.khandual at arm.com/
> To avoid further confusion: since we discussed things further on the v1
> thread after this v2 thread was posted, I'm waiting for a v3 to be
> posted which addresses the comments there (e.g. ID reg field handling,
> mutual exclusion for breakpoint manipulation).

Agreed, although I am still working on the mutual exclusion for breakpoint
manipulation problem. Besides just carved out - MDCR_EL3.[TDS|TPM] related
EL3 boot requirement's document update in a separate series as discussed.

https://lore.kernel.org/all/20241211065425.1106683-1-anshuman.khandual at arm.com/


From krzk at kernel.org  Wed Dec 11 00:38:54 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 09:38:54 +0100
Subject: [PATCH v13 01/25] virt: geniezone: enable gzvm-ko in defconfig
In-Reply-To: <20241114100802.4116-2-liju-clr.chen@mediatek.com>
References: <20241114100802.4116-1-liju-clr.chen@mediatek.com>
 <20241114100802.4116-2-liju-clr.chen@mediatek.com>
Message-ID: <1ecf2e8c-86cd-4ba2-832b-014a05a80d26@kernel.org>

On 14/11/2024 11:07, Liju-clr Chen wrote:
> From: Yingshiuan Pan <yingshiuan.pan at mediatek.com>
> 

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.


> Add config in defconfig to enable gzvm driver by default

This we see from the diff. You must explain why we want it.

> 
> Signed-off-by: Yingshiuan Pan <yingshiuan.pan at mediatek.com>
> Signed-off-by: Yi-De Wu <yi-de.wu at mediatek.com>
> Signed-off-by: Liju Chen <liju-clr.chen at mediatek.com>
> ---
>  arch/arm64/configs/defconfig | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index d13218d0c30f..0f63d4837b61 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -1733,3 +1733,5 @@ CONFIG_CORESIGHT_STM=m
>  CONFIG_CORESIGHT_CPU_DEBUG=m
>  CONFIG_CORESIGHT_CTI=m
>  CONFIG_MEMTEST=y
> +CONFIG_VIRT_DRIVERS=y
> +CONFIG_MTK_GZVM=m

Does not look like placed correctly, according to savedefconfig.

I still do not see any reason to have it enabled.

Your patches have weird order or this is just wrong. There is no such
thing as "MTK_GZVM". Use git grep, if you do not believe me.


Best regards,
Krzysztof


From chenhuacai at kernel.org  Wed Dec 11 00:41:42 2024
From: chenhuacai at kernel.org (Huacai Chen)
Date: Wed, 11 Dec 2024 16:41:42 +0800
Subject: [PATCH v1 4/5] loongarch/bug: Add ARCH_WARN_ASM macro for
 BUG/WARN asm code sharing with Rust
In-Reply-To: <20241210001802.228725-5-fujita.tomonori@gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com> <20241210001802.228725-5-fujita.tomonori@gmail.com>
Message-ID: <CAAhV-H7BxE7xeA982Pr4PFxgfNpgXs6H4OZ2LydmYAtYjvYNaw@mail.gmail.com>

Hi, FUJITA,

On Tue, Dec 10, 2024 at 8:19?AM FUJITA Tomonori
<fujita.tomonori at gmail.com> wrote:
>
> Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
> Rust to avoid the duplication.
>
> No functional changes.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
> ---
>  arch/loongarch/include/asm/bug.h | 31 ++++++++++++++++++++++++++++---
>  1 file changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/arch/loongarch/include/asm/bug.h b/arch/loongarch/include/asm/bug.h
> index 08388876ade4..2343c4226595 100644
> --- a/arch/loongarch/include/asm/bug.h
> +++ b/arch/loongarch/include/asm/bug.h
> @@ -21,14 +21,21 @@
>  #ifndef CONFIG_GENERIC_BUG
>  #define __BUG_ENTRY(flags)
>  #else
> -#define __BUG_ENTRY(flags)                                     \
> +
> +#define __BUG_ENTRY_START                                      \
>                 .pushsection __bug_table, "aw";                 \
>                 .align 2;                                       \
>         10000:  .long 10001f - .;                               \
> -               _BUGVERBOSE_LOCATION(__FILE__, __LINE__)        \
> -               .short flags;                                   \
> +
> +#define __BUG_ENTRY_END                                                \
>                 .popsection;                                    \
>         10001:
> +
> +#define __BUG_ENTRY(flags)                                     \
> +               __BUG_ENTRY_START                       \
> +               _BUGVERBOSE_LOCATION(__FILE__, __LINE__)        \
> +               .short flags;                                   \
> +               __BUG_ENTRY_END
>  #endif
>
>  #define ASM_BUG_FLAGS(flags)                                   \
> @@ -55,6 +62,24 @@ do {                                                         \
>         unreachable();                                          \
>  } while (0)
>
> +#ifdef CONFIG_DEBUG_BUGVERBOSE
> +#define __BUG_LOCATION_STRING(file, line)              \
> +               ".long " file "- .;"                    \
> +               ".short " line ";"
> +#else
> +#define __BUG_LOCATION_STRING(_file, _line)
> +#endif
Can we use file and line instead of _file and _line, which is the same
as the CONFIG_DEBUG_BUGVERBOSE case?

> +
> +#define __BUG_ENTRY_STRING(file, line, flags)          \
> +               __stringify(__BUG_ENTRY_START)          \
> +               __BUG_LOCATION_STRING(file, line)       \
> +               ".short " flags ";"                     \
> +               __stringify(__BUG_ENTRY_END)
> +
> +#define ARCH_WARN_ASM(file, line, flags, size)         \
> +       __BUG_ENTRY_STRING(file, line, flags)           \
> +       __stringify(break BRK_BUG) ";"
> +
Can we use the same indentation in this file?

Huacai

>  #define HAVE_ARCH_BUG
>
>  #include <asm-generic/bug.h>
> --
> 2.43.0
>


From linux at fw-web.de  Wed Dec 11 00:43:58 2024
From: linux at fw-web.de (Frank Wunderlich (linux))
Date: Wed, 11 Dec 2024 09:43:58 +0100
Subject: [PATCH v5 2/5] pinctrl: mediatek: add MT7988 pinctrl driver
In-Reply-To: <32201aec-f3d2-49a7-b0ca-2ede10fec103@wanadoo.fr>
References: <20241202110045.22084-1-linux@fw-web.de>
 <20241202110045.22084-3-linux@fw-web.de>
 <32201aec-f3d2-49a7-b0ca-2ede10fec103@wanadoo.fr>
Message-ID: <598f595589d061bf314d942095cd5dc6@fw-web.de>

Am 2024-12-10 19:45, schrieb Christophe JAILLET:
> Le 02/12/2024 ? 12:00, Frank Wunderlich a ?crit?:
>> From: Daniel Golle <daniel at makrotopia.org>
>> 
>> Add pinctrl driver for the MediaTek MT7988 SoC.
>> 
>> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
>> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
>> [correctly initialise for the function_desc structure]
>> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>> 
>> ---
> 
> ...
> 
>> +/* flash */
>> +static int mt7988_snfi_pins[] = { 22, 23, 24, 25, 26, 27 };
>> +static int mt7988_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
>> +
>> +static int mt7988_emmc_45_pins[] = {
>> +	21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
>> +};
>> +static int mt7988_emmc_45_funcs[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 
>> };
>> +
>> +static int mt7988_sdcard_pins[] = { 32, 33, 34, 35, 36, 37 };
>> +static int mt7988_sdcard_funcs[] = { 5, 5, 5, 5, 5, 5 };
>> +
>> +static int mt7988_emmc_51_pins[] = { 38, 39, 40, 41, 42, 43,
>> +				     44, 45, 46, 47, 48, 49 };
>> +static int mt7988_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
>> 1, 1 };
> 
> At least all the _pins arrays could be const.
> Maybe we could also make it possible to have _funcs const as well.
> 
> ...
> 
>> +static struct mtk_pin_soc mt7988_data = {
> 
> const?

can do, but for funcs i see no clear way

angelo, can i keep the RB, when changing pins/mtk_pin_soc to const 
(without changing macro in drivers/pinctrl/mediatek/pinctrl-moore.h)?

>> +	.reg_cal = mt7988_reg_cals,
>> +	.pins = mt7988_pins,
>> +	.npins = ARRAY_SIZE(mt7988_pins),
>> +	.grps = mt7988_groups,
>> +	.ngrps = ARRAY_SIZE(mt7988_groups),
>> +	.funcs = mt7988_functions,
>> +	.nfuncs = ARRAY_SIZE(mt7988_functions),
>> +	.eint_hw = &mt7988_eint_hw,
>> +	.gpio_m = 0,
>> +	.ies_present = false,
>> +	.base_names = mt7988_pinctrl_register_base_names,
>> +	.nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
>> +	.bias_disable_set = mtk_pinconf_bias_disable_set,
>> +	.bias_disable_get = mtk_pinconf_bias_disable_get,
>> +	.bias_set = mtk_pinconf_bias_set,
>> +	.bias_get = mtk_pinconf_bias_get,
>> +	.pull_type = mt7988_pull_type,
>> +	.bias_set_combo = mtk_pinconf_bias_set_combo,
>> +	.bias_get_combo = mtk_pinconf_bias_get_combo,
>> +	.drive_set = mtk_pinconf_drive_set_rev1,
>> +	.drive_get = mtk_pinconf_drive_get_rev1,
>> +	.adv_pull_get = mtk_pinconf_adv_pull_get,
>> +	.adv_pull_set = mtk_pinconf_adv_pull_set,
>> +};
> 
> ...
> 
> CJ


From krzk at kernel.org  Wed Dec 11 00:44:13 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 09:44:13 +0100
Subject: [PATCH v13 04/25] virt: geniezone: Add GenieZone hypervisor
 driver
In-Reply-To: <20241114100802.4116-5-liju-clr.chen@mediatek.com>
References: <20241114100802.4116-1-liju-clr.chen@mediatek.com>
 <20241114100802.4116-5-liju-clr.chen@mediatek.com>
Message-ID: <7b79d4b5-ba91-41a0-90d1-c64bcab53cec@kernel.org>

On 14/11/2024 11:07, Liju-clr Chen wrote:
> +
> +static int gzvm_dev_open(struct inode *inode, struct file *file)
> +{
> +	/*
> +	 * Reference count to prevent this module is unload without destroying
> +	 * VM

So you re-implemented suppress-bind attrs... no, drop.

> +	 */
> +	try_module_get(THIS_MODULE);
> +	return 0;
> +}
> +
> +static int gzvm_dev_release(struct inode *inode, struct file *file)
> +{
> +	module_put(THIS_MODULE);
> +	return 0;
> +}
> +
> +static const struct file_operations gzvm_chardev_ops = {
> +	.llseek		= noop_llseek,
> +	.open		= gzvm_dev_open,
> +	.release	= gzvm_dev_release,
> +};
> +
> +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(gzvm_drv.drv_version, &gzvm_drv.hyp_version) != 0) {
> +		dev_err(&pdev->dev, "Not found available conduit\n");

So you can autodetect your hypervisor? Why your soc info drivers cannot
instantiate this device thus removing any need for fake DT node (fake
because no resources and used only to satisfy Linux driver instantiation)?


> +		return -ENODEV;
> +	}
> +
> +	pr_debug("Found GenieZone hypervisor version %u.%u.%llu\n",
> +		 gzvm_drv.hyp_version.major, gzvm_drv.hyp_version.minor,
> +		 gzvm_drv.hyp_version.sub);
> +
> +	return misc_register(&gzvm_dev);
> +}
> +
> +static void gzvm_drv_remove(struct platform_device *pdev)
> +{
> +	misc_deregister(&gzvm_dev);
> +}
> +
> +static const struct of_device_id gzvm_of_match[] = {
> +	{ .compatible = "mediatek,geniezone" },
> +	{/* sentinel */},
> +};
> +
> +static struct platform_driver gzvm_driver = {
> +	.probe = gzvm_drv_probe,
> +	.remove = gzvm_drv_remove,
> +	.driver = {
> +		.name = KBUILD_MODNAME,
> +		.of_match_table = gzvm_of_match,
> +	},
> +};
> +
> +module_platform_driver(gzvm_driver);
> +
> +MODULE_DEVICE_TABLE(of, gzvm_of_match);

This is immediately after next to ID table. Never in different place, so
I wonder from which obscure code did you copy it and what other issues
like that we can find...

> +MODULE_AUTHOR("MediaTek");
> +MODULE_DESCRIPTION("GenieZone interface for VMM");
> +MODULE_LICENSE("GPL");
Best regards,
Krzysztof


From heiko at sntech.de  Wed Dec 11 00:46:57 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 11 Dec 2024 09:46:57 +0100
Subject: [PATCH v2 0/4] Add support for HDMI1 output on RK3588 SoC
In-Reply-To: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
Message-ID: <12942826.iMDcRRXYNz@diego>

Hi Cristian,

Am Mittwoch, 11. Dezember 2024, 00:06:13 CET schrieb Cristian Ciocaltea:
> The patches provide the basic support to handle the second HDMI output
> port found on Rockchip RK3588 SoC.
> 
> For now I enabled it on Radxa ROCK 5B only, the board I've been using to
> validate this.
> 
> ** IMPORTANT **
> 
> The series has a runtime dependency on "phy: phy-rockchip-samsung-hdptx:
> Don't use dt aliases to determine phy-id", a patch submitted recently by
> Heiko [1].  Without applying it, the functionality on both HDMI TX ports
> will break.

Looking at the drm/rockchip patch, that should not cause disruptions on
its own, right?

Only with the dts-parts enabled would we run into phy-issue.
(Asking, because things go through different trees and the drm
part looks ready)


Heiko


> Furthermore, please note this is subject to the same limitations as
> HDMI0 when it comes to the supported display modes.  The fixes provided
> via [2] are not applicable to HDMI1, hence I will handle it separately
> as soon as all dependencies are merged.
> 
> Thanks,
> Cristian
> 
> [1] https://lore.kernel.org/lkml/20241206103401.1780416-3-heiko at sntech.de/
> [2] https://lore.kernel.org/all/20241116-vop2-hdmi0-disp-modes-v1-0-2bca51db4898 at collabora.com/
> 
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
> Changes in v2:
> - Override hdmi1 pinctrl-0 on rock-5b as it requires hdmim0_tx1_cec
>   instead of hdmim2_tx1_cec (fixes a pin conflict when enabling
>   CONFIG_SPI_ROCKCHIP_SFC)
> - Link to v1: https://lore.kernel.org/r/20241207-rk3588-hdmi1-v1-0-ca3a99b46a40 at collabora.com
> 
> ---
> Cristian Ciocaltea (4):
>       drm/rockchip: dw_hdmi_qp: Add support for RK3588 HDMI1 output
>       arm64: dts: rockchip: Add PHY node for HDMI1 TX port on RK3588
>       arm64: dts: rockchip: Add HDMI1 node on RK3588
>       arm64: dts: rockchip: Enable HDMI1 on rock-5b
> 
>  arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi  |  62 ++++++++++++
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts |  44 ++++++++-
>  drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c  | 119 +++++++++++++++++++-----
>  3 files changed, 200 insertions(+), 25 deletions(-)
> ---
> base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
> change-id: 20241207-rk3588-hdmi1-704cbb7cd75f
> 
> 






From krzk at kernel.org  Wed Dec 11 00:46:54 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 09:46:54 +0100
Subject: [PATCH v5 0/2] coresight: Add label sysfs node support
In-Reply-To: <20241210122253.31926-1-quic_jinlmao@quicinc.com>
References: <20241210122253.31926-1-quic_jinlmao@quicinc.com>
Message-ID: <avimk3fdjal6ohezktrexnbguxf6wj5tv6jbcqy5r4bnuww6kz@3xjt3mutne7n>

On Tue, Dec 10, 2024 at 08:22:51PM +0800, Mao Jinlong wrote:
> With current design, the name of the non-cpu bounded coresight
> component is the device type with the number. And with 'ls' command
> we can get the register address of the component. But from these
> information, we can't know what the HW or system the component belongs
> to. Add label in DT and show the hw information by reading label sysfs
> node.
> 
> cti_sys0 -> ../../../devices/platform/soc at 0/138f0000.cti/cti_sys0
> cti_sys1 -> ../../../devices/platform/soc at 0/13900000.cti/cti_sys1
> tpdm0 -> ../../../devices/platform/soc at 0/10b0d000.tpdm/tpdm0
> tpdm1 -> ../../../devices/platform/soc at 0/10c28000.tpdm/tpdm1
> tpdm2 -> ../../../devices/platform/soc at 0/10c29000.tpdm/tpdm2
> 
> /sys/bus/coresight/devices # cat cti*/label
> cti_dlct_0
> cti_dlct_1
> cti_apss_0
> cti_apss_1
> cti_apss_2
> 
> Change since V4:
> 1. Add label in DT and add label sysfs node for each coresight device. 

This is v5, no links to previous versions (I really suggest to start
using b4 if you want to make your process easier for you), no other
changes so subject is obviously the same and looking for this patchset
previous versions gives me 0 results:

https://lore.kernel.org/all/?q=%22coresight%3A+Add+label+sysfs+node+support%22

OK, let's try b4 diff:

b4 diff '20241210122253.31926-1-quic_jinlmao at quicinc.com'
Grabbing thread from lore.kernel.org/all/20241210122253.31926-1-quic_jinlmao at quicinc.com/t.mbox.gz
Checking for older revisions
Grabbing search results from lore.kernel.org
Nothing matching that query.
---
Analyzing 3 messages in the thread
Could not find lower series to compare against.


So how do you expect us to do any meaningful review?

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec 11 00:47:51 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 09:47:51 +0100
Subject: [PATCH v5 1/2] dt-bindings: arm: Add label in the coresight
 components
In-Reply-To: <20241210122253.31926-2-quic_jinlmao@quicinc.com>
References: <20241210122253.31926-1-quic_jinlmao@quicinc.com>
 <20241210122253.31926-2-quic_jinlmao@quicinc.com>
Message-ID: <ee5g6cy3kpwwyhlop7ex7zm5fombbmqbvp34exhm6dv22v5fwh@5o4xxwam3mnk>

On Tue, Dec 10, 2024 at 08:22:52PM +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 label to show hardware context information of each coresight
> device. There will be a sysfs node label in each device folder.
> 
> cat /sys/bus/coresight/devices/cti_sys0/label
> 
> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>

It is impossible to figure out what changed here comparing to previous
version (see details in cover letter). I will skip the review.

Best regards,
Krzysztof



From heiko at sntech.de  Wed Dec 11 00:52:10 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 11 Dec 2024 09:52:10 +0100
Subject: [PATCH v5 01/18] drm/rockchip: vop2: Add debugfs support
In-Reply-To: <121ab3c0.68d0.193b48b32ed.Coremail.andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com> <4471861.MSiuQNM8U4@diego>
 <121ab3c0.68d0.193b48b32ed.Coremail.andyshrk@163.com>
Message-ID: <3527424.cLl3JjQhRp@diego>

Hi Andy,

Am Mittwoch, 11. Dezember 2024, 08:07:21 CET schrieb Andy Yan:
> At 2024-12-10 19:57:44, "Heiko St?bner" <heiko at sntech.de> wrote:
> >Am Montag, 9. Dezember 2024, 13:29:13 CET schrieb Andy Yan:
> >> From: Andy Yan <andy.yan at rock-chips.com>
> >> 
> >> /sys/kernel/debug/dri/vop2/summary:  dump vop display state
> >> /sys/kernel/debug/dri/vop2/regs: dump whole vop registers
> >> /sys/kernel/debug/dri/vop2/active_regs: only dump the registers of
> >> activated modules
> >> 
> >> Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
> >> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
> >> Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
> >> Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
> >> ---
> >
> >> +static void __vop2_regs_dump(struct seq_file *s, bool active_only)
> >> +{
> >> +	struct drm_info_node *node = s->private;
> >> +	struct vop2 *vop2 = node->info_ent->data;
> >> +	struct drm_minor *minor = node->minor;
> >> +	struct drm_device *drm_dev = minor->dev;
> >> +	const struct vop2_regs_dump *dump;
> >> +	unsigned int i;
> >> +
> >> +	drm_modeset_lock_all(drm_dev);
> >> +
> >> +	regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
> >> +
> >> +	if (vop2->enable_count) {
> >> +		for (i = 0; i < vop2->data->regs_dump_size; i++) {
> >> +			dump = &vop2->data->regs_dump[i];
> >> +			vop2_regs_print(vop2, s, dump, active_only);
> >> +		}
> >> +	} else {
> >> +		seq_printf(s, "VOP disabled\n");
> >> +	}
> >> +	drm_modeset_unlock_all(drm_dev);
> >> +
> >
> >nit: not needed empty line at the end of the function
> 
> Will fixed in V6.
> 
> >
> >> +}
> >> +
> >
> >> +static void vop2_debugfs_init(struct vop2 *vop2, struct drm_minor *minor)
> >> +{
> >> +	struct dentry *root;
> >> +	unsigned int i;
> >> +
> >> +	root = debugfs_create_dir("vop2", minor->debugfs_root);
> >> +	if (!IS_ERR(root)) {
> >> +		for (i = 0; i < ARRAY_SIZE(vop2_debugfs_list); i++)
> >> +			vop2_debugfs_list[i].data = vop2;
> >> +
> >> +		drm_debugfs_create_files(vop2_debugfs_list,
> >> +					 ARRAY_SIZE(vop2_debugfs_list),
> >> +					 root, minor);
> >> +	}
> >> +}
> >> +
> >> +static int vop2_crtc_late_register(struct drm_crtc *crtc)
> >> +{
> >> +	struct vop2_video_port *vp = to_vop2_video_port(crtc);
> >> +	struct vop2 *vop2 = vp->vop2;
> >> +
> >> +	if (drm_crtc_index(crtc) == 0)
> >> +		vop2_debugfs_init(vop2, crtc->dev->primary);
> >> +
> >> +	return 0;
> >> +}
> >
> >I'm wondering about, shoudln't there be an unregister step too?
> >I.e. the late_register callback says:
> >"should be unregistered in the early_unregister callback" [0].
> >
> >And there exists drm_debugfs_remove_files(), though it doesn't
> >seem t be used much - just by tegra.
> >
> >I haven't managed to find drm code handling that automatically though?
> 
> Did a little digging?
>  rockchip_drm_unbind --?drm_dev_unregister(drm_dev)--?drm_debugfs_dev_fini
> --?debugfs_remove_recursive(dev->debugfs_root);
> This will remove all the debugfs file under /dri/0-->display-subsystem  when we
> remove rockchipdrm when it build as module.

thanks a lot for finding this. And yes, that covers all possible cases.

> If it is builtin, whether we remove them seems to make no difference when we
> reboot or thutdown the system ?
> I also searched for other platforms using similar late register hook, and it seems they haven't remove debugfs  either.

unbind can be called even if the driver is builtin - i.e. a driver
does not need to be a module to be unbount/rebound again.

But the drm_debugfs_dev_fini() function you found, solves that
in all cases, so this patch can stay as it is - minus the empty line.

Thanks a lot
Heiko




From dmitry.baryshkov at linaro.org  Wed Dec 11 00:52:51 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 11 Dec 2024 10:52:51 +0200
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <b47d44cc-77b7-4137-97e3-b245e1394580@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>
 <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>
 <iyknardi445n4h74am22arpgc4vlchh6z6cvkbff2xg76pd655@nozwz7snt476>
 <1219b46d-2aea-4377-a8ca-024039ee1499@quicinc.com>
 <CAF6AEGs4EebrwyQZviNXqB2=3h2wgZpmbrdGHuEU4z1D014GRA@mail.gmail.com>
 <b47d44cc-77b7-4137-97e3-b245e1394580@quicinc.com>
Message-ID: <pndxbcduiwytfwkortyxpdqgwa4bm3ajnjpa5nedjtgndq6z5v@mziv5z36zeqr>

On Wed, Dec 11, 2024 at 01:06:58PM +0530, Pavan Kondeti wrote:
> +devicetree
> 
> On Tue, Dec 10, 2024 at 07:43:19PM -0800, Rob Clark wrote:
> > On Tue, Dec 10, 2024 at 7:08?PM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> > >
> > > On 12/11/2024 6:43 AM, Bjorn Andersson wrote:
> > > > On Tue, Dec 10, 2024 at 02:22:27AM +0530, Akhil P Oommen wrote:
> > > >> On 12/10/2024 1:24 AM, Rob Clark wrote:
> > > >>> On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> > > >>>>
> > > >>>> When kernel is booted in EL2, SECVID registers are accessible to the
> > > >>>> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> > > >>>> on Zap firmware. Also, we can't load a secure firmware without a
> > > >>>> hypervisor that supports it.
> > > >>>
> > > >>> Shouldn't we do this based on whether zap node is in dtb (and not disabled)?
> > > >>
> > > >> This is better, isn't it? Otherwise, multiple overlays should be
> > > >> maintained for each soc/board since EL2 can be toggled from bootloader.
> > > >> And this feature is likely going to be more widely available.
> > > >>
> > > >
> > > > The DeviceTree passed to the OS needs to describe the world that said OS
> > > > is going to operate in. If you change the world you need to change the
> > > > description.
> > > > There are several other examples where this would be necessary
> > > > (remoteproc and watchdog to name two examples from the Qualcomm upstream
> > > > world).
> > >
> > > But basic things work without those changes, right? For eg: Desktop UI
> > 
> > It isn't really so much about whether certain use-cases can work with
> > a sub-optimal description of the hw (where in this case "hw" really
> > means "hw plus how the fw allows things to look to the HLOS").. It is
> > more about the hw/fw/whatever providing an accurate description of
> > what things look like to the HLOS.
> > 
> > I'm leaning more towards the hw+fw providing HLOS an accurate view...
> > and the fact that that carries over into other areas of dtb (ie. it
> > isn't the only thing that slbounce needs to patch, as I previously
> > mentioned) reinforces my view there.  This seems like a thing to fix
> > in fw/bootloader tbh.
> > 
> 
> Thanks Rob and Bjorn for your inputs. At the moment, we don't have
> capability in our bootloader to apply a *specific* overlay when Linux
> kernel is starteed in EL, this is making GPU non-functional. This patch
> from Akhil fixes the problem without depending on the bootloader.
> 
> From this discussion, I understand that it is recommended to provide
> HW+FW view in dT correctly instead of doing runtime checks in the
> kernel. We can take this as a requirement to the bootloader.
> 
> I would like to check how we should proceed with overlay. Should we
> submit dtso upstream and let bootloader apply the overlay at runtime or
> this whole overlay needs to be maintained in the bootloader. Also,
> Should we build all board dtb for EL2 as well or just leave it at compiling
> the EL2 dtbo (one per SoC)?

It doesn't have to be a dtbo. Instead you might just patch the DT
(Ideally via the https://github.com/U-Boot-EFI/EFI_DT_FIXUP_PROTOCOL).
I think the bootloader already changes the DT (by fixing memory sizes,
etc), so enabling or disabling ZAP & fixing several other bits and
pieces sounds logical.

-- 
With best wishes
Dmitry


From qperret at google.com  Wed Dec 11 00:57:22 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 08:57:22 +0000
Subject: [PATCH v2 12/18] KVM: arm64: Introduce
 __pkvm_host_relax_guest_perms()
In-Reply-To: <CA+EHjTwNgf5fPuWMaPaN4mcdd5y4uydJsXi-zEBatFnbwoaLLQ@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-13-qperret@google.com>
 <CA+EHjTwNgf5fPuWMaPaN4mcdd5y4uydJsXi-zEBatFnbwoaLLQ@mail.gmail.com>
Message-ID: <Z1lT8nGwEMqkedQs@google.com>

On Tuesday 10 Dec 2024 at 14:56:05 (+0000), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
> >
> > Introduce a new hypercall allowing the host to relax the stage-2
> > permissions of mappings in a non-protected guest page-table. It will be
> > used later once we start allowing RO memslots and dirty logging.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_asm.h              |  1 +
> >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
> >  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 20 ++++++++++++++++
> >  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 23 +++++++++++++++++++
> >  4 files changed, 45 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > index 0b6c4d325134..5d51933e44fb 100644
> > --- a/arch/arm64/include/asm/kvm_asm.h
> > +++ b/arch/arm64/include/asm/kvm_asm.h
> > @@ -67,6 +67,7 @@ enum __kvm_host_smccc_func {
> >         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
> >         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> >         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
> > +       __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_guest_perms,
> >         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
> >         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
> >         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > index e528a42ed60e..db0dd83c2457 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > @@ -41,6 +41,7 @@ int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
> >  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
> >  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
> >  int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
> > +int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu);
> 
> The parameters are the same as __pkvm_host_share_guest, but in a
> different order. I looked ahead at later patches in the series, and similar
> issues regarding parameter type and ordering, so I won't mention it
> for the later patches.

Ack to this and the other comment below, thanks for the review!

> 
> >  bool addr_is_memory(phys_addr_t phys);
> >  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > index 04a9053ae1d5..60dd56bbd743 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > @@ -267,6 +267,25 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
> >         cpu_reg(host_ctxt, 1) =  ret;
> >  }
> >
> > +static void handle___pkvm_host_relax_guest_perms(struct kvm_cpu_context *host_ctxt)
> > +{
> > +       DECLARE_REG(u64, gfn, host_ctxt, 1);
> > +       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 2);
> > +       struct pkvm_hyp_vcpu *hyp_vcpu;
> > +       int ret = -EINVAL;
> > +
> > +       if (!is_protected_kvm_enabled())
> > +               goto out;
> > +
> > +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> > +       if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> > +               goto out;
> > +
> > +       ret = __pkvm_host_relax_guest_perms(gfn, prot, hyp_vcpu);
> > +out:
> > +       cpu_reg(host_ctxt, 1) = ret;
> > +}
> > +
> >  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
> >  {
> >         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> > @@ -478,6 +497,7 @@ static const hcall_t host_hcall[] = {
> >         HANDLE_FUNC(__pkvm_host_unshare_hyp),
> >         HANDLE_FUNC(__pkvm_host_share_guest),
> >         HANDLE_FUNC(__pkvm_host_unshare_guest),
> > +       HANDLE_FUNC(__pkvm_host_relax_guest_perms),
> >         HANDLE_FUNC(__kvm_adjust_pc),
> >         HANDLE_FUNC(__kvm_vcpu_run),
> >         HANDLE_FUNC(__kvm_flush_vm_context),
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > index aa27a3e42e5e..d4b28e93e790 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > @@ -1480,3 +1480,26 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm)
> >
> >         return ret;
> >  }
> > +
> > +int __pkvm_host_relax_guest_perms(u64 gfn, enum kvm_pgtable_prot prot, struct pkvm_hyp_vcpu *vcpu)
> > +{
> > +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> > +       u64 ipa = hyp_pfn_to_phys(gfn);
> > +       u64 phys;
> > +       int ret;
> > +
> > +       if ((prot & KVM_PGTABLE_PROT_RWX) != prot)
> > +               return -EPERM;
> 
> Why not
> 
> +       if (prot & ~KVM_PGTABLE_PROT_RWX)
> 
> Simpler and consistent with similar checks in the file (e.g.,
> __pkvm_host_share_guest)
> 
> Cheers,
> /fuad
> 
> 
> > +
> > +       host_lock_component();
> > +       guest_lock_component(vm);
> > +
> > +       ret = __check_host_unshare_guest(vm, &phys, ipa);
> > +       if (!ret)
> > +               ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0);
> > +
> > +       guest_unlock_component(vm);
> > +       host_unlock_component();
> > +
> > +       return ret;
> > +}
> > --
> > 2.47.0.338.g60cca15819-goog
> >


From thomas.richard at bootlin.com  Wed Dec 11 00:59:30 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Wed, 11 Dec 2024 09:59:30 +0100
Subject: [PATCH] PCI: j721e: In j721e_pcie_suspend_noirq() check
 reset_gpio before to use it
In-Reply-To: <20241210154256.GA3242512@bhelgaas>
References: <20241210154256.GA3242512@bhelgaas>
Message-ID: <6c7cb07c-af9e-4f69-84df-2b59a57e4182@bootlin.com>

On 12/10/24 16:42, Bjorn Helgaas wrote:
> On Mon, Dec 09, 2024 at 12:23:21PM +0100, Thomas Richard wrote:
>> The reset_gpio is optional, so in j721e_pcie_suspend_noirq() check if it is
>> not NULL before to use it.
> 
> If you have occasion to post a v2, update subject to:
> 
>   PCI: j721e: Check reset_gpio for NULL before using it
> 
> s/before to use it/before using it/
> 
> Did you trip over a NULL pointer dereference here?  Or maybe found via
> inspection?

By inspection

> 
> It looks like gpiod_set_value_cansleep(desc) *should* be a no-op if
> desc is NULL, based on this comment [1]:
> 
>  * This descriptor validation needs to be inserted verbatim into each
>  * function taking a descriptor, so we need to use a preprocessor
>  * macro to avoid endless duplication. If the desc is NULL it is an
>  * optional GPIO and calls should just bail out.
> 
> and the fact that the VALIDATE_DESC_VOID() macro looks like it would
> return early in that case.
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpio/gpiolib.c?id=v6.12#n2316

Oh yes you're right.
In fact, the if statement in probe() and resume_noirq() is for msleep(),
not really for gpiod_set_value_cansleep().

So this patch is useless.

Regards,

Thomas


From quic_pkondeti at quicinc.com  Wed Dec 11 00:59:35 2024
From: quic_pkondeti at quicinc.com (Pavan Kondeti)
Date: Wed, 11 Dec 2024 14:29:35 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <pndxbcduiwytfwkortyxpdqgwa4bm3ajnjpa5nedjtgndq6z5v@mziv5z36zeqr>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <CAF6AEGtKfWOGpd1gMfJ96BjCqwERZzBVmj5GzmjKxw8_vmSrJg@mail.gmail.com>
 <f4813046-5952-4d16-bae6-37303f22ad1a@quicinc.com>
 <iyknardi445n4h74am22arpgc4vlchh6z6cvkbff2xg76pd655@nozwz7snt476>
 <1219b46d-2aea-4377-a8ca-024039ee1499@quicinc.com>
 <CAF6AEGs4EebrwyQZviNXqB2=3h2wgZpmbrdGHuEU4z1D014GRA@mail.gmail.com>
 <b47d44cc-77b7-4137-97e3-b245e1394580@quicinc.com>
 <pndxbcduiwytfwkortyxpdqgwa4bm3ajnjpa5nedjtgndq6z5v@mziv5z36zeqr>
Message-ID: <d788a810-1d54-48d5-a8f5-19a8e7a64313@quicinc.com>

On Wed, Dec 11, 2024 at 10:52:51AM +0200, Dmitry Baryshkov wrote:
> On Wed, Dec 11, 2024 at 01:06:58PM +0530, Pavan Kondeti wrote:
> > +devicetree
> > 
> > On Tue, Dec 10, 2024 at 07:43:19PM -0800, Rob Clark wrote:
> > > On Tue, Dec 10, 2024 at 7:08?PM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> > > >
> > > > On 12/11/2024 6:43 AM, Bjorn Andersson wrote:
> > > > > On Tue, Dec 10, 2024 at 02:22:27AM +0530, Akhil P Oommen wrote:
> > > > >> On 12/10/2024 1:24 AM, Rob Clark wrote:
> > > > >>> On Mon, Dec 9, 2024 at 12:20?AM Akhil P Oommen <quic_akhilpo at quicinc.com> wrote:
> > > > >>>>
> > > > >>>> When kernel is booted in EL2, SECVID registers are accessible to the
> > > > >>>> KMD. So we can use that to switch GPU's secure mode to avoid dependency
> > > > >>>> on Zap firmware. Also, we can't load a secure firmware without a
> > > > >>>> hypervisor that supports it.
> > > > >>>
> > > > >>> Shouldn't we do this based on whether zap node is in dtb (and not disabled)?
> > > > >>
> > > > >> This is better, isn't it? Otherwise, multiple overlays should be
> > > > >> maintained for each soc/board since EL2 can be toggled from bootloader.
> > > > >> And this feature is likely going to be more widely available.
> > > > >>
> > > > >
> > > > > The DeviceTree passed to the OS needs to describe the world that said OS
> > > > > is going to operate in. If you change the world you need to change the
> > > > > description.
> > > > > There are several other examples where this would be necessary
> > > > > (remoteproc and watchdog to name two examples from the Qualcomm upstream
> > > > > world).
> > > >
> > > > But basic things work without those changes, right? For eg: Desktop UI
> > > 
> > > It isn't really so much about whether certain use-cases can work with
> > > a sub-optimal description of the hw (where in this case "hw" really
> > > means "hw plus how the fw allows things to look to the HLOS").. It is
> > > more about the hw/fw/whatever providing an accurate description of
> > > what things look like to the HLOS.
> > > 
> > > I'm leaning more towards the hw+fw providing HLOS an accurate view...
> > > and the fact that that carries over into other areas of dtb (ie. it
> > > isn't the only thing that slbounce needs to patch, as I previously
> > > mentioned) reinforces my view there.  This seems like a thing to fix
> > > in fw/bootloader tbh.
> > > 
> > 
> > Thanks Rob and Bjorn for your inputs. At the moment, we don't have
> > capability in our bootloader to apply a *specific* overlay when Linux
> > kernel is starteed in EL, this is making GPU non-functional. This patch
> > from Akhil fixes the problem without depending on the bootloader.
> > 
> > From this discussion, I understand that it is recommended to provide
> > HW+FW view in dT correctly instead of doing runtime checks in the
> > kernel. We can take this as a requirement to the bootloader.
> > 
> > I would like to check how we should proceed with overlay. Should we
> > submit dtso upstream and let bootloader apply the overlay at runtime or
> > this whole overlay needs to be maintained in the bootloader. Also,
> > Should we build all board dtb for EL2 as well or just leave it at compiling
> > the EL2 dtbo (one per SoC)?
> 
> It doesn't have to be a dtbo. Instead you might just patch the DT
> (Ideally via the https://github.com/U-Boot-EFI/EFI_DT_FIXUP_PROTOCOL).
> I think the bootloader already changes the DT (by fixing memory sizes,
> etc), so enabling or disabling ZAP & fixing several other bits and
> pieces sounds logical.
> 

Yes, that would mean maintaining this completely outside upstream
kernel. As you said, this is currently happening for bootargs, memory
etc.

Thanks,
Pavan


From clement.legoffic at foss.st.com  Wed Dec 11 01:02:17 2024
From: clement.legoffic at foss.st.com (Clement LE GOFFIC)
Date: Wed, 11 Dec 2024 10:02:17 +0100
Subject: [PATCH v4] watchdog: stm32_iwdg: Add pretimeout support
In-Reply-To: <20240415134903.8084-1-marex@denx.de>
References: <20240415134903.8084-1-marex@denx.de>
Message-ID: <49ccec07-4d4c-4582-814b-d4a60adbbfe1@foss.st.com>

On 4/15/24 15:48, Marek Vasut wrote:
> The STM32MP15xx IWDG adds registers which permit this IP to generate
> pretimeout interrupt. This interrupt can also be used to wake the CPU
> from suspend. Implement support for generating this interrupt and let
> userspace configure the pretimeout. In case the pretimeout is not
> configured by user, set pretimeout to 3/4 of the WDT timeout cycle.
> 
> Reviewed-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
> Tested-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Guenter Roeck <linux at roeck-us.net>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Wim Van Sebroeck <wim at linux-watchdog.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> Cc: linux-watchdog at vger.kernel.org
> ---
> V2: - Subtract the pretimeout value from timeout value before writing it
>        into the IWDG pretimeout register, because the watchdog counter
>        register is counting down, and the pretimeout interrupt triggers
>        when watchdog counter register matches the pretimeout register
>        content.
>      - Set default pretimeout to 3/4 of timeout .
> V3: - Use dev instead of pdev->dev
>      - Swap order of ret/return 0
>      - Split this from the DT changes, which are orthogonal
>      - Uh, this patch got stuck in upstreaming queue, sorry
> V4: - Update commit message to match V2 default pretimeout to 3/4
>      - Add RB/TB from Cl?ment
> ---
>   drivers/watchdog/stm32_iwdg.c | 95 ++++++++++++++++++++++++++++++++++-
>   1 file changed, 94 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
> index 5404e03876202..d700e0d49bb95 100644
> --- a/drivers/watchdog/stm32_iwdg.c
> +++ b/drivers/watchdog/stm32_iwdg.c
>  
>  [.....]
>  
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq <= 0)
> +		return 0;

Hi Marek,

After re-evaluating this patch, it seems it lacks of a dt-bindings 
update that tackles the 'interrupts' property you are adding.

That said, the interrupt line should not be mandatory for the driver to 
probe. For backward compatibility with existing DT, I recommend to use 
the 'platform_get_irq_optional()' API to not fail during the probe of 
the driver.

Best regards,

Cl?ment


From jianqi.ren.cn at windriver.com  Wed Dec 11 02:02:49 2024
From: jianqi.ren.cn at windriver.com (jianqi.ren.cn at windriver.com)
Date: Wed, 11 Dec 2024 18:02:49 +0800
Subject: [PATCH 6.1.y] media: mtk-vcodec: potential null pointer deference in SCP
Message-ID: <20241211100249.2069678-1-jianqi.ren.cn@windriver.com>

From: Fullway Wang <fullwaywang at outlook.com>

[ Upstream commit 53dbe08504442dc7ba4865c09b3bbf5fe849681b ]

The return value of devm_kzalloc() needs to be checked to avoid
NULL pointer deference. This is similar to CVE-2022-3113.

Link: https://lore.kernel.org/linux-media/PH7PR20MB5925094DAE3FD750C7E39E01BF712 at PH7PR20MB5925.namprd20.prod.outlook.com
Signed-off-by: Fullway Wang <fullwaywang at outlook.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab at kernel.org>
Signed-off-by: Jianqi Ren <jianqi.ren.cn at windriver.com>
---
 drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c
index d8e66b645bd8..27f08b1d34d1 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c
@@ -65,6 +65,8 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev)
 	}
 
 	fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
+	if (!fw)
+		return ERR_PTR(-ENOMEM);
 	fw->type = SCP;
 	fw->ops = &mtk_vcodec_rproc_msg;
 	fw->scp = scp;
-- 
2.25.1



From krzk at kernel.org  Wed Dec 11 01:06:58 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 10:06:58 +0100
Subject: [PATCH v3 5/6] arm64: dts: imx8mp: Add fsl,dsp-ctrl property for
 dsp
In-Reply-To: <20241210125338.104959-6-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
 <20241210125338.104959-6-daniel.baluta@nxp.com>
Message-ID: <l3z3mu5inmfc23v4mymtcb4gnzic5zupqfpcuk7vqeweluy5jn@c2b5ex4lkdgc>

On Tue, Dec 10, 2024 at 02:53:37PM +0200, Daniel Baluta wrote:
> Audio block control contains a set of registers some of them used for
> DSP configuration.
> 
> Drivers (rproc, SOF) are using fsl,dsp-ctrl property to access those
> registers in order to control the operations of the DSP (e.g for
> start, reset, etc).

This should have been implemented as reset controller, not syscon. It's
really poor choice to call everything syscon. It does not scale, does
not provide you runtime PM or probe ordering (device links). Quick look
at your drivers suggest that you have exacvtly that problems.

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec 11 01:07:35 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 10:07:35 +0100
Subject: [PATCH v3 4/6] dt-bindings: clock: imx8mp: Add syscon compatible
In-Reply-To: <20241210125338.104959-5-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
 <20241210125338.104959-5-daniel.baluta@nxp.com>
Message-ID: <247owlllg4dzqdk2sead5xb33x5pclkrhuvnthdepem3dwrecf@xauk2um726he>

On Tue, Dec 10, 2024 at 02:53:36PM +0200, Daniel Baluta wrote:
> imx8mp audiomix contains a set of registers used to control
> the DSP.
> 
> The dsp will use this to acquire o reference to audiomix registers
> and handle the registers to control the dsp.


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

Best regards,
Krzysztof



From manivannan.sadhasivam at linaro.org  Wed Dec 11 01:14:21 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 11 Dec 2024 14:44:21 +0530
Subject: [PATCH] PCI: j721e: In j721e_pcie_suspend_noirq() check
 reset_gpio before to use it
In-Reply-To: <6c7cb07c-af9e-4f69-84df-2b59a57e4182@bootlin.com>
References: <20241210154256.GA3242512@bhelgaas>
 <6c7cb07c-af9e-4f69-84df-2b59a57e4182@bootlin.com>
Message-ID: <20241211091421.4empou7mbm35ynxq@thinkpad>

On Wed, Dec 11, 2024 at 09:59:30AM +0100, Thomas Richard wrote:
> On 12/10/24 16:42, Bjorn Helgaas wrote:
> > On Mon, Dec 09, 2024 at 12:23:21PM +0100, Thomas Richard wrote:
> >> The reset_gpio is optional, so in j721e_pcie_suspend_noirq() check if it is
> >> not NULL before to use it.
> > 
> > If you have occasion to post a v2, update subject to:
> > 
> >   PCI: j721e: Check reset_gpio for NULL before using it
> > 
> > s/before to use it/before using it/
> > 
> > Did you trip over a NULL pointer dereference here?  Or maybe found via
> > inspection?
> 
> By inspection
> 
> > 
> > It looks like gpiod_set_value_cansleep(desc) *should* be a no-op if
> > desc is NULL, based on this comment [1]:
> > 
> >  * This descriptor validation needs to be inserted verbatim into each
> >  * function taking a descriptor, so we need to use a preprocessor
> >  * macro to avoid endless duplication. If the desc is NULL it is an
> >  * optional GPIO and calls should just bail out.
> > 
> > and the fact that the VALIDATE_DESC_VOID() macro looks like it would
> > return early in that case.
> > 
> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpio/gpiolib.c?id=v6.12#n2316
> 
> Oh yes you're right.
> In fact, the if statement in probe() and resume_noirq() is for msleep(),
> not really for gpiod_set_value_cansleep().
> 
> So this patch is useless.
> 

Yes. Almost all of the GPIO APIs accepting desc (except few) use VALIDATE_DESC()
to check for NULL descriptor. So explicit check is not needed.

- Mani

-- 
????????? ????????


From cristian.ciocaltea at collabora.com  Wed Dec 11 01:16:14 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 11:16:14 +0200
Subject: [PATCH v2 0/4] Add support for HDMI1 output on RK3588 SoC
In-Reply-To: <12942826.iMDcRRXYNz@diego>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
 <12942826.iMDcRRXYNz@diego>
Message-ID: <43ae0fc5-d775-49d7-80cd-af111ff8fb25@collabora.com>

Hi Heiko,

On 12/11/24 10:46 AM, Heiko St?bner wrote:
> Hi Cristian,
> 
> Am Mittwoch, 11. Dezember 2024, 00:06:13 CET schrieb Cristian Ciocaltea:
>> The patches provide the basic support to handle the second HDMI output
>> port found on Rockchip RK3588 SoC.
>>
>> For now I enabled it on Radxa ROCK 5B only, the board I've been using to
>> validate this.
>>
>> ** IMPORTANT **
>>
>> The series has a runtime dependency on "phy: phy-rockchip-samsung-hdptx:
>> Don't use dt aliases to determine phy-id", a patch submitted recently by
>> Heiko [1].  Without applying it, the functionality on both HDMI TX ports
>> will break.
> 
> Looking at the drm/rockchip patch, that should not cause disruptions on
> its own, right?
> 
> Only with the dts-parts enabled would we run into phy-issue.
> (Asking, because things go through different trees and the drm
> part looks ready)

That's right, I should have better explained this - all patches except
the last one (that is actually enabling HDMI1 on a specific board) can
be safely applied.

Thanks,
Cristian


From iuliana.prodan at nxp.com  Wed Dec 11 01:21:51 2024
From: iuliana.prodan at nxp.com (Iuliana Prodan)
Date: Wed, 11 Dec 2024 11:21:51 +0200
Subject: [PATCH v3 0/6] Configure imx8mp dsp node for rproc usage
In-Reply-To: <20241210125338.104959-1-daniel.baluta@nxp.com>
References: <20241210125338.104959-1-daniel.baluta@nxp.com>
Message-ID: <f1382b53-d2b1-4622-af37-69431f764f79@nxp.com>


On 12/10/2024 2:53 PM, Daniel Baluta wrote:
> DSP found in i.MX8MP SOC can be used by multiple frameworks in order to
> enable various applications:
>          - rproc/rpmsg framework, used to load for example Zephyr samples
>          - Sound Open Firmware, used to enable various audio processing
>            pipelines.
>
> Current dsp node was configured with SOF in mind but it doesn't work
> well with imx8mp-evk dts. SOF controls audio IPs from firmware side
> while imx8mp-evk preffers to control audio IPs from Linux side.
>
> So, configure 'dsp' node to be used with rproc scenario and later will
> add a separate dts or an overlay to configure the node for SOF.
>
> This patch series configures and enables dsp node to be used with rproc.
>
> Changes since v1:
>          - document syscon compatible as pointed by Peng Fan
>          - do not disable dsp_reserved node in the dtsi file as pointed
>            by Ahmad Fatoum.
> Changes since v2:
>          - Fix dts example in patch 4/6
>          - Frank Li commented that we should handle the reset using the reset
>          interface. I have two objections on this: we are using some bits from audiomix
>          for reset together some other bits from DAP region. Also, the implementation is already upstream!
>          Frank Li agreed that it's up to Rob opinion on this.
>
> Daniel Baluta (6):
>    arm64: dts: imx8mp: Add mu2 root clock
>    arm64: dts: imx8mp: Configure dsp node for rproc usage
>    arm64: dts: imx8mp: Add DSP clocks
>    dt-bindings: clock: imx8mp: Add syscon compatible
>    arm64: dts: imx8mp: Add fsl,dsp-ctrl property for dsp
>    arm64: dts: Add dsp rproc related mem regions
For the series:

Reviewed-by: Iuliana Prodan <iuliana.prodan at nxp.com>

Thanks,
Iulia



From krzysztof.kozlowski at linaro.org  Wed Dec 11 01:22:48 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 10:22:48 +0100
Subject: [RESEND PATCH] media: dt-bindings: trivial white-space and
 example cleanup
In-Reply-To: <20241209113405.74226-1-krzysztof.kozlowski@linaro.org>
References: <20241209113405.74226-1-krzysztof.kozlowski@linaro.org>
Message-ID: <357a8910-82cc-4401-b985-0d01cc7b9128@linaro.org>

On 09/12/2024 12:34, Krzysztof Kozlowski wrote:
> Minor cleanups without funcitonal impact:
>  - There should not be an empty blank line after SPDX tag,
>  - Convention is to indent DTS examples in coding style with 2- or
>    4-space indentation (4 is preferred),
>  - Drop unused labels in DTS examples.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> ---
> 
> No comments since August... Can it be applied?

I think I missed here Rob's review.

Best regards,
Krzysztof


From krzysztof.kozlowski at linaro.org  Wed Dec 11 01:25:09 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 10:25:09 +0100
Subject: [RESEND PATCH] media: dt-bindings: trivial white-space and example cleanup
Message-ID: <20241211092509.34342-1-krzysztof.kozlowski@linaro.org>

Minor cleanups without funcitonal impact:
 - There should not be an empty blank line after SPDX tag,
 - Convention is to indent DTS examples in coding style with 2- or
   4-space indentation (4 is preferred),
 - Drop unused labels in DTS examples.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

---

Resending second time, because I missed previous Rob's review.

I added now also Bryan's and Heiko's reviews from last resend.
---
 .../media/allwinner,sun50i-h6-vpu-g2.yaml     |  1 -
 .../bindings/media/amlogic,meson-ir-tx.yaml   |  1 -
 .../bindings/media/amphion,vpu.yaml           |  1 -
 .../bindings/media/fsl,imx6ull-pxp.yaml       |  1 -
 .../media/mediatek,vcodec-decoder.yaml        |  1 -
 .../media/mediatek,vcodec-encoder.yaml        |  1 -
 .../media/mediatek,vcodec-subdev-decoder.yaml |  1 -
 .../media/microchip,sama5d4-vdec.yaml         | 17 ++++----
 .../bindings/media/nxp,imx8mq-vpu.yaml        | 41 +++++++++----------
 .../bindings/media/qcom,msm8916-camss.yaml    |  1 -
 .../bindings/media/qcom,msm8996-camss.yaml    |  1 -
 .../bindings/media/qcom,sdm660-camss.yaml     |  1 -
 .../bindings/media/qcom,sdm845-camss.yaml     |  1 -
 .../bindings/media/qcom,sm8250-camss.yaml     |  1 -
 .../bindings/media/rockchip,rk3568-vepu.yaml  |  1 -
 .../bindings/media/rockchip-vpu.yaml          | 29 +++++++------
 16 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml b/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
index a4f06bbdfe49..8ba5177ac631 100644
--- a/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
+++ b/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/allwinner,sun50i-h6-vpu-g2.yaml#
diff --git a/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml b/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
index 377acce93423..6da8a6aded23 100644
--- a/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
+++ b/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/amlogic,meson-ir-tx.yaml#
diff --git a/Documentation/devicetree/bindings/media/amphion,vpu.yaml b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
index 9801de3ed84e..5a920d9e78c7 100644
--- a/Documentation/devicetree/bindings/media/amphion,vpu.yaml
+++ b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/amphion,vpu.yaml#
diff --git a/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml b/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
index 84a5e894ace4..3f47744459aa 100644
--- a/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
+++ b/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/fsl,imx6ull-pxp.yaml#
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
index b401c67e3ba0..d726d141a434 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/mediatek,vcodec-decoder.yaml#
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
index b45743d0a9ec..110e8f5f1f9e 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/mediatek,vcodec-encoder.yaml#
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
index a500a585c692..5865e6f0be89 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#
diff --git a/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml b/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
index 59b805ca47c5..ede086d55add 100644
--- a/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
+++ b/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/microchip,sama5d4-vdec.yaml#
@@ -36,12 +35,12 @@ additionalProperties: false
 
 examples:
   - |
-        #include <dt-bindings/clock/at91.h>
-        #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/at91.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
 
-        vdec0: vdec at 300000 {
-                compatible = "microchip,sama5d4-vdec";
-                reg = <0x00300000 0x100000>;
-                interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>;
-                clocks = <&pmc PMC_TYPE_PERIPHERAL 19>;
-        };
+    vdec at 300000 {
+        compatible = "microchip,sama5d4-vdec";
+        reg = <0x00300000 0x100000>;
+        interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>;
+        clocks = <&pmc PMC_TYPE_PERIPHERAL 19>;
+    };
diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
index 3d58f02b0c5d..19528262810a 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#
@@ -44,26 +43,26 @@ additionalProperties: false
 
 examples:
   - |
-        #include <dt-bindings/clock/imx8mq-clock.h>
-        #include <dt-bindings/power/imx8mq-power.h>
-        #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/power/imx8mq-power.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-        vpu_g1: video-codec at 38300000 {
-                compatible = "nxp,imx8mq-vpu-g1";
-                reg = <0x38300000 0x10000>;
-                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-                clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
-                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
-        };
+    video-codec at 38300000 {
+        compatible = "nxp,imx8mq-vpu-g1";
+        reg = <0x38300000 0x10000>;
+        interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
+        power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
+    };
   - |
-        #include <dt-bindings/clock/imx8mq-clock.h>
-        #include <dt-bindings/power/imx8mq-power.h>
-        #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/power/imx8mq-power.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-        vpu_g2: video-codec at 38300000 {
-                compatible = "nxp,imx8mq-vpu-g2";
-                reg = <0x38310000 0x10000>;
-                interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-                clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
-                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
-        };
+    video-codec at 38300000 {
+        compatible = "nxp,imx8mq-vpu-g2";
+        reg = <0x38310000 0x10000>;
+        interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+        power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
+    };
diff --git a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
index 9cc0a968a401..3469a43f00d4 100644
--- a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,msm8916-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
index 5cb0e337ea6e..644646de338a 100644
--- a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,msm8996-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
index 584106e275f6..68d8670557f5 100644
--- a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,sdm660-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
index d32daaef1b50..289494f561e5 100644
--- a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,sdm845-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
index 06db2c1e6079..a372d991e652 100644
--- a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/qcom,sm8250-camss.yaml#
diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
index 947ad699cc5e..d246f5d38427 100644
--- a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/rockchip,rk3568-vepu.yaml#
diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
index 719aeb2dc593..8c2501634080 100644
--- a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/media/rockchip-vpu.yaml#
@@ -92,18 +91,18 @@ additionalProperties: false
 
 examples:
   - |
-        #include <dt-bindings/clock/rk3288-cru.h>
-        #include <dt-bindings/interrupt-controller/arm-gic.h>
-        #include <dt-bindings/power/rk3288-power.h>
+    #include <dt-bindings/clock/rk3288-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/rk3288-power.h>
 
-        vpu: video-codec at ff9a0000 {
-                compatible = "rockchip,rk3288-vpu";
-                reg = <0xff9a0000 0x800>;
-                interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
-                interrupt-names = "vepu", "vdpu";
-                clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
-                clock-names = "aclk", "hclk";
-                power-domains = <&power RK3288_PD_VIDEO>;
-                iommus = <&vpu_mmu>;
-        };
+    video-codec at ff9a0000 {
+        compatible = "rockchip,rk3288-vpu";
+        reg = <0xff9a0000 0x800>;
+        interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "vepu", "vdpu";
+        clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
+        clock-names = "aclk", "hclk";
+        power-domains = <&power RK3288_PD_VIDEO>;
+        iommus = <&vpu_mmu>;
+    };
-- 
2.43.0



From krzk at kernel.org  Wed Dec 11 01:27:53 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 10:27:53 +0100
Subject: [PATCH v2 1/2] dt-bindings: mmc: mtk-sd: Document compatibles
 that need two register ranges
In-Reply-To: <20241210073212.3917912-2-wenst@chromium.org>
References: <20241210073212.3917912-1-wenst@chromium.org>
 <20241210073212.3917912-2-wenst@chromium.org>
Message-ID: <qgsqjp6bodaiwfzpy54vgeo7pkyhfpdalvt7qjkodosnec4v3w@34446achvtve>

On Tue, Dec 10, 2024 at 03:32:10PM +0800, Chen-Yu Tsai wrote:
> Besides the MT8183's MMC controller and all its compatible derivatives,
> the recently added MT7986 and MT8196 also require two register ranges.
> This is based on the actual device trees.
> 
> Properly enforce this in the binding.
> 
> Fixes: 4a8bd2b07d88 ("dt-bindings: mmc: mtk-sd: Add mt7988 SoC")
> Fixes: 58927c9dc4ab ("dt-bindings: mmc: mtk-sd: Add support for MT8196")
> Cc: Frank Wunderlich <frank-w at public-files.de>
> Cc: Andy-ld Lu <andy-ld.lu at mediatek.com>
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)

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

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec 11 01:31:42 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 10:31:42 +0100
Subject: [PATCH v2 1/2] dt-bindings: display: panel-lvds: Add compatible
 for AUO G084SN05 V9
In-Reply-To: <20241210105705.116116-1-festevam@gmail.com>
References: <20241210105705.116116-1-festevam@gmail.com>
Message-ID: <yujvdu3s6v7z7th2lrdscqfxocx2zy2u4owakisvnjppz2udqv@5ok2rcf4exd4>

On Tue, Dec 10, 2024 at 07:57:04AM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> The AUO G084SN05 V9 is an 8.4" 800x600 LVDS display.
> 
> Add a compatible entry for this LVDS display model.
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>
> ---
> Changes since v1:
> - Added devicetree at vger.kernel.org on Cc.
> 
>  Documentation/devicetree/bindings/display/panel/panel-lvds.yaml | 2 ++
>  1 file changed, 2 insertions(+)

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

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec 11 01:35:47 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 10:35:47 +0100
Subject: [PATCH v2 1/2] dt-bindings: thermal: fsl,imx91-tmu: add bindings
 for NXP i.MX91 thermal module
In-Reply-To: <20241210-imx91tmu-v2-1-5032aad4d88e@nxp.com>
References: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
 <20241210-imx91tmu-v2-1-5032aad4d88e@nxp.com>
Message-ID: <u2y3owsp442geue2knfhnx4zhrzefmky6bl47nxaaqhw7dhpb3@vkc6z7c5hwv2>

On Tue, Dec 10, 2024 at 04:27:02PM -0500, Frank Li wrote:
> +description:
> +  i.MX91 features a new temperature sensor. It includes programmable
> +  temperature threshold comparators for both normal and privileged
> +  accesses and allows a programmable measurement frequency for the
> +  Periodic One-Shot Measurement mode. Additionally, it provides
> +  status registers for indicating the end of measurement and threshold
> +  violation events.
> +

Missing ref to thermal-sensor.yaml

> +properties:
> +  compatible:
> +    items:
> +      - const: fsl,imx91-tmu
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  nvmem-cells:
> +    items:
> +      - description: Phandle to the trim control 1 provided by ocotp
> +      - description: Phandle to the trim control 2 provided by ocotp
> +
> +  nvmem-cell-names:
> +    items:
> +      - const: trim1
> +      - const: trim2
> +
> +  "#thermal-sensor-cells":
> +    enum: [0, 1]

Why this is flexible? How many sensors do you have there?

> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - '#thermal-sensor-cells'

Use consistent quotes, either ' or "

> +
> +additionalProperties: false

This should be unevaluatedProperties: false after referencing mentioned
earlier thermal-sensor yaml

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec 11 01:37:59 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 10:37:59 +0100
Subject: [PATCH v2 1/8] dt-bindings: mailbox: mediatek: Add GCE header
 file for MT8196
In-Reply-To: <20241211032256.28494-2-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
 <20241211032256.28494-2-jason-jh.lin@mediatek.com>
Message-ID: <ozifi65uycmxc5hqeu4onbths5u7dg532iufjxplsjw4jjmhf6@6bdsaabd7hl7>

On Wed, Dec 11, 2024 at 11:22:49AM +0800, Jason-JH.Lin wrote:
> Add the Global Command Engine (GCE) header file to define the GCE
> thread priority, GCE subsys ID and GCE events for MT8196.

This we see from the diff. What we do not see is why priority is a
binding. Looking briefly at existing code: it is not a binding, there is
no driver user.

> 
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> ---
>  .../dt-bindings/mailbox/mediatek,mt8196-gce.h | 1439 +++++++++++++++++
>  1 file changed, 1439 insertions(+)
>  create mode 100644 include/dt-bindings/mailbox/mediatek,mt8196-gce.h
> 
> diff --git a/include/dt-bindings/mailbox/mediatek,mt8196-gce.h b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h
> new file mode 100644
> index 000000000000..860d69100157
> --- /dev/null
> +++ b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h
> @@ -0,0 +1,1439 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +/*
> + * Copyright (c) 2024 MediaTek Inc.
> + *
> + */
> +
> +#ifndef _DT_BINDINGS_GCE_MT8196_H
> +#define _DT_BINDINGS_GCE_MT8196_H
> +
> +/* GCE thread priority */
> +#define CMDQ_THR_PRIO_LOWEST	0
> +#define CMDQ_THR_PRIO_1		1
> +#define CMDQ_THR_PRIO_2		2
> +#define CMDQ_THR_PRIO_3		3
> +#define CMDQ_THR_PRIO_4		4
> +#define CMDQ_THR_PRIO_5		5
> +#define CMDQ_THR_PRIO_6		6
> +#define CMDQ_THR_PRIO_HIGHEST	7
> +
> +/* GCE subsys table */
> +#define SUBSYS_1300XXXX		0
> +#define SUBSYS_1400XXXX		1
> +#define SUBSYS_1401XXXX		2
> +#define SUBSYS_1402XXXX		3
> +#define SUBSYS_1502XXXX		4
> +#define SUBSYS_1880XXXX		5
> +#define SUBSYS_1881XXXX		6
> +#define SUBSYS_1882XXXX		7
> +#define SUBSYS_1883XXXX		8
> +#define SUBSYS_1884XXXX		9
> +#define SUBSYS_1000XXXX		10
> +#define SUBSYS_1001XXXX		11
> +#define SUBSYS_1002XXXX		12
> +#define SUBSYS_1003XXXX		13
> +#define SUBSYS_1004XXXX		14
> +#define SUBSYS_1005XXXX		15
> +#define SUBSYS_1020XXXX		16
> +#define SUBSYS_1028XXXX		17
> +#define SUBSYS_1700XXXX		18
> +#define SUBSYS_1701XXXX		19
> +#define SUBSYS_1702XXXX		20
> +#define SUBSYS_1703XXXX		21
> +#define SUBSYS_1800XXXX		22
> +#define SUBSYS_1801XXXX		23
> +#define SUBSYS_1802XXXX		24
> +#define SUBSYS_1804XXXX		25
> +#define SUBSYS_1805XXXX		26
> +#define SUBSYS_1808XXXX		27
> +#define SUBSYS_180aXXXX		28
> +#define SUBSYS_180bXXXX		29
> +#define SUBSYS_NO_SUPPORT	99
> +
> +/*
> + * GCE General Purpose Register (GPR) support
> + * Leave note for scenario usage here
> + */
> +/* GCE: write mask */

That's a definite no-go. Register masks are not bindings.

> +#define GCE_GPR_R00		0x0
> +#define GCE_GPR_R01		0x1

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec 11 01:39:13 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 10:39:13 +0100
Subject: [PATCH v2 2/8] dt-bindings: mailbox: mediatek: Add MT8196
 support for gce-mailbox
In-Reply-To: <20241211032256.28494-3-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
 <20241211032256.28494-3-jason-jh.lin@mediatek.com>
Message-ID: <yhfxpflyumevs66sdwgiiyuablpfxfxw3e7ybrxju7ssicmnu5@truuiuvxlq6e>

On Wed, Dec 11, 2024 at 11:22:50AM +0800, Jason-JH.Lin wrote:
> Add compatible name and iommus property for MT8196.
> 
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> ---
>  .../devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml     | 4 ++++
>  1 file changed, 4 insertions(+)

Headers are never separate from the bindings patch...

And you reveived exactly the same comments before which you just
ignored.

NAK.

Best regards,
Krzysztof



From aarnoud at me.com  Wed Dec 11 01:42:10 2024
From: aarnoud at me.com (Alexandre ARNOUD)
Date: Wed, 11 Dec 2024 10:42:10 +0100
Subject: [PATCH v2 0/4] Add support for HDMI1 output on RK3588 SoC
In-Reply-To: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
Message-ID: <BC29D61C-317D-4F82-AF42-EA3D705B0632@me.com>

Hello Cristian,

> On 11 Dec 2024, at 12:06 AM, Cristian Ciocaltea <cristian.ciocaltea at collabora.com> wrote:
> 
> Changes in v2:
> - Override hdmi1 pinctrl-0 on rock-5b as it requires hdmim0_tx1_cec
>  instead of hdmim2_tx1_cec (fixes a pin conflict when enabling
>  CONFIG_SPI_ROCKCHIP_SFC)
> - Link to v1: https://lore.kernel.org/r/20241207-rk3588-hdmi1-v1-0-ca3a99b46a40 at collabora.com
> 
> ---
> Cristian Ciocaltea (4):
>      drm/rockchip: dw_hdmi_qp: Add support for RK3588 HDMI1 output
>      arm64: dts: rockchip: Add PHY node for HDMI1 TX port on RK3588
>      arm64: dts: rockchip: Add HDMI1 node on RK3588
>      arm64: dts: rockchip: Enable HDMI1 on rock-5b
> 
> arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi  |  62 ++++++++++++
> arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts |  44 ++++++++-
> drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c  | 119 +++++++++++++++++++-----
> 3 files changed, 200 insertions(+), 25 deletions(-)
> ---
> base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
> change-id: 20241207-rk3588-hdmi1-704cbb7cd75f

Tested-by: Alexandre ARNOUD <aarnoud at me.com>

Works perfectly on Rock-5B, thanks for your work.

Regards,

Alex

From aliceryhl at google.com  Wed Dec 11 01:48:27 2024
From: aliceryhl at google.com (Alice Ryhl)
Date: Wed, 11 Dec 2024 10:48:27 +0100
Subject: [PATCH v1 5/5] rust: Add warn_on and warn_on_once
In-Reply-To: <20241211.094054.1429837669366274024.fujita.tomonori@gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com>
 <20241210001802.228725-6-fujita.tomonori@gmail.com> <CAH5fLgiShKMGo6AYWM-4S8JK+iDA+tUfz9uxkns82g0nLW--NQ@mail.gmail.com>
 <20241211.094054.1429837669366274024.fujita.tomonori@gmail.com>
Message-ID: <CAH5fLgj9rBOrcQa193RpuA708CFK1ojMqhmiNWF7dbyNFPJcJA@mail.gmail.com>

On Wed, Dec 11, 2024 at 1:41?AM FUJITA Tomonori
<fujita.tomonori at gmail.com> wrote:
>
> On Tue, 10 Dec 2024 10:05:07 +0100
> Alice Ryhl <aliceryhl at google.com> wrote:
>
> > On Tue, Dec 10, 2024 at 1:19?AM FUJITA Tomonori
> > <fujita.tomonori at gmail.com> wrote:
> >>
> >> Add warn_on and warn_on_once macros. Wrapping the C's WARN_* and BUG_*
> >> macros doesn't work so this uses the assembly code exported by the C
> >> side via ARCH_WARN_ASM macro. Like the static branch code, this
> >> generates the assembly code for rust dynamically by using the C
> >> preprocessor.
> >>
> >> file()! macro doesn't work for the Rust inline assembly in the same
> >> way as __FILE__ for the C inline assembly. So the code to handle a
> >> file name is different from the C assembly code (similar to the
> >> arm64/loongarch assembly).
> >>
> >> ASM_REACHABLE definition works in the same way to get objtool's
> >> reachable asm code. The architectures which use objtool (x86 and
> >> loongarch) needs it.
> >>
> >> Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
> >
> >> +#[macro_export]
> >> +#[doc(hidden)]
> >> +#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
> >> +#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
> >
> >> +#[macro_export]
> >> +#[doc(hidden)]
> >> +#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
> >> +#[cfg(any(target_arch = "aarch64", target_arch = "loongarch64"))]
> >
> > What's the reason for this arch-specific code? The file!()/line!()
> > invocations? Could they be passed as an argument to the asm instead so
> > that we don't need target_arch cfgs? I understand that they don't work
> > exactly the same way, but maybe it could still work?
>
> Because of "error: named argument never used" in Rust inline assembly:
>
> All the archs define ARCH_WARN_ASM macro in the same way:
>
> #define ARCH_WARN_ASM(file, line, flags, size)
>
> However, only x86 and risc-v asm code use the size argument. Without
> the cfgs, I'll get the following on arm64/loongarch:
>
> error: named argument never used
>   --> /home/fujita/git/linux-rust/drivers/block/rnull.rs:54:9
>    |
> 54 |         warn_on!(true);
>    |         ^^^^^^^^^^^^^^ named argument never used
>    |
>    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {size} */"`
>    = note: this error originates in the macro `$crate::warn_flags` which comes from the expansion of the macro `warn_on` (in Nightly builds, run with -Z macro-backtrace for more info)
>
>
> Any way to make the compiler to ignore this?

The error message suggests adding an asm comment. Does that not work?

You could even add the comment unconditionally on the Rust side. It's
not like the comment hurts on the platforms that *do* use the size
parameter.

> >> +#[macro_export]
> >> +#[doc(hidden)]
> >> +#[cfg(all(CONFIG_BUG, CONFIG_UML))]
> >> +macro_rules! warn_flags {
> >> +    ($flags:expr) => {
> >> +        // SAFETY: Just an FFI call.
> >> +        unsafe {
> >> +            $crate::bindings::warn_slowpath_fmt(
> >> +                $crate::c_str!(::core::file!()).as_ptr() as *const ::core::ffi::c_char,
> >> +                line!() as i32,
> >> +                $flags as u32,
> >> +                ::core::ptr::null() as *const ::core::ffi::c_char,
> >
> > I wonder if this could be written to utilize Location::caller()
> > instead so that `#[track_caller]` works?
>
> You meant that we could make warn_flags() function instead of macro
> with Location::caller()?
>
> If so, we need to add cfgs to warn_on and warn_on_once because both macro
> and function of warn_flags are necessary?

Well, I'm not sure! I don't know if it's feasible at all, since using
Location::caller() would mean that the file/line is not a compile-time
constant. But if we can, then I think #[track_caller] support would be
nice.

Alice


From wens at csie.org  Wed Dec 11 01:48:54 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 11 Dec 2024 17:48:54 +0800
Subject: [RESEND PATCH] media: dt-bindings: trivial white-space and
 example cleanup
In-Reply-To: <20241211092509.34342-1-krzysztof.kozlowski@linaro.org>
References: <20241211092509.34342-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CAGb2v64bGgum7L2Fcg=FBru7ousCJgSyew7kr7VvYhM+ok_dKA@mail.gmail.com>

On Wed, Dec 11, 2024 at 5:25?PM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> Minor cleanups without funcitonal impact:
>  - There should not be an empty blank line after SPDX tag,
>  - Convention is to indent DTS examples in coding style with 2- or
>    4-space indentation (4 is preferred),
>  - Drop unused labels in DTS examples.
>
> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> Reviewed-by: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>
> ---
>
> Resending second time, because I missed previous Rob's review.
>
> I added now also Bryan's and Heiko's reviews from last resend.
> ---
>  .../media/allwinner,sun50i-h6-vpu-g2.yaml     |  1 -

FWIW,

Acked-by: Chen-Yu Tsai <wens at csie.org>

>  .../bindings/media/amlogic,meson-ir-tx.yaml   |  1 -
>  .../bindings/media/amphion,vpu.yaml           |  1 -
>  .../bindings/media/fsl,imx6ull-pxp.yaml       |  1 -
>  .../media/mediatek,vcodec-decoder.yaml        |  1 -
>  .../media/mediatek,vcodec-encoder.yaml        |  1 -
>  .../media/mediatek,vcodec-subdev-decoder.yaml |  1 -
>  .../media/microchip,sama5d4-vdec.yaml         | 17 ++++----
>  .../bindings/media/nxp,imx8mq-vpu.yaml        | 41 +++++++++----------
>  .../bindings/media/qcom,msm8916-camss.yaml    |  1 -
>  .../bindings/media/qcom,msm8996-camss.yaml    |  1 -
>  .../bindings/media/qcom,sdm660-camss.yaml     |  1 -
>  .../bindings/media/qcom,sdm845-camss.yaml     |  1 -
>  .../bindings/media/qcom,sm8250-camss.yaml     |  1 -
>  .../bindings/media/rockchip,rk3568-vepu.yaml  |  1 -
>  .../bindings/media/rockchip-vpu.yaml          | 29 +++++++------
>  16 files changed, 42 insertions(+), 58 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml b/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
> index a4f06bbdfe49..8ba5177ac631 100644
> --- a/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
> +++ b/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/allwinner,sun50i-h6-vpu-g2.yaml#
> diff --git a/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml b/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
> index 377acce93423..6da8a6aded23 100644
> --- a/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
> +++ b/Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/amlogic,meson-ir-tx.yaml#
> diff --git a/Documentation/devicetree/bindings/media/amphion,vpu.yaml b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
> index 9801de3ed84e..5a920d9e78c7 100644
> --- a/Documentation/devicetree/bindings/media/amphion,vpu.yaml
> +++ b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/amphion,vpu.yaml#
> diff --git a/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml b/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
> index 84a5e894ace4..3f47744459aa 100644
> --- a/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
> +++ b/Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/fsl,imx6ull-pxp.yaml#
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
> index b401c67e3ba0..d726d141a434 100644
> --- a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/mediatek,vcodec-decoder.yaml#
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
> index b45743d0a9ec..110e8f5f1f9e 100644
> --- a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/mediatek,vcodec-encoder.yaml#
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
> index a500a585c692..5865e6f0be89 100644
> --- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#
> diff --git a/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml b/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
> index 59b805ca47c5..ede086d55add 100644
> --- a/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
> +++ b/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/microchip,sama5d4-vdec.yaml#
> @@ -36,12 +35,12 @@ additionalProperties: false
>
>  examples:
>    - |
> -        #include <dt-bindings/clock/at91.h>
> -        #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/clock/at91.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
>
> -        vdec0: vdec at 300000 {
> -                compatible = "microchip,sama5d4-vdec";
> -                reg = <0x00300000 0x100000>;
> -                interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>;
> -                clocks = <&pmc PMC_TYPE_PERIPHERAL 19>;
> -        };
> +    vdec at 300000 {
> +        compatible = "microchip,sama5d4-vdec";
> +        reg = <0x00300000 0x100000>;
> +        interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>;
> +        clocks = <&pmc PMC_TYPE_PERIPHERAL 19>;
> +    };
> diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> index 3d58f02b0c5d..19528262810a 100644
> --- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> +++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#
> @@ -44,26 +43,26 @@ additionalProperties: false
>
>  examples:
>    - |
> -        #include <dt-bindings/clock/imx8mq-clock.h>
> -        #include <dt-bindings/power/imx8mq-power.h>
> -        #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/imx8mq-clock.h>
> +    #include <dt-bindings/power/imx8mq-power.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>
> -        vpu_g1: video-codec at 38300000 {
> -                compatible = "nxp,imx8mq-vpu-g1";
> -                reg = <0x38300000 0x10000>;
> -                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> -                clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
> -                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
> -        };
> +    video-codec at 38300000 {
> +        compatible = "nxp,imx8mq-vpu-g1";
> +        reg = <0x38300000 0x10000>;
> +        interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +        clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
> +        power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
> +    };
>    - |
> -        #include <dt-bindings/clock/imx8mq-clock.h>
> -        #include <dt-bindings/power/imx8mq-power.h>
> -        #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/imx8mq-clock.h>
> +    #include <dt-bindings/power/imx8mq-power.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>
> -        vpu_g2: video-codec at 38300000 {
> -                compatible = "nxp,imx8mq-vpu-g2";
> -                reg = <0x38310000 0x10000>;
> -                interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> -                clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> -                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
> -        };
> +    video-codec at 38300000 {
> +        compatible = "nxp,imx8mq-vpu-g2";
> +        reg = <0x38310000 0x10000>;
> +        interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +        clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +        power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
> +    };
> diff --git a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
> index 9cc0a968a401..3469a43f00d4 100644
> --- a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/qcom,msm8916-camss.yaml#
> diff --git a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
> index 5cb0e337ea6e..644646de338a 100644
> --- a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/qcom,msm8996-camss.yaml#
> diff --git a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
> index 584106e275f6..68d8670557f5 100644
> --- a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/qcom,sdm660-camss.yaml#
> diff --git a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
> index d32daaef1b50..289494f561e5 100644
> --- a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/qcom,sdm845-camss.yaml#
> diff --git a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> index 06db2c1e6079..a372d991e652 100644
> --- a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/qcom,sm8250-camss.yaml#
> diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
> index 947ad699cc5e..d246f5d38427 100644
> --- a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
> +++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/rockchip,rk3568-vepu.yaml#
> diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
> index 719aeb2dc593..8c2501634080 100644
> --- a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
> +++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> -
>  %YAML 1.2
>  ---
>  $id: http://devicetree.org/schemas/media/rockchip-vpu.yaml#
> @@ -92,18 +91,18 @@ additionalProperties: false
>
>  examples:
>    - |
> -        #include <dt-bindings/clock/rk3288-cru.h>
> -        #include <dt-bindings/interrupt-controller/arm-gic.h>
> -        #include <dt-bindings/power/rk3288-power.h>
> +    #include <dt-bindings/clock/rk3288-cru.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/rk3288-power.h>
>
> -        vpu: video-codec at ff9a0000 {
> -                compatible = "rockchip,rk3288-vpu";
> -                reg = <0xff9a0000 0x800>;
> -                interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
> -                             <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> -                interrupt-names = "vepu", "vdpu";
> -                clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
> -                clock-names = "aclk", "hclk";
> -                power-domains = <&power RK3288_PD_VIDEO>;
> -                iommus = <&vpu_mmu>;
> -        };
> +    video-codec at ff9a0000 {
> +        compatible = "rockchip,rk3288-vpu";
> +        reg = <0xff9a0000 0x800>;
> +        interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-names = "vepu", "vdpu";
> +        clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
> +        clock-names = "aclk", "hclk";
> +        power-domains = <&power RK3288_PD_VIDEO>;
> +        iommus = <&vpu_mmu>;
> +    };
> --
> 2.43.0
>
>


From balakrishnan.s at microchip.com  Wed Dec 11 01:46:15 2024
From: balakrishnan.s at microchip.com (Balakrishnan Sambath)
Date: Wed, 11 Dec 2024 15:16:15 +0530
Subject: [PATCH v2] ASoC: dt-bindings: sound: atmel-at91sam9g20ek: convert
 to json-schema
Message-ID: <20241211-sound-atmel-at91sam9g20ek-v2-1-86a0e31e6af9@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>
---
Changes in v2:
- Add missing CODEC pin options to 'atmel,audio-routing' items.
- Drop 'minItems' from 'atmel,audio-routing' since enum defines valid connections.
- Add subsystem tag to subject.
- Add blank line between properties and fix typo.
- Add audio complex description.
- Link to v1: https://lore.kernel.org/lkml/20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b at microchip.com
---
 .../bindings/sound/atmel,at91sam9g20ek-wm8731.yaml | 70 ++++++++++++++++++++++
 .../sound/atmel-at91sam9g20ek-wm8731-audio.txt     | 26 --------
 2 files changed, 70 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 0000000000000000000000000000000000000000..7f6334c96e0b753f83a1714a34514f101c2639c9
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml
@@ -0,0 +1,70 @@
+# 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>
+
+description:
+  The audio complex configuration for Atmel at91sam9g20ek with WM8731 audio codec.
+
+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.
+    items:
+      enum:
+        # Board Connectors
+        - Ext Spk
+        - Int Mic
+
+        # CODEC Pins
+        - LOUT
+        - ROUT
+        - LHPOUT
+        - RHPOUT
+        - LLINEIN
+        - RLINEIN
+        - 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 9c5a9947b64d454a892e1e4148ff06be7c33d6cd..0000000000000000000000000000000000000000
--- 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: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241210-sound-atmel-at91sam9g20ek-b0e9dee4533c

Best regards,
-- 
Balakrishnan Sambath <balakrishnan.s at microchip.com>



From cristian.ciocaltea at collabora.com  Wed Dec 11 01:52:06 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 11:52:06 +0200
Subject: [PATCH v2 0/4] Add support for HDMI1 output on RK3588 SoC
In-Reply-To: <BC29D61C-317D-4F82-AF42-EA3D705B0632@me.com>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
 <BC29D61C-317D-4F82-AF42-EA3D705B0632@me.com>
Message-ID: <a0cf9b40-8ac2-4d6a-a26c-bafa85096440@collabora.com>

Hi Alex,

On 12/11/24 11:42 AM, Alexandre ARNOUD wrote:
> Hello Cristian,
> 
>> On 11 Dec 2024, at 12:06 AM, Cristian Ciocaltea <cristian.ciocaltea at collabora.com> wrote:
>>
>> Changes in v2:
>> - Override hdmi1 pinctrl-0 on rock-5b as it requires hdmim0_tx1_cec
>>  instead of hdmim2_tx1_cec (fixes a pin conflict when enabling
>>  CONFIG_SPI_ROCKCHIP_SFC)
>> - Link to v1: https://lore.kernel.org/r/20241207-rk3588-hdmi1-v1-0-ca3a99b46a40 at collabora.com
>>
>> ---
>> Cristian Ciocaltea (4):
>>      drm/rockchip: dw_hdmi_qp: Add support for RK3588 HDMI1 output
>>      arm64: dts: rockchip: Add PHY node for HDMI1 TX port on RK3588
>>      arm64: dts: rockchip: Add HDMI1 node on RK3588
>>      arm64: dts: rockchip: Enable HDMI1 on rock-5b
>>
>> arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi  |  62 ++++++++++++
>> arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts |  44 ++++++++-
>> drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c  | 119 +++++++++++++++++++-----
>> 3 files changed, 200 insertions(+), 25 deletions(-)
>> ---
>> base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
>> change-id: 20241207-rk3588-hdmi1-704cbb7cd75f
> 
> Tested-by: Alexandre ARNOUD <aarnoud at me.com>
> 
> Works perfectly on Rock-5B, thanks for your work.

Thanks for your quick test report on the series, which helped
identifying the pin conflict issue which I missed initially.

Regards,
Cristian


From qperret at google.com  Wed Dec 11 01:58:07 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 09:58:07 +0000
Subject: [PATCH v2 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <CA+EHjTw4GX3j_ssN-tWnf780xkvyKO5mBN6fnvXeWvQcBDmcNg@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-11-qperret@google.com>
 <CA+EHjTwHSyQ1FJc7axbLNuBxSWpRVE6brb34nO+F59=QRmfQEg@mail.gmail.com>
 <Z1hhHRdpCZcLs046@google.com>
 <CA+EHjTw4GX3j_ssN-tWnf780xkvyKO5mBN6fnvXeWvQcBDmcNg@mail.gmail.com>
Message-ID: <Z1liL3BtoPnSyvlh@google.com>

On Tuesday 10 Dec 2024 at 15:51:01 (+0000), Fuad Tabba wrote:
> On Tue, 10 Dec 2024 at 15:41, Quentin Perret <qperret at google.com> wrote:
> > > Initially I thought the comment was related to the warning below,
> > > which confused me.
> >
> > It actually is about the warning below :-)
> >
> > > Now I think what you're trying to say is that we'll
> > > allow the share, and the (unrelated to the comment) warning is to
> > > ensure that the PKVM_PAGE_SHARED_OWNED is consistent with the share
> > > count.
> >
> > So, the only case where the host should ever attempt do use
> > __pkvm_host_share_guest() on a page that is already shared is for a page
> > already shared *with an np-guest*. The page->host_share_guest_count being
> > elevated is the easiest way to check that the page is indeed in that
> > state, hence the warning.
> >
> > If for example the host was trying to share with an np-guest a page that
> > is currently shared with the hypervisor, that check would fail. We can
> > discuss whether or not we would want to allow it, but for now there is
> > strictly no need for it so I went with the restrictive option. We can
> > relax that constraint later if need be.
> >
> > > I think what you should have here, which would work better with the
> > > comment, is something like:
> > >
> > >                 /* Only host to np-guest multi-sharing is tolerated */
> > > +               if (pkvm_hyp_vcpu_is_protected(vcpu))
> > > +                       return -EPERM;
> > >
> > > That would even make the comment unnecessary.
> >
> > I would prefer not adding this here, handle___pkvm_host_share_guest() in
> > hyp-main.c already does that for us.
> 
> I understand now, and I agree that an additional check isn't
> necessary. Could you clarify the comment though? It's the word "only"
> that threw me off, since to me it implied that the check was enforcing
> the word "only". Maybe:
> 
> >                 /* Tolerate host to np-guest multi-sharing. */

I guess 'only' is somewhat important, it is the _only_ type of
multi-sharing that we allow and the check enforces precisely that. The
WARN_ON() will be triggered for any other type of multi-sharing, so we
are really checking that _only_ np-guest multi-sharing goes through.

Perhaps the confusing part is that the code as-is relies on WARN_ON()
being fatal for the enforcement. Would it help if I changed the 'break'
statement right after to 'fallthrough' so we proceed to return -EPERM?
In practice we won't return anything as the hypervisor will panic, but
I presume it is better from a logic perspective.

Cheers,
Quentin


From qperret at google.com  Wed Dec 11 02:03:24 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 10:03:24 +0000
Subject: [PATCH v2 16/18] KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
In-Reply-To: <CA+EHjTw_e_q5TFkgxvVDKxwj-C5S0Hd1OfVO4_FitrB8_J2Rpw@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-17-qperret@google.com>
 <CA+EHjTw_e_q5TFkgxvVDKxwj-C5S0Hd1OfVO4_FitrB8_J2Rpw@mail.gmail.com>
Message-ID: <Z1ljbPFsUdUC8AD3@google.com>

On Tuesday 10 Dec 2024 at 15:23:02 (+0000), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
> >
> > Introduce a new hypercall to flush the TLBs of non-protected guests. The
> > host kernel will be responsible for issuing this hypercall after changing
> > stage-2 permissions using the __pkvm_host_relax_guest_perms() or
> > __pkvm_host_wrprotect_guest() paths. This is left under the host's
> > responsibility for performance reasons.
> >
> > Note however that the TLB maintenance for all *unmap* operations still
> > remains entirely under the hypervisor's responsibility for security
> > reasons -- an unmapped page may be donated to another entity, so a stale
> > TLB entry could be used to leak private data.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_asm.h   |  1 +
> >  arch/arm64/kvm/hyp/nvhe/hyp-main.c | 17 +++++++++++++++++
> >  2 files changed, 18 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > index 6178e12a0dbc..df6237d0459c 100644
> > --- a/arch/arm64/include/asm/kvm_asm.h
> > +++ b/arch/arm64/include/asm/kvm_asm.h
> > @@ -87,6 +87,7 @@ enum __kvm_host_smccc_func {
> >         __KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
> >         __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
> >         __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
> > +       __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
> >  };
> >
> >  #define DECLARE_KVM_VHE_SYM(sym)       extern char sym[]
> > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > index de0012a75827..219d7fb850ec 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > @@ -398,6 +398,22 @@ static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
> >         __kvm_tlb_flush_vmid(kern_hyp_va(mmu));
> >  }
> >
> > +static void handle___pkvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
> > +{
> > +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> > +       struct pkvm_hyp_vm *hyp_vm;
> > +
> > +       if (!is_protected_kvm_enabled())
> > +               return;
> > +
> > +       hyp_vm = get_pkvm_hyp_vm(handle);
> > +       if (!hyp_vm)
> > +               return;
> > +
> > +       __kvm_tlb_flush_vmid(&hyp_vm->kvm.arch.mmu);
> > +       put_pkvm_hyp_vm(hyp_vm);
> > +}
> 
> Since this is practically the same as kvm_tlb_flush_vmid(), does it
> make sense to modify that instead (handle___kvm_tlb_flush_vmid()) to
> do the right thing depending on whether pkvm is enabled? Thinking as
> well for the future in case we want to support the rest of the
> kvm_tlb_flush_vmid_*().

I considered it, but the two implementations want different arguments --
pkvm wants the handle while standard KVM uses the kvm struct address
directly. I had an implementation at some point that multiplexed the
implementations on a single HVC (we'd interpret the arguments
differently depending on pKVM being enabled or not) but that felt more
error prone than simply having two HVCs.

Happy to reconsider if we can find a good way to make it work though.


From tabba at google.com  Wed Dec 11 02:07:16 2024
From: tabba at google.com (Fuad Tabba)
Date: Wed, 11 Dec 2024 10:07:16 +0000
Subject: [PATCH v2 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <Z1liL3BtoPnSyvlh@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-11-qperret@google.com>
 <CA+EHjTwHSyQ1FJc7axbLNuBxSWpRVE6brb34nO+F59=QRmfQEg@mail.gmail.com>
 <Z1hhHRdpCZcLs046@google.com> <CA+EHjTw4GX3j_ssN-tWnf780xkvyKO5mBN6fnvXeWvQcBDmcNg@mail.gmail.com>
 <Z1liL3BtoPnSyvlh@google.com>
Message-ID: <CA+EHjTw+3oAcp3ujjPmbcu42=95nw8WA=rZHYFL91ZK_Wfs_vA@mail.gmail.com>

On Wed, 11 Dec 2024 at 09:58, Quentin Perret <qperret at google.com> wrote:
>
> On Tuesday 10 Dec 2024 at 15:51:01 (+0000), Fuad Tabba wrote:
> > On Tue, 10 Dec 2024 at 15:41, Quentin Perret <qperret at google.com> wrote:
> > > > Initially I thought the comment was related to the warning below,
> > > > which confused me.
> > >
> > > It actually is about the warning below :-)
> > >
> > > > Now I think what you're trying to say is that we'll
> > > > allow the share, and the (unrelated to the comment) warning is to
> > > > ensure that the PKVM_PAGE_SHARED_OWNED is consistent with the share
> > > > count.
> > >
> > > So, the only case where the host should ever attempt do use
> > > __pkvm_host_share_guest() on a page that is already shared is for a page
> > > already shared *with an np-guest*. The page->host_share_guest_count being
> > > elevated is the easiest way to check that the page is indeed in that
> > > state, hence the warning.
> > >
> > > If for example the host was trying to share with an np-guest a page that
> > > is currently shared with the hypervisor, that check would fail. We can
> > > discuss whether or not we would want to allow it, but for now there is
> > > strictly no need for it so I went with the restrictive option. We can
> > > relax that constraint later if need be.
> > >
> > > > I think what you should have here, which would work better with the
> > > > comment, is something like:
> > > >
> > > >                 /* Only host to np-guest multi-sharing is tolerated */
> > > > +               if (pkvm_hyp_vcpu_is_protected(vcpu))
> > > > +                       return -EPERM;
> > > >
> > > > That would even make the comment unnecessary.
> > >
> > > I would prefer not adding this here, handle___pkvm_host_share_guest() in
> > > hyp-main.c already does that for us.
> >
> > I understand now, and I agree that an additional check isn't
> > necessary. Could you clarify the comment though? It's the word "only"
> > that threw me off, since to me it implied that the check was enforcing
> > the word "only". Maybe:
> >
> > >                 /* Tolerate host to np-guest multi-sharing. */
>
> I guess 'only' is somewhat important, it is the _only_ type of
> multi-sharing that we allow and the check enforces precisely that. The
> WARN_ON() will be triggered for any other type of multi-sharing, so we
> are really checking that _only_ np-guest multi-sharing goes through.
>
> Perhaps the confusing part is that the code as-is relies on WARN_ON()
> being fatal for the enforcement. Would it help if I changed the 'break'
> statement right after to 'fallthrough' so we proceed to return -EPERM?
> In practice we won't return anything as the hypervisor will panic, but
> I presume it is better from a logic perspective.

It would, but then we wouldn't be tolerating np-guest multisharing,
but like you said, it's not like we're tolerating it now anyway.

I wonder if it would be better simply not to allow multisharing at all for now.

Cheers,
/fuad


> Cheers,
> Quentin


From tabba at google.com  Wed Dec 11 02:11:17 2024
From: tabba at google.com (Fuad Tabba)
Date: Wed, 11 Dec 2024 10:11:17 +0000
Subject: [PATCH v2 15/18] KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
In-Reply-To: <Z1iaof2DgZfZxc4l@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-16-qperret@google.com>
 <CA+EHjTzOjwNyUkS5_zSUiAbiCauLKKgkKU6TM_-+Wsh9A0FdRQ@mail.gmail.com> <Z1iaof2DgZfZxc4l@google.com>
Message-ID: <CA+EHjTyzh_tqH-M4zSDEQ9meK_W_c-sQDvJ6H4kBd4e_MCmLfA@mail.gmail.com>

Hi Quentin,

On Tue, 10 Dec 2024 at 19:46, Quentin Perret <qperret at google.com> wrote:
>
> On Tuesday 10 Dec 2024 at 15:14:03 (+0000), Fuad Tabba wrote:
> > > +int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu)
> > > +{
> > > +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> > > +       u64 ipa = hyp_pfn_to_phys(gfn);
> > > +       u64 phys;
> > > +       int ret;
> > > +
> > > +       host_lock_component();
> > > +       guest_lock_component(vm);
> > > +
> > > +       ret = __check_host_unshare_guest(vm, &phys, ipa);
> >
> > While I'm bikeshedding some more, does the name
> > __check_host_unshare_guest() make sense? Should it be something like
> > __check_host_changeperm_guest(), or something along those lines? (feel
> > free to ignore this :) )
>
> I understand the comment, but not a huge fan of 'changeperm' as that
> sounds like we're only allowing permission changes while we use this
> all over the place. Maybe __check_host_is_shared_guest()? Naming is
> hard, so happy to take suggestions :-)

I've gone and done it now :) I almost like that, it's the *is* part I
don't like since it implied a boolean return. Maybe just
__check_host_shared_guest(), no is?

Cheers,
/fuad


From cristian.ciocaltea at collabora.com  Wed Dec 11 02:15:06 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 12:15:06 +0200
Subject: [PATCH v2 2/5] drm/rockchip: vop2: Drop unnecessary if_pixclk_rate
 computation
In-Reply-To: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
Message-ID: <20241211-vop2-hdmi0-disp-modes-v2-2-471cf5001e45@collabora.com>

The if_pixclk_rate variable is not being used outside of the if-block in
rk3588_calc_cru_cfg(), hence move the superfluous assignment from the
first branch to the inner comment-block.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 9873172e3fd331f4457fb70c5416dad7af9e3536..8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1695,8 +1695,8 @@ static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
 			K = 2;
 		}
 
-		if_pixclk_rate = (dclk_core_rate << 1) / K;
 		/*
+		 * if_pixclk_rate = (dclk_core_rate << 1) / K;
 		 * if_dclk_rate = dclk_core_rate / K;
 		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
 		 * *if_dclk_div = dclk_rate / if_dclk_rate;

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Wed Dec 11 02:15:07 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 12:15:07 +0200
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes handling
 on RK3588 HDMI0
In-Reply-To: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
Message-ID: <20241211-vop2-hdmi0-disp-modes-v2-3-471cf5001e45@collabora.com>

The RK3588 specific implementation is currently quite limited in terms
of handling the full range of display modes supported by the connected
screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
few of them.

Additionally, it doesn't cope well with non-integer refresh rates like
59.94, 29.97, 23.98, etc.

Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
all display modes up to 4K at 60Hz.

Tested-by: FUKAUMI Naoki <naoki at radxa.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -158,6 +158,7 @@ struct vop2_video_port {
 	struct drm_crtc crtc;
 	struct vop2 *vop2;
 	struct clk *dclk;
+	struct clk *dclk_src;
 	unsigned int id;
 	const struct vop2_video_port_data *data;
 
@@ -212,6 +213,7 @@ struct vop2 {
 	struct clk *hclk;
 	struct clk *aclk;
 	struct clk *pclk;
+	struct clk *pll_hdmiphy0;
 
 	/* optional internal rgb encoder */
 	struct rockchip_rgb *rgb;
@@ -220,6 +222,8 @@ struct vop2 {
 	struct vop2_win win[];
 };
 
+#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
+
 #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
 					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
 
@@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
 
 	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
 
+	if (vp->dclk_src)
+		clk_set_parent(vp->dclk, vp->dclk_src);
+
 	clk_disable_unprepare(vp->dclk);
 
 	vop2->enable_count--;
@@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
 
 	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
 
+	/*
+	 * Switch to HDMI PHY PLL as DCLK source for display modes up
+	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
+	 */
+	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
+		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
+			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
+
+			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
+				if (!vp->dclk_src)
+					vp->dclk_src = clk_get_parent(vp->dclk);
+
+				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
+				if (ret < 0)
+					drm_warn(vop2->drm,
+						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
+				break;
+			}
+		}
+	}
+
 	clk_set_rate(vp->dclk, clock);
 
 	vop2_post_config(crtc);
@@ -3167,6 +3195,12 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 		return PTR_ERR(vop2->pclk);
 	}
 
+	vop2->pll_hdmiphy0 = devm_clk_get_optional(vop2->dev, "pll_hdmiphy0");
+	if (IS_ERR(vop2->pll_hdmiphy0)) {
+		drm_err(vop2->drm, "failed to get pll_hdmiphy0\n");
+		return PTR_ERR(vop2->pll_hdmiphy0);
+	}
+
 	vop2->irq = platform_get_irq(pdev, 0);
 	if (vop2->irq < 0) {
 		drm_err(vop2->drm, "cannot find irq for vop2\n");

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Wed Dec 11 02:15:08 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 12:15:08 +0200
Subject: [PATCH v2 4/5] arm64: dts: rockchip: Enable HDMI0 PHY clk provider
 on RK3588
In-Reply-To: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
Message-ID: <20241211-vop2-hdmi0-disp-modes-v2-4-471cf5001e45@collabora.com>

Since commit c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock
provider support"), the HDMI PHY PLL can be used as an alternative and
more accurate pixel clock source for VOP2 to improve display modes
handling on RK3588 SoC.

Add the missing #clock-cells property to allow using the clock provider
functionality of HDMI0 PHY.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index a337f3fb8377e4a3a200d4d3a3773a237de2bd6e..22462e86f48027ab7c5e270f2fa04df7afcc1d24 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -2811,6 +2811,7 @@ hdptxphy_hdmi0: phy at fed60000 {
 		reg = <0x0 0xfed60000 0x0 0x2000>;
 		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
 		clock-names = "ref", "apb";
+		#clock-cells = <0>;
 		#phy-cells = <0>;
 		resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
 			 <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Wed Dec 11 02:15:09 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 12:15:09 +0200
Subject: [PATCH v2 5/5] arm64: dts: rockchip: Add HDMI0 PHY PLL clock
 source to VOP2 on RK3588
In-Reply-To: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
Message-ID: <20241211-vop2-hdmi0-disp-modes-v2-5-471cf5001e45@collabora.com>

VOP2 on RK3588 is able to use the HDMI PHY PLL as an alternative and
more accurate pixel clock source to improve handling of display modes up
to 4K at 60Hz on video ports 0, 1 and 2.

For now only HDMI0 output is supported, hence add the related PLL clock.

Tested-by: FUKAUMI Naoki <naoki at radxa.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 22462e86f48027ab7c5e270f2fa04df7afcc1d24..d07be2a81f28b4cbfe314992c662d8cfb3d3d344 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1262,14 +1262,16 @@ vop: vop at fdd90000 {
 			 <&cru DCLK_VOP1>,
 			 <&cru DCLK_VOP2>,
 			 <&cru DCLK_VOP3>,
-			 <&cru PCLK_VOP_ROOT>;
+			 <&cru PCLK_VOP_ROOT>,
+			 <&hdptxphy_hdmi0>;
 		clock-names = "aclk",
 			      "hclk",
 			      "dclk_vp0",
 			      "dclk_vp1",
 			      "dclk_vp2",
 			      "dclk_vp3",
-			      "pclk_vop";
+			      "pclk_vop",
+			      "pll_hdmiphy0";
 		iommus = <&vop_mmu>;
 		power-domains = <&power RK3588_PD_VOP>;
 		rockchip,grf = <&sys_grf>;

-- 
2.47.0



From qperret at google.com  Wed Dec 11 02:18:44 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 10:18:44 +0000
Subject: [PATCH v2 15/18] KVM: arm64: Introduce
 __pkvm_host_mkyoung_guest()
In-Reply-To: <CA+EHjTyzh_tqH-M4zSDEQ9meK_W_c-sQDvJ6H4kBd4e_MCmLfA@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-16-qperret@google.com>
 <CA+EHjTzOjwNyUkS5_zSUiAbiCauLKKgkKU6TM_-+Wsh9A0FdRQ@mail.gmail.com>
 <Z1iaof2DgZfZxc4l@google.com>
 <CA+EHjTyzh_tqH-M4zSDEQ9meK_W_c-sQDvJ6H4kBd4e_MCmLfA@mail.gmail.com>
Message-ID: <Z1lnBDBNq_PKKN4l@google.com>

On Wednesday 11 Dec 2024 at 10:11:17 (+0000), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Tue, 10 Dec 2024 at 19:46, Quentin Perret <qperret at google.com> wrote:
> >
> > On Tuesday 10 Dec 2024 at 15:14:03 (+0000), Fuad Tabba wrote:
> > > > +int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu)
> > > > +{
> > > > +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> > > > +       u64 ipa = hyp_pfn_to_phys(gfn);
> > > > +       u64 phys;
> > > > +       int ret;
> > > > +
> > > > +       host_lock_component();
> > > > +       guest_lock_component(vm);
> > > > +
> > > > +       ret = __check_host_unshare_guest(vm, &phys, ipa);
> > >
> > > While I'm bikeshedding some more, does the name
> > > __check_host_unshare_guest() make sense? Should it be something like
> > > __check_host_changeperm_guest(), or something along those lines? (feel
> > > free to ignore this :) )
> >
> > I understand the comment, but not a huge fan of 'changeperm' as that
> > sounds like we're only allowing permission changes while we use this
> > all over the place. Maybe __check_host_is_shared_guest()? Naming is
> > hard, so happy to take suggestions :-)
> 
> I've gone and done it now :) I almost like that, it's the *is* part I
> don't like since it implied a boolean return. Maybe just
> __check_host_shared_guest(), no is?

Deal!

Cheers,
Quentin


From suzuki.poulose at arm.com  Wed Dec 11 02:20:02 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 11 Dec 2024 10:20:02 +0000
Subject: [PATCH] coresight: Drop atomics in connection refcounts
In-Reply-To: <20241128121414.2425119-1-james.clark@linaro.org>
References: <20241128121414.2425119-1-james.clark@linaro.org>
Message-ID: <173391229097.561442.2664501227957186728.b4-ty@arm.com>

On Thu, 28 Nov 2024 12:14:14 +0000, James Clark wrote:
> These belong to the device being enabled or disabled and are only ever
> used inside the device's spinlock. Remove the atomics to not imply that
> there are any other concurrent accesses.
> 
> If atomics were necessary I don't think they would have been enough
> anyway. There would be nothing to prevent an enable or disable running
> concurrently if not for the spinlock.
> 
> [...]

Applied, thanks!

[1/1] coresight: Drop atomics in connection refcounts
      https://git.kernel.org/coresight/c/5aec7c065fba0c56d6c1ea5d629395210f174be8

Best regards,
-- 
Suzuki K Poulose <suzuki.poulose at arm.com>


From suzuki.poulose at arm.com  Wed Dec 11 02:20:47 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 11 Dec 2024 10:20:47 +0000
Subject: [PATCH v7 0/3] coresight: Add static trace id support
In-Reply-To: <20241121062829.11571-1-quic_jinlmao@quicinc.com>
References: <20241121062829.11571-1-quic_jinlmao@quicinc.com>
Message-ID: <173391229097.561442.14812407436677697542.b4-ty@arm.com>

On Thu, 21 Nov 2024 14:28:26 +0800, Mao Jinlong wrote:
> Some HW has static trace id which cannot be changed via
> software programming. For this case, configure the trace id
> in device tree with "arm,static-trace-id = <xxx>", and
> call coresight_trace_id_get_static_system_id with the trace id value
> in device probe function. The id will be reserved for the HW
> all the time if the device is probed.
> 
> [...]

Applied, with minor fixups. thanks!

[1/3] dt-bindings: arm: Add arm,static-trace-id for coresight dummy source
      https://git.kernel.org/coresight/c/d0a10da78cbfabcbc2eda87ac238bc03bb2b2c81
[2/3] coresight: Add support to get static id for system trace sources
      https://git.kernel.org/coresight/c/fd9b7e8e9fbc23d69fa4accc881dea2cf13a2e2e
[3/3] coresight: dummy: Add static trace id support for dummy source
      https://git.kernel.org/coresight/c/f7d7454607cf863cc860e201636117e242d45fe0

Best regards,
-- 
Suzuki K Poulose <suzuki.poulose at arm.com>


From tabba at google.com  Wed Dec 11 02:21:20 2024
From: tabba at google.com (Fuad Tabba)
Date: Wed, 11 Dec 2024 10:21:20 +0000
Subject: [PATCH v2 16/18] KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
In-Reply-To: <Z1ljbPFsUdUC8AD3@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-17-qperret@google.com>
 <CA+EHjTw_e_q5TFkgxvVDKxwj-C5S0Hd1OfVO4_FitrB8_J2Rpw@mail.gmail.com> <Z1ljbPFsUdUC8AD3@google.com>
Message-ID: <CA+EHjTwnZ8S4LUgmJ40g8juHh5OneWUWtJDDCnn03Xw0MvQ-=A@mail.gmail.com>

Hi Quentin,

On Wed, 11 Dec 2024 at 10:03, Quentin Perret <qperret at google.com> wrote:
>
> On Tuesday 10 Dec 2024 at 15:23:02 (+0000), Fuad Tabba wrote:
> > Hi Quentin,
> >
> > On Tue, 3 Dec 2024 at 10:38, Quentin Perret <qperret at google.com> wrote:
> > >
> > > Introduce a new hypercall to flush the TLBs of non-protected guests. The
> > > host kernel will be responsible for issuing this hypercall after changing
> > > stage-2 permissions using the __pkvm_host_relax_guest_perms() or
> > > __pkvm_host_wrprotect_guest() paths. This is left under the host's
> > > responsibility for performance reasons.
> > >
> > > Note however that the TLB maintenance for all *unmap* operations still
> > > remains entirely under the hypervisor's responsibility for security
> > > reasons -- an unmapped page may be donated to another entity, so a stale
> > > TLB entry could be used to leak private data.
> > >
> > > Signed-off-by: Quentin Perret <qperret at google.com>
> > > ---
> > >  arch/arm64/include/asm/kvm_asm.h   |  1 +
> > >  arch/arm64/kvm/hyp/nvhe/hyp-main.c | 17 +++++++++++++++++
> > >  2 files changed, 18 insertions(+)
> > >
> > > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > > index 6178e12a0dbc..df6237d0459c 100644
> > > --- a/arch/arm64/include/asm/kvm_asm.h
> > > +++ b/arch/arm64/include/asm/kvm_asm.h
> > > @@ -87,6 +87,7 @@ enum __kvm_host_smccc_func {
> > >         __KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
> > >         __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
> > >         __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
> > > +       __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
> > >  };
> > >
> > >  #define DECLARE_KVM_VHE_SYM(sym)       extern char sym[]
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > > index de0012a75827..219d7fb850ec 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > > @@ -398,6 +398,22 @@ static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
> > >         __kvm_tlb_flush_vmid(kern_hyp_va(mmu));
> > >  }
> > >
> > > +static void handle___pkvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
> > > +{
> > > +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> > > +       struct pkvm_hyp_vm *hyp_vm;
> > > +
> > > +       if (!is_protected_kvm_enabled())
> > > +               return;
> > > +
> > > +       hyp_vm = get_pkvm_hyp_vm(handle);
> > > +       if (!hyp_vm)
> > > +               return;
> > > +
> > > +       __kvm_tlb_flush_vmid(&hyp_vm->kvm.arch.mmu);
> > > +       put_pkvm_hyp_vm(hyp_vm);
> > > +}
> >
> > Since this is practically the same as kvm_tlb_flush_vmid(), does it
> > make sense to modify that instead (handle___kvm_tlb_flush_vmid()) to
> > do the right thing depending on whether pkvm is enabled? Thinking as
> > well for the future in case we want to support the rest of the
> > kvm_tlb_flush_vmid_*().
>
> I considered it, but the two implementations want different arguments --
> pkvm wants the handle while standard KVM uses the kvm struct address
> directly. I had an implementation at some point that multiplexed the
> implementations on a single HVC (we'd interpret the arguments
> differently depending on pKVM being enabled or not) but that felt more
> error prone than simply having two HVCs.
>
> Happy to reconsider if we can find a good way to make it work though.

I don't have a strong opinion about this. I think that for now, since
it's only this function, it's probably fine. That said, the
multiplexing is (as of patch 18, which I haven't reviewed yet) is just
lifted higher up to the host kernel, albeit with fewer parameters to
wiggle around.

To summarize, I think we can worry about it if/once we need the other
tlb_flush_* variants.

Cheers,
/fuad


From qperret at google.com  Wed Dec 11 02:21:53 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 10:21:53 +0000
Subject: [PATCH v2 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <Z1lmG-3KnOZrOCCa@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-11-qperret@google.com>
 <CA+EHjTwHSyQ1FJc7axbLNuBxSWpRVE6brb34nO+F59=QRmfQEg@mail.gmail.com>
 <Z1hhHRdpCZcLs046@google.com>
 <CA+EHjTw4GX3j_ssN-tWnf780xkvyKO5mBN6fnvXeWvQcBDmcNg@mail.gmail.com>
 <Z1liL3BtoPnSyvlh@google.com>
 <CA+EHjTw+3oAcp3ujjPmbcu42=95nw8WA=rZHYFL91ZK_Wfs_vA@mail.gmail.com>
 <Z1lmG-3KnOZrOCCa@google.com>
Message-ID: <Z1lnwZPrx9GzgFCG@google.com>

On Wednesday 11 Dec 2024 at 10:14:51 (+0000), Quentin Perret wrote:
> On Wednesday 11 Dec 2024 at 10:07:16 (+0000), Fuad Tabba wrote:
> > On Wed, 11 Dec 2024 at 09:58, Quentin Perret <qperret at google.com> wrote:
> > >
> > > On Tuesday 10 Dec 2024 at 15:51:01 (+0000), Fuad Tabba wrote:
> > > > On Tue, 10 Dec 2024 at 15:41, Quentin Perret <qperret at google.com> wrote:
> > > > > > Initially I thought the comment was related to the warning below,
> > > > > > which confused me.
> > > > >
> > > > > It actually is about the warning below :-)
> > > > >
> > > > > > Now I think what you're trying to say is that we'll
> > > > > > allow the share, and the (unrelated to the comment) warning is to
> > > > > > ensure that the PKVM_PAGE_SHARED_OWNED is consistent with the share
> > > > > > count.
> > > > >
> > > > > So, the only case where the host should ever attempt do use
> > > > > __pkvm_host_share_guest() on a page that is already shared is for a page
> > > > > already shared *with an np-guest*. The page->host_share_guest_count being
> > > > > elevated is the easiest way to check that the page is indeed in that
> > > > > state, hence the warning.
> > > > >
> > > > > If for example the host was trying to share with an np-guest a page that
> > > > > is currently shared with the hypervisor, that check would fail. We can
> > > > > discuss whether or not we would want to allow it, but for now there is
> > > > > strictly no need for it so I went with the restrictive option. We can
> > > > > relax that constraint later if need be.
> > > > >
> > > > > > I think what you should have here, which would work better with the
> > > > > > comment, is something like:
> > > > > >
> > > > > >                 /* Only host to np-guest multi-sharing is tolerated */
> > > > > > +               if (pkvm_hyp_vcpu_is_protected(vcpu))
> > > > > > +                       return -EPERM;
> > > > > >
> > > > > > That would even make the comment unnecessary.
> > > > >
> > > > > I would prefer not adding this here, handle___pkvm_host_share_guest() in
> > > > > hyp-main.c already does that for us.
> > > >
> > > > I understand now, and I agree that an additional check isn't
> > > > necessary. Could you clarify the comment though? It's the word "only"
> > > > that threw me off, since to me it implied that the check was enforcing
> > > > the word "only". Maybe:
> > > >
> > > > >                 /* Tolerate host to np-guest multi-sharing. */
> > >
> > > I guess 'only' is somewhat important, it is the _only_ type of
> > > multi-sharing that we allow and the check enforces precisely that. The
> > > WARN_ON() will be triggered for any other type of multi-sharing, so we
> > > are really checking that _only_ np-guest multi-sharing goes through.
> > >
> > > Perhaps the confusing part is that the code as-is relies on WARN_ON()
> > > being fatal for the enforcement. Would it help if I changed the 'break'
> > > statement right after to 'fallthrough' so we proceed to return -EPERM?
> > > In practice we won't return anything as the hypervisor will panic, but
> > > I presume it is better from a logic perspective.
> > 
> > It would, but then we wouldn't be tolerating np-guest multisharing,
> > but like you said, it's not like we're tolerating it now anyway.
> > 
> > I wonder if it would be better simply not to allow multisharing at all for now.
> 
> That would mean turning off MMU notifiers in the host and taking
> long-term GUP pins on np-guest pages I think. Multi-sharing can be
> caused by many things, KSM, the zero page ... so we we'd need to turn
> all of that off (IOW, no MMU notifiers).
> 
> That's more or less the status quo in Android, but I vote for not going
> down that path upstream. pKVM should ideally be transparent for np-guest
> support if at all possible.

And to clarify my suggestion above, we should fallthrough IFF
host_share_guest_count is 0, but break otherwise to retain multi-sharing
support. So it's not a simple s/break/fallthrough change, that needs a
tiny bit of added logic.


From suzuki.poulose at arm.com  Wed Dec 11 02:22:41 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 11 Dec 2024 10:22:41 +0000
Subject: [PATCH] coresight: Fix dsb_mode_store() unsigned val is never less than zero
In-Reply-To: <122503017ada249fbf12be3fa4ee6ccb8f8c78cc.1732156624.git.xiaopei01@kylinos.cn>
References: <202410150702.UaZ7kvet-lkp@intel.com> <122503017ada249fbf12be3fa4ee6ccb8f8c78cc.1732156624.git.xiaopei01@kylinos.cn>
Message-ID: <173391254211.561817.4532591708453721807.b4-ty@arm.com>

On Thu, 21 Nov 2024 10:40:03 +0800, Pei Xiao wrote:
> dsb_mode_store() warn: unsigned 'val' is never less than zero.
> 
> 

Applied, thanks!

[1/1] coresight: Fix dsb_mode_store() unsigned val is never less than zero
      https://git.kernel.org/coresight/c/d4276259f3a57131291d879b53fc05863c6b59fa

Best regards,
-- 
Suzuki K Poulose <suzuki.poulose at arm.com>


From brgl at bgdev.pl  Wed Dec 11 02:23:35 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Wed, 11 Dec 2024 11:23:35 +0100
Subject: [PATCH 1/3] i2c: davinci: kill platform data
Message-ID: <20241211102337.37956-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

There are no more board file users of this driver. The platform data
structure is only used internally. Two of the four fields it stores are
not used at all anymore. Pull the remainder into the driver data struct
and shrink code by removing parts that are now dead code.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/i2c/busses/i2c-davinci.c          | 80 +++++------------------
 include/linux/platform_data/i2c-davinci.h | 26 --------
 2 files changed, 17 insertions(+), 89 deletions(-)
 delete mode 100644 include/linux/platform_data/i2c-davinci.h

diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 71dc0a6688b7..4b499931fdfd 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -26,7 +26,6 @@
 #include <linux/cpufreq.h>
 #include <linux/gpio/consumer.h>
 #include <linux/of.h>
-#include <linux/platform_data/i2c-davinci.h>
 #include <linux/pm_runtime.h>
 
 /* ----- global defines ----------------------------------------------- */
@@ -117,6 +116,8 @@
 /* timeout for pm runtime autosuspend */
 #define DAVINCI_I2C_PM_TIMEOUT	1000	/* ms */
 
+#define DAVINCI_I2C_DEFAULT_BUS_FREQ	100
+
 struct davinci_i2c_dev {
 	struct device           *dev;
 	void __iomem		*base;
@@ -132,13 +133,10 @@ struct davinci_i2c_dev {
 #ifdef CONFIG_CPU_FREQ
 	struct notifier_block	freq_transition;
 #endif
-	struct davinci_i2c_platform_data *pdata;
-};
-
-/* default platform data to use if not supplied in the platform_device */
-static struct davinci_i2c_platform_data davinci_i2c_platform_data_default = {
-	.bus_freq	= 100,
-	.bus_delay	= 0,
+	/* standard bus frequency (kHz) */
+	unsigned int		bus_freq;
+	/* Chip has a ICPFUNC register */
+	bool			has_pfunc;
 };
 
 static inline void davinci_i2c_write_reg(struct davinci_i2c_dev *i2c_dev,
@@ -168,7 +166,6 @@ static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
 
 static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
 {
-	struct davinci_i2c_platform_data *pdata = dev->pdata;
 	u16 psc;
 	u32 clk;
 	u32 d;
@@ -212,16 +209,16 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
 	if (of_node && of_device_is_compatible(of_node, "ti,keystone-i2c"))
 		d = 6;
 
-	clk = ((input_clock / (psc + 1)) / (pdata->bus_freq * 1000));
+	clk = ((input_clock / (psc + 1)) / (dev->bus_freq * 1000));
 	/* Avoid driving the bus too fast because of rounding errors above */
-	if (input_clock / (psc + 1) / clk > pdata->bus_freq * 1000)
+	if (input_clock / (psc + 1) / clk > dev->bus_freq * 1000)
 		clk++;
 	/*
 	 * According to I2C-BUS Spec 2.1, in FAST-MODE LOW period should be at
 	 * least 1.3uS, which is not the case with 50% duty cycle. Driving HIGH
 	 * to LOW ratio as 1 to 2 is more safe.
 	 */
-	if (pdata->bus_freq > 100)
+	if (dev->bus_freq > 100)
 		clkl = (clk << 1) / 3;
 	else
 		clkl = (clk >> 1);
@@ -255,8 +252,6 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
  */
 static int i2c_davinci_init(struct davinci_i2c_dev *dev)
 {
-	struct davinci_i2c_platform_data *pdata = dev->pdata;
-
 	/* put I2C into reset */
 	davinci_i2c_reset_ctrl(dev, 0);
 
@@ -274,8 +269,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
 		davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKL_REG));
 	dev_dbg(dev->dev, "CLKH = %d\n",
 		davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKH_REG));
-	dev_dbg(dev->dev, "bus_freq = %dkHz, bus_delay = %d\n",
-		pdata->bus_freq, pdata->bus_delay);
+	dev_dbg(dev->dev, "bus_freq = %dkHz\n", dev->bus_freq);
 
 
 	/* Take the I2C module out of reset: */
@@ -309,12 +303,6 @@ static void davinci_i2c_unprepare_recovery(struct i2c_adapter *adap)
 	i2c_davinci_init(dev);
 }
 
-static struct i2c_bus_recovery_info davinci_i2c_gpio_recovery_info = {
-	.recover_bus = i2c_generic_scl_recovery,
-	.prepare_recovery = davinci_i2c_prepare_recovery,
-	.unprepare_recovery = davinci_i2c_unprepare_recovery,
-};
-
 static void davinci_i2c_set_scl(struct i2c_adapter *adap, int val)
 {
 	struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
@@ -414,7 +402,6 @@ static int
 i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 {
 	struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
-	struct davinci_i2c_platform_data *pdata = dev->pdata;
 	u32 flag;
 	u16 w;
 	unsigned long time_left;
@@ -424,10 +411,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 		return -EADDRNOTAVAIL;
 	}
 
-	/* Introduce a delay, required for some boards (e.g Davinci EVM) */
-	if (pdata->bus_delay)
-		udelay(pdata->bus_delay);
-
 	/* set the target address */
 	davinci_i2c_write_reg(dev, DAVINCI_I2C_SAR_REG, msg->addr);
 
@@ -758,8 +741,8 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 {
 	struct davinci_i2c_dev *dev;
 	struct i2c_adapter *adap;
-	struct i2c_bus_recovery_info *rinfo;
 	int r, irq;
+	u32 prop;
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
@@ -773,29 +756,15 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 
 	dev->dev = &pdev->dev;
 	dev->irq = irq;
-	dev->pdata = dev_get_platdata(&pdev->dev);
 	platform_set_drvdata(pdev, dev);
 
-	if (!dev->pdata && pdev->dev.of_node) {
-		u32 prop;
+	r = device_property_read_u32(&pdev->dev, "clock-frequency", &prop);
+	if (r)
+		prop = DAVINCI_I2C_DEFAULT_BUS_FREQ;
 
-		dev->pdata = devm_kzalloc(&pdev->dev,
-			sizeof(struct davinci_i2c_platform_data), GFP_KERNEL);
-		if (!dev->pdata)
-			return -ENOMEM;
+	dev->bus_freq = prop / 1000;
 
-		memcpy(dev->pdata, &davinci_i2c_platform_data_default,
-			sizeof(struct davinci_i2c_platform_data));
-		if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency",
-			&prop))
-			dev->pdata->bus_freq = prop / 1000;
-
-		dev->pdata->has_pfunc =
-			of_property_read_bool(pdev->dev.of_node,
-					      "ti,has-pfunc");
-	} else if (!dev->pdata) {
-		dev->pdata = &davinci_i2c_platform_data_default;
-	}
+	dev->has_pfunc = device_property_present(&pdev->dev, "ti,has-pfunc");
 
 	dev->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(dev->clk))
@@ -843,23 +812,8 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 	adap->timeout = DAVINCI_I2C_TIMEOUT;
 	adap->dev.of_node = pdev->dev.of_node;
 
-	if (dev->pdata->has_pfunc)
+	if (dev->has_pfunc)
 		adap->bus_recovery_info = &davinci_i2c_scl_recovery_info;
-	else if (dev->pdata->gpio_recovery) {
-		rinfo =  &davinci_i2c_gpio_recovery_info;
-		adap->bus_recovery_info = rinfo;
-		rinfo->scl_gpiod = devm_gpiod_get(&pdev->dev, "scl",
-						  GPIOD_OUT_HIGH_OPEN_DRAIN);
-		if (IS_ERR(rinfo->scl_gpiod)) {
-			r = PTR_ERR(rinfo->scl_gpiod);
-			goto err_unuse_clocks;
-		}
-		rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN);
-		if (IS_ERR(rinfo->sda_gpiod)) {
-			r = PTR_ERR(rinfo->sda_gpiod);
-			goto err_unuse_clocks;
-		}
-	}
 
 	adap->nr = pdev->id;
 	r = i2c_add_numbered_adapter(adap);
diff --git a/include/linux/platform_data/i2c-davinci.h b/include/linux/platform_data/i2c-davinci.h
deleted file mode 100644
index 98967df07468..000000000000
--- a/include/linux/platform_data/i2c-davinci.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * DaVinci I2C controller platform_device info
- *
- * Author: Vladimir Barinov, MontaVista Software, Inc. <source at mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
-*/
-
-#ifndef __ASM_ARCH_I2C_H
-#define __ASM_ARCH_I2C_H
-
-/* All frequencies are expressed in kHz */
-struct davinci_i2c_platform_data {
-	unsigned int	bus_freq;	/* standard bus frequency (kHz) */
-	unsigned int	bus_delay;	/* post-transaction delay (usec) */
-	bool		gpio_recovery;	/* Use GPIO recovery method */
-	bool		has_pfunc;	/* Chip has a ICPFUNC register */
-};
-
-/* for board setup code */
-void davinci_init_i2c(struct davinci_i2c_platform_data *);
-
-#endif /* __ASM_ARCH_I2C_H */
-- 
2.45.2



From brgl at bgdev.pl  Wed Dec 11 02:23:36 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Wed, 11 Dec 2024 11:23:36 +0100
Subject: [PATCH 2/3] i2c: davinci: order includes alphabetically
In-Reply-To: <20241211102337.37956-1-brgl@bgdev.pl>
References: <20241211102337.37956-1-brgl@bgdev.pl>
Message-ID: <20241211102337.37956-2-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

For better readability order included headers alphabetically.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/i2c/busses/i2c-davinci.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 4b499931fdfd..bab9f785eeec 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -11,22 +11,23 @@
  *
  * ----------------------------------------------------------------------------
  */
+
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/clk.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/cpufreq.h>
-#include <linux/gpio/consumer.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
 
 /* ----- global defines ----------------------------------------------- */
 
-- 
2.45.2



From qperret at google.com  Wed Dec 11 02:14:51 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 10:14:51 +0000
Subject: [PATCH v2 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <CA+EHjTw+3oAcp3ujjPmbcu42=95nw8WA=rZHYFL91ZK_Wfs_vA@mail.gmail.com>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-11-qperret@google.com>
 <CA+EHjTwHSyQ1FJc7axbLNuBxSWpRVE6brb34nO+F59=QRmfQEg@mail.gmail.com>
 <Z1hhHRdpCZcLs046@google.com>
 <CA+EHjTw4GX3j_ssN-tWnf780xkvyKO5mBN6fnvXeWvQcBDmcNg@mail.gmail.com>
 <Z1liL3BtoPnSyvlh@google.com>
 <CA+EHjTw+3oAcp3ujjPmbcu42=95nw8WA=rZHYFL91ZK_Wfs_vA@mail.gmail.com>
Message-ID: <Z1lmG-3KnOZrOCCa@google.com>

On Wednesday 11 Dec 2024 at 10:07:16 (+0000), Fuad Tabba wrote:
> On Wed, 11 Dec 2024 at 09:58, Quentin Perret <qperret at google.com> wrote:
> >
> > On Tuesday 10 Dec 2024 at 15:51:01 (+0000), Fuad Tabba wrote:
> > > On Tue, 10 Dec 2024 at 15:41, Quentin Perret <qperret at google.com> wrote:
> > > > > Initially I thought the comment was related to the warning below,
> > > > > which confused me.
> > > >
> > > > It actually is about the warning below :-)
> > > >
> > > > > Now I think what you're trying to say is that we'll
> > > > > allow the share, and the (unrelated to the comment) warning is to
> > > > > ensure that the PKVM_PAGE_SHARED_OWNED is consistent with the share
> > > > > count.
> > > >
> > > > So, the only case where the host should ever attempt do use
> > > > __pkvm_host_share_guest() on a page that is already shared is for a page
> > > > already shared *with an np-guest*. The page->host_share_guest_count being
> > > > elevated is the easiest way to check that the page is indeed in that
> > > > state, hence the warning.
> > > >
> > > > If for example the host was trying to share with an np-guest a page that
> > > > is currently shared with the hypervisor, that check would fail. We can
> > > > discuss whether or not we would want to allow it, but for now there is
> > > > strictly no need for it so I went with the restrictive option. We can
> > > > relax that constraint later if need be.
> > > >
> > > > > I think what you should have here, which would work better with the
> > > > > comment, is something like:
> > > > >
> > > > >                 /* Only host to np-guest multi-sharing is tolerated */
> > > > > +               if (pkvm_hyp_vcpu_is_protected(vcpu))
> > > > > +                       return -EPERM;
> > > > >
> > > > > That would even make the comment unnecessary.
> > > >
> > > > I would prefer not adding this here, handle___pkvm_host_share_guest() in
> > > > hyp-main.c already does that for us.
> > >
> > > I understand now, and I agree that an additional check isn't
> > > necessary. Could you clarify the comment though? It's the word "only"
> > > that threw me off, since to me it implied that the check was enforcing
> > > the word "only". Maybe:
> > >
> > > >                 /* Tolerate host to np-guest multi-sharing. */
> >
> > I guess 'only' is somewhat important, it is the _only_ type of
> > multi-sharing that we allow and the check enforces precisely that. The
> > WARN_ON() will be triggered for any other type of multi-sharing, so we
> > are really checking that _only_ np-guest multi-sharing goes through.
> >
> > Perhaps the confusing part is that the code as-is relies on WARN_ON()
> > being fatal for the enforcement. Would it help if I changed the 'break'
> > statement right after to 'fallthrough' so we proceed to return -EPERM?
> > In practice we won't return anything as the hypervisor will panic, but
> > I presume it is better from a logic perspective.
> 
> It would, but then we wouldn't be tolerating np-guest multisharing,
> but like you said, it's not like we're tolerating it now anyway.
> 
> I wonder if it would be better simply not to allow multisharing at all for now.

That would mean turning off MMU notifiers in the host and taking
long-term GUP pins on np-guest pages I think. Multi-sharing can be
caused by many things, KSM, the zero page ... so we we'd need to turn
all of that off (IOW, no MMU notifiers).

That's more or less the status quo in Android, but I vote for not going
down that path upstream. pKVM should ideally be transparent for np-guest
support if at all possible.

Thanks,
Quentin


From cristian.ciocaltea at collabora.com  Wed Dec 11 02:15:05 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 12:15:05 +0200
Subject: [PATCH v2 1/5] dt-bindings: display: vop2: Add optional PLL clock
 properties
In-Reply-To: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
Message-ID: <20241211-vop2-hdmi0-disp-modes-v2-1-471cf5001e45@collabora.com>

On RK3588, HDMI PHY PLL can be used as an alternative and more accurate
pixel clock source for VOP2 video ports 0, 1 and 2.

Document the optional PLL clock properties corresponding to the two HDMI
PHYs available on the SoC.

Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
index 2531726af306bd388c00c3c0a1785b2c7367e2bd..46d956e63338e196361483a668fbf5597ebce24f 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -53,6 +53,8 @@ properties:
       - description: Pixel clock for video port 2.
       - description: Pixel clock for video port 3.
       - description: Peripheral(vop grf/dsi) clock.
+      - description: Alternative pixel clock provided by HDMI0 PHY PLL.
+      - description: Alternative pixel clock provided by HDMI1 PHY PLL.
 
   clock-names:
     minItems: 5
@@ -64,6 +66,8 @@ properties:
       - const: dclk_vp2
       - const: dclk_vp3
       - const: pclk_vop
+      - const: pll_hdmiphy0
+      - const: pll_hdmiphy1
 
   rockchip,grf:
     $ref: /schemas/types.yaml#/definitions/phandle

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Wed Dec 11 02:15:04 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 11 Dec 2024 12:15:04 +0200
Subject: [PATCH v2 0/5] Improve Rockchip VOP2 display modes handling on
 RK3588 HDMI0
Message-ID: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>

VOP2 support for RK3588 SoC is currently not capable to handle the full
range of display modes advertised by the connected screens, e.g. it
doesn't cope well with non-integer refresh rates like 59.94, 29.97,
23.98, etc.

There are two HDMI PHYs available on RK3588, each providing a PLL that
can be used by three out of the four VOP2 video ports as an alternative
and more accurate pixel clock source. This is able to correctly handle
all display modes up to 4K at 60Hz.

As for the moment HDMI1 output is not supported upstream, the patch
series targets HDMI0 only.

Additionally, note that testing any HDMI 2.0 specific modes, e.g.
4K at 60Hz, requires high TMDS clock ratio and scrambling support [1]. The
patch is usable but not yet ready to be submitted - I will handle this
soon.

Thanks,
Cristian

[1] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commits/rk3588-hdmi-bridge-next-20241115

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
Changes in v2:
- Collected Acked-by tag from Rob and Tested-by from Naoki
- Rebased series onto v6.13-rc1
- Link to v1: https://lore.kernel.org/r/20241116-vop2-hdmi0-disp-modes-v1-0-2bca51db4898 at collabora.com

---
Cristian Ciocaltea (5):
      dt-bindings: display: vop2: Add optional PLL clock properties
      drm/rockchip: vop2: Drop unnecessary if_pixclk_rate computation
      drm/rockchip: vop2: Improve display modes handling on RK3588 HDMI0
      arm64: dts: rockchip: Enable HDMI0 PHY clk provider on RK3588
      arm64: dts: rockchip: Add HDMI0 PHY PLL clock source to VOP2 on RK3588

 .../bindings/display/rockchip/rockchip-vop2.yaml   |  4 +++
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi      |  7 +++--
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c       | 36 +++++++++++++++++++++-
 3 files changed, 44 insertions(+), 3 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241116-vop2-hdmi0-disp-modes-b39e3619768f



From brgl at bgdev.pl  Wed Dec 11 02:23:37 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Wed, 11 Dec 2024 11:23:37 +0100
Subject: [PATCH 3/3] i2c: davinci: use generic device property accessors
In-Reply-To: <20241211102337.37956-1-brgl@bgdev.pl>
References: <20241211102337.37956-1-brgl@bgdev.pl>
Message-ID: <20241211102337.37956-3-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Don't use generic OF APIs if the generic device-level ones will do.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/i2c/busses/i2c-davinci.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index bab9f785eeec..6a909d339681 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -23,9 +23,9 @@
 #include <linux/io.h>
 #include <linux/kernel.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/sched.h>
 #include <linux/slab.h>
 
@@ -173,7 +173,6 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
 	u32 clkh;
 	u32 clkl;
 	u32 input_clock = clk_get_rate(dev->clk);
-	struct device_node *of_node = dev->dev->of_node;
 
 	/* NOTE: I2C Clock divider programming info
 	 * As per I2C specs the following formulas provide prescaler
@@ -207,7 +206,7 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
 		psc++;	/* better to run under spec than over */
 	d = (psc >= 2) ? 5 : 7 - psc;
 
-	if (of_node && of_device_is_compatible(of_node, "ti,keystone-i2c"))
+	if (device_is_compatible(dev->dev, "ti,keystone-i2c"))
 		d = 6;
 
 	clk = ((input_clock / (psc + 1)) / (dev->bus_freq * 1000));
@@ -811,7 +810,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 	adap->algo = &i2c_davinci_algo;
 	adap->dev.parent = &pdev->dev;
 	adap->timeout = DAVINCI_I2C_TIMEOUT;
-	adap->dev.of_node = pdev->dev.of_node;
+	adap->dev.of_node = dev_of_node(&pdev->dev);
 
 	if (dev->has_pfunc)
 		adap->bus_recovery_info = &davinci_i2c_scl_recovery_info;
-- 
2.45.2



From tabba at google.com  Wed Dec 11 02:32:54 2024
From: tabba at google.com (Fuad Tabba)
Date: Wed, 11 Dec 2024 10:32:54 +0000
Subject: [PATCH v2 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <Z1lnwZPrx9GzgFCG@google.com>
References: <20241203103735.2267589-1-qperret@google.com> <20241203103735.2267589-11-qperret@google.com>
 <CA+EHjTwHSyQ1FJc7axbLNuBxSWpRVE6brb34nO+F59=QRmfQEg@mail.gmail.com>
 <Z1hhHRdpCZcLs046@google.com> <CA+EHjTw4GX3j_ssN-tWnf780xkvyKO5mBN6fnvXeWvQcBDmcNg@mail.gmail.com>
 <Z1liL3BtoPnSyvlh@google.com> <CA+EHjTw+3oAcp3ujjPmbcu42=95nw8WA=rZHYFL91ZK_Wfs_vA@mail.gmail.com>
 <Z1lmG-3KnOZrOCCa@google.com> <Z1lnwZPrx9GzgFCG@google.com>
Message-ID: <CA+EHjTzrL9v3DBGRht_-JPpfpd0eW1xYAMcbeNA83B1K64oPgg@mail.gmail.com>

On Wed, 11 Dec 2024 at 10:21, Quentin Perret <qperret at google.com> wrote:
>
> On Wednesday 11 Dec 2024 at 10:14:51 (+0000), Quentin Perret wrote:
> > On Wednesday 11 Dec 2024 at 10:07:16 (+0000), Fuad Tabba wrote:
> > > On Wed, 11 Dec 2024 at 09:58, Quentin Perret <qperret at google.com> wrote:
> > > >
> > > > On Tuesday 10 Dec 2024 at 15:51:01 (+0000), Fuad Tabba wrote:
> > > > > On Tue, 10 Dec 2024 at 15:41, Quentin Perret <qperret at google.com> wrote:
> > > > > > > Initially I thought the comment was related to the warning below,
> > > > > > > which confused me.
> > > > > >
> > > > > > It actually is about the warning below :-)
> > > > > >
> > > > > > > Now I think what you're trying to say is that we'll
> > > > > > > allow the share, and the (unrelated to the comment) warning is to
> > > > > > > ensure that the PKVM_PAGE_SHARED_OWNED is consistent with the share
> > > > > > > count.
> > > > > >
> > > > > > So, the only case where the host should ever attempt do use
> > > > > > __pkvm_host_share_guest() on a page that is already shared is for a page
> > > > > > already shared *with an np-guest*. The page->host_share_guest_count being
> > > > > > elevated is the easiest way to check that the page is indeed in that
> > > > > > state, hence the warning.
> > > > > >
> > > > > > If for example the host was trying to share with an np-guest a page that
> > > > > > is currently shared with the hypervisor, that check would fail. We can
> > > > > > discuss whether or not we would want to allow it, but for now there is
> > > > > > strictly no need for it so I went with the restrictive option. We can
> > > > > > relax that constraint later if need be.
> > > > > >
> > > > > > > I think what you should have here, which would work better with the
> > > > > > > comment, is something like:
> > > > > > >
> > > > > > >                 /* Only host to np-guest multi-sharing is tolerated */
> > > > > > > +               if (pkvm_hyp_vcpu_is_protected(vcpu))
> > > > > > > +                       return -EPERM;
> > > > > > >
> > > > > > > That would even make the comment unnecessary.
> > > > > >
> > > > > > I would prefer not adding this here, handle___pkvm_host_share_guest() in
> > > > > > hyp-main.c already does that for us.
> > > > >
> > > > > I understand now, and I agree that an additional check isn't
> > > > > necessary. Could you clarify the comment though? It's the word "only"
> > > > > that threw me off, since to me it implied that the check was enforcing
> > > > > the word "only". Maybe:
> > > > >
> > > > > >                 /* Tolerate host to np-guest multi-sharing. */
> > > >
> > > > I guess 'only' is somewhat important, it is the _only_ type of
> > > > multi-sharing that we allow and the check enforces precisely that. The
> > > > WARN_ON() will be triggered for any other type of multi-sharing, so we
> > > > are really checking that _only_ np-guest multi-sharing goes through.
> > > >
> > > > Perhaps the confusing part is that the code as-is relies on WARN_ON()
> > > > being fatal for the enforcement. Would it help if I changed the 'break'
> > > > statement right after to 'fallthrough' so we proceed to return -EPERM?
> > > > In practice we won't return anything as the hypervisor will panic, but
> > > > I presume it is better from a logic perspective.
> > >
> > > It would, but then we wouldn't be tolerating np-guest multisharing,
> > > but like you said, it's not like we're tolerating it now anyway.
> > >
> > > I wonder if it would be better simply not to allow multisharing at all for now.
> >
> > That would mean turning off MMU notifiers in the host and taking
> > long-term GUP pins on np-guest pages I think. Multi-sharing can be
> > caused by many things, KSM, the zero page ... so we we'd need to turn
> > all of that off (IOW, no MMU notifiers).
> >
> > That's more or less the status quo in Android, but I vote for not going
> > down that path upstream. pKVM should ideally be transparent for np-guest
> > support if at all possible.
>
> And to clarify my suggestion above, we should fallthrough IFF
> host_share_guest_count is 0, but break otherwise to retain multi-sharing
> support. So it's not a simple s/break/fallthrough change, that needs a
> tiny bit of added logic.

I think this would make things clearer. Thanks.

/fuad


From maz at kernel.org  Wed Dec 11 02:40:02 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Dec 2024 10:40:02 +0000
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <92cee905-a505-4ce9-9bbc-6fba4cea1d80@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
	<87ed2fs03w.wl-maz@kernel.org>
	<92cee905-a505-4ce9-9bbc-6fba4cea1d80@quicinc.com>
Message-ID: <86sequsdtp.wl-maz@kernel.org>

On Wed, 11 Dec 2024 00:37:34 +0000,
Pavan Kondeti <quic_pkondeti at quicinc.com> wrote:
> 
> On Tue, Dec 10, 2024 at 09:24:03PM +0000, Marc Zyngier wrote:
> > > +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> > > +{
> > > +	int ret;
> > > +
> > > +#ifdef CONFIG_ARM64
> > > +	/*
> > > +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> > > +	 * to switch the secure mode to avoid the dependency on zap shader.
> > > +	 */
> > > +	if (is_kernel_in_hyp_mode())
> > > +		goto direct_switch;
> > 
> > No, please. To check whether you are *booted* at EL2, you need to
> > check for is_hyp_available(). Whether the kernel runs at EL1 or EL2 is
> > none of the driver's business, really. This is still absolutely
> > disgusting from an abstraction perspective, but I guess we don't have
> > much choice here.
> > 
> 
> Thanks Marc. Any suggestions on how we can make is_hyp_mode_available()
> available for modules? Do you prefer exporting
> kvm_protected_mode_initialized and __boot_cpu_mode symbols directly or
> try something like [1]?

Ideally, neither. These were bad ideas nine years ago, and they still
are. The least ugly hack I can come up with is the patch below, and
you'd write something like:

	if (cpus_have_cap(ARM64_HAS_EL2_OWNERSHIP))
		blah();

This is obviously completely untested.

It also doesn't solve the problem of the kernel booted on bare-metal
at EL1, or with a hypervisor that doesn't change the programming
interface of the device under the guest's feet. Eventually, someone
will have to address these cases.

Thanks,

	M.

From 4823e7bb868d3ac2b938ecc4c3dbbdd460656af1 Mon Sep 17 00:00:00 2001
From: Marc Zyngier <maz at kernel.org>
Date: Wed, 11 Dec 2024 10:02:25 +0000
Subject: [PATCH] arm64: Expose kernel ownership of EL2 via a capability

It appears that some drivers have to jump through a lot of hoops
to initialise correctly when running under a particular hypervisor,
while they can directly do it when running bare-metal.

Unfortunately, said hypervisor cannot be directly identified as it
doesn't implement the correct SMCCC interface, leaving the driver
with a certain amount of guesswork.

Being booted at EL2 provides at least an indication that there is no
non-nesting hypervisor, which is good enough to discriminate the
humpy hypervisor.

For this purpose, expose a new system-wide CPU capability aptly named
ARM64_HAS_EL2_OWNERSHIP, which said driver can check.

Note that this doesn't solve the problem of a kernel booted at EL1
without a hypervisor, or with a hypervisor that doesn't break the
device programming interface.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 11 +++++++++++
 arch/arm64/tools/cpucaps       |  1 +
 2 files changed, 12 insertions(+)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 36c7b29ddf9e8..8fdc3ef23d9dc 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1868,6 +1868,11 @@ static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
 		  is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
 }
 
+static bool has_el2_ownership(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	return is_hyp_mode_available();
+}
+
 #if defined(ID_AA64MMFR0_EL1_TGRAN_LPA2) && defined(ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2)
 static bool has_lpa2_at_stage1(u64 mmfr0)
 {
@@ -3012,6 +3017,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, GCS, IMP)
 	},
 #endif
+	{
+		.desc = "Kernel owns EL2",
+		.capability = ARM64_HAS_EL2_OWNERSHIP,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_el2_ownership,
+	},
 	{},
 };
 
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 1e65f2fb45bd1..94ce3462e6298 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -24,6 +24,7 @@ HAS_DIT
 HAS_E0PD
 HAS_ECV
 HAS_ECV_CNTPOFF
+HAS_EL2_OWNERSHIP
 HAS_EPAN
 HAS_EVT
 HAS_FPMR
-- 
2.39.2


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


From heiko at sntech.de  Wed Dec 11 02:43:42 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 11 Dec 2024 11:43:42 +0100
Subject: (subset) [PATCH v2 0/4] Add support for HDMI1 output on RK3588 SoC
In-Reply-To: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
References: <20241211-rk3588-hdmi1-v2-0-02cdca22ff68@collabora.com>
Message-ID: <173391381115.2426313.13144345816370660962.b4-ty@sntech.de>


On Wed, 11 Dec 2024 01:06:13 +0200, Cristian Ciocaltea wrote:
> The patches provide the basic support to handle the second HDMI output
> port found on Rockchip RK3588 SoC.
> 
> For now I enabled it on Radxa ROCK 5B only, the board I've been using to
> validate this.
> 
> ** IMPORTANT **
> 
> [...]

Applied, thanks!

[1/4] drm/rockchip: dw_hdmi_qp: Add support for RK3588 HDMI1 output
      commit: 0f818db20c77506ddd870761785740f8230a4207

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From Jonathan.Cameron at huawei.com  Wed Dec 11 03:12:47 2024
From: Jonathan.Cameron at huawei.com (Jonathan Cameron)
Date: Wed, 11 Dec 2024 11:12:47 +0000
Subject: [PATCH 1/2] perf: Fujitsu: Add the Uncore MAC PMU driver
In-Reply-To: <OSZPR01MB690841B2D3522EC863F10800D4242@OSZPR01MB6908.jpnprd01.prod.outlook.com>
References: <20241108054006.2550856-1-fj5100bi@fujitsu.com>
	<20241108054006.2550856-2-fj5100bi@fujitsu.com>
	<20241108141911.00003e14@huawei.com>
	<OSZPR01MB690841B2D3522EC863F10800D4242@OSZPR01MB6908.jpnprd01.prod.outlook.com>
Message-ID: <20241211111247.00003a05@huawei.com>


> > > +device_initcall(register_fujitsu_mac_pmu_driver);
> > > diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> > > index 2361ed4d2b15..e6e49e09488a 100644
> > > --- a/include/linux/cpuhotplug.h
> > > +++ b/include/linux/cpuhotplug.h
> > > @@ -227,6 +227,7 @@ enum cpuhp_state {
> > >  	CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE,
> > >  	CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE,
> > >  	CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
> > > +	CPUHP_AP_PERF_ARM_FUJITSU_MAC_ONLINE,  
> > 
> > Can this use CPU_AP_ONLINE_DYN
> > or are there some ordering contraints?  
> 
> It follows the same principles as other PMU drivers.

Some of them and I suspect the is cut and paste rather than justified.
+ Not sure how long the dynamic part has been available.

> 
> >   
> > >  	CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
> > >  	CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
> > >  	CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,  
> 
> Best Regards,
> Yoshihiro Furudera



From quic_jinlmao at quicinc.com  Wed Dec 11 03:13:58 2024
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Wed, 11 Dec 2024 19:13:58 +0800
Subject: [PATCH v5 0/2] coresight: Add label sysfs node support
In-Reply-To: <avimk3fdjal6ohezktrexnbguxf6wj5tv6jbcqy5r4bnuww6kz@3xjt3mutne7n>
References: <20241210122253.31926-1-quic_jinlmao@quicinc.com>
 <avimk3fdjal6ohezktrexnbguxf6wj5tv6jbcqy5r4bnuww6kz@3xjt3mutne7n>
Message-ID: <7bdaa38a-c114-4538-8fbb-85e0f326f436@quicinc.com>



On 2024/12/11 16:46, Krzysztof Kozlowski wrote:
> On Tue, Dec 10, 2024 at 08:22:51PM +0800, Mao Jinlong wrote:
>> With current design, the name of the non-cpu bounded coresight
>> component is the device type with the number. And with 'ls' command
>> we can get the register address of the component. But from these
>> information, we can't know what the HW or system the component belongs
>> to. Add label in DT and show the hw information by reading label sysfs
>> node.
>>
>> cti_sys0 -> ../../../devices/platform/soc at 0/138f0000.cti/cti_sys0
>> cti_sys1 -> ../../../devices/platform/soc at 0/13900000.cti/cti_sys1
>> tpdm0 -> ../../../devices/platform/soc at 0/10b0d000.tpdm/tpdm0
>> tpdm1 -> ../../../devices/platform/soc at 0/10c28000.tpdm/tpdm1
>> tpdm2 -> ../../../devices/platform/soc at 0/10c29000.tpdm/tpdm2
>>
>> /sys/bus/coresight/devices # cat cti*/label
>> cti_dlct_0
>> cti_dlct_1
>> cti_apss_0
>> cti_apss_1
>> cti_apss_2
>>
>> Change since V4:
>> 1. Add label in DT and add label sysfs node for each coresight device.
> 
> This is v5, no links to previous versions (I really suggest to start
> using b4 if you want to make your process easier for you), no other
> changes so subject is obviously the same and looking for this patchset
> previous versions gives me 0 results:
> 
> https://lore.kernel.org/all/?q=%22coresight%3A+Add+label+sysfs+node+support%22
> 
> OK, let's try b4 diff:
> 
> b4 diff '20241210122253.31926-1-quic_jinlmao at quicinc.com'
> Grabbing thread from lore.kernel.org/all/20241210122253.31926-1-quic_jinlmao at quicinc.com/t.mbox.gz
> Checking for older revisions
> Grabbing search results from lore.kernel.org
> Nothing matching that query.
> ---
> Analyzing 3 messages in the thread
> Could not find lower series to compare against.
> 
> 
> So how do you expect us to do any meaningful review?
> 
> Best regards,
> Krzysztof
I will resend the patches with the links of lower series.

> 



From o451686892 at gmail.com  Wed Dec 11 03:16:39 2024
From: o451686892 at gmail.com (Weizhao Ouyang)
Date: Wed, 11 Dec 2024 19:16:39 +0800
Subject: [PATCH v2] kselftest/arm64: abi: fix SVCR detection
Message-ID: <20241211111639.12344-1-o451686892@gmail.com>

When using svcr_in to check ZA and Streaming Mode, we should make sure
that the value in x2 is correct, otherwise it may trigger an Illegal
instruction if FEAT_SVE and !FEAT_SME.

Fixes: 43e3f85523e4 ("kselftest/arm64: Add SME support to syscall ABI test")
Signed-off-by: Weizhao Ouyang <o451686892 at gmail.com>
---
 .../selftests/arm64/abi/syscall-abi-asm.S     | 32 +++++++++----------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
index df3230fdac39..66ab2e0bae5f 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
+++ b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
@@ -81,32 +81,31 @@ do_syscall:
 	stp	x27, x28, [sp, #96]
 
 	// Set SVCR if we're doing SME
-	cbz	x1, 1f
+	cbz	x1, load_gpr
 	adrp	x2, svcr_in
 	ldr	x2, [x2, :lo12:svcr_in]
 	msr	S3_3_C4_C2_2, x2
-1:
 
 	// Load ZA and ZT0 if enabled - uses x12 as scratch due to SME LDR
-	tbz	x2, #SVCR_ZA_SHIFT, 1f
+	tbz	x2, #SVCR_ZA_SHIFT, load_gpr
 	mov	w12, #0
 	ldr	x2, =za_in
-2:	_ldr_za 12, 2
+1:	_ldr_za 12, 2
 	add	x2, x2, x1
 	add	x12, x12, #1
 	cmp	x1, x12
-	bne	2b
+	bne	1b
 
 	// ZT0
 	mrs	x2, S3_0_C0_C4_5	// ID_AA64SMFR0_EL1
 	ubfx	x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \
 			 #ID_AA64SMFR0_EL1_SMEver_WIDTH
-	cbz	x2, 1f
+	cbz	x2, load_gpr
 	adrp	x2, zt_in
 	add	x2, x2, :lo12:zt_in
 	_ldr_zt 2
-1:
 
+load_gpr:
 	// Load GPRs x8-x28, and save our SP/FP for later comparison
 	ldr	x2, =gpr_in
 	add	x2, x2, #64
@@ -125,9 +124,9 @@ do_syscall:
 	str	x30, [x2], #8		// LR
 
 	// Load FPRs if we're not doing neither SVE nor streaming SVE
-	cbnz	x0, 1f
+	cbnz	x0, check_sve_in
 	ldr	x2, =svcr_in
-	tbnz	x2, #SVCR_SM_SHIFT, 1f
+	tbnz	x2, #SVCR_SM_SHIFT, check_sve_in
 
 	ldr	x2, =fpr_in
 	ldp	q0, q1, [x2]
@@ -148,8 +147,8 @@ do_syscall:
 	ldp	q30, q31, [x2, #16 * 30]
 
 	b	2f
-1:
 
+check_sve_in:
 	// Load the SVE registers if we're doing SVE/SME
 
 	ldr	x2, =z_in
@@ -256,32 +255,31 @@ do_syscall:
 	stp	q30, q31, [x2, #16 * 30]
 
 	// Save SVCR if we're doing SME
-	cbz	x1, 1f
+	cbz	x1, check_sve_out
 	mrs	x2, S3_3_C4_C2_2
 	adrp	x3, svcr_out
 	str	x2, [x3, :lo12:svcr_out]
-1:
 
 	// Save ZA if it's enabled - uses x12 as scratch due to SME STR
-	tbz	x2, #SVCR_ZA_SHIFT, 1f
+	tbz	x2, #SVCR_ZA_SHIFT, check_sve_out
 	mov	w12, #0
 	ldr	x2, =za_out
-2:	_str_za 12, 2
+1:	_str_za 12, 2
 	add	x2, x2, x1
 	add	x12, x12, #1
 	cmp	x1, x12
-	bne	2b
+	bne	1b
 
 	// ZT0
 	mrs	x2, S3_0_C0_C4_5	// ID_AA64SMFR0_EL1
 	ubfx	x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \
 			#ID_AA64SMFR0_EL1_SMEver_WIDTH
-	cbz	x2, 1f
+	cbz	x2, check_sve_out
 	adrp	x2, zt_out
 	add	x2, x2, :lo12:zt_out
 	_str_zt 2
-1:
 
+check_sve_out:
 	// Save the SVE state if we have some
 	cbz	x0, 1f
 
-- 
2.45.2



From robh at kernel.org  Wed Dec 11 03:21:35 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 05:21:35 -0600
Subject: [PATCH v2] ASoC: dt-bindings: sound: atmel-at91sam9g20ek:
 convert to json-schema
In-Reply-To: <20241211-sound-atmel-at91sam9g20ek-v2-1-86a0e31e6af9@microchip.com>
References: <20241211-sound-atmel-at91sam9g20ek-v2-1-86a0e31e6af9@microchip.com>
Message-ID: <173391609559.2340929.13321693035546295768.robh@kernel.org>


On Wed, 11 Dec 2024 15:16:15 +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>
> ---
> Changes in v2:
> - Add missing CODEC pin options to 'atmel,audio-routing' items.
> - Drop 'minItems' from 'atmel,audio-routing' since enum defines valid connections.
> - Add subsystem tag to subject.
> - Add blank line between properties and fix typo.
> - Add audio complex description.
> - Link to v1: https://lore.kernel.org/lkml/20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b at microchip.com
> ---
>  .../bindings/sound/atmel,at91sam9g20ek-wm8731.yaml | 70 ++++++++++++++++++++++
>  .../sound/atmel-at91sam9g20ek-wm8731-audio.txt     | 26 --------
>  2 files changed, 70 insertions(+), 26 deletions(-)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.example.dtb: sound: atmel,audio-routing:2: 'Int MIC' is not one of ['Ext Spk', 'Int Mic', 'LOUT', 'ROUT', 'LHPOUT', 'RHPOUT', 'LLINEIN', 'RLINEIN', 'MICIN']
	from schema $id: http://devicetree.org/schemas/sound/atmel,at91sam9g20ek-wm8731.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241211-sound-atmel-at91sam9g20ek-v2-1-86a0e31e6af9 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 towinchenmi at gmail.com  Wed Dec 11 03:19:28 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:19:28 +0800
Subject: [PATCH 1/7] dt-bindings: cpufreq: apple,cluster-cpufreq: Add A7-A11, T2 compatibles
In-Reply-To: <20241211112244.18393-1-towinchenmi@gmail.com>
References: <20241211112244.18393-1-towinchenmi@gmail.com>
Message-ID: <20241211112244.18393-2-towinchenmi@gmail.com>

Add compatibles for Apple A7-A11, T2 SoCs.

Apple A7, A8, A8X gets the per-SoC compatible and the A7
"apple,s5l8960x-cluster-cpufreq" compatible.

Apple A9, A9X, A10, A10X, T2, A11 gets the per-SoC compatible, M1
"apple,t8103-cluster-cpufreq" compatible, then the
"apple,cluster-cpufreq" fallback compatible.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../bindings/cpufreq/apple,cluster-cpufreq.yaml        | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml b/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml
index 76cb9726660e..896276b8c6bb 100644
--- a/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml
+++ b/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml
@@ -24,9 +24,17 @@ properties:
               - apple,t8112-cluster-cpufreq
           - const: apple,cluster-cpufreq
       - items:
-          - const: apple,t6000-cluster-cpufreq
+          - enum:
+              - apple,s8000-cluster-cpufreq
+              - apple,t8010-cluster-cpufreq
+              - apple,t8015-cluster-cpufreq
+              - apple,t6000-cluster-cpufreq
           - const: apple,t8103-cluster-cpufreq
           - const: apple,cluster-cpufreq
+      - items:
+          - const: apple,t7000-cluster-cpufreq
+          - const: apple,s5l8960x-cluster-cpufreq
+      - const: apple,s5l8960x-cluster-cpufreq
 
   reg:
     maxItems: 1
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 03:19:29 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:19:29 +0800
Subject: [PATCH 2/7] cpufreq: apple-soc: Drop setting the PS2 field on M2+
In-Reply-To: <20241211112244.18393-1-towinchenmi@gmail.com>
References: <20241211112244.18393-1-towinchenmi@gmail.com>
Message-ID: <20241211112244.18393-3-towinchenmi@gmail.com>

From: Hector Martin <marcan at marcan.st>

Newer device do not use this. It is not known what this field does,
but change the behavior to be same as macOS to be safe.

Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 4dcacab9b4bf..ad6c7b8f290c 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -25,7 +25,7 @@
 #define APPLE_DVFS_CMD			0x20
 #define APPLE_DVFS_CMD_BUSY		BIT(31)
 #define APPLE_DVFS_CMD_SET		BIT(25)
-#define APPLE_DVFS_CMD_PS2		GENMASK(16, 12)
+#define APPLE_DVFS_CMD_PS2		GENMASK(15, 12)
 #define APPLE_DVFS_CMD_PS1		GENMASK(4, 0)
 
 /* Same timebase as CPU counter (24MHz) */
@@ -55,6 +55,7 @@
 #define APPLE_DVFS_TRANSITION_TIMEOUT 100
 
 struct apple_soc_cpufreq_info {
+	bool has_ps2;
 	u64 max_pstate;
 	u64 cur_pstate_mask;
 	u64 cur_pstate_shift;
@@ -69,18 +70,21 @@ struct apple_cpu_priv {
 static struct cpufreq_driver apple_soc_cpufreq_driver;
 
 static const struct apple_soc_cpufreq_info soc_t8103_info = {
+	.has_ps2 = true,
 	.max_pstate = 15,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8103,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103,
 };
 
 static const struct apple_soc_cpufreq_info soc_t8112_info = {
+	.has_ps2 = false,
 	.max_pstate = 31,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8112,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8112,
 };
 
 static const struct apple_soc_cpufreq_info soc_default_info = {
+	.has_ps2 = false,
 	.max_pstate = 15,
 	.cur_pstate_mask = 0, /* fallback */
 };
@@ -148,9 +152,12 @@ static int apple_soc_cpufreq_set_target(struct cpufreq_policy *policy,
 		return -EIO;
 	}
 
-	reg &= ~(APPLE_DVFS_CMD_PS1 | APPLE_DVFS_CMD_PS2);
+	reg &= ~APPLE_DVFS_CMD_PS1;
 	reg |= FIELD_PREP(APPLE_DVFS_CMD_PS1, pstate);
-	reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
+	if (priv->info->has_ps2) {
+		reg &= ~APPLE_DVFS_CMD_PS2;
+		reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
+	}
 	reg |= APPLE_DVFS_CMD_SET;
 
 	writeq_relaxed(reg, priv->reg_base + APPLE_DVFS_CMD);
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 03:19:30 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:19:30 +0800
Subject: [PATCH 3/7] cpufreq: apple-soc: Allow per-SoC configuration of APPLE_DVFS_CMD_PS1
In-Reply-To: <20241211112244.18393-1-towinchenmi@gmail.com>
References: <20241211112244.18393-1-towinchenmi@gmail.com>
Message-ID: <20241211112244.18393-4-towinchenmi@gmail.com>

Support for SoC that has a different APPLE_DVFS_CMD_PS1 will be added soon,
so modify the driver first to allow it to be configured per-SoC.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index ad6c7b8f290c..90e34105b50b 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -27,6 +27,7 @@
 #define APPLE_DVFS_CMD_SET		BIT(25)
 #define APPLE_DVFS_CMD_PS2		GENMASK(15, 12)
 #define APPLE_DVFS_CMD_PS1		GENMASK(4, 0)
+#define APPLE_DVFS_CMD_PS1_SHIFT	0
 
 /* Same timebase as CPU counter (24MHz) */
 #define APPLE_DVFS_LAST_CHG_TIME	0x38
@@ -59,6 +60,8 @@ struct apple_soc_cpufreq_info {
 	u64 max_pstate;
 	u64 cur_pstate_mask;
 	u64 cur_pstate_shift;
+	u64 ps1_mask;
+	u64 ps1_shift;
 };
 
 struct apple_cpu_priv {
@@ -74,6 +77,8 @@ static const struct apple_soc_cpufreq_info soc_t8103_info = {
 	.max_pstate = 15,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8103,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103,
+	.ps1_mask = APPLE_DVFS_CMD_PS1,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_SHIFT,
 };
 
 static const struct apple_soc_cpufreq_info soc_t8112_info = {
@@ -81,12 +86,16 @@ static const struct apple_soc_cpufreq_info soc_t8112_info = {
 	.max_pstate = 31,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8112,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8112,
+	.ps1_mask = APPLE_DVFS_CMD_PS1,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_SHIFT,
 };
 
 static const struct apple_soc_cpufreq_info soc_default_info = {
 	.has_ps2 = false,
 	.max_pstate = 15,
 	.cur_pstate_mask = 0, /* fallback */
+	.ps1_mask = APPLE_DVFS_CMD_PS1,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_SHIFT,
 };
 
 static const struct of_device_id apple_soc_cpufreq_of_match[] __maybe_unused = {
@@ -152,8 +161,8 @@ static int apple_soc_cpufreq_set_target(struct cpufreq_policy *policy,
 		return -EIO;
 	}
 
-	reg &= ~APPLE_DVFS_CMD_PS1;
-	reg |= FIELD_PREP(APPLE_DVFS_CMD_PS1, pstate);
+	reg &= ~priv->info->ps1_mask;
+	reg |= pstate << priv->info->ps1_shift;
 	if (priv->info->has_ps2) {
 		reg &= ~APPLE_DVFS_CMD_PS2;
 		reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 03:19:31 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:19:31 +0800
Subject: [PATCH 4/7] cpufreq: apple-soc: Use 32-bit read for status register
In-Reply-To: <20241211112244.18393-1-towinchenmi@gmail.com>
References: <20241211112244.18393-1-towinchenmi@gmail.com>
Message-ID: <20241211112244.18393-5-towinchenmi@gmail.com>

Apple A7-A9(X) SoCs requires 32-bit reads on the status register. Newer
SoCs accepts 32-bit reads on the status register as well.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 90e34105b50b..b27d261fe5a6 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -122,7 +122,7 @@ static unsigned int apple_soc_cpufreq_get_rate(unsigned int cpu)
 	unsigned int pstate;
 
 	if (priv->info->cur_pstate_mask) {
-		u64 reg = readq_relaxed(priv->reg_base + APPLE_DVFS_STATUS);
+		u32 reg = readl_relaxed(priv->reg_base + APPLE_DVFS_STATUS);
 
 		pstate = (reg & priv->info->cur_pstate_mask) >>  priv->info->cur_pstate_shift;
 	} else {
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 03:19:32 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:19:32 +0800
Subject: [PATCH 5/7] cpufreq: apple-soc: Increase cluster switch timeout to 400us
In-Reply-To: <20241211112244.18393-1-towinchenmi@gmail.com>
References: <20241211112244.18393-1-towinchenmi@gmail.com>
Message-ID: <20241211112244.18393-6-towinchenmi@gmail.com>

Apple A11 SoC takes a long time to switch. Maximum switch time
observed is 345us, so increase the cluster switch timeout to 400us
to be safe.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index b27d261fe5a6..94e57f055a5f 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -53,7 +53,7 @@
 #define APPLE_DVFS_PLL_FACTOR_MULT	GENMASK(31, 16)
 #define APPLE_DVFS_PLL_FACTOR_DIV	GENMASK(15, 0)
 
-#define APPLE_DVFS_TRANSITION_TIMEOUT 100
+#define APPLE_DVFS_TRANSITION_TIMEOUT 400
 
 struct apple_soc_cpufreq_info {
 	bool has_ps2;
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 03:19:33 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:19:33 +0800
Subject: [PATCH 6/7] cpufreq: apple-soc: Set fallback transition latency to APPLE_DVFS_TRANSITION_TIMEOUT
In-Reply-To: <20241211112244.18393-1-towinchenmi@gmail.com>
References: <20241211112244.18393-1-towinchenmi@gmail.com>
Message-ID: <20241211112244.18393-7-towinchenmi@gmail.com>

The driver already assumes transitions will not take longer than
APPLE_DVFS_TRANSITION_TIMEOUT in apple_soc_cpufreq_set_target(), so it
makes little sense to set CPUFREQ_ETERNAL as the transition latency
when the transistion latency is not given by the opp-table.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 94e57f055a5f..0af36f911bea 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -291,7 +291,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy)
 
 	transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
 	if (!transition_latency)
-		transition_latency = CPUFREQ_ETERNAL;
+		transition_latency = APPLE_DVFS_TRANSITION_TIMEOUT;
 
 	policy->cpuinfo.transition_latency = transition_latency;
 	policy->dvfs_possible_from_any_cpu = true;
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 03:19:34 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:19:34 +0800
Subject: [PATCH 7/7] cpufreq: apple-soc: Add Apple A7-A8X SoC cpufreq support
In-Reply-To: <20241211112244.18393-1-towinchenmi@gmail.com>
References: <20241211112244.18393-1-towinchenmi@gmail.com>
Message-ID: <20241211112244.18393-8-towinchenmi@gmail.com>

These SoCs only use 3 bits for p-states, and have a different
APPLE_DVFS_CMD_PS1 mask value.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 30 +++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 0af36f911bea..12ee9123a1c2 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -22,12 +22,14 @@
 #include <linux/pm_opp.h>
 #include <linux/slab.h>
 
-#define APPLE_DVFS_CMD			0x20
-#define APPLE_DVFS_CMD_BUSY		BIT(31)
-#define APPLE_DVFS_CMD_SET		BIT(25)
-#define APPLE_DVFS_CMD_PS2		GENMASK(15, 12)
-#define APPLE_DVFS_CMD_PS1		GENMASK(4, 0)
-#define APPLE_DVFS_CMD_PS1_SHIFT	0
+#define APPLE_DVFS_CMD				0x20
+#define APPLE_DVFS_CMD_BUSY			BIT(31)
+#define APPLE_DVFS_CMD_SET			BIT(25)
+#define APPLE_DVFS_CMD_PS1_S5L8960X		GENMASK(24, 22)
+#define APPLE_DVFS_CMD_PS1_S5L8960X_SHIFT	22
+#define APPLE_DVFS_CMD_PS2			GENMASK(15, 12)
+#define APPLE_DVFS_CMD_PS1			GENMASK(4, 0)
+#define APPLE_DVFS_CMD_PS1_SHIFT		0
 
 /* Same timebase as CPU counter (24MHz) */
 #define APPLE_DVFS_LAST_CHG_TIME	0x38
@@ -36,6 +38,9 @@
  * Apple ran out of bits and had to shift this in T8112...
  */
 #define APPLE_DVFS_STATUS			0x50
+#define APPLE_DVFS_STATUS_CUR_PS_S5L8960X	GENMASK(5, 3)
+#define APPLE_DVFS_STATUS_CUR_PS_SHIFT_S5L8960X	3
+#define APPLE_DVFS_STATUS_TGT_PS_S5L8960X	GENMASK(2, 0)
 #define APPLE_DVFS_STATUS_CUR_PS_T8103		GENMASK(7, 4)
 #define APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103	4
 #define APPLE_DVFS_STATUS_TGT_PS_T8103		GENMASK(3, 0)
@@ -72,6 +77,15 @@ struct apple_cpu_priv {
 
 static struct cpufreq_driver apple_soc_cpufreq_driver;
 
+static const struct apple_soc_cpufreq_info soc_s5l8960x_info = {
+	.has_ps2 = false,
+	.max_pstate = 7,
+	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_S5L8960X,
+	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_S5L8960X,
+	.ps1_mask = APPLE_DVFS_CMD_PS1_S5L8960X,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_S5L8960X_SHIFT,
+};
+
 static const struct apple_soc_cpufreq_info soc_t8103_info = {
 	.has_ps2 = true,
 	.max_pstate = 15,
@@ -99,6 +113,10 @@ static const struct apple_soc_cpufreq_info soc_default_info = {
 };
 
 static const struct of_device_id apple_soc_cpufreq_of_match[] __maybe_unused = {
+	{
+		.compatible = "apple,s5l8960x-cluster-cpufreq",
+		.data = &soc_s5l8960x_info,
+	},
 	{
 		.compatible = "apple,t8103-cluster-cpufreq",
 		.data = &soc_t8103_info,
-- 
2.47.1



From pgwipeout at gmail.com  Wed Dec 11 03:26:46 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Wed, 11 Dec 2024 06:26:46 -0500
Subject: [PATCH] arm64: dts: rockchip: Delete redundant RK3328 GMAC
 stability fixes
In-Reply-To: <e00f08d2351e82d6acd56271a68c7ed05b3362e8.1733901896.git.dsimic@manjaro.org>
References: <e00f08d2351e82d6acd56271a68c7ed05b3362e8.1733901896.git.dsimic@manjaro.org>
Message-ID: <CAMdYzYpnx=pHJ+oqshgfZFp=Mfqp3TcMmEForqJ+s9KuhkgnqA@mail.gmail.com>

On Wed, Dec 11, 2024 at 2:29?AM Dragan Simic <dsimic at manjaro.org> wrote:
>

Good Morning,

> Since the commit 8a469ee35606 ("arm64: dts: rockchip: Add txpbl node for
> RK3399/RK3328"), having "snps,txpbl" properties defined as Ethernet stability
> fixes in RK3328-based board dts(i) files is redundant, because that commit
> added the required fix to the RK3328 SoC dtsi, so let's delete them.
>
> It has been determined that the Ethernet stability fixes no longer require
> the "snps,rxpbl" and "snps,aal" properties, [1] out of which the latter also
> induces performance penalties, so let's delete these properties from the
> relevant RK3328-based board dts(i) files.

You may want to include snps,force_thresh_dma_mode in this group such
as on the rock64. It's even more limiting than snps,aal.

Otherwise,
Acked-by: Peter Geis <pgwipeout at gmail.com>

Very Respectfully,
Peter Geis

>
> This commit completes the removal of these redundant "snps,*" properties
> that was started by a patch from Peter Geis. [2]
>
> [1] https://lore.kernel.org/linux-rockchip/CAMdYzYpj3d7Rq0O0QjV4r6HEf_e07R0QAhPT2NheZdQV3TnQ6g at mail.gmail.com/
> [2] https://lore.kernel.org/linux-rockchip/20241210013010.81257-7-pgwipeout at gmail.com/
>
> Cc: Peter Geis <pgwipeout at gmail.com>
> Signed-off-by: Dragan Simic <dsimic at manjaro.org>
> ---
>  arch/arm64/boot/dts/rockchip/rk3328-a1.dts                | 1 -
>  arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi        | 1 -
>  arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 1 -
>  arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts         | 3 ---
>  4 files changed, 6 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
> index 824183e515da..24baaa7f1d8c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
> @@ -110,7 +110,6 @@ &gmac2io {
>         phy-supply = <&vcc_io>;
>         pinctrl-names = "default";
>         pinctrl-0 = <&rgmiim1_pins>;
> -       snps,aal;
>         snps,pbl = <0x4>;
>         tx_delay = <0x26>;
>         rx_delay = <0x11>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
> index f9fab35aed23..d5f129e304e5 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
> @@ -142,7 +142,6 @@ &gmac2io {
>         phy-supply = <&vcc_io_33>;
>         pinctrl-0 = <&rgmiim1_pins>;
>         pinctrl-names = "default";
> -       snps,aal;
>
>         mdio {
>                 compatible = "snps,dwmac-mdio";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
> index 181ec6de0019..9ec93f61433e 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
> @@ -113,7 +113,6 @@ &gmac2io {
>         phy-supply = <&vcc_io>;
>         pinctrl-0 = <&rgmiim1_pins>;
>         pinctrl-names = "default";
> -       snps,aal;
>
>         mdio {
>                 compatible = "snps,dwmac-mdio";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> index 3e08e2fd0a78..59dead1cc503 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> @@ -153,9 +153,6 @@ &gmac2io {
>         phy-supply = <&vcc_io>;
>         pinctrl-names = "default";
>         pinctrl-0 = <&rgmiim1_pins>;
> -       snps,aal;
> -       snps,rxpbl = <0x4>;
> -       snps,txpbl = <0x4>;
>         tx_delay = <0x26>;
>         rx_delay = <0x11>;
>         status = "okay";


From krzk at kernel.org  Wed Dec 11 03:29:05 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 11 Dec 2024 12:29:05 +0100
Subject: [PATCH v2] ASoC: dt-bindings: sound: atmel-at91sam9g20ek: convert
 to json-schema
In-Reply-To: <20241211-sound-atmel-at91sam9g20ek-v2-1-86a0e31e6af9@microchip.com>
References: <20241211-sound-atmel-at91sam9g20ek-v2-1-86a0e31e6af9@microchip.com>
Message-ID: <0358a6ac-4037-444b-8e65-4e5afa29e8c3@kernel.org>

On 11/12/2024 10:46, Balakrishnan Sambath wrote:
> +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.
> +    items:
> +      enum:
> +        # Board Connectors
> +        - Ext Spk
> +        - Int Mic
> +
> +        # CODEC Pins
> +        - LOUT
> +        - ROUT
> +        - LHPOUT
> +        - RHPOUT
> +        - LLINEIN
> +        - RLINEIN
> +        - MICIN

As previously questioned, I don't think you can create infinite amount
of pairs out of it. Assuming you always connect board with codec
(because codec-codec are already defined inside the codec), you can have
max 14 pairs, but most likely less in practice.

Best regards,
Krzysztof


From charan.pedumuru at microchip.com  Wed Dec 11 03:29:22 2024
From: charan.pedumuru at microchip.com (Charan Pedumuru)
Date: Wed, 11 Dec 2024 16:59:22 +0530
Subject: [PATCH] dt-bindings: mfd: atmel,at91sam9260: Convert to json
 schema
Message-ID: <20241211-matrix-v1-1-5ef0104a3af4@microchip.com>

Convert old text based binding to json schema.
Changes during conversion:
Add a fallback for all compatibles as the IP core is compatible
with `syscon`.

Signed-off-by: Charan Pedumuru <charan.pedumuru at microchip.com>
---
 .../bindings/mfd/atmel,at91sam9260-matrix.yaml     | 54 ++++++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-matrix.txt       | 26 -----------
 2 files changed, 54 insertions(+), 26 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml
new file mode 100644
index 000000000000..0e827882823f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/atmel,at91sam9260-matrix.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip AT91 Bus Matrix
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+
+description:
+  The Bus Matrix (MATRIX) implements a multi-layer AHB, based on the
+  AHB-Lite protocol, that enables parallel access paths between multiple
+  masters and slaves in a system, thus increasing the overall bandwidth.
+
+properties:
+  compatible:
+    anyOf:
+      - items:
+          - enum:
+              - atmel,at91sam9260-matrix
+              - atmel,at91sam9261-matrix
+              - atmel,at91sam9263-matrix
+              - atmel,at91sam9rl-matrix
+              - atmel,at91sam9g45-matrix
+              - atmel,at91sam9n12-matrix
+              - atmel,at91sam9x5-matrix
+              - atmel,sama5d3-matrix
+          - const: syscon
+      - items:
+          - const: microchip,sam9x60-matrix
+          - const: atmel,at91sam9x5-matrix
+          - const: syscon
+      - items:
+          - const: microchip,sam9x7-matrix
+          - const: atmel,at91sam9x5-matrix
+          - const: syscon
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    matrix at ffffec00 {
+        compatible = "atmel,sama5d3-matrix", "syscon";
+        reg = <0xffffec00 0x200>;
+    };
diff --git a/Documentation/devicetree/bindings/mfd/atmel-matrix.txt b/Documentation/devicetree/bindings/mfd/atmel-matrix.txt
deleted file mode 100644
index 6e5f83614e83..000000000000
--- a/Documentation/devicetree/bindings/mfd/atmel-matrix.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-* Device tree bindings for Atmel Bus Matrix
-
-The Bus Matrix registers are used to configure Atmel SoCs internal bus
-behavior (master/slave priorities, undefined burst length type, ...)
-
-Required properties:
-- compatible:		Should be one of the following
-			"atmel,at91sam9260-matrix", "syscon"
-			"atmel,at91sam9261-matrix", "syscon"
-			"atmel,at91sam9263-matrix", "syscon"
-			"atmel,at91sam9rl-matrix", "syscon"
-			"atmel,at91sam9g45-matrix", "syscon"
-			"atmel,at91sam9n12-matrix", "syscon"
-			"atmel,at91sam9x5-matrix", "syscon"
-			"atmel,sama5d3-matrix", "syscon"
-			"microchip,sam9x60-matrix", "syscon"
-			"microchip,sam9x7-matrix", "atmel,at91sam9x5-matrix", "syscon"
-- reg:			Contains offset/length value of the Bus Matrix
-			memory region.
-
-Example:
-
-matrix: matrix at ffffec00 {
-	compatible = "atmel,sama5d3-matrix", "syscon";
-	reg = <0xffffec00 0x200>;
-};

---
base-commit: 1b2ab8149928c1cea2d7eca30cd35bb7fe014053
change-id: 20241210-matrix-30021676fb6f

Best regards,
-- 
Charan Pedumuru <charan.pedumuru at microchip.com>



From christian.loehle at arm.com  Wed Dec 11 03:32:41 2024
From: christian.loehle at arm.com (Christian Loehle)
Date: Wed, 11 Dec 2024 11:32:41 +0000
Subject: [PATCH 6/7] cpufreq: apple-soc: Set fallback transition latency
 to APPLE_DVFS_TRANSITION_TIMEOUT
In-Reply-To: <20241211112244.18393-7-towinchenmi@gmail.com>
References: <20241211112244.18393-1-towinchenmi@gmail.com>
 <20241211112244.18393-7-towinchenmi@gmail.com>
Message-ID: <3fab85df-371a-410b-a8de-40b6a62e9efe@arm.com>

On 12/11/24 11:19, Nick Chan wrote:
> The driver already assumes transitions will not take longer than
> APPLE_DVFS_TRANSITION_TIMEOUT in apple_soc_cpufreq_set_target(), so it
> makes little sense to set CPUFREQ_ETERNAL as the transition latency
> when the transistion latency is not given by the opp-table.
> 
> Signed-off-by: Nick Chan <towinchenmi at gmail.com>
> ---
>  drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
> index 94e57f055a5f..0af36f911bea 100644
> --- a/drivers/cpufreq/apple-soc-cpufreq.c
> +++ b/drivers/cpufreq/apple-soc-cpufreq.c
> @@ -291,7 +291,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy)
>  
>  	transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
>  	if (!transition_latency)
> -		transition_latency = CPUFREQ_ETERNAL;
> +		transition_latency = APPLE_DVFS_TRANSITION_TIMEOUT;

transition_latency is in ns, APPLE_DVFS_TRANSITION_TIMEOUT in us.
LGTM otherwise.

>  
>  	policy->cpuinfo.transition_latency = transition_latency;
>  	policy->dvfs_possible_from_any_cpu = true;



From towinchenmi at gmail.com  Wed Dec 11 03:34:36 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:34:36 +0800
Subject: [PATCH v4 0/3] Apple DWI backlight driver
Message-ID: <20241211113512.19009-1-towinchenmi@gmail.com>

Apple SoCs come with a 2-wire interface named DWI. On some iPhones, iPads
and iPod touches the backlight controller is connected via this interface.
This series adds a backlight driver for backlight controllers connected
this way.

Changes since v3:
- $ref to common.yaml in bindings
- (and then additionalProperties is changed to unevaluatedProperties)
- Use hex everywhere in bindings example
- Use sizeof(*dwi_bl) instead of the type of the struct when doing
devm_kzalloc()
- Use devm_platform_get_and_ioremap_resource() in driver
- Fix sorting in drivers/video/backlight/Makefile
- In drivers/video/backlight/Kconfig, move config to right after
BACKLIGHT_APPLE
- Explain this driver being completely different from apple_bl

v3: https://lore.kernel.org/asahi/20241209075908.140014-1-towinchenmi at gmail.com/T

Changes since v2:
- Add missing includes in driver
- Fix file path in MAINTAINERS

v2: https://lore.kernel.org/asahi/20241207130433.30351-1-towinchenmi at gmail.com/T

Changes since v1:
- Fixed dt-bindings $id.
- Make power-domains an optional property in dt-bindings.
- Added missing error checking after devm_ioremap_resource() in
dwi_bl_probe().

v1: https://lore.kernel.org/asahi/20241206172735.4310-1-towinchenmi at gmail.com/T

Nick Chan
---

Nick Chan (3):
  dt-bindings: leds: backlight: apple,dwi-bl: Add Apple DWI backlight
  backlight: dwi_bl: Add Apple DWI backlight driver
  MAINTAINERS: Add entries for Apple DWI backlight controller

 .../bindings/leds/backlight/apple,dwi-bl.yaml |  57 ++++++++
 MAINTAINERS                                   |   2 +
 drivers/video/backlight/Kconfig               |  12 ++
 drivers/video/backlight/Makefile              |   1 +
 drivers/video/backlight/dwi_bl.c              | 122 ++++++++++++++++++
 5 files changed, 194 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
 create mode 100644 drivers/video/backlight/dwi_bl.c


base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 03:34:37 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:34:37 +0800
Subject: [PATCH v4 1/3] dt-bindings: leds: backlight: apple,dwi-bl: Add Apple DWI backlight
In-Reply-To: <20241211113512.19009-1-towinchenmi@gmail.com>
References: <20241211113512.19009-1-towinchenmi@gmail.com>
Message-ID: <20241211113512.19009-2-towinchenmi@gmail.com>

Add backlight controllers attached via Apple DWI 2-wire interface.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../bindings/leds/backlight/apple,dwi-bl.yaml | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml

diff --git a/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
new file mode 100644
index 000000000000..29caeb356e6f
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/apple,dwi-bl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple DWI 2-Wire Interface Backlight Controller
+
+maintainers:
+  - Nick Chan <towinchenmi at gmail.com>
+
+description:
+  Apple SoCs contain a 2-wire interface called DWI. On some Apple iPhones,
+  iPads and iPod touches with a LCD display, 1-2 backlight controllers
+  are connected via DWI. Interfacing with DWI controls all backlight
+  controllers at the same time. As such, the backlight controllers are
+  treated as a single controller regardless of the underlying
+  configuration.
+
+allOf:
+  - $ref: common.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,s5l8960x-dwi-bl
+          - apple,t7000-dwi-bl
+          - apple,s8000-dwi-bl
+          - apple,t8010-dwi-bl
+          - apple,t8015-dwi-bl
+      - const: apple,dwi-bl
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      dwi_bl: backlight at 20e200010 {
+        compatible = "apple,s5l8960x-dwi-bl", "apple,dwi-bl";
+        reg = <0x2 0x0e200010 0x0 0x8>;
+        power-domains = <&ps_dwi>;
+      };
+    };
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 03:34:38 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:34:38 +0800
Subject: [PATCH v4 2/3] backlight: dwi_bl: Add Apple DWI backlight driver
In-Reply-To: <20241211113512.19009-1-towinchenmi@gmail.com>
References: <20241211113512.19009-1-towinchenmi@gmail.com>
Message-ID: <20241211113512.19009-3-towinchenmi@gmail.com>

Add driver for backlight controllers attached via Apple DWI 2-wire
interface, which is found on some Apple iPhones, iPads and iPod touches
with a LCD display.

Although there is an existing apple_bl driver, it is for backlight
controllers on Intel Macs attached via PCI, which is completely different
from the Samsung-derived DWI block.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/video/backlight/Kconfig  |  12 +++
 drivers/video/backlight/Makefile |   1 +
 drivers/video/backlight/dwi_bl.c | 122 +++++++++++++++++++++++++++++++
 3 files changed, 135 insertions(+)
 create mode 100644 drivers/video/backlight/dwi_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 3614a5d29c71..debb1326df63 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -290,6 +290,18 @@ config BACKLIGHT_APPLE
 	  If you have an Intel-based Apple say Y to enable a driver for its
 	  backlight.
 
+config BACKLIGHT_APPLE_DWI
+	tristate "Apple DWI 2-Wire Interface Backlight Driver"
+	depends on ARCH_APPLE || COMPILE_TEST
+	default y
+	help
+	  Say Y to enable the backlight driver for backlight controllers
+	  attached via the Apple DWI 2-wire interface which is found in some
+	  Apple iPhones, iPads and iPod touches.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called dwi_bl.
+
 config BACKLIGHT_QCOM_WLED
 	tristate "Qualcomm PMIC WLED Driver"
 	select REGMAP
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 8fc98f760a8a..45cc80d9ae22 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_BACKLIGHT_ADP5520)		+= adp5520_bl.o
 obj-$(CONFIG_BACKLIGHT_ADP8860)		+= adp8860_bl.o
 obj-$(CONFIG_BACKLIGHT_ADP8870)		+= adp8870_bl.o
 obj-$(CONFIG_BACKLIGHT_APPLE)		+= apple_bl.o
+obj-$(CONFIG_BACKLIGHT_APPLE_DWI)	+= dwi_bl.o
 obj-$(CONFIG_BACKLIGHT_AS3711)		+= as3711_bl.o
 obj-$(CONFIG_BACKLIGHT_BD6107)		+= bd6107.o
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE)	+= backlight.o
diff --git a/drivers/video/backlight/dwi_bl.c b/drivers/video/backlight/dwi_bl.c
new file mode 100644
index 000000000000..59e5cad0fbd8
--- /dev/null
+++ b/drivers/video/backlight/dwi_bl.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Driver for backlight controllers attached via Apple DWI 2-wire interface
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include <linux/backlight.h>
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#define DWI_BL_CTL			0x0
+#define DWI_BL_CTL_SEND1		BIT(0)
+#define DWI_BL_CTL_SEND2		BIT(4)
+#define DWI_BL_CTL_SEND3		BIT(5)
+#define DWI_BL_CTL_LE_DATA		BIT(6)
+/* Only used on Apple A9 and later */
+#define DWI_BL_CTL_SEND4		BIT(12)
+
+#define DWI_BL_CMD			0x4
+#define DWI_BL_CMD_TYPE			GENMASK(31, 28)
+#define DWI_BL_CMD_TYPE_SET_BRIGHTNESS	0xa
+#define DWI_BL_CMD_DATA			GENMASK(10, 0)
+
+#define DWI_BL_CTL_SEND			(DWI_BL_CTL_SEND1 | \
+					 DWI_BL_CTL_SEND2 | \
+					 DWI_BL_CTL_SEND3 | \
+					 DWI_BL_CTL_LE_DATA | \
+					 DWI_BL_CTL_SEND4)
+
+#define DWI_BL_MAX_BRIGHTNESS		2047
+
+struct apple_dwi_bl {
+	void __iomem *base;
+};
+
+static int dwi_bl_update_status(struct backlight_device *bl)
+{
+	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
+
+	int brightness = backlight_get_brightness(bl);
+
+	u32 cmd = 0;
+
+	cmd |= FIELD_PREP(DWI_BL_CMD_DATA, brightness);
+	cmd |= FIELD_PREP(DWI_BL_CMD_TYPE, DWI_BL_CMD_TYPE_SET_BRIGHTNESS);
+
+	writel(cmd, dwi_bl->base + DWI_BL_CMD);
+	writel(DWI_BL_CTL_SEND, dwi_bl->base + DWI_BL_CTL);
+
+	return 0;
+}
+
+static int dwi_bl_get_brightness(struct backlight_device *bl)
+{
+	struct apple_dwi_bl *dwi_bl = bl_get_data(bl);
+
+	u32 cmd = readl(dwi_bl->base + DWI_BL_CMD);
+
+	return FIELD_GET(DWI_BL_CMD_DATA, cmd);
+}
+
+static const struct backlight_ops dwi_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = dwi_bl_get_brightness,
+	.update_status	= dwi_bl_update_status
+};
+
+static int dwi_bl_probe(struct platform_device *dev)
+{
+	struct apple_dwi_bl *dwi_bl;
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct resource *res;
+
+	dwi_bl = devm_kzalloc(&dev->dev, sizeof(*dwi_bl), GFP_KERNEL);
+	if (!dwi_bl)
+		return -ENOMEM;
+
+	dwi_bl->base = devm_platform_get_and_ioremap_resource(dev, 0, &res);
+	if (IS_ERR(dwi_bl->base))
+		return PTR_ERR(dwi_bl->base);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = DWI_BL_MAX_BRIGHTNESS;
+
+	bl = devm_backlight_device_register(&dev->dev, dev->name, &dev->dev,
+					dwi_bl, &dwi_bl_ops, &props);
+	if (IS_ERR(bl))
+		return PTR_ERR(bl);
+
+	platform_set_drvdata(dev, dwi_bl);
+
+	bl->props.brightness = dwi_bl_get_brightness(bl);
+
+	return 0;
+}
+
+static const struct of_device_id dwi_bl_of_match[] = {
+	{ .compatible = "apple,dwi-bl" },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, dwi_bl_of_match);
+
+static struct platform_driver dwi_bl_driver = {
+	.driver		= {
+		.name	= "dwi-bl",
+		.of_match_table = dwi_bl_of_match
+	},
+	.probe		= dwi_bl_probe,
+};
+
+module_platform_driver(dwi_bl_driver);
+
+MODULE_DESCRIPTION("Apple DWI Backlight Driver");
+MODULE_AUTHOR("Nick Chan <towinchenmi at gmail.com>");
+MODULE_LICENSE("Dual MIT/GPL");
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 03:34:39 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:34:39 +0800
Subject: [PATCH v4 3/3] MAINTAINERS: Add entries for Apple DWI backlight controller
In-Reply-To: <20241211113512.19009-1-towinchenmi@gmail.com>
References: <20241211113512.19009-1-towinchenmi@gmail.com>
Message-ID: <20241211113512.19009-4-towinchenmi@gmail.com>

Add MAINTAINERS entries for the driver.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 17daa9ee9384..3a7dec3f9a5a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2196,6 +2196,7 @@ F:	Documentation/devicetree/bindings/i2c/apple,i2c.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/apple,*
 F:	Documentation/devicetree/bindings/iommu/apple,dart.yaml
 F:	Documentation/devicetree/bindings/iommu/apple,sart.yaml
+F:	Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml
 F:	Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
 F:	Documentation/devicetree/bindings/net/bluetooth/brcm,bcm4377-bluetooth.yaml
 F:	Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml
@@ -2221,6 +2222,7 @@ F:	drivers/nvmem/apple-efuses.c
 F:	drivers/pinctrl/pinctrl-apple-gpio.c
 F:	drivers/pwm/pwm-apple.c
 F:	drivers/soc/apple/*
+F:	drivers/video/backlight/dwi_bl.c
 F:	drivers/watchdog/apple_wdt.c
 F:	include/dt-bindings/interrupt-controller/apple-aic.h
 F:	include/dt-bindings/pinctrl/apple.h
-- 
2.47.1



From michal.simek at amd.com  Wed Dec 11 03:36:29 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 12:36:29 +0100
Subject: [PATCH V2 0/2] Add atomic transfer support to i2c-xiic
In-Reply-To: <20241210095242.1982770-1-manikanta.guntupalli@amd.com>
References: <20241210095242.1982770-1-manikanta.guntupalli@amd.com>
Message-ID: <ae05a342-1b9b-47b6-92fe-502505abb111@amd.com>

+Kees

On 12/10/24 10:52, Manikanta Guntupalli wrote:
> This patch series adds atomic transfer support to the i2c-xiic
> controller.
> ---
> Changes for V2:
> Remove NULL checks for tx_msg and rx_msg, as __xiic_start_xfer() already
> has checks.
> 
> Manikanta Guntupalli (2):
>    i2c: xiic: Relocate xiic_i2c_runtime_suspend and
>      xiic_i2c_runtime_resume to facilitate atomic mode
>    i2c: xiic: Add atomic transfer support
> 
>   drivers/i2c/busses/i2c-xiic.c | 281 +++++++++++++++++++++++++++-------
>   1 file changed, 227 insertions(+), 54 deletions(-)
> 

Kees should be in CC on this because he was reviewing v1 version of this.

 From my perspective this is fine.

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

Thanks,
Michal


From towinchenmi at gmail.com  Wed Dec 11 03:19:27 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Wed, 11 Dec 2024 19:19:27 +0800
Subject: [PATCH 0/7] Apple A7-A11, T2 SoC cpufreq support
Message-ID: <20241211112244.18393-1-towinchenmi@gmail.com>

This series add driver support for cpufreq Apple A7-A11, T2 SoCs.
Device Tree nodes will be included in another series.

Nick Chan

---

Hector Martin (1):
  cpufreq: apple-soc: Drop setting the PS2 field on M2+

Nick Chan (6):
  dt-bindings: cpufreq: apple,cluster-cpufreq: Add A7-A11, T2
    compatibles
  cpufreq: apple-soc: Allow per-SoC configuration of APPLE_DVFS_CMD_PS1
  cpufreq: apple-soc: Use 32-bit read for status register
  cpufreq: apple-soc: Increase cluster switch timeout to 400us
  cpufreq: apple-soc: Set fallback transition latency to
    APPLE_DVFS_TRANSITION_TIMEOUT
  cpufreq: apple-soc: Add Apple A7-A8X SoC cpufreq support

 .../cpufreq/apple,cluster-cpufreq.yaml        | 10 +++-
 drivers/cpufreq/apple-soc-cpufreq.c           | 56 +++++++++++++++----
 2 files changed, 54 insertions(+), 12 deletions(-)


base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
-- 
2.47.1



From Jonathan.Cameron at huawei.com  Wed Dec 11 03:39:09 2024
From: Jonathan.Cameron at huawei.com (Jonathan Cameron)
Date: Wed, 11 Dec 2024 11:39:09 +0000
Subject: [PATCH v2 1/2] perf: Fujitsu: Add the Uncore MAC PMU driver
In-Reply-To: <20241122061753.2598688-2-fj5100bi@fujitsu.com>
References: <20241122061753.2598688-1-fj5100bi@fujitsu.com>
	<20241122061753.2598688-2-fj5100bi@fujitsu.com>
Message-ID: <20241211113909.000039d0@huawei.com>

On Fri, 22 Nov 2024 06:17:52 +0000
Yoshihiro Furudera <fj5100bi at fujitsu.com> wrote:

> This adds a new dynamic PMU to the Perf Events framework to program and
> control the Uncore MAC PMUs in Fujitsu chips.
> 
> This driver was created with reference to drivers/perf/qcom_l3_pmu.c.
> 
> This driver exports formatting and event information to sysfs so it can
> be used by the perf user space tools with the syntaxes:
> 
> perf stat -e mac_iod0_mac0_ch0/ea-mac/ ls
> perf stat -e mac_iod0_mac0_ch0/event=0x80/ ls
> 
> FUJITSU-MONAKA Specification URL:
> https://github.com/fujitsu/FUJITSU-MONAKA
> 
> Signed-off-by: Yoshihiro Furudera <fj5100bi at fujitsu.com>
Hi,

A few comments inline.

Thanks,

Jonathan

> diff --git a/drivers/perf/fujitsu_mac_pmu.c b/drivers/perf/fujitsu_mac_pmu.c
> new file mode 100644
> index 000000000000..810f51f798a0
> --- /dev/null
> +++ b/drivers/perf/fujitsu_mac_pmu.c

> +/* Number of counters on each PMU */
> +#define MAC_NUM_COUNTERS  8
> +/* Mask for the event type field within perf_event_attr.config and EVTYPE reg */
> +#define MAC_EVTYPE_MASK   0xFF
> +
> +/* Perfmon registers */
> +#define MAC_PM_EVCNTR(__cntr) (0x000 + ((__cntr) & 0x7) * 8)
> +#define MAC_PM_CNTCTL(__cntr) (0x100 + ((__cntr) & 0x7) * 8)
> +#define MAC_PM_EVTYPE(__cntr) (0x200 + ((__cntr) & 0x7) * 8)

Do you need the masking?  As far as I can tell the idx that goes
into these calls is capped as below MAC_NUM_COUNTERS so
that masking operation will never do anything.  I hope the only
other value that occurs (-1) is never used with these.


> +#define MAC_PM_CR         0x400
> +#define MAC_PM_CNTENSET   0x410
> +#define MAC_PM_CNTENCLR   0x418
> +#define MAC_PM_INTENSET   0x420
> +#define MAC_PM_INTENCLR   0x428
> +#define MAC_PM_OVSR       0x440
> +
> +/* MAC_PM_CNTCTLx */
> +#define PMCNT_RESET           0
> +
> +/* MAC_PM_EVTYPEx */
> +#define EVSEL(__val)          ((__val) & MAC_EVTYPE_MASK)

FIELD_GET() and just use the mask inline.

> +
> +/* MAC_PM_CR */
> +#define PM_RESET              (1UL << 1)

BIT(1)

> +#define PM_ENABLE             (1UL << 0)

BIT(0)

> +
> +/* MAC_PM_CNTENSET */
> +#define PMCNTENSET(__cntr)    (1UL << ((__cntr) & 0x7))
> +
> +/* MAC_PM_CNTENCLR */
> +#define PMCNTENCLR(__cntr)    (1UL << ((__cntr) & 0x7))
With above note on whether the mask is needed and the small size
of that shift. BIT(__cntr) should work.

> +#define PM_CNTENCLR_RESET     0xFF
> +
> +/* MAC_PM_INTENSET */
> +#define PMINTENSET(__cntr)    (1UL << ((__cntr) & 0x7))
> +
> +/* MAC_PM_INTENCLR */
> +#define PMINTENCLR(__cntr)    (1UL << ((__cntr) & 0x7))
> +#define PM_INTENCLR_RESET     0xFF
> +
> +/* MAC_PM_OVSR */
> +#define PMOVSRCLR(__cntr)     (1UL << ((__cntr) & 0x7))
> +#define PMOVSRCLR_RESET       0xFF


> +static int fujitsu_mac__event_init(struct perf_event *event)
> +{
> +	struct mac_pmu *macpmu = to_mac_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +
> +	/* Is the event for this PMU? */
> +	if (event->attr.type != event->pmu->type)
> +		return -ENOENT;
> +
> +	/*
> +	 * Sampling not supported
> +	 * since these events are not core-attributable.
Strange line wrap.  
	 * Sampling not supported since these events are not
	 * core-attributable.

would be more conventional.

> +	 */
> +	if (hwc->sample_period)
> +		return -EINVAL;
> +
> +	/*
> +	 * Task mode not available, we run the counters as socket counters,
> +	 * not attributable to any CPU and therefore cannot attribute per-task.
> +	 */
> +	if (event->cpu < 0)
> +		return -EINVAL;
> +
> +	/* Validate the group */
> +	if (!fujitsu_mac__validate_event_group(event))
> +		return -EINVAL;
> +
> +	hwc->idx = -1;
> +
> +	/*
> +	 * Many perf core operations (eg. events rotation) operate on a
> +	 * single CPU context. This is obvious for CPU PMUs, where one
> +	 * expects the same sets of events being observed on all CPUs,
> +	 * but can lead to issues for off-core PMUs, like this one, where
> +	 * each event could be theoretically assigned to a different CPU.
> +	 * To mitigate this, we enforce CPU assignment to one designated
> +	 * processor (the one described in the "cpumask" attribute exported
> +	 * by the PMU device). perf user space tools honor this and avoid
> +	 * opening more than one copy of the events.
> +	 */
> +	event->cpu = cpumask_first(&macpmu->cpumask);
> +
> +	return 0;
> +}
>
> +
> +static void fujitsu_mac__event_del(struct perf_event *event, int flags)
> +{
> +	struct mac_pmu *macpmu = to_mac_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +
> +	/* Stop and clean up */
> +	fujitsu_mac__event_stop(event,  flags | PERF_EF_UPDATE);

Drop the extra space before flags.

> +	macpmu->events[hwc->idx] = NULL;
> +	bitmap_release_region(macpmu->used_mask, hwc->idx, 0);
> +
> +	/* Propagate changes to the userspace mapping. */
> +	perf_event_update_userpage(event);
> +}



...

> +static ssize_t cpumask_show(struct device *dev,
> +			    struct device_attribute *attr, char *buf)
> +{
> +	struct mac_pmu *macpmu = to_mac_pmu(dev_get_drvdata(dev));
If as suggested below you used an index to store the cpu rather than
a one hot mask, you'd need to create the mask here to print it.
> +
> +	return cpumap_print_to_pagebuf(true, buf, &macpmu->cpumask);
> +}

...

> +static int fujitsu_mac_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
> +{
> +	struct mac_pmu *macpmu = hlist_entry_safe(node, struct mac_pmu, node);
> +
> +	/* If there is not a CPU/PMU association pick this CPU */
> +	if (cpumask_empty(&macpmu->cpumask))
> +		cpumask_set_cpu(cpu, &macpmu->cpumask);
As below. Seems like just storing the CPU index (and using -1 for not yet
set) would be simpler than
> +
> +	return 0;
> +}
> +
> +static int fujitsu_mac_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
> +{
> +	struct mac_pmu *macpmu = hlist_entry_safe(node, struct mac_pmu, node);
> +	unsigned int target;
> +
> +	if (!cpumask_test_and_clear_cpu(cpu, &macpmu->cpumask))

If you are only ever going to set one bit in the mask, why not just
store the CPU index instead?

> +		return 0;
> +
> +	target = cpumask_any_but(cpu_online_mask, cpu);
> +	if (target >= nr_cpu_ids)
> +		return 0;
> +
> +	perf_pmu_migrate_context(&macpmu->pmu, cpu, target);
> +	cpumask_set_cpu(target, &macpmu->cpumask);
> +
> +	return 0;
> +}
> +
> +static int fujitsu_mac_pmu_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct acpi_device *acpi_dev;
> +	struct mac_pmu *macpmu;
> +	struct resource *memrc;
> +	char *name;
> +	int ret;
> +	u64 uid;
> +
> +	acpi_dev = ACPI_COMPANION(dev);
> +	if (!acpi_dev)
> +		return -ENODEV;
> +
> +	ret = acpi_dev_uid_to_integer(acpi_dev, &uid);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "unable to read ACPI uid\n");
> +
> +	macpmu = devm_kzalloc(dev, sizeof(*macpmu), GFP_KERNEL);
> +	name = devm_kasprintf(dev, GFP_KERNEL, "mac_iod%llu_mac%llu_ch%llu",
> +			  (uid >> 8) & 0xF, (uid >> 4) & 0xF, uid & 0xF);
> +	if (!macpmu)
> +		return -ENOMEM;

Why allocate two before checking either?  That's an unusual pattern.
Check if macpmu is NULL before trying to allocate name.

> +
> +	if (!name)
> +		return -ENOMEM;
> +
> +	macpmu->pmu = (struct pmu) {
> +		.parent		= dev,
> +		.task_ctx_nr	= perf_invalid_context,
> +
> +		.pmu_enable	= fujitsu_mac__pmu_enable,
> +		.pmu_disable	= fujitsu_mac__pmu_disable,
> +		.event_init	= fujitsu_mac__event_init,
> +		.add		= fujitsu_mac__event_add,
> +		.del		= fujitsu_mac__event_del,
> +		.start		= fujitsu_mac__event_start,
> +		.stop		= fujitsu_mac__event_stop,
> +		.read		= fujitsu_mac__event_read,
> +
> +		.attr_groups	= fujitsu_mac_pmu_attr_grps,
> +		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE
> +	};
> +
> +	macpmu->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &memrc);
> +	if (IS_ERR(macpmu->regs))
> +		return PTR_ERR(macpmu->regs);
> +
> +	fujitsu_mac__init(macpmu);
> +
> +	ret = platform_get_irq(pdev, 0);
> +	if (ret <= 0)
> +		return ret;
> +
> +	ret = devm_request_irq(dev, ret, fujitsu_mac__handle_irq, 0,
> +			       name, macpmu);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Request for IRQ failed for slice @%pa\n",
> +						&memrc->start);
> +
> +	/* Add this instance to the list used by the offline callback */
> +	ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_FUJITSU_MAC_ONLINE, &macpmu->node);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Error %d registering hotplug", ret);
> +
> +	ret = perf_pmu_register(&macpmu->pmu, name, -1);
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "Failed to register MAC PMU (%d)\n", ret);

dev_err_probe() already pretty prints the return value.  No need to print the numeric
value as well. 

> +
> +	dev_dbg(dev, "Registered %s, type: %d\n", name, macpmu->pmu.type);
> +
> +	return 0;
> +}

> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> index a04b73c40173..21006d1cda59 100644
> --- a/include/linux/cpuhotplug.h
> +++ b/include/linux/cpuhotplug.h
> @@ -228,6 +228,7 @@ enum cpuhp_state {
>  	CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE,
>  	CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
>  	CPUHP_AP_PERF_ARM_MRVL_PEM_ONLINE,
> +	CPUHP_AP_PERF_ARM_FUJITSU_MAC_ONLINE,

If the DYN option works for you, I think we should go with that.
Some more recent PMU drivers are already using it without problem.

>  	CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
>  	CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
>  	CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,



From michal.simek at amd.com  Wed Dec 11 03:48:59 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 12:48:59 +0100
Subject: [PATCH v2] arm64: zynqmp: add clock-output-names property in
 clock nodes
In-Reply-To: <20241122095712.1166883-1-naman.trivedimanojbhai@amd.com>
References: <20241122095712.1166883-1-naman.trivedimanojbhai@amd.com>
Message-ID: <844282e1-1c69-4d66-bd98-f9188901c7ac@amd.com>



On 11/22/24 10:57, Naman Trivedi wrote:
> Add clock-output-names property to clock nodes, so that the resulting
> clock name do not change when clock node name is changed.
> Also, replace underscores with hyphens in the clock node names as per
> dt-schema rule.
> 
> Signed-off-by: Naman Trivedi <naman.trivedimanojbhai at amd.com>
> ---
> v1: https://lore.kernel.org/all/c5d6effa-bdcf-49e3-a4bf-3713db889b70 at kernel.org
> Changes v1 -> v2:
> - Fix the clock node names by replacing underscore with hyphen.
> ---
>   arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi | 15 ++++++++++-----
>   1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> index 60d1b1acf9a0..385fed8a852a 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> @@ -10,39 +10,44 @@
>   
>   #include <dt-bindings/clock/xlnx-zynqmp-clk.h>
>   / {
> -	pss_ref_clk: pss_ref_clk {
> +	pss_ref_clk: pss-ref-clk {
>   		bootph-all;
>   		compatible = "fixed-clock";
>   		#clock-cells = <0>;
>   		clock-frequency = <33333333>;
> +		clock-output-names = "pss_ref_clk";
>   	};
>   
> -	video_clk: video_clk {
> +	video_clk: video-clk {
>   		bootph-all;
>   		compatible = "fixed-clock";
>   		#clock-cells = <0>;
>   		clock-frequency = <27000000>;
> +		clock-output-names = "video_clk";
>   	};
>   
> -	pss_alt_ref_clk: pss_alt_ref_clk {
> +	pss_alt_ref_clk: pss-alt-ref-clk {
>   		bootph-all;
>   		compatible = "fixed-clock";
>   		#clock-cells = <0>;
>   		clock-frequency = <0>;
> +		clock-output-names = "pss_alt_ref_clk";
>   	};
>   
> -	gt_crx_ref_clk: gt_crx_ref_clk {
> +	gt_crx_ref_clk: gt-crx-ref-clk {
>   		bootph-all;
>   		compatible = "fixed-clock";
>   		#clock-cells = <0>;
>   		clock-frequency = <108000000>;
> +		clock-output-names = "gt_crx_ref_clk";
>   	};
>   
> -	aux_ref_clk: aux_ref_clk {
> +	aux_ref_clk: aux-ref-clk {
>   		bootph-all;
>   		compatible = "fixed-clock";
>   		#clock-cells = <0>;
>   		clock-frequency = <27000000>;
> +		clock-output-names = "aux_ref_clk";
>   	};
>   };
>   

Apply.

M


From andrei.simion at microchip.com  Wed Dec 11 04:03:17 2024
From: andrei.simion at microchip.com (Andrei Simion)
Date: Wed, 11 Dec 2024 14:03:17 +0200
Subject: [PATCH v2] ASoC: dt-bindings: sound: atmel-at91sam9g20ek: convert to json-schema
In-Reply-To: <20241211-sound-atmel-at91sam9g20ek-v2-1-86a0e31e6af9@microchip.com>
References: <20241211-sound-atmel-at91sam9g20ek-v2-1-86a0e31e6af9@microchip.com>
Message-ID: <20241211120316.22494-1-andrei.simion@microchip.com>

Hi,

On 11.12.2024 11:46, 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>
> ---
> Changes in v2:
> - Add missing CODEC pin options to 'atmel,audio-routing' items.
> - Drop 'minItems' from 'atmel,audio-routing' since enum defines valid connections.
> - Add subsystem tag to subject.
> - Add blank line between properties and fix typo.
> - Add audio complex description.
> - Link to v1: https://lore.kernel.org/lkml/20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b at microchip.com
> ---
>  .../bindings/sound/atmel,at91sam9g20ek-wm8731.yaml | 70 ++++++++++++++++++++++
>  .../sound/atmel-at91sam9g20ek-wm8731-audio.txt     | 26 --------
>  2 files changed, 70 insertions(+), 26 deletions(-)

I recommend you to remove from title the word 'sound'.
You can check the commit history of the Documentation/devicetree/bindings/sound/
before you write the commit title.

Best Regards,
Andrei Simion





From peter.griffin at linaro.org  Wed Dec 11 04:13:39 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 11 Dec 2024 12:13:39 +0000
Subject: [PATCH v3 2/3] firmware: add exynos ACPM protocol driver
In-Reply-To: <2eedbbe1-6b4c-427b-a369-5b08dc27deaf@linaro.org>
References: <20241205175345.201595-1-tudor.ambarus@linaro.org>
 <20241205175345.201595-3-tudor.ambarus@linaro.org> <ce757b8e-4e6c-4ba9-9483-b57e6e230fdf@linaro.org>
 <vxqi23hxw7bmtfs5wk3u7szganpv5aa74b26xrvpmbehkltodw@dpum7zrxdz44> <2eedbbe1-6b4c-427b-a369-5b08dc27deaf@linaro.org>
Message-ID: <CADrjBPo_YmTuuW9c3LtWzMp7Sf4365e2bxuuYBUiFPPc42d1dA@mail.gmail.com>

Hi Daniel,

Thanks for your review feedback.

On Fri, 6 Dec 2024 at 19:50, Daniel Lezcano <daniel.lezcano at linaro.org> wrote:
>
> On 12/6/24 14:28, Krzysztof Kozlowski wrote:
> > On Fri, Dec 06, 2024 at 12:39:56AM +0100, Daniel Lezcano wrote:
> >>> +# SPDX-License-Identifier: GPL-2.0-only
> >>> +
> >>> +config EXYNOS_ACPM_PROTOCOL
> >>> +   tristate "Exynos Alive Clock and Power Manager (ACPM) Message Protocol"
> >>
> >> Given the importance of this driver where a lot of PM services rely on, does
> >> it really make sense to allow it as a module ?

Yes, we want the option to build it as a module so we can use the
upstreamed driver with Generic Kernel Image (GKI) [1].

> >>
> >> Some PM services may be needed very early in the boot process
> >>
> >
> > If it works as module e.g. on Android, it is beneficial. I think the
> > platform was booting fine without it, at least to some shell, so I can
> > imagine this can be loaded a bit later.
>
> Usually the firmware sets the frequency to the maximum in order to boot
> the kernel as fast as possible. That may lead to thermal issues at boot
> time where the thermal framework won't be able to kick in as some
> components will depends on ACPM while the system stays at its highest
> performance state.

That isn't an issue here as the Pixel 6 bootloader leaves CPUs at mid
point frequencies during boot. I would actually expect most modern
phone bootloaders (since the launch of GKI at least) to do something
similar as it is a requirement for Generic Kernel Image (GKI) [1] that
all the SoC drivers are built as modules.

[1] https://source.android.com/docs/core/architecture/kernel/generic-kernel-image

Thanks,

Peter


From lee at kernel.org  Wed Dec 11 04:17:18 2024
From: lee at kernel.org (Lee Jones)
Date: Wed, 11 Dec 2024 12:17:18 +0000
Subject: [PATCH v9 1/9] HID: hid-sensor-hub: don't use stale
 platform-data on remove
In-Reply-To: <20241112143732.GG8552@google.com>
References: <20241107114712.538976-1-heiko@sntech.de>
 <20241107114712.538976-2-heiko@sntech.de>
 <nycvar.YFH.7.76.2411071358210.20286@cbobk.fhfr.pm>
 <4934964.GXAFRqVoOG@diego>
 <nycvar.YFH.7.76.2411071534110.20286@cbobk.fhfr.pm>
 <20241112143732.GG8552@google.com>
Message-ID: <20241211120844.GD7139@google.com>

On Tue, 12 Nov 2024, Lee Jones wrote:

> On Thu, 07 Nov 2024, Jiri Kosina wrote:
> 
> > On Thu, 7 Nov 2024, Heiko St?bner wrote:
> > 
> > > This change was more or less a surprise find, because I wanted to make
> > > the platform_data pointer in the mfd_cell struct const and this the hid
> > > sensor hub stood out as doing something strange ;-) .
> > > 
> > > So patch 2 of this series actually depends on this change to not cause
> > > build errors.
> > 
> > Ah, right.
> > 
> > > But seeing that we're after -rc6 alredy, I would assume the brunt of the 
> > > mcu series might need to wait after 6.13-rc1 anyway - but I guess that 
> > > depends on how Lee sees things ;-) .
> > 
> > OK, I am keeping my hands off it for the time being.
> 
> I can take it now with an Ack.

Looking to apply this set now.

Ack please.

-- 
Lee Jones [???]


From sudeep.holla at arm.com  Wed Dec 11 04:18:25 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 11 Dec 2024 12:18:25 +0000
Subject: Fwd: ARM64: CPUIdle driver is not select any Idle state other
 then WFI
In-Reply-To: <20241211055052.gbxnyqpui3t3zpw5@lcpd911>
References: <CAO6a-9_aPLCx2CqecQBGbK78_=+-tT44RepPkrBjpkWSvjj4Tg@mail.gmail.com>
 <CAO6a-98cdSvyd7jgAyGNmsC2nxmRSyr3GppxvZU9yHU1xqwz3g@mail.gmail.com>
 <20241211055052.gbxnyqpui3t3zpw5@lcpd911>
Message-ID: <20241211121825.GA2054801@bogus>

On Wed, Dec 11, 2024 at 11:20:52AM +0530, Dhruva Gole wrote:
> Hi Vivek,
>
> On Oct 14, 2024 at 16:06:34 +0530, Vivek yadav wrote:
> > ---------- Forwarded message ---------
> > From: Vivek yadav <linux.ninja23 at gmail.com>
> > Date: Fri, Oct 11, 2024 at 3:14?PM
> > Subject: ARM64: CPUIdle driver is not select any Idle state other then WFI
> > To: <linux-pm at vger.kernel.org>
>
> + Kevin, Vignesh and few colleagues at TI who have been working on this as
> well.
>
> >
> >
> > Hi @all,
> >
> > I am working on one custom SoC. Where I add one CPUIdle state for
> > ``arm,cortex-a55`` processor.
>
> Any further luck on this?
>
> I have also been working on something similar[1] but on an A53 core on
> TI-K3 AM62x processor.

Does upstream DTS have support for this platform to understand it better ?
Even reference to any complete DT file for the platform will help.

> >
> > idle-states {
> >       entry-method = "psci";
> >        cpu_ret_l: cpu-retention-l {
> >          compatible = "arm,idle-state";
> >          arm,psci-suspend-param = <0x00010001>;
> >          local-timer-stop;
> >          entry-latency-us = <55>;
> >           exit-latency-us = <140>;
> >           min-residency-us = <780>;
> >     };
> > };
> >
> > I am using ``Menu governor`` with the ``psci_idle driver`` in its original form.
> > After booting Linux I find out that the CPUIdle core is never going
> > inside the ``cpu-retention`` state.
> > To check time spent by CPU in any state. I am using the below command.
> >
> > ``cat /sys/devices/system/cpu/cpu*/cpuidle/state*/time``
>
> What I was seeing is in a multi core system (2 or more) all cores don't
> enter the idle-state simultaneously. There's something keeping atleast 1
> core always busy. However I could definitely see entry into TF-A from 1
> core at a time.

Does the platform have system timers ? What are the deeper idle states ?
If it is retention state with local timers on, I doubt if my suspicion of
CPU acting as broadcast timer in absence of a better/system timer.

> I then switched to a single core system to see if we were atall able to
> enter TF-A when only 1 core was available for linux, it turned out that
> with the "local-timer-stop" property that we have, this is never
> possible.
>

Yes my suspicion seems correct now but I can't confirm unless I understand
the platform completely.

> See this chunk in the kernel cpuidle driver:
> 	if (broadcast && tick_broadcast_enter()) {
>
> When I dug deeper into tick_broadcast_enter it always returns something
> non zero and hence in my case it was entering the if block and tried to
> find a deepest state. Then the deepest state would always return WFI and
> not the idle-state I had added.
>
> What we found out was on our kernel we end up using
>
> kernel/time/tick-broadcast-hrtimer.c
>
> This always seems to be keeping atleast 1 CPU busy and prevents idle.
> If we remove the local-timer-stop it was helping us, but we still need
> to dig into the full impact of what that entails and I am still
> interested in finding out how so many other users of similar idle-state
> implementation are able to do so without trouble.
>

Interesting. So if the platform is functional removing local-timer-stop,
I am bit confused. Either there is something else that is getting it out
from the idle state so, it should be fine and it could be just some
misconfiguration.

> Arm64 recommends to use arch_timer instead of external timers. Once we
> enter el3, timer interrupts to el1 is blocked and hence it's equivalent
> to local-timer-stop, so it does make sense to keep this property, but
> then how are others able to enter idle-states for all plugged CPUs at
> the same time?
>

Some systems have system timer that can take over as broadcast timer when
CPUs enter deeper idle states where the local timers are stopped.

--
Regards,
Sudeep


From karprzy7 at gmail.com  Wed Dec 11 04:20:26 2024
From: karprzy7 at gmail.com (Karol Przybylski)
Date: Wed, 11 Dec 2024 13:20:26 +0100
Subject: [PATCH] drm: zynqmp_dp: Fix integer overflow in zynqmp_dp_rate_get()
Message-ID: <20241211122026.797511-1-karprzy7@gmail.com>

This patch fixes a potential integer overflow in the zynqmp_dp_rate_get() function.

The issue comes up when the expression drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000 is evaluated using 32-bit arithmetic.

Now the constant is casted to compatible u64 type.

Resolves CID 1636340 and CID 1635811

Signed-off-by: Karol Przybylski <karprzy7 at gmail.com>
---
 drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 25c5dc61e..55e92344b 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -2190,7 +2190,7 @@ static int zynqmp_dp_rate_get(void *data, u64 *val)
 	struct zynqmp_dp *dp = data;
 
 	mutex_lock(&dp->lock);
-	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000;
+	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * (u64)10000;
 	mutex_unlock(&dp->lock);
 	return 0;
 }
-- 
2.34.1



From jikos at kernel.org  Wed Dec 11 04:24:42 2024
From: jikos at kernel.org (Jiri Kosina)
Date: Wed, 11 Dec 2024 13:24:42 +0100 (CET)
Subject: [PATCH v9 1/9] HID: hid-sensor-hub: don't use stale platform-data
 on remove
In-Reply-To: <20241211120844.GD7139@google.com>
References: <20241107114712.538976-1-heiko@sntech.de> <20241107114712.538976-2-heiko@sntech.de> <nycvar.YFH.7.76.2411071358210.20286@cbobk.fhfr.pm> <4934964.GXAFRqVoOG@diego> <nycvar.YFH.7.76.2411071534110.20286@cbobk.fhfr.pm> <20241112143732.GG8552@google.com>
 <20241211120844.GD7139@google.com>
Message-ID: <n914pn7o-pr9n-5ss0-p744-73402nnn843p@xreary.bet>

On Wed, 11 Dec 2024, Lee Jones wrote:

> > > > This change was more or less a surprise find, because I wanted to make
> > > > the platform_data pointer in the mfd_cell struct const and this the hid
> > > > sensor hub stood out as doing something strange ;-) .
> > > > 
> > > > So patch 2 of this series actually depends on this change to not cause
> > > > build errors.
> > > 
> > > Ah, right.
> > > 
> > > > But seeing that we're after -rc6 alredy, I would assume the brunt of the 
> > > > mcu series might need to wait after 6.13-rc1 anyway - but I guess that 
> > > > depends on how Lee sees things ;-) .
> > > 
> > > OK, I am keeping my hands off it for the time being.
> > 
> > I can take it now with an Ack.
> 
> Looking to apply this set now.
> 
> Ack please.

I'd preferer if Srinivas could ack this as the more specific maintainer. 
Srinivas, please? 

Thanks,

-- 
Jiri Kosina
SUSE Labs



From qperret at google.com  Wed Dec 11 04:34:23 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 12:34:23 +0000
Subject: [PATCH v4 07/14] KVM: arm64: Rework specifying restricted
 features for protected VMs
In-Reply-To: <20241202154742.3611749-8-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-8-tabba@google.com>
Message-ID: <Z1mGzwZqVQCWWSTX@google.com>

On Monday 02 Dec 2024 at 15:47:34 (+0000), Fuad Tabba wrote:
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index f333b189fb43..230b0638f0c2 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -1422,6 +1422,7 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
>  	return test_bit(feature, ka->vcpu_features);
>  }
>  
> +#define kvm_vcpu_has_feature(k, f)	__vcpu_has_feature(&(k)->arch, (f))
>  #define vcpu_has_feature(v, f)	__vcpu_has_feature(&(v)->kvm->arch, (f))

Nit: I see nested uses the raw __vcpu_has_feature() helper, so I guess
we should try and be consistent. Either way works, we can do the same
thing in sys_regs.c, or convert nested.c to use kvm_vcpu_has_feature().


From qperret at google.com  Wed Dec 11 04:38:13 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 12:38:13 +0000
Subject: [PATCH v4 09/14] KVM: arm64: Remove redundant setting of HCR_EL2
 trap bit
In-Reply-To: <20241202154742.3611749-10-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-10-tabba@google.com>
Message-ID: <Z1mHtVJ4f7_N_wk4@google.com>

On Monday 02 Dec 2024 at 15:47:36 (+0000), Fuad Tabba wrote:
> In hVHE mode, HCR_E2H should be set for both protected and
> non-protected VMs. Since commit 23c9d58cb458 ("KVM: arm64: Fix

I'm not finding that sha upstream, in which branch is it?

> initializing traps in protected mode"), this has been fixed, and
> the setting of the flag here is redundant.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/kvm/hyp/nvhe/pkvm.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index ffa500b500f2..cede527a59d4 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -57,9 +57,6 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
>  	/* No support for AArch32. */
>  	val |= HCR_RW;
>  
> -	if (has_hvhe())
> -		val |= HCR_E2H;
> -
>  	/*
>  	 * Always trap:
>  	 * - Feature id registers: to control features exposed to guests
> -- 
> 2.47.0.338.g60cca15819-goog
> 


From michal.simek at amd.com  Wed Dec 11 04:41:32 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:32 +0100
Subject: [PATCH 13/15] ARM: zynq: Enable QSPIs on platforms
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <b10d922fec7fde0948205b266bf7e960113859c5.1733920873.git.michal.simek@amd.com>

Enable QSPIs with default MTD layout used for testing.
Zybos, Microzed and Zturn are only enabling controller without specifying
MTD map.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-cc108.dts       | 39 ++++++++++++++++++
 arch/arm/boot/dts/xilinx/zynq-microzed.dts    |  6 +++
 arch/arm/boot/dts/xilinx/zynq-zc702.dts       | 39 ++++++++++++++++++
 arch/arm/boot/dts/xilinx/zynq-zc706.dts       | 40 +++++++++++++++++++
 arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts | 37 +++++++++++++++++
 arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts | 39 ++++++++++++++++++
 arch/arm/boot/dts/xilinx/zynq-zed.dts         | 40 +++++++++++++++++++
 .../boot/dts/xilinx/zynq-zturn-common.dtsi    |  5 +++
 arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts     |  6 +++
 arch/arm/boot/dts/xilinx/zynq-zybo.dts        |  6 +++
 10 files changed, 257 insertions(+)

diff --git a/arch/arm/boot/dts/xilinx/zynq-cc108.dts b/arch/arm/boot/dts/xilinx/zynq-cc108.dts
index 5e542ded3d0c..f5525c048426 100644
--- a/arch/arm/boot/dts/xilinx/zynq-cc108.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-cc108.dts
@@ -18,6 +18,7 @@ / {
 	aliases {
 		ethernet0 = &gem0;
 		serial0 = &uart0;
+		spi0 = &qspi;
 	};
 
 	chosen {
@@ -51,6 +52,44 @@ ethernet_phy: ethernet-phy at 1 {
 	};
 };
 
+&qspi {
+	status = "okay";
+	num-cs = <1>;
+	flash at 0 { /* 16 MB */
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-max-frequency = <50000000>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		partition at 0 {
+			label = "qspi-fsbl-uboot-bs";
+			reg = <0x0 0x400000>; /* 4MB */
+		};
+		partition at 400000 {
+			label = "qspi-linux";
+			reg = <0x400000 0x400000>; /* 4MB */
+		};
+		partition at 800000 {
+			label = "qspi-rootfs";
+			reg = <0x800000 0x400000>; /* 4MB */
+		};
+		partition at c00000 {
+			label = "qspi-devicetree";
+			reg = <0xc00000 0x100000>; /* 1MB */
+		};
+		partition at d00000 {
+			label = "qspi-scratch";
+			reg = <0xd00000 0x200000>; /* 2MB */
+		};
+		partition at f00000 {
+			label = "qspi-uboot-env";
+			reg = <0xf00000 0x100000>; /* 1MB */
+		};
+	};
+};
+
 &sdhci1 {
 	status = "okay";
 	broken-cd ;
diff --git a/arch/arm/boot/dts/xilinx/zynq-microzed.dts b/arch/arm/boot/dts/xilinx/zynq-microzed.dts
index f2f560cc0c0d..4c3e56980c98 100644
--- a/arch/arm/boot/dts/xilinx/zynq-microzed.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-microzed.dts
@@ -13,6 +13,7 @@ / {
 	aliases {
 		ethernet0 = &gem0;
 		serial0 = &uart1;
+		spi0 = &qspi;
 	};
 
 	memory at 0 {
@@ -35,6 +36,11 @@ &clkc {
 	ps-clk-frequency = <33333333>;
 };
 
+&qspi {
+	bootph-all;
+	status = "okay";
+};
+
 &gem0 {
 	status = "okay";
 	phy-mode = "rgmii-id";
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
index e4c9491081f8..a88fc38882aa 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
@@ -15,6 +15,7 @@ aliases {
 		ethernet0 = &gem0;
 		i2c0 = &i2c0;
 		serial0 = &uart1;
+		spi0 = &qspi;
 		mmc0 = &sdhci0;
 		nvmem0 = &eeprom;
 		rtc0 = &rtc;
@@ -393,6 +394,44 @@ conf-tx {
 	};
 };
 
+&qspi {
+	bootph-all;
+	status = "okay";
+	num-cs = <1>;
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition at 0 {
+				label = "qspi-fsbl-uboot";
+				reg = <0x0 0x100000>;
+			};
+			partition at 100000 {
+				label = "qspi-linux";
+				reg = <0x100000 0x500000>;
+			};
+			partition at 600000 {
+				label = "qspi-device-tree";
+				reg = <0x600000 0x20000>;
+			};
+			partition at 620000 {
+				label = "qspi-rootfs";
+				reg = <0x620000 0x5e0000>;
+			};
+			partition at c00000 {
+				label = "qspi-bitstream";
+				reg = <0xc00000 0x400000>;
+			};
+		};
+	};
+};
+
 &sdhci0 {
 	bootph-all;
 	status = "okay";
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc706.dts b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
index 1e38c5caec22..3b803c698473 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc706.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
@@ -14,6 +14,7 @@ aliases {
 		ethernet0 = &gem0;
 		i2c0 = &i2c0;
 		serial0 = &uart1;
+		spi0 = &qspi;
 		mmc0 = &sdhci0;
 		nvmem0 = &eeprom;
 		rtc0 = &rtc;
@@ -304,6 +305,45 @@ conf-tx {
 	};
 };
 
+&qspi {
+	bootph-all;
+	status = "okay";
+	num-cs = <2>;
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>, <1>;
+		parallel-memories = /bits/ 64 <0x1000000 0x1000000>; /* 16MB */
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition at 0 {
+				label = "qspi-fsbl-uboot";
+				reg = <0x0 0x100000>;
+			};
+			partition at 100000 {
+				label = "qspi-linux";
+				reg = <0x100000 0x500000>;
+			};
+			partition at 600000 {
+				label = "qspi-device-tree";
+				reg = <0x600000 0x20000>;
+			};
+			partition at 620000 {
+				label = "qspi-rootfs";
+				reg = <0x620000 0x5e0000>;
+			};
+			partition at c00000 {
+				label = "qspi-bitstream";
+				reg = <0xc00000 0x400000>;
+			};
+		};
+	};
+};
+
 &sdhci0 {
 	bootph-all;
 	status = "okay";
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts
index 02876f6d23a5..5fe799c3c7cf 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts
@@ -15,6 +15,7 @@ aliases {
 		ethernet0 = &gem0;
 		i2c0 = &i2c0;
 		serial0 = &uart1;
+		spi0 = &qspi;
 		spi1 = &spi1;
 	};
 
@@ -56,7 +57,43 @@ eeprom: eeprom at 52 {
 		compatible = "atmel,24c02";
 		reg = <0x52>;
 	};
+};
 
+&qspi {
+	status = "okay";
+	num-cs = <1>;
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition at 0 {
+				label = "qspi-fsbl-uboot";
+				reg = <0x0 0x100000>;
+			};
+			partition at 100000 {
+				label = "qspi-linux";
+				reg = <0x100000 0x500000>;
+			};
+			partition at 600000 {
+				label = "qspi-device-tree";
+				reg = <0x600000 0x20000>;
+			};
+			partition at 620000 {
+				label = "qspi-rootfs";
+				reg = <0x620000 0x5e0000>;
+			};
+			partition at c00000 {
+				label = "qspi-bitstream";
+				reg = <0xc00000 0x400000>;
+			};
+		};
+	};
 };
 
 &sdhci0 {
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts
index f07af61eaa29..103e87ea7253 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts
@@ -15,6 +15,7 @@ aliases {
 		ethernet0 = &gem1;
 		i2c0 = &i2c1;
 		serial0 = &uart0;
+		spi0 = &qspi;
 		spi1 = &spi0;
 	};
 
@@ -57,6 +58,44 @@ si570: clock-generator at 55 {
 	};
 };
 
+&qspi {
+	status = "okay";
+	num-cs = <2>;
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>, <1>;
+		parallel-memories = /bits/ 64 <0x1000000 0x1000000>; /* 16MB */
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition at 0 {
+				label = "qspi-fsbl-uboot";
+				reg = <0x0 0x100000>;
+			};
+			partition at 100000 {
+				label = "qspi-linux";
+				reg = <0x100000 0x500000>;
+			};
+			partition at 600000 {
+				label = "qspi-device-tree";
+				reg = <0x600000 0x20000>;
+			};
+			partition at 620000 {
+				label = "qspi-rootfs";
+				reg = <0x620000 0x5e0000>;
+			};
+			partition at c00000 {
+				label = "qspi-bitstream";
+				reg = <0xc00000 0x400000>;
+			};
+		};
+	};
+};
+
 &spi0 {
 	status = "okay";
 	num-cs = <4>;
diff --git a/arch/arm/boot/dts/xilinx/zynq-zed.dts b/arch/arm/boot/dts/xilinx/zynq-zed.dts
index ff2b4e06efbb..52ba569b2b9f 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zed.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zed.dts
@@ -13,6 +13,7 @@ / {
 	aliases {
 		ethernet0 = &gem0;
 		serial0 = &uart1;
+		spi0 = &qspi;
 		mmc0 = &sdhci0;
 	};
 
@@ -46,6 +47,45 @@ ethernet_phy: ethernet-phy at 0 {
 	};
 };
 
+&qspi {
+	bootph-all;
+	status = "okay";
+	num-cs = <1>;
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition at 0 {
+				label = "qspi-fsbl-uboot";
+				reg = <0x0 0x100000>;
+			};
+			partition at 100000 {
+				label = "qspi-linux";
+				reg = <0x100000 0x500000>;
+			};
+			partition at 600000 {
+				label = "qspi-device-tree";
+				reg = <0x600000 0x20000>;
+			};
+			partition at 620000 {
+				label = "qspi-rootfs";
+				reg = <0x620000 0x5e0000>;
+			};
+			partition at c00000 {
+				label = "qspi-bitstream";
+				reg = <0xc00000 0x400000>;
+			};
+		};
+	};
+};
+
 &sdhci0 {
 	bootph-all;
 	status = "okay";
diff --git a/arch/arm/boot/dts/xilinx/zynq-zturn-common.dtsi b/arch/arm/boot/dts/xilinx/zynq-zturn-common.dtsi
index 800e891495f5..defef9c8da13 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zturn-common.dtsi
+++ b/arch/arm/boot/dts/xilinx/zynq-zturn-common.dtsi
@@ -63,6 +63,11 @@ &clkc {
 	ps-clk-frequency = <33333333>;
 };
 
+&qspi {
+	bootph-all;
+	status = "okay";
+};
+
 &gem0 {
 	status = "okay";
 	phy-mode = "rgmii-id";
diff --git a/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts b/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
index 6983caa35b0d..5e4247da2285 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
@@ -10,6 +10,7 @@ / {
 	aliases {
 		ethernet0 = &gem0;
 		serial0 = &uart1;
+		spi0 = &qspi;
 	};
 
 	memory at 0 {
@@ -52,6 +53,11 @@ ethernet_phy: ethernet-phy at 0 {
 	};
 };
 
+&qspi {
+	bootph-all;
+	status = "okay";
+};
+
 &sdhci0 {
 	bootph-all;
 	status = "okay";
diff --git a/arch/arm/boot/dts/xilinx/zynq-zybo.dts b/arch/arm/boot/dts/xilinx/zynq-zybo.dts
index f365693fe2f7..fbc7d1b12e94 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zybo.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zybo.dts
@@ -13,6 +13,7 @@ / {
 	aliases {
 		ethernet0 = &gem0;
 		serial0 = &uart1;
+		spi0 = &qspi;
 		mmc0 = &sdhci0;
 	};
 
@@ -47,6 +48,11 @@ ethernet_phy: ethernet-phy at 0 {
 	};
 };
 
+&qspi {
+	bootph-all;
+	status = "okay";
+};
+
 &sdhci0 {
 	bootph-all;
 	status = "okay";
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:33 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:33 +0100
Subject: [PATCH 14/15] ARM: zynq: Add sdhci to alias node
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <9fa60b57e038d51ae6677fac6628ecd663ddd2cd.1733920873.git.michal.simek@amd.com>

Ensure that controller will all the time use the same ID.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-microzed.dts | 1 +
 arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/xilinx/zynq-microzed.dts b/arch/arm/boot/dts/xilinx/zynq-microzed.dts
index 4c3e56980c98..20c04862679d 100644
--- a/arch/arm/boot/dts/xilinx/zynq-microzed.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-microzed.dts
@@ -14,6 +14,7 @@ aliases {
 		ethernet0 = &gem0;
 		serial0 = &uart1;
 		spi0 = &qspi;
+		mmc0 = &sdhci0;
 	};
 
 	memory at 0 {
diff --git a/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts b/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
index 5e4247da2285..56b917eec783 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
@@ -11,6 +11,7 @@ aliases {
 		ethernet0 = &gem0;
 		serial0 = &uart1;
 		spi0 = &qspi;
+		mmc0 = &sdhci0;
 	};
 
 	memory at 0 {
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:34 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:34 +0100
Subject: [PATCH 15/15] ARM: zynq: Remove ethernet0 alias from Microzed
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <f4189063a8923ad380675f8e426e739ee3110baa.1733920873.git.michal.simek@amd.com>

Ethernet is not using alias for ID assignment that's why alias is not
needed and can be removed.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-microzed.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/xilinx/zynq-microzed.dts b/arch/arm/boot/dts/xilinx/zynq-microzed.dts
index 20c04862679d..68b867e8369e 100644
--- a/arch/arm/boot/dts/xilinx/zynq-microzed.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-microzed.dts
@@ -11,7 +11,6 @@ / {
 	compatible = "avnet,zynq-microzed", "xlnx,zynq-microzed", "xlnx,zynq-7000";
 
 	aliases {
-		ethernet0 = &gem0;
 		serial0 = &uart1;
 		spi0 = &qspi;
 		mmc0 = &sdhci0;
-- 
2.43.0



From lee at kernel.org  Wed Dec 11 04:45:56 2024
From: lee at kernel.org (Lee Jones)
Date: Wed, 11 Dec 2024 12:45:56 +0000
Subject: [PATCH v6 2/7] mfd: nxp-siul2: add support for NXP SIUL2
In-Reply-To: <20241113101124.1279648-3-andrei.stefanescu@oss.nxp.com>
References: <20241113101124.1279648-1-andrei.stefanescu@oss.nxp.com>
 <20241113101124.1279648-3-andrei.stefanescu@oss.nxp.com>
Message-ID: <20241211124454.GE7139@google.com>

Mark,

Seeing as the vast majority of this 400 line driver pertains to Regmap
handling (!), would you be kind enough to cast your expert eye over it
please?

On Wed, 13 Nov 2024, Andrei Stefanescu wrote:

> SIUL2 (System Integration Unit Lite) is a hardware module which
> implements various functionalities:
> - reading SoC information
> - pinctrl
> - GPIO (including interrupts)
> 
> This commit only adds support for pinctrl&GPIO(one cell). Further
> commits will add nvmem functionality(a second cell).

It's not an MFD until it has more than one device.

Please add that now or it cannot be accepted.

[pausing my review here for the time being]

> There are multiple register types in the SIUL2 module:
> - MIDR (MCU ID Register)
> 	* contains information about the SoC.
> - Interrupt related registers
> 	* There are 32 interrupts named EIRQ. An EIRQ
> 	  may be routed to one or more GPIOs. Not all
> 	  GPIOs have EIRQs associated with them
> - MSCR (Multiplexed Signal Configuration Register)
> 	* handle pinmuxing and pinconf
> - IMCR (Input Multiplexed Signal Configuration Register)
> 	* are part of pinmuxing
> - PGPDO/PGPDI (Parallel GPIO Pad Data Out/In Register)
> 	* Write/Read the GPIO value
> 
> There are two SIUL2 modules in the S32G SoC. This driver handles
> both because functionality is shared between them. For example:
> some GPIOs in SIUL2_0 have interrupt capability but the registers
> configuring this are in SIUL2_1.
> 
> Signed-off-by: Andrei Stefanescu <andrei.stefanescu at oss.nxp.com>
> ---
>  drivers/mfd/Kconfig           |  12 +
>  drivers/mfd/Makefile          |   1 +
>  drivers/mfd/nxp-siul2.c       | 410 ++++++++++++++++++++++++++++++++++
>  include/linux/mfd/nxp-siul2.h |  55 +++++
>  4 files changed, 478 insertions(+)
>  create mode 100644 drivers/mfd/nxp-siul2.c
>  create mode 100644 include/linux/mfd/nxp-siul2.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index f9325bcce1b9..fc590789e8b3 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1098,6 +1098,18 @@ config MFD_NTXEC
>  	  certain e-book readers designed by the original design manufacturer
>  	  Netronix.
>  
> +config MFD_NXP_SIUL2
> +	tristate "NXP SIUL2 MFD driver"
> +	select MFD_CORE
> +	select REGMAP_MMIO
> +	depends on ARCH_S32 || COMPILE_TEST
> +	help
> +	  Select this to get support for the NXP SIUL2 (System Integration
> +	  Unit Lite) module. This hardware block contains registers for
> +	  SoC information, pinctrl and GPIO functionality. This will
> +	  probe a MFD driver which will contain cells for a combined
> +	  pinctrl&GPIO driver and nvmem drivers for the SoC information.
> +
>  config MFD_RETU
>  	tristate "Nokia Retu and Tahvo multi-function device"
>  	select MFD_CORE
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 2a9f91e81af8..7b19ea014221 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -226,6 +226,7 @@ obj-$(CONFIG_MFD_INTEL_PMC_BXT)	+= intel_pmc_bxt.o
>  obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
>  obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
>  obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
> +obj-$(CONFIG_MFD_NXP_SIUL2) 	+= nxp-siul2.o
>  obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
>  obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
>  obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
> diff --git a/drivers/mfd/nxp-siul2.c b/drivers/mfd/nxp-siul2.c
> new file mode 100644
> index 000000000000..7751992e4df3
> --- /dev/null
> +++ b/drivers/mfd/nxp-siul2.c
> @@ -0,0 +1,410 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * SIUL2(System Integration Unit Lite) MFD driver
> + *
> + * Copyright 2024 NXP
> + */
> +#include <linux/init.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/nxp-siul2.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +
> +#define S32G_NUM_SIUL2 2
> +
> +#define S32_REG_RANGE(start, end, name, access)		\
> +	{						\
> +		.reg_name = (name),			\
> +		.reg_start_offset = (start),		\
> +		.reg_end_offset = (end),		\
> +		.reg_access = (access),			\
> +		.valid = true,				\
> +	}
> +
> +#define S32_INVALID_REG_RANGE		\
> +	{				\
> +		.reg_name = NULL,	\
> +		.reg_access = NULL,	\
> +		.valid = false,		\
> +	}
> +
> +static const struct mfd_cell nxp_siul2_devs[] = {
> +	{
> +		.name = "s32g-siul2-pinctrl",
> +	}
> +};
> +
> +/**
> + * struct nxp_siul2_reg_range_info: a register range in SIUL2
> + * @reg_name: the name for the register range
> + * @reg_start_offset: the first valid register offset
> + * @reg_end_offset: the last valid register offset
> + * @reg_access: the read/write access tables if not NULL
> + * @valid: whether the register range is valid or not
> + */
> +struct nxp_siul2_reg_range_info {
> +	const char *reg_name;
> +	unsigned int reg_start_offset;
> +	unsigned int reg_end_offset;
> +	const struct regmap_access_table *reg_access;
> +	bool valid;
> +};
> +
> +static const struct regmap_range s32g2_siul2_0_imcr_reg_ranges[] = {
> +	/* IMCR0 - IMCR1 */
> +	regmap_reg_range(0, 4),
> +	/* IMCR3 - IMCR61 */
> +	regmap_reg_range(0xC, 0xF4),
> +	/* IMCR68 - IMCR83 */
> +	regmap_reg_range(0x110, 0x14C)
> +};
> +
> +static const struct regmap_access_table s32g2_siul2_0_imcr = {
> +	.yes_ranges = s32g2_siul2_0_imcr_reg_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(s32g2_siul2_0_imcr_reg_ranges)
> +};
> +
> +static const struct regmap_range s32g2_siul2_0_pgpd_reg_ranges[] = {
> +	/* PGPD*0 - PGPD*5 */
> +	regmap_reg_range(0, 0xA),
> +	/* PGPD*6 - PGPD*6 */
> +	regmap_reg_range(0xE, 0xE),
> +};
> +
> +static const struct regmap_access_table s32g2_siul2_0_pgpd = {
> +	.yes_ranges = s32g2_siul2_0_pgpd_reg_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(s32g2_siul2_0_pgpd_reg_ranges)
> +};
> +
> +static const struct regmap_range s32g2_siul2_1_irq_reg_ranges[] = {
> +	/* DISR0 */
> +	regmap_reg_range(0x10, 0x10),
> +	/* DIRER0 */
> +	regmap_reg_range(0x18, 0x18),
> +	/* DIRSR0 */
> +	regmap_reg_range(0x20, 0x20),
> +	/* IREER0 */
> +	regmap_reg_range(0x28, 0x28),
> +	/* IFEER0 */
> +	regmap_reg_range(0x30, 0x30),
> +};
> +
> +static const struct regmap_access_table s32g2_siul2_1_irq = {
> +	.yes_ranges = s32g2_siul2_1_irq_reg_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(s32g2_siul2_1_irq_reg_ranges),
> +};
> +
> +static const struct regmap_range s32g2_siul2_1_irq_volatile_reg_range[] = {
> +	/* DISR0 */
> +	regmap_reg_range(0x10, 0x10)
> +};
> +
> +static const struct regmap_access_table s32g2_siul2_1_irq_volatile = {
> +	.yes_ranges = s32g2_siul2_1_irq_volatile_reg_range,
> +	.n_yes_ranges = ARRAY_SIZE(s32g2_siul2_1_irq_volatile_reg_range),
> +};
> +
> +static const struct regmap_range s32g2_siul2_1_mscr_reg_ranges[] = {
> +	/* MSCR112 - MSCR122 */
> +	regmap_reg_range(0, 0x28),
> +	/* MSCR144 - MSCR190 */
> +	regmap_reg_range(0x80, 0x138)
> +};
> +
> +static const struct regmap_access_table s32g2_siul2_1_mscr = {
> +	.yes_ranges = s32g2_siul2_1_mscr_reg_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(s32g2_siul2_1_mscr_reg_ranges),
> +};
> +
> +static const struct regmap_range s32g2_siul2_1_imcr_reg_ranges[] = {
> +	/* IMCR119 - IMCR121 */
> +	regmap_reg_range(0, 8),
> +	/* IMCR128 - IMCR129 */
> +	regmap_reg_range(0x24, 0x28),
> +	/* IMCR143 - IMCR151 */
> +	regmap_reg_range(0x60, 0x80),
> +	/* IMCR153 - IMCR161 */
> +	regmap_reg_range(0x88, 0xA8),
> +	/* IMCR205 - IMCR212 */
> +	regmap_reg_range(0x158, 0x174),
> +	/* IMCR224 - IMCR225 */
> +	regmap_reg_range(0x1A4, 0x1A8),
> +	/* IMCR233 - IMCR248 */
> +	regmap_reg_range(0x1C8, 0x204),
> +	/* IMCR273 - IMCR274 */
> +	regmap_reg_range(0x268, 0x26C),
> +	/* IMCR278 - IMCR281 */
> +	regmap_reg_range(0x27C, 0x288),
> +	/* IMCR283 - IMCR286 */
> +	regmap_reg_range(0x290, 0x29C),
> +	/* IMCR288 - IMCR294 */
> +	regmap_reg_range(0x2A4, 0x2BC),
> +	/* IMCR296 - IMCR302 */
> +	regmap_reg_range(0x2C4, 0x2DC),
> +	/* IMCR304 - IMCR310 */
> +	regmap_reg_range(0x2E4, 0x2FC),
> +	/* IMCR312 - IMCR314 */
> +	regmap_reg_range(0x304, 0x30C),
> +	/* IMCR316 */
> +	regmap_reg_range(0x314, 0x314),
> +	/* IMCR 318 */
> +	regmap_reg_range(0x31C, 0x31C),
> +	/* IMCR322 - IMCR340 */
> +	regmap_reg_range(0x32C, 0x374),
> +	/* IMCR343 - IMCR360 */
> +	regmap_reg_range(0x380, 0x3C4),
> +	/* IMCR363 - IMCR380 */
> +	regmap_reg_range(0x3D0, 0x414),
> +	/* IMCR383 - IMCR393 */
> +	regmap_reg_range(0x420, 0x448),
> +	/* IMCR398 - IMCR433 */
> +	regmap_reg_range(0x45C, 0x4E8),
> +	/* IMCR467 - IMCR470 */
> +	regmap_reg_range(0x570, 0x57C),
> +	/* IMCR473 - IMCR475 */
> +	regmap_reg_range(0x588, 0x590),
> +	/* IMCR478 - IMCR480*/
> +	regmap_reg_range(0x59C, 0x5A4),
> +	/* IMCR483 - IMCR485 */
> +	regmap_reg_range(0x5B0, 0x5B8),
> +	/* IMCR488 - IMCR490 */
> +	regmap_reg_range(0x5C4, 0x5CC),
> +	/* IMCR493 - IMCR495 */
> +	regmap_reg_range(0x5D8, 0x5E0),
> +};
> +
> +static const struct regmap_access_table s32g2_siul2_1_imcr = {
> +	.yes_ranges = s32g2_siul2_1_imcr_reg_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(s32g2_siul2_1_imcr_reg_ranges)
> +};
> +
> +static const struct regmap_range s32g2_siul2_1_pgpd_reg_ranges[] = {
> +	/* PGPD*7 */
> +	regmap_reg_range(0xC, 0xC),
> +	/* PGPD*9 */
> +	regmap_reg_range(0x10, 0x10),
> +	/* PDPG*10 - PGPD*11 */
> +	regmap_reg_range(0x14, 0x16),
> +};
> +
> +static const struct regmap_access_table s32g2_siul2_1_pgpd = {
> +	.yes_ranges = s32g2_siul2_1_pgpd_reg_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(s32g2_siul2_1_pgpd_reg_ranges)
> +};
> +
> +static const struct nxp_siul2_reg_range_info
> +s32g2_reg_ranges[S32G_NUM_SIUL2][SIUL2_NUM_REG_TYPES] = {
> +	/* SIUL2_0 */
> +	{
> +		[SIUL2_MPIDR] = S32_REG_RANGE(4, 8, "SIUL2_0_MPIDR", NULL),
> +		/* Interrupts are to be controlled from SIUL2_1 */
> +		[SIUL2_IRQ] = S32_INVALID_REG_RANGE,
> +		[SIUL2_MSCR] = S32_REG_RANGE(0x240, 0x3D4, "SIUL2_0_MSCR",
> +					     NULL),
> +		[SIUL2_IMCR] = S32_REG_RANGE(0xA40, 0xB8C, "SIUL2_0_IMCR",
> +					     &s32g2_siul2_0_imcr),
> +		[SIUL2_PGPDO] = S32_REG_RANGE(0x1700, 0x170E,
> +					      "SIUL2_0_PGPDO",
> +					      &s32g2_siul2_0_pgpd),
> +		[SIUL2_PGPDI] = S32_REG_RANGE(0x1740, 0x174E,
> +					      "SIUL2_0_PGPDI",
> +					      &s32g2_siul2_0_pgpd),
> +	},
> +	/* SIUL2_1 */
> +	{
> +		[SIUL2_MPIDR] = S32_REG_RANGE(4, 8, "SIUL2_1_MPIDR", NULL),
> +		[SIUL2_IRQ] = S32_REG_RANGE(0x10, 0xC0, "SIUL2_1_IRQ",
> +					    &s32g2_siul2_1_irq),
> +		[SIUL2_MSCR] = S32_REG_RANGE(0x400, 0x538, "SIUL2_1_MSCR",
> +					     &s32g2_siul2_1_mscr),
> +		[SIUL2_IMCR] = S32_REG_RANGE(0xC1C, 0x11FC, "SIUL2_1_IMCR",
> +					     &s32g2_siul2_1_imcr),
> +		[SIUL2_PGPDO] = S32_REG_RANGE(0x1700, 0x1716,
> +					      "SIUL2_1_PGPDO",
> +					      &s32g2_siul2_1_pgpd),
> +		[SIUL2_PGPDI] = S32_REG_RANGE(0x1740, 0x1756,
> +					      "SIUL2_1_PGPDI",
> +					      &s32g2_siul2_1_pgpd),
> +	},
> +};
> +
> +static const struct regmap_config nxp_siul2_regmap_irq_conf = {
> +	.val_bits = 32,
> +	.val_format_endian = REGMAP_ENDIAN_LITTLE,
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.cache_type = REGCACHE_FLAT,
> +	.use_raw_spinlock = true,
> +	.volatile_table = &s32g2_siul2_1_irq_volatile,
> +};
> +
> +static const struct regmap_config nxp_siul2_regmap_generic_conf = {
> +	.val_bits = 32,
> +	.val_format_endian = REGMAP_ENDIAN_LITTLE,
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.cache_type = REGCACHE_FLAT,
> +	.use_raw_spinlock = true,
> +};
> +
> +static const struct regmap_config nxp_siul2_regmap_pgpdo_conf = {
> +	.val_bits = 16,
> +	.val_format_endian = REGMAP_ENDIAN_LITTLE,
> +	.reg_bits = 32,
> +	.reg_stride = 2,
> +	.cache_type = REGCACHE_FLAT,
> +	.use_raw_spinlock = true,
> +};
> +
> +static const struct regmap_config nxp_siul2_regmap_pgpdi_conf = {
> +	.val_bits = 16,
> +	.val_format_endian = REGMAP_ENDIAN_LITTLE,
> +	.reg_bits = 32,
> +	.reg_stride = 2,
> +	.cache_type = REGCACHE_NONE,
> +	.use_raw_spinlock = true,
> +};
> +
> +static int nxp_siul2_init_regmap(struct platform_device *pdev,
> +				 void __iomem *base, unsigned int siul)
> +{
> +	const struct regmap_config *regmap_configs[SIUL2_NUM_REG_TYPES] = {
> +		[SIUL2_MPIDR]	= &nxp_siul2_regmap_generic_conf,
> +		[SIUL2_IRQ]	= &nxp_siul2_regmap_irq_conf,
> +		[SIUL2_MSCR]	= &nxp_siul2_regmap_generic_conf,
> +		[SIUL2_IMCR]	= &nxp_siul2_regmap_generic_conf,
> +		[SIUL2_PGPDO]	= &nxp_siul2_regmap_pgpdo_conf,
> +		[SIUL2_PGPDI]	= &nxp_siul2_regmap_pgpdi_conf,
> +	};
> +	const struct nxp_siul2_reg_range_info *tmp_range;
> +	struct regmap_config tmp_conf;
> +	struct nxp_siul2_info *info;
> +	struct nxp_siul2_mfd *priv;
> +	void __iomem *reg_start;
> +	int i;
> +
> +	priv = platform_get_drvdata(pdev);
> +	info = &priv->siul2[siul];
> +
> +	for (i = 0; i < SIUL2_NUM_REG_TYPES; i++) {
> +		if (!s32g2_reg_ranges[siul][i].valid)
> +			continue;
> +
> +		tmp_range = &s32g2_reg_ranges[siul][i];
> +		tmp_conf = *regmap_configs[i];
> +		tmp_conf.name = tmp_range->reg_name;
> +		tmp_conf.max_register =
> +			tmp_range->reg_end_offset - tmp_range->reg_start_offset;
> +
> +		if (tmp_conf.cache_type != REGCACHE_NONE)
> +			tmp_conf.num_reg_defaults_raw =
> +				tmp_conf.max_register / tmp_conf.reg_stride;
> +
> +		if (tmp_range->reg_access) {
> +			tmp_conf.wr_table = tmp_range->reg_access;
> +			tmp_conf.rd_table = tmp_range->reg_access;
> +		}
> +
> +		reg_start = base + tmp_range->reg_start_offset;
> +		info->regmaps[i] = devm_regmap_init_mmio(&pdev->dev, reg_start,
> +							 &tmp_conf);
> +		if (IS_ERR(info->regmaps[i]))
> +			return dev_err_probe(&pdev->dev,
> +					     PTR_ERR(info->regmaps[i]),
> +					     "regmap %d init failed: %ld\n", i,
> +					     PTR_ERR(info->regmaps[i]));
> +	}
> +
> +	return 0;
> +}
> +
> +static int nxp_siul2_parse_dtb(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct of_phandle_args pinspec;
> +	struct nxp_siul2_mfd *priv;
> +	void __iomem *base;
> +	char reg_name[16];
> +	int i, ret;
> +
> +	priv = platform_get_drvdata(pdev);
> +
> +	for (i = 0; i < priv->num_siul2; i++) {
> +		ret = snprintf(reg_name, ARRAY_SIZE(reg_name), "siul2%d", i);
> +		if (ret < 0 || ret >= ARRAY_SIZE(reg_name))
> +			return ret;
> +
> +		base = devm_platform_ioremap_resource_byname(pdev, reg_name);
> +		if (IS_ERR(base))
> +			return dev_err_probe(&pdev->dev, PTR_ERR(base),
> +					     "Failed to get MEM resource: %s\n",
> +					     reg_name);
> +
> +		ret = nxp_siul2_init_regmap(pdev, base, i);
> +		if (ret)
> +			return ret;
> +
> +		ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
> +						       i, &pinspec);
> +		if (ret)
> +			return ret;
> +
> +		of_node_put(pinspec.np);
> +
> +		if (pinspec.args_count != 3)
> +			return dev_err_probe(&pdev->dev, -EINVAL,
> +					     "Invalid pinspec count: %d\n",
> +					     pinspec.args_count);
> +
> +		priv->siul2[i].gpio_base = pinspec.args[1];
> +		priv->siul2[i].gpio_num = pinspec.args[2];
> +	}
> +
> +	return 0;
> +}
> +
> +static int nxp_siul2_probe(struct platform_device *pdev)
> +{
> +	struct nxp_siul2_mfd *priv;
> +	int ret;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->num_siul2 = S32G_NUM_SIUL2;
> +	priv->siul2 = devm_kcalloc(&pdev->dev, priv->num_siul2,
> +				   sizeof(*priv->siul2), GFP_KERNEL);
> +	if (!priv->siul2)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, priv);
> +	ret = nxp_siul2_parse_dtb(pdev);
> +	if (ret)
> +		return ret;
> +
> +	return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
> +				    nxp_siul2_devs, ARRAY_SIZE(nxp_siul2_devs),
> +				    NULL, 0, NULL);
> +}
> +
> +static const struct of_device_id nxp_siul2_dt_ids[] = {
> +	{ .compatible = "nxp,s32g2-siul2" },
> +	{ .compatible = "nxp,s32g3-siul2" },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, nxp_siul2_dt_ids);
> +
> +static struct platform_driver nxp_siul2_mfd_driver = {
> +	.driver = {
> +		.name		= "nxp-siul2-mfd",
> +		.of_match_table	= nxp_siul2_dt_ids,
> +	},
> +	.probe = nxp_siul2_probe,
> +};
> +
> +module_platform_driver(nxp_siul2_mfd_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("NXP SIUL2 MFD driver");
> +MODULE_AUTHOR("Andrei Stefanescu <andrei.stefanescu at oss.nxp.com>");
> diff --git a/include/linux/mfd/nxp-siul2.h b/include/linux/mfd/nxp-siul2.h
> new file mode 100644
> index 000000000000..238c812dba29
> --- /dev/null
> +++ b/include/linux/mfd/nxp-siul2.h
> @@ -0,0 +1,55 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * S32 SIUL2 core definitions
> + *
> + * Copyright 2024 NXP
> + */
> +
> +#ifndef __DRIVERS_MFD_NXP_SIUL2_H
> +#define __DRIVERS_MFD_NXP_SIUL2_H
> +
> +#include <linux/regmap.h>
> +
> +/**
> + * enum nxp_siul2_reg_type - an enum for SIUL2 reg types
> + * @SIUL2_MPIDR - SoC info
> + * @SIUL2_IRQ - IRQ related registers, only valid in SIUL2_1
> + * @SIUL2_MSCR - used for pinmuxing and pinconf
> + * @SIUL2_IMCR - used for pinmuxing
> + * @SIUL2_PGPDO - writing the GPIO value
> + * @SIUL2_PGPDI - reading the GPIO value
> + */
> +enum nxp_siul2_reg_type {
> +	SIUL2_MPIDR,
> +	SIUL2_IRQ,
> +	SIUL2_MSCR,
> +	SIUL2_IMCR,
> +	SIUL2_PGPDO,
> +	SIUL2_PGPDI,
> +
> +	SIUL2_NUM_REG_TYPES
> +};
> +
> +/**
> + * struct nxp_siul2_info - details about one SIUL2 hardware instance
> + * @regmaps: the regmaps for each register type for a SIUL2 hardware instance
> + * @gpio_base: the first GPIO in this SIUL2 module
> + * @gpio_num: the number of GPIOs in this SIUL2 module
> + */
> +struct nxp_siul2_info {
> +	struct regmap *regmaps[SIUL2_NUM_REG_TYPES];
> +	u32 gpio_base;
> +	u32 gpio_num;
> +};
> +
> +/**
> + * struct nxp_siul2_mfd - driver data
> + * @siul2: info about the SIUL2 modules present
> + * @num_siul2: number of siul2 modules
> + */
> +struct nxp_siul2_mfd {
> +	struct nxp_siul2_info *siul2;
> +	u8 num_siul2;
> +};
> +
> +#endif /* __DRIVERS_MFD_NXP_SIUL2_H */
> -- 
> 2.45.2
> 

-- 
Lee Jones [???]


From qperret at google.com  Wed Dec 11 04:46:12 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 12:46:12 +0000
Subject: [PATCH v4 10/14] KVM: arm64: Calculate cptr_el2 traps on
 activating traps
In-Reply-To: <20241202154742.3611749-11-tabba@google.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-11-tabba@google.com>
Message-ID: <Z1mJlF-H5R_-f83I@google.com>

On Monday 02 Dec 2024 at 15:47:37 (+0000), Fuad Tabba wrote:
> -static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
> -{
> -	struct kvm *kvm = vcpu->kvm;
> -	u64 val = vcpu->arch.cptr_el2;
> -
> -	if (!has_hvhe()) {
> -		val |= CPTR_NVHE_EL2_RES1;
> -		val &= ~(CPTR_NVHE_EL2_RES0);
> -	}
> -
> -	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
> -		val |= CPTR_EL2_TAM;
> -
> -	/* SVE can be disabled by userspace even if supported. */
> -	if (!vcpu_has_sve(vcpu)) {
> -		if (has_hvhe())
> -			val &= ~(CPACR_ELx_ZEN);
> -		else
> -			val |= CPTR_EL2_TZ;
> -	}
> -
> -	/* No SME support in KVM. */
> -	BUG_ON(kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP));
> -	if (has_hvhe())
> -		val &= ~(CPACR_ELx_SMEN);
> -	else
> -		val |= CPTR_EL2_TSM;
> -
> -	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP)) {
> -		if (has_hvhe())
> -			val |= CPACR_EL1_TTA;
> -		else
> -			val |= CPTR_EL2_TTA;
> -	}
> -
> -	vcpu->arch.cptr_el2 = val;
> -}

Mooh, wasn't this function added in this very series? Not a huge deal,
but is there any way we could consolidate things a bit?


From brgl at bgdev.pl  Wed Dec 11 04:46:11 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Wed, 11 Dec 2024 13:46:11 +0100
Subject: arm64: include/linux/compiler_types.h:542:38: error: call to
 '__compiletime_assert_1050' declared with attribute error: clamp() low limit
 min greater than high limit max_avail
In-Reply-To: <bd95d7249ff94e31beb11b3f71a64e87@AcuMS.aculab.com>
References: <CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g@mail.gmail.com>
 <8dde5a62-4ce6-4954-86c9-54d961aed6df@stanley.mountain> <CA+G9fYv5gW1gByakU1yyQ__BoAKWkCcg=vGGyNep7+5p9_2uJA@mail.gmail.com>
 <bd95d7249ff94e31beb11b3f71a64e87@AcuMS.aculab.com>
Message-ID: <CAMRc=Mf8CmKs-_FddnLFU7aoOAPU6Xv8MqyZo8x9Uv-Eu+hs_g@mail.gmail.com>

On Fri, Dec 6, 2024 at 3:20?AM David Laight <David.Laight at aculab.com> wrote:
>
> From: Naresh Kamboju
> > Sent: 05 December 2024 18:42
> >
> > On Thu, 5 Dec 2024 at 20:46, Dan Carpenter <dan.carpenter at linaro.org> wrote:
> > >
> > > Add David to the CC list.
> >
> > Anders bisected this reported issue and found the first bad commit as,
> >
> > # first bad commit:
> >   [ef32b92ac605ba1b7692827330b9c60259f0af49]
> >   minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
>
> That 'just' changed the test to use __builtin_constant_p() and
> thus gets checked after the optimiser has run.
>
> I can paraphrase the code as:
> unsigned int fn(unsigned int x)
> {
>         return clamp(10, 5, x == 0 ? 0 : x - 1);
> }
> which is never actually called with x <= 5.
> The compiler converts it to:
>         return x < 0 ? clamp(10, 5, 0) : clamp(10, 5, x);
> (Probably because it can see that clamp(10, 5, 0) is constant.)
> And then the compile-time sanity check in clamp() fires.
>
> The order of the arguments to clamp is just wrong!
>
>         David
>

The build is still failing with today's next, should the offending
commit be reverted?

Bartosz


From tabba at google.com  Wed Dec 11 04:52:00 2024
From: tabba at google.com (Fuad Tabba)
Date: Wed, 11 Dec 2024 12:52:00 +0000
Subject: [PATCH v4 09/14] KVM: arm64: Remove redundant setting of HCR_EL2
 trap bit
In-Reply-To: <Z1mHtVJ4f7_N_wk4@google.com>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-10-tabba@google.com>
 <Z1mHtVJ4f7_N_wk4@google.com>
Message-ID: <CA+EHjTy=zpDx6OhcQFAk7uxcqQmsVUgB=DuZUppszr0KVPGZhA@mail.gmail.com>

On Wed, 11 Dec 2024 at 12:38, Quentin Perret <qperret at google.com> wrote:
>
> On Monday 02 Dec 2024 at 15:47:36 (+0000), Fuad Tabba wrote:
> > In hVHE mode, HCR_E2H should be set for both protected and
> > non-protected VMs. Since commit 23c9d58cb458 ("KVM: arm64: Fix
>
> I'm not finding that sha upstream, in which branch is it?

The whole commit is wrong, not just the hash, which refers to
something I have locally. It should be
b56680de9c64 ("KVM: arm64: Initialize trap register values in hyp in pKVM")

I'll fix on the respin. Thanks!
/fuad


> > initializing traps in protected mode"), this has been fixed, and
> > the setting of the flag here is redundant.
> >
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> > ---
> >  arch/arm64/kvm/hyp/nvhe/pkvm.c | 3 ---
> >  1 file changed, 3 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > index ffa500b500f2..cede527a59d4 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > @@ -57,9 +57,6 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
> >       /* No support for AArch32. */
> >       val |= HCR_RW;
> >
> > -     if (has_hvhe())
> > -             val |= HCR_E2H;
> > -
> >       /*
> >        * Always trap:
> >        * - Feature id registers: to control features exposed to guests
> > --
> > 2.47.0.338.g60cca15819-goog
> >


From tabba at google.com  Wed Dec 11 04:55:15 2024
From: tabba at google.com (Fuad Tabba)
Date: Wed, 11 Dec 2024 12:55:15 +0000
Subject: [PATCH v4 10/14] KVM: arm64: Calculate cptr_el2 traps on
 activating traps
In-Reply-To: <Z1mJlF-H5R_-f83I@google.com>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-11-tabba@google.com>
 <Z1mJlF-H5R_-f83I@google.com>
Message-ID: <CA+EHjTwDSo3XXxruPQSbJZJ7wNqyFX4fec-SFuYfd2XBqJX_DA@mail.gmail.com>

On Wed, 11 Dec 2024 at 12:46, Quentin Perret <qperret at google.com> wrote:
>
> On Monday 02 Dec 2024 at 15:47:37 (+0000), Fuad Tabba wrote:
> > -static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
> > -{
> > -     struct kvm *kvm = vcpu->kvm;
> > -     u64 val = vcpu->arch.cptr_el2;
> > -
> > -     if (!has_hvhe()) {
> > -             val |= CPTR_NVHE_EL2_RES1;
> > -             val &= ~(CPTR_NVHE_EL2_RES0);
> > -     }
> > -
> > -     if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
> > -             val |= CPTR_EL2_TAM;
> > -
> > -     /* SVE can be disabled by userspace even if supported. */
> > -     if (!vcpu_has_sve(vcpu)) {
> > -             if (has_hvhe())
> > -                     val &= ~(CPACR_ELx_ZEN);
> > -             else
> > -                     val |= CPTR_EL2_TZ;
> > -     }
> > -
> > -     /* No SME support in KVM. */
> > -     BUG_ON(kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP));
> > -     if (has_hvhe())
> > -             val &= ~(CPACR_ELx_SMEN);
> > -     else
> > -             val |= CPTR_EL2_TSM;
> > -
> > -     if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP)) {
> > -             if (has_hvhe())
> > -                     val |= CPACR_EL1_TTA;
> > -             else
> > -                     val |= CPTR_EL2_TTA;
> > -     }
> > -
> > -     vcpu->arch.cptr_el2 = val;
> > -}
>
> Mooh, wasn't this function added in this very series? Not a huge deal,
> but is there any way we could consolidate things a bit?

Yes it was, but it was added when I was doing the grouping in Patch
02, without changing the actual trapping, to make that commit easier
to read. If I were to consolidate them then Patch 02 would be changing
more than one thing at the same time, making it (imo) more difficult
to reason about things...

/fuad


From michal.simek at amd.com  Wed Dec 11 04:41:20 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:20 +0100
Subject: [PATCH 01/15] ARM: zynq: Replace 'io-standard' with 'power-source' property
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <cf45ed95fe0be083446d5aaf5f946f38acba7728.1733920873.git.michal.simek@amd.com>

From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>

Replace 'io-standard' property with 'power-source' property in all
zynq dts files to be in sync with Zynq Pinctrl driver.

Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-zc702.dts | 22 +++++++++++-----------
 arch/arm/boot/dts/xilinx/zynq-zc706.dts | 18 +++++++++---------
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
index 6efdbca9d3ef..a933c0341b69 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
@@ -210,7 +210,7 @@ mux {
 		conf {
 			groups = "can0_9_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
@@ -233,7 +233,7 @@ mux {
 		conf {
 			groups = "ethernet0_0_grp";
 			slew-rate = <0>;
-			io-standard = <4>;
+			power-source = <4>;
 		};
 
 		conf-rx {
@@ -256,7 +256,7 @@ mux-mdio {
 		conf-mdio {
 			groups = "mdio0_0_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 			bias-disable;
 		};
 	};
@@ -274,7 +274,7 @@ conf {
 				 "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
 				 "gpio0_13_grp", "gpio0_14_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-pull-up {
@@ -298,7 +298,7 @@ conf {
 			groups = "i2c0_10_grp";
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -311,7 +311,7 @@ mux {
 		conf {
 			groups = "gpio0_50_grp", "gpio0_51_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -324,7 +324,7 @@ mux {
 		conf {
 			groups = "sdio0_2_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 			bias-disable;
 		};
 
@@ -338,7 +338,7 @@ conf-cd {
 			bias-high-impedance;
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		mux-wp {
@@ -351,7 +351,7 @@ conf-wp {
 			bias-high-impedance;
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -364,7 +364,7 @@ mux {
 		conf {
 			groups = "uart1_10_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
@@ -387,7 +387,7 @@ mux {
 		conf {
 			groups = "usb0_0_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc706.dts b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
index 77943c16d33f..d21e3ae4ebb2 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc706.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
@@ -150,7 +150,7 @@ mux {
 		conf {
 			groups = "ethernet0_0_grp";
 			slew-rate = <0>;
-			io-standard = <4>;
+			power-source = <4>;
 		};
 
 		conf-rx {
@@ -173,7 +173,7 @@ mux-mdio {
 		conf-mdio {
 			groups = "mdio0_0_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 			bias-disable;
 		};
 	};
@@ -187,7 +187,7 @@ mux {
 		conf {
 			groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-pull-up {
@@ -211,7 +211,7 @@ conf {
 			groups = "i2c0_10_grp";
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -224,7 +224,7 @@ mux {
 		conf {
 			groups = "sdio0_2_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 			bias-disable;
 		};
 
@@ -238,7 +238,7 @@ conf-cd {
 			bias-high-impedance;
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		mux-wp {
@@ -251,7 +251,7 @@ conf-wp {
 			bias-high-impedance;
 			bias-pull-up;
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 	};
 
@@ -264,7 +264,7 @@ mux {
 		conf {
 			groups = "uart1_10_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
@@ -287,7 +287,7 @@ mux {
 		conf {
 			groups = "usb0_0_grp";
 			slew-rate = <0>;
-			io-standard = <1>;
+			power-source = <1>;
 		};
 
 		conf-rx {
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:19 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:19 +0100
Subject: [PATCH 00/15] ARM: zynq: Sync DTs with U-Boot
Message-ID: <cover.1733920873.git.michal.simek@amd.com>

Hi,

over years there were some changes pushed to U-Boot which were never merged
back to Linux. U-Boot introduced new option OF_UPSTREAM and start to sync
up DTs from Linux back to U-Boot.
This series is addressing differences.
There are still 3 more differences but they should be addressed separately.

Thanks,
Michal


Michal Simek (14):
  ARM: zynq: Remove deprecated device_type property
  ARM: zynq: DT: List OCM memory for all platforms
  ARM: zynq: Mark boot-phase-specific device nodes
  ARM: zynq: Do not define address/size-cells for nand-controller
  ARM: zynq: Wire smcc with nand/nor memories on zc770 platform
  ARM: zynq: Add ethernet phy reset information to DT(zc702)
  ARM: zynq: Define u-boot bootscrip addr via DT
  ARM: zynq: Point via nvmem0 alias to eeprom on zc702/zc706
  ARM: zynq: Define rtc alias on zc702/zc706
  ARM: zynq: Rename i2c?-gpio to i2c?-gpio-grp
  ARM: zynq: Fix fpga region DT nodes name
  ARM: zynq: Enable QSPIs on platforms
  ARM: zynq: Add sdhci to alias node
  ARM: zynq: Remove ethernet0 alias from Microzed

Sai Krishna Potthuri (1):
  ARM: zynq: Replace 'io-standard' with 'power-source' property

 arch/arm/boot/dts/xilinx/zynq-7000.dtsi       | 33 ++++++-
 arch/arm/boot/dts/xilinx/zynq-cc108.dts       | 41 ++++++++-
 arch/arm/boot/dts/xilinx/zynq-microzed.dts    | 10 ++-
 arch/arm/boot/dts/xilinx/zynq-parallella.dts  |  1 -
 arch/arm/boot/dts/xilinx/zynq-zc702.dts       | 87 +++++++++++++------
 arch/arm/boot/dts/xilinx/zynq-zc706.dts       | 67 +++++++++++---
 arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts | 39 ++++++++-
 arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts | 31 +++++++
 arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts | 35 ++++++++
 arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts | 41 ++++++++-
 arch/arm/boot/dts/xilinx/zynq-zed.dts         | 43 ++++++++-
 .../boot/dts/xilinx/zynq-zturn-common.dtsi    |  8 ++
 arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts     | 10 ++-
 arch/arm/boot/dts/xilinx/zynq-zybo.dts        |  9 +-
 14 files changed, 404 insertions(+), 51 deletions(-)

-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:21 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:21 +0100
Subject: [PATCH 02/15] ARM: zynq: Remove deprecated device_type property
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <77152dc14271a2340f63e6d407f36293ed656d49.1733920873.git.michal.simek@amd.com>

Based on DT specification device_type property is deprecated and should be
used only for cpu and memory nodes. That's why remove other usage. In this
case ethernet phy.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-cc108.dts       | 1 -
 arch/arm/boot/dts/xilinx/zynq-parallella.dts  | 1 -
 arch/arm/boot/dts/xilinx/zynq-zc702.dts       | 1 -
 arch/arm/boot/dts/xilinx/zynq-zc706.dts       | 1 -
 arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts | 1 -
 arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts | 1 -
 arch/arm/boot/dts/xilinx/zynq-zed.dts         | 1 -
 arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts     | 1 -
 arch/arm/boot/dts/xilinx/zynq-zybo.dts        | 1 -
 9 files changed, 9 deletions(-)

diff --git a/arch/arm/boot/dts/xilinx/zynq-cc108.dts b/arch/arm/boot/dts/xilinx/zynq-cc108.dts
index 8b9ab9bba23b..b930a5953b49 100644
--- a/arch/arm/boot/dts/xilinx/zynq-cc108.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-cc108.dts
@@ -48,7 +48,6 @@ &gem0 {
 
 	ethernet_phy: ethernet-phy at 1 {
 		reg = <1>;
-		device_type = "ethernet-phy";
 	};
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-parallella.dts b/arch/arm/boot/dts/xilinx/zynq-parallella.dts
index 54592aeb92b9..366af4fcf8d9 100644
--- a/arch/arm/boot/dts/xilinx/zynq-parallella.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-parallella.dts
@@ -46,7 +46,6 @@ ethernet_phy: ethernet-phy at 0 {
 		compatible = "ethernet-phy-id0141.0e90",
 		             "ethernet-phy-ieee802.3-c22";
 		reg = <0>;
-		device_type = "ethernet-phy";
 		marvell,reg-init = <0x3 0x10 0xff00 0x1e>,
 		                   <0x3 0x11 0xfff0 0xa>;
 	};
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
index a933c0341b69..b77d2ae82606 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
@@ -95,7 +95,6 @@ &gem0 {
 
 	ethernet_phy: ethernet-phy at 7 {
 		reg = <7>;
-		device_type = "ethernet-phy";
 	};
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc706.dts b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
index d21e3ae4ebb2..50636906981e 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc706.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
@@ -46,7 +46,6 @@ &gem0 {
 
 	ethernet_phy: ethernet-phy at 7 {
 		reg = <7>;
-		device_type = "ethernet-phy";
 	};
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts
index 0dd352289a45..9bb5b3a5252f 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts
@@ -45,7 +45,6 @@ &gem0 {
 
 	ethernet_phy: ethernet-phy at 7 {
 		reg = <7>;
-		device_type = "ethernet-phy";
 	};
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts
index 38d96adc870c..3fd0d05588bb 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts
@@ -40,7 +40,6 @@ &gem1 {
 
 	ethernet_phy: ethernet-phy at 7 {
 		reg = <7>;
-		device_type = "ethernet-phy";
 	};
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zed.dts b/arch/arm/boot/dts/xilinx/zynq-zed.dts
index 6a5a93aa6552..63effb7809c5 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zed.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zed.dts
@@ -43,7 +43,6 @@ &gem0 {
 
 	ethernet_phy: ethernet-phy at 0 {
 		reg = <0>;
-		device_type = "ethernet-phy";
 	};
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts b/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
index 7b87e10d3953..da76cfd65832 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
@@ -49,7 +49,6 @@ &gem0 {
 
 	ethernet_phy: ethernet-phy at 0 {
 		reg = <0>;
-		device_type = "ethernet-phy";
 	};
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zybo.dts b/arch/arm/boot/dts/xilinx/zynq-zybo.dts
index 755f6f109d5a..4784ef115dad 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zybo.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zybo.dts
@@ -44,7 +44,6 @@ &gem0 {
 
 	ethernet_phy: ethernet-phy at 0 {
 		reg = <0>;
-		device_type = "ethernet-phy";
 	};
 };
 
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:22 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:22 +0100
Subject: [PATCH 03/15] ARM: zynq: DT: List OCM memory for all platforms
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <68da82d3d0733e33672562487a9df4a9374d8e1a.1733920873.git.michal.simek@amd.com>

Move OCM description from zc702 to all zynq boards.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-7000.dtsi | 11 +++++++++++
 arch/arm/boot/dts/xilinx/zynq-zc702.dts | 13 -------------
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
index a7db3f3009f2..fe224d41320c 100644
--- a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
@@ -190,6 +190,17 @@ mc: memory-controller at f8006000 {
 			reg = <0xf8006000 0x1000>;
 		};
 
+		ocm: sram at fffc0000 {
+			compatible = "mmio-sram";
+			reg = <0xfffc0000 0x10000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0xfffc0000 0x10000>;
+			ocm-sram at 0 {
+				reg = <0x0 0x10000>;
+			};
+		};
+
 		uart0: serial at e0000000 {
 			compatible = "xlnx,xuartps", "cdns,uart-r1p8";
 			status = "disabled";
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
index b77d2ae82606..126c0b0ecdda 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
@@ -63,19 +63,6 @@ usb_phy0: phy0 {
 	};
 };
 
-&amba {
-	ocm: sram at fffc0000 {
-		compatible = "mmio-sram";
-		reg = <0xfffc0000 0x10000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0xfffc0000 0x10000>;
-		ocm-sram at 0 {
-			reg = <0x0 0x10000>;
-		};
-	};
-};
-
 &can0 {
 	status = "okay";
 	pinctrl-names = "default";
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:23 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:23 +0100
Subject: [PATCH 04/15] ARM: zynq: Mark boot-phase-specific device nodes
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <f25387e0123ee81f7d8246add3c6ec063f3cfa78.1733920873.git.michal.simek@amd.com>

Tag boot specific device nodes which are required for booting.
In our case this is sync up with U-Boot project where all these IPs are
already tagged and tested.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-7000.dtsi         | 4 ++++
 arch/arm/boot/dts/xilinx/zynq-cc108.dts         | 1 +
 arch/arm/boot/dts/xilinx/zynq-microzed.dts      | 2 ++
 arch/arm/boot/dts/xilinx/zynq-zc702.dts         | 2 ++
 arch/arm/boot/dts/xilinx/zynq-zc706.dts         | 2 ++
 arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts   | 1 +
 arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts   | 1 +
 arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts   | 1 +
 arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts   | 1 +
 arch/arm/boot/dts/xilinx/zynq-zed.dts           | 2 ++
 arch/arm/boot/dts/xilinx/zynq-zturn-common.dtsi | 3 +++
 arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts       | 2 ++
 arch/arm/boot/dts/xilinx/zynq-zybo.dts          | 2 ++
 13 files changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
index fe224d41320c..0dfe2ddd0b5f 100644
--- a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
@@ -93,6 +93,7 @@ replicator_in_port0: endpoint {
 	};
 
 	amba: axi {
+		bootph-all;
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -319,12 +320,14 @@ sdhci1: mmc at e0101000 {
 		};
 
 		slcr: slcr at f8000000 {
+			bootph-all;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd";
 			reg = <0xF8000000 0x1000>;
 			ranges;
 			clkc: clkc at 100 {
+				bootph-all;
 				#clock-cells = <1>;
 				compatible = "xlnx,ps7-clkc";
 				fclk-enable = <0>;
@@ -409,6 +412,7 @@ ttc1: timer at f8002000 {
 		};
 
 		scutimer: timer at f8f00600 {
+			bootph-all;
 			interrupt-parent = <&intc>;
 			interrupts = <1 13 0x301>;
 			compatible = "arm,cortex-a9-twd-timer";
diff --git a/arch/arm/boot/dts/xilinx/zynq-cc108.dts b/arch/arm/boot/dts/xilinx/zynq-cc108.dts
index b930a5953b49..5e542ded3d0c 100644
--- a/arch/arm/boot/dts/xilinx/zynq-cc108.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-cc108.dts
@@ -58,6 +58,7 @@ &sdhci1 {
 };
 
 &uart0 {
+	bootph-all;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-microzed.dts b/arch/arm/boot/dts/xilinx/zynq-microzed.dts
index 6ed84fb15902..f2f560cc0c0d 100644
--- a/arch/arm/boot/dts/xilinx/zynq-microzed.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-microzed.dts
@@ -46,10 +46,12 @@ ethernet_phy: ethernet-phy at 0 {
 };
 
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
index 126c0b0ecdda..424e78f6c148 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
@@ -390,12 +390,14 @@ conf-tx {
 };
 
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdhci0_default>;
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1_default>;
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc706.dts b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
index 50636906981e..199fb37257c2 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc706.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
@@ -303,12 +303,14 @@ conf-tx {
 };
 
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdhci0_default>;
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1_default>;
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts
index 9bb5b3a5252f..02876f6d23a5 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts
@@ -84,6 +84,7 @@ partition at 0 {
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts
index 56732e8f6ca1..ba040743e10d 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts
@@ -54,6 +54,7 @@ &spi0 {
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts
index d2359b789eb8..d6392d4ece9c 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts
@@ -60,5 +60,6 @@ &spi1 {
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts
index 3fd0d05588bb..f07af61eaa29 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts
@@ -72,5 +72,6 @@ eeprom: eeprom at 2 {
 };
 
 &uart0 {
+	bootph-all;
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/xilinx/zynq-zed.dts b/arch/arm/boot/dts/xilinx/zynq-zed.dts
index 63effb7809c5..ff2b4e06efbb 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zed.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zed.dts
@@ -47,10 +47,12 @@ ethernet_phy: ethernet-phy at 0 {
 };
 
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zturn-common.dtsi b/arch/arm/boot/dts/xilinx/zynq-zturn-common.dtsi
index 33b02e05ce82..800e891495f5 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zturn-common.dtsi
+++ b/arch/arm/boot/dts/xilinx/zynq-zturn-common.dtsi
@@ -73,14 +73,17 @@ ethernet_phy: ethernet-phy at 0 {
 };
 
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 };
 
 &uart0 {
+	bootph-all;
 	status = "okay";
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts b/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
index da76cfd65832..6983caa35b0d 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts
@@ -53,10 +53,12 @@ ethernet_phy: ethernet-phy at 0 {
 };
 
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/xilinx/zynq-zybo.dts b/arch/arm/boot/dts/xilinx/zynq-zybo.dts
index 4784ef115dad..f365693fe2f7 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zybo.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zybo.dts
@@ -48,10 +48,12 @@ ethernet_phy: ethernet-phy at 0 {
 };
 
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 };
 
 &uart1 {
+	bootph-all;
 	status = "okay";
 };
 
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:24 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:24 +0100
Subject: [PATCH 05/15] ARM: zynq: Do not define address/size-cells for nand-controller
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <37057526d8ee14416f61fb6e2b82bed65bde5d3c.1733920873.git.michal.simek@amd.com>

There is no reason to define address/size-cells without defining child
nodes. That's why remove them.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-7000.dtsi | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
index 0dfe2ddd0b5f..d334b5f75c8e 100644
--- a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
@@ -294,8 +294,6 @@ nfc0: nand-controller at 0,0 {
 				compatible = "arm,pl353-nand-r2p1";
 				reg = <0 0 0x1000000>;
 				status = "disabled";
-				#address-cells = <1>;
-				#size-cells = <0>;
 			};
 		};
 
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:26 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:26 +0100
Subject: [PATCH 07/15] ARM: zynq: Add ethernet phy reset information to DT(zc702)
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <9e18d59ca339804320d2a5e3c7362aefa3bb7c99.1733920873.git.michal.simek@amd.com>

Added phy reset gpio information for gem0.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-zc702.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
index 424e78f6c148..975385f4ac01 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
@@ -79,6 +79,8 @@ &gem0 {
 	phy-handle = <&ethernet_phy>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_gem0_default>;
+	phy-reset-gpio = <&gpio0 11 0>;
+	phy-reset-active-low;
 
 	ethernet_phy: ethernet-phy at 7 {
 		reg = <7>;
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:25 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:25 +0100
Subject: [PATCH 06/15] ARM: zynq: Wire smcc with nand/nor memories on zc770 platform
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <12e697975a1d026e811c2f63aa8bbbd0b9ff4f70.1733920873.git.michal.simek@amd.com>

Describe nor child flash node under smcc and enable it for xm012 extension
card. And also describe nand flash memory for xm011 card.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-7000.dtsi       |  7 ++++
 arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts | 30 ++++++++++++++++
 arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts | 34 +++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
index d334b5f75c8e..268647668db2 100644
--- a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
@@ -289,12 +289,19 @@ smcc: memory-controller at e000e000 {
 				  0x2 0x0 0xe4000000 0x2000000>; /* SRAM/NOR CS1 region */
 			#address-cells = <2>;
 			#size-cells = <1>;
+			interrupt-parent = <&intc>;
+			interrupts = <0 18 4>;
 
 			nfc0: nand-controller at 0,0 {
 				compatible = "arm,pl353-nand-r2p1";
 				reg = <0 0 0x1000000>;
 				status = "disabled";
 			};
+			nor0: flash at 1,0 {
+				status = "disabled";
+				compatible = "cfi-flash";
+				reg = <1 0 0x2000000>;
+			};
 		};
 
 		sdhci0: mmc at e0100000 {
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts
index ba040743e10d..f9a086fe66d3 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts
@@ -47,6 +47,36 @@ eeprom: eeprom at 52 {
 	};
 };
 
+&nfc0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	nand at 0 {
+		reg = <0>;
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition at 0 {
+				label = "nand-fsbl-uboot";
+				reg = <0x0 0x1000000>;
+			};
+			partition at 1000000 {
+				label = "nand-linux";
+				reg = <0x1000000 0x2000000>;
+			};
+			partition at 3000000 {
+				label = "nand-rootfs";
+				reg = <0x3000000 0x200000>;
+			};
+		};
+	};
+};
+
+&smcc {
+	status = "okay";
+};
+
 &spi0 {
 	status = "okay";
 	num-cs = <4>;
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts b/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts
index d6392d4ece9c..24520e7d3965 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts
@@ -53,6 +53,40 @@ eeprom1: eeprom at 52 {
 	};
 };
 
+&nor0 {
+	status = "okay";
+	bank-width = <1>;
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		partition at 0 {
+			label = "nor-fsbl-uboot";
+			reg = <0x0 0x100000>;
+		};
+		partition at 100000 {
+			label = "nor-linux";
+			reg = <0x100000 0x500000>;
+		};
+		partition at 600000 {
+			label = "nor-device-tree";
+			reg = <0x600000 0x20000>;
+		};
+		partition at 620000 {
+			label = "nor-rootfs";
+			reg = <0x620000 0x5e0000>;
+		};
+		partition at c00000 {
+			label = "nor-bitstream";
+			reg = <0xc00000 0x400000>;
+		};
+	};
+};
+
+&smcc {
+	status = "okay";
+};
+
 &spi1 {
 	status = "okay";
 	num-cs = <4>;
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:27 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:27 +0100
Subject: [PATCH 08/15] ARM: zynq: Define u-boot bootscrip addr via DT
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <9252bb464c5c82fda6018ea450c6f453a5d8412c.1733920873.git.michal.simek@amd.com>

Define bootscript address in RAM via DT property. Adding default value to
common DTSI. Platform DT description can remove this property or rewrite
it.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

bootscr-address is documented in dt-schema already.
---
 arch/arm/boot/dts/xilinx/zynq-7000.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
index 268647668db2..46182a5690b8 100644
--- a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
@@ -8,6 +8,13 @@ / {
 	#size-cells = <1>;
 	compatible = "xlnx,zynq-7000";
 
+	options {
+		u-boot {
+			compatible = "u-boot,config";
+			bootscr-address = /bits/ 64 <0x3000000>;
+		};
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:28 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:28 +0100
Subject: [PATCH 09/15] ARM: zynq: Point via nvmem0 alias to eeprom on zc702/zc706
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <c4a28874455a8747638551cf09ba31aa803b8b09.1733920873.git.michal.simek@amd.com>

EEPROM stores identification information about board like a board name,
revision, serial number and ethernet MAC address. U-Boot is capable to read
nvmemX aliases and read/display provided information when nvmem alias link
is described.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-zc702.dts | 3 ++-
 arch/arm/boot/dts/xilinx/zynq-zc706.dts | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
index 975385f4ac01..9a4f3e822c7e 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
@@ -16,6 +16,7 @@ aliases {
 		i2c0 = &i2c0;
 		serial0 = &uart1;
 		mmc0 = &sdhci0;
+		nvmem0 = &eeprom;
 	};
 
 	memory at 0 {
@@ -140,7 +141,7 @@ i2c at 2 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <2>;
-			eeprom at 54 {
+			eeprom: eeprom at 54 {
 				compatible = "atmel,24c08";
 				reg = <0x54>;
 			};
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc706.dts b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
index 199fb37257c2..1ebf8e422c3c 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc706.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
@@ -15,6 +15,7 @@ aliases {
 		i2c0 = &i2c0;
 		serial0 = &uart1;
 		mmc0 = &sdhci0;
+		nvmem0 = &eeprom;
 	};
 
 	memory at 0 {
@@ -99,7 +100,7 @@ i2c at 2 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <2>;
-			eeprom at 54 {
+			eeprom: eeprom at 54 {
 				compatible = "atmel,24c08";
 				reg = <0x54>;
 			};
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:29 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:29 +0100
Subject: [PATCH 10/15] ARM: zynq: Define rtc alias on zc702/zc706
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <9ee86a22d15fb127b8b31cf1ab6059ffb05ad55b.1733920873.git.michal.simek@amd.com>

Define rtc alias on zc702/zc706 boards.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-zc702.dts | 3 ++-
 arch/arm/boot/dts/xilinx/zynq-zc706.dts | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
index 9a4f3e822c7e..b5db97dd7192 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
@@ -17,6 +17,7 @@ aliases {
 		serial0 = &uart1;
 		mmc0 = &sdhci0;
 		nvmem0 = &eeprom;
+		rtc0 = &rtc;
 	};
 
 	memory at 0 {
@@ -163,7 +164,7 @@ i2c at 4 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <4>;
-			rtc at 51 {
+			rtc: rtc at 51 {
 				compatible = "nxp,pcf8563";
 				reg = <0x51>;
 			};
diff --git a/arch/arm/boot/dts/xilinx/zynq-zc706.dts b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
index 1ebf8e422c3c..1e38c5caec22 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc706.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc706.dts
@@ -16,6 +16,7 @@ aliases {
 		serial0 = &uart1;
 		mmc0 = &sdhci0;
 		nvmem0 = &eeprom;
+		rtc0 = &rtc;
 	};
 
 	memory at 0 {
@@ -122,7 +123,7 @@ i2c at 4 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <4>;
-			rtc at 51 {
+			rtc: rtc at 51 {
 				compatible = "nxp,pcf8563";
 				reg = <0x51>;
 			};
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:30 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:30 +0100
Subject: [PATCH 11/15] ARM: zynq: Rename i2c?-gpio to i2c?-gpio-grp
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <43b2f451bfd2ebce70f3ac6442586838d3e21951.1733920873.git.michal.simek@amd.com>

Anything ending with gpio/gpios is taken as gpio phande/description which
is reported as the issue coming from gpio-consumer.yaml schema.
That's why rename the gpio suffix to gpio-grp to avoid name collision.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-zc702.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
index b5db97dd7192..e4c9491081f8 100644
--- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
+++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
@@ -292,7 +292,7 @@ conf {
 		};
 	};
 
-	pinctrl_i2c0_gpio: i2c0-gpio {
+	pinctrl_i2c0_gpio: i2c0-gpio-grp {
 		mux {
 			groups = "gpio0_50_grp", "gpio0_51_grp";
 			function = "gpio0";
-- 
2.43.0



From michal.simek at amd.com  Wed Dec 11 04:41:31 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 13:41:31 +0100
Subject: [PATCH 12/15] ARM: zynq: Fix fpga region DT nodes name
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <0fcce9f0fa4fc2e170a7c5374d0b4063fa0bbd71.1733920873.git.michal.simek@amd.com>

fpga-full is not aligned with the latest dt-schema. Generic name
fpga-region should be used.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/boot/dts/xilinx/zynq-7000.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
index 46182a5690b8..153b8d93cbee 100644
--- a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
@@ -41,7 +41,7 @@ cpu1: cpu at 1 {
 		};
 	};
 
-	fpga_full: fpga-full {
+	fpga_full: fpga-region {
 		compatible = "fpga-region";
 		fpga-mgr = <&devcfg>;
 		#address-cells = <1>;
-- 
2.43.0



From laurent.pinchart at ideasonboard.com  Wed Dec 11 04:59:36 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 11 Dec 2024 14:59:36 +0200
Subject: [PATCH] drm: zynqmp_dp: Fix integer overflow in
 zynqmp_dp_rate_get()
In-Reply-To: <20241211122026.797511-1-karprzy7@gmail.com>
References: <20241211122026.797511-1-karprzy7@gmail.com>
Message-ID: <20241211125936.GA23711@pendragon.ideasonboard.com>

Hi Karol,

Thank you for the patch.

On Wed, Dec 11, 2024 at 01:20:26PM +0100, Karol Przybylski wrote:
> This patch fixes a potential integer overflow in the zynqmp_dp_rate_get() function.
> 
> The issue comes up when the expression drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000 is evaluated using 32-bit arithmetic.

Please wrap your commit message text to 82 columns.

> 
> Now the constant is casted to compatible u64 type.
> 
> Resolves CID 1636340 and CID 1635811
> 

Does this need a Fixes: tag ? How about 'Cc: stable at vger.kernel.org' to
get it backported to stable kernels ?

> Signed-off-by: Karol Przybylski <karprzy7 at gmail.com>
> ---
>  drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index 25c5dc61e..55e92344b 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -2190,7 +2190,7 @@ static int zynqmp_dp_rate_get(void *data, u64 *val)
>  	struct zynqmp_dp *dp = data;
>  
>  	mutex_lock(&dp->lock);
> -	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000;
> +	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * (u64)10000;

You can also make the integer a 64-bit constant with

	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000ULL;

>  	mutex_unlock(&dp->lock);
>  	return 0;
>  }

-- 
Regards,

Laurent Pinchart


From heiko at sntech.de  Wed Dec 11 05:01:48 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 11 Dec 2024 14:01:48 +0100
Subject: [PATCH v9 1/9] HID: hid-sensor-hub: don't use stale platform-data on
 remove
In-Reply-To: <n914pn7o-pr9n-5ss0-p744-73402nnn843p@xreary.bet>
References: <20241107114712.538976-1-heiko@sntech.de> <20241211120844.GD7139@google.com>
 <n914pn7o-pr9n-5ss0-p744-73402nnn843p@xreary.bet>
Message-ID: <3196449.TQGk6oTFT5@diego>

Am Mittwoch, 11. Dezember 2024, 13:24:42 CET schrieb Jiri Kosina:
> On Wed, 11 Dec 2024, Lee Jones wrote:
> 
> > > > > This change was more or less a surprise find, because I wanted to make
> > > > > the platform_data pointer in the mfd_cell struct const and this the hid
> > > > > sensor hub stood out as doing something strange ;-) .
> > > > > 
> > > > > So patch 2 of this series actually depends on this change to not cause
> > > > > build errors.
> > > > 
> > > > Ah, right.
> > > > 
> > > > > But seeing that we're after -rc6 alredy, I would assume the brunt of the 
> > > > > mcu series might need to wait after 6.13-rc1 anyway - but I guess that 
> > > > > depends on how Lee sees things ;-) .
> > > > 
> > > > OK, I am keeping my hands off it for the time being.
> > > 
> > > I can take it now with an Ack.
> > 
> > Looking to apply this set now.
> > 
> > Ack please.
> 
> I'd preferer if Srinivas could ack this as the more specific maintainer. 
> Srinivas, please? 

The patch already includes the
   Ack from Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>
from a previous version, so I guess it should be ok already?





From linus.walleij at linaro.org  Wed Dec 11 05:04:03 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Dec 2024 14:04:03 +0100
Subject: [PATCH 1/4] ARM: Disable jump-label on PREEMPT_RT
In-Reply-To: <20241210160556.2341497-2-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org> <20241210160556.2341497-2-arnd@kernel.org>
Message-ID: <CACRpkdYP6yWHuWGwHZCe7SQLg-BFtLb-KKHxqrXbeM2hhrsgfA@mail.gmail.com>

On Tue, Dec 10, 2024 at 5:06?PM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Thomas Gleixner <tglx at linutronix.de>
>
> jump-labels are used to efficiently switch between two possible code
> paths. To achieve this, stop_machine() is used to keep the CPU in a
> known state while the opcode is modified. The usage of stop_machine()
> here leads to large latency spikes which can be observed on PREEMPT_RT.
>
> Jump labels may change the target during runtime and are not restricted
> to debug or "configuration/ setup" part of a PREEMPT_RT system where
> high latencies could be defined as acceptable.
>
> On 64-bit Arm, it is possible to use jump labels without the
> stop_machine() call, which architecturally provides a way to atomically
> change one 32-bit instruction word while keeping maintaining consistency,
> but this is not generally the case on 32-bit, in particular in thumb2
> mode.
>
> Disable jump-label support on a PREEMPT_RT system when SMP is enabled.
>
> [bigeasy: Patch description.]
> [arnd: add !SMP case, extend changelog]
>
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Link: https://lkml.kernel.org/r/20220613182447.112191-2-bigeasy at linutronix.de
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Makes sense.

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From andre.przywara at arm.com  Wed Dec 11 05:08:53 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 11 Dec 2024 13:08:53 +0000
Subject: [PATCH 2/2] ARM: dts: sunxi: add support for RerVision
 A33-Vstar board
In-Reply-To: <7310cb53109197e61a24659b259f5148b3962328.camel@icenowy.me>
References: <20240913104845.4112986-1-uwu@icenowy.me>
	<20240913104845.4112986-2-uwu@icenowy.me>
	<7310cb53109197e61a24659b259f5148b3962328.camel@icenowy.me>
Message-ID: <20241211130853.25b82d7b@donnerap.manchester.arm.com>

On Tue, 17 Sep 2024 17:54:38 +0800
Icenowy Zheng <uwu at icenowy.me> wrote:

Hi,

I do understand it's too late now, but just saw some oddities about the
regulator voltages when looking at the U-Boot version of this patch:

> ? 2024-09-13???? 18:48 +0800?Icenowy Zheng???
> > RerVision A33-Vstar board is a board based on their A33-Core1 SoM
> > (A33
> > SoC + 512MiB DRAM + 4GiB eMMC + AXP223 PMIC), with multiple
> > peripherals:
> > 
> > - MicroSD card slot
> > - 4.0mm/1.7mm DC jack connected to ACIN of AXP223 (and a XH2.54 2-pin
> > ? connector for alternative 5V DC IN)
> > - OTG-capable microUSB port
> > - Reserved pads for soldering Li-ion battery and/or 3V RTC battery
> > - 3 LRADC-attached keys and 2 fixed function power/reset keys
> > - AP6212 Wi-Fi/BT combo module
> > - On-board GL850G hub attached to the USB host port of A33, and a
> > ? RTL8152 USB Ethernet chip at the downstream of the hub
> > - Onboard microphone (not supported yet) and headphone jack
> > - 3 UART ports as PH2.0 3-pin connectors (UART2 one is currently used
> > as
> > ? debug output and others are ignored yet)
> > 
> > Signed-off-by: Icenowy Zheng <uwu at icenowy.me>
> > ---  
> 
> Add a dependency to this patch at [1], which allows GL850G to have
> downstream device nodes in DT.
> 
> [1]
> https://lore.kernel.org/lkml/20240917094008.283529-1-uwu at icenowy.me/
> 
> > ?arch/arm/boot/dts/allwinner/Makefile????????? |?? 1 +
> > ?.../dts/allwinner/sun8i-a33-vstar-core1.dtsi? |? 96 ++++++++
> > ?.../boot/dts/allwinner/sun8i-a33-vstar.dts??? | 205
> > ++++++++++++++++++
> > ?3 files changed, 302 insertions(+)
> > ?create mode 100644 arch/arm/boot/dts/allwinner/sun8i-a33-vstar-
> > core1.dtsi
> > ?create mode 100644 arch/arm/boot/dts/allwinner/sun8i-a33-vstar.dts
> > 
> > diff --git a/arch/arm/boot/dts/allwinner/Makefile
> > b/arch/arm/boot/dts/allwinner/Makefile
> > index cd0d044882cf8..d548f4a2621a1 100644
> > --- a/arch/arm/boot/dts/allwinner/Makefile
> > +++ b/arch/arm/boot/dts/allwinner/Makefile
> > @@ -215,6 +215,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
> > ????????sun8i-a33-olinuxino.dtb \
> > ????????sun8i-a33-q8-tablet.dtb \
> > ????????sun8i-a33-sinlinx-sina33.dtb \
> > +???????sun8i-a33-vstar.dtb \
> > ????????sun8i-a83t-allwinner-h8homlet-v2.dtb \
> > ????????sun8i-a83t-bananapi-m3.dtb \
> > ????????sun8i-a83t-cubietruck-plus.dtb \
> > diff --git a/arch/arm/boot/dts/allwinner/sun8i-a33-vstar-core1.dtsi
> > b/arch/arm/boot/dts/allwinner/sun8i-a33-vstar-core1.dtsi
> > new file mode 100644
> > index 0000000000000..ba794b842ec4e
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/allwinner/sun8i-a33-vstar-core1.dtsi
> > @@ -0,0 +1,96 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Copyright (C) 2024 Icenowy Zheng <uwu at icenowy.me>
> > + */
> > +
> > +#include "sun8i-a33.dtsi"
> > +
> > +&mmc2 {
> > +???????pinctrl-names = "default";
> > +???????pinctrl-0 = <&mmc2_8bit_pins>;
> > +???????vmmc-supply = <&reg_dcdc1>;
> > +???????bus-width = <8>;
> > +???????non-removable;
> > +???????cap-mmc-hw-reset;
> > +???????status = "okay";
> > +};
> > +
> > +&mmc2_8bit_pins {
> > +???????/* Increase drive strength for DDR modes */
> > +???????drive-strength = <40>;
> > +};
> > +
> > +&r_rsb {
> > +???????status = "okay";
> > +
> > +???????axp22x: pmic at 3a3 {
> > +???????????????compatible = "x-powers,axp223";
> > +???????????????reg = <0x3a3>;
> > +???????????????interrupt-parent = <&r_intc>;
> > +???????????????interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
> > +???????????????eldoin-supply = <&reg_dcdc1>;
> > +???????????????x-powers,drive-vbus-en;
> > +???????};
> > +};
> > +
> > +#include "axp223.dtsi"
> > +
> > +&reg_aldo1 {
> > +???????regulator-always-on;
> > +???????regulator-min-microvolt = <3300000>;
> > +???????regulator-max-microvolt = <3300000>;
> > +???????regulator-name = "vcc-io";
> > +};
> > +
> > +&reg_aldo2 {
> > +???????regulator-always-on;
> > +???????regulator-min-microvolt = <2350000>;
> > +???????regulator-max-microvolt = <2650000>;

So what is the value? I guess no one is adjusting this, ever? So it stays
at the 2.5V that U-Boot programs? I think we should fix this to this
voltage, then. What's the value that the BSP uses, is that different?

> > +???????regulator-name = "vdd-dll";
> > +};
> > +
> > +&reg_aldo3 {
> > +???????regulator-always-on;
> > +???????regulator-min-microvolt = <3300000>;
> > +???????regulator-max-microvolt = <3300000>;
> > +???????regulator-name = "vcc-avcc";
> > +};
> > +
> > +&reg_dc5ldo {
> > +???????regulator-always-on;
> > +???????regulator-min-microvolt = <900000>;
> > +???????regulator-max-microvolt = <1400000>;

Same here, why a range? I don't see U-Boot setting this, so does it stay
at some reset value, or does the kernel adjust it when the AXP driver
comes up? If any case, we should have exactly one voltage in here.

> > +???????regulator-name = "vdd-cpus";
> > +};
> > +
> > +&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 = <900000>;
> > +???????regulator-max-microvolt = <1400000>;

Sames as above, looks like to be 1.1V here?

There reason I am pointing this out is this relies on U-Boot setting some
hardcoded values, which I want to get rid off, as U-Boot should read the
voltages from the DT as well.

Cheers,
Andre

> > +???????regulator-name = "vdd-sys";
> > +};
> > +
> > +&reg_dcdc3 {
> > +???????regulator-always-on;
> > +???????regulator-min-microvolt = <900000>;
> > +???????regulator-max-microvolt = <1400000>;
> > +???????regulator-name = "vdd-cpu";
> > +};
> > +
> > +&reg_dcdc5 {
> > +???????regulator-always-on;
> > +???????regulator-min-microvolt = <1500000>;
> > +???????regulator-max-microvolt = <1500000>;
> > +???????regulator-name = "vcc-dram";
> > +};
> > +
> > +&reg_rtc_ldo {
> > +???????regulator-name = "vcc-rtc";
> > +};
> > diff --git a/arch/arm/boot/dts/allwinner/sun8i-a33-vstar.dts
> > b/arch/arm/boot/dts/allwinner/sun8i-a33-vstar.dts
> > new file mode 100644
> > index 0000000000000..9f5c29b3df46d
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/allwinner/sun8i-a33-vstar.dts
> > @@ -0,0 +1,205 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Copyright (C) 2024 Icenowy Zheng <uwu at icenowy.me>
> > + */
> > +
> > +/dts-v1/;
> > +#include "sun8i-a33-vstar-core1.dtsi"
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/input/input.h>
> > +
> > +/ {
> > +???????model = "Rervision A33-Vstar";
> > +???????compatible = "rervision,a33-vstar",
> > +??????????????????? "rervision,a33-core1",
> > +??????????????????? "allwinner,sun8i-a33";
> > +
> > +???????aliases {
> > +???????????????serial0 = &uart0;
> > +???????????????ethernet0 = &r8152;
> > +???????};
> > +
> > +???????chosen {
> > +???????????????stdout-path = "serial0:115200n8";
> > +???????};
> > +
> > +???????reg_usb1_vbus: regulator-usb1-vbus {
> > +???????????????compatible = "regulator-fixed";
> > +???????????????regulator-name = "usb1-vbus";
> > +???????????????regulator-min-microvolt = <5000000>;
> > +???????????????regulator-max-microvolt = <5000000>;
> > +???????????????regulator-boot-on;
> > +???????????????enable-active-high;
> > +???????????????gpio = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2 */
> > +???????};
> > +
> > +???????wifi_pwrseq: pwrseq {
> > +???????????????compatible = "mmc-pwrseq-simple";
> > +???????????????reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL6 */
> > +???????????????clocks = <&rtc CLK_OSC32K_FANOUT>;
> > +???????????????clock-names = "ext_clock";
> > +???????};
> > +};
> > +
> > +&ac_power_supply {
> > +???????status = "okay";
> > +};
> > +
> > +&codec {
> > +???????status = "okay";
> > +};
> > +
> > +&dai {
> > +???????status = "okay";
> > +};
> > +
> > +&ehci0 {
> > +???????#address-cells = <1>;
> > +???????#size-cells = <0>;
> > +???????status = "okay";
> > +
> > +???????hub at 1 {
> > +???????????????/* Onboard GL850G hub which needs no extra power
> > sequence */
> > +???????????????compatible = "usb5e3,608";
> > +???????????????reg = <1>;
> > +???????????????#address-cells = <1>;
> > +???????????????#size-cells = <0>;
> > +
> > +???????????????r8152: ethernet at 4 {
> > +???????????????????????/*
> > +??????????????????????? * Onboard Realtek RTL8152 USB Ethernet,
> > +??????????????????????? * with no MAC address programmed
> > +??????????????????????? */
> > +???????????????????????compatible = "usbbda,8152";
> > +???????????????????????reg = <4>;
> > +???????????????};
> > +???????};
> > +};
> > +
> > +&lradc {
> > +???????vref-supply = <&reg_aldo3>;
> > +???????status = "okay";
> > +
> > +???????button-191 {
> > +???????????????label = "V+";
> > +???????????????linux,code = <KEY_VOLUMEUP>;
> > +???????????????channel = <0>;
> > +???????????????voltage = <191011>;
> > +???????};
> > +
> > +???????button-391 {
> > +???????????????label = "V-";
> > +???????????????linux,code = <KEY_VOLUMEDOWN>;
> > +???????????????channel = <0>;
> > +???????????????voltage = <391304>;
> > +???????};
> > +
> > +???????button-600 {
> > +???????????????label = "BACK";
> > +???????????????linux,code = <KEY_BACK>;
> > +???????????????channel = <0>;
> > +???????????????voltage = <600000>;
> > +???????};
> > +};
> > +
> > +&mmc0 {
> > +???????vmmc-supply = <&reg_dcdc1>;
> > +???????bus-width = <4>;
> > +???????cd-gpios = <&pio 1 4 GPIO_ACTIVE_LOW>; /* PB4 */
> > +???????status = "okay";
> > +};
> > +
> > +&mmc1 {
> > +???????pinctrl-names = "default";
> > +???????pinctrl-0 = <&mmc1_pg_pins>;
> > +???????vmmc-supply = <&reg_dldo1>;
> > +???????mmc-pwrseq = <&wifi_pwrseq>;
> > +???????bus-width = <4>;
> > +???????non-removable;
> > +???????status = "okay";
> > +
> > +???????brcmf: wifi at 1 {
> > +???????????????reg = <1>;
> > +???????????????compatible = "brcm,bcm4329-fmac";
> > +???????????????interrupt-parent = <&r_pio>;
> > +???????????????interrupts = <0 7 IRQ_TYPE_LEVEL_LOW>; /* PL7 */
> > +???????????????interrupt-names = "host-wake";
> > +???????};
> > +};
> > +
> > +/*
> > + * Our WiFi chip needs both DLDO1 and DLDO2 to be powered at the
> > same
> > + * time, with the two being in sync. Since this is not really
> > + * supported right now, just use the two as always on, and we will
> > fix
> > + * it later.
> > + */
> > +&reg_dldo1 {
> > +???????regulator-always-on;
> > +???????regulator-min-microvolt = <3300000>;
> > +???????regulator-max-microvolt = <3300000>;
> > +???????regulator-name = "vcc-wifi0";
> > +};
> > +
> > +&reg_dldo2 {
> > +???????regulator-always-on;
> > +???????regulator-min-microvolt = <3300000>;
> > +???????regulator-max-microvolt = <3300000>;
> > +???????regulator-name = "vcc-wifi1";
> > +};
> > +
> > +&reg_drivevbus {
> > +???????regulator-name = "usb0-vbus";
> > +???????status = "okay";
> > +};
> > +
> > +&sound {
> > +???????/* TODO: on-board microphone */
> > +
> > +???????simple-audio-card,widgets = "Headphone", "Headphone Jack";
> > +???????simple-audio-card,routing =
> > +???????????????"Left DAC", "DACL",
> > +???????????????"Right DAC", "DACR",
> > +???????????????"Headphone Jack", "HP";
> > +???????status = "okay";
> > +};
> > +
> > +&uart0 {
> > +???????pinctrl-names = "default";
> > +???????pinctrl-0 = <&uart0_pb_pins>;
> > +???????status = "okay";
> > +};
> > +
> > +&uart1 {
> > +???????pinctrl-names = "default";
> > +???????pinctrl-0 = <&uart1_pg_pins>, <&uart1_cts_rts_pg_pins>;
> > +???????uart-has-rtscts;
> > +???????status = "okay";
> > +
> > +???????bluetooth {
> > +???????????????compatible = "brcm,bcm43438-bt";
> > +???????????????clocks = <&rtc CLK_OSC32K_FANOUT>;
> > +???????????????clock-names = "lpo";
> > +???????????????vbat-supply = <&reg_dldo1>;
> > +???????????????device-wakeup-gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
> > /* PL10 */
> > +???????????????host-wakeup-gpios = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; /*
> > PL9 */
> > +???????????????shutdown-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /*
> > PL8 */
> > +???????};
> > +};
> > +
> > +&usb_otg {
> > +???????dr_mode = "otg";
> > +???????status = "okay";
> > +};
> > +
> > +&usb_power_supply {
> > +???????status = "okay";
> > +};
> > +
> > +&usbphy {
> > +???????usb0_id_det-gpios = <&pio 7 8 GPIO_ACTIVE_HIGH>; /* PH8 */
> > +???????usb0_vbus_power-supply = <&usb_power_supply>;
> > +???????usb0_vbus-supply = <&reg_drivevbus>;
> > +???????usb1_vbus-supply = <&reg_usb1_vbus>;
> > +???????status = "okay";
> > +};  
> 



From jikos at kernel.org  Wed Dec 11 05:11:11 2024
From: jikos at kernel.org (Jiri Kosina)
Date: Wed, 11 Dec 2024 14:11:11 +0100 (CET)
Subject: [PATCH v9 1/9] HID: hid-sensor-hub: don't use stale platform-data
 on remove
In-Reply-To: <3196449.TQGk6oTFT5@diego>
References: <20241107114712.538976-1-heiko@sntech.de> <20241211120844.GD7139@google.com> <n914pn7o-pr9n-5ss0-p744-73402nnn843p@xreary.bet> <3196449.TQGk6oTFT5@diego>
Message-ID: <4s41717n-3888-os6o-384n-7678n0361r0s@xreary.bet>

On Wed, 11 Dec 2024, Heiko St?bner wrote:

> > > > > > This change was more or less a surprise find, because I wanted to make
> > > > > > the platform_data pointer in the mfd_cell struct const and this the hid
> > > > > > sensor hub stood out as doing something strange ;-) .
> > > > > > 
> > > > > > So patch 2 of this series actually depends on this change to not cause
> > > > > > build errors.
> > > > > 
> > > > > Ah, right.
> > > > > 
> > > > > > But seeing that we're after -rc6 alredy, I would assume the brunt of the 
> > > > > > mcu series might need to wait after 6.13-rc1 anyway - but I guess that 
> > > > > > depends on how Lee sees things ;-) .
> > > > > 
> > > > > OK, I am keeping my hands off it for the time being.
> > > > 
> > > > I can take it now with an Ack.
> > > 
> > > Looking to apply this set now.
> > > 
> > > Ack please.
> > 
> > I'd preferer if Srinivas could ack this as the more specific maintainer. 
> > Srinivas, please? 
> 
> The patch already includes the
>    Ack from Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>
> from a previous version, so I guess it should be ok already?

Ah, I missed that, indeed, sorry for the noise.

With that

	Acked-by: Jiri Kosina <jkosina at suse.com>

and Lee, please feel free to take it.

Thanks,

-- 
Jiri Kosina
SUSE Labs



From tabba at google.com  Wed Dec 11 05:11:22 2024
From: tabba at google.com (Fuad Tabba)
Date: Wed, 11 Dec 2024 13:11:22 +0000
Subject: [PATCH v4 07/14] KVM: arm64: Rework specifying restricted
 features for protected VMs
In-Reply-To: <Z1mGzwZqVQCWWSTX@google.com>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-8-tabba@google.com>
 <Z1mGzwZqVQCWWSTX@google.com>
Message-ID: <CA+EHjTzaVadZgO++bSYopQpy8DyfP1W8ytoOd6Q7yy+yEVqfeA@mail.gmail.com>

On Wed, 11 Dec 2024 at 12:34, Quentin Perret <qperret at google.com> wrote:
>
> On Monday 02 Dec 2024 at 15:47:34 (+0000), Fuad Tabba wrote:
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index f333b189fb43..230b0638f0c2 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -1422,6 +1422,7 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
> >       return test_bit(feature, ka->vcpu_features);
> >  }
> >
> > +#define kvm_vcpu_has_feature(k, f)   __vcpu_has_feature(&(k)->arch, (f))
> >  #define vcpu_has_feature(v, f)       __vcpu_has_feature(&(v)->kvm->arch, (f))
>
> Nit: I see nested uses the raw __vcpu_has_feature() helper, so I guess
> we should try and be consistent. Either way works, we can do the same
> thing in sys_regs.c, or convert nested.c to use kvm_vcpu_has_feature().

I'll add a patch on the respin to fix the nested callers. The lines
that call these macros/helpers are already quite long, and even though
it will add a bit of churn, imo the resulting code is more readable
with a kvm_vcpu_has_feature() helper.

Cheers,
/fuad


From sebastian.fricke at collabora.com  Wed Dec 11 05:17:02 2024
From: sebastian.fricke at collabora.com (Sebastian Fricke)
Date: Wed, 11 Dec 2024 14:17:02 +0100
Subject: [PATCH v6 2/3] media: mediatek: vcodec: support extended h264
 decode
In-Reply-To: <20241116031616.15656-3-yunfei.dong@mediatek.com>
References: <20241116031616.15656-1-yunfei.dong@mediatek.com>
 <20241116031616.15656-3-yunfei.dong@mediatek.com>
Message-ID: <20241211131702.sfen7wva4qk4ks7n@basti-XPS-13-9310>

Hey Yunfei,

On 16.11.2024 11:16, Yunfei Dong wrote:
>The address end of working buffer can't be calculated directly with buffer
>size in kernel for some special architecture. Adding new extend vsi_ex to
>calculate the address end in firmware.
>Adding capability to separate extend and non extend driver for different
>platform.
>At last, hardware can parse the syntax to get nal information in firmware
>for extend architecture, needn't to parse it again in kernel.

I'd recommend changing this to:

Add a new extended vsi_ext struct besides the existing vsi struct, to
enable calculating the end of the adress range of the current working
buffer for architectures, where simply adding the buffer size to the
start of the address range isn't sufficient.
Additionally, on extended architectures, the NAL information can be
fetched directly from the firmware, which allows skipping the parsing
step within the kernel.

Also, this sentence:
>Adding capability to separate extend and non extend driver for different
>platform.

Is a bit ambigious for me and doesn't seem to be something worth
mentioning. But maybe I misunderstand your point here.

>
>Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
>Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>---
> .../vcodec/decoder/mtk_vcodec_dec_drv.h       |   2 +
> .../decoder/vdec/vdec_h264_req_multi_if.c     | 575 ++++++++++++++++--
> 2 files changed, 518 insertions(+), 59 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 ac568ed14fa2..a0bb23962209 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
>@@ -17,6 +17,7 @@
>
> #define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
> #define IS_VDEC_INNER_RACING(capability) ((capability) & MTK_VCODEC_INNER_RACING)
>+#define IS_VDEC_SUPPORT_EX(capability) ((capability) & MTK_VDEC_IS_SUPPORT_EX)

I'd recommend changing this to: IS_VDEC_SUPPORT_EXT as EXT is way less
ambigious acronym for extension, EX could mean way more.
You'll see me mentioning that below a couple of times.

>
> enum mtk_vcodec_dec_chip_name {
> 	MTK_VDEC_INVAL = 0,
>@@ -42,6 +43,7 @@ enum mtk_vdec_format_types {
> 	MTK_VDEC_FORMAT_HEVC_FRAME = 0x1000,
> 	MTK_VCODEC_INNER_RACING = 0x20000,
> 	MTK_VDEC_IS_SUPPORT_10BIT = 0x40000,
>+	MTK_VDEC_IS_SUPPORT_EX = 0x80000,
> };
>
> /*
>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 ab192ce0b851..a7de95b9a7c0 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
>@@ -128,6 +128,83 @@ struct vdec_h264_slice_share_info {
> 	u16 nal_info;
> };
>
>+/*
>+ * struct vdec_h264_slice_mem - memory address and size (shared interface with firmware)
>+ */
>+struct vdec_h264_slice_mem {
>+	union {
>+		u64 buf;
>+		u64 dma_addr;
>+	};
>+	union {
>+		size_t size;
>+		u64 dma_addr_end;
>+	};
>+};
>+
>+/**
>+ * struct vdec_h264_slice_fb - frame buffer for decoding (shared interface with firmware)
>+ *
>+ * @y:  current y buffer address info

As this is a description I'd say lets describe a bit more detailed and
rewrite this to: "@y: current luma buffer address info"


>+ * @c:  current c buffer address info

... and "@c: current chroma buffer address info"

>+ */
>+struct vdec_h264_slice_fb {
>+	struct vdec_h264_slice_mem y;
>+	struct vdec_h264_slice_mem c;
>+};
>+
>+/**
>+ * struct vdec_h264_slice_info_ex - extend decode information (shared interface with firmware)

Can we call this also ..info_ext please?

>+ *
>+ * @wdma_end_addr_offset:	offset from buffer start
>+ * @nal_info:			nal info of current picture
>+ * @timeout:			Decode timeout: 1 timeout, 0 no timeout

I'd rename the description to: "Toggles whether a decode operation can timeout"
Then the effect of 1 and 0 becomes obvious.

>+ * @reserved:			reserved
>+ * @vdec_fb_va:		VDEC frame buffer struct virtual address
>+ * @crc:			Used to check whether hardware's status is right

I'd rename this to: "Displays the hardware status"
Saying whether a status is "right" is rather ambigious.

>+ */
>+struct vdec_h264_slice_info_ex {

... and this ... info_ext

>+	u64 wdma_end_addr_offset;
>+	u16 nal_info;
>+	u16 timeout;
>+	u32 reserved;
>+	u64 vdec_fb_va;
>+	u32 crc[8];
>+};
>+
>+/**
>+ * struct vdec_h264_slice_vsi_ex - extend shared memory for decode information exchange

s/vsi_ex/vsi_ext/

>+ *        between SCP and Host (shared interface with firmware).
>+ *
>+ * @bs:		input buffer info
>+ * @fb:		current y/c buffer
>+ *
>+ * @ube:		ube buffer

While we are at it and this acronym isn't terrible self-descriptive
could you write in the description what ube stands for?

>+ * @trans:		transcoded buffer
>+ * @row_info:		row info buffer
>+ * @err_map:		err map buffer
>+ * @slice_bc:		slice buffer
>+ *
>+ * @mv_buf_dma:	HW working motion vector buffer

HW working sounds weird, do you want to say the current?

>+ * @dec:		decode information (AP-R, VPU-W)
>+ * @h264_slice_params:	decode parameters for hw used

s/for hw used/used for the hw/

>+ */
>+struct vdec_h264_slice_vsi_ex {

s/vsi_ex/vsi_ext/

>+	/* LAT dec addr */
>+	struct vdec_h264_slice_mem bs;
>+	struct vdec_h264_slice_fb fb;
>+
>+	struct vdec_h264_slice_mem ube;
>+	struct vdec_h264_slice_mem trans;
>+	struct vdec_h264_slice_mem row_info;
>+	struct vdec_h264_slice_mem err_map;
>+	struct vdec_h264_slice_mem slice_bc;
>+
>+	struct vdec_h264_slice_mem mv_buf_dma[H264_MAX_MV_NUM];
>+	struct vdec_h264_slice_info_ex dec;

s/info_ex/info_ext/

>+	struct vdec_h264_slice_lat_dec_param h264_slice_params;
>+};
>+
> /**
>  * struct vdec_h264_slice_inst - h264 decoder instance
>  *
>@@ -138,8 +215,10 @@ struct vdec_h264_slice_share_info {
>  * @vpu:		VPU instance
>  * @vsi:		vsi used for lat
>  * @vsi_core:		vsi used for core
>- *
>- * @vsi_ctx:		Local VSI data for this decoding context
>+ * @vsi_ctx:		Local vsi data for this decoding context
>+ * @vsi_ex:		extend vsi used for lat

s/vsi_ex/vsi_ext/
s/extend/extended/

>+ * @vsi_core_ex:	extend vsi used for core

s/vsi_core_ex/vsi_core_ext/
s/extend/extended/

>+ * @vsi_ctx_ex:	Local extend vsi data for this decoding context

s/vsi_ctx_ex/vsi_ctx_ext/
s/extend/extended/

Also you can drop the word Local as that is clear already with:
"for this decoding context"

>  * @h264_slice_param:	the parameters that hardware use to decode
>  *
>  * @resolution_changed:resolution changed
>@@ -148,7 +227,9 @@ struct vdec_h264_slice_share_info {
>  *
>  * @dpb:		decoded picture buffer used to store reference
>  *			buffer information
>- *@is_field_bitstream:	is field bitstream
>+ * @is_field_bitstream: is field bitstream

That is not a description, that is a repetition :)
Please make this a bit more descriptive. Like do you describe anywhere
else already what a field bitstream is and how it differentiates from
the alternative?

>+ *
>+ * @decode:		lat decoder pointer for different architecture

s/architecture/architectures/

>  */
> struct vdec_h264_slice_inst {
> 	unsigned int slice_dec_num;
>@@ -156,10 +237,18 @@ struct vdec_h264_slice_inst {
> 	struct mtk_vcodec_mem pred_buf;
> 	struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM];
> 	struct vdec_vpu_inst vpu;
>-	struct vdec_h264_slice_vsi *vsi;
>-	struct vdec_h264_slice_vsi *vsi_core;
>-
>-	struct vdec_h264_slice_vsi vsi_ctx;
>+	union {
>+		struct {
>+			struct vdec_h264_slice_vsi *vsi;
>+			struct vdec_h264_slice_vsi *vsi_core;
>+			struct vdec_h264_slice_vsi vsi_ctx;
>+		};
>+		struct {
>+			struct vdec_h264_slice_vsi_ex *vsi_ex;
>+			struct vdec_h264_slice_vsi_ex *vsi_core_ex;
>+			struct vdec_h264_slice_vsi_ex vsi_ctx_ex;

s/vsi_ex/vsi_ext/
s/vsi_core_ex/vsi_core_ext/
s/vsi_ctx_ex/vsi_ctx_ext/

>+		};
>+	};
> 	struct vdec_h264_slice_lat_dec_param h264_slice_param;
>
> 	unsigned int resolution_changed;
>@@ -168,6 +257,9 @@ struct vdec_h264_slice_inst {
>
> 	struct v4l2_h264_dpb_entry dpb[16];
> 	bool is_field_bitstream;
>+
>+	int (*decode)(void *h_vdec, struct mtk_vcodec_mem *bs,
>+		      struct vdec_fb *unused, bool *res_chg);
> };
>
> static int vdec_h264_slice_fill_decode_parameters(struct vdec_h264_slice_inst *inst,
>@@ -389,62 +481,143 @@ static void vdec_h264_slice_get_crop_info(struct vdec_h264_slice_inst *inst,
> 		       cr->left, cr->top, cr->width, cr->height);
> }
>
>-static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx)
>+static void vdec_h264_slice_setup_lat_buffer_ex(struct vdec_h264_slice_inst *inst,

s/buffer_ex/buffer_ext/

>+						struct mtk_vcodec_mem *bs,
>+						struct vdec_lat_buf *lat_buf)
> {
>-	struct vdec_h264_slice_inst *inst;
>-	int err, vsi_size;
>+	struct mtk_vcodec_mem *mem;
>+	int i;
>
>-	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
>-	if (!inst)
>-		return -ENOMEM;
>+	inst->vsi_ex->bs.dma_addr = (u64)bs->dma_addr;
>+	inst->vsi_ex->bs.size = bs->size;
>
>-	inst->ctx = ctx;
>+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
>+		mem = &inst->mv_buf[i];
>+		inst->vsi_ex->mv_buf_dma[i].dma_addr = mem->dma_addr;

s/vsi_ex/vsi_ext/
and in all other cases below ...

>+		inst->vsi_ex->mv_buf_dma[i].size = mem->size;
>+	}
>+	inst->vsi_ex->ube.dma_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
>+	inst->vsi_ex->ube.size = lat_buf->ctx->msg_queue.wdma_addr.size;
>
>-	inst->vpu.id = SCP_IPI_VDEC_LAT;
>-	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
>-	inst->vpu.ctx = ctx;
>-	inst->vpu.codec_type = ctx->current_codec;
>-	inst->vpu.capture_type = ctx->capture_fourcc;
>+	inst->vsi_ex->row_info.dma_addr = 0;
>+	inst->vsi_ex->row_info.size = 0;
>
>-	err = vpu_dec_init(&inst->vpu);
>-	if (err) {
>-		mtk_vdec_err(ctx, "vdec_h264 init err=%d", err);
>-		goto error_free_inst;
>+	inst->vsi_ex->err_map.dma_addr = lat_buf->wdma_err_addr.dma_addr;
>+	inst->vsi_ex->err_map.size = lat_buf->wdma_err_addr.size;
>+
>+	inst->vsi_ex->slice_bc.dma_addr = lat_buf->slice_bc_addr.dma_addr;
>+	inst->vsi_ex->slice_bc.size = lat_buf->slice_bc_addr.size;
>+
>+	inst->vsi_ex->trans.dma_addr_end = inst->ctx->msg_queue.wdma_rptr_addr;
>+	inst->vsi_ex->trans.dma_addr = inst->ctx->msg_queue.wdma_wptr_addr;
>+}
>+
>+static int vdec_h264_slice_setup_core_buffer_ex(struct vdec_h264_slice_inst *inst,

s/buffer_ex/buffer_ext/

>+						struct vdec_h264_slice_share_info *share_info,
>+						struct vdec_lat_buf *lat_buf)
>+{
>+	struct mtk_vcodec_mem *mem;
>+	struct mtk_vcodec_dec_ctx *ctx = inst->ctx;
>+	struct vb2_v4l2_buffer *vb2_v4l2;
>+	struct vdec_fb *fb;
>+	u64 y_fb_dma, c_fb_dma = 0;
>+	int i;
>+
>+	fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
>+	if (!fb) {
>+		mtk_vdec_err(ctx, "fb buffer is NULL");

A frame buffer buffer sounds a bit repetitive, lets just call it frame
buffer. Also this error message tells the user nothing. When I look at
the function within `mtk_vcodec_dec_stateless` it looks like the only
way we get a NULL here is if `v4l2_m2m_next_dst_buf` returns nothing,
e.g. if we don't have a next destination buffer. Can you confirm this?
If that is the case a better error message would be:
"Unable to get a CAPTURE buffer, because the CAPTURE queue is empty"
Or something along those lines.

>+		return -EBUSY;
> 	}
>
>-	vsi_size = round_up(sizeof(struct vdec_h264_slice_vsi), VCODEC_DEC_ALIGNED_64);
>-	inst->vsi = inst->vpu.vsi;
>-	inst->vsi_core =
>-		(struct vdec_h264_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
>-	inst->resolution_changed = true;
>-	inst->realloc_mv_buf = true;
>+	y_fb_dma = (u64)fb->base_y.dma_addr;
>+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
>+		c_fb_dma =
>+			y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;

Looks like it is worth it to create a separate variable for picinfo as
you use it here and below, so that you can do a bit less copy-paste.

>+	else
>+		c_fb_dma = (u64)fb->base_c.dma_addr;
>
>-	mtk_vdec_debug(ctx, "lat struct size = %d,%d,%d,%d vsi: %d\n",
>-		       (int)sizeof(struct mtk_h264_sps_param),
>-		       (int)sizeof(struct mtk_h264_pps_param),
>-		       (int)sizeof(struct vdec_h264_slice_lat_dec_param),
>-		       (int)sizeof(struct mtk_h264_dpb_info),
>-		       vsi_size);
>-	mtk_vdec_debug(ctx, "lat H264 instance >> %p, codec_type = 0x%x",
>-		       inst, inst->vpu.codec_type);
>+	mtk_vdec_debug(ctx, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, c_fb_dma);
>
>-	ctx->drv_handle = inst;
>-	return 0;
>+	inst->vsi_core_ex->fb.y.dma_addr = y_fb_dma;

s/vsi_core_ex/vsi_core_ext/
and everywhere below ...

>+	inst->vsi_core_ex->fb.y.size = ctx->picinfo.fb_sz[0];
>+	inst->vsi_core_ex->fb.c.dma_addr = c_fb_dma;
>+	inst->vsi_core_ex->fb.c.size = ctx->picinfo.fb_sz[1];
>
>-error_free_inst:
>-	kfree(inst);
>-	return err;
>+	inst->vsi_core_ex->dec.vdec_fb_va = (unsigned long)fb;
>+	inst->vsi_core_ex->dec.nal_info = share_info->nal_info;
>+
>+	inst->vsi_core_ex->ube.dma_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
>+	inst->vsi_core_ex->ube.size = lat_buf->ctx->msg_queue.wdma_addr.size;
>+
>+	inst->vsi_core_ex->err_map.dma_addr = lat_buf->wdma_err_addr.dma_addr;
>+	inst->vsi_core_ex->err_map.size = lat_buf->wdma_err_addr.size;
>+
>+	inst->vsi_core_ex->slice_bc.dma_addr = lat_buf->slice_bc_addr.dma_addr;
>+	inst->vsi_core_ex->slice_bc.size = lat_buf->slice_bc_addr.size;
>+
>+	inst->vsi_core_ex->row_info.dma_addr = 0;
>+	inst->vsi_core_ex->row_info.size = 0;
>+
>+	inst->vsi_core_ex->trans.dma_addr = share_info->trans_start;
>+	inst->vsi_core_ex->trans.dma_addr_end = share_info->trans_end;
>+
>+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
>+		mem = &inst->mv_buf[i];
>+		inst->vsi_core_ex->mv_buf_dma[i].dma_addr = mem->dma_addr;
>+		inst->vsi_core_ex->mv_buf_dma[i].size = mem->size;
>+	}
>+
>+	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
>+	v4l2_m2m_buf_copy_metadata(&lat_buf->ts_info, vb2_v4l2, true);
>+
>+	return 0;
> }
>
>-static void vdec_h264_slice_deinit(void *h_vdec)
>+static int vdec_h264_slice_core_decode_ex(struct vdec_lat_buf *lat_buf)

s/decode_ex/decode_ext/

No no no, I don't like this or vdec_h264_slice_lat_decode_ex you
basically just duplicated the whole decode function in both cases and
added a few extended bits to them. Unless the two routines are
substantially different (which from my point of view they are not) you
should be able to create conditional branches for the extended bits into
the decode functions.

But please also look at my general comments in the functions, I'd still
like to know why timeouts are handled the way they are and whether the
status of a device can be made a bit more obvious to the user.

> {
>-	struct vdec_h264_slice_inst *inst = h_vdec;
>+	int err, timeout;
>+	struct mtk_vcodec_dec_ctx *ctx = lat_buf->ctx;
>+	struct vdec_h264_slice_inst *inst = ctx->drv_handle;
>+	struct vdec_h264_slice_share_info *share_info = lat_buf->private_data;
>+	struct vdec_vpu_inst *vpu = &inst->vpu;
>
>-	vpu_dec_deinit(&inst->vpu);
>-	vdec_h264_slice_free_mv_buf(inst);
>-	vdec_msg_queue_deinit(&inst->ctx->msg_queue, inst->ctx);
>+	mtk_vdec_debug(ctx, "[h264-core] vdec_h264 core decode");

This looks like a left over development comment, this is not useful for
general debugging and shouldn't be upstreamed.

>+	memcpy(&inst->vsi_core_ex->h264_slice_params, &share_info->h264_slice_params,
>+	       sizeof(share_info->h264_slice_params));
>
>-	kfree(inst);
>+	err = vdec_h264_slice_setup_core_buffer_ex(inst, share_info, lat_buf);

s/buffer_ex/buffer_ext/

>+	if (err)
>+		goto vdec_dec_end;
>+
>+	vdec_h264_slice_fill_decode_reflist(inst, &inst->vsi_core_ex->h264_slice_params,
>+					    share_info);
>+	err = vpu_dec_core(vpu);
>+	if (err) {
>+		mtk_vdec_err(ctx, "core decode err=%d", err);
>+		goto vdec_dec_end;
>+	}
>+
>+	/* wait decoder done interrupt */
>+	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
>+					       WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
>+	if (timeout)
>+		mtk_vdec_err(ctx, "core decode timeout: pic_%d", ctx->decoded_frame_cnt);

So as you don't bail out here, it looks like this conditional branch
will end up returning 0. Why do you return 0 on a timeout? Isn't a
timeout a failed decode?

>+	inst->vsi_core_ex->dec.timeout = !!timeout;
>+
>+	vpu_dec_core_end(vpu);
>+	mtk_vdec_debug(ctx, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
>+		       ctx->decoded_frame_cnt,
>+		       inst->vsi_core_ex->dec.crc[0], inst->vsi_core_ex->dec.crc[1],
>+		       inst->vsi_core_ex->dec.crc[2], inst->vsi_core_ex->dec.crc[3],
>+		       inst->vsi_core_ex->dec.crc[4], inst->vsi_core_ex->dec.crc[5],
>+		       inst->vsi_core_ex->dec.crc[6], inst->vsi_core_ex->dec.crc[7]);

Can you add a small comment above this that explains to the user what
these CRCs are supposed to mean?

>+
>+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);
>+	mtk_vdec_debug(ctx, "core decode done err=%d", err);
>+	ctx->decoded_frame_cnt++;
>+	return 0;
> }
>
> static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
>@@ -559,6 +732,127 @@ static void vdec_h264_insert_startcode(struct mtk_vcodec_dec_dev *vcodec_dev, un
> 	(*bs_size) += 4;
> }
>
>+static int vdec_h264_slice_lat_decode_ex(void *h_vdec, struct mtk_vcodec_mem *bs,
>+					 struct vdec_fb *fb, bool *res_chg)
>+{

>+	struct vdec_h264_slice_inst *inst = h_vdec;
>+	struct vdec_vpu_inst *vpu = &inst->vpu;
>+	struct mtk_video_dec_buf *src_buf_info;
>+	int err, timeout = 0;
>+	unsigned int data[2];
>+	struct vdec_lat_buf *lat_buf;
>+	struct vdec_h264_slice_share_info *share_info;
>+
>+	if (vdec_msg_queue_init(&inst->ctx->msg_queue, inst->ctx,
>+				vdec_h264_slice_core_decode_ex,
>+				sizeof(*share_info)))
>+		return -ENOMEM;
>+
>+	/* bs NULL means flush decoder */
>+	if (!bs) {
>+		vdec_msg_queue_wait_lat_buf_full(&inst->ctx->msg_queue);
>+		return vpu_dec_reset(vpu);
>+	}
>+
>+	if (inst->is_field_bitstream)
>+		return -EINVAL;
>+
>+	lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx);
>+	if (!lat_buf) {
>+		mtk_vdec_debug(inst->ctx, "failed to get lat buffer");
>+		return -EAGAIN;
>+	}
>+	share_info = lat_buf->private_data;
>+	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;
>+	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,
>+						     &inst->vsi_ex->h264_slice_params);
>+	if (err)
>+		goto err_free_fb_out;
>+
>+	vdec_h264_insert_startcode(inst->ctx->dev, bs->va, &bs->size,
>+				   &share_info->h264_slice_params.pps);
>+
>+	*res_chg = inst->resolution_changed;
>+	if (inst->resolution_changed) {
>+		mtk_vdec_debug(inst->ctx, "- resolution changed -");
>+		if (inst->realloc_mv_buf) {
>+			err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo);
>+			inst->realloc_mv_buf = false;
>+			if (err)
>+				goto err_free_fb_out;
>+		}
>+		inst->resolution_changed = false;
>+	}
>+
>+	vdec_h264_slice_setup_lat_buffer_ex(inst, bs, lat_buf);
>+	mtk_vdec_debug(inst->ctx, "lat:trans(0x%llx 0x%lx) err:0x%llx",
>+		       inst->vsi_ex->ube.dma_addr, (unsigned long)inst->vsi_ex->ube.size,
>+		       inst->vsi_ex->err_map.dma_addr);
>+
>+	mtk_vdec_debug(inst->ctx, "slice(0x%llx 0x%lx) rprt((0x%llx 0x%llx))",
>+		       inst->vsi_ex->slice_bc.dma_addr, (unsigned long)inst->vsi_ex->slice_bc.size,
>+		       inst->vsi_ex->trans.dma_addr, inst->vsi_ex->trans.dma_addr_end);
>+
>+	err = vpu_dec_start(vpu, data, 2);
>+	if (err) {
>+		mtk_vdec_debug(inst->ctx, "lat decode err: %d", err);
>+		goto err_free_fb_out;
>+	}
>+
>+	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
>+		inst->vsi_ex->dec.wdma_end_addr_offset;
>+
>+	share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
>+	share_info->nal_info = inst->vsi_ex->dec.nal_info;
>+
>+	if (IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
>+		memcpy(&share_info->h264_slice_params, &inst->vsi_ex->h264_slice_params,
>+		       sizeof(share_info->h264_slice_params));
>+		vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf);
>+	}
>+
>+	/* wait decoder done interrupt */
>+	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
>+					       WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
>+	if (timeout)
>+		mtk_vdec_err(inst->ctx, "lat decode timeout: pic_%d", inst->slice_dec_num);
>+	inst->vsi_ex->dec.timeout = !!timeout;
>+
>+	err = vpu_dec_end(vpu);
>+	if (err == SLICE_HEADER_FULL || err == TRANS_BUFFER_FULL) {
>+		if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability))
>+			vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
>+		inst->slice_dec_num++;
>+		mtk_vdec_err(inst->ctx, "lat dec fail: pic_%d err:%d", inst->slice_dec_num, err);
>+		return -EINVAL;
>+	}
>+
>+	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
>+		inst->vsi_ex->dec.wdma_end_addr_offset;
>+
>+	vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue, share_info->trans_end);
>+
>+	if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
>+		memcpy(&share_info->h264_slice_params, &inst->vsi_ex->h264_slice_params,
>+		       sizeof(share_info->h264_slice_params));
>+		vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf);
>+	}
>+	mtk_vdec_debug(inst->ctx, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num,
>+		       inst->vsi_ex->dec.crc[0], inst->vsi_ex->dec.crc[1],
>+		       inst->vsi_ex->dec.crc[2]);
>+
>+	inst->slice_dec_num++;
>+	return 0;
>+err_free_fb_out:
>+	vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
>+	mtk_vdec_err(inst->ctx, "slice dec number: %d err: %d", inst->slice_dec_num, err);
>+	return err;
>+}
>+
> static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
> 				      struct vdec_fb *fb, bool *res_chg)
> {
>@@ -704,18 +998,17 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
> 	return err;
> }
>
>-static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
>-					 struct vdec_fb *unused, bool *res_chg)
>+static int vdec_h264_slice_single_decode_ex(void *h_vdec, struct mtk_vcodec_mem *bs,

s/decode_ex/decode_ext/

>+					    struct vdec_fb *unused, bool *res_chg)
> {
> 	struct vdec_h264_slice_inst *inst = h_vdec;
> 	struct vdec_vpu_inst *vpu = &inst->vpu;
> 	struct mtk_video_dec_buf *src_buf_info, *dst_buf_info;
> 	struct vdec_fb *fb;
>-	unsigned char *buf;
> 	unsigned int data[2], i;
> 	u64 y_fb_dma, c_fb_dma;
> 	struct mtk_vcodec_mem *mem;
>-	int err, nal_start_idx;
>+	int err;
>
> 	/* bs NULL means flush decoder */
> 	if (!bs)
>@@ -735,6 +1028,96 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs
> 	mtk_vdec_debug(inst->ctx, "[h264-dec] [%d] y_dma=%llx c_dma=%llx",
> 		       inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma);
>
>+	inst->vsi_ctx_ex.bs.dma_addr = (u64)bs->dma_addr;
>+	inst->vsi_ctx_ex.bs.size = bs->size;
>+	inst->vsi_ctx_ex.fb.y.dma_addr = y_fb_dma;
>+	inst->vsi_ctx_ex.fb.c.dma_addr = c_fb_dma;
>+	inst->vsi_ctx_ex.dec.vdec_fb_va = (u64)(uintptr_t)fb;
>+
>+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
>+				   &dst_buf_info->m2m_buf.vb, true);
>+	err = get_vdec_sig_decode_parameters(inst);
>+	if (err)
>+		goto err_free_fb_out;
>+
>+	memcpy(&inst->vsi_ctx_ex.h264_slice_params, &inst->h264_slice_param,
>+	       sizeof(inst->vsi_ctx_ex.h264_slice_params));
>+
>+	*res_chg = inst->resolution_changed;
>+	if (inst->resolution_changed) {
>+		mtk_vdec_debug(inst->ctx, "- resolution changed -");
>+		if (inst->realloc_mv_buf) {
>+			err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo);
>+			inst->realloc_mv_buf = false;
>+			if (err)
>+				goto err_free_fb_out;
>+		}
>+		inst->resolution_changed = false;
>+
>+		for (i = 0; i < H264_MAX_MV_NUM; i++) {
>+			mem = &inst->mv_buf[i];
>+			inst->vsi_ctx_ex.mv_buf_dma[i].dma_addr = mem->dma_addr;
>+		}
>+	}
>+
>+	memcpy(inst->vpu.vsi, &inst->vsi_ctx_ex, sizeof(inst->vsi_ctx_ex));
>+	err = vpu_dec_start(vpu, data, 2);
>+	if (err)
>+		goto err_free_fb_out;
>+
>+	/* wait decoder done interrupt */
>+	err = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
>+					   WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
>+	if (err)
>+		mtk_vdec_err(inst->ctx, "decode timeout: pic_%d", inst->ctx->decoded_frame_cnt);
>+
>+	inst->vsi_ex->dec.timeout = !!err;
>+	err = vpu_dec_end(vpu);
>+	if (err)
>+		goto err_free_fb_out;
>+
>+	memcpy(&inst->vsi_ctx_ex, inst->vpu.vsi, sizeof(inst->vsi_ctx_ex));
>+	mtk_vdec_debug(inst->ctx, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
>+		       inst->ctx->decoded_frame_cnt,
>+		       inst->vsi_ctx_ex.dec.crc[0], inst->vsi_ctx_ex.dec.crc[1],
>+		       inst->vsi_ctx_ex.dec.crc[2], inst->vsi_ctx_ex.dec.crc[3],
>+		       inst->vsi_ctx_ex.dec.crc[4], inst->vsi_ctx_ex.dec.crc[5],
>+		       inst->vsi_ctx_ex.dec.crc[6], inst->vsi_ctx_ex.dec.crc[7]);
>+
>+	inst->ctx->decoded_frame_cnt++;
>+	return 0;
>+
>+err_free_fb_out:
>+	mtk_vdec_err(inst->ctx, "dec frame number: %d err: %d", inst->ctx->decoded_frame_cnt, err);
>+	return err;
>+}
>+
>+static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
>+					 struct vdec_fb *unused, bool *res_chg)
>+{
>+	struct vdec_h264_slice_inst *inst = h_vdec;
>+	struct vdec_vpu_inst *vpu = &inst->vpu;
>+	struct mtk_video_dec_buf *src_buf_info, *dst_buf_info;
>+	struct vdec_fb *fb;
>+	unsigned char *buf;
>+	unsigned int data[2], i;
>+	u64 y_fb_dma, c_fb_dma;
>+	struct mtk_vcodec_mem *mem;
>+	int err, nal_start_idx;
>+
>+	/* bs NULL means flush decoder */
>+	if (!bs)
>+		return vpu_dec_reset(vpu);
>+
>+	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
>+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
>+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
>+
>+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
>+	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
>+	mtk_vdec_debug(inst->ctx, "[h264-dec] [%d] y_dma=%llx c_dma=%llx",
>+		       inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma);
>+
> 	inst->vsi_ctx.dec.bs_buf_addr = (u64)bs->dma_addr;
> 	inst->vsi_ctx.dec.bs_buf_size = bs->size;
> 	inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
>@@ -807,21 +1190,95 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs
> 	return err;
> }
>
>+static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx)
>+{
>+	struct vdec_h264_slice_inst *inst;
>+	int err, vsi_size;
>+	unsigned char *temp;
>+
>+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
>+	if (!inst)
>+		return -ENOMEM;
>+
>+	inst->ctx = ctx;
>+
>+	inst->vpu.id = SCP_IPI_VDEC_LAT;
>+	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
>+	inst->vpu.ctx = ctx;
>+	inst->vpu.codec_type = ctx->current_codec;
>+	inst->vpu.capture_type = ctx->capture_fourcc;
>+
>+	err = vpu_dec_init(&inst->vpu);
>+	if (err) {
>+		mtk_vdec_err(ctx, "vdec_h264 init err=%d", err);
>+		goto error_free_inst;
>+	}
>+
>+	if (IS_VDEC_SUPPORT_EX(ctx->dev->dec_capability)) {

s/SUPPORT_EX/SUPPORT_EXT/

same treatment for the other variables below ending with ex

>+		vsi_size = sizeof(struct vdec_h264_slice_vsi_ex);
>+
>+		vsi_size = round_up(vsi_size, VCODEC_DEC_ALIGNED_64);
>+		inst->vsi_ex = inst->vpu.vsi;
>+		temp = (unsigned char *)inst->vsi_ex;
>+		inst->vsi_core_ex = (struct vdec_h264_slice_vsi_ex *)(temp + vsi_size);
>+
>+		if (inst->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE)
>+			inst->decode = vdec_h264_slice_single_decode_ex;
>+		else
>+			inst->decode = vdec_h264_slice_lat_decode_ex;
>+	} else {
>+		vsi_size = sizeof(struct vdec_h264_slice_vsi);
>+
>+		vsi_size = round_up(vsi_size, VCODEC_DEC_ALIGNED_64);
>+		inst->vsi = inst->vpu.vsi;
>+		temp = (unsigned char *)inst->vsi;
>+		inst->vsi_core = (struct vdec_h264_slice_vsi *)(temp + vsi_size);
>+
>+		if (inst->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE)
>+			inst->decode = vdec_h264_slice_single_decode;
>+		else
>+			inst->decode = vdec_h264_slice_lat_decode;
>+	}

This looks all so extremely similar to me ... Please help me out here,
why do we need a vsi_core and a vsi_core_ext ? You could easily assign
the same value that you assign to vsi_core_ext to vsi_core in case the
architecture supports the extended VSI. So why do you need to have a the
vsi structs besides the vsi_ext structs?

>+	inst->resolution_changed = true;
>+	inst->realloc_mv_buf = true;
>+
>+	mtk_vdec_debug(ctx, "lat struct size = %d,%d,%d,%d vsi: %d\n",
>+		       (int)sizeof(struct mtk_h264_sps_param),
>+		       (int)sizeof(struct mtk_h264_pps_param),
>+		       (int)sizeof(struct vdec_h264_slice_lat_dec_param),
>+		       (int)sizeof(struct mtk_h264_dpb_info),
>+		       vsi_size);
>+	mtk_vdec_debug(ctx, "lat H264 instance >> %p, codec_type = 0x%x",
>+		       inst, inst->vpu.codec_type);
>+
>+	ctx->drv_handle = inst;
>+	return 0;
>+
>+error_free_inst:
>+	kfree(inst);
>+	return err;
>+}
>+
>+static void vdec_h264_slice_deinit(void *h_vdec)
>+{
>+	struct vdec_h264_slice_inst *inst = h_vdec;
>+
>+	vpu_dec_deinit(&inst->vpu);
>+	vdec_h264_slice_free_mv_buf(inst);
>+	vdec_msg_queue_deinit(&inst->ctx->msg_queue, inst->ctx);
>+
>+	kfree(inst);
>+}
>+
> static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
> 				  struct vdec_fb *unused, bool *res_chg)
> {
> 	struct vdec_h264_slice_inst *inst = h_vdec;
>-	int ret;
>
> 	if (!h_vdec)
> 		return -EINVAL;
>
>-	if (inst->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE)
>-		ret = vdec_h264_slice_single_decode(h_vdec, bs, unused, res_chg);
>-	else
>-		ret = vdec_h264_slice_lat_decode(h_vdec, bs, unused, res_chg);
>-
>-	return ret;
>+	return inst->decode(h_vdec, bs, unused, res_chg);

One reason more to try avoiding the split into separate functions for
extended and non-extended, more callbacks make the code just harder and
harder to navigate and understand.

> }
>
> static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type,
>-- 
>2.46.0
>
>

Regards,
Sebastian Fricke


From sebastian.fricke at collabora.com  Wed Dec 11 05:17:40 2024
From: sebastian.fricke at collabora.com (Sebastian Fricke)
Date: Wed, 11 Dec 2024 14:17:40 +0100
Subject: [PATCH v6 1/3] media: mediatek: vcodec: remove vsi operation in
 common interface
In-Reply-To: <20241116031616.15656-2-yunfei.dong@mediatek.com>
References: <20241116031616.15656-1-yunfei.dong@mediatek.com>
 <20241116031616.15656-2-yunfei.dong@mediatek.com>
Message-ID: <20241211131740.x6lrlamgi5ogdq7b@basti-XPS-13-9310>

Hey Yunfei,

On 16.11.2024 11:16, Yunfei Dong wrote:
>Extend struct video shared information (vsi) to send different
>parameters to scp for mt8188 architecture is changed.
>Remove vsi related operation in common interface to make sure the
>interface can be called by extended and non extended architecture
>at the same time. The new extended interfaces with new vsi will
>be introduced in later patches.

My recommendation:

Extend the VSI (video shared information) struct to allow sending slice
parameters to SCP, as the parameters have changed on MT8188
architecture. Remove VSI related information from the common interface
to ensure, that the interface is usable by architectures with and
without the extended parameters. The new VSI extensions will be
introduced in later patches.

The rest looks good to me.

Regards,
Sebastian Fricke

>Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

>Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>---
> .../vcodec/decoder/vdec/vdec_h264_req_multi_if.c    | 13 +++++++------
> 1 file changed, 7 insertions(+), 6 deletions(-)
>
>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 1ed0ccec5665..ab192ce0b851 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
>@@ -171,9 +171,9 @@ struct vdec_h264_slice_inst {
> };
>
> static int vdec_h264_slice_fill_decode_parameters(struct vdec_h264_slice_inst *inst,
>-						  struct vdec_h264_slice_share_info *share_info)
>+						  struct vdec_h264_slice_share_info *share_info,
>+						  struct vdec_h264_slice_lat_dec_param *slice_param)
> {
>-	struct vdec_h264_slice_lat_dec_param *slice_param = &inst->vsi->h264_slice_params;
> 	const struct v4l2_ctrl_h264_decode_params *dec_params;
> 	const struct v4l2_ctrl_h264_scaling_matrix *src_matrix;
> 	const struct v4l2_ctrl_h264_sps *sps;
>@@ -266,9 +266,6 @@ static int get_vdec_sig_decode_parameters(struct vdec_h264_slice_inst *inst)
> 	mtk_vdec_h264_get_ref_list(b0_reflist, v4l2_b0_reflist, reflist_builder.num_valid);
> 	mtk_vdec_h264_get_ref_list(b1_reflist, v4l2_b1_reflist, reflist_builder.num_valid);
>
>-	memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
>-	       sizeof(inst->vsi_ctx.h264_slice_params));
>-
> 	return 0;
> }
>
>@@ -608,7 +605,8 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
> 	lat_buf->src_buf_req = src_buf_info->m2m_buf.vb.vb2_buf.req_obj.req;
> 	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);
>+	err = vdec_h264_slice_fill_decode_parameters(inst, share_info,
>+						     &inst->vsi->h264_slice_params);
> 	if (err)
> 		goto err_free_fb_out;
>
>@@ -749,6 +747,9 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs
> 	if (err)
> 		goto err_free_fb_out;
>
>+	memcpy(&inst->vsi_ctx.h264_slice_params, &inst->h264_slice_param,
>+	       sizeof(inst->vsi_ctx.h264_slice_params));
>+
> 	buf = (unsigned char *)bs->va;
> 	nal_start_idx = mtk_vdec_h264_find_start_code(buf, bs->size);
> 	if (nal_start_idx < 0) {
>-- 
>2.46.0


From dan.carpenter at linaro.org  Wed Dec 11 05:21:40 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Wed, 11 Dec 2024 16:21:40 +0300
Subject: arm64: include/linux/compiler_types.h:542:38: error: call to
 '__compiletime_assert_1050' declared with attribute error: clamp() low limit
 min greater than high limit max_avail
In-Reply-To: <CAMRc=Mf8CmKs-_FddnLFU7aoOAPU6Xv8MqyZo8x9Uv-Eu+hs_g@mail.gmail.com>
References: <CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g@mail.gmail.com>
 <8dde5a62-4ce6-4954-86c9-54d961aed6df@stanley.mountain>
 <CA+G9fYv5gW1gByakU1yyQ__BoAKWkCcg=vGGyNep7+5p9_2uJA@mail.gmail.com>
 <bd95d7249ff94e31beb11b3f71a64e87@AcuMS.aculab.com>
 <CAMRc=Mf8CmKs-_FddnLFU7aoOAPU6Xv8MqyZo8x9Uv-Eu+hs_g@mail.gmail.com>
Message-ID: <49a14c12-a452-4877-aedf-94bac6ed2b7b@stanley.mountain>

On Wed, Dec 11, 2024 at 01:46:11PM +0100, Bartosz Golaszewski wrote:
> On Fri, Dec 6, 2024 at 3:20?AM David Laight <David.Laight at aculab.com> wrote:
> >
> > From: Naresh Kamboju
> > > Sent: 05 December 2024 18:42
> > >
> > > On Thu, 5 Dec 2024 at 20:46, Dan Carpenter <dan.carpenter at linaro.org> wrote:
> > > >
> > > > Add David to the CC list.
> > >
> > > Anders bisected this reported issue and found the first bad commit as,
> > >
> > > # first bad commit:
> > >   [ef32b92ac605ba1b7692827330b9c60259f0af49]
> > >   minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
> >
> > That 'just' changed the test to use __builtin_constant_p() and
> > thus gets checked after the optimiser has run.
> >
> > I can paraphrase the code as:
> > unsigned int fn(unsigned int x)
> > {
> >         return clamp(10, 5, x == 0 ? 0 : x - 1);
> > }
> > which is never actually called with x <= 5.
> > The compiler converts it to:
> >         return x < 0 ? clamp(10, 5, 0) : clamp(10, 5, x);
> > (Probably because it can see that clamp(10, 5, 0) is constant.)
> > And then the compile-time sanity check in clamp() fires.
> >
> > The order of the arguments to clamp is just wrong!
> >
> >         David
> >
> 
> The build is still failing with today's next, should the offending
> commit be reverted?
> 

It's a simple fix.  I've sent a patch.

regards,
dan carpenter



From bigeasy at linutronix.de  Wed Dec 11 05:26:07 2024
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Wed, 11 Dec 2024 14:26:07 +0100
Subject: [PATCH 1/4] ARM: Disable jump-label on PREEMPT_RT
In-Reply-To: <20241210160556.2341497-2-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-2-arnd@kernel.org>
Message-ID: <20241211132607.z1zDTk89@linutronix.de>

On 2024-12-10 17:05:53 [+0100], Arnd Bergmann wrote:
> From: Thomas Gleixner <tglx at linutronix.de>
> 
> jump-labels are used to efficiently switch between two possible code
> paths. To achieve this, stop_machine() is used to keep the CPU in a
> known state while the opcode is modified. The usage of stop_machine()
> here leads to large latency spikes which can be observed on PREEMPT_RT.
> 
> Jump labels may change the target during runtime and are not restricted
> to debug or "configuration/ setup" part of a PREEMPT_RT system where
> high latencies could be defined as acceptable.
> 
> On 64-bit Arm, it is possible to use jump labels without the
> stop_machine() call, which architecturally provides a way to atomically
> change one 32-bit instruction word while keeping maintaining consistency,
> but this is not generally the case on 32-bit, in particular in thumb2
> mode.
> 
> Disable jump-label support on a PREEMPT_RT system when SMP is enabled.
> 
> [bigeasy: Patch description.]
> [arnd: add !SMP case, extend changelog]
> 
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Link: https://lkml.kernel.org/r/20220613182447.112191-2-bigeasy at linutronix.de
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---
> I slightly changed the patch from the version currently in linux-rt.git
> to leave jump labels enabled on single-CPU kernels that are still
> fairly common on 32-bit arm.

So HOTPLUG_CPU depends on SMP and without SMP there no HOTPLUG_CPU so
the patch function will be invoked directly. So we patch and flush.
Well, okay.

> If there are no additional concerns about this version, I will
> forward it to Russell's patch system

I'm fine with it, thank you.

Sebastian


From linus.walleij at linaro.org  Wed Dec 11 05:29:29 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Dec 2024 14:29:29 +0100
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <20241210160556.2341497-3-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org> <20241210160556.2341497-3-arnd@kernel.org>
Message-ID: <CACRpkdZaoD2vqbCi1AFUa6mF2_=c3Nu4R0CvxFAep0VMgtMtOQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 5:06?PM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
>
> gup_pgd_range() is invoked with disabled interrupts and invokes

There is no gup_pgd_range() in the kernel, is this patch a bit
old?

There is gup_fast_pgd_range().
See 23babe1934d7637b598e4c9d9f3876e318fa63a4
gup.c contains:

  get_user_pages_fast attempts to pin user pages by
  walking the page tables directly and avoids taking locks.
(...)
   Let's consistently call the "fast-only" part of GUP "GUP-fast"
   and rename all relevant internal functions to start with
   "gup_fast", to make it clearer that this is not ordinary GUP.
   The current mixture of "lockless",  "gup" and "gup_fast" is
   confusing.

So fast GUP is supposed to be lockless, and should just not
have this problem. So it can't be addressing gup_fast_pgd_range()
right?

> __kmap_local_page_prot() via pte_offset_map(), gup_p4d_range().
> With HIGHPTE enabled, __kmap_local_page_prot() invokes kmap_high_get()
> which uses a spinlock_t via lock_kmap_any(). This leads to an
> sleeping-while-atomic error on PREEMPT_RT because spinlock_t becomes a
> sleeping lock and must not be acquired in atomic context.

I think this needs to be inspected by David Hildenbrand, if he consistently
rename the GPU functions to be "fast" and there is a lock somewhere
deep in there, something must be wrong and violating the API
contract.

> The loop in map_new_virtual() uses wait_queue_head_t for wake up which
> also is using a spinlock_t.
>
> Since HIGHPTE is rarely needed at all, turn it off for PREEMPT_RT
> to allow the use of get_user_pages_fast().
>
> [arnd: rework patch to turn off HIGHPTE instead of HAVE_PAST_GUP]

HAVE_FAST_GUP

I'm still confused, how can something that is supposed to be
lockless "fast" acquire a spinlock? Something is odd here.

> Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
> ---
> There is an open question about whether HIGHPTE is still needed
> at all, given how rare 32-bit machines with more than 4GB
> are on any architecture. If we instead decide to remove HIGHPTE
> altogether, this patch is no longer needed.

I'm more asking if HIGHPTE even acquires a spinlock anymore
as it is supposed to be "fast"/lockless. If it does, it is clearly violating
the "fast" promise of the fast GUP API and should not exist.

Yours,
Linus Walleij


From quic_bibekkum at quicinc.com  Wed Dec 11 05:29:48 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Wed, 11 Dec 2024 18:59:48 +0530
Subject: [PATCH RESEND v17 3/5] iommu/arm-smmu: add support for PRR bit
 setup
In-Reply-To: <CAF6AEGtyc+_2V6qoZCwvRQ_QcC+uCXFXcWRpsQemEfd+rC6R+A@mail.gmail.com>
References: <20241114160721.1527934-1-quic_bibekkum@quicinc.com>
 <20241114160721.1527934-4-quic_bibekkum@quicinc.com>
 <CAF6AEGuwWsAkRyF-h5Aj3KzM7iksb12HsfJ5Ks+-P8hv60MWFg@mail.gmail.com>
 <CAF6AEGvVteuOOMod6yw9_6eOn2PxAx+BR8sVOHAHp7Ts8XigBw@mail.gmail.com>
 <5696afa2-c4ab-42fe-b29a-6ecee622fbb4@quicinc.com>
 <CAF6AEGuMmdnOmATMy8f+YgGxfrYb5mkG_qgy870wZPebKaZjVQ@mail.gmail.com>
 <04da6036-56c4-4b8c-b75b-b5e96a089efc@quicinc.com>
 <CAF6AEGt-e_4kGyfiO=_oCLX8E3z76zeZ2MbRe1GicZj4hTEu+g@mail.gmail.com>
 <808e1041-0d61-4ee8-9778-0f9b7d0fb719@quicinc.com>
 <CAF6AEGtyc+_2V6qoZCwvRQ_QcC+uCXFXcWRpsQemEfd+rC6R+A@mail.gmail.com>
Message-ID: <738f9dc8-0fe4-47e9-b3ff-f19f2f5badb8@quicinc.com>



On 12/6/2024 8:48 PM, Rob Clark wrote:
> On Fri, Dec 6, 2024 at 4:36?AM Bibek Kumar Patro
> <quic_bibekkum at quicinc.com> wrote:
>>
>>
>>
>> On 12/4/2024 8:54 PM, Rob Clark wrote:
>>> On Wed, Dec 4, 2024 at 3:28?AM Bibek Kumar Patro
>>> <quic_bibekkum at quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 11/22/2024 10:04 PM, Rob Clark wrote:
>>>>> On Fri, Nov 22, 2024 at 8:20?AM Bibek Kumar Patro
>>>>> <quic_bibekkum at quicinc.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 11/21/2024 3:40 AM, Rob Clark wrote:
>>>>>>> On Wed, Nov 20, 2024 at 9:17?AM Rob Clark <robdclark at gmail.com> wrote:
>>>>>>>>
>>>>>>>> On Thu, Nov 14, 2024 at 8:10?AM Bibek Kumar Patro
>>>>>>>> <quic_bibekkum at quicinc.com> wrote:
>>>>>>>>>
>>>>>>>>> Add an adreno-smmu-priv interface for drm/msm to call
>>>>>>>>> into arm-smmu-qcom and initiate the PRR bit setup or reset
>>>>>>>>> sequence as per request.
>>>>>>>>>
>>>>>>>>> This will be used by GPU to setup the PRR bit and related
>>>>>>>>> configuration registers through adreno-smmu private
>>>>>>>>> interface instead of directly poking the smmu hardware.
>>>>>>>>>
>>>>>>>>> Suggested-by: Rob Clark <robdclark at gmail.com>
>>>>>>>>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
>>>>>>>>> ---
>>>>>>>>>      drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 37 ++++++++++++++++++++++
>>>>>>>>>      drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 ++
>>>>>>>>>      include/linux/adreno-smmu-priv.h           | 14 ++++++++
>>>>>>>>>      3 files changed, 53 insertions(+)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>>>>>> index d26f5aea248e..0e4f3fbda961 100644
>>>>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>>>>>>>> @@ -16,6 +16,8 @@
>>>>>>>>>
>>>>>>>>>      #define QCOM_DUMMY_VAL -1
>>>>>>>>>
>>>>>>>>> +#define GFX_ACTLR_PRR          (1 << 5)
>>>>>>>>> +
>>>>>>>>>      static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
>>>>>>>>>      {
>>>>>>>>>             return container_of(smmu, struct qcom_smmu, smmu);
>>>>>>>>> @@ -99,6 +101,32 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
>>>>>>>>>             arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
>>>>>>>>>      }
>>>>>>>>>
>>>>>>>>> +static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
>>>>>>>>> +{
>>>>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>>>>>>> +       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>>>>>>>>> +       u32 reg = 0;
>>>>>>>>> +
>>>>>>>>> +       reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
>>>>>>>>> +       reg &= ~GFX_ACTLR_PRR;
>>>>>>>>> +       if (set)
>>>>>>>>> +               reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
>>>>>>>>> +       arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
>>>>>>>>> +{
>>>>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
>>>>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>>>>>>> +
>>>>>>>>> +       writel_relaxed(lower_32_bits(page_addr),
>>>>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
>>>>>>>>> +
>>>>>>>>> +       writel_relaxed(upper_32_bits(page_addr),
>>>>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>>      #define QCOM_ADRENO_SMMU_GPU_SID 0
>>>>>>>>>
>>>>>>>>>      static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
>>>>>>>>> @@ -210,6 +238,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>>>>>>>>>      static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>>>>>>                     struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>>>>>>>>>      {
>>>>>>>>> +       const struct device_node *np = smmu_domain->smmu->dev->of_node;
>>>>>>>>>             struct adreno_smmu_priv *priv;
>>>>>>>>>
>>>>>>>>>             smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>>>>>>>> @@ -239,6 +268,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>>>>>>>>>             priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
>>>>>>>>>             priv->set_stall = qcom_adreno_smmu_set_stall;
>>>>>>>>>             priv->resume_translation = qcom_adreno_smmu_resume_translation;
>>>>>>>>> +       priv->set_prr_bit = NULL;
>>>>>>>>> +       priv->set_prr_addr = NULL;
>>>>>>>>> +
>>>>>>>>> +       if (of_device_is_compatible(np, "qcom,smmu-500") &&
>>>>>>>>> +                       of_device_is_compatible(np, "qcom,adreno-smmu")) {
>>>>>>>>
>>>>>>>> fwiw, it seems like PRR actually works on sc7180, which is _not_
>>>>>>>> mmu-500, so I guess the support actually goes back further.
>>>>>>>>
>>>>>>>> I'm curious if we can just rely on this being supported by any hw that
>>>>>>>> has a6xx or newer?
>>>>>>>
>>>>>>>
>>>>>>> Also, unrelated, but we can't assume the smmu is powered when drm
>>>>>>> driver calls set_prr_bit/addr, could you add in runpm get/put around
>>>>>>> the register access?
>>>>>>>
>>>>>>
>>>>>> I see, thanks for this observation.
>>>>>> It's surely a possible case, when they access these registers
>>>>>> SMMU state is off.
>>>>>> I will add the suggested runpm ops around the register access.
>>>>>>
>>>>>>> Otherwise Conner and I have vk sparse residency working now
>>>>>>>
>>>>>>
>>>>>> Sorry, could not get this. Did you mean that vk sparse residency
>>>>>> is working now using this patch?
>>>>>
>>>>> Yes, vk sparse residency is working with this patch (plus addition of
>>>>> runpm get/put, plus drm/msm patches plus turnip patches) ;-)
>>>>>
>>>>
>>>> Thanks for testing the sparse residency feature with our patch Rob,
>>>> I have an additional query regarding the adreno private interfaces.
>>>> Specifically, I was referring to other interfaces such as
>>>> qcom_adreno_smmu_get_fault_info [1]. It appears that we do not have a
>>>> runpm get/put around the register access in this context.
>>>
>>> get_fault_info() is called from the iommu fault handler callback, so
>>> from the fault irq handler, which is why it didn't need the runpm
>>> get/put.  Maybe it is bad to make this assumption about usage, but
>>> then again adreno_smmu_priv isn't really a general purpose interface.
>>>
>>
>> Ah okay, got it.
>> I was just going through all the adreno_smmmu_priv interfaces just
>> to get a better understanding of it's interaction with smmu and it seems
>> like apart from PRR and get_fault_info(), set_ttbr0_cfg(),
>> resume_translation() is also having reg access but not voting.
>> Should we put runpm_put/get here as well or these can be excluded.
>> <Just curious about the thought process behind this, is it because of
>> some sequence when to put a vote, like reg access in middle of smmu
>> power cycle and not in beginning or end.>
> 
> I think we just haven't needed it, or noticed that we needed it,
> outside of setting up prr.
> 
> As I mentioned, get_fault_info() is called from the fault irq, so we
> know the smmu is already powered.
> 

okay got it, that makes sense.

> As far as set_ttbr0_cfg(), it probably works just because
> arm_smmu_write_context_bank() ends up getting called again in the
> resume path, so if the smmu is suspended when set_ttbr0_cfg() is
> called, the writes just get ignored.  But the updated cfg is
> re-applied to the hw when it is resumed.  Probably the same situation
> with resume_translation().. ie. if the smmu is suspended there are no
> translations to resume.
> 
> Maybe it would be more correct in set_ttbr0_cfg() and
> resume_translation() to do a pm_runtime_get_if_in_use() and skip the
> hw writes if the smmu is suspended.
> 
>>
>>>> Could you please clarify whether we need an SMMU vote around register
>>>> access in the case of PRR? IMO, should the users of this callback ensure
>>>> they put a vote before accessing the cb?
>>>
>>> How can drm vote for the smmu device?  I guess it could power up
>>> itself and rely on device-link.. but that is pretty overkill to power
>>> up the entire gpu in this case.  I think it is best for the vote to
>>> happen in the PRR callbacks.
>>>
>>
>> Okay I see, GPU can only power itself up through <gpu_state_get I
>> assume> but won't have exclusive access to power on the smmu only.
>>
>> Incase we go forward to put vote in PRR callback for SMMU, I was
>> planning that we can refactor existing arm_smmu_rpm_put/get() from
>> arm_smmu.c to it's header file so that the same can be used in
>> arm_smmu_qcom.c ? What's your thoughts on this?
> 
> I had briefly thought of doing the same.  But the main reason for
> those helpers is common arm-smmu code that is used on non-qcom
> platforms where runpm is not enabled.  In arm-smmu-qcom.c, we know
> that runpm is enabled, so we could just use  return
> pm_runtime_resume_and_get()/pm_runtime_put_autosuspend() directly.
> 

Ohkay I see, we then do not need pm_runtime_enabled() check for qcom 
platforms before putting the vote.
I am currently modifying this patch only to directly add
pm_runtime_resume_and_get()/pm_runtime_put_autosuspend()
around the register access of PRR related adreno private interfaces.
I will send this updated patch as part of v18 shortly.

Additionally, we can evaluate the use of pm_runtime operations for 
set_ttbr0_cfg() and resume_translation() in a separate series ?

Thanks & regards,
Bibek

> BR,
> -R
> 
>> Thanks & regards,
>> Bibek
>>
>>> BR,
>>> -R
>>>
>>>> [1]:
>>>> https://lore.kernel.org/all/20210610214431.539029-1-robdclark at gmail.com/
>>>>
>>>> Thanks & regards,
>>>> Bibek
>>>>
>>>>> BR,
>>>>> -R
>>>>>
>>>>>> Thanks & regards,
>>>>>> Bibek
>>>>>>
>>>>>>> BR,
>>>>>>> -R
>>>>>>>
>>>>>>>>
>>>>>>>>> +               priv->set_prr_bit = qcom_adreno_smmu_set_prr_bit;
>>>>>>>>> +               priv->set_prr_addr = qcom_adreno_smmu_set_prr_addr;
>>>>>>>>> +       }
>>>>>>>>>
>>>>>>>>>             return 0;
>>>>>>>>>      }
>>>>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>>>>>> index e2aeb511ae90..2dbf3243b5ad 100644
>>>>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>>>>>>>>> @@ -154,6 +154,8 @@ enum arm_smmu_cbar_type {
>>>>>>>>>      #define ARM_SMMU_SCTLR_M               BIT(0)
>>>>>>>>>
>>>>>>>>>      #define ARM_SMMU_CB_ACTLR              0x4
>>>>>>>>> +#define ARM_SMMU_GFX_PRR_CFG_LADDR     0x6008
>>>>>>>>> +#define ARM_SMMU_GFX_PRR_CFG_UADDR     0x600C
>>>>>>>>>
>>>>>>>>>      #define ARM_SMMU_CB_RESUME             0x8
>>>>>>>>>      #define ARM_SMMU_RESUME_TERMINATE      BIT(0)
>>>>>>>>> diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
>>>>>>>>> index c637e0997f6d..614665153b3e 100644
>>>>>>>>> --- a/include/linux/adreno-smmu-priv.h
>>>>>>>>> +++ b/include/linux/adreno-smmu-priv.h
>>>>>>>>> @@ -50,6 +50,18 @@ struct adreno_smmu_fault_info {
>>>>>>>>>       *                 the GPU driver must call resume_translation()
>>>>>>>>>       * @resume_translation: Resume translation after a fault
>>>>>>>>>       *
>>>>>>>>> + * *CAUTION* : PRR callbacks (set_prr_bit/set_prr_addr) are NULL terminated for
>>>>>>>>> + *             targets without PRR support. Exercise caution and verify target
>>>>>>>>> + *             capabilities before invoking these callbacks to prevent potential
>>>>>>>>> + *             runtime errors or unexpected behavior.
>>>>>>>>> + *
>>>>>>>>> + * @set_prr_bit:   Extendible interface to be used by GPU to modify the
>>>>>>>>> + *                ACTLR register bits, currently used to configure
>>>>>>>>> + *                Partially-Resident-Region (PRR) bit for feature's
>>>>>>>>> + *                setup and reset sequence as requested.
>>>>>>>>> + * @set_prr_addr:  Configure the PRR_CFG_*ADDR register with the
>>>>>>>>> + *                physical address of PRR page passed from
>>>>>>>>> + *                GPU driver.
>>>>>>>>>       *
>>>>>>>>>       * The GPU driver (drm/msm) and adreno-smmu work together for controlling
>>>>>>>>>       * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
>>>>>>>>> @@ -67,6 +79,8 @@ struct adreno_smmu_priv {
>>>>>>>>>          void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
>>>>>>>>>          void (*set_stall)(const void *cookie, bool enabled);
>>>>>>>>>          void (*resume_translation)(const void *cookie, bool terminate);
>>>>>>>>> +    void (*set_prr_bit)(const void *cookie, bool set);
>>>>>>>>> +    void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
>>>>>>>>>      };
>>>>>>>>>
>>>>>>>>>      #endif /* __ADRENO_SMMU_PRIV_H */
>>>>>>>>> --
>>>>>>>>> 2.34.1
>>>>>>>>>
>>>>>>
>>>>
>>



From tabba at google.com  Wed Dec 11 05:30:15 2024
From: tabba at google.com (Fuad Tabba)
Date: Wed, 11 Dec 2024 13:30:15 +0000
Subject: [PATCH v4 04/14] KVM: arm64: Use KVM extension checks for allowed
 protected VM capabilities
In-Reply-To: <Z1mTtS9nGvVM-BIq@google.com>
References: <20241202154742.3611749-1-tabba@google.com> <20241202154742.3611749-5-tabba@google.com>
 <Z1MwAomiLhnMn--k@google.com> <CA+EHjTy6Y6w9RyU2Vn8O+DDviSJf=P-Y4c+xVFqY-3GmHBv3kQ@mail.gmail.com>
 <Z1mTtS9nGvVM-BIq@google.com>
Message-ID: <CA+EHjTz6B_8YzreN5EEqh6u-ZGLj0GjBxGe2THCwjWP0RT5KeA@mail.gmail.com>

On Wed, 11 Dec 2024 at 13:29, Quentin Perret <qperret at google.com> wrote:
>
> On Monday 09 Dec 2024 at 08:14:15 (+0000), Fuad Tabba wrote:
> > Hi Quentin,
> >
> > On Fri, 6 Dec 2024 at 17:10, Quentin Perret <qperret at google.com> wrote:
> > >
> > > On Monday 02 Dec 2024 at 15:47:31 (+0000), Fuad Tabba wrote:
> > > > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > > index fb733b36c6c1..59ff6aac514c 100644
> > > > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > > @@ -329,34 +329,20 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
> > > >
> > > >       bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
> > > >
> > > > -     /*
> > > > -      * For protected VMs, always allow:
> > > > -      * - CPU starting in poweroff state
> > > > -      * - PSCI v0.2
> > > > -      */
> > > > -     set_bit(KVM_ARM_VCPU_POWER_OFF, allowed_features);
> > >
> > > For my understanding, why do we drop this bit?
> >
> > Since the hypervisor is responsible for the power state of protected
> > VMs. This should either be a separate patch or I should explain it in
> > the commit message. Any preference?
>
> Gotcha, perhaps make that its own patch so we have a commit message
> motivating the change?

Will do.
/fuad


From qperret at google.com  Wed Dec 11 05:29:25 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Dec 2024 13:29:25 +0000
Subject: [PATCH v4 04/14] KVM: arm64: Use KVM extension checks for
 allowed protected VM capabilities
In-Reply-To: <CA+EHjTy6Y6w9RyU2Vn8O+DDviSJf=P-Y4c+xVFqY-3GmHBv3kQ@mail.gmail.com>
References: <20241202154742.3611749-1-tabba@google.com>
 <20241202154742.3611749-5-tabba@google.com>
 <Z1MwAomiLhnMn--k@google.com>
 <CA+EHjTy6Y6w9RyU2Vn8O+DDviSJf=P-Y4c+xVFqY-3GmHBv3kQ@mail.gmail.com>
Message-ID: <Z1mTtS9nGvVM-BIq@google.com>

On Monday 09 Dec 2024 at 08:14:15 (+0000), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Fri, 6 Dec 2024 at 17:10, Quentin Perret <qperret at google.com> wrote:
> >
> > On Monday 02 Dec 2024 at 15:47:31 (+0000), Fuad Tabba wrote:
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > index fb733b36c6c1..59ff6aac514c 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > @@ -329,34 +329,20 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
> > >
> > >       bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
> > >
> > > -     /*
> > > -      * For protected VMs, always allow:
> > > -      * - CPU starting in poweroff state
> > > -      * - PSCI v0.2
> > > -      */
> > > -     set_bit(KVM_ARM_VCPU_POWER_OFF, allowed_features);
> >
> > For my understanding, why do we drop this bit?
> 
> Since the hypervisor is responsible for the power state of protected
> VMs. This should either be a separate patch or I should explain it in
> the commit message. Any preference?

Gotcha, perhaps make that its own patch so we have a commit message
motivating the change?


From linus.walleij at linaro.org  Wed Dec 11 05:32:51 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Dec 2024 14:32:51 +0100
Subject: [PATCH 3/4] ARM: drop CONFIG_HIGHPTE support
In-Reply-To: <20241210160556.2341497-4-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org> <20241210160556.2341497-4-arnd@kernel.org>
Message-ID: <CACRpkdZoRbJ4DwRpZQMKbEAvzg4AAdp4B+94SFLm1ssiQmjUwQ@mail.gmail.com>

On Tue, Dec 10, 2024 at 5:06?PM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> CONFIG_HIGHPTE was added in linux-2.6.32, a few years before 64-bit
> support. At the time it made sense, as the CONFIG_ARM_LPAE option allowed
> systems with 16GB of memory that made lowmem a particularly scarce
> resource, and the HIGHPTE implementation gave feature parity with 32-bit
> x86 and frv machines.
>
> Since Arm is the last architecture remaining that uses this, and almost
> no 32-bit machines support more than 4GB of RAM, the cost of continuing
> to maintain HIGHPTE seems unjustified, so remove it here to allow
> simplifying the generic page table handling.
>
> Link: https://lore.kernel.org/lkml/20241204103042.1904639-8-arnd at kernel.org/T/#u
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

I'm in favor of this if the x86 patch goes in. We need to get rid
of highmem anyway and this will need to happen sooner or later
either way.
Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From kevin.brodsky at arm.com  Wed Dec 11 05:35:28 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Wed, 11 Dec 2024 14:35:28 +0100
Subject: [RFC PATCH 12/16] arm64: mm: Map p4d/pgd with privileged pkey
In-Reply-To: <20241210122355.GN8562@noisy.programming.kicks-ass.net>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-13-kevin.brodsky@arm.com>
 <20241209102440.GI21636@noisy.programming.kicks-ass.net>
 <75a345d4-78ea-4434-a4cd-3f2095ce2b31@arm.com>
 <20241210122355.GN8562@noisy.programming.kicks-ass.net>
Message-ID: <8aedf3db-d1a5-4cc6-974b-a3d9fffe4f52@arm.com>

On 10/12/2024 13:23, Peter Zijlstra wrote:
> On Tue, Dec 10, 2024 at 10:27:56AM +0100, Kevin Brodsky wrote:
>> On 09/12/2024 11:24, Peter Zijlstra wrote:
>>> On Fri, Dec 06, 2024 at 10:11:06AM +0000, Kevin Brodsky wrote:
>>>> If CONFIG_KPKEYS_HARDENED_PGTABLES is enabled, map p4d/pgd pages
>>>> using a privileged pkey (KPKEYS_PKEY_PGTABLES), so that they can
>>>> only be written under guard(kpkeys_hardened_pgtables).
>>>>
>>>> The case where pgd is not page-sized is not currently handled -
>>>> this is pending support for pkeys in kmem_cache.
>>>>
>>>> This patch is a no-op if CONFIG_KPKEYS_HARDENED_PGTABLES is disabled
>>>> (default).
>>> Should not this live in pagetable_*_[cd]tor() in generic code?
>> This would certainly be preferable but it doesn't look like such helpers
>> exist for p4d/pgd. For p4d, we could potentially handle this in the
>> generic __p4d_alloc(), but I'm not sure we can assume that
>> p4d_alloc_one() won't be called from somewhere else. pgd_alloc() is
>> entirely arch-specific so not much we can do there.
> Can't we add the missing pagetable_{p4d,pgd}_[cd]tor() functions. Yes,
> it will mean touching a bunch of arch code, but it shouldn't be hard.

It does look doable. The p4d level shouldn't be an issue, it's unclear
why it doesn't follow the same pattern as pud already. pgd will be more
involved (no generic layer at all) but as you say it should just be
about some churn in arch code.

An extra complication is that the pgd level may be smaller than a page,
at least on arm64 (see pgd_alloc() in arch/arm64/mm/pgd.c). I suppose
affected architectures will have to define their own pgd_alloc_one().

I'll give it a try and post something separately if it looks sensible.

- Kevin


From kevin.brodsky at arm.com  Wed Dec 11 05:37:38 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Wed, 11 Dec 2024 14:37:38 +0100
Subject: [RFC PATCH 13/16] arm64: mm: Reset pkey in __tlb_remove_table()
In-Reply-To: <20241210122706.GO8562@noisy.programming.kicks-ass.net>
References: <20241206101110.1646108-1-kevin.brodsky@arm.com>
 <20241206101110.1646108-14-kevin.brodsky@arm.com>
 <20241209102913.GJ21636@noisy.programming.kicks-ass.net>
 <7124d7f4-1d4c-4497-94d8-243af2ed071a@arm.com>
 <20241210122706.GO8562@noisy.programming.kicks-ass.net>
Message-ID: <a8fea276-152f-4cf3-a87f-e48ae6e5c024@arm.com>

On 10/12/2024 13:27, Peter Zijlstra wrote:
> On Tue, Dec 10, 2024 at 10:28:44AM +0100, Kevin Brodsky wrote:
>> On 09/12/2024 11:29, Peter Zijlstra wrote:
>>> On Fri, Dec 06, 2024 at 10:11:07AM +0000, Kevin Brodsky wrote:
>>>> [...]
>>>>
>>>> diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
>>>> index a947c6e784ed..d1611ffa6d91 100644
>>>> --- a/arch/arm64/include/asm/tlb.h
>>>> +++ b/arch/arm64/include/asm/tlb.h
>>>> @@ -10,10 +10,14 @@
>>>>  
>>>>  #include <linux/pagemap.h>
>>>>  #include <linux/swap.h>
>>>> +#include <linux/kpkeys.h>
>>>>  
>>>>  static inline void __tlb_remove_table(void *_table)
>>>>  {
>>>> -	free_page_and_swap_cache((struct page *)_table);
>>>> +	struct page *page = (struct page *)_table;
>>>> +
>>>> +	kpkeys_unprotect_pgtable_memory((unsigned long)page_address(page), 1);
>>>> +	free_page_and_swap_cache(page);
>>>>  }
>>> Same as for the others, perhaps stick this in generic code instead of in
>>> the arch code?
>> This should be doable, with some refactoring. __tlb_remove_table() is
>> currently called from two functions in mm/mmu_gather.c, I suppose I
>> could create a wrapper there that calls
>> kpkeys_unprotect_pgtable_memory() and then __tlb_remove_table(). Like in
>> the p4d case I do however wonder how robust this is, as
>> __tlb_remove_table() could end up being called from other places.
> I don't foresee other __tlb_remove_table() users, this is all rather
> speicific code. But if there ever were to be new users, it is something
> they would have to take into consideration.

Fair enough, I'll handle that in mm/mmu_gather.c then.

- Kevin


From guomin_chen at sina.com  Wed Dec 11 05:45:05 2024
From: guomin_chen at sina.com (guomin_chen at sina.com)
Date: Wed, 11 Dec 2024 21:45:05 +0800
Subject: [PATCH] firmware: arm_scmi: Delete the meaningless scmi_bus_id.
Message-ID: <20241211134505.2218386-1-guomin_chen@sina.com>

From: guomin chen <guomin_chen at sina.com>

Currently, scmi_bus_id is only used to set scmi_dev.id,
which in turn sets the SCMI device name. After removing
scmi_bus_id, it is clearer and more meaningful to directly
use the input parameters name and protocol to set the SCMI
device name.

Signed-off-by: guomin chen <guomin_chen at sina.com>
---
 drivers/firmware/arm_scmi/bus.c    | 16 ++--------------
 drivers/firmware/arm_scmi/driver.c |  4 ++--
 2 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 157172a5f2b5..c4e013a77e33 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -20,7 +20,6 @@
 BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
 EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
 
-static DEFINE_IDA(scmi_bus_id);
 
 static DEFINE_IDR(scmi_requested_devices);
 /* Protect access to scmi_requested_devices */
@@ -341,7 +340,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
 	if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
 		atomic_set(&scmi_syspower_registered, 0);
 
-	ida_free(&scmi_bus_id, scmi_dev->id);
 	device_unregister(&scmi_dev->dev);
 }
 
@@ -349,7 +347,7 @@ static struct scmi_device *
 __scmi_device_create(struct device_node *np, struct device *parent,
 		     int protocol, const char *name)
 {
-	int id, retval;
+	int retval;
 	struct scmi_device *scmi_dev;
 
 	/*
@@ -387,20 +385,12 @@ __scmi_device_create(struct device_node *np, struct device *parent,
 		return NULL;
 	}
 
-	id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
-	if (id < 0) {
-		kfree_const(scmi_dev->name);
-		kfree(scmi_dev);
-		return NULL;
-	}
-
-	scmi_dev->id = id;
 	scmi_dev->protocol_id = protocol;
 	scmi_dev->dev.parent = parent;
 	device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
 	scmi_dev->dev.bus = &scmi_bus_type;
 	scmi_dev->dev.release = scmi_device_release;
-	dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
+	dev_set_name(&scmi_dev->dev, "scmi_dev.%s.%d", scmi_dev->name, protocol);
 
 	retval = device_register(&scmi_dev->dev);
 	if (retval)
@@ -413,7 +403,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
 	return scmi_dev;
 put_dev:
 	put_device(&scmi_dev->dev);
-	ida_free(&scmi_bus_id, id);
 	return NULL;
 }
 
@@ -526,7 +515,6 @@ static void __exit scmi_bus_exit(void)
 	 */
 	scmi_devices_unregister();
 	bus_unregister(&scmi_bus_type);
-	ida_destroy(&scmi_bus_id);
 }
 module_exit(scmi_bus_exit);
 
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 1b5fb2c4ce86..bbf1f05f2be3 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2641,8 +2641,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
 	cinfo->max_msg_size = info->desc->max_msg_size;
 
 	/* Create a unique name for this transport device */
-	snprintf(name, 32, "__scmi_transport_device_%s_%02X",
-		 idx ? "rx" : "tx", prot_id);
+	snprintf(name, 32, "__scmi_transport_device_%s",
+		 idx ? "rx" : "tx");
 	/* Create a uniquely named, dedicated transport device for this chan */
 	tdev = scmi_device_create(of_node, info->dev, prot_id, name);
 	if (!tdev) {
-- 
2.47.1



From andrew at lunn.ch  Wed Dec 11 05:45:46 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 11 Dec 2024 14:45:46 +0100
Subject: [PATCH 07/15] ARM: zynq: Add ethernet phy reset information to
 DT(zc702)
In-Reply-To: <9e18d59ca339804320d2a5e3c7362aefa3bb7c99.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
 <9e18d59ca339804320d2a5e3c7362aefa3bb7c99.1733920873.git.michal.simek@amd.com>
Message-ID: <8395fb6b-d7a5-4e2c-9eb3-4984b8c775c4@lunn.ch>

On Wed, Dec 11, 2024 at 01:41:26PM +0100, Michal Simek wrote:
> Added phy reset gpio information for gem0.
> 
> Signed-off-by: Michal Simek <michal.simek at amd.com>
> ---
> 
>  arch/arm/boot/dts/xilinx/zynq-zc702.dts | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
> index 424e78f6c148..975385f4ac01 100644
> --- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
> +++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
> @@ -79,6 +79,8 @@ &gem0 {
>  	phy-handle = <&ethernet_phy>;
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_gem0_default>;
> +	phy-reset-gpio = <&gpio0 11 0>;
> +	phy-reset-active-low;

Hi Michal

Could you point me at code which actually implements these two
properties.

What is more normal is a reset-gpios property in the PHY node, or a
reset-gpios in the MDIO node.

	Andrew


From Trevor.Wu at mediatek.com  Wed Dec 11 05:47:32 2024
From: Trevor.Wu at mediatek.com (=?utf-8?B?VHJldm9yIFd1ICjlkLPmlofoia8p?=)
Date: Wed, 11 Dec 2024 13:47:32 +0000
Subject: [PATCH] ASoC: mediatek: mt8188: Enable apll1 clock during reg rw
 to prevent hang
In-Reply-To: <108d4187-26af-43f6-8b1e-0e48516524a4@notapiano>
References: <20241203-mt8188-afe-fix-hang-disabled-apll1-clk-v1-1-07cdd7760834@collabora.com>
	 <a10dbdf265194e77a69b6e40afa3df9636b3ab14.camel@mediatek.com>
	 <a70a0521-985d-43a4-a1fa-36eb733d5ca9@collabora.com>
	 <1d2ee55dde84bcab6f777525042c6789b9f2c1fc.camel@mediatek.com>
	 <108d4187-26af-43f6-8b1e-0e48516524a4@notapiano>
Message-ID: <57cf1810250d922ee01b9eff096c945c5c3a1375.camel@mediatek.com>

On Mon, 2024-12-09 at 17:07 -0300, N?colas F. R. A. Prado wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On Fri, Dec 06, 2024 at 06:57:00AM +0000, Trevor Wu (???) wrote:
> > On Thu, 2024-12-05 at 13:51 +0100, AngeloGioacchino Del Regno
> > wrote:
> > > 
> > > 
> > > Il 04/12/24 13:17, Trevor Wu (???) ha scritto:
> > > > On Tue, 2024-12-03 at 17:07 -0300, N?colas F. R. A. Prado
> > > > wrote:
> > > > 
> > > > > 
> > > > > Currently, booting the Genio 700 EVK board with the MT8188
> > > > > sound
> > > > > platform driver configured as a module
> > > > > (CONFIG_SND_SOC_MT8188=m)
> > > > > results
> > > > > in a system hang right when the HW registers for the audio
> > > > > controller
> > > > > are read:
> > > > > 
> > > > >    mt8188-audio 10b10000.audio-controller: No cache defaults,
> > > > > reading
> > > > > back from HW
> > > > > 
> > > > > The hang doesn't occur with the driver configured as builtin
> > > > > as
> > > > > then
> > > > > the
> > > > > unused clocks are still enabled.
> > > > > 
> > > > > Enable the apll1 clock during register read/write to prevent
> > > > > the
> > > > > hang.
> > > > > 
> > > > > Signed-off-by: N?colas F. R. A. Prado <
> > > > > nfraprado at collabora.com>
> > > > > ---
> > > > >   sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 4 ++++
> > > > >   1 file changed, 4 insertions(+)
> > > > > 
> > > > > diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > > b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > > index
> > > > > e69c1bb2cb239596dee50b166c20192d5408be10..fb8cf286df3f02ac076
> > > > > 528b
> > > > > 898f
> > > > > d0d7a708ec1ea 100644
> > > > > --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > > +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
> > > > > @@ -587,6 +587,8 @@ int mt8188_afe_enable_reg_rw_clk(struct
> > > > > mtk_base_afe *afe)
> > > > >          mt8188_afe_enable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_A1SYS_HP]);
> > > > > 
> > > > >          mt8188_afe_enable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_A1SYS]);
> > > > > 
> > > > > +       mt8188_afe_enable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_APMIXED_APLL1]);
> > > > > 
> > > > > +
> > > > >          return 0;
> > > > >   }
> > > > 
> > > > Hi Nicolas,
> > > > 
> > > > If I understand correctly, APLL1 should be the parent clock of
> > > > AUD_A1SYS_HP and AUD_A1SYS, so it should be enabled
> > > > automatically
> > > > by
> > > > CCF.
> > > > 
> > > > I'm not sure why you resolved the hang issue after enabling
> > > > APLL1.
> > > > Could you share more details about the solution?
> > > > 
> > > 
> > > Hmm. Now I see what's happening here...
> > > 
> > > Nicolas, Trevor,
> > > 
> > > Possible parents for top_a1sys_hp are:
> > >   - clk26m
> > >   - apll1_d4
> > > 
> > > ...what's happening here most probably is that after the clock
> > > gets
> > > disabled as
> > > unused, it gets parented to clk26m by default as that is parent
> > > index
> > > 0... and
> > > something else in AFE needs APLL1 to feed a clock to .. something
> > > ..
> > > to allow
> > > register access.
> > > 
> > > Trevor, do you know why is this IP unaccessible when A1SYS is
> > > parented to clk26m?
> > 
> > Hi Angelo,
> > 
> > As far as I know, it should work even though the clock is parented
> > to
> > clk26m.
> > 
> > Unfortunately, I have no idea about why APLL1 enabling can resolve
> > the
> > hang issue. I'm also curious about how Nicolas found the solution
> > to
> > resolve the problem.
> > 
> > From the description, it seems that the problem is related to
> > register
> > r/w hang. If I remembered correctly, when the mtcmos of ADSP_INFRA
> > is
> > ON, register r/w won't cause the cpu to hang. However, ADSP_INFRA
> > has
> > been configured as ALWAYS_ON in the driver. I'm not sure if it
> > doesn't
> > work correctly when the driver is configured as a module. Maybe
> > Nicolas
> > can also check this.
> 
> Indeed, as suggested by Angelo, adding
> 
>   assigned-clocks = <&topckgen CLK_TOP_A1SYS_HP>;
>   assigned-clock-parents = <&topckgen CLK_TOP_APLL1_D4>;
> 
> to the afe node also fixes this issue.
> 
> In mt8188.dtsi, we currently have
> 
>   afe: audio-controller at 10b10000 {
>         ...
>         assigned-clocks = <&topckgen CLK_TOP_A1SYS_HP>;
>         assigned-clock-parents =  <&clk26m>;
> 
> So the question is, do other MT8188 platforms need clk26m to be the
> parent of
> a1sys_hp? Depending on that I can either update the parent on the
> common
> mt8188.dtsi or on the genio700-evk.dts, which is where I observed the
> issue. I
> don't have access to other mt8188 platforms. Trevor, do you know?


If I remember correctly, the reason for assigning 26m as the parent of
a1sys_hp is to save power[1], as APLL is not necessary in all cases.

[1] 
https://lore.kernel.org/r/20230510035526.18137-5-trevor.wu at mediatek.com

Thanks,
Trevor

> 
> As for how I identified this issue, I noticed that when booting with
> the
> platform driver as a module the system would hang, and that passing
> clk_ignore_unused avoided the issue. Then I selectively ignored some
> unused
> clocks until I narrowed down to ignoring unused only the apll1 clock,
> meaning
> the apll1 clock needed to be left on during the platform driver probe
> for the
> system to not hang.
> 
> Thanks,
> N?colas
> 
> > 
> > Thanks,
> > Trevor
> > 
> > > 
> > > That might give Nicolas a definitive hint about how to resolve
> > > this
> > > issue.
> > > 
> > > Cheers,
> > > Angelo
> > > 
> > > > Thanks,
> > > > Trevor
> > > > 
> > > > > 
> > > > > @@ -594,6 +596,8 @@ int mt8188_afe_disable_reg_rw_clk(struct
> > > > > mtk_base_afe *afe)
> > > > >   {
> > > > >          struct mt8188_afe_private *afe_priv = afe-
> > > > > > platform_priv;
> > > > > 
> > > > > +       mt8188_afe_disable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_APMIXED_APLL1]);
> > > > > 
> > > > > +
> > > > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_A1SYS]);
> > > > > 
> > > > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_A1SYS_HP]);
> > > > > 
> > > > >          mt8188_afe_disable_clk(afe, afe_priv-
> > > > > > clk[MT8188_CLK_AUD_AFE]);
> > > > > 
> > > > > ---
> > > > > base-commit: b852e1e7a0389ed6168ef1d38eb0bad71a6b11e8
> > > > > change-id: 20241203-mt8188-afe-fix-hang-disabled-apll1-clk-
> > > > > b3c11782cbaf
> > > > > 
> > > > > Best regards,
> > > > > --
> > > > > N?colas F. R. A. Prado <nfraprado at collabora.com>
> > > > > 
> > > > > 
> > > 
> > > 

From bigeasy at linutronix.de  Wed Dec 11 05:48:11 2024
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Wed, 11 Dec 2024 14:48:11 +0100
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <20241210160556.2341497-3-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-3-arnd@kernel.org>
Message-ID: <20241211134811.wM_UADhQ@linutronix.de>

On 2024-12-10 17:05:54 [+0100], Arnd Bergmann wrote:
> From: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
> 
> gup_pgd_range() is invoked with disabled interrupts and invokes
> __kmap_local_page_prot() via pte_offset_map(), gup_p4d_range().

s at gup_pgd_range@gup_fast_pgd_range@
s at gup_p4d_range@gup_fast_p4d_range@

The functions got renamed?

> With HIGHPTE enabled, __kmap_local_page_prot() invokes kmap_high_get()
> which uses a spinlock_t via lock_kmap_any(). This leads to an
> sleeping-while-atomic error on PREEMPT_RT because spinlock_t becomes a
> sleeping lock and must not be acquired in atomic context.
> 
> The loop in map_new_virtual() uses wait_queue_head_t for wake up which
> also is using a spinlock_t.
> 
> Since HIGHPTE is rarely needed at all, turn it off for PREEMPT_RT
> to allow the use of get_user_pages_fast().
> 
> [arnd: rework patch to turn off HIGHPTE instead of HAVE_PAST_GUP]
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

This version works, too. Thanks.

> ---
> There is an open question about whether HIGHPTE is still needed
> at all, given how rare 32-bit machines with more than 4GB
> are on any architecture. If we instead decide to remove HIGHPTE
> altogether, this patch is no longer needed.

HIGHPTE isn't much about 4GiB+ but about the page-table which is
offloaded to HIGHMEM. Maybe it is more likely to be needed with 4GiB+ of
memory. No idea. X86 had support for up to 64GiB of memory and is the
only architecture supporting HIGHPTE :)

I guess if you have boxes with 4GiB+ and can proof that the performance
improves without HIGHPTE (since you don't have to map the page table).
The question is then how much of low mem has to be used instead and when
does it start to hurt.

Sebastian


From linus.walleij at linaro.org  Wed Dec 11 05:53:11 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Dec 2024 14:53:11 +0100
Subject: [PATCH 4/4] mm: drop HIGHPTE support altogether
In-Reply-To: <20241210160556.2341497-5-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org> <20241210160556.2341497-5-arnd@kernel.org>
Message-ID: <CACRpkdbsN9WNZ4Fo++FvK+2xxe6VF+66oaBgs4+o3oGUfW4OaA@mail.gmail.com>

On Tue, Dec 10, 2024 at 5:06?PM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> With both x86 and arm having dropped CONFIG_HIGHPTE support, no
> architecture is left using it, so remove the remnants in common code.
>
> It is likely that further cleanups are possible in the page table
> code but those are not obvious from the config options.
>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Acked-by: Linus Walleij <linus.walleij at linaro.org>

Mapping PTEs in highmem makes no sense to me, it's better
that we try other solutions to move away from highmem use
altogether.

Yours,
Linus Walleij


From m-malladi at ti.com  Wed Dec 11 05:59:39 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Wed, 11 Dec 2024 19:29:39 +0530
Subject: [PATCH net v4 0/2] IEP clock module bug fixes
Message-ID: <20241211135941.1800240-1-m-malladi@ti.com>

Hi All,
This series has some bug fixes for IEP module needed by PPS and
timesync operations.

Patch 1/2 fixes firmware load sequence to run all the firmwares
when either of the ethernet interfaces is up. Move all the code
common for firmware bringup under common functions.

Patch 2/2 fixes distorted PPS signal when the ethernet interfaces
are brough down and up. This patch also fixes enabling PPS signal
after bringing the interface up, without disabling PPS.

MD Danish Anwar (1):
  net: ti: icssg-prueth: Fix firmware load sequence.

Meghana Malladi (1):
  net: ti: icssg-prueth: Fix clearing of IEP_CMP_CFG registers during
    iep_init

 drivers/net/ethernet/ti/icssg/icss_iep.c      |   9 +
 drivers/net/ethernet/ti/icssg/icssg_common.c  |   1 -
 drivers/net/ethernet/ti/icssg/icssg_config.c  |  41 ++--
 drivers/net/ethernet/ti/icssg/icssg_config.h  |   1 +
 drivers/net/ethernet/ti/icssg/icssg_prueth.c  | 200 ++++++++++++------
 drivers/net/ethernet/ti/icssg/icssg_prueth.h  |   6 +-
 .../net/ethernet/ti/icssg/icssg_prueth_sr1.c  |   1 -
 7 files changed, 179 insertions(+), 80 deletions(-)


base-commit: dfc14664794a4706e0c2186a0c082386e6b14c4d
-- 
2.25.1



From m-malladi at ti.com  Wed Dec 11 05:59:40 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Wed, 11 Dec 2024 19:29:40 +0530
Subject: [PATCH net v4 1/2] net: ti: icssg-prueth: Fix firmware load sequence.
In-Reply-To: <20241211135941.1800240-1-m-malladi@ti.com>
References: <20241211135941.1800240-1-m-malladi@ti.com>
Message-ID: <20241211135941.1800240-2-m-malladi@ti.com>

From: MD Danish Anwar <danishanwar at ti.com>

Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0
and SLICE1. Currently whenever any ICSSG interface comes up we load the
respective firmwares to PRU cores and whenever interface goes down, we
stop the resective cores. Due to this, when SLICE0 goes down while
SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is
stopped. This results in clock jump for SLICE1 interface as the timesync
related operations are no longer running.

As there are interdependencies between SLICE0 and SLICE1 firmwares,
fix this by running both PRU0 and PRU1 firmwares as long as at least 1
ICSSG interface is up. Add new flag in prueth struct to check if all
firmwares are running and remove the old flag (fw_running).

Use emacs_initialized as reference count to load the firmwares for the
first and last interface up/down. Moving init_emac_mode and fw_offload_mode
API outside of icssg_config to icssg_common_start API as they need
to be called only once per firmware boot.

Change prueth_emac_restart() to return error code and add error prints
inside the caller of this functions in case of any failures.

Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Signed-off-by: Meghana Malladi <m-malladi at ti.com>
---

Hi all,

This patch is based on net-next tagged next-20241205
v3:https://lore.kernel.org/all/20241205082831.777868-2-m-malladi at ti.com/

* Changes since v3 (v4-v3):
- Add error handling for prueth_emac_restart() suggested by Roger Quadros <rogerq at kernel.org>
- Remove fw_running flag as suggested by Roger Quadros <rogerq at kernel.org> and Diogo Ivo <diogo.ivo at siemens.com>
- Few cosmetic changes suggested by Kalesh Anakkur Purayil <kalesh-anakkur.purayil at broadcom.com>

 drivers/net/ethernet/ti/icssg/icssg_common.c  |   1 -
 drivers/net/ethernet/ti/icssg/icssg_config.c  |  41 ++--
 drivers/net/ethernet/ti/icssg/icssg_config.h  |   1 +
 drivers/net/ethernet/ti/icssg/icssg_prueth.c  | 200 ++++++++++++------
 drivers/net/ethernet/ti/icssg/icssg_prueth.h  |   6 +-
 .../net/ethernet/ti/icssg/icssg_prueth_sr1.c  |   1 -
 6 files changed, 170 insertions(+), 80 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
index fdebeb2f84e0..179b5de58281 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -872,7 +872,6 @@ void prueth_emac_stop(struct prueth_emac *emac)
 		return;
 	}
 
-	emac->fw_running = 0;
 	if (!emac->is_sr1)
 		rproc_shutdown(prueth->txpru[slice]);
 	rproc_shutdown(prueth->rtu[slice]);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
index 5d2491c2943a..ddfd1c02a885 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
@@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac)
 	return 0;
 }
 
-static void icssg_init_emac_mode(struct prueth *prueth)
+void icssg_init_emac_mode(struct prueth *prueth)
 {
 	/* When the device is configured as a bridge and it is being brought
 	 * back to the emac mode, the host mac address has to be set as 0.
@@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth)
 	int i;
 	u8 mac[ETH_ALEN] = { 0 };
 
-	if (prueth->emacs_initialized)
-		return;
-
 	/* Set VLAN TABLE address base */
 	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
 			   addr <<  SMEM_VLAN_OFFSET);
@@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth)
 	/* Clear host MAC address */
 	icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
 }
+EXPORT_SYMBOL_GPL(icssg_init_emac_mode);
 
-static void icssg_init_fw_offload_mode(struct prueth *prueth)
+void icssg_init_fw_offload_mode(struct prueth *prueth)
 {
 	u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET;
 	int i;
 
-	if (prueth->emacs_initialized)
-		return;
-
 	/* Set VLAN TABLE address base */
 	regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK,
 			   addr <<  SMEM_VLAN_OFFSET);
@@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth)
 		icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr);
 	icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST);
 }
+EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode);
 
 int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
 {
@@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
 	struct icssg_flow_cfg __iomem *flow_cfg;
 	int ret;
 
-	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
-		icssg_init_fw_offload_mode(prueth);
-	else
-		icssg_init_emac_mode(prueth);
-
 	memset_io(config, 0, TAS_GATE_MASK_LIST0);
 	icssg_miig_queues_init(prueth, slice);
 
@@ -786,3 +777,27 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port)
 		writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET);
 }
 EXPORT_SYMBOL_GPL(icssg_set_pvid);
+
+int emac_fdb_flow_id_updated(struct prueth_emac *emac)
+{
+	struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
+	int slice = prueth_emac_slice(emac);
+	struct mgmt_cmd fdb_cmd = { 0 };
+	int ret;
+
+	fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
+	fdb_cmd.type   = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
+	fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq);
+	fdb_cmd.param  = 0;
+
+	fdb_cmd.param |= (slice << 4);
+	fdb_cmd.cmd_args[0] = 0;
+
+	ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp);
+	if (ret)
+		return ret;
+
+	WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum);
+	return fdb_cmd_rsp.status == 1 ? 0 : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
index 92c2deaa3068..c884e9fa099e 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
@@ -55,6 +55,7 @@ struct icssg_rxq_ctx {
 #define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
 #define ICSSG_FW_MGMT_CMD_TYPE		0x04
 #define ICSSG_FW_MGMT_PKT		0x80000000
+#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW	0x05
 
 struct icssg_r30_cmd {
 	u32 cmd[4];
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index c568c84a032b..c675d3d9c789 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -164,11 +164,11 @@ static struct icssg_firmwares icssg_emac_firmwares[] = {
 	}
 };
 
-static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
+static int prueth_emac_start(struct prueth *prueth, int slice)
 {
 	struct icssg_firmwares *firmwares;
 	struct device *dev = prueth->dev;
-	int slice, ret;
+	int ret;
 
 	if (prueth->is_switch_mode)
 		firmwares = icssg_switch_firmwares;
@@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 	else
 		firmwares = icssg_emac_firmwares;
 
-	slice = prueth_emac_slice(emac);
-	if (slice < 0) {
-		netdev_err(emac->ndev, "invalid port\n");
-		return -EINVAL;
-	}
-
-	ret = icssg_config(prueth, emac, slice);
-	if (ret)
-		return ret;
-
 	ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
 	ret = rproc_boot(prueth->pru[slice]);
 	if (ret) {
@@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 		goto halt_rtu;
 	}
 
-	emac->fw_running = 1;
 	return 0;
 
 halt_rtu:
@@ -220,6 +209,78 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 	return ret;
 }
 
+static int prueth_emac_common_start(struct prueth *prueth)
+{
+	struct prueth_emac *emac;
+	int ret = 0;
+	int slice;
+
+	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
+		return -EINVAL;
+
+	/* clear SMEM and MSMC settings for all slices */
+	memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
+	memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
+
+	icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
+	icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
+
+	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
+		icssg_init_fw_offload_mode(prueth);
+	else
+		icssg_init_emac_mode(prueth);
+
+	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
+		emac = prueth->emac[slice];
+		if (emac) {
+			ret |= icssg_config(prueth, emac, slice);
+			if (ret)
+				return ret;
+		}
+		ret |= prueth_emac_start(prueth, slice);
+	}
+
+	if (ret)
+		return ret;
+	prueth->prus_running = 1;
+
+	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
+	       prueth->emac[ICSS_SLICE1];
+	ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
+			    emac, IEP_DEFAULT_CYCLE_TIME_NS);
+	if (ret)
+		dev_err(prueth->dev, "Failed to initialize IEP module\n");
+
+	return ret;
+}
+
+static int prueth_emac_common_stop(struct prueth *prueth)
+{
+	struct prueth_emac *emac;
+	int slice;
+
+	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
+		return -EINVAL;
+
+	icssg_class_disable(prueth->miig_rt, ICSS_SLICE0);
+	icssg_class_disable(prueth->miig_rt, ICSS_SLICE1);
+
+	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
+		if (prueth->prus_running) {
+			rproc_shutdown(prueth->txpru[slice]);
+			rproc_shutdown(prueth->rtu[slice]);
+			rproc_shutdown(prueth->pru[slice]);
+		}
+	}
+	prueth->prus_running = 0;
+
+	emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] :
+	       prueth->emac[ICSS_SLICE1];
+	icss_iep_exit(emac->iep);
+
+	return 0;
+}
+
 /* called back by PHY layer if there is change in link state of hw port*/
 static void emac_adjust_link(struct net_device *ndev)
 {
@@ -369,12 +430,13 @@ static void prueth_iep_settime(void *clockops_data, u64 ns)
 {
 	struct icssg_setclock_desc __iomem *sc_descp;
 	struct prueth_emac *emac = clockops_data;
+	struct prueth *prueth = emac->prueth;
 	struct icssg_setclock_desc sc_desc;
 	u64 cyclecount;
 	u32 cycletime;
 	int timeout;
 
-	if (!emac->fw_running)
+	if (!prueth->prus_running)
 		return;
 
 	sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET;
@@ -543,23 +605,17 @@ 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;
+	struct icssg_flow_cfg __iomem *flow_cfg;
 	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, false);
 	icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
 
 	/* Notify the stack of the actual queue counts. */
@@ -597,18 +653,23 @@ static int emac_ndo_open(struct net_device *ndev)
 		goto cleanup_napi;
 	}
 
-	/* reset and start PRU firmware */
-	ret = prueth_emac_start(prueth, emac);
-	if (ret)
-		goto free_rx_irq;
+	if (!prueth->emacs_initialized) {
+		ret = prueth_emac_common_start(prueth);
+		if (ret)
+			goto stop;
+	}
 
-	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
+	flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
+	writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
+	ret = emac_fdb_flow_id_updated(emac);
 
-	if (!prueth->emacs_initialized) {
-		ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
-				    emac, IEP_DEFAULT_CYCLE_TIME_NS);
+	if (ret) {
+		netdev_err(ndev, "Failed to update Rx Flow ID %d", ret);
+		goto stop;
 	}
 
+	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
+
 	ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
 				   IRQF_ONESHOT, dev_name(dev), emac);
 	if (ret)
@@ -653,8 +714,7 @@ static int emac_ndo_open(struct net_device *ndev)
 free_tx_ts_irq:
 	free_irq(emac->tx_ts_irq, emac);
 stop:
-	prueth_emac_stop(emac);
-free_rx_irq:
+	prueth_emac_common_stop(prueth);
 	free_irq(emac->rx_chns.irq[rx_flow], emac);
 cleanup_napi:
 	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
@@ -689,8 +749,6 @@ static int emac_ndo_stop(struct net_device *ndev)
 	if (ndev->phydev)
 		phy_stop(ndev->phydev);
 
-	icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
-
 	if (emac->prueth->is_hsr_offload_mode)
 		__dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast);
 	else
@@ -728,11 +786,9 @@ static int emac_ndo_stop(struct net_device *ndev)
 	/* Destroying the queued work in ndo_stop() */
 	cancel_delayed_work_sync(&emac->stats_work);
 
-	if (prueth->emacs_initialized == 1)
-		icss_iep_exit(emac->iep);
-
 	/* stop PRUs */
-	prueth_emac_stop(emac);
+	if (prueth->emacs_initialized == 1)
+		prueth_emac_common_stop(prueth);
 
 	free_irq(emac->tx_ts_irq, emac);
 
@@ -1053,10 +1109,11 @@ static void prueth_offload_fwd_mark_update(struct prueth *prueth)
 	}
 }
 
-static void prueth_emac_restart(struct prueth *prueth)
+static int prueth_emac_restart(struct prueth *prueth)
 {
 	struct prueth_emac *emac0 = prueth->emac[PRUETH_MAC0];
 	struct prueth_emac *emac1 = prueth->emac[PRUETH_MAC1];
+	int ret;
 
 	/* Detach the net_device for both PRUeth ports*/
 	if (netif_running(emac0->ndev))
@@ -1065,36 +1122,46 @@ static void prueth_emac_restart(struct prueth *prueth)
 		netif_device_detach(emac1->ndev);
 
 	/* Disable both PRUeth ports */
-	icssg_set_port_state(emac0, ICSSG_EMAC_PORT_DISABLE);
-	icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
+	ret = icssg_set_port_state(emac0, ICSSG_EMAC_PORT_DISABLE);
+	ret |= icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE);
+	if (ret)
+		return ret;
 
 	/* Stop both pru cores for both PRUeth ports*/
-	prueth_emac_stop(emac0);
-	prueth->emacs_initialized--;
-	prueth_emac_stop(emac1);
-	prueth->emacs_initialized--;
+	ret = prueth_emac_common_stop(prueth);
+	if (ret) {
+		dev_err(prueth->dev, "Failed to stop the firmwares");
+		return ret;
+	}
 
 	/* Start both pru cores for both PRUeth ports */
-	prueth_emac_start(prueth, emac0);
-	prueth->emacs_initialized++;
-	prueth_emac_start(prueth, emac1);
-	prueth->emacs_initialized++;
+	ret = prueth_emac_common_start(prueth);
+	if (ret) {
+		dev_err(prueth->dev, "Failed to start the firmwares");
+		return ret;
+	}
 
 	/* Enable forwarding for both PRUeth ports */
-	icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
-	icssg_set_port_state(emac1, ICSSG_EMAC_PORT_FORWARD);
+	ret = icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD);
+	ret |= icssg_set_port_state(emac1, ICSSG_EMAC_PORT_FORWARD);
 
 	/* Attache net_device for both PRUeth ports */
 	netif_device_attach(emac0->ndev);
 	netif_device_attach(emac1->ndev);
+
+	return ret;
 }
 
 static void icssg_change_mode(struct prueth *prueth)
 {
 	struct prueth_emac *emac;
-	int mac;
+	int mac, ret;
 
-	prueth_emac_restart(prueth);
+	ret = prueth_emac_restart(prueth);
+	if (ret) {
+		dev_err(prueth->dev, "Failed to restart the firmwares, aborting the process");
+		return;
+	}
 
 	for (mac = PRUETH_MAC0; mac < PRUETH_NUM_MACS; mac++) {
 		emac = prueth->emac[mac];
@@ -1173,13 +1240,18 @@ static void prueth_netdevice_port_unlink(struct net_device *ndev)
 {
 	struct prueth_emac *emac = netdev_priv(ndev);
 	struct prueth *prueth = emac->prueth;
+	int ret;
 
 	prueth->br_members &= ~BIT(emac->port_id);
 
 	if (prueth->is_switch_mode) {
 		prueth->is_switch_mode = false;
 		emac->port_vlan = 0;
-		prueth_emac_restart(prueth);
+		ret = prueth_emac_restart(prueth);
+		if (ret) {
+			dev_err(prueth->dev, "Failed to restart the firmwares, aborting the process");
+			return;
+		}
 	}
 
 	prueth_offload_fwd_mark_update(prueth);
@@ -1228,6 +1300,7 @@ static void prueth_hsr_port_unlink(struct net_device *ndev)
 	struct prueth *prueth = emac->prueth;
 	struct prueth_emac *emac0;
 	struct prueth_emac *emac1;
+	int ret;
 
 	emac0 = prueth->emac[PRUETH_MAC0];
 	emac1 = prueth->emac[PRUETH_MAC1];
@@ -1238,7 +1311,11 @@ static void prueth_hsr_port_unlink(struct net_device *ndev)
 		emac0->port_vlan = 0;
 		emac1->port_vlan = 0;
 		prueth->hsr_dev = NULL;
-		prueth_emac_restart(prueth);
+		ret = prueth_emac_restart(prueth);
+		if (ret) {
+			dev_err(prueth->dev, "Failed to restart the firmwares, aborting the process");
+			return;
+		}
 		netdev_dbg(ndev, "Disabling HSR Offload mode\n");
 	}
 }
@@ -1413,13 +1490,10 @@ static int prueth_probe(struct platform_device *pdev)
 		prueth->pa_stats = NULL;
 	}
 
-	if (eth0_node) {
+	if (eth0_node || eth1_node) {
 		ret = prueth_get_cores(prueth, ICSS_SLICE0, false);
 		if (ret)
 			goto put_cores;
-	}
-
-	if (eth1_node) {
 		ret = prueth_get_cores(prueth, ICSS_SLICE1, false);
 		if (ret)
 			goto put_cores;
@@ -1618,14 +1692,12 @@ static int prueth_probe(struct platform_device *pdev)
 	pruss_put(prueth->pruss);
 
 put_cores:
-	if (eth1_node) {
-		prueth_put_cores(prueth, ICSS_SLICE1);
-		of_node_put(eth1_node);
-	}
-
-	if (eth0_node) {
+	if (eth0_node || eth1_node) {
 		prueth_put_cores(prueth, ICSS_SLICE0);
 		of_node_put(eth0_node);
+
+		prueth_put_cores(prueth, ICSS_SLICE1);
+		of_node_put(eth1_node);
 	}
 
 	return ret;
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index f5c1d473e9f9..d917945dad68 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -140,7 +140,6 @@ 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;
 	u8 mac_addr[6];
@@ -257,6 +256,7 @@ struct icssg_firmwares {
  * @is_switchmode_supported: indicates platform support for switch mode
  * @switch_id: ID for mapping switch ports to bridge
  * @default_vlan: Default VLAN for host
+ * @prus_running: flag to indicate if all pru cores are running
  */
 struct prueth {
 	struct device *dev;
@@ -298,6 +298,7 @@ struct prueth {
 	int default_vlan;
 	/** @vtbl_lock: Lock for vtbl in shared memory */
 	spinlock_t vtbl_lock;
+	bool prus_running;
 };
 
 struct emac_tx_ts_response {
@@ -361,6 +362,8 @@ int icssg_set_port_state(struct prueth_emac *emac,
 			 enum icssg_port_state_cmd state);
 void icssg_config_set_speed(struct prueth_emac *emac);
 void icssg_config_half_duplex(struct prueth_emac *emac);
+void icssg_init_emac_mode(struct prueth *prueth);
+void icssg_init_fw_offload_mode(struct prueth *prueth);
 
 /* Buffer queue helpers */
 int icssg_queue_pop(struct prueth *prueth, u8 queue);
@@ -377,6 +380,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
 		       u8 untag_mask, bool add);
 u16 icssg_get_pvid(struct prueth_emac *emac);
 void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port);
+int emac_fdb_flow_id_updated(struct prueth_emac *emac);
 #define prueth_napi_to_tx_chn(pnapi) \
 	container_of(pnapi, struct prueth_tx_chn, napi_tx)
 
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c
index 5024f0647a0d..a95b0150341a 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c
@@ -440,7 +440,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 		goto halt_pru;
 	}
 
-	emac->fw_running = 1;
 	return 0;
 
 halt_pru:
-- 
2.25.1



From m-malladi at ti.com  Wed Dec 11 05:59:41 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Wed, 11 Dec 2024 19:29:41 +0530
Subject: [PATCH net v4 2/2] net: ti: icssg-prueth: Fix clearing of IEP_CMP_CFG registers during iep_init
In-Reply-To: <20241211135941.1800240-1-m-malladi@ti.com>
References: <20241211135941.1800240-1-m-malladi@ti.com>
Message-ID: <20241211135941.1800240-3-m-malladi@ti.com>

When ICSSG interfaces are brought down and brought up again, the
pru cores are shut down and booted again, flushing out all the memories
and start again in a clean state. Hence it is expected that the
IEP_CMP_CFG register needs to be flushed during iep_init() to ensure
that the existing residual configuration doesn't cause any unusual
behavior. If the register is not cleared, existing IEP_CMP_CFG set for
CMP1 will result in SYNC0_OUT signal based on the SYNC_OUT register values.

After bringing the interface up, calling PPS enable doesn't work as
the driver believes PPS is already enabled, (iep->pps_enabled is not
cleared during interface bring down) and driver will just return true
even though there is no signal. Fix this by disabling pps and perout.

Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver")
Signed-off-by: Meghana Malladi <m-malladi at ti.com>
Reviewed-by: Roger Quadros <rogerq at kernel.org>
---

Hi all,

This patch is based on net-next tagged next-20241205
v3: https://lore.kernel.org/all/20241205082831.777868-3-m-malladi at ti.com/

* Changes since v2 (v4-v2):
- Collected Reviewed-by tag from Roger Quadros <rogerq at kernel.org>

 drivers/net/ethernet/ti/icssg/icss_iep.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c
index 5d6d1cf78e93..a96861debbe3 100644
--- a/drivers/net/ethernet/ti/icssg/icss_iep.c
+++ b/drivers/net/ethernet/ti/icssg/icss_iep.c
@@ -215,6 +215,10 @@ static void icss_iep_enable_shadow_mode(struct icss_iep *iep)
 	for (cmp = IEP_MIN_CMP; cmp < IEP_MAX_CMP; cmp++) {
 		regmap_update_bits(iep->map, ICSS_IEP_CMP_STAT_REG,
 				   IEP_CMP_STATUS(cmp), IEP_CMP_STATUS(cmp));
+
+		regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
+				   IEP_CMP_CFG_CMP_EN(cmp), 0);
+
 	}
 
 	/* enable reset counter on CMP0 event */
@@ -780,6 +784,11 @@ int icss_iep_exit(struct icss_iep *iep)
 	}
 	icss_iep_disable(iep);
 
+	if (iep->pps_enabled)
+		icss_iep_pps_enable(iep, false);
+	else if (iep->perout_enabled)
+		icss_iep_perout_enable(iep, NULL, false);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(icss_iep_exit);
-- 
2.25.1



From bigeasy at linutronix.de  Wed Dec 11 06:04:02 2024
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Wed, 11 Dec 2024 15:04:02 +0100
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <20241211134811.wM_UADhQ@linutronix.de>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-3-arnd@kernel.org>
 <20241211134811.wM_UADhQ@linutronix.de>
Message-ID: <20241211140402.yf7gMExr@linutronix.de>

On 2024-12-11 14:48:11 [+0100], To Arnd Bergmann wrote:
> I guess if you have boxes with 4GiB+ and can proof that the performance
> improves without HIGHPTE (since you don't have to map the page table).
> The question is then how much of low mem has to be used instead and when
> does it start to hurt.

Some numbers have been been documented in commit
   14315592009c1 ("x86, mm: Allow highmem user page tables to be disabled at boot time")

and I would like cite:
| We could probably handwave up an argument for a threshold at 16G of total
| RAM.

which means HIGHPTE would make sense with >= 16GiB of memory.

Sebastian


From michal.simek at amd.com  Wed Dec 11 06:04:28 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 15:04:28 +0100
Subject: [PATCH 07/15] ARM: zynq: Add ethernet phy reset information to
 DT(zc702)
In-Reply-To: <8395fb6b-d7a5-4e2c-9eb3-4984b8c775c4@lunn.ch>
References: <cover.1733920873.git.michal.simek@amd.com>
 <9e18d59ca339804320d2a5e3c7362aefa3bb7c99.1733920873.git.michal.simek@amd.com>
 <8395fb6b-d7a5-4e2c-9eb3-4984b8c775c4@lunn.ch>
Message-ID: <344eb4b3-1073-4c65-a8ba-fee943776627@amd.com>

Hi Andrew,

On 12/11/24 14:45, Andrew Lunn wrote:
> On Wed, Dec 11, 2024 at 01:41:26PM +0100, Michal Simek wrote:
>> Added phy reset gpio information for gem0.
>>
>> Signed-off-by: Michal Simek <michal.simek at amd.com>
>> ---
>>
>>   arch/arm/boot/dts/xilinx/zynq-zc702.dts | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
>> index 424e78f6c148..975385f4ac01 100644
>> --- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
>> +++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
>> @@ -79,6 +79,8 @@ &gem0 {
>>   	phy-handle = <&ethernet_phy>;
>>   	pinctrl-names = "default";
>>   	pinctrl-0 = <&pinctrl_gem0_default>;
>> +	phy-reset-gpio = <&gpio0 11 0>;
>> +	phy-reset-active-low;
> 
> Hi Michal
> 
> Could you point me at code which actually implements these two
> properties.

I have tracked it down and it was only used from 2016 to 2018 in Xilinx 
downstream Linux repository. After that it was removed.

If you are interested
https://gitenterprise.xilinx.com/Linux/linux-xlnx/commit/6f43a25c416e532530eaed897acff6f5249907e4

> 
> What is more normal is a reset-gpios property in the PHY node, or a
> reset-gpios in the MDIO node.

Thanks for review. This patch should be dropped from this series.

Thanks,
Michal


From mark.rutland at arm.com  Wed Dec 11 06:07:02 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 11 Dec 2024 14:07:02 +0000
Subject: [PATCH 0/2] arm64: stacktrace: Fixes
Message-ID: <20241211140704.2498712-1-mark.rutland@arm.com>

These patches fix a couple of issues in the arm64 stacktrace code. Both
address some fallout from the recent changes to unwinding across
exception boundaries, though the issue in the second patch has been
latent in the code for a while.

The first patch was previously posted independently at:

  https://lore.kernel.org/linux-arm-kernel/20241209110351.1876804-1-mark.rutland at arm.com/

... the version here has a better commit message, but is otherwise
unchanged.

The patches are based on v6.13-rc2, and I've given them some light
functional testing (booting them and running the test cases in the
commit messages).

Mark.

Mark Rutland (2):
  arm64: stacktrace: Skip reporting LR at exception boundaries
  arm64: stacktrace: Don't WARN when unwinding other tasks

 arch/arm64/kernel/stacktrace.c | 32 +++++++-------------------------
 1 file changed, 7 insertions(+), 25 deletions(-)

-- 
2.30.2



From mark.rutland at arm.com  Wed Dec 11 06:07:03 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 11 Dec 2024 14:07:03 +0000
Subject: [PATCH 1/2] arm64: stacktrace: Skip reporting LR at exception boundaries
In-Reply-To: <20241211140704.2498712-1-mark.rutland@arm.com>
References: <20241211140704.2498712-1-mark.rutland@arm.com>
Message-ID: <20241211140704.2498712-2-mark.rutland@arm.com>

Aishwarya reports that warnings are sometimes seen when running the
ftrace kselftests, e.g.

| WARNING: CPU: 5 PID: 2066 at arch/arm64/kernel/stacktrace.c:141 arch_stack_walk+0x4a0/0x4c0
| Modules linked in:
| CPU: 5 UID: 0 PID: 2066 Comm: ftracetest Not tainted 6.13.0-rc2 #2
| Hardware name: linux,dummy-virt (DT)
| pstate: 604000c5 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
| pc : arch_stack_walk+0x4a0/0x4c0
| lr : arch_stack_walk+0x248/0x4c0
| sp : ffff800083643d20
| x29: ffff800083643dd0 x28: ffff00007b891400 x27: ffff00007b891928
| x26: 0000000000000001 x25: 00000000000000c0 x24: ffff800082f39d80
| x23: ffff80008003ee8c x22: ffff80008004baa8 x21: ffff8000800533e0
| x20: ffff800083643e10 x19: ffff80008003eec8 x18: 0000000000000000
| x17: 0000000000000000 x16: ffff800083640000 x15: 0000000000000000
| x14: 02a37a802bbb8a92 x13: 00000000000001a9 x12: 0000000000000001
| x11: ffff800082ffad60 x10: ffff800083643d20 x9 : ffff80008003eed0
| x8 : ffff80008004baa8 x7 : ffff800086f2be80 x6 : ffff0000057cf000
| x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff800086f2b690
| x2 : ffff80008004baa8 x1 : ffff80008004baa8 x0 : ffff80008004baa8
| Call trace:
|  arch_stack_walk+0x4a0/0x4c0 (P)
|  arch_stack_walk+0x248/0x4c0 (L)
|  profile_pc+0x44/0x80
|  profile_tick+0x50/0x80 (F)
|  tick_nohz_handler+0xcc/0x160 (F)
|  __hrtimer_run_queues+0x2ac/0x340 (F)
|  hrtimer_interrupt+0xf4/0x268 (F)
|  arch_timer_handler_virt+0x34/0x60 (F)
|  handle_percpu_devid_irq+0x88/0x220 (F)
|  generic_handle_domain_irq+0x34/0x60 (F)
|  gic_handle_irq+0x54/0x140 (F)
|  call_on_irq_stack+0x24/0x58 (F)
|  do_interrupt_handler+0x88/0x98
|  el1_interrupt+0x34/0x68 (F)
|  el1h_64_irq_handler+0x18/0x28
|  el1h_64_irq+0x6c/0x70
|  queued_spin_lock_slowpath+0x78/0x460 (P)

The warning in question is:

  WARN_ON_ONCE(state->common.pc == orig_pc))

... in kunwind_recover_return_address(), which is triggered when
return_to_handler() is encountered in the trace, but
ftrace_graph_ret_addr() cannot find a corresponding original return
address on the fgraph return stack.

This happens because the stacktrace code encounters an exception
boundary where the LR was not live at the time of the exception, but the
LR happens to contain return_to_handler(); either because the task
recently returned there, or due to unfortunate usage of the LR at a
scratch register. In such cases attempts to recover the return address
via ftrace_graph_ret_addr() may fail, triggering the WARN_ON_ONCE()
above and aborting the unwind (hence the stacktrace terminating after
reporting the PC at the time of the exception).

Handling unreliable LR values in these cases is likely to require some
larger rework, so for the moment avoid this problem by restoring the old
behaviour of skipping the LR at exception boundaries, which the
stacktrace code did prior to commit:

  c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")

This commit is effectively a partial revert, keeping the structures and
logic to explicitly identify exception boundaries while still skipping
reporting of the LR. The logic to explicitly identify exception
boundaries is still useful for general robustness and as a building
block for future support for RELIABLE_STACKTRACE.

Fixes: c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reported-by: Aishwarya TCV <aishwarya.tcv at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/stacktrace.c | 24 ++----------------------
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index caef85462acb6..4a08ad8158380 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -26,7 +26,6 @@ enum kunwind_source {
 	KUNWIND_SOURCE_CALLER,
 	KUNWIND_SOURCE_TASK,
 	KUNWIND_SOURCE_REGS_PC,
-	KUNWIND_SOURCE_REGS_LR,
 };
 
 union unwind_flags {
@@ -178,23 +177,8 @@ int kunwind_next_regs_pc(struct kunwind_state *state)
 	state->regs = regs;
 	state->common.pc = regs->pc;
 	state->common.fp = regs->regs[29];
-	state->source = KUNWIND_SOURCE_REGS_PC;
-	return 0;
-}
-
-static __always_inline int
-kunwind_next_regs_lr(struct kunwind_state *state)
-{
-	/*
-	 * The stack for the regs was consumed by kunwind_next_regs_pc(), so we
-	 * cannot consume that again here, but we know the regs are safe to
-	 * access.
-	 */
-	state->common.pc = state->regs->regs[30];
-	state->common.fp = state->regs->regs[29];
 	state->regs = NULL;
-	state->source = KUNWIND_SOURCE_REGS_LR;
-
+	state->source = KUNWIND_SOURCE_REGS_PC;
 	return 0;
 }
 
@@ -274,11 +258,8 @@ kunwind_next(struct kunwind_state *state)
 	case KUNWIND_SOURCE_FRAME:
 	case KUNWIND_SOURCE_CALLER:
 	case KUNWIND_SOURCE_TASK:
-	case KUNWIND_SOURCE_REGS_LR:
-		err = kunwind_next_frame_record(state);
-		break;
 	case KUNWIND_SOURCE_REGS_PC:
-		err = kunwind_next_regs_lr(state);
+		err = kunwind_next_frame_record(state);
 		break;
 	default:
 		err = -EINVAL;
@@ -436,7 +417,6 @@ static const char *state_source_string(const struct kunwind_state *state)
 	case KUNWIND_SOURCE_CALLER:	return "C";
 	case KUNWIND_SOURCE_TASK:	return "T";
 	case KUNWIND_SOURCE_REGS_PC:	return "P";
-	case KUNWIND_SOURCE_REGS_LR:	return "L";
 	default:			return "U";
 	}
 }
-- 
2.30.2



From mark.rutland at arm.com  Wed Dec 11 06:07:04 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 11 Dec 2024 14:07:04 +0000
Subject: [PATCH 2/2] arm64: stacktrace: Don't WARN when unwinding other tasks
In-Reply-To: <20241211140704.2498712-1-mark.rutland@arm.com>
References: <20241211140704.2498712-1-mark.rutland@arm.com>
Message-ID: <20241211140704.2498712-3-mark.rutland@arm.com>

The arm64 stacktrace code has a few error conditions where a
WARN_ON_ONCE() is triggered before the stacktrace is terminated and an
error is returned to the caller. The conditions shouldn't be triggered
when unwinding the current task, but it is possible to trigger these
when unwinding another task which is not blocked, as the stack of that
task is concurrently modified. Kent reports that these warnings can be
triggered while running filesystem tests on bcachefs, which calls the
stacktrace code directly.

To produce a meaningful stacktrace of another task, the task in question
should be blocked, but the stacktrace code is expected to be robust to
cases where it is not blocked. Note that this is purely about not
unuduly scaring the user and/or crashing the kernel; stacktraces in such
cases are meaningless and may leak kernel secrets from the stack of the
task being unwound.

Ideally we'd pin the task in a blocked state during the unwind, as we do
for /proc/${PID}/wchan since commit:

  42a20f86dc19f928 ("sched: Add wrapper for get_wchan() to keep task blocked")

... but a bunch of places don't do that, notably /proc/${PID}/stack,
where we don't pin the task in a blocked state, but do restrict the
output to privileged users since commit:

  f8a00cef17206ecd ("proc: restrict kernel stack dumps to root")

... and so it's possible to trigger these warnings accidentally, e.g. by
reading /proc/*/stack (as root):

| for n in $(seq 1 10); do
|     while true; do cat /proc/*/stack > /dev/null 2>&1; done &
| done
| ------------[ cut here ]------------
| WARNING: CPU: 3 PID: 166 at arch/arm64/kernel/stacktrace.c:207 arch_stack_walk+0x1c8/0x370
| Modules linked in:
| CPU: 3 UID: 0 PID: 166 Comm: cat Not tainted 6.13.0-rc2-00003-g3dafa7a7925d #2
| Hardware name: linux,dummy-virt (DT)
| pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
| pc : arch_stack_walk+0x1c8/0x370
| lr : arch_stack_walk+0x1b0/0x370
| sp : ffff800080773890
| x29: ffff800080773930 x28: fff0000005c44500 x27: fff00000058fa038
| x26: 000000007ffff000 x25: 0000000000000000 x24: 0000000000000000
| x23: ffffa35a8d9600ec x22: 0000000000000000 x21: fff00000043a33c0
| x20: ffff800080773970 x19: ffffa35a8d960168 x18: 0000000000000000
| x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
| x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
| x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
| x8 : ffff8000807738e0 x7 : ffff8000806e3800 x6 : ffff8000806e3818
| x5 : ffff800080773920 x4 : ffff8000806e4000 x3 : ffff8000807738e0
| x2 : 0000000000000018 x1 : ffff8000806e3800 x0 : 0000000000000000
| Call trace:
|  arch_stack_walk+0x1c8/0x370 (P)
|  stack_trace_save_tsk+0x8c/0x108
|  proc_pid_stack+0xb0/0x134
|  proc_single_show+0x60/0x120
|  seq_read_iter+0x104/0x438
|  seq_read+0xf8/0x140
|  vfs_read+0xc4/0x31c
|  ksys_read+0x70/0x108
|  __arm64_sys_read+0x1c/0x28
|  invoke_syscall+0x48/0x104
|  el0_svc_common.constprop.0+0x40/0xe0
|  do_el0_svc+0x1c/0x28
|  el0_svc+0x30/0xcc
|  el0t_64_sync_handler+0x10c/0x138
|  el0t_64_sync+0x198/0x19c
| ---[ end trace 0000000000000000 ]---

Fix this by only warning when unwinding the current task. When unwinding
another task the error conditions will be handled by returning an error
without producing a warning.

The two warnings in kunwind_next_frame_record_meta() were added recently
as part of commit:

  c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")

The warning when recovering the fgraph return address has changed form
many times, but was originally introduced back in commit:

  9f416319f40cd857 ("arm64: fix unwind_frame() for filtered out fn for function graph tracing")

Fixes: c2c6b27b5aa14fa2 ("arm64: stacktrace: unwind exception boundaries")
Fixes: 9f416319f40cd857 ("arm64: fix unwind_frame() for filtered out fn for function graph tracing")
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reported-by: Kent Overstreet <kent.overstreet at linux.dev>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Kees Cook <keescook at chromium.org>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/stacktrace.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 4a08ad8158380..1d9d51d7627fd 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -137,8 +137,10 @@ kunwind_recover_return_address(struct kunwind_state *state)
 		orig_pc = ftrace_graph_ret_addr(state->task, &state->graph_idx,
 						state->common.pc,
 						(void *)state->common.fp);
-		if (WARN_ON_ONCE(state->common.pc == orig_pc))
+		if (state->common.pc == orig_pc) {
+			WARN_ON_ONCE(state->task == current);
 			return -EINVAL;
+		}
 		state->common.pc = orig_pc;
 		state->flags.fgraph = 1;
 	}
@@ -199,12 +201,12 @@ kunwind_next_frame_record_meta(struct kunwind_state *state)
 	case FRAME_META_TYPE_FINAL:
 		if (meta == &task_pt_regs(tsk)->stackframe)
 			return -ENOENT;
-		WARN_ON_ONCE(1);
+		WARN_ON_ONCE(tsk == current);
 		return -EINVAL;
 	case FRAME_META_TYPE_PT_REGS:
 		return kunwind_next_regs_pc(state);
 	default:
-		WARN_ON_ONCE(1);
+		WARN_ON_ONCE(tsk == current);
 		return -EINVAL;
 	}
 }
-- 
2.30.2



From michal.simek at amd.com  Wed Dec 11 06:14:06 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 15:14:06 +0100
Subject: [PATCH] mailbox: zynqmp: setup IPI for each valid child node
In-Reply-To: <20241112170612.2577383-1-tanmay.shah@amd.com>
References: <20241112170612.2577383-1-tanmay.shah@amd.com>
Message-ID: <66ba0a5b-dba5-4162-b83f-2058b0dce3f8@amd.com>



On 11/12/24 18:06, Tanmay Shah wrote:
> As per zynqmp-ipi bindings, zynqmp IPI node can have multiple child nodes.
> Current IPI setup function is set only for first child node. If IPI node
> has multiple child nodes in the device-tree, then IPI setup fails for
> child nodes other than first child node. In such case kernel will crash.
> Fix this crash by registering IPI setup function for each available child
> node.
> 
> Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
> ---
>   drivers/mailbox/zynqmp-ipi-mailbox.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
> index 521d08b9ab47..815e0492f029 100644
> --- a/drivers/mailbox/zynqmp-ipi-mailbox.c
> +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
> @@ -940,10 +940,10 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
>   	pdata->num_mboxes = num_mboxes;
>   
>   	mbox = pdata->ipi_mboxes;
> -	mbox->setup_ipi_fn = ipi_fn;
> -
>   	for_each_available_child_of_node(np, nc) {
>   		mbox->pdata = pdata;
> +		mbox->setup_ipi_fn = ipi_fn;
> +
>   		ret = zynqmp_ipi_mbox_probe(mbox, nc);
>   		if (ret) {
>   			of_node_put(nc);
> 
> base-commit: 28955f4fa2823e39f1ecfb3a37a364563527afbc

I think you should add Fixed tag and also cc stable at kernel.org

With that fixed feel free to add
Reviewed-by: Michal Simek <michal.simek at amd.com>

Thanks,
Michal


From andrew at lunn.ch  Wed Dec 11 06:21:41 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 11 Dec 2024 15:21:41 +0100
Subject: [PATCH 07/15] ARM: zynq: Add ethernet phy reset information to
 DT(zc702)
In-Reply-To: <344eb4b3-1073-4c65-a8ba-fee943776627@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
 <9e18d59ca339804320d2a5e3c7362aefa3bb7c99.1733920873.git.michal.simek@amd.com>
 <8395fb6b-d7a5-4e2c-9eb3-4984b8c775c4@lunn.ch>
 <344eb4b3-1073-4c65-a8ba-fee943776627@amd.com>
Message-ID: <897ab5eb-a210-41d6-bfef-a60ab74f5943@lunn.ch>

On Wed, Dec 11, 2024 at 03:04:28PM +0100, Michal Simek wrote:
> Hi Andrew,
> 
> On 12/11/24 14:45, Andrew Lunn wrote:
> > On Wed, Dec 11, 2024 at 01:41:26PM +0100, Michal Simek wrote:
> > > Added phy reset gpio information for gem0.
> > > 
> > > Signed-off-by: Michal Simek <michal.simek at amd.com>
> > > ---
> > > 
> > >   arch/arm/boot/dts/xilinx/zynq-zc702.dts | 2 ++
> > >   1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
> > > index 424e78f6c148..975385f4ac01 100644
> > > --- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
> > > +++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
> > > @@ -79,6 +79,8 @@ &gem0 {
> > >   	phy-handle = <&ethernet_phy>;
> > >   	pinctrl-names = "default";
> > >   	pinctrl-0 = <&pinctrl_gem0_default>;
> > > +	phy-reset-gpio = <&gpio0 11 0>;
> > > +	phy-reset-active-low;
> > 
> > Hi Michal
> > 
> > Could you point me at code which actually implements these two
> > properties.
> 
> I have tracked it down and it was only used from 2016 to 2018 in Xilinx
> downstream Linux repository. After that it was removed.

O.K. So when you ran the DT lint tools to validate these DT changes,
why did it not give errors pointing this out?

I wounder how many other such errors there are in this patchset?

	Andrew


From broonie at kernel.org  Wed Dec 11 06:22:28 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 14:22:28 +0000
Subject: [PATCH v2] kselftest/arm64: abi: fix SVCR detection
In-Reply-To: <20241211111639.12344-1-o451686892@gmail.com>
References: <20241211111639.12344-1-o451686892@gmail.com>
Message-ID: <804c336a-30c7-4d4c-b8dd-24912de39808@sirena.org.uk>

On Wed, Dec 11, 2024 at 07:16:39PM +0800, Weizhao Ouyang wrote:
> When using svcr_in to check ZA and Streaming Mode, we should make sure
> that the value in x2 is correct, otherwise it may trigger an Illegal
> instruction if FEAT_SVE and !FEAT_SME.

Reviewed-by: Mark Brown <broonie at kernel.org>

Thanks for spotting 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/20241211/d34a3100/attachment.sig>

From srinivas.pandruvada at linux.intel.com  Wed Dec 11 06:23:40 2024
From: srinivas.pandruvada at linux.intel.com (srinivas pandruvada)
Date: Wed, 11 Dec 2024 06:23:40 -0800
Subject: [PATCH v9 1/9] HID: hid-sensor-hub: don't use stale
 platform-data on remove
In-Reply-To: <n914pn7o-pr9n-5ss0-p744-73402nnn843p@xreary.bet>
References: <20241107114712.538976-1-heiko@sntech.de>
	 <20241107114712.538976-2-heiko@sntech.de>
	 <nycvar.YFH.7.76.2411071358210.20286@cbobk.fhfr.pm>
	 <4934964.GXAFRqVoOG@diego>
	 <nycvar.YFH.7.76.2411071534110.20286@cbobk.fhfr.pm>
	 <20241112143732.GG8552@google.com> <20241211120844.GD7139@google.com>
	 <n914pn7o-pr9n-5ss0-p744-73402nnn843p@xreary.bet>
Message-ID: <8d736607552e88f28672ef5217431f61951df126.camel@linux.intel.com>

On Wed, 2024-12-11 at 13:24 +0100, Jiri Kosina wrote:
> On Wed, 11 Dec 2024, Lee Jones wrote:
> 
> > > > > This change was more or less a surprise find, because I
> > > > > wanted to make
> > > > > the platform_data pointer in the mfd_cell struct const and
> > > > > this the hid
> > > > > sensor hub stood out as doing something strange ;-) .
> > > > > 
> > > > > So patch 2 of this series actually depends on this change to
> > > > > not cause
> > > > > build errors.
> > > > 
> > > > Ah, right.
> > > > 
> > > > > But seeing that we're after -rc6 alredy, I would assume the
> > > > > brunt of the 
> > > > > mcu series might need to wait after 6.13-rc1 anyway - but I
> > > > > guess that 
> > > > > depends on how Lee sees things ;-) .
> > > > 
> > > > OK, I am keeping my hands off it for the time being.
> > > 
> > > I can take it now with an Ack.
> > 
> > Looking to apply this set now.
> > 
> > Ack please.
> 
> I'd preferer if Srinivas could ack this as the more specific
> maintainer. 
> Srinivas, please? 
My ACK is already in the patch:

Fixes: e651a1da442a ("HID: hid-sensor-hub: Allow parallel synchronous
reads")
Cc: stable at vger.kernel.org
Acked-by: Benjamin Tissoires <bentiss at kernel.org>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>


Thanks,
Srinivas

> 
> Thanks,
> 



From bigeasy at linutronix.de  Wed Dec 11 06:25:17 2024
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Wed, 11 Dec 2024 15:25:17 +0100
Subject: [PATCH 3/4] ARM: drop CONFIG_HIGHPTE support
In-Reply-To: <20241210160556.2341497-4-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-4-arnd@kernel.org>
Message-ID: <20241211142517.fhnOz46I@linutronix.de>

On 2024-12-10 17:05:55 [+0100], Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> CONFIG_HIGHPTE was added in linux-2.6.32, a few years before 64-bit
> support. At the time it made sense, as the CONFIG_ARM_LPAE option allowed
> systems with 16GB of memory that made lowmem a particularly scarce
> resource, and the HIGHPTE implementation gave feature parity with 32-bit
> x86 and frv machines.
> 
> Since Arm is the last architecture remaining that uses this, and almost
> no 32-bit machines support more than 4GB of RAM, the cost of continuing
> to maintain HIGHPTE seems unjustified, so remove it here to allow
> simplifying the generic page table handling.
> 
> Link: https://lore.kernel.org/lkml/20241204103042.1904639-8-arnd at kernel.org/T/#u
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---
> I sent a patch to drop HIGHPTE support on x86 today, see
> https://lore.kernel.org/lkml/20241210144945.2325330-9-arnd at kernel.org/T/#u
> 
> If that one gets merged, we can merge this one instead of the one
> that makes HIGHPTE depend on !PREEMPT_RT, but if we decide against
> the x86 change, then we probably don't want this one either.

Based on what I have written in 20241211140402.yf7gMExr at linutronix.de it
makes sense.

Acked-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

Sebastian


From bigeasy at linutronix.de  Wed Dec 11 06:29:43 2024
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Wed, 11 Dec 2024 15:29:43 +0100
Subject: [PATCH 4/4] mm: drop HIGHPTE support altogether
In-Reply-To: <20241210160556.2341497-5-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-5-arnd@kernel.org>
Message-ID: <20241211142943.cp0Wcuxk@linutronix.de>

On 2024-12-10 17:05:56 [+0100], Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> With both x86 and arm having dropped CONFIG_HIGHPTE support, no
> architecture is left using it, so remove the remnants in common code.
> 
> It is likely that further cleanups are possible in the page table
> code but those are not obvious from the config options.
> 
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Acked-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

Sebastian


From arnd at arndb.de  Wed Dec 11 06:30:22 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 11 Dec 2024 15:30:22 +0100
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <20241211140402.yf7gMExr@linutronix.de>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-3-arnd@kernel.org>
 <20241211134811.wM_UADhQ@linutronix.de>
 <20241211140402.yf7gMExr@linutronix.de>
Message-ID: <001c1d0e-a0fd-47f4-be35-0fd808f3b01a@app.fastmail.com>

On Wed, Dec 11, 2024, at 15:04, Sebastian Andrzej Siewior wrote:
> On 2024-12-11 14:48:11 [+0100], To Arnd Bergmann wrote:
>> I guess if you have boxes with 4GiB+ and can proof that the performance
>> improves without HIGHPTE (since you don't have to map the page table).
>> The question is then how much of low mem has to be used instead and when
>> does it start to hurt.
>
> Some numbers have been been documented in commit
>    14315592009c1 ("x86, mm: Allow highmem user page tables to be 
> disabled at boot time")
>
> and I would like cite:
> | We could probably handwave up an argument for a threshold at 16G of total
> | RAM.
>
> which means HIGHPTE would make sense with >= 16GiB of memory.

Very useful, thanks!

On x86, that means we can definitely remove HIGHPTE along with
CONFIG_HIGHMEM64G on x86.

On 32-bit ARM, we still need to support LPAE for systems that
require 64-bit addressing. LPAE supports 36 bits of addressing
(up to 64GB), but the largest actual size I've seen mentioned
is 16GB (Hisilicon HiP04, Calxeda Midway servers) and I'm
certain nobody actually requires these to perform well
given that they are no longer useful for the workloads they
were designed for.

There are also a small number of embedded systems with 8GB
(Ti Keystone2, NVidia Tegra3, Marvell Armada XP), but they
are rare enough that turning off HIGHPTE is completely safe.

      Arnd


From linus.walleij at linaro.org  Wed Dec 11 06:31:26 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Dec 2024 15:31:26 +0100
Subject: [PATCH 3/4] ARM: drop CONFIG_HIGHPTE support
In-Reply-To: <Z1mYufbtXpeEwTAq@shell.armlinux.org.uk>
References: <20241210160556.2341497-1-arnd@kernel.org> <20241210160556.2341497-4-arnd@kernel.org>
 <CACRpkdZoRbJ4DwRpZQMKbEAvzg4AAdp4B+94SFLm1ssiQmjUwQ@mail.gmail.com> <Z1mYufbtXpeEwTAq@shell.armlinux.org.uk>
Message-ID: <CACRpkdb0g4zGQ-xu3yW=rRmz0zOVYnr-c-KaTSr155YvbrAv8A@mail.gmail.com>

On Wed, Dec 11, 2024 at 2:51?PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:
> On Wed, Dec 11, 2024 at 02:32:51PM +0100, Linus Walleij wrote:
> > On Tue, Dec 10, 2024 at 5:06?PM Arnd Bergmann <arnd at kernel.org> wrote:
> >
> > > From: Arnd Bergmann <arnd at arndb.de>
> > >
> > > CONFIG_HIGHPTE was added in linux-2.6.32, a few years before 64-bit
> > > support. At the time it made sense, as the CONFIG_ARM_LPAE option allowed
> > > systems with 16GB of memory that made lowmem a particularly scarce
> > > resource, and the HIGHPTE implementation gave feature parity with 32-bit
> > > x86 and frv machines.
> > >
> > > Since Arm is the last architecture remaining that uses this, and almost
> > > no 32-bit machines support more than 4GB of RAM, the cost of continuing
> > > to maintain HIGHPTE seems unjustified, so remove it here to allow
> > > simplifying the generic page table handling.
> > >
> > > Link: https://lore.kernel.org/lkml/20241204103042.1904639-8-arnd at kernel.org/T/#u
> > > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> >
> > I'm in favor of this if the x86 patch goes in. We need to get rid
> > of highmem anyway and this will need to happen sooner or later
> > either way.
>
> Well... I use highmem routinely.

Oh I don't mean we should get rid of it without any replacement. Certainly
systems with big physical memories need to be usable.

I am pursuing two ideas (inspired by Arnd and MM people):

1. The easy option - "densemem", on systems with a "hole" in the physical
    memory making the 1:1 linear phys-to-virt map run out too soon and
    overconsume virual memory, actually collect the physical memory on low
    virtual addresses by elaborate phys-to-virt virt-to-phys and page
    numbering that isn't 1:1.

2. The hard option - 4G-by-4G splitting, making the kernel and userspace
    virtual memory spaces separate as it is in hardware on S/390, so the
    kernel can use a while 4G of memory for its needs. I banged my head
    against this a fair amount of time, so I might be incompetent to do it,
    but I still try.

Yours,
Linus Walleij


From d-gole at ti.com  Wed Dec 11 06:34:28 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Wed, 11 Dec 2024 20:04:28 +0530
Subject: Fwd: ARM64: CPUIdle driver is not select any Idle state other
 then WFI
In-Reply-To: <20241211121825.GA2054801@bogus>
References: <CAO6a-9_aPLCx2CqecQBGbK78_=+-tT44RepPkrBjpkWSvjj4Tg@mail.gmail.com>
 <CAO6a-98cdSvyd7jgAyGNmsC2nxmRSyr3GppxvZU9yHU1xqwz3g@mail.gmail.com>
 <20241211055052.gbxnyqpui3t3zpw5@lcpd911>
 <20241211121825.GA2054801@bogus>
Message-ID: <20241211143428.kaoovhiwar74dy6x@lcpd911>

On Dec 11, 2024 at 12:18:25 +0000, Sudeep Holla wrote:
> On Wed, Dec 11, 2024 at 11:20:52AM +0530, Dhruva Gole wrote:
[...]
> > >
> > >
> > > Hi @all,
> > >
> > > I am working on one custom SoC. Where I add one CPUIdle state for
> > > ``arm,cortex-a55`` processor.
> >
> > Any further luck on this?
> >
> > I have also been working on something similar[1] but on an A53 core on
> > TI-K3 AM62x processor.
> 
> Does upstream DTS have support for this platform to understand it better ?
> Even reference to any complete DT file for the platform will help.

Yes, you can ref to the AM625 (CPU layout) DT here:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/ti/k3-am625.dtsi

The board/starter kit DT is:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/ti/k3-am625-sk.dts

The patches for idle state are not upstream, and only exist in this
patch of mine here:
https://github.com/DhruvaG2000/v-linux/commit/0fd088d624276a2e72b8dc6660d261ab6d194f4b

[...]
> > See this chunk in the kernel cpuidle driver:
> > 	if (broadcast && tick_broadcast_enter()) {
> >
> > When I dug deeper into tick_broadcast_enter it always returns something
> > non zero and hence in my case it was entering the if block and tried to
> > find a deepest state. Then the deepest state would always return WFI and
> > not the idle-state I had added.
> >
> > What we found out was on our kernel we end up using
> >
> > kernel/time/tick-broadcast-hrtimer.c
> >
> > This always seems to be keeping atleast 1 CPU busy and prevents idle.
> > If we remove the local-timer-stop it was helping us, but we still need
> > to dig into the full impact of what that entails and I am still
> > interested in finding out how so many other users of similar idle-state
> > implementation are able to do so without trouble.
> >
> 
> Interesting. So if the platform is functional removing local-timer-stop,
> I am bit confused. Either there is something else that is getting it out

Yes it was interesting to us too, as to how the RCU didn't kick in and
system continued to function as though nothing was wrong.

> from the idle state so, it should be fine and it could be just some

It's probably UART keypresses or some userspace processes that get
scheduled that bring the CPUs back out of TF-A's cpu_standby.
Is it possible that EL1 interrupts can bring EL3 out of WFI? Is yes then
it explains the behaviour. The arch timer could also be continuing to
tick and bringing the CPUs out of ATF WFI.

> misconfiguration.
> 
> > Arm64 recommends to use arch_timer instead of external timers. Once we
> > enter el3, timer interrupts to el1 is blocked and hence it's equivalent
> > to local-timer-stop, so it does make sense to keep this property, but
> > then how are others able to enter idle-states for all plugged CPUs at
> > the same time?
> >
> 
> Some systems have system timer that can take over as broadcast timer when
> CPUs enter deeper idle states where the local timers are stopped.

In CPUIdle we're not really clock gating anything so the timer does keep
ticking. So in this particular case it might make sense to remove the
local-timer-stop property from the idle-state.

However we're looking into taking this further and putting interconnect
and few other PLLs in bypass which could cause arch timer for eg. to
tick slower. In this case would it still make sense to omit the
property? We may even have some usecases planned where we may turn OFF
the CPU once it is in TF-A cpu_standby/ WFI. What would be the right
approach in such scenarios?

Could you provide any examples where the local-timer-stop property is
being used and an alternative timer can be configured once we enter the
idle-state where CPU CTX maybe lost or clocks maybe bypass? It would be
great if you could share some example implementation if you're aware.

I took a look at QCom / NXP DT's but I couldn't exactly figure out how
they were setting up alternate timers once CPU hit idle-state.

PS. If it helps atall here's also my hack TF-A code where we enter just
CPU RET state for now:
https://github.com/DhruvaG2000/tfa-dev/commit/2d4b441d2f4c6d9ee0d6a62d93920ee8ab77dd42#diff-4fa4f4f6a5faa221390928a8079f76392536559f66e420a0182dba8e5966f4c6R232

-- 
Best regards,
Dhruva Gole
Texas Instruments Incorporated


From michal.simek at amd.com  Wed Dec 11 06:37:03 2024
From: michal.simek at amd.com (Michal Simek)
Date: Wed, 11 Dec 2024 15:37:03 +0100
Subject: [PATCH 07/15] ARM: zynq: Add ethernet phy reset information to
 DT(zc702)
In-Reply-To: <897ab5eb-a210-41d6-bfef-a60ab74f5943@lunn.ch>
References: <cover.1733920873.git.michal.simek@amd.com>
 <9e18d59ca339804320d2a5e3c7362aefa3bb7c99.1733920873.git.michal.simek@amd.com>
 <8395fb6b-d7a5-4e2c-9eb3-4984b8c775c4@lunn.ch>
 <344eb4b3-1073-4c65-a8ba-fee943776627@amd.com>
 <897ab5eb-a210-41d6-bfef-a60ab74f5943@lunn.ch>
Message-ID: <5051fb04-1bcc-4448-aa68-6ff300cc17d2@amd.com>



On 12/11/24 15:21, Andrew Lunn wrote:
> On Wed, Dec 11, 2024 at 03:04:28PM +0100, Michal Simek wrote:
>> Hi Andrew,
>>
>> On 12/11/24 14:45, Andrew Lunn wrote:
>>> On Wed, Dec 11, 2024 at 01:41:26PM +0100, Michal Simek wrote:
>>>> Added phy reset gpio information for gem0.
>>>>
>>>> Signed-off-by: Michal Simek <michal.simek at amd.com>
>>>> ---
>>>>
>>>>    arch/arm/boot/dts/xilinx/zynq-zc702.dts | 2 ++
>>>>    1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/arch/arm/boot/dts/xilinx/zynq-zc702.dts b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
>>>> index 424e78f6c148..975385f4ac01 100644
>>>> --- a/arch/arm/boot/dts/xilinx/zynq-zc702.dts
>>>> +++ b/arch/arm/boot/dts/xilinx/zynq-zc702.dts
>>>> @@ -79,6 +79,8 @@ &gem0 {
>>>>    	phy-handle = <&ethernet_phy>;
>>>>    	pinctrl-names = "default";
>>>>    	pinctrl-0 = <&pinctrl_gem0_default>;
>>>> +	phy-reset-gpio = <&gpio0 11 0>;
>>>> +	phy-reset-active-low;
>>>
>>> Hi Michal
>>>
>>> Could you point me at code which actually implements these two
>>> properties.
>>
>> I have tracked it down and it was only used from 2016 to 2018 in Xilinx
>> downstream Linux repository. After that it was removed.
> 
> O.K. So when you ran the DT lint tools to validate these DT changes,
> why did it not give errors pointing this out?
> 
> I wounder how many other such errors there are in this patchset?

That's definitely valid concern.
I was running it but for all files there are a lot of other issues generated 
that I missed this one.

../linux/arch/arm/boot/dts/xilinx/zynq-zc702.dtb: ethernet at e000b000: Unevaluated 
properties are not allowed ('phy-reset-active-low', 'phy-reset-gpio' were 
unexpected)

Thanks,
Michal




From dan.carpenter at linaro.org  Wed Dec 11 06:43:26 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Wed, 11 Dec 2024 17:43:26 +0300
Subject: [PATCH net v4 2/2] net: ti: icssg-prueth: Fix clearing of
 IEP_CMP_CFG registers during iep_init
In-Reply-To: <20241211135941.1800240-3-m-malladi@ti.com>
References: <20241211135941.1800240-1-m-malladi@ti.com>
 <20241211135941.1800240-3-m-malladi@ti.com>
Message-ID: <3b0b84f9-d51b-4075-9d1a-5c2042ee6c4e@stanley.mountain>

On Wed, Dec 11, 2024 at 07:29:41PM +0530, Meghana Malladi wrote:
>  drivers/net/ethernet/ti/icssg/icss_iep.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c
> index 5d6d1cf78e93..a96861debbe3 100644
> --- a/drivers/net/ethernet/ti/icssg/icss_iep.c
> +++ b/drivers/net/ethernet/ti/icssg/icss_iep.c
> @@ -215,6 +215,10 @@ static void icss_iep_enable_shadow_mode(struct icss_iep *iep)
>  	for (cmp = IEP_MIN_CMP; cmp < IEP_MAX_CMP; cmp++) {
>  		regmap_update_bits(iep->map, ICSS_IEP_CMP_STAT_REG,
>  				   IEP_CMP_STATUS(cmp), IEP_CMP_STATUS(cmp));
> +
> +		regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
> +				   IEP_CMP_CFG_CMP_EN(cmp), 0);
> +

Don't add this blank line.

You won't detect this by running checkpatch on the patch, but if you
apply the patch and re-run checkpatch on the file then it will complain
about this.

>  	}
>  
>  	/* enable reset counter on CMP0 event */
> @@ -780,6 +784,11 @@ int icss_iep_exit(struct icss_iep *iep)
>  	}
>  	icss_iep_disable(iep);
>  
> +	if (iep->pps_enabled)
> +		icss_iep_pps_enable(iep, false);
> +	else if (iep->perout_enabled)
> +		icss_iep_perout_enable(iep, NULL, false);


Do we need the else?  Could be written as:

	if (iep->pps_enabled)
		icss_iep_pps_enable(iep, false);
	if (iep->perout_enabled)
		icss_iep_perout_enable(iep, NULL, false);

regards,
dan carpenter




From robh at kernel.org  Wed Dec 11 06:55:41 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Dec 2024 08:55:41 -0600
Subject: [PATCH v6 01/19] dt-bindings: display: imx: Add i.MX8qxp Display
 Controller processing units
In-Reply-To: <30924a9e-7d01-46f6-9e47-405c08acdde3@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
 <20241209033923.3009629-2-victor.liu@nxp.com>
 <20241210221508.GA550635-robh@kernel.org>
 <30924a9e-7d01-46f6-9e47-405c08acdde3@nxp.com>
Message-ID: <20241211145541.GA2837320-robh@kernel.org>

On Wed, Dec 11, 2024 at 11:05:52AM +0800, Liu Ying wrote:
> On 12/11/2024, Rob Herring wrote:
> > On Mon, Dec 09, 2024 at 11:39:05AM +0800, Liu Ying wrote:
> >> Freescale i.MX8qxp Display Controller is implemented as construction set of
> >> building blocks with unified concept and standardized interfaces.  Document
> >> all existing processing units.
> >>
> >> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> >> ---
> >> v6:
> >> * No change.
> >>
> >> v5:
> >> * Document aliases for processing units which have multiple instances in
> >>   the Display Controller.  Drop Rob's previous R-b tag. (Maxime)
> >>
> >> v4:
> >> * Collect Rob's R-b tag.
> >>
> >> v3:
> >> * Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
> >>   fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
> >>   into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
> >> * Document all processing units. (Rob)
> >>
> >> v2:
> >> * Drop fsl,dc-*-id DT properties. (Krzysztof)
> >> * Add port property to fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
> >> * Fix register range sizes in examples.
> >>
> >>  .../display/imx/fsl,imx8qxp-dc-blitblend.yaml |  46 ++++++
> >>  .../display/imx/fsl,imx8qxp-dc-clut.yaml      |  49 ++++++
> >>  .../imx/fsl,imx8qxp-dc-constframe.yaml        |  49 ++++++
> >>  .../display/imx/fsl,imx8qxp-dc-dither.yaml    |  49 ++++++
> >>  .../display/imx/fsl,imx8qxp-dc-extdst.yaml    |  77 +++++++++
> >>  .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 ++++++++++++++++++
> >>  .../display/imx/fsl,imx8qxp-dc-filter.yaml    |  47 ++++++
> >>  .../display/imx/fsl,imx8qxp-dc-framegen.yaml  |  68 ++++++++
> >>  .../display/imx/fsl,imx8qxp-dc-gammacor.yaml  |  38 +++++
> >>  .../imx/fsl,imx8qxp-dc-layerblend.yaml        |  45 ++++++
> >>  .../display/imx/fsl,imx8qxp-dc-matrix.yaml    |  48 ++++++
> >>  .../display/imx/fsl,imx8qxp-dc-rop.yaml       |  48 ++++++
> >>  .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++++
> >>  .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  89 +++++++++++
> >>  .../display/imx/fsl,imx8qxp-dc-signature.yaml |  58 +++++++
> >>  .../display/imx/fsl,imx8qxp-dc-store.yaml     | 100 ++++++++++++
> >>  .../display/imx/fsl,imx8qxp-dc-tcon.yaml      |  50 ++++++
> >>  17 files changed, 1042 insertions(+)
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
> >>
> >> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
> >> new file mode 100644
> >> index 000000000000..7f800e72c3f3
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
> >> @@ -0,0 +1,46 @@
> >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blitblend.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Freescale i.MX8qxp Display Controller Blit Blend Unit
> >> +
> >> +description: |
> >> +  Combines two input frames to a single output frame, all frames having the
> >> +  same dimension.
> >> +
> >> +  Each Blit Blend Unit device should have an alias in the aliases node, in the
> >> +  form of dc<x>-blitblend<y>, where <x> is an integer specifying the Display
> >> +  Controller instance and <y> is an integer specifying the Blit Blend Unit
> >> +  device instance.
> > 
> > That's really an abuse of aliases. If you need to describe connections 
> > between components, use the graph binding like everyone else does for 
> > display path components.
> 
> I need to describe components' instance numbers which imply the connections
> between components but not vice versa. If I use the graph binding, I cannot
> get the instance numbers(0 or 1) of the two display engines(documented by
> fsl,imx8qxp-dc-display-engine.yaml). If you have no objections, I may add the
> instance numbers to compatible strings, like brcm,bcm2835-pixelvalve0.yaml.
> What do you think?

You could have dc<x> and blitblend<y> aliases and use the graph to 
define the connections. But I'm not really a fan of adding custom 
aliases either. Why are the instance numbers important?

Are the programming models or features of the instances different? If 
so, then a different compatible or property describing the feature may 
be appropriate.

Rob


From dsimic at manjaro.org  Wed Dec 11 07:22:41 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 11 Dec 2024 16:22:41 +0100
Subject: [PATCH] arm64: dts: rockchip: Delete redundant RK3328 GMAC
 stability fixes
In-Reply-To: <CAMdYzYpnx=pHJ+oqshgfZFp=Mfqp3TcMmEForqJ+s9KuhkgnqA@mail.gmail.com>
References: <e00f08d2351e82d6acd56271a68c7ed05b3362e8.1733901896.git.dsimic@manjaro.org>
 <CAMdYzYpnx=pHJ+oqshgfZFp=Mfqp3TcMmEForqJ+s9KuhkgnqA@mail.gmail.com>
Message-ID: <eb3ab82527b8c5bfa746894837661b1a@manjaro.org>

Hello Peter,

On 2024-12-11 12:26, Peter Geis wrote:
> On Wed, Dec 11, 2024 at 2:29?AM Dragan Simic <dsimic at manjaro.org> 
> wrote:
>> Since the commit 8a469ee35606 ("arm64: dts: rockchip: Add txpbl node 
>> for
>> RK3399/RK3328"), having "snps,txpbl" properties defined as Ethernet 
>> stability
>> fixes in RK3328-based board dts(i) files is redundant, because that 
>> commit
>> added the required fix to the RK3328 SoC dtsi, so let's delete them.
>> 
>> It has been determined that the Ethernet stability fixes no longer 
>> require
>> the "snps,rxpbl" and "snps,aal" properties, [1] out of which the 
>> latter also
>> induces performance penalties, so let's delete these properties from 
>> the
>> relevant RK3328-based board dts(i) files.
> 
> You may want to include snps,force_thresh_dma_mode in this group such
> as on the rock64. It's even more limiting than snps,aal.
> 
> Otherwise,
> Acked-by: Peter Geis <pgwipeout at gmail.com>

Thanks for your suggestion and review!

I'll add "snps,force_thresh_dma_mode" to the set of redundant DT
properties deleted from RK3328-based board dts(i) files in the v2
of this patch.

>> This commit completes the removal of these redundant "snps,*" 
>> properties
>> that was started by a patch from Peter Geis. [2]
>> 
>> [1] 
>> https://lore.kernel.org/linux-rockchip/CAMdYzYpj3d7Rq0O0QjV4r6HEf_e07R0QAhPT2NheZdQV3TnQ6g at mail.gmail.com/
>> [2] 
>> https://lore.kernel.org/linux-rockchip/20241210013010.81257-7-pgwipeout at gmail.com/
>> 
>> Cc: Peter Geis <pgwipeout at gmail.com>
>> Signed-off-by: Dragan Simic <dsimic at manjaro.org>
>> ---
>>  arch/arm64/boot/dts/rockchip/rk3328-a1.dts                | 1 -
>>  arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi        | 1 -
>>  arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 1 -
>>  arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts         | 3 ---
>>  4 files changed, 6 deletions(-)
>> 
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts 
>> b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
>> index 824183e515da..24baaa7f1d8c 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
>> @@ -110,7 +110,6 @@ &gmac2io {
>>         phy-supply = <&vcc_io>;
>>         pinctrl-names = "default";
>>         pinctrl-0 = <&rgmiim1_pins>;
>> -       snps,aal;
>>         snps,pbl = <0x4>;
>>         tx_delay = <0x26>;
>>         rx_delay = <0x11>;
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi 
>> b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
>> index f9fab35aed23..d5f129e304e5 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
>> @@ -142,7 +142,6 @@ &gmac2io {
>>         phy-supply = <&vcc_io_33>;
>>         pinctrl-0 = <&rgmiim1_pins>;
>>         pinctrl-names = "default";
>> -       snps,aal;
>> 
>>         mdio {
>>                 compatible = "snps,dwmac-mdio";
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi 
>> b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
>> index 181ec6de0019..9ec93f61433e 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
>> @@ -113,7 +113,6 @@ &gmac2io {
>>         phy-supply = <&vcc_io>;
>>         pinctrl-0 = <&rgmiim1_pins>;
>>         pinctrl-names = "default";
>> -       snps,aal;
>> 
>>         mdio {
>>                 compatible = "snps,dwmac-mdio";
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts 
>> b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
>> index 3e08e2fd0a78..59dead1cc503 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
>> @@ -153,9 +153,6 @@ &gmac2io {
>>         phy-supply = <&vcc_io>;
>>         pinctrl-names = "default";
>>         pinctrl-0 = <&rgmiim1_pins>;
>> -       snps,aal;
>> -       snps,rxpbl = <0x4>;
>> -       snps,txpbl = <0x4>;
>>         tx_delay = <0x26>;
>>         rx_delay = <0x11>;
>>         status = "okay";


From robdclark at gmail.com  Wed Dec 11 07:22:02 2024
From: robdclark at gmail.com (Rob Clark)
Date: Wed, 11 Dec 2024 07:22:02 -0800
Subject: [PATCH RESEND v17 3/5] iommu/arm-smmu: add support for PRR bit setup
In-Reply-To: <738f9dc8-0fe4-47e9-b3ff-f19f2f5badb8@quicinc.com>
References: <20241114160721.1527934-1-quic_bibekkum@quicinc.com>
 <20241114160721.1527934-4-quic_bibekkum@quicinc.com> <CAF6AEGuwWsAkRyF-h5Aj3KzM7iksb12HsfJ5Ks+-P8hv60MWFg@mail.gmail.com>
 <CAF6AEGvVteuOOMod6yw9_6eOn2PxAx+BR8sVOHAHp7Ts8XigBw@mail.gmail.com>
 <5696afa2-c4ab-42fe-b29a-6ecee622fbb4@quicinc.com> <CAF6AEGuMmdnOmATMy8f+YgGxfrYb5mkG_qgy870wZPebKaZjVQ@mail.gmail.com>
 <04da6036-56c4-4b8c-b75b-b5e96a089efc@quicinc.com> <CAF6AEGt-e_4kGyfiO=_oCLX8E3z76zeZ2MbRe1GicZj4hTEu+g@mail.gmail.com>
 <808e1041-0d61-4ee8-9778-0f9b7d0fb719@quicinc.com> <CAF6AEGtyc+_2V6qoZCwvRQ_QcC+uCXFXcWRpsQemEfd+rC6R+A@mail.gmail.com>
 <738f9dc8-0fe4-47e9-b3ff-f19f2f5badb8@quicinc.com>
Message-ID: <CAF6AEGtNg5WuWUK74ChHNHHntOFeWNdDMTLUq+4N3T6xAe3m1Q@mail.gmail.com>

On Wed, Dec 11, 2024 at 5:30?AM Bibek Kumar Patro
<quic_bibekkum at quicinc.com> wrote:
>
>
>
> On 12/6/2024 8:48 PM, Rob Clark wrote:
> > On Fri, Dec 6, 2024 at 4:36?AM Bibek Kumar Patro
> > <quic_bibekkum at quicinc.com> wrote:
> >>
> >>
> >>
> >> On 12/4/2024 8:54 PM, Rob Clark wrote:
> >>> On Wed, Dec 4, 2024 at 3:28?AM Bibek Kumar Patro
> >>> <quic_bibekkum at quicinc.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 11/22/2024 10:04 PM, Rob Clark wrote:
> >>>>> On Fri, Nov 22, 2024 at 8:20?AM Bibek Kumar Patro
> >>>>> <quic_bibekkum at quicinc.com> wrote:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 11/21/2024 3:40 AM, Rob Clark wrote:
> >>>>>>> On Wed, Nov 20, 2024 at 9:17?AM Rob Clark <robdclark at gmail.com> wrote:
> >>>>>>>>
> >>>>>>>> On Thu, Nov 14, 2024 at 8:10?AM Bibek Kumar Patro
> >>>>>>>> <quic_bibekkum at quicinc.com> wrote:
> >>>>>>>>>
> >>>>>>>>> Add an adreno-smmu-priv interface for drm/msm to call
> >>>>>>>>> into arm-smmu-qcom and initiate the PRR bit setup or reset
> >>>>>>>>> sequence as per request.
> >>>>>>>>>
> >>>>>>>>> This will be used by GPU to setup the PRR bit and related
> >>>>>>>>> configuration registers through adreno-smmu private
> >>>>>>>>> interface instead of directly poking the smmu hardware.
> >>>>>>>>>
> >>>>>>>>> Suggested-by: Rob Clark <robdclark at gmail.com>
> >>>>>>>>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
> >>>>>>>>> ---
> >>>>>>>>>      drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 37 ++++++++++++++++++++++
> >>>>>>>>>      drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 ++
> >>>>>>>>>      include/linux/adreno-smmu-priv.h           | 14 ++++++++
> >>>>>>>>>      3 files changed, 53 insertions(+)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>>>>>>> index d26f5aea248e..0e4f3fbda961 100644
> >>>>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> >>>>>>>>> @@ -16,6 +16,8 @@
> >>>>>>>>>
> >>>>>>>>>      #define QCOM_DUMMY_VAL -1
> >>>>>>>>>
> >>>>>>>>> +#define GFX_ACTLR_PRR          (1 << 5)
> >>>>>>>>> +
> >>>>>>>>>      static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> >>>>>>>>>      {
> >>>>>>>>>             return container_of(smmu, struct qcom_smmu, smmu);
> >>>>>>>>> @@ -99,6 +101,32 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
> >>>>>>>>>             arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
> >>>>>>>>>      }
> >>>>>>>>>
> >>>>>>>>> +static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
> >>>>>>>>> +{
> >>>>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
> >>>>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
> >>>>>>>>> +       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
> >>>>>>>>> +       u32 reg = 0;
> >>>>>>>>> +
> >>>>>>>>> +       reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
> >>>>>>>>> +       reg &= ~GFX_ACTLR_PRR;
> >>>>>>>>> +       if (set)
> >>>>>>>>> +               reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
> >>>>>>>>> +       arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
> >>>>>>>>> +{
> >>>>>>>>> +       struct arm_smmu_domain *smmu_domain = (void *)cookie;
> >>>>>>>>> +       struct arm_smmu_device *smmu = smmu_domain->smmu;
> >>>>>>>>> +
> >>>>>>>>> +       writel_relaxed(lower_32_bits(page_addr),
> >>>>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
> >>>>>>>>> +
> >>>>>>>>> +       writel_relaxed(upper_32_bits(page_addr),
> >>>>>>>>> +                               smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>>      #define QCOM_ADRENO_SMMU_GPU_SID 0
> >>>>>>>>>
> >>>>>>>>>      static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
> >>>>>>>>> @@ -210,6 +238,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
> >>>>>>>>>      static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> >>>>>>>>>                     struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> >>>>>>>>>      {
> >>>>>>>>> +       const struct device_node *np = smmu_domain->smmu->dev->of_node;
> >>>>>>>>>             struct adreno_smmu_priv *priv;
> >>>>>>>>>
> >>>>>>>>>             smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
> >>>>>>>>> @@ -239,6 +268,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> >>>>>>>>>             priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
> >>>>>>>>>             priv->set_stall = qcom_adreno_smmu_set_stall;
> >>>>>>>>>             priv->resume_translation = qcom_adreno_smmu_resume_translation;
> >>>>>>>>> +       priv->set_prr_bit = NULL;
> >>>>>>>>> +       priv->set_prr_addr = NULL;
> >>>>>>>>> +
> >>>>>>>>> +       if (of_device_is_compatible(np, "qcom,smmu-500") &&
> >>>>>>>>> +                       of_device_is_compatible(np, "qcom,adreno-smmu")) {
> >>>>>>>>
> >>>>>>>> fwiw, it seems like PRR actually works on sc7180, which is _not_
> >>>>>>>> mmu-500, so I guess the support actually goes back further.
> >>>>>>>>
> >>>>>>>> I'm curious if we can just rely on this being supported by any hw that
> >>>>>>>> has a6xx or newer?
> >>>>>>>
> >>>>>>>
> >>>>>>> Also, unrelated, but we can't assume the smmu is powered when drm
> >>>>>>> driver calls set_prr_bit/addr, could you add in runpm get/put around
> >>>>>>> the register access?
> >>>>>>>
> >>>>>>
> >>>>>> I see, thanks for this observation.
> >>>>>> It's surely a possible case, when they access these registers
> >>>>>> SMMU state is off.
> >>>>>> I will add the suggested runpm ops around the register access.
> >>>>>>
> >>>>>>> Otherwise Conner and I have vk sparse residency working now
> >>>>>>>
> >>>>>>
> >>>>>> Sorry, could not get this. Did you mean that vk sparse residency
> >>>>>> is working now using this patch?
> >>>>>
> >>>>> Yes, vk sparse residency is working with this patch (plus addition of
> >>>>> runpm get/put, plus drm/msm patches plus turnip patches) ;-)
> >>>>>
> >>>>
> >>>> Thanks for testing the sparse residency feature with our patch Rob,
> >>>> I have an additional query regarding the adreno private interfaces.
> >>>> Specifically, I was referring to other interfaces such as
> >>>> qcom_adreno_smmu_get_fault_info [1]. It appears that we do not have a
> >>>> runpm get/put around the register access in this context.
> >>>
> >>> get_fault_info() is called from the iommu fault handler callback, so
> >>> from the fault irq handler, which is why it didn't need the runpm
> >>> get/put.  Maybe it is bad to make this assumption about usage, but
> >>> then again adreno_smmu_priv isn't really a general purpose interface.
> >>>
> >>
> >> Ah okay, got it.
> >> I was just going through all the adreno_smmmu_priv interfaces just
> >> to get a better understanding of it's interaction with smmu and it seems
> >> like apart from PRR and get_fault_info(), set_ttbr0_cfg(),
> >> resume_translation() is also having reg access but not voting.
> >> Should we put runpm_put/get here as well or these can be excluded.
> >> <Just curious about the thought process behind this, is it because of
> >> some sequence when to put a vote, like reg access in middle of smmu
> >> power cycle and not in beginning or end.>
> >
> > I think we just haven't needed it, or noticed that we needed it,
> > outside of setting up prr.
> >
> > As I mentioned, get_fault_info() is called from the fault irq, so we
> > know the smmu is already powered.
> >
>
> okay got it, that makes sense.
>
> > As far as set_ttbr0_cfg(), it probably works just because
> > arm_smmu_write_context_bank() ends up getting called again in the
> > resume path, so if the smmu is suspended when set_ttbr0_cfg() is
> > called, the writes just get ignored.  But the updated cfg is
> > re-applied to the hw when it is resumed.  Probably the same situation
> > with resume_translation().. ie. if the smmu is suspended there are no
> > translations to resume.
> >
> > Maybe it would be more correct in set_ttbr0_cfg() and
> > resume_translation() to do a pm_runtime_get_if_in_use() and skip the
> > hw writes if the smmu is suspended.
> >
> >>
> >>>> Could you please clarify whether we need an SMMU vote around register
> >>>> access in the case of PRR? IMO, should the users of this callback ensure
> >>>> they put a vote before accessing the cb?
> >>>
> >>> How can drm vote for the smmu device?  I guess it could power up
> >>> itself and rely on device-link.. but that is pretty overkill to power
> >>> up the entire gpu in this case.  I think it is best for the vote to
> >>> happen in the PRR callbacks.
> >>>
> >>
> >> Okay I see, GPU can only power itself up through <gpu_state_get I
> >> assume> but won't have exclusive access to power on the smmu only.
> >>
> >> Incase we go forward to put vote in PRR callback for SMMU, I was
> >> planning that we can refactor existing arm_smmu_rpm_put/get() from
> >> arm_smmu.c to it's header file so that the same can be used in
> >> arm_smmu_qcom.c ? What's your thoughts on this?
> >
> > I had briefly thought of doing the same.  But the main reason for
> > those helpers is common arm-smmu code that is used on non-qcom
> > platforms where runpm is not enabled.  In arm-smmu-qcom.c, we know
> > that runpm is enabled, so we could just use  return
> > pm_runtime_resume_and_get()/pm_runtime_put_autosuspend() directly.
> >
>
> Ohkay I see, we then do not need pm_runtime_enabled() check for qcom
> platforms before putting the vote.
> I am currently modifying this patch only to directly add
> pm_runtime_resume_and_get()/pm_runtime_put_autosuspend()
> around the register access of PRR related adreno private interfaces.
> I will send this updated patch as part of v18 shortly.
>
> Additionally, we can evaluate the use of pm_runtime operations for
> set_ttbr0_cfg() and resume_translation() in a separate series ?

Yup, sounds good

BR,
-R


From bigeasy at linutronix.de  Wed Dec 11 07:22:57 2024
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Wed, 11 Dec 2024 16:22:57 +0100
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <CACRpkdZaoD2vqbCi1AFUa6mF2_=c3Nu4R0CvxFAep0VMgtMtOQ@mail.gmail.com>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-3-arnd@kernel.org>
 <CACRpkdZaoD2vqbCi1AFUa6mF2_=c3Nu4R0CvxFAep0VMgtMtOQ@mail.gmail.com>
Message-ID: <20241211152257.Igx3aT2Y@linutronix.de>

On 2024-12-11 14:29:29 [+0100], Linus Walleij wrote:
> So fast GUP is supposed to be lockless, and should just not
> have this problem. So it can't be addressing gup_fast_pgd_range()
> right?
?
> I'm more asking if HIGHPTE even acquires a spinlock anymore
> as it is supposed to be "fast"/lockless. If it does, it is clearly violating
> the "fast" promise of the fast GUP API and should not exist.

This is lockless on x86. The problem is ARM's
arch_kmap_local_high_get(). This is where the lock is from.

> Yours,
> Linus Walleij

Sebastian


From ryan.wanner at microchip.com  Wed Dec 11 07:25:32 2024
From: ryan.wanner at microchip.com (Ryan Wanner)
Date: Wed, 11 Dec 2024 08:25:32 -0700
Subject: [PATCH v3 07/13] dt-bindings: clock: Add SAMA7D65 PMC compatible
 string
In-Reply-To: <20241210164638.GA3770349-robh@kernel.org>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com>
 <20241210164638.GA3770349-robh@kernel.org>
Message-ID: <fb11338b-986f-4a9a-a0dd-e8f4e63941aa@microchip.com>

On 12/10/24 09:46, Rob Herring wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Fri, Dec 06, 2024 at 12:59:52PM -0700, Ryan.Wanner at microchip.com wrote:
>> From: Dharma Balasubiramani <dharma.b at microchip.com>
>>
>> Add the `microchip,sama7d65-pmc` compatible string to the existing binding,
>> since the SAMA7D65 PMC shares the same properties and clock requirements
>> as the SAMA7G5.
>>
>> Export MCK3 and MCK5 to be accessed and referenced in DT to assign to
>> the clocks property for sama7d65 SoC.
>>
>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
>> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> 
> Missing Conor's ack.
I removed the ack because I have changed the original patch that was
acked. Should the ack not have been removed even though the original
patch as been changed?


From frederic at kernel.org  Wed Dec 11 07:40:19 2024
From: frederic at kernel.org (Frederic Weisbecker)
Date: Wed, 11 Dec 2024 16:40:19 +0100
Subject: [PATCH 06/19] soc/qman: test: Use kthread_run_on_cpu()
In-Reply-To: <20241211154035.75565-1-frederic@kernel.org>
References: <20241211154035.75565-1-frederic@kernel.org>
Message-ID: <20241211154035.75565-7-frederic@kernel.org>

Use the proper API instead of open coding it.

However it looks like kthreads here could be replaced by the use of a
per-cpu workqueue instead.

Signed-off-by: Frederic Weisbecker <frederic at kernel.org>
---
 drivers/soc/fsl/qbman/qman_test_stash.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman_test_stash.c b/drivers/soc/fsl/qbman/qman_test_stash.c
index b7e8e5ec884c..f4d3c2146f4f 100644
--- a/drivers/soc/fsl/qbman/qman_test_stash.c
+++ b/drivers/soc/fsl/qbman/qman_test_stash.c
@@ -108,14 +108,12 @@ static int on_all_cpus(int (*fn)(void))
 			.fn = fn,
 			.started = ATOMIC_INIT(0)
 		};
-		struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
-			"hotpotato%d", cpu);
+		struct task_struct *k = kthread_run_on_cpu(bstrap_fn, &bstrap,
+							   cpu, "hotpotato%d");
 		int ret;
 
 		if (IS_ERR(k))
 			return -ENOMEM;
-		kthread_bind(k, cpu);
-		wake_up_process(k);
 		/*
 		 * If we call kthread_stop() before the "wake up" has had an
 		 * effect, then the thread may exit with -EINTR without ever
-- 
2.46.0



From frederic at kernel.org  Wed Dec 11 07:40:14 2024
From: frederic at kernel.org (Frederic Weisbecker)
Date: Wed, 11 Dec 2024 16:40:14 +0100
Subject: [PATCH 01/19] arm/bL_switcher: Use kthread_run_on_cpu()
In-Reply-To: <20241211154035.75565-1-frederic@kernel.org>
References: <20241211154035.75565-1-frederic@kernel.org>
Message-ID: <20241211154035.75565-2-frederic@kernel.org>

Use the proper API instead of open coding it.

Reviewed-by: Dave Martin <Dave.Martin at arm.com>
Acked-by: Nicolas Pitre <nico at fluxnic.net>
Signed-off-by: Frederic Weisbecker <frederic at kernel.org>
---
 arch/arm/common/bL_switcher.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c
index 9a9aa53547a6..d1e82a318e3b 100644
--- a/arch/arm/common/bL_switcher.c
+++ b/arch/arm/common/bL_switcher.c
@@ -307,13 +307,11 @@ static struct task_struct *bL_switcher_thread_create(int cpu, void *arg)
 {
 	struct task_struct *task;
 
-	task = kthread_create_on_node(bL_switcher_thread, arg,
-				      cpu_to_node(cpu), "kswitcher_%d", cpu);
-	if (!IS_ERR(task)) {
-		kthread_bind(task, cpu);
-		wake_up_process(task);
-	} else
+	task = kthread_run_on_cpu(bL_switcher_thread, arg,
+				  cpu, "kswitcher_%d");
+	if (IS_ERR(task))
 		pr_err("%s failed for CPU %d\n", __func__, cpu);
+
 	return task;
 }
 
-- 
2.46.0



From khilman at baylibre.com  Wed Dec 11 07:41:55 2024
From: khilman at baylibre.com (Kevin Hilman)
Date: Wed, 11 Dec 2024 07:41:55 -0800
Subject: [PATCH v6 0/3] pmdomain: ti_sci: collect and send low-power
 mode constraints
In-Reply-To: <CAPDyKFo9N8M73Z6Ltsbnd-WR-jYAqBedAHndViSD7YaKKYgBsA@mail.gmail.com>
References: <20241206-lpm-v6-10-constraints-pmdomain-v6-0-833980158c68@baylibre.com>
 <CAPDyKFo9N8M73Z6Ltsbnd-WR-jYAqBedAHndViSD7YaKKYgBsA@mail.gmail.com>
Message-ID: <7ho71ifcqk.fsf@baylibre.com>

Ulf Hansson <ulf.hansson at linaro.org> writes:

> On Fri, 6 Dec 2024 at 23:13, Kevin Hilman <khilman at baylibre.com> wrote:
>>
>> The latest (10.x) version of the firmware for the PM co-processor (aka
>> device manager, or DM) adds support for a "managed" mode, where the DM
>> firmware will select the specific low power state which is entered
>> when Linux requests a system-wide suspend.
>>
>> In this mode, the DM will always attempt the deepest low-power state
>> available for the SoC.
>>
>> However, Linux (or OSes running on other cores) may want to constrain
>> the DM for certain use cases.  For example, the deepest state may have
>> a wakeup/resume latency that is too long for certain use cases.  Or,
>> some wakeup-capable devices may potentially be powered off in deep
>> low-power states, but if one of those devices is enabled as a wakeup
>> source, it should not be powered off.
>>
>> These kinds of constraints are are already known in Linux by the use
>> of existing APIs such as per-device PM QoS and device wakeup APIs, but
>> now we need to communicate these constraints to the DM.
>>
>> For TI SoCs with TI SCI support, all DM-managed devices will be
>> connected to a TI SCI PM domain.  So the goal of this series is to use
>> the PM domain driver for TI SCI devices to collect constraints, and
>> communicate them to the DM via the new TI SCI APIs.
>>
>> This is all managed by TI SCI PM domain code.  No new APIs are needed
>> by Linux drivers.  Any device that is managed by TI SCI will be
>> checked for QoS constraints or wakeup capability and the constraints
>> will be collected and sent to the DM.
>>
>> This series depends on the support for the new TI SCI APIs (v10) and
>> was also tested with this series to update 8250_omap serial support
>> for AM62x[2].
>>
>> [1] https://lore.kernel.org/all/20240801195422.2296347-1-msp at baylibre.com
>> [2] https://lore.kernel.org/all/20240807141227.1093006-1-msp at baylibre.com/
>>
>> Signed-off-by: Kevin Hilman <khilman at baylibre.com>
>> ---
>> Changes in v6:
>> - fix build warning on arm32 when building with W=1 and CONFIG_PM_SLEEP=n
>> - rebase onto v6.13-rc1
>> - fix latency units: convert usecs (PM QoS) to msecs (TI SCI)
>> - all dependencies are now merged in v6.13-rc1
>> - Link to v5: https://lore.kernel.org/r/20241101-lpm-v6-10-constraints-pmdomain-v5-0-3011aa04622f at baylibre.com
>
> v6 applied for next and by amending patch1 to deal with the sorting of
> include files, thanks!

Thank you for the fixuup.

Kevin


From miko.lenczewski at arm.com  Wed Dec 11 07:45:04 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 15:45:04 +0000
Subject: [RFC PATCH v1 3/5] arm64: Add errata and workarounds for systems with broken BBML2
In-Reply-To: <20241211154611.40395-1-miko.lenczewski@arm.com>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
Message-ID: <20241211154611.40395-4-miko.lenczewski@arm.com>

There are systems which claim support for BBML2, but whose
implementation of this support is broken. Add a Kconfig erratum for each
of these systems, and a cpufeature workaround that forces the supported
BBM level on these systems to 0.

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 Documentation/arch/arm64/silicon-errata.rst |  32 ++++
 arch/arm64/Kconfig                          | 164 ++++++++++++++++++++
 arch/arm64/kernel/cpufeature.c              |  32 +++-
 3 files changed, 227 insertions(+), 1 deletion(-)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index b42fea07c5ce..4b4c1dd9b671 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -126,16 +126,26 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A76      | #3324349        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A76      | #3696297        | ARM64_ERRATUM_3696297       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #1491015        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #1508412        | ARM64_ERRATUM_1508412       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #3324348        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A77      | #3696294        | ARM64_ERRATUM_3696294       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A78      | #3324344        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A78      | #3696287        | ARM64_ERRATUM_3696287       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A78C     | #3324346,3324347| ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A78C     | #3696291        | ARM64_ERRATUM_3696291       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A78C     | #3696292        | ARM64_ERRATUM_3696292       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2119858        | ARM64_ERRATUM_2119858       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2054223        | ARM64_ERRATUM_2054223       |
@@ -144,6 +154,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #3324338        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A710     | #3696244        | ARM64_ERRATUM_3696244       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A715     | #2645198        | ARM64_ERRATUM_2645198       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A715     | #3456084        | ARM64_ERRATUM_3194386       |
@@ -156,6 +168,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X1       | #3324344        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X1       | #3696287        | ARM64_ERRATUM_3696287       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X1C      | #3324346        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X2       | #2119858        | ARM64_ERRATUM_2119858       |
@@ -164,10 +178,18 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X2       | #3324338        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X2       | #3696244        | ARM64_ERRATUM_3696244       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X3       | #3324335        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X3       | #3696239        | ARM64_ERRATUM_3696239       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X4       | #3043263        | ARM64_ERRATUM_3043263       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X4       | #3194386        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X925     | #3056274        | ARM64_ERRATUM_3056274       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X925     | #3324334        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N1     | #1188873,1418040| ARM64_ERRATUM_1418040       |
@@ -180,6 +202,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N1     | #3324349        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-N1     | #3696297        | ARM64_ERRATUM_3696297       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N2     | #2139208        | ARM64_ERRATUM_2139208       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N2     | #2067961        | ARM64_ERRATUM_2067961       |
@@ -188,14 +212,22 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N2     | #3324339        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-N2     | #3696250        | ARM64_ERRATUM_3696250       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N3     | #3456111        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V1     | #1619801        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V1     | #3324341        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-V1     | #3696285        | ARM64_ERRATUM_3696285       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V2     | #3324336        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-V2     | #3696242        | ARM64_ERRATUM_3696242       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-V3     | #3053180        | ARM64_ERRATUM_3053180       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V3     | #3312417        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | MMU-500         | #841119,826419  | N/A                         |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..9ef8418e8410 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1127,6 +1127,170 @@ config ARM64_ERRATUM_3194386
 
 	  If unsure, say Y.
 
+config ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	bool
+
+config ARM64_ERRATUM_3696250
+	bool "Neoverse-N2: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Neoverse-N2 cores (r0p0, r0p1, r0p2, r0p3) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696244
+	bool "Cortex-A710/Cortex-X2: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-A710 and Cortex-X2 cores (r0p0, r1p0, r2p0, r2p1)
+	  declare break-before-make level 2 support, but changing the block
+	  size without utilising a break-before-make sequence, or
+	  mis-programming the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696297
+	bool "Cortex-A76/Neoverse-N1: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  This option adds a workaround for ARM Cortex-A76/Neoverse-N1 erratum
+	  3696297.
+
+	  Affected Cortex-A76 and Neoverse-N1 cores (r0p0, r1p0, r2p0, r3p0,
+	  r3p1, r4p0, r4p1) declare break-before-make level 2 support, but
+	  changing the block size without utilising a break-before-make sequence,
+	  or mis-programming the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696294
+	bool "Cortex-A77: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  This option adds a workaround for ARM Cortex-A77 erratum 3696294.
+
+	  Affected Cortex-A77 cores (r0p0, r1p0, r1p1) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696239
+	bool "Cortex-X3: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-X3 cores (r0p0, r1p0, r1p1, r1p2) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696242
+	bool "Neoverse-V2: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Neoverse-V2 cores (r0p0, r0p1, r0p2) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696285
+	bool "Neoverse-V1: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Neoverse-V1 cores (r0p0, r1p0, r1p1, r1p2) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696287
+	bool "Cortex-A78/Cortex-X1: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-A78 and Cortex-X1 cores (r0p0, r1p0, r1p1, r1p2)
+	  declare break-before-make level 2 support, but changing the block
+	  size without utilising a break-before-make sequence, or
+	  mis-programming the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696291
+	bool "Cortex-A78C: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-A78C cores (r0p0, r0p1, r0p2) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696292
+	bool "Cortex-A78C: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-A78C cores (r0p1, r0p2) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3056274
+	bool "Cortex-X925: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-X925 cores (r0p0, r0p1) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3043263
+	bool "Cortex-X4: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-X4 cores (r0p0, r0p1, r0p2) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3053180
+	bool "Neoverse-V3: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Neoverse-V3 cores (r0p0, r0p1) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 7cc94bd5da24..e6c05b330e0f 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2167,6 +2167,36 @@ static bool hvhe_possible(const struct arm64_cpu_capabilities *entry,
 	return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_HVHE);
 }
 
+static bool has_bbml2(const struct arm64_cpu_capabilities *entry,
+		      int scope)
+{
+	if (IS_ENABLED(CONFIG_ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT)) {
+		static const struct midr_range broken_bbml2_list[] = {
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
+			{}
+		};
+
+		if (is_midr_in_range_list(read_cpuid_id(), broken_bbml2_list))
+			return false;
+	}
+
+	return has_cpuid_feature(entry, scope);
+}
+
 #ifdef CONFIG_ARM64_PAN
 static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused)
 {
@@ -2921,7 +2951,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.desc = "BBM Level 2 Support",
 		.capability = ARM64_HAS_BBML2,
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
-		.matches = has_cpuid_feature,
+		.matches = has_bbml2,
 		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, BBM, 2)
 	},
 	{
-- 
2.45.2



From miko.lenczewski at arm.com  Wed Dec 11 07:45:05 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 15:45:05 +0000
Subject: [RFC PATCH v1 4/5] arm64/mm: Delay tlbi in contpte_convert() under BBML2
In-Reply-To: <20241211154611.40395-1-miko.lenczewski@arm.com>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
Message-ID: <20241211154611.40395-5-miko.lenczewski@arm.com>

When converting a region via contpte_convert() to use mTHP, we have two
different goals. We have to mark each entry as contiguous, and we would
like to smear the dirty and young (access) bits across all entries in
the contiguous block. Currently, we do this by first accumulating the
dirty and young bits in the block, using an atomic
__ptep_get_and_clear() and the relevant pte_{dirty,young}() calls,
performing a tlbi, and finally smearing the correct bits across the
block using __set_ptes().

This approach works fine for BBM level 0, but with support for BBM level
2 we are allowed to reorder the tlbi to after setting the pagetable
entries. This reordering means that other threads will not see an
invalid pagetable entry, instead operating on stale data, until we have
performed our smearing and issued the invalidation. Avoiding this
invalid entry reduces faults in other threads, and thus improves
performance marginally (more so when there are more threads).

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 arch/arm64/mm/contpte.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 55107d27d3f8..fc927be800ee 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -68,9 +68,13 @@ static void contpte_convert(struct mm_struct *mm, unsigned long addr,
 			pte = pte_mkyoung(pte);
 	}
 
-	__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
+	if (!system_supports_bbml2())
+		__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
 
 	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
+
+	if (system_supports_bbml2())
+		__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
 }
 
 void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
-- 
2.45.2



From broonie at kernel.org  Wed Dec 11 07:44:55 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 15:44:55 +0000
Subject: [PATCH v6 2/7] mfd: nxp-siul2: add support for NXP SIUL2
In-Reply-To: <20241211124454.GE7139@google.com>
References: <20241113101124.1279648-1-andrei.stefanescu@oss.nxp.com>
 <20241113101124.1279648-3-andrei.stefanescu@oss.nxp.com>
 <20241211124454.GE7139@google.com>
Message-ID: <3b090335-20b4-4d73-aabc-ddac98311e33@sirena.org.uk>

On Wed, Dec 11, 2024 at 12:45:56PM +0000, Lee Jones wrote:

> Seeing as the vast majority of this 400 line driver pertains to Regmap
> handling (!), would you be kind enough to cast your expert eye over it
> please?

Is there something specific you're concerned about there?  It looks like
it's just data which should be fine.
-------------- 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/20241211/e6850d54/attachment.sig>

From detlev.casanova at collabora.com  Wed Dec 11 07:45:01 2024
From: detlev.casanova at collabora.com (Detlev Casanova)
Date: Wed, 11 Dec 2024 10:45:01 -0500
Subject: [PATCH v5 05/18] drm/rockchip: vop2: Set AXI id for rk3588
In-Reply-To: <2d381563.5e54.193b46d2f30.Coremail.andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com> <5839604.DvuYhMxLoT@trenzalore>
 <2d381563.5e54.193b46d2f30.Coremail.andyshrk@163.com>
Message-ID: <5843712.DvuYhMxLoT@bootstrap>

On Wednesday, 11 December 2024 01:34:34 EST Andy Yan wrote:
> Hi Detlev,
> 
> At 2024-12-11 02:40:14, "Detlev Casanova" <detlev.casanova at collabora.com> 
wrote:
> >Hi Andy,
> >
> >On Monday, 9 December 2024 07:29:18 EST Andy Yan wrote:
> >> From: Andy Yan <andy.yan at rock-chips.com>
> >> 
> >> There are two AXI bus in vop2, windows attached on the same bus must
> >> have a unique channel YUV and RGB channel ID.
> >> 
> >> The default IDs will conflict with each other on the rk3588, so they
> >> need to be reassigned.
> >> 
> >> Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
> >> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
> >> Tested-by: Derek Foreman <derek.foreman at collabora.com>
> >> 
> >> ---
> >> 
> >> Changes in v5:
> >> - Added in V5
> >> 
> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 14 +++++++++++
> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  9 +++++++
> >>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 26 +++++++++++++++++++-
> >>  3 files changed, 48 insertions(+), 1 deletion(-)
> >> 
> >> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> >> b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index
> >> dc4edd65bc9e..8b9ca046eeeb 100644
> >> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> >> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> >> @@ -1426,6 +1426,12 @@ static void vop2_plane_atomic_update(struct
> >> drm_plane *plane, &fb->format->format,
> >> 
> >>  		afbc_en ? "AFBC" : "", &yrgb_mst);
> >> 
> >> +	if (vop2->data->soc_id > 3568) {
> >
> >Shouldn't this be done only for rk3588, as specified in the comments below
> >? The test we did before showed that it is failing on rk3576 and 3576 is >
> >3588.
> I think this is because you tested before with the patch I gave Derek 
> without axi id assigned for rk3576.
> I assigned axi id for rk3576 in this version 18/18?The new ID assignment can
> adapt to more application scenarios.?, can you test it with the whole V5
> version again?

Yes, I will do that. But patch 18 mentions:
+       /* Read only bit on rk3576*/
+       [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),

And the bit is being written here. If it is indeed writable, then I would drop 
that comment.

> >I suggest
> >
> >	if (vop2->data->soc_id == 3588) {
> >
> >Regards,
> >Detlev
> >
> >> +		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data-
> >>
> >>axi_bus_id);
> >>
> >> +		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data-
> >>
> >>axi_yrgb_r_id);
> >>
> >> +		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data-
> >>
> >>axi_uv_r_id);
> >>
> >> +	}
> >> +
> >> 
> >>  	if (vop2_cluster_window(win))
> >>  	
> >>  		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN,
> >
> >half_block_en);
> >

Detlev.




From dan.carpenter at linaro.org  Wed Dec 11 07:46:15 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Wed, 11 Dec 2024 18:46:15 +0300
Subject: [PATCH net v4 1/2] net: ti: icssg-prueth: Fix firmware load
 sequence.
In-Reply-To: <20241211135941.1800240-2-m-malladi@ti.com>
References: <20241211135941.1800240-1-m-malladi@ti.com>
 <20241211135941.1800240-2-m-malladi@ti.com>
Message-ID: <304870d9-10c7-43b3-8255-8f2b0422d759@stanley.mountain>

On Wed, Dec 11, 2024 at 07:29:40PM +0530, Meghana Malladi wrote:
> -static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
> +static int prueth_emac_start(struct prueth *prueth, int slice)
>  {
>  	struct icssg_firmwares *firmwares;
>  	struct device *dev = prueth->dev;
> -	int slice, ret;
> +	int ret;
>  
>  	if (prueth->is_switch_mode)
>  		firmwares = icssg_switch_firmwares;
> @@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>  	else
>  		firmwares = icssg_emac_firmwares;
>  
> -	slice = prueth_emac_slice(emac);
> -	if (slice < 0) {
> -		netdev_err(emac->ndev, "invalid port\n");
> -		return -EINVAL;
> -	}
> -
> -	ret = icssg_config(prueth, emac, slice);
> -	if (ret)
> -		return ret;
> -
>  	ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
>  	ret = rproc_boot(prueth->pru[slice]);

This isn't introduced by this patch but eventually Colin King is going to
get annoyed with you for setting ret twice in a row.

>  	if (ret) {
> @@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>  		goto halt_rtu;
>  	}
>  
> -	emac->fw_running = 1;
>  	return 0;
>  
>  halt_rtu:
> @@ -220,6 +209,78 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>  	return ret;
>  }
>  
> +static int prueth_emac_common_start(struct prueth *prueth)
> +{
> +	struct prueth_emac *emac;
> +	int ret = 0;
> +	int slice;
> +
> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
> +		return -EINVAL;
> +
> +	/* clear SMEM and MSMC settings for all slices */
> +	memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
> +	memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
> +
> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
> +
> +	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
> +		icssg_init_fw_offload_mode(prueth);
> +	else
> +		icssg_init_emac_mode(prueth);
> +
> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
> +		emac = prueth->emac[slice];
> +		if (emac) {
> +			ret |= icssg_config(prueth, emac, slice);
> +			if (ret)
> +				return ret;

Here we return directly.

> +		}
> +		ret |= prueth_emac_start(prueth, slice);

Here we continue.  Generally, I would expect there to be some clean up
on this error path like this:

		ret = prueth_emac_start(prueth, slice);
		if (ret)
			goto unwind_slices;

	...

	return 0;

unwind_slices:
	while (--slice >= 0)
		prueth_emac_stop(prueth, slice);

	return ret;

I dread to see how the cleanup is handled on this path...

Ok.  I've looked at it and, nope, it doesn't work.  This is freed in
prueth_emac_common_stop() but partial allocations are not freed.
Also the prueth_emac_stop() is open coded as three calls to
rproc_shutdown() which is ugly.

I've written a blog which describes a system for writing error
handling code.  If each function cleans up after itself by freeing
its own partial allocations then you don't need to have a variable
like "prueth->prus_running = 1;" to track how far the allocation
process went before failing.
https://staticthinking.wordpress.com/2022/04/28/free-the-last-thing-style/

regards,
dan carpenter



From miko.lenczewski at arm.com  Wed Dec 11 07:45:01 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 15:45:01 +0000
Subject: [RFC PATCH v1 0/5] Initial BBML2 support for contpte_convert()
Message-ID: <20241211154611.40395-1-miko.lenczewski@arm.com>

Hi All,

This patch series seeks to gather feedback on adding initial support
for level 2 of the Break-Before-Make arm64 architectural feature,
specifically to contpte_convert().

This support reorders a TLB invalidation in contpte_convert(), and
optionally elides said invalidation completely which leads to a 12%
improvement when executing a microbenchmark designed to force the
pathological path where contpte_convert() gets called. This
represents an 80% reduction in the cost of calling contpte_convert().

However, the elision of the invalidation is still pending review to
ensure it is architecturally valid. Without it, the reodering also
represents a performance improvement due to reducing thread contention,
as there is a smaller time window for racing threads to see an invalid
pagetable entry (especially if they already have a cached entry in their
TLB that they are working off of).

This series is based on v6.13-rc2 (fac04efc5c79).

Break-Before-Make Level 2
=========================

Break-Before-Make (BBM) sequences ensure a consistent view of the
page tables. They avoid TLB multi-hits and ensure atomicity and
ordering guarantees. BBM level 0 simply defines the current use
of page tables. When you want to change certain bits in a pte,
you need to:

- clear the pte
- dsb()
- issue a tlbi for the pte
- dsb()
- repaint the pte
- dsb()

When changing block size, or toggling the contiguous bit, we
currently use this BBM level 0 sequence. With BBM level 2 support,
however, we can relax the BBM sequence and benefit from a performance
improvement. The hardware would then either automatically handle the
TLB invalidations, or would take a TLB Conflict Abort Exception.

This exception can either be a stage 1 or stage 2 exception, depending
on whether stage 1 or stage 2 translations are in use. The architecture
currently mandates a worst-case invalidation of vmalle1 or vmalls12e1,
when stage 2 translation is not in-use and in-use respectively.

Outstanding Questions and Remaining TODOs
=========================================

Patch 4 moves the tlbi so that the window where the pte is invalid is
significantly smaller. This reduces the chances of racing threads
accessing the memory during the window and taking a fault. This is
confirmed to be architecturally sound.

Patch 5 removes the tlbi entirely. This has the benefit of
significantly reducing the cost of contpte_convert(). While testing
has demonstrated that this works as expected on Arm-designed CPUs, we
are still in the process of confirming whether it is architecturally
correct. I am requesting review while that process is on-going. Patch 5
would be dropped if it turns out to be architecturally unsound.

Another note is that the stage 2 TLB conflict handling is included as
patch 1 of this series. This patch could (and probably should) be sent
separately as it may be useful outside this series, but is included for
reference.

Thanks,
Miko

Miko?aj Lenczewski (5):
  arm64: Add TLB Conflict Abort Exception handler to KVM
  arm64: Add BBM Level 2 cpu feature
  arm64: Add errata and workarounds for systems with broken BBML2
  arm64/mm: Delay tlbi in contpte_convert() under BBML2
  arm64/mm: Elide tlbi in contpte_convert() under BBML2

 Documentation/arch/arm64/silicon-errata.rst |  32 ++++
 arch/arm64/Kconfig                          | 164 ++++++++++++++++++++
 arch/arm64/include/asm/cpufeature.h         |  14 ++
 arch/arm64/include/asm/esr.h                |   8 +
 arch/arm64/kernel/cpufeature.c              |  37 +++++
 arch/arm64/kvm/mmu.c                        |   6 +
 arch/arm64/mm/contpte.c                     |   3 +-
 arch/arm64/mm/fault.c                       |  27 +++-
 arch/arm64/tools/cpucaps                    |   1 +
 9 files changed, 290 insertions(+), 2 deletions(-)

-- 
2.45.2



From m.felsch at pengutronix.de  Wed Dec 11 07:46:22 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Wed, 11 Dec 2024 16:46:22 +0100
Subject: [PATCH v2 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241210-imx91tmu-v2-2-5032aad4d88e@nxp.com>
References: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
 <20241210-imx91tmu-v2-2-5032aad4d88e@nxp.com>
Message-ID: <20241211154622.f2jwwrqansk6il3o@pengutronix.de>

On 24-12-10, Frank Li wrote:
> From: Pengfei Li <pengfei.li_1 at nxp.com>
> 
> Introduce support for the i.MX91 thermal monitoring unit, which features a
> single sensor for the CPU. The register layout differs from other chips,
> necessitating the creation of a dedicated file for this.
> 
> Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> change from v1 to v2
> - use low case for hexvalue
> - combine struct imx91_tmu and tmu_sensor
> - simplify imx91_tmu_start() and imx91_tmu_enable()
> - use s16 for imx91_tmu_get_temp(), which may negative value
> - use reverse christmas tree style
> - use run time pm
> - use oneshot to sample temp
> - register thermal zone after hardware init
> ---
>  drivers/thermal/Kconfig         |  10 ++
>  drivers/thermal/Makefile        |   1 +
>  drivers/thermal/imx91_thermal.c | 265 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 276 insertions(+)
> 
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index d3f9686e26e71..da403ed86aeb1 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -296,6 +296,16 @@ config IMX8MM_THERMAL
>  	  cpufreq is used as the cooling device to throttle CPUs when the passive
>  	  trip is crossed.
>  
> +config IMX91_THERMAL
> +	tristate "Temperature sensor driver for NXP i.MX91 SoC"
> +	depends on ARCH_MXC || COMPILE_TEST
> +	depends on OF
> +	help
> +	  Support for Temperature sensor found on NXP i.MX91 SoC.
> +	  It supports one critical trip point and one passive trip point. The
> +	  cpufreq is used as the cooling device to throttle CPUs when the passive
> +	  trip is crossed.
> +
>  config K3_THERMAL
>  	tristate "Texas Instruments K3 thermal support"
>  	depends on ARCH_K3 || COMPILE_TEST
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index 9abf43a74f2bb..08da241e6a598 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
>  obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
>  obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
>  obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
> +obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
>  obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
>  obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
>  obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
> diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
> new file mode 100644
> index 0000000000000..ebb59eda92951
> --- /dev/null
> +++ b/drivers/thermal/imx91_thermal.c
> @@ -0,0 +1,265 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2024 NXP.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/iopoll.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/thermal.h>
> +
> +#define CTRL0			0x0

Unused

> +
> +#define STAT0			0x10
> +#define STAT0_DRDY0_IF_MASK	BIT(16)
> +
> +#define DATA0			0x20
> +
> +#define THR_CTRL01		0x30
> +#define THR_CTRL23		0x40

Both are unused too

> +#define CTRL1			0x200

Unused

> +#define CTRL1_SET		0x204
> +#define CTRL1_CLR		0x208
> +#define CTRL1_EN		BIT(31)
> +#define CTRL1_START		BIT(30)
> +#define CTRL1_STOP		BIT(29)
> +#define CTRL1_RES_MASK		GENMASK(19, 18)
> +#define CTRL1_MEAS_MODE_MASK	GENMASK(25, 24)
> +#define   CTRL1_MEAS_MODE_SINGLE	0
> +#define   CTRL1_MEAS_MODE_CONTINUES	1
> +#define   CTRL1_MEAS_MODE_PERIODIC	2
> +
> +#define REF_DIV			0x280
> +#define DIV_EN			BIT(31)
> +#define DIV_MASK		GENMASK(23, 16)
> +
> +#define PUD_ST_CTRL		0x2B0
> +#define PUDL_MASK		GENMASK(23, 16)
> +
> +#define TRIM1			0x2E0
> +#define TRIM2			0x2F0
					^
				still upper-case

> +#define TMU_TEMP_LOW_LIMIT	-40000
> +#define TMU_TEMP_HIGH_LIMIT	125000
> +
> +#define DEFAULT_TRIM1_CONFIG 0xb561bc2d
> +#define DEFAULT_TRIM2_CONFIG 0x65d4
> +
> +struct imx91_tmu {
> +	void __iomem *base;
> +	struct clk *clk;
> +	struct device *dev;
> +	struct thermal_zone_device *tzd;
> +};
> +
> +static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
> +{
> +	u32 val = start ? CTRL1_START : CTRL1_STOP;
> +
> +	writel_relaxed(val, tmu->base + CTRL1_SET);
> +}
> +
> +static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
> +{
> +	u32 reg = enable ? CTRL1_SET : CTRL1_CLR;
> +
> +	writel_relaxed(CTRL1_EN, tmu->base + reg);
> +}
> +
> +static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
> +{
> +	struct imx91_tmu *tmu = thermal_zone_device_priv(tz);
> +	s16 data;
> +	int ret;
> +	u32 val;
> +
> +	ret = pm_runtime_resume_and_get(tmu->dev);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = readl_relaxed_poll_timeout(tmu->base + STAT0, val,
> +					 val & STAT0_DRDY0_IF_MASK, 1000,
> +					 40000);
> +	if (ret)
> +		return -EAGAIN;
		 ^
Missing pm_runtime_put(). Instead goto out;

> +
> +	/* DATA0 is 16bit signed number */
> +	data = readw_relaxed(tmu->base + DATA0);
> +	*temp = data * 1000 / 64;
> +	if (*temp < TMU_TEMP_LOW_LIMIT || *temp > TMU_TEMP_HIGH_LIMIT)
> +		return -EAGAIN;
			^
		ret = -EAGAIN;
		goto out;

out:
> +
> +	pm_runtime_put(tmu->dev);
> +
> +	return 0;
	
	return ret;
> +}
> +
> +static struct thermal_zone_device_ops tmu_tz_ops = {
> +	.get_temp = imx91_tmu_get_temp,
> +};
> +
> +static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
> +{
> +	struct device *dev = tmu->dev;
> +	u32 trim1, trim2;
> +	int ret;
> +
> +	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
> +	if (ret)
> +		return ret;
> +
> +	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
> +	if (ret)
> +		return ret;
> +
> +	if (trim1 == 0 || trim2 == 0)
> +		return -EINVAL;
> +
> +	writel_relaxed(trim1, tmu->base + TRIM1);
> +	writel_relaxed(trim2, tmu->base + TRIM2);
> +
> +	return 0;
> +}
> +
> +static int imx91_tmu_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;

Since you already have the dev pointer, you can make use of it...

> +	struct imx91_tmu *tmu;
> +	unsigned long rate;
> +	u32 div;
> +	int ret;
> +
> +	tmu = devm_kzalloc(&pdev->dev, sizeof(struct imx91_tmu), GFP_KERNEL);
				^
				here
> +	if (!tmu)
> +		return -ENOMEM;
> +
> +	tmu->dev = &pdev->dev;

	and here

> +
> +	tmu->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(tmu->base))
> +		return PTR_ERR(tmu->base);
			^
		dev_err_probe();

> +
> +	tmu->clk = devm_clk_get_enabled(dev, NULL);
> +	if (IS_ERR(tmu->clk))
> +		return dev_err_probe(dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
> +
> +	platform_set_drvdata(pdev, tmu);
> +
> +	/* disable the monitor during initialization */
> +	imx91_tmu_enable(tmu, false);
> +	imx91_tmu_start(tmu, false);

No need to disable it here since both bits (ENABLE and START) are 0
after a reset.

> +	ret = imx91_init_from_nvmem_cells(tmu);
> +	if (ret) {
> +		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
> +		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
			^
Can you please anwer if _relaxed API is sufficient? I don't know why you
making use of the _relaxed API here anyway. We have only a few MMIO
accesses here, so why can't we use the writel() instead? This applies to
the whole driver.

> +	}
> +
> +	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
> +	rate = clk_get_rate(tmu->clk);
> +	div = (rate / 4000000) - 1;
> +	if (div > FIELD_GET(DIV_MASK, DIV_MASK))
			^
This misuse the FIELD_GET() API. Instead please add a define e.g. DIV_MAX.

> +		return -EINVAL;
			^
		dev_err_probe()
> +
> +	/* Set divider value and enable divider */
> +	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
> +
> +	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
> +	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
		^
You dont need to repeat the default value, so this line can be dropped.

> +
> +	/*
> +	 * Set resolution mode
> +	 * 00b - Conversion time = 0.59325 ms
> +	 * 01b - Conversion time = 1.10525 ms
> +	 * 10b - Conversion time = 2.12925 ms
> +	 * 11b - Conversion time = 4.17725 ms
> +	 */
> +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
> +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);

Same here, you repeat the module default after reset, so please drop it.

> +	writel_relaxed(CTRL1_MEAS_MODE_MASK, tmu->base + CTRL1_CLR);
> +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, CTRL1_MEAS_MODE_SINGLE),
> +		       tmu->base + CTRL1_SET);
> +
> +	clk_disable_unprepare(tmu->clk);

Drop this, and

> +	pm_runtime_set_suspended(dev);

replace this with: pm_runtime_set_active()

> +	pm_runtime_enable(dev);
		^
devm_pm_runtime_enable()

> +	tmu->tzd = devm_thermal_of_zone_register(dev, 0, tmu, &tmu_tz_ops);
> +	if (IS_ERR(tmu->tzd))
> +		return dev_err_probe(dev, PTR_ERR(tmu->tzd),
> +				     "failed to register thermal zone sensor\n");


pm_runtime_put()


> +
> +	return 0;
> +}
> +
> +static void imx91_tmu_remove(struct platform_device *pdev)
> +{
> +	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
> +
> +	/* disable tmu */
> +	imx91_tmu_start(tmu, false);

No need to clear the START bit since we are running in
single-shot-measurements now.

> +	imx91_tmu_enable(tmu, false);
> +}
> +
> +static int imx91_tmu_runtime_suspend(struct device *dev)
> +{
> +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> +
> +	/* disable tmu */
> +	imx91_tmu_start(tmu, false);

Can be dropped.

> +	imx91_tmu_enable(tmu, false);
> +
> +	clk_disable_unprepare(tmu->clk);
> +
> +	return 0;
> +}
> +
> +static int imx91_tmu_runtime_resume(struct device *dev)
> +{
> +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = clk_prepare_enable(tmu->clk);
> +	if (ret)
> +		return ret;
> +
> +	imx91_tmu_enable(tmu, true);
> +	imx91_tmu_start(tmu, true);

Drop imx91_tmu_start() from the resume since this isn't related to the
runtime-pm. Instead the function needs to be called within
imx91_tmu_get_temp().

> +	return 0;
> +}
> +
> +static const struct dev_pm_ops imx91_tmu_pm_ops = {
> +	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
> +	RUNTIME_PM_OPS(imx91_tmu_runtime_suspend, imx91_tmu_runtime_resume, NULL)
> +};

DEFINE_RUNTIME_DEV_PM_OPS()

> +
> +static const struct of_device_id imx91_tmu_table[] = {
> +	{ .compatible = "fsl,imx91-tmu", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, imx91_tmu_table);
> +
> +static struct platform_driver imx91_tmu = {
> +	.driver = {
> +		.name	= "i.MX91_thermal",
				^
Please don't use such names, instead use imx91_thermal.

Regards,
  Marco

> +		.pm	= pm_ptr(&imx91_tmu_pm_ops),
> +		.of_match_table = imx91_tmu_table,
> +	},
> +	.probe = imx91_tmu_probe,
> +	.remove = imx91_tmu_remove,
> +};
> +module_platform_driver(imx91_tmu);
> +
> +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> +MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
> +MODULE_LICENSE("GPL");
> 
> -- 
> 2.34.1
> 
> 


From miko.lenczewski at arm.com  Wed Dec 11 07:45:02 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 15:45:02 +0000
Subject: [RFC PATCH v1 1/5] arm64: Add TLB Conflict Abort Exception handler to KVM
In-Reply-To: <20241211154611.40395-1-miko.lenczewski@arm.com>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
Message-ID: <20241211154611.40395-2-miko.lenczewski@arm.com>

Currently, KVM does not handle the case of a stage 2 TLB conflict abort
exception. The Arm ARM specifies that the worst-case handling of such an
exception requires a `tlbi vmalls12e1`. Perform such an invalidation
when this exception is encountered.

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 arch/arm64/include/asm/esr.h | 8 ++++++++
 arch/arm64/kvm/mmu.c         | 6 ++++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d1b1a33f9a8b..8a66f81ca291 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -121,6 +121,7 @@
 #define ESR_ELx_FSC_SEA_TTW(n)	(0x14 + (n))
 #define ESR_ELx_FSC_SECC	(0x18)
 #define ESR_ELx_FSC_SECC_TTW(n)	(0x1c + (n))
+#define ESR_ELx_FSC_TLBABT	(0x30)
 
 /* Status codes for individual page table levels */
 #define ESR_ELx_FSC_ACCESS_L(n)	(ESR_ELx_FSC_ACCESS + (n))
@@ -464,6 +465,13 @@ static inline bool esr_fsc_is_access_flag_fault(unsigned long esr)
 	       (esr == ESR_ELx_FSC_ACCESS_L(0));
 }
 
+static inline bool esr_fsc_is_tlb_conflict_abort(unsigned long esr)
+{
+	esr = esr & ESR_ELx_FSC;
+
+	return esr == ESR_ELx_FSC_TLBABT;
+}
+
 /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */
 static inline bool esr_iss_is_eretax(unsigned long esr)
 {
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index c9d46ad57e52..c8c6f5a97a1b 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1756,6 +1756,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 	ipa = fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
 	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
 
+	if (esr_fsc_is_tlb_conflict_abort(esr)) {
+		// does a `tlbi vmalls12e1is`
+		__kvm_tlb_flush_vmid(&vcpu->kvm->arch.mmu);
+		return 1;
+	}
+
 	if (esr_fsc_is_translation_fault(esr)) {
 		/* Beyond sanitised PARange (which is the IPA limit) */
 		if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit())) {
-- 
2.45.2



From miko.lenczewski at arm.com  Wed Dec 11 07:45:03 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 15:45:03 +0000
Subject: [RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <20241211154611.40395-1-miko.lenczewski@arm.com>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
Message-ID: <20241211154611.40395-3-miko.lenczewski@arm.com>

The Break-Before-Make cpu feature supports multiple levels (levels 0-2),
and this commit adds a dedicated BBML2 cpufeature to test against
support for.

In supporting BBM level 2, we open ourselves up to potential TLB
Conflict Abort Exceptions during expected execution, instead of only
in exceptional circumstances. In the case of an abort, it is
implementation defined at what stage the abort is generated, and
the minimal set of required invalidations is also implementation
defined. The maximal set of invalidations is to do a `tlbi vmalle1`
or `tlbi vmalls12e1`, depending on the stage.

Such aborts should not occur on Arm hardware, and were not seen in
benchmarked systems, so unless performance concerns arise, implementing
the abort handlers with the worst-case invalidations seems like an
alright hack.

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 arch/arm64/include/asm/cpufeature.h | 14 ++++++++++++++
 arch/arm64/kernel/cpufeature.c      |  7 +++++++
 arch/arm64/mm/fault.c               | 27 ++++++++++++++++++++++++++-
 arch/arm64/tools/cpucaps            |  1 +
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 8b4e5a3cd24c..a9f2ac335392 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -866,6 +866,20 @@ static __always_inline bool system_supports_mpam_hcr(void)
 	return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
 }
 
+static inline bool system_supports_bbml2(void)
+{
+	/* currently, BBM is only relied on by code touching the userspace page
+	 * tables, and as such we are guaranteed that caps have been finalised.
+	 *
+	 * if later we want to use BBM for kernel mappings, particularly early
+	 * in the kernel, this may return 0 even if BBML2 is actually supported,
+	 * which means unnecessary break-before-make sequences, but is still
+	 * correct
+	 */
+
+	return alternative_has_cap_unlikely(ARM64_HAS_BBML2);
+}
+
 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 6ce71f444ed8..7cc94bd5da24 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2917,6 +2917,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP)
 	},
+	{
+		.desc = "BBM Level 2 Support",
+		.capability = ARM64_HAS_BBML2,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_cpuid_feature,
+		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, BBM, 2)
+	},
 	{
 		.desc = "52-bit Virtual Addressing for KVM (LPA2)",
 		.capability = ARM64_HAS_LPA2,
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index ef63651099a9..dc119358cbc1 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -844,6 +844,31 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
 	return 0;
 }
 
+static int do_conflict_abort(unsigned long far, unsigned long esr,
+			     struct pt_regs *regs)
+{
+	if (!system_supports_bbml2())
+		return do_bad(far, esr, regs);
+
+	/* if we receive a TLB conflict abort, we know that there are multiple
+	 * TLB entries that translate the same address range. the minimum set
+	 * of invalidations to clear these entries is implementation defined.
+	 * the maximum set is defined as either tlbi(vmalls12e1) or tlbi(alle1).
+	 *
+	 * if el2 is enabled and stage 2 translation enabled, this may be
+	 * raised as a stage 2 abort. if el2 is enabled but stage 2 translation
+	 * disabled, or if el2 is disabled, it will be raised as a stage 1
+	 * abort.
+	 *
+	 * local_flush_tlb_all() does a tlbi(vmalle1), which is enough to
+	 * handle a stage 1 abort.
+	 */
+
+	local_flush_tlb_all();
+
+	return 0;
+}
+
 static const struct fault_info fault_info[] = {
 	{ do_bad,		SIGKILL, SI_KERNEL,	"ttbr address size fault"	},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"level 1 address size fault"	},
@@ -893,7 +918,7 @@ static const struct fault_info fault_info[] = {
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 45"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 46"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 47"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"TLB conflict abort"		},
+	{ do_conflict_abort,	SIGKILL, SI_KERNEL,	"TLB conflict abort"		},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"Unsupported atomic hardware update fault"	},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 50"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 51"			},
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index eb17f59e543c..4ee0fbb7765b 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -26,6 +26,7 @@ HAS_ECV
 HAS_ECV_CNTPOFF
 HAS_EPAN
 HAS_EVT
+HAS_BBML2
 HAS_FPMR
 HAS_FGT
 HAS_FPSIMD
-- 
2.45.2



From miko.lenczewski at arm.com  Wed Dec 11 07:45:06 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 15:45:06 +0000
Subject: [RFC PATCH v1 5/5] arm64/mm: Elide tlbi in contpte_convert() under BBML2
In-Reply-To: <20241211154611.40395-1-miko.lenczewski@arm.com>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
Message-ID: <20241211154611.40395-6-miko.lenczewski@arm.com>

If we support BBM level 2, we can potentially avoid an intermediate
TLB invalidation, as hardware is capable of managing the TLB itself
in this situation. Hardware will either silently clear out the
offending entry, or will take a TLB Conflict Abort Exception.

Note that such aborts should not occur on Arm hardware and indeed
were not seen on any of the benchmarked systems.

Eliding the invalidation results in a 12% improvement on a
microbenchmark which targeted the worst case of contpte_convert(), which
represents an 80% reduction in the overhead of contpte_convert().

Note also that this patch is pending review to ensure that it is
architecturally valid, and we are working with Arm architects to
validate this patch.

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 arch/arm64/mm/contpte.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index fc927be800ee..009690770415 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -72,9 +72,6 @@ static void contpte_convert(struct mm_struct *mm, unsigned long addr,
 		__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
 
 	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
-
-	if (system_supports_bbml2())
-		__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
 }
 
 void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
-- 
2.45.2



From robh at kernel.org  Wed Dec 11 07:47:13 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 09:47:13 -0600
Subject: [PATCH v4 2/7] dt-bindings: phy: samsung,usb3-drd-phy: gs101:
 require Type-C properties
In-Reply-To: <20241206-gs101-phy-lanes-orientation-phy-v4-2-f5961268b149@linaro.org>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
 <20241206-gs101-phy-lanes-orientation-phy-v4-2-f5961268b149@linaro.org>
Message-ID: <173393203254.3086087.14024716233496700566.robh@kernel.org>


On Fri, 06 Dec 2024 16:31:02 +0000, Andr? Draszik wrote:
> orientation-switch is the standard declaration to inform the Type-C mux
> layer that a remote-endpoint is capable of processing orientation
> change messages.
> 
> The USB PHY on gs101 needs to be configured based on the orientation of
> the connector. For that the DTS needs a link between the phy's port and
> a TCPCi, and we'll need to inform the phy driver that it should handle
> the orientation (register a handler).
> 
> Update the schema to enforce that by requiring the orientation-switch
> and port properties on gs101 (only). We disallow orientation-switch on
> all other supported platforms, since other versions of this phy (or its
> system integration) don't currently support or even need it.
> 
> Even though this new required gs101 property is an ABI break, the
> intention for the driver is to behave as before if it's missing
> (meaning for gs101 it will work in SS mode in one orientation only).
> Other platforms are not affected.
> 
> Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> 
> ---
> v3:
> * update as per Rob's suggestion (I hope :-)
> 
> v2:
> * squash original patches #2 and #3
> * actually disallow orientation-switch on !gs101 (not just optional) (Conor)
> * update commit message to clarify that the intention for the driver is
>   to work with old and new DTS (Conor)
> * collect tags
> 
> foo
> ---
>  Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From festevam at gmail.com  Wed Dec 11 07:59:00 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 11 Dec 2024 12:59:00 -0300
Subject: [PATCH v2 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241210-imx91tmu-v2-2-5032aad4d88e@nxp.com>
References: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com> <20241210-imx91tmu-v2-2-5032aad4d88e@nxp.com>
Message-ID: <CAOMZO5DC=Y=BU-MX0B_ecOBnkhbiUXXKDDYgn4-uhDNyihOXoA@mail.gmail.com>

On Tue, Dec 10, 2024 at 6:27?PM Frank Li <Frank.Li at nxp.com> wrote:

> +#define CTRL0                  0x0
> +
> +#define STAT0                  0x10
...
> +#define DATA0                  0x20

These generic short macro names can easily clash in the future.

It would be better to add a better namespace definition.

For example:

IMX91_THERMAL_CTRL0
IMX91_THERMAL_STAT0
IMX91_THERMAL_DATA0


From olteanv at gmail.com  Wed Dec 11 07:59:19 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Wed, 11 Dec 2024 17:59:19 +0200
Subject: [PATCH net-next 0/9] net: dsa: cleanup EEE (part 1)
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <20241211155919.rv3gglwnuuy4rn4y@skbuf>

On Tue, Dec 10, 2024 at 02:17:52PM +0000, Russell King (Oracle) wrote:
> Hi,
> 
> First part of DSA EEE cleanups.
> 
> Patch 1 removes a useless test that is always false. dp->pl will always
> be set for user ports, so !dp->pl in the EEE methods will always be
> false.
> 
> Patch 2 adds support for a new DSA support_eee() method, which tells
> DSA whether the DSA driver supports EEE, and thus whether the ethtool
> set_eee() and get_eee() methods should return -EOPNOTSUPP.
> 
> Patch 3 adds a trivial implementation for this new method which
> indicates that EEE is supported.
> 
> Patches 4..8 adds implementations for .supports_eee() to all drivers
> that support EEE in some form.
> 
> Patch 9 switches the core DSA code to require a .supports_eee()
> implementation if DSA is supported. Any DSA driver that doesn't
> implement this method after this patch will not support the ethtool
> EEE methods.
> 
> Part 2 will remove the (now) useless .get_mac_eee() DSA operation.

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From broonie at kernel.org  Wed Dec 11 07:48:10 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 15:48:10 +0000
Subject: [PATCH V2 01/46] arm64/sysreg: Update register fields for
 ID_AA64MMFR0_EL1
In-Reply-To: <20241210055311.780688-2-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-2-anshuman.khandual@arm.com>
Message-ID: <409a5ef5-5237-41d9-9cf6-274c010ab2d8@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:26AM +0530, Anshuman Khandual wrote:
> This updates ID_AA64MMFR0_EL1.FGT and ID_AA64MMFR0_EL1.PARANGE register
> fields as per the definitions based on DDI0601 2024-09.

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/20241211/94748d01/attachment.sig>

From robh at kernel.org  Wed Dec 11 07:54:39 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 09:54:39 -0600
Subject: [PATCH v2 0/2] Enable audio output for Genio 700 EVK board
In-Reply-To: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>
References: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>
Message-ID: <173393224281.3090994.9490420905071029981.robh@kernel.org>


On Tue, 10 Dec 2024 17:54:27 -0300, N?colas F. R. A. Prado wrote:
> This series enables audio output support for the Genio 700 EVK board.
> Patch 1 adds the missing #sound-dai-cells property in the MT6359 node as
> a prerequisite, and patch 2 describes the audio DT nodes to get audio
> output working on the two audio jacks, Earphone and Speaker, present on
> the board.
> 
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> ---
> Changes in v2:
> - Dropped merged/unnecessary patches (2, 3, 4)
> - Removed unnecessary mediatek,dai-link property
> - Link to v1: https://lore.kernel.org/r/20241205-genio700-audio-output-v1-0-0e955c78c29e at collabora.com
> 
> ---
> N?colas F. R. A. Prado (2):
>       arm64: dts: mt6359: Add #sound-dai-cells property
>       arm64: dts: mediatek: mt8390-genio-700-evk: Add sound output support
> 
>  arch/arm64/boot/dts/mediatek/mt6359.dtsi           |  1 +
>  .../boot/dts/mediatek/mt8390-genio-700-evk.dts     | 48 ++++++++++++++++++++++
>  2 files changed, 49 insertions(+)
> ---
> base-commit: d1486dca38afd08ca279ae94eb3a397f10737824
> change-id: 20241204-genio700-audio-output-fba8f2ebad10
> 
> Best regards,
> --
> N?colas F. R. A. Prado <nfraprado at collabora.com>
> 
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y mediatek/mt8390-genio-700-evk.dtb' for 20241210-genio700-audio-output-v2-0-c50886ae0be2 at collabora.com:

arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dtb: pmic: '#sound-dai-cells', 'mt6359codec', 'mt6359rtc' do not match any of the regexes: 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/mfd/mediatek,mt6397.yaml#
arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dtb: jpeg-decoder at 1a040000: iommus: [[124, 685], [124, 686], [124, 690], [124, 691], [124, 692], [124, 693]] is too long
	from schema $id: http://devicetree.org/schemas/media/mediatek-jpeg-decoder.yaml#







From robh at kernel.org  Wed Dec 11 07:54:43 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 09:54:43 -0600
Subject: [PATCH 00/15] ARM: zynq: Sync DTs with U-Boot
In-Reply-To: <cover.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
Message-ID: <173393224728.3091150.11085112233542602601.robh@kernel.org>


On Wed, 11 Dec 2024 13:41:19 +0100, Michal Simek wrote:
> Hi,
> 
> over years there were some changes pushed to U-Boot which were never merged
> back to Linux. U-Boot introduced new option OF_UPSTREAM and start to sync
> up DTs from Linux back to U-Boot.
> This series is addressing differences.
> There are still 3 more differences but they should be addressed separately.
> 
> Thanks,
> Michal
> 
> 
> Michal Simek (14):
>   ARM: zynq: Remove deprecated device_type property
>   ARM: zynq: DT: List OCM memory for all platforms
>   ARM: zynq: Mark boot-phase-specific device nodes
>   ARM: zynq: Do not define address/size-cells for nand-controller
>   ARM: zynq: Wire smcc with nand/nor memories on zc770 platform
>   ARM: zynq: Add ethernet phy reset information to DT(zc702)
>   ARM: zynq: Define u-boot bootscrip addr via DT
>   ARM: zynq: Point via nvmem0 alias to eeprom on zc702/zc706
>   ARM: zynq: Define rtc alias on zc702/zc706
>   ARM: zynq: Rename i2c?-gpio to i2c?-gpio-grp
>   ARM: zynq: Fix fpga region DT nodes name
>   ARM: zynq: Enable QSPIs on platforms
>   ARM: zynq: Add sdhci to alias node
>   ARM: zynq: Remove ethernet0 alias from Microzed
> 
> Sai Krishna Potthuri (1):
>   ARM: zynq: Replace 'io-standard' with 'power-source' property
> 
>  arch/arm/boot/dts/xilinx/zynq-7000.dtsi       | 33 ++++++-
>  arch/arm/boot/dts/xilinx/zynq-cc108.dts       | 41 ++++++++-
>  arch/arm/boot/dts/xilinx/zynq-microzed.dts    | 10 ++-
>  arch/arm/boot/dts/xilinx/zynq-parallella.dts  |  1 -
>  arch/arm/boot/dts/xilinx/zynq-zc702.dts       | 87 +++++++++++++------
>  arch/arm/boot/dts/xilinx/zynq-zc706.dts       | 67 +++++++++++---
>  arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts | 39 ++++++++-
>  arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts | 31 +++++++
>  arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts | 35 ++++++++
>  arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts | 41 ++++++++-
>  arch/arm/boot/dts/xilinx/zynq-zed.dts         | 43 ++++++++-
>  .../boot/dts/xilinx/zynq-zturn-common.dtsi    |  8 ++
>  arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts     | 10 ++-
>  arch/arm/boot/dts/xilinx/zynq-zybo.dts        |  9 +-
>  14 files changed, 404 insertions(+), 51 deletions(-)
> 
> --
> 2.43.0
> 
> 
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y xilinx/zynq-cc108.dtb xilinx/zynq-microzed.dtb xilinx/zynq-parallella.dtb xilinx/zynq-zc702.dtb xilinx/zynq-zc706.dtb xilinx/zynq-zc770-xm010.dtb xilinx/zynq-zc770-xm011.dtb xilinx/zynq-zc770-xm012.dtb xilinx/zynq-zc770-xm013.dtb xilinx/zynq-zed.dtb xilinx/zynq-zybo-z7.dtb xilinx/zynq-zybo.dtb' for cover.1733920873.git.michal.simek at amd.com:

arch/arm/boot/dts/xilinx/zynq-parallella.dtb: ethernet at e000b000: ethernet-phy at 0: Unevaluated properties are not allowed ('marvell,reg-init' was unexpected)
	from schema $id: http://devicetree.org/schemas/net/cdns,macb.yaml#
arch/arm/boot/dts/xilinx/zynq-zc702.dtb: ethernet at e000b000: Unevaluated properties are not allowed ('phy-reset-active-low', 'phy-reset-gpio' were unexpected)
	from schema $id: http://devicetree.org/schemas/net/cdns,macb.yaml#







From linux at armlinux.org.uk  Wed Dec 11 07:55:31 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 11 Dec 2024 15:55:31 +0000
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <20241211140402.yf7gMExr@linutronix.de>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-3-arnd@kernel.org>
 <20241211134811.wM_UADhQ@linutronix.de>
 <20241211140402.yf7gMExr@linutronix.de>
Message-ID: <Z1m18yn67dsJRVWA@shell.armlinux.org.uk>

On Wed, Dec 11, 2024 at 03:04:02PM +0100, Sebastian Andrzej Siewior wrote:
> On 2024-12-11 14:48:11 [+0100], To Arnd Bergmann wrote:
> > I guess if you have boxes with 4GiB+ and can proof that the performance
> > improves without HIGHPTE (since you don't have to map the page table).
> > The question is then how much of low mem has to be used instead and when
> > does it start to hurt.
> 
> Some numbers have been been documented in commit
>    14315592009c1 ("x86, mm: Allow highmem user page tables to be disabled at boot time")
> 
> and I would like cite:
> | We could probably handwave up an argument for a threshold at 16G of total
> | RAM.
> 
> which means HIGHPTE would make sense with >= 16GiB of memory.

However, there is more to consider.

32-bit Arm works out at the same for this:

    Assuming 768M of lowmem we have 196608 potential lowmem PTE
    pages. Each page can map 2M of RAM in a PAE-enabled configuration,
    meaning a maximum of 384G of RAM could potentially be mapped using
    lowmem PTEs.

because, presumably, x86 uses 8 bytes per PTE entry, whereas on Arm we
still use 4 bytes, but because we keep two copies of a PTE (one for
hardware, the other for the kernel) it works out that we're the same
there - one PTE page can also map 2M of RAM.

However, what is quite different is the L1 page tables. On x86,
everything is nice and easy, and each page table is one 4k page.
On 32-bit Arm, this is not the case - we need to grab a 16k page for
the L1, and the more immovable allocations we have in lowmem, the
harder it will be to satisfy this. Failing to grab a 16k page
leads to fork() failing and an unusable system.

So, we want to keep as many immovable allocations out of lowmem as
possible - which is an additional constraint x86 doesn't have, and
shouldn't be overlooked without ensuring that the probability of it
happening remains acceptably low.

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


From olteanv at gmail.com  Wed Dec 11 08:00:59 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Wed, 11 Dec 2024 18:00:59 +0200
Subject: [PATCH net-next 0/9] net: dsa: cleanup EEE (part 1)
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <20241211160059.ypcydtoenlfc2wog@skbuf>

On Tue, Dec 10, 2024 at 02:17:52PM +0000, Russell King (Oracle) wrote:
> Part 2 will remove the (now) useless .get_mac_eee() DSA operation.

Thanks for the work. For part 2, could you also include changes to
Documentation/networking/dsa/ to explain the new usage pattern?


From miko.lenczewski at arm.com  Wed Dec 11 08:01:40 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 16:01:40 +0000
Subject: [RESEND RFC PATCH v1 4/5] arm64/mm: Delay tlbi in contpte_convert() under BBML2
In-Reply-To: <20241211160218.41404-1-miko.lenczewski@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
Message-ID: <20241211160218.41404-5-miko.lenczewski@arm.com>

When converting a region via contpte_convert() to use mTHP, we have two
different goals. We have to mark each entry as contiguous, and we would
like to smear the dirty and young (access) bits across all entries in
the contiguous block. Currently, we do this by first accumulating the
dirty and young bits in the block, using an atomic
__ptep_get_and_clear() and the relevant pte_{dirty,young}() calls,
performing a tlbi, and finally smearing the correct bits across the
block using __set_ptes().

This approach works fine for BBM level 0, but with support for BBM level
2 we are allowed to reorder the tlbi to after setting the pagetable
entries. This reordering means that other threads will not see an
invalid pagetable entry, instead operating on stale data, until we have
performed our smearing and issued the invalidation. Avoiding this
invalid entry reduces faults in other threads, and thus improves
performance marginally (more so when there are more threads).

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 arch/arm64/mm/contpte.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 55107d27d3f8..fc927be800ee 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -68,9 +68,13 @@ static void contpte_convert(struct mm_struct *mm, unsigned long addr,
 			pte = pte_mkyoung(pte);
 	}
 
-	__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
+	if (!system_supports_bbml2())
+		__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
 
 	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
+
+	if (system_supports_bbml2())
+		__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
 }
 
 void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
-- 
2.45.2



From miko.lenczewski at arm.com  Wed Dec 11 08:01:41 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 16:01:41 +0000
Subject: [RESEND RFC PATCH v1 5/5] arm64/mm: Elide tlbi in contpte_convert() under BBML2
In-Reply-To: <20241211160218.41404-1-miko.lenczewski@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
Message-ID: <20241211160218.41404-6-miko.lenczewski@arm.com>

If we support BBM level 2, we can potentially avoid an intermediate
TLB invalidation, as hardware is capable of managing the TLB itself
in this situation. Hardware will either silently clear out the
offending entry, or will take a TLB Conflict Abort Exception.

Note that such aborts should not occur on Arm hardware and indeed
were not seen on any of the benchmarked systems.

Eliding the invalidation results in a 12% improvement on a
microbenchmark which targeted the worst case of contpte_convert(), which
represents an 80% reduction in the overhead of contpte_convert().

Note also that this patch is pending review to ensure that it is
architecturally valid, and we are working with Arm architects to
validate this patch.

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 arch/arm64/mm/contpte.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index fc927be800ee..009690770415 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -72,9 +72,6 @@ static void contpte_convert(struct mm_struct *mm, unsigned long addr,
 		__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
 
 	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
-
-	if (system_supports_bbml2())
-		__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
 }
 
 void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
-- 
2.45.2



From miko.lenczewski at arm.com  Wed Dec 11 08:01:36 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 16:01:36 +0000
Subject: [RESEND RFC PATCH v1 0/5] Initial BBML2 support for contpte_convert()
Message-ID: <20241211160218.41404-1-miko.lenczewski@arm.com>

Resending as had wrong address for linux-doc and kvmarm. Apologies for
spam.

Hi All,

This patch series seeks to gather feedback on adding initial support
for level 2 of the Break-Before-Make arm64 architectural feature,
specifically to contpte_convert().

This support reorders a TLB invalidation in contpte_convert(), and
optionally elides said invalidation completely which leads to a 12%
improvement when executing a microbenchmark designed to force the
pathological path where contpte_convert() gets called. This
represents an 80% reduction in the cost of calling contpte_convert().

However, the elision of the invalidation is still pending review to
ensure it is architecturally valid. Without it, the reodering also
represents a performance improvement due to reducing thread contention,
as there is a smaller time window for racing threads to see an invalid
pagetable entry (especially if they already have a cached entry in their
TLB that they are working off of).

This series is based on v6.13-rc2 (fac04efc5c79).

Break-Before-Make Level 2
=========================

Break-Before-Make (BBM) sequences ensure a consistent view of the
page tables. They avoid TLB multi-hits and ensure atomicity and
ordering guarantees. BBM level 0 simply defines the current use
of page tables. When you want to change certain bits in a pte,
you need to:

- clear the pte
- dsb()
- issue a tlbi for the pte
- dsb()
- repaint the pte
- dsb()

When changing block size, or toggling the contiguous bit, we
currently use this BBM level 0 sequence. With BBM level 2 support,
however, we can relax the BBM sequence and benefit from a performance
improvement. The hardware would then either automatically handle the
TLB invalidations, or would take a TLB Conflict Abort Exception.

This exception can either be a stage 1 or stage 2 exception, depending
on whether stage 1 or stage 2 translations are in use. The architecture
currently mandates a worst-case invalidation of vmalle1 or vmalls12e1,
when stage 2 translation is not in-use and in-use respectively.

Outstanding Questions and Remaining TODOs
=========================================

Patch 4 moves the tlbi so that the window where the pte is invalid is
significantly smaller. This reduces the chances of racing threads
accessing the memory during the window and taking a fault. This is
confirmed to be architecturally sound.

Patch 5 removes the tlbi entirely. This has the benefit of
significantly reducing the cost of contpte_convert(). While testing
has demonstrated that this works as expected on Arm-designed CPUs, we
are still in the process of confirming whether it is architecturally
correct. I am requesting review while that process is on-going. Patch 5
would be dropped if it turns out to be architecturally unsound.

Another note is that the stage 2 TLB conflict handling is included as
patch 1 of this series. This patch could (and probably should) be sent
separately as it may be useful outside this series, but is included for
reference.

Thanks,
Miko

Miko?aj Lenczewski (5):
  arm64: Add TLB Conflict Abort Exception handler to KVM
  arm64: Add BBM Level 2 cpu feature
  arm64: Add errata and workarounds for systems with broken BBML2
  arm64/mm: Delay tlbi in contpte_convert() under BBML2
  arm64/mm: Elide tlbi in contpte_convert() under BBML2

 Documentation/arch/arm64/silicon-errata.rst |  32 ++++
 arch/arm64/Kconfig                          | 164 ++++++++++++++++++++
 arch/arm64/include/asm/cpufeature.h         |  14 ++
 arch/arm64/include/asm/esr.h                |   8 +
 arch/arm64/kernel/cpufeature.c              |  37 +++++
 arch/arm64/kvm/mmu.c                        |   6 +
 arch/arm64/mm/contpte.c                     |   3 +-
 arch/arm64/mm/fault.c                       |  27 +++-
 arch/arm64/tools/cpucaps                    |   1 +
 9 files changed, 290 insertions(+), 2 deletions(-)

-- 
2.45.2



From miko.lenczewski at arm.com  Wed Dec 11 08:01:37 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 16:01:37 +0000
Subject: [RESEND RFC PATCH v1 1/5] arm64: Add TLB Conflict Abort Exception handler to KVM
In-Reply-To: <20241211160218.41404-1-miko.lenczewski@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
Message-ID: <20241211160218.41404-2-miko.lenczewski@arm.com>

Currently, KVM does not handle the case of a stage 2 TLB conflict abort
exception. The Arm ARM specifies that the worst-case handling of such an
exception requires a `tlbi vmalls12e1`. Perform such an invalidation
when this exception is encountered.

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 arch/arm64/include/asm/esr.h | 8 ++++++++
 arch/arm64/kvm/mmu.c         | 6 ++++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d1b1a33f9a8b..8a66f81ca291 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -121,6 +121,7 @@
 #define ESR_ELx_FSC_SEA_TTW(n)	(0x14 + (n))
 #define ESR_ELx_FSC_SECC	(0x18)
 #define ESR_ELx_FSC_SECC_TTW(n)	(0x1c + (n))
+#define ESR_ELx_FSC_TLBABT	(0x30)
 
 /* Status codes for individual page table levels */
 #define ESR_ELx_FSC_ACCESS_L(n)	(ESR_ELx_FSC_ACCESS + (n))
@@ -464,6 +465,13 @@ static inline bool esr_fsc_is_access_flag_fault(unsigned long esr)
 	       (esr == ESR_ELx_FSC_ACCESS_L(0));
 }
 
+static inline bool esr_fsc_is_tlb_conflict_abort(unsigned long esr)
+{
+	esr = esr & ESR_ELx_FSC;
+
+	return esr == ESR_ELx_FSC_TLBABT;
+}
+
 /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */
 static inline bool esr_iss_is_eretax(unsigned long esr)
 {
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index c9d46ad57e52..c8c6f5a97a1b 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1756,6 +1756,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 	ipa = fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
 	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
 
+	if (esr_fsc_is_tlb_conflict_abort(esr)) {
+		// does a `tlbi vmalls12e1is`
+		__kvm_tlb_flush_vmid(&vcpu->kvm->arch.mmu);
+		return 1;
+	}
+
 	if (esr_fsc_is_translation_fault(esr)) {
 		/* Beyond sanitised PARange (which is the IPA limit) */
 		if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit())) {
-- 
2.45.2



From miko.lenczewski at arm.com  Wed Dec 11 08:01:38 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 16:01:38 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <20241211160218.41404-1-miko.lenczewski@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
Message-ID: <20241211160218.41404-3-miko.lenczewski@arm.com>

The Break-Before-Make cpu feature supports multiple levels (levels 0-2),
and this commit adds a dedicated BBML2 cpufeature to test against
support for.

In supporting BBM level 2, we open ourselves up to potential TLB
Conflict Abort Exceptions during expected execution, instead of only
in exceptional circumstances. In the case of an abort, it is
implementation defined at what stage the abort is generated, and
the minimal set of required invalidations is also implementation
defined. The maximal set of invalidations is to do a `tlbi vmalle1`
or `tlbi vmalls12e1`, depending on the stage.

Such aborts should not occur on Arm hardware, and were not seen in
benchmarked systems, so unless performance concerns arise, implementing
the abort handlers with the worst-case invalidations seems like an
alright hack.

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 arch/arm64/include/asm/cpufeature.h | 14 ++++++++++++++
 arch/arm64/kernel/cpufeature.c      |  7 +++++++
 arch/arm64/mm/fault.c               | 27 ++++++++++++++++++++++++++-
 arch/arm64/tools/cpucaps            |  1 +
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 8b4e5a3cd24c..a9f2ac335392 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -866,6 +866,20 @@ static __always_inline bool system_supports_mpam_hcr(void)
 	return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
 }
 
+static inline bool system_supports_bbml2(void)
+{
+	/* currently, BBM is only relied on by code touching the userspace page
+	 * tables, and as such we are guaranteed that caps have been finalised.
+	 *
+	 * if later we want to use BBM for kernel mappings, particularly early
+	 * in the kernel, this may return 0 even if BBML2 is actually supported,
+	 * which means unnecessary break-before-make sequences, but is still
+	 * correct
+	 */
+
+	return alternative_has_cap_unlikely(ARM64_HAS_BBML2);
+}
+
 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 6ce71f444ed8..7cc94bd5da24 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2917,6 +2917,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP)
 	},
+	{
+		.desc = "BBM Level 2 Support",
+		.capability = ARM64_HAS_BBML2,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_cpuid_feature,
+		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, BBM, 2)
+	},
 	{
 		.desc = "52-bit Virtual Addressing for KVM (LPA2)",
 		.capability = ARM64_HAS_LPA2,
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index ef63651099a9..dc119358cbc1 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -844,6 +844,31 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
 	return 0;
 }
 
+static int do_conflict_abort(unsigned long far, unsigned long esr,
+			     struct pt_regs *regs)
+{
+	if (!system_supports_bbml2())
+		return do_bad(far, esr, regs);
+
+	/* if we receive a TLB conflict abort, we know that there are multiple
+	 * TLB entries that translate the same address range. the minimum set
+	 * of invalidations to clear these entries is implementation defined.
+	 * the maximum set is defined as either tlbi(vmalls12e1) or tlbi(alle1).
+	 *
+	 * if el2 is enabled and stage 2 translation enabled, this may be
+	 * raised as a stage 2 abort. if el2 is enabled but stage 2 translation
+	 * disabled, or if el2 is disabled, it will be raised as a stage 1
+	 * abort.
+	 *
+	 * local_flush_tlb_all() does a tlbi(vmalle1), which is enough to
+	 * handle a stage 1 abort.
+	 */
+
+	local_flush_tlb_all();
+
+	return 0;
+}
+
 static const struct fault_info fault_info[] = {
 	{ do_bad,		SIGKILL, SI_KERNEL,	"ttbr address size fault"	},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"level 1 address size fault"	},
@@ -893,7 +918,7 @@ static const struct fault_info fault_info[] = {
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 45"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 46"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 47"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"TLB conflict abort"		},
+	{ do_conflict_abort,	SIGKILL, SI_KERNEL,	"TLB conflict abort"		},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"Unsupported atomic hardware update fault"	},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 50"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 51"			},
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index eb17f59e543c..4ee0fbb7765b 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -26,6 +26,7 @@ HAS_ECV
 HAS_ECV_CNTPOFF
 HAS_EPAN
 HAS_EVT
+HAS_BBML2
 HAS_FPMR
 HAS_FGT
 HAS_FPSIMD
-- 
2.45.2



From miko.lenczewski at arm.com  Wed Dec 11 08:01:39 2024
From: miko.lenczewski at arm.com (=?UTF-8?q?Miko=C5=82aj=20Lenczewski?=)
Date: Wed, 11 Dec 2024 16:01:39 +0000
Subject: [RESEND RFC PATCH v1 3/5] arm64: Add errata and workarounds for systems with broken BBML2
In-Reply-To: <20241211160218.41404-1-miko.lenczewski@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
Message-ID: <20241211160218.41404-4-miko.lenczewski@arm.com>

There are systems which claim support for BBML2, but whose
implementation of this support is broken. Add a Kconfig erratum for each
of these systems, and a cpufeature workaround that forces the supported
BBM level on these systems to 0.

Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
---
 Documentation/arch/arm64/silicon-errata.rst |  32 ++++
 arch/arm64/Kconfig                          | 164 ++++++++++++++++++++
 arch/arm64/kernel/cpufeature.c              |  32 +++-
 3 files changed, 227 insertions(+), 1 deletion(-)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index b42fea07c5ce..4b4c1dd9b671 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -126,16 +126,26 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A76      | #3324349        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A76      | #3696297        | ARM64_ERRATUM_3696297       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #1491015        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #1508412        | ARM64_ERRATUM_1508412       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #3324348        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A77      | #3696294        | ARM64_ERRATUM_3696294       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A78      | #3324344        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A78      | #3696287        | ARM64_ERRATUM_3696287       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A78C     | #3324346,3324347| ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A78C     | #3696291        | ARM64_ERRATUM_3696291       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A78C     | #3696292        | ARM64_ERRATUM_3696292       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2119858        | ARM64_ERRATUM_2119858       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2054223        | ARM64_ERRATUM_2054223       |
@@ -144,6 +154,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #3324338        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A710     | #3696244        | ARM64_ERRATUM_3696244       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A715     | #2645198        | ARM64_ERRATUM_2645198       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A715     | #3456084        | ARM64_ERRATUM_3194386       |
@@ -156,6 +168,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X1       | #3324344        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X1       | #3696287        | ARM64_ERRATUM_3696287       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X1C      | #3324346        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X2       | #2119858        | ARM64_ERRATUM_2119858       |
@@ -164,10 +178,18 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X2       | #3324338        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X2       | #3696244        | ARM64_ERRATUM_3696244       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X3       | #3324335        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X3       | #3696239        | ARM64_ERRATUM_3696239       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X4       | #3043263        | ARM64_ERRATUM_3043263       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X4       | #3194386        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X925     | #3056274        | ARM64_ERRATUM_3056274       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X925     | #3324334        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N1     | #1188873,1418040| ARM64_ERRATUM_1418040       |
@@ -180,6 +202,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N1     | #3324349        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-N1     | #3696297        | ARM64_ERRATUM_3696297       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N2     | #2139208        | ARM64_ERRATUM_2139208       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N2     | #2067961        | ARM64_ERRATUM_2067961       |
@@ -188,14 +212,22 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N2     | #3324339        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-N2     | #3696250        | ARM64_ERRATUM_3696250       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N3     | #3456111        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V1     | #1619801        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V1     | #3324341        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-V1     | #3696285        | ARM64_ERRATUM_3696285       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V2     | #3324336        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-V2     | #3696242        | ARM64_ERRATUM_3696242       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-V3     | #3053180        | ARM64_ERRATUM_3053180       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V3     | #3312417        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | MMU-500         | #841119,826419  | N/A                         |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..9ef8418e8410 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1127,6 +1127,170 @@ config ARM64_ERRATUM_3194386
 
 	  If unsure, say Y.
 
+config ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	bool
+
+config ARM64_ERRATUM_3696250
+	bool "Neoverse-N2: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Neoverse-N2 cores (r0p0, r0p1, r0p2, r0p3) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696244
+	bool "Cortex-A710/Cortex-X2: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-A710 and Cortex-X2 cores (r0p0, r1p0, r2p0, r2p1)
+	  declare break-before-make level 2 support, but changing the block
+	  size without utilising a break-before-make sequence, or
+	  mis-programming the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696297
+	bool "Cortex-A76/Neoverse-N1: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  This option adds a workaround for ARM Cortex-A76/Neoverse-N1 erratum
+	  3696297.
+
+	  Affected Cortex-A76 and Neoverse-N1 cores (r0p0, r1p0, r2p0, r3p0,
+	  r3p1, r4p0, r4p1) declare break-before-make level 2 support, but
+	  changing the block size without utilising a break-before-make sequence,
+	  or mis-programming the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696294
+	bool "Cortex-A77: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  This option adds a workaround for ARM Cortex-A77 erratum 3696294.
+
+	  Affected Cortex-A77 cores (r0p0, r1p0, r1p1) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696239
+	bool "Cortex-X3: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-X3 cores (r0p0, r1p0, r1p1, r1p2) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696242
+	bool "Neoverse-V2: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Neoverse-V2 cores (r0p0, r0p1, r0p2) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696285
+	bool "Neoverse-V1: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Neoverse-V1 cores (r0p0, r1p0, r1p1, r1p2) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696287
+	bool "Cortex-A78/Cortex-X1: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-A78 and Cortex-X1 cores (r0p0, r1p0, r1p1, r1p2)
+	  declare break-before-make level 2 support, but changing the block
+	  size without utilising a break-before-make sequence, or
+	  mis-programming the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696291
+	bool "Cortex-A78C: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-A78C cores (r0p0, r0p1, r0p2) declare
+	  break-before-make level 2 support, but changing the block size
+	  without utilising a break-before-make sequence, or mis-programming
+	  the contiguous hint bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3696292
+	bool "Cortex-A78C: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-A78C cores (r0p1, r0p2) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3056274
+	bool "Cortex-X925: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-X925 cores (r0p0, r0p1) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3043263
+	bool "Cortex-X4: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Cortex-X4 cores (r0p0, r0p1, r0p2) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
+config ARM64_ERRATUM_3053180
+	bool "Neoverse-V3: workaround for broken BBM level 2 support"
+	default y
+	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
+	help
+	  Affected Neoverse-V3 cores (r0p0, r0p1) declare break-before-make
+	  level 2 support, but changing the block size without utilising a
+	  break-before-make sequence, or mis-programming the contiguous hint
+	  bit can lead to a livelock.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 7cc94bd5da24..e6c05b330e0f 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2167,6 +2167,36 @@ static bool hvhe_possible(const struct arm64_cpu_capabilities *entry,
 	return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_HVHE);
 }
 
+static bool has_bbml2(const struct arm64_cpu_capabilities *entry,
+		      int scope)
+{
+	if (IS_ENABLED(CONFIG_ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT)) {
+		static const struct midr_range broken_bbml2_list[] = {
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
+			MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
+			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
+			{}
+		};
+
+		if (is_midr_in_range_list(read_cpuid_id(), broken_bbml2_list))
+			return false;
+	}
+
+	return has_cpuid_feature(entry, scope);
+}
+
 #ifdef CONFIG_ARM64_PAN
 static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused)
 {
@@ -2921,7 +2951,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.desc = "BBM Level 2 Support",
 		.capability = ARM64_HAS_BBML2,
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
-		.matches = has_cpuid_feature,
+		.matches = has_bbml2,
 		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, BBM, 2)
 	},
 	{
-- 
2.45.2



From robh at kernel.org  Wed Dec 11 08:16:27 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 10:16:27 -0600
Subject: [PATCH v3 04/13] dt-bindings: serial: atmel,at91-usart: add
 microchip,sama7d65-usart
In-Reply-To: <05baeeda872ab06d4d84718c535453b787740876.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <05baeeda872ab06d4d84718c535453b787740876.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <173393378758.3240340.14434192091992606298.robh@kernel.org>


On Fri, 06 Dec 2024 12:59:49 -0700, Ryan.Wanner at microchip.com wrote:
> From: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Add SAMA7D65 USART compatible to DT bindings documentation.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---
>  Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From robh at kernel.org  Wed Dec 11 08:16:05 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 10:16:05 -0600
Subject: [PATCH v3 03/13] dt-bindings: atmel-sysreg: add sama7d65 RAM and
 PIT
In-Reply-To: <96e64f01eee264ad0ac4c720a7a1cab4f95c206b.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <96e64f01eee264ad0ac4c720a7a1cab4f95c206b.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <173393376441.3234883.1609232326529788470.robh@kernel.org>


On Fri, 06 Dec 2024 12:59:48 -0700, Ryan.Wanner at microchip.com wrote:
> From: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Add SAMA7D65 RAM controller, PIT64 DT bindings.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---
>  .../devicetree/bindings/arm/atmel-sysregs.txt      | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From robh at kernel.org  Wed Dec 11 08:16:45 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 10:16:45 -0600
Subject: [PATCH v3 05/13] dt-bindings: pinctrl: at91-pio4: add
 microchip,sama7d65-pinctrl
In-Reply-To: <b41307089b72fd92f8e2d314e4750194df9c888a.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <b41307089b72fd92f8e2d314e4750194df9c888a.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <173393380185.3240760.14016997587827186442.robh@kernel.org>


On Fri, 06 Dec 2024 12:59:50 -0700, Ryan.Wanner at microchip.com wrote:
> From: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Add pinctrl bindings for microchip sama7d65 SoC.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---
>  .../devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt      | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From broonie at kernel.org  Wed Dec 11 08:28:17 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Dec 2024 16:28:17 +0000
Subject: [PATCH V2 02/46] arm64/sysreg: Update register fields for
 ID_AA64MMFR4_EL1
In-Reply-To: <20241210055311.780688-3-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-3-anshuman.khandual@arm.com>
Message-ID: <f27091f1-879a-4434-8124-2d1e27241078@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:27AM +0530, Anshuman Khandual wrote:
> This updates ID_AA64MMFR4_EL1 register as per the definitions based on
> DDI0601 2024-09.

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/20241211/2385e7c9/attachment.sig>

From festevam at gmail.com  Wed Dec 11 08:29:39 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 11 Dec 2024 13:29:39 -0300
Subject: [PATCH v2 1/2] dt-bindings: display: panel-lvds: Add compatible
 for AUO G084SN05 V9
In-Reply-To: <yujvdu3s6v7z7th2lrdscqfxocx2zy2u4owakisvnjppz2udqv@5ok2rcf4exd4>
References: <20241210105705.116116-1-festevam@gmail.com> <yujvdu3s6v7z7th2lrdscqfxocx2zy2u4owakisvnjppz2udqv@5ok2rcf4exd4>
Message-ID: <CAOMZO5B3810+4RJsPUtL3ASxqpDd+UmC=GcY6t8-ad7NZXZLjQ@mail.gmail.com>

Hi Neil,

On Wed, Dec 11, 2024 at 6:31?AM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On Tue, Dec 10, 2024 at 07:57:04AM -0300, Fabio Estevam wrote:
> > From: Fabio Estevam <festevam at denx.de>
> >
> > The AUO G084SN05 V9 is an 8.4" 800x600 LVDS display.
> >
> > Add a compatible entry for this LVDS display model.
> >
> > Signed-off-by: Fabio Estevam <festevam at denx.de>
> > ---
> > Changes since v1:
> > - Added devicetree at vger.kernel.org on Cc.
> >
> >  Documentation/devicetree/bindings/display/panel/panel-lvds.yaml | 2 ++
> >  1 file changed, 2 insertions(+)
>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Would it be OK for you if Shawn applies both patches via his i.MX ARM tree?


From ivo.ivanov.ivanov1 at gmail.com  Wed Dec 11 08:29:41 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Wed, 11 Dec 2024 18:29:41 +0200
Subject: [PATCH v2 0/1] arm64: dts: exynos8895: Add m2-pmu, poweroff and reboot
Message-ID: <20241211162942.450525-1-ivo.ivanov.ivanov1@gmail.com>

Hey folks,

This series adds support for the mongoose cluster PMU in DT hence
a compatible for that was recently added.

After this patchset, I'm planning to submit patches for more hardware
support.

Kind regards,
Ivo.

Changes since v2:
 - Dropped the poweroff and reboot patch, since it works as-is with the
   included dtsi.

Ivaylo Ivanov (1):
  arm64: dts: exynos8895: Add a PMU node for the second cluster

 arch/arm64/boot/dts/exynos/exynos8895.dtsi | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

-- 
2.43.0



From ivo.ivanov.ivanov1 at gmail.com  Wed Dec 11 08:29:42 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Wed, 11 Dec 2024 18:29:42 +0200
Subject: [PATCH v2 1/1] arm64: dts: exynos8895: Add a PMU node for the second cluster
In-Reply-To: <20241211162942.450525-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241211162942.450525-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <20241211162942.450525-2-ivo.ivanov.ivanov1@gmail.com>

Since we have a PMU compatible for Samsung's Mongoose cores now, drop
the comment that explains the lack of it and define the node.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
---
 arch/arm64/boot/dts/exynos/exynos8895.dtsi | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos8895.dtsi b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
index ee393f4f0..90b318b2f 100644
--- a/arch/arm64/boot/dts/exynos/exynos8895.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
@@ -38,7 +38,17 @@ arm-a53-pmu {
 				     <&cpu3>;
 	};
 
-	/* There's no PMU model for the Mongoose cores */
+	mongoose-m2-pmu {
+		compatible = "samsung,mongoose-pmu";
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu4>,
+				     <&cpu5>,
+				     <&cpu6>,
+				     <&cpu7>;
+	};
 
 	cpus {
 		#address-cells = <1>;
-- 
2.43.0



From Frank.li at nxp.com  Wed Dec 11 08:30:51 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 11:30:51 -0500
Subject: [PATCH v2 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241211154622.f2jwwrqansk6il3o@pengutronix.de>
References: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
 <20241210-imx91tmu-v2-2-5032aad4d88e@nxp.com>
 <20241211154622.f2jwwrqansk6il3o@pengutronix.de>
Message-ID: <Z1m+O1UV4HD+7Rr2@lizhi-Precision-Tower-5810>

On Wed, Dec 11, 2024 at 04:46:22PM +0100, Marco Felsch wrote:
> On 24-12-10, Frank Li wrote:
> > From: Pengfei Li <pengfei.li_1 at nxp.com>
> >
> > Introduce support for the i.MX91 thermal monitoring unit, which features a
> > single sensor for the CPU. The register layout differs from other chips,
> > necessitating the creation of a dedicated file for this.
> >
> > Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > change from v1 to v2
> > - use low case for hexvalue
> > - combine struct imx91_tmu and tmu_sensor
> > - simplify imx91_tmu_start() and imx91_tmu_enable()
> > - use s16 for imx91_tmu_get_temp(), which may negative value
> > - use reverse christmas tree style
> > - use run time pm
> > - use oneshot to sample temp
> > - register thermal zone after hardware init
> > ---
> >  drivers/thermal/Kconfig         |  10 ++
> >  drivers/thermal/Makefile        |   1 +
> >  drivers/thermal/imx91_thermal.c | 265 ++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 276 insertions(+)
> >
> > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > index d3f9686e26e71..da403ed86aeb1 100644
> > --- a/drivers/thermal/Kconfig
> > +++ b/drivers/thermal/Kconfig
> > @@ -296,6 +296,16 @@ config IMX8MM_THERMAL
> >  	  cpufreq is used as the cooling device to throttle CPUs when the passive
> >  	  trip is crossed.
> >
> > +config IMX91_THERMAL
> > +	tristate "Temperature sensor driver for NXP i.MX91 SoC"
> > +	depends on ARCH_MXC || COMPILE_TEST
> > +	depends on OF
> > +	help
> > +	  Support for Temperature sensor found on NXP i.MX91 SoC.
> > +	  It supports one critical trip point and one passive trip point. The
> > +	  cpufreq is used as the cooling device to throttle CPUs when the passive
> > +	  trip is crossed.
> > +
> >  config K3_THERMAL
> >  	tristate "Texas Instruments K3 thermal support"
> >  	depends on ARCH_K3 || COMPILE_TEST
> > diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> > index 9abf43a74f2bb..08da241e6a598 100644
> > --- a/drivers/thermal/Makefile
> > +++ b/drivers/thermal/Makefile
> > @@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
> >  obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
> >  obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
> >  obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
> > +obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
> >  obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
> >  obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
> >  obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
> > diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
> > new file mode 100644
> > index 0000000000000..ebb59eda92951
> > --- /dev/null
> > +++ b/drivers/thermal/imx91_thermal.c
> > @@ -0,0 +1,265 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2024 NXP.
> > + */
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/clk.h>
> > +#include <linux/err.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/nvmem-consumer.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/thermal.h>
> > +
> > +#define CTRL0			0x0
>
> Unused
>
> > +
> > +#define STAT0			0x10
> > +#define STAT0_DRDY0_IF_MASK	BIT(16)
> > +
> > +#define DATA0			0x20
> > +
> > +#define THR_CTRL01		0x30
> > +#define THR_CTRL23		0x40
>
> Both are unused too
>
> > +#define CTRL1			0x200
>
> Unused
>
> > +#define CTRL1_SET		0x204
> > +#define CTRL1_CLR		0x208
> > +#define CTRL1_EN		BIT(31)
> > +#define CTRL1_START		BIT(30)
> > +#define CTRL1_STOP		BIT(29)
> > +#define CTRL1_RES_MASK		GENMASK(19, 18)
> > +#define CTRL1_MEAS_MODE_MASK	GENMASK(25, 24)
> > +#define   CTRL1_MEAS_MODE_SINGLE	0
> > +#define   CTRL1_MEAS_MODE_CONTINUES	1
> > +#define   CTRL1_MEAS_MODE_PERIODIC	2
> > +
> > +#define REF_DIV			0x280
> > +#define DIV_EN			BIT(31)
> > +#define DIV_MASK		GENMASK(23, 16)
> > +
> > +#define PUD_ST_CTRL		0x2B0
> > +#define PUDL_MASK		GENMASK(23, 16)
> > +
> > +#define TRIM1			0x2E0
> > +#define TRIM2			0x2F0
> 					^
> 				still upper-case
>
> > +#define TMU_TEMP_LOW_LIMIT	-40000
> > +#define TMU_TEMP_HIGH_LIMIT	125000
> > +
> > +#define DEFAULT_TRIM1_CONFIG 0xb561bc2d
> > +#define DEFAULT_TRIM2_CONFIG 0x65d4
> > +
> > +struct imx91_tmu {
> > +	void __iomem *base;
> > +	struct clk *clk;
> > +	struct device *dev;
> > +	struct thermal_zone_device *tzd;
> > +};
> > +
> > +static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
> > +{
> > +	u32 val = start ? CTRL1_START : CTRL1_STOP;
> > +
> > +	writel_relaxed(val, tmu->base + CTRL1_SET);
> > +}
> > +
> > +static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
> > +{
> > +	u32 reg = enable ? CTRL1_SET : CTRL1_CLR;
> > +
> > +	writel_relaxed(CTRL1_EN, tmu->base + reg);
> > +}
> > +
> > +static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
> > +{
> > +	struct imx91_tmu *tmu = thermal_zone_device_priv(tz);
> > +	s16 data;
> > +	int ret;
> > +	u32 val;
> > +
> > +	ret = pm_runtime_resume_and_get(tmu->dev);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	ret = readl_relaxed_poll_timeout(tmu->base + STAT0, val,
> > +					 val & STAT0_DRDY0_IF_MASK, 1000,
> > +					 40000);
> > +	if (ret)
> > +		return -EAGAIN;
> 		 ^
> Missing pm_runtime_put(). Instead goto out;
>
> > +
> > +	/* DATA0 is 16bit signed number */
> > +	data = readw_relaxed(tmu->base + DATA0);
> > +	*temp = data * 1000 / 64;
> > +	if (*temp < TMU_TEMP_LOW_LIMIT || *temp > TMU_TEMP_HIGH_LIMIT)
> > +		return -EAGAIN;
> 			^
> 		ret = -EAGAIN;
> 		goto out;
>
> out:
> > +
> > +	pm_runtime_put(tmu->dev);
> > +
> > +	return 0;
>
> 	return ret;
> > +}
> > +
> > +static struct thermal_zone_device_ops tmu_tz_ops = {
> > +	.get_temp = imx91_tmu_get_temp,
> > +};
> > +
> > +static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
> > +{
> > +	struct device *dev = tmu->dev;
> > +	u32 trim1, trim2;
> > +	int ret;
> > +
> > +	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (trim1 == 0 || trim2 == 0)
> > +		return -EINVAL;
> > +
> > +	writel_relaxed(trim1, tmu->base + TRIM1);
> > +	writel_relaxed(trim2, tmu->base + TRIM2);
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx91_tmu_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
>
> Since you already have the dev pointer, you can make use of it...
>
> > +	struct imx91_tmu *tmu;
> > +	unsigned long rate;
> > +	u32 div;
> > +	int ret;
> > +
> > +	tmu = devm_kzalloc(&pdev->dev, sizeof(struct imx91_tmu), GFP_KERNEL);
> 				^
> 				here
> > +	if (!tmu)
> > +		return -ENOMEM;
> > +
> > +	tmu->dev = &pdev->dev;
>
> 	and here
>
> > +
> > +	tmu->base = devm_platform_ioremap_resource(pdev, 0);
> > +	if (IS_ERR(tmu->base))
> > +		return PTR_ERR(tmu->base);
> 			^
> 		dev_err_probe();
>
> > +
> > +	tmu->clk = devm_clk_get_enabled(dev, NULL);
> > +	if (IS_ERR(tmu->clk))
> > +		return dev_err_probe(dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
> > +
> > +	platform_set_drvdata(pdev, tmu);
> > +
> > +	/* disable the monitor during initialization */
> > +	imx91_tmu_enable(tmu, false);
> > +	imx91_tmu_start(tmu, false);
>
> No need to disable it here since both bits (ENABLE and START) are 0
> after a reset.

Maybe uboot enable it. We can't depend on reset value without really set
hardware reset bit.

>
> > +	ret = imx91_init_from_nvmem_cells(tmu);
> > +	if (ret) {
> > +		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
> > +		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
> 			^
> Can you please anwer if _relaxed API is sufficient? I don't know why you
> making use of the _relaxed API here anyway. We have only a few MMIO
> accesses here, so why can't we use the writel() instead? This applies to
> the whole driver.

There are not big difference writel_relaxed() or writel() for this driver.
Just original owner pick one.

>
> > +	}
> > +
> > +	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
> > +	rate = clk_get_rate(tmu->clk);
> > +	div = (rate / 4000000) - 1;
> > +	if (div > FIELD_GET(DIV_MASK, DIV_MASK))
> 			^
> This misuse the FIELD_GET() API. Instead please add a define e.g. DIV_MAX.

I don't think so, It avoid define another macro DIV_MAX, which may miss
defined, the related marco should come from one source.

For example:

DIV_MASK is GENMASK(23, 16),  DIV_MAX is 256. But if hardware upgrade,
DIV_MASK to GENMASK(24, 16), DIV_MAX is quite easy to forget update it and
hard to find such mis-match when div value < 256.

>
> > +		return -EINVAL;
> 			^
> 		dev_err_probe()
> > +
> > +	/* Set divider value and enable divider */
> > +	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
> > +
> > +	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
> > +	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
> 		^
> You dont need to repeat the default value, so this line can be dropped.
>
> > +
> > +	/*
> > +	 * Set resolution mode
> > +	 * 00b - Conversion time = 0.59325 ms
> > +	 * 01b - Conversion time = 1.10525 ms
> > +	 * 10b - Conversion time = 2.12925 ms
> > +	 * 11b - Conversion time = 4.17725 ms
> > +	 */
> > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
> > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);
>
> Same here, you repeat the module default after reset, so please drop it.
>
> > +	writel_relaxed(CTRL1_MEAS_MODE_MASK, tmu->base + CTRL1_CLR);
> > +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, CTRL1_MEAS_MODE_SINGLE),
> > +		       tmu->base + CTRL1_SET);
> > +
> > +	clk_disable_unprepare(tmu->clk);
>
> Drop this, and
>
> > +	pm_runtime_set_suspended(dev);
>
> replace this with: pm_runtime_set_active();

No big difference, if set_active, we need add Enable TMU here. I can
change to set_active.

Frank

>
> > +	pm_runtime_enable(dev);
> 		^
> devm_pm_runtime_enable()
>
> > +	tmu->tzd = devm_thermal_of_zone_register(dev, 0, tmu, &tmu_tz_ops);
> > +	if (IS_ERR(tmu->tzd))
> > +		return dev_err_probe(dev, PTR_ERR(tmu->tzd),
> > +				     "failed to register thermal zone sensor\n");
>
>
> pm_runtime_put()
>
>
> > +
> > +	return 0;
> > +}
> > +
> > +static void imx91_tmu_remove(struct platform_device *pdev)
> > +{
> > +	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
> > +
> > +	/* disable tmu */
> > +	imx91_tmu_start(tmu, false);
>
> No need to clear the START bit since we are running in
> single-shot-measurements now.
>
> > +	imx91_tmu_enable(tmu, false);
> > +}
> > +
> > +static int imx91_tmu_runtime_suspend(struct device *dev)
> > +{
> > +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> > +
> > +	/* disable tmu */
> > +	imx91_tmu_start(tmu, false);
>
> Can be dropped.
>
> > +	imx91_tmu_enable(tmu, false);
> > +
> > +	clk_disable_unprepare(tmu->clk);
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx91_tmu_runtime_resume(struct device *dev)
> > +{
> > +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> > +	int ret;
> > +
> > +	ret = clk_prepare_enable(tmu->clk);
> > +	if (ret)
> > +		return ret;
> > +
> > +	imx91_tmu_enable(tmu, true);
> > +	imx91_tmu_start(tmu, true);
>
> Drop imx91_tmu_start() from the resume since this isn't related to the
> runtime-pm. Instead the function needs to be called within
> imx91_tmu_get_temp().
>
> > +	return 0;
> > +}
> > +
> > +static const struct dev_pm_ops imx91_tmu_pm_ops = {
> > +	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
> > +	RUNTIME_PM_OPS(imx91_tmu_runtime_suspend, imx91_tmu_runtime_resume, NULL)
> > +};
>
> DEFINE_RUNTIME_DEV_PM_OPS()
>
> > +
> > +static const struct of_device_id imx91_tmu_table[] = {
> > +	{ .compatible = "fsl,imx91-tmu", },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(of, imx91_tmu_table);
> > +
> > +static struct platform_driver imx91_tmu = {
> > +	.driver = {
> > +		.name	= "i.MX91_thermal",
> 				^
> Please don't use such names, instead use imx91_thermal.
>
> Regards,
>   Marco
>
> > +		.pm	= pm_ptr(&imx91_tmu_pm_ops),
> > +		.of_match_table = imx91_tmu_table,
> > +	},
> > +	.probe = imx91_tmu_probe,
> > +	.remove = imx91_tmu_remove,
> > +};
> > +module_platform_driver(imx91_tmu);
> > +
> > +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> > +MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
> > +MODULE_LICENSE("GPL");
> >
> > --
> > 2.34.1
> >
> >


From clement.legoffic at foss.st.com  Wed Dec 11 08:34:57 2024
From: clement.legoffic at foss.st.com (=?UTF-8?q?Cl=C3=A9ment=20Le=20Goffic?=)
Date: Wed, 11 Dec 2024 17:34:57 +0100
Subject: [PATCH] watchdog: stm32_iwdg: fix DT backward compatibility
Message-ID: <20241211163457.301140-1-clement.legoffic@foss.st.com>

The commit 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
introduces the support for the pre-timeout interrupt.

The support for this interrupt is optional but the driver mandates the
interrupts property in the device-tree, breaking the compatibility with
existing device-trees.

Use the platform_get_irq_optional() API to comply with existing
device-trees.

Fixes: 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
Signed-off-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
---

Please consider merging this patch in the v6.13 cycle to avoid breaking
the compatibility of the existing device-tree.

drivers/watchdog/stm32_iwdg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index d700e0d49bb95..8ad06b54c5adc 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -286,7 +286,7 @@ static int stm32_iwdg_irq_init(struct platform_device *pdev,
 	if (!wdt->data->has_early_wakeup)
 		return 0;

-	irq = platform_get_irq(pdev, 0);
+	irq = platform_get_irq_optional(pdev, 0);
 	if (irq <= 0)
 		return 0;


base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
--
2.34.1



From maz at kernel.org  Wed Dec 11 08:52:49 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Dec 2024 16:52:49 +0000
Subject: [RFC PATCH v1 3/5] arm64: Add errata and workarounds for systems with broken BBML2
In-Reply-To: <20241211154611.40395-4-miko.lenczewski@arm.com>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
	<20241211154611.40395-4-miko.lenczewski@arm.com>
Message-ID: <86pllyrwke.wl-maz@kernel.org>

On Wed, 11 Dec 2024 15:45:04 +0000,
Miko?aj Lenczewski <miko.lenczewski at arm.com> wrote:
> 
> There are systems which claim support for BBML2, but whose
> implementation of this support is broken. Add a Kconfig erratum for each
> of these systems, and a cpufeature workaround that forces the supported
> BBM level on these systems to 0.
> 
> Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
> ---
>  Documentation/arch/arm64/silicon-errata.rst |  32 ++++
>  arch/arm64/Kconfig                          | 164 ++++++++++++++++++++
>  arch/arm64/kernel/cpufeature.c              |  32 +++-
>  3 files changed, 227 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 100570a048c5..9ef8418e8410 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1127,6 +1127,170 @@ config ARM64_ERRATUM_3194386
>  
>  	  If unsure, say Y.
>  
> +config ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
> +	bool
> +
> +config ARM64_ERRATUM_3696250
> +	bool "Neoverse-N2: workaround for broken BBM level 2 support"
> +	default y
> +	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
> +	help
> +	  Affected Neoverse-N2 cores (r0p0, r0p1, r0p2, r0p3) declare

So you list a number of affected revisions...

[...]

> +static bool has_bbml2(const struct arm64_cpu_capabilities *entry,
> +		      int scope)
> +{
> +	if (IS_ENABLED(CONFIG_ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT)) {
> +		static const struct midr_range broken_bbml2_list[] = {
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
> +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
> +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
> +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
> +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
> +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
> +			{}

... and yet you flag all versions as broken? So which one is it? If it
is really the case that all versions are broken, then the text should
be simplified. Otherwise, this should really list the broken versions.

The other thing is that I find it incredibly dangerous to rely on
some config option to disable a feature that will absolutely eat your
data if it is broken. I'd rather see the whole BBM-L2 being behind an
option, and unconditionally check for b0rken CPUs.

Specially when it looks like there isn't a single CPU on the planet
that implemented the feature correctly... :-/

Thanks,

	M.

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


From neil.armstrong at linaro.org  Wed Dec 11 08:57:26 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Wed, 11 Dec 2024 17:57:26 +0100
Subject: [PATCH v2 1/2] dt-bindings: display: panel-lvds: Add compatible
 for AUO G084SN05 V9
In-Reply-To: <CAOMZO5B3810+4RJsPUtL3ASxqpDd+UmC=GcY6t8-ad7NZXZLjQ@mail.gmail.com>
References: <20241210105705.116116-1-festevam@gmail.com>
 <yujvdu3s6v7z7th2lrdscqfxocx2zy2u4owakisvnjppz2udqv@5ok2rcf4exd4>
 <CAOMZO5B3810+4RJsPUtL3ASxqpDd+UmC=GcY6t8-ad7NZXZLjQ@mail.gmail.com>
Message-ID: <1b3d37ce-a362-4846-bb7f-7cbe4c28608b@linaro.org>

Hi,

On 11/12/2024 17:29, Fabio Estevam wrote:
> Hi Neil,
> 
> On Wed, Dec 11, 2024 at 6:31?AM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>>
>> On Tue, Dec 10, 2024 at 07:57:04AM -0300, Fabio Estevam wrote:
>>> From: Fabio Estevam <festevam at denx.de>
>>>
>>> The AUO G084SN05 V9 is an 8.4" 800x600 LVDS display.
>>>
>>> Add a compatible entry for this LVDS display model.
>>>
>>> Signed-off-by: Fabio Estevam <festevam at denx.de>
>>> ---
>>> Changes since v1:
>>> - Added devicetree at vger.kernel.org on Cc.
>>>
>>>   Documentation/devicetree/bindings/display/panel/panel-lvds.yaml | 2 ++
>>>   1 file changed, 2 insertions(+)
>>
>> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> Would it be OK for you if Shawn applies both patches via his i.MX ARM tree?

I don't think it's a good idea, there's no build dependency so I'd
rather apply patch 1 via drm-misc

Neil


From Markus.Elfring at web.de  Wed Dec 11 09:02:46 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Wed, 11 Dec 2024 18:02:46 +0100
Subject: [PATCH v6 6/7] pinctrl: s32cc: implement GPIO functionality
In-Reply-To: <20241113101124.1279648-7-andrei.stefanescu@oss.nxp.com>
References: <20241113101124.1279648-7-andrei.stefanescu@oss.nxp.com>
Message-ID: <384bdbaf-15f1-4cad-8f77-371ccb67d952@web.de>

?
> +++ b/drivers/pinctrl/nxp/pinctrl-s32cc.c
?
> +static void s32_gpio_free(struct gpio_chip *gc, unsigned int gpio)
> +{
?
> +	spin_lock_irqsave(&ipctl->gpio_configs_lock, flags);
> +
> +	list_for_each_entry_safe(gpio_pin, tmp, &ipctl->gpio_configs, list) {
?
> +	}
> +
> +unlock:
> +	spin_unlock_irqrestore(&ipctl->gpio_configs_lock, flags);
> +}

How do you think about to apply another call ?scoped_guard(spinlock_irqsave, &ipctl->gpio_configs_lock)? here?

Regards,
Markus


From mripard at kernel.org  Wed Dec 11 09:07:57 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Wed, 11 Dec 2024 18:07:57 +0100
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes
 handling on RK3588 HDMI0
In-Reply-To: <20241211-vop2-hdmi0-disp-modes-v2-3-471cf5001e45@collabora.com>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
 <20241211-vop2-hdmi0-disp-modes-v2-3-471cf5001e45@collabora.com>
Message-ID: <64vc5pkj44w3qxf5wkcxgghpwhvoagzemcsfqmi7fhsxt7vlqd@yfcgloi45ygh>

On Wed, Dec 11, 2024 at 12:15:07PM +0200, Cristian Ciocaltea wrote:
> The RK3588 specific implementation is currently quite limited in terms
> of handling the full range of display modes supported by the connected
> screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
> few of them.
> 
> Additionally, it doesn't cope well with non-integer refresh rates like
> 59.94, 29.97, 23.98, etc.
> 
> Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
> all display modes up to 4K at 60Hz.
> 
> Tested-by: FUKAUMI Naoki <naoki at radxa.com>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> @@ -158,6 +158,7 @@ struct vop2_video_port {
>  	struct drm_crtc crtc;
>  	struct vop2 *vop2;
>  	struct clk *dclk;
> +	struct clk *dclk_src;
>  	unsigned int id;
>  	const struct vop2_video_port_data *data;
>  
> @@ -212,6 +213,7 @@ struct vop2 {
>  	struct clk *hclk;
>  	struct clk *aclk;
>  	struct clk *pclk;
> +	struct clk *pll_hdmiphy0;
>  
>  	/* optional internal rgb encoder */
>  	struct rockchip_rgb *rgb;
> @@ -220,6 +222,8 @@ struct vop2 {
>  	struct vop2_win win[];
>  };
>  
> +#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
> +
>  #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
>  					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
>  
> @@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
>  
>  	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
>  
> +	if (vp->dclk_src)
> +		clk_set_parent(vp->dclk, vp->dclk_src);
> +
>  	clk_disable_unprepare(vp->dclk);
>  
>  	vop2->enable_count--;
> @@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
>  
>  	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
>  
> +	/*
> +	 * Switch to HDMI PHY PLL as DCLK source for display modes up
> +	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
> +	 */
> +	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
> +		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
> +			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
> +
> +			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
> +				if (!vp->dclk_src)
> +					vp->dclk_src = clk_get_parent(vp->dclk);
> +
> +				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
> +				if (ret < 0)
> +					drm_warn(vop2->drm,
> +						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
> +				break;
> +			}
> +		}
> +	}
> +

It seems pretty fragile to do it at atomic_enable time, even more so
since you don't lock the parent either.

Any reason not to do it in the DRM or clock driver probe, and make sure
you never change the parent somehow?

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

From sebastian.fricke at collabora.com  Wed Dec 11 09:10:52 2024
From: sebastian.fricke at collabora.com (Sebastian Fricke)
Date: Wed, 11 Dec 2024 18:10:52 +0100
Subject: [PATCH v6 3/3] media: mediatek: vcodec: add description for vsi
 struct
In-Reply-To: <20241116031616.15656-4-yunfei.dong@mediatek.com>
References: <20241116031616.15656-1-yunfei.dong@mediatek.com>
 <20241116031616.15656-4-yunfei.dong@mediatek.com>
Message-ID: <20241211171052.wl4wqoka7yyeso2l@basti-XPS-13-9310>

Hey Yunfei,

On 16.11.2024 11:16, Yunfei Dong wrote:
>If the video shared information (vsi) is changed accidentally,

How can that struct be changed accidentally?

>will leading to play h264 bitstream fail if the firmware won't
>be changed at the same time.

Okay I guess you mean that the struct has to be memcpy'd to the firmware
to synchronize it right?
Also is this really just a H264 thing? I would imagine that incorrect
data in the firmware will cause issues no matter which codec.

>Marking the shared struct with "shared interface with firmware".

Can we do anything more to ensure that the firmware doesn't fall out of
sync besides adding a comment to the description?

To fix grammatical issues the description above should be changed to:

The vsi (video shared information) struct needs to be synchronized
between the firmware and the host, as a change that is only done in the
host version of the struct but isn't synchronized to the firmware can
lead to decoding issues with H264 bitstreams. Highlight this requirement
within the struct descriptions.

But as highlighted above it is not clear to me whether the content of
this message is right yet.

>
>Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
>Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
>Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>---
> .../mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c    | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
>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 a7de95b9a7c0..5a202691e209 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
>@@ -30,6 +30,7 @@ enum vdec_h264_core_dec_err_type {
>
> /**
>  * struct vdec_h264_slice_lat_dec_param  - parameters for decode current frame
>+ *        (shared interface with firmware)
>  *
>  * @sps:		h264 sps syntax parameters
>  * @pps:		h264 pps syntax parameters
>@@ -48,7 +49,7 @@ struct vdec_h264_slice_lat_dec_param {
> };
>
> /**
>- * struct vdec_h264_slice_info - decode information
>+ * struct vdec_h264_slice_info - decode information (shared interface with firmware)
>  *
>  * @nal_info:		nal info of current picture
>  * @timeout:		Decode timeout: 1 timeout, 0 no timeout
>@@ -72,7 +73,7 @@ struct vdec_h264_slice_info {
>
> /**
>  * struct vdec_h264_slice_vsi - shared memory for decode information exchange
>- *        between SCP and Host.
>+ *        between SCP and Host (shared interface with firmware).

In this case, I feel like the previous description made the fact, that
this is shared data between the host and the firmware, rather clear
already.

>  *
>  * @wdma_err_addr:		wdma error dma address
>  * @wdma_start_addr:		wdma start dma address
>-- 
>2.46.0
>
>
Regards,
Sebastian Fricke


From linux at roeck-us.net  Wed Dec 11 09:12:06 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 11 Dec 2024 09:12:06 -0800
Subject: [PATCH] watchdog: stm32_iwdg: fix DT backward compatibility
In-Reply-To: <20241211163457.301140-1-clement.legoffic@foss.st.com>
References: <20241211163457.301140-1-clement.legoffic@foss.st.com>
Message-ID: <213073e5-c929-4207-a9a5-13194012cf70@roeck-us.net>

On 12/11/24 08:34, Cl?ment Le Goffic wrote:
> The commit 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
> introduces the support for the pre-timeout interrupt.
> 
> The support for this interrupt is optional but the driver mandates the
> interrupts property in the device-tree, breaking the compatibility with
> existing device-trees.
> 
> Use the platform_get_irq_optional() API to comply with existing
> device-trees.
> 
> Fixes: 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
> Signed-off-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

> ---
> 
> Please consider merging this patch in the v6.13 cycle to avoid breaking
> the compatibility of the existing device-tree.
> 
> drivers/watchdog/stm32_iwdg.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
> index d700e0d49bb95..8ad06b54c5adc 100644
> --- a/drivers/watchdog/stm32_iwdg.c
> +++ b/drivers/watchdog/stm32_iwdg.c
> @@ -286,7 +286,7 @@ static int stm32_iwdg_irq_init(struct platform_device *pdev,
>   	if (!wdt->data->has_early_wakeup)
>   		return 0;
> 
> -	irq = platform_get_irq(pdev, 0);
> +	irq = platform_get_irq_optional(pdev, 0);
>   	if (irq <= 0)
>   		return 0;
> 
> 
> base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
> --
> 2.34.1
> 



From ivo.ivanov.ivanov1 at gmail.com  Wed Dec 11 09:23:53 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Wed, 11 Dec 2024 19:23:53 +0200
Subject: [PATCH v2] dt-bindings: power: actions,owl-sps: convert to YAML
In-Reply-To: <20241103123917.2890436-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241103123917.2890436-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <f395a019-800f-49a4-a3cc-28efafc4faa9@gmail.com>

On 11/3/24 14:39, Ivaylo Ivanov wrote:
> Convert the Actions Semi Owl Smart Power System (SPS) bindings to DT
> schema.
>
> Changes during conversion:
>  - Add a description
>
> Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
> Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>
> ---
> v2: add r-b tag from Krzysztof Kozlowski <krzk at kernel.org>
> v2: update commit message to be accurate (Krzysztof)
> v2: don't preserve formatting in the description (Krzysztof)
> v2: add a blank line after additionalProperties (Krzysztof)
> ---
>  .../bindings/power/actions,owl-sps.txt        | 21 --------
>  .../bindings/power/actions,owl-sps.yaml       | 51 +++++++++++++++++++
>  MAINTAINERS                                   |  2 +-
>  3 files changed, 52 insertions(+), 22 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/power/actions,owl-sps.txt
>  create mode 100644 Documentation/devicetree/bindings/power/actions,owl-sps.yaml
>
> diff --git a/Documentation/devicetree/bindings/power/actions,owl-sps.txt b/Documentation/devicetree/bindings/power/actions,owl-sps.txt

BUMP - what happened with the patch? Been a month now and
all the other ones have been applied.

Best regards, Ivo.

> deleted file mode 100644
> index a3571937b..000000000
> --- a/Documentation/devicetree/bindings/power/actions,owl-sps.txt
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -Actions Semi Owl Smart Power System (SPS)
> -
> -Required properties:
> -- compatible          :  "actions,s500-sps" for S500
> -                         "actions,s700-sps" for S700
> -                         "actions,s900-sps" for S900
> -- reg                 :  Offset and length of the register set for the device.
> -- #power-domain-cells :  Must be 1.
> -                         See macros in:
> -                          include/dt-bindings/power/owl-s500-powergate.h for S500
> -                          include/dt-bindings/power/owl-s700-powergate.h for S700
> -                          include/dt-bindings/power/owl-s900-powergate.h for S900
> -
> -
> -Example:
> -
> -		sps: power-controller at b01b0100 {
> -			compatible = "actions,s500-sps";
> -			reg = <0xb01b0100 0x100>;
> -			#power-domain-cells = <1>;
> -		};
> diff --git a/Documentation/devicetree/bindings/power/actions,owl-sps.yaml b/Documentation/devicetree/bindings/power/actions,owl-sps.yaml
> new file mode 100644
> index 000000000..0855d82f3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/actions,owl-sps.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/power/actions,owl-sps.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Actions Semi Owl Smart Power System (SPS)
> +
> +maintainers:
> +  - Andreas F?rber <afaerber at suse.de>
> +
> +description:
> +  Actions Semi Owl SoCs feature a Smart Power System (SPS) that manages power
> +  domains to optimize power usage across various hardware blocks. Each power
> +  domain corresponds to a specific hardware block and is represented by a bit
> +  in the power control register and an acknowledgment bit, which is then
> +  translated into a corresponding voltage on a rail.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - actions,s500-sps
> +      - actions,s700-sps
> +      - actions,s900-sps
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#power-domain-cells":
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#power-domain-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/power/owl-s500-powergate.h>
> +    soc {
> +      #address-cells = <1>;
> +      #size-cells = <1>;
> +      sps: power-controller at b01b0100 {
> +        compatible = "actions,s500-sps";
> +        reg = <0xb01b0100 0x100>;
> +        #power-domain-cells = <1>;
> +      };
> +    };
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 76ea65128..420d06d37 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2023,7 +2023,7 @@ F:	Documentation/devicetree/bindings/interrupt-controller/actions,owl-sirq.yaml
>  F:	Documentation/devicetree/bindings/mmc/owl-mmc.yaml
>  F:	Documentation/devicetree/bindings/net/actions,owl-emac.yaml
>  F:	Documentation/devicetree/bindings/pinctrl/actions,*
> -F:	Documentation/devicetree/bindings/power/actions,owl-sps.txt
> +F:	Documentation/devicetree/bindings/power/actions,owl-sps.yaml
>  F:	Documentation/devicetree/bindings/timer/actions,owl-timer.yaml
>  F:	arch/arm/boot/dts/actions/
>  F:	arch/arm/mach-actions/



From heiko at sntech.de  Wed Dec 11 09:23:03 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 11 Dec 2024 18:23:03 +0100
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes handling on
 RK3588 HDMI0
In-Reply-To: <64vc5pkj44w3qxf5wkcxgghpwhvoagzemcsfqmi7fhsxt7vlqd@yfcgloi45ygh>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
 <20241211-vop2-hdmi0-disp-modes-v2-3-471cf5001e45@collabora.com>
 <64vc5pkj44w3qxf5wkcxgghpwhvoagzemcsfqmi7fhsxt7vlqd@yfcgloi45ygh>
Message-ID: <1820767.5KxKD5qtyk@diego>

Am Mittwoch, 11. Dezember 2024, 18:07:57 CET schrieb Maxime Ripard:
> On Wed, Dec 11, 2024 at 12:15:07PM +0200, Cristian Ciocaltea wrote:
> > The RK3588 specific implementation is currently quite limited in terms
> > of handling the full range of display modes supported by the connected
> > screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
> > few of them.
> > 
> > Additionally, it doesn't cope well with non-integer refresh rates like
> > 59.94, 29.97, 23.98, etc.
> > 
> > Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
> > all display modes up to 4K at 60Hz.
> > 
> > Tested-by: FUKAUMI Naoki <naoki at radxa.com>
> > Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> > ---
> >  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
> >  1 file changed, 34 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > @@ -158,6 +158,7 @@ struct vop2_video_port {
> >  	struct drm_crtc crtc;
> >  	struct vop2 *vop2;
> >  	struct clk *dclk;
> > +	struct clk *dclk_src;
> >  	unsigned int id;
> >  	const struct vop2_video_port_data *data;
> >  
> > @@ -212,6 +213,7 @@ struct vop2 {
> >  	struct clk *hclk;
> >  	struct clk *aclk;
> >  	struct clk *pclk;
> > +	struct clk *pll_hdmiphy0;
> >  
> >  	/* optional internal rgb encoder */
> >  	struct rockchip_rgb *rgb;
> > @@ -220,6 +222,8 @@ struct vop2 {
> >  	struct vop2_win win[];
> >  };
> >  
> > +#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
> > +
> >  #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
> >  					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
> >  
> > @@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
> >  
> >  	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
> >  
> > +	if (vp->dclk_src)
> > +		clk_set_parent(vp->dclk, vp->dclk_src);
> > +
> >  	clk_disable_unprepare(vp->dclk);
> >  
> >  	vop2->enable_count--;
> > @@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
> >  
> >  	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
> >  
> > +	/*
> > +	 * Switch to HDMI PHY PLL as DCLK source for display modes up
> > +	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
> > +	 */
> > +	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
> > +		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
> > +			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
> > +
> > +			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
> > +				if (!vp->dclk_src)
> > +					vp->dclk_src = clk_get_parent(vp->dclk);
> > +
> > +				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
> > +				if (ret < 0)
> > +					drm_warn(vop2->drm,
> > +						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
> > +				break;
> > +			}
> > +		}
> > +	}
> > +
> 
> It seems pretty fragile to do it at atomic_enable time, even more so
> since you don't lock the parent either.
> 
> Any reason not to do it in the DRM or clock driver probe, and make sure
> you never change the parent somehow?

On rk3588 we have 3 dclk_s and 2 hdmi controllers. Each video-port can
use the clock generated from either the hdmi0phy or hdmi1phy, depending
on which hdmi-controller it uses.

So you actually need to know which vpX will output to which hdmiY to then
reparent that dclk to the hdmiphy output.







From cl at gentwo.org  Wed Dec 11 09:24:33 2024
From: cl at gentwo.org (Christoph Lameter (Ampere))
Date: Wed, 11 Dec 2024 09:24:33 -0800 (PST)
Subject: [RFC PATCH 0/3] arm64: support FEAT_BBM level 2 and large block
 mapping when rodata=full
In-Reply-To: <20241210113151.GC14735@willie-the-truck>
References: <20241118181711.962576-1-yang@os.amperecomputing.com> <20241210113151.GC14735@willie-the-truck>
Message-ID: <6714a00a-220e-c43b-7f06-4a2397159cd7@gentwo.org>

On Tue, 10 Dec 2024, Will Deacon wrote:

> > With FEAT_BBM level 2 support, splitting large block page table to
> > smaller ones doesn't need to make the page table entry invalid anymore.
> > This allows kernel split large block mapping on the fly.
>
> I think you can still get TLB conflict aborts in this case, so this
> doesn't work. Hopefully the architecture can strengthen this in the

Which platforms get TLB conflicts? Ours does not. Is this an errata on
some platforms?



From maz at kernel.org  Wed Dec 11 09:40:36 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Dec 2024 17:40:36 +0000
Subject: [RESEND RFC PATCH v1 1/5] arm64: Add TLB Conflict Abort Exception handler to KVM
In-Reply-To: <20241211160218.41404-2-miko.lenczewski@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
	<20241211160218.41404-2-miko.lenczewski@arm.com>
Message-ID: <86o71irucr.wl-maz@kernel.org>

On Wed, 11 Dec 2024 16:01:37 +0000,
Miko?aj Lenczewski <miko.lenczewski at arm.com> wrote:
> 
> Currently, KVM does not handle the case of a stage 2 TLB conflict abort
> exception. The Arm ARM specifies that the worst-case handling of such an
> exception requires a `tlbi vmalls12e1`.

Not quite. It says (I_JCCRT):

<quote>
* For the EL1&0 translation regime, when stage 2 translations are in
  use, either VMALLS12E1 or ALLE1.
</quote>

> Perform such an invalidation when this exception is encountered.

What you fail to describe is *why* this is needed. You know it, I know
it, but not everybody does. A reference to the ARM ARM would
definitely be helpful.

> 
> Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
> ---
>  arch/arm64/include/asm/esr.h | 8 ++++++++
>  arch/arm64/kvm/mmu.c         | 6 ++++++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index d1b1a33f9a8b..8a66f81ca291 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -121,6 +121,7 @@
>  #define ESR_ELx_FSC_SEA_TTW(n)	(0x14 + (n))
>  #define ESR_ELx_FSC_SECC	(0x18)
>  #define ESR_ELx_FSC_SECC_TTW(n)	(0x1c + (n))
> +#define ESR_ELx_FSC_TLBABT	(0x30)
>  
>  /* Status codes for individual page table levels */
>  #define ESR_ELx_FSC_ACCESS_L(n)	(ESR_ELx_FSC_ACCESS + (n))
> @@ -464,6 +465,13 @@ static inline bool esr_fsc_is_access_flag_fault(unsigned long esr)
>  	       (esr == ESR_ELx_FSC_ACCESS_L(0));
>  }
>  
> +static inline bool esr_fsc_is_tlb_conflict_abort(unsigned long esr)
> +{
> +	esr = esr & ESR_ELx_FSC;
> +
> +	return esr == ESR_ELx_FSC_TLBABT;
> +}
> +
>  /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */
>  static inline bool esr_iss_is_eretax(unsigned long esr)
>  {
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index c9d46ad57e52..c8c6f5a97a1b 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1756,6 +1756,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>  	ipa = fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>  	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
>  
> +	if (esr_fsc_is_tlb_conflict_abort(esr)) {
> +		// does a `tlbi vmalls12e1is`

nit: this isn't a very useful comment.

> +		__kvm_tlb_flush_vmid(&vcpu->kvm->arch.mmu);
> +		return 1;
> +	}

That's not enough, unfortunately. A nested VM has *many* VMIDs (the
flattening of all translation contexts that the guest uses).

So you can either iterate over all the valid VMIDs owned by this
guest, or more simply issue a TLBI ALLE1, which will do the trick in a
much more efficient way.

The other thing is that you are using an IS invalidation, which is
farther reaching than necessary. Why would you invalidate the TLBs for
CPUs that are only innocent bystanders? A non-shareable invalidation
seems preferable to me.

> +
>  	if (esr_fsc_is_translation_fault(esr)) {
>  		/* Beyond sanitised PARange (which is the IPA limit) */
>  		if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit())) {

But it also begs the question: why only KVM, and not the host? This
handler will only take effect for a TLB Conflict abort delivered from
an EL1 guest to EL2.

However, it doesn't seem to me that the host is equipped to deal with
this sort of exception for itself. Shouldn't you start with that?

Thanks,

	M.

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


From mripard at kernel.org  Wed Dec 11 09:47:44 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Wed, 11 Dec 2024 18:47:44 +0100
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes
 handling on RK3588 HDMI0
In-Reply-To: <1820767.5KxKD5qtyk@diego>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
 <20241211-vop2-hdmi0-disp-modes-v2-3-471cf5001e45@collabora.com>
 <64vc5pkj44w3qxf5wkcxgghpwhvoagzemcsfqmi7fhsxt7vlqd@yfcgloi45ygh>
 <1820767.5KxKD5qtyk@diego>
Message-ID: <a4ex3s23r4k6wehyoaw3aylpcexfrclrxxykjpabhdfne2jgmu@ii6riiiga2zj>

On Wed, Dec 11, 2024 at 06:23:03PM +0100, Heiko St?bner wrote:
> Am Mittwoch, 11. Dezember 2024, 18:07:57 CET schrieb Maxime Ripard:
> > On Wed, Dec 11, 2024 at 12:15:07PM +0200, Cristian Ciocaltea wrote:
> > > The RK3588 specific implementation is currently quite limited in terms
> > > of handling the full range of display modes supported by the connected
> > > screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
> > > few of them.
> > > 
> > > Additionally, it doesn't cope well with non-integer refresh rates like
> > > 59.94, 29.97, 23.98, etc.
> > > 
> > > Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
> > > all display modes up to 4K at 60Hz.
> > > 
> > > Tested-by: FUKAUMI Naoki <naoki at radxa.com>
> > > Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> > > ---
> > >  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
> > >  1 file changed, 34 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > > index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
> > > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > > @@ -158,6 +158,7 @@ struct vop2_video_port {
> > >  	struct drm_crtc crtc;
> > >  	struct vop2 *vop2;
> > >  	struct clk *dclk;
> > > +	struct clk *dclk_src;
> > >  	unsigned int id;
> > >  	const struct vop2_video_port_data *data;
> > >  
> > > @@ -212,6 +213,7 @@ struct vop2 {
> > >  	struct clk *hclk;
> > >  	struct clk *aclk;
> > >  	struct clk *pclk;
> > > +	struct clk *pll_hdmiphy0;
> > >  
> > >  	/* optional internal rgb encoder */
> > >  	struct rockchip_rgb *rgb;
> > > @@ -220,6 +222,8 @@ struct vop2 {
> > >  	struct vop2_win win[];
> > >  };
> > >  
> > > +#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
> > > +
> > >  #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
> > >  					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
> > >  
> > > @@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
> > >  
> > >  	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
> > >  
> > > +	if (vp->dclk_src)
> > > +		clk_set_parent(vp->dclk, vp->dclk_src);
> > > +
> > >  	clk_disable_unprepare(vp->dclk);
> > >  
> > >  	vop2->enable_count--;
> > > @@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
> > >  
> > >  	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
> > >  
> > > +	/*
> > > +	 * Switch to HDMI PHY PLL as DCLK source for display modes up
> > > +	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
> > > +	 */
> > > +	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
> > > +		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
> > > +			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
> > > +
> > > +			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
> > > +				if (!vp->dclk_src)
> > > +					vp->dclk_src = clk_get_parent(vp->dclk);
> > > +
> > > +				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
> > > +				if (ret < 0)
> > > +					drm_warn(vop2->drm,
> > > +						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
> > > +				break;
> > > +			}
> > > +		}
> > > +	}
> > > +
> > 
> > It seems pretty fragile to do it at atomic_enable time, even more so
> > since you don't lock the parent either.
> > 
> > Any reason not to do it in the DRM or clock driver probe, and make sure
> > you never change the parent somehow?
> 
> On rk3588 we have 3 dclk_s and 2 hdmi controllers. Each video-port can
> use the clock generated from either the hdmi0phy or hdmi1phy, depending
> on which hdmi-controller it uses.
> 
> So you actually need to know which vpX will output to which hdmiY to then
> reparent that dclk to the hdmiphy output.

The Rockchip nomenclature isn't super obvious to me, sorry. Is there a
datasheet for this somewhere? Also, does this vpX -> HDMI-Y mapping need
to be dynamic?

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

From peter.griffin at linaro.org  Wed Dec 11 09:53:57 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 11 Dec 2024 17:53:57 +0000
Subject: [PATCH v4 7/7] phy: exynos5-usbdrd: allow DWC3 runtime suspend
 with UDC bound (E850+)
In-Reply-To: <CADrjBPrz1qUxbEVFR8OT785xLPwWmu3_ZThSne+EtpS8_NHEEg@mail.gmail.com>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
 <20241206-gs101-phy-lanes-orientation-phy-v4-7-f5961268b149@linaro.org> <CADrjBPrz1qUxbEVFR8OT785xLPwWmu3_ZThSne+EtpS8_NHEEg@mail.gmail.com>
Message-ID: <CADrjBPqW81kaK=Wco7wMg50APTXGRwhnfFjbnogrSQ-T_mWnUQ@mail.gmail.com>

Hi Andr?,

On Sat, 7 Dec 2024 at 22:03, Peter Griffin <peter.griffin at linaro.org> wrote:
>
> Hi Andr?,
>
> On Fri, 6 Dec 2024 at 16:31, Andr? Draszik <andre.draszik at linaro.org> wrote:
> >
> > To make USB runtime suspend work when a UDC has been bound, the phy
> > needs to inform the USBDRD controller (DWC3) that Vbus and bvalid are
> > gone, so that it can in turn raise the respective gadget interrupt with
> > event == DWC3_DEVICE_EVENT_DISCONNECT, which will cause the USB stack
> > to clean up, allowing DWC3 to enter runtime suspend.
> >
> > On e850 and gs101 this isn't working, as the respective signals are not
> > directly connected, and instead this driver uses override bits in the
> > PHY IP to set those signals. It currently forcefully sets them to 'on',
> > so the above mentioned interrupt will not be raised, preventing runtime
> > suspend.
> >
> > To detect that state, update this driver to act on the TCPC's
> > orientation signal - when orientation == NONE, Vbus is gone and we can
> > clear the respective bits. Similarly, for other orientation values we
> > re-enable them.
> >
> > This makes runtime suspend work on platforms with a TCPC (like Pixel6),
> > while keeping compatibility with platforms without (e850-96).
> >
> > With runtime suspend working, USB-C cable orientation detection now
> > also fully works on such platforms, and the link comes up as Superspeed
> > as expected irrespective of the cable orientation and whether UDC /
> > gadget are configured and active.
> >
> > Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
>
> As mentioned on the last patch, in my testing cable orientation
> detection is working, but Pixel is detected as a superspeed device in
> one orientation, and high speed device in the other orientation. So
> you should either change the wording of the last paragraph in the
> commit message (assuming you get the same results as me) or make it
> detect as superspeed in both orientations.

You can disregard this point, I had a typo in my test setup :( I just
confirmed that it is detected as SuperSpeed in both orientations.

Thanks,

Peter


From peter.griffin at linaro.org  Wed Dec 11 09:55:23 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 11 Dec 2024 17:55:23 +0000
Subject: [PATCH v4 6/7] phy: exynos5-usbdrd: subscribe to orientation
 notifier if required
In-Reply-To: <CADrjBPoZqbAM=2zOdgXD_dTrgh-J7yE+OX_JSVJ42Lmzb-DPEw@mail.gmail.com>
References: <20241206-gs101-phy-lanes-orientation-phy-v4-0-f5961268b149@linaro.org>
 <20241206-gs101-phy-lanes-orientation-phy-v4-6-f5961268b149@linaro.org> <CADrjBPoZqbAM=2zOdgXD_dTrgh-J7yE+OX_JSVJ42Lmzb-DPEw@mail.gmail.com>
Message-ID: <CADrjBPpv7Y-v4w-ZjsM52wPXM1G=v028BxmJA=_zb4ksDq21EQ@mail.gmail.com>

Hi Andr?,

On Sat, 7 Dec 2024 at 21:31, Peter Griffin <peter.griffin at linaro.org> wrote:
>
> Hi Andr?,
>
> Firstly, thanks for all your work getting USB on Pixel 6 / gs101
> working upstream :)
>
> On Fri, 6 Dec 2024 at 16:31, Andr? Draszik <andre.draszik at linaro.org> wrote:
> >
> > gs101's SS phy needs to be configured differently based on the
> > connector orientation, as the SS link can only be established if the
> > mux is configured correctly.
> >
> > The code to handle programming of the mux is in place already, this commit
> > now adds the missing pieces to subscribe to the Type-C orientation
> > switch event.
> >
> > Note that for this all to work we rely on the USB controller
> > re-initialising us. It should invoke our .exit() upon cable unplug, and
> > during cable plug we'll receive the orientation event after which we
> > expect our .init() to be called.
> >
> > Above reinitialisation happens if the DWC3 controller can enter runtime
> > suspend automatically. For the DWC3 driver, this is an opt-in:
> >     echo auto > /sys/devices/.../11110000.usb/power/control
> > Once done, things work as long as the UDC is not bound as otherwise it
> > stays busy because it doesn't cancel / stop outstanding TRBs. For now
> > we have to manually unbind the UDC in that case:
> >      echo "" > sys/kernel/config/usb_gadget/.../UDC
> >
> > Note that if the orientation-switch property is missing from the DT,
> > the code will behave as before this commit (meaning for gs101 it will
> > work in SS mode in one orientation only). Other platforms are not
> > affected either way.
> >
> > Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
>
> Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
> Tested-by: Peter Griffin <peter.griffin at linaro.org>
>
> Notes on testing:
>
> I tested this series with the corresponding DT using a Pixel 6 device
> with 2 different USB hubs and also plugging directly into my laptop.
> I've tried various combinations of plugging / unplugging from both
> ends of the USB cable and changing cable orientation. With the latest
> series the disconnect/reconnect always seems robustly detected and
> Pixel is enumerated as a USB device by the host, adb connection to the
> phone is possible even with the cable orientation changing between
> disconnect/reconnect.
>
> One thing I did notice during testing is that in one cable orientation
> Pixel is detected as a `SuperSpeed USB device` by the host and in the
> other cable orientation it is detected as a `high-speed USB device`.
> Which suggests there is still a latent bug in the phy
> re-configuration.

You can disregard this last point, I had a typo in my test setup :( I
just confirmed that it is detected as SuperSpeed in both orientations.

Thanks,

Peter


From heiko at sntech.de  Wed Dec 11 10:01:15 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 11 Dec 2024 19:01:15 +0100
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes handling on
 RK3588 HDMI0
In-Reply-To: <a4ex3s23r4k6wehyoaw3aylpcexfrclrxxykjpabhdfne2jgmu@ii6riiiga2zj>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
 <1820767.5KxKD5qtyk@diego>
 <a4ex3s23r4k6wehyoaw3aylpcexfrclrxxykjpabhdfne2jgmu@ii6riiiga2zj>
Message-ID: <1756448.izSxrag8PF@diego>

Am Mittwoch, 11. Dezember 2024, 18:47:44 CET schrieb Maxime Ripard:
> On Wed, Dec 11, 2024 at 06:23:03PM +0100, Heiko St?bner wrote:
> > Am Mittwoch, 11. Dezember 2024, 18:07:57 CET schrieb Maxime Ripard:
> > > On Wed, Dec 11, 2024 at 12:15:07PM +0200, Cristian Ciocaltea wrote:
> > > > The RK3588 specific implementation is currently quite limited in terms
> > > > of handling the full range of display modes supported by the connected
> > > > screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
> > > > few of them.
> > > > 
> > > > Additionally, it doesn't cope well with non-integer refresh rates like
> > > > 59.94, 29.97, 23.98, etc.
> > > > 
> > > > Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
> > > > all display modes up to 4K at 60Hz.
> > > > 
> > > > Tested-by: FUKAUMI Naoki <naoki at radxa.com>
> > > > Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> > > > ---
> > > >  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
> > > >  1 file changed, 34 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > > > index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
> > > > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > > > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > > > @@ -158,6 +158,7 @@ struct vop2_video_port {
> > > >  	struct drm_crtc crtc;
> > > >  	struct vop2 *vop2;
> > > >  	struct clk *dclk;
> > > > +	struct clk *dclk_src;
> > > >  	unsigned int id;
> > > >  	const struct vop2_video_port_data *data;
> > > >  
> > > > @@ -212,6 +213,7 @@ struct vop2 {
> > > >  	struct clk *hclk;
> > > >  	struct clk *aclk;
> > > >  	struct clk *pclk;
> > > > +	struct clk *pll_hdmiphy0;
> > > >  
> > > >  	/* optional internal rgb encoder */
> > > >  	struct rockchip_rgb *rgb;
> > > > @@ -220,6 +222,8 @@ struct vop2 {
> > > >  	struct vop2_win win[];
> > > >  };
> > > >  
> > > > +#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
> > > > +
> > > >  #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
> > > >  					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
> > > >  
> > > > @@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
> > > >  
> > > >  	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
> > > >  
> > > > +	if (vp->dclk_src)
> > > > +		clk_set_parent(vp->dclk, vp->dclk_src);
> > > > +
> > > >  	clk_disable_unprepare(vp->dclk);
> > > >  
> > > >  	vop2->enable_count--;
> > > > @@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
> > > >  
> > > >  	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
> > > >  
> > > > +	/*
> > > > +	 * Switch to HDMI PHY PLL as DCLK source for display modes up
> > > > +	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
> > > > +	 */
> > > > +	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
> > > > +		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
> > > > +			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
> > > > +
> > > > +			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
> > > > +				if (!vp->dclk_src)
> > > > +					vp->dclk_src = clk_get_parent(vp->dclk);
> > > > +
> > > > +				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
> > > > +				if (ret < 0)
> > > > +					drm_warn(vop2->drm,
> > > > +						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
> > > > +				break;
> > > > +			}
> > > > +		}
> > > > +	}
> > > > +
> > > 
> > > It seems pretty fragile to do it at atomic_enable time, even more so
> > > since you don't lock the parent either.
> > > 
> > > Any reason not to do it in the DRM or clock driver probe, and make sure
> > > you never change the parent somehow?
> > 
> > On rk3588 we have 3 dclk_s and 2 hdmi controllers. Each video-port can
> > use the clock generated from either the hdmi0phy or hdmi1phy, depending
> > on which hdmi-controller it uses.
> > 
> > So you actually need to know which vpX will output to which hdmiY to then
> > reparent that dclk to the hdmiphy output.
> 
> The Rockchip nomenclature isn't super obvious to me, sorry. Is there a
> datasheet for this somewhere? Also, does this vpX -> HDMI-Y mapping need
> to be dynamic?

VPs are CRTCs in drm-language and each of them can drive a differing
number of output encoders. Those video-ports also have differing output
characteristics in terms of supported resolution and other properties.

The rk3588 TRM has leaked in a number of places, and if you find a
TRM-part2, there is a section labeled "Display Output Interface Description"
that has a nice graphic for that.

Or in short:
- CRTC(VP)0 supports 8K resolution and can drive DP0+1, HDMI0+1, eDP0+1
  [if I'm reading things correctly, 8K together with CRTC1 somehow)
- CRTC(VP)1 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP0+1
- CRTC(VP)2 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP01, DSI0+1
- CRTC(VP)3 supports 2K resolution and can drive DSI0+1 and some BT1120,BT656

so for the 3 higher resolution CRTCs there are essentially 6 or 8 output options
depending on the board design




From scclevenger at os.amperecomputing.com  Wed Dec 11 10:01:41 2024
From: scclevenger at os.amperecomputing.com (Steve Clevenger)
Date: Wed, 11 Dec 2024 10:01:41 -0800
Subject: [PATCH] coresight: docs: Remove target sink from examples
In-Reply-To: <20241210144933.295798-1-james.clark@linaro.org>
References: <20241210144933.295798-1-james.clark@linaro.org>
Message-ID: <9e53f5b9-d8a9-46b8-8ff1-7f018e2d9c06@os.amperecomputing.com>


Hi James,

I thought I'd mention this issue with multicore self-hosted trace. The
perf command line syntax does not allow a sink "type" to be specified
(e.g. @tmc_etf or @tmc_etr). For multicore, it doesn't make sense to
specify a processor mapped sink as would be the case for single core
trace. A sink "type" should be allowed to avoid the auto select default.
In our case, the default is the ETF sink.

Thanks,
Steve C.

On 12/10/2024 6:49 AM, James Clark wrote:
> Previously the sink had to be specified, but now it auto selects one by
> default. Including a sink in the examples causes issues when copy
> pasting the command because it might not work if that sink isn't
> present. Remove the sink from all the basic examples and create a new
> section specifically about overriding the default one.
> 
> Make the text a but more concise now that it's in the advanced section,
> and similarly for removing the old kernel advice.
> 
> Signed-off-by: James Clark <james.clark at linaro.org>
> ---
>  Documentation/trace/coresight/coresight.rst   | 41 ++++++++-----------
>  .../userspace-api/perf_ring_buffer.rst        |  4 +-
>  2 files changed, 18 insertions(+), 27 deletions(-)
> 
> diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst
> index d4f93d6a2d63..806699871b80 100644
> --- a/Documentation/trace/coresight/coresight.rst
> +++ b/Documentation/trace/coresight/coresight.rst
> @@ -462,44 +462,35 @@ queried by the perf command line tool:
>  
>  		cs_etm//                                    [Kernel PMU event]
>  
> -	linaro at linaro-nano:~$
> -
>  Regardless of the number of tracers available in a system (usually equal to the
>  amount of processor cores), the "cs_etm" PMU will be listed only once.
>  
>  A Coresight PMU works the same way as any other PMU, i.e the name of the PMU is
> -listed along with configuration options within forward slashes '/'.  Since a
> -Coresight system will typically have more than one sink, the name of the sink to
> -work with needs to be specified as an event option.
> -On newer kernels the available sinks are listed in sysFS under
> +provided along with configuration options within forward slashes '/' (see
> +`Config option formats`_).
> +
> +Advanced Perf framework usage
> +-----------------------------
> +
> +Sink selection
> +~~~~~~~~~~~~~~
> +
> +An appropriate sink will be selected automatically for use with Perf, but since
> +there will typically be more than one sink, the name of the sink to use may be
> +specified as a special config option prefixed with '@'.
> +
> +The available sinks are listed in sysFS under
>  ($SYSFS)/bus/event_source/devices/cs_etm/sinks/::
>  
>  	root at localhost:/sys/bus/event_source/devices/cs_etm/sinks# ls
>  	tmc_etf0  tmc_etr0  tpiu0
>  
> -On older kernels, this may need to be found from the list of coresight devices,
> -available under ($SYSFS)/bus/coresight/devices/::
> -
> -	root:~# ls /sys/bus/coresight/devices/
> -	 etm0     etm1     etm2         etm3  etm4      etm5      funnel0
> -	 funnel1  funnel2  replicator0  stm0  tmc_etf0  tmc_etr0  tpiu0
>  	root at linaro-nano:~# perf record -e cs_etm/@tmc_etr0/u --per-thread program
>  
> -As mentioned above in section "Device Naming scheme", the names of the devices could
> -look different from what is used in the example above. One must use the device names
> -as it appears under the sysFS.
> -
> -The syntax within the forward slashes '/' is important.  The '@' character
> -tells the parser that a sink is about to be specified and that this is the sink
> -to use for the trace session.
> -
>  More information on the above and other example on how to use Coresight with
>  the perf tools can be found in the "HOWTO.md" file of the openCSD gitHub
>  repository [#third]_.
>  
> -Advanced perf framework usage
> ------------------------------
> -
>  AutoFDO analysis using the perf tools
>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>  
> @@ -508,7 +499,7 @@ perf can be used to record and analyze trace of programs.
>  Execution can be recorded using 'perf record' with the cs_etm event,
>  specifying the name of the sink to record to, e.g::
>  
> -    perf record -e cs_etm/@tmc_etr0/u --per-thread
> +    perf record -e cs_etm//u --per-thread
>  
>  The 'perf report' and 'perf script' commands can be used to analyze execution,
>  synthesizing instruction and branch events from the instruction trace.
> @@ -572,7 +563,7 @@ sort example is from the AutoFDO tutorial (https://gcc.gnu.org/wiki/AutoFDO/Tuto
>  	Bubble sorting array of 30000 elements
>  	5910 ms
>  
> -	$ perf record -e cs_etm/@tmc_etr0/u --per-thread taskset -c 2 ./sort
> +	$ perf record -e cs_etm//u --per-thread taskset -c 2 ./sort
>  	Bubble sorting array of 30000 elements
>  	12543 ms
>  	[ perf record: Woken up 35 times to write data ]
> diff --git a/Documentation/userspace-api/perf_ring_buffer.rst b/Documentation/userspace-api/perf_ring_buffer.rst
> index bde9d8cbc106..dc71544532ce 100644
> --- a/Documentation/userspace-api/perf_ring_buffer.rst
> +++ b/Documentation/userspace-api/perf_ring_buffer.rst
> @@ -627,7 +627,7 @@ regular ring buffer.
>  AUX events and AUX trace data are two different things.  Let's see an
>  example::
>  
> -        perf record -a -e cycles -e cs_etm/@tmc_etr0/ -- sleep 2
> +        perf record -a -e cycles -e cs_etm// -- sleep 2
>  
>  The above command enables two events: one is the event *cycles* from PMU
>  and another is the AUX event *cs_etm* from Arm CoreSight, both are saved
> @@ -766,7 +766,7 @@ only record AUX trace data at a specific time point which users are
>  interested in.  E.g. below gives an example of how to take snapshots
>  with 1 second interval with Arm CoreSight::
>  
> -  perf record -e cs_etm/@tmc_etr0/u -S -a program &
> +  perf record -e cs_etm//u -S -a program &
>    PERFPID=$!
>    while true; do
>        kill -USR2 $PERFPID



From quic_molvera at quicinc.com  Wed Dec 11 10:46:09 2024
From: quic_molvera at quicinc.com (Melody Olvera)
Date: Wed, 11 Dec 2024 10:46:09 -0800
Subject: [PATCH v3 6/7] arm64: dts: qcom: Add board dts files for SM8750
 MTP and QRD
In-Reply-To: <79e55e6e-e560-4f43-8d6e-bbaf7fcf157a@quicinc.com>
References: <20241204-sm8750_master_dt-v3-0-4d5a8269950b@quicinc.com>
 <20241204-sm8750_master_dt-v3-6-4d5a8269950b@quicinc.com>
 <b9225284-7830-4aa4-aed2-7f58fb7320e8@oss.qualcomm.com>
 <79e55e6e-e560-4f43-8d6e-bbaf7fcf157a@quicinc.com>
Message-ID: <f353a230-b9ab-4c25-846b-6e5f0e404ca0@quicinc.com>



On 12/5/2024 10:21 AM, Melody Olvera wrote:
>
>
> On 12/5/2024 8:45 AM, Konrad Dybcio wrote:
>> On 5.12.2024 12:18 AM, Melody Olvera wrote:
>>> Add MTP and QRD dts files for SM8750 describing board clocks, 
>>> regulators,
>>> gpio keys, etc.
>>>
>>> Signed-off-by: Melody Olvera <quic_molvera at quicinc.com>
>>> ---
>> [...]
>>
>> Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>
>>> +&tlmm {
>>> +??? /* reserved for secure world */
>>> +??? gpio-reserved-ranges = <36 4>, <74 1>;
>>> +};
>> Any chance you could describe what those specifically are?
>>
>
> I'm not too certain, and even if I was, I'm not certain I'd be at 
> liberty to say.

Spoke w some folks; looks like we're suing these for NFC eSE. I can add 
in next ps.

Thanks,
Melody


From sashal at kernel.org  Wed Dec 11 10:49:37 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed, 11 Dec 2024 13:49:37 -0500
Subject: [PATCH AUTOSEL 6.12 21/36] bpf: Zero index arg error string for dynptr and iter
In-Reply-To: <20241211185028.3841047-1-sashal@kernel.org>
References: <20241211185028.3841047-1-sashal@kernel.org>
Message-ID: <20241211185028.3841047-21-sashal@kernel.org>

From: Kumar Kartikeya Dwivedi <memxor at gmail.com>

[ Upstream commit bd74e238ae6944b462f57ce8752440a011ba4530 ]

Andrii spotted that process_dynptr_func's rejection of incorrect
argument register type will print an error string where argument numbers
are not zero-indexed, unlike elsewhere in the verifier.  Fix this by
subtracting 1 from regno. The same scenario exists for iterator
messages. Fix selftest error strings that match on the exact argument
number while we're at it to ensure clean bisection.

Suggested-by: Andrii Nakryiko <andrii at kernel.org>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor at gmail.com>
Link: https://lore.kernel.org/r/20241203002235.3776418-1-memxor at gmail.com
Signed-off-by: Alexei Starovoitov <ast at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 kernel/bpf/verifier.c                         | 12 +++++-----
 .../testing/selftests/bpf/progs/dynptr_fail.c | 22 +++++++++----------
 .../selftests/bpf/progs/iters_state_safety.c  | 14 ++++++------
 .../selftests/bpf/progs/iters_testmod_seq.c   |  4 ++--
 .../bpf/progs/test_kfunc_dynptr_param.c       |  2 +-
 .../selftests/bpf/progs/verifier_bits_iter.c  |  4 ++--
 6 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 91317857ea3ee..436a83784b7d2 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -7903,7 +7903,7 @@ static int process_dynptr_func(struct bpf_verifier_env *env, int regno, int insn
 	if (reg->type != PTR_TO_STACK && reg->type != CONST_PTR_TO_DYNPTR) {
 		verbose(env,
 			"arg#%d expected pointer to stack or const struct bpf_dynptr\n",
-			regno);
+			regno - 1);
 		return -EINVAL;
 	}
 
@@ -7957,7 +7957,7 @@ static int process_dynptr_func(struct bpf_verifier_env *env, int regno, int insn
 		if (!is_dynptr_reg_valid_init(env, reg)) {
 			verbose(env,
 				"Expected an initialized dynptr as arg #%d\n",
-				regno);
+				regno - 1);
 			return -EINVAL;
 		}
 
@@ -7965,7 +7965,7 @@ static int process_dynptr_func(struct bpf_verifier_env *env, int regno, int insn
 		if (!is_dynptr_type_expected(env, reg, arg_type & ~MEM_RDONLY)) {
 			verbose(env,
 				"Expected a dynptr of type %s as arg #%d\n",
-				dynptr_type_str(arg_to_dynptr_type(arg_type)), regno);
+				dynptr_type_str(arg_to_dynptr_type(arg_type)), regno - 1);
 			return -EINVAL;
 		}
 
@@ -8029,7 +8029,7 @@ static int process_iter_arg(struct bpf_verifier_env *env, int regno, int insn_id
 	 */
 	btf_id = btf_check_iter_arg(meta->btf, meta->func_proto, regno - 1);
 	if (btf_id < 0) {
-		verbose(env, "expected valid iter pointer as arg #%d\n", regno);
+		verbose(env, "expected valid iter pointer as arg #%d\n", regno - 1);
 		return -EINVAL;
 	}
 	t = btf_type_by_id(meta->btf, btf_id);
@@ -8039,7 +8039,7 @@ static int process_iter_arg(struct bpf_verifier_env *env, int regno, int insn_id
 		/* bpf_iter_<type>_new() expects pointer to uninit iter state */
 		if (!is_iter_reg_valid_uninit(env, reg, nr_slots)) {
 			verbose(env, "expected uninitialized iter_%s as arg #%d\n",
-				iter_type_str(meta->btf, btf_id), regno);
+				iter_type_str(meta->btf, btf_id), regno - 1);
 			return -EINVAL;
 		}
 
@@ -8063,7 +8063,7 @@ static int process_iter_arg(struct bpf_verifier_env *env, int regno, int insn_id
 			break;
 		case -EINVAL:
 			verbose(env, "expected an initialized iter_%s as arg #%d\n",
-				iter_type_str(meta->btf, btf_id), regno);
+				iter_type_str(meta->btf, btf_id), regno - 1);
 			return err;
 		case -EPROTO:
 			verbose(env, "expected an RCU CS when using %s\n", meta->func_name);
diff --git a/tools/testing/selftests/bpf/progs/dynptr_fail.c b/tools/testing/selftests/bpf/progs/dynptr_fail.c
index 8f36c9de75915..dfd817d0348c4 100644
--- a/tools/testing/selftests/bpf/progs/dynptr_fail.c
+++ b/tools/testing/selftests/bpf/progs/dynptr_fail.c
@@ -149,7 +149,7 @@ int ringbuf_release_uninit_dynptr(void *ctx)
 
 /* A dynptr can't be used after it has been invalidated */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #3")
+__failure __msg("Expected an initialized dynptr as arg #2")
 int use_after_invalid(void *ctx)
 {
 	struct bpf_dynptr ptr;
@@ -428,7 +428,7 @@ int invalid_helper2(void *ctx)
 
 /* A bpf_dynptr is invalidated if it's been written into */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #1")
+__failure __msg("Expected an initialized dynptr as arg #0")
 int invalid_write1(void *ctx)
 {
 	struct bpf_dynptr ptr;
@@ -1407,7 +1407,7 @@ int invalid_slice_rdwr_rdonly(struct __sk_buff *skb)
 
 /* bpf_dynptr_adjust can only be called on initialized dynptrs */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #1")
+__failure __msg("Expected an initialized dynptr as arg #0")
 int dynptr_adjust_invalid(void *ctx)
 {
 	struct bpf_dynptr ptr = {};
@@ -1420,7 +1420,7 @@ int dynptr_adjust_invalid(void *ctx)
 
 /* bpf_dynptr_is_null can only be called on initialized dynptrs */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #1")
+__failure __msg("Expected an initialized dynptr as arg #0")
 int dynptr_is_null_invalid(void *ctx)
 {
 	struct bpf_dynptr ptr = {};
@@ -1433,7 +1433,7 @@ int dynptr_is_null_invalid(void *ctx)
 
 /* bpf_dynptr_is_rdonly can only be called on initialized dynptrs */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #1")
+__failure __msg("Expected an initialized dynptr as arg #0")
 int dynptr_is_rdonly_invalid(void *ctx)
 {
 	struct bpf_dynptr ptr = {};
@@ -1446,7 +1446,7 @@ int dynptr_is_rdonly_invalid(void *ctx)
 
 /* bpf_dynptr_size can only be called on initialized dynptrs */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #1")
+__failure __msg("Expected an initialized dynptr as arg #0")
 int dynptr_size_invalid(void *ctx)
 {
 	struct bpf_dynptr ptr = {};
@@ -1459,7 +1459,7 @@ int dynptr_size_invalid(void *ctx)
 
 /* Only initialized dynptrs can be cloned */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #1")
+__failure __msg("Expected an initialized dynptr as arg #0")
 int clone_invalid1(void *ctx)
 {
 	struct bpf_dynptr ptr1 = {};
@@ -1493,7 +1493,7 @@ int clone_invalid2(struct xdp_md *xdp)
 
 /* Invalidating a dynptr should invalidate its clones */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #3")
+__failure __msg("Expected an initialized dynptr as arg #2")
 int clone_invalidate1(void *ctx)
 {
 	struct bpf_dynptr clone;
@@ -1514,7 +1514,7 @@ int clone_invalidate1(void *ctx)
 
 /* Invalidating a dynptr should invalidate its parent */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #3")
+__failure __msg("Expected an initialized dynptr as arg #2")
 int clone_invalidate2(void *ctx)
 {
 	struct bpf_dynptr ptr;
@@ -1535,7 +1535,7 @@ int clone_invalidate2(void *ctx)
 
 /* Invalidating a dynptr should invalidate its siblings */
 SEC("?raw_tp")
-__failure __msg("Expected an initialized dynptr as arg #3")
+__failure __msg("Expected an initialized dynptr as arg #2")
 int clone_invalidate3(void *ctx)
 {
 	struct bpf_dynptr ptr;
@@ -1723,7 +1723,7 @@ __noinline long global_call_bpf_dynptr(const struct bpf_dynptr *dynptr)
 }
 
 SEC("?raw_tp")
-__failure __msg("arg#1 expected pointer to stack or const struct bpf_dynptr")
+__failure __msg("arg#0 expected pointer to stack or const struct bpf_dynptr")
 int test_dynptr_reg_type(void *ctx)
 {
 	struct task_struct *current = NULL;
diff --git a/tools/testing/selftests/bpf/progs/iters_state_safety.c b/tools/testing/selftests/bpf/progs/iters_state_safety.c
index d47e59aba6de3..f41257eadbb25 100644
--- a/tools/testing/selftests/bpf/progs/iters_state_safety.c
+++ b/tools/testing/selftests/bpf/progs/iters_state_safety.c
@@ -73,7 +73,7 @@ int create_and_forget_to_destroy_fail(void *ctx)
 }
 
 SEC("?raw_tp")
-__failure __msg("expected an initialized iter_num as arg #1")
+__failure __msg("expected an initialized iter_num as arg #0")
 int destroy_without_creating_fail(void *ctx)
 {
 	/* init with zeros to stop verifier complaining about uninit stack */
@@ -91,7 +91,7 @@ int destroy_without_creating_fail(void *ctx)
 }
 
 SEC("?raw_tp")
-__failure __msg("expected an initialized iter_num as arg #1")
+__failure __msg("expected an initialized iter_num as arg #0")
 int compromise_iter_w_direct_write_fail(void *ctx)
 {
 	struct bpf_iter_num iter;
@@ -143,7 +143,7 @@ int compromise_iter_w_direct_write_and_skip_destroy_fail(void *ctx)
 }
 
 SEC("?raw_tp")
-__failure __msg("expected an initialized iter_num as arg #1")
+__failure __msg("expected an initialized iter_num as arg #0")
 int compromise_iter_w_helper_write_fail(void *ctx)
 {
 	struct bpf_iter_num iter;
@@ -230,7 +230,7 @@ int valid_stack_reuse(void *ctx)
 }
 
 SEC("?raw_tp")
-__failure __msg("expected uninitialized iter_num as arg #1")
+__failure __msg("expected uninitialized iter_num as arg #0")
 int double_create_fail(void *ctx)
 {
 	struct bpf_iter_num iter;
@@ -258,7 +258,7 @@ int double_create_fail(void *ctx)
 }
 
 SEC("?raw_tp")
-__failure __msg("expected an initialized iter_num as arg #1")
+__failure __msg("expected an initialized iter_num as arg #0")
 int double_destroy_fail(void *ctx)
 {
 	struct bpf_iter_num iter;
@@ -284,7 +284,7 @@ int double_destroy_fail(void *ctx)
 }
 
 SEC("?raw_tp")
-__failure __msg("expected an initialized iter_num as arg #1")
+__failure __msg("expected an initialized iter_num as arg #0")
 int next_without_new_fail(void *ctx)
 {
 	struct bpf_iter_num iter;
@@ -305,7 +305,7 @@ int next_without_new_fail(void *ctx)
 }
 
 SEC("?raw_tp")
-__failure __msg("expected an initialized iter_num as arg #1")
+__failure __msg("expected an initialized iter_num as arg #0")
 int next_after_destroy_fail(void *ctx)
 {
 	struct bpf_iter_num iter;
diff --git a/tools/testing/selftests/bpf/progs/iters_testmod_seq.c b/tools/testing/selftests/bpf/progs/iters_testmod_seq.c
index 4a176e6aede89..6543d5b6e0a97 100644
--- a/tools/testing/selftests/bpf/progs/iters_testmod_seq.c
+++ b/tools/testing/selftests/bpf/progs/iters_testmod_seq.c
@@ -79,7 +79,7 @@ int testmod_seq_truncated(const void *ctx)
 
 SEC("?raw_tp")
 __failure
-__msg("expected an initialized iter_testmod_seq as arg #2")
+__msg("expected an initialized iter_testmod_seq as arg #1")
 int testmod_seq_getter_before_bad(const void *ctx)
 {
 	struct bpf_iter_testmod_seq it;
@@ -89,7 +89,7 @@ int testmod_seq_getter_before_bad(const void *ctx)
 
 SEC("?raw_tp")
 __failure
-__msg("expected an initialized iter_testmod_seq as arg #2")
+__msg("expected an initialized iter_testmod_seq as arg #1")
 int testmod_seq_getter_after_bad(const void *ctx)
 {
 	struct bpf_iter_testmod_seq it;
diff --git a/tools/testing/selftests/bpf/progs/test_kfunc_dynptr_param.c b/tools/testing/selftests/bpf/progs/test_kfunc_dynptr_param.c
index e68667aec6a65..cd4d752bd089c 100644
--- a/tools/testing/selftests/bpf/progs/test_kfunc_dynptr_param.c
+++ b/tools/testing/selftests/bpf/progs/test_kfunc_dynptr_param.c
@@ -45,7 +45,7 @@ int BPF_PROG(not_valid_dynptr, int cmd, union bpf_attr *attr, unsigned int size)
 }
 
 SEC("?lsm.s/bpf")
-__failure __msg("arg#1 expected pointer to stack or const struct bpf_dynptr")
+__failure __msg("arg#0 expected pointer to stack or const struct bpf_dynptr")
 int BPF_PROG(not_ptr_to_stack, int cmd, union bpf_attr *attr, unsigned int size)
 {
 	unsigned long val = 0;
diff --git a/tools/testing/selftests/bpf/progs/verifier_bits_iter.c b/tools/testing/selftests/bpf/progs/verifier_bits_iter.c
index 7c881bca9af5c..497febf5c578d 100644
--- a/tools/testing/selftests/bpf/progs/verifier_bits_iter.c
+++ b/tools/testing/selftests/bpf/progs/verifier_bits_iter.c
@@ -32,7 +32,7 @@ int BPF_PROG(no_destroy, struct bpf_iter_meta *meta, struct cgroup *cgrp)
 
 SEC("iter/cgroup")
 __description("uninitialized iter in ->next()")
-__failure __msg("expected an initialized iter_bits as arg #1")
+__failure __msg("expected an initialized iter_bits as arg #0")
 int BPF_PROG(next_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp)
 {
 	struct bpf_iter_bits *it = NULL;
@@ -43,7 +43,7 @@ int BPF_PROG(next_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp)
 
 SEC("iter/cgroup")
 __description("uninitialized iter in ->destroy()")
-__failure __msg("expected an initialized iter_bits as arg #1")
+__failure __msg("expected an initialized iter_bits as arg #0")
 int BPF_PROG(destroy_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp)
 {
 	struct bpf_iter_bits it = {};
-- 
2.43.0



From sashal at kernel.org  Wed Dec 11 10:49:46 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed, 11 Dec 2024 13:49:46 -0500
Subject: [PATCH AUTOSEL 6.12 30/36] ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A
In-Reply-To: <20241211185028.3841047-1-sashal@kernel.org>
References: <20241211185028.3841047-1-sashal@kernel.org>
Message-ID: <20241211185028.3841047-30-sashal@kernel.org>

From: Qinxin Xia <xiaqinxin at huawei.com>

[ Upstream commit c2b46ae022704a2d845e59461fa24431ad627022 ]

HiSilicon HIP09A platforms using the same SMMU PMCG with HIP09
and thus suffers the same erratum. List them in the PMCG platform
information list without introducing a new SMMU PMCG Model.

Update the silicon-errata.rst as well.

Reviewed-by: Yicong Yang <yangyicong at hisilicon.com>
Acked-by: Hanjun Guo <guohanjun at huawei.com>
Signed-off-by: Qinxin Xia <xiaqinxin at huawei.com>
Link: https://lore.kernel.org/r/20241205013331.1484017-1-xiaqinxin at huawei.com
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/arch/arm64/silicon-errata.rst | 5 +++--
 drivers/acpi/arm64/iort.c                   | 2 ++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index 65bfab1b18614..a678ea0ae4a00 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -255,8 +255,9 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | Hisilicon      | Hip08 SMMU PMCG | #162001800      | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
-| Hisilicon      | Hip{08,09,10,10C| #162001900      | N/A                         |
-|                | ,11} SMMU PMCG  |                 |                             |
+| Hisilicon      | Hip{08,09,09A,10| #162001900      | N/A                         |
+|                | ,10C,11}        |                 |                             |
+|                | SMMU PMCG       |                 |                             |
 +----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
 | Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 4c745a26226b2..bf3be532e0895 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1703,6 +1703,8 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = {
 	/* HiSilicon Hip09 Platform */
 	{"HISI  ", "HIP09   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
 	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+	{"HISI  ", "HIP09A  ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
 	/* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */
 	{"HISI  ", "HIP10   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
 	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
-- 
2.43.0



From sashal at kernel.org  Wed Dec 11 10:51:39 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed, 11 Dec 2024 13:51:39 -0500
Subject: [PATCH AUTOSEL 6.6 02/23] watchdog: mediatek: Add support for MT6735 TOPRGU/WDT
In-Reply-To: <20241211185214.3841978-1-sashal@kernel.org>
References: <20241211185214.3841978-1-sashal@kernel.org>
Message-ID: <20241211185214.3841978-2-sashal@kernel.org>

From: Yassine Oudjana <y.oudjana at protonmail.com>

[ Upstream commit 15ddf704f56f8c95ff74dfd1157ed8646b322fa1 ]

Add support for the Top Reset Generation Unit/Watchdog Timer found on
MT6735.

Signed-off-by: Yassine Oudjana <y.oudjana at protonmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
Link: https://lore.kernel.org/r/20241106104738.195968-3-y.oudjana at protonmail.com
Signed-off-by: Guenter Roeck <linux at roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim at linux-watchdog.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/watchdog/mtk_wdt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index b2330b16b497a..f8c90555d0b03 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -10,6 +10,7 @@
  */
 
 #include <dt-bindings/reset/mt2712-resets.h>
+#include <dt-bindings/reset/mediatek,mt6735-wdt.h>
 #include <dt-bindings/reset/mediatek,mt6795-resets.h>
 #include <dt-bindings/reset/mt7986-resets.h>
 #include <dt-bindings/reset/mt8183-resets.h>
@@ -81,6 +82,10 @@ static const struct mtk_wdt_data mt2712_data = {
 	.toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
 };
 
+static const struct mtk_wdt_data mt6735_data = {
+	.toprgu_sw_rst_num = MT6735_TOPRGU_RST_NUM,
+};
+
 static const struct mtk_wdt_data mt6795_data = {
 	.toprgu_sw_rst_num = MT6795_TOPRGU_SW_RST_NUM,
 };
@@ -442,6 +447,7 @@ static int mtk_wdt_resume(struct device *dev)
 static const struct of_device_id mtk_wdt_dt_ids[] = {
 	{ .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
 	{ .compatible = "mediatek,mt6589-wdt" },
+	{ .compatible = "mediatek,mt6735-wdt", .data = &mt6735_data },
 	{ .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data },
 	{ .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
 	{ .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
-- 
2.43.0



From peter at korsgaard.com  Wed Dec 11 10:54:37 2024
From: peter at korsgaard.com (Peter Korsgaard)
Date: Wed, 11 Dec 2024 19:54:37 +0100
Subject: [PATCH 01/15] ARM: zynq: Replace 'io-standard' with
 'power-source' property
In-Reply-To: <cf45ed95fe0be083446d5aaf5f946f38acba7728.1733920873.git.michal.simek@amd.com>
References: <cover.1733920873.git.michal.simek@amd.com>
 <cf45ed95fe0be083446d5aaf5f946f38acba7728.1733920873.git.michal.simek@amd.com>
Message-ID: <9e6f04e1-26d2-4dbb-ab34-da39d4fee739@korsgaard.com>

On 12/11/24 13:41, Michal Simek wrote:
> From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
> 
> Replace 'io-standard' property with 'power-source' property in all
> zynq dts files to be in sync with Zynq Pinctrl driver.
> 
> Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> Signed-off-by: Michal Simek <michal.simek at amd.com>

Reviewed-by: Peter Korsgaard <peter at korsgaard.com>

>   			slew-rate = <0>;
> -			io-standard = <1>;
> +			power-source = <1>;

It would be nice to replace those magic numbers with the corresponding 
IO_STANDARD_* defines for readability.

-- 
Bye, Peter Korsgaard



From marex at denx.de  Wed Dec 11 10:31:12 2024
From: marex at denx.de (Marek Vasut)
Date: Wed, 11 Dec 2024 19:31:12 +0100
Subject: [PATCH v4] watchdog: stm32_iwdg: Add pretimeout support
In-Reply-To: <49ccec07-4d4c-4582-814b-d4a60adbbfe1@foss.st.com>
References: <20240415134903.8084-1-marex@denx.de>
 <49ccec07-4d4c-4582-814b-d4a60adbbfe1@foss.st.com>
Message-ID: <656838f1-40e5-44de-aaba-d8f5ba496af7@denx.de>

On 12/11/24 10:02 AM, Clement LE GOFFIC wrote:
> On 4/15/24 15:48, Marek Vasut wrote:
>> The STM32MP15xx IWDG adds registers which permit this IP to generate
>> pretimeout interrupt. This interrupt can also be used to wake the CPU
>> from suspend. Implement support for generating this interrupt and let
>> userspace configure the pretimeout. In case the pretimeout is not
>> configured by user, set pretimeout to 3/4 of the WDT timeout cycle.
>>
>> Reviewed-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
>> Tested-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
>> Signed-off-by: Marek Vasut <marex at denx.de>
>> ---
>> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
>> Cc: Guenter Roeck <linux at roeck-us.net>
>> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
>> Cc: Wim Van Sebroeck <wim at linux-watchdog.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-stm32 at st-md-mailman.stormreply.com
>> Cc: linux-watchdog at vger.kernel.org
>> ---
>> V2: - Subtract the pretimeout value from timeout value before writing it
>> ?????? into the IWDG pretimeout register, because the watchdog counter
>> ?????? register is counting down, and the pretimeout interrupt triggers
>> ?????? when watchdog counter register matches the pretimeout register
>> ?????? content.
>> ???? - Set default pretimeout to 3/4 of timeout .
>> V3: - Use dev instead of pdev->dev
>> ???? - Swap order of ret/return 0
>> ???? - Split this from the DT changes, which are orthogonal
>> ???? - Uh, this patch got stuck in upstreaming queue, sorry
>> V4: - Update commit message to match V2 default pretimeout to 3/4
>> ???? - Add RB/TB from Cl?ment
>> ---
>> ? drivers/watchdog/stm32_iwdg.c | 95 ++++++++++++++++++++++++++++++++++-
>> ? 1 file changed, 94 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/ 
>> stm32_iwdg.c
>> index 5404e03876202..d700e0d49bb95 100644
>> --- a/drivers/watchdog/stm32_iwdg.c
>> +++ b/drivers/watchdog/stm32_iwdg.c
>>
>> ?[.....]
>>
>> +
>> +??? irq = platform_get_irq(pdev, 0);
>> +??? if (irq <= 0)
>> +??????? return 0;
> 
> Hi Marek,
> 
> After re-evaluating this patch, it seems it lacks of a dt-bindings 
> update that tackles the 'interrupts' property you are adding.
> 
> That said, the interrupt line should not be mandatory for the driver to 
> probe. For backward compatibility with existing DT, I recommend to use 
> the 'platform_get_irq_optional()' API to not fail during the probe of 
> the driver.
I saw the fix
[PATCH] watchdog: stm32_iwdg: fix DT backward compatibility
Thank you for that. I'll wait for V2 with updated commit message .

As far as I understood the problem, the goal is to remove error message 
printed by the platform_get_irq() in case the DT interrupt property is 
missing, but this is only an esthetic fix, not a functional one, because 
the driver probes even if the interrupts DT property is missing, it only 
prints the error message while at it, correct ?


From sashal at kernel.org  Wed Dec 11 10:49:19 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed, 11 Dec 2024 13:49:19 -0500
Subject: [PATCH AUTOSEL 6.12 03/36] Revert "watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs"
In-Reply-To: <20241211185028.3841047-1-sashal@kernel.org>
References: <20241211185028.3841047-1-sashal@kernel.org>
Message-ID: <20241211185028.3841047-3-sashal@kernel.org>

From: Peter Griffin <peter.griffin at linaro.org>

[ Upstream commit ccfb765944bb66813398958983cb8141e2624a6b ]

This reverts commit 746f0770f916e6c48e422d6a34e67eae16707f0e.

Now that we can register a SoC specific regmap with syscon using
of_syscon_register_regmap() api we can switch back to using
syscon_regmap_lookup_by_phandle() in the client drivers.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
Link: https://lore.kernel.org/r/20241029191131.2329414-1-peter.griffin at linaro.org
Signed-off-by: Guenter Roeck <linux at roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim at linux-watchdog.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/watchdog/Kconfig       | 1 +
 drivers/watchdog/s3c2410_wdt.c | 8 ++++----
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 94c96bcfefe34..0b59c669c26d3 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -549,6 +549,7 @@ 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 686cf544d0ae7..349d30462c8c0 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 = exynos_get_pmu_regmap_by_phandle(dev->of_node,
-						 "samsung,syscon-phandle");
+		wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
+						"samsung,syscon-phandle");
 		if (IS_ERR(wdt->pmureg))
 			return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
-					     "PMU regmap lookup failed.\n");
+					     "syscon regmap lookup failed.\n");
 	}
 
 	wdt_irq = platform_get_irq(pdev, 0);
-- 
2.43.0



From sashal at kernel.org  Wed Dec 11 10:49:20 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed, 11 Dec 2024 13:49:20 -0500
Subject: [PATCH AUTOSEL 6.12 04/36] watchdog: mediatek: Add support for MT6735 TOPRGU/WDT
In-Reply-To: <20241211185028.3841047-1-sashal@kernel.org>
References: <20241211185028.3841047-1-sashal@kernel.org>
Message-ID: <20241211185028.3841047-4-sashal@kernel.org>

From: Yassine Oudjana <y.oudjana at protonmail.com>

[ Upstream commit 15ddf704f56f8c95ff74dfd1157ed8646b322fa1 ]

Add support for the Top Reset Generation Unit/Watchdog Timer found on
MT6735.

Signed-off-by: Yassine Oudjana <y.oudjana at protonmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
Link: https://lore.kernel.org/r/20241106104738.195968-3-y.oudjana at protonmail.com
Signed-off-by: Guenter Roeck <linux at roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim at linux-watchdog.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/watchdog/mtk_wdt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index c35f85ce8d69c..91a11715f6de5 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -10,6 +10,7 @@
  */
 
 #include <dt-bindings/reset/mt2712-resets.h>
+#include <dt-bindings/reset/mediatek,mt6735-wdt.h>
 #include <dt-bindings/reset/mediatek,mt6795-resets.h>
 #include <dt-bindings/reset/mt7986-resets.h>
 #include <dt-bindings/reset/mt8183-resets.h>
@@ -87,6 +88,10 @@ static const struct mtk_wdt_data mt2712_data = {
 	.toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
 };
 
+static const struct mtk_wdt_data mt6735_data = {
+	.toprgu_sw_rst_num = MT6735_TOPRGU_RST_NUM,
+};
+
 static const struct mtk_wdt_data mt6795_data = {
 	.toprgu_sw_rst_num = MT6795_TOPRGU_SW_RST_NUM,
 };
@@ -483,6 +488,7 @@ static int mtk_wdt_resume(struct device *dev)
 static const struct of_device_id mtk_wdt_dt_ids[] = {
 	{ .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
 	{ .compatible = "mediatek,mt6589-wdt" },
+	{ .compatible = "mediatek,mt6735-wdt", .data = &mt6735_data },
 	{ .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data },
 	{ .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
 	{ .compatible = "mediatek,mt7988-wdt", .data = &mt7988_data },
-- 
2.43.0



From sashal at kernel.org  Wed Dec 11 10:49:21 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed, 11 Dec 2024 13:49:21 -0500
Subject: [PATCH AUTOSEL 6.12 05/36] watchdog: s3c2410_wdt: add support for exynosautov920 SoC
In-Reply-To: <20241211185028.3841047-1-sashal@kernel.org>
References: <20241211185028.3841047-1-sashal@kernel.org>
Message-ID: <20241211185028.3841047-5-sashal@kernel.org>

From: Byoungtae Cho <bt.cho at samsung.com>

[ Upstream commit a5cb13980e00e9c4fbc382d68eda250ab6a14d7c ]

Adds the compatibles and drvdata for the ExynosAuto V920 SoC. This SoC
is almost similar to ExynosAutoV9, but some CPU configurations are quite
different, so it should be added. Plus it also support DBGACK like as
GS101 SoC.

Signed-off-by: Byoungtae Cho <bt.cho at samsung.com>
Signed-off-by: Taewan Kim <trunixs.kim at samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
Link: https://lore.kernel.org/r/20241021063903.793166-3-trunixs.kim at samsung.com
Signed-off-by: Guenter Roeck <linux at roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim at linux-watchdog.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/watchdog/s3c2410_wdt.c | 37 +++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 349d30462c8c0..30450e99e5e9d 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -63,6 +63,10 @@
 #define EXYNOS850_CLUSTER1_NONCPU_INT_EN	0x1644
 #define EXYNOSAUTOV9_CLUSTER1_NONCPU_OUT	0x1520
 #define EXYNOSAUTOV9_CLUSTER1_NONCPU_INT_EN	0x1544
+#define EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT	0x1420
+#define EXYNOSAUTOV920_CLUSTER0_NONCPU_INT_EN	0x1444
+#define EXYNOSAUTOV920_CLUSTER1_NONCPU_OUT	0x1720
+#define EXYNOSAUTOV920_CLUSTER1_NONCPU_INT_EN	0x1744
 
 #define EXYNOS850_CLUSTER0_WDTRESET_BIT		24
 #define EXYNOS850_CLUSTER1_WDTRESET_BIT		23
@@ -303,6 +307,32 @@ static const struct s3c2410_wdt_variant drv_data_gs101_cl1 = {
 		  QUIRK_HAS_DBGACK_BIT,
 };
 
+static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl0 = {
+	.mask_reset_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_INT_EN,
+	.mask_bit = 2,
+	.mask_reset_inv = true,
+	.rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET,
+	.rst_stat_bit = EXYNOSAUTOV9_CLUSTER0_WDTRESET_BIT,
+	.cnt_en_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT,
+	.cnt_en_bit = 7,
+	.quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET |
+		  QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN |
+		  QUIRK_HAS_DBGACK_BIT,
+};
+
+static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = {
+	.mask_reset_reg = EXYNOSAUTOV920_CLUSTER1_NONCPU_INT_EN,
+	.mask_bit = 2,
+	.mask_reset_inv = true,
+	.rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET,
+	.rst_stat_bit = EXYNOSAUTOV9_CLUSTER1_WDTRESET_BIT,
+	.cnt_en_reg = EXYNOSAUTOV920_CLUSTER1_NONCPU_OUT,
+	.cnt_en_bit = 7,
+	.quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET |
+		  QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN |
+		  QUIRK_HAS_DBGACK_BIT,
+};
+
 static const struct of_device_id s3c2410_wdt_match[] = {
 	{ .compatible = "google,gs101-wdt",
 	  .data = &drv_data_gs101_cl0 },
@@ -320,6 +350,8 @@ static const struct of_device_id s3c2410_wdt_match[] = {
 	  .data = &drv_data_exynos850_cl0 },
 	{ .compatible = "samsung,exynosautov9-wdt",
 	  .data = &drv_data_exynosautov9_cl0 },
+	{ .compatible = "samsung,exynosautov920-wdt",
+	  .data = &drv_data_exynosautov920_cl0 },
 	{},
 };
 MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
@@ -643,7 +675,8 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt)
 	/* Choose Exynos850/ExynosAutov9 driver data w.r.t. cluster index */
 	if (variant == &drv_data_exynos850_cl0 ||
 	    variant == &drv_data_exynosautov9_cl0 ||
-	    variant == &drv_data_gs101_cl0) {
+	    variant == &drv_data_gs101_cl0 ||
+	    variant == &drv_data_exynosautov920_cl0) {
 		u32 index;
 		int err;
 
@@ -662,6 +695,8 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt)
 				variant = &drv_data_exynosautov9_cl1;
 			else if (variant == &drv_data_gs101_cl0)
 				variant = &drv_data_gs101_cl1;
+			else if (variant == &drv_data_exynosautov920_cl0)
+				variant = &drv_data_exynosautov920_cl1;
 			break;
 		default:
 			return dev_err_probe(dev, -EINVAL, "wrong cluster index: %u\n", index);
-- 
2.43.0



From m.felsch at pengutronix.de  Wed Dec 11 10:57:05 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Wed, 11 Dec 2024 19:57:05 +0100
Subject: [PATCH v2 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <Z1m+O1UV4HD+7Rr2@lizhi-Precision-Tower-5810>
References: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
 <20241210-imx91tmu-v2-2-5032aad4d88e@nxp.com>
 <20241211154622.f2jwwrqansk6il3o@pengutronix.de>
 <Z1m+O1UV4HD+7Rr2@lizhi-Precision-Tower-5810>
Message-ID: <20241211185705.7b5uw26loobibzln@pengutronix.de>

On 24-12-11, Frank Li wrote:
> On Wed, Dec 11, 2024 at 04:46:22PM +0100, Marco Felsch wrote:
> > On 24-12-10, Frank Li wrote:
> > > From: Pengfei Li <pengfei.li_1 at nxp.com>
> > >
> > > Introduce support for the i.MX91 thermal monitoring unit, which features a
> > > single sensor for the CPU. The register layout differs from other chips,
> > > necessitating the creation of a dedicated file for this.
> > >
> > > Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
> > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > > ---
> > > change from v1 to v2
> > > - use low case for hexvalue
> > > - combine struct imx91_tmu and tmu_sensor
> > > - simplify imx91_tmu_start() and imx91_tmu_enable()
> > > - use s16 for imx91_tmu_get_temp(), which may negative value
> > > - use reverse christmas tree style
> > > - use run time pm
> > > - use oneshot to sample temp
> > > - register thermal zone after hardware init
> > > ---
> > >  drivers/thermal/Kconfig         |  10 ++
> > >  drivers/thermal/Makefile        |   1 +
> > >  drivers/thermal/imx91_thermal.c | 265 ++++++++++++++++++++++++++++++++++++++++
> > >  3 files changed, 276 insertions(+)
> > >
> > > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > > index d3f9686e26e71..da403ed86aeb1 100644
> > > --- a/drivers/thermal/Kconfig
> > > +++ b/drivers/thermal/Kconfig
> > > @@ -296,6 +296,16 @@ config IMX8MM_THERMAL
> > >  	  cpufreq is used as the cooling device to throttle CPUs when the passive
> > >  	  trip is crossed.
> > >
> > > +config IMX91_THERMAL
> > > +	tristate "Temperature sensor driver for NXP i.MX91 SoC"
> > > +	depends on ARCH_MXC || COMPILE_TEST
> > > +	depends on OF
> > > +	help
> > > +	  Support for Temperature sensor found on NXP i.MX91 SoC.
> > > +	  It supports one critical trip point and one passive trip point. The
> > > +	  cpufreq is used as the cooling device to throttle CPUs when the passive
> > > +	  trip is crossed.
> > > +
> > >  config K3_THERMAL
> > >  	tristate "Texas Instruments K3 thermal support"
> > >  	depends on ARCH_K3 || COMPILE_TEST
> > > diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> > > index 9abf43a74f2bb..08da241e6a598 100644
> > > --- a/drivers/thermal/Makefile
> > > +++ b/drivers/thermal/Makefile
> > > @@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
> > >  obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
> > >  obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
> > >  obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
> > > +obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
> > >  obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
> > >  obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
> > >  obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
> > > diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
> > > new file mode 100644
> > > index 0000000000000..ebb59eda92951
> > > --- /dev/null
> > > +++ b/drivers/thermal/imx91_thermal.c
> > > @@ -0,0 +1,265 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright 2024 NXP.
> > > + */
> > > +
> > > +#include <linux/bitfield.h>
> > > +#include <linux/clk.h>
> > > +#include <linux/err.h>
> > > +#include <linux/iopoll.h>
> > > +#include <linux/nvmem-consumer.h>
> > > +#include <linux/module.h>
> > > +#include <linux/of.h>
> > > +#include <linux/of_device.h>
> > > +#include <linux/platform_device.h>
> > > +#include <linux/pm_runtime.h>
> > > +#include <linux/thermal.h>
> > > +
> > > +#define CTRL0			0x0
> >
> > Unused
> >
> > > +
> > > +#define STAT0			0x10
> > > +#define STAT0_DRDY0_IF_MASK	BIT(16)
> > > +
> > > +#define DATA0			0x20
> > > +
> > > +#define THR_CTRL01		0x30
> > > +#define THR_CTRL23		0x40
> >
> > Both are unused too
> >
> > > +#define CTRL1			0x200
> >
> > Unused
> >
> > > +#define CTRL1_SET		0x204
> > > +#define CTRL1_CLR		0x208
> > > +#define CTRL1_EN		BIT(31)
> > > +#define CTRL1_START		BIT(30)
> > > +#define CTRL1_STOP		BIT(29)
> > > +#define CTRL1_RES_MASK		GENMASK(19, 18)
> > > +#define CTRL1_MEAS_MODE_MASK	GENMASK(25, 24)
> > > +#define   CTRL1_MEAS_MODE_SINGLE	0
> > > +#define   CTRL1_MEAS_MODE_CONTINUES	1
> > > +#define   CTRL1_MEAS_MODE_PERIODIC	2
> > > +
> > > +#define REF_DIV			0x280
> > > +#define DIV_EN			BIT(31)
> > > +#define DIV_MASK		GENMASK(23, 16)
> > > +
> > > +#define PUD_ST_CTRL		0x2B0
> > > +#define PUDL_MASK		GENMASK(23, 16)
> > > +
> > > +#define TRIM1			0x2E0
> > > +#define TRIM2			0x2F0
> > 					^
> > 				still upper-case
> >
> > > +#define TMU_TEMP_LOW_LIMIT	-40000
> > > +#define TMU_TEMP_HIGH_LIMIT	125000
> > > +
> > > +#define DEFAULT_TRIM1_CONFIG 0xb561bc2d
> > > +#define DEFAULT_TRIM2_CONFIG 0x65d4
> > > +
> > > +struct imx91_tmu {
> > > +	void __iomem *base;
> > > +	struct clk *clk;
> > > +	struct device *dev;
> > > +	struct thermal_zone_device *tzd;
> > > +};
> > > +
> > > +static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
> > > +{
> > > +	u32 val = start ? CTRL1_START : CTRL1_STOP;
> > > +
> > > +	writel_relaxed(val, tmu->base + CTRL1_SET);
> > > +}
> > > +
> > > +static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
> > > +{
> > > +	u32 reg = enable ? CTRL1_SET : CTRL1_CLR;
> > > +
> > > +	writel_relaxed(CTRL1_EN, tmu->base + reg);
> > > +}
> > > +
> > > +static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
> > > +{
> > > +	struct imx91_tmu *tmu = thermal_zone_device_priv(tz);
> > > +	s16 data;
> > > +	int ret;
> > > +	u32 val;
> > > +
> > > +	ret = pm_runtime_resume_and_get(tmu->dev);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	ret = readl_relaxed_poll_timeout(tmu->base + STAT0, val,
> > > +					 val & STAT0_DRDY0_IF_MASK, 1000,
> > > +					 40000);
> > > +	if (ret)
> > > +		return -EAGAIN;
> > 		 ^
> > Missing pm_runtime_put(). Instead goto out;
> >
> > > +
> > > +	/* DATA0 is 16bit signed number */
> > > +	data = readw_relaxed(tmu->base + DATA0);
> > > +	*temp = data * 1000 / 64;
> > > +	if (*temp < TMU_TEMP_LOW_LIMIT || *temp > TMU_TEMP_HIGH_LIMIT)
> > > +		return -EAGAIN;
> > 			^
> > 		ret = -EAGAIN;
> > 		goto out;
> >
> > out:
> > > +
> > > +	pm_runtime_put(tmu->dev);
> > > +
> > > +	return 0;
> >
> > 	return ret;
> > > +}
> > > +
> > > +static struct thermal_zone_device_ops tmu_tz_ops = {
> > > +	.get_temp = imx91_tmu_get_temp,
> > > +};
> > > +
> > > +static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
> > > +{
> > > +	struct device *dev = tmu->dev;
> > > +	u32 trim1, trim2;
> > > +	int ret;
> > > +
> > > +	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	if (trim1 == 0 || trim2 == 0)
> > > +		return -EINVAL;
> > > +
> > > +	writel_relaxed(trim1, tmu->base + TRIM1);
> > > +	writel_relaxed(trim2, tmu->base + TRIM2);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int imx91_tmu_probe(struct platform_device *pdev)
> > > +{
> > > +	struct device *dev = &pdev->dev;
> >
> > Since you already have the dev pointer, you can make use of it...
> >
> > > +	struct imx91_tmu *tmu;
> > > +	unsigned long rate;
> > > +	u32 div;
> > > +	int ret;
> > > +
> > > +	tmu = devm_kzalloc(&pdev->dev, sizeof(struct imx91_tmu), GFP_KERNEL);
> > 				^
> > 				here
> > > +	if (!tmu)
> > > +		return -ENOMEM;
> > > +
> > > +	tmu->dev = &pdev->dev;
> >
> > 	and here
> >
> > > +
> > > +	tmu->base = devm_platform_ioremap_resource(pdev, 0);
> > > +	if (IS_ERR(tmu->base))
> > > +		return PTR_ERR(tmu->base);
> > 			^
> > 		dev_err_probe();
> >
> > > +
> > > +	tmu->clk = devm_clk_get_enabled(dev, NULL);
> > > +	if (IS_ERR(tmu->clk))
> > > +		return dev_err_probe(dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
> > > +
> > > +	platform_set_drvdata(pdev, tmu);
> > > +
> > > +	/* disable the monitor during initialization */
> > > +	imx91_tmu_enable(tmu, false);
> > > +	imx91_tmu_start(tmu, false);
> >
> > No need to disable it here since both bits (ENABLE and START) are 0
> > after a reset.
> 
> Maybe uboot enable it. We can't depend on reset value without really set
> hardware reset bit.

So the module can't be rested e.g. by disabling module power? Having a
dedicated reset mechanism would be much simpler instead of writing each
reg-field to the default value.

> > > +	ret = imx91_init_from_nvmem_cells(tmu);
> > > +	if (ret) {
> > > +		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
> > > +		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
> > 			^
> > Can you please anwer if _relaxed API is sufficient? I don't know why you
> > making use of the _relaxed API here anyway. We have only a few MMIO
> > accesses here, so why can't we use the writel() instead? This applies to
> > the whole driver.
> 
> There are not big difference writel_relaxed() or writel() for this driver.
> Just original owner pick one.

NACK, the difference is that _relaxed() APIs don't guarantee the order
the register access is done.

> > > +	}
> > > +
> > > +	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
> > > +	rate = clk_get_rate(tmu->clk);
> > > +	div = (rate / 4000000) - 1;
> > > +	if (div > FIELD_GET(DIV_MASK, DIV_MASK))
> > 			^
> > This misuse the FIELD_GET() API. Instead please add a define e.g. DIV_MAX.
> 
> I don't think so, It avoid define another macro DIV_MAX, which may miss
> defined, the related marco should come from one source.
> 
> For example:
> 
> DIV_MASK is GENMASK(23, 16),  DIV_MAX is 256. But if hardware upgrade,
> DIV_MASK to GENMASK(24, 16), DIV_MAX is quite easy to forget update it and
> hard to find such mis-match when div value < 256.

We not talking about "possible" other HW. For now it's just this one and
using FIELD_GET() this way is seems odd, at least to me.

> > > +		return -EINVAL;
> > 			^
> > 		dev_err_probe()
> > > +
> > > +	/* Set divider value and enable divider */
> > > +	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
> > > +
> > > +	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
> > > +	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
> > 		^
> > You dont need to repeat the default value, so this line can be dropped.
> >
> > > +
> > > +	/*
> > > +	 * Set resolution mode
> > > +	 * 00b - Conversion time = 0.59325 ms
> > > +	 * 01b - Conversion time = 1.10525 ms
> > > +	 * 10b - Conversion time = 2.12925 ms
> > > +	 * 11b - Conversion time = 4.17725 ms
> > > +	 */
> > > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
> > > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);
> >
> > Same here, you repeat the module default after reset, so please drop it.
> >
> > > +	writel_relaxed(CTRL1_MEAS_MODE_MASK, tmu->base + CTRL1_CLR);
> > > +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, CTRL1_MEAS_MODE_SINGLE),
> > > +		       tmu->base + CTRL1_SET);
> > > +
> > > +	clk_disable_unprepare(tmu->clk);
> >
> > Drop this, and
> >
> > > +	pm_runtime_set_suspended(dev);
> >
> > replace this with: pm_runtime_set_active();
> 
> No big difference, if set_active, we need add Enable TMU here. I can
> change to set_active.

You don't need to manually disable the clock, it would be done by the
runtime-pm.

Regards,
  Marco


> Frank
> 
> >
> > > +	pm_runtime_enable(dev);
> > 		^
> > devm_pm_runtime_enable()
> >
> > > +	tmu->tzd = devm_thermal_of_zone_register(dev, 0, tmu, &tmu_tz_ops);
> > > +	if (IS_ERR(tmu->tzd))
> > > +		return dev_err_probe(dev, PTR_ERR(tmu->tzd),
> > > +				     "failed to register thermal zone sensor\n");
> >
> >
> > pm_runtime_put()
> >
> >
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static void imx91_tmu_remove(struct platform_device *pdev)
> > > +{
> > > +	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
> > > +
> > > +	/* disable tmu */
> > > +	imx91_tmu_start(tmu, false);
> >
> > No need to clear the START bit since we are running in
> > single-shot-measurements now.
> >
> > > +	imx91_tmu_enable(tmu, false);
> > > +}
> > > +
> > > +static int imx91_tmu_runtime_suspend(struct device *dev)
> > > +{
> > > +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> > > +
> > > +	/* disable tmu */
> > > +	imx91_tmu_start(tmu, false);
> >
> > Can be dropped.
> >
> > > +	imx91_tmu_enable(tmu, false);
> > > +
> > > +	clk_disable_unprepare(tmu->clk);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int imx91_tmu_runtime_resume(struct device *dev)
> > > +{
> > > +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> > > +	int ret;
> > > +
> > > +	ret = clk_prepare_enable(tmu->clk);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	imx91_tmu_enable(tmu, true);
> > > +	imx91_tmu_start(tmu, true);
> >
> > Drop imx91_tmu_start() from the resume since this isn't related to the
> > runtime-pm. Instead the function needs to be called within
> > imx91_tmu_get_temp().
> >
> > > +	return 0;
> > > +}
> > > +
> > > +static const struct dev_pm_ops imx91_tmu_pm_ops = {
> > > +	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
> > > +	RUNTIME_PM_OPS(imx91_tmu_runtime_suspend, imx91_tmu_runtime_resume, NULL)
> > > +};
> >
> > DEFINE_RUNTIME_DEV_PM_OPS()
> >
> > > +
> > > +static const struct of_device_id imx91_tmu_table[] = {
> > > +	{ .compatible = "fsl,imx91-tmu", },
> > > +	{ },
> > > +};
> > > +MODULE_DEVICE_TABLE(of, imx91_tmu_table);
> > > +
> > > +static struct platform_driver imx91_tmu = {
> > > +	.driver = {
> > > +		.name	= "i.MX91_thermal",
> > 				^
> > Please don't use such names, instead use imx91_thermal.
> >
> > Regards,
> >   Marco
> >
> > > +		.pm	= pm_ptr(&imx91_tmu_pm_ops),
> > > +		.of_match_table = imx91_tmu_table,
> > > +	},
> > > +	.probe = imx91_tmu_probe,
> > > +	.remove = imx91_tmu_remove,
> > > +};
> > > +module_platform_driver(imx91_tmu);
> > > +
> > > +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> > > +MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
> > > +MODULE_LICENSE("GPL");
> > >
> > > --
> > > 2.34.1
> > >
> > >
> 


From robin.murphy at arm.com  Wed Dec 11 11:04:58 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Dec 2024 19:04:58 +0000
Subject: [PATCH] perf/arm-cmn: Permit more exhaustive groups
Message-ID: <bdfd1e58dac449e407c5cacfd6bf8577dc0a5899.1733943898.git.robin.murphy@arm.com>

The group validation logic still somewhat assumes the original CMN-600
case of events counting globally, such that if one tries to group 9
events where the first 8 target a single DTC domain, the 9th will be
rejected because *a* DTC domain is full, even though it might only
target other non-overlapping domains and thus still be schedulable.
Improve matters by only counting the DTCs that the new event actually
needs (as arm_cmn_val_add_event() was already clever enough to do).

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/perf/arm-cmn.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index edefb51ac90a..b49e353e10ab 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -1779,8 +1779,8 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event)
 		goto done;
 	}
 
-	for (i = 0; i < CMN_MAX_DTCS; i++)
-		if (val->dtc_count[i] == CMN_DT_NUM_COUNTERS)
+	for_each_hw_dtc_idx(hw, dtc, idx)
+		if (val->dtc_count[dtc] == CMN_DT_NUM_COUNTERS)
 			goto done;
 
 	for_each_hw_dn(hw, dn, i) {
-- 
2.39.2.101.g768bb238c484.dirty



From cristian.marussi at arm.com  Wed Dec 11 10:28:43 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 11 Dec 2024 18:28:43 +0000
Subject: [PATCH] firmware: arm_scmi: Delete the meaningless scmi_bus_id.
In-Reply-To: <20241211134505.2218386-1-guomin_chen@sina.com_quarantine>
References: <20241211134505.2218386-1-guomin_chen@sina.com_quarantine>
Message-ID: <Z1nZPmB7nW7HUdYL@pluto>

On Wed, Dec 11, 2024 at 09:45:05PM +0800, guomin_chen at sina.com wrote:
> From: guomin chen <guomin_chen at sina.com>
> 
> Currently, scmi_bus_id is only used to set scmi_dev.id,
> which in turn sets the SCMI device name. After removing
> scmi_bus_id, it is clearer and more meaningful to directly
> use the input parameters name and protocol to set the SCMI
> device name.

Hi,

even though using progressive IDs in devices is less readable, I agree,
we need ID in the name to keep the device unique.

It is true that we can have only one protocol/name unique pair amongst
the *requested* devices BUT it is also true that the SCMI stack as it
stands can be instantiated multiple times if you define multiple DT SCMI
top-nodes: this is already used in the wild to sort of represent
multiple virtual/physical SCMI Server backend (all anyway identified by
ID-0 as from the spec...)

So if you have defind in the DT 2 SCMI instance with both a protocol at 15/HWMON,
as an example, the arm_scmi/driver.c will probe twice and it will try to
create 2 instances of 'requested' devices for 15/hwmon and both of these
will be attached to the same *unique* SCMI bus...so we need the uniqe ID
to differentiate them....same for the transport devices.

Sorry but NACK for me: regarding the readability, I could agree, but you
can anyway easily understand which device is which by looking at the
drivers/ links generated in the scmi_protocol bus directory.

Thanks,
Cristian


From james.quinlan at broadcom.com  Wed Dec 11 11:39:42 2024
From: james.quinlan at broadcom.com (James Quinlan)
Date: Wed, 11 Dec 2024 14:39:42 -0500
Subject: [PATCH v4 08/10] PCI: brcmstb: Adjust PHY PLL setup to use a
 54MHz input refclk
In-Reply-To: <f9f49030-0518-4e30-91a7-3c088c31180b@suse.de>
References: <20241025124515.14066-1-svarbanov@suse.de>
 <20241025124515.14066-9-svarbanov@suse.de>
 <4bbdf9ed-f429-411b-8f5f-e51857f0f9d0@broadcom.com>
 <f9f49030-0518-4e30-91a7-3c088c31180b@suse.de>
Message-ID: <474e5e38-37a4-439b-b25a-fe60df03f25b@broadcom.com>

On 12/10/24 08:42, Stanimir Varbanov wrote:
> Hi Jim
>
> On 12/10/24 12:52 AM, James Quinlan wrote:
>> On 10/25/24 08:45, Stanimir Varbanov wrote:
>>> The default input reference clock for the PHY PLL is 100Mhz, except for
>>> some devices where it is 54Mhz like bcm2712C1 and bcm2712D0.
>>>
>>> To implement this adjustments introduce a new .post_setup op in
>>> pcie_cfg_data and call it at the end of brcm_pcie_setup function.
>>>
>>> The bcm2712 .post_setup callback implements the required MDIO writes that
>>> switch the PLL refclk and also change PHY PM clock period.
>>>
>>> Without this RPi5 PCIex1 is unable to enumerate endpoint devices on
>>> the expansion connector.
>>>
>>> Signed-off-by: Stanimir Varbanov <svarbanov at suse.de>
>>> ---
>>> v3 -> v4:
>>>  ? - Improved patch description (Florian)
>>>
>>>  ? drivers/pci/controller/pcie-brcmstb.c | 42 +++++++++++++++++++++++++++
>>>  ? 1 file changed, 42 insertions(+)
>>>
>>> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/
>>> controller/pcie-brcmstb.c
>>> index d970a76aa9ef..2571dcc14560 100644
>>> --- a/drivers/pci/controller/pcie-brcmstb.c
>>> +++ b/drivers/pci/controller/pcie-brcmstb.c
>>> @@ -55,6 +55,10 @@
>>>  ? #define PCIE_RC_DL_MDIO_WR_DATA??????????????? 0x1104
>>>  ? #define PCIE_RC_DL_MDIO_RD_DATA??????????????? 0x1108
>>>  ? +#define PCIE_RC_PL_PHY_CTL_15??????????????? 0x184c
>>> +#define? PCIE_RC_PL_PHY_CTL_15_DIS_PLL_PD_MASK??????? 0x400000
>>> +#define? PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK??? 0xff
>>> +
>>>  ? #define PCIE_MISC_MISC_CTRL??????????????? 0x4008
>>>  ? #define? PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE_MASK??? 0x80
>>>  ? #define? PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE_MASK??? 0x400
>>> @@ -251,6 +255,7 @@ struct pcie_cfg_data {
>>>  ????? u8 num_inbound_wins;
>>>  ????? int (*perst_set)(struct brcm_pcie *pcie, u32 val);
>>>  ????? int (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
>>> +??? int (*post_setup)(struct brcm_pcie *pcie);
>>>  ? };
>>>  ? ? struct subdev_regulators {
>>> @@ -826,6 +831,36 @@ static int brcm_pcie_perst_set_generic(struct
>>> brcm_pcie *pcie, u32 val)
>>>  ????? return 0;
>>>  ? }
>>>  ? +static int brcm_pcie_post_setup_bcm2712(struct brcm_pcie *pcie)
>>> +{
>>> +??? const u16 data[] = { 0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030,
>>> 0x5030, 0x0007 };
>>> +??? const u8 regs[] = { 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e };
>>> +??? int ret, i;
>>> +??? u32 tmp;
>>> +
>>> +??? /* Allow a 54MHz (xosc) refclk source */
>>> +??? ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0,
>>> SET_ADDR_OFFSET, 0x1600);
>>> +??? if (ret < 0)
>>> +??????? return ret;
>>> +
>>> +??? for (i = 0; i < ARRAY_SIZE(regs); i++) {
>>> +??????? ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, regs[i],
>>> data[i]);
>>> +??????? if (ret < 0)
>>> +??????????? return ret;
>>> +??? }
>>> +
>>> +??? usleep_range(100, 200);
>>> +
>>> +??? /* Fix for L1SS errata */
>>> +??? tmp = readl(pcie->base + PCIE_RC_PL_PHY_CTL_15);
>>> +??? tmp &= ~PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK;
>>> +??? /* PM clock period is 18.52ns (round down) */
>>> +??? tmp |= 0x12;
>>> +??? writel(tmp, pcie->base + PCIE_RC_PL_PHY_CTL_15);
>> Hi Stan,
>>
>> Can you please say more about where this errata came from?? I asked the
>> 7712 PCIe HW folks and they said that there best guess was that it was a
>> old workaround for a particular Broadcom Wifi endpoint.? Do you know its
>> origin?
> Unfortunately, I don't know the details. See the comments on previous
> series version [1]. My observation shows that MDIO writes are
> implemented in RPi platform firmware only for pcie2 (where RP1 south
> bridge is connected) but not for pcie1 expansion connector.

Well, I think my concern is more about the comment "Fix for L1SS errata" 
rather than the code.? If this is a bonafide errata it should have an 
identifier and some documentation somewhere. Declaring it to be an 
unknown errata provides little info.

Code-wise, you could use u32p_replace_bits(..., PM_CLK_PERIOD_MASK) to 
do the field value insertion.

All the above being said, I have no objection since this code is 
specific to the RPi platform.

Jim Quinlan? Broadcom STB/CM

>
> ~Stan
>
> [1] https://www.spinics.net/lists/linux-pci/msg160842.html
>



From james.quinlan at broadcom.com  Wed Dec 11 12:01:40 2024
From: james.quinlan at broadcom.com (James Quinlan)
Date: Wed, 11 Dec 2024 15:01:40 -0500
Subject: [PATCH v4 06/10] PCI: brcmstb: Enable external MSI-X if available
In-Reply-To: <20241025124515.14066-7-svarbanov@suse.de>
References: <20241025124515.14066-1-svarbanov@suse.de>
 <20241025124515.14066-7-svarbanov@suse.de>
Message-ID: <f0a734d9-6bf6-4d28-b30b-99b6be9f62dc@broadcom.com>

On 10/25/24 08:45, Stanimir Varbanov wrote:
> On RPi5 there is an external MIP MSI-X interrupt controller
> which can handle up to 64 interrupts.
>
> Signed-off-by: Stanimir Varbanov <svarbanov at suse.de>
> ---
> v3 -> v4:
>   - no changes.
>
>   drivers/pci/controller/pcie-brcmstb.c | 63 +++++++++++++++++++++++++--
>   1 file changed, 59 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
> index c01462b07eea..af01a7915c94 100644
> --- a/drivers/pci/controller/pcie-brcmstb.c
> +++ b/drivers/pci/controller/pcie-brcmstb.c
> @@ -1318,6 +1318,52 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
>   	return 0;
>   }
>   
> +static int brcm_pcie_enable_external_msix(struct brcm_pcie *pcie,
> +					  struct device_node *msi_np)
> +{
> +	struct inbound_win inbound_wins[PCIE_BRCM_MAX_INBOUND_WINS];
> +	u64 msi_pci_addr, msi_phys_addr;
> +	struct resource r;
> +	int mip_bar, ret;
> +	u32 val, reg;
> +
> +	ret = of_property_read_reg(msi_np, 1, &msi_pci_addr, NULL);
> +	if (ret)
> +		return ret;
> +
> +	ret = of_address_to_resource(msi_np, 0, &r);
> +	if (ret)
> +		return ret;
> +
> +	msi_phys_addr = r.start;
> +
> +	/* Find free inbound window for MIP access */
> +	mip_bar = brcm_pcie_get_inbound_wins(pcie, inbound_wins);
> +	if (mip_bar < 0)
> +		return mip_bar;
> +
> +	mip_bar += 1;
> +	reg = brcm_bar_reg_offset(mip_bar);
> +
> +	val = lower_32_bits(msi_pci_addr);
> +	val |= brcm_pcie_encode_ibar_size(SZ_4K);
> +	writel(val, pcie->base + reg);
> +
> +	val = upper_32_bits(msi_pci_addr);
> +	writel(val, pcie->base + reg + 4);
> +
> +	reg = brcm_ubus_reg_offset(mip_bar);
> +
> +	val = lower_32_bits(msi_phys_addr);
> +	val |= PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_ACCESS_EN_MASK;
> +	writel(val, pcie->base + reg);
> +
> +	val = upper_32_bits(msi_phys_addr);
> +	writel(val, pcie->base + reg + 4);

Hi Stan,

It looks like all this is doing is setting up an identity-mapped inbound 
window, is that correct?? If so, couldn't you get the same effect by 
adding an identity-mapped dma-range in the PCIe DT node?

Jim Quinlan? Broadcom STB/CM

> +
> +	return 0;
> +}
> +
>   static const char * const supplies[] = {
>   	"vpcie3v3",
>   	"vpcie3v3aux",
> @@ -1879,11 +1925,20 @@ static int brcm_pcie_probe(struct platform_device *pdev)
>   		goto fail;
>   	}
>   
> -	msi_np = of_parse_phandle(pcie->np, "msi-parent", 0);
> -	if (pci_msi_enabled() && msi_np == pcie->np) {
> -		ret = brcm_pcie_enable_msi(pcie);
> +	if (pci_msi_enabled()) {
> +		msi_np = of_parse_phandle(pcie->np, "msi-parent", 0);
> +		const char *str;
> +
> +		if (msi_np == pcie->np) {
> +			str = "internal MSI";
> +			ret = brcm_pcie_enable_msi(pcie);
> +		} else {
> +			str = "external MSI-X";
> +			ret = brcm_pcie_enable_external_msix(pcie, msi_np);
> +		}
> +
>   		if (ret) {
> -			dev_err(pcie->dev, "probe of internal MSI failed");
> +			dev_err(pcie->dev, "enable of %s failed\n", str);
>   			goto fail;
>   		}
>   	}




From helgaas at kernel.org  Wed Dec 11 12:24:09 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 11 Dec 2024 14:24:09 -0600
Subject: [PATCH] PCI: j721e: In j721e_pcie_suspend_noirq() check
 reset_gpio before to use it
In-Reply-To: <20241211091421.4empou7mbm35ynxq@thinkpad>
Message-ID: <20241211202409.GA3305505@bhelgaas>

[+cc GPIO folks in case they think it's worthwhile to document that
it's safe to pass NULL pointers to gpiod_*() interfaces]

On Wed, Dec 11, 2024 at 02:44:21PM +0530, Manivannan Sadhasivam wrote:
> On Wed, Dec 11, 2024 at 09:59:30AM +0100, Thomas Richard wrote:
> > On 12/10/24 16:42, Bjorn Helgaas wrote:
> > > On Mon, Dec 09, 2024 at 12:23:21PM +0100, Thomas Richard wrote:
> > >> The reset_gpio is optional, so in j721e_pcie_suspend_noirq()
> > >> check if it is not NULL before to use it.

> > >> +++ b/drivers/pci/controller/cadence/pci-j721e.c
> > >> @@ -644,7 +644,9 @@ 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);
> > >> +               if (pcie->reset_gpio)
> > >> +                       gpiod_set_value_cansleep(pcie->reset_gpio, 0);
> > >> +
> > >>                 clk_disable_unprepare(pcie->refclk);
> > >>         }

> > > It looks like gpiod_set_value_cansleep(desc) *should* be a no-op if
> > > desc is NULL, based on this comment [1]:
> > > 
> > >  * This descriptor validation needs to be inserted verbatim into each
> > >  * function taking a descriptor, so we need to use a preprocessor
> > >  * macro to avoid endless duplication. If the desc is NULL it is an
> > >  * optional GPIO and calls should just bail out.
> > > 
> > > and the fact that the VALIDATE_DESC_VOID() macro looks like it would
> > > return early in that case.
> > > 
> > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpio/gpiolib.c?id=v6.12#n2316

> Yes. Almost all of the GPIO APIs accepting desc (except few) use
> VALIDATE_DESC() to check for NULL descriptor. So explicit check is
> not needed.

I think it would be nice if the kernel-doc for these functions
mentioned this somewhere.  It's kind of a pain for every user to have
to deduce this.

Bjorn


From Frank.li at nxp.com  Wed Dec 11 12:39:35 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:39:35 -0500
Subject: [PATCH v2 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241211185705.7b5uw26loobibzln@pengutronix.de>
References: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
 <20241210-imx91tmu-v2-2-5032aad4d88e@nxp.com>
 <20241211154622.f2jwwrqansk6il3o@pengutronix.de>
 <Z1m+O1UV4HD+7Rr2@lizhi-Precision-Tower-5810>
 <20241211185705.7b5uw26loobibzln@pengutronix.de>
Message-ID: <Z1n4h/AxzthB0V9l@lizhi-Precision-Tower-5810>

On Wed, Dec 11, 2024 at 07:57:05PM +0100, Marco Felsch wrote:
> On 24-12-11, Frank Li wrote:
> > On Wed, Dec 11, 2024 at 04:46:22PM +0100, Marco Felsch wrote:
> > > On 24-12-10, Frank Li wrote:
> > > > From: Pengfei Li <pengfei.li_1 at nxp.com>
> > > >
> > > > Introduce support for the i.MX91 thermal monitoring unit, which features a
> > > > single sensor for the CPU. The register layout differs from other chips,
> > > > necessitating the creation of a dedicated file for this.
> > > >
> > > > Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
> > > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > > > ---
> > > > change from v1 to v2
> > > > - use low case for hexvalue
> > > > - combine struct imx91_tmu and tmu_sensor
> > > > - simplify imx91_tmu_start() and imx91_tmu_enable()
> > > > - use s16 for imx91_tmu_get_temp(), which may negative value
> > > > - use reverse christmas tree style
> > > > - use run time pm
> > > > - use oneshot to sample temp
> > > > - register thermal zone after hardware init
> > > > ---
> > > >  drivers/thermal/Kconfig         |  10 ++
> > > >  drivers/thermal/Makefile        |   1 +
> > > >  drivers/thermal/imx91_thermal.c | 265 ++++++++++++++++++++++++++++++++++++++++
> > > >  3 files changed, 276 insertions(+)
> > > >

[...]

> > > > +	platform_set_drvdata(pdev, tmu);
> > > > +
> > > > +	/* disable the monitor during initialization */
> > > > +	imx91_tmu_enable(tmu, false);
> > > > +	imx91_tmu_start(tmu, false);
> > >
> > > No need to disable it here since both bits (ENABLE and START) are 0
> > > after a reset.
> >
> > Maybe uboot enable it. We can't depend on reset value without really set
> > hardware reset bit.
>
> So the module can't be rested e.g. by disabling module power? Having a
> dedicated reset mechanism would be much simpler instead of writing each
> reg-field to the default value.

Not all module can be power off individual. Normally, it should have sw
reset bit in controller. but I have not find it in this module.

>
> > > > +	ret = imx91_init_from_nvmem_cells(tmu);
> > > > +	if (ret) {
> > > > +		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
> > > > +		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
> > > 			^
> > > Can you please anwer if _relaxed API is sufficient? I don't know why you
> > > making use of the _relaxed API here anyway. We have only a few MMIO
> > > accesses here, so why can't we use the writel() instead? This applies to
> > > the whole driver.
> >
> > There are not big difference writel_relaxed() or writel() for this driver.
> > Just original owner pick one.
>
> NACK, the difference is that _relaxed() APIs don't guarantee the order
> the register access is done.

It is totally wrong. *_relexed() API can guarantee the register access
order. Only can't guarantee order with other memory. such as

1 writel_related(A, 0)
2. x = 3
3 writel_related(B, 1)

Hardware/memory model, require B=1 must be after A=0, but not necessary
after x=3, that's means (2) x=3 may happen after 3.

if use writel(), guarantee 1, 2, 3 as order.  Here have not DMA involved.
So not any impact if (2) after (3).

Typically, only below case have to use writel().
2 (update DMA descritpor), 3 start DMA,

Additional, writel() also can't guarantee register access is done!!!!

writel() just means you send a write command to bus. Not guarantee to reach
target module. typical case is

writel(A, 0);
udelay(1);
writel(A, 1);

The interval between A=1 and A=0 may less than 1us if timer have not use
MMIO register. (arm system counter).

In this driver, the only valuable benefit by using writel() instead of
writel_relexed() is "short function name".

>
> > > > +	}
> > > > +
> > > > +	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
> > > > +	rate = clk_get_rate(tmu->clk);
> > > > +	div = (rate / 4000000) - 1;
> > > > +	if (div > FIELD_GET(DIV_MASK, DIV_MASK))
> > > 			^
> > > This misuse the FIELD_GET() API. Instead please add a define e.g. DIV_MAX.
> >
> > I don't think so, It avoid define another macro DIV_MAX, which may miss
> > defined, the related marco should come from one source.
> >
> > For example:
> >
> > DIV_MASK is GENMASK(23, 16),  DIV_MAX is 256. But if hardware upgrade,
> > DIV_MASK to GENMASK(24, 16), DIV_MAX is quite easy to forget update it and
> > hard to find such mis-match when div value < 256.
>
> We not talking about "possible" other HW. For now it's just this one and
> using FIELD_GET() this way is seems odd, at least to me.

If you look implement of FIELD_GET()
(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask));, it will be
reasonable.

Hardware IP may update in future, bitwidth of field may expand.

>
> > > > +		return -EINVAL;
> > > 			^
> > > 		dev_err_probe()
> > > > +
> > > > +	/* Set divider value and enable divider */
> > > > +	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
> > > > +
> > > > +	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
> > > > +	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
> > > 		^
> > > You dont need to repeat the default value, so this line can be dropped.
> > >
> > > > +
> > > > +	/*
> > > > +	 * Set resolution mode
> > > > +	 * 00b - Conversion time = 0.59325 ms
> > > > +	 * 01b - Conversion time = 1.10525 ms
> > > > +	 * 10b - Conversion time = 2.12925 ms
> > > > +	 * 11b - Conversion time = 4.17725 ms
> > > > +	 */
> > > > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
> > > > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);
> > >
> > > Same here, you repeat the module default after reset, so please drop it.
> > >
> > > > +	writel_relaxed(CTRL1_MEAS_MODE_MASK, tmu->base + CTRL1_CLR);
> > > > +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, CTRL1_MEAS_MODE_SINGLE),
> > > > +		       tmu->base + CTRL1_SET);
> > > > +
> > > > +	clk_disable_unprepare(tmu->clk);
> > >
> > > Drop this, and
> > >
> > > > +	pm_runtime_set_suspended(dev);
> > >
> > > replace this with: pm_runtime_set_active();
> >
> > No big difference, if set_active, we need add Enable TMU here. I can
> > change to set_active.
>
> You don't need to manually disable the clock, it would be done by the
> runtime-pm.

Yes, runtime-pm can disable clock, but it need align harware and run time
state before enable runtime pm.

There are two options
1 disable all hardware resources and pm_runtime_set_suspended()
2. enable all hardware resources and set_active()

After algned, use runtime pm API to controller it.

I choose option1, you prefer option 2.

Frank
>
> Regards,
>   Marco
>
>
[...]
> > > > +
> > > > +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> > > > +MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
> > > > +MODULE_LICENSE("GPL");
> > > >
> > > > --
> > > > 2.34.1
> > > >
> > > >
> >


From dsimic at manjaro.org  Wed Dec 11 12:40:52 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 11 Dec 2024 21:40:52 +0100
Subject: [PATCH v2] arm64: dts: rockchip: Delete redundant RK3328 GMAC stability fixes
Message-ID: <fe05ecccc9fe27a678ad3e700ea022429f659724.1733943615.git.dsimic@manjaro.org>

Since the commit 8a469ee35606 ("arm64: dts: rockchip: Add txpbl node for
RK3399/RK3328"), having "snps,txpbl" properties defined as Ethernet stability
fixes in RK3328-based board dts(i) files is redundant, because that commit
added the required fix to the RK3328 SoC dtsi, so let's delete them.

It has been determined that the Ethernet stability fixes no longer require
"snps,rxpbl", "snps,aal" and "snps,force_thresh_dma_mode" properties, [1][2]
out of which the last two also induce performance penalties, so let's delete
these properties from the relevant RK3328-based board dts(i) files.

This commit completes the removal of these redundant "snps,*" DT properties
that was started by a patch from Peter Geis. [3]

[1] https://lore.kernel.org/linux-rockchip/CAMdYzYpj3d7Rq0O0QjV4r6HEf_e07R0QAhPT2NheZdQV3TnQ6g at mail.gmail.com/
[2] https://lore.kernel.org/linux-rockchip/CAMdYzYpnx=pHJ+oqshgfZFp=Mfqp3TcMmEForqJ+s9KuhkgnqA at mail.gmail.com/
[3] https://lore.kernel.org/linux-rockchip/20241210013010.81257-7-pgwipeout at gmail.com/

Cc: Peter Geis <pgwipeout at gmail.com>
Acked-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Dragan Simic <dsimic at manjaro.org>
---

Notes:
    Changes in v2:
      - Added "snps,force_thresh_dma_mode" to the set of redundant properties
        deleted from RK3328 board dts(i) files, as suggested by Peter, [2] and
        updated the patch description to reflect the set extension
      - Collected Acked-by tag from Peter [2]
    
    Link to v1: https://lore.kernel.org/linux-rockchip/e00f08d2351e82d6acd56271a68c7ed05b3362e8.1733901896.git.dsimic at manjaro.org/T/#u

 arch/arm64/boot/dts/rockchip/rk3328-a1.dts                | 1 -
 arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi        | 1 -
 arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi | 1 -
 arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts         | 3 ---
 arch/arm64/boot/dts/rockchip/rk3328-rock64.dts            | 1 -
 5 files changed, 7 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
index 824183e515da..24baaa7f1d8c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
@@ -110,7 +110,6 @@ &gmac2io {
 	phy-supply = <&vcc_io>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&rgmiim1_pins>;
-	snps,aal;
 	snps,pbl = <0x4>;
 	tx_delay = <0x26>;
 	rx_delay = <0x11>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
index f9fab35aed23..d5f129e304e5 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2.dtsi
@@ -142,7 +142,6 @@ &gmac2io {
 	phy-supply = <&vcc_io_33>;
 	pinctrl-0 = <&rgmiim1_pins>;
 	pinctrl-names = "default";
-	snps,aal;
 
 	mdio {
 		compatible = "snps,dwmac-mdio";
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
index 181ec6de0019..9ec93f61433e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dtsi
@@ -113,7 +113,6 @@ &gmac2io {
 	phy-supply = <&vcc_io>;
 	pinctrl-0 = <&rgmiim1_pins>;
 	pinctrl-names = "default";
-	snps,aal;
 
 	mdio {
 		compatible = "snps,dwmac-mdio";
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
index 3e08e2fd0a78..59dead1cc503 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
@@ -153,9 +153,6 @@ &gmac2io {
 	phy-supply = <&vcc_io>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&rgmiim1_pins>;
-	snps,aal;
-	snps,rxpbl = <0x4>;
-	snps,txpbl = <0x4>;
 	tx_delay = <0x26>;
 	rx_delay = <0x11>;
 	status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
index 90fef766f3ae..2ed602d44ec8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
@@ -144,7 +144,6 @@ &gmac2io {
 	phy-mode = "rgmii";
 	pinctrl-names = "default";
 	pinctrl-0 = <&rgmiim1_pins>;
-	snps,force_thresh_dma_mode;
 	snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
 	snps,reset-active-low;
 	snps,reset-delays-us = <0 10000 50000>;


From jonathan at raspberrypi.com  Wed Dec 11 12:54:12 2024
From: jonathan at raspberrypi.com (Jonathan Bell)
Date: Wed, 11 Dec 2024 20:54:12 +0000
Subject: [PATCH v4 08/10] PCI: brcmstb: Adjust PHY PLL setup to use a
 54MHz input refclk
In-Reply-To: <474e5e38-37a4-439b-b25a-fe60df03f25b@broadcom.com>
References: <20241025124515.14066-1-svarbanov@suse.de> <20241025124515.14066-9-svarbanov@suse.de>
 <4bbdf9ed-f429-411b-8f5f-e51857f0f9d0@broadcom.com> <f9f49030-0518-4e30-91a7-3c088c31180b@suse.de>
 <474e5e38-37a4-439b-b25a-fe60df03f25b@broadcom.com>
Message-ID: <CADQZjwci2SVN=AG178kj3yN=17nVixOHEZOjZCs9LSUihbby4Q@mail.gmail.com>

On Wed, 11 Dec 2024 at 19:39, James Quinlan <james.quinlan at broadcom.com> wrote:
>
> On 12/10/24 08:42, Stanimir Varbanov wrote:
> > Hi Jim
> >
> > On 12/10/24 12:52 AM, James Quinlan wrote:
> >> On 10/25/24 08:45, Stanimir Varbanov wrote:
> >>> The default input reference clock for the PHY PLL is 100Mhz, except for
> >>> some devices where it is 54Mhz like bcm2712C1 and bcm2712D0.
> >>>
> >>> To implement this adjustments introduce a new .post_setup op in
> >>> pcie_cfg_data and call it at the end of brcm_pcie_setup function.
> >>>
> >>> The bcm2712 .post_setup callback implements the required MDIO writes that
> >>> switch the PLL refclk and also change PHY PM clock period.
> >>>
> >>> Without this RPi5 PCIex1 is unable to enumerate endpoint devices on
> >>> the expansion connector.
> >>>
> >>> Signed-off-by: Stanimir Varbanov <svarbanov at suse.de>
> >>> ---
> >>> v3 -> v4:
> >>>    - Improved patch description (Florian)
> >>>
> >>>    drivers/pci/controller/pcie-brcmstb.c | 42 +++++++++++++++++++++++++++
> >>>    1 file changed, 42 insertions(+)
> >>>
> >>> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/
> >>> controller/pcie-brcmstb.c
> >>> index d970a76aa9ef..2571dcc14560 100644
> >>> --- a/drivers/pci/controller/pcie-brcmstb.c
> >>> +++ b/drivers/pci/controller/pcie-brcmstb.c
> >>> @@ -55,6 +55,10 @@
> >>>    #define PCIE_RC_DL_MDIO_WR_DATA                0x1104
> >>>    #define PCIE_RC_DL_MDIO_RD_DATA                0x1108
> >>>    +#define PCIE_RC_PL_PHY_CTL_15                0x184c
> >>> +#define  PCIE_RC_PL_PHY_CTL_15_DIS_PLL_PD_MASK        0x400000
> >>> +#define  PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK    0xff
> >>> +
> >>>    #define PCIE_MISC_MISC_CTRL                0x4008
> >>>    #define  PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE_MASK    0x80
> >>>    #define  PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE_MASK    0x400
> >>> @@ -251,6 +255,7 @@ struct pcie_cfg_data {
> >>>        u8 num_inbound_wins;
> >>>        int (*perst_set)(struct brcm_pcie *pcie, u32 val);
> >>>        int (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
> >>> +    int (*post_setup)(struct brcm_pcie *pcie);
> >>>    };
> >>>      struct subdev_regulators {
> >>> @@ -826,6 +831,36 @@ static int brcm_pcie_perst_set_generic(struct
> >>> brcm_pcie *pcie, u32 val)
> >>>        return 0;
> >>>    }
> >>>    +static int brcm_pcie_post_setup_bcm2712(struct brcm_pcie *pcie)
> >>> +{
> >>> +    const u16 data[] = { 0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030,
> >>> 0x5030, 0x0007 };
> >>> +    const u8 regs[] = { 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e };
> >>> +    int ret, i;
> >>> +    u32 tmp;
> >>> +
> >>> +    /* Allow a 54MHz (xosc) refclk source */
> >>> +    ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0,
> >>> SET_ADDR_OFFSET, 0x1600);
> >>> +    if (ret < 0)
> >>> +        return ret;
> >>> +
> >>> +    for (i = 0; i < ARRAY_SIZE(regs); i++) {
> >>> +        ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, regs[i],
> >>> data[i]);
> >>> +        if (ret < 0)
> >>> +            return ret;
> >>> +    }
> >>> +
> >>> +    usleep_range(100, 200);
> >>> +
> >>> +    /* Fix for L1SS errata */
> >>> +    tmp = readl(pcie->base + PCIE_RC_PL_PHY_CTL_15);
> >>> +    tmp &= ~PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK;
> >>> +    /* PM clock period is 18.52ns (round down) */
> >>> +    tmp |= 0x12;
> >>> +    writel(tmp, pcie->base + PCIE_RC_PL_PHY_CTL_15);
> >> Hi Stan,
> >>
> >> Can you please say more about where this errata came from?  I asked the
> >> 7712 PCIe HW folks and they said that there best guess was that it was a
> >> old workaround for a particular Broadcom Wifi endpoint.  Do you know its
> >> origin?
> > Unfortunately, I don't know the details. See the comments on previous
> > series version [1]. My observation shows that MDIO writes are
> > implemented in RPi platform firmware only for pcie2 (where RP1 south
> > bridge is connected) but not for pcie1 expansion connector.
>
> Well, I think my concern is more about the comment "Fix for L1SS errata"
> rather than the code.  If this is a bonafide errata it should have an
> identifier and some documentation somewhere. Declaring it to be an
> unknown errata provides little info.

I'm the originator of this thunk - erratum is perhaps the wrong description.
If the reference clock provided to the RC is 54MHz and not 100MHz, as
is the case on BCM2712, then many of the L1 sub-state timers run
slower which means state transitions are unnecessarily lengthened.

This change, and the MDIO manipulation above, should be applied
regardless of the RC instance and/or connected EP.

> Code-wise, you could use u32p_replace_bits(..., PM_CLK_PERIOD_MASK) to
> do the field value insertion.
>
> All the above being said, I have no objection since this code is
> specific to the RPi platform.
>
> Jim Quinlan  Broadcom STB/CM
>
> >
> > ~Stan
> >
> > [1] https://www.spinics.net/lists/linux-pci/msg160842.html
> >
>

Regards
Jonathan


From Frank.Li at nxp.com  Wed Dec 11 12:57:34 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:34 -0500
Subject: [PATCH v12 6/9] PCI: endpoint: Add pci_epf_align_inbound_addr()
 helper for address alignment
In-Reply-To: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
Message-ID: <20241211-ep-msi-v12-6-33d4532fa520@nxp.com>

Introduce the helper function pci_epf_align_inbound_addr() to adjust
addresses according to PCI BAR alignment requirements, converting addresses
into base and offset values.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change form v9 to v12
- none

change from v8 to v9
- pci_epf_align_inbound_addr(), base and off must be not NULL
- rm pci_epf_align_inbound_addr_lo_hi()

change from v7 to v8
- change name to pci_epf_align_inbound_addr()
- update comment said only need for memory, which not allocated by
pci_epf_alloc_space().

change from v6 to v7
- new patch
---
 drivers/pci/endpoint/pci-epf-core.c | 44 +++++++++++++++++++++++++++++++++++++
 include/linux/pci-epf.h             |  3 +++
 2 files changed, 47 insertions(+)

diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 8fa2797d4169a..d7a80f9c1e661 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -464,6 +464,50 @@ struct pci_epf *pci_epf_create(const char *name)
 }
 EXPORT_SYMBOL_GPL(pci_epf_create);
 
+/**
+ * pci_epf_align_inbound_addr() - Get base address and offset that match BAR's
+ *			  alignment requirement
+ * @epf: the EPF device
+ * @addr: the address of the memory
+ * @bar: the BAR number corresponding to map addr
+ * @base: return base address, which match BAR's alignment requirement.
+ * @off: return offset.
+ *
+ * Helper function to convert input 'addr' to base and offset, which match
+ * BAR's alignment requirement.
+ *
+ * The pci_epf_alloc_space() function already accounts for alignment. This is
+ * primarily intended for use with other memory regions not allocated by
+ * pci_epf_alloc_space(), such as peripheral register spaces or the trigger
+ * address for a platform MSI controller.
+ */
+int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
+			       u64 addr, u64 *base, size_t *off)
+{
+	const struct pci_epc_features *epc_features;
+	u64 align;
+
+	if (!base || !off)
+		return -EINVAL;
+
+	epc_features = pci_epc_get_features(epf->epc, epf->func_no, epf->vfunc_no);
+	if (!epc_features) {
+		dev_err(&epf->dev, "epc_features not implemented\n");
+		return -EOPNOTSUPP;
+	}
+
+	align = epc_features->align;
+	align = align ? align : 128;
+	if (epc_features->bar[bar].type == BAR_FIXED)
+		align = max(epc_features->bar[bar].fixed_size, align);
+
+	*base = round_down(addr, align);
+	*off = addr & (align - 1);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_align_inbound_addr);
+
 static void pci_epf_dev_release(struct device *dev)
 {
 	struct pci_epf *epf = to_pci_epf(dev);
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 5374e6515ffa0..2847d195433bf 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -238,6 +238,9 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
 			  enum pci_epc_interface_type type);
 void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
 			enum pci_epc_interface_type type);
+
+int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
+			       u64 addr, u64 *base, size_t *off);
 int pci_epf_bind(struct pci_epf *epf);
 void pci_epf_unbind(struct pci_epf *epf);
 int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 11 12:57:35 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:35 -0500
Subject: [PATCH v12 7/9] PCI: endpoint: pci-epf-test: Add doorbell test
 support
In-Reply-To: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
Message-ID: <20241211-ep-msi-v12-7-33d4532fa520@nxp.com>

Add three registers: doorbell_bar, doorbell_addr, and doorbell_data. Use
pci_epf_alloc_doorbell() to allocate a doorbell address space.

Enable the Root Complex (RC) side driver to trigger pci-epc-test's doorbell
callback handler by writing doorbell_data to the mapped doorbell_bar's
address space.

Set STATUS_DOORBELL_SUCCESS in the doorbell callback to indicate
completion.

Avoid breaking compatibility between host and endpoint, add new command
COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL. Host side need send
COMMAND_ENABLE_DOORBELL to map one bar's inbound address to MSI space.
the command COMMAND_DISABLE_DOORBELL to recovery original inbound address
mapping.

	 	Host side new driver	Host side old driver

EP: new driver      S				F
EP: old driver      F				F

S: If EP side support MSI, 'pcitest -B' return success.
   If EP side doesn't support MSI, the same to 'F'.

F: 'pcitest -B' return failure, other case as usual.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v12
- none

Change from v8 to v9
- move pci_epf_alloc_doorbell() into pci_epf_{enable/disable}_doorbell().
- remove doorbell_done in commit message.
- rename pci_epf_{enable/disable}_doorbell() to
pci_epf_test_{enable/disable}_doorbell() to align corrent code style.

Change from v7 to v8
- rename to pci_epf_align_inbound_addr_lo_hi()

Change from v6 to v7
- use help function pci_epf_align_addr_lo_hi()

Change from v5 to v6
- rename doorbell_addr to doorbell_offset

Chagne from v4 to v5
- Add doorbell free at unbind function.
- Move msi irq handler to here to more complex user case, such as differece
doorbell can use difference handler function.
- Add Niklas's code to handle fixed bar's case. If need add your signed-off
tag or co-developer tag, please let me know.

change from v3 to v4
- remove revid requirement
- Add command COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL.
- call pci_epc_set_bar() to map inbound address to MSI space only at
COMMAND_ENABLE_DOORBELL.
---
 drivers/pci/endpoint/functions/pci-epf-test.c | 132 ++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index ef6677f34116e..a0a0e86a081cb 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -11,12 +11,14 @@
 #include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/msi.h>
 #include <linux/slab.h>
 #include <linux/pci_ids.h>
 #include <linux/random.h>
 
 #include <linux/pci-epc.h>
 #include <linux/pci-epf.h>
+#include <linux/pci-ep-msi.h>
 #include <linux/pci_regs.h>
 
 #define IRQ_TYPE_INTX			0
@@ -29,6 +31,8 @@
 #define COMMAND_READ			BIT(3)
 #define COMMAND_WRITE			BIT(4)
 #define COMMAND_COPY			BIT(5)
+#define COMMAND_ENABLE_DOORBELL		BIT(6)
+#define COMMAND_DISABLE_DOORBELL	BIT(7)
 
 #define STATUS_READ_SUCCESS		BIT(0)
 #define STATUS_READ_FAIL		BIT(1)
@@ -39,6 +43,11 @@
 #define STATUS_IRQ_RAISED		BIT(6)
 #define STATUS_SRC_ADDR_INVALID		BIT(7)
 #define STATUS_DST_ADDR_INVALID		BIT(8)
+#define STATUS_DOORBELL_SUCCESS		BIT(9)
+#define STATUS_DOORBELL_ENABLE_SUCCESS	BIT(10)
+#define STATUS_DOORBELL_ENABLE_FAIL	BIT(11)
+#define STATUS_DOORBELL_DISABLE_SUCCESS BIT(12)
+#define STATUS_DOORBELL_DISABLE_FAIL	BIT(13)
 
 #define FLAG_USE_DMA			BIT(0)
 
@@ -74,6 +83,9 @@ struct pci_epf_test_reg {
 	u32	irq_type;
 	u32	irq_number;
 	u32	flags;
+	u32	doorbell_bar;
+	u32	doorbell_offset;
+	u32	doorbell_data;
 } __packed;
 
 static struct pci_epf_header test_header = {
@@ -642,6 +654,117 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test,
 	}
 }
 
+static irqreturn_t pci_epf_test_doorbell_handler(int irq, void *data)
+{
+	struct pci_epf_test *epf_test = data;
+	enum pci_barno test_reg_bar = epf_test->test_reg_bar;
+	struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
+
+	reg->status |= STATUS_DOORBELL_SUCCESS;
+	pci_epf_test_raise_irq(epf_test, reg);
+
+	return IRQ_HANDLED;
+}
+
+static void pci_epf_test_doorbell_cleanup(struct pci_epf_test *epf_test)
+{
+	struct pci_epf_test_reg *reg = epf_test->reg[epf_test->test_reg_bar];
+	struct pci_epf *epf = epf_test->epf;
+
+	if (reg->doorbell_bar > 0) {
+		free_irq(epf->db_msg[0].virq, epf_test);
+		reg->doorbell_bar = NO_BAR;
+	}
+
+	if (epf->db_msg)
+		pci_epf_free_doorbell(epf);
+}
+
+static void pci_epf_test_enable_doorbell(struct pci_epf_test *epf_test,
+					 struct pci_epf_test_reg *reg)
+{
+	struct pci_epf *epf = epf_test->epf;
+	struct pci_epf_bar db_bar = {};
+	struct pci_epc *epc = epf->epc;
+	struct msi_msg *msg;
+	enum pci_barno bar;
+	size_t offset;
+	int ret;
+
+	ret = pci_epf_alloc_doorbell(epf, 1);
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		return;
+	}
+
+	msg = &epf->db_msg[0].msg;
+	bar = pci_epc_get_next_free_bar(epf_test->epc_features, epf_test->test_reg_bar + 1);
+	if (bar < BAR_0 || bar == epf_test->test_reg_bar || !epf->db_msg) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		return;
+	}
+
+	ret = request_irq(epf->db_msg[0].virq, pci_epf_test_doorbell_handler, 0,
+			  "pci-test-doorbell", epf_test);
+	if (ret) {
+		dev_err(&epf->dev,
+			"Failed to request irq %d, doorbell feature is not supported\n",
+			epf->db_msg[0].virq);
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+		return;
+	}
+
+	reg->doorbell_data = msg->data;
+	reg->doorbell_bar = bar;
+
+	msg = &epf->db_msg[0].msg;
+	ret = pci_epf_align_inbound_addr(epf, bar, ((u64)msg->address_hi << 32) | msg->address_lo,
+					 &db_bar.phys_addr, &offset);
+
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+		return;
+	}
+
+	reg->doorbell_offset = offset;
+
+	db_bar.barno = bar;
+	db_bar.size = epf->bar[bar].size;
+	db_bar.flags = epf->bar[bar].flags;
+
+	ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &db_bar);
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+	} else {
+		reg->status |= STATUS_DOORBELL_ENABLE_SUCCESS;
+	}
+}
+
+static void pci_epf_test_disable_doorbell(struct pci_epf_test *epf_test,
+					  struct pci_epf_test_reg *reg)
+{
+	enum pci_barno bar = reg->doorbell_bar;
+	struct pci_epf *epf = epf_test->epf;
+	struct pci_epc *epc = epf->epc;
+	int ret;
+
+	if (bar < BAR_0 || bar == epf_test->test_reg_bar || !epf->db_msg) {
+		reg->status |= STATUS_DOORBELL_DISABLE_FAIL;
+		return;
+	}
+
+	ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &epf->bar[bar]);
+	if (ret)
+		reg->status |= STATUS_DOORBELL_DISABLE_FAIL;
+	else
+		reg->status |= STATUS_DOORBELL_DISABLE_SUCCESS;
+
+	pci_epf_test_doorbell_cleanup(epf_test);
+}
+
 static void pci_epf_test_cmd_handler(struct work_struct *work)
 {
 	u32 command;
@@ -688,6 +811,14 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 		pci_epf_test_copy(epf_test, reg);
 		pci_epf_test_raise_irq(epf_test, reg);
 		break;
+	case COMMAND_ENABLE_DOORBELL:
+		pci_epf_test_enable_doorbell(epf_test, reg);
+		pci_epf_test_raise_irq(epf_test, reg);
+		break;
+	case COMMAND_DISABLE_DOORBELL:
+		pci_epf_test_disable_doorbell(epf_test, reg);
+		pci_epf_test_raise_irq(epf_test, reg);
+		break;
 	default:
 		dev_err(dev, "Invalid command 0x%x\n", command);
 		break;
@@ -934,6 +1065,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
 		pci_epf_test_clean_dma_chan(epf_test);
 		pci_epf_test_clear_bar(epf);
 	}
+	pci_epf_test_doorbell_cleanup(epf_test);
 	pci_epf_test_free_space(epf);
 }
 

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 11 12:57:36 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:36 -0500
Subject: [PATCH v12 8/9] misc: pci_endpoint_test: Add doorbell test case
In-Reply-To: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
Message-ID: <20241211-ep-msi-v12-8-33d4532fa520@nxp.com>

Add three registers: PCIE_ENDPOINT_TEST_DB_BAR, PCIE_ENDPOINT_TEST_DB_ADDR,
and PCIE_ENDPOINT_TEST_DB_DATA.

Trigger the doorbell by writing data from PCI_ENDPOINT_TEST_DB_DATA to the
address provided by PCI_ENDPOINT_TEST_DB_OFFSET and wait for endpoint
feedback.

Add two command to COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL
to enable EP side's doorbell support and avoid compatible problem, which
host side driver miss-match with endpoint side function driver. See below
table:

		Host side new driver	Host side old driver
EP: new driver		S			F
EP: old driver		F			F

S: If EP side support MSI, 'pcitest -B' return success.
   If EP side doesn't support MSI, the same to 'F'.

F: 'pcitest -B' return failure, other case as usual.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v12
- none

Change from v8 to v9
- change PCITEST_DOORBELL to 0xa

Change form v6 to v8
- none

Change from v5 to v6
- %s/PCI_ENDPOINT_TEST_DB_ADDR/PCI_ENDPOINT_TEST_DB_OFFSET/g

Change from v4 to v5
- remove unused varible
- add irq_type at pci_endpoint_test_doorbell();

change from v3 to v4
- Add COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL.
- Remove new DID requirement.
---
 drivers/misc/pci_endpoint_test.c | 80 ++++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/pcitest.h     |  1 +
 2 files changed, 81 insertions(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 3aaaf47fa4ee2..b3f36b6ba8ba2 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -42,6 +42,8 @@
 #define COMMAND_READ				BIT(3)
 #define COMMAND_WRITE				BIT(4)
 #define COMMAND_COPY				BIT(5)
+#define COMMAND_ENABLE_DOORBELL			BIT(6)
+#define COMMAND_DISABLE_DOORBELL		BIT(7)
 
 #define PCI_ENDPOINT_TEST_STATUS		0x8
 #define STATUS_READ_SUCCESS			BIT(0)
@@ -53,6 +55,11 @@
 #define STATUS_IRQ_RAISED			BIT(6)
 #define STATUS_SRC_ADDR_INVALID			BIT(7)
 #define STATUS_DST_ADDR_INVALID			BIT(8)
+#define STATUS_DOORBELL_SUCCESS			BIT(9)
+#define STATUS_DOORBELL_ENABLE_SUCCESS		BIT(10)
+#define STATUS_DOORBELL_ENABLE_FAIL		BIT(11)
+#define STATUS_DOORBELL_DISABLE_SUCCESS		BIT(12)
+#define STATUS_DOORBELL_DISABLE_FAIL		BIT(13)
 
 #define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR	0x0c
 #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR	0x10
@@ -67,6 +74,10 @@
 #define PCI_ENDPOINT_TEST_IRQ_NUMBER		0x28
 
 #define PCI_ENDPOINT_TEST_FLAGS			0x2c
+#define PCI_ENDPOINT_TEST_DB_BAR		0x30
+#define PCI_ENDPOINT_TEST_DB_OFFSET		0x34
+#define PCI_ENDPOINT_TEST_DB_DATA		0x38
+
 #define FLAG_USE_DMA				BIT(0)
 
 #define PCI_DEVICE_ID_TI_AM654			0xb00c
@@ -108,6 +119,7 @@ enum pci_barno {
 	BAR_3,
 	BAR_4,
 	BAR_5,
+	NO_BAR = -1,
 };
 
 struct pci_endpoint_test {
@@ -746,6 +758,71 @@ static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
 	return false;
 }
 
+static bool pci_endpoint_test_doorbell(struct pci_endpoint_test *test)
+{
+	struct pci_dev *pdev = test->pdev;
+	struct device *dev = &pdev->dev;
+	int irq_type = test->irq_type;
+	enum pci_barno bar;
+	u32 data, status;
+	u32 addr;
+
+	if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
+		dev_err(dev, "Invalid IRQ type option\n");
+		return false;
+	}
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
+				 COMMAND_ENABLE_DOORBELL);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+	if (status & STATUS_DOORBELL_ENABLE_FAIL) {
+		dev_err(dev, "Failed to enable doorbell\n");
+		return false;
+	}
+
+	data = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_DATA);
+	addr = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_OFFSET);
+	bar = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_BAR);
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS, 0);
+
+	bar = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_BAR);
+
+	writel(data, test->bar[bar] + addr);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+
+	if (!(status & STATUS_DOORBELL_SUCCESS))
+		dev_err(dev, "Endpoint have not received Doorbell\n");
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
+				 COMMAND_DISABLE_DOORBELL);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status |= pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+
+	if (status & STATUS_DOORBELL_DISABLE_FAIL) {
+		dev_err(dev, "Failed to disable doorbell\n");
+		return false;
+	}
+
+	if (!(status & STATUS_DOORBELL_SUCCESS))
+		return false;
+
+	return true;
+}
+
 static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 				    unsigned long arg)
 {
@@ -793,6 +870,9 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 	case PCITEST_CLEAR_IRQ:
 		ret = pci_endpoint_test_clear_irq(test);
 		break;
+	case PCITEST_DOORBELL:
+		ret = pci_endpoint_test_doorbell(test);
+		break;
 	}
 
 ret:
diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h
index 94b46b043b536..b82e7f2ed937d 100644
--- a/include/uapi/linux/pcitest.h
+++ b/include/uapi/linux/pcitest.h
@@ -20,6 +20,7 @@
 #define PCITEST_MSIX		_IOW('P', 0x7, int)
 #define PCITEST_SET_IRQTYPE	_IOW('P', 0x8, int)
 #define PCITEST_GET_IRQTYPE	_IO('P', 0x9)
+#define PCITEST_DOORBELL	_IO('P', 0xa)
 #define PCITEST_CLEAR_IRQ	_IO('P', 0x10)
 
 #define PCITEST_FLAGS_USE_DMA	0x00000001

-- 
2.34.1



From robh at kernel.org  Wed Dec 11 12:57:11 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 14:57:11 -0600
Subject: [PATCH 0/3] mfd: syscon: Cleanup, fix race condition and remove
 platform driver
Message-ID: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>

Questions from Krzysztof and a syscon related binding review got me 
looking at the syscon "driver". This series is the result.

This short series drops the stale platform driver part of syscon 
support, fixes a race condition in device_node_get_regmap()
which is used by all the lookup functions, and allows for registering 
nodes without "syscon" compatibles.

Compile tested only. Testing on Tensor, the one user of 
of_syscon_register_regmap(), would be helpful.

Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
Rob Herring (Arm) (3):
      mfd: syscon: Fix race in device_node_get_regmap()
      mfd: syscon: Remove the platform driver support
      mfd: syscon: Allow syscon nodes without a "syscon" compatible

 drivers/mfd/syscon.c                 | 92 +++++-------------------------------
 drivers/mfd/vexpress-sysreg.c        |  1 -
 include/linux/platform_data/syscon.h |  9 ----
 3 files changed, 13 insertions(+), 89 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241211-syscon-fixes-9f35ecb9bfbe

Best regards,
-- 
Rob Herring (Arm) <robh at kernel.org>



From robh at kernel.org  Wed Dec 11 12:57:12 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 14:57:12 -0600
Subject: [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap()
In-Reply-To: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
References: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
Message-ID: <20241211-syscon-fixes-v1-1-b5ac8c219e96@kernel.org>

It is possible for multiple, simultaneous callers calling
device_node_get_regmap() with the same node to fail to find an entry in
the syscon_list. There is a period of time while the first caller is
calling of_syscon_register() that subsequent callers also fail to find
an entry in the syscon_list and then call of_syscon_register() a second
time.

Fix this by keeping the lock held until after of_syscon_register()
completes and adds the node to syscon_list. Convert the spinlock to a
mutex as many of the functions called in of_syscon_register() may sleep.

Fixes: bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform devices")
Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
 drivers/mfd/syscon.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 3e1d699ba934..72f20de9652d 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
@@ -27,7 +28,7 @@
 
 static struct platform_driver syscon_driver;
 
-static DEFINE_SPINLOCK(syscon_list_slock);
+static DEFINE_MUTEX(syscon_list_lock);
 static LIST_HEAD(syscon_list);
 
 struct syscon {
@@ -54,6 +55,8 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
 	struct resource res;
 	struct reset_control *reset;
 
+	WARN_ON(!mutex_is_locked(&syscon_list_lock));
+
 	struct syscon *syscon __free(kfree) = kzalloc(sizeof(*syscon), GFP_KERNEL);
 	if (!syscon)
 		return ERR_PTR(-ENOMEM);
@@ -146,9 +149,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
 	syscon->regmap = regmap;
 	syscon->np = np;
 
-	spin_lock(&syscon_list_slock);
 	list_add_tail(&syscon->list, &syscon_list);
-	spin_unlock(&syscon_list_slock);
 
 	return_ptr(syscon);
 
@@ -169,7 +170,7 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
 {
 	struct syscon *entry, *syscon = NULL;
 
-	spin_lock(&syscon_list_slock);
+	mutex_lock(&syscon_list_lock);
 
 	list_for_each_entry(entry, &syscon_list, list)
 		if (entry->np == np) {
@@ -177,11 +178,11 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
 			break;
 		}
 
-	spin_unlock(&syscon_list_slock);
-
 	if (!syscon)
 		syscon = of_syscon_register(np, check_res);
 
+	mutex_unlock(&syscon_list_lock);
+
 	if (IS_ERR(syscon))
 		return ERR_CAST(syscon);
 
@@ -212,7 +213,7 @@ int of_syscon_register_regmap(struct device_node *np, struct regmap *regmap)
 		return -ENOMEM;
 
 	/* check if syscon entry already exists */
-	spin_lock(&syscon_list_slock);
+	mutex_lock(&syscon_list_lock);
 
 	list_for_each_entry(entry, &syscon_list, list)
 		if (entry->np == np) {
@@ -225,12 +226,12 @@ int of_syscon_register_regmap(struct device_node *np, struct regmap *regmap)
 
 	/* register the regmap in syscon list */
 	list_add_tail(&syscon->list, &syscon_list);
-	spin_unlock(&syscon_list_slock);
+	mutex_unlock(&syscon_list_lock);
 
 	return 0;
 
 err_unlock:
-	spin_unlock(&syscon_list_slock);
+	mutex_unlock(&syscon_list_lock);
 	kfree(syscon);
 	return ret;
 }

-- 
2.45.2



From robh at kernel.org  Wed Dec 11 12:57:13 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 14:57:13 -0600
Subject: [PATCH 2/3] mfd: syscon: Remove the platform driver support
In-Reply-To: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
References: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
Message-ID: <20241211-syscon-fixes-v1-2-b5ac8c219e96@kernel.org>

The platform driver is dead code. It is not used by DT platforms since
commit bdb0066df96e ("mfd: syscon: Decouple syscon interface from
platform devices") which said:

    For non-DT based platforms, this patch keeps syscon platform driver
    structure so that syscon can be probed and such non-DT based drivers
    can use syscon_regmap_lookup_by_pdev API and access regmap handles.
    Once all users of "syscon_regmap_lookup_by_pdev" migrated to DT based,
    we can completely remove platform driver of syscon, and keep only helper
    functions to get regmap handles.

The last user of syscon_regmap_lookup_by_pdevname() was removed in 2018.
syscon_regmap_lookup_by_pdevname() was then removed in 2019, but that
commit failed to remove the rest of the platform driver.

Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
 drivers/mfd/syscon.c                 | 66 ------------------------------------
 drivers/mfd/vexpress-sysreg.c        |  1 -
 include/linux/platform_data/syscon.h |  9 -----
 3 files changed, 76 deletions(-)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 72f20de9652d..bfb1f69fcff1 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -12,22 +12,15 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/hwspinlock.h>
-#include <linux/io.h>
-#include <linux/init.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/platform_data/syscon.h>
-#include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
 #include <linux/mfd/syscon.h>
 #include <linux/slab.h>
 
-static struct platform_driver syscon_driver;
-
 static DEFINE_MUTEX(syscon_list_lock);
 static LIST_HEAD(syscon_list);
 
@@ -337,62 +330,3 @@ struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np,
 	return regmap;
 }
 EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle_optional);
-
-static int syscon_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct syscon_platform_data *pdata = dev_get_platdata(dev);
-	struct syscon *syscon;
-	struct regmap_config syscon_config = syscon_regmap_config;
-	struct resource *res;
-	void __iomem *base;
-
-	syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
-	if (!syscon)
-		return -ENOMEM;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENOENT;
-
-	base = devm_ioremap(dev, res->start, resource_size(res));
-	if (!base)
-		return -ENOMEM;
-
-	syscon_config.max_register = resource_size(res) - 4;
-	if (!syscon_config.max_register)
-		syscon_config.max_register_is_0 = true;
-
-	if (pdata)
-		syscon_config.name = pdata->label;
-	syscon->regmap = devm_regmap_init_mmio(dev, base, &syscon_config);
-	if (IS_ERR(syscon->regmap)) {
-		dev_err(dev, "regmap init failed\n");
-		return PTR_ERR(syscon->regmap);
-	}
-
-	platform_set_drvdata(pdev, syscon);
-
-	dev_dbg(dev, "regmap %pR registered\n", res);
-
-	return 0;
-}
-
-static const struct platform_device_id syscon_ids[] = {
-	{ "syscon", },
-	{ }
-};
-
-static struct platform_driver syscon_driver = {
-	.driver = {
-		.name = "syscon",
-	},
-	.probe		= syscon_probe,
-	.id_table	= syscon_ids,
-};
-
-static int __init syscon_init(void)
-{
-	return platform_driver_register(&syscon_driver);
-}
-postcore_initcall(syscon_init);
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
index d34d58ce46db..ef03d6cec9ff 100644
--- a/drivers/mfd/vexpress-sysreg.c
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -10,7 +10,6 @@
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
-#include <linux/platform_data/syscon.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
diff --git a/include/linux/platform_data/syscon.h b/include/linux/platform_data/syscon.h
deleted file mode 100644
index 2c089dd3e2bd..000000000000
--- a/include/linux/platform_data/syscon.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef PLATFORM_DATA_SYSCON_H
-#define PLATFORM_DATA_SYSCON_H
-
-struct syscon_platform_data {
-	const char *label;
-};
-
-#endif

-- 
2.45.2



From robh at kernel.org  Wed Dec 11 12:57:14 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 11 Dec 2024 14:57:14 -0600
Subject: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon"
 compatible
In-Reply-To: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
References: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
Message-ID: <20241211-syscon-fixes-v1-3-b5ac8c219e96@kernel.org>

of_syscon_register_regmap() was added for nodes which need a custom
regmap setup. It's not really correct for those nodes to claim they are
compatible with "syscon" as the default handling likely doesn't work in
those cases. If device_node_get_regmap() happens to be called first,
then of_syscon_register() will be called and an incorrect regmap will be
created (barring some other error). That may lead to unknown results in
the worst case. In the best case, of_syscon_register_regmap() will fail
with -EEXIST. This problem remains unless these cases drop "syscon" (an
ABI issue) or we exclude them using their specific compatible. ATM,
there is only one user: "google,gs101-pmu"

There are also cases of adding "syscon" compatible to existing nodes
after the fact in order to register the syscon. That presents a
potential DT ABI problem. Instead, if there's a kernel change needing a
syscon for a node, then it should be possible to allow the kernel to
register a syscon without a DT change. That's only possible by using
of_syscon_register_regmap() currently, but in the future we may want to
support a match list for cases which don't need a custom regmap.

With this change, the lookup functions will succeed for any node
registered by of_syscon_register_regmap() regardless of whether the node
compatible contains "syscon".

Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
 drivers/mfd/syscon.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index bfb1f69fcff1..e6df2825c14d 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -171,8 +171,10 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
 			break;
 		}
 
-	if (!syscon)
+	if (!syscon && of_device_is_compatible(np, "syscon"))
 		syscon = of_syscon_register(np, check_res);
+	else
+		syscon = ERR_PTR(-EINVAL);
 
 	mutex_unlock(&syscon_list_lock);
 
@@ -238,9 +240,6 @@ EXPORT_SYMBOL_GPL(device_node_to_regmap);
 
 struct regmap *syscon_node_to_regmap(struct device_node *np)
 {
-	if (!of_device_is_compatible(np, "syscon"))
-		return ERR_PTR(-EINVAL);
-
 	return device_node_get_regmap(np, true);
 }
 EXPORT_SYMBOL_GPL(syscon_node_to_regmap);

-- 
2.45.2



From Frank.Li at nxp.com  Wed Dec 11 12:57:28 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:28 -0500
Subject: [PATCH v12 0/9] PCI: EP: Add RC-to-EP doorbell with platform MSI
 controller
Message-ID: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>

??????????????   ?????????????????????????????????????   ??????????????????
?            ?   ?                                   ?   ?                ?
?            ?   ? PCI Endpoint                      ?   ? PCI Host       ?
?            ?   ?                                   ?   ?                ?
?            ????? 1.platform_msi_domain_alloc_irqs()?   ?                ?
?            ?   ?                                   ?   ?                ?
? MSI        ????? 2.write_msi_msg()                 ??????BAR<n>         ?
? Controller ?   ?   update doorbell register address?   ?                ?
?            ?   ?   for BAR                         ?   ?                ?
?            ?   ?                                   ?   ? 3. Write BAR<n>?
?            ?????????????????????????????????????????????                ?
?            ?   ?                                   ?   ?                ?
?            ????? 4.Irq Handle                      ?   ?                ?
?            ?   ?                                   ?   ?                ?
?            ?   ?                                   ?   ?                ?
??????????????   ?????????????????????????????????????   ??????????????????

This patches based on old https://lore.kernel.org/imx/20221124055036.1630573-1-Frank.Li at nxp.com/

Original patch only target to vntb driver. But actually it is common
method.

This patches add new API to pci-epf-core, so any EP driver can use it.

Previous v2 discussion here.
https://lore.kernel.org/imx/20230911220920.1817033-1-Frank.Li at nxp.com/

Changes in v12:
- Change to use IRQ_DOMAIN_MSI_IMMUTABLE and add help function
irq_domain_msi_is_immuatble().
- split PCI: endpoint: pci-ep-msi: Add MSI address/data pair mutable check to 3 patches
- Link to v11: https://lore.kernel.org/r/20241209-ep-msi-v11-0-7434fa8397bd at nxp.com

Changes in v11:
- Change to use MSI_FLAG_MSG_IMMUTABLE
- Link to v10: https://lore.kernel.org/r/20241204-ep-msi-v10-0-87c378dbcd6d at nxp.com

Changes in v10:

Thomas Gleixner:
	There are big change in pci-ep-msi.c. I am sure if go on the
corrent path. The key improvement is remove only 1 function devices's
limitation.

	I use new patch for imutable check, which relative additional
feature compared to base enablement patch.

- Remove patch Add msi_remove_device_irq_domain() in platform_device_msi_free_irqs_all()
- Add new patch irqchip/gic-v3-its: Avoid overwriting msi_prepare callback if provided by msi_domain_info
- Remove only support 1 endpoint function limiation.
- Create one MSI domain for each endpoint function devices.
- Use "msi-map" in pci ep controler node, instead of of msi-parent. first
argument is
	(func_no << 8 | vfunc_no)

- Link to v9: https://lore.kernel.org/r/20241203-ep-msi-v9-0-a60dbc3f15dd at nxp.com

Changes in v9
- Add patch platform-msi: Add msi_remove_device_irq_domain() in platform_device_msi_free_irqs_all()
- Remove patch PCI: endpoint: Add pci_epc_get_fn() API for customizable filtering
- Remove API pci_epf_align_inbound_addr_lo_hi
- Move doorbell_alloc in to doorbell_enable function.
- Link to v8: https://lore.kernel.org/r/20241116-ep-msi-v8-0-6f1f68ffd1bb at nxp.com

Changes in v8:
- update helper function name to pci_epf_align_inbound_addr()
- Link to v7: https://lore.kernel.org/r/20241114-ep-msi-v7-0-d4ac7aafbd2c at nxp.com

Changes in v7:
- Add helper function pci_epf_align_addr();
- Link to v6: https://lore.kernel.org/r/20241112-ep-msi-v6-0-45f9722e3c2a at nxp.com

Changes in v6:
- change doorbell_addr to doorbell_offset
- use round_down()
- add Niklas's test by tag
- rebase to pci/endpoint
- Link to v5: https://lore.kernel.org/r/20241108-ep-msi-v5-0-a14951c0d007 at nxp.com

Changes in v5:
- Move request_irq to epf test function driver for more flexiable user case
- Add fixed size bar handler
- Some minor improvememtn to see each patches's changelog.
- Link to v4: https://lore.kernel.org/r/20241031-ep-msi-v4-0-717da2d99b28 at nxp.com

Changes in v4:
- Remove patch genirq/msi: Add cleanup guard define for msi_lock_descs()/msi_unlock_descs()
- Use new method to avoid compatible problem.
  Add new command DOORBELL_ENABLE and DOORBELL_DISABLE.
  pcitest -B send DOORBELL_ENABLE first, EP test function driver try to
remap one of BAR_N (except test register bar) to ITS MSI MMIO space. Old
driver don't support new command, so failure return, not side effect.
  After test, DOORBELL_DISABLE command send out to recover original map, so
pcitest bar test can pass as normal.
- Other detail change see each patches's change log
- Link to v3: https://lore.kernel.org/r/20241015-ep-msi-v3-0-cedc89a16c1a at nxp.com

Change from v2 to v3
- Fixed manivannan's comments
- Move common part to pci-ep-msi.c and pci-ep-msi.h
- rebase to 6.12-rc1
- use RevID to distingiush old version

mkdir /sys/kernel/config/pci_ep/functions/pci_epf_test/func1
echo 16 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/msi_interrupts
echo 0x080c > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/deviceid
echo 0x1957 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/vendorid
echo 1 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/revid
^^^^^^ to enable platform msi support.
ln -s /sys/kernel/config/pci_ep/functions/pci_epf_test/func1 /sys/kernel/config/pci_ep/controllers/4c380000.pcie-ep

- use new device ID, which identify support doorbell to avoid broken
compatility.

    Enable doorbell support only for PCI_DEVICE_ID_IMX8_DB, while other devices
    keep the same behavior as before.

           EP side             RC with old driver      RC with new driver
    PCI_DEVICE_ID_IMX8_DB          no probe              doorbell enabled
    Other device ID             doorbell disabled*       doorbell disabled*

    * Behavior remains unchanged.

Change from v1 to v2
- Add missed patch for endpont/pci-epf-test.c
- Move alloc and free to epc driver from epf.
- Provide general help function for EPC driver to alloc platform msi irq.
- Fixed manivannan's comments.

To: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
To: Krzysztof Wilczy?ski <kw at linux.com>
To: Kishon Vijay Abraham I <kishon at kernel.org>
To: Bjorn Helgaas <bhelgaas at google.com>
To: Arnd Bergmann <arnd at arndb.de>
To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: linux-kernel at vger.kernel.org
Cc: linux-pci at vger.kernel.org
Cc: imx at lists.linux.dev
Cc: Niklas Cassel <cassel at kernel.org>
Cc: dlemoal at kernel.org
Cc: jdmason at kudzu.us
To: Rafael J. Wysocki <rafael at kernel.org>
To: Thomas Gleixner <tglx at linutronix.de>
To: Anup Patel <apatel at ventanamicro.com>
To: Kishon Vijay Abraham I <kishon at kernel.org>
To: Marc Zyngier <maz at kernel.org>
To: Thomas Gleixner <tglx at linutronix.de>
Cc: linux-arm-kernel at lists.infradead.org

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Frank Li (9):
      irqchip/gic-v3-its: Avoid overwriting msi_prepare callback if provided by msi_domain_info
      PCI: endpoint: Add RC-to-EP doorbell support using platform MSI controller
      irqdomain: Add IRQ_DOMAIN_FLAG_MSI_IMMUTABLE and irq_domain_is_msi_immutable()
      irqchip/gic-v3-its: Set IRQ_DOMAIN_FLAG_MSI_IMMUTABLE for ITS
      PCI: endpoint: pci-ep-msi: Add check for MSI address/data pair immutability
      PCI: endpoint: Add pci_epf_align_inbound_addr() helper for address alignment
      PCI: endpoint: pci-epf-test: Add doorbell test support
      misc: pci_endpoint_test: Add doorbell test case
      tools: PCI: Add 'B' option for test doorbell

 drivers/irqchip/irq-gic-v3-its-msi-parent.c   |   3 +-
 drivers/irqchip/irq-gic-v3-its.c              |   2 +-
 drivers/misc/pci_endpoint_test.c              |  80 ++++++++++++++
 drivers/pci/endpoint/Makefile                 |   2 +-
 drivers/pci/endpoint/functions/pci-epf-test.c | 132 ++++++++++++++++++++++
 drivers/pci/endpoint/pci-ep-msi.c             | 153 ++++++++++++++++++++++++++
 drivers/pci/endpoint/pci-epf-core.c           |  44 ++++++++
 include/linux/irqdomain.h                     |   8 ++
 include/linux/pci-ep-msi.h                    |  15 +++
 include/linux/pci-epf.h                       |  19 ++++
 include/uapi/linux/pcitest.h                  |   1 +
 tools/pci/pcitest.c                           |  16 ++-
 12 files changed, 471 insertions(+), 4 deletions(-)
---
base-commit: 102a25797c66c8f4cf7fafe0b0de95cc7126b3fa
change-id: 20241010-ep-msi-8b4cab33b1be

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Wed Dec 11 12:57:29 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:29 -0500
Subject: [PATCH v12 1/9] irqchip/gic-v3-its: Avoid overwriting msi_prepare
 callback if provided by msi_domain_info
In-Reply-To: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
Message-ID: <20241211-ep-msi-v12-1-33d4532fa520@nxp.com>

  ?????????????????????????????????    ?????????
  ?                               ?    ?       ?
  ? PCI Endpoint Controller (1)   ?????? ITS   ?
  ?                               ?    ?       ?
  ?????????????????????????????????    ?????????
      ?        ?
      ?        ?
  ????????  ????????
  ?      ?  ?      ?
  ?Func1 ?  ?Func2 ?
  ? (2)  ?  ?      ?
  ????????  ????????
     ?         ?
     ?         ?
     ?????????????????????????? PCIe Bus

(1) is platform device, which is generally descripted by Device Tree(DT).
(2) Func1 and Func2 is created by configfs

The current platform MSI API supports only a single device. For instance,
a platform device (e.g., PCI Endpoint Controller) calls
platform_device_msi_init_and_alloc_irqs() to allocate MSI IRQs.

Child devices (e.g., function devices created by configfs) require
individual MSI domains, with the same MSI parent domain as the parent
device. These individual domains need specialized msi_prepare callbacks to
set  msi_alloc_info_t. However, the current ITS implementation overwrites
the msi_prepare callback with its_pmsi_prepare().

Modify the implementation to assign its_pmsi_prepare() only if
msi_domain_info::msi_prepare is NULL, allowing customized callbacks where
needed.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v11 to v12
- none

Change from v9 to v11
- new patch
---
 drivers/irqchip/irq-gic-v3-its-msi-parent.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
index 75aa0d4bd1346..33e94cfc4d506 100644
--- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
@@ -195,7 +195,8 @@ static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 		 * FIXME: See the above PCI prepare comment. The domain
 		 * size is also known at domain creation time.
 		 */
-		info->ops->msi_prepare = its_pmsi_prepare;
+		if (!info->ops->msi_prepare)
+			info->ops->msi_prepare = its_pmsi_prepare;
 		break;
 	default:
 		/* Confused. How did the lib return true? */

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 11 12:57:30 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:30 -0500
Subject: [PATCH v12 2/9] PCI: endpoint: Add RC-to-EP doorbell support using
 platform MSI controller
In-Reply-To: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
Message-ID: <20241211-ep-msi-v12-2-33d4532fa520@nxp.com>

Doorbell feature is implemented by mapping the EP's MSI interrupt
controller message address to a dedicated BAR in the EPC core. It is the
responsibility of the EPF driver to pass the actual message data to be
written by the host to the doorbell BAR region through its own logic.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v10 to v12
- none

Change from v9 to v10
- Create msi domain for each function device.
- Remove only function support limiation. My hardware only support one
function, so not test more than one case.
- use "msi-map" descript msi information

  msi-map = <func_no << 8  | vfunc_no, &its, start_stream_id,  size>;

Chagne from v8 to v9
- sort header file
- use pci_epc_get(dev_name(msi_desc_to_dev(desc)));
- check epf number at pci_epf_alloc_doorbell
- Add comments for miss msi-parent case

change from v5 to v8
-none

Change from v4 to v5
- Remove request_irq() in pci_epc_alloc_doorbell() and leave to EP function
driver, so ep function driver can register differece call back function for
difference doorbell events and set irq affinity to differece CPU core.
- Improve error message when MSI allocate failure.

Change from v3 to v4
- msi change to use msi_get_virq() avoid use msi_for_each_desc().
- add new struct for pci_epf_doorbell_msg to msi msg,virq and irq name.
- move mutex lock to epc function
- initialize variable at declear place.
- passdown epf to epc*() function to simplify code.
---
 drivers/pci/endpoint/Makefile     |   2 +-
 drivers/pci/endpoint/pci-ep-msi.c | 148 ++++++++++++++++++++++++++++++++++++++
 include/linux/pci-ep-msi.h        |  15 ++++
 include/linux/pci-epf.h           |  16 +++++
 4 files changed, 180 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/endpoint/Makefile b/drivers/pci/endpoint/Makefile
index 95b2fe47e3b06..a1ccce440c2c5 100644
--- a/drivers/pci/endpoint/Makefile
+++ b/drivers/pci/endpoint/Makefile
@@ -5,4 +5,4 @@
 
 obj-$(CONFIG_PCI_ENDPOINT_CONFIGFS)	+= pci-ep-cfs.o
 obj-$(CONFIG_PCI_ENDPOINT)		+= pci-epc-core.o pci-epf-core.o\
-					   pci-epc-mem.o functions/
+					   pci-epc-mem.o pci-ep-msi.o functions/
diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
new file mode 100644
index 0000000000000..b0a91fde202f3
--- /dev/null
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCI Endpoint *Controller* (EPC) MSI library
+ *
+ * Copyright (C) 2024 NXP
+ * Author: Frank Li <Frank.Li at nxp.com>
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/pci-epc.h>
+#include <linux/pci-epf.h>
+#include <linux/pci-ep-cfs.h>
+#include <linux/pci-ep-msi.h>
+#include <linux/slab.h>
+
+static void pci_epf_write_msi_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	struct msi_desc *desc = irq_data_get_msi_desc(d);
+	struct pci_epf *epf = to_pci_epf(desc->dev);
+
+	if (epf && epf->db_msg && desc->msi_index < epf->num_db)
+		memcpy(&epf->db_msg[desc->msi_index].msg, msg, sizeof(*msg));
+}
+
+static void pci_epf_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+	arg->desc = desc;
+	arg->hwirq = desc->msi_index;
+}
+
+static int pci_epf_msi_prepare(struct irq_domain *domain, struct device *dev,
+			       int nvec, msi_alloc_info_t *arg)
+{
+	struct pci_epf *epf = to_pci_epf(dev);
+	struct msi_domain_info *msi_info;
+	struct pci_epc *epc = epf->epc;
+
+	memset(arg, 0, sizeof(*arg));
+	arg->scratchpad[0].ul = of_msi_map_id(epc->dev.parent, NULL,
+					      (epf->func_no << 8) | epf->vfunc_no);
+
+	/*
+	 * @domain->msi_domain_info->hwsize contains the size of the device
+	 * domain, but vector allocation happens one by one.
+	 */
+	msi_info = msi_get_domain_info(domain);
+	if (msi_info->hwsize > nvec)
+		nvec = msi_info->hwsize;
+
+	/* Allocate at least 32 MSIs, and always as a power of 2 */
+	nvec = max_t(int, 32, roundup_pow_of_two(nvec));
+
+	msi_info = msi_get_domain_info(domain->parent);
+	return msi_info->ops->msi_prepare(domain->parent, dev, nvec, arg);
+}
+
+static const struct msi_domain_template pci_epf_msi_template = {
+	.chip = {
+		.name			= "EP-MSI",
+		.irq_mask		= irq_chip_mask_parent,
+		.irq_unmask		= irq_chip_unmask_parent,
+		.irq_write_msi_msg	= pci_epf_write_msi_msg,
+		/* The rest is filled in by the MSI parent */
+	},
+
+	.ops = {
+		.msi_prepare		= pci_epf_msi_prepare,
+		.set_desc		= pci_epf_msi_set_desc,
+	},
+
+	.info = {
+		.bus_token		= DOMAIN_BUS_DEVICE_MSI,
+	},
+};
+
+static int pci_epf_device_msi_init_and_alloc_irqs(struct device *dev, unsigned int nvec)
+{
+	struct irq_domain *domain = dev->msi.domain;
+
+	if (!domain)
+		return -EINVAL;
+
+	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN,
+					  &pci_epf_msi_template, nvec, NULL, NULL))
+		return -ENODEV;
+
+	return msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, nvec - 1);
+}
+
+int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
+{
+	struct pci_epc *epc = epf->epc;
+	struct device *dev = &epf->dev;
+	struct irq_domain *dom;
+	void *msg;
+	u32 rid;
+	int ret;
+	int i;
+
+	rid = (epf->func_no << 8) | epf->vfunc_no;
+	dom = of_msi_map_get_device_domain(epc->dev.parent, rid, DOMAIN_BUS_PLATFORM_MSI);
+	if (!dom) {
+		dev_err(dev, "Can't find msi domain\n");
+		return -EINVAL;
+	}
+
+	dev_set_msi_domain(dev, dom);
+
+	msg = kcalloc(num_db, sizeof(struct pci_epf_doorbell_msg), GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	epf->num_db = num_db;
+	epf->db_msg = msg;
+
+	ret = pci_epf_device_msi_init_and_alloc_irqs(dev, num_db);
+	if (ret) {
+		/*
+		 * The pcie_ep DT node has to specify 'msi-parent' for EP
+		 * doorbell support to work. Right now only GIC ITS is
+		 * supported. If you have GIC ITS and reached this print,
+		 * perhaps you are missing 'msi-map' in DT.
+		 */
+		dev_err(dev, "Failed to allocate MSI\n");
+		kfree(msg);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < num_db; i++)
+		epf->db_msg[i].virq = msi_get_virq(dev, i);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epf_alloc_doorbell);
+
+void pci_epf_free_doorbell(struct pci_epf *epf)
+{
+	msi_domain_free_irqs_all(&epf->dev, MSI_DEFAULT_DOMAIN);
+	msi_remove_device_irq_domain(&epf->dev, MSI_DEFAULT_DOMAIN);
+
+	kfree(epf->db_msg);
+	epf->db_msg = NULL;
+	epf->num_db = 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_free_doorbell);
diff --git a/include/linux/pci-ep-msi.h b/include/linux/pci-ep-msi.h
new file mode 100644
index 0000000000000..f0cfecf491199
--- /dev/null
+++ b/include/linux/pci-ep-msi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PCI Endpoint *Function* side MSI header file
+ *
+ * Copyright (C) 2024 NXP
+ * Author: Frank Li <Frank.Li at nxp.com>
+ */
+
+#ifndef __PCI_EP_MSI__
+#define __PCI_EP_MSI__
+
+int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 nums);
+void pci_epf_free_doorbell(struct pci_epf *epf);
+
+#endif /* __PCI_EP_MSI__ */
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 18a3aeb62ae4e..5374e6515ffa0 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -12,6 +12,7 @@
 #include <linux/configfs.h>
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <linux/msi.h>
 #include <linux/pci.h>
 
 struct pci_epf;
@@ -125,6 +126,17 @@ struct pci_epf_bar {
 	int		flags;
 };
 
+/**
+ * struct pci_epf_doorbell_msg - represents doorbell message
+ * @msi_msg: MSI message
+ * @virq: irq number of this doorbell MSI message
+ * @name: irq name for doorbell interrupt
+ */
+struct pci_epf_doorbell_msg {
+	struct msi_msg msg;
+	int virq;
+};
+
 /**
  * struct pci_epf - represents the PCI EPF device
  * @dev: the PCI EPF device
@@ -152,6 +164,8 @@ struct pci_epf_bar {
  * @vfunction_num_map: bitmap to manage virtual function number
  * @pci_vepf: list of virtual endpoint functions associated with this function
  * @event_ops: Callbacks for capturing the EPC events
+ * @db_msg: data for MSI from RC side
+ * @num_db: number of doorbells
  */
 struct pci_epf {
 	struct device		dev;
@@ -182,6 +196,8 @@ struct pci_epf {
 	unsigned long		vfunction_num_map;
 	struct list_head	pci_vepf;
 	const struct pci_epc_event_ops *event_ops;
+	struct pci_epf_doorbell_msg *db_msg;
+	u16 num_db;
 };
 
 /**

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 11 12:57:31 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:31 -0500
Subject: [PATCH v12 3/9] irqdomain: Add IRQ_DOMAIN_FLAG_MSI_IMMUTABLE and
 irq_domain_is_msi_immutable()
In-Reply-To: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
Message-ID: <20241211-ep-msi-v12-3-33d4532fa520@nxp.com>

Add the flag IRQ_DOMAIN_FLAG_MSI_IMMUTABLE and the API function
irq_domain_is_msi_immutable() to check if the MSI controller retains an
immutable address/data pair during irq_set_affinity().

Ensure compatibility with MSI users like PCIe Endpoint Doorbell, which
require the address/data pair to remain unchanged after setup. Use this
function to verify if the MSI controller is immutable.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v11 to v12
- change to IRQ_DOMAIN_FLAG_MSI_IMMUTABLE to minimized the code change.

Thomas Gleixner:
	I move IRQ_DOMAIN_FLAG_MSI_IMMUTABLE to irqdomain.h to simplify
helper function's implement. But I am not sure if it is reasonable.

	If you have any concern, let me know.
---
 include/linux/irqdomain.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index e432b6a12a32f..e63652604b621 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -231,6 +231,9 @@ enum {
 	/* Irq domain must destroy generic chips when removed */
 	IRQ_DOMAIN_FLAG_DESTROY_GC	= (1 << 10),
 
+	/* Address and data pair is mutable when irq_set_affinity() */
+	IRQ_DOMAIN_FLAG_MSI_IMMUTABLE	= (1 << 11),
+
 	/*
 	 * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
 	 * for implementation specific purposes and ignored by the
@@ -692,6 +695,11 @@ static inline bool irq_domain_is_msi_device(struct irq_domain *domain)
 	return domain->flags & IRQ_DOMAIN_FLAG_MSI_DEVICE;
 }
 
+static inline bool irq_domain_is_msi_immutable(struct irq_domain *domain)
+{
+	return domain->flags & IRQ_DOMAIN_FLAG_MSI_IMMUTABLE;
+}
+
 #else	/* CONFIG_IRQ_DOMAIN_HIERARCHY */
 static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
 			unsigned int nr_irqs, int node, void *arg)

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 11 12:57:32 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:32 -0500
Subject: [PATCH v12 4/9] irqchip/gic-v3-its: Set
 IRQ_DOMAIN_FLAG_MSI_IMMUTABLE for ITS
In-Reply-To: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
Message-ID: <20241211-ep-msi-v12-4-33d4532fa520@nxp.com>

Set the IRQ_DOMAIN_FLAG_MSI_IMMUTABLE flag for ITS, as it does not change
the address/data pair after setup.

Ensure compatibility with MSI users, such as PCIe Endpoint Doorbell, which
require the address/data pair to remain unchanged. Enable PCIe endpoints to
use ITS for triggering doorbells from the PCIe Root Complex (RC) side.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
change from v11 to v12
- new patch
---
 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 92244cfa04647..edaae13bbd3cc 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -5126,7 +5126,7 @@ static int its_init_domain(struct its_node *its)
 	irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
 
 	inner_domain->msi_parent_ops = &gic_v3_its_msi_parent_ops;
-	inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
+	inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT | IRQ_DOMAIN_FLAG_MSI_IMMUTABLE;
 
 	return 0;
 }

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 11 12:57:33 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:33 -0500
Subject: [PATCH v12 5/9] PCI: endpoint: pci-ep-msi: Add check for MSI
 address/data pair immutability
In-Reply-To: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
Message-ID: <20241211-ep-msi-v12-5-33d4532fa520@nxp.com>

Check the immutability of the MSI address/data pair by calling
irq_domain_is_msi_immutable() when allocating a doorbell.

Prevent the use of MSI controllers that change the address/data pair during
irq_set_affinity(), as the current PCI endpoint implementation does not
support such behavior.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v11 to v12
- use helper function irq_domain_is_msi_immutable().
- remove msi parent check.
- split msi header, its and endpoint to 3 patches.
- rework commit message.

Change from v9 to v11
- new patch
---
 drivers/pci/endpoint/pci-ep-msi.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
index b0a91fde202f3..eda027b734b73 100644
--- a/drivers/pci/endpoint/pci-ep-msi.c
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -107,6 +107,11 @@ int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
 		return -EINVAL;
 	}
 
+	if (!irq_domain_is_msi_immutable(dom)) {
+		dev_err(dev, "Can't support mutable address/data pair MSI controller\n");
+		return -EINVAL;
+	}
+
 	dev_set_msi_domain(dev, dom);
 
 	msg = kcalloc(num_db, sizeof(struct pci_epf_doorbell_msg), GFP_KERNEL);

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 11 12:57:37 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 11 Dec 2024 15:57:37 -0500
Subject: [PATCH v12 9/9] tools: PCI: Add 'B' option for test doorbell
In-Reply-To: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
Message-ID: <20241211-ep-msi-v12-9-33d4532fa520@nxp.com>

Add doorbell test support.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v3 to v12
- none
---
 tools/pci/pcitest.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 7b530d838d408..fcff0224a3381 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -34,6 +34,7 @@ struct pci_test {
 	bool		copy;
 	unsigned long	size;
 	bool		use_dma;
+	bool		doorbell;
 };
 
 static int run_test(struct pci_test *test)
@@ -147,6 +148,15 @@ static int run_test(struct pci_test *test)
 			fprintf(stdout, "%s\n", result[ret]);
 	}
 
+	if (test->doorbell) {
+		ret = ioctl(fd, PCITEST_DOORBELL, 0);
+		fprintf(stdout, "Ringing doorbell on the EP\t\t");
+		if (ret < 0)
+			fprintf(stdout, "TEST FAILED\n");
+		else
+			fprintf(stdout, "%s\n", result[ret]);
+	}
+
 	fflush(stdout);
 	close(fd);
 	return (ret < 0) ? ret : 1 - ret; /* return 0 if test succeeded */
@@ -172,7 +182,7 @@ int main(int argc, char **argv)
 	/* set default endpoint device */
 	test->device = "/dev/pci-endpoint-test.0";
 
-	while ((c = getopt(argc, argv, "D:b:m:x:i:deIlhrwcs:")) != EOF)
+	while ((c = getopt(argc, argv, "D:b:m:x:i:BdeIlhrwcs:")) != EOF)
 	switch (c) {
 	case 'D':
 		test->device = optarg;
@@ -222,6 +232,9 @@ int main(int argc, char **argv)
 	case 'd':
 		test->use_dma = true;
 		continue;
+	case 'B':
+		test->doorbell = true;
+		continue;
 	case 'h':
 	default:
 usage:
@@ -241,6 +254,7 @@ int main(int argc, char **argv)
 			"\t-w			Write buffer test\n"
 			"\t-c			Copy buffer test\n"
 			"\t-s <size>		Size of buffer {default: 100KB}\n"
+			"\t-B			Doorbell test\n"
 			"\t-h			Print this help message\n",
 			argv[0]);
 		return -EINVAL;

-- 
2.34.1



From will at kernel.org  Wed Dec 11 13:02:44 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 21:02:44 +0000
Subject: [RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <20241211154611.40395-3-miko.lenczewski@arm.com>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
 <20241211154611.40395-3-miko.lenczewski@arm.com>
Message-ID: <20241211210243.GA17155@willie-the-truck>

On Wed, Dec 11, 2024 at 03:45:03PM +0000, Miko?aj Lenczewski wrote:
> The Break-Before-Make cpu feature supports multiple levels (levels 0-2),
> and this commit adds a dedicated BBML2 cpufeature to test against
> support for.
> 
> In supporting BBM level 2, we open ourselves up to potential TLB
> Conflict Abort Exceptions during expected execution, instead of only
> in exceptional circumstances. In the case of an abort, it is
> implementation defined at what stage the abort is generated, and
> the minimal set of required invalidations is also implementation
> defined. The maximal set of invalidations is to do a `tlbi vmalle1`
> or `tlbi vmalls12e1`, depending on the stage.
> 
> Such aborts should not occur on Arm hardware, and were not seen in
> benchmarked systems, so unless performance concerns arise, implementing
> the abort handlers with the worst-case invalidations seems like an
> alright hack.
> 
> Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
> ---
>  arch/arm64/include/asm/cpufeature.h | 14 ++++++++++++++
>  arch/arm64/kernel/cpufeature.c      |  7 +++++++
>  arch/arm64/mm/fault.c               | 27 ++++++++++++++++++++++++++-
>  arch/arm64/tools/cpucaps            |  1 +
>  4 files changed, 48 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 8b4e5a3cd24c..a9f2ac335392 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -866,6 +866,20 @@ static __always_inline bool system_supports_mpam_hcr(void)
>  	return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
>  }
>  
> +static inline bool system_supports_bbml2(void)
> +{
> +	/* currently, BBM is only relied on by code touching the userspace page
> +	 * tables, and as such we are guaranteed that caps have been finalised.
> +	 *
> +	 * if later we want to use BBM for kernel mappings, particularly early
> +	 * in the kernel, this may return 0 even if BBML2 is actually supported,
> +	 * which means unnecessary break-before-make sequences, but is still
> +	 * correct
> +	 */
> +
> +	return alternative_has_cap_unlikely(ARM64_HAS_BBML2);
> +}
> +
>  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 6ce71f444ed8..7cc94bd5da24 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2917,6 +2917,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>  		.matches = has_cpuid_feature,
>  		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP)
>  	},
> +	{
> +		.desc = "BBM Level 2 Support",
> +		.capability = ARM64_HAS_BBML2,
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +		.matches = has_cpuid_feature,
> +		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, BBM, 2)
> +	},
>  	{
>  		.desc = "52-bit Virtual Addressing for KVM (LPA2)",
>  		.capability = ARM64_HAS_LPA2,
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index ef63651099a9..dc119358cbc1 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -844,6 +844,31 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
>  	return 0;
>  }
>  
> +static int do_conflict_abort(unsigned long far, unsigned long esr,
> +			     struct pt_regs *regs)
> +{
> +	if (!system_supports_bbml2())
> +		return do_bad(far, esr, regs);
> +
> +	/* if we receive a TLB conflict abort, we know that there are multiple
> +	 * TLB entries that translate the same address range. the minimum set
> +	 * of invalidations to clear these entries is implementation defined.
> +	 * the maximum set is defined as either tlbi(vmalls12e1) or tlbi(alle1).
> +	 *
> +	 * if el2 is enabled and stage 2 translation enabled, this may be
> +	 * raised as a stage 2 abort. if el2 is enabled but stage 2 translation
> +	 * disabled, or if el2 is disabled, it will be raised as a stage 1
> +	 * abort.
> +	 *
> +	 * local_flush_tlb_all() does a tlbi(vmalle1), which is enough to
> +	 * handle a stage 1 abort.
> +	 */
> +
> +	local_flush_tlb_all();
> +
> +	return 0;
> +}

Can we actually guarantee that we make it this far without taking another
abort? Given that I'm yet to see one of these things in the wild, I'm
fairly opposed to pretending that we can handle them. We'd be much better
off only violating BBM on CPUs that are known to handle the conflict
gracefully. Judging by your later patch, this is practically keyed off
the MIDR _anyway_...

Will


From will at kernel.org  Wed Dec 11 13:30:19 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 21:30:19 +0000
Subject: [PATCH v3 1/1] arm64: rsi: Add automatic arm-cca-guest module
 loading
In-Reply-To: <20241207012128.247522-2-jeremy.linton@arm.com>
References: <20241207012128.247522-1-jeremy.linton@arm.com>
 <20241207012128.247522-2-jeremy.linton@arm.com>
Message-ID: <20241211213018.GA17486@willie-the-truck>

On Fri, Dec 06, 2024 at 07:21:28PM -0600, Jeremy Linton wrote:
> The TSM module provides guest identification and attestation when a
> guest runs in CCA mode. By creating a dummy platform device, let's
> ensure the module is automatically loaded. The udev daemon loads the
> TSM module after it receives a device addition event. Once that
> happens, it can be used earlier in the boot process to decrypt the
> rootfs.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> Reviewed-by: Gavin Shan <gshan at redhat.com>
> ---
>  arch/arm64/include/asm/rsi.h                    |  2 ++
>  arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
>  drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
>  3 files changed, 25 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
> index 188cbb9b23f5..b42aeac05340 100644
> --- a/arch/arm64/include/asm/rsi.h
> +++ b/arch/arm64/include/asm/rsi.h
> @@ -10,6 +10,8 @@
>  #include <linux/jump_label.h>
>  #include <asm/rsi_cmds.h>
>  
> +#define RSI_PDEV_NAME "arm-cca-dev"
> +
>  DECLARE_STATIC_KEY_FALSE(rsi_present);
>  
>  void __init arm64_rsi_init(void);
> diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
> index 3031f25c32ef..5434e5496ac2 100644
> --- a/arch/arm64/kernel/rsi.c
> +++ b/arch/arm64/kernel/rsi.c
> @@ -8,6 +8,7 @@
>  #include <linux/psci.h>
>  #include <linux/swiotlb.h>
>  #include <linux/cc_platform.h>
> +#include <linux/platform_device.h>
>  
>  #include <asm/io.h>
>  #include <asm/mem_encrypt.h>
> @@ -140,3 +141,17 @@ void __init arm64_rsi_init(void)
>  	static_branch_enable(&rsi_present);
>  }
>  
> +static struct platform_device rsi_dev = {
> +	.name = RSI_PDEV_NAME,
> +	.id = PLATFORM_DEVID_NONE
> +};
> +
> +static int __init rsi_init(void)
> +{
> +	if (is_realm_world() &&
> +	    platform_device_register(&rsi_dev))
> +		pr_err("failed to register rsi platform device\n");
> +	return 0;
> +}
> +
> +arch_initcall(rsi_init)

This file already has an arm64_rsi_init()... Ideally, we'd hang this
off the end of that instead of the initcall but I suspect you're going
to tell me that platform_device_register() doesn't like being called
that early?

If so, perhaps arm64_create_dummy_rsi_dev() might be better?

Will


From will at kernel.org  Wed Dec 11 13:34:11 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 21:34:11 +0000
Subject: [PATCH 0/6] arm64: errata: Add Qualcomm CPUs to the Spectre
 mitigation lists
In-Reply-To: <CAD=FV=U5xraosVuDGXxBN5Ajo0n=s50JZqtgQGPs1C9jM3YaFw@mail.gmail.com>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241210155604.GA15918@willie-the-truck>
 <CAD=FV=U5xraosVuDGXxBN5Ajo0n=s50JZqtgQGPs1C9jM3YaFw@mail.gmail.com>
Message-ID: <20241211213410.GB17486@willie-the-truck>

On Tue, Dec 10, 2024 at 08:53:46AM -0800, Doug Anderson wrote:
> On Tue, Dec 10, 2024 at 7:56?AM Will Deacon <will at kernel.org> wrote:
> > On Mon, Dec 09, 2024 at 09:43:10AM -0800, Douglas Anderson wrote:
> > >
> > > Since Qualcomm CPUs are all derivatives of ARM cores they all have
> > > unique MIDR values. This means that the tables listing necessary
> > > Spectre mitigations need special entries for them. However, those
> > > entries are not present and that means that some Spectre mitigations
> > > are lacking for Qualcomm CPUs.
> > >
> > > I've made an attempt at **GUESSING** what the right patches should be
> > > to enable mitigations for Qualcomm CPUs. This is mostly me searching
> > > the web to figure out what ARM cores various Qualcomm cores are based
> > > off of.
> > >
> > > These patches get more and more sketchy as the series progresses and I
> > > have noted that the later patces DON'T EVEN COMPILE. I have included
> > > them to make it obvious that I think these cores are affected even if
> > > I don't have all the right information to mitigate them. Hopefully
> > > Qualcomm can come and fix this mess for me.
> > >
> > > I'll note that I am certainly no expert on Spectre. Mostly I ended up
> > > here running `lscpu` on a device and noticing that it thought that it
> > > wasn't affected by Spectre v2 when I thought it was.
> >
> > Whilst only Qualcomm can say definitively whether or not they are
> > affected (and what values of 'k' are required for the loop-based
> > workarounds), I can't help but wonder whether the current mitigation
> > code is structured the wrong way around in this case.
> >
> > It looks to me like we don't have a way to identify a "vulnerable" CPU
> > for Spectre-BHB; either a CPU has some sort of mitigation or it's
> > unaffected. That means that there's very little incentive for vendors
> > to add their CPUs to one of the lists -- if they do nothing, userspace
> > is told that everything is golden and they don't pay the performance
> > hit of a workaround!
> >
> > So I think we should consider turning this on its head and assume that
> > CPUs we don't know about are vulnerable, having a list of unaffected
> > cores that predate the introduction of CSV2.3 which can be queried by
> > is_spectre_bhb_affected(). We can do that without the assistance of the
> > CPU vendors.
> >
> > Does that make sense, or did I miss something?
> 
> It makes sense to me. I'm not sure I'd be the best person to actually
> implement that, though. Maybe someone CCed on this thread could take a
> stab at it? It seems like folks from ARM would know the most about the
> various mitigations and which pre-CSV2.3 cores were safe.

I think we could start with an empty list tbh. If you take a stab at it,
I'm happy to review it. Folks with knowledge about the specific CPUs
can send patches on top.

Will


From will at kernel.org  Wed Dec 11 13:43:39 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 21:43:39 +0000
Subject: [PATCH v2] arm64/Kconfig: Drop EXECMEM dependency from
 ARCH_WANTS_EXECMEM_LATE
In-Reply-To: <20241210043257.715822-1-anshuman.khandual@arm.com>
References: <20241210043257.715822-1-anshuman.khandual@arm.com>
Message-ID: <20241211214338.GC17486@willie-the-truck>

On Tue, Dec 10, 2024 at 10:02:57AM +0530, Anshuman Khandual wrote:
> ARCH_WANTS_EXECMEM_LATE indicates subscribing platform's preference for
> EXECMEM late initialisation without creating a new dependency. Hence this
> just drops EXECMEM dependency while selecting ARCH_WANTS_EXECMEM_LATE.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: linux-arm-kernel at lists.infradead.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 patch applies on v6.13-rc1
> 
> Changes in V2:
> 
> - Dropped generic EXECMEM config changes per Catalin
> - Updated the commit message as required
> 
> Changes in V1:
> 
> https://lore.kernel.org/all/20241209031251.515903-1-anshuman.khandual at arm.com/
> 
>  arch/arm64/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b5479c8b454c..b146372bc365 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -113,7 +113,7 @@ config ARM64
>  	select ARCH_WANT_FRAME_POINTERS
>  	select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
>  	select ARCH_WANT_LD_ORPHAN_WARN
> -	select ARCH_WANTS_EXECMEM_LATE if EXECMEM
> +	select ARCH_WANTS_EXECMEM_LATE
>  	select ARCH_WANTS_NO_INSTR
>  	select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
>  	select ARCH_HAS_UBSAN

tbh, I really don't see what we gain from this change but it also
looks harmless. *shrug* I guess I can pick it up.

Will


From will at kernel.org  Wed Dec 11 13:49:40 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 21:49:40 +0000
Subject: [PATCH v2 1/1] KVM: arm64: Allow cacheable stage 2 mapping using
 VMA flags
In-Reply-To: <SA1PR12MB71991EC85E8EEDD1C5115886B03E2@SA1PR12MB7199.namprd12.prod.outlook.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241118131958.4609-2-ankita@nvidia.com>
 <20241210141334.GD15607@willie-the-truck>
 <SA1PR12MB71991EC85E8EEDD1C5115886B03E2@SA1PR12MB7199.namprd12.prod.outlook.com>
Message-ID: <20241211214939.GD17486@willie-the-truck>

On Wed, Dec 11, 2024 at 02:58:38AM +0000, Ankit Agrawal wrote:
> Thanks Will for taking a look.
> 
> >> The device memory such as on the Grace Hopper systems is interchangeable
> >> with DDR memory and retains its properties. Allow executable faults
> >> on the memory determined as Normal cacheable.
> >
> > Sorry, but a change this subtle to the arch code is going to need a _much_
> > better explanation than the rambling text above.
> 
> Understood, I'll work on the text and try to make it coherent.

Heh, I thought it was the patch trying to make things coherent :p

Will


From will at kernel.org  Wed Dec 11 13:51:40 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 21:51:40 +0000
Subject: [PATCH] perf/arm-cmn: Permit more exhaustive groups
In-Reply-To: <bdfd1e58dac449e407c5cacfd6bf8577dc0a5899.1733943898.git.robin.murphy@arm.com>
References: <bdfd1e58dac449e407c5cacfd6bf8577dc0a5899.1733943898.git.robin.murphy@arm.com>
Message-ID: <20241211215139.GE17486@willie-the-truck>

[+ Ilkka for comments/testing]

On Wed, Dec 11, 2024 at 07:04:58PM +0000, Robin Murphy wrote:
> The group validation logic still somewhat assumes the original CMN-600
> case of events counting globally, such that if one tries to group 9
> events where the first 8 target a single DTC domain, the 9th will be
> rejected because *a* DTC domain is full, even though it might only
> target other non-overlapping domains and thus still be schedulable.
> Improve matters by only counting the DTCs that the new event actually
> needs (as arm_cmn_val_add_event() was already clever enough to do).
> 
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>  drivers/perf/arm-cmn.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index edefb51ac90a..b49e353e10ab 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -1779,8 +1779,8 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event)
>  		goto done;
>  	}
>  
> -	for (i = 0; i < CMN_MAX_DTCS; i++)
> -		if (val->dtc_count[i] == CMN_DT_NUM_COUNTERS)
> +	for_each_hw_dtc_idx(hw, dtc, idx)
> +		if (val->dtc_count[dtc] == CMN_DT_NUM_COUNTERS)
>  			goto done;
>  
>  	for_each_hw_dn(hw, dn, i) {
> -- 
> 2.39.2.101.g768bb238c484.dirty
> 


From will at kernel.org  Wed Dec 11 13:56:38 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 21:56:38 +0000
Subject: [PATCH v2] perf: imx9_perf: Introduce AXI filter version to
 refactor the driver and better extension
In-Reply-To: <20241211053455.z5zzawfacpyv2dlt@hippo>
References: <20241125104338.2433339-1-xu.yang_2@nxp.com>
 <20241209154419.GB12428@willie-the-truck>
 <20241210020212.yz3xowvdk27zmgsl@hippo>
 <20241210133732.GA15607@willie-the-truck>
 <20241211053455.z5zzawfacpyv2dlt@hippo>
Message-ID: <20241211215637.GF17486@willie-the-truck>

On Wed, Dec 11, 2024 at 01:35:16PM +0800, Xu Yang wrote:
> On Tue, Dec 10, 2024 at 01:37:32PM +0000, Will Deacon wrote:
> > On Tue, Dec 10, 2024 at 10:02:12AM +0800, Xu Yang wrote:
> > > On Mon, Dec 09, 2024 at 03:44:20PM +0000, Will Deacon wrote:
> > > > On Mon, Nov 25, 2024 at 06:43:38PM +0800, Xu Yang wrote:
> > > > > The imx93 is the first supported DDR PMU that supports read transaction,
> > > > > write transaction and read beats events which corresponding respecitively
> > > > > to counter 2, 3 and 4.
> > > > > 
> > > > > However, transaction-based AXI match has low accuracy when get total bits
> > > > > compared to beats-based. And imx93 doesn't assign AXI_ID to each master.
> > > > > So axi filter is not used widely on imx93. This could be regards as AXI
> > > > > filter version 1.
> > > > > 
> > > > > To improve the AXI filter capability, imx95 supports 1 read beats and 3
> > > > > write beats event which corresponding respecitively to counter 2-5. imx95
> > > > > also detailed AXI_ID allocation so that most of the master could be count
> > > > > individually. This could be regards as AXI filter version 2.
> > > > > 
> > > > > This will introduce AXI filter version to refactor the driver and support
> > > > > better extension, such as coming imx943.
> > > > > 
> > > > > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > > > > 
> > > > > ---
> > > > > Changes in v2:
> > > > >  - modify subject
> > > > >  - add comments for AXI_FILTER version
> > > > >  - type -> filter_ver
> > > > > ---
> > > > >  drivers/perf/fsl_imx9_ddr_perf.c | 33 ++++++++++++++++++++++++--------
> > > > >  1 file changed, 25 insertions(+), 8 deletions(-)
> > 
> > [...]
> > 
> > > > > @@ -624,11 +641,11 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
> > > > >  	hwc->idx = counter;
> > > > >  	hwc->state |= PERF_HES_STOPPED;
> > > > >  
> > > > > -	if (is_imx93(pmu))
> > > > > +	if (axi_filter_v1(pmu))
> > > > >  		/* read trans, write trans, read beat */
> > > > >  		imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
> > > > 
> > > > Hmm, doesn't this change mean we now enable this for imx91 as well? My
> > > > reading of the commit message is that imx93 was the first chip which
> > > > supports this.
> > > 
> > > Yes, it's enabled for imx91 too. In fact, imx91 is compatible with imx93.
> > > They use same configuration for axi filter.
> > 
> > Ok, but my worry is that the above code looks like userspace now _must_
> > provide valid values for the config1 (axi_id) and config2 (axi_mask)
> > fields on imx91, whereas before I think they were ignored by the driver.
> > 
> > In fact, without this change, how were the PMCFGn registers configured
> > on imx91? It looks to me like they were left uninitialised...
> 
> Before this change, PMCFGn registers are indeed not configured on imx91.
> However, they should be configured as imx93. I notice this thing when
> make this patch. First thing I tried is to add is_imx91(), then check it
> and is_imx93() by "||" operator. However, this way seems not scalable as
> more imx9x Soc comes out. Basically, AXI filter version will keep at V2
> unless big changes due to new features. However, perf tool need export
> correct MetricName via identifier in sysfs. So I made this patch, then
> PMCFGn will be configured based on axi filter version rather than pmu
> name.

Gotcha. But that means this is a fix, right? The commit message doesn't
really indicate that and we probably want a Fixes: tag to indicate how
far it should be backported.

Please can you send a v3 with that so I can apply it?

Thanks,

Will


From catalin.marinas at arm.com  Wed Dec 11 14:01:59 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 11 Dec 2024 22:01:59 +0000
Subject: [PATCH v2 1/1] KVM: arm64: Allow cacheable stage 2 mapping using
 VMA flags
In-Reply-To: <20241118131958.4609-2-ankita@nvidia.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241118131958.4609-2-ankita@nvidia.com>
Message-ID: <Z1oL1yZtdvGUIW9h@arm.com>

Hi Ankit,

On Mon, Nov 18, 2024 at 01:19:58PM +0000, ankita at nvidia.com wrote:
> Currently KVM determines if a VMA is pointing at IO memory by checking
> pfn_is_map_memory(). However, the MM already gives us a way to tell what
> kind of memory it is by inspecting the VMA.
> 
> This patch solves the problems where it is possible for the kernel to
> have VMAs pointing at cachable memory without causing
> pfn_is_map_memory() to be true, eg DAX memremap cases and CXL/pre-CXL
> devices. This memory is now properly marked as cachable in KVM.
> 
> The pfn_is_map_memory() is restrictive and allows only for the memory
> that is added to the kernel to be marked as cacheable. In most cases
> the code needs to know if there is a struct page, or if the memory is
> in the kernel map and pfn_valid() is an appropriate API for this.
> Extend the umbrella with pfn_valid() to include memory with no struct
> pages for consideration to be mapped cacheable in stage 2. A !pfn_valid()
> implies that the memory is unsafe to be mapped as cacheable.

Please note that a pfn_valid() does not imply the memory is in the
linear map, only that there's a struct page. Some cache maintenance you
do later in the patch may fail. kvm_is_device_pfn() was changed by
commit 873ba463914c ("arm64: decouple check whether pfn is in linear map
from pfn_valid()"), see the log for some explanation.

> Moreover take account of the mapping type in the VMA to make a decision
> on the mapping. The VMA's pgprot is tested to determine the memory type
> with the following mapping:
>  pgprot_noncached    MT_DEVICE_nGnRnE   device (or Normal_NC)
>  pgprot_writecombine MT_NORMAL_NC       device (or Normal_NC)
>  pgprot_device       MT_DEVICE_nGnRE    device (or Normal_NC)
>  pgprot_tagged       MT_NORMAL_TAGGED   RAM / Normal
>  -                   MT_NORMAL          RAM / Normal
> 
> Also take care of the following two cases that prevents the memory to
> be safely mapped as cacheable:
> 1. The VMA pgprot have VM_IO set alongwith MT_NORMAL or
>    MT_NORMAL_TAGGED. Although unexpected and wrong, presence of such
>    configuration cannot be ruled out.
> 2. Configurations where VM_MTE_ALLOWED is not set and KVM_CAP_ARM_MTE
>    is enabled. Otherwise a malicious guest can enable MTE at stage 1
>    without the hypervisor being able to tell. This could cause external
>    aborts.

A first point I'd make - we can simplify this a bit and only allow such
configuration if FWB is present. Do you have a platform without FWB that
needs such feature?

Another reason for the above is my second point - I don't like relying
on the user mapping memory type for this (at some point we may have
device pass-through without a VMM mapping). Can we use something like a
new VM_FORCE_CACHED flag instead? There's precedent for this with
VM_ALLOW_ANY_UNCACHED.

> Introduce a new variable noncacheable to represent whether the memory
> should not be mapped as cacheable. The noncacheable as false implies
> the memory is safe to be mapped cacheable. Use this to handle the
> aforementioned potentially unsafe cases for cacheable mapping.
> 
> Note when FWB is not enabled, the kernel expects to trivially do
> cache management by flushing the memory by linearly converting a
> kvm_pte to phys_addr to a KVA, see kvm_flush_dcache_to_poc(). This is
> only possibile for struct page backed memory. Do not allow non-struct
> page memory to be cachable without FWB.

I want to be sure we actually have a real case for this for the !FWB
case. One issue is that it introduces a mismatch between the VMM and the
guest mappings I'd rather not have to have to deal with. Another is that
we can't guarantee it is mapped in the kernel linear map, pfn_valid()
does not imply this (I'll say this a few times through this patch).

> The device memory such as on the Grace Hopper systems is interchangeable
> with DDR memory and retains its properties. Allow executable faults
> on the memory determined as Normal cacheable.

As Will said, please introduce the exec handling separately, it will be
easier to follow the patches.

The exec fault would require cache maintenance in certain conditions
(depending on CTR_EL0.{DIC,IDC}). Since you introduce some conditions on
pfn_valid() w.r.t. D-cache maintenance, I assume we have similar
restrictions for I/D cache coherency.

> @@ -1430,6 +1425,23 @@ static bool kvm_vma_mte_allowed(struct vm_area_struct *vma)
>  	return vma->vm_flags & VM_MTE_ALLOWED;
>  }
>  
> +/*
> + * Determine the memory region cacheability from VMA's pgprot. This
> + * is used to set the stage 2 PTEs.
> + */
> +static unsigned long mapping_type(pgprot_t page_prot)
> +{
> +	return FIELD_GET(PTE_ATTRINDX_MASK, pgprot_val(page_prot));
> +}
> +
> +/*
> + * Determine if the mapping type is normal cacheable.
> + */
> +static bool mapping_type_normal_cacheable(unsigned long mt)
> +{
> +	return (mt == MT_NORMAL || mt == MT_NORMAL_TAGGED);
> +}

Personally I'd not use this at all, maybe at most as a safety check and
warn but I'd rather have an opt-in from the host driver (which could
also ensure that the user mapping is cached).

> +
>  static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  			  struct kvm_s2_trans *nested,
>  			  struct kvm_memory_slot *memslot, unsigned long hva,
> @@ -1438,8 +1450,9 @@ 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, vfio_allow_any_uc = false;
> +	bool noncacheable = false, vfio_allow_any_uc = false;
>  	unsigned long mmu_seq;
> +	unsigned long mt;
>  	phys_addr_t ipa = fault_ipa;
>  	struct kvm *kvm = vcpu->kvm;
>  	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
> @@ -1568,6 +1581,17 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  
>  	vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED;
>  
> +	mt = mapping_type(vma->vm_page_prot);
> +
> +	/*
> +	 * Check for potentially ineligible or unsafe conditions for
> +	 * cacheable mappings.
> +	 */
> +	if (vma->vm_flags & VM_IO)
> +		noncacheable = true;
> +	else if (!mte_allowed && kvm_has_mte(kvm))
> +		noncacheable = true;
> +
>  	/* Don't use the VMA after the unlock -- it may have vanished */
>  	vma = NULL;
>  
> @@ -1591,19 +1615,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  	if (is_error_noslot_pfn(pfn))
>  		return -EFAULT;
>  
> -	if (kvm_is_device_pfn(pfn)) {
> -		/*
> -		 * If the page was identified as device early by looking at
> -		 * the VMA flags, vma_pagesize is already representing the
> -		 * largest quantity we can map.  If instead it was mapped
> -		 * via __kvm_faultin_pfn(), vma_pagesize is set to PAGE_SIZE
> -		 * and must not be upgraded.
> -		 *
> -		 * In both cases, we don't let transparent_hugepage_adjust()
> -		 * change things at the last minute.
> -		 */
> -		device = true;
> -	} else if (logging_active && !write_fault) {
> +	/*
> +	 * pfn_valid() indicates to the code if there is a struct page, or
> +	 * if the memory is in the kernel map. Any memory region otherwise
> +	 * is unsafe to be cacheable.
> +	 */
> +	if (!pfn_valid(pfn))
> +		noncacheable = true;

The assumptions here are wrong. pfn_valid() does not imply the memory is
in the kernel map.

> +
> +	if (!noncacheable && logging_active && !write_fault) {
>  		/*
>  		 * Only actually map the page as writable if this was a write
>  		 * fault.
> @@ -1611,7 +1631,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  		writable = false;
>  	}
>  
> -	if (exec_fault && device)
> +	/*
> +	 * Do not allow exec fault; unless the memory is determined safely
> +	 * to be Normal cacheable.
> +	 */
> +	if (exec_fault && (noncacheable || !mapping_type_normal_cacheable(mt)))
>  		return -ENOEXEC;
>  
>  	/*
> @@ -1641,10 +1665,19 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  	}
>  
>  	/*
> +	 * If the page was identified as device early by looking at
> +	 * the VMA flags, vma_pagesize is already representing the
> +	 * largest quantity we can map.  If instead it was mapped
> +	 * via gfn_to_pfn_prot(), vma_pagesize is set to PAGE_SIZE
> +	 * and must not be upgraded.
> +	 *
> +	 * In both cases, we don't let transparent_hugepage_adjust()
> +	 * change things at the last minute.
> +	 *
>  	 * If we are not forced to use page mapping, check if we are
>  	 * backed by a THP and thus use block mapping if possible.
>  	 */
> -	if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) {
> +	if (vma_pagesize == PAGE_SIZE && !(force_pte || noncacheable)) {
>  		if (fault_is_perm && fault_granule > PAGE_SIZE)
>  			vma_pagesize = fault_granule;
>  		else
> @@ -1658,7 +1691,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  		}
>  	}
>  
> -	if (!fault_is_perm && !device && kvm_has_mte(kvm)) {
> +	if (!fault_is_perm && !noncacheable && kvm_has_mte(kvm)) {
>  		/* Check the VMM hasn't introduced a new disallowed VMA */
>  		if (mte_allowed) {
>  			sanitise_mte_tags(kvm, pfn, vma_pagesize);
> @@ -1674,7 +1707,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  	if (exec_fault)
>  		prot |= KVM_PGTABLE_PROT_X;
>  
> -	if (device) {
> +	/*
> +	 * If any of the following pgprot modifiers are applied on the pgprot,
> +	 * consider as device memory and map in Stage 2 as device or
> +	 * Normal noncached:
> +	 * pgprot_noncached
> +	 * pgprot_writecombine
> +	 * pgprot_device
> +	 */
> +	if (!mapping_type_normal_cacheable(mt)) {
>  		if (vfio_allow_any_uc)
>  			prot |= KVM_PGTABLE_PROT_NORMAL_NC;
>  		else
> @@ -1684,6 +1725,20 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  		prot |= KVM_PGTABLE_PROT_X;
>  	}

I'd leave the device check in place, maybe rename it to something else
to distinguish from linear map memory (e.g. !pfn_is_map_memory()) and
only deal with the attributes for this device pfn which could be Device,
Normal-NC or Normal-WB depending on the presence of some VM_* flags.
Deny execution in the first patch, introduce it subsequently.

> +	/*
> +	 *  When FWB is unsupported KVM needs to do cache flushes
> +	 *  (via dcache_clean_inval_poc()) of the underlying memory. This is
> +	 *  only possible if the memory is already mapped into the kernel map
> +	 *  at the usual spot.
> +	 *
> +	 *  Validate that there is a struct page for the PFN which maps
> +	 *  to the KVA that the flushing code expects.
> +	 */
> +	if (!stage2_has_fwb(pgt) && !(pfn_valid(pfn))) {
> +		ret = -EINVAL;
> +		goto out_unlock;
> +	}

Cache maintenance relies on memory being mapped. That's what
memblock_is_map_memory() gives us. Hotplugged memory ends up in memblock
as arm64 selects ARCH_KEEP_MEMBLOCK.

> +
>  	/*
>  	 * Under the premise of getting a FSC_PERM fault, we just need to relax
>  	 * permissions only if vma_pagesize equals fault_granule. Otherwise,
> -- 
> 2.34.1
> 

-- 
Catalin


From will at kernel.org  Wed Dec 11 14:14:32 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 22:14:32 +0000
Subject: [PATCH v2 4/6] arm64/kvm: Avoid invalid physical addresses to
 signal owner updates
In-Reply-To: <20241205150229.3510177-12-ardb+git@google.com>
References: <20241205150229.3510177-8-ardb+git@google.com>
 <20241205150229.3510177-12-ardb+git@google.com>
Message-ID: <20241211221431.GG17486@willie-the-truck>

Hi Ard,

On Thu, Dec 05, 2024 at 04:02:34PM +0100, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb at kernel.org>
> 
> The pKVM stage2 mapping code relies on an invalid physical address to
> signal to the internal API that only the owner_id fields of descriptors
> should be updated, and these are stored in the high bits of invalid
> descriptors covering memory that has been donated to protected guests,
> and is therefore unmapped from the host stage-2 page tables.
> 
> Given that these invalid PAs are never stored into the descriptors, it
> is better to rely on an explicit flag, to clarify the API and to avoid
> confusion regarding whether or not the output address of a descriptor
> can ever be invalid to begin with (which is not the case with LPA2).
> 
> That removes a dependency on the logic that reasons about the maximum PA
> range, which differs on LPA2 capable CPUs based on whether LPA2 is
> enabled or not, and will be further clarified in subsequent patches.
> 
> Cc: Quentin Perret <qperret at google.com>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
>  arch/arm64/kvm/hyp/pgtable.c | 33 ++++++--------------
>  1 file changed, 10 insertions(+), 23 deletions(-)

Sorry that I didn't reply again on v1, but I have an annoying request
that would make this a little easier for me to follow (since I'm tainted
with the pKVM stack in Android that we're gradually landing upstream):

> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 40bd55966540..0569e1d97c38 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -35,14 +35,6 @@ static bool kvm_pgtable_walk_skip_cmo(const struct kvm_pgtable_visit_ctx *ctx)
>  	return unlikely(ctx->flags & KVM_PGTABLE_WALK_SKIP_CMO);
>  }
>  
> -static bool kvm_phys_is_valid(u64 phys)
> -{
> -	u64 parange_max = kvm_get_parange_max();
> -	u8 shift = id_aa64mmfr0_parange_to_phys_shift(parange_max);
> -
> -	return phys < BIT(shift);
> -}
> -
>  static bool kvm_block_mapping_supported(const struct kvm_pgtable_visit_ctx *ctx, u64 phys)
>  {
>  	u64 granule = kvm_granule_size(ctx->level);
> @@ -53,7 +45,7 @@ static bool kvm_block_mapping_supported(const struct kvm_pgtable_visit_ctx *ctx,
>  	if (granule > (ctx->end - ctx->addr))
>  		return false;
>  
> -	if (kvm_phys_is_valid(phys) && !IS_ALIGNED(phys, granule))
> +	if (!IS_ALIGNED(phys, granule))
>  		return false;
>  
>  	return IS_ALIGNED(ctx->addr, granule);
> @@ -587,6 +579,9 @@ struct stage2_map_data {
>  
>  	/* Force mappings to page granularity */
>  	bool				force_pte;
> +
> +	/* Walk should update owner_id only */
> +	bool				owner_update;

Can you rename this to "annotation", please? We'll eventually land other
types of invalid pte than ownership (e.g. MMIO_GUARD) and, given that
the ownership walker is caught by the 'force_pte' flag, it's a little
more generic.

Again, apologies I didn't ask for this earlier.

Will


From lkp at intel.com  Wed Dec 11 14:17:21 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Dec 2024 06:17:21 +0800
Subject: [PATCH v2 6/8] soc: mediatek: Add programming flow for
 unsupported subsys ID hardware
In-Reply-To: <20241211032256.28494-7-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-7-jason-jh.lin@mediatek.com>
Message-ID: <202412120633.avM5EfRz-lkp@intel.com>

Hi Jason-JH.Lin,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.13-rc2 next-20241211]
[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/Jason-JH-Lin/dt-bindings-mailbox-mediatek-Add-GCE-header-file-for-MT8196/20241211-112605
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20241211032256.28494-7-jason-jh.lin%40mediatek.com
patch subject: [PATCH v2 6/8] soc: mediatek: Add programming flow for unsupported subsys ID hardware
config: arm64-randconfig-002-20241212 (https://download.01.org/0day-ci/archive/20241212/202412120633.avM5EfRz-lkp at intel.com/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241212/202412120633.avM5EfRz-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/202412120633.avM5EfRz-lkp at intel.com/

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: cmdq_subsys_is_valid
   >>> referenced by mtk-mmsys.c:173 (drivers/soc/mediatek/mtk-mmsys.c:173)
   >>>               drivers/soc/mediatek/mtk-mmsys.o:(mtk_mmsys_update_bits) in archive vmlinux.a
   >>> referenced by mtk-mutex.c:976 (drivers/soc/mediatek/mtk-mutex.c:976)
   >>>               drivers/soc/mediatek/mtk-mutex.o:(mtk_mutex_enable_by_cmdq) in archive vmlinux.a

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


From csokas.bence at prolan.hu  Wed Dec 11 14:22:05 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?=)
Date: Wed, 11 Dec 2024 23:22:05 +0100
Subject: [PATCH] ASoC: sun4i-codec: Use new devm clk and reset APIs
Message-ID: <20241211222205.1915027-1-csokas.bence@prolan.hu>

Clean up error handling by using the new devm_
clock and reset functions. This should make it
easier to add new code, as we can eliminate the
"goto ladder" in probe().

Signed-off-by: Bence Cs?k?s <csokas.bence at prolan.hu>
---
 sound/soc/sunxi/sun4i-codec.c | 41 ++++++-----------------------------
 1 file changed, 7 insertions(+), 34 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 3d6156fefe75..b0ca293979d7 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -2273,7 +2273,7 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 	}
 
 	/* Get the clocks from the DT */
-	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
+	scodec->clk_apb = devm_clk_get_enabled(&pdev->dev, "apb");
 	if (IS_ERR(scodec->clk_apb)) {
 		dev_err(&pdev->dev, "Failed to get the APB clock\n");
 		return PTR_ERR(scodec->clk_apb);
@@ -2286,8 +2286,7 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 	}
 
 	if (quirks->has_reset) {
-		scodec->rst = devm_reset_control_get_exclusive(&pdev->dev,
-							       NULL);
+		scodec->rst = devm_reset_control_get_exclusive_deasserted(&pdev->dev, NULL);
 		if (IS_ERR(scodec->rst)) {
 			dev_err(&pdev->dev, "Failed to get reset control\n");
 			return PTR_ERR(scodec->rst);
@@ -2323,22 +2322,6 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	/* Enable the bus clock */
-	if (clk_prepare_enable(scodec->clk_apb)) {
-		dev_err(&pdev->dev, "Failed to enable the APB clock\n");
-		return -EINVAL;
-	}
-
-	/* Deassert the reset control */
-	if (scodec->rst) {
-		ret = reset_control_deassert(scodec->rst);
-		if (ret) {
-			dev_err(&pdev->dev,
-				"Failed to deassert the reset control\n");
-			goto err_clk_disable;
-		}
-	}
-
 	/* DMA configuration for TX FIFO */
 	scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
 	scodec->playback_dma_data.maxburst = quirks->dma_max_burst;
@@ -2356,7 +2339,7 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 				     &sun4i_codec_dai, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register our codec\n");
-		goto err_assert_reset;
+		return ret;
 	}
 
 	ret = devm_snd_soc_register_component(&pdev->dev,
@@ -2364,20 +2347,20 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 					      &dummy_cpu_dai, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register our DAI\n");
-		goto err_assert_reset;
+		return ret;
 	}
 
 	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
-		goto err_assert_reset;
+		return ret;
 	}
 
 	card = quirks->create_card(&pdev->dev);
 	if (IS_ERR(card)) {
 		ret = PTR_ERR(card);
 		dev_err(&pdev->dev, "Failed to create our card\n");
-		goto err_assert_reset;
+		return ret;
 	}
 
 	snd_soc_card_set_drvdata(card, scodec);
@@ -2385,17 +2368,10 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 	ret = snd_soc_register_card(card);
 	if (ret) {
 		dev_err_probe(&pdev->dev, ret, "Failed to register our card\n");
-		goto err_assert_reset;
+		return ret;
 	}
 
 	return 0;
-
-err_assert_reset:
-	if (scodec->rst)
-		reset_control_assert(scodec->rst);
-err_clk_disable:
-	clk_disable_unprepare(scodec->clk_apb);
-	return ret;
 }
 
 static void sun4i_codec_remove(struct platform_device *pdev)
@@ -2404,9 +2380,6 @@ static void sun4i_codec_remove(struct platform_device *pdev)
 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
 
 	snd_soc_unregister_card(card);
-	if (scodec->rst)
-		reset_control_assert(scodec->rst);
-	clk_disable_unprepare(scodec->clk_apb);
 }
 
 static struct platform_driver sun4i_codec_driver = {
-- 
2.34.1




From will at kernel.org  Wed Dec 11 14:30:35 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 22:30:35 +0000
Subject: [RFC PATCH 0/3] arm64: support FEAT_BBM level 2 and large block
 mapping when rodata=full
In-Reply-To: <414b3388-c2e5-45ae-9f1d-c35310fdbf8b@os.amperecomputing.com>
References: <20241118181711.962576-1-yang@os.amperecomputing.com>
 <20241210113151.GC14735@willie-the-truck>
 <414b3388-c2e5-45ae-9f1d-c35310fdbf8b@os.amperecomputing.com>
Message-ID: <20241211223034.GA17836@willie-the-truck>

Hey,

On Tue, Dec 10, 2024 at 11:33:16AM -0800, Yang Shi wrote:
> On 12/10/24 3:31 AM, Will Deacon wrote:
> > On Mon, Nov 18, 2024 at 10:16:07AM -0800, Yang Shi wrote:
> > > When rodata=full kernel linear mapping is mapped by PTE due to arm's
> > > break-before-make rule.
> > > 
> > > This resulted in a couple of problems:
> > >    - performance degradation
> > >    - more TLB pressure
> > >    - memory waste for kernel page table
> > > 
> > > There are some workarounds to mitigate the problems, for example, using
> > > rodata=on, but this compromises the security measurement.
> > > 
> > > With FEAT_BBM level 2 support, splitting large block page table to
> > > smaller ones doesn't need to make the page table entry invalid anymore.
> > > This allows kernel split large block mapping on the fly.
> > I think you can still get TLB conflict aborts in this case, so this
> > doesn't work. Hopefully the architecture can strengthen this in the
> > future to give you what you need.
> 
> Thanks for responding. This is a little bit surprising. I thought FEAT_BBM
> level 2 can handle the TLB conflict gracefully. At least its description
> made me assume so. And Catalin also mentioned FEAT_BBM level 2 can be used
> to split vmemmap page table in HVO patch discussion
> (https://lore.kernel.org/all/Zo68DP6siXfb6ZBR at arm.com/).
> 
> It sounds a little bit contradicting if the TLB conflict still can happen
> with FEAT_BBM level 2. It makes the benefit of FEAT_BBM level 2 much less
> than expected.

You can read the Arm ARM just as badly as I can :)

 | I_HYQMB
 |
 | If any level is supported and the TLB entries are not invalidated after
 | the writes that modified the translation table entries are completed,
 | then a TLB conflict abort can be generated because in a TLB there might
 | be multiple translation table entries that all translate the same IA.

Note *any level*.

Furthermore:

 | R_FWRMB
 |
 | If all of the following apply, then a TLB conflict abort is reported
 | to EL2:
 | * Level 1 or level 2 is supported.
 | * Stage 2 translations are enabled in the current translation regime.
 | * A TLB conflict abort is generated due to changing the block size or
 |   Contiguous bit.

I think this series is trying to handle some of this:

https://lore.kernel.org/r/20241211154611.40395-1-miko.lenczewski at arm.com

> Is it out of question to handle the TLB conflict aborts? IIUC we should just
> need flush TLB then resume, and it doesn't require to hold any locks as
> well.

See my reply here:

https://lore.kernel.org/r/20241211210243.GA17155 at willie-the-truck

> And I chatted with our architects, I was told the TLB conflict abort doesn't
> happen on AmpereOne. Maybe this is why I didn't see the problem when I
> tested the patches.

I'm actually open to having an MIDR-based lookup for this if its your own
micro-architecture.

Will


From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:32:49 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:32:49 +0000
Subject: [PATCH v2 0/8] Refactor cpuid and metric table lookup code
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <173395636900.1729195.10506266683827384224.git-patchwork-notify@kernel.org>

Hello:

This series was applied to riscv/linux.git (fixes)
by Arnaldo Carvalho de Melo <acme at redhat.com>:

On Thu,  7 Nov 2024 08:20:27 -0800 you wrote:
> Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
> lookup:
> https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
> These patches remove a lot of the logic relating CPUIDs to PMUs so
> that the PMU isn't part of the question when finding a metric table.
> For time reasons, it doesn't go as far as allowing system metrics
> without a metric table as a metric table is needed for metrics to
> refer to other metrics, and the refactoring of that resolution is a
> hassle.
> 
> [...]

Here is the summary with links:
  - [v2,1/8] perf jevents: fix breakage when do perf stat on system metric
    https://git.kernel.org/riscv/c/4a159e6049f3
  - [v2,2/8] perf header: Move is_cpu_online to numa bench
    https://git.kernel.org/riscv/c/c6fafe36bab3
  - [v2,3/8] perf header: Refactor get_cpuid to take a CPU for ARM
    https://git.kernel.org/riscv/c/cec0d6572a44
  - [v2,4/8] perf arm64 header: Use cpu argument in get_cpuid
    https://git.kernel.org/riscv/c/538737da9625
  - [v2,5/8] perf header: Avoid transitive PMU includes
    https://git.kernel.org/riscv/c/7463ee17a740
  - [v2,6/8] perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
    https://git.kernel.org/riscv/c/494c403ff159
  - [v2,7/8] perf jevents: Add map_for_cpu
    https://git.kernel.org/riscv/c/0434410fa45c
  - [v2,8/8] perf pmu: Move pmu_metrics_table__find and remove ARM override
    https://git.kernel.org/riscv/c/8f997865ee9e

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:32:57 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:32:57 +0000
Subject: [PATCH v1] dma: fix typo in the comment
In-Reply-To: <20240918034114.860132-1-yanzhen@vivo.com>
References: <20240918034114.860132-1-yanzhen@vivo.com>
Message-ID: <173395637749.1729195.15051372994717315610.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Vinod Koul <vkoul at kernel.org>:

On Wed, 18 Sep 2024 11:41:14 +0800 you wrote:
> Correctly spelled comments make it easier for the reader to understand
> the code.
> 
> Replace 'enngine' with 'engine' in the comment &
> replace 'trascatioin' with 'transaction' in the comment &
> replace 'descripter' with 'descriptor' in the comment &
> replace 'descritpor' with 'descriptor' in the comment &
> replace 'rgisters' with 'registers' in the comment.
> 
> [...]

Here is the summary with links:
  - [v1] dma: fix typo in the comment
    https://git.kernel.org/riscv/c/39d283d14692

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:32:30 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:32:30 +0000
Subject: [PATCH v4 00/20] Remove PERF_HAVE_DWARF_REGS
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <173395635051.1729195.13191557882673334015.git-patchwork-notify@kernel.org>

Hello:

This series was applied to riscv/linux.git (fixes)
by Namhyung Kim <namhyung at kernel.org>:

On Fri,  8 Nov 2024 15:45:45 -0800 you wrote:
> These changes were originally on top of:
> https://lore.kernel.org/lkml/20241017001354.56973-1-irogers at google.com/
> 
> Prior to these patches PERF_HAVE_DWARF_REGS indicated the presence of
> dwarf-regs.c in the arch directory. dwarf-regs.c provided upto 4
> functions:
> 
> [...]

Here is the summary with links:
  - [v4,01/20] perf bpf-prologue: Remove unused file
    https://git.kernel.org/riscv/c/2bf7692eadc5
  - [v4,02/20] perf dwarf-regs: Remove PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
    https://git.kernel.org/riscv/c/6ac75289b288
  - [v4,03/20] perf dwarf-regs: Add EM_HOST and EF_HOST defines
    https://git.kernel.org/riscv/c/ae894b77923e
  - [v4,04/20] perf disasm: Add e_machine/e_flags to struct arch
    https://git.kernel.org/riscv/c/cd6c9dca9d4b
  - [v4,05/20] perf dwarf-regs: Pass accurate disassembly machine to get_dwarf_regnum
    https://git.kernel.org/riscv/c/9fc4489a16f4
  - [v4,06/20] perf dwarf-regs: Pass ELF flags to get_dwarf_regstr
    https://git.kernel.org/riscv/c/a784847c2da1
  - [v4,07/20] perf dwarf-regs: Move x86 dwarf-regs out of arch
    https://git.kernel.org/riscv/c/bf4e799a0a33
  - [v4,08/20] perf arm64: Remove dwarf-regs.c
    https://git.kernel.org/riscv/c/6f8e8add5a0a
  - [v4,09/20] perf arm: Remove dwarf-regs.c
    https://git.kernel.org/riscv/c/0c0a20ecdf67
  - [v4,10/20] perf dwarf-regs: Move csky dwarf-regs out of arch
    https://git.kernel.org/riscv/c/d4a0c4f22121
  - [v4,11/20] perf loongarch: Remove dwarf-regs.c
    https://git.kernel.org/riscv/c/1d37bd8366d8
  - [v4,12/20] perf mips: Remove dwarf-regs.c
    https://git.kernel.org/riscv/c/8a768a2f6592
  - [v4,13/20] perf dwarf-regs: Move powerpc dwarf-regs out of arch
    https://git.kernel.org/riscv/c/285b523c2da2
  - [v4,14/20] perf riscv: Remove dwarf-regs.c and add dwarf-regs-table.h
    https://git.kernel.org/riscv/c/a90c4519186d
  - [v4,15/20] perf s390: Remove dwarf-regs.c
    https://git.kernel.org/riscv/c/b232b704a781
  - [v4,16/20] perf sh: Remove dwarf-regs.c
    https://git.kernel.org/riscv/c/04150f29e212
  - [v4,17/20] perf sparc: Remove dwarf-regs.c
    https://git.kernel.org/riscv/c/85567a2a8d42
  - [v4,18/20] perf xtensa: Remove dwarf-regs.c
    https://git.kernel.org/riscv/c/a4747c09507d
  - [v4,19/20] perf dwarf-regs: Remove get_arch_regstr code
    https://git.kernel.org/riscv/c/3ef6b89a129a
  - [v4,20/20] perf build: Remove PERF_HAVE_DWARF_REGS
    https://git.kernel.org/riscv/c/ddbfb6f20c1b

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:32:44 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:32:44 +0000
Subject: [PATCH 1/2] asm-generic: provide generic page_to_phys and
 phys_to_page implementations
In-Reply-To: <20241023053644.311692-2-hch@lst.de>
References: <20241023053644.311692-2-hch@lst.de>
Message-ID: <173395636448.1729195.13128530873311699126.git-patchwork-notify@kernel.org>

Hello:

This series was applied to riscv/linux.git (fixes)
by Arnd Bergmann <arnd at arndb.de>:

On Wed, 23 Oct 2024 07:36:36 +0200 you wrote:
> page_to_phys is duplicated by all architectures, and from some strange
> reason placed in <asm/io.h> where it doesn't fit at all.
> 
> phys_to_page is only provided by a few architectures despite having a lot
> of open coded users.
> 
> Provide generic versions in <asm-generic/memory_model.h> to make these
> helpers more easily usable.
> 
> [...]

Here is the summary with links:
  - [1/2] asm-generic: provide generic page_to_phys and phys_to_page implementations
    https://git.kernel.org/riscv/c/c5c3238d9b8c
  - [2/2] asm-generic: add an optional pfn_valid check to page_to_phys
    https://git.kernel.org/riscv/c/3e25d5a49f99

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:32:46 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:32:46 +0000
Subject: [PATCH] kernel/irq/proc: performance: replace seq_printf with
 seq_put_decimal_ull_width
In-Reply-To: <20241103080552.4787-1-00107082@163.com>
References: <20241103080552.4787-1-00107082@163.com>
Message-ID: <173395636600.1729195.17930169527159894833.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Michael Ellerman <mpe at ellerman.id.au>:

On Sun,  3 Nov 2024 16:05:52 +0800 you wrote:
> seq_printf is costy, when stress reading /proc/interrupts, profiling indicates
> seq_printf takes about ~47% of show_interrupts samples:
> 
>     show_interrupts(94.495% 5166019/5466991)
> 	seq_printf(47.429% 2450210/5166019)
> 	    vsnprintf(89.232% 2186366/2450210)
> 		format_decode(24.005% 524831/2186366)
> 		number(19.488% 426084/2186366)
> 		memcpy_orig(3.739% 81753/2186366)
> 		...
> 	_raw_spin_unlock_irqrestore(26.643% 1376379/5166019)
> 	mtree_load(8.059% 416304/5166019)
> 
> [...]

Here is the summary with links:
  - kernel/irq/proc: performance: replace seq_printf with seq_put_decimal_ull_width
    https://git.kernel.org/riscv/c/5b881c1f8379

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:32:47 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:32:47 +0000
Subject: [PATCH v2] of/fdt: add dt_phys arg to early_init_dt_scan and
 early_init_dt_verify
In-Reply-To: <20241023171426.452688-1-usamaarif642@gmail.com>
References: <20241023171426.452688-1-usamaarif642@gmail.com>
Message-ID: <173395636750.1729195.6853192666319119853.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Rob Herring (Arm) <robh at kernel.org>:

On Wed, 23 Oct 2024 18:14:26 +0100 you wrote:
> __pa() is only intended to be used for linear map addresses and using
> it for initial_boot_params which is in fixmap for arm64 will give an
> incorrect value. Hence save the physical address when it is known at
> boot time when calling early_init_dt_scan for arm64 and use it at kexec
> time instead of converting the virtual address using __pa().
> 
> Reported-by: Breno Leitao <leitao at debian.org>
> Suggested-by: Mark Rutland <mark.rutland at arm.com>
> Signed-off-by: Usama Arif <usamaarif642 at gmail.com>
> Fixes: ac10be5cdbfa ("arm64: Use common of_kexec_alloc_and_setup_fdt()")
> 
> [...]

Here is the summary with links:
  - [v2] of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify
    https://git.kernel.org/riscv/c/b2473a359763

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:33:06 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:33:06 +0000
Subject: [PATCH] firmware: Switch back to struct platform_driver::remove()
In-Reply-To: <36974feb6035201d53384557259ec72fe311053b.1731397962.git.u.kleine-koenig@baylibre.com>
References: <36974feb6035201d53384557259ec72fe311053b.1731397962.git.u.kleine-koenig@baylibre.com>
Message-ID: <173395638610.1729195.7835904976463124425.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Greg Kroah-Hartman <gregkh at linuxfoundation.org>:

On Tue, 12 Nov 2024 09:35:20 +0100 you wrote:
> After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
> return void") .remove() is (again) the right callback to implement for
> platform drivers.
> 
> Convert all platform drivers below drivers/firmware to use .remove(),
> with the eventual goal to drop struct platform_driver::remove_new(). As
> .remove() and .remove_new() have the same prototypes, conversion is done
> by just changing the structure member name in the driver initializer.
> 
> [...]

Here is the summary with links:
  - firmware: Switch back to struct platform_driver::remove()
    https://git.kernel.org/riscv/c/5770e9f237b6

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:33:22 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:33:22 +0000
Subject: [PATCH v4] ACPI: introduce acpi_arch_init
In-Reply-To: <20241121-intro-acpi-arch-init-v4-1-b1fb517e7d8b@gmail.com>
References: <20241121-intro-acpi-arch-init-v4-1-b1fb517e7d8b@gmail.com>
Message-ID: <173395640299.1729195.506901103763287454.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Rafael J. Wysocki <rafael.j.wysocki at intel.com>:

On Thu, 21 Nov 2024 22:25:21 +0800 you wrote:
> From: Miao Wang <shankerwangmiao at gmail.com>
> 
> To avoid arch-specific code in general ACPI initialization flow,
> we introduce a weak symbol acpi_arch_init. Currently, arm64 and
> riscv can utillize this to insert their arch-specific flow. In
> the future, other architectures can also have chance to define
> their own arch-specific acpi initialization process if necessary.
> 
> [...]

Here is the summary with links:
  - [v4] ACPI: introduce acpi_arch_init
    https://git.kernel.org/riscv/c/9d8a2b033db1

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From will at kernel.org  Wed Dec 11 14:40:15 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 22:40:15 +0000
Subject: [PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <b859bdcd-7343-4d53-9f3a-f374deca725a@sirena.org.uk>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
 <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>
 <20241210170953.GB16075@willie-the-truck>
 <b859bdcd-7343-4d53-9f3a-f374deca725a@sirena.org.uk>
Message-ID: <20241211224015.GB17836@willie-the-truck>

On Tue, Dec 10, 2024 at 06:43:05PM +0000, Mark Brown wrote:
> On Tue, Dec 10, 2024 at 05:09:55PM +0000, Will Deacon wrote:
> 
> > Can we _please_ just generate this stuff. It feels like we've been
> > making silly typos over and over again with the current approach so
> > either it's hard or we're not very good at it. Either way, it should be
> > automated.
> 
> > Others have managed it [1], so it's clearly do-able.
> 
> Yes, the issues here are not technical ones.  Though there are some
> complications -  eg, IIRC the XML doesn't encode the signedness of
> fields like we do and there's areas where we've deliberately diverged.
> Given the amount of review I end up having to do of sysreg changes your
> reasoning is especially apparent to me.  I've passed this feedback on
> (again).

One thing we _could_ do is have a tool (in-tree) that takes two copies
of the sysreg file (i.e. before and after applying a diff) along with a
copy of the XML and, for the the new fields being added, shows how the
XML represents those compared to the diff. It should then be relatively
straightforward to flag the use of an unallocated encoding (like we had
here) and also things like assigning a field name to a RES0 region.

So this wouldn't be generating the patches from the XML, but more like
using the XML as an oracle in a linter.

Will


From lkp at intel.com  Wed Dec 11 14:39:54 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Dec 2024 06:39:54 +0800
Subject: [PATCH v2 6/8] soc: mediatek: Add programming flow for
 unsupported subsys ID hardware
In-Reply-To: <20241211032256.28494-7-jason-jh.lin@mediatek.com>
References: <20241211032256.28494-7-jason-jh.lin@mediatek.com>
Message-ID: <202412120643.qzGYgONG-lkp@intel.com>

Hi Jason-JH.Lin,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.13-rc2 next-20241211]
[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/Jason-JH-Lin/dt-bindings-mailbox-mediatek-Add-GCE-header-file-for-MT8196/20241211-112605
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20241211032256.28494-7-jason-jh.lin%40mediatek.com
patch subject: [PATCH v2 6/8] soc: mediatek: Add programming flow for unsupported subsys ID hardware
config: sparc-randconfig-001-20241212 (https://download.01.org/0day-ci/archive/20241212/202412120643.qzGYgONG-lkp at intel.com/config)
compiler: sparc-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241212/202412120643.qzGYgONG-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/202412120643.qzGYgONG-lkp at intel.com/

All errors (new ones prefixed by >>):

   sparc-linux-ld: drivers/soc/mediatek/mtk-mmsys.o: in function `mtk_mmsys_update_bits':
>> drivers/soc/mediatek/mtk-mmsys.c:173:(.text+0x6c): undefined reference to `cmdq_subsys_is_valid'
   sparc-linux-ld: drivers/soc/mediatek/mtk-mutex.o: in function `mtk_mutex_enable_by_cmdq':
>> drivers/soc/mediatek/mtk-mutex.c:976:(.text+0x48c): undefined reference to `cmdq_subsys_is_valid'


vim +173 drivers/soc/mediatek/mtk-mmsys.c

   162	
   163	static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, u32 val,
   164					  struct cmdq_pkt *cmdq_pkt)
   165	{
   166		int ret;
   167		u32 tmp;
   168	
   169		if (mmsys->cmdq_base.size && cmdq_pkt) {
   170			struct cmdq_client *cl = (struct cmdq_client *)cmdq_pkt->cl;
   171	
   172			offset += mmsys->cmdq_base.offset;
 > 173			if (cmdq_subsys_is_valid(cl->chan, mmsys->cmdq_base.subsys)) {
   174				ret = cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
   175							  offset, val, mask);
   176			} else {
   177				/* only MMIO access, no need to check mminfro_offset */
   178				ret = cmdq_pkt_assign(cmdq_pkt, 0,
   179						      CMDQ_ADDR_HIGH(mmsys->cmdq_base.pa_base));
   180				ret |= cmdq_pkt_write_s_mask_value(cmdq_pkt, 0,
   181								   CMDQ_ADDR_LOW(offset), val, mask);
   182			}
   183			if (ret)
   184				pr_debug("CMDQ unavailable: using CPU write\n");
   185			else
   186				return;
   187		}
   188		tmp = readl_relaxed(mmsys->regs + offset);
   189		tmp = (tmp & ~mask) | (val & mask);
   190		writel_relaxed(tmp, mmsys->regs + offset);
   191	}
   192	

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


From heiko at sntech.de  Wed Dec 11 14:45:40 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 11 Dec 2024 23:45:40 +0100
Subject: [PATCH] drm/rockchip: Remove unnecessary checking
In-Reply-To: <20241206114233.1270989-1-guoqing.jiang@canonical.com>
References: <20241206114233.1270989-1-guoqing.jiang@canonical.com>
Message-ID: <173395708760.2509957.4198864245551096465.b4-ty@sntech.de>


On Fri, 06 Dec 2024 19:42:33 +0800, Guoqing Jiang wrote:
> It is not needed since drm_atomic_helper_shutdown checks it.
> 
> 

Applied, thanks!

[1/1] drm/rockchip: Remove unnecessary checking
      commit: 8ddc8dfb8329349d5efb0418c9f20025333e2d98

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Wed Dec 11 14:45:41 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 11 Dec 2024 23:45:41 +0100
Subject: [PATCH drm-misc-next] rockchip/drm: vop2: don't check color_mgmt_changed in atomic_enable
In-Reply-To: <20241206192013.342692-3-pZ010001011111@proton.me>
References: <20241206192013.342692-3-pZ010001011111@proton.me>
Message-ID: <173395708760.2509957.1013367330408721282.b4-ty@sntech.de>


On Fri, 06 Dec 2024 19:26:10 +0000, Piotr Zalewski wrote:
> Remove color_mgmt_changed check from vop2_crtc_atomic_try_set_gamma to
> allow gamma LUT rewrite during modeset when coming out of suspend. Add
> a check for color_mgmt_changed directly in vop2_crtc_atomic_flush.
> 
> This patch fixes the patch adding gamma LUT support for vop2 [1].
> 
> [1] https://lore.kernel.org/linux-rockchip/20241101185545.559090-3-pZ010001011111 at proton.me/
> 
> [...]

Applied, thanks!

[1/1] rockchip/drm: vop2: don't check color_mgmt_changed in atomic_enable
      commit: 9c22b6ece2e5c2308f41ba4bec27cfa158397fa7

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:33:10 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:33:10 +0000
Subject: [PATCH v3] ftrace: Consolidate ftrace_regs accessor functions for
 archs using pt_regs
In-Reply-To: <20241010202114.2289f6fd@gandalf.local.home>
References: <20241010202114.2289f6fd@gandalf.local.home>
Message-ID: <173395639050.1729195.18342749493985130890.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Steven Rostedt (Google) <rostedt at goodmis.org>:

On Thu, 10 Oct 2024 20:21:14 -0400 you wrote:
> From: Steven Rostedt <rostedt at goodmis.org>
> 
> Most architectures use pt_regs within ftrace_regs making a lot of the
> accessor functions just calls to the pt_regs internally. Instead of
> duplication this effort, use a HAVE_ARCH_FTRACE_REGS for architectures
> that have their own ftrace_regs that is not based on pt_regs and will
> define all the accessor functions, and for the architectures that just use
> pt_regs, it will leave it undefined, and the default accessor functions
> will be used.
> 
> [...]

Here is the summary with links:
  - [v3] ftrace: Consolidate ftrace_regs accessor functions for archs using pt_regs
    https://git.kernel.org/riscv/c/e4cf33ca4812

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:33:17 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:33:17 +0000
Subject: [PATCH v2 0/2] ftrace: Make ftrace_regs abstract and consolidate code
In-Reply-To: <20241008230527.674939311@goodmis.org>
References: <20241008230527.674939311@goodmis.org>
Message-ID: <173395639774.1729195.5975449690225774291.git-patchwork-notify@kernel.org>

Hello:

This series was applied to riscv/linux.git (fixes)
by Steven Rostedt (Google) <rostedt at goodmis.org>:

On Tue, 08 Oct 2024 19:05:27 -0400 you wrote:
> This is based on:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git/
>      ftrace/for-next
> 
> ftrace_regs was created to hold registers that store information to save
> function parameters, return value and stack. Since it is a subset of
> pt_regs, it should only be used by its accessor functions. But because
> pt_regs can easily be taken from ftrace_regs (on most archs), it is
> tempting to use it directly. But when running on other architectures, it
> may fail to build or worse, build but crash the kernel!
> 
> [...]

Here is the summary with links:
  - [v2,1/2] ftrace: Make ftrace_regs abstract from direct use
    https://git.kernel.org/riscv/c/7888af4166d4
  - [v2,2/2] ftrace: Consolidate ftrace_regs accessor functions for archs using pt_regs
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Dec 11 14:33:12 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 11 Dec 2024 22:33:12 +0000
Subject: [PATCH 00/28] vdso: Preparations for generic data storage
In-Reply-To: <20241010-vdso-generic-base-v1-0-b64f0842d512@linutronix.de>
References: <20241010-vdso-generic-base-v1-0-b64f0842d512@linutronix.de>
Message-ID: <173395639200.1729195.15576952837564128066.git-patchwork-notify@kernel.org>

Hello:

This series was applied to riscv/linux.git (fixes)
by Thomas Gleixner <tglx at linutronix.de>:

On Thu, 10 Oct 2024 09:01:02 +0200 you wrote:
> Historically each architecture defined their own datapage to store the
> VDSO data. This stands in contrast to the generic nature of the VDSO
> code itself.
> We plan to introduce a generic framework for the management of the VDSO
> data storage that can be used by all architectures and which works
> together with the existing generic VDSO code.
> 
> [...]

Here is the summary with links:
  - [01/28] csky/vdso: Remove gettimeofday() and friends from VDSO
    (no matching commit)
  - [02/28] csky/vdso: Remove arch_vma_name()
    (no matching commit)
  - [03/28] s390/vdso: Drop LBASE_VDSO
    (no matching commit)
  - [04/28] arm64: vdso: Drop LBASE_VDSO
    (no matching commit)
  - [05/28] arm64: vdso: Use only one single vvar mapping
    (no matching commit)
  - [06/28] riscv: vdso: Use only one single vvar mapping
    https://git.kernel.org/riscv/c/d34b60752fcb
  - [07/28] arm: vdso: Remove assembly for datapage access
    (no matching commit)
  - [08/28] LoongArch: vDSO: Use vdso/datapage.h to access vDSO data
    (no matching commit)
  - [09/28] MIPS: vdso: Avoid name conflict around "vdso_data"
    (no matching commit)
  - [10/28] x86/mm/mmap: Remove arch_vma_name()
    (no matching commit)
  - [11/28] x86: vdso: Use __arch_get_vdso_data() to access vdso data
    (no matching commit)
  - [12/28] x86: vdso: Place vdso_data at beginning of vvar page
    (no matching commit)
  - [13/28] x86: vdso: Access rng data from kernel without vvar
    (no matching commit)
  - [14/28] x86: vdso: Allocate vvar page from C code
    (no matching commit)
  - [15/28] x86: vdso: Access timens vdso data without vvar.h
    (no matching commit)
  - [16/28] x86: vdso: Access rng vdso data without vvar.h
    (no matching commit)
  - [17/28] x86: vdso: Move the rng offset to vsyscall.h
    (no matching commit)
  - [18/28] x86: vdso: Access vdso data without vvar.h
    (no matching commit)
  - [19/28] x86: vdso: Delete vvar.h
    (no matching commit)
  - [20/28] x86: vdso: Split virtual clock pages into dedicated mapping
    (no matching commit)
  - [21/28] powerpc: vdso: Remove offset comment from 32bit vdso_arch_data
    (no matching commit)
  - [22/28] powerpc: procfs: Propagate error of remap_pfn_range()
    (no matching commit)
  - [23/28] powerpc/pseries/lparcfg: Fix printing of system_active_processors
    (no matching commit)
  - [24/28] powerpc/pseries/lparcfg: Use num_possible_cpus() for potential processors
    (no matching commit)
  - [25/28] powerpc: Add kconfig option for the systemcfg page
    (no matching commit)
  - [26/28] powerpc: Split systemcfg data out of vdso data page
    (no matching commit)
  - [27/28] powerpc: Split systemcfg struct definitions out from vdso
    (no matching commit)
  - [28/28] vdso: Rename struct arch_vdso_data to arch_vdso_time_data
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From heiko at sntech.de  Wed Dec 11 14:45:39 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 11 Dec 2024 23:45:39 +0100
Subject: [PATCH] drm/rockchip: dw_hdmi_qp: Simplify clock handling
In-Reply-To: <20241202-dw-hdmi-qp-rk-clk-bulk-v1-1-60a7cc9cd74e@collabora.com>
References: <20241202-dw-hdmi-qp-rk-clk-bulk-v1-1-60a7cc9cd74e@collabora.com>
Message-ID: <173395708761.2509957.6810456712864653104.b4-ty@sntech.de>


On Mon, 02 Dec 2024 22:27:34 +0200, Cristian Ciocaltea wrote:
> Make use of the recently introduced devm_clk_bulk_get_all_enabled()
> helper to simplify the code a bit.
> 
> 

Applied, thanks!

[1/1] drm/rockchip: dw_hdmi_qp: Simplify clock handling
      commit: 19851fa2ba9824bede16f55234f63d9423897c3d

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From will at kernel.org  Wed Dec 11 14:59:32 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 22:59:32 +0000
Subject: [PATCH RESEND kvmtool 0/4] arm: Payload memory layout change
In-Reply-To: <20241128151246.10858-1-alexandru.elisei@arm.com>
References: <20241128151246.10858-1-alexandru.elisei@arm.com>
Message-ID: <20241211225931.GC17836@willie-the-truck>

On Thu, Nov 28, 2024 at 03:12:42PM +0000, Alexandru Elisei wrote:
> (resending because I accidently only sent the cover letter, sorry for that)
> 
> The first 3 patches are fixes to kvm__arch_load_kernel_image(). I've CC'ed
> the riscv maintainer because it looks to me like riscv is similarly
> affected.
> 
> Patch #4 ("arm64: Increase the payload memory region size to 512MB") might
> be controversial. Follows a bug report I received from Abdollahi Sina in
> private. Details in the commit message, but the gist of the patch is that
> the memory region where kernel + initrd + DTB are copied to are changed
> from 256MB to 512MB.  As a result, the DTB and initrd are moved from below
> ram_start + 256MB to ram_start + 512MB to accomodate a larger initrd.  If
> users rely on finding the DTB and initrd at the current addresses, then I'm
> not sure the patch is justified - after all, if someone really wants to use
> such a large initrd instead of a disk image with virtio, then replacing
> SZ_256M with SZ_512M locally doesn't look like a big ask.
> 
> On the other hand, if there are no users that rely on the current payload
> layout, increasing the memory region size to 512MB to allow for more
> unusual use cases, while still maintaining compatibility with older
> kernels, doesn't seem unreasonable to me.
> 
> Please comment, I don't feel strongly either way - I'll happy drop the last
> patch if there are objections.

Well, I won't reject an imperial.ac.uk patch on a hunch, so let's go for
the whole lot and see if anybody complains!

I'll fix the indentation issue spotted by Drew when applying (thanks!).

Will


From dmitry.baryshkov at linaro.org  Wed Dec 11 15:04:05 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 12 Dec 2024 01:04:05 +0200
Subject: [PATCH v5 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <519cc025-0782-4f96-a169-1fe87b280173@norik.com>
References: <20241210091901.83028-1-andrej.picej@norik.com>
 <20241210091901.83028-3-andrej.picej@norik.com>
 <irpmhq7vxjra6vhmdh7p63ajj57n3h2c4br3ija2jmwtoewist@zyxfmx6k5m4e>
 <aa2de99d-21f4-4843-83b7-5d2db78be86f@norik.com>
 <qhmsobin3fsmoc7ic2jtancowfscoauyroruxdpwhmqwlogtkz@6by3s2ruwzwp>
 <519cc025-0782-4f96-a169-1fe87b280173@norik.com>
Message-ID: <rputm4gnjj6nb66ix7dqbxr2janltia6rlb6zunhf7x3mgooxw@o3lblnyp5cci>

On Wed, Dec 11, 2024 at 08:57:17AM +0100, Andrej Picej wrote:
> 
> 
> On 10. 12. 24 14:59, Dmitry Baryshkov wrote:
> > On Tue, Dec 10, 2024 at 02:41:01PM +0100, Andrej Picej wrote:
> > > 
> > > 
> > > On 10. 12. 24 12:43, Dmitry Baryshkov wrote:
> > > > On Tue, Dec 10, 2024 at 10:19:00AM +0100, Andrej Picej wrote:
> > > > > Add a optional properties to change LVDS output voltage. This should not
> > > > > be static as this depends mainly on the connected display voltage
> > > > > requirement. We have three properties:
> > > > > - "ti,lvds-termination-ohms", which sets near end termination,
> > > > > - "ti,lvds-vod-swing-data-microvolt" and
> > > > > - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> > > > > output voltage for data and clock lanes. They are defined as an array
> > > > > with min and max values. The appropriate bitfield will be set if
> > > > > selected constraints can be met.
> > > > > 
> > > > > If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> > > > > end termination will be used. Selecting only one:
> > > > > "ti,lvds-vod-swing-data-microvolt" or
> > > > > "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> > > > > constraint for only data/clock lanes will be met. Setting both is
> > > > > recommended.
> > > > > 
> > > > > Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> > > > > ---
> > > > > Changes in v5:
> > > > > - specify default values in sn65dsi83_parse_lvds_endpoint,
> > > > > - move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
> > > > > Changes in v4:
> > > > > - fix typo in commit message bitfiled -> bitfield
> > > > > - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
> > > > > of separate variables for channel A/B
> > > > > - add more checks on return value of "of_property_read_u32_array"
> > > > > Changes in v3:
> > > > > - use microvolts for default array values 1000 mV -> 1000000 uV.
> > > > > Changes in v2:
> > > > > - use datasheet tables to get the proper configuration
> > > > > - since major change was done change the authorship to myself
> > > > > ---
> > > > >    drivers/gpu/drm/bridge/ti-sn65dsi83.c | 142 +++++++++++++++++++++++++-
> > > > >    1 file changed, 139 insertions(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > > > index 57a7ed13f996..f9578b38da28 100644
> > > > > --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > > > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > > > @@ -132,6 +132,16 @@
> > > > >    #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
> > > > >    #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
> > > > > +enum sn65dsi83_channel {
> > > > > +	CHANNEL_A,
> > > > > +	CHANNEL_B
> > > > > +};
> > > > > +
> > > > > +enum sn65dsi83_lvds_term {
> > > > > +	OHM_100,
> > > > > +	OHM_200
> > > > > +};
> > > > > +
> > > > >    enum sn65dsi83_model {
> > > > >    	MODEL_SN65DSI83,
> > > > >    	MODEL_SN65DSI84,
> > > > > @@ -147,6 +157,8 @@ struct sn65dsi83 {
> > > > >    	struct regulator		*vcc;
> > > > >    	bool				lvds_dual_link;
> > > > >    	bool				lvds_dual_link_even_odd_swap;
> > > > > +	int				lvds_vod_swing_conf[2];
> > > > > +	int				lvds_term_conf[2];
> > > > >    };
> > > > >    static const struct regmap_range sn65dsi83_readable_ranges[] = {
> > > > > @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
> > > > >    	.max_register = REG_IRQ_STAT,
> > > > >    };
> > > > > +static const int lvds_vod_swing_data_table[2][4][2] = {
> > > > > +	{	/* 100 Ohm */
> > > > > +		{ 180000, 313000 },
> > > > > +		{ 215000, 372000 },
> > > > > +		{ 250000, 430000 },
> > > > > +		{ 290000, 488000 },
> > > > > +	},
> > > > > +	{	/* 200 Ohm */
> > > > > +		{ 150000, 261000 },
> > > > > +		{ 200000, 346000 },
> > > > > +		{ 250000, 428000 },
> > > > > +		{ 300000, 511000 },
> > > > > +	},
> > > > > +};
> > > > > +
> > > > > +static const int lvds_vod_swing_clock_table[2][4][2] = {
> > > > > +	{	/* 100 Ohm */
> > > > > +		{ 140000, 244000 },
> > > > > +		{ 168000, 290000 },
> > > > > +		{ 195000, 335000 },
> > > > > +		{ 226000, 381000 },
> > > > > +	},
> > > > > +	{	/* 200 Ohm */
> > > > > +		{ 117000, 204000 },
> > > > > +		{ 156000, 270000 },
> > > > > +		{ 195000, 334000 },
> > > > > +		{ 234000, 399000 },
> > > > > +	},
> > > > > +};
> > > > > +
> > > > >    static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
> > > > >    {
> > > > >    	return container_of(bridge, struct sn65dsi83, bridge);
> > > > > @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
> > > > >    		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
> > > > >    	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
> > > > > -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
> > > > > +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
> > > > > +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
> > > > > +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
> > > > >    	regmap_write(ctx->regmap, REG_LVDS_LANE,
> > > > >    		     (ctx->lvds_dual_link_even_odd_swap ?
> > > > >    		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
> > > > > -		     REG_LVDS_LANE_CHA_LVDS_TERM |
> > > > > -		     REG_LVDS_LANE_CHB_LVDS_TERM);
> > > > > +		     (ctx->lvds_term_conf[CHANNEL_A] ?
> > > > > +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
> > > > > +		     (ctx->lvds_term_conf[CHANNEL_B] ?
> > > > > +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
> > > > >    	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
> > > > >    	le16val = cpu_to_le16(mode->hdisplay);
> > > > > @@ -576,10 +622,100 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
> > > > >    	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
> > > > >    };
> > > > > +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
> > > > > +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
> > > > > +{
> > > > > +	int i;
> > > > > +
> > > > > +	for (i = 0; i <= 3; i++) {
> > > > > +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
> > > > > +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
> > > > > +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> > > > > +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
> > > > > +			return i;
> > > > > +	}
> > > > > +
> > > > > +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
> > > > > +	return -EINVAL;
> > > > > +}
> > > > > +
> > > > > +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> > > > > +{
> > > > > +	struct device *dev = ctx->dev;
> > > > > +	struct device_node *endpoint;
> > > > > +	int endpoint_reg;
> > > > > +	/* Set so the property can be freely selected if not defined */
> > > > > +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
> > > > > +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
> > > > > +	u32 lvds_term;
> > > > > +	u8 lvds_term_conf = 0x1;
> > > > > +	int lvds_vod_swing_conf = 0x1;
> > > > 
> > > > Magic values
> > > 
> > > Can you please elaborate.
> > > 
> > > I can use:
> > > u8 lvds_term_conf = OHM_200;
> > > 
> > > What about lvds_vod_swing_conf? Should I create additional define for it?
> > > But this doesn't solve a hidden meaning? Maybe additional comment above?
> > > Would like to avoid using voltages for it, since then we are reverse
> > > engineering the table in datasheet to match the default reg value.
> > 
> > I think the following example solves both problems:
> > 
> > lvds_term = 200;
> > of_property_read_u32(..., &lvds_term);
> > 
> > if (lvds_term == 100)
> > 	ctx->lvds_term_conf[channel] = OHM_100;
> > else if (lvds_term == 200)
> > 	ctx->lvds_term_conf[channel] = OHM_200;
> > else
> > 	return -EINVAL;
> > 
> > The same approach can be applied to lvds_vod_swing_conf, resulting in
> > removal of magic values.
> 
> Sorry, but I think it is not that easy when it comes to the
> lvds_vod_swing_conf. We should assign default value if
> "ti,lvds-vod-swing-data-microvolt" and "ti,lvds-vod-swing-clock-microvolt"
> are not defined. Default value of the lvds_vod_swing_conf is 0x1, but this
> doesn't have any straight forward meaning like OHM_200 for example.
> 
> What we can do in that case is that we copy the values from defined
> datasheet tables to the "lvds_vod_swing_data[2]" and "lvds_vod_swing_clk[2]"
> arrays and then run the
> sn65dsi83_select_lvds_vod_swing with it, which will return the default value
> (0x1).
> 
> /* If both properties are not defined assign default limits */
> if (ret_data && ret_clock) {
> 	memcpy(lvds_vod_swing_data,
> 	     lvds_vod_swing_data_table[ctx->lvds_term_conf[channel]][1],
> 	     sizeof(lvds_vod_swing_data));
> 	memcpy(lvds_vod_swing_clk,
> 	    lvds_vod_swing_clock_table[ctx->lvds_term_conf[channel]][1],
> 	    sizeof(lvds_vod_swing_clk));
> }
> lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
> 	lvds_vod_swing_data, lvds_vod_swing_clk,
> 	ctx->lvds_term_conf[channel]);
> if (lvds_vod_swing_conf < 0) {
> 	ret = lvds_vod_swing_conf;
> 	goto exit;
> }
> 
> ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
> 
> I'm not sure if using this approach gets rid of the problem with magic
> values.
> Or maybe I'm not seeing the obvious solution so please bear with me.

Yes, the defaults (0..1000000) should be fixed to result in the same
value (0x01) as if the property wasn't specified at all.

I think the following should work:

	/* artifical values to select the defaults in both cases */
	u32 lvds_vod_swing_data[2] = { 190000, 330000 };
	u32 lvds_vod_swing_clk[2] = { 150000, 250000 };

Yes, they are artificial, as stated in the comment. Yes, I think it's
better than special-casing in the property handling.

-- 
With best wishes
Dmitry


From fujita.tomonori at gmail.com  Wed Dec 11 15:16:39 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Thu, 12 Dec 2024 08:16:39 +0900 (JST)
Subject: [PATCH v1 4/5] loongarch/bug: Add ARCH_WARN_ASM macro for
 BUG/WARN asm code sharing with Rust
In-Reply-To: <CAAhV-H7BxE7xeA982Pr4PFxgfNpgXs6H4OZ2LydmYAtYjvYNaw@mail.gmail.com>
References: <20241210001802.228725-1-fujita.tomonori@gmail.com>
	<20241210001802.228725-5-fujita.tomonori@gmail.com>
	<CAAhV-H7BxE7xeA982Pr4PFxgfNpgXs6H4OZ2LydmYAtYjvYNaw@mail.gmail.com>
Message-ID: <20241212.081639.1353664129364117890.fujita.tomonori@gmail.com>

On Wed, 11 Dec 2024 16:41:42 +0800
Huacai Chen <chenhuacai at kernel.org> wrote:

>> +#ifdef CONFIG_DEBUG_BUGVERBOSE
>> +#define __BUG_LOCATION_STRING(file, line)              \
>> +               ".long " file "- .;"                    \
>> +               ".short " line ";"
>> +#else
>> +#define __BUG_LOCATION_STRING(_file, _line)
>> +#endif
> Can we use file and line instead of _file and _line, which is the same
> as the CONFIG_DEBUG_BUGVERBOSE case?

Of course, I'll fix in v2. I should have done that.

>> +
>> +#define __BUG_ENTRY_STRING(file, line, flags)          \
>> +               __stringify(__BUG_ENTRY_START)          \
>> +               __BUG_LOCATION_STRING(file, line)       \
>> +               ".short " flags ";"                     \
>> +               __stringify(__BUG_ENTRY_END)
>> +
>> +#define ARCH_WARN_ASM(file, line, flags, size)         \
>> +       __BUG_ENTRY_STRING(file, line, flags)           \
>> +       __stringify(break BRK_BUG) ";"
>> +
> Can we use the same indentation in this file?

Oops, I'll fix in v2.

Thanks!


From kaleshsingh at google.com  Wed Dec 11 15:27:47 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:47 -0800
Subject: [PATCH mm-unstable v2 09/16] mm: parisc: Introduce arch_align_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-10-kaleshsingh@google.com>

Introduce parisc arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/parisc/include/asm/pgtable.h |  1 +
 arch/parisc/kernel/sys_parisc.c   | 53 +++++++++++++++++--------------
 2 files changed, 31 insertions(+), 23 deletions(-)

diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index babf65751e81..73987357c78e 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -505,6 +505,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index f852fe274abe..c1702d481e33 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -96,24 +96,16 @@ unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
 
 enum mmap_allocation_direction {UP, DOWN};
 
-static unsigned long arch_get_unmapped_area_common(struct file *filp,
-	unsigned long addr, unsigned long len, unsigned long pgoff,
-	unsigned long flags, enum mmap_allocation_direction dir)
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
 {
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma, *prev;
 	unsigned long filp_pgoff;
-	int do_color_align;
-	struct vm_unmapped_area_info info = {
-		.length = len
-	};
+	bool do_color_align;
 
 	if (unlikely(len > TASK_SIZE))
 		return -ENOMEM;
 
-	do_color_align = 0;
-	if (filp || (flags & MAP_SHARED))
-		do_color_align = 1;
 	filp_pgoff = GET_FILP_PGOFF(filp);
 
 	if (flags & MAP_FIXED) {
@@ -128,18 +120,33 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
 		return addr;
 	}
 
-	if (addr) {
-		if (do_color_align)
-			addr = COLOR_ALIGN(addr, filp_pgoff, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
+	do_color_align = filp || (flags & MAP_SHARED);
 
-		vma = find_vma_prev(mm, addr, &prev);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)) &&
-		    (!prev || addr >= vm_end_gap(prev)))
-			return addr;
-	}
+	if (do_color_align)
+		addr = COLOR_ALIGN(addr, filp_pgoff, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
+static unsigned long arch_get_unmapped_area_common(struct file *filp,
+	unsigned long addr, unsigned long len, unsigned long pgoff,
+	unsigned long flags, enum mmap_allocation_direction dir)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long filp_pgoff;
+	bool do_color_align;
+	struct vm_unmapped_area_info info = {
+		.length = len
+	};
+
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
+
+	filp_pgoff = GET_FILP_PGOFF(filp);
+	do_color_align = filp || (flags & MAP_SHARED);
 
 	info.align_mask = do_color_align ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
 	info.align_offset = shared_align_offset(filp_pgoff, pgoff);
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:50 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:50 -0800
Subject: [PATCH mm-unstable v2 12/16] mm: sparc32: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-13-kaleshsingh@google.com>

Introduce sparc32 arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.

If a sufficiently sized hole doesn't exist at the hint address,
fallback to searching the entire valid VA space instead of only
the VA space above the hint address.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/sparc/include/asm/pgtable_32.h |  1 +
 arch/sparc/kernel/sys_sparc_32.c    | 33 +++++++++++++++++++----------
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 62bcafe38b1f..95084c4d0b01 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -437,6 +437,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
 
 /* We provide our own get_unmapped_area to cope with VA holes for userland */
 #define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_MMAP_HINT
 
 #define pmd_pgtable(pmd)	((pgtable_t)__pmd_page(pmd))
 
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index fb31bc0c5b48..0cc717755417 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -40,13 +40,17 @@ SYSCALL_DEFINE0(getpagesize)
 	return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */
 }
 
-unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
 {
-	struct vm_unmapped_area_info info = {};
-	bool file_hugepage = false;
+	bool file_hugepage;
+
+	/* See asm-sparc/uaccess.h */
+	if (len > TASK_SIZE - PAGE_SIZE)
+		return -ENOMEM;
 
-	if (filp && is_file_hugepages(filp))
-		file_hugepage = true;
+	file_hugepage = filp && is_file_hugepages(filp);
 
 	if (flags & MAP_FIXED) {
 		/* We do not accept a shared mapping if it would violate
@@ -58,14 +62,21 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
 		return addr;
 	}
 
-	/* See asm-sparc/uaccess.h */
-	if (len > TASK_SIZE - PAGE_SIZE)
-		return -ENOMEM;
-	if (!addr)
-		addr = TASK_UNMAPPED_BASE;
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
+				     unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
+{
+	struct vm_unmapped_area_info info = {};
+	bool file_hugepage = false;
+
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.length = len;
-	info.low_limit = addr;
+	info.low_limit = TASK_UNMAPPED_BASE;
 	info.high_limit = TASK_SIZE;
 	if (!file_hugepage) {
 		info.align_mask = (flags & MAP_SHARED) ?
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:43 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:43 -0800
Subject: [PATCH mm-unstable v2 05/16] mm: arc: Use generic_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-6-kaleshsingh@google.com>

Introduce arc arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/arc/include/asm/pgtable.h |  1 +
 arch/arc/mm/mmap.c             | 43 +++++++++++++++++-----------------
 2 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 4cf45a99fd79..af3210ea4888 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
 
 /* to cope with aliasing VIPT cache */
 #define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c
index 2185afe8d59f..df01d4d9964b 100644
--- a/arch/arc/mm/mmap.c
+++ b/arch/arc/mm/mmap.c
@@ -14,6 +14,26 @@
 
 #include <asm/cacheflush.h>
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	/*
+	 * We enforce the MAP_FIXED case.
+	 */
+	if (flags & MAP_FIXED) {
+		if (flags & MAP_SHARED &&
+		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
+			return -EINVAL;
+		return addr;
+	}
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 /*
  * Ensure that shared mappings are correctly aligned to
  * avoid aliasing issues with VIPT caches.
@@ -27,30 +47,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	struct vm_unmapped_area_info info = {};
 
-	/*
-	 * We enforce the MAP_FIXED case.
-	 */
-	if (flags & MAP_FIXED) {
-		if (flags & MAP_SHARED &&
-		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
-			return -EINVAL;
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
 		return addr;
-	}
-
-	if (len > TASK_SIZE)
-		return -ENOMEM;
-
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
 
 	info.length = len;
 	info.low_limit = mm->mmap_base;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:48 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:48 -0800
Subject: [PATCH mm-unstable v2 10/16] mm: s390: Use generic_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-11-kaleshsingh@google.com>

Introduce s390 arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/s390/include/asm/pgtable.h |  1 +
 arch/s390/mm/mmap.c             | 51 +++++++++++++++------------------
 2 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 48268095b0a3..eaecb558ab9b 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -1997,6 +1997,7 @@ extern void s390_reset_cmma(struct mm_struct *mm);
 /* s390 has a private copy of get unmapped area to deal with cache synonyms */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #define pmd_pgtable(pmd) \
 	((pgtable_t)__va(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE))
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index 33f3504be90b..8afb046605c9 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -83,28 +83,33 @@ static int get_align_mask(struct file *filp, unsigned long flags)
 	return 0;
 }
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	/* requested length too big for entire address space */
+	if (len > TASK_SIZE - mmap_min_addr)
+		return -ENOMEM;
+
+	if (flags & MAP_FIXED)
+		return addr;
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 				     unsigned long len, unsigned long pgoff,
 				     unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	struct vm_unmapped_area_info info = {};
 
-	if (len > TASK_SIZE - mmap_min_addr)
-		return -ENOMEM;
-
-	if (flags & MAP_FIXED)
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (IS_ERR_VALUE(addr))
+		return addr;
+	if (addr)
 		goto check_asce_limit;
 
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			goto check_asce_limit;
-	}
-
 	info.length = len;
 	info.low_limit = mm->mmap_base;
 	info.high_limit = TASK_SIZE;
@@ -123,25 +128,15 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad
 					     unsigned long len, unsigned long pgoff,
 					     unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
 	struct vm_unmapped_area_info info = {};
 
-	/* requested length too big for entire address space */
-	if (len > TASK_SIZE - mmap_min_addr)
-		return -ENOMEM;
-
-	if (flags & MAP_FIXED)
-		goto check_asce_limit;
-
 	/* requesting a specific address */
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
-				(!vma || addr + len <= vm_start_gap(vma)))
-			goto check_asce_limit;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (IS_ERR_VALUE(addr))
+		return addr;
+	if (addr)
+		goto check_asce_limit;
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:49 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:49 -0800
Subject: [PATCH mm-unstable v2 11/16] mm: sh: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-12-kaleshsingh@google.com>

Introduce sh arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/sh/include/asm/pgtable.h |  1 +
 arch/sh/mm/mmap.c             | 83 ++++++++++++++---------------------
 2 files changed, 33 insertions(+), 51 deletions(-)

diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index 729f5c6225fb..072dbe038808 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -149,5 +149,6 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
 /* arch/sh/mm/mmap.c */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* __ASM_SH_PGTABLE_H */
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index c442734d9b0c..ebda962e8c4e 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -51,14 +51,14 @@ static inline unsigned long COLOUR_ALIGN(unsigned long addr,
 	return base + off;
 }
 
-unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
-	unsigned long len, unsigned long pgoff, unsigned long flags,
-	vm_flags_t vm_flags)
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
 {
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	int do_colour_align;
-	struct vm_unmapped_area_info info = {};
+	bool do_colour_align;
+
+	if (unlikely(len > TASK_SIZE))
+		return -ENOMEM;
 
 	if (flags & MAP_FIXED) {
 		/* We do not accept a shared mapping if it would violate
@@ -70,24 +70,29 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		return addr;
 	}
 
-	if (unlikely(len > TASK_SIZE))
-		return -ENOMEM;
+	do_colour_align = filp || (flags & MAP_SHARED);
 
-	do_colour_align = 0;
-	if (filp || (flags & MAP_SHARED))
-		do_colour_align = 1;
+	if (do_colour_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
 
-	if (addr) {
-		if (do_colour_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
 
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags,
+	vm_flags_t vm_flags)
+{
+	struct vm_unmapped_area_info info = {};
+	bool do_colour_align;
+
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
+
+	do_colour_align = filp || (flags & MAP_SHARED);
 
 	info.length = len;
 	info.low_limit = TASK_UNMAPPED_BASE;
@@ -102,41 +107,17 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 			  const unsigned long len, const unsigned long pgoff,
 			  const unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
 	unsigned long addr = addr0;
-	int do_colour_align;
 	struct vm_unmapped_area_info info = {};
+	bool do_colour_align;
 
-	if (flags & MAP_FIXED) {
-		/* We do not accept a shared mapping if it would violate
-		 * cache aliasing constraints.
-		 */
-		if ((flags & MAP_SHARED) &&
-		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
-			return -EINVAL;
+	/* requesting a specific address */
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
 		return addr;
-	}
 
-	if (unlikely(len > TASK_SIZE))
-		return -ENOMEM;
-
-	do_colour_align = 0;
-	if (filp || (flags & MAP_SHARED))
-		do_colour_align = 1;
-
-	/* requesting a specific address */
-	if (addr) {
-		if (do_colour_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	do_colour_align = filp || (flags & MAP_SHARED);
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:51 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:51 -0800
Subject: [PATCH mm-unstable v2 13/16] mm: sparc64: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-14-kaleshsingh@google.com>

Introduce sparc64 arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/sparc/include/asm/pgtable_64.h |  1 +
 arch/sparc/kernel/sys_sparc_64.c    | 96 +++++++++++------------------
 2 files changed, 37 insertions(+), 60 deletions(-)

diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 2b7f358762c1..f24a4eb2777b 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -1148,6 +1148,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 /* We provide a special get_unmapped_area for framebuffer mmaps to try and use
  * the largest alignment possible such that larget PTEs can be used.
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index c5a284df7b41..e44d55b30a84 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -98,17 +98,19 @@ static unsigned long get_align_mask(struct file *filp, unsigned long flags)
 	return 0;
 }
 
-unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
 {
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct * vma;
-	unsigned long task_size = TASK_SIZE;
-	int do_color_align;
-	struct vm_unmapped_area_info info = {};
-	bool file_hugepage = false;
+	unsigned long task_size;
+	bool do_color_align;
+	bool file_hugepage;
 
-	if (filp && is_file_hugepages(filp))
-		file_hugepage = true;
+	task_size = test_thread_flag(TIF_32BIT) ? STACK_TOP32 : TASK_SIZE;
+	if (unlikely(len > task_size || len >= VA_EXCLUDE_START))
+		return -ENOMEM;
+
+	file_hugepage = filp && is_file_hugepages(filp);
 
 	if (flags & MAP_FIXED) {
 		/* We do not accept a shared mapping if it would violate
@@ -120,26 +122,29 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
 		return addr;
 	}
 
-	if (test_thread_flag(TIF_32BIT))
-		task_size = STACK_TOP32;
-	if (unlikely(len > task_size || len >= VA_EXCLUDE_START))
-		return -ENOMEM;
+	do_color_align = (filp || (flags & MAP_SHARED)) && !file_hugepage;
 
-	do_color_align = 0;
-	if ((filp || (flags & MAP_SHARED)) && !file_hugepage)
-		do_color_align = 1;
+	if (do_color_align)
+		addr = COLOR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
 
-	if (addr) {
-		if (do_color_align)
-			addr = COLOR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
 
-		vma = find_vma(mm, addr);
-		if (task_size - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
+				     unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
+{
+	struct vm_unmapped_area_info info = {};
+	unsigned long task_size;
+	bool file_hugepage;
+
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
+
+	task_size = test_thread_flag(TIF_32BIT) ? STACK_TOP32 : TASK_SIZE;
+	file_hugepage = filp && is_file_hugepages(filp);
 
 	info.length = len;
 	info.low_limit = TASK_UNMAPPED_BASE;
@@ -164,49 +169,20 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 			  const unsigned long len, const unsigned long pgoff,
 			  const unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
-	unsigned long task_size = STACK_TOP32;
 	unsigned long addr = addr0;
-	int do_color_align;
 	struct vm_unmapped_area_info info = {};
-	bool file_hugepage = false;
+	bool file_hugepage;
 
 	/* This should only ever run for 32-bit processes.  */
 	BUG_ON(!test_thread_flag(TIF_32BIT));
 
-	if (filp && is_file_hugepages(filp))
-		file_hugepage = true;
-
-	if (flags & MAP_FIXED) {
-		/* We do not accept a shared mapping if it would violate
-		 * cache aliasing constraints.
-		 */
-		if (!file_hugepage && (flags & MAP_SHARED) &&
-		    ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
-			return -EINVAL;
-		return addr;
-	}
-
-	if (unlikely(len > task_size))
-		return -ENOMEM;
-
-	do_color_align = 0;
-	if ((filp || (flags & MAP_SHARED)) && !file_hugepage)
-		do_color_align = 1;
-
 	/* requesting a specific address */
-	if (addr) {
-		if (do_color_align)
-			addr = COLOR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
-		vma = find_vma(mm, addr);
-		if (task_size - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	file_hugepage = filp && is_file_hugepages(filp);
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:52 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:52 -0800
Subject: [PATCH mm-unstable v2 14/16] mm: xtensa: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-15-kaleshsingh@google.com>

Introduce xtensa arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.

If a sufficiently sized hole doesn't exist at the hint address,
fallback to searching the entire valid VA space instead of only
the VA space above the hint address.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/xtensa/kernel/syscall.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c
index dc54f854c2f5..6bbe10c2a633 100644
--- a/arch/xtensa/kernel/syscall.c
+++ b/arch/xtensa/kernel/syscall.c
@@ -54,12 +54,12 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice,
 }
 
 #ifdef CONFIG_MMU
-unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
-		unsigned long len, unsigned long pgoff, unsigned long flags,
-		vm_flags_t vm_flags)
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
 {
-	struct vm_area_struct *vmm;
-	struct vma_iterator vmi;
+	if (len > TASK_SIZE)
+		return -ENOMEM;
 
 	if (flags & MAP_FIXED) {
 		/* We do not accept a shared mapping if it would violate
@@ -71,16 +71,27 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		return addr;
 	}
 
-	if (len > TASK_SIZE)
-		return -ENOMEM;
-	if (!addr)
-		addr = TASK_UNMAPPED_BASE;
-
 	if (flags & MAP_SHARED)
 		addr = COLOUR_ALIGN(addr, pgoff);
 	else
 		addr = PAGE_ALIGN(addr);
 
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+		unsigned long len, unsigned long pgoff, unsigned long flags,
+		vm_flags_t vm_flags)
+{
+	struct vm_area_struct *vmm;
+	struct vma_iterator vmi;
+
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
+
+	addr = TASK_UNMAPPED_BASE;
+
 	vma_iter_init(&vmi, current->mm, addr);
 	for_each_vma(vmi, vmm) {
 		/* At this point:  (addr < vmm->vm_end). */
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:53 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:53 -0800
Subject: [PATCH mm-unstable v2 15/16] mm: powerpc: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-16-kaleshsingh@google.com>

Introduce powerpc arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 arch/powerpc/include/asm/book3s/64/slice.h |  1 +
 arch/powerpc/mm/book3s64/slice.c           | 31 ++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/arch/powerpc/include/asm/book3s/64/slice.h b/arch/powerpc/include/asm/book3s/64/slice.h
index 5fbe18544cbd..89f629080e90 100644
--- a/arch/powerpc/include/asm/book3s/64/slice.h
+++ b/arch/powerpc/include/asm/book3s/64/slice.h
@@ -10,6 +10,7 @@
 #endif
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 #endif
 
 #define SLICE_LOW_SHIFT		28
diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c
index bc9a39821d1c..b4067c57c778 100644
--- a/arch/powerpc/mm/book3s64/slice.c
+++ b/arch/powerpc/mm/book3s64/slice.c
@@ -647,6 +647,37 @@ static int file_to_psize(struct file *file)
 }
 #endif
 
+static unsigned long slice_mmap_hint(unsigned long addr, unsigned long len,
+				     unsigned long flags, unsigned int psize)
+{
+	unsigned long hint_addr = slice_get_unmapped_area(addr, len, flags, psize, 0);
+
+	if (IS_ERR_VALUE(hint_addr) || hint_addr == PAGE_ALIGN(addr))
+		return hint_addr;
+
+	return 0;
+}
+
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	unsigned int psize;
+
+	if (!addr)
+		return 0;
+
+	if (radix_enabled())
+		return generic_mmap_hint(filp, addr, len, pgoff, flags);
+
+	if (filp && is_file_hugepages(filp))
+		psize = file_to_psize(filp);
+	else
+		psize = mm_ctx_user_psize(&current->mm->context);
+
+	return slice_mmap_hint(addr, len, flags, psize);
+}
+
 unsigned long arch_get_unmapped_area(struct file *filp,
 				     unsigned long addr,
 				     unsigned long len,
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:54 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:54 -0800
Subject: [PATCH mm-unstable v2 16/16] mm: Respect mmap hint before THP
 alignment if allocation is possible
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-17-kaleshsingh@google.com>

Commit 249608ee4713 ("mm: respect mmap hint address when aligning for THP")
fallsback to PAGE_SIZE alignment instead of THP alignment
for anonymous mapping as long as a hint address is provided by the user
-- even if we weren't able to allocate the unmapped area at the hint
address in the end.

This was done to address the immediate regression in anonymous mappings
where the hint address were being ignored in some cases; due to commit
efa7df3e3bb5 ("mm: align larger anonymous mappings on THP boundaries").

It was later pointed out that this issue also existed for file-backed
mappings from file systems that use thp_get_unmapped_area() for their
.get_unmapped_area() file operation.

The same fix was not applied for file-backed mappings since it would
mean any mmap requests that provide a hint address would be only
PAGE_SIZE-aligned regardless of whether allocation was successful at
the hint address or not.

Instead, use arch_mmap_hint() to first attempt allocation at the hint
address and fallback to THP alignment if there isn't sufficient VA space
to satisfy the allocation at the hint address.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---
 mm/huge_memory.c | 17 ++++++++++-------
 mm/mmap.c        |  1 -
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 2da5520bfe24..426761a30aff 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1097,6 +1097,16 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
 	loff_t off_align = round_up(off, size);
 	unsigned long len_pad, ret, off_sub;
 
+	/*
+	 * If allocation at the address hint succeeds; respect the hint and
+	 * don't try to align to THP boundary;
+	 *
+	 * Or if an the requested extent is invalid return the error immediately.
+	 */
+	addr = arch_mmap_hint(filp, addr, len, off, flags);
+	if (addr)
+		return addr;
+
 	if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall())
 		return 0;
 
@@ -1117,13 +1127,6 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
 	if (IS_ERR_VALUE(ret))
 		return 0;
 
-	/*
-	 * Do not try to align to THP boundary if allocation at the address
-	 * hint succeeds.
-	 */
-	if (ret == addr)
-		return addr;
-
 	off_sub = (off - ret) & (size - 1);
 
 	if (test_bit(MMF_TOPDOWN, &current->mm->flags) && !off_sub)
diff --git a/mm/mmap.c b/mm/mmap.c
index 76dd6acdf051..3286fdff26f2 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -814,7 +814,6 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
 	if (get_area) {
 		addr = get_area(file, addr, len, pgoff, flags);
 	} else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && !file
-		   && !addr /* no hint */
 		   && IS_ALIGNED(len, PMD_SIZE)) {
 		/* Ensures that larger anonymous mappings are THP aligned. */
 		addr = thp_get_unmapped_area_vmflags(file, addr, len,
-- 
2.47.0.338.g60cca15819-goog



From willmcvicker at google.com  Wed Dec 11 15:33:46 2024
From: willmcvicker at google.com (William McVicker)
Date: Wed, 11 Dec 2024 15:33:46 -0800
Subject: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon"
 compatible
In-Reply-To: <20241211-syscon-fixes-v1-3-b5ac8c219e96@kernel.org>
References: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
 <20241211-syscon-fixes-v1-3-b5ac8c219e96@kernel.org>
Message-ID: <Z1ohWoq1jEFgR17P@google.com>

Hi Rob,

Thanks for working on this!

On 12/11/2024, Rob Herring (Arm) wrote:
> of_syscon_register_regmap() was added for nodes which need a custom
> regmap setup. It's not really correct for those nodes to claim they are
> compatible with "syscon" as the default handling likely doesn't work in
> those cases. If device_node_get_regmap() happens to be called first,
> then of_syscon_register() will be called and an incorrect regmap will be
> created (barring some other error). That may lead to unknown results in
> the worst case. In the best case, of_syscon_register_regmap() will fail
> with -EEXIST. This problem remains unless these cases drop "syscon" (an
> ABI issue) or we exclude them using their specific compatible. ATM,
> there is only one user: "google,gs101-pmu"
> 
> There are also cases of adding "syscon" compatible to existing nodes
> after the fact in order to register the syscon. That presents a
> potential DT ABI problem. Instead, if there's a kernel change needing a
> syscon for a node, then it should be possible to allow the kernel to
> register a syscon without a DT change. That's only possible by using
> of_syscon_register_regmap() currently, but in the future we may want to
> support a match list for cases which don't need a custom regmap.
> 
> With this change, the lookup functions will succeed for any node
> registered by of_syscon_register_regmap() regardless of whether the node
> compatible contains "syscon".
> 
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
> ---
>  drivers/mfd/syscon.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> index bfb1f69fcff1..e6df2825c14d 100644
> --- a/drivers/mfd/syscon.c
> +++ b/drivers/mfd/syscon.c
> @@ -171,8 +171,10 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
>  			break;
>  		}
>  
> -	if (!syscon)
> +	if (!syscon && of_device_is_compatible(np, "syscon"))
>  		syscon = of_syscon_register(np, check_res);
> +	else
> +		syscon = ERR_PTR(-EINVAL);

This else case actually breaks Pixel 6 (Tensor) since you are now returning
-EINVAL when the syscon is created by the exynos-pmu driver and present in the
list. Instead you should only return -EINVAL if the syscon doesn't exist and
the device node is not a compatible syscon device. If you still want to check
for `of_device_is_compatible(np, "syscon")` even when the syscon is found in
the list, that should be okay , but it's probably best to check that before
inserting the regmap in the list to begin with.

This worked for me on my Pixel 6 device:

	if (!syscon) {
		if (of_device_is_compatible(np, "syscon"))
			syscon = of_syscon_register(np, check_res);
		else
			syscon = ERR_PTR(-EINVAL);
	}

Thanks,
Will


From dmitry.baryshkov at linaro.org  Wed Dec 11 15:35:02 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 12 Dec 2024 01:35:02 +0200
Subject: [PATCH v6 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <db4d9d4e-855f-4647-9b93-ccc5ec0202b3@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
 <20241209033923.3009629-13-victor.liu@nxp.com>
 <3j4fguv4oienfaj4fghpiqpmnq3aczu4azhdo5jzvywc5mawm5@hh33p3dhf6xa>
 <db4d9d4e-855f-4647-9b93-ccc5ec0202b3@nxp.com>
Message-ID: <q6pdop6ucowtoxxr66czq7yooujyvp6qs5vcg6gpmi3q4rs4l3@szyqt5pxteoz>

On Wed, Dec 11, 2024 at 03:43:20PM +0800, Liu Ying wrote:
> On 12/10/2024, Dmitry Baryshkov wrote:
> > On Mon, Dec 09, 2024 at 11:39:16AM +0800, Liu Ying wrote:
> >> i.MX8qxp Display Controller(DC) is comprised of three main components that
> >> include a blit engine for 2D graphics accelerations, display controller for
> >> display output processing, as well as a command sequencer.  Add kernel
> >> mode setting support for the display controller part with two CRTCs and
> >> two primary planes(backed by FetchLayer and FetchWarp respectively).  The
> >> registers of the display controller are accessed without command sequencer
> >> involved, instead just by using CPU.  The command sequencer is supposed to
> >> be used by the blit engine.
> >>
> >> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> >> ---
> >> v6:
> >> * No change.
> >>
> >> v5:
> >> * Replace .remove_new with .remove in dc-drv.c. (Uwe)
> >>
> >> v4:
> >> * Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
> >>   function calls from KMS routine to initialization stage. (Dmitry)
> >> * Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
> >>   appropriate .h header files or .c source files. (Dmitry)
> >> * Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
> >> * Drop dc_drm->pe_rpm_count. (Dmitry)
> >> * Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
> >> * Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
> >>   Instead, put it in struct dc_crtc.  (Dmitry)
> >> * Call devm_request_irq() to request IRQs, instead of using drmm action.
> >>   (Dmitry)
> >> * Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
> >> * Select DRM_CLIENT_SELECTION due to rebase.
> >> * Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
> >> * Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
> >> * Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
> >>   rebase.
> >> * Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
> >>   register dc_drm_component_unbind_all() action.
> >> * Request interrupts in dc_crtc_post_init() after encoder initialization to
> >>   make sure next bridge is found first.
> >>
> >> v3:
> >> * No change.
> >>
> >> v2:
> >> * Find next bridge from TCon's port.
> >> * Drop drm/drm_module.h include from dc-drv.c.
> >>
> >>  drivers/gpu/drm/imx/dc/Kconfig    |   5 +
> >>  drivers/gpu/drm/imx/dc/Makefile   |   5 +-
> >>  drivers/gpu/drm/imx/dc/dc-crtc.c  | 558 ++++++++++++++++++++++++++++++
> >>  drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
> >>  drivers/gpu/drm/imx/dc/dc-drv.c   | 244 +++++++++++++
> >>  drivers/gpu/drm/imx/dc/dc-drv.h   |  19 +
> >>  drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
> >>  drivers/gpu/drm/imx/dc/dc-kms.h   |  58 ++++
> >>  drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
> >>  9 files changed, 1274 insertions(+), 2 deletions(-)
> >>  create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
> >>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
> >>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
> >>  create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
> >>
> >> diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
> >> index 1fc84c7475de..415993207f2e 100644
> >> --- a/drivers/gpu/drm/imx/dc/Kconfig
> >> +++ b/drivers/gpu/drm/imx/dc/Kconfig
> >> @@ -1,6 +1,11 @@
> >>  config DRM_IMX8_DC
> >>  	tristate "Freescale i.MX8 Display Controller Graphics"
> >>  	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
> >> +	select DRM_CLIENT_SELECTION
> >> +	select DRM_GEM_DMA_HELPER
> >> +	select DRM_KMS_HELPER
> >> +	select DRM_DISPLAY_HELPER
> >> +	select DRM_BRIDGE_CONNECTOR
> >>  	select GENERIC_IRQ_CHIP
> >>  	select REGMAP
> >>  	select REGMAP_MMIO
> >> diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
> >> index 1ce3e8a8db22..b9d33c074984 100644
> >> --- a/drivers/gpu/drm/imx/dc/Makefile
> >> +++ b/drivers/gpu/drm/imx/dc/Makefile
> >> @@ -1,6 +1,7 @@
> >>  # SPDX-License-Identifier: GPL-2.0
> >>  
> >> -imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
> >> -		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
> >> +imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
> >> +		    dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
> >> +		    dc-plane.o dc-tc.o
> >>  
> >>  obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
> >> diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
> >> new file mode 100644
> >> index 000000000000..fd6daa1807d8
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
> >> @@ -0,0 +1,558 @@
> >> +// SPDX-License-Identifier: GPL-2.0+
> >> +/*
> >> + * Copyright 2024 NXP
> >> + */
> >> +
> >> +#include <linux/completion.h>
> >> +#include <linux/container_of.h>
> >> +#include <linux/interrupt.h>
> >> +#include <linux/irqreturn.h>
> >> +#include <linux/pm_runtime.h>
> >> +#include <linux/spinlock.h>
> >> +
> >> +#include <drm/drm_atomic.h>
> >> +#include <drm/drm_atomic_helper.h>
> >> +#include <drm/drm_atomic_state_helper.h>
> >> +#include <drm/drm_crtc.h>
> >> +#include <drm/drm_device.h>
> >> +#include <drm/drm_drv.h>
> >> +#include <drm/drm_modes.h>
> >> +#include <drm/drm_modeset_helper_vtables.h>
> >> +#include <drm/drm_plane.h>
> >> +#include <drm/drm_print.h>
> >> +#include <drm/drm_vblank.h>
> >> +
> >> +#include "dc-de.h"
> >> +#include "dc-drv.h"
> >> +#include "dc-kms.h"
> >> +#include "dc-pe.h"
> >> +
> >> +#define dc_crtc_dbg(crtc, fmt, ...)					\
> >> +do {									\
> >> +	typeof(crtc) _crtc = (crtc);					\
> > 
> > Use exact type instead of typeof.
> 
> Will do.
> 
> > 
> >> +	drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
> >> +		    _crtc->base.id, _crtc->name, ##__VA_ARGS__);	\
> >> +} while (0)
> >> +
> >> +#define dc_crtc_err(crtc, fmt, ...)					\
> >> +do {									\
> >> +	typeof(crtc) _crtc = (crtc);					\
> >> +	drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
> >> +		_crtc->base.id, _crtc->name, ##__VA_ARGS__);		\
> >> +} while (0)
> >> +
> >> +#define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c)				\
> >> +do {									\
> >> +	unsigned long ret;						\
> >> +	ret = wait_for_completion_timeout(&dc_crtc->c, HZ);		\
> >> +	if (ret == 0)							\
> >> +		dc_crtc_err(crtc, "%s: wait for " #c " timeout\n",	\
> >> +							__func__);	\
> >> +} while (0)
> >> +
> >> +#define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg)					\
> >> +do {									\
> >> +	typeof(fg) _fg = (fg);						\
> >> +	if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) {		\
> >> +		dc_fg_secondary_clear_channel_status(_fg);		\
> >> +		dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n",		\
> >> +							__func__);	\
> >> +	}								\
> >> +} while (0)
> >> +
> >> +#define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg)			\
> >> +do {									\
> >> +	if (dc_fg_wait_for_secondary_syncup(fg))			\
> >> +		dc_crtc_err(crtc,					\
> >> +			"%s: FrameGen secondary channel isn't syncup\n",\
> >> +							__func__);	\
> >> +} while (0)
> >> +
> >> +static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
> >> +{
> >> +	return container_of(crtc, struct dc_crtc, base);
> >> +}
> >> +
> >> +static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
> >> +{
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +
> >> +	return dc_fg_get_frame_index(dc_crtc->fg);
> >> +}
> >> +
> >> +static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
> >> +{
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +
> >> +	enable_irq(dc_crtc->irq_dec_framecomplete);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
> >> +{
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +
> >> +	disable_irq_nosync(dc_crtc->irq_dec_framecomplete);
> > 
> > Why is it _nosync?
> 
> Because disable_irq() can only be called from preemptible code according to
> it's kerneldoc. If I use disable_irq() here, I get this with
> CONFIG_DEBUG_ATOMIC_SLEEP enabled:

Please add a one-line comment, like "nosync because of the atomic
context"

> 
> [   50.607503] BUG: sleeping function called from invalid context at kernel/irq/manage.c:738
> [   50.615691] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/0
> [   50.623527] preempt_count: 10003, expected: 0
> [   50.627888] RCU nest depth: 0, expected: 0
> [   50.631993] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.13.0-rc2-next-20241209-00026-g800cb5b7df74 #1407
> [   50.642092] Hardware name: Freescale i.MX8QXP MEK (DT)
> [   50.647237] Call trace:
> [   50.649687]  show_stack+0x18/0x24 (C)
> [   50.653369]  dump_stack_lvl+0x80/0xb4
> [   50.657043]  dump_stack+0x18/0x24
> [   50.660370]  __might_resched+0x114/0x170
> [   50.664306]  __might_sleep+0x48/0x98
> [   50.667894]  disable_irq+0x24/0x60
> [   50.671308]  dc_crtc_disable_vblank+0x14/0x20 [imx8_dc_drm]
> [   50.676912]  drm_vblank_disable_and_save+0xc0/0x108 [drm]
> [   50.682533]  vblank_disable_fn+0x78/0x9c [drm]
> [   50.687146]  drm_handle_vblank+0x238/0x2e8 [drm]
> [   50.691932]  drm_crtc_handle_vblank+0x1c/0x28 [drm]
> [   50.696980]  dc_crtc_irq_handler_dec_framecomplete+0x1c/0x6c [imx8_dc_drm]
> [   50.703886]  __handle_irq_event_percpu+0x60/0x14c
> [   50.708604]  handle_irq_event+0x4c/0xac
> [   50.712443]  handle_level_irq+0xc0/0x1b0
> [   50.716379]  generic_handle_irq+0x34/0x4c
> [   50.720392]  dc_ic_irq_handler+0x128/0x160 [imx8_dc_drm]
> [   50.725727]  generic_handle_domain_irq+0x2c/0x44
> [   50.730357]  imx_irqsteer_irq_handler+0xc0/0x1a0
> [   50.734987]  generic_handle_domain_irq+0x2c/0x44
> [   50.739609]  gic_handle_irq+0x4c/0x114
> [   50.743362]  call_on_irq_stack+0x24/0x4c
> [   50.747298]  do_interrupt_handler+0x80/0x84
> [   50.751494]  el1_interrupt+0x34/0x68
> [   50.755082]  el1h_64_irq_handler+0x18/0x24
> [   50.759191]  el1h_64_irq+0x6c/0x70
> [   50.762597]  default_idle_call+0x28/0x3c (P)
> [   50.766879]  default_idle_call+0x24/0x3c (L)
> [   50.771163]  do_idle+0x200/0x25c
> [   50.774403]  cpu_startup_entry+0x34/0x3c
> [   50.778338]  kernel_init+0x0/0x1d8
> [   50.781752]  start_kernel+0x5c4/0x70c
> [   50.785427]  __primary_switched+0x88/0x90
> 
> > 
> >> +}
> >> +
> >> +static irqreturn_t
> >> +dc_crtc_dec_framecomplete_irq_handler(int irq, void *dev_id)
> >> +{
> >> +	struct dc_crtc *dc_crtc = dev_id;
> >> +	struct drm_crtc *crtc = &dc_crtc->base;
> >> +	unsigned long flags;
> >> +
> >> +	drm_crtc_handle_vblank(crtc);
> >> +
> >> +	spin_lock_irqsave(&crtc->dev->event_lock, flags);
> >> +	if (dc_crtc->event) {
> >> +		drm_crtc_send_vblank_event(crtc, dc_crtc->event);
> >> +		dc_crtc->event = NULL;
> >> +		drm_crtc_vblank_put(crtc);
> >> +	}
> >> +	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> >> +
> >> +	return IRQ_HANDLED;
> >> +}
> >> +
> >> +static irqreturn_t dc_crtc_common_irq_handler(int irq, void *dev_id)
> >> +{
> >> +	struct dc_crtc *dc_crtc = dev_id;
> >> +
> >> +	if (irq == dc_crtc->irq_dec_seqcomplete)
> >> +		complete(&dc_crtc->dec_seqcomplete_done);
> >> +	else if (irq == dc_crtc->irq_dec_shdld)
> >> +		complete(&dc_crtc->dec_shdld_done);
> >> +	else if (irq == dc_crtc->irq_ed_cont_shdld)
> >> +		complete(&dc_crtc->ed_cont_shdld_done);
> >> +	else if (irq == dc_crtc->irq_ed_safe_shdld)
> >> +		complete(&dc_crtc->ed_safe_shdld_done);
> > 
> > Is there any reason to have a single multiplex handler instead of having
> > 4 separate handlers, each doing one simple thing?
> 
> Just thought that one irq handler is feasible to implement the common
> handling logic. It's also ok to use 4 separate handlers with a little
> performance improvement. I may change to use 4 separate handlers by
> introducing a DEFINE_DC_CRTC_IRQ_HANDLER() marco.

Just define them one by one, there is no need for a macro.

> 
> > 
> >> +
> >> +	return IRQ_HANDLED;
> >> +}
> >> +
> >> +static const struct drm_crtc_funcs dc_crtc_funcs = {
> >> +	.reset			= drm_atomic_helper_crtc_reset,
> >> +	.destroy		= drm_crtc_cleanup,
> >> +	.set_config		= drm_atomic_helper_set_config,
> >> +	.page_flip		= drm_atomic_helper_page_flip,
> >> +	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
> >> +	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
> >> +	.get_vblank_counter	= dc_crtc_get_vblank_counter,
> >> +	.enable_vblank		= dc_crtc_enable_vblank,
> >> +	.disable_vblank		= dc_crtc_disable_vblank,
> >> +	.get_vblank_timestamp	= drm_crtc_vblank_helper_get_vblank_timestamp,
> >> +};
> >> +
> >> +static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
> >> +{
> >> +	struct drm_crtc *crtc = crtc_state->crtc;
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +
> >> +	spin_lock_irq(&crtc->dev->event_lock);
> >> +	if (crtc_state->event) {
> >> +		WARN_ON(drm_crtc_vblank_get(crtc));
> >> +		WARN_ON(dc_crtc->event);
> >> +		dc_crtc->event = crtc_state->event;
> >> +		crtc_state->event = NULL;
> >> +	}
> >> +	spin_unlock_irq(&crtc->dev->event_lock);
> >> +}
> >> +
> >> +static enum drm_mode_status
> >> +dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
> >> +{
> >> +	return dc_fg_check_clock(dc_crtc->fg, clk_khz);
> >> +}
> > 
> > inline
> 
> Will do.
> 
> > 
> >> +
> >> +static enum drm_mode_status
> >> +dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
> >> +{
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +	enum drm_mode_status status;
> >> +
> >> +	status = dc_crtc_check_clock(dc_crtc, mode->clock);
> >> +	if (status != MODE_OK)
> >> +		return status;
> >> +
> >> +	if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
> >> +		return MODE_CLOCK_HIGH;
> >> +
> >> +	return MODE_OK;
> >> +}
> >> +
> >> +static int
> >> +dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >> +{
> >> +	struct drm_crtc_state *new_crtc_state =
> >> +				drm_atomic_get_new_crtc_state(state, crtc);
> >> +	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +	enum drm_mode_status status;
> >> +
> >> +	status = dc_crtc_check_clock(dc_crtc, adj->clock);
> >> +	if (status != MODE_OK)
> >> +		return -EINVAL;
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static void
> >> +dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >> +{
> >> +	struct drm_crtc_state *new_crtc_state =
> >> +				drm_atomic_get_new_crtc_state(state, crtc);
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +	int idx, ret;
> >> +
> >> +	if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
> >> +	    !new_crtc_state->active)
> >> +		return;
> >> +
> >> +	if (!drm_dev_enter(crtc->dev, &idx))
> >> +		return;
> >> +
> >> +	/* request pixel engine power-on when CRTC starts to be active */
> >> +	ret = pm_runtime_resume_and_get(dc_crtc->pe->dev);
> >> +	if (ret)
> >> +		dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
> >> +			    ret);
> >> +
> >> +	drm_dev_exit(idx);
> >> +}
> >> +
> >> +static void
> >> +dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >> +{
> >> +	struct drm_crtc_state *old_crtc_state =
> >> +				drm_atomic_get_old_crtc_state(state, crtc);
> >> +	struct drm_crtc_state *new_crtc_state =
> >> +				drm_atomic_get_new_crtc_state(state, crtc);
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +	int idx;
> >> +
> >> +	if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
> >> +	    (!old_crtc_state->active && !new_crtc_state->active))
> >> +		return;
> >> +
> >> +	if (!drm_dev_enter(crtc->dev, &idx))
> >> +		goto out;
> >> +
> >> +	enable_irq(dc_crtc->irq_ed_cont_shdld);
> >> +
> >> +	/* flush plane update out to display */
> >> +	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
> >> +
> >> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
> >> +
> >> +	disable_irq(dc_crtc->irq_ed_cont_shdld);
> >> +
> >> +	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
> >> +
> >> +	drm_dev_exit(idx);
> >> +
> >> +out:
> >> +	dc_crtc_queue_state_event(new_crtc_state);
> >> +}
> >> +
> >> +static void
> >> +dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >> +{
> >> +	struct drm_crtc_state *new_crtc_state =
> >> +				drm_atomic_get_new_crtc_state(state, crtc);
> >> +	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +	enum dc_link_id cf_link;
> >> +	int idx, ret;
> >> +
> >> +	dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
> >> +
> >> +	drm_crtc_vblank_on(crtc);
> >> +
> >> +	if (!drm_dev_enter(crtc->dev, &idx))
> >> +		goto out;
> >> +
> >> +	/* request display engine power-on when CRTC is enabled */
> >> +	ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
> >> +	if (ret < 0)
> >> +		dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
> >> +			    ret);
> >> +
> >> +	enable_irq(dc_crtc->irq_dec_shdld);
> >> +	enable_irq(dc_crtc->irq_ed_cont_shdld);
> >> +	enable_irq(dc_crtc->irq_ed_safe_shdld);
> >> +
> >> +	dc_fg_cfg_videomode(dc_crtc->fg, adj);
> >> +
> >> +	dc_cf_framedimensions(dc_crtc->cf_cont,
> >> +			      adj->crtc_hdisplay, adj->crtc_vdisplay);
> >> +	dc_cf_framedimensions(dc_crtc->cf_safe,
> >> +			      adj->crtc_hdisplay, adj->crtc_vdisplay);
> >> +
> >> +	/* constframe in safety stream shows blue frame */
> >> +	dc_cf_constantcolor_blue(dc_crtc->cf_safe);
> >> +	cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
> >> +	dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
> >> +
> >> +	/* show CRTC background if no plane is enabled */
> >> +	if (new_crtc_state->plane_mask == 0) {
> >> +		/* constframe in content stream shows black frame */
> >> +		dc_cf_constantcolor_black(dc_crtc->cf_cont);
> >> +
> >> +		cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
> >> +		dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
> >> +	}
> >> +
> >> +	dc_fg_enable_clock(dc_crtc->fg);
> >> +	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
> >> +	dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
> >> +	dc_fg_shdtokgen(dc_crtc->fg);
> >> +	dc_fg_enable(dc_crtc->fg);
> >> +
> >> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdld_done);
> >> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
> >> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdld_done);
> >> +
> >> +	disable_irq(dc_crtc->irq_ed_safe_shdld);
> >> +	disable_irq(dc_crtc->irq_ed_cont_shdld);
> >> +	disable_irq(dc_crtc->irq_dec_shdld);
> >> +
> >> +	DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
> >> +
> >> +	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
> >> +
> >> +	drm_dev_exit(idx);
> >> +
> >> +out:
> >> +	dc_crtc_queue_state_event(new_crtc_state);
> >> +}
> >> +
> >> +static void
> >> +dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >> +{
> >> +	struct drm_crtc_state *new_crtc_state =
> >> +				drm_atomic_get_new_crtc_state(state, crtc);
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +	int idx, ret;
> >> +
> >> +	if (!drm_dev_enter(crtc->dev, &idx))
> >> +		goto out;
> >> +
> >> +	enable_irq(dc_crtc->irq_dec_seqcomplete);
> >> +	dc_fg_disable(dc_crtc->fg);
> >> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
> >> +	disable_irq(dc_crtc->irq_dec_seqcomplete);
> >> +
> >> +	dc_fg_disable_clock(dc_crtc->fg);
> >> +
> >> +	/* request pixel engine power-off as plane is off too */
> >> +	ret = pm_runtime_put(dc_crtc->pe->dev);
> >> +	if (ret)
> >> +		dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
> >> +			    ret);
> >> +
> >> +	/* request display engine power-off when CRTC is disabled */
> >> +	ret = pm_runtime_put(dc_crtc->de->dev);
> > 
> > Can this be expressed as a devlink between PE and DE?
> 
> Looking at struct dc_{pe,de}, PE and DE are not dependent with each other,
> i.e., no consumer/supplier relationship(note that blit engine in PE can work
> by itself without DE) between them. So, it doesn't look right to link the two
> devices.

Ack

> 
> > 
> >> +	if (ret < 0)
> >> +		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
> >> +			    ret);
> >> +
> >> +	drm_dev_exit(idx);
> >> +
> >> +out:
> >> +	drm_crtc_vblank_off(crtc);
> >> +
> >> +	spin_lock_irq(&crtc->dev->event_lock);
> >> +	if (new_crtc_state->event && !new_crtc_state->active) {
> >> +		drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
> >> +		new_crtc_state->event = NULL;
> >> +	}
> >> +	spin_unlock_irq(&crtc->dev->event_lock);
> >> +}
> >> +
> >> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc)
> >> +{
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +	int ret;
> >> +
> >> +	if (!dc_fg_wait_for_frame_index_moving(dc_crtc->fg))
> >> +		return;
> >> +
> >> +	dc_fg_disable_clock(dc_crtc->fg);
> >> +
> >> +	if (pm_runtime_active(dc_crtc->pe->dev)) {
> >> +		ret = pm_runtime_put_sync(dc_crtc->pe->dev);
> >> +		if (ret)
> >> +			dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
> >> +				    ret);
> >> +	}
> >> +
> >> +	ret = pm_runtime_put_sync(dc_crtc->de->dev);
> >> +	if (ret < 0)
> >> +		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
> >> +			    ret);
> >> +}
> >> +
> >> +static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
> >> +					 bool in_vblank_irq,
> >> +					 int *vpos, int *hpos,
> >> +					 ktime_t *stime, ktime_t *etime,
> >> +					 const struct drm_display_mode *mode)
> >> +{
> >> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >> +	int vdisplay = mode->crtc_vdisplay;
> >> +	int vtotal = mode->crtc_vtotal;
> >> +	bool reliable;
> >> +	int line;
> >> +	int idx;
> >> +
> >> +	if (stime)
> >> +		*stime = ktime_get();
> >> +
> >> +	if (!drm_dev_enter(crtc->dev, &idx)) {
> >> +		reliable = false;
> >> +		*vpos = 0;
> >> +		*hpos = 0;
> >> +		goto out;
> >> +	}
> >> +
> >> +	/* line index starts with 0 for the first active output line */
> >> +	line = dc_fg_get_line_index(dc_crtc->fg);
> >> +
> >> +	if (line < vdisplay)
> >> +		/* active scanout area - positive */
> >> +		*vpos = line + 1;
> >> +	else
> >> +		/* inside vblank - negative */
> >> +		*vpos = line - (vtotal - 1);
> >> +
> >> +	*hpos = 0;
> >> +
> >> +	reliable = true;
> >> +
> >> +	drm_dev_exit(idx);
> >> +out:
> >> +	if (etime)
> >> +		*etime = ktime_get();
> >> +
> >> +	return reliable;
> >> +}
> >> +
> >> +static const struct drm_crtc_helper_funcs dc_helper_funcs = {
> >> +	.mode_valid		= dc_crtc_mode_valid,
> >> +	.atomic_check		= dc_crtc_atomic_check,
> >> +	.atomic_begin		= dc_crtc_atomic_begin,
> >> +	.atomic_flush		= dc_crtc_atomic_flush,
> >> +	.atomic_enable		= dc_crtc_atomic_enable,
> >> +	.atomic_disable		= dc_crtc_atomic_disable,
> >> +	.get_scanout_position	= dc_crtc_get_scanout_position,
> >> +};
> >> +
> >> +static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
> >> +{
> >> +	struct {
> >> +		struct device *dev;
> >> +		unsigned int irq;
> >> +		irqreturn_t (*irq_handler)(int irq, void *dev_id);
> >> +	} irqs[DC_CRTC_IRQS] = {
> >> +		{
> >> +			dc_crtc->de->dev,
> >> +			dc_crtc->irq_dec_framecomplete,
> >> +			dc_crtc_dec_framecomplete_irq_handler,
> >> +		}, {
> >> +			dc_crtc->de->dev,
> >> +			dc_crtc->irq_dec_seqcomplete,
> >> +			dc_crtc_common_irq_handler,
> >> +		}, {
> >> +			dc_crtc->de->dev,
> >> +			dc_crtc->irq_dec_shdld,
> >> +			dc_crtc_common_irq_handler,
> >> +		}, {
> >> +			dc_crtc->ed_cont->dev,
> >> +			dc_crtc->irq_ed_cont_shdld,
> >> +			dc_crtc_common_irq_handler,
> >> +		}, {
> >> +			dc_crtc->ed_safe->dev,
> >> +			dc_crtc->irq_ed_safe_shdld,
> >> +			dc_crtc_common_irq_handler,
> >> +		},
> >> +	};
> >> +	int i, ret;
> >> +
> >> +	for (i = 0; i < DC_CRTC_IRQS; i++) {
> >> +		struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
> >> +
> >> +		ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
> >> +				       irqs[i].irq_handler, IRQF_NO_AUTOEN,
> >> +				       dev_name(irqs[i].dev), dc_crtc);
> >> +		if (ret) {
> >> +			dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
> >> +				irqs[i].irq, ret);
> >> +			return ret;
> >> +		}
> >> +
> >> +		irq->dc_crtc = dc_crtc;
> >> +		irq->irq = irqs[i].irq;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
> >> +{
> >> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> >> +	struct drm_device *drm = &dc_drm->base;
> >> +	struct dc_de *de = dc_drm->de[crtc_index];
> >> +	struct dc_pe *pe = dc_drm->pe;
> >> +	struct dc_plane *dc_primary;
> >> +	int ret;
> >> +
> >> +	dc_crtc->de = de;
> >> +	dc_crtc->pe = pe;
> >> +
> >> +	init_completion(&dc_crtc->dec_seqcomplete_done);
> >> +	init_completion(&dc_crtc->dec_shdld_done);
> >> +	init_completion(&dc_crtc->ed_cont_shdld_done);
> >> +	init_completion(&dc_crtc->ed_safe_shdld_done);
> >> +
> >> +	dc_crtc->cf_cont = pe->cf_cont[crtc_index];
> >> +	dc_crtc->cf_safe = pe->cf_safe[crtc_index];
> >> +	dc_crtc->ed_cont = pe->ed_cont[crtc_index];
> >> +	dc_crtc->ed_safe = pe->ed_safe[crtc_index];
> >> +	dc_crtc->fg = de->fg;
> >> +
> >> +	dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
> >> +	dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
> >> +	dc_crtc->irq_dec_shdld = de->irq_shdld;
> >> +	dc_crtc->irq_ed_safe_shdld = dc_crtc->ed_safe->irq_shdld;
> >> +	dc_crtc->irq_ed_cont_shdld = dc_crtc->ed_cont->irq_shdld;
> >> +
> >> +	dc_primary = &dc_drm->dc_primary[crtc_index];
> >> +	ret = dc_plane_init(dc_drm, dc_primary);
> >> +	if (ret) {
> >> +		dev_err(drm->dev,
> >> +			"failed to init primary plane for display engine%u: %d\n",
> >> +			de->id, ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
> >> +
> >> +	ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
> >> +					NULL, &dc_crtc_funcs, NULL);
> >> +	if (ret)
> >> +		dev_err(drm->dev,
> >> +			"failed to add CRTC for display engine%u: %d\n",
> >> +			de->id, ret);
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
> >> +{
> >> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> >> +	struct drm_device *drm = &dc_drm->base;
> >> +
> >> +	return dc_crtc_request_irqs(drm, dc_crtc);
> >> +}
> >> diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
> >> index 17a44362118e..8a7b6c03a222 100644
> >> --- a/drivers/gpu/drm/imx/dc/dc-de.h
> >> +++ b/drivers/gpu/drm/imx/dc/dc-de.h
> >> @@ -13,6 +13,9 @@
> >>  
> >>  #define DC_DISPLAYS	2
> >>  
> >> +#define DC_FRAMEGEN_MAX_FRAME_INDEX	0x3ffff
> >> +#define DC_FRAMEGEN_MAX_CLOCK_KHZ	300000
> >> +
> >>  struct dc_fg {
> >>  	struct device *dev;
> >>  	struct regmap *reg;
> >> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
> >> index fd68861f770a..1e4b8afa3eec 100644
> >> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
> >> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
> >> @@ -3,11 +3,254 @@
> >>   * Copyright 2024 NXP
> >>   */
> >>  
> >> +#include <linux/clk.h>
> >> +#include <linux/component.h>
> >> +#include <linux/device.h>
> >> +#include <linux/dma-mapping.h>
> >> +#include <linux/mod_devicetable.h>
> >>  #include <linux/module.h>
> >> +#include <linux/of.h>
> >> +#include <linux/of_platform.h>
> >>  #include <linux/platform_device.h>
> >> +#include <linux/pm.h>
> >> +#include <linux/pm_runtime.h>
> >>  
> >> +#include <drm/drm_atomic_helper.h>
> >> +#include <drm/drm_client_setup.h>
> >> +#include <drm/drm_crtc.h>
> >> +#include <drm/drm_drv.h>
> >> +#include <drm/drm_fbdev_dma.h>
> >> +#include <drm/drm_fourcc.h>
> >> +#include <drm/drm_gem_dma_helper.h>
> >> +#include <drm/drm_managed.h>
> >> +#include <drm/drm_modeset_helper.h>
> >> +#include <drm/drm_of.h>
> >> +
> >> +#include "dc-de.h"
> >>  #include "dc-drv.h"
> >>  
> >> +struct dc_priv {
> >> +	struct drm_device *drm;
> >> +	struct clk *clk_cfg;
> >> +};
> >> +
> >> +DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
> >> +
> >> +static struct drm_driver dc_drm_driver = {
> >> +	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
> >> +	DRM_GEM_DMA_DRIVER_OPS,
> >> +	DRM_FBDEV_DMA_DRIVER_OPS,
> >> +	.fops = &dc_drm_driver_fops,
> >> +	.name = "imx8-dc",
> >> +	.desc = "i.MX8 DC DRM graphics",
> >> +	.date = "20240530",
> >> +	.major = 1,
> >> +	.minor = 0,
> >> +	.patchlevel = 0,
> >> +};
> >> +
> >> +static void
> >> +dc_add_components(struct device *dev, struct component_match **matchptr)
> >> +{
> >> +	struct device_node *child, *grandchild;
> >> +
> >> +	for_each_available_child_of_node(dev->of_node, child) {
> >> +		/* The interrupt controller is not a component. */
> >> +		if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
> >> +			continue;
> >> +
> >> +		drm_of_component_match_add(dev, matchptr, component_compare_of,
> >> +					   child);
> >> +
> >> +		for_each_available_child_of_node(child, grandchild)
> >> +			drm_of_component_match_add(dev, matchptr,
> >> +						   component_compare_of,
> >> +						   grandchild);
> >> +	}
> >> +}
> >> +
> >> +static void dc_drm_component_unbind_all(void *ptr)
> >> +{
> >> +	struct dc_drm_device *dc_drm = ptr;
> >> +	struct drm_device *drm = &dc_drm->base;
> >> +
> >> +	component_unbind_all(drm->dev, dc_drm);
> >> +}
> >> +
> >> +static int dc_drm_bind(struct device *dev)
> >> +{
> >> +	struct dc_priv *priv = dev_get_drvdata(dev);
> >> +	struct dc_drm_device *dc_drm;
> >> +	struct drm_device *drm;
> >> +	int ret;
> >> +
> >> +	dc_drm = devm_drm_dev_alloc(dev, &dc_drm_driver, struct dc_drm_device,
> >> +				    base);
> >> +	if (IS_ERR(dc_drm))
> >> +		return PTR_ERR(dc_drm);
> >> +
> >> +	drm = &dc_drm->base;
> >> +
> >> +	ret = component_bind_all(dev, dc_drm);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	ret = devm_add_action_or_reset(dev, dc_drm_component_unbind_all,
> >> +				       dc_drm);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	ret = dc_kms_init(dc_drm);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	ret = drm_dev_register(drm, 0);
> >> +	if (ret) {
> >> +		dev_err(dev, "failed to register drm device: %d\n", ret);
> >> +		goto err;
> >> +	}
> >> +
> >> +	drm_client_setup_with_fourcc(drm, DRM_FORMAT_XRGB8888);
> >> +
> >> +	priv->drm = drm;
> >> +
> >> +	return 0;
> >> +
> >> +err:
> >> +	dc_kms_uninit(dc_drm);
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +static void dc_drm_unbind(struct device *dev)
> >> +{
> >> +	struct dc_priv *priv = dev_get_drvdata(dev);
> >> +	struct dc_drm_device *dc_drm = to_dc_drm_device(priv->drm);
> >> +	struct drm_device *drm = &dc_drm->base;
> >> +	struct drm_crtc *crtc;
> >> +
> >> +	priv->drm = NULL;
> >> +	drm_dev_unplug(drm);
> >> +	dc_kms_uninit(dc_drm);
> >> +	drm_atomic_helper_shutdown(drm);
> >> +
> >> +	drm_for_each_crtc(crtc, drm)
> >> +		dc_crtc_disable_at_unbind(crtc);
> > 
> > There should be no need for that. drm_atomic_helper_shutdown() should
> > disable all the CRTCs.
> 
> In case DRM device is unplugged, drm_atomic_helper_shutdown does not
> effectively disable the CRTCs due to the bypassed logics wrapped by
> drm_dev_{enter,exit}.  That's why dc_crtc_disable_at_unbind() is called
> here to effectively disable the CRTCs.

I see. I haven't faced drm_dev_unplug() earlier. I checked, the "not
disabled" behaviour is documented and all other drivers don't perform
any kind of cleanup afterwards. Thus I think it's safe to drop the
dc_crtc_disable_at_unbind() unless it causes any kind of HW issues.

> 
> > 
> > Also, who is going to do drm_dev_unregister()? I don't see it in the
> > code.
> 
> drm_dev_unplug() right above calls drm_dev_unregister().
> 
> > 
> >> +}
> >> +
> >> +static const struct component_master_ops dc_drm_ops = {
> >> +	.bind = dc_drm_bind,
> >> +	.unbind = dc_drm_unbind,
> >> +};
> >> +
> >> +static int dc_probe(struct platform_device *pdev)
> >> +{
> >> +	struct component_match *match = NULL;
> >> +	struct dc_priv *priv;
> >> +	int ret;
> >> +
> >> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> >> +	if (!priv)
> >> +		return -ENOMEM;
> >> +
> >> +	priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
> >> +	if (IS_ERR(priv->clk_cfg))
> >> +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
> >> +				     "failed to get cfg clock\n");
> >> +
> >> +	dev_set_drvdata(&pdev->dev, priv);
> >> +
> >> +	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	ret = devm_pm_runtime_enable(&pdev->dev);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	ret = devm_of_platform_populate(&pdev->dev);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	dc_add_components(&pdev->dev, &match);
> >> +
> >> +	ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
> >> +	if (ret)
> >> +		return dev_err_probe(&pdev->dev, ret,
> >> +				     "failed to add component master\n");
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static void dc_remove(struct platform_device *pdev)
> >> +{
> >> +	component_master_del(&pdev->dev, &dc_drm_ops);
> >> +}
> >> +
> >> +static int dc_runtime_suspend(struct device *dev)
> >> +{
> >> +	struct dc_priv *priv = dev_get_drvdata(dev);
> >> +
> >> +	clk_disable_unprepare(priv->clk_cfg);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int dc_runtime_resume(struct device *dev)
> >> +{
> >> +	struct dc_priv *priv = dev_get_drvdata(dev);
> >> +	int ret;
> >> +
> >> +	ret = clk_prepare_enable(priv->clk_cfg);
> >> +	if (ret)
> >> +		dev_err(dev, "failed to enable cfg clock: %d\n", ret);
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +static int dc_suspend(struct device *dev)
> >> +{
> >> +	struct dc_priv *priv = dev_get_drvdata(dev);
> >> +
> >> +	return drm_mode_config_helper_suspend(priv->drm);
> >> +}
> >> +
> >> +static int dc_resume(struct device *dev)
> >> +{
> >> +	struct dc_priv *priv = dev_get_drvdata(dev);
> >> +
> >> +	return drm_mode_config_helper_resume(priv->drm);
> >> +}
> >> +
> >> +static void dc_shutdown(struct platform_device *pdev)
> >> +{
> >> +	struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
> >> +
> >> +	drm_atomic_helper_shutdown(priv->drm);
> >> +}
> >> +
> >> +static const struct dev_pm_ops dc_pm_ops = {
> >> +	RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
> >> +	SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
> >> +};
> >> +
> >> +static const struct of_device_id dc_dt_ids[] = {
> >> +	{ .compatible = "fsl,imx8qxp-dc", },
> >> +	{ /* sentinel */ }
> >> +};
> >> +MODULE_DEVICE_TABLE(of, dc_dt_ids);
> >> +
> >> +static struct platform_driver dc_driver = {
> >> +	.probe = dc_probe,
> >> +	.remove = dc_remove,
> >> +	.shutdown = dc_shutdown,
> >> +	.driver = {
> >> +		.name = "imx8-dc",
> >> +		.of_match_table	= dc_dt_ids,
> >> +		.pm = pm_sleep_ptr(&dc_pm_ops),
> >> +	},
> >> +};
> >> +
> >>  static struct platform_driver * const dc_drivers[] = {
> >>  	&dc_cf_driver,
> >>  	&dc_de_driver,
> >> @@ -19,6 +262,7 @@ static struct platform_driver * const dc_drivers[] = {
> >>  	&dc_lb_driver,
> >>  	&dc_pe_driver,
> >>  	&dc_tc_driver,
> >> +	&dc_driver,
> >>  };
> >>  
> >>  static int __init dc_drm_init(void)
> >> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
> >> index 3b11f4862c6c..39a771a13933 100644
> >> --- a/drivers/gpu/drm/imx/dc/dc-drv.h
> >> +++ b/drivers/gpu/drm/imx/dc/dc-drv.h
> >> @@ -6,19 +6,38 @@
> >>  #ifndef __DC_DRV_H__
> >>  #define __DC_DRV_H__
> >>  
> >> +#include <linux/container_of.h>
> >>  #include <linux/platform_device.h>
> >>  
> >>  #include <drm/drm_device.h>
> >> +#include <drm/drm_encoder.h>
> >>  
> >>  #include "dc-de.h"
> >> +#include "dc-kms.h"
> >>  #include "dc-pe.h"
> >>  
> >>  struct dc_drm_device {
> >>  	struct drm_device base;
> >> +	struct dc_crtc dc_crtc[DC_DISPLAYS];
> >> +	struct dc_plane dc_primary[DC_DISPLAYS];
> >> +	struct drm_encoder encoder[DC_DISPLAYS];
> >>  	struct dc_de *de[DC_DISPLAYS];
> >>  	struct dc_pe *pe;
> >>  };
> >>  
> >> +static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
> >> +{
> >> +	return container_of(drm, struct dc_drm_device, base);
> >> +}
> >> +
> >> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
> >> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
> >> +
> >> +int dc_kms_init(struct dc_drm_device *dc_drm);
> >> +void dc_kms_uninit(struct dc_drm_device *dc_drm);
> >> +
> >> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
> >> +
> >>  extern struct platform_driver dc_cf_driver;
> >>  extern struct platform_driver dc_ed_driver;
> >>  extern struct platform_driver dc_de_driver;
> >> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
> >> new file mode 100644
> >> index 000000000000..2b18aa37a4a8
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/imx/dc/dc-kms.c
> >> @@ -0,0 +1,143 @@
> >> +// SPDX-License-Identifier: GPL-2.0+
> >> +/*
> >> + * Copyright 2024 NXP
> >> + */
> >> +
> >> +#include <linux/of.h>
> >> +#include <linux/of_graph.h>
> >> +
> >> +#include <drm/drm_atomic_helper.h>
> >> +#include <drm/drm_bridge.h>
> >> +#include <drm/drm_bridge_connector.h>
> >> +#include <drm/drm_connector.h>
> >> +#include <drm/drm_crtc.h>
> >> +#include <drm/drm_device.h>
> >> +#include <drm/drm_encoder.h>
> >> +#include <drm/drm_gem_framebuffer_helper.h>
> >> +#include <drm/drm_mode_config.h>
> >> +#include <drm/drm_print.h>
> >> +#include <drm/drm_probe_helper.h>
> >> +#include <drm/drm_simple_kms_helper.h>
> >> +#include <drm/drm_vblank.h>
> >> +
> >> +#include "dc-de.h"
> >> +#include "dc-drv.h"
> >> +#include "dc-kms.h"
> >> +
> >> +static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
> >> +	.fb_create = drm_gem_fb_create,
> >> +	.atomic_check = drm_atomic_helper_check,
> >> +	.atomic_commit = drm_atomic_helper_commit,
> >> +};
> >> +
> >> +static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
> >> +					int crtc_index)
> >> +{
> >> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> >> +	struct drm_device *drm = &dc_drm->base;
> >> +	struct drm_crtc *crtc = &dc_crtc->base;
> >> +	struct drm_connector *connector;
> >> +	struct device *dev = drm->dev;
> >> +	struct drm_encoder *encoder;
> >> +	struct drm_bridge *bridge;
> >> +	int ret;
> >> +
> >> +	bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
> >> +					0, 0);
> >> +	if (IS_ERR(bridge)) {
> >> +		ret = PTR_ERR(bridge);
> >> +		if (ret == -ENODEV)
> >> +			return 0;
> >> +
> >> +		return dev_err_probe(dev, ret,
> >> +				     "failed to find bridge for CRTC%u\n",
> >> +				     crtc->index);
> >> +	}
> >> +
> >> +	encoder = &dc_drm->encoder[crtc_index];
> >> +	ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
> >> +	if (ret) {
> >> +		dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
> >> +			crtc->index, ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	encoder->possible_crtcs = drm_crtc_mask(crtc);
> >> +
> >> +	ret = drm_bridge_attach(encoder, bridge, NULL,
> >> +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >> +	if (ret) {
> >> +		dev_err(dev,
> >> +			"failed to attach bridge to encoder for CRTC%u: %d\n",
> >> +			crtc->index, ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	connector = drm_bridge_connector_init(drm, encoder);
> >> +	if (IS_ERR(connector)) {
> >> +		ret = PTR_ERR(connector);
> >> +		dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
> >> +			crtc->index, ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = drm_connector_attach_encoder(connector, encoder);
> >> +	if (ret)
> >> +		dev_err(dev,
> >> +			"failed to attach encoder to connector for CRTC%u: %d\n",
> >> +			crtc->index, ret);
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +int dc_kms_init(struct dc_drm_device *dc_drm)
> >> +{
> >> +	struct drm_device *drm = &dc_drm->base;
> >> +	int ret, i;
> >> +
> >> +	ret = drmm_mode_config_init(drm);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	drm->mode_config.min_width = 60;
> >> +	drm->mode_config.min_height = 60;
> >> +	drm->mode_config.max_width = 8192;
> >> +	drm->mode_config.max_height = 8192;
> >> +	drm->mode_config.funcs = &dc_drm_mode_config_funcs;
> >> +
> >> +	drm->vblank_disable_immediate = true;
> >> +	drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
> >> +
> >> +	for (i = 0; i < DC_DISPLAYS; i++) {
> >> +		ret = dc_crtc_init(dc_drm, i);
> >> +		if (ret)
> >> +			return ret;
> >> +
> >> +		ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
> >> +		if (ret)
> >> +			return ret;
> >> +	}
> >> +
> >> +	for (i = 0; i < DC_DISPLAYS; i++) {
> >> +		ret = dc_crtc_post_init(dc_drm, i);
> > 
> > Can you use .late_register for this?
> 
> Kerneldoc of struct drm_crtc_funcs::late_register says it's used to register
> additional userspace interfaces like debugfs interfaces. And, it seems that
> everyone implementing this uses it to add debugfs interfaces. So, it will
> kind of abuse it to do CRTC post initialization.

Why can't they be requested earlier then?

> 
> > 
> >> +		if (ret)
> >> +			return ret;
> >> +	}
> >> +
> >> +	ret = drm_vblank_init(drm, DC_DISPLAYS);
> >> +	if (ret) {
> >> +		dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	drm_mode_config_reset(drm);
> >> +
> >> +	drm_kms_helper_poll_init(drm);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +void dc_kms_uninit(struct dc_drm_device *dc_drm)
> >> +{
> >> +	drm_kms_helper_poll_fini(&dc_drm->base);
> >> +}
> >> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
> >> new file mode 100644
> >> index 000000000000..57f6e0c15f57
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/imx/dc/dc-kms.h
> >> @@ -0,0 +1,58 @@
> >> +/* SPDX-License-Identifier: GPL-2.0+ */
> >> +/*
> >> + * Copyright 2024 NXP
> >> + */
> >> +
> >> +#ifndef __DC_KMS_H__
> >> +#define __DC_KMS_H__
> >> +
> >> +#include <linux/completion.h>
> >> +
> >> +#include <drm/drm_crtc.h>
> >> +#include <drm/drm_plane.h>
> >> +#include <drm/drm_vblank.h>
> >> +
> >> +#include "dc-de.h"
> >> +#include "dc-fu.h"
> >> +#include "dc-pe.h"
> >> +
> >> +#define DC_CRTC_IRQS	5
> >> +
> >> +struct dc_crtc_irq {
> >> +	struct dc_crtc *dc_crtc;
> >> +	unsigned int irq;
> >> +};
> >> +
> > 
> > Please provide some documentation for the structure in the form of the
> > kerneldoc. E.g. what is the difference between ed_cont and ed_safe?
> 
> Will add kerneldoc for struct dc_{crtc,plane,drm_device} and tell the
> difference between ed_cont(content stream) and ed_safe(safety stream).
> 
> > The de and fg pointers are global, please don't cache them
> > unnecessarily.
> 
> Global? I don't catch your meaning, sorry. To me, it's handy to access de
> and fg via the two pointers in struct dc_crtc.

I had to spend some time understanding if they are per-CRTC or if there
are a single instances of those subdevices. Thus I suggest to access
them through dc_drm_device. You can ignore this suggestion though.

> 
> > 
> >> +struct dc_crtc {
> >> +	struct drm_crtc base;
> >> +	struct dc_de *de;
> >> +	struct dc_pe *pe;
> >> +	struct dc_cf *cf_cont;
> >> +	struct dc_cf *cf_safe;
> >> +	struct dc_ed *ed_cont;
> >> +	struct dc_ed *ed_safe;
> >> +	struct dc_fg *fg;
> >> +	unsigned int irq_dec_framecomplete;
> >> +	unsigned int irq_dec_seqcomplete;
> >> +	unsigned int irq_dec_shdld;
> >> +	unsigned int irq_ed_cont_shdld;
> >> +	unsigned int irq_ed_safe_shdld;
> >> +	struct completion dec_seqcomplete_done;
> >> +	struct completion dec_shdld_done;
> >> +	struct completion ed_safe_shdld_done;
> >> +	struct completion ed_cont_shdld_done;
> >> +	struct drm_pending_vblank_event *event;
> >> +	struct dc_crtc_irq irqs[DC_CRTC_IRQS];
> >> +};
> >> +
> >> +struct dc_plane {
> >> +	struct drm_plane base;
> >> +	struct dc_fu *fu;
> >> +	struct dc_cf *cf;
> >> +	struct dc_lb *lb;
> >> +	struct dc_ed *ed;
> >> +};
> >> +
> >> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc);
> >> +
> >> +#endif /* __DC_KMS_H__ */
> >> diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
> >> new file mode 100644
> >> index 000000000000..78d0d2cd3451
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/imx/dc/dc-plane.c
> >> @@ -0,0 +1,241 @@
> >> +// SPDX-License-Identifier: GPL-2.0+
> >> +/*
> >> + * Copyright 2024 NXP
> >> + */
> >> +
> >> +#include <linux/container_of.h>
> >> +
> >> +#include <drm/drm_atomic.h>
> >> +#include <drm/drm_atomic_helper.h>
> >> +#include <drm/drm_atomic_state_helper.h>
> >> +#include <drm/drm_crtc.h>
> >> +#include <drm/drm_drv.h>
> >> +#include <drm/drm_fb_dma_helper.h>
> >> +#include <drm/drm_fourcc.h>
> >> +#include <drm/drm_framebuffer.h>
> >> +#include <drm/drm_gem_atomic_helper.h>
> >> +#include <drm/drm_plane_helper.h>
> >> +#include <drm/drm_print.h>
> >> +
> >> +#include "dc-drv.h"
> >> +#include "dc-fu.h"
> >> +#include "dc-kms.h"
> >> +
> >> +#define DC_PLANE_MAX_PITCH	0x10000
> >> +#define DC_PLANE_MAX_PIX_CNT	8192
> >> +
> >> +#define dc_plane_dbg(plane, fmt, ...)					\
> >> +do {									\
> >> +	typeof(plane) _plane = (plane);					\
> >> +	drm_dbg_kms(_plane->dev, "[PLANE:%d:%s] " fmt,			\
> >> +		    _plane->base.id, _plane->name, ##__VA_ARGS__);	\
> >> +} while (0)
> >> +
> >> +static const uint32_t dc_plane_formats[] = {
> >> +	DRM_FORMAT_XRGB8888,
> >> +};
> >> +
> >> +static const struct drm_plane_funcs dc_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,
> >> +};
> >> +
> >> +static inline struct dc_plane *to_dc_plane(struct drm_plane *plane)
> >> +{
> >> +	return container_of(plane, struct dc_plane, base);
> >> +}
> >> +
> >> +static int dc_plane_check_no_off_screen(struct drm_plane_state *state,
> >> +					struct drm_crtc_state *crtc_state)
> >> +{
> >> +	if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
> >> +	    state->dst.x2 > crtc_state->adjusted_mode.hdisplay ||
> >> +	    state->dst.y2 > crtc_state->adjusted_mode.vdisplay) {
> >> +		dc_plane_dbg(state->plane, "no off screen\n");
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int dc_plane_check_max_source_resolution(struct drm_plane_state *state)
> >> +{
> >> +	int src_h = drm_rect_height(&state->src) >> 16;
> >> +	int src_w = drm_rect_width(&state->src) >> 16;
> >> +
> >> +	if (src_w > DC_PLANE_MAX_PIX_CNT || src_h > DC_PLANE_MAX_PIX_CNT) {
> >> +		dc_plane_dbg(state->plane, "invalid source resolution\n");
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int dc_plane_check_fb(struct drm_plane_state *state)
> >> +{
> >> +	struct drm_framebuffer *fb = state->fb;
> >> +	dma_addr_t baseaddr = drm_fb_dma_get_gem_addr(fb, state, 0);
> >> +
> >> +	/* base address alignment */
> >> +	if (baseaddr & 0x3) {
> >> +		dc_plane_dbg(state->plane, "fb bad baddr alignment\n");
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	/* pitches[0] range */
> >> +	if (fb->pitches[0] > DC_PLANE_MAX_PITCH) {
> >> +		dc_plane_dbg(state->plane, "fb pitches[0] is out of range\n");
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	/* pitches[0] alignment */
> >> +	if (fb->pitches[0] & 0x3) {
> >> +		dc_plane_dbg(state->plane, "fb bad pitches[0] alignment\n");
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int
> >> +dc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
> >> +{
> >> +	struct drm_plane_state *plane_state =
> >> +				drm_atomic_get_new_plane_state(state, plane);
> >> +	struct drm_crtc_state *crtc_state;
> >> +	int ret;
> >> +
> >> +	/* ok to disable */
> >> +	if (!plane_state->fb)
> >> +		return 0;
> >> +
> >> +	if (!plane_state->crtc) {
> >> +		dc_plane_dbg(plane, "no CRTC in plane state\n");
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	crtc_state =
> >> +		drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
> >> +	if (WARN_ON(!crtc_state))
> >> +		return -EINVAL;
> >> +
> >> +	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
> >> +						  DRM_PLANE_NO_SCALING,
> >> +						  DRM_PLANE_NO_SCALING,
> >> +						  true, false);
> >> +	if (ret) {
> >> +		dc_plane_dbg(plane, "failed to check plane state: %d\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	ret = dc_plane_check_no_off_screen(plane_state, crtc_state);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	ret = dc_plane_check_max_source_resolution(plane_state);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	return dc_plane_check_fb(plane_state);
> >> +}
> >> +
> >> +static void
> >> +dc_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state)
> >> +{
> >> +	struct drm_plane_state *new_state =
> >> +				drm_atomic_get_new_plane_state(state, plane);
> >> +	struct dc_plane *dplane = to_dc_plane(plane);
> >> +	struct drm_framebuffer *fb = new_state->fb;
> >> +	const struct dc_fu_ops *fu_ops;
> >> +	struct dc_lb *lb = dplane->lb;
> >> +	struct dc_fu *fu = dplane->fu;
> >> +	dma_addr_t baseaddr;
> >> +	int src_w, src_h;
> >> +	int idx;
> >> +
> >> +	if (!drm_dev_enter(plane->dev, &idx))
> >> +		return;
> >> +
> >> +	src_w = drm_rect_width(&new_state->src) >> 16;
> >> +	src_h = drm_rect_height(&new_state->src) >> 16;
> >> +
> >> +	baseaddr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
> >> +
> >> +	fu_ops = dc_fu_get_ops(dplane->fu);
> >> +
> >> +	fu_ops->set_layerblend(fu, lb);
> >> +	fu_ops->set_burstlength(fu, baseaddr);
> >> +	fu_ops->set_src_stride(fu, DC_FETCHUNIT_FRAC0, fb->pitches[0]);
> >> +	fu_ops->set_src_buf_dimensions(fu, DC_FETCHUNIT_FRAC0, src_w, src_h);
> >> +	fu_ops->set_fmt(fu, DC_FETCHUNIT_FRAC0, fb->format);
> >> +	fu_ops->set_framedimensions(fu, src_w, src_h);
> >> +	fu_ops->set_baseaddress(fu, DC_FETCHUNIT_FRAC0, baseaddr);
> >> +	fu_ops->enable_src_buf(fu, DC_FETCHUNIT_FRAC0);
> >> +
> >> +	dc_plane_dbg(plane, "uses %s\n", fu_ops->get_name(fu));
> >> +
> >> +	dc_lb_pec_dynamic_prim_sel(lb, dc_cf_get_link_id(dplane->cf));
> >> +	dc_lb_pec_dynamic_sec_sel(lb, fu_ops->get_link_id(fu));
> >> +	dc_lb_mode(lb, LB_BLEND);
> >> +	dc_lb_position(lb, new_state->dst.x1, new_state->dst.y1);
> >> +	dc_lb_pec_clken(lb, CLKEN_AUTOMATIC);
> >> +
> >> +	dc_plane_dbg(plane, "uses LayerBlend%u\n", dc_lb_get_id(lb));
> >> +
> >> +	/* set ExtDst's source to LayerBlend */
> >> +	dc_ed_pec_src_sel(dplane->ed, dc_lb_get_link_id(lb));
> >> +
> >> +	drm_dev_exit(idx);
> >> +}
> >> +
> >> +static void dc_plane_atomic_disable(struct drm_plane *plane,
> >> +				    struct drm_atomic_state *state)
> >> +{
> >> +	struct dc_plane *dplane = to_dc_plane(plane);
> >> +	const struct dc_fu_ops *fu_ops;
> >> +	int idx;
> >> +
> >> +	if (!drm_dev_enter(plane->dev, &idx))
> >> +		return;
> >> +
> >> +	/* disable fetchunit in shadow */
> >> +	fu_ops = dc_fu_get_ops(dplane->fu);
> >> +	fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
> >> +
> >> +	/* set ExtDst's source to ConstFrame */
> >> +	dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
> >> +
> >> +	drm_dev_exit(idx);
> >> +}
> >> +
> >> +static const struct drm_plane_helper_funcs dc_plane_helper_funcs = {
> >> +	.atomic_check = dc_plane_atomic_check,
> >> +	.atomic_update = dc_plane_atomic_update,
> >> +	.atomic_disable = dc_plane_atomic_disable,
> >> +};
> >> +
> >> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
> >> +{
> >> +	struct drm_plane *plane = &dc_plane->base;
> >> +	int ret;
> >> +
> >> +	ret = drm_universal_plane_init(&dc_drm->base, plane, 0, &dc_plane_funcs,
> >> +				       dc_plane_formats,
> >> +				       ARRAY_SIZE(dc_plane_formats),
> >> +				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	drm_plane_helper_add(plane, &dc_plane_helper_funcs);
> >> +
> >> +	dc_plane->fu = dc_drm->pe->fu_disp[plane->index];
> >> +	dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
> >> +	dc_plane->lb = dc_drm->pe->lb[plane->index];
> >> +	dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
> >> +
> >> +	return 0;
> >> +}
> >> -- 
> >> 2.34.1
> >>
> > 
> 
> -- 
> Regards,
> Liu Ying

-- 
With best wishes
Dmitry


From will at kernel.org  Wed Dec 11 15:44:14 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 23:44:14 +0000
Subject: [PATCH RESEND kvmtool 0/4] arm: Payload memory layout change
In-Reply-To: <20241128151246.10858-1-alexandru.elisei@arm.com>
References: <20241128151246.10858-1-alexandru.elisei@arm.com>
Message-ID: <173395873873.2737640.3783988676491071650.b4-ty@kernel.org>

On Thu, 28 Nov 2024 15:12:42 +0000, Alexandru Elisei wrote:
> (resending because I accidently only sent the cover letter, sorry for that)
> 
> The first 3 patches are fixes to kvm__arch_load_kernel_image(). I've CC'ed
> the riscv maintainer because it looks to me like riscv is similarly
> affected.
> 
> Patch #4 ("arm64: Increase the payload memory region size to 512MB") might
> be controversial. Follows a bug report I received from Abdollahi Sina in
> private. Details in the commit message, but the gist of the patch is that
> the memory region where kernel + initrd + DTB are copied to are changed
> from 256MB to 512MB.  As a result, the DTB and initrd are moved from below
> ram_start + 256MB to ram_start + 512MB to accomodate a larger initrd.  If
> users rely on finding the DTB and initrd at the current addresses, then I'm
> not sure the patch is justified - after all, if someone really wants to use
> such a large initrd instead of a disk image with virtio, then replacing
> SZ_256M with SZ_512M locally doesn't look like a big ask.
> 
> [...]

Applied to arm64 (sina), thanks!

[1/4] arm: Fix off-by-one errors when computing payload memory layout
      https://git.kernel.org/arm64/c/167aa1e
[2/4] arm: Check return value for host_to_guest_flat()
      https://git.kernel.org/arm64/c/ca57fb6
[3/4] arm64: Use the kernel header image_size when loading into memory
      https://git.kernel.org/arm64/c/32345de
[4/4] arm64: Increase the payload memory region size to 512MB
      https://git.kernel.org/arm64/c/9b26a8e

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From kaleshsingh at google.com  Wed Dec 11 15:27:38 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:38 -0800
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
Message-ID: <20241211232754.1583023-1-kaleshsingh@google.com>

Hi all,

This is v2 othe the arch_mmap_hint() series.

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate most of the error handling in arch_mmap_hint().
  - Patch 16 ("mm: Fallback to generic_mmap_hint()") was folded into
    Patch 2 ("mm: x86: Introduce arch_mmap_hint()")

v1: https://lore.kernel.org/r/20241210024119.2488608-1-kaleshsingh at google.com/

=======

This series introduces arch_mmap_hint() to handle allocating VA space
for the hint address.

Patches 1-16 introduce this new helper and Patch 17 uses it to fix the
issue of mmap hint being ignored in some cases due to THP alignment [1]

[1] https://lore.kernel.org/r/20241118214650.3667577-1-kaleshsingh at google.com/

Thanks,
Kalesh


Kalesh Singh (16):
  mm: Introduce generic_mmap_hint()
  mm: x86: Introduce arch_mmap_hint()
  mm: arm: Introduce arch_mmap_hint()
  mm: alpha: Introduce arch_mmap_hint()
  mm: arc: Use generic_mmap_hint()
  mm: csky: Introduce arch_mmap_hint()
  mm: loongarch: Introduce arch_mmap_hint()
  mm: mips: Introduce arch_align_mmap_hint()
  mm: parisc: Introduce arch_align_mmap_hint()
  mm: s390: Use generic_mmap_hint()
  mm: sh: Introduce arch_mmap_hint()
  mm: sparc32: Introduce arch_mmap_hint()
  mm: sparc64: Introduce arch_mmap_hint()
  mm: xtensa: Introduce arch_mmap_hint()
  mm: powerpc: Introduce arch_mmap_hint()
  mm: Respect mmap hint before THP alignment if allocation is possible

 arch/alpha/include/asm/pgtable.h           |   1 +
 arch/alpha/kernel/osf_sys.c                |  31 +++---
 arch/arc/include/asm/pgtable.h             |   1 +
 arch/arc/mm/mmap.c                         |  43 +++++----
 arch/arm/include/asm/pgtable.h             |   1 +
 arch/arm/mm/mmap.c                         | 107 +++++++++------------
 arch/csky/abiv1/inc/abi/pgtable-bits.h     |   1 +
 arch/csky/abiv1/mmap.c                     |  68 +++++++------
 arch/loongarch/include/asm/pgtable.h       |   1 +
 arch/loongarch/mm/mmap.c                   |  49 +++++-----
 arch/mips/include/asm/pgtable.h            |   1 +
 arch/mips/mm/mmap.c                        |  50 +++++-----
 arch/parisc/include/asm/pgtable.h          |   1 +
 arch/parisc/kernel/sys_parisc.c            |  53 +++++-----
 arch/powerpc/include/asm/book3s/64/slice.h |   1 +
 arch/powerpc/mm/book3s64/slice.c           |  31 ++++++
 arch/s390/include/asm/pgtable.h            |   1 +
 arch/s390/mm/mmap.c                        |  51 +++++-----
 arch/sh/include/asm/pgtable.h              |   1 +
 arch/sh/mm/mmap.c                          |  83 ++++++----------
 arch/sparc/include/asm/pgtable_32.h        |   1 +
 arch/sparc/include/asm/pgtable_64.h        |   1 +
 arch/sparc/kernel/sys_sparc_32.c           |  33 ++++---
 arch/sparc/kernel/sys_sparc_64.c           |  96 +++++++-----------
 arch/x86/include/asm/pgtable_64.h          |   1 +
 arch/x86/kernel/sys_x86_64.c               |  64 ++++++------
 arch/xtensa/kernel/syscall.c               |  31 ++++--
 include/linux/sched/mm.h                   |   9 ++
 mm/huge_memory.c                           |  17 ++--
 mm/mmap.c                                  |  86 +++++++++++------
 30 files changed, 491 insertions(+), 424 deletions(-)

-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:39 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:39 -0800
Subject: [PATCH mm-unstable v2 01/16] mm: Introduce generic_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-2-kaleshsingh@google.com>

Consolidate the hint searches from both directions (topdown and
bottomup) into generic_mmap_hint().

No functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 include/linux/sched/mm.h |  4 +++
 mm/mmap.c                | 76 ++++++++++++++++++++++++----------------
 2 files changed, 50 insertions(+), 30 deletions(-)

diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index 928a626725e6..edeec19d1708 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -201,6 +201,10 @@ unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm,
 					   unsigned long flags,
 					   vm_flags_t vm_flags);
 
+unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
+				unsigned long len, unsigned long pgoff,
+				unsigned long flags);
+
 unsigned long
 generic_get_unmapped_area(struct file *filp, unsigned long addr,
 			  unsigned long len, unsigned long pgoff,
diff --git a/mm/mmap.c b/mm/mmap.c
index df9154b15ef9..382b4eac5406 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -620,6 +620,47 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)
 	return addr;
 }
 
+/*
+ * Look up unmapped area at the requested hint addr
+ *
+ * NOTE: MAP_FIXED is also handled here since it's a special case of
+ * enforcing the hint address.
+ *
+ * Returns:
+ *    ERR_VALUE: If the requested mapping is not valid
+ *    0: If there isn't a sufficiently large hole at the hint addr.
+ *    addr: If sufficient VA space is available at the hint address;
+ *          or MAP_FIXED was specified.
+ */
+unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
+				unsigned long len, unsigned long pgoff,
+				unsigned long flags)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma, *prev;
+	const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
+
+	/* requested length too big for entire address space */
+	if (len > mmap_end - mmap_min_addr)
+		return -ENOMEM;
+
+	if (flags & MAP_FIXED)
+		return addr;
+
+	if (!addr)
+		return 0;
+
+	addr = PAGE_ALIGN(addr);
+	vma = find_vma_prev(mm, addr, &prev);
+	if (mmap_end - len >= addr && addr >= mmap_min_addr &&
+	    (!vma || addr + len <= vm_start_gap(vma)) &&
+	    (!prev || addr >= vm_end_gap(prev)))
+		return addr;
+
+	/* Fallback to VA space search */
+	return 0;
+}
+
 /* Get an address range which is currently unmapped.
  * For shmat() with addr=0.
  *
@@ -637,25 +678,13 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
 			  unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma, *prev;
 	struct vm_unmapped_area_info info = {};
 	const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
 
-	if (len > mmap_end - mmap_min_addr)
-		return -ENOMEM;
-
-	if (flags & MAP_FIXED)
+	addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
 		return addr;
 
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma_prev(mm, addr, &prev);
-		if (mmap_end - len >= addr && addr >= mmap_min_addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)) &&
-		    (!prev || addr >= vm_end_gap(prev)))
-			return addr;
-	}
-
 	info.length = len;
 	info.low_limit = mm->mmap_base;
 	info.high_limit = mmap_end;
@@ -685,27 +714,14 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 				  unsigned long len, unsigned long pgoff,
 				  unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma, *prev;
 	struct mm_struct *mm = current->mm;
 	struct vm_unmapped_area_info info = {};
 	const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
 
-	/* requested length too big for entire address space */
-	if (len > mmap_end - mmap_min_addr)
-		return -ENOMEM;
-
-	if (flags & MAP_FIXED)
-		return addr;
-
 	/* requesting a specific address */
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma_prev(mm, addr, &prev);
-		if (mmap_end - len >= addr && addr >= mmap_min_addr &&
-				(!vma || addr + len <= vm_start_gap(vma)) &&
-				(!prev || addr >= vm_end_gap(prev)))
-			return addr;
-	}
+	addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:40 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:40 -0800
Subject: [PATCH mm-unstable v2 02/16] mm: x86: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-3-kaleshsingh@google.com>

Introduce x86 arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Fallback to generic_mmap_hint() if an architecture doesn't
provide HAVE_ARCH_MMAP_HINT.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate most of the error handling in arch_mmap_hint().
  - Fallback to generic_mmap_hint() if arch_mmap_hint() is not provided.

 arch/x86/include/asm/pgtable_64.h |  1 +
 arch/x86/kernel/sys_x86_64.c      | 64 +++++++++++++++----------------
 include/linux/sched/mm.h          |  5 +++
 mm/mmap.c                         |  9 +++++
 4 files changed, 45 insertions(+), 34 deletions(-)

diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index d1426b64c1b9..4472fd0040c3 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -245,6 +245,7 @@ extern void cleanup_highmap(void);
 
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #define PAGE_AGP    PAGE_KERNEL_NOCACHE
 #define HAVE_PAGE_AGP 1
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 776ae6fa7f2d..008c6d19bd02 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -123,31 +123,44 @@ static inline unsigned long stack_guard_placement(vm_flags_t vm_flags)
 	return 0;
 }
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	unsigned long begin, end;
+
+	find_start_end(addr, flags, &begin, &end);
+
+	/* requested length too big for entire address space */
+	if (len > end || len > TASK_SIZE)
+		return -ENOMEM;
+
+	/* No address checking. See comment at mmap_address_hint_valid() */
+	if (flags & MAP_FIXED)
+		return addr;
+
+	addr = PAGE_ALIGN(addr);
+
+	/* Fallback to VA space search? */
+	if (!mmap_address_hint_valid(addr, len))
+		return 0;
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 unsigned long
 arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
 		       unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
 {
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	struct vm_unmapped_area_info info = {};
 	unsigned long begin, end;
 
-	if (flags & MAP_FIXED)
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
 		return addr;
 
 	find_start_end(addr, flags, &begin, &end);
 
-	if (len > end)
-		return -ENOMEM;
-
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (end - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
-
 	info.length = len;
 	info.low_limit = begin;
 	info.high_limit = end;
@@ -168,34 +181,17 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
 			  unsigned long len, unsigned long pgoff,
 			  unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma;
-	struct mm_struct *mm = current->mm;
 	unsigned long addr = addr0;
 	struct vm_unmapped_area_info info = {};
 
-	/* requested length too big for entire address space */
-	if (len > TASK_SIZE)
-		return -ENOMEM;
-
-	/* No address checking. See comment at mmap_address_hint_valid() */
-	if (flags & MAP_FIXED)
-		return addr;
-
 	/* for MAP_32BIT mappings we force the legacy mmap base */
 	if (!in_32bit_syscall() && (flags & MAP_32BIT))
 		goto bottomup;
 
 	/* requesting a specific address */
-	if (addr) {
-		addr &= PAGE_MASK;
-		if (!mmap_address_hint_valid(addr, len))
-			goto get_unmapped_area;
-
-		vma = find_vma(mm, addr);
-		if (!vma || addr + len <= vm_start_gap(vma))
-			return addr;
-	}
-get_unmapped_area:
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index edeec19d1708..f4143703f234 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -205,6 +205,11 @@ unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
 				unsigned long len, unsigned long pgoff,
 				unsigned long flags);
 
+/* See generic_mmap_hint() */
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags);
+
 unsigned long
 generic_get_unmapped_area(struct file *filp, unsigned long addr,
 			  unsigned long len, unsigned long pgoff,
diff --git a/mm/mmap.c b/mm/mmap.c
index 382b4eac5406..76dd6acdf051 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -705,6 +705,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 }
 #endif
 
+#ifndef HAVE_ARCH_MMAP_HINT
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+				      unsigned long len, unsigned long pgoff,
+				      unsigned long flags)
+{
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+#endif
+
 /*
  * This mmap-allocator allocates new areas top-down from below the
  * stack's low limit (the base):
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:41 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:41 -0800
Subject: [PATCH mm-unstable v2 03/16] mm: arm: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-4-kaleshsingh@google.com>

Introduce arm arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/arm/include/asm/pgtable.h |   1 +
 arch/arm/mm/mmap.c             | 107 ++++++++++++++-------------------
 2 files changed, 46 insertions(+), 62 deletions(-)

diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index be91e376df79..1433b3ff4caa 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -330,6 +330,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 3dbb383c26d5..15e7e4348af7 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -17,6 +17,41 @@
 	((((addr)+SHMLBA-1)&~(SHMLBA-1)) +	\
 	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	bool aliasing = cache_is_vipt_aliasing();
+	bool do_align;
+
+	/* requested length too big for entire address space */
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	/*
+	 * We enforce the MAP_FIXED case.
+	 */
+	if (flags & MAP_FIXED) {
+		if (aliasing && flags & MAP_SHARED &&
+		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
+			return -EINVAL;
+		return addr;
+	}
+
+	/*
+	 * We only need to do colour alignment if either the I or D
+	 * caches alias.
+	 */
+	do_align = aliasing && (filp || (flags & MAP_SHARED));
+
+	if (do_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 /*
  * We need to ensure that shared mappings are correctly aligned to
  * avoid aliasing issues with VIPT caches.  We need to ensure that
@@ -32,42 +67,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	int do_align = 0;
-	int aliasing = cache_is_vipt_aliasing();
 	struct vm_unmapped_area_info info = {};
+	bool aliasing = cache_is_vipt_aliasing();
+	bool do_align;
 
-	/*
-	 * We only need to do colour alignment if either the I or D
-	 * caches alias.
-	 */
-	if (aliasing)
-		do_align = filp || (flags & MAP_SHARED);
-
-	/*
-	 * We enforce the MAP_FIXED case.
-	 */
-	if (flags & MAP_FIXED) {
-		if (aliasing && flags & MAP_SHARED &&
-		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
-			return -EINVAL;
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
 		return addr;
-	}
-
-	if (len > TASK_SIZE)
-		return -ENOMEM;
 
-	if (addr) {
-		if (do_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	do_align = aliasing && (filp || (flags & MAP_SHARED));
 
 	info.length = len;
 	info.low_limit = mm->mmap_base;
@@ -82,42 +90,17 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 		        const unsigned long len, const unsigned long pgoff,
 		        const unsigned long flags, vm_flags_t vm_flags)
 {
-	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
 	unsigned long addr = addr0;
-	int do_align = 0;
-	int aliasing = cache_is_vipt_aliasing();
 	struct vm_unmapped_area_info info = {};
+	bool aliasing = cache_is_vipt_aliasing();
+	bool do_align;
 
-	/*
-	 * We only need to do colour alignment if either the I or D
-	 * caches alias.
-	 */
-	if (aliasing)
-		do_align = filp || (flags & MAP_SHARED);
-
-	/* requested length too big for entire address space */
-	if (len > TASK_SIZE)
-		return -ENOMEM;
-
-	if (flags & MAP_FIXED) {
-		if (aliasing && flags & MAP_SHARED &&
-		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
-			return -EINVAL;
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
 		return addr;
-	}
 
-	/* requesting a specific address */
-	if (addr) {
-		if (do_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-				(!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	do_align = aliasing && (filp || (flags & MAP_SHARED));
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:42 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:42 -0800
Subject: [PATCH mm-unstable v2 04/16] mm: alpha: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-5-kaleshsingh@google.com>

Introduce alpha arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - Consolidate error handling in arch_mmap_hint().

 arch/alpha/include/asm/pgtable.h |  1 +
 arch/alpha/kernel/osf_sys.c      | 31 ++++++++++++++++++++-----------
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h
index 635f0a5f5bbd..372885a01abd 100644
--- a/arch/alpha/include/asm/pgtable.h
+++ b/arch/alpha/include/asm/pgtable.h
@@ -362,5 +362,6 @@ extern void paging_init(void);
 
 /* We have our own get_unmapped_area to cope with ADDR_LIMIT_32BIT.  */
 #define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* _ALPHA_PGTABLE_H */
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 86185021f75a..308f832732dc 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -1225,10 +1225,9 @@ arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
 	return vm_unmapped_area(&info);
 }
 
-unsigned long
-arch_get_unmapped_area(struct file *filp, unsigned long addr,
-		       unsigned long len, unsigned long pgoff,
-		       unsigned long flags, vm_flags_t vm_flags)
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
 {
 	unsigned long limit;
 
@@ -1241,8 +1240,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	if (len > limit)
 		return -ENOMEM;
 
-	if (flags & MAP_FIXED)
-		return addr;
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
+unsigned long
+arch_get_unmapped_area(struct file *filp, unsigned long addr,
+		       unsigned long len, unsigned long pgoff,
+		       unsigned long flags, vm_flags_t vm_flags)
+{
+	unsigned long limit;
 
 	/* First, see if the given suggestion fits.
 
@@ -1253,12 +1259,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	   That said, I can see the use in being able to suggest not
 	   merely specific addresses, but regions of memory -- perhaps
 	   this feature should be incorporated into all ports?  */
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
 
-	if (addr) {
-		addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
-		if (addr != (unsigned long) -ENOMEM)
-			return addr;
-	}
+	/* "32 bit" actually means 31 bit, since pointers sign extend.  */
+	if (current->personality & ADDR_LIMIT_32BIT)
+		limit = 0x80000000;
+	else
+		limit = TASK_SIZE;
 
 	/* Next, try allocating at TASK_UNMAPPED_BASE.  */
 	addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:44 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:44 -0800
Subject: [PATCH mm-unstable v2 06/16] mm: csky: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-7-kaleshsingh@google.com>

Introduce csky arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/csky/abiv1/inc/abi/pgtable-bits.h |  1 +
 arch/csky/abiv1/mmap.c                 | 68 ++++++++++++++------------
 2 files changed, 38 insertions(+), 31 deletions(-)

diff --git a/arch/csky/abiv1/inc/abi/pgtable-bits.h b/arch/csky/abiv1/inc/abi/pgtable-bits.h
index ae7a2f76dd42..c346a9fcb522 100644
--- a/arch/csky/abiv1/inc/abi/pgtable-bits.h
+++ b/arch/csky/abiv1/inc/abi/pgtable-bits.h
@@ -51,5 +51,6 @@
 					((offset) << 10)})
 
 #define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* __ASM_CSKY_PGTABLE_BITS_H */
diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c
index 1047865e82a9..0c5c51a081e4 100644
--- a/arch/csky/abiv1/mmap.c
+++ b/arch/csky/abiv1/mmap.c
@@ -13,6 +13,39 @@
 	((((addr)+SHMLBA-1)&~(SHMLBA-1)) +	\
 	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
 
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
+{
+	bool do_align;
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	/*
+	 * We only need to do colour alignment if either the I or D
+	 * caches alias.
+	 */
+	do_align = filp || (flags & MAP_SHARED);
+
+	/*
+	 * We enforce the MAP_FIXED case.
+	 */
+	if (flags & MAP_FIXED) {
+		if (flags & MAP_SHARED &&
+		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (do_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
 /*
  * We need to ensure that shared mappings are correctly aligned to
  * avoid aliasing issues with VIPT caches.  We need to ensure that
@@ -27,8 +60,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		unsigned long flags, vm_flags_t vm_flags)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	int do_align = 0;
+	bool do_align;
 	struct vm_unmapped_area_info info = {
 		.length = len,
 		.low_limit = mm->mmap_base,
@@ -36,37 +68,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		.align_offset = pgoff << PAGE_SHIFT
 	};
 
-	/*
-	 * We only need to do colour alignment if either the I or D
-	 * caches alias.
-	 */
-	do_align = filp || (flags & MAP_SHARED);
-
-	/*
-	 * We enforce the MAP_FIXED case.
-	 */
-	if (flags & MAP_FIXED) {
-		if (flags & MAP_SHARED &&
-		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
-			return -EINVAL;
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
 		return addr;
-	}
-
-	if (len > TASK_SIZE)
-		return -ENOMEM;
-
-	if (addr) {
-		if (do_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
 
+	do_align = filp || (flags & MAP_SHARED);
 	info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
 	return vm_unmapped_area(&info);
 }
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:46 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:46 -0800
Subject: [PATCH mm-unstable v2 08/16] mm: mips: Introduce arch_align_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-9-kaleshsingh@google.com>

Introduce mips arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/mips/include/asm/pgtable.h |  1 +
 arch/mips/mm/mmap.c             | 50 ++++++++++++++++++---------------
 2 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index c29a551eb0ca..837f25624369 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -766,5 +766,6 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* _ASM_PGTABLE_H */
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 5d2a1225785b..ee9f675190f1 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -26,15 +26,11 @@ EXPORT_SYMBOL(shm_align_mask);
 
 enum mmap_allocation_direction {UP, DOWN};
 
-static unsigned long arch_get_unmapped_area_common(struct file *filp,
-	unsigned long addr0, unsigned long len, unsigned long pgoff,
-	unsigned long flags, enum mmap_allocation_direction dir)
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
 {
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	unsigned long addr = addr0;
-	int do_color_align;
-	struct vm_unmapped_area_info info = {};
+	bool do_color_align;
 
 	if (unlikely(len > TASK_SIZE))
 		return -ENOMEM;
@@ -54,22 +50,32 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
 		return addr;
 	}
 
-	do_color_align = 0;
-	if (filp || (flags & MAP_SHARED))
-		do_color_align = 1;
+	do_color_align = filp || (flags & MAP_SHARED);
+
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
+
+static unsigned long arch_get_unmapped_area_common(struct file *filp,
+	unsigned long addr0, unsigned long len, unsigned long pgoff,
+	unsigned long flags, enum mmap_allocation_direction dir)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long addr = addr0;
+	struct vm_unmapped_area_info info = {};
+	bool do_color_align;
 
 	/* requesting a specific address */
-	if (addr) {
-		if (do_color_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
+
+	do_color_align = filp || (flags & MAP_SHARED);
 
 	info.length = len;
 	info.align_mask = do_color_align ? (PAGE_MASK & shm_align_mask) : 0;
-- 
2.47.0.338.g60cca15819-goog



From kaleshsingh at google.com  Wed Dec 11 15:27:45 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Wed, 11 Dec 2024 15:27:45 -0800
Subject: [PATCH mm-unstable v2 07/16] mm: loongarch: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <20241211232754.1583023-8-kaleshsingh@google.com>

Introduce loongarch arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
This is a preparatory patch, no functional change is introduced.

Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
---

Changes in v2:
  - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
    special case of the hint addr being "enforced", per Yang Shi.
  - Consolidate error handling in arch_mmap_hint().

 arch/loongarch/include/asm/pgtable.h |  1 +
 arch/loongarch/mm/mmap.c             | 49 +++++++++++++++-------------
 2 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
index da346733a1da..326a6c4b7488 100644
--- a/arch/loongarch/include/asm/pgtable.h
+++ b/arch/loongarch/include/asm/pgtable.h
@@ -624,6 +624,7 @@ static inline long pmd_protnone(pmd_t pmd)
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define HAVE_ARCH_MMAP_HINT
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/loongarch/mm/mmap.c b/arch/loongarch/mm/mmap.c
index 914e82ff3f65..9e57bb27642f 100644
--- a/arch/loongarch/mm/mmap.c
+++ b/arch/loongarch/mm/mmap.c
@@ -17,15 +17,11 @@
 
 enum mmap_allocation_direction {UP, DOWN};
 
-static unsigned long arch_get_unmapped_area_common(struct file *filp,
-	unsigned long addr0, unsigned long len, unsigned long pgoff,
-	unsigned long flags, enum mmap_allocation_direction dir)
+unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
+			     unsigned long len, unsigned long pgoff,
+			     unsigned long flags)
 {
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	unsigned long addr = addr0;
-	int do_color_align;
-	struct vm_unmapped_area_info info = {};
+	bool do_color_align;
 
 	if (unlikely(len > TASK_SIZE))
 		return -ENOMEM;
@@ -45,22 +41,31 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
 		return addr;
 	}
 
-	do_color_align = 0;
-	if (filp || (flags & MAP_SHARED))
-		do_color_align = 1;
+	do_color_align = filp || (flags & MAP_SHARED);
+
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	return generic_mmap_hint(filp, addr, len, pgoff, flags);
+}
+
+static unsigned long arch_get_unmapped_area_common(struct file *filp,
+	unsigned long addr0, unsigned long len, unsigned long pgoff,
+	unsigned long flags, enum mmap_allocation_direction dir)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long addr = addr0;
+	bool do_color_align;
+	struct vm_unmapped_area_info info = {};
 
 	/* requesting a specific address */
-	if (addr) {
-		if (do_color_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-
-		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
+	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
+	if (addr)
+		return addr;
+
+	do_color_align = filp || (flags & MAP_SHARED);
 
 	info.length = len;
 	info.align_mask = do_color_align ? (PAGE_MASK & SHM_ALIGN_MASK) : 0;
-- 
2.47.0.338.g60cca15819-goog



From will at kernel.org  Wed Dec 11 15:44:15 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 23:44:15 +0000
Subject: [PATCH v2] arm64/Kconfig: Drop EXECMEM dependency from ARCH_WANTS_EXECMEM_LATE
In-Reply-To: <20241210043257.715822-1-anshuman.khandual@arm.com>
References: <20241210043257.715822-1-anshuman.khandual@arm.com>
Message-ID: <173395344324.1068904.2330956532631016501.b4-ty@kernel.org>

On Tue, 10 Dec 2024 10:02:57 +0530, Anshuman Khandual wrote:
> ARCH_WANTS_EXECMEM_LATE indicates subscribing platform's preference for
> EXECMEM late initialisation without creating a new dependency. Hence this
> just drops EXECMEM dependency while selecting ARCH_WANTS_EXECMEM_LATE.
> 
> 

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/Kconfig: Drop EXECMEM dependency from ARCH_WANTS_EXECMEM_LATE
      https://git.kernel.org/arm64/c/9456a15947c1

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Wed Dec 11 15:44:16 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Dec 2024 23:44:16 +0000
Subject: [PATCH] perf/dwc_pcie: Qualify RAS DES VSEC Capability by Vendor, Revision
In-Reply-To: <20241209222938.3219364-1-helgaas@kernel.org>
References: <20241209222938.3219364-1-helgaas@kernel.org>
Message-ID: <173395359744.1069392.3564048634010264629.b4-ty@kernel.org>

On Mon, 09 Dec 2024 16:29:38 -0600, Bjorn Helgaas wrote:
> PCI Vendor-Specific (VSEC) Capabilities are defined by each vendor.
> Devices from different vendors may advertise a VSEC Capability with the DWC
> RAS DES functionality, but the vendors may assign different VSEC IDs.
> 
> Search for the DWC RAS DES Capability using the VSEC ID and VSEC Rev
> chosen by the vendor.
> 
> [...]

Thanks, Bjorn, for sorting this out and also to Shuai and Ilkka for
giving it a whirl on their platforms.

Applied to will (for-next/perf), thanks!

[1/1] perf/dwc_pcie: Qualify RAS DES VSEC Capability by Vendor, Revision
      https://git.kernel.org/will/c/b34d605d120f

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From yang at os.amperecomputing.com  Wed Dec 11 16:05:04 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Wed, 11 Dec 2024 16:05:04 -0800
Subject: [RFC PATCH 0/3] arm64: support FEAT_BBM level 2 and large block
 mapping when rodata=full
In-Reply-To: <20241211223034.GA17836@willie-the-truck>
References: <20241118181711.962576-1-yang@os.amperecomputing.com>
 <20241210113151.GC14735@willie-the-truck>
 <414b3388-c2e5-45ae-9f1d-c35310fdbf8b@os.amperecomputing.com>
 <20241211223034.GA17836@willie-the-truck>
Message-ID: <311c9f5a-b4d2-41e8-a30e-10fcfb8f19ba@os.amperecomputing.com>



On 12/11/24 2:30 PM, Will Deacon wrote:
> Hey,
>
> On Tue, Dec 10, 2024 at 11:33:16AM -0800, Yang Shi wrote:
>> On 12/10/24 3:31 AM, Will Deacon wrote:
>>> On Mon, Nov 18, 2024 at 10:16:07AM -0800, Yang Shi wrote:
>>>> When rodata=full kernel linear mapping is mapped by PTE due to arm's
>>>> break-before-make rule.
>>>>
>>>> This resulted in a couple of problems:
>>>>     - performance degradation
>>>>     - more TLB pressure
>>>>     - memory waste for kernel page table
>>>>
>>>> There are some workarounds to mitigate the problems, for example, using
>>>> rodata=on, but this compromises the security measurement.
>>>>
>>>> With FEAT_BBM level 2 support, splitting large block page table to
>>>> smaller ones doesn't need to make the page table entry invalid anymore.
>>>> This allows kernel split large block mapping on the fly.
>>> I think you can still get TLB conflict aborts in this case, so this
>>> doesn't work. Hopefully the architecture can strengthen this in the
>>> future to give you what you need.
>> Thanks for responding. This is a little bit surprising. I thought FEAT_BBM
>> level 2 can handle the TLB conflict gracefully. At least its description
>> made me assume so. And Catalin also mentioned FEAT_BBM level 2 can be used
>> to split vmemmap page table in HVO patch discussion
>> (https://lore.kernel.org/all/Zo68DP6siXfb6ZBR at arm.com/).
>>
>> It sounds a little bit contradicting if the TLB conflict still can happen
>> with FEAT_BBM level 2. It makes the benefit of FEAT_BBM level 2 much less
>> than expected.
> You can read the Arm ARM just as badly as I can :)
>
>   | I_HYQMB
>   |
>   | If any level is supported and the TLB entries are not invalidated after
>   | the writes that modified the translation table entries are completed,
>   | then a TLB conflict abort can be generated because in a TLB there might
>   | be multiple translation table entries that all translate the same IA.
>
> Note *any level*.
>
> Furthermore:
>
>   | R_FWRMB
>   |
>   | If all of the following apply, then a TLB conflict abort is reported
>   | to EL2:
>   | * Level 1 or level 2 is supported.
>   | * Stage 2 translations are enabled in the current translation regime.
>   | * A TLB conflict abort is generated due to changing the block size or
>   |   Contiguous bit.

Thank you so much for pinpointing the document.

>
> I think this series is trying to handle some of this:
>
> https://lore.kernel.org/r/20241211154611.40395-1-miko.lenczewski at arm.com

Thanks for sharing the series. It is new. Yes, both are trying to add 
BBMlv2 support to optimize some usecases.

>
>> Is it out of question to handle the TLB conflict aborts? IIUC we should just
>> need flush TLB then resume, and it doesn't require to hold any locks as
>> well.
> See my reply here:
>
> https://lore.kernel.org/r/20241211210243.GA17155 at willie-the-truck

Yeah, it is hard to guarantee recursive TLB conflict abort never happens.

>
>> And I chatted with our architects, I was told the TLB conflict abort doesn't
>> happen on AmpereOne. Maybe this is why I didn't see the problem when I
>> tested the patches.
> I'm actually open to having an MIDR-based lookup for this if its your own
> micro-architecture.

I think it actually makes our life easier. We can just enable BBMlv2 for 
the CPUs which can handle TLB conflict gracefully, so we don't worry 
about handling TLB conflict abort at all. I can implement this in v2.

> Will



From gchen.guomin at gmail.com  Wed Dec 11 18:12:52 2024
From: gchen.guomin at gmail.com (gchen chen)
Date: Thu, 12 Dec 2024 10:12:52 +0800
Subject: [PATCH] firmware: arm_scmi: Delete the meaningless scmi_bus_id.
In-Reply-To: <Z1nZPmB7nW7HUdYL@pluto>
References: <20241211134505.2218386-1-guomin_chen@sina.com_quarantine> <Z1nZPmB7nW7HUdYL@pluto>
Message-ID: <CAEEwsfT3QikwmiiVKq4p_UU1ph6x1+w7wepkO5ohDA83dXKNmA@mail.gmail.com>

Cristian Marussi <cristian.marussi at arm.com> ?2024?12?12??? 02:28???
>
> On Wed, Dec 11, 2024 at 09:45:05PM +0800, guomin_chen at sina.com wrote:
> > From: guomin chen <guomin_chen at sina.com>
> >
> > Currently, scmi_bus_id is only used to set scmi_dev.id,
> > which in turn sets the SCMI device name. After removing
> > scmi_bus_id, it is clearer and more meaningful to directly
> > use the input parameters name and protocol to set the SCMI
> > device name.
>
> Hi,
>
> even though using progressive IDs in devices is less readable, I agree,
> we need ID in the name to keep the device unique.
>
> It is true that we can have only one protocol/name unique pair amongst
> the *requested* devices BUT it is also true that the SCMI stack as it
> stands can be instantiated multiple times if you define multiple DT SCMI
> top-nodes: this is already used in the wild to sort of represent
> multiple virtual/physical SCMI Server backend (all anyway identified by
> ID-0 as from the spec...)
>
> So if you have defind in the DT 2 SCMI instance with both a protocol at 15/HWMON,
> as an example, the arm_scmi/driver.c will probe twice and it will try to
> create 2 instances of 'requested' devices for 15/hwmon and both of these
> will be attached to the same *unique* SCMI bus...so we need the uniqe ID
> to differentiate them....same for the transport devices.

Okay, it is true that if two SCMI instances are defined in DT using
the same protocol,
it will result in devices with the same name. Thank you for pointing this out!

Thanks

> Sorry but NACK for me: regarding the readability, I could agree, but you
> can anyway easily understand which device is which by looking at the
> drivers/ links generated in the scmi_protocol bus directory.
>
> Thanks,
> Cristian


From fujita.tomonori at gmail.com  Wed Dec 11 18:18:22 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Thu, 12 Dec 2024 11:18:22 +0900 (JST)
Subject: [PATCH v1 5/5] rust: Add warn_on and warn_on_once
In-Reply-To: <CAH5fLgj9rBOrcQa193RpuA708CFK1ojMqhmiNWF7dbyNFPJcJA@mail.gmail.com>
References: <CAH5fLgiShKMGo6AYWM-4S8JK+iDA+tUfz9uxkns82g0nLW--NQ@mail.gmail.com>
	<20241211.094054.1429837669366274024.fujita.tomonori@gmail.com>
	<CAH5fLgj9rBOrcQa193RpuA708CFK1ojMqhmiNWF7dbyNFPJcJA@mail.gmail.com>
Message-ID: <20241212.111822.2107715832201318415.fujita.tomonori@gmail.com>

On Wed, 11 Dec 2024 10:48:27 +0100
Alice Ryhl <aliceryhl at google.com> wrote:

>> >> +#[macro_export]
>> >> +#[doc(hidden)]
>> >> +#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
>> >> +#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
>> >
>> >> +#[macro_export]
>> >> +#[doc(hidden)]
>> >> +#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
>> >> +#[cfg(any(target_arch = "aarch64", target_arch = "loongarch64"))]
>> >
>> > What's the reason for this arch-specific code? The file!()/line!()
>> > invocations? Could they be passed as an argument to the asm instead so
>> > that we don't need target_arch cfgs? I understand that they don't work
>> > exactly the same way, but maybe it could still work?
>>
>> Because of "error: named argument never used" in Rust inline assembly:
>>
>> All the archs define ARCH_WARN_ASM macro in the same way:
>>
>> #define ARCH_WARN_ASM(file, line, flags, size)
>>
>> However, only x86 and risc-v asm code use the size argument. Without
>> the cfgs, I'll get the following on arm64/loongarch:
>>
>> error: named argument never used
>>   --> /home/fujita/git/linux-rust/drivers/block/rnull.rs:54:9
>>    |
>> 54 |         warn_on!(true);
>>    |         ^^^^^^^^^^^^^^ named argument never used
>>    |
>>    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {size} */"`
>>    = note: this error originates in the macro `$crate::warn_flags` which comes from the expansion of the macro `warn_on` (in Nightly builds, run with -Z macro-backtrace for more info)
>>
>>
>> Any way to make the compiler to ignore this?
> 
> The error message suggests adding an asm comment. Does that not work?

Ah, works! I didn't understand what "an asm comment" is..

> You could even add the comment unconditionally on the Rust side. It's
> not like the comment hurts on the platforms that *do* use the size
> parameter.

Yeah, I confirmed that this also works for the architectures that
do use the size.

I'll remove the target_arch cfg in v2. Thanks!

>> >> +#[macro_export]
>> >> +#[doc(hidden)]
>> >> +#[cfg(all(CONFIG_BUG, CONFIG_UML))]
>> >> +macro_rules! warn_flags {
>> >> +    ($flags:expr) => {
>> >> +        // SAFETY: Just an FFI call.
>> >> +        unsafe {
>> >> +            $crate::bindings::warn_slowpath_fmt(
>> >> +                $crate::c_str!(::core::file!()).as_ptr() as *const ::core::ffi::c_char,
>> >> +                line!() as i32,
>> >> +                $flags as u32,
>> >> +                ::core::ptr::null() as *const ::core::ffi::c_char,
>> >
>> > I wonder if this could be written to utilize Location::caller()
>> > instead so that `#[track_caller]` works?
>>
>> You meant that we could make warn_flags() function instead of macro
>> with Location::caller()?
>>
>> If so, we need to add cfgs to warn_on and warn_on_once because both macro
>> and function of warn_flags are necessary?
> 
> Well, I'm not sure! I don't know if it's feasible at all, since using
> Location::caller() would mean that the file/line is not a compile-time
> constant. But if we can, then I think #[track_caller] support would be
> nice.

I think that using Location::caller() makes the code complicated
(needs more cfgs for UML). All the callers (warn_* and bug_*) of
warn_flags and warn_flags itself must be macro for all the archs
execpt for UML. We don't want to have the UML version of all the
callers.


From daeinki at gmail.com  Wed Dec 11 18:31:08 2024
From: daeinki at gmail.com (Inki Dae)
Date: Thu, 12 Dec 2024 11:31:08 +0900
Subject: [PATCH] drm/exynos: Remove unnecessary checking
In-Reply-To: <20241206114531.1271123-1-guoqing.jiang@canonical.com>
References: <20241206114531.1271123-1-guoqing.jiang@canonical.com>
Message-ID: <CAAQKjZMuJc1y-6apj6KMVrg6WMVkLbpZ17A=+G6X1OJep+4rPQ@mail.gmail.com>

Hi,

2024? 12? 6? (?) ?? 8:45, Guoqing Jiang <guoqing.jiang at canonical.com>?? ??:
>
> It is not needed since drm_atomic_helper_shutdown checks it.

Correct.

Merged. Thanks,
Inki Dae

>
> Signed-off-by: Guoqing Jiang <guoqing.jiang at canonical.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 2a466d8179f4..461384705cf9 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -357,8 +357,7 @@ static void exynos_drm_platform_shutdown(struct platform_device *pdev)
>  {
>         struct drm_device *drm = platform_get_drvdata(pdev);
>
> -       if (drm)
> -               drm_atomic_helper_shutdown(drm);
> +       drm_atomic_helper_shutdown(drm);
>  }
>
>  static struct platform_driver exynos_drm_platform_driver = {
> --
> 2.35.3
>
>


From Jason-JH.Lin at mediatek.com  Wed Dec 11 19:05:05 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Thu, 12 Dec 2024 03:05:05 +0000
Subject: [PATCH v2 1/8] dt-bindings: mailbox: mediatek: Add GCE header
 file for MT8196
In-Reply-To: <ozifi65uycmxc5hqeu4onbths5u7dg532iufjxplsjw4jjmhf6@6bdsaabd7hl7>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
	 <20241211032256.28494-2-jason-jh.lin@mediatek.com>
	 <ozifi65uycmxc5hqeu4onbths5u7dg532iufjxplsjw4jjmhf6@6bdsaabd7hl7>
Message-ID: <04f7bd2a7d69ab7d02c88cf05bda5ae0c4cb6573.camel@mediatek.com>

Hi Krzysztof,

Thanks for the reviews.

On Wed, 2024-12-11 at 10:37 +0100, Krzysztof Kozlowski wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On Wed, Dec 11, 2024 at 11:22:49AM +0800, Jason-JH.Lin wrote:
> > Add the Global Command Engine (GCE) header file to define the GCE
> > thread priority, GCE subsys ID and GCE events for MT8196.
> 
> This we see from the diff. What we do not see is why priority is a
> binding. Looking briefly at existing code: it is not a binding, there
> is
> no driver user.
> 

This priority value is used to configure the priority level for each
GCE hardware thread, so it is a necessary hardware attribute.

It's hard to find where the priority is used in existing driver code
because we parsed it from DTS.

It is used in all mediaTeks' DTS using the GCE.
For example, in mt8195.dts:

vdosys0: syscon at 1c01a000 {
    compatible = "mediatek,mt8195-vdosys0", "mediatek,mt8195-mmsys",
"syscon";
    reg = <0 0x1c01a000 0 0x1000>;
    mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
    #clock-cells = <1>;
    mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0xa000 0x1000>;
}

CMDQ driver(mtk-cmdq-mailbox.c) will get the args parsed from mboxes
property in cmdq_xlate() and then it will store CMDQ_THR_PRIO_4 to the
specific thread structure. 
The user of CMDQ driver will send command to CMDQ driver by 
cmdq_mbox_send_data(), and this priority setting will be configured to
GCE hardware thread.

> > 
> > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> > ---
> >  .../dt-bindings/mailbox/mediatek,mt8196-gce.h | 1439
> > +++++++++++++++++
> >  1 file changed, 1439 insertions(+)
> >  create mode 100644 include/dt-bindings/mailbox/mediatek,mt8196-
> > gce.h
> > 
> > diff --git a/include/dt-bindings/mailbox/mediatek,mt8196-gce.h
> > b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h
> > new file mode 100644
> > index 000000000000..860d69100157
> > --- /dev/null
> > +++ b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h
> > @@ -0,0 +1,1439 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> > +/*
> > + * Copyright (c) 2024 MediaTek Inc.
> > + *
> > + */
> > +
> > +#ifndef _DT_BINDINGS_GCE_MT8196_H
> > +#define _DT_BINDINGS_GCE_MT8196_H
> > +
> > +/* GCE thread priority */
> > +#define CMDQ_THR_PRIO_LOWEST 0
> > +#define CMDQ_THR_PRIO_1              1
> > +#define CMDQ_THR_PRIO_2              2
> > +#define CMDQ_THR_PRIO_3              3
> > +#define CMDQ_THR_PRIO_4              4
> > +#define CMDQ_THR_PRIO_5              5
> > +#define CMDQ_THR_PRIO_6              6
> > +#define CMDQ_THR_PRIO_HIGHEST        7
> > +
> > +/* GCE subsys table */
> > +#define SUBSYS_1300XXXX              0
> > +#define SUBSYS_1400XXXX              1
> > +#define SUBSYS_1401XXXX              2
> > +#define SUBSYS_1402XXXX              3
> > +#define SUBSYS_1502XXXX              4
> > +#define SUBSYS_1880XXXX              5
> > +#define SUBSYS_1881XXXX              6
> > +#define SUBSYS_1882XXXX              7
> > +#define SUBSYS_1883XXXX              8
> > +#define SUBSYS_1884XXXX              9
> > +#define SUBSYS_1000XXXX              10
> > +#define SUBSYS_1001XXXX              11
> > +#define SUBSYS_1002XXXX              12
> > +#define SUBSYS_1003XXXX              13
> > +#define SUBSYS_1004XXXX              14
> > +#define SUBSYS_1005XXXX              15
> > +#define SUBSYS_1020XXXX              16
> > +#define SUBSYS_1028XXXX              17
> > +#define SUBSYS_1700XXXX              18
> > +#define SUBSYS_1701XXXX              19
> > +#define SUBSYS_1702XXXX              20
> > +#define SUBSYS_1703XXXX              21
> > +#define SUBSYS_1800XXXX              22
> > +#define SUBSYS_1801XXXX              23
> > +#define SUBSYS_1802XXXX              24
> > +#define SUBSYS_1804XXXX              25
> > +#define SUBSYS_1805XXXX              26
> > +#define SUBSYS_1808XXXX              27
> > +#define SUBSYS_180aXXXX              28
> > +#define SUBSYS_180bXXXX              29
> > +#define SUBSYS_NO_SUPPORT    99
> > +
> > +/*
> > + * GCE General Purpose Register (GPR) support
> > + * Leave note for scenario usage here
> > + */
> > +/* GCE: write mask */
> 
> That's a definite no-go. Register masks are not bindings.
> 

I'm sorry to the confusion.

These defines are the index of GCE General Purpose Register for
generating instructions, they are not register masks.

The comment "/* GCE: write mask */" is briefly describe that the usage
of GCE_GPR_R0 and GCE_GPR_R01 is used to store the register mask when
GCE executing the WRITE instruction. And it can also store the register
mask of POLL and READ instruction.

I will add more words to make this comment clearer, like this:
/*GCE: store the mask of instruction */

Regards,
Jason-JH.Lin

> > +#define GCE_GPR_R00          0x0
> > +#define GCE_GPR_R01          0x1
> 
> Best regards,
> Krzysztof
> 

From cki-project at redhat.com  Wed Dec 11 19:12:04 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Thu, 12 Dec 2024 03:12:04 -0000
Subject: =?utf-8?b?4pyF?= PASS (MISSED 4 of 69): Test report for for-kernelci
 (6.13.0-rc2, upstream-arm-next, 2e7aff49)
Message-ID: <90068.124121122120700101@us-mta-207.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/core' and 'for-next/perf' into for-kernelci

You can find all the details about the test run at
    https://datawarehouse.cki-project.org/kcidb/checkouts/redhat:1584886177

Tests that were not ran because of internal issues: 
    Reboot test [aarch64]
    stress: stress-ng - cpu-cache [aarch64]
    stress: stress-ng - memory [aarch64]


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 0x1207 at gmail.com  Wed Dec 11 19:33:25 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Thu, 12 Dec 2024 11:33:25 +0800
Subject: [PATCH net-next v1] net: stmmac: Drop redundant dwxgmac_tc_ops variable
Message-ID: <20241212033325.282817-1-0x1207@gmail.com>

dwmac510_tc_ops and dwxgmac_tc_ops are completely identical,
keep dwmac510_tc_ops to provide better backward compatibility.

Signed-off-by: Furong Xu <0x1207 at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/hwif.c      |  4 ++--
 drivers/net/ethernet/stmicro/stmmac/hwif.h      |  1 -
 drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 11 -----------
 3 files changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 4bd79de2e222..31bdbab9a46c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -267,7 +267,7 @@ static const struct stmmac_hwif_entry {
 		.hwtimestamp = &stmmac_ptp,
 		.ptp = &stmmac_ptp_clock_ops,
 		.mode = NULL,
-		.tc = &dwxgmac_tc_ops,
+		.tc = &dwmac510_tc_ops,
 		.mmc = &dwxgmac_mmc_ops,
 		.est = &dwmac510_est_ops,
 		.setup = dwxgmac2_setup,
@@ -290,7 +290,7 @@ static const struct stmmac_hwif_entry {
 		.hwtimestamp = &stmmac_ptp,
 		.ptp = &stmmac_ptp_clock_ops,
 		.mode = NULL,
-		.tc = &dwxgmac_tc_ops,
+		.tc = &dwmac510_tc_ops,
 		.mmc = &dwxgmac_mmc_ops,
 		.est = &dwmac510_est_ops,
 		.setup = dwxlgmac2_setup,
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index e428c82b7d31..2f7295b6c1c5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -685,7 +685,6 @@ extern const struct stmmac_dma_ops dwmac410_dma_ops;
 extern const struct stmmac_ops dwmac510_ops;
 extern const struct stmmac_tc_ops dwmac4_tc_ops;
 extern const struct stmmac_tc_ops dwmac510_tc_ops;
-extern const struct stmmac_tc_ops dwxgmac_tc_ops;
 
 #define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
 #define GMAC4_VERSION		0x00000110	/* GMAC4+ CORE Version */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
index 6a79e6a111ed..694d6ee14381 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -1284,14 +1284,3 @@ const struct stmmac_tc_ops dwmac510_tc_ops = {
 	.query_caps = tc_query_caps,
 	.setup_mqprio = tc_setup_dwmac510_mqprio,
 };
-
-const struct stmmac_tc_ops dwxgmac_tc_ops = {
-	.init = tc_init,
-	.setup_cls_u32 = tc_setup_cls_u32,
-	.setup_cbs = tc_setup_cbs,
-	.setup_cls = tc_setup_cls,
-	.setup_taprio = tc_setup_taprio,
-	.setup_etf = tc_setup_etf,
-	.query_caps = tc_query_caps,
-	.setup_mqprio = tc_setup_dwmac510_mqprio,
-};
-- 
2.34.1



From Jason-JH.Lin at mediatek.com  Wed Dec 11 19:41:31 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Thu, 12 Dec 2024 03:41:31 +0000
Subject: [PATCH v2 2/8] dt-bindings: mailbox: mediatek: Add MT8196 support
 for gce-mailbox
In-Reply-To: <yhfxpflyumevs66sdwgiiyuablpfxfxw3e7ybrxju7ssicmnu5@truuiuvxlq6e>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
	 <20241211032256.28494-3-jason-jh.lin@mediatek.com>
	 <yhfxpflyumevs66sdwgiiyuablpfxfxw3e7ybrxju7ssicmnu5@truuiuvxlq6e>
Message-ID: <64326843358d450c9172f3dea1c85e7422e20430.camel@mediatek.com>

Hi Krzysztof,

Thanks for the reviews.

On Wed, 2024-12-11 at 10:39 +0100, Krzysztof Kozlowski wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On Wed, Dec 11, 2024 at 11:22:50AM +0800, Jason-JH.Lin wrote:
> > Add compatible name and iommus property for MT8196.
> > 
> > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> > ---
> >  .../devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml     | 4
> > ++++
> >  1 file changed, 4 insertions(+)
> 
> Headers are never separate from the bindings patch...

Do you mean I need to merge [PATCH 1/8] and [PATCH 2/8] into 1 patch?

> 
> And you reveived exactly the same comments before which you just
> ignored.
> 

I checked the dt_binding_check history and checkpatch history, but I
didn't see the WARNING like `header is separated from bindings`.
But I did see the WARNING of maintainers updating that appeared every
time when I added the new file.

Here is my history of dt_binding_check:
make dt_binding_check
DT_SCHEMA_FILES=Documentation/devicetree/bindings/mailbox/mediatek,gce-
mailbox.yaml O=/tmp/src_kernel/kernel/out -C kernel/linux-next -k
make[1]: Entering directory '/tmp/src_kernel/kernel/kernel/linux-next'
make[2]: Entering directory '/tmp/src_kernel/kernel/out'
HOSTCC  scripts/basic/fixdep
HOSTCC  scripts/dtc/dtc.o
HOSTCC  scripts/dtc/data.o
HOSTCC  scripts/dtc/srcpos.o
HOSTCC  scripts/dtc/flattree.o
HOSTCC  scripts/dtc/fstree.o
HOSTCC  scripts/dtc/livetree.o
HOSTCC  scripts/dtc/checks.o
HOSTCC  scripts/dtc/util.o
HOSTCC  scripts/dtc/treesource.o
LEX     scripts/dtc/dtc-lexer.lex.c
YACC    scripts/dtc/dtc-parser.tab.[ch]
HOSTCC  scripts/dtc/dtc-lexer.lex.o
HOSTCC  scripts/dtc/dtc-parser.tab.o
SCHEMA  Documentation/devicetree/bindings/processed-schema.json
HOSTLD  scripts/dtc/dtc
CHKDT   /tmp/src_kernel/kernel/kernel/linux-
next/Documentation/devicetree/bindings
LINT    /tmp/src_kernel/kernel/kernel/linux-
next/Documentation/devicetree/bindings
DTEX    Documentation/devicetree/bindings/mailbox/mediatek,gce-
mailbox.example.dts
DTC [C] Documentation/devicetree/bindings/mailbox/mediatek,gce-
mailbox.example.dtb
make[2]: Leaving directory '/tmp/src_kernel/kernel/out'
make[1]: Leaving directory '/tmp/src_kernel/kernel/kernel/linux-next'
[09:53:30] - - - - - - - - - -> [ OK ] KERN_DIR=kernel/linux-next make
-k -j32 dt_binding_check
DT_SCHEMA_FILES=Documentation/devicetree/bindings/mailbox/mediatek,gce-
mailbox.yaml


Here is my history of checkpatch:
~/linux$ ./scripts/checkpatch.pl --strict --ignore=GERRIT_CHANGE_ID --
show-types 000*

-----------------------
0000-cover-letter.patch
-----------------------
total: 0 errors, 0 warnings, 0 checks, 0 lines checked

0000-cover-letter.patch has no obvious style problems and is ready for
submission.
---------------------------------------------------------------
0001-dt-bindings-mailbox-mediatek-Add-GCE-header-file-for.patch
---------------------------------------------------------------
Traceback (most recent call last):
  File "scripts/spdxcheck.py", line 6, in <module>
      from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does
MAINTAINERS need updating?
#17:
      new file mode 100644

      total: 0 errors, 1 warnings, 0 checks, 1439 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.

0001-dt-bindings-mailbox-mediatek-Add-GCE-header-file-for.patch has
style problems, please review.
---------------------------------------------------------------
0002-dt-bindings-mailbox-mediatek-Add-MT8196-support-for-.patch
---------------------------------------------------------------
total: 0 errors, 0 warnings, 0 checks, 16 lines checked

0002-dt-bindings-mailbox-mediatek-Add-MT8196-support-for-.patch has no
obvious style problems and is ready for submission.
---------------------------------------------------------------


Did I miss some configuration?

Regards,
Jason-JH.Lin

> NAK.
> 
> Best regards,
> Krzysztof
> 

From Jason-JH.Lin at mediatek.com  Wed Dec 11 19:48:15 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Thu, 12 Dec 2024 03:48:15 +0000
Subject: [PATCH v2 7/8] drm/mediatek: Add programming flow for unsupported
 subsys ID hardware
In-Reply-To: <4e10e2cd5d58321bdd7e5dabf5fb70702f8afc92.camel@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
	 <20241211032256.28494-8-jason-jh.lin@mediatek.com>
	 <761ef6ecfe8298f945e6627aff29f864fcf7b9c0.camel@mediatek.com>
	 <4e10e2cd5d58321bdd7e5dabf5fb70702f8afc92.camel@mediatek.com>
Message-ID: <5954e33f25cb2bb4e1d369ff174bd8d574accd55.camel@mediatek.com>

Hi CK,

Thanks for the reviews.

On Wed, 2024-12-11 at 04:04 +0000, CK Hu (???) wrote:
> On Wed, 2024-12-11 at 11:46 +0800, CK Hu wrote:
> > Hi, Jason:
> > 
> > On Wed, 2024-12-11 at 11:22 +0800, Jason-JH.Lin wrote:
> > > To support hardware without subsys IDs on new SoCs, add a
> > > programming
> > > flow that checks whether the subsys ID is valid. If the subsys ID
> > > is
> > > invalid, the flow will call 2 alternative CMDQ APIs:
> > > cmdq_pkt_assign() and cmdq_pkt_write_s_value() to achieve the
> > > same
> > > functionality.
> > > 
> > > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> > > ---
> > >  drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 34
> > > ++++++++++++++++++++-----
> > >  1 file changed, 28 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > > b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > > index edc6417639e6..0792c895526f 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > > @@ -66,14 +66,38 @@ struct mtk_ddp_comp_dev {
> > >  	struct cmdq_client_reg cmdq_reg;
> > >  };
> > >  
> > > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > > +static void mtk_ddp_write_cmdq_pkt(struct cmdq_pkt *cmdq_pkt,
> > > struct cmdq_client_reg *cmdq_reg,
> > > +				   unsigned int offset, unsigned int
> > > value, unsigned int mask)
> > 
> > Drop this function.
> 
> Sorry, it seems cmdq_subsys_is_valid() is used to check the SoC
> support new API or not.
> But I would try to find out a way not to always check using new API
> or not.
> 

OK, I can help you  test it, if you have any idea for this.

I'll use `cl->chan, cmdq_reg->subsys == INVALID_SUBSYS` instead of
calling `cmdq_subsys_is_valid()` to avoid function calls.

> Regards,
> CK
> 
> > 
> > > +{
> > > +	struct cmdq_client *cl = (struct cmdq_client *)cmdq_pkt->cl;
> > > +
> > > +	offset += cmdq_reg->offset;
> > > +
> > > +	if (cmdq_subsys_is_valid(cl->chan, cmdq_reg->subsys)) {
> > > +		if (mask == GENMASK(31, 0))
> > > +			cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
> > > offset, value);
> > > +		else
> > > +			cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys, 
> > > offset, value, mask);
> > > +	} else {
> > > +		/* only MMIO access, no need to check mminfro_offset */
> > > +		cmdq_pkt_assign(cmdq_pkt, 0, CMDQ_ADDR_HIGH(cmdq_reg-
> > > >pa_base));
> > > +		if (mask == GENMASK(31, 0))
> > > +			cmdq_pkt_write_s_value(cmdq_pkt, 0,
> > > CMDQ_ADDR_LOW(offset), value);
> > > +		else
> > > +			cmdq_pkt_write_s_mask_value(cmdq_pkt, 0,
> > > CMDQ_ADDR_LOW(offset),
> > > +						    value, mask);
> > > +	}
> > > +}
> > > +#endif

[snip]

> > >  	else
> > >  #endif
> > >  		writel_relaxed(value, regs + offset);
> > > @@ -98,8 +121,7 @@ void mtk_ddp_write_mask(struct cmdq_pkt
> > > *cmdq_pkt, unsigned int value,
> > >  {
> > >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > >  	if (cmdq_pkt) {
> > > -		cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys,
> > > -				    cmdq_reg->offset + offset, value,
> > > mask);
> > > +		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset,
> > > value, mask);
> > 
> > /* only MMIO access, no need to check mminfro_offset */
> > cmdq_pkt_assign(cmdq_pkt, CMDQ_XXXREG_0, CMDQ_ADDR_HIGH(cmdq_reg-
> > >pa_base));
> > cmdq_pkt_write_s_mask_value(cmdq_pkt, CMDQ_XXXREG_0,
> > CMDQ_ADDR_LOW(offset),
> > 			    value, mask);
> > 
> > CMDQ_XXXREG_0 is defined in cmdq header file.
> > 

OK, I'll use CMDQ_THR_SPR_IDX0 instead.

Regards,
Jason-JH.Lin

> > Regards,
> > CK

From hui.wang at canonical.com  Wed Dec 11 20:31:26 2024
From: hui.wang at canonical.com (Hui Wang)
Date: Thu, 12 Dec 2024 12:31:26 +0800
Subject: [PATCH] ARM: dts: nxp: imx6qdl: add dr_mode to usbotg
Message-ID: <20241212043126.73045-1-hui.wang@canonical.com>

For the chipidea usb driver, if the dr_mode is not set, it will set
the device to otg mode by default, so here the dr_mode has not been
set for a long time. But some testcases need to parse the dr_mode from
DT and decide the follow-up test strategy, here set the dr_mode to otg
explicitly for QA's testcases.

Signed-off-by: Hui Wang <hui.wang at canonical.com>
---
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
index d2200c9db25a..285fb7314a88 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
@@ -982,6 +982,7 @@ usbotg: usb at 2184000 {
 				clocks = <&clks IMX6QDL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
+				dr_mode = "otg";
 				ahb-burst-config = <0x0>;
 				tx-burst-size-dword = <0x10>;
 				rx-burst-size-dword = <0x10>;
-- 
2.34.1



From patchwork-bot+netdevbpf at kernel.org  Wed Dec 11 20:40:39 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 12 Dec 2024 04:40:39 +0000
Subject: [PATCH net-next 0/9] net: dsa: cleanup EEE (part 1)
In-Reply-To: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
References: <Z1hNkEb13FMuDQiY@shell.armlinux.org.uk>
Message-ID: <173397843974.1849456.11438174584563074655.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, 10 Dec 2024 14:17:52 +0000 you wrote:
> Hi,
> 
> First part of DSA EEE cleanups.
> 
> Patch 1 removes a useless test that is always false. dp->pl will always
> be set for user ports, so !dp->pl in the EEE methods will always be
> false.
> 
> [...]

Here is the summary with links:
  - [net-next,1/9] net: dsa: remove check for dp->pl in EEE methods
    https://git.kernel.org/netdev/net-next/c/66c366392e55
  - [net-next,2/9] net: dsa: add hook to determine whether EEE is supported
    https://git.kernel.org/netdev/net-next/c/9723a77318b7
  - [net-next,3/9] net: dsa: provide implementation of .support_eee()
    https://git.kernel.org/netdev/net-next/c/99379f587278
  - [net-next,4/9] net: dsa: b53/bcm_sf2: implement .support_eee() method
    https://git.kernel.org/netdev/net-next/c/c86692fc2cb7
  - [net-next,5/9] net: dsa: mt753x: implement .support_eee() method
    https://git.kernel.org/netdev/net-next/c/7eb4f3d9fe17
  - [net-next,6/9] net: dsa: qca8k: implement .support_eee() method
    https://git.kernel.org/netdev/net-next/c/fe3ef44385b2
  - [net-next,7/9] net: dsa: mv88e6xxx: implement .support_eee() method
    https://git.kernel.org/netdev/net-next/c/eb3126e720e7
  - [net-next,8/9] net: dsa: ksz: implement .support_eee() method
    https://git.kernel.org/netdev/net-next/c/801fd546c1ca
  - [net-next,9/9] net: dsa: require .support_eee() method to be implemented
    https://git.kernel.org/netdev/net-next/c/88325a291a0c

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From lkp at intel.com  Wed Dec 11 20:53:04 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Dec 2024 12:53:04 +0800
Subject: [PATCH] pinctrl: mediatek: Add support for MT8196
In-Reply-To: <20241211055454.17120-3-ot_cathy.xu@mediatek.com>
References: <20241211055454.17120-3-ot_cathy.xu@mediatek.com>
Message-ID: <202412121226.WW9Airfh-lkp@intel.com>

Hi ot907280,

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 linus/master v6.13-rc2 next-20241211]
[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/ot907280/pinctrl-mediatek-Add-support-for-MT8196/20241211-140107
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
patch link:    https://lore.kernel.org/r/20241211055454.17120-3-ot_cathy.xu%40mediatek.com
patch subject: [PATCH] pinctrl: mediatek: Add support for MT8196
config: arm64-randconfig-002-20241212 (https://download.01.org/0day-ci/archive/20241212/202412121226.WW9Airfh-lkp at intel.com/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241212/202412121226.WW9Airfh-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/202412121226.WW9Airfh-lkp at intel.com/

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: mtk_paris_pinctrl_pm_ops
   >>> referenced by pinctrl-mt8196.c
   >>>               drivers/pinctrl/mediatek/pinctrl-mt8196.o:(mt8196_pinctrl_driver) in archive vmlinux.a

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


From xu.yang_2 at nxp.com  Wed Dec 11 20:52:51 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 12 Dec 2024 12:52:51 +0800
Subject: [PATCH v2] perf: imx9_perf: Introduce AXI filter version to
 refactor the driver and better extension
In-Reply-To: <20241211215637.GF17486@willie-the-truck>
References: <20241125104338.2433339-1-xu.yang_2@nxp.com>
 <20241209154419.GB12428@willie-the-truck>
 <20241210020212.yz3xowvdk27zmgsl@hippo>
 <20241210133732.GA15607@willie-the-truck>
 <20241211053455.z5zzawfacpyv2dlt@hippo>
 <20241211215637.GF17486@willie-the-truck>
Message-ID: <20241212045232.hdstkxd3qcdtrmvr@hippo>

On Wed, Dec 11, 2024 at 09:56:38PM +0000, Will Deacon wrote:
> On Wed, Dec 11, 2024 at 01:35:16PM +0800, Xu Yang wrote:
> > On Tue, Dec 10, 2024 at 01:37:32PM +0000, Will Deacon wrote:
> > > On Tue, Dec 10, 2024 at 10:02:12AM +0800, Xu Yang wrote:
> > > > On Mon, Dec 09, 2024 at 03:44:20PM +0000, Will Deacon wrote:
> > > > > On Mon, Nov 25, 2024 at 06:43:38PM +0800, Xu Yang wrote:
> > > > > > The imx93 is the first supported DDR PMU that supports read transaction,
> > > > > > write transaction and read beats events which corresponding respecitively
> > > > > > to counter 2, 3 and 4.
> > > > > > 
> > > > > > However, transaction-based AXI match has low accuracy when get total bits
> > > > > > compared to beats-based. And imx93 doesn't assign AXI_ID to each master.
> > > > > > So axi filter is not used widely on imx93. This could be regards as AXI
> > > > > > filter version 1.
> > > > > > 
> > > > > > To improve the AXI filter capability, imx95 supports 1 read beats and 3
> > > > > > write beats event which corresponding respecitively to counter 2-5. imx95
> > > > > > also detailed AXI_ID allocation so that most of the master could be count
> > > > > > individually. This could be regards as AXI filter version 2.
> > > > > > 
> > > > > > This will introduce AXI filter version to refactor the driver and support
> > > > > > better extension, such as coming imx943.
> > > > > > 
> > > > > > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > > > > > 
> > > > > > ---
> > > > > > Changes in v2:
> > > > > >  - modify subject
> > > > > >  - add comments for AXI_FILTER version
> > > > > >  - type -> filter_ver
> > > > > > ---
> > > > > >  drivers/perf/fsl_imx9_ddr_perf.c | 33 ++++++++++++++++++++++++--------
> > > > > >  1 file changed, 25 insertions(+), 8 deletions(-)
> > > 
> > > [...]
> > > 
> > > > > > @@ -624,11 +641,11 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
> > > > > >  	hwc->idx = counter;
> > > > > >  	hwc->state |= PERF_HES_STOPPED;
> > > > > >  
> > > > > > -	if (is_imx93(pmu))
> > > > > > +	if (axi_filter_v1(pmu))
> > > > > >  		/* read trans, write trans, read beat */
> > > > > >  		imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
> > > > > 
> > > > > Hmm, doesn't this change mean we now enable this for imx91 as well? My
> > > > > reading of the commit message is that imx93 was the first chip which
> > > > > supports this.
> > > > 
> > > > Yes, it's enabled for imx91 too. In fact, imx91 is compatible with imx93.
> > > > They use same configuration for axi filter.
> > > 
> > > Ok, but my worry is that the above code looks like userspace now _must_
> > > provide valid values for the config1 (axi_id) and config2 (axi_mask)
> > > fields on imx91, whereas before I think they were ignored by the driver.
> > > 
> > > In fact, without this change, how were the PMCFGn registers configured
> > > on imx91? It looks to me like they were left uninitialised...
> > 
> > Before this change, PMCFGn registers are indeed not configured on imx91.
> > However, they should be configured as imx93. I notice this thing when
> > make this patch. First thing I tried is to add is_imx91(), then check it
> > and is_imx93() by "||" operator. However, this way seems not scalable as
> > more imx9x Soc comes out. Basically, AXI filter version will keep at V2
> > unless big changes due to new features. However, perf tool need export
> > correct MetricName via identifier in sysfs. So I made this patch, then
> > PMCFGn will be configured based on axi filter version rather than pmu
> > name.
> 
> Gotcha. But that means this is a fix, right? The commit message doesn't
> really indicate that and we probably want a Fixes: tag to indicate how
> far it should be backported.
> 
> Please can you send a v3 with that so I can apply it?

Sure.

Thanks,
Xu Yang


From quic_pkondeti at quicinc.com  Wed Dec 11 21:31:00 2024
From: quic_pkondeti at quicinc.com (Pavan Kondeti)
Date: Thu, 12 Dec 2024 11:01:00 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <86sequsdtp.wl-maz@kernel.org>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <87ed2fs03w.wl-maz@kernel.org>
 <92cee905-a505-4ce9-9bbc-6fba4cea1d80@quicinc.com>
 <86sequsdtp.wl-maz@kernel.org>
Message-ID: <c197264b-3791-493a-b717-3dfd844de922@quicinc.com>

On Wed, Dec 11, 2024 at 10:40:02AM +0000, Marc Zyngier wrote:
> On Wed, 11 Dec 2024 00:37:34 +0000,
> Pavan Kondeti <quic_pkondeti at quicinc.com> wrote:
> > 
> > On Tue, Dec 10, 2024 at 09:24:03PM +0000, Marc Zyngier wrote:
> > > > +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> > > > +{
> > > > +	int ret;
> > > > +
> > > > +#ifdef CONFIG_ARM64
> > > > +	/*
> > > > +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> > > > +	 * to switch the secure mode to avoid the dependency on zap shader.
> > > > +	 */
> > > > +	if (is_kernel_in_hyp_mode())
> > > > +		goto direct_switch;
> > > 
> > > No, please. To check whether you are *booted* at EL2, you need to
> > > check for is_hyp_available(). Whether the kernel runs at EL1 or EL2 is
> > > none of the driver's business, really. This is still absolutely
> > > disgusting from an abstraction perspective, but I guess we don't have
> > > much choice here.
> > > 
> > 
> > Thanks Marc. Any suggestions on how we can make is_hyp_mode_available()
> > available for modules? Do you prefer exporting
> > kvm_protected_mode_initialized and __boot_cpu_mode symbols directly or
> > try something like [1]?
> 
> Ideally, neither. These were bad ideas nine years ago, and they still
> are. The least ugly hack I can come up with is the patch below, and
> you'd write something like:
> 
> 	if (cpus_have_cap(ARM64_HAS_EL2_OWNERSHIP))
> 		blah();
> 
> This is obviously completely untested.
> 

I have tested your patch. It works as intended. Thanks Marc.

> It also doesn't solve the problem of the kernel booted on bare-metal
> at EL1, or with a hypervisor that doesn't change the programming
> interface of the device under the guest's feet. Eventually, someone
> will have to address these cases.
> 

Noted, Thanks.

~Pavan


From xiazhengqiao at huaqin.corp-partner.google.com  Wed Dec 11 22:20:43 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Thu, 12 Dec 2024 14:20:43 +0800
Subject: [PATCH v5 1/4] dt-bindings: arm: mediatek: Add MT8186 Chinchou Chromebook
In-Reply-To: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <20241212062046.22509-2-xiazhengqiao@huaqin.corp-partner.google.com>

Add an entry for the MT8186 based Chinchou Chromebook, also known as the
ASUS Chromebook CZ12 Flip (CZ1204F) and CZ12(CZ1204C).

Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../devicetree/bindings/arm/mediatek.yaml     | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 1d4bb50fcd8d..d3cc6fbad8d0 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -239,6 +239,34 @@ properties:
           - enum:
               - mediatek,mt8183-pumpkin
           - const: mediatek,mt8183
+      - description: Google Chinchou (Asus Chromebook CZ1104CM2A/CZ1204CM2A)
+        items:
+          - const: google,chinchou-sku0
+          - const: google,chinchou-sku2
+          - const: google,chinchou-sku4
+          - const: google,chinchou-sku5
+          - const: google,chinchou
+          - const: mediatek,mt8186
+      - description: Google Chinchou (Asus Chromebook CZ1104FM2A/CZ1204FM2A/CZ1104CM2A/CZ1204CM2A)
+        items:
+          - const: google,chinchou-sku1
+          - const: google,chinchou-sku3
+          - const: google,chinchou-sku6
+          - const: google,chinchou-sku7
+          - const: google,chinchou-sku17
+          - const: google,chinchou-sku20
+          - const: google,chinchou-sku22
+          - const: google,chinchou-sku23
+          - const: google,chinchou
+          - const: mediatek,mt8186
+      - description: Google Chinchou360 (Asus Chromebook CZ1104FM2A/CZ1204FM2A Flip)
+        items:
+          - const: google,chinchou-sku16
+          - const: google,chinchou-sku18
+          - const: google,chinchou-sku19
+          - const: google,chinchou-sku21
+          - const: google,chinchou
+          - const: mediatek,mt8186
       - description: Google Magneton (Lenovo IdeaPad Slim 3 Chromebook (14M868))
         items:
           - const: google,steelix-sku393219
-- 
2.17.1



From xiazhengqiao at huaqin.corp-partner.google.com  Wed Dec 11 22:20:44 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Thu, 12 Dec 2024 14:20:44 +0800
Subject: [PATCH v5 2/4] arm64: dts: mediatek: Add MT8186 Chinchou Chromebooks
In-Reply-To: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <20241212062046.22509-3-xiazhengqiao@huaqin.corp-partner.google.com>

MT8186 chinchou, known as ASUS Chromebook CZ12 Flip (CZ1204F)
and CZ12(CZ1204C), is a MT8186 based laptop.
It is based on the "corsola" design.It includes chinchou and chinchou360,
including LTE, stylus, touchscreen combinations.

Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
---
 arch/arm64/boot/dts/mediatek/Makefile         |   3 +
 .../mediatek/mt8186-corsola-chinchou-sku0.dts |  18 +
 .../mediatek/mt8186-corsola-chinchou-sku1.dts |  35 ++
 .../mt8186-corsola-chinchou-sku16.dts         |  29 ++
 .../dts/mediatek/mt8186-corsola-chinchou.dtsi | 321 ++++++++++++++++++
 5 files changed, 406 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 8fd7b2bb7a15..0db7770e8907 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -55,6 +55,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku0.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku1.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-chinchou-sku16.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
new file mode 100644
index 000000000000..5d012bc4ff0d
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-chinchou.dtsi"
+
+/ {
+	model = "Google chinchou CZ1104CM2A/CZ1204CM2A";
+	compatible = "google,chinchou-sku0", "google,chinchou-sku2",
+			"google,chinchou-sku4", "google,chinchou-sku5",
+			"google,chinchou", "mediatek,mt8186";
+};
+
+&gpio_keys {
+	status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
new file mode 100644
index 000000000000..9d6e62af6944
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-chinchou.dtsi"
+
+/ {
+	model = "Google chinchou CZ1104FM2A/CZ1204FM2A/CZ1104CM2A/CZ1204CM2A";
+	compatible = "google,chinchou-sku1", "google,chinchou-sku3",
+			"google,chinchou-sku6", "google,chinchou-sku7",
+			"google,chinchou-sku17", "google,chinchou-sku20",
+			"google,chinchou-sku22", "google,chinchou-sku23",
+			"google,chinchou", "mediatek,mt8186";
+};
+
+&gpio_keys {
+	status = "disabled";
+};
+
+&i2c1 {
+	i2c-scl-internal-delay-ns = <10000>;
+
+	touchscreen: touchscreen at 41 {
+		compatible = "ilitek,ili2901";
+		reg = <0x41>;
+		interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&touchscreen_pins>;
+		reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>;
+		vccio-supply = <&pp1800_tchscr_report_disable>;
+		vcc33-supply = <&pp3300_z2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts
new file mode 100644
index 000000000000..eb377de1fcde
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-chinchou.dtsi"
+
+/ {
+	model = "Google chinchou CZ1104FM2A/CZ1204FM2A";
+	compatible = "google,chinchou-sku16", "google,chinchou-sku18",
+			"google,chinchou-sku19", "google,chinchou-sku21",
+			"google,chinchou", "mediatek,mt8186";
+};
+
+&i2c1 {
+	i2c-scl-internal-delay-ns = <10000>;
+
+	touchscreen: touchscreen at 41 {
+		compatible = "ilitek,ili2901";
+		reg = <0x41>;
+		interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&touchscreen_pins>;
+		reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>;
+		vccio-supply = <&pp1800_tchscr_report_disable>;
+		vcc33-supply = <&pp3300_z2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi
new file mode 100644
index 000000000000..800792157021
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi
@@ -0,0 +1,321 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola.dtsi"
+
+/ {
+	/delete-node/ speaker-codec;
+
+	pp1000_edpbrdg: regulator-pp1000-edpbrdg {
+		compatible = "regulator-fixed";
+		regulator-name = "pp1000_edpbrdg";
+		pinctrl-names = "default";
+		pinctrl-0 = <&en_pp1000_edpbrdg>;
+		enable-active-high;
+		regulator-boot-on;
+		gpio = <&pio 29 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&pp3300_z2>;
+	};
+
+	pp1800_edpbrdg_dx: regulator-pp1800-edpbrdg-dx {
+		compatible = "regulator-fixed";
+		regulator-name = "pp1800_edpbrdg_dx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&en_pp1800_edpbrdg>;
+		enable-active-high;
+		regulator-boot-on;
+		gpio = <&pio 30 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&mt6366_vio18_reg>;
+	};
+
+	pp3300_edp_dx: regulator-pp3300-edp-dx {
+		compatible = "regulator-fixed";
+		regulator-name = "pp3300_edp_dx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&en_pp3300_edpbrdg>;
+		enable-active-high;
+		regulator-boot-on;
+		gpio = <&pio 31 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&pp3300_z2>;
+	};
+
+	pp1800_tchscr_report_disable: regulator-pp1800-tchscr-report-disable {
+		compatible = "regulator-fixed";
+		regulator-name = "pp1800_tchscr_report_disable";
+		pinctrl-names = "default";
+		regulator-boot-on;
+		pinctrl-0 = <&touch_pin_report>;
+		gpio = <&pio 37 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&dsi_out {
+	remote-endpoint = <&anx7625_in>;
+};
+
+&i2c0 {
+	clock-frequency = <400000>;
+
+	anx_bridge: anx7625 at 58 {
+		compatible = "analogix,anx7625";
+		reg = <0x58>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&anx7625_pins>;
+		enable-gpios = <&pio 96 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&pio 98 GPIO_ACTIVE_HIGH>;
+		vdd10-supply = <&pp1000_edpbrdg>;
+		vdd18-supply = <&pp1800_edpbrdg_dx>;
+		vdd33-supply = <&pp3300_edp_dx>;
+		analogix,lane0-swing = /bits/ 8 <0x70 0x30>;
+		analogix,lane1-swing = /bits/ 8 <0x70 0x30>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				anx7625_in: endpoint {
+					remote-endpoint = <&dsi_out>;
+					data-lanes = <0 1 2 3>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				anx7625_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+		};
+
+		aux-bus {
+			panel: panel {
+				compatible = "edp-panel";
+				power-supply = <&pp3300_disp_x>;
+				backlight = <&backlight_lcd0>;
+
+				port {
+					panel_in: endpoint {
+						remote-endpoint = <&anx7625_out>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&i2c2 {
+	/delete-node/ trackpad at 15;
+
+	touchpad at 15 {
+		compatible = "hid-over-i2c";
+		reg = <0x15>;
+		interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>;
+		post-power-on-delay-ms = <10>;
+		hid-descr-addr = <0x0001>;
+		vdd-supply = <&pp3300_s3>;
+		wakeup-source;
+	};
+};
+
+&i2c5 {
+	clock-frequency = <400000>;
+	/delete-node/ codec at 1a;
+
+	rt5650: rt5650 at 1a {
+		compatible = "realtek,rt5650";
+		reg = <0x1a>;
+		avdd-supply = <&mt6366_vio18_reg>;
+		cpvdd-supply = <&mt6366_vio18_reg>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&speaker_codec_pins_default>;
+		cbj-sleeve-gpios = <&pio 150 GPIO_ACTIVE_HIGH>;
+		interrupt-parent = <&pio>;
+		interrupts = <17 IRQ_TYPE_EDGE_BOTH>;
+		#sound-dai-cells = <0>;
+		realtek,dmic1-data-pin = <2>;
+		realtek,jd-mode = <2>;
+	};
+};
+
+&i2c_tunnel {
+	/delete-node/ sbs-battery at b;
+
+	battery: sbs-battery at f {
+		compatible = "sbs,sbs-battery";
+		reg = <0xf>;
+		sbs,i2c-retry-count = <2>;
+		sbs,poll-retry-count = <1>;
+	};
+};
+
+&keyboard_controller {
+	keypad,num-columns = <15>;
+
+	function-row-physmap = <
+		MATRIX_KEY(0x00, 0x02, 0)        /* T1 */
+		MATRIX_KEY(0x03, 0x02, 0)        /* T2 */
+		MATRIX_KEY(0x02, 0x02, 0)        /* T3 */
+		MATRIX_KEY(0x01, 0x02, 0)        /* T4 */
+		MATRIX_KEY(0x03, 0x04, 0)        /* T5 */
+		MATRIX_KEY(0x02, 0x04, 0)        /* T6 */
+		MATRIX_KEY(0x01, 0x04, 0)        /* T7 */
+		MATRIX_KEY(0x02, 0x09, 0)        /* T8 */
+		MATRIX_KEY(0x01, 0x09, 0)        /* T9 */
+		MATRIX_KEY(0x00, 0x04, 0)        /* T10 */
+		MATRIX_KEY(0x00, 0x01, 0)        /* T11 */
+		MATRIX_KEY(0x01, 0x05, 0)        /* T12 */
+	>;
+
+	linux,keymap = <
+		CROS_STD_MAIN_KEYMAP
+		MATRIX_KEY(0x00, 0x02, KEY_BACK)           /* T1 */
+		MATRIX_KEY(0x03, 0x02, KEY_REFRESH)        /* T2 */
+		MATRIX_KEY(0x02, 0x02, KEY_ZOOM)           /* T3 */
+		MATRIX_KEY(0x01, 0x02, KEY_SCALE)          /* T4 */
+		MATRIX_KEY(0x03, 0x04, KEY_SYSRQ)          /* T5 */
+		MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN) /* T6 */
+		MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP)   /* T7 */
+		MATRIX_KEY(0x02, 0x09, KEY_MUTE)           /* T8 */
+		MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN)	   /* T9 */
+		MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP)	   /* T10 */
+		MATRIX_KEY(0x00, 0x01, KEY_MICMUTE)        /* T11 */
+		MATRIX_KEY(0x01, 0x05, KEY_CONTROLPANEL)   /* T12 */
+		MATRIX_KEY(0x03, 0x05, KEY_PREVIOUSSONG)   /* T13 */
+		MATRIX_KEY(0x00, 0x09, KEY_PLAYPAUSE)	   /* T14 */
+		MATRIX_KEY(0x00, 0x0b, KEY_NEXTSONG)	   /* T15 */
+		MATRIX_KEY(0x03, 0x00, KEY_LEFTMETA)	   /* Search*/
+		MATRIX_KEY(0x01, 0x0e, KEY_LEFTCTRL)	   /* Left Control*/
+		MATRIX_KEY(0x06, 0x0d, KEY_LEFTALT)        /* Left ALT*/
+		MATRIX_KEY(0x03, 0x0e, KEY_RIGHTCTRL)      /* Right Control*/
+		MATRIX_KEY(0x06, 0x0a, KEY_BACKSLASH)      /* BACKSLASH*/
+	>;
+};
+
+&mmc1_pins_default {
+	pins-clk {
+		drive-strength = <8>;
+	};
+
+	pins-cmd-dat {
+		drive-strength = <8>;
+	};
+};
+
+&mmc1_pins_uhs {
+	pins-clk {
+		drive-strength = <8>;
+	};
+
+	pins-cmd-dat {
+		drive-strength = <8>;
+	};
+};
+
+&pen_insert {
+	wakeup-event-action = <EV_ACT_ANY>;
+};
+
+&pio {
+	anx7625_pins: anx7625-pins {
+		pins-int {
+			pinmux = <PINMUX_GPIO9__FUNC_GPIO9>;
+			input-enable;
+			bias-disable;
+		};
+
+		pins-reset {
+			pinmux = <PINMUX_GPIO98__FUNC_GPIO98>;
+			output-low;
+		};
+
+		pins-power-en {
+			pinmux = <PINMUX_GPIO96__FUNC_GPIO96>;
+			output-low;
+		};
+	};
+
+	en_pp1000_edpbrdg: pp1000-edpbrdg-en-pins {
+		pins-vreg-en {
+			pinmux = <PINMUX_GPIO29__FUNC_GPIO29>;
+			output-low;
+		};
+	};
+
+	en_pp1800_edpbrdg: pp1800-edpbrdg-en-pins {
+		pins-vreg-en {
+			pinmux = <PINMUX_GPIO30__FUNC_GPIO30>;
+			output-low;
+		};
+	};
+
+	en_pp3300_edpbrdg: pp3300-edpbrdg-en-pins {
+		pins-vreg-en {
+			pinmux = <PINMUX_GPIO31__FUNC_GPIO31>;
+			output-low;
+		};
+	};
+
+	touch_pin_report: pin-report-pins {
+		pins-touch-en {
+			pinmux = <PINMUX_GPIO37__FUNC_GPIO37>;
+			output-low;
+		};
+	};
+};
+
+&sound {
+	compatible = "mediatek,mt8186-mt6366-rt5650-sound";
+	model = "mt8186_rt5650";
+	mediatek,adsp = <&adsp>;
+
+	audio-routing =
+		"Headphone", "HPOL",
+		"Headphone", "HPOR",
+		"IN1P", "Headset Mic",
+		"IN1N", "Headset Mic",
+		"Speakers", "SPOL",
+		"Speakers", "SPOR",
+		"HDMI1", "TX";
+
+	hs-playback-dai-link {
+		codec {
+			sound-dai = <&rt5650>;
+		};
+	};
+
+	hs-capture-dai-link {
+		codec {
+			sound-dai = <&rt5650>;
+		};
+	};
+
+	spk-share-dai-link {
+	};
+
+	spk-hdmi-playback-dai-link {
+		codec {
+			sound-dai = <&it6505dptx>;
+		};
+	};
+};
+
+&touchscreen_pins {
+	/delete-node/ pins-report-sw;
+};
+
+&wifi_enable_pin {
+	pins-wifi-enable {
+		pinmux = <PINMUX_GPIO51__FUNC_GPIO51>;
+	};
+};
+
+&wifi_pwrseq {
+	reset-gpios = <&pio 51 GPIO_ACTIVE_LOW>;
+};
-- 
2.17.1



From xiazhengqiao at huaqin.corp-partner.google.com  Wed Dec 11 22:20:45 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Thu, 12 Dec 2024 14:20:45 +0800
Subject: [PATCH v5 3/4] arm64: dts: mediatek: Add extcon node for DP bridge
In-Reply-To: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <20241212062046.22509-4-xiazhengqiao@huaqin.corp-partner.google.com>

Add extcon node for DP bridge to make the display work properly.

Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
index cfcc7909dfe6..e324e3fd347e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
@@ -424,6 +424,7 @@
 		ovdd-supply = <&mt6366_vsim2_reg>;
 		pwr18-supply = <&pp1800_dpbrdg_dx>;
 		reset-gpios = <&pio 177 GPIO_ACTIVE_LOW>;
+		extcon = <&usbc_extcon>;
 
 		ports {
 			#address-cells = <1>;
@@ -1656,6 +1657,11 @@
 				try-power-role = "source";
 			};
 		};
+
+		usbc_extcon: extcon0 {
+			compatible = "google,extcon-usbc-cros-ec";
+			google,usb-port-id = <0>;
+		};
 	};
 };
 
-- 
2.17.1



From xiazhengqiao at huaqin.corp-partner.google.com  Wed Dec 11 22:20:42 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Thu, 12 Dec 2024 14:20:42 +0800
Subject: [PATCH v5 0/4] arm64: dts: mediatek: Add MT8186 Chinchou
Message-ID: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>

This is v5 of the MT8186 Chromebook device tree series to support
MT8186 chinchou platform. It is based on the "corsola" design.
It includes chinchou and chinchou360, including LTE, stylus,
touchscreen combinations.

Changes in v5:
- move sku17 here to keep alphabetical order.
- do not use the MTK_DRIVE_xxx definitions.
- Modify exton to extcon
- Link to v4: https://patchwork.kernel.org/project/linux-arm-kernel/cover/20241202032035.29045-1-xiazhengqiao at huaqin.corp-partner.google.com/

Changes in v4:
- modify 'rt1019p_pins_default' to 'speaker_codec_pins_default'
- Move usbc_extcon out of typec
- Link to v3: https://patchwork.kernel.org/project/linux-arm-kernel/cover/20241021072626.15102-1-xiazhengqiao at huaqin.corp-partner.google.com/

Changes in v3:
- Add a patch to change codec in pmic (in mt8186-corsola.dtsi) to audio-codec
- Link to v2: https://lore.kernel.org/all/20241018091135.17075-1-xiazhengqiao at huaqin.corp-partner.google.com/

Changes in v2:
- Modify location of "const: google,chinchou-sku17" in mediatek.yaml
- rename "pin-report" to "pin-report-pins"
- add "vcc33-supply" and "vcc33-supply" 
- rename "cbj-sleeve-gpio" to "cbj-sleeve-gpios"
- modify subnode of sound 
- Link to v1: https://lore.kernel.org/all/172900161180.733089.8963543745385219831.robh at kernel.org/


Zhengqiao Xia (4):
  dt-bindings: arm: mediatek: Add MT8186 Chinchou Chromebook
  arm64: dts: mediatek: Add MT8186 Chinchou Chromebooks
  arm64: dts: mediatek: Add extcon node for DP bridge
  arm64: dts: mediatek: Modify audio codec name for pmic

 .../devicetree/bindings/arm/mediatek.yaml     |  28 ++
 arch/arm64/boot/dts/mediatek/Makefile         |   3 +
 .../mediatek/mt8186-corsola-chinchou-sku0.dts |  18 +
 .../mediatek/mt8186-corsola-chinchou-sku1.dts |  35 ++
 .../mt8186-corsola-chinchou-sku16.dts         |  29 ++
 .../dts/mediatek/mt8186-corsola-chinchou.dtsi | 321 ++++++++++++++++++
 .../boot/dts/mediatek/mt8186-corsola.dtsi     |   8 +-
 7 files changed, 441 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku0.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku1.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou-sku16.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-chinchou.dtsi

-- 
2.17.1



From xiazhengqiao at huaqin.corp-partner.google.com  Wed Dec 11 22:20:46 2024
From: xiazhengqiao at huaqin.corp-partner.google.com (Zhengqiao Xia)
Date: Thu, 12 Dec 2024 14:20:46 +0800
Subject: [PATCH v5 4/4] arm64: dts: mediatek: Modify audio codec name for pmic
In-Reply-To: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <20241212062046.22509-5-xiazhengqiao@huaqin.corp-partner.google.com>

change `codec` in pmic (in mt8186-corsola.dtsi) to `audio-codec`

Signed-off-by: Zhengqiao Xia <xiazhengqiao at huaqin.corp-partner.google.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
index e324e3fd347e..cebb134331fb 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
@@ -1276,7 +1276,7 @@
 		interrupts-extended = <&pio 201 IRQ_TYPE_LEVEL_HIGH>;
 		#interrupt-cells = <2>;
 
-		mt6366codec: codec {
+		mt6366codec: audio-codec {
 			compatible = "mediatek,mt6366-sound", "mediatek,mt6358-sound";
 			Avdd-supply = <&mt6366_vaud28_reg>;
 			mediatek,dmic-mode = <1>; /* one-wire */
-- 
2.17.1



From xu.yang_2 at nxp.com  Wed Dec 11 22:48:34 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 12 Dec 2024 14:48:34 +0800
Subject: [PATCH v3] perf: imx9_perf: Introduce AXI filter version to refactor the driver and better extension
Message-ID: <20241212064834.1353149-1-xu.yang_2@nxp.com>

The imx93 is the first supported DDR PMU that supports read transaction,
write transaction and read beats events which corresponding respecitively
to counter 2, 3 and 4.

However, transaction-based AXI match has low accuracy when get total bits
compared to beats-based. And imx93 doesn't assign AXI_ID to each master.
So axi filter is not used widely on imx93. This could be regards as AXI
filter version 1.

To improve the AXI filter capability, imx95 supports 1 read beats and 3
write beats event which corresponding respecitively to counter 2-5. imx95
also detailed AXI_ID allocation so that most of the master could be count
individually. This could be regards as AXI filter version 2.

This will introduce AXI filter version to refactor the driver and support
better extension, such as coming imx943. This is also a potential fix on
imx91 when configure axi filter.

Fixes: 44798fe136dc ("perf: imx_perf: add support for i.MX91 platform")
Cc: stable at vger.kernel.org
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v3:
 - fix checkpatch warning
 - add fix tag
Changes in v2:
 - modify subject
 - add comments for AXI_FILTER version
 - type -> filter_ver
---
 drivers/perf/fsl_imx9_ddr_perf.c | 33 ++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
index 3c856d9a4e97..843f163e6c33 100644
--- a/drivers/perf/fsl_imx9_ddr_perf.c
+++ b/drivers/perf/fsl_imx9_ddr_perf.c
@@ -63,8 +63,21 @@
 
 static DEFINE_IDA(ddr_ida);
 
+/*
+ * V1 support 1 read transaction, 1 write transaction and 1 read beats
+ * event which corresponding respecitively to counter 2, 3 and 4.
+ */
+#define DDR_PERF_AXI_FILTER_V1		0x1
+
+/*
+ * V2 support 1 read beats and 3 write beats events which corresponding
+ * respecitively to counter 2-5.
+ */
+#define DDR_PERF_AXI_FILTER_V2		0x2
+
 struct imx_ddr_devtype_data {
 	const char *identifier;		/* system PMU identifier for userspace */
+	unsigned int filter_ver;	/* AXI filter version */
 };
 
 struct ddr_pmu {
@@ -83,24 +96,27 @@ struct ddr_pmu {
 
 static const struct imx_ddr_devtype_data imx91_devtype_data = {
 	.identifier = "imx91",
+	.filter_ver = DDR_PERF_AXI_FILTER_V1
 };
 
 static const struct imx_ddr_devtype_data imx93_devtype_data = {
 	.identifier = "imx93",
+	.filter_ver = DDR_PERF_AXI_FILTER_V1
 };
 
 static const struct imx_ddr_devtype_data imx95_devtype_data = {
 	.identifier = "imx95",
+	.filter_ver = DDR_PERF_AXI_FILTER_V2
 };
 
-static inline bool is_imx93(struct ddr_pmu *pmu)
+static inline bool axi_filter_v1(struct ddr_pmu *pmu)
 {
-	return pmu->devtype_data == &imx93_devtype_data;
+	return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V1;
 }
 
-static inline bool is_imx95(struct ddr_pmu *pmu)
+static inline bool axi_filter_v2(struct ddr_pmu *pmu)
 {
-	return pmu->devtype_data == &imx95_devtype_data;
+	return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V2;
 }
 
 static const struct of_device_id imx_ddr_pmu_dt_ids[] = {
@@ -155,7 +171,7 @@ static const struct attribute_group ddr_perf_cpumask_attr_group = {
 struct imx9_pmu_events_attr {
 	struct device_attribute attr;
 	u64 id;
-	const void *devtype_data;
+	const struct imx_ddr_devtype_data *devtype_data;
 };
 
 static ssize_t ddr_pmu_event_show(struct device *dev,
@@ -307,7 +323,8 @@ ddr_perf_events_attrs_is_visible(struct kobject *kobj,
 	if (!eattr->devtype_data)
 		return attr->mode;
 
-	if (eattr->devtype_data != ddr_pmu->devtype_data)
+	if (eattr->devtype_data != ddr_pmu->devtype_data &&
+	    eattr->devtype_data->filter_ver != ddr_pmu->devtype_data->filter_ver)
 		return 0;
 
 	return attr->mode;
@@ -624,11 +641,11 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
 	hwc->idx = counter;
 	hwc->state |= PERF_HES_STOPPED;
 
-	if (is_imx93(pmu))
+	if (axi_filter_v1(pmu))
 		/* read trans, write trans, read beat */
 		imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
 
-	if (is_imx95(pmu))
+	if (axi_filter_v2(pmu))
 		/* write beat, read beat2, read beat1, read beat */
 		imx95_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
 
-- 
2.34.1



From viresh.kumar at linaro.org  Wed Dec 11 22:51:00 2024
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Dec 2024 12:21:00 +0530
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <20241206135600.4083965-2-beata.michalska@arm.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
Message-ID: <20241212065100.sjb7lrlmksbm2hdk@vireshk-i7>

On 06-12-24, 13:55, Beata Michalska wrote:
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 04fc786dd2c0..70df2a24437b 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -747,9 +747,14 @@ show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
>  show_one(scaling_min_freq, min);
>  show_one(scaling_max_freq, max);
>  
> -__weak unsigned int arch_freq_get_on_cpu(int cpu)
> +__weak int arch_freq_get_on_cpu(int cpu)
>  {
> -	return 0;
> +	return -EOPNOTSUPP;

I did suggest not doing this as it may not be acceptable.

https://lore.kernel.org/all/CAKohpokFUpQyHYO017kOn-Jbt0CFZ1GuxoG3N-fenWJ_poW=4Q at mail.gmail.com/

-- 
viresh


From xu.yang_2 at nxp.com  Wed Dec 11 22:57:08 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 12 Dec 2024 14:57:08 +0800
Subject: [PATCH RESEND v3] perf: imx9_perf: Introduce AXI filter version to refactor the driver and better extension
Message-ID: <20241212065708.1353513-1-xu.yang_2@nxp.com>

The imx93 is the first supported DDR PMU that supports read transaction,
write transaction and read beats events which corresponding respecitively
to counter 2, 3 and 4.

However, transaction-based AXI match has low accuracy when get total bits
compared to beats-based. And imx93 doesn't assign AXI_ID to each master.
So axi filter is not used widely on imx93. This could be regards as AXI
filter version 1.

To improve the AXI filter capability, imx95 supports 1 read beats and 3
write beats event which corresponding respecitively to counter 2-5. imx95
also detailed AXI_ID allocation so that most of the master could be count
individually. This could be regards as AXI filter version 2.

This will introduce AXI filter version to refactor the driver and support
better extension, such as coming imx943. This is also a potential fix on
imx91 when configure axi filter.

Fixes: 44798fe136dc ("perf: imx_perf: add support for i.MX91 platform")
Cc: stable at vger.kernel.org
Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v3:
 - fix checkpatch warning
 - add fix tag
 - add Rb tag [RESEND]
Changes in v2:
 - modify subject
 - add comments for AXI_FILTER version
 - type -> filter_ver
---
 drivers/perf/fsl_imx9_ddr_perf.c | 33 ++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
index 3c856d9a4e97..843f163e6c33 100644
--- a/drivers/perf/fsl_imx9_ddr_perf.c
+++ b/drivers/perf/fsl_imx9_ddr_perf.c
@@ -63,8 +63,21 @@
 
 static DEFINE_IDA(ddr_ida);
 
+/*
+ * V1 support 1 read transaction, 1 write transaction and 1 read beats
+ * event which corresponding respecitively to counter 2, 3 and 4.
+ */
+#define DDR_PERF_AXI_FILTER_V1		0x1
+
+/*
+ * V2 support 1 read beats and 3 write beats events which corresponding
+ * respecitively to counter 2-5.
+ */
+#define DDR_PERF_AXI_FILTER_V2		0x2
+
 struct imx_ddr_devtype_data {
 	const char *identifier;		/* system PMU identifier for userspace */
+	unsigned int filter_ver;	/* AXI filter version */
 };
 
 struct ddr_pmu {
@@ -83,24 +96,27 @@ struct ddr_pmu {
 
 static const struct imx_ddr_devtype_data imx91_devtype_data = {
 	.identifier = "imx91",
+	.filter_ver = DDR_PERF_AXI_FILTER_V1
 };
 
 static const struct imx_ddr_devtype_data imx93_devtype_data = {
 	.identifier = "imx93",
+	.filter_ver = DDR_PERF_AXI_FILTER_V1
 };
 
 static const struct imx_ddr_devtype_data imx95_devtype_data = {
 	.identifier = "imx95",
+	.filter_ver = DDR_PERF_AXI_FILTER_V2
 };
 
-static inline bool is_imx93(struct ddr_pmu *pmu)
+static inline bool axi_filter_v1(struct ddr_pmu *pmu)
 {
-	return pmu->devtype_data == &imx93_devtype_data;
+	return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V1;
 }
 
-static inline bool is_imx95(struct ddr_pmu *pmu)
+static inline bool axi_filter_v2(struct ddr_pmu *pmu)
 {
-	return pmu->devtype_data == &imx95_devtype_data;
+	return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V2;
 }
 
 static const struct of_device_id imx_ddr_pmu_dt_ids[] = {
@@ -155,7 +171,7 @@ static const struct attribute_group ddr_perf_cpumask_attr_group = {
 struct imx9_pmu_events_attr {
 	struct device_attribute attr;
 	u64 id;
-	const void *devtype_data;
+	const struct imx_ddr_devtype_data *devtype_data;
 };
 
 static ssize_t ddr_pmu_event_show(struct device *dev,
@@ -307,7 +323,8 @@ ddr_perf_events_attrs_is_visible(struct kobject *kobj,
 	if (!eattr->devtype_data)
 		return attr->mode;
 
-	if (eattr->devtype_data != ddr_pmu->devtype_data)
+	if (eattr->devtype_data != ddr_pmu->devtype_data &&
+	    eattr->devtype_data->filter_ver != ddr_pmu->devtype_data->filter_ver)
 		return 0;
 
 	return attr->mode;
@@ -624,11 +641,11 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
 	hwc->idx = counter;
 	hwc->state |= PERF_HES_STOPPED;
 
-	if (is_imx93(pmu))
+	if (axi_filter_v1(pmu))
 		/* read trans, write trans, read beat */
 		imx93_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
 
-	if (is_imx95(pmu))
+	if (axi_filter_v2(pmu))
 		/* write beat, read beat2, read beat1, read beat */
 		imx95_ddr_perf_monitor_config(pmu, event_id, counter, cfg1, cfg2);
 
-- 
2.34.1



From towinchenmi at gmail.com  Wed Dec 11 23:03:00 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 12 Dec 2024 15:03:00 +0800
Subject: [PATCH v2 1/7] dt-bindings: cpufreq: apple,cluster-cpufreq: Add A7-A11, T2 compatibles
In-Reply-To: <20241212070344.3858-1-towinchenmi@gmail.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
Message-ID: <20241212070344.3858-2-towinchenmi@gmail.com>

Add compatibles for Apple A7-A11, T2 SoCs.

Apple A7, A8, A8X gets the per-SoC compatible and the A7
"apple,s5l8960x-cluster-cpufreq" compatible.

Apple A9, A9X, A10, A10X, T2, A11 gets the per-SoC compatible, M1
"apple,t8103-cluster-cpufreq" compatible, then the
"apple,cluster-cpufreq" fallback compatible.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../bindings/cpufreq/apple,cluster-cpufreq.yaml        | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml b/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml
index 76cb9726660e..896276b8c6bb 100644
--- a/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml
+++ b/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml
@@ -24,9 +24,17 @@ properties:
               - apple,t8112-cluster-cpufreq
           - const: apple,cluster-cpufreq
       - items:
-          - const: apple,t6000-cluster-cpufreq
+          - enum:
+              - apple,s8000-cluster-cpufreq
+              - apple,t8010-cluster-cpufreq
+              - apple,t8015-cluster-cpufreq
+              - apple,t6000-cluster-cpufreq
           - const: apple,t8103-cluster-cpufreq
           - const: apple,cluster-cpufreq
+      - items:
+          - const: apple,t7000-cluster-cpufreq
+          - const: apple,s5l8960x-cluster-cpufreq
+      - const: apple,s5l8960x-cluster-cpufreq
 
   reg:
     maxItems: 1
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 23:03:01 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 12 Dec 2024 15:03:01 +0800
Subject: [PATCH v2 2/7] cpufreq: apple-soc: Drop setting the PS2 field on M2+
In-Reply-To: <20241212070344.3858-1-towinchenmi@gmail.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
Message-ID: <20241212070344.3858-3-towinchenmi@gmail.com>

From: Hector Martin <marcan at marcan.st>

Newer device do not use this. It is not known what this field does,
but change the behavior to be same as macOS to be safe.

Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 4dcacab9b4bf..ad6c7b8f290c 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -25,7 +25,7 @@
 #define APPLE_DVFS_CMD			0x20
 #define APPLE_DVFS_CMD_BUSY		BIT(31)
 #define APPLE_DVFS_CMD_SET		BIT(25)
-#define APPLE_DVFS_CMD_PS2		GENMASK(16, 12)
+#define APPLE_DVFS_CMD_PS2		GENMASK(15, 12)
 #define APPLE_DVFS_CMD_PS1		GENMASK(4, 0)
 
 /* Same timebase as CPU counter (24MHz) */
@@ -55,6 +55,7 @@
 #define APPLE_DVFS_TRANSITION_TIMEOUT 100
 
 struct apple_soc_cpufreq_info {
+	bool has_ps2;
 	u64 max_pstate;
 	u64 cur_pstate_mask;
 	u64 cur_pstate_shift;
@@ -69,18 +70,21 @@ struct apple_cpu_priv {
 static struct cpufreq_driver apple_soc_cpufreq_driver;
 
 static const struct apple_soc_cpufreq_info soc_t8103_info = {
+	.has_ps2 = true,
 	.max_pstate = 15,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8103,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103,
 };
 
 static const struct apple_soc_cpufreq_info soc_t8112_info = {
+	.has_ps2 = false,
 	.max_pstate = 31,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8112,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8112,
 };
 
 static const struct apple_soc_cpufreq_info soc_default_info = {
+	.has_ps2 = false,
 	.max_pstate = 15,
 	.cur_pstate_mask = 0, /* fallback */
 };
@@ -148,9 +152,12 @@ static int apple_soc_cpufreq_set_target(struct cpufreq_policy *policy,
 		return -EIO;
 	}
 
-	reg &= ~(APPLE_DVFS_CMD_PS1 | APPLE_DVFS_CMD_PS2);
+	reg &= ~APPLE_DVFS_CMD_PS1;
 	reg |= FIELD_PREP(APPLE_DVFS_CMD_PS1, pstate);
-	reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
+	if (priv->info->has_ps2) {
+		reg &= ~APPLE_DVFS_CMD_PS2;
+		reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
+	}
 	reg |= APPLE_DVFS_CMD_SET;
 
 	writeq_relaxed(reg, priv->reg_base + APPLE_DVFS_CMD);
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 23:03:02 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 12 Dec 2024 15:03:02 +0800
Subject: [PATCH v2 3/7] cpufreq: apple-soc: Allow per-SoC configuration of APPLE_DVFS_CMD_PS1
In-Reply-To: <20241212070344.3858-1-towinchenmi@gmail.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
Message-ID: <20241212070344.3858-4-towinchenmi@gmail.com>

Support for SoC that has a different APPLE_DVFS_CMD_PS1 will be added soon,
so modify the driver first to allow it to be configured per-SoC.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index ad6c7b8f290c..90e34105b50b 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -27,6 +27,7 @@
 #define APPLE_DVFS_CMD_SET		BIT(25)
 #define APPLE_DVFS_CMD_PS2		GENMASK(15, 12)
 #define APPLE_DVFS_CMD_PS1		GENMASK(4, 0)
+#define APPLE_DVFS_CMD_PS1_SHIFT	0
 
 /* Same timebase as CPU counter (24MHz) */
 #define APPLE_DVFS_LAST_CHG_TIME	0x38
@@ -59,6 +60,8 @@ struct apple_soc_cpufreq_info {
 	u64 max_pstate;
 	u64 cur_pstate_mask;
 	u64 cur_pstate_shift;
+	u64 ps1_mask;
+	u64 ps1_shift;
 };
 
 struct apple_cpu_priv {
@@ -74,6 +77,8 @@ static const struct apple_soc_cpufreq_info soc_t8103_info = {
 	.max_pstate = 15,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8103,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103,
+	.ps1_mask = APPLE_DVFS_CMD_PS1,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_SHIFT,
 };
 
 static const struct apple_soc_cpufreq_info soc_t8112_info = {
@@ -81,12 +86,16 @@ static const struct apple_soc_cpufreq_info soc_t8112_info = {
 	.max_pstate = 31,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8112,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8112,
+	.ps1_mask = APPLE_DVFS_CMD_PS1,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_SHIFT,
 };
 
 static const struct apple_soc_cpufreq_info soc_default_info = {
 	.has_ps2 = false,
 	.max_pstate = 15,
 	.cur_pstate_mask = 0, /* fallback */
+	.ps1_mask = APPLE_DVFS_CMD_PS1,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_SHIFT,
 };
 
 static const struct of_device_id apple_soc_cpufreq_of_match[] __maybe_unused = {
@@ -152,8 +161,8 @@ static int apple_soc_cpufreq_set_target(struct cpufreq_policy *policy,
 		return -EIO;
 	}
 
-	reg &= ~APPLE_DVFS_CMD_PS1;
-	reg |= FIELD_PREP(APPLE_DVFS_CMD_PS1, pstate);
+	reg &= ~priv->info->ps1_mask;
+	reg |= pstate << priv->info->ps1_shift;
 	if (priv->info->has_ps2) {
 		reg &= ~APPLE_DVFS_CMD_PS2;
 		reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 23:03:03 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 12 Dec 2024 15:03:03 +0800
Subject: [PATCH v2 4/7] cpufreq: apple-soc: Use 32-bit read for status register
In-Reply-To: <20241212070344.3858-1-towinchenmi@gmail.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
Message-ID: <20241212070344.3858-5-towinchenmi@gmail.com>

Apple A7-A9(X) SoCs requires 32-bit reads on the status register. Newer
SoCs accepts 32-bit reads on the status register as well.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 90e34105b50b..b27d261fe5a6 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -122,7 +122,7 @@ static unsigned int apple_soc_cpufreq_get_rate(unsigned int cpu)
 	unsigned int pstate;
 
 	if (priv->info->cur_pstate_mask) {
-		u64 reg = readq_relaxed(priv->reg_base + APPLE_DVFS_STATUS);
+		u32 reg = readl_relaxed(priv->reg_base + APPLE_DVFS_STATUS);
 
 		pstate = (reg & priv->info->cur_pstate_mask) >>  priv->info->cur_pstate_shift;
 	} else {
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 23:03:04 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 12 Dec 2024 15:03:04 +0800
Subject: [PATCH v2 5/7] cpufreq: apple-soc: Increase cluster switch timeout to 400us
In-Reply-To: <20241212070344.3858-1-towinchenmi@gmail.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
Message-ID: <20241212070344.3858-6-towinchenmi@gmail.com>

Apple A11 SoC takes a long time to switch. Maximum switch time
observed is 345us, so increase the cluster switch timeout to 400us
to be safe.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index b27d261fe5a6..94e57f055a5f 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -53,7 +53,7 @@
 #define APPLE_DVFS_PLL_FACTOR_MULT	GENMASK(31, 16)
 #define APPLE_DVFS_PLL_FACTOR_DIV	GENMASK(15, 0)
 
-#define APPLE_DVFS_TRANSITION_TIMEOUT 100
+#define APPLE_DVFS_TRANSITION_TIMEOUT 400
 
 struct apple_soc_cpufreq_info {
 	bool has_ps2;
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 23:03:05 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 12 Dec 2024 15:03:05 +0800
Subject: [PATCH v2 6/7] cpufreq: apple-soc: Set fallback transition latency to APPLE_DVFS_TRANSITION_TIMEOUT
In-Reply-To: <20241212070344.3858-1-towinchenmi@gmail.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
Message-ID: <20241212070344.3858-7-towinchenmi@gmail.com>

The driver already assumes transitions will not take longer than
APPLE_DVFS_TRANSITION_TIMEOUT in apple_soc_cpufreq_set_target(), so it
makes little sense to set CPUFREQ_ETERNAL as the transition latency
when the transistion latency is not given by the opp-table.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 94e57f055a5f..c9f31a3653e2 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -291,7 +291,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy)
 
 	transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
 	if (!transition_latency)
-		transition_latency = CPUFREQ_ETERNAL;
+		transition_latency = APPLE_DVFS_TRANSITION_TIMEOUT * 1000;
 
 	policy->cpuinfo.transition_latency = transition_latency;
 	policy->dvfs_possible_from_any_cpu = true;
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 11 23:03:06 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 12 Dec 2024 15:03:06 +0800
Subject: [PATCH v2 7/7] cpufreq: apple-soc: Add Apple A7-A8X SoC cpufreq support
In-Reply-To: <20241212070344.3858-1-towinchenmi@gmail.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
Message-ID: <20241212070344.3858-8-towinchenmi@gmail.com>

These SoCs only use 3 bits for p-states, and have a different
APPLE_DVFS_CMD_PS1 mask value.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 30 +++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index c9f31a3653e2..c3a6dd8ae22a 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -22,12 +22,14 @@
 #include <linux/pm_opp.h>
 #include <linux/slab.h>
 
-#define APPLE_DVFS_CMD			0x20
-#define APPLE_DVFS_CMD_BUSY		BIT(31)
-#define APPLE_DVFS_CMD_SET		BIT(25)
-#define APPLE_DVFS_CMD_PS2		GENMASK(15, 12)
-#define APPLE_DVFS_CMD_PS1		GENMASK(4, 0)
-#define APPLE_DVFS_CMD_PS1_SHIFT	0
+#define APPLE_DVFS_CMD				0x20
+#define APPLE_DVFS_CMD_BUSY			BIT(31)
+#define APPLE_DVFS_CMD_SET			BIT(25)
+#define APPLE_DVFS_CMD_PS1_S5L8960X		GENMASK(24, 22)
+#define APPLE_DVFS_CMD_PS1_S5L8960X_SHIFT	22
+#define APPLE_DVFS_CMD_PS2			GENMASK(15, 12)
+#define APPLE_DVFS_CMD_PS1			GENMASK(4, 0)
+#define APPLE_DVFS_CMD_PS1_SHIFT		0
 
 /* Same timebase as CPU counter (24MHz) */
 #define APPLE_DVFS_LAST_CHG_TIME	0x38
@@ -36,6 +38,9 @@
  * Apple ran out of bits and had to shift this in T8112...
  */
 #define APPLE_DVFS_STATUS			0x50
+#define APPLE_DVFS_STATUS_CUR_PS_S5L8960X	GENMASK(5, 3)
+#define APPLE_DVFS_STATUS_CUR_PS_SHIFT_S5L8960X	3
+#define APPLE_DVFS_STATUS_TGT_PS_S5L8960X	GENMASK(2, 0)
 #define APPLE_DVFS_STATUS_CUR_PS_T8103		GENMASK(7, 4)
 #define APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103	4
 #define APPLE_DVFS_STATUS_TGT_PS_T8103		GENMASK(3, 0)
@@ -72,6 +77,15 @@ struct apple_cpu_priv {
 
 static struct cpufreq_driver apple_soc_cpufreq_driver;
 
+static const struct apple_soc_cpufreq_info soc_s5l8960x_info = {
+	.has_ps2 = false,
+	.max_pstate = 7,
+	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_S5L8960X,
+	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_S5L8960X,
+	.ps1_mask = APPLE_DVFS_CMD_PS1_S5L8960X,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_S5L8960X_SHIFT,
+};
+
 static const struct apple_soc_cpufreq_info soc_t8103_info = {
 	.has_ps2 = true,
 	.max_pstate = 15,
@@ -99,6 +113,10 @@ static const struct apple_soc_cpufreq_info soc_default_info = {
 };
 
 static const struct of_device_id apple_soc_cpufreq_of_match[] __maybe_unused = {
+	{
+		.compatible = "apple,s5l8960x-cluster-cpufreq",
+		.data = &soc_s5l8960x_info,
+	},
 	{
 		.compatible = "apple,t8103-cluster-cpufreq",
 		.data = &soc_t8103_info,
-- 
2.47.1



From viresh.kumar at linaro.org  Wed Dec 11 23:07:12 2024
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Dec 2024 12:37:12 +0530
Subject: [PATCH] cpufreq: enable 1200Mhz clock speed for armada-37xx
In-Reply-To: <20241125211452.14987-1-ben@bens.haus>
References: <20241125211452.14987-1-ben@bens.haus>
Message-ID: <20241212070712.txkxgmiugzji3doz@vireshk-i7>

Marek,

On 25-11-24, 13:14, bschnei at gmail.com wrote:
> From: Benjamin Schneider <ben at bens.haus>
> 
> This frequency was disabled because of stability problems whose source could
> not be accurately identified[1]. After seven months of testing, the evidence
> points to an incorrectly configured bootloader as the source of the historical
> instability. Testing was performed on two A3720 devices with this frequency
> enabled and the ondemand policy in use. Marvell merged[2] changes to their
> bootloader source needed to address the stability issue. This driver should
> expose this frequency option to users.
> 
> [1] https://github.com/torvalds/linux/commit/484f2b7c61b9ae58cc00c5127bcbcd9177af8dfe
> [2] https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell/pull/44
> 
> Signed-off-by: Benjamin Schneider <ben at bens.haus>
> Reviewed-by: Pali Roh?r <pali at kernel.org>
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> Acked-by: Gregory CLEMENT <gregory.clement at bootlin.com>
> ---
>  drivers/cpufreq/armada-37xx-cpufreq.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
> index bea41ccabf1f..f28a4435fba7 100644
> --- a/drivers/cpufreq/armada-37xx-cpufreq.c
> +++ b/drivers/cpufreq/armada-37xx-cpufreq.c
> @@ -102,11 +102,7 @@ struct armada_37xx_dvfs {
>  };
>  
>  static struct armada_37xx_dvfs armada_37xx_dvfs[] = {
> -	/*
> -	 * The cpufreq scaling for 1.2 GHz variant of the SOC is currently
> -	 * unstable because we do not know how to configure it properly.
> -	 */
> -	/* {.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} }, */
> +	{.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} },
>  	{.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} },
>  	{.cpu_freq_max = 800*1000*1000,  .divider = {1, 2, 3, 4} },
>  	{.cpu_freq_max = 600*1000*1000,  .divider = {2, 4, 5, 6} },

Any inputs on this before I apply it ?

-- 
viresh


From towinchenmi at gmail.com  Wed Dec 11 23:02:59 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 12 Dec 2024 15:02:59 +0800
Subject: [PATCH v2 0/7] Apple A7-A11, T2 SoC cpufreq support
Message-ID: <20241212070344.3858-1-towinchenmi@gmail.com>

This series add driver support for cpufreq Apple A7-A11, T2 SoCs.
Device Tree nodes will be included in another series.

Changes since v1:
- transition_latency is in ns, APPLE_DVFS_TRANSITION_TIMEOUT in us.
Multiply APPLE_DVFS_TRANSITION_TIMEOUT by 1000 before setting it as
transition_latency.

v1: https://lore.kernel.org/asahi/20241211112244.18393-1-towinchenmi at gmail.com/T

Nick Chan
---
Hector Martin (1):
  cpufreq: apple-soc: Drop setting the PS2 field on M2+

Nick Chan (6):
  dt-bindings: cpufreq: apple,cluster-cpufreq: Add A7-A11, T2
    compatibles
  cpufreq: apple-soc: Allow per-SoC configuration of APPLE_DVFS_CMD_PS1
  cpufreq: apple-soc: Use 32-bit read for status register
  cpufreq: apple-soc: Increase cluster switch timeout to 400us
  cpufreq: apple-soc: Set fallback transition latency to
    APPLE_DVFS_TRANSITION_TIMEOUT
  cpufreq: apple-soc: Add Apple A7-A8X SoC cpufreq support

 .../cpufreq/apple,cluster-cpufreq.yaml        | 10 +++-
 drivers/cpufreq/apple-soc-cpufreq.c           | 56 +++++++++++++++----
 2 files changed, 54 insertions(+), 12 deletions(-)


base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
-- 
2.47.1



From michal.simek at amd.com  Wed Dec 11 23:12:34 2024
From: michal.simek at amd.com (Michal Simek)
Date: Thu, 12 Dec 2024 08:12:34 +0100
Subject: [PATCH 00/15] ARM: zynq: Sync DTs with U-Boot
In-Reply-To: <173393224728.3091150.11085112233542602601.robh@kernel.org>
References: <cover.1733920873.git.michal.simek@amd.com>
 <173393224728.3091150.11085112233542602601.robh@kernel.org>
Message-ID: <0335793c-4606-43dd-b1ab-8f67785f5629@amd.com>



On 12/11/24 16:54, Rob Herring (Arm) wrote:
> 
> On Wed, 11 Dec 2024 13:41:19 +0100, Michal Simek wrote:
>> Hi,
>>
>> over years there were some changes pushed to U-Boot which were never merged
>> back to Linux. U-Boot introduced new option OF_UPSTREAM and start to sync
>> up DTs from Linux back to U-Boot.
>> This series is addressing differences.
>> There are still 3 more differences but they should be addressed separately.
>>
>> Thanks,
>> Michal
>>
>>
>> Michal Simek (14):
>>    ARM: zynq: Remove deprecated device_type property
>>    ARM: zynq: DT: List OCM memory for all platforms
>>    ARM: zynq: Mark boot-phase-specific device nodes
>>    ARM: zynq: Do not define address/size-cells for nand-controller
>>    ARM: zynq: Wire smcc with nand/nor memories on zc770 platform
>>    ARM: zynq: Add ethernet phy reset information to DT(zc702)
>>    ARM: zynq: Define u-boot bootscrip addr via DT
>>    ARM: zynq: Point via nvmem0 alias to eeprom on zc702/zc706
>>    ARM: zynq: Define rtc alias on zc702/zc706
>>    ARM: zynq: Rename i2c?-gpio to i2c?-gpio-grp
>>    ARM: zynq: Fix fpga region DT nodes name
>>    ARM: zynq: Enable QSPIs on platforms
>>    ARM: zynq: Add sdhci to alias node
>>    ARM: zynq: Remove ethernet0 alias from Microzed
>>
>> Sai Krishna Potthuri (1):
>>    ARM: zynq: Replace 'io-standard' with 'power-source' property
>>
>>   arch/arm/boot/dts/xilinx/zynq-7000.dtsi       | 33 ++++++-
>>   arch/arm/boot/dts/xilinx/zynq-cc108.dts       | 41 ++++++++-
>>   arch/arm/boot/dts/xilinx/zynq-microzed.dts    | 10 ++-
>>   arch/arm/boot/dts/xilinx/zynq-parallella.dts  |  1 -
>>   arch/arm/boot/dts/xilinx/zynq-zc702.dts       | 87 +++++++++++++------
>>   arch/arm/boot/dts/xilinx/zynq-zc706.dts       | 67 +++++++++++---
>>   arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts | 39 ++++++++-
>>   arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts | 31 +++++++
>>   arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts | 35 ++++++++
>>   arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts | 41 ++++++++-
>>   arch/arm/boot/dts/xilinx/zynq-zed.dts         | 43 ++++++++-
>>   .../boot/dts/xilinx/zynq-zturn-common.dtsi    |  8 ++
>>   arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts     | 10 ++-
>>   arch/arm/boot/dts/xilinx/zynq-zybo.dts        |  9 +-
>>   14 files changed, 404 insertions(+), 51 deletions(-)
>>
>> --
>> 2.43.0
>>
>>
>>
> 
> 
> My bot found new DTB warnings on the .dts files added or changed in this
> series.
> 
> Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
> are fixed by another series. Ultimately, it is up to the platform
> maintainer whether these warnings are acceptable or not. No need to reply
> unless the platform maintainer has comments.
> 
> If you already ran DT checks and didn't see these error(s), then
> make sure dt-schema is up to date:
> 
>    pip3 install dtschema --upgrade
> 
> 
> New warnings running 'make CHECK_DTBS=y xilinx/zynq-cc108.dtb xilinx/zynq-microzed.dtb xilinx/zynq-parallella.dtb xilinx/zynq-zc702.dtb xilinx/zynq-zc706.dtb xilinx/zynq-zc770-xm010.dtb xilinx/zynq-zc770-xm011.dtb xilinx/zynq-zc770-xm012.dtb xilinx/zynq-zc770-xm013.dtb xilinx/zynq-zed.dtb xilinx/zynq-zybo-z7.dtb xilinx/zynq-zybo.dtb' for cover.1733920873.git.michal.simek at amd.com:
> 
> arch/arm/boot/dts/xilinx/zynq-parallella.dtb: ethernet at e000b000: ethernet-phy at 0: Unevaluated properties are not allowed ('marvell,reg-init' was unexpected)
> 	from schema $id: http://devicetree.org/schemas/net/cdns,macb.yaml#

This is not issue caused by this series.


> arch/arm/boot/dts/xilinx/zynq-zc702.dtb: ethernet at e000b000: Unevaluated properties are not allowed ('phy-reset-active-low', 'phy-reset-gpio' were unexpected)
> 	from schema $id: http://devicetree.org/schemas/net/cdns,macb.yaml#

This has been reported by Andrew already and the patch will be removed.

Thanks,
Michal



From krzk at kernel.org  Wed Dec 11 23:20:01 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 08:20:01 +0100
Subject: [PATCH v2 2/8] dt-bindings: mailbox: mediatek: Add MT8196 support
 for gce-mailbox
In-Reply-To: <64326843358d450c9172f3dea1c85e7422e20430.camel@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
 <20241211032256.28494-3-jason-jh.lin@mediatek.com>
 <yhfxpflyumevs66sdwgiiyuablpfxfxw3e7ybrxju7ssicmnu5@truuiuvxlq6e>
 <64326843358d450c9172f3dea1c85e7422e20430.camel@mediatek.com>
Message-ID: <8cf7e03a-7994-4dd5-b496-e00b4827ee22@kernel.org>

On 12/12/2024 04:41, Jason-JH Lin (???) wrote:
> Hi Krzysztof,
> 
> Thanks for the reviews.
> 
> On Wed, 2024-12-11 at 10:39 +0100, Krzysztof Kozlowski wrote:
>> External email : Please do not click links or open attachments until
>> you have verified the sender or the content.
>>
>>
>> On Wed, Dec 11, 2024 at 11:22:50AM +0800, Jason-JH.Lin wrote:
>>> Add compatible name and iommus property for MT8196.
>>>
>>> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
>>> ---
>>>  .../devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml     | 4
>>> ++++
>>>  1 file changed, 4 insertions(+)
>>
>> Headers are never separate from the bindings patch...
> 
> Do you mean I need to merge [PATCH 1/8] and [PATCH 2/8] into 1 patch?
I asked this last time.

Best regards,
Krzysztof


From krzk at kernel.org  Wed Dec 11 23:20:37 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 08:20:37 +0100
Subject: [PATCH v2 1/8] dt-bindings: mailbox: mediatek: Add GCE header
 file for MT8196
In-Reply-To: <04f7bd2a7d69ab7d02c88cf05bda5ae0c4cb6573.camel@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
 <20241211032256.28494-2-jason-jh.lin@mediatek.com>
 <ozifi65uycmxc5hqeu4onbths5u7dg532iufjxplsjw4jjmhf6@6bdsaabd7hl7>
 <04f7bd2a7d69ab7d02c88cf05bda5ae0c4cb6573.camel@mediatek.com>
Message-ID: <e9caf0fe-a77f-40cb-9fc3-9da3d95f27ca@kernel.org>

On 12/12/2024 04:05, Jason-JH Lin (???) wrote:
> Hi Krzysztof,
> 
> Thanks for the reviews.
> 
> On Wed, 2024-12-11 at 10:37 +0100, Krzysztof Kozlowski wrote:
>> External email : Please do not click links or open attachments until
>> you have verified the sender or the content.
>>
>>
>> On Wed, Dec 11, 2024 at 11:22:49AM +0800, Jason-JH.Lin wrote:
>>> Add the Global Command Engine (GCE) header file to define the GCE
>>> thread priority, GCE subsys ID and GCE events for MT8196.
>>
>> This we see from the diff. What we do not see is why priority is a
>> binding. Looking briefly at existing code: it is not a binding, there
>> is
>> no driver user.
>>
> 
> This priority value is used to configure the priority level for each
> GCE hardware thread, so it is a necessary hardware attribute.

I did not say these are not "hardware". I said these are not bindings.
Bring arguments why these are bindings.

> 
> It's hard to find where the priority is used in existing driver code
> because we parsed it from DTS.

So not a binding.

> 
> It is used in all mediaTeks' DTS using the GCE.
> For example, in mt8195.dts:
> 
> vdosys0: syscon at 1c01a000 {
>     compatible = "mediatek,mt8195-vdosys0", "mediatek,mt8195-mmsys",
> "syscon";
>     reg = <0 0x1c01a000 0 0x1000>;
>     mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
>     #clock-cells = <1>;
>     mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0xa000 0x1000>;
> }
> 
> CMDQ driver(mtk-cmdq-mailbox.c) will get the args parsed from mboxes
> property in cmdq_xlate() and then it will store CMDQ_THR_PRIO_4 to the
> specific thread structure. 

So not a binding.

> The user of CMDQ driver will send command to CMDQ driver by 
> cmdq_mbox_send_data(), and this priority setting will be configured to
> GCE hardware thread.

And other things there are the same, we do not talk only about this one
thing. I asked last time to drop which is not a binding.


...

>>> +
>>> +/*
>>> + * GCE General Purpose Register (GPR) support
>>> + * Leave note for scenario usage here
>>> + */
>>> +/* GCE: write mask */
>>
>> That's a definite no-go. Register masks are not bindings.
>>
> 
> I'm sorry to the confusion.
> 
> These defines are the index of GCE General Purpose Register for
> generating instructions, they are not register masks.

Index of register is also sounding like register.

> 
> The comment "/* GCE: write mask */" is briefly describe that the usage
> of GCE_GPR_R0 and GCE_GPR_R01 is used to store the register mask when
> GCE executing the WRITE instruction. And it can also store the register
> mask of POLL and READ instruction.
> 
> I will add more words to make this comment clearer, like this:
> /*GCE: store the mask of instruction */

Not sure, because I feel you just avoid doing what is right and keep
pushing your own narrative. Where is it used in the driver?

I just looked for "GCE_GPR_R00" - no usage at all. So not a binding.

Best regards,
Krzysztof


From andyshrk at 163.com  Wed Dec 11 23:52:34 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 12 Dec 2024 15:52:34 +0800 (CST)
Subject: [PATCH v5 05/18] drm/rockchip: vop2: Set AXI id for rk3588
In-Reply-To: <5843712.DvuYhMxLoT@bootstrap>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <5839604.DvuYhMxLoT@trenzalore>
 <2d381563.5e54.193b46d2f30.Coremail.andyshrk@163.com>
 <5843712.DvuYhMxLoT@bootstrap>
Message-ID: <3f1eace4.75cf.193b9daf585.Coremail.andyshrk@163.com>


Hi Detlev,

At 2024-12-11 23:45:01, "Detlev Casanova" <detlev.casanova at collabora.com> wrote:
>On Wednesday, 11 December 2024 01:34:34 EST Andy Yan wrote:
>> Hi Detlev,
>> 
>> At 2024-12-11 02:40:14, "Detlev Casanova" <detlev.casanova at collabora.com> 
>wrote:
>> >Hi Andy,
>> >
>> >On Monday, 9 December 2024 07:29:18 EST Andy Yan wrote:
>> >> From: Andy Yan <andy.yan at rock-chips.com>
>> >> 
>> >> There are two AXI bus in vop2, windows attached on the same bus must
>> >> have a unique channel YUV and RGB channel ID.
>> >> 
>> >> The default IDs will conflict with each other on the rk3588, so they
>> >> need to be reassigned.
>> >> 
>> >> Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
>> >> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>> >> Tested-by: Derek Foreman <derek.foreman at collabora.com>
>> >> 
>> >> ---
>> >> 
>> >> Changes in v5:
>> >> - Added in V5
>> >> 
>> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 14 +++++++++++
>> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  9 +++++++
>> >>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 26 +++++++++++++++++++-
>> >>  3 files changed, 48 insertions(+), 1 deletion(-)
>> >> 
>> >> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> >> b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index
>> >> dc4edd65bc9e..8b9ca046eeeb 100644
>> >> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> >> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> >> @@ -1426,6 +1426,12 @@ static void vop2_plane_atomic_update(struct
>> >> drm_plane *plane, &fb->format->format,
>> >> 
>> >>  		afbc_en ? "AFBC" : "", &yrgb_mst);
>> >> 
>> >> +	if (vop2->data->soc_id > 3568) {
>> >
>> >Shouldn't this be done only for rk3588, as specified in the comments below
>> >? The test we did before showed that it is failing on rk3576 and 3576 is >
>> >3588.
>> I think this is because you tested before with the patch I gave Derek 
>> without axi id assigned for rk3576.
>> I assigned axi id for rk3576 in this version 18/18?The new ID assignment can
>> adapt to more application scenarios.?, can you test it with the whole V5
>> version again?
>
>Yes, I will do that. But patch 18 mentions:
>+       /* Read only bit on rk3576*/
>+       [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
>
>And the bit is being written here. If it is indeed writable, then I would drop 
>that comment.
The AXI_BUS_ID for two Cluster windows on RK3576 are fixed by hardware, that means
whether we write it or not, it won't change anything.
But the AXI_BUS_ID for Esmart windows on rk3576 and  AXI_YRGB/UV_R_ID for all
cluster/esmart windows on rk3576 are writeable.
I think we directly write it here as the current code can make things easy.



>
>> >I suggest
>> >
>> >	if (vop2->data->soc_id == 3588) {
>> >
>> >Regards,
>> >Detlev
>> >
>> >> +		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data-
>> >>
>> >>axi_bus_id);
>> >>
>> >> +		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data-
>> >>
>> >>axi_yrgb_r_id);
>> >>
>> >> +		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data-
>> >>
>> >>axi_uv_r_id);
>> >>
>> >> +	}
>> >> +
>> >> 
>> >>  	if (vop2_cluster_window(win))
>> >>  	
>> >>  		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN,
>> >
>> >half_block_en);
>> >
>
>Detlev.
>
>
>
>_______________________________________________
>Linux-rockchip mailing list
>Linux-rockchip at lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-rockchip

From mripard at kernel.org  Thu Dec 12 00:02:44 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 12 Dec 2024 08:02:44 +0000
Subject: [PATCH v6 10/19] drm/imx: Add i.MX8qxp Display Controller pixel
 engine
In-Reply-To: <20241209033923.3009629-11-victor.liu@nxp.com>
References: <20241209033923.3009629-11-victor.liu@nxp.com>
Message-ID: <f5e1154a6a3a60856553716cdb8f6fd2@kernel.org>

On Mon, 9 Dec 2024 11:39:14 +0800, Liu Ying wrote:
> i.MX8qxp Display Controller pixel engine consists of all processing
> units that operate in the AXI bus clock domain.  Add drivers for
> ConstFrame, ExtDst, FetchLayer, FetchWarp and LayerBlend units, as
> well as a pixel engine driver, so that two displays with primary
> planes can be supported.  The pixel engine driver and those unit
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From mripard at kernel.org  Thu Dec 12 00:02:52 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 12 Dec 2024 08:02:52 +0000
Subject: [PATCH v6 11/19] drm/imx: Add i.MX8qxp Display Controller
 interrupt controller
In-Reply-To: <20241209033923.3009629-12-victor.liu@nxp.com>
References: <20241209033923.3009629-12-victor.liu@nxp.com>
Message-ID: <d89975ed06ae64a4871a8807f53d1e18@kernel.org>

On Mon, 9 Dec 2024 11:39:15 +0800, Liu Ying wrote:
> i.MX8qxp Display Controller has a built-in interrupt controller to support
> Enable/Status/Preset/Clear interrupt bit.  Add driver for it.
> 
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From mripard at kernel.org  Thu Dec 12 00:02:58 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 12 Dec 2024 08:02:58 +0000
Subject: [PATCH v6 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <20241209033923.3009629-13-victor.liu@nxp.com>
References: <20241209033923.3009629-13-victor.liu@nxp.com>
Message-ID: <f3051a8c08d8af623d686cea162c945e@kernel.org>

On Mon, 9 Dec 2024 11:39:16 +0800, Liu Ying wrote:
> i.MX8qxp Display Controller(DC) is comprised of three main components that
> include a blit engine for 2D graphics accelerations, display controller for
> display output processing, as well as a command sequencer.  Add kernel
> mode setting support for the display controller part with two CRTCs and
> two primary planes(backed by FetchLayer and FetchWarp respectively).  The
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From mripard at kernel.org  Thu Dec 12 00:02:36 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 12 Dec 2024 08:02:36 +0000
Subject: [PATCH v6 09/19] drm/imx: Add i.MX8qxp Display Controller
 display engine
In-Reply-To: <20241209033923.3009629-10-victor.liu@nxp.com>
References: <20241209033923.3009629-10-victor.liu@nxp.com>
Message-ID: <e3b1230308d20b4e7525952d01eb44fd@kernel.org>

On Mon, 9 Dec 2024 11:39:13 +0800, Liu Ying wrote:
> i.MX8qxp Display Controller display engine consists of all processing
> units that operate in a display clock domain.  Add minimal feature
> support with FrameGen and TCon so that the engine can output display
> timings.  The FrameGen driver, TCon driver and display engine driver
> are components to be aggregated by a master registered in the upcoming
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From cassel at kernel.org  Thu Dec 12 00:04:12 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Thu, 12 Dec 2024 09:04:12 +0100
Subject: [PATCH] PCI: dw-rockchip: Enumerate endpoints based on
 dll_link_up irq in the combined sys irq
In-Reply-To: <20241211053104.7sgo5bmmjnolwvhh@thinkpad>
References: <20241127145041.3531400-2-cassel@kernel.org>
 <20241211053104.7sgo5bmmjnolwvhh@thinkpad>
Message-ID: <Z1qY_K57lamVxqRm@ryzen>

On Wed, Dec 11, 2024 at 11:01:04AM +0530, Manivannan Sadhasivam wrote:
> On Wed, Nov 27, 2024 at 03:50:42PM +0100, Niklas Cassel wrote:
> > Most boards using the pcie-dw-rockchip PCIe controller lack standard
> > hotplug support.
> > 
> > Thus, when an endpoint is attached to the SoC, users have to rescan the bus
> > manually to enumerate the device. This can be avoided by using the
> > 'dll_link_up' interrupt in the combined system interrupt 'sys'.
> > 
> > Once the 'dll_link_up' irq is received, the bus underneath the host bridge
> > is scanned to enumerate PCIe endpoint devices.
> > 
> > This commit implements the same functionality that was implemented in the
> > DWC based pcie-qcom driver in commit 4581403f6792 ("PCI: qcom: Enumerate
> > endpoints based on Link up event in 'global_irq' interrupt").
> > 
> > The Root Complex specific device tree binding for pcie-dw-rockchip already
> > has the 'sys' interrupt marked as required, so there is no need to update
> > the device tree binding. This also means that we can request the 'sys' IRQ
> > unconditionally.
> > 
> > Signed-off-by: Niklas Cassel <cassel at kernel.org>
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

Thanks for the review!

Could this patch please be picked up?


Kind regards,
Niklas


From andrej.picej at norik.com  Thu Dec 12 00:08:03 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu, 12 Dec 2024 09:08:03 +0100
Subject: [PATCH v5 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <rputm4gnjj6nb66ix7dqbxr2janltia6rlb6zunhf7x3mgooxw@o3lblnyp5cci>
References: <20241210091901.83028-1-andrej.picej@norik.com>
 <20241210091901.83028-3-andrej.picej@norik.com>
 <irpmhq7vxjra6vhmdh7p63ajj57n3h2c4br3ija2jmwtoewist@zyxfmx6k5m4e>
 <aa2de99d-21f4-4843-83b7-5d2db78be86f@norik.com>
 <qhmsobin3fsmoc7ic2jtancowfscoauyroruxdpwhmqwlogtkz@6by3s2ruwzwp>
 <519cc025-0782-4f96-a169-1fe87b280173@norik.com>
 <rputm4gnjj6nb66ix7dqbxr2janltia6rlb6zunhf7x3mgooxw@o3lblnyp5cci>
Message-ID: <ad8843d6-e5a3-437a-af4d-f2248b247a65@norik.com>



On 12. 12. 24 00:04, Dmitry Baryshkov wrote:
> On Wed, Dec 11, 2024 at 08:57:17AM +0100, Andrej Picej wrote:
>>
>>
>> On 10. 12. 24 14:59, Dmitry Baryshkov wrote:
>>> On Tue, Dec 10, 2024 at 02:41:01PM +0100, Andrej Picej wrote:
>>>>
>>>>
>>>> On 10. 12. 24 12:43, Dmitry Baryshkov wrote:
>>>>> On Tue, Dec 10, 2024 at 10:19:00AM +0100, Andrej Picej wrote:
>>>>>> Add a optional properties to change LVDS output voltage. This should not
>>>>>> be static as this depends mainly on the connected display voltage
>>>>>> requirement. We have three properties:
>>>>>> - "ti,lvds-termination-ohms", which sets near end termination,
>>>>>> - "ti,lvds-vod-swing-data-microvolt" and
>>>>>> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
>>>>>> output voltage for data and clock lanes. They are defined as an array
>>>>>> with min and max values. The appropriate bitfield will be set if
>>>>>> selected constraints can be met.
>>>>>>
>>>>>> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
>>>>>> end termination will be used. Selecting only one:
>>>>>> "ti,lvds-vod-swing-data-microvolt" or
>>>>>> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
>>>>>> constraint for only data/clock lanes will be met. Setting both is
>>>>>> recommended.
>>>>>>
>>>>>> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
>>>>>> ---
>>>>>> Changes in v5:
>>>>>> - specify default values in sn65dsi83_parse_lvds_endpoint,
>>>>>> - move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
>>>>>> Changes in v4:
>>>>>> - fix typo in commit message bitfiled -> bitfield
>>>>>> - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
>>>>>> of separate variables for channel A/B
>>>>>> - add more checks on return value of "of_property_read_u32_array"
>>>>>> Changes in v3:
>>>>>> - use microvolts for default array values 1000 mV -> 1000000 uV.
>>>>>> Changes in v2:
>>>>>> - use datasheet tables to get the proper configuration
>>>>>> - since major change was done change the authorship to myself
>>>>>> ---
>>>>>>     drivers/gpu/drm/bridge/ti-sn65dsi83.c | 142 +++++++++++++++++++++++++-
>>>>>>     1 file changed, 139 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>>>> index 57a7ed13f996..f9578b38da28 100644
>>>>>> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>>>> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>>>> @@ -132,6 +132,16 @@
>>>>>>     #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>>>>>>     #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>>>>>> +enum sn65dsi83_channel {
>>>>>> +	CHANNEL_A,
>>>>>> +	CHANNEL_B
>>>>>> +};
>>>>>> +
>>>>>> +enum sn65dsi83_lvds_term {
>>>>>> +	OHM_100,
>>>>>> +	OHM_200
>>>>>> +};
>>>>>> +
>>>>>>     enum sn65dsi83_model {
>>>>>>     	MODEL_SN65DSI83,
>>>>>>     	MODEL_SN65DSI84,
>>>>>> @@ -147,6 +157,8 @@ struct sn65dsi83 {
>>>>>>     	struct regulator		*vcc;
>>>>>>     	bool				lvds_dual_link;
>>>>>>     	bool				lvds_dual_link_even_odd_swap;
>>>>>> +	int				lvds_vod_swing_conf[2];
>>>>>> +	int				lvds_term_conf[2];
>>>>>>     };
>>>>>>     static const struct regmap_range sn65dsi83_readable_ranges[] = {
>>>>>> @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>>>>>>     	.max_register = REG_IRQ_STAT,
>>>>>>     };
>>>>>> +static const int lvds_vod_swing_data_table[2][4][2] = {
>>>>>> +	{	/* 100 Ohm */
>>>>>> +		{ 180000, 313000 },
>>>>>> +		{ 215000, 372000 },
>>>>>> +		{ 250000, 430000 },
>>>>>> +		{ 290000, 488000 },
>>>>>> +	},
>>>>>> +	{	/* 200 Ohm */
>>>>>> +		{ 150000, 261000 },
>>>>>> +		{ 200000, 346000 },
>>>>>> +		{ 250000, 428000 },
>>>>>> +		{ 300000, 511000 },
>>>>>> +	},
>>>>>> +};
>>>>>> +
>>>>>> +static const int lvds_vod_swing_clock_table[2][4][2] = {
>>>>>> +	{	/* 100 Ohm */
>>>>>> +		{ 140000, 244000 },
>>>>>> +		{ 168000, 290000 },
>>>>>> +		{ 195000, 335000 },
>>>>>> +		{ 226000, 381000 },
>>>>>> +	},
>>>>>> +	{	/* 200 Ohm */
>>>>>> +		{ 117000, 204000 },
>>>>>> +		{ 156000, 270000 },
>>>>>> +		{ 195000, 334000 },
>>>>>> +		{ 234000, 399000 },
>>>>>> +	},
>>>>>> +};
>>>>>> +
>>>>>>     static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>>>>>>     {
>>>>>>     	return container_of(bridge, struct sn65dsi83, bridge);
>>>>>> @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>>>>>>     		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>>>>>>     	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
>>>>>> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
>>>>>> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
>>>>>> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
>>>>>> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
>>>>>>     	regmap_write(ctx->regmap, REG_LVDS_LANE,
>>>>>>     		     (ctx->lvds_dual_link_even_odd_swap ?
>>>>>>     		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
>>>>>> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
>>>>>> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
>>>>>> +		     (ctx->lvds_term_conf[CHANNEL_A] ?
>>>>>> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
>>>>>> +		     (ctx->lvds_term_conf[CHANNEL_B] ?
>>>>>> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>>>>>>     	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>>>>>>     	le16val = cpu_to_le16(mode->hdisplay);
>>>>>> @@ -576,10 +622,100 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>>>>>>     	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>>>>>>     };
>>>>>> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
>>>>>> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
>>>>>> +{
>>>>>> +	int i;
>>>>>> +
>>>>>> +	for (i = 0; i <= 3; i++) {
>>>>>> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
>>>>>> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
>>>>>> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
>>>>>> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
>>>>>> +			return i;
>>>>>> +	}
>>>>>> +
>>>>>> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
>>>>>> +	return -EINVAL;
>>>>>> +}
>>>>>> +
>>>>>> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
>>>>>> +{
>>>>>> +	struct device *dev = ctx->dev;
>>>>>> +	struct device_node *endpoint;
>>>>>> +	int endpoint_reg;
>>>>>> +	/* Set so the property can be freely selected if not defined */
>>>>>> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
>>>>>> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
>>>>>> +	u32 lvds_term;
>>>>>> +	u8 lvds_term_conf = 0x1;
>>>>>> +	int lvds_vod_swing_conf = 0x1;
>>>>>
>>>>> Magic values
>>>>
>>>> Can you please elaborate.
>>>>
>>>> I can use:
>>>> u8 lvds_term_conf = OHM_200;
>>>>
>>>> What about lvds_vod_swing_conf? Should I create additional define for it?
>>>> But this doesn't solve a hidden meaning? Maybe additional comment above?
>>>> Would like to avoid using voltages for it, since then we are reverse
>>>> engineering the table in datasheet to match the default reg value.
>>>
>>> I think the following example solves both problems:
>>>
>>> lvds_term = 200;
>>> of_property_read_u32(..., &lvds_term);
>>>
>>> if (lvds_term == 100)
>>> 	ctx->lvds_term_conf[channel] = OHM_100;
>>> else if (lvds_term == 200)
>>> 	ctx->lvds_term_conf[channel] = OHM_200;
>>> else
>>> 	return -EINVAL;
>>>
>>> The same approach can be applied to lvds_vod_swing_conf, resulting in
>>> removal of magic values.
>>
>> Sorry, but I think it is not that easy when it comes to the
>> lvds_vod_swing_conf. We should assign default value if
>> "ti,lvds-vod-swing-data-microvolt" and "ti,lvds-vod-swing-clock-microvolt"
>> are not defined. Default value of the lvds_vod_swing_conf is 0x1, but this
>> doesn't have any straight forward meaning like OHM_200 for example.
>>
>> What we can do in that case is that we copy the values from defined
>> datasheet tables to the "lvds_vod_swing_data[2]" and "lvds_vod_swing_clk[2]"
>> arrays and then run the
>> sn65dsi83_select_lvds_vod_swing with it, which will return the default value
>> (0x1).
>>
>> /* If both properties are not defined assign default limits */
>> if (ret_data && ret_clock) {
>> 	memcpy(lvds_vod_swing_data,
>> 	     lvds_vod_swing_data_table[ctx->lvds_term_conf[channel]][1],
>> 	     sizeof(lvds_vod_swing_data));
>> 	memcpy(lvds_vod_swing_clk,
>> 	    lvds_vod_swing_clock_table[ctx->lvds_term_conf[channel]][1],
>> 	    sizeof(lvds_vod_swing_clk));
>> }
>> lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
>> 	lvds_vod_swing_data, lvds_vod_swing_clk,
>> 	ctx->lvds_term_conf[channel]);
>> if (lvds_vod_swing_conf < 0) {
>> 	ret = lvds_vod_swing_conf;
>> 	goto exit;
>> }
>>
>> ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
>>
>> I'm not sure if using this approach gets rid of the problem with magic
>> values.
>> Or maybe I'm not seeing the obvious solution so please bear with me.
> 
> Yes, the defaults (0..1000000) should be fixed to result in the same
> value (0x01) as if the property wasn't specified at all

The defaults (0..1000000) is selected because in case if only one 
property is defined in dts (ti,lvds-vod-swing-data-microvolt or 
ti,lvds-vod-swing-clock-microvolt) the other array values don't effect 
the decision which "lvds_vod_swing_conf" is selected. That's why we 
initialized the array to be out off bounds of the datasheet tables, all 
values in the table match the not defined property, so 
lvds_vod_swing_conf is selected purely on the basis of the defined property.

Example:
DTS
ti,lvds-vod-swing-data-microvolt = <250000 428000>;
//ti,lvds-vod-swing-clock-microvolt NOT DEFINED;

After parsing the devicetree we will get:
lvds_vod_swing_data = [ 250000, 428000 ]
lvds_vod_swing_clk = [ 0, 1000000 ]

In sn65dsi83_select_lvds_vod_swing lvds_vod_swing_clk[] values don't 
effect the decision making since

lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1]

is always true.

> 
> I think the following should work:
> 
> 	/* artifical values to select the defaults in both cases */
> 	u32 lvds_vod_swing_data[2] = { 190000, 330000 };
> 	u32 lvds_vod_swing_clk[2] = { 150000, 250000 };

This sets the default to 0x0. It should be:
u32 lvds_vod_swing_data[2] = { 200000, 372000 };
u32 lvds_vod_swing_clk[2] = { 156000, 290000 };
This selects the default 0x1 in both cases, if termination is 100 or 200 
Ohms.

Nevertheless I think I got your point. But I would still like to give 
the user the freedom to only specify one property if maybe connected 
panel only has limits on data lanes/clock lane.
So maybe set the arrays lvds_vod_swing_data/clk to [0, 1000000] if 
of_property_read_u32_array returns -EINVAL (property does not exist).
What do you say?

> 
> Yes, they are artificial, as stated in the comment. Yes, I think it's
> better than special-casing in the property handling.
> 


From krzk at kernel.org  Thu Dec 12 00:13:27 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 09:13:27 +0100
Subject: [PATCH v4 1/3] dt-bindings: leds: backlight: apple,dwi-bl: Add
 Apple DWI backlight
In-Reply-To: <20241211113512.19009-2-towinchenmi@gmail.com>
References: <20241211113512.19009-1-towinchenmi@gmail.com>
 <20241211113512.19009-2-towinchenmi@gmail.com>
Message-ID: <6fazyksxkcbhugivwgozuyjdig37vnshbwtdmzjcbrqywgszvd@sm27uhqgsma4>

On Wed, Dec 11, 2024 at 07:34:37PM +0800, Nick Chan wrote:
> Add backlight controllers attached via Apple DWI 2-wire interface.
> 
> Signed-off-by: Nick Chan <towinchenmi at gmail.com>
> ---
>  .../bindings/leds/backlight/apple,dwi-bl.yaml | 57 +++++++++++++++++++
>  1 file changed, 57 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml

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

Best regards,
Krzysztof



From shijie at os.amperecomputing.com  Thu Dec 12 00:24:24 2024
From: shijie at os.amperecomputing.com (Huang Shijie)
Date: Thu, 12 Dec 2024 16:24:24 +0800
Subject: [PATCH v4 0/2] arm64: refactor the rodata=xxx
Message-ID: <20241212082426.4110-1-shijie@os.amperecomputing.com>

>From Documentation/admin-guide/kernel-parameters.txt, we know that:
 rodata=	[KNL,EARLY]
	on	Mark read-only kernel memory as read-only (default).
	off	Leave read-only kernel memory writable for debugging.
	full	Mark read-only kernel memory and aliases as read-only
		[arm64]

So the "rodata=on" is the default.

But the current code does not follow the document, it makes "rodata=full"
as the default.

This patch set follows Anshuman Khandual's suggetions. 
It makes the "rodata=on" as the default, and removes the CONFIG_RODATA_FULL_DEFAULT_ENABLED.

v4:
  Follows Anshuman Khandual/Ard Biesheuvel's suggetions:
  - Change commit message format.
  - Change the titile name.
  - others

v3:
  Follows Anshuman Khandual's suggetions:
  - Merge patch 1 and patch 3 into one patch.
  - Remove patch 4 
  - update comments and document.
   https://lists.infradead.org/pipermail/linux-arm-kernel/2024-December/984344.html

v2:
  Follows Will's suggetions.
  Add a new file fine-tuning-tips.rst for the expert users.
   https://lists.infradead.org/pipermail/linux-arm-kernel/2024-November/981190.html

v1:
   https://lists.infradead.org/pipermail/linux-arm-kernel/2024-October/971415.html


Huang Shijie (2):
  arm64: refactor the rodata=xxx
  arm64/Kconfig: Remove CONFIG_RODATA_FULL_DEFAULT_ENABLED

 .../admin-guide/kernel-parameters.txt         |  2 +-
 arch/arm64/Kconfig                            | 14 ----------
 arch/arm64/include/asm/setup.h                | 26 +++++++++++++++++--
 arch/arm64/mm/pageattr.c                      |  2 +-
 4 files changed, 26 insertions(+), 18 deletions(-)

-- 
2.40.1



From shijie at os.amperecomputing.com  Thu Dec 12 00:24:25 2024
From: shijie at os.amperecomputing.com (Huang Shijie)
Date: Thu, 12 Dec 2024 16:24:25 +0800
Subject: [PATCH v4 1/2] arm64: refactor the rodata=xxx
In-Reply-To: <20241212082426.4110-1-shijie@os.amperecomputing.com>
References: <20241212082426.4110-1-shijie@os.amperecomputing.com>
Message-ID: <20241212082426.4110-2-shijie@os.amperecomputing.com>

As per admin guide documentation, "rodata=on" should be the default on
platforms. Documentation/admin-guide/kernel-parameters.txt describes
these options as

   rodata=         [KNL,EARLY]
           on      Mark read-only kernel memory as read-only (default).
           off     Leave read-only kernel memory writable for debugging.
           full    Mark read-only kernel memory and aliases as read-only
                   [arm64]

But on arm64 platform, "rodata=full" is the default instead. This patch
implements the following changes.

 - Make "rodata=on" behaviour same as the original "rodata=full"
 - Make "rodata=noalias" (new) behaviour same as the original "rodata=on"
 - Drop the original "rodata=full"
 - Add comment for arch_parse_debug_rodata()
 - Update kernel-parameters.txt as required

After this patch, the "rodata=on" will be the default on arm64 platform
as well.

Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
---
 .../admin-guide/kernel-parameters.txt         |  2 +-
 arch/arm64/include/asm/setup.h                | 26 +++++++++++++++++--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index a22b7e621007..51bce7b9d805 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5901,7 +5901,7 @@
 	rodata=		[KNL,EARLY]
 		on	Mark read-only kernel memory as read-only (default).
 		off	Leave read-only kernel memory writable for debugging.
-		full	Mark read-only kernel memory and aliases as read-only
+		noalias	Use more block mappings,may have better performance.
 		        [arm64]
 
 	rockchip.usb_uart
diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
index ba269a7a3201..37f58a603224 100644
--- a/arch/arm64/include/asm/setup.h
+++ b/arch/arm64/include/asm/setup.h
@@ -13,6 +13,28 @@
 extern phys_addr_t __fdt_pointer __initdata;
 extern u64 __cacheline_aligned boot_args[4];
 
+/*
+ * rodata=on (default)
+ *
+ *    This applies read-only attributes to VM areas and to the linear
+ *    alias of the backing pages as well. This prevents code or read-
+ *    only data from being modified (inadvertently or intentionally),
+ *    via another mapping for the same memory page.
+ *
+ *    But this might cause linear map region to be mapped down to base
+ *    pages, which may adversely affect performance in some cases.
+ *
+ * rodata=off
+ *
+ *    This provides more block mappings and contiguous hints for linear
+ *    map region which would minimize TLB footprint. This also leaves
+ *    read-only kernel memory writable for debugging.
+ *
+ * rodata=noalias
+ *
+ *    This provides more block mappings and contiguous hints for linear
+ *    map region which would minimize TLB footprint.
+ */
 static inline bool arch_parse_debug_rodata(char *arg)
 {
 	extern bool rodata_enabled;
@@ -21,7 +43,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
 	if (!arg)
 		return false;
 
-	if (!strcmp(arg, "full")) {
+	if (!strcmp(arg, "on")) {
 		rodata_enabled = rodata_full = true;
 		return true;
 	}
@@ -31,7 +53,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
 		return true;
 	}
 
-	if (!strcmp(arg, "on")) {
+	if (!strcmp(arg, "noalias")) {
 		rodata_enabled = true;
 		rodata_full = false;
 		return true;
-- 
2.40.1



From krzk at kernel.org  Thu Dec 12 00:25:08 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 09:25:08 +0100
Subject: [PATCH v2 1/7] dt-bindings: cpufreq: apple,cluster-cpufreq: Add
 A7-A11, T2 compatibles
In-Reply-To: <20241212070344.3858-2-towinchenmi@gmail.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
 <20241212070344.3858-2-towinchenmi@gmail.com>
Message-ID: <f7whbncdt3yud3loe6xane4gwzpvyygfdju6e55gf6s2s3k75k@n7ehtngsrqxp>

On Thu, Dec 12, 2024 at 03:03:00PM +0800, Nick Chan wrote:
> Add compatibles for Apple A7-A11, T2 SoCs.
> 
> Apple A7, A8, A8X gets the per-SoC compatible and the A7
> "apple,s5l8960x-cluster-cpufreq" compatible.
> 
> Apple A9, A9X, A10, A10X, T2, A11 gets the per-SoC compatible, M1
> "apple,t8103-cluster-cpufreq" compatible, then the
> "apple,cluster-cpufreq" fallback compatible.
> 
> Signed-off-by: Nick Chan <towinchenmi at gmail.com>

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

Best regards,
Krzysztof



From shijie at os.amperecomputing.com  Thu Dec 12 00:24:26 2024
From: shijie at os.amperecomputing.com (Huang Shijie)
Date: Thu, 12 Dec 2024 16:24:26 +0800
Subject: [PATCH v4 2/2] arm64/Kconfig: Remove CONFIG_RODATA_FULL_DEFAULT_ENABLED
In-Reply-To: <20241212082426.4110-1-shijie@os.amperecomputing.com>
References: <20241212082426.4110-1-shijie@os.amperecomputing.com>
Message-ID: <20241212082426.4110-3-shijie@os.amperecomputing.com>

After patch "arm64: refacotr the rodata=xxx",
the "rodata=on" becomes the default.

     ......................................
	if (!strcmp(arg, "on")) {
		rodata_enabled = rodata_full = true;
		return true;
	}
     ......................................

The rodata_full is always "true" via "rodata=on" and does not
depend on the config RODATA_FULL_DEFAULT_ENABLED anymore,
so it can be dropped.

Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>
Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
---
 arch/arm64/Kconfig       | 14 --------------
 arch/arm64/mm/pageattr.c |  2 +-
 2 files changed, 1 insertion(+), 15 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cbfd357f94a6..1c69982302ed 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1666,20 +1666,6 @@ config MITIGATE_SPECTRE_BRANCH_HISTORY
 	  When taking an exception from user-space, a sequence of branches
 	  or a firmware call overwrites the branch history.
 
-config RODATA_FULL_DEFAULT_ENABLED
-	bool "Apply r/o permissions of VM areas also to their linear aliases"
-	default y
-	help
-	  Apply read-only attributes of VM areas to the linear alias of
-	  the backing pages as well. This prevents code or read-only data
-	  from being modified (inadvertently or intentionally) via another
-	  mapping of the same memory page. This additional enhancement can
-	  be turned off at runtime by passing rodata=[off|on] (and turned on
-	  with rodata=full if this option is set to 'n')
-
-	  This requires the linear region to be mapped down to pages,
-	  which may adversely affect performance in some cases.
-
 config ARM64_SW_TTBR0_PAN
 	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
 	depends on !KCSAN
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 39fd1f7ff02a..6eef08d8451e 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -20,7 +20,7 @@ struct page_change_data {
 	pgprot_t clear_mask;
 };
 
-bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED);
+bool rodata_full __ro_after_init = true;
 
 bool can_set_direct_map(void)
 {
-- 
2.40.1



From peng.fan at oss.nxp.com  Thu Dec 12 00:24:40 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 12 Dec 2024 16:24:40 +0800
Subject: [PATCH 0/2] Make i.MX9 OCOTP work as accessing controller
Message-ID: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>

Previously there was discussion on using "feature-controller" or
adding a specific node to group the fuse information for U-Boot to
parse and update node. But rejected by DT maintainer(Rob).

Since the STM32 engineers added access controller concept and landed
the support in Linux Kernel, reuse the concept for i.MX.

i.MX OCOTP eFuse has some bits to indicate a specific periphral or
function is avaiable for current chip, for example i.MX93 has variants
that not have NPU. So introduce '#access-controller-cells' for OCOTP,
and add "#access-controllers = <&ocotp [gate_index]>" for periphrals
that needs accessing control checking.

In OCOTP driver, the nodes under "/soc at 0" will be iterated, and checked
if property "#access-controllers" exsits. If not allow access, detach
the node.

In the end, cpu nodes should still be handled by bootloader.
And I may also update i.MX8M to use same method to support variants
if this patchset is good.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Peng Fan (2):
      dt-bindings: nvmem: imx-ocotp: Introduce #access-controller-cells
      nvmem: imx-ocotp-ele: Support accessing controller for i.MX9

 .../devicetree/bindings/nvmem/imx-ocotp.yaml       |   5 +
 drivers/nvmem/imx-ocotp-ele.c                      | 187 ++++++++++++++++++++-
 include/dt-bindings/nvmem/fsl,imx93-ocotp.h        |  24 +++
 include/dt-bindings/nvmem/fsl,imx95-ocotp.h        |  43 +++++
 4 files changed, 258 insertions(+), 1 deletion(-)
---
base-commit: 3e42dc9229c5950e84b1ed705f94ed75ed208228
change-id: 20241212-imx-ocotp-cbef304140f5

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Thu Dec 12 00:24:42 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 12 Dec 2024 16:24:42 +0800
Subject: [PATCH 2/2] nvmem: imx-ocotp-ele: Support accessing controller for
 i.MX9
In-Reply-To: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>
References: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>
Message-ID: <20241212-imx-ocotp-v1-2-198bb0af86a0@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX9 OCOTP supports a specific peripheral or function being fused
which means disabled, so
 - Introduce ocotp_access_gates to be container of efuse gate info
 - Iterate each node under '/soc' to check accessing permission. If not
   allowed to be accessed, detach the node

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/nvmem/imx-ocotp-ele.c | 187 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 186 insertions(+), 1 deletion(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index ca6dd71d8a2e29888c6e556aaea116c1a967cb5f..542539b86efd2d38be2903c1d0ea72f918ff5b75 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -5,6 +5,8 @@
  * Copyright 2023 NXP
  */
 
+#include <dt-bindings/nvmem/fsl,imx93-ocotp.h>
+#include <dt-bindings/nvmem/fsl,imx95-ocotp.h>
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -27,6 +29,7 @@ struct ocotp_map_entry {
 };
 
 struct ocotp_devtype_data {
+	const struct ocotp_access_gates *access_gates;
 	u32 reg_off;
 	char *name;
 	u32 size;
@@ -36,11 +39,26 @@ struct ocotp_devtype_data {
 	struct ocotp_map_entry entry[];
 };
 
+#define OCOTP_MAX_NUM_GATE_WORDS 4
+#define IMX93_OCOTP_NUM_GATES 17
+#define IMX95_OCOTP_NUM_GATES 36
+
+struct ocotp_access_gates {
+	u32 num_words;
+	u32 words[OCOTP_MAX_NUM_GATE_WORDS];
+	u32 num_gates;
+	struct access_gate {
+		u32 word;
+		u32 mask;
+	} gates[];
+};
+
 struct imx_ocotp_priv {
 	struct device *dev;
 	void __iomem *base;
 	struct nvmem_config config;
 	struct mutex lock;
+	u32 value[OCOTP_MAX_NUM_GATE_WORDS];
 	const struct ocotp_devtype_data *data;
 };
 
@@ -131,6 +149,100 @@ static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
 	cell->read_post_process = imx_ocotp_cell_pp;
 }
 
+static int imx_ele_ocotp_check_access(struct platform_device *pdev, u32 id)
+{
+	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
+	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
+	u32 word, mask;
+
+	if (id >= access_gates->num_gates) {
+		dev_err(&pdev->dev, "Index %d too large\n", id);
+		return -EACCES;
+	}
+
+	word = access_gates->gates[id].word;
+	mask = access_gates->gates[id].mask;
+
+	dev_dbg(&pdev->dev, "id:%d word:%d mask:0x%08x\n", id, word, mask);
+	/* true means not allow access */
+	if (priv->value[word] & mask)
+		return -EACCES;
+
+	return 0;
+}
+
+static int imx_ele_ocotp_grant_access(struct platform_device *pdev, struct device_node *parent)
+{
+	struct device_node *child;
+	struct device *dev = &pdev->dev;
+
+	for_each_available_child_of_node(parent, child) {
+		struct of_phandle_iterator it;
+		int err;
+		u32 id;
+
+		of_for_each_phandle(&it, err, child, "access-controllers",
+				    "#access-controller-cells", 0) {
+			struct of_phandle_args provider_args;
+			struct device_node *provider = it.node;
+
+			if (err) {
+				dev_err(dev, "Unable to get access-controllers property for node %s\n, err: %d",
+					child->full_name, err);
+				of_node_put(provider);
+				return err;
+			}
+
+			/* Only support one cell */
+			if (of_phandle_iterator_args(&it, provider_args.args, 1) != 1) {
+				dev_err(dev, "wrong args count\n");
+				return -EINVAL;
+			}
+
+			id = provider_args.args[0];
+
+			dev_dbg(dev, "Checking node: %s gate: %d\n", child->full_name, id);
+
+			if (imx_ele_ocotp_check_access(pdev, id)) {
+				of_detach_node(child);
+				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
+					child->full_name);
+			}
+		}
+
+		imx_ele_ocotp_grant_access(pdev, child);
+	}
+
+	return 0;
+}
+
+static int imx_ele_ocotp_access_control(struct platform_device *pdev)
+{
+	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
+	struct device_node *soc __free(device_node) = of_find_node_by_path("/soc");
+	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
+	void __iomem *reg = priv->base + priv->data->reg_off;
+	u32 off;
+	int i;
+
+	if (!priv->data->access_gates)
+		return 0;
+
+	if (!soc)
+		soc = of_find_node_by_path("/soc at 0");
+
+	/* This should never happen */
+	WARN_ON(!soc);
+
+	for (i = 0; i < access_gates->num_words; i++) {
+		off = access_gates->words[i] << 2;
+		priv->value[i] = readl(reg + off);
+		dev_dbg(&pdev->dev, "word:%d 0x%08x\n", access_gates->words[i], priv->value[i]);
+	}
+
+	return imx_ele_ocotp_grant_access(pdev, soc);
+}
+
 static int imx_ele_ocotp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -161,14 +273,43 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
 	mutex_init(&priv->lock);
 
+	platform_set_drvdata(pdev, priv);
+
 	nvmem = devm_nvmem_register(dev, &priv->config);
 	if (IS_ERR(nvmem))
 		return PTR_ERR(nvmem);
 
-	return 0;
+
+	return imx_ele_ocotp_access_control(pdev);
 }
 
+static const struct ocotp_access_gates imx93_access_gates = {
+	.num_words = 3,
+	.words = {19, 20, 21},
+	.num_gates = IMX93_OCOTP_NUM_GATES,
+	.gates = {
+		[IMX93_OCOTP_NPU_GATE]		= { .word = 19, .mask = BIT(13) },
+		[IMX93_OCOTP_A550_GATE]		= { .word = 19, .mask = BIT(14) },
+		[IMX93_OCOTP_A551_GATE]		= { .word = 19, .mask = BIT(15) },
+		[IMX93_OCOTP_M33_GATE]		= { .word = 19, .mask = BIT(24) },
+		[IMX93_OCOTP_CAN1_FD_GATE]	= { .word = 19, .mask = BIT(28) },
+		[IMX93_OCOTP_CAN2_FD_GATE]	= { .word = 19, .mask = BIT(29) },
+		[IMX93_OCOTP_CAN1_GATE]		= { .word = 19, .mask = BIT(30) },
+		[IMX93_OCOTP_CAN2_GATE]		= { .word = 19, .mask = BIT(31) },
+		[IMX93_OCOTP_USB1_GATE]		= { .word = 20, .mask = BIT(3) },
+		[IMX93_OCOTP_USB2_GATE]		= { .word = 20, .mask = BIT(4) },
+		[IMX93_OCOTP_ENET1_GATE]	= { .word = 20, .mask = BIT(5) },
+		[IMX93_OCOTP_ENET2_GATE]	= { .word = 20, .mask = BIT(6) },
+		[IMX93_OCOTP_PXP_GATE]		= { .word = 20, .mask = BIT(10) },
+		[IMX93_OCOTP_MIPI_CSI1_GATE]	= { .word = 20, .mask = BIT(17) },
+		[IMX93_OCOTP_MIPI_DSI1_GATE]	= { .word = 20, .mask = BIT(19) },
+		[IMX93_OCOTP_LVDS1_GATE]	= { .word = 20, .mask = BIT(24) },
+		[IMX93_OCOTP_ADC1_GATE]		= { .word = 21, .mask = BIT(7) },
+	},
+};
+
 static const struct ocotp_devtype_data imx93_ocotp_data = {
+	.access_gates = &imx93_access_gates,
 	.reg_off = 0x8000,
 	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,
@@ -183,7 +324,51 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
 	},
 };
 
+static const struct ocotp_access_gates imx95_access_gates = {
+	.num_words = 3,
+	.words = {17, 18, 19},
+	.num_gates = IMX95_OCOTP_NUM_GATES,
+	.gates = {
+		[IMX95_OCOTP_CANFD1_GATE]	= { .word = 17, .mask = BIT(20) },
+		[IMX95_OCOTP_CANFD2_GATE]	= { .word = 17, .mask = BIT(21) },
+		[IMX95_OCOTP_CANFD3_GATE]	= { .word = 17, .mask = BIT(22) },
+		[IMX95_OCOTP_CANFD4_GATE]	= { .word = 17, .mask = BIT(23) },
+		[IMX95_OCOTP_CANFD5_GATE]	= { .word = 17, .mask = BIT(24) },
+		[IMX95_OCOTP_CAN1_GATE]	= { .word = 17, .mask = BIT(25) },
+		[IMX95_OCOTP_CAN2_GATE]	= { .word = 17, .mask = BIT(26) },
+		[IMX95_OCOTP_CAN3_GATE]	= { .word = 17, .mask = BIT(27) },
+		[IMX95_OCOTP_CAN4_GATE]	= { .word = 17, .mask = BIT(28) },
+		[IMX95_OCOTP_CAN5_GATE]	= { .word = 17, .mask = BIT(29) },
+		[IMX95_OCOTP_NPU_GATE]		= { .word = 18, .mask = BIT(0) },
+		[IMX95_OCOTP_A550_GATE]	= { .word = 18, .mask = BIT(1) },
+		[IMX95_OCOTP_A551_GATE]	= { .word = 18, .mask = BIT(2) },
+		[IMX95_OCOTP_A552_GATE]	= { .word = 18, .mask = BIT(3) },
+		[IMX95_OCOTP_A553_GATE]	= { .word = 18, .mask = BIT(4) },
+		[IMX95_OCOTP_A554_GATE]	= { .word = 18, .mask = BIT(5) },
+		[IMX95_OCOTP_A555_GATE]	= { .word = 18, .mask = BIT(6) },
+		[IMX95_OCOTP_M7_GATE]		= { .word = 18, .mask = BIT(9) },
+		[IMX95_OCOTP_DCSS_GATE]	= { .word = 18, .mask = BIT(22) },
+		[IMX95_OCOTP_LVDS1_GATE]	= { .word = 18, .mask = BIT(27) },
+		[IMX95_OCOTP_ISP_GATE]		= { .word = 18, .mask = BIT(29) },
+		[IMX95_OCOTP_USB1_GATE]	= { .word = 19, .mask = BIT(2) },
+		[IMX95_OCOTP_USB2_GATE]	= { .word = 19, .mask = BIT(3) },
+		[IMX95_OCOTP_NETC_GATE]	= { .word = 19, .mask = BIT(4) },
+		[IMX95_OCOTP_PCIE1_GATE]	= { .word = 19, .mask = BIT(6) },
+		[IMX95_OCOTP_PCIE2_GATE]	= { .word = 19, .mask = BIT(7) },
+		[IMX95_OCOTP_ADC1_GATE]	= { .word = 19, .mask = BIT(8) },
+		[IMX95_OCOTP_EARC_RX_GATE]	= { .word = 19, .mask = BIT(11) },
+		[IMX95_OCOTP_GPU3D_GATE]	= { .word = 19, .mask = BIT(16) },
+		[IMX95_OCOTP_VPU_GATE]		= { .word = 19, .mask = BIT(17) },
+		[IMX95_OCOTP_JPEG_ENC_GATE]	= { .word = 19, .mask = BIT(18) },
+		[IMX95_OCOTP_JPEG_DEC_GATE]	= { .word = 19, .mask = BIT(19) },
+		[IMX95_OCOTP_MIPI_CSI1_GATE]	= { .word = 19, .mask = BIT(21) },
+		[IMX95_OCOTP_MIPI_CSI2_GATE]	= { .word = 19, .mask = BIT(22) },
+		[IMX95_OCOTP_MIPI_DSI1_GATE]	= { .word = 19, .mask = BIT(23) },
+	}
+};
+
 static const struct ocotp_devtype_data imx95_ocotp_data = {
+	.access_gates = &imx95_access_gates,
 	.reg_off = 0x8000,
 	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,

-- 
2.37.1



From krzk at kernel.org  Thu Dec 12 00:17:27 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 09:17:27 +0100
Subject: [PATCH v3 07/13] dt-bindings: clock: Add SAMA7D65 PMC compatible
 string
In-Reply-To: <fb11338b-986f-4a9a-a0dd-e8f4e63941aa@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com>
 <20241210164638.GA3770349-robh@kernel.org>
 <fb11338b-986f-4a9a-a0dd-e8f4e63941aa@microchip.com>
Message-ID: <s77ndnhfnpssi4hynbf5n2ylkrhftnlfu37km5vpqbeb552w47@fhklcvdnwasa>

On Wed, Dec 11, 2024 at 08:25:32AM -0700, Ryan Wanner wrote:
> On 12/10/24 09:46, Rob Herring wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> > On Fri, Dec 06, 2024 at 12:59:52PM -0700, Ryan.Wanner at microchip.com wrote:
> >> From: Dharma Balasubiramani <dharma.b at microchip.com>
> >>
> >> Add the `microchip,sama7d65-pmc` compatible string to the existing binding,
> >> since the SAMA7D65 PMC shares the same properties and clock requirements
> >> as the SAMA7G5.
> >>
> >> Export MCK3 and MCK5 to be accessed and referenced in DT to assign to
> >> the clocks property for sama7d65 SoC.
> >>
> >> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> >> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> > 
> > Missing Conor's ack.
> I removed the ack because I have changed the original patch that was
> acked. Should the ack not have been removed even though the original
> patch as been changed?

Nothing in changelog says about changes to this patch. Nothing also
mentions dropping acks.

Please read:

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 krzk at kernel.org  Thu Dec 12 00:17:47 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 09:17:47 +0100
Subject: [PATCH v3 07/13] dt-bindings: clock: Add SAMA7D65 PMC compatible
 string
In-Reply-To: <5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com>
References: <cover.1733505542.git.Ryan.Wanner@microchip.com>
 <5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com>
Message-ID: <faf3547rv7easjc6rwewzn3xdp2y2zc4opsbqvhvsbi6e5g6fd@dkcdkiycp5op>

On Fri, Dec 06, 2024 at 12:59:52PM -0700, Ryan.Wanner at microchip.com wrote:
> From: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Add the `microchip,sama7d65-pmc` compatible string to the existing binding,
> since the SAMA7D65 PMC shares the same properties and clock requirements
> as the SAMA7G5.
> 
> Export MCK3 and MCK5 to be accessed and referenced in DT to assign to
> the clocks property for sama7d65 SoC.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
> ---

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

Best regards,
Krzysztof



From ardb+git at google.com  Thu Dec 12 00:18:42 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu, 12 Dec 2024 09:18:42 +0100
Subject: [PATCH v3 0/6] arm64: Clean up and simplify PA space size handling
Message-ID: <20241212081841.2168124-8-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

This series addresses a number of buglets related to how we handle the
size of the physical address space when building LPA2 capable kernels:

- reject 52-bit physical addressess in the mapping routines when LPA2 is
  configured but not available at runtime
- ensure that TCR.IPS is not set to 52-bits if LPA2 is not supported
- ensure that TCR_EL2.PS and DS match the host, regardless of whether
  LPA2 is available at stage 2
- don't rely on kvm_get_parange() and invalid physical addresses as
  control flags in the pKVM page donation APIs

Finally, the configurable 48-bit physical address space limit is dropped
entirely, as it doesn't buy us a lot now that all the PARange and {I}PS
handling is done at runtime.

Changes since v2:
- add a definition of MAX_POSSIBLE_PHYSMEM_BITS to fix a build error in
  zsmalloc (#1)
- rename 'owner_update' to 'annotation' (#4)

Changes since v1:
- rebase onto v6.13-rc1
- add Anshuman's ack to patch #1
- incorporate Anshuman's feedback on patches #1 and #2
- tweak owner_update logic in patch #4

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>
Cc: Quentin Perret <qperret at google.com>

Ard Biesheuvel (6):
  arm64/mm: Reduce PA space to 48 bits when LPA2 is not enabled
  arm64/mm: Override PARange for !LPA2 and use it consistently
  arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
  arm64/kvm: Avoid invalid physical addresses to signal owner updates
  arm64: Kconfig: force ARM64_PAN=y when enabling TTBR0 sw PAN
  arm64/mm: Drop configurable 48-bit physical address space limit

 arch/arm64/Kconfig                     | 37 ++------------------
 arch/arm64/include/asm/assembler.h     | 14 +++-----
 arch/arm64/include/asm/cpufeature.h    |  3 +-
 arch/arm64/include/asm/kvm_pgtable.h   |  3 +-
 arch/arm64/include/asm/pgtable-hwdef.h | 12 +------
 arch/arm64/include/asm/pgtable-prot.h  |  7 ++++
 arch/arm64/include/asm/pgtable.h       | 11 +-----
 arch/arm64/include/asm/sparsemem.h     |  5 ++-
 arch/arm64/include/asm/sysreg.h        |  6 ----
 arch/arm64/kernel/cpufeature.c         |  2 +-
 arch/arm64/kernel/pi/idreg-override.c  |  9 +++++
 arch/arm64/kernel/pi/map_kernel.c      |  6 ++++
 arch/arm64/kvm/arm.c                   |  8 ++---
 arch/arm64/kvm/hyp/pgtable.c           | 33 ++++++-----------
 arch/arm64/mm/init.c                   |  7 +++-
 arch/arm64/mm/pgd.c                    |  9 ++---
 arch/arm64/mm/proc.S                   |  2 --
 scripts/gdb/linux/constants.py.in      |  1 -
 tools/arch/arm64/include/asm/sysreg.h  |  6 ----
 19 files changed, 64 insertions(+), 117 deletions(-)

-- 
2.47.1.613.gc27f4b7a9f-goog



From ardb+git at google.com  Thu Dec 12 00:18:43 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu, 12 Dec 2024 09:18:43 +0100
Subject: [PATCH v3 1/6] arm64/mm: Reduce PA space to 48 bits when LPA2 is not enabled
In-Reply-To: <20241212081841.2168124-8-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
Message-ID: <20241212081841.2168124-9-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Currently, LPA2 kernel support implies support for up to 52 bits of
physical addressing, and this is reflected in global definitions such as
PHYS_MASK_SHIFT and MAX_PHYSMEM_BITS.

This is potentially problematic, given that LPA2 hardware support is
modeled as a CPU feature which can be overridden, and with LPA2 hardware
support turned off, attempting to map physical regions with address bits
[51:48] set (which may exist on LPA2 capable systems booting with
arm64.nolva) will result in corrupted mappings with a truncated output
address and bogus shareability attributes.

This means that the accepted physical address range in the mapping
routines should be at most 48 bits wide when LPA2 support is configured
but not enabled at runtime.

Fixes: 352b0395b505 ("arm64: Enable 52-bit virtual addressing for 4k and 16k granule configs")
Cc: <stable at vger.kernel.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgtable-hwdef.h | 6 ------
 arch/arm64/include/asm/pgtable-prot.h  | 7 +++++++
 arch/arm64/include/asm/sparsemem.h     | 5 ++++-
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index c78a988cca93..a9136cc551cc 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -222,12 +222,6 @@
  */
 #define S1_TABLE_AP		(_AT(pmdval_t, 3) << 61)
 
-/*
- * Highest possible physical address supported.
- */
-#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
-#define PHYS_MASK		((UL(1) << PHYS_MASK_SHIFT) - 1)
-
 #define TTBR_CNP_BIT		(UL(1) << 0)
 
 /*
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 9f9cf13bbd95..a95f1f77bb39 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -81,6 +81,7 @@ extern unsigned long prot_ns_shared;
 #define lpa2_is_enabled()	false
 #define PTE_MAYBE_SHARED	PTE_SHARED
 #define PMD_MAYBE_SHARED	PMD_SECT_S
+#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
 #else
 static inline bool __pure lpa2_is_enabled(void)
 {
@@ -89,8 +90,14 @@ static inline bool __pure lpa2_is_enabled(void)
 
 #define PTE_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PTE_SHARED)
 #define PMD_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PMD_SECT_S)
+#define PHYS_MASK_SHIFT		(lpa2_is_enabled() ? CONFIG_ARM64_PA_BITS : 48)
 #endif
 
+/*
+ * Highest possible physical address supported.
+ */
+#define PHYS_MASK		((UL(1) << PHYS_MASK_SHIFT) - 1)
+
 /*
  * If we have userspace only BTI we don't want to mark kernel pages
  * guarded even if the system does support BTI.
diff --git a/arch/arm64/include/asm/sparsemem.h b/arch/arm64/include/asm/sparsemem.h
index 8a8acc220371..84783efdc9d1 100644
--- a/arch/arm64/include/asm/sparsemem.h
+++ b/arch/arm64/include/asm/sparsemem.h
@@ -5,7 +5,10 @@
 #ifndef __ASM_SPARSEMEM_H
 #define __ASM_SPARSEMEM_H
 
-#define MAX_PHYSMEM_BITS	CONFIG_ARM64_PA_BITS
+#include <asm/pgtable-prot.h>
+
+#define MAX_PHYSMEM_BITS		PHYS_MASK_SHIFT
+#define MAX_POSSIBLE_PHYSMEM_BITS	(52)
 
 /*
  * Section size must be at least 512MB for 64K base
-- 
2.47.1.613.gc27f4b7a9f-goog



From ardb+git at google.com  Thu Dec 12 00:18:44 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu, 12 Dec 2024 09:18:44 +0100
Subject: [PATCH v3 2/6] arm64/mm: Override PARange for !LPA2 and use it consistently
In-Reply-To: <20241212081841.2168124-8-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
Message-ID: <20241212081841.2168124-10-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

When FEAT_LPA{,2} are not implemented, the ID_AA64MMFR0_EL1.PARange and
TCR.IPS values corresponding with 52-bit physical addressing are
reserved.

Setting the TCR.IPS field to 0b110 (52-bit physical addressing) has side
effects, such as how the TTBRn_ELx.BADDR fields are interpreted, and so
it is important that disabling FEAT_LPA2 (by overriding the
ID_AA64MMFR0.TGran fields) also presents a PARange field consistent with
that.

So limit the field to 48 bits unless LPA2 is enabled, and update
existing references to use the override consistently.

Fixes: 352b0395b505 ("arm64: Enable 52-bit virtual addressing for 4k and 16k granule configs")
Cc: <stable at vger.kernel.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/assembler.h    | 5 +++++
 arch/arm64/kernel/cpufeature.c        | 2 +-
 arch/arm64/kernel/pi/idreg-override.c | 9 +++++++++
 arch/arm64/kernel/pi/map_kernel.c     | 6 ++++++
 arch/arm64/mm/init.c                  | 7 ++++++-
 5 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 3d8d534a7a77..ad63457a05c5 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -343,6 +343,11 @@ alternative_cb_end
 	// Narrow PARange to fit the PS field in TCR_ELx
 	ubfx	\tmp0, \tmp0, #ID_AA64MMFR0_EL1_PARANGE_SHIFT, #3
 	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_MAX
+#ifdef CONFIG_ARM64_LPA2
+alternative_if_not ARM64_HAS_VA52
+	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_48
+alternative_else_nop_endif
+#endif
 	cmp	\tmp0, \tmp1
 	csel	\tmp0, \tmp1, \tmp0, hi
 	bfi	\tcr, \tmp0, \pos, #3
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed8..f8cb8a6ab98a 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -3478,7 +3478,7 @@ static void verify_hyp_capabilities(void)
 		return;
 
 	safe_mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
-	mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
+	mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 	mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
 
 	/* Verify VMID bits */
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index 22159251eb3a..c6b185b885f7 100644
--- a/arch/arm64/kernel/pi/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -83,6 +83,15 @@ static bool __init mmfr2_varange_filter(u64 val)
 		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;
+
+		/*
+		 * Override PARange to 48 bits - the override will just be
+		 * ignored if the actual PARange is smaller, but this is
+		 * unlikely to be the case for LPA2 capable silicon.
+		 */
+		id_aa64mmfr0_override.val |=
+			ID_AA64MMFR0_EL1_PARANGE_48 << ID_AA64MMFR0_EL1_PARANGE_SHIFT;
+		id_aa64mmfr0_override.mask |= 0xfU << ID_AA64MMFR0_EL1_PARANGE_SHIFT;
 	}
 #endif
 	return true;
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
index f374a3e5a5fe..e57b043f324b 100644
--- a/arch/arm64/kernel/pi/map_kernel.c
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -136,6 +136,12 @@ 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;
+	u64 mmfr0 = read_sysreg(id_aa64mmfr0_el1);
+	u64 parange = cpuid_feature_extract_unsigned_field(mmfr0,
+							   ID_AA64MMFR0_EL1_PARANGE_SHIFT);
+
+	tcr &= ~TCR_IPS_MASK;
+	tcr |= parange << TCR_IPS_SHIFT;
 
 	asm("	msr	sctlr_el1, %0		;"
 	    "	isb				;"
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d21f67d67cf5..2b2289d55eaa 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -280,7 +280,12 @@ void __init arm64_memblock_init(void)
 
 	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
 		extern u16 memstart_offset_seed;
-		u64 mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
+
+		/*
+		 * Use the sanitised version of id_aa64mmfr0_el1 so that linear
+		 * map randomization can be enabled by shrinking the IPA space.
+		 */
+		u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 		int parange = cpuid_feature_extract_unsigned_field(
 					mmfr0, ID_AA64MMFR0_EL1_PARANGE_SHIFT);
 		s64 range = linear_region_size -
-- 
2.47.1.613.gc27f4b7a9f-goog



From ardb+git at google.com  Thu Dec 12 00:18:45 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu, 12 Dec 2024 09:18:45 +0100
Subject: [PATCH v3 3/6] arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
In-Reply-To: <20241212081841.2168124-8-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
Message-ID: <20241212081841.2168124-11-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

When the host stage1 is configured for LPA2, the value currently being
programmed into TCR_EL2.T0SZ may be invalid unless LPA2 is configured
at HYP as well.  This means kvm_lpa2_is_enabled() is not the right
condition to test when setting TCR_EL2.DS, as it will return false if
LPA2 is only available for stage 1 but not for stage 2.

Similary, programming TCR_EL2.PS based on a limited IPA range due to
lack of stage2 LPA2 support could potentially result in problems.

So use lpa2_is_enabled() instead, and set the PS field according to the
host's IPS, which is capped at 48 bits if LPA2 support is absent or
disabled. Whether or not we can make meaningful use of such a
configuration is a different question.

Cc: <stable at vger.kernel.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kvm/arm.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..7b2735ad32e9 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1990,8 +1990,7 @@ static int kvm_init_vector_slots(void)
 static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
 {
 	struct kvm_nvhe_init_params *params = per_cpu_ptr_nvhe_sym(kvm_init_params, cpu);
-	u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
-	unsigned long tcr;
+	unsigned long tcr, ips;
 
 	/*
 	 * Calculate the raw per-cpu offset without a translation from the
@@ -2005,6 +2004,7 @@ static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
 	params->mair_el2 = read_sysreg(mair_el1);
 
 	tcr = read_sysreg(tcr_el1);
+	ips = FIELD_GET(TCR_IPS_MASK, tcr);
 	if (cpus_have_final_cap(ARM64_KVM_HVHE)) {
 		tcr |= TCR_EPD1_MASK;
 	} else {
@@ -2014,8 +2014,8 @@ static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
 	tcr &= ~TCR_T0SZ_MASK;
 	tcr |= TCR_T0SZ(hyp_va_bits);
 	tcr &= ~TCR_EL2_PS_MASK;
-	tcr |= FIELD_PREP(TCR_EL2_PS_MASK, kvm_get_parange(mmfr0));
-	if (kvm_lpa2_is_enabled())
+	tcr |= FIELD_PREP(TCR_EL2_PS_MASK, ips);
+	if (lpa2_is_enabled())
 		tcr |= TCR_EL2_DS;
 	params->tcr_el2 = tcr;
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From ardb+git at google.com  Thu Dec 12 00:18:46 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu, 12 Dec 2024 09:18:46 +0100
Subject: [PATCH v3 4/6] arm64/kvm: Avoid invalid physical addresses to signal
 owner updates
In-Reply-To: <20241212081841.2168124-8-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
Message-ID: <20241212081841.2168124-12-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The pKVM stage2 mapping code relies on an invalid physical address to
signal to the internal API that only the annotations of descriptors
should be updated, and these are stored in the high bits of invalid
descriptors covering memory that has been donated to protected guests,
and is therefore unmapped from the host stage-2 page tables.

Given that these invalid PAs are never stored into the descriptors, it
is better to rely on an explicit flag, to clarify the API and to avoid
confusion regarding whether or not the output address of a descriptor
can ever be invalid to begin with (which is not the case with LPA2).

That removes a dependency on the logic that reasons about the maximum PA
range, which differs on LPA2 capable CPUs based on whether LPA2 is
enabled or not, and will be further clarified in subsequent patches.

Cc: Quentin Perret <qperret at google.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kvm/hyp/pgtable.c | 33 ++++++--------------
 1 file changed, 10 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 40bd55966540..ed600126161a 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -35,14 +35,6 @@ static bool kvm_pgtable_walk_skip_cmo(const struct kvm_pgtable_visit_ctx *ctx)
 	return unlikely(ctx->flags & KVM_PGTABLE_WALK_SKIP_CMO);
 }
 
-static bool kvm_phys_is_valid(u64 phys)
-{
-	u64 parange_max = kvm_get_parange_max();
-	u8 shift = id_aa64mmfr0_parange_to_phys_shift(parange_max);
-
-	return phys < BIT(shift);
-}
-
 static bool kvm_block_mapping_supported(const struct kvm_pgtable_visit_ctx *ctx, u64 phys)
 {
 	u64 granule = kvm_granule_size(ctx->level);
@@ -53,7 +45,7 @@ static bool kvm_block_mapping_supported(const struct kvm_pgtable_visit_ctx *ctx,
 	if (granule > (ctx->end - ctx->addr))
 		return false;
 
-	if (kvm_phys_is_valid(phys) && !IS_ALIGNED(phys, granule))
+	if (!IS_ALIGNED(phys, granule))
 		return false;
 
 	return IS_ALIGNED(ctx->addr, granule);
@@ -587,6 +579,9 @@ struct stage2_map_data {
 
 	/* Force mappings to page granularity */
 	bool				force_pte;
+
+	/* Walk should update owner_id only */
+	bool				annotation;
 };
 
 u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
@@ -885,18 +880,7 @@ static u64 stage2_map_walker_phys_addr(const struct kvm_pgtable_visit_ctx *ctx,
 {
 	u64 phys = data->phys;
 
-	/*
-	 * Stage-2 walks to update ownership data are communicated to the map
-	 * walker using an invalid PA. Avoid offsetting an already invalid PA,
-	 * which could overflow and make the address valid again.
-	 */
-	if (!kvm_phys_is_valid(phys))
-		return phys;
-
-	/*
-	 * Otherwise, work out the correct PA based on how far the walk has
-	 * gotten.
-	 */
+	/* Work out the correct PA based on how far the walk has gotten */
 	return phys + (ctx->addr - ctx->start);
 }
 
@@ -908,6 +892,9 @@ static bool stage2_leaf_mapping_allowed(const struct kvm_pgtable_visit_ctx *ctx,
 	if (data->force_pte && ctx->level < KVM_PGTABLE_LAST_LEVEL)
 		return false;
 
+	if (data->annotation && ctx->level == KVM_PGTABLE_LAST_LEVEL)
+		return true;
+
 	return kvm_block_mapping_supported(ctx, phys);
 }
 
@@ -923,7 +910,7 @@ static int stage2_map_walker_try_leaf(const struct kvm_pgtable_visit_ctx *ctx,
 	if (!stage2_leaf_mapping_allowed(ctx, data))
 		return -E2BIG;
 
-	if (kvm_phys_is_valid(phys))
+	if (!data->annotation)
 		new = kvm_init_valid_leaf_pte(phys, data->attr, ctx->level);
 	else
 		new = kvm_init_invalid_leaf_owner(data->owner_id);
@@ -1085,11 +1072,11 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size,
 {
 	int ret;
 	struct stage2_map_data map_data = {
-		.phys		= KVM_PHYS_INVALID,
 		.mmu		= pgt->mmu,
 		.memcache	= mc,
 		.owner_id	= owner_id,
 		.force_pte	= true,
+		.annotation	= true,
 	};
 	struct kvm_pgtable_walker walker = {
 		.cb		= stage2_map_walker,
-- 
2.47.1.613.gc27f4b7a9f-goog



From ardb+git at google.com  Thu Dec 12 00:18:47 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu, 12 Dec 2024 09:18:47 +0100
Subject: [PATCH v3 5/6] arm64: Kconfig: force ARM64_PAN=y when enabling TTBR0
 sw PAN
In-Reply-To: <20241212081841.2168124-8-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
Message-ID: <20241212081841.2168124-13-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

There are a couple of instances of Kconfig constraints where PAN must be
enabled too if TTBR0 sw PAN is enabled, primarily to avoid dealing with
the modified TTBR0_EL1 sysreg format that is used when 52-bit physical
addressing and/or CnP are enabled (support for either implies support
for hardware PAN as well, which will supersede PAN emulation if both are
available)

Let's simplify this, and always enable ARM64_PAN when enabling TTBR0 sw
PAN. This decouples the PAN configuration from the VA size selection,
permitting us to simplify the latter in subsequent patches. (Note that
PAN and TTBR0 sw PAN can still be disabled after this patch, but not
independently)

To avoid a convoluted circular Kconfig dependency involving KCSAN, make
ARM64_MTE select ARM64_PAN too, instead of depending on it.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/Kconfig | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..c1ca21adddc1 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1379,7 +1379,6 @@ config ARM64_VA_BITS_48
 
 config ARM64_VA_BITS_52
 	bool "52-bit"
-	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
@@ -1431,7 +1430,6 @@ config ARM64_PA_BITS_48
 config ARM64_PA_BITS_52
 	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
 	  part of the ARMv8.2-LPA extension.
@@ -1681,6 +1679,7 @@ config RODATA_FULL_DEFAULT_ENABLED
 config ARM64_SW_TTBR0_PAN
 	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
 	depends on !KCSAN
+	select ARM64_PAN
 	help
 	  Enabling this option prevents the kernel from accessing
 	  user-space memory directly by pointing TTBR0_EL1 to a reserved
@@ -1937,7 +1936,6 @@ config ARM64_RAS_EXTN
 config ARM64_CNP
 	bool "Enable support for Common Not Private (CNP) translations"
 	default y
-	depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
 	help
 	  Common Not Private (CNP) allows translation table entries to
 	  be shared between different PEs in the same inner shareable
@@ -2132,7 +2130,7 @@ config ARM64_MTE
 	depends on AS_HAS_ARMV8_5
 	depends on AS_HAS_LSE_ATOMICS
 	# Required for tag checking in the uaccess routines
-	depends on ARM64_PAN
+	select ARM64_PAN
 	select ARCH_HAS_SUBPAGE_FAULTS
 	select ARCH_USES_HIGH_VMA_FLAGS
 	select ARCH_USES_PG_ARCH_2
-- 
2.47.1.613.gc27f4b7a9f-goog



From ardb+git at google.com  Thu Dec 12 00:18:48 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Thu, 12 Dec 2024 09:18:48 +0100
Subject: [PATCH v3 6/6] arm64/mm: Drop configurable 48-bit physical address
 space limit
In-Reply-To: <20241212081841.2168124-8-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
Message-ID: <20241212081841.2168124-14-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Currently, the maximum supported physical address space can be
configured as either 48 bits or 52 bits. The only remaining difference
between these in practice is that the former omits the masking and
shifting required to construct TTBR and PTE values, which carry bits #48
and higher disjoint from the rest of the physical address.

The overhead of performing these additional calculations is negligible,
and so there is little reason to retain support for two different
configurations, and we can simply support whatever the hardware
supports.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/Kconfig                     | 31 +-------------------
 arch/arm64/include/asm/assembler.h     | 13 ++------
 arch/arm64/include/asm/cpufeature.h    |  3 +-
 arch/arm64/include/asm/kvm_pgtable.h   |  3 +-
 arch/arm64/include/asm/pgtable-hwdef.h |  6 +---
 arch/arm64/include/asm/pgtable-prot.h  |  4 +--
 arch/arm64/include/asm/pgtable.h       | 11 +------
 arch/arm64/include/asm/sysreg.h        |  6 ----
 arch/arm64/mm/pgd.c                    |  9 +++---
 arch/arm64/mm/proc.S                   |  2 --
 scripts/gdb/linux/constants.py.in      |  1 -
 tools/arch/arm64/include/asm/sysreg.h  |  6 ----
 12 files changed, 14 insertions(+), 81 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c1ca21adddc1..7ebd0ba32a32 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1416,38 +1416,9 @@ config ARM64_VA_BITS
 	default 48 if ARM64_VA_BITS_48
 	default 52 if ARM64_VA_BITS_52
 
-choice
-	prompt "Physical address space size"
-	default ARM64_PA_BITS_48
-	help
-	  Choose the maximum physical address range that the kernel will
-	  support.
-
-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"
-	depends on ARM64_64K_PAGES || ARM64_VA_BITS_52
-	help
-	  Enable support for a 52-bit physical address space, introduced as
-	  part of the ARMv8.2-LPA extension.
-
-	  With this enabled, the kernel will also continue to work on CPUs that
-	  do not support ARMv8.2-LPA, but with some added memory overhead (and
-	  minor performance overhead).
-
-endchoice
-
-config ARM64_PA_BITS
-	int
-	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
+	depends on !ARM64_64K_PAGES
 
 choice
 	prompt "Endianness"
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index ad63457a05c5..01a1e3c16283 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -342,14 +342,13 @@ alternative_cb_end
 	mrs	\tmp0, ID_AA64MMFR0_EL1
 	// Narrow PARange to fit the PS field in TCR_ELx
 	ubfx	\tmp0, \tmp0, #ID_AA64MMFR0_EL1_PARANGE_SHIFT, #3
-	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_MAX
 #ifdef CONFIG_ARM64_LPA2
 alternative_if_not ARM64_HAS_VA52
 	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_48
-alternative_else_nop_endif
-#endif
 	cmp	\tmp0, \tmp1
 	csel	\tmp0, \tmp1, \tmp0, hi
+alternative_else_nop_endif
+#endif
 	bfi	\tcr, \tmp0, \pos, #3
 	.endm
 
@@ -599,21 +598,13 @@ alternative_endif
  * 	ttbr:	returns the TTBR value
  */
 	.macro	phys_to_ttbr, ttbr, phys
-#ifdef CONFIG_ARM64_PA_BITS_52
 	orr	\ttbr, \phys, \phys, lsr #46
 	and	\ttbr, \ttbr, #TTBR_BADDR_MASK_52
-#else
-	mov	\ttbr, \phys
-#endif
 	.endm
 
 	.macro	phys_to_pte, pte, phys
-#ifdef CONFIG_ARM64_PA_BITS_52
 	orr	\pte, \phys, \phys, lsr #PTE_ADDR_HIGH_SHIFT
 	and	\pte, \pte, #PHYS_TO_PTE_ADDR_MASK
-#else
-	mov	\pte, \phys
-#endif
 	.endm
 
 /*
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index b64e49bd9d10..ed327358e734 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -885,9 +885,8 @@ static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
 	 * However, by the "D10.1.4 Principles of the ID scheme
 	 * for fields in ID registers", ARM DDI 0487C.a, any new
 	 * value is guaranteed to be higher than what we know already.
-	 * As a safe limit, we return the limit supported by the kernel.
 	 */
-	default: return CONFIG_ARM64_PA_BITS;
+	default: return 52;
 	}
 }
 
diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index aab04097b505..525aef178cb4 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -30,8 +30,7 @@
 
 static inline u64 kvm_get_parange_max(void)
 {
-	if (kvm_lpa2_is_enabled() ||
-	   (IS_ENABLED(CONFIG_ARM64_PA_BITS_52) && PAGE_SHIFT == 16))
+	if (kvm_lpa2_is_enabled() || PAGE_SHIFT == 16)
 		return ID_AA64MMFR0_EL1_PARANGE_52;
 	else
 		return ID_AA64MMFR0_EL1_PARANGE_48;
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index a9136cc551cc..9b34180042b2 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -176,7 +176,6 @@
 #define PTE_SWBITS_MASK		_AT(pteval_t, (BIT(63) | GENMASK(58, 55)))
 
 #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_HIGH_SHIFT	36
@@ -186,7 +185,6 @@
 #define PTE_ADDR_HIGH_SHIFT	42
 #define PHYS_TO_PTE_ADDR_MASK	GENMASK_ULL(49, 8)
 #endif
-#endif
 
 /*
  * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
@@ -327,12 +325,10 @@
 /*
  * TTBR.
  */
-#ifdef CONFIG_ARM64_PA_BITS_52
 /*
- * TTBR_ELx[1] is RES0 in this configuration.
+ * TTBR_ELx[1] is RES0 when using 52-bit physical addressing
  */
 #define TTBR_BADDR_MASK_52	GENMASK_ULL(47, 2)
-#endif
 
 #ifdef CONFIG_ARM64_VA_BITS_52
 /* Must be at least 64-byte aligned to prevent corruption of the TTBR */
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index a95f1f77bb39..b73acf25341f 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -81,7 +81,7 @@ extern unsigned long prot_ns_shared;
 #define lpa2_is_enabled()	false
 #define PTE_MAYBE_SHARED	PTE_SHARED
 #define PMD_MAYBE_SHARED	PMD_SECT_S
-#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
+#define PHYS_MASK_SHIFT		(52)
 #else
 static inline bool __pure lpa2_is_enabled(void)
 {
@@ -90,7 +90,7 @@ static inline bool __pure lpa2_is_enabled(void)
 
 #define PTE_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PTE_SHARED)
 #define PMD_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PMD_SECT_S)
-#define PHYS_MASK_SHIFT		(lpa2_is_enabled() ? CONFIG_ARM64_PA_BITS : 48)
+#define PHYS_MASK_SHIFT		(lpa2_is_enabled() ? 52 : 48)
 #endif
 
 /*
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6986345b537a..ec8124d66b9c 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -69,10 +69,9 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 	pr_err("%s:%d: bad pte %016llx.\n", __FILE__, __LINE__, pte_val(e))
 
 /*
- * Macros to convert between a physical address and its placement in a
+ * Helpers to convert between a physical address and its placement in a
  * page table entry, taking care of 52-bit addresses.
  */
-#ifdef CONFIG_ARM64_PA_BITS_52
 static inline phys_addr_t __pte_to_phys(pte_t pte)
 {
 	pte_val(pte) &= ~PTE_MAYBE_SHARED;
@@ -83,10 +82,6 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
 {
 	return (phys | (phys >> PTE_ADDR_HIGH_SHIFT)) & PHYS_TO_PTE_ADDR_MASK;
 }
-#else
-#define __pte_to_phys(pte)	(pte_val(pte) & PTE_ADDR_LOW)
-#define __phys_to_pte_val(phys)	(phys)
-#endif
 
 #define pte_pfn(pte)		(__pte_to_phys(pte) >> PAGE_SHIFT)
 #define pfn_pte(pfn,prot)	\
@@ -1495,11 +1490,7 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
 	update_mmu_cache_range(NULL, vma, addr, ptep, 1)
 #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
 
-#ifdef CONFIG_ARM64_PA_BITS_52
 #define phys_to_ttbr(addr)	(((addr) | ((addr) >> 46)) & TTBR_BADDR_MASK_52)
-#else
-#define phys_to_ttbr(addr)	(addr)
-#endif
 
 /*
  * On arm64 without hardware Access Flag, copying from user will fail because
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index b8303a83c0bf..f902893ec903 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -916,12 +916,6 @@
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2		0x3
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX		0x7
 
-#ifdef CONFIG_ARM64_PA_BITS_52
-#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_52
-#else
-#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_48
-#endif
-
 #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
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 0c501cabc238..8722ab6d4b1c 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -48,20 +48,21 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 
 void __init pgtable_cache_init(void)
 {
+	unsigned int pgd_size = PGD_SIZE;
+
 	if (pgdir_is_page_size())
 		return;
 
-#ifdef CONFIG_ARM64_PA_BITS_52
 	/*
 	 * With 52-bit physical addresses, the architecture requires the
 	 * top-level table to be aligned to at least 64 bytes.
 	 */
-	BUILD_BUG_ON(PGD_SIZE < 64);
-#endif
+	if (PHYS_MASK_SHIFT >= 52)
+		pgd_size = max(pgd_size, 64);
 
 	/*
 	 * Naturally aligned pgds required by the architecture.
 	 */
-	pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
+	pgd_cache = kmem_cache_create("pgd_cache", pgd_size, pgd_size,
 				      SLAB_PANIC, NULL);
 }
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index b8edc5765441..51ed0e9d0a0d 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -197,10 +197,8 @@ SYM_FUNC_ALIAS(__pi_idmap_cpu_replace_ttbr1, idmap_cpu_replace_ttbr1)
 
 	.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
diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
index fd6bd69c5096..05034c0b8fd7 100644
--- a/scripts/gdb/linux/constants.py.in
+++ b/scripts/gdb/linux/constants.py.in
@@ -141,7 +141,6 @@ LX_CONFIG(CONFIG_ARM64_4K_PAGES)
 LX_CONFIG(CONFIG_ARM64_16K_PAGES)
 LX_CONFIG(CONFIG_ARM64_64K_PAGES)
 if IS_BUILTIN(CONFIG_ARM64):
-    LX_VALUE(CONFIG_ARM64_PA_BITS)
     LX_VALUE(CONFIG_ARM64_VA_BITS)
     LX_VALUE(CONFIG_PAGE_SHIFT)
     LX_VALUE(CONFIG_ARCH_FORCE_MAX_ORDER)
diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index cd8420e8c3ad..daeecb1a5366 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -574,12 +574,6 @@
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MIN		0x2
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX		0x7
 
-#ifdef CONFIG_ARM64_PA_BITS_52
-#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_52
-#else
-#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_48
-#endif
-
 #if defined(CONFIG_ARM64_4K_PAGES)
 #define ID_AA64MMFR0_EL1_TGRAN_SHIFT		ID_AA64MMFR0_EL1_TGRAN4_SHIFT
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN
-- 
2.47.1.613.gc27f4b7a9f-goog



From peng.fan at oss.nxp.com  Thu Dec 12 00:24:41 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 12 Dec 2024 16:24:41 +0800
Subject: [PATCH 1/2] dt-bindings: nvmem: imx-ocotp: Introduce
 #access-controller-cells
In-Reply-To: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>
References: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>
Message-ID: <20241212-imx-ocotp-v1-1-198bb0af86a0@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Introduce "#access-controller-cells" to make OCOTP be an accessing
controller, because i.MX Family OCOTP supports a specific peripheral
or function being fused which means being disabled.

Add the i.MX[95,93] OCOTP gate index.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/nvmem/imx-ocotp.yaml       |  5 +++
 include/dt-bindings/nvmem/fsl,imx93-ocotp.h        | 24 ++++++++++++
 include/dt-bindings/nvmem/fsl,imx95-ocotp.h        | 43 ++++++++++++++++++++++
 3 files changed, 72 insertions(+)

diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
index b2cb76cf9053a883a158acaf5eaa108895818afc..c78e202ced22f1c278f7be827b71ba434832d2a7 100644
--- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
+++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
@@ -54,6 +54,11 @@ properties:
   clocks:
     maxItems: 1
 
+  "#access-controller-cells":
+    const: 1
+    description:
+      Contains the gate ID associated to the peripheral.
+
 required:
   - "#address-cells"
   - "#size-cells"
diff --git a/include/dt-bindings/nvmem/fsl,imx93-ocotp.h b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ef525173845fd4ee0e847cf5a17e53a14f71362
--- /dev/null
+++ b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+#ifndef _DT_BINDINGS_NVMEM_IMX93_OTPC_H
+#define _DT_BINDINGS_NVMEM_IMX93_OTPC_H
+
+#define IMX93_OCOTP_NPU_GATE		0
+#define IMX93_OCOTP_A550_GATE		1
+#define IMX93_OCOTP_A551_GATE		2
+#define IMX93_OCOTP_M33_GATE		3
+#define IMX93_OCOTP_CAN1_FD_GATE	4
+#define IMX93_OCOTP_CAN2_FD_GATE	5
+#define IMX93_OCOTP_CAN1_GATE		6
+#define IMX93_OCOTP_CAN2_GATE		7
+#define IMX93_OCOTP_USB1_GATE		8
+#define IMX93_OCOTP_USB2_GATE		9
+#define IMX93_OCOTP_ENET1_GATE		10
+#define IMX93_OCOTP_ENET2_GATE		11
+#define IMX93_OCOTP_PXP_GATE		12
+#define IMX93_OCOTP_MIPI_CSI1_GATE	13
+#define IMX93_OCOTP_MIPI_DSI1_GATE	14
+#define IMX93_OCOTP_LVDS1_GATE		15
+#define IMX93_OCOTP_ADC1_GATE		16
+
+#endif
diff --git a/include/dt-bindings/nvmem/fsl,imx95-ocotp.h b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d21d1f690974d0215c71352168378a150f489af
--- /dev/null
+++ b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+#ifndef _DT_BINDINGS_NVMEM_IMX95_OTPC_H
+#define _DT_BINDINGS_NVMEM_IMX95_OTPC_H
+
+#define IMX95_OCOTP_CANFD1_GATE		0
+#define IMX95_OCOTP_CANFD2_GATE		1
+#define IMX95_OCOTP_CANFD3_GATE		2
+#define IMX95_OCOTP_CANFD4_GATE		3
+#define IMX95_OCOTP_CANFD5_GATE		4
+#define IMX95_OCOTP_CAN1_GATE		5
+#define IMX95_OCOTP_CAN2_GATE		6
+#define IMX95_OCOTP_CAN3_GATE		7
+#define IMX95_OCOTP_CAN4_GATE		8
+#define IMX95_OCOTP_CAN5_GATE		9
+#define IMX95_OCOTP_NPU_GATE		10
+#define IMX95_OCOTP_A550_GATE		11
+#define IMX95_OCOTP_A551_GATE		12
+#define IMX95_OCOTP_A552_GATE		13
+#define IMX95_OCOTP_A553_GATE		14
+#define IMX95_OCOTP_A554_GATE		15
+#define IMX95_OCOTP_A555_GATE		16
+#define IMX95_OCOTP_M7_GATE		17
+#define IMX95_OCOTP_DCSS_GATE		18
+#define IMX95_OCOTP_LVDS1_GATE		19
+#define IMX95_OCOTP_ISP_GATE		20
+#define IMX95_OCOTP_USB1_GATE		21
+#define IMX95_OCOTP_USB2_GATE		22
+#define IMX95_OCOTP_NETC_GATE		23
+#define IMX95_OCOTP_PCIE1_GATE		24
+#define IMX95_OCOTP_PCIE2_GATE		25
+#define IMX95_OCOTP_ADC1_GATE		26
+#define IMX95_OCOTP_EARC_RX_GATE	27
+#define IMX95_OCOTP_GPU3D_GATE		28
+#define IMX95_OCOTP_VPU_GATE		29
+#define IMX95_OCOTP_JPEG_ENC_GATE	30
+#define IMX95_OCOTP_JPEG_DEC_GATE	31
+#define IMX95_OCOTP_MIPI_CSI1_GATE	32
+#define IMX95_OCOTP_MIPI_CSI2_GATE	33
+#define IMX95_OCOTP_MIPI_DSI1_GATE	34
+#define IMX95_OCOTP_V2X_GATE		35
+
+#endif

-- 
2.37.1



From maz at kernel.org  Thu Dec 12 00:25:53 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Dec 2024 08:25:53 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <20241211160218.41404-3-miko.lenczewski@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
	<20241211160218.41404-3-miko.lenczewski@arm.com>
Message-ID: <87cyhxs3xq.wl-maz@kernel.org>

Ah, so this is where this is hiding. I missed it in my review of patch
#1 yesterday.

On Wed, 11 Dec 2024 16:01:38 +0000,
Miko?aj Lenczewski <miko.lenczewski at arm.com> wrote:
> 
> The Break-Before-Make cpu feature supports multiple levels (levels 0-2),
> and this commit adds a dedicated BBML2 cpufeature to test against
> support for.
> 
> In supporting BBM level 2, we open ourselves up to potential TLB
> Conflict Abort Exceptions during expected execution, instead of only
> in exceptional circumstances. In the case of an abort, it is
> implementation defined at what stage the abort is generated, and

*IF* stage-2 is enabled. Also, in the case of the EL2&0 translation
regime, no stage-2 applies, so it can only be a stage-1 abort.

> the minimal set of required invalidations is also implementation
> defined. The maximal set of invalidations is to do a `tlbi vmalle1`
> or `tlbi vmalls12e1`, depending on the stage.
> 
> Such aborts should not occur on Arm hardware, and were not seen in
> benchmarked systems, so unless performance concerns arise, implementing

Which systems? Given that you have deny-listed *all* half recent ARM
Ltd implementations, I'm a bit puzzled.

> the abort handlers with the worst-case invalidations seems like an
> alright hack.
> 
> Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
> ---
>  arch/arm64/include/asm/cpufeature.h | 14 ++++++++++++++
>  arch/arm64/kernel/cpufeature.c      |  7 +++++++
>  arch/arm64/mm/fault.c               | 27 ++++++++++++++++++++++++++-
>  arch/arm64/tools/cpucaps            |  1 +
>  4 files changed, 48 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 8b4e5a3cd24c..a9f2ac335392 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -866,6 +866,20 @@ static __always_inline bool system_supports_mpam_hcr(void)
>  	return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
>  }
>  
> +static inline bool system_supports_bbml2(void)
> +{
> +	/* currently, BBM is only relied on by code touching the userspace page
> +	 * tables, and as such we are guaranteed that caps have been finalised.
> +	 *
> +	 * if later we want to use BBM for kernel mappings, particularly early
> +	 * in the kernel, this may return 0 even if BBML2 is actually supported,
> +	 * which means unnecessary break-before-make sequences, but is still
> +	 * correct

Comment style, capitalisation, punctuation.

> +	 */
> +
> +	return alternative_has_cap_unlikely(ARM64_HAS_BBML2);
> +}
> +
>  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 6ce71f444ed8..7cc94bd5da24 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2917,6 +2917,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>  		.matches = has_cpuid_feature,
>  		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP)
>  	},
> +	{
> +		.desc = "BBM Level 2 Support",
> +		.capability = ARM64_HAS_BBML2,
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +		.matches = has_cpuid_feature,
> +		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, BBM, 2)
> +	},
>  	{
>  		.desc = "52-bit Virtual Addressing for KVM (LPA2)",
>  		.capability = ARM64_HAS_LPA2,
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index ef63651099a9..dc119358cbc1 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -844,6 +844,31 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
>  	return 0;
>  }
>  
> +static int do_conflict_abort(unsigned long far, unsigned long esr,
> +			     struct pt_regs *regs)
> +{
> +	if (!system_supports_bbml2())
> +		return do_bad(far, esr, regs);
> +
> +	/* if we receive a TLB conflict abort, we know that there are multiple
> +	 * TLB entries that translate the same address range. the minimum set
> +	 * of invalidations to clear these entries is implementation defined.
> +	 * the maximum set is defined as either tlbi(vmalls12e1) or tlbi(alle1).
> +	 *
> +	 * if el2 is enabled and stage 2 translation enabled, this may be
> +	 * raised as a stage 2 abort. if el2 is enabled but stage 2 translation
> +	 * disabled, or if el2 is disabled, it will be raised as a stage 1
> +	 * abort.
> +	 *
> +	 * local_flush_tlb_all() does a tlbi(vmalle1), which is enough to
> +	 * handle a stage 1 abort.

Same comment about comments.

> +	 */
> +
> +	local_flush_tlb_all();

The elephant in the room: if TLBs are in such a sorry state, what
guarantees we can make it this far?

I honestly don't think you can reliably handle a TLB Conflict abort in
the same translation regime as the original fault, given that we don't
know the scope of that fault. You are probably making an educated
guess that it is good enough on the CPUs you know of, but I don't see
anything in the architecture that indicates the "blast radius" of a
TLB conflict.

Which makes me think that your KVM patch is equally broken on nVHE and
hVHE. Such fault should probably be handled while at EL2, not after
returning to EL1.

Thanks,

	M.

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


From syzbot+67a9ec5b1706e0184581 at syzkaller.appspotmail.com  Thu Dec 12 00:48:18 2024
From: syzbot+67a9ec5b1706e0184581 at syzkaller.appspotmail.com (syzbot)
Date: Thu, 12 Dec 2024 00:48:18 -0800
Subject: [syzbot] [kvmarm?] BUG: unable to handle kernel paging request in __hwasan_check_x0_ADDR
Message-ID: <675aa352.050a0220.1ac542.0018.GAE@google.com>

Hello,

syzbot found the following issue on:

HEAD commit:    5db899a34f75 Merge remote-tracking branch 'kernel/kvmarm/n..
git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git fuzzme
console output: https://syzkaller.appspot.com/x/log.txt?x=16db78f8580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=fde68ab6d6c8c8ab
dashboard link: https://syzkaller.appspot.com/bug?extid=67a9ec5b1706e0184581
compiler:       Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
userspace arch: arm64

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/384ffdcca292/non_bootable_disk-5db899a3.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/4938b757ff4a/vmlinux-5db899a3.xz
kernel image: https://storage.googleapis.com/syzbot-assets/936938b47987/Image-5db899a3.gz.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+67a9ec5b1706e0184581 at syzkaller.appspotmail.com

Unable to handle kernel paging request at virtual address efff800000000137
KASAN: probably user-memory-access in range [0x0000000000001370-0x000000000000137f]
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
swapper pgtable: 4k pages, 52-bit VAs, pgdp=0000000044a53000
[efff800000000137] pgd=1000000049992003, p4d=1000000049993003, pud=0000000000000000
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 UID: 0 PID: 6560 Comm: syz.2.929 Not tainted 6.12.0-rc7-syzkaller-g5db899a34f75 #0
Hardware name: linux,dummy-virt (DT)
pstate: 80402009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : __hwasan_check_x0_67043363+0x4/0x30
lr : vgic_get_irq+0x7c/0x3d4 arch/arm64/kvm/vgic/vgic.c:93
sp : ffff80008c597650
x29: ffff80008c597660 x28: 00000000000000e0 x27: 0000000000000004
x26: 0000000000000002 x25: ffff800083a7fe20 x24: 16f0000014accd90
x23: 16f0000014acb9a0 x22: 0000000000000000 x21: a9ff80008c583000
x20: 0000000000000001 x19: efff800000000000 x18: 0000000000000005
x17: 0000000000000000 x16: 0000000000000137 x15: 0000000000000000
x14: 0000000000000002 x13: 0000000000000003 x12: 70f000000a33ba80
x11: 0000000000080000 x10: 0000000000001378 x9 : efff800000000000
x8 : 0000000000000001 x7 : 0000000000000001 x6 : 0000000000000001
x5 : ffff80008c597858 x4 : ffff8000800f2b38 x3 : ffff8000800f7a00
x2 : 0000000000000001 x1 : 0000000000000001 x0 : 0000000000001378
Call trace:
 __hwasan_check_x0_67043363+0x4/0x30
 vgic_mmio_write_invlpi+0xb0/0x174 arch/arm64/kvm/vgic/vgic-mmio-v3.c:546
 dispatch_mmio_write+0x2a4/0x308
 kvm_iodevice_write include/kvm/iodev.h:54 [inline]
 __kvm_io_bus_write+0x290/0x340 virt/kvm/kvm_main.c:5852
 kvm_io_bus_write+0x100/0x1bc virt/kvm/kvm_main.c:5877
 io_mem_abort+0x4b8/0x7a0 arch/arm64/kvm/mmio.c:204
 kvm_handle_guest_abort+0xb4c/0x1c64 arch/arm64/kvm/mmu.c:1880
 handle_trap_exceptions arch/arm64/kvm/handle_exit.c:351 [inline]
 handle_exit+0x1a0/0x274 arch/arm64/kvm/handle_exit.c:381
 kvm_arch_vcpu_ioctl_run+0xbc0/0x15b0 arch/arm64/kvm/arm.c:1279
 kvm_vcpu_ioctl+0x660/0xf78 virt/kvm/kvm_main.c:4475
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:907 [inline]
 __se_sys_ioctl fs/ioctl.c:893 [inline]
 __arm64_sys_ioctl+0x108/0x184 fs/ioctl.c:893
 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
 invoke_syscall+0x78/0x1b8 arch/arm64/kernel/syscall.c:49
 el0_svc_common+0xe8/0x1b0 arch/arm64/kernel/syscall.c:132
 do_el0_svc+0x40/0x50 arch/arm64/kernel/syscall.c:151
 el0_svc+0x54/0x14c arch/arm64/kernel/entry-common.c:712
 el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730
 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
Code: a90efbfd d2800441 143a3ed3 9344dc10 (38706930) 
---[ end trace 0000000000000000 ]---
----------------
Code disassembly (best guess):
   0:	a90efbfd 	stp	x29, x30, [sp, #232]
   4:	d2800441 	mov	x1, #0x22                  	// #34
   8:	143a3ed3 	b	0xe8fb54
   c:	9344dc10 	sbfx	x16, x0, #4, #52
* 10:	38706930 	ldrb	w16, [x9, x16] <-- trapping instruction


---
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 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 maz at kernel.org  Thu Dec 12 00:50:12 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Dec 2024 08:50:12 +0000
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <c197264b-3791-493a-b717-3dfd844de922@quicinc.com>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
	<87ed2fs03w.wl-maz@kernel.org>
	<92cee905-a505-4ce9-9bbc-6fba4cea1d80@quicinc.com>
	<86sequsdtp.wl-maz@kernel.org>
	<c197264b-3791-493a-b717-3dfd844de922@quicinc.com>
Message-ID: <87bjxhs2t7.wl-maz@kernel.org>

On Thu, 12 Dec 2024 05:31:00 +0000,
Pavan Kondeti <quic_pkondeti at quicinc.com> wrote:
> 
> On Wed, Dec 11, 2024 at 10:40:02AM +0000, Marc Zyngier wrote:
> > On Wed, 11 Dec 2024 00:37:34 +0000,
> > Pavan Kondeti <quic_pkondeti at quicinc.com> wrote:
> > > 
> > > On Tue, Dec 10, 2024 at 09:24:03PM +0000, Marc Zyngier wrote:
> > > > > +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> > > > > +{
> > > > > +	int ret;
> > > > > +
> > > > > +#ifdef CONFIG_ARM64
> > > > > +	/*
> > > > > +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> > > > > +	 * to switch the secure mode to avoid the dependency on zap shader.
> > > > > +	 */
> > > > > +	if (is_kernel_in_hyp_mode())
> > > > > +		goto direct_switch;
> > > > 
> > > > No, please. To check whether you are *booted* at EL2, you need to
> > > > check for is_hyp_available(). Whether the kernel runs at EL1 or EL2 is
> > > > none of the driver's business, really. This is still absolutely
> > > > disgusting from an abstraction perspective, but I guess we don't have
> > > > much choice here.
> > > > 
> > > 
> > > Thanks Marc. Any suggestions on how we can make is_hyp_mode_available()
> > > available for modules? Do you prefer exporting
> > > kvm_protected_mode_initialized and __boot_cpu_mode symbols directly or
> > > try something like [1]?
> > 
> > Ideally, neither. These were bad ideas nine years ago, and they still
> > are. The least ugly hack I can come up with is the patch below, and
> > you'd write something like:
> > 
> > 	if (cpus_have_cap(ARM64_HAS_EL2_OWNERSHIP))
> > 		blah();
> > 
> > This is obviously completely untested.
> > 
> 
> I have tested your patch. It works as intended. Thanks Marc.

Note that you will probably get some push-back from the arm64
maintainers on this front, because this is a fairly incomplete (and
fragile) solution.

It would be much better if the discriminant came from the device tree.
After all, the hypervisor is fscking-up^W^Wchanging the programming
model of the GPU, and that should be reflected in the DT. Because for
all intent and purposes, this is not the same hardware anymore.

The GPU isn't the only device that needs fixing in that way: the
SMMUv3 needs to be exposed to the OS, and the PCIe ports need to be
linked to it and the ITS. So at the end of the day, detecting EL2 only
serves a limited purpose. You need to handle these cases, and might as
well put the GPU in the same bag.

Which means that you'd either have a pair of static DTs (one that
exposes the brokenness of the firmware, and one that doesn't), or you
go the dtbhack route to compose the DT at boot time.

Thanks,

	M.

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


From damon.ding at rock-chips.com  Thu Dec 12 00:55:19 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 12 Dec 2024 16:55:19 +0800
Subject: [PATCH v1 06/10] drm/bridge: analogix_dp: Add support for phy
 configuration.
In-Reply-To: <twhosvpoyafo472gqsblpvxmuewe2lkqufxabp2q7o636uinfm@unzyfv2pchqn>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <20241127075157.856029-7-damon.ding@rock-chips.com>
 <twhosvpoyafo472gqsblpvxmuewe2lkqufxabp2q7o636uinfm@unzyfv2pchqn>
Message-ID: <f6fd6efe-73bb-4aa2-a075-9a03c39951df@rock-chips.com>

Hi Dmitry,

On 2024/11/30 16:53, Dmitry Baryshkov wrote:
> On Wed, Nov 27, 2024 at 03:51:53PM +0800, Damon Ding wrote:
>> Add support to configurate link rate, lane count, voltage swing and
>> pre-emphasis with phy_configure(). It is helpful in application scenarios
>> where analogix controller is mixed with the phy of other vendors.
>>
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>> ---
>>   .../drm/bridge/analogix/analogix_dp_core.c    |  4 +-
>>   .../drm/bridge/analogix/analogix_dp_core.h    |  2 +
>>   .../gpu/drm/bridge/analogix/analogix_dp_reg.c | 90 +++++++++++++++++++
>>   3 files changed, 94 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> index 6f10d88a34c5..7624ed13cdbf 100644
>> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> @@ -1672,7 +1672,7 @@ EXPORT_SYMBOL_GPL(analogix_dp_probe);
>>   
>>   int analogix_dp_suspend(struct analogix_dp_device *dp)
>>   {
>> -	phy_power_off(dp->phy);
>> +	analogix_dp_phy_power_off(dp);
> 
> Why?
> 
>>   
>>   	if (dp->plat_data->power_off)
>>   		dp->plat_data->power_off(dp->plat_data);
>> @@ -1696,7 +1696,7 @@ int analogix_dp_resume(struct analogix_dp_device *dp)
>>   	if (dp->plat_data->power_on)
>>   		dp->plat_data->power_on(dp->plat_data);
>>   
>> -	phy_power_on(dp->phy);
>> +	analogix_dp_phy_power_on(dp);
> 
> Why?
> 

These changes for phy_power_on()/phy_power_off() may be unnecessary. I 
will just put the phy_set_mode() before phy_power_on() in next version.

>>   
>>   	analogix_dp_init_dp(dp);
>>   
>> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
>> index 774d11574b09..a76079d61768 100644
>> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
>> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
>> @@ -232,5 +232,7 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
>>   			     struct dp_sdp *vsc, bool blocking);
>>   ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
>>   			     struct drm_dp_aux_msg *msg);
>> +void analogix_dp_phy_power_on(struct analogix_dp_device *dp);
>> +void analogix_dp_phy_power_off(struct analogix_dp_device *dp);
>>   
>>   #endif /* _ANALOGIX_DP_CORE_H */
>> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
>> index 3afc73c858c4..809bb0c72d18 100644
>> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
>> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
>> @@ -11,6 +11,7 @@
>>   #include <linux/gpio/consumer.h>
>>   #include <linux/io.h>
>>   #include <linux/iopoll.h>
>> +#include <linux/phy/phy.h>
>>   
>>   #include <drm/bridge/analogix_dp.h>
>>   
>> @@ -513,10 +514,27 @@ void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
>>   void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
>>   {
>>   	u32 reg;
>> +	int ret;
>>   
>>   	reg = bwtype;
>>   	if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
>>   		writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
>> +
>> +	if (dp->phy) {
>> +		union phy_configure_opts phy_cfg = {0};
>> +
>> +		phy_cfg.dp.lanes = dp->link_train.lane_count;
> 
> You can drop this, .set_lanes is false.
> 
>> +		phy_cfg.dp.link_rate =
>> +			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
>> +		phy_cfg.dp.set_lanes = false;
>> +		phy_cfg.dp.set_rate = true;
>> +		phy_cfg.dp.set_voltages = false;
> 
> You don't need to set those to false, it's cleared by = {0};
> 
>> +		ret = phy_configure(dp->phy, &phy_cfg);
>> +		if (ret && ret != -EOPNOTSUPP) {
>> +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
>> +			return;
>> +		}
>> +	}
>>   }
>>   
>>   void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
>> @@ -530,9 +548,24 @@ void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
>>   void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
>>   {
>>   	u32 reg;
>> +	int ret;
>>   
>>   	reg = count;
>>   	writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
>> +
>> +	if (dp->phy) {
>> +		union phy_configure_opts phy_cfg = {0};
>> +
>> +		phy_cfg.dp.lanes = dp->link_train.lane_count;
>> +		phy_cfg.dp.set_lanes = true;
>> +		phy_cfg.dp.set_rate = false;
>> +		phy_cfg.dp.set_voltages = false;
> 
> Likewise
> 
>> +		ret = phy_configure(dp->phy, &phy_cfg);
>> +		if (ret && ret != -EOPNOTSUPP) {
>> +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
>> +			return;
>> +		}
>> +	}
>>   }
>>   
>>   void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
>> @@ -546,10 +579,39 @@ void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
>>   void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp)
>>   {
>>   	u8 lane;
>> +	int ret;
>>   
>>   	for (lane = 0; lane < dp->link_train.lane_count; lane++)
>>   		writel(dp->link_train.training_lane[lane],
>>   		       dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane);
>> +
>> +	if (dp->phy) {
>> +		union phy_configure_opts phy_cfg = {0};
>> +
>> +		for (lane = 0; lane < dp->link_train.lane_count; lane++) {
>> +			u8 training_lane = dp->link_train.training_lane[lane];
>> +			u8 vs, pe;
>> +
>> +			vs = (training_lane & DP_TRAIN_VOLTAGE_SWING_MASK) >>
>> +			     DP_TRAIN_VOLTAGE_SWING_SHIFT;
>> +			pe = (training_lane & DP_TRAIN_PRE_EMPHASIS_MASK) >>
>> +			     DP_TRAIN_PRE_EMPHASIS_SHIFT;
>> +			phy_cfg.dp.voltage[lane] = vs;
>> +			phy_cfg.dp.pre[lane] = pe;
>> +		}
>> +
>> +		phy_cfg.dp.lanes = dp->link_train.lane_count;
>> +		phy_cfg.dp.link_rate =
>> +			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
> 
> You can drop these two.

Indeed, all the needless assignments for phy_configure() will be deleted 
in next version.

> 
>> +		phy_cfg.dp.set_lanes = false;
>> +		phy_cfg.dp.set_rate = false;
>> +		phy_cfg.dp.set_voltages = true;
>> +		ret = phy_configure(dp->phy, &phy_cfg);
>> +		if (ret && ret != -EOPNOTSUPP) {
>> +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
>> +			return;
>> +		}
>> +	}
>>   }
>>   
>>   u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane)
>> @@ -1053,3 +1115,31 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
>>   
>>   	return -EREMOTEIO;
>>   }
>> +
>> +void analogix_dp_phy_power_on(struct analogix_dp_device *dp)
>> +{
>> +	int ret;
>> +
>> +	ret = phy_set_mode(dp->phy, PHY_MODE_DP);
>> +	if (ret) {
>> +		dev_err(dp->dev, "%s: phy_set_mode() failed: %d\n", __func__, ret);
>> +		return;
>> +	}
>> +
>> +	ret = phy_power_on(dp->phy);
>> +	if (ret) {
>> +		dev_err(dp->dev, "%s: phy_power_on() failed: %d\n", __func__, ret);
> 
> There is already a dev_err() call in phy_power_on().
> 
>> +		return;
>> +	}
>> +}
>> +
>> +void analogix_dp_phy_power_off(struct analogix_dp_device *dp)
>> +{
>> +	int ret;
>> +
>> +	ret = phy_power_off(dp->phy);
>> +	if (ret) {
>> +		dev_err(dp->dev, "%s: phy_power_off() failed: %d\n", __func__, ret);
> 
> There is already a dev_err() call in phy_power_off().
> 
>> +		return;
>> +	}
>> +}
>> -- 
>> 2.34.1
>>
>>
>> _______________________________________________
>> Linux-rockchip mailing list
>> Linux-rockchip at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-rockchip
> 

Best regards,
Damon



From alain.volmat at foss.st.com  Thu Dec 12 01:09:19 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:09:19 +0100
Subject: [PATCH v3 13/15] media: stm32: dcmipp: add core support for the
 stm32mp25
In-Reply-To: <832ee6b4-8238-4ef6-b870-f541b744880b@xs4all.nl>
References: <20241118-csi_dcmipp_mp25-v3-0-c1914afb0a0f@foss.st.com>
 <20241118-csi_dcmipp_mp25-v3-13-c1914afb0a0f@foss.st.com>
 <832ee6b4-8238-4ef6-b870-f541b744880b@xs4all.nl>
Message-ID: <20241212090919.GA3572448@gnbcxd0016.gnb.st.com>

Hi Hans,

On Tue, Dec 03, 2024 at 10:07:31AM +0100, Hans Verkuil wrote:
> Hi Alain,
> 
> On 18/11/2024 14:35, Alain Volmat wrote:
> > The stm32mp25 supports both parallel & csi inputs.
> > An additional clock control is necessary.
> > Skeleton of the subdev structures for the stm32mp25 is added,
> > identical for the time being to the stm32mp13 however more subdeves
> > will be added in further commits.
> > 
> > Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> > ---
> >  .../platform/st/stm32/stm32-dcmipp/dcmipp-core.c   | 98 ++++++++++++++++++----
> >  1 file changed, 80 insertions(+), 18 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 d2cc19bb40d77f67a1f5fe565bc62f45eff2d266..0087f9017f024ba6b918b99c1ef39212ad6b881a 100644
> > --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
> > +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
> > @@ -40,6 +40,7 @@ struct dcmipp_device {
> >  
> >  	/* Hardware resources */
> >  	void __iomem			*regs;
> > +	struct clk			*mclk;
> >  	struct clk			*kclk;
> >  
> >  	/* The pipeline configuration */
> > @@ -132,6 +133,40 @@ static const struct dcmipp_pipeline_config stm32mp13_pipe_cfg = {
> >  	.hw_revision	= DCMIPP_STM32MP13_VERR
> >  };
> >  
> > +static const struct dcmipp_ent_config stm32mp25_ent_config[] = {
> > +	{
> > +		.name = "dcmipp_input",
> > +		.init = dcmipp_inp_ent_init,
> > +		.release = dcmipp_inp_ent_release,
> > +	},
> > +	{
> > +		.name = "dcmipp_dump_postproc",
> > +		.init = dcmipp_byteproc_ent_init,
> > +		.release = dcmipp_byteproc_ent_release,
> > +	},
> > +	{
> > +		.name = "dcmipp_dump_capture",
> > +		.init = dcmipp_bytecap_ent_init,
> > +		.release = dcmipp_bytecap_ent_release,
> > +	},
> > +};
> > +
> > +static const struct dcmipp_ent_link stm32mp25_ent_links[] = {
> > +	DCMIPP_ENT_LINK(ID_INPUT, 1, ID_DUMP_BYTEPROC, 0,
> > +			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
> > +	DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE,  0,
> > +			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
> > +};
> > +
> > +#define DCMIPP_STM32MP25_VERR  0x30
> > +static const struct dcmipp_pipeline_config stm32mp25_pipe_cfg = {
> > +	.ents		= stm32mp25_ent_config,
> > +	.num_ents	= ARRAY_SIZE(stm32mp25_ent_config),
> > +	.links		= stm32mp25_ent_links,
> > +	.num_links	= ARRAY_SIZE(stm32mp25_ent_links),
> > +	.hw_revision    = DCMIPP_STM32MP25_VERR
> > +};
> > +
> >  #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\
> >  			     (f) == MEDIA_LNK_FL_ENABLED ? "ENABLED" :\
> >  			     (f) == MEDIA_LNK_FL_IMMUTABLE ? "IMMUTABLE" :\
> > @@ -212,6 +247,7 @@ static int dcmipp_create_subdevs(struct dcmipp_device *dcmipp)
> >  
> >  static const struct of_device_id dcmipp_of_match[] = {
> >  	{ .compatible = "st,stm32mp13-dcmipp", .data = &stm32mp13_pipe_cfg },
> > +	{ .compatible = "st,stm32mp25-dcmipp", .data = &stm32mp25_pipe_cfg },
> >  	{ /* end node */ },
> >  };
> >  MODULE_DEVICE_TABLE(of, dcmipp_of_match);
> > @@ -261,13 +297,22 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
> >  {
> >  	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
> >  	unsigned int ret;
> > -	int src_pad;
> > +	int src_pad, i;
> >  	struct dcmipp_ent_device *sink;
> > -	struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL };
> > +	struct v4l2_fwnode_endpoint vep = { 0 };
> >  	struct fwnode_handle *ep;
> > +	enum v4l2_mbus_type supported_types[] = {
> > +		V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, V4L2_MBUS_CSI2_DPHY
> > +	};
> > +	int supported_types_nb = ARRAY_SIZE(supported_types);
> >  
> >  	dev_dbg(dcmipp->dev, "Subdev \"%s\" bound\n", subdev->name);
> >  
> > +	/* Only MP25 supports CSI input */
> > +	if (!of_device_is_compatible(dcmipp->dev->of_node,
> > +				     "st,stm32mp25-dcmipp"))
> > +		supported_types_nb--;
> > +
> >  	/*
> >  	 * Link this sub-device to DCMIPP, it could be
> >  	 * a parallel camera sensor or a CSI-2 to parallel bridge
> > @@ -284,21 +329,23 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
> >  		return -ENODEV;
> >  	}
> >  
> > -	/* Check for parallel bus-type first, then bt656 */
> > -	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> > -	if (ret) {
> > -		vep.bus_type = V4L2_MBUS_BT656;
> > +	/* Check for supported MBUS type */
> > +	for (i = 0; i < supported_types_nb; i++) {
> > +		vep.bus_type = supported_types[i];
> >  		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> > -		if (ret) {
> > -			dev_err(dcmipp->dev, "Could not parse the endpoint\n");
> > -			fwnode_handle_put(ep);
> > -			return ret;
> > -		}
> > +		if (!ret)
> > +			break;
> >  	}
> >  
> >  	fwnode_handle_put(ep);
> >  
> > -	if (vep.bus.parallel.bus_width == 0) {
> > +	if (ret) {
> > +		dev_err(dcmipp->dev, "Could not parse the endpoint\n");
> > +		return ret;
> > +	}
> > +
> > +	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY &&
> > +	    vep.bus.parallel.bus_width == 0) {
> >  		dev_err(dcmipp->dev, "Invalid parallel interface bus-width\n");
> >  		return -ENODEV;
> >  	}
> > @@ -311,11 +358,13 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
> >  		return -ENODEV;
> >  	}
> >  
> > -	/* Parallel input device detected, connect it to parallel subdev */
> > +	/* Connect input device to the dcmipp_input subdev */
> >  	sink = dcmipp->entity[ID_INPUT];
> > -	sink->bus.flags = vep.bus.parallel.flags;
> > -	sink->bus.bus_width = vep.bus.parallel.bus_width;
> > -	sink->bus.data_shift = vep.bus.parallel.data_shift;
> > +	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) {
> > +		sink->bus.flags = vep.bus.parallel.flags;
> > +		sink->bus.bus_width = vep.bus.parallel.bus_width;
> > +		sink->bus.data_shift = vep.bus.parallel.data_shift;
> > +	}
> >  	sink->bus_type = vep.bus_type;
> >  	ret = media_create_pad_link(&subdev->entity, src_pad, sink->ent, 0,
> >  				    MEDIA_LNK_FL_IMMUTABLE |
> > @@ -414,7 +463,7 @@ static int dcmipp_graph_init(struct dcmipp_device *dcmipp)
> >  static int dcmipp_probe(struct platform_device *pdev)
> >  {
> >  	struct dcmipp_device *dcmipp;
> > -	struct clk *kclk;
> > +	struct clk *kclk, *mclk;
> >  	const struct dcmipp_pipeline_config *pipe_cfg;
> >  	struct reset_control *rstc;
> >  	int irq;
> > @@ -474,12 +523,20 @@ static int dcmipp_probe(struct platform_device *pdev)
> >  		return ret;
> >  	}
> >  
> > -	kclk = devm_clk_get(&pdev->dev, NULL);
> > +	kclk = devm_clk_get(&pdev->dev, "kclk");
> >  	if (IS_ERR(kclk))
> >  		return dev_err_probe(&pdev->dev, PTR_ERR(kclk),
> >  				     "Unable to get kclk\n");
> >  	dcmipp->kclk = kclk;
> >  
> > +	if (!of_device_is_compatible(pdev->dev.of_node, "st,stm32mp13-dcmipp")) {
> > +		mclk = devm_clk_get(&pdev->dev, "mclk");
> > +		if (IS_ERR(mclk))
> > +			return dev_err_probe(&pdev->dev, PTR_ERR(mclk),
> > +					     "Unable to get mclk\n");
> > +		dcmipp->mclk = mclk;
> > +	}
> > +
> >  	dcmipp->entity = devm_kcalloc(&pdev->dev, dcmipp->pipe_cfg->num_ents,
> >  				      sizeof(*dcmipp->entity), GFP_KERNEL);
> >  	if (!dcmipp->entity)
> > @@ -542,6 +599,7 @@ static int dcmipp_runtime_suspend(struct device *dev)
> >  	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
> >  
> >  	clk_disable_unprepare(dcmipp->kclk);
> > +	clk_disable_unprepare(dcmipp->mclk);
> >  
> >  	return 0;
> >  }
> > @@ -551,6 +609,10 @@ static int dcmipp_runtime_resume(struct device *dev)
> >  	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
> >  	int ret;
> >  
> > +	ret = clk_prepare_enable(dcmipp->mclk);
> > +	if (ret)
> > +		dev_err(dev, "%s: Failed to prepare_enable mclk\n", __func__);
> > +
> 
> Shouldn't this return on error?

Yes indeed.

> 
> >  	ret = clk_prepare_enable(dcmipp->kclk);
> >  	if (ret)
> >  		dev_err(dev, "%s: Failed to prepare_enable kclk\n", __func__);
> 
> And on error here, it should call clk_disable_unprepare for mclk.

Ok.
> 
> > 
> 
> This was reported by smatch:
> 
> .../dcmipp-core.c:620 dcmipp_runtime_resume() warn: 'dcmipp->mclk' from clk_prepare_enable() not released on lines: 620.
> 
> Everything else in this series looks good to me, so you can either post a fix for this
> and I will fold it into this 13/15 patch, or you post an updated v3.1 13/15 patch.
> Or of course a v4, if you prefer.

I prepared a v4 with this fix in the 13/15 (that's the only difference
between the v3 and the v4). Will post it right away.

Regards,
Alain

> 
> Regards,
> 
> 	Hans


From michal.swiatkowski at linux.intel.com  Thu Dec 12 01:08:49 2024
From: michal.swiatkowski at linux.intel.com (Michal Swiatkowski)
Date: Thu, 12 Dec 2024 10:08:49 +0100
Subject: [PATCH net-next v1] net: stmmac: Drop redundant dwxgmac_tc_ops
 variable
In-Reply-To: <20241212033325.282817-1-0x1207@gmail.com>
References: <20241212033325.282817-1-0x1207@gmail.com>
Message-ID: <Z1qoITwRF9QLkZq/@mev-dev.igk.intel.com>

On Thu, Dec 12, 2024 at 11:33:25AM +0800, Furong Xu wrote:
> dwmac510_tc_ops and dwxgmac_tc_ops are completely identical,
> keep dwmac510_tc_ops to provide better backward compatibility.
> 
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/hwif.c      |  4 ++--
>  drivers/net/ethernet/stmicro/stmmac/hwif.h      |  1 -
>  drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 11 -----------
>  3 files changed, 2 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
> index 4bd79de2e222..31bdbab9a46c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
> @@ -267,7 +267,7 @@ static const struct stmmac_hwif_entry {
>  		.hwtimestamp = &stmmac_ptp,
>  		.ptp = &stmmac_ptp_clock_ops,
>  		.mode = NULL,
> -		.tc = &dwxgmac_tc_ops,
> +		.tc = &dwmac510_tc_ops,
>  		.mmc = &dwxgmac_mmc_ops,
>  		.est = &dwmac510_est_ops,
>  		.setup = dwxgmac2_setup,
> @@ -290,7 +290,7 @@ static const struct stmmac_hwif_entry {
>  		.hwtimestamp = &stmmac_ptp,
>  		.ptp = &stmmac_ptp_clock_ops,
>  		.mode = NULL,
> -		.tc = &dwxgmac_tc_ops,
> +		.tc = &dwmac510_tc_ops,
>  		.mmc = &dwxgmac_mmc_ops,
>  		.est = &dwmac510_est_ops,
>  		.setup = dwxlgmac2_setup,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
> index e428c82b7d31..2f7295b6c1c5 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
> @@ -685,7 +685,6 @@ extern const struct stmmac_dma_ops dwmac410_dma_ops;
>  extern const struct stmmac_ops dwmac510_ops;
>  extern const struct stmmac_tc_ops dwmac4_tc_ops;
>  extern const struct stmmac_tc_ops dwmac510_tc_ops;
> -extern const struct stmmac_tc_ops dwxgmac_tc_ops;
>  
>  #define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
>  #define GMAC4_VERSION		0x00000110	/* GMAC4+ CORE Version */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
> index 6a79e6a111ed..694d6ee14381 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
> @@ -1284,14 +1284,3 @@ const struct stmmac_tc_ops dwmac510_tc_ops = {
>  	.query_caps = tc_query_caps,
>  	.setup_mqprio = tc_setup_dwmac510_mqprio,
>  };
> -
> -const struct stmmac_tc_ops dwxgmac_tc_ops = {
> -	.init = tc_init,
> -	.setup_cls_u32 = tc_setup_cls_u32,
> -	.setup_cbs = tc_setup_cbs,
> -	.setup_cls = tc_setup_cls,
> -	.setup_taprio = tc_setup_taprio,
> -	.setup_etf = tc_setup_etf,
> -	.query_caps = tc_query_caps,
> -	.setup_mqprio = tc_setup_dwmac510_mqprio,
> -};

LGTM
Reviewed-by: Michal Swiatkowski <michal.swiatkowski at linux.intel.com>

Thanks
> -- 
> 2.34.1


From alain.volmat at foss.st.com  Thu Dec 12 01:17:33 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:33 +0100
Subject: [PATCH v4 09/15] media: stm32: dcmipp: add 1X16 RGB / YUV formats
 support
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-9-fbeb55a05ed7@foss.st.com>

Add 1X16 RGB & YUV formats support within bytecap & byteproc.
Slightly change the link_validate function to be able to validate
against either 1X16 or 2X8 variant of a format.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 .../st/stm32/stm32-dcmipp/dcmipp-bytecap.c         | 23 ++++++++++++++++------
 .../st/stm32/stm32-dcmipp/dcmipp-byteproc.c        |  5 +++++
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
index 6596902a1760..da80e1aa37ca 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
@@ -56,10 +56,15 @@ struct dcmipp_bytecap_pix_map {
 
 static const struct dcmipp_bytecap_pix_map dcmipp_bytecap_pix_map_list[] = {
 	PIXMAP_MBUS_PFMT(RGB565_2X8_LE, RGB565),
+	PIXMAP_MBUS_PFMT(RGB565_1X16, RGB565),
 	PIXMAP_MBUS_PFMT(YUYV8_2X8, YUYV),
+	PIXMAP_MBUS_PFMT(YUYV8_1X16, YUYV),
 	PIXMAP_MBUS_PFMT(YVYU8_2X8, YVYU),
+	PIXMAP_MBUS_PFMT(YVYU8_1X16, YVYU),
 	PIXMAP_MBUS_PFMT(UYVY8_2X8, UYVY),
+	PIXMAP_MBUS_PFMT(UYVY8_1X16, UYVY),
 	PIXMAP_MBUS_PFMT(VYUY8_2X8, VYUY),
+	PIXMAP_MBUS_PFMT(VYUY8_1X16, VYUY),
 	PIXMAP_MBUS_PFMT(Y8_1X8, GREY),
 	PIXMAP_MBUS_PFMT(SBGGR8_1X8, SBGGR8),
 	PIXMAP_MBUS_PFMT(SGBRG8_1X8, SGBRG8),
@@ -813,8 +818,7 @@ static int dcmipp_bytecap_link_validate(struct media_link *link)
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 		.pad = link->source->index,
 	};
-	const struct dcmipp_bytecap_pix_map *vpix;
-	int ret;
+	int ret, i;
 
 	ret = v4l2_subdev_call(source_sd, pad, get_fmt, NULL, &source_fmt);
 	if (ret < 0)
@@ -828,10 +832,17 @@ static int dcmipp_bytecap_link_validate(struct media_link *link)
 		return -EINVAL;
 	}
 
-	vpix = dcmipp_bytecap_pix_map_by_pixelformat(vcap->format.pixelformat);
-	if (source_fmt.format.code != vpix->code) {
-		dev_err(vcap->dev, "Wrong mbus_code 0x%x, (0x%x expected)\n",
-			vpix->code, source_fmt.format.code);
+	for (i = 0; i < ARRAY_SIZE(dcmipp_bytecap_pix_map_list); i++) {
+		if (dcmipp_bytecap_pix_map_list[i].pixelformat ==
+			vcap->format.pixelformat &&
+		    dcmipp_bytecap_pix_map_list[i].code ==
+			source_fmt.format.code)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(dcmipp_bytecap_pix_map_list)) {
+		dev_err(vcap->dev, "mbus code 0x%x do not match capture device format (0x%x)\n",
+			vcap->format.pixelformat, source_fmt.format.code);
 		return -EINVAL;
 	}
 
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
index 72f1bb4c64ad..3c742a546441 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
@@ -48,10 +48,15 @@ struct dcmipp_byteproc_pix_map {
 	}
 static const struct dcmipp_byteproc_pix_map dcmipp_byteproc_pix_map_list[] = {
 	PIXMAP_MBUS_BPP(RGB565_2X8_LE, 2),
+	PIXMAP_MBUS_BPP(RGB565_1X16, 2),
 	PIXMAP_MBUS_BPP(YUYV8_2X8, 2),
+	PIXMAP_MBUS_BPP(YUYV8_1X16, 2),
 	PIXMAP_MBUS_BPP(YVYU8_2X8, 2),
+	PIXMAP_MBUS_BPP(YVYU8_1X16, 2),
 	PIXMAP_MBUS_BPP(UYVY8_2X8, 2),
+	PIXMAP_MBUS_BPP(UYVY8_1X16, 2),
 	PIXMAP_MBUS_BPP(VYUY8_2X8, 2),
+	PIXMAP_MBUS_BPP(VYUY8_1X16, 2),
 	PIXMAP_MBUS_BPP(Y8_1X8, 1),
 	PIXMAP_MBUS_BPP(SBGGR8_1X8, 1),
 	PIXMAP_MBUS_BPP(SGBRG8_1X8, 1),

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:38 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:38 +0100
Subject: [PATCH v4 14/15] arm64: dts: st: add csi & dcmipp node in
 stm32mp25
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-14-fbeb55a05ed7@foss.st.com>

Add nodes describing the csi and dcmipp controllers handling the
camera pipeline on the stm32mp25x.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 6fe12e3bd7dd..0176ccafa03f 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -603,6 +603,29 @@ i2c8: i2c at 46040000 {
 				status = "disabled";
 			};
 
+			csi: csi at 48020000 {
+				compatible = "st,stm32mp25-csi";
+				reg = <0x48020000 0x2000>;
+				interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+				resets = <&rcc CSI_R>;
+				clocks = <&rcc CK_KER_CSI>, <&rcc CK_KER_CSITXESC>,
+					 <&rcc CK_KER_CSIPHY>;
+				clock-names = "pclk", "txesc", "csi2phy";
+				access-controllers = <&rifsc 86>;
+				status = "disabled";
+			};
+
+			dcmipp: dcmipp at 48030000 {
+				compatible = "st,stm32mp25-dcmipp";
+				reg = <0x48030000 0x1000>;
+				interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
+				resets = <&rcc DCMIPP_R>;
+				clocks = <&rcc CK_BUS_DCMIPP>, <&rcc CK_KER_CSI>;
+				clock-names = "kclk", "mclk";
+				access-controllers = <&rifsc 87>;
+				status = "disabled";
+			};
+
 			sdmmc1: mmc at 48220000 {
 				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
 				arm,primecell-periphid = <0x00353180>;

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:34 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:34 +0100
Subject: [PATCH v4 10/15] media: stm32: dcmipp: avoid duplicated format on
 enum in bytecap
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-10-fbeb55a05ed7@foss.st.com>

Avoid duplication of enumerated pixelformat on the bytecap
video capture device.  Indeed, since the bytecap format list
contains both CSI & parallel 16bits formats, ensure that same
pixelformat are not reported twice when performing enumeration
of supported formats.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 .../st/stm32/stm32-dcmipp/dcmipp-bytecap.c         | 42 +++++++++++-----------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
index da80e1aa37ca..1c1b6b48918e 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
@@ -268,34 +268,34 @@ static int dcmipp_bytecap_enum_fmt_vid_cap(struct file *file, void *priv,
 {
 	const struct dcmipp_bytecap_pix_map *vpix;
 	unsigned int index = f->index;
-	unsigned int i;
+	unsigned int i, prev_pixelformat = 0;
 
-	if (f->mbus_code) {
-		/*
-		 * If a media bus code is specified, only enumerate formats
-		 * compatible with it.
-		 */
-		for (i = 0; i < ARRAY_SIZE(dcmipp_bytecap_pix_map_list); i++) {
-			vpix = &dcmipp_bytecap_pix_map_list[i];
-			if (vpix->code != f->mbus_code)
-				continue;
+	/*
+	 * List up all formats (or only ones matching f->mbus_code), taking
+	 * care of removing duplicated entries (due to support of both
+	 * parallel & csi 16 bits formats
+	 */
+	for (i = 0; i < ARRAY_SIZE(dcmipp_bytecap_pix_map_list); i++) {
+		vpix = &dcmipp_bytecap_pix_map_list[i];
+		/* Skip formats not matching requested mbus code */
+		if (f->mbus_code && vpix->code != f->mbus_code)
+			continue;
 
-			if (index == 0)
-				break;
+		/* Skip duplicated pixelformat */
+		if (vpix->pixelformat == prev_pixelformat)
+			continue;
 
-			index--;
-		}
+		prev_pixelformat = vpix->pixelformat;
 
-		if (i == ARRAY_SIZE(dcmipp_bytecap_pix_map_list))
-			return -EINVAL;
-	} else {
-		/* Otherwise, enumerate all formats. */
-		if (f->index >= ARRAY_SIZE(dcmipp_bytecap_pix_map_list))
-			return -EINVAL;
+		if (index == 0)
+			break;
 
-		vpix = &dcmipp_bytecap_pix_map_list[f->index];
+		index--;
 	}
 
+	if (i == ARRAY_SIZE(dcmipp_bytecap_pix_map_list))
+		return -EINVAL;
+
 	f->pixelformat = vpix->pixelformat;
 
 	return 0;

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:39 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:39 +0100
Subject: [PATCH v4 15/15] arm64: dts: st: enable imx335/csi/dcmipp pipeline
 on stm32mp257f-ev1
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-15-fbeb55a05ed7@foss.st.com>

Enable the camera pipeline with a imx335 sensor connected to the
dcmipp via the csi interface.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>

---

v2:
  - correct regulators & camera node names
  - removal of powerdown property within imx335 node
  - removal of useless status property within imx335 node
  - correct imx335 reset-gpio polarity
---
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 85 ++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index 6f393b082789..a6a57cbcf730 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -27,6 +27,38 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
+	clocks {
+		clk_ext_camera: clk-ext-camera {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	imx335_2v9: regulator-2v9 {
+		compatible = "regulator-fixed";
+		regulator-name = "imx335-avdd";
+		regulator-min-microvolt = <2900000>;
+		regulator-max-microvolt = <2900000>;
+		regulator-always-on;
+	};
+
+	imx335_1v8: regulator-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "imx335-ovdd";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+	};
+
+	imx335_1v2: regulator-1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "imx335-dvdd";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-always-on;
+	};
+
 	memory at 80000000 {
 		device_type = "memory";
 		reg = <0x0 0x80000000 0x1 0x0>;
@@ -50,6 +82,40 @@ &arm_wdt {
 	status = "okay";
 };
 
+&csi {
+	vdd-supply =  <&scmi_vddcore>;
+	vdda18-supply = <&scmi_v1v8>;
+	status = "okay";
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port at 0 {
+			reg = <0>;
+			csi_sink: endpoint {
+				remote-endpoint = <&imx335_ep>;
+				data-lanes = <1 2>;
+				bus-type = <4>;
+			};
+		};
+		port at 1 {
+			reg = <1>;
+			csi_source: endpoint {
+				remote-endpoint = <&dcmipp_0>;
+			};
+		};
+	};
+};
+
+&dcmipp {
+	status = "okay";
+	port {
+		dcmipp_0: endpoint {
+			remote-endpoint = <&csi_source>;
+			bus-type = <4>;
+		};
+	};
+};
+
 &ethernet2 {
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&eth2_rgmii_pins_a>;
@@ -81,6 +147,25 @@ &i2c2 {
 	i2c-scl-falling-time-ns = <13>;
 	clock-frequency = <400000>;
 	status = "okay";
+
+	imx335: camera at 1a {
+		compatible = "sony,imx335";
+		reg = <0x1a>;
+		clocks = <&clk_ext_camera>;
+		avdd-supply = <&imx335_2v9>;
+		ovdd-supply = <&imx335_1v8>;
+		dvdd-supply = <&imx335_1v2>;
+		reset-gpios = <&gpioi 7 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
+
+		port {
+			imx335_ep: endpoint {
+				remote-endpoint = <&csi_sink>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+				link-frequencies = /bits/ 64 <594000000>;
+			};
+		};
+	};
 };
 
 &i2c8 {

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:27 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:27 +0100
Subject: [PATCH v4 03/15] media: stm32: csi: addition of the STM32 CSI
 driver
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-3-fbeb55a05ed7@foss.st.com>

The STM32 CSI controller is tightly coupled with the DCMIPP and act as an
input stage to receive data coming from the sensor and transferring
them into the DCMIPP.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>

---
v3: get reset controller within probe function and remove it
    from the driver structure
    use devm_clk_bulk apis rather 3 separate clks

v2: correct data-lanes handling, using values 1 & 2
    update yaml filename in MAINTAINERS
---
 MAINTAINERS                                 |    8 +
 drivers/media/platform/st/stm32/Kconfig     |   14 +
 drivers/media/platform/st/stm32/Makefile    |    1 +
 drivers/media/platform/st/stm32/stm32-csi.c | 1137 +++++++++++++++++++++++++++
 4 files changed, 1160 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..2ffa10e38e52 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14495,6 +14495,14 @@ W:	https://linuxtv.org
 T:	git git://linuxtv.org/media.git
 F:	drivers/media/dvb-frontends/stv6111*
 
+MEDIA DRIVERS FOR STM32 - CSI
+M:	Alain Volmat <alain.volmat at foss.st.com>
+L:	linux-media at vger.kernel.org
+S:	Supported
+T:	git git://linuxtv.org/media_tree.git
+F:	Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
+F:	drivers/media/platform/stm32/stm32-csi.c
+
 MEDIA DRIVERS FOR STM32 - DCMI / DCMIPP
 M:	Hugues Fruchet <hugues.fruchet at foss.st.com>
 M:	Alain Volmat <alain.volmat at foss.st.com>
diff --git a/drivers/media/platform/st/stm32/Kconfig b/drivers/media/platform/st/stm32/Kconfig
index 9df9a2a17728..f12e67bcc9bc 100644
--- a/drivers/media/platform/st/stm32/Kconfig
+++ b/drivers/media/platform/st/stm32/Kconfig
@@ -1,6 +1,20 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 # V4L drivers
+config VIDEO_STM32_CSI
+	tristate "STM32 Camera Serial Interface (CSI) support"
+	depends on V4L_PLATFORM_DRIVERS
+	depends on VIDEO_DEV && OF
+	depends on ARCH_STM32 || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select V4L2_FWNODE
+	help
+	  This module makes the STM32 Camera Serial Interface (CSI)
+	  available as a v4l2 device.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called stm32-csi.
+
 config VIDEO_STM32_DCMI
 	tristate "STM32 Digital Camera Memory Interface (DCMI) support"
 	depends on V4L_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/st/stm32/Makefile b/drivers/media/platform/st/stm32/Makefile
index 7ed8297b9b19..9ae57897f030 100644
--- a/drivers/media/platform/st/stm32/Makefile
+++ b/drivers/media/platform/st/stm32/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_VIDEO_STM32_CSI) += stm32-csi.o
 obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32-dcmi.o
 obj-$(CONFIG_VIDEO_STM32_DCMIPP) += stm32-dcmipp/
 stm32-dma2d-objs := dma2d/dma2d.o dma2d/dma2d-hw.o
diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
new file mode 100644
index 000000000000..48941aae8c9b
--- /dev/null
+++ b/drivers/media/platform/st/stm32/stm32-csi.c
@@ -0,0 +1,1137 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for STM32 Camera Serial Interface
+ *
+ * Copyright (C) STMicroelectronics SA 2024
+ * Author: Alain Volmat <alain.volmat at foss.st.com>
+ * for STMicroelectronics.
+ */
+
+#include <linux/clk.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>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include <media/mipi-csi2.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define STM32_CSI_CR				0x0000
+#define STM32_CSI_CR_CSIEN			BIT(0)
+#define STM32_CSI_CR_VCXSTART(x)		BIT(2 + ((x) * 4))
+#define STM32_CSI_CR_VCXSTOP(x)			BIT(3 + ((x) * 4))
+#define STM32_CSI_PCR				0x0004
+#define STM32_CSI_PCR_DL1EN			BIT(3)
+#define STM32_CSI_PCR_DL0EN			BIT(2)
+#define STM32_CSI_PCR_CLEN			BIT(1)
+#define STM32_CSI_PCR_PWRDOWN			BIT(0)
+#define STM32_CSI_VCXCFGR1(x)			((((x) + 1) * 0x0010) + 0x0)
+#define STM32_CSI_VCXCFGR1_ALLDT		BIT(0)
+#define STM32_CSI_VCXCFGR1_DT0EN		BIT(1)
+#define STM32_CSI_VCXCFGR1_DT1EN		BIT(2)
+#define STM32_CSI_VCXCFGR1_CDTFT_SHIFT		8
+#define STM32_CSI_VCXCFGR1_DT0_SHIFT		16
+#define STM32_CSI_VCXCFGR1_DT0FT_SHIFT		24
+#define STM32_CSI_VCXCFGR2(x)			((((x) + 1) * 0x0010) + 0x4)
+#define STM32_CSI_VCXCFGR2_DT1_SHIFT		0
+#define STM32_CSI_VCXCFGR2_DT1FT_SHIFT		8
+#define STM32_CSI_INPUT_BPP8			2
+#define STM32_CSI_INPUT_BPP10			3
+#define STM32_CSI_INPUT_BPP12			4
+#define STM32_CSI_INPUT_BPP14			5
+#define STM32_CSI_LMCFGR			0x0070
+#define STM32_CSI_LMCFGR_LANENB_SHIFT		8
+#define STM32_CSI_LMCFGR_DLMAP_SHIFT		16
+#define STM32_CSI_IER0				0x0080
+#define STM32_CSI_IER1				0x0084
+#define STM32_CSI_SR0				0x0090
+#define STM32_CSI_SR0_SYNCERRF			BIT(30)
+#define STM32_CSI_SR0_SPKTERRF			BIT(28)
+#define STM32_CSI_SR0_IDERRF			BIT(27)
+#define STM32_CSI_SR0_CECCERRF			BIT(26)
+#define STM32_CSI_SR0_ECCERRF			BIT(25)
+#define STM32_CSI_SR0_CRCERRF			BIT(24)
+#define STM32_CSI_SR0_CCFIFOFF			BIT(21)
+#define STM32_CSI_SR0_VCXSTATEF(x)		BIT(17 + (x))
+#define STM32_CSI_SR1				0x0094
+#define STM32_CSI_SR1_ECTRLDL1F			BIT(12)
+#define STM32_CSI_SR1_ESYNCESCDL1F		BIT(11)
+#define STM32_CSI_SR1_EESCDL1F			BIT(10)
+#define STM32_CSI_SR1_ESOTSYNCDL1F		BIT(9)
+#define STM32_CSI_SR1_ESOTDL1F			BIT(8)
+#define STM32_CSI_SR1_ECTRLDL0F			BIT(4)
+#define STM32_CSI_SR1_ESYNCESCDL0F		BIT(3)
+#define STM32_CSI_SR1_EESCDL0F			BIT(2)
+#define STM32_CSI_SR1_ESOTSYNCDL0F		BIT(1)
+#define STM32_CSI_SR1_ESOTDL0F			BIT(0)
+#define STM32_CSI_FCR0				0x0100
+#define STM32_CSI_FCR1				0x0104
+#define STM32_CSI_SPDFR				0x0110
+#define STM32_CSI_DT_MASK			0x3f
+#define STM32_CSI_VC_MASK			0x03
+#define STM32_CSI_ERR1				0x0114
+#define STM32_CSI_ERR1_IDVCERR_SHIFT		22
+#define STM32_CSI_ERR1_IDDTERR_SHIFT		16
+#define STM32_CSI_ERR1_CECCVCERR_SHIFT		14
+#define STM32_CSI_ERR1_CECCDTERR_SHIFT		8
+#define STM32_CSI_ERR1_CRCVCERR_SHIFT		6
+#define STM32_CSI_ERR1_CRCDTERR_SHIFT		0
+#define STM32_CSI_ERR2				0x0118
+#define STM32_CSI_ERR2_SYNCVCERR_SHIFT		18
+#define STM32_CSI_ERR2_SPKTVCERR_SHIFT		6
+#define STM32_CSI_ERR2_SPKTDTERR_SHIFT		0
+#define STM32_CSI_PRCR				0x1000
+#define STM32_CSI_PRCR_PEN			BIT(1)
+#define STM32_CSI_PMCR				0x1004
+#define STM32_CSI_PFCR				0x1008
+#define STM32_CSI_PFCR_CCFR_MASK		GENMASK(5, 0)
+#define STM32_CSI_PFCR_CCFR_SHIFT		0
+#define STM32_CSI_PFCR_HSFR_MASK		GENMASK(14, 8)
+#define STM32_CSI_PFCR_HSFR_SHIFT		8
+#define STM32_CSI_PFCR_DLD			BIT(16)
+#define STM32_CSI_PTCR0				0x1010
+#define STM32_CSI_PTCR0_TCKEN			BIT(0)
+#define STM32_CSI_PTCR1				0x1014
+#define STM32_CSI_PTCR1_TWM			BIT(16)
+#define STM32_CSI_PTCR1_TDI_MASK		GENMASK(7, 0)
+#define STM32_CSI_PTCR1_TDI_SHIFT		0
+#define STM32_CSI_PTSR				0x1018
+
+#define STM32_CSI_LANES_MAX	2
+
+#define STM32_CSI_SR0_ERRORS	(STM32_CSI_SR0_SYNCERRF | STM32_CSI_SR0_SPKTERRF |\
+				 STM32_CSI_SR0_IDERRF | STM32_CSI_SR0_CECCERRF |\
+				 STM32_CSI_SR0_ECCERRF | STM32_CSI_SR0_CRCERRF |\
+				 STM32_CSI_SR0_CCFIFOFF)
+#define STM32_CSI_SR1_DL0_ERRORS	(STM32_CSI_SR1_ECTRLDL0F | STM32_CSI_SR1_ESYNCESCDL0F |\
+				 STM32_CSI_SR1_EESCDL0F | STM32_CSI_SR1_ESOTSYNCDL0F |\
+				 STM32_CSI_SR1_ESOTDL0F)
+#define STM32_CSI_SR1_DL1_ERRORS	(STM32_CSI_SR1_ECTRLDL1F | STM32_CSI_SR1_ESYNCESCDL1F |\
+				 STM32_CSI_SR1_EESCDL1F | STM32_CSI_SR1_ESOTSYNCDL1F |\
+				 STM32_CSI_SR1_ESOTDL1F)
+#define STM32_CSI_SR1_ERRORS	(STM32_CSI_SR1_DL0_ERRORS | STM32_CSI_SR1_DL1_ERRORS)
+
+enum stm32_csi_pads {
+	STM32_CSI_PAD_SINK,
+	STM32_CSI_PAD_SOURCE,
+	STM32_CSI_PAD_MAX,
+};
+
+struct stm32_csi_event {
+	u32 mask;
+	const char * const name;
+};
+
+static const struct stm32_csi_event stm32_csi_events_sr0[] = {
+	{STM32_CSI_SR0_SYNCERRF,	"Synchronization error"},
+	{STM32_CSI_SR0_SPKTERRF,	"Short packet error"},
+	{STM32_CSI_SR0_IDERRF,		"Data type ID error"},
+	{STM32_CSI_SR0_CECCERRF,	"Corrected ECC error"},
+	{STM32_CSI_SR0_ECCERRF,		"ECC error"},
+	{STM32_CSI_SR0_CRCERRF,		"CRC error"},
+	{STM32_CSI_SR0_CCFIFOFF,	"Clk changer FIFO full error"},
+};
+
+#define STM32_CSI_NUM_SR0_EVENTS ARRAY_SIZE(stm32_csi_events_sr0)
+
+static const struct stm32_csi_event stm32_csi_events_sr1[] = {
+	{STM32_CSI_SR1_ECTRLDL1F,	"L1: D-PHY control error"},
+	{STM32_CSI_SR1_ESYNCESCDL1F,
+		"L1: D-PHY low power data transmission synchro error"},
+	{STM32_CSI_SR1_EESCDL1F,	"L1: D-PHY escape entry error"},
+	{STM32_CSI_SR1_ESOTSYNCDL1F,
+		"L1: Start of transmission synchro error"},
+	{STM32_CSI_SR1_ESOTDL1F,	"L1: Start of transmission error"},
+	{STM32_CSI_SR1_ECTRLDL0F,	"L0: D-PHY control error"},
+	{STM32_CSI_SR1_ESYNCESCDL0F,
+		"L0: D-PHY low power data transmission synchro error"},
+	{STM32_CSI_SR1_EESCDL0F,	"L0: D-PHY escape entry error"},
+	{STM32_CSI_SR1_ESOTSYNCDL0F,
+		"L0: Start of transmission synchro error"},
+	{STM32_CSI_SR1_ESOTDL0F,	"L0: Start of transmission error"},
+};
+
+#define STM32_CSI_NUM_SR1_EVENTS ARRAY_SIZE(stm32_csi_events_sr1)
+
+enum stm32_csi_clk {
+	STM32_CSI_CLK_PCLK,
+	STM32_CSI_CLK_TXESC,
+	STM32_CSI_CLK_CSI2PHY,
+	STM32_CSI_CLK_NB,
+};
+
+static const char * const stm32_csi_clks_id[] = {
+	"pclk",
+	"txesc",
+	"csi2phy",
+};
+
+struct stm32_csi_dev {
+	struct device			*dev;
+
+	void __iomem			*base;
+
+	struct clk_bulk_data		clks[STM32_CSI_CLK_NB];
+	struct regulator_bulk_data	supplies[2];
+
+	u8				lanes[STM32_CSI_LANES_MAX];
+	u8				num_lanes;
+
+	/*
+	 * spinlock slock is used to protect to srX_counters tables being
+	 * accessed from log_status and interrupt context
+	 */
+	spinlock_t			slock;
+
+	u32				sr0_counters[STM32_CSI_NUM_SR0_EVENTS];
+	u32				sr1_counters[STM32_CSI_NUM_SR1_EVENTS];
+
+	struct v4l2_subdev		sd;
+	struct v4l2_async_notifier	notifier;
+	struct media_pad		pads[STM32_CSI_PAD_MAX];
+
+	/* Remote source */
+	struct v4l2_subdev		*s_subdev;
+	u32				s_subdev_pad_nb;
+};
+
+struct stm32_csi_fmts {
+	u32 code;
+	u32 datatype;
+	u32 input_fmt;
+	u8 bpp;
+};
+
+#define FMT_MBUS_DT_DTFMT_BPP(mbus, dt, input, byteperpixel)		\
+	{								\
+		.code = MEDIA_BUS_FMT_##mbus,				\
+		.datatype = MIPI_CSI2_DT_##dt,				\
+		.input_fmt = STM32_CSI_INPUT_##input,	\
+		.bpp = byteperpixel,					\
+	}
+static const struct stm32_csi_fmts stm32_csi_formats[] = {
+	/* YUV 422 8 bit */
+	FMT_MBUS_DT_DTFMT_BPP(UYVY8_1X16, YUV422_8B, BPP8, 8),
+	FMT_MBUS_DT_DTFMT_BPP(YUYV8_1X16, YUV422_8B, BPP8, 8),
+	FMT_MBUS_DT_DTFMT_BPP(YVYU8_1X16, YUV422_8B, BPP8, 8),
+	FMT_MBUS_DT_DTFMT_BPP(VYUY8_1X16, YUV422_8B, BPP8, 8),
+
+	/* Raw Bayer */
+	/* 8 bit */
+	FMT_MBUS_DT_DTFMT_BPP(SBGGR8_1X8, RAW8, BPP8, 8),
+	FMT_MBUS_DT_DTFMT_BPP(SGBRG8_1X8, RAW8, BPP8, 8),
+	FMT_MBUS_DT_DTFMT_BPP(SGRBG8_1X8, RAW8, BPP8, 8),
+	FMT_MBUS_DT_DTFMT_BPP(SRGGB8_1X8, RAW8, BPP8, 8),
+	/* 10 bit */
+	FMT_MBUS_DT_DTFMT_BPP(SRGGB10_1X10, RAW10, BPP10, 10),
+	FMT_MBUS_DT_DTFMT_BPP(SGBRG10_1X10, RAW10, BPP10, 10),
+	FMT_MBUS_DT_DTFMT_BPP(SGRBG10_1X10, RAW10, BPP10, 10),
+	FMT_MBUS_DT_DTFMT_BPP(SRGGB10_1X10, RAW10, BPP10, 10),
+	/* 12 bit */
+	FMT_MBUS_DT_DTFMT_BPP(SRGGB12_1X12, RAW12, BPP12, 12),
+	FMT_MBUS_DT_DTFMT_BPP(SGBRG12_1X12, RAW12, BPP12, 12),
+	FMT_MBUS_DT_DTFMT_BPP(SGRBG12_1X12, RAW12, BPP12, 12),
+	FMT_MBUS_DT_DTFMT_BPP(SRGGB12_1X12, RAW12, BPP12, 12),
+	/* 14 bit */
+	FMT_MBUS_DT_DTFMT_BPP(SRGGB14_1X14, RAW14, BPP14, 14),
+	FMT_MBUS_DT_DTFMT_BPP(SGBRG14_1X14, RAW14, BPP14, 14),
+	FMT_MBUS_DT_DTFMT_BPP(SGRBG14_1X14, RAW14, BPP14, 14),
+	FMT_MBUS_DT_DTFMT_BPP(SRGGB14_1X14, RAW14, BPP14, 14),
+
+	/* RGB 565 */
+	FMT_MBUS_DT_DTFMT_BPP(RGB565_1X16, RGB565, BPP8, 8),
+
+	/* JPEG (datatype isn't used) */
+	FMT_MBUS_DT_DTFMT_BPP(JPEG_1X8, NULL, BPP8, 8),
+};
+
+struct stm32_csi_mbps_phy_reg {
+	unsigned int mbps;
+	unsigned int hsfreqrange;
+	unsigned int osc_freq_target;
+};
+
+/*
+ * Table describing configuration of the PHY depending on the
+ * intended Bit Rate. From table 5-8 Frequency Ranges and Defaults
+ * of the Synopsis DWC MIPI PHY databook
+ */
+static const struct stm32_csi_mbps_phy_reg snps_stm32mp25[] = {
+	{ .mbps =   80,	.hsfreqrange = 0x00,	.osc_freq_target = 460 },
+	{ .mbps =   90, .hsfreqrange = 0x10,	.osc_freq_target = 460 },
+	{ .mbps =  100, .hsfreqrange = 0x20,	.osc_freq_target = 460 },
+	{ .mbps =  110, .hsfreqrange = 0x30,	.osc_freq_target = 460 },
+	{ .mbps =  120, .hsfreqrange = 0x01,	.osc_freq_target = 460 },
+	{ .mbps =  130, .hsfreqrange = 0x11,	.osc_freq_target = 460 },
+	{ .mbps =  140, .hsfreqrange = 0x21,	.osc_freq_target = 460 },
+	{ .mbps =  150, .hsfreqrange = 0x31,	.osc_freq_target = 460 },
+	{ .mbps =  160, .hsfreqrange = 0x02,	.osc_freq_target = 460 },
+	{ .mbps =  170, .hsfreqrange = 0x12,	.osc_freq_target = 460 },
+	{ .mbps =  180, .hsfreqrange = 0x22,	.osc_freq_target = 460 },
+	{ .mbps =  190, .hsfreqrange = 0x32,	.osc_freq_target = 460 },
+	{ .mbps =  205, .hsfreqrange = 0x03,	.osc_freq_target = 460 },
+	{ .mbps =  220, .hsfreqrange = 0x13,	.osc_freq_target = 460 },
+	{ .mbps =  235, .hsfreqrange = 0x23,	.osc_freq_target = 460 },
+	{ .mbps =  250, .hsfreqrange = 0x33,	.osc_freq_target = 460 },
+	{ .mbps =  275, .hsfreqrange = 0x04,	.osc_freq_target = 460 },
+	{ .mbps =  300, .hsfreqrange = 0x14,	.osc_freq_target = 460 },
+	{ .mbps =  325, .hsfreqrange = 0x25,	.osc_freq_target = 460 },
+	{ .mbps =  350, .hsfreqrange = 0x35,	.osc_freq_target = 460 },
+	{ .mbps =  400, .hsfreqrange = 0x05,	.osc_freq_target = 460 },
+	{ .mbps =  450, .hsfreqrange = 0x16,	.osc_freq_target = 460 },
+	{ .mbps =  500, .hsfreqrange = 0x26,	.osc_freq_target = 460 },
+	{ .mbps =  550, .hsfreqrange = 0x37,	.osc_freq_target = 460 },
+	{ .mbps =  600, .hsfreqrange = 0x07,	.osc_freq_target = 460 },
+	{ .mbps =  650, .hsfreqrange = 0x18,	.osc_freq_target = 460 },
+	{ .mbps =  700, .hsfreqrange = 0x28,	.osc_freq_target = 460 },
+	{ .mbps =  750, .hsfreqrange = 0x39,	.osc_freq_target = 460 },
+	{ .mbps =  800, .hsfreqrange = 0x09,	.osc_freq_target = 460 },
+	{ .mbps =  850, .hsfreqrange = 0x19,	.osc_freq_target = 460 },
+	{ .mbps =  900, .hsfreqrange = 0x29,	.osc_freq_target = 460 },
+	{ .mbps =  950, .hsfreqrange = 0x3a,	.osc_freq_target = 460 },
+	{ .mbps = 1000, .hsfreqrange = 0x0a,	.osc_freq_target = 460 },
+	{ .mbps = 1050, .hsfreqrange = 0x1a,	.osc_freq_target = 460 },
+	{ .mbps = 1100, .hsfreqrange = 0x2a,	.osc_freq_target = 460 },
+	{ .mbps = 1150, .hsfreqrange = 0x3b,	.osc_freq_target = 460 },
+	{ .mbps = 1200, .hsfreqrange = 0x0b,	.osc_freq_target = 460 },
+	{ .mbps = 1250, .hsfreqrange = 0x1b,	.osc_freq_target = 460 },
+	{ .mbps = 1300, .hsfreqrange = 0x2b,	.osc_freq_target = 460 },
+	{ .mbps = 1350, .hsfreqrange = 0x3c,	.osc_freq_target = 460 },
+	{ .mbps = 1400, .hsfreqrange = 0x0c,	.osc_freq_target = 460 },
+	{ .mbps = 1450, .hsfreqrange = 0x1c,	.osc_freq_target = 460 },
+	{ .mbps = 1500, .hsfreqrange = 0x2c,	.osc_freq_target = 460 },
+	{ .mbps = 1550, .hsfreqrange = 0x3d,	.osc_freq_target = 285 },
+	{ .mbps = 1600, .hsfreqrange = 0x0d,	.osc_freq_target = 295 },
+	{ .mbps = 1650, .hsfreqrange = 0x1d,	.osc_freq_target = 304 },
+	{ .mbps = 1700, .hsfreqrange = 0x2e,	.osc_freq_target = 313 },
+	{ .mbps = 1750, .hsfreqrange = 0x3e,	.osc_freq_target = 322 },
+	{ .mbps = 1800, .hsfreqrange = 0x0e,	.osc_freq_target = 331 },
+	{ .mbps = 1850, .hsfreqrange = 0x1e,	.osc_freq_target = 341 },
+	{ .mbps = 1900, .hsfreqrange = 0x2f,	.osc_freq_target = 350 },
+	{ .mbps = 1950, .hsfreqrange = 0x3f,	.osc_freq_target = 359 },
+	{ .mbps = 2000, .hsfreqrange = 0x0f,	.osc_freq_target = 368 },
+	{ .mbps = 2050, .hsfreqrange = 0x40,	.osc_freq_target = 377 },
+	{ .mbps = 2100, .hsfreqrange = 0x41,	.osc_freq_target = 387 },
+	{ .mbps = 2150, .hsfreqrange = 0x42,	.osc_freq_target = 396 },
+	{ .mbps = 2200, .hsfreqrange = 0x43,	.osc_freq_target = 405 },
+	{ .mbps = 2250, .hsfreqrange = 0x44,	.osc_freq_target = 414 },
+	{ .mbps = 2300, .hsfreqrange = 0x45,	.osc_freq_target = 423 },
+	{ .mbps = 2350, .hsfreqrange = 0x46,	.osc_freq_target = 432 },
+	{ .mbps = 2400, .hsfreqrange = 0x47,	.osc_freq_target = 442 },
+	{ .mbps = 2450, .hsfreqrange = 0x48,	.osc_freq_target = 451 },
+	{ .mbps = 2500, .hsfreqrange = 0x49,	.osc_freq_target = 460 },
+	{ /* sentinel */ }
+};
+
+static const struct v4l2_mbus_framefmt fmt_default = {
+	.width = 640,
+	.height = 480,
+	.code = MEDIA_BUS_FMT_RGB565_1X16,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_REC709,
+	.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
+	.quantization = V4L2_QUANTIZATION_DEFAULT,
+	.xfer_func = V4L2_XFER_FUNC_DEFAULT,
+};
+
+static const struct stm32_csi_fmts *stm32_csi_code_to_fmt(unsigned int code)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(stm32_csi_formats); i++)
+		if (stm32_csi_formats[i].code == code)
+			return &stm32_csi_formats[i];
+
+	return NULL;
+}
+
+static inline struct stm32_csi_dev *to_csidev(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct stm32_csi_dev, sd);
+}
+
+static int stm32_csi_setup_lane_merger(struct stm32_csi_dev *csidev)
+{
+	u32 lmcfgr = 0;
+	int i;
+
+	for (i = 0; i < csidev->num_lanes; i++) {
+		if (!csidev->lanes[i] || csidev->lanes[i] > STM32_CSI_LANES_MAX) {
+			dev_err(csidev->dev, "Invalid lane id (%d)\n", csidev->lanes[i]);
+			return -EINVAL;
+		}
+		lmcfgr |= (csidev->lanes[i] << ((i * 4) + STM32_CSI_LMCFGR_DLMAP_SHIFT));
+	}
+
+	lmcfgr |= (csidev->num_lanes << STM32_CSI_LMCFGR_LANENB_SHIFT);
+
+	writel_relaxed(lmcfgr, csidev->base + STM32_CSI_LMCFGR);
+
+	return 0;
+}
+
+static void stm32_csi_phy_reg_write(struct stm32_csi_dev *csidev,
+				    u32 addr, u32 val)
+{
+	/* Based on sequence described at section 5.2.3.2 of DesignWave document */
+	/* For writing the 4-bit testcode MSBs */
+	/* Set testen to high */
+	writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1);
+
+	/* Set testclk to high */
+	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
+
+	/* Place 0x00 in testdin */
+	writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1);
+
+	/*
+	 * Set testclk to low (with the falling edge on testclk, the testdin
+	 * signal content is latched internally)
+	 */
+	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
+
+	/* Set testen to low */
+	writel_relaxed(0, csidev->base + STM32_CSI_PTCR1);
+
+	/* Place the 8-bit word corresponding to the testcode MSBs in testdin */
+	writel_relaxed(((addr >> 8) & STM32_CSI_PTCR1_TDI_MASK) << STM32_CSI_PTCR1_TDI_SHIFT,
+		       csidev->base + STM32_CSI_PTCR1);
+
+	/* Set testclk to high */
+	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
+
+	/* For writing the 8-bit testcode LSBs */
+	/* Set testclk to low */
+	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
+
+	/* Set testen to high */
+	writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1);
+
+	/* Set testclk to high */
+	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
+
+	/* Place the 8-bit word test data in testdin */
+	writel_relaxed((addr & STM32_CSI_PTCR1_TDI_MASK) <<
+		       STM32_CSI_PTCR1_TDI_SHIFT | STM32_CSI_PTCR1_TWM,
+		       csidev->base + STM32_CSI_PTCR1);
+
+	/*
+	 * Set testclk to low (with the falling edge on testclk, the testdin
+	 * signal content is latched internally)
+	 */
+	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
+
+	/* Set testen to low */
+	writel_relaxed(0, csidev->base + STM32_CSI_PTCR1);
+
+	/* For writing the data */
+	/* Place the 8-bit word corresponding to the page offset in testdin */
+	writel_relaxed((val & STM32_CSI_PTCR1_TDI_MASK) << STM32_CSI_PTCR1_TDI_SHIFT,
+		       csidev->base + STM32_CSI_PTCR1);
+
+	/* Set testclk to high (test data is programmed internally */
+	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
+
+	/* Finish by setting testclk to low */
+	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
+}
+
+static int stm32_csi_start(struct stm32_csi_dev *csidev,
+			   struct v4l2_subdev_state *state)
+{
+	const struct stm32_csi_mbps_phy_reg *phy_regs;
+	struct v4l2_mbus_framefmt *sink_fmt;
+	const struct stm32_csi_fmts *fmt;
+	unsigned long phy_clk_frate;
+	unsigned int mbps;
+	u32 lanes_ie = 0;
+	u32 lanes_en = 0;
+	s64 link_freq;
+	int ret;
+	u32 ccfr;
+
+	dev_dbg(csidev->dev, "Starting the CSI2\n");
+
+	/* Get the bpp value on pad0 (input of CSI) */
+	sink_fmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SINK);
+	fmt = stm32_csi_code_to_fmt(sink_fmt->code);
+
+	/* Get the remote sensor link frequency */
+	if (!csidev->s_subdev)
+		return -EIO;
+
+	link_freq = v4l2_get_link_freq(csidev->s_subdev->ctrl_handler,
+				       fmt->bpp, 2 * csidev->num_lanes);
+	if (link_freq < 0)
+		return link_freq;
+
+	/* MBPS is expressed in Mbps, hence link_freq / 100000 * 2 */
+	mbps = div_s64(link_freq, 500000);
+	dev_dbg(csidev->dev, "Computed Mbps: %u\n", mbps);
+
+	for (phy_regs = snps_stm32mp25; phy_regs->mbps != 0; phy_regs++)
+		if (phy_regs->mbps >= mbps)
+			break;
+
+	if (!phy_regs->mbps) {
+		dev_err(csidev->dev, "Unsupported PHY speed (%u Mbps)", mbps);
+		return -ERANGE;
+	}
+
+	dev_dbg(csidev->dev, "PHY settings: (%u Mbps, %u HS FRange, %u OSC Freq)\n",
+		phy_regs->mbps, phy_regs->hsfreqrange,
+		phy_regs->osc_freq_target);
+
+	/* Prepare lanes related configuration bits */
+	lanes_ie |= STM32_CSI_SR1_DL0_ERRORS;
+	lanes_en |= STM32_CSI_PCR_DL0EN;
+	if (csidev->num_lanes == 2) {
+		lanes_ie |= STM32_CSI_SR1_DL1_ERRORS;
+		lanes_en |= STM32_CSI_PCR_DL1EN;
+	}
+
+	ret = pm_runtime_get_sync(csidev->dev);
+	if (ret < 0)
+		return ret;
+
+	/* Retrieve CSI2PHY clock rate to compute CCFR value */
+	phy_clk_frate = clk_get_rate(csidev->clks[STM32_CSI_CLK_CSI2PHY].clk);
+	if (!phy_clk_frate) {
+		pm_runtime_put(csidev->dev);
+		dev_err(csidev->dev, "CSI2PHY clock rate invalid (0)\n");
+		return ret;
+	}
+
+	ret = stm32_csi_setup_lane_merger(csidev);
+	if (ret) {
+		pm_runtime_put(csidev->dev);
+		return ret;
+	}
+
+	/* Enable the CSI */
+	writel_relaxed(STM32_CSI_CR_CSIEN, csidev->base + STM32_CSI_CR);
+
+	/* Enable some global CSI related interrupts - bits are same as SR0 */
+	writel_relaxed(STM32_CSI_SR0_ERRORS, csidev->base + STM32_CSI_IER0);
+
+	/* Enable lanes related error interrupts */
+	writel_relaxed(lanes_ie, csidev->base + STM32_CSI_IER1);
+
+	/* Initialization of the D-PHY */
+	/* Stop the D-PHY */
+	writel_relaxed(0, csidev->base + STM32_CSI_PRCR);
+
+	/* Keep the D-PHY in power down state */
+	writel_relaxed(0, csidev->base + STM32_CSI_PCR);
+
+	/* Enable testclr clock during 15ns */
+	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
+	udelay(1);
+	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
+
+	/* Set hsfreqrange */
+	phy_clk_frate /= 1000000;
+	ccfr = (phy_clk_frate - 17) * 4;
+	writel_relaxed((ccfr << STM32_CSI_PFCR_CCFR_SHIFT) |
+		       (phy_regs->hsfreqrange << STM32_CSI_PFCR_HSFR_SHIFT),
+		       csidev->base + STM32_CSI_PFCR);
+
+	/* set reg @08 deskew_polarity_rw 1'b1 */
+	stm32_csi_phy_reg_write(csidev, 0x08, 0x38);
+
+	/* set reg @0xE4 counter_for_des_en_config_if_rx 0x10 + DLL prog EN */
+	/* This is because 13<= cfgclkfreqrange[5:0]<=38 */
+	stm32_csi_phy_reg_write(csidev, 0xe4, 0x11);
+
+	/* set reg @0xe2 & reg @0xe3 value DLL target oscilation freq */
+	/* Based on the table page 77, osc_freq_target */
+	stm32_csi_phy_reg_write(csidev, 0xe2, phy_regs->osc_freq_target & 0xFF);
+	stm32_csi_phy_reg_write(csidev, 0xe3, (phy_regs->osc_freq_target >> 8) & 0x0F);
+
+	writel_relaxed(STM32_CSI_PFCR_DLD | readl_relaxed(csidev->base + STM32_CSI_PFCR),
+		       csidev->base + STM32_CSI_PFCR);
+
+	/* Enable Lanes */
+	writel_relaxed(lanes_en | STM32_CSI_PCR_CLEN, csidev->base + STM32_CSI_PCR);
+	writel_relaxed(lanes_en | STM32_CSI_PCR_CLEN | STM32_CSI_PCR_PWRDOWN,
+		       csidev->base + STM32_CSI_PCR);
+
+	writel_relaxed(STM32_CSI_PRCR_PEN, csidev->base + STM32_CSI_PRCR);
+
+	/* Remove the force */
+	writel_relaxed(0, csidev->base + STM32_CSI_PMCR);
+
+	return ret;
+}
+
+static void stm32_csi_stop(struct stm32_csi_dev *csidev)
+{
+	dev_dbg(csidev->dev, "Stopping the CSI2\n");
+
+	/* Disable the D-PHY */
+	writel_relaxed(0, csidev->base + STM32_CSI_PCR);
+
+	/* Disable ITs */
+	writel_relaxed(0, csidev->base + STM32_CSI_IER0);
+	writel_relaxed(0, csidev->base + STM32_CSI_IER1);
+
+	/* Disable the CSI */
+	writel_relaxed(0, csidev->base + STM32_CSI_CR);
+
+	pm_runtime_put(csidev->dev);
+}
+
+static int stm32_csi_start_vc(struct stm32_csi_dev *csidev,
+			      struct v4l2_subdev_state *state, u32 vc)
+{
+	struct v4l2_mbus_framefmt *mbus_fmt;
+	const struct stm32_csi_fmts *fmt;
+	u32 cfgr1 = 0;
+	int ret = 0;
+	u32 status;
+
+	mbus_fmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SOURCE);
+	fmt = stm32_csi_code_to_fmt(mbus_fmt->code);
+
+	/* If the mbus code is JPEG, don't enable filtering */
+	if (mbus_fmt->code == MEDIA_BUS_FMT_JPEG_1X8) {
+		cfgr1 |= STM32_CSI_VCXCFGR1_ALLDT;
+		cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_CDTFT_SHIFT;
+		dev_dbg(csidev->dev, "VC%d: enable AllDT mode\n", vc);
+	} else {
+		cfgr1 |= fmt->datatype << STM32_CSI_VCXCFGR1_DT0_SHIFT;
+		cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_DT0FT_SHIFT;
+		cfgr1 |= STM32_CSI_VCXCFGR1_DT0EN;
+		dev_dbg(csidev->dev, "VC%d: enable DT0(0x%x)/DT0FT(0x%x)\n",
+			vc, fmt->datatype, fmt->input_fmt);
+	}
+	writel_relaxed(cfgr1, csidev->base + STM32_CSI_VCXCFGR1(vc));
+
+	/* Enable processing of the virtual-channel and wait for its status */
+	writel_relaxed(STM32_CSI_CR_VCXSTART(vc) | STM32_CSI_CR_CSIEN,
+		       csidev->base + STM32_CSI_CR);
+
+	ret = readl_relaxed_poll_timeout(csidev->base + STM32_CSI_SR0,
+					 status,
+					 status & STM32_CSI_SR0_VCXSTATEF(vc),
+					 1000, 1000000);
+	if (ret) {
+		dev_err(csidev->dev, "failed to start VC(%d)\n", vc);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int stm32_csi_stop_vc(struct stm32_csi_dev *csidev, u32 vc)
+{
+	int ret = 0;
+	u32 status;
+
+	/* Stop the Virtual Channel */
+	writel_relaxed(STM32_CSI_CR_VCXSTOP(vc) | STM32_CSI_CR_CSIEN,
+		       csidev->base + STM32_CSI_CR);
+
+	ret = readl_relaxed_poll_timeout(csidev->base + STM32_CSI_SR0,
+					 status,
+					 !(status & STM32_CSI_SR0_VCXSTATEF(vc)),
+					 1000, 1000000);
+	if (ret) {
+		dev_err(csidev->dev, "failed to stop VC(%d)\n", vc);
+		return ret;
+	}
+
+	/* Disable all DTs */
+	writel_relaxed(0, csidev->base + STM32_CSI_VCXCFGR1(vc));
+	writel_relaxed(0, csidev->base + STM32_CSI_VCXCFGR2(vc));
+
+	return 0;
+}
+
+static int stm32_csi_disable_streams(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *state, u32 pad,
+				     u64 streams_mask)
+{
+	struct stm32_csi_dev *csidev = to_csidev(sd);
+	int ret;
+
+	ret = v4l2_subdev_disable_streams(csidev->s_subdev,
+					  csidev->s_subdev_pad_nb, BIT_ULL(0));
+	if (ret)
+		return ret;
+
+	/* Stop the VC0 */
+	ret = stm32_csi_stop_vc(csidev, 0);
+	if (ret)
+		dev_err(csidev->dev, "Failed to stop VC0\n");
+
+	stm32_csi_stop(csidev);
+
+	return 0;
+}
+
+static int stm32_csi_enable_streams(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_state *state, u32 pad,
+				    u64 streams_mask)
+{
+	struct stm32_csi_dev *csidev = to_csidev(sd);
+	int ret;
+
+	ret = stm32_csi_start(csidev, state);
+	if (ret)
+		return ret;
+
+	/* Configure & start the VC0 */
+	ret = stm32_csi_start_vc(csidev, state, 0);
+	if (ret) {
+		dev_err(csidev->dev, "Failed to start VC0\n");
+		stm32_csi_stop(csidev);
+		return ret;
+	}
+
+	ret = v4l2_subdev_enable_streams(csidev->s_subdev,
+					 csidev->s_subdev_pad_nb, BIT_ULL(0));
+	if (ret) {
+		stm32_csi_stop_vc(csidev, 0);
+		stm32_csi_stop(csidev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int stm32_csi_init_state(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state)
+{
+	int i;
+
+	for (i = 0; i < sd->entity.num_pads; i++)
+		*v4l2_subdev_state_get_format(state, i) = fmt_default;
+
+	return 0;
+}
+
+static int stm32_csi_enum_mbus_code(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_state *state,
+				    struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(stm32_csi_formats))
+		return -EINVAL;
+
+	code->code = stm32_csi_formats[code->index].code;
+	return 0;
+}
+
+static int stm32_csi_set_pad_format(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_state *state,
+				    struct v4l2_subdev_format *format)
+{
+	struct stm32_csi_dev *csidev = to_csidev(sd);
+	struct v4l2_mbus_framefmt *framefmt;
+	const struct stm32_csi_fmts *fmt;
+
+	fmt = stm32_csi_code_to_fmt(format->format.code);
+	if (!fmt) {
+		dev_dbg(csidev->dev, "Unsupported code %d, use default\n",
+			format->format.code);
+		format->format.code = fmt_default.code;
+	}
+
+	framefmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SINK);
+
+	if (format->pad == STM32_CSI_PAD_SOURCE)
+		format->format = *framefmt;
+	else
+		*framefmt = format->format;
+
+	framefmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SOURCE);
+	*framefmt = format->format;
+
+	return 0;
+}
+
+static int stm32_csi_log_status(struct v4l2_subdev *sd)
+{
+	struct stm32_csi_dev *csidev = to_csidev(sd);
+	unsigned long flags;
+	unsigned int i;
+
+	spin_lock_irqsave(&csidev->slock, flags);
+
+	for (i = 0; i < STM32_CSI_NUM_SR0_EVENTS; i++) {
+		if (csidev->sr0_counters[i])
+			dev_info(csidev->dev, "%s events: %d\n",
+				 stm32_csi_events_sr0[i].name,
+				 csidev->sr0_counters[i]);
+	}
+
+	for (i = 0; i < STM32_CSI_NUM_SR1_EVENTS; i++) {
+		if (csidev->sr1_counters[i])
+			dev_info(csidev->dev, "%s events: %d\n",
+				 stm32_csi_events_sr1[i].name,
+				 csidev->sr1_counters[i]);
+	}
+
+	spin_unlock_irqrestore(&csidev->slock, flags);
+
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops stm32_csi_core_ops = {
+	.log_status = stm32_csi_log_status,
+};
+
+static const struct v4l2_subdev_video_ops stm32_csi_video_ops = {
+	.s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_pad_ops stm32_csi_pad_ops = {
+	.enum_mbus_code = stm32_csi_enum_mbus_code,
+	.set_fmt = stm32_csi_set_pad_format,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.enable_streams = stm32_csi_enable_streams,
+	.disable_streams = stm32_csi_disable_streams,
+};
+
+static const struct v4l2_subdev_ops stm32_csi_subdev_ops = {
+	.core		= &stm32_csi_core_ops,
+	.pad		= &stm32_csi_pad_ops,
+	.video		= &stm32_csi_video_ops,
+};
+
+static const struct v4l2_subdev_internal_ops stm32_csi_subdev_internal_ops = {
+	.init_state = stm32_csi_init_state,
+};
+
+static int stm32_csi_async_bound(struct v4l2_async_notifier *notifier,
+				 struct v4l2_subdev *s_subdev,
+				 struct v4l2_async_connection *asd)
+{
+	struct v4l2_subdev *sd = notifier->sd;
+	struct stm32_csi_dev *csidev = to_csidev(sd);
+	int remote_pad;
+
+	remote_pad = media_entity_get_fwnode_pad(&s_subdev->entity,
+						 s_subdev->fwnode,
+						 MEDIA_PAD_FL_SOURCE);
+	if (remote_pad < 0) {
+		dev_err(csidev->dev, "Couldn't find output pad for subdev %s\n",
+			s_subdev->name);
+		return remote_pad;
+	}
+
+	csidev->s_subdev = s_subdev;
+	csidev->s_subdev_pad_nb = remote_pad;
+
+	return media_create_pad_link(&csidev->s_subdev->entity,
+				     remote_pad, &csidev->sd.entity,
+				     STM32_CSI_PAD_SINK,
+				     MEDIA_LNK_FL_ENABLED |
+				     MEDIA_LNK_FL_IMMUTABLE);
+}
+
+static const struct v4l2_async_notifier_operations stm32_csi_notifier_ops = {
+	.bound		= stm32_csi_async_bound,
+};
+
+static irqreturn_t stm32_csi_irq_thread(int irq, void *arg)
+{
+	struct stm32_csi_dev *csidev = arg;
+	unsigned long flags;
+	u32 sr0, sr1;
+	int i;
+
+	sr0 = readl_relaxed(csidev->base + STM32_CSI_SR0);
+	sr1 = readl_relaxed(csidev->base + STM32_CSI_SR1);
+
+	/* Clear interrupt */
+	writel_relaxed(sr0 & STM32_CSI_SR0_ERRORS,
+		       csidev->base + STM32_CSI_FCR0);
+	writel_relaxed(sr1 & STM32_CSI_SR1_ERRORS,
+		       csidev->base + STM32_CSI_FCR1);
+
+	spin_lock_irqsave(&csidev->slock, flags);
+
+	for (i = 0; i < STM32_CSI_NUM_SR0_EVENTS; i++)
+		if (sr0 & stm32_csi_events_sr0[i].mask)
+			csidev->sr0_counters[i]++;
+
+	for (i = 0; i < STM32_CSI_NUM_SR1_EVENTS; i++)
+		if (sr1 & stm32_csi_events_sr1[i].mask)
+			csidev->sr1_counters[i]++;
+
+	spin_unlock_irqrestore(&csidev->slock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static int stm32_csi_get_resources(struct stm32_csi_dev *csidev,
+				   struct platform_device *pdev)
+{
+	int irq, ret, i;
+
+	csidev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+	if (IS_ERR(csidev->base))
+		return dev_err_probe(&pdev->dev, PTR_ERR(csidev->base),
+				     "Failed to ioremap resource\n");
+
+	for (i = 0; i < STM32_CSI_CLK_NB; i++)
+		csidev->clks[i].id = stm32_csi_clks_id[i];
+
+	ret = devm_clk_bulk_get(&pdev->dev, STM32_CSI_CLK_NB,
+				csidev->clks);
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "Couldn't get clks\n");
+
+	csidev->supplies[0].supply = "vdd";
+	csidev->supplies[1].supply = "vdda18";
+	ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(csidev->supplies),
+				      csidev->supplies);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "Failed to request regulator vdd\n");
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+					stm32_csi_irq_thread, IRQF_ONESHOT,
+					dev_name(&pdev->dev), csidev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "Unable to request irq");
+
+	return 0;
+}
+
+static int stm32_csi_parse_dt(struct stm32_csi_dev *csidev)
+{
+	struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
+	struct v4l2_async_connection *asd;
+	struct fwnode_handle *ep;
+	int ret;
+
+	/* Get bus characteristics from devicetree */
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csidev->dev), 0, 0,
+					     FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!ep) {
+		dev_err(csidev->dev, "Could not find the endpoint\n");
+		return -ENODEV;
+	}
+
+	ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
+	fwnode_handle_put(ep);
+	if (ret) {
+		dev_err(csidev->dev, "Could not parse v4l2 endpoint\n");
+		return ret;
+	}
+
+	csidev->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
+	if (csidev->num_lanes > STM32_CSI_LANES_MAX) {
+		dev_err(csidev->dev, "Unsupported number of data-lanes: %d\n",
+			csidev->num_lanes);
+		return -EINVAL;
+	}
+
+	memcpy(csidev->lanes, v4l2_ep.bus.mipi_csi2.data_lanes,
+	       sizeof(csidev->lanes));
+
+	ep = fwnode_graph_get_next_endpoint(dev_fwnode(csidev->dev), NULL);
+	if (!ep) {
+		dev_err(csidev->dev, "Failed to get next endpoint\n");
+		return -EINVAL;
+	}
+
+	v4l2_async_subdev_nf_init(&csidev->notifier, &csidev->sd);
+
+	asd = v4l2_async_nf_add_fwnode_remote(&csidev->notifier, ep,
+					      struct v4l2_async_connection);
+
+	fwnode_handle_put(ep);
+
+	if (IS_ERR(asd)) {
+		dev_err(csidev->dev, "Failed to add fwnode remote subdev\n");
+		return PTR_ERR(asd);
+	}
+
+	csidev->notifier.ops = &stm32_csi_notifier_ops;
+
+	ret = v4l2_async_nf_register(&csidev->notifier);
+	if (ret) {
+		dev_err(csidev->dev, "Failed to register notifier\n");
+		v4l2_async_nf_cleanup(&csidev->notifier);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int stm32_csi_probe(struct platform_device *pdev)
+{
+	struct stm32_csi_dev *csidev;
+	struct reset_control *rstc;
+	int ret;
+
+	csidev = devm_kzalloc(&pdev->dev, sizeof(*csidev), GFP_KERNEL);
+	if (!csidev)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, csidev);
+	csidev->dev = &pdev->dev;
+
+	spin_lock_init(&csidev->slock);
+
+	ret = stm32_csi_get_resources(csidev, pdev);
+	if (ret)
+		goto err_free_priv;
+
+	ret = stm32_csi_parse_dt(csidev);
+	if (ret)
+		goto err_free_priv;
+
+	csidev->sd.owner = THIS_MODULE;
+	csidev->sd.dev = &pdev->dev;
+	csidev->sd.internal_ops = &stm32_csi_subdev_internal_ops;
+	v4l2_subdev_init(&csidev->sd, &stm32_csi_subdev_ops);
+	v4l2_set_subdevdata(&csidev->sd, &pdev->dev);
+	snprintf(csidev->sd.name, sizeof(csidev->sd.name), "%s",
+		 dev_name(&pdev->dev));
+
+	/* Create our media pads */
+	csidev->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	csidev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	csidev->pads[STM32_CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+	csidev->pads[STM32_CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+	ret = media_entity_pads_init(&csidev->sd.entity, STM32_CSI_PAD_MAX,
+				     csidev->pads);
+	if (ret)
+		goto err_cleanup;
+
+	ret = v4l2_subdev_init_finalize(&csidev->sd);
+	if (ret < 0)
+		goto err_cleanup;
+
+	ret = v4l2_async_register_subdev(&csidev->sd);
+	if (ret < 0)
+		goto err_cleanup;
+
+	/* Reset device */
+	rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(rstc)) {
+		ret = dev_err_probe(&pdev->dev, PTR_ERR(rstc),
+				    "Couldn't get reset control\n");
+		goto err_cleanup;
+	}
+
+	ret = reset_control_assert(rstc);
+	if (ret) {
+		ret = dev_err_probe(&pdev->dev, ret,
+				    "Failed to assert the reset line\n");
+		goto err_cleanup;
+	}
+
+	usleep_range(3000, 5000);
+
+	ret = reset_control_deassert(rstc);
+	if (ret) {
+		ret = dev_err_probe(&pdev->dev, ret,
+				    "Failed to deassert the reset line\n");
+		goto err_cleanup;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	dev_info(&pdev->dev,
+		 "Probed CSI with %u lanes\n", csidev->num_lanes);
+
+	return 0;
+
+err_cleanup:
+	v4l2_async_nf_cleanup(&csidev->notifier);
+err_free_priv:
+	return ret;
+}
+
+static void stm32_csi_remove(struct platform_device *pdev)
+{
+	struct stm32_csi_dev *csidev = platform_get_drvdata(pdev);
+
+	v4l2_async_unregister_subdev(&csidev->sd);
+
+	pm_runtime_disable(&pdev->dev);
+}
+
+static int stm32_csi_runtime_suspend(struct device *dev)
+{
+	struct stm32_csi_dev *csidev = dev_get_drvdata(dev);
+	int ret;
+
+	clk_bulk_disable_unprepare(STM32_CSI_CLK_NB, csidev->clks);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(csidev->supplies),
+				     csidev->supplies);
+	if (ret < 0)
+		dev_err(dev, "cannot disable regulators %d\n", ret);
+
+	return 0;
+}
+
+static int stm32_csi_runtime_resume(struct device *dev)
+{
+	struct stm32_csi_dev *csidev = dev_get_drvdata(dev);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(csidev->supplies),
+				    csidev->supplies);
+	if (ret)
+		goto error_out;
+
+	ret = clk_bulk_prepare_enable(STM32_CSI_CLK_NB, csidev->clks);
+	if (ret)
+		goto error_disable_supplies;
+
+	return 0;
+
+error_disable_supplies:
+	ret = regulator_bulk_disable(ARRAY_SIZE(csidev->supplies), csidev->supplies);
+	if (ret < 0)
+		dev_err(dev, "cannot disable regulators %d\n", ret);
+error_out:
+	dev_err(csidev->dev, "Failed to resume: %d\n", ret);
+
+	return ret;
+}
+
+static const struct of_device_id stm32_csi_of_table[] = {
+	{ .compatible = "st,stm32mp25-csi", },
+	{ /* end node */ },
+};
+MODULE_DEVICE_TABLE(of, stm32_csi_of_table);
+
+static const struct dev_pm_ops stm32_csi_pm_ops = {
+	RUNTIME_PM_OPS(stm32_csi_runtime_suspend,
+		       stm32_csi_runtime_resume, NULL)
+};
+
+static struct platform_driver stm32_csi_driver = {
+	.driver	= {
+		.name = "stm32-csi",
+		.of_match_table = stm32_csi_of_table,
+		.pm = pm_ptr(&stm32_csi_pm_ops),
+	},
+	.probe	= stm32_csi_probe,
+	.remove = stm32_csi_remove,
+};
+
+module_platform_driver(stm32_csi_driver);
+
+MODULE_AUTHOR("Alain Volmat <alain.volmat at foss.st.com>");
+MODULE_DESCRIPTION("STM32 CSI controller");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:25 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:25 +0100
Subject: [PATCH v4 01/15] media: stm32: dcmipp: correct
 dma_set_mask_and_coherent mask value
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-1-fbeb55a05ed7@foss.st.com>

Correct the call to dma_set_mask_and_coherent which should be set
to DMA_BIT_MASK(32).

Fixes: 28e0f3772296 ("media: stm32-dcmipp: STM32 DCMIPP camera interface driver")
Cc: stable at vger.kernel.org
Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
index 7edd49bfe7e5..7f9fa79402df 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
@@ -887,7 +887,7 @@ struct dcmipp_ent_device *dcmipp_bytecap_ent_init(struct device *dev,
 	q->dev = dev;
 
 	/* DCMIPP requires 16 bytes aligned buffers */
-	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32) & ~0x0f);
+	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 	if (ret) {
 		dev_err(dev, "Failed to set DMA mask\n");
 		goto err_mutex_destroy;

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:36 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:36 +0100
Subject: [PATCH v4 12/15] dt-bindings: media: add the stm32mp25 compatible
 of DCMIPP
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-12-fbeb55a05ed7@foss.st.com>

Add the stm32mp25 compatible for the DCMIPP.
The stm32mp25 distinguish with the stm32mp13 by the fact that:
 - supports also csi inputs in addition to parallel inputs
 - requires an addition csi clock to be present

Add also access-controllers, an optional property that
allows a peripheral to refer to one or more domain access controller(s).

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
v2:
  - move allOf after required
  - reword commit message
---
 .../devicetree/bindings/media/st,stm32-dcmipp.yaml | 53 +++++++++++++++++++---
 1 file changed, 47 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/st,stm32-dcmipp.yaml b/Documentation/devicetree/bindings/media/st,stm32-dcmipp.yaml
index 87731f3ce7bd..7b03a77adbce 100644
--- a/Documentation/devicetree/bindings/media/st,stm32-dcmipp.yaml
+++ b/Documentation/devicetree/bindings/media/st,stm32-dcmipp.yaml
@@ -12,7 +12,9 @@ maintainers:
 
 properties:
   compatible:
-    const: st,stm32mp13-dcmipp
+    enum:
+      - st,stm32mp13-dcmipp
+      - st,stm32mp25-dcmipp
 
   reg:
     maxItems: 1
@@ -21,11 +23,24 @@ properties:
     maxItems: 1
 
   clocks:
-    maxItems: 1
+    items:
+      - description: bus clock
+      - description: csi clock
+    minItems: 1
+
+  clock-names:
+    items:
+      - const: kclk
+      - const: mclk
+    minItems: 1
 
   resets:
     maxItems: 1
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
   port:
     $ref: /schemas/graph.yaml#/$defs/port-base
     unevaluatedProperties: false
@@ -39,7 +54,7 @@ properties:
 
         properties:
           bus-type:
-            enum: [5, 6]
+            enum: [4, 5, 6]
             default: 5
 
           bus-width:
@@ -50,9 +65,6 @@ properties:
           hsync-active: true
           vsync-active: true
 
-        required:
-          - pclk-sample
-
 required:
   - compatible
   - reg
@@ -61,6 +73,35 @@ required:
   - resets
   - port
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - st,stm32mp13-dcmipp
+    then:
+      properties:
+        clocks:
+          maxItems: 1
+
+        clock-names:
+          maxItems: 1
+
+        port:
+          properties:
+            endpoint:
+              properties:
+                bus-type:
+                  enum: [5, 6]
+    else:
+      properties:
+        clocks:
+          minItems: 2
+
+        clock-names:
+          minItems: 2
+
 additionalProperties: false
 
 examples:

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:32 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:32 +0100
Subject: [PATCH v4 08/15] media: stm32: dcmipp: add bayer 10~14 bits
 formats
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-8-fbeb55a05ed7@foss.st.com>

Add support for bayer formats from 10 to 14 bits.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 .../media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c    | 12 ++++++++++++
 .../media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c   | 12 ++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
index 209693e8296e..6596902a1760 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
@@ -65,6 +65,18 @@ static const struct dcmipp_bytecap_pix_map dcmipp_bytecap_pix_map_list[] = {
 	PIXMAP_MBUS_PFMT(SGBRG8_1X8, SGBRG8),
 	PIXMAP_MBUS_PFMT(SGRBG8_1X8, SGRBG8),
 	PIXMAP_MBUS_PFMT(SRGGB8_1X8, SRGGB8),
+	PIXMAP_MBUS_PFMT(SBGGR10_1X10, SBGGR10),
+	PIXMAP_MBUS_PFMT(SGBRG10_1X10, SGBRG10),
+	PIXMAP_MBUS_PFMT(SGRBG10_1X10, SGRBG10),
+	PIXMAP_MBUS_PFMT(SRGGB10_1X10, SRGGB10),
+	PIXMAP_MBUS_PFMT(SBGGR12_1X12, SBGGR12),
+	PIXMAP_MBUS_PFMT(SGBRG12_1X12, SGBRG12),
+	PIXMAP_MBUS_PFMT(SGRBG12_1X12, SGRBG12),
+	PIXMAP_MBUS_PFMT(SRGGB12_1X12, SRGGB12),
+	PIXMAP_MBUS_PFMT(SBGGR14_1X14, SBGGR14),
+	PIXMAP_MBUS_PFMT(SGBRG14_1X14, SGBRG14),
+	PIXMAP_MBUS_PFMT(SGRBG14_1X14, SGRBG14),
+	PIXMAP_MBUS_PFMT(SRGGB14_1X14, SRGGB14),
 	PIXMAP_MBUS_PFMT(JPEG_1X8, JPEG),
 };
 
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
index a19c8235af56..72f1bb4c64ad 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
@@ -57,6 +57,18 @@ static const struct dcmipp_byteproc_pix_map dcmipp_byteproc_pix_map_list[] = {
 	PIXMAP_MBUS_BPP(SGBRG8_1X8, 1),
 	PIXMAP_MBUS_BPP(SGRBG8_1X8, 1),
 	PIXMAP_MBUS_BPP(SRGGB8_1X8, 1),
+	PIXMAP_MBUS_BPP(SBGGR10_1X10, 2),
+	PIXMAP_MBUS_BPP(SGBRG10_1X10, 2),
+	PIXMAP_MBUS_BPP(SGRBG10_1X10, 2),
+	PIXMAP_MBUS_BPP(SRGGB10_1X10, 2),
+	PIXMAP_MBUS_BPP(SBGGR12_1X12, 2),
+	PIXMAP_MBUS_BPP(SGBRG12_1X12, 2),
+	PIXMAP_MBUS_BPP(SGRBG12_1X12, 2),
+	PIXMAP_MBUS_BPP(SRGGB12_1X12, 2),
+	PIXMAP_MBUS_BPP(SBGGR14_1X14, 2),
+	PIXMAP_MBUS_BPP(SGBRG14_1X14, 2),
+	PIXMAP_MBUS_BPP(SGRBG14_1X14, 2),
+	PIXMAP_MBUS_BPP(SRGGB14_1X14, 2),
 	PIXMAP_MBUS_BPP(JPEG_1X8, 1),
 };
 

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:29 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:29 +0100
Subject: [PATCH v4 05/15] media: stm32: dcmipp: replace s_stream with
 enable/disable_streams
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-5-fbeb55a05ed7@foss.st.com>

Replace s_stream ops with enable_streams and disable_streams.
At the same time, use v4l2_subdev_enable_streams and
v4l2_subdev_disable_streams functions instead of
direct s_stream calls.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>

---
v2: add missing state argument within dcmipp_par_configure call
---
 .../st/stm32/stm32-dcmipp/dcmipp-bytecap.c         |  49 ++++------
 .../st/stm32/stm32-dcmipp/dcmipp-byteproc.c        |  98 +++++++++++--------
 .../st/stm32/stm32-dcmipp/dcmipp-parallel.c        | 107 ++++++++++++---------
 3 files changed, 139 insertions(+), 115 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
index 7f9fa79402df..209693e8296e 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
@@ -112,6 +112,7 @@ struct dcmipp_bytecap_device {
 	u32 sequence;
 	struct media_pipeline pipe;
 	struct v4l2_subdev *s_subdev;
+	u32 s_subdev_pad_nb;
 
 	enum dcmipp_state state;
 
@@ -337,33 +338,6 @@ static const struct v4l2_ioctl_ops dcmipp_bytecap_ioctl_ops = {
 	.vidioc_streamoff = vb2_ioctl_streamoff,
 };
 
-static int dcmipp_pipeline_s_stream(struct dcmipp_bytecap_device *vcap,
-				    int state)
-{
-	struct media_pad *pad;
-	int ret;
-
-	/*
-	 * Get source subdev - since link is IMMUTABLE, pointer is cached
-	 * within the dcmipp_bytecap_device structure
-	 */
-	if (!vcap->s_subdev) {
-		pad = media_pad_remote_pad_first(&vcap->vdev.entity.pads[0]);
-		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-			return -EINVAL;
-		vcap->s_subdev = media_entity_to_v4l2_subdev(pad->entity);
-	}
-
-	ret = v4l2_subdev_call(vcap->s_subdev, video, s_stream, state);
-	if (ret < 0) {
-		dev_err(vcap->dev, "failed to %s streaming (%d)\n",
-			state ? "start" : "stop", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
 static void dcmipp_start_capture(struct dcmipp_bytecap_device *vcap,
 				 struct dcmipp_buf *buf)
 {
@@ -395,11 +369,24 @@ static int dcmipp_bytecap_start_streaming(struct vb2_queue *vq,
 	struct dcmipp_bytecap_device *vcap = vb2_get_drv_priv(vq);
 	struct media_entity *entity = &vcap->vdev.entity;
 	struct dcmipp_buf *buf;
+	struct media_pad *pad;
 	int ret;
 
 	vcap->sequence = 0;
 	memset(&vcap->count, 0, sizeof(vcap->count));
 
+	/*
+	 * Get source subdev - since link is IMMUTABLE, pointer is cached
+	 * within the dcmipp_bytecap_device structure
+	 */
+	if (!vcap->s_subdev) {
+		pad = media_pad_remote_pad_first(&vcap->vdev.entity.pads[0]);
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+			return -EINVAL;
+		vcap->s_subdev = media_entity_to_v4l2_subdev(pad->entity);
+		vcap->s_subdev_pad_nb = pad->index;
+	}
+
 	ret = pm_runtime_resume_and_get(vcap->dev);
 	if (ret < 0) {
 		dev_err(vcap->dev, "%s: Failed to start streaming, cannot get sync (%d)\n",
@@ -414,7 +401,8 @@ static int dcmipp_bytecap_start_streaming(struct vb2_queue *vq,
 		goto err_pm_put;
 	}
 
-	ret = dcmipp_pipeline_s_stream(vcap, 1);
+	ret = v4l2_subdev_enable_streams(vcap->s_subdev,
+					 vcap->s_subdev_pad_nb, BIT_ULL(0));
 	if (ret)
 		goto err_media_pipeline_stop;
 
@@ -482,7 +470,10 @@ static void dcmipp_bytecap_stop_streaming(struct vb2_queue *vq)
 	int ret;
 	u32 status;
 
-	dcmipp_pipeline_s_stream(vcap, 0);
+	ret = v4l2_subdev_disable_streams(vcap->s_subdev,
+					  vcap->s_subdev_pad_nb, BIT_ULL(0));
+	if (ret)
+		dev_warn(vcap->dev, "Failed to disable stream\n");
 
 	/* Stop the media pipeline */
 	media_pipeline_stop(vcap->vdev.entity.pads);
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
index 50500112eab9..a19c8235af56 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
@@ -380,30 +380,19 @@ static int dcmipp_byteproc_set_selection(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static const struct v4l2_subdev_pad_ops dcmipp_byteproc_pad_ops = {
-	.enum_mbus_code		= dcmipp_byteproc_enum_mbus_code,
-	.enum_frame_size	= dcmipp_byteproc_enum_frame_size,
-	.get_fmt		= v4l2_subdev_get_fmt,
-	.set_fmt		= dcmipp_byteproc_set_fmt,
-	.get_selection		= dcmipp_byteproc_get_selection,
-	.set_selection		= dcmipp_byteproc_set_selection,
-};
-
 static int dcmipp_byteproc_configure_scale_crop
-			(struct dcmipp_byteproc_device *byteproc)
+			(struct dcmipp_byteproc_device *byteproc,
+			 struct v4l2_subdev_state *state)
 {
 	const struct dcmipp_byteproc_pix_map *vpix;
-	struct v4l2_subdev_state *state;
 	struct v4l2_mbus_framefmt *sink_fmt;
 	u32 hprediv, vprediv;
 	struct v4l2_rect *compose, *crop;
 	u32 val = 0;
 
-	state = v4l2_subdev_lock_and_get_active_state(&byteproc->sd);
 	sink_fmt = v4l2_subdev_state_get_format(state, 0);
 	compose = v4l2_subdev_state_get_compose(state, 0);
 	crop = v4l2_subdev_state_get_crop(state, 1);
-	v4l2_subdev_unlock_state(state);
 
 	/* find output format bpp */
 	vpix = dcmipp_byteproc_pix_map_by_code(sink_fmt->code);
@@ -458,46 +447,73 @@ static int dcmipp_byteproc_configure_scale_crop
 	return 0;
 }
 
-static int dcmipp_byteproc_s_stream(struct v4l2_subdev *sd, int enable)
+static int dcmipp_byteproc_enable_streams(struct v4l2_subdev *sd,
+					  struct v4l2_subdev_state *state,
+					  u32 pad, u64 streams_mask)
 {
 	struct dcmipp_byteproc_device *byteproc = v4l2_get_subdevdata(sd);
 	struct v4l2_subdev *s_subdev;
-	struct media_pad *pad;
-	int ret = 0;
+	struct media_pad *s_pad;
+	int ret;
 
 	/* Get source subdev */
-	pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
-	if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+	s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
+	if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity))
 		return -EINVAL;
-	s_subdev = media_entity_to_v4l2_subdev(pad->entity);
-
-	if (enable) {
-		ret = dcmipp_byteproc_configure_scale_crop(byteproc);
-		if (ret)
-			return ret;
-
-		ret = v4l2_subdev_call(s_subdev, video, s_stream, enable);
-		if (ret < 0) {
-			dev_err(byteproc->dev,
-				"failed to start source subdev streaming (%d)\n",
-				ret);
-			return ret;
-		}
-	} else {
-		ret = v4l2_subdev_call(s_subdev, video, s_stream, enable);
-		if (ret < 0) {
-			dev_err(byteproc->dev,
-				"failed to stop source subdev streaming (%d)\n",
-				ret);
-			return ret;
-		}
+	s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
+
+	ret = dcmipp_byteproc_configure_scale_crop(byteproc, state);
+	if (ret)
+		return ret;
+
+	ret = v4l2_subdev_enable_streams(s_subdev, s_pad->index, BIT_ULL(0));
+	if (ret < 0) {
+		dev_err(byteproc->dev,
+			"failed to start source subdev streaming (%d)\n", ret);
+		return ret;
 	}
 
 	return 0;
 }
 
+static int dcmipp_byteproc_disable_streams(struct v4l2_subdev *sd,
+					   struct v4l2_subdev_state *state,
+					   u32 pad, u64 streams_mask)
+{
+	struct dcmipp_byteproc_device *byteproc = v4l2_get_subdevdata(sd);
+	struct v4l2_subdev *s_subdev;
+	struct media_pad *s_pad;
+	int ret;
+
+	/* Get source subdev */
+	s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
+	if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity))
+		return -EINVAL;
+	s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
+
+	ret = v4l2_subdev_disable_streams(s_subdev, s_pad->index, BIT_ULL(0));
+	if (ret < 0) {
+		dev_err(byteproc->dev,
+			"failed to start source subdev streaming (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops dcmipp_byteproc_pad_ops = {
+	.enum_mbus_code		= dcmipp_byteproc_enum_mbus_code,
+	.enum_frame_size	= dcmipp_byteproc_enum_frame_size,
+	.get_fmt		= v4l2_subdev_get_fmt,
+	.set_fmt		= dcmipp_byteproc_set_fmt,
+	.get_selection		= dcmipp_byteproc_get_selection,
+	.set_selection		= dcmipp_byteproc_set_selection,
+	.enable_streams		= dcmipp_byteproc_enable_streams,
+	.disable_streams	= dcmipp_byteproc_disable_streams,
+};
+
 static const struct v4l2_subdev_video_ops dcmipp_byteproc_video_ops = {
-	.s_stream = dcmipp_byteproc_s_stream,
+	.s_stream = v4l2_subdev_s_stream_helper,
 };
 
 static const struct v4l2_subdev_ops dcmipp_byteproc_ops = {
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c
index 05e8897ae37a..823c9da336a7 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c
@@ -260,18 +260,11 @@ static int dcmipp_par_set_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static const struct v4l2_subdev_pad_ops dcmipp_par_pad_ops = {
-	.enum_mbus_code		= dcmipp_par_enum_mbus_code,
-	.enum_frame_size	= dcmipp_par_enum_frame_size,
-	.get_fmt		= v4l2_subdev_get_fmt,
-	.set_fmt		= dcmipp_par_set_fmt,
-};
-
-static int dcmipp_par_configure(struct dcmipp_par_device *par)
+static int dcmipp_par_configure(struct dcmipp_par_device *par,
+				struct v4l2_subdev_state *state)
 {
 	u32 val = 0;
 	const struct dcmipp_par_pix_map *vpix;
-	struct v4l2_subdev_state *state;
 	struct v4l2_mbus_framefmt *sink_fmt;
 	struct v4l2_mbus_framefmt *src_fmt;
 
@@ -305,10 +298,8 @@ static int dcmipp_par_configure(struct dcmipp_par_device *par)
 	}
 
 	/* Set format */
-	state = v4l2_subdev_lock_and_get_active_state(&par->sd);
 	sink_fmt = v4l2_subdev_state_get_format(state, 0);
 	src_fmt = v4l2_subdev_state_get_format(state, 1);
-	v4l2_subdev_unlock_state(state);
 
 	vpix = dcmipp_par_pix_map_by_code(sink_fmt->code, src_fmt->code);
 	if (!vpix) {
@@ -327,53 +318,79 @@ static int dcmipp_par_configure(struct dcmipp_par_device *par)
 	return 0;
 }
 
-static int dcmipp_par_s_stream(struct v4l2_subdev *sd, int enable)
+static int dcmipp_par_enable_streams(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *state,
+				     u32 pad, u64 streams_mask)
 {
 	struct dcmipp_par_device *par =
 				container_of(sd, struct dcmipp_par_device, sd);
 	struct v4l2_subdev *s_subdev;
-	struct media_pad *pad;
-	int ret = 0;
+	struct media_pad *s_pad;
+	int ret;
 
 	/* Get source subdev */
-	pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
-	if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+	s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
+	if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity))
 		return -EINVAL;
-	s_subdev = media_entity_to_v4l2_subdev(pad->entity);
-
-	if (enable) {
-		ret = dcmipp_par_configure(par);
-		if (ret)
-			return ret;
-
-		/* Enable parallel interface */
-		reg_set(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
-
-		ret = v4l2_subdev_call(s_subdev, video, s_stream, enable);
-		if (ret < 0) {
-			dev_err(par->dev,
-				"failed to start source subdev streaming (%d)\n",
-				ret);
-			return ret;
-		}
-	} else {
-		ret = v4l2_subdev_call(s_subdev, video, s_stream, enable);
-		if (ret < 0) {
-			dev_err(par->dev,
-				"failed to stop source subdev streaming (%d)\n",
-				ret);
-			return ret;
-		}
+	s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
+
+	ret = dcmipp_par_configure(par, state);
+	if (ret)
+		return ret;
+
+	/* Enable parallel interface */
+	reg_set(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
 
-		/* Disable parallel interface */
-		reg_clear(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
+	ret = v4l2_subdev_enable_streams(s_subdev, s_pad->index, BIT_ULL(0));
+	if (ret < 0) {
+		dev_err(par->dev,
+			"failed to start source subdev streaming (%d)\n", ret);
+		return ret;
 	}
 
-	return ret;
+	return 0;
 }
 
+static int dcmipp_par_disable_streams(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_state *state,
+				      u32 pad, u64 streams_mask)
+{
+	struct dcmipp_par_device *par =
+				container_of(sd, struct dcmipp_par_device, sd);
+	struct v4l2_subdev *s_subdev;
+	struct media_pad *s_pad;
+	int ret;
+
+	/* Get source subdev */
+	s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
+	if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity))
+		return -EINVAL;
+	s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
+
+	ret = v4l2_subdev_disable_streams(s_subdev, s_pad->index, BIT_ULL(0));
+	if (ret < 0) {
+		dev_err(par->dev,
+			"failed to stop source subdev streaming (%d)\n", ret);
+		return ret;
+	}
+
+	/* Disable parallel interface */
+	reg_clear(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
+
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops dcmipp_par_pad_ops = {
+	.enum_mbus_code		= dcmipp_par_enum_mbus_code,
+	.enum_frame_size	= dcmipp_par_enum_frame_size,
+	.get_fmt		= v4l2_subdev_get_fmt,
+	.set_fmt		= dcmipp_par_set_fmt,
+	.enable_streams		= dcmipp_par_enable_streams,
+	.disable_streams	= dcmipp_par_disable_streams,
+};
+
 static const struct v4l2_subdev_video_ops dcmipp_par_video_ops = {
-	.s_stream = dcmipp_par_s_stream,
+	.s_stream = v4l2_subdev_s_stream_helper,
 };
 
 static const struct v4l2_subdev_ops dcmipp_par_ops = {

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:26 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:26 +0100
Subject: [PATCH v4 02/15] dt-bindings: media: add description of stm32 csi
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-2-fbeb55a05ed7@foss.st.com>

Add the stm32 csi controller description.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
v2:
  - rename into st,stm32mp25-csi.yaml to match compatible
  - correct port / data-lanes (remove useless lines &
    use data-lanes 1 and 2 instead of 0 and 1)
  - correct commit log
---
 .../bindings/media/st,stm32mp25-csi.yaml           | 125 +++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
new file mode 100644
index 000000000000..33bedfe41924
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
@@ -0,0 +1,125 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/st,stm32mp25-csi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32 CSI controller
+
+description:
+  The STM32 CSI controller allows connecting a CSI based
+  camera to the DCMIPP camera pipeline.
+
+maintainers:
+  - Alain Volmat <alain.volmat at foss.st.com>
+
+properties:
+  compatible:
+    enum:
+      - st,stm32mp25-csi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 3
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: txesc
+      - const: csi2phy
+
+  resets:
+    maxItems: 1
+
+  vdd-supply:
+    description: Digital core power supply (0.91V)
+
+  vdda18-supply:
+    description: System analog power supply (1.8V)
+
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port node
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                items:
+                  - const: 1
+                  - const: 2
+
+            required:
+              - data-lanes
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port node
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/media/video-interfaces.h>
+    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+    csi at 48020000 {
+        compatible = "st,stm32mp25-csi";
+        reg = <0x48020000 0x2000>;
+        interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+        resets = <&rcc CSI_R>;
+        clocks = <&rcc CK_KER_CSI>, <&rcc CK_KER_CSITXESC>, <&rcc CK_KER_CSIPHY>;
+        clock-names = "pclk", "txesc", "csi2phy";
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            port at 0 {
+                reg = <0>;
+                endpoint {
+                    remote-endpoint = <&imx335_ep>;
+                    data-lanes = <1 2>;
+                    bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+                endpoint {
+                    remote-endpoint = <&dcmipp_0>;
+                };
+            };
+        };
+    };
+
+...

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:31 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:31 +0100
Subject: [PATCH v4 07/15] media: stm32: dcmipp: add support for csi input
 into dcmipp-input
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-7-fbeb55a05ed7@foss.st.com>

On stm32mp25, the dcmipp can accept data coming from a CSI bus in
addition to the parallel interface.  Add this support into
dcmipp-input subdev.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 .../platform/st/stm32/stm32-dcmipp/dcmipp-input.c  | 134 +++++++++++++++++----
 1 file changed, 110 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c
index 689eb4c72e18..7e5311b67d7e 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/v4l2-mediabus.h>
+#include <media/mipi-csi2.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-subdev.h>
 
@@ -19,6 +20,9 @@
 #define DCMIPP_PRCR_FORMAT_YUV422	0x1e
 #define DCMIPP_PRCR_FORMAT_RGB565	0x22
 #define DCMIPP_PRCR_FORMAT_RAW8		0x2a
+#define DCMIPP_PRCR_FORMAT_RAW10	0x2b
+#define DCMIPP_PRCR_FORMAT_RAW12	0x2c
+#define DCMIPP_PRCR_FORMAT_RAW14	0x2d
 #define DCMIPP_PRCR_FORMAT_G8		0x4a
 #define DCMIPP_PRCR_FORMAT_BYTE_STREAM	0x5a
 #define DCMIPP_PRCR_ESS			BIT(4)
@@ -31,43 +35,75 @@
 #define DCMIPP_PRESCR	0x108
 #define DCMIPP_PRESUR	0x10c
 
+#define DCMIPP_CMCR	0x204
+#define DCMIPP_CMCR_INSEL	BIT(0)
+
+#define DCMIPP_P0FSCR	0x404
+#define DCMIPP_P0FSCR_DTMODE_MASK	GENMASK(17, 16)
+#define DCMIPP_P0FSCR_DTMODE_SHIFT	16
+#define DCMIPP_P0FSCR_DTMODE_DTIDA	0x00
+#define DCMIPP_P0FSCR_DTMODE_ALLDT	0x03
+#define DCMIPP_P0FSCR_DTIDA_MASK	GENMASK(5, 0)
+#define DCMIPP_P0FSCR_DTIDA_SHIFT	0
+
 #define IS_SINK(pad) (!(pad))
 #define IS_SRC(pad)  ((pad))
 
 struct dcmipp_inp_pix_map {
 	unsigned int code_sink;
 	unsigned int code_src;
+	/* Parallel related information */
 	u8 prcr_format;
 	u8 prcr_swapcycles;
+	/* CSI related information */
+	unsigned int dt;
 };
 
-#define PIXMAP_SINK_SRC_PRCR_SWAP(sink, src, prcr, swap)	\
+#define PIXMAP_SINK_SRC_PRCR_SWAP(sink, src, prcr, swap, data_type)	\
 	{							\
 		.code_sink = MEDIA_BUS_FMT_##sink,		\
 		.code_src = MEDIA_BUS_FMT_##src,		\
 		.prcr_format = DCMIPP_PRCR_FORMAT_##prcr,	\
 		.prcr_swapcycles = swap,			\
+		.dt = data_type,				\
 	}
 static const struct dcmipp_inp_pix_map dcmipp_inp_pix_map_list[] = {
 	/* RGB565 */
-	PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_LE, RGB565_2X8_LE, RGB565, 1),
-	PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_BE, RGB565_2X8_LE, RGB565, 0),
+	PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_LE, RGB565_2X8_LE, RGB565, 1, MIPI_CSI2_DT_RGB565),
+	PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_BE, RGB565_2X8_LE, RGB565, 0, MIPI_CSI2_DT_RGB565),
+	PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_1X16, RGB565_1X16, RGB565, 0, MIPI_CSI2_DT_RGB565),
 	/* YUV422 */
-	PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, YUYV8_2X8, YUV422, 1),
-	PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, UYVY8_2X8, YUV422, 0),
-	PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, UYVY8_2X8, YUV422, 1),
-	PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, YUYV8_2X8, YUV422, 0),
-	PIXMAP_SINK_SRC_PRCR_SWAP(YVYU8_2X8, YVYU8_2X8, YUV422, 1),
-	PIXMAP_SINK_SRC_PRCR_SWAP(VYUY8_2X8, VYUY8_2X8, YUV422, 1),
+	PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, YUYV8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B),
+	PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_1X16, YUYV8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B),
+	PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, UYVY8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B),
+	PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, UYVY8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B),
+	PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_1X16, UYVY8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B),
+	PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, YUYV8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B),
+	PIXMAP_SINK_SRC_PRCR_SWAP(YVYU8_2X8, YVYU8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B),
+	PIXMAP_SINK_SRC_PRCR_SWAP(YVYU8_1X16, YVYU8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B),
+	PIXMAP_SINK_SRC_PRCR_SWAP(VYUY8_2X8, VYUY8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B),
+	PIXMAP_SINK_SRC_PRCR_SWAP(VYUY8_1X16, VYUY8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B),
 	/* GREY */
-	PIXMAP_SINK_SRC_PRCR_SWAP(Y8_1X8, Y8_1X8, G8, 0),
+	PIXMAP_SINK_SRC_PRCR_SWAP(Y8_1X8, Y8_1X8, G8, 0, MIPI_CSI2_DT_RAW8),
 	/* Raw Bayer */
-	PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR8_1X8, SBGGR8_1X8, RAW8, 0),
-	PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG8_1X8, SGBRG8_1X8, RAW8, 0),
-	PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG8_1X8, SGRBG8_1X8, RAW8, 0),
-	PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB8_1X8, SRGGB8_1X8, RAW8, 0),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR8_1X8, SBGGR8_1X8, RAW8, 0, MIPI_CSI2_DT_RAW8),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG8_1X8, SGBRG8_1X8, RAW8, 0, MIPI_CSI2_DT_RAW8),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG8_1X8, SGRBG8_1X8, RAW8, 0, MIPI_CSI2_DT_RAW8),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB8_1X8, SRGGB8_1X8, RAW8, 0, MIPI_CSI2_DT_RAW8),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR10_1X10, SBGGR10_1X10, RAW10, 0, MIPI_CSI2_DT_RAW10),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG10_1X10, SGBRG10_1X10, RAW10, 0, MIPI_CSI2_DT_RAW10),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG10_1X10, SGRBG10_1X10, RAW10, 0, MIPI_CSI2_DT_RAW10),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB10_1X10, SRGGB10_1X10, RAW10, 0, MIPI_CSI2_DT_RAW10),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR12_1X12, SBGGR12_1X12, RAW12, 0, MIPI_CSI2_DT_RAW12),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG12_1X12, SGBRG12_1X12, RAW12, 0, MIPI_CSI2_DT_RAW12),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG12_1X12, SGRBG12_1X12, RAW12, 0, MIPI_CSI2_DT_RAW12),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB12_1X12, SRGGB12_1X12, RAW12, 0, MIPI_CSI2_DT_RAW12),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR14_1X14, SBGGR14_1X14, RAW14, 0, MIPI_CSI2_DT_RAW14),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG14_1X14, SGBRG14_1X14, RAW14, 0, MIPI_CSI2_DT_RAW14),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG14_1X14, SGRBG14_1X14, RAW14, 0, MIPI_CSI2_DT_RAW14),
+	PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB14_1X14, SRGGB14_1X14, RAW14, 0, MIPI_CSI2_DT_RAW14),
 	/* JPEG */
-	PIXMAP_SINK_SRC_PRCR_SWAP(JPEG_1X8, JPEG_1X8, BYTE_STREAM, 0),
+	PIXMAP_SINK_SRC_PRCR_SWAP(JPEG_1X8, JPEG_1X8, BYTE_STREAM, 0, 0),
 };
 
 /*
@@ -260,8 +296,8 @@ static int dcmipp_inp_set_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int dcmipp_inp_configure(struct dcmipp_inp_device *inp,
-				struct v4l2_subdev_state *state)
+static int dcmipp_inp_configure_parallel(struct dcmipp_inp_device *inp,
+					 struct v4l2_subdev_state *state)
 {
 	u32 val = 0;
 	const struct dcmipp_inp_pix_map *vpix;
@@ -315,6 +351,52 @@ static int dcmipp_inp_configure(struct dcmipp_inp_device *inp,
 
 	reg_write(inp, DCMIPP_PRCR, val);
 
+	/* Select the DCMIPP parallel interface */
+	reg_write(inp, DCMIPP_CMCR, 0);
+
+	/* Enable parallel interface */
+	reg_set(inp, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
+
+	return 0;
+}
+
+static int dcmipp_inp_configure_csi(struct dcmipp_inp_device *inp,
+				    struct v4l2_subdev_state *state)
+{
+	const struct dcmipp_inp_pix_map *vpix;
+	struct v4l2_mbus_framefmt *sink_fmt;
+	struct v4l2_mbus_framefmt *src_fmt;
+
+	/* Get format information */
+	sink_fmt = v4l2_subdev_state_get_format(state, 0);
+	src_fmt = v4l2_subdev_state_get_format(state, 1);
+
+	vpix = dcmipp_inp_pix_map_by_code(sink_fmt->code, src_fmt->code);
+	if (!vpix) {
+		dev_err(inp->dev, "Invalid sink/src format configuration\n");
+		return -EINVAL;
+	}
+
+	/* Apply configuration on each input pipe */
+	reg_clear(inp, DCMIPP_P0FSCR,
+		  DCMIPP_P0FSCR_DTMODE_MASK | DCMIPP_P0FSCR_DTIDA_MASK);
+
+	/* In case of JPEG we don't know the DT so we allow all data */
+	/*
+	 * TODO - check instead dt == 0 for the time being to allow other
+	 * unknown data-type
+	 */
+	if (!vpix->dt)
+		reg_set(inp, DCMIPP_P0FSCR,
+			DCMIPP_P0FSCR_DTMODE_ALLDT << DCMIPP_P0FSCR_DTMODE_SHIFT);
+	else
+		reg_set(inp, DCMIPP_P0FSCR,
+			vpix->dt << DCMIPP_P0FSCR_DTIDA_SHIFT |
+			DCMIPP_P0FSCR_DTMODE_DTIDA);
+
+	/* Select the DCMIPP CSI interface */
+	reg_write(inp, DCMIPP_CMCR, DCMIPP_CMCR_INSEL);
+
 	return 0;
 }
 
@@ -326,7 +408,7 @@ static int dcmipp_inp_enable_streams(struct v4l2_subdev *sd,
 				container_of(sd, struct dcmipp_inp_device, sd);
 	struct v4l2_subdev *s_subdev;
 	struct media_pad *s_pad;
-	int ret;
+	int ret = 0;
 
 	/* Get source subdev */
 	s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
@@ -334,13 +416,14 @@ static int dcmipp_inp_enable_streams(struct v4l2_subdev *sd,
 		return -EINVAL;
 	s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
 
-	ret = dcmipp_inp_configure(inp, state);
+	if (inp->ved.bus_type == V4L2_MBUS_PARALLEL ||
+	    inp->ved.bus_type == V4L2_MBUS_BT656)
+		ret = dcmipp_inp_configure_parallel(inp, state);
+	else if (inp->ved.bus_type == V4L2_MBUS_CSI2_DPHY)
+		ret = dcmipp_inp_configure_csi(inp, state);
 	if (ret)
 		return ret;
 
-	/* Enable parallel interface */
-	reg_set(inp, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
-
 	ret = v4l2_subdev_enable_streams(s_subdev, s_pad->index, BIT_ULL(0));
 	if (ret < 0) {
 		dev_err(inp->dev,
@@ -374,8 +457,11 @@ static int dcmipp_inp_disable_streams(struct v4l2_subdev *sd,
 		return ret;
 	}
 
-	/* Disable parallel interface */
-	reg_clear(inp, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
+	if (inp->ved.bus_type == V4L2_MBUS_PARALLEL ||
+	    inp->ved.bus_type == V4L2_MBUS_BT656) {
+		/* Disable parallel interface */
+		reg_clear(inp, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
+	}
 
 	return 0;
 }

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:30 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:30 +0100
Subject: [PATCH v4 06/15] media: stm32: dcmipp: rename dcmipp_parallel into
 dcmipp_input
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-6-fbeb55a05ed7@foss.st.com>

In preparation of the introduction of dcmipp csi input support, rename
the dcmipp_parallel subdev into a generic dcmipp_input which will be in
charge of handling both parallel input & csi input.
Only structures / variables / functions and file naming are changed without
any functional modifications.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 .../media/platform/st/stm32/stm32-dcmipp/Makefile  |   2 +-
 .../platform/st/stm32/stm32-dcmipp/dcmipp-common.h |   4 +-
 .../platform/st/stm32/stm32-dcmipp/dcmipp-core.c   |  12 +-
 .../{dcmipp-parallel.c => dcmipp-input.c}          | 178 ++++++++++-----------
 4 files changed, 98 insertions(+), 98 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/Makefile b/drivers/media/platform/st/stm32/stm32-dcmipp/Makefile
index 8920d9388a21..159105fb40b8 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/Makefile
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/Makefile
@@ -1,4 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-stm32-dcmipp-y := dcmipp-core.o dcmipp-common.o dcmipp-parallel.o dcmipp-byteproc.o dcmipp-bytecap.o
+stm32-dcmipp-y := dcmipp-core.o dcmipp-common.o dcmipp-input.o dcmipp-byteproc.o dcmipp-bytecap.o
 
 obj-$(CONFIG_VIDEO_STM32_DCMIPP) += stm32-dcmipp.o
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h
index 7a7cf43baf24..fe5f97233f5e 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h
@@ -199,11 +199,11 @@ static inline void __reg_clear(struct device *dev, void __iomem *base, u32 reg,
 }
 
 /* DCMIPP subdev init / release entry points */
-struct dcmipp_ent_device *dcmipp_par_ent_init(struct device *dev,
+struct dcmipp_ent_device *dcmipp_inp_ent_init(struct device *dev,
 					      const char *entity_name,
 					      struct v4l2_device *v4l2_dev,
 					      void __iomem *regs);
-void dcmipp_par_ent_release(struct dcmipp_ent_device *ved);
+void dcmipp_inp_ent_release(struct dcmipp_ent_device *ved);
 struct dcmipp_ent_device *
 dcmipp_byteproc_ent_init(struct device *dev, const char *entity_name,
 			 struct v4l2_device *v4l2_dev, void __iomem *regs);
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 3806f7c6e2fe..97590079bb5a 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
@@ -95,9 +95,9 @@ struct dcmipp_pipeline_config {
 
 static const struct dcmipp_ent_config stm32mp13_ent_config[] = {
 	{
-		.name = "dcmipp_parallel",
-		.init = dcmipp_par_ent_init,
-		.release = dcmipp_par_ent_release,
+		.name = "dcmipp_input",
+		.init = dcmipp_inp_ent_init,
+		.release = dcmipp_inp_ent_release,
 	},
 	{
 		.name = "dcmipp_dump_postproc",
@@ -111,12 +111,12 @@ static const struct dcmipp_ent_config stm32mp13_ent_config[] = {
 	},
 };
 
-#define ID_PARALLEL 0
+#define ID_INPUT 0
 #define ID_DUMP_BYTEPROC 1
 #define ID_DUMP_CAPTURE 2
 
 static const struct dcmipp_ent_link stm32mp13_ent_links[] = {
-	DCMIPP_ENT_LINK(ID_PARALLEL,      1, ID_DUMP_BYTEPROC, 0,
+	DCMIPP_ENT_LINK(ID_INPUT, 1, ID_DUMP_BYTEPROC, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
 	DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE,  0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
@@ -309,7 +309,7 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
 	}
 
 	/* Parallel input device detected, connect it to parallel subdev */
-	sink = dcmipp->entity[ID_PARALLEL];
+	sink = dcmipp->entity[ID_INPUT];
 	sink->bus.flags = vep.bus.parallel.flags;
 	sink->bus.bus_width = vep.bus.parallel.bus_width;
 	sink->bus.data_shift = vep.bus.parallel.data_shift;
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c
similarity index 66%
rename from drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c
rename to drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c
index 823c9da336a7..689eb4c72e18 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c
@@ -34,7 +34,7 @@
 #define IS_SINK(pad) (!(pad))
 #define IS_SRC(pad)  ((pad))
 
-struct dcmipp_par_pix_map {
+struct dcmipp_inp_pix_map {
 	unsigned int code_sink;
 	unsigned int code_src;
 	u8 prcr_format;
@@ -48,7 +48,7 @@ struct dcmipp_par_pix_map {
 		.prcr_format = DCMIPP_PRCR_FORMAT_##prcr,	\
 		.prcr_swapcycles = swap,			\
 	}
-static const struct dcmipp_par_pix_map dcmipp_par_pix_map_list[] = {
+static const struct dcmipp_inp_pix_map dcmipp_inp_pix_map_list[] = {
 	/* RGB565 */
 	PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_LE, RGB565_2X8_LE, RGB565, 1),
 	PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_BE, RGB565_2X8_LE, RGB565, 0),
@@ -74,18 +74,18 @@ static const struct dcmipp_par_pix_map dcmipp_par_pix_map_list[] = {
  * Search through the pix_map table, skipping two consecutive entry with the
  * same code
  */
-static inline const struct dcmipp_par_pix_map *dcmipp_par_pix_map_by_index
+static inline const struct dcmipp_inp_pix_map *dcmipp_inp_pix_map_by_index
 						(unsigned int index,
 						 unsigned int pad)
 {
 	unsigned int i = 0;
 	u32 prev_code = 0, cur_code;
 
-	while (i < ARRAY_SIZE(dcmipp_par_pix_map_list)) {
+	while (i < ARRAY_SIZE(dcmipp_inp_pix_map_list)) {
 		if (IS_SRC(pad))
-			cur_code = dcmipp_par_pix_map_list[i].code_src;
+			cur_code = dcmipp_inp_pix_map_list[i].code_src;
 		else
-			cur_code = dcmipp_par_pix_map_list[i].code_sink;
+			cur_code = dcmipp_inp_pix_map_list[i].code_sink;
 
 		if (cur_code == prev_code) {
 			i++;
@@ -99,32 +99,32 @@ static inline const struct dcmipp_par_pix_map *dcmipp_par_pix_map_by_index
 		index--;
 	}
 
-	if (i >= ARRAY_SIZE(dcmipp_par_pix_map_list))
+	if (i >= ARRAY_SIZE(dcmipp_inp_pix_map_list))
 		return NULL;
 
-	return &dcmipp_par_pix_map_list[i];
+	return &dcmipp_inp_pix_map_list[i];
 }
 
-static inline const struct dcmipp_par_pix_map *dcmipp_par_pix_map_by_code
+static inline const struct dcmipp_inp_pix_map *dcmipp_inp_pix_map_by_code
 					(u32 code_sink, u32 code_src)
 {
 	unsigned int i;
 
-	for (i = 0; i < ARRAY_SIZE(dcmipp_par_pix_map_list); i++) {
-		if ((dcmipp_par_pix_map_list[i].code_sink == code_sink &&
-		     dcmipp_par_pix_map_list[i].code_src == code_src) ||
-		    (dcmipp_par_pix_map_list[i].code_sink == code_src &&
-		     dcmipp_par_pix_map_list[i].code_src == code_sink) ||
-		    (dcmipp_par_pix_map_list[i].code_sink == code_sink &&
+	for (i = 0; i < ARRAY_SIZE(dcmipp_inp_pix_map_list); i++) {
+		if ((dcmipp_inp_pix_map_list[i].code_sink == code_sink &&
+		     dcmipp_inp_pix_map_list[i].code_src == code_src) ||
+		    (dcmipp_inp_pix_map_list[i].code_sink == code_src &&
+		     dcmipp_inp_pix_map_list[i].code_src == code_sink) ||
+		    (dcmipp_inp_pix_map_list[i].code_sink == code_sink &&
 		     code_src == 0) ||
 		    (code_sink == 0 &&
-		     dcmipp_par_pix_map_list[i].code_src == code_src))
-			return &dcmipp_par_pix_map_list[i];
+		     dcmipp_inp_pix_map_list[i].code_src == code_src))
+			return &dcmipp_inp_pix_map_list[i];
 	}
 	return NULL;
 }
 
-struct dcmipp_par_device {
+struct dcmipp_inp_device {
 	struct dcmipp_ent_device ved;
 	struct v4l2_subdev sd;
 	struct device *dev;
@@ -142,7 +142,7 @@ static const struct v4l2_mbus_framefmt fmt_default = {
 	.xfer_func = DCMIPP_XFER_FUNC_DEFAULT,
 };
 
-static int dcmipp_par_init_state(struct v4l2_subdev *sd,
+static int dcmipp_inp_init_state(struct v4l2_subdev *sd,
 				 struct v4l2_subdev_state *sd_state)
 {
 	unsigned int i;
@@ -157,12 +157,12 @@ static int dcmipp_par_init_state(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int dcmipp_par_enum_mbus_code(struct v4l2_subdev *sd,
+static int dcmipp_inp_enum_mbus_code(struct v4l2_subdev *sd,
 				     struct v4l2_subdev_state *sd_state,
 				     struct v4l2_subdev_mbus_code_enum *code)
 {
-	const struct dcmipp_par_pix_map *vpix =
-		dcmipp_par_pix_map_by_index(code->index, code->pad);
+	const struct dcmipp_inp_pix_map *vpix =
+		dcmipp_inp_pix_map_by_index(code->index, code->pad);
 
 	if (!vpix)
 		return -EINVAL;
@@ -172,17 +172,17 @@ static int dcmipp_par_enum_mbus_code(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int dcmipp_par_enum_frame_size(struct v4l2_subdev *sd,
+static int dcmipp_inp_enum_frame_size(struct v4l2_subdev *sd,
 				      struct v4l2_subdev_state *sd_state,
 				      struct v4l2_subdev_frame_size_enum *fse)
 {
-	const struct dcmipp_par_pix_map *vpix;
+	const struct dcmipp_inp_pix_map *vpix;
 
 	if (fse->index)
 		return -EINVAL;
 
 	/* Only accept code in the pix map table */
-	vpix = dcmipp_par_pix_map_by_code(IS_SINK(fse->pad) ? fse->code : 0,
+	vpix = dcmipp_inp_pix_map_by_code(IS_SINK(fse->pad) ? fse->code : 0,
 					  IS_SRC(fse->pad) ? fse->code : 0);
 	if (!vpix)
 		return -EINVAL;
@@ -195,20 +195,20 @@ static int dcmipp_par_enum_frame_size(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static void dcmipp_par_adjust_fmt(struct dcmipp_par_device *par,
+static void dcmipp_inp_adjust_fmt(struct dcmipp_inp_device *inp,
 				  struct v4l2_mbus_framefmt *fmt, __u32 pad)
 {
-	const struct dcmipp_par_pix_map *vpix;
+	const struct dcmipp_inp_pix_map *vpix;
 
 	/* Only accept code in the pix map table */
-	vpix = dcmipp_par_pix_map_by_code(IS_SINK(pad) ? fmt->code : 0,
+	vpix = dcmipp_inp_pix_map_by_code(IS_SINK(pad) ? fmt->code : 0,
 					  IS_SRC(pad) ? fmt->code : 0);
 	if (!vpix)
 		fmt->code = fmt_default.code;
 
 	/* Exclude JPEG if BT656 bus is selected */
 	if (vpix && vpix->code_sink == MEDIA_BUS_FMT_JPEG_1X8 &&
-	    par->ved.bus_type == V4L2_MBUS_BT656)
+	    inp->ved.bus_type == V4L2_MBUS_BT656)
 		fmt->code = fmt_default.code;
 
 	fmt->width = clamp_t(u32, fmt->width, DCMIPP_FRAME_MIN_WIDTH,
@@ -222,11 +222,11 @@ static void dcmipp_par_adjust_fmt(struct dcmipp_par_device *par,
 	dcmipp_colorimetry_clamp(fmt);
 }
 
-static int dcmipp_par_set_fmt(struct v4l2_subdev *sd,
+static int dcmipp_inp_set_fmt(struct v4l2_subdev *sd,
 			      struct v4l2_subdev_state *sd_state,
 			      struct v4l2_subdev_format *fmt)
 {
-	struct dcmipp_par_device *par = v4l2_get_subdevdata(sd);
+	struct dcmipp_inp_device *inp = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *mf;
 
 	if (v4l2_subdev_is_streaming(sd))
@@ -235,10 +235,10 @@ static int dcmipp_par_set_fmt(struct v4l2_subdev *sd,
 	mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
 
 	/* Set the new format */
-	dcmipp_par_adjust_fmt(par, &fmt->format, fmt->pad);
+	dcmipp_inp_adjust_fmt(inp, &fmt->format, fmt->pad);
 
-	dev_dbg(par->dev, "%s: format update: old:%dx%d (0x%x, %d, %d, %d, %d) new:%dx%d (0x%x, %d, %d, %d, %d)\n",
-		par->sd.name,
+	dev_dbg(inp->dev, "%s: format update: old:%dx%d (0x%x, %d, %d, %d, %d) new:%dx%d (0x%x, %d, %d, %d, %d)\n",
+		inp->sd.name,
 		/* old */
 		mf->width, mf->height, mf->code,
 		mf->colorspace,	mf->quantization,
@@ -254,30 +254,30 @@ static int dcmipp_par_set_fmt(struct v4l2_subdev *sd,
 	if (IS_SINK(fmt->pad)) {
 		mf = v4l2_subdev_state_get_format(sd_state, 1);
 		*mf = fmt->format;
-		dcmipp_par_adjust_fmt(par, mf, 1);
+		dcmipp_inp_adjust_fmt(inp, mf, 1);
 	}
 
 	return 0;
 }
 
-static int dcmipp_par_configure(struct dcmipp_par_device *par,
+static int dcmipp_inp_configure(struct dcmipp_inp_device *inp,
 				struct v4l2_subdev_state *state)
 {
 	u32 val = 0;
-	const struct dcmipp_par_pix_map *vpix;
+	const struct dcmipp_inp_pix_map *vpix;
 	struct v4l2_mbus_framefmt *sink_fmt;
 	struct v4l2_mbus_framefmt *src_fmt;
 
 	/* Set vertical synchronization polarity */
-	if (par->ved.bus.flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+	if (inp->ved.bus.flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
 		val |= DCMIPP_PRCR_VSPOL;
 
 	/* Set horizontal synchronization polarity */
-	if (par->ved.bus.flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+	if (inp->ved.bus.flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
 		val |= DCMIPP_PRCR_HSPOL;
 
 	/* Set pixel clock polarity */
-	if (par->ved.bus.flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+	if (inp->ved.bus.flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
 		val |= DCMIPP_PRCR_PCKPOL;
 
 	/*
@@ -287,23 +287,23 @@ static int dcmipp_par_configure(struct dcmipp_par_device *par,
 	 * SAV=0xff000080 & EAV=0xff00009d.
 	 * With DCMIPP this means LSC=SAV=0x80 & LEC=EAV=0x9d.
 	 */
-	if (par->ved.bus_type == V4L2_MBUS_BT656) {
+	if (inp->ved.bus_type == V4L2_MBUS_BT656) {
 		val |= DCMIPP_PRCR_ESS;
 
 		/* Unmask all codes */
-		reg_write(par, DCMIPP_PRESUR, 0xffffffff);/* FEC:LEC:LSC:FSC */
+		reg_write(inp, DCMIPP_PRESUR, 0xffffffff);/* FEC:LEC:LSC:FSC */
 
 		/* Trig on LSC=0x80 & LEC=0x9d codes, ignore FSC and FEC */
-		reg_write(par, DCMIPP_PRESCR, 0xff9d80ff);/* FEC:LEC:LSC:FSC */
+		reg_write(inp, DCMIPP_PRESCR, 0xff9d80ff);/* FEC:LEC:LSC:FSC */
 	}
 
 	/* Set format */
 	sink_fmt = v4l2_subdev_state_get_format(state, 0);
 	src_fmt = v4l2_subdev_state_get_format(state, 1);
 
-	vpix = dcmipp_par_pix_map_by_code(sink_fmt->code, src_fmt->code);
+	vpix = dcmipp_inp_pix_map_by_code(sink_fmt->code, src_fmt->code);
 	if (!vpix) {
-		dev_err(par->dev, "Invalid sink/src format configuration\n");
+		dev_err(inp->dev, "Invalid sink/src format configuration\n");
 		return -EINVAL;
 	}
 
@@ -313,17 +313,17 @@ static int dcmipp_par_configure(struct dcmipp_par_device *par,
 	if (vpix->prcr_swapcycles)
 		val |= DCMIPP_PRCR_SWAPCYCLES;
 
-	reg_write(par, DCMIPP_PRCR, val);
+	reg_write(inp, DCMIPP_PRCR, val);
 
 	return 0;
 }
 
-static int dcmipp_par_enable_streams(struct v4l2_subdev *sd,
+static int dcmipp_inp_enable_streams(struct v4l2_subdev *sd,
 				     struct v4l2_subdev_state *state,
 				     u32 pad, u64 streams_mask)
 {
-	struct dcmipp_par_device *par =
-				container_of(sd, struct dcmipp_par_device, sd);
+	struct dcmipp_inp_device *inp =
+				container_of(sd, struct dcmipp_inp_device, sd);
 	struct v4l2_subdev *s_subdev;
 	struct media_pad *s_pad;
 	int ret;
@@ -334,16 +334,16 @@ static int dcmipp_par_enable_streams(struct v4l2_subdev *sd,
 		return -EINVAL;
 	s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
 
-	ret = dcmipp_par_configure(par, state);
+	ret = dcmipp_inp_configure(inp, state);
 	if (ret)
 		return ret;
 
 	/* Enable parallel interface */
-	reg_set(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
+	reg_set(inp, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
 
 	ret = v4l2_subdev_enable_streams(s_subdev, s_pad->index, BIT_ULL(0));
 	if (ret < 0) {
-		dev_err(par->dev,
+		dev_err(inp->dev,
 			"failed to start source subdev streaming (%d)\n", ret);
 		return ret;
 	}
@@ -351,12 +351,12 @@ static int dcmipp_par_enable_streams(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int dcmipp_par_disable_streams(struct v4l2_subdev *sd,
+static int dcmipp_inp_disable_streams(struct v4l2_subdev *sd,
 				      struct v4l2_subdev_state *state,
 				      u32 pad, u64 streams_mask)
 {
-	struct dcmipp_par_device *par =
-				container_of(sd, struct dcmipp_par_device, sd);
+	struct dcmipp_inp_device *inp =
+				container_of(sd, struct dcmipp_inp_device, sd);
 	struct v4l2_subdev *s_subdev;
 	struct media_pad *s_pad;
 	int ret;
@@ -369,86 +369,86 @@ static int dcmipp_par_disable_streams(struct v4l2_subdev *sd,
 
 	ret = v4l2_subdev_disable_streams(s_subdev, s_pad->index, BIT_ULL(0));
 	if (ret < 0) {
-		dev_err(par->dev,
+		dev_err(inp->dev,
 			"failed to stop source subdev streaming (%d)\n", ret);
 		return ret;
 	}
 
 	/* Disable parallel interface */
-	reg_clear(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
+	reg_clear(inp, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
 
 	return 0;
 }
 
-static const struct v4l2_subdev_pad_ops dcmipp_par_pad_ops = {
-	.enum_mbus_code		= dcmipp_par_enum_mbus_code,
-	.enum_frame_size	= dcmipp_par_enum_frame_size,
+static const struct v4l2_subdev_pad_ops dcmipp_inp_pad_ops = {
+	.enum_mbus_code		= dcmipp_inp_enum_mbus_code,
+	.enum_frame_size	= dcmipp_inp_enum_frame_size,
 	.get_fmt		= v4l2_subdev_get_fmt,
-	.set_fmt		= dcmipp_par_set_fmt,
-	.enable_streams		= dcmipp_par_enable_streams,
-	.disable_streams	= dcmipp_par_disable_streams,
+	.set_fmt		= dcmipp_inp_set_fmt,
+	.enable_streams		= dcmipp_inp_enable_streams,
+	.disable_streams	= dcmipp_inp_disable_streams,
 };
 
-static const struct v4l2_subdev_video_ops dcmipp_par_video_ops = {
+static const struct v4l2_subdev_video_ops dcmipp_inp_video_ops = {
 	.s_stream = v4l2_subdev_s_stream_helper,
 };
 
-static const struct v4l2_subdev_ops dcmipp_par_ops = {
-	.pad = &dcmipp_par_pad_ops,
-	.video = &dcmipp_par_video_ops,
+static const struct v4l2_subdev_ops dcmipp_inp_ops = {
+	.pad = &dcmipp_inp_pad_ops,
+	.video = &dcmipp_inp_video_ops,
 };
 
-static void dcmipp_par_release(struct v4l2_subdev *sd)
+static void dcmipp_inp_release(struct v4l2_subdev *sd)
 {
-	struct dcmipp_par_device *par =
-				container_of(sd, struct dcmipp_par_device, sd);
+	struct dcmipp_inp_device *inp =
+				container_of(sd, struct dcmipp_inp_device, sd);
 
-	kfree(par);
+	kfree(inp);
 }
 
-static const struct v4l2_subdev_internal_ops dcmipp_par_int_ops = {
-	.init_state = dcmipp_par_init_state,
-	.release = dcmipp_par_release,
+static const struct v4l2_subdev_internal_ops dcmipp_inp_int_ops = {
+	.init_state = dcmipp_inp_init_state,
+	.release = dcmipp_inp_release,
 };
 
-void dcmipp_par_ent_release(struct dcmipp_ent_device *ved)
+void dcmipp_inp_ent_release(struct dcmipp_ent_device *ved)
 {
-	struct dcmipp_par_device *par =
-			container_of(ved, struct dcmipp_par_device, ved);
+	struct dcmipp_inp_device *inp =
+			container_of(ved, struct dcmipp_inp_device, ved);
 
-	dcmipp_ent_sd_unregister(ved, &par->sd);
+	dcmipp_ent_sd_unregister(ved, &inp->sd);
 }
 
-struct dcmipp_ent_device *dcmipp_par_ent_init(struct device *dev,
+struct dcmipp_ent_device *dcmipp_inp_ent_init(struct device *dev,
 					      const char *entity_name,
 					      struct v4l2_device *v4l2_dev,
 					      void __iomem *regs)
 {
-	struct dcmipp_par_device *par;
+	struct dcmipp_inp_device *inp;
 	const unsigned long pads_flag[] = {
 		MEDIA_PAD_FL_SINK, MEDIA_PAD_FL_SOURCE,
 	};
 	int ret;
 
-	/* Allocate the par struct */
-	par = kzalloc(sizeof(*par), GFP_KERNEL);
-	if (!par)
+	/* Allocate the inp struct */
+	inp = kzalloc(sizeof(*inp), GFP_KERNEL);
+	if (!inp)
 		return ERR_PTR(-ENOMEM);
 
-	par->regs = regs;
+	inp->regs = regs;
 
 	/* Initialize ved and sd */
-	ret = dcmipp_ent_sd_register(&par->ved, &par->sd, v4l2_dev,
+	ret = dcmipp_ent_sd_register(&inp->ved, &inp->sd, v4l2_dev,
 				     entity_name, MEDIA_ENT_F_VID_IF_BRIDGE,
 				     ARRAY_SIZE(pads_flag), pads_flag,
-				     &dcmipp_par_int_ops, &dcmipp_par_ops,
+				     &dcmipp_inp_int_ops, &dcmipp_inp_ops,
 				     NULL, NULL);
 	if (ret) {
-		kfree(par);
+		kfree(inp);
 		return ERR_PTR(ret);
 	}
 
-	par->dev = dev;
+	inp->dev = dev;
 
-	return &par->ved;
+	return &inp->ved;
 }

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:28 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:28 +0100
Subject: [PATCH v4 04/15] media: stm32: dcmipp: use
 v4l2_subdev_is_streaming
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-4-fbeb55a05ed7@foss.st.com>

Rely on v4l2_subdev_is_streaming in order to know if the subdev
is streaming or not instead of relying on a local variable.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c | 6 +-----
 drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c | 5 +----
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
index 5a361ad6b023..50500112eab9 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
@@ -78,7 +78,6 @@ struct dcmipp_byteproc_device {
 	struct v4l2_subdev sd;
 	struct device *dev;
 	void __iomem *regs;
-	bool streaming;
 };
 
 static const struct v4l2_mbus_framefmt fmt_default = {
@@ -239,11 +238,10 @@ static int dcmipp_byteproc_set_fmt(struct v4l2_subdev *sd,
 				   struct v4l2_subdev_state *sd_state,
 				   struct v4l2_subdev_format *fmt)
 {
-	struct dcmipp_byteproc_device *byteproc = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *mf;
 	struct v4l2_rect *crop, *compose;
 
-	if (byteproc->streaming)
+	if (v4l2_subdev_is_streaming(sd))
 		return -EBUSY;
 
 	mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
@@ -495,8 +493,6 @@ static int dcmipp_byteproc_s_stream(struct v4l2_subdev *sd, int enable)
 		}
 	}
 
-	byteproc->streaming = enable;
-
 	return 0;
 }
 
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c
index 62c5c3331cfe..05e8897ae37a 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c
@@ -129,7 +129,6 @@ struct dcmipp_par_device {
 	struct v4l2_subdev sd;
 	struct device *dev;
 	void __iomem *regs;
-	bool streaming;
 };
 
 static const struct v4l2_mbus_framefmt fmt_default = {
@@ -230,7 +229,7 @@ static int dcmipp_par_set_fmt(struct v4l2_subdev *sd,
 	struct dcmipp_par_device *par = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *mf;
 
-	if (par->streaming)
+	if (v4l2_subdev_is_streaming(sd))
 		return -EBUSY;
 
 	mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
@@ -370,8 +369,6 @@ static int dcmipp_par_s_stream(struct v4l2_subdev *sd, int enable)
 		reg_clear(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
 	}
 
-	par->streaming = enable;
-
 	return ret;
 }
 

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:24 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:24 +0100
Subject: [PATCH v4 00/15] media: stm32: introduction of CSI / DCMIPP for
 STM32MP25
Message-ID: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>

This series introduces the camera pipeline support for the
STM32MP25 SOC.  The STM32MP25 has 3 pipelines, fed from a
single camera input which can be either parallel or csi.

This series adds the basic support for the 1st pipe (dump)
which, in term of features is same as the one featured on
the STM32MP13 SOC.  It focuses on introduction of the
CSI input stage for the DCMIPP, and the CSI specific new
control code for the DCMIPP.
One of the subdev of the DCMIPP, dcmipp_parallel is now
renamed as dcmipp_input since it allows to not only control
the parallel but also the csi interface.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
Changes in v4:
* stm32-dcmipp: correct patch 13/15 with clk error handling in
  dcmipp_runtime_resume function
- Link to v3: https://lore.kernel.org/r/20241118-csi_dcmipp_mp25-v3-0-c1914afb0a0f at foss.st.com

Changes in v3:
* stm32-csi: use clk_bulk api
* stm32-csiL perform reset control within the probe
- Link to v2: https://lore.kernel.org/r/20241105-csi_dcmipp_mp25-v2-0-b9fc8a7273c2 at foss.st.com

---
Alain Volmat (15):
      media: stm32: dcmipp: correct dma_set_mask_and_coherent mask value
      dt-bindings: media: add description of stm32 csi
      media: stm32: csi: addition of the STM32 CSI driver
      media: stm32: dcmipp: use v4l2_subdev_is_streaming
      media: stm32: dcmipp: replace s_stream with enable/disable_streams
      media: stm32: dcmipp: rename dcmipp_parallel into dcmipp_input
      media: stm32: dcmipp: add support for csi input into dcmipp-input
      media: stm32: dcmipp: add bayer 10~14 bits formats
      media: stm32: dcmipp: add 1X16 RGB / YUV formats support
      media: stm32: dcmipp: avoid duplicated format on enum in bytecap
      media: stm32: dcmipp: fill media ctl hw_revision field
      dt-bindings: media: add the stm32mp25 compatible of DCMIPP
      media: stm32: dcmipp: add core support for the stm32mp25
      arm64: dts: st: add csi & dcmipp node in stm32mp25
      arm64: dts: st: enable imx335/csi/dcmipp pipeline on stm32mp257f-ev1

 .../devicetree/bindings/media/st,stm32-dcmipp.yaml |   53 +-
 .../bindings/media/st,stm32mp25-csi.yaml           |  125 +++
 MAINTAINERS                                        |    8 +
 arch/arm64/boot/dts/st/stm32mp251.dtsi             |   23 +
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts         |   85 ++
 drivers/media/platform/st/stm32/Kconfig            |   14 +
 drivers/media/platform/st/stm32/Makefile           |    1 +
 drivers/media/platform/st/stm32/stm32-csi.c        | 1137 ++++++++++++++++++++
 .../media/platform/st/stm32/stm32-dcmipp/Makefile  |    2 +-
 .../st/stm32/stm32-dcmipp/dcmipp-bytecap.c         |  128 ++-
 .../st/stm32/stm32-dcmipp/dcmipp-byteproc.c        |  119 +-
 .../platform/st/stm32/stm32-dcmipp/dcmipp-common.h |    4 +-
 .../platform/st/stm32/stm32-dcmipp/dcmipp-core.c   |  122 ++-
 .../platform/st/stm32/stm32-dcmipp/dcmipp-input.c  |  540 ++++++++++
 .../st/stm32/stm32-dcmipp/dcmipp-parallel.c        |  440 --------
 15 files changed, 2224 insertions(+), 577 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241007-csi_dcmipp_mp25-7779601f57da

Best regards,
-- 
Alain Volmat <alain.volmat at foss.st.com>



From Cloud.Zhang at mediatek.com  Thu Dec 12 01:20:12 2024
From: Cloud.Zhang at mediatek.com (mtk22730)
Date: Thu, 12 Dec 2024 17:20:12 +0800
Subject: [PATCH] [v1] spi: spi-mtk-nor: Modify the clock architecture of nor controller
Message-ID: <20241212092206.14071-1-Cloud.Zhang@mediatek.com>

From: Cloud Zhang <cloud.zhang at mediatek.com>

The clock used by different platforms is not same. So it is
necessary to modify the clock architecture to be adaptable to more
platforms.

Signed-off-by: Cloud Zhang <cloud.zhang at mediatek.com>
---
 drivers/spi/spi-mtk-nor.c | 118 ++++++++++++++++++++++----------------
 1 file changed, 68 insertions(+), 50 deletions(-)

diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index 85ab5ce96c4d..d466a8d3f062 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -99,6 +99,8 @@
 
 #define CLK_TO_US(sp, clkcnt)		DIV_ROUND_UP(clkcnt, sp->spi_freq / 1000000)
 
+#define MAX_CLOCK_CNT		6
+
 struct mtk_nor_caps {
 	u8 dma_bits;
 
@@ -110,16 +112,19 @@ struct mtk_nor_caps {
 	u8 extra_dummy_bit;
 };
 
+struct clk_info {
+	struct clk *clki;
+	const char *name;
+};
+
 struct mtk_nor {
 	struct spi_controller *ctlr;
 	struct device *dev;
 	void __iomem *base;
 	u8 *buffer;
 	dma_addr_t buffer_dma;
-	struct clk *spi_clk;
-	struct clk *ctlr_clk;
-	struct clk *axi_clk;
-	struct clk *axi_s_clk;
+	struct clk_info clocks[MAX_CLOCK_CNT];
+	u8 clock_cnt;
 	unsigned int spi_freq;
 	bool wbuf_en;
 	bool has_irq;
@@ -703,42 +708,74 @@ static int mtk_nor_transfer_one_message(struct spi_controller *host,
 
 static void mtk_nor_disable_clk(struct mtk_nor *sp)
 {
-	clk_disable_unprepare(sp->spi_clk);
-	clk_disable_unprepare(sp->ctlr_clk);
-	clk_disable_unprepare(sp->axi_clk);
-	clk_disable_unprepare(sp->axi_s_clk);
+	u8 i;
+
+	for (i = 0; i < sp->clock_cnt; i++)
+		clk_disable_unprepare(sp->clocks[i].clki);
 }
 
 static int mtk_nor_enable_clk(struct mtk_nor *sp)
 {
 	int ret;
+	u8 i, j;
 
-	ret = clk_prepare_enable(sp->spi_clk);
-	if (ret)
-		return ret;
+	for (i = 0; i < sp->clock_cnt; i++) {
+		ret = clk_prepare_enable(sp->clocks[i].clki);
+		if (ret) {
+			for (j = 0; j < i; j++)
+				clk_disable_unprepare(sp->clocks[j].clki);
 
-	ret = clk_prepare_enable(sp->ctlr_clk);
-	if (ret) {
-		clk_disable_unprepare(sp->spi_clk);
-		return ret;
+			return ret;
+		}
+
+		if (strcmp(sp->clocks[i].name, "spi"))
+			sp->spi_freq = clk_get_rate(sp->clocks[i].clki);
 	}
 
-	ret = clk_prepare_enable(sp->axi_clk);
-	if (ret) {
-		clk_disable_unprepare(sp->spi_clk);
-		clk_disable_unprepare(sp->ctlr_clk);
-		return ret;
+	return 0;
+}
+
+static int mtk_nor_parse_clk(struct device *dev, struct mtk_nor *sp)
+{
+	struct device_node *np = dev->of_node;
+	int ret;
+	const char *name;
+	u8 cnt, i;
+
+	cnt = of_property_count_strings(np, "clock-names");
+	if (!cnt || (cnt == -EINVAL)) {
+		dev_err(dev, "Unable to find clocks\n");
+		ret = -EINVAL;
+		goto out;
+	} else if (cnt < 0) {
+		dev_err(dev, "Count clock strings failed, err %d\n", cnt);
+		ret = cnt;
+		goto out;
+	} else if (cnt > MAX_CLOCK_CNT) {
+		ret = -EINVAL;
+		goto out;
 	}
 
-	ret = clk_prepare_enable(sp->axi_s_clk);
-	if (ret) {
-		clk_disable_unprepare(sp->spi_clk);
-		clk_disable_unprepare(sp->ctlr_clk);
-		clk_disable_unprepare(sp->axi_clk);
-		return ret;
+	sp->clock_cnt = cnt;
+
+	for (i = 0; i < cnt; i++) {
+		ret = of_property_read_string_index(np, "clock-names", i,
+				       &name);
+		if (ret) {
+			dev_err(dev, "failed to get clock string\n");
+			return ret;
+		}
+
+		sp->clocks[i].name = name;
+		sp->clocks[i].clki = devm_clk_get(dev, sp->clocks[i].name);
+		if (IS_ERR(sp->clocks[i].clki)) {
+			dev_err(dev, "get clock %s fail\n", sp->clocks[i].name);
+			return PTR_ERR(sp->clocks[i].clki);
+		}
 	}
 
-	return 0;
+out:
+	return ret;
 }
 
 static void mtk_nor_init(struct mtk_nor *sp)
@@ -813,29 +850,12 @@ static int mtk_nor_probe(struct platform_device *pdev)
 	struct mtk_nor *sp;
 	struct mtk_nor_caps *caps;
 	void __iomem *base;
-	struct clk *spi_clk, *ctlr_clk, *axi_clk, *axi_s_clk;
 	int ret, irq;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
-	spi_clk = devm_clk_get(&pdev->dev, "spi");
-	if (IS_ERR(spi_clk))
-		return PTR_ERR(spi_clk);
-
-	ctlr_clk = devm_clk_get(&pdev->dev, "sf");
-	if (IS_ERR(ctlr_clk))
-		return PTR_ERR(ctlr_clk);
-
-	axi_clk = devm_clk_get_optional(&pdev->dev, "axi");
-	if (IS_ERR(axi_clk))
-		return PTR_ERR(axi_clk);
-
-	axi_s_clk = devm_clk_get_optional(&pdev->dev, "axi_s");
-	if (IS_ERR(axi_s_clk))
-		return PTR_ERR(axi_s_clk);
-
 	caps = (struct mtk_nor_caps *)of_device_get_match_data(&pdev->dev);
 
 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(caps->dma_bits));
@@ -868,10 +888,6 @@ static int mtk_nor_probe(struct platform_device *pdev)
 	sp->wbuf_en = false;
 	sp->ctlr = ctlr;
 	sp->dev = &pdev->dev;
-	sp->spi_clk = spi_clk;
-	sp->ctlr_clk = ctlr_clk;
-	sp->axi_clk = axi_clk;
-	sp->axi_s_clk = axi_s_clk;
 	sp->caps = caps;
 	sp->high_dma = caps->dma_bits > 32;
 	sp->buffer = dmam_alloc_coherent(&pdev->dev,
@@ -885,11 +901,13 @@ static int mtk_nor_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	ret = mtk_nor_enable_clk(sp);
+	ret = mtk_nor_parse_clk(sp->dev, sp);
 	if (ret < 0)
 		return ret;
 
-	sp->spi_freq = clk_get_rate(sp->spi_clk);
+	ret = mtk_nor_enable_clk(sp);
+	if (ret < 0)
+		return ret;
 
 	mtk_nor_init(sp);
 
-- 
2.46.0



From ryan.roberts at arm.com  Thu Dec 12 01:23:20 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 12 Dec 2024 09:23:20 +0000
Subject: [RESEND RFC PATCH v1 1/5] arm64: Add TLB Conflict Abort Exception
 handler to KVM
In-Reply-To: <86o71irucr.wl-maz@kernel.org>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-2-miko.lenczewski@arm.com>
 <86o71irucr.wl-maz@kernel.org>
Message-ID: <5d4ccb2c-da45-4471-9bb1-90212b50dad7@arm.com>

On 11/12/2024 17:40, Marc Zyngier wrote:
> On Wed, 11 Dec 2024 16:01:37 +0000,
> Miko?aj Lenczewski <miko.lenczewski at arm.com> wrote:
>>
>> Currently, KVM does not handle the case of a stage 2 TLB conflict abort
>> exception. The Arm ARM specifies that the worst-case handling of such an
>> exception requires a `tlbi vmalls12e1`.
> 
> Not quite. It says (I_JCCRT):
> 
> <quote>
> * For the EL1&0 translation regime, when stage 2 translations are in
>   use, either VMALLS12E1 or ALLE1.
> </quote>
> 
>> Perform such an invalidation when this exception is encountered.
> 
> What you fail to describe is *why* this is needed. You know it, I know
> it, but not everybody does. A reference to the ARM ARM would
> definitely be helpful.
> 
>>
>> Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
>> ---
>>  arch/arm64/include/asm/esr.h | 8 ++++++++
>>  arch/arm64/kvm/mmu.c         | 6 ++++++
>>  2 files changed, 14 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
>> index d1b1a33f9a8b..8a66f81ca291 100644
>> --- a/arch/arm64/include/asm/esr.h
>> +++ b/arch/arm64/include/asm/esr.h
>> @@ -121,6 +121,7 @@
>>  #define ESR_ELx_FSC_SEA_TTW(n)	(0x14 + (n))
>>  #define ESR_ELx_FSC_SECC	(0x18)
>>  #define ESR_ELx_FSC_SECC_TTW(n)	(0x1c + (n))
>> +#define ESR_ELx_FSC_TLBABT	(0x30)
>>  
>>  /* Status codes for individual page table levels */
>>  #define ESR_ELx_FSC_ACCESS_L(n)	(ESR_ELx_FSC_ACCESS + (n))
>> @@ -464,6 +465,13 @@ static inline bool esr_fsc_is_access_flag_fault(unsigned long esr)
>>  	       (esr == ESR_ELx_FSC_ACCESS_L(0));
>>  }
>>  
>> +static inline bool esr_fsc_is_tlb_conflict_abort(unsigned long esr)
>> +{
>> +	esr = esr & ESR_ELx_FSC;
>> +
>> +	return esr == ESR_ELx_FSC_TLBABT;
>> +}
>> +
>>  /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */
>>  static inline bool esr_iss_is_eretax(unsigned long esr)
>>  {
>> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
>> index c9d46ad57e52..c8c6f5a97a1b 100644
>> --- a/arch/arm64/kvm/mmu.c
>> +++ b/arch/arm64/kvm/mmu.c
>> @@ -1756,6 +1756,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>>  	ipa = fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
>>  	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
>>  
>> +	if (esr_fsc_is_tlb_conflict_abort(esr)) {
>> +		// does a `tlbi vmalls12e1is`
> 
> nit: this isn't a very useful comment.
> 
>> +		__kvm_tlb_flush_vmid(&vcpu->kvm->arch.mmu);
>> +		return 1;
>> +	}
> 
> That's not enough, unfortunately. A nested VM has *many* VMIDs (the
> flattening of all translation contexts that the guest uses).
> 
> So you can either iterate over all the valid VMIDs owned by this
> guest, or more simply issue a TLBI ALLE1, which will do the trick in a
> much more efficient way.
> 
> The other thing is that you are using an IS invalidation, which is
> farther reaching than necessary. Why would you invalidate the TLBs for
> CPUs that are only innocent bystanders? A non-shareable invalidation
> seems preferable to me.
> 
>> +
>>  	if (esr_fsc_is_translation_fault(esr)) {
>>  		/* Beyond sanitised PARange (which is the IPA limit) */
>>  		if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit())) {
> 
> But it also begs the question: why only KVM, and not the host? This
> handler will only take effect for a TLB Conflict abort delivered from
> an EL1 guest to EL2.

Hi Marc,

I believe the intent of this patch is to protect the host/KVM against a guest
that is using BBML2. The host/KVM always assumes BBML0 and therefore doesn't do
any operations that are allowed by the arch to cause a conflict abort. Therefore
the host doesn't need to handle it. But a guest could be taking advantage of
BBML2 and therefore it's architiecturally possible for a conflict abort to be
raised to EL2. I think today that would take down the host?

So really I think this could be considered a stand-alone KVM hardening improvement?

> 
> However, it doesn't seem to me that the host is equipped to deal with
> this sort of exception for itself. Shouldn't you start with that?

If the host isn't doing any BBML2 operations it doesn't need to handle it, I
don't think? Obviously that changes later in the series and Miko is adding the
required handling to the host.

Thanks,
Ryan

> 
> Thanks,
> 
> 	M.
> 



From dmitry.baryshkov at linaro.org  Thu Dec 12 01:28:05 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 12 Dec 2024 11:28:05 +0200
Subject: [PATCH v5 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <ad8843d6-e5a3-437a-af4d-f2248b247a65@norik.com>
References: <20241210091901.83028-1-andrej.picej@norik.com>
 <20241210091901.83028-3-andrej.picej@norik.com>
 <irpmhq7vxjra6vhmdh7p63ajj57n3h2c4br3ija2jmwtoewist@zyxfmx6k5m4e>
 <aa2de99d-21f4-4843-83b7-5d2db78be86f@norik.com>
 <qhmsobin3fsmoc7ic2jtancowfscoauyroruxdpwhmqwlogtkz@6by3s2ruwzwp>
 <519cc025-0782-4f96-a169-1fe87b280173@norik.com>
 <rputm4gnjj6nb66ix7dqbxr2janltia6rlb6zunhf7x3mgooxw@o3lblnyp5cci>
 <ad8843d6-e5a3-437a-af4d-f2248b247a65@norik.com>
Message-ID: <roxosjotsh65dkecrwhhtlhkhqseezkj7ydk532shc27irzmd3@xry3ggjdq4uo>

On Thu, Dec 12, 2024 at 09:08:03AM +0100, Andrej Picej wrote:
> 
> 
> On 12. 12. 24 00:04, Dmitry Baryshkov wrote:
> > On Wed, Dec 11, 2024 at 08:57:17AM +0100, Andrej Picej wrote:
> > > 
> > > 
> > > On 10. 12. 24 14:59, Dmitry Baryshkov wrote:
> > > > On Tue, Dec 10, 2024 at 02:41:01PM +0100, Andrej Picej wrote:
> > > > > 
> > > > > 
> > > > > On 10. 12. 24 12:43, Dmitry Baryshkov wrote:
> > > > > > On Tue, Dec 10, 2024 at 10:19:00AM +0100, Andrej Picej wrote:
> > > > > > > Add a optional properties to change LVDS output voltage. This should not
> > > > > > > be static as this depends mainly on the connected display voltage
> > > > > > > requirement. We have three properties:
> > > > > > > - "ti,lvds-termination-ohms", which sets near end termination,
> > > > > > > - "ti,lvds-vod-swing-data-microvolt" and
> > > > > > > - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> > > > > > > output voltage for data and clock lanes. They are defined as an array
> > > > > > > with min and max values. The appropriate bitfield will be set if
> > > > > > > selected constraints can be met.
> > > > > > > 
> > > > > > > If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> > > > > > > end termination will be used. Selecting only one:
> > > > > > > "ti,lvds-vod-swing-data-microvolt" or
> > > > > > > "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> > > > > > > constraint for only data/clock lanes will be met. Setting both is
> > > > > > > recommended.
> > > > > > > 
> > > > > > > Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> > > > > > > ---
> > > > > > > Changes in v5:
> > > > > > > - specify default values in sn65dsi83_parse_lvds_endpoint,
> > > > > > > - move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
> > > > > > > Changes in v4:
> > > > > > > - fix typo in commit message bitfiled -> bitfield
> > > > > > > - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
> > > > > > > of separate variables for channel A/B
> > > > > > > - add more checks on return value of "of_property_read_u32_array"
> > > > > > > Changes in v3:
> > > > > > > - use microvolts for default array values 1000 mV -> 1000000 uV.
> > > > > > > Changes in v2:
> > > > > > > - use datasheet tables to get the proper configuration
> > > > > > > - since major change was done change the authorship to myself
> > > > > > > ---
> > > > > > >     drivers/gpu/drm/bridge/ti-sn65dsi83.c | 142 +++++++++++++++++++++++++-
> > > > > > >     1 file changed, 139 insertions(+), 3 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > > > > > index 57a7ed13f996..f9578b38da28 100644
> > > > > > > --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > > > > > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> > > > > > > @@ -132,6 +132,16 @@
> > > > > > >     #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
> > > > > > >     #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
> > > > > > > +enum sn65dsi83_channel {
> > > > > > > +	CHANNEL_A,
> > > > > > > +	CHANNEL_B
> > > > > > > +};
> > > > > > > +
> > > > > > > +enum sn65dsi83_lvds_term {
> > > > > > > +	OHM_100,
> > > > > > > +	OHM_200
> > > > > > > +};
> > > > > > > +
> > > > > > >     enum sn65dsi83_model {
> > > > > > >     	MODEL_SN65DSI83,
> > > > > > >     	MODEL_SN65DSI84,
> > > > > > > @@ -147,6 +157,8 @@ struct sn65dsi83 {
> > > > > > >     	struct regulator		*vcc;
> > > > > > >     	bool				lvds_dual_link;
> > > > > > >     	bool				lvds_dual_link_even_odd_swap;
> > > > > > > +	int				lvds_vod_swing_conf[2];
> > > > > > > +	int				lvds_term_conf[2];
> > > > > > >     };
> > > > > > >     static const struct regmap_range sn65dsi83_readable_ranges[] = {
> > > > > > > @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
> > > > > > >     	.max_register = REG_IRQ_STAT,
> > > > > > >     };
> > > > > > > +static const int lvds_vod_swing_data_table[2][4][2] = {
> > > > > > > +	{	/* 100 Ohm */
> > > > > > > +		{ 180000, 313000 },
> > > > > > > +		{ 215000, 372000 },
> > > > > > > +		{ 250000, 430000 },
> > > > > > > +		{ 290000, 488000 },
> > > > > > > +	},
> > > > > > > +	{	/* 200 Ohm */
> > > > > > > +		{ 150000, 261000 },
> > > > > > > +		{ 200000, 346000 },
> > > > > > > +		{ 250000, 428000 },
> > > > > > > +		{ 300000, 511000 },
> > > > > > > +	},
> > > > > > > +};
> > > > > > > +
> > > > > > > +static const int lvds_vod_swing_clock_table[2][4][2] = {
> > > > > > > +	{	/* 100 Ohm */
> > > > > > > +		{ 140000, 244000 },
> > > > > > > +		{ 168000, 290000 },
> > > > > > > +		{ 195000, 335000 },
> > > > > > > +		{ 226000, 381000 },
> > > > > > > +	},
> > > > > > > +	{	/* 200 Ohm */
> > > > > > > +		{ 117000, 204000 },
> > > > > > > +		{ 156000, 270000 },
> > > > > > > +		{ 195000, 334000 },
> > > > > > > +		{ 234000, 399000 },
> > > > > > > +	},
> > > > > > > +};
> > > > > > > +
> > > > > > >     static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
> > > > > > >     {
> > > > > > >     	return container_of(bridge, struct sn65dsi83, bridge);
> > > > > > > @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
> > > > > > >     		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
> > > > > > >     	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
> > > > > > > -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
> > > > > > > +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
> > > > > > > +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
> > > > > > > +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
> > > > > > >     	regmap_write(ctx->regmap, REG_LVDS_LANE,
> > > > > > >     		     (ctx->lvds_dual_link_even_odd_swap ?
> > > > > > >     		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
> > > > > > > -		     REG_LVDS_LANE_CHA_LVDS_TERM |
> > > > > > > -		     REG_LVDS_LANE_CHB_LVDS_TERM);
> > > > > > > +		     (ctx->lvds_term_conf[CHANNEL_A] ?
> > > > > > > +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
> > > > > > > +		     (ctx->lvds_term_conf[CHANNEL_B] ?
> > > > > > > +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
> > > > > > >     	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
> > > > > > >     	le16val = cpu_to_le16(mode->hdisplay);
> > > > > > > @@ -576,10 +622,100 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
> > > > > > >     	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
> > > > > > >     };
> > > > > > > +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
> > > > > > > +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
> > > > > > > +{
> > > > > > > +	int i;
> > > > > > > +
> > > > > > > +	for (i = 0; i <= 3; i++) {
> > > > > > > +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
> > > > > > > +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
> > > > > > > +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> > > > > > > +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
> > > > > > > +			return i;
> > > > > > > +	}
> > > > > > > +
> > > > > > > +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
> > > > > > > +	return -EINVAL;
> > > > > > > +}
> > > > > > > +
> > > > > > > +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> > > > > > > +{
> > > > > > > +	struct device *dev = ctx->dev;
> > > > > > > +	struct device_node *endpoint;
> > > > > > > +	int endpoint_reg;
> > > > > > > +	/* Set so the property can be freely selected if not defined */
> > > > > > > +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
> > > > > > > +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
> > > > > > > +	u32 lvds_term;
> > > > > > > +	u8 lvds_term_conf = 0x1;
> > > > > > > +	int lvds_vod_swing_conf = 0x1;
> > > > > > 
> > > > > > Magic values
> > > > > 
> > > > > Can you please elaborate.
> > > > > 
> > > > > I can use:
> > > > > u8 lvds_term_conf = OHM_200;
> > > > > 
> > > > > What about lvds_vod_swing_conf? Should I create additional define for it?
> > > > > But this doesn't solve a hidden meaning? Maybe additional comment above?
> > > > > Would like to avoid using voltages for it, since then we are reverse
> > > > > engineering the table in datasheet to match the default reg value.
> > > > 
> > > > I think the following example solves both problems:
> > > > 
> > > > lvds_term = 200;
> > > > of_property_read_u32(..., &lvds_term);
> > > > 
> > > > if (lvds_term == 100)
> > > > 	ctx->lvds_term_conf[channel] = OHM_100;
> > > > else if (lvds_term == 200)
> > > > 	ctx->lvds_term_conf[channel] = OHM_200;
> > > > else
> > > > 	return -EINVAL;
> > > > 
> > > > The same approach can be applied to lvds_vod_swing_conf, resulting in
> > > > removal of magic values.
> > > 
> > > Sorry, but I think it is not that easy when it comes to the
> > > lvds_vod_swing_conf. We should assign default value if
> > > "ti,lvds-vod-swing-data-microvolt" and "ti,lvds-vod-swing-clock-microvolt"
> > > are not defined. Default value of the lvds_vod_swing_conf is 0x1, but this
> > > doesn't have any straight forward meaning like OHM_200 for example.
> > > 
> > > What we can do in that case is that we copy the values from defined
> > > datasheet tables to the "lvds_vod_swing_data[2]" and "lvds_vod_swing_clk[2]"
> > > arrays and then run the
> > > sn65dsi83_select_lvds_vod_swing with it, which will return the default value
> > > (0x1).
> > > 
> > > /* If both properties are not defined assign default limits */
> > > if (ret_data && ret_clock) {
> > > 	memcpy(lvds_vod_swing_data,
> > > 	     lvds_vod_swing_data_table[ctx->lvds_term_conf[channel]][1],
> > > 	     sizeof(lvds_vod_swing_data));
> > > 	memcpy(lvds_vod_swing_clk,
> > > 	    lvds_vod_swing_clock_table[ctx->lvds_term_conf[channel]][1],
> > > 	    sizeof(lvds_vod_swing_clk));
> > > }
> > > lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
> > > 	lvds_vod_swing_data, lvds_vod_swing_clk,
> > > 	ctx->lvds_term_conf[channel]);
> > > if (lvds_vod_swing_conf < 0) {
> > > 	ret = lvds_vod_swing_conf;
> > > 	goto exit;
> > > }
> > > 
> > > ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
> > > 
> > > I'm not sure if using this approach gets rid of the problem with magic
> > > values.
> > > Or maybe I'm not seeing the obvious solution so please bear with me.
> > 
> > Yes, the defaults (0..1000000) should be fixed to result in the same
> > value (0x01) as if the property wasn't specified at all
> 
> The defaults (0..1000000) is selected because in case if only one property
> is defined in dts (ti,lvds-vod-swing-data-microvolt or
> ti,lvds-vod-swing-clock-microvolt) the other array values don't effect the
> decision which "lvds_vod_swing_conf" is selected. That's why we initialized
> the array to be out off bounds of the datasheet tables, all values in the
> table match the not defined property, so lvds_vod_swing_conf is selected
> purely on the basis of the defined property.

I see, thanks for the explanation.

> 
> Example:
> DTS
> ti,lvds-vod-swing-data-microvolt = <250000 428000>;
> //ti,lvds-vod-swing-clock-microvolt NOT DEFINED;
> 
> After parsing the devicetree we will get:
> lvds_vod_swing_data = [ 250000, 428000 ]
> lvds_vod_swing_clk = [ 0, 1000000 ]
> 
> In sn65dsi83_select_lvds_vod_swing lvds_vod_swing_clk[] values don't effect
> the decision making since
> 
> lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1]
> 
> is always true.
> 
> > 
> > I think the following should work:
> > 
> > 	/* artifical values to select the defaults in both cases */
> > 	u32 lvds_vod_swing_data[2] = { 190000, 330000 };
> > 	u32 lvds_vod_swing_clk[2] = { 150000, 250000 };
> 
> This sets the default to 0x0. It should be:
> u32 lvds_vod_swing_data[2] = { 200000, 372000 };
> u32 lvds_vod_swing_clk[2] = { 156000, 290000 };
> This selects the default 0x1 in both cases, if termination is 100 or 200
> Ohms.
> 
> Nevertheless I think I got your point. But I would still like to give the
> user the freedom to only specify one property if maybe connected panel only
> has limits on data lanes/clock lane.
> So maybe set the arrays lvds_vod_swing_data/clk to [0, 1000000] if
> of_property_read_u32_array returns -EINVAL (property does not exist).
> What do you say?

After your explanation, I think it might be better to explicitly set the
value to 0x1, but not at the top of the function, but next to a check
that both properties are (not) set.

> 
> > 
> > Yes, they are artificial, as stated in the comment. Yes, I think it's
> > better than special-casing in the property handling.
> > 

-- 
With best wishes
Dmitry


From krzysztof.kozlowski at linaro.org  Thu Dec 12 01:31:10 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 10:31:10 +0100
Subject: [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap()
In-Reply-To: <20241211-syscon-fixes-v1-1-b5ac8c219e96@kernel.org>
References: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
 <20241211-syscon-fixes-v1-1-b5ac8c219e96@kernel.org>
Message-ID: <9e91fd4d-8589-4403-8025-4c8ccb8e67b8@linaro.org>

On 11/12/2024 21:57, Rob Herring (Arm) wrote:
> It is possible for multiple, simultaneous callers calling
> device_node_get_regmap() with the same node to fail to find an entry in
> the syscon_list. There is a period of time while the first caller is
> calling of_syscon_register() that subsequent callers also fail to find
> an entry in the syscon_list and then call of_syscon_register() a second
> time.
> 
> Fix this by keeping the lock held until after of_syscon_register()
> completes and adds the node to syscon_list. Convert the spinlock to a
> mutex as many of the functions called in of_syscon_register() may sleep.

Maybe mention the reason for conversion to mutex: lock will be now
containing non-atomic kzalloc and regmap_init_mmio, where the latter
calls clk_get and clk_prepare, which both are sleeping, I believe.

Otherwise it feels you are converting to mutex just to make code better,
which would be then a separate commit.

Everything else looks good.

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

Best regards,
Krzysztof


From karprzy7 at gmail.com  Thu Dec 12 01:34:24 2024
From: karprzy7 at gmail.com (Karol P)
Date: Thu, 12 Dec 2024 10:34:24 +0100
Subject: [PATCH] drm: zynqmp_dp: Fix integer overflow in zynqmp_dp_rate_get()
In-Reply-To: <20241211125936.GA23711@pendragon.ideasonboard.com>
References: <20241211122026.797511-1-karprzy7@gmail.com> <20241211125936.GA23711@pendragon.ideasonboard.com>
Message-ID: <CAKwoAfqFbZ0rWzYwX+WTJzMUE1K1Es_UtZj6YXwDKqs=HR6f5g@mail.gmail.com>

On Wed, 11 Dec 2024 at 13:59, Laurent Pinchart
<laurent.pinchart at ideasonboard.com> wrote:
>
> Hi Karol,
>
> Thank you for the patch.
>
> On Wed, Dec 11, 2024 at 01:20:26PM +0100, Karol Przybylski wrote:
> > This patch fixes a potential integer overflow in the zynqmp_dp_rate_get() function.
> >
> > The issue comes up when the expression drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000 is evaluated using 32-bit arithmetic.
>
> Please wrap your commit message text to 82 columns.
>
> >
> > Now the constant is casted to compatible u64 type.
> >
> > Resolves CID 1636340 and CID 1635811
> >
>
> Does this need a Fixes: tag ? How about 'Cc: stable at vger.kernel.org' to
> get it backported to stable kernels ?

Thanks for the feedback, I'll add it.

>
> > Signed-off-by: Karol Przybylski <karprzy7 at gmail.com>
> > ---
> >  drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > index 25c5dc61e..55e92344b 100644
> > --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > @@ -2190,7 +2190,7 @@ static int zynqmp_dp_rate_get(void *data, u64 *val)
> >       struct zynqmp_dp *dp = data;
> >
> >       mutex_lock(&dp->lock);
> > -     *val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000;
> > +     *val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * (u64)10000;
>
> You can also make the integer a 64-bit constant with
>
>         *val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000ULL;
>
> >       mutex_unlock(&dp->lock);
> >       return 0;
> >  }

It does look better. I will send v2 of this patch.

>
> --
> Regards,
>
> Laurent Pinchart


From ping.bai at nxp.com  Thu Dec 12 01:35:54 2024
From: ping.bai at nxp.com (Jacky Bai)
Date: Thu, 12 Dec 2024 17:35:54 +0800
Subject: [PATCH 0/1] Add i.MX943 basic dtsi support
Message-ID: <20241212093555.1376568-1-ping.bai@nxp.com>

The i.MX94 family is an i.MX MPU with an integrated time-sensitive
networking (TSN) switch, enabling configurable, secure communications
with rich protocol support in industrial and automotive environments.
This is also NXP?s first chip supporting future-proof, postquantum cryptography.
The multicore design of the i.MX 94 family delivers high-performance and low
latency across both application and real-time domains, with an integrated
functional safety island.

This chip offers a rich set of peripherals targeting industrial, automotive
telematics, and consumer IoT market segments. Part of the EdgeVerse portfolio
of intelligent edge solutions, the i.MX 943 family will be offered in commercial,
industrial, extended industrial and automotive level qualification and backed
by NXP?s product longevity program.

Jacky Bai (1):
  arm64: dts: freescale: Add basic dtsi for imx943

 arch/arm64/boot/dts/freescale/imx943-clock.h  |  196 +++
 .../arm64/boot/dts/freescale/imx943-pinfunc.h | 1542 +++++++++++++++++
 arch/arm64/boot/dts/freescale/imx943-power.h  |   41 +
 arch/arm64/boot/dts/freescale/imx943.dtsi     | 1284 ++++++++++++++
 4 files changed, 3063 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx943-clock.h
 create mode 100644 arch/arm64/boot/dts/freescale/imx943-pinfunc.h
 create mode 100644 arch/arm64/boot/dts/freescale/imx943-power.h
 create mode 100644 arch/arm64/boot/dts/freescale/imx943.dtsi

-- 
2.34.1



From defa.li at mediatek.com  Thu Dec 12 01:17:53 2024
From: defa.li at mediatek.com (Defa Li)
Date: Thu, 12 Dec 2024 17:17:53 +0800
Subject: [PATCH v2] i3c: master: Improve initialization of numbered I2C adapters
Message-ID: <20241212091818.8591-1-defa.li@mediatek.com>

Add logic to initialize I2C adapters with a specific ID if available,
improving device identification and configuration.

For mixed buses, in addition to the i3c alias, an i2c alias can be added to
assign a fixed bus number to the i2c adapter.

This allows an alias node such as:
    aliases {
        i2c2 = &mixed_bus_a,
        i3c2 = &mixed_bus_a,
        i3c4 = &mixed_bus_b,
    };

    /* assigned "i3c-2" and "i2c-2" */
    mixed_bus_a: i3c-master {
    };

If there is no i2c alias for a mixed bus, the i2c adapter numbers will
remain as is and will be assigned starting after the highest fixed bus
number.

    /* assigned "i3c-4" and likely assigned "i2c-3" */
    mixed_bus_b: i3c-master {
    };

v2:
  - Modify commit message and code format issues

Signed-off-by: Defa Li <defa.li at mediatek.com>
---
 drivers/i3c/master.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 42310c9a00c2..92223e0b6e59 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -2486,7 +2486,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
 	struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master);
 	struct i2c_dev_desc *i2cdev;
 	struct i2c_dev_boardinfo *i2cboardinfo;
-	int ret;
+	int ret, id = -ENODEV;
 
 	adap->dev.parent = master->dev.parent;
 	adap->owner = master->dev.parent->driver->owner;
@@ -2497,7 +2497,15 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
 	adap->timeout = 1000;
 	adap->retries = 3;
 
-	ret = i2c_add_adapter(adap);
+	if (master->dev.of_node)
+		id = of_alias_get_id(master->dev.of_node, "i2c");
+
+	if (id >= 0) {
+		adap->nr = id;
+		ret = i2c_add_numbered_adapter(adap);
+	} else {
+		ret = i2c_add_adapter(adap);
+	}
 	if (ret)
 		return ret;
 
-- 
2.46.0



From crystal.guo at mediatek.com  Thu Dec 12 00:59:46 2024
From: crystal.guo at mediatek.com (Crystal Guo)
Date: Thu, 12 Dec 2024 16:59:46 +0800
Subject: [PATCH 0/2] Add MediaTek DRAMC driver support
Message-ID: <20241212090029.13692-1-crystal.guo@mediatek.com>

This series is based on linux-next, tag: next-20241210.

Vcore DVFS feature need know the current DDR data rate.
Add MediaTek DRAMC driver to provide an interface that can
obtain current DDR data rate.

Crystal Guo (2):
  memory/mediatek: Add an interface to get current DDR data rate
  dt-bindings: memory-controllers: Add mediatek common-dramc dt-bindings

 .../mediatek,common-dramc.yaml                | 129 +++++++
 drivers/memory/Kconfig                        |   1 +
 drivers/memory/Makefile                       |   1 +
 drivers/memory/mediatek/Kconfig               |  21 ++
 drivers/memory/mediatek/Makefile              |   2 +
 drivers/memory/mediatek/mtk-dramc.c           | 325 ++++++++++++++++++
 include/linux/soc/mediatek/mtk-dramc.h        |  41 +++
 7 files changed, 520 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
 create mode 100644 drivers/memory/mediatek/Kconfig
 create mode 100644 drivers/memory/mediatek/Makefile
 create mode 100644 drivers/memory/mediatek/mtk-dramc.c
 create mode 100644 include/linux/soc/mediatek/mtk-dramc.h

-- 
2.18.0



From crystal.guo at mediatek.com  Thu Dec 12 00:59:47 2024
From: crystal.guo at mediatek.com (Crystal Guo)
Date: Thu, 12 Dec 2024 16:59:47 +0800
Subject: [PATCH 1/2] memory/mediatek: Add an interface to get current DDR data rate
In-Reply-To: <20241212090029.13692-1-crystal.guo@mediatek.com>
References: <20241212090029.13692-1-crystal.guo@mediatek.com>
Message-ID: <20241212090029.13692-2-crystal.guo@mediatek.com>

Add MediaTek DRAMC driver to provide an interface that can
obtain current DDR data rate.

Signed-off-by: Crystal Guo <crystal.guo at mediatek.com>
---
 drivers/memory/Kconfig                 |   1 +
 drivers/memory/Makefile                |   1 +
 drivers/memory/mediatek/Kconfig        |  21 ++
 drivers/memory/mediatek/Makefile       |   2 +
 drivers/memory/mediatek/mtk-dramc.c    | 325 +++++++++++++++++++++++++
 include/linux/soc/mediatek/mtk-dramc.h |  41 ++++
 6 files changed, 391 insertions(+)
 create mode 100644 drivers/memory/mediatek/Kconfig
 create mode 100644 drivers/memory/mediatek/Makefile
 create mode 100644 drivers/memory/mediatek/mtk-dramc.c
 create mode 100644 include/linux/soc/mediatek/mtk-dramc.h

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index c82d8d8a16ea..b1698549ff81 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -227,5 +227,6 @@ config STM32_FMC2_EBI
 
 source "drivers/memory/samsung/Kconfig"
 source "drivers/memory/tegra/Kconfig"
+source "drivers/memory/mediatek/Kconfig"
 
 endif
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index d2e6ca9abbe0..cf1091449d2e 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_STM32_FMC2_EBI)	+= stm32-fmc2-ebi.o
 
 obj-$(CONFIG_SAMSUNG_MC)	+= samsung/
 obj-$(CONFIG_TEGRA_MC)		+= tegra/
+obj-$(CONFIG_HAVE_MTK_MC)	+= mediatek/
 obj-$(CONFIG_TI_EMIF_SRAM)	+= ti-emif-sram.o
 obj-$(CONFIG_FPGA_DFL_EMIF)	+= dfl-emif.o
 
diff --git a/drivers/memory/mediatek/Kconfig b/drivers/memory/mediatek/Kconfig
new file mode 100644
index 000000000000..00764cdb157e
--- /dev/null
+++ b/drivers/memory/mediatek/Kconfig
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config HAVE_MTK_MC
+	bool "MediaTek Memory Controller support"
+	help
+	  This option allows to enable MediaTek memory controller drivers,
+	  which may include controllers for DRAM or others.
+	  Select Y here if you need support for MediaTek memory controller.
+	  If you don't need, select N.
+
+if HAVE_MTK_MC
+
+config MTK_DRAMC
+	tristate "MediaTek DRAMC driver"
+	depends on HAVE_MTK_MC
+	help
+	  This option selects the MediaTek DRAMC driver, which provides
+	  an interface for reporting the current data rate of DRAM.
+	  Select Y here if you need support for the MediaTek DRAMC driver.
+	  If you don't need, select N.
+
+endif
diff --git a/drivers/memory/mediatek/Makefile b/drivers/memory/mediatek/Makefile
new file mode 100644
index 000000000000..a1395fc55b41
--- /dev/null
+++ b/drivers/memory/mediatek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_MTK_DRAMC)		+= mtk-dramc.o
diff --git a/drivers/memory/mediatek/mtk-dramc.c b/drivers/memory/mediatek/mtk-dramc.c
new file mode 100644
index 000000000000..9c2c8e187a4a
--- /dev/null
+++ b/drivers/memory/mediatek/mtk-dramc.c
@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 MediaTek Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/printk.h>
+#include <linux/io.h>
+#include <linux/soc/mediatek/mtk-dramc.h>
+
+static struct platform_device *dramc_pdev;
+static struct platform_driver dramc_drv;
+
+static int fmeter_init(struct platform_device *pdev,
+		       struct fmeter_dev_t *fmeter_dev_ptr, unsigned int fmeter_version)
+{
+	struct device_node *dramc_node = pdev->dev.of_node;
+	int ret;
+
+	ret = of_property_read_u32(dramc_node,
+				   "crystal-freq", &(fmeter_dev_ptr->crystal_freq));
+	ret |= of_property_read_u32(dramc_node,
+				    "shu-of", &(fmeter_dev_ptr->shu_of));
+	ret |= of_property_read_u32_array(dramc_node,
+					  "shu-lv", (unsigned int *)&(fmeter_dev_ptr->shu_lv), 3);
+	ret |= of_property_read_u32_array(dramc_node,
+					  "pll-id", (unsigned int *)&(fmeter_dev_ptr->pll_id), 3);
+	ret |= of_property_read_u32_array(dramc_node,
+					  "sdmpcw", (unsigned int *)(fmeter_dev_ptr->sdmpcw), 6);
+	ret |= of_property_read_u32_array(dramc_node,
+					  "posdiv", (unsigned int *)(fmeter_dev_ptr->posdiv), 6);
+	ret |= of_property_read_u32_array(dramc_node,
+					  "fbksel", (unsigned int *)(fmeter_dev_ptr->fbksel), 6);
+	ret |= of_property_read_u32_array(dramc_node,
+					  "dqsopen", (unsigned int *)(fmeter_dev_ptr->dqsopen), 6);
+	if (fmeter_version == 1) {
+		fmeter_dev_ptr->version = 1;
+		ret |= of_property_read_u32_array(dramc_node,
+			"async-ca", (unsigned int *)(fmeter_dev_ptr->async_ca), 6);
+		ret |= of_property_read_u32_array(dramc_node,
+			"dq-ser-mode", (unsigned int *)(fmeter_dev_ptr->dq_ser_mode), 6);
+	}
+	return ret;
+}
+
+static ssize_t dram_data_rate_show(struct device_driver *driver, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "DRAM data rate = %d\n",
+		mtk_dramc_get_data_rate());
+}
+
+static DRIVER_ATTR_RO(dram_data_rate);
+
+static int dramc_probe(struct platform_device *pdev)
+{
+	struct device_node *dramc_node = pdev->dev.of_node;
+	struct dramc_dev_t *dramc_dev_ptr;
+	unsigned int fmeter_version;
+	struct resource *res;
+	unsigned int i, size;
+	int ret;
+
+	pr_info("%s: module probe.\n", __func__);
+	dramc_pdev = pdev;
+	dramc_dev_ptr = devm_kmalloc(&pdev->dev,
+				     sizeof(struct dramc_dev_t), GFP_KERNEL);
+
+	if (!dramc_dev_ptr)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(dramc_node,
+				   "support-ch-cnt", &dramc_dev_ptr->support_ch_cnt);
+	if (ret) {
+		pr_info("%s: get support_ch_cnt fail\n", __func__);
+		return -EINVAL;
+	}
+
+	dramc_dev_ptr->sleep_base = of_iomap(dramc_node,
+					     dramc_dev_ptr->support_ch_cnt * 4);
+	if (IS_ERR(dramc_dev_ptr->sleep_base)) {
+		pr_info("%s: unable to map sleep base\n", __func__);
+		return -EINVAL;
+	}
+
+	size = sizeof(phys_addr_t) * dramc_dev_ptr->support_ch_cnt;
+	dramc_dev_ptr->dramc_chn_base_ao = devm_kmalloc(&pdev->dev,
+							size, GFP_KERNEL);
+	if (!(dramc_dev_ptr->dramc_chn_base_ao))
+		return -ENOMEM;
+	dramc_dev_ptr->dramc_chn_base_nao = devm_kmalloc(&pdev->dev,
+							 size, GFP_KERNEL);
+	if (!(dramc_dev_ptr->dramc_chn_base_nao))
+		return -ENOMEM;
+	dramc_dev_ptr->ddrphy_chn_base_ao = devm_kmalloc(&pdev->dev,
+							 size, GFP_KERNEL);
+	if (!(dramc_dev_ptr->ddrphy_chn_base_ao))
+		return -ENOMEM;
+	dramc_dev_ptr->ddrphy_chn_base_nao = devm_kmalloc(&pdev->dev,
+							  size, GFP_KERNEL);
+	if (!(dramc_dev_ptr->ddrphy_chn_base_nao))
+		return -ENOMEM;
+
+	for (i = 0; i < dramc_dev_ptr->support_ch_cnt; i++) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		dramc_dev_ptr->dramc_chn_base_ao[i] =
+			devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(dramc_dev_ptr->dramc_chn_base_ao[i])) {
+			pr_info("%s: unable to map ch%d DRAMC AO base\n",
+				__func__, i);
+			return -EINVAL;
+		}
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM,
+					    i + dramc_dev_ptr->support_ch_cnt);
+		dramc_dev_ptr->dramc_chn_base_nao[i] =
+			devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(dramc_dev_ptr->dramc_chn_base_nao[i])) {
+			pr_info("%s: unable to map ch%d DRAMC NAO base\n",
+				__func__, i);
+			return -EINVAL;
+		}
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM,
+					    i + dramc_dev_ptr->support_ch_cnt * 2);
+		dramc_dev_ptr->ddrphy_chn_base_ao[i] =
+			devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(dramc_dev_ptr->ddrphy_chn_base_ao[i])) {
+			pr_info("%s: unable to map ch%d DDRPHY AO base\n",
+				__func__, i);
+			return -EINVAL;
+		}
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM,
+					    i + dramc_dev_ptr->support_ch_cnt * 3);
+		dramc_dev_ptr->ddrphy_chn_base_nao[i] =
+			devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(dramc_dev_ptr->ddrphy_chn_base_nao[i])) {
+			pr_info("%s: unable to map ch%d DDRPHY NAO base\n",
+				__func__, i);
+			return -EINVAL;
+		}
+	}
+
+	ret = of_property_read_u32(dramc_node, "fmeter-version", &fmeter_version);
+	if (ret) {
+		pr_info("%s: get fmeter_version fail\n", __func__);
+		return -EINVAL;
+	}
+	pr_info("%s: fmeter_version(%d)\n", __func__, fmeter_version);
+
+	if (fmeter_version == 1) {
+		dramc_dev_ptr->fmeter_dev_ptr = devm_kmalloc(&pdev->dev,
+							     sizeof(struct fmeter_dev_t),
+							     GFP_KERNEL);
+		if (!(dramc_dev_ptr->fmeter_dev_ptr)) {
+			pr_info("%s: memory  alloc fail\n", __func__);
+			return -ENOMEM;
+		}
+		ret = fmeter_init(pdev, dramc_dev_ptr->fmeter_dev_ptr, fmeter_version);
+		if (ret) {
+			pr_info("%s: fmeter_init fail\n", __func__);
+			return -EINVAL;
+		}
+	} else {
+		dramc_dev_ptr->fmeter_dev_ptr = NULL;
+	}
+	ret = driver_create_file(pdev->dev.driver, &driver_attr_dram_data_rate);
+	if (ret) {
+		pr_info("%s: fail to create dram_data_rate sysfs\n", __func__);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, dramc_dev_ptr);
+	pr_info("%s: DRAM data rate = %d\n", __func__,
+		mtk_dramc_get_data_rate());
+
+	return ret;
+}
+
+static unsigned int fmeter_v1(struct dramc_dev_t *dramc_dev_ptr)
+{
+	struct fmeter_dev_t *fmeter_dev_ptr =
+		(struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr;
+	unsigned int shu_lv_val;
+	unsigned int pll_id_val;
+	unsigned int sdmpcw_val;
+	unsigned int posdiv_val;
+	unsigned int ckdiv4_val;
+	unsigned int offset;
+	unsigned int vco_freq;
+	unsigned int fbksel;
+	unsigned int dqsopen;
+	unsigned int async_ca;
+	unsigned int dq_ser_mode;
+
+	shu_lv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] +
+		fmeter_dev_ptr->shu_lv.offset) &
+		fmeter_dev_ptr->shu_lv.mask) >>
+		fmeter_dev_ptr->shu_lv.shift;
+
+	pll_id_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] +
+		fmeter_dev_ptr->pll_id.offset) &
+		fmeter_dev_ptr->pll_id.mask) >>
+		fmeter_dev_ptr->pll_id.shift;
+
+	offset = fmeter_dev_ptr->sdmpcw[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	sdmpcw_val = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
+		fmeter_dev_ptr->sdmpcw[pll_id_val].mask) >>
+		fmeter_dev_ptr->sdmpcw[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->posdiv[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	posdiv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
+		fmeter_dev_ptr->posdiv[pll_id_val].mask) >>
+		fmeter_dev_ptr->posdiv[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->fbksel[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	fbksel = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
+		fmeter_dev_ptr->fbksel[pll_id_val].mask) >>
+		fmeter_dev_ptr->fbksel[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->dqsopen[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	dqsopen = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
+		fmeter_dev_ptr->dqsopen[pll_id_val].mask) >>
+		fmeter_dev_ptr->dqsopen[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->async_ca[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	async_ca = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
+		fmeter_dev_ptr->async_ca[pll_id_val].mask) >>
+		fmeter_dev_ptr->async_ca[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->dq_ser_mode[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	dq_ser_mode = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
+		fmeter_dev_ptr->dq_ser_mode[pll_id_val].mask) >>
+		fmeter_dev_ptr->dq_ser_mode[pll_id_val].shift;
+	ckdiv4_val = (dq_ser_mode == 1); // 1: DIV4, 2: DIV8, 3: DIV16
+
+	posdiv_val &= ~(0x4);
+
+	vco_freq = ((fmeter_dev_ptr->crystal_freq) *
+		(sdmpcw_val >> 7)) >> posdiv_val >> 1 >> ckdiv4_val
+		<< fbksel;
+
+	if ((dqsopen == 1) && (async_ca == 1))
+		vco_freq >>= 1;
+
+	return vco_freq;
+}
+
+/*
+ * mtk_dramc_get_data_rate - calculate DRAM data rate
+ *
+ * Returns DRAM data rate (MB/s)
+ */
+unsigned int mtk_dramc_get_data_rate(void)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+	struct fmeter_dev_t *fmeter_dev_ptr;
+
+	if (!dramc_pdev)
+		return 0;
+
+	dramc_dev_ptr =
+		(struct dramc_dev_t *)platform_get_drvdata(dramc_pdev);
+
+	fmeter_dev_ptr = (struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr;
+	if (!fmeter_dev_ptr)
+		return 0;
+
+	if (fmeter_dev_ptr->version == 1)
+		return fmeter_v1(dramc_dev_ptr);
+	return 0;
+}
+EXPORT_SYMBOL(mtk_dramc_get_data_rate);
+
+static int dramc_remove(struct platform_device *pdev)
+{
+	dramc_pdev = NULL;
+
+	return 0;
+}
+
+static const struct of_device_id dramc_of_ids[] = {
+	{.compatible = "mediatek,common-dramc",},
+	{}
+};
+
+static struct platform_driver dramc_drv = {
+	.probe = dramc_probe,
+	.remove = dramc_remove,
+	.driver = {
+		.name = "dramc_drv",
+		.owner = THIS_MODULE,
+		.of_match_table = dramc_of_ids,
+	},
+};
+
+static int __init dramc_drv_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&dramc_drv);
+	if (ret) {
+		pr_info("%s: init fail, ret 0x%x\n", __func__, ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+module_init(dramc_drv_init);
+
+MODULE_AUTHOR("Mediatek Corporation");
+MODULE_DESCRIPTION("MediaTek DRAMC Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/soc/mediatek/mtk-dramc.h b/include/linux/soc/mediatek/mtk-dramc.h
new file mode 100644
index 000000000000..95e7dbfe7d0e
--- /dev/null
+++ b/include/linux/soc/mediatek/mtk-dramc.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef __MTK_DRAMC_H__
+#define __MTK_DRAMC_H__
+
+struct reg_ctrl_t {
+	unsigned int offset;
+	unsigned int mask;
+	unsigned int shift;
+};
+
+struct fmeter_dev_t {
+	unsigned int version;
+	unsigned int crystal_freq;
+	unsigned int shu_of;
+	struct reg_ctrl_t shu_lv;
+	struct reg_ctrl_t pll_id;
+	struct reg_ctrl_t sdmpcw[2];
+	struct reg_ctrl_t posdiv[2];
+	struct reg_ctrl_t fbksel[2];
+	struct reg_ctrl_t dqsopen[2];
+	struct reg_ctrl_t async_ca[2];
+	struct reg_ctrl_t dq_ser_mode[2];
+};
+
+struct dramc_dev_t {
+	unsigned int support_ch_cnt;
+	void __iomem **dramc_chn_base_ao;
+	void __iomem **dramc_chn_base_nao;
+	void __iomem **ddrphy_chn_base_ao;
+	void __iomem **ddrphy_chn_base_nao;
+	void __iomem *sleep_base;
+	void *fmeter_dev_ptr;
+};
+
+unsigned int mtk_dramc_get_data_rate(void);
+
+#endif /* __MTK_DRAMC_H__ */
-- 
2.18.0



From crystal.guo at mediatek.com  Thu Dec 12 00:59:48 2024
From: crystal.guo at mediatek.com (Crystal Guo)
Date: Thu, 12 Dec 2024 16:59:48 +0800
Subject: [PATCH 2/2] dt-bindings: memory-controllers: Add mediatek common-dramc dt-bindings
In-Reply-To: <20241212090029.13692-1-crystal.guo@mediatek.com>
References: <20241212090029.13692-1-crystal.guo@mediatek.com>
Message-ID: <20241212090029.13692-3-crystal.guo@mediatek.com>

Add devicetree binding for mediatek common-dramc driver.

The DRAM controller of MediaTek SoC provides an interface to
get the current data rate of DRAM.

Signed-off-by: Crystal Guo <crystal.guo at mediatek.com>
---
 .../mediatek,common-dramc.yaml                | 129 ++++++++++++++++++
 1 file changed, 129 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
new file mode 100644
index 000000000000..c9e608c7f183
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
@@ -0,0 +1,129 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+# Copyright (c) 2024 MediaTek Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/mediatek,common-dramc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Common DRAMC (DRAM Controller)
+
+maintainers:
+  - Crystal Guo <crystal.guo at mediatek.com>
+
+description: |
+  The DRAM controller of MediaTek SoC provides an interface to
+  get the current data rate of DRAM.
+
+properties:
+  compatible:
+    const: mediatek,common-dramc
+
+  reg:
+    minItems: 9
+    items:
+      - description: DRAMC_AO_CHA_BASE
+      - description: DRAMC_AO_CHB_BASE
+      - description: DRAMC_AO_CHC_BASE
+      - description: DRAMC_AO_CHD_BASE
+      - description: DRAMC_NAO_CHA_BASE
+      - description: DRAMC_NAO_CHB_BASE
+      - description: DRAMC_NAO_CHC_BASE
+      - description: DRAMC_NAO_CHD_BASE
+      - description: DDRPHY_AO_CHA_BASE
+      - description: DDRPHY_AO_CHB_BASE
+      - description: DDRPHY_AO_CHC_BASE
+      - description: DDRPHY_AO_CHD_BASE
+      - description: DDRPHY_NAO_CHA_BASE
+      - description: DDRPHY_NAO_CHB_BASE
+      - description: DDRPHY_NAO_CHC_BASE
+      - description: DDRPHY_NAO_CHD_BASE
+      - description: SLEEP_BASE
+
+  support-ch-cnt:
+    maxItems: 1
+
+  fmeter-version:
+    maxItems: 1
+    description:
+      Fmeter version for calculating dram data rate
+
+  crystal-freq:
+    maxItems: 1
+    description:
+      Reference clock rate in MHz
+
+  shu-of:
+    maxItems: 1
+
+  pll-id: true
+  shu-lv: true
+  sdmpcw: true
+  posdiv: true
+  fbksel: true
+  dqsopen: true
+  async-ca: true
+  dq-ser-mode: true
+
+required:
+  - compatible
+  - reg
+  - support-ch-cnt
+  - fmeter-version
+  - crystal-freq
+  - pll-id
+  - shu-lv
+  - shu-of
+  - sdmpcw
+  - posdiv
+  - fbksel
+  - dqsopen
+  - async-ca
+  - dq-ser-mode
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        dramc: dramc at 10230000 {
+            compatible = "mediatek,common-dramc";
+            reg = <0 0x10230000 0 0x2000>, /* DRAMC_AO_CHA_BASE */
+                <0 0x10240000 0 0x2000>, /* DRAMC_AO_CHB_BASE */
+                <0 0x10250000 0 0x2000>, /* DRAMC_AO_CHC_BASE */
+                <0 0x10260000 0 0x2000>, /* DRAMC_AO_CHD_BASE */
+                <0 0x10234000 0 0x1000>, /* DRAMC_NAO_CHA_BASE */
+                <0 0x10244000 0 0x1000>, /* DRAMC_NAO_CHB_BASE */
+                <0 0x10254000 0 0x1000>, /* DRAMC_NAO_CHC_BASE */
+                <0 0x10264000 0 0x1000>, /* DRAMC_NAO_CHD_BASE */
+                <0 0x10238000 0 0x2000>, /* DDRPHY_AO_CHA_BASE */
+                <0 0x10248000 0 0x2000>, /* DDRPHY_AO_CHB_BASE */
+                <0 0x10258000 0 0x2000>, /* DDRPHY_AO_CHC_BASE */
+                <0 0x10268000 0 0x2000>, /* DDRPHY_AO_CHD_BASE */
+                <0 0x10236000 0 0x2000>, /* DDRPHY_NAO_CHA_BASE */
+                <0 0x10246000 0 0x2000>, /* DDRPHY_NAO_CHB_BASE */
+                <0 0x10256000 0 0x2000>, /* DDRPHY_NAO_CHC_BASE */
+                <0 0x10266000 0 0x2000>, /* DDRPHY_NAO_CHD_BASE */
+                <0 0x10006000 0 0x1000>; /* SLEEP_BASE */
+            support-ch-cnt = <4>;
+            fmeter-version = <1>;
+            crystal-freq = <26>;
+            pll-id = <0x0e98 0x02000000 25>;
+            shu-lv = <0x0e98 0x0000c000 14>;
+            shu-of = <0x700>;
+            sdmpcw = <0x0908 0x0007fff8 3>,
+                <0x0928 0x0007fff8 3>;
+            posdiv = <0x090c 0x00003800 11>,
+                <0x092c 0x00003800 11>;
+            fbksel = <0x0910 0x00000040 6>,
+                <0x0910 0x00000040 6>;
+            dqsopen = <0x0d94 0x04000000 26>,
+                <0x0d94 0x04000000 26>;
+            async-ca = <0x0d08 0x00000001 0>,
+                <0x0d08 0x00000001 0>;
+            dq-ser-mode = <0x0dc4 0x00000018 3>,
+                <0x0dc4 0x00000018 3>;
+        };
+    };
-- 
2.18.0



From richard.xnu.clark at gmail.com  Thu Dec 12 01:18:56 2024
From: richard.xnu.clark at gmail.com (richard clark)
Date: Thu, 12 Dec 2024 17:18:56 +0800
Subject: Question about interrupt prioriyt of ARM GICv3/4
In-Reply-To: <86cyi5tanz.wl-maz@kernel.org>
References: <CAJNi4rMfhZOCT+7Ki14vUs+dZbv9cxCZ0s+jgn6=_om4NTgo_A@mail.gmail.com>
 <86cyi5tanz.wl-maz@kernel.org>
Message-ID: <CAJNi4rPDVXS3Ft3nHLXvMzHmn9d10Nz4Pxeduoe+v5HaK=CEAg@mail.gmail.com>

Hi M,

On Fri, Dec 6, 2024 at 5:37?PM Marc Zyngier <maz at kernel.org> wrote:
>
> On Fri, 06 Dec 2024 08:33:11 +0000,
> richard clark <richard.xnu.clark at gmail.com> wrote:
> >
> > Hi,
> > Currently seems the GICv3/4 irqchip configures all the interrupts as
> > the same priority, I am thinking about to minimize the latency of the
> > interrupt for a particular device, e.g, the arm arch_timer in the RTL
> > system. The question is,
> > 1. Why don't we provide a /proc or /sys interface for the enduser to
> > set the priority of a specific interrupt(SPI/PPI)?
>
> I'm afraid this really has nothing to do with any particular interrupt
> architecture.
>
> Before thinking of exposing the interrupt priority to userspace, you
> should look at what this translates into for the kernel once you allow
> interrupts to be preempted by another one with a higher priority.
>
Interrupt priority doesn't necessarily mean the preemption, seems
you're talking about the interrupt preemption harm according to your
statement followed.Frankly I am just thinking higher priority will win
the lower ones in case massive external interrupts received in the GIC
level (you see I am still talking about GIC, not kernel)
>
> This means that at every point where you would normally see a
> local_irq_save(), spinlock_irqsave() or equivalent, you would need to
> explicitly specify the priority that you allow for preemption. You
> should then make sure that any code that can be run during an
> interrupt is reentrant. You need to define which data structures can
> be manipulated at which priority level... The list goes on.
>
irqsave just masks the interrupt from the point of cpu, I don't think
it will mess things up if preemption really happens (no? then what the
side-effect is for the nested interrupt handling in the softirq part.
damage the semantic of the lock primitives?)
>
> If you want a small taste of the complexity, just look at what
> handling NMIs (or even pseudo-NMIs in the case of GICv3) means, and
> generalise it to not just two, but an arbitrary range of priorities.
>
> If you want the full blown experience, look at the BSDs and their use
> of spl*(). I don't think anyone has any plan to get there, and the RT
> patches have shown that there is little need for it.
>
As supplement?the fiq is suggested to be used as an alternative to the
higher priority in the RT area...
>
> > 2. Is there any way to verify the higher priority interrupt will have
> > more dominant to be selected to the CPU (IOW, the priority is really
> > working) in case of multiple different interrupts asserted to the GIC
> > at the same time(some debug registers of GIC like GICD_REEMPT_CNT :-)
> > to record higher priority wins)?
>
> The GIC architecture makes no promise that the interrupt you
> acknowledge is the highest priority pending interrupt, because this is
> by definition a very racy process.
>
> Also, even on busy systems, you will very rarely see two interrupts
> targeting the same CPU being made pending at the same time, so that
> the interrupt delivery system would have to arbitrate between the two.
> That's because interrupts are vanishingly rare in the grand scheme of
> things.
>
1. I am trying to stress the external interrupts to the core#0 via the
stress-ng tool with one of interrupt being configured as higher
priority to see the benchmark data, it's time consuming as you can
image, still is in progress(BTW, I can't see any lockup similar hang
in the system with a higher priority configured)
2. This raises a very interesting question and I am also very curious
about is, what is the purpose for the GIC to introduce the interrupt
priority features, a placeholder feature reserved for the future? Ah,
hardware prefer to provide more functionalities than its being
actually used by software, any other justification except that?
>
> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


From alain.volmat at foss.st.com  Thu Dec 12 01:17:35 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:35 +0100
Subject: [PATCH v4 11/15] media: stm32: dcmipp: fill media ctl hw_revision
 field
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-11-fbeb55a05ed7@foss.st.com>

Add hw_revision field information of the media controller so that
application can distinguish between variants of DCMIPP implementations.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

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 97590079bb5a..62dd17e0488d 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
@@ -87,6 +87,7 @@ struct dcmipp_pipeline_config {
 	size_t num_ents;
 	const struct dcmipp_ent_link *links;
 	size_t num_links;
+	u32 hw_revision;
 };
 
 /* --------------------------------------------------------------------------
@@ -122,11 +123,13 @@ static const struct dcmipp_ent_link stm32mp13_ent_links[] = {
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
 };
 
+#define DCMIPP_STM32MP13_VERR	0x10
 static const struct dcmipp_pipeline_config stm32mp13_pipe_cfg = {
 	.ents		= stm32mp13_ent_config,
 	.num_ents	= ARRAY_SIZE(stm32mp13_ent_config),
 	.links		= stm32mp13_ent_links,
-	.num_links	= ARRAY_SIZE(stm32mp13_ent_links)
+	.num_links	= ARRAY_SIZE(stm32mp13_ent_links),
+	.hw_revision	= DCMIPP_STM32MP13_VERR
 };
 
 #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\
@@ -496,6 +499,7 @@ static int dcmipp_probe(struct platform_device *pdev)
 	/* Initialize media device */
 	strscpy(dcmipp->mdev.model, DCMIPP_MDEV_MODEL_NAME,
 		sizeof(dcmipp->mdev.model));
+	dcmipp->mdev.hw_revision = pipe_cfg->hw_revision;
 	dcmipp->mdev.dev = &pdev->dev;
 	media_device_init(&dcmipp->mdev);
 

-- 
2.34.1



From alain.volmat at foss.st.com  Thu Dec 12 01:17:37 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 12 Dec 2024 10:17:37 +0100
Subject: [PATCH v4 13/15] media: stm32: dcmipp: add core support for the
 stm32mp25
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <20241212-csi_dcmipp_mp25-v4-13-fbeb55a05ed7@foss.st.com>

The stm32mp25 supports both parallel & csi inputs.
An additional clock control is necessary.
Skeleton of the subdev structures for the stm32mp25 is added,
identical for the time being to the stm32mp13 however more subdeves
will be added in further commits.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
v4:
  - correct clock handling within dcmipp_runtime_resume
---
 .../platform/st/stm32/stm32-dcmipp/dcmipp-core.c   | 104 +++++++++++++++++----
 1 file changed, 85 insertions(+), 19 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 62dd17e0488d..71acf539e1f3 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
@@ -40,6 +40,7 @@ struct dcmipp_device {
 
 	/* Hardware resources */
 	void __iomem			*regs;
+	struct clk			*mclk;
 	struct clk			*kclk;
 
 	/* The pipeline configuration */
@@ -132,6 +133,40 @@ static const struct dcmipp_pipeline_config stm32mp13_pipe_cfg = {
 	.hw_revision	= DCMIPP_STM32MP13_VERR
 };
 
+static const struct dcmipp_ent_config stm32mp25_ent_config[] = {
+	{
+		.name = "dcmipp_input",
+		.init = dcmipp_inp_ent_init,
+		.release = dcmipp_inp_ent_release,
+	},
+	{
+		.name = "dcmipp_dump_postproc",
+		.init = dcmipp_byteproc_ent_init,
+		.release = dcmipp_byteproc_ent_release,
+	},
+	{
+		.name = "dcmipp_dump_capture",
+		.init = dcmipp_bytecap_ent_init,
+		.release = dcmipp_bytecap_ent_release,
+	},
+};
+
+static const struct dcmipp_ent_link stm32mp25_ent_links[] = {
+	DCMIPP_ENT_LINK(ID_INPUT, 1, ID_DUMP_BYTEPROC, 0,
+			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
+	DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE,  0,
+			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
+};
+
+#define DCMIPP_STM32MP25_VERR  0x30
+static const struct dcmipp_pipeline_config stm32mp25_pipe_cfg = {
+	.ents		= stm32mp25_ent_config,
+	.num_ents	= ARRAY_SIZE(stm32mp25_ent_config),
+	.links		= stm32mp25_ent_links,
+	.num_links	= ARRAY_SIZE(stm32mp25_ent_links),
+	.hw_revision    = DCMIPP_STM32MP25_VERR
+};
+
 #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\
 			     (f) == MEDIA_LNK_FL_ENABLED ? "ENABLED" :\
 			     (f) == MEDIA_LNK_FL_IMMUTABLE ? "IMMUTABLE" :\
@@ -212,6 +247,7 @@ static int dcmipp_create_subdevs(struct dcmipp_device *dcmipp)
 
 static const struct of_device_id dcmipp_of_match[] = {
 	{ .compatible = "st,stm32mp13-dcmipp", .data = &stm32mp13_pipe_cfg },
+	{ .compatible = "st,stm32mp25-dcmipp", .data = &stm32mp25_pipe_cfg },
 	{ /* end node */ },
 };
 MODULE_DEVICE_TABLE(of, dcmipp_of_match);
@@ -261,13 +297,22 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
 {
 	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
 	unsigned int ret;
-	int src_pad;
+	int src_pad, i;
 	struct dcmipp_ent_device *sink;
-	struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL };
+	struct v4l2_fwnode_endpoint vep = { 0 };
 	struct fwnode_handle *ep;
+	enum v4l2_mbus_type supported_types[] = {
+		V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, V4L2_MBUS_CSI2_DPHY
+	};
+	int supported_types_nb = ARRAY_SIZE(supported_types);
 
 	dev_dbg(dcmipp->dev, "Subdev \"%s\" bound\n", subdev->name);
 
+	/* Only MP25 supports CSI input */
+	if (!of_device_is_compatible(dcmipp->dev->of_node,
+				     "st,stm32mp25-dcmipp"))
+		supported_types_nb--;
+
 	/*
 	 * Link this sub-device to DCMIPP, it could be
 	 * a parallel camera sensor or a CSI-2 to parallel bridge
@@ -284,21 +329,23 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
 		return -ENODEV;
 	}
 
-	/* Check for parallel bus-type first, then bt656 */
-	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
-	if (ret) {
-		vep.bus_type = V4L2_MBUS_BT656;
+	/* Check for supported MBUS type */
+	for (i = 0; i < supported_types_nb; i++) {
+		vep.bus_type = supported_types[i];
 		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
-		if (ret) {
-			dev_err(dcmipp->dev, "Could not parse the endpoint\n");
-			fwnode_handle_put(ep);
-			return ret;
-		}
+		if (!ret)
+			break;
 	}
 
 	fwnode_handle_put(ep);
 
-	if (vep.bus.parallel.bus_width == 0) {
+	if (ret) {
+		dev_err(dcmipp->dev, "Could not parse the endpoint\n");
+		return ret;
+	}
+
+	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY &&
+	    vep.bus.parallel.bus_width == 0) {
 		dev_err(dcmipp->dev, "Invalid parallel interface bus-width\n");
 		return -ENODEV;
 	}
@@ -311,11 +358,13 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
 		return -ENODEV;
 	}
 
-	/* Parallel input device detected, connect it to parallel subdev */
+	/* Connect input device to the dcmipp_input subdev */
 	sink = dcmipp->entity[ID_INPUT];
-	sink->bus.flags = vep.bus.parallel.flags;
-	sink->bus.bus_width = vep.bus.parallel.bus_width;
-	sink->bus.data_shift = vep.bus.parallel.data_shift;
+	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) {
+		sink->bus.flags = vep.bus.parallel.flags;
+		sink->bus.bus_width = vep.bus.parallel.bus_width;
+		sink->bus.data_shift = vep.bus.parallel.data_shift;
+	}
 	sink->bus_type = vep.bus_type;
 	ret = media_create_pad_link(&subdev->entity, src_pad, sink->ent, 0,
 				    MEDIA_LNK_FL_IMMUTABLE |
@@ -414,7 +463,7 @@ static int dcmipp_graph_init(struct dcmipp_device *dcmipp)
 static int dcmipp_probe(struct platform_device *pdev)
 {
 	struct dcmipp_device *dcmipp;
-	struct clk *kclk;
+	struct clk *kclk, *mclk;
 	const struct dcmipp_pipeline_config *pipe_cfg;
 	struct reset_control *rstc;
 	int irq;
@@ -474,12 +523,20 @@ static int dcmipp_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	kclk = devm_clk_get(&pdev->dev, NULL);
+	kclk = devm_clk_get(&pdev->dev, "kclk");
 	if (IS_ERR(kclk))
 		return dev_err_probe(&pdev->dev, PTR_ERR(kclk),
 				     "Unable to get kclk\n");
 	dcmipp->kclk = kclk;
 
+	if (!of_device_is_compatible(pdev->dev.of_node, "st,stm32mp13-dcmipp")) {
+		mclk = devm_clk_get(&pdev->dev, "mclk");
+		if (IS_ERR(mclk))
+			return dev_err_probe(&pdev->dev, PTR_ERR(mclk),
+					     "Unable to get mclk\n");
+		dcmipp->mclk = mclk;
+	}
+
 	dcmipp->entity = devm_kcalloc(&pdev->dev, dcmipp->pipe_cfg->num_ents,
 				      sizeof(*dcmipp->entity), GFP_KERNEL);
 	if (!dcmipp->entity)
@@ -542,6 +599,7 @@ static int dcmipp_runtime_suspend(struct device *dev)
 	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
 
 	clk_disable_unprepare(dcmipp->kclk);
+	clk_disable_unprepare(dcmipp->mclk);
 
 	return 0;
 }
@@ -551,9 +609,17 @@ static int dcmipp_runtime_resume(struct device *dev)
 	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
 	int ret;
 
+	ret = clk_prepare_enable(dcmipp->mclk);
+	if (ret) {
+		dev_err(dev, "%s: Failed to prepare_enable mclk\n", __func__);
+		return ret;
+	}
+
 	ret = clk_prepare_enable(dcmipp->kclk);
-	if (ret)
+	if (ret) {
+		clk_disable_unprepare(dcmipp->mclk);
 		dev_err(dev, "%s: Failed to prepare_enable kclk\n", __func__);
+	}
 
 	return ret;
 }

-- 
2.34.1



From will at kernel.org  Thu Dec 12 01:41:28 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Dec 2024 09:41:28 +0000
Subject: [PATCH RESEND kvmtool 0/4] arm: Payload memory layout change
In-Reply-To: <173395873873.2737640.3783988676491071650.b4-ty@kernel.org>
References: <20241128151246.10858-1-alexandru.elisei@arm.com>
 <173395873873.2737640.3783988676491071650.b4-ty@kernel.org>
Message-ID: <20241212094127.GA18819@willie-the-truck>

On Wed, Dec 11, 2024 at 11:44:14PM +0000, Will Deacon wrote:
> On Thu, 28 Nov 2024 15:12:42 +0000, Alexandru Elisei wrote:
> > (resending because I accidently only sent the cover letter, sorry for that)
> > 
> > The first 3 patches are fixes to kvm__arch_load_kernel_image(). I've CC'ed
> > the riscv maintainer because it looks to me like riscv is similarly
> > affected.
> > 
> > Patch #4 ("arm64: Increase the payload memory region size to 512MB") might
> > be controversial. Follows a bug report I received from Abdollahi Sina in
> > private. Details in the commit message, but the gist of the patch is that
> > the memory region where kernel + initrd + DTB are copied to are changed
> > from 256MB to 512MB.  As a result, the DTB and initrd are moved from below
> > ram_start + 256MB to ram_start + 512MB to accomodate a larger initrd.  If
> > users rely on finding the DTB and initrd at the current addresses, then I'm
> > not sure the patch is justified - after all, if someone really wants to use
> > such a large initrd instead of a disk image with virtio, then replacing
> > SZ_256M with SZ_512M locally doesn't look like a big ask.
> > 
> > [...]
> 
> Applied to arm64 (sina), thanks!
> 
> [1/4] arm: Fix off-by-one errors when computing payload memory layout
>       https://git.kernel.org/arm64/c/167aa1e
> [2/4] arm: Check return value for host_to_guest_flat()
>       https://git.kernel.org/arm64/c/ca57fb6
> [3/4] arm64: Use the kernel header image_size when loading into memory
>       https://git.kernel.org/arm64/c/32345de
> [4/4] arm64: Increase the payload memory region size to 512MB
>       https://git.kernel.org/arm64/c/9b26a8e

Sorry, these links are all broken as I generated the thankyou note
against a testing branch. Rest assured that the changes are pushed to
the kvmtool.git:

https://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git/

Will


From cassel at kernel.org  Thu Dec 12 01:43:57 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Thu, 12 Dec 2024 10:43:57 +0100
Subject: [PATCH v2] PCI: rockchip-ep: Fix error code in
 rockchip_pcie_ep_init_ob_mem()
In-Reply-To: <Z014ylYz_xrrgI4W@stanley.mountain>
References: <Z014ylYz_xrrgI4W@stanley.mountain>
Message-ID: <Z1qwXYtO4pBswIXS@ryzen>

On Mon, Dec 02, 2024 at 12:07:22PM +0300, Dan Carpenter wrote:
> Return -ENOMEM if pci_epc_mem_alloc_addr() fails.  Don't return success.
> 
> Fixes: 945648019466 ("PCI: rockchip-ep: Refactor rockchip_pcie_ep_probe() memory allocations")
> Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>
> Reviewed-by: Damien Le Moal <dlemoal at kernel.org>
> ---
> v2: Update the git hash for the Fixes tag because the tree was rebased I guess.
> 
>  drivers/pci/controller/pcie-rockchip-ep.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
> index 1064b7b06cef..34162ca14093 100644
> --- a/drivers/pci/controller/pcie-rockchip-ep.c
> +++ b/drivers/pci/controller/pcie-rockchip-ep.c
> @@ -784,6 +784,7 @@ static int rockchip_pcie_ep_init_ob_mem(struct rockchip_pcie_ep *ep)
>  						  SZ_1M);
>  	if (!ep->irq_cpu_addr) {
>  		dev_err(dev, "failed to reserve memory space for MSI\n");
> +		err = -ENOMEM;
>  		goto err_epc_mem_exit;
>  	}
>  
> -- 
> 2.45.2
> 

Reviewed-by: Niklas Cassel <cassel at kernel.org>


From will at kernel.org  Thu Dec 12 01:50:26 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Dec 2024 09:50:26 +0000
Subject: [GIT PULL] iommu/arm-smmu: Fix for 6.13-rc
Message-ID: <20241212095025.GA18975@willie-the-truck>

Hi Joerg,

Please can you pull this lonely Arm SMMU fix for 6.13-rc? It addresses
an incorrect use of smp_processor_id() from a preemptible section in the
NVIDIA custom cmdq code.

Cheers,

Will

--->8

The following changes since commit fac04efc5c793dccbd07e2d59af9f90b7fc0dca4:

  Linux 6.13-rc2 (2024-12-08 14:03:39 -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 1f806218164d1bb93f3db21eaf61254b08acdf03:

  iommu/tegra241-cmdqv: do not use smp_processor_id in preemptible context (2024-12-09 23:38:30 +0000)

----------------------------------------------------------------
Arm SMMU fixes for 6.13-rc

- Use raw_smp_processor_id() when balancing traffic for NVIDIA's custom
  command queue implementation.

----------------------------------------------------------------
Luis Claudio R. Goncalves (1):
      iommu/tegra241-cmdqv: do not use smp_processor_id in preemptible context

 drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


From karprzy7 at gmail.com  Thu Dec 12 01:50:57 2024
From: karprzy7 at gmail.com (Karol Przybylski)
Date: Thu, 12 Dec 2024 10:50:57 +0100
Subject: [PATCHv2] drm: zynqmp_dp: Fix integer overflow in zynqmp_dp_rate_get()
Message-ID: <20241212095057.1015146-1-karprzy7@gmail.com>

This patch fixes a potential integer overflow in the zynqmp_dp_rate_get()

The issue comes up when the expression
drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000 is evaluated using 32-bit
Now the constant is a compatible 64-bit type.

Resolves coverity issues: CID 1636340 and CID 1635811

Signed-off-by: Karol Przybylski <karprzy7 at gmail.com>
Fixes: 28edaacb821c6 ("drm: zynqmp_dp: Add debugfs interface for compliance testing")
---
 drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 25c5dc61e..56a261a40 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -2190,7 +2190,7 @@ static int zynqmp_dp_rate_get(void *data, u64 *val)
 	struct zynqmp_dp *dp = data;
 
 	mutex_lock(&dp->lock);
-	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000;
+	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000ULL;
 	mutex_unlock(&dp->lock);
 	return 0;
 }
-- 
2.34.1



From angelogioacchino.delregno at collabora.com  Thu Dec 12 01:57:37 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 12 Dec 2024 10:57:37 +0100
Subject: [PATCH 0/8] arm64: dts: mediatek: Drop regulator-compatible
 property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <1b75d7ee-38d7-47fc-b7df-c46793a85036@collabora.com>

Il 11/12/24 06:24, Chen-Yu Tsai ha scritto:
> Hi folks,
> 
> This series drops usage of the long deprecated "regulator-compatible"
> property from MediaTek device tree files. The property was introduced
> in 2012, and then subsequently deprecated after two months. It was
> never carried over during the binding YAML conversion.
> 
> Drop the property from the MT6315 regulator binding, and all MediaTek
> device tree files. IMO it should never have been used to begin with.
> This also gets rid of any validation errors [1] related to them.
> 
> Please have a look.
> 

Whole series is

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> 
> Thanks
> ChenYu
> 
> [1] https://lore.kernel.org/all/173386568696.497617.3727087837255802552.robh at kernel.org/
> 
> Chen-Yu Tsai (8):
>    regulator: dt-bindings: mt6315: Drop regulator-compatible property
>    arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property
>    arm64: dts: mediatek: mt8173-elm: Drop regulator-compatible property
>    arm64: dts: mediatek: mt8192-asurada: Drop regulator-compatible
>      property
>    arm64: dts: mediatek: mt8195-cherry: Drop regulator-compatible
>      property
>    arm64: dts: mediatek: mt8195-demo: Drop regulator-compatible property
>    arm64: dts: medaitek: mt8395-nio-12l: Drop regulator-compatible
>      property
>    arm64: dts: mediatek: mt8395-genio-1200-evk: Drop regulator-compatible
>      property
> 
>   .../bindings/regulator/mt6315-regulator.yaml  |  6 -----
>   arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi  | 23 -------------------
>   arch/arm64/boot/dts/mediatek/mt8173-evb.dts   | 23 -------------------
>   .../boot/dts/mediatek/mt8192-asurada.dtsi     |  3 ---
>   .../boot/dts/mediatek/mt8195-cherry.dtsi      |  2 --
>   arch/arm64/boot/dts/mediatek/mt8195-demo.dts  |  9 --------
>   .../dts/mediatek/mt8395-genio-1200-evk.dts    |  2 --
>   .../dts/mediatek/mt8395-radxa-nio-12l.dts     |  2 --
>   8 files changed, 70 deletions(-)
> 




From laurentiumihalcea111 at gmail.com  Thu Dec 12 01:59:19 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Thu, 12 Dec 2024 11:59:19 +0200
Subject: [PATCH v2 3/5] ASoC: dt-bindings: audio-graph-card2: add widgets
 and hp-det-gpios support
In-Reply-To: <ZzUH3n50Vw6RhmNJ@lizhi-Precision-Tower-5810>
References: <20241113195240.3699-1-laurentiumihalcea111@gmail.com>
 <20241113195240.3699-4-laurentiumihalcea111@gmail.com>
 <ZzUH3n50Vw6RhmNJ@lizhi-Precision-Tower-5810>
Message-ID: <1fc1f1ae-766d-4266-84ec-11dbd67a608a@gmail.com>



On 11/13/2024 10:11 PM, Frank Li wrote:
> On Wed, Nov 13, 2024 at 02:52:38PM -0500, Laurentiu Mihalcea wrote:
>> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>>
>> Introduce the 'widgets' property, allowing the creation of widgets from
>> 4 template widgets: Microphone, Line, Headphone, and Speaker. Also
>> introduce the 'hp-det-gpios' property, which allows using headphone
>> detection using the specified GPIO.
>>
>> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>> ---
>>  .../devicetree/bindings/sound/audio-graph-card2.yaml          | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml
>> index f943f90d8b15..94588353f852 100644
>> --- a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml
>> +++ b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml
>> @@ -37,6 +37,10 @@ properties:
>>    codec2codec:
>>      type: object
>>      description: Codec to Codec node
>> +  hp-det-gpios:
>> +    $ref: audio-graph.yaml#/properties/hp-det-gpios
>> +  widgets:
>> +    $ref: audio-graph.yaml#/properties/widgets
> why not direct ref Documentation/devicetree/bindings/sound/audio-graph.yaml
> and define these again here.
We don't actually want all the properties from 'audio-graph.yaml' (for the moment at least). Also ref-ing 'audio-graph.yaml' will make the 'dais' property required, which is not targeted in this patch. Maybe Kuninori Morimoto can comment more on this.
>
> Frank
>
>>  required:
>>    - compatible
>> --
>> 2.34.1
>>



From maz at kernel.org  Thu Dec 12 01:57:05 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Dec 2024 09:57:05 +0000
Subject: [RESEND RFC PATCH v1 1/5] arm64: Add TLB Conflict Abort Exception handler to KVM
In-Reply-To: <5d4ccb2c-da45-4471-9bb1-90212b50dad7@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
	<20241211160218.41404-2-miko.lenczewski@arm.com>
	<86o71irucr.wl-maz@kernel.org>
	<5d4ccb2c-da45-4471-9bb1-90212b50dad7@arm.com>
Message-ID: <86msh1rzpq.wl-maz@kernel.org>

Hi Ryan,

On Thu, 12 Dec 2024 09:23:20 +0000,
Ryan Roberts <ryan.roberts at arm.com> wrote:
> 
> Hi Marc,
> 
> I believe the intent of this patch is to protect the host/KVM against a guest
> that is using BBML2. The host/KVM always assumes BBML0 and therefore doesn't do
> any operations that are allowed by the arch to cause a conflict abort. Therefore
> the host doesn't need to handle it. But a guest could be taking advantage of
> BBML2 and therefore it's architiecturally possible for a conflict abort to be
> raised to EL2. I think today that would take down the host?
> 
> So really I think this could be considered a stand-alone KVM
> hardening improvement?

I'm not disputing the need for a TLB Conflict abort handler. It will
be a good addition once we agree on what needs to be done.

> > However, it doesn't seem to me that the host is equipped to deal with
> > this sort of exception for itself. Shouldn't you start with that?
> 
> If the host isn't doing any BBML2 operations it doesn't need to handle it, I
> don't think? Obviously that changes later in the series and Miko is adding the
> required handling to the host.

Yes, and that's what I overlooked yesterday, and I replied to that
change this morning.

Thanks,

	M.

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


From angelogioacchino.delregno at collabora.com  Thu Dec 12 01:57:19 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 12 Dec 2024 10:57:19 +0100
Subject: [PATCH 1/8] regulator: dt-bindings: mt6315: Drop
 regulator-compatible property
In-Reply-To: <20241211052427.4178367-2-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
 <20241211052427.4178367-2-wenst@chromium.org>
Message-ID: <b75520cf-1377-4436-9ad4-ef5be4b372e7@collabora.com>

Il 11/12/24 06:24, Chen-Yu Tsai ha scritto:
> The "regulator-compatible" property has been deprecated since 2012 in
> commit 13511def87b9 ("regulator: deprecate regulator-compatible DT
> property"), which is so old it's not even mentioned in the converted
> regulator bindings YAML file. It should not have been used for new
> submissions such as the MT6315.
> 
> Drop the property from the MT6315 regulator binding and its examples.
> 
> Fixes: 977fb5b58469 ("regulator: document binding for MT6315 regulator")
> Fixes: 6d435a94ba5b ("regulator: mt6315: Enforce regulator-compatible, not name")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Dec 12 02:01:12 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 12 Dec 2024 11:01:12 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: mt8390-genio-700-evk: Add
 sound output support
In-Reply-To: <20241210-genio700-audio-output-v2-2-c50886ae0be2@collabora.com>
References: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>
 <20241210-genio700-audio-output-v2-2-c50886ae0be2@collabora.com>
Message-ID: <ba964eb1-324f-40f2-a5e3-7acd441cd218@collabora.com>

Il 10/12/24 21:54, N?colas F. R. A. Prado ha scritto:
> Describe all the components to get sound output working on the two audio
> jacks, Earphone and Speaker, present on the Genio 700 EVK board with the
> audio DSP enabled.
> 
> Co-developed-by: Aary Patil <aary.patil at mediatek.com>
> Signed-off-by: Aary Patil <aary.patil at mediatek.com>
> Co-developed-by: Suhrid Subramaniam <suhrid.subramaniam at mediatek.com>
> Signed-off-by: Suhrid Subramaniam <suhrid.subramaniam at mediatek.com>
> Co-developed-by: parkeryang <Parker.Yang at mediatek.com>
> Signed-off-by: parkeryang <Parker.Yang at mediatek.com>
> 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  Thu Dec 12 02:04:52 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 12 Dec 2024 11:04:52 +0100
Subject: (subset) [PATCH 0/8] arm64: dts: mediatek: Drop
 regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <173399789246.41280.12946526807536049492.b4-ty@collabora.com>

On Wed, 11 Dec 2024 13:24:18 +0800, Chen-Yu Tsai wrote:
> This series drops usage of the long deprecated "regulator-compatible"
> property from MediaTek device tree files. The property was introduced
> in 2012, and then subsequently deprecated after two months. It was
> never carried over during the binding YAML conversion.
> 
> Drop the property from the MT6315 regulator binding, and all MediaTek
> device tree files. IMO it should never have been used to begin with.
> This also gets rid of any validation errors [1] related to them.
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[2/8] arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property
      commit: a6d5983e40f5d5b219337569cdd269727f5a3e2e
[3/8] arm64: dts: mediatek: mt8173-elm: Drop regulator-compatible property
      commit: 4b907b3ea5fba240808136cc5599d14b52230b39
[4/8] arm64: dts: mediatek: mt8192-asurada: Drop regulator-compatible property
      commit: d1fb968551c8688652b8b817bb081fdc9c25cd48
[5/8] arm64: dts: mediatek: mt8195-cherry: Drop regulator-compatible property
      commit: 4dbaa5d5def2c49e44efaa5e796c23d9b904be09
[6/8] arm64: dts: mediatek: mt8195-demo: Drop regulator-compatible property
      commit: 2a8af9b95f504260a6d8200a11f0ae5c90e9f787
[7/8] arm64: dts: medaitek: mt8395-nio-12l: Drop regulator-compatible property
      commit: ab60442f26b15ba69b210974722a851ed03188ff
[8/8] arm64: dts: mediatek: mt8395-genio-1200-evk: Drop regulator-compatible property
      commit: b99bf07c2c8b3c85c1935ddca2a73bc686f8d847

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Thu Dec 12 02:04:53 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 12 Dec 2024 11:04:53 +0100
Subject: [PATCH 1/2] arm64: dts: mediatek: mt8173-elm: Fix MT6397 PMIC
 sub-node names
In-Reply-To: <20241210092614.3951748-1-wenst@chromium.org>
References: <20241210092614.3951748-1-wenst@chromium.org>
Message-ID: <173399789318.41280.12144237345151657264.b4-ty@collabora.com>

On Tue, 10 Dec 2024 17:26:12 +0800, Chen-Yu Tsai wrote:
> The MT6397 PMIC bindings specify exact names for its sub-nodes. The
> names used in the current dts don't match, causing a validation error.
> 
> Fix up the names. Also drop the label for the regulators node, since
> any reference should be against the individual regulator sub-nodes.
> 
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/2] arm64: dts: mediatek: mt8173-elm: Fix MT6397 PMIC sub-node names
      commit: beb06b727194f68b0a4b5183e50c88265ce185af
[2/2] arm64: dts: mediatek: mt8173-evb: Fix MT6397 PMIC sub-node names
      commit: 9545ba142865b9099d43c972b9ebcf463606499a

Cheers,
Angelo




From laurentiumihalcea111 at gmail.com  Thu Dec 12 02:04:47 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Thu, 12 Dec 2024 12:04:47 +0200
Subject: [PATCH v2 5/5] arm64: dts: imx: add imx95 dts for sof
In-Reply-To: <ZzUKPehw2G9XcRsb@lizhi-Precision-Tower-5810>
References: <20241113195240.3699-1-laurentiumihalcea111@gmail.com>
 <20241113195240.3699-6-laurentiumihalcea111@gmail.com>
 <ZzUKPehw2G9XcRsb@lizhi-Precision-Tower-5810>
Message-ID: <392884c8-0f4e-43a5-b81c-bf2e80cbddfd@gmail.com>



On 11/13/2024 10:21 PM, Frank Li wrote:
> On Wed, Nov 13, 2024 at 02:52:40PM -0500, Laurentiu Mihalcea wrote:
>> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>>
>> Add imx95 DTS for SOF usage.
>>
>> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>> ---
>>  arch/arm64/boot/dts/freescale/Makefile        |  1 +
>>  .../dts/freescale/imx95-19x19-evk-sof.dts     | 74 +++++++++++++++++++
> look like it should be dt overlay.
ah, interesting idea, but I don't really see its usage here? As far as I was able to understand the overlays are used to dynamically change the DTB (via u-boot), which we don't really need at the moment.

>
>>  2 files changed, 75 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts
>>
>> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
>> index 42e6482a31cb..0a313133d013 100644
>> --- a/arch/arm64/boot/dts/freescale/Makefile
>> +++ b/arch/arm64/boot/dts/freescale/Makefile
>> @@ -269,6 +269,7 @@ 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
>> +dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk-sof.dtb
>>
>>  imx8mm-kontron-dl-dtbs			:= imx8mm-kontron-bl.dtb imx8mm-kontron-dl.dtbo
>>
>> diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts
>> new file mode 100644
>> index 000000000000..3fa4c252e355
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts
>> @@ -0,0 +1,74 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Copyright 2024 NXP
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "imx95-19x19-evk.dts"
>> +
>> +/ {
>> +	reserved-memory {
>> +		adma_res: memory at 86100000 {
>> +			compatible = "shared-dma-pool";
>> +			reg = <0x0 0x86100000 0x0 0x100000>;
>> +			no-map;
>> +		};
>> +	};
>> +
>> +	sound-wm8962 {
>> +		status = "disabled";
>> +	};
>> +
>> +	sof-sound-wm8962 {
>> +		compatible = "audio-graph-card2";
>> +		links = <&cpu>;
>> +		label = "wm8962-audio";
>> +		hp-det-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>;
>> +		pinctrl-names = "default";
>> +		pinctrl-0 = <&pinctrl_hp>;
>> +		widgets =
>> +			"Headphone", "Headphones",
>> +			"Microphone", "Headset Mic";
>> +		routing =
>> +			"Headphones", "HPOUTL",
>> +			"Headphones", "HPOUTR",
>> +			"Headset Mic", "MICBIAS",
>> +			"IN3R", "Headset Mic",
>> +			"IN1R", "Headset Mic";
>> +	};
>> +
>> +	sof_cpu: cm7-cpu at 80000000 {
>> +		compatible = "fsl,imx95-cm7-sof";
>> +		reg = <0x0 0x80000000 0x0 0x6100000>;
>> +		memory-region = <&adma_res>;
>> +		mboxes = <&mu7 2 0>, <&mu7 2 1>, <&mu7 3 0>, <&mu7 3 1>;
>> +		mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";
>> +		cpu: port {
>> +			cpu_ep: endpoint { remote-endpoint = <&codec_ep>; };
>> +		};
>> +	};
> please sort by node name.
Fix in v3

>
>> +};
>> +
>> +&edma2 {
>> +	dma-channel-mask = <0xc0000000>, <0x0>;
>> +};
> Why need change dma mask here ?
Channels 30 and 31 are reserved for firmware usage

>
>> +
>> +&sai3 {
>> +	status = "disabled";
>> +};
>> +
>> +&wm8962 {
>> +	assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>,
>> +			  <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>,
>> +			  <&scmi_clk IMX95_CLK_AUDIOPLL1>,
>> +			  <&scmi_clk IMX95_CLK_AUDIOPLL2>,
>> +			  <&scmi_clk IMX95_CLK_SAI3>;
>> +	assigned-clock-parents = <0>, <0>, <0>, <0>, <&scmi_clk IMX95_CLK_AUDIOPLL1>;
>> +	assigned-clock-rates = <3932160000>, <3612672000>,
>> +			       <393216000>, <361267200>,
>> +			       <12288000>;
>> +	port {
>> +		codec_ep: endpoint { remote-endpoint = <&cpu_ep>; };
>> +	};
>> +};
>> --
>> 2.34.1
>>



From angelogioacchino.delregno at collabora.com  Thu Dec 12 02:04:53 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 12 Dec 2024 11:04:53 +0100
Subject: [PATCH v2 0/2] Enable audio output for Genio 700 EVK board
In-Reply-To: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>
References: <20241210-genio700-audio-output-v2-0-c50886ae0be2@collabora.com>
Message-ID: <173399789370.41280.16875335834079584278.b4-ty@collabora.com>

On Tue, 10 Dec 2024 17:54:27 -0300, N?colas F. R. A. Prado wrote:
> This series enables audio output support for the Genio 700 EVK board.
> Patch 1 adds the missing #sound-dai-cells property in the MT6359 node as
> a prerequisite, and patch 2 describes the audio DT nodes to get audio
> output working on the two audio jacks, Earphone and Speaker, present on
> the board.
> 
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/2] arm64: dts: mt6359: Add #sound-dai-cells property
      commit: 9bc8353be720ca1f9cb6e03825929bc172e1157d
[2/2] arm64: dts: mediatek: mt8390-genio-700-evk: Add sound output support
      commit: b8457716eeee45ed5cb6b8fdc5a5b459f7ebe819

Cheers,
Angelo




From maz at kernel.org  Thu Dec 12 02:12:32 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Dec 2024 10:12:32 +0000
Subject: Question about interrupt prioriyt of ARM GICv3/4
In-Reply-To: <CAJNi4rPDVXS3Ft3nHLXvMzHmn9d10Nz4Pxeduoe+v5HaK=CEAg@mail.gmail.com>
References: <CAJNi4rMfhZOCT+7Ki14vUs+dZbv9cxCZ0s+jgn6=_om4NTgo_A@mail.gmail.com>
	<86cyi5tanz.wl-maz@kernel.org>
	<CAJNi4rPDVXS3Ft3nHLXvMzHmn9d10Nz4Pxeduoe+v5HaK=CEAg@mail.gmail.com>
Message-ID: <86ldwlryzz.wl-maz@kernel.org>

On Thu, 12 Dec 2024 09:18:56 +0000,
richard clark <richard.xnu.clark at gmail.com> wrote:
> 
> Hi M,

Hi r,

> 
> On Fri, Dec 6, 2024 at 5:37?PM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Fri, 06 Dec 2024 08:33:11 +0000,
> > richard clark <richard.xnu.clark at gmail.com> wrote:
> > >
> > > Hi,
> > > Currently seems the GICv3/4 irqchip configures all the interrupts as
> > > the same priority, I am thinking about to minimize the latency of the
> > > interrupt for a particular device, e.g, the arm arch_timer in the RTL
> > > system. The question is,
> > > 1. Why don't we provide a /proc or /sys interface for the enduser to
> > > set the priority of a specific interrupt(SPI/PPI)?
> >
> > I'm afraid this really has nothing to do with any particular interrupt
> > architecture.
> >
> > Before thinking of exposing the interrupt priority to userspace, you
> > should look at what this translates into for the kernel once you allow
> > interrupts to be preempted by another one with a higher priority.
> >
> Interrupt priority doesn't necessarily mean the preemption, seems
> you're talking about the interrupt preemption harm according to your
> statement followed.Frankly I am just thinking higher priority will win
> the lower ones in case massive external interrupts received in the GIC
> level (you see I am still talking about GIC, not kernel)

As I stated at the end of my email, the GIC only gives guarantee that
you will ack the highest priority interrupt in finite time. Not right
when it is made pending. Yes, it has the concept of HPPI. But that
from the PoV of the CPU interface, not that of the distributor. Factor
in the Stream interface, and you realise that expecting to always ack
the highest priority pending interrupt is akin to expecting no
reordering of packets in a network.

> >
> > This means that at every point where you would normally see a
> > local_irq_save(), spinlock_irqsave() or equivalent, you would need to
> > explicitly specify the priority that you allow for preemption. You
> > should then make sure that any code that can be run during an
> > interrupt is reentrant. You need to define which data structures can
> > be manipulated at which priority level... The list goes on.
> >
> irqsave just masks the interrupt from the point of cpu, I don't think
> it will mess things up if preemption really happens (no? then what the
> side-effect is for the nested interrupt handling in the softirq part.
> damage the semantic of the lock primitives?)
> >
> > If you want a small taste of the complexity, just look at what
> > handling NMIs (or even pseudo-NMIs in the case of GICv3) means, and
> > generalise it to not just two, but an arbitrary range of priorities.
> >
> > If you want the full blown experience, look at the BSDs and their use
> > of spl*(). I don't think anyone has any plan to get there, and the RT
> > patches have shown that there is little need for it.
> >
> As supplement?the fiq is suggested to be used as an alternative to the
> higher priority in the RT area...

<PulpFiction>
FIQ's dead, baby. FIQ's dead.
</PulpFiction>

> >
> > > 2. Is there any way to verify the higher priority interrupt will have
> > > more dominant to be selected to the CPU (IOW, the priority is really
> > > working) in case of multiple different interrupts asserted to the GIC
> > > at the same time(some debug registers of GIC like GICD_REEMPT_CNT :-)
> > > to record higher priority wins)?
> >
> > The GIC architecture makes no promise that the interrupt you
> > acknowledge is the highest priority pending interrupt, because this is
> > by definition a very racy process.
> >
> > Also, even on busy systems, you will very rarely see two interrupts
> > targeting the same CPU being made pending at the same time, so that
> > the interrupt delivery system would have to arbitrate between the two.
> > That's because interrupts are vanishingly rare in the grand scheme of
> > things.
> >
> 1. I am trying to stress the external interrupts to the core#0 via the
> stress-ng tool with one of interrupt being configured as higher
> priority to see the benchmark data, it's time consuming as you can
> image, still is in progress(BTW, I can't see any lockup similar hang
> in the system with a higher priority configured)

If you don't have preemption, I don't think anything wrong will
happen. But I don't expect any benefit either.

> 2. This raises a very interesting question and I am also very curious
> about is, what is the purpose for the GIC to introduce the interrupt
> priority features, a placeholder feature reserved for the future? Ah,
> hardware prefer to provide more functionalities than its being
> actually used by software, any other justification except that?

You realise that the HW is not exclusively designed for Linux, right?

	M.

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


From martin at wetterwald.eu  Thu Dec 12 02:13:27 2024
From: martin at wetterwald.eu (Martin Wetterwald)
Date: Thu, 12 Dec 2024 11:13:27 +0100
Subject: Raspberry Pi 3B: Failed to create device link with soc:firmware:gpio
Message-ID: <CAFERDQ2hLHek+0ViVqbqgOD+4xwC2ZwK1KhgGdLP_zGnonEs4w@mail.gmail.com>

Hello Saravana and Florian,

Back in 2023, you discussed about an issue concerning the Raspberry Pi 4, that
you fixed in commit 1a5ecc73b2bfeffe036212d4a6bfacee053ab0a1:
https://lore.kernel.org/lkml/03b70a8a-0591-f28b-a567-9d2f736f17e5 at gmail.com/
https://lore.kernel.org/all/20230302023509.319903-1-saravanak at google.com/

Today, I notice I see the same issue, but it's with the Raspberry Pi 3B (V1.2).
I'm using the upstream kernel 6.12.3, with the upstream DTB.

You can find my kernel miniconfig (basis being allnoconfig) here:
https://gist.github.com/mwetterw/299bb1317fccf9e68125cb0f5da7384c

During boot, I see following messages:
> Bluetooth: HCI UART driver ver 2.3
> Bluetooth: HCI UART protocol H4 registered
> Bluetooth: HCI UART protocol Broadcom registered
> bcm2835-mbox 3f00b880.mailbox: mailbox enabled
> 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 99, base_baud = 0) is a PL011 rev2
> raspberrypi-firmware soc:firmware: Attached to firmware from 2024-09-13T16:00:14
> uart-pl011 3f201000.serial: Failed to create device link (0x180) with soc:firmware:gpio

Here is an extract of the relevant FDT nodes.
Because my setup involves first the proprietary GPU firmware, then the U-Boot
bootloader before finally launching the kernel, I used following command in
order to make sure I see the same FDT as Linux:

> ssh rpi 'cat /sys/firmware/fdt' | fdtdump -

> firmware {
>     compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
>     mboxes = <0x0000001b>;
>     phandle = <0x0000001c>;
>     clocks {
>         compatible = "raspberrypi,firmware-clocks";
>         #clock-cells = <0x00000001>;
>         phandle = <0x00000015>;
>     };
>     gpio {
>         compatible = "raspberrypi,firmware-gpio";
>         gpio-controller;
>         #gpio-cells = <0x00000002>;
>         gpio-line-names = "BT_ON", "WL_ON", "STATUS_LED", "LAN_RUN", "HDMI_HPD_N", "CAM_GPIO0", "CAM_GPIO1", "PWR_LOW_N";
>         status = "okay";
>         phandle = <0x0000000a>;
>     };
> };

> serial at 7e201000 {
>     compatible = "arm,pl011", "arm,primecell";
>     reg = <0x7e201000 0x00000200>;
>     interrupts = <0x00000002 0x00000019>;
>     clocks = <0x00000007 0x00000013 0x00000007 0x00000014>;
>     clock-names = "uartclk", "apb_pclk";
>     arm,primecell-periphid = <0x00241011>;
>     status = "okay";
>     pinctrl-names = "default";
>     pinctrl-0 = <0x00000008 0x00000009>;
>     phandle = <0x00000048>;
>     bluetooth {
>         compatible = "brcm,bcm43438-bt";
>         max-speed = <0x001e8480>;
>         shutdown-gpios = <0x0000000a 0x00000000 0x00000000>;
>         phandle = <0x00000049>;
>     };
> };

If I understand correctly, the serial dev bus, together with
CONFIG_BT_HCI_UART, CONFIG_BT_HCI_UART_BCM, and if associated to the correct
DTB nodes describing the bluetooth chip, should allow the kernel to handle the
serial Bluetooth HCI himself, without the userspace needing to launch user
space tools like hciattach or btattach?

Is the log

> uart-pl011 3f201000.serial: Failed to create device link (0x180) with soc:firmware:gpio

a hint to the reason why the kernel doesn't automatically handle my Bluetooth
HCI over serial?

How to solve this log error, and how to let the kernel handle the HCI himself?
Am I missing kernel configuration flags?

Thanks!
Martin


From krzysztof.kozlowski at linaro.org  Thu Dec 12 02:21:03 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 11:21:03 +0100
Subject: [PATCH 1/3] mfd: syscon: Fix race in device_node_get_regmap()
In-Reply-To: <20241211-syscon-fixes-v1-1-b5ac8c219e96@kernel.org>
References: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
 <20241211-syscon-fixes-v1-1-b5ac8c219e96@kernel.org>
Message-ID: <c6ac74d3-d3b5-44d3-bb12-8965034dbb15@linaro.org>

On 11/12/2024 21:57, Rob Herring (Arm) wrote:
> It is possible for multiple, simultaneous callers calling
> device_node_get_regmap() with the same node to fail to find an entry in
> the syscon_list. There is a period of time while the first caller is
> calling of_syscon_register() that subsequent callers also fail to find
> an entry in the syscon_list and then call of_syscon_register() a second
> time.
> 
> Fix this by keeping the lock held until after of_syscon_register()
> completes and adds the node to syscon_list. Convert the spinlock to a
> mutex as many of the functions called in of_syscon_register() may sleep.
> 
> Fixes: bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform devices")
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
Tested on arm64: Qualcomm SM8450
Tested on armv7: Exynos5422

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

Best regards,
Krzysztof


From krzysztof.kozlowski at linaro.org  Thu Dec 12 02:21:25 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 11:21:25 +0100
Subject: [PATCH 2/3] mfd: syscon: Remove the platform driver support
In-Reply-To: <20241211-syscon-fixes-v1-2-b5ac8c219e96@kernel.org>
References: <20241211-syscon-fixes-v1-0-b5ac8c219e96@kernel.org>
 <20241211-syscon-fixes-v1-2-b5ac8c219e96@kernel.org>
Message-ID: <f19b4400-b94b-47ff-8431-2363d396284e@linaro.org>

On 11/12/2024 21:57, Rob Herring (Arm) wrote:
> The platform driver is dead code. It is not used by DT platforms since
> commit bdb0066df96e ("mfd: syscon: Decouple syscon interface from
> platform devices") which said:
> 
>     For non-DT based platforms, this patch keeps syscon platform driver
>     structure so that syscon can be probed and such non-DT based drivers
>     can use syscon_regmap_lookup_by_pdev API and access regmap handles.
>     Once all users of "syscon_regmap_lookup_by_pdev" migrated to DT based,
>     we can completely remove platform driver of syscon, and keep only helper
>     functions to get regmap handles.
> 
> The last user of syscon_regmap_lookup_by_pdevname() was removed in 2018.
> syscon_regmap_lookup_by_pdevname() was then removed in 2019, but that
> commit failed to remove the rest of the platform driver.
> 
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
FWIW:

Tested on arm64: Qualcomm SM8450
Tested on armv7: Samsung Exynos5422

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

Best regards,
Krzysztof


From clement.legoffic at foss.st.com  Thu Dec 12 02:20:50 2024
From: clement.legoffic at foss.st.com (=?UTF-8?q?Cl=C3=A9ment=20Le=20Goffic?=)
Date: Thu, 12 Dec 2024 11:20:50 +0100
Subject: [PATCH v2] watchdog: stm32_iwdg: fix error message during driver probe
In-Reply-To: <20241211163457.301140-1-clement.legoffic@foss.st.com>
References: <20241211163457.301140-1-clement.legoffic@foss.st.com>
Message-ID: <20241212102050.374501-1-clement.legoffic@foss.st.com>

The commit 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
introduces the support for the pre-timeout interrupt.

The support for this interrupt is optional but the driver uses the
platform_get_irq() wich produces an error message during the driver
probe if we don't have any `interrupts` property in the DT.

Use the platform_get_irq_optional() API to get rid of the error message
as this property is optional.

Fixes: 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
Signed-off-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
---
v1 -> v2: Change the commit message because it only prints an error
message and dont break the DT backward compatibility.

drivers/watchdog/stm32_iwdg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index d700e0d49bb95..8ad06b54c5adc 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -286,7 +286,7 @@ static int stm32_iwdg_irq_init(struct platform_device *pdev,
 	if (!wdt->data->has_early_wakeup)
 		return 0;

-	irq = platform_get_irq(pdev, 0);
+	irq = platform_get_irq_optional(pdev, 0);
 	if (irq <= 0)
 		return 0;


base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
--
2.34.1



From robh at kernel.org  Thu Dec 12 02:27:10 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 12 Dec 2024 04:27:10 -0600
Subject: [PATCH 2/2] dt-bindings: memory-controllers: Add mediatek
 common-dramc dt-bindings
In-Reply-To: <20241212090029.13692-3-crystal.guo@mediatek.com>
References: <20241212090029.13692-1-crystal.guo@mediatek.com>
 <20241212090029.13692-3-crystal.guo@mediatek.com>
Message-ID: <173399922996.1678560.9494303027075425033.robh@kernel.org>


On Thu, 12 Dec 2024 16:59:48 +0800, Crystal Guo wrote:
> Add devicetree binding for mediatek common-dramc driver.
> 
> The DRAM controller of MediaTek SoC provides an interface to
> get the current data rate of DRAM.
> 
> Signed-off-by: Crystal Guo <crystal.guo at mediatek.com>
> ---
>  .../mediatek,common-dramc.yaml                | 129 ++++++++++++++++++
>  1 file changed, 129 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: support-ch-cnt: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: fmeter-version: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: crystal-freq: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: shu-of: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: pll-id: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: shu-lv: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: sdmpcw: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: posdiv: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: fbksel: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: dqsopen: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: async-ca: missing type definition
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml: dq-ser-mode: missing type definition

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241212090029.13692-3-crystal.guo at mediatek.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 angelogioacchino.delregno at collabora.com  Thu Dec 12 02:27:53 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 12 Dec 2024 11:27:53 +0100
Subject: [PATCH 2/2] dt-bindings: memory-controllers: Add mediatek
 common-dramc dt-bindings
In-Reply-To: <20241212090029.13692-3-crystal.guo@mediatek.com>
References: <20241212090029.13692-1-crystal.guo@mediatek.com>
 <20241212090029.13692-3-crystal.guo@mediatek.com>
Message-ID: <5d06211b-5ee2-48dd-9334-7c8bcffb894e@collabora.com>

Il 12/12/24 09:59, Crystal Guo ha scritto:
> Add devicetree binding for mediatek common-dramc driver.
> 
> The DRAM controller of MediaTek SoC provides an interface to
> get the current data rate of DRAM.
> 
> Signed-off-by: Crystal Guo <crystal.guo at mediatek.com>
> ---
>   .../mediatek,common-dramc.yaml                | 129 ++++++++++++++++++
>   1 file changed, 129 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
> new file mode 100644
> index 000000000000..c9e608c7f183
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
> @@ -0,0 +1,129 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +# Copyright (c) 2024 MediaTek Inc.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/memory-controllers/mediatek,common-dramc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek Common DRAMC (DRAM Controller)

MediaTek DRAM Controller (DRAMC)

> +
> +maintainers:
> +  - Crystal Guo <crystal.guo at mediatek.com>
> +
> +description: |
> +  The DRAM controller of MediaTek SoC provides an interface to
> +  get the current data rate of DRAM.

No, the DRAM Controller does much more than just that.

> +
> +properties:
> +  compatible:
> +    const: mediatek,common-dramc

Absolutely no! Compatibles are per-soc.

mediatek,mt8186-dramc
mediatek,mt8188-dramc
mediatek,mt8195-dramc

etc

> +
> +  reg:
> +    minItems: 9
> +    items:
> +      - description: DRAMC_AO_CHA_BASE
> +      - description: DRAMC_AO_CHB_BASE
> +      - description: DRAMC_AO_CHC_BASE
> +      - description: DRAMC_AO_CHD_BASE

All those channels are sequential in AO->NAO, in the sense that
every channel is:

CH0     AO: 0x10230000   len: 0x4000
CH0    NAO: 0x10234000   len: 0x2000
CH0 PHY_AO: 0x10236000   len: 0x2000
CH0 PHY_AO: 0x10238000   len: 0x2000

So the reg can be simplified as

minItems: 4
items:
   - description: DRAM Controller Channel 0
   - description: DRAM Controller Channel 1
   - description: DRAM Controller Channel 2
   - description: DRAM Controller Channel 3


> +      - description: DRAMC_NAO_CHA_BASE
> +      - description: DRAMC_NAO_CHB_BASE
> +      - description: DRAMC_NAO_CHC_BASE
> +      - description: DRAMC_NAO_CHD_BASE
> +      - description: DDRPHY_AO_CHA_BASE
> +      - description: DDRPHY_AO_CHB_BASE
> +      - description: DDRPHY_AO_CHC_BASE
> +      - description: DDRPHY_AO_CHD_BASE
> +      - description: DDRPHY_NAO_CHA_BASE
> +      - description: DDRPHY_NAO_CHB_BASE
> +      - description: DDRPHY_NAO_CHC_BASE
> +      - description: DDRPHY_NAO_CHD_BASE
> +      - description: SLEEP_BASE

You're not using the SLEEP_BASE iospace, and that's not even really specific
to the DRAM Controller. Drop it.

> +
> +  support-ch-cnt:
> +    maxItems: 1

Don't tell me that the DRAM Controller in MediaTek SoCs cannot see how many
channels are actually occupied by a DRAM bank, because I will be really skeptical.

You can autodetect that in the driver, you don't need a DT property for that.

> +
> +  fmeter-version:
> +    maxItems: 1
> +    description:
> +      Fmeter version for calculating dram data rate

The Fmeter version is SoC-specific, you need platform data, not DT property.

> +
> +  crystal-freq:
> +    maxItems: 1
> +    description:
> +      Reference clock rate in MHz

Is this crystal an external component, or is it integrated into the SoC?

> +
> +  shu-of:
> +    maxItems: 1

There's no description, what is shu-of?

> +
> +  pll-id: true
> +  shu-lv: true
> +  sdmpcw: true
> +  posdiv: true
> +  fbksel: true
> +  dqsopen: true
> +  async-ca: true
> +  dq-ser-mode: true

Same for these ones, please describe them - but then remember: if those parameters
are board-specific, they can stay here, otherwise those go in platform data.

Besides, I doubt that those are board specific.

Regards,
Angelo



From ryan.roberts at arm.com  Thu Dec 12 02:37:27 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 12 Dec 2024 10:37:27 +0000
Subject: [RESEND RFC PATCH v1 1/5] arm64: Add TLB Conflict Abort Exception
 handler to KVM
In-Reply-To: <86msh1rzpq.wl-maz@kernel.org>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-2-miko.lenczewski@arm.com>
 <86o71irucr.wl-maz@kernel.org> <5d4ccb2c-da45-4471-9bb1-90212b50dad7@arm.com>
 <86msh1rzpq.wl-maz@kernel.org>
Message-ID: <342b9c16-690d-42ed-a6f4-bb3972193a8f@arm.com>

On 12/12/2024 09:57, Marc Zyngier wrote:
> Hi Ryan,
> 
> On Thu, 12 Dec 2024 09:23:20 +0000,
> Ryan Roberts <ryan.roberts at arm.com> wrote:
>>
>> Hi Marc,
>>
>> I believe the intent of this patch is to protect the host/KVM against a guest
>> that is using BBML2. The host/KVM always assumes BBML0 and therefore doesn't do
>> any operations that are allowed by the arch to cause a conflict abort. Therefore
>> the host doesn't need to handle it. But a guest could be taking advantage of
>> BBML2 and therefore it's architiecturally possible for a conflict abort to be
>> raised to EL2. I think today that would take down the host?
>>
>> So really I think this could be considered a stand-alone KVM
>> hardening improvement?
> 
> I'm not disputing the need for a TLB Conflict abort handler. It will
> be a good addition once we agree on what needs to be done.

OK great, glad we are on the same page. I'll leave Miko to work through the details.

> 
>>> However, it doesn't seem to me that the host is equipped to deal with
>>> this sort of exception for itself. Shouldn't you start with that?
>>
>> If the host isn't doing any BBML2 operations it doesn't need to handle it, I
>> don't think? Obviously that changes later in the series and Miko is adding the
>> required handling to the host.
> 
> Yes, and that's what I overlooked yesterday, and I replied to that
> change this morning.
> 
> Thanks,
> 
> 	M.
> 



From andrej.picej at norik.com  Thu Dec 12 02:38:22 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu, 12 Dec 2024 11:38:22 +0100
Subject: [PATCH v5 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <roxosjotsh65dkecrwhhtlhkhqseezkj7ydk532shc27irzmd3@xry3ggjdq4uo>
References: <20241210091901.83028-1-andrej.picej@norik.com>
 <20241210091901.83028-3-andrej.picej@norik.com>
 <irpmhq7vxjra6vhmdh7p63ajj57n3h2c4br3ija2jmwtoewist@zyxfmx6k5m4e>
 <aa2de99d-21f4-4843-83b7-5d2db78be86f@norik.com>
 <qhmsobin3fsmoc7ic2jtancowfscoauyroruxdpwhmqwlogtkz@6by3s2ruwzwp>
 <519cc025-0782-4f96-a169-1fe87b280173@norik.com>
 <rputm4gnjj6nb66ix7dqbxr2janltia6rlb6zunhf7x3mgooxw@o3lblnyp5cci>
 <ad8843d6-e5a3-437a-af4d-f2248b247a65@norik.com>
 <roxosjotsh65dkecrwhhtlhkhqseezkj7ydk532shc27irzmd3@xry3ggjdq4uo>
Message-ID: <08a10b77-011d-4003-ac33-4bef45d801bd@norik.com>



On 12. 12. 24 10:28, Dmitry Baryshkov wrote:
> On Thu, Dec 12, 2024 at 09:08:03AM +0100, Andrej Picej wrote:
>>
>>
>> On 12. 12. 24 00:04, Dmitry Baryshkov wrote:
>>> On Wed, Dec 11, 2024 at 08:57:17AM +0100, Andrej Picej wrote:
>>>>
>>>>
>>>> On 10. 12. 24 14:59, Dmitry Baryshkov wrote:
>>>>> On Tue, Dec 10, 2024 at 02:41:01PM +0100, Andrej Picej wrote:
>>>>>>
>>>>>>
>>>>>> On 10. 12. 24 12:43, Dmitry Baryshkov wrote:
>>>>>>> On Tue, Dec 10, 2024 at 10:19:00AM +0100, Andrej Picej wrote:
>>>>>>>> Add a optional properties to change LVDS output voltage. This should not
>>>>>>>> be static as this depends mainly on the connected display voltage
>>>>>>>> requirement. We have three properties:
>>>>>>>> - "ti,lvds-termination-ohms", which sets near end termination,
>>>>>>>> - "ti,lvds-vod-swing-data-microvolt" and
>>>>>>>> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
>>>>>>>> output voltage for data and clock lanes. They are defined as an array
>>>>>>>> with min and max values. The appropriate bitfield will be set if
>>>>>>>> selected constraints can be met.
>>>>>>>>
>>>>>>>> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
>>>>>>>> end termination will be used. Selecting only one:
>>>>>>>> "ti,lvds-vod-swing-data-microvolt" or
>>>>>>>> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
>>>>>>>> constraint for only data/clock lanes will be met. Setting both is
>>>>>>>> recommended.
>>>>>>>>
>>>>>>>> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
>>>>>>>> ---
>>>>>>>> Changes in v5:
>>>>>>>> - specify default values in sn65dsi83_parse_lvds_endpoint,
>>>>>>>> - move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
>>>>>>>> Changes in v4:
>>>>>>>> - fix typo in commit message bitfiled -> bitfield
>>>>>>>> - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
>>>>>>>> of separate variables for channel A/B
>>>>>>>> - add more checks on return value of "of_property_read_u32_array"
>>>>>>>> Changes in v3:
>>>>>>>> - use microvolts for default array values 1000 mV -> 1000000 uV.
>>>>>>>> Changes in v2:
>>>>>>>> - use datasheet tables to get the proper configuration
>>>>>>>> - since major change was done change the authorship to myself
>>>>>>>> ---
>>>>>>>>      drivers/gpu/drm/bridge/ti-sn65dsi83.c | 142 +++++++++++++++++++++++++-
>>>>>>>>      1 file changed, 139 insertions(+), 3 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>>>>>> index 57a7ed13f996..f9578b38da28 100644
>>>>>>>> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>>>>>> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
>>>>>>>> @@ -132,6 +132,16 @@
>>>>>>>>      #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
>>>>>>>>      #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
>>>>>>>> +enum sn65dsi83_channel {
>>>>>>>> +	CHANNEL_A,
>>>>>>>> +	CHANNEL_B
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +enum sn65dsi83_lvds_term {
>>>>>>>> +	OHM_100,
>>>>>>>> +	OHM_200
>>>>>>>> +};
>>>>>>>> +
>>>>>>>>      enum sn65dsi83_model {
>>>>>>>>      	MODEL_SN65DSI83,
>>>>>>>>      	MODEL_SN65DSI84,
>>>>>>>> @@ -147,6 +157,8 @@ struct sn65dsi83 {
>>>>>>>>      	struct regulator		*vcc;
>>>>>>>>      	bool				lvds_dual_link;
>>>>>>>>      	bool				lvds_dual_link_even_odd_swap;
>>>>>>>> +	int				lvds_vod_swing_conf[2];
>>>>>>>> +	int				lvds_term_conf[2];
>>>>>>>>      };
>>>>>>>>      static const struct regmap_range sn65dsi83_readable_ranges[] = {
>>>>>>>> @@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
>>>>>>>>      	.max_register = REG_IRQ_STAT,
>>>>>>>>      };
>>>>>>>> +static const int lvds_vod_swing_data_table[2][4][2] = {
>>>>>>>> +	{	/* 100 Ohm */
>>>>>>>> +		{ 180000, 313000 },
>>>>>>>> +		{ 215000, 372000 },
>>>>>>>> +		{ 250000, 430000 },
>>>>>>>> +		{ 290000, 488000 },
>>>>>>>> +	},
>>>>>>>> +	{	/* 200 Ohm */
>>>>>>>> +		{ 150000, 261000 },
>>>>>>>> +		{ 200000, 346000 },
>>>>>>>> +		{ 250000, 428000 },
>>>>>>>> +		{ 300000, 511000 },
>>>>>>>> +	},
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +static const int lvds_vod_swing_clock_table[2][4][2] = {
>>>>>>>> +	{	/* 100 Ohm */
>>>>>>>> +		{ 140000, 244000 },
>>>>>>>> +		{ 168000, 290000 },
>>>>>>>> +		{ 195000, 335000 },
>>>>>>>> +		{ 226000, 381000 },
>>>>>>>> +	},
>>>>>>>> +	{	/* 200 Ohm */
>>>>>>>> +		{ 117000, 204000 },
>>>>>>>> +		{ 156000, 270000 },
>>>>>>>> +		{ 195000, 334000 },
>>>>>>>> +		{ 234000, 399000 },
>>>>>>>> +	},
>>>>>>>> +};
>>>>>>>> +
>>>>>>>>      static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
>>>>>>>>      {
>>>>>>>>      	return container_of(bridge, struct sn65dsi83, bridge);
>>>>>>>> @@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
>>>>>>>>      		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
>>>>>>>>      	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
>>>>>>>> -	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
>>>>>>>> +	regmap_write(ctx->regmap, REG_LVDS_VCOM,
>>>>>>>> +			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
>>>>>>>> +			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
>>>>>>>>      	regmap_write(ctx->regmap, REG_LVDS_LANE,
>>>>>>>>      		     (ctx->lvds_dual_link_even_odd_swap ?
>>>>>>>>      		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
>>>>>>>> -		     REG_LVDS_LANE_CHA_LVDS_TERM |
>>>>>>>> -		     REG_LVDS_LANE_CHB_LVDS_TERM);
>>>>>>>> +		     (ctx->lvds_term_conf[CHANNEL_A] ?
>>>>>>>> +			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
>>>>>>>> +		     (ctx->lvds_term_conf[CHANNEL_B] ?
>>>>>>>> +			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
>>>>>>>>      	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
>>>>>>>>      	le16val = cpu_to_le16(mode->hdisplay);
>>>>>>>> @@ -576,10 +622,100 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
>>>>>>>>      	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
>>>>>>>>      };
>>>>>>>> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
>>>>>>>> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
>>>>>>>> +{
>>>>>>>> +	int i;
>>>>>>>> +
>>>>>>>> +	for (i = 0; i <= 3; i++) {
>>>>>>>> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
>>>>>>>> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
>>>>>>>> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
>>>>>>>> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
>>>>>>>> +			return i;
>>>>>>>> +	}
>>>>>>>> +
>>>>>>>> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
>>>>>>>> +	return -EINVAL;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
>>>>>>>> +{
>>>>>>>> +	struct device *dev = ctx->dev;
>>>>>>>> +	struct device_node *endpoint;
>>>>>>>> +	int endpoint_reg;
>>>>>>>> +	/* Set so the property can be freely selected if not defined */
>>>>>>>> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
>>>>>>>> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
>>>>>>>> +	u32 lvds_term;
>>>>>>>> +	u8 lvds_term_conf = 0x1;
>>>>>>>> +	int lvds_vod_swing_conf = 0x1;
>>>>>>>
>>>>>>> Magic values
>>>>>>
>>>>>> Can you please elaborate.
>>>>>>
>>>>>> I can use:
>>>>>> u8 lvds_term_conf = OHM_200;
>>>>>>
>>>>>> What about lvds_vod_swing_conf? Should I create additional define for it?
>>>>>> But this doesn't solve a hidden meaning? Maybe additional comment above?
>>>>>> Would like to avoid using voltages for it, since then we are reverse
>>>>>> engineering the table in datasheet to match the default reg value.
>>>>>
>>>>> I think the following example solves both problems:
>>>>>
>>>>> lvds_term = 200;
>>>>> of_property_read_u32(..., &lvds_term);
>>>>>
>>>>> if (lvds_term == 100)
>>>>> 	ctx->lvds_term_conf[channel] = OHM_100;
>>>>> else if (lvds_term == 200)
>>>>> 	ctx->lvds_term_conf[channel] = OHM_200;
>>>>> else
>>>>> 	return -EINVAL;
>>>>>
>>>>> The same approach can be applied to lvds_vod_swing_conf, resulting in
>>>>> removal of magic values.
>>>>
>>>> Sorry, but I think it is not that easy when it comes to the
>>>> lvds_vod_swing_conf. We should assign default value if
>>>> "ti,lvds-vod-swing-data-microvolt" and "ti,lvds-vod-swing-clock-microvolt"
>>>> are not defined. Default value of the lvds_vod_swing_conf is 0x1, but this
>>>> doesn't have any straight forward meaning like OHM_200 for example.
>>>>
>>>> What we can do in that case is that we copy the values from defined
>>>> datasheet tables to the "lvds_vod_swing_data[2]" and "lvds_vod_swing_clk[2]"
>>>> arrays and then run the
>>>> sn65dsi83_select_lvds_vod_swing with it, which will return the default value
>>>> (0x1).
>>>>
>>>> /* If both properties are not defined assign default limits */
>>>> if (ret_data && ret_clock) {
>>>> 	memcpy(lvds_vod_swing_data,
>>>> 	     lvds_vod_swing_data_table[ctx->lvds_term_conf[channel]][1],
>>>> 	     sizeof(lvds_vod_swing_data));
>>>> 	memcpy(lvds_vod_swing_clk,
>>>> 	    lvds_vod_swing_clock_table[ctx->lvds_term_conf[channel]][1],
>>>> 	    sizeof(lvds_vod_swing_clk));
>>>> }
>>>> lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev,
>>>> 	lvds_vod_swing_data, lvds_vod_swing_clk,
>>>> 	ctx->lvds_term_conf[channel]);
>>>> if (lvds_vod_swing_conf < 0) {
>>>> 	ret = lvds_vod_swing_conf;
>>>> 	goto exit;
>>>> }
>>>>
>>>> ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
>>>>
>>>> I'm not sure if using this approach gets rid of the problem with magic
>>>> values.
>>>> Or maybe I'm not seeing the obvious solution so please bear with me.
>>>
>>> Yes, the defaults (0..1000000) should be fixed to result in the same
>>> value (0x01) as if the property wasn't specified at all
>>
>> The defaults (0..1000000) is selected because in case if only one property
>> is defined in dts (ti,lvds-vod-swing-data-microvolt or
>> ti,lvds-vod-swing-clock-microvolt) the other array values don't effect the
>> decision which "lvds_vod_swing_conf" is selected. That's why we initialized
>> the array to be out off bounds of the datasheet tables, all values in the
>> table match the not defined property, so lvds_vod_swing_conf is selected
>> purely on the basis of the defined property.
> 
> I see, thanks for the explanation.
> 
>>
>> Example:
>> DTS
>> ti,lvds-vod-swing-data-microvolt = <250000 428000>;
>> //ti,lvds-vod-swing-clock-microvolt NOT DEFINED;
>>
>> After parsing the devicetree we will get:
>> lvds_vod_swing_data = [ 250000, 428000 ]
>> lvds_vod_swing_clk = [ 0, 1000000 ]
>>
>> In sn65dsi83_select_lvds_vod_swing lvds_vod_swing_clk[] values don't effect
>> the decision making since
>>
>> lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
>> lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1]
>>
>> is always true.
>>
>>>
>>> I think the following should work:
>>>
>>> 	/* artifical values to select the defaults in both cases */
>>> 	u32 lvds_vod_swing_data[2] = { 190000, 330000 };
>>> 	u32 lvds_vod_swing_clk[2] = { 150000, 250000 };
>>
>> This sets the default to 0x0. It should be:
>> u32 lvds_vod_swing_data[2] = { 200000, 372000 };
>> u32 lvds_vod_swing_clk[2] = { 156000, 290000 };
>> This selects the default 0x1 in both cases, if termination is 100 or 200
>> Ohms.
>>
>> Nevertheless I think I got your point. But I would still like to give the
>> user the freedom to only specify one property if maybe connected panel only
>> has limits on data lanes/clock lane.
>> So maybe set the arrays lvds_vod_swing_data/clk to [0, 1000000] if
>> of_property_read_u32_array returns -EINVAL (property does not exist).
>> What do you say?
> 
> After your explanation, I think it might be better to explicitly set the
> value to 0x1, but not at the top of the function, but next to a check
> that both properties are (not) set.

Ok. Will apply this in the next version.
Thanks.

> 
>>
>>>
>>> Yes, they are artificial, as stated in the comment. Yes, I think it's
>>> better than special-casing in the property handling.
>>>
> 


From mark.rutland at arm.com  Thu Dec 12 02:40:46 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 12 Dec 2024 10:40:46 +0000
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <87bjxhs2t7.wl-maz@kernel.org>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <87ed2fs03w.wl-maz@kernel.org>
 <92cee905-a505-4ce9-9bbc-6fba4cea1d80@quicinc.com>
 <86sequsdtp.wl-maz@kernel.org>
 <c197264b-3791-493a-b717-3dfd844de922@quicinc.com>
 <87bjxhs2t7.wl-maz@kernel.org>
Message-ID: <Z1q9rnzOlB9J5dXb@J2N7QTR9R3>

On Thu, Dec 12, 2024 at 08:50:12AM +0000, Marc Zyngier wrote:
> On Thu, 12 Dec 2024 05:31:00 +0000,
> Pavan Kondeti <quic_pkondeti at quicinc.com> wrote:
> > 
> > On Wed, Dec 11, 2024 at 10:40:02AM +0000, Marc Zyngier wrote:
> > > On Wed, 11 Dec 2024 00:37:34 +0000,
> > > Pavan Kondeti <quic_pkondeti at quicinc.com> wrote:
> > > > 
> > > > On Tue, Dec 10, 2024 at 09:24:03PM +0000, Marc Zyngier wrote:
> > > > > > +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> > > > > > +{
> > > > > > +	int ret;
> > > > > > +
> > > > > > +#ifdef CONFIG_ARM64
> > > > > > +	/*
> > > > > > +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> > > > > > +	 * to switch the secure mode to avoid the dependency on zap shader.
> > > > > > +	 */
> > > > > > +	if (is_kernel_in_hyp_mode())
> > > > > > +		goto direct_switch;
> > > > > 
> > > > > No, please. To check whether you are *booted* at EL2, you need to
> > > > > check for is_hyp_available(). Whether the kernel runs at EL1 or EL2 is
> > > > > none of the driver's business, really. This is still absolutely
> > > > > disgusting from an abstraction perspective, but I guess we don't have
> > > > > much choice here.
> > > > > 
> > > > 
> > > > Thanks Marc. Any suggestions on how we can make is_hyp_mode_available()
> > > > available for modules? Do you prefer exporting
> > > > kvm_protected_mode_initialized and __boot_cpu_mode symbols directly or
> > > > try something like [1]?
> > > 
> > > Ideally, neither. These were bad ideas nine years ago, and they still
> > > are. The least ugly hack I can come up with is the patch below, and
> > > you'd write something like:
> > > 
> > > 	if (cpus_have_cap(ARM64_HAS_EL2_OWNERSHIP))
> > > 		blah();
> > > 
> > > This is obviously completely untested.
> > > 
> > 
> > I have tested your patch. It works as intended. Thanks Marc.
> 
> Note that you will probably get some push-back from the arm64
> maintainers on this front, because this is a fairly incomplete (and
> fragile) solution.
> 
> It would be much better if the discriminant came from the device tree.
> After all, the hypervisor is fscking-up^W^Wchanging the programming
> model of the GPU, and that should be reflected in the DT. Because for
> all intent and purposes, this is not the same hardware anymore.

FWIW I agree 100%, this should be described in DT.

The cpucap doesn't describe the actual property we care about, and it
cannot in general (e.g. for nested virt). I would strongly prefer to not
have that as it's setting ourselves up for failure.

> The GPU isn't the only device that needs fixing in that way: the
> SMMUv3 needs to be exposed to the OS, and the PCIe ports need to be
> linked to it and the ITS. So at the end of the day, detecting EL2 only
> serves a limited purpose. You need to handle these cases, and might as
> well put the GPU in the same bag.
> 
> Which means that you'd either have a pair of static DTs (one that
> exposes the brokenness of the firmware, and one that doesn't), or you
> go the dtbhack route to compose the DT at boot time.

Liekwise, agreed on all of this.

Mark.


From angelogioacchino.delregno at collabora.com  Thu Dec 12 02:46:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 12 Dec 2024 11:46:21 +0100
Subject: [PATCH 1/2] memory/mediatek: Add an interface to get current DDR
 data rate
In-Reply-To: <20241212090029.13692-2-crystal.guo@mediatek.com>
References: <20241212090029.13692-1-crystal.guo@mediatek.com>
 <20241212090029.13692-2-crystal.guo@mediatek.com>
Message-ID: <f1515081-14f3-4cde-9c9a-16390b8d3891@collabora.com>

Il 12/12/24 09:59, Crystal Guo ha scritto:
> Add MediaTek DRAMC driver to provide an interface that can
> obtain current DDR data rate.
> 
> Signed-off-by: Crystal Guo <crystal.guo at mediatek.com>
> ---
>   drivers/memory/Kconfig                 |   1 +
>   drivers/memory/Makefile                |   1 +
>   drivers/memory/mediatek/Kconfig        |  21 ++
>   drivers/memory/mediatek/Makefile       |   2 +
>   drivers/memory/mediatek/mtk-dramc.c    | 325 +++++++++++++++++++++++++
>   include/linux/soc/mediatek/mtk-dramc.h |  41 ++++
>   6 files changed, 391 insertions(+)
>   create mode 100644 drivers/memory/mediatek/Kconfig
>   create mode 100644 drivers/memory/mediatek/Makefile
>   create mode 100644 drivers/memory/mediatek/mtk-dramc.c
>   create mode 100644 include/linux/soc/mediatek/mtk-dramc.h
> 
> diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
> index c82d8d8a16ea..b1698549ff81 100644
> --- a/drivers/memory/Kconfig
> +++ b/drivers/memory/Kconfig
> @@ -227,5 +227,6 @@ config STM32_FMC2_EBI
>   
>   source "drivers/memory/samsung/Kconfig"
>   source "drivers/memory/tegra/Kconfig"
> +source "drivers/memory/mediatek/Kconfig"
>   
>   endif
> diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
> index d2e6ca9abbe0..cf1091449d2e 100644
> --- a/drivers/memory/Makefile
> +++ b/drivers/memory/Makefile
> @@ -27,6 +27,7 @@ obj-$(CONFIG_STM32_FMC2_EBI)	+= stm32-fmc2-ebi.o
>   
>   obj-$(CONFIG_SAMSUNG_MC)	+= samsung/
>   obj-$(CONFIG_TEGRA_MC)		+= tegra/
> +obj-$(CONFIG_HAVE_MTK_MC)	+= mediatek/
>   obj-$(CONFIG_TI_EMIF_SRAM)	+= ti-emif-sram.o
>   obj-$(CONFIG_FPGA_DFL_EMIF)	+= dfl-emif.o
>   
> diff --git a/drivers/memory/mediatek/Kconfig b/drivers/memory/mediatek/Kconfig
> new file mode 100644
> index 000000000000..00764cdb157e
> --- /dev/null
> +++ b/drivers/memory/mediatek/Kconfig
> @@ -0,0 +1,21 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +config HAVE_MTK_MC
> +	bool "MediaTek Memory Controller support"
> +	help
> +	  This option allows to enable MediaTek memory controller drivers,
> +	  which may include controllers for DRAM or others.
> +	  Select Y here if you need support for MediaTek memory controller.
> +	  If you don't need, select N.
> +
> +if HAVE_MTK_MC
> +
> +config MTK_DRAMC
> +	tristate "MediaTek DRAMC driver"
> +	depends on HAVE_MTK_MC
> +	help
> +	  This option selects the MediaTek DRAMC driver, which provides
> +	  an interface for reporting the current data rate of DRAM.
> +	  Select Y here if you need support for the MediaTek DRAMC driver.
> +	  If you don't need, select N.
> +
> +endif
> diff --git a/drivers/memory/mediatek/Makefile b/drivers/memory/mediatek/Makefile
> new file mode 100644
> index 000000000000..a1395fc55b41
> --- /dev/null
> +++ b/drivers/memory/mediatek/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +obj-$(CONFIG_MTK_DRAMC)		+= mtk-dramc.o
> diff --git a/drivers/memory/mediatek/mtk-dramc.c b/drivers/memory/mediatek/mtk-dramc.c
> new file mode 100644
> index 000000000000..9c2c8e187a4a
> --- /dev/null
> +++ b/drivers/memory/mediatek/mtk-dramc.c
> @@ -0,0 +1,325 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2024 MediaTek Inc.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/printk.h>
> +#include <linux/io.h>
> +#include <linux/soc/mediatek/mtk-dramc.h>
> +
> +static struct platform_device *dramc_pdev;
> +static struct platform_driver dramc_drv;

You don't need these globals.

> +
> +static int fmeter_init(struct platform_device *pdev,
> +		       struct fmeter_dev_t *fmeter_dev_ptr, unsigned int fmeter_version)
> +{
> +	struct device_node *dramc_node = pdev->dev.of_node;
> +	int ret;
> +
> +	ret = of_property_read_u32(dramc_node,
> +				   "crystal-freq", &(fmeter_dev_ptr->crystal_freq));
> +	ret |= of_property_read_u32(dramc_node,
> +				    "shu-of", &(fmeter_dev_ptr->shu_of));

ret |= x doesn't make sense.

ret = ...
if (ret)
	return ret;

> +	ret |= of_property_read_u32_array(dramc_node,
> +					  "shu-lv", (unsigned int *)&(fmeter_dev_ptr->shu_lv), 3);
> +	ret |= of_property_read_u32_array(dramc_node,
> +					  "pll-id", (unsigned int *)&(fmeter_dev_ptr->pll_id), 3);
> +	ret |= of_property_read_u32_array(dramc_node,
> +					  "sdmpcw", (unsigned int *)(fmeter_dev_ptr->sdmpcw), 6);
> +	ret |= of_property_read_u32_array(dramc_node,
> +					  "posdiv", (unsigned int *)(fmeter_dev_ptr->posdiv), 6);
> +	ret |= of_property_read_u32_array(dramc_node,
> +					  "fbksel", (unsigned int *)(fmeter_dev_ptr->fbksel), 6);
> +	ret |= of_property_read_u32_array(dramc_node,
> +					  "dqsopen", (unsigned int *)(fmeter_dev_ptr->dqsopen), 6);
> +	if (fmeter_version == 1) {
> +		fmeter_dev_ptr->version = 1;
> +		ret |= of_property_read_u32_array(dramc_node,
> +			"async-ca", (unsigned int *)(fmeter_dev_ptr->async_ca), 6);
> +		ret |= of_property_read_u32_array(dramc_node,
> +			"dq-ser-mode", (unsigned int *)(fmeter_dev_ptr->dq_ser_mode), 6);
> +	}
> +	return ret;
> +}
> +
> +static ssize_t dram_data_rate_show(struct device_driver *driver, char *buf)
> +{
> +	return snprintf(buf, PAGE_SIZE, "DRAM data rate = %d\n",
> +		mtk_dramc_get_data_rate());
> +}
> +
> +static DRIVER_ATTR_RO(dram_data_rate);> +
> +static int dramc_probe(struct platform_device *pdev)
> +{
> +	struct device_node *dramc_node = pdev->dev.of_node;
> +	struct dramc_dev_t *dramc_dev_ptr;
> +	unsigned int fmeter_version;
> +	struct resource *res;
> +	unsigned int i, size;
> +	int ret;
> +
> +	pr_info("%s: module probe.\n", __func__);

This pr_info makes no sense. Please remove.

> +	dramc_pdev = pdev;
> +	dramc_dev_ptr = devm_kmalloc(&pdev->dev,
> +				     sizeof(struct dramc_dev_t), GFP_KERNEL);
> +
> +	if (!dramc_dev_ptr)
> +		return -ENOMEM;
> +
> +	ret = of_property_read_u32(dramc_node,
> +				   "support-ch-cnt", &dramc_dev_ptr->support_ch_cnt);
> +	if (ret) {
> +		pr_info("%s: get support_ch_cnt fail\n", __func__);

that's an error, and you want dev_err_probe().

> +		return -EINVAL;
> +	}
> +
> +	dramc_dev_ptr->sleep_base = of_iomap(dramc_node,
> +					     dramc_dev_ptr->support_ch_cnt * 4);
> +	if (IS_ERR(dramc_dev_ptr->sleep_base)) {
> +		pr_info("%s: unable to map sleep base\n", __func__);

same, here and everywhere else

> +		return -EINVAL;
> +	}
> +
> +	size = sizeof(phys_addr_t) * dramc_dev_ptr->support_ch_cnt;
> +	dramc_dev_ptr->dramc_chn_base_ao = devm_kmalloc(&pdev->dev,
> +							size, GFP_KERNEL);
> +	if (!(dramc_dev_ptr->dramc_chn_base_ao))
> +		return -ENOMEM;
> +	dramc_dev_ptr->dramc_chn_base_nao = devm_kmalloc(&pdev->dev,
> +							 size, GFP_KERNEL);
> +	if (!(dramc_dev_ptr->dramc_chn_base_nao))
> +		return -ENOMEM;
> +	dramc_dev_ptr->ddrphy_chn_base_ao = devm_kmalloc(&pdev->dev,
> +							 size, GFP_KERNEL);
> +	if (!(dramc_dev_ptr->ddrphy_chn_base_ao))
> +		return -ENOMEM;
> +	dramc_dev_ptr->ddrphy_chn_base_nao = devm_kmalloc(&pdev->dev,
> +							  size, GFP_KERNEL);
> +	if (!(dramc_dev_ptr->ddrphy_chn_base_nao))
> +		return -ENOMEM;
> +
> +	for (i = 0; i < dramc_dev_ptr->support_ch_cnt; i++) {
> +		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
> +		dramc_dev_ptr->dramc_chn_base_ao[i] =
> +			devm_ioremap_resource(&pdev->dev, res);
> +		if (IS_ERR(dramc_dev_ptr->dramc_chn_base_ao[i])) {
> +			pr_info("%s: unable to map ch%d DRAMC AO base\n",
> +				__func__, i);
> +			return -EINVAL;
> +		}
> +
> +		res = platform_get_resource(pdev, IORESOURCE_MEM,
> +					    i + dramc_dev_ptr->support_ch_cnt);
> +		dramc_dev_ptr->dramc_chn_base_nao[i] =
> +			devm_ioremap_resource(&pdev->dev, res);
> +		if (IS_ERR(dramc_dev_ptr->dramc_chn_base_nao[i])) {
> +			pr_info("%s: unable to map ch%d DRAMC NAO base\n",
> +				__func__, i);
> +			return -EINVAL;
> +		}
> +
> +		res = platform_get_resource(pdev, IORESOURCE_MEM,
> +					    i + dramc_dev_ptr->support_ch_cnt * 2);
> +		dramc_dev_ptr->ddrphy_chn_base_ao[i] =
> +			devm_ioremap_resource(&pdev->dev, res);
> +		if (IS_ERR(dramc_dev_ptr->ddrphy_chn_base_ao[i])) {
> +			pr_info("%s: unable to map ch%d DDRPHY AO base\n",
> +				__func__, i);
> +			return -EINVAL;
> +		}
> +
> +		res = platform_get_resource(pdev, IORESOURCE_MEM,
> +					    i + dramc_dev_ptr->support_ch_cnt * 3);
> +		dramc_dev_ptr->ddrphy_chn_base_nao[i] =
> +			devm_ioremap_resource(&pdev->dev, res);
> +		if (IS_ERR(dramc_dev_ptr->ddrphy_chn_base_nao[i])) {
> +			pr_info("%s: unable to map ch%d DDRPHY NAO base\n",
> +				__func__, i);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	ret = of_property_read_u32(dramc_node, "fmeter-version", &fmeter_version);

This is something for platform data, not devicetree.

> +	if (ret) {
> +		pr_info("%s: get fmeter_version fail\n", __func__);
> +		return -EINVAL;
> +	}
> +	pr_info("%s: fmeter_version(%d)\n", __func__, fmeter_version);
> +
> +	if (fmeter_version == 1) {
> +		dramc_dev_ptr->fmeter_dev_ptr = devm_kmalloc(&pdev->dev,
> +							     sizeof(struct fmeter_dev_t),
> +							     GFP_KERNEL);
> +		if (!(dramc_dev_ptr->fmeter_dev_ptr)) {
> +			pr_info("%s: memory  alloc fail\n", __func__);
> +			return -ENOMEM;
> +		}
> +		ret = fmeter_init(pdev, dramc_dev_ptr->fmeter_dev_ptr, fmeter_version);
> +		if (ret) {
> +			pr_info("%s: fmeter_init fail\n", __func__);
> +			return -EINVAL;
> +		}
> +	} else {
> +		dramc_dev_ptr->fmeter_dev_ptr = NULL;
> +	}
> +	ret = driver_create_file(pdev->dev.driver, &driver_attr_dram_data_rate);
> +	if (ret) {
> +		pr_info("%s: fail to create dram_data_rate sysfs\n", __func__);
> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, dramc_dev_ptr);
> +	pr_info("%s: DRAM data rate = %d\n", __func__,
> +		mtk_dramc_get_data_rate());
> +
> +	return ret;
> +}
> +
> +static unsigned int fmeter_v1(struct dramc_dev_t *dramc_dev_ptr)
> +{
> +	struct fmeter_dev_t *fmeter_dev_ptr =
> +		(struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr;
> +	unsigned int shu_lv_val;
> +	unsigned int pll_id_val;
> +	unsigned int sdmpcw_val;
> +	unsigned int posdiv_val;
> +	unsigned int ckdiv4_val;
> +	unsigned int offset;
> +	unsigned int vco_freq;
> +	unsigned int fbksel;
> +	unsigned int dqsopen;
> +	unsigned int async_ca;
> +	unsigned int dq_ser_mode;
> +
> +	shu_lv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] +
> +		fmeter_dev_ptr->shu_lv.offset) &
> +		fmeter_dev_ptr->shu_lv.mask) >>
> +		fmeter_dev_ptr->shu_lv.shift;
> +
> +	pll_id_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] +
> +		fmeter_dev_ptr->pll_id.offset) &
> +		fmeter_dev_ptr->pll_id.mask) >>
> +		fmeter_dev_ptr->pll_id.shift;
> +
> +	offset = fmeter_dev_ptr->sdmpcw[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	sdmpcw_val = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->sdmpcw[pll_id_val].mask) >>
> +		fmeter_dev_ptr->sdmpcw[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->posdiv[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	posdiv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->posdiv[pll_id_val].mask) >>
> +		fmeter_dev_ptr->posdiv[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->fbksel[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	fbksel = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->fbksel[pll_id_val].mask) >>
> +		fmeter_dev_ptr->fbksel[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->dqsopen[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	dqsopen = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->dqsopen[pll_id_val].mask) >>
> +		fmeter_dev_ptr->dqsopen[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->async_ca[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	async_ca = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->async_ca[pll_id_val].mask) >>
> +		fmeter_dev_ptr->async_ca[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->dq_ser_mode[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	dq_ser_mode = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->dq_ser_mode[pll_id_val].mask) >>
> +		fmeter_dev_ptr->dq_ser_mode[pll_id_val].shift;
> +	ckdiv4_val = (dq_ser_mode == 1); // 1: DIV4, 2: DIV8, 3: DIV16
> +
> +	posdiv_val &= ~(0x4);
> +
> +	vco_freq = ((fmeter_dev_ptr->crystal_freq) *
> +		(sdmpcw_val >> 7)) >> posdiv_val >> 1 >> ckdiv4_val
> +		<< fbksel;

That vco_freq calculation is seriously unreadable :\

> +
> +	if ((dqsopen == 1) && (async_ca == 1))
> +		vco_freq >>= 1;
> +
> +	return vco_freq;
> +}
> +
> +/*
> + * mtk_dramc_get_data_rate - calculate DRAM data rate
> + *
> + * Returns DRAM data rate (MB/s)
> + */
> +unsigned int mtk_dramc_get_data_rate(void)
> +{
> +	struct dramc_dev_t *dramc_dev_ptr;
> +	struct fmeter_dev_t *fmeter_dev_ptr;
> +
> +	if (!dramc_pdev)
> +		return 0;
> +
> +	dramc_dev_ptr =
> +		(struct dramc_dev_t *)platform_get_drvdata(dramc_pdev);
> +
> +	fmeter_dev_ptr = (struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr;
> +	if (!fmeter_dev_ptr)
> +		return 0;
> +
> +	if (fmeter_dev_ptr->version == 1)
> +		return fmeter_v1(dramc_dev_ptr);
> +	return 0;
> +}
> +EXPORT_SYMBOL(mtk_dramc_get_data_rate);

Not sure about mtk_dramc_get_data_rate().

Please show an example of how you're actually using it in the external driver,
as there are many ways to expose this value.

> +
> +static int dramc_remove(struct platform_device *pdev)
> +{
> +	dramc_pdev = NULL;
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id dramc_of_ids[] = {
> +	{.compatible = "mediatek,common-dramc",},

{ .compatible = "mediatek,something" },
{ /* sentinel */ }

> +	{}
> +};
> +
> +static struct platform_driver dramc_drv = {
> +	.probe = dramc_probe,
> +	.remove = dramc_remove,
> +	.driver = {
> +		.name = "dramc_drv",
> +		.owner = THIS_MODULE,
> +		.of_match_table = dramc_of_ids,
> +	},
> +};

module_platform_driver(...)

> +
> +static int __init dramc_drv_init(void)

...so that function is not needed.

> +{
> +	int ret;
> +
> +	ret = platform_driver_register(&dramc_drv);
> +	if (ret) {
> +		pr_info("%s: init fail, ret 0x%x\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +module_init(dramc_drv_init);
> +
> +MODULE_AUTHOR("Mediatek Corporation");

MODULE_AUTHOR("Author Name <your.email at mediatek.com>");

> +MODULE_DESCRIPTION("MediaTek DRAMC Driver");

MODULE_DESCRIPTION("MediaTek DRAM Controller driver");



...and I have a hunch that this series will need many versions before the code
quality bar reaches a nice level...

Cheers,
Angelo

> +MODULE_LICENSE("GPL");


From ryan.roberts at arm.com  Thu Dec 12 02:55:45 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 12 Dec 2024 10:55:45 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <87cyhxs3xq.wl-maz@kernel.org>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-3-miko.lenczewski@arm.com>
 <87cyhxs3xq.wl-maz@kernel.org>
Message-ID: <084c5ada-51af-4c1a-b50a-4401e62ddbd6@arm.com>

On 12/12/2024 08:25, Marc Zyngier wrote:
> Ah, so this is where this is hiding. I missed it in my review of patch
> #1 yesterday.
> 
> On Wed, 11 Dec 2024 16:01:38 +0000,
> Miko?aj Lenczewski <miko.lenczewski at arm.com> wrote:
>>
>> The Break-Before-Make cpu feature supports multiple levels (levels 0-2),
>> and this commit adds a dedicated BBML2 cpufeature to test against
>> support for.
>>
>> In supporting BBM level 2, we open ourselves up to potential TLB
>> Conflict Abort Exceptions during expected execution, instead of only
>> in exceptional circumstances. In the case of an abort, it is
>> implementation defined at what stage the abort is generated, and
> 
> *IF* stage-2 is enabled. Also, in the case of the EL2&0 translation
> regime, no stage-2 applies, so it can only be a stage-1 abort.
> 
>> the minimal set of required invalidations is also implementation
>> defined. The maximal set of invalidations is to do a `tlbi vmalle1`
>> or `tlbi vmalls12e1`, depending on the stage.
>>
>> Such aborts should not occur on Arm hardware, and were not seen in
>> benchmarked systems, so unless performance concerns arise, implementing
> 
> Which systems? Given that you have deny-listed *all* half recent ARM
> Ltd implementations, I'm a bit puzzled.
> 
>> the abort handlers with the worst-case invalidations seems like an
>> alright hack.
>>
>> Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
>> ---
>>  arch/arm64/include/asm/cpufeature.h | 14 ++++++++++++++
>>  arch/arm64/kernel/cpufeature.c      |  7 +++++++
>>  arch/arm64/mm/fault.c               | 27 ++++++++++++++++++++++++++-
>>  arch/arm64/tools/cpucaps            |  1 +
>>  4 files changed, 48 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
>> index 8b4e5a3cd24c..a9f2ac335392 100644
>> --- a/arch/arm64/include/asm/cpufeature.h
>> +++ b/arch/arm64/include/asm/cpufeature.h
>> @@ -866,6 +866,20 @@ static __always_inline bool system_supports_mpam_hcr(void)
>>  	return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
>>  }
>>  
>> +static inline bool system_supports_bbml2(void)
>> +{
>> +	/* currently, BBM is only relied on by code touching the userspace page
>> +	 * tables, and as such we are guaranteed that caps have been finalised.
>> +	 *
>> +	 * if later we want to use BBM for kernel mappings, particularly early
>> +	 * in the kernel, this may return 0 even if BBML2 is actually supported,
>> +	 * which means unnecessary break-before-make sequences, but is still
>> +	 * correct
> 
> Comment style, capitalisation, punctuation.
> 
>> +	 */
>> +
>> +	return alternative_has_cap_unlikely(ARM64_HAS_BBML2);
>> +}
>> +
>>  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 6ce71f444ed8..7cc94bd5da24 100644
>> --- a/arch/arm64/kernel/cpufeature.c
>> +++ b/arch/arm64/kernel/cpufeature.c
>> @@ -2917,6 +2917,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>>  		.matches = has_cpuid_feature,
>>  		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP)
>>  	},
>> +	{
>> +		.desc = "BBM Level 2 Support",
>> +		.capability = ARM64_HAS_BBML2,
>> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
>> +		.matches = has_cpuid_feature,
>> +		ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, BBM, 2)
>> +	},
>>  	{
>>  		.desc = "52-bit Virtual Addressing for KVM (LPA2)",
>>  		.capability = ARM64_HAS_LPA2,
>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>> index ef63651099a9..dc119358cbc1 100644
>> --- a/arch/arm64/mm/fault.c
>> +++ b/arch/arm64/mm/fault.c
>> @@ -844,6 +844,31 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
>>  	return 0;
>>  }
>>  
>> +static int do_conflict_abort(unsigned long far, unsigned long esr,
>> +			     struct pt_regs *regs)
>> +{
>> +	if (!system_supports_bbml2())
>> +		return do_bad(far, esr, regs);
>> +
>> +	/* if we receive a TLB conflict abort, we know that there are multiple
>> +	 * TLB entries that translate the same address range. the minimum set
>> +	 * of invalidations to clear these entries is implementation defined.
>> +	 * the maximum set is defined as either tlbi(vmalls12e1) or tlbi(alle1).
>> +	 *
>> +	 * if el2 is enabled and stage 2 translation enabled, this may be
>> +	 * raised as a stage 2 abort. if el2 is enabled but stage 2 translation
>> +	 * disabled, or if el2 is disabled, it will be raised as a stage 1
>> +	 * abort.
>> +	 *
>> +	 * local_flush_tlb_all() does a tlbi(vmalle1), which is enough to
>> +	 * handle a stage 1 abort.
> 
> Same comment about comments.
> 
>> +	 */
>> +
>> +	local_flush_tlb_all();
> 
> The elephant in the room: if TLBs are in such a sorry state, what
> guarantees we can make it this far?

I'll leave Miko to respond to your other comments, but I wanted to address this
one, since it's pretty fundamental. We went around this loop internally and
concluded that what we are doing is architecturally sound.

The expectation is that a conflict abort can only be generated as a result of
the change in patch 4 (and patch 5). That change makes it possible for the TLB
to end up with a multihit. But crucially that can only happen for user space
memory because that change only operates on user memory. And while the TLB may
detect the conflict at any time, the conflict abort is only permitted to be
reported when an architectural access is prevented by the conflict. So we never
do anything that would allow a conflict for a kernel memory access and a user
memory conflict abort can never be triggered as a result of accessing kernel memory.

Copy/pasting comment from AlexC on the topic, which explains it better than I can:

"""
The intent is certainly that in cases where the hardware detects a TLB conflict
abort, it is only permitted to report it (by generating an exception) if it
applies to an access that is being attempted architecturally. ... that property
can be built from the following two properties:

1. The TLB conflict can only be reported as an Instruction Abort or a Data Abort

2. Those two exception types must be reported synchronously and precisely.
"""

> 
> I honestly don't think you can reliably handle a TLB Conflict abort in
> the same translation regime as the original fault, given that we don't
> know the scope of that fault. You are probably making an educated
> guess that it is good enough on the CPUs you know of, but I don't see
> anything in the architecture that indicates the "blast radius" of a
> TLB conflict.

OK, so I'm claiming that the blast radius is limited to the region of memory
that we are operating on in contpte_collapse() in patch 4. Perhaps we need to go
re-read the ARM and come back with the specific statements that led us to that
conclusion?

Thanks,
Ryan

> 
> Which makes me think that your KVM patch is equally broken on nVHE and
> hVHE. Such fault should probably be handled while at EL2, not after
> returning to EL1.
> 
> Thanks,
> 
> 	M.
> 



From jinjian.song at fibocom.com  Thu Dec 12 02:55:55 2024
From: jinjian.song at fibocom.com (Jinjian Song)
Date: Thu, 12 Dec 2024 18:55:55 +0800
Subject: [net-next v1] net: wwan: t7xx: Fix FSM command timeout issue
Message-ID: <20241212105555.10364-1-jinjian.song@fibocom.com>

When driver processes the internal state change command, it use
asynchronous thread to process the command operation. If the main
thread detects that the task has timed out, the asynchronous thread
will panic when executing te completion notification because the
main thread completion object is released.

BUG: unable to handle page fault for address: fffffffffffffff8
PGD 1f283a067 P4D 1f283a067 PUD 1f283c067 PMD 0
Oops: 0000 [#1] PREEMPT SMP NOPTI
RIP: 0010:complete_all+0x3e/0xa0
[...]
Call Trace:
 <TASK>
 ? __die_body+0x68/0xb0
 ? page_fault_oops+0x379/0x3e0
 ? exc_page_fault+0x69/0xa0
 ? asm_exc_page_fault+0x22/0x30
 ? complete_all+0x3e/0xa0
 fsm_main_thread+0xa3/0x9c0 [mtk_t7xx (HASH:1400 5)]
 ? __pfx_autoremove_wake_function+0x10/0x10
 kthread+0xd8/0x110
 ? __pfx_fsm_main_thread+0x10/0x10 [mtk_t7xx (HASH:1400 5)]
 ? __pfx_kthread+0x10/0x10
 ret_from_fork+0x38/0x50
 ? __pfx_kthread+0x10/0x10
 ret_from_fork_asm+0x1b/0x30
 </TASK>
[...]
CR2: fffffffffffffff8
---[ end trace 0000000000000000 ]---

After the main thread determines that the task has timed out, mark
the completion invalid, and add judgment in the asynchronous task.

Signed-off-by: Jinjian Song <jinjian.song at fibocom.com>
---
 drivers/net/wwan/t7xx/t7xx_state_monitor.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
index 3931c7a13f5a..57f1a7730fff 100644
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
@@ -108,7 +108,8 @@ static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command
 {
 	if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
 		*cmd->ret = result;
-		complete_all(cmd->done);
+		if (cmd->done)
+			complete_all(cmd->done);
 	}
 
 	kfree(cmd);
@@ -503,8 +504,10 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id
 
 		wait_ret = wait_for_completion_timeout(&done,
 						       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
-		if (!wait_ret)
+		if (!wait_ret) {
+			cmd->done = NULL;
 			return -ETIMEDOUT;
+		}
 
 		return ret;
 	}
-- 
2.34.1



From krzk at kernel.org  Thu Dec 12 02:58:00 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 11:58:00 +0100
Subject: [PATCH 2/2] dt-bindings: memory-controllers: Add mediatek
 common-dramc dt-bindings
In-Reply-To: <20241212090029.13692-3-crystal.guo@mediatek.com>
References: <20241212090029.13692-1-crystal.guo@mediatek.com>
 <20241212090029.13692-3-crystal.guo@mediatek.com>
Message-ID: <c978937a-e589-4e9a-ba37-265dbfc1b252@kernel.org>

On 12/12/2024 09:59, Crystal Guo wrote:
> Add devicetree binding for mediatek common-dramc driver.
> 
> The DRAM controller of MediaTek SoC provides an interface to
> get the current data rate of DRAM.

Bindings are before users.



A nit, subject: drop second/last, redundant "dt-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

> 
> Signed-off-by: Crystal Guo <crystal.guo at mediatek.com>
> ---
>  .../mediatek,common-dramc.yaml                | 129 ++++++++++++++++++
>  1 file changed, 129 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
> new file mode 100644
> index 000000000000..c9e608c7f183
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,common-dramc.yaml
> @@ -0,0 +1,129 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +# Copyright (c) 2024 MediaTek Inc.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/memory-controllers/mediatek,common-dramc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek Common DRAMC (DRAM Controller)

Common? Is this a real thing? Please describe the hardware.

> +
> +maintainers:
> +  - Crystal Guo <crystal.guo at mediatek.com>
> +
> +description: |

Do not need '|' unless you need to preserve formatting.

> +  The DRAM controller of MediaTek SoC provides an interface to
> +  get the current data rate of DRAM.

So not common here?

> +
> +properties:
> +  compatible:
> +    const: mediatek,common-dramc

This has to be SoC.

> +
> +  reg:
> +    minItems: 9

Why this is flexible?

> +    items:
> +      - description: DRAMC_AO_CHA_BASE
> +      - description: DRAMC_AO_CHB_BASE
> +      - description: DRAMC_AO_CHC_BASE
> +      - description: DRAMC_AO_CHD_BASE
> +      - description: DRAMC_NAO_CHA_BASE
> +      - description: DRAMC_NAO_CHB_BASE
> +      - description: DRAMC_NAO_CHC_BASE
> +      - description: DRAMC_NAO_CHD_BASE
> +      - description: DDRPHY_AO_CHA_BASE
> +      - description: DDRPHY_AO_CHB_BASE
> +      - description: DDRPHY_AO_CHC_BASE
> +      - description: DDRPHY_AO_CHD_BASE
> +      - description: DDRPHY_NAO_CHA_BASE
> +      - description: DDRPHY_NAO_CHB_BASE
> +      - description: DDRPHY_NAO_CHC_BASE
> +      - description: DDRPHY_NAO_CHD_BASE
> +      - description: SLEEP_BASE

Don't use some defines. Look at other bindings how they describe items.

> +
> +  support-ch-cnt:

Nope

> +    maxItems: 1
> +
> +  fmeter-version:
> +    maxItems: 1
> +    description:
> +      Fmeter version for calculating dram data rate
> +
> +  crystal-freq:
> +    maxItems: 1
> +    description:
> +      Reference clock rate in MHz
> +
> +  shu-of:
> +    maxItems: 1
> +
> +  pll-id: true
> +  shu-lv: true
> +  sdmpcw: true
> +  posdiv: true
> +  fbksel: true
> +  dqsopen: true
> +  async-ca: true
> +  dq-ser-mode: true


This binding is terrible. Was not tested and does not follow any
guidelines. Please read example schema and writing bindings document.
You can also read slides from my talks...


> +
> +required:
> +  - compatible
> +  - reg
> +  - support-ch-cnt
> +  - fmeter-version
> +  - crystal-freq
> +  - pll-id
> +  - shu-lv
> +  - shu-of
> +  - sdmpcw
> +  - posdiv
> +  - fbksel
> +  - dqsopen
> +  - async-ca
> +  - dq-ser-mode
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        dramc: dramc at 10230000 {

memory-controller@
and drop unused label.

Best regards,
Krzysztof


From mateusz.polchlopek at intel.com  Thu Dec 12 03:01:51 2024
From: mateusz.polchlopek at intel.com (Mateusz Polchlopek)
Date: Thu, 12 Dec 2024 12:01:51 +0100
Subject: [net-next v1] net: wwan: t7xx: Fix FSM command timeout issue
In-Reply-To: <20241212105555.10364-1-jinjian.song@fibocom.com>
References: <20241212105555.10364-1-jinjian.song@fibocom.com>
Message-ID: <b409c23a-0b6f-458c-8e34-039338e799c0@intel.com>



On 12/12/2024 11:55 AM, Jinjian Song wrote:
> When driver processes the internal state change command, it use
> asynchronous thread to process the command operation. If the main
> thread detects that the task has timed out, the asynchronous thread
> will panic when executing te completion notification because the
> main thread completion object is released.
> 
> BUG: unable to handle page fault for address: fffffffffffffff8
> PGD 1f283a067 P4D 1f283a067 PUD 1f283c067 PMD 0
> Oops: 0000 [#1] PREEMPT SMP NOPTI
> RIP: 0010:complete_all+0x3e/0xa0
> [...]
> Call Trace:
>   <TASK>
>   ? __die_body+0x68/0xb0
>   ? page_fault_oops+0x379/0x3e0
>   ? exc_page_fault+0x69/0xa0
>   ? asm_exc_page_fault+0x22/0x30
>   ? complete_all+0x3e/0xa0
>   fsm_main_thread+0xa3/0x9c0 [mtk_t7xx (HASH:1400 5)]
>   ? __pfx_autoremove_wake_function+0x10/0x10
>   kthread+0xd8/0x110
>   ? __pfx_fsm_main_thread+0x10/0x10 [mtk_t7xx (HASH:1400 5)]
>   ? __pfx_kthread+0x10/0x10
>   ret_from_fork+0x38/0x50
>   ? __pfx_kthread+0x10/0x10
>   ret_from_fork_asm+0x1b/0x30
>   </TASK>
> [...]
> CR2: fffffffffffffff8
> ---[ end trace 0000000000000000 ]---
> 
> After the main thread determines that the task has timed out, mark
> the completion invalid, and add judgment in the asynchronous task.
> 
> Signed-off-by: Jinjian Song <jinjian.song at fibocom.com>
> ---
>   drivers/net/wwan/t7xx/t7xx_state_monitor.c | 7 +++++--
>   1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
> index 3931c7a13f5a..57f1a7730fff 100644
> --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
> +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
> @@ -108,7 +108,8 @@ static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command
>   {
>   	if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
>   		*cmd->ret = result;
> -		complete_all(cmd->done);
> +		if (cmd->done)
> +			complete_all(cmd->done);
>   	}
>   
>   	kfree(cmd);
> @@ -503,8 +504,10 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id
>   
>   		wait_ret = wait_for_completion_timeout(&done,
>   						       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
> -		if (!wait_ret)
> +		if (!wait_ret) {
> +			cmd->done = NULL;
>   			return -ETIMEDOUT;
> +		}
>   
>   		return ret;
>   	}

If this is a fix then should be targeted to net and not net-next
and probably should have Fixes: tag.


From krzk at kernel.org  Thu Dec 12 03:02:44 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 12:02:44 +0100
Subject: [PATCH 1/2] memory/mediatek: Add an interface to get current DDR
 data rate
In-Reply-To: <20241212090029.13692-2-crystal.guo@mediatek.com>
References: <20241212090029.13692-1-crystal.guo@mediatek.com>
 <20241212090029.13692-2-crystal.guo@mediatek.com>
Message-ID: <a2288f77-0178-4769-8bf3-662c82b8b4e3@kernel.org>

On 12/12/2024 09:59, Crystal Guo wrote:
> Add MediaTek DRAMC driver to provide an interface that can
> obtain current DDR data rate.
> 
> Signed-off-by: Crystal Guo <crystal.guo at mediatek.com>
> ---
>  drivers/memory/Kconfig                 |   1 +
>  drivers/memory/Makefile                |   1 +
>  drivers/memory/mediatek/Kconfig        |  21 ++
>  drivers/memory/mediatek/Makefile       |   2 +
>  drivers/memory/mediatek/mtk-dramc.c    | 325 +++++++++++++++++++++++++
>  include/linux/soc/mediatek/mtk-dramc.h |  41 ++++
>  6 files changed, 391 insertions(+)
>  create mode 100644 drivers/memory/mediatek/Kconfig
>  create mode 100644 drivers/memory/mediatek/Makefile
>  create mode 100644 drivers/memory/mediatek/mtk-dramc.c
>  create mode 100644 include/linux/soc/mediatek/mtk-dramc.h
> 
> diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
> index c82d8d8a16ea..b1698549ff81 100644
> --- a/drivers/memory/Kconfig
> +++ b/drivers/memory/Kconfig
> @@ -227,5 +227,6 @@ config STM32_FMC2_EBI
>  
>  source "drivers/memory/samsung/Kconfig"
>  source "drivers/memory/tegra/Kconfig"
> +source "drivers/memory/mediatek/Kconfig"
>  
>  endif
> diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
> index d2e6ca9abbe0..cf1091449d2e 100644
> --- a/drivers/memory/Makefile
> +++ b/drivers/memory/Makefile
> @@ -27,6 +27,7 @@ obj-$(CONFIG_STM32_FMC2_EBI)	+= stm32-fmc2-ebi.o
>  
>  obj-$(CONFIG_SAMSUNG_MC)	+= samsung/
>  obj-$(CONFIG_TEGRA_MC)		+= tegra/
> +obj-$(CONFIG_HAVE_MTK_MC)	+= mediatek/

What is HAVE? Why this is not just MTK_MC or ARCH_MEDIATEK?

>  obj-$(CONFIG_TI_EMIF_SRAM)	+= ti-emif-sram.o
>  obj-$(CONFIG_FPGA_DFL_EMIF)	+= dfl-emif.o
>  
> diff --git a/drivers/memory/mediatek/Kconfig b/drivers/memory/mediatek/Kconfig
> new file mode 100644
> index 000000000000..00764cdb157e
> --- /dev/null
> +++ b/drivers/memory/mediatek/Kconfig
> @@ -0,0 +1,21 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +config HAVE_MTK_MC
> +	bool "MediaTek Memory Controller support"
> +	help
> +	  This option allows to enable MediaTek memory controller drivers,
> +	  which may include controllers for DRAM or others.
> +	  Select Y here if you need support for MediaTek memory controller.
> +	  If you don't need, select N.
> +
> +if HAVE_MTK_MC
> +
> +config MTK_DRAMC
> +	tristate "MediaTek DRAMC driver"
> +	depends on HAVE_MTK_MC

Feels useless, isn't it part of if?

> +	help
> +	  This option selects the MediaTek DRAMC driver, which provides
> +	  an interface for reporting the current data rate of DRAM.
> +	  Select Y here if you need support for the MediaTek DRAMC driver.
> +	  If you don't need, select N.
> +
> +endif
> diff --git a/drivers/memory/mediatek/Makefile b/drivers/memory/mediatek/Makefile
> new file mode 100644
> index 000000000000..a1395fc55b41
> --- /dev/null
> +++ b/drivers/memory/mediatek/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +obj-$(CONFIG_MTK_DRAMC)		+= mtk-dramc.o
> diff --git a/drivers/memory/mediatek/mtk-dramc.c b/drivers/memory/mediatek/mtk-dramc.c
> new file mode 100644
> index 000000000000..9c2c8e187a4a
> --- /dev/null
> +++ b/drivers/memory/mediatek/mtk-dramc.c
> @@ -0,0 +1,325 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2024 MediaTek Inc.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/printk.h>
> +#include <linux/io.h>
> +#include <linux/soc/mediatek/mtk-dramc.h>
> +
> +static struct platform_device *dramc_pdev;
> +static struct platform_driver dramc_drv;

Drop both. Don't write singleton code.

...

> +		if (!(dramc_dev_ptr->fmeter_dev_ptr)) {
> +			pr_info("%s: memory  alloc fail\n", __func__);
> +			return -ENOMEM;
> +		}
> +		ret = fmeter_init(pdev, dramc_dev_ptr->fmeter_dev_ptr, fmeter_version);
> +		if (ret) {
> +			pr_info("%s: fmeter_init fail\n", __func__);
> +			return -EINVAL;
> +		}
> +	} else {
> +		dramc_dev_ptr->fmeter_dev_ptr = NULL;
> +	}
> +	ret = driver_create_file(pdev->dev.driver, &driver_attr_dram_data_rate);
> +	if (ret) {
> +		pr_info("%s: fail to create dram_data_rate sysfs\n", __func__);
> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, dramc_dev_ptr);
> +	pr_info("%s: DRAM data rate = %d\n", __func__,
> +		mtk_dramc_get_data_rate());


This is terible coding style. Driver is in very poor shape.

Please perform extensive internal review in Mediatek to avoid sending
very poor quality contributions. This uses community resources in unfair
way. Few more comments, but all this code needs extensive rework and I
am not going to explain you basics of Linux Coding style, if you do not
want to take existing code as learning examples. Work with your
collegagues on that.


> +
> +	return ret;
> +}
> +
> +static unsigned int fmeter_v1(struct dramc_dev_t *dramc_dev_ptr)
> +{
> +	struct fmeter_dev_t *fmeter_dev_ptr =
> +		(struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr;
> +	unsigned int shu_lv_val;
> +	unsigned int pll_id_val;
> +	unsigned int sdmpcw_val;
> +	unsigned int posdiv_val;
> +	unsigned int ckdiv4_val;
> +	unsigned int offset;
> +	unsigned int vco_freq;
> +	unsigned int fbksel;
> +	unsigned int dqsopen;
> +	unsigned int async_ca;
> +	unsigned int dq_ser_mode;
> +
> +	shu_lv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] +
> +		fmeter_dev_ptr->shu_lv.offset) &
> +		fmeter_dev_ptr->shu_lv.mask) >>
> +		fmeter_dev_ptr->shu_lv.shift;
> +
> +	pll_id_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] +
> +		fmeter_dev_ptr->pll_id.offset) &
> +		fmeter_dev_ptr->pll_id.mask) >>
> +		fmeter_dev_ptr->pll_id.shift;
> +
> +	offset = fmeter_dev_ptr->sdmpcw[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	sdmpcw_val = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->sdmpcw[pll_id_val].mask) >>
> +		fmeter_dev_ptr->sdmpcw[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->posdiv[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	posdiv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->posdiv[pll_id_val].mask) >>
> +		fmeter_dev_ptr->posdiv[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->fbksel[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	fbksel = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->fbksel[pll_id_val].mask) >>
> +		fmeter_dev_ptr->fbksel[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->dqsopen[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	dqsopen = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->dqsopen[pll_id_val].mask) >>
> +		fmeter_dev_ptr->dqsopen[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->async_ca[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	async_ca = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->async_ca[pll_id_val].mask) >>
> +		fmeter_dev_ptr->async_ca[pll_id_val].shift;
> +
> +	offset = fmeter_dev_ptr->dq_ser_mode[pll_id_val].offset +
> +		fmeter_dev_ptr->shu_of * shu_lv_val;
> +	dq_ser_mode = (readl(dramc_dev_ptr->ddrphy_chn_base_nao[0] + offset) &
> +		fmeter_dev_ptr->dq_ser_mode[pll_id_val].mask) >>
> +		fmeter_dev_ptr->dq_ser_mode[pll_id_val].shift;
> +	ckdiv4_val = (dq_ser_mode == 1); // 1: DIV4, 2: DIV8, 3: DIV16
> +
> +	posdiv_val &= ~(0x4);
> +
> +	vco_freq = ((fmeter_dev_ptr->crystal_freq) *
> +		(sdmpcw_val >> 7)) >> posdiv_val >> 1 >> ckdiv4_val
> +		<< fbksel;
> +
> +	if ((dqsopen == 1) && (async_ca == 1))
> +		vco_freq >>= 1;
> +
> +	return vco_freq;
> +}
> +
> +/*
> + * mtk_dramc_get_data_rate - calculate DRAM data rate
> + *
> + * Returns DRAM data rate (MB/s)
> + */
> +unsigned int mtk_dramc_get_data_rate(void)
> +{
> +	struct dramc_dev_t *dramc_dev_ptr;
> +	struct fmeter_dev_t *fmeter_dev_ptr;
> +
> +	if (!dramc_pdev)
> +		return 0;
> +
> +	dramc_dev_ptr =
> +		(struct dramc_dev_t *)platform_get_drvdata(dramc_pdev);
> +
> +	fmeter_dev_ptr = (struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr;
> +	if (!fmeter_dev_ptr)
> +		return 0;
> +
> +	if (fmeter_dev_ptr->version == 1)
> +		return fmeter_v1(dramc_dev_ptr);
> +	return 0;
> +}
> +EXPORT_SYMBOL(mtk_dramc_get_data_rate);

NAK, not used.

> +
> +static int dramc_remove(struct platform_device *pdev)
> +{
> +	dramc_pdev = NULL;
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id dramc_of_ids[] = {
> +	{.compatible = "mediatek,common-dramc",},
> +	{}
> +};
> +
> +static struct platform_driver dramc_drv = {
> +	.probe = dramc_probe,
> +	.remove = dramc_remove,
> +	.driver = {
> +		.name = "dramc_drv",
> +		.owner = THIS_MODULE,

NAK. You sent us 10 year old code, which means you replicated all the
bugs, issues and old-coding styles existing 10 years ago.

Start *FROM SCRATCH* from the newest driver, so you won't send us same
junk we already fixed during last 10 years.


> +		.of_match_table = dramc_of_ids,
> +	},
> +};
> +
> +static int __init dramc_drv_init(void)
> +{
> +	int ret;
> +
> +	ret = platform_driver_register(&dramc_drv);
> +	if (ret) {
> +		pr_info("%s: init fail, ret 0x%x\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +module_init(dramc_drv_init);

No, just module_platform_driver

> +
> +MODULE_AUTHOR("Mediatek Corporation");
> +MODULE_DESCRIPTION("MediaTek DRAMC Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/soc/mediatek/mtk-dramc.h b/include/linux/soc/mediatek/mtk-dramc.h
> new file mode 100644
> index 000000000000..95e7dbfe7d0e
> --- /dev/null
> +++ b/include/linux/soc/mediatek/mtk-dramc.h

Move everything into driver.

> @@ -0,0 +1,41 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019 MediaTek Inc.
> + */
> +
> +#ifndef __MTK_DRAMC_H__
> +#define __MTK_DRAMC_H__
> +
> +struct reg_ctrl_t {
> +	unsigned int offset;
> +	unsigned int mask;
> +	unsigned int shift;
> +};
> +
> +struct fmeter_dev_t {
> +	unsigned int version;
> +	unsigned int crystal_freq;
> +	unsigned int shu_of;
> +	struct reg_ctrl_t shu_lv;
> +	struct reg_ctrl_t pll_id;
> +	struct reg_ctrl_t sdmpcw[2];
> +	struct reg_ctrl_t posdiv[2];
> +	struct reg_ctrl_t fbksel[2];
> +	struct reg_ctrl_t dqsopen[2];
> +	struct reg_ctrl_t async_ca[2];
> +	struct reg_ctrl_t dq_ser_mode[2];
> +};
> +
> +struct dramc_dev_t {
> +	unsigned int support_ch_cnt;
> +	void __iomem **dramc_chn_base_ao;
> +	void __iomem **dramc_chn_base_nao;
> +	void __iomem **ddrphy_chn_base_ao;
> +	void __iomem **ddrphy_chn_base_nao;
> +	void __iomem *sleep_base;
> +	void *fmeter_dev_ptr;
> +};
> +
> +unsigned int mtk_dramc_get_data_rate(void);


Drop, unused.

> +
> +#endif /* __MTK_DRAMC_H__ */


Best regards,
Krzysztof


From christian.loehle at arm.com  Thu Dec 12 03:06:09 2024
From: christian.loehle at arm.com (Christian Loehle)
Date: Thu, 12 Dec 2024 11:06:09 +0000
Subject: [PATCH v2 6/7] cpufreq: apple-soc: Set fallback transition
 latency to APPLE_DVFS_TRANSITION_TIMEOUT
In-Reply-To: <20241212070344.3858-7-towinchenmi@gmail.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
 <20241212070344.3858-7-towinchenmi@gmail.com>
Message-ID: <df140f26-496d-44ce-8363-ffc908f2effa@arm.com>

On 12/12/24 07:03, Nick Chan wrote:
> The driver already assumes transitions will not take longer than
> APPLE_DVFS_TRANSITION_TIMEOUT in apple_soc_cpufreq_set_target(), so it
> makes little sense to set CPUFREQ_ETERNAL as the transition latency
> when the transistion latency is not given by the opp-table.
> 
> Signed-off-by: Nick Chan <towinchenmi at gmail.com>

Reviewed-by: Christian Loehle <christian.loehle at arm.com>

> ---
>  drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
> index 94e57f055a5f..c9f31a3653e2 100644
> --- a/drivers/cpufreq/apple-soc-cpufreq.c
> +++ b/drivers/cpufreq/apple-soc-cpufreq.c
> @@ -291,7 +291,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy)
>  
>  	transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
>  	if (!transition_latency)
> -		transition_latency = CPUFREQ_ETERNAL;
> +		transition_latency = APPLE_DVFS_TRANSITION_TIMEOUT * 1000;
>  
>  	policy->cpuinfo.transition_latency = transition_latency;
>  	policy->dvfs_possible_from_any_cpu = true;



From christian.loehle at arm.com  Thu Dec 12 03:08:57 2024
From: christian.loehle at arm.com (Christian Loehle)
Date: Thu, 12 Dec 2024 11:08:57 +0000
Subject: [PATCH v2 6/7] cpufreq: apple-soc: Set fallback transition
 latency to APPLE_DVFS_TRANSITION_TIMEOUT
In-Reply-To: <df140f26-496d-44ce-8363-ffc908f2effa@arm.com>
References: <20241212070344.3858-1-towinchenmi@gmail.com>
 <20241212070344.3858-7-towinchenmi@gmail.com>
 <df140f26-496d-44ce-8363-ffc908f2effa@arm.com>
Message-ID: <2d262f80-81cf-4957-8d4d-ccb5f45e5d75@arm.com>

On 12/12/24 11:06, Christian Loehle wrote:
> On 12/12/24 07:03, Nick Chan wrote:
>> The driver already assumes transitions will not take longer than
>> APPLE_DVFS_TRANSITION_TIMEOUT in apple_soc_cpufreq_set_target(), so it
>> makes little sense to set CPUFREQ_ETERNAL as the transition latency
>> when the transistion latency is not given by the opp-table.
>>
>> Signed-off-by: Nick Chan <towinchenmi at gmail.com>
> 
> Reviewed-by: Christian Loehle <christian.loehle at arm.com>
> 
>> ---
>>  drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
>> index 94e57f055a5f..c9f31a3653e2 100644
>> --- a/drivers/cpufreq/apple-soc-cpufreq.c
>> +++ b/drivers/cpufreq/apple-soc-cpufreq.c
>> @@ -291,7 +291,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy)
>>  
>>  	transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
>>  	if (!transition_latency)
>> -		transition_latency = CPUFREQ_ETERNAL;
>> +		transition_latency = APPLE_DVFS_TRANSITION_TIMEOUT * 1000;

s/1000/NSEC_PER_USEC would have been the cleaner choice in case you respin.

>>  
>>  	policy->cpuinfo.transition_latency = transition_latency;
>>  	policy->dvfs_possible_from_any_cpu = true;
> 
> 



From laurentiumihalcea111 at gmail.com  Thu Dec 12 03:11:29 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Thu, 12 Dec 2024 13:11:29 +0200
Subject: [PATCH v2 4/5] ASoC: SOF: imx: add driver for imx95
In-Reply-To: <ZzUJQCeWclsrr/lr@lizhi-Precision-Tower-5810>
References: <20241113195240.3699-1-laurentiumihalcea111@gmail.com>
 <20241113195240.3699-5-laurentiumihalcea111@gmail.com>
 <ZzUJQCeWclsrr/lr@lizhi-Precision-Tower-5810>
Message-ID: <c47710a5-7e53-48b1-bd6b-c0123865aee5@gmail.com>



On 11/13/2024 10:17 PM, Frank Li wrote:
> On Wed, Nov 13, 2024 at 02:52:39PM -0500, Laurentiu Mihalcea wrote:
>> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>>
>> Add SOF driver for imx95.
>>
>> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>> ---
>>  sound/soc/sof/imx/Kconfig  |   8 +
>>  sound/soc/sof/imx/Makefile |   2 +
>>  sound/soc/sof/imx/imx95.c  | 401 +++++++++++++++++++++++++++++++++++++
> why not reused exist one? look likes simular.
>
> Frank
the SOF drivers do indeed have some similarities, but each of them has their own quirks which IMO makes it a bit harder to add the 95 support. We need to figure out the common parts and then move them to imx-common, but I believe this can be solved incrementally.
>
>>  3 files changed, 411 insertions(+)
>>  create mode 100644 sound/soc/sof/imx/imx95.c
>>
>> diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig
>> index 4751b04d5e6f..51a70a193533 100644
>> --- a/sound/soc/sof/imx/Kconfig
>> +++ b/sound/soc/sof/imx/Kconfig
>> @@ -50,4 +50,12 @@ config SND_SOC_SOF_IMX8ULP
>>  	  Say Y if you have such a device.
>>  	  If unsure select "N".
>>
>> +config SND_SOC_SOF_IMX95
>> +	tristate "SOF support for i.MX95"
>> +	depends on IMX_DSP
>> +	help
>> +	  This adds support for Sound Open Firmware for NXP i.MX95 platforms.
>> +	  Say Y if you have such a device.
>> +	  If unsure select "N".
>> +
>>  endif ## SND_SOC_SOF_IMX_TOPLEVEL
>> diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile
>> index be0bf0736dfa..715ac3798668 100644
>> --- a/sound/soc/sof/imx/Makefile
>> +++ b/sound/soc/sof/imx/Makefile
>> @@ -2,10 +2,12 @@
>>  snd-sof-imx8-y := imx8.o
>>  snd-sof-imx8m-y := imx8m.o
>>  snd-sof-imx8ulp-y := imx8ulp.o
>> +snd-sof-imx95-y := imx95.o
>>
>>  snd-sof-imx-common-y := imx-common.o
>>
>>  obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o
>>  obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o
>>  obj-$(CONFIG_SND_SOC_SOF_IMX8ULP) += snd-sof-imx8ulp.o
>> +obj-$(CONFIG_SND_SOC_SOF_IMX95) += snd-sof-imx95.o
>>  obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o
>> diff --git a/sound/soc/sof/imx/imx95.c b/sound/soc/sof/imx/imx95.c
>> new file mode 100644
>> index 000000000000..5a0e44f5bd48
>> --- /dev/null
>> +++ b/sound/soc/sof/imx/imx95.c
>> @@ -0,0 +1,401 @@
>> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
>> +/*
>> + * Copyright 2024 NXP
>> + */
>> +
>> +#include <linux/arm-smccc.h>
>> +#include <linux/clk.h>
>> +#include <linux/firmware/imx/dsp.h>
>> +#include <linux/module.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/of_reserved_mem.h>
>> +#include <sound/sof.h>
>> +
>> +#include "../sof-of-dev.h"
>> +#include "../ops.h"
>> +
>> +#define IMX_SIP_SRC 0xC2000005
>> +#define IMX_SIP_SRC_M_RESET_ADDR_SET 0x03
>> +
>> +#define IMX95_CPU_VEC_FLAGS_BOOT BIT(29)
>> +
>> +#define IMX_SIP_LMM 0xC200000F
>> +#define IMX_SIP_LMM_BOOT 0x0
>> +#define IMX_SIP_LMM_SHUTDOWN 0x1
>> +
>> +#define IMX95_M7_LM_ID 0x1
>> +
>> +#define MBOX_DSPBOX_OFFSET 0x1000
>> +#define MBOX_WINDOW_OFFSET 0x6000000
>> +
>> +struct imx95_priv {
>> +	struct platform_device *ipc_dev;
>> +	struct imx_dsp_ipc *ipc_handle;
>> +	resource_size_t bootaddr;
>> +};
>> +
>> +static void imx95_ipc_handle_reply(struct imx_dsp_ipc *ipc)
>> +{
>> +	unsigned long flags;
>> +	struct snd_sof_dev *sdev = imx_dsp_get_data(ipc);
>> +
>> +	spin_lock_irqsave(&sdev->ipc_lock, flags);
>> +	snd_sof_ipc_process_reply(sdev, 0);
>> +	spin_unlock_irqrestore(&sdev->ipc_lock, flags);
>> +}
>> +
>> +static void imx95_ipc_handle_request(struct imx_dsp_ipc *ipc)
>> +{
>> +	snd_sof_ipc_msgs_rx(imx_dsp_get_data(ipc));
>> +}
>> +
>> +static struct imx_dsp_ops ipc_ops = {
>> +	.handle_reply = imx95_ipc_handle_reply,
>> +	.handle_request = imx95_ipc_handle_request,
>> +};
>> +
>> +static int imx95_disable_enable_core(bool enable)
>> +{
>> +	struct arm_smccc_res res;
>> +
>> +	if (enable)
>> +		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_BOOT, IMX95_M7_LM_ID,
>> +			      0, 0, 0, 0, 0, &res);
>> +	else
>> +		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_SHUTDOWN, IMX95_M7_LM_ID,
>> +			      0, 0, 0, 0, 0, &res);
>> +
>> +	return res.a0;
>> +}
>> +
>> +static int imx95_run(struct snd_sof_dev *sdev)
>> +{
>> +	return imx95_disable_enable_core(true);
>> +}
>> +
>> +static int imx95_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
>> +{
>> +	struct imx95_priv *priv = sdev->pdata->hw_pdata;
>> +
>> +	sof_mailbox_write(sdev, sdev->host_box.offset,
>> +			  msg->msg_data, msg->msg_size);
>> +
>> +	imx_dsp_ring_doorbell(priv->ipc_handle, 0);
>> +
>> +	return 0;
>> +}
>> +
>> +static int imx95_get_mailbox_offset(struct snd_sof_dev *sdev)
>> +{
>> +	return MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
>> +}
>> +
>> +static int imx95_get_bar_index(struct snd_sof_dev *sdev, u32 type)
>> +{
>> +	switch (type) {
>> +	case SOF_FW_BLK_TYPE_SRAM:
>> +		return type;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +}
>> +
>> +static int imx95_get_window_offset(struct snd_sof_dev *sdev, u32 id)
>> +{
>> +	return MBOX_WINDOW_OFFSET;
>> +}
>> +
>> +static int imx95_set_power_state(struct snd_sof_dev *sdev,
>> +				 const struct sof_dsp_power_state *target_state)
>> +{
>> +	sdev->dsp_power_state = *target_state;
>> +
>> +	return 0;
>> +}
>> +
>> +static int imx95_suspend_resume(struct snd_sof_dev *sdev, bool suspend)
>> +{
>> +	struct imx95_priv *priv;
>> +	int ret, i;
>> +
>> +	priv = sdev->pdata->hw_pdata;
>> +
>> +	if (suspend) {
>> +		ret = imx95_disable_enable_core(false);
>> +		if (ret) {
>> +			dev_err(sdev->dev, "failed to stop core\n");
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
>> +		if (suspend)
>> +			imx_dsp_free_channel(priv->ipc_handle, i);
>> +		else
>> +			imx_dsp_request_channel(priv->ipc_handle, i);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int imx95_runtime_resume(struct snd_sof_dev *sdev)
>> +{
>> +	int ret;
>> +	const struct sof_dsp_power_state target_state = {
>> +		.state = SOF_DSP_PM_D0,
>> +	};
>> +
>> +	ret = imx95_suspend_resume(sdev, false);
>> +	if (ret < 0) {
>> +		dev_err(sdev->dev, "failed to runtime resume: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
>> +}
>> +
>> +static int imx95_resume(struct snd_sof_dev *sdev)
>> +{
>> +	int ret;
>> +	const struct sof_dsp_power_state target_state = {
>> +		.state = SOF_DSP_PM_D0,
>> +	};
>> +
>> +	ret = imx95_suspend_resume(sdev, false);
>> +	if (ret < 0) {
>> +		dev_err(sdev->dev, "failed to resume: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	if (pm_runtime_suspended(sdev->dev)) {
>> +		pm_runtime_disable(sdev->dev);
>> +		pm_runtime_set_active(sdev->dev);
>> +		pm_runtime_mark_last_busy(sdev->dev);
>> +		pm_runtime_enable(sdev->dev);
>> +		pm_runtime_idle(sdev->dev);
>> +	}
>> +
>> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
>> +}
>> +
>> +static int imx95_runtime_suspend(struct snd_sof_dev *sdev)
>> +{
>> +	int ret;
>> +	const struct sof_dsp_power_state target_state = {
>> +		.state = SOF_DSP_PM_D3,
>> +	};
>> +
>> +	ret = imx95_suspend_resume(sdev, true);
>> +	if (ret < 0) {
>> +		dev_err(sdev->dev, "failed to runtime suspend: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
>> +}
>> +
>> +static int imx95_suspend(struct snd_sof_dev *sdev, unsigned int target_state)
>> +{
>> +	int ret;
>> +	const struct sof_dsp_power_state target_power_state = {
>> +		.state = target_state,
>> +	};
>> +
>> +	if (!pm_runtime_suspended(sdev->dev)) {
>> +		ret = imx95_suspend_resume(sdev, true);
>> +		if (ret < 0) {
>> +			dev_err(sdev->dev, "failed to suspend: %d\n", ret);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	return snd_sof_dsp_set_power_state(sdev, &target_power_state);
>> +}
>> +
>> +static struct snd_soc_dai_driver imx95_dai[] = {
>> +	{
>> +		.name = "sai3",
>> +		.playback = {
>> +			.channels_min = 1,
>> +			.channels_max = 32,
>> +		},
>> +		.capture = {
>> +			.channels_min = 1,
>> +			.channels_max = 32,
>> +		},
>> +	},
>> +};
>> +
>> +static int imx95_probe(struct snd_sof_dev *sdev)
>> +{
>> +	struct platform_device *pdev;
>> +	struct imx95_priv *priv;
>> +	struct resource *res;
>> +	struct arm_smccc_res smc_ret;
>> +	int ret;
>> +
>> +	pdev = container_of(sdev->dev, struct platform_device, dev);
>> +
>> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>> +	if (!priv)
>> +		return dev_err_probe(&pdev->dev, -ENOMEM, "failed to alloc priv\n");
>> +
>> +	sdev->pdata->hw_pdata = priv;
>> +
>> +	/* map SRAM */
>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +	if (!res)
>> +		return dev_err_probe(&pdev->dev, -ENODEV,
>> +				     "failed to fetch SRAM region\n");
>> +
>> +	sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap(&pdev->dev, res->start,
>> +						       resource_size(res));
>> +	if (IS_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]))
>> +		return dev_err_probe(&pdev->dev,
>> +				     PTR_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]),
>> +				     "failed to map SRAM region\n");
>> +
>> +	sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
>> +	sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
>> +	sdev->dsp_box.offset = MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
>> +	priv->bootaddr = res->start;
>> +
>> +	ret = of_reserved_mem_device_init(sdev->dev);
>> +	if (ret)
>> +		return dev_err_probe(&pdev->dev, ret,
>> +				     "failed to bind DMA region\n");
>> +
>> +	priv->ipc_dev = platform_device_register_data(&pdev->dev, "imx-dsp",
>> +						      PLATFORM_DEVID_NONE,
>> +						      pdev, sizeof(*pdev));
>> +	if (IS_ERR(priv->ipc_dev))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->ipc_dev),
>> +				     "failed to create IPC device\n");
>> +
>> +	priv->ipc_handle = dev_get_drvdata(&priv->ipc_dev->dev);
>> +	if (!priv->ipc_handle) {
>> +		ret = -EPROBE_DEFER;
>> +		dev_err(&pdev->dev, "failed to fetch ipc handle\n");
>> +		goto err_unregister_ipc_dev;
>> +	}
>> +
>> +	priv->ipc_handle->ops = &ipc_ops;
>> +	imx_dsp_set_data(priv->ipc_handle, sdev);
>> +
>> +	/* set core boot reset address */
>> +	arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M_RESET_ADDR_SET, priv->bootaddr,
>> +		      IMX95_CPU_VEC_FLAGS_BOOT, 0, 0, 0, 0, &smc_ret);
>> +	if ((int)smc_ret.a0 < 0) {
>> +		ret = smc_ret.a0;
>> +		dev_err(&pdev->dev, "failed to set boot address: %d", ret);
>> +		goto err_unregister_ipc_dev;
>> +	}
>> +
>> +	return 0;
>> +
>> +err_unregister_ipc_dev:
>> +	platform_device_unregister(priv->ipc_dev);
>> +
>> +	return ret;
>> +}
>> +
>> +static void imx95_remove(struct snd_sof_dev *sdev)
>> +{
>> +	struct imx95_priv *priv;
>> +
>> +	priv = sdev->pdata->hw_pdata;
>> +
>> +	if (imx95_disable_enable_core(false))
>> +		dev_err(sdev->dev, "failed to stop core\n");
>> +
>> +	platform_device_unregister(priv->ipc_dev);
>> +}
>> +
>> +static const struct snd_sof_dsp_ops sof_imx95_ops = {
>> +	.probe = imx95_probe,
>> +	.remove = imx95_remove,
>> +
>> +	/* mandatory "DSP" ops */
>> +	.run = imx95_run,
>> +	.block_read = sof_block_read,
>> +	.block_write = sof_block_write,
>> +	.send_msg = imx95_send_msg,
>> +	.load_firmware = snd_sof_load_firmware_memcpy,
>> +	.ipc_msg_data = sof_ipc_msg_data,
>> +
>> +	.mailbox_read = sof_mailbox_read,
>> +	.mailbox_write = sof_mailbox_write,
>> +
>> +	.get_mailbox_offset = imx95_get_mailbox_offset,
>> +	.get_bar_index = imx95_get_bar_index,
>> +	.get_window_offset = imx95_get_window_offset,
>> +
>> +	.pcm_open = sof_stream_pcm_open,
>> +	.pcm_close = sof_stream_pcm_close,
>> +	.set_stream_data_offset = sof_set_stream_data_offset,
>> +
>> +	.runtime_suspend = imx95_runtime_suspend,
>> +	.runtime_resume = imx95_runtime_resume,
>> +
>> +	.resume = imx95_resume,
>> +	.suspend = imx95_suspend,
>> +
>> +	.set_power_state = imx95_set_power_state,
>> +
>> +	.drv = imx95_dai,
>> +	.num_drv = ARRAY_SIZE(imx95_dai),
>> +
>> +	.hw_info = SNDRV_PCM_INFO_MMAP |
>> +		   SNDRV_PCM_INFO_MMAP_VALID |
>> +		   SNDRV_PCM_INFO_INTERLEAVED |
>> +		   SNDRV_PCM_INFO_PAUSE |
>> +		   SNDRV_PCM_INFO_BATCH |
>> +		   SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
>> +};
>> +
>> +static struct snd_sof_of_mach sof_imx95_machs[] = {
>> +	{
>> +		.compatible = "fsl,imx95-19x19-evk",
>> +		.sof_tplg_filename = "sof-imx95-wm8962.tplg",
>> +		.drv_name = "asoc-audio-graph-card2",
>> +	},
>> +	{
>> +	},
>> +};
>> +
>> +static struct sof_dev_desc sof_of_imx95_desc = {
>> +	.of_machines = sof_imx95_machs,
>> +	.ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
>> +	.ipc_default = SOF_IPC_TYPE_3,
>> +	.default_fw_path = {
>> +		[SOF_IPC_TYPE_3] = "imx/sof",
>> +	},
>> +	.default_tplg_path = {
>> +		[SOF_IPC_TYPE_3] = "imx/sof-tplg",
>> +	},
>> +	.default_fw_filename = {
>> +		[SOF_IPC_TYPE_3] = "sof-imx95.ri",
>> +	},
>> +	.ops = &sof_imx95_ops,
>> +};
>> +
>> +static const struct of_device_id sof_of_imx95_ids[] = {
>> +	{ .compatible = "fsl,imx95-cm7-sof", .data = &sof_of_imx95_desc },
>> +	{ },
>> +};
>> +MODULE_DEVICE_TABLE(of, sof_of_imx95_ids);
>> +
>> +static struct platform_driver snd_sof_of_imx95_driver = {
>> +	.probe = sof_of_probe,
>> +	.remove = sof_of_remove,
>> +	.driver = {
>> +		.name = "sof-audio-of-imx95",
>> +		.pm = &sof_of_pm,
>> +		.of_match_table = sof_of_imx95_ids,
>> +	},
>> +};
>> +module_platform_driver(snd_sof_of_imx95_driver);
>> +
>> +MODULE_LICENSE("Dual BSD/GPL");
>> +MODULE_DESCRIPTION("SOF support for i.MX95 platforms");
>> +MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>");
>> --
>> 2.34.1
>>



From Jason-JH.Lin at mediatek.com  Thu Dec 12 03:24:47 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Thu, 12 Dec 2024 11:24:47 +0000
Subject: [PATCH v2 1/8] dt-bindings: mailbox: mediatek: Add GCE header
 file for MT8196
In-Reply-To: <e9caf0fe-a77f-40cb-9fc3-9da3d95f27ca@kernel.org>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
	 <20241211032256.28494-2-jason-jh.lin@mediatek.com>
	 <ozifi65uycmxc5hqeu4onbths5u7dg532iufjxplsjw4jjmhf6@6bdsaabd7hl7>
	 <04f7bd2a7d69ab7d02c88cf05bda5ae0c4cb6573.camel@mediatek.com>
	 <e9caf0fe-a77f-40cb-9fc3-9da3d95f27ca@kernel.org>
Message-ID: <ce68d58f78d12317cab689e0ee1c02dc373d50dc.camel@mediatek.com>

On Thu, 2024-12-12 at 08:20 +0100, Krzysztof Kozlowski wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On 12/12/2024 04:05, Jason-JH Lin (???) wrote:
> > Hi Krzysztof,
> > 
> > Thanks for the reviews.
> > 
> > On Wed, 2024-12-11 at 10:37 +0100, Krzysztof Kozlowski wrote:
> > > External email : Please do not click links or open attachments
> > > until
> > > you have verified the sender or the content.
> > > 
> > > 
> > > On Wed, Dec 11, 2024 at 11:22:49AM +0800, Jason-JH.Lin wrote:
> > > > Add the Global Command Engine (GCE) header file to define the
> > > > GCE
> > > > thread priority, GCE subsys ID and GCE events for MT8196.
> > > 
> > > This we see from the diff. What we do not see is why priority is
> > > a
> > > binding. Looking briefly at existing code: it is not a binding,
> > > there
> > > is
> > > no driver user.
> > > 
> > 
> > This priority value is used to configure the priority level for
> > each
> > GCE hardware thread, so it is a necessary hardware attribute.
> 
> I did not say these are not "hardware". I said these are not
> bindings.
> Bring arguments why these are bindings.
> 

Not only bringing arguments, we use it to configure each GCE thread's
priority.

Please forgive me to ask a trivial question.
Do you mean if there is no driver using it directly, then it can not be
a binding?
Or could you give me an example for what should be binding and what
should not be binding?


Considering to these 3 points, I think GCE thread priority is suitable
to be part of the Device Tree Binding:

1. Describing Hardware Properties
- The Device Tree is a data structure for describing hardware, and GCE
thread priority, as part of the hardware, should be described in the
Device Tree.

2. Driver Usage
- Device Tree data is used by drivers to initialize and configure
hardware, and GCE thread priority is necessary configuration data for
the driver. After parsing the mboxes args from DTS, CMDQ driver use it
to configure GCE thread.

3. Standardization
- Device Tree bindings should be standardized, and GCE thread priority
should have consistent meaning and usage across different hardware
platforms. Looking into the latest header: mediatek,mt8188-gce.h,
mediatek,mt6795-gce.h and mt8195-gce.h, they all have defined GCE
thread priority.

> > 
> > It's hard to find where the priority is used in existing driver
> > code
> > because we parsed it from DTS.
> 
> So not a binding.
> 
> > 
> > It is used in all mediaTeks' DTS using the GCE.
> > For example, in mt8195.dts:
> > 
> > vdosys0: syscon at 1c01a000 {
> >     compatible = "mediatek,mt8195-vdosys0", "mediatek,mt8195-
> > mmsys",
> > "syscon";
> >     reg = <0 0x1c01a000 0 0x1000>;
> >     mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
> >     #clock-cells = <1>;
> >     mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0xa000
> > 0x1000>;
> > }
> > 
> > CMDQ driver(mtk-cmdq-mailbox.c) will get the args parsed from
> > mboxes
> > property in cmdq_xlate() and then it will store CMDQ_THR_PRIO_4 to
> > the
> > specific thread structure.
> 
> So not a binding.
> 
> > The user of CMDQ driver will send command to CMDQ driver by
> > cmdq_mbox_send_data(), and this priority setting will be configured
> > to
> > GCE hardware thread.
> 
> And other things there are the same, we do not talk only about this
> one
> thing. I asked last time to drop which is not a binding.
> 
> 

I just reference all the previous mediatek,mtXXXX-gce.h to add the same
binding. Except for the GPR part I added this time, I don't know what
else should be dropped.

> ...
> 
> > > > +
> > > > +/*
> > > > + * GCE General Purpose Register (GPR) support
> > > > + * Leave note for scenario usage here
> > > > + */
> > > > +/* GCE: write mask */
> > > 
> > > That's a definite no-go. Register masks are not bindings.
> > > 
> > 
> > I'm sorry to the confusion.
> > 
> > These defines are the index of GCE General Purpose Register for
> > generating instructions, they are not register masks.
> 
> Index of register is also sounding like register.
> 
> > 
> > The comment "/* GCE: write mask */" is briefly describe that the
> > usage
> > of GCE_GPR_R0 and GCE_GPR_R01 is used to store the register mask
> > when
> > GCE executing the WRITE instruction. And it can also store the
> > register
> > mask of POLL and READ instruction.
> > 
> > I will add more words to make this comment clearer, like this:
> > /*GCE: store the mask of instruction */
> 
> Not sure, because I feel you just avoid doing what is right and keep
> pushing your own narrative. Where is it used in the driver?
> 
> I just looked for "GCE_GPR_R00" - no usage at all. So not a binding.
> 

Currently, GCE_GPR_R15 is used for generating POLL instruction and it
has been defined as a MACRO `#define CMDQ_POLL_ADDR_GPR (15)`
in mtk-cmdq-helper.c.

Others GPRs are not used currently and they can be define as MACRO in
the same way of GCE_GPR_R15, so I can drop these GPR define in the next
version. Perhaps the SoCs in the future has changed the rules of GPR
index, we can add it back and get them from DTS.

Regards,
Jason-JH.Lin

> Best regards,
> Krzysztof

From Jason-JH.Lin at mediatek.com  Thu Dec 12 03:25:01 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Thu, 12 Dec 2024 11:25:01 +0000
Subject: [PATCH v2 2/8] dt-bindings: mailbox: mediatek: Add MT8196 support
 for gce-mailbox
In-Reply-To: <8cf7e03a-7994-4dd5-b496-e00b4827ee22@kernel.org>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
	 <20241211032256.28494-3-jason-jh.lin@mediatek.com>
	 <yhfxpflyumevs66sdwgiiyuablpfxfxw3e7ybrxju7ssicmnu5@truuiuvxlq6e>
	 <64326843358d450c9172f3dea1c85e7422e20430.camel@mediatek.com>
	 <8cf7e03a-7994-4dd5-b496-e00b4827ee22@kernel.org>
Message-ID: <421a353d33b3cb2800fa7ef022553a4f05cb2ca6.camel@mediatek.com>

On Thu, 2024-12-12 at 08:20 +0100, Krzysztof Kozlowski wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On 12/12/2024 04:41, Jason-JH Lin (???) wrote:
> > Hi Krzysztof,
> > 
> > Thanks for the reviews.
> > 
> > On Wed, 2024-12-11 at 10:39 +0100, Krzysztof Kozlowski wrote:
> > > External email : Please do not click links or open attachments
> > > until
> > > you have verified the sender or the content.
> > > 
> > > 
> > > On Wed, Dec 11, 2024 at 11:22:50AM +0800, Jason-JH.Lin wrote:
> > > > Add compatible name and iommus property for MT8196.
> > > > 
> > > > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> > > > ---
> > > >  .../devicetree/bindings/mailbox/mediatek,gce-
> > > > mailbox.yaml     | 4
> > > > ++++
> > > >  1 file changed, 4 insertions(+)
> > > 
> > > Headers are never separate from the bindings patch...
> > 
> > Do you mean I need to merge [PATCH 1/8] and [PATCH 2/8] into 1
> > patch?
> 
> I asked this last time.
> 

Oh, you're right.

Sorry, I missed the last sentence in [PATCH v1 1/8]:
This goes with binding.

I'll merge them at the next version.

Regards,
Jason-JH.Lin

> Best regards,
> Krzysztof

From m.felsch at pengutronix.de  Thu Dec 12 03:31:55 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Thu, 12 Dec 2024 12:31:55 +0100
Subject: [PATCH v2 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <Z1n4h/AxzthB0V9l@lizhi-Precision-Tower-5810>
References: <20241210-imx91tmu-v2-0-5032aad4d88e@nxp.com>
 <20241210-imx91tmu-v2-2-5032aad4d88e@nxp.com>
 <20241211154622.f2jwwrqansk6il3o@pengutronix.de>
 <Z1m+O1UV4HD+7Rr2@lizhi-Precision-Tower-5810>
 <20241211185705.7b5uw26loobibzln@pengutronix.de>
 <Z1n4h/AxzthB0V9l@lizhi-Precision-Tower-5810>
Message-ID: <20241212113155.wfbbmxcrtcefzuha@pengutronix.de>

On 24-12-11, Frank Li wrote:
> On Wed, Dec 11, 2024 at 07:57:05PM +0100, Marco Felsch wrote:
> > On 24-12-11, Frank Li wrote:
> > > On Wed, Dec 11, 2024 at 04:46:22PM +0100, Marco Felsch wrote:
> > > > On 24-12-10, Frank Li wrote:
> > > > > From: Pengfei Li <pengfei.li_1 at nxp.com>
> > > > >
> > > > > Introduce support for the i.MX91 thermal monitoring unit, which features a
> > > > > single sensor for the CPU. The register layout differs from other chips,
> > > > > necessitating the creation of a dedicated file for this.
> > > > >
> > > > > Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
> > > > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > > > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > > > > ---
> > > > > change from v1 to v2
> > > > > - use low case for hexvalue
> > > > > - combine struct imx91_tmu and tmu_sensor
> > > > > - simplify imx91_tmu_start() and imx91_tmu_enable()
> > > > > - use s16 for imx91_tmu_get_temp(), which may negative value
> > > > > - use reverse christmas tree style
> > > > > - use run time pm
> > > > > - use oneshot to sample temp
> > > > > - register thermal zone after hardware init
> > > > > ---
> > > > >  drivers/thermal/Kconfig         |  10 ++
> > > > >  drivers/thermal/Makefile        |   1 +
> > > > >  drivers/thermal/imx91_thermal.c | 265 ++++++++++++++++++++++++++++++++++++++++
> > > > >  3 files changed, 276 insertions(+)
> > > > >
> 
> [...]
> 
> > > > > +	platform_set_drvdata(pdev, tmu);
> > > > > +
> > > > > +	/* disable the monitor during initialization */
> > > > > +	imx91_tmu_enable(tmu, false);
> > > > > +	imx91_tmu_start(tmu, false);
> > > >
> > > > No need to disable it here since both bits (ENABLE and START) are 0
> > > > after a reset.
> > >
> > > Maybe uboot enable it. We can't depend on reset value without really set
> > > hardware reset bit.
> >
> > So the module can't be rested e.g. by disabling module power? Having a
> > dedicated reset mechanism would be much simpler instead of writing each
> > reg-field to the default value.
> 
> Not all module can be power off individual. Normally, it should have sw
> reset bit in controller. but I have not find it in this module.
> 
> >
> > > > > +	ret = imx91_init_from_nvmem_cells(tmu);
> > > > > +	if (ret) {
> > > > > +		writel_relaxed(DEFAULT_TRIM1_CONFIG, tmu->base + TRIM1);
> > > > > +		writel_relaxed(DEFAULT_TRIM2_CONFIG, tmu->base + TRIM2);
> > > > 			^
> > > > Can you please anwer if _relaxed API is sufficient? I don't know why you
> > > > making use of the _relaxed API here anyway. We have only a few MMIO
> > > > accesses here, so why can't we use the writel() instead? This applies to
> > > > the whole driver.
> > >
> > > There are not big difference writel_relaxed() or writel() for this driver.
> > > Just original owner pick one.
> >
> > NACK, the difference is that _relaxed() APIs don't guarantee the order
> > the register access is done.
> 
> It is totally wrong. *_relexed() API can guarantee the register access
> order. Only can't guarantee order with other memory. such as
> 
> 1 writel_related(A, 0)
> 2. x = 3
> 3 writel_related(B, 1)
> 
> Hardware/memory model, require B=1 must be after A=0, but not necessary
> after x=3, that's means (2) x=3 may happen after 3.
> 
> if use writel(), guarantee 1, 2, 3 as order.  Here have not DMA involved.
> So not any impact if (2) after (3).
> 
> Typically, only below case have to use writel().
> 2 (update DMA descritpor), 3 start DMA,
> 
> Additional, writel() also can't guarantee register access is done!!!!
> 
> writel() just means you send a write command to bus. Not guarantee to reach
> target module. typical case is
> 
> writel(A, 0);
> udelay(1);
> writel(A, 1);
> 
> The interval between A=1 and A=0 may less than 1us if timer have not use
> MMIO register. (arm system counter).
> 
> In this driver, the only valuable benefit by using writel() instead of
> writel_relexed() is "short function name".

You're right, I had to check the documentation once again. The _relaxed
API is fine by me, thank you also for the clarification.

> > > > > +	}
> > > > > +
> > > > > +	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
> > > > > +	rate = clk_get_rate(tmu->clk);
> > > > > +	div = (rate / 4000000) - 1;
> > > > > +	if (div > FIELD_GET(DIV_MASK, DIV_MASK))
> > > > 			^
> > > > This misuse the FIELD_GET() API. Instead please add a define e.g. DIV_MAX.
> > >
> > > I don't think so, It avoid define another macro DIV_MAX, which may miss
> > > defined, the related marco should come from one source.
> > >
> > > For example:
> > >
> > > DIV_MASK is GENMASK(23, 16),  DIV_MAX is 256. But if hardware upgrade,
> > > DIV_MASK to GENMASK(24, 16), DIV_MAX is quite easy to forget update it and
> > > hard to find such mis-match when div value < 256.
> >
> > We not talking about "possible" other HW. For now it's just this one and
> > using FIELD_GET() this way is seems odd, at least to me.
> 
> If you look implement of FIELD_GET()
> (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask));, it will be
> reasonable.

I know the implementation and still IMHO it's not the correct usage at
least to me. What's wrong is that a mask doesn't define the possible
values for a reg-field, e.g. GENMASK(1, 0) could allow all values from 0
to 3 but the HW may allow only 0 and 1.

> Hardware IP may update in future, bitwidth of field may expand.

Please see above.

> > > > > +		return -EINVAL;
> > > > 			^
> > > > 		dev_err_probe()
> > > > > +
> > > > > +	/* Set divider value and enable divider */
> > > > > +	writel_relaxed(DIV_EN | FIELD_PREP(DIV_MASK, div), tmu->base + REF_DIV);
> > > > > +
> > > > > +	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
> > > > > +	writel_relaxed(FIELD_PREP(PUDL_MASK, 100U), tmu->base + PUD_ST_CTRL);
> > > > 		^
> > > > You dont need to repeat the default value, so this line can be dropped.
> > > >
> > > > > +
> > > > > +	/*
> > > > > +	 * Set resolution mode
> > > > > +	 * 00b - Conversion time = 0.59325 ms
> > > > > +	 * 01b - Conversion time = 1.10525 ms
> > > > > +	 * 10b - Conversion time = 2.12925 ms
> > > > > +	 * 11b - Conversion time = 4.17725 ms
> > > > > +	 */
> > > > > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x3), tmu->base + CTRL1_CLR);
> > > > > +	writel_relaxed(FIELD_PREP(CTRL1_RES_MASK, 0x1), tmu->base + CTRL1_SET);
> > > >
> > > > Same here, you repeat the module default after reset, so please drop it.
> > > >
> > > > > +	writel_relaxed(CTRL1_MEAS_MODE_MASK, tmu->base + CTRL1_CLR);
> > > > > +	writel_relaxed(FIELD_PREP(CTRL1_MEAS_MODE_MASK, CTRL1_MEAS_MODE_SINGLE),
> > > > > +		       tmu->base + CTRL1_SET);
> > > > > +
> > > > > +	clk_disable_unprepare(tmu->clk);
> > > >
> > > > Drop this, and
> > > >
> > > > > +	pm_runtime_set_suspended(dev);
> > > >
> > > > replace this with: pm_runtime_set_active();
> > >
> > > No big difference, if set_active, we need add Enable TMU here. I can
> > > change to set_active.
> >
> > You don't need to manually disable the clock, it would be done by the
> > runtime-pm.
> 
> Yes, runtime-pm can disable clock, but it need align harware and run time
> state before enable runtime pm.
> 
> There are two options
> 1 disable all hardware resources and pm_runtime_set_suspended()
> 2. enable all hardware resources and set_active()

I know.

> After algned, use runtime pm API to controller it.
> 
> I choose option1, you prefer option 2.

I know this too and I'm fine with it albeit I would like option 2 more
because:
 - based on pm-runtime API only
 - easier to enable autosuspend feature

Regards,
  Marco

> Frank
> >
> > Regards,
> >   Marco
> >
> >
> [...]
> > > > > +
> > > > > +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> > > > > +MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
> > > > > +MODULE_LICENSE("GPL");
> > > > >
> > > > > --
> > > > > 2.34.1
> > > > >
> > > > >
> > >
> 


From broonie at kernel.org  Thu Dec 12 03:33:05 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 12 Dec 2024 11:33:05 +0000
Subject: [PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <20241211224015.GB17836@willie-the-truck>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
 <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>
 <20241210170953.GB16075@willie-the-truck>
 <b859bdcd-7343-4d53-9f3a-f374deca725a@sirena.org.uk>
 <20241211224015.GB17836@willie-the-truck>
Message-ID: <248dea18-bfad-4ec9-9a7d-5c87c7f48c84@sirena.org.uk>

On Wed, Dec 11, 2024 at 10:40:15PM +0000, Will Deacon wrote:
> On Tue, Dec 10, 2024 at 06:43:05PM +0000, Mark Brown wrote:

> > Yes, the issues here are not technical ones.  Though there are some
> > complications -  eg, IIRC the XML doesn't encode the signedness of
> > fields like we do and there's areas where we've deliberately diverged.
> > Given the amount of review I end up having to do of sysreg changes your
> > reasoning is especially apparent to me.  I've passed this feedback on
> > (again).

> One thing we _could_ do is have a tool (in-tree) that takes two copies
> of the sysreg file (i.e. before and after applying a diff) along with a
> copy of the XML and, for the the new fields being added, shows how the
> XML represents those compared to the diff. It should then be relatively
> straightforward to flag the use of an unallocated encoding (like we had
> here) and also things like assigning a field name to a RES0 region.

> So this wouldn't be generating the patches from the XML, but more like
> using the XML as an oracle in a linter.

That'd be useful, yes - unfortunately I think that's still something I
can't work on myself at the moment for the above mentioned non-technical
reasons.
-------------- 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/20241212/467ed514/attachment.sig>

From qperret at google.com  Thu Dec 12 03:33:17 2024
From: qperret at google.com (Quentin Perret)
Date: Thu, 12 Dec 2024 11:33:17 +0000
Subject: [PATCH v3 4/6] arm64/kvm: Avoid invalid physical addresses to
 signal owner updates
In-Reply-To: <20241212081841.2168124-12-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
 <20241212081841.2168124-12-ardb+git@google.com>
Message-ID: <Z1rJ_dMJJzGOmjNs@google.com>

On Thursday 12 Dec 2024 at 09:18:46 (+0100), Ard Biesheuvel wrote:
> @@ -908,6 +892,9 @@ static bool stage2_leaf_mapping_allowed(const struct kvm_pgtable_visit_ctx *ctx,
>  	if (data->force_pte && ctx->level < KVM_PGTABLE_LAST_LEVEL)
>  		return false;
>  
> +	if (data->annotation && ctx->level == KVM_PGTABLE_LAST_LEVEL)
> +		return true;
> +

I don't think it's a problem, but what's the rationale for checking
ctx->level here? The data->force_pte logic should already do this for us
and be somewhat orthogonal to data->annotation, no?

Either way, the patch looks good to me

  Reviewed-by: Quentin Perret <qperret at google.com>

Cheers,
Quentin

>  	return kvm_block_mapping_supported(ctx, phys);
>  }


From phil at zankapfel.net  Thu Dec 12 03:30:14 2024
From: phil at zankapfel.net (Phil Eichinger)
Date: Thu, 12 Dec 2024 12:30:14 +0100
Subject: [PATCH] watchdog: aspeed: replace mdelay with msleep
Message-ID: <20241212113014.1075414-1-phil@zankapfel.net>

Since it is not called in an atomic context the mdelay function
can be replaced with msleep to avoid busy wait.

Signed-off-by: Phil Eichinger <phil at zankapfel.net>
---
 drivers/watchdog/aspeed_wdt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index b4773a6aaf8c..98ef341408f7 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -208,7 +208,7 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
 	wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY;
 	aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000);
 
-	mdelay(1000);
+	msleep(1000);
 
 	return 0;
 }
-- 
2.39.5



From marex at denx.de  Thu Dec 12 03:15:46 2024
From: marex at denx.de (Marek Vasut)
Date: Thu, 12 Dec 2024 12:15:46 +0100
Subject: [PATCH v2] watchdog: stm32_iwdg: fix error message during driver
 probe
In-Reply-To: <20241212102050.374501-1-clement.legoffic@foss.st.com>
References: <20241211163457.301140-1-clement.legoffic@foss.st.com>
 <20241212102050.374501-1-clement.legoffic@foss.st.com>
Message-ID: <51671397-3bf4-40a9-99dc-262517634109@denx.de>

On 12/12/24 11:20 AM, Cl?ment Le Goffic wrote:
> The commit 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
> introduces the support for the pre-timeout interrupt.
> 
> The support for this interrupt is optional but the driver uses the
> platform_get_irq() wich produces an error message during the driver
> probe if we don't have any `interrupts` property in the DT.
> 
> Use the platform_get_irq_optional() API to get rid of the error message
> as this property is optional.
> 
> Fixes: 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
> Signed-off-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
Reviewed-by: Marek Vasut <marex at denx.de>


From maz at kernel.org  Thu Dec 12 03:35:09 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Dec 2024 11:35:09 +0000
Subject: [PATCH v2 17/18] KVM: arm64: Introduce the EL1 pKVM MMU
In-Reply-To: <20241203103735.2267589-18-qperret@google.com>
References: <20241203103735.2267589-1-qperret@google.com>
	<20241203103735.2267589-18-qperret@google.com>
Message-ID: <86jzc5rv6a.wl-maz@kernel.org>

On Tue, 03 Dec 2024 10:37:34 +0000,
Quentin Perret <qperret at google.com> wrote:
> 
> Introduce a set of helper functions allowing to manipulate the pKVM
> guest stage-2 page-tables from EL1 using pKVM's HVC interface.
> 
> Each helper has an exact one-to-one correspondance with the traditional
> kvm_pgtable_stage2_*() functions from pgtable.c, with a strictly
> matching prototype. This will ease plumbing later on in mmu.c.
> 
> These callbacks track the gfn->pfn mappings in a simple rb_tree indexed
> by IPA in lieu of a page-table. This rb-tree is kept in sync with pKVM's
> state and is protected by a new rwlock -- the existing mmu_lock
> protection does not suffice in the map() path where the tree must be
> modified while user_mem_abort() only acquires a read_lock.
> 
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
> 
> The embedded union inside struct kvm_pgtable is arguably a bit horrible
> currently... I considered making the pgt argument to all kvm_pgtable_*()
> functions an opaque void * ptr, and moving the definition of
> struct kvm_pgtable to pgtable.c and the pkvm version into pkvm.c. Given
> that the allocation of that data-structure is done by the caller, that
> means we'd need to expose kvm_pgtable_get_pgd_size() or something that
> each MMU (pgtable.c and pkvm.c) would have to implement and things like
> that. But that felt like a bigger surgery, so I went with the simpler
> option. Thoughts welcome :-)

I really don't think it is too bad, and I rather keep some typing
rather than going the void * route. Some comments below.

> 
> Similarly, happy to drop the mappings_lock if we want to teach
> user_mem_abort() about taking a write lock on the mmu_lock in the pKVM
> case, but again this implementation is the least invasive into normal
> KVM so that felt like a reasonable starting point.
> ---
>  arch/arm64/include/asm/kvm_host.h    |   1 +
>  arch/arm64/include/asm/kvm_pgtable.h |  27 ++--
>  arch/arm64/include/asm/kvm_pkvm.h    |  28 ++++
>  arch/arm64/kvm/pkvm.c                | 195 +++++++++++++++++++++++++++
>  4 files changed, 242 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index f75988e3515b..05936b57a3a4 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -85,6 +85,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
>  struct kvm_hyp_memcache {
>  	phys_addr_t head;
>  	unsigned long nr_pages;
> +	struct pkvm_mapping *mapping; /* only used from EL1 */
>  };
>  
>  static inline void push_hyp_memcache(struct kvm_hyp_memcache *mc,
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 04418b5e3004..d24d18874015 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -412,15 +412,24 @@ static inline bool kvm_pgtable_walk_lock_held(void)
>   *			be used instead of block mappings.
>   */
>  struct kvm_pgtable {
> -	u32					ia_bits;
> -	s8					start_level;
> -	kvm_pteref_t				pgd;
> -	struct kvm_pgtable_mm_ops		*mm_ops;
> -
> -	/* Stage-2 only */
> -	struct kvm_s2_mmu			*mmu;
> -	enum kvm_pgtable_stage2_flags		flags;
> -	kvm_pgtable_force_pte_cb_t		force_pte_cb;
> +	union {
> +		struct {
> +			u32					ia_bits;
> +			s8					start_level;
> +			kvm_pteref_t				pgd;
> +			struct kvm_pgtable_mm_ops		*mm_ops;
> +
> +			/* Stage-2 only */
> +			struct kvm_s2_mmu			*mmu;
> +			enum kvm_pgtable_stage2_flags		flags;
> +			kvm_pgtable_force_pte_cb_t		force_pte_cb;
> +		};
> +		struct {
> +			struct kvm				*kvm;

Given that the kvm_s2_mmu already has a back-pointer to kvm_arch,
maybe you could keep that one common and use it?

There is also some baked assumption that non-NV is always using the
s2_mmu that's embedded in kvm_arch.

> +			struct rb_root				mappings;
> +			rwlock_t				mappings_lock;
> +		} pkvm;
> +	};
>  };
>  
>  /**
> diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> index cd56acd9a842..84211d5daf87 100644
> --- a/arch/arm64/include/asm/kvm_pkvm.h
> +++ b/arch/arm64/include/asm/kvm_pkvm.h
> @@ -11,6 +11,12 @@
>  #include <linux/scatterlist.h>
>  #include <asm/kvm_pgtable.h>
>  
> +struct pkvm_mapping {
> +	u64 gfn;
> +	u64 pfn;
> +	struct rb_node node;

nit: make the node the first field.

> +};
> +
>  /* Maximum number of VMs that can co-exist under pKVM. */
>  #define KVM_MAX_PVMS 255
>  
> @@ -137,4 +143,26 @@ static inline size_t pkvm_host_sve_state_size(void)
>  			SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_sve_max_vl)));
>  }
>  
> +static inline pkvm_handle_t pkvm_pgt_to_handle(struct kvm_pgtable *pgt)
> +{
> +	return pgt->pkvm.kvm->arch.pkvm.handle;
> +}
> +
> +int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops);
> +void pkvm_pgtable_destroy(struct kvm_pgtable *pgt);
> +int pkvm_pgtable_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
> +			   u64 phys, enum kvm_pgtable_prot prot,
> +			   void *mc, enum kvm_pgtable_walk_flags flags);
> +int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold);
> +int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
> +			     enum kvm_pgtable_walk_flags flags);
> +void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags);
> +int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc);
> +void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level);
> +kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
> +					enum kvm_pgtable_prot prot, void *mc, bool force_pte);
> +
>  #endif	/* __ARM64_KVM_PKVM_H__ */
> diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
> index 85117ea8f351..9c648a510671 100644
> --- a/arch/arm64/kvm/pkvm.c
> +++ b/arch/arm64/kvm/pkvm.c
> @@ -7,6 +7,7 @@
>  #include <linux/init.h>
>  #include <linux/kmemleak.h>
>  #include <linux/kvm_host.h>
> +#include <asm/kvm_mmu.h>
>  #include <linux/memblock.h>
>  #include <linux/mutex.h>
>  #include <linux/sort.h>
> @@ -268,3 +269,197 @@ static int __init finalize_pkvm(void)
>  	return ret;
>  }
>  device_initcall_sync(finalize_pkvm);
> +
> +static int cmp_mappings(struct rb_node *node, const struct rb_node *parent)
> +{
> +	struct pkvm_mapping *a = rb_entry(node, struct pkvm_mapping, node);
> +	struct pkvm_mapping *b = rb_entry(parent, struct pkvm_mapping, node);
> +
> +	if (a->gfn < b->gfn)
> +		return -1;
> +	if (a->gfn > b->gfn)
> +		return 1;
> +	return 0;
> +}
> +
> +static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
> +{
> +	struct rb_node *node = root->rb_node, *prev = NULL;
> +	struct pkvm_mapping *mapping;
> +
> +	while (node) {
> +		mapping = rb_entry(node, struct pkvm_mapping, node);
> +		if (mapping->gfn == gfn)
> +			return node;
> +		prev = node;
> +		node = (gfn < mapping->gfn) ? node->rb_left : node->rb_right;
> +	}
> +
> +	return prev;
> +}
> +
> +#define for_each_mapping_in_range(pgt, start_ipa, end_ipa, mapping, tmp)				\
> +	for (tmp = find_first_mapping_node(&pgt->pkvm.mappings, ((start_ipa) >> PAGE_SHIFT));		\
> +	     tmp && ({ mapping = rb_entry(tmp, struct pkvm_mapping, node); tmp = rb_next(tmp); 1; });)	\
> +		if (mapping->gfn < ((start_ipa) >> PAGE_SHIFT))						\
> +			continue;									\
> +		else if (mapping->gfn >= ((end_ipa) >> PAGE_SHIFT))					\
> +			break;										\
> +		else

Oh gawd... This makes my head spin, and it can't be said that I'm
adverse to the most bizarre macro constructs. I came up with this:

diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index 9c648a5106717..b1b8501cae8f7 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -298,13 +298,19 @@ static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
 	return prev;
 }
 
-#define for_each_mapping_in_range(pgt, start_ipa, end_ipa, mapping, tmp)				\
-	for (tmp = find_first_mapping_node(&pgt->pkvm.mappings, ((start_ipa) >> PAGE_SHIFT));		\
-	     tmp && ({ mapping = rb_entry(tmp, struct pkvm_mapping, node); tmp = rb_next(tmp); 1; });)	\
-		if (mapping->gfn < ((start_ipa) >> PAGE_SHIFT))						\
-			continue;									\
-		else if (mapping->gfn >= ((end_ipa) >> PAGE_SHIFT))					\
-			break;										\
+#define for_each_mapping_in_range(__pgt, __start, __end, __map)				 \
+	for (struct rb_node *__tmp = find_first_mapping_node(&__pgt->pkvm.mappings, 	 \
+							     ((__start) >> PAGE_SHIFT)); \
+	     __tmp && ({								 \
+			     __map = rb_entry(__tmp, struct pkvm_mapping, node); 	 \
+			     __tmp = rb_next(__tmp);					 \
+			     true;							 \
+		     });								 \
+	     )										 \
+		if (__map->gfn < ((__start) >> PAGE_SHIFT))				 \
+			continue;							 \
+		else if (__map->gfn >= ((__end) >> PAGE_SHIFT))				 \
+			break;								 \
 		else
 
 int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops)
@@ -371,11 +377,10 @@ int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
 {
 	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
 	struct pkvm_mapping *mapping;
-	struct rb_node *tmp;
 	int ret = 0;
 
 	write_lock(&pgt->pkvm.mappings_lock);
-	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp) {
+	for_each_mapping_in_range(pgt, addr, addr + size, mapping) {
 		ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
 		if (WARN_ON(ret))
 			break;
@@ -392,11 +397,10 @@ int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
 {
 	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
 	struct pkvm_mapping *mapping;
-	struct rb_node *tmp;
 	int ret = 0;
 
 	read_lock(&pgt->pkvm.mappings_lock);
-	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp) {
+	for_each_mapping_in_range(pgt, addr, addr + size, mapping) {
 		ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn);
 		if (WARN_ON(ret))
 			break;
@@ -409,10 +413,9 @@ int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
 int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
 {
 	struct pkvm_mapping *mapping;
-	struct rb_node *tmp;
 
 	read_lock(&pgt->pkvm.mappings_lock);
-	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp)
+	for_each_mapping_in_range(pgt, addr, addr + size, mapping)
 		__clean_dcache_guest_page(pfn_to_kaddr(mapping->pfn), PAGE_SIZE);
 	read_unlock(&pgt->pkvm.mappings_lock);
 
@@ -423,11 +426,10 @@ bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size,
 {
 	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
 	struct pkvm_mapping *mapping;
-	struct rb_node *tmp;
 	bool young = false;
 
 	read_lock(&pgt->pkvm.mappings_lock);
-	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp)
+	for_each_mapping_in_range(pgt, addr, addr + size, mapping)
 		young |= kvm_call_hyp_nvhe(__pkvm_host_test_clear_young_guest, handle, mapping->gfn,
 					   mkold);
 	read_unlock(&pgt->pkvm.mappings_lock);

Should be semantically equivalent, but I find it way more readable.

Also, maybe add a comment indicating why __tmp needs to be updated
*before* the body of the loop gets executed (case of freeing the
mapping from within the body).

> +
> +int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops)
> +{
> +	pgt->pkvm.kvm		= kvm_s2_mmu_to_kvm(mmu);
> +	pgt->pkvm.mappings	= RB_ROOT;
> +	rwlock_init(&pgt->pkvm.mappings_lock);

We talked about this f2f: Given that this lock is semantically
equivalent to the MMU lock, maybe just use that by upgrading it to be
taken as for write when pKVM is enabled.

It should be easy enough to wrap that in helpers that DTRT, and all
this code could become devoid of any extra locking.

[...]

> +int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
> +			     enum kvm_pgtable_walk_flags flags)
> +{
> +	return kvm_call_hyp_nvhe(__pkvm_host_relax_guest_perms, addr >> PAGE_SHIFT, prot);
> +}
> +
> +void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags)
> +{
> +	WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_mkyoung_guest, addr >> PAGE_SHIFT));
> +}
> +
> +void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
> +{
> +	WARN_ON(1);
> +}
> +
> +kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
> +					enum kvm_pgtable_prot prot, void *mc, bool force_pte)
> +{
> +	WARN_ON(1);
> +	return NULL;
> +}
> +
> +int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc)
> +{
> +	WARN_ON(1);
> +	return -EINVAL;
> +}

Maybe turn these warnings into their _ONCE version. If we end-up here,
seeing it once should be enough to realise we're toast.

Thanks,

	M.

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


From ardb at kernel.org  Thu Dec 12 03:44:38 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 12 Dec 2024 12:44:38 +0100
Subject: [PATCH v3 4/6] arm64/kvm: Avoid invalid physical addresses to
 signal owner updates
In-Reply-To: <Z1rJ_dMJJzGOmjNs@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com> <20241212081841.2168124-12-ardb+git@google.com>
 <Z1rJ_dMJJzGOmjNs@google.com>
Message-ID: <CAMj1kXERuRK_MdHJOY+SKR=BJ-Yi+q0FNgVayq3W_jL9zdjLVA@mail.gmail.com>

On Thu, 12 Dec 2024 at 12:33, Quentin Perret <qperret at google.com> wrote:
>
> On Thursday 12 Dec 2024 at 09:18:46 (+0100), Ard Biesheuvel wrote:
> > @@ -908,6 +892,9 @@ static bool stage2_leaf_mapping_allowed(const struct kvm_pgtable_visit_ctx *ctx,
> >       if (data->force_pte && ctx->level < KVM_PGTABLE_LAST_LEVEL)
> >               return false;
> >
> > +     if (data->annotation && ctx->level == KVM_PGTABLE_LAST_LEVEL)
> > +             return true;
> > +
>
> I don't think it's a problem, but what's the rationale for checking
> ctx->level here? The data->force_pte logic should already do this for us
> and be somewhat orthogonal to data->annotation, no?
>

So you are saying this could be

> > +     if (data->annotation)
> > +             return true;

right? That hides the fact that we expect data->annotation to imply
data->force_pte, but other than that, it should work the same, yes.

> Either way, the patch looks good to me
>
>   Reviewed-by: Quentin Perret <qperret at google.com>
>

Thanks!


From festevam at gmail.com  Thu Dec 12 03:45:35 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 12 Dec 2024 08:45:35 -0300
Subject: [PATCH] ARM: dts: imx27-eukrea-mbimxsd27: Fix ADS7846 interrupt
Message-ID: <20241212114535.558496-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

According to ti,ads7843.yaml the ADS7846 interrupt should be described
via interrupt-parent and interrupts properties.

Do it accordingly to fix the following dt-schema warning:

ads7846 at 0: interrupts: [[9], [25], [8]] is too long

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts b/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts
index d78793601306..7ee1e8c3bb08 100644
--- a/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts
@@ -76,7 +76,8 @@ ads7846 at 0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_touch>;
 		reg = <0>;
-		interrupts = <&gpio4 25 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
 		spi-cpol;
 		spi-max-frequency = <1500000>;
 		ti,keep-vref-on;
-- 
2.34.1



From faraz.ata at samsung.com  Thu Dec 12 03:57:05 2024
From: faraz.ata at samsung.com (Faraz Ata)
Date: Thu, 12 Dec 2024 17:27:05 +0530
Subject: [PATCH v2] arm64: dts: exynosautov920: Add DMA nodes
References: <CGME20241212115815epcas5p29fdba4ddb93d08035f422444cb826ec3@epcas5p2.samsung.com>
Message-ID: <20241212115709.1724-1-faraz.ata@samsung.com>

ExynosAutov920 SoC has 7 DMA controllers. Two secure DMAC
(SPDMA0 & SPDMA1) and five non-secure DMAC (PDMA0 to PDMA4).
Add the required dt nodes for the same.

Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
Signed-off-by: Faraz Ata <faraz.ata at samsung.com>
---
Changes in v2:
- Fixed review comments from Krzysztof and Tudor as below,
- Fixed typo s/adds/add, s/node/nodes.
- Changed DMA base addresses to lowercase hex.
- Link to v1: https://patchwork.kernel.org/project/linux-samsung-soc/patch/20241204122335.1578-1-faraz.ata at samsung.com/
---
 .../arm64/boot/dts/exynos/exynosautov920.dtsi | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
index c759134c909e..dd984dc2bdcd 100644
--- a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
@@ -193,6 +193,69 @@ gic: interrupt-controller at 10400000 {
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		spdma0: dma-controller at 10180000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x10180000 0x1000>;
+			interrupts = <GIC_SPI 918 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		spdma1: dma-controller at 10190000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x10190000 0x1000>;
+			interrupts = <GIC_SPI 917 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma0: dma-controller at 101a0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101a0000 0x1000>;
+			interrupts = <GIC_SPI 916 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma1: dma-controller at 101b0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101b0000 0x1000>;
+			interrupts = <GIC_SPI 915 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma2: dma-controller at 101c0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101c0000 0x1000>;
+			interrupts = <GIC_SPI 914 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma3: dma-controller at 101d0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101d0000 0x1000>;
+			interrupts = <GIC_SPI 913 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
+		pdma4: dma-controller at 101e0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x101e0000 0x1000>;
+			interrupts = <GIC_SPI 912 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_misc CLK_MOUT_MISC_NOC_USER>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+
 		cmu_peric0: clock-controller at 10800000 {
 			compatible = "samsung,exynosautov920-cmu-peric0";
 			reg = <0x10800000 0x8000>;
-- 
2.34.1



From mike.leach at linaro.org  Thu Dec 12 04:03:13 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 12 Dec 2024 12:03:13 +0000
Subject: [PATCH v7 8/9] coresight: tools: Add configuration table test tools
In-Reply-To: <9cb1ef5e-eb61-4177-a039-4049850196a5@linaro.org>
References: <20241127134256.2254851-1-mike.leach@linaro.org>
 <20241127134256.2254851-9-mike.leach@linaro.org> <9cb1ef5e-eb61-4177-a039-4049850196a5@linaro.org>
Message-ID: <CAJ9a7VhG0Mxo=66JpGkPYDBLwo_fmv6BbLx2jPLeDd76f2gfCQ@mail.gmail.com>

Hi James

On Tue, 3 Dec 2024 at 14:25, James Clark <james.clark at linaro.org> wrote:
>
>
>
> On 27/11/2024 1:42 pm, Mike Leach wrote:
> > Add an example config table generator to test loading configuration
> > tables.
> >
> > Provides a table buffer writer function that can be re-used in other
> > userspace programs.
> >
> > Table write format matches that expected by the corresponding reader
> > in the configfs driver code.
> >
> > Generates tables and outputs in form of binary files.
> >
> > Add a config table file reader and printer. Takes in config table files
> > and prints the contents. Uses table reader source from kernel driver.
> >
> > Signed-off-by: Mike Leach <mike.leach at linaro.org>
> > ---
> >   MAINTAINERS                                   |   1 +
> >   .../coresight/coresight-config-table.h        |   5 +
>
> Hi Mike,
>
> Isn't there some convention about maintaining a copy of kernel headers
> in the tools? Especially as you wouldn't rebuild the tools after
> updating the kernel headers so breakages might go unnoticed.
>

Not sure - perf keeps a copy and has a check script on build to ensure
the copy matches the kernel version.
Keeping two copies of the same thing always strikes me as poor
practice, so I went for copying over.

Both methods risk breakages when something in the kernel changes.

> [...]
>
> > +
> > +/*
> > + * sets of presets leaves strobing window constant while varying period to allow
> > + * experimentation with mark / space ratios for various workloads
> > + */
> > +static u64 afdo_set_a_presets[AFDO_NR_PRESETS][AFDO_NR_PARAM_SUM] = {
> > +     { 2000, 100 },
> > +     { 2000, 1000 },
> > +     { 2000, 5000 },
> > +     { 2000, 10000 },
> > +     { 4000, 100 },
>
> The comment above here looks like its for example1, this one does vary
> the window size.
>
> Probably only example2 is enough, I assumed they were different but
> example2 is basically the same as example1 with an extra preset list. We
> could comment that the second preset list is optional and delete
> example1. Saves people reading more and wondering what the difference is.
>

Yes - perhaps both examples were not necessary - but the point was you
can have two configs in a single loadable table.

> I tried to make an example that doesn't use an existing feature by
> reacreating afdo from scratch which I thought would be a good example.
> It's pasted at the end. I had to copy paste the ETMv4 macros and
> constants though, I couldn't include them in the userspace generator
> because of this error:
>

The updated ETM config set that is to follow addresses this issue -
the macros are split off into a separate file  (and adds in a whole
lot of validation - ensuring a configuration cannot specify and
allocate more resources than are available.)
This is also the reason that the examples provided were very simple.
More complex ones are to follow!

This set was focused on loading tables so that the next patchsets
dealing with resource validating ETM configs and CTI configs had an
easy to use test platform.


>    coresight-config.h:10:10: fatal error: linux/coresight.h: No such
> file
>    or directory
>     10 | #include <linux/coresight.h>
>
> I also got this error when loading it:
>
> Unable to handle kernel NULL pointer dereference at virtual address
> 0000000000000008
>
> cscfg_reset_feat (drivers/hwtracing/coresight/coresight-config.c:64
> coresight-config.c:124) coresight
> cscfg_load_config_sets
> (drivers/hwtracing/coresight/coresight-syscfg.c:217
> coresight-syscfg.c:262 coresight-syscfg.c:492 coresight-syscfg.c:610)
> coresight
> cscfg_dyn_load_cfg_table
> (drivers/hwtracing/coresight/coresight-syscfg-configfs.c:294) coresight
> cscfg_cfg_load_table_write
> (drivers/hwtracing/coresight/coresight-syscfg-configfs.c:799) coresight
> configfs_release_bin_file (fs/configfs/file.c:415)
> __fput (fs/file_table.c:432)
> __fput_sync (fs/file_table.c:517)
> __arm64_sys_close (fs/open.c:1568 fs/open.c:1550 fs/open.c:1550)
> invoke_syscall (arch/arm64/kernel/syscall.c:?
> arch/arm64/kernel/syscall.c:49)
> el0_svc_common (include/linux/thread_info.h:127
> arch/arm64/kernel/syscall.c:140)
> do_el0_svc (arch/arm64/kernel/syscall.c:152)
>

I'll go back to my tests to check I was testing what I thought I was -
and didn't accidentally change something after testing and before
sending the patchset.

>
> So I'm wondering if we can do the same thing by setting values via
> individual files rather than one binary blob which would avoid some of
> these issues. From what I understand the feature params can already be
> set directly this way via
> /sys/kernel/config/cs-syscfg/features/strobing/params/period/value
>


> We'd have to add a way to add new configs with a mkdir, then the same
> things can be configured without needing an additional tool. Links
> between features and configs can be done with symlinks which is also
> mentioned in the configfs docs.
>
> Something like this would be a bit like the current version:
>
>   # ls /config/cs-syscfg
>   configurations
>   features
>
>   # mkdir /config/cs-syscfg/features/my_config
>   # ls /config/cs-syscfg/features/my_config
>   description
>   matches
>   regs_desc
>   params
>
>   # mkdir /config/cs-syscfg/features/my_config/regs_desc/TRCRSCTLRn0
>   # ls /config/cs-syscfg/features/my_config/TRCRSCTLRn0
>   type
>   offset
>   val
>   mask
>

This is precisely what I wanted to avoid. Doing it this way is both
time consuming for the user and ends up reproducing most of the sysfs
files in configfs.

Parameters are there to allow a limited amount of relevent runtime
adjustment. Parameter values may also only populate part of a hw
register depending on use case.

The resource approach allows us to define certain bitfields e.g.
Branch broadcast - as user configurable - but omit anything users are
not allowed to meddle with.

The table load is atomic - it is validated and succeeds or fails
completely. The load mechanism prevents the new configuration from
becoming visible until it is loaded. The configfs per file method has
an issue in deciding when the configuration is "complete". If you look
in the configfs docs/source there was at one time  a  "commit"
methodology proposed, but this never came to fruition.

Table load  re-uses the same mechanisms as the built-in and loadable
module methods for adding configurations, but without the need for
re-compiling the kernel / compiling against a specific kernel -
meaning loadable tables are dependent only on the hardware available,
not the kernel version. Adding a per file option means that the new
configurations would be different from the current load methods
upstream - and appear differently in configfs.

> But another way could be to enumerate all possible regs for each device.
> This would remove the need to have all the #defines in whatever tool is
> making the config (avoiding the #include issue from above):
>
>   # mkdir /config/cs-syscfg/features/my_config
>   # ls /config/cs-syscfg/features/my_config/regs_desc
>
>   regs_desc is initially empty, but specify what device it's for to make
>   all the properties appear (or the mkdir could be done in an etmv4
>   folder):
>
>   # echo "SRC_ETM4" > matches
>   # ls /config/cs-syscfg/features/my_config/regs_desc
>   TRCRSCTLRn0
>   TRCRSCTLRn1
>   TRCRSCTLRn2
>   ... etc ...
>
>   Now type and offset don't need to be set:
>
>   # ls /config/cs-syscfg/features/my_config/regs_desc/TRCRSCTLRn0
>   val
>   mask
>   save
>
> Don't we already have the full list of parameters in
> etm4_cfg_map_reg_offset(), so we can expose this to users via configfs
> directly rather than needing any tooling. And doesn't any new device
> that's supported by the config mechanism need to know about all its
> parameters, so it wouldn't remove any flexibility?
>

Mike


>



--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From qperret at google.com  Thu Dec 12 04:03:34 2024
From: qperret at google.com (Quentin Perret)
Date: Thu, 12 Dec 2024 12:03:34 +0000
Subject: [PATCH v2 17/18] KVM: arm64: Introduce the EL1 pKVM MMU
In-Reply-To: <86jzc5rv6a.wl-maz@kernel.org>
References: <20241203103735.2267589-1-qperret@google.com>
 <20241203103735.2267589-18-qperret@google.com>
 <86jzc5rv6a.wl-maz@kernel.org>
Message-ID: <Z1rRFuXdj_DjZrvX@google.com>

On Thursday 12 Dec 2024 at 11:35:09 (+0000), Marc Zyngier wrote:
> On Tue, 03 Dec 2024 10:37:34 +0000,
> Quentin Perret <qperret at google.com> wrote:
> > 
> > Introduce a set of helper functions allowing to manipulate the pKVM
> > guest stage-2 page-tables from EL1 using pKVM's HVC interface.
> > 
> > Each helper has an exact one-to-one correspondance with the traditional
> > kvm_pgtable_stage2_*() functions from pgtable.c, with a strictly
> > matching prototype. This will ease plumbing later on in mmu.c.
> > 
> > These callbacks track the gfn->pfn mappings in a simple rb_tree indexed
> > by IPA in lieu of a page-table. This rb-tree is kept in sync with pKVM's
> > state and is protected by a new rwlock -- the existing mmu_lock
> > protection does not suffice in the map() path where the tree must be
> > modified while user_mem_abort() only acquires a read_lock.
> > 
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> > 
> > The embedded union inside struct kvm_pgtable is arguably a bit horrible
> > currently... I considered making the pgt argument to all kvm_pgtable_*()
> > functions an opaque void * ptr, and moving the definition of
> > struct kvm_pgtable to pgtable.c and the pkvm version into pkvm.c. Given
> > that the allocation of that data-structure is done by the caller, that
> > means we'd need to expose kvm_pgtable_get_pgd_size() or something that
> > each MMU (pgtable.c and pkvm.c) would have to implement and things like
> > that. But that felt like a bigger surgery, so I went with the simpler
> > option. Thoughts welcome :-)
> 
> I really don't think it is too bad, and I rather keep some typing
> rather than going the void * route. Some comments below.

Sounds good.

> > 
> > Similarly, happy to drop the mappings_lock if we want to teach
> > user_mem_abort() about taking a write lock on the mmu_lock in the pKVM
> > case, but again this implementation is the least invasive into normal
> > KVM so that felt like a reasonable starting point.
> > ---
> >  arch/arm64/include/asm/kvm_host.h    |   1 +
> >  arch/arm64/include/asm/kvm_pgtable.h |  27 ++--
> >  arch/arm64/include/asm/kvm_pkvm.h    |  28 ++++
> >  arch/arm64/kvm/pkvm.c                | 195 +++++++++++++++++++++++++++
> >  4 files changed, 242 insertions(+), 9 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index f75988e3515b..05936b57a3a4 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -85,6 +85,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
> >  struct kvm_hyp_memcache {
> >  	phys_addr_t head;
> >  	unsigned long nr_pages;
> > +	struct pkvm_mapping *mapping; /* only used from EL1 */
> >  };
> >  
> >  static inline void push_hyp_memcache(struct kvm_hyp_memcache *mc,
> > diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> > index 04418b5e3004..d24d18874015 100644
> > --- a/arch/arm64/include/asm/kvm_pgtable.h
> > +++ b/arch/arm64/include/asm/kvm_pgtable.h
> > @@ -412,15 +412,24 @@ static inline bool kvm_pgtable_walk_lock_held(void)
> >   *			be used instead of block mappings.
> >   */
> >  struct kvm_pgtable {
> > -	u32					ia_bits;
> > -	s8					start_level;
> > -	kvm_pteref_t				pgd;
> > -	struct kvm_pgtable_mm_ops		*mm_ops;
> > -
> > -	/* Stage-2 only */
> > -	struct kvm_s2_mmu			*mmu;
> > -	enum kvm_pgtable_stage2_flags		flags;
> > -	kvm_pgtable_force_pte_cb_t		force_pte_cb;
> > +	union {
> > +		struct {
> > +			u32					ia_bits;
> > +			s8					start_level;
> > +			kvm_pteref_t				pgd;
> > +			struct kvm_pgtable_mm_ops		*mm_ops;
> > +
> > +			/* Stage-2 only */
> > +			struct kvm_s2_mmu			*mmu;
> > +			enum kvm_pgtable_stage2_flags		flags;
> > +			kvm_pgtable_force_pte_cb_t		force_pte_cb;
> > +		};
> > +		struct {
> > +			struct kvm				*kvm;
> 
> Given that the kvm_s2_mmu already has a back-pointer to kvm_arch,
> maybe you could keep that one common and use it?
> 
> There is also some baked assumption that non-NV is always using the
> s2_mmu that's embedded in kvm_arch.

Right, what I need is one kvm_s2_mmu_to_kvm() away, so that should work
nicely. And as discussed below, I'll try ditching mappings_lock, so we
should be left the rb_root on its own.

> > +			struct rb_root				mappings;
> > +			rwlock_t				mappings_lock;
> > +		} pkvm;
> > +	};
> >  };
> >  
> >  /**
> > diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> > index cd56acd9a842..84211d5daf87 100644
> > --- a/arch/arm64/include/asm/kvm_pkvm.h
> > +++ b/arch/arm64/include/asm/kvm_pkvm.h
> > @@ -11,6 +11,12 @@
> >  #include <linux/scatterlist.h>
> >  #include <asm/kvm_pgtable.h>
> >  
> > +struct pkvm_mapping {
> > +	u64 gfn;
> > +	u64 pfn;
> > +	struct rb_node node;
> 
> nit: make the node the first field.

Ack.

> > +};
> > +
> >  /* Maximum number of VMs that can co-exist under pKVM. */
> >  #define KVM_MAX_PVMS 255
> >  
> > @@ -137,4 +143,26 @@ static inline size_t pkvm_host_sve_state_size(void)
> >  			SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_sve_max_vl)));
> >  }
> >  
> > +static inline pkvm_handle_t pkvm_pgt_to_handle(struct kvm_pgtable *pgt)
> > +{
> > +	return pgt->pkvm.kvm->arch.pkvm.handle;
> > +}
> > +
> > +int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops);
> > +void pkvm_pgtable_destroy(struct kvm_pgtable *pgt);
> > +int pkvm_pgtable_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
> > +			   u64 phys, enum kvm_pgtable_prot prot,
> > +			   void *mc, enum kvm_pgtable_walk_flags flags);
> > +int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
> > +int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
> > +int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
> > +bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold);
> > +int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
> > +			     enum kvm_pgtable_walk_flags flags);
> > +void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags);
> > +int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc);
> > +void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level);
> > +kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
> > +					enum kvm_pgtable_prot prot, void *mc, bool force_pte);
> > +
> >  #endif	/* __ARM64_KVM_PKVM_H__ */
> > diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
> > index 85117ea8f351..9c648a510671 100644
> > --- a/arch/arm64/kvm/pkvm.c
> > +++ b/arch/arm64/kvm/pkvm.c
> > @@ -7,6 +7,7 @@
> >  #include <linux/init.h>
> >  #include <linux/kmemleak.h>
> >  #include <linux/kvm_host.h>
> > +#include <asm/kvm_mmu.h>
> >  #include <linux/memblock.h>
> >  #include <linux/mutex.h>
> >  #include <linux/sort.h>
> > @@ -268,3 +269,197 @@ static int __init finalize_pkvm(void)
> >  	return ret;
> >  }
> >  device_initcall_sync(finalize_pkvm);
> > +
> > +static int cmp_mappings(struct rb_node *node, const struct rb_node *parent)
> > +{
> > +	struct pkvm_mapping *a = rb_entry(node, struct pkvm_mapping, node);
> > +	struct pkvm_mapping *b = rb_entry(parent, struct pkvm_mapping, node);
> > +
> > +	if (a->gfn < b->gfn)
> > +		return -1;
> > +	if (a->gfn > b->gfn)
> > +		return 1;
> > +	return 0;
> > +}
> > +
> > +static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
> > +{
> > +	struct rb_node *node = root->rb_node, *prev = NULL;
> > +	struct pkvm_mapping *mapping;
> > +
> > +	while (node) {
> > +		mapping = rb_entry(node, struct pkvm_mapping, node);
> > +		if (mapping->gfn == gfn)
> > +			return node;
> > +		prev = node;
> > +		node = (gfn < mapping->gfn) ? node->rb_left : node->rb_right;
> > +	}
> > +
> > +	return prev;
> > +}
> > +
> > +#define for_each_mapping_in_range(pgt, start_ipa, end_ipa, mapping, tmp)				\
> > +	for (tmp = find_first_mapping_node(&pgt->pkvm.mappings, ((start_ipa) >> PAGE_SHIFT));		\
> > +	     tmp && ({ mapping = rb_entry(tmp, struct pkvm_mapping, node); tmp = rb_next(tmp); 1; });)	\
> > +		if (mapping->gfn < ((start_ipa) >> PAGE_SHIFT))						\
> > +			continue;									\
> > +		else if (mapping->gfn >= ((end_ipa) >> PAGE_SHIFT))					\
> > +			break;										\
> > +		else
> 
> Oh gawd... This makes my head spin, and it can't be said that I'm
> adverse to the most bizarre macro constructs. I came up with this:
> 
> diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
> index 9c648a5106717..b1b8501cae8f7 100644
> --- a/arch/arm64/kvm/pkvm.c
> +++ b/arch/arm64/kvm/pkvm.c
> @@ -298,13 +298,19 @@ static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
>  	return prev;
>  }
>  
> -#define for_each_mapping_in_range(pgt, start_ipa, end_ipa, mapping, tmp)				\
> -	for (tmp = find_first_mapping_node(&pgt->pkvm.mappings, ((start_ipa) >> PAGE_SHIFT));		\
> -	     tmp && ({ mapping = rb_entry(tmp, struct pkvm_mapping, node); tmp = rb_next(tmp); 1; });)	\
> -		if (mapping->gfn < ((start_ipa) >> PAGE_SHIFT))						\
> -			continue;									\
> -		else if (mapping->gfn >= ((end_ipa) >> PAGE_SHIFT))					\
> -			break;										\
> +#define for_each_mapping_in_range(__pgt, __start, __end, __map)				 \
> +	for (struct rb_node *__tmp = find_first_mapping_node(&__pgt->pkvm.mappings, 	 \
> +							     ((__start) >> PAGE_SHIFT)); \
> +	     __tmp && ({								 \
> +			     __map = rb_entry(__tmp, struct pkvm_mapping, node); 	 \
> +			     __tmp = rb_next(__tmp);					 \
> +			     true;							 \
> +		     });								 \
> +	     )										 \
> +		if (__map->gfn < ((__start) >> PAGE_SHIFT))				 \
> +			continue;							 \
> +		else if (__map->gfn >= ((__end) >> PAGE_SHIFT))				 \
> +			break;								 \
>  		else
>  
>  int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops)
> @@ -371,11 +377,10 @@ int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
>  {
>  	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
>  	struct pkvm_mapping *mapping;
> -	struct rb_node *tmp;
>  	int ret = 0;
>  
>  	write_lock(&pgt->pkvm.mappings_lock);
> -	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp) {
> +	for_each_mapping_in_range(pgt, addr, addr + size, mapping) {
>  		ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
>  		if (WARN_ON(ret))
>  			break;
> @@ -392,11 +397,10 @@ int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
>  {
>  	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
>  	struct pkvm_mapping *mapping;
> -	struct rb_node *tmp;
>  	int ret = 0;
>  
>  	read_lock(&pgt->pkvm.mappings_lock);
> -	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp) {
> +	for_each_mapping_in_range(pgt, addr, addr + size, mapping) {
>  		ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn);
>  		if (WARN_ON(ret))
>  			break;
> @@ -409,10 +413,9 @@ int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
>  int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
>  {
>  	struct pkvm_mapping *mapping;
> -	struct rb_node *tmp;
>  
>  	read_lock(&pgt->pkvm.mappings_lock);
> -	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp)
> +	for_each_mapping_in_range(pgt, addr, addr + size, mapping)
>  		__clean_dcache_guest_page(pfn_to_kaddr(mapping->pfn), PAGE_SIZE);
>  	read_unlock(&pgt->pkvm.mappings_lock);
>  
> @@ -423,11 +426,10 @@ bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size,
>  {
>  	pkvm_handle_t handle = pkvm_pgt_to_handle(pgt);
>  	struct pkvm_mapping *mapping;
> -	struct rb_node *tmp;
>  	bool young = false;
>  
>  	read_lock(&pgt->pkvm.mappings_lock);
> -	for_each_mapping_in_range(pgt, addr, addr + size, mapping, tmp)
> +	for_each_mapping_in_range(pgt, addr, addr + size, mapping)
>  		young |= kvm_call_hyp_nvhe(__pkvm_host_test_clear_young_guest, handle, mapping->gfn,
>  					   mkold);
>  	read_unlock(&pgt->pkvm.mappings_lock);
> 
> Should be semantically equivalent, but I find it way more readable.

Yep, declaring __tmp within the loop itself is much nicer, it certainly
doesn't need to outlive it. I'll fold that in, thanks!

> Also, maybe add a comment indicating why __tmp needs to be updated
> *before* the body of the loop gets executed (case of freeing the
> mapping from within the body).

Ack, and I might rename the macro to for_each_mapping_in_range_safe()
as well to make it clear we have that property.

> > +
> > +int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops)
> > +{
> > +	pgt->pkvm.kvm		= kvm_s2_mmu_to_kvm(mmu);
> > +	pgt->pkvm.mappings	= RB_ROOT;
> > +	rwlock_init(&pgt->pkvm.mappings_lock);
> 
> We talked about this f2f: Given that this lock is semantically
> equivalent to the MMU lock, maybe just use that by upgrading it to be
> taken as for write when pKVM is enabled.
> 
> It should be easy enough to wrap that in helpers that DTRT, and all
> this code could become devoid of any extra locking.

OK, I'll also stick lockdep assertions to document and enforce the
locking requirements from here.

> > +int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
> > +			     enum kvm_pgtable_walk_flags flags)
> > +{
> > +	return kvm_call_hyp_nvhe(__pkvm_host_relax_guest_perms, addr >> PAGE_SHIFT, prot);
> > +}
> > +
> > +void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags)
> > +{
> > +	WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_mkyoung_guest, addr >> PAGE_SHIFT));
> > +}
> > +
> > +void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
> > +{
> > +	WARN_ON(1);
> > +}
> > +
> > +kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
> > +					enum kvm_pgtable_prot prot, void *mc, bool force_pte)
> > +{
> > +	WARN_ON(1);
> > +	return NULL;
> > +}
> > +
> > +int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc)
> > +{
> > +	WARN_ON(1);
> > +	return -EINVAL;
> > +}
> 
> Maybe turn these warnings into their _ONCE version. If we end-up here,
> seeing it once should be enough to realise we're toast.

Will do.

Cheers,
Quentin


From krzk at kernel.org  Thu Dec 12 04:08:53 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 13:08:53 +0100
Subject: [PATCH] ARM: dts: imx27-eukrea-mbimxsd27: Fix ADS7846 interrupt
In-Reply-To: <20241212114535.558496-1-festevam@gmail.com>
References: <20241212114535.558496-1-festevam@gmail.com>
Message-ID: <8e82a0f6-de16-48d1-a194-c7764c29cc0b@kernel.org>

On 12/12/2024 12:45, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> According to ti,ads7843.yaml the ADS7846 interrupt should be described

That's not true. Above binding does not tell it at all. Nothing about
parent.

> via interrupt-parent and interrupts properties.
> 
> Do it accordingly to fix the following dt-schema warning:
> 
> ads7846 at 0: interrupts: [[9], [25], [8]] is too long

Not entirely. Your reasons are just not correct. There is different
error there - wrong interrupt specifier because you have some specific
interrupt controller (GPIO). Author probably wanted interrupts extended.

Best regards,
Krzysztof


From andi.shyti at kernel.org  Thu Dec 12 04:12:37 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Thu, 12 Dec 2024 13:12:37 +0100
Subject: [PATCH] i2c: imx: make controller available until system
 suspend_noirq() and from resume_noirq()
In-Reply-To: <20241125142108.1613016-1-carlos.song@nxp.com>
References: <20241125142108.1613016-1-carlos.song@nxp.com>
Message-ID: <awvsvzf5ucgcvl6v7giuxeb6dvt3sw5e6kxo7t56n4rk6u3527@2hid4a7acavv>

Hi Carlos,

On Mon, Nov 25, 2024 at 10:21:08PM +0800, carlos.song at nxp.com wrote:
> From: Carlos Song <carlos.song at nxp.com>
> 
> Put runtime pm to resume state between suspend() and suspend_noirq(),
> resume_noirq() and resume(), because some I2C devices need controller
> on to do communication during this period.
> 
> The controller can't be wakeup once runtime pm is disabled and in
> runtime autosuspended state.
> 
> The problem can be easily reproduced on the I.MX8MQ platform:
> PMIC needs to be used to enable regular when the system resumes.
> When PMIC uses I2C controller, I2C runtime pm has not been enabled,
> so in i2c xfer(), pm_runtime_resume_and_get() will return error,
> which causes data transfer failed. Therefore, regulars can not
> be enabled and hang system resumes.
> Here is resume error log:
> [   53.888902] galcore 38000000.gpu3d: PM: calling genpd_resume_noirq @ 529, parent: platform
> [   53.897203] i2c_imx_xfer, pm_runtime_resume_and_get is -13
> [   53.902713] imx-pgc imx-pgc-domain.5: failed to enable regulator: -EACCES
> [   53.909518] galcore 38000000.gpu3d: PM: genpd_resume_noirq returned 0 after 12331 usecs
> [   53.917545] mxc_hantro 38300000.vpu: PM: calling genpd_resume_noirq @ 529, parent: soc at 0
> [   53.925659] i2c_imx_xfer, pm_runtime_resume_and_get is -13
> [   53.931157] imx-pgc imx-pgc-domain.6: failed to enable regulator: -EACCES
> 
> I.MX8MQ system resume normally after applying the fix. Here is resume log:
> [   71.068807] galcore 38000000.gpu3d: PM: calling genpd_resume_noirq @ 530, parent: platform
> [   71.077103] i2c_imx_xfer, pm_runtime_resume_and_get is 0
> [   71.083578] galcore 38000000.gpu3d: PM: genpd_resume_noirq returned 0 after 6490 usecs
> [   71.091526] mxc_hantro 38300000.vpu: PM: calling genpd_resume_noirq @ 530, parent: soc at 0
> [   71.099638] i2c_imx_xfer, pm_runtime_resume_and_get is 0
> [   71.106091] mxc_hantro 38300000.vpu: PM: genpd_resume_noirq returned 0 after 6458 usecs
> 
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>

merged to i2c/i2c-host.

Thanks,
Andi


From andrej.picej at norik.com  Thu Dec 12 04:17:09 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu, 12 Dec 2024 13:17:09 +0100
Subject: [PATCH v6 0/3] SN65DSI83/4 lvds_vod_swing properties
Message-ID: <20241212121712.214639-1-andrej.picej@norik.com>

Hi all,

The LVDS differential voltage swing can be specified as arrays of min, max
in microvolts. Two arrays, one for data-lanes and one for clock-lane can
be specified. Additionally, because LVDS voltage swing depends on near-end
termination this can now also be specified with separate property.

Driver goes through the tables, taken from datasheet [1] and selects the
appropriate configuration. If appropriate configuration can not be found
the probe fails. If these properties are not defined default values are
used as before.

This patch series depends on the patch
"[PATCH v2 11/15] arm64: dts: imx8mm-phyboard-polis: Add support for PEB-AV-10"
(https://lore.kernel.org/all/20241202072052.2195283-12-andrej.picej at norik.com/)
which is currently under review. Please apply the dependent series first before
applying this one.

v1 is at: https://lore.kernel.org/all/20241127103031.1007893-1-andrej.picej at norik.com/
v2 is at: https://lore.kernel.org/all/20241203085822.2475138-1-andrej.picej at norik.com/
v3 is at: https://lore.kernel.org/all/20241203110054.2506123-1-andrej.picej at norik.com/
v4 is at: https://lore.kernel.org/all/20241205134021.2592013-1-andrej.picej at norik.com/
v5 is at: https://lore.kernel.org/all/20241210091901.83028-1-andrej.picej at norik.com/

[1] https://www.ti.com/lit/ds/symlink/sn65dsi83.pdf?ts=1732738773429&ref_url=https%253A%252F%252Fwww.mouser.co.uk%252F

Best regards,
Andrej

Andrej Picej (3):
  dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for
    ti,lvds-vod-swing
  drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
  arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing

 .../bindings/display/bridge/ti,sn65dsi83.yaml |  34 ++++-
 .../imx8mm-phyboard-polis-peb-av-10.dtso      |   2 +
 drivers/gpu/drm/bridge/ti-sn65dsi83.c         | 143 +++++++++++++++++-
 3 files changed, 174 insertions(+), 5 deletions(-)

-- 
2.34.1



From andrej.picej at norik.com  Thu Dec 12 04:17:11 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu, 12 Dec 2024 13:17:11 +0100
Subject: [PATCH v6 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
In-Reply-To: <20241212121712.214639-1-andrej.picej@norik.com>
References: <20241212121712.214639-1-andrej.picej@norik.com>
Message-ID: <20241212121712.214639-3-andrej.picej@norik.com>

Add a optional properties to change LVDS output voltage. This should not
be static as this depends mainly on the connected display voltage
requirement. We have three properties:
- "ti,lvds-termination-ohms", which sets near end termination,
- "ti,lvds-vod-swing-data-microvolt" and
- "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
output voltage for data and clock lanes. They are defined as an array
with min and max values. The appropriate bitfield will be set if
selected constraints can be met.

If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
end termination will be used. Selecting only one:
"ti,lvds-vod-swing-data-microvolt" or
"ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
constraint for only data/clock lanes will be met. Setting both is
recommended.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v6:
- rework termination resistor logic, default is now set by resistor value, not
reg value,
- move setting lvds_vod_swing_conf to default value of 0x1 inside if statement
which checks if both properties are not set
Changes in v5:
- specify default values in sn65dsi83_parse_lvds_endpoint,
- move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
Changes in v4:
- fix typo in commit message bitfiled -> bitfield
- use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
of separate variables for channel A/B
- add more checks on return value of "of_property_read_u32_array"
Changes in v3:
- use microvolts for default array values 1000 mV -> 1000000 uV.
Changes in v2:
- use datasheet tables to get the proper configuration
- since major change was done change the authorship to myself
---
 drivers/gpu/drm/bridge/ti-sn65dsi83.c | 143 +++++++++++++++++++++++++-
 1 file changed, 140 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 57a7ed13f996..8dd9a410a492 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -132,6 +132,16 @@
 #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
 #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
 
+enum sn65dsi83_channel {
+	CHANNEL_A,
+	CHANNEL_B
+};
+
+enum sn65dsi83_lvds_term {
+	OHM_100,
+	OHM_200
+};
+
 enum sn65dsi83_model {
 	MODEL_SN65DSI83,
 	MODEL_SN65DSI84,
@@ -147,6 +157,8 @@ struct sn65dsi83 {
 	struct regulator		*vcc;
 	bool				lvds_dual_link;
 	bool				lvds_dual_link_even_odd_swap;
+	int				lvds_vod_swing_conf[2];
+	int				lvds_term_conf[2];
 };
 
 static const struct regmap_range sn65dsi83_readable_ranges[] = {
@@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
 	.max_register = REG_IRQ_STAT,
 };
 
+static const int lvds_vod_swing_data_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 180000, 313000 },
+		{ 215000, 372000 },
+		{ 250000, 430000 },
+		{ 290000, 488000 },
+	},
+	{	/* 200 Ohm */
+		{ 150000, 261000 },
+		{ 200000, 346000 },
+		{ 250000, 428000 },
+		{ 300000, 511000 },
+	},
+};
+
+static const int lvds_vod_swing_clock_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 140000, 244000 },
+		{ 168000, 290000 },
+		{ 195000, 335000 },
+		{ 226000, 381000 },
+	},
+	{	/* 200 Ohm */
+		{ 117000, 204000 },
+		{ 156000, 270000 },
+		{ 195000, 334000 },
+		{ 234000, 399000 },
+	},
+};
+
 static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
 {
 	return container_of(bridge, struct sn65dsi83, bridge);
@@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
 		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
 
 	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
-	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
+	regmap_write(ctx->regmap, REG_LVDS_VCOM,
+			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
+			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
 	regmap_write(ctx->regmap, REG_LVDS_LANE,
 		     (ctx->lvds_dual_link_even_odd_swap ?
 		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
-		     REG_LVDS_LANE_CHA_LVDS_TERM |
-		     REG_LVDS_LANE_CHB_LVDS_TERM);
+		     (ctx->lvds_term_conf[CHANNEL_A] ?
+			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
+		     (ctx->lvds_term_conf[CHANNEL_B] ?
+			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
 	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
 
 	le16val = cpu_to_le16(mode->hdisplay);
@@ -576,10 +622,101 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
 	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
 };
 
+static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
+	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
+{
+	int i;
+
+	for (i = 0; i <= 3; i++) {
+		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
+		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
+		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
+		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
+			return i;
+	}
+
+	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
+	return -EINVAL;
+}
+
+static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *endpoint;
+	int endpoint_reg;
+	/* Set so the property can be freely selected if not defined */
+	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
+	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
+	/* Set default near end terminataion to 200 Ohm */
+	u32 lvds_term = 200;
+	int lvds_vod_swing_conf;
+	int ret = 0;
+	int ret_data;
+	int ret_clock;
+
+	if (channel == CHANNEL_A)
+		endpoint_reg = 2;
+	else
+		endpoint_reg = 3;
+
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
+
+	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
+	if (lvds_term == 100)
+		ctx->lvds_term_conf[channel] = OHM_100;
+	else if (lvds_term == 200)
+		ctx->lvds_term_conf[channel] = OHM_200;
+	else
+		return -EINVAL;
+
+	ret_data = of_property_read_u32_array(endpoint, "ti,lvds-vod-swing-data-microvolt",
+					lvds_vod_swing_data, ARRAY_SIZE(lvds_vod_swing_data));
+	if (ret_data != 0 && ret_data != -EINVAL) {
+		ret = ret_data;
+		goto exit;
+	}
+
+	ret_clock = of_property_read_u32_array(endpoint, "ti,lvds-vod-swing-clock-microvolt",
+					lvds_vod_swing_clk, ARRAY_SIZE(lvds_vod_swing_clk));
+	if (ret_clock != 0 && ret_clock != -EINVAL) {
+		ret = ret_clock;
+		goto exit;
+	}
+
+	/* Use default value if both properties are NOT defined. */
+	if (ret_data == -EINVAL && ret_clock == -EINVAL)
+		lvds_vod_swing_conf = 0x1;
+
+	/* Use lookup table if any of the two properties is defined. */
+	if (!ret_data || !ret_clock) {
+		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev, lvds_vod_swing_data,
+						lvds_vod_swing_clk, ctx->lvds_term_conf[channel]);
+		if (lvds_vod_swing_conf < 0) {
+			ret = lvds_vod_swing_conf;
+			goto exit;
+		}
+	}
+
+	ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
+	ret = 0;
+exit:
+	of_node_put(endpoint);
+	return ret;
+}
+
 static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
 {
 	struct drm_bridge *panel_bridge;
 	struct device *dev = ctx->dev;
+	int ret;
+
+	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
+	if (ret < 0)
+		return ret;
+
+	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
+	if (ret < 0)
+		return ret;
 
 	ctx->lvds_dual_link = false;
 	ctx->lvds_dual_link_even_odd_swap = false;
-- 
2.34.1



From andrej.picej at norik.com  Thu Dec 12 04:17:10 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu, 12 Dec 2024 13:17:10 +0100
Subject: [PATCH v6 1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for ti,lvds-vod-swing
In-Reply-To: <20241212121712.214639-1-andrej.picej@norik.com>
References: <20241212121712.214639-1-andrej.picej@norik.com>
Message-ID: <20241212121712.214639-2-andrej.picej@norik.com>

Add properties which can be used to specify LVDS differential output
voltage. Since this also depends on near-end signal termination also
include property which sets this. LVDS differential output voltage is
specified with an array (min, max), which should match the one from
connected device.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes in v6:
- no change
Changes in v5:
- added Krzysztof's reviewed-by tag
Changes in v4:
- removed "additionalProperties: true" from the patch as it is not needed
Changes in v3:
- no change
Changes in v2:
- move LVDS port schema to a $defs and reference it from there
- properties are now defined in microvolts/ohms
- use 1 property for data-lane and 1 for clock-lane LVDS voltage swing
- add 1 property which sets LVDS near-end termination
- since major change was done change the authorship to myself
---
 .../bindings/display/bridge/ti,sn65dsi83.yaml | 34 +++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
index 48a97bb3e2e0..bad6f5c81b06 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
@@ -80,12 +80,12 @@ properties:
                   - const: 4
 
       port at 2:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-A output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
       port at 3:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-B output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
     required:
       - port at 0
@@ -96,6 +96,36 @@ required:
   - reg
   - ports
 
+$defs:
+  lvds-port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    unevaluatedProperties: false
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          ti,lvds-termination-ohms:
+            description: The value of near end differential termination in ohms.
+            enum: [100, 200]
+            default: 200
+
+          ti,lvds-vod-swing-clock-microvolt:
+            description: LVDS diferential output voltage <min max> for clock
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
+          ti,lvds-vod-swing-data-microvolt:
+            description: LVDS diferential output voltage <min max> for data
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
 allOf:
   - if:
       properties:
-- 
2.34.1



From andrej.picej at norik.com  Thu Dec 12 04:17:12 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Thu, 12 Dec 2024 13:17:12 +0100
Subject: [PATCH v6 3/3] arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing
In-Reply-To: <20241212121712.214639-1-andrej.picej@norik.com>
References: <20241212121712.214639-1-andrej.picej@norik.com>
Message-ID: <20241212121712.214639-4-andrej.picej@norik.com>

Set custom differential output voltage for LVDS, to fulfill requirements
of the connected display. LVDS differential voltage for data-lanes and
clock output has to be between 200 mV and 600 mV.
Driver sets 200 Ohm near-end termination by default.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v6:
- no change
Changes in v5:
- no change
Changes in v4:
- no change
Changes in v3:
- no change
Changes in v2:
- use new properties from previous patches
---
 .../boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso     | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
index a9de42cf14be..8bf9cc553bea 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
@@ -186,6 +186,8 @@ port at 2 {
 			reg = <2>;
 			bridge_out: endpoint {
 				remote-endpoint = <&panel_in>;
+				ti,lvds-vod-swing-clock-microvolt = <200000 600000>;
+				ti,lvds-vod-swing-data-microvolt = <200000 600000>;
 			};
 		};
 	};
-- 
2.34.1



From krzk at kernel.org  Thu Dec 12 04:23:13 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Dec 2024 13:23:13 +0100
Subject: [PATCH v2 1/8] dt-bindings: mailbox: mediatek: Add GCE header
 file for MT8196
In-Reply-To: <ce68d58f78d12317cab689e0ee1c02dc373d50dc.camel@mediatek.com>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
 <20241211032256.28494-2-jason-jh.lin@mediatek.com>
 <ozifi65uycmxc5hqeu4onbths5u7dg532iufjxplsjw4jjmhf6@6bdsaabd7hl7>
 <04f7bd2a7d69ab7d02c88cf05bda5ae0c4cb6573.camel@mediatek.com>
 <e9caf0fe-a77f-40cb-9fc3-9da3d95f27ca@kernel.org>
 <ce68d58f78d12317cab689e0ee1c02dc373d50dc.camel@mediatek.com>
Message-ID: <5d48f335-7b14-487b-ba08-6354d21d8993@kernel.org>

On 12/12/2024 12:24, Jason-JH Lin (???) wrote:
>>>>
>>>> On Wed, Dec 11, 2024 at 11:22:49AM +0800, Jason-JH.Lin wrote:
>>>>> Add the Global Command Engine (GCE) header file to define the
>>>>> GCE
>>>>> thread priority, GCE subsys ID and GCE events for MT8196.
>>>>
>>>> This we see from the diff. What we do not see is why priority is
>>>> a
>>>> binding. Looking briefly at existing code: it is not a binding,
>>>> there
>>>> is
>>>> no driver user.
>>>>
>>>
>>> This priority value is used to configure the priority level for
>>> each
>>> GCE hardware thread, so it is a necessary hardware attribute.
>>
>> I did not say these are not "hardware". I said these are not
>> bindings.
>> Bring arguments why these are bindings.
>>
> 
> Not only bringing arguments, we use it to configure each GCE thread's
> priority.
> 
> Please forgive me to ask a trivial question.
> Do you mean if there is no driver using it directly, then it can not be
> a binding?

Here:
<qqqwdzmcnkuga6qvvszgg7o2myb26sld5i37e4konhln2n4cgc at mwtropwj3ywv>

> Or could you give me an example for what should be binding and what
> should not be binding?

Look at all clock IDs of recent arm64 SoC clock controllers.

> 
> 
> Considering to these 3 points, I think GCE thread priority is suitable
> to be part of the Device Tree Binding:
> 
> 1. Describing Hardware Properties
> - The Device Tree is a data structure for describing hardware, and GCE
> thread priority, as part of the hardware, should be described in the
> Device Tree.

I thought we talk about bindings, not DeviceTree. Where is any
Devicetree here? Please point me to the code which is Devicetree in this
patch.


> 
> 2. Driver Usage
> - Device Tree data is used by drivers to initialize and configure
> hardware, and GCE thread priority is necessary configuration data for
> the driver. After parsing the mboxes args from DTS, CMDQ driver use it
> to configure GCE thread.

We talk about bindings, so why are you describing something else?

> 
> 3. Standardization
> - Device Tree bindings should be standardized, and GCE thread priority
> should have consistent meaning and usage across different hardware
> platforms. Looking into the latest header: mediatek,mt8188-gce.h,
> mediatek,mt6795-gce.h and mt8195-gce.h, they all have defined GCE
> thread priority.

None of above arguments have anything related to the talk here. You
invent some stuff like "standardization" or "driver usage".



> 
>>>
>>> It's hard to find where the priority is used in existing driver
>>> code
>>> because we parsed it from DTS.
>>
>> So not a binding.
>>
>>>
>>> It is used in all mediaTeks' DTS using the GCE.
>>> For example, in mt8195.dts:
>>>
>>> vdosys0: syscon at 1c01a000 {
>>>     compatible = "mediatek,mt8195-vdosys0", "mediatek,mt8195-
>>> mmsys",
>>> "syscon";
>>>     reg = <0 0x1c01a000 0 0x1000>;
>>>     mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
>>>     #clock-cells = <1>;
>>>     mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0xa000
>>> 0x1000>;
>>> }
>>>
>>> CMDQ driver(mtk-cmdq-mailbox.c) will get the args parsed from
>>> mboxes
>>> property in cmdq_xlate() and then it will store CMDQ_THR_PRIO_4 to
>>> the
>>> specific thread structure.
>>
>> So not a binding.
>>
>>> The user of CMDQ driver will send command to CMDQ driver by
>>> cmdq_mbox_send_data(), and this priority setting will be configured
>>> to
>>> GCE hardware thread.
>>
>> And other things there are the same, we do not talk only about this
>> one
>> thing. I asked last time to drop which is not a binding.
>>
>>
> 
> I just reference all the previous mediatek,mtXXXX-gce.h to add the same
> binding. Except for the GPR part I added this time, I don't know what
> else should be dropped.

Your commit msg does not help me, either. Why this is supposed to be a
binding? Basically your rationale is: someone added headers, so I call
it binding.

This is invalid argument.

Someone added junk, incorrect style or bugs, so you do the same?


> 
>> ...
>>
>>>>> +
>>>>> +/*
>>>>> + * GCE General Purpose Register (GPR) support
>>>>> + * Leave note for scenario usage here
>>>>> + */
>>>>> +/* GCE: write mask */
>>>>
>>>> That's a definite no-go. Register masks are not bindings.
>>>>
>>>
>>> I'm sorry to the confusion.
>>>
>>> These defines are the index of GCE General Purpose Register for
>>> generating instructions, they are not register masks.
>>
>> Index of register is also sounding like register.
>>
>>>
>>> The comment "/* GCE: write mask */" is briefly describe that the
>>> usage
>>> of GCE_GPR_R0 and GCE_GPR_R01 is used to store the register mask
>>> when
>>> GCE executing the WRITE instruction. And it can also store the
>>> register
>>> mask of POLL and READ instruction.
>>>
>>> I will add more words to make this comment clearer, like this:
>>> /*GCE: store the mask of instruction */
>>
>> Not sure, because I feel you just avoid doing what is right and keep
>> pushing your own narrative. Where is it used in the driver?
>>
>> I just looked for "GCE_GPR_R00" - no usage at all. So not a binding.
>>
> 
> Currently, GCE_GPR_R15 is used for generating POLL instruction and it
> has been defined as a MACRO `#define CMDQ_POLL_ADDR_GPR (15)`
> in mtk-cmdq-helper.c.

I search for GCE_GPR_R15. No usage at all.

Point me to specific line in your code. Paste it here.

Above #define does not use.

I am finishing replying, because you keep avoiding actual answers and
bring some false proves forcing me to re-iterate the same over and over.

Point to specific line of code and you point to something else and then
claim this is argument in discussion.



Best regards,
Krzysztof


From qperret at google.com  Thu Dec 12 04:27:09 2024
From: qperret at google.com (Quentin Perret)
Date: Thu, 12 Dec 2024 12:27:09 +0000
Subject: [PATCH v3 4/6] arm64/kvm: Avoid invalid physical addresses to
 signal owner updates
In-Reply-To: <CAMj1kXERuRK_MdHJOY+SKR=BJ-Yi+q0FNgVayq3W_jL9zdjLVA@mail.gmail.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
 <20241212081841.2168124-12-ardb+git@google.com>
 <Z1rJ_dMJJzGOmjNs@google.com>
 <CAMj1kXERuRK_MdHJOY+SKR=BJ-Yi+q0FNgVayq3W_jL9zdjLVA@mail.gmail.com>
Message-ID: <Z1rWnejzN5Zk8TDU@google.com>

On Thursday 12 Dec 2024 at 12:44:38 (+0100), Ard Biesheuvel wrote:
> On Thu, 12 Dec 2024 at 12:33, Quentin Perret <qperret at google.com> wrote:
> >
> > On Thursday 12 Dec 2024 at 09:18:46 (+0100), Ard Biesheuvel wrote:
> > > @@ -908,6 +892,9 @@ static bool stage2_leaf_mapping_allowed(const struct kvm_pgtable_visit_ctx *ctx,
> > >       if (data->force_pte && ctx->level < KVM_PGTABLE_LAST_LEVEL)
> > >               return false;
> > >
> > > +     if (data->annotation && ctx->level == KVM_PGTABLE_LAST_LEVEL)
> > > +             return true;
> > > +
> >
> > I don't think it's a problem, but what's the rationale for checking
> > ctx->level here? The data->force_pte logic should already do this for us
> > and be somewhat orthogonal to data->annotation, no?
> >
> 
> So you are saying this could be
> 
> > > +     if (data->annotation)
> > > +             return true;
> 
> right?

Yep, exactly.

> That hides the fact that we expect data->annotation to imply
> data->force_pte, but other than that, it should work the same, yes.

Eventually we'll want to make the two orthogonal to each other (e.g. to
annotate blocks when donating huge pages to protected guests), but
that'll require more work so again I don't mind that check in the
current code. We can always get rid of it when annotations on blocks
are supported.

Cheers,
Quentin


From christophe.jaillet at wanadoo.fr  Thu Dec 12 04:33:32 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Thu, 12 Dec 2024 13:33:32 +0100
Subject: [PATCH v6 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <20241212121712.214639-3-andrej.picej@norik.com>
References: <20241212121712.214639-1-andrej.picej@norik.com>
 <20241212121712.214639-3-andrej.picej@norik.com>
Message-ID: <45f90007-3136-4b59-a3fc-6fc0147b8ad8@wanadoo.fr>

Le 12/12/2024 ? 13:17, Andrej Picej a ?crit?:
> Add a optional properties to change LVDS output voltage. This should not
> be static as this depends mainly on the connected display voltage
> requirement. We have three properties:
> - "ti,lvds-termination-ohms", which sets near end termination,
> - "ti,lvds-vod-swing-data-microvolt" and
> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> output voltage for data and clock lanes. They are defined as an array
> with min and max values. The appropriate bitfield will be set if
> selected constraints can be met.
> 
> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> end termination will be used. Selecting only one:
> "ti,lvds-vod-swing-data-microvolt" or
> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> constraint for only data/clock lanes will be met. Setting both is
> recommended.

...

> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
> +	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
> +{
> +	int i;
> +
> +	for (i = 0; i <= 3; i++) {
> +		if (lvds_vod_swing_data_table[lvds_term][i][0] >= lvds_vod_swing_data[0] &&
> +		lvds_vod_swing_data_table[lvds_term][i][1] <= lvds_vod_swing_data[1] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
> +		lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])

Adding a few spaces to align things would help reading.

> +			return i;
> +	}
> +
> +	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
> +	return -EINVAL;
> +}
> +
> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> +{
> +	struct device *dev = ctx->dev;
> +	struct device_node *endpoint;
> +	int endpoint_reg;
> +	/* Set so the property can be freely selected if not defined */
> +	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
> +	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
> +	/* Set default near end terminataion to 200 Ohm */
> +	u32 lvds_term = 200;
> +	int lvds_vod_swing_conf;
> +	int ret = 0;
> +	int ret_data;
> +	int ret_clock;
> +
> +	if (channel == CHANNEL_A)
> +		endpoint_reg = 2;
> +	else
> +		endpoint_reg = 3;
> +
> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
> +
> +	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
> +	if (lvds_term == 100)
> +		ctx->lvds_term_conf[channel] = OHM_100;
> +	else if (lvds_term == 200)
> +		ctx->lvds_term_conf[channel] = OHM_200;
> +	else
> +		return -EINVAL;

Should it be:
	else {
		ret = -EINVAL;
		goto exit;
	}
?

> +
> +	ret_data = of_property_read_u32_array(endpoint, "ti,lvds-vod-swing-data-microvolt",
> +					lvds_vod_swing_data, ARRAY_SIZE(lvds_vod_swing_data));
> +	if (ret_data != 0 && ret_data != -EINVAL) {
> +		ret = ret_data;
> +		goto exit;
> +	}
> +
> +	ret_clock = of_property_read_u32_array(endpoint, "ti,lvds-vod-swing-clock-microvolt",
> +					lvds_vod_swing_clk, ARRAY_SIZE(lvds_vod_swing_clk));
> +	if (ret_clock != 0 && ret_clock != -EINVAL) {
> +		ret = ret_clock;
> +		goto exit;
> +	}
> +
> +	/* Use default value if both properties are NOT defined. */
> +	if (ret_data == -EINVAL && ret_clock == -EINVAL)
> +		lvds_vod_swing_conf = 0x1;
> +
> +	/* Use lookup table if any of the two properties is defined. */
> +	if (!ret_data || !ret_clock) {
> +		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev, lvds_vod_swing_data,
> +						lvds_vod_swing_clk, ctx->lvds_term_conf[channel]);
> +		if (lvds_vod_swing_conf < 0) {
> +			ret = lvds_vod_swing_conf;
> +			goto exit;
> +		}
> +	}
> +
> +	ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
> +	ret = 0;
> +exit:
> +	of_node_put(endpoint);
> +	return ret;
> +}

...

CJ


From sudeep.holla at arm.com  Thu Dec 12 04:46:37 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 12 Dec 2024 12:46:37 +0000
Subject: Fwd: ARM64: CPUIdle driver is not select any Idle state other
 then WFI
In-Reply-To: <20241211143428.kaoovhiwar74dy6x@lcpd911>
References: <CAO6a-9_aPLCx2CqecQBGbK78_=+-tT44RepPkrBjpkWSvjj4Tg@mail.gmail.com>
 <CAO6a-98cdSvyd7jgAyGNmsC2nxmRSyr3GppxvZU9yHU1xqwz3g@mail.gmail.com>
 <20241211055052.gbxnyqpui3t3zpw5@lcpd911>
 <20241211121825.GA2054801@bogus>
 <20241211143428.kaoovhiwar74dy6x@lcpd911>
Message-ID: <Z1rbLdWW75KQw5cl@bogus>

On Wed, Dec 11, 2024 at 08:04:28PM +0530, Dhruva Gole wrote:
> On Dec 11, 2024 at 12:18:25 +0000, Sudeep Holla wrote:
> > On Wed, Dec 11, 2024 at 11:20:52AM +0530, Dhruva Gole wrote:
> [...]
> > > >
> > > >
> > > > Hi @all,
> > > >
> > > > I am working on one custom SoC. Where I add one CPUIdle state for
> > > > ``arm,cortex-a55`` processor.
> > >
> > > Any further luck on this?
> > >
> > > I have also been working on something similar[1] but on an A53 core on
> > > TI-K3 AM62x processor.
> > 
> > Does upstream DTS have support for this platform to understand it better ?
> > Even reference to any complete DT file for the platform will help.
> 
> Yes, you can ref to the AM625 (CPU layout) DT here:
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/ti/k3-am625.dtsi
> 
> The board/starter kit DT is:
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/ti/k3-am625-sk.dts
> 
> The patches for idle state are not upstream, and only exist in this
> patch of mine here:
> https://github.com/DhruvaG2000/v-linux/commit/0fd088d624276a2e72b8dc6660d261ab6d194f4b
>

"arm,psci-suspend-param" indicate that this idle state doesn't loose the
cpu context which means timer doesn't stop. So adding "local-timer-stop"
sound completely wrong to me.

> [...]
> > > See this chunk in the kernel cpuidle driver:
> > > 	if (broadcast && tick_broadcast_enter()) {
> > >
> > > When I dug deeper into tick_broadcast_enter it always returns something
> > > non zero and hence in my case it was entering the if block and tried to
> > > find a deepest state. Then the deepest state would always return WFI and
> > > not the idle-state I had added.
> > >

It depends. If this is the last CPU and since you have marked the state with
"local-timer-stop" and the system doesn't have any other timers to use as
source of broadcast, it prevents one of the CPU entering that state. So you
could be matching all the above conditions on your platform and hence you
are observing the above.

> > > What we found out was on our kernel we end up using
> > >
> > > kernel/time/tick-broadcast-hrtimer.c
> > >
> > > This always seems to be keeping atleast 1 CPU busy and prevents idle.
> > > If we remove the local-timer-stop it was helping us, but we still need
> > > to dig into the full impact of what that entails and I am still
> > > interested in finding out how so many other users of similar idle-state
> > > implementation are able to do so without trouble.
> > >
> >

As mentioned about adding "local-timer-stop" for a retention state seems
pure wrong in my opinion as it contradicts to the fact that context is
retained.

> > Interesting. So if the platform is functional removing local-timer-stop,
> > I am bit confused. Either there is something else that is getting it out
>
> Yes it was interesting to us too, as to how the RCU didn't kick in and
> system continued to function as though nothing was wrong.
>

It worked as if it was a state with context lost. So there might be some
impact on the latency though it as the kernel assumed context lost and
re-entered/resumed through resume entry point rather than where it called
cpu_suspend() similar to wfi(). I mean only on the CPUs it was able to
enter this state as one of the CPU will never enter this if there are no
system timers to act as broadcast timer.

Does you system not have Arch timers memory mapped interface enabled and
interrupt wired to GIC(other than PPIs) ? Look at Juno R2 as example.

> > from the idle state so, it should be fine and it could be just some
> 
> It's probably UART keypresses or some userspace processes that get
> scheduled that bring the CPUs back out of TF-A's cpu_standby.

I doubt the CPU resume from suspend is based on some userspace event.

> Is it possible that EL1 interrupts can bring EL3 out of WFI? Is yes then
> it explains the behaviour. The arch timer could also be continuing to
> tick and bringing the CPUs out of ATF WFI.
>

Yes but that doesn't explain the behaviour. It could be just the timer
event from the broadcast timer.

> > misconfiguration.
> > 
> > > Arm64 recommends to use arch_timer instead of external timers. Once we
> > > enter el3, timer interrupts to el1 is blocked and hence it's equivalent
> > > to local-timer-stop, so it does make sense to keep this property, but
> > > then how are others able to enter idle-states for all plugged CPUs at
> > > the same time?
> > >
> > 
> > Some systems have system timer that can take over as broadcast timer when
> > CPUs enter deeper idle states where the local timers are stopped.
> 
> In CPUIdle we're not really clock gating anything so the timer does keep
> ticking. So in this particular case it might make sense to remove the
> local-timer-stop property from the idle-state.
>

Correct in your case it is retention state and hence local CPU timers
keep ticking and you can safely drop that property. However if you add
deeper idle states like CPU OFF with the power rail cut off, then you need
some system timer to act as backup/broadcast timer so that all the CPUs
can enter the state concurrently and wake up successfully.

> However we're looking into taking this further and putting interconnect
> and few other PLLs in bypass which could cause arch timer for eg. to
> tick slower.

I assume it will be present as another timer with the rate set appropriately.

> In this case would it still make sense to omit the property? 

No, you should mark it as stopped even if it is running at slower rate
as I am not sure if the local CPU timer support can handle rate change.

> We may even have some usecases planned where we may turn OFF
> the CPU once it is in TF-A cpu_standby/ WFI. What would be the right
> approach in such scenarios?
>

As mentioned above, this will be separate state and all CPUs can use this
if there is another system broadcast timer.

> Could you provide any examples where the local-timer-stop property is
> being used and an alternative timer can be configured once we enter the
> idle-state where CPU CTX maybe lost or clocks maybe bypass?
> great if you could share some example implementation if you're aware.

As I mentioned, Juno R2 is an example. It was broken on R0 with some SoC
errata(can't recall all the details as I looked at it almost a decade ago)

-- 
Regards,
Sudeep


From broonie at kernel.org  Thu Dec 12 04:51:42 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 12 Dec 2024 12:51:42 +0000
Subject: (subset) [PATCH 0/8] arm64: dts: mediatek: Drop
 regulator-compatible property
In-Reply-To: <20241211052427.4178367-1-wenst@chromium.org>
References: <20241211052427.4178367-1-wenst@chromium.org>
Message-ID: <173400790262.46374.4565987048605318462.b4-ty@kernel.org>

On Wed, 11 Dec 2024 13:24:18 +0800, Chen-Yu Tsai wrote:
> This series drops usage of the long deprecated "regulator-compatible"
> property from MediaTek device tree files. The property was introduced
> in 2012, and then subsequently deprecated after two months. It was
> never carried over during the binding YAML conversion.
> 
> Drop the property from the MT6315 regulator binding, and all MediaTek
> device tree files. IMO it should never have been used to begin with.
> This also gets rid of any validation errors [1] related to them.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[1/8] regulator: dt-bindings: mt6315: Drop regulator-compatible property
      commit: 08242719a8af603db54a2a79234a8fe600680105

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 mark.kettenis at xs4all.nl  Thu Dec 12 05:02:45 2024
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Thu, 12 Dec 2024 14:02:45 +0100
Subject: Question about interrupt prioriyt of ARM GICv3/4
In-Reply-To: <86ldwlryzz.wl-maz@kernel.org> (message from Marc Zyngier on Thu,
	12 Dec 2024 10:12:32 +0000)
References: <CAJNi4rMfhZOCT+7Ki14vUs+dZbv9cxCZ0s+jgn6=_om4NTgo_A@mail.gmail.com>
	<86cyi5tanz.wl-maz@kernel.org>
	<CAJNi4rPDVXS3Ft3nHLXvMzHmn9d10Nz4Pxeduoe+v5HaK=CEAg@mail.gmail.com> <86ldwlryzz.wl-maz@kernel.org>
Message-ID: <871pydxde2.fsf@bloch.sibelius.xs4all.nl>

> Date: Thu, 12 Dec 2024 10:12:32 +0000
> From: Marc Zyngier <maz at kernel.org>

Hi Marc, Richard,

> On Thu, 12 Dec 2024 09:18:56 +0000,
> richard clark <richard.xnu.clark at gmail.com> wrote:
> > 
> > Hi M,
> 
> Hi r,
> 
> > 
> > On Fri, Dec 6, 2024 at 5:37?PM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > On Fri, 06 Dec 2024 08:33:11 +0000,
> > > richard clark <richard.xnu.clark at gmail.com> wrote:
> > > >
> > > > Hi,
> > > > Currently seems the GICv3/4 irqchip configures all the interrupts as
> > > > the same priority, I am thinking about to minimize the latency of the
> > > > interrupt for a particular device, e.g, the arm arch_timer in the RTL
> > > > system. The question is,
> > > > 1. Why don't we provide a /proc or /sys interface for the enduser to
> > > > set the priority of a specific interrupt(SPI/PPI)?
> > >
> > > I'm afraid this really has nothing to do with any particular interrupt
> > > architecture.
> > >
> > > Before thinking of exposing the interrupt priority to userspace, you
> > > should look at what this translates into for the kernel once you allow
> > > interrupts to be preempted by another one with a higher priority.
> > >
> > Interrupt priority doesn't necessarily mean the preemption, seems
> > you're talking about the interrupt preemption harm according to your
> > statement followed.Frankly I am just thinking higher priority will win
> > the lower ones in case massive external interrupts received in the GIC
> > level (you see I am still talking about GIC, not kernel)
> 
> As I stated at the end of my email, the GIC only gives guarantee that
> you will ack the highest priority interrupt in finite time. Not right
> when it is made pending. Yes, it has the concept of HPPI. But that
> from the PoV of the CPU interface, not that of the distributor. Factor
> in the Stream interface, and you realise that expecting to always ack
> the highest priority pending interrupt is akin to expecting no
> reordering of packets in a network.
> 
> > >
> > > This means that at every point where you would normally see a
> > > local_irq_save(), spinlock_irqsave() or equivalent, you would need to
> > > explicitly specify the priority that you allow for preemption. You
> > > should then make sure that any code that can be run during an
> > > interrupt is reentrant. You need to define which data structures can
> > > be manipulated at which priority level... The list goes on.
> > >
> > irqsave just masks the interrupt from the point of cpu, I don't think
> > it will mess things up if preemption really happens (no? then what the
> > side-effect is for the nested interrupt handling in the softirq part.
> > damage the semantic of the lock primitives?)
> > >
> > > If you want a small taste of the complexity, just look at what
> > > handling NMIs (or even pseudo-NMIs in the case of GICv3) means, and
> > > generalise it to not just two, but an arbitrary range of priorities.
> > >
> > > If you want the full blown experience, look at the BSDs and their use
> > > of spl*(). I don't think anyone has any plan to get there, and the RT
> > > patches have shown that there is little need for it.
> > >
> > As supplement?the fiq is suggested to be used as an alternative to the
> > higher priority in the RT area...
> 
> <PulpFiction>
> FIQ's dead, baby. FIQ's dead.
> </PulpFiction>

Hah, tell that to Apple! ;).

> > > > 2. Is there any way to verify the higher priority interrupt will have
> > > > more dominant to be selected to the CPU (IOW, the priority is really
> > > > working) in case of multiple different interrupts asserted to the GIC
> > > > at the same time(some debug registers of GIC like GICD_REEMPT_CNT :-)
> > > > to record higher priority wins)?
> > >
> > > The GIC architecture makes no promise that the interrupt you
> > > acknowledge is the highest priority pending interrupt, because this is
> > > by definition a very racy process.
> > >
> > > Also, even on busy systems, you will very rarely see two interrupts
> > > targeting the same CPU being made pending at the same time, so that
> > > the interrupt delivery system would have to arbitrate between the two.
> > > That's because interrupts are vanishingly rare in the grand scheme of
> > > things.
> > >
> > 1. I am trying to stress the external interrupts to the core#0 via the
> > stress-ng tool with one of interrupt being configured as higher
> > priority to see the benchmark data, it's time consuming as you can
> > image, still is in progress(BTW, I can't see any lockup similar hang
> > in the system with a higher priority configured)
> 
> If you don't have preemption, I don't think anything wrong will
> happen. But I don't expect any benefit either.

Based on my experience with OpenBSD, I'm not even sure there is much
benefit even if you have preemtion.

And regarding anything wrong happening: there is an interesting bug in
the RK3399 GIC integration where it gets the priorities wrong:

https://github.com/openbsd/src/blob/feb3ea439d8f49b3c0e33f54c34631a611b98e21/sys/arch/arm64/dev/agintc.c#L395

(that comment is my interpretation of what's happening; I might be
misinterpreting what's really going on)

As far as I can tell the Linux code doesn't handle that quirk.
Probably it doesn't matter because Linux only uses the priority
mechanisms to implement pseudo-NMI functionality and/or doesn't do
preemption of interrupts.

> > 2. This raises a very interesting question and I am also very curious
> > about is, what is the purpose for the GIC to introduce the interrupt
> > priority features, a placeholder feature reserved for the future? Ah,
> > hardware prefer to provide more functionalities than its being
> > actually used by software, any other justification except that?
> 
> You realise that the HW is not exclusively designed for Linux, right?
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.
> 
> 


From wahrenst at gmx.net  Thu Dec 12 05:15:57 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Thu, 12 Dec 2024 14:15:57 +0100
Subject: Raspberry Pi 3B: Failed to create device link with
 soc:firmware:gpio
In-Reply-To: <CAFERDQ2hLHek+0ViVqbqgOD+4xwC2ZwK1KhgGdLP_zGnonEs4w@mail.gmail.com>
References: <CAFERDQ2hLHek+0ViVqbqgOD+4xwC2ZwK1KhgGdLP_zGnonEs4w@mail.gmail.com>
Message-ID: <d02a7143-43e7-4851-a06e-d57981362a5a@gmx.net>

Am 12.12.24 um 11:13 schrieb Martin Wetterwald:
> Hello Saravana and Florian,
>
> Back in 2023, you discussed about an issue concerning the Raspberry Pi 4, that
> you fixed in commit 1a5ecc73b2bfeffe036212d4a6bfacee053ab0a1:
> https://lore.kernel.org/lkml/03b70a8a-0591-f28b-a567-9d2f736f17e5 at gmail.com/
> https://lore.kernel.org/all/20230302023509.319903-1-saravanak at google.com/
>
> Today, I notice I see the same issue, but it's with the Raspberry Pi 3B (V1.2).
> I'm using the upstream kernel 6.12.3, with the upstream DTB.
>
> You can find my kernel miniconfig (basis being allnoconfig) here:
> https://gist.github.com/mwetterw/299bb1317fccf9e68125cb0f5da7384c
What happens if you replace your custom config with arm64/defconfig?
Does the issue still occurs?
>
> During boot, I see following messages:
>> Bluetooth: HCI UART driver ver 2.3
>> Bluetooth: HCI UART protocol H4 registered
>> Bluetooth: HCI UART protocol Broadcom registered
>> bcm2835-mbox 3f00b880.mailbox: mailbox enabled
>> 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 99, base_baud = 0) is a PL011 rev2
>> raspberrypi-firmware soc:firmware: Attached to firmware from 2024-09-13T16:00:14
>> uart-pl011 3f201000.serial: Failed to create device link (0x180) with soc:firmware:gpio
> Here is an extract of the relevant FDT nodes.
> Because my setup involves first the proprietary GPU firmware, then the U-Boot
> bootloader before finally launching the kernel, I used following command in
> order to make sure I see the same FDT as Linux:
>
>> ssh rpi 'cat /sys/firmware/fdt' | fdtdump -
>> firmware {
>>      compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
>>      mboxes = <0x0000001b>;
>>      phandle = <0x0000001c>;
>>      clocks {
>>          compatible = "raspberrypi,firmware-clocks";
>>          #clock-cells = <0x00000001>;
>>          phandle = <0x00000015>;
>>      };
>>      gpio {
>>          compatible = "raspberrypi,firmware-gpio";
>>          gpio-controller;
>>          #gpio-cells = <0x00000002>;
>>          gpio-line-names = "BT_ON", "WL_ON", "STATUS_LED", "LAN_RUN", "HDMI_HPD_N", "CAM_GPIO0", "CAM_GPIO1", "PWR_LOW_N";
>>          status = "okay";
>>          phandle = <0x0000000a>;
>>      };
>> };
>> serial at 7e201000 {
>>      compatible = "arm,pl011", "arm,primecell";
>>      reg = <0x7e201000 0x00000200>;
>>      interrupts = <0x00000002 0x00000019>;
>>      clocks = <0x00000007 0x00000013 0x00000007 0x00000014>;
>>      clock-names = "uartclk", "apb_pclk";
>>      arm,primecell-periphid = <0x00241011>;
>>      status = "okay";
>>      pinctrl-names = "default";
>>      pinctrl-0 = <0x00000008 0x00000009>;
>>      phandle = <0x00000048>;
>>      bluetooth {
>>          compatible = "brcm,bcm43438-bt";
>>          max-speed = <0x001e8480>;
>>          shutdown-gpios = <0x0000000a 0x00000000 0x00000000>;
>>          phandle = <0x00000049>;
>>      };
>> };
> If I understand correctly, the serial dev bus, together with
> CONFIG_BT_HCI_UART, CONFIG_BT_HCI_UART_BCM, and if associated to the correct
> DTB nodes describing the bluetooth chip, should allow the kernel to handle the
> serial Bluetooth HCI himself, without the userspace needing to launch user
> space tools like hciattach or btattach?
>
> Is the log
>
>> uart-pl011 3f201000.serial: Failed to create device link (0x180) with soc:firmware:gpio
> a hint to the reason why the kernel doesn't automatically handle my Bluetooth
> HCI over serial?
>
> How to solve this log error, and how to let the kernel handle the HCI himself?
> Am I missing kernel configuration flags?
>
> Thanks!
> Martin
>



From yangchen.openbmc at gmail.com  Thu Dec 12 05:32:23 2024
From: yangchen.openbmc at gmail.com (Yang Chen)
Date: Thu, 12 Dec 2024 21:32:23 +0800
Subject: [PATCH v1 1/4] ARM: dts: aspeed: minerva: add i/o expanders on bus 0
In-Reply-To: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
References: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
Message-ID: <20241212133226.342937-2-yangchen.openbmc@gmail.com>

Add three I/O expanders on i2c bus 0, assign the GPIO line name to each
GPIO in use, and specify the interrupt GPIO that has been used on it and
give the interrupt gpio number.

Signed-off-by: Yang Chen <yangchen.openbmc at gmail.com>
---
 .../aspeed/aspeed-bmc-facebook-minerva.dts    | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
index 468a33f50ef2..426e249c3326 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
@@ -208,6 +208,63 @@ leds_gpio: gpio at 19 {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
+
+	gpio at 11 {
+		compatible = "nxp,pca9555";
+		reg = <0x11>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <238 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+		"PWRGD_P24V_SMPWROK", "P1V5_PWROK",
+		"P3V3_PWROK", "P5V_PWROK",
+		"P12V_SCM_PWROK", "P12V_PWROK",
+		"P24V_PWROK", "P48V_HSC_PWROK",
+		"ERR_GPIO_IRQ", "TMP75_ALERT_N",
+		"BMC_PWROK", "P12V_INA230_ALERT_N",
+		"P24V_INA230_ALERT_N","",
+		"P48V_HSC_ALERT_N", "P1V05_PWROK";
+	};
+
+	gpio at 12 {
+		compatible = "nxp,pca9555";
+		reg = <0x12>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <240 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+		"P1V05_PWR_FAIL", "P1V5_PWR_FAIL",
+		"P24V_PWR_FAIL", "P24V_SM_PWR_FAIL",
+		"IRQ_NW0/1/2_N", "IRQ_NW3/4/5_N",
+		"RTC_INT_N_R", "ERR_GPIO_IRQ",
+		"", "",
+		"", "",
+		"", "",
+		"", "";
+	};
+
+	gpio at 13 {
+		compatible = "nxp,pca9555";
+		reg = <0x13>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <242 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+		"", "",
+		"", "",
+		"", "",
+		"", "",
+		"RACKMON_A_1", "RACKMON_A_2",
+		"RACKMON_B_1", "RACKMON_B_2",
+		"", "",
+		"", "";
+	};
 };
 
 &i2c1 {
-- 
2.34.1



From yangchen.openbmc at gmail.com  Thu Dec 12 05:32:24 2024
From: yangchen.openbmc at gmail.com (Yang Chen)
Date: Thu, 12 Dec 2024 21:32:24 +0800
Subject: [PATCH v1 2/4] ARM: dts: aspeed: minerva: add i/o expanders on each FCB
In-Reply-To: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
References: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
Message-ID: <20241212133226.342937-3-yangchen.openbmc@gmail.com>

Add four I/O expanders on each i2c of fan control board (FCB), assign the
GPIO line name to each GPIO in use, and specify the interrupt GPIO number
for each FCB's i/o expander.

Signed-off-by: Yang Chen <yangchen.openbmc at gmail.com>
---
 .../aspeed/aspeed-bmc-facebook-minerva.dts    | 456 ++++++++++++++++++
 1 file changed, 456 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
index 426e249c3326..9cd225ae96cb 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
@@ -342,6 +342,82 @@ temperature-sensor at 4b {
 				compatible = "ti,tmp75";
 				reg = <0x4b>;
 			};
+
+			gpio at 11 {
+				compatible = "nxp,pca9555";
+				reg = <0x11>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <218 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"P48V_FAN1_PWRGD_R", "P48V_FAN2_PWRGD_R",
+				"P48V_FAN3_PWRGD_R", "P48V_FAN4_PWRGD_R",
+				"FCB_1_P48V_ZONE0_PWRGD_R", "FCB_1_P48V_ZONE1_PWRGD_R",
+				"FCB_1_PWRGD_P3V3_R", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 12 {
+				compatible = "nxp,pca9555";
+				reg = <0x12>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <218 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"INA238_FAN1_ALERT_N", "INA238_FAN2_ALERT_N",
+				"INA238_FAN3_ALERT_N", "INA238_FAN4_ALERT_N",
+				"FCB_1_TMP75_ALERT_N", "",
+				"", "",
+				"FAN1_PRSNT", "FAN2_PRSNT",
+				"FAN3_PRSNT", "FAN4_PRSNT",
+				"", "",
+				"", "";
+			};
+
+			gpio at 13 {
+				compatible = "nxp,pca9555";
+				reg = <0x13>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <218 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FAN1_IL_TACH_ALERT", "FAN1_OL_TACH_ALERT",
+				"FAN2_IL_TACH_ALERT", "FAN2_OL_TACH_ALERT",
+				"FAN3_IL_TACH_ALERT", "FAN3_OL_TACH_ALERT",
+				"FAN4_IL_TACH_ALERT", "FAN4_IL_TACH_ALERT",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 17 {
+				compatible = "nxp,pca9555";
+				reg = <0x17>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <218 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FCB_1_P1V0_POWER_FAIL", "FCB_1_P1V8_POWER_FAIL",
+				"FCB_1_P48V_ZONE0_POWER_FAIL", "FAN1_POWER_FAIL",
+				"FAN2_POWER_FAIL", "FAN3_POWER_FAIL",
+				"FAN4_POWER_FAIL", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
 		};
 		// FCB 2
 		imux17: i2c at 0 {
@@ -389,6 +465,82 @@ temperature-sensor at 4b {
 				compatible = "ti,tmp75";
 				reg = <0x4b>;
 			};
+
+			gpio at 11 {
+				compatible = "nxp,pca9555";
+				reg = <0x11>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <220 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"P48V_FAN5_PWRGD_R", "P48V_FAN6_PWRGD_R",
+				"P48V_FAN7_PWRGD_R", "P48V_FAN8_PWRGD_R",
+				"FCB_2_P48V_ZONE0_PWRGD_R", "FCB_2_P48V_ZONE1_PWRGD_R",
+				"FCB_2_PWRGD_P3V3_R", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 12 {
+				compatible = "nxp,pca9555";
+				reg = <0x12>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <220 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"INA238_FAN5_ALERT_N", "INA238_FAN6_ALERT_N",
+				"INA238_FAN7_ALERT_N", "INA238_FAN8_ALERT_N",
+				"FCB_2_TMP75_ALERT_N", "",
+				"", "",
+				"FAN5_PRSNT", "FAN6_PRSNT",
+				"FAN7_PRSNT", "FAN8_PRSNT",
+				"", "",
+				"", "";
+			};
+
+			gpio at 13 {
+				compatible = "nxp,pca9555";
+				reg = <0x13>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <220 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FAN5_IL_TACH_ALERT", "FAN5_OL_TACH_ALERT",
+				"FAN6_IL_TACH_ALERT", "FAN6_OL_TACH_ALERT",
+				"FAN7_IL_TACH_ALERT", "FAN7_OL_TACH_ALERT",
+				"FAN8_IL_TACH_ALERT", "FAN8_IL_TACH_ALERT",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 17 {
+				compatible = "nxp,pca9555";
+				reg = <0x17>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <220 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FCB_2_P1V0_POWER_FAIL", "FCB_2_P1V8_POWER_FAIL",
+				"FCB_2_P48V_ZONE0_POWER_FAIL", "FAN5_POWER_FAIL",
+				"FAN6_POWER_FAIL", "FAN7_POWER_FAIL",
+				"FAN8_POWER_FAIL", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
 		};
 		// FCB 3
 		imux18: i2c at 3 {
@@ -436,6 +588,82 @@ temperature-sensor at 4b {
 				compatible = "ti,tmp75";
 				reg = <0x4b>;
 			};
+
+			gpio at 11 {
+				compatible = "nxp,pca9555";
+				reg = <0x11>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <230 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"P48V_FAN9_PWRGD_R", "P48V_FAN10_PWRGD_R",
+				"P48V_FAN11_PWRGD_R", "P48V_FAN12_PWRGD_R",
+				"FCB_3_P48V_ZONE0_PWRGD_R", "FCB_3_P48V_ZONE1_PWRGD_R",
+				"FCB_3_PWRGD_P3V3_R", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 12 {
+				compatible = "nxp,pca9555";
+				reg = <0x12>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <230 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"INA238_FAN9_ALERT_N", "INA238_FAN10_ALERT_N",
+				"INA238_FAN11_ALERT_N", "INA238_FAN12_ALERT_N",
+				"FCB_3_TMP75_ALERT_N", "",
+				"", "",
+				"FAN9_PRSNT", "FAN10_PRSNT",
+				"FAN11_PRSNT", "FAN12_PRSNT",
+				"", "",
+				"", "";
+			};
+
+			gpio at 13 {
+				compatible = "nxp,pca9555";
+				reg = <0x13>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <230 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FAN9_IL_TACH_ALERT", "FAN9_OL_TACH_ALERT",
+				"FAN10_IL_TACH_ALERT", "FAN10_OL_TACH_ALERT",
+				"FAN11_IL_TACH_ALERT", "FAN11_OL_TACH_ALERT",
+				"FAN12_IL_TACH_ALERT", "FAN12_IL_TACH_ALERT",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 17 {
+				compatible = "nxp,pca9555";
+				reg = <0x17>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <230 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FCB_3_P1V0_POWER_FAIL", "FCB_3_P1V8_POWER_FAIL",
+				"FCB_3_P48V_ZONE0_POWER_FAIL", "FAN9_POWER_FAIL",
+				"FAN10_POWER_FAIL", "FAN11_POWER_FAIL",
+				"FAN12_POWER_FAIL", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
 		};
 		// FCB 4
 		imux19: i2c at 2 {
@@ -483,6 +711,82 @@ temperature-sensor at 4b {
 				compatible = "ti,tmp75";
 				reg = <0x4b>;
 			};
+
+			gpio at 11 {
+				compatible = "nxp,pca9555";
+				reg = <0x11>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <232 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"P48V_FAN13_PWRGD_R", "P48V_FAN14_PWRGD_R",
+				"P48V_FAN15_PWRGD_R", "P48V_FAN16_PWRGD_R",
+				"FCB_4_P48V_ZONE0_PWRGD_R", "FCB_4_P48V_ZONE1_PWRGD_R",
+				"FCB_4_PWRGD_P3V3_R", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 12 {
+				compatible = "nxp,pca9555";
+				reg = <0x12>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <232 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"INA238_FAN13_ALERT_N", "INA238_FAN14_ALERT_N",
+				"INA238_FAN15_ALERT_N", "INA238_FAN16_ALERT_N",
+				"FCB_4_TMP75_ALERT_N", "",
+				"", "",
+				"FAN13_PRSNT", "FAN14_PRSNT",
+				"FAN15_PRSNT", "FAN16_PRSNT",
+				"", "",
+				"", "";
+			};
+
+			gpio at 13 {
+				compatible = "nxp,pca9555";
+				reg = <0x13>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <232 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FAN13_IL_TACH_ALERT", "FAN13_OL_TACH_ALERT",
+				"FAN14_IL_TACH_ALERT", "FAN14_OL_TACH_ALERT",
+				"FAN15_IL_TACH_ALERT", "FAN15_OL_TACH_ALERT",
+				"FAN16_IL_TACH_ALERT", "FAN16_IL_TACH_ALERT",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 17 {
+				compatible = "nxp,pca9555";
+				reg = <0x17>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <232 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FCB_4_P1V0_POWER_FAIL", "FCB_4_P1V8_POWER_FAIL",
+				"FCB_4_P48V_ZONE0_POWER_FAIL", "FAN13_POWER_FAIL",
+				"FAN14_POWER_FAIL", "FAN15_POWER_FAIL",
+				"FAN16_POWER_FAIL", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
 		};
 		// FCB 5
 		imux20: i2c at 4 {
@@ -529,6 +833,82 @@ temperature-sensor at 4b {
 				compatible = "ti,tmp75";
 				reg = <0x4b>;
 			};
+
+			gpio at 11 {
+				compatible = "nxp,pca9555";
+				reg = <0x11>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <254 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"P48V_FAN20_PWRGD_R", "P48V_FAN19_PWRGD_R",
+				"P48V_FAN18_PWRGD_R", "P48V_FAN17_PWRGD_R",
+				"FCB_5_P48V_ZONE0_PWRGD_R", "FCB_5_P48V_ZONE1_PWRGD_R",
+				"FCB_5_PWRGD_P3V3_R", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 12 {
+				compatible = "nxp,pca9555";
+				reg = <0x12>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <254 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"INA238_FAN20_ALERT_N", "INA238_FAN19_ALERT_N",
+				"INA238_FAN18_ALERT_N", "INA238_FAN17_ALERT_N",
+				"FCB_5_TMP75_ALERT_N", "",
+				"", "",
+				"FAN20_PRSNT", "FAN19_PRSNT",
+				"FAN18_PRSNT", "FAN17_PRSNT",
+				"", "",
+				"", "";
+			};
+
+			gpio at 13 {
+				compatible = "nxp,pca9555";
+				reg = <0x13>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <254 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FAN20_IL_TACH_ALERT", "FAN20_OL_TACH_ALERT",
+				"FAN19_IL_TACH_ALERT", "FAN19_OL_TACH_ALERT",
+				"FAN18_IL_TACH_ALERT", "FAN18_OL_TACH_ALERT",
+				"FAN17_IL_TACH_ALERT", "FAN17_OL_TACH_ALERT",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 17 {
+				compatible = "nxp,pca9555";
+				reg = <0x17>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <254 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FCB_5_P1V0_POWER_FAIL", "FCB_5_P1V8_POWER_FAIL",
+				"FCB_5_P48V_ZONE0_POWER_FAIL", "FAN20_POWER_FAIL",
+				"FAN19_POWER_FAIL", "FAN18_POWER_FAIL",
+				"FAN17_POWER_FAIL", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
 		};
 		// FCB 6
 		imux21: i2c at 5 {
@@ -575,6 +955,82 @@ temperature-sensor at 4b {
 				compatible = "ti,tmp75";
 				reg = <0x4b>;
 			};
+
+			gpio at 11 {
+				compatible = "nxp,pca9555";
+				reg = <0x11>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <252 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"P48V_FAN24_PWRGD_R", "P48V_FAN23_PWRGD_R",
+				"P48V_FAN22_PWRGD_R", "P48V_FAN21_PWRGD_R",
+				"FCB_6_P48V_ZONE0_PWRGD_R", "FCB_6_P48V_ZONE1_PWRGD_R",
+				"FCB_6_PWRGD_P3V3_R", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 12 {
+				compatible = "nxp,pca9555";
+				reg = <0x12>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <252 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"INA238_FAN24_ALERT_N", "INA238_FAN23_ALERT_N",
+				"INA238_FAN22_ALERT_N", "INA238_FAN21_ALERT_N",
+				"FCB_6_TMP75_ALERT_N", "",
+				"", "",
+				"FAN24_PRSNT", "FAN23_PRSNT",
+				"FAN22_PRSNT", "FAN21_PRSNT",
+				"", "",
+				"", "";
+			};
+
+			gpio at 13 {
+				compatible = "nxp,pca9555";
+				reg = <0x13>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <252 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FAN24_IL_TACH_ALERT", "FAN24_OL_TACH_ALERT",
+				"FAN23_IL_TACH_ALERT", "FAN23_OL_TACH_ALERT",
+				"FAN22_IL_TACH_ALERT", "FAN22_OL_TACH_ALERT",
+				"FAN21_IL_TACH_ALERT", "FAN21_OL_TACH_ALERT",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
+
+			gpio at 17 {
+				compatible = "nxp,pca9555";
+				reg = <0x17>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&sgpiom0>;
+				interrupts = <252 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+				"FCB_6_P1V0_POWER_FAIL", "FCB_6_P1V8_POWER_FAIL",
+				"FCB_6_P48V_ZONE0_POWER_FAIL", "FAN24_POWER_FAIL",
+				"FAN23_POWER_FAIL", "FAN22_POWER_FAIL",
+				"FAN21_POWER_FAIL", "",
+				"", "",
+				"", "",
+				"", "",
+				"", "";
+			};
 		};
 
 		imux22: i2c at 6 {
-- 
2.34.1



From yangchen.openbmc at gmail.com  Thu Dec 12 05:32:25 2024
From: yangchen.openbmc at gmail.com (Yang Chen)
Date: Thu, 12 Dec 2024 21:32:25 +0800
Subject: [PATCH v1 3/4] ARM: dts: aspeed: minerva: add bmc ready led setting
In-Reply-To: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
References: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
Message-ID: <20241212133226.342937-4-yangchen.openbmc@gmail.com>

Add GPIO BMC_READY on LED and give it active value and transitory flag.

Signed-off-by: Yang Chen <yangchen.openbmc at gmail.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
index 9cd225ae96cb..7fddbe833cc2 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
@@ -101,6 +101,11 @@ led-4 {
 			gpios = <&leds_gpio 10 GPIO_ACTIVE_LOW>;
 			default-state = "off";
 		};
+
+		led-5 {
+			label = "bmc_ready_noled";
+			gpios = <&sgpiom0 141 (GPIO_ACTIVE_HIGH|GPIO_TRANSITORY)>;
+		};
 	};
 
 	spi_gpio: spi {
-- 
2.34.1



From yangchen.openbmc at gmail.com  Thu Dec 12 05:32:22 2024
From: yangchen.openbmc at gmail.com (Yang Chen)
Date: Thu, 12 Dec 2024 21:32:22 +0800
Subject: [PATCH v1 0/4] Revise Meta (Facebook) Minerva BMC
Message-ID: <20241212133226.342937-1-yangchen.openbmc@gmail.com>

Revise the linux device tree entry related to Meta (Facebook) Minerva
specific devices connected to BMC (AST2600) SoC.

Base on:
https://lore.kernel.org/all/172722509817.374662.7338401100529556748.b4-ty at codeconstruct.com.au/

Yang Chen (4):
  ARM: dts: aspeed: minerva: add i/o expanders on bus 0
  ARM: dts: aspeed: minerva: add i/o expanders on each FCB
  ARM: dts: aspeed: minerva: add bmc ready led setting
  ARM: dts: aspeed: minerva: add second source RTC

 .../aspeed/aspeed-bmc-facebook-minerva.dts    | 523 ++++++++++++++++++
 1 file changed, 523 insertions(+)

-- 
2.34.1



From yangchen.openbmc at gmail.com  Thu Dec 12 05:32:26 2024
From: yangchen.openbmc at gmail.com (Yang Chen)
Date: Thu, 12 Dec 2024 21:32:26 +0800
Subject: [PATCH v1 4/4] ARM: dts: aspeed: minerva: add second source RTC
In-Reply-To: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
References: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
Message-ID: <20241212133226.342937-5-yangchen.openbmc@gmail.com>

Add second source RTC on i2c bus 9.

Signed-off-by: Yang Chen <yangchen.openbmc at gmail.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
index 7fddbe833cc2..ef96b17becb2 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-minerva.dts
@@ -1292,6 +1292,11 @@ rtc at 51 {
 		compatible = "nxp,pcf8563";
 		reg = <0x51>;
 	};
+
+	rtc at 68 {
+		compatible = "dallas,ds1339";
+		reg = <0x68>;
+	};
 };
 
 &i2c12 {
-- 
2.34.1



From svarbanov at suse.de  Thu Dec 12 05:48:35 2024
From: svarbanov at suse.de (Stanimir Varbanov)
Date: Thu, 12 Dec 2024 15:48:35 +0200
Subject: [PATCH v4 08/10] PCI: brcmstb: Adjust PHY PLL setup to use a
 54MHz input refclk
In-Reply-To: <CADQZjwci2SVN=AG178kj3yN=17nVixOHEZOjZCs9LSUihbby4Q@mail.gmail.com>
References: <20241025124515.14066-1-svarbanov@suse.de>
 <20241025124515.14066-9-svarbanov@suse.de>
 <4bbdf9ed-f429-411b-8f5f-e51857f0f9d0@broadcom.com>
 <f9f49030-0518-4e30-91a7-3c088c31180b@suse.de>
 <474e5e38-37a4-439b-b25a-fe60df03f25b@broadcom.com>
 <CADQZjwci2SVN=AG178kj3yN=17nVixOHEZOjZCs9LSUihbby4Q@mail.gmail.com>
Message-ID: <462fcc0a-3b4a-4b59-b414-a2d305dcd29a@suse.de>

Hi

On 12/11/24 10:54 PM, Jonathan Bell wrote:
> On Wed, 11 Dec 2024 at 19:39, James Quinlan <james.quinlan at broadcom.com> wrote:
>>
>> On 12/10/24 08:42, Stanimir Varbanov wrote:
>>> Hi Jim
>>>
>>> On 12/10/24 12:52 AM, James Quinlan wrote:
>>>> On 10/25/24 08:45, Stanimir Varbanov wrote:
>>>>> The default input reference clock for the PHY PLL is 100Mhz, except for
>>>>> some devices where it is 54Mhz like bcm2712C1 and bcm2712D0.
>>>>>
>>>>> To implement this adjustments introduce a new .post_setup op in
>>>>> pcie_cfg_data and call it at the end of brcm_pcie_setup function.
>>>>>
>>>>> The bcm2712 .post_setup callback implements the required MDIO writes that
>>>>> switch the PLL refclk and also change PHY PM clock period.
>>>>>
>>>>> Without this RPi5 PCIex1 is unable to enumerate endpoint devices on
>>>>> the expansion connector.
>>>>>
>>>>> Signed-off-by: Stanimir Varbanov <svarbanov at suse.de>
>>>>> ---
>>>>> v3 -> v4:
>>>>>    - Improved patch description (Florian)
>>>>>
>>>>>    drivers/pci/controller/pcie-brcmstb.c | 42 +++++++++++++++++++++++++++
>>>>>    1 file changed, 42 insertions(+)
>>>>>
>>>>> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/
>>>>> controller/pcie-brcmstb.c
>>>>> index d970a76aa9ef..2571dcc14560 100644
>>>>> --- a/drivers/pci/controller/pcie-brcmstb.c
>>>>> +++ b/drivers/pci/controller/pcie-brcmstb.c
>>>>> @@ -55,6 +55,10 @@
>>>>>    #define PCIE_RC_DL_MDIO_WR_DATA                0x1104
>>>>>    #define PCIE_RC_DL_MDIO_RD_DATA                0x1108
>>>>>    +#define PCIE_RC_PL_PHY_CTL_15                0x184c
>>>>> +#define  PCIE_RC_PL_PHY_CTL_15_DIS_PLL_PD_MASK        0x400000
>>>>> +#define  PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK    0xff
>>>>> +
>>>>>    #define PCIE_MISC_MISC_CTRL                0x4008
>>>>>    #define  PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE_MASK    0x80
>>>>>    #define  PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE_MASK    0x400
>>>>> @@ -251,6 +255,7 @@ struct pcie_cfg_data {
>>>>>        u8 num_inbound_wins;
>>>>>        int (*perst_set)(struct brcm_pcie *pcie, u32 val);
>>>>>        int (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
>>>>> +    int (*post_setup)(struct brcm_pcie *pcie);
>>>>>    };
>>>>>      struct subdev_regulators {
>>>>> @@ -826,6 +831,36 @@ static int brcm_pcie_perst_set_generic(struct
>>>>> brcm_pcie *pcie, u32 val)
>>>>>        return 0;
>>>>>    }
>>>>>    +static int brcm_pcie_post_setup_bcm2712(struct brcm_pcie *pcie)
>>>>> +{
>>>>> +    const u16 data[] = { 0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030,
>>>>> 0x5030, 0x0007 };
>>>>> +    const u8 regs[] = { 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e };
>>>>> +    int ret, i;
>>>>> +    u32 tmp;
>>>>> +
>>>>> +    /* Allow a 54MHz (xosc) refclk source */
>>>>> +    ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0,
>>>>> SET_ADDR_OFFSET, 0x1600);
>>>>> +    if (ret < 0)
>>>>> +        return ret;
>>>>> +
>>>>> +    for (i = 0; i < ARRAY_SIZE(regs); i++) {
>>>>> +        ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, regs[i],
>>>>> data[i]);
>>>>> +        if (ret < 0)
>>>>> +            return ret;
>>>>> +    }
>>>>> +
>>>>> +    usleep_range(100, 200);
>>>>> +
>>>>> +    /* Fix for L1SS errata */
>>>>> +    tmp = readl(pcie->base + PCIE_RC_PL_PHY_CTL_15);
>>>>> +    tmp &= ~PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK;
>>>>> +    /* PM clock period is 18.52ns (round down) */
>>>>> +    tmp |= 0x12;
>>>>> +    writel(tmp, pcie->base + PCIE_RC_PL_PHY_CTL_15);
>>>> Hi Stan,
>>>>
>>>> Can you please say more about where this errata came from?  I asked the
>>>> 7712 PCIe HW folks and they said that there best guess was that it was a
>>>> old workaround for a particular Broadcom Wifi endpoint.  Do you know its
>>>> origin?
>>> Unfortunately, I don't know the details. See the comments on previous
>>> series version [1]. My observation shows that MDIO writes are
>>> implemented in RPi platform firmware only for pcie2 (where RP1 south
>>> bridge is connected) but not for pcie1 expansion connector.
>>
>> Well, I think my concern is more about the comment "Fix for L1SS errata"
>> rather than the code.  If this is a bonafide errata it should have an
>> identifier and some documentation somewhere. Declaring it to be an
>> unknown errata provides little info.
> 
> I'm the originator of this thunk - erratum is perhaps the wrong description.
> If the reference clock provided to the RC is 54MHz and not 100MHz, as
> is the case on BCM2712, then many of the L1 sub-state timers run
> slower which means state transitions are unnecessarily lengthened.
> 
> This change, and the MDIO manipulation above, should be applied
> regardless of the RC instance and/or connected EP.
> 

Thank you Jonathan.

I guess you are fine to take this description in the next version of the
series?

~Stan




From linux at roeck-us.net  Thu Dec 12 05:56:14 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 12 Dec 2024 05:56:14 -0800
Subject: [PATCH] watchdog: aspeed: replace mdelay with msleep
In-Reply-To: <20241212113014.1075414-1-phil@zankapfel.net>
References: <20241212113014.1075414-1-phil@zankapfel.net>
Message-ID: <3fe75eab-e700-4ae2-984b-42342ec7d784@roeck-us.net>

On 12/12/24 03:30, Phil Eichinger wrote:
> Since it is not called in an atomic context the mdelay function
> can be replaced with msleep to avoid busy wait.
> 
> Signed-off-by: Phil Eichinger <phil at zankapfel.net>
> ---
>   drivers/watchdog/aspeed_wdt.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
> index b4773a6aaf8c..98ef341408f7 100644
> --- a/drivers/watchdog/aspeed_wdt.c
> +++ b/drivers/watchdog/aspeed_wdt.c
> @@ -208,7 +208,7 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
>   	wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY;
>   	aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000);
>   
> -	mdelay(1000);
> +	msleep(1000);
>   
>   	return 0;
>   }
This is a _restart_ handler. The only purpose of the delay is to wait
for the reset to trigger. It is not supposed to sleep.

NACK.

Guenter





From linux at roeck-us.net  Thu Dec 12 05:57:09 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 12 Dec 2024 05:57:09 -0800
Subject: [PATCH v2] watchdog: stm32_iwdg: fix error message during driver
 probe
In-Reply-To: <20241212102050.374501-1-clement.legoffic@foss.st.com>
References: <20241211163457.301140-1-clement.legoffic@foss.st.com>
 <20241212102050.374501-1-clement.legoffic@foss.st.com>
Message-ID: <194f1c3a-2333-4a33-b459-d50f02e1b98c@roeck-us.net>

On 12/12/24 02:20, Cl?ment Le Goffic wrote:
> The commit 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
> introduces the support for the pre-timeout interrupt.
> 
> The support for this interrupt is optional but the driver uses the
> platform_get_irq() wich produces an error message during the driver
> probe if we don't have any `interrupts` property in the DT.
> 
> Use the platform_get_irq_optional() API to get rid of the error message
> as this property is optional.
> 
> Fixes: 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
> Signed-off-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

> ---
> v1 -> v2: Change the commit message because it only prints an error
> message and dont break the DT backward compatibility.
> 
> drivers/watchdog/stm32_iwdg.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
> index d700e0d49bb95..8ad06b54c5adc 100644
> --- a/drivers/watchdog/stm32_iwdg.c
> +++ b/drivers/watchdog/stm32_iwdg.c
> @@ -286,7 +286,7 @@ static int stm32_iwdg_irq_init(struct platform_device *pdev,
>   	if (!wdt->data->has_early_wakeup)
>   		return 0;
> 
> -	irq = platform_get_irq(pdev, 0);
> +	irq = platform_get_irq_optional(pdev, 0);
>   	if (irq <= 0)
>   		return 0;
> 
> 
> base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
> --
> 2.34.1
> 
> 



From francesco at dolcini.it  Thu Dec 12 06:10:03 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Thu, 12 Dec 2024 15:10:03 +0100
Subject: imx8m-blk-ctrl: WARNING, no release() function
Message-ID: <20241212141003.GA44219@francesco-nb>

Hello,
on v6.13-rc2 (PREEMPT_RT, if it matters), I have the following warning

[    4.615793] ------------[ cut here ]------------
[    4.615814] Device 'mediablk-mipi-csi2-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
[    4.618977] WARNING: CPU: 1 PID: 11 at /drivers/base/core.c:2569 device_release+0x80/0x94
[    4.638974] Modules linked in: ecdh_generic ecc etnaviv(+) rfkill libaes samsung_dsim gpu_sched imx_sdma(+) governor_userspace imx_bus dwc3_imx8mp spi_nxp_fspi lontium_lt8912b ina2xx snd_soc_wm8904 ti_ads1015 industrialio_triggered_buffer kfifo_buf lm75 snvs_pwrkey pwm_imx27 nvmem_snvs_lpgpr imx8mm_thermal caam flexcan error can_dev spi_imx usb_conn_gpio display_connector roles gpio_keys fuse ipv6 autofs4
[    4.639073] CPU: 1 UID: 0 PID: 11 Comm: kworker/u16:0 Not tainted 6.13.0-rc2-0.0.0-devel-00040-ga1625b19385c #1
[    4.639082] Hardware name: Toradex Verdin iMX8M Plus WB on Dahlia Board (DT)
[    4.639087] Workqueue: events_unbound deferred_probe_work_func
[    4.639099] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[    4.639107] pc : device_release+0x80/0x94
[    4.639116] lr : device_release+0x80/0x94
[    4.639122] sp : ffff80008142b910
[    4.639125] x29: ffff80008142b910 x28: 00000000fffffdfb x27: ffff000005c92180
[    4.639137] x26: ffff000000018028 x25: ffff000000046dc0 x24: ffff800080c43710
[    4.639147] x23: 0000000100000001 x22: 0000000000000000 x21: ffff800080e43750
[    4.639158] x20: 0000000000000000 x19: ffff000007cb06d8 x18: 0000000000000006
[    4.639168] x17: 0000000000000001 x16: 0000000000000000 x15: 0000000000000002
[    4.639179] x14: 0000000000001400 x13: ffff0000000a9110 x12: 0000000000225510
[    4.639190] x11: 0000000000000000 x10: 00000000000009c0 x9 : ffff80008142b790
[    4.639200] x8 : ffff00000013bba0 x7 : 000000000000002d x6 : 000000000113158e
[    4.639210] x5 : 00000001134e0800 x4 : 0000000000000002 x3 : ffff000003b04c50
[    4.639221] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff00000013b180
[    4.639231] Call trace:
[    4.639235]  device_release+0x80/0x94 (P)
[    4.639245]  device_release+0x80/0x94 (L)
[    4.639253]  kobject_put+0xb0/0x214
[    4.639264]  put_device+0x14/0x24
[    4.639272]  genpd_remove+0x114/0x248
[    4.639281]  pm_genpd_remove+0x30/0x58
[    4.639288]  imx8m_blk_ctrl_probe+0x36c/0x540
[    4.639299]  platform_probe+0x68/0xdc
[    4.639308]  really_probe+0xc0/0x39c
[    4.639315]  __driver_probe_device+0x7c/0x14c
[    4.639322]  driver_probe_device+0x3c/0x120
[    4.639329]  __device_attach_driver+0xbc/0x160
[    4.639336]  bus_for_each_drv+0x88/0xe8
[    4.639346]  __device_attach+0xa0/0x1b4
[    4.639353]  device_initial_probe+0x14/0x20
[    4.639360]  bus_probe_device+0xb0/0xbc
[    4.639366]  deferred_probe_work_func+0xa0/0xf0
[    4.639373]  process_one_work+0x148/0x284
[    4.639383]  worker_thread+0x2d0/0x3e4
[    4.639391]  kthread+0x110/0x114
[    4.639399]  ret_from_fork+0x10/0x20
[    4.639409] ---[ end trace 0000000000000000 ]---

and more for other devices, from the same driver.

Just reporting for the moment, in case someone has some ideas or wants to
have a look.

Francesco



From thomas.lendacky at amd.com  Thu Dec 12 06:23:07 2024
From: thomas.lendacky at amd.com (Tom Lendacky)
Date: Thu, 12 Dec 2024 08:23:07 -0600
Subject: [PATCHv2 2/2] x86/mm: Make memremap(MEMREMAP_WB) map memory as
 encrypted by default
In-Reply-To: <bz3vlh3lri7yfckdkddopwhsgvkmizhw5q6ecomgeba7q22ufp@ntu2kugiho4o>
References: <20241021105723.2707507-1-kirill.shutemov@linux.intel.com>
 <20241021105723.2707507-3-kirill.shutemov@linux.intel.com>
 <20241118164616.GAZztvWGs9cOV8t20_@fat_crate.local>
 <s4frmqwtuvclinuu7ttyzfpe7bj7hju5xgt6sxzy3gyt3prr62@rrgvhkv4lgwv>
 <20241121114952.GCZz8eYEVa3yubYQzO@fat_crate.local>
 <bz3vlh3lri7yfckdkddopwhsgvkmizhw5q6ecomgeba7q22ufp@ntu2kugiho4o>
Message-ID: <079cb87c-78aa-5fb5-b28f-e7a54e51aa78@amd.com>

On 12/10/24 07:26, Kirill A. Shutemov wrote:
> On Thu, Nov 21, 2024 at 12:49:52PM +0100, Borislav Petkov wrote:
>> On Tue, Nov 19, 2024 at 10:21:05AM +0200, Kirill A. Shutemov wrote:
>>> Sure, we can workaround every place that touches such ranges.
>>
>> Every place? Which every place? I thought this is only an EISA issue?
> 
> I looked at other places where we call memremap(MEMREMAP_WB) such as
> acpi_wakeup_cpu(). We actually get encrypted/private mapping for this
> callsite despite __ioremap_caller() being called encrypted == false.
> This happens because of IORES_MAP_ENCRYPTED check in __ioremap_caller().
> 
> So we depend on the BIOS here. The EISA problem happens because the
> target memory is in !IORES_MAP_ENCRYPTED memory.
> 
> It's hard to say if any other memremap(MEMREMAP_WB) would trigger the
> issue. And what will happen after next BIOS update.
> 
>> Then clearly your changelogs need to expand considerably more what we're
>> *really* addressing here.
>>
>>> Or we can address problem at the root and make creating decrypted/shared
>>> mappings explicit.
>>
>> What is the problem? That KVM implicitly converts memory to shared? Why does
>> KVM do that an can it be fixed not to?
>>
>> Doesn't sound like the guest's problem.
> 
> Well, the problem is on the both sides.
> 
> VMM behaviour on such accesses is not specified in any spec. AFAIK all
> current VMM implementations do this implicit conversion.
> 
> I think it has to be fixed. VMMs (not only KVM) should not silently
> convert memory to shared. But VMMs cannot make memory access to go away.
> The only option they have is to inject #VE instead indicating bogus
> access. At this point it becomes a guest problem.
> 
> It will get fixed in VMMs naturally when TDX Connect gets enabled.
> With a secure device assigned to a TD, VMM would loose the ability to
> convert memory on its own. The guest would have to unlock the memory
> first. This will make implicit conversion impossible.
> 
> But it also means guest should never initiate shared access without
> explicit conversion. Otherwise #VE will crash it.
> 
>> Or maybe this needs a lot more explanation what we're fixing here.
>>
>>> Such mappings have both functional (as we see here) and security
>>> implications (VMM can manipulate the guest memory range). We should not
>>> create decrypted mappings by default on legacy interfaces.
>>
>> So we're getting closer.
>>
>> The changes themselves are fine but your text is missing a lot about what
>> we're fixing here. When I asked, I barely scratched the surface. So can we
>> elaborate here pls?
> 
> What about this:
> 
> x86/mm: Make memremap(MEMREMAP_WB) map memory as encrypted by default
> 
> Currently memremap(MEMREMAP_WB) can produce decrypted/shared mapping:
> 
> memremap(MEMREMAP_WB)
>   arch_memremap_wb()
>     ioremap_cache()
>       __ioremap_caller(.encrytped = false)

That's because try_ram_remap() invokes arch_memremap_can_ram_remap()
which is returning false (for some reason).

When arch_memremap_can_ram_remap() returns false, ioremap_cache() is
invoked. ioremap() should provide shared mappings unless specifically
requested to provide an encrypted mapping (via encrypted parameter) or
if __ioremap_check_mem() determines that an encrypted mapping is needed.

Can logic be added to arch_memremap_can_ram_remap() to return true for
the cases that TDX is having issues with?

Thanks,
Tom

> 
> In such cases, the IORES_MAP_ENCRYPTED flag on the memory will determine
> if the resulting mapping is encrypted or decrypted.
> 
> Creating a decrypted mapping without explicit request from the caller is
> risky:
> 
>   - It can inadvertently expose the guest's data and compromise the
>     guest.
> 
>   - Accessing private memory via shared/decrypted mapping on TDX will
>     either trigger implicit conversion to shared or #VE (depending on
>     VMM implementation).
> 
>     Implicit conversion is destructive: subsequent access to the same
>     memory via private mapping will trigger a hard-to-debug #VE crash.
> 
> The kernel already provides a way to request decrypted mapping
> explicitly via the MEMREMAP_DEC flag.
> 
> Modify memremap(MEMREMAP_WB) to produce encrypted/private mapping by
> default unless MEMREMAP_DEC is specified.
> 
> This change fixes the crash on kexec in TDX guests if CONFIG_EISA is
> enabled.
>  


From maz at kernel.org  Thu Dec 12 06:26:59 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Dec 2024 14:26:59 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <084c5ada-51af-4c1a-b50a-4401e62ddbd6@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
	<20241211160218.41404-3-miko.lenczewski@arm.com>
	<87cyhxs3xq.wl-maz@kernel.org>
	<084c5ada-51af-4c1a-b50a-4401e62ddbd6@arm.com>
Message-ID: <86ikrprn7w.wl-maz@kernel.org>

On Thu, 12 Dec 2024 10:55:45 +0000,
Ryan Roberts <ryan.roberts at arm.com> wrote:
> 
> On 12/12/2024 08:25, Marc Zyngier wrote:
> >> +
> >> +	local_flush_tlb_all();
> > 
> > The elephant in the room: if TLBs are in such a sorry state, what
> > guarantees we can make it this far?
> 
> I'll leave Miko to respond to your other comments, but I wanted to address this
> one, since it's pretty fundamental. We went around this loop internally and
> concluded that what we are doing is architecturally sound.
> 
> The expectation is that a conflict abort can only be generated as a result of
> the change in patch 4 (and patch 5). That change makes it possible for the TLB
> to end up with a multihit. But crucially that can only happen for user space
> memory because that change only operates on user memory. And while the TLB may
> detect the conflict at any time, the conflict abort is only permitted to be
> reported when an architectural access is prevented by the conflict. So we never
> do anything that would allow a conflict for a kernel memory access and a user
> memory conflict abort can never be triggered as a result of accessing kernel memory.
> 
> Copy/pasting comment from AlexC on the topic, which explains it better than I can:
> 
> """
> The intent is certainly that in cases where the hardware detects a TLB conflict
> abort, it is only permitted to report it (by generating an exception) if it
> applies to an access that is being attempted architecturally. ... that property
> can be built from the following two properties:
> 
> 1. The TLB conflict can only be reported as an Instruction Abort or a Data Abort
> 
> 2. Those two exception types must be reported synchronously and precisely.
> """

I totally agree with this. The issue is that nothing says that the
abort is in any way related to userspace.

> > 
> > I honestly don't think you can reliably handle a TLB Conflict abort in
> > the same translation regime as the original fault, given that we don't
> > know the scope of that fault. You are probably making an educated
> > guess that it is good enough on the CPUs you know of, but I don't see
> > anything in the architecture that indicates the "blast radius" of a
> > TLB conflict.
> 
> OK, so I'm claiming that the blast radius is limited to the region of memory
> that we are operating on in contpte_collapse() in patch 4. Perhaps we need to go
> re-read the ARM and come back with the specific statements that led us to that
> conclusion?

But we don't know for sure what caused this conflict by the time we
arrive in the handler. It could equally be because we have a glaring
bug somewhere on the kernel side, even if you are *now* only concerned
with userspace.

If anything, this should absolutely check for FAR_EL1 and assert that
this is indeed caused by such change.

Thanks,

	M.

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


From Dave.Martin at arm.com  Thu Dec 12 06:35:56 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 14:35:56 +0000
Subject: [PATCH v2] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <20241210160940.2031997-1-kevin.brodsky@arm.com>
References: <20241210160940.2031997-1-kevin.brodsky@arm.com>
Message-ID: <Z1r0zO3BrYrt1xNY@e133380.arm.com>

Hi,

On Tue, Dec 10, 2024 at 04:09:40PM +0000, Kevin Brodsky wrote:
> Commit eaf62ce1563b ("arm64/signal: Set up and restore the GCS
> context for signal handlers") introduced a potential failure point
> at the end of setup_return(). This is unfortunate as it is too late
> to deliver a SIGSEGV: if that SIGSEGV is handled, the subsequent
> sigreturn will end up returning to the original handler, which is
> not the intention (since we failed to deliver that signal).
> 
> Make sure this does not happen by calling gcs_signal_entry()
> at the very beginning of setup_return(), and add a comment just
> after to discourage error cases being introduced from that point
> onwards.
> 
> While at it, also take care of copy_siginfo_to_user(): since it may
> fail, we shouldn't be calling it after setup_return() either. Call
> it before setup_return() instead, and move the setting of X1/X2
> inside setup_return() where it belongs (after the "point of no
> failure").
> 
> Background: the first part of setup_rt_frame(), including
> setup_sigframe(), has no impact on the execution of the interrupted
> thread. The signal frame is written to the stack, but the stack
> pointer remains unchanged. Failure at this stage can be recovered by
> a SIGSEGV handler, and sigreturn will restore the original context,
> at the point where the original signal occurred. On the other hand,
> once setup_return() has updated registers including SP, the thread's
> control flow has been modified and we must deliver the original
> signal.
> 
> Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")
> Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
> ---
> v1..v2:
> * Added a short comment in setup_rt_frame() after the call to
>   setup_return() to discourage adding failure points there.
>   [Dave's suggestion]

Assuming that this was the only change, I was OK for you to add:

Reviewed-by: Dave Martin <Dave.Martin at arm.com>

> 
> Cc: broonie at kernel.org
> Cc: catalin.marinas at arm.com
> Cc: Dave.Martin at arm.com
> Cc: will at kernel.org
> ---
>  arch/arm64/kernel/signal.c | 48 ++++++++++++++++++++++++++------------
>  1 file changed, 33 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c

[...]

> @@ -1537,14 +1553,16 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,

[...]

>  		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;
> -			regs->regs[2] = (unsigned long)&frame->uc;
> -		}
> -	}
> +
> +	/*
> +	 * We must not fail if setup_return() succeeded - see comment at the
> +	 * beginning of setup_return().
> +	 */
>  
>  	if (err == 0)
>  		set_handler_user_access_state();
> 
> base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
> -- 
> 2.47.0
> 
> 

Cheers
---Dave


From rmk+kernel at armlinux.org.uk  Thu Dec 12 06:46:44 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 12 Dec 2024 14:46:44 +0000
Subject: [PATCH net-next 4/7] net: stmmac: remove redundant code from ethtool
 EEE ops
In-Reply-To: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
References: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
Message-ID: <E1tLkSi-006qff-3A@rmk-PC.armlinux.org.uk>

Setting edata->tx_lpi_enabled in stmmac_ethtool_op_get_eee() gets
overwritten by phylib, so there's no point setting this.

In stmmac_ethtool_op_set_eee(), now that stmmac is using the result of
phylib's evaluation of EEE, there is no need to handle anything in the
ethtool EEE ops other than calling through to the appropriate phylink
function, which will pass on to phylib the users request.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 5ce095a62feb..3a10788bb210 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -898,8 +898,6 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
 	if (!priv->dma_cap.eee)
 		return -EOPNOTSUPP;
 
-	edata->tx_lpi_enabled = priv->tx_lpi_enabled;
-
 	return phylink_ethtool_get_eee(priv->phylink, edata);
 }
 
@@ -911,13 +909,6 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
 	if (!priv->dma_cap.eee)
 		return -EOPNOTSUPP;
 
-	if (priv->tx_lpi_enabled != edata->tx_lpi_enabled)
-		netdev_warn(priv->dev,
-			    "Setting EEE tx-lpi is not supported\n");
-
-	if (!edata->eee_enabled)
-		stmmac_disable_eee_mode(priv);
-
 	return phylink_ethtool_set_eee(priv->phylink, edata);
 }
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Thu Dec 12 06:46:49 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 12 Dec 2024 14:46:49 +0000
Subject: [PATCH net-next 5/7] net: stmmac: remove priv->tx_lpi_enabled
In-Reply-To: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
References: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
Message-ID: <E1tLkSn-006qfl-6n@rmk-PC.armlinux.org.uk>

Through using phylib's EEE state, priv->tx_lpi_enabled has become a
write-only variable. Remove it.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h      | 1 -
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 --
 2 files changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 1d86439b8a14..77a7a098ebd1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -310,7 +310,6 @@ struct stmmac_priv {
 	int eee_enabled;
 	int eee_active;
 	int tx_lpi_timer;
-	int tx_lpi_enabled;
 	int eee_tw_timer;
 	bool eee_sw_timer_en;
 	unsigned int mode;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 75f540d7ec7d..3acc6f6e2190 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -978,7 +978,6 @@ static void stmmac_mac_link_down(struct phylink_config *config,
 
 	stmmac_mac_set(priv, priv->ioaddr, false);
 	priv->eee_active = false;
-	priv->tx_lpi_enabled = false;
 	priv->eee_enabled = stmmac_eee_init(priv);
 	stmmac_set_eee_pls(priv, priv->hw, false);
 
@@ -1093,7 +1092,6 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 				STMMAC_FLAG_RX_CLK_RUNS_IN_LPI)) >= 0;
 		priv->eee_enabled = stmmac_eee_init(priv);
 		priv->tx_lpi_timer = phy->eee_cfg.tx_lpi_timer;
-		priv->tx_lpi_enabled = priv->eee_enabled;
 		stmmac_set_eee_pls(priv, priv->hw, true);
 	}
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Thu Dec 12 06:46:54 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 12 Dec 2024 14:46:54 +0000
Subject: [PATCH net-next 6/7] net: stmmac: report EEE error statistics if EEE
 is supported
In-Reply-To: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
References: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
Message-ID: <E1tLkSs-006qfr-AN@rmk-PC.armlinux.org.uk>

Report the number of EEE error statistics in the xstats even when EEE
is not enabled in hardware, but is supported. The PHY maintains this
counter even when EEE is not enabled.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 3a10788bb210..a33d7db810f0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -654,7 +654,7 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
 					     (*(u32 *)p);
 			}
 		}
-		if (priv->eee_enabled) {
+		if (priv->dma_cap.eee) {
 			int val = phylink_get_eee_err(priv->phylink);
 			if (val)
 				priv->xstats.phy_eee_wakeup_error_n = val;
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Thu Dec 12 06:46:59 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 12 Dec 2024 14:46:59 +0000
Subject: [PATCH net-next 7/7] net: stmmac: convert to use
 phy_eee_rx_clock_stop()
In-Reply-To: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
References: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
Message-ID: <E1tLkSx-006qfx-Fk@rmk-PC.armlinux.org.uk>

Convert stmmac to use phy_eee_rx_clock_stop() to set the PHY receive
clock stop in LPI setting, rather than calling the legacy
phy_init_eee() function.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3acc6f6e2190..d5516ef0f098 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1087,9 +1087,9 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 
 	stmmac_mac_set(priv, priv->ioaddr, true);
 	if (phy && priv->dma_cap.eee) {
-		priv->eee_active = phy->enable_tx_lpi &&
-			phy_init_eee(phy, !(priv->plat->flags &
-				STMMAC_FLAG_RX_CLK_RUNS_IN_LPI)) >= 0;
+		phy_eee_rx_clock_stop(phy, !(priv->plat->flags &
+					     STMMAC_FLAG_RX_CLK_RUNS_IN_LPI));
+		priv->eee_active = phy->enable_tx_lpi;
 		priv->eee_enabled = stmmac_eee_init(priv);
 		priv->tx_lpi_timer = phy->eee_cfg.tx_lpi_timer;
 		stmmac_set_eee_pls(priv, priv->hw, true);
-- 
2.30.2



From linux at armlinux.org.uk  Thu Dec 12 06:46:09 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 12 Dec 2024 14:46:09 +0000
Subject: [PATCH net-next 0/7] net: stmmac: clean up and fix EEE implementation
Message-ID: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>

Hi,

This is a rework of stmmac's EEE support in light of the addition of EEE
management to phylib.

Patch 1 adds configuration of the receive clock phy_eee_rx_clock_stop()
(which was part of another series.)

Patch 2 moves the tracking of tx_lpi_timer to phylib.

Patch 3 makes stmmac EEE state depend on phylib's enable_tx_lpi flag.

Patch 4 removes redundant code from the ethtool EEE operations.

Patch 5 removes the driver private tx_lpi_enabled, which will now be
managed by phylib.

Patch 6 removes the dependence of EEE error statistics on the EEE
enable state, instead depending on whether EEE is supported by the
hardware.

Patch 7 removes phy_init_eee(), instead using phy_eee_rx_clock_stop()
to configure whether the PHY may stop the receive clock.

 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  1 -
 .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   | 25 ++------------------
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 26 +++++++++++++--------
 drivers/net/phy/phy.c                              | 27 ++++++++++++++++++----
 include/linux/phy.h                                |  1 +
 5 files changed, 42 insertions(+), 38 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  Thu Dec 12 06:46:33 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 12 Dec 2024 14:46:33 +0000
Subject: [PATCH net-next 2/7] net: stmmac: move tx_lpi_timer tracking to
 phylib
In-Reply-To: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
References: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
Message-ID: <E1tLkSX-006qfS-Rx@rmk-PC.armlinux.org.uk>

When stmmac_ethtool_op_get_eee() is called, stmmac sets the tx_lpi_timer
and tx_lpi_enabled members, and then calls into phylink and thus phylib.
phylib overwrites these members.

phylib will also cause a link down/link up transition when settings
that impact the MAC have been changed.

Convert stmmac to use the tx_lpi_timer setting in struct phy_device,
updating priv->tx_lpi_timer each time when the link comes up, rather
than trying to maintain this user setting itself. We initialise the
phylib tx_lpi_timer setting by doing a get_ee-modify-set_eee sequence
with the last known priv->tx_lpi_timer value. In order for this to work
correctly, we also need this member to be initialised earlier.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c   | 14 +-------------
 .../net/ethernet/stmicro/stmmac/stmmac_main.c  | 18 ++++++++++++++----
 2 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 1d77389ce953..5ce095a62feb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -898,7 +898,6 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
 	if (!priv->dma_cap.eee)
 		return -EOPNOTSUPP;
 
-	edata->tx_lpi_timer = priv->tx_lpi_timer;
 	edata->tx_lpi_enabled = priv->tx_lpi_enabled;
 
 	return phylink_ethtool_get_eee(priv->phylink, edata);
@@ -908,7 +907,6 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
 				     struct ethtool_keee *edata)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
-	int ret;
 
 	if (!priv->dma_cap.eee)
 		return -EOPNOTSUPP;
@@ -920,17 +918,7 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
 	if (!edata->eee_enabled)
 		stmmac_disable_eee_mode(priv);
 
-	ret = phylink_ethtool_set_eee(priv->phylink, edata);
-	if (ret)
-		return ret;
-
-	if (edata->eee_enabled &&
-	    priv->tx_lpi_timer != edata->tx_lpi_timer) {
-		priv->tx_lpi_timer = edata->tx_lpi_timer;
-		stmmac_eee_init(priv);
-	}
-
-	return 0;
+	return phylink_ethtool_set_eee(priv->phylink, edata);
 }
 
 static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d45fd7a3acd5..d202bee73b8f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1092,6 +1092,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 			phy_init_eee(phy, !(priv->plat->flags &
 				STMMAC_FLAG_RX_CLK_RUNS_IN_LPI)) >= 0;
 		priv->eee_enabled = stmmac_eee_init(priv);
+		priv->tx_lpi_timer = phy->eee_cfg.tx_lpi_timer;
 		priv->tx_lpi_enabled = priv->eee_enabled;
 		stmmac_set_eee_pls(priv, priv->hw, true);
 	}
@@ -1190,6 +1191,15 @@ static int stmmac_init_phy(struct net_device *dev)
 		ret = phylink_fwnode_phy_connect(priv->phylink, fwnode, 0);
 	}
 
+	if (ret == 0) {
+		struct ethtool_keee eee;
+
+		if (phylink_ethtool_get_eee(priv->phylink, &eee)) {
+			eee.tx_lpi_timer = priv->tx_lpi_timer;
+			phylink_ethtool_set_eee(priv->phylink, &eee);
+		}
+	}
+
 	if (!priv->plat->pmt) {
 		struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
 
@@ -3442,10 +3452,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
 
 	priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
 
-	/* Convert the timer from msec to usec */
-	if (!priv->tx_lpi_timer)
-		priv->tx_lpi_timer = eee_timer * 1000;
-
 	if (priv->use_riwt) {
 		u32 queue;
 
@@ -3912,6 +3918,10 @@ static int __stmmac_open(struct net_device *dev,
 	u32 chan;
 	int ret;
 
+	/* Initialise the tx lpi timer, converting from msec to usec */
+	if (!priv->tx_lpi_timer)
+		priv->tx_lpi_timer = eee_timer * 1000;
+
 	ret = pm_runtime_resume_and_get(priv->device);
 	if (ret < 0)
 		return ret;
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Thu Dec 12 06:46:38 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 12 Dec 2024 14:46:38 +0000
Subject: [PATCH net-next 3/7] net: stmmac: make EEE depend on
 phy->enable_tx_lpi
In-Reply-To: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
References: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
Message-ID: <E1tLkSc-006qfZ-Vc@rmk-PC.armlinux.org.uk>

Make stmmac EEE depend on phylib's evaluation of user settings and PHY
negotiation, as indicated by phy->enable_tx_lpi. This will ensure when
phylib has evaluated that the user has disabled LPI, phy_init_eee()
will not be called, and priv->eee_active will be false, causing LPI/EEE
to be disabled.

This is an interim measure - phy_init_eee() will be removed in a later
patch.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d202bee73b8f..75f540d7ec7d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1088,7 +1088,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 
 	stmmac_mac_set(priv, priv->ioaddr, true);
 	if (phy && priv->dma_cap.eee) {
-		priv->eee_active =
+		priv->eee_active = phy->enable_tx_lpi &&
 			phy_init_eee(phy, !(priv->plat->flags &
 				STMMAC_FLAG_RX_CLK_RUNS_IN_LPI)) >= 0;
 		priv->eee_enabled = stmmac_eee_init(priv);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Thu Dec 12 06:46:28 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 12 Dec 2024 14:46:28 +0000
Subject: [PATCH net-next 1/7] net: phy: add configuration of rx clock stop
 mode
In-Reply-To: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
References: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
Message-ID: <E1tLkSS-006qfM-OH@rmk-PC.armlinux.org.uk>

Add a function to allow configuration of the PCS's clock stop enable
bit, used to configure whether the xMII receive clock can be stopped
during LPI mode.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/phy/phy.c | 27 ++++++++++++++++++++++-----
 include/linux/phy.h   |  1 +
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index e4b04cdaa995..a4b9fcc2503a 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1640,6 +1640,27 @@ void phy_mac_interrupt(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_mac_interrupt);
 
+/**
+ * phy_eee_rx_clock_stop() - configure PHY receive clock in LPI
+ * @phydev: target phy_device struct
+ * @clk_stop_enable: flag to indicate whether the clock can be stopped
+ *
+ * Configure whether the PHY can disable its receive clock during LPI mode,
+ * See IEEE 802.3 sections 22.2.2.2, 35.2.2.10, and 45.2.3.1.4.
+ *
+ * Returns: 0 or negative error.
+ */
+int phy_eee_rx_clock_stop(struct phy_device *phydev, bool clk_stop_enable)
+{
+	/* Configure the PHY to stop receiving xMII
+	 * clock while it is signaling LPI.
+	 */
+	return phy_modify_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
+			      MDIO_PCS_CTRL1_CLKSTOP_EN,
+			      clk_stop_enable ? MDIO_PCS_CTRL1_CLKSTOP_EN : 0);
+}
+EXPORT_SYMBOL_GPL(phy_eee_rx_clock_stop);
+
 /**
  * phy_init_eee - init and check the EEE feature
  * @phydev: target phy_device struct
@@ -1664,11 +1685,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
 		return -EPROTONOSUPPORT;
 
 	if (clk_stop_enable)
-		/* Configure the PHY to stop receiving xMII
-		 * clock while it is signaling LPI.
-		 */
-		ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
-				       MDIO_PCS_CTRL1_CLKSTOP_EN);
+		ret = phy_eee_rx_clock_stop(phydev, true);
 
 	return ret < 0 ? ret : 0;
 }
diff --git a/include/linux/phy.h b/include/linux/phy.h
index e597a32cc787..ba9d16fc69b8 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -2095,6 +2095,7 @@ int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask);
 int phy_unregister_fixup_for_id(const char *bus_id);
 int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask);
 
+int phy_eee_rx_clock_stop(struct phy_device *phydev, bool clk_stop_enable);
 int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable);
 int phy_get_eee_err(struct phy_device *phydev);
 int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_keee *data);
-- 
2.30.2



From ryan.roberts at arm.com  Thu Dec 12 07:05:24 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 12 Dec 2024 15:05:24 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <86ikrprn7w.wl-maz@kernel.org>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-3-miko.lenczewski@arm.com>
 <87cyhxs3xq.wl-maz@kernel.org> <084c5ada-51af-4c1a-b50a-4401e62ddbd6@arm.com>
 <86ikrprn7w.wl-maz@kernel.org>
Message-ID: <2b1cc228-a8d5-4383-ab25-abbbcccd2e2c@arm.com>

On 12/12/2024 14:26, Marc Zyngier wrote:
> On Thu, 12 Dec 2024 10:55:45 +0000,
> Ryan Roberts <ryan.roberts at arm.com> wrote:
>>
>> On 12/12/2024 08:25, Marc Zyngier wrote:
>>>> +
>>>> +	local_flush_tlb_all();
>>>
>>> The elephant in the room: if TLBs are in such a sorry state, what
>>> guarantees we can make it this far?
>>
>> I'll leave Miko to respond to your other comments, but I wanted to address this
>> one, since it's pretty fundamental. We went around this loop internally and
>> concluded that what we are doing is architecturally sound.
>>
>> The expectation is that a conflict abort can only be generated as a result of
>> the change in patch 4 (and patch 5). That change makes it possible for the TLB
>> to end up with a multihit. But crucially that can only happen for user space
>> memory because that change only operates on user memory. And while the TLB may
>> detect the conflict at any time, the conflict abort is only permitted to be
>> reported when an architectural access is prevented by the conflict. So we never
>> do anything that would allow a conflict for a kernel memory access and a user
>> memory conflict abort can never be triggered as a result of accessing kernel memory.
>>
>> Copy/pasting comment from AlexC on the topic, which explains it better than I can:
>>
>> """
>> The intent is certainly that in cases where the hardware detects a TLB conflict
>> abort, it is only permitted to report it (by generating an exception) if it
>> applies to an access that is being attempted architecturally. ... that property
>> can be built from the following two properties:
>>
>> 1. The TLB conflict can only be reported as an Instruction Abort or a Data Abort
>>
>> 2. Those two exception types must be reported synchronously and precisely.
>> """
> 
> I totally agree with this. The issue is that nothing says that the
> abort is in any way related to userspace.
> 
>>>
>>> I honestly don't think you can reliably handle a TLB Conflict abort in
>>> the same translation regime as the original fault, given that we don't
>>> know the scope of that fault. You are probably making an educated
>>> guess that it is good enough on the CPUs you know of, but I don't see
>>> anything in the architecture that indicates the "blast radius" of a
>>> TLB conflict.
>>
>> OK, so I'm claiming that the blast radius is limited to the region of memory
>> that we are operating on in contpte_collapse() in patch 4. Perhaps we need to go
>> re-read the ARM and come back with the specific statements that led us to that
>> conclusion?

>From the ARM:
"""
RFCPSG: If level 1 or level 2 is supported and the Contiguous bit in a set of
Block descriptors or Page descriptors is changed, then a TLB conflict abort can
be generated because multiple translation table entries might exist within a TLB
that translates the same IA.
"""

Although I guess it's not totally explicit, I've interpretted that as saying
that conflicting TLB entries can only arise for the IA range for which the
contiguous bits have been modified in the translation tables.

Given we are only fiddling with the contiguous bits for user space mappings in
this way, that's why I'm asserting we will only get a conflict abort for user
space mappings... assuming the absence of kernel bugs, anyway...

> 
> But we don't know for sure what caused this conflict by the time we
> arrive in the handler. It could equally be because we have a glaring
> bug somewhere on the kernel side, even if you are *now* only concerned
> with userspace.

OK I see what you are saying; previously a conflict abort would have led to
calling do_bad(), which returns 1, which causes do_mem_abort() to either kill
the kernel or the process depending on the origin of the abort. (although if it
came from kernel due to bug, we're just hoping that the conflict doesn't affect
the path through the handler). With this change, we always assume we can fix it
with the TLBI.

How about this change to ensure we still die for issues originating from the kernel?

if (!user_mode(regs) || !system_supports_bbml2())
		return do_bad(far, esr, regs);

> 
> If anything, this should absolutely check for FAR_EL1 and assert that
> this is indeed caused by such change.

I'm not really sure how we would check this reliably? Without patch 5, the
problem is somewhat constrained; we could have as many changes in flight as
there are CPUs so we could keep a list of all the {mm_struct, VA-range} that are
being modified. But if patch 5 is confirmed to be architecturally sound, then
there is no "terminating tlbi" so there is no bound on the set of {mm_struct,
VA-range}'s that could legitimately cause a conflict abort.

Thanks,
Ryan

> 
> Thanks,
> 
> 	M.
> 



From quic_bibekkum at quicinc.com  Thu Dec 12 07:14:00 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Thu, 12 Dec 2024 20:44:00 +0530
Subject: [PATCH v18 3/5] iommu/arm-smmu: add support for PRR bit setup
In-Reply-To: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
References: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
Message-ID: <20241212151402.159102-4-quic_bibekkum@quicinc.com>

Add an adreno-smmu-priv interface for drm/msm to call
into arm-smmu-qcom and initiate the PRR bit setup or reset
sequence as per request.

This will be used by GPU to setup the PRR bit and related
configuration registers through adreno-smmu private
interface instead of directly poking the smmu hardware.

Suggested-by: Rob Clark <robdclark at gmail.com>
Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 52 ++++++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu.h      |  2 +
 include/linux/adreno-smmu-priv.h           | 14 ++++++
 3 files changed, 68 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index d26f5aea248e..818fdbd706da 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -16,6 +16,8 @@

 #define QCOM_DUMMY_VAL	-1

+#define GFX_ACTLR_PRR          (1 << 5)
+
 static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
 {
 	return container_of(smmu, struct qcom_smmu, smmu);
@@ -99,6 +101,47 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina
 	arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
 }

+static void qcom_adreno_smmu_set_prr_bit(const void *cookie, bool set)
+{
+	struct arm_smmu_domain *smmu_domain = (void *)cookie;
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
+	u32 reg = 0;
+	int ret;
+
+	ret = pm_runtime_resume_and_get(smmu->dev);
+	if (ret < 0) {
+		dev_err(smmu->dev, "failed to get runtime PM: %d\n", ret);
+		return;
+	}
+
+	reg =  arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR);
+	reg &= ~GFX_ACTLR_PRR;
+	if (set)
+		reg |= FIELD_PREP(GFX_ACTLR_PRR, 1);
+	arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg);
+	pm_runtime_put_autosuspend(smmu->dev);
+}
+
+static void qcom_adreno_smmu_set_prr_addr(const void *cookie, phys_addr_t page_addr)
+{
+	struct arm_smmu_domain *smmu_domain = (void *)cookie;
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	int ret;
+
+	ret = pm_runtime_resume_and_get(smmu->dev);
+	if (ret < 0) {
+		dev_err(smmu->dev, "failed to get runtime PM: %d\n", ret);
+		return;
+	}
+
+	writel_relaxed(lower_32_bits(page_addr),
+				smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR);
+	writel_relaxed(upper_32_bits(page_addr),
+				smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR);
+	pm_runtime_put_autosuspend(smmu->dev);
+}
+
 #define QCOM_ADRENO_SMMU_GPU_SID 0

 static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
@@ -210,6 +253,7 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
 static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
 		struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
 {
+	const struct device_node *np = smmu_domain->smmu->dev->of_node;
 	struct adreno_smmu_priv *priv;

 	smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
@@ -239,6 +283,14 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
 	priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
 	priv->set_stall = qcom_adreno_smmu_set_stall;
 	priv->resume_translation = qcom_adreno_smmu_resume_translation;
+	priv->set_prr_bit = NULL;
+	priv->set_prr_addr = NULL;
+
+	if (of_device_is_compatible(np, "qcom,smmu-500") &&
+			of_device_is_compatible(np, "qcom,adreno-smmu")) {
+		priv->set_prr_bit = qcom_adreno_smmu_set_prr_bit;
+		priv->set_prr_addr = qcom_adreno_smmu_set_prr_addr;
+	}

 	return 0;
 }
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index e2aeb511ae90..2dbf3243b5ad 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -154,6 +154,8 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_SCTLR_M		BIT(0)

 #define ARM_SMMU_CB_ACTLR		0x4
+#define ARM_SMMU_GFX_PRR_CFG_LADDR	0x6008
+#define ARM_SMMU_GFX_PRR_CFG_UADDR	0x600C

 #define ARM_SMMU_CB_RESUME		0x8
 #define ARM_SMMU_RESUME_TERMINATE	BIT(0)
diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h
index c637e0997f6d..614665153b3e 100644
--- a/include/linux/adreno-smmu-priv.h
+++ b/include/linux/adreno-smmu-priv.h
@@ -50,6 +50,18 @@ struct adreno_smmu_fault_info {
  *                 the GPU driver must call resume_translation()
  * @resume_translation: Resume translation after a fault
  *
+ * *CAUTION* : PRR callbacks (set_prr_bit/set_prr_addr) are NULL terminated for
+ *             targets without PRR support. Exercise caution and verify target
+ *             capabilities before invoking these callbacks to prevent potential
+ *             runtime errors or unexpected behavior.
+ *
+ * @set_prr_bit:   Extendible interface to be used by GPU to modify the
+ *		   ACTLR register bits, currently used to configure
+ *		   Partially-Resident-Region (PRR) bit for feature's
+ *		   setup and reset sequence as requested.
+ * @set_prr_addr:  Configure the PRR_CFG_*ADDR register with the
+ *		   physical address of PRR page passed from
+ *		   GPU driver.
  *
  * The GPU driver (drm/msm) and adreno-smmu work together for controlling
  * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
@@ -67,6 +79,8 @@ struct adreno_smmu_priv {
     void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
     void (*set_stall)(const void *cookie, bool enabled);
     void (*resume_translation)(const void *cookie, bool terminate);
+    void (*set_prr_bit)(const void *cookie, bool set);
+    void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
 };

 #endif /* __ADRENO_SMMU_PRIV_H */
--
2.34.1



From quic_bibekkum at quicinc.com  Thu Dec 12 07:14:01 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Thu, 12 Dec 2024 20:44:01 +0530
Subject: [PATCH v18 4/5] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
In-Reply-To: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
References: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
Message-ID: <20241212151402.159102-5-quic_bibekkum@quicinc.com>

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.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 33 ++++++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h |  1 +
 2 files changed, 34 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 818fdbd706da..c6614be01d77 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -250,14 +250,37 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
 	return true;
 }

+static void qcom_smmu_set_actlr_dev(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
+		const struct of_device_id *client_match)
+{
+	const struct of_device_id *match =
+			of_match_device(client_match, dev);
+
+	if (!match) {
+		dev_dbg(dev, "no ACTLR settings present\n");
+		return;
+	}
+
+	arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR, (unsigned long)match->data);
+}
+
 static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
 		struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
 {
 	const struct device_node *np = smmu_domain->smmu->dev->of_node;
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+	const struct of_device_id *client_match;
+	int cbndx = smmu_domain->cfg.cbndx;
 	struct adreno_smmu_priv *priv;

 	smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;

+	client_match = qsmmu->data->client_match;
+
+	if (client_match)
+		qcom_smmu_set_actlr_dev(dev, smmu, cbndx, client_match);
+
 	/* Only enable split pagetables for the GPU device (SID 0) */
 	if (!qcom_adreno_smmu_is_gpu_device(dev))
 		return 0;
@@ -321,8 +344,18 @@ 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 of_device_id *client_match;
+	int cbndx = smmu_domain->cfg.cbndx;
+
 	smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;

+	client_match = qsmmu->data->client_match;
+
+	if (client_match)
+		qcom_smmu_set_actlr_dev(dev, smmu, cbndx, client_match);
+
 	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 b55cd3e3ae48..8addd453f5f1 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
@@ -28,6 +28,7 @@ struct qcom_smmu_match_data {
 	const struct qcom_smmu_config *cfg;
 	const struct arm_smmu_impl *impl;
 	const struct arm_smmu_impl *adreno_impl;
+	const struct of_device_id * const client_match;
 };

 irqreturn_t qcom_smmu_context_fault(int irq, void *dev);
--
2.34.1



From Frank.li at nxp.com  Thu Dec 12 07:13:09 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 12 Dec 2024 10:13:09 -0500
Subject: [PATCH v2 4/5] ASoC: SOF: imx: add driver for imx95
In-Reply-To: <c47710a5-7e53-48b1-bd6b-c0123865aee5@gmail.com>
References: <20241113195240.3699-1-laurentiumihalcea111@gmail.com>
 <20241113195240.3699-5-laurentiumihalcea111@gmail.com>
 <ZzUJQCeWclsrr/lr@lizhi-Precision-Tower-5810>
 <c47710a5-7e53-48b1-bd6b-c0123865aee5@gmail.com>
Message-ID: <Z1r9hWH1ioR5vI5H@lizhi-Precision-Tower-5810>

On Thu, Dec 12, 2024 at 01:11:29PM +0200, Laurentiu Mihalcea wrote:
>
>
> On 11/13/2024 10:17 PM, Frank Li wrote:
> > On Wed, Nov 13, 2024 at 02:52:39PM -0500, Laurentiu Mihalcea wrote:
> >> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> >>
> >> Add SOF driver for imx95.
> >>
> >> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> >> ---
> >>  sound/soc/sof/imx/Kconfig  |   8 +
> >>  sound/soc/sof/imx/Makefile |   2 +
> >>  sound/soc/sof/imx/imx95.c  | 401 +++++++++++++++++++++++++++++++++++++
> > why not reused exist one? look likes simular.
> >
> > Frank
> the SOF drivers do indeed have some similarities, but each of them has their own quirks which IMO makes it a bit harder to add the 95 support. We need to figure out the common parts and then move them to imx-common, but I believe this can be solved incrementally.

You should create common part firstly, then implement equal function with
existed part. Finially add imx95 part.

Frank

> >
> >>  3 files changed, 411 insertions(+)
> >>  create mode 100644 sound/soc/sof/imx/imx95.c
> >>
> >> diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig
> >> index 4751b04d5e6f..51a70a193533 100644
> >> --- a/sound/soc/sof/imx/Kconfig
> >> +++ b/sound/soc/sof/imx/Kconfig
> >> @@ -50,4 +50,12 @@ config SND_SOC_SOF_IMX8ULP
> >>  	  Say Y if you have such a device.
> >>  	  If unsure select "N".
> >>
> >> +config SND_SOC_SOF_IMX95
> >> +	tristate "SOF support for i.MX95"
> >> +	depends on IMX_DSP
> >> +	help
> >> +	  This adds support for Sound Open Firmware for NXP i.MX95 platforms.
> >> +	  Say Y if you have such a device.
> >> +	  If unsure select "N".
> >> +
> >>  endif ## SND_SOC_SOF_IMX_TOPLEVEL
> >> diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile
> >> index be0bf0736dfa..715ac3798668 100644
> >> --- a/sound/soc/sof/imx/Makefile
> >> +++ b/sound/soc/sof/imx/Makefile
> >> @@ -2,10 +2,12 @@
> >>  snd-sof-imx8-y := imx8.o
> >>  snd-sof-imx8m-y := imx8m.o
> >>  snd-sof-imx8ulp-y := imx8ulp.o
> >> +snd-sof-imx95-y := imx95.o
> >>
> >>  snd-sof-imx-common-y := imx-common.o
> >>
> >>  obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o
> >>  obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o
> >>  obj-$(CONFIG_SND_SOC_SOF_IMX8ULP) += snd-sof-imx8ulp.o
> >> +obj-$(CONFIG_SND_SOC_SOF_IMX95) += snd-sof-imx95.o
> >>  obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o
> >> diff --git a/sound/soc/sof/imx/imx95.c b/sound/soc/sof/imx/imx95.c
> >> new file mode 100644
> >> index 000000000000..5a0e44f5bd48
> >> --- /dev/null
> >> +++ b/sound/soc/sof/imx/imx95.c
> >> @@ -0,0 +1,401 @@
> >> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
> >> +/*
> >> + * Copyright 2024 NXP
> >> + */
> >> +
> >> +#include <linux/arm-smccc.h>
> >> +#include <linux/clk.h>
> >> +#include <linux/firmware/imx/dsp.h>
> >> +#include <linux/module.h>
> >> +#include <linux/of_platform.h>
> >> +#include <linux/of_reserved_mem.h>
> >> +#include <sound/sof.h>
> >> +
> >> +#include "../sof-of-dev.h"
> >> +#include "../ops.h"
> >> +
> >> +#define IMX_SIP_SRC 0xC2000005
> >> +#define IMX_SIP_SRC_M_RESET_ADDR_SET 0x03
> >> +
> >> +#define IMX95_CPU_VEC_FLAGS_BOOT BIT(29)
> >> +
> >> +#define IMX_SIP_LMM 0xC200000F
> >> +#define IMX_SIP_LMM_BOOT 0x0
> >> +#define IMX_SIP_LMM_SHUTDOWN 0x1
> >> +
> >> +#define IMX95_M7_LM_ID 0x1
> >> +
> >> +#define MBOX_DSPBOX_OFFSET 0x1000
> >> +#define MBOX_WINDOW_OFFSET 0x6000000
> >> +
> >> +struct imx95_priv {
> >> +	struct platform_device *ipc_dev;
> >> +	struct imx_dsp_ipc *ipc_handle;
> >> +	resource_size_t bootaddr;
> >> +};
> >> +
> >> +static void imx95_ipc_handle_reply(struct imx_dsp_ipc *ipc)
> >> +{
> >> +	unsigned long flags;
> >> +	struct snd_sof_dev *sdev = imx_dsp_get_data(ipc);
> >> +
> >> +	spin_lock_irqsave(&sdev->ipc_lock, flags);
> >> +	snd_sof_ipc_process_reply(sdev, 0);
> >> +	spin_unlock_irqrestore(&sdev->ipc_lock, flags);
> >> +}
> >> +
> >> +static void imx95_ipc_handle_request(struct imx_dsp_ipc *ipc)
> >> +{
> >> +	snd_sof_ipc_msgs_rx(imx_dsp_get_data(ipc));
> >> +}
> >> +
> >> +static struct imx_dsp_ops ipc_ops = {
> >> +	.handle_reply = imx95_ipc_handle_reply,
> >> +	.handle_request = imx95_ipc_handle_request,
> >> +};
> >> +
> >> +static int imx95_disable_enable_core(bool enable)
> >> +{
> >> +	struct arm_smccc_res res;
> >> +
> >> +	if (enable)
> >> +		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_BOOT, IMX95_M7_LM_ID,
> >> +			      0, 0, 0, 0, 0, &res);
> >> +	else
> >> +		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_SHUTDOWN, IMX95_M7_LM_ID,
> >> +			      0, 0, 0, 0, 0, &res);
> >> +
> >> +	return res.a0;
> >> +}
> >> +
> >> +static int imx95_run(struct snd_sof_dev *sdev)
> >> +{
> >> +	return imx95_disable_enable_core(true);
> >> +}
> >> +
> >> +static int imx95_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
> >> +{
> >> +	struct imx95_priv *priv = sdev->pdata->hw_pdata;
> >> +
> >> +	sof_mailbox_write(sdev, sdev->host_box.offset,
> >> +			  msg->msg_data, msg->msg_size);
> >> +
> >> +	imx_dsp_ring_doorbell(priv->ipc_handle, 0);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int imx95_get_mailbox_offset(struct snd_sof_dev *sdev)
> >> +{
> >> +	return MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
> >> +}
> >> +
> >> +static int imx95_get_bar_index(struct snd_sof_dev *sdev, u32 type)
> >> +{
> >> +	switch (type) {
> >> +	case SOF_FW_BLK_TYPE_SRAM:
> >> +		return type;
> >> +	default:
> >> +		return -EINVAL;
> >> +	}
> >> +}
> >> +
> >> +static int imx95_get_window_offset(struct snd_sof_dev *sdev, u32 id)
> >> +{
> >> +	return MBOX_WINDOW_OFFSET;
> >> +}
> >> +
> >> +static int imx95_set_power_state(struct snd_sof_dev *sdev,
> >> +				 const struct sof_dsp_power_state *target_state)
> >> +{
> >> +	sdev->dsp_power_state = *target_state;
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int imx95_suspend_resume(struct snd_sof_dev *sdev, bool suspend)
> >> +{
> >> +	struct imx95_priv *priv;
> >> +	int ret, i;
> >> +
> >> +	priv = sdev->pdata->hw_pdata;
> >> +
> >> +	if (suspend) {
> >> +		ret = imx95_disable_enable_core(false);
> >> +		if (ret) {
> >> +			dev_err(sdev->dev, "failed to stop core\n");
> >> +			return ret;
> >> +		}
> >> +	}
> >> +
> >> +	for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
> >> +		if (suspend)
> >> +			imx_dsp_free_channel(priv->ipc_handle, i);
> >> +		else
> >> +			imx_dsp_request_channel(priv->ipc_handle, i);
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int imx95_runtime_resume(struct snd_sof_dev *sdev)
> >> +{
> >> +	int ret;
> >> +	const struct sof_dsp_power_state target_state = {
> >> +		.state = SOF_DSP_PM_D0,
> >> +	};
> >> +
> >> +	ret = imx95_suspend_resume(sdev, false);
> >> +	if (ret < 0) {
> >> +		dev_err(sdev->dev, "failed to runtime resume: %d\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
> >> +}
> >> +
> >> +static int imx95_resume(struct snd_sof_dev *sdev)
> >> +{
> >> +	int ret;
> >> +	const struct sof_dsp_power_state target_state = {
> >> +		.state = SOF_DSP_PM_D0,
> >> +	};
> >> +
> >> +	ret = imx95_suspend_resume(sdev, false);
> >> +	if (ret < 0) {
> >> +		dev_err(sdev->dev, "failed to resume: %d\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	if (pm_runtime_suspended(sdev->dev)) {
> >> +		pm_runtime_disable(sdev->dev);
> >> +		pm_runtime_set_active(sdev->dev);
> >> +		pm_runtime_mark_last_busy(sdev->dev);
> >> +		pm_runtime_enable(sdev->dev);
> >> +		pm_runtime_idle(sdev->dev);
> >> +	}
> >> +
> >> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
> >> +}
> >> +
> >> +static int imx95_runtime_suspend(struct snd_sof_dev *sdev)
> >> +{
> >> +	int ret;
> >> +	const struct sof_dsp_power_state target_state = {
> >> +		.state = SOF_DSP_PM_D3,
> >> +	};
> >> +
> >> +	ret = imx95_suspend_resume(sdev, true);
> >> +	if (ret < 0) {
> >> +		dev_err(sdev->dev, "failed to runtime suspend: %d\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
> >> +}
> >> +
> >> +static int imx95_suspend(struct snd_sof_dev *sdev, unsigned int target_state)
> >> +{
> >> +	int ret;
> >> +	const struct sof_dsp_power_state target_power_state = {
> >> +		.state = target_state,
> >> +	};
> >> +
> >> +	if (!pm_runtime_suspended(sdev->dev)) {
> >> +		ret = imx95_suspend_resume(sdev, true);
> >> +		if (ret < 0) {
> >> +			dev_err(sdev->dev, "failed to suspend: %d\n", ret);
> >> +			return ret;
> >> +		}
> >> +	}
> >> +
> >> +	return snd_sof_dsp_set_power_state(sdev, &target_power_state);
> >> +}
> >> +
> >> +static struct snd_soc_dai_driver imx95_dai[] = {
> >> +	{
> >> +		.name = "sai3",
> >> +		.playback = {
> >> +			.channels_min = 1,
> >> +			.channels_max = 32,
> >> +		},
> >> +		.capture = {
> >> +			.channels_min = 1,
> >> +			.channels_max = 32,
> >> +		},
> >> +	},
> >> +};
> >> +
> >> +static int imx95_probe(struct snd_sof_dev *sdev)
> >> +{
> >> +	struct platform_device *pdev;
> >> +	struct imx95_priv *priv;
> >> +	struct resource *res;
> >> +	struct arm_smccc_res smc_ret;
> >> +	int ret;
> >> +
> >> +	pdev = container_of(sdev->dev, struct platform_device, dev);
> >> +
> >> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> >> +	if (!priv)
> >> +		return dev_err_probe(&pdev->dev, -ENOMEM, "failed to alloc priv\n");
> >> +
> >> +	sdev->pdata->hw_pdata = priv;
> >> +
> >> +	/* map SRAM */
> >> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> +	if (!res)
> >> +		return dev_err_probe(&pdev->dev, -ENODEV,
> >> +				     "failed to fetch SRAM region\n");
> >> +
> >> +	sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap(&pdev->dev, res->start,
> >> +						       resource_size(res));
> >> +	if (IS_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]))
> >> +		return dev_err_probe(&pdev->dev,
> >> +				     PTR_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]),
> >> +				     "failed to map SRAM region\n");
> >> +
> >> +	sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
> >> +	sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
> >> +	sdev->dsp_box.offset = MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
> >> +	priv->bootaddr = res->start;
> >> +
> >> +	ret = of_reserved_mem_device_init(sdev->dev);
> >> +	if (ret)
> >> +		return dev_err_probe(&pdev->dev, ret,
> >> +				     "failed to bind DMA region\n");
> >> +
> >> +	priv->ipc_dev = platform_device_register_data(&pdev->dev, "imx-dsp",
> >> +						      PLATFORM_DEVID_NONE,
> >> +						      pdev, sizeof(*pdev));
> >> +	if (IS_ERR(priv->ipc_dev))
> >> +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->ipc_dev),
> >> +				     "failed to create IPC device\n");
> >> +
> >> +	priv->ipc_handle = dev_get_drvdata(&priv->ipc_dev->dev);
> >> +	if (!priv->ipc_handle) {
> >> +		ret = -EPROBE_DEFER;
> >> +		dev_err(&pdev->dev, "failed to fetch ipc handle\n");
> >> +		goto err_unregister_ipc_dev;
> >> +	}
> >> +
> >> +	priv->ipc_handle->ops = &ipc_ops;
> >> +	imx_dsp_set_data(priv->ipc_handle, sdev);
> >> +
> >> +	/* set core boot reset address */
> >> +	arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M_RESET_ADDR_SET, priv->bootaddr,
> >> +		      IMX95_CPU_VEC_FLAGS_BOOT, 0, 0, 0, 0, &smc_ret);
> >> +	if ((int)smc_ret.a0 < 0) {
> >> +		ret = smc_ret.a0;
> >> +		dev_err(&pdev->dev, "failed to set boot address: %d", ret);
> >> +		goto err_unregister_ipc_dev;
> >> +	}
> >> +
> >> +	return 0;
> >> +
> >> +err_unregister_ipc_dev:
> >> +	platform_device_unregister(priv->ipc_dev);
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +static void imx95_remove(struct snd_sof_dev *sdev)
> >> +{
> >> +	struct imx95_priv *priv;
> >> +
> >> +	priv = sdev->pdata->hw_pdata;
> >> +
> >> +	if (imx95_disable_enable_core(false))
> >> +		dev_err(sdev->dev, "failed to stop core\n");
> >> +
> >> +	platform_device_unregister(priv->ipc_dev);
> >> +}
> >> +
> >> +static const struct snd_sof_dsp_ops sof_imx95_ops = {
> >> +	.probe = imx95_probe,
> >> +	.remove = imx95_remove,
> >> +
> >> +	/* mandatory "DSP" ops */
> >> +	.run = imx95_run,
> >> +	.block_read = sof_block_read,
> >> +	.block_write = sof_block_write,
> >> +	.send_msg = imx95_send_msg,
> >> +	.load_firmware = snd_sof_load_firmware_memcpy,
> >> +	.ipc_msg_data = sof_ipc_msg_data,
> >> +
> >> +	.mailbox_read = sof_mailbox_read,
> >> +	.mailbox_write = sof_mailbox_write,
> >> +
> >> +	.get_mailbox_offset = imx95_get_mailbox_offset,
> >> +	.get_bar_index = imx95_get_bar_index,
> >> +	.get_window_offset = imx95_get_window_offset,
> >> +
> >> +	.pcm_open = sof_stream_pcm_open,
> >> +	.pcm_close = sof_stream_pcm_close,
> >> +	.set_stream_data_offset = sof_set_stream_data_offset,
> >> +
> >> +	.runtime_suspend = imx95_runtime_suspend,
> >> +	.runtime_resume = imx95_runtime_resume,
> >> +
> >> +	.resume = imx95_resume,
> >> +	.suspend = imx95_suspend,
> >> +
> >> +	.set_power_state = imx95_set_power_state,
> >> +
> >> +	.drv = imx95_dai,
> >> +	.num_drv = ARRAY_SIZE(imx95_dai),
> >> +
> >> +	.hw_info = SNDRV_PCM_INFO_MMAP |
> >> +		   SNDRV_PCM_INFO_MMAP_VALID |
> >> +		   SNDRV_PCM_INFO_INTERLEAVED |
> >> +		   SNDRV_PCM_INFO_PAUSE |
> >> +		   SNDRV_PCM_INFO_BATCH |
> >> +		   SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
> >> +};
> >> +
> >> +static struct snd_sof_of_mach sof_imx95_machs[] = {
> >> +	{
> >> +		.compatible = "fsl,imx95-19x19-evk",
> >> +		.sof_tplg_filename = "sof-imx95-wm8962.tplg",
> >> +		.drv_name = "asoc-audio-graph-card2",
> >> +	},
> >> +	{
> >> +	},
> >> +};
> >> +
> >> +static struct sof_dev_desc sof_of_imx95_desc = {
> >> +	.of_machines = sof_imx95_machs,
> >> +	.ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
> >> +	.ipc_default = SOF_IPC_TYPE_3,
> >> +	.default_fw_path = {
> >> +		[SOF_IPC_TYPE_3] = "imx/sof",
> >> +	},
> >> +	.default_tplg_path = {
> >> +		[SOF_IPC_TYPE_3] = "imx/sof-tplg",
> >> +	},
> >> +	.default_fw_filename = {
> >> +		[SOF_IPC_TYPE_3] = "sof-imx95.ri",
> >> +	},
> >> +	.ops = &sof_imx95_ops,
> >> +};
> >> +
> >> +static const struct of_device_id sof_of_imx95_ids[] = {
> >> +	{ .compatible = "fsl,imx95-cm7-sof", .data = &sof_of_imx95_desc },
> >> +	{ },
> >> +};
> >> +MODULE_DEVICE_TABLE(of, sof_of_imx95_ids);
> >> +
> >> +static struct platform_driver snd_sof_of_imx95_driver = {
> >> +	.probe = sof_of_probe,
> >> +	.remove = sof_of_remove,
> >> +	.driver = {
> >> +		.name = "sof-audio-of-imx95",
> >> +		.pm = &sof_of_pm,
> >> +		.of_match_table = sof_of_imx95_ids,
> >> +	},
> >> +};
> >> +module_platform_driver(snd_sof_of_imx95_driver);
> >> +
> >> +MODULE_LICENSE("Dual BSD/GPL");
> >> +MODULE_DESCRIPTION("SOF support for i.MX95 platforms");
> >> +MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>");
> >> --
> >> 2.34.1
> >>
>


From joey.gouly at arm.com  Thu Dec 12 07:14:06 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Thu, 12 Dec 2024 15:14:06 +0000
Subject: [PATCH 6.6 v1] KVM: arm64: Disable MPAM visibility by default and ignore VMM writes
Message-ID: <20241212151406.1436382-1-joey.gouly@arm.com>

From: James Morse <james.morse at arm.com>

commit 6685f5d572c22e1003e7c0d089afe1c64340ab1f upstream.

commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits in
ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to guests,
but didn't add trap handling. A previous patch supplied the missing trap
handling.

Existing VMs that have the MPAM field of ID_AA64PFR0_EL1 set need to
be migratable, but there is little point enabling the MPAM CPU
interface on new VMs until there is something a guest can do with it.

Clear the MPAM field from the guest's ID_AA64PFR0_EL1 and on hardware
that supports MPAM, politely ignore the VMMs attempts to set this bit.

Guests exposed to this bug have the sanitised value of the MPAM field,
so only the correct value needs to be ignored. This means the field
can continue to be used to block migration to incompatible hardware
(between MPAM=1 and MPAM=5), and the VMM can't rely on the field
being ignored.

Signed-off-by: James Morse <james.morse at arm.com>
Co-developed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Reviewed-by: Gavin Shan <gshan at redhat.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/r/20241030160317.2528209-7-joey.gouly at arm.com
Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
[ joey: fixed up merge conflict, no ID_FILTERED macro in 6.6 ]
Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: stable at vger.kernel.org # 6.6.x
Cc: Vitaly Chikunov <vt at altlinux.org>
Link: https://lore.kernel.org/linux-arm-kernel/20241202045830.e4yy3nkvxtzaybxk at altlinux.org/
---

This fixes an issue seen when using KVM with a 6.6 host kernel, and
newer (6.13+) kernels in the guest.

Tested with a stripped down version of set_id_regs from the original
patch series.

 arch/arm64/kvm/sys_regs.c | 52 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 370a1a7bd369..2031703424ea 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1330,6 +1330,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
 			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
 
 		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MPAM_frac);
 		break;
 	case SYS_ID_AA64ISAR1_EL1:
 		if (!vcpu_has_ptrauth(vcpu))
@@ -1472,6 +1473,13 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
 
 	val &= ~ID_AA64PFR0_EL1_AMU_MASK;
 
+	/*
+	 * MPAM is disabled by default as KVM also needs a set of PARTID to
+	 * program the MPAMVPMx_EL2 PARTID remapping registers with. But some
+	 * older kernels let the guest see the ID bit.
+	 */
+	val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
+
 	return val;
 }
 
@@ -1560,6 +1568,42 @@ static int set_id_dfr0_el1(struct kvm_vcpu *vcpu,
 	return set_id_reg(vcpu, rd, val);
 }
 
+static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
+			       const struct sys_reg_desc *rd, u64 user_val)
+{
+	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+	u64 mpam_mask = ID_AA64PFR0_EL1_MPAM_MASK;
+
+	/*
+	 * Commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits
+	 * in ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to
+	 * guests, but didn't add trap handling. KVM doesn't support MPAM and
+	 * always returns an UNDEF for these registers. The guest must see 0
+	 * for this field.
+	 *
+	 * But KVM must also accept values from user-space that were provided
+	 * by KVM. On CPUs that support MPAM, permit user-space to write
+	 * the sanitizied value to ID_AA64PFR0_EL1.MPAM, but ignore this field.
+	 */
+	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
+		user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
+
+	return set_id_reg(vcpu, rd, user_val);
+}
+
+static int set_id_aa64pfr1_el1(struct kvm_vcpu *vcpu,
+			       const struct sys_reg_desc *rd, u64 user_val)
+{
+	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
+	u64 mpam_mask = ID_AA64PFR1_EL1_MPAM_frac_MASK;
+
+	/* See set_id_aa64pfr0_el1 for comment about MPAM */
+	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
+		user_val &= ~ID_AA64PFR1_EL1_MPAM_frac_MASK;
+
+	return set_id_reg(vcpu, rd, user_val);
+}
+
 /*
  * cpufeature ID register user accessors
  *
@@ -2018,10 +2062,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_ID_AA64PFR0_EL1),
 	  .access = access_id_reg,
 	  .get_user = get_id_reg,
-	  .set_user = set_id_reg,
+	  .set_user = set_id_aa64pfr0_el1,
 	  .reset = read_sanitised_id_aa64pfr0_el1,
 	  .val = ID_AA64PFR0_EL1_CSV2_MASK | ID_AA64PFR0_EL1_CSV3_MASK, },
-	ID_SANITISED(ID_AA64PFR1_EL1),
+	{ SYS_DESC(SYS_ID_AA64PFR1_EL1),
+	  .access = access_id_reg,
+	  .get_user = get_id_reg,
+	  .set_user = set_id_aa64pfr1_el1,
+	  .reset = kvm_read_sanitised_id_reg, },
 	ID_UNALLOCATED(4,2),
 	ID_UNALLOCATED(4,3),
 	ID_SANITISED(ID_AA64ZFR0_EL1),
-- 
2.25.1



From quic_bibekkum at quicinc.com  Thu Dec 12 07:13:57 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Thu, 12 Dec 2024 20:43:57 +0530
Subject: [PATCH v18 0/5] iommu/arm-smmu: introduction of ACTLR implementation for Qualcomm SoCs
Message-ID: <20241212151402.159102-1-quic_bibekkum@quicinc.com>

This patch series consist of six parts and covers the following:

1. Provide option to re-enable context caching to retain prefetcher
   settings during reset and runtime suspend.

2. Remove cfg inside qcom_smmu structure and replace it with single
   pointer to qcom_smmu_match_data avoiding replication of multiple
   members from same.

3. Add support for ACTLR PRR bit setup via adreno-smmu-priv interface.

4. Introduce intital set of driver changes to implement ACTLR register
   for custom prefetcher settings in Qualcomm SoCs.

5. Add ACTLR data and support for qcom_smmu_500.

Changes in v18 from v17_RESEND:
 - 1/5 : No changes
 - 2/5 : No changes - reviewed-by tags collected
 - 3/5 : Addition of
   pm_runtime_resume_and_get()/pm_runtime_put_autosuspend()
   around register access of PRR related private interfaces
   as discussed in v17_RESEND.
 - 4/5, 5/5 : No changes - reviewed-by tags collected
 Link to v17_RESEND:
 https://lore.kernel.org/all/20241114160721.1527934-1-quic_bibekkum at quicinc.com/

Resend of v17:
 Addition of minor fix of the build warning reported by kernel test robot [1] by powerpc_random config [2].
 [1]:https://lore.kernel.org/all/202411140748.6mcFdJdO-lkp at intel.com/#t
 [2]:https://download.01.org/0day-ci/archive/20241114/202411140748.6mcFdJdO-lkp at intel.com/config

Changes in v17 from v16:
 Tags provided earlier not collected yet on patch 1/5, 3/5, 4/5, 5/5
 due to the following revisions:
 - 1/5 : Move the CPRE workaround out of qualcomm specific logic and gate with config
         , update the silicon-errata.rst file
 - 2/5 : No changes - reviewed-by tags collected
 - 3/5 : Move the compatible check before assignment of callback as suggested.
 - 4/5 : Add the actlr setting for *adreno variant* of MMU-500 as well.
 - 5/5 : Due to changes in 1/5, minor refactoring had to be done before adding table.
 Link to v16:
 https://lore.kernel.org/all/20241008125410.3422512-1-quic_bibekkum at quicinc.com/

Changes in v16 from v15:
 - Incorporate Dimitry's suggestion on patch 4/5 to use dev_dbg instead of dev_notice.
 - Fix kernel test robot warning [1] coming for 32bit architecture configuration.
 - Updatingthe tags
 [1]: https://lore.kernel.org/all/202409230343.Q8KnYl2w-lkp at intel.com/
 Link to v15:
 https://lore.kernel.org/all/20240920155813.3434021-1-quic_bibekkum at quicinc.com/

Changes in v15 from v14:
 - As discussed with Robin and Dmitry modify the actlr table and logic to use
   compatible string instead of sid, mask for device matching which is
   similar to qcom_smmu_client_of_match mechanism.
 - Expand the comment in qcom_smmu500_reset to document reason why CPRE bit is re-enabled again
   after arm_mmu500_reset resets the bit.
 - Rearrange the series in order to keep prefetch setting patches in the end.
 Link to v14:
 https://lore.kernel.org/all/20240816174259.2056829-1-quic_bibekkum at quicinc.com/

Changes in v14 from v13:
 Patch 6/6:
 - As discussed incorprate changes to carry out PRR implementation only for
   targets based on MMU-500 by using compat string based SMMU version detection.
 - Split the set_actlr interface into two separate interface namely set_prr_bit
   and set_prr_addr to set the prr enable bit and prr page address resepectively.
 Patch 3/6:
  - Fix a bug in gfx actlr_config which is uncovered while testing the gfx actlr setting in sc7280
    during PRR experiment which prevented clients on certain sids of gfx smmmu to be skipped during
    setting up of the ACTLR values : Fix involves swapping the arguments passed in smr_is_subset to make
     device smr <from devicetree> a subset of actlr_config table entries < defined in the driver>.
 Patch 4/6, 5/6:
  - Sort the actlr table values in increasing order of the SIDs.
 Link to v13:
 https://lore.kernel.org/all/20240628140435.1652374-1-quic_bibekkum at quicinc.com/

Changes in v13 from v12:
 - Fix the compilation issues reported by kernel test robot [1].
 [1]: https://lore.kernel.org/all/202406281241.xEX0TWjt-lkp at intel.com/#t
 Link to v12:
 https://lore.kernel.org/all/20240626143020.3682243-1-quic_bibekkum at quicinc.com/

Changes in v12 from v11:
 Changes to incorporate suggestion from Rob:
 - Fix the set and reset logic for prr bit as pointed out in v11-6/6.
 - Rename set_actlr_bit function name to set_prr.
 - Add extension for PRR name as Partially-Resident-Region in comments
   for set_prr function.
 - Add few missing sids for sc7280 in patch-5/6.
 Link to v11:
 https://lore.kernel.org/all/20240605121713.3596499-1-quic_bibekkum at quicinc.com/

Changes in v11 from v10:
 - Include a new patch 6/6 to add support for ACTLR PRR bit
   through adreno-smmu-priv interface as suggested by Rob and Dmitry.
 Link to v10:
 https://lore.kernel.org/all/20240524131800.2288259-1-quic_bibekkum at quicinc.com/

Changes in v10 from v9:
 - Added reviewed-by tags 1/5,2/5,3/5.
 Changes incorporated:
 - Remove redundant PRR bit setting from gfx actlr table(patch 4/5,5/5)
   as this bit needs special handling in the gfx driver along with
   the associated register settings.
 Link to discussion on PRR bit:
 https://lore.kernel.org/all/f2222714-1e00-424e-946d-c314d55541b8 at quicinc.com/
 Link to v9:
 https://lore.kernel.org/all/20240123144543.9405-1-quic_bibekkum at quicinc.com/

Changes in v9 from v8:
 Changes to incorporate suggestions from Konrad as follows:
 - Re-wrap struct members of actlr_variant in patch 4/5,5/5
   in a cleaner way.
 - Move actlr_config members to the header.
 Link to v8:
 https://lore.kernel.org/all/20240116150411.23876-1-quic_bibekkum at quicinc.com/

Changes in v8 from v7:
 - Added reviewed-by tags on patch 1/5, 2/5.
 Changes to incorporate suggestions from Pavan and Konrad:
 - Remove non necessary extra lines.
 - Use num_smmu and num_actlrcfg to store the array size and use the
   same to traverse the table and save on sentinel space along with
   indentation levels.
 - Refactor blocks containing qcom_smmu_set_actlr to remove block
   repetition in patch 3/5.
 - Change copyright year from 2023 to 2022-2023 in patch 3/5.
 - Modify qcom_smmu_match_data.actlrvar and actlr_variant.actlrcfg to
   const pointer to a const resource.
 - use C99 designated initializers and put the address first.
 Link to v7:
 https://lore.kernel.org/all/20240109114220.30243-1-quic_bibekkum at quicinc.com/

Changes in v7 from v6:
 Changes to incorporate suggestions from Dmitry as follows:
 - Use io_start address instead of compatible string to identify the
   correct instance by comparing with smmu start address and check for
   which smmu the corresponding actlr table is to be picked.
Link to v6:
https://lore.kernel.org/all/20231220133808.5654-1-quic_bibekkum at quicinc.com/

Changes in v6 from v5:
 - Remove extra Suggested-by tags.
 - Add return check for arm_mmu500_reset in 1/5 as discussed.
Link to v5:
https://lore.kernel.org/all/20231219135947.1623-1-quic_bibekkum at quicinc.com/

Changes in v5 from v4:
 New addition:
 - Modify copyright year in arm-smmu-qcom.h to 2023 from 2022.
 Changes to incorporate suggestions from Dmitry as follows:
 - Modify the defines for prefetch in (foo << bar) format
   as suggested.(FIELD_PREP could not be used in defines
   is not inside any block/function)
 Changes to incorporate suggestions from Konrad as follows:
 - Shift context caching enablement patch as 1/5 instead of 5/5 to
   be picked up as independent patch.
 - Fix the codestyle to orient variables in reverse xmas tree format
   for patch 1/5.
 - Fix variable name in patch 1/5 as suggested.
 Link to v4:
https://lore.kernel.org/all/20231215101827.30549-1-quic_bibekkum at quicinc.com/

Changes in v4 from v3:
 New addition:
 - Remove actlrcfg_size and use NULL end element instead to traverse
   the actlr table, as this would be a cleaner approach by removing
   redundancy of actlrcfg_size.
 - Renaming of actlr set function to arm_smmu_qcom based proprietary
   convention.
 - break from loop once sid is found and ACTLR value is initialized
   in qcom_smmu_set_actlr.
 - Modify the GFX prefetch value separating into 2 sensible defines.
 - Modify comments for prefetch defines as per SMMU-500 TRM.
 Changes to incorporate suggestions from Konrad as follows:
 - Use Reverse-Christmas-tree sorting wherever applicable.
 - Pass arguments directly to arm_smmu_set_actlr instead of creating
   duplicate variables.
 - Use array indexing instead of direct pointer addressed by new
   addition of eliminating actlrcfg_size.
 - Switch the HEX value's case from upper to lower case in SC7280
   actlrcfg table.
 Changes to incorporate suggestions from Dmitry as follows:
 - Separate changes not related to ACTLR support to different commit
   with patch 5/5.
 - Using pointer to struct for arguments in smr_is_subset().
 Changes to incorporate suggestions from Bjorn as follows:
 - fix the commit message for patch 2/5 to properly document the
   value space to avoid confusion.
 Fixed build issues reported by kernel test robot [1] for
 arm64-allyesconfig [2].
 [1]: https://lore.kernel.org/all/202312011750.Pwca3TWE-lkp at intel.com/
 [2]:
https://download.01.org/0day-ci/archive/20231201/202312011750.Pwca3TWE-lkp at intel.com/config
 Link to v3:
https://lore.kernel.org/all/20231127145412.3981-1-quic_bibekkum at quicinc.com/

Changes in v3 from v2:
 New addition:
 - Include patch 3/4 for adding ACTLR support and data for SC7280.
 - Add driver changes for actlr support in gpu smmu.
 - Add target wise actlr data and implementation ops for gpu smmu.
 Changes to incorporate suggestions from Robin as follows:
 - Match the ACTLR values with individual corresponding SID instead
   of assuming that any SMR will be programmed to match a superset of
   the data.
 - Instead of replicating each elements from qcom_smmu_match_data to
   qcom_smmu structre during smmu device creation, replace the
   replicated members with qcom_smmu_match_data structure inside
   qcom_smmu structre and handle the dereference in places that
   requires them.
 Changes to incorporate suggestions from Dmitry and Konrad as follows:
 - Maintain actlr table inside a single structure instead of
   nested structure.
 - Rename prefetch defines to more appropriately describe their
   behavior.
 - Remove SM8550 specific implementation ops and roll back to default
   qcom_smmu_500_impl implementation ops.
 - Add back the removed comments which are NAK.
 - Fix commit description for patch 4/4.
 Link to v2:
https://lore.kernel.org/all/20231114135654.30475-1-quic_bibekkum at quicinc.com/

Changes in v2 from v1:
 - Incorporated suggestions on v1 from Dmitry,Konrad,Pratyush.
 - Added defines for ACTLR values.
 - Linked sm8550 implementation structure to corresponding
   compatible string.
 - Repackaged actlr value set implementation to separate function.
 - Fixed indentation errors.
 - Link to v1:
https://lore.kernel.org/all/20231103215124.1095-1-quic_bibekkum at quicinc.com/

Changes in v1 from RFC:
 - Incorporated suggestion form Robin on RFC
 - Moved the actlr data table into driver, instead of maintaining
   it inside soc specific DT and piggybacking on exisiting iommus
   property (iommu = <SID, MASK, ACTLR>) to set this value during
   smmu probe.
 - Link to RFC:
https://lore.kernel.org/all/a01e7e60-6ead-4a9e-ba90-22a8a6bbd03f at quicinc.com/

Bibek Kumar Patro (5):
  iommu/arm-smmu: re-enable context caching in smmu reset operation
  iommu/arm-smmu: refactor qcom_smmu structure to include single pointer
  iommu/arm-smmu: add support for PRR bit setup
  iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
  iommu/arm-smmu: add ACTLR data and support for qcom_smmu_500

 Documentation/arch/arm64/silicon-errata.rst   |   3 +-
 drivers/iommu/Kconfig                         |  12 ++
 drivers/iommu/arm/arm-smmu/arm-smmu-impl.c    |   5 +-
 .../iommu/arm/arm-smmu/arm-smmu-qcom-debug.c  |   2 +-
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c    | 120 +++++++++++++++++-
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h    |   3 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.h         |   2 +
 include/linux/adreno-smmu-priv.h              |  14 ++
 8 files changed, 155 insertions(+), 6 deletions(-)

--
2.34.1



From quic_bibekkum at quicinc.com  Thu Dec 12 07:13:58 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Thu, 12 Dec 2024 20:43:58 +0530
Subject: [PATCH v18 1/5] iommu/arm-smmu: re-enable context caching in smmu reset operation
In-Reply-To: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
References: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
Message-ID: <20241212151402.159102-2-quic_bibekkum@quicinc.com>

Default MMU-500 reset operation disables context caching in
prefetch buffer. It is however expected for context banks using
the ACTLR register to retain their prefetch value during reset
and runtime suspend.

Add config 'ARM_SMMU_MMU_500_CPRE_ERRATA' to gate this errata
workaround in default MMU-500 reset operation which defaults to
'Y' and provide option to disable workaround for context caching
in prefetch buffer as and when needed.

Suggested-by: Will Deacon <will at kernel.org>
Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
---
 Documentation/arch/arm64/silicon-errata.rst |  3 ++-
 drivers/iommu/Kconfig                       | 12 ++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu-impl.c  |  5 +++--
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index 65bfab1b1861..92207d55fd1c 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -198,7 +198,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V3     | #3312417        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
-| ARM            | MMU-500         | #841119,826419  | N/A                         |
+| ARM            | MMU-500         | #841119,826419  | ARM_SMMU_MMU_500_CPRE_ERRATA|
+|                |                 | #562869,1047329 |                             |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | MMU-600         | #1076982,1209401| N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index ade4e8cf2a3e..90ba5818af81 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -367,6 +367,18 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
 	  'arm-smmu.disable_bypass' will continue to override this
 	  config.

+config ARM_SMMU_MMU_500_CPRE_ERRATA
+	bool "Enable errata workaround for CPRE in SMMU reset path"
+	depends on ARM_SMMU
+	default y
+	help
+	  Say Y here (by default) to apply workaround to disable
+	  MMU-500's next-page prefetcher for sake of 4 known errata.
+
+	  Say N here only when it is sure that any errata related to
+	  prefetch enablement are not applicable on the platform.
+	  Refer silicon-errata.rst for info on errata IDs.
+
 config ARM_SMMU_QCOM
 	def_tristate y
 	depends on ARM_SMMU && ARCH_QCOM
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
index 99030e6b16e7..db9b9a8e139c 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
@@ -110,7 +110,6 @@ static struct arm_smmu_device *cavium_smmu_impl_init(struct arm_smmu_device *smm
 int arm_mmu500_reset(struct arm_smmu_device *smmu)
 {
 	u32 reg, major;
-	int i;
 	/*
 	 * On MMU-500 r2p0 onwards we need to clear ACR.CACHE_LOCK before
 	 * writes to the context bank ACTLRs will stick. And we just hope that
@@ -128,11 +127,12 @@ int arm_mmu500_reset(struct arm_smmu_device *smmu)
 	reg |= ARM_MMU500_ACR_SMTNMB_TLBEN | ARM_MMU500_ACR_S2CRB_TLBEN;
 	arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sACR, reg);

+#ifdef CONFIG_ARM_SMMU_MMU_500_CPRE_ERRATA
 	/*
 	 * Disable MMU-500's not-particularly-beneficial next-page
 	 * prefetcher for the sake of at least 5 known errata.
 	 */
-	for (i = 0; i < smmu->num_context_banks; ++i) {
+	for (int i = 0; i < smmu->num_context_banks; ++i) {
 		reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR);
 		reg &= ~ARM_MMU500_ACTLR_CPRE;
 		arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg);
@@ -140,6 +140,7 @@ int arm_mmu500_reset(struct arm_smmu_device *smmu)
 		if (reg & ARM_MMU500_ACTLR_CPRE)
 			dev_warn_once(smmu->dev, "Failed to disable prefetcher for errata workarounds, check SACR.CACHE_LOCK\n");
 	}
+#endif

 	return 0;
 }
--
2.34.1



From quic_bibekkum at quicinc.com  Thu Dec 12 07:13:59 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Thu, 12 Dec 2024 20:43:59 +0530
Subject: [PATCH v18 2/5] iommu/arm-smmu: refactor qcom_smmu structure to include single pointer
In-Reply-To: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
References: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
Message-ID: <20241212151402.159102-3-quic_bibekkum@quicinc.com>

qcom_smmu_match_data is static and constant so refactor qcom_smmu
to store single pointer to qcom_smmu_match_data instead of
replicating multiple child members of the same and handle the further
dereferences in the places that want them.

Suggested-by: Robin Murphy <robin.murphy at arm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reviewed-by: Rob Clark <robdclark at gmail.com>
Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c | 2 +-
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c       | 2 +-
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h       | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
index 548783f3f8e8..d03b2239baad 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
@@ -73,7 +73,7 @@ void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu)
 	if (__ratelimit(&rs)) {
 		dev_err(smmu->dev, "TLB sync timed out -- SMMU may be deadlocked\n");

-		cfg = qsmmu->cfg;
+		cfg = qsmmu->data->cfg;
 		if (!cfg)
 			return;

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 6372f3e25c4b..d26f5aea248e 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -507,7 +507,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
 		return ERR_PTR(-ENOMEM);

 	qsmmu->smmu.impl = impl;
-	qsmmu->cfg = data->cfg;
+	qsmmu->data = data;

 	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 3c134d1a6277..b55cd3e3ae48 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
@@ -8,7 +8,7 @@

 struct qcom_smmu {
 	struct arm_smmu_device smmu;
-	const struct qcom_smmu_config *cfg;
+	const struct qcom_smmu_match_data *data;
 	bool bypass_quirk;
 	u8 bypass_cbndx;
 	u32 stall_enabled;
--
2.34.1



From quic_bibekkum at quicinc.com  Thu Dec 12 07:14:02 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Thu, 12 Dec 2024 20:44:02 +0530
Subject: [PATCH v18 5/5] iommu/arm-smmu: add ACTLR data and support for qcom_smmu_500
In-Reply-To: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
References: <20241212151402.159102-1-quic_bibekkum@quicinc.com>
Message-ID: <20241212151402.159102-6-quic_bibekkum@quicinc.com>

Add ACTLR data table for qcom_smmu_500 including
corresponding data entry and set prefetch value by
way of a list of compatible strings.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 33 ++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index c6614be01d77..40f3a5a9f605 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -16,8 +16,40 @@

 #define QCOM_DUMMY_VAL	-1

+/*
+ * SMMU-500 TRM defines BIT(0) as CMTLB (Enable context caching in the
+ * macro TLB) and BIT(1) as CPRE (Enable context caching in the prefetch
+ * buffer). The remaining bits are implementation defined and vary across
+ * SoCs.
+ */
+
+#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 GFX_ACTLR_PRR          (1 << 5)

+static const struct of_device_id qcom_smmu_actlr_client_of_match[] = {
+	{ .compatible = "qcom,adreno",
+			.data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) },
+	{ .compatible = "qcom,adreno-gmu",
+			.data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) },
+	{ .compatible = "qcom,adreno-smmu",
+			.data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) },
+	{ .compatible = "qcom,fastrpc",
+			.data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) },
+	{ .compatible = "qcom,sc7280-mdss",
+			.data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) },
+	{ .compatible = "qcom,sc7280-venus",
+			.data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) },
+	{ .compatible = "qcom,sm8550-mdss",
+			.data = (const void *) (PREFETCH_DEFAULT | CMTLB) },
+	{ }
+};
+
 static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
 {
 	return container_of(smmu, struct qcom_smmu, smmu);
@@ -635,6 +667,7 @@ static const struct qcom_smmu_match_data qcom_smmu_500_impl0_data = {
 	.impl = &qcom_smmu_500_impl,
 	.adreno_impl = &qcom_adreno_smmu_500_impl,
 	.cfg = &qcom_smmu_impl0_cfg,
+	.client_match = qcom_smmu_actlr_client_of_match,
 };

 /*
--
2.34.1



From james.clark at linaro.org  Thu Dec 12 07:27:26 2024
From: james.clark at linaro.org (James Clark)
Date: Thu, 12 Dec 2024 15:27:26 +0000
Subject: [PATCH] coresight: docs: Remove target sink from examples
In-Reply-To: <9e53f5b9-d8a9-46b8-8ff1-7f018e2d9c06@os.amperecomputing.com>
References: <20241210144933.295798-1-james.clark@linaro.org>
 <9e53f5b9-d8a9-46b8-8ff1-7f018e2d9c06@os.amperecomputing.com>
Message-ID: <24299600-277f-48f4-9be5-cbd65ab6ddb7@linaro.org>



On 11/12/2024 6:01 pm, Steve Clevenger wrote:
> 
> Hi James,
> 
> I thought I'd mention this issue with multicore self-hosted trace. The
> perf command line syntax does not allow a sink "type" to be specified
> (e.g. @tmc_etf or @tmc_etr). For multicore, it doesn't make sense to
> specify a processor mapped sink as would be the case for single core
> trace. A sink "type" should be allowed to avoid the auto select default.
> In our case, the default is the ETF sink.
> 
> Thanks,
> Steve C.
> 

I'm sure it would be possible to add support for this, but I'm wondering 
if the real issue is that the default selection logic is wrong? Are you 
saying the default you get is ETF but you want ETR? And there is both 
for each ETM? The default selection logic isn't easy to summarize but it 
should prefer ETR (sysmem) over ETF (link sink), see coresight_find_sink().

It's probably better to fix that rather than add a new sink selection 
feature. Maybe if you shared a diagram of your coresight architecture it 
would help.

Thanks
James



From jason-jh.lin at mediatek.com  Thu Dec 12 07:33:43 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Thu, 12 Dec 2024 23:33:43 +0800
Subject: [PATCH 1/2] dt-bindings: display: mediatek: ovl: Modify rules for MT8195/MT8188
In-Reply-To: <20241212153344.27408-1-jason-jh.lin@mediatek.com>
References: <20241212153344.27408-1-jason-jh.lin@mediatek.com>
Message-ID: <20241212153344.27408-2-jason-jh.lin@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.com>

Modify rules for both MT8195 and MT8188.
Hardware capabilities include color formats and AFBC are
changed since MT8195, stop using the settings of MT8183.

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 .../bindings/display/mediatek/mediatek,ovl.yaml           | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index 9ea796a033b2..0ace12bbb623 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -36,16 +36,14 @@ properties:
           - enum:
               - mediatek,mt6795-disp-ovl
           - const: mediatek,mt8173-disp-ovl
-      - items:
-          - enum:
-              - mediatek,mt8188-disp-ovl
-              - mediatek,mt8195-disp-ovl
-          - const: mediatek,mt8183-disp-ovl
       - items:
           - enum:
               - mediatek,mt8186-disp-ovl
               - mediatek,mt8365-disp-ovl
           - const: mediatek,mt8192-disp-ovl
+      - items:
+          - const: mediatek,mt8188-disp-ovl
+          - const: mediatek,mt8195-disp-ovl
 
   reg:
     maxItems: 1
-- 
2.43.0



From alexandre.torgue at foss.st.com  Thu Dec 12 07:32:14 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Thu, 12 Dec 2024 16:32:14 +0100
Subject: [PATCH v2] firewall: remove misplaced semicolon from
 stm32_firewall_get_firewall
In-Reply-To: <20241109055049.269163-1-guanjing@cmss.chinamobile.com>
References: <20241109055049.269163-1-guanjing@cmss.chinamobile.com>
Message-ID: <d8eb157e-2f35-45a4-ba3e-cb296ced0a80@foss.st.com>

Hi

On 11/9/24 06:50, guanjing wrote:
> Remove misplaced colon in stm32_firewall_get_firewall()
> which results in a syntax error when the code is compiled
> without CONFIG_STM32_FIREWALL.
> 
> Fixes: 5c9668cfc6d7 ("firewall: introduce stm32_firewall framework")
> Signed-off-by: guanjing <guanjing at cmss.chinamobile.com>
> ---
>   include/linux/bus/stm32_firewall_device.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/linux/bus/stm32_firewall_device.h b/include/linux/bus/stm32_firewall_device.h
> index 18e0a2fc3816..5178b72bc920 100644
> --- a/include/linux/bus/stm32_firewall_device.h
> +++ b/include/linux/bus/stm32_firewall_device.h
> @@ -115,7 +115,7 @@ void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 su
>   #else /* CONFIG_STM32_FIREWALL */
>   
>   int stm32_firewall_get_firewall(struct device_node *np, struct stm32_firewall *firewall,
> -				unsigned int nb_firewall);
> +				unsigned int nb_firewall)
>   {
>   	return -ENODEV;
>   }

Applied on stm32-next.

Regards
Alex


From jason-jh.lin at mediatek.com  Thu Dec 12 07:33:44 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Thu, 12 Dec 2024 23:33:44 +0800
Subject: [PATCH 2/2] dts: arm64: mediatek: mt8188: Update OVL compatible from MT8183 to MT8195
In-Reply-To: <20241212153344.27408-1-jason-jh.lin@mediatek.com>
References: <20241212153344.27408-1-jason-jh.lin@mediatek.com>
Message-ID: <20241212153344.27408-3-jason-jh.lin@mediatek.com>

The OVL hardware capabilities have changed starting from MT8195,
making the MT8183 compatible no longer applicable.
Therefore, it is necessary to update the OVL compatible from MT8183 to
MT8195.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8188.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index faccc7f16259..23ec3ff6cad9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -2488,7 +2488,7 @@ jpeg_decoder: jpeg-decoder at 1a040000 {
 		};
 
 		ovl0: ovl at 1c000000 {
-			compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8183-disp-ovl";
+			compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8195-disp-ovl";
 			reg = <0 0x1c000000 0 0x1000>;
 			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
 			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 12 07:33:42 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Thu, 12 Dec 2024 23:33:42 +0800
Subject: [PATCH 0/2] Update MT8188 OVL compatible from MT8183 to MT8195
Message-ID: <20241212153344.27408-1-jason-jh.lin@mediatek.com>

This patch series updates the compatible strings for the MediaTek OVL
in the MT8188 dts and the corresponding dt-binding.
The changes ensure that the MT8188 OVL device is correctly identified
and managed by the appropriate drivers.

The first patch is resending the reviewed and acked patch from:
- https://lore.kernel.org/all/5d9e6f6c-604d-4e2d-a448-fc5b8bd24a75 at collabora.com/
and rebase it to the latest linux-next-20241212.

The second patch is updating the mt8188.dtsi according to the first patch.

Hsiao Chien Sung (1):
  dt-bindings: display: mediatek: ovl: Modify rules for MT8195/MT8188

Jason-JH.Lin (1):
  dts: arm64: mediatek: mt8188: Update OVL compatible from MT8183 to
    MT8195

 .../bindings/display/mediatek/mediatek,ovl.yaml           | 8 +++-----
 arch/arm64/boot/dts/mediatek/mt8188.dtsi                  | 2 +-
 2 files changed, 4 insertions(+), 6 deletions(-)

-- 
2.43.0



From geert at linux-m68k.org  Thu Dec 12 07:36:44 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 12 Dec 2024 16:36:44 +0100
Subject: [PATCH v2 13/13] arm64: defconfig: Enable R9A09G047 SoC
In-Reply-To: <20241203105005.103927-14-biju.das.jz@bp.renesas.com>
References: <20241203105005.103927-1-biju.das.jz@bp.renesas.com> <20241203105005.103927-14-biju.das.jz@bp.renesas.com>
Message-ID: <CAMuHMdUPXicL1+suMeYrXK7qEmLYE-1uuHpMys_qnxqz9Ed8KQ@mail.gmail.com>

On Tue, Dec 3, 2024 at 11:51?AM Biju Das <biju.das.jz at bp.renesas.com> wrote:
> Enable support for the Renesas RZ/G3E (R9A09G047) SoC in the ARM64
> defconfig.
>
> 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.14.

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 Dave.Martin at arm.com  Thu Dec 12 07:39:55 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 15:39:55 +0000
Subject: [RFC PATCH 1/6] arm_mpam: Clean up config update checks in mpam_apply_config()
In-Reply-To: <20241212154000.330467-1-Dave.Martin@arm.com>
References: <20241212154000.330467-1-Dave.Martin@arm.com>
Message-ID: <20241212154000.330467-2-Dave.Martin@arm.com>

In mpam_apply_config(), a simple memcmp() test is used to check
whether the config passed by the caller is already installed or
not.

This check will never find a match except (very occasionally) by
accident, since the component's version of the struct contains
things that the caller won't pass or doesn't know (such as the
garbage collection record).  There might also be random padding.

This may result in MSCs being reprogrammed unnecessarily.

Instead, only compare fields that the caller specified.  If
anything is present in the caller's config and doesn't match the
installed config, paste it across.  If nothing was pasted across
then the MSC reprogramming step is skipped (as the previous code
attempted to do).

Signed-off-by: Dave Martin <Dave.Martin at arm.com>

---

There are comments in the code suggesting a change of this sort.
I may or may not have gone in the right direction with this, and
I have only tried to clean up the behaviour rather than optimising.

No attempt is made to skip unnecessary MSC register updates if the MSC
reprogramming goes ahead.

NOT well tested, yet.
---
 drivers/platform/arm64/mpam/mpam_devices.c | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/platform/arm64/mpam/mpam_devices.c b/drivers/platform/arm64/mpam/mpam_devices.c
index 9463045c0011..41962dd1bb68 100644
--- a/drivers/platform/arm64/mpam/mpam_devices.c
+++ b/drivers/platform/arm64/mpam/mpam_devices.c
@@ -3120,6 +3120,29 @@ static void mpam_extend_config(struct mpam_class *class, struct mpam_config *cfg
 	}
 }
 
+#define maybe_update_config(cfg, feature, newcfg, member, changes) do { \
+	if (mpam_has_feature(feature, newcfg) &&			\
+	    (newcfg)->member != (cfg)->member) {			\
+		(cfg)->member = (newcfg)->member;			\
+		mpam_set_feature(feature, cfg);				\
+									\
+		(changes) |= (feature);					\
+	}								\
+} while (0)
+
+static mpam_features_t mpam_update_config(struct mpam_config *cfg,
+					  const struct mpam_config *newcfg)
+{
+	mpam_features_t changes = 0;
+
+	maybe_update_config(cfg, mpam_feat_cpor_part, newcfg, cpbm, changes);
+	maybe_update_config(cfg, mpam_feat_mbw_part, newcfg, mbw_pbm, changes);
+	maybe_update_config(cfg, mpam_feat_mbw_max, newcfg, mbw_max, changes);
+	maybe_update_config(cfg, mpam_feat_mbw_min, newcfg, mbw_min, changes);
+
+	return changes;
+}
+
 /* TODO: split into write_config/sync_config */
 /* TODO: add config_dirty bitmap to drive sync_config */
 int mpam_apply_config(struct mpam_component *comp, u16 partid,
-- 
2.34.1



From Dave.Martin at arm.com  Thu Dec 12 07:39:57 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 15:39:57 +0000
Subject: [RFC PATCH 3/6] arm_mpam: Delete unused function resctrl_arch_set_rmid()
In-Reply-To: <20241212154000.330467-1-Dave.Martin@arm.com>
References: <20241212154000.330467-1-Dave.Martin@arm.com>
Message-ID: <20241212154000.330467-4-Dave.Martin@arm.com>

The function resctrl_arch_set_rmid() appears to have been left
behind after earlier refactoring and is now unused.

To avoid needing to answer awkward questions about how this
function should apply partition ID namespace remappings, just get
rid of it.

No functional change.

Signed-off-by: Dave Martin <Dave.Martin at arm.com>

---

I'm assuming here that there are no pending branches that implement /
use this function.

When moving tasks between monitoring groups, resctrlfs currently
extracts the CLOSID from struct rdtgroup and passes it explicitly
to resctrl_arch_set_closid_rmid(), so there seems to be no need for
a separate helper that doesn't overwrite the arch's control
partition identifier.
---
 arch/arm64/include/asm/mpam.h | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h
index e5f385767174..df725d2d9d05 100644
--- a/arch/arm64/include/asm/mpam.h
+++ b/arch/arm64/include/asm/mpam.h
@@ -93,20 +93,6 @@ static inline u64 mpam_get_regval(struct task_struct *tsk)
 #endif
 }
 
-static inline void resctrl_arch_set_rmid(struct task_struct *tsk, u32 rmid)
-{
-#ifdef CONFIG_ARM64_MPAM
-	u64 regval = mpam_get_regval(tsk);
-
-	regval &= ~MPAM1_EL1_PMG_D;
-	regval &= ~MPAM1_EL1_PMG_I;
-	regval |= FIELD_PREP(MPAM1_EL1_PMG_D, rmid);
-	regval |= FIELD_PREP(MPAM1_EL1_PMG_I, rmid);
-
-	WRITE_ONCE(task_thread_info(tsk)->mpam_partid_pmg, regval);
-#endif
-}
-
 static inline void mpam_thread_switch(struct task_struct *tsk)
 {
 	u64 oldregval;
-- 
2.34.1



From Dave.Martin at arm.com  Thu Dec 12 07:39:56 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 15:39:56 +0000
Subject: [RFC PATCH 2/6] arm_mpam: Fix read-back of cloned resource controls under CDP emulation
In-Reply-To: <20241212154000.330467-1-Dave.Martin@arm.com>
References: <20241212154000.330467-1-Dave.Martin@arm.com>
Message-ID: <20241212154000.330467-3-Dave.Martin@arm.com>

When reading resource control values through a resctrl schemata
file, the index into the configuration array in the MPAM driver
is currently translated incorrectly.

This means that when resctrl is mounted with the "cdp" option, the
wrong array entry may be returned or an out-of-bounds array access
may occur when reading back of control values for the MB resource.

Fix it by translating the index for affected resources as if they
were "DATA" resources.  ("CODE" would also work, but because
resctrl_arch_update_one() clones schemata writes across "CODE" and
"DATA" for affected resources, it does not matter which one is
read.)

Signed-off-by: Dave Martin <Dave.Martin at arm.com>

---

This issue was introduced by the non-upstream commit
"arm_mpam: resctrl: Improve CDP emulation"

(commit b097a6193546dbbd27cd19d7e16e1e750ebb030f in
git://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git mpam/snapshot/v6.12-rc1 )
---
 drivers/platform/arm64/mpam/mpam_resctrl.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
index 76ddbce0ea9c..30f2caec11d7 100644
--- a/drivers/platform/arm64/mpam/mpam_resctrl.c
+++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
@@ -1097,6 +1097,14 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_ctrl_domain *d,
 	dom = container_of(d, struct mpam_resctrl_dom, resctrl_ctrl_dom);
 	cprops = &res->class->props;
 
+	/*
+	 * When CDP is enabled, but the resource doesn't support it,
+	 * the control is cloned across both partids.
+	 * Pick one at random to read:
+	 */
+	if (mpam_resctrl_hide_cdp(r->rid))
+		type = CDP_DATA;
+
 	partid = resctrl_get_config_index(closid, type);
 	cfg = &dom->comp->cfg[partid];
 
-- 
2.34.1



From Dave.Martin at arm.com  Thu Dec 12 07:39:54 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 15:39:54 +0000
Subject: [RFC PATCH 0/6] Introduce flexible CLOSID/RMID translation
Message-ID: <20241212154000.330467-1-Dave.Martin@arm.com>

This series introduces an ID remapping scheme, as a preparatory step
towards improved support for MPAM hardware that implements the MPAM
PARTID Narrowing feature.

This series is not a complete implementation, but is sufficient to
provide additional resctrl monitoring groups beyond the number of PMGs
supported by the hardware (with some limitations; see "Limitations",
below).

Based on:
git://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git mpam/snapshot/v6.12-rc1


Background
==========

An MPAM Memory System Component (MSC) that does not implement the
PARTID Narrowing feature (Narrowing) provides independently
programmable resource controls for each PARTID up to the maximum PARTID
that the MSC supports.

An MSC that _does_ implement Narrowing performs a remapping step to
convert the PARTID from the incoming memory transaction ("request
PARTID", or "reqPARTID") to an internal ID ("internal PARTID", or
"intPARTID") before looking up and applying resource controls.  Such an
MSC does not necessarily need to provide the same number of
independently programmable resource control partitions (indexed by the
intPARTID) as that which the size of the supported PARTID ("reqPARTID")
space would otherwise require.  Instead, independently programmable
resource controls are provided for each intPARTID, accompanied by a
software programmable mapping that allows each reqPARTID to be mapped
independently to a selected intPARTID.

Typically, the number of intPARTIDs supported by a Narrowing MSC is
smaller than the number of reqPARTIDs.  Narrowing permits multiple
reqPARTIDs to be mapped to each intPARTID, so allowing the whole MPAM
PARTID space to be served.

A non-Narrowing MSC can be understood as implementing special case of
Narrowing, where the reqPARTID-to-intPARTID mapping is the identity
function and is not programmable.


The number of independently configurable control partitions at a given
MSC cannot exceed the number of intPARTIDs available, so the number of
resctrl CLOSIDs (which need to be independently controllable) must
typically be limited not to exceed the maximum number of intPARTIDs
available on any Narrowing MSC.

However, the presence of a programmable reqPARTID-to-intPARTID mapping
in each MSC creates an opportunity: because a group of multiple MPAM
PARTIDs can be mapped onto the same controls, they behave as a single
resource control partition.  Because the PARTID is used as a match
criterion for monitoring purposes along with the MPAM Performance
Monitoring Group (PMG) identifier assigned each memory system
transaction, the specific PARTID in the group can be used to
distinguish transactions for monitoring purposes, even within the same
resctrl control group and when the PMGs of the transactions are the
same.

This means that it becomes possible to provide a larger number of
resctrl monitoring groups than the number of PMGs supported by the MPAM
hardware implementation.


In order to take advantage of this, a more flexible mapping scheme is
required for mapping resctrl CLOSIDs and RMIDs to MPAM PARTIDs and PMGs
than the current MPAM driver provides.

Similar approaches have been suggested by other people
(see Acknowledgements).

However, since I was already working on this, I'm posting my approach
for comparison.


This Series
===========

This series introduces a remapping scheme as follows:

1) The resctrl partition identifiers are combined into a single
identifier (formally the Cartesian product of the CLOSID, Code/Data
partition where applicable, and RMID ID spaces).

2) The resulting identifier is then broken down into the MPAM PARTID
and PMG, in such a way that each possible <CLOSID, CDP index, RMID>
maps to a unique <PARTID, PMG> pair and vice versa, and so that any two
<PARTID, PMG> that differ only in the PMG value, map onto the same
<CLOSID, CDP index> pair.


This transformation could be done in intuitive way using bitwise
concatenation, shift and masking operations, but since the size of the
MPAM hardware ID spaces may limited, I have tried to generalise this
approach using multiplication in place of bit-shifts, to permit ID
spaces whose size is not a power of two.


Limitations
===========

This series aims to contain all translations within the mpam_resctrl.c
code.  This seems the most sensible place for it, since this is a
conversion scheme that will be used to interface the MPAM hardware with
the resctrl core code (but has nothing to do with the "pure" MPAM
architecture or the resctrl core code itself).

To simplify the interface between mpam_resctrl.c and mpam_devices.c,
the ID conversion scheme is arranged so that each resctrl CLOSID maps
to a contiguous sequence of MPAM PARTIDs.  This means that programming
controls for a CLOSID can be achieved by iterating over the appropriate
range of PARTIDs.

No change is made to program the reqPARTID-to-intPARTID mappings, so
the number of MPAM PARTIDs in use continues to be limited not to exceed
the maximum number of intPARTIDs available, for now.

Because a CLOSID may be fragmented across multiple PARTIDs, this series
will cause certain types of resource control to be applied incorrectly
to each individual PARTID instead of the whole resctrl control group.

Future patches will need to program the intPARTID mappings
appropriately and/or disable certain controls in order to restore the
expected regulation behaviour as seen by users of resctrl.


Patches
=======

Patches 1-3 are pending fixes / cleanups for the MPAM branch.  They
have nothing directly to do with this series, but I don't want to
maintain two versions of my development branch.  This seems as a good a
time as any to post them.

Patch 4 implements the ID remapping scheme.

Following these are two development patches which may be useful to
reviewers:

Patch 5 adds a kernel command-line parameter mpam.partid_per_closid=<n>
to allow the number of PARTIDs to map to each CLOSID.  This is intended
to be temporary, but since the patches contain no logic for choosing
this parameter, allowing it to be specified on the kernel command line
makes it easier to experiment with different configurations.

Patch 6 adds some debug printks to show how MPAM PARTIDs / PMGs are
actually being assigned, and shows when each MSC is reprogrammed.
Since we don't want to create unintentional ABI exposing these IDs, I
don't expect this to be upstreamed in any form.


Acknowledgements
================

Thanks to Shaopeng Tan for pointing out this opportunity and suggesting
a related idea, and to Zeng Heng who has also implemented something
similar. [1], [2], [3]


References
==========

Zeng Heng <zengheng4 at huawei.com>:

[1] (v3) arm_mpam: Introduce the Narrow-PARTID feature for MPAM driver
https://lore.kernel.org/linux-arm-kernel/20241207092136.2488426-1-zengheng4 at huawei.com/

[2] (v2) arm_mpam: Introduce the Narrow-PARTID feature for MPAM driver
https://lore.kernel.org/linux-arm-kernel/20241119135104.595630-1-zengheng4 at huawei.com/

[3] (v1) arm_mpam: Introduce the definitions of intPARTID and reqPARTID
https://lore.kernel.org/linux-arm-kernel/20241114135037.918470-1-zengheng4 at huawei.com/



Dave Martin (6):
  arm_mpam: Clean up config update checks in mpam_apply_config()
  arm_mpam: Fix read-back of cloned resource controls under CDP
    emulation
  arm_mpam: Delete unused function resctrl_arch_set_rmid()
  arm_mpam: Introduce flexible CLOSID/RMID translation
  arm_mpam: [NFU] Rework ID remapping to use a kernel command-line
    argument
  arm_mpam: [NFU] Development diagnostics for MPAM ID assignments

 arch/arm64/include/asm/mpam.h              |  21 +-
 drivers/platform/arm64/mpam/mpam_devices.c |  29 +++
 drivers/platform/arm64/mpam/mpam_resctrl.c | 214 +++++++++++++--------
 3 files changed, 168 insertions(+), 96 deletions(-)


base-commit: 4d17b37b670795954fd7a70c8ec83fb705a5e2ad
-- 
2.34.1



From Dave.Martin at arm.com  Thu Dec 12 07:39:58 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 15:39:58 +0000
Subject: [RFC PATCH 4/6] arm_mpam: Introduce flexible CLOSID/RMID translation
In-Reply-To: <20241212154000.330467-1-Dave.Martin@arm.com>
References: <20241212154000.330467-1-Dave.Martin@arm.com>
Message-ID: <20241212154000.330467-5-Dave.Martin@arm.com>

Currently, the MPAM driver uses the resctrl CLOSID directly as the
MPAM Partition Identifier (PARTID; possibly modified to give
different PARTIDs to code and data when Code/Data Partitioning /
CDP is enabled), and uses the resctrl RMID directly as the MPAM
Performance Monitoring Group identifier (PMG).

In preparation for using the MPAM PARTID Narrowing feature to allow
more resctrl monitoring groups to be provided than the number of
PMG values supported by the hardware, a more flexible remapping
scheme is needed.

Factor out ID translation operations in the MPAM resctrl glue code
into a couple of self-contained helpers, and call them as
appropriate.

The translation scheme has a single parameter, partid_per_closid,
which is currently hard-wired to 1.

As a result, this patch should have no effect on functionality.

Logic to determine / control the mapping parameters can be
introduced later.

The ID transformation may be visualised as follows:

without CDP:
  +---------------------------------------------------+-----------+
  |                       CLOSID                      |    RMID   |
  +---------------------------------------------------+-------+---+
  |                           PARTID                  :       |PMG|
  +-----------------------------------------------------------+---+

and with CDP, where the "CDP" field is 0 for the data sub-
partition and 1 for the code sub-partition:
  +-----------------------------------------------+---+-----------+
  |                     CLOSID                    |CDP|    RMID   |
  +-----------------------------------------------+---+-------+---+
  |                           PARTID                  :       |PMG|
  +-----------------------------------------------------------+---+

where each box represents a non-negative integer spanning some
fixed range starting from zero, and horizontal concatenation
denotes multiplying the value denoted by the left-hand box by the
span of the right-hand box, and adding the result to the value
denoted by the right-hand box; thus, most-significant fields are on
the left.

(Except for the span of each field not necessarily being a power of
two, this is conceptually identical to concatenation and cutting of
bitfields.)

The dotted segment indicates the least significant part of PARTID,
which spans partid_per_closid PARTIDs and discriminates monitoring
groups that use the same MPAM PMG value.

Signed-off-by: Dave Martin <Dave.Martin at arm.com>
---
 drivers/platform/arm64/mpam/mpam_resctrl.c | 200 +++++++++++----------
 1 file changed, 110 insertions(+), 90 deletions(-)

diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
index 30f2caec11d7..0473286ec65a 100644
--- a/drivers/platform/arm64/mpam/mpam_resctrl.c
+++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
@@ -156,6 +156,18 @@ static bool mpam_resctrl_hide_cdp(enum resctrl_res_level rid)
 	return cdp_enabled && !resctrl_arch_get_cdp_enabled(rid);
 }
 
+static unsigned int partid_per_closid = 1;
+
+static unsigned int mpam_num_pmg(void)
+{
+	return mpam_pmg_max + 1;
+}
+
+static unsigned int mpam_num_rmid(void)
+{
+	return mpam_num_pmg() * partid_per_closid;
+}
+
 /*
  * MSC may raise an error interrupt if it sees an out or range partid/pmg,
  * and go on to truncate the value. Regardless of what the hardware supports,
@@ -163,35 +175,71 @@ static bool mpam_resctrl_hide_cdp(enum resctrl_res_level rid)
  */
 u32 resctrl_arch_get_num_closid(struct rdt_resource *ignored)
 {
-	return mpam_partid_max + 1;
+	u32 res = (mpam_partid_max + 1) / partid_per_closid;
+
+	WARN_ON(res < 1);
+	return res;
 }
 
-u32 resctrl_arch_system_num_rmid_idx(void)
+static void mpam_resctrl_partid_range(u32 closid, enum resctrl_conf_type type,
+				      const struct rdt_resource *r,
+				      u16 *min_partid, u16 *max_partid)
 {
-	u8 closid_shift = fls(mpam_pmg_max);
-	u32 num_partid = resctrl_arch_get_num_closid(NULL);
+	u16 base_partid = closid;
+	u16 span = 1;
+
+	if (cdp_enabled) {
+		base_partid *= 2;
+		if (mpam_resctrl_hide_cdp(r->rid) ||
+		    type == CDP_NONE)
+			span *= 2;
+	}
 
-	return num_partid << closid_shift;
+	*min_partid = base_partid * partid_per_closid;
+	if (max_partid)
+		*max_partid = *min_partid + (span * partid_per_closid - 1);
 }
 
-u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
+static void mpam_resctrl_hwid(u32 closid, u32 rmid,
+			      u16 *partid_d, u16 *partid_i, u8 *pmg)
 {
-	u8 closid_shift = fls(mpam_pmg_max);
+	const u16 pmg_hi = rmid / mpam_num_pmg();
+	const u16 pmg_lo = rmid % mpam_num_pmg();
+	u16 base_partid = closid;
+	u16 partid_stride = 0;
+
+	if (cdp_enabled) {
+		base_partid *= 2;
+		partid_stride = 1;
+	}
 
-	BUG_ON(closid_shift > 8);
+	partid_stride *= partid_per_closid;
+	base_partid *= partid_per_closid;
+	base_partid += pmg_hi;
 
-	return (closid << closid_shift) | rmid;
+	*partid_d = base_partid;
+	if (partid_i)
+		*partid_i = base_partid + partid_stride;
+
+	*pmg = pmg_lo;
 }
 
-void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
+u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
 {
-	u8 closid_shift = fls(mpam_pmg_max);
-	u32 pmg_mask = ~(~0 << closid_shift);
+	return closid * mpam_num_rmid() + rmid;
+}
 
-	BUG_ON(closid_shift > 8);
+u32 resctrl_arch_system_num_rmid_idx(void)
+{
+	u32 num_closid = resctrl_arch_get_num_closid(NULL);
 
-	*closid = idx >> closid_shift;
-	*rmid = idx & pmg_mask;
+	return resctrl_arch_rmid_idx_encode(num_closid, 0);
+}
+
+void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
+{
+	*closid = idx / mpam_num_rmid();
+	*rmid = idx % mpam_num_rmid();
 }
 
 void resctrl_arch_sched_in(struct task_struct *tsk)
@@ -203,21 +251,14 @@ void resctrl_arch_sched_in(struct task_struct *tsk)
 
 void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid, u32 rmid)
 {
+	u16 partid_d, partid_i;
+	u8 pmg;
+
 	BUG_ON(closid > U16_MAX);
 	BUG_ON(rmid > U8_MAX);
 
-	if (!cdp_enabled) {
-		mpam_set_cpu_defaults(cpu, closid, closid, rmid, rmid);
-	} else {
-		/*
-		 * When CDP is enabled, resctrl halves the closid range and we
-		 * use odd/even partid for one closid.
-		 */
-		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
-		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
-
-		mpam_set_cpu_defaults(cpu, partid_d, partid_i, rmid, rmid);
-	}
+	mpam_resctrl_hwid(closid, rmid, &partid_d, &partid_i, &pmg);
+	mpam_set_cpu_defaults(cpu, partid_d, partid_i, pmg, pmg);
 }
 
 void resctrl_arch_sync_cpu_closid_rmid(void *info)
@@ -236,41 +277,38 @@ void resctrl_arch_sync_cpu_closid_rmid(void *info)
 
 void resctrl_arch_set_closid_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
 {
+	u16 partid_d, partid_i;
+	u8 pmg;
+
 	BUG_ON(closid > U16_MAX);
 	BUG_ON(rmid > U8_MAX);
 
-	if (!cdp_enabled) {
-		mpam_set_task_partid_pmg(tsk, closid, closid, rmid, rmid);
-	} else {
-		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
-		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
-
-		mpam_set_task_partid_pmg(tsk, partid_d, partid_i, rmid, rmid);
-	}
+	mpam_resctrl_hwid(closid, rmid, &partid_d, &partid_i, &pmg);
+	mpam_set_task_partid_pmg(tsk, partid_d, partid_i, pmg, pmg);
 }
 
 bool resctrl_arch_match_closid(struct task_struct *tsk, u32 closid)
 {
+	u16 min_partid, max_partid;
 	u64 regval = mpam_get_regval(tsk);
 	u32 tsk_closid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
 
-	if (cdp_enabled)
-		tsk_closid >>= 1;
-
-	return tsk_closid == closid;
+	mpam_resctrl_partid_range(closid, CDP_NONE, NULL,
+				  &min_partid, &max_partid);
+	return tsk_closid >= min_partid && tsk_closid <= max_partid;
 }
 
 /* The task's pmg is not unique, the partid must be considered too */
 bool resctrl_arch_match_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
 {
+	u16 partid_d;
+	u8 pmg;
 	u64 regval = mpam_get_regval(tsk);
-	u32 tsk_closid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
-	u32 tsk_rmid = FIELD_GET(MPAM1_EL1_PMG_D, regval);
-
-	if (cdp_enabled)
-		tsk_closid >>= 1;
+	u16 tsk_partid_d = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
+	u8 tsk_pmg = FIELD_GET(MPAM1_EL1_PMG_D, regval);
 
-	return (tsk_closid == closid) && (tsk_rmid == rmid);
+	mpam_resctrl_hwid(closid, rmid, &partid_d, NULL, &pmg);
+	return (tsk_partid_d == partid_d) && (tsk_pmg == pmg);
 }
 
 struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
@@ -370,6 +408,7 @@ int resctrl_arch_rmid_read(struct rdt_resource	*r, struct rdt_mon_domain *d,
 	struct mpam_resctrl_dom *dom;
 	u32 mon = *(u32 *)arch_mon_ctx;
 	enum mpam_device_features type;
+	u16 partid_d, partid_i, pmg;
 
 	resctrl_arch_rmid_read_context_check();
 
@@ -391,27 +430,23 @@ int resctrl_arch_rmid_read(struct rdt_resource	*r, struct rdt_mon_domain *d,
 	if (cfg.mon == USE_RMID_IDX)
 		cfg.mon = resctrl_arch_rmid_idx_encode(closid, rmid);
 
+	mpam_resctrl_hwid(closid, rmid, &partid_d, &partid_i, &cfg.pmg);
 	cfg.match_pmg = true;
-	cfg.pmg = rmid;
+	cfg.pmg = pmg;
 	cfg.opts = resctrl_evt_config_to_mpam(dom->mbm_local_evt_cfg);
 
 	if (irqs_disabled()) {
 		/* Check if we can access this domain without an IPI */
 		err = -EIO;
 	} else {
-		if (cdp_enabled) {
-			cfg.partid = closid << 1;
-			err = mpam_msmon_read(dom->comp, &cfg, type, val);
-			if (err)
-				return err;
+		cfg.partid = partid_d;
+		err = mpam_msmon_read(dom->comp, &cfg, type, val);
 
-			cfg.partid += 1;
+		if (partid_i != partid_d) {
+			cfg.partid = partid_i;
 			err = mpam_msmon_read(dom->comp, &cfg, type, &cdp_val);
 			if (!err)
 				*val += cdp_val;
-		} else {
-			cfg.partid = closid;
-			err = mpam_msmon_read(dom->comp, &cfg, type, val);
 		}
 	}
 
@@ -423,6 +458,7 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_mon_domain *d,
 {
 	struct mon_cfg cfg;
 	struct mpam_resctrl_dom *dom;
+	u16 partid_d, partid_i;
 
 	if (eventid != QOS_L3_MBM_LOCAL_EVENT_ID)
 		return;
@@ -433,14 +469,13 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_mon_domain *d,
 
 	dom = container_of(d, struct mpam_resctrl_dom, resctrl_mon_dom);
 
-	if (cdp_enabled) {
-		cfg.partid = closid << 1;
-		mpam_msmon_reset_mbwu(dom->comp, &cfg);
+	mpam_resctrl_hwid(closid, rmid, &partid_d, &partid_i, &cfg.pmg);
 
-		cfg.partid += 1;
-		mpam_msmon_reset_mbwu(dom->comp, &cfg);
-	} else {
-		cfg.partid = closid;
+	cfg.partid = partid_d;
+	mpam_msmon_reset_mbwu(dom->comp, &cfg);
+
+	if (partid_i != partid_d) {
+		cfg.partid = partid_i;
 		mpam_msmon_reset_mbwu(dom->comp, &cfg);
 	}
 }
@@ -1081,7 +1116,7 @@ static void mpam_resctrl_exit(void)
 u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_ctrl_domain *d,
 			    u32 closid, enum resctrl_conf_type type)
 {
-	u32 partid;
+	u16 partid;
 	struct mpam_config *cfg;
 	struct mpam_props *cprops;
 	struct mpam_resctrl_res *res;
@@ -1097,15 +1132,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_ctrl_domain *d,
 	dom = container_of(d, struct mpam_resctrl_dom, resctrl_ctrl_dom);
 	cprops = &res->class->props;
 
-	/*
-	 * When CDP is enabled, but the resource doesn't support it,
-	 * the control is cloned across both partids.
-	 * Pick one at random to read:
-	 */
-	if (mpam_resctrl_hide_cdp(r->rid))
-		type = CDP_DATA;
-
-	partid = resctrl_get_config_index(closid, type);
+	mpam_resctrl_partid_range(closid, type, r, &partid, NULL);
 	cfg = &dom->comp->cfg[partid];
 
 	switch (r->rid) {
@@ -1126,7 +1153,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_ctrl_domain *d,
 		return -EINVAL;
 	}
 
-	if (!r->alloc_capable || partid >= resctrl_arch_get_num_closid(r) ||
+	if (!r->alloc_capable || partid > mpam_partid_max ||
 	    !mpam_has_feature(configured_by, cfg))
 		return resctrl_get_default_ctrl(r);
 
@@ -1147,8 +1174,8 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_ctrl_domain *d,
 int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_ctrl_domain *d,
 			    u32 closid, enum resctrl_conf_type t, u32 cfg_val)
 {
-	int err;
-	u32 partid;
+	int err = 0;
+	u16 partid, min_partid, max_partid;
 	struct mpam_config cfg;
 	struct mpam_props *cprops;
 	struct mpam_resctrl_res *res;
@@ -1163,8 +1190,10 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_ctrl_domain *d,
 	dom = container_of(d, struct mpam_resctrl_dom, resctrl_ctrl_dom);
 	cprops = &res->class->props;
 
-	partid = resctrl_get_config_index(closid, t);
-	if (!r->alloc_capable || partid >= resctrl_arch_get_num_closid(r))
+	mpam_resctrl_partid_range(closid, t, r, &min_partid, &max_partid);
+	if (!r->alloc_capable ||
+	    min_partid > mpam_partid_max ||
+	    max_partid > mpam_partid_max)
 		return -EINVAL;
 
 	cfg.features = 0;
@@ -1190,22 +1219,13 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_ctrl_domain *d,
 		return -EINVAL;
 	}
 
-	/*
-	 * When CDP is enabled, but the resource doesn't support it, we need to
-	 * apply the same configuration to the other partid.
-	 */
-	if (mpam_resctrl_hide_cdp(r->rid)) {
-		partid = resctrl_get_config_index(closid, CDP_CODE);
+	for (partid = min_partid; partid <= max_partid; partid++) {
 		err = mpam_apply_config(dom->comp, partid, &cfg);
 		if (err)
-			return err;
-
-		partid = resctrl_get_config_index(closid, CDP_DATA);
-		return mpam_apply_config(dom->comp, partid, &cfg);
-
-	} else {
-		return mpam_apply_config(dom->comp, partid, &cfg);
+			break;
 	}
+
+	return err;
 }
 
 /* TODO: this is IPI heavy */
-- 
2.34.1



From steven.price at arm.com  Thu Dec 12 07:55:35 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:35 +0000
Subject: [PATCH v6 10/43] arm64: kvm: Allow passing machine type in KVM creation
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-11-steven.price@arm.com>

Previously machine type was used purely for specifying the physical
address size of the guest. Reserve the higher bits to specify an ARM
specific machine type and declare a new type 'KVM_VM_TYPE_ARM_REALM'
used to create a realm guest.

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/arm.c     | 17 +++++++++++++++++
 arch/arm64/kvm/mmu.c     |  3 ---
 include/uapi/linux/kvm.h | 19 +++++++++++++++----
 3 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index c505ec61180a..73016e1e0067 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -207,6 +207,23 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 	mutex_unlock(&kvm->lock);
 #endif
 
+	if (type & ~(KVM_VM_TYPE_ARM_MASK | KVM_VM_TYPE_ARM_IPA_SIZE_MASK))
+		return -EINVAL;
+
+	switch (type & KVM_VM_TYPE_ARM_MASK) {
+	case KVM_VM_TYPE_ARM_NORMAL:
+		break;
+	case KVM_VM_TYPE_ARM_REALM:
+		kvm->arch.is_realm = true;
+		if (!kvm_is_realm(kvm)) {
+			/* Realm support unavailable */
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	kvm_init_nested(kvm);
 
 	ret = kvm_share_hyp(kvm, kvm + 1);
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index f09d580c12ad..f3b48895aee5 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -873,9 +873,6 @@ static int kvm_init_ipa_range(struct kvm *kvm,
 	if (kvm_is_realm(kvm))
 		kvm_ipa_limit = kvm_realm_ipa_limit();
 
-	if (type & ~KVM_VM_TYPE_ARM_IPA_SIZE_MASK)
-		return -EINVAL;
-
 	phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type);
 	if (is_protected_kvm_enabled()) {
 		phys_shift = kvm_ipa_limit;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index f448198838cf..05fb31ced849 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -648,14 +648,25 @@ struct kvm_enable_cap {
 #define KVM_S390_SIE_PAGE_OFFSET 1
 
 /*
- * On arm64, machine type can be used to request the physical
- * address size for the VM. Bits[7-0] are reserved for the guest
- * PA size shift (i.e, log2(PA_Size)). For backward compatibility,
- * value 0 implies the default IPA size, 40bits.
+ * On arm64, machine type can be used to request both the machine type and
+ * the physical address size for the VM.
+ *
+ * Bits[11-8] are reserved for the ARM specific machine type.
+ *
+ * Bits[7-0] are reserved for the guest PA size shift (i.e, log2(PA_Size)).
+ * For backward compatibility, value 0 implies the default IPA size, 40bits.
  */
+#define KVM_VM_TYPE_ARM_SHIFT		8
+#define KVM_VM_TYPE_ARM_MASK		(0xfULL << KVM_VM_TYPE_ARM_SHIFT)
+#define KVM_VM_TYPE_ARM(_type)		\
+	(((_type) << KVM_VM_TYPE_ARM_SHIFT) & KVM_VM_TYPE_ARM_MASK)
+#define KVM_VM_TYPE_ARM_NORMAL		KVM_VM_TYPE_ARM(0)
+#define KVM_VM_TYPE_ARM_REALM		KVM_VM_TYPE_ARM(1)
+
 #define KVM_VM_TYPE_ARM_IPA_SIZE_MASK	0xffULL
 #define KVM_VM_TYPE_ARM_IPA_SIZE(x)		\
 	((x) & KVM_VM_TYPE_ARM_IPA_SIZE_MASK)
+
 /*
  * ioctls for /dev/kvm fds:
  */
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:36 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:36 +0000
Subject: [PATCH v6 11/43] arm64: RME: RTT tear down
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-12-steven.price@arm.com>

The RMM owns the stage 2 page tables for a realm, and KVM must request
that the RMM creates/destroys entries as necessary. The physical pages
to store the page tables are delegated to the realm as required, and can
be undelegated when no longer used.

Creating new RTTs is the easy part, tearing down is a little more
tricky. The result of realm_rtt_destroy() can be used to effectively
walk the tree and destroy the entries (undelegating pages that were
given to the realm).

Signed-off-by: Steven Price <steven.price at arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
---
Changes since v5:
 * Rename some RME_xxx defines to do with page sizes as RMM_xxx - they are
   a property of the RMM specification not the RME architecture.
Changes since v2:
 * Moved {alloc,free}_delegated_page() and ensure_spare_page() to a
   later patch when they are actually used.
 * Some simplifications now rmi_xxx() functions allow NULL as an output
   parameter.
 * Improved comments and code layout.
---
 arch/arm64/include/asm/kvm_rme.h |  19 ++++++
 arch/arm64/kvm/mmu.c             |   6 +-
 arch/arm64/kvm/rme.c             | 112 +++++++++++++++++++++++++++++++
 3 files changed, 134 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 209cd99f03dd..32bdedf1d866 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -71,5 +71,24 @@ u32 kvm_realm_ipa_limit(void);
 int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap);
 int kvm_init_realm_vm(struct kvm *kvm);
 void kvm_destroy_realm(struct kvm *kvm);
+void kvm_realm_destroy_rtts(struct kvm *kvm, u32 ia_bits);
+
+#define RMM_RTT_BLOCK_LEVEL	2
+#define RMM_RTT_MAX_LEVEL	3
+
+#define RMM_PAGE_SHIFT		12
+#define RMM_PAGE_SIZE		BIT(RMM_PAGE_SHIFT)
+/* See ARM64_HW_PGTABLE_LEVEL_SHIFT() */
+#define RMM_RTT_LEVEL_SHIFT(l)	\
+	((RMM_PAGE_SHIFT - 3) * (4 - (l)) + 3)
+#define RMM_L2_BLOCK_SIZE	BIT(RMM_RTT_LEVEL_SHIFT(2))
+
+static inline unsigned long rme_rtt_level_mapsize(int level)
+{
+	if (WARN_ON(level > RMM_RTT_MAX_LEVEL))
+		return RMM_PAGE_SIZE;
+
+	return (1UL << RMM_RTT_LEVEL_SHIFT(level));
+}
 
 #endif
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index f3b48895aee5..325b578c734d 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1054,14 +1054,15 @@ void stage2_unmap_vm(struct kvm *kvm)
 void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
 {
 	struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
-	struct kvm_pgtable *pgt = NULL;
+	struct kvm_pgtable *pgt;
 
 	write_lock(&kvm->mmu_lock);
+	pgt = mmu->pgt;
 	if (kvm_is_realm(kvm) &&
 	    (kvm_realm_state(kvm) != REALM_STATE_DEAD &&
 	     kvm_realm_state(kvm) != REALM_STATE_NONE)) {
-		/* Tearing down RTTs will be added in a later patch */
 		write_unlock(&kvm->mmu_lock);
+		kvm_realm_destroy_rtts(kvm, pgt->ia_bits);
 
 		/*
 		 * The physical PGD pages are delegated to the RMM, so cannot
@@ -1071,7 +1072,6 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
 		 */
 		return;
 	}
-	pgt = mmu->pgt;
 	if (pgt) {
 		mmu->pgd_phys = 0;
 		mmu->pgt = NULL;
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 5530ec2653b7..5e719235dd77 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -141,6 +141,118 @@ static int realm_create_rd(struct kvm *kvm)
 	return r;
 }
 
+static int realm_rtt_destroy(struct realm *realm, unsigned long addr,
+			     int level, phys_addr_t *rtt_granule,
+			     unsigned long *next_addr)
+{
+	unsigned long out_rtt;
+	int ret;
+
+	ret = rmi_rtt_destroy(virt_to_phys(realm->rd), addr, level,
+			      &out_rtt, next_addr);
+
+	*rtt_granule = out_rtt;
+
+	return ret;
+}
+
+static int realm_tear_down_rtt_level(struct realm *realm, int level,
+				     unsigned long start, unsigned long end)
+{
+	ssize_t map_size;
+	unsigned long addr, next_addr;
+
+	if (WARN_ON(level > RMM_RTT_MAX_LEVEL))
+		return -EINVAL;
+
+	map_size = rme_rtt_level_mapsize(level - 1);
+
+	for (addr = start; addr < end; addr = next_addr) {
+		phys_addr_t rtt_granule;
+		int ret;
+		unsigned long align_addr = ALIGN(addr, map_size);
+
+		next_addr = ALIGN(addr + 1, map_size);
+
+		if (next_addr > end || align_addr != addr) {
+			/*
+			 * The target range is smaller than what this level
+			 * covers, recurse deeper.
+			 */
+			ret = realm_tear_down_rtt_level(realm,
+							level + 1,
+							addr,
+							min(next_addr, end));
+			if (ret)
+				return ret;
+			continue;
+		}
+
+		ret = realm_rtt_destroy(realm, addr, level,
+					&rtt_granule, &next_addr);
+
+		switch (RMI_RETURN_STATUS(ret)) {
+		case RMI_SUCCESS:
+			free_delegated_granule(rtt_granule);
+			break;
+		case RMI_ERROR_RTT:
+			if (next_addr > addr) {
+				/* Missing RTT, skip */
+				break;
+			}
+			/*
+			 * We tear down the RTT range for the full IPA
+			 * space, after everything is unmapped. Also we
+			 * descend down only if we cannot tear down a
+			 * top level RTT. Thus RMM must be able to walk
+			 * to the requested level. e.g., a block mapping
+			 * exists at L1 or L2.
+			 */
+			if (WARN_ON(RMI_RETURN_INDEX(ret) != level))
+				return -EBUSY;
+			if (WARN_ON(level == RMM_RTT_MAX_LEVEL))
+				return -EBUSY;
+
+			/*
+			 * The table has active entries in it, recurse deeper
+			 * and tear down the RTTs.
+			 */
+			next_addr = ALIGN(addr + 1, map_size);
+			ret = realm_tear_down_rtt_level(realm,
+							level + 1,
+							addr,
+							next_addr);
+			if (ret)
+				return ret;
+			/*
+			 * Now that the child RTTs are destroyed,
+			 * retry at this level.
+			 */
+			next_addr = addr;
+			break;
+		default:
+			WARN_ON(1);
+			return -ENXIO;
+		}
+	}
+
+	return 0;
+}
+
+static int realm_tear_down_rtt_range(struct realm *realm,
+				     unsigned long start, unsigned long end)
+{
+	return realm_tear_down_rtt_level(realm, get_start_level(realm) + 1,
+					 start, end);
+}
+
+void kvm_realm_destroy_rtts(struct kvm *kvm, u32 ia_bits)
+{
+	struct realm *realm = &kvm->arch.realm;
+
+	WARN_ON(realm_tear_down_rtt_range(realm, 0, (1UL << ia_bits)));
+}
+
 /* Protects access to rme_vmid_bitmap */
 static DEFINE_SPINLOCK(rme_vmid_lock);
 static unsigned long *rme_vmid_bitmap;
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:37 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:37 +0000
Subject: [PATCH v6 12/43] arm64: RME: Allocate/free RECs to match vCPUs
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-13-steven.price@arm.com>

The RMM maintains a data structure known as the Realm Execution Context
(or REC). It is similar to struct kvm_vcpu and tracks the state of the
virtual CPUs. KVM must delegate memory and request the structures are
created when vCPUs are created, and suitably tear down on destruction.

RECs must also be supplied with addition pages - auxiliary (or AUX)
granules - for storing the larger registers state (e.g. for SVE). The
number of AUX granules for a REC depends on the parameters with which
the Realm was created - the RMM makes this information available via the
RMI_REC_AUX_COUNT call performed after creating the Realm Descriptor (RD).

Note that only some of register state for the REC can be set by KVM, the
rest is defined by the RMM (zeroed). The register state then cannot be
changed by KVM after the REC is created (except when the guest
explicitly requests this e.g. by performing a PSCI call). The RMM also
requires that the VMM creates RECs in ascending order of the MPIDR.

See Realm Management Monitor specification (DEN0137) for more information:
https://developer.arm.com/documentation/den0137/

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v5:
 * Separate the concept of vcpu_is_rec() and
   kvm_arm_vcpu_rec_finalized() by using the KVM_ARM_VCPU_REC feature as
   the indication that the VCPU is a REC.
Changes since v2:
 * Free rec->run earlier in kvm_destroy_realm() and adapt to previous patches.
---
 arch/arm64/include/asm/kvm_emulate.h |   7 ++
 arch/arm64/include/asm/kvm_host.h    |   3 +
 arch/arm64/include/asm/kvm_rme.h     |  18 ++++
 arch/arm64/kvm/arm.c                 |   9 ++
 arch/arm64/kvm/reset.c               |  11 ++
 arch/arm64/kvm/rme.c                 | 144 +++++++++++++++++++++++++++
 6 files changed, 192 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 27f54a7778aa..ec2b6d9c9c07 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -722,7 +722,14 @@ static inline bool kvm_realm_is_created(struct kvm *kvm)
 
 static inline bool vcpu_is_rec(struct kvm_vcpu *vcpu)
 {
+	if (static_branch_unlikely(&kvm_rme_is_available))
+		return vcpu_has_feature(vcpu, KVM_ARM_VCPU_REC);
 	return false;
 }
 
+static inline bool kvm_arm_vcpu_rec_finalized(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.rec.mpidr != INVALID_HWID;
+}
+
 #endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 8482638dce3b..220195c727ef 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -789,6 +789,9 @@ struct kvm_vcpu_arch {
 
 	/* Per-vcpu CCSIDR override or NULL */
 	u32 *ccsidr;
+
+	/* Realm meta data */
+	struct realm_rec rec;
 };
 
 /*
diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 32bdedf1d866..62d4a63d3035 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -6,6 +6,7 @@
 #ifndef __ASM_KVM_RME_H
 #define __ASM_KVM_RME_H
 
+#include <asm/rmi_smc.h>
 #include <uapi/linux/kvm.h>
 
 /**
@@ -65,6 +66,21 @@ struct realm {
 	unsigned int ia_bits;
 };
 
+/**
+ * struct realm_rec - Additional per VCPU data for a Realm
+ *
+ * @mpidr: MPIDR (Multiprocessor Affinity Register) value to identify this VCPU
+ * @rec_page: Kernel VA of the RMM's private page for this REC
+ * @aux_pages: Additional pages private to the RMM for this REC
+ * @run: Kernel VA of the RmiRecRun structure shared with the RMM
+ */
+struct realm_rec {
+	unsigned long mpidr;
+	void *rec_page;
+	struct page *aux_pages[REC_PARAMS_AUX_GRANULES];
+	struct rec_run *run;
+};
+
 void kvm_init_rme(void);
 u32 kvm_realm_ipa_limit(void);
 
@@ -72,6 +88,8 @@ int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap);
 int kvm_init_realm_vm(struct kvm *kvm);
 void kvm_destroy_realm(struct kvm *kvm);
 void kvm_realm_destroy_rtts(struct kvm *kvm, u32 ia_bits);
+int kvm_create_rec(struct kvm_vcpu *vcpu);
+void kvm_destroy_rec(struct kvm_vcpu *vcpu);
 
 #define RMM_RTT_BLOCK_LEVEL	2
 #define RMM_RTT_MAX_LEVEL	3
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 73016e1e0067..2d97147651be 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -525,6 +525,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 	/* Force users to call KVM_ARM_VCPU_INIT */
 	vcpu_clear_flag(vcpu, VCPU_INITIALIZED);
 
+	vcpu->arch.rec.mpidr = INVALID_HWID;
+
 	vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO;
 
 	/* Set up the timer */
@@ -1467,6 +1469,9 @@ static unsigned long system_supported_vcpu_features(void)
 	if (!cpus_have_final_cap(ARM64_HAS_NESTED_VIRT))
 		clear_bit(KVM_ARM_VCPU_HAS_EL2, &features);
 
+	if (!static_branch_unlikely(&kvm_rme_is_available))
+		clear_bit(KVM_ARM_VCPU_REC, &features);
+
 	return features;
 }
 
@@ -1506,6 +1511,10 @@ static int kvm_vcpu_init_check_features(struct kvm_vcpu *vcpu,
 	if (test_bit(KVM_ARM_VCPU_HAS_EL2, &features))
 		return -EINVAL;
 
+	/* RME is incompatible with AArch32 */
+	if (test_bit(KVM_ARM_VCPU_REC, &features))
+		return -EINVAL;
+
 	return 0;
 }
 
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 470524b31951..16a5d11fc75a 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -137,6 +137,11 @@ int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature)
 			return -EPERM;
 
 		return kvm_vcpu_finalize_sve(vcpu);
+	case KVM_ARM_VCPU_REC:
+		if (!kvm_is_realm(vcpu->kvm) || !vcpu_is_rec(vcpu))
+			return -EINVAL;
+
+		return kvm_create_rec(vcpu);
 	}
 
 	return -EINVAL;
@@ -147,6 +152,11 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu)
 	if (vcpu_has_sve(vcpu) && !kvm_arm_vcpu_sve_finalized(vcpu))
 		return false;
 
+	if (kvm_is_realm(vcpu->kvm) &&
+	    !(vcpu_is_rec(vcpu) && kvm_arm_vcpu_rec_finalized(vcpu) &&
+	      READ_ONCE(vcpu->kvm->arch.realm.state) == REALM_STATE_ACTIVE))
+		return false;
+
 	return true;
 }
 
@@ -159,6 +169,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu)
 		kvm_unshare_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
 	kfree(sve_state);
 	kfree(vcpu->arch.ccsidr);
+	kvm_destroy_rec(vcpu);
 }
 
 static void kvm_vcpu_reset_sve(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 5e719235dd77..ad984706f68c 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -426,6 +426,150 @@ void kvm_destroy_realm(struct kvm *kvm)
 	kvm_free_stage2_pgd(&kvm->arch.mmu);
 }
 
+static void free_rec_aux(struct page **aux_pages,
+			 unsigned int num_aux)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_aux; i++)
+		free_delegated_granule(page_to_phys(aux_pages[i]));
+}
+
+static int alloc_rec_aux(struct page **aux_pages,
+			 u64 *aux_phys_pages,
+			 unsigned int num_aux)
+{
+	int ret;
+	unsigned int i;
+
+	for (i = 0; i < num_aux; i++) {
+		struct page *aux_page;
+		phys_addr_t aux_page_phys;
+
+		aux_page = alloc_page(GFP_KERNEL);
+		if (!aux_page) {
+			ret = -ENOMEM;
+			goto out_err;
+		}
+		aux_page_phys = page_to_phys(aux_page);
+		if (rmi_granule_delegate(aux_page_phys)) {
+			__free_page(aux_page);
+			ret = -ENXIO;
+			goto out_err;
+		}
+		aux_pages[i] = aux_page;
+		aux_phys_pages[i] = aux_page_phys;
+	}
+
+	return 0;
+out_err:
+	free_rec_aux(aux_pages, i);
+	return ret;
+}
+
+int kvm_create_rec(struct kvm_vcpu *vcpu)
+{
+	struct user_pt_regs *vcpu_regs = vcpu_gp_regs(vcpu);
+	unsigned long mpidr = kvm_vcpu_get_mpidr_aff(vcpu);
+	struct realm *realm = &vcpu->kvm->arch.realm;
+	struct realm_rec *rec = &vcpu->arch.rec;
+	unsigned long rec_page_phys;
+	struct rec_params *params;
+	int r, i;
+
+	if (kvm_realm_state(vcpu->kvm) != REALM_STATE_NEW)
+		return -ENOENT;
+
+	/*
+	 * The RMM will report PSCI v1.0 to Realms and the KVM_ARM_VCPU_PSCI_0_2
+	 * flag covers v0.2 and onwards.
+	 */
+	if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_PSCI_0_2))
+		return -EINVAL;
+
+	BUILD_BUG_ON(sizeof(*params) > PAGE_SIZE);
+	BUILD_BUG_ON(sizeof(*rec->run) > PAGE_SIZE);
+
+	params = (struct rec_params *)get_zeroed_page(GFP_KERNEL);
+	rec->rec_page = (void *)__get_free_page(GFP_KERNEL);
+	rec->run = (void *)get_zeroed_page(GFP_KERNEL);
+	if (!params || !rec->rec_page || !rec->run) {
+		r = -ENOMEM;
+		goto out_free_pages;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(params->gprs); i++)
+		params->gprs[i] = vcpu_regs->regs[i];
+
+	params->pc = vcpu_regs->pc;
+
+	if (vcpu->vcpu_id == 0)
+		params->flags |= REC_PARAMS_FLAG_RUNNABLE;
+
+	rec_page_phys = virt_to_phys(rec->rec_page);
+
+	if (rmi_granule_delegate(rec_page_phys)) {
+		r = -ENXIO;
+		goto out_free_pages;
+	}
+
+	r = alloc_rec_aux(rec->aux_pages, params->aux, realm->num_aux);
+	if (r)
+		goto out_undelegate_rmm_rec;
+
+	params->num_rec_aux = realm->num_aux;
+	params->mpidr = mpidr;
+
+	if (rmi_rec_create(virt_to_phys(realm->rd),
+			   rec_page_phys,
+			   virt_to_phys(params))) {
+		r = -ENXIO;
+		goto out_free_rec_aux;
+	}
+
+	rec->mpidr = mpidr;
+
+	free_page((unsigned long)params);
+	return 0;
+
+out_free_rec_aux:
+	free_rec_aux(rec->aux_pages, realm->num_aux);
+out_undelegate_rmm_rec:
+	if (WARN_ON(rmi_granule_undelegate(rec_page_phys)))
+		rec->rec_page = NULL;
+out_free_pages:
+	free_page((unsigned long)rec->run);
+	free_page((unsigned long)rec->rec_page);
+	free_page((unsigned long)params);
+	return r;
+}
+
+void kvm_destroy_rec(struct kvm_vcpu *vcpu)
+{
+	struct realm *realm = &vcpu->kvm->arch.realm;
+	struct realm_rec *rec = &vcpu->arch.rec;
+	unsigned long rec_page_phys;
+
+	if (!vcpu_is_rec(vcpu))
+		return;
+
+	free_page((unsigned long)rec->run);
+
+	rec_page_phys = virt_to_phys(rec->rec_page);
+
+	/*
+	 * The REC and any AUX pages cannot be reclaimed until the REC is
+	 * destroyed. So if the REC destroy fails then the REC page and any AUX
+	 * pages will be leaked.
+	 */
+	if (WARN_ON(rmi_rec_destroy(rec_page_phys)))
+		return;
+
+	free_rec_aux(rec->aux_pages, realm->num_aux);
+
+	free_delegated_granule(rec_page_phys);
+}
+
 int kvm_init_realm_vm(struct kvm *kvm)
 {
 	struct realm_params *params;
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:38 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:38 +0000
Subject: [PATCH v6 13/43] KVM: arm64: vgic: Provide helper for number of list registers
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-14-steven.price@arm.com>

Currently the number of list registers available is stored in a global
(kvm_vgic_global_state.nr_lr). With Arm CCA the RMM is permitted to
reserve list registers for its own use and so the number of available
list registers can be fewer for a realm VM. Provide a wrapper function
to fetch the global in preparation for restricting nr_lr when dealing
with a realm VM.

Signed-off-by: Steven Price <steven.price at arm.com>
---
New patch for v6
---
 arch/arm64/kvm/vgic/vgic.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index cc8c6b9b5dd8..1077fab2df4b 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -21,6 +21,11 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
 	.gicv3_cpuif = STATIC_KEY_FALSE_INIT,
 };
 
+static inline int kvm_vcpu_vgic_nr_lr(struct kvm_vcpu *vcpu)
+{
+	return kvm_vgic_global_state.nr_lr;
+}
+
 /*
  * Locking order is always:
  * kvm->lock (mutex)
@@ -802,7 +807,7 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
 	lockdep_assert_held(&vgic_cpu->ap_list_lock);
 
 	count = compute_ap_list_depth(vcpu, &multi_sgi);
-	if (count > kvm_vgic_global_state.nr_lr || multi_sgi)
+	if (count > kvm_vcpu_vgic_nr_lr(vcpu) || multi_sgi)
 		vgic_sort_ap_list(vcpu);
 
 	count = 0;
@@ -831,7 +836,7 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
 
 		raw_spin_unlock(&irq->irq_lock);
 
-		if (count == kvm_vgic_global_state.nr_lr) {
+		if (count == kvm_vcpu_vgic_nr_lr(vcpu)) {
 			if (!list_is_last(&irq->ap_list,
 					  &vgic_cpu->ap_list_head))
 				vgic_set_underflow(vcpu);
@@ -840,7 +845,7 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
 	}
 
 	/* Nuke remaining LRs */
-	for (i = count ; i < kvm_vgic_global_state.nr_lr; i++)
+	for (i = count ; i < kvm_vcpu_vgic_nr_lr(vcpu); i++)
 		vgic_clear_lr(vcpu, i);
 
 	if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:39 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:39 +0000
Subject: [PATCH v6 14/43] arm64: RME: Support for the VGIC in realms
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-15-steven.price@arm.com>

The RMM provides emulation of a VGIC to the realm guest but delegates
much of the handling to the host. Implement support in KVM for
saving/restoring state to/from the REC structure.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes from v5:
 * Handle RMM providing fewer GIC LRs than the hardware supports.
---
 arch/arm64/include/asm/kvm_rme.h |  1 +
 arch/arm64/kvm/arm.c             | 16 +++++++++---
 arch/arm64/kvm/rme.c             |  5 ++++
 arch/arm64/kvm/vgic/vgic-init.c  |  2 +-
 arch/arm64/kvm/vgic/vgic-v3.c    |  5 ++++
 arch/arm64/kvm/vgic/vgic.c       | 43 ++++++++++++++++++++++++++++++--
 6 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 62d4a63d3035..be64b749fcac 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -83,6 +83,7 @@ struct realm_rec {
 
 void kvm_init_rme(void);
 u32 kvm_realm_ipa_limit(void);
+u32 kvm_realm_vgic_nr_lr(void);
 
 int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap);
 int kvm_init_realm_vm(struct kvm *kvm);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 2d97147651be..ab00fb7a8ece 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -683,19 +683,24 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+	kvm_timer_vcpu_put(vcpu);
+	kvm_vgic_put(vcpu);
+
+	vcpu->cpu = -1;
+
+	if (vcpu_is_rec(vcpu))
+		return;
+
 	kvm_arch_vcpu_put_debug_state_flags(vcpu);
 	kvm_arch_vcpu_put_fp(vcpu);
 	if (has_vhe())
 		kvm_vcpu_put_vhe(vcpu);
-	kvm_timer_vcpu_put(vcpu);
-	kvm_vgic_put(vcpu);
 	kvm_vcpu_pmu_restore_host(vcpu);
 	if (vcpu_has_nv(vcpu))
 		kvm_vcpu_put_hw_mmu(vcpu);
 	kvm_arm_vmid_clear_active();
 
 	vcpu_clear_on_unsupported_cpu(vcpu);
-	vcpu->cpu = -1;
 }
 
 static void __kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu)
@@ -902,6 +907,11 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
 			return ret;
 	}
 
+	if (!irqchip_in_kernel(kvm) && kvm_is_realm(vcpu->kvm)) {
+		/* Userspace irqchip not yet supported with Realms */
+		return -EOPNOTSUPP;
+	}
+
 	mutex_lock(&kvm->arch.config_lock);
 	set_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags);
 	mutex_unlock(&kvm->arch.config_lock);
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index ad984706f68c..72778d8ab52b 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -52,6 +52,11 @@ u32 kvm_realm_ipa_limit(void)
 	return u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_S2SZ);
 }
 
+u32 kvm_realm_vgic_nr_lr(void)
+{
+	return u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_GICV3_NUM_LRS);
+}
+
 static int get_start_level(struct realm *realm)
 {
 	return 4 - stage2_pgtable_levels(realm->ia_bits);
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index bc7e22ab5d81..0ec9f6f62e86 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -79,7 +79,7 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
 	 * the proper checks already.
 	 */
 	if (type == KVM_DEV_TYPE_ARM_VGIC_V2 &&
-		!kvm_vgic_global_state.can_emulate_gicv2)
+	    (!kvm_vgic_global_state.can_emulate_gicv2 || kvm_is_realm(kvm)))
 		return -ENODEV;
 
 	/* Must be held to avoid race with vCPU creation */
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index f267bc2486a1..9048e86e5775 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -7,9 +7,11 @@
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 #include <kvm/arm_vgic.h>
+#include <asm/kvm_emulate.h>
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_asm.h>
+#include <asm/rmi_smc.h>
 
 #include "vgic.h"
 
@@ -746,6 +748,9 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
+	if (vcpu_is_rec(vcpu))
+		cpu_if->vgic_vmcr = vcpu->arch.rec.run->exit.gicv3_vmcr;
+
 	kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
 	WARN_ON(vgic_v4_put(vcpu));
 
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 1077fab2df4b..4218de3ea9da 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -10,7 +10,9 @@
 #include <linux/list_sort.h>
 #include <linux/nospec.h>
 
+#include <asm/kvm_emulate.h>
 #include <asm/kvm_hyp.h>
+#include <asm/kvm_rme.h>
 
 #include "vgic.h"
 
@@ -23,6 +25,8 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
 
 static inline int kvm_vcpu_vgic_nr_lr(struct kvm_vcpu *vcpu)
 {
+	if (unlikely(vcpu_is_rec(vcpu)))
+		return kvm_realm_vgic_nr_lr();
 	return kvm_vgic_global_state.nr_lr;
 }
 
@@ -864,10 +868,23 @@ static inline bool can_access_vgic_from_kernel(void)
 	return !static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) || has_vhe();
 }
 
+static inline void vgic_rmm_save_state(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
+	int i;
+
+	for (i = 0; i < kvm_vcpu_vgic_nr_lr(vcpu); i++) {
+		cpu_if->vgic_lr[i] = vcpu->arch.rec.run->exit.gicv3_lrs[i];
+		vcpu->arch.rec.run->enter.gicv3_lrs[i] = 0;
+	}
+}
+
 static inline void vgic_save_state(struct kvm_vcpu *vcpu)
 {
 	if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
 		vgic_v2_save_state(vcpu);
+	else if (vcpu_is_rec(vcpu))
+		vgic_rmm_save_state(vcpu);
 	else
 		__vgic_v3_save_state(&vcpu->arch.vgic_cpu.vgic_v3);
 }
@@ -894,10 +911,28 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 	vgic_prune_ap_list(vcpu);
 }
 
+static inline void vgic_rmm_restore_state(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
+	int i;
+
+	for (i = 0; i < kvm_vcpu_vgic_nr_lr(vcpu); i++) {
+		vcpu->arch.rec.run->enter.gicv3_lrs[i] = cpu_if->vgic_lr[i];
+		/*
+		 * Also populate the rec.run->exit copies so that a late
+		 * decision to back out from entering the realm doesn't cause
+		 * the state to be lost
+		 */
+		vcpu->arch.rec.run->exit.gicv3_lrs[i] = cpu_if->vgic_lr[i];
+	}
+}
+
 static inline void vgic_restore_state(struct kvm_vcpu *vcpu)
 {
 	if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
 		vgic_v2_restore_state(vcpu);
+	else if (vcpu_is_rec(vcpu))
+		vgic_rmm_restore_state(vcpu);
 	else
 		__vgic_v3_restore_state(&vcpu->arch.vgic_cpu.vgic_v3);
 }
@@ -938,7 +973,9 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
 
 void kvm_vgic_load(struct kvm_vcpu *vcpu)
 {
-	if (unlikely(!irqchip_in_kernel(vcpu->kvm) || !vgic_initialized(vcpu->kvm))) {
+	if (unlikely(!irqchip_in_kernel(vcpu->kvm) ||
+		     !vgic_initialized(vcpu->kvm) ||
+		     vcpu_is_rec(vcpu))) {
 		if (has_vhe() && static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
 			__vgic_v3_activate_traps(&vcpu->arch.vgic_cpu.vgic_v3);
 		return;
@@ -952,7 +989,9 @@ void kvm_vgic_load(struct kvm_vcpu *vcpu)
 
 void kvm_vgic_put(struct kvm_vcpu *vcpu)
 {
-	if (unlikely(!irqchip_in_kernel(vcpu->kvm) || !vgic_initialized(vcpu->kvm))) {
+	if (unlikely(!irqchip_in_kernel(vcpu->kvm) ||
+		     !vgic_initialized(vcpu->kvm) ||
+		     vcpu_is_rec(vcpu))) {
 		if (has_vhe() && static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
 			__vgic_v3_deactivate_traps(&vcpu->arch.vgic_cpu.vgic_v3);
 		return;
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:40 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:40 +0000
Subject: [PATCH v6 15/43] KVM: arm64: Support timers in realm RECs
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-16-steven.price@arm.com>

The RMM keeps track of the timer while the realm REC is running, but on
exit to the normal world KVM is responsible for handling the timers.

A later patch adds the support for propagating the timer values from the
exit data structure and calling kvm_realm_timers_update().

Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/arch_timer.c  | 45 ++++++++++++++++++++++++++++++++----
 include/kvm/arm_arch_timer.h |  2 ++
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 1215df590418..46fa903ed7ab 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -162,6 +162,13 @@ static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)
 
 static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
 {
+	struct kvm_vcpu *vcpu = ctxt->vcpu;
+
+	if (kvm_is_realm(vcpu->kvm)) {
+		WARN_ON(offset);
+		return;
+	}
+
 	if (!ctxt->offset.vm_offset) {
 		WARN(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
 		return;
@@ -459,6 +466,21 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
 	}
 }
 
+void kvm_realm_timers_update(struct kvm_vcpu *vcpu)
+{
+	struct arch_timer_cpu *arch_timer = &vcpu->arch.timer_cpu;
+	int i;
+
+	for (i = 0; i < NR_KVM_EL0_TIMERS; i++) {
+		struct arch_timer_context *timer = &arch_timer->timers[i];
+		bool status = timer_get_ctl(timer) & ARCH_TIMER_CTRL_IT_STAT;
+		bool level = kvm_timer_irq_can_fire(timer) && status;
+
+		if (level != timer->irq.level)
+			kvm_timer_update_irq(vcpu, level, timer);
+	}
+}
+
 /* Only called for a fully emulated timer */
 static void timer_emulate(struct arch_timer_context *ctx)
 {
@@ -830,6 +852,8 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 	if (unlikely(!timer->enabled))
 		return;
 
+	kvm_timer_unblocking(vcpu);
+
 	get_timer_map(vcpu, &map);
 
 	if (static_branch_likely(&has_gic_active_state)) {
@@ -843,8 +867,6 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 		kvm_timer_vcpu_load_nogic(vcpu);
 	}
 
-	kvm_timer_unblocking(vcpu);
-
 	timer_restore_state(map.direct_vtimer);
 	if (map.direct_ptimer)
 		timer_restore_state(map.direct_ptimer);
@@ -987,7 +1009,9 @@ static void timer_context_init(struct kvm_vcpu *vcpu, int timerid)
 
 	ctxt->vcpu = vcpu;
 
-	if (timerid == TIMER_VTIMER)
+	if (kvm_is_realm(vcpu->kvm))
+		ctxt->offset.vm_offset = NULL;
+	else if (timerid == TIMER_VTIMER)
 		ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset;
 	else
 		ctxt->offset.vm_offset = &kvm->arch.timer_data.poffset;
@@ -1010,13 +1034,19 @@ static void timer_context_init(struct kvm_vcpu *vcpu, int timerid)
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
+	u64 cntvoff;
 
 	for (int i = 0; i < NR_KVM_TIMERS; i++)
 		timer_context_init(vcpu, i);
 
+	if (kvm_is_realm(vcpu->kvm))
+		cntvoff = 0;
+	else
+		cntvoff = kvm_phys_timer_read();
+
 	/* Synchronize offsets across timers of a VM if not already provided */
 	if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) {
-		timer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read());
+		timer_set_offset(vcpu_vtimer(vcpu), cntvoff);
 		timer_set_offset(vcpu_ptimer(vcpu), 0);
 	}
 
@@ -1524,6 +1554,13 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
 		return -EINVAL;
 	}
 
+	/*
+	 * We don't use mapped IRQs for Realms because the RMI doesn't allow
+	 * us setting the LR.HW bit in the VGIC.
+	 */
+	if (vcpu_is_rec(vcpu))
+		return 0;
+
 	get_timer_map(vcpu, &map);
 
 	ret = kvm_vgic_map_phys_irq(vcpu,
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index fd650a8789b9..21297643e529 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -112,6 +112,8 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 
+void kvm_realm_timers_update(struct kvm_vcpu *vcpu);
+
 u64 kvm_phys_timer_read(void);
 
 void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu);
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:41 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:41 +0000
Subject: [PATCH v6 16/43] arm64: RME: Allow VMM to set RIPAS
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-17-steven.price@arm.com>

Each page within the protected region of the realm guest can be marked
as either RAM or EMPTY. Allow the VMM to control this before the guest
has started and provide the equivalent functions to change this (with
the guest's approval) at runtime.

When transitioning from RIPAS RAM (1) to RIPAS EMPTY (0) the memory is
unmapped from the guest and undelegated allowing the memory to be reused
by the host. When transitioning to RIPAS RAM the actual population of
the leaf RTTs is done later on stage 2 fault, however it may be
necessary to allocate additional RTTs to allow the RMM track the RIPAS
for the requested range.

When freeing a block mapping it is necessary to temporarily unfold the
RTT which requires delegating an extra page to the RMM, this page can
then be recovered once the contents of the block mapping have been
freed.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes from v5:
 * Adapt to rebasing.
 * Introduce find_map_level()
 * Rename some functions to be clearer.
 * Drop the "spare page" functionality.
Changes from v2:
 * {alloc,free}_delegated_page() moved from previous patch to this one.
 * alloc_delegated_page() now takes a gfp_t flags parameter.
 * Fix the reference counting of guestmem pages to avoid leaking memory.
 * Several misc code improvements and extra comments.
---
 arch/arm64/include/asm/kvm_rme.h |  17 ++
 arch/arm64/kvm/mmu.c             |   8 +-
 arch/arm64/kvm/rme.c             | 411 +++++++++++++++++++++++++++++++
 3 files changed, 433 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index be64b749fcac..4e7758f0e4b5 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -92,6 +92,15 @@ void kvm_realm_destroy_rtts(struct kvm *kvm, u32 ia_bits);
 int kvm_create_rec(struct kvm_vcpu *vcpu);
 void kvm_destroy_rec(struct kvm_vcpu *vcpu);
 
+void kvm_realm_unmap_range(struct kvm *kvm,
+			   unsigned long ipa,
+			   u64 size,
+			   bool unmap_private);
+int realm_set_ipa_state(struct kvm_vcpu *vcpu,
+			unsigned long addr, unsigned long end,
+			unsigned long ripas,
+			unsigned long *top_ipa);
+
 #define RMM_RTT_BLOCK_LEVEL	2
 #define RMM_RTT_MAX_LEVEL	3
 
@@ -110,4 +119,12 @@ static inline unsigned long rme_rtt_level_mapsize(int level)
 	return (1UL << RMM_RTT_LEVEL_SHIFT(level));
 }
 
+static inline bool realm_is_addr_protected(struct realm *realm,
+					   unsigned long addr)
+{
+	unsigned int ia_bits = realm->ia_bits;
+
+	return !(addr & ~(BIT(ia_bits - 1) - 1));
+}
+
 #endif
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 325b578c734d..b100d4b3aa29 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -310,6 +310,7 @@ static void invalidate_icache_guest_page(void *va, size_t size)
  * @start: The intermediate physical base address of the range to unmap
  * @size:  The size of the area to unmap
  * @may_block: Whether or not we are permitted to block
+ * @only_shared: If true then protected mappings should not be unmapped
  *
  * Clear a range of stage-2 mappings, lowering the various ref-counts.  Must
  * be called while holding mmu_lock (unless for freeing the stage2 pgd before
@@ -317,7 +318,7 @@ static void invalidate_icache_guest_page(void *va, size_t size)
  * with things behind our backs.
  */
 static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size,
-				 bool may_block)
+				 bool may_block, bool only_shared)
 {
 	struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
 	phys_addr_t end = start + size;
@@ -331,7 +332,7 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
 void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
 			    u64 size, bool may_block)
 {
-	__unmap_stage2_range(mmu, start, size, may_block);
+	__unmap_stage2_range(mmu, start, size, may_block, false);
 }
 
 void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
@@ -1932,7 +1933,8 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
 
 	__unmap_stage2_range(&kvm->arch.mmu, range->start << PAGE_SHIFT,
 			     (range->end - range->start) << PAGE_SHIFT,
-			     range->may_block);
+			     range->may_block,
+			     range->only_shared);
 
 	kvm_nested_s2_unmap(kvm, range->may_block);
 	return false;
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 72778d8ab52b..e8ad04405ecd 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -62,6 +62,51 @@ static int get_start_level(struct realm *realm)
 	return 4 - stage2_pgtable_levels(realm->ia_bits);
 }
 
+static int find_map_level(struct realm *realm,
+			  unsigned long start,
+			  unsigned long end)
+{
+	int level = RMM_RTT_MAX_LEVEL;
+
+	while (level > get_start_level(realm)) {
+		unsigned long map_size = rme_rtt_level_mapsize(level - 1);
+
+		if (!IS_ALIGNED(start, map_size) ||
+		    (start + map_size) > end)
+			break;
+
+		level--;
+	}
+
+	return level;
+}
+
+static phys_addr_t alloc_delegated_granule(struct kvm_mmu_memory_cache *mc,
+					   gfp_t flags)
+{
+	phys_addr_t phys = PHYS_ADDR_MAX;
+	void *virt;
+
+	if (mc)
+		virt = kvm_mmu_memory_cache_alloc(mc);
+	else
+		virt = (void *)__get_free_page(flags);
+
+	if (!virt)
+		goto out;
+
+	phys = virt_to_phys(virt);
+
+	if (rmi_granule_delegate(phys)) {
+		free_page((unsigned long)virt);
+
+		phys = PHYS_ADDR_MAX;
+	}
+
+out:
+	return phys;
+}
+
 static void free_delegated_granule(phys_addr_t phys)
 {
 	if (WARN_ON(rmi_granule_undelegate(phys))) {
@@ -72,6 +117,132 @@ static void free_delegated_granule(phys_addr_t phys)
 	free_page((unsigned long)phys_to_virt(phys));
 }
 
+static int realm_rtt_create(struct realm *realm,
+			    unsigned long addr,
+			    int level,
+			    phys_addr_t phys)
+{
+	addr = ALIGN_DOWN(addr, rme_rtt_level_mapsize(level - 1));
+	return rmi_rtt_create(virt_to_phys(realm->rd), phys, addr, level);
+}
+
+static int realm_rtt_fold(struct realm *realm,
+			  unsigned long addr,
+			  int level,
+			  phys_addr_t *rtt_granule)
+{
+	unsigned long out_rtt;
+	int ret;
+
+	ret = rmi_rtt_fold(virt_to_phys(realm->rd), addr, level, &out_rtt);
+
+	if (RMI_RETURN_STATUS(ret) == RMI_SUCCESS && rtt_granule)
+		*rtt_granule = out_rtt;
+
+	return ret;
+}
+
+static int realm_destroy_protected(struct realm *realm,
+				   unsigned long ipa,
+				   unsigned long *next_addr)
+{
+	unsigned long rd = virt_to_phys(realm->rd);
+	unsigned long addr;
+	phys_addr_t rtt;
+	int ret;
+
+loop:
+	ret = rmi_data_destroy(rd, ipa, &addr, next_addr);
+	if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+		if (*next_addr > ipa)
+			return 0; /* UNASSIGNED */
+		rtt = alloc_delegated_granule(NULL, GFP_KERNEL);
+		if (WARN_ON(rtt == PHYS_ADDR_MAX))
+			return -1;
+		/*
+		 * ASSIGNED - ipa is mapped as a block, so split. The index
+		 * from the return code should be 2 otherwise it appears
+		 * there's a huge page bigger than KVM currently supports
+		 */
+		WARN_ON(RMI_RETURN_INDEX(ret) != 2);
+		ret = realm_rtt_create(realm, ipa, 3, rtt);
+		if (WARN_ON(ret)) {
+			free_delegated_granule(rtt);
+			return -1;
+		}
+		/* retry */
+		goto loop;
+	} else if (WARN_ON(ret)) {
+		return -1;
+	}
+	ret = rmi_granule_undelegate(addr);
+
+	/*
+	 * If the undelegate fails then something has gone seriously
+	 * wrong: take an extra reference to just leak the page
+	 */
+	if (!WARN_ON(ret))
+		put_page(phys_to_page(addr));
+
+	return 0;
+}
+
+static void realm_unmap_shared_range(struct kvm *kvm,
+				     int level,
+				     unsigned long start,
+				     unsigned long end)
+{
+	struct realm *realm = &kvm->arch.realm;
+	unsigned long rd = virt_to_phys(realm->rd);
+	ssize_t map_size = rme_rtt_level_mapsize(level);
+	unsigned long next_addr, addr;
+	unsigned long shared_bit = BIT(realm->ia_bits - 1);
+
+	if (WARN_ON(level > RMM_RTT_MAX_LEVEL))
+		return;
+
+	start |= shared_bit;
+	end |= shared_bit;
+
+	for (addr = start; addr < end; addr = next_addr) {
+		unsigned long align_addr = ALIGN(addr, map_size);
+		int ret;
+
+		next_addr = ALIGN(addr + 1, map_size);
+
+		if (align_addr != addr || next_addr > end) {
+			/* Need to recurse deeper */
+			if (addr < align_addr)
+				next_addr = align_addr;
+			realm_unmap_shared_range(kvm, level + 1, addr,
+						 min(next_addr, end));
+			continue;
+		}
+
+		ret = rmi_rtt_unmap_unprotected(rd, addr, level, &next_addr);
+		switch (RMI_RETURN_STATUS(ret)) {
+		case RMI_SUCCESS:
+			break;
+		case RMI_ERROR_RTT:
+			if (next_addr == addr) {
+				/*
+				 * There's a mapping here, but it's not a block
+				 * mapping, so reset next_addr to the next block
+				 * boundary and recurse to clear out the pages
+				 * one level deeper.
+				 */
+				next_addr = ALIGN(addr + 1, map_size);
+				realm_unmap_shared_range(kvm, level + 1, addr,
+							 next_addr);
+			}
+			break;
+		default:
+			WARN_ON(1);
+			return;
+		}
+	}
+}
+
 static int realm_create_rd(struct kvm *kvm)
 {
 	struct realm *realm = &kvm->arch.realm;
@@ -161,6 +332,30 @@ static int realm_rtt_destroy(struct realm *realm, unsigned long addr,
 	return ret;
 }
 
+static int realm_create_rtt_levels(struct realm *realm,
+				   unsigned long ipa,
+				   int level,
+				   int max_level,
+				   struct kvm_mmu_memory_cache *mc)
+{
+	if (WARN_ON(level == max_level))
+		return 0;
+
+	while (level++ < max_level) {
+		phys_addr_t rtt = alloc_delegated_granule(mc, GFP_KERNEL);
+
+		if (rtt == PHYS_ADDR_MAX)
+			return -ENOMEM;
+
+		if (realm_rtt_create(realm, ipa, level, rtt)) {
+			free_delegated_granule(rtt);
+			return -ENXIO;
+		}
+	}
+
+	return 0;
+}
+
 static int realm_tear_down_rtt_level(struct realm *realm, int level,
 				     unsigned long start, unsigned long end)
 {
@@ -251,6 +446,61 @@ static int realm_tear_down_rtt_range(struct realm *realm,
 					 start, end);
 }
 
+/*
+ * Returns 0 on successful fold, a negative value on error, a positive value if
+ * we were not able to fold all tables at this level.
+ */
+static int realm_fold_rtt_level(struct realm *realm, int level,
+				unsigned long start, unsigned long end)
+{
+	int not_folded = 0;
+	ssize_t map_size;
+	unsigned long addr, next_addr;
+
+	if (WARN_ON(level > RMM_RTT_MAX_LEVEL))
+		return -EINVAL;
+
+	map_size = rme_rtt_level_mapsize(level - 1);
+
+	for (addr = start; addr < end; addr = next_addr) {
+		phys_addr_t rtt_granule;
+		int ret;
+		unsigned long align_addr = ALIGN(addr, map_size);
+
+		next_addr = ALIGN(addr + 1, map_size);
+
+		ret = realm_rtt_fold(realm, align_addr, level, &rtt_granule);
+
+		switch (RMI_RETURN_STATUS(ret)) {
+		case RMI_SUCCESS:
+			free_delegated_granule(rtt_granule);
+			break;
+		case RMI_ERROR_RTT:
+			if (level == RMM_RTT_MAX_LEVEL ||
+			    RMI_RETURN_INDEX(ret) < level) {
+				not_folded++;
+				break;
+			}
+			/* Recurse a level deeper */
+			ret = realm_fold_rtt_level(realm,
+						   level + 1,
+						   addr,
+						   next_addr);
+			if (ret < 0)
+				return ret;
+			else if (ret == 0)
+				/* Try again at this level */
+				next_addr = addr;
+			break;
+		default:
+			WARN_ON(1);
+			return -ENXIO;
+		}
+	}
+
+	return not_folded;
+}
+
 void kvm_realm_destroy_rtts(struct kvm *kvm, u32 ia_bits)
 {
 	struct realm *realm = &kvm->arch.realm;
@@ -258,6 +508,155 @@ void kvm_realm_destroy_rtts(struct kvm *kvm, u32 ia_bits)
 	WARN_ON(realm_tear_down_rtt_range(realm, 0, (1UL << ia_bits)));
 }
 
+static void realm_unmap_private_range(struct kvm *kvm,
+				      unsigned long start,
+				      unsigned long end)
+{
+	struct realm *realm = &kvm->arch.realm;
+	unsigned long next_addr, addr;
+
+	for (addr = start; addr < end; addr = next_addr) {
+		int ret;
+
+		ret = realm_destroy_protected(realm, addr, &next_addr);
+
+		if (WARN_ON(ret))
+			break;
+	}
+
+	realm_fold_rtt_level(realm, get_start_level(realm) + 1,
+			     start, end);
+}
+
+void kvm_realm_unmap_range(struct kvm *kvm, unsigned long start, u64 size,
+			   bool unmap_private)
+{
+	unsigned long end = start + size;
+	struct realm *realm = &kvm->arch.realm;
+
+	end = min(BIT(realm->ia_bits - 1), end);
+
+	if (realm->state == REALM_STATE_NONE)
+		return;
+
+	realm_unmap_shared_range(kvm, find_map_level(realm, start, end),
+				 start, end);
+	if (unmap_private)
+		realm_unmap_private_range(kvm, start, end);
+}
+
+int realm_set_ipa_state(struct kvm_vcpu *vcpu,
+			unsigned long start,
+			unsigned long end,
+			unsigned long ripas,
+			unsigned long *top_ipa)
+{
+	struct kvm *kvm = vcpu->kvm;
+	struct realm *realm = &kvm->arch.realm;
+	struct realm_rec *rec = &vcpu->arch.rec;
+	phys_addr_t rd_phys = virt_to_phys(realm->rd);
+	phys_addr_t rec_phys = virt_to_phys(rec->rec_page);
+	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
+	unsigned long ipa = start;
+	int ret = 0;
+
+	while (ipa < end) {
+		unsigned long next;
+
+		ret = rmi_rtt_set_ripas(rd_phys, rec_phys, ipa, end, &next);
+
+		if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+			int walk_level = RMI_RETURN_INDEX(ret);
+			int level = find_map_level(realm, ipa, end);
+
+			/*
+			 * If the RMM walk ended early then more tables are
+			 * needed to reach the required depth to set the RIPAS.
+			 */
+			if (walk_level < level) {
+				ret = realm_create_rtt_levels(realm, ipa,
+							      walk_level,
+							      level,
+							      memcache);
+				/* Retry with RTTs created */
+				if (!ret)
+					continue;
+			} else {
+				ret = -EINVAL;
+			}
+
+			break;
+		} else if (RMI_RETURN_STATUS(ret) != RMI_SUCCESS) {
+			WARN(1, "Unexpected error in %s: %#x\n", __func__,
+			     ret);
+			ret = -EINVAL;
+			break;
+		}
+		ipa = next;
+	}
+
+	*top_ipa = ipa;
+
+	if (ripas == RMI_EMPTY && ipa != start)
+		realm_unmap_private_range(kvm, start, ipa);
+
+	return ret;
+}
+
+static int realm_init_ipa_state(struct realm *realm,
+				unsigned long ipa,
+				unsigned long end)
+{
+	phys_addr_t rd_phys = virt_to_phys(realm->rd);
+	int ret;
+
+	while (ipa < end) {
+		unsigned long next;
+
+		ret = rmi_rtt_init_ripas(rd_phys, ipa, end, &next);
+
+		if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+			int err_level = RMI_RETURN_INDEX(ret);
+			int level = find_map_level(realm, ipa, end);
+
+			if (WARN_ON(err_level >= level))
+				return -ENXIO;
+
+			ret = realm_create_rtt_levels(realm, ipa,
+						      err_level,
+						      level, NULL);
+			if (ret)
+				return ret;
+			/* Retry with the RTT levels in place */
+			continue;
+		} else if (WARN_ON(ret)) {
+			return -ENXIO;
+		}
+
+		ipa = next;
+	}
+
+	return 0;
+}
+
+static int kvm_init_ipa_range_realm(struct kvm *kvm,
+				    struct kvm_cap_arm_rme_init_ipa_args *args)
+{
+	gpa_t addr, end;
+	struct realm *realm = &kvm->arch.realm;
+
+	addr = args->init_ipa_base;
+	end = addr + args->init_ipa_size;
+
+	if (end < addr)
+		return -EINVAL;
+
+	if (kvm_realm_state(kvm) != REALM_STATE_NEW)
+		return -EINVAL;
+
+	return realm_init_ipa_state(realm, addr, end);
+}
+
 /* Protects access to rme_vmid_bitmap */
 static DEFINE_SPINLOCK(rme_vmid_lock);
 static unsigned long *rme_vmid_bitmap;
@@ -383,6 +782,18 @@ int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
 	case KVM_CAP_ARM_RME_CREATE_RD:
 		r = kvm_create_realm(kvm);
 		break;
+	case KVM_CAP_ARM_RME_INIT_IPA_REALM: {
+		struct kvm_cap_arm_rme_init_ipa_args args;
+		void __user *argp = u64_to_user_ptr(cap->args[1]);
+
+		if (copy_from_user(&args, argp, sizeof(args))) {
+			r = -EFAULT;
+			break;
+		}
+
+		r = kvm_init_ipa_range_realm(kvm, &args);
+		break;
+	}
 	default:
 		r = -EINVAL;
 		break;
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:42 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:42 +0000
Subject: [PATCH v6 17/43] arm64: RME: Handle realm enter/exit
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-18-steven.price@arm.com>

Entering a realm is done using a SMC call to the RMM. On exit the
exit-codes need to be handled slightly differently to the normal KVM
path so define our own functions for realm enter/exit and hook them
in if the guest is a realm guest.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v5:
 * For a RIPAS_CHANGE request from the guest perform the actual RIPAS
   change on next entry rather than immediately on the exit. This allows
   the VMM to 'reject' a RIPAS change by refusing to continue
   scheduling.
Changes since v4:
 * Rename handle_rme_exit() to handle_rec_exit()
 * Move the loop to copy registers into the REC enter structure from the
   to rec_exit_handlers callbacks to kvm_rec_enter(). This fixes a bug
   where the handler exits to user space and user space wants to modify
   the GPRS.
 * Some code rearrangement in rec_exit_ripas_change().
Changes since v2:
 * realm_set_ipa_state() now provides an output parameter for the
   top_iap that was changed. Use this to signal the VMM with the correct
   range that has been transitioned.
 * Adapt to previous patch changes.
---
 arch/arm64/include/asm/kvm_rme.h |   3 +
 arch/arm64/kvm/Makefile          |   2 +-
 arch/arm64/kvm/arm.c             |  19 +++-
 arch/arm64/kvm/rme-exit.c        | 167 +++++++++++++++++++++++++++++++
 arch/arm64/kvm/rme.c             |  48 +++++++++
 5 files changed, 233 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm64/kvm/rme-exit.c

diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 4e7758f0e4b5..0410650cd545 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -92,6 +92,9 @@ void kvm_realm_destroy_rtts(struct kvm *kvm, u32 ia_bits);
 int kvm_create_rec(struct kvm_vcpu *vcpu);
 void kvm_destroy_rec(struct kvm_vcpu *vcpu);
 
+int kvm_rec_enter(struct kvm_vcpu *vcpu);
+int handle_rec_exit(struct kvm_vcpu *vcpu, int rec_run_status);
+
 void kvm_realm_unmap_range(struct kvm *kvm,
 			   unsigned long ipa,
 			   u64 size,
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index ce8a10d3161d..0170e902fb63 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -24,7 +24,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-mmio.o vgic/vgic-mmio-v2.o \
 	 vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
 	 vgic/vgic-its.o vgic/vgic-debug.o \
-	 rme.o
+	 rme.o rme-exit.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
 kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index ab00fb7a8ece..6e83b2e3a6cf 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1264,7 +1264,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		trace_kvm_entry(*vcpu_pc(vcpu));
 		guest_timing_enter_irqoff();
 
-		ret = kvm_arm_vcpu_enter_exit(vcpu);
+		if (vcpu_is_rec(vcpu))
+			ret = kvm_rec_enter(vcpu);
+		else
+			ret = kvm_arm_vcpu_enter_exit(vcpu);
 
 		vcpu->mode = OUTSIDE_GUEST_MODE;
 		vcpu->stat.exits++;
@@ -1318,10 +1321,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 
 		local_irq_enable();
 
-		trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
-
 		/* Exit types that need handling before we can be preempted */
-		handle_exit_early(vcpu, ret);
+		if (!vcpu_is_rec(vcpu)) {
+			trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu),
+				       *vcpu_pc(vcpu));
+
+			handle_exit_early(vcpu, ret);
+		}
 
 		preempt_enable();
 
@@ -1344,7 +1350,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 			ret = ARM_EXCEPTION_IL;
 		}
 
-		ret = handle_exit(vcpu, ret);
+		if (vcpu_is_rec(vcpu))
+			ret = handle_rec_exit(vcpu, ret);
+		else
+			ret = handle_exit(vcpu, ret);
 	}
 
 	/* Tell userspace about in-kernel device output levels */
diff --git a/arch/arm64/kvm/rme-exit.c b/arch/arm64/kvm/rme-exit.c
new file mode 100644
index 000000000000..e532aa80e10d
--- /dev/null
+++ b/arch/arm64/kvm/rme-exit.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#include <linux/kvm_host.h>
+#include <kvm/arm_hypercalls.h>
+#include <kvm/arm_psci.h>
+
+#include <asm/rmi_smc.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_rme.h>
+#include <asm/kvm_mmu.h>
+
+typedef int (*exit_handler_fn)(struct kvm_vcpu *vcpu);
+
+static int rec_exit_reason_notimpl(struct kvm_vcpu *vcpu)
+{
+	struct realm_rec *rec = &vcpu->arch.rec;
+
+	pr_err("[vcpu %d] Unhandled exit reason from realm (ESR: %#llx)\n",
+	       vcpu->vcpu_id, rec->run->exit.esr);
+	return -ENXIO;
+}
+
+static int rec_exit_sync_dabt(struct kvm_vcpu *vcpu)
+{
+	return kvm_handle_guest_abort(vcpu);
+}
+
+static int rec_exit_sync_iabt(struct kvm_vcpu *vcpu)
+{
+	struct realm_rec *rec = &vcpu->arch.rec;
+
+	pr_err("[vcpu %d] Unhandled instruction abort (ESR: %#llx).\n",
+	       vcpu->vcpu_id, rec->run->exit.esr);
+	return -ENXIO;
+}
+
+static int rec_exit_sys_reg(struct kvm_vcpu *vcpu)
+{
+	struct realm_rec *rec = &vcpu->arch.rec;
+	unsigned long esr = kvm_vcpu_get_esr(vcpu);
+	int rt = kvm_vcpu_sys_get_rt(vcpu);
+	bool is_write = !(esr & 1);
+	int ret;
+
+	if (is_write)
+		vcpu_set_reg(vcpu, rt, rec->run->exit.gprs[0]);
+
+	ret = kvm_handle_sys_reg(vcpu);
+
+	if (ret >= 0 && !is_write)
+		rec->run->enter.gprs[0] = vcpu_get_reg(vcpu, rt);
+
+	return ret;
+}
+
+static exit_handler_fn rec_exit_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]	= rec_exit_reason_notimpl,
+	[ESR_ELx_EC_SYS64]	= rec_exit_sys_reg,
+	[ESR_ELx_EC_DABT_LOW]	= rec_exit_sync_dabt,
+	[ESR_ELx_EC_IABT_LOW]	= rec_exit_sync_iabt
+};
+
+static int rec_exit_psci(struct kvm_vcpu *vcpu)
+{
+	struct realm_rec *rec = &vcpu->arch.rec;
+	int i;
+
+	for (i = 0; i < REC_RUN_GPRS; i++)
+		vcpu_set_reg(vcpu, i, rec->run->exit.gprs[i]);
+
+	return kvm_smccc_call_handler(vcpu);
+}
+
+static int rec_exit_ripas_change(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+	struct realm *realm = &kvm->arch.realm;
+	struct realm_rec *rec = &vcpu->arch.rec;
+	unsigned long base = rec->run->exit.ripas_base;
+	unsigned long top = rec->run->exit.ripas_top;
+	unsigned long ripas = rec->run->exit.ripas_value;
+
+	if (!realm_is_addr_protected(realm, base) ||
+	    !realm_is_addr_protected(realm, top - 1)) {
+		kvm_err("Invalid RIPAS_CHANGE for %#lx - %#lx, ripas: %#lx\n",
+			base, top, ripas);
+		return -EINVAL;
+	}
+
+	/* Exit to VMM, the actual RIPAS change is done on next entry */
+	kvm_prepare_memory_fault_exit(vcpu, base, top - base, false, false,
+				      ripas == RMI_RAM);
+
+	return 0;
+}
+
+static void update_arch_timer_irq_lines(struct kvm_vcpu *vcpu)
+{
+	struct realm_rec *rec = &vcpu->arch.rec;
+
+	__vcpu_sys_reg(vcpu, CNTV_CTL_EL0) = rec->run->exit.cntv_ctl;
+	__vcpu_sys_reg(vcpu, CNTV_CVAL_EL0) = rec->run->exit.cntv_cval;
+	__vcpu_sys_reg(vcpu, CNTP_CTL_EL0) = rec->run->exit.cntp_ctl;
+	__vcpu_sys_reg(vcpu, CNTP_CVAL_EL0) = rec->run->exit.cntp_cval;
+
+	kvm_realm_timers_update(vcpu);
+}
+
+/*
+ * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
+ * proper exit to userspace.
+ */
+int handle_rec_exit(struct kvm_vcpu *vcpu, int rec_run_ret)
+{
+	struct realm_rec *rec = &vcpu->arch.rec;
+	u8 esr_ec = ESR_ELx_EC(rec->run->exit.esr);
+	unsigned long status, index;
+
+	status = RMI_RETURN_STATUS(rec_run_ret);
+	index = RMI_RETURN_INDEX(rec_run_ret);
+
+	/*
+	 * If a PSCI_SYSTEM_OFF request raced with a vcpu executing, we might
+	 * see the following status code and index indicating an attempt to run
+	 * a REC when the RD state is SYSTEM_OFF.  In this case, we just need to
+	 * return to user space which can deal with the system event or will try
+	 * to run the KVM VCPU again, at which point we will no longer attempt
+	 * to enter the Realm because we will have a sleep request pending on
+	 * the VCPU as a result of KVM's PSCI handling.
+	 */
+	if (status == RMI_ERROR_REALM && index == 1) {
+		vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
+		return 0;
+	}
+
+	if (rec_run_ret)
+		return -ENXIO;
+
+	vcpu->arch.fault.esr_el2 = rec->run->exit.esr;
+	vcpu->arch.fault.far_el2 = rec->run->exit.far;
+	vcpu->arch.fault.hpfar_el2 = rec->run->exit.hpfar;
+
+	update_arch_timer_irq_lines(vcpu);
+
+	/* Reset the emulation flags for the next run of the REC */
+	rec->run->enter.flags = 0;
+
+	switch (rec->run->exit.exit_reason) {
+	case RMI_EXIT_SYNC:
+		return rec_exit_handlers[esr_ec](vcpu);
+	case RMI_EXIT_IRQ:
+	case RMI_EXIT_FIQ:
+		return 1;
+	case RMI_EXIT_PSCI:
+		return rec_exit_psci(vcpu);
+	case RMI_EXIT_RIPAS_CHANGE:
+		return rec_exit_ripas_change(vcpu);
+	}
+
+	kvm_pr_unimpl("Unsupported exit reason: %u\n",
+		      rec->run->exit.exit_reason);
+	vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+	return 0;
+}
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index e8ad04405ecd..22f0c74455af 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -842,6 +842,54 @@ void kvm_destroy_realm(struct kvm *kvm)
 	kvm_free_stage2_pgd(&kvm->arch.mmu);
 }
 
+static void kvm_complete_ripas_change(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+	struct realm_rec *rec = &vcpu->arch.rec;
+	unsigned long base = rec->run->exit.ripas_base;
+	unsigned long top = rec->run->exit.ripas_top;
+	unsigned long ripas = rec->run->exit.ripas_value;
+	unsigned long top_ipa;
+	int ret;
+
+	do {
+		kvm_mmu_topup_memory_cache(&vcpu->arch.mmu_page_cache,
+					   kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu));
+		write_lock(&kvm->mmu_lock);
+		ret = realm_set_ipa_state(vcpu, base, top, ripas, &top_ipa);
+		write_unlock(&kvm->mmu_lock);
+
+		if (WARN(ret && ret != -ENOMEM,
+			 "Unable to satisfy RIPAS_CHANGE for %#lx - %#lx, ripas: %#lx\n",
+			 base, top, ripas))
+			break;
+
+		base = top_ipa;
+	} while (top_ipa < top);
+}
+
+int kvm_rec_enter(struct kvm_vcpu *vcpu)
+{
+	struct realm_rec *rec = &vcpu->arch.rec;
+
+	switch (rec->run->exit.exit_reason) {
+	case RMI_EXIT_HOST_CALL:
+	case RMI_EXIT_PSCI:
+		for (int i = 0; i < REC_RUN_GPRS; i++)
+			rec->run->enter.gprs[i] = vcpu_get_reg(vcpu, i);
+		break;
+	case RMI_EXIT_RIPAS_CHANGE:
+		kvm_complete_ripas_change(vcpu);
+		break;
+	}
+
+	if (kvm_realm_state(vcpu->kvm) != REALM_STATE_ACTIVE)
+		return -EINVAL;
+
+	return rmi_rec_enter(virt_to_phys(rec->rec_page),
+			     virt_to_phys(rec->run));
+}
+
 static void free_rec_aux(struct page **aux_pages,
 			 unsigned int num_aux)
 {
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:43 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:43 +0000
Subject: [PATCH v6 18/43] KVM: arm64: Handle realm MMIO emulation
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-19-steven.price@arm.com>

MMIO emulation for a realm cannot be done directly with the VM's
registers as they are protected from the host. However, for emulatable
data aborts, the RMM uses GPRS[0] to provide the read/written value.
We can transfer this from/to the equivalent VCPU's register entry and
then depend on the generic MMIO handling code in KVM.

For a MMIO read, the value is placed in the shared RecExit structure
during kvm_handle_mmio_return() rather than in the VCPU's register
entry.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v5:
 * Inject SEA to the guest is an emulatable MMIO access triggers a data
   abort.
 * kvm_handle_mmio_return() - disable kvm_incr_pc() for a REC (as the PC
   isn't under the host's control) and move the REC_ENTER_EMULATED_MMIO
   flag setting to this location (as that tells the RMM to skip the
   instruction).
---
 arch/arm64/kvm/inject_fault.c |  4 +++-
 arch/arm64/kvm/mmio.c         | 16 ++++++++++++----
 arch/arm64/kvm/rme-exit.c     |  6 ++++++
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index a640e839848e..611867b81ac2 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -165,7 +165,9 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt, u32 addr)
  */
 void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr)
 {
-	if (vcpu_el1_is_32bit(vcpu))
+	if (unlikely(vcpu_is_rec(vcpu)))
+		vcpu->arch.rec.run->enter.flags |= REC_ENTER_INJECT_SEA;
+	else if (vcpu_el1_is_32bit(vcpu))
 		inject_abt32(vcpu, false, addr);
 	else
 		inject_abt64(vcpu, false, addr);
diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c
index ab365e839874..e0889f17c3f9 100644
--- a/arch/arm64/kvm/mmio.c
+++ b/arch/arm64/kvm/mmio.c
@@ -6,6 +6,7 @@
 
 #include <linux/kvm_host.h>
 #include <asm/kvm_emulate.h>
+#include <asm/rmi_smc.h>
 #include <trace/events/kvm.h>
 
 #include "trace.h"
@@ -136,14 +137,21 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu)
 		trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr,
 			       &data);
 		data = vcpu_data_host_to_guest(vcpu, data, len);
-		vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data);
+
+		if (vcpu_is_rec(vcpu))
+			vcpu->arch.rec.run->enter.gprs[0] = data;
+		else
+			vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data);
 	}
 
 	/*
 	 * The MMIO instruction is emulated and should not be re-executed
 	 * in the guest.
 	 */
-	kvm_incr_pc(vcpu);
+	if (vcpu_is_rec(vcpu))
+		vcpu->arch.rec.run->enter.flags |= REC_ENTER_EMULATED_MMIO;
+	else
+		kvm_incr_pc(vcpu);
 
 	return 1;
 }
@@ -162,14 +170,14 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 	 * No valid syndrome? Ask userspace for help if it has
 	 * volunteered to do so, and bail out otherwise.
 	 *
-	 * In the protected VM case, there isn't much userspace can do
+	 * In the protected/realm VM case, there isn't much userspace can do
 	 * though, so directly deliver an exception to the guest.
 	 */
 	if (!kvm_vcpu_dabt_isvalid(vcpu)) {
 		trace_kvm_mmio_nisv(*vcpu_pc(vcpu), kvm_vcpu_get_esr(vcpu),
 				    kvm_vcpu_get_hfar(vcpu), fault_ipa);
 
-		if (vcpu_is_protected(vcpu)) {
+		if (vcpu_is_protected(vcpu) || vcpu_is_rec(vcpu)) {
 			kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
 			return 1;
 		}
diff --git a/arch/arm64/kvm/rme-exit.c b/arch/arm64/kvm/rme-exit.c
index e532aa80e10d..8f0f9ab57f28 100644
--- a/arch/arm64/kvm/rme-exit.c
+++ b/arch/arm64/kvm/rme-exit.c
@@ -25,6 +25,12 @@ static int rec_exit_reason_notimpl(struct kvm_vcpu *vcpu)
 
 static int rec_exit_sync_dabt(struct kvm_vcpu *vcpu)
 {
+	struct realm_rec *rec = &vcpu->arch.rec;
+
+	if (kvm_vcpu_dabt_iswrite(vcpu) && kvm_vcpu_dabt_isvalid(vcpu))
+		vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu),
+			     rec->run->exit.gprs[0]);
+
 	return kvm_handle_guest_abort(vcpu);
 }
 
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:44 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:44 +0000
Subject: [PATCH v6 19/43] arm64: RME: Allow populating initial contents
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-20-steven.price@arm.com>

The VMM needs to populate the realm with some data before starting (e.g.
a kernel and initrd). This is measured by the RMM and used as part of
the attestation later on.

For now only 4k mappings are supported, future work may add support for
larger mappings.

Co-developed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v5:
 * Refactor to use PFNs rather than tracking struct page in
   realm_create_protected_data_page().
 * Pull changes from a later patch (in the v5 series) for accessing
   pages from a guest memfd.
 * Do the populate in chunks to avoid holding locks for too long and
   triggering RCU stall warnings.
---
 arch/arm64/kvm/rme.c | 243 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 243 insertions(+)

diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 22f0c74455af..d4561e368cd5 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/kvm_host.h>
+#include <linux/hugetlb.h>
 
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
@@ -545,6 +546,236 @@ void kvm_realm_unmap_range(struct kvm *kvm, unsigned long start, u64 size,
 		realm_unmap_private_range(kvm, start, end);
 }
 
+static int realm_create_protected_data_page(struct realm *realm,
+					    unsigned long ipa,
+					    kvm_pfn_t dst_pfn,
+					    kvm_pfn_t src_pfn,
+					    unsigned long flags)
+{
+	phys_addr_t dst_phys, src_phys;
+	int ret;
+
+	dst_phys = __pfn_to_phys(dst_pfn);
+	src_phys = __pfn_to_phys(src_pfn);
+
+	if (rmi_granule_delegate(dst_phys))
+		return -ENXIO;
+
+	ret = rmi_data_create(virt_to_phys(realm->rd), dst_phys, ipa, src_phys,
+			      flags);
+
+	if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+		/* Create missing RTTs and retry */
+		int level = RMI_RETURN_INDEX(ret);
+
+		ret = realm_create_rtt_levels(realm, ipa, level,
+					      RMM_RTT_MAX_LEVEL, NULL);
+		if (ret)
+			goto err;
+
+		ret = rmi_data_create(virt_to_phys(realm->rd), dst_phys, ipa,
+				      src_phys, flags);
+	}
+
+	if (!ret)
+		return 0;
+
+err:
+	if (WARN_ON(rmi_granule_undelegate(dst_phys))) {
+		/* Page can't be returned to NS world so is lost */
+		get_page(pfn_to_page(dst_pfn));
+	}
+	return -ENXIO;
+}
+
+static int fold_rtt(struct realm *realm, unsigned long addr, int level)
+{
+	phys_addr_t rtt_addr;
+	int ret;
+
+	ret = realm_rtt_fold(realm, addr, level + 1, &rtt_addr);
+	if (ret)
+		return ret;
+
+	free_delegated_granule(rtt_addr);
+
+	return 0;
+}
+
+static int populate_par_region(struct kvm *kvm,
+			       phys_addr_t ipa_base,
+			       phys_addr_t ipa_end,
+			       u32 flags)
+{
+	struct realm *realm = &kvm->arch.realm;
+	struct kvm_memory_slot *memslot;
+	gfn_t base_gfn, end_gfn;
+	int idx;
+	phys_addr_t ipa;
+	int ret = 0;
+	unsigned long data_flags = 0;
+
+	base_gfn = gpa_to_gfn(ipa_base);
+	end_gfn = gpa_to_gfn(ipa_end);
+
+	if (flags & KVM_ARM_RME_POPULATE_FLAGS_MEASURE)
+		data_flags = RMI_MEASURE_CONTENT;
+
+	idx = srcu_read_lock(&kvm->srcu);
+	memslot = gfn_to_memslot(kvm, base_gfn);
+	if (!memslot) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	/* We require the region to be contained within a single memslot */
+	if (memslot->base_gfn + memslot->npages < end_gfn) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!kvm_slot_can_be_private(memslot)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	write_lock(&kvm->mmu_lock);
+
+	ipa = ipa_base;
+	while (ipa < ipa_end) {
+		struct vm_area_struct *vma;
+		unsigned long map_size;
+		unsigned int vma_shift;
+		unsigned long offset;
+		unsigned long hva;
+		struct page *page;
+		bool writeable;
+		kvm_pfn_t pfn;
+		int level, i;
+
+		hva = gfn_to_hva_memslot(memslot, gpa_to_gfn(ipa));
+		vma = vma_lookup(current->mm, hva);
+		if (!vma) {
+			ret = -EFAULT;
+			break;
+		}
+
+		/* FIXME: Currently we only support 4k sized mappings */
+		vma_shift = PAGE_SHIFT;
+
+		map_size = 1 << vma_shift;
+
+		ipa = ALIGN_DOWN(ipa, map_size);
+
+		switch (map_size) {
+		case RMM_L2_BLOCK_SIZE:
+			level = 2;
+			break;
+		case PAGE_SIZE:
+			level = 3;
+			break;
+		default:
+			WARN_ONCE(1, "Unsupported vma_shift %d", vma_shift);
+			ret = -EFAULT;
+			break;
+		}
+
+		pfn = __kvm_faultin_pfn(memslot, gpa_to_gfn(ipa), FOLL_WRITE,
+					&writeable, &page);
+
+		if (is_error_pfn(pfn)) {
+			ret = -EFAULT;
+			break;
+		}
+
+		if (level < RMM_RTT_MAX_LEVEL) {
+			/*
+			 * A temporary RTT is needed during the map, precreate
+			 * it, however if there is an error (e.g. missing
+			 * parent tables) this will be handled in the
+			 * realm_create_protected_data_page() call.
+			 */
+			realm_create_rtt_levels(realm, ipa, level,
+						RMM_RTT_MAX_LEVEL, NULL);
+		}
+
+		for (offset = 0, i = 0; offset < map_size && !ret;
+		     offset += PAGE_SIZE, i++) {
+			phys_addr_t page_ipa = ipa + offset;
+			kvm_pfn_t priv_pfn;
+			struct page *gmem_page;
+			int order;
+
+			ret = kvm_gmem_get_pfn(kvm, memslot,
+					       page_ipa >> PAGE_SHIFT,
+					       &priv_pfn, &gmem_page, &order);
+			if (ret)
+				break;
+
+			ret = realm_create_protected_data_page(realm, page_ipa,
+							       priv_pfn,
+							       pfn + i,
+							       data_flags);
+		}
+
+		kvm_release_faultin_page(kvm, page, false, false);
+
+		if (ret)
+			break;
+
+		if (level == 2)
+			fold_rtt(realm, ipa, level);
+
+		ipa += map_size;
+	}
+
+	write_unlock(&kvm->mmu_lock);
+
+out:
+	srcu_read_unlock(&kvm->srcu, idx);
+	return ret;
+}
+
+static int kvm_populate_realm(struct kvm *kvm,
+			      struct kvm_cap_arm_rme_populate_realm_args *args)
+{
+	phys_addr_t ipa_base, ipa_end;
+
+	if (kvm_realm_state(kvm) != REALM_STATE_NEW)
+		return -EINVAL;
+
+	if (!IS_ALIGNED(args->populate_ipa_base, PAGE_SIZE) ||
+	    !IS_ALIGNED(args->populate_ipa_size, PAGE_SIZE))
+		return -EINVAL;
+
+	if (args->flags & ~RMI_MEASURE_CONTENT)
+		return -EINVAL;
+
+	ipa_base = args->populate_ipa_base;
+	ipa_end = ipa_base + args->populate_ipa_size;
+
+	if (ipa_end < ipa_base)
+		return -EINVAL;
+
+	/*
+	 * Perform the populate in parts to ensure locks are not held for too
+	 * long
+	 */
+	while (ipa_base < ipa_end) {
+		phys_addr_t end = min(ipa_end, ipa_base + SZ_2M);
+
+		int ret = populate_par_region(kvm, ipa_base, end,
+					      args->flags);
+
+		if (ret)
+			return ret;
+
+		ipa_base = end;
+	}
+
+	return 0;
+}
+
 int realm_set_ipa_state(struct kvm_vcpu *vcpu,
 			unsigned long start,
 			unsigned long end,
@@ -794,6 +1025,18 @@ int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
 		r = kvm_init_ipa_range_realm(kvm, &args);
 		break;
 	}
+	case KVM_CAP_ARM_RME_POPULATE_REALM: {
+		struct kvm_cap_arm_rme_populate_realm_args args;
+		void __user *argp = u64_to_user_ptr(cap->args[1]);
+
+		if (copy_from_user(&args, argp, sizeof(args))) {
+			r = -EFAULT;
+			break;
+		}
+
+		r = kvm_populate_realm(kvm, &args);
+		break;
+	}
 	default:
 		r = -EINVAL;
 		break;
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:45 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:45 +0000
Subject: [PATCH v6 20/43] arm64: RME: Runtime faulting of memory
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-21-steven.price@arm.com>

At runtime if the realm guest accesses memory which hasn't yet been
mapped then KVM needs to either populate the region or fault the guest.

For memory in the lower (protected) region of IPA a fresh page is
provided to the RMM which will zero the contents. For memory in the
upper (shared) region of IPA, the memory from the memslot is mapped
into the realm VM non secure.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v5:
 * Reduce use of struct page in preparation for supporting the RMM
   having a different page size to the host.
 * Handle a race when delegating a page where another CPU has faulted on
   a the same page (and already delegated the physical page) but not yet
   mapped it. In this case simply return to the guest to either use the
   mapping from the other CPU (or refault if the race is lost).
 * The changes to populate_par_region() are moved into the previous
   patch where they belong.
Changes since v4:
 * Code cleanup following review feedback.
 * Drop the PTE_SHARED bit when creating unprotected page table entries.
   This is now set by the RMM and the host has no control of it and the
   spec requires the bit to be set to zero.
Changes since v2:
 * Avoid leaking memory if failing to map it in the realm.
 * Correctly mask RTT based on LPA2 flag (see rtt_get_phys()).
 * Adapt to changes in previous patches.
---
 arch/arm64/include/asm/kvm_emulate.h |  10 ++
 arch/arm64/include/asm/kvm_rme.h     |  10 ++
 arch/arm64/kvm/mmu.c                 | 124 +++++++++++++++++++--
 arch/arm64/kvm/rme.c                 | 156 +++++++++++++++++++++++++++
 4 files changed, 293 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index ec2b6d9c9c07..b13e367b6972 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -720,6 +720,16 @@ static inline bool kvm_realm_is_created(struct kvm *kvm)
 	return kvm_is_realm(kvm) && kvm_realm_state(kvm) != REALM_STATE_NONE;
 }
 
+static inline gpa_t kvm_gpa_from_fault(struct kvm *kvm, phys_addr_t fault_ipa)
+{
+	if (kvm_is_realm(kvm)) {
+		struct realm *realm = &kvm->arch.realm;
+
+		return fault_ipa & ~BIT(realm->ia_bits - 1);
+	}
+	return fault_ipa;
+}
+
 static inline bool vcpu_is_rec(struct kvm_vcpu *vcpu)
 {
 	if (static_branch_unlikely(&kvm_rme_is_available))
diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 0410650cd545..158f77e24a26 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -99,6 +99,16 @@ void kvm_realm_unmap_range(struct kvm *kvm,
 			   unsigned long ipa,
 			   u64 size,
 			   bool unmap_private);
+int realm_map_protected(struct realm *realm,
+			unsigned long base_ipa,
+			kvm_pfn_t pfn,
+			unsigned long size,
+			struct kvm_mmu_memory_cache *memcache);
+int realm_map_non_secure(struct realm *realm,
+			 unsigned long ipa,
+			 kvm_pfn_t pfn,
+			 unsigned long size,
+			 struct kvm_mmu_memory_cache *memcache);
 int realm_set_ipa_state(struct kvm_vcpu *vcpu,
 			unsigned long addr, unsigned long end,
 			unsigned long ripas,
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index b100d4b3aa29..e88714903ce5 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -325,8 +325,13 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
 
 	lockdep_assert_held_write(&kvm->mmu_lock);
 	WARN_ON(size & ~PAGE_MASK);
-	WARN_ON(stage2_apply_range(mmu, start, end, kvm_pgtable_stage2_unmap,
-				   may_block));
+
+	if (kvm_is_realm(kvm))
+		kvm_realm_unmap_range(kvm, start, size, !only_shared);
+	else
+		WARN_ON(stage2_apply_range(mmu, start, end,
+					   kvm_pgtable_stage2_unmap,
+					   may_block));
 }
 
 void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
@@ -346,7 +351,10 @@ static void stage2_flush_memslot(struct kvm *kvm,
 	phys_addr_t addr = memslot->base_gfn << PAGE_SHIFT;
 	phys_addr_t end = addr + PAGE_SIZE * memslot->npages;
 
-	kvm_stage2_flush_range(&kvm->arch.mmu, addr, end);
+	if (kvm_is_realm(kvm))
+		kvm_realm_unmap_range(kvm, addr, end - addr, false);
+	else
+		kvm_stage2_flush_range(&kvm->arch.mmu, addr, end);
 }
 
 /**
@@ -1037,6 +1045,10 @@ void stage2_unmap_vm(struct kvm *kvm)
 	struct kvm_memory_slot *memslot;
 	int idx, bkt;
 
+	/* For realms this is handled by the RMM so nothing to do here */
+	if (kvm_is_realm(kvm))
+		return;
+
 	idx = srcu_read_lock(&kvm->srcu);
 	mmap_read_lock(current->mm);
 	write_lock(&kvm->mmu_lock);
@@ -1062,6 +1074,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
 	if (kvm_is_realm(kvm) &&
 	    (kvm_realm_state(kvm) != REALM_STATE_DEAD &&
 	     kvm_realm_state(kvm) != REALM_STATE_NONE)) {
+		kvm_stage2_unmap_range(mmu, 0, (~0ULL) & PAGE_MASK, false);
 		write_unlock(&kvm->mmu_lock);
 		kvm_realm_destroy_rtts(kvm, pgt->ia_bits);
 
@@ -1446,6 +1459,76 @@ static bool kvm_vma_mte_allowed(struct vm_area_struct *vma)
 	return vma->vm_flags & VM_MTE_ALLOWED;
 }
 
+static int realm_map_ipa(struct kvm *kvm, phys_addr_t ipa,
+			 kvm_pfn_t pfn, unsigned long map_size,
+			 enum kvm_pgtable_prot prot,
+			 struct kvm_mmu_memory_cache *memcache)
+{
+	struct realm *realm = &kvm->arch.realm;
+
+	if (WARN_ON(!(prot & KVM_PGTABLE_PROT_W)))
+		return -EFAULT;
+
+	if (!realm_is_addr_protected(realm, ipa))
+		return realm_map_non_secure(realm, ipa, pfn, map_size,
+					    memcache);
+
+	return realm_map_protected(realm, ipa, pfn, map_size, memcache);
+}
+
+static int private_memslot_fault(struct kvm_vcpu *vcpu,
+				 phys_addr_t fault_ipa,
+				 struct kvm_memory_slot *memslot)
+{
+	struct kvm *kvm = vcpu->kvm;
+	gpa_t gpa = kvm_gpa_from_fault(kvm, fault_ipa);
+	gfn_t gfn = gpa >> PAGE_SHIFT;
+	bool priv_exists = kvm_mem_is_private(kvm, gfn);
+	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
+	struct page *page;
+	kvm_pfn_t pfn;
+	int ret;
+	/*
+	 * For Realms, the shared address is an alias of the private GPA with
+	 * the top bit set. Thus is the fault address matches the GPA then it
+	 * is the private alias.
+	 */
+	bool is_priv_gfn = (gpa == fault_ipa);
+
+	if (priv_exists != is_priv_gfn) {
+		kvm_prepare_memory_fault_exit(vcpu,
+					      gpa,
+					      PAGE_SIZE,
+					      kvm_is_write_fault(vcpu),
+					      false, is_priv_gfn);
+
+		return -EFAULT;
+	}
+
+	if (!is_priv_gfn) {
+		/* Not a private mapping, handling normally */
+		return -EINVAL;
+	}
+
+	ret = kvm_mmu_topup_memory_cache(memcache,
+					 kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu));
+	if (ret)
+		return ret;
+
+	ret = kvm_gmem_get_pfn(kvm, memslot, gfn, &pfn, &page, NULL);
+	if (ret)
+		return ret;
+
+	/* FIXME: Should be able to use bigger than PAGE_SIZE mappings */
+	ret = realm_map_ipa(kvm, fault_ipa, pfn, PAGE_SIZE, KVM_PGTABLE_PROT_W,
+			    memcache);
+	if (!ret)
+		return 1; /* Handled */
+
+	put_page(page);
+	return ret;
+}
+
 static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 			  struct kvm_s2_trans *nested,
 			  struct kvm_memory_slot *memslot, unsigned long hva,
@@ -1472,6 +1555,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	if (fault_is_perm)
 		fault_granule = kvm_vcpu_trap_get_perm_fault_granule(vcpu);
 	write_fault = kvm_is_write_fault(vcpu);
+
+	/*
+	 * Realms cannot map protected pages read-only
+	 * FIXME: It should be possible to map unprotected pages read-only
+	 */
+	if (vcpu_is_rec(vcpu))
+		write_fault = true;
+
 	exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu);
 	VM_BUG_ON(write_fault && exec_fault);
 
@@ -1579,7 +1670,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		ipa &= ~(vma_pagesize - 1);
 	}
 
-	gfn = ipa >> PAGE_SHIFT;
+	gfn = kvm_gpa_from_fault(kvm, ipa) >> PAGE_SHIFT;
 	mte_allowed = kvm_vma_mte_allowed(vma);
 
 	vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED;
@@ -1660,7 +1751,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * If we are not forced to use page mapping, check if we are
 	 * backed by a THP and thus use block mapping if possible.
 	 */
-	if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) {
+	/* FIXME: We shouldn't need to disable this for realms */
+	if (vma_pagesize == PAGE_SIZE && !(force_pte || device || kvm_is_realm(kvm))) {
 		if (fault_is_perm && fault_granule > PAGE_SIZE)
 			vma_pagesize = fault_granule;
 		else
@@ -1712,6 +1804,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		 */
 		prot &= ~KVM_NV_GUEST_MAP_SZ;
 		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot);
+	} else if (kvm_is_realm(kvm)) {
+		ret = realm_map_ipa(kvm, fault_ipa, pfn, vma_pagesize,
+				    prot, memcache);
 	} else {
 		ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
 					     __pfn_to_phys(pfn), prot,
@@ -1854,8 +1949,15 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		nested = &nested_trans;
 	}
 
-	gfn = ipa >> PAGE_SHIFT;
+	gfn = kvm_gpa_from_fault(vcpu->kvm, ipa) >> PAGE_SHIFT;
 	memslot = gfn_to_memslot(vcpu->kvm, gfn);
+
+	if (kvm_slot_can_be_private(memslot)) {
+		ret = private_memslot_fault(vcpu, ipa, memslot);
+		if (ret != -EINVAL)
+			goto out;
+	}
+
 	hva = gfn_to_hva_memslot_prot(memslot, gfn, &writable);
 	write_fault = kvm_is_write_fault(vcpu);
 	if (kvm_is_error_hva(hva) || (write_fault && !writable)) {
@@ -1899,7 +2001,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		 * of the page size.
 		 */
 		ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
-		ret = io_mem_abort(vcpu, ipa);
+		ret = io_mem_abort(vcpu, kvm_gpa_from_fault(vcpu->kvm, ipa));
 		goto out_unlock;
 	}
 
@@ -1947,6 +2049,10 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
+	/* We don't support aging for Realms */
+	if (kvm_is_realm(kvm))
+		return true;
+
 	return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, true);
@@ -1963,6 +2069,10 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
+	/* We don't support aging for Realms */
+	if (kvm_is_realm(kvm))
+		return true;
+
 	return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, false);
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index d4561e368cd5..146ef598a581 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -602,6 +602,162 @@ static int fold_rtt(struct realm *realm, unsigned long addr, int level)
 	return 0;
 }
 
+int realm_map_protected(struct realm *realm,
+			unsigned long ipa,
+			kvm_pfn_t pfn,
+			unsigned long map_size,
+			struct kvm_mmu_memory_cache *memcache)
+{
+	phys_addr_t phys = __pfn_to_phys(pfn);
+	phys_addr_t rd = virt_to_phys(realm->rd);
+	unsigned long base_ipa = ipa;
+	unsigned long size;
+	int map_level;
+	int ret = 0;
+
+	if (WARN_ON(!IS_ALIGNED(ipa, map_size)))
+		return -EINVAL;
+
+	switch (map_size) {
+	case PAGE_SIZE:
+		map_level = 3;
+		break;
+	case RMM_L2_BLOCK_SIZE:
+		map_level = 2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (map_level < RMM_RTT_MAX_LEVEL) {
+		/*
+		 * A temporary RTT is needed during the map, precreate it,
+		 * however if there is an error (e.g. missing parent tables)
+		 * this will be handled below.
+		 */
+		realm_create_rtt_levels(realm, ipa, map_level,
+					RMM_RTT_MAX_LEVEL, memcache);
+	}
+
+	for (size = 0; size < map_size; size += PAGE_SIZE) {
+		if (rmi_granule_delegate(phys)) {
+			/*
+			 * It's likely we raced with another VCPU on the same
+			 * fault. Assume the other VCPU has handled the fault
+			 * and return to the guest.
+			 */
+			return 0;
+		}
+
+		ret = rmi_data_create_unknown(rd, phys, ipa);
+
+		if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+			/* Create missing RTTs and retry */
+			int level = RMI_RETURN_INDEX(ret);
+
+			ret = realm_create_rtt_levels(realm, ipa, level,
+						      RMM_RTT_MAX_LEVEL,
+						      memcache);
+			WARN_ON(ret);
+			if (ret)
+				goto err_undelegate;
+
+			ret = rmi_data_create_unknown(rd, phys, ipa);
+		}
+		WARN_ON(ret);
+
+		if (ret)
+			goto err_undelegate;
+
+		phys += PAGE_SIZE;
+		ipa += PAGE_SIZE;
+	}
+
+	if (map_size == RMM_L2_BLOCK_SIZE)
+		ret = fold_rtt(realm, base_ipa, map_level);
+	if (WARN_ON(ret))
+		goto err;
+
+	return 0;
+
+err_undelegate:
+	if (WARN_ON(rmi_granule_undelegate(phys))) {
+		/* Page can't be returned to NS world so is lost */
+		get_page(phys_to_page(phys));
+	}
+err:
+	while (size > 0) {
+		unsigned long data, top;
+
+		phys -= PAGE_SIZE;
+		size -= PAGE_SIZE;
+		ipa -= PAGE_SIZE;
+
+		WARN_ON(rmi_data_destroy(rd, ipa, &data, &top));
+
+		if (WARN_ON(rmi_granule_undelegate(phys))) {
+			/* Page can't be returned to NS world so is lost */
+			get_page(phys_to_page(phys));
+		}
+	}
+	return -ENXIO;
+}
+
+int realm_map_non_secure(struct realm *realm,
+			 unsigned long ipa,
+			 kvm_pfn_t pfn,
+			 unsigned long map_size,
+			 struct kvm_mmu_memory_cache *memcache)
+{
+	phys_addr_t rd = virt_to_phys(realm->rd);
+	int map_level;
+	int ret = 0;
+	unsigned long desc = __pfn_to_phys(pfn) |
+			     PTE_S2_MEMATTR(MT_S2_FWB_NORMAL) |
+			     /* FIXME: Read+Write permissions for now */
+			     (3 << 6);
+
+	if (WARN_ON(!IS_ALIGNED(ipa, map_size)))
+		return -EINVAL;
+
+	switch (map_size) {
+	case PAGE_SIZE:
+		map_level = 3;
+		break;
+	case RMM_L2_BLOCK_SIZE:
+		map_level = 2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = rmi_rtt_map_unprotected(rd, ipa, map_level, desc);
+
+	if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+		/* Create missing RTTs and retry */
+		int level = RMI_RETURN_INDEX(ret);
+
+		ret = realm_create_rtt_levels(realm, ipa, level, map_level,
+					      memcache);
+		if (WARN_ON(ret))
+			return -ENXIO;
+
+		ret = rmi_rtt_map_unprotected(rd, ipa, map_level, desc);
+	}
+	/*
+	 * RMI_ERROR_RTT can be reported for two reasons: either the RTT tables
+	 * are not there, or there is an RTTE already present for the address.
+	 * The call to realm_create_rtt_levels() above handles the first case,
+	 * and in the second case this indicates that another thread has
+	 * already populated the RTTE for us, so we can ignore the error and
+	 * continue.
+	 */
+	if (WARN_ON(ret && RMI_RETURN_STATUS(ret) != RMI_ERROR_RTT))
+		return -ENXIO;
+
+	return 0;
+}
+
 static int populate_par_region(struct kvm *kvm,
 			       phys_addr_t ipa_base,
 			       phys_addr_t ipa_end,
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:46 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:46 +0000
Subject: [PATCH v6 21/43] KVM: arm64: Handle realm VCPU load
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-22-steven.price@arm.com>

When loading a realm VCPU much of the work is handled by the RMM so only
some of the actions are required. Rearrange kvm_arch_vcpu_load()
slightly so we can bail out early for a realm guest.

Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/arm.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 6e83b2e3a6cf..f588b528c3f9 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -656,10 +656,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 	kvm_vgic_load(vcpu);
 	kvm_timer_vcpu_load(vcpu);
-	if (has_vhe())
-		kvm_vcpu_load_vhe(vcpu);
-	kvm_arch_vcpu_load_fp(vcpu);
-	kvm_vcpu_pmu_restore_guest(vcpu);
 	if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
 		kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
 
@@ -675,6 +671,15 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 	vcpu_set_pauth_traps(vcpu);
 
+	/* No additional state needs to be loaded on Realmed VMs */
+	if (vcpu_is_rec(vcpu))
+		return;
+
+	if (has_vhe())
+		kvm_vcpu_load_vhe(vcpu);
+	kvm_arch_vcpu_load_fp(vcpu);
+	kvm_vcpu_pmu_restore_guest(vcpu);
+
 	kvm_arch_vcpu_load_debug_state_flags(vcpu);
 
 	if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus))
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:47 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:47 +0000
Subject: [PATCH v6 22/43] KVM: arm64: Validate register access for a Realm VM
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-23-steven.price@arm.com>

The RMM only allows setting the GPRS (x0-x30) and PC for a realm
guest. Check this in kvm_arm_set_reg() so that the VMM can receive a
suitable error return if other registers are accessed.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v5:
 * Upper GPRS can be set as part of a HOST_CALL return, so fix up the
   test to allow them.
---
 arch/arm64/kvm/guest.c | 43 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 12dad841f2a5..1ee2fe072f1a 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -73,6 +73,24 @@ static u64 core_reg_offset_from_id(u64 id)
 	return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE);
 }
 
+static bool kvm_realm_validate_core_reg(u64 off)
+{
+	/*
+	 * Note that GPRs can only sometimes be controlled by the VMM.
+	 * For PSCI only X0-X6 are used, higher registers are ignored (restored
+	 * from the REC).
+	 * For HOST_CALL all of X0-X30 are copied to the RsiHostCall structure.
+	 * For emulated MMIO X0 is always used.
+	 */
+	switch (off) {
+	case KVM_REG_ARM_CORE_REG(regs.regs[0]) ...
+	     KVM_REG_ARM_CORE_REG(regs.regs[30]):
+	case KVM_REG_ARM_CORE_REG(regs.pc):
+		return true;
+	}
+	return false;
+}
+
 static int core_reg_size_from_offset(const struct kvm_vcpu *vcpu, u64 off)
 {
 	int size;
@@ -115,6 +133,9 @@ static int core_reg_size_from_offset(const struct kvm_vcpu *vcpu, u64 off)
 	if (vcpu_has_sve(vcpu) && core_reg_offset_is_vreg(off))
 		return -EINVAL;
 
+	if (kvm_is_realm(vcpu->kvm) && !kvm_realm_validate_core_reg(off))
+		return -EPERM;
+
 	return size;
 }
 
@@ -783,12 +804,34 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	return kvm_arm_sys_reg_get_reg(vcpu, reg);
 }
 
+/*
+ * The RMI ABI only enables setting some GPRs and PC. The selection of GPRs
+ * that are available depends on the Realm state and the reason for the last
+ * exit.  All other registers are reset to architectural or otherwise defined
+ * reset values by the RMM, except for a few configuration fields that
+ * correspond to Realm parameters.
+ */
+static bool validate_realm_set_reg(struct kvm_vcpu *vcpu,
+				   const struct kvm_one_reg *reg)
+{
+	if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) {
+		u64 off = core_reg_offset_from_id(reg->id);
+
+		return kvm_realm_validate_core_reg(off);
+	}
+
+	return false;
+}
+
 int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 {
 	/* We currently use nothing arch-specific in upper 32 bits */
 	if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM64 >> 32)
 		return -EINVAL;
 
+	if (kvm_is_realm(vcpu->kvm) && !validate_realm_set_reg(vcpu, reg))
+		return -EINVAL;
+
 	switch (reg->id & KVM_REG_ARM_COPROC_MASK) {
 	case KVM_REG_ARM_CORE:	return set_core_reg(vcpu, reg);
 	case KVM_REG_ARM_FW:
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:48 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:48 +0000
Subject: [PATCH v6 23/43] KVM: arm64: Handle Realm PSCI requests
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-24-steven.price@arm.com>

The RMM needs to be informed of the target REC when a PSCI call is made
with an MPIDR argument. Expose an ioctl to the userspace in case the PSCI
is handled by it.

Co-developed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/include/asm/kvm_rme.h |  3 +++
 arch/arm64/kvm/arm.c             | 25 +++++++++++++++++++++++++
 arch/arm64/kvm/psci.c            | 29 +++++++++++++++++++++++++++++
 arch/arm64/kvm/rme.c             | 15 +++++++++++++++
 4 files changed, 72 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 158f77e24a26..90a4537ad38d 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -113,6 +113,9 @@ int realm_set_ipa_state(struct kvm_vcpu *vcpu,
 			unsigned long addr, unsigned long end,
 			unsigned long ripas,
 			unsigned long *top_ipa);
+int realm_psci_complete(struct kvm_vcpu *calling,
+			struct kvm_vcpu *target,
+			unsigned long status);
 
 #define RMM_RTT_BLOCK_LEVEL	2
 #define RMM_RTT_MAX_LEVEL	3
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index f588b528c3f9..eff1a4ec892b 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1745,6 +1745,22 @@ static int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
 	return __kvm_arm_vcpu_set_events(vcpu, events);
 }
 
+static int kvm_arm_vcpu_rmm_psci_complete(struct kvm_vcpu *vcpu,
+					  struct kvm_arm_rmm_psci_complete *arg)
+{
+	struct kvm_vcpu *target = kvm_mpidr_to_vcpu(vcpu->kvm, arg->target_mpidr);
+
+	if (!target)
+		return -EINVAL;
+
+	/*
+	 * RMM v1.0 only supports PSCI_RET_SUCCESS or PSCI_RET_DENIED
+	 * for the status. But, let us leave it to the RMM to filter
+	 * for making this future proof.
+	 */
+	return realm_psci_complete(vcpu, target, arg->psci_status);
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
 			 unsigned int ioctl, unsigned long arg)
 {
@@ -1867,6 +1883,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 
 		return kvm_arm_vcpu_finalize(vcpu, what);
 	}
+	case KVM_ARM_VCPU_RMM_PSCI_COMPLETE: {
+		struct kvm_arm_rmm_psci_complete req;
+
+		if (!kvm_is_realm(vcpu->kvm))
+			return -EINVAL;
+		if (copy_from_user(&req, argp, sizeof(req)))
+			return -EFAULT;
+		return kvm_arm_vcpu_rmm_psci_complete(vcpu, &req);
+	}
 	default:
 		r = -EINVAL;
 	}
diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c
index 3b5dbe9a0a0e..9dc161abc30c 100644
--- a/arch/arm64/kvm/psci.c
+++ b/arch/arm64/kvm/psci.c
@@ -103,6 +103,12 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
 
 	reset_state->reset = true;
 	kvm_make_request(KVM_REQ_VCPU_RESET, vcpu);
+	/*
+	 * Make sure we issue PSCI_COMPLETE before the VCPU can be
+	 * scheduled.
+	 */
+	if (vcpu_is_rec(vcpu))
+		realm_psci_complete(source_vcpu, vcpu, PSCI_RET_SUCCESS);
 
 	/*
 	 * Make sure the reset request is observed if the RUNNABLE mp_state is
@@ -115,6 +121,10 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
 
 out_unlock:
 	spin_unlock(&vcpu->arch.mp_state_lock);
+	if (vcpu_is_rec(vcpu) && ret != PSCI_RET_SUCCESS)
+		realm_psci_complete(source_vcpu, vcpu,
+				    ret == PSCI_RET_ALREADY_ON ?
+				    PSCI_RET_SUCCESS : PSCI_RET_DENIED);
 	return ret;
 }
 
@@ -142,6 +152,25 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
 	/* Ignore other bits of target affinity */
 	target_affinity &= target_affinity_mask;
 
+	if (vcpu_is_rec(vcpu)) {
+		struct kvm_vcpu *target_vcpu;
+
+		/* RMM supports only zero affinity level */
+		if (lowest_affinity_level != 0)
+			return PSCI_RET_INVALID_PARAMS;
+
+		target_vcpu = kvm_mpidr_to_vcpu(kvm, target_affinity);
+		if (!target_vcpu)
+			return PSCI_RET_INVALID_PARAMS;
+
+		/*
+		 * Provide the references of running and target RECs to the RMM
+		 * so that the RMM can complete the PSCI request.
+		 */
+		realm_psci_complete(vcpu, target_vcpu, PSCI_RET_SUCCESS);
+		return PSCI_RET_SUCCESS;
+	}
+
 	/*
 	 * If one or more VCPU matching target affinity are running
 	 * then ON else OFF
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 146ef598a581..5831d379760a 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -118,6 +118,21 @@ static void free_delegated_granule(phys_addr_t phys)
 	free_page((unsigned long)phys_to_virt(phys));
 }
 
+int realm_psci_complete(struct kvm_vcpu *calling, struct kvm_vcpu *target,
+			unsigned long status)
+{
+	int ret;
+
+	ret = rmi_psci_complete(virt_to_phys(calling->arch.rec.rec_page),
+				virt_to_phys(target->arch.rec.rec_page),
+				status);
+
+	if (ret)
+		return -EINVAL;
+
+	return 0;
+}
+
 static int realm_rtt_create(struct realm *realm,
 			    unsigned long addr,
 			    int level,
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:49 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:49 +0000
Subject: [PATCH v6 24/43] KVM: arm64: WARN on injected undef exceptions
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-25-steven.price@arm.com>

The RMM doesn't allow injection of a undefined exception into a realm
guest. Add a WARN to catch if this ever happens.

Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/inject_fault.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index 611867b81ac2..705463058ce0 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -226,6 +226,8 @@ void kvm_inject_size_fault(struct kvm_vcpu *vcpu)
  */
 void kvm_inject_undefined(struct kvm_vcpu *vcpu)
 {
+	if (vcpu_is_rec(vcpu))
+		WARN(1, "Cannot inject undefined exception into REC. Continuing with unknown behaviour");
 	if (vcpu_el1_is_32bit(vcpu))
 		inject_undef32(vcpu);
 	else
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:50 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:50 +0000
Subject: [PATCH v6 25/43] arm64: Don't expose stolen time for realm guests
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-26-steven.price@arm.com>

It doesn't make much sense as a realm guest wouldn't want to trust the
host. It will also need some extra work to ensure that KVM will only
attempt to write into a shared memory region. So for now just disable
it.

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/arm.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index eff1a4ec892b..134acb4ee26f 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -432,7 +432,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		r = system_supports_mte();
 		break;
 	case KVM_CAP_STEAL_TIME:
-		r = kvm_arm_pvtime_supported();
+		if (kvm_is_realm(kvm))
+			r = 0;
+		else
+			r = kvm_arm_pvtime_supported();
 		break;
 	case KVM_CAP_ARM_EL1_32BIT:
 		r = cpus_have_final_cap(ARM64_HAS_32BIT_EL1);
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:51 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:51 +0000
Subject: [PATCH v6 26/43] arm64: rme: allow userspace to inject aborts
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-27-steven.price@arm.com>

From: Joey Gouly <joey.gouly at arm.com>

Extend KVM_SET_VCPU_EVENTS to support realms, where KVM cannot set the
system registers, and the RMM must perform it on next REC entry.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 Documentation/virt/kvm/api.rst |  2 ++
 arch/arm64/kvm/guest.c         | 24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index df4679415a4c..1c622d8ca602 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -1291,6 +1291,8 @@ User space may need to inject several types of events to the guest.
 Set the pending SError exception state for this VCPU. It is not possible to
 'cancel' an Serror that has been made pending.
 
+User space cannot inject SErrors into Realms.
+
 If the guest performed an access to I/O memory which could not be handled by
 userspace, for example because of missing instruction syndrome decode
 information or because there is no device mapped at the accessed IPA, then
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 1ee2fe072f1a..920e0fd73698 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -883,6 +883,30 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
 	bool has_esr = events->exception.serror_has_esr;
 	bool ext_dabt_pending = events->exception.ext_dabt_pending;
 
+	if (vcpu_is_rec(vcpu)) {
+		/* Cannot inject SError into a Realm. */
+		if (serror_pending)
+			return -EINVAL;
+
+		/*
+		 * If a data abort is pending, set the flag and let the RMM
+		 * inject an SEA when the REC is scheduled to be run.
+		 */
+		if (ext_dabt_pending) {
+			/*
+			 * Can only inject SEA into a Realm if the previous exit
+			 * was due to a data abort of an Unprotected IPA.
+			 */
+			if (!(vcpu->arch.rec.run->enter.flags & REC_ENTER_EMULATED_MMIO))
+				return -EINVAL;
+
+			vcpu->arch.rec.run->enter.flags &= ~REC_ENTER_EMULATED_MMIO;
+			vcpu->arch.rec.run->enter.flags |= REC_ENTER_INJECT_SEA;
+		}
+
+		return 0;
+	}
+
 	if (serror_pending && has_esr) {
 		if (!cpus_have_final_cap(ARM64_HAS_RAS_EXTN))
 			return -EINVAL;
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:52 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:52 +0000
Subject: [PATCH v6 27/43] arm64: rme: support RSI_HOST_CALL
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-28-steven.price@arm.com>

From: Joey Gouly <joey.gouly at arm.com>

Forward RSI_HOST_CALLS to KVM's HVC handler.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v4:
 * Setting GPRS is now done by kvm_rec_enter() rather than
   rec_exit_host_call() (see previous patch - arm64: RME: Handle realm
   enter/exit). This fixes a bug where the registers set by user space
   were being ignored.
---
 arch/arm64/kvm/rme-exit.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/kvm/rme-exit.c b/arch/arm64/kvm/rme-exit.c
index 8f0f9ab57f28..b2a367474d74 100644
--- a/arch/arm64/kvm/rme-exit.c
+++ b/arch/arm64/kvm/rme-exit.c
@@ -103,6 +103,26 @@ static int rec_exit_ripas_change(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+static int rec_exit_host_call(struct kvm_vcpu *vcpu)
+{
+	int ret, i;
+	struct realm_rec *rec = &vcpu->arch.rec;
+
+	vcpu->stat.hvc_exit_stat++;
+
+	for (i = 0; i < REC_RUN_GPRS; i++)
+		vcpu_set_reg(vcpu, i, rec->run->exit.gprs[i]);
+
+	ret = kvm_smccc_call_handler(vcpu);
+
+	if (ret < 0) {
+		vcpu_set_reg(vcpu, 0, ~0UL);
+		ret = 1;
+	}
+
+	return ret;
+}
+
 static void update_arch_timer_irq_lines(struct kvm_vcpu *vcpu)
 {
 	struct realm_rec *rec = &vcpu->arch.rec;
@@ -164,6 +184,8 @@ int handle_rec_exit(struct kvm_vcpu *vcpu, int rec_run_ret)
 		return rec_exit_psci(vcpu);
 	case RMI_EXIT_RIPAS_CHANGE:
 		return rec_exit_ripas_change(vcpu);
+	case RMI_EXIT_HOST_CALL:
+		return rec_exit_host_call(vcpu);
 	}
 
 	kvm_pr_unimpl("Unsupported exit reason: %u\n",
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:53 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:53 +0000
Subject: [PATCH v6 28/43] arm64: rme: Allow checking SVE on VM instance
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-29-steven.price@arm.com>

From: Suzuki K Poulose <suzuki.poulose at arm.com>

Given we have different types of VMs supported, check the
support for SVE for the given instance of the VM to accurately
report the status.

Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/include/asm/kvm_rme.h | 2 ++
 arch/arm64/kvm/arm.c             | 5 ++++-
 arch/arm64/kvm/rme.c             | 5 +++++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 90a4537ad38d..0d89ab1645c1 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -85,6 +85,8 @@ void kvm_init_rme(void);
 u32 kvm_realm_ipa_limit(void);
 u32 kvm_realm_vgic_nr_lr(void);
 
+bool kvm_rme_supports_sve(void);
+
 int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap);
 int kvm_init_realm_vm(struct kvm *kvm);
 void kvm_destroy_realm(struct kvm *kvm);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 134acb4ee26f..6f7f96ab781d 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -456,7 +456,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		r = get_kvm_ipa_limit();
 		break;
 	case KVM_CAP_ARM_SVE:
-		r = system_supports_sve();
+		if (kvm_is_realm(kvm))
+			r = kvm_rme_supports_sve();
+		else
+			r = system_supports_sve();
 		break;
 	case KVM_CAP_ARM_PTRAUTH_ADDRESS:
 	case KVM_CAP_ARM_PTRAUTH_GENERIC:
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 5831d379760a..27a479feb907 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -20,6 +20,11 @@ static bool rme_supports(unsigned long feature)
 	return !!u64_get_bits(rmm_feat_reg0, feature);
 }
 
+bool kvm_rme_supports_sve(void)
+{
+	return rme_supports(RMI_FEATURE_REGISTER_0_SVE_EN);
+}
+
 static int rmi_check_version(void)
 {
 	struct arm_smccc_res res;
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:54 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:54 +0000
Subject: [PATCH v6 29/43] arm64: RME: Always use 4k pages for realms
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-30-steven.price@arm.com>

Always split up huge pages to avoid problems managing huge pages. There
are two issues currently:

1. The uABI for the VMM allows populating memory on 4k boundaries even
   if the underlying allocator (e.g. hugetlbfs) is using a larger page
   size. Using a memfd for private allocations will push this issue onto
   the VMM as it will need to respect the granularity of the allocator.

2. The guest is able to request arbitrary ranges to be remapped as
   shared. Again with a memfd approach it will be up to the VMM to deal
   with the complexity and either overmap (need the huge mapping and add
   an additional 'overlapping' shared mapping) or reject the request as
   invalid due to the use of a huge page allocator.

For now just break everything down to 4k pages in the RMM controlled
stage 2.

Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/mmu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index e88714903ce5..9ede143ccef1 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1603,6 +1603,10 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	if (logging_active) {
 		force_pte = true;
 		vma_shift = PAGE_SHIFT;
+	} else if (kvm_is_realm(kvm)) {
+		// Force PTE level mappings for realms
+		force_pte = true;
+		vma_shift = PAGE_SHIFT;
 	} else {
 		vma_shift = get_vma_page_shift(vma, hva);
 	}
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:55 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:55 +0000
Subject: [PATCH v6 30/43] arm64: rme: Prevent Device mappings for Realms
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-31-steven.price@arm.com>

Physical device assignment is not yet supported by the RMM, so it
doesn't make much sense to allow device mappings within the realm.
Prevent them when the guest is a realm.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes from v5:
 * Also prevent accesses in user_mem_abort()
---
 arch/arm64/kvm/mmu.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 9ede143ccef1..cef7c3dcbf99 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1149,6 +1149,10 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 	if (is_protected_kvm_enabled())
 		return -EPERM;
 
+	/* We don't support mapping special pages into a Realm */
+	if (kvm_is_realm(kvm))
+		return -EINVAL;
+
 	size += offset_in_page(guest_ipa);
 	guest_ipa &= PAGE_MASK;
 
@@ -1725,6 +1729,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	if (exec_fault && device)
 		return -ENOEXEC;
 
+	/*
+	 * Don't allow device accesses to protected memory as we don't (yet)
+	 * support protected devices.
+	 */
+	if (device && kvm_is_realm(kvm) &&
+	    kvm_gpa_from_fault(kvm, fault_ipa) == fault_ipa)
+		return -EINVAL;
+
 	/*
 	 * Potentially reduce shadow S2 permissions to match the guest's own
 	 * S2. For exec faults, we'd only reach this point if the guest
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:56 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:56 +0000
Subject: [PATCH v6 31/43] arm_pmu: Provide a mechanism for disabling the physical IRQ
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-32-steven.price@arm.com>

Arm CCA assigns the physical PMU device to the guest running in realm
world, however the IRQs are routed via the host. To enter a realm guest
while a PMU IRQ is pending it is necessary to block the physical IRQ to
prevent an immediate exit. Provide a mechanism in the PMU driver for KVM
to control the physical IRQ.

Signed-off-by: Steven Price <steven.price at arm.com>
---
v3: Add a dummy function for the !CONFIG_ARM_PMU case.
---
 drivers/perf/arm_pmu.c       | 15 +++++++++++++++
 include/linux/perf/arm_pmu.h |  5 +++++
 2 files changed, 20 insertions(+)

diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 398cce3d76fc..2cdcdda8f638 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -735,6 +735,21 @@ static int arm_perf_teardown_cpu(unsigned int cpu, struct hlist_node *node)
 	return 0;
 }
 
+void arm_pmu_set_phys_irq(bool enable)
+{
+	int cpu = get_cpu();
+	struct arm_pmu *pmu = per_cpu(cpu_armpmu, cpu);
+	int irq;
+
+	irq = armpmu_get_cpu_irq(pmu, cpu);
+	if (irq && !enable)
+		per_cpu(cpu_irq_ops, cpu)->disable_pmuirq(irq);
+	else if (irq && enable)
+		per_cpu(cpu_irq_ops, cpu)->enable_pmuirq(irq);
+
+	put_cpu();
+}
+
 #ifdef CONFIG_CPU_PM
 static void cpu_pm_pmu_setup(struct arm_pmu *armpmu, unsigned long cmd)
 {
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 4b5b83677e3f..6c2631e2cbd7 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -172,6 +172,7 @@ void kvm_host_pmu_init(struct arm_pmu *pmu);
 #endif
 
 bool arm_pmu_irq_is_nmi(void);
+void arm_pmu_set_phys_irq(bool enable);
 
 /* Internal functions only for core arm_pmu code */
 struct arm_pmu *armpmu_alloc(void);
@@ -182,6 +183,10 @@ void armpmu_free_irq(int irq, int cpu);
 
 #define ARMV8_PMU_PDEV_NAME "armv8-pmu"
 
+#else /* CONFIG_ARM_PMU */
+
+static inline void arm_pmu_set_phys_irq(bool enable) {}
+
 #endif /* CONFIG_ARM_PMU */
 
 #define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:57 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:57 +0000
Subject: [PATCH v6 32/43] arm64: rme: Enable PMU support with a realm guest
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-33-steven.price@arm.com>

Use the PMU registers from the RmiRecExit structure to identify when an
overflow interrupt is due and inject it into the guest. Also hook up the
configuration option for enabling the PMU within the guest.

When entering a realm guest with a PMU interrupt pending, it is
necessary to disable the physical interrupt. Otherwise when the RMM
restores the PMU state the physical interrupt will trigger causing an
immediate exit back to the host. The guest is expected to acknowledge
the interrupt causing a host exit (to update the GIC state) which gives
the opportunity to re-enable the physical interrupt before the next PMU
event.

Number of PMU counters is configured by the VMM by writing to PMCR.N.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v2:
 * Add a macro kvm_pmu_get_irq_level() to avoid compile issues when PMU
   support is disabled.
---
 arch/arm64/kvm/arm.c      | 11 +++++++++++
 arch/arm64/kvm/guest.c    |  7 +++++++
 arch/arm64/kvm/pmu-emul.c |  3 +++
 arch/arm64/kvm/rme.c      |  8 ++++++++
 arch/arm64/kvm/sys_regs.c |  2 +-
 include/kvm/arm_pmu.h     |  4 ++++
 6 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 6f7f96ab781d..ae3596a25272 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -15,6 +15,7 @@
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
 #include <linux/mman.h>
+#include <linux/perf/arm_pmu.h>
 #include <linux/sched.h>
 #include <linux/kvm.h>
 #include <linux/kvm_irqfd.h>
@@ -1209,6 +1210,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 	run->exit_reason = KVM_EXIT_UNKNOWN;
 	run->flags = 0;
 	while (ret > 0) {
+		bool pmu_stopped = false;
+
 		/*
 		 * Check conditions before entering the guest
 		 */
@@ -1240,6 +1243,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 
 		kvm_pmu_flush_hwstate(vcpu);
 
+		if (vcpu_is_rec(vcpu) && kvm_pmu_get_irq_level(vcpu)) {
+			pmu_stopped = true;
+			arm_pmu_set_phys_irq(false);
+		}
+
 		local_irq_disable();
 
 		kvm_vgic_flush_hwstate(vcpu);
@@ -1342,6 +1350,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 
 		preempt_enable();
 
+		if (pmu_stopped)
+			arm_pmu_set_phys_irq(true);
+
 		/*
 		 * The ARMv8 architecture doesn't give the hypervisor
 		 * a mechanism to prevent a guest from dropping to AArch32 EL0
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 920e0fd73698..b4e3839f6076 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -804,6 +804,8 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	return kvm_arm_sys_reg_get_reg(vcpu, reg);
 }
 
+#define KVM_REG_ARM_PMCR_EL0		ARM64_SYS_REG(3, 3, 9, 12, 0)
+
 /*
  * The RMI ABI only enables setting some GPRs and PC. The selection of GPRs
  * that are available depends on the Realm state and the reason for the last
@@ -818,6 +820,11 @@ static bool validate_realm_set_reg(struct kvm_vcpu *vcpu,
 		u64 off = core_reg_offset_from_id(reg->id);
 
 		return kvm_realm_validate_core_reg(off);
+	} else {
+		switch (reg->id) {
+		case KVM_REG_ARM_PMCR_EL0:
+			return true;
+		}
 	}
 
 	return false;
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 456102bc0b55..5628b573ca41 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -397,6 +397,9 @@ static bool kvm_pmu_overflow_status(struct kvm_vcpu *vcpu)
 {
 	u64 reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);
 
+	if (vcpu_is_rec(vcpu))
+		return vcpu->arch.rec.run->exit.pmu_ovf_status;
+
 	reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1);
 
 	/*
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 27a479feb907..e562e77c1f94 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -303,6 +303,11 @@ static int realm_create_rd(struct kvm *kvm)
 	params->rtt_base = kvm->arch.mmu.pgd_phys;
 	params->vmid = realm->vmid;
 
+	if (kvm->arch.arm_pmu) {
+		params->pmu_num_ctrs = kvm->arch.pmcr_n;
+		params->flags |= RMI_REALM_PARAM_FLAG_PMU;
+	}
+
 	params_phys = virt_to_phys(params);
 
 	if (rmi_realm_create(rd_phys, params_phys)) {
@@ -1370,6 +1375,9 @@ int kvm_create_rec(struct kvm_vcpu *vcpu)
 	if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_PSCI_0_2))
 		return -EINVAL;
 
+	if (vcpu->kvm->arch.arm_pmu && !kvm_vcpu_has_pmu(vcpu))
+		return -EINVAL;
+
 	BUILD_BUG_ON(sizeof(*params) > PAGE_SIZE);
 	BUILD_BUG_ON(sizeof(*rec->run) > PAGE_SIZE);
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 83c6b4a07ef5..a4713609e230 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1324,7 +1324,7 @@ static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
 	 * implements. Ignore this error to maintain compatibility
 	 * with the existing KVM behavior.
 	 */
-	if (!kvm_vm_has_ran_once(kvm) &&
+	if (!kvm_vm_has_ran_once(kvm) && !kvm_realm_is_created(kvm) &&
 	    new_n <= kvm_arm_pmu_get_max_counters(kvm))
 		kvm->arch.pmcr_n = new_n;
 
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index e61dd7dd2286..30625a6fd143 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -77,6 +77,8 @@ void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu);
 void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu);
 void kvm_vcpu_pmu_resync_el0(void);
 
+#define kvm_pmu_get_irq_level(vcpu) ((vcpu)->arch.pmu.irq_level)
+
 #define kvm_vcpu_has_pmu(vcpu)					\
 	(vcpu_has_feature(vcpu, KVM_ARM_VCPU_PMU_V3))
 
@@ -164,6 +166,8 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
 	return 0;
 }
 
+#define kvm_pmu_get_irq_level(vcpu) (false)
+
 #define kvm_vcpu_has_pmu(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) {}
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:58 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:58 +0000
Subject: [PATCH v6 33/43] kvm: rme: Hide KVM_CAP_READONLY_MEM for realm guests
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-34-steven.price@arm.com>

For protected memory read only isn't supported. While it may be possible
to support read only for unprotected memory, this isn't supported at the
present time.

Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/arm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index ae3596a25272..b6f63ab33354 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -377,7 +377,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ONE_REG:
 	case KVM_CAP_ARM_PSCI:
 	case KVM_CAP_ARM_PSCI_0_2:
-	case KVM_CAP_READONLY_MEM:
 	case KVM_CAP_MP_STATE:
 	case KVM_CAP_IMMEDIATE_EXIT:
 	case KVM_CAP_VCPU_EVENTS:
@@ -391,6 +390,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_COUNTER_OFFSET:
 		r = 1;
 		break;
+	case KVM_CAP_READONLY_MEM:
 	case KVM_CAP_SET_GUEST_DEBUG:
 		r = !kvm_is_realm(kvm);
 		break;
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:59 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:59 +0000
Subject: [PATCH v6 34/43] arm64: RME: Propagate number of breakpoints and watchpoints to userspace
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-35-steven.price@arm.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

The RMM describes the maximum number of BPs/WPs available to the guest
in the Feature Register 0. Propagate those numbers into ID_AA64DFR0_EL1,
which is visible to userspace. A VMM needs this information in order to
set up realm parameters.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/include/asm/kvm_rme.h |  2 ++
 arch/arm64/kvm/rme.c             | 22 ++++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c        |  2 +-
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 0d89ab1645c1..f8e37907e2d5 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -85,6 +85,8 @@ void kvm_init_rme(void);
 u32 kvm_realm_ipa_limit(void);
 u32 kvm_realm_vgic_nr_lr(void);
 
+u64 kvm_realm_reset_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val);
+
 bool kvm_rme_supports_sve(void);
 
 int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap);
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index e562e77c1f94..d21042d5ec9a 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -63,6 +63,28 @@ u32 kvm_realm_vgic_nr_lr(void)
 	return u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_GICV3_NUM_LRS);
 }
 
+u64 kvm_realm_reset_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
+{
+	u32 bps = u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_NUM_BPS);
+	u32 wps = u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_NUM_WPS);
+	u32 ctx_cmps;
+
+	if (!kvm_is_realm(vcpu->kvm))
+		return val;
+
+	/* Ensure CTX_CMPs is still valid */
+	ctx_cmps = FIELD_GET(ID_AA64DFR0_EL1_CTX_CMPs, val);
+	ctx_cmps = min(bps, ctx_cmps);
+
+	val &= ~(ID_AA64DFR0_EL1_BRPs_MASK | ID_AA64DFR0_EL1_WRPs_MASK |
+		 ID_AA64DFR0_EL1_CTX_CMPs);
+	val |= FIELD_PREP(ID_AA64DFR0_EL1_BRPs_MASK, bps) |
+	       FIELD_PREP(ID_AA64DFR0_EL1_WRPs_MASK, wps) |
+	       FIELD_PREP(ID_AA64DFR0_EL1_CTX_CMPs, ctx_cmps);
+
+	return val;
+}
+
 static int get_start_level(struct realm *realm)
 {
 	return 4 - stage2_pgtable_levels(realm->ia_bits);
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index a4713609e230..55cde43b36b9 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1806,7 +1806,7 @@ static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
 	/* Hide SPE from guests */
 	val &= ~ID_AA64DFR0_EL1_PMSVer_MASK;
 
-	return val;
+	return kvm_realm_reset_id_aa64dfr0_el1(vcpu, val);
 }
 
 static int set_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:56:00 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:56:00 +0000
Subject: [PATCH v6 35/43] arm64: RME: Set breakpoint parameters through SET_ONE_REG
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-36-steven.price@arm.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Allow userspace to configure the number of breakpoints and watchpoints
of a Realm VM through KVM_SET_ONE_REG ID_AA64DFR0_EL1.

The KVM sys_reg handler checks the user value against the maximum value
given by RMM (arm64_check_features() gets it from the
read_sanitised_id_aa64dfr0_el1() reset handler).

Userspace discovers that it can write these fields by issuing a
KVM_ARM_GET_REG_WRITABLE_MASKS ioctl.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/guest.c    |  2 ++
 arch/arm64/kvm/rme.c      |  3 +++
 arch/arm64/kvm/sys_regs.c | 17 +++++++++++------
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index b4e3839f6076..60756b4c18fc 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -805,6 +805,7 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 }
 
 #define KVM_REG_ARM_PMCR_EL0		ARM64_SYS_REG(3, 3, 9, 12, 0)
+#define KVM_REG_ARM_ID_AA64DFR0_EL1	ARM64_SYS_REG(3, 0, 0, 5, 0)
 
 /*
  * The RMI ABI only enables setting some GPRs and PC. The selection of GPRs
@@ -823,6 +824,7 @@ static bool validate_realm_set_reg(struct kvm_vcpu *vcpu,
 	} else {
 		switch (reg->id) {
 		case KVM_REG_ARM_PMCR_EL0:
+		case KVM_REG_ARM_ID_AA64DFR0_EL1:
 			return true;
 		}
 	}
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index d21042d5ec9a..d77754ce8d14 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -293,6 +293,7 @@ static int realm_create_rd(struct kvm *kvm)
 	void *rd = NULL;
 	phys_addr_t rd_phys, params_phys;
 	size_t pgd_size = kvm_pgtable_stage2_pgd_size(kvm->arch.mmu.vtcr);
+	u64 dfr0 = kvm_read_vm_id_reg(kvm, SYS_ID_AA64DFR0_EL1);
 	int i, r;
 
 	if (WARN_ON(realm->rd) || WARN_ON(!realm->params))
@@ -324,6 +325,8 @@ static int realm_create_rd(struct kvm *kvm)
 	params->rtt_num_start = pgd_size / PAGE_SIZE;
 	params->rtt_base = kvm->arch.mmu.pgd_phys;
 	params->vmid = realm->vmid;
+	params->num_bps = SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr0);
+	params->num_wps = SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr0);
 
 	if (kvm->arch.arm_pmu) {
 		params->pmu_num_ctrs = kvm->arch.pmcr_n;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 55cde43b36b9..750f69abd3a5 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1815,6 +1815,9 @@ static int set_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
 {
 	u8 debugver = SYS_FIELD_GET(ID_AA64DFR0_EL1, DebugVer, val);
 	u8 pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer, val);
+	u8 bps = SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, val);
+	u8 wps = SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, val);
+	u8 ctx_cmps = SYS_FIELD_GET(ID_AA64DFR0_EL1, CTX_CMPs, val);
 
 	/*
 	 * Prior to commit 3d0dba5764b9 ("KVM: arm64: PMU: Move the
@@ -1834,10 +1837,11 @@ static int set_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
 		val &= ~ID_AA64DFR0_EL1_PMUVer_MASK;
 
 	/*
-	 * ID_AA64DFR0_EL1.DebugVer is one of those awkward fields with a
-	 * nonzero minimum safe value.
+	 * ID_AA64DFR0_EL1.DebugVer, BRPs and WRPs all have to be greater than
+	 * zero. CTX_CMPs is never greater than BRPs.
 	 */
-	if (debugver < ID_AA64DFR0_EL1_DebugVer_IMP)
+	if (debugver < ID_AA64DFR0_EL1_DebugVer_IMP || !bps || !wps ||
+	    ctx_cmps > bps)
 		return -EINVAL;
 
 	return set_id_reg(vcpu, rd, val);
@@ -1984,10 +1988,11 @@ static int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 	mutex_lock(&vcpu->kvm->arch.config_lock);
 
 	/*
-	 * Once the VM has started the ID registers are immutable. Reject any
-	 * write that does not match the final register value.
+	 * Once the VM has started or the Realm descriptor is created, the ID
+	 * registers are immutable. Reject any write that does not match the
+	 * final register value.
 	 */
-	if (kvm_vm_has_ran_once(vcpu->kvm)) {
+	if (kvm_vm_has_ran_once(vcpu->kvm) || kvm_realm_is_created(vcpu->kvm)) {
 		if (val != read_id_reg(vcpu, rd))
 			ret = -EBUSY;
 		else
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:56:01 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:56:01 +0000
Subject: [PATCH v6 36/43] arm64: RME: Initialize PMCR.N with number counter supported by RMM
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-37-steven.price@arm.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Provide an accurate number of available PMU counters to userspace when
setting up a Realm.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/include/asm/kvm_rme.h | 1 +
 arch/arm64/kvm/pmu-emul.c        | 3 +++
 arch/arm64/kvm/rme.c             | 5 +++++
 3 files changed, 9 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index f8e37907e2d5..7839ef81c20e 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -84,6 +84,7 @@ struct realm_rec {
 void kvm_init_rme(void);
 u32 kvm_realm_ipa_limit(void);
 u32 kvm_realm_vgic_nr_lr(void);
+u8 kvm_realm_max_pmu_counters(void);
 
 u64 kvm_realm_reset_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val);
 
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 5628b573ca41..f201f86ed7c8 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -1016,6 +1016,9 @@ u8 kvm_arm_pmu_get_max_counters(struct kvm *kvm)
 {
 	struct arm_pmu *arm_pmu = kvm->arch.arm_pmu;
 
+	if (kvm_is_realm(kvm))
+		return kvm_realm_max_pmu_counters();
+
 	/*
 	 * The arm_pmu->cntr_mask considers the fixed counter(s) as well.
 	 * Ignore those and return only the general-purpose counters.
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index d77754ce8d14..1230550e2a71 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -63,6 +63,11 @@ u32 kvm_realm_vgic_nr_lr(void)
 	return u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_GICV3_NUM_LRS);
 }
 
+u8 kvm_realm_max_pmu_counters(void)
+{
+	return u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS);
+}
+
 u64 kvm_realm_reset_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
 {
 	u32 bps = u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_NUM_BPS);
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:56:02 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:56:02 +0000
Subject: [PATCH v6 37/43] arm64: RME: Propagate max SVE vector length from RMM
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-38-steven.price@arm.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

RMM provides the maximum vector length it supports for a guest in its
feature register. Make it visible to the rest of KVM and to userspace
via KVM_REG_ARM64_SVE_VLS.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  2 +-
 arch/arm64/include/asm/kvm_rme.h  |  1 +
 arch/arm64/kvm/guest.c            |  2 +-
 arch/arm64/kvm/reset.c            | 12 ++++++++++--
 arch/arm64/kvm/rme.c              |  6 ++++++
 5 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 220195c727ef..5b16e7d61de8 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -75,9 +75,9 @@ enum kvm_mode kvm_get_mode(void);
 static inline enum kvm_mode kvm_get_mode(void) { return KVM_MODE_NONE; };
 #endif
 
-extern unsigned int __ro_after_init kvm_sve_max_vl;
 extern unsigned int __ro_after_init kvm_host_sve_max_vl;
 int __init kvm_arm_init_sve(void);
+unsigned int kvm_sve_get_max_vl(struct kvm *kvm);
 
 u32 __attribute_const__ kvm_target_cpu(void);
 void kvm_reset_vcpu(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 7839ef81c20e..4b2e21d5f37e 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -85,6 +85,7 @@ void kvm_init_rme(void);
 u32 kvm_realm_ipa_limit(void);
 u32 kvm_realm_vgic_nr_lr(void);
 u8 kvm_realm_max_pmu_counters(void);
+unsigned int kvm_realm_sve_max_vl(void);
 
 u64 kvm_realm_reset_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val);
 
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 60756b4c18fc..429c8f10b76a 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -377,7 +377,7 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 		if (vq_present(vqs, vq))
 			max_vq = vq;
 
-	if (max_vq > sve_vq_from_vl(kvm_sve_max_vl))
+	if (max_vq > sve_vq_from_vl(kvm_sve_get_max_vl(vcpu->kvm)))
 		return -EINVAL;
 
 	/*
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 16a5d11fc75a..26134c904865 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -46,7 +46,7 @@ unsigned int __ro_after_init kvm_host_sve_max_vl;
 #define VCPU_RESET_PSTATE_SVC	(PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
 				 PSR_AA32_I_BIT | PSR_AA32_F_BIT)
 
-unsigned int __ro_after_init kvm_sve_max_vl;
+static unsigned int __ro_after_init kvm_sve_max_vl;
 
 int __init kvm_arm_init_sve(void)
 {
@@ -76,9 +76,17 @@ int __init kvm_arm_init_sve(void)
 	return 0;
 }
 
+unsigned int kvm_sve_get_max_vl(struct kvm *kvm)
+{
+	if (kvm_is_realm(kvm))
+		return kvm_realm_sve_max_vl();
+	else
+		return kvm_sve_max_vl;
+}
+
 static void kvm_vcpu_enable_sve(struct kvm_vcpu *vcpu)
 {
-	vcpu->arch.sve_max_vl = kvm_sve_max_vl;
+	vcpu->arch.sve_max_vl = kvm_sve_get_max_vl(vcpu->kvm);
 
 	/*
 	 * Userspace can still customize the vector lengths by writing
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 1230550e2a71..39dbc19e4a42 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -68,6 +68,12 @@ u8 kvm_realm_max_pmu_counters(void)
 	return u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS);
 }
 
+unsigned int kvm_realm_sve_max_vl(void)
+{
+	return sve_vl_from_vq(u64_get_bits(rmm_feat_reg0,
+					   RMI_FEATURE_REGISTER_0_SVE_VL) + 1);
+}
+
 u64 kvm_realm_reset_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
 {
 	u32 bps = u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_NUM_BPS);
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:56:03 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:56:03 +0000
Subject: [PATCH v6 38/43] arm64: RME: Configure max SVE vector length for a Realm
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-39-steven.price@arm.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Obtain the max vector length configured by userspace on the vCPUs, and
write it into the Realm parameters. By default the vCPU is configured
with the max vector length reported by RMM, and userspace can reduce it
with a write to KVM_REG_ARM64_SVE_VLS.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/guest.c |  3 ++-
 arch/arm64/kvm/rme.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 429c8f10b76a..5562029368c5 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -363,7 +363,7 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	if (!vcpu_has_sve(vcpu))
 		return -ENOENT;
 
-	if (kvm_arm_vcpu_sve_finalized(vcpu))
+	if (kvm_arm_vcpu_sve_finalized(vcpu) || kvm_realm_is_created(vcpu->kvm))
 		return -EPERM; /* too late! */
 
 	if (WARN_ON(vcpu->arch.sve_state))
@@ -825,6 +825,7 @@ static bool validate_realm_set_reg(struct kvm_vcpu *vcpu,
 		switch (reg->id) {
 		case KVM_REG_ARM_PMCR_EL0:
 		case KVM_REG_ARM_ID_AA64DFR0_EL1:
+		case KVM_REG_ARM64_SVE_VLS:
 			return true;
 		}
 	}
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 39dbc19e4a42..3116ecee37a8 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -297,6 +297,44 @@ static void realm_unmap_shared_range(struct kvm *kvm,
 	}
 }
 
+static int realm_init_sve_param(struct kvm *kvm, struct realm_params *params)
+{
+	int ret = 0;
+	unsigned long i;
+	struct kvm_vcpu *vcpu;
+	int max_vl, realm_max_vl = -1;
+
+	/*
+	 * Get the preferred SVE configuration, set by userspace with the
+	 * KVM_ARM_VCPU_SVE feature and KVM_REG_ARM64_SVE_VLS pseudo-register.
+	 */
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		mutex_lock(&vcpu->mutex);
+		if (vcpu_has_sve(vcpu)) {
+			if (!kvm_arm_vcpu_sve_finalized(vcpu))
+				ret = -EINVAL;
+			max_vl = vcpu->arch.sve_max_vl;
+		} else {
+			max_vl = 0;
+		}
+		mutex_unlock(&vcpu->mutex);
+		if (ret)
+			return ret;
+
+		/* We need all vCPUs to have the same SVE config */
+		if (realm_max_vl >= 0 && realm_max_vl != max_vl)
+			return -EINVAL;
+
+		realm_max_vl = max_vl;
+	}
+
+	if (realm_max_vl > 0) {
+		params->sve_vl = sve_vq_from_vl(realm_max_vl) - 1;
+		params->flags |= RMI_REALM_PARAM_FLAG_SVE;
+	}
+	return 0;
+}
+
 static int realm_create_rd(struct kvm *kvm)
 {
 	struct realm *realm = &kvm->arch.realm;
@@ -344,6 +382,10 @@ static int realm_create_rd(struct kvm *kvm)
 		params->flags |= RMI_REALM_PARAM_FLAG_PMU;
 	}
 
+	r = realm_init_sve_param(kvm, params);
+	if (r)
+		goto out_undelegate_tables;
+
 	params_phys = virt_to_phys(params);
 
 	if (rmi_realm_create(rd_phys, params_phys)) {
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:56:04 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:56:04 +0000
Subject: [PATCH v6 39/43] arm64: RME: Provide register list for unfinalized RME RECs
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-40-steven.price@arm.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

KVM_GET_REG_LIST should not be called before SVE is finalized. The ioctl
handler currently returns -EPERM in this case. But because it uses
kvm_arm_vcpu_is_finalized(), it now also rejects the call for
unfinalized REC even though finalizing the REC can only be done late,
after Realm descriptor creation.

Move the check to copy_sve_reg_indices(). One adverse side effect of
this change is that a KVM_GET_REG_LIST call that only probes for the
array size will now succeed even if SVE is not finalized, but that seems
harmless since the following KVM_GET_REG_LIST with the full array will
fail.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/arm.c   | 4 ----
 arch/arm64/kvm/guest.c | 9 +++------
 2 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index b6f63ab33354..9badb7764667 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1832,10 +1832,6 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 		if (unlikely(!kvm_vcpu_initialized(vcpu)))
 			break;
 
-		r = -EPERM;
-		if (!kvm_arm_vcpu_is_finalized(vcpu))
-			break;
-
 		r = -EFAULT;
 		if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
 			break;
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 5562029368c5..24be77888061 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -674,12 +674,9 @@ static unsigned long num_sve_regs(const struct kvm_vcpu *vcpu)
 {
 	const unsigned int slices = vcpu_sve_slices(vcpu);
 
-	if (!vcpu_has_sve(vcpu))
+	if (!vcpu_has_sve(vcpu) || !kvm_arm_vcpu_sve_finalized(vcpu))
 		return 0;
 
-	/* Policed by KVM_GET_REG_LIST: */
-	WARN_ON(!kvm_arm_vcpu_sve_finalized(vcpu));
-
 	return slices * (SVE_NUM_PREGS + SVE_NUM_ZREGS + 1 /* FFR */)
 		+ 1; /* KVM_REG_ARM64_SVE_VLS */
 }
@@ -695,8 +692,8 @@ static int copy_sve_reg_indices(const struct kvm_vcpu *vcpu,
 	if (!vcpu_has_sve(vcpu))
 		return 0;
 
-	/* Policed by KVM_GET_REG_LIST: */
-	WARN_ON(!kvm_arm_vcpu_sve_finalized(vcpu));
+	if (!kvm_arm_vcpu_sve_finalized(vcpu))
+		return -EPERM;
 
 	/*
 	 * Enumerate this first, so that userspace can save/restore in
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:56:05 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:56:05 +0000
Subject: [PATCH v6 40/43] arm64: RME: Provide accurate register list
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-41-steven.price@arm.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Userspace can set a few registers with KVM_SET_ONE_REG (9 GP registers
at runtime, and 3 system registers during initialization). Update the
register list returned by KVM_GET_REG_LIST.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/guest.c      | 19 ++++++++----
 arch/arm64/kvm/hypercalls.c |  4 +--
 arch/arm64/kvm/sys_regs.c   | 58 ++++++++++++++++++++++++++++---------
 3 files changed, 60 insertions(+), 21 deletions(-)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 24be77888061..e8c38eb5c245 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -621,8 +621,6 @@ static const u64 timer_reg_list[] = {
 	KVM_REG_ARM_PTIMER_CVAL,
 };
 
-#define NUM_TIMER_REGS ARRAY_SIZE(timer_reg_list)
-
 static bool is_timer_reg(u64 index)
 {
 	switch (index) {
@@ -637,9 +635,14 @@ static bool is_timer_reg(u64 index)
 	return false;
 }
 
+static unsigned long num_timer_regs(struct kvm_vcpu *vcpu)
+{
+	return kvm_is_realm(vcpu->kvm) ? 0 : ARRAY_SIZE(timer_reg_list);
+}
+
 static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 {
-	for (int i = 0; i < NUM_TIMER_REGS; i++) {
+	for (int i = 0; i < num_timer_regs(vcpu); i++) {
 		if (put_user(timer_reg_list[i], uindices))
 			return -EFAULT;
 		uindices++;
@@ -677,6 +680,9 @@ static unsigned long num_sve_regs(const struct kvm_vcpu *vcpu)
 	if (!vcpu_has_sve(vcpu) || !kvm_arm_vcpu_sve_finalized(vcpu))
 		return 0;
 
+	if (kvm_is_realm(vcpu->kvm))
+		return 1; /* KVM_REG_ARM64_SVE_VLS */
+
 	return slices * (SVE_NUM_PREGS + SVE_NUM_ZREGS + 1 /* FFR */)
 		+ 1; /* KVM_REG_ARM64_SVE_VLS */
 }
@@ -704,6 +710,9 @@ static int copy_sve_reg_indices(const struct kvm_vcpu *vcpu,
 		return -EFAULT;
 	++num_regs;
 
+	if (kvm_is_realm(vcpu->kvm))
+		return num_regs;
+
 	for (i = 0; i < slices; i++) {
 		for (n = 0; n < SVE_NUM_ZREGS; n++) {
 			reg = KVM_REG_ARM64_SVE_ZREG(n, i);
@@ -742,7 +751,7 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
 	res += num_sve_regs(vcpu);
 	res += kvm_arm_num_sys_reg_descs(vcpu);
 	res += kvm_arm_get_fw_num_regs(vcpu);
-	res += NUM_TIMER_REGS;
+	res += num_timer_regs(vcpu);
 
 	return res;
 }
@@ -776,7 +785,7 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 	ret = copy_timer_indices(vcpu, uindices);
 	if (ret < 0)
 		return ret;
-	uindices += NUM_TIMER_REGS;
+	uindices += num_timer_regs(vcpu);
 
 	return kvm_arm_copy_sys_reg_indices(vcpu, uindices);
 }
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 27ce4cb44904..378576771125 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -407,14 +407,14 @@ void kvm_arm_teardown_hypercalls(struct kvm *kvm)
 
 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
 {
-	return ARRAY_SIZE(kvm_arm_fw_reg_ids);
+	return kvm_is_realm(vcpu->kvm) ? 0 : ARRAY_SIZE(kvm_arm_fw_reg_ids);
 }
 
 int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_ids); i++) {
+	for (i = 0; i < kvm_arm_get_fw_num_regs(vcpu); i++) {
 		if (put_user(kvm_arm_fw_reg_ids[i], uindices++))
 			return -EFAULT;
 	}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 750f69abd3a5..2fcc93d7310e 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -4706,18 +4706,18 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
 				    sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
 }
 
-static unsigned int num_demux_regs(void)
+static unsigned int num_demux_regs(struct kvm_vcpu *vcpu)
 {
-	return CSSELR_MAX;
+	return kvm_is_realm(vcpu->kvm) ? 0 : CSSELR_MAX;
 }
 
-static int write_demux_regids(u64 __user *uindices)
+static int write_demux_regids(struct kvm_vcpu *vcpu, u64 __user *uindices)
 {
 	u64 val = KVM_REG_ARM64 | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX;
 	unsigned int i;
 
 	val |= KVM_REG_ARM_DEMUX_ID_CCSIDR;
-	for (i = 0; i < CSSELR_MAX; i++) {
+	for (i = 0; i < num_demux_regs(vcpu); i++) {
 		if (put_user(val | i, uindices))
 			return -EFAULT;
 		uindices++;
@@ -4725,6 +4725,23 @@ static int write_demux_regids(u64 __user *uindices)
 	return 0;
 }
 
+static unsigned int num_invariant_regs(struct kvm_vcpu *vcpu)
+{
+	return kvm_is_realm(vcpu->kvm) ? 0 : ARRAY_SIZE(invariant_sys_regs);
+}
+
+static int write_invariant_regids(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_invariant_regs(vcpu); i++) {
+		if (put_user(sys_reg_to_index(&invariant_sys_regs[i]), uindices))
+			return -EFAULT;
+		uindices++;
+	}
+	return 0;
+}
+
 static u64 sys_reg_to_index(const struct sys_reg_desc *reg)
 {
 	return (KVM_REG_ARM64 | KVM_REG_SIZE_U64 |
@@ -4748,11 +4765,27 @@ static bool copy_reg_to_user(const struct sys_reg_desc *reg, u64 __user **uind)
 	return true;
 }
 
+static bool kvm_realm_sys_reg_hidden_user(const struct kvm_vcpu *vcpu, u64 reg)
+{
+	if (!kvm_is_realm(vcpu->kvm))
+		return false;
+
+	switch (reg) {
+	case SYS_ID_AA64DFR0_EL1:
+	case SYS_PMCR_EL0:
+		return false;
+	}
+	return true;
+}
+
 static int walk_one_sys_reg(const struct kvm_vcpu *vcpu,
 			    const struct sys_reg_desc *rd,
 			    u64 __user **uind,
 			    unsigned int *total)
 {
+	if (kvm_realm_sys_reg_hidden_user(vcpu, reg_to_encoding(rd)))
+		return 0;
+
 	/*
 	 * Ignore registers we trap but don't save,
 	 * and for which no custom user accessor is provided.
@@ -4790,29 +4823,26 @@ static int walk_sys_regs(struct kvm_vcpu *vcpu, u64 __user *uind)
 
 unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu)
 {
-	return ARRAY_SIZE(invariant_sys_regs)
-		+ num_demux_regs()
+	return num_invariant_regs(vcpu)
+		+ num_demux_regs(vcpu)
 		+ walk_sys_regs(vcpu, (u64 __user *)NULL);
 }
 
 int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 {
-	unsigned int i;
 	int err;
 
-	/* Then give them all the invariant registers' indices. */
-	for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++) {
-		if (put_user(sys_reg_to_index(&invariant_sys_regs[i]), uindices))
-			return -EFAULT;
-		uindices++;
-	}
+	err = write_invariant_regids(vcpu, uindices);
+	if (err)
+		return err;
+	uindices += num_invariant_regs(vcpu);
 
 	err = walk_sys_regs(vcpu, uindices);
 	if (err < 0)
 		return err;
 	uindices += err;
 
-	return write_demux_regids(uindices);
+	return write_demux_regids(vcpu, uindices);
 }
 
 #define KVM_ARM_FEATURE_ID_RANGE_INDEX(r)			\
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:56:06 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:56:06 +0000
Subject: [PATCH v6 41/43] arm64: kvm: Expose support for private memory
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-42-steven.price@arm.com>

Select KVM_GENERIC_PRIVATE_MEM and provide the necessary support
functions.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v2:
 * Switch kvm_arch_has_private_mem() to a macro to avoid overhead of a
   function call.
 * Guard definitions of kvm_arch_{pre,post}_set_memory_attributes() with
   #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES.
 * Early out in kvm_arch_post_set_memory_attributes() if the WARN_ON
   should trigger.
---
 arch/arm64/include/asm/kvm_host.h |  6 ++++++
 arch/arm64/kvm/Kconfig            |  1 +
 arch/arm64/kvm/mmu.c              | 22 ++++++++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5b16e7d61de8..837e2d29609d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1408,6 +1408,12 @@ struct kvm *kvm_arch_alloc_vm(void);
 
 #define vcpu_is_protected(vcpu)		kvm_vm_is_protected((vcpu)->kvm)
 
+#ifdef CONFIG_KVM_PRIVATE_MEM
+#define kvm_arch_has_private_mem(kvm) ((kvm)->arch.is_realm)
+#else
+#define kvm_arch_has_private_mem(kvm) false
+#endif
+
 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
 bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index ead632ad01b4..7bc1a2c89b3a 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -38,6 +38,7 @@ menuconfig KVM
 	select HAVE_KVM_VCPU_RUN_PID_CHANGE
 	select SCHED_INFO
 	select GUEST_PERF_EVENTS if PERF_EVENTS
+	select KVM_GENERIC_PRIVATE_MEM
 	help
 	  Support hosting virtualized guest machines.
 
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index cef7c3dcbf99..8b2d803e558a 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -2314,6 +2314,28 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
 	return ret;
 }
 
+#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
+bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm,
+					struct kvm_gfn_range *range)
+{
+	WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm));
+	return false;
+}
+
+bool kvm_arch_post_set_memory_attributes(struct kvm *kvm,
+					 struct kvm_gfn_range *range)
+{
+	if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm)))
+		return false;
+
+	if (range->arg.attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE)
+		range->only_shared = true;
+	kvm_unmap_gfn_range(kvm, range);
+
+	return false;
+}
+#endif
+
 void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot)
 {
 }
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:56:07 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:56:07 +0000
Subject: [PATCH v6 42/43] KVM: arm64: Expose KVM_ARM_VCPU_REC to user space
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-43-steven.price@arm.com>

Increment KVM_VCPU_MAX_FEATURES to expose the new capability to user
space.

*NOTE*: This also exposes KVM_ARM_VCPU_HAS_EL2 (as it is one less than
KVM_ARM_VCPU_REC) - so this currently depends on nested virt being
'finished' before merging. See below for discussion:

https://lore.kernel.org/r/a7011738-a084-46fa-947f-395d90b37f8b%40arm.com

Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 837e2d29609d..df3168cbe70a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -40,7 +40,7 @@
 
 #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
 
-#define KVM_VCPU_MAX_FEATURES 7
+#define KVM_VCPU_MAX_FEATURES 9
 #define KVM_VCPU_VALID_FEATURES	(BIT(KVM_VCPU_MAX_FEATURES) - 1)
 
 #define KVM_REQ_SLEEP \
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:56:08 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:56:08 +0000
Subject: [PATCH v6 43/43] KVM: arm64: Allow activating realms
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-44-steven.price@arm.com>

Add the ioctl to activate a realm and set the static branch to enable
access to the realm functionality if the RMM is detected.

Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/rme.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 3116ecee37a8..39d056e5c5b2 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -1147,6 +1147,20 @@ static int kvm_init_ipa_range_realm(struct kvm *kvm,
 	return realm_init_ipa_state(realm, addr, end);
 }
 
+static int kvm_activate_realm(struct kvm *kvm)
+{
+	struct realm *realm = &kvm->arch.realm;
+
+	if (kvm_realm_state(kvm) != REALM_STATE_NEW)
+		return -EINVAL;
+
+	if (rmi_realm_activate(virt_to_phys(realm->rd)))
+		return -ENXIO;
+
+	WRITE_ONCE(realm->state, REALM_STATE_ACTIVE);
+	return 0;
+}
+
 /* Protects access to rme_vmid_bitmap */
 static DEFINE_SPINLOCK(rme_vmid_lock);
 static unsigned long *rme_vmid_bitmap;
@@ -1296,6 +1310,9 @@ int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
 		r = kvm_populate_realm(kvm, &args);
 		break;
 	}
+	case KVM_CAP_ARM_RME_ACTIVATE_REALM:
+		r = kvm_activate_realm(kvm);
+		break;
 	default:
 		r = -EINVAL;
 		break;
@@ -1567,5 +1584,5 @@ void kvm_init_rme(void)
 	if (rme_vmid_init())
 		return;
 
-	/* Future patch will enable static branch kvm_rme_is_available */
+	static_branch_enable(&kvm_rme_is_available);
 }
-- 
2.43.0



From tudor.ambarus at linaro.org  Thu Dec 12 08:00:39 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 16:00:39 +0000
Subject: [PATCH v2 2/4] arm64: dts: exynos: gs101: add AP to APM mailbox
 node
In-Reply-To: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
References: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
Message-ID: <20241212-b4-acpm-v4-upstream-dts-v2-2-91b7a6f6d0b0@linaro.org>

GS101 has 14 mailbox controllers. Add the AP to APM mailbox node.

Mailbox controllers have a shared register that can be used for passing
the mailbox messages. The AP to APM mailbox controller is used just as a
doorbell mechanism. It raises interrupt to the firmware after the mailbox
message has been written to SRAM where the TX/RX rings are defined.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 1441e9a252c2..04561e15b96c 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -1445,6 +1445,15 @@ wakeup-interrupt-controller {
 			};
 		};
 
+		ap2apm_mailbox: mailbox at 17610000 {
+			compatible = "google,gs101-mbox";
+			reg = <0x17610000 0x1000>;
+			clocks = <&cmu_apm CLK_GOUT_APM_MAILBOX_APM_AP_PCLK>;
+			clock-names = "pclk";
+			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <2>;
+		};
+
 		pinctrl_gsactrl: pinctrl at 17940000 {
 			compatible = "google,gs101-pinctrl";
 			reg = <0x17940000 0x00001000>;

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec 12 08:00:37 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 16:00:37 +0000
Subject: [PATCH v2 0/4] arm64: exynos: gs101: add ACPM related nodes
Message-ID: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>

Define SRAM, mailbox and ACPM protocol in device tree.
Enable the mailbox and ACPM protocol in defconfig.

Use a constant for the channel type until the bindings header file gets
queued. Bindings and driver changes at:
Link: https://lore.kernel.org/all/20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf at linaro.org/
Link: https://lore.kernel.org/all/20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9 at linaro.org/

Changes in v2:
- update nodes based on the bindings updates
- update mailbox and power-management (mailbox client) nodes to specify
  channel type (doorbell or data) and channel ID.

v1:
Link: https://lore.kernel.org/linux-arm-kernel/20241205180200.203146-1-tudor.ambarus at linaro.org/

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Tudor Ambarus (4):
      arm64: dts: exynos: gs101: add SRAM node
      arm64: dts: exynos: gs101: add AP to APM mailbox node
      arm64: dts: exynos: gs101: add ACPM protocol node
      arm64: defconfig: enable ACPM protocol and Exynos mailbox

 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 39 ++++++++++++++++++++++++++++
 arch/arm64/configs/defconfig                 |  2 ++
 2 files changed, 41 insertions(+)
---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241212-b4-acpm-v4-upstream-dts-2fc0b6a3bbda

Best regards,
-- 
Tudor Ambarus <tudor.ambarus at linaro.org>



From tudor.ambarus at linaro.org  Thu Dec 12 08:00:40 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 16:00:40 +0000
Subject: [PATCH v2 3/4] arm64: dts: exynos: gs101: add ACPM protocol node
In-Reply-To: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
References: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
Message-ID: <20241212-b4-acpm-v4-upstream-dts-v2-3-91b7a6f6d0b0@linaro.org>

Add the ACPM protocol node. ACPM protocol provides interface for all
the client drivers making use of the features offered by the
Active Power Management (APM) module.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 04561e15b96c..8c3f07371912 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -277,6 +277,28 @@ apm_sram: sram at 2039000 {
 		ranges = <0x0 0x0 0x2039000 0x40000>;
 	};
 
+	firmware {
+		acpm_ipc: power-management {
+			compatible = "google,gs101-acpm-ipc";
+			mboxes = <&ap2apm_mailbox 0 0
+				  &ap2apm_mailbox 0 1
+				  &ap2apm_mailbox 0 2
+				  &ap2apm_mailbox 0 3
+				  &ap2apm_mailbox 0 4
+				  &ap2apm_mailbox 0 5
+				  &ap2apm_mailbox 0 6
+				  &ap2apm_mailbox 0 7
+				  &ap2apm_mailbox 0 8
+				  &ap2apm_mailbox 0 9
+				  &ap2apm_mailbox 0 10
+				  &ap2apm_mailbox 0 11
+				  &ap2apm_mailbox 0 12
+				  &ap2apm_mailbox 0 13
+				  &ap2apm_mailbox 0 14>;
+			shmem = <&apm_sram>;
+		};
+	};
+
 	soc: soc at 0 {
 		compatible = "simple-bus";
 		#address-cells = <1>;

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec 12 08:00:38 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 16:00:38 +0000
Subject: [PATCH v2 1/4] arm64: dts: exynos: gs101: add SRAM node
In-Reply-To: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
References: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
Message-ID: <20241212-b4-acpm-v4-upstream-dts-v2-1-91b7a6f6d0b0@linaro.org>

SRAM is used by the ACPM protocol to retrieve the ACPM channels
information, which includes the TX/RX rings among other channel
configuration data. Add the SRAM node.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 302c5beb224a..1441e9a252c2 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -269,6 +269,14 @@ bldr_log_hist_reserved: bldr-log-hist-reserved at fd900000 {
 		};
 	};
 
+	apm_sram: sram at 2039000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0x2039000 0x40000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x2039000 0x40000>;
+	};
+
 	soc: soc at 0 {
 		compatible = "simple-bus";
 		#address-cells = <1>;

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec 12 08:00:41 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 16:00:41 +0000
Subject: [PATCH v2 4/4] arm64: defconfig: enable ACPM protocol and Exynos
 mailbox
In-Reply-To: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
References: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
Message-ID: <20241212-b4-acpm-v4-upstream-dts-v2-4-91b7a6f6d0b0@linaro.org>

Enable the Samsung Exynos ACPM protocol and its transport layer, the
Exynos mailbox driver. Samsung Exynos platforms implement ACPM to
provide support for PMIC, clock frequency scaling, clock configuration
and temperature sensors.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..91139b1cf813 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -262,6 +262,7 @@ CONFIG_IMX_SCU=y
 CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
 CONFIG_QCOM_QSEECOM=y
 CONFIG_QCOM_QSEECOM_UEFISECAPP=y
+CONFIG_EXYNOS_ACPM_PROTOCOL=m
 CONFIG_GNSS=m
 CONFIG_GNSS_MTK_SERIAL=m
 CONFIG_MTD=y
@@ -1378,6 +1379,7 @@ CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_TEGRA186_TIMER=y
 CONFIG_RENESAS_OSTM=y
 CONFIG_ARM_MHU=y
+CONFIG_EXYNOS_MBOX=m
 CONFIG_IMX_MBOX=y
 CONFIG_OMAP2PLUS_MBOX=m
 CONFIG_PLATFORM_MHU=y

-- 
2.47.0.338.g60cca15819-goog



From kevin.brodsky at arm.com  Thu Dec 12 08:01:13 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 12 Dec 2024 17:01:13 +0100
Subject: [PATCH v2] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <Z1r0zO3BrYrt1xNY@e133380.arm.com>
References: <20241210160940.2031997-1-kevin.brodsky@arm.com>
 <Z1r0zO3BrYrt1xNY@e133380.arm.com>
Message-ID: <adf75d67-e665-47c7-a0de-9bfdf5406d40@arm.com>

On 12/12/2024 15:35, Dave Martin wrote:
> Hi,
>
> On Tue, Dec 10, 2024 at 04:09:40PM +0000, Kevin Brodsky wrote:
>> Commit eaf62ce1563b ("arm64/signal: Set up and restore the GCS
>> context for signal handlers") introduced a potential failure point
>> at the end of setup_return(). This is unfortunate as it is too late
>> to deliver a SIGSEGV: if that SIGSEGV is handled, the subsequent
>> sigreturn will end up returning to the original handler, which is
>> not the intention (since we failed to deliver that signal).
>>
>> Make sure this does not happen by calling gcs_signal_entry()
>> at the very beginning of setup_return(), and add a comment just
>> after to discourage error cases being introduced from that point
>> onwards.
>>
>> While at it, also take care of copy_siginfo_to_user(): since it may
>> fail, we shouldn't be calling it after setup_return() either. Call
>> it before setup_return() instead, and move the setting of X1/X2
>> inside setup_return() where it belongs (after the "point of no
>> failure").
>>
>> Background: the first part of setup_rt_frame(), including
>> setup_sigframe(), has no impact on the execution of the interrupted
>> thread. The signal frame is written to the stack, but the stack
>> pointer remains unchanged. Failure at this stage can be recovered by
>> a SIGSEGV handler, and sigreturn will restore the original context,
>> at the point where the original signal occurred. On the other hand,
>> once setup_return() has updated registers including SP, the thread's
>> control flow has been modified and we must deliver the original
>> signal.
>>
>> Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")
>> Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
>> ---
>> v1..v2:
>> * Added a short comment in setup_rt_frame() after the call to
>>   setup_return() to discourage adding failure points there.
>>   [Dave's suggestion]
> Assuming that this was the only change, I was OK for you to add:
>
> Reviewed-by: Dave Martin <Dave.Martin at arm.com>

Apologies, forgot to add it, thanks for the reminder!

- Kevin


From ryan.roberts at arm.com  Thu Dec 12 08:03:52 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 12 Dec 2024 16:03:52 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <86h678sy00.wl-maz@kernel.org>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-3-miko.lenczewski@arm.com>
 <87cyhxs3xq.wl-maz@kernel.org> <084c5ada-51af-4c1a-b50a-4401e62ddbd6@arm.com>
 <86ikrprn7w.wl-maz@kernel.org> <2b1cc228-a8d5-4383-ab25-abbbcccd2e2c@arm.com>
 <86h678sy00.wl-maz@kernel.org>
Message-ID: <5c551e43-78e9-4336-ab16-b55c0d6c7f92@arm.com>

On 12/12/2024 15:48, Marc Zyngier wrote:
> On Thu, 12 Dec 2024 15:05:24 +0000,
> Ryan Roberts <ryan.roberts at arm.com> wrote:
>>
>> On 12/12/2024 14:26, Marc Zyngier wrote:
>>> On Thu, 12 Dec 2024 10:55:45 +0000,
>>> Ryan Roberts <ryan.roberts at arm.com> wrote:
>>>>
>>>> On 12/12/2024 08:25, Marc Zyngier wrote:
>>>>>> +
>>>>>> +	local_flush_tlb_all();
>>>>>
>>>>> The elephant in the room: if TLBs are in such a sorry state, what
>>>>> guarantees we can make it this far?
>>>>
>>>> I'll leave Miko to respond to your other comments, but I wanted to address this
>>>> one, since it's pretty fundamental. We went around this loop internally and
>>>> concluded that what we are doing is architecturally sound.
>>>>
>>>> The expectation is that a conflict abort can only be generated as a result of
>>>> the change in patch 4 (and patch 5). That change makes it possible for the TLB
>>>> to end up with a multihit. But crucially that can only happen for user space
>>>> memory because that change only operates on user memory. And while the TLB may
>>>> detect the conflict at any time, the conflict abort is only permitted to be
>>>> reported when an architectural access is prevented by the conflict. So we never
>>>> do anything that would allow a conflict for a kernel memory access and a user
>>>> memory conflict abort can never be triggered as a result of accessing kernel memory.
>>>>
>>>> Copy/pasting comment from AlexC on the topic, which explains it better than I can:
>>>>
>>>> """
>>>> The intent is certainly that in cases where the hardware detects a TLB conflict
>>>> abort, it is only permitted to report it (by generating an exception) if it
>>>> applies to an access that is being attempted architecturally. ... that property
>>>> can be built from the following two properties:
>>>>
>>>> 1. The TLB conflict can only be reported as an Instruction Abort or a Data Abort
>>>>
>>>> 2. Those two exception types must be reported synchronously and precisely.
>>>> """
>>>
>>> I totally agree with this. The issue is that nothing says that the
>>> abort is in any way related to userspace.
>>>
>>>>>
>>>>> I honestly don't think you can reliably handle a TLB Conflict abort in
>>>>> the same translation regime as the original fault, given that we don't
>>>>> know the scope of that fault. You are probably making an educated
>>>>> guess that it is good enough on the CPUs you know of, but I don't see
>>>>> anything in the architecture that indicates the "blast radius" of a
>>>>> TLB conflict.
>>>>
>>>> OK, so I'm claiming that the blast radius is limited to the region of memory
>>>> that we are operating on in contpte_collapse() in patch 4. Perhaps we need to go
>>>> re-read the ARM and come back with the specific statements that led us to that
>>>> conclusion?
>>
>> From the ARM:
>> """
>> RFCPSG: If level 1 or level 2 is supported and the Contiguous bit in a set of
>> Block descriptors or Page descriptors is changed, then a TLB conflict abort can
>> be generated because multiple translation table entries might exist within a TLB
>> that translates the same IA.
>> """
>>
>> Although I guess it's not totally explicit, I've interpretted that as saying
>> that conflicting TLB entries can only arise for the IA range for which the
>> contiguous bits have been modified in the translation tables.
> 
> Right, that's reassuring, thanks for digging that one.
> 
>> Given we are only fiddling with the contiguous bits for user space mappings in
>> this way, that's why I'm asserting we will only get a conflict abort for user
>> space mappings... assuming the absence of kernel bugs, anyway...
> 
> For now. But if you dare scanning the list, you'll find a lot of
> people willing to do far more than just that. Including changing the
> shape of the linear map.

Ahh. Sorry I don't do a good job of monitoring the lists. But was just having a
conversation with Catalin about exactly this.

> 
>>
>>>
>>> But we don't know for sure what caused this conflict by the time we
>>> arrive in the handler. It could equally be because we have a glaring
>>> bug somewhere on the kernel side, even if you are *now* only concerned
>>> with userspace.
>>
>> OK I see what you are saying; previously a conflict abort would have led to
>> calling do_bad(), which returns 1, which causes do_mem_abort() to either kill
>> the kernel or the process depending on the origin of the abort. (although if it
>> came from kernel due to bug, we're just hoping that the conflict doesn't affect
>> the path through the handler). With this change, we always assume we can fix it
>> with the TLBI.
>>
>> How about this change to ensure we still die for issues originating from the kernel?
>>
>> if (!user_mode(regs) || !system_supports_bbml2())
>> 		return do_bad(far, esr, regs);
> 
> That wouldn't catch a TLB conflict on get_user(), would it?

Oh good point.

> 
>>> If anything, this should absolutely check for FAR_EL1 and assert that
>>> this is indeed caused by such change.
>>
>> I'm not really sure how we would check this reliably? Without patch 5, the
>> problem is somewhat constrained; we could have as many changes in flight as
>> there are CPUs so we could keep a list of all the {mm_struct, VA-range} that are
>> being modified. But if patch 5 is confirmed to be architecturally sound, then
>> there is no "terminating tlbi" so there is no bound on the set of {mm_struct,
>> VA-range}'s that could legitimately cause a conflict abort.
> 
> I didn't mean to imply that we should identify the exact cause of the
> abort. I was hoping to simply check that FAR_EL1 reports a userspace
> VA. Why wouldn't that work?

Ahh gottya! Yes agreed, this sounds like the right approach.

> 
> 	M.
> 



From angelogioacchino.delregno at collabora.com  Thu Dec 12 08:05:35 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 12 Dec 2024 17:05:35 +0100
Subject: [PATCH 2/2] dts: arm64: mediatek: mt8188: Update OVL compatible
 from MT8183 to MT8195
In-Reply-To: <20241212153344.27408-3-jason-jh.lin@mediatek.com>
References: <20241212153344.27408-1-jason-jh.lin@mediatek.com>
 <20241212153344.27408-3-jason-jh.lin@mediatek.com>
Message-ID: <6710abd1-128d-48ff-84a1-880053fd9e84@collabora.com>

Il 12/12/24 16:33, Jason-JH.Lin ha scritto:
> The OVL hardware capabilities have changed starting from MT8195,
> making the MT8183 compatible no longer applicable.
> Therefore, it is necessary to update the OVL compatible from MT8183 to
> MT8195.
> 
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>

Jason, just so you know - I have patches here adding DSC and merge components of
VDO0, other than all MDP3 components.

Those are almost ready to send, I only need to finish some testing before ;-)

For this one, anyway:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


> ---
>   arch/arm64/boot/dts/mediatek/mt8188.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> index faccc7f16259..23ec3ff6cad9 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> @@ -2488,7 +2488,7 @@ jpeg_decoder: jpeg-decoder at 1a040000 {
>   		};
>   
>   		ovl0: ovl at 1c000000 {
> -			compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8183-disp-ovl";
> +			compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8195-disp-ovl";
>   			reg = <0 0x1c000000 0 0x1000>;
>   			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
>   			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;




From gregkh at linuxfoundation.org  Thu Dec 12 06:53:26 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 12 Dec 2024 15:53:26 +0100
Subject: [PATCH 6.1 261/772] perf cs-etm: Dont flush when packet_queue fills up
In-Reply-To: <20241212144349.797589255@linuxfoundation.org>
References: <20241212144349.797589255@linuxfoundation.org>
Message-ID: <20241212144400.702320466@linuxfoundation.org>

6.1-stable review patch.  If anyone has any objections, please let me know.

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

From: James Clark <james.clark at linaro.org>

[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]

cs_etm__flush(), like cs_etm__sample() is an operation that generates a
sample and then swaps the current with the previous packet. Calling
flush after processing the queues results in two swaps which corrupts
the next sample. Therefore it wasn't appropriate to call flush here so
remove it.

Flushing is still done on a discontinuity to explicitly clear the last
branch buffer, but when the packet_queue fills up before reaching a
timestamp, that's not a discontinuity and the call to
cs_etm__process_traceid_queue() already generated samples and drained
the buffers correctly.

This is visible by looking for a branch that has the same target as the
previous branch and the following source is before the address of the
last target, which is impossible as execution would have had to have
gone backwards:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
   (packet_queue fills here before a timestamp, resulting in a flush and
    branch target ffff80008011cadc is duplicated.)
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

After removing the flush the correct branch target is used for the
second sample, and ffff8000801117c4 is no longer before the previous
address:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

Make sure that a final branch stack is output at the end of the trace
by calling cs_etm__end_block(). This is already done for both the
timeless decode paths.

Fixes: 21fe8dc1191a ("perf cs-etm: Add support for CPU-wide trace scenarios")
Reported-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Closes: https://lore.kernel.org/all/20240719092619.274730-1-gankulkarni at os.amperecomputing.com/
Reviewed-by: Leo Yan <leo.yan at arm.com>
Signed-off-by: James Clark <james.clark at linaro.org>
Tested-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Cc: Ben Gainey <ben.gainey at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Ruidong Tian <tianruidong at linux.alibaba.com>
Cc: Benjamin Gray <bgray at linux.ibm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: coresight at lists.linaro.org
Cc: John Garry <john.g.garry at oracle.com>
Cc: scclevenger at os.amperecomputing.com
Link: https://lore.kernel.org/r/20240916135743.1490403-2-james.clark at linaro.org
Signed-off-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/perf/util/cs-etm.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 09e240e4477d0..3b54baf79bd4a 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2124,12 +2124,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
 
 		/* Ignore return value */
 		cs_etm__process_traceid_queue(etmq, tidq);
-
-		/*
-		 * Generate an instruction sample with the remaining
-		 * branchstack entries.
-		 */
-		cs_etm__flush(etmq, tidq);
 	}
 }
 
@@ -2226,7 +2220,7 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
 
 	while (1) {
 		if (!etm->heap.heap_cnt)
-			goto out;
+			break;
 
 		/* Take the entry at the top of the min heap */
 		cs_queue_nr = etm->heap.heap_array[0].queue_nr;
@@ -2309,6 +2303,23 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
 		ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp);
 	}
 
+	for (i = 0; i < etm->queues.nr_queues; i++) {
+		struct int_node *inode;
+
+		etmq = etm->queues.queue_array[i].priv;
+		if (!etmq)
+			continue;
+
+		intlist__for_each_entry(inode, etmq->traceid_queues_list) {
+			int idx = (int)(intptr_t)inode->priv;
+
+			/* Flush any remaining branch stack entries */
+			tidq = etmq->traceid_queues[idx];
+			ret = cs_etm__end_block(etmq, tidq);
+			if (ret)
+				return ret;
+		}
+	}
 out:
 	return ret;
 }
-- 
2.43.0





From festevam at gmail.com  Thu Dec 12 08:10:38 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 12 Dec 2024 13:10:38 -0300
Subject: [PATCH v2 0/2] media: verisilicon: fix reference padding issue
In-Reply-To: <01020193bb8a24ad-99eafebb-3b0b-40c0-9b28-3a0dbc84327a-000000@eu-west-1.amazonses.com>
References: <01020193bb8a24ad-99eafebb-3b0b-40c0-9b28-3a0dbc84327a-000000@eu-west-1.amazonses.com>
Message-ID: <CAOMZO5DgW3YrpMJPCTzQ-LZCopB4tNPoJhyFQrr6RBvbnBu4VA@mail.gmail.com>

On Thu, Dec 12, 2024 at 12:43?PM Benjamin Gaignard
<benjamin.gaignard at collabora.com> wrote:
>
> Hantro hardware is splited into two parts: the decoder which produce
> tiled pixels formats and the post-processor which produce raster pixels
> formats.
> When post-processor is used the selected pixels format may not have the
> some padding/stride than the decoder output pixels format. This led to
> miscomputing chroma and motion vectors offsets so data are overlapping.
> This series introduce a reference pixels format that decoder use to
> compute the various needed offsets and size.
>
> With this series Fluster for VP9 tests is now 207/305 vs 145/305.
> HEVC test score isn't impacted by these patches (still 141/147).
>
> Version 2:
> - rebased on top of media-commiter/next
> - Add reviewed-by tags
>
> Benjamin Gaignard (2):
>   media: verisilicon: Store reference frames pixels format
>   media: verisilicon: Fix IMX8 native pixels format steps values

Do both patches deserve a Fixes tag?


From Dave.Martin at arm.com  Thu Dec 12 07:39:59 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 15:39:59 +0000
Subject: [RFC PATCH 5/6] arm_mpam: [NFU] Rework ID remapping to use a kernel command-line argument
In-Reply-To: <20241212154000.330467-1-Dave.Martin@arm.com>
References: <20241212154000.330467-1-Dave.Martin@arm.com>
Message-ID: <20241212154000.330467-6-Dave.Martin@arm.com>

Hacking the source is an acceptable interface for experimentation,
but not very convenient.

Instead, add a kernel command-line parameter
mpam_partid_per_closid=<n> to specify how many PARTIDs are used to
provide monitoring groups for each resctrl CLOSID.

This change is not intended for upstream.

Signed-off-by: Dave Martin <Dave.Martin at arm.com>
---
 drivers/platform/arm64/mpam/mpam_resctrl.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
index 0473286ec65a..870efbf39f6f 100644
--- a/drivers/platform/arm64/mpam/mpam_resctrl.c
+++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
@@ -3,6 +3,9 @@
 
 #define pr_fmt(fmt) "mpam: resctrl: " fmt
 
+#undef KBUILD_MODNAME
+#define KBUILD_MODNAME "mpam"
+
 #include <linux/arm_mpam.h>
 #include <linux/cacheinfo.h>
 #include <linux/cpu.h>
@@ -10,6 +13,7 @@
 #include <linux/errno.h>
 #include <linux/limits.h>
 #include <linux/list.h>
+#include <linux/moduleparam.h>
 #include <linux/printk.h>
 #include <linux/rculist.h>
 #include <linux/resctrl.h>
@@ -158,6 +162,24 @@ static bool mpam_resctrl_hide_cdp(enum resctrl_res_level rid)
 
 static unsigned int partid_per_closid = 1;
 
+static int mpam_resctrl_partid_per_closid_set(const char *val,
+					      const struct kernel_param *kp)
+{
+	/*
+	 * 16 in an arbitrary maximum, sufficient for experimentation
+	 * but not ridiculously large:
+	 */
+	return param_set_uint_minmax(val, kp, 1, 16);
+}
+
+static const struct kernel_param_ops mpam_resctrl_partid_per_closid_ops  = {
+	.set = mpam_resctrl_partid_per_closid_set,
+	.get = param_get_uint,
+};
+
+device_param_cb(partid_per_closid, &mpam_resctrl_partid_per_closid_ops,
+		&partid_per_closid, 0444);
+
 static unsigned int mpam_num_pmg(void)
 {
 	return mpam_pmg_max + 1;
-- 
2.34.1



From Dave.Martin at arm.com  Thu Dec 12 07:40:00 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 15:40:00 +0000
Subject: [RFC PATCH 6/6] arm_mpam: [NFU] Development diagnostics for MPAM ID assignments
In-Reply-To: <20241212154000.330467-1-Dave.Martin@arm.com>
References: <20241212154000.330467-1-Dave.Martin@arm.com>
Message-ID: <20241212154000.330467-7-Dave.Martin@arm.com>

Purely for development purposes, add some printks to show what MPAM
IDs actually get assigned and configured.

This would otherwise be observable only though statistical
measurements of performance (or not observable at all).

This change is not intended for upstream.

Signed-off-by: Dave Martin <Dave.Martin at arm.com>
---
 arch/arm64/include/asm/mpam.h              | 7 +++++++
 drivers/platform/arm64/mpam/mpam_devices.c | 6 ++++++
 2 files changed, 13 insertions(+)

diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h
index df725d2d9d05..4ae2e635e261 100644
--- a/arch/arm64/include/asm/mpam.h
+++ b/arch/arm64/include/asm/mpam.h
@@ -66,6 +66,9 @@ static inline void mpam_set_cpu_defaults(int cpu, u16 partid_d, u16 partid_i,
 	default_val |= FIELD_PREP(MPAM1_EL1_PMG_I, pmg_i);
 
 	WRITE_ONCE(per_cpu(arm64_mpam_default, cpu), default_val);
+
+	pr_info("MPAM: CPU%d -> (D=%d:%d, I=%d:%d)\n",
+		cpu, partid_d, pmg_d, partid_i, pmg_i);
 }
 
 static inline void mpam_set_task_partid_pmg(struct task_struct *tsk,
@@ -81,6 +84,10 @@ static inline void mpam_set_task_partid_pmg(struct task_struct *tsk,
 	regval |= FIELD_PREP(MPAM1_EL1_PMG_I, pmg_i);
 
 	WRITE_ONCE(task_thread_info(tsk)->mpam_partid_pmg, regval);
+
+	pr_info("MPAM: task %s[%d/%d] -> (D=%d:%d, I=%d:%d)\n",
+		current->comm, current->pid, current->tgid,
+		partid_d, pmg_d, partid_i, pmg_i);
 #endif
 }
 
diff --git a/drivers/platform/arm64/mpam/mpam_devices.c b/drivers/platform/arm64/mpam/mpam_devices.c
index 41962dd1bb68..dd84c0aa50f6 100644
--- a/drivers/platform/arm64/mpam/mpam_devices.c
+++ b/drivers/platform/arm64/mpam/mpam_devices.c
@@ -3158,6 +3158,12 @@ int mpam_apply_config(struct mpam_component *comp, u16 partid,
 
 	mpam_extend_config(comp->class, cfg);
 
+	pr_info("mpam_apply_config(): comp %d partid %d cfg={0x%x: 0x%lx, 0x%lx, %u, %u}\n",
+		comp->comp_id, partid, cfg->features,
+		(unsigned long)cfg->cpbm,
+		(unsigned long)cfg->mbw_pbm,
+		cfg->mbw_min, cfg->mbw_max);
+
 	if (!mpam_update_config(&comp->cfg[partid], cfg))
 		return 0;
 
-- 
2.34.1



From benjamin.gaignard at collabora.com  Thu Dec 12 07:43:33 2024
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Thu, 12 Dec 2024 15:43:33 +0000
Subject: [PATCH v2 1/2] media: verisilicon: Store reference frames pixels format
In-Reply-To: <20241212154328.84904-1-benjamin.gaignard@collabora.com>
References: <20241212154328.84904-1-benjamin.gaignard@collabora.com>
Message-ID: <01020193bb8a2706-6355fcf8-dd11-4685-8d3f-512a19423599-000000@eu-west-1.amazonses.com>

Hantro decoder always produce tiled pixels formats but
when the post-processor is used the destination pixels
format is a non tiled pixels format. This led to compute
wrong reference frame size and offsets.
Getting and saving the correct tiled pixels format for 8
and 10 bit stream solve the computation issues.

Fluster VP9 score increase to 166/305 (vs 145/305).
HEVC score is still 141/147.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
Version 2:
- rebased on top of media-commiter/next
- Add reviewed-by tags

 drivers/media/platform/verisilicon/hantro.h   |  2 ++
 .../media/platform/verisilicon/hantro_g2.c    |  2 +-
 .../platform/verisilicon/hantro_postproc.c    | 32 +++++++------------
 .../media/platform/verisilicon/hantro_v4l2.c  | 21 ++++++++++++
 4 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h
index 811260dc3c77..14fc6a3e2878 100644
--- a/drivers/media/platform/verisilicon/hantro.h
+++ b/drivers/media/platform/verisilicon/hantro.h
@@ -227,6 +227,7 @@ struct hantro_dev {
  * @src_fmt:		V4L2 pixel format of active source format.
  * @vpu_dst_fmt:	Descriptor of active destination format.
  * @dst_fmt:		V4L2 pixel format of active destination format.
+ * @ref_fmt:		V4L2 pixel format of the reference frames format.
  *
  * @ctrl_handler:	Control handler used to register controls.
  * @jpeg_quality:	User-specified JPEG compression quality.
@@ -255,6 +256,7 @@ struct hantro_ctx {
 	struct v4l2_pix_format_mplane src_fmt;
 	const struct hantro_fmt *vpu_dst_fmt;
 	struct v4l2_pix_format_mplane dst_fmt;
+	struct v4l2_pix_format_mplane ref_fmt;
 
 	struct v4l2_ctrl_handler ctrl_handler;
 	int jpeg_quality;
diff --git a/drivers/media/platform/verisilicon/hantro_g2.c b/drivers/media/platform/verisilicon/hantro_g2.c
index 5c1d799d8618..aae0b562fabb 100644
--- a/drivers/media/platform/verisilicon/hantro_g2.c
+++ b/drivers/media/platform/verisilicon/hantro_g2.c
@@ -47,7 +47,7 @@ irqreturn_t hantro_g2_irq(int irq, void *dev_id)
 
 size_t hantro_g2_chroma_offset(struct hantro_ctx *ctx)
 {
-	return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8;
+	return ctx->ref_fmt.plane_fmt[0].bytesperline *	ctx->ref_fmt.height;
 }
 
 size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx)
diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c
index 232c93eea7ee..c435a393e0cb 100644
--- a/drivers/media/platform/verisilicon/hantro_postproc.c
+++ b/drivers/media/platform/verisilicon/hantro_postproc.c
@@ -194,35 +194,25 @@ void hantro_postproc_free(struct hantro_ctx *ctx)
 
 static unsigned int hantro_postproc_buffer_size(struct hantro_ctx *ctx)
 {
-	struct v4l2_pix_format_mplane pix_mp;
-	const struct hantro_fmt *fmt;
 	unsigned int buf_size;
 
-	/* this should always pick native format */
-	fmt = hantro_get_default_fmt(ctx, false, ctx->bit_depth, HANTRO_AUTO_POSTPROC);
-	if (!fmt)
-		return 0;
-
-	v4l2_fill_pixfmt_mp(&pix_mp, fmt->fourcc, ctx->src_fmt.width,
-			    ctx->src_fmt.height);
-
-	buf_size = pix_mp.plane_fmt[0].sizeimage;
+	buf_size = ctx->ref_fmt.plane_fmt[0].sizeimage;
 	if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
-		buf_size += hantro_h264_mv_size(pix_mp.width,
-						pix_mp.height);
+		buf_size += hantro_h264_mv_size(ctx->ref_fmt.width,
+						ctx->ref_fmt.height);
 	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME)
-		buf_size += hantro_vp9_mv_size(pix_mp.width,
-					       pix_mp.height);
+		buf_size += hantro_vp9_mv_size(ctx->ref_fmt.width,
+					       ctx->ref_fmt.height);
 	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE) {
-		buf_size += hantro_hevc_mv_size(pix_mp.width,
-						pix_mp.height);
+		buf_size += hantro_hevc_mv_size(ctx->ref_fmt.width,
+						ctx->ref_fmt.height);
 		if (ctx->hevc_dec.use_compression)
-			buf_size += hantro_hevc_compressed_size(pix_mp.width,
-								pix_mp.height);
+			buf_size += hantro_hevc_compressed_size(ctx->ref_fmt.width,
+								ctx->ref_fmt.height);
 	}
 	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME)
-		buf_size += hantro_av1_mv_size(pix_mp.width,
-					       pix_mp.height);
+		buf_size += hantro_av1_mv_size(ctx->ref_fmt.width,
+					       ctx->ref_fmt.height);
 
 	return buf_size;
 }
diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c
index 2513adfbd825..2bce940a5822 100644
--- a/drivers/media/platform/verisilicon/hantro_v4l2.c
+++ b/drivers/media/platform/verisilicon/hantro_v4l2.c
@@ -126,6 +126,24 @@ hantro_find_format(const struct hantro_ctx *ctx, u32 fourcc)
 	return NULL;
 }
 
+static int
+hantro_set_reference_frames_format(struct hantro_ctx *ctx)
+{
+	const struct hantro_fmt *fmt;
+	int dst_bit_depth = hantro_get_format_depth(ctx->vpu_dst_fmt->fourcc);
+
+	fmt = hantro_get_default_fmt(ctx, false, dst_bit_depth, HANTRO_AUTO_POSTPROC);
+	if (!fmt)
+		return -EINVAL;
+
+	ctx->ref_fmt.width = ctx->src_fmt.width;
+	ctx->ref_fmt.height = ctx->src_fmt.height;
+
+	v4l2_apply_frmsize_constraints(&ctx->ref_fmt.width, &ctx->ref_fmt.height, &fmt->frmsize);
+	return v4l2_fill_pixfmt_mp(&ctx->ref_fmt, fmt->fourcc,
+				   ctx->ref_fmt.width, ctx->ref_fmt.height);
+}
+
 const struct hantro_fmt *
 hantro_get_default_fmt(const struct hantro_ctx *ctx, bool bitstream,
 		       int bit_depth, bool need_postproc)
@@ -595,6 +613,9 @@ static int hantro_set_fmt_cap(struct hantro_ctx *ctx,
 
 	ctx->vpu_dst_fmt = hantro_find_format(ctx, pix_mp->pixelformat);
 	ctx->dst_fmt = *pix_mp;
+	ret = hantro_set_reference_frames_format(ctx);
+	if (ret)
+		return ret;
 
 	/*
 	 * Current raw format might have become invalid with newly
-- 
2.43.0



From benjamin.gaignard at collabora.com  Thu Dec 12 07:43:34 2024
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Thu, 12 Dec 2024 15:43:34 +0000
Subject: [PATCH v2 2/2] media: verisilicon: Fix IMX8 native pixels format steps values
In-Reply-To: <20241212154328.84904-1-benjamin.gaignard@collabora.com>
References: <20241212154328.84904-1-benjamin.gaignard@collabora.com>
Message-ID: <01020193bb8a2955-5c7c8665-b689-44bb-9119-b0e636e20840-000000@eu-west-1.amazonses.com>

Hantro decoder non post-processed pixels formats steps are different
from post-processed ones.
Fix the steps according to hardware limitation.
Since reference frame pixels format issue has been fix, it is possible
to use V4L2_PIX_FMT_NV15_4L4 rather V4L2_PIX_FMT_P010_4L4 for 10bits
streams.

Fluster VP9 score goes up to 207/305.
HEVC score is still 141/147.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
Version 2:
- rebased on top of media-commiter/next
- Add reviewed-by tags

 drivers/media/platform/verisilicon/imx8m_vpu_hw.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
index f850d8bddef6..35799da534ed 100644
--- a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
+++ b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
@@ -187,23 +187,23 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
 		.frmsize = {
 			.min_width = FMT_MIN_WIDTH,
 			.max_width = FMT_UHD_WIDTH,
-			.step_width = TILE_MB_DIM,
+			.step_width = 8,
 			.min_height = FMT_MIN_HEIGHT,
 			.max_height = FMT_UHD_HEIGHT,
-			.step_height = TILE_MB_DIM,
+			.step_height = 32,
 		},
 	},
 	{
-		.fourcc = V4L2_PIX_FMT_P010_4L4,
+		.fourcc = V4L2_PIX_FMT_NV15_4L4,
 		.codec_mode = HANTRO_MODE_NONE,
 		.match_depth = true,
 		.frmsize = {
 			.min_width = FMT_MIN_WIDTH,
 			.max_width = FMT_UHD_WIDTH,
-			.step_width = TILE_MB_DIM,
+			.step_width = 8,
 			.min_height = FMT_MIN_HEIGHT,
 			.max_height = FMT_UHD_HEIGHT,
-			.step_height = TILE_MB_DIM,
+			.step_height = 32,
 		},
 	},
 	{
-- 
2.43.0



From benjamin.gaignard at collabora.com  Thu Dec 12 07:43:33 2024
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Thu, 12 Dec 2024 15:43:33 +0000
Subject: [PATCH v2 0/2] media: verisilicon: fix reference padding issue
Message-ID: <01020193bb8a24ad-99eafebb-3b0b-40c0-9b28-3a0dbc84327a-000000@eu-west-1.amazonses.com>

Hantro hardware is splited into two parts: the decoder which produce
tiled pixels formats and the post-processor which produce raster pixels
formats.
When post-processor is used the selected pixels format may not have the
some padding/stride than the decoder output pixels format. This led to
miscomputing chroma and motion vectors offsets so data are overlapping.
This series introduce a reference pixels format that decoder use to
compute the various needed offsets and size.

With this series Fluster for VP9 tests is now 207/305 vs 145/305.
HEVC test score isn't impacted by these patches (still 141/147).

Version 2:
- rebased on top of media-commiter/next
- Add reviewed-by tags

Benjamin Gaignard (2):
  media: verisilicon: Store reference frames pixels format
  media: verisilicon: Fix IMX8 native pixels format steps values

 drivers/media/platform/verisilicon/hantro.h   |  2 ++
 .../media/platform/verisilicon/hantro_g2.c    |  2 +-
 .../platform/verisilicon/hantro_postproc.c    | 32 +++++++------------
 .../media/platform/verisilicon/hantro_v4l2.c  | 21 ++++++++++++
 .../media/platform/verisilicon/imx8m_vpu_hw.c | 10 +++---
 5 files changed, 40 insertions(+), 27 deletions(-)

-- 
2.43.0



From tudor.ambarus at linaro.org  Thu Dec 12 07:43:44 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 15:43:44 +0000
Subject: [PATCH v4 0/3] mailbox: add Samsung Exynos driver
Message-ID: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>

The samsung exynos mailbox controller has 16 flag bits for hardware
interrupt generation and a shared register for passing mailbox messages.
When the controller is used by the ACPM protocol the shared register is
ignored and the mailbox controller acts as a doorbell. The controller
just raises the interrupt to APM after the ACPM protocol has written
the message to SRAM.

I mark this as v3 because it is a continuation of:
https://lore.kernel.org/linux-arm-kernel/20241017163649.3007062-1-tudor.ambarus at linaro.org/

Changes in v4:
- rename bindings file to be based on compatible: google,gs101-acpm-mbox
- specify doorbell or data mode via '#mbox-cells' dt property. Update
  driver and introduce exynos_mbox_of_xlate() to parse the mode.
- s/samsung/Samsung/, s/exynos/Exynos/
- use writel instead of writel_relaxed
- remove stray of_match_ptr() 

Changes in v3:
- decouple the mailbox controller driver from the ACPM protocol driver
- address Krzysztof's review comments

v2:
https://lore.kernel.org/linux-arm-kernel/20241017163649.3007062-1-tudor.ambarus at linaro.org/

v1:
https://lore.kernel.org/linux-arm-kernel/20241004165301.1979527-1-tudor.ambarus at linaro.org/

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Tudor Ambarus (3):
      dt-bindings: mailbox: add google,gs101-mbox bindings
      mailbox: add Samsung Exynos driver
      MAINTAINERS: add entry for Samsung Exynos mailbox driver

 .../bindings/mailbox/google,gs101-mbox.yaml        |  79 +++++++++
 MAINTAINERS                                        |  10 ++
 drivers/mailbox/Kconfig                            |  11 ++
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/exynos-mailbox.c                   | 184 +++++++++++++++++++++
 include/dt-bindings/mailbox/google,gs101.h         |  14 ++
 6 files changed, 300 insertions(+)
---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241212-acpm-v4-upstream-mbox-948714004b05

Best regards,
-- 
Tudor Ambarus <tudor.ambarus at linaro.org>



From tudor.ambarus at linaro.org  Thu Dec 12 07:43:46 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 15:43:46 +0000
Subject: [PATCH v4 2/3] mailbox: add Samsung Exynos driver
In-Reply-To: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>
References: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>
Message-ID: <20241212-acpm-v4-upstream-mbox-v4-2-02f8de92cfaf@linaro.org>

The Samsung Exynos mailbox controller has 16 flag bits for hardware
interrupt generation and a shared register for passing mailbox messages.
When the controller is used by the ACPM protocol the shared register is
ignored and the mailbox controller acts as a doorbell. The controller
just raises the interrupt to APM after the ACPM protocol has written
the message to SRAM.

Add support for the Samsung Exynos mailbox controller.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/mailbox/Kconfig          |  11 +++
 drivers/mailbox/Makefile         |   2 +
 drivers/mailbox/exynos-mailbox.c | 184 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 197 insertions(+)

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 8ecba7fb999e..44b808c4d97f 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -36,6 +36,17 @@ config ARM_MHU_V3
 	  that provides different means of transports: supported extensions
 	  will be discovered and possibly managed at probe-time.
 
+config EXYNOS_MBOX
+	tristate "Exynos Mailbox"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	help
+	  Say Y here if you want to build the Samsung Exynos Mailbox controller
+	  driver. The controller has 16 flag bits for hardware interrupt
+	  generation and a shared register for passing mailbox messages.
+	  When the controller is used by the ACPM protocol the shared register
+	  is ignored and the mailbox controller acts as a doorbell that raises
+	  the interrupt to the ACPM firmware.
+
 config IMX_MBOX
 	tristate "i.MX Mailbox"
 	depends on ARCH_MXC || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 5f4f5b0ce2cc..86192b5c7c32 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -11,6 +11,8 @@ obj-$(CONFIG_ARM_MHU_V2)	+= arm_mhuv2.o
 
 obj-$(CONFIG_ARM_MHU_V3)	+= arm_mhuv3.o
 
+obj-$(CONFIG_EXYNOS_MBOX)	+= exynos-mailbox.o
+
 obj-$(CONFIG_IMX_MBOX)	+= imx-mailbox.o
 
 obj-$(CONFIG_ARMADA_37XX_RWTM_MBOX)	+= armada-37xx-rwtm-mailbox.o
diff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c
new file mode 100644
index 000000000000..9d875806d0f9
--- /dev/null
+++ b/drivers/mailbox/exynos-mailbox.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#include <dt-bindings/mailbox/google,gs101.h>
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define EXYNOS_MBOX_MCUCTRL		0x0	/* Mailbox Control Register */
+#define EXYNOS_MBOX_INTCR0		0x24	/* Interrupt Clear Register 0 */
+#define EXYNOS_MBOX_INTMR0		0x28	/* Interrupt Mask Register 0 */
+#define EXYNOS_MBOX_INTSR0		0x2c	/* Interrupt Status Register 0 */
+#define EXYNOS_MBOX_INTMSR0		0x30	/* Interrupt Mask Status Register 0 */
+#define EXYNOS_MBOX_INTGR1		0x40	/* Interrupt Generation Register 1 */
+#define EXYNOS_MBOX_INTMR1		0x48	/* Interrupt Mask Register 1 */
+#define EXYNOS_MBOX_INTSR1		0x4c	/* Interrupt Status Register 1 */
+#define EXYNOS_MBOX_INTMSR1		0x50	/* Interrupt Mask Status Register 1 */
+
+#define EXYNOS_MBOX_INTMR0_MASK		GENMASK(15, 0)
+#define EXYNOS_MBOX_INTGR1_MASK		GENMASK(15, 0)
+
+#define EXYNOS_MBOX_CHAN_COUNT		HWEIGHT32(EXYNOS_MBOX_INTGR1_MASK)
+
+enum {
+	EXYNOS_MBOX_CELL_TYPE,
+	EXYNOS_MBOX_CELL_ID,
+	EXYNOS_MBOX_CELLS
+};
+
+#define EXYNOS_MBOX_CELL_TYPE_COUNT	2
+
+/**
+ * struct exynos_mbox - driver's private data.
+ * @regs:	mailbox registers base address.
+ * @mbox:	pointer to the mailbox controller.
+ * @dev:	pointer to the mailbox device.
+ * @pclk:	pointer to the mailbox peripheral clock.
+ */
+struct exynos_mbox {
+	void __iomem *regs;
+	struct mbox_controller *mbox;
+	struct device *dev;
+	struct clk *pclk;
+};
+
+static int exynos_mbox_chan_index(struct mbox_chan *chan)
+{
+	struct mbox_controller *mbox = chan->mbox;
+	int i;
+
+	for (i = 0; i < mbox->num_chans; i++)
+		if (chan == &mbox->chans[i])
+			return i;
+	return -EINVAL;
+}
+
+static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct exynos_mbox *exynos_mbox = dev_get_drvdata(chan->mbox->dev);
+	int index;
+
+	index = exynos_mbox_chan_index(chan);
+	if (index < 0)
+		return index;
+
+	writel(BIT(index), exynos_mbox->regs + EXYNOS_MBOX_INTGR1);
+
+	return 0;
+}
+
+static const struct mbox_chan_ops exynos_mbox_chan_ops = {
+	.send_data = exynos_mbox_send_data,
+};
+
+static struct mbox_chan *exynos_mbox_of_xlate(struct mbox_controller *mbox,
+					      const struct of_phandle_args *sp)
+{
+	u32 type, id;
+
+	if (sp->args_count != EXYNOS_MBOX_CELLS) {
+		dev_err(mbox->dev, "Invalid argument count %d\n",
+			sp->args_count);
+		return ERR_PTR(-EINVAL);
+	}
+
+	type = sp->args[EXYNOS_MBOX_CELL_TYPE];
+	if (type >= EXYNOS_MBOX_CELL_TYPE_COUNT) {
+		dev_err(mbox->dev, "Invalid channel type %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (type == DATA) {
+		dev_err(mbox->dev, "DATA channel type [%d] not supported\n",
+			type);
+		return ERR_PTR(-EINVAL);
+	};
+
+	id = sp->args[EXYNOS_MBOX_CELL_ID];
+	if (id >= mbox->num_chans) {
+		dev_err(mbox->dev, "Invalid channel ID %d\n", id);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return &mbox->chans[id];
+}
+
+static const struct of_device_id exynos_mbox_match[] = {
+	{ .compatible = "google,gs101-mbox" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos_mbox_match);
+
+static int exynos_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct exynos_mbox *exynos_mbox;
+	struct mbox_controller *mbox;
+	struct mbox_chan *chans;
+	int i;
+
+	exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL);
+	if (!exynos_mbox)
+		return -ENOMEM;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	chans = devm_kcalloc(dev, EXYNOS_MBOX_CHAN_COUNT, sizeof(*chans),
+			     GFP_KERNEL);
+	if (!chans)
+		return -ENOMEM;
+
+	exynos_mbox->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(exynos_mbox->regs))
+		return PTR_ERR(exynos_mbox->regs);
+
+	exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk");
+	if (IS_ERR(exynos_mbox->pclk))
+		return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk),
+				     "Failed to enable clock.\n");
+
+	mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT;
+	mbox->chans = chans;
+	mbox->dev = dev;
+	mbox->ops = &exynos_mbox_chan_ops;
+	mbox->of_xlate = exynos_mbox_of_xlate;
+
+	for (i = 0; i < EXYNOS_MBOX_CHAN_COUNT; i++)
+		chans[i].mbox = mbox;
+
+	exynos_mbox->dev = dev;
+	exynos_mbox->mbox = mbox;
+
+	platform_set_drvdata(pdev, exynos_mbox);
+
+	/* Mask out all interrupts. We support just polling channels for now. */
+	writel(EXYNOS_MBOX_INTMR0_MASK, exynos_mbox->regs + EXYNOS_MBOX_INTMR0);
+
+	return devm_mbox_controller_register(dev, mbox);
+}
+
+static struct platform_driver exynos_mbox_driver = {
+	.probe	= exynos_mbox_probe,
+	.driver	= {
+		.name = "exynos-acpm-mbox",
+		.of_match_table	= exynos_mbox_match,
+	},
+};
+module_platform_driver(exynos_mbox_driver);
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos mailbox driver");
+MODULE_LICENSE("GPL");

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec 12 07:43:45 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 15:43:45 +0000
Subject: [PATCH v4 1/3] dt-bindings: mailbox: add google,gs101-mbox
 bindings
In-Reply-To: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>
References: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>
Message-ID: <20241212-acpm-v4-upstream-mbox-v4-1-02f8de92cfaf@linaro.org>

Add bindings for the Samsung Exynos Mailbox Controller.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 .../bindings/mailbox/google,gs101-mbox.yaml        | 79 ++++++++++++++++++++++
 include/dt-bindings/mailbox/google,gs101.h         | 14 ++++
 2 files changed, 93 insertions(+)

diff --git a/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
new file mode 100644
index 000000000000..efc2f605acea
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright 2024 Linaro Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/google,gs101-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos Mailbox Controller
+
+maintainers:
+  - Tudor Ambarus <tudor.ambarus at linaro.org>
+
+description: |
+  The samsung exynos mailbox controller has 16 flag bits for hardware interrupt
+  generation and a shared register for passing mailbox messages. When the
+  controller is used by the ACPM protocol the shared register is ignored and
+  the mailbox controller acts as a doorbell. The controller just raises the
+  interrupt to the firmware after the ACPM protocol has written the message to
+  SRAM.
+
+properties:
+  compatible:
+    const: google,gs101-mbox
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: pclk
+
+  interrupts:
+    description: IRQ line for the RX mailbox.
+    maxItems: 1
+
+  '#mbox-cells':
+    description: |
+      <&phandle type channel>
+      phandle : label name of controller.
+      type    : channel type, doorbell or data-transfer.
+      channel : channel number.
+
+      Here is how a client can reference them:
+      mboxes = <&ap2apm_mailbox DOORBELL 2>;
+      mboxes = <&ap2apm_mailbox DATA 3>;
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - '#mbox-cells'
+
+additionalProperties: false
+
+examples:
+  # Doorbell mode.
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/google,gs101.h>
+
+    soc {
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        ap2apm_mailbox: mailbox at 17610000 {
+            compatible = "google,gs101-acpm-mbox";
+            reg = <0x17610000 0x1000>;
+            clocks = <&cmu_apm CLK_GOUT_APM_MAILBOX_APM_AP_PCLK>;
+            clock-names = "pclk";
+            interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 0>;
+            #mbox-cells = <2>;
+        };
+    };
diff --git a/include/dt-bindings/mailbox/google,gs101.h b/include/dt-bindings/mailbox/google,gs101.h
new file mode 100644
index 000000000000..7ff4fe669f9e
--- /dev/null
+++ b/include/dt-bindings/mailbox/google,gs101.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright 2024 Linaro Ltd.
+ *
+ * This header provides constants for the defined mailbox channel types.
+ */
+
+#ifndef _DT_BINDINGS_MAILBOX_GOOGLE_GS101_H
+#define _DT_BINDINGS_MAILBOX_GOOGLE_GS101_H
+
+#define DOORBELL	0
+#define DATA		1
+
+#endif /* _DT_BINDINGS_MAILBOX_GOOGLE_GS101_H */

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec 12 07:43:47 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 15:43:47 +0000
Subject: [PATCH v4 3/3] MAINTAINERS: add entry for Samsung Exynos mailbox
 driver
In-Reply-To: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>
References: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>
Message-ID: <20241212-acpm-v4-upstream-mbox-v4-3-02f8de92cfaf@linaro.org>

Add entry for the Samsung Exynos mailbox driver.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 17daa9ee9384..b3b472771476 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3023,6 +3023,7 @@ F:	drivers/*/*s3c24*
 F:	drivers/*/*s3c64xx*
 F:	drivers/*/*s5pv210*
 F:	drivers/clocksource/samsung_pwm_timer.c
+F:	drivers/mailbox/exynos-mailbox.c
 F:	drivers/memory/samsung/
 F:	drivers/pwm/pwm-samsung.c
 F:	drivers/soc/samsung/
@@ -20715,6 +20716,15 @@ F:	arch/arm64/boot/dts/exynos/exynos850*
 F:	drivers/clk/samsung/clk-exynos850.c
 F:	include/dt-bindings/clock/exynos850.h
 
+SAMSUNG EXYNOS MAILBOX DRIVER
+M:	Tudor Ambarus <tudor.ambarus at linaro.org>
+L:	linux-kernel at vger.kernel.org
+L:	linux-samsung-soc at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
+F:	drivers/mailbox/exynos-mailbox.c
+F:	include/dt-bindings/mailbox/google,gs101.h
+
 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 M:	Krzysztof Kozlowski <krzk at kernel.org>
 L:	linux-crypto at vger.kernel.org

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec 12 07:46:21 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 15:46:21 +0000
Subject: [PATCH v4 0/3] firmware: add Exynos ACPM protocol driver
Message-ID: <20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9@linaro.org>

Alive Clock and Power Manager (ACPM) Message Protocol is defined for
the purpose of communication between the ACPM firmware and masters
(AP, AOC, ...). ACPM firmware operates on the Active Power Management
(APM) module that handles overall power activities.

This protocol library provides the interface for all the client drivers
making use of the features offered by the APM. Add ACPM protocol support.

Changes in v4:
- rename bindings filename based on compatible
- bindings: drop nodename
- bindings: drop mboxes description
- bindings: remove initdata-base prop, and define it based on compatible
- bindings: move additionalProperties after the required block
- bindings: drop firmware node from examples
- bindings: drop unused label in examples
- bindings: rename node to power-management
- driver: switch 2 macros to inline functions for readability
- driver: add checl to avoid shift overflow on these inline functions
- driver: use ktime_to_ms(ktime_get()) to record ktime
- driver: use the default non-relaxed IO accessors
- driver: remove atomic handling
- driver: remove stray of_match_ptr()
- driver: move header in include/linux/firmware
- driver: make sure to, from are 32-bit aligned and count is a 32bit
  quantity before calling __{ioread, write}32_copy
- driver: reject IRQ channels (not supported yet_ at the top of do_xfer,
  instead of when waiting for response.

Changes in v3:
- decouple the mailbox controller driver from the ACPM protocol driver
- address Krzysztof's eview comments 
- add ACPM PMIC protocol helpers

v2:
https://lore.kernel.org/linux-arm-kernel/20241017163649.3007062-1-tudor.ambarus at linaro.org/

v1:
https://lore.kernel.org/linux-arm-kernel/20241004165301.1979527-1-tudor.ambarus at linaro.org/

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Tudor Ambarus (3):
      dt-bindings: firmware: add google,gs101-acpm-ipc binding
      firmware: add Exynos ACPM protocol driver
      MAINTAINERS: add entry for the Samsung Exynos ACPM mailbox protocol

 .../bindings/firmware/google,gs101-acpm-ipc.yaml   |  51 ++
 MAINTAINERS                                        |  10 +
 drivers/firmware/Kconfig                           |   1 +
 drivers/firmware/Makefile                          |   1 +
 drivers/firmware/samsung/Kconfig                   |  14 +
 drivers/firmware/samsung/Makefile                  |   4 +
 drivers/firmware/samsung/exynos-acpm-pmic.c        | 239 ++++++
 drivers/firmware/samsung/exynos-acpm-pmic.h        |  24 +
 drivers/firmware/samsung/exynos-acpm.c             | 800 +++++++++++++++++++++
 drivers/firmware/samsung/exynos-acpm.h             |  15 +
 .../linux/firmware/samsung/exynos-acpm-protocol.h  |  55 ++
 11 files changed, 1214 insertions(+)
---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241212-b4-acpm-v4-upstream-firmware-4633e1f9a0ab

Best regards,
-- 
Tudor Ambarus <tudor.ambarus at linaro.org>



From tudor.ambarus at linaro.org  Thu Dec 12 07:46:22 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 15:46:22 +0000
Subject: [PATCH v4 1/3] dt-bindings: firmware: add google,gs101-acpm-ipc
 binding
In-Reply-To: <20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9@linaro.org>
References: <20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9@linaro.org>
Message-ID: <20241212-b4-acpm-v4-upstream-firmware-v4-1-3f18ca64f1b9@linaro.org>

Add bindings for the Samsung Exynos ACPM mailbox protocol.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 .../bindings/firmware/google,gs101-acpm-ipc.yaml   | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
new file mode 100644
index 000000000000..8821325abcef
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2024 Linaro Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/google,gs101-acpm-ipc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos ACPM mailbox protocol
+
+maintainers:
+  - Tudor Ambarus <tudor.ambarus at linaro.org>
+
+description: |
+  ACPM (Alive Clock and Power Manager) is a firmware that operates on the
+  APM (Active Power Management) module that handles overall power management
+  activities. ACPM and masters regard each other as independent hardware
+  component and communicate with each other using mailbox messages and
+  shared memory.
+
+  This binding is intended to define the interface the firmware implementing
+  ACPM provides for OSPM in the device tree.
+
+properties:
+  compatible:
+    const: google,gs101-acpm-ipc
+
+  mboxes:
+    maxItems: 1
+
+  shmem:
+    description:
+      List of phandle pointing to the shared memory (SHM) area. The memory
+      contains channels configuration data and the TX/RX ring buffers that
+      are used for passing messages to/from the ACPM firmware.
+    maxItems: 1
+
+
+required:
+  - compatible
+  - mboxes
+  - shmem
+
+additionalProperties: false
+
+examples:
+  - |
+    power-management {
+        compatible = "google,gs101-acpm-ipc";
+        mboxes = <&ap2apm_mailbox 0>;
+        shmem = <&apm_sram>;
+    };

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec 12 07:46:24 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 15:46:24 +0000
Subject: [PATCH v4 3/3] MAINTAINERS: add entry for the Samsung Exynos ACPM
 mailbox protocol
In-Reply-To: <20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9@linaro.org>
References: <20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9@linaro.org>
Message-ID: <20241212-b4-acpm-v4-upstream-firmware-v4-3-3f18ca64f1b9@linaro.org>

Add entry for the Samsung Exynos ACPM mailbox protocol.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 17daa9ee9384..07d0a360cf66 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3023,6 +3023,7 @@ F:	drivers/*/*s3c24*
 F:	drivers/*/*s3c64xx*
 F:	drivers/*/*s5pv210*
 F:	drivers/clocksource/samsung_pwm_timer.c
+F:	drivers/firmware/samsung/
 F:	drivers/memory/samsung/
 F:	drivers/pwm/pwm-samsung.c
 F:	drivers/soc/samsung/
@@ -20715,6 +20716,15 @@ F:	arch/arm64/boot/dts/exynos/exynos850*
 F:	drivers/clk/samsung/clk-exynos850.c
 F:	include/dt-bindings/clock/exynos850.h
 
+SAMSUNG EXYNOS ACPM MAILBOX PROTOCOL
+M:	Tudor Ambarus <tudor.ambarus at linaro.org>
+L:	linux-kernel at vger.kernel.org
+L:	linux-samsung-soc at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
+F:	drivers/firmware/samsung/exynos-acpm*
+F:	include/linux/firmware/samsung/exynos-acpm-protocol.h
+
 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 M:	Krzysztof Kozlowski <krzk at kernel.org>
 L:	linux-crypto at vger.kernel.org

-- 
2.47.0.338.g60cca15819-goog



From tudor.ambarus at linaro.org  Thu Dec 12 07:46:23 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 15:46:23 +0000
Subject: [PATCH v4 2/3] firmware: add Exynos ACPM protocol driver
In-Reply-To: <20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9@linaro.org>
References: <20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9@linaro.org>
Message-ID: <20241212-b4-acpm-v4-upstream-firmware-v4-2-3f18ca64f1b9@linaro.org>

Alive Clock and Power Manager (ACPM) Message Protocol is defined for
the purpose of communication between the ACPM firmware and masters
(AP, AOC, ...). ACPM firmware operates on the Active Power Management
(APM) module that handles overall power activities.

ACPM and masters regard each other as independent hardware component and
communicate with each other using mailbox messages and shared memory.

This protocol library provides the interface for all the client drivers
making use of the features offered by the APM. Add ACPM protocol support.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/firmware/Kconfig                           |   1 +
 drivers/firmware/Makefile                          |   1 +
 drivers/firmware/samsung/Kconfig                   |  14 +
 drivers/firmware/samsung/Makefile                  |   4 +
 drivers/firmware/samsung/exynos-acpm-pmic.c        | 239 ++++++
 drivers/firmware/samsung/exynos-acpm-pmic.h        |  24 +
 drivers/firmware/samsung/exynos-acpm.c             | 800 +++++++++++++++++++++
 drivers/firmware/samsung/exynos-acpm.h             |  15 +
 .../linux/firmware/samsung/exynos-acpm-protocol.h  |  55 ++
 9 files changed, 1153 insertions(+)

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 71d8b26c4103..24edb956831b 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -267,6 +267,7 @@ source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/microchip/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/qcom/Kconfig"
+source "drivers/firmware/samsung/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
 source "drivers/firmware/tegra/Kconfig"
 source "drivers/firmware/xilinx/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 7a8d486e718f..91efcc868a05 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -33,6 +33,7 @@ obj-y				+= efi/
 obj-y				+= imx/
 obj-y				+= psci/
 obj-y				+= qcom/
+obj-y				+= samsung/
 obj-y				+= smccc/
 obj-y				+= tegra/
 obj-y				+= xilinx/
diff --git a/drivers/firmware/samsung/Kconfig b/drivers/firmware/samsung/Kconfig
new file mode 100644
index 000000000000..eed8cd8a677b
--- /dev/null
+++ b/drivers/firmware/samsung/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config EXYNOS_ACPM_PROTOCOL
+	tristate "Exynos Alive Clock and Power Manager (ACPM) Message Protocol"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	depends on EXYNOS_MBOX
+	help
+	  Alive Clock and Power Manager (ACPM) Message Protocol is defined for
+	  the purpose of communication between the ACPM firmware and masters
+	  (AP, AOC, ...). ACPM firmware operates on the Active Power Management
+	  (APM) module that handles overall power activities.
+
+	  This protocol library provides interface for all the client drivers
+	  making use of the features offered by the APM.
diff --git a/drivers/firmware/samsung/Makefile b/drivers/firmware/samsung/Makefile
new file mode 100644
index 000000000000..7b4c9f6f34f5
--- /dev/null
+++ b/drivers/firmware/samsung/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+acpm-protocol-objs			:= exynos-acpm.o exynos-acpm-pmic.o
+obj-$(CONFIG_EXYNOS_ACPM_PROTOCOL)	+= acpm-protocol.o
diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.c b/drivers/firmware/samsung/exynos-acpm-pmic.c
new file mode 100644
index 000000000000..dda5277556d1
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm-pmic.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+#include <linux/bitfield.h>
+#include <linux/firmware/samsung/exynos-acpm-protocol.h>
+#include <linux/ktime.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include "exynos-acpm.h"
+#include "exynos-acpm-pmic.h"
+
+#define ACPM_PMIC_CHANNEL		GENMASK(15, 12)
+#define ACPM_PMIC_TYPE			GENMASK(11, 8)
+#define ACPM_PMIC_REG			GENMASK(7, 0)
+
+#define ACPM_PMIC_RETURN		GENMASK(31, 24)
+#define ACPM_PMIC_MASK			GENMASK(23, 16)
+#define ACPM_PMIC_VALUE			GENMASK(15, 8)
+#define ACPM_PMIC_FUNC			GENMASK(7, 0)
+
+#define ACPM_PMIC_BULK_SHIFT		8
+#define ACPM_PMIC_BULK_MASK		GENMASK(7, 0)
+#define ACPM_PMIC_BULK_MAX_COUNT	8
+
+enum exynos_acpm_pmic_func {
+	ACPM_PMIC_READ,
+	ACPM_PMIC_WRITE,
+	ACPM_PMIC_UPDATE,
+	ACPM_PMIC_BULK_READ,
+	ACPM_PMIC_BULK_WRITE,
+};
+
+static inline u32 acpm_pmic_set_bulk(u32 data, unsigned int i)
+{
+	return (data & ACPM_PMIC_BULK_MASK) << (ACPM_PMIC_BULK_SHIFT * i);
+}
+
+static inline u32 acpm_pmic_get_bulk(u32 data, unsigned int i)
+{
+	return (data >> (ACPM_PMIC_BULK_SHIFT * i)) & ACPM_PMIC_BULK_MASK;
+}
+
+static void acpm_pmic_init_read_cmd(u32 *cmd, u8 type, u8 reg, u8 chan)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_READ);
+	cmd[3] = ktime_to_ms(ktime_get());
+}
+
+int acpm_pmic_read_reg(const struct acpm_handle *handle, int acpm_chan_id,
+		       u8 type, u8 reg, u8 chan, u8 *dest)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_read_cmd(cmd, type, reg, chan);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	*dest = FIELD_GET(ACPM_PMIC_VALUE, xfer.rx.cmd[1]);
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+static void acpm_pmic_init_bulk_read_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+					 u8 count)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_BULK_READ) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, count);
+}
+
+int acpm_pmic_bulk_read(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 count, u8 *buf)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int i, ret;
+
+	if (count > ACPM_PMIC_BULK_MAX_COUNT)
+		return -EINVAL;
+
+	acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	ret = FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < count; i++) {
+		if (i < 4)
+			buf[i] = acpm_pmic_get_bulk(xfer.rx.cmd[2], i);
+		else
+			buf[i] = acpm_pmic_get_bulk(xfer.rx.cmd[3], i - 4);
+	}
+
+	return 0;
+}
+
+static void acpm_pmic_init_write_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+				     u8 value)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_WRITE) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, value);
+	cmd[3] = ktime_to_ms(ktime_get());
+}
+
+int acpm_pmic_write_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 value)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_write_cmd(cmd, type, reg, chan, value);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+static void acpm_pmic_init_bulk_write_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+					  u8 count, u8 *buf)
+{
+	int i;
+
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_BULK_WRITE) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, count);
+
+	for (i = 0; i < count; i++) {
+		if (i < 4)
+			cmd[2] |= acpm_pmic_set_bulk(buf[i], i);
+		else
+			cmd[3] |= acpm_pmic_set_bulk(buf[i], i - 4);
+	}
+}
+
+int acpm_pmic_bulk_write(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 count, u8 *buf)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	if (count > ACPM_PMIC_BULK_MAX_COUNT)
+		return -EINVAL;
+
+	acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+static void acpm_pmic_init_update_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+				      u8 value, u8 mask)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_UPDATE) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, value) |
+		 FIELD_PREP(ACPM_PMIC_MASK, mask);
+	cmd[3] = ktime_to_ms(ktime_get());
+}
+
+int acpm_pmic_update_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 value, u8 mask)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask);
+
+	xfer.tx.cmd = cmd;
+	xfer.tx.len = sizeof(cmd);
+	xfer.rx.cmd = cmd;
+	xfer.rx.len = sizeof(cmd);
+	xfer.acpm_chan_id = acpm_chan_id;
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos ACPM mailbox PMIC protocol driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.h b/drivers/firmware/samsung/exynos-acpm-pmic.h
new file mode 100644
index 000000000000..c7ff5fdde25a
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm-pmic.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+#ifndef __EXYNOS_ACPM_MFD_H__
+#define __EXYNOS_ACPM_MFD_H__
+
+#include <linux/types.h>
+
+struct acpm_handle;
+
+int acpm_pmic_read_reg(const struct acpm_handle *handle, int acpm_chan_id,
+		       u8 type, u8 reg, u8 chan, u8 *dest);
+int acpm_pmic_bulk_read(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+int acpm_pmic_write_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 value);
+int acpm_pmic_bulk_write(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+int acpm_pmic_update_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 value, u8 mask);
+#endif /* __EXYNOS_ACPM_MFD_H__ */
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
new file mode 100644
index 000000000000..c82757d16b11
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -0,0 +1,800 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitmap.h>
+#include <linux/bits.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/firmware/samsung/exynos-acpm-protocol.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/math.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "exynos-acpm.h"
+#include "exynos-acpm-pmic.h"
+
+#define ACPM_PROTOCOL_SEQNUM		GENMASK(21, 16)
+
+/* The unit of counter is 20 us. 5000 * 20 = 100 ms */
+#define ACPM_POLL_TIMEOUT		5000
+#define ACPM_TX_TIMEOUT_US		500000
+
+#define ACPM_GS101_INITDATA_BASE	0xa000
+
+/**
+ * struct acpm_shmem - shared memory configuration information.
+ * @reserved:	unused fields.
+ * @chans:	offset to array of struct acpm_chan_shmem.
+ * @reserved1:	unused fields.
+ * @num_chans:	number of channels.
+ */
+struct acpm_shmem {
+	u32 reserved[2];
+	u32 chans;
+	u32 reserved1[3];
+	u32 num_chans;
+};
+
+/**
+ * struct acpm_chan_shmem - descriptor of a shared memory channel.
+ *
+ * @id:			channel ID.
+ * @reserved:		unused fields.
+ * @rx_rear:		rear pointer of APM RX queue (TX for AP).
+ * @rx_front:		front pointer of APM RX queue (TX for AP).
+ * @rx_base:		base address of APM RX queue (TX for AP).
+ * @reserved1:		unused fields.
+ * @tx_rear:		rear pointer of APM TX queue (RX for AP).
+ * @tx_front:		front pointer of APM TX queue (RX for AP).
+ * @tx_base:		base address of APM TX queue (RX for AP).
+ * @qlen:		queue length. Applies to both TX/RX queues.
+ * @mlen:		message length. Applies to both TX/RX queues.
+ * @reserved2:		unused fields.
+ * @poll_completion:	true when the channel works on polling.
+ */
+struct acpm_chan_shmem {
+	u32 id;
+	u32 reserved[3];
+	u32 rx_rear;
+	u32 rx_front;
+	u32 rx_base;
+	u32 reserved1[3];
+	u32 tx_rear;
+	u32 tx_front;
+	u32 tx_base;
+	u32 qlen;
+	u32 mlen;
+	u32 reserved2[2];
+	u32 poll_completion;
+};
+
+/**
+ * struct acpm_queue - exynos acpm queue.
+ *
+ * @rear:	rear address of the queue.
+ * @front:	front address of the queue.
+ * @base:	base address of the queue.
+ */
+struct acpm_queue {
+	void __iomem *rear;
+	void __iomem *front;
+	void __iomem *base;
+};
+
+/**
+ * struct acpm_rx_data - RX queue data.
+ *
+ * @cmd:	pointer to where the data shall be saved.
+ * @n_cmd:	number of 32-bit commands.
+ * @response:	true if the client expects the RX data.
+ */
+struct acpm_rx_data {
+	u32 *cmd;
+	size_t n_cmd;
+	bool response;
+};
+
+#define ACPM_SEQNUM_MAX    64
+
+/**
+ * struct acpm_chan - driver internal representation of a channel.
+ * @cl:		mailbox client.
+ * @chan:	mailbox channel.
+ * @acpm:	pointer to driver private data.
+ * @tx:		TX queue. The enqueue is done by the host.
+ *			- front index is written by the host.
+ *			- rear index is written by the firmware.
+ *
+ * @rx:		RX queue. The enqueue is done by the firmware.
+ *			- front index is written by the firmware.
+ *			- rear index is written by the host.
+ * @tx_lock:	protects TX queue.
+ * @rx_lock:	protects RX queue.
+ * @qlen:	queue length. Applies to both TX/RX queues.
+ * @mlen:	message length. Applies to both TX/RX queues.
+ * @seqnum:	sequence number of the last message enqueued on TX queue.
+ * @id:		channel ID.
+ * @poll_completion:	indicates if the transfer needs to be polled for
+ *			completion or interrupt mode is used.
+ * @bitmap_seqnum: bitmap that tracks the messages on the TX/RX queues.
+ * @rx_data:	internal buffer used to drain the RX queue.
+ */
+struct acpm_chan {
+	struct mbox_client cl;
+	struct mbox_chan *chan;
+	struct acpm_info *acpm;
+	struct acpm_queue tx;
+	struct acpm_queue rx;
+	struct mutex tx_lock;
+	struct mutex rx_lock;
+
+	unsigned int qlen;
+	unsigned int mlen;
+	u8 seqnum;
+	u8 id;
+	bool poll_completion;
+
+	DECLARE_BITMAP(bitmap_seqnum, ACPM_SEQNUM_MAX - 1);
+	struct acpm_rx_data rx_data[ACPM_SEQNUM_MAX];
+};
+
+/**
+ * struct acpm_info - driver's private data.
+ * @shmem:	pointer to the SRAM configuration data.
+ * @sram_base:	base address of SRAM.
+ * @chans:	pointer to the ACPM channel parameters retrieved from SRAM.
+ * @dev:	pointer to the exynos-acpm device.
+ * @handle:	instance of acpm_handle to send to clients.
+ * @node:	list head
+ * @num_chans:	number of channels available for this controller.
+ * @users:	number of users of this instance.
+ */
+struct acpm_info {
+	struct acpm_shmem __iomem *shmem;
+	void __iomem *sram_base;
+	struct acpm_chan *chans;
+	struct device *dev;
+	struct acpm_handle handle;
+	struct list_head node;
+	u32 num_chans;
+	/* protected by acpm_list_mutex */
+	int users;
+};
+
+/**
+ * struct acpm_match_data - of_device_id data.
+ * @initdata_base:	offset in SRAM where the channels configuration resides.
+ */
+struct acpm_match_data {
+	loff_t initdata_base;
+};
+
+#define client_to_acpm_chan(c) container_of(c, struct acpm_chan, cl)
+#define handle_to_acpm_info(h) container_of(h, struct acpm_info, handle)
+
+/* List of all ACPM devices active in system */
+static LIST_HEAD(acpm_list);
+/* Protection for the entire list */
+static DEFINE_MUTEX(acpm_list_mutex);
+
+static inline void acpm_memcpy_fromio32(void *to, const void __iomem *from,
+					size_t count)
+{
+	WARN_ON(!IS_ALIGNED((unsigned long)from, 4) ||
+		!IS_ALIGNED((unsigned long)to, 4) ||
+		count % 4);
+
+	__ioread32_copy(to, from, count / 4);
+}
+
+static inline void acpm_memcpy_toio32(void __iomem *to, const void *from,
+				      size_t count)
+{
+	WARN_ON(!IS_ALIGNED((unsigned long)to, 4) ||
+		!IS_ALIGNED((unsigned long)from, 4) ||
+		count % 4);
+
+	__iowrite32_copy(to, from, count / 4);
+}
+
+/**
+ * acpm_get_rx() - get response from RX queue.
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer to get response for.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_get_rx(struct acpm_chan *achan, struct acpm_xfer *xfer)
+{
+	struct acpm_msg *tx = &xfer->tx;
+	struct acpm_msg *rx = &xfer->rx;
+	struct acpm_rx_data *rx_data;
+	const void __iomem *base, *addr;
+	u32 rx_front, rx_seqnum, tx_seqnum, seqnum;
+	u32 i, val, mlen;
+	bool rx_set = false;
+
+	rx_front = readl(achan->rx.front);
+	i = readl(achan->rx.rear);
+
+	/* Bail out if RX is empty. */
+	if (i == rx_front)
+		return 0;
+
+	base = achan->rx.base;
+	mlen = achan->mlen;
+
+	tx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, tx->cmd[0]);
+
+	/* Drain RX queue. */
+	do {
+		/* Read RX seqnum. */
+		addr = base + mlen * i;
+		val = readl(addr);
+
+		rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, val);
+		if (!rx_seqnum)
+			return -EIO;
+		/*
+		 * mssg seqnum starts with value 1, whereas the driver considers
+		 * the first mssg at index 0.
+		 */
+		seqnum = rx_seqnum - 1;
+		rx_data = &achan->rx_data[seqnum];
+
+		if (rx_data->response) {
+			if (rx_seqnum == tx_seqnum) {
+				acpm_memcpy_fromio32(rx->cmd, addr, rx->len);
+				rx_set = true;
+				clear_bit(seqnum, achan->bitmap_seqnum);
+			} else {
+				/*
+				 * The RX data corresponds to another request.
+				 * Save the data to drain the queue, but don't
+				 * clear yet the bitmap. It will be cleared
+				 * after the response is copied to the request.
+				 */
+				acpm_memcpy_fromio32(rx_data->cmd, addr,
+						     rx->len);
+			}
+		} else {
+			clear_bit(seqnum, achan->bitmap_seqnum);
+		}
+
+		i = (i + 1) % achan->qlen;
+	} while (i != rx_front);
+
+	/* We saved all responses, mark RX empty. */
+	writel(rx_front, achan->rx.rear);
+
+	/*
+	 * If the response was not in this iteration of the queue, check if the
+	 * RX data was previously saved.
+	 */
+	rx_data = &achan->rx_data[tx_seqnum - 1];
+	if (!rx_set && rx_data->response) {
+		rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM,
+				      rx_data->cmd[0]);
+
+		if (rx_seqnum == tx_seqnum) {
+			memcpy(rx->cmd, rx_data->cmd, rx->len);
+			clear_bit(rx_seqnum - 1, achan->bitmap_seqnum);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * acpm_dequeue_by_polling() - RX dequeue by polling.
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer being waited for.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_dequeue_by_polling(struct acpm_chan *achan,
+				   struct acpm_xfer *xfer)
+{
+	struct device *dev = achan->acpm->dev;
+	struct acpm_msg *tx = &xfer->tx;
+	unsigned int cnt_20us = 0;
+	u32 seqnum;
+	int ret;
+
+	seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, tx->cmd[0]);
+
+	do {
+		mutex_lock(&achan->rx_lock);
+		ret = acpm_get_rx(achan, xfer);
+		mutex_unlock(&achan->rx_lock);
+		if (ret)
+			return ret;
+
+		if (!test_bit(seqnum - 1, achan->bitmap_seqnum))
+			return 0;
+
+		/* Determined experimentally. */
+		usleep_range(20, 30);
+		cnt_20us++;
+	} while (cnt_20us < ACPM_POLL_TIMEOUT);
+
+	dev_err(dev, "Timeout! ch:%u s:%u bitmap:%lx, cnt_20us = %d.\n",
+		achan->id, seqnum, achan->bitmap_seqnum[0], cnt_20us);
+
+	return -ETIME;
+}
+
+/**
+ * acpm_wait_for_queue_slots() - wait for queue slots.
+ *
+ * @achan:		ACPM channel info.
+ * @next_tx_front:	next front index of the TX queue.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_wait_for_queue_slots(struct acpm_chan *achan, u32 next_tx_front)
+{
+	u32 val, ret;
+
+	/*
+	 * Wait for RX front to keep up with TX front. Make sure there's at
+	 * least one element between them.
+	 */
+	ret = readl_poll_timeout(achan->rx.front, val, next_tx_front != val, 0,
+				 ACPM_TX_TIMEOUT_US);
+	if (ret) {
+		dev_err(achan->acpm->dev, "RX front can not keep up with TX front.\n");
+		return ret;
+	}
+
+	ret = readl_poll_timeout(achan->tx.rear, val, next_tx_front != val, 0,
+				 ACPM_TX_TIMEOUT_US);
+	if (ret)
+		dev_err(achan->acpm->dev, "TX queue is full.\n");
+
+	return ret;
+}
+
+/**
+ * acpm_prepare_xfer() - prepare a transfer before writing the message to the
+ * TX queue.
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer being prepared.
+ */
+static void acpm_prepare_xfer(struct acpm_chan *achan, struct acpm_xfer *xfer)
+{
+	struct acpm_msg *tx = &xfer->tx;
+	struct acpm_rx_data *rx_data;
+
+	/* Prevent chan->seqnum from being re-used */
+	do {
+		if (++achan->seqnum == ACPM_SEQNUM_MAX)
+			achan->seqnum = 1;
+	} while (test_bit(achan->seqnum - 1, achan->bitmap_seqnum));
+
+	tx->cmd[0] |= FIELD_PREP(ACPM_PROTOCOL_SEQNUM, achan->seqnum);
+
+	/* Clear data for upcoming responses */
+	rx_data = &achan->rx_data[achan->seqnum - 1];
+	memset(rx_data->cmd, 0, sizeof(*rx_data->cmd) * rx_data->n_cmd);
+	if (xfer->rx.cmd)
+		rx_data->response = true;
+
+	/* Flag the index based on seqnum. (seqnum: 1~63, bitmap: 0~62) */
+	set_bit(achan->seqnum - 1, achan->bitmap_seqnum);
+}
+
+/**
+ * acpm_wait_for_message_response - an helper to group all possible ways of
+ * waiting for a synchronous message response.
+ *
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer being waited for.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_wait_for_message_response(struct acpm_chan *achan,
+					  struct acpm_xfer *xfer)
+{
+	/* Just polling mode supported for now. */
+	return acpm_dequeue_by_polling(achan, xfer);
+}
+
+/**
+ * acpm_do_xfer() - do one transfer.
+ * @handle:	pointer to the acpm handle.
+ * @xfer:	transfer to initiate and wait for response.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int acpm_do_xfer(const struct acpm_handle *handle, struct acpm_xfer *xfer)
+{
+	struct acpm_info *acpm = handle_to_acpm_info(handle);
+	struct acpm_chan *achan = &acpm->chans[xfer->acpm_chan_id];
+	struct acpm_msg *tx = &xfer->tx;
+	u32 idx, tx_front;
+	int ret;
+
+	if (!tx->cmd || tx->len > achan->mlen || xfer->rx.len > achan->mlen)
+		return -EINVAL;
+
+	if (!achan->poll_completion) {
+		dev_err(achan->acpm->dev, "Interrupt mode not supported\n");
+		return -EOPNOTSUPP;
+	}
+
+	mutex_lock(&achan->tx_lock);
+
+	tx_front = readl(achan->tx.front);
+	idx = (tx_front + 1) % achan->qlen;
+
+	ret = acpm_wait_for_queue_slots(achan, idx);
+	if (ret) {
+		mutex_unlock(&achan->tx_lock);
+		return ret;
+	}
+
+	acpm_prepare_xfer(achan, xfer);
+
+	/* Write TX command. */
+	acpm_memcpy_toio32(achan->tx.base + achan->mlen * tx_front, tx->cmd,
+			   tx->len);
+
+	/* Advance TX front. */
+	writel(idx, achan->tx.front);
+
+	mutex_unlock(&achan->tx_lock);
+
+	ret = mbox_send_message(achan->chan, xfer);
+	if (ret < 0)
+		return ret;
+
+	ret = acpm_wait_for_message_response(achan, xfer);
+
+	/*
+	 * NOTE: we might prefer not to need the mailbox ticker to manage the
+	 * transfer queueing since the protocol layer queues things by itself.
+	 * Unfortunately, we have to kick the mailbox framework after we have
+	 * received our message.
+	 */
+	mbox_client_txdone(achan->chan, ret);
+
+	return ret;
+}
+
+/**
+ * acpm_put_handle() - release the handle acquired by acpm_get_by_phandle.
+ * @handle:	Handle acquired by acpm_get_by_phandle.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_put_handle(const struct acpm_handle *handle)
+{
+	struct acpm_info *acpm;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	acpm = handle_to_acpm_info(handle);
+	mutex_lock(&acpm_list_mutex);
+	if (!WARN_ON(!acpm->users))
+		acpm->users--;
+	mutex_unlock(&acpm_list_mutex);
+
+	return 0;
+}
+
+/**
+ * devm_acpm_release() - devres release method.
+ * @dev: pointer to device.
+ * @res: pointer to resource.
+ */
+static void devm_acpm_release(struct device *dev, void *res)
+{
+	const struct acpm_handle **ptr = res;
+	const struct acpm_handle *handle = *ptr;
+	int ret;
+
+	ret = acpm_put_handle(handle);
+	if (ret)
+		dev_err(dev, "failed to put handle %d\n", ret);
+}
+
+/**
+ * acpm_get_by_phandle() - get the ACPM handle using DT phandle.
+ * @np:		device node.
+ * @property:	property name containing phandle on ACPM node.
+ *
+ * Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
+ */
+static const struct acpm_handle *acpm_get_by_phandle(struct device_node *np,
+						     const char *property)
+{
+	struct acpm_handle *handle = NULL;
+	struct device_node *acpm_np;
+	struct acpm_info *info;
+
+	if (!np) {
+		pr_err("I need a device pointer\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	acpm_np = of_parse_phandle(np, property, 0);
+	if (!acpm_np)
+		return ERR_PTR(-ENODEV);
+
+	mutex_lock(&acpm_list_mutex);
+	list_for_each_entry(info, &acpm_list, node) {
+		if (acpm_np == info->dev->of_node) {
+			handle = &info->handle;
+			info->users++;
+			break;
+		}
+	}
+	mutex_unlock(&acpm_list_mutex);
+	of_node_put(acpm_np);
+
+	if (!handle)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return handle;
+}
+
+/**
+ * devm_acpm_get_by_phandle() - managed get handle using phandle.
+ * @dev:	device pointer requesting ACPM handle.
+ * @property:	property name containing phandle on ACPM node.
+ *
+ * Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
+ */
+const struct acpm_handle *devm_acpm_get_by_phandle(struct device *dev,
+						   const char *property)
+{
+	const struct acpm_handle *handle;
+	const struct acpm_handle **ptr;
+
+	ptr = devres_alloc(devm_acpm_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+	handle = acpm_get_by_phandle(dev_of_node(dev), property);
+
+	if (!IS_ERR(handle)) {
+		*ptr = handle;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return handle;
+}
+EXPORT_SYMBOL_GPL(devm_acpm_get_by_phandle);
+
+/**
+ * acpm_chan_shmem_get_params() - get channel parameters and addresses of the
+ * TX/RX queues.
+ * @achan:	ACPM channel info.
+ * @chan_shmem:	__iomem pointer to a channel described in shared memory.
+ */
+static void acpm_chan_shmem_get_params(struct acpm_chan *achan,
+				struct acpm_chan_shmem __iomem *chan_shmem)
+{
+	void __iomem *base = achan->acpm->sram_base;
+	struct acpm_queue *rx = &achan->rx;
+	struct acpm_queue *tx = &achan->tx;
+
+	achan->mlen = readl(&chan_shmem->mlen);
+	achan->poll_completion = readl(&chan_shmem->poll_completion);
+	achan->id = readl(&chan_shmem->id);
+	achan->qlen = readl(&chan_shmem->qlen);
+
+	tx->base = base + readl(&chan_shmem->rx_base);
+	tx->rear = base + readl(&chan_shmem->rx_rear);
+	tx->front = base + readl(&chan_shmem->rx_front);
+
+	rx->base = base + readl(&chan_shmem->tx_base);
+	rx->rear = base + readl(&chan_shmem->tx_rear);
+	rx->front = base + readl(&chan_shmem->tx_front);
+
+	dev_vdbg(achan->acpm->dev, "ID = %d poll = %d, mlen = %d, qlen = %d\n",
+		 achan->id, achan->poll_completion, achan->mlen, achan->qlen);
+}
+
+/**
+ * acpm_achan_alloc_cmds() - allocate buffers for retrieving data from the ACPM
+ * firmware.
+ * @achan:	ACPM channel info.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_achan_alloc_cmds(struct acpm_chan *achan)
+{
+	struct device *dev = achan->acpm->dev;
+	struct acpm_rx_data *rx_data;
+	size_t cmd_size, n_cmd;
+	int i;
+
+	if (achan->mlen == 0)
+		return 0;
+
+	cmd_size = sizeof(*(achan->rx_data[0].cmd));
+	n_cmd = DIV_ROUND_UP_ULL(achan->mlen, cmd_size);
+
+	for (i = 0; i < ACPM_SEQNUM_MAX; i++) {
+		rx_data = &achan->rx_data[i];
+		rx_data->n_cmd = n_cmd;
+		rx_data->cmd = devm_kcalloc(dev, n_cmd, cmd_size, GFP_KERNEL);
+		if (!rx_data->cmd)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * acpm_free_mbox_chans() - free mailbox channels.
+ * @acpm:	pointer to driver data.
+ */
+static void acpm_free_mbox_chans(struct acpm_info *acpm)
+{
+	int i;
+
+	for (i = 0; i < acpm->num_chans; i++)
+		mbox_free_channel(acpm->chans[i].chan);
+}
+
+/**
+ * acpm_channels_init() - initialize channels based on the configuration data in
+ * the shared memory.
+ * @acpm:	pointer to driver data.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_channels_init(struct acpm_info *acpm)
+{
+	struct acpm_shmem __iomem *shmem = acpm->shmem;
+	struct acpm_chan_shmem __iomem *chans_shmem;
+	struct device *dev = acpm->dev;
+	int i, ret;
+
+	acpm->num_chans = readl(&shmem->num_chans);
+	acpm->chans = devm_kcalloc(dev, acpm->num_chans, sizeof(*acpm->chans),
+				   GFP_KERNEL);
+	if (!acpm->chans)
+		return -ENOMEM;
+
+	chans_shmem = acpm->sram_base + readl(&shmem->chans);
+
+	for (i = 0; i < acpm->num_chans; i++) {
+		struct acpm_chan_shmem __iomem *chan_shmem = &chans_shmem[i];
+		struct acpm_chan *achan = &acpm->chans[i];
+		struct mbox_client *cl = &achan->cl;
+
+		achan->acpm = acpm;
+
+		acpm_chan_shmem_get_params(achan, chan_shmem);
+
+		ret = acpm_achan_alloc_cmds(achan);
+		if (ret)
+			return ret;
+
+		mutex_init(&achan->rx_lock);
+		mutex_init(&achan->tx_lock);
+
+		cl->dev = dev;
+
+		achan->chan = mbox_request_channel(cl, achan->id);
+		if (IS_ERR(achan->chan)) {
+			acpm_free_mbox_chans(acpm);
+			return PTR_ERR(achan->chan);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * acpm_setup_ops() - setup the operations structures.
+ * @acpm:	pointer to the driver data.
+ */
+static void acpm_setup_ops(struct acpm_info *acpm)
+{
+	struct acpm_pmic_ops *pmic_ops = &acpm->handle.ops.pmic_ops;
+
+	pmic_ops->read_reg = acpm_pmic_read_reg;
+	pmic_ops->bulk_read = acpm_pmic_bulk_read;
+	pmic_ops->write_reg = acpm_pmic_write_reg;
+	pmic_ops->bulk_write = acpm_pmic_bulk_write;
+	pmic_ops->update_reg = acpm_pmic_update_reg;
+}
+
+static int acpm_probe(struct platform_device *pdev)
+{
+	const struct acpm_match_data *match_data;
+	struct device *dev = &pdev->dev;
+	struct device_node *shmem;
+	struct acpm_info *acpm;
+	resource_size_t size;
+	struct resource res;
+	int ret;
+
+	acpm = devm_kzalloc(dev, sizeof(*acpm), GFP_KERNEL);
+	if (!acpm)
+		return -ENOMEM;
+
+	shmem = of_parse_phandle(dev->of_node, "shmem", 0);
+	ret = of_address_to_resource(shmem, 0, &res);
+	of_node_put(shmem);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get shared memory.\n");
+
+	size = resource_size(&res);
+	acpm->sram_base = devm_ioremap(dev, res.start, size);
+	if (!acpm->sram_base)
+		return dev_err_probe(dev, -ENOMEM,
+				     "Failed to ioremap shared memory.\n");
+
+	match_data = of_device_get_match_data(dev);
+	if (!match_data)
+		return dev_err_probe(dev, -EINVAL,
+				     "Faile to get match data.\n");
+
+	acpm->shmem = acpm->sram_base + match_data->initdata_base;
+	acpm->dev = dev;
+
+	ret = acpm_channels_init(acpm);
+	if (ret)
+		return ret;
+
+	acpm_setup_ops(acpm);
+
+	INIT_LIST_HEAD(&acpm->node);
+	mutex_lock(&acpm_list_mutex);
+	list_add_tail(&acpm->node, &acpm_list);
+	mutex_unlock(&acpm_list_mutex);
+
+	platform_set_drvdata(pdev, acpm);
+
+	return 0;
+}
+
+static const struct acpm_match_data acpm_gs101 = {
+	.initdata_base = ACPM_GS101_INITDATA_BASE,
+};
+
+static const struct of_device_id acpm_match[] = {
+	{
+		.compatible = "google,gs101-acpm-ipc",
+		.data = &acpm_gs101,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, acpm_match);
+
+static struct platform_driver acpm_driver = {
+	.probe	= acpm_probe,
+	.driver	= {
+		.name = "exynos-acpm-protocol",
+		.of_match_table	= acpm_match,
+	},
+};
+module_platform_driver(acpm_driver);
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos ACPM mailbox protocol driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h
new file mode 100644
index 000000000000..a03adcd260f5
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+#ifndef __EXYNOS_ACPM_H__
+#define __EXYNOS_ACPM_H__
+
+struct acpm_handle;
+struct acpm_xfer;
+
+int acpm_do_xfer(const struct acpm_handle *handle, struct acpm_xfer *xfer);
+
+#endif /* __EXYNOS_ACPM_H__ */
diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h
new file mode 100644
index 000000000000..f834af20cef8
--- /dev/null
+++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#ifndef __EXYNOS_ACPM_PROTOCOL_H
+#define __EXYNOS_ACPM_PROTOCOL_H
+
+#include <linux/types.h>
+
+struct acpm_msg {
+	u32 *cmd;
+	size_t len;
+};
+
+struct acpm_xfer {
+	struct acpm_msg tx;
+	struct acpm_msg rx;
+	int acpm_chan_id;
+};
+
+struct acpm_handle;
+
+struct acpm_pmic_ops {
+	int (*read_reg)(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 *dest);
+	int (*bulk_read)(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+	int (*write_reg)(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 value);
+	int (*bulk_write)(const struct acpm_handle *handle, int acpm_chan_id,
+			  u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+	int (*update_reg)(const struct acpm_handle *handle, int acpm_chan_id,
+			  u8 type, u8 reg, u8 chan, u8 value, u8 mask);
+};
+
+struct acpm_ops {
+	struct acpm_pmic_ops pmic_ops;
+};
+
+/**
+ * struct acpm_handle - Reference to an initialized protocol instance
+ * @ops:
+ */
+struct acpm_handle {
+	struct acpm_ops ops;
+};
+
+struct device;
+
+const struct acpm_handle *devm_acpm_get_by_phandle(struct device *dev,
+						   const char *property);
+#endif /* __EXYNOS_ACPM_PROTOCOL_H */

-- 
2.47.0.338.g60cca15819-goog



From maz at kernel.org  Thu Dec 12 07:48:47 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Dec 2024 15:48:47 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <2b1cc228-a8d5-4383-ab25-abbbcccd2e2c@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
	<20241211160218.41404-3-miko.lenczewski@arm.com>
	<87cyhxs3xq.wl-maz@kernel.org>
	<084c5ada-51af-4c1a-b50a-4401e62ddbd6@arm.com>
	<86ikrprn7w.wl-maz@kernel.org>
	<2b1cc228-a8d5-4383-ab25-abbbcccd2e2c@arm.com>
Message-ID: <86h678sy00.wl-maz@kernel.org>

On Thu, 12 Dec 2024 15:05:24 +0000,
Ryan Roberts <ryan.roberts at arm.com> wrote:
> 
> On 12/12/2024 14:26, Marc Zyngier wrote:
> > On Thu, 12 Dec 2024 10:55:45 +0000,
> > Ryan Roberts <ryan.roberts at arm.com> wrote:
> >>
> >> On 12/12/2024 08:25, Marc Zyngier wrote:
> >>>> +
> >>>> +	local_flush_tlb_all();
> >>>
> >>> The elephant in the room: if TLBs are in such a sorry state, what
> >>> guarantees we can make it this far?
> >>
> >> I'll leave Miko to respond to your other comments, but I wanted to address this
> >> one, since it's pretty fundamental. We went around this loop internally and
> >> concluded that what we are doing is architecturally sound.
> >>
> >> The expectation is that a conflict abort can only be generated as a result of
> >> the change in patch 4 (and patch 5). That change makes it possible for the TLB
> >> to end up with a multihit. But crucially that can only happen for user space
> >> memory because that change only operates on user memory. And while the TLB may
> >> detect the conflict at any time, the conflict abort is only permitted to be
> >> reported when an architectural access is prevented by the conflict. So we never
> >> do anything that would allow a conflict for a kernel memory access and a user
> >> memory conflict abort can never be triggered as a result of accessing kernel memory.
> >>
> >> Copy/pasting comment from AlexC on the topic, which explains it better than I can:
> >>
> >> """
> >> The intent is certainly that in cases where the hardware detects a TLB conflict
> >> abort, it is only permitted to report it (by generating an exception) if it
> >> applies to an access that is being attempted architecturally. ... that property
> >> can be built from the following two properties:
> >>
> >> 1. The TLB conflict can only be reported as an Instruction Abort or a Data Abort
> >>
> >> 2. Those two exception types must be reported synchronously and precisely.
> >> """
> > 
> > I totally agree with this. The issue is that nothing says that the
> > abort is in any way related to userspace.
> > 
> >>>
> >>> I honestly don't think you can reliably handle a TLB Conflict abort in
> >>> the same translation regime as the original fault, given that we don't
> >>> know the scope of that fault. You are probably making an educated
> >>> guess that it is good enough on the CPUs you know of, but I don't see
> >>> anything in the architecture that indicates the "blast radius" of a
> >>> TLB conflict.
> >>
> >> OK, so I'm claiming that the blast radius is limited to the region of memory
> >> that we are operating on in contpte_collapse() in patch 4. Perhaps we need to go
> >> re-read the ARM and come back with the specific statements that led us to that
> >> conclusion?
> 
> From the ARM:
> """
> RFCPSG: If level 1 or level 2 is supported and the Contiguous bit in a set of
> Block descriptors or Page descriptors is changed, then a TLB conflict abort can
> be generated because multiple translation table entries might exist within a TLB
> that translates the same IA.
> """
> 
> Although I guess it's not totally explicit, I've interpretted that as saying
> that conflicting TLB entries can only arise for the IA range for which the
> contiguous bits have been modified in the translation tables.

Right, that's reassuring, thanks for digging that one.

> Given we are only fiddling with the contiguous bits for user space mappings in
> this way, that's why I'm asserting we will only get a conflict abort for user
> space mappings... assuming the absence of kernel bugs, anyway...

For now. But if you dare scanning the list, you'll find a lot of
people willing to do far more than just that. Including changing the
shape of the linear map.

>
> > 
> > But we don't know for sure what caused this conflict by the time we
> > arrive in the handler. It could equally be because we have a glaring
> > bug somewhere on the kernel side, even if you are *now* only concerned
> > with userspace.
> 
> OK I see what you are saying; previously a conflict abort would have led to
> calling do_bad(), which returns 1, which causes do_mem_abort() to either kill
> the kernel or the process depending on the origin of the abort. (although if it
> came from kernel due to bug, we're just hoping that the conflict doesn't affect
> the path through the handler). With this change, we always assume we can fix it
> with the TLBI.
> 
> How about this change to ensure we still die for issues originating from the kernel?
> 
> if (!user_mode(regs) || !system_supports_bbml2())
> 		return do_bad(far, esr, regs);

That wouldn't catch a TLB conflict on get_user(), would it?

> > If anything, this should absolutely check for FAR_EL1 and assert that
> > this is indeed caused by such change.
> 
> I'm not really sure how we would check this reliably? Without patch 5, the
> problem is somewhat constrained; we could have as many changes in flight as
> there are CPUs so we could keep a list of all the {mm_struct, VA-range} that are
> being modified. But if patch 5 is confirmed to be architecturally sound, then
> there is no "terminating tlbi" so there is no bound on the set of {mm_struct,
> VA-range}'s that could legitimately cause a conflict abort.

I didn't mean to imply that we should identify the exact cause of the
abort. I was hoping to simply check that FAR_EL1 reports a userspace
VA. Why wouldn't that work?

	M.

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


From kevin_chen at aspeedtech.com  Thu Dec 12 07:52:29 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Thu, 12 Dec 2024 23:52:29 +0800
Subject: [PATCH v3 0/6] Introduce ASPEED AST27XX BMC SoC
Message-ID: <20241212155237.848336-1-kevin_chen@aspeedtech.com>

---
v3:
  - Split clk and reset driver to other commits, which are in series of
    "Add support for AST2700 clk driver".
  - For BMC console by UART12, add uart12 using ASPEED INTC architecture.

aspeed,ast2700-intc.yaml
  - Add minItems to 1 to fix the warning by "make dtbs_check W=1".
  - Add intc1 into example.

Kconfig.platforms
  - Remove MACH_ASPEED_G7.

Kevin Chen (6):
  dt-bindings: interrupt-controller: Refine size/interrupt-cell usage.
  dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
  arm64: aspeed: Add support for ASPEED AST27XX BMC SoC
  arm64: dts: aspeed: Add initial AST27XX device tree
  arm64: dts: aspeed: Add initial AST2700 EVB device tree
  arm64: defconfig: Add ASPEED AST2700 family support

 .../bindings/arm/aspeed/aspeed.yaml           |   6 +
 .../aspeed,ast2700-intc.yaml                  |  60 ++++-
 MAINTAINERS                                   |   1 +
 arch/arm64/Kconfig.platforms                  |   6 +
 arch/arm64/boot/dts/Makefile                  |   1 +
 arch/arm64/boot/dts/aspeed/Makefile           |   4 +
 arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi     | 236 ++++++++++++++++++
 arch/arm64/boot/dts/aspeed/ast2700-evb.dts    |  57 +++++
 arch/arm64/configs/defconfig                  |   1 +
 9 files changed, 359 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm64/boot/dts/aspeed/Makefile
 create mode 100644 arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi
 create mode 100644 arch/arm64/boot/dts/aspeed/ast2700-evb.dts

-- 
2.34.1



From kevin_chen at aspeedtech.com  Thu Dec 12 07:52:30 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Thu, 12 Dec 2024 23:52:30 +0800
Subject: [PATCH v3 1/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
In-Reply-To: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
Message-ID: <20241212155237.848336-2-kevin_chen@aspeedtech.com>

Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
---
 Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 2f92b8ab08fa..600424929df9 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -8,6 +8,7 @@ title: Aspeed SoC based boards
 
 maintainers:
   - Joel Stanley <joel at jms.id.au>
+  - Kevin Chen <kevin_chen at aspeedtech.com>
 
 properties:
   $nodename:
@@ -101,4 +102,10 @@ properties:
               - ufispace,ncplite-bmc
           - const: aspeed,ast2600
 
+      - description: AST2700 based boards
+        items:
+          - enum:
+              - aspeed,ast2700-evb
+          - const: aspeed,ast2700
+
 additionalProperties: true
-- 
2.34.1



From kevin_chen at aspeedtech.com  Thu Dec 12 07:52:31 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Thu, 12 Dec 2024 23:52:31 +0800
Subject: [PATCH v3 1/6] dt-bindings: interrupt-controller: Refine size/interrupt-cell usage.
In-Reply-To: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
Message-ID: <20241212155237.848336-3-kevin_chen@aspeedtech.com>

1. Because size-cells is no need to use 2, modify to 1 for use.
2. Add minItems to 1 for interrupts for intc1.
3. Add 1 interrupt of intc1 example into yaml file.
4. Add intc1 sub-module of uart12 as example using the intc0 and intc1.
---
 .../aspeed,ast2700-intc.yaml                  | 60 +++++++++++++++----
 1 file changed, 47 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
index 55636d06a674..eadfbc45326b 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
@@ -31,6 +31,7 @@ properties:
       type as defined in interrupt.txt in this directory.
 
   interrupts:
+    minItems: 1
     maxItems: 6
     description: |
       Depend to which INTC0 or INTC1 used.
@@ -68,19 +69,52 @@ examples:
     #include <dt-bindings/interrupt-controller/arm-gic.h>
 
     bus {
+      #address-cells = <2>;
+      #size-cells = <1>;
+
+      intc0: interrupt-controller at 12100000 {
+        compatible = "simple-mfd";
+        reg = <0 0x12100000 0x4000>;
+        ranges = <0x0 0x0 0x0 0x12100000 0x4000>;
         #address-cells = <2>;
-        #size-cells = <2>;
-
-        interrupt-controller at 12101b00 {
-            compatible = "aspeed,ast2700-intc-ic";
-            reg = <0 0x12101b00 0 0x10>;
-            #interrupt-cells = <2>;
-            interrupt-controller;
-            interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+        #size-cells = <1>;
+
+        intc0_11: interrupt-controller at 1b00 {
+          compatible = "aspeed,ast2700-intc-ic";
+          reg = <0 0x12101b00 0x10>;
+          #interrupt-cells = <2>;
+          interrupt-controller;
+          interrupts = <GIC_SPI 192 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                       <GIC_SPI 193 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                       <GIC_SPI 194 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                       <GIC_SPI 195 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                       <GIC_SPI 196 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                       <GIC_SPI 197 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
         };
+      };
+
+      intc1: interrupt-controller at 14c18000 {
+        compatible = "simple-mfd";
+        reg = <0 0x14c18000 0x400>;
+        ranges = <0x0 0x0 0x0 0x14c18000 0x400>;
+        #address-cells = <2>;
+        #size-cells = <1>;
+
+        intc1_4: interrupt-controller at 140 {
+          compatible = "aspeed,ast2700-intc-ic";
+          reg = <0x0 0x140 0x10>;
+          #interrupt-cells = <2>;
+          interrupt-controller;
+          interrupts-extended = <&intc0_11 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+        };
+      };
+
+      uart12: serial at 14c33b00 {
+        compatible = "ns16550a";
+        reg = <0x0 0x14c33b00 0x100>;
+        interrupts-extended = <&intc1_4 18 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+        reg-shift = <2>;
+        reg-io-width = <4>;
+        no-loopback-test;
+      };
     };
-- 
2.34.1



From kevin_chen at aspeedtech.com  Thu Dec 12 07:52:32 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Thu, 12 Dec 2024 23:52:32 +0800
Subject: [PATCH v3 2/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
In-Reply-To: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
Message-ID: <20241212155237.848336-4-kevin_chen@aspeedtech.com>

Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
---
 Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 2f92b8ab08fa..20191fee1f5b 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -101,4 +101,10 @@ properties:
               - ufispace,ncplite-bmc
           - const: aspeed,ast2600
 
+      - description: AST2700 based boards
+        items:
+          - enum:
+              - aspeed,ast2700-evb
+          - const: aspeed,ast2700
+
 additionalProperties: true
-- 
2.34.1



From kevin_chen at aspeedtech.com  Thu Dec 12 07:52:33 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Thu, 12 Dec 2024 23:52:33 +0800
Subject: [PATCH v3 2/6] dt-bindings: interrupt-controller: Fix the size-cells in ast2700-intc
In-Reply-To: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
Message-ID: <20241212155237.848336-5-kevin_chen@aspeedtech.com>

It is no need to let size-cells to 2 for the ASPEED AST27XX INTC. Modify
the ast2700-intc example usage.

Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
---
 .../bindings/interrupt-controller/aspeed,ast2700-intc.yaml    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
index 55636d06a674..69503aa638fb 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
@@ -69,11 +69,11 @@ examples:
 
     bus {
         #address-cells = <2>;
-        #size-cells = <2>;
+        #size-cells = <1>;
 
         interrupt-controller at 12101b00 {
             compatible = "aspeed,ast2700-intc-ic";
-            reg = <0 0x12101b00 0 0x10>;
+            reg = <0 0x12101b00 0x10>;
             #interrupt-cells = <2>;
             interrupt-controller;
             interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.34.1



From kevin_chen at aspeedtech.com  Thu Dec 12 07:52:34 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Thu, 12 Dec 2024 23:52:34 +0800
Subject: [PATCH v3 3/6] arm64: aspeed: Add support for ASPEED AST27XX BMC SoC
In-Reply-To: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
Message-ID: <20241212155237.848336-6-kevin_chen@aspeedtech.com>

Add ARCH_ASPEED in current arm64 architecture.

Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
---
 MAINTAINERS                  | 1 +
 arch/arm64/Kconfig.platforms | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 17daa9ee9384..c6d04cea43d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2261,6 +2261,7 @@ Q:	https://patchwork.ozlabs.org/project/linux-aspeed/list/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joel/bmc.git
 F:	Documentation/devicetree/bindings/arm/aspeed/
 F:	arch/arm/boot/dts/aspeed/
+F:	arch/arm64/boot/dts/aspeed/
 F:	arch/arm/mach-aspeed/
 N:	aspeed
 
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 370a9d2b6919..894b80434776 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -40,6 +40,12 @@ config ARCH_APPLE
 	  This enables support for Apple's in-house ARM SoC family, such
 	  as the Apple M1.
 
+config ARCH_ASPEED
+	bool "Aspeed SoC family"
+	help
+	  Say yes if you intend to run on an Aspeed ast2700 or similar
+	  seventh generation Aspeed BMCs.
+
 menuconfig ARCH_BCM
 	bool "Broadcom SoC Support"
 
-- 
2.34.1



From kevin_chen at aspeedtech.com  Thu Dec 12 07:52:35 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Thu, 12 Dec 2024 23:52:35 +0800
Subject: [PATCH v3 4/6] arm64: dts: aspeed: Add initial AST27XX device tree
In-Reply-To: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
Message-ID: <20241212155237.848336-7-kevin_chen@aspeedtech.com>

Add aspeed-g7.dtsi to be AST27XX device tree.

Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
---
 arch/arm64/boot/dts/Makefile              |   1 +
 arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi | 236 ++++++++++++++++++++++
 2 files changed, 237 insertions(+)
 create mode 100644 arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi

diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 21cd3a87f385..6a590a66e1a9 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -9,6 +9,7 @@ subdir-y += amlogic
 subdir-y += apm
 subdir-y += apple
 subdir-y += arm
+subdir-y += aspeed
 subdir-y += bitmain
 subdir-y += broadcom
 subdir-y += cavium
diff --git a/arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi b/arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi
new file mode 100644
index 000000000000..3f1e801dec4c
--- /dev/null
+++ b/arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <dt-bindings/clock/aspeed,ast2700-scu.h>
+#include <dt-bindings/reset/aspeed,ast2700-scu.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/aspeed-scu-ic.h>
+
+/ {
+	compatible = "aspeed,ast2700";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			i-cache-size = <0x8000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			enable-method = "psci";
+			reg = <0x0 0x1>;
+			i-cache-size = <0x8000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			enable-method = "psci";
+			reg = <0x0 0x2>;
+			i-cache-size = <0x8000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			enable-method = "psci";
+			reg = <0x0 0x3>;
+			i-cache-size = <0x8000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2>;
+		};
+
+		l2: l2-cache0 {
+			compatible = "cache";
+			cache-level = <2>;
+			cache-unified;
+			cache-size = <0x80000>;
+			cache-line-size = <64>;
+			cache-sets = <1024>;
+		};
+	};
+
+	pmu {
+		compatible = "arm,cortex-a35-pmu";
+		interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+		arm,cpu-registers-not-fw-configured;
+		always-on;
+	};
+
+	soc0: soc at 10000000 {
+		compatible = "simple-bus";
+		reg = <0x0 0x10000000 0x10000000>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		syscon0: syscon at 12c02000 {
+			compatible = "aspeed,ast2700-scu0", "syscon", "simple-mfd";
+			reg = <0x0 0x12c02000 0x1000>;
+			ranges = <0x0 0x0 0 0x12c02000 0x1000>;
+			#address-cells = <2>;
+			#size-cells = <1>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		intc0: interrupt-controller at 12100000 {
+			compatible = "simple-mfd";
+			reg = <0 0x12100000 0x4000>;
+			ranges = <0x0 0x0 0x0 0x12100000 0x4000>;
+			#address-cells = <2>;
+			#size-cells = <1>;
+
+			intc0_11: interrupt-controller at 1b00 {
+				compatible = "aspeed,ast2700-intc-ic";
+				reg = <0x0 0x1b00 0x10>;
+				#interrupt-cells = <2>;
+				interrupt-controller;
+				interrupts = <GIC_SPI 192 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+					     <GIC_SPI 193 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+					     <GIC_SPI 194 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+					     <GIC_SPI 195 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+					     <GIC_SPI 196 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+					     <GIC_SPI 197 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			};
+		};
+
+		gic: interrupt-controller at 12200000 {
+			compatible = "arm,gic-v3";
+			reg = <0 0x12200000 0x10000>, /* GICD */
+			      <0 0x12280000 0x80000>, /* GICR */
+			      <0 0x40440000 0x1000>;  /* GICC */
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			interrupt-parent = <&gic>;
+		};
+	};
+
+	soc1: soc at 14000000 {
+		compatible = "simple-bus";
+		reg = <0x0 0x14000000 0x10000000>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		syscon1: syscon at 14c02000 {
+			compatible = "aspeed,ast2700-scu1", "syscon", "simple-mfd";
+			reg = <0x0 0x14c02000 0x1000>;
+			ranges = <0x0 0x0 0x0 0x14c02000 0x1000>;
+			#address-cells = <2>;
+			#size-cells = <1>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		intc1: interrupt-controller at 14c18000 {
+			compatible = "simple-mfd";
+			reg = <0 0x14c18000 0x400>;
+			ranges = <0x0 0x0 0x0 0x14c18000 0x400>;
+			#address-cells = <2>;
+			#size-cells = <1>;
+
+			intc1_0: interrupt-controller at 100 {
+				compatible = "aspeed,ast2700-intc-ic";
+				reg = <0x0 0x100 0x10>;
+				#interrupt-cells = <2>;
+				interrupt-controller;
+				interrupts-extended = <&intc0_11 0 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			};
+
+			intc1_1: interrupt-controller at 110 {
+				compatible = "aspeed,ast2700-intc-ic";
+				reg = <0x0 0x110 0x10>;
+				#interrupt-cells = <2>;
+				interrupt-controller;
+				interrupts-extended = <&intc0_11 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			};
+
+			intc1_2: interrupt-controller at 120 {
+				compatible = "aspeed,ast2700-intc-ic";
+				reg = <0x0 0x120 0x10>;
+				#interrupt-cells = <2>;
+				interrupt-controller;
+				interrupts-extended = <&intc0_11 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			};
+
+			intc1_3: interrupt-controller at 130 {
+				compatible = "aspeed,ast2700-intc-ic";
+				reg = <0x0 0x130 0x10>;
+				#interrupt-cells = <2>;
+				interrupt-controller;
+				interrupts-extended = <&intc0_11 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			};
+
+			intc1_4: interrupt-controller at 140 {
+				compatible = "aspeed,ast2700-intc-ic";
+				reg = <0x0 0x140 0x10>;
+				#interrupt-cells = <2>;
+				interrupt-controller;
+				interrupts-extended = <&intc0_11 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			};
+
+			intc1_5: interrupt-controller at 150 {
+				compatible = "aspeed,ast2700-intc-ic";
+				reg = <0x0 0x150 0x10>;
+				#interrupt-cells = <2>;
+				interrupt-controller;
+				interrupts-extended = <&intc0_11 5 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			};
+		};
+
+		uart12: serial at 14c33b00 {
+			compatible = "ns16550a";
+			reg = <0x0 0x14c33b00 0x100>;
+			interrupts-extended = <&intc1_4 18 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			clocks = <&syscon1 SCU1_CLK_GATE_UART12CLK>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			no-loopback-test;
+		};
+	};
+};
-- 
2.34.1



From kevin_chen at aspeedtech.com  Thu Dec 12 07:52:36 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Thu, 12 Dec 2024 23:52:36 +0800
Subject: [PATCH v3 5/6] arm64: dts: aspeed: Add initial AST2700 EVB device tree
In-Reply-To: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
Message-ID: <20241212155237.848336-8-kevin_chen@aspeedtech.com>

Add EVB board of AST2700 in ASPEED Architecture.

Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
---
 arch/arm64/boot/dts/aspeed/Makefile        |  4 ++
 arch/arm64/boot/dts/aspeed/ast2700-evb.dts | 57 ++++++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 arch/arm64/boot/dts/aspeed/Makefile
 create mode 100644 arch/arm64/boot/dts/aspeed/ast2700-evb.dts

diff --git a/arch/arm64/boot/dts/aspeed/Makefile b/arch/arm64/boot/dts/aspeed/Makefile
new file mode 100644
index 000000000000..ffe7e15017cc
--- /dev/null
+++ b/arch/arm64/boot/dts/aspeed/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+dtb-$(CONFIG_ARCH_ASPEED) += \
+	ast2700-evb.dtb
diff --git a/arch/arm64/boot/dts/aspeed/ast2700-evb.dts b/arch/arm64/boot/dts/aspeed/ast2700-evb.dts
new file mode 100644
index 000000000000..6dad88c98ce0
--- /dev/null
+++ b/arch/arm64/boot/dts/aspeed/ast2700-evb.dts
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/dts-v1/;
+
+#include "aspeed-g7.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+	model = "AST2700A1-EVB";
+	compatible = "aspeed,ast2700-evb", "aspeed,ast2700";
+
+	aliases {
+		serial12 = &uart12;
+	};
+
+	chosen {
+		bootargs = "console=ttyS12,115200n8";
+		stdout-path = &uart12;
+	};
+
+	firmware {
+		optee: optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
+
+	memory at 400000000 {
+		device_type = "memory";
+		reg = <0x4 0x00000000 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		mcu_fw: mcu-firmware at 42fe00000 {
+			reg = <0x4 0x2fe00000 0x200000>;
+			no-map;
+		};
+
+		atf: trusted-firmware-a at 430000000 {
+			reg = <0x4 0x30000000 0x80000>;
+			no-map;
+		};
+
+		optee_core: optee_core at 430080000 {
+			reg = <0x4 0x30080000 0x1000000>;
+			no-map;
+		};
+	};
+};
+
+&uart12 {
+	status = "okay";
+};
-- 
2.34.1



From kevin_chen at aspeedtech.com  Thu Dec 12 07:52:37 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Thu, 12 Dec 2024 23:52:37 +0800
Subject: [PATCH v3 6/6] arm64: defconfig: Add ASPEED AST2700 family support
In-Reply-To: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
Message-ID: <20241212155237.848336-9-kevin_chen@aspeedtech.com>

Enable CONFIG_ARCH_ASPEED in arm64 defconfig.

Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..8826068c7c1d 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -38,6 +38,7 @@ CONFIG_ARCH_AIROHA=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
 CONFIG_ARCH_APPLE=y
+CONFIG_ARCH_ASPEED=y
 CONFIG_ARCH_BCM=y
 CONFIG_ARCH_BCM2835=y
 CONFIG_ARCH_BCM_IPROC=y
-- 
2.34.1



From lee at kernel.org  Thu Dec 12 07:55:33 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 12 Dec 2024 15:55:33 +0000
Subject: [PATCH v9 1/9] HID: hid-sensor-hub: don't use stale
 platform-data on remove
In-Reply-To: <4s41717n-3888-os6o-384n-7678n0361r0s@xreary.bet>
References: <20241107114712.538976-1-heiko@sntech.de>
 <20241211120844.GD7139@google.com>
 <n914pn7o-pr9n-5ss0-p744-73402nnn843p@xreary.bet>
 <3196449.TQGk6oTFT5@diego>
 <4s41717n-3888-os6o-384n-7678n0361r0s@xreary.bet>
Message-ID: <20241212155533.GG7139@google.com>

On Wed, 11 Dec 2024, Jiri Kosina wrote:

> On Wed, 11 Dec 2024, Heiko St?bner wrote:
> 
> > > > > > > This change was more or less a surprise find, because I wanted to make
> > > > > > > the platform_data pointer in the mfd_cell struct const and this the hid
> > > > > > > sensor hub stood out as doing something strange ;-) .
> > > > > > > 
> > > > > > > So patch 2 of this series actually depends on this change to not cause
> > > > > > > build errors.
> > > > > > 
> > > > > > Ah, right.
> > > > > > 
> > > > > > > But seeing that we're after -rc6 alredy, I would assume the brunt of the 
> > > > > > > mcu series might need to wait after 6.13-rc1 anyway - but I guess that 
> > > > > > > depends on how Lee sees things ;-) .
> > > > > > 
> > > > > > OK, I am keeping my hands off it for the time being.
> > > > > 
> > > > > I can take it now with an Ack.
> > > > 
> > > > Looking to apply this set now.
> > > > 
> > > > Ack please.
> > > 
> > > I'd preferer if Srinivas could ack this as the more specific maintainer. 
> > > Srinivas, please? 
> > 
> > The patch already includes the
> >    Ack from Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>
> > from a previous version, so I guess it should be ok already?
> 
> Ah, I missed that, indeed, sorry for the noise.
> 
> With that
> 
> 	Acked-by: Jiri Kosina <jkosina at suse.com>
> 
> and Lee, please feel free to take it.

Thanks, will do.

-- 
Lee Jones [???]


From steven.price at arm.com  Thu Dec 12 07:55:25 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:25 +0000
Subject: [PATCH v6 00/43] arm64: Support for Arm CCA in KVM
Message-ID: <20241212155610.76522-1-steven.price@arm.com>

This series adds support for running protected VMs using KVM under the
Arm Confidential Compute Architecture (CCA).

The related guest support was merged for v6.13-rc1 so you no longer need
that separately.

There are numerous changes since v5, many thanks for the review
comments. The highlights are below, and individual patches have a changelog.

 * KVM_VCPU_MAX_FEATURES is incremented. *NOTE*: This effectively
   exposes the nested virtualisation feature. So this series as it
   stands has a dependency on that being finished before it can be
   merged. See [2] for more details.

 * Properly support the RMM providing a more limited number of GIC LRs
   than the hardware.

 * Drop patch tracking number of pages for the top level PGD, it's
   easier calculating it when we need it.

 * Drop the "spare page" - it was causing code complexity and it's a bit
   premature to start making such optimisations before we've got real
   platforms to benchmark.

Major limitations:

 * Only supports 4k host PAGE_SIZE (if PAGE_SIZE != 4k then the realm
   extensions are disabled). I'm looking at removing this restriction,
   but I didn't want to delay this posting.

 * No support for huge pages when mapping the guest's pages. There is
   some 'dead' code left over from before guest_mem was supported. This
   is partly a current limitation of guest_memfd. It's also on my todo list to
   look at improving this.

The ABI to the RMM (the RMI) is based on RMM v1.0-rel0 specification[1].

This series is based on v6.13-rc1. It is also available as a git
repository:

https://gitlab.arm.com/linux-arm/linux-cca cca-host/v6

Work in progress changes for kvmtool are available from the git
repository below:

https://gitlab.arm.com/linux-arm/kvmtool-cca cca/v4

[1] https://developer.arm.com/documentation/den0137/1-0rel0/
[2] https://lore.kernel.org/r/a7011738-a084-46fa-947f-395d90b37f8b%40arm.com

Jean-Philippe Brucker (7):
  arm64: RME: Propagate number of breakpoints and watchpoints to
    userspace
  arm64: RME: Set breakpoint parameters through SET_ONE_REG
  arm64: RME: Initialize PMCR.N with number counter supported by RMM
  arm64: RME: Propagate max SVE vector length from RMM
  arm64: RME: Configure max SVE vector length for a Realm
  arm64: RME: Provide register list for unfinalized RME RECs
  arm64: RME: Provide accurate register list

Joey Gouly (2):
  arm64: rme: allow userspace to inject aborts
  arm64: rme: support RSI_HOST_CALL

Sean Christopherson (1):
  KVM: Prepare for handling only shared mappings in mmu_notifier events

Steven Price (30):
  arm64: RME: Handle Granule Protection Faults (GPFs)
  arm64: RME: Add SMC definitions for calling the RMM
  arm64: RME: Add wrappers for RMI calls
  arm64: RME: Check for RME support at KVM init
  arm64: RME: Define the user ABI
  arm64: RME: ioctls to create and configure realms
  arm64: kvm: Allow passing machine type in KVM creation
  arm64: RME: RTT tear down
  arm64: RME: Allocate/free RECs to match vCPUs
  KVM: arm64: vgic: Provide helper for number of list registers
  arm64: RME: Support for the VGIC in realms
  KVM: arm64: Support timers in realm RECs
  arm64: RME: Allow VMM to set RIPAS
  arm64: RME: Handle realm enter/exit
  KVM: arm64: Handle realm MMIO emulation
  arm64: RME: Allow populating initial contents
  arm64: RME: Runtime faulting of memory
  KVM: arm64: Handle realm VCPU load
  KVM: arm64: Validate register access for a Realm VM
  KVM: arm64: Handle Realm PSCI requests
  KVM: arm64: WARN on injected undef exceptions
  arm64: Don't expose stolen time for realm guests
  arm64: RME: Always use 4k pages for realms
  arm64: rme: Prevent Device mappings for Realms
  arm_pmu: Provide a mechanism for disabling the physical IRQ
  arm64: rme: Enable PMU support with a realm guest
  kvm: rme: Hide KVM_CAP_READONLY_MEM for realm guests
  arm64: kvm: Expose support for private memory
  KVM: arm64: Expose KVM_ARM_VCPU_REC to user space
  KVM: arm64: Allow activating realms

Suzuki K Poulose (3):
  kvm: arm64: Include kvm_emulate.h in kvm/arm_psci.h
  kvm: arm64: Expose debug HW register numbers for Realm
  arm64: rme: Allow checking SVE on VM instance

 Documentation/virt/kvm/api.rst       |    3 +
 arch/arm64/include/asm/kvm_emulate.h |   40 +
 arch/arm64/include/asm/kvm_host.h    |   17 +-
 arch/arm64/include/asm/kvm_rme.h     |  152 +++
 arch/arm64/include/asm/rmi_cmds.h    |  508 ++++++++
 arch/arm64/include/asm/rmi_smc.h     |  259 +++++
 arch/arm64/include/asm/virt.h        |    1 +
 arch/arm64/include/uapi/asm/kvm.h    |   49 +
 arch/arm64/kvm/Kconfig               |    1 +
 arch/arm64/kvm/Makefile              |    3 +-
 arch/arm64/kvm/arch_timer.c          |   45 +-
 arch/arm64/kvm/arm.c                 |  174 ++-
 arch/arm64/kvm/guest.c               |  107 +-
 arch/arm64/kvm/hypercalls.c          |    4 +-
 arch/arm64/kvm/inject_fault.c        |    6 +-
 arch/arm64/kvm/mmio.c                |   16 +-
 arch/arm64/kvm/mmu.c                 |  195 +++-
 arch/arm64/kvm/pmu-emul.c            |    6 +
 arch/arm64/kvm/psci.c                |   29 +
 arch/arm64/kvm/reset.c               |   23 +-
 arch/arm64/kvm/rme-exit.c            |  195 ++++
 arch/arm64/kvm/rme.c                 | 1588 ++++++++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c            |   79 +-
 arch/arm64/kvm/vgic/vgic-init.c      |    2 +-
 arch/arm64/kvm/vgic/vgic-v3.c        |    5 +
 arch/arm64/kvm/vgic/vgic.c           |   54 +-
 arch/arm64/mm/fault.c                |   31 +-
 drivers/perf/arm_pmu.c               |   15 +
 include/kvm/arm_arch_timer.h         |    2 +
 include/kvm/arm_pmu.h                |    4 +
 include/kvm/arm_psci.h               |    2 +
 include/linux/kvm_host.h             |    2 +
 include/linux/perf/arm_pmu.h         |    5 +
 include/uapi/linux/kvm.h             |   31 +-
 virt/kvm/kvm_main.c                  |    7 +
 35 files changed, 3557 insertions(+), 103 deletions(-)
 create mode 100644 arch/arm64/include/asm/kvm_rme.h
 create mode 100644 arch/arm64/include/asm/rmi_cmds.h
 create mode 100644 arch/arm64/include/asm/rmi_smc.h
 create mode 100644 arch/arm64/kvm/rme-exit.c
 create mode 100644 arch/arm64/kvm/rme.c

-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:26 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:26 +0000
Subject: [PATCH v6 01/43] KVM: Prepare for handling only shared mappings in mmu_notifier events
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-2-steven.price@arm.com>

From: Sean Christopherson <seanjc at google.com>

Add flags to "struct kvm_gfn_range" to let notifier events target only
shared and only private mappings, and write up the existing mmu_notifier
events to be shared-only (private memory is never associated with a
userspace virtual address, i.e. can't be reached via mmu_notifiers).

Add two flags so that KVM can handle the three possibilities (shared,
private, and shared+private) without needing something like a tri-state
enum.

Link: https://lore.kernel.org/all/ZJX0hk+KpQP0KUyB at google.com
Signed-off-by: Sean Christopherson <seanjc at google.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 include/linux/kvm_host.h | 2 ++
 virt/kvm/kvm_main.c      | 7 +++++++
 2 files changed, 9 insertions(+)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 401439bb21e3..86088968107a 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -260,6 +260,8 @@ struct kvm_gfn_range {
 	gfn_t start;
 	gfn_t end;
 	union kvm_mmu_notifier_arg arg;
+	bool only_private;
+	bool only_shared;
 	bool may_block;
 };
 bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index de2c11dae231..17727f1330ff 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -593,6 +593,13 @@ static __always_inline kvm_mn_ret_t __kvm_handle_hva_range(struct kvm *kvm,
 			 * the second or later invocation of the handler).
 			 */
 			gfn_range.arg = range->arg;
+
+			/*
+			 * HVA-based notifications aren't relevant to private
+			 * mappings as they don't have a userspace mapping.
+			 */
+			gfn_range.only_private = false;
+			gfn_range.only_shared = true;
 			gfn_range.may_block = range->may_block;
 
 			/*
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:27 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:27 +0000
Subject: [PATCH v6 02/43] kvm: arm64: Include kvm_emulate.h in kvm/arm_psci.h
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-3-steven.price@arm.com>

From: Suzuki K Poulose <suzuki.poulose at arm.com>

Fix a potential build error (like below, when asm/kvm_emulate.h gets
included after the kvm/arm_psci.h) by including the missing header file
in kvm/arm_psci.h:

./include/kvm/arm_psci.h: In function ?kvm_psci_version?:
./include/kvm/arm_psci.h:29:13: error: implicit declaration of function
   ?vcpu_has_feature?; did you mean ?cpu_have_feature?? [-Werror=implicit-function-declaration]
   29 |         if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PSCI_0_2)) {
	         |             ^~~~~~~~~~~~~~~~
			       |             cpu_have_feature

Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 include/kvm/arm_psci.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h
index cbaec804eb83..38dab7add79b 100644
--- a/include/kvm/arm_psci.h
+++ b/include/kvm/arm_psci.h
@@ -10,6 +10,8 @@
 #include <linux/kvm_host.h>
 #include <uapi/linux/psci.h>
 
+#include <asm/kvm_emulate.h>
+
 #define KVM_ARM_PSCI_0_1	PSCI_VERSION(0, 1)
 #define KVM_ARM_PSCI_0_2	PSCI_VERSION(0, 2)
 #define KVM_ARM_PSCI_1_0	PSCI_VERSION(1, 0)
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:28 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:28 +0000
Subject: [PATCH v6 03/43] arm64: RME: Handle Granule Protection Faults (GPFs)
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-4-steven.price@arm.com>

If the host attempts to access granules that have been delegated for use
in a realm these accesses will be caught and will trigger a Granule
Protection Fault (GPF).

A fault during a page walk signals a bug in the kernel and is handled by
oopsing the kernel. A non-page walk fault could be caused by user space
having access to a page which has been delegated to the kernel and will
trigger a SIGBUS to allow debugging why user space is trying to access a
delegated page.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v2:
 * Include missing "Granule Protection Fault at level -1"
---
 arch/arm64/mm/fault.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index ef63651099a9..29821dc89f73 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -844,6 +844,25 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
 	return 0;
 }
 
+static int do_gpf_ptw(unsigned long far, unsigned long esr, struct pt_regs *regs)
+{
+	const struct fault_info *inf = esr_to_fault_info(esr);
+
+	die_kernel_fault(inf->name, far, esr, regs);
+	return 0;
+}
+
+static int do_gpf(unsigned long far, unsigned long esr, struct pt_regs *regs)
+{
+	const struct fault_info *inf = esr_to_fault_info(esr);
+
+	if (!is_el1_instruction_abort(esr) && fixup_exception(regs))
+		return 0;
+
+	arm64_notify_die(inf->name, regs, inf->sig, inf->code, far, esr);
+	return 0;
+}
+
 static const struct fault_info fault_info[] = {
 	{ do_bad,		SIGKILL, SI_KERNEL,	"ttbr address size fault"	},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"level 1 address size fault"	},
@@ -880,12 +899,12 @@ static const struct fault_info fault_info[] = {
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 32"			},
 	{ do_alignment_fault,	SIGBUS,  BUS_ADRALN,	"alignment fault"		},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 34"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 35"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 36"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 37"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 38"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 39"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 40"			},
+	{ do_gpf_ptw,		SIGKILL, SI_KERNEL,	"Granule Protection Fault at level -1" },
+	{ do_gpf_ptw,		SIGKILL, SI_KERNEL,	"Granule Protection Fault at level 0" },
+	{ do_gpf_ptw,		SIGKILL, SI_KERNEL,	"Granule Protection Fault at level 1" },
+	{ do_gpf_ptw,		SIGKILL, SI_KERNEL,	"Granule Protection Fault at level 2" },
+	{ do_gpf_ptw,		SIGKILL, SI_KERNEL,	"Granule Protection Fault at level 3" },
+	{ do_gpf,		SIGBUS,  SI_KERNEL,	"Granule Protection Fault not on table walk" },
 	{ do_bad,		SIGKILL, SI_KERNEL,	"level -1 address size fault"	},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 42"			},
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level -1 translation fault"	},
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:29 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:29 +0000
Subject: [PATCH v6 04/43] arm64: RME: Add SMC definitions for calling the RMM
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-5-steven.price@arm.com>

The RMM (Realm Management Monitor) provides functionality that can be
accessed by SMC calls from the host.

The SMC definitions are based on DEN0137[1] version 1.0-rel0

[1] https://developer.arm.com/documentation/den0137/1-0rel0/

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v5:
 * Sorted the SMC #defines by value.
 * Renamed SMI_RxI_CALL to SMI_RMI_CALL since the macro is only used for
   RMI calls.
 * Renamed REC_GIC_NUM_LRS to REC_MAX_GIC_NUM_LRS since the actual
   number of available list registers could be lower.
 * Provided a define for the reserved fields of FeatureRegister0.
 * Fix inconsistent names for padding fields.
Changes since v4:
 * Update to point to final released RMM spec.
 * Minor rearrangements.
Changes since v3:
 * Update to match RMM spec v1.0-rel0-rc1.
Changes since v2:
 * Fix specification link.
 * Rename rec_entry->rec_enter to match spec.
 * Fix size of pmu_ovf_status to match spec.
---
 arch/arm64/include/asm/rmi_smc.h | 259 +++++++++++++++++++++++++++++++
 1 file changed, 259 insertions(+)
 create mode 100644 arch/arm64/include/asm/rmi_smc.h

diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_smc.h
new file mode 100644
index 000000000000..eec659e284cd
--- /dev/null
+++ b/arch/arm64/include/asm/rmi_smc.h
@@ -0,0 +1,259 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023-2024 ARM Ltd.
+ *
+ * The values and structures in this file are from the Realm Management Monitor
+ * specification (DEN0137) version 1.0-rel0:
+ * https://developer.arm.com/documentation/den0137/1-0rel0/
+ */
+
+#ifndef __ASM_RME_SMC_H
+#define __ASM_RME_SMC_H
+
+#include <linux/arm-smccc.h>
+
+#define SMC_RMI_CALL(func)				\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,		\
+			   ARM_SMCCC_SMC_64,		\
+			   ARM_SMCCC_OWNER_STANDARD,	\
+			   (func))
+
+#define SMC_RMI_VERSION			SMC_RMI_CALL(0x0150)
+#define SMC_RMI_GRANULE_DELEGATE	SMC_RMI_CALL(0x0151)
+#define SMC_RMI_GRANULE_UNDELEGATE	SMC_RMI_CALL(0x0152)
+#define SMC_RMI_DATA_CREATE		SMC_RMI_CALL(0x0153)
+#define SMC_RMI_DATA_CREATE_UNKNOWN	SMC_RMI_CALL(0x0154)
+#define SMC_RMI_DATA_DESTROY		SMC_RMI_CALL(0x0155)
+
+#define SMC_RMI_REALM_ACTIVATE		SMC_RMI_CALL(0x0157)
+#define SMC_RMI_REALM_CREATE		SMC_RMI_CALL(0x0158)
+#define SMC_RMI_REALM_DESTROY		SMC_RMI_CALL(0x0159)
+#define SMC_RMI_REC_CREATE		SMC_RMI_CALL(0x015a)
+#define SMC_RMI_REC_DESTROY		SMC_RMI_CALL(0x015b)
+#define SMC_RMI_REC_ENTER		SMC_RMI_CALL(0x015c)
+#define SMC_RMI_RTT_CREATE		SMC_RMI_CALL(0x015d)
+#define SMC_RMI_RTT_DESTROY		SMC_RMI_CALL(0x015e)
+#define SMC_RMI_RTT_MAP_UNPROTECTED	SMC_RMI_CALL(0x015f)
+
+#define SMC_RMI_RTT_READ_ENTRY		SMC_RMI_CALL(0x0161)
+#define SMC_RMI_RTT_UNMAP_UNPROTECTED	SMC_RMI_CALL(0x0162)
+
+#define SMC_RMI_PSCI_COMPLETE		SMC_RMI_CALL(0x0164)
+#define SMC_RMI_FEATURES		SMC_RMI_CALL(0x0165)
+#define SMC_RMI_RTT_FOLD		SMC_RMI_CALL(0x0166)
+#define SMC_RMI_REC_AUX_COUNT		SMC_RMI_CALL(0x0167)
+#define SMC_RMI_RTT_INIT_RIPAS		SMC_RMI_CALL(0x0168)
+#define SMC_RMI_RTT_SET_RIPAS		SMC_RMI_CALL(0x0169)
+
+#define RMI_ABI_MAJOR_VERSION	1
+#define RMI_ABI_MINOR_VERSION	0
+
+#define RMI_ABI_VERSION_GET_MAJOR(version) ((version) >> 16)
+#define RMI_ABI_VERSION_GET_MINOR(version) ((version) & 0xFFFF)
+#define RMI_ABI_VERSION(major, minor)      (((major) << 16) | (minor))
+
+#define RMI_UNASSIGNED			0
+#define RMI_ASSIGNED			1
+#define RMI_TABLE			2
+
+#define RMI_RETURN_STATUS(ret)		((ret) & 0xFF)
+#define RMI_RETURN_INDEX(ret)		(((ret) >> 8) & 0xFF)
+
+#define RMI_SUCCESS		0
+#define RMI_ERROR_INPUT		1
+#define RMI_ERROR_REALM		2
+#define RMI_ERROR_REC		3
+#define RMI_ERROR_RTT		4
+
+enum rmi_ripas {
+	RMI_EMPTY = 0,
+	RMI_RAM = 1,
+	RMI_DESTROYED = 2,
+};
+
+#define RMI_NO_MEASURE_CONTENT	0
+#define RMI_MEASURE_CONTENT	1
+
+#define RMI_FEATURE_REGISTER_0_S2SZ		GENMASK(7, 0)
+#define RMI_FEATURE_REGISTER_0_LPA2		BIT(8)
+#define RMI_FEATURE_REGISTER_0_SVE_EN		BIT(9)
+#define RMI_FEATURE_REGISTER_0_SVE_VL		GENMASK(13, 10)
+#define RMI_FEATURE_REGISTER_0_NUM_BPS		GENMASK(19, 14)
+#define RMI_FEATURE_REGISTER_0_NUM_WPS		GENMASK(25, 20)
+#define RMI_FEATURE_REGISTER_0_PMU_EN		BIT(26)
+#define RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS	GENMASK(31, 27)
+#define RMI_FEATURE_REGISTER_0_HASH_SHA_256	BIT(32)
+#define RMI_FEATURE_REGISTER_0_HASH_SHA_512	BIT(33)
+#define RMI_FEATURE_REGISTER_0_GICV3_NUM_LRS	GENMASK(37, 34)
+#define RMI_FEATURE_REGISTER_0_MAX_RECS_ORDER	GENMASK(41, 38)
+#define RMI_FEATURE_REGISTER_0_Reserved		GENMASK(63, 42)
+
+#define RMI_REALM_PARAM_FLAG_LPA2		BIT(0)
+#define RMI_REALM_PARAM_FLAG_SVE		BIT(1)
+#define RMI_REALM_PARAM_FLAG_PMU		BIT(2)
+
+/*
+ * Note many of these fields are smaller than u64 but all fields have u64
+ * alignment, so use u64 to ensure correct alignment.
+ */
+struct realm_params {
+	union { /* 0x0 */
+		struct {
+			u64 flags;
+			u64 s2sz;
+			u64 sve_vl;
+			u64 num_bps;
+			u64 num_wps;
+			u64 pmu_num_ctrs;
+			u64 hash_algo;
+		};
+		u8 padding0[0x400];
+	};
+	union { /* 0x400 */
+		u8 rpv[64];
+		u8 padding1[0x400];
+	};
+	union { /* 0x800 */
+		struct {
+			u64 vmid;
+			u64 rtt_base;
+			s64 rtt_level_start;
+			u64 rtt_num_start;
+		};
+		u8 padding2[0x800];
+	};
+};
+
+/*
+ * The number of GPRs (starting from X0) that are
+ * configured by the host when a REC is created.
+ */
+#define REC_CREATE_NR_GPRS		8
+
+#define REC_PARAMS_FLAG_RUNNABLE	BIT_ULL(0)
+
+#define REC_PARAMS_AUX_GRANULES		16
+
+struct rec_params {
+	union { /* 0x0 */
+		u64 flags;
+		u8 padding0[0x100];
+	};
+	union { /* 0x100 */
+		u64 mpidr;
+		u8 padding1[0x100];
+	};
+	union { /* 0x200 */
+		u64 pc;
+		u8 padding2[0x100];
+	};
+	union { /* 0x300 */
+		u64 gprs[REC_CREATE_NR_GPRS];
+		u8 padding3[0x500];
+	};
+	union { /* 0x800 */
+		struct {
+			u64 num_rec_aux;
+			u64 aux[REC_PARAMS_AUX_GRANULES];
+		};
+		u8 padding4[0x800];
+	};
+};
+
+#define REC_ENTER_EMULATED_MMIO		BIT(0)
+#define REC_ENTER_INJECT_SEA		BIT(1)
+#define REC_ENTER_TRAP_WFI		BIT(2)
+#define REC_ENTER_TRAP_WFE		BIT(3)
+#define REC_ENTER_RIPAS_RESPONSE	BIT(4)
+
+#define REC_RUN_GPRS			31
+#define REC_MAX_GIC_NUM_LRS		16
+
+struct rec_enter {
+	union { /* 0x000 */
+		u64 flags;
+		u8 padding0[0x200];
+	};
+	union { /* 0x200 */
+		u64 gprs[REC_RUN_GPRS];
+		u8 padding1[0x100];
+	};
+	union { /* 0x300 */
+		struct {
+			u64 gicv3_hcr;
+			u64 gicv3_lrs[REC_MAX_GIC_NUM_LRS];
+		};
+		u8 padding2[0x100];
+	};
+	u8 padding3[0x400];
+};
+
+#define RMI_EXIT_SYNC			0x00
+#define RMI_EXIT_IRQ			0x01
+#define RMI_EXIT_FIQ			0x02
+#define RMI_EXIT_PSCI			0x03
+#define RMI_EXIT_RIPAS_CHANGE		0x04
+#define RMI_EXIT_HOST_CALL		0x05
+#define RMI_EXIT_SERROR			0x06
+
+struct rec_exit {
+	union { /* 0x000 */
+		u8 exit_reason;
+		u8 padding0[0x100];
+	};
+	union { /* 0x100 */
+		struct {
+			u64 esr;
+			u64 far;
+			u64 hpfar;
+		};
+		u8 padding1[0x100];
+	};
+	union { /* 0x200 */
+		u64 gprs[REC_RUN_GPRS];
+		u8 padding2[0x100];
+	};
+	union { /* 0x300 */
+		struct {
+			u64 gicv3_hcr;
+			u64 gicv3_lrs[REC_MAX_GIC_NUM_LRS];
+			u64 gicv3_misr;
+			u64 gicv3_vmcr;
+		};
+		u8 padding3[0x100];
+	};
+	union { /* 0x400 */
+		struct {
+			u64 cntp_ctl;
+			u64 cntp_cval;
+			u64 cntv_ctl;
+			u64 cntv_cval;
+		};
+		u8 padding4[0x100];
+	};
+	union { /* 0x500 */
+		struct {
+			u64 ripas_base;
+			u64 ripas_top;
+			u64 ripas_value;
+		};
+		u8 padding5[0x100];
+	};
+	union { /* 0x600 */
+		u16 imm;
+		u8 padding6[0x100];
+	};
+	union { /* 0x700 */
+		struct {
+			u8 pmu_ovf_status;
+		};
+		u8 padding7[0x100];
+	};
+};
+
+struct rec_run {
+	struct rec_enter enter;
+	struct rec_exit exit;
+};
+
+#endif
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:30 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:30 +0000
Subject: [PATCH v6 05/43] arm64: RME: Add wrappers for RMI calls
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-6-steven.price@arm.com>

The wrappers make the call sites easier to read and deal with the
boiler plate of handling the error codes from the RMM.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes from v5:
 * Further improve comments
Changes from v4:
 * Improve comments
Changes from v2:
 * Make output arguments optional.
 * Mask RIPAS value rmi_rtt_read_entry()
 * Drop unused rmi_rtt_get_phys()
---
 arch/arm64/include/asm/rmi_cmds.h | 508 ++++++++++++++++++++++++++++++
 1 file changed, 508 insertions(+)
 create mode 100644 arch/arm64/include/asm/rmi_cmds.h

diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi_cmds.h
new file mode 100644
index 000000000000..043b7ff278ee
--- /dev/null
+++ b/arch/arm64/include/asm/rmi_cmds.h
@@ -0,0 +1,508 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#ifndef __ASM_RMI_CMDS_H
+#define __ASM_RMI_CMDS_H
+
+#include <linux/arm-smccc.h>
+
+#include <asm/rmi_smc.h>
+
+struct rtt_entry {
+	unsigned long walk_level;
+	unsigned long desc;
+	int state;
+	int ripas;
+};
+
+/**
+ * rmi_data_create() - Create a data granule
+ * @rd: PA of the RD
+ * @data: PA of the target granule
+ * @ipa: IPA at which the granule will be mapped in the guest
+ * @src: PA of the source granule
+ * @flags: RMI_MEASURE_CONTENT if the contents should be measured
+ *
+ * Create a new data granule, copying contents from a non-secure granule.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_data_create(unsigned long rd, unsigned long data,
+				  unsigned long ipa, unsigned long src,
+				  unsigned long flags)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_DATA_CREATE, rd, data, ipa, src,
+			     flags, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_data_create_unknown() - Create a data granule with unknown contents
+ * @rd: PA of the RD
+ * @data: PA of the target granule
+ * @ipa: IPA at which the granule will be mapped in the guest
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_data_create_unknown(unsigned long rd,
+					  unsigned long data,
+					  unsigned long ipa)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_DATA_CREATE_UNKNOWN, rd, data, ipa, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_data_destroy() - Destroy a data granule
+ * @rd: PA of the RD
+ * @ipa: IPA at which the granule is mapped in the guest
+ * @data_out: PA of the granule which was destroyed
+ * @top_out: Top IPA of non-live RTT entries
+ *
+ * Unmap a protected IPA from stage 2, transitioning it to DESTROYED.
+ * The IPA cannot be used by the guest unless it is transitioned to RAM again
+ * by the realm guest.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_data_destroy(unsigned long rd, unsigned long ipa,
+				   unsigned long *data_out,
+				   unsigned long *top_out)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_DATA_DESTROY, rd, ipa, &res);
+
+	if (data_out)
+		*data_out = res.a1;
+	if (top_out)
+		*top_out = res.a2;
+
+	return res.a0;
+}
+
+/**
+ * rmi_features() - Read feature register
+ * @index: Feature register index
+ * @out: Feature register value is written to this pointer
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_features(unsigned long index, unsigned long *out)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_FEATURES, index, &res);
+
+	if (out)
+		*out = res.a1;
+	return res.a0;
+}
+
+/**
+ * rmi_granule_delegate() - Delegate a granule
+ * @phys: PA of the granule
+ *
+ * Delegate a granule for use by the realm world.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_granule_delegate(unsigned long phys)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_GRANULE_DELEGATE, phys, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_granule_undelegate() - Undelegate a granule
+ * @phys: PA of the granule
+ *
+ * Undelegate a granule to allow use by the normal world. Will fail if the
+ * granule is in use.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_granule_undelegate(unsigned long phys)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_GRANULE_UNDELEGATE, phys, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_psci_complete() - Complete pending PSCI command
+ * @calling_rec: PA of the calling REC
+ * @target_rec: PA of the target REC
+ * @status: Status of the PSCI request
+ *
+ * Completes a pending PSCI command which was called with an MPIDR argument, by
+ * providing the corresponding REC.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_psci_complete(unsigned long calling_rec,
+				    unsigned long target_rec,
+				    unsigned long status)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_PSCI_COMPLETE, calling_rec, target_rec,
+			     status, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_realm_activate() - Active a realm
+ * @rd: PA of the RD
+ *
+ * Mark a realm as Active signalling that creation is complete and allowing
+ * execution of the realm.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_realm_activate(unsigned long rd)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_REALM_ACTIVATE, rd, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_realm_create() - Create a realm
+ * @rd: PA of the RD
+ * @params_ptr: PA of realm parameters
+ *
+ * Create a new realm using the given parameters.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_realm_create(unsigned long rd, unsigned long params_ptr)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_REALM_CREATE, rd, params_ptr, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_realm_destroy() - Destroy a realm
+ * @rd: PA of the RD
+ *
+ * Destroys a realm, all objects belonging to the realm must be destroyed first.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_realm_destroy(unsigned long rd)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_REALM_DESTROY, rd, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_rec_aux_count() - Get number of auxiliary granules required
+ * @rd: PA of the RD
+ * @aux_count: Number of pages written to this pointer
+ *
+ * A REC may require extra auxiliary pages to be delegated for the RMM to
+ * store metadata (not visible to the normal world) in. This function provides
+ * the number of pages that are required.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rec_aux_count(unsigned long rd, unsigned long *aux_count)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_REC_AUX_COUNT, rd, &res);
+
+	if (aux_count)
+		*aux_count = res.a1;
+	return res.a0;
+}
+
+/**
+ * rmi_rec_create() - Create a REC
+ * @rd: PA of the RD
+ * @rec: PA of the target REC
+ * @params_ptr: PA of REC parameters
+ *
+ * Create a REC using the parameters specified in the struct rec_params pointed
+ * to by @params_ptr.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rec_create(unsigned long rd, unsigned long rec,
+				 unsigned long params_ptr)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_REC_CREATE, rd, rec, params_ptr, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_rec_destroy() - Destroy a REC
+ * @rec: PA of the target REC
+ *
+ * Destroys a REC. The REC must not be running.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rec_destroy(unsigned long rec)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_REC_DESTROY, rec, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_rec_enter() - Enter a REC
+ * @rec: PA of the target REC
+ * @run_ptr: PA of RecRun structure
+ *
+ * Starts (or continues) execution within a REC.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rec_enter(unsigned long rec, unsigned long run_ptr)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_REC_ENTER, rec, run_ptr, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_rtt_create() - Creates an RTT
+ * @rd: PA of the RD
+ * @rtt: PA of the target RTT
+ * @ipa: Base of the IPA range described by the RTT
+ * @level: Depth of the RTT within the tree
+ *
+ * Creates an RTT (Realm Translation Table) at the specified level for the
+ * translation of the specified address within the realm.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rtt_create(unsigned long rd, unsigned long rtt,
+				 unsigned long ipa, long level)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_RTT_CREATE, rd, rtt, ipa, level, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_rtt_destroy() - Destroy an RTT
+ * @rd: PA of the RD
+ * @ipa: Base of the IPA range described by the RTT
+ * @level: Depth of the RTT within the tree
+ * @out_rtt: Pointer to write the PA of the RTT which was destroyed
+ * @out_top: Pointer to write the top IPA of non-live RTT entries
+ *
+ * Destroys an RTT. The RTT must be non-live, i.e. none of the entries in the
+ * table are in ASSIGNED or TABLE state.
+ *
+ * Return: RMI return code.
+ */
+static inline int rmi_rtt_destroy(unsigned long rd,
+				  unsigned long ipa,
+				  long level,
+				  unsigned long *out_rtt,
+				  unsigned long *out_top)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_RTT_DESTROY, rd, ipa, level, &res);
+
+	if (out_rtt)
+		*out_rtt = res.a1;
+	if (out_top)
+		*out_top = res.a2;
+
+	return res.a0;
+}
+
+/**
+ * rmi_rtt_fold() - Fold an RTT
+ * @rd: PA of the RD
+ * @ipa: Base of the IPA range described by the RTT
+ * @level: Depth of the RTT within the tree
+ * @out_rtt: Pointer to write the PA of the RTT which was destroyed
+ *
+ * Folds an RTT. If all entries with the RTT are 'homogeneous' the RTT can be
+ * folded into the parent and the RTT destroyed.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rtt_fold(unsigned long rd, unsigned long ipa,
+			       long level, unsigned long *out_rtt)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_RTT_FOLD, rd, ipa, level, &res);
+
+	if (out_rtt)
+		*out_rtt = res.a1;
+
+	return res.a0;
+}
+
+/**
+ * rmi_rtt_init_ripas() - Set RIPAS for new realm
+ * @rd: PA of the RD
+ * @base: Base of target IPA region
+ * @top: Top of target IPA region
+ * @out_top: Top IPA of range whose RIPAS was modified
+ *
+ * Sets the RIPAS of a target IPA range to RAM, for a realm in the NEW state.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rtt_init_ripas(unsigned long rd, unsigned long base,
+				     unsigned long top, unsigned long *out_top)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_RTT_INIT_RIPAS, rd, base, top, &res);
+
+	if (out_top)
+		*out_top = res.a1;
+
+	return res.a0;
+}
+
+/**
+ * rmi_rtt_map_unprotected() - Map NS pages into a realm
+ * @rd: PA of the RD
+ * @ipa: Base IPA of the mapping
+ * @level: Depth within the RTT tree
+ * @desc: RTTE descriptor
+ *
+ * Create a mapping from an Unprotected IPA to a Non-secure PA.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rtt_map_unprotected(unsigned long rd,
+					  unsigned long ipa,
+					  long level,
+					  unsigned long desc)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_RTT_MAP_UNPROTECTED, rd, ipa, level,
+			     desc, &res);
+
+	return res.a0;
+}
+
+/**
+ * rmi_rtt_read_entry() - Read an RTTE
+ * @rd: PA of the RD
+ * @ipa: IPA for which to read the RTTE
+ * @level: RTT level at which to read the RTTE
+ * @rtt: Output structure describing the RTTE
+ *
+ * Reads a RTTE (Realm Translation Table Entry).
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rtt_read_entry(unsigned long rd, unsigned long ipa,
+				     long level, struct rtt_entry *rtt)
+{
+	struct arm_smccc_1_2_regs regs = {
+		SMC_RMI_RTT_READ_ENTRY,
+		rd, ipa, level
+	};
+
+	arm_smccc_1_2_smc(&regs, &regs);
+
+	rtt->walk_level = regs.a1;
+	rtt->state = regs.a2 & 0xFF;
+	rtt->desc = regs.a3;
+	rtt->ripas = regs.a4 & 0xFF;
+
+	return regs.a0;
+}
+
+/**
+ * rmi_rtt_set_ripas() - Set RIPAS for an running realm
+ * @rd: PA of the RD
+ * @rec: PA of the REC making the request
+ * @base: Base of target IPA region
+ * @top: Top of target IPA region
+ * @out_top: Pointer to write top IPA of range whose RIPAS was modified
+ *
+ * Completes a request made by the realm to change the RIPAS of a target IPA
+ * range.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rtt_set_ripas(unsigned long rd, unsigned long rec,
+				    unsigned long base, unsigned long top,
+				    unsigned long *out_top)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_RTT_SET_RIPAS, rd, rec, base, top, &res);
+
+	if (out_top)
+		*out_top = res.a1;
+
+	return res.a0;
+}
+
+/**
+ * rmi_rtt_unmap_unprotected() - Remove a NS mapping
+ * @rd: PA of the RD
+ * @ipa: Base IPA of the mapping
+ * @level: Depth within the RTT tree
+ * @out_top: Pointer to write top IPA of non-live RTT entries
+ *
+ * Removes a mapping at an Unprotected IPA.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rtt_unmap_unprotected(unsigned long rd,
+					    unsigned long ipa,
+					    long level,
+					    unsigned long *out_top)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_invoke(SMC_RMI_RTT_UNMAP_UNPROTECTED, rd, ipa,
+			     level, &res);
+
+	if (out_top)
+		*out_top = res.a1;
+
+	return res.a0;
+}
+
+#endif /* __ASM_RMI_CMDS_H */
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:31 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:31 +0000
Subject: [PATCH v6 06/43] arm64: RME: Check for RME support at KVM init
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-7-steven.price@arm.com>

Query the RMI version number and check if it is a compatible version. A
static key is also provided to signal that a supported RMM is available.

Functions are provided to query if a VM or VCPU is a realm (or rec)
which currently will always return false.

Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v5:
 * Reword "unsupported" message from "host supports" to "we want" to
   clarify that 'we' are the 'host'.
Changes since v2:
 * Drop return value from kvm_init_rme(), it was always 0.
 * Rely on the RMM return value to identify whether the RSI ABI is
   compatible.
---
 arch/arm64/include/asm/kvm_emulate.h | 18 +++++++++
 arch/arm64/include/asm/kvm_host.h    |  4 ++
 arch/arm64/include/asm/kvm_rme.h     | 56 ++++++++++++++++++++++++++++
 arch/arm64/include/asm/virt.h        |  1 +
 arch/arm64/kvm/Makefile              |  3 +-
 arch/arm64/kvm/arm.c                 |  6 +++
 arch/arm64/kvm/rme.c                 | 50 +++++++++++++++++++++++++
 7 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/include/asm/kvm_rme.h
 create mode 100644 arch/arm64/kvm/rme.c

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index cf811009a33c..4d417e39763e 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -702,4 +702,22 @@ static inline void kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
 {
 	vcpu_set_flag(vcpu, GUEST_HAS_PTRAUTH);
 }
+
+static inline bool kvm_is_realm(struct kvm *kvm)
+{
+	if (static_branch_unlikely(&kvm_rme_is_available) && kvm)
+		return kvm->arch.is_realm;
+	return false;
+}
+
+static inline enum realm_state kvm_realm_state(struct kvm *kvm)
+{
+	return READ_ONCE(kvm->arch.realm.state);
+}
+
+static inline bool vcpu_is_rec(struct kvm_vcpu *vcpu)
+{
+	return false;
+}
+
 #endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e18e9244d17a..8482638dce3b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -27,6 +27,7 @@
 #include <asm/fpsimd.h>
 #include <asm/kvm.h>
 #include <asm/kvm_asm.h>
+#include <asm/kvm_rme.h>
 #include <asm/vncr_mapping.h>
 
 #define __KVM_HAVE_ARCH_INTC_INITIALIZED
@@ -380,6 +381,9 @@ struct kvm_arch {
 	 * the associated pKVM instance in the hypervisor.
 	 */
 	struct kvm_protected_vm pkvm;
+
+	bool is_realm;
+	struct realm realm;
 };
 
 struct kvm_vcpu_fault_info {
diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
new file mode 100644
index 000000000000..69af5c3a1e44
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#ifndef __ASM_KVM_RME_H
+#define __ASM_KVM_RME_H
+
+/**
+ * enum realm_state - State of a Realm
+ */
+enum realm_state {
+	/**
+	 * @REALM_STATE_NONE:
+	 *      Realm has not yet been created. rmi_realm_create() may be
+	 *      called to create the realm.
+	 */
+	REALM_STATE_NONE,
+	/**
+	 * @REALM_STATE_NEW:
+	 *      Realm is under construction, not eligible for execution. Pages
+	 *      may be populated with rmi_data_create().
+	 */
+	REALM_STATE_NEW,
+	/**
+	 * @REALM_STATE_ACTIVE:
+	 *      Realm has been created and is eligible for execution with
+	 *      rmi_rec_enter(). Pages may no longer be populated with
+	 *      rmi_data_create().
+	 */
+	REALM_STATE_ACTIVE,
+	/**
+	 * @REALM_STATE_DYING:
+	 *      Realm is in the process of being destroyed or has already been
+	 *      destroyed.
+	 */
+	REALM_STATE_DYING,
+	/**
+	 * @REALM_STATE_DEAD:
+	 *      Realm has been destroyed.
+	 */
+	REALM_STATE_DEAD
+};
+
+/**
+ * struct realm - Additional per VM data for a Realm
+ *
+ * @state: The lifetime state machine for the realm
+ */
+struct realm {
+	enum realm_state state;
+};
+
+void kvm_init_rme(void);
+
+#endif
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index ebf4a9f943ed..e45d47156dcf 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -81,6 +81,7 @@ void __hyp_reset_vectors(void);
 bool is_kvm_arm_initialised(void);
 
 DECLARE_STATIC_KEY_FALSE(kvm_protected_mode_initialized);
+DECLARE_STATIC_KEY_FALSE(kvm_rme_is_available);
 
 static inline bool is_pkvm_initialized(void)
 {
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 3cf7adb2b503..ce8a10d3161d 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -23,7 +23,8 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-v3.o vgic/vgic-v4.o \
 	 vgic/vgic-mmio.o vgic/vgic-mmio-v2.o \
 	 vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
-	 vgic/vgic-its.o vgic/vgic-debug.o
+	 vgic/vgic-its.o vgic/vgic-debug.o \
+	 rme.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
 kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..93087eca9c51 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -40,6 +40,7 @@
 #include <asm/kvm_nested.h>
 #include <asm/kvm_pkvm.h>
 #include <asm/kvm_ptrauth.h>
+#include <asm/kvm_rme.h>
 #include <asm/sections.h>
 
 #include <kvm/arm_hypercalls.h>
@@ -59,6 +60,8 @@ enum kvm_wfx_trap_policy {
 static enum kvm_wfx_trap_policy kvm_wfi_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;
 static enum kvm_wfx_trap_policy kvm_wfe_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;
 
+DEFINE_STATIC_KEY_FALSE(kvm_rme_is_available);
+
 DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);
 
 DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
@@ -2769,6 +2772,9 @@ static __init int kvm_arm_init(void)
 
 	in_hyp_mode = is_kernel_in_hyp_mode();
 
+	if (in_hyp_mode)
+		kvm_init_rme();
+
 	if (cpus_have_final_cap(ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE) ||
 	    cpus_have_final_cap(ARM64_WORKAROUND_1508412))
 		kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
new file mode 100644
index 000000000000..b88269b80c11
--- /dev/null
+++ b/arch/arm64/kvm/rme.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/rmi_cmds.h>
+#include <asm/virt.h>
+
+static int rmi_check_version(void)
+{
+	struct arm_smccc_res res;
+	int version_major, version_minor;
+	unsigned long host_version = RMI_ABI_VERSION(RMI_ABI_MAJOR_VERSION,
+						     RMI_ABI_MINOR_VERSION);
+
+	arm_smccc_1_1_invoke(SMC_RMI_VERSION, host_version, &res);
+
+	if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
+		return -ENXIO;
+
+	version_major = RMI_ABI_VERSION_GET_MAJOR(res.a1);
+	version_minor = RMI_ABI_VERSION_GET_MINOR(res.a1);
+
+	if (res.a0 != RMI_SUCCESS) {
+		kvm_err("Unsupported RMI ABI (v%d.%d) we want v%d.%d\n",
+			version_major, version_minor,
+			RMI_ABI_MAJOR_VERSION,
+			RMI_ABI_MINOR_VERSION);
+		return -ENXIO;
+	}
+
+	kvm_info("RMI ABI version %d.%d\n", version_major, version_minor);
+
+	return 0;
+}
+
+void kvm_init_rme(void)
+{
+	if (PAGE_SIZE != SZ_4K)
+		/* Only 4k page size on the host is supported */
+		return;
+
+	if (rmi_check_version())
+		/* Continue without realm support */
+		return;
+
+	/* Future patch will enable static branch kvm_rme_is_available */
+}
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:32 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:32 +0000
Subject: [PATCH v6 07/43] arm64: RME: Define the user ABI
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-8-steven.price@arm.com>

There is one (multiplexed) CAP which can be used to create, populate and
then activate the realm.

Co-developed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes from v5:
 * Actually expose the new VCPU capability (KVM_ARM_VCPU_REC) by bumping
   KVM_VCPU_MAX_FEATURES - note this also exposes KVM_ARM_VCPU_HAS_EL2!
---
 Documentation/virt/kvm/api.rst    |  1 +
 arch/arm64/include/uapi/asm/kvm.h | 49 +++++++++++++++++++++++++++++++
 include/uapi/linux/kvm.h          | 12 ++++++++
 3 files changed, 62 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 454c2aaa155e..df4679415a4c 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -5088,6 +5088,7 @@ Recognised values for feature:
 
   =====      ===========================================
   arm64      KVM_ARM_VCPU_SVE (requires KVM_CAP_ARM_SVE)
+  arm64      KVM_ARM_VCPU_REC (requires KVM_CAP_ARM_RME)
   =====      ===========================================
 
 Finalizes the configuration of the specified vcpu feature.
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 66736ff04011..8810719523ec 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -108,6 +108,7 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_PTRAUTH_ADDRESS	5 /* VCPU uses address authentication */
 #define KVM_ARM_VCPU_PTRAUTH_GENERIC	6 /* VCPU uses generic authentication */
 #define KVM_ARM_VCPU_HAS_EL2		7 /* Support nested virtualization */
+#define KVM_ARM_VCPU_REC		8 /* VCPU REC state as part of Realm */
 
 struct kvm_vcpu_init {
 	__u32 target;
@@ -418,6 +419,54 @@ enum {
 #define   KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES	3
 #define   KVM_DEV_ARM_ITS_CTRL_RESET		4
 
+/* KVM_CAP_ARM_RME on VM fd */
+#define KVM_CAP_ARM_RME_CONFIG_REALM		0
+#define KVM_CAP_ARM_RME_CREATE_RD		1
+#define KVM_CAP_ARM_RME_INIT_IPA_REALM		2
+#define KVM_CAP_ARM_RME_POPULATE_REALM		3
+#define KVM_CAP_ARM_RME_ACTIVATE_REALM		4
+
+#define KVM_CAP_ARM_RME_MEASUREMENT_ALGO_SHA256		0
+#define KVM_CAP_ARM_RME_MEASUREMENT_ALGO_SHA512		1
+
+#define KVM_CAP_ARM_RME_RPV_SIZE 64
+
+/* List of configuration items accepted for KVM_CAP_ARM_RME_CONFIG_REALM */
+#define KVM_CAP_ARM_RME_CFG_RPV			0
+#define KVM_CAP_ARM_RME_CFG_HASH_ALGO		1
+
+struct kvm_cap_arm_rme_config_item {
+	__u32 cfg;
+	union {
+		/* cfg == KVM_CAP_ARM_RME_CFG_RPV */
+		struct {
+			__u8	rpv[KVM_CAP_ARM_RME_RPV_SIZE];
+		};
+
+		/* cfg == KVM_CAP_ARM_RME_CFG_HASH_ALGO */
+		struct {
+			__u32	hash_algo;
+		};
+
+		/* Fix the size of the union */
+		__u8	reserved[256];
+	};
+};
+
+#define KVM_ARM_RME_POPULATE_FLAGS_MEASURE	BIT(0)
+struct kvm_cap_arm_rme_populate_realm_args {
+	__u64 populate_ipa_base;
+	__u64 populate_ipa_size;
+	__u32 flags;
+	__u32 reserved[3];
+};
+
+struct kvm_cap_arm_rme_init_ipa_args {
+	__u64 init_ipa_base;
+	__u64 init_ipa_size;
+	__u32 reserved[4];
+};
+
 /* Device Control API on vcpu fd */
 #define KVM_ARM_VCPU_PMU_V3_CTRL	0
 #define   KVM_ARM_VCPU_PMU_V3_IRQ	0
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 502ea63b5d2e..f448198838cf 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -934,6 +934,8 @@ struct kvm_enable_cap {
 #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237
 #define KVM_CAP_X86_GUEST_MODE 238
 
+#define KVM_CAP_ARM_RME 300 /* FIXME: Large number to prevent conflicts */
+
 struct kvm_irq_routing_irqchip {
 	__u32 irqchip;
 	__u32 pin;
@@ -1581,4 +1583,14 @@ struct kvm_pre_fault_memory {
 	__u64 padding[5];
 };
 
+/* Available with KVM_CAP_ARM_RME, only for VMs with KVM_VM_TYPE_ARM_REALM  */
+struct kvm_arm_rmm_psci_complete {
+	__u64 target_mpidr;
+	__u32 psci_status;
+	__u32 padding[3];
+};
+
+/* FIXME: Update nr (0xd2) when merging */
+#define KVM_ARM_VCPU_RMM_PSCI_COMPLETE	_IOW(KVMIO, 0xd2, struct kvm_arm_rmm_psci_complete)
+
 #endif /* __LINUX_KVM_H */
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:33 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:33 +0000
Subject: [PATCH v6 08/43] arm64: RME: ioctls to create and configure realms
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-9-steven.price@arm.com>

Add the KVM_CAP_ARM_RME_CREATE_RD ioctl to create a realm. This involves
delegating pages to the RMM to hold the Realm Descriptor (RD) and for
the base level of the Realm Translation Tables (RTT). A VMID also need
to be picked, since the RMM has a separate VMID address space a
dedicated allocator is added for this purpose.

KVM_CAP_ARM_RME_CONFIG_REALM is provided to allow configuring the realm
before it is created. Configuration options can be classified as:

 1. Parameters specific to the Realm stage2 (e.g. IPA Size, vmid, stage2
    entry level, entry level RTTs, number of RTTs in start level, LPA2)
    Most of these are not measured by RMM and comes from KVM book
    keeping.

 2. Parameters controlling "Arm Architecture features for the VM". (e.g.
    SVE VL, PMU counters, number of HW BRPs/WPs), configured by the VMM
    using the "user ID register write" mechanism. These will be
    supported in the later patches.

 3. Parameters are not part of the core Arm architecture but defined
    by the RMM spec (e.g. Hash algorithm for measurement,
    Personalisation value). These are programmed via
    KVM_CAP_ARM_RME_CONFIG_REALM.

For the IPA size there is the possibility that the RMM supports a
different size to the IPA size supported by KVM for normal guests. At
the moment the 'normal limit' is exposed by KVM_CAP_ARM_VM_IPA_SIZE and
the IPA size is configured by the bottom bits of vm_type in
KVM_CREATE_VM. This means that it isn't easy for the VMM to discover
what IPA sizes are supported for Realm guests. Since the IPA is part of
the measurement of the realm guest the current expectation is that the
VMM will be required to pick the IPA size demanded by attestation and
therefore simply failing if this isn't available is fine. An option
would be to expose a new capability ioctl to obtain the RMM's maximum
IPA size if this is needed in the future.

Co-developed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
Changes since v5:
 * Introduce free_delegated_granule() to replace many
   undelegate/free_page() instances and centralise the comment on
   leaking when the undelegate fails.
 * Several other minor improvements suggested by reviews - thanks for
   the feedback!
Changes since v2:
 * Improved commit description.
 * Improved return failures for rmi_check_version().
 * Clear contents of PGD after it has been undelegated in case the RMM
   left stale data.
 * Minor changes to reflect changes in previous patches.
---
 arch/arm64/include/asm/kvm_emulate.h |   5 +
 arch/arm64/include/asm/kvm_rme.h     |  19 ++
 arch/arm64/kvm/arm.c                 |  18 ++
 arch/arm64/kvm/mmu.c                 |  22 +-
 arch/arm64/kvm/rme.c                 | 296 +++++++++++++++++++++++++++
 5 files changed, 358 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 4d417e39763e..27f54a7778aa 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -715,6 +715,11 @@ static inline enum realm_state kvm_realm_state(struct kvm *kvm)
 	return READ_ONCE(kvm->arch.realm.state);
 }
 
+static inline bool kvm_realm_is_created(struct kvm *kvm)
+{
+	return kvm_is_realm(kvm) && kvm_realm_state(kvm) != REALM_STATE_NONE;
+}
+
 static inline bool vcpu_is_rec(struct kvm_vcpu *vcpu)
 {
 	return false;
diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_rme.h
index 69af5c3a1e44..209cd99f03dd 100644
--- a/arch/arm64/include/asm/kvm_rme.h
+++ b/arch/arm64/include/asm/kvm_rme.h
@@ -6,6 +6,8 @@
 #ifndef __ASM_KVM_RME_H
 #define __ASM_KVM_RME_H
 
+#include <uapi/linux/kvm.h>
+
 /**
  * enum realm_state - State of a Realm
  */
@@ -46,11 +48,28 @@ enum realm_state {
  * struct realm - Additional per VM data for a Realm
  *
  * @state: The lifetime state machine for the realm
+ * @rd: Kernel mapping of the Realm Descriptor (RD)
+ * @params: Parameters for the RMI_REALM_CREATE command
+ * @num_aux: The number of auxiliary pages required by the RMM
+ * @vmid: VMID to be used by the RMM for the realm
+ * @ia_bits: Number of valid Input Address bits in the IPA
  */
 struct realm {
 	enum realm_state state;
+
+	void *rd;
+	struct realm_params *params;
+
+	unsigned long num_aux;
+	unsigned int vmid;
+	unsigned int ia_bits;
 };
 
 void kvm_init_rme(void);
+u32 kvm_realm_ipa_limit(void);
+
+int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap);
+int kvm_init_realm_vm(struct kvm *kvm);
+void kvm_destroy_realm(struct kvm *kvm);
 
 #endif
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 93087eca9c51..2bbf30d66424 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -153,6 +153,13 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 		}
 		mutex_unlock(&kvm->slots_lock);
 		break;
+	case KVM_CAP_ARM_RME:
+		if (!kvm_is_realm(kvm))
+			return -EINVAL;
+		mutex_lock(&kvm->lock);
+		r = kvm_realm_enable_cap(kvm, cap);
+		mutex_unlock(&kvm->lock);
+		break;
 	default:
 		break;
 	}
@@ -215,6 +222,13 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 
 	bitmap_zero(kvm->arch.vcpu_features, KVM_VCPU_MAX_FEATURES);
 
+	/* Initialise the realm bits after the generic bits are enabled */
+	if (kvm_is_realm(kvm)) {
+		ret = kvm_init_realm_vm(kvm);
+		if (ret)
+			goto err_free_cpumask;
+	}
+
 	return 0;
 
 err_free_cpumask:
@@ -274,6 +288,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 	kvm_unshare_hyp(kvm, kvm + 1);
 
 	kvm_arm_teardown_hypercalls(kvm);
+	kvm_destroy_realm(kvm);
 }
 
 static bool kvm_has_full_ptr_auth(void)
@@ -421,6 +436,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES:
 		r = BIT(0);
 		break;
+	case KVM_CAP_ARM_RME:
+		r = static_key_enabled(&kvm_rme_is_available);
+		break;
 	default:
 		r = 0;
 	}
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index c9d46ad57e52..f09d580c12ad 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -863,12 +863,16 @@ static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = {
 	.icache_inval_pou	= invalidate_icache_guest_page,
 };
 
-static int kvm_init_ipa_range(struct kvm_s2_mmu *mmu, unsigned long type)
+static int kvm_init_ipa_range(struct kvm *kvm,
+			      struct kvm_s2_mmu *mmu, unsigned long type)
 {
 	u32 kvm_ipa_limit = get_kvm_ipa_limit();
 	u64 mmfr0, mmfr1;
 	u32 phys_shift;
 
+	if (kvm_is_realm(kvm))
+		kvm_ipa_limit = kvm_realm_ipa_limit();
+
 	if (type & ~KVM_VM_TYPE_ARM_IPA_SIZE_MASK)
 		return -EINVAL;
 
@@ -933,7 +937,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 		return -EINVAL;
 	}
 
-	err = kvm_init_ipa_range(mmu, type);
+	err = kvm_init_ipa_range(kvm, mmu, type);
 	if (err)
 		return err;
 
@@ -1056,6 +1060,20 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
 	struct kvm_pgtable *pgt = NULL;
 
 	write_lock(&kvm->mmu_lock);
+	if (kvm_is_realm(kvm) &&
+	    (kvm_realm_state(kvm) != REALM_STATE_DEAD &&
+	     kvm_realm_state(kvm) != REALM_STATE_NONE)) {
+		/* Tearing down RTTs will be added in a later patch */
+		write_unlock(&kvm->mmu_lock);
+
+		/*
+		 * The physical PGD pages are delegated to the RMM, so cannot
+		 * be freed at this point. This function will be called again
+		 * from kvm_destroy_realm() after the physical pages have been
+		 * returned at which point the memory can be freed.
+		 */
+		return;
+	}
 	pgt = mmu->pgt;
 	if (pgt) {
 		mmu->pgd_phys = 0;
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index b88269b80c11..5530ec2653b7 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
@@ -5,9 +5,20 @@
 
 #include <linux/kvm_host.h>
 
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_mmu.h>
 #include <asm/rmi_cmds.h>
 #include <asm/virt.h>
 
+#include <asm/kvm_pgtable.h>
+
+static unsigned long rmm_feat_reg0;
+
+static bool rme_supports(unsigned long feature)
+{
+	return !!u64_get_bits(rmm_feat_reg0, feature);
+}
+
 static int rmi_check_version(void)
 {
 	struct arm_smccc_res res;
@@ -36,6 +47,285 @@ static int rmi_check_version(void)
 	return 0;
 }
 
+u32 kvm_realm_ipa_limit(void)
+{
+	return u64_get_bits(rmm_feat_reg0, RMI_FEATURE_REGISTER_0_S2SZ);
+}
+
+static int get_start_level(struct realm *realm)
+{
+	return 4 - stage2_pgtable_levels(realm->ia_bits);
+}
+
+static void free_delegated_granule(phys_addr_t phys)
+{
+	if (WARN_ON(rmi_granule_undelegate(phys))) {
+		/* Undelegate failed: leak the page */
+		return;
+	}
+
+	free_page((unsigned long)phys_to_virt(phys));
+}
+
+static int realm_create_rd(struct kvm *kvm)
+{
+	struct realm *realm = &kvm->arch.realm;
+	struct realm_params *params = realm->params;
+	void *rd = NULL;
+	phys_addr_t rd_phys, params_phys;
+	size_t pgd_size = kvm_pgtable_stage2_pgd_size(kvm->arch.mmu.vtcr);
+	int i, r;
+
+	if (WARN_ON(realm->rd) || WARN_ON(!realm->params))
+		return -EEXIST;
+
+	rd = (void *)__get_free_page(GFP_KERNEL);
+	if (!rd)
+		return -ENOMEM;
+
+	rd_phys = virt_to_phys(rd);
+	if (rmi_granule_delegate(rd_phys)) {
+		r = -ENXIO;
+		goto free_rd;
+	}
+
+	for (i = 0; i < pgd_size; i += PAGE_SIZE) {
+		phys_addr_t pgd_phys = kvm->arch.mmu.pgd_phys + i;
+
+		if (rmi_granule_delegate(pgd_phys)) {
+			r = -ENXIO;
+			goto out_undelegate_tables;
+		}
+	}
+
+	realm->ia_bits = VTCR_EL2_IPA(kvm->arch.mmu.vtcr);
+
+	params->s2sz = VTCR_EL2_IPA(kvm->arch.mmu.vtcr);
+	params->rtt_level_start = get_start_level(realm);
+	params->rtt_num_start = pgd_size / PAGE_SIZE;
+	params->rtt_base = kvm->arch.mmu.pgd_phys;
+	params->vmid = realm->vmid;
+
+	params_phys = virt_to_phys(params);
+
+	if (rmi_realm_create(rd_phys, params_phys)) {
+		r = -ENXIO;
+		goto out_undelegate_tables;
+	}
+
+	if (WARN_ON(rmi_rec_aux_count(rd_phys, &realm->num_aux))) {
+		WARN_ON(rmi_realm_destroy(rd_phys));
+		goto out_undelegate_tables;
+	}
+
+	realm->rd = rd;
+
+	return 0;
+
+out_undelegate_tables:
+	while (--i >= 0) {
+		phys_addr_t pgd_phys = kvm->arch.mmu.pgd_phys + i * PAGE_SIZE;
+
+		if (WARN_ON(rmi_granule_undelegate(pgd_phys))) {
+			/* Leak the pages if they cannot be returned */
+			kvm->arch.mmu.pgt = NULL;
+			break;
+		}
+	}
+	if (WARN_ON(rmi_granule_undelegate(rd_phys))) {
+		/* Leak the page if it isn't returned */
+		return r;
+	}
+free_rd:
+	free_page((unsigned long)rd);
+	return r;
+}
+
+/* Protects access to rme_vmid_bitmap */
+static DEFINE_SPINLOCK(rme_vmid_lock);
+static unsigned long *rme_vmid_bitmap;
+
+static int rme_vmid_init(void)
+{
+	unsigned int vmid_count = 1 << kvm_get_vmid_bits();
+
+	rme_vmid_bitmap = bitmap_zalloc(vmid_count, GFP_KERNEL);
+	if (!rme_vmid_bitmap) {
+		kvm_err("%s: Couldn't allocate rme vmid bitmap\n", __func__);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int rme_vmid_reserve(void)
+{
+	int ret;
+	unsigned int vmid_count = 1 << kvm_get_vmid_bits();
+
+	spin_lock(&rme_vmid_lock);
+	ret = bitmap_find_free_region(rme_vmid_bitmap, vmid_count, 0);
+	spin_unlock(&rme_vmid_lock);
+
+	return ret;
+}
+
+static void rme_vmid_release(unsigned int vmid)
+{
+	spin_lock(&rme_vmid_lock);
+	bitmap_release_region(rme_vmid_bitmap, vmid, 0);
+	spin_unlock(&rme_vmid_lock);
+}
+
+static int kvm_create_realm(struct kvm *kvm)
+{
+	struct realm *realm = &kvm->arch.realm;
+	int ret;
+
+	if (!kvm_is_realm(kvm))
+		return -EINVAL;
+	if (kvm_realm_is_created(kvm))
+		return -EEXIST;
+
+	ret = rme_vmid_reserve();
+	if (ret < 0)
+		return ret;
+	realm->vmid = ret;
+
+	ret = realm_create_rd(kvm);
+	if (ret) {
+		rme_vmid_release(realm->vmid);
+		return ret;
+	}
+
+	WRITE_ONCE(realm->state, REALM_STATE_NEW);
+
+	/* The realm is up, free the parameters.  */
+	free_page((unsigned long)realm->params);
+	realm->params = NULL;
+
+	return 0;
+}
+
+static int config_realm_hash_algo(struct realm *realm,
+				  struct kvm_cap_arm_rme_config_item *cfg)
+{
+	switch (cfg->hash_algo) {
+	case KVM_CAP_ARM_RME_MEASUREMENT_ALGO_SHA256:
+		if (!rme_supports(RMI_FEATURE_REGISTER_0_HASH_SHA_256))
+			return -EINVAL;
+		break;
+	case KVM_CAP_ARM_RME_MEASUREMENT_ALGO_SHA512:
+		if (!rme_supports(RMI_FEATURE_REGISTER_0_HASH_SHA_512))
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+	realm->params->hash_algo = cfg->hash_algo;
+	return 0;
+}
+
+static int kvm_rme_config_realm(struct kvm *kvm, struct kvm_enable_cap *cap)
+{
+	struct kvm_cap_arm_rme_config_item cfg;
+	struct realm *realm = &kvm->arch.realm;
+	int r = 0;
+
+	if (kvm_realm_is_created(kvm))
+		return -EBUSY;
+
+	if (copy_from_user(&cfg, (void __user *)cap->args[1], sizeof(cfg)))
+		return -EFAULT;
+
+	switch (cfg.cfg) {
+	case KVM_CAP_ARM_RME_CFG_RPV:
+		memcpy(&realm->params->rpv, &cfg.rpv, sizeof(cfg.rpv));
+		break;
+	case KVM_CAP_ARM_RME_CFG_HASH_ALGO:
+		r = config_realm_hash_algo(realm, &cfg);
+		break;
+	default:
+		r = -EINVAL;
+	}
+
+	return r;
+}
+
+int kvm_realm_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
+{
+	int r = 0;
+
+	if (!kvm_is_realm(kvm))
+		return -EINVAL;
+
+	switch (cap->args[0]) {
+	case KVM_CAP_ARM_RME_CONFIG_REALM:
+		r = kvm_rme_config_realm(kvm, cap);
+		break;
+	case KVM_CAP_ARM_RME_CREATE_RD:
+		r = kvm_create_realm(kvm);
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+
+	return r;
+}
+
+void kvm_destroy_realm(struct kvm *kvm)
+{
+	struct realm *realm = &kvm->arch.realm;
+	size_t pgd_size = kvm_pgtable_stage2_pgd_size(kvm->arch.mmu.vtcr);
+	int i;
+
+	if (realm->params) {
+		free_page((unsigned long)realm->params);
+		realm->params = NULL;
+	}
+
+	if (!kvm_realm_is_created(kvm))
+		return;
+
+	WRITE_ONCE(realm->state, REALM_STATE_DYING);
+
+	if (realm->rd) {
+		phys_addr_t rd_phys = virt_to_phys(realm->rd);
+
+		if (WARN_ON(rmi_realm_destroy(rd_phys)))
+			return;
+		free_delegated_granule(rd_phys);
+		realm->rd = NULL;
+	}
+
+	rme_vmid_release(realm->vmid);
+
+	for (i = 0; i < pgd_size; i += PAGE_SIZE) {
+		phys_addr_t pgd_phys = kvm->arch.mmu.pgd_phys + i;
+
+		if (WARN_ON(rmi_granule_undelegate(pgd_phys)))
+			return;
+	}
+
+	WRITE_ONCE(realm->state, REALM_STATE_DEAD);
+
+	/* Now that the Realm is destroyed, free the entry level RTTs */
+	kvm_free_stage2_pgd(&kvm->arch.mmu);
+}
+
+int kvm_init_realm_vm(struct kvm *kvm)
+{
+	struct realm_params *params;
+
+	params = (struct realm_params *)get_zeroed_page(GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+
+	kvm->arch.realm.params = params;
+	return 0;
+}
+
 void kvm_init_rme(void)
 {
 	if (PAGE_SIZE != SZ_4K)
@@ -46,5 +336,11 @@ void kvm_init_rme(void)
 		/* Continue without realm support */
 		return;
 
+	if (WARN_ON(rmi_features(0, &rmm_feat_reg0)))
+		return;
+
+	if (rme_vmid_init())
+		return;
+
 	/* Future patch will enable static branch kvm_rme_is_available */
 }
-- 
2.43.0



From steven.price at arm.com  Thu Dec 12 07:55:34 2024
From: steven.price at arm.com (Steven Price)
Date: Thu, 12 Dec 2024 15:55:34 +0000
Subject: [PATCH v6 09/43] kvm: arm64: Expose debug HW register numbers for Realm
In-Reply-To: <20241212155610.76522-1-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
Message-ID: <20241212155610.76522-10-steven.price@arm.com>

From: Suzuki K Poulose <suzuki.poulose at arm.com>

Expose VM specific Debug HW register numbers.

Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Steven Price <steven.price at arm.com>
---
 arch/arm64/kvm/arm.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 2bbf30d66424..c505ec61180a 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -78,6 +78,22 @@ bool is_kvm_arm_initialised(void)
 	return kvm_arm_initialised;
 }
 
+static u32 kvm_arm_get_num_brps(struct kvm *kvm)
+{
+	if (!kvm_is_realm(kvm))
+		return get_num_brps();
+	/* Realm guest is not debuggable. */
+	return 0;
+}
+
+static u32 kvm_arm_get_num_wrps(struct kvm *kvm)
+{
+	if (!kvm_is_realm(kvm))
+		return get_num_wrps();
+	/* Realm guest is not debuggable. */
+	return 0;
+}
+
 int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
 {
 	return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
@@ -350,7 +366,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_IRQ_LINE_LAYOUT_2:
 	case KVM_CAP_ARM_NISV_TO_USER:
 	case KVM_CAP_ARM_INJECT_EXT_DABT:
-	case KVM_CAP_SET_GUEST_DEBUG:
 	case KVM_CAP_VCPU_ATTRIBUTES:
 	case KVM_CAP_PTP_KVM:
 	case KVM_CAP_ARM_SYSTEM_SUSPEND:
@@ -358,6 +373,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_COUNTER_OFFSET:
 		r = 1;
 		break;
+	case KVM_CAP_SET_GUEST_DEBUG:
+		r = !kvm_is_realm(kvm);
+		break;
 	case KVM_CAP_SET_GUEST_DEBUG2:
 		return KVM_GUESTDBG_VALID_MASK;
 	case KVM_CAP_ARM_SET_DEVICE_ADDR:
@@ -403,10 +421,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		r = cpus_have_final_cap(ARM64_HAS_32BIT_EL1);
 		break;
 	case KVM_CAP_GUEST_DEBUG_HW_BPS:
-		r = get_num_brps();
+		r = kvm_arm_get_num_brps(kvm);
 		break;
 	case KVM_CAP_GUEST_DEBUG_HW_WPS:
-		r = get_num_wrps();
+		r = kvm_arm_get_num_wrps(kvm);
 		break;
 	case KVM_CAP_ARM_PMU_V3:
 		r = kvm_arm_support_pmu_v3();
-- 
2.43.0



From helgaas at kernel.org  Thu Dec 12 08:15:24 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 12 Dec 2024 10:15:24 -0600
Subject: [net-next v1] net: wwan: t7xx: Fix FSM command timeout issue
In-Reply-To: <20241212105555.10364-1-jinjian.song@fibocom.com>
Message-ID: <20241212161524.GA3345429@bhelgaas>

On Thu, Dec 12, 2024 at 06:55:55PM +0800, Jinjian Song wrote:
> When driver processes the internal state change command, it use
> asynchronous thread to process the command operation. If the main
> thread detects that the task has timed out, the asynchronous thread
> will panic when executing te completion notification because the
> main thread completion object is released.

s/it use/it uses an/
s/te/the/
s/is released/has been released/


From joey.gouly at arm.com  Thu Dec 12 08:54:40 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Thu, 12 Dec 2024 16:54:40 +0000
Subject: [PATCH v6 32/43] arm64: rme: Enable PMU support with a realm
 guest
In-Reply-To: <20241212155610.76522-33-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
 <20241212155610.76522-33-steven.price@arm.com>
Message-ID: <20241212165440.GA1479329@e124191.cambridge.arm.com>

On Thu, Dec 12, 2024 at 03:55:57PM +0000, Steven Price wrote:
> Use the PMU registers from the RmiRecExit structure to identify when an
> overflow interrupt is due and inject it into the guest. Also hook up the
> configuration option for enabling the PMU within the guest.
> 
> When entering a realm guest with a PMU interrupt pending, it is
> necessary to disable the physical interrupt. Otherwise when the RMM
> restores the PMU state the physical interrupt will trigger causing an
> immediate exit back to the host. The guest is expected to acknowledge
> the interrupt causing a host exit (to update the GIC state) which gives
> the opportunity to re-enable the physical interrupt before the next PMU
> event.
> 
> Number of PMU counters is configured by the VMM by writing to PMCR.N.
> 
> Signed-off-by: Steven Price <steven.price at arm.com>
> ---
> Changes since v2:
>  * Add a macro kvm_pmu_get_irq_level() to avoid compile issues when PMU
>    support is disabled.
> ---
>  arch/arm64/kvm/arm.c      | 11 +++++++++++
>  arch/arm64/kvm/guest.c    |  7 +++++++
>  arch/arm64/kvm/pmu-emul.c |  3 +++
>  arch/arm64/kvm/rme.c      |  8 ++++++++
>  arch/arm64/kvm/sys_regs.c |  2 +-
>  include/kvm/arm_pmu.h     |  4 ++++
>  6 files changed, 34 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 6f7f96ab781d..ae3596a25272 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -15,6 +15,7 @@
>  #include <linux/vmalloc.h>
>  #include <linux/fs.h>
>  #include <linux/mman.h>
> +#include <linux/perf/arm_pmu.h>
>  #include <linux/sched.h>
>  #include <linux/kvm.h>
>  #include <linux/kvm_irqfd.h>
> @@ -1209,6 +1210,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
>  	run->exit_reason = KVM_EXIT_UNKNOWN;
>  	run->flags = 0;
>  	while (ret > 0) {
> +		bool pmu_stopped = false;
> +
>  		/*
>  		 * Check conditions before entering the guest
>  		 */
> @@ -1240,6 +1243,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
>  
>  		kvm_pmu_flush_hwstate(vcpu);
>  
> +		if (vcpu_is_rec(vcpu) && kvm_pmu_get_irq_level(vcpu)) {
> +			pmu_stopped = true;
> +			arm_pmu_set_phys_irq(false);
> +		}
> +
>  		local_irq_disable();
>  
>  		kvm_vgic_flush_hwstate(vcpu);
> @@ -1342,6 +1350,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
>  
>  		preempt_enable();
>  
> +		if (pmu_stopped)
> +			arm_pmu_set_phys_irq(true);
> +
>  		/*
>  		 * The ARMv8 architecture doesn't give the hypervisor
>  		 * a mechanism to prevent a guest from dropping to AArch32 EL0
> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
> index 920e0fd73698..b4e3839f6076 100644
> --- a/arch/arm64/kvm/guest.c
> +++ b/arch/arm64/kvm/guest.c
> @@ -804,6 +804,8 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
>  	return kvm_arm_sys_reg_get_reg(vcpu, reg);
>  }
>  
> +#define KVM_REG_ARM_PMCR_EL0		ARM64_SYS_REG(3, 3, 9, 12, 0)

There's already SYS_PMCR_EL0 defined, so it seems this is not needed?

> +
>  /*
>   * The RMI ABI only enables setting some GPRs and PC. The selection of GPRs
>   * that are available depends on the Realm state and the reason for the last
> @@ -818,6 +820,11 @@ static bool validate_realm_set_reg(struct kvm_vcpu *vcpu,
>  		u64 off = core_reg_offset_from_id(reg->id);
>  
>  		return kvm_realm_validate_core_reg(off);
> +	} else {
> +		switch (reg->id) {
> +		case KVM_REG_ARM_PMCR_EL0:
> +			return true;
> +		}
>  	}
>  
>  	return false;
> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> index 456102bc0b55..5628b573ca41 100644
> --- a/arch/arm64/kvm/pmu-emul.c
> +++ b/arch/arm64/kvm/pmu-emul.c
> @@ -397,6 +397,9 @@ static bool kvm_pmu_overflow_status(struct kvm_vcpu *vcpu)
>  {
>  	u64 reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);
>  
> +	if (vcpu_is_rec(vcpu))
> +		return vcpu->arch.rec.run->exit.pmu_ovf_status;
> +
>  	reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1);
>  
>  	/*
> diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
> index 27a479feb907..e562e77c1f94 100644
> --- a/arch/arm64/kvm/rme.c
> +++ b/arch/arm64/kvm/rme.c
> @@ -303,6 +303,11 @@ static int realm_create_rd(struct kvm *kvm)
>  	params->rtt_base = kvm->arch.mmu.pgd_phys;
>  	params->vmid = realm->vmid;
>  
> +	if (kvm->arch.arm_pmu) {
> +		params->pmu_num_ctrs = kvm->arch.pmcr_n;
> +		params->flags |= RMI_REALM_PARAM_FLAG_PMU;
> +	}
> +
>  	params_phys = virt_to_phys(params);
>  
>  	if (rmi_realm_create(rd_phys, params_phys)) {
> @@ -1370,6 +1375,9 @@ int kvm_create_rec(struct kvm_vcpu *vcpu)
>  	if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_PSCI_0_2))
>  		return -EINVAL;
>  
> +	if (vcpu->kvm->arch.arm_pmu && !kvm_vcpu_has_pmu(vcpu))
> +		return -EINVAL;
> +
>  	BUILD_BUG_ON(sizeof(*params) > PAGE_SIZE);
>  	BUILD_BUG_ON(sizeof(*rec->run) > PAGE_SIZE);
>  
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 83c6b4a07ef5..a4713609e230 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1324,7 +1324,7 @@ static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
>  	 * implements. Ignore this error to maintain compatibility
>  	 * with the existing KVM behavior.
>  	 */
> -	if (!kvm_vm_has_ran_once(kvm) &&
> +	if (!kvm_vm_has_ran_once(kvm) && !kvm_realm_is_created(kvm) &&
>  	    new_n <= kvm_arm_pmu_get_max_counters(kvm))
>  		kvm->arch.pmcr_n = new_n;
>  
> diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
> index e61dd7dd2286..30625a6fd143 100644
> --- a/include/kvm/arm_pmu.h
> +++ b/include/kvm/arm_pmu.h
> @@ -77,6 +77,8 @@ void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu);
>  void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu);
>  void kvm_vcpu_pmu_resync_el0(void);
>  
> +#define kvm_pmu_get_irq_level(vcpu) ((vcpu)->arch.pmu.irq_level)
> +
>  #define kvm_vcpu_has_pmu(vcpu)					\
>  	(vcpu_has_feature(vcpu, KVM_ARM_VCPU_PMU_V3))
>  
> @@ -164,6 +166,8 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
>  	return 0;
>  }
>  
> +#define kvm_pmu_get_irq_level(vcpu) (false)
> +
>  #define kvm_vcpu_has_pmu(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) {}

Thanks,
Joey


From benjamin.gaignard at collabora.com  Thu Dec 12 08:15:11 2024
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Thu, 12 Dec 2024 17:15:11 +0100
Subject: [PATCH v2 0/2] media: verisilicon: fix reference padding issue
In-Reply-To: <CAOMZO5DgW3YrpMJPCTzQ-LZCopB4tNPoJhyFQrr6RBvbnBu4VA@mail.gmail.com>
References: <01020193bb8a24ad-99eafebb-3b0b-40c0-9b28-3a0dbc84327a-000000@eu-west-1.amazonses.com>
 <CAOMZO5DgW3YrpMJPCTzQ-LZCopB4tNPoJhyFQrr6RBvbnBu4VA@mail.gmail.com>
Message-ID: <21db56f1-ee5d-4309-8fa6-5aaf92782885@collabora.com>


Le 12/12/2024 ? 17:10, Fabio Estevam a ?crit?:
> On Thu, Dec 12, 2024 at 12:43?PM Benjamin Gaignard
> <benjamin.gaignard at collabora.com> wrote:
>> Hantro hardware is splited into two parts: the decoder which produce
>> tiled pixels formats and the post-processor which produce raster pixels
>> formats.
>> When post-processor is used the selected pixels format may not have the
>> some padding/stride than the decoder output pixels format. This led to
>> miscomputing chroma and motion vectors offsets so data are overlapping.
>> This series introduce a reference pixels format that decoder use to
>> compute the various needed offsets and size.
>>
>> With this series Fluster for VP9 tests is now 207/305 vs 145/305.
>> HEVC test score isn't impacted by these patches (still 141/147).
>>
>> Version 2:
>> - rebased on top of media-commiter/next
>> - Add reviewed-by tags
>>
>> Benjamin Gaignard (2):
>>    media: verisilicon: Store reference frames pixels format
>>    media: verisilicon: Fix IMX8 native pixels format steps values
> Do both patches deserve a Fixes tag?

There is dependency in around hevc compress feature in post-proc code.
I don't think it could be applied on stable kernel



From Dave.Martin at arm.com  Thu Dec 12 08:17:56 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 16:17:56 +0000
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 0/5] arm_mpam:
 Introduce the Narrow-PARTID feature for MPAM driver
In-Reply-To: <20241207092136.2488426-1-zengheng4@huawei.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
Message-ID: <Z1sMtF9bvw5NZOC6@e133380.arm.com>

Hi,

On Sat, Dec 07, 2024 at 05:21:31PM +0800, Zeng Heng wrote:
> The patch set is applied for mpam/snapshot/v6.12-rc1 branch of
> https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git
> repository.
> 
> The narrow-partid feature in MPAM allows for a more efficient use of
> PARTIDs by enabling a many-to-one mapping of reqpartids (requested PARTIDs)
> to intpartids (internal PARTIDs). This mapping reduces the number of unique
> PARTIDs needed, thus allowing more tasks or processes to be monitored and
> managed with the available resources.
> 
> For a mixture of MSCs system, for MSCs that do not support narrow-partid,
> we use the PARTIDs exceeding the number of closids as reqPARTIDs for
> expanding the monitoring groups.

Mixed systems still seem not to be handled completely by this series?

You do cope with the scenario where some MSCs support Narrowing and
some do not, but there is still the problem of incompatible controls.

If a non-Narrowing MSC has controls that are not of the "partition
bitmap" type, then splitting a resctrl control group across multiple
PARTIDs is going to change the hardware regulation behaviour.  There
does not seem to be any way to work around this be programming
different control values (for example).  So, there may be over- or
under-allocation of resources compared with what the user requests in
resctrlfs.

So, I think there is still a need to check which controls are present,
and either disable the use of non-identity intPARTID<->reqPARTID
mappings if incompatible controls are present (or don't expose those
controls to resctrl).

(If you were not trying to address this issue yet then that is not a
problem for an RFC, but it is best to be clear about the
limitations...)

> In order to keep the existing resctrl API interface, the rmid contains both
> req_idx and PMG information instead of PMG only under the MPAM driver. The
> req_idx represents the req_idx-th sub-monitoring group under the control
> group. The new rmid would be like:
> 
>     rmid = (req_idx << shift | pmg).
> 
> The new conversion relationship between closid/rmid and (req)PARTID/PMG is:
> 
>     (req)PARTID = (rmid.req_idx * n) + closid,
>     PMG = rmid.pmg.
> 
> Each intPARTID has m reqPARTIDs, which are used to expand the number of
> monitoring groups under the control group. Therefore, the number of
> monitoring groups is no longer limited by the range of MPAM PMG, which
> enhances the extensibility of the system's monitoring capabilities.
> 
> ---
> Compared with v1:
>   - Rebase this patch set on latest MPAM driver of the v6.12-rc1 branch.
> 
> Compared with v2:
>   - Refactor closid/rmid pair translation
>   - Simplify the logic of synchronize configuration
>   - Remove reqPARTID pool
> ---

This approach looks reasonable overall, and in this version the changes
do seem to be better localised in the mpam_resctrl.c glue code now.

I had also been working on a similar approach, so I have posted it for
comparison [1] -- though the two approaches are doing pretty much the
same thing, some details differ.

(Note, I have not addressed PARTID Narrowing at all yet; however,
I think more thought is needed for that.)


Note: Are there bisection issues with some of the patches in the
series?  It looks like not all of the ID conversions are applied in the
same patch, so I'm wondering whether strange behaviour may be seen at
the intermediate commits.

Cheers
---Dave


[1] [RFC PATCH 0/6] Introduce flexible CLOSID/RMID translation
https://lore.kernel.org/lkml/20241212154000.330467-1-Dave.Martin at arm.com/


From Dave.Martin at arm.com  Thu Dec 12 08:18:12 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 16:18:12 +0000
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 2/5] arm_mpam: Read
 monitor value with new closid/rmid pair
In-Reply-To: <20241207092136.2488426-3-zengheng4@huawei.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
 <20241207092136.2488426-3-zengheng4@huawei.com>
Message-ID: <Z1sMxKM9o6lAiZGr@e133380.arm.com>

Hi,

On Sat, Dec 07, 2024 at 05:21:33PM +0800, Zeng Heng wrote:
> The MPAM driver statically assigns all reqPARTIDs to respective intPARTIDs.
> For the new rmid allocation strategy, it will check if there is an
> available rmid of any reqPARTID which belongs to the input closid, not just
> the rmids belonging to the closid.
> 
> For a mixture of MSCs system, for MSCs that do not support narrow-partid,
> we use the PARTIDs exceeding the number of closids as reqPARTIDs for
> expanding the monitoring groups.
> 
> In order to keep the existing resctrl API interface, the rmid contains both
> req_idx and PMG information instead of PMG only under the MPAM driver. The
> req_idx represents the req_idx-th sub-monitoring group under the control
> group. The new rmid would be like:
> 
>     rmid = (req_idx << shift | pmg).
> 
> The mapping relationships between each group's closid/rmid and the
> respective MSCs' intPARTID/reqPARTID/PARTID are illustrated:
> 
> n - Indicates the total number of intPARTIDs
> m - Indicates the number of reqPARTIDs per intPARTID
> 
> P - Partition group (control group)
> M - Monitoring group
> 
> Group closid rmid.req_idx (req)PARTID      MSCs with narrow-partid  MSCs without narrow-partid
> P1    0      -            0                   intPARTID_1              PARTID_1
> M1_1  0      0            0                       ??? reqPARTID_1_1       ??? PARTID_1_1
> M1_2  0      1            0+n                     ??? reqPARTID_1_2       ??? PARTID_1_2
> M1_3  0      2            0+n*2                   ??? reqPARTID_1_3       ??? PARTID_1_3
>  ...                                              ??? ...                 ??? ...
> M1_m  0      (m-1)        0+n*(m-1)               ??? reqPARTID_1_m       ??? PARTID_1_m
> 
> P2    1      -            1                   intPARTID_2              PARTID_2
> M2_1  1      0            1                       ??? reqPARTID_2_1       ??? PARTID_2_1
> M2_2  1      1            1+n                     ??? reqPARTID_2_2       ??? PARTID_2_2
> M2_3  1      2            1+n*2                   ??? reqPARTID_2_3       ??? PARTID_2_3
>  ...                                              ??? ...                 ??? ...
> M2_m  1      (m-1)        1+n*(m-1)               ??? reqPARTID_2_m       ??? PARTID_2_m
> 
> Pn    (n-1)  -            (n-1)               intPARTID_n              PARTID_n
> Mn_1  (n-1)  0            (n-1)                   ??? reqPARTID_n_1       ??? PARTID_n_1
> Mn_2  (n-1)  1            (n-1)+n                 ??? reqPARTID_n_2       ??? PARTID_n_2
> Mn_3  (n-1)  2            (n-1)+n*2               ??? reqPARTID_n_3       ??? PARTID_n_3
>  ...                                              ??? ...                 ??? ...
> Mn_m  (n-1)  (m-1)        (n-1)+n*(m-1) = n*m-1   ??? reqPARTID_n_m       ??? PARTID_n_m
> 
> Based on the example provided, the conversion relationship between
> closid/rmid and (req)PARTID/PMG is:
> 
>     (req)PARTID = (rmid.req_idx * n) + closid,
>     PMG = rmid.pmg.

It seemed more natural to me for the PARTIDs assigned to a particular
CLOSID to be consecutively numbered (see [1]), though it works either
way.

Otherwise, the approach makes sense.

[...]

Cheers
---Dave


[1] [RFC PATCH 4/6] arm_mpam: Introduce flexible CLOSID/RMID translation
https://lore.kernel.org/lkml/20241212154000.330467-5-Dave.Martin at arm.com/


From Dave.Martin at arm.com  Thu Dec 12 08:18:53 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 16:18:53 +0000
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 4/5] arm_mpam:
 Automatically synchronize the configuration of all sub-monitoring groups
In-Reply-To: <20241207092136.2488426-5-zengheng4@huawei.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
 <20241207092136.2488426-5-zengheng4@huawei.com>
Message-ID: <Z1sM7TMK+BHQEwgI@e133380.arm.com>

Hi,

On Sat, Dec 07, 2024 at 05:21:35PM +0800, Zeng Heng wrote:
> After the system expands the narrow-partid feature and statically assigns
> all (req)PARTIDs to each control group, the following scenarios require
> configuration synchronization operations:
> 
>   1. MSCs that support narrow-partid need to establish a mapping between
>      reqPARTID and intPARTID after creating a new monitoring group.
>   2. MSCs that do not support narrow-partid need to synchronize the
>      configuration of sub-monitoring groups after users update the control
>      group configuration.
> 
> In __write_config(), we synchronize a control group's configuration to each
> sub-monitoring group.
> 
> Signed-off-by: Zeng Heng <zengheng4 at huawei.com>
> ---
>  drivers/platform/arm64/mpam/mpam_devices.c  | 25 ++++++++++++++++++---
>  drivers/platform/arm64/mpam/mpam_internal.h |  3 +++
>  drivers/platform/arm64/mpam/mpam_resctrl.c  | 10 ++++++++-
>  3 files changed, 34 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/platform/arm64/mpam/mpam_devices.c b/drivers/platform/arm64/mpam/mpam_devices.c
> index 781c9146718d..91c5849f76e3 100644
> --- a/drivers/platform/arm64/mpam/mpam_devices.c
> +++ b/drivers/platform/arm64/mpam/mpam_devices.c
> @@ -1544,6 +1544,7 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
>  	u32 pri_val = 0;
>  	u16 cmax = MPAMCFG_CMAX_CMAX;
>  	u16 bwa_fract = MPAMCFG_MBW_MAX_MAX;
> +	u16 intpartid = req2intpartid(partid);
>  	struct mpam_msc *msc = ris->vmsc->msc;
>  	struct mpam_props *rprops = &ris->props;
>  	u16 dspri = GENMASK(rprops->dspri_wd, 0);
> @@ -1554,8 +1555,14 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
>  
>  	if (mpam_has_feature(mpam_feat_partid_nrw, rprops)) {
>  		mpam_write_partsel_reg(msc, INTPARTID,
> -				       MPAMCFG_INTPARTID_INTERNAL | partid);
> -		__mpam_intpart_sel(ris->ris_idx, partid, msc);
> +				       MPAMCFG_INTPARTID_INTERNAL |
> +				       intpartid);
> +
> +		/* Already finish mapping reqPARTID to intPARTID */
> +		if (partid != intpartid)
> +			goto out;
> +
> +		__mpam_intpart_sel(ris->ris_idx, intpartid, msc);
>  	}
>  
>  	if (mpam_has_feature(mpam_feat_cpor_part, rprops)) {

[...]

> @@ -3072,9 +3080,20 @@ struct mpam_write_config_arg {
>  
>  static int __write_config(void *arg)
>  {
> +	int closid_num = resctrl_arch_get_num_closid(NULL);
>  	struct mpam_write_config_arg *c = arg;
> +	u32 reqpartid, req_idx;
> +
> +	WARN_ON(c->partid >= closid_num);
>  
> -	mpam_reprogram_ris_partid(c->ris, c->partid, &c->comp->cfg[c->partid]);
> +	/* Synchronize the configuration to each sub-monitoring group. */
> +	for (req_idx = 0; req_idx < get_num_reqpartid_per_closid();
> +	     req_idx++) {
> +		reqpartid = req_idx * closid_num + c->partid;
> +
> +		mpam_reprogram_ris_partid(c->ris, reqpartid,
> +					 &c->comp->cfg[c->partid]);
> +	}
>  
>  	return 0;
>  }

I haven't decided whether this iteration belongs here or in
mpam_resctrl.c.

Your approach looks like it should work; I do it in
resctrl_arch_update_one() instead [1], but I think the approaches are
pretty much equivalent -- but let me know if you have any thoughts on
it.

[...]

Cheers
---Dave


[1] [RFC PATCH 4/6] arm_mpam: Introduce flexible CLOSID/RMID translation
https://lore.kernel.org/lkml/20241212154000.330467-5-Dave.Martin at arm.com/


From dave.stevenson at raspberrypi.com  Thu Dec 12 08:18:50 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 16:18:50 +0000
Subject: [PATCH v2 0/7] drm/vc4: Fixup DT and DT binding issues from recent
 patchset
Message-ID: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>

I missed the DT errors from the recent patchset[1] (DT patches
in linux-next via Florian, DRM bindings patches on dri-misc-next)
as Rob's bot report got spam filtered, so this is a fixup set.

Largely it was changes to number of interrupts or clocks in the
bindings, so those are now covered.

I've fixed up the missing "interrupt-controller" flags for 2711
and 2712 whilst here.

I can't get my head around what is meant to happen with ranges:
"soc at 107c000000: firmware: 'ranges' is a required property"
The meaning seems obvious.

However if I add it then I get:
"firmware: '#address-cells', '#size-cells', 'dma-ranges', 'ranges' do
not match any of the regexes: 'pinctrl-[0-9]+'
from schema $id: http://devicetree.org/schemas/arm/bcm/raspberrypi,bcm2835-firmware.yaml#

There's obviously some other flag I need to set in the bindings,
but I can't work it out. We have similar errors for all the Pi
platforms for one or more nodes.
Please advise and I'll happily fix them all.

Thanks
  Dave

[1] https://lore.kernel.org/linux-arm-kernel/20241025-drm-vc4-2712-support-v2-0-35efa83c8fc0 at raspberrypi.com/

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
Thanks to Stefan and Krzysztof for their reviews.
Hopefully I've addressed all points raised in the correct manner.

Changes in v2:
- Commits have now be merged from drm-misc-next to linux-next, so all
  commit hashes are valid on linux-next.
- 1/7 Removed references to "previous commit". Fixed up indentation.
  Added maxItems
- 2/7 Defined widest constraints
- 3/7 Added maxItems and removed reference to Linux
- 4/7 Described the errors. Split into two for fix of node name vs addr
  being wrong.
- Added new patch removing "required" for interrupt-controller and
  interrupt-cells for bcm2836-l1-intc
- 5/7 (now 7/7) Removed the intc node for 2712 - it's irrelevant on 64bit systems
- 6/7 dropped as updating the binding is the correct answer
- 7/7 dropped. simple-bus claims ranges is required, but adding it
  creates other errors. I'm unclear as to the right solution.

- Link to v1: https://lore.kernel.org/r/20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a at raspberrypi.com

---
Dave Stevenson (7):
      dt-bindings: display: bcm2711-hdmi: Add interrupt details for BCM2712
      dt-bindings: display: Fix BCM2835 HVS bindings for BCM2712
      dt-bindings: gpio: brcmstb: permit gpio-line-names property
      dt-bindings: interrupt-controller: brcm,bcm2836-l1-intc: Drop interrupt-controller requirement
      arm64: dts: broadcom: Rename bcm2712 interrupt controllers
      arm64: dts: broadcom: Correct hdmi device node names
      arm64: dts: broadcom: Remove intc controller on BCM2712.

 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 107 ++++++++++++++++++---
 .../bindings/display/brcm,bcm2835-hvs.yaml         |  83 +++++++++++++---
 .../bindings/gpio/brcm,brcmstb-gpio.yaml           |   4 +
 .../interrupt-controller/brcm,bcm2836-l1-intc.yaml |   2 -
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi          |  13 +--
 5 files changed, 170 insertions(+), 39 deletions(-)
---
base-commit: 3a6b7ba51f16c093420959ab2bd3476d180547fa
change-id: 20241128-dt-bcm2712-fixes-afb0e8a0a476

Best regards,
-- 
Dave Stevenson <dave.stevenson at raspberrypi.com>



From dave.stevenson at raspberrypi.com  Thu Dec 12 08:18:51 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 16:18:51 +0000
Subject: [PATCH v2 1/7] dt-bindings: display: bcm2711-hdmi: Add interrupt
 details for BCM2712
In-Reply-To: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v2-1-35986e04d0f4@raspberrypi.com>

Commit 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
added the compatible strings for BCM2712, but missed out that the
number of interrupts changed.

Update the schema to include the interrupt requirements.

Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 107 ++++++++++++++++++---
 1 file changed, 93 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
index 6d11f5955b51..a7ca3a336187 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
@@ -56,22 +56,38 @@ properties:
       - const: cec
 
   interrupts:
-    items:
-      - description: CEC TX interrupt
-      - description: CEC RX interrupt
-      - description: CEC stuck at low interrupt
-      - description: Wake-up interrupt
-      - description: Hotplug connected interrupt
-      - description: Hotplug removed interrupt
+    oneOf:
+      - items:
+        - description: CEC TX interrupt
+        - description: CEC RX interrupt
+        - description: CEC stuck at low interrupt
+        - description: Wake-up interrupt
+        - description: Hotplug connected interrupt
+        - description: Hotplug removed interrupt
+
+      - items:
+        - description: CEC TX interrupt
+        - description: CEC RX interrupt
+        - description: CEC stuck at low interrupt
+        - description: Hotplug connected interrupt
+        - description: Hotplug removed interrupt
 
   interrupt-names:
-    items:
-      - const: cec-tx
-      - const: cec-rx
-      - const: cec-low
-      - const: wakeup
-      - const: hpd-connected
-      - const: hpd-removed
+    oneOf:
+      - items:
+        - const: cec-tx
+        - const: cec-rx
+        - const: cec-low
+        - const: wakeup
+        - const: hpd-connected
+        - const: hpd-removed
+
+      - items:
+        - const: cec-tx
+        - const: cec-rx
+        - const: cec-low
+        - const: hpd-connected
+        - const: hpd-removed
 
   ddc:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -112,6 +128,66 @@ required:
 
 additionalProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - brcm,bcm2711-hdmi0
+              - brcm,bcm2711-hdmi1
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: CEC TX interrupt
+            - description: CEC RX interrupt
+            - description: CEC stuck at low interrupt
+            - description: Wake-up interrupt
+            - description: Hotplug connected interrupt
+            - description: Hotplug removed interrupt
+        interrupt-names:
+          items:
+            - const: cec-tx
+            - const: cec-rx
+            - const: cec-low
+            - const: wakeup
+            - const: hpd-connected
+            - const: hpd-removed
+
+
+      required:
+        - interrupts
+        - interrupt-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - brcm,bcm2712-hdmi0
+              - brcm,bcm2712-hdmi1
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: CEC TX interrupt
+            - description: CEC RX interrupt
+            - description: CEC stuck at low interrupt
+            - description: Hotplug connected interrupt
+            - description: Hotplug removed interrupt
+        interrupts-names:
+          items:
+            - const: cec-tx
+            - const: cec-rx
+            - const: cec-low
+            - const: hpd-connected
+            - const: hpd-removed
+
+      required:
+        - interrupts
+        - interrupt-names
+
 examples:
   - |
     hdmi0: hdmi at 7ef00700 {
@@ -136,6 +212,9 @@ examples:
                     "hd";
         clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
         clock-names = "hdmi", "bvb", "audio", "cec";
+        interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
+        interrupt-names = "cec-tx", "cec-rx", "cec-low", "wakeup",
+                "hpd-connected", "hpd-removed";
         resets = <&dvp 0>;
         ddc = <&ddc0>;
     };

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Thu Dec 12 08:18:52 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 16:18:52 +0000
Subject: [PATCH v2 2/7] dt-bindings: display: Fix BCM2835 HVS bindings for
 BCM2712
In-Reply-To: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v2-2-35986e04d0f4@raspberrypi.com>

Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
added the compatible string for BCM2712, but missed out that
the number of interrupts and clocks changed too.

Update to validate clock and interrupts for the variants.

Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2835-hvs.yaml         | 83 ++++++++++++++++++----
 1 file changed, 69 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
index f91c9dce2a44..36bf8eec88a6 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
@@ -20,11 +20,20 @@ properties:
     maxItems: 1
 
   interrupts:
-    maxItems: 1
+    minItems: 1
+    maxItems: 3
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 3
 
   clocks:
-    maxItems: 1
-    description: Core Clock
+    minItems: 1
+    maxItems: 2
+
+  clock-names:
+    minItems: 1
+    maxItems: 2
 
 required:
   - compatible
@@ -33,17 +42,63 @@ required:
 
 additionalProperties: false
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - brcm,bcm2711-hvs
-          - brcm,bcm2712-hvs
-
-then:
-  required:
-    - clocks
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2711-hvs
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Core Clock
+        interrupts:
+          maxItems: 1
+
+      required:
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2712-hvs
+
+    then:
+      properties:
+        clocks:
+          maxItems: 2
+        clock-names:
+          items:
+            - const: core
+            - const: disp
+        interrupts:
+          items:
+            - description: Channel 0 End of frame
+            - description: Channel 1 End of frame
+            - description: Channel 2 End of frame
+        interrupt-names:
+          items:
+            - const: ch0-eof
+            - const: ch1-eof
+            - const: ch2-eof
+      required:
+        - clocks
+        - clock-names
+        - interrupt-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2835-hvs
+
+    then:
+      properties:
+        interrupts:
+          maxItems: 1
 
 examples:
   - |

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Thu Dec 12 08:18:53 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 16:18:53 +0000
Subject: [PATCH v2 3/7] dt-bindings: gpio: brcmstb: permit gpio-line-names
 property
In-Reply-To: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v2-3-35986e04d0f4@raspberrypi.com>

gpio-line-names is a generic property that can be supported by any
GPIO controller, so permit it through the binding.

It is permitted to have a variable number of GPIOs per node based
on brcm,gpio-bank-widths, so define an arbitrary maximum number of
items based on current users.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
index f096f286da19..fbd69b4cecc7 100644
--- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
@@ -64,6 +64,10 @@ properties:
 
   gpio-ranges: true
 
+  gpio-line-names:
+    minItems: 1
+    maxItems: 128
+
   wakeup-source:
     type: boolean
     description: >

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Thu Dec 12 08:18:54 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 16:18:54 +0000
Subject: [PATCH v2 4/7] dt-bindings: interrupt-controller:
 brcm,bcm2836-l1-intc: Drop interrupt-controller requirement
In-Reply-To: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v2-4-35986e04d0f4@raspberrypi.com>

Since commit 88bbe85dcd37 ("irqchip: bcm2836: Move SMP startup code to
arch/arm (v2)") the bcm2836-l1-intc block on bcm2711 is only used as a
base address for the smp_boot_secondary hook on 32 bit kernels. It is
not used as an interrupt controller.

Drop the binding requirement for interrupt-controller and interrupt-cells
to satisfy validation on this platform.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml  | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
index 5fda626c80ce..2ff390c1705b 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
@@ -34,8 +34,6 @@ properties:
 required:
   - compatible
   - reg
-  - interrupt-controller
-  - '#interrupt-cells'
 
 additionalProperties: false
 

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Thu Dec 12 08:18:55 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 16:18:55 +0000
Subject: [PATCH v2 5/7] arm64: dts: broadcom: Rename bcm2712 interrupt
 controllers
In-Reply-To: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v2-5-35986e04d0f4@raspberrypi.com>

CHECK_DTBS produces errors on bcm2712-rpi-5-b.dtb and bcm2712-d-rpi-5-b.dtb
of:
intc at 7d508380: $nodename:0: 'intc at 7d508380' does not match '^interrupt-controller(@[0-9a-f,]+)*$'
        from schema $id: http://devicetree.org/schemas/interrupt-controller/brcm,l2-intc.yaml#
intc at 7d508400: $nodename:0: 'intc at 7d508400' does not match '^interrupt-controller(@[0-9a-f,]+)*$'
        from schema $id: http://devicetree.org/schemas/interrupt-controller/brcm,l2-intc.yaml#

Rename the nodes from intc to interrupt-controller.

Fixes: f66b382affd8 ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
index 39305e0869ec..bd78af0211b6 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -336,7 +336,7 @@ ddc1: i2c at 7d508280 {
 			#size-cells = <0>;
 		};
 
-		bsc_irq: intc at 7d508380 {
+		bsc_irq: interrupt-controller at 7d508380 {
 			compatible = "brcm,bcm7271-l2-intc";
 			reg = <0x7d508380 0x10>;
 			interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
@@ -344,7 +344,7 @@ bsc_irq: intc at 7d508380 {
 			#interrupt-cells = <1>;
 		};
 
-		main_irq: intc at 7d508400 {
+		main_irq: interrupt-controller at 7d508400 {
 			compatible = "brcm,bcm7271-l2-intc";
 			reg = <0x7d508400 0x10>;
 			interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Thu Dec 12 08:18:56 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 16:18:56 +0000
Subject: [PATCH v2 6/7] arm64: dts: broadcom: Correct hdmi device node
 names
In-Reply-To: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v2-6-35986e04d0f4@raspberrypi.com>

The names of the hdmi0 and hdmi1 nodes had addresses that
didn't match the reg properties for the nodes.

Fixes: f66b382affd8 ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
index bd78af0211b6..f42fad2d8b37 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -352,7 +352,7 @@ main_irq: interrupt-controller at 7d508400 {
 			#interrupt-cells = <1>;
 		};
 
-		hdmi0: hdmi at 7ef00700 {
+		hdmi0: hdmi at 7c701400 {
 			compatible = "brcm,bcm2712-hdmi0";
 			reg = <0x7c701400 0x300>,
 			      <0x7c701000 0x200>,
@@ -381,7 +381,7 @@ hdmi0: hdmi at 7ef00700 {
 			ddc = <&ddc0>;
 		};
 
-		hdmi1: hdmi at 7ef05700 {
+		hdmi1: hdmi at 7c706400 {
 			compatible = "brcm,bcm2712-hdmi1";
 			reg = <0x7c706400 0x300>,
 			      <0x7c706000 0x200>,

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Thu Dec 12 08:18:57 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 16:18:57 +0000
Subject: [PATCH v2 7/7] arm64: dts: broadcom: Remove intc controller on
 BCM2712.
In-Reply-To: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v2-7-35986e04d0f4@raspberrypi.com>

The brcm,bcm2836-l1-intc controller isn't used on this platform.
It is used on 32-bit kernels for the smp_boot_secondary hook, but
BCM2712 can't run a 32-bit kernel.

Remove the node.

Fixes: e1417095a139 ("arm64: dts: broadcom: Add firmware clocks and power nodes to Pi5 DT")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
index f42fad2d8b37..9a426aa27c74 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -221,11 +221,6 @@ mailbox: mailbox at 7c013880 {
 			#mbox-cells = <0>;
 		};
 
-		local_intc: interrupt-controller at 7cd00000 {
-			compatible = "brcm,bcm2836-l1-intc";
-			reg = <0x7cd00000 0x100>;
-		};
-
 		uart10: serial at 7d001000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x7d001000 0x200>;

-- 
2.34.1



From Dave.Martin at arm.com  Thu Dec 12 08:19:40 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 16:19:40 +0000
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 5/5] arm_mpam:
 Adapting the closid/rmid matching determination functions
In-Reply-To: <20241207092136.2488426-6-zengheng4@huawei.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
 <20241207092136.2488426-6-zengheng4@huawei.com>
Message-ID: <Z1sNHFhpYlPvVANC@e133380.arm.com>

Hi,

On Sat, Dec 07, 2024 at 05:21:36PM +0800, Zeng Heng wrote:
> According to the previous patches, add the inverse functions for the
> closid/rmid conversion functions to serve as the conversion functions for
> reqpartid/pmg. And adapt the matching determination functions
> resctrl_arch_match_closid() and resctrl_arch_match_rmid() by the inverse
> functions.
> 
> For the same reason, when updating the (req)PARTID/PMG pair for a task,
> the new conversion functions also are used for adaptation.
> 
> Signed-off-by: Zeng Heng <zengheng4 at huawei.com>
> ---
>  arch/arm64/include/asm/mpam.h              |  6 ++-
>  drivers/platform/arm64/mpam/mpam_resctrl.c | 63 +++++++++++++++-------
>  2 files changed, 47 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h
> index e5f385767174..9fc095530671 100644
> --- a/arch/arm64/include/asm/mpam.h
> +++ b/arch/arm64/include/asm/mpam.h
> @@ -93,6 +93,8 @@ static inline u64 mpam_get_regval(struct task_struct *tsk)
>  #endif
>  }
>  
> +u32 rmid2pmg(u32 rmid);
> +
>  static inline void resctrl_arch_set_rmid(struct task_struct *tsk, u32 rmid)
>  {
>  #ifdef CONFIG_ARM64_MPAM
> @@ -100,8 +102,8 @@ static inline void resctrl_arch_set_rmid(struct task_struct *tsk, u32 rmid)
>  
>  	regval &= ~MPAM1_EL1_PMG_D;
>  	regval &= ~MPAM1_EL1_PMG_I;
> -	regval |= FIELD_PREP(MPAM1_EL1_PMG_D, rmid);
> -	regval |= FIELD_PREP(MPAM1_EL1_PMG_I, rmid);
> +	regval |= FIELD_PREP(MPAM1_EL1_PMG_D, rmid2pmg(rmid));
> +	regval |= FIELD_PREP(MPAM1_EL1_PMG_I, rmid2pmg(rmid));

Note, this function does not seem to be used; I added a patch in my
series [1] to get rid of it instead of converting it.

>  
>  	WRITE_ONCE(task_thread_info(tsk)->mpam_partid_pmg, regval);
>  #endif
> diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c

[...]

>  void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid, u32 rmid)
>  {
> -	BUG_ON(closid > U16_MAX);
> -	BUG_ON(rmid > U8_MAX);
> +	u32 reqpartid = closid_rmid2reqpartid(closid, rmid);
> +	u32 pmg = rmid2pmg(rmid);
> +	u32 partid_d, partid_i;
> +
> +	BUG_ON(reqpartid > U16_MAX);
> +	BUG_ON(pmg > U8_MAX);
>  
>  	if (!cdp_enabled) {
> -		mpam_set_cpu_defaults(cpu, closid, closid, rmid, rmid);
> +		mpam_set_cpu_defaults(cpu, reqpartid, reqpartid, pmg, pmg);
>  	} else {
>  		/*
>  		 * When CDP is enabled, resctrl halves the closid range and we
>  		 * use odd/even partid for one closid.
>  		 */
> -		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
> -		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
> +		partid_d = resctrl_get_config_index(reqpartid, CDP_DATA);
> +		partid_i = resctrl_get_config_index(reqpartid, CDP_CODE);
>  
> -		mpam_set_cpu_defaults(cpu, partid_d, partid_i, rmid, rmid);
> +		mpam_set_cpu_defaults(cpu, partid_d, partid_i, pmg, pmg);

Prior to this patch, will the PARTID and/or PMG programmed for a
control group be different from the PARTID and/or PMG used to program
the MSCs?

If so, those changes probably need to be in the same patch.

[...]

> @@ -289,41 +307,46 @@ void resctrl_arch_sync_cpu_closid_rmid(void *info)

[...]

>  /* The task's pmg is not unique, the partid must be considered too */
>  bool resctrl_arch_match_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
>  {
>  	u64 regval = mpam_get_regval(tsk);
> -	u32 tsk_closid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
> -	u32 tsk_rmid = FIELD_GET(MPAM1_EL1_PMG_D, regval);
> +	u32 tsk_pmg = FIELD_GET(MPAM1_EL1_PMG_D, regval);
> +	u32 tsk_partid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
>  
>  	if (cdp_enabled)
> -		tsk_closid >>= 1;
> +		tsk_partid >>= 1;
>  
> -	return (tsk_closid == closid) && (tsk_rmid == rmid);
> +	return (reqpartid2closid(tsk_partid) == closid) &&
> +	       (reqpartid_pmg2rmid(tsk_partid, tsk_pmg) == rmid);

Do we actually need the reverse mappings here?

It doesn't really matter which ID namespace is used for the
comparison, so in my version of this I converted the passed-in closid
and rmid to PARTID / PMG form and then compared those with tsk's
values.

(But if I've missed some subtlety here, please let me know!)

[...]

Cheers
---Dave


[1] [RFC PATCH 3/6] arm_mpam: Delete unused function resctrl_arch_set_rmid()
https://lore.kernel.org/lkml/20241212154000.330467-4-Dave.Martin at arm.com/


From joro at 8bytes.org  Thu Dec 12 08:26:05 2024
From: joro at 8bytes.org (Joerg Roedel)
Date: Thu, 12 Dec 2024 17:26:05 +0100
Subject: [GIT PULL] iommu/arm-smmu: Fix for 6.13-rc
In-Reply-To: <20241212095025.GA18975@willie-the-truck>
References: <20241212095025.GA18975@willie-the-truck>
Message-ID: <Z1sOndzI5_VxdxXe@8bytes.org>

On Thu, Dec 12, 2024 at 09:50:26AM +0000, Will Deacon wrote:
>   git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git tags/arm-smmu-fixes

Pulled, thanks Will.


From apatel at ventanamicro.com  Thu Dec 12 08:41:01 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 12 Dec 2024 22:11:01 +0530
Subject: [PATCH 1/4] irqchip/riscv-imsic: Handle non-atomic MSI updates
 for device
In-Reply-To: <87r06gq2di.ffs@tglx>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
 <20241208150711.297624-2-apatel@ventanamicro.com> <875xnuq6dc.ffs@tglx>
 <CAK9=C2VqU2mdLL-R20bdgvDHi0WcuNyUSqRo7Pztsu-8X1wVvw@mail.gmail.com> <87r06gq2di.ffs@tglx>
Message-ID: <CAK9=C2XEhtB00y6WTMaO0X=7K820T_BSCLA5bw6hJbfvQAD+Pw@mail.gmail.com>

Hi Thomas,

On Mon, Dec 9, 2024 at 9:23?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> Anup!
>
> On Mon, Dec 09 2024 at 17:38, Anup Patel wrote:
> > On Mon, Dec 9, 2024 at 1:44?AM Thomas Gleixner <tglx at linutronix.de> wrote:
> >> There is no guarantee that set_affinity() runs on the original target
> >> CPU (CPU 1). Your scheme only works, when CPU1 vector 0x20 is not used
> >> by some other device. If it's used, you lost as CPU1 will consume the
> >> vector and your pending check is not seeing anything.
> >>
> >> x86 ensures CPU locality by deferring the affinity move to the next
> >> device interrupt on the original target CPU (CPU1 in the above
> >> example). See CONFIG_GENERIC_IRQ_PENDING.
> >
> > I agree with you.
> >
> > The IMSIC driver must do the affinity move upon the next device
> > interrupt on the old CPU. I will update this patch in the next revision.
> >
> > BTW, I did not find CONFIG_GENERIC_IRQ_PENDING. Is the
> > name correct ?
>
> CONFIG_GENERIC_PENDING_IRQ is close enough :)
>
> >> The interrupt domains which are not affected (remap) set the
> >> IRQ_MOVE_PCNTXT flag to avoid that dance and don't use that affinity
> >> setter code path at all.
> >
> > Yes, setting the IRQ_MOVE_PCNTXT flag in the remap domain
> > makes perfect sense.
> >
> > I suggest adding IRQ_MOVE_PCNTXT usage as part of Drew's
> > irqbypass series which adds a remap domain in the IOMMU
> > driver. Unless you insist on having it as part of this series ?
>
> You need to look at the other RISC-V controllers. Those which do not
> need this should set it. That's historically backwards.
>
> I think we can reverse the logic here. As this needs backporting, I
> can't make a full cleanup of this, but for your problem the patch below
> should just work.
>
> Select GENERIC_PENDING_IRQ and GENERIC_PENDING_IRQ_CHIPFLAGS and set the
> IRQCHIP_MOVE_DEFERRED flag on your interrrupt chip and the core logic
> takes care of the PCNTXT bits.
>
> I'll convert x86 in a seperate step and remove the PCNTXT leftovers and
> the new config knob once the dust has settled.
>
> Thanks,
>
>         tglx
> ---
> --- a/include/linux/irq.h
> +++ b/include/linux/irq.h
> @@ -567,6 +567,7 @@ struct irq_chip {
>   *                                    in the suspend path if they are in disabled state
>   * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
>   * IRQCHIP_IMMUTABLE:                Don't ever change anything in this chip
> + * IRQCHIP_MOVE_DEFERRED:            Move the interrupt in actual interrupt context
>   */
>  enum {
>         IRQCHIP_SET_TYPE_MASKED                 = (1 <<  0),
> @@ -581,6 +582,7 @@ enum {
>         IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND        = (1 <<  9),
>         IRQCHIP_AFFINITY_PRE_STARTUP            = (1 << 10),
>         IRQCHIP_IMMUTABLE                       = (1 << 11),
> +       IRQCHIP_MOVE_DEFERRED                   = (1 << 12),
>  };
>
>  #include <linux/irqdesc.h>
> --- a/kernel/irq/Kconfig
> +++ b/kernel/irq/Kconfig
> @@ -31,6 +31,10 @@ config GENERIC_IRQ_EFFECTIVE_AFF_MASK
>  config GENERIC_PENDING_IRQ
>         bool
>
> +# Deduce delayed migration from top-level interrupt chip flags
> +config GENERIC_PENDING_IRQ_CHIPFLAGS
> +       bool
> +
>  # Support for generic irq migrating off cpu before the cpu is offline.
>  config GENERIC_IRQ_MIGRATION
>         bool
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -47,6 +47,13 @@ int irq_set_chip(unsigned int irq, const
>                 return -EINVAL;
>
>         desc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
> +
> +       if (IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS) && chip) {
> +               if (chip->flags & IRQCHIP_MOVE_DEFERRED)
> +                       irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
> +               else
> +                       irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
> +       }

We need similar changes in irq_domain_set_hwirq_and_chip()
because we use IRQ_DOMAIN_HIERARCHY in RISC-V.

--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1509,6 +1509,13 @@ int irq_domain_set_hwirq_and_chip(struct
irq_domain *domain, unsigned int virq,
        irq_data->chip = (struct irq_chip *)(chip ? chip : &no_irq_chip);
        irq_data->chip_data = chip_data;

+       if (IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS) && chip) {
+               if (chip->flags & IRQCHIP_MOVE_DEFERRED)
+                       irq_clear_status_flags(virq, IRQ_MOVE_PCNTXT);
+               else
+                       irq_set_status_flags(virq, IRQ_MOVE_PCNTXT);
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(irq_domain_set_hwirq_and_chip);


>         irq_put_desc_unlock(desc, flags);
>         /*
>          * For !CONFIG_SPARSE_IRQ make the irq show up in
> @@ -1114,16 +1121,21 @@ void irq_modify_status(unsigned int irq,
>         trigger = irqd_get_trigger_type(&desc->irq_data);
>
>         irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
> -                  IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT);
> +                  IRQD_TRIGGER_MASK | IRQD_LEVEL);
>         if (irq_settings_has_no_balance_set(desc))
>                 irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
>         if (irq_settings_is_per_cpu(desc))
>                 irqd_set(&desc->irq_data, IRQD_PER_CPU);
> -       if (irq_settings_can_move_pcntxt(desc))
> -               irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
>         if (irq_settings_is_level(desc))
>                 irqd_set(&desc->irq_data, IRQD_LEVEL);
>
> +       /* Keep this around until x86 is converted over */
> +       if (!IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS)) {
> +               irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
> +               if (irq_settings_can_move_pcntxt(desc))
> +                       irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
> +       }
> +

These changes in irq_modify_status() need to be dropped to support
the above changes in irq_domain_set_hwirq_and_chip().

>         tmp = irq_settings_get_trigger_mask(desc);
>         if (tmp != IRQ_TYPE_NONE)
>                 trigger = tmp;
>
>
>

Let me know if you have alternate suggestions instead of the above changes.

Regards,
Anup


From lpieralisi at kernel.org  Thu Dec 12 08:46:09 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Thu, 12 Dec 2024 17:46:09 +0100
Subject: [PATCH v8 2/2] PCI: imx6: Add IOMMU and ITS MSI support for
 i.MX95
In-Reply-To: <20241210-imx95_lut-v8-2-2e730b2e5fde@nxp.com>
References: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
 <20241210-imx95_lut-v8-2-2e730b2e5fde@nxp.com>
Message-ID: <Z1sTUaoA5yk9RcIc@lpieralisi>

On Tue, Dec 10, 2024 at 05:48:59PM -0500, Frank Li wrote:
> For the i.MX95, configuration of a LUT is necessary to convert Bus Device
> Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
> This involves checking msi-map and iommu-map device tree properties to
> ensure consistent mapping of PCI BDF to the same stream IDs. Subsequently,
> LUT-related registers are configured. In the absence of an msi-map, the
> built-in MSI controller is utilized as a fallback.

This is wrong information. What you want to say is that if an msi-map
isn't detected this means that the platform relies on DWC built-in
controller for MSIs (that does not need streamIDs handling).

That's quite different from what you are writing here.

> 
> Register a PCI bus callback function to handle enable_device() and
> disable_device() operations, setting up the LUT whenever a new PCI device
> is enabled.
> 
> Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> Change from v7 to v8
> - update comment message according to Lorenzo Pieralisi's suggestion.
> - rework err target table
> - improve err==0 && target ==NULL description, use 1:1 map RID to
> stream ID.
> - invalidate case -> unexisted case, never happen
> - sid_i will not do mask, add comments said only MSI glue layer add
> controller id.
> - rework iommu map and msi map return value check logic according to
> Lorenzo Pieralisi's suggestion
> 
> Change from v5 to v7
> - change comment rid to RID
> - some mini change according to mani's feedback
> 
> Change from v4 to v5
> - rework commt message
> - add comment for mutex
> - s/reqid/rid/
> - keep only one loop when enable lut
> - add warning when try to add duplicate rid
> - Replace hardcode 0xffff with IMX95_PE0_LUT_MASK
> - Fix some error message
> 
> Change from v3 to v4
> - Check target value at of_map_id().
> - of_node_put() for target.
> - add case for msi-map exist, but rid entry is not exist.
> 
> Change from v2 to v3
> - Use the "target" argument of of_map_id()
> - Check if rid already in lut table when enable device
> 
> change from v1 to v2
> - set callback to pci_host_bridge instead pci->ops.
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 186 +++++++++++++++++++++++++++++++++-
>  1 file changed, 185 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index c8d5c90aa4d45..d325f4fb279c8 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -55,6 +55,22 @@
>  #define IMX95_PE0_GEN_CTRL_3			0x1058
>  #define IMX95_PCIE_LTSSM_EN			BIT(0)
>  
> +#define IMX95_PE0_LUT_ACSCTRL			0x1008
> +#define IMX95_PEO_LUT_RWA			BIT(16)
> +#define IMX95_PE0_LUT_ENLOC			GENMASK(4, 0)
> +
> +#define IMX95_PE0_LUT_DATA1			0x100c
> +#define IMX95_PE0_LUT_VLD			BIT(31)
> +#define IMX95_PE0_LUT_DAC_ID			GENMASK(10, 8)
> +#define IMX95_PE0_LUT_STREAM_ID			GENMASK(5, 0)
> +
> +#define IMX95_PE0_LUT_DATA2			0x1010
> +#define IMX95_PE0_LUT_REQID			GENMASK(31, 16)
> +#define IMX95_PE0_LUT_MASK			GENMASK(15, 0)
> +
> +#define IMX95_SID_MASK				GENMASK(5, 0)
> +#define IMX95_MAX_LUT				32
> +
>  #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
>  
>  enum imx_pcie_variants {
> @@ -87,6 +103,7 @@ enum imx_pcie_variants {
>   * workaround suspend resume on some devices which are affected by this errata.
>   */
>  #define IMX_PCIE_FLAG_BROKEN_SUSPEND		BIT(9)
> +#define IMX_PCIE_FLAG_HAS_LUT			BIT(10)
>  
>  #define imx_check_flag(pci, val)	(pci->drvdata->flags & val)
>  
> @@ -139,6 +156,9 @@ struct imx_pcie {
>  	struct device		*pd_pcie_phy;
>  	struct phy		*phy;
>  	const struct imx_pcie_drvdata *drvdata;
> +
> +	/* Ensure that only one device's LUT is configured at any given time */
> +	struct mutex		lock;
>  };
>  
>  /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
> @@ -930,6 +950,162 @@ static void imx_pcie_stop_link(struct dw_pcie *pci)
>  	imx_pcie_ltssm_disable(dev);
>  }
>  
> +static int imx_pcie_add_lut(struct imx_pcie *imx_pcie, u16 rid, u8 sid)
> +{
> +	struct dw_pcie *pci = imx_pcie->pci;
> +	struct device *dev = pci->dev;
> +	u32 data1, data2;
> +	int free = -1;
> +	int i;
> +
> +	if (sid >= 64) {
> +		dev_err(dev, "Invalid SID for index %d\n", sid);
> +		return -EINVAL;
> +	}
> +
> +	guard(mutex)(&imx_pcie->lock);
> +
> +	/*
> +	 * Iterate through all LUT entries to check for duplicate RID and
> +	 * identify the first available entry. Configure this available entry
> +	 * immediately after verification to avoid rescanning it.
> +	 */
> +	for (i = 0; i < IMX95_MAX_LUT; i++) {
> +		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
> +		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, &data1);
> +
> +		if (!(data1 & IMX95_PE0_LUT_VLD)) {
> +			if (free < 0)
> +				free = i;
> +			continue;
> +		}
> +
> +		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
> +
> +		/* Do not add duplicate RID */
> +		if (rid == FIELD_GET(IMX95_PE0_LUT_REQID, data2)) {
> +			dev_warn(dev, "Existing LUT entry available for RID (%d)", rid);
> +			return 0;
> +		}
> +	}
> +
> +	if (free < 0) {
> +		dev_err(dev, "LUT entry is not available\n");
> +		return -ENOSPC;
> +	}
> +
> +	data1 = FIELD_PREP(IMX95_PE0_LUT_DAC_ID, 0);
> +	data1 |= FIELD_PREP(IMX95_PE0_LUT_STREAM_ID, sid);
> +	data1 |= IMX95_PE0_LUT_VLD;
> +	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, data1);
> +
> +	data2 = IMX95_PE0_LUT_MASK; /* Match all bits of RID */
> +	data2 |= FIELD_PREP(IMX95_PE0_LUT_REQID, rid);
> +	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, data2);
> +
> +	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, free);
> +
> +	return 0;
> +}
> +
> +static void imx_pcie_remove_lut(struct imx_pcie *imx_pcie, u16 rid)
> +{
> +	u32 data2;
> +	int i;
> +
> +	guard(mutex)(&imx_pcie->lock);
> +
> +	for (i = 0; i < IMX95_MAX_LUT; i++) {
> +		regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i);
> +		regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
> +		if (FIELD_GET(IMX95_PE0_LUT_REQID, data2) == rid) {
> +			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, 0);
> +			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, 0);
> +			regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i);
> +
> +			break;
> +		}
> +	}
> +}
> +
> +static int imx_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> +{
> +	struct imx_pcie *imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> +	u32 sid_i, sid_m, rid = pci_dev_id(pdev);
> +	struct device_node *target;
> +	struct device *dev;
> +	int err_i, err_m;
> +	u32 sid;
> +
> +	dev = imx_pcie->pci->dev;
> +
> +	target = NULL;
> +	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
> +	if (target) {
> +		of_node_put(target);
> +	} else {
> +		/*
> +		 * "target == NULL && err_i == 0" means use 1:1 map RID to

Is it what it means ? Or does it mean that the iommu-map property was found
and RID is out of range ?

Could you point me at a sample dts for this host bridge please ?

> +		 * stream ID. Hardware can't support this because stream ID
> +		 * only 5bits

It is 5 or 6 bits ? From GENMASK(5, 0) above it should be 6.

> +		 */
> +		err_i = -EINVAL;
> +	}
> +
> +	target = NULL;
> +	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
> +
> +	/*
> +	 *   err_m      target
> +	 *	0	NULL		Use 1:1 map RID to stream ID,

Again, is that what it really means ?

> +	 *				Current hardware can't support it,
> +	 *				So return -EINVAL.
> +	 *      != 0    NULL		msi-map not exist, use built-in MSI.

does not exist.

> +	 *	0	!= NULL		Get correct streamID from RID.
> +	 *	!= 0	!= NULL		Unexisted case, never happen.

"Invalid combination"

> +	 */
> +	if (!err_m && !target)
> +		return -EINVAL;
> +	else if (target)
> +		of_node_put(target); /* Find stream ID map entry for RID in msi-map */
> +
> +	/*
> +	 * msi-map        iommu-map
> +	 *   N                N            DWC MSI Ctrl
> +	 *   Y                Y            ITS + SMMU, require the same sid
> +	 *   Y                N            ITS
> +	 *   N                Y            DWC MSI Ctrl + SMMU
> +	 */
> +	if (err_i && err_m)
> +		return 0;
> +
> +	if (!err_i && !err_m) {
> +		/*
> +		 * MSI glue layer auto add 2 bits controller ID ahead of stream

What's "MSI glue layer" ?

> +		 * ID, so mask this 2bits to get stream ID.
> +		 * But IOMMU glue layer doesn't do that.

and "IOMMU glue layer" ?

> +		 */
> +		if (sid_i != (sid_m & IMX95_SID_MASK)) {
> +			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
> +			return -EINVAL;
> +		}
> +	}
> +
> +	sid = sid_i;

err_i could be != 0 here, I understand that the end result is
fine given how the code is written but it is misleading.

	if (!err_i)
	else if (!err_m)

> +	if (!err_m)
> +		sid = sid_m & IMX95_SID_MASK;
> +
> +	return imx_pcie_add_lut(imx_pcie, rid, sid);
> +}
> +
> +static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> +{
> +	struct imx_pcie *imx_pcie;
> +
> +	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> +	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
> +}
> +
>  static int imx_pcie_host_init(struct dw_pcie_rp *pp)
>  {
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -946,6 +1122,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
>  		}
>  	}
>  
> +	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
> +		pp->bridge->enable_device = imx_pcie_enable_device;
> +		pp->bridge->disable_device = imx_pcie_disable_device;
> +	}
> +
>  	imx_pcie_assert_core_reset(imx_pcie);
>  
>  	if (imx_pcie->drvdata->init_phy)
> @@ -1330,6 +1511,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
>  	imx_pcie->pci = pci;
>  	imx_pcie->drvdata = of_device_get_match_data(dev);
>  
> +	mutex_init(&imx_pcie->lock);
> +
>  	/* Find the PHY if one is defined, only imx7d uses it */
>  	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
>  	if (np) {
> @@ -1627,7 +1810,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
>  	},
>  	[IMX95] = {
>  		.variant = IMX95,
> -		.flags = IMX_PCIE_FLAG_HAS_SERDES,
> +		.flags = IMX_PCIE_FLAG_HAS_SERDES |
> +			 IMX_PCIE_FLAG_HAS_LUT,
>  		.clk_names = imx8mq_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
>  		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> 
> -- 
> 2.34.1
> 


From broonie at kernel.org  Thu Dec 12 08:47:46 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 12 Dec 2024 16:47:46 +0000
Subject: [PATCH v2] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <20241210160940.2031997-1-kevin.brodsky@arm.com>
References: <20241210160940.2031997-1-kevin.brodsky@arm.com>
Message-ID: <5db7f7a0-1d3c-4bbd-ad2b-124bf54f49ef@sirena.org.uk>

On Tue, Dec 10, 2024 at 04:09:40PM +0000, Kevin Brodsky wrote:

> While at it, also take care of copy_siginfo_to_user(): since it may
> fail, we shouldn't be calling it after setup_return() either. Call
> it before setup_return() instead, and move the setting of X1/X2
> inside setup_return() where it belongs (after the "point of no
> failure").

> Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")

Presumably we also need a Fixes for whatever introduced the above copy.
Otherwise

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/20241212/929a0413/attachment.sig>

From gregkh at linuxfoundation.org  Thu Dec 12 06:57:16 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 12 Dec 2024 15:57:16 +0100
Subject: [PATCH 5.15 241/565] perf cs-etm: Dont flush when packet_queue fills up
In-Reply-To: <20241212144311.432886635@linuxfoundation.org>
References: <20241212144311.432886635@linuxfoundation.org>
Message-ID: <20241212144321.005145113@linuxfoundation.org>

5.15-stable review patch.  If anyone has any objections, please let me know.

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

From: James Clark <james.clark at linaro.org>

[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]

cs_etm__flush(), like cs_etm__sample() is an operation that generates a
sample and then swaps the current with the previous packet. Calling
flush after processing the queues results in two swaps which corrupts
the next sample. Therefore it wasn't appropriate to call flush here so
remove it.

Flushing is still done on a discontinuity to explicitly clear the last
branch buffer, but when the packet_queue fills up before reaching a
timestamp, that's not a discontinuity and the call to
cs_etm__process_traceid_queue() already generated samples and drained
the buffers correctly.

This is visible by looking for a branch that has the same target as the
previous branch and the following source is before the address of the
last target, which is impossible as execution would have had to have
gone backwards:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
   (packet_queue fills here before a timestamp, resulting in a flush and
    branch target ffff80008011cadc is duplicated.)
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

After removing the flush the correct branch target is used for the
second sample, and ffff8000801117c4 is no longer before the previous
address:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

Make sure that a final branch stack is output at the end of the trace
by calling cs_etm__end_block(). This is already done for both the
timeless decode paths.

Fixes: 21fe8dc1191a ("perf cs-etm: Add support for CPU-wide trace scenarios")
Reported-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Closes: https://lore.kernel.org/all/20240719092619.274730-1-gankulkarni at os.amperecomputing.com/
Reviewed-by: Leo Yan <leo.yan at arm.com>
Signed-off-by: James Clark <james.clark at linaro.org>
Tested-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Cc: Ben Gainey <ben.gainey at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Ruidong Tian <tianruidong at linux.alibaba.com>
Cc: Benjamin Gray <bgray at linux.ibm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: coresight at lists.linaro.org
Cc: John Garry <john.g.garry at oracle.com>
Cc: scclevenger at os.amperecomputing.com
Link: https://lore.kernel.org/r/20240916135743.1490403-2-james.clark at linaro.org
Signed-off-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/perf/util/cs-etm.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index f323adb1af855..6fa698186f0b6 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2126,12 +2126,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
 
 		/* Ignore return value */
 		cs_etm__process_traceid_queue(etmq, tidq);
-
-		/*
-		 * Generate an instruction sample with the remaining
-		 * branchstack entries.
-		 */
-		cs_etm__flush(etmq, tidq);
 	}
 }
 
@@ -2228,7 +2222,7 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
 
 	while (1) {
 		if (!etm->heap.heap_cnt)
-			goto out;
+			break;
 
 		/* Take the entry at the top of the min heap */
 		cs_queue_nr = etm->heap.heap_array[0].queue_nr;
@@ -2311,6 +2305,23 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
 		ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp);
 	}
 
+	for (i = 0; i < etm->queues.nr_queues; i++) {
+		struct int_node *inode;
+
+		etmq = etm->queues.queue_array[i].priv;
+		if (!etmq)
+			continue;
+
+		intlist__for_each_entry(inode, etmq->traceid_queues_list) {
+			int idx = (int)(intptr_t)inode->priv;
+
+			/* Flush any remaining branch stack entries */
+			tidq = etmq->traceid_queues[idx];
+			ret = cs_etm__end_block(etmq, tidq);
+			if (ret)
+				return ret;
+		}
+	}
 out:
 	return ret;
 }
-- 
2.43.0





From Dave.Martin at arm.com  Thu Dec 12 09:06:36 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 12 Dec 2024 17:06:36 +0000
Subject: [RFC PATCH 1/6] arm_mpam: Clean up config update checks in
 mpam_apply_config()
In-Reply-To: <20241212154000.330467-2-Dave.Martin@arm.com>
References: <20241212154000.330467-1-Dave.Martin@arm.com>
 <20241212154000.330467-2-Dave.Martin@arm.com>
Message-ID: <Z1sYHLZQBW9girSf@e133380.arm.com>

Hi all,

On Thu, Dec 12, 2024 at 03:39:55PM +0000, Dave Martin wrote:
> In mpam_apply_config(), a simple memcmp() test is used to check
> whether the config passed by the caller is already installed or
> not.
> 
> This check will never find a match except (very occasionally) by
> accident, since the component's version of the struct contains
> things that the caller won't pass or doesn't know (such as the
> garbage collection record).  There might also be random padding.
> 
> This may result in MSCs being reprogrammed unnecessarily.
> 
> Instead, only compare fields that the caller specified.  If
> anything is present in the caller's config and doesn't match the
> installed config, paste it across.  If nothing was pasted across
> then the MSC reprogramming step is skipped (as the previous code
> attempted to do).
> 
> Signed-off-by: Dave Martin <Dave.Martin at arm.com>
> 
> ---
> 
> There are comments in the code suggesting a change of this sort.
> I may or may not have gone in the right direction with this, and
> I have only tried to clean up the behaviour rather than optimising.
> 
> No attempt is made to skip unnecessary MSC register updates if the MSC
> reprogramming goes ahead.
> 
> NOT well tested, yet.
> ---

Oops, git rebase didn't spot that this patch had already been applied,
due to adjacent hunks inserted in the meantime from other patches.

This patch can be dropped from this series.

[...]

Cheers
---Dave


From catalin.marinas at arm.com  Thu Dec 12 09:10:14 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 12 Dec 2024 17:10:14 +0000
Subject: [PATCH v2] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <5db7f7a0-1d3c-4bbd-ad2b-124bf54f49ef@sirena.org.uk>
References: <20241210160940.2031997-1-kevin.brodsky@arm.com>
 <5db7f7a0-1d3c-4bbd-ad2b-124bf54f49ef@sirena.org.uk>
Message-ID: <Z1sY9tIsAZ84W93-@arm.com>

On Thu, Dec 12, 2024 at 04:47:46PM +0000, Mark Brown wrote:
> On Tue, Dec 10, 2024 at 04:09:40PM +0000, Kevin Brodsky wrote:
> > While at it, also take care of copy_siginfo_to_user(): since it may
> > fail, we shouldn't be calling it after setup_return() either. Call
> > it before setup_return() instead, and move the setting of X1/X2
> > inside setup_return() where it belongs (after the "point of no
> > failure").
> 
> > Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")
> 
> Presumably we also need a Fixes for whatever introduced the above copy.

Hmm, it was like this from the beginning. If we are to do a cc stable to
the oldest maintained LTS, I'd rather have a separate patch for
copy_siginfo_to_user(), it doesn't make much sense to backport a GCS
patch to early kernels.

-- 
Catalin


From lee at kernel.org  Thu Dec 12 09:17:57 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 12 Dec 2024 17:17:57 +0000
Subject: [PATCH v9 0/9] Drivers to support the MCU on QNAP NAS devices
In-Reply-To: <20241107114712.538976-1-heiko@sntech.de>
References: <20241107114712.538976-1-heiko@sntech.de>
Message-ID: <173402387748.2234929.7484373598047473898.b4-ty@kernel.org>

On Thu, 07 Nov 2024 12:47:03 +0100, Heiko Stuebner wrote:
> This implements a set of drivers for the MCU used on QNAP NAS devices.
> 
> Of course no documentation for the serial protocol is available, so
> thankfully QNAP has a tool on their rescue-inird to talk to the MCU and
> I found interceptty [0] to listen to what goes over the serial connection.
> 
> In general it looks like there are two different generations in general,
> an "EC" device and now this "MCU" - referenced in the strings of the
> userspace handlers for those devices.
> 
> [...]

Applied, thanks!

[1/9] HID: hid-sensor-hub: don't use stale platform-data on remove
      commit: e079a120f31e3f9c00180aa13c1df18cc138f7fe
[2/9] mfd: core: make platform_data pointer const in struct mfd_cell
      commit: 8f4009ad901c44f0428dbde654c4dd1fb29c863b
[3/9] dt-bindings: mfd: add binding for qnap,ts433-mcu devices
      commit: 8877bcff3e3b4f08a1fc0232dbfdaeda085cfdf3
[4/9] mfd: add base driver for qnap-mcu devices
      commit: 944ca826f69e4723853b3876875b03aeafe67b60
[5/9] leds: add driver for LEDs from qnap-mcu devices
      commit: fe6a21ee38f12e3e5f9adbd2f9a840be105b943f
[6/9] Input: add driver for the input part of qnap-mcu devices
      commit: 4b27e0da257371d3d141fae38fdbdc3c3a67bce6
[7/9] hwmon: add driver for the hwmon parts of qnap-mcu devices
      commit: 41755872a8a8ab8d1644459d9634c53b743fe2be
[8/9] arm64: dts: rockchip: hook up the MCU on the QNAP TS433
      (no commit info)
[9/9] arm64: dts: rockchip: set hdd led labels on qnap-ts433
      (no commit info)

--
Lee Jones [???]



From lee at kernel.org  Thu Dec 12 09:19:07 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 12 Dec 2024 17:19:07 +0000
Subject: [PATCH v9 0/9] Drivers to support the MCU on QNAP NAS devices
In-Reply-To: <173402387748.2234929.7484373598047473898.b4-ty@kernel.org>
References: <20241107114712.538976-1-heiko@sntech.de>
 <173402387748.2234929.7484373598047473898.b4-ty@kernel.org>
Message-ID: <20241212171907.GH7139@google.com>

On Thu, 12 Dec 2024, Lee Jones wrote:

> On Thu, 07 Nov 2024 12:47:03 +0100, Heiko Stuebner wrote:
> > This implements a set of drivers for the MCU used on QNAP NAS devices.
> > 
> > Of course no documentation for the serial protocol is available, so
> > thankfully QNAP has a tool on their rescue-inird to talk to the MCU and
> > I found interceptty [0] to listen to what goes over the serial connection.
> > 
> > In general it looks like there are two different generations in general,
> > an "EC" device and now this "MCU" - referenced in the strings of the
> > userspace handlers for those devices.
> > 
> > [...]
> 
> Applied, thanks!
> 
> [1/9] HID: hid-sensor-hub: don't use stale platform-data on remove
>       commit: e079a120f31e3f9c00180aa13c1df18cc138f7fe
> [2/9] mfd: core: make platform_data pointer const in struct mfd_cell
>       commit: 8f4009ad901c44f0428dbde654c4dd1fb29c863b
> [3/9] dt-bindings: mfd: add binding for qnap,ts433-mcu devices
>       commit: 8877bcff3e3b4f08a1fc0232dbfdaeda085cfdf3
> [4/9] mfd: add base driver for qnap-mcu devices
>       commit: 944ca826f69e4723853b3876875b03aeafe67b60
> [5/9] leds: add driver for LEDs from qnap-mcu devices
>       commit: fe6a21ee38f12e3e5f9adbd2f9a840be105b943f
> [6/9] Input: add driver for the input part of qnap-mcu devicesj
>       commit: 4b27e0da257371d3d141fae38fdbdc3c3a67bce6
> [7/9] hwmon: add driver for the hwmon parts of qnap-mcu devices
>       commit: 41755872a8a8ab8d1644459d9634c53b743fe2be

> [8/9] arm64: dts: rockchip: hook up the MCU on the QNAP TS433
>       (no commit info)
> [9/9] arm64: dts: rockchip: set hdd led labels on qnap-ts433
>       (no commit info)

As you can see, I have _not_ applied these two DTS patches.

-- 
Lee Jones [???]


From lee at kernel.org  Thu Dec 12 09:19:54 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 12 Dec 2024 17:19:54 +0000
Subject: [PATCH v9 0/9] Drivers to support the MCU on QNAP NAS devices
In-Reply-To: <173402387748.2234929.7484373598047473898.b4-ty@kernel.org>
References: <20241107114712.538976-1-heiko@sntech.de>
 <173402387748.2234929.7484373598047473898.b4-ty@kernel.org>
Message-ID: <20241212171954.GI7139@google.com>

On Thu, 12 Dec 2024, Lee Jones wrote:

> On Thu, 07 Nov 2024 12:47:03 +0100, Heiko Stuebner wrote:
> > This implements a set of drivers for the MCU used on QNAP NAS devices.
> > 
> > Of course no documentation for the serial protocol is available, so
> > thankfully QNAP has a tool on their rescue-inird to talk to the MCU and
> > I found interceptty [0] to listen to what goes over the serial connection.
> > 
> > In general it looks like there are two different generations in general,
> > an "EC" device and now this "MCU" - referenced in the strings of the
> > userspace handlers for those devices.
> > 
> > [...]
> 
> Applied, thanks!
> 
> [1/9] HID: hid-sensor-hub: don't use stale platform-data on remove
>       commit: e079a120f31e3f9c00180aa13c1df18cc138f7fe
> [2/9] mfd: core: make platform_data pointer const in struct mfd_cell
>       commit: 8f4009ad901c44f0428dbde654c4dd1fb29c863b
> [3/9] dt-bindings: mfd: add binding for qnap,ts433-mcu devices
>       commit: 8877bcff3e3b4f08a1fc0232dbfdaeda085cfdf3
> [4/9] mfd: add base driver for qnap-mcu devices
>       commit: 944ca826f69e4723853b3876875b03aeafe67b60
> [5/9] leds: add driver for LEDs from qnap-mcu devices
>       commit: fe6a21ee38f12e3e5f9adbd2f9a840be105b943f
> [6/9] Input: add driver for the input part of qnap-mcu devices
>       commit: 4b27e0da257371d3d141fae38fdbdc3c3a67bce6
> [7/9] hwmon: add driver for the hwmon parts of qnap-mcu devices
>       commit: 41755872a8a8ab8d1644459d9634c53b743fe2be

Once build testing is complete, I'll send out a PR.

Note to self: ib-mfd-hid-hwmon-input-leds-6.14

-- 
Lee Jones [???]


From gregkh at linuxfoundation.org  Thu Dec 12 06:58:48 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 12 Dec 2024 15:58:48 +0100
Subject: [PATCH 5.10 190/459] perf cs-etm: Dont flush when packet_queue fills up
In-Reply-To: <20241212144253.511169641@linuxfoundation.org>
References: <20241212144253.511169641@linuxfoundation.org>
Message-ID: <20241212144301.068702140@linuxfoundation.org>

5.10-stable review patch.  If anyone has any objections, please let me know.

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

From: James Clark <james.clark at linaro.org>

[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]

cs_etm__flush(), like cs_etm__sample() is an operation that generates a
sample and then swaps the current with the previous packet. Calling
flush after processing the queues results in two swaps which corrupts
the next sample. Therefore it wasn't appropriate to call flush here so
remove it.

Flushing is still done on a discontinuity to explicitly clear the last
branch buffer, but when the packet_queue fills up before reaching a
timestamp, that's not a discontinuity and the call to
cs_etm__process_traceid_queue() already generated samples and drained
the buffers correctly.

This is visible by looking for a branch that has the same target as the
previous branch and the following source is before the address of the
last target, which is impossible as execution would have had to have
gone backwards:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
   (packet_queue fills here before a timestamp, resulting in a flush and
    branch target ffff80008011cadc is duplicated.)
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

After removing the flush the correct branch target is used for the
second sample, and ffff8000801117c4 is no longer before the previous
address:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

Make sure that a final branch stack is output at the end of the trace
by calling cs_etm__end_block(). This is already done for both the
timeless decode paths.

Fixes: 21fe8dc1191a ("perf cs-etm: Add support for CPU-wide trace scenarios")
Reported-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Closes: https://lore.kernel.org/all/20240719092619.274730-1-gankulkarni at os.amperecomputing.com/
Reviewed-by: Leo Yan <leo.yan at arm.com>
Signed-off-by: James Clark <james.clark at linaro.org>
Tested-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Cc: Ben Gainey <ben.gainey at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Ruidong Tian <tianruidong at linux.alibaba.com>
Cc: Benjamin Gray <bgray at linux.ibm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: coresight at lists.linaro.org
Cc: John Garry <john.g.garry at oracle.com>
Cc: scclevenger at os.amperecomputing.com
Link: https://lore.kernel.org/r/20240916135743.1490403-2-james.clark at linaro.org
Signed-off-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/perf/util/cs-etm.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index a2a369e2fbb67..e3fa32b83367e 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2098,12 +2098,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
 
 		/* Ignore return value */
 		cs_etm__process_traceid_queue(etmq, tidq);
-
-		/*
-		 * Generate an instruction sample with the remaining
-		 * branchstack entries.
-		 */
-		cs_etm__flush(etmq, tidq);
 	}
 }
 
@@ -2186,7 +2180,7 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
 
 	while (1) {
 		if (!etm->heap.heap_cnt)
-			goto out;
+			break;
 
 		/* Take the entry at the top of the min heap */
 		cs_queue_nr = etm->heap.heap_array[0].queue_nr;
@@ -2269,6 +2263,23 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
 		ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, timestamp);
 	}
 
+	for (i = 0; i < etm->queues.nr_queues; i++) {
+		struct int_node *inode;
+
+		etmq = etm->queues.queue_array[i].priv;
+		if (!etmq)
+			continue;
+
+		intlist__for_each_entry(inode, etmq->traceid_queues_list) {
+			int idx = (int)(intptr_t)inode->priv;
+
+			/* Flush any remaining branch stack entries */
+			tidq = etmq->traceid_queues[idx];
+			ret = cs_etm__end_block(etmq, tidq);
+			if (ret)
+				return ret;
+		}
+	}
 out:
 	return ret;
 }
-- 
2.43.0





From broonie at kernel.org  Thu Dec 12 09:26:47 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 12 Dec 2024 17:26:47 +0000
Subject: [PATCH v2] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <Z1sY9tIsAZ84W93-@arm.com>
References: <20241210160940.2031997-1-kevin.brodsky@arm.com>
 <5db7f7a0-1d3c-4bbd-ad2b-124bf54f49ef@sirena.org.uk>
 <Z1sY9tIsAZ84W93-@arm.com>
Message-ID: <a70cd007-a2c8-477f-972e-fa1e9c362604@sirena.org.uk>

On Thu, Dec 12, 2024 at 05:10:14PM +0000, Catalin Marinas wrote:
> On Thu, Dec 12, 2024 at 04:47:46PM +0000, Mark Brown wrote:

> > > Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")

> > Presumably we also need a Fixes for whatever introduced the above copy.

> Hmm, it was like this from the beginning. If we are to do a cc stable to
> the oldest maintained LTS, I'd rather have a separate patch for
> copy_siginfo_to_user(), it doesn't make much sense to backport a GCS
> patch to early kernels.

Hrm, good point about it triggering backports.  I'm not sure it's worth
doing that 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/20241212/93a51634/attachment.sig>

From robh at kernel.org  Thu Dec 12 09:28:56 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 12 Dec 2024 11:28:56 -0600
Subject: [PATCH v4 1/3] dt-bindings: mailbox: add google,gs101-mbox
 bindings
In-Reply-To: <20241212-acpm-v4-upstream-mbox-v4-1-02f8de92cfaf@linaro.org>
References: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>
 <20241212-acpm-v4-upstream-mbox-v4-1-02f8de92cfaf@linaro.org>
Message-ID: <173402453635.2828943.15564980222849076434.robh@kernel.org>


On Thu, 12 Dec 2024 15:43:45 +0000, Tudor Ambarus wrote:
> Add bindings for the Samsung Exynos Mailbox Controller.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  .../bindings/mailbox/google,gs101-mbox.yaml        | 79 ++++++++++++++++++++++
>  include/dt-bindings/mailbox/google,gs101.h         | 14 ++++
>  2 files changed, 93 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/mailbox/google,gs101-mbox.example.dtb: /example-0/soc/mailbox at 17610000: failed to match any schema with compatible: ['google,gs101-acpm-mbox']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241212-acpm-v4-upstream-mbox-v4-1-02f8de92cfaf 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 Frank.li at nxp.com  Thu Dec 12 09:29:16 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 12 Dec 2024 12:29:16 -0500
Subject: [PATCH v8 2/2] PCI: imx6: Add IOMMU and ITS MSI support for
 i.MX95
In-Reply-To: <Z1sTUaoA5yk9RcIc@lpieralisi>
References: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
 <20241210-imx95_lut-v8-2-2e730b2e5fde@nxp.com>
 <Z1sTUaoA5yk9RcIc@lpieralisi>
Message-ID: <Z1sdbH7N1Ly9eXc0@lizhi-Precision-Tower-5810>

On Thu, Dec 12, 2024 at 05:46:09PM +0100, Lorenzo Pieralisi wrote:
> On Tue, Dec 10, 2024 at 05:48:59PM -0500, Frank Li wrote:
> > For the i.MX95, configuration of a LUT is necessary to convert Bus Device
> > Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
> > This involves checking msi-map and iommu-map device tree properties to
> > ensure consistent mapping of PCI BDF to the same stream IDs. Subsequently,
> > LUT-related registers are configured. In the absence of an msi-map, the
> > built-in MSI controller is utilized as a fallback.
>
> This is wrong information. What you want to say is that if an msi-map
> isn't detected this means that the platform relies on DWC built-in
> controller for MSIs (that does not need streamIDs handling).
>
> That's quite different from what you are writing here.

How about ?

"If an msi-map isn't detected, platform relies on DWC built-in controller
for MSIs that does not need streamdIDs"

>
> >
> > Register a PCI bus callback function to handle enable_device() and
> > disable_device() operations, setting up the LUT whenever a new PCI device
> > is enabled.
> >
> > Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>

[...]

> > +	int err_i, err_m;
> > +	u32 sid;
> > +
> > +	dev = imx_pcie->pci->dev;
> > +
> > +	target = NULL;
> > +	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
> > +	if (target) {
> > +		of_node_put(target);
> > +	} else {
> > +		/*
> > +		 * "target == NULL && err_i == 0" means use 1:1 map RID to
>
> Is it what it means ? Or does it mean that the iommu-map property was found
> and RID is out of range ?

yes, if this happen, sid_i will be equal to RID.

>
> Could you point me at a sample dts for this host bridge please ?

https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/boot/dts/freescale/imx95.dtsi

/* 0x10~0x17 stream id for pci0 */
   iommu-map = <0x000 &smmu 0x10 0x1>,
               <0x100 &smmu 0x11 0x7>;

/* msi part */
   msi-map = <0x000 &its 0x10 0x1>,
             <0x100 &its 0x11 0x7>;

>
> > +		 * stream ID. Hardware can't support this because stream ID
> > +		 * only 5bits
>
> It is 5 or 6 bits ? From GENMASK(5, 0) above it should be 6.

Sorry for typo. it is 6bits.

>
> > +		 */
> > +		err_i = -EINVAL;
> > +	}
> > +
> > +	target = NULL;
> > +	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
> > +
> > +	/*
> > +	 *   err_m      target
> > +	 *	0	NULL		Use 1:1 map RID to stream ID,
>
> Again, is that what it really means ?
>
> > +	 *				Current hardware can't support it,
> > +	 *				So return -EINVAL.
> > +	 *      != 0    NULL		msi-map not exist, use built-in MSI.
>
> does not exist.
>
> > +	 *	0	!= NULL		Get correct streamID from RID.
> > +	 *	!= 0	!= NULL		Unexisted case, never happen.
>
> "Invalid combination"
>
> > +	 */
> > +	if (!err_m && !target)
> > +		return -EINVAL;
> > +	else if (target)
> > +		of_node_put(target); /* Find stream ID map entry for RID in msi-map */
> > +
> > +	/*
> > +	 * msi-map        iommu-map
> > +	 *   N                N            DWC MSI Ctrl
> > +	 *   Y                Y            ITS + SMMU, require the same sid
> > +	 *   Y                N            ITS
> > +	 *   N                Y            DWC MSI Ctrl + SMMU
> > +	 */
> > +	if (err_i && err_m)
> > +		return 0;
> > +
> > +	if (!err_i && !err_m) {
> > +		/*
> > +		 * MSI glue layer auto add 2 bits controller ID ahead of stream
>
> What's "MSI glue layer" ?

It is common term for IC desgin, which connect IP's signal to platform with
some simple logic. Inside chip, when connect LUT output 6bit streamIDs
to MSI controller, there are 2bits hardcode controller ID information
append to 6 bits streamID.

           Glue Layer
          <==========>
???????                  ????????????
? LUT ? 6bit stream ID   ?          ?
?     ????????????????????  MSI     ?
???????    2bit ctrl ID  ?          ?
            ??????????????          ?
            ?            ?          ?
 00 PCIe0   ?            ?          ?
 01 ENETC   ?            ?          ?
 10 PCIe1   ?            ?          ?
            ?            ????????????

>
> > +		 * ID, so mask this 2bits to get stream ID.
> > +		 * But IOMMU glue layer doesn't do that.
>
> and "IOMMU glue layer" ?

See above.

Frank

>
> > +		 */
> > +		if (sid_i != (sid_m & IMX95_SID_MASK)) {
> > +			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	sid = sid_i;
>
> err_i could be != 0 here, I understand that the end result is
> fine given how the code is written but it is misleading.
>
> 	if (!err_i)
> 	else if (!err_m)

Okay

>
> > +	if (!err_m)
> > +		sid = sid_m & IMX95_SID_MASK;
> > +
> > +	return imx_pcie_add_lut(imx_pcie, rid, sid);
> > +}
> > +
> > +static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> > +{
> > +	struct imx_pcie *imx_pcie;
> > +
> > +	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> > +	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
> > +}
> > +
> >  static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> >  {
> >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > @@ -946,6 +1122,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> >  		}
> >  	}
> >
> > +	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
> > +		pp->bridge->enable_device = imx_pcie_enable_device;
> > +		pp->bridge->disable_device = imx_pcie_disable_device;
> > +	}
> > +
> >  	imx_pcie_assert_core_reset(imx_pcie);
> >
> >  	if (imx_pcie->drvdata->init_phy)
> > @@ -1330,6 +1511,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
> >  	imx_pcie->pci = pci;
> >  	imx_pcie->drvdata = of_device_get_match_data(dev);
> >
> > +	mutex_init(&imx_pcie->lock);
> > +
> >  	/* Find the PHY if one is defined, only imx7d uses it */
> >  	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
> >  	if (np) {
> > @@ -1627,7 +1810,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
> >  	},
> >  	[IMX95] = {
> >  		.variant = IMX95,
> > -		.flags = IMX_PCIE_FLAG_HAS_SERDES,
> > +		.flags = IMX_PCIE_FLAG_HAS_SERDES |
> > +			 IMX_PCIE_FLAG_HAS_LUT,
> >  		.clk_names = imx8mq_clks,
> >  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> >  		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> >
> > --
> > 2.34.1
> >


From Frank.li at nxp.com  Thu Dec 12 09:39:06 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 12 Dec 2024 12:39:06 -0500
Subject: [PATCH 1/2] dt-bindings: nvmem: imx-ocotp: Introduce
 #access-controller-cells
In-Reply-To: <20241212-imx-ocotp-v1-1-198bb0af86a0@nxp.com>
References: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>
 <20241212-imx-ocotp-v1-1-198bb0af86a0@nxp.com>
Message-ID: <Z1sfuloPhKdv3Zel@lizhi-Precision-Tower-5810>

On Thu, Dec 12, 2024 at 04:24:41PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
>
> Introduce "#access-controller-cells" to make OCOTP be an accessing
> controller, because i.MX Family OCOTP supports a specific peripheral
> or function being fused which means being disabled.
>
> Add the i.MX[95,93] OCOTP gate index.
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---

Nice feature!

Reviewed-by: Frank Li <Frank.Li at nxp.com>

>  .../devicetree/bindings/nvmem/imx-ocotp.yaml       |  5 +++
>  include/dt-bindings/nvmem/fsl,imx93-ocotp.h        | 24 ++++++++++++
>  include/dt-bindings/nvmem/fsl,imx95-ocotp.h        | 43 ++++++++++++++++++++++
>  3 files changed, 72 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
> index b2cb76cf9053a883a158acaf5eaa108895818afc..c78e202ced22f1c278f7be827b71ba434832d2a7 100644
> --- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
> +++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
> @@ -54,6 +54,11 @@ properties:
>    clocks:
>      maxItems: 1
>
> +  "#access-controller-cells":
> +    const: 1
> +    description:
> +      Contains the gate ID associated to the peripheral.
> +
>  required:
>    - "#address-cells"
>    - "#size-cells"
> diff --git a/include/dt-bindings/nvmem/fsl,imx93-ocotp.h b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..6ef525173845fd4ee0e847cf5a17e53a14f71362
> --- /dev/null
> +++ b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> +
> +#ifndef _DT_BINDINGS_NVMEM_IMX93_OTPC_H
> +#define _DT_BINDINGS_NVMEM_IMX93_OTPC_H
> +
> +#define IMX93_OCOTP_NPU_GATE		0
> +#define IMX93_OCOTP_A550_GATE		1
> +#define IMX93_OCOTP_A551_GATE		2
> +#define IMX93_OCOTP_M33_GATE		3
> +#define IMX93_OCOTP_CAN1_FD_GATE	4
> +#define IMX93_OCOTP_CAN2_FD_GATE	5
> +#define IMX93_OCOTP_CAN1_GATE		6
> +#define IMX93_OCOTP_CAN2_GATE		7
> +#define IMX93_OCOTP_USB1_GATE		8
> +#define IMX93_OCOTP_USB2_GATE		9
> +#define IMX93_OCOTP_ENET1_GATE		10
> +#define IMX93_OCOTP_ENET2_GATE		11
> +#define IMX93_OCOTP_PXP_GATE		12
> +#define IMX93_OCOTP_MIPI_CSI1_GATE	13
> +#define IMX93_OCOTP_MIPI_DSI1_GATE	14
> +#define IMX93_OCOTP_LVDS1_GATE		15
> +#define IMX93_OCOTP_ADC1_GATE		16
> +
> +#endif
> diff --git a/include/dt-bindings/nvmem/fsl,imx95-ocotp.h b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..2d21d1f690974d0215c71352168378a150f489af
> --- /dev/null
> +++ b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
> @@ -0,0 +1,43 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> +
> +#ifndef _DT_BINDINGS_NVMEM_IMX95_OTPC_H
> +#define _DT_BINDINGS_NVMEM_IMX95_OTPC_H
> +
> +#define IMX95_OCOTP_CANFD1_GATE		0
> +#define IMX95_OCOTP_CANFD2_GATE		1
> +#define IMX95_OCOTP_CANFD3_GATE		2
> +#define IMX95_OCOTP_CANFD4_GATE		3
> +#define IMX95_OCOTP_CANFD5_GATE		4
> +#define IMX95_OCOTP_CAN1_GATE		5
> +#define IMX95_OCOTP_CAN2_GATE		6
> +#define IMX95_OCOTP_CAN3_GATE		7
> +#define IMX95_OCOTP_CAN4_GATE		8
> +#define IMX95_OCOTP_CAN5_GATE		9
> +#define IMX95_OCOTP_NPU_GATE		10
> +#define IMX95_OCOTP_A550_GATE		11
> +#define IMX95_OCOTP_A551_GATE		12
> +#define IMX95_OCOTP_A552_GATE		13
> +#define IMX95_OCOTP_A553_GATE		14
> +#define IMX95_OCOTP_A554_GATE		15
> +#define IMX95_OCOTP_A555_GATE		16
> +#define IMX95_OCOTP_M7_GATE		17
> +#define IMX95_OCOTP_DCSS_GATE		18
> +#define IMX95_OCOTP_LVDS1_GATE		19
> +#define IMX95_OCOTP_ISP_GATE		20
> +#define IMX95_OCOTP_USB1_GATE		21
> +#define IMX95_OCOTP_USB2_GATE		22
> +#define IMX95_OCOTP_NETC_GATE		23
> +#define IMX95_OCOTP_PCIE1_GATE		24
> +#define IMX95_OCOTP_PCIE2_GATE		25
> +#define IMX95_OCOTP_ADC1_GATE		26
> +#define IMX95_OCOTP_EARC_RX_GATE	27
> +#define IMX95_OCOTP_GPU3D_GATE		28
> +#define IMX95_OCOTP_VPU_GATE		29
> +#define IMX95_OCOTP_JPEG_ENC_GATE	30
> +#define IMX95_OCOTP_JPEG_DEC_GATE	31
> +#define IMX95_OCOTP_MIPI_CSI1_GATE	32
> +#define IMX95_OCOTP_MIPI_CSI2_GATE	33
> +#define IMX95_OCOTP_MIPI_DSI1_GATE	34
> +#define IMX95_OCOTP_V2X_GATE		35
> +
> +#endif
>
> --
> 2.37.1
>


From gregkh at linuxfoundation.org  Thu Dec 12 07:00:28 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 12 Dec 2024 16:00:28 +0100
Subject: [PATCH 5.4 110/321] perf cs-etm: Dont flush when packet_queue fills up
In-Reply-To: <20241212144229.291682835@linuxfoundation.org>
References: <20241212144229.291682835@linuxfoundation.org>
Message-ID: <20241212144234.330343381@linuxfoundation.org>

5.4-stable review patch.  If anyone has any objections, please let me know.

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

From: James Clark <james.clark at linaro.org>

[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]

cs_etm__flush(), like cs_etm__sample() is an operation that generates a
sample and then swaps the current with the previous packet. Calling
flush after processing the queues results in two swaps which corrupts
the next sample. Therefore it wasn't appropriate to call flush here so
remove it.

Flushing is still done on a discontinuity to explicitly clear the last
branch buffer, but when the packet_queue fills up before reaching a
timestamp, that's not a discontinuity and the call to
cs_etm__process_traceid_queue() already generated samples and drained
the buffers correctly.

This is visible by looking for a branch that has the same target as the
previous branch and the following source is before the address of the
last target, which is impossible as execution would have had to have
gone backwards:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
   (packet_queue fills here before a timestamp, resulting in a flush and
    branch target ffff80008011cadc is duplicated.)
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

After removing the flush the correct branch target is used for the
second sample, and ffff8000801117c4 is no longer before the previous
address:

  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0
  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34

Make sure that a final branch stack is output at the end of the trace
by calling cs_etm__end_block(). This is already done for both the
timeless decode paths.

Fixes: 21fe8dc1191a ("perf cs-etm: Add support for CPU-wide trace scenarios")
Reported-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Closes: https://lore.kernel.org/all/20240719092619.274730-1-gankulkarni at os.amperecomputing.com/
Reviewed-by: Leo Yan <leo.yan at arm.com>
Signed-off-by: James Clark <james.clark at linaro.org>
Tested-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Cc: Ben Gainey <ben.gainey at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Ruidong Tian <tianruidong at linux.alibaba.com>
Cc: Benjamin Gray <bgray at linux.ibm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: coresight at lists.linaro.org
Cc: John Garry <john.g.garry at oracle.com>
Cc: scclevenger at os.amperecomputing.com
Link: https://lore.kernel.org/r/20240916135743.1490403-2-james.clark at linaro.org
Signed-off-by: Namhyung Kim <namhyung at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/perf/util/cs-etm.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index f5a9cb4088080..bd63bd14417fd 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2066,12 +2066,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
 
 		/* Ignore return value */
 		cs_etm__process_traceid_queue(etmq, tidq);
-
-		/*
-		 * Generate an instruction sample with the remaining
-		 * branchstack entries.
-		 */
-		cs_etm__flush(etmq, tidq);
 	}
 }
 
@@ -2154,7 +2148,7 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
 
 	while (1) {
 		if (!etm->heap.heap_cnt)
-			goto out;
+			break;
 
 		/* Take the entry at the top of the min heap */
 		cs_queue_nr = etm->heap.heap_array[0].queue_nr;
@@ -2237,6 +2231,23 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
 		ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, timestamp);
 	}
 
+	for (i = 0; i < etm->queues.nr_queues; i++) {
+		struct int_node *inode;
+
+		etmq = etm->queues.queue_array[i].priv;
+		if (!etmq)
+			continue;
+
+		intlist__for_each_entry(inode, etmq->traceid_queues_list) {
+			int idx = (int)(intptr_t)inode->priv;
+
+			/* Flush any remaining branch stack entries */
+			tidq = etmq->traceid_queues[idx];
+			ret = cs_etm__end_block(etmq, tidq);
+			if (ret)
+				return ret;
+		}
+	}
 out:
 	return ret;
 }
-- 
2.43.0





From Frank.li at nxp.com  Thu Dec 12 09:45:48 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 12 Dec 2024 12:45:48 -0500
Subject: [PATCH 2/2] nvmem: imx-ocotp-ele: Support accessing controller
 for i.MX9
In-Reply-To: <20241212-imx-ocotp-v1-2-198bb0af86a0@nxp.com>
References: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>
 <20241212-imx-ocotp-v1-2-198bb0af86a0@nxp.com>
Message-ID: <Z1shTD5QLRXB1wAk@lizhi-Precision-Tower-5810>

On Thu, Dec 12, 2024 at 04:24:42PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
>
> i.MX9 OCOTP supports a specific peripheral or function being fused
> which means disabled, so
>  - Introduce ocotp_access_gates to be container of efuse gate info
>  - Iterate each node under '/soc' to check accessing permission. If not
>    allowed to be accessed, detach the node
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/nvmem/imx-ocotp-ele.c | 187 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 186 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
> index ca6dd71d8a2e29888c6e556aaea116c1a967cb5f..542539b86efd2d38be2903c1d0ea72f918ff5b75 100644
> --- a/drivers/nvmem/imx-ocotp-ele.c
> +++ b/drivers/nvmem/imx-ocotp-ele.c
> @@ -5,6 +5,8 @@
>   * Copyright 2023 NXP
>   */
>
> +#include <dt-bindings/nvmem/fsl,imx93-ocotp.h>
> +#include <dt-bindings/nvmem/fsl,imx95-ocotp.h>
>  #include <linux/device.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
> @@ -27,6 +29,7 @@ struct ocotp_map_entry {
>  };
>
>  struct ocotp_devtype_data {
> +	const struct ocotp_access_gates *access_gates;
>  	u32 reg_off;
>  	char *name;
>  	u32 size;
> @@ -36,11 +39,26 @@ struct ocotp_devtype_data {
>  	struct ocotp_map_entry entry[];
>  };
>
> +#define OCOTP_MAX_NUM_GATE_WORDS 4
> +#define IMX93_OCOTP_NUM_GATES 17
> +#define IMX95_OCOTP_NUM_GATES 36
> +
> +struct ocotp_access_gates {
> +	u32 num_words;
> +	u32 words[OCOTP_MAX_NUM_GATE_WORDS];
> +	u32 num_gates;
> +	struct access_gate {
> +		u32 word;
> +		u32 mask;
> +	} gates[];
> +};
> +
>  struct imx_ocotp_priv {
>  	struct device *dev;
>  	void __iomem *base;
>  	struct nvmem_config config;
>  	struct mutex lock;
> +	u32 value[OCOTP_MAX_NUM_GATE_WORDS];
>  	const struct ocotp_devtype_data *data;
>  };
>
> @@ -131,6 +149,100 @@ static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
>  	cell->read_post_process = imx_ocotp_cell_pp;
>  }
>
> +static int imx_ele_ocotp_check_access(struct platform_device *pdev, u32 id)
> +{
> +	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
> +	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
> +	u32 word, mask;
> +
> +	if (id >= access_gates->num_gates) {
> +		dev_err(&pdev->dev, "Index %d too large\n", id);
> +		return -EACCES;
> +	}
> +
> +	word = access_gates->gates[id].word;
> +	mask = access_gates->gates[id].mask;
> +
> +	dev_dbg(&pdev->dev, "id:%d word:%d mask:0x%08x\n", id, word, mask);
> +	/* true means not allow access */
> +	if (priv->value[word] & mask)
> +		return -EACCES;
> +
> +	return 0;
> +}
> +
> +static int imx_ele_ocotp_grant_access(struct platform_device *pdev, struct device_node *parent)
> +{
> +	struct device_node *child;
> +	struct device *dev = &pdev->dev;
> +
> +	for_each_available_child_of_node(parent, child) {
> +		struct of_phandle_iterator it;
> +		int err;
> +		u32 id;
> +
> +		of_for_each_phandle(&it, err, child, "access-controllers",
> +				    "#access-controller-cells", 0) {
> +			struct of_phandle_args provider_args;
> +			struct device_node *provider = it.node;
> +
> +			if (err) {
> +				dev_err(dev, "Unable to get access-controllers property for node %s\n, err: %d",
> +					child->full_name, err);
> +				of_node_put(provider);
> +				return err;
> +			}
> +
> +			/* Only support one cell */
> +			if (of_phandle_iterator_args(&it, provider_args.args, 1) != 1) {
> +				dev_err(dev, "wrong args count\n");
> +				return -EINVAL;
> +			}
> +
> +			id = provider_args.args[0];
> +
> +			dev_dbg(dev, "Checking node: %s gate: %d\n", child->full_name, id);
> +
> +			if (imx_ele_ocotp_check_access(pdev, id)) {
> +				of_detach_node(child);
> +				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
> +					child->full_name);
> +			}
> +		}
> +
> +		imx_ele_ocotp_grant_access(pdev, child);
> +	}

Does it mean ocopt driver have to probe before other driver probe?

Frank

> +
> +	return 0;
> +}
> +
> +static int imx_ele_ocotp_access_control(struct platform_device *pdev)
> +{
> +	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
> +	struct device_node *soc __free(device_node) = of_find_node_by_path("/soc");
> +	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
> +	void __iomem *reg = priv->base + priv->data->reg_off;
> +	u32 off;
> +	int i;
> +
> +	if (!priv->data->access_gates)
> +		return 0;
> +
> +	if (!soc)
> +		soc = of_find_node_by_path("/soc at 0");
> +
> +	/* This should never happen */
> +	WARN_ON(!soc);
> +
> +	for (i = 0; i < access_gates->num_words; i++) {
> +		off = access_gates->words[i] << 2;
> +		priv->value[i] = readl(reg + off);
> +		dev_dbg(&pdev->dev, "word:%d 0x%08x\n", access_gates->words[i], priv->value[i]);
> +	}
> +
> +	return imx_ele_ocotp_grant_access(pdev, soc);
> +}
> +
>  static int imx_ele_ocotp_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -161,14 +273,43 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
>  	priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
>  	mutex_init(&priv->lock);
>
> +	platform_set_drvdata(pdev, priv);
> +
>  	nvmem = devm_nvmem_register(dev, &priv->config);
>  	if (IS_ERR(nvmem))
>  		return PTR_ERR(nvmem);
>
> -	return 0;
> +
> +	return imx_ele_ocotp_access_control(pdev);
>  }
>
> +static const struct ocotp_access_gates imx93_access_gates = {
> +	.num_words = 3,
> +	.words = {19, 20, 21},
> +	.num_gates = IMX93_OCOTP_NUM_GATES,
> +	.gates = {
> +		[IMX93_OCOTP_NPU_GATE]		= { .word = 19, .mask = BIT(13) },
> +		[IMX93_OCOTP_A550_GATE]		= { .word = 19, .mask = BIT(14) },
> +		[IMX93_OCOTP_A551_GATE]		= { .word = 19, .mask = BIT(15) },
> +		[IMX93_OCOTP_M33_GATE]		= { .word = 19, .mask = BIT(24) },
> +		[IMX93_OCOTP_CAN1_FD_GATE]	= { .word = 19, .mask = BIT(28) },
> +		[IMX93_OCOTP_CAN2_FD_GATE]	= { .word = 19, .mask = BIT(29) },
> +		[IMX93_OCOTP_CAN1_GATE]		= { .word = 19, .mask = BIT(30) },
> +		[IMX93_OCOTP_CAN2_GATE]		= { .word = 19, .mask = BIT(31) },
> +		[IMX93_OCOTP_USB1_GATE]		= { .word = 20, .mask = BIT(3) },
> +		[IMX93_OCOTP_USB2_GATE]		= { .word = 20, .mask = BIT(4) },
> +		[IMX93_OCOTP_ENET1_GATE]	= { .word = 20, .mask = BIT(5) },
> +		[IMX93_OCOTP_ENET2_GATE]	= { .word = 20, .mask = BIT(6) },
> +		[IMX93_OCOTP_PXP_GATE]		= { .word = 20, .mask = BIT(10) },
> +		[IMX93_OCOTP_MIPI_CSI1_GATE]	= { .word = 20, .mask = BIT(17) },
> +		[IMX93_OCOTP_MIPI_DSI1_GATE]	= { .word = 20, .mask = BIT(19) },
> +		[IMX93_OCOTP_LVDS1_GATE]	= { .word = 20, .mask = BIT(24) },
> +		[IMX93_OCOTP_ADC1_GATE]		= { .word = 21, .mask = BIT(7) },
> +	},
> +};
> +
>  static const struct ocotp_devtype_data imx93_ocotp_data = {
> +	.access_gates = &imx93_access_gates,
>  	.reg_off = 0x8000,
>  	.reg_read = imx_ocotp_reg_read,
>  	.size = 2048,
> @@ -183,7 +324,51 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
>  	},
>  };
>
> +static const struct ocotp_access_gates imx95_access_gates = {
> +	.num_words = 3,
> +	.words = {17, 18, 19},
> +	.num_gates = IMX95_OCOTP_NUM_GATES,
> +	.gates = {
> +		[IMX95_OCOTP_CANFD1_GATE]	= { .word = 17, .mask = BIT(20) },
> +		[IMX95_OCOTP_CANFD2_GATE]	= { .word = 17, .mask = BIT(21) },
> +		[IMX95_OCOTP_CANFD3_GATE]	= { .word = 17, .mask = BIT(22) },
> +		[IMX95_OCOTP_CANFD4_GATE]	= { .word = 17, .mask = BIT(23) },
> +		[IMX95_OCOTP_CANFD5_GATE]	= { .word = 17, .mask = BIT(24) },
> +		[IMX95_OCOTP_CAN1_GATE]	= { .word = 17, .mask = BIT(25) },
> +		[IMX95_OCOTP_CAN2_GATE]	= { .word = 17, .mask = BIT(26) },
> +		[IMX95_OCOTP_CAN3_GATE]	= { .word = 17, .mask = BIT(27) },
> +		[IMX95_OCOTP_CAN4_GATE]	= { .word = 17, .mask = BIT(28) },
> +		[IMX95_OCOTP_CAN5_GATE]	= { .word = 17, .mask = BIT(29) },
> +		[IMX95_OCOTP_NPU_GATE]		= { .word = 18, .mask = BIT(0) },
> +		[IMX95_OCOTP_A550_GATE]	= { .word = 18, .mask = BIT(1) },
> +		[IMX95_OCOTP_A551_GATE]	= { .word = 18, .mask = BIT(2) },
> +		[IMX95_OCOTP_A552_GATE]	= { .word = 18, .mask = BIT(3) },
> +		[IMX95_OCOTP_A553_GATE]	= { .word = 18, .mask = BIT(4) },
> +		[IMX95_OCOTP_A554_GATE]	= { .word = 18, .mask = BIT(5) },
> +		[IMX95_OCOTP_A555_GATE]	= { .word = 18, .mask = BIT(6) },
> +		[IMX95_OCOTP_M7_GATE]		= { .word = 18, .mask = BIT(9) },
> +		[IMX95_OCOTP_DCSS_GATE]	= { .word = 18, .mask = BIT(22) },
> +		[IMX95_OCOTP_LVDS1_GATE]	= { .word = 18, .mask = BIT(27) },
> +		[IMX95_OCOTP_ISP_GATE]		= { .word = 18, .mask = BIT(29) },
> +		[IMX95_OCOTP_USB1_GATE]	= { .word = 19, .mask = BIT(2) },
> +		[IMX95_OCOTP_USB2_GATE]	= { .word = 19, .mask = BIT(3) },
> +		[IMX95_OCOTP_NETC_GATE]	= { .word = 19, .mask = BIT(4) },
> +		[IMX95_OCOTP_PCIE1_GATE]	= { .word = 19, .mask = BIT(6) },
> +		[IMX95_OCOTP_PCIE2_GATE]	= { .word = 19, .mask = BIT(7) },
> +		[IMX95_OCOTP_ADC1_GATE]	= { .word = 19, .mask = BIT(8) },
> +		[IMX95_OCOTP_EARC_RX_GATE]	= { .word = 19, .mask = BIT(11) },
> +		[IMX95_OCOTP_GPU3D_GATE]	= { .word = 19, .mask = BIT(16) },
> +		[IMX95_OCOTP_VPU_GATE]		= { .word = 19, .mask = BIT(17) },
> +		[IMX95_OCOTP_JPEG_ENC_GATE]	= { .word = 19, .mask = BIT(18) },
> +		[IMX95_OCOTP_JPEG_DEC_GATE]	= { .word = 19, .mask = BIT(19) },
> +		[IMX95_OCOTP_MIPI_CSI1_GATE]	= { .word = 19, .mask = BIT(21) },
> +		[IMX95_OCOTP_MIPI_CSI2_GATE]	= { .word = 19, .mask = BIT(22) },
> +		[IMX95_OCOTP_MIPI_DSI1_GATE]	= { .word = 19, .mask = BIT(23) },
> +	}
> +};
> +
>  static const struct ocotp_devtype_data imx95_ocotp_data = {
> +	.access_gates = &imx95_access_gates,
>  	.reg_off = 0x8000,
>  	.reg_read = imx_ocotp_reg_read,
>  	.size = 2048,
>
> --
> 2.37.1
>


From catalin.marinas at arm.com  Thu Dec 12 09:51:54 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 12 Dec 2024 17:51:54 +0000
Subject: [PATCH v2] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <a70cd007-a2c8-477f-972e-fa1e9c362604@sirena.org.uk>
References: <20241210160940.2031997-1-kevin.brodsky@arm.com>
 <5db7f7a0-1d3c-4bbd-ad2b-124bf54f49ef@sirena.org.uk>
 <Z1sY9tIsAZ84W93-@arm.com>
 <a70cd007-a2c8-477f-972e-fa1e9c362604@sirena.org.uk>
Message-ID: <Z1siulo_PKdI3xC_@arm.com>

On Thu, Dec 12, 2024 at 05:26:47PM +0000, Mark Brown wrote:
> On Thu, Dec 12, 2024 at 05:10:14PM +0000, Catalin Marinas wrote:
> > On Thu, Dec 12, 2024 at 04:47:46PM +0000, Mark Brown wrote:
> > > > Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")
> > > 
> > > Presumably we also need a Fixes for whatever introduced the above copy.
> > 
> > Hmm, it was like this from the beginning. If we are to do a cc stable to
> > the oldest maintained LTS, I'd rather have a separate patch for
> > copy_siginfo_to_user(), it doesn't make much sense to backport a GCS
> > patch to early kernels.
> 
> Hrm, good point about it triggering backports.  I'm not sure it's worth
> doing that TBH.

I had the same thoughts. I think this was mostly triggered by the
POR_EL0 changes when Will raised the point that the kernel might return
with a more privileged value in this sysreg.

-- 
Catalin


From tudor.ambarus at linaro.org  Thu Dec 12 09:53:22 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 12 Dec 2024 17:53:22 +0000
Subject: [PATCH v4 1/3] dt-bindings: mailbox: add google,gs101-mbox
 bindings
In-Reply-To: <173402453635.2828943.15564980222849076434.robh@kernel.org>
References: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>
 <20241212-acpm-v4-upstream-mbox-v4-1-02f8de92cfaf@linaro.org>
 <173402453635.2828943.15564980222849076434.robh@kernel.org>
Message-ID: <90720b8f-340f-4f27-ae51-df98b2e5e820@linaro.org>



On 12/12/24 5:28 PM, Rob Herring (Arm) wrote:
> My bot found errors running 'make dt_binding_check' on your patch:
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/mailbox/google,gs101-mbox.example.dtb:
>  /example-0/soc/mailbox at 17610000: failed to match any schema with 
> compatible: ['google,gs101-acpm-mbox']

ugh, I remember I fixed this, compatible in the example needs to be
updated to 'google,gs101-mbox'. I'll send a new version tomorrow.

Thanks,
ta


From smostafa at google.com  Thu Dec 12 10:04:00 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:00 +0000
Subject: [RFC PATCH v2 36/58] KVM: arm64: smmu-v3: Add detach_dev
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-37-smostafa@google.com>

Add detach_dev for stage-1 and stage-2 domains.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 76 ++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index a96eb6625c48..ec3f8d9749d3 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -335,7 +335,6 @@ static u64 *smmu_alloc_cd(struct hyp_arm_smmu_v3_device *smmu, u32 pasid_bits)
 	return (u64 *)hyp_virt_to_phys(cd_table);
 }
 
-__maybe_unused
 static void smmu_free_cd(u64 *cd_table, u32 pasid_bits)
 {
 	u32 order = get_order((1 << pasid_bits) *
@@ -1052,6 +1051,80 @@ static int smmu_attach_dev(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_dom
 	return ret;
 }
 
+static int smmu_detach_dev(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_domain *domain,
+			   u32 sid, u32 pasid)
+{
+	struct arm_smmu_ste *dst;
+	int i, ret;
+	struct hyp_arm_smmu_v3_device *smmu = to_smmu(iommu);
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+	u32 pasid_bits = 0;
+	u64 *cd_table, *cd;
+
+	kvm_iommu_lock(iommu);
+	dst = smmu_get_ste_ptr(smmu, sid);
+	if (!dst) {
+		ret = -ENODEV;
+		goto out_unlock;
+	}
+
+	/*
+	 * For stage-1:
+	 * - The kernel has to detach pasid = 0 the last.
+	 * - This will free the CD.
+	 */
+	if (smmu_domain->type == KVM_ARM_SMMU_DOMAIN_S1) {
+		pasid_bits = FIELD_GET(STRTAB_STE_0_S1CDMAX, dst->data[0]);
+		if (pasid >= (1 << pasid_bits)) {
+			ret = -E2BIG;
+			goto out_unlock;
+		}
+		cd_table = (u64 *)(dst->data[0] & STRTAB_STE_0_S1CTXPTR_MASK);
+		if (WARN_ON(!cd_table)) {
+			ret = -ENODEV;
+			goto out_unlock;
+		}
+
+		cd_table = hyp_phys_to_virt((phys_addr_t)cd_table);
+		if (pasid == 0) {
+			int j;
+
+			/* Ensure other pasids are detached. */
+			for (j = 1 ; j < (1 << pasid_bits) ; ++j) {
+				cd = smmu_get_cd_ptr(cd_table, j);
+				if (cd[0] & CTXDESC_CD_0_V) {
+					ret = -EINVAL;
+					goto out_unlock;
+				}
+			}
+		} else {
+			cd = smmu_get_cd_ptr(cd_table, pasid);
+			cd[0] = 0;
+			smmu_sync_cd(smmu, sid, pasid);
+			cd[1] = 0;
+			cd[2] = 0;
+			cd[3] = 0;
+			ret = smmu_sync_cd(smmu, sid, pasid);
+			goto out_unlock;
+		}
+	}
+	/* For stage-2 and pasid = 0 */
+	dst->data[0] = 0;
+	ret = smmu_sync_ste(smmu, sid);
+	if (ret)
+		goto out_unlock;
+	for (i = 1; i < STRTAB_STE_DWORDS; i++)
+		dst->data[i] = 0;
+
+	ret = smmu_sync_ste(smmu, sid);
+
+	smmu_free_cd(cd_table, pasid_bits);
+
+out_unlock:
+	kvm_iommu_unlock(iommu);
+	return ret;
+}
+
 /* Shared with the kernel driver in EL1 */
 struct kvm_iommu_ops smmu_ops = {
 	.init				= smmu_init,
@@ -1060,4 +1133,5 @@ struct kvm_iommu_ops smmu_ops = {
 	.free_domain			= smmu_free_domain,
 	.iotlb_sync			= smmu_iotlb_sync,
 	.attach_dev			= smmu_attach_dev,
+	.detach_dev			= smmu_detach_dev,
 };
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:01 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:01 +0000
Subject: [RFC PATCH v2 37/58] iommu/io-pgtable: Generalize walker interface
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-38-smostafa@google.com>

Add a common struct for walker, which has a callback visitor
with HW agnostic info (phys addr + size).

Add size to walker so it can walk a range of IOVAs.

Also, add a cookie for the arm walker.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/gpu/drm/msm/msm_iommu.c       |  5 +++-
 drivers/iommu/io-pgtable-arm-common.c | 35 ++++++++++++++++++---------
 include/linux/io-pgtable-arm.h        |  2 +-
 include/linux/io-pgtable.h            | 18 ++++++++++++--
 4 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 3e692818ba1f..8516861dd626 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -200,6 +200,9 @@ msm_iommu_pagetable_walk(struct msm_mmu *mmu, unsigned long iova, uint64_t ptes[
 {
 	struct msm_iommu_pagetable *pagetable;
 	struct arm_lpae_io_pgtable_walk_data wd = {};
+	struct io_pgtable_walk_common walker = {
+		.data = &wd,
+	};
 
 	if (mmu->type != MSM_MMU_IOMMU_PAGETABLE)
 		return -EINVAL;
@@ -209,7 +212,7 @@ msm_iommu_pagetable_walk(struct msm_mmu *mmu, unsigned long iova, uint64_t ptes[
 	if (!pagetable->pgtbl_ops->pgtable_walk)
 		return -EINVAL;
 
-	pagetable->pgtbl_ops->pgtable_walk(pagetable->pgtbl_ops, iova, &wd);
+	pagetable->pgtbl_ops->pgtable_walk(pagetable->pgtbl_ops, iova, 1, &walker);
 
 	for (int i = 0; i < ARRAY_SIZE(wd.ptes); i++)
 		ptes[i] = wd.ptes[i];
diff --git a/drivers/iommu/io-pgtable-arm-common.c b/drivers/iommu/io-pgtable-arm-common.c
index 21ee8ff7c881..4fc0b03494e3 100644
--- a/drivers/iommu/io-pgtable-arm-common.c
+++ b/drivers/iommu/io-pgtable-arm-common.c
@@ -481,7 +481,8 @@ struct iova_to_phys_data {
 static int visit_iova_to_phys(struct io_pgtable_walk_data *walk_data, int lvl,
 			      arm_lpae_iopte *ptep, size_t size)
 {
-	struct iova_to_phys_data *data = walk_data->data;
+	struct io_pgtable_walk_common *walker = walk_data->data;
+	struct iova_to_phys_data *data = walker->data;
 	data->pte = *ptep;
 	data->lvl = lvl;
 	return 0;
@@ -492,8 +493,11 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	struct iova_to_phys_data d;
-	struct io_pgtable_walk_data walk_data = {
+	struct io_pgtable_walk_common walker = {
 		.data = &d,
+	};
+	struct io_pgtable_walk_data walk_data = {
+		.data = &walker,
 		.visit = visit_iova_to_phys,
 		.addr = iova,
 		.end = iova + 1,
@@ -511,23 +515,25 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
 static int visit_pgtable_walk(struct io_pgtable_walk_data *walk_data, int lvl,
 			      arm_lpae_iopte *ptep, size_t size)
 {
-	struct arm_lpae_io_pgtable_walk_data *data = walk_data->data;
-	data->ptes[data->level++] = *ptep;
+	struct io_pgtable_walk_common *walker = walk_data->data;
+	struct arm_lpae_io_pgtable_walk_data *data = walker->data;
+
+	data->ptes[lvl] = *ptep;
+	data->level = lvl + 1;
 	return 0;
 }
 
-static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova, void *wd)
+static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
+				 size_t size, struct io_pgtable_walk_common *walker)
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	struct io_pgtable_walk_data walk_data = {
-		.data = wd,
+		.data = walker,
 		.visit = visit_pgtable_walk,
 		.addr = iova,
-		.end = iova + 1,
+		.end = iova + size,
 	};
 
-	((struct arm_lpae_io_pgtable_walk_data *)wd)->level = 0;
-
 	return __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
 }
 
@@ -537,6 +543,7 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
 {
 	struct io_pgtable *iop = &data->iop;
 	arm_lpae_iopte pte = READ_ONCE(*ptep);
+	struct io_pgtable_walk_common *walker = walk_data->data;
 
 	size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
 	int ret = walk_data->visit(walk_data, lvl, ptep, size);
@@ -544,6 +551,8 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
 		return ret;
 
 	if (iopte_leaf(pte, lvl, iop->fmt)) {
+		if (walker->visit_leaf)
+			walker->visit_leaf(iopte_to_paddr(pte, data), size, walker, ptep);
 		walk_data->addr += size;
 		return 0;
 	}
@@ -585,7 +594,8 @@ static int __arm_lpae_iopte_walk(struct arm_lpae_io_pgtable *data,
 static int visit_dirty(struct io_pgtable_walk_data *walk_data, int lvl,
 		       arm_lpae_iopte *ptep, size_t size)
 {
-	struct iommu_dirty_bitmap *dirty = walk_data->data;
+	struct io_pgtable_walk_common *walker = walk_data->data;
+	struct iommu_dirty_bitmap *dirty = walker->data;
 
 	if (!iopte_leaf(*ptep, lvl, walk_data->iop->fmt))
 		return 0;
@@ -606,9 +616,12 @@ static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	struct io_pgtable_walk_common walker = {
+		.data = dirty,
+	};
 	struct io_pgtable_walk_data walk_data = {
 		.iop = &data->iop,
-		.data = dirty,
+		.data = &walker,
 		.visit = visit_dirty,
 		.flags = flags,
 		.addr = iova,
diff --git a/include/linux/io-pgtable-arm.h b/include/linux/io-pgtable-arm.h
index 88922314157d..9e5878c37d78 100644
--- a/include/linux/io-pgtable-arm.h
+++ b/include/linux/io-pgtable-arm.h
@@ -18,7 +18,7 @@ struct arm_lpae_io_pgtable {
 
 struct io_pgtable_walk_data {
 	struct io_pgtable		*iop;
-	void				*data;
+	struct io_pgtable_walk_common	*data;
 	int (*visit)(struct io_pgtable_walk_data *walk_data, int lvl,
 		     arm_lpae_iopte *ptep, size_t size);
 	unsigned long			flags;
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index f789234c703b..da50e17b0177 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -185,12 +185,25 @@ struct io_pgtable_cfg {
  *
  * @ptes:     The recorded PTE values from the walk
  * @level:    The level of the last PTE
+ * @cookie:   Cookie set by caller to identify it
  *
  * @level also specifies the last valid index in @ptes
  */
 struct arm_lpae_io_pgtable_walk_data {
 	u64 ptes[4];
 	int level;
+	void *cookie;
+};
+
+/**
+ * struct io_pgtable_walk_common - common information from a pgtable walk
+ * @visit_leaf: callback for each leaf providing it's physical address and size
+ */
+struct io_pgtable_walk_common {
+	void (*visit_leaf)(phys_addr_t paddr, size_t size,
+			   struct io_pgtable_walk_common *data,
+			   void *wd);
+	void *data; /* pointer to walk data as arm_lpae_io_pgtable_walk_data*/
 };
 
 /**
@@ -199,7 +212,7 @@ struct arm_lpae_io_pgtable_walk_data {
  * @map_pages:    Map a physically contiguous range of pages of the same size.
  * @unmap_pages:  Unmap a range of virtually contiguous pages of the same size.
  * @iova_to_phys: Translate iova to physical address.
- * @pgtable_walk: (optional) Perform a page table walk for a given iova.
+ * @pgtable_walk: (optional) Perform a page table walk for a given iova and size.
  *
  * These functions map directly onto the iommu_ops member functions with
  * the same names.
@@ -213,7 +226,8 @@ struct io_pgtable_ops {
 			      struct iommu_iotlb_gather *gather);
 	phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops,
 				    unsigned long iova);
-	int (*pgtable_walk)(struct io_pgtable_ops *ops, unsigned long iova, void *wd);
+	int (*pgtable_walk)(struct io_pgtable_ops *ops, unsigned long iova,
+			    size_t size, struct io_pgtable_walk_common *walker);
 	int (*read_and_clear_dirty)(struct io_pgtable_ops *ops,
 				    unsigned long iova, size_t size,
 				    unsigned long flags,
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:02 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:02 +0000
Subject: [RFC PATCH v2 38/58] iommu/io-pgtable-arm: Add post table walker callback
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-39-smostafa@google.com>

Add a callback for postable, this would be used by pKVM to
cleanup tables next.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/io-pgtable-arm-common.c | 15 ++++++++++++++-
 include/linux/io-pgtable-arm.h        |  2 ++
 include/linux/io-pgtable.h            |  2 ++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/io-pgtable-arm-common.c b/drivers/iommu/io-pgtable-arm-common.c
index 4fc0b03494e3..076240eaec19 100644
--- a/drivers/iommu/io-pgtable-arm-common.c
+++ b/drivers/iommu/io-pgtable-arm-common.c
@@ -523,6 +523,13 @@ static int visit_pgtable_walk(struct io_pgtable_walk_data *walk_data, int lvl,
 	return 0;
 }
 
+static void visit_pgtable_post_table(struct arm_lpae_io_pgtable_walk_data *data,
+				     arm_lpae_iopte *ptep, int lvl)
+{
+	if (data->visit_post_table)
+		data->visit_post_table(data, ptep, lvl);
+}
+
 static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
 				 size_t size, struct io_pgtable_walk_common *walker)
 {
@@ -530,6 +537,7 @@ static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
 	struct io_pgtable_walk_data walk_data = {
 		.data = walker,
 		.visit = visit_pgtable_walk,
+		.visit_post_table = visit_pgtable_post_table,
 		.addr = iova,
 		.end = iova + size,
 	};
@@ -562,7 +570,12 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
 	}
 
 	ptep = iopte_deref(pte, data);
-	return __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);
+	ret = __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);
+
+	if (walk_data->visit_post_table)
+		walk_data->visit_post_table(data, ptep, lvl);
+
+	return ret;
 }
 
 static int __arm_lpae_iopte_walk(struct arm_lpae_io_pgtable *data,
diff --git a/include/linux/io-pgtable-arm.h b/include/linux/io-pgtable-arm.h
index 9e5878c37d78..c00eb0cb7e43 100644
--- a/include/linux/io-pgtable-arm.h
+++ b/include/linux/io-pgtable-arm.h
@@ -21,6 +21,8 @@ struct io_pgtable_walk_data {
 	struct io_pgtable_walk_common	*data;
 	int (*visit)(struct io_pgtable_walk_data *walk_data, int lvl,
 		     arm_lpae_iopte *ptep, size_t size);
+	void (*visit_post_table)(struct arm_lpae_io_pgtable_walk_data *data,
+				 arm_lpae_iopte *ptep, int lvl);
 	unsigned long			flags;
 	u64				addr;
 	const u64			end;
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index da50e17b0177..86226571cdb8 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -193,6 +193,8 @@ struct arm_lpae_io_pgtable_walk_data {
 	u64 ptes[4];
 	int level;
 	void *cookie;
+	void (*visit_post_table)(struct arm_lpae_io_pgtable_walk_data *data,
+				 arm_lpae_iopte *ptep, int lvl);
 };
 
 /**
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:03 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:03 +0000
Subject: [RFC PATCH v2 39/58] drivers/iommu: io-pgtable: Add IO_PGTABLE_QUIRK_UNMAP_INVAL
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-40-smostafa@google.com>

Only invalidate PTE without clearing it.

For io-pgtable-armm that also leaves the table allocated after an
unmap as they can't be freed.

This quirk also will allow the page table walker to traverse through
tables invalidated by an unmap, allowing the caller to doing any
booking keeping and freeing the table after.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/io-pgtable-arm-common.c | 50 +++++++++++++++++++--------
 include/linux/io-pgtable-arm.h        |  7 +++-
 include/linux/io-pgtable.h            |  5 ++-
 3 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-common.c b/drivers/iommu/io-pgtable-arm-common.c
index 076240eaec19..89be1aa72a6b 100644
--- a/drivers/iommu/io-pgtable-arm-common.c
+++ b/drivers/iommu/io-pgtable-arm-common.c
@@ -42,7 +42,10 @@ static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
 static void __arm_lpae_clear_pte(arm_lpae_iopte *ptep, struct io_pgtable_cfg *cfg, int num_entries)
 {
 	for (int i = 0; i < num_entries; i++)
-		ptep[i] = 0;
+		if (cfg->quirks & IO_PGTABLE_QUIRK_UNMAP_INVAL)
+			ptep[i] &= ~ARM_LPAE_PTE_VALID;
+		else
+			ptep[i] = 0;
 
 	if (!cfg->coherent_walk && num_entries)
 		__arm_lpae_sync_pte(ptep, num_entries, cfg);
@@ -170,7 +173,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
 
 	/* Grab a pointer to the next level */
 	pte = READ_ONCE(*ptep);
-	if (!pte) {
+	if (!iopte_valid(pte)) {
 		cptep = __arm_lpae_alloc_pages(tblsz, gfp, cfg, data->iop.cookie);
 		if (!cptep)
 			return -ENOMEM;
@@ -182,9 +185,9 @@ static 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 (iopte_valid(pte) && !iopte_leaf(pte, lvl, data->iop.fmt)) {
 		cptep = iopte_deref(pte, data);
-	} else if (pte) {
+	} else if (iopte_valid(pte)) {
 		/* We require an unmap first */
 		return arm_lpae_unmap_empty();
 	}
@@ -316,7 +319,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 (!iopte_valid(pte) || iopte_leaf(pte, lvl, data->iop.fmt))
 			continue;
 
 		__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
@@ -401,7 +404,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 	unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
 	ptep += unmap_idx_start;
 	pte = READ_ONCE(*ptep);
-	if (WARN_ON(!pte))
+	if (WARN_ON(!iopte_valid(pte)))
 		return 0;
 
 	/* If the size matches this level, we're in the right place */
@@ -412,7 +415,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 		/* Find and handle non-leaf entries */
 		for (i = 0; i < num_entries; i++) {
 			pte = READ_ONCE(ptep[i]);
-			if (WARN_ON(!pte))
+			if (WARN_ON(!iopte_valid(pte)))
 				break;
 
 			if (!iopte_leaf(pte, lvl, iop->fmt)) {
@@ -421,7 +424,9 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 				/* Also flush any partial walks */
 				io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
 							  ARM_LPAE_GRANULE(data));
-				__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
+				if (!(iop->cfg.quirks & IO_PGTABLE_QUIRK_UNMAP_INVAL))
+					__arm_lpae_free_pgtable(data, lvl + 1,
+								iopte_deref(pte, data));
 			}
 		}
 
@@ -523,9 +528,12 @@ static int visit_pgtable_walk(struct io_pgtable_walk_data *walk_data, int lvl,
 	return 0;
 }
 
-static void visit_pgtable_post_table(struct arm_lpae_io_pgtable_walk_data *data,
+static void visit_pgtable_post_table(struct io_pgtable_walk_data *walk_data,
 				     arm_lpae_iopte *ptep, int lvl)
 {
+	struct io_pgtable_walk_common *walker = walk_data->data;
+	struct arm_lpae_io_pgtable_walk_data *data = walker->data;
+
 	if (data->visit_post_table)
 		data->visit_post_table(data, ptep, lvl);
 }
@@ -550,30 +558,41 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
 			    arm_lpae_iopte *ptep, int lvl)
 {
 	struct io_pgtable *iop = &data->iop;
+	struct io_pgtable_cfg *cfg = &iop->cfg;
 	arm_lpae_iopte pte = READ_ONCE(*ptep);
 	struct io_pgtable_walk_common *walker = walk_data->data;
+	arm_lpae_iopte *old_ptep = ptep;
+	bool is_leaf, is_table;
 
 	size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
 	int ret = walk_data->visit(walk_data, lvl, ptep, size);
 	if (ret)
 		return ret;
 
-	if (iopte_leaf(pte, lvl, iop->fmt)) {
+	if (cfg->quirks & IO_PGTABLE_QUIRK_UNMAP_INVAL) {
+		/* Visitng invalid tables as it still have enteries. */
+		is_table = pte && iopte_table(pte | ARM_LPAE_PTE_VALID, lvl);
+		is_leaf = pte && iopte_leaf(pte | ARM_LPAE_PTE_VALID, lvl, iop->fmt);
+	} else {
+		is_table = iopte_table(pte, lvl);
+		is_leaf = iopte_leaf(pte, lvl, iop->fmt);
+	}
+
+	if (is_leaf) {
 		if (walker->visit_leaf)
 			walker->visit_leaf(iopte_to_paddr(pte, data), size, walker, ptep);
 		walk_data->addr += size;
 		return 0;
 	}
 
-	if (!iopte_table(pte, lvl)) {
+	if (!is_table)
 		return -EINVAL;
-	}
 
 	ptep = iopte_deref(pte, data);
 	ret = __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);
 
 	if (walk_data->visit_post_table)
-		walk_data->visit_post_table(data, ptep, lvl);
+		walk_data->visit_post_table(walk_data, old_ptep, lvl);
 
 	return ret;
 }
@@ -744,7 +763,8 @@ int arm_lpae_init_pgtable_s1(struct io_pgtable_cfg *cfg,
 	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
 			    IO_PGTABLE_QUIRK_ARM_TTBR1 |
 			    IO_PGTABLE_QUIRK_ARM_OUTER_WBWA |
-			    IO_PGTABLE_QUIRK_ARM_HD))
+			    IO_PGTABLE_QUIRK_ARM_HD |
+			    IO_PGTABLE_QUIRK_UNMAP_INVAL))
 		return -EINVAL;
 
 	ret = arm_lpae_init_pgtable(cfg, data);
@@ -830,7 +850,7 @@ int arm_lpae_init_pgtable_s2(struct io_pgtable_cfg *cfg,
 	typeof(&cfg->arm_lpae_s2_cfg.vtcr) vtcr = &cfg->arm_lpae_s2_cfg.vtcr;
 
 	/* The NS quirk doesn't apply at stage 2 */
-	if (cfg->quirks)
+	if (cfg->quirks & ~IO_PGTABLE_QUIRK_UNMAP_INVAL)
 		return -EINVAL;
 
 	ret = arm_lpae_init_pgtable(cfg, data);
diff --git a/include/linux/io-pgtable-arm.h b/include/linux/io-pgtable-arm.h
index c00eb0cb7e43..407f05fb300a 100644
--- a/include/linux/io-pgtable-arm.h
+++ b/include/linux/io-pgtable-arm.h
@@ -21,7 +21,7 @@ struct io_pgtable_walk_data {
 	struct io_pgtable_walk_common	*data;
 	int (*visit)(struct io_pgtable_walk_data *walk_data, int lvl,
 		     arm_lpae_iopte *ptep, size_t size);
-	void (*visit_post_table)(struct arm_lpae_io_pgtable_walk_data *data,
+	void (*visit_post_table)(struct io_pgtable_walk_data *walk_data,
 				 arm_lpae_iopte *ptep, int lvl);
 	unsigned long			flags;
 	u64				addr;
@@ -193,6 +193,11 @@ static inline bool iopte_table(arm_lpae_iopte pte, int lvl)
 	return iopte_type(pte) == ARM_LPAE_PTE_TYPE_TABLE;
 }
 
+static inline bool iopte_valid(arm_lpae_iopte pte)
+{
+	return pte & ARM_LPAE_PTE_VALID;
+}
+
 #ifdef __KVM_NVHE_HYPERVISOR__
 #include <nvhe/memory.h>
 #define __arm_lpae_virt_to_phys	hyp_virt_to_phys
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index 86226571cdb8..ce0aed9c87d2 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -89,6 +89,8 @@ struct io_pgtable_cfg {
 	 *	attributes set in the TCR for a non-coherent page-table walker.
 	 *
 	 * IO_PGTABLE_QUIRK_ARM_HD: Enables dirty tracking in stage 1 pagetable.
+	 *
+	 * IO_PGTABLE_QUIRK_UNMAP_INVAL: Only invalidate PTE on unmap, don't clear it.
 	 */
 	#define IO_PGTABLE_QUIRK_ARM_NS			BIT(0)
 	#define IO_PGTABLE_QUIRK_NO_PERMS		BIT(1)
@@ -97,6 +99,7 @@ struct io_pgtable_cfg {
 	#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)
+	#define IO_PGTABLE_QUIRK_UNMAP_INVAL		BIT(8)
 	unsigned long			quirks;
 	unsigned long			pgsize_bitmap;
 	unsigned int			ias;
@@ -194,7 +197,7 @@ struct arm_lpae_io_pgtable_walk_data {
 	int level;
 	void *cookie;
 	void (*visit_post_table)(struct arm_lpae_io_pgtable_walk_data *data,
-				 arm_lpae_iopte *ptep, int lvl);
+				 u64 *ptep, int lvl);
 };
 
 /**
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:04 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:04 +0000
Subject: [RFC PATCH v2 40/58] KVM: arm64: smmu-v3: Add map/unmap pages and iova_to_phys
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-41-smostafa@google.com>

Add map_pages and iova_to_phys HVC code, which
mainly calls the io-pgtable.

For unmap_pages, we rely on IO_PGTABLE_QUIRK_UNMAP_INVAL, where the
driver first calls unmap_pages which invalidate all the pages as
a typical unmap, issuing all the necessary TLB invalidations.
Then, we will start a page table with 2 callbacks:
- visit_leaf: for each unmapped leaf, it would decrement the refcount
  of the page using __pkvm_host_unuse_dma(), reversing the what IOMMU
  core does in map.
- visit_post_table: this would free any invalidated tables as they
  wouldn't be freed because of the quirk.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 147 ++++++++++++++++++++
 1 file changed, 147 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index ec3f8d9749d3..1821a3420a4d 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -808,15 +808,74 @@ static const struct iommu_flush_ops smmu_tlb_ops = {
 	.tlb_add_page	= smmu_tlb_add_page,
 };
 
+static void smmu_unmap_visit_leaf(phys_addr_t addr, size_t size,
+				  struct io_pgtable_walk_common *data,
+				  void *wd)
+{
+	u64 *ptep = wd;
+
+	WARN_ON(__pkvm_host_unuse_dma(addr, size));
+	*ptep = 0;
+}
+
+/*
+ * On unmap with the IO_PGTABLE_QUIRK_UNMAP_INVAL, unmap doesn't clear
+ * or free any tables, so after the unmap walk the table and on the post
+ * walk we free invalid tables.
+ * One caveat, is that a table can be unmapped while it points to other
+ * tables which would be valid, and we would need to free those also.
+ * The simples solution is to look at the walk PTE info and if any of
+ * the parents is invalid it means that this table also needs to freed.
+ */
+static void smmu_unmap_visit_post_table(struct arm_lpae_io_pgtable_walk_data *walk_data,
+					arm_lpae_iopte *ptep, int lvl)
+{
+	struct arm_lpae_io_pgtable *data = walk_data->cookie;
+	size_t table_size;
+	int i;
+	bool invalid = false;
+
+	if (lvl == data->start_level)
+		table_size = ARM_LPAE_PGD_SIZE(data);
+	else
+		table_size = ARM_LPAE_GRANULE(data);
+
+	for (i = 0 ; i <= lvl ; ++i)
+		invalid |= !iopte_valid(walk_data->ptes[lvl]);
+
+	if (!invalid)
+		return;
+
+	__arm_lpae_free_pages(ptep, table_size, &data->iop.cfg, data->iop.cookie);
+	*ptep = 0;
+}
+
 static void smmu_iotlb_sync(struct kvm_hyp_iommu_domain *domain,
 			    struct iommu_iotlb_gather *gather)
 {
 	size_t size;
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+	struct io_pgtable *pgtable = smmu_domain->pgtable;
+	struct arm_lpae_io_pgtable *data = io_pgtable_to_data(pgtable);
+	struct arm_lpae_io_pgtable_walk_data wd = {
+		.cookie = data,
+		.visit_post_table = smmu_unmap_visit_post_table,
+	};
+	struct io_pgtable_walk_common walk_data = {
+		.visit_leaf = smmu_unmap_visit_leaf,
+		.data = &wd,
+	};
 
 	if (!gather->pgsize)
 		return;
 	size = gather->end - gather->start + 1;
 	smmu_tlb_inv_range(domain, gather->start, size,  gather->pgsize, true);
+
+	/*
+	 * Now decrement the refcount of unmapped pages thanks to
+	 * IO_PGTABLE_QUIRK_UNMAP_INVAL
+	 */
+	pgtable->ops.pgtable_walk(&pgtable->ops, gather->start, size, &walk_data);
 }
 
 static int smmu_domain_config_s2(struct kvm_hyp_iommu_domain *domain,
@@ -966,6 +1025,7 @@ static int smmu_domain_finalise(struct hyp_arm_smmu_v3_device *smmu,
 			.oas = smmu->ias,
 			.coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENCY,
 			.tlb = &smmu_tlb_ops,
+			.quirks = IO_PGTABLE_QUIRK_UNMAP_INVAL,
 		};
 	} else {
 		cfg = (struct io_pgtable_cfg) {
@@ -975,6 +1035,7 @@ static int smmu_domain_finalise(struct hyp_arm_smmu_v3_device *smmu,
 			.oas = smmu->oas,
 			.coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENCY,
 			.tlb = &smmu_tlb_ops,
+			.quirks = IO_PGTABLE_QUIRK_UNMAP_INVAL,
 		};
 	}
 
@@ -1125,6 +1186,89 @@ static int smmu_detach_dev(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_dom
 	return ret;
 }
 
+static int smmu_map_pages(struct kvm_hyp_iommu_domain *domain, unsigned long iova,
+			  phys_addr_t paddr, size_t pgsize,
+			  size_t pgcount, int prot, size_t *total_mapped)
+{
+	size_t mapped;
+	size_t granule;
+	int ret;
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+	struct io_pgtable *pgtable = smmu_domain->pgtable;
+
+	if (!pgtable)
+		return -EINVAL;
+
+	granule = 1UL << __ffs(smmu_domain->pgtable->cfg.pgsize_bitmap);
+	if (!IS_ALIGNED(iova | paddr | pgsize, granule))
+		return -EINVAL;
+
+	hyp_spin_lock(&smmu_domain->pgt_lock);
+	while (pgcount && !ret) {
+		mapped = 0;
+		ret = pgtable->ops.map_pages(&pgtable->ops, iova, paddr,
+					     pgsize, pgcount, prot, 0, &mapped);
+		if (ret)
+			break;
+		WARN_ON(!IS_ALIGNED(mapped, pgsize));
+		WARN_ON(mapped > pgcount * pgsize);
+
+		pgcount -= mapped / pgsize;
+		*total_mapped += mapped;
+		iova += mapped;
+		paddr += mapped;
+	}
+	hyp_spin_unlock(&smmu_domain->pgt_lock);
+
+	return 0;
+}
+
+static size_t smmu_unmap_pages(struct kvm_hyp_iommu_domain *domain, unsigned long iova,
+			       size_t pgsize, size_t pgcount, struct iommu_iotlb_gather *gather)
+{
+	size_t granule, unmapped, total_unmapped = 0;
+	size_t size = pgsize * pgcount;
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+	struct io_pgtable *pgtable = smmu_domain->pgtable;
+
+	if (!pgtable)
+		return -EINVAL;
+
+	granule = 1UL << __ffs(smmu_domain->pgtable->cfg.pgsize_bitmap);
+	if (!IS_ALIGNED(iova | pgsize, granule))
+		return 0;
+
+	hyp_spin_lock(&smmu_domain->pgt_lock);
+	while (total_unmapped < size) {
+		unmapped = pgtable->ops.unmap_pages(&pgtable->ops, iova, pgsize,
+						    pgcount, gather);
+		if (!unmapped)
+			break;
+		iova += unmapped;
+		total_unmapped += unmapped;
+		pgcount -= unmapped / pgsize;
+	}
+	hyp_spin_unlock(&smmu_domain->pgt_lock);
+	return total_unmapped;
+}
+
+static phys_addr_t smmu_iova_to_phys(struct kvm_hyp_iommu_domain *domain,
+				     unsigned long iova)
+{
+	phys_addr_t paddr;
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+	struct io_pgtable *pgtable = smmu_domain->pgtable;
+
+	if (!pgtable)
+		return -EINVAL;
+
+	hyp_spin_lock(&smmu_domain->pgt_lock);
+	paddr = pgtable->ops.iova_to_phys(&pgtable->ops, iova);
+	hyp_spin_unlock(&smmu_domain->pgt_lock);
+
+	return paddr;
+}
+
 /* Shared with the kernel driver in EL1 */
 struct kvm_iommu_ops smmu_ops = {
 	.init				= smmu_init,
@@ -1134,4 +1278,7 @@ struct kvm_iommu_ops smmu_ops = {
 	.iotlb_sync			= smmu_iotlb_sync,
 	.attach_dev			= smmu_attach_dev,
 	.detach_dev			= smmu_detach_dev,
+	.map_pages			= smmu_map_pages,
+	.unmap_pages			= smmu_unmap_pages,
+	.iova_to_phys			= smmu_iova_to_phys,
 };
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:05 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:05 +0000
Subject: [RFC PATCH v2 41/58] KVM: arm64: smmu-v3: Add DABT handler
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-42-smostafa@google.com>

Add a data abort handler for the SMMUv3, we allow access for
ETVQ and GERROR for debug purpose.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 58 +++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index 1821a3420a4d..2a99873d980f 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -13,6 +13,7 @@
 #include <nvhe/mem_protect.h>
 #include <nvhe/mm.h>
 #include <nvhe/pkvm.h>
+#include <nvhe/trap_handler.h>
 
 #define ARM_SMMU_POLL_TIMEOUT_US	100000 /* 100ms arbitrary timeout */
 
@@ -1269,6 +1270,62 @@ static phys_addr_t smmu_iova_to_phys(struct kvm_hyp_iommu_domain *domain,
 	return paddr;
 }
 
+static bool smmu_dabt_device(struct hyp_arm_smmu_v3_device *smmu,
+			     struct kvm_cpu_context *host_ctxt,
+			     u64 esr, u32 off)
+{
+	bool is_write = esr & ESR_ELx_WNR;
+	unsigned int len = BIT((esr & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT);
+	int rd = (esr & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT;
+	const u32 no_access  = 0;
+	const u32 read_write = (u32)(-1);
+	const u32 read_only = is_write ? no_access : read_write;
+	u32 mask = no_access;
+
+	/*
+	 * Only handle MMIO access with u32 size and alignment.
+	 * We don't need to change 64-bit registers for now.
+	 */
+	if ((len != sizeof(u32)) || (off & (sizeof(u32) - 1)))
+		return false;
+
+	switch (off) {
+	case ARM_SMMU_EVTQ_PROD + SZ_64K:
+		mask = read_write;
+		break;
+	case ARM_SMMU_EVTQ_CONS + SZ_64K:
+		mask = read_write;
+		break;
+	case ARM_SMMU_GERROR:
+		mask = read_only;
+		break;
+	case ARM_SMMU_GERRORN:
+		mask = read_write;
+		break;
+	};
+
+	if (!mask)
+		return false;
+	if (is_write)
+		writel_relaxed(cpu_reg(host_ctxt, rd) & mask, smmu->base + off);
+	else
+		cpu_reg(host_ctxt, rd) = readl_relaxed(smmu->base + off);
+
+	return true;
+}
+
+static bool smmu_dabt_handler(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr)
+{
+	struct hyp_arm_smmu_v3_device *smmu;
+
+	for_each_smmu(smmu) {
+		if (addr < smmu->mmio_addr || addr >= smmu->mmio_addr + smmu->mmio_size)
+			continue;
+		return smmu_dabt_device(smmu, host_ctxt, esr, addr - smmu->mmio_addr);
+	}
+	return false;
+}
+
 /* Shared with the kernel driver in EL1 */
 struct kvm_iommu_ops smmu_ops = {
 	.init				= smmu_init,
@@ -1281,4 +1338,5 @@ struct kvm_iommu_ops smmu_ops = {
 	.map_pages			= smmu_map_pages,
 	.unmap_pages			= smmu_unmap_pages,
 	.iova_to_phys			= smmu_iova_to_phys,
+	.dabt_handler			= smmu_dabt_handler,
 };
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:06 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:06 +0000
Subject: [RFC PATCH v2 42/58] iommu/arm-smmu-v3-kvm: Add host driver for pKVM
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-43-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Under protected KVM (pKVM), the host does not have access to guest or
hypervisor memory. This means that devices owned by the host must be
isolated by the SMMU, and the hypervisor is in charge of the SMMU.

Introduce the host component that replaces the normal SMMUv3 driver when
pKVM is enabled, and sends configuration and requests to the actual
driver running in the hypervisor (EL2).

Rather than rely on regular driver probe, pKVM directly calls
kvm_arm_smmu_v3_init(), which synchronously finds all SMMUs and hands
them to the hypervisor. If the regular driver is enabled, it will not
find any free SMMU to drive once it gets probed.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/arm/arm-smmu-v3/Makefile        |  6 ++
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 64 +++++++++++++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c

diff --git a/drivers/iommu/arm/arm-smmu-v3/Makefile b/drivers/iommu/arm/arm-smmu-v3/Makefile
index 515a84f14783..7a182adbebc1 100644
--- a/drivers/iommu/arm/arm-smmu-v3/Makefile
+++ b/drivers/iommu/arm/arm-smmu-v3/Makefile
@@ -6,3 +6,9 @@ arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_SVA) += arm-smmu-v3-sva.o
 arm_smmu_v3-$(CONFIG_TEGRA241_CMDQV) += tegra241-cmdqv.o
 
 obj-$(CONFIG_ARM_SMMU_V3_KUNIT_TEST) += arm-smmu-v3-test.o
+
+obj-$(CONFIG_ARM_SMMU_V3_PKVM) += arm_smmu_v3_kvm.o
+ccflags-$(CONFIG_ARM_SMMU_V3_PKVM) += -Iarch/arm64/kvm/
+arm_smmu_v3_kvm-objs-y += arm-smmu-v3-kvm.o
+arm_smmu_v3_kvm-objs-y += arm-smmu-v3-common.o
+arm_smmu_v3_kvm-objs := $(arm_smmu_v3_kvm-objs-y)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
new file mode 100644
index 000000000000..8cea33d15e08
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pKVM host driver for the Arm SMMUv3
+ *
+ * Copyright (C) 2022 Linaro Ltd.
+ */
+#include <asm/kvm_mmu.h>
+
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include <kvm/arm_smmu_v3.h>
+
+#include "arm-smmu-v3.h"
+
+extern struct kvm_iommu_ops kvm_nvhe_sym(smmu_ops);
+
+static int kvm_arm_smmu_probe(struct platform_device *pdev)
+{
+	return -ENOSYS;
+}
+
+static void kvm_arm_smmu_remove(struct platform_device *pdev)
+{
+}
+
+static const struct of_device_id arm_smmu_of_match[] = {
+	{ .compatible = "arm,smmu-v3", },
+	{ },
+};
+
+static struct platform_driver kvm_arm_smmu_driver = {
+	.driver = {
+		.name = "kvm-arm-smmu-v3",
+		.of_match_table = arm_smmu_of_match,
+	},
+	.remove = kvm_arm_smmu_remove,
+};
+
+static int kvm_arm_smmu_v3_init_drv(void)
+{
+	return platform_driver_probe(&kvm_arm_smmu_driver, kvm_arm_smmu_probe);
+}
+
+static void kvm_arm_smmu_v3_remove_drv(void)
+{
+	platform_driver_unregister(&kvm_arm_smmu_driver);
+}
+
+struct kvm_iommu_driver kvm_smmu_v3_ops = {
+	.init_driver = kvm_arm_smmu_v3_init_drv,
+	.remove_driver = kvm_arm_smmu_v3_remove_drv,
+};
+
+static int kvm_arm_smmu_v3_register(void)
+{
+	if (!is_protected_kvm_enabled())
+		return 0;
+
+	return kvm_iommu_register_driver(&kvm_smmu_v3_ops,
+					kern_hyp_va(lm_alias(&kvm_nvhe_sym(smmu_ops))));
+};
+
+core_initcall(kvm_arm_smmu_v3_register);
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:07 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:07 +0000
Subject: [RFC PATCH v2 43/58] iommu/arm-smmu-v3-kvm: Pass a list of SMMU
 devices to the hypervisor
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-44-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Build a list of devices and donate the page to the hypervisor. At this
point the host is trusted and this would be a good opportunity to
provide more information about the system. For example, which devices
are owned by the host (perhaps via the VMID and SW bits in the stream
table, although we populate the stream table lazily at the moment.)

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 128 +++++++++++++++++-
 1 file changed, 126 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index 8cea33d15e08..e2d9bd97ddc5 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -15,9 +15,73 @@
 
 extern struct kvm_iommu_ops kvm_nvhe_sym(smmu_ops);
 
+struct host_arm_smmu_device {
+	struct arm_smmu_device		smmu;
+	pkvm_handle_t			id;
+};
+
+#define smmu_to_host(_smmu) \
+	container_of(_smmu, struct host_arm_smmu_device, smmu);
+
+static size_t				kvm_arm_smmu_cur;
+static size_t				kvm_arm_smmu_count;
+static struct hyp_arm_smmu_v3_device	*kvm_arm_smmu_array;
+
 static int kvm_arm_smmu_probe(struct platform_device *pdev)
 {
-	return -ENOSYS;
+	int ret;
+	size_t size;
+	phys_addr_t ioaddr;
+	struct resource *res;
+	struct arm_smmu_device *smmu;
+	struct device *dev = &pdev->dev;
+	struct host_arm_smmu_device *host_smmu;
+	struct hyp_arm_smmu_v3_device *hyp_smmu;
+
+	if (kvm_arm_smmu_cur >= kvm_arm_smmu_count)
+		return -ENOSPC;
+
+	hyp_smmu = &kvm_arm_smmu_array[kvm_arm_smmu_cur];
+
+	host_smmu = devm_kzalloc(dev, sizeof(*host_smmu), GFP_KERNEL);
+	if (!host_smmu)
+		return -ENOMEM;
+
+	smmu = &host_smmu->smmu;
+	smmu->dev = dev;
+
+	ret = arm_smmu_fw_probe(pdev, smmu);
+	if (ret)
+		return ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	size = resource_size(res);
+	if (size < SZ_128K) {
+		dev_err(dev, "unsupported MMIO region size (%pr)\n", res);
+		return -EINVAL;
+	}
+	ioaddr = res->start;
+	host_smmu->id = kvm_arm_smmu_cur;
+
+	smmu->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(smmu->base))
+		return PTR_ERR(smmu->base);
+
+	ret = arm_smmu_device_hw_probe(smmu);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, smmu);
+
+	/* Hypervisor parameters */
+	hyp_smmu->pgsize_bitmap = smmu->pgsize_bitmap;
+	hyp_smmu->oas = smmu->oas;
+	hyp_smmu->ias = smmu->ias;
+	hyp_smmu->mmio_addr = ioaddr;
+	hyp_smmu->mmio_size = size;
+	kvm_arm_smmu_cur++;
+
+	return arm_smmu_register_iommu(smmu, &kvm_arm_smmu_ops, ioaddr);
 }
 
 static void kvm_arm_smmu_remove(struct platform_device *pdev)
@@ -37,9 +101,69 @@ static struct platform_driver kvm_arm_smmu_driver = {
 	.remove = kvm_arm_smmu_remove,
 };
 
+static int kvm_arm_smmu_array_alloc(void)
+{
+	int smmu_order;
+	struct device_node *np;
+
+	kvm_arm_smmu_count = 0;
+	for_each_compatible_node(np, NULL, "arm,smmu-v3")
+		kvm_arm_smmu_count++;
+
+	if (!kvm_arm_smmu_count)
+		return 0;
+
+	/* Allocate the parameter list shared with the hypervisor */
+	smmu_order = get_order(kvm_arm_smmu_count * sizeof(*kvm_arm_smmu_array));
+	kvm_arm_smmu_array = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
+						      smmu_order);
+	if (!kvm_arm_smmu_array)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void kvm_arm_smmu_array_free(void)
+{
+	int order;
+
+	order = get_order(kvm_arm_smmu_count * sizeof(*kvm_arm_smmu_array));
+	free_pages((unsigned long)kvm_arm_smmu_array, order);
+}
+
 static int kvm_arm_smmu_v3_init_drv(void)
 {
-	return platform_driver_probe(&kvm_arm_smmu_driver, kvm_arm_smmu_probe);
+	int ret;
+
+	/*
+	 * Check whether any device owned by the host is behind an SMMU.
+	 */
+	ret = kvm_arm_smmu_array_alloc();
+	if (ret || !kvm_arm_smmu_count)
+		return ret;
+
+	ret = platform_driver_probe(&kvm_arm_smmu_driver, kvm_arm_smmu_probe);
+	if (ret)
+		goto err_free;
+
+	if (kvm_arm_smmu_cur != kvm_arm_smmu_count) {
+		/* A device exists but failed to probe */
+		ret = -EUNATCH;
+		goto err_free;
+	}
+
+	/*
+	 * These variables are stored in the nVHE image, and won't be accessible
+	 * after KVM initialization. Ownership of kvm_arm_smmu_array will be
+	 * transferred to the hypervisor as well.
+	 */
+	kvm_hyp_arm_smmu_v3_smmus = kvm_arm_smmu_array;
+	kvm_hyp_arm_smmu_v3_count = kvm_arm_smmu_count;
+	return 0;
+
+err_free:
+	kvm_arm_smmu_array_free();
+	return ret;
 }
 
 static void kvm_arm_smmu_v3_remove_drv(void)
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:08 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:08 +0000
Subject: [RFC PATCH v2 44/58] iommu/arm-smmu-v3-kvm: Validate device features
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-45-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

The KVM hypervisor driver supports a small subset of features. Ensure
the implementation is compatible, and disable some unused features.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index e2d9bd97ddc5..4b0c9ff6e7f1 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -27,6 +27,45 @@ static size_t				kvm_arm_smmu_cur;
 static size_t				kvm_arm_smmu_count;
 static struct hyp_arm_smmu_v3_device	*kvm_arm_smmu_array;
 
+static bool kvm_arm_smmu_validate_features(struct arm_smmu_device *smmu)
+{
+	unsigned int required_features =
+		ARM_SMMU_FEAT_TT_LE;
+	unsigned int forbidden_features =
+		ARM_SMMU_FEAT_STALL_FORCE;
+	unsigned int keep_features =
+		ARM_SMMU_FEAT_2_LVL_STRTAB	|
+		ARM_SMMU_FEAT_2_LVL_CDTAB	|
+		ARM_SMMU_FEAT_TT_LE		|
+		ARM_SMMU_FEAT_SEV		|
+		ARM_SMMU_FEAT_COHERENCY		|
+		ARM_SMMU_FEAT_TRANS_S1		|
+		ARM_SMMU_FEAT_TRANS_S2		|
+		ARM_SMMU_FEAT_VAX		|
+		ARM_SMMU_FEAT_RANGE_INV;
+
+	if (smmu->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY) {
+		dev_err(smmu->dev, "unsupported layout\n");
+		return false;
+	}
+
+	if ((smmu->features & required_features) != required_features) {
+		dev_err(smmu->dev, "missing features 0x%x\n",
+			required_features & ~smmu->features);
+		return false;
+	}
+
+	if (smmu->features & forbidden_features) {
+		dev_err(smmu->dev, "features 0x%x forbidden\n",
+			smmu->features & forbidden_features);
+		return false;
+	}
+
+	smmu->features &= keep_features;
+
+	return true;
+}
+
 static int kvm_arm_smmu_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -71,6 +110,9 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (!kvm_arm_smmu_validate_features(smmu))
+		return -ENODEV;
+
 	platform_set_drvdata(pdev, smmu);
 
 	/* Hypervisor parameters */
@@ -79,6 +121,7 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 	hyp_smmu->ias = smmu->ias;
 	hyp_smmu->mmio_addr = ioaddr;
 	hyp_smmu->mmio_size = size;
+	hyp_smmu->features = smmu->features;
 	kvm_arm_smmu_cur++;
 
 	return arm_smmu_register_iommu(smmu, &kvm_arm_smmu_ops, ioaddr);
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:09 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:09 +0000
Subject: [RFC PATCH v2 45/58] iommu/arm-smmu-v3-kvm: Allocate structures and
 reset device
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-46-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Allocate the structures that will be shared between hypervisor and SMMU:
command queue and stream table. Install them in the MMIO registers,
along with some configuration bits. After hyp initialization, the host
won't have access to those pages anymore.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 53 +++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index 4b0c9ff6e7f1..e4a5bdc830bc 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -18,6 +18,7 @@ extern struct kvm_iommu_ops kvm_nvhe_sym(smmu_ops);
 struct host_arm_smmu_device {
 	struct arm_smmu_device		smmu;
 	pkvm_handle_t			id;
+	u32				boot_gbpa;
 };
 
 #define smmu_to_host(_smmu) \
@@ -66,6 +67,35 @@ static bool kvm_arm_smmu_validate_features(struct arm_smmu_device *smmu)
 	return true;
 }
 
+static int kvm_arm_smmu_device_reset(struct host_arm_smmu_device *host_smmu)
+{
+	int ret;
+	u32 reg;
+	struct arm_smmu_device *smmu = &host_smmu->smmu;
+
+	reg = readl_relaxed(smmu->base + ARM_SMMU_CR0);
+	if (reg & CR0_SMMUEN)
+		dev_warn(smmu->dev, "SMMU currently enabled! Resetting...\n");
+
+	/* Disable bypass */
+	host_smmu->boot_gbpa = readl_relaxed(smmu->base + ARM_SMMU_GBPA);
+	ret = arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
+	if (ret)
+		return ret;
+
+	ret = arm_smmu_device_disable(smmu);
+	if (ret)
+		return ret;
+
+	/* Stream table */
+	arm_smmu_write_strtab(smmu);
+
+	/* Command queue */
+	writeq_relaxed(smmu->cmdq.q.q_base, smmu->base + ARM_SMMU_CMDQ_BASE);
+
+	return 0;
+}
+
 static int kvm_arm_smmu_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -113,6 +143,20 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 	if (!kvm_arm_smmu_validate_features(smmu))
 		return -ENODEV;
 
+	ret = arm_smmu_init_one_queue(smmu, &smmu->cmdq.q, smmu->base,
+				      ARM_SMMU_CMDQ_PROD, ARM_SMMU_CMDQ_CONS,
+				      CMDQ_ENT_DWORDS, "cmdq");
+	if (ret)
+		return ret;
+
+	ret = arm_smmu_init_strtab(smmu);
+	if (ret)
+		return ret;
+
+	ret = kvm_arm_smmu_device_reset(host_smmu);
+	if (ret)
+		return ret;
+
 	platform_set_drvdata(pdev, smmu);
 
 	/* Hypervisor parameters */
@@ -129,6 +173,15 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 
 static void kvm_arm_smmu_remove(struct platform_device *pdev)
 {
+	struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
+	struct host_arm_smmu_device *host_smmu = smmu_to_host(smmu);
+
+	/*
+	 * There was an error during hypervisor setup. The hyp driver may
+	 * have already enabled the device, so disable it.
+	 */
+	arm_smmu_device_disable(smmu);
+	arm_smmu_update_gbpa(smmu, host_smmu->boot_gbpa, GBPA_ABORT);
 }
 
 static const struct of_device_id arm_smmu_of_match[] = {
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:10 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:10 +0000
Subject: [RFC PATCH v2 46/58] KVM: arm64: Add function to topup generic allocator
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-47-smostafa@google.com>

Soon, IOMMU driver might need to topup the IOMMU pool from map_pages
IOMMU operation, which has a gfp flag is it might be called from
atomic context, add a function to topup an allocator with an ID
that also accepts gfp flags.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  4 ++++
 arch/arm64/kvm/mmu.c              | 20 ++++++++++++++++++++
 arch/arm64/kvm/pkvm.c             | 20 ++++++++++++++++++++
 3 files changed, 44 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a3b5d8dd8995..59a23828bd0e 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -155,6 +155,8 @@ static inline void __free_hyp_memcache(struct kvm_hyp_memcache *mc,
 
 void free_hyp_memcache(struct kvm_hyp_memcache *mc);
 int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages, unsigned long order);
+int topup_hyp_memcache_gfp(struct kvm_hyp_memcache *mc, unsigned long min_pages,
+			   unsigned long order, gfp_t gfp);
 
 static inline void init_hyp_memcache(struct kvm_hyp_memcache *mc)
 {
@@ -1628,6 +1630,8 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
 #define HYP_ALLOC_MGT_IOMMU_ID		1
 
 unsigned long __pkvm_reclaim_hyp_alloc_mgt(unsigned long nr_pages);
+int __pkvm_topup_hyp_alloc_mgt_gfp(unsigned long id, unsigned long nr_pages,
+				   unsigned long sz_alloc, gfp_t gfp);
 
 struct kvm_iommu_driver {
 	int (*init_driver)(void);
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index ef7e8c156afb..229338877c59 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1225,6 +1225,11 @@ static void *hyp_mc_alloc_fn(void *flags, unsigned long order)
 	return addr;
 }
 
+static void *hyp_mc_alloc_gfp_fn(void *flags, unsigned long order)
+{
+	return (void *)__get_free_pages(*(gfp_t *)flags, order);
+}
+
 void free_hyp_memcache(struct kvm_hyp_memcache *mc)
 {
 	unsigned long flags = mc->flags;
@@ -1249,6 +1254,21 @@ int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages,
 				    kvm_host_pa, (void *)flags, order);
 }
 
+int topup_hyp_memcache_gfp(struct kvm_hyp_memcache *mc, unsigned long min_pages,
+			   unsigned long order, gfp_t gfp)
+{
+	void *flags = &gfp;
+
+	if (!is_protected_kvm_enabled())
+		return 0;
+
+	if (order > PAGE_SHIFT)
+		return -E2BIG;
+
+	return __topup_hyp_memcache(mc, min_pages, hyp_mc_alloc_gfp_fn,
+				    kvm_host_pa, flags, order);
+}
+
 /**
  * kvm_phys_addr_ioremap - map a device range to guest IPA
  *
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index e6df35aae840..0c45acbbff6e 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -1114,3 +1114,23 @@ unsigned long __pkvm_reclaim_hyp_alloc_mgt(unsigned long nr_pages)
 
 	return reclaimed;
 }
+
+int __pkvm_topup_hyp_alloc_mgt_gfp(unsigned long id, unsigned long nr_pages,
+				   unsigned long sz_alloc, gfp_t gfp)
+{
+	struct kvm_hyp_memcache mc;
+	int ret;
+
+	init_hyp_memcache(&mc);
+
+	ret = topup_hyp_memcache_gfp(&mc, nr_pages, get_order(sz_alloc), gfp);
+	if (ret)
+		return ret;
+
+	ret = kvm_call_hyp_nvhe(__pkvm_hyp_alloc_mgt_refill, id,
+				mc.head, mc.nr_pages);
+	if (ret)
+		free_hyp_memcache(&mc);
+
+	return ret;
+}
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:11 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:11 +0000
Subject: [RFC PATCH v2 47/58] KVM: arm64: Add macro for SMCCC call with all returns
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-48-smostafa@google.com>

Add a macro that returns SMCCC returns from a hypercall.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/include/asm/kvm_host.h | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 59a23828bd0e..3cdc99ebdd0d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1248,7 +1248,18 @@ void kvm_arm_resume_guest(struct kvm *kvm);
 #define vcpu_has_run_once(vcpu)	!!rcu_access_pointer((vcpu)->pid)
 
 #ifndef __KVM_NVHE_HYPERVISOR__
-#define kvm_call_hyp_nvhe(f, ...)						\
+#define kvm_call_hyp_nvhe_smccc(f, ...)					\
+	({								\
+		struct arm_smccc_res res;				\
+									\
+		arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(f),		\
+				  ##__VA_ARGS__, &res);			\
+		WARN_ON(res.a0 != SMCCC_RET_SUCCESS);			\
+									\
+		res;							\
+	})
+
+#define kvm_call_hyp_nvhe(f, ...)					\
 	({								\
 		struct arm_smccc_res res;				\
 									\
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:12 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:12 +0000
Subject: [RFC PATCH v2 48/58] iommu/arm-smmu-v3-kvm: Add function to topup
 IOMMU allocator
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-49-smostafa@google.com>

The hypervisor returns requests for memory allocation in HVCs
encoded in the return registers.

Add a function that checks those returns and topup the IOMMU
alloctor in response to requests, and a macro that calls
this function around calling an HVC.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index e4a5bdc830bc..dab2d59b5a88 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2022 Linaro Ltd.
  */
+#include <asm/kvm_pkvm.h>
 #include <asm/kvm_mmu.h>
 
 #include <linux/of_platform.h>
@@ -28,6 +29,45 @@ static size_t				kvm_arm_smmu_cur;
 static size_t				kvm_arm_smmu_count;
 static struct hyp_arm_smmu_v3_device	*kvm_arm_smmu_array;
 
+static int kvm_arm_smmu_topup_memcache(struct arm_smccc_res *res, gfp_t gfp)
+{
+	struct kvm_hyp_req req;
+
+	hyp_reqs_smccc_decode(res, &req);
+
+	if ((res->a1 == -ENOMEM) && (req.type != KVM_HYP_REQ_TYPE_MEM)) {
+		/*
+		 * There is no way for drivers to populate hyp_alloc requests,
+		 * so -ENOMEM + no request indicates that.
+		 */
+		return __pkvm_topup_hyp_alloc(1);
+	} else if (req.type != KVM_HYP_REQ_TYPE_MEM) {
+		return -EBADE;
+	}
+
+	if (req.mem.dest == REQ_MEM_DEST_HYP_IOMMU) {
+		return __pkvm_topup_hyp_alloc_mgt_gfp(HYP_ALLOC_MGT_IOMMU_ID,
+						      req.mem.nr_pages,
+						      req.mem.sz_alloc,
+						      gfp);
+	} else if (req.mem.dest == REQ_MEM_DEST_HYP_ALLOC) {
+		/* Fill hyp alloc*/
+		return __pkvm_topup_hyp_alloc(req.mem.nr_pages);
+	}
+
+	pr_err("Bogus mem request");
+	return -EBADE;
+}
+
+#define kvm_call_hyp_nvhe_mc(...)					\
+({									\
+	struct arm_smccc_res __res;					\
+	do {								\
+		__res = kvm_call_hyp_nvhe_smccc(__VA_ARGS__);		\
+	} while (__res.a1 && !kvm_arm_smmu_topup_memcache(&__res, GFP_KERNEL));\
+	__res.a1;							\
+})
+
 static bool kvm_arm_smmu_validate_features(struct arm_smmu_device *smmu)
 {
 	unsigned int required_features =
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:13 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:13 +0000
Subject: [RFC PATCH v2 49/58] iommu/arm-smmu-v3-kvm: Add IOMMU ops
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-50-smostafa@google.com>

Add iommu_ops: attach_dev, release_device, probe_device, domain_alloc/
free, capable, and some other common ops with the kernel SMMUv3
driver: device_group, of_xlate, get_resv_regions.

Other ops as map/unmap and iova_to_phys added next.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 284 ++++++++++++++++++
 1 file changed, 284 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index dab2d59b5a88..071743f5acf9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -7,6 +7,7 @@
 #include <asm/kvm_pkvm.h>
 #include <asm/kvm_mmu.h>
 
+#include <linux/arm-smccc.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 
@@ -25,9 +26,26 @@ struct host_arm_smmu_device {
 #define smmu_to_host(_smmu) \
 	container_of(_smmu, struct host_arm_smmu_device, smmu);
 
+struct kvm_arm_smmu_master {
+	struct arm_smmu_device		*smmu;
+	struct device			*dev;
+	struct kvm_arm_smmu_domain      *domain;
+};
+
+struct kvm_arm_smmu_domain {
+	struct iommu_domain		domain;
+	struct arm_smmu_device		*smmu;
+	struct mutex			init_mutex;
+	pkvm_handle_t			id;
+};
+
+#define to_kvm_smmu_domain(_domain) \
+	container_of(_domain, struct kvm_arm_smmu_domain, domain)
+
 static size_t				kvm_arm_smmu_cur;
 static size_t				kvm_arm_smmu_count;
 static struct hyp_arm_smmu_v3_device	*kvm_arm_smmu_array;
+static DEFINE_IDA(kvm_arm_smmu_domain_ida);
 
 static int kvm_arm_smmu_topup_memcache(struct arm_smccc_res *res, gfp_t gfp)
 {
@@ -68,6 +86,267 @@ static int kvm_arm_smmu_topup_memcache(struct arm_smccc_res *res, gfp_t gfp)
 	__res.a1;							\
 })
 
+static struct platform_driver kvm_arm_smmu_driver;
+
+static struct arm_smmu_device *
+kvm_arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
+{
+	struct device *dev;
+
+	dev = driver_find_device_by_fwnode(&kvm_arm_smmu_driver.driver, fwnode);
+	put_device(dev);
+	return dev ? dev_get_drvdata(dev) : NULL;
+}
+
+static struct iommu_ops kvm_arm_smmu_ops;
+
+static struct iommu_device *kvm_arm_smmu_probe_device(struct device *dev)
+{
+	struct arm_smmu_device *smmu;
+	struct kvm_arm_smmu_master *master;
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+	if (WARN_ON_ONCE(dev_iommu_priv_get(dev)))
+		return ERR_PTR(-EBUSY);
+
+	smmu = kvm_arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
+	if (!smmu)
+		return ERR_PTR(-ENODEV);
+
+	master = kzalloc(sizeof(*master), GFP_KERNEL);
+	if (!master)
+		return ERR_PTR(-ENOMEM);
+
+	master->dev = dev;
+	master->smmu = smmu;
+	dev_iommu_priv_set(dev, master);
+
+	return &smmu->iommu;
+}
+
+static struct iommu_domain *kvm_arm_smmu_domain_alloc(unsigned type)
+{
+	struct kvm_arm_smmu_domain *kvm_smmu_domain;
+
+	/*
+	 * We don't support
+	 * - IOMMU_DOMAIN_DMA_FQ because lazy unmap would clash with memory
+	 *   donation to guests.
+	 * - IOMMU_DOMAIN_IDENTITY: Requires a stage-2 only transparent domain.
+	 */
+	if (type != IOMMU_DOMAIN_DMA &&
+	    type != IOMMU_DOMAIN_UNMANAGED)
+		return ERR_PTR(-EOPNOTSUPP);
+
+	kvm_smmu_domain = kzalloc(sizeof(*kvm_smmu_domain), GFP_KERNEL);
+	if (!kvm_smmu_domain)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&kvm_smmu_domain->init_mutex);
+
+	return &kvm_smmu_domain->domain;
+}
+
+static int kvm_arm_smmu_domain_finalize(struct kvm_arm_smmu_domain *kvm_smmu_domain,
+					struct kvm_arm_smmu_master *master)
+{
+	int ret = 0;
+	struct arm_smmu_device *smmu = master->smmu;
+	unsigned int max_domains;
+	enum kvm_arm_smmu_domain_type type;
+	struct io_pgtable_cfg cfg;
+	unsigned long ias;
+
+	if (kvm_smmu_domain->smmu && (kvm_smmu_domain->smmu != smmu))
+		return -EINVAL;
+
+	if (kvm_smmu_domain->smmu)
+		return 0;
+	/* Default to stage-1. */
+	if (smmu->features & ARM_SMMU_FEAT_TRANS_S1) {
+		ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
+		cfg = (struct io_pgtable_cfg) {
+			.fmt = ARM_64_LPAE_S1,
+			.pgsize_bitmap = smmu->pgsize_bitmap,
+			.ias = min_t(unsigned long, ias, VA_BITS),
+			.oas = smmu->ias,
+			.coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENCY,
+		};
+		ret = io_pgtable_configure(&cfg);
+		if (ret)
+			return ret;
+
+		type = KVM_ARM_SMMU_DOMAIN_S1;
+		kvm_smmu_domain->domain.pgsize_bitmap = cfg.pgsize_bitmap;
+		kvm_smmu_domain->domain.geometry.aperture_end = (1UL << cfg.ias) - 1;
+		max_domains = 1 << smmu->asid_bits;
+	} else {
+		cfg = (struct io_pgtable_cfg) {
+			.fmt = ARM_64_LPAE_S2,
+			.pgsize_bitmap = smmu->pgsize_bitmap,
+			.ias = smmu->ias,
+			.oas = smmu->oas,
+			.coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENCY,
+		};
+		ret = io_pgtable_configure(&cfg);
+		if (ret)
+			return ret;
+
+		type = KVM_ARM_SMMU_DOMAIN_S2;
+		kvm_smmu_domain->domain.pgsize_bitmap = cfg.pgsize_bitmap;
+		kvm_smmu_domain->domain.geometry.aperture_end = (1UL << cfg.ias) - 1;
+		max_domains = 1 << smmu->vmid_bits;
+	}
+	kvm_smmu_domain->domain.geometry.force_aperture = true;
+
+	/*
+	 * The hypervisor uses the domain_id for asid/vmid so it has to be
+	 * unique, and it has to be in range of this smmu, which can be
+	 * either 8 or 16 bits.
+	 */
+	ret = ida_alloc_range(&kvm_arm_smmu_domain_ida, 0,
+			      min(KVM_IOMMU_MAX_DOMAINS, max_domains), GFP_KERNEL);
+	if (ret < 0)
+		return ret;
+
+	kvm_smmu_domain->id = ret;
+
+	ret = kvm_call_hyp_nvhe_mc(__pkvm_host_iommu_alloc_domain,
+				   kvm_smmu_domain->id, type);
+	if (ret) {
+		ida_free(&kvm_arm_smmu_domain_ida, kvm_smmu_domain->id);
+		return ret;
+	}
+
+	kvm_smmu_domain->smmu = smmu;
+	return 0;
+}
+
+static void kvm_arm_smmu_domain_free(struct iommu_domain *domain)
+{
+	int ret;
+	struct kvm_arm_smmu_domain *kvm_smmu_domain = to_kvm_smmu_domain(domain);
+	struct arm_smmu_device *smmu = kvm_smmu_domain->smmu;
+
+	if (smmu) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_iommu_free_domain, kvm_smmu_domain->id);
+		ida_free(&kvm_arm_smmu_domain_ida, kvm_smmu_domain->id);
+	}
+	kfree(kvm_smmu_domain);
+}
+
+static int kvm_arm_smmu_detach_dev(struct host_arm_smmu_device *host_smmu,
+				   struct kvm_arm_smmu_master *master)
+{
+	int i, ret;
+	struct arm_smmu_device *smmu = &host_smmu->smmu;
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
+	struct kvm_arm_smmu_domain *domain = master->domain;
+
+	if (!domain)
+		return 0;
+
+	for (i = 0; i < fwspec->num_ids; i++) {
+		int sid = fwspec->ids[i];
+
+		ret = kvm_call_hyp_nvhe(__pkvm_host_iommu_detach_dev,
+					host_smmu->id, domain->id, sid, 0);
+		if (ret) {
+			dev_err(smmu->dev, "cannot detach device %s (0x%x): %d\n",
+				dev_name(master->dev), sid, ret);
+			break;
+		}
+	}
+
+	master->domain = NULL;
+
+	return ret;
+}
+
+static void kvm_arm_smmu_release_device(struct device *dev)
+{
+	struct kvm_arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct host_arm_smmu_device *host_smmu = smmu_to_host(master->smmu);
+
+	kvm_arm_smmu_detach_dev(host_smmu, master);
+	kfree(master);
+	iommu_fwspec_free(dev);
+}
+
+static int kvm_arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
+{
+	int i, ret;
+	struct arm_smmu_device *smmu;
+	struct host_arm_smmu_device *host_smmu;
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct kvm_arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct kvm_arm_smmu_domain *kvm_smmu_domain = to_kvm_smmu_domain(domain);
+
+	if (!master)
+		return -ENODEV;
+
+	smmu = master->smmu;
+	host_smmu = smmu_to_host(smmu);
+
+	ret = kvm_arm_smmu_detach_dev(host_smmu, master);
+	if (ret)
+		return ret;
+
+	mutex_lock(&kvm_smmu_domain->init_mutex);
+	ret = kvm_arm_smmu_domain_finalize(kvm_smmu_domain, master);
+	mutex_unlock(&kvm_smmu_domain->init_mutex);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < fwspec->num_ids; i++) {
+		int sid = fwspec->ids[i];
+
+		ret = kvm_call_hyp_nvhe_mc(__pkvm_host_iommu_attach_dev,
+					   host_smmu->id, kvm_smmu_domain->id,
+					   sid, 0, 0);
+		if (ret) {
+			dev_err(smmu->dev, "cannot attach device %s (0x%x): %d\n",
+				dev_name(dev), sid, ret);
+			goto out_ret;
+		}
+	}
+	master->domain = kvm_smmu_domain;
+
+out_ret:
+	if (ret)
+		kvm_arm_smmu_detach_dev(host_smmu, master);
+	return ret;
+}
+
+static bool kvm_arm_smmu_capable(struct device *dev, enum iommu_cap cap)
+{
+	struct kvm_arm_smmu_master *master = dev_iommu_priv_get(dev);
+
+	switch (cap) {
+	case IOMMU_CAP_CACHE_COHERENCY:
+		return master->smmu->features & ARM_SMMU_FEAT_COHERENCY;
+	case IOMMU_CAP_NOEXEC:
+	default:
+		return false;
+	}
+}
+
+static struct iommu_ops kvm_arm_smmu_ops = {
+	.capable		= kvm_arm_smmu_capable,
+	.device_group		= arm_smmu_device_group,
+	.of_xlate		= arm_smmu_of_xlate,
+	.get_resv_regions	= arm_smmu_get_resv_regions,
+	.probe_device		= kvm_arm_smmu_probe_device,
+	.release_device		= kvm_arm_smmu_release_device,
+	.domain_alloc		= kvm_arm_smmu_domain_alloc,
+	.pgsize_bitmap		= -1UL,
+	.owner			= THIS_MODULE,
+	.default_domain_ops = &(const struct iommu_domain_ops) {
+		.attach_dev	= kvm_arm_smmu_attach_dev,
+		.free		= kvm_arm_smmu_domain_free,
+	}
+};
+
 static bool kvm_arm_smmu_validate_features(struct arm_smmu_device *smmu)
 {
 	unsigned int required_features =
@@ -183,6 +462,11 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 	if (!kvm_arm_smmu_validate_features(smmu))
 		return -ENODEV;
 
+	if (kvm_arm_smmu_ops.pgsize_bitmap == -1UL)
+		kvm_arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap;
+	else
+		kvm_arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap;
+
 	ret = arm_smmu_init_one_queue(smmu, &smmu->cmdq.q, smmu->base,
 				      ARM_SMMU_CMDQ_PROD, ARM_SMMU_CMDQ_CONS,
 				      CMDQ_ENT_DWORDS, "cmdq");
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:14 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:14 +0000
Subject: [RFC PATCH v2 50/58] iommu/arm-smmu-v3-kvm: Add map, unmap and
 iova_to_phys operations
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-51-smostafa@google.com>

Add map, unmap and iova_to_phys, which are forwarded to the
hypervisor.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 72 +++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index 071743f5acf9..82f0191b222c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -331,6 +331,75 @@ static bool kvm_arm_smmu_capable(struct device *dev, enum iommu_cap cap)
 	}
 }
 
+static int kvm_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 *total_mapped)
+{
+	size_t mapped;
+	size_t size = pgsize * pgcount;
+	struct kvm_arm_smmu_domain *kvm_smmu_domain = to_kvm_smmu_domain(domain);
+	struct arm_smccc_res res;
+
+	do {
+		res = kvm_call_hyp_nvhe_smccc(__pkvm_host_iommu_map_pages,
+					      kvm_smmu_domain->id,
+					      iova, paddr, pgsize, pgcount, prot);
+		mapped = res.a1;
+		iova += mapped;
+		paddr += mapped;
+		WARN_ON(mapped % pgsize);
+		WARN_ON(mapped > pgcount * pgsize);
+		pgcount -= mapped / pgsize;
+		*total_mapped += mapped;
+	} while (*total_mapped < size && !kvm_arm_smmu_topup_memcache(&res, gfp));
+	if (*total_mapped < size)
+		return -EINVAL;
+
+	return 0;
+}
+
+static size_t kvm_arm_smmu_unmap_pages(struct iommu_domain *domain,
+				       unsigned long iova, size_t pgsize,
+				       size_t pgcount,
+				       struct iommu_iotlb_gather *iotlb_gather)
+{
+	size_t unmapped;
+	size_t total_unmapped = 0;
+	size_t size = pgsize * pgcount;
+	struct kvm_arm_smmu_domain *kvm_smmu_domain = to_kvm_smmu_domain(domain);
+	struct arm_smccc_res res;
+
+	do {
+		res = kvm_call_hyp_nvhe_smccc(__pkvm_host_iommu_unmap_pages,
+					      kvm_smmu_domain->id,
+					      iova, pgsize, pgcount);
+		unmapped = res.a1;
+		total_unmapped += unmapped;
+		iova += unmapped;
+		WARN_ON(unmapped % pgsize);
+		pgcount -= unmapped / pgsize;
+
+		/*
+		 * The page table driver can unmap less than we asked for. If it
+		 * didn't unmap anything at all, then it either reached the end
+		 * of the range, or it needs a page in the memcache to break a
+		 * block mapping.
+		 */
+	} while (total_unmapped < size &&
+		 (unmapped || !kvm_arm_smmu_topup_memcache(&res, GFP_ATOMIC)));
+
+	return total_unmapped;
+}
+
+static phys_addr_t kvm_arm_smmu_iova_to_phys(struct iommu_domain *domain,
+					     dma_addr_t iova)
+{
+	struct kvm_arm_smmu_domain *kvm_smmu_domain = to_kvm_smmu_domain(domain);
+
+	return kvm_call_hyp_nvhe(__pkvm_host_iommu_iova_to_phys, kvm_smmu_domain->id, iova);
+}
+
 static struct iommu_ops kvm_arm_smmu_ops = {
 	.capable		= kvm_arm_smmu_capable,
 	.device_group		= arm_smmu_device_group,
@@ -344,6 +413,9 @@ static struct iommu_ops kvm_arm_smmu_ops = {
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= kvm_arm_smmu_attach_dev,
 		.free		= kvm_arm_smmu_domain_free,
+		.map_pages	= kvm_arm_smmu_map_pages,
+		.unmap_pages	= kvm_arm_smmu_unmap_pages,
+		.iova_to_phys	= kvm_arm_smmu_iova_to_phys,
 	}
 };
 
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:15 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:15 +0000
Subject: [RFC PATCH v2 51/58] iommu/arm-smmu-v3-kvm: Support PASID operations
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-52-smostafa@google.com>

Add support for set_dev_pasid and remove_dev_pasid, the hypervisor
already supports pasid, so we just need to forward it in the
hypercalls in addition to proper tracking of domains per master.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 58 +++++++++++++++----
 1 file changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index 82f0191b222c..cbcd8a75d562 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -29,7 +29,8 @@ struct host_arm_smmu_device {
 struct kvm_arm_smmu_master {
 	struct arm_smmu_device		*smmu;
 	struct device			*dev;
-	struct kvm_arm_smmu_domain      *domain;
+	struct xarray			domains;
+	u32				ssid_bits;
 };
 
 struct kvm_arm_smmu_domain {
@@ -119,6 +120,10 @@ static struct iommu_device *kvm_arm_smmu_probe_device(struct device *dev)
 
 	master->dev = dev;
 	master->smmu = smmu;
+
+	device_property_read_u32(dev, "pasid-num-bits", &master->ssid_bits);
+	master->ssid_bits = min(smmu->ssid_bits, master->ssid_bits);
+	xa_init(&master->domains);
 	dev_iommu_priv_set(dev, master);
 
 	return &smmu->iommu;
@@ -235,13 +240,14 @@ static void kvm_arm_smmu_domain_free(struct iommu_domain *domain)
 	kfree(kvm_smmu_domain);
 }
 
-static int kvm_arm_smmu_detach_dev(struct host_arm_smmu_device *host_smmu,
-				   struct kvm_arm_smmu_master *master)
+static int kvm_arm_smmu_detach_dev_pasid(struct host_arm_smmu_device *host_smmu,
+					 struct kvm_arm_smmu_master *master,
+					 ioasid_t pasid)
 {
 	int i, ret;
 	struct arm_smmu_device *smmu = &host_smmu->smmu;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
-	struct kvm_arm_smmu_domain *domain = master->domain;
+	struct kvm_arm_smmu_domain *domain = xa_load(&master->domains, pasid);
 
 	if (!domain)
 		return 0;
@@ -250,7 +256,7 @@ static int kvm_arm_smmu_detach_dev(struct host_arm_smmu_device *host_smmu,
 		int sid = fwspec->ids[i];
 
 		ret = kvm_call_hyp_nvhe(__pkvm_host_iommu_detach_dev,
-					host_smmu->id, domain->id, sid, 0);
+					host_smmu->id, domain->id, sid, pasid);
 		if (ret) {
 			dev_err(smmu->dev, "cannot detach device %s (0x%x): %d\n",
 				dev_name(master->dev), sid, ret);
@@ -258,22 +264,39 @@ static int kvm_arm_smmu_detach_dev(struct host_arm_smmu_device *host_smmu,
 		}
 	}
 
-	master->domain = NULL;
+	xa_erase(&master->domains, pasid);
 
 	return ret;
 }
 
+static int kvm_arm_smmu_detach_dev(struct host_arm_smmu_device *host_smmu,
+				   struct kvm_arm_smmu_master *master)
+{
+	return kvm_arm_smmu_detach_dev_pasid(host_smmu, master, 0);
+}
+
+static void kvm_arm_smmu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
+					  struct iommu_domain *domain)
+{
+	struct kvm_arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct host_arm_smmu_device *host_smmu = smmu_to_host(master->smmu);
+
+	kvm_arm_smmu_detach_dev_pasid(host_smmu, master, pasid);
+}
+
 static void kvm_arm_smmu_release_device(struct device *dev)
 {
 	struct kvm_arm_smmu_master *master = dev_iommu_priv_get(dev);
 	struct host_arm_smmu_device *host_smmu = smmu_to_host(master->smmu);
 
 	kvm_arm_smmu_detach_dev(host_smmu, master);
+	xa_destroy(&master->domains);
 	kfree(master);
 	iommu_fwspec_free(dev);
 }
 
-static int kvm_arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
+static int kvm_arm_smmu_set_dev_pasid(struct iommu_domain *domain,
+				      struct device *dev, ioasid_t pasid)
 {
 	int i, ret;
 	struct arm_smmu_device *smmu;
@@ -288,7 +311,7 @@ static int kvm_arm_smmu_attach_dev(struct iommu_domain *domain, struct device *d
 	smmu = master->smmu;
 	host_smmu = smmu_to_host(smmu);
 
-	ret = kvm_arm_smmu_detach_dev(host_smmu, master);
+	ret = kvm_arm_smmu_detach_dev_pasid(host_smmu, master, pasid);
 	if (ret)
 		return ret;
 
@@ -303,14 +326,14 @@ static int kvm_arm_smmu_attach_dev(struct iommu_domain *domain, struct device *d
 
 		ret = kvm_call_hyp_nvhe_mc(__pkvm_host_iommu_attach_dev,
 					   host_smmu->id, kvm_smmu_domain->id,
-					   sid, 0, 0);
+					   sid, pasid, master->ssid_bits);
 		if (ret) {
 			dev_err(smmu->dev, "cannot attach device %s (0x%x): %d\n",
 				dev_name(dev), sid, ret);
 			goto out_ret;
 		}
 	}
-	master->domain = kvm_smmu_domain;
+	ret = xa_insert(&master->domains, pasid, kvm_smmu_domain, GFP_KERNEL);
 
 out_ret:
 	if (ret)
@@ -318,6 +341,19 @@ static int kvm_arm_smmu_attach_dev(struct iommu_domain *domain, struct device *d
 	return ret;
 }
 
+static int kvm_arm_smmu_attach_dev(struct iommu_domain *domain,
+				   struct device *dev)
+{
+	struct kvm_arm_smmu_master *master = dev_iommu_priv_get(dev);
+	unsigned long pasid = 0;
+
+	/* All pasids must be removed first. */
+	if (xa_find_after(&master->domains, &pasid, ULONG_MAX, XA_PRESENT))
+		return -EBUSY;
+
+	return kvm_arm_smmu_set_dev_pasid(domain, dev, 0);
+}
+
 static bool kvm_arm_smmu_capable(struct device *dev, enum iommu_cap cap)
 {
 	struct kvm_arm_smmu_master *master = dev_iommu_priv_get(dev);
@@ -409,6 +445,7 @@ static struct iommu_ops kvm_arm_smmu_ops = {
 	.release_device		= kvm_arm_smmu_release_device,
 	.domain_alloc		= kvm_arm_smmu_domain_alloc,
 	.pgsize_bitmap		= -1UL,
+	.remove_dev_pasid	= kvm_arm_smmu_remove_dev_pasid,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= kvm_arm_smmu_attach_dev,
@@ -416,6 +453,7 @@ static struct iommu_ops kvm_arm_smmu_ops = {
 		.map_pages	= kvm_arm_smmu_map_pages,
 		.unmap_pages	= kvm_arm_smmu_unmap_pages,
 		.iova_to_phys	= kvm_arm_smmu_iova_to_phys,
+		.set_dev_pasid	= kvm_arm_smmu_set_dev_pasid,
 	}
 };
 
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:16 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:16 +0000
Subject: [RFC PATCH v2 52/58] iommu/arm-smmu-v3-kvm: Add IRQs for the driver
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-53-smostafa@google.com>

Handle IRQs from the KVM kernel driver, it should be safe to do it
from the kernel as this a debug feature.

Only GERROR and EVTQ irqs are handled.
Unlike the kernel driver, we don't do much here (no rest in SMMU or
interaction of cmdq) but just printing.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c   |   3 +-
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 138 ++++++++++++++++++
 2 files changed, 139 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index 2a99873d980f..60f0760f49eb 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -365,7 +365,6 @@ static int smmu_init_registers(struct hyp_arm_smmu_v3_device *smmu)
 	      FIELD_PREP(CR1_QUEUE_IC, CR1_CACHE_WB);
 	writel_relaxed(val, smmu->base + ARM_SMMU_CR1);
 	writel_relaxed(CR2_PTM, smmu->base + ARM_SMMU_CR2);
-	writel_relaxed(0, smmu->base + ARM_SMMU_IRQ_CTRL);
 
 	val = readl_relaxed(smmu->base + ARM_SMMU_GERROR);
 	old = readl_relaxed(smmu->base + ARM_SMMU_GERRORN);
@@ -540,7 +539,7 @@ static int smmu_reset_device(struct hyp_arm_smmu_v3_device *smmu)
 		goto err_disable_cmdq;
 
 	/* Enable translation */
-	return smmu_write_cr0(smmu, CR0_SMMUEN | CR0_CMDQEN | CR0_ATSCHK);
+	return smmu_write_cr0(smmu, CR0_SMMUEN | CR0_CMDQEN | CR0_ATSCHK | CR0_EVTQEN);
 
 err_disable_cmdq:
 	return smmu_write_cr0(smmu, 0);
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index cbcd8a75d562..674ce2b02a4b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -496,11 +496,107 @@ static bool kvm_arm_smmu_validate_features(struct arm_smmu_device *smmu)
 	return true;
 }
 
+static irqreturn_t kvm_arm_smmu_evt_handler(int irq, void *dev)
+{
+	int i;
+	struct arm_smmu_device *smmu = dev;
+	struct arm_smmu_queue *q = &smmu->evtq.q;
+	struct arm_smmu_ll_queue *llq = &q->llq;
+	static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
+				      DEFAULT_RATELIMIT_BURST);
+	u64 evt[EVTQ_ENT_DWORDS];
+
+	do {
+		while (!queue_remove_raw(q, evt)) {
+			u8 id = FIELD_GET(EVTQ_0_ID, evt[0]);
+
+			if (!__ratelimit(&rs))
+				continue;
+
+			dev_info(smmu->dev, "event 0x%02x received:\n", id);
+			for (i = 0; i < ARRAY_SIZE(evt); ++i)
+				dev_info(smmu->dev, "\t0x%016llx\n",
+					 (unsigned long long)evt[i]);
+
+			cond_resched();
+		}
+
+		/*
+		 * Not much we can do on overflow, so scream and pretend we're
+		 * trying harder.
+		 */
+		if (queue_sync_prod_in(q) == -EOVERFLOW)
+			dev_err(smmu->dev, "EVTQ overflow detected -- events lost\n");
+	} while (!queue_empty(llq));
+
+	/* Sync our overflow flag, as we believe we're up to speed */
+	queue_sync_cons_ovf(q);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t kvm_arm_smmu_gerror_handler(int irq, void *dev)
+{
+	u32 gerror, gerrorn, active;
+	struct arm_smmu_device *smmu = dev;
+
+	gerror = readl_relaxed(smmu->base + ARM_SMMU_GERROR);
+	gerrorn = readl_relaxed(smmu->base + ARM_SMMU_GERRORN);
+
+	active = gerror ^ gerrorn;
+	if (!(active & GERROR_ERR_MASK))
+		return IRQ_NONE; /* No errors pending */
+
+	dev_warn(smmu->dev,
+		 "unexpected global error reported (0x%08x), this could be serious\n",
+		 active);
+
+	/* There is no API to reconfigure the device at the moment.*/
+	if (active & GERROR_SFM_ERR)
+		dev_err(smmu->dev, "device has entered Service Failure Mode!\n");
+
+	if (active & GERROR_MSI_GERROR_ABT_ERR)
+		dev_warn(smmu->dev, "GERROR MSI write aborted\n");
+
+	if (active & GERROR_MSI_PRIQ_ABT_ERR)
+		dev_warn(smmu->dev, "PRIQ MSI write aborted\n");
+
+	if (active & GERROR_MSI_EVTQ_ABT_ERR)
+		dev_warn(smmu->dev, "EVTQ MSI write aborted\n");
+
+	if (active & GERROR_MSI_CMDQ_ABT_ERR)
+		dev_warn(smmu->dev, "CMDQ MSI write aborted\n");
+
+	if (active & GERROR_PRIQ_ABT_ERR)
+		dev_err(smmu->dev, "PRIQ write aborted -- events may have been lost\n");
+
+	if (active & GERROR_EVTQ_ABT_ERR)
+		dev_err(smmu->dev, "EVTQ write aborted -- events may have been lost\n");
+
+	if (active & GERROR_CMDQ_ERR) {
+		dev_err(smmu->dev, "CMDQ ERR -- Hypervisor cmdq corrupted?\n");
+		BUG();
+	}
+
+	writel(gerror, smmu->base + ARM_SMMU_GERRORN);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t kvm_arm_smmu_pri_handler(int irq, void *dev)
+{
+	struct arm_smmu_device *smmu = dev;
+
+	dev_err(smmu->dev, "PRI not supported in KVM driver!\n");
+
+	return IRQ_HANDLED;
+}
+
 static int kvm_arm_smmu_device_reset(struct host_arm_smmu_device *host_smmu)
 {
 	int ret;
 	u32 reg;
 	struct arm_smmu_device *smmu = &host_smmu->smmu;
+	u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN;
 
 	reg = readl_relaxed(smmu->base + ARM_SMMU_CR0);
 	if (reg & CR0_SMMUEN)
@@ -522,6 +618,39 @@ static int kvm_arm_smmu_device_reset(struct host_arm_smmu_device *host_smmu)
 	/* Command queue */
 	writeq_relaxed(smmu->cmdq.q.q_base, smmu->base + ARM_SMMU_CMDQ_BASE);
 
+	/* Event queue */
+	writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE);
+	writel_relaxed(smmu->evtq.q.llq.prod, smmu->base + SZ_64K + ARM_SMMU_EVTQ_PROD);
+	writel_relaxed(smmu->evtq.q.llq.cons, smmu->base + SZ_64K + ARM_SMMU_EVTQ_CONS);
+
+	/* Disable IRQs first */
+	ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL,
+				      ARM_SMMU_IRQ_CTRLACK);
+	if (ret) {
+		dev_err(smmu->dev, "failed to disable irqs\n");
+		return ret;
+	}
+
+	/*
+	 * We don't support combined irqs for now, no specific reason, they are uncommon
+	 * so we just try to avoid bloating the code.
+	 */
+	if (smmu->combined_irq)
+		dev_err(smmu->dev, "Combined irqs not supported by this driver\n");
+	else
+		arm_smmu_setup_unique_irqs(smmu, kvm_arm_smmu_evt_handler,
+					   kvm_arm_smmu_gerror_handler,
+					   kvm_arm_smmu_pri_handler);
+
+	if (smmu->features & ARM_SMMU_FEAT_PRI)
+		irqen_flags |= IRQ_CTRL_PRIQ_IRQEN;
+
+	/* Enable interrupt generation on the SMMU */
+	ret = arm_smmu_write_reg_sync(smmu, irqen_flags,
+				      ARM_SMMU_IRQ_CTRL, ARM_SMMU_IRQ_CTRLACK);
+	if (ret)
+		dev_warn(smmu->dev, "failed to enable irqs\n");
+
 	return 0;
 }
 
@@ -565,6 +694,8 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 	if (IS_ERR(smmu->base))
 		return PTR_ERR(smmu->base);
 
+	arm_smmu_probe_irq(pdev, smmu);
+
 	ret = arm_smmu_device_hw_probe(smmu);
 	if (ret)
 		return ret;
@@ -583,6 +714,13 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	/* evtq */
+	ret = arm_smmu_init_one_queue(smmu, &smmu->evtq.q, smmu->base + SZ_64K,
+				      ARM_SMMU_EVTQ_PROD, ARM_SMMU_EVTQ_CONS,
+				      EVTQ_ENT_DWORDS, "evtq");
+	if (ret)
+		return ret;
+
 	ret = arm_smmu_init_strtab(smmu);
 	if (ret)
 		return ret;
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:17 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:17 +0000
Subject: [RFC PATCH v2 53/58] iommu/arm-smmu-v3-kvm: Probe power domains
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-54-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Try to use SCMI if possible, otherwise rely on HVC to the hypervisor
to notify about power changes, this is ONLY safe if the SMMU resets
to blocking DMA.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 78 +++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index 674ce2b02a4b..deeed994a131 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -8,6 +8,7 @@
 #include <asm/kvm_mmu.h>
 
 #include <linux/arm-smccc.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 
@@ -21,6 +22,7 @@ struct host_arm_smmu_device {
 	struct arm_smmu_device		smmu;
 	pkvm_handle_t			id;
 	u32				boot_gbpa;
+	struct kvm_power_domain		power_domain;
 };
 
 #define smmu_to_host(_smmu) \
@@ -654,6 +656,77 @@ static int kvm_arm_smmu_device_reset(struct host_arm_smmu_device *host_smmu)
 	return 0;
 }
 
+static int kvm_arm_probe_scmi_pd(struct device_node *scmi_node,
+				 struct kvm_power_domain *pd)
+{
+	int ret;
+	struct resource res;
+	struct of_phandle_args args;
+
+	pd->type = KVM_POWER_DOMAIN_ARM_SCMI;
+
+	ret = of_parse_phandle_with_args(scmi_node, "shmem", NULL, 0, &args);
+	if (ret)
+		return ret;
+
+	ret = of_address_to_resource(args.np, 0, &res);
+	if (ret)
+		goto out_put_nodes;
+
+	ret = of_property_read_u32(scmi_node, "arm,smc-id",
+				   &pd->arm_scmi.smc_id);
+	if (ret)
+		goto out_put_nodes;
+
+	/*
+	 * The shared buffer is unmapped from the host while a request is in
+	 * flight, so it has to be on its own page.
+	 */
+	if (!IS_ALIGNED(res.start, SZ_64K) || resource_size(&res) < SZ_64K) {
+		ret = -EINVAL;
+		goto out_put_nodes;
+	}
+
+	pd->arm_scmi.shmem_base = res.start;
+	pd->arm_scmi.shmem_size = resource_size(&res);
+
+out_put_nodes:
+	of_node_put(args.np);
+	return ret;
+}
+
+/* TODO: Move this. None of it is specific to SMMU */
+static int kvm_arm_probe_power_domain(struct device *dev,
+				      struct kvm_power_domain *pd)
+{
+	int ret;
+	struct device_node *parent;
+	struct of_phandle_args args;
+
+	if (!of_get_property(dev->of_node, "power-domains", NULL))
+		return 0;
+
+	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
+					 "#power-domain-cells", 0, &args);
+	if (ret)
+		return ret;
+
+	parent = of_get_parent(args.np);
+	if (parent && of_device_is_compatible(parent, "arm,scmi-smc") &&
+	    args.args_count > 0) {
+		pd->arm_scmi.domain_id = args.args[0];
+		ret = kvm_arm_probe_scmi_pd(parent, pd);
+	} else {
+		dev_warn(dev, "Unknown PM method for %pOF, using HVC\n",
+			 args.np);
+		pd->type = KVM_POWER_DOMAIN_HOST_HVC;
+		pd->device_id = kvm_arm_smmu_cur;
+	}
+	of_node_put(parent);
+	of_node_put(args.np);
+	return ret;
+}
+
 static int kvm_arm_smmu_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -681,6 +754,10 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = kvm_arm_probe_power_domain(dev, &host_smmu->power_domain);
+	if (ret)
+		return ret;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	size = resource_size(res);
 	if (size < SZ_128K) {
@@ -738,6 +815,7 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 	hyp_smmu->mmio_addr = ioaddr;
 	hyp_smmu->mmio_size = size;
 	hyp_smmu->features = smmu->features;
+	hyp_smmu->iommu.power_domain = host_smmu->power_domain;
 	kvm_arm_smmu_cur++;
 
 	return arm_smmu_register_iommu(smmu, &kvm_arm_smmu_ops, ioaddr);
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:18 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:18 +0000
Subject: [RFC PATCH v2 54/58] iommu/arm-smmu-v3-kvm: Enable runtime PM
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-55-smostafa@google.com>

Enable runtime PM for the KVM SMMUv3 driver. The PM link to DMA masters
dictates when the SMMU should be powered on.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index deeed994a131..e987c273ff3c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -11,6 +11,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #include <kvm/arm_smmu_v3.h>
 
@@ -127,6 +128,12 @@ static struct iommu_device *kvm_arm_smmu_probe_device(struct device *dev)
 	master->ssid_bits = min(smmu->ssid_bits, master->ssid_bits);
 	xa_init(&master->domains);
 	dev_iommu_priv_set(dev, master);
+	if (!device_link_add(dev, smmu->dev,
+			     DL_FLAG_PM_RUNTIME |
+			     DL_FLAG_AUTOREMOVE_SUPPLIER)) {
+		kfree(master);
+		return ERR_PTR(-ENOLINK);
+	}
 
 	return &smmu->iommu;
 }
@@ -818,6 +825,14 @@ static int kvm_arm_smmu_probe(struct platform_device *pdev)
 	hyp_smmu->iommu.power_domain = host_smmu->power_domain;
 	kvm_arm_smmu_cur++;
 
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	/*
+	 * Take a reference to keep the SMMU powered on while the hypervisor
+	 * initializes it.
+	 */
+	pm_runtime_resume_and_get(dev);
+
 	return arm_smmu_register_iommu(smmu, &kvm_arm_smmu_ops, ioaddr);
 }
 
@@ -826,6 +841,8 @@ static void kvm_arm_smmu_remove(struct platform_device *pdev)
 	struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
 	struct host_arm_smmu_device *host_smmu = smmu_to_host(smmu);
 
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
 	/*
 	 * There was an error during hypervisor setup. The hyp driver may
 	 * have already enabled the device, so disable it.
@@ -834,6 +851,30 @@ static void kvm_arm_smmu_remove(struct platform_device *pdev)
 	arm_smmu_update_gbpa(smmu, host_smmu->boot_gbpa, GBPA_ABORT);
 }
 
+static int kvm_arm_smmu_suspend(struct device *dev)
+{
+	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+	struct host_arm_smmu_device *host_smmu = smmu_to_host(smmu);
+
+	if (host_smmu->power_domain.type == KVM_POWER_DOMAIN_HOST_HVC)
+		return kvm_call_hyp_nvhe(__pkvm_host_hvc_pd, host_smmu->id, 0);
+	return 0;
+}
+
+static int kvm_arm_smmu_resume(struct device *dev)
+{
+	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+	struct host_arm_smmu_device *host_smmu = smmu_to_host(smmu);
+
+	if (host_smmu->power_domain.type == KVM_POWER_DOMAIN_HOST_HVC)
+		return kvm_call_hyp_nvhe(__pkvm_host_hvc_pd, host_smmu->id, 1);
+	return 0;
+}
+
+static const struct dev_pm_ops kvm_arm_smmu_pm_ops = {
+	SET_RUNTIME_PM_OPS(kvm_arm_smmu_suspend, kvm_arm_smmu_resume, NULL)
+};
+
 static const struct of_device_id arm_smmu_of_match[] = {
 	{ .compatible = "arm,smmu-v3", },
 	{ },
@@ -843,6 +884,7 @@ static struct platform_driver kvm_arm_smmu_driver = {
 	.driver = {
 		.name = "kvm-arm-smmu-v3",
 		.of_match_table = arm_smmu_of_match,
+		.pm = &kvm_arm_smmu_pm_ops,
 	},
 	.remove = kvm_arm_smmu_remove,
 };
@@ -877,6 +919,12 @@ static void kvm_arm_smmu_array_free(void)
 	free_pages((unsigned long)kvm_arm_smmu_array, order);
 }
 
+static int smmu_put_device(struct device *dev, void *data)
+{
+	pm_runtime_put(dev);
+	return 0;
+}
+
 static int kvm_arm_smmu_v3_init_drv(void)
 {
 	int ret;
@@ -905,6 +953,7 @@ static int kvm_arm_smmu_v3_init_drv(void)
 	 */
 	kvm_hyp_arm_smmu_v3_smmus = kvm_arm_smmu_array;
 	kvm_hyp_arm_smmu_v3_count = kvm_arm_smmu_count;
+
 	return 0;
 
 err_free:
@@ -931,4 +980,21 @@ static int kvm_arm_smmu_v3_register(void)
 					kern_hyp_va(lm_alias(&kvm_nvhe_sym(smmu_ops))));
 };
 
+/*
+ * KVM init hypervisor at device_sync init call,
+ * so we drop the PM references of the SMMU taken at probe
+ * at the late initcall where it's guaranteed the hypervisor
+ * has initialized the SMMUs.
+ */
+static int kvm_arm_smmu_v3_post_init(void)
+{
+	if (!kvm_arm_smmu_count)
+		return 0;
+
+	WARN_ON(driver_for_each_device(&kvm_arm_smmu_driver.driver, NULL,
+				       NULL, smmu_put_device));
+	return 0;
+}
+
 core_initcall(kvm_arm_smmu_v3_register);
+late_initcall(kvm_arm_smmu_v3_post_init);
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:19 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:19 +0000
Subject: [RFC PATCH v2 55/58] drivers/iommu: Add deferred map_sg operations
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-56-smostafa@google.com>

With pKVM SMMUv3 driver which para-virtualizes the IOMMU in the
hypervisor, has an extra overhead with map_sg, as it loops over
iommu_map, and for each map requires context switching, disabling
interrupts...

Instead, add an new domain operations:
- alloc_cookie_sg: Allocate a new sg deferred cookie
- add_deferred_map_sg: Add a mapping to the cookie
- consume_deferred_map_sg: Consume and release the cookie

Alternativly, we can pass the sg list as is. However, this would
duplicate some of the logic and it would make more sense to
conolidate all the sg list parsing for IOMMU drivers in one place.

virtio-iommu is another IOMMU that can benfit from this, but it
would need to have a new operation that standerdize passing
an sglist based on these ops.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/iommu.c | 53 +++++++++++++++++++++++++++++++++++++++++--
 include/linux/iommu.h | 19 ++++++++++++++++
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 83c8e617a2c5..3a3c48631dd6 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2608,6 +2608,37 @@ size_t iommu_unmap_fast(struct iommu_domain *domain,
 }
 EXPORT_SYMBOL_GPL(iommu_unmap_fast);
 
+static int __iommu_add_sg(struct iommu_map_cookie_sg *cookie_sg,
+			  unsigned long iova, phys_addr_t paddr, size_t size)
+{
+	struct iommu_domain *domain = cookie_sg->domain;
+	const struct iommu_domain_ops *ops = domain->ops;
+	unsigned int min_pagesz;
+	size_t pgsize, count;
+
+	if (unlikely(!(domain->type & __IOMMU_DOMAIN_PAGING)))
+		return -EINVAL;
+
+	if (WARN_ON(domain->pgsize_bitmap == 0UL))
+		return -ENODEV;
+
+	/* find out the minimum page size supported */
+	min_pagesz = 1 << __ffs(domain->pgsize_bitmap);
+
+	/*
+	 * both the virtual address and the physical one, as well as
+	 * the size of the mapping, must be aligned (at least) to the
+	 * size of the smallest page supported by the hardware
+	 */
+	if (!IS_ALIGNED(iova | paddr | size, min_pagesz)) {
+		pr_err("unaligned: iova 0x%lx pa %pa size 0x%zx min_pagesz 0x%x\n",
+		       iova, &paddr, size, min_pagesz);
+		return -EINVAL;
+	}
+	pgsize = iommu_pgsize(domain, iova, paddr, size, &count);
+	return ops->add_deferred_map_sg(cookie_sg, paddr, pgsize, count);
+}
+
 ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
 		     struct scatterlist *sg, unsigned int nents, int prot,
 		     gfp_t gfp)
@@ -2617,6 +2648,9 @@ ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
 	phys_addr_t start;
 	unsigned int i = 0;
 	int ret;
+	bool deferred_sg = ops->alloc_cookie_sg && ops->add_deferred_map_sg &&
+			   ops->consume_deferred_map_sg;
+	struct iommu_map_cookie_sg *cookie_sg;
 
 	might_sleep_if(gfpflags_allow_blocking(gfp));
 
@@ -2625,12 +2659,24 @@ ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
 				__GFP_HIGHMEM)))
 		return -EINVAL;
 
+	if (deferred_sg) {
+		cookie_sg = ops->alloc_cookie_sg(iova, prot, nents, gfp);
+		if (!cookie_sg) {
+			pr_err("iommu: failed alloc cookie\n");
+			return -ENOMEM;
+		}
+		cookie_sg->domain = domain;
+	}
+
 	while (i <= nents) {
 		phys_addr_t s_phys = sg_phys(sg);
 
 		if (len && s_phys != start + len) {
-			ret = __iommu_map(domain, iova + mapped, start,
-					len, prot, gfp);
+			if (deferred_sg)
+				ret = __iommu_add_sg(cookie_sg, iova + mapped, start, len);
+			else
+				ret = __iommu_map(domain, iova + mapped, start,
+						  len, prot, gfp);
 
 			if (ret)
 				goto out_err;
@@ -2654,6 +2700,9 @@ ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
 			sg = sg_next(sg);
 	}
 
+	if (deferred_sg)
+		ops->consume_deferred_map_sg(cookie_sg);
+
 	if (ops->iotlb_sync_map) {
 		ret = ops->iotlb_sync_map(domain, iova, mapped);
 		if (ret)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c75877044185..5e60ac349228 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -601,6 +601,14 @@ struct iommu_ops {
 	u8 user_pasid_table:1;
 };
 
+/**
+ * struct iommu_map_cookie_sg - Cookie for a deferred map sg
+ * @domain: Domain for the sg lit
+ */
+struct iommu_map_cookie_sg {
+	struct iommu_domain *domain;
+};
+
 /**
  * struct iommu_domain_ops - domain specific operations
  * @attach_dev: attach an iommu domain to a device
@@ -638,6 +646,11 @@ struct iommu_ops {
  * @enable_nesting: Enable nesting
  * @set_pgtable_quirks: Set io page table quirks (IO_PGTABLE_QUIRK_*)
  * @free: Release the domain after use.
+ * @alloc_cookie_sg: Allocate a cookie that would be used to create
+ *		     a sg list, filled from the next functions
+ * @add_deferred_map_sg: Add a mapping to a cookie of a sg list.
+ * @consume_deferred_map_sg: Consume the sg list as now all mappings are added,
+ *			     it should also release the cookie as it's not used.
  */
 struct iommu_domain_ops {
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
@@ -668,6 +681,12 @@ struct iommu_domain_ops {
 				  unsigned long quirks);
 
 	void (*free)(struct iommu_domain *domain);
+
+	struct iommu_map_cookie_sg *(*alloc_cookie_sg)(unsigned long iova, int prot,
+						       unsigned int nents, gfp_t gfp);
+	int (*add_deferred_map_sg)(struct iommu_map_cookie_sg *cookie,
+				   phys_addr_t paddr, size_t pgsize, size_t pgcount);
+	int (*consume_deferred_map_sg)(struct iommu_map_cookie_sg *cookie);
 };
 
 /**
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:24 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:24 +0000
Subject: [RFC PATCH v2 00/58] KVM: Arm SMMUv3 driver for pKVM
Message-ID: <20241212180423.1578358-1-smostafa@google.com>

This is v2 of the series sent last year:
https://lore.kernel.org/kvmarm/20230201125328.2186498-1-jean-philippe at linaro.org/

pKVM overview:
=============
The pKVM hypervisor, recently introduced on arm64, provides a separation
of privileges between the host and hypervisor parts of KVM, where the
hypervisor is trusted by guests but the host is not [1][2]. The host is
initially trusted during boot, but its privileges are reduced after KVM
is initialized so that, if an adversary later gains access to the large
attack surface of the host, it cannot access guest data.

Currently with pKVM, the host can still instruct DMA-capable devices
like the GPU to access guest and hypervisor memory, which undermines
this isolation. Preventing DMA attacks requires an IOMMU, owned by the
hypervisor.

This series adds a hypervisor driver for the Arm SMMUv3 IOMMU. Since the
hypervisor part of pKVM (called nVHE here) is minimal, moving the whole
host SMMU driver into nVHE isn't really an option. It is too large and
complex and requires infrastructure from all over the kernel. We add a
reduced nVHE driver that deals with populating the SMMU tables and the
command queue, and the host driver still deals with probing and some
initialization.

Some of the pKVM infrastructure is not upstream yet, which are dependencies
for this series, so it should be considered a forward looking RFC for
what we think about how DMA isolation can be supported in pKVM or in
other similar confidential computing solutions and not a ready to merge
solution.
This is discussed further in the dependencies section below.

Patches overview
================
The patches are split as follows:
Patches 1-10: Mostly about splitting the current SMMUv3 driver and
io-pgtable-arm library, so the code can be re-used in the KVM driver
either inside the kernel or the hypervisor.
Most of these patches are best reviewed with git's --color-moved.

Patches 11-24: Introduce the hypervisor core code for IOMMUs which is
not specific to SMMUv3, these are the hypercall handlers and common
logic in the hypervisor.
It also introduces the key functions __pkvm_host_{un}use_dma_page which
are used to track DMA mapped pages, more on this in the design section.

Patches 25-41: Add the hypervisor part of the KVM SMMUv3 driver which
is called by hypervisor core IOMMU code, these are para-virtualized
operations such as attach/detach, map/unmap...

Patches 42-54: Add the kernel part of the KVM SMMUv3 driver, this
probes the IOMMUs and initialises them and populates the list of SMMUs
to the hypervisor, it also implements the kernel iommu_ops and registers
the IOMMUs with the kernel.

Patches 55-58: Two extra optimizations introduced at the end to avoid
complicating the start of the series, one to optimise iommu_map_sg and
the other is to batch TLB invalidation which I noticed to be a problem
while testing as my HW doesn?t support range invalidation.

A development branch is available at:
https://android-kvm.googlesource.com/linux/+log/refs/heads/for-upstream/pkvm-smmu

Design
======
We've explored 4 solutions so far, we only mention two of them here
which I believe are the most promising as they offer private IO spaces,
while the others were discussed in the v1 of the series cover letter.

1. Paravirtual I/O page tables
This is the solution implemented in this series. The host creates
IOVA->HPA mappings with two hypercalls map_pages() and unmap_pages(), and
the hypervisor populates the page tables. Page tables are abstracted into
IOMMU domains, which allow multiple devices to share the same address
space. Another four hypercalls, alloc_domain(), attach_dev(), detach_dev()
and free_domain(), manage the domains, the semantics of those hypercalls
are almost identical to the IOMMU ops which make the kernel driver part
simpler.

Some key points in the hypervisor design:
a- Tracking mapped pages: the hypervisor must prevent pages mapped in the
   IOMMU to be donated to a protected guest or the hypervisor, or allow
   a protected guest/hypervisor page be mapped in an IOMMU domain.

   For that we rely on the vmemmap refcount, where each time a page is
   mapped it?s refcount is incremented and ownership is checked, and
   each time it's successfully unmapped it?s decremented. And any memory
   donation would be denied for refcounted pages.

b- Locking: The io-pgtable-arm is lockless under some guarantees of how
   the IOMMU code behaves. However with pKVM, the kernel is not trusted
   and a malicious kernel can issue concurrent requests causing memory
   corruption or UAF, so that it has to be locked in the hypervisor.

c- Memory management: The hypervisor needs a way to allocate pages for
   the pv page tables, for that an IOMMU pool is created which can be
   topped up from a hypercall, and the IOMMU hypercalls returns encoded
   memory requests which can be fulfilled by the kernel driver.

2. Nested SMMUv3 translation (with emulation)
Another approach is to rely on nested translation support which is
optional in SMMUv3, that requires an architecturally accurate emulation
of SMMUv3 which can be complicated including cmdq emulation.

With this approach, we can use the same page tables as the CPU stage-2,
which adds more constraints on HW (SMMUv3 features must match the CPU)
and the ability of the devices to handle faults as the CPU part relies
on lazy mapping and has no guarantees about pages being mapped.
Or we can use a shadow IOMMU page table instead.

I have a prototype that is not ready yet to be posted for nested:
https://android-kvm.googlesource.com/linux/+log/refs/heads/smostafa/android15-6.6-smmu-nesting-wip


The trade off between the 2 approaches can be roughly summarised as:
Paravirtualization:
- Compatible with more HW (and IOMMUs).
- Better DMA performance due to shorter table walks/less TLB pressure
- Needs extra complexity to squeeze the last bit of optimization (around
  unmap, and map_sg).

Nested Emulation
- Faster map_pages (not sure about unmap because it requires cmdq
  emulation for TLB invalidation if DVM not used).
- Needs extra complexity for architecturally emulating SMMUv3.

I believe that the first approach looks more promising with this trade
off. However, I plan to complete the nested emulation and post it with
a comparison with this approach in terms of performance, and maybe this
topic can be discussed in an upcoming conference.

Dependencies
============
This series depends on some parts of pKVM that are not upstreamed yet,
some of them are currently posted[3][4]. However, not to spam the list
with many of these changes which are not relevant to IOMMU/SMMUv3 the
patches are developed on top of them.

This series also depends on another series reworking the io-pgtable walker[5]

Performance
===========
With CONFIG_DMA_MAP_BENCHMARK on a 4-core Morello board.
Numbers represent the average time needed for one dma_map/dma_unmap call
in ?s, lower is better.
It is compared with the kernel driver, which is not quite a fair comparison
as it doesn't fulfil pKVM DMA isolation requirements. However, these
numbers are provided just to give a rough idea about how the overhead
looks like.
			Kernel driver	      pKVM driver
4K - 1 thread		0.1/0.7               0.3/1.3
4K - 4 threads		0.1/1.1               0.5/3.3
1M - 1 thread		0.8/21.5              2.6/27.3
1M - 4 threads		1.1/45.7              3.6/46.2

And tested as follows:
echo dma_map_benchmark > /sys/bus/pci/devices/0000\:06\:00.0/driver_override
echo 0000:06:00.0 >  /sys/bus/pci/devices/0000\:06\:00.0/driver/unbind
echo 0000:06:00.0 > /sys/bus/pci/drivers/dma_map_benchmark/bind
./dma_map_bechmark -t $threads -g $nr_pages


Future work
==========
- Add IDENTITY_DOMAIN support, I already have some patches for that, but
  didn?t want to complicate this series, I can send them separately.
- Complete the comparison with the nesting support and find the most
  suitable solution for upstream.


Main changes since v1
=====================
- Patches are reordered to split the introduction of the KVM IOMMU
  code and the SMMUv3 driver.
- KVM EL2 code is closer the EL1 where domains are decoupled from
  IOMMUs.
- SMMUv3 new features (stage-1 support, IRQ and EVTQ in the kernel).
- Adaptions to the new SMMUv3 cleanups.
- Rework tracking of mapped pages to improve performance.
- Rework locking to improve performance.
- Rework unmap to improve performance.
- Adding iotlb_gather to optimize unmap.
- Add new operations to optimize map_sg operation.
- Registering driver is dynamically done instead of statically checked.
- Memory allocation for page table pages are changed to be separate
  pool and HVCs instead of share mc that required atomic allocation.
- Support for higher order page allocation.
- Support for non-coherent SMMUs.
- Support for DABT and MMIO emulation.


[1] https://lore.kernel.org/kvmarm/20220519134204.5379-1-will at kernel.org/
[2] https://www.youtube.com/watch?v=9npebeVFbFw
[3] https://lore.kernel.org/kvmarm/20241203103735.2267589-1-qperret at google.com/
[4] https://lore.kernel.org/all/20241202154742.3611749-1-tabba at google.com/
[5] https://lore.kernel.org/linux-iommu/20241028213146.238941-1-robdclark at gmail.com/T/#t


Jean-Philippe Brucker (23):
  iommu/io-pgtable-arm: Split the page table driver
  iommu/io-pgtable-arm: Split initialization
  iommu/io-pgtable: Add configure() operation
  iommu/arm-smmu-v3: Move some definitions to arm64 include/
  iommu/arm-smmu-v3: Extract driver-specific bits from probe function
  iommu/arm-smmu-v3: Move some functions to arm-smmu-v3-common.c
  iommu/arm-smmu-v3: Move queue and table allocation to
    arm-smmu-v3-common.c
  iommu/arm-smmu-v3: Move firmware probe to arm-smmu-v3-common
  iommu/arm-smmu-v3: Move IOMMU registration to arm-smmu-v3-common.c
  KVM: arm64: pkvm: Add pkvm_udelay()
  KVM: arm64: pkvm: Add __pkvm_host_add_remove_page()
  KVM: arm64: pkvm: Support SCMI power domain
  KVM: arm64: iommu: Support power management
  KVM: arm64: iommu: Add SMMUv3 driver
  KVM: arm64: smmu-v3: Initialize registers
  KVM: arm64: smmu-v3: Setup command queue
  KVM: arm64: smmu-v3: Reset the device
  KVM: arm64: smmu-v3: Support io-pgtable
  iommu/arm-smmu-v3-kvm: Add host driver for pKVM
  iommu/arm-smmu-v3-kvm: Pass a list of SMMU devices to the hypervisor
  iommu/arm-smmu-v3-kvm: Validate device features
  iommu/arm-smmu-v3-kvm: Allocate structures and reset device
  iommu/arm-smmu-v3-kvm: Probe power domains

Mostafa Saleh (35):
  iommu/arm-smmu-v3: Move common irq code to common file
  KVM: arm64: Add __pkvm_{use, unuse}_dma()
  KVM: arm64: Introduce IOMMU driver infrastructure
  KVM: arm64: pkvm: Add IOMMU hypercalls
  KVM: arm64: iommu: Add a memory pool for the IOMMU
  KVM: arm64: iommu: Add domains
  KVM: arm64: iommu: Add {attach, detach}_dev
  KVM: arm64: iommu: Add map/unmap() operations
  KVM: arm64: iommu: support iommu_iotlb_gather
  KVM: arm64: Support power domains
  KVM: arm64: iommu: Support DABT for IOMMU
  KVM: arm64: smmu-v3: Setup stream table
  KVM: arm64: smmu-v3: Setup event queue
  KVM: arm64: smmu-v3: Add {alloc/free}_domain
  KVM: arm64: smmu-v3: Add TLB ops
  KVM: arm64: smmu-v3: Add context descriptor functions
  KVM: arm64: smmu-v3: Add attach_dev
  KVM: arm64: smmu-v3: Add detach_dev
  iommu/io-pgtable: Generalize walker interface
  iommu/io-pgtable-arm: Add post table walker callback
  drivers/iommu: io-pgtable: Add IO_PGTABLE_QUIRK_UNMAP_INVAL
  KVM: arm64: smmu-v3: Add map/unmap pages and iova_to_phys
  KVM: arm64: smmu-v3: Add DABT handler
  KVM: arm64: Add function to topup generic allocator
  KVM: arm64: Add macro for SMCCC call with all returns
  iommu/arm-smmu-v3-kvm: Add function to topup IOMMU allocator
  iommu/arm-smmu-v3-kvm: Add IOMMU ops
  iommu/arm-smmu-v3-kvm: Add map, unmap and iova_to_phys operations
  iommu/arm-smmu-v3-kvm: Support PASID operations
  iommu/arm-smmu-v3-kvm: Add IRQs for the driver
  iommu/arm-smmu-v3-kvm: Enable runtime PM
  drivers/iommu: Add deferred map_sg operations
  KVM: arm64: iommu: Add hypercall for map_sg
  iommu/arm-smmu-v3-kvm: Implement sg operations
  iommu/arm-smmu-v3-kvm: Support command queue batching

 arch/arm64/include/asm/arm-smmu-v3-common.h   |  592 +++++++
 arch/arm64/include/asm/kvm_asm.h              |    9 +
 arch/arm64/include/asm/kvm_host.h             |   48 +-
 arch/arm64/include/asm/kvm_hyp.h              |    2 +
 arch/arm64/kvm/Makefile                       |    2 +-
 arch/arm64/kvm/arm.c                          |    8 +-
 arch/arm64/kvm/hyp/hyp-constants.c            |    1 +
 arch/arm64/kvm/hyp/include/nvhe/iommu.h       |   91 ++
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |    3 +
 arch/arm64/kvm/hyp/include/nvhe/mm.h          |    1 +
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |   37 +
 .../arm64/kvm/hyp/include/nvhe/trap_handler.h |    2 +
 arch/arm64/kvm/hyp/nvhe/Makefile              |    6 +-
 arch/arm64/kvm/hyp/nvhe/alloc_mgt.c           |    2 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  114 ++
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c   | 1390 +++++++++++++++++
 .../arm64/kvm/hyp/nvhe/iommu/io-pgtable-arm.c |  153 ++
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c         |  490 ++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         |  133 +-
 arch/arm64/kvm/hyp/nvhe/mm.c                  |   17 +
 arch/arm64/kvm/hyp/nvhe/power/hvc.c           |   47 +
 arch/arm64/kvm/hyp/nvhe/power/scmi.c          |  231 +++
 arch/arm64/kvm/hyp/nvhe/setup.c               |    9 +
 arch/arm64/kvm/hyp/nvhe/timer-sr.c            |   42 +
 arch/arm64/kvm/iommu.c                        |   89 ++
 arch/arm64/kvm/mmu.c                          |   20 +
 arch/arm64/kvm/pkvm.c                         |   20 +
 drivers/gpu/drm/msm/msm_iommu.c               |    5 +-
 drivers/iommu/Kconfig                         |    9 +
 drivers/iommu/Makefile                        |    2 +-
 drivers/iommu/arm/arm-smmu-v3/Makefile        |    7 +
 .../arm/arm-smmu-v3/arm-smmu-v3-common.c      |  824 ++++++++++
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 1093 +++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  989 +-----------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  758 +++------
 drivers/iommu/io-pgtable-arm-common.c         |  929 +++++++++++
 drivers/iommu/io-pgtable-arm.c                | 1061 +------------
 drivers/iommu/io-pgtable-arm.h                |   30 -
 drivers/iommu/io-pgtable.c                    |   15 +
 drivers/iommu/iommu.c                         |   53 +-
 include/kvm/arm_smmu_v3.h                     |   46 +
 include/kvm/iommu.h                           |   59 +
 include/kvm/power_domain.h                    |   24 +
 include/linux/io-pgtable-arm.h                |  233 +++
 include/linux/io-pgtable.h                    |   38 +-
 include/linux/iommu.h                         |   43 +-
 46 files changed, 7169 insertions(+), 2608 deletions(-)
 create mode 100644 arch/arm64/include/asm/arm-smmu-v3-common.h
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/iommu.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
 create mode 100644 arch/arm64/kvm/hyp/nvhe/iommu/io-pgtable-arm.c
 create mode 100644 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
 create mode 100644 arch/arm64/kvm/hyp/nvhe/power/hvc.c
 create mode 100644 arch/arm64/kvm/hyp/nvhe/power/scmi.c
 create mode 100644 arch/arm64/kvm/iommu.c
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-common.c
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
 create mode 100644 drivers/iommu/io-pgtable-arm-common.c
 delete mode 100644 drivers/iommu/io-pgtable-arm.h
 create mode 100644 include/kvm/arm_smmu_v3.h
 create mode 100644 include/kvm/iommu.h
 create mode 100644 include/kvm/power_domain.h
 create mode 100644 include/linux/io-pgtable-arm.h

-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:25 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:25 +0000
Subject: [RFC PATCH v2 01/58] iommu/io-pgtable-arm: Split the page table driver
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-2-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

To allow the KVM IOMMU driver to populate page tables using the
io-pgtable-arm code, move the shared bits into io-pgtable-arm-common.c.

Here we move the bulk of the common code, and a subsequent patch handles
the bits that require more care. phys_to_virt() and virt_to_phys() do
need special handling here because the hypervisor will have its own
version. It will also implement its own version of
__arm_lpae_alloc_pages(), __arm_lpae_free_pages() and
__arm_lpae_sync_pte() since the hypervisor needs some assistance for
allocating pages.

Some other minor changes around mapping existing or unmapping empty
PTEs as WARN_ON is fatal in the hypervisor.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/Makefile                |   2 +-
 drivers/iommu/io-pgtable-arm-common.c | 625 ++++++++++++++++++++
 drivers/iommu/io-pgtable-arm.c        | 795 +-------------------------
 drivers/iommu/io-pgtable-arm.h        |  30 -
 include/linux/io-pgtable-arm.h        | 223 ++++++++
 5 files changed, 866 insertions(+), 809 deletions(-)
 create mode 100644 drivers/iommu/io-pgtable-arm-common.c
 delete mode 100644 drivers/iommu/io-pgtable-arm.h
 create mode 100644 include/linux/io-pgtable-arm.h

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 542760d963ec..70c5386ce298 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
-obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
+obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o io-pgtable-arm-common.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_DART) += io-pgtable-dart.o
 obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU)	+= of_iommu.o
diff --git a/drivers/iommu/io-pgtable-arm-common.c b/drivers/iommu/io-pgtable-arm-common.c
new file mode 100644
index 000000000000..ef14a1b50d32
--- /dev/null
+++ b/drivers/iommu/io-pgtable-arm-common.c
@@ -0,0 +1,625 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * CPU-agnostic ARM page table allocator.
+ * A copy of this library is embedded in the KVM nVHE image.
+ *
+ * Copyright (C) 2022 Arm Limited
+ *
+ * Author: Will Deacon <will.deacon at arm.com>
+ */
+
+#include <linux/io-pgtable-arm.h>
+
+#include <linux/sizes.h>
+#include <linux/types.h>
+
+#define iopte_deref(pte, d) __arm_lpae_phys_to_virt(iopte_to_paddr(pte, d))
+
+static arm_lpae_iopte paddr_to_iopte(phys_addr_t paddr,
+				     struct arm_lpae_io_pgtable *data)
+{
+	arm_lpae_iopte pte = paddr;
+
+	/* Of the bits which overlap, either 51:48 or 15:12 are always RES0 */
+	return (pte | (pte >> (48 - 12))) & ARM_LPAE_PTE_ADDR_MASK;
+}
+
+static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
+				  struct arm_lpae_io_pgtable *data)
+{
+	u64 paddr = pte & ARM_LPAE_PTE_ADDR_MASK;
+
+	if (ARM_LPAE_GRANULE(data) < SZ_64K)
+		return paddr;
+
+	/* Rotate the packed high-order bits back to the top */
+	return (paddr | (paddr << (48 - 12))) & (ARM_LPAE_PTE_ADDR_MASK << 4);
+}
+
+static void __arm_lpae_clear_pte(arm_lpae_iopte *ptep, struct io_pgtable_cfg *cfg, int num_entries)
+{
+	for (int i = 0; i < num_entries; i++)
+		ptep[i] = 0;
+
+	if (!cfg->coherent_walk && num_entries)
+		__arm_lpae_sync_pte(ptep, num_entries, cfg);
+}
+
+static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
+			       struct iommu_iotlb_gather *gather,
+			       unsigned long iova, size_t size, size_t pgcount,
+			       int lvl, arm_lpae_iopte *ptep);
+
+static void __arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
+				phys_addr_t paddr, arm_lpae_iopte prot,
+				int lvl, int num_entries, arm_lpae_iopte *ptep)
+{
+	arm_lpae_iopte pte = prot;
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
+	int i;
+
+	if (data->iop.fmt != ARM_MALI_LPAE && lvl == ARM_LPAE_MAX_LEVELS - 1)
+		pte |= ARM_LPAE_PTE_TYPE_PAGE;
+	else
+		pte |= ARM_LPAE_PTE_TYPE_BLOCK;
+
+	for (i = 0; i < num_entries; i++)
+		ptep[i] = pte | paddr_to_iopte(paddr + i * sz, data);
+
+	if (!cfg->coherent_walk)
+		__arm_lpae_sync_pte(ptep, num_entries, cfg);
+}
+
+static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
+			     unsigned long iova, phys_addr_t paddr,
+			     arm_lpae_iopte prot, int lvl, int num_entries,
+			     arm_lpae_iopte *ptep)
+{
+	int i;
+
+	for (i = 0; i < num_entries; i++)
+		if (iopte_leaf(ptep[i], lvl, data->iop.fmt)) {
+			/* We require an unmap first */
+			return arm_lpae_map_exists();
+		} else if (iopte_type(ptep[i]) == ARM_LPAE_PTE_TYPE_TABLE) {
+			/*
+			 * We need to unmap and free the old table before
+			 * overwriting it with a block entry.
+			 */
+			arm_lpae_iopte *tblp;
+			size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
+
+			tblp = ptep - ARM_LPAE_LVL_IDX(iova, lvl, data);
+			if (__arm_lpae_unmap(data, NULL, iova + i * sz, sz, 1,
+					     lvl, tblp) != sz) {
+				WARN_ON(1);
+				return -EINVAL;
+			}
+		}
+
+	__arm_lpae_init_pte(data, paddr, prot, lvl, num_entries, ptep);
+	return 0;
+}
+
+static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table,
+					     arm_lpae_iopte *ptep,
+					     arm_lpae_iopte curr,
+					     struct arm_lpae_io_pgtable *data)
+{
+	arm_lpae_iopte old, new;
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+
+	new = paddr_to_iopte(__arm_lpae_virt_to_phys(table), data) |
+			     ARM_LPAE_PTE_TYPE_TABLE;
+	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
+		new |= ARM_LPAE_PTE_NSTABLE;
+
+	/*
+	 * Ensure the table itself is visible before its PTE can be.
+	 * Whilst we could get away with cmpxchg64_release below, this
+	 * doesn't have any ordering semantics when !CONFIG_SMP.
+	 */
+	dma_wmb();
+
+	old = cmpxchg64_relaxed(ptep, curr, new);
+
+	if (cfg->coherent_walk || (old & ARM_LPAE_PTE_SW_SYNC))
+		return old;
+
+	/* Even if it's not ours, there's no point waiting; just kick it */
+	__arm_lpae_sync_pte(ptep, 1, cfg);
+	if (old == curr)
+		WRITE_ONCE(*ptep, new | ARM_LPAE_PTE_SW_SYNC);
+
+	return old;
+}
+
+static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
+			  phys_addr_t paddr, size_t size, size_t pgcount,
+			  arm_lpae_iopte prot, int lvl, arm_lpae_iopte *ptep,
+			  gfp_t gfp, size_t *mapped)
+{
+	arm_lpae_iopte *cptep, pte;
+	size_t block_size = ARM_LPAE_BLOCK_SIZE(lvl, data);
+	size_t tblsz = ARM_LPAE_GRANULE(data);
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	int ret = 0, num_entries, max_entries, map_idx_start;
+
+	/* Find our entry at the current level */
+	map_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
+	ptep += map_idx_start;
+
+	/* If we can install a leaf entry at this level, then do so */
+	if (size == block_size) {
+		max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start;
+		num_entries = min_t(int, pgcount, max_entries);
+		ret = arm_lpae_init_pte(data, iova, paddr, prot, lvl, num_entries, ptep);
+		if (!ret)
+			*mapped += num_entries * size;
+
+		return ret;
+	}
+
+	/* We can't allocate tables at the final level */
+	if (WARN_ON(lvl >= ARM_LPAE_MAX_LEVELS - 1))
+		return -EINVAL;
+
+	/* Grab a pointer to the next level */
+	pte = READ_ONCE(*ptep);
+	if (!pte) {
+		cptep = __arm_lpae_alloc_pages(tblsz, gfp, cfg, data->iop.cookie);
+		if (!cptep)
+			return -ENOMEM;
+
+		pte = arm_lpae_install_table(cptep, ptep, 0, data);
+		if (pte)
+			__arm_lpae_free_pages(cptep, tblsz, cfg, data->iop.cookie);
+	} else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) {
+		__arm_lpae_sync_pte(ptep, 1, cfg);
+	}
+
+	if (pte && !iopte_leaf(pte, lvl, data->iop.fmt)) {
+		cptep = iopte_deref(pte, data);
+	} else if (pte) {
+		/* We require an unmap first */
+		return arm_lpae_unmap_empty();
+	}
+
+	/* Rinse, repeat */
+	return __arm_lpae_map(data, iova, paddr, size, pgcount, prot, lvl + 1,
+			      cptep, gfp, mapped);
+}
+
+static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
+					   int prot)
+{
+	arm_lpae_iopte pte;
+
+	if (data->iop.fmt == ARM_64_LPAE_S1 ||
+	    data->iop.fmt == ARM_32_LPAE_S1) {
+		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_DBM;
+		if (!(prot & IOMMU_PRIV))
+			pte |= ARM_LPAE_PTE_AP_UNPRIV;
+	} else {
+		pte = ARM_LPAE_PTE_HAP_FAULT;
+		if (prot & IOMMU_READ)
+			pte |= ARM_LPAE_PTE_HAP_READ;
+		if (prot & IOMMU_WRITE)
+			pte |= ARM_LPAE_PTE_HAP_WRITE;
+	}
+
+	/*
+	 * 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 (prot & IOMMU_MMIO)
+			pte |= ARM_LPAE_PTE_MEMATTR_DEV;
+		else if (prot & IOMMU_CACHE)
+			pte |= ARM_LPAE_PTE_MEMATTR_OIWB;
+		else
+			pte |= ARM_LPAE_PTE_MEMATTR_NC;
+	} else {
+		if (prot & IOMMU_MMIO)
+			pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV
+				<< ARM_LPAE_PTE_ATTRINDX_SHIFT);
+		else if (prot & IOMMU_CACHE)
+			pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE
+				<< ARM_LPAE_PTE_ATTRINDX_SHIFT);
+	}
+
+	/*
+	 * Also Mali has its own notions of shareability wherein its Inner
+	 * domain covers the cores within the GPU, and its Outer domain is
+	 * "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)
+		pte |= ARM_LPAE_PTE_SH_IS;
+	else
+		pte |= ARM_LPAE_PTE_SH_OS;
+
+	if (prot & IOMMU_NOEXEC)
+		pte |= ARM_LPAE_PTE_XN;
+
+	if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
+		pte |= ARM_LPAE_PTE_NS;
+
+	if (data->iop.fmt != ARM_MALI_LPAE)
+		pte |= ARM_LPAE_PTE_AF;
+
+	return pte;
+}
+
+int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
+		       phys_addr_t paddr, size_t pgsize, size_t pgcount,
+		       int iommu_prot, gfp_t gfp, size_t *mapped)
+{
+	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	arm_lpae_iopte *ptep = data->pgd;
+	int ret, lvl = data->start_level;
+	arm_lpae_iopte prot;
+	long iaext = (s64)iova >> cfg->ias;
+
+	if (WARN_ON(!pgsize || (pgsize & cfg->pgsize_bitmap) != pgsize))
+		return -EINVAL;
+
+	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
+		iaext = ~iaext;
+	if (WARN_ON(iaext || paddr >> cfg->oas))
+		return -ERANGE;
+
+	if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
+		return -EINVAL;
+
+	prot = arm_lpae_prot_to_pte(data, iommu_prot);
+	ret = __arm_lpae_map(data, iova, paddr, pgsize, pgcount, prot, lvl,
+			     ptep, gfp, mapped);
+	/*
+	 * Synchronise all PTE updates for the new mapping before there's
+	 * a chance for anything to kick off a table walk for the new iova.
+	 */
+	wmb();
+
+	return ret;
+}
+
+void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
+			     arm_lpae_iopte *ptep)
+{
+	arm_lpae_iopte *start, *end;
+	unsigned long table_size;
+
+	if (lvl == data->start_level)
+		table_size = ARM_LPAE_PGD_SIZE(data);
+	else
+		table_size = ARM_LPAE_GRANULE(data);
+
+	start = ptep;
+
+	/* Only leaf entries at the last level */
+	if (lvl == ARM_LPAE_MAX_LEVELS - 1)
+		end = ptep;
+	else
+		end = (void *)ptep + table_size;
+
+	while (ptep != end) {
+		arm_lpae_iopte pte = *ptep++;
+
+		if (!pte || iopte_leaf(pte, lvl, data->iop.fmt))
+			continue;
+
+		__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
+	}
+
+	__arm_lpae_free_pages(start, table_size, &data->iop.cfg, data->iop.cookie);
+}
+
+static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
+				       struct iommu_iotlb_gather *gather,
+				       unsigned long iova, size_t size,
+				       arm_lpae_iopte blk_pte, int lvl,
+				       arm_lpae_iopte *ptep, size_t pgcount)
+{
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	arm_lpae_iopte pte, *tablep;
+	phys_addr_t blk_paddr;
+	size_t tablesz = ARM_LPAE_GRANULE(data);
+	size_t split_sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
+	int ptes_per_table = ARM_LPAE_PTES_PER_TABLE(data);
+	int i, unmap_idx_start = -1, num_entries = 0, max_entries;
+
+	if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS))
+		return 0;
+
+	tablep = __arm_lpae_alloc_pages(tablesz, GFP_ATOMIC, cfg, data->iop.cookie);
+	if (!tablep)
+		return 0; /* Bytes unmapped */
+
+	if (size == split_sz) {
+		unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
+		max_entries = ptes_per_table - unmap_idx_start;
+		num_entries = min_t(int, pgcount, max_entries);
+	}
+
+	blk_paddr = iopte_to_paddr(blk_pte, data);
+	pte = iopte_prot(blk_pte);
+
+	for (i = 0; i < ptes_per_table; i++, blk_paddr += split_sz) {
+		/* Unmap! */
+		if (i >= unmap_idx_start && i < (unmap_idx_start + num_entries))
+			continue;
+
+		__arm_lpae_init_pte(data, blk_paddr, pte, lvl, 1, &tablep[i]);
+	}
+
+	pte = arm_lpae_install_table(tablep, ptep, blk_pte, data);
+	if (pte != blk_pte) {
+		__arm_lpae_free_pages(tablep, tablesz, cfg, data->iop.cookie);
+		/*
+		 * We may race against someone unmapping another part of this
+		 * block, but anything else is invalid. We can't misinterpret
+		 * a page entry here since we're never at the last level.
+		 */
+		if (iopte_type(pte) != ARM_LPAE_PTE_TYPE_TABLE)
+			return 0;
+
+		tablep = iopte_deref(pte, data);
+	} else if (unmap_idx_start >= 0) {
+		for (i = 0; i < num_entries; i++)
+			io_pgtable_tlb_add_page(&data->iop, gather, iova + i * size, size);
+
+		return num_entries * size;
+	}
+
+	return __arm_lpae_unmap(data, gather, iova, size, pgcount, lvl, tablep);
+}
+
+static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
+			       struct iommu_iotlb_gather *gather,
+			       unsigned long iova, size_t size, size_t pgcount,
+			       int lvl, arm_lpae_iopte *ptep)
+{
+	arm_lpae_iopte pte;
+	struct io_pgtable *iop = &data->iop;
+	int i = 0, num_entries, max_entries, unmap_idx_start;
+
+	/* Something went horribly wrong and we ran out of page table */
+	if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS))
+		return 0;
+
+	unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
+	ptep += unmap_idx_start;
+	pte = READ_ONCE(*ptep);
+	if (WARN_ON(!pte))
+		return 0;
+
+	/* If the size matches this level, we're in the right place */
+	if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) {
+		max_entries = ARM_LPAE_PTES_PER_TABLE(data) - unmap_idx_start;
+		num_entries = min_t(int, pgcount, max_entries);
+
+		/* Find and handle non-leaf entries */
+		for (i = 0; i < num_entries; i++) {
+			pte = READ_ONCE(ptep[i]);
+			if (WARN_ON(!pte))
+				break;
+
+			if (!iopte_leaf(pte, lvl, iop->fmt)) {
+				__arm_lpae_clear_pte(&ptep[i], &iop->cfg, 1);
+
+				/* Also flush any partial walks */
+				io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
+							  ARM_LPAE_GRANULE(data));
+				__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
+			}
+		}
+
+		/* Clear the remaining entries */
+		__arm_lpae_clear_pte(ptep, &iop->cfg, i);
+
+		if (gather && !iommu_iotlb_gather_queued(gather))
+			for (int j = 0; j < i; j++)
+				io_pgtable_tlb_add_page(iop, gather, iova + j * size, size);
+
+		return i * size;
+	} else if (iopte_leaf(pte, lvl, iop->fmt)) {
+		/*
+		 * Insert a table at the next level to map the old region,
+		 * minus the part we want to unmap
+		 */
+		return arm_lpae_split_blk_unmap(data, gather, iova, size, pte,
+						lvl + 1, ptep, pgcount);
+	}
+
+	/* Keep on walkin' */
+	ptep = iopte_deref(pte, data);
+	return __arm_lpae_unmap(data, gather, iova, size, pgcount, lvl + 1, ptep);
+}
+
+size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
+			    size_t pgsize, size_t pgcount,
+			    struct iommu_iotlb_gather *gather)
+{
+	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	arm_lpae_iopte *ptep = data->pgd;
+	long iaext = (s64)iova >> cfg->ias;
+
+	if (WARN_ON(!pgsize || (pgsize & cfg->pgsize_bitmap) != pgsize || !pgcount))
+		return 0;
+
+	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
+		iaext = ~iaext;
+	if (WARN_ON(iaext))
+		return 0;
+
+	return __arm_lpae_unmap(data, gather, iova, pgsize, pgcount,
+				data->start_level, ptep);
+}
+
+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);
+
+struct iova_to_phys_data {
+	arm_lpae_iopte pte;
+	int lvl;
+};
+
+static int visit_iova_to_phys(struct io_pgtable_walk_data *walk_data, int lvl,
+			      arm_lpae_iopte *ptep, size_t size)
+{
+	struct iova_to_phys_data *data = walk_data->data;
+	data->pte = *ptep;
+	data->lvl = lvl;
+	return 0;
+}
+
+phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
+				  unsigned long iova)
+{
+	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	struct iova_to_phys_data d;
+	struct io_pgtable_walk_data walk_data = {
+		.data = &d,
+		.visit = visit_iova_to_phys,
+		.addr = iova,
+		.end = iova + 1,
+	};
+	int ret;
+
+	ret = __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
+	if (ret)
+		return 0;
+
+	iova &= (ARM_LPAE_BLOCK_SIZE(d.lvl, data) - 1);
+	return iopte_to_paddr(d.pte, data) | iova;
+}
+
+static int visit_pgtable_walk(struct io_pgtable_walk_data *walk_data, int lvl,
+			      arm_lpae_iopte *ptep, size_t size)
+{
+	struct arm_lpae_io_pgtable_walk_data *data = walk_data->data;
+	data->ptes[data->level++] = *ptep;
+	return 0;
+}
+
+int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova, void *wd)
+{
+	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	struct io_pgtable_walk_data walk_data = {
+		.data = wd,
+		.visit = visit_pgtable_walk,
+		.addr = iova,
+		.end = iova + 1,
+	};
+
+	((struct arm_lpae_io_pgtable_walk_data *)wd)->level = 0;
+
+	return __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
+}
+
+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);
+
+	size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
+	int ret = walk_data->visit(walk_data, lvl, ptep, size);
+	if (ret)
+		return ret;
+
+	if (iopte_leaf(pte, lvl, iop->fmt)) {
+		walk_data->addr += size;
+		return 0;
+	}
+
+	if (!iopte_table(pte, lvl)) {
+		return -EINVAL;
+	}
+
+	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) {
+		ret = io_pgtable_visit(data, walk_data, ptep + idx, lvl);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int visit_dirty(struct io_pgtable_walk_data *walk_data, int lvl,
+		       arm_lpae_iopte *ptep, size_t size)
+{
+	struct iommu_dirty_bitmap *dirty = walk_data->data;
+
+	if (!iopte_leaf(*ptep, lvl, walk_data->iop->fmt))
+		return 0;
+
+	if (iopte_writeable_dirty(*ptep)) {
+		iommu_dirty_bitmap_record(dirty, walk_data->addr, size);
+		if (!(walk_data->flags & IOMMU_DIRTY_NO_CLEAR))
+			iopte_set_writeable_clean(ptep);
+	}
+
+	return 0;
+}
+
+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 io_pgtable_walk_data walk_data = {
+		.iop = &data->iop,
+		.data = dirty,
+		.visit = visit_dirty,
+		.flags = flags,
+		.addr = iova,
+		.end = iova + size,
+	};
+	arm_lpae_iopte *ptep = data->pgd;
+	int lvl = data->start_level;
+
+	if (WARN_ON(!size))
+		return -EINVAL;
+	if (WARN_ON((iova + size - 1) & ~(BIT(cfg->ias) - 1)))
+		return -EINVAL;
+	if (data->iop.fmt != ARM_64_LPAE_S1)
+		return -EINVAL;
+
+	return __arm_lpae_iopte_walk(data, &walk_data, ptep, lvl);
+}
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 6739e1fa54ec..cb4eb513adbf 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * CPU-agnostic ARM page table allocator.
+ * Host-specific functions. The rest is in io-pgtable-arm-common.c.
  *
  * Copyright (C) 2014 ARM Limited
  *
@@ -11,7 +12,7 @@
 
 #include <linux/atomic.h>
 #include <linux/bitops.h>
-#include <linux/io-pgtable.h>
+#include <linux/io-pgtable-arm.h>
 #include <linux/kernel.h>
 #include <linux/sizes.h>
 #include <linux/slab.h>
@@ -20,195 +21,33 @@
 
 #include <asm/barrier.h>
 
-#include "io-pgtable-arm.h"
 #include "iommu-pages.h"
 
 #define ARM_LPAE_MAX_ADDR_BITS		52
 #define ARM_LPAE_S2_MAX_CONCAT_PAGES	16
-#define ARM_LPAE_MAX_LEVELS		4
 
-/* Struct accessors */
-#define io_pgtable_to_data(x)						\
-	container_of((x), struct arm_lpae_io_pgtable, iop)
-
-#define io_pgtable_ops_to_data(x)					\
-	io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
-
-/*
- * Calculate the right shift amount to get to the portion describing level l
- * in a virtual address mapped by the pagetable in d.
- */
-#define ARM_LPAE_LVL_SHIFT(l,d)						\
-	(((ARM_LPAE_MAX_LEVELS - (l)) * (d)->bits_per_level) +		\
-	ilog2(sizeof(arm_lpae_iopte)))
-
-#define ARM_LPAE_GRANULE(d)						\
-	(sizeof(arm_lpae_iopte) << (d)->bits_per_level)
-#define ARM_LPAE_PGD_SIZE(d)						\
-	(sizeof(arm_lpae_iopte) << (d)->pgd_bits)
-
-#define ARM_LPAE_PTES_PER_TABLE(d)					\
-	(ARM_LPAE_GRANULE(d) >> ilog2(sizeof(arm_lpae_iopte)))
-
-/*
- * Calculate the index at level l used to map virtual address a using the
- * pagetable in d.
- */
-#define ARM_LPAE_PGD_IDX(l,d)						\
-	((l) == (d)->start_level ? (d)->pgd_bits - (d)->bits_per_level : 0)
-
-#define ARM_LPAE_LVL_IDX(a,l,d)						\
-	(((u64)(a) >> ARM_LPAE_LVL_SHIFT(l,d)) &			\
-	 ((1 << ((d)->bits_per_level + ARM_LPAE_PGD_IDX(l,d))) - 1))
-
-/* Calculate the block/page mapping size at level l for pagetable in d. */
-#define ARM_LPAE_BLOCK_SIZE(l,d)	(1ULL << ARM_LPAE_LVL_SHIFT(l,d))
-
-/* Page table bits */
-#define ARM_LPAE_PTE_TYPE_SHIFT		0
-#define ARM_LPAE_PTE_TYPE_MASK		0x3
-
-#define ARM_LPAE_PTE_TYPE_BLOCK		1
-#define ARM_LPAE_PTE_TYPE_TABLE		3
-#define ARM_LPAE_PTE_TYPE_PAGE		3
-
-#define ARM_LPAE_PTE_ADDR_MASK		GENMASK_ULL(47,12)
-
-#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)
-#define ARM_LPAE_PTE_SH_IS		(((arm_lpae_iopte)3) << 8)
-#define ARM_LPAE_PTE_NS			(((arm_lpae_iopte)1) << 5)
-#define ARM_LPAE_PTE_VALID		(((arm_lpae_iopte)1) << 0)
-
-#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_PTE_XN | ARM_LPAE_PTE_DBM)
-#define ARM_LPAE_PTE_ATTR_MASK		(ARM_LPAE_PTE_ATTR_LO_MASK |	\
-					 ARM_LPAE_PTE_ATTR_HI_MASK)
-/* Software bit for solving coherency races */
-#define ARM_LPAE_PTE_SW_SYNC		(((arm_lpae_iopte)1) << 55)
-
-/* Stage-1 PTE */
-#define ARM_LPAE_PTE_AP_UNPRIV		(((arm_lpae_iopte)1) << 6)
-#define ARM_LPAE_PTE_AP_RDONLY_BIT	7
-#define ARM_LPAE_PTE_AP_RDONLY		(((arm_lpae_iopte)1) << \
-					   ARM_LPAE_PTE_AP_RDONLY_BIT)
-#define ARM_LPAE_PTE_AP_WR_CLEAN_MASK	(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)
-
-/* Stage-2 PTE */
-#define ARM_LPAE_PTE_HAP_FAULT		(((arm_lpae_iopte)0) << 6)
-#define ARM_LPAE_PTE_HAP_READ		(((arm_lpae_iopte)1) << 6)
-#define ARM_LPAE_PTE_HAP_WRITE		(((arm_lpae_iopte)2) << 6)
-#define ARM_LPAE_PTE_MEMATTR_OIWB	(((arm_lpae_iopte)0xf) << 2)
-#define ARM_LPAE_PTE_MEMATTR_NC		(((arm_lpae_iopte)0x5) << 2)
-#define ARM_LPAE_PTE_MEMATTR_DEV	(((arm_lpae_iopte)0x1) << 2)
-
-/* Register bits */
-#define ARM_LPAE_VTCR_SL0_MASK		0x3
-
-#define ARM_LPAE_TCR_T0SZ_SHIFT		0
-
-#define ARM_LPAE_VTCR_PS_SHIFT		16
-#define ARM_LPAE_VTCR_PS_MASK		0x7
-
-#define ARM_LPAE_MAIR_ATTR_SHIFT(n)	((n) << 3)
-#define ARM_LPAE_MAIR_ATTR_MASK		0xff
-#define ARM_LPAE_MAIR_ATTR_DEVICE	0x04
-#define ARM_LPAE_MAIR_ATTR_NC		0x44
-#define ARM_LPAE_MAIR_ATTR_INC_OWBRWA	0xf4
-#define ARM_LPAE_MAIR_ATTR_WBRWA	0xff
-#define ARM_LPAE_MAIR_ATTR_IDX_NC	0
-#define ARM_LPAE_MAIR_ATTR_IDX_CACHE	1
-#define ARM_LPAE_MAIR_ATTR_IDX_DEV	2
-#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE	3
-
-#define ARM_MALI_LPAE_TTBR_ADRMODE_TABLE (3u << 0)
-#define ARM_MALI_LPAE_TTBR_READ_INNER	BIT(2)
-#define ARM_MALI_LPAE_TTBR_SHARE_OUTER	BIT(4)
-
-#define ARM_MALI_LPAE_MEMATTR_IMP_DEF	0x88ULL
-#define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL
-
-/* IOPTE accessors */
-#define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d))
-
-#define iopte_type(pte)					\
-	(((pte) >> ARM_LPAE_PTE_TYPE_SHIFT) & ARM_LPAE_PTE_TYPE_MASK)
-
-#define iopte_prot(pte)	((pte) & ARM_LPAE_PTE_ATTR_MASK)
-
-#define iopte_writeable_dirty(pte)				\
-	(((pte) & ARM_LPAE_PTE_AP_WR_CLEAN_MASK) == ARM_LPAE_PTE_DBM)
-
-#define iopte_set_writeable_clean(ptep)				\
-	set_bit(ARM_LPAE_PTE_AP_RDONLY_BIT, (unsigned long *)(ptep))
-
-struct arm_lpae_io_pgtable {
-	struct io_pgtable	iop;
-
-	int			pgd_bits;
-	int			start_level;
-	int			bits_per_level;
-
-	void			*pgd;
-};
-
-typedef u64 arm_lpae_iopte;
-
-static inline bool iopte_leaf(arm_lpae_iopte pte, int lvl,
-			      enum io_pgtable_fmt fmt)
-{
-	if (lvl == (ARM_LPAE_MAX_LEVELS - 1) && fmt != ARM_MALI_LPAE)
-		return iopte_type(pte) == ARM_LPAE_PTE_TYPE_PAGE;
-
-	return iopte_type(pte) == ARM_LPAE_PTE_TYPE_BLOCK;
-}
+static bool selftest_running = false;
 
-static inline bool iopte_table(arm_lpae_iopte pte, int lvl)
+int arm_lpae_map_exists(void)
 {
-	if (lvl == (ARM_LPAE_MAX_LEVELS - 1))
-		return false;
-	return iopte_type(pte) == ARM_LPAE_PTE_TYPE_TABLE;
+	WARN_ON(!selftest_running);
+	return -EEXIST;
 }
 
-static arm_lpae_iopte paddr_to_iopte(phys_addr_t paddr,
-				     struct arm_lpae_io_pgtable *data)
+int arm_lpae_unmap_empty(void)
 {
-	arm_lpae_iopte pte = paddr;
-
-	/* Of the bits which overlap, either 51:48 or 15:12 are always RES0 */
-	return (pte | (pte >> (48 - 12))) & ARM_LPAE_PTE_ADDR_MASK;
+	WARN_ON(!selftest_running);
+	return -EEXIST;
 }
 
-static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
-				  struct arm_lpae_io_pgtable *data)
-{
-	u64 paddr = pte & ARM_LPAE_PTE_ADDR_MASK;
-
-	if (ARM_LPAE_GRANULE(data) < SZ_64K)
-		return paddr;
-
-	/* Rotate the packed high-order bits back to the top */
-	return (paddr | (paddr << (48 - 12))) & (ARM_LPAE_PTE_ADDR_MASK << 4);
-}
-
-static bool selftest_running = false;
-
 static dma_addr_t __arm_lpae_dma_addr(void *pages)
 {
 	return (dma_addr_t)virt_to_phys(pages);
 }
 
-static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
-				    struct io_pgtable_cfg *cfg,
-				    void *cookie)
+void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
+			     struct io_pgtable_cfg *cfg,
+			     void *cookie)
 {
 	struct device *dev = cfg->iommu_dev;
 	int order = get_order(size);
@@ -253,9 +92,9 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
 	return NULL;
 }
 
-static void __arm_lpae_free_pages(void *pages, size_t size,
-				  struct io_pgtable_cfg *cfg,
-				  void *cookie)
+void __arm_lpae_free_pages(void *pages, size_t size,
+			   struct io_pgtable_cfg *cfg,
+			   void *cookie)
 {
 	if (!cfg->coherent_walk)
 		dma_unmap_single(cfg->iommu_dev, __arm_lpae_dma_addr(pages),
@@ -267,300 +106,13 @@ static void __arm_lpae_free_pages(void *pages, size_t size,
 		iommu_free_pages(pages, get_order(size));
 }
 
-static void __arm_lpae_sync_pte(arm_lpae_iopte *ptep, int num_entries,
-				struct io_pgtable_cfg *cfg)
+void __arm_lpae_sync_pte(arm_lpae_iopte *ptep, int num_entries,
+			 struct io_pgtable_cfg *cfg)
 {
 	dma_sync_single_for_device(cfg->iommu_dev, __arm_lpae_dma_addr(ptep),
 				   sizeof(*ptep) * num_entries, DMA_TO_DEVICE);
 }
 
-static void __arm_lpae_clear_pte(arm_lpae_iopte *ptep, struct io_pgtable_cfg *cfg, int num_entries)
-{
-	for (int i = 0; i < num_entries; i++)
-		ptep[i] = 0;
-
-	if (!cfg->coherent_walk && num_entries)
-		__arm_lpae_sync_pte(ptep, num_entries, cfg);
-}
-
-static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
-			       struct iommu_iotlb_gather *gather,
-			       unsigned long iova, size_t size, size_t pgcount,
-			       int lvl, arm_lpae_iopte *ptep);
-
-static void __arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
-				phys_addr_t paddr, arm_lpae_iopte prot,
-				int lvl, int num_entries, arm_lpae_iopte *ptep)
-{
-	arm_lpae_iopte pte = prot;
-	struct io_pgtable_cfg *cfg = &data->iop.cfg;
-	size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
-	int i;
-
-	if (data->iop.fmt != ARM_MALI_LPAE && lvl == ARM_LPAE_MAX_LEVELS - 1)
-		pte |= ARM_LPAE_PTE_TYPE_PAGE;
-	else
-		pte |= ARM_LPAE_PTE_TYPE_BLOCK;
-
-	for (i = 0; i < num_entries; i++)
-		ptep[i] = pte | paddr_to_iopte(paddr + i * sz, data);
-
-	if (!cfg->coherent_walk)
-		__arm_lpae_sync_pte(ptep, num_entries, cfg);
-}
-
-static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
-			     unsigned long iova, phys_addr_t paddr,
-			     arm_lpae_iopte prot, int lvl, int num_entries,
-			     arm_lpae_iopte *ptep)
-{
-	int i;
-
-	for (i = 0; i < num_entries; i++)
-		if (iopte_leaf(ptep[i], lvl, data->iop.fmt)) {
-			/* We require an unmap first */
-			WARN_ON(!selftest_running);
-			return -EEXIST;
-		} else if (iopte_type(ptep[i]) == ARM_LPAE_PTE_TYPE_TABLE) {
-			/*
-			 * We need to unmap and free the old table before
-			 * overwriting it with a block entry.
-			 */
-			arm_lpae_iopte *tblp;
-			size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
-
-			tblp = ptep - ARM_LPAE_LVL_IDX(iova, lvl, data);
-			if (__arm_lpae_unmap(data, NULL, iova + i * sz, sz, 1,
-					     lvl, tblp) != sz) {
-				WARN_ON(1);
-				return -EINVAL;
-			}
-		}
-
-	__arm_lpae_init_pte(data, paddr, prot, lvl, num_entries, ptep);
-	return 0;
-}
-
-static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table,
-					     arm_lpae_iopte *ptep,
-					     arm_lpae_iopte curr,
-					     struct arm_lpae_io_pgtable *data)
-{
-	arm_lpae_iopte old, new;
-	struct io_pgtable_cfg *cfg = &data->iop.cfg;
-
-	new = paddr_to_iopte(__pa(table), data) | ARM_LPAE_PTE_TYPE_TABLE;
-	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
-		new |= ARM_LPAE_PTE_NSTABLE;
-
-	/*
-	 * Ensure the table itself is visible before its PTE can be.
-	 * Whilst we could get away with cmpxchg64_release below, this
-	 * doesn't have any ordering semantics when !CONFIG_SMP.
-	 */
-	dma_wmb();
-
-	old = cmpxchg64_relaxed(ptep, curr, new);
-
-	if (cfg->coherent_walk || (old & ARM_LPAE_PTE_SW_SYNC))
-		return old;
-
-	/* Even if it's not ours, there's no point waiting; just kick it */
-	__arm_lpae_sync_pte(ptep, 1, cfg);
-	if (old == curr)
-		WRITE_ONCE(*ptep, new | ARM_LPAE_PTE_SW_SYNC);
-
-	return old;
-}
-
-static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
-			  phys_addr_t paddr, size_t size, size_t pgcount,
-			  arm_lpae_iopte prot, int lvl, arm_lpae_iopte *ptep,
-			  gfp_t gfp, size_t *mapped)
-{
-	arm_lpae_iopte *cptep, pte;
-	size_t block_size = ARM_LPAE_BLOCK_SIZE(lvl, data);
-	size_t tblsz = ARM_LPAE_GRANULE(data);
-	struct io_pgtable_cfg *cfg = &data->iop.cfg;
-	int ret = 0, num_entries, max_entries, map_idx_start;
-
-	/* Find our entry at the current level */
-	map_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
-	ptep += map_idx_start;
-
-	/* If we can install a leaf entry at this level, then do so */
-	if (size == block_size) {
-		max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start;
-		num_entries = min_t(int, pgcount, max_entries);
-		ret = arm_lpae_init_pte(data, iova, paddr, prot, lvl, num_entries, ptep);
-		if (!ret)
-			*mapped += num_entries * size;
-
-		return ret;
-	}
-
-	/* We can't allocate tables at the final level */
-	if (WARN_ON(lvl >= ARM_LPAE_MAX_LEVELS - 1))
-		return -EINVAL;
-
-	/* Grab a pointer to the next level */
-	pte = READ_ONCE(*ptep);
-	if (!pte) {
-		cptep = __arm_lpae_alloc_pages(tblsz, gfp, cfg, data->iop.cookie);
-		if (!cptep)
-			return -ENOMEM;
-
-		pte = arm_lpae_install_table(cptep, ptep, 0, data);
-		if (pte)
-			__arm_lpae_free_pages(cptep, tblsz, cfg, data->iop.cookie);
-	} else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) {
-		__arm_lpae_sync_pte(ptep, 1, cfg);
-	}
-
-	if (pte && !iopte_leaf(pte, lvl, data->iop.fmt)) {
-		cptep = iopte_deref(pte, data);
-	} else if (pte) {
-		/* We require an unmap first */
-		WARN_ON(!selftest_running);
-		return -EEXIST;
-	}
-
-	/* Rinse, repeat */
-	return __arm_lpae_map(data, iova, paddr, size, pgcount, prot, lvl + 1,
-			      cptep, gfp, mapped);
-}
-
-static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
-					   int prot)
-{
-	arm_lpae_iopte pte;
-
-	if (data->iop.fmt == ARM_64_LPAE_S1 ||
-	    data->iop.fmt == ARM_32_LPAE_S1) {
-		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_DBM;
-		if (!(prot & IOMMU_PRIV))
-			pte |= ARM_LPAE_PTE_AP_UNPRIV;
-	} else {
-		pte = ARM_LPAE_PTE_HAP_FAULT;
-		if (prot & IOMMU_READ)
-			pte |= ARM_LPAE_PTE_HAP_READ;
-		if (prot & IOMMU_WRITE)
-			pte |= ARM_LPAE_PTE_HAP_WRITE;
-	}
-
-	/*
-	 * 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 (prot & IOMMU_MMIO)
-			pte |= ARM_LPAE_PTE_MEMATTR_DEV;
-		else if (prot & IOMMU_CACHE)
-			pte |= ARM_LPAE_PTE_MEMATTR_OIWB;
-		else
-			pte |= ARM_LPAE_PTE_MEMATTR_NC;
-	} else {
-		if (prot & IOMMU_MMIO)
-			pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV
-				<< ARM_LPAE_PTE_ATTRINDX_SHIFT);
-		else if (prot & IOMMU_CACHE)
-			pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE
-				<< ARM_LPAE_PTE_ATTRINDX_SHIFT);
-	}
-
-	/*
-	 * Also Mali has its own notions of shareability wherein its Inner
-	 * domain covers the cores within the GPU, and its Outer domain is
-	 * "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)
-		pte |= ARM_LPAE_PTE_SH_IS;
-	else
-		pte |= ARM_LPAE_PTE_SH_OS;
-
-	if (prot & IOMMU_NOEXEC)
-		pte |= ARM_LPAE_PTE_XN;
-
-	if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
-		pte |= ARM_LPAE_PTE_NS;
-
-	if (data->iop.fmt != ARM_MALI_LPAE)
-		pte |= ARM_LPAE_PTE_AF;
-
-	return pte;
-}
-
-static int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
-			      phys_addr_t paddr, size_t pgsize, size_t pgcount,
-			      int iommu_prot, gfp_t gfp, size_t *mapped)
-{
-	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
-	struct io_pgtable_cfg *cfg = &data->iop.cfg;
-	arm_lpae_iopte *ptep = data->pgd;
-	int ret, lvl = data->start_level;
-	arm_lpae_iopte prot;
-	long iaext = (s64)iova >> cfg->ias;
-
-	if (WARN_ON(!pgsize || (pgsize & cfg->pgsize_bitmap) != pgsize))
-		return -EINVAL;
-
-	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
-		iaext = ~iaext;
-	if (WARN_ON(iaext || paddr >> cfg->oas))
-		return -ERANGE;
-
-	if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
-		return -EINVAL;
-
-	prot = arm_lpae_prot_to_pte(data, iommu_prot);
-	ret = __arm_lpae_map(data, iova, paddr, pgsize, pgcount, prot, lvl,
-			     ptep, gfp, mapped);
-	/*
-	 * Synchronise all PTE updates for the new mapping before there's
-	 * a chance for anything to kick off a table walk for the new iova.
-	 */
-	wmb();
-
-	return ret;
-}
-
-static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
-				    arm_lpae_iopte *ptep)
-{
-	arm_lpae_iopte *start, *end;
-	unsigned long table_size;
-
-	if (lvl == data->start_level)
-		table_size = ARM_LPAE_PGD_SIZE(data);
-	else
-		table_size = ARM_LPAE_GRANULE(data);
-
-	start = ptep;
-
-	/* Only leaf entries at the last level */
-	if (lvl == ARM_LPAE_MAX_LEVELS - 1)
-		end = ptep;
-	else
-		end = (void *)ptep + table_size;
-
-	while (ptep != end) {
-		arm_lpae_iopte pte = *ptep++;
-
-		if (!pte || iopte_leaf(pte, lvl, data->iop.fmt))
-			continue;
-
-		__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
-	}
-
-	__arm_lpae_free_pages(start, table_size, &data->iop.cfg, data->iop.cookie);
-}
-
 static void arm_lpae_free_pgtable(struct io_pgtable *iop)
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_to_data(iop);
@@ -569,319 +121,6 @@ static void arm_lpae_free_pgtable(struct io_pgtable *iop)
 	kfree(data);
 }
 
-static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
-				       struct iommu_iotlb_gather *gather,
-				       unsigned long iova, size_t size,
-				       arm_lpae_iopte blk_pte, int lvl,
-				       arm_lpae_iopte *ptep, size_t pgcount)
-{
-	struct io_pgtable_cfg *cfg = &data->iop.cfg;
-	arm_lpae_iopte pte, *tablep;
-	phys_addr_t blk_paddr;
-	size_t tablesz = ARM_LPAE_GRANULE(data);
-	size_t split_sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
-	int ptes_per_table = ARM_LPAE_PTES_PER_TABLE(data);
-	int i, unmap_idx_start = -1, num_entries = 0, max_entries;
-
-	if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS))
-		return 0;
-
-	tablep = __arm_lpae_alloc_pages(tablesz, GFP_ATOMIC, cfg, data->iop.cookie);
-	if (!tablep)
-		return 0; /* Bytes unmapped */
-
-	if (size == split_sz) {
-		unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
-		max_entries = ptes_per_table - unmap_idx_start;
-		num_entries = min_t(int, pgcount, max_entries);
-	}
-
-	blk_paddr = iopte_to_paddr(blk_pte, data);
-	pte = iopte_prot(blk_pte);
-
-	for (i = 0; i < ptes_per_table; i++, blk_paddr += split_sz) {
-		/* Unmap! */
-		if (i >= unmap_idx_start && i < (unmap_idx_start + num_entries))
-			continue;
-
-		__arm_lpae_init_pte(data, blk_paddr, pte, lvl, 1, &tablep[i]);
-	}
-
-	pte = arm_lpae_install_table(tablep, ptep, blk_pte, data);
-	if (pte != blk_pte) {
-		__arm_lpae_free_pages(tablep, tablesz, cfg, data->iop.cookie);
-		/*
-		 * We may race against someone unmapping another part of this
-		 * block, but anything else is invalid. We can't misinterpret
-		 * a page entry here since we're never at the last level.
-		 */
-		if (iopte_type(pte) != ARM_LPAE_PTE_TYPE_TABLE)
-			return 0;
-
-		tablep = iopte_deref(pte, data);
-	} else if (unmap_idx_start >= 0) {
-		for (i = 0; i < num_entries; i++)
-			io_pgtable_tlb_add_page(&data->iop, gather, iova + i * size, size);
-
-		return num_entries * size;
-	}
-
-	return __arm_lpae_unmap(data, gather, iova, size, pgcount, lvl, tablep);
-}
-
-static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
-			       struct iommu_iotlb_gather *gather,
-			       unsigned long iova, size_t size, size_t pgcount,
-			       int lvl, arm_lpae_iopte *ptep)
-{
-	arm_lpae_iopte pte;
-	struct io_pgtable *iop = &data->iop;
-	int i = 0, num_entries, max_entries, unmap_idx_start;
-
-	/* Something went horribly wrong and we ran out of page table */
-	if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS))
-		return 0;
-
-	unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
-	ptep += unmap_idx_start;
-	pte = READ_ONCE(*ptep);
-	if (WARN_ON(!pte))
-		return 0;
-
-	/* If the size matches this level, we're in the right place */
-	if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) {
-		max_entries = ARM_LPAE_PTES_PER_TABLE(data) - unmap_idx_start;
-		num_entries = min_t(int, pgcount, max_entries);
-
-		/* Find and handle non-leaf entries */
-		for (i = 0; i < num_entries; i++) {
-			pte = READ_ONCE(ptep[i]);
-			if (WARN_ON(!pte))
-				break;
-
-			if (!iopte_leaf(pte, lvl, iop->fmt)) {
-				__arm_lpae_clear_pte(&ptep[i], &iop->cfg, 1);
-
-				/* Also flush any partial walks */
-				io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
-							  ARM_LPAE_GRANULE(data));
-				__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
-			}
-		}
-
-		/* Clear the remaining entries */
-		__arm_lpae_clear_pte(ptep, &iop->cfg, i);
-
-		if (gather && !iommu_iotlb_gather_queued(gather))
-			for (int j = 0; j < i; j++)
-				io_pgtable_tlb_add_page(iop, gather, iova + j * size, size);
-
-		return i * size;
-	} else if (iopte_leaf(pte, lvl, iop->fmt)) {
-		/*
-		 * Insert a table at the next level to map the old region,
-		 * minus the part we want to unmap
-		 */
-		return arm_lpae_split_blk_unmap(data, gather, iova, size, pte,
-						lvl + 1, ptep, pgcount);
-	}
-
-	/* Keep on walkin' */
-	ptep = iopte_deref(pte, data);
-	return __arm_lpae_unmap(data, gather, iova, size, pgcount, lvl + 1, ptep);
-}
-
-static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
-				   size_t pgsize, size_t pgcount,
-				   struct iommu_iotlb_gather *gather)
-{
-	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
-	struct io_pgtable_cfg *cfg = &data->iop.cfg;
-	arm_lpae_iopte *ptep = data->pgd;
-	long iaext = (s64)iova >> cfg->ias;
-
-	if (WARN_ON(!pgsize || (pgsize & cfg->pgsize_bitmap) != pgsize || !pgcount))
-		return 0;
-
-	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
-		iaext = ~iaext;
-	if (WARN_ON(iaext))
-		return 0;
-
-	return __arm_lpae_unmap(data, gather, iova, pgsize, pgcount,
-				data->start_level, ptep);
-}
-
-struct io_pgtable_walk_data {
-	struct io_pgtable		*iop;
-	void				*data;
-	int (*visit)(struct io_pgtable_walk_data *walk_data, int lvl,
-		     arm_lpae_iopte *ptep, size_t size);
-	unsigned long			flags;
-	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);
-
-struct iova_to_phys_data {
-	arm_lpae_iopte pte;
-	int lvl;
-};
-
-static int visit_iova_to_phys(struct io_pgtable_walk_data *walk_data, int lvl,
-			      arm_lpae_iopte *ptep, size_t size)
-{
-	struct iova_to_phys_data *data = walk_data->data;
-	data->pte = *ptep;
-	data->lvl = lvl;
-	return 0;
-}
-
-static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
-					 unsigned long iova)
-{
-	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
-	struct iova_to_phys_data d;
-	struct io_pgtable_walk_data walk_data = {
-		.data = &d,
-		.visit = visit_iova_to_phys,
-		.addr = iova,
-		.end = iova + 1,
-	};
-	int ret;
-
-	ret = __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
-	if (ret)
-		return 0;
-
-	iova &= (ARM_LPAE_BLOCK_SIZE(d.lvl, data) - 1);
-	return iopte_to_paddr(d.pte, data) | iova;
-}
-
-static int visit_pgtable_walk(struct io_pgtable_walk_data *walk_data, int lvl,
-			      arm_lpae_iopte *ptep, size_t size)
-{
-	struct arm_lpae_io_pgtable_walk_data *data = walk_data->data;
-	data->ptes[data->level++] = *ptep;
-	return 0;
-}
-
-static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
-				 void *wd)
-{
-	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
-	struct io_pgtable_walk_data walk_data = {
-		.data = wd,
-		.visit = visit_pgtable_walk,
-		.addr = iova,
-		.end = iova + 1,
-	};
-
-	((struct arm_lpae_io_pgtable_walk_data *)wd)->level = 0;
-
-	return __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level);
-}
-
-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);
-
-	size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
-	int ret = walk_data->visit(walk_data, lvl, ptep, size);
-	if (ret)
-		return ret;
-
-	if (iopte_leaf(pte, lvl, iop->fmt)) {
-		walk_data->addr += size;
-		return 0;
-	}
-
-	if (!iopte_table(pte, lvl)) {
-		return -EINVAL;
-	}
-
-	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) {
-		ret = io_pgtable_visit(data, walk_data, ptep + idx, lvl);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-static int visit_dirty(struct io_pgtable_walk_data *walk_data, int lvl,
-		       arm_lpae_iopte *ptep, size_t size)
-{
-	struct iommu_dirty_bitmap *dirty = walk_data->data;
-
-	if (!iopte_leaf(*ptep, lvl, walk_data->iop->fmt))
-		return 0;
-
-	if (iopte_writeable_dirty(*ptep)) {
-		iommu_dirty_bitmap_record(dirty, walk_data->addr, size);
-		if (!(walk_data->flags & IOMMU_DIRTY_NO_CLEAR))
-			iopte_set_writeable_clean(ptep);
-	}
-
-	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 io_pgtable_walk_data walk_data = {
-		.iop = &data->iop,
-		.data = dirty,
-		.visit = visit_dirty,
-		.flags = flags,
-		.addr = iova,
-		.end = iova + size,
-	};
-	arm_lpae_iopte *ptep = data->pgd;
-	int lvl = data->start_level;
-
-	if (WARN_ON(!size))
-		return -EINVAL;
-	if (WARN_ON((iova + size - 1) & ~(BIT(cfg->ias) - 1)))
-		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;
diff --git a/drivers/iommu/io-pgtable-arm.h b/drivers/iommu/io-pgtable-arm.h
deleted file mode 100644
index ba7cfdf7afa0..000000000000
--- a/drivers/iommu/io-pgtable-arm.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-#ifndef IO_PGTABLE_ARM_H_
-#define IO_PGTABLE_ARM_H_
-
-#define ARM_LPAE_TCR_TG0_4K		0
-#define ARM_LPAE_TCR_TG0_64K		1
-#define ARM_LPAE_TCR_TG0_16K		2
-
-#define ARM_LPAE_TCR_TG1_16K		1
-#define ARM_LPAE_TCR_TG1_4K		2
-#define ARM_LPAE_TCR_TG1_64K		3
-
-#define ARM_LPAE_TCR_SH_NS		0
-#define ARM_LPAE_TCR_SH_OS		2
-#define ARM_LPAE_TCR_SH_IS		3
-
-#define ARM_LPAE_TCR_RGN_NC		0
-#define ARM_LPAE_TCR_RGN_WBWA		1
-#define ARM_LPAE_TCR_RGN_WT		2
-#define ARM_LPAE_TCR_RGN_WB		3
-
-#define ARM_LPAE_TCR_PS_32_BIT		0x0ULL
-#define ARM_LPAE_TCR_PS_36_BIT		0x1ULL
-#define ARM_LPAE_TCR_PS_40_BIT		0x2ULL
-#define ARM_LPAE_TCR_PS_42_BIT		0x3ULL
-#define ARM_LPAE_TCR_PS_44_BIT		0x4ULL
-#define ARM_LPAE_TCR_PS_48_BIT		0x5ULL
-#define ARM_LPAE_TCR_PS_52_BIT		0x6ULL
-
-#endif /* IO_PGTABLE_ARM_H_ */
diff --git a/include/linux/io-pgtable-arm.h b/include/linux/io-pgtable-arm.h
new file mode 100644
index 000000000000..1f56dabca18c
--- /dev/null
+++ b/include/linux/io-pgtable-arm.h
@@ -0,0 +1,223 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef IO_PGTABLE_H_
+#define IO_PGTABLE_H_
+
+#include <linux/io-pgtable.h>
+
+typedef u64 arm_lpae_iopte;
+
+struct arm_lpae_io_pgtable {
+	struct io_pgtable	iop;
+
+	int			pgd_bits;
+	int			start_level;
+	int			bits_per_level;
+
+	void			*pgd;
+};
+
+struct io_pgtable_walk_data {
+	struct io_pgtable		*iop;
+	void				*data;
+	int (*visit)(struct io_pgtable_walk_data *walk_data, int lvl,
+		     arm_lpae_iopte *ptep, size_t size);
+	unsigned long			flags;
+	u64				addr;
+	const u64			end;
+};
+
+/* Struct accessors */
+#define io_pgtable_to_data(x)						\
+	container_of((x), struct arm_lpae_io_pgtable, iop)
+
+#define io_pgtable_ops_to_data(x)					\
+	io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
+
+/*
+ * Calculate the right shift amount to get to the portion describing level l
+ * in a virtual address mapped by the pagetable in d.
+ */
+#define ARM_LPAE_LVL_SHIFT(l,d)						\
+	(((ARM_LPAE_MAX_LEVELS - (l)) * (d)->bits_per_level) +		\
+	ilog2(sizeof(arm_lpae_iopte)))
+
+#define ARM_LPAE_GRANULE(d)						\
+	(sizeof(arm_lpae_iopte) << (d)->bits_per_level)
+#define ARM_LPAE_PGD_SIZE(d)						\
+	(sizeof(arm_lpae_iopte) << (d)->pgd_bits)
+
+#define ARM_LPAE_PTES_PER_TABLE(d)					\
+	(ARM_LPAE_GRANULE(d) >> ilog2(sizeof(arm_lpae_iopte)))
+
+/*
+ * Calculate the index at level l used to map virtual address a using the
+ * pagetable in d.
+ */
+#define ARM_LPAE_PGD_IDX(l,d)						\
+	((l) == (d)->start_level ? (d)->pgd_bits - (d)->bits_per_level : 0)
+
+#define ARM_LPAE_LVL_IDX(a,l,d)						\
+	(((u64)(a) >> ARM_LPAE_LVL_SHIFT(l,d)) &			\
+	 ((1 << ((d)->bits_per_level + ARM_LPAE_PGD_IDX(l,d))) - 1))
+
+/* Calculate the block/page mapping size at level l for pagetable in d. */
+#define ARM_LPAE_BLOCK_SIZE(l,d)	(1ULL << ARM_LPAE_LVL_SHIFT(l,d))
+
+/* Page table bits */
+#define ARM_LPAE_PTE_TYPE_SHIFT		0
+#define ARM_LPAE_PTE_TYPE_MASK		0x3
+
+#define ARM_LPAE_PTE_TYPE_BLOCK		1
+#define ARM_LPAE_PTE_TYPE_TABLE		3
+#define ARM_LPAE_PTE_TYPE_PAGE		3
+
+#define ARM_LPAE_PTE_ADDR_MASK		GENMASK_ULL(47,12)
+
+#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)
+#define ARM_LPAE_PTE_SH_IS		(((arm_lpae_iopte)3) << 8)
+#define ARM_LPAE_PTE_NS			(((arm_lpae_iopte)1) << 5)
+#define ARM_LPAE_PTE_VALID		(((arm_lpae_iopte)1) << 0)
+
+#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_PTE_XN | ARM_LPAE_PTE_DBM)
+#define ARM_LPAE_PTE_ATTR_MASK		(ARM_LPAE_PTE_ATTR_LO_MASK |	\
+					 ARM_LPAE_PTE_ATTR_HI_MASK)
+/* Software bit for solving coherency races */
+#define ARM_LPAE_PTE_SW_SYNC		(((arm_lpae_iopte)1) << 55)
+
+/* Stage-1 PTE */
+#define ARM_LPAE_PTE_AP_UNPRIV		(((arm_lpae_iopte)1) << 6)
+#define ARM_LPAE_PTE_AP_RDONLY_BIT	7
+#define ARM_LPAE_PTE_AP_RDONLY		(((arm_lpae_iopte)1) << \
+					   ARM_LPAE_PTE_AP_RDONLY_BIT)
+#define ARM_LPAE_PTE_AP_WR_CLEAN_MASK	(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)
+
+/* Stage-2 PTE */
+#define ARM_LPAE_PTE_HAP_FAULT		(((arm_lpae_iopte)0) << 6)
+#define ARM_LPAE_PTE_HAP_READ		(((arm_lpae_iopte)1) << 6)
+#define ARM_LPAE_PTE_HAP_WRITE		(((arm_lpae_iopte)2) << 6)
+#define ARM_LPAE_PTE_MEMATTR_OIWB	(((arm_lpae_iopte)0xf) << 2)
+#define ARM_LPAE_PTE_MEMATTR_NC		(((arm_lpae_iopte)0x5) << 2)
+#define ARM_LPAE_PTE_MEMATTR_DEV	(((arm_lpae_iopte)0x1) << 2)
+
+/* Register bits */
+#define ARM_LPAE_VTCR_SL0_MASK		0x3
+
+#define ARM_LPAE_TCR_T0SZ_SHIFT		0
+
+#define ARM_LPAE_VTCR_PS_SHIFT		16
+#define ARM_LPAE_VTCR_PS_MASK		0x7
+
+#define ARM_LPAE_MAIR_ATTR_SHIFT(n)	((n) << 3)
+#define ARM_LPAE_MAIR_ATTR_MASK		0xff
+#define ARM_LPAE_MAIR_ATTR_DEVICE	0x04
+#define ARM_LPAE_MAIR_ATTR_NC		0x44
+#define ARM_LPAE_MAIR_ATTR_INC_OWBRWA	0xf4
+#define ARM_LPAE_MAIR_ATTR_WBRWA	0xff
+#define ARM_LPAE_MAIR_ATTR_IDX_NC	0
+#define ARM_LPAE_MAIR_ATTR_IDX_CACHE	1
+#define ARM_LPAE_MAIR_ATTR_IDX_DEV	2
+#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE	3
+
+#define ARM_MALI_LPAE_TTBR_ADRMODE_TABLE (3u << 0)
+#define ARM_MALI_LPAE_TTBR_READ_INNER	BIT(2)
+#define ARM_MALI_LPAE_TTBR_SHARE_OUTER	BIT(4)
+
+#define ARM_MALI_LPAE_MEMATTR_IMP_DEF	0x88ULL
+#define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL
+
+#define ARM_LPAE_MAX_LEVELS		4
+
+#define ARM_LPAE_TCR_TG0_4K		0
+#define ARM_LPAE_TCR_TG0_64K		1
+#define ARM_LPAE_TCR_TG0_16K		2
+
+#define ARM_LPAE_TCR_TG1_16K		1
+#define ARM_LPAE_TCR_TG1_4K		2
+#define ARM_LPAE_TCR_TG1_64K		3
+
+#define ARM_LPAE_TCR_SH_NS		0
+#define ARM_LPAE_TCR_SH_OS		2
+#define ARM_LPAE_TCR_SH_IS		3
+
+#define ARM_LPAE_TCR_RGN_NC		0
+#define ARM_LPAE_TCR_RGN_WBWA		1
+#define ARM_LPAE_TCR_RGN_WT		2
+#define ARM_LPAE_TCR_RGN_WB		3
+
+#define ARM_LPAE_TCR_PS_32_BIT		0x0ULL
+#define ARM_LPAE_TCR_PS_36_BIT		0x1ULL
+#define ARM_LPAE_TCR_PS_40_BIT		0x2ULL
+#define ARM_LPAE_TCR_PS_42_BIT		0x3ULL
+#define ARM_LPAE_TCR_PS_44_BIT		0x4ULL
+#define ARM_LPAE_TCR_PS_48_BIT		0x5ULL
+#define ARM_LPAE_TCR_PS_52_BIT		0x6ULL
+
+/* IOPTE accessors */
+#define iopte_type(pte)					\
+	(((pte) >> ARM_LPAE_PTE_TYPE_SHIFT) & ARM_LPAE_PTE_TYPE_MASK)
+
+#define iopte_prot(pte)	((pte) & ARM_LPAE_PTE_ATTR_MASK)
+
+#define iopte_writeable_dirty(pte)				\
+	(((pte) & ARM_LPAE_PTE_AP_WR_CLEAN_MASK) == ARM_LPAE_PTE_DBM)
+
+#define iopte_set_writeable_clean(ptep)				\
+	set_bit(ARM_LPAE_PTE_AP_RDONLY_BIT, (unsigned long *)(ptep))
+
+
+static inline bool iopte_leaf(arm_lpae_iopte pte, int lvl,
+			      enum io_pgtable_fmt fmt)
+{
+	if (lvl == (ARM_LPAE_MAX_LEVELS - 1) && fmt != ARM_MALI_LPAE)
+		return iopte_type(pte) == ARM_LPAE_PTE_TYPE_PAGE;
+
+	return iopte_type(pte) == ARM_LPAE_PTE_TYPE_BLOCK;
+}
+
+static inline bool iopte_table(arm_lpae_iopte pte, int lvl)
+{
+	if (lvl == (ARM_LPAE_MAX_LEVELS - 1))
+		return false;
+	return iopte_type(pte) == ARM_LPAE_PTE_TYPE_TABLE;
+}
+
+#define __arm_lpae_virt_to_phys	__pa
+#define __arm_lpae_phys_to_virt	__va
+
+/* Generic functions */
+int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
+		       phys_addr_t paddr, size_t pgsize, size_t pgcount,
+		       int iommu_prot, gfp_t gfp, size_t *mapped);
+size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
+			    size_t pgsize, size_t pgcount,
+			    struct iommu_iotlb_gather *gather);
+phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
+				  unsigned long iova);
+void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
+			     arm_lpae_iopte *ptep);
+
+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);
+
+int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova, void *wd);
+
+/* Host/hyp-specific functions */
+void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp, struct io_pgtable_cfg *cfg, void *cookie);
+void __arm_lpae_free_pages(void *pages, size_t size, struct io_pgtable_cfg *cfg, void *cookie);
+void __arm_lpae_sync_pte(arm_lpae_iopte *ptep, int num_entries,
+			 struct io_pgtable_cfg *cfg);
+int arm_lpae_map_exists(void);
+int arm_lpae_unmap_empty(void);
+#endif /* IO_PGTABLE_H_ */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:27 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:27 +0000
Subject: [RFC PATCH v2 03/58] iommu/io-pgtable: Add configure() operation
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-4-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Allow IOMMU drivers to create the io-pgtable configuration without
allocating any tables. This will be used by the SMMUv3-KVM driver to
initialize a config and pass it to KVM.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/io-pgtable-arm.c | 16 ++++++++++++++++
 drivers/iommu/io-pgtable.c     | 15 +++++++++++++++
 include/linux/io-pgtable.h     | 15 +++++++++++++++
 3 files changed, 46 insertions(+)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 8d435a5bcd9a..e85866c90290 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -148,6 +148,13 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 	return NULL;
 }
 
+static int arm_64_lpae_configure_s1(struct io_pgtable_cfg *cfg)
+{
+	struct arm_lpae_io_pgtable data = {};
+
+	return arm_lpae_init_pgtable_s1(cfg, &data);
+}
+
 static struct io_pgtable *
 arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 {
@@ -178,6 +185,13 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 	return NULL;
 }
 
+static int arm_64_lpae_configure_s2(struct io_pgtable_cfg *cfg)
+{
+	struct arm_lpae_io_pgtable data = {};
+
+	return arm_lpae_init_pgtable_s2(cfg, &data);
+}
+
 static struct io_pgtable *
 arm_32_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 {
@@ -264,12 +278,14 @@ struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = {
 	.caps	= IO_PGTABLE_CAP_CUSTOM_ALLOCATOR,
 	.alloc	= arm_64_lpae_alloc_pgtable_s1,
 	.free	= arm_lpae_free_pgtable,
+	.configure	= arm_64_lpae_configure_s1,
 };
 
 struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns = {
 	.caps	= IO_PGTABLE_CAP_CUSTOM_ALLOCATOR,
 	.alloc	= arm_64_lpae_alloc_pgtable_s2,
 	.free	= arm_lpae_free_pgtable,
+	.configure	= arm_64_lpae_configure_s2,
 };
 
 struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s1_init_fns = {
diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c
index 8841c1487f00..be65f70ec2a6 100644
--- a/drivers/iommu/io-pgtable.c
+++ b/drivers/iommu/io-pgtable.c
@@ -99,3 +99,18 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops)
 	io_pgtable_init_table[iop->fmt]->free(iop);
 }
 EXPORT_SYMBOL_GPL(free_io_pgtable_ops);
+
+int io_pgtable_configure(struct io_pgtable_cfg *cfg)
+{
+	const struct io_pgtable_init_fns *fns;
+
+	if (cfg->fmt >= IO_PGTABLE_NUM_FMTS)
+		return -EINVAL;
+
+	fns = io_pgtable_init_table[cfg->fmt];
+	if (!fns || !fns->configure)
+		return -EOPNOTSUPP;
+
+	return fns->configure(cfg);
+}
+EXPORT_SYMBOL_GPL(io_pgtable_configure);
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index d7bfbf351975..f789234c703b 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
@@ -241,6 +243,17 @@ struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
  */
 void free_io_pgtable_ops(struct io_pgtable_ops *ops);
 
+/**
+ * io_pgtable_configure - Create page table config
+ *
+ * @cfg:	The page table configuration.
+ *
+ * Initialize @cfg in the same way as alloc_io_pgtable_ops(), without allocating
+ * anything.
+ *
+ * Not all io_pgtable drivers implement this operation.
+ */
+int io_pgtable_configure(struct io_pgtable_cfg *cfg);
 
 /*
  * Internal structures for page table allocator implementations.
@@ -301,11 +314,13 @@ enum io_pgtable_caps {
  *
  * @alloc: Allocate a set of page tables described by cfg.
  * @free:  Free the page tables associated with iop.
+ * @configure: Create the configuration without allocating anything. Optional.
  * @caps:  Combination of @io_pgtable_caps flags encoding the backend capabilities.
  */
 struct io_pgtable_init_fns {
 	struct io_pgtable *(*alloc)(struct io_pgtable_cfg *cfg, void *cookie);
 	void (*free)(struct io_pgtable *iop);
+	int (*configure)(struct io_pgtable_cfg *cfg);
 	u32 caps;
 };
 
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:26 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:26 +0000
Subject: [RFC PATCH v2 02/58] iommu/io-pgtable-arm: Split initialization
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-3-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Extract the configuration part from io-pgtable-arm.c, move it to
io-pgtable-arm-common.c.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/io-pgtable-arm-common.c | 284 ++++++++++++++++++++++++--
 drivers/iommu/io-pgtable-arm.c        | 250 +----------------------
 include/linux/io-pgtable-arm.h        |  20 +-
 3 files changed, 286 insertions(+), 268 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-common.c b/drivers/iommu/io-pgtable-arm-common.c
index ef14a1b50d32..21ee8ff7c881 100644
--- a/drivers/iommu/io-pgtable-arm-common.c
+++ b/drivers/iommu/io-pgtable-arm-common.c
@@ -15,6 +15,9 @@
 
 #define iopte_deref(pte, d) __arm_lpae_phys_to_virt(iopte_to_paddr(pte, d))
 
+#define ARM_LPAE_MAX_ADDR_BITS		52
+#define ARM_LPAE_S2_MAX_CONCAT_PAGES	16
+
 static arm_lpae_iopte paddr_to_iopte(phys_addr_t paddr,
 				     struct arm_lpae_io_pgtable *data)
 {
@@ -257,9 +260,9 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
 	return pte;
 }
 
-int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
-		       phys_addr_t paddr, size_t pgsize, size_t pgcount,
-		       int iommu_prot, gfp_t gfp, size_t *mapped)
+static int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
+			      phys_addr_t paddr, size_t pgsize, size_t pgcount,
+			      int iommu_prot, gfp_t gfp, size_t *mapped)
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	struct io_pgtable_cfg *cfg = &data->iop.cfg;
@@ -444,9 +447,9 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 	return __arm_lpae_unmap(data, gather, iova, size, pgcount, lvl + 1, ptep);
 }
 
-size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
-			    size_t pgsize, size_t pgcount,
-			    struct iommu_iotlb_gather *gather)
+static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
+				   size_t pgsize, size_t pgcount,
+				   struct iommu_iotlb_gather *gather)
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	struct io_pgtable_cfg *cfg = &data->iop.cfg;
@@ -484,8 +487,8 @@ static int visit_iova_to_phys(struct io_pgtable_walk_data *walk_data, int lvl,
 	return 0;
 }
 
-phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
-				  unsigned long iova)
+static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
+					 unsigned long iova)
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	struct iova_to_phys_data d;
@@ -513,7 +516,7 @@ static int visit_pgtable_walk(struct io_pgtable_walk_data *walk_data, int lvl,
 	return 0;
 }
 
-int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova, void *wd)
+static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova, void *wd)
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	struct io_pgtable_walk_data walk_data = {
@@ -596,10 +599,10 @@ static int visit_dirty(struct io_pgtable_walk_data *walk_data, int lvl,
 	return 0;
 }
 
-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)
+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;
@@ -623,3 +626,258 @@ int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
 
 	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;
+	unsigned int max_addr_bits = 48;
+
+	/*
+	 * We need to restrict the supported page sizes to match the
+	 * translation regime for a particular granule. Aim to match
+	 * the CPU page size if possible, otherwise prefer smaller sizes.
+	 * While we're at it, restrict the block sizes to match the
+	 * chosen granule.
+	 */
+	if (cfg->pgsize_bitmap & PAGE_SIZE)
+		granule = PAGE_SIZE;
+	else if (cfg->pgsize_bitmap & ~PAGE_MASK)
+		granule = 1UL << __fls(cfg->pgsize_bitmap & ~PAGE_MASK);
+	else if (cfg->pgsize_bitmap & PAGE_MASK)
+		granule = 1UL << __ffs(cfg->pgsize_bitmap & PAGE_MASK);
+	else
+		granule = 0;
+
+	switch (granule) {
+	case SZ_4K:
+		page_sizes = (SZ_4K | SZ_2M | SZ_1G);
+		break;
+	case SZ_16K:
+		page_sizes = (SZ_16K | SZ_32M);
+		break;
+	case SZ_64K:
+		max_addr_bits = 52;
+		page_sizes = (SZ_64K | SZ_512M);
+		if (cfg->oas > 48)
+			page_sizes |= 1ULL << 42; /* 4TB */
+		break;
+	default:
+		page_sizes = 0;
+	}
+
+	cfg->pgsize_bitmap &= page_sizes;
+	cfg->ias = min(cfg->ias, max_addr_bits);
+	cfg->oas = min(cfg->oas, max_addr_bits);
+}
+
+int arm_lpae_init_pgtable(struct io_pgtable_cfg *cfg,
+			  struct arm_lpae_io_pgtable *data)
+{
+	int levels, va_bits, pg_shift;
+
+	arm_lpae_restrict_pgsizes(cfg);
+
+	if (!(cfg->pgsize_bitmap & (SZ_4K | SZ_16K | SZ_64K)))
+		return -EINVAL;
+
+	if (cfg->ias > ARM_LPAE_MAX_ADDR_BITS)
+		return -E2BIG;
+
+	if (cfg->oas > ARM_LPAE_MAX_ADDR_BITS)
+		return -E2BIG;
+
+	pg_shift = __ffs(cfg->pgsize_bitmap);
+	data->bits_per_level = pg_shift - ilog2(sizeof(arm_lpae_iopte));
+
+	va_bits = cfg->ias - pg_shift;
+	levels = DIV_ROUND_UP(va_bits, data->bits_per_level);
+	data->start_level = ARM_LPAE_MAX_LEVELS - levels;
+
+	/* Calculate the actual size of our pgd (without concatenation) */
+	data->pgd_bits = va_bits - (data->bits_per_level * (levels - 1));
+
+	data->iop.ops = (struct io_pgtable_ops) {
+		.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,
+		.pgtable_walk	= arm_lpae_pgtable_walk,
+	};
+
+	return 0;
+}
+
+int arm_lpae_init_pgtable_s1(struct io_pgtable_cfg *cfg,
+			     struct arm_lpae_io_pgtable *data)
+{
+	u64 reg;
+	int ret;
+	typeof(&cfg->arm_lpae_s1_cfg.tcr) tcr = &cfg->arm_lpae_s1_cfg.tcr;
+	bool tg1;
+
+	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
+			    IO_PGTABLE_QUIRK_ARM_TTBR1 |
+			    IO_PGTABLE_QUIRK_ARM_OUTER_WBWA |
+			    IO_PGTABLE_QUIRK_ARM_HD))
+		return -EINVAL;
+
+	ret = arm_lpae_init_pgtable(cfg, data);
+	if (ret)
+		return ret;
+
+	/* TCR */
+	if (cfg->coherent_walk) {
+		tcr->sh = ARM_LPAE_TCR_SH_IS;
+		tcr->irgn = ARM_LPAE_TCR_RGN_WBWA;
+		tcr->orgn = ARM_LPAE_TCR_RGN_WBWA;
+		if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_OUTER_WBWA)
+			return -EINVAL;
+	} else {
+		tcr->sh = ARM_LPAE_TCR_SH_OS;
+		tcr->irgn = ARM_LPAE_TCR_RGN_NC;
+		if (!(cfg->quirks & IO_PGTABLE_QUIRK_ARM_OUTER_WBWA))
+			tcr->orgn = ARM_LPAE_TCR_RGN_NC;
+		else
+			tcr->orgn = ARM_LPAE_TCR_RGN_WBWA;
+	}
+
+	tg1 = cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1;
+	switch (ARM_LPAE_GRANULE(data)) {
+	case SZ_4K:
+		tcr->tg = tg1 ? ARM_LPAE_TCR_TG1_4K : ARM_LPAE_TCR_TG0_4K;
+		break;
+	case SZ_16K:
+		tcr->tg = tg1 ? ARM_LPAE_TCR_TG1_16K : ARM_LPAE_TCR_TG0_16K;
+		break;
+	case SZ_64K:
+		tcr->tg = tg1 ? ARM_LPAE_TCR_TG1_64K : ARM_LPAE_TCR_TG0_64K;
+		break;
+	}
+
+	switch (cfg->oas) {
+	case 32:
+		tcr->ips = ARM_LPAE_TCR_PS_32_BIT;
+		break;
+	case 36:
+		tcr->ips = ARM_LPAE_TCR_PS_36_BIT;
+		break;
+	case 40:
+		tcr->ips = ARM_LPAE_TCR_PS_40_BIT;
+		break;
+	case 42:
+		tcr->ips = ARM_LPAE_TCR_PS_42_BIT;
+		break;
+	case 44:
+		tcr->ips = ARM_LPAE_TCR_PS_44_BIT;
+		break;
+	case 48:
+		tcr->ips = ARM_LPAE_TCR_PS_48_BIT;
+		break;
+	case 52:
+		tcr->ips = ARM_LPAE_TCR_PS_52_BIT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	tcr->tsz = 64ULL - cfg->ias;
+
+	/* MAIRs */
+	reg = (ARM_LPAE_MAIR_ATTR_NC
+	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_NC)) |
+	      (ARM_LPAE_MAIR_ATTR_WBRWA
+	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_CACHE)) |
+	      (ARM_LPAE_MAIR_ATTR_DEVICE
+	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_DEV)) |
+	      (ARM_LPAE_MAIR_ATTR_INC_OWBRWA
+	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE));
+
+	cfg->arm_lpae_s1_cfg.mair = reg;
+	return 0;
+}
+
+int arm_lpae_init_pgtable_s2(struct io_pgtable_cfg *cfg,
+			     struct arm_lpae_io_pgtable *data)
+{
+	u64 sl;
+	int ret;
+	typeof(&cfg->arm_lpae_s2_cfg.vtcr) vtcr = &cfg->arm_lpae_s2_cfg.vtcr;
+
+	/* The NS quirk doesn't apply at stage 2 */
+	if (cfg->quirks)
+		return -EINVAL;
+
+	ret = arm_lpae_init_pgtable(cfg, data);
+	if (ret)
+		return ret;
+
+	/*
+	 * Concatenate PGDs at level 1 if possible in order to reduce
+	 * the depth of the stage-2 walk.
+	 */
+	if (data->start_level == 0) {
+		unsigned long pgd_pages;
+
+		pgd_pages = ARM_LPAE_PGD_SIZE(data) / sizeof(arm_lpae_iopte);
+		if (pgd_pages <= ARM_LPAE_S2_MAX_CONCAT_PAGES) {
+			data->pgd_bits += data->bits_per_level;
+			data->start_level++;
+		}
+	}
+
+	/* VTCR */
+	if (cfg->coherent_walk) {
+		vtcr->sh = ARM_LPAE_TCR_SH_IS;
+		vtcr->irgn = ARM_LPAE_TCR_RGN_WBWA;
+		vtcr->orgn = ARM_LPAE_TCR_RGN_WBWA;
+	} else {
+		vtcr->sh = ARM_LPAE_TCR_SH_OS;
+		vtcr->irgn = ARM_LPAE_TCR_RGN_NC;
+		vtcr->orgn = ARM_LPAE_TCR_RGN_NC;
+	}
+
+	sl = data->start_level;
+
+	switch (ARM_LPAE_GRANULE(data)) {
+	case SZ_4K:
+		vtcr->tg = ARM_LPAE_TCR_TG0_4K;
+		sl++; /* SL0 format is different for 4K granule size */
+		break;
+	case SZ_16K:
+		vtcr->tg = ARM_LPAE_TCR_TG0_16K;
+		break;
+	case SZ_64K:
+		vtcr->tg = ARM_LPAE_TCR_TG0_64K;
+		break;
+	}
+
+	switch (cfg->oas) {
+	case 32:
+		vtcr->ps = ARM_LPAE_TCR_PS_32_BIT;
+		break;
+	case 36:
+		vtcr->ps = ARM_LPAE_TCR_PS_36_BIT;
+		break;
+	case 40:
+		vtcr->ps = ARM_LPAE_TCR_PS_40_BIT;
+		break;
+	case 42:
+		vtcr->ps = ARM_LPAE_TCR_PS_42_BIT;
+		break;
+	case 44:
+		vtcr->ps = ARM_LPAE_TCR_PS_44_BIT;
+		break;
+	case 48:
+		vtcr->ps = ARM_LPAE_TCR_PS_48_BIT;
+		break;
+	case 52:
+		vtcr->ps = ARM_LPAE_TCR_PS_52_BIT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	vtcr->tsz = 64ULL - cfg->ias;
+	vtcr->sl = ~sl & ARM_LPAE_VTCR_SL0_MASK;
+	return 0;
+}
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index cb4eb513adbf..8d435a5bcd9a 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -19,12 +19,9 @@
 #include <linux/types.h>
 #include <linux/dma-mapping.h>
 
-#include <asm/barrier.h>
-
 #include "iommu-pages.h"
 
-#define ARM_LPAE_MAX_ADDR_BITS		52
-#define ARM_LPAE_S2_MAX_CONCAT_PAGES	16
+#include <asm/barrier.h>
 
 static bool selftest_running = false;
 
@@ -121,177 +118,17 @@ static void arm_lpae_free_pgtable(struct io_pgtable *iop)
 	kfree(data);
 }
 
-static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
-{
-	unsigned long granule, page_sizes;
-	unsigned int max_addr_bits = 48;
-
-	/*
-	 * We need to restrict the supported page sizes to match the
-	 * translation regime for a particular granule. Aim to match
-	 * the CPU page size if possible, otherwise prefer smaller sizes.
-	 * While we're at it, restrict the block sizes to match the
-	 * chosen granule.
-	 */
-	if (cfg->pgsize_bitmap & PAGE_SIZE)
-		granule = PAGE_SIZE;
-	else if (cfg->pgsize_bitmap & ~PAGE_MASK)
-		granule = 1UL << __fls(cfg->pgsize_bitmap & ~PAGE_MASK);
-	else if (cfg->pgsize_bitmap & PAGE_MASK)
-		granule = 1UL << __ffs(cfg->pgsize_bitmap & PAGE_MASK);
-	else
-		granule = 0;
-
-	switch (granule) {
-	case SZ_4K:
-		page_sizes = (SZ_4K | SZ_2M | SZ_1G);
-		break;
-	case SZ_16K:
-		page_sizes = (SZ_16K | SZ_32M);
-		break;
-	case SZ_64K:
-		max_addr_bits = 52;
-		page_sizes = (SZ_64K | SZ_512M);
-		if (cfg->oas > 48)
-			page_sizes |= 1ULL << 42; /* 4TB */
-		break;
-	default:
-		page_sizes = 0;
-	}
-
-	cfg->pgsize_bitmap &= page_sizes;
-	cfg->ias = min(cfg->ias, max_addr_bits);
-	cfg->oas = min(cfg->oas, max_addr_bits);
-}
-
-static struct arm_lpae_io_pgtable *
-arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
-{
-	struct arm_lpae_io_pgtable *data;
-	int levels, va_bits, pg_shift;
-
-	arm_lpae_restrict_pgsizes(cfg);
-
-	if (!(cfg->pgsize_bitmap & (SZ_4K | SZ_16K | SZ_64K)))
-		return NULL;
-
-	if (cfg->ias > ARM_LPAE_MAX_ADDR_BITS)
-		return NULL;
-
-	if (cfg->oas > ARM_LPAE_MAX_ADDR_BITS)
-		return NULL;
-
-	data = kmalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return NULL;
-
-	pg_shift = __ffs(cfg->pgsize_bitmap);
-	data->bits_per_level = pg_shift - ilog2(sizeof(arm_lpae_iopte));
-
-	va_bits = cfg->ias - pg_shift;
-	levels = DIV_ROUND_UP(va_bits, data->bits_per_level);
-	data->start_level = ARM_LPAE_MAX_LEVELS - levels;
-
-	/* Calculate the actual size of our pgd (without concatenation) */
-	data->pgd_bits = va_bits - (data->bits_per_level * (levels - 1));
-
-	data->iop.ops = (struct io_pgtable_ops) {
-		.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,
-		.pgtable_walk	= arm_lpae_pgtable_walk,
-	};
-
-	return data;
-}
-
 static struct io_pgtable *
 arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 {
-	u64 reg;
 	struct arm_lpae_io_pgtable *data;
-	typeof(&cfg->arm_lpae_s1_cfg.tcr) tcr = &cfg->arm_lpae_s1_cfg.tcr;
-	bool tg1;
-
-	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
-			    IO_PGTABLE_QUIRK_ARM_TTBR1 |
-			    IO_PGTABLE_QUIRK_ARM_OUTER_WBWA |
-			    IO_PGTABLE_QUIRK_ARM_HD))
-		return NULL;
 
-	data = arm_lpae_alloc_pgtable(cfg);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return NULL;
 
-	/* TCR */
-	if (cfg->coherent_walk) {
-		tcr->sh = ARM_LPAE_TCR_SH_IS;
-		tcr->irgn = ARM_LPAE_TCR_RGN_WBWA;
-		tcr->orgn = ARM_LPAE_TCR_RGN_WBWA;
-		if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_OUTER_WBWA)
-			goto out_free_data;
-	} else {
-		tcr->sh = ARM_LPAE_TCR_SH_OS;
-		tcr->irgn = ARM_LPAE_TCR_RGN_NC;
-		if (!(cfg->quirks & IO_PGTABLE_QUIRK_ARM_OUTER_WBWA))
-			tcr->orgn = ARM_LPAE_TCR_RGN_NC;
-		else
-			tcr->orgn = ARM_LPAE_TCR_RGN_WBWA;
-	}
-
-	tg1 = cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1;
-	switch (ARM_LPAE_GRANULE(data)) {
-	case SZ_4K:
-		tcr->tg = tg1 ? ARM_LPAE_TCR_TG1_4K : ARM_LPAE_TCR_TG0_4K;
-		break;
-	case SZ_16K:
-		tcr->tg = tg1 ? ARM_LPAE_TCR_TG1_16K : ARM_LPAE_TCR_TG0_16K;
-		break;
-	case SZ_64K:
-		tcr->tg = tg1 ? ARM_LPAE_TCR_TG1_64K : ARM_LPAE_TCR_TG0_64K;
-		break;
-	}
-
-	switch (cfg->oas) {
-	case 32:
-		tcr->ips = ARM_LPAE_TCR_PS_32_BIT;
-		break;
-	case 36:
-		tcr->ips = ARM_LPAE_TCR_PS_36_BIT;
-		break;
-	case 40:
-		tcr->ips = ARM_LPAE_TCR_PS_40_BIT;
-		break;
-	case 42:
-		tcr->ips = ARM_LPAE_TCR_PS_42_BIT;
-		break;
-	case 44:
-		tcr->ips = ARM_LPAE_TCR_PS_44_BIT;
-		break;
-	case 48:
-		tcr->ips = ARM_LPAE_TCR_PS_48_BIT;
-		break;
-	case 52:
-		tcr->ips = ARM_LPAE_TCR_PS_52_BIT;
-		break;
-	default:
+	if (arm_lpae_init_pgtable_s1(cfg, data))
 		goto out_free_data;
-	}
-
-	tcr->tsz = 64ULL - cfg->ias;
-
-	/* MAIRs */
-	reg = (ARM_LPAE_MAIR_ATTR_NC
-	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_NC)) |
-	      (ARM_LPAE_MAIR_ATTR_WBRWA
-	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_CACHE)) |
-	      (ARM_LPAE_MAIR_ATTR_DEVICE
-	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_DEV)) |
-	      (ARM_LPAE_MAIR_ATTR_INC_OWBRWA
-	       << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE));
-
-	cfg->arm_lpae_s1_cfg.mair = reg;
 
 	/* Looking good; allocate a pgd */
 	data->pgd = __arm_lpae_alloc_pages(ARM_LPAE_PGD_SIZE(data),
@@ -314,86 +151,14 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 static struct io_pgtable *
 arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 {
-	u64 sl;
 	struct arm_lpae_io_pgtable *data;
-	typeof(&cfg->arm_lpae_s2_cfg.vtcr) vtcr = &cfg->arm_lpae_s2_cfg.vtcr;
-
-	/* The NS quirk doesn't apply at stage 2 */
-	if (cfg->quirks)
-		return NULL;
 
-	data = arm_lpae_alloc_pgtable(cfg);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return NULL;
 
-	/*
-	 * Concatenate PGDs at level 1 if possible in order to reduce
-	 * the depth of the stage-2 walk.
-	 */
-	if (data->start_level == 0) {
-		unsigned long pgd_pages;
-
-		pgd_pages = ARM_LPAE_PGD_SIZE(data) / sizeof(arm_lpae_iopte);
-		if (pgd_pages <= ARM_LPAE_S2_MAX_CONCAT_PAGES) {
-			data->pgd_bits += data->bits_per_level;
-			data->start_level++;
-		}
-	}
-
-	/* VTCR */
-	if (cfg->coherent_walk) {
-		vtcr->sh = ARM_LPAE_TCR_SH_IS;
-		vtcr->irgn = ARM_LPAE_TCR_RGN_WBWA;
-		vtcr->orgn = ARM_LPAE_TCR_RGN_WBWA;
-	} else {
-		vtcr->sh = ARM_LPAE_TCR_SH_OS;
-		vtcr->irgn = ARM_LPAE_TCR_RGN_NC;
-		vtcr->orgn = ARM_LPAE_TCR_RGN_NC;
-	}
-
-	sl = data->start_level;
-
-	switch (ARM_LPAE_GRANULE(data)) {
-	case SZ_4K:
-		vtcr->tg = ARM_LPAE_TCR_TG0_4K;
-		sl++; /* SL0 format is different for 4K granule size */
-		break;
-	case SZ_16K:
-		vtcr->tg = ARM_LPAE_TCR_TG0_16K;
-		break;
-	case SZ_64K:
-		vtcr->tg = ARM_LPAE_TCR_TG0_64K;
-		break;
-	}
-
-	switch (cfg->oas) {
-	case 32:
-		vtcr->ps = ARM_LPAE_TCR_PS_32_BIT;
-		break;
-	case 36:
-		vtcr->ps = ARM_LPAE_TCR_PS_36_BIT;
-		break;
-	case 40:
-		vtcr->ps = ARM_LPAE_TCR_PS_40_BIT;
-		break;
-	case 42:
-		vtcr->ps = ARM_LPAE_TCR_PS_42_BIT;
-		break;
-	case 44:
-		vtcr->ps = ARM_LPAE_TCR_PS_44_BIT;
-		break;
-	case 48:
-		vtcr->ps = ARM_LPAE_TCR_PS_48_BIT;
-		break;
-	case 52:
-		vtcr->ps = ARM_LPAE_TCR_PS_52_BIT;
-		break;
-	default:
+	if (arm_lpae_init_pgtable_s2(cfg, data))
 		goto out_free_data;
-	}
-
-	vtcr->tsz = 64ULL - cfg->ias;
-	vtcr->sl = ~sl & ARM_LPAE_VTCR_SL0_MASK;
 
 	/* Allocate pgd pages */
 	data->pgd = __arm_lpae_alloc_pages(ARM_LPAE_PGD_SIZE(data),
@@ -447,10 +212,13 @@ arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
 
 	cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G);
 
-	data = arm_lpae_alloc_pgtable(cfg);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return NULL;
 
+	if (arm_lpae_init_pgtable(cfg, data))
+		return NULL;
+
 	/* Mali seems to need a full 4-level table regardless of IAS */
 	if (data->start_level > 0) {
 		data->start_level = 0;
diff --git a/include/linux/io-pgtable-arm.h b/include/linux/io-pgtable-arm.h
index 1f56dabca18c..337e9254fdbd 100644
--- a/include/linux/io-pgtable-arm.h
+++ b/include/linux/io-pgtable-arm.h
@@ -195,23 +195,15 @@ static inline bool iopte_table(arm_lpae_iopte pte, int lvl)
 #define __arm_lpae_phys_to_virt	__va
 
 /* Generic functions */
-int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
-		       phys_addr_t paddr, size_t pgsize, size_t pgcount,
-		       int iommu_prot, gfp_t gfp, size_t *mapped);
-size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
-			    size_t pgsize, size_t pgcount,
-			    struct iommu_iotlb_gather *gather);
-phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
-				  unsigned long iova);
 void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
 			     arm_lpae_iopte *ptep);
 
-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);
-
-int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova, void *wd);
+int arm_lpae_init_pgtable(struct io_pgtable_cfg *cfg,
+			  struct arm_lpae_io_pgtable *data);
+int arm_lpae_init_pgtable_s1(struct io_pgtable_cfg *cfg,
+			     struct arm_lpae_io_pgtable *data);
+int arm_lpae_init_pgtable_s2(struct io_pgtable_cfg *cfg,
+			     struct arm_lpae_io_pgtable *data);
 
 /* Host/hyp-specific functions */
 void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp, struct io_pgtable_cfg *cfg, void *cookie);
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:28 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:28 +0000
Subject: [RFC PATCH v2 04/58] iommu/arm-smmu-v3: Move some definitions to
 arm64 include/
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-5-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

So that the KVM SMMUv3 driver can re-use architectural definitions,
command structures and feature bits, move them to the arm64 include/

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/include/asm/arm-smmu-v3-common.h | 547 ++++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 540 +------------------
 2 files changed, 549 insertions(+), 538 deletions(-)
 create mode 100644 arch/arm64/include/asm/arm-smmu-v3-common.h

diff --git a/arch/arm64/include/asm/arm-smmu-v3-common.h b/arch/arm64/include/asm/arm-smmu-v3-common.h
new file mode 100644
index 000000000000..e6e339248816
--- /dev/null
+++ b/arch/arm64/include/asm/arm-smmu-v3-common.h
@@ -0,0 +1,547 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ARM_SMMU_V3_COMMON_H
+#define _ARM_SMMU_V3_COMMON_H
+
+#include <linux/bitfield.h>
+
+/* MMIO registers */
+#define ARM_SMMU_IDR0			0x0
+#define IDR0_ST_LVL			GENMASK(28, 27)
+#define IDR0_ST_LVL_2LVL		1
+#define IDR0_STALL_MODEL		GENMASK(25, 24)
+#define IDR0_STALL_MODEL_STALL		0
+#define IDR0_STALL_MODEL_FORCE		2
+#define IDR0_TTENDIAN			GENMASK(22, 21)
+#define IDR0_TTENDIAN_MIXED		0
+#define IDR0_TTENDIAN_LE		2
+#define IDR0_TTENDIAN_BE		3
+#define IDR0_CD2L			(1 << 19)
+#define IDR0_VMID16			(1 << 18)
+#define IDR0_PRI			(1 << 16)
+#define IDR0_SEV			(1 << 14)
+#define IDR0_MSI			(1 << 13)
+#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
+#define IDR0_TTF_AARCH32_64		3
+#define IDR0_S1P			(1 << 1)
+#define IDR0_S2P			(1 << 0)
+
+#define ARM_SMMU_IDR1			0x4
+#define IDR1_TABLES_PRESET		(1 << 30)
+#define IDR1_QUEUES_PRESET		(1 << 29)
+#define IDR1_REL			(1 << 28)
+#define IDR1_ATTR_TYPES_OVR		(1 << 27)
+#define IDR1_CMDQS			GENMASK(25, 21)
+#define IDR1_EVTQS			GENMASK(20, 16)
+#define IDR1_PRIQS			GENMASK(15, 11)
+#define IDR1_SSIDSIZE			GENMASK(10, 6)
+#define IDR1_SIDSIZE			GENMASK(5, 0)
+
+#define ARM_SMMU_IDR3			0xc
+#define IDR3_RIL			(1 << 10)
+
+#define ARM_SMMU_IDR5			0x14
+#define IDR5_STALL_MAX			GENMASK(31, 16)
+#define IDR5_GRAN64K			(1 << 6)
+#define IDR5_GRAN16K			(1 << 5)
+#define IDR5_GRAN4K			(1 << 4)
+#define IDR5_OAS			GENMASK(2, 0)
+#define IDR5_OAS_32_BIT			0
+#define IDR5_OAS_36_BIT			1
+#define IDR5_OAS_40_BIT			2
+#define IDR5_OAS_42_BIT			3
+#define IDR5_OAS_44_BIT			4
+#define IDR5_OAS_48_BIT			5
+#define IDR5_OAS_52_BIT			6
+#define IDR5_VAX			GENMASK(11, 10)
+#define IDR5_VAX_52_BIT			1
+
+#define ARM_SMMU_IIDR			0x18
+#define IIDR_PRODUCTID			GENMASK(31, 20)
+#define IIDR_VARIANT			GENMASK(19, 16)
+#define IIDR_REVISION			GENMASK(15, 12)
+#define IIDR_IMPLEMENTER		GENMASK(11, 0)
+
+#define ARM_SMMU_CR0			0x20
+#define CR0_ATSCHK			(1 << 4)
+#define CR0_CMDQEN			(1 << 3)
+#define CR0_EVTQEN			(1 << 2)
+#define CR0_PRIQEN			(1 << 1)
+#define CR0_SMMUEN			(1 << 0)
+
+#define ARM_SMMU_CR0ACK			0x24
+
+#define ARM_SMMU_CR1			0x28
+#define CR1_TABLE_SH			GENMASK(11, 10)
+#define CR1_TABLE_OC			GENMASK(9, 8)
+#define CR1_TABLE_IC			GENMASK(7, 6)
+#define CR1_QUEUE_SH			GENMASK(5, 4)
+#define CR1_QUEUE_OC			GENMASK(3, 2)
+#define CR1_QUEUE_IC			GENMASK(1, 0)
+/* CR1 cacheability fields don't quite follow the usual TCR-style encoding */
+#define CR1_CACHE_NC			0
+#define CR1_CACHE_WB			1
+#define CR1_CACHE_WT			2
+
+#define ARM_SMMU_CR2			0x2c
+#define CR2_PTM				(1 << 2)
+#define CR2_RECINVSID			(1 << 1)
+#define CR2_E2H				(1 << 0)
+
+#define ARM_SMMU_GBPA			0x44
+#define GBPA_UPDATE			(1 << 31)
+#define GBPA_ABORT			(1 << 20)
+
+#define ARM_SMMU_IRQ_CTRL		0x50
+#define IRQ_CTRL_EVTQ_IRQEN		(1 << 2)
+#define IRQ_CTRL_PRIQ_IRQEN		(1 << 1)
+#define IRQ_CTRL_GERROR_IRQEN		(1 << 0)
+
+#define ARM_SMMU_IRQ_CTRLACK		0x54
+
+#define ARM_SMMU_GERROR			0x60
+#define GERROR_SFM_ERR			(1 << 8)
+#define GERROR_MSI_GERROR_ABT_ERR	(1 << 7)
+#define GERROR_MSI_PRIQ_ABT_ERR		(1 << 6)
+#define GERROR_MSI_EVTQ_ABT_ERR		(1 << 5)
+#define GERROR_MSI_CMDQ_ABT_ERR		(1 << 4)
+#define GERROR_PRIQ_ABT_ERR		(1 << 3)
+#define GERROR_EVTQ_ABT_ERR		(1 << 2)
+#define GERROR_CMDQ_ERR			(1 << 0)
+#define GERROR_ERR_MASK			0x1fd
+
+#define ARM_SMMU_GERRORN		0x64
+
+#define ARM_SMMU_GERROR_IRQ_CFG0	0x68
+#define ARM_SMMU_GERROR_IRQ_CFG1	0x70
+#define ARM_SMMU_GERROR_IRQ_CFG2	0x74
+
+#define ARM_SMMU_STRTAB_BASE		0x80
+#define STRTAB_BASE_RA			(1UL << 62)
+#define STRTAB_BASE_ADDR_MASK		GENMASK_ULL(51, 6)
+
+#define ARM_SMMU_STRTAB_BASE_CFG	0x88
+#define STRTAB_BASE_CFG_FMT		GENMASK(17, 16)
+#define STRTAB_BASE_CFG_FMT_LINEAR	0
+#define STRTAB_BASE_CFG_FMT_2LVL	1
+#define STRTAB_BASE_CFG_SPLIT		GENMASK(10, 6)
+#define STRTAB_BASE_CFG_LOG2SIZE	GENMASK(5, 0)
+
+#define ARM_SMMU_CMDQ_BASE		0x90
+#define ARM_SMMU_CMDQ_PROD		0x98
+#define ARM_SMMU_CMDQ_CONS		0x9c
+
+#define ARM_SMMU_EVTQ_BASE		0xa0
+#define ARM_SMMU_EVTQ_PROD		0xa8
+#define ARM_SMMU_EVTQ_CONS		0xac
+#define ARM_SMMU_EVTQ_IRQ_CFG0		0xb0
+#define ARM_SMMU_EVTQ_IRQ_CFG1		0xb8
+#define ARM_SMMU_EVTQ_IRQ_CFG2		0xbc
+
+#define ARM_SMMU_PRIQ_BASE		0xc0
+#define ARM_SMMU_PRIQ_PROD		0xc8
+#define ARM_SMMU_PRIQ_CONS		0xcc
+#define ARM_SMMU_PRIQ_IRQ_CFG0		0xd0
+#define ARM_SMMU_PRIQ_IRQ_CFG1		0xd8
+#define ARM_SMMU_PRIQ_IRQ_CFG2		0xdc
+
+#define ARM_SMMU_REG_SZ			0xe00
+
+/* Common MSI config fields */
+#define MSI_CFG0_ADDR_MASK		GENMASK_ULL(51, 2)
+#define MSI_CFG2_SH			GENMASK(5, 4)
+#define MSI_CFG2_MEMATTR		GENMASK(3, 0)
+
+/* Common memory attribute values */
+#define ARM_SMMU_SH_NSH			0
+#define ARM_SMMU_SH_OSH			2
+#define ARM_SMMU_SH_ISH			3
+#define ARM_SMMU_MEMATTR_DEVICE_nGnRE	0x1
+#define ARM_SMMU_MEMATTR_OIWB		0xf
+
+#define Q_BASE_RWA			(1UL << 62)
+#define Q_BASE_ADDR_MASK		GENMASK_ULL(51, 5)
+#define Q_BASE_LOG2SIZE			GENMASK(4, 0)
+
+/*
+ * Stream table.
+ *
+ * Linear: Enough to cover 1 << IDR1.SIDSIZE entries
+ * 2lvl: 128k L1 entries,
+ *       256 lazy entries per table (each table covers a PCI bus)
+ */
+#define STRTAB_SPLIT			8
+
+#define STRTAB_L1_DESC_SPAN		GENMASK_ULL(4, 0)
+#define STRTAB_L1_DESC_L2PTR_MASK	GENMASK_ULL(51, 6)
+
+#define STRTAB_STE_DWORDS		8
+
+struct arm_smmu_ste {
+	__le64 data[STRTAB_STE_DWORDS];
+};
+
+#define STRTAB_NUM_L2_STES		(1 << STRTAB_SPLIT)
+struct arm_smmu_strtab_l2 {
+	struct arm_smmu_ste stes[STRTAB_NUM_L2_STES];
+};
+
+struct arm_smmu_strtab_l1 {
+	__le64 l2ptr;
+};
+#define STRTAB_MAX_L1_ENTRIES		(1 << 17)
+
+static inline u32 arm_smmu_strtab_l1_idx(u32 sid)
+{
+	return sid / STRTAB_NUM_L2_STES;
+}
+
+static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
+{
+	return sid % STRTAB_NUM_L2_STES;
+}
+
+#define STRTAB_STE_0_V			(1UL << 0)
+#define STRTAB_STE_0_CFG		GENMASK_ULL(3, 1)
+#define STRTAB_STE_0_CFG_ABORT		0
+#define STRTAB_STE_0_CFG_BYPASS		4
+#define STRTAB_STE_0_CFG_S1_TRANS	5
+#define STRTAB_STE_0_CFG_S2_TRANS	6
+
+#define STRTAB_STE_0_S1FMT		GENMASK_ULL(5, 4)
+#define STRTAB_STE_0_S1FMT_LINEAR	0
+#define STRTAB_STE_0_S1FMT_64K_L2	2
+#define STRTAB_STE_0_S1CTXPTR_MASK	GENMASK_ULL(51, 6)
+#define STRTAB_STE_0_S1CDMAX		GENMASK_ULL(63, 59)
+
+#define STRTAB_STE_1_S1DSS		GENMASK_ULL(1, 0)
+#define STRTAB_STE_1_S1DSS_TERMINATE	0x0
+#define STRTAB_STE_1_S1DSS_BYPASS	0x1
+#define STRTAB_STE_1_S1DSS_SSID0	0x2
+
+#define STRTAB_STE_1_S1C_CACHE_NC	0UL
+#define STRTAB_STE_1_S1C_CACHE_WBRA	1UL
+#define STRTAB_STE_1_S1C_CACHE_WT	2UL
+#define STRTAB_STE_1_S1C_CACHE_WB	3UL
+#define STRTAB_STE_1_S1CIR		GENMASK_ULL(3, 2)
+#define STRTAB_STE_1_S1COR		GENMASK_ULL(5, 4)
+#define STRTAB_STE_1_S1CSH		GENMASK_ULL(7, 6)
+
+#define STRTAB_STE_1_S1STALLD		(1UL << 27)
+
+#define STRTAB_STE_1_EATS		GENMASK_ULL(29, 28)
+#define STRTAB_STE_1_EATS_ABT		0UL
+#define STRTAB_STE_1_EATS_TRANS		1UL
+#define STRTAB_STE_1_EATS_S1CHK		2UL
+
+#define STRTAB_STE_1_STRW		GENMASK_ULL(31, 30)
+#define STRTAB_STE_1_STRW_NSEL1		0UL
+#define STRTAB_STE_1_STRW_EL2		2UL
+
+#define STRTAB_STE_1_SHCFG		GENMASK_ULL(45, 44)
+#define STRTAB_STE_1_SHCFG_INCOMING	1UL
+
+#define STRTAB_STE_2_S2VMID		GENMASK_ULL(15, 0)
+#define STRTAB_STE_2_VTCR		GENMASK_ULL(50, 32)
+#define STRTAB_STE_2_VTCR_S2T0SZ	GENMASK_ULL(5, 0)
+#define STRTAB_STE_2_VTCR_S2SL0		GENMASK_ULL(7, 6)
+#define STRTAB_STE_2_VTCR_S2IR0		GENMASK_ULL(9, 8)
+#define STRTAB_STE_2_VTCR_S2OR0		GENMASK_ULL(11, 10)
+#define STRTAB_STE_2_VTCR_S2SH0		GENMASK_ULL(13, 12)
+#define STRTAB_STE_2_VTCR_S2TG		GENMASK_ULL(15, 14)
+#define STRTAB_STE_2_VTCR_S2PS		GENMASK_ULL(18, 16)
+#define STRTAB_STE_2_S2AA64		(1UL << 51)
+#define STRTAB_STE_2_S2ENDI		(1UL << 52)
+#define STRTAB_STE_2_S2PTW		(1UL << 54)
+#define STRTAB_STE_2_S2S		(1UL << 57)
+#define STRTAB_STE_2_S2R		(1UL << 58)
+
+#define STRTAB_STE_3_S2TTB_MASK		GENMASK_ULL(51, 4)
+
+/*
+ * Context descriptors.
+ *
+ * Linear: when less than 1024 SSIDs are supported
+ * 2lvl: at most 1024 L1 entries,
+ *       1024 lazy entries per table.
+ */
+#define CTXDESC_L2_ENTRIES		1024
+
+#define CTXDESC_L1_DESC_V		(1UL << 0)
+#define CTXDESC_L1_DESC_L2PTR_MASK	GENMASK_ULL(51, 12)
+
+#define CTXDESC_CD_DWORDS		8
+
+struct arm_smmu_cd {
+	__le64 data[CTXDESC_CD_DWORDS];
+};
+
+struct arm_smmu_cdtab_l2 {
+	struct arm_smmu_cd cds[CTXDESC_L2_ENTRIES];
+};
+
+struct arm_smmu_cdtab_l1 {
+	__le64 l2ptr;
+};
+
+static inline unsigned int arm_smmu_cdtab_l1_idx(unsigned int ssid)
+{
+	return ssid / CTXDESC_L2_ENTRIES;
+}
+
+static inline unsigned int arm_smmu_cdtab_l2_idx(unsigned int ssid)
+{
+	return ssid % CTXDESC_L2_ENTRIES;
+}
+
+#define CTXDESC_CD_0_TCR_T0SZ		GENMASK_ULL(5, 0)
+#define CTXDESC_CD_0_TCR_TG0		GENMASK_ULL(7, 6)
+#define CTXDESC_CD_0_TCR_IRGN0		GENMASK_ULL(9, 8)
+#define CTXDESC_CD_0_TCR_ORGN0		GENMASK_ULL(11, 10)
+#define CTXDESC_CD_0_TCR_SH0		GENMASK_ULL(13, 12)
+#define CTXDESC_CD_0_TCR_EPD0		(1ULL << 14)
+#define CTXDESC_CD_0_TCR_EPD1		(1ULL << 30)
+
+#define CTXDESC_CD_0_ENDI		(1UL << 15)
+#define CTXDESC_CD_0_V			(1UL << 31)
+
+#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)
+#define CTXDESC_CD_0_A			(1UL << 46)
+#define CTXDESC_CD_0_ASET		(1UL << 47)
+#define CTXDESC_CD_0_ASID		GENMASK_ULL(63, 48)
+
+#define CTXDESC_CD_1_TTB0_MASK		GENMASK_ULL(51, 4)
+
+/*
+ * When the SMMU only supports linear context descriptor tables, pick a
+ * reasonable size limit (64kB).
+ */
+#define CTXDESC_LINEAR_CDMAX		ilog2(SZ_64K / sizeof(struct arm_smmu_cd))
+
+/* Command queue */
+#define CMDQ_ENT_SZ_SHIFT		4
+#define CMDQ_ENT_DWORDS			((1 << CMDQ_ENT_SZ_SHIFT) >> 3)
+#define CMDQ_MAX_SZ_SHIFT		(Q_MAX_SZ_SHIFT - CMDQ_ENT_SZ_SHIFT)
+
+#define CMDQ_CONS_ERR			GENMASK(30, 24)
+#define CMDQ_ERR_CERROR_NONE_IDX	0
+#define CMDQ_ERR_CERROR_ILL_IDX		1
+#define CMDQ_ERR_CERROR_ABT_IDX		2
+#define CMDQ_ERR_CERROR_ATC_INV_IDX	3
+
+#define CMDQ_0_OP			GENMASK_ULL(7, 0)
+#define CMDQ_0_SSV			(1UL << 11)
+
+#define CMDQ_PREFETCH_0_SID		GENMASK_ULL(63, 32)
+#define CMDQ_PREFETCH_1_SIZE		GENMASK_ULL(4, 0)
+#define CMDQ_PREFETCH_1_ADDR_MASK	GENMASK_ULL(63, 12)
+
+#define CMDQ_CFGI_0_SSID		GENMASK_ULL(31, 12)
+#define CMDQ_CFGI_0_SID			GENMASK_ULL(63, 32)
+#define CMDQ_CFGI_1_LEAF		(1UL << 0)
+#define CMDQ_CFGI_1_RANGE		GENMASK_ULL(4, 0)
+
+#define CMDQ_TLBI_0_NUM			GENMASK_ULL(16, 12)
+#define CMDQ_TLBI_RANGE_NUM_MAX		31
+#define CMDQ_TLBI_0_SCALE		GENMASK_ULL(24, 20)
+#define CMDQ_TLBI_0_VMID		GENMASK_ULL(47, 32)
+#define CMDQ_TLBI_0_ASID		GENMASK_ULL(63, 48)
+#define CMDQ_TLBI_1_LEAF		(1UL << 0)
+#define CMDQ_TLBI_1_TTL			GENMASK_ULL(9, 8)
+#define CMDQ_TLBI_1_TG			GENMASK_ULL(11, 10)
+#define CMDQ_TLBI_1_VA_MASK		GENMASK_ULL(63, 12)
+#define CMDQ_TLBI_1_IPA_MASK		GENMASK_ULL(51, 12)
+
+#define CMDQ_ATC_0_SSID			GENMASK_ULL(31, 12)
+#define CMDQ_ATC_0_SID			GENMASK_ULL(63, 32)
+#define CMDQ_ATC_0_GLOBAL		(1UL << 9)
+#define CMDQ_ATC_1_SIZE			GENMASK_ULL(5, 0)
+#define CMDQ_ATC_1_ADDR_MASK		GENMASK_ULL(63, 12)
+
+#define CMDQ_PRI_0_SSID			GENMASK_ULL(31, 12)
+#define CMDQ_PRI_0_SID			GENMASK_ULL(63, 32)
+#define CMDQ_PRI_1_GRPID		GENMASK_ULL(8, 0)
+#define CMDQ_PRI_1_RESP			GENMASK_ULL(13, 12)
+
+#define CMDQ_RESUME_0_RESP_TERM		0UL
+#define CMDQ_RESUME_0_RESP_RETRY	1UL
+#define CMDQ_RESUME_0_RESP_ABORT	2UL
+#define CMDQ_RESUME_0_RESP		GENMASK_ULL(13, 12)
+#define CMDQ_RESUME_0_SID		GENMASK_ULL(63, 32)
+#define CMDQ_RESUME_1_STAG		GENMASK_ULL(15, 0)
+
+#define CMDQ_SYNC_0_CS			GENMASK_ULL(13, 12)
+#define CMDQ_SYNC_0_CS_NONE		0
+#define CMDQ_SYNC_0_CS_IRQ		1
+#define CMDQ_SYNC_0_CS_SEV		2
+#define CMDQ_SYNC_0_MSH			GENMASK_ULL(23, 22)
+#define CMDQ_SYNC_0_MSIATTR		GENMASK_ULL(27, 24)
+#define CMDQ_SYNC_0_MSIDATA		GENMASK_ULL(63, 32)
+#define CMDQ_SYNC_1_MSIADDR_MASK	GENMASK_ULL(51, 2)
+
+/* Event queue */
+#define EVTQ_ENT_SZ_SHIFT		5
+#define EVTQ_ENT_DWORDS			((1 << EVTQ_ENT_SZ_SHIFT) >> 3)
+#define EVTQ_MAX_SZ_SHIFT		(Q_MAX_SZ_SHIFT - EVTQ_ENT_SZ_SHIFT)
+
+#define EVTQ_0_ID			GENMASK_ULL(7, 0)
+
+#define EVT_ID_TRANSLATION_FAULT	0x10
+#define EVT_ID_ADDR_SIZE_FAULT		0x11
+#define EVT_ID_ACCESS_FAULT		0x12
+#define EVT_ID_PERMISSION_FAULT		0x13
+
+#define EVTQ_0_SSV			(1UL << 11)
+#define EVTQ_0_SSID			GENMASK_ULL(31, 12)
+#define EVTQ_0_SID			GENMASK_ULL(63, 32)
+#define EVTQ_1_STAG			GENMASK_ULL(15, 0)
+#define EVTQ_1_STALL			(1UL << 31)
+#define EVTQ_1_PnU			(1UL << 33)
+#define EVTQ_1_InD			(1UL << 34)
+#define EVTQ_1_RnW			(1UL << 35)
+#define EVTQ_1_S2			(1UL << 39)
+#define EVTQ_1_CLASS			GENMASK_ULL(41, 40)
+#define EVTQ_1_TT_READ			(1UL << 44)
+#define EVTQ_2_ADDR			GENMASK_ULL(63, 0)
+#define EVTQ_3_IPA			GENMASK_ULL(51, 12)
+
+/* PRI queue */
+#define PRIQ_ENT_SZ_SHIFT		4
+#define PRIQ_ENT_DWORDS			((1 << PRIQ_ENT_SZ_SHIFT) >> 3)
+#define PRIQ_MAX_SZ_SHIFT		(Q_MAX_SZ_SHIFT - PRIQ_ENT_SZ_SHIFT)
+
+#define PRIQ_0_SID			GENMASK_ULL(31, 0)
+#define PRIQ_0_SSID			GENMASK_ULL(51, 32)
+#define PRIQ_0_PERM_PRIV		(1UL << 58)
+#define PRIQ_0_PERM_EXEC		(1UL << 59)
+#define PRIQ_0_PERM_READ		(1UL << 60)
+#define PRIQ_0_PERM_WRITE		(1UL << 61)
+#define PRIQ_0_PRG_LAST			(1UL << 62)
+#define PRIQ_0_SSID_V			(1UL << 63)
+
+#define PRIQ_1_PRG_IDX			GENMASK_ULL(8, 0)
+#define PRIQ_1_ADDR_MASK		GENMASK_ULL(63, 12)
+
+/* Synthesized features */
+#define ARM_SMMU_FEAT_2_LVL_STRTAB	(1 << 0)
+#define ARM_SMMU_FEAT_2_LVL_CDTAB	(1 << 1)
+#define ARM_SMMU_FEAT_TT_LE		(1 << 2)
+#define ARM_SMMU_FEAT_TT_BE		(1 << 3)
+#define ARM_SMMU_FEAT_PRI		(1 << 4)
+#define ARM_SMMU_FEAT_ATS		(1 << 5)
+#define ARM_SMMU_FEAT_SEV		(1 << 6)
+#define ARM_SMMU_FEAT_MSI		(1 << 7)
+#define ARM_SMMU_FEAT_COHERENCY		(1 << 8)
+#define ARM_SMMU_FEAT_TRANS_S1		(1 << 9)
+#define ARM_SMMU_FEAT_TRANS_S2		(1 << 10)
+#define ARM_SMMU_FEAT_STALLS		(1 << 11)
+#define ARM_SMMU_FEAT_HYP		(1 << 12)
+#define ARM_SMMU_FEAT_STALL_FORCE	(1 << 13)
+#define ARM_SMMU_FEAT_VAX		(1 << 14)
+#define ARM_SMMU_FEAT_RANGE_INV		(1 << 15)
+#define ARM_SMMU_FEAT_BTM		(1 << 16)
+#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_ATTR_TYPES_OVR	(1 << 20)
+#define ARM_SMMU_FEAT_HA		(1 << 21)
+#define ARM_SMMU_FEAT_HD		(1 << 22)
+
+enum pri_resp {
+	PRI_RESP_DENY = 0,
+	PRI_RESP_FAIL = 1,
+	PRI_RESP_SUCC = 2,
+};
+
+struct arm_smmu_cmdq_ent {
+	/* Common fields */
+	u8				opcode;
+	bool				substream_valid;
+
+	/* Command-specific fields */
+	union {
+		#define CMDQ_OP_PREFETCH_CFG	0x1
+		struct {
+			u32			sid;
+		} prefetch;
+
+		#define CMDQ_OP_CFGI_STE	0x3
+		#define CMDQ_OP_CFGI_ALL	0x4
+		#define CMDQ_OP_CFGI_CD		0x5
+		#define CMDQ_OP_CFGI_CD_ALL	0x6
+		struct {
+			u32			sid;
+			u32			ssid;
+			union {
+				bool		leaf;
+				u8		span;
+			};
+		} cfgi;
+
+		#define CMDQ_OP_TLBI_NH_ASID	0x11
+		#define CMDQ_OP_TLBI_NH_VA	0x12
+		#define CMDQ_OP_TLBI_EL2_ALL	0x20
+		#define CMDQ_OP_TLBI_EL2_ASID	0x21
+		#define CMDQ_OP_TLBI_EL2_VA	0x22
+		#define CMDQ_OP_TLBI_S12_VMALL	0x28
+		#define CMDQ_OP_TLBI_S2_IPA	0x2a
+		#define CMDQ_OP_TLBI_NSNH_ALL	0x30
+		struct {
+			u8			num;
+			u8			scale;
+			u16			asid;
+			u16			vmid;
+			bool			leaf;
+			u8			ttl;
+			u8			tg;
+			u64			addr;
+		} tlbi;
+
+		#define CMDQ_OP_ATC_INV		0x40
+		#define ATC_INV_SIZE_ALL	52
+		struct {
+			u32			sid;
+			u32			ssid;
+			u64			addr;
+			u8			size;
+			bool			global;
+		} atc;
+
+		#define CMDQ_OP_PRI_RESP	0x41
+		struct {
+			u32			sid;
+			u32			ssid;
+			u16			grpid;
+			enum pri_resp		resp;
+		} pri;
+
+		#define CMDQ_OP_RESUME		0x44
+		struct {
+			u32			sid;
+			u16			stag;
+			u8			resp;
+		} resume;
+
+		#define CMDQ_OP_CMD_SYNC	0x46
+		struct {
+			u64			msiaddr;
+		} sync;
+	};
+};
+
+#endif /* _ARM_SMMU_V3_COMMON_H */
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 1e9952ca989f..fc1b8c2af2a2 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -8,7 +8,6 @@
 #ifndef _ARM_SMMU_V3_H
 #define _ARM_SMMU_V3_H
 
-#include <linux/bitfield.h>
 #include <linux/iommu.h>
 #include <linux/kernel.h>
 #include <linux/mmzone.h>
@@ -16,167 +15,7 @@
 
 struct arm_smmu_device;
 
-/* MMIO registers */
-#define ARM_SMMU_IDR0			0x0
-#define IDR0_ST_LVL			GENMASK(28, 27)
-#define IDR0_ST_LVL_2LVL		1
-#define IDR0_STALL_MODEL		GENMASK(25, 24)
-#define IDR0_STALL_MODEL_STALL		0
-#define IDR0_STALL_MODEL_FORCE		2
-#define IDR0_TTENDIAN			GENMASK(22, 21)
-#define IDR0_TTENDIAN_MIXED		0
-#define IDR0_TTENDIAN_LE		2
-#define IDR0_TTENDIAN_BE		3
-#define IDR0_CD2L			(1 << 19)
-#define IDR0_VMID16			(1 << 18)
-#define IDR0_PRI			(1 << 16)
-#define IDR0_SEV			(1 << 14)
-#define IDR0_MSI			(1 << 13)
-#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
-#define IDR0_TTF_AARCH32_64		3
-#define IDR0_S1P			(1 << 1)
-#define IDR0_S2P			(1 << 0)
-
-#define ARM_SMMU_IDR1			0x4
-#define IDR1_TABLES_PRESET		(1 << 30)
-#define IDR1_QUEUES_PRESET		(1 << 29)
-#define IDR1_REL			(1 << 28)
-#define IDR1_ATTR_TYPES_OVR		(1 << 27)
-#define IDR1_CMDQS			GENMASK(25, 21)
-#define IDR1_EVTQS			GENMASK(20, 16)
-#define IDR1_PRIQS			GENMASK(15, 11)
-#define IDR1_SSIDSIZE			GENMASK(10, 6)
-#define IDR1_SIDSIZE			GENMASK(5, 0)
-
-#define ARM_SMMU_IDR3			0xc
-#define IDR3_RIL			(1 << 10)
-
-#define ARM_SMMU_IDR5			0x14
-#define IDR5_STALL_MAX			GENMASK(31, 16)
-#define IDR5_GRAN64K			(1 << 6)
-#define IDR5_GRAN16K			(1 << 5)
-#define IDR5_GRAN4K			(1 << 4)
-#define IDR5_OAS			GENMASK(2, 0)
-#define IDR5_OAS_32_BIT			0
-#define IDR5_OAS_36_BIT			1
-#define IDR5_OAS_40_BIT			2
-#define IDR5_OAS_42_BIT			3
-#define IDR5_OAS_44_BIT			4
-#define IDR5_OAS_48_BIT			5
-#define IDR5_OAS_52_BIT			6
-#define IDR5_VAX			GENMASK(11, 10)
-#define IDR5_VAX_52_BIT			1
-
-#define ARM_SMMU_IIDR			0x18
-#define IIDR_PRODUCTID			GENMASK(31, 20)
-#define IIDR_VARIANT			GENMASK(19, 16)
-#define IIDR_REVISION			GENMASK(15, 12)
-#define IIDR_IMPLEMENTER		GENMASK(11, 0)
-
-#define ARM_SMMU_CR0			0x20
-#define CR0_ATSCHK			(1 << 4)
-#define CR0_CMDQEN			(1 << 3)
-#define CR0_EVTQEN			(1 << 2)
-#define CR0_PRIQEN			(1 << 1)
-#define CR0_SMMUEN			(1 << 0)
-
-#define ARM_SMMU_CR0ACK			0x24
-
-#define ARM_SMMU_CR1			0x28
-#define CR1_TABLE_SH			GENMASK(11, 10)
-#define CR1_TABLE_OC			GENMASK(9, 8)
-#define CR1_TABLE_IC			GENMASK(7, 6)
-#define CR1_QUEUE_SH			GENMASK(5, 4)
-#define CR1_QUEUE_OC			GENMASK(3, 2)
-#define CR1_QUEUE_IC			GENMASK(1, 0)
-/* CR1 cacheability fields don't quite follow the usual TCR-style encoding */
-#define CR1_CACHE_NC			0
-#define CR1_CACHE_WB			1
-#define CR1_CACHE_WT			2
-
-#define ARM_SMMU_CR2			0x2c
-#define CR2_PTM				(1 << 2)
-#define CR2_RECINVSID			(1 << 1)
-#define CR2_E2H				(1 << 0)
-
-#define ARM_SMMU_GBPA			0x44
-#define GBPA_UPDATE			(1 << 31)
-#define GBPA_ABORT			(1 << 20)
-
-#define ARM_SMMU_IRQ_CTRL		0x50
-#define IRQ_CTRL_EVTQ_IRQEN		(1 << 2)
-#define IRQ_CTRL_PRIQ_IRQEN		(1 << 1)
-#define IRQ_CTRL_GERROR_IRQEN		(1 << 0)
-
-#define ARM_SMMU_IRQ_CTRLACK		0x54
-
-#define ARM_SMMU_GERROR			0x60
-#define GERROR_SFM_ERR			(1 << 8)
-#define GERROR_MSI_GERROR_ABT_ERR	(1 << 7)
-#define GERROR_MSI_PRIQ_ABT_ERR		(1 << 6)
-#define GERROR_MSI_EVTQ_ABT_ERR		(1 << 5)
-#define GERROR_MSI_CMDQ_ABT_ERR		(1 << 4)
-#define GERROR_PRIQ_ABT_ERR		(1 << 3)
-#define GERROR_EVTQ_ABT_ERR		(1 << 2)
-#define GERROR_CMDQ_ERR			(1 << 0)
-#define GERROR_ERR_MASK			0x1fd
-
-#define ARM_SMMU_GERRORN		0x64
-
-#define ARM_SMMU_GERROR_IRQ_CFG0	0x68
-#define ARM_SMMU_GERROR_IRQ_CFG1	0x70
-#define ARM_SMMU_GERROR_IRQ_CFG2	0x74
-
-#define ARM_SMMU_STRTAB_BASE		0x80
-#define STRTAB_BASE_RA			(1UL << 62)
-#define STRTAB_BASE_ADDR_MASK		GENMASK_ULL(51, 6)
-
-#define ARM_SMMU_STRTAB_BASE_CFG	0x88
-#define STRTAB_BASE_CFG_FMT		GENMASK(17, 16)
-#define STRTAB_BASE_CFG_FMT_LINEAR	0
-#define STRTAB_BASE_CFG_FMT_2LVL	1
-#define STRTAB_BASE_CFG_SPLIT		GENMASK(10, 6)
-#define STRTAB_BASE_CFG_LOG2SIZE	GENMASK(5, 0)
-
-#define ARM_SMMU_CMDQ_BASE		0x90
-#define ARM_SMMU_CMDQ_PROD		0x98
-#define ARM_SMMU_CMDQ_CONS		0x9c
-
-#define ARM_SMMU_EVTQ_BASE		0xa0
-#define ARM_SMMU_EVTQ_PROD		0xa8
-#define ARM_SMMU_EVTQ_CONS		0xac
-#define ARM_SMMU_EVTQ_IRQ_CFG0		0xb0
-#define ARM_SMMU_EVTQ_IRQ_CFG1		0xb8
-#define ARM_SMMU_EVTQ_IRQ_CFG2		0xbc
-
-#define ARM_SMMU_PRIQ_BASE		0xc0
-#define ARM_SMMU_PRIQ_PROD		0xc8
-#define ARM_SMMU_PRIQ_CONS		0xcc
-#define ARM_SMMU_PRIQ_IRQ_CFG0		0xd0
-#define ARM_SMMU_PRIQ_IRQ_CFG1		0xd8
-#define ARM_SMMU_PRIQ_IRQ_CFG2		0xdc
-
-#define ARM_SMMU_REG_SZ			0xe00
-
-/* Common MSI config fields */
-#define MSI_CFG0_ADDR_MASK		GENMASK_ULL(51, 2)
-#define MSI_CFG2_SH			GENMASK(5, 4)
-#define MSI_CFG2_MEMATTR		GENMASK(3, 0)
-
-/* Common memory attribute values */
-#define ARM_SMMU_SH_NSH			0
-#define ARM_SMMU_SH_OSH			2
-#define ARM_SMMU_SH_ISH			3
-#define ARM_SMMU_MEMATTR_DEVICE_nGnRE	0x1
-#define ARM_SMMU_MEMATTR_OIWB		0xf
+#include <asm/arm-smmu-v3-common.h>
 
 #define Q_IDX(llq, p)			((p) & ((1 << (llq)->max_n_shift) - 1))
 #define Q_WRP(llq, p)			((p) & (1 << (llq)->max_n_shift))
@@ -186,10 +25,6 @@ struct arm_smmu_device;
 					 Q_IDX(&((q)->llq), p) *	\
 					 (q)->ent_dwords)
 
-#define Q_BASE_RWA			(1UL << 62)
-#define Q_BASE_ADDR_MASK		GENMASK_ULL(51, 5)
-#define Q_BASE_LOG2SIZE			GENMASK(4, 0)
-
 /* Ensure DMA allocations are naturally aligned */
 #ifdef CONFIG_CMA_ALIGNMENT
 #define Q_MAX_SZ_SHIFT			(PAGE_SHIFT + CONFIG_CMA_ALIGNMENT)
@@ -197,180 +32,6 @@ struct arm_smmu_device;
 #define Q_MAX_SZ_SHIFT			(PAGE_SHIFT + MAX_PAGE_ORDER)
 #endif
 
-/*
- * Stream table.
- *
- * Linear: Enough to cover 1 << IDR1.SIDSIZE entries
- * 2lvl: 128k L1 entries,
- *       256 lazy entries per table (each table covers a PCI bus)
- */
-#define STRTAB_SPLIT			8
-
-#define STRTAB_L1_DESC_SPAN		GENMASK_ULL(4, 0)
-#define STRTAB_L1_DESC_L2PTR_MASK	GENMASK_ULL(51, 6)
-
-#define STRTAB_STE_DWORDS		8
-
-struct arm_smmu_ste {
-	__le64 data[STRTAB_STE_DWORDS];
-};
-
-#define STRTAB_NUM_L2_STES		(1 << STRTAB_SPLIT)
-struct arm_smmu_strtab_l2 {
-	struct arm_smmu_ste stes[STRTAB_NUM_L2_STES];
-};
-
-struct arm_smmu_strtab_l1 {
-	__le64 l2ptr;
-};
-#define STRTAB_MAX_L1_ENTRIES		(1 << 17)
-
-static inline u32 arm_smmu_strtab_l1_idx(u32 sid)
-{
-	return sid / STRTAB_NUM_L2_STES;
-}
-
-static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
-{
-	return sid % STRTAB_NUM_L2_STES;
-}
-
-#define STRTAB_STE_0_V			(1UL << 0)
-#define STRTAB_STE_0_CFG		GENMASK_ULL(3, 1)
-#define STRTAB_STE_0_CFG_ABORT		0
-#define STRTAB_STE_0_CFG_BYPASS		4
-#define STRTAB_STE_0_CFG_S1_TRANS	5
-#define STRTAB_STE_0_CFG_S2_TRANS	6
-
-#define STRTAB_STE_0_S1FMT		GENMASK_ULL(5, 4)
-#define STRTAB_STE_0_S1FMT_LINEAR	0
-#define STRTAB_STE_0_S1FMT_64K_L2	2
-#define STRTAB_STE_0_S1CTXPTR_MASK	GENMASK_ULL(51, 6)
-#define STRTAB_STE_0_S1CDMAX		GENMASK_ULL(63, 59)
-
-#define STRTAB_STE_1_S1DSS		GENMASK_ULL(1, 0)
-#define STRTAB_STE_1_S1DSS_TERMINATE	0x0
-#define STRTAB_STE_1_S1DSS_BYPASS	0x1
-#define STRTAB_STE_1_S1DSS_SSID0	0x2
-
-#define STRTAB_STE_1_S1C_CACHE_NC	0UL
-#define STRTAB_STE_1_S1C_CACHE_WBRA	1UL
-#define STRTAB_STE_1_S1C_CACHE_WT	2UL
-#define STRTAB_STE_1_S1C_CACHE_WB	3UL
-#define STRTAB_STE_1_S1CIR		GENMASK_ULL(3, 2)
-#define STRTAB_STE_1_S1COR		GENMASK_ULL(5, 4)
-#define STRTAB_STE_1_S1CSH		GENMASK_ULL(7, 6)
-
-#define STRTAB_STE_1_S1STALLD		(1UL << 27)
-
-#define STRTAB_STE_1_EATS		GENMASK_ULL(29, 28)
-#define STRTAB_STE_1_EATS_ABT		0UL
-#define STRTAB_STE_1_EATS_TRANS		1UL
-#define STRTAB_STE_1_EATS_S1CHK		2UL
-
-#define STRTAB_STE_1_STRW		GENMASK_ULL(31, 30)
-#define STRTAB_STE_1_STRW_NSEL1		0UL
-#define STRTAB_STE_1_STRW_EL2		2UL
-
-#define STRTAB_STE_1_SHCFG		GENMASK_ULL(45, 44)
-#define STRTAB_STE_1_SHCFG_INCOMING	1UL
-
-#define STRTAB_STE_2_S2VMID		GENMASK_ULL(15, 0)
-#define STRTAB_STE_2_VTCR		GENMASK_ULL(50, 32)
-#define STRTAB_STE_2_VTCR_S2T0SZ	GENMASK_ULL(5, 0)
-#define STRTAB_STE_2_VTCR_S2SL0		GENMASK_ULL(7, 6)
-#define STRTAB_STE_2_VTCR_S2IR0		GENMASK_ULL(9, 8)
-#define STRTAB_STE_2_VTCR_S2OR0		GENMASK_ULL(11, 10)
-#define STRTAB_STE_2_VTCR_S2SH0		GENMASK_ULL(13, 12)
-#define STRTAB_STE_2_VTCR_S2TG		GENMASK_ULL(15, 14)
-#define STRTAB_STE_2_VTCR_S2PS		GENMASK_ULL(18, 16)
-#define STRTAB_STE_2_S2AA64		(1UL << 51)
-#define STRTAB_STE_2_S2ENDI		(1UL << 52)
-#define STRTAB_STE_2_S2PTW		(1UL << 54)
-#define STRTAB_STE_2_S2S		(1UL << 57)
-#define STRTAB_STE_2_S2R		(1UL << 58)
-
-#define STRTAB_STE_3_S2TTB_MASK		GENMASK_ULL(51, 4)
-
-/*
- * Context descriptors.
- *
- * Linear: when less than 1024 SSIDs are supported
- * 2lvl: at most 1024 L1 entries,
- *       1024 lazy entries per table.
- */
-#define CTXDESC_L2_ENTRIES		1024
-
-#define CTXDESC_L1_DESC_V		(1UL << 0)
-#define CTXDESC_L1_DESC_L2PTR_MASK	GENMASK_ULL(51, 12)
-
-#define CTXDESC_CD_DWORDS		8
-
-struct arm_smmu_cd {
-	__le64 data[CTXDESC_CD_DWORDS];
-};
-
-struct arm_smmu_cdtab_l2 {
-	struct arm_smmu_cd cds[CTXDESC_L2_ENTRIES];
-};
-
-struct arm_smmu_cdtab_l1 {
-	__le64 l2ptr;
-};
-
-static inline unsigned int arm_smmu_cdtab_l1_idx(unsigned int ssid)
-{
-	return ssid / CTXDESC_L2_ENTRIES;
-}
-
-static inline unsigned int arm_smmu_cdtab_l2_idx(unsigned int ssid)
-{
-	return ssid % CTXDESC_L2_ENTRIES;
-}
-
-#define CTXDESC_CD_0_TCR_T0SZ		GENMASK_ULL(5, 0)
-#define CTXDESC_CD_0_TCR_TG0		GENMASK_ULL(7, 6)
-#define CTXDESC_CD_0_TCR_IRGN0		GENMASK_ULL(9, 8)
-#define CTXDESC_CD_0_TCR_ORGN0		GENMASK_ULL(11, 10)
-#define CTXDESC_CD_0_TCR_SH0		GENMASK_ULL(13, 12)
-#define CTXDESC_CD_0_TCR_EPD0		(1ULL << 14)
-#define CTXDESC_CD_0_TCR_EPD1		(1ULL << 30)
-
-#define CTXDESC_CD_0_ENDI		(1UL << 15)
-#define CTXDESC_CD_0_V			(1UL << 31)
-
-#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)
-#define CTXDESC_CD_0_A			(1UL << 46)
-#define CTXDESC_CD_0_ASET		(1UL << 47)
-#define CTXDESC_CD_0_ASID		GENMASK_ULL(63, 48)
-
-#define CTXDESC_CD_1_TTB0_MASK		GENMASK_ULL(51, 4)
-
-/*
- * When the SMMU only supports linear context descriptor tables, pick a
- * reasonable size limit (64kB).
- */
-#define CTXDESC_LINEAR_CDMAX		ilog2(SZ_64K / sizeof(struct arm_smmu_cd))
-
-/* Command queue */
-#define CMDQ_ENT_SZ_SHIFT		4
-#define CMDQ_ENT_DWORDS			((1 << CMDQ_ENT_SZ_SHIFT) >> 3)
-#define CMDQ_MAX_SZ_SHIFT		(Q_MAX_SZ_SHIFT - CMDQ_ENT_SZ_SHIFT)
-
-#define CMDQ_CONS_ERR			GENMASK(30, 24)
-#define CMDQ_ERR_CERROR_NONE_IDX	0
-#define CMDQ_ERR_CERROR_ILL_IDX		1
-#define CMDQ_ERR_CERROR_ABT_IDX		2
-#define CMDQ_ERR_CERROR_ATC_INV_IDX	3
-
 #define CMDQ_PROD_OWNED_FLAG		Q_OVERFLOW_FLAG
 
 /*
@@ -380,99 +41,6 @@ static inline unsigned int arm_smmu_cdtab_l2_idx(unsigned int ssid)
  */
 #define CMDQ_BATCH_ENTRIES		BITS_PER_LONG
 
-#define CMDQ_0_OP			GENMASK_ULL(7, 0)
-#define CMDQ_0_SSV			(1UL << 11)
-
-#define CMDQ_PREFETCH_0_SID		GENMASK_ULL(63, 32)
-#define CMDQ_PREFETCH_1_SIZE		GENMASK_ULL(4, 0)
-#define CMDQ_PREFETCH_1_ADDR_MASK	GENMASK_ULL(63, 12)
-
-#define CMDQ_CFGI_0_SSID		GENMASK_ULL(31, 12)
-#define CMDQ_CFGI_0_SID			GENMASK_ULL(63, 32)
-#define CMDQ_CFGI_1_LEAF		(1UL << 0)
-#define CMDQ_CFGI_1_RANGE		GENMASK_ULL(4, 0)
-
-#define CMDQ_TLBI_0_NUM			GENMASK_ULL(16, 12)
-#define CMDQ_TLBI_RANGE_NUM_MAX		31
-#define CMDQ_TLBI_0_SCALE		GENMASK_ULL(24, 20)
-#define CMDQ_TLBI_0_VMID		GENMASK_ULL(47, 32)
-#define CMDQ_TLBI_0_ASID		GENMASK_ULL(63, 48)
-#define CMDQ_TLBI_1_LEAF		(1UL << 0)
-#define CMDQ_TLBI_1_TTL			GENMASK_ULL(9, 8)
-#define CMDQ_TLBI_1_TG			GENMASK_ULL(11, 10)
-#define CMDQ_TLBI_1_VA_MASK		GENMASK_ULL(63, 12)
-#define CMDQ_TLBI_1_IPA_MASK		GENMASK_ULL(51, 12)
-
-#define CMDQ_ATC_0_SSID			GENMASK_ULL(31, 12)
-#define CMDQ_ATC_0_SID			GENMASK_ULL(63, 32)
-#define CMDQ_ATC_0_GLOBAL		(1UL << 9)
-#define CMDQ_ATC_1_SIZE			GENMASK_ULL(5, 0)
-#define CMDQ_ATC_1_ADDR_MASK		GENMASK_ULL(63, 12)
-
-#define CMDQ_PRI_0_SSID			GENMASK_ULL(31, 12)
-#define CMDQ_PRI_0_SID			GENMASK_ULL(63, 32)
-#define CMDQ_PRI_1_GRPID		GENMASK_ULL(8, 0)
-#define CMDQ_PRI_1_RESP			GENMASK_ULL(13, 12)
-
-#define CMDQ_RESUME_0_RESP_TERM		0UL
-#define CMDQ_RESUME_0_RESP_RETRY	1UL
-#define CMDQ_RESUME_0_RESP_ABORT	2UL
-#define CMDQ_RESUME_0_RESP		GENMASK_ULL(13, 12)
-#define CMDQ_RESUME_0_SID		GENMASK_ULL(63, 32)
-#define CMDQ_RESUME_1_STAG		GENMASK_ULL(15, 0)
-
-#define CMDQ_SYNC_0_CS			GENMASK_ULL(13, 12)
-#define CMDQ_SYNC_0_CS_NONE		0
-#define CMDQ_SYNC_0_CS_IRQ		1
-#define CMDQ_SYNC_0_CS_SEV		2
-#define CMDQ_SYNC_0_MSH			GENMASK_ULL(23, 22)
-#define CMDQ_SYNC_0_MSIATTR		GENMASK_ULL(27, 24)
-#define CMDQ_SYNC_0_MSIDATA		GENMASK_ULL(63, 32)
-#define CMDQ_SYNC_1_MSIADDR_MASK	GENMASK_ULL(51, 2)
-
-/* Event queue */
-#define EVTQ_ENT_SZ_SHIFT		5
-#define EVTQ_ENT_DWORDS			((1 << EVTQ_ENT_SZ_SHIFT) >> 3)
-#define EVTQ_MAX_SZ_SHIFT		(Q_MAX_SZ_SHIFT - EVTQ_ENT_SZ_SHIFT)
-
-#define EVTQ_0_ID			GENMASK_ULL(7, 0)
-
-#define EVT_ID_TRANSLATION_FAULT	0x10
-#define EVT_ID_ADDR_SIZE_FAULT		0x11
-#define EVT_ID_ACCESS_FAULT		0x12
-#define EVT_ID_PERMISSION_FAULT		0x13
-
-#define EVTQ_0_SSV			(1UL << 11)
-#define EVTQ_0_SSID			GENMASK_ULL(31, 12)
-#define EVTQ_0_SID			GENMASK_ULL(63, 32)
-#define EVTQ_1_STAG			GENMASK_ULL(15, 0)
-#define EVTQ_1_STALL			(1UL << 31)
-#define EVTQ_1_PnU			(1UL << 33)
-#define EVTQ_1_InD			(1UL << 34)
-#define EVTQ_1_RnW			(1UL << 35)
-#define EVTQ_1_S2			(1UL << 39)
-#define EVTQ_1_CLASS			GENMASK_ULL(41, 40)
-#define EVTQ_1_TT_READ			(1UL << 44)
-#define EVTQ_2_ADDR			GENMASK_ULL(63, 0)
-#define EVTQ_3_IPA			GENMASK_ULL(51, 12)
-
-/* PRI queue */
-#define PRIQ_ENT_SZ_SHIFT		4
-#define PRIQ_ENT_DWORDS			((1 << PRIQ_ENT_SZ_SHIFT) >> 3)
-#define PRIQ_MAX_SZ_SHIFT		(Q_MAX_SZ_SHIFT - PRIQ_ENT_SZ_SHIFT)
-
-#define PRIQ_0_SID			GENMASK_ULL(31, 0)
-#define PRIQ_0_SSID			GENMASK_ULL(51, 32)
-#define PRIQ_0_PERM_PRIV		(1UL << 58)
-#define PRIQ_0_PERM_EXEC		(1UL << 59)
-#define PRIQ_0_PERM_READ		(1UL << 60)
-#define PRIQ_0_PERM_WRITE		(1UL << 61)
-#define PRIQ_0_PRG_LAST			(1UL << 62)
-#define PRIQ_0_SSID_V			(1UL << 63)
-
-#define PRIQ_1_PRG_IDX			GENMASK_ULL(8, 0)
-#define PRIQ_1_ADDR_MASK		GENMASK_ULL(63, 12)
-
 /* High-level queue structures */
 #define ARM_SMMU_POLL_TIMEOUT_US	1000000 /* 1s! */
 #define ARM_SMMU_POLL_SPIN_COUNT	10
@@ -480,88 +48,6 @@ static inline unsigned int arm_smmu_cdtab_l2_idx(unsigned int ssid)
 #define MSI_IOVA_BASE			0x8000000
 #define MSI_IOVA_LENGTH			0x100000
 
-enum pri_resp {
-	PRI_RESP_DENY = 0,
-	PRI_RESP_FAIL = 1,
-	PRI_RESP_SUCC = 2,
-};
-
-struct arm_smmu_cmdq_ent {
-	/* Common fields */
-	u8				opcode;
-	bool				substream_valid;
-
-	/* Command-specific fields */
-	union {
-		#define CMDQ_OP_PREFETCH_CFG	0x1
-		struct {
-			u32			sid;
-		} prefetch;
-
-		#define CMDQ_OP_CFGI_STE	0x3
-		#define CMDQ_OP_CFGI_ALL	0x4
-		#define CMDQ_OP_CFGI_CD		0x5
-		#define CMDQ_OP_CFGI_CD_ALL	0x6
-		struct {
-			u32			sid;
-			u32			ssid;
-			union {
-				bool		leaf;
-				u8		span;
-			};
-		} cfgi;
-
-		#define CMDQ_OP_TLBI_NH_ASID	0x11
-		#define CMDQ_OP_TLBI_NH_VA	0x12
-		#define CMDQ_OP_TLBI_EL2_ALL	0x20
-		#define CMDQ_OP_TLBI_EL2_ASID	0x21
-		#define CMDQ_OP_TLBI_EL2_VA	0x22
-		#define CMDQ_OP_TLBI_S12_VMALL	0x28
-		#define CMDQ_OP_TLBI_S2_IPA	0x2a
-		#define CMDQ_OP_TLBI_NSNH_ALL	0x30
-		struct {
-			u8			num;
-			u8			scale;
-			u16			asid;
-			u16			vmid;
-			bool			leaf;
-			u8			ttl;
-			u8			tg;
-			u64			addr;
-		} tlbi;
-
-		#define CMDQ_OP_ATC_INV		0x40
-		#define ATC_INV_SIZE_ALL	52
-		struct {
-			u32			sid;
-			u32			ssid;
-			u64			addr;
-			u8			size;
-			bool			global;
-		} atc;
-
-		#define CMDQ_OP_PRI_RESP	0x41
-		struct {
-			u32			sid;
-			u32			ssid;
-			u16			grpid;
-			enum pri_resp		resp;
-		} pri;
-
-		#define CMDQ_OP_RESUME		0x44
-		struct {
-			u32			sid;
-			u16			stag;
-			u8			resp;
-		} resume;
-
-		#define CMDQ_OP_CMD_SYNC	0x46
-		struct {
-			u64			msiaddr;
-		} sync;
-	};
-};
-
 struct arm_smmu_ll_queue {
 	union {
 		u64			val;
@@ -703,29 +189,7 @@ struct arm_smmu_device {
 	void __iomem			*base;
 	void __iomem			*page1;
 
-#define ARM_SMMU_FEAT_2_LVL_STRTAB	(1 << 0)
-#define ARM_SMMU_FEAT_2_LVL_CDTAB	(1 << 1)
-#define ARM_SMMU_FEAT_TT_LE		(1 << 2)
-#define ARM_SMMU_FEAT_TT_BE		(1 << 3)
-#define ARM_SMMU_FEAT_PRI		(1 << 4)
-#define ARM_SMMU_FEAT_ATS		(1 << 5)
-#define ARM_SMMU_FEAT_SEV		(1 << 6)
-#define ARM_SMMU_FEAT_MSI		(1 << 7)
-#define ARM_SMMU_FEAT_COHERENCY		(1 << 8)
-#define ARM_SMMU_FEAT_TRANS_S1		(1 << 9)
-#define ARM_SMMU_FEAT_TRANS_S2		(1 << 10)
-#define ARM_SMMU_FEAT_STALLS		(1 << 11)
-#define ARM_SMMU_FEAT_HYP		(1 << 12)
-#define ARM_SMMU_FEAT_STALL_FORCE	(1 << 13)
-#define ARM_SMMU_FEAT_VAX		(1 << 14)
-#define ARM_SMMU_FEAT_RANGE_INV		(1 << 15)
-#define ARM_SMMU_FEAT_BTM		(1 << 16)
-#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_ATTR_TYPES_OVR	(1 << 20)
-#define ARM_SMMU_FEAT_HA		(1 << 21)
-#define ARM_SMMU_FEAT_HD		(1 << 22)
+	/* See arm-smmu-v3-common.h*/
 	u32				features;
 
 #define ARM_SMMU_OPT_SKIP_PREFETCH	(1 << 0)
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:29 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:29 +0000
Subject: [RFC PATCH v2 05/58] iommu/arm-smmu-v3: Extract driver-specific bits
 from probe function
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-6-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

As we're about to share the arm_smmu_device_hw_probe() function with the
KVM driver, extract bits that are specific to the normal driver.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 21 ++++++++++++---------
 1 file changed, 12 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 737c5b882355..702863c94f91 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4167,7 +4167,7 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 
 	if (reg & IDR0_MSI) {
 		smmu->features |= ARM_SMMU_FEAT_MSI;
-		if (coherent && !disable_msipolling)
+		if (coherent)
 			smmu->options |= ARM_SMMU_OPT_MSIPOLL;
 	}
 
@@ -4316,11 +4316,6 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 		smmu->oas = 48;
 	}
 
-	if (arm_smmu_ops.pgsize_bitmap == -1UL)
-		arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap;
-	else
-		arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap;
-
 	/* Set the DMA mask for our table walker */
 	if (dma_set_mask_and_coherent(smmu->dev, DMA_BIT_MASK(smmu->oas)))
 		dev_warn(smmu->dev,
@@ -4334,9 +4329,6 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 
 	arm_smmu_device_iidr_probe(smmu);
 
-	if (arm_smmu_sva_supported(smmu))
-		smmu->features |= ARM_SMMU_FEAT_SVA;
-
 	dev_info(smmu->dev, "ias %lu-bit, oas %lu-bit (features 0x%08x)\n",
 		 smmu->ias, smmu->oas, smmu->features);
 	return 0;
@@ -4606,6 +4598,17 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (arm_smmu_sva_supported(smmu))
+		smmu->features |= ARM_SMMU_FEAT_SVA;
+
+	if (disable_msipolling)
+		smmu->options &= ~ARM_SMMU_OPT_MSIPOLL;
+
+	if (arm_smmu_ops.pgsize_bitmap == -1UL)
+		arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap;
+	else
+		arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap;
+
 	/* Initialise in-memory data structures */
 	ret = arm_smmu_init_structures(smmu);
 	if (ret)
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:30 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:30 +0000
Subject: [RFC PATCH v2 06/58] iommu/arm-smmu-v3: Move some functions to arm-smmu-v3-common.c
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-7-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Move functions that can be shared between normal and KVM drivers to
arm-smmu-v3-common.c

Only straightforward moves here. More subtle factoring will be done in
then next patches.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/arm/arm-smmu-v3/Makefile        |   1 +
 .../arm/arm-smmu-v3/arm-smmu-v3-common.c      | 365 ++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 363 -----------------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  11 +
 4 files changed, 377 insertions(+), 363 deletions(-)
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-common.c

diff --git a/drivers/iommu/arm/arm-smmu-v3/Makefile b/drivers/iommu/arm/arm-smmu-v3/Makefile
index dc98c88b48c8..515a84f14783 100644
--- a/drivers/iommu/arm/arm-smmu-v3/Makefile
+++ b/drivers/iommu/arm/arm-smmu-v3/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_ARM_SMMU_V3) += arm_smmu_v3.o
 arm_smmu_v3-y := arm-smmu-v3.o
+arm_smmu_v3-y += arm-smmu-v3-common.o
 arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_SVA) += arm-smmu-v3-sva.o
 arm_smmu_v3-$(CONFIG_TEGRA241_CMDQV) += tegra241-cmdqv.o
 
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
new file mode 100644
index 000000000000..cfd5ba69e67e
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-common.c
@@ -0,0 +1,365 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
+#include <linux/pci.h>
+
+#include "arm-smmu-v3.h"
+#include "../../dma-iommu.h"
+
+#define IIDR_IMPLEMENTER_ARM		0x43b
+#define IIDR_PRODUCTID_ARM_MMU_600	0x483
+#define IIDR_PRODUCTID_ARM_MMU_700	0x487
+
+static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
+{
+	u32 reg;
+	unsigned int implementer, productid, variant, revision;
+
+	reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR);
+	implementer = FIELD_GET(IIDR_IMPLEMENTER, reg);
+	productid = FIELD_GET(IIDR_PRODUCTID, reg);
+	variant = FIELD_GET(IIDR_VARIANT, reg);
+	revision = FIELD_GET(IIDR_REVISION, reg);
+
+	switch (implementer) {
+	case IIDR_IMPLEMENTER_ARM:
+		switch (productid) {
+		case IIDR_PRODUCTID_ARM_MMU_600:
+			/* Arm erratum 1076982 */
+			if (variant == 0 && revision <= 2)
+				smmu->features &= ~ARM_SMMU_FEAT_SEV;
+			/* Arm erratum 1209401 */
+			if (variant < 2)
+				smmu->features &= ~ARM_SMMU_FEAT_NESTING;
+			break;
+		case IIDR_PRODUCTID_ARM_MMU_700:
+			/* Arm erratum 2812531 */
+			smmu->features &= ~ARM_SMMU_FEAT_BTM;
+			smmu->options |= ARM_SMMU_OPT_CMDQ_FORCE_SYNC;
+			/* Arm errata 2268618, 2812531 */
+			smmu->features &= ~ARM_SMMU_FEAT_NESTING;
+			break;
+		}
+		break;
+	}
+}
+
+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 hw_features = 0;
+
+	switch (FIELD_GET(IDR0_HTTU, reg)) {
+	case IDR0_HTTU_ACCESS_DIRTY:
+		hw_features |= ARM_SMMU_FEAT_HD;
+		fallthrough;
+	case IDR0_HTTU_ACCESS:
+		hw_features |= ARM_SMMU_FEAT_HA;
+	}
+
+	if (smmu->dev->of_node)
+		smmu->features |= hw_features;
+	else if (hw_features != fw_features)
+		/* ACPI IORT sets the HTTU bits */
+		dev_warn(smmu->dev,
+			 "IDR0.HTTU features(0x%x) overridden by FW configuration (0x%x)\n",
+			  hw_features, fw_features);
+}
+
+int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
+{
+	u32 reg;
+	bool coherent = smmu->features & ARM_SMMU_FEAT_COHERENCY;
+
+	/* IDR0 */
+	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0);
+
+	/* 2-level structures */
+	if (FIELD_GET(IDR0_ST_LVL, reg) == IDR0_ST_LVL_2LVL)
+		smmu->features |= ARM_SMMU_FEAT_2_LVL_STRTAB;
+
+	if (reg & IDR0_CD2L)
+		smmu->features |= ARM_SMMU_FEAT_2_LVL_CDTAB;
+
+	/*
+	 * Translation table endianness.
+	 * We currently require the same endianness as the CPU, but this
+	 * could be changed later by adding a new IO_PGTABLE_QUIRK.
+	 */
+	switch (FIELD_GET(IDR0_TTENDIAN, reg)) {
+	case IDR0_TTENDIAN_MIXED:
+		smmu->features |= ARM_SMMU_FEAT_TT_LE | ARM_SMMU_FEAT_TT_BE;
+		break;
+#ifdef __BIG_ENDIAN
+	case IDR0_TTENDIAN_BE:
+		smmu->features |= ARM_SMMU_FEAT_TT_BE;
+		break;
+#else
+	case IDR0_TTENDIAN_LE:
+		smmu->features |= ARM_SMMU_FEAT_TT_LE;
+		break;
+#endif
+	default:
+		dev_err(smmu->dev, "unknown/unsupported TT endianness!\n");
+		return -ENXIO;
+	}
+
+	/* Boolean feature flags */
+	if (IS_ENABLED(CONFIG_PCI_PRI) && reg & IDR0_PRI)
+		smmu->features |= ARM_SMMU_FEAT_PRI;
+
+	if (IS_ENABLED(CONFIG_PCI_ATS) && reg & IDR0_ATS)
+		smmu->features |= ARM_SMMU_FEAT_ATS;
+
+	if (reg & IDR0_SEV)
+		smmu->features |= ARM_SMMU_FEAT_SEV;
+
+	if (reg & IDR0_MSI) {
+		smmu->features |= ARM_SMMU_FEAT_MSI;
+		if (coherent)
+			smmu->options |= ARM_SMMU_OPT_MSIPOLL;
+	}
+
+	if (reg & IDR0_HYP) {
+		smmu->features |= ARM_SMMU_FEAT_HYP;
+		if (cpus_have_cap(ARM64_HAS_VIRT_HOST_EXTN))
+			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.
+	 */
+	if (!!(reg & IDR0_COHACC) != coherent)
+		dev_warn(smmu->dev, "IDR0.COHACC overridden by FW configuration (%s)\n",
+			 coherent ? "true" : "false");
+
+	switch (FIELD_GET(IDR0_STALL_MODEL, reg)) {
+	case IDR0_STALL_MODEL_FORCE:
+		smmu->features |= ARM_SMMU_FEAT_STALL_FORCE;
+		fallthrough;
+	case IDR0_STALL_MODEL_STALL:
+		smmu->features |= ARM_SMMU_FEAT_STALLS;
+	}
+
+	if (reg & IDR0_S1P)
+		smmu->features |= ARM_SMMU_FEAT_TRANS_S1;
+
+	if (reg & IDR0_S2P)
+		smmu->features |= ARM_SMMU_FEAT_TRANS_S2;
+
+	if (!(reg & (IDR0_S1P | IDR0_S2P))) {
+		dev_err(smmu->dev, "no translation support!\n");
+		return -ENXIO;
+	}
+
+	/* We only support the AArch64 table format at present */
+	switch (FIELD_GET(IDR0_TTF, reg)) {
+	case IDR0_TTF_AARCH32_64:
+		smmu->ias = 40;
+		fallthrough;
+	case IDR0_TTF_AARCH64:
+		break;
+	default:
+		dev_err(smmu->dev, "AArch64 table format not supported!\n");
+		return -ENXIO;
+	}
+
+	/* ASID/VMID sizes */
+	smmu->asid_bits = reg & IDR0_ASID16 ? 16 : 8;
+	smmu->vmid_bits = reg & IDR0_VMID16 ? 16 : 8;
+
+	/* IDR1 */
+	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR1);
+	if (reg & (IDR1_TABLES_PRESET | IDR1_QUEUES_PRESET | IDR1_REL)) {
+		dev_err(smmu->dev, "embedded implementation not supported\n");
+		return -ENXIO;
+	}
+
+	if (reg & IDR1_ATTR_TYPES_OVR)
+		smmu->features |= ARM_SMMU_FEAT_ATTR_TYPES_OVR;
+
+	/* Queue sizes, capped to ensure natural alignment */
+	smmu->cmdq.q.llq.max_n_shift = min_t(u32, CMDQ_MAX_SZ_SHIFT,
+					     FIELD_GET(IDR1_CMDQS, reg));
+	if (smmu->cmdq.q.llq.max_n_shift <= ilog2(CMDQ_BATCH_ENTRIES)) {
+		/*
+		 * We don't support splitting up batches, so one batch of
+		 * commands plus an extra sync needs to fit inside the command
+		 * queue. There's also no way we can handle the weird alignment
+		 * restrictions on the base pointer for a unit-length queue.
+		 */
+		dev_err(smmu->dev, "command queue size <= %d entries not supported\n",
+			CMDQ_BATCH_ENTRIES);
+		return -ENXIO;
+	}
+
+	smmu->evtq.q.llq.max_n_shift = min_t(u32, EVTQ_MAX_SZ_SHIFT,
+					     FIELD_GET(IDR1_EVTQS, reg));
+	smmu->priq.q.llq.max_n_shift = min_t(u32, PRIQ_MAX_SZ_SHIFT,
+					     FIELD_GET(IDR1_PRIQS, reg));
+
+	/* SID/SSID sizes */
+	smmu->ssid_bits = FIELD_GET(IDR1_SSIDSIZE, reg);
+	smmu->sid_bits = FIELD_GET(IDR1_SIDSIZE, reg);
+	smmu->iommu.max_pasids = 1UL << smmu->ssid_bits;
+
+	/*
+	 * If the SMMU supports fewer bits than would fill a single L2 stream
+	 * table, use a linear table instead.
+	 */
+	if (smmu->sid_bits <= STRTAB_SPLIT)
+		smmu->features &= ~ARM_SMMU_FEAT_2_LVL_STRTAB;
+
+	/* IDR3 */
+	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR3);
+	if (FIELD_GET(IDR3_RIL, reg))
+		smmu->features |= ARM_SMMU_FEAT_RANGE_INV;
+
+	/* IDR5 */
+	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR5);
+
+	/* Maximum number of outstanding stalls */
+	smmu->evtq.max_stalls = FIELD_GET(IDR5_STALL_MAX, reg);
+
+	/* Page sizes */
+	if (reg & IDR5_GRAN64K)
+		smmu->pgsize_bitmap |= SZ_64K | SZ_512M;
+	if (reg & IDR5_GRAN16K)
+		smmu->pgsize_bitmap |= SZ_16K | SZ_32M;
+	if (reg & IDR5_GRAN4K)
+		smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G;
+
+	/* Input address size */
+	if (FIELD_GET(IDR5_VAX, reg) == IDR5_VAX_52_BIT)
+		smmu->features |= ARM_SMMU_FEAT_VAX;
+
+	/* Output address size */
+	switch (FIELD_GET(IDR5_OAS, reg)) {
+	case IDR5_OAS_32_BIT:
+		smmu->oas = 32;
+		break;
+	case IDR5_OAS_36_BIT:
+		smmu->oas = 36;
+		break;
+	case IDR5_OAS_40_BIT:
+		smmu->oas = 40;
+		break;
+	case IDR5_OAS_42_BIT:
+		smmu->oas = 42;
+		break;
+	case IDR5_OAS_44_BIT:
+		smmu->oas = 44;
+		break;
+	case IDR5_OAS_52_BIT:
+		smmu->oas = 52;
+		smmu->pgsize_bitmap |= 1ULL << 42; /* 4TB */
+		break;
+	default:
+		dev_info(smmu->dev,
+			"unknown output address size. Truncating to 48-bit\n");
+		fallthrough;
+	case IDR5_OAS_48_BIT:
+		smmu->oas = 48;
+	}
+
+	/* Set the DMA mask for our table walker */
+	if (dma_set_mask_and_coherent(smmu->dev, DMA_BIT_MASK(smmu->oas)))
+		dev_warn(smmu->dev,
+			 "failed to set DMA mask for table walker\n");
+
+	smmu->ias = max(smmu->ias, smmu->oas);
+
+	if ((smmu->features & ARM_SMMU_FEAT_TRANS_S1) &&
+	    (smmu->features & ARM_SMMU_FEAT_TRANS_S2))
+		smmu->features |= ARM_SMMU_FEAT_NESTING;
+
+	arm_smmu_device_iidr_probe(smmu);
+
+	dev_info(smmu->dev, "ias %lu-bit, oas %lu-bit (features 0x%08x)\n",
+		 smmu->ias, smmu->oas, smmu->features);
+	return 0;
+}
+
+int arm_smmu_write_reg_sync(struct arm_smmu_device *smmu, u32 val,
+			    unsigned int reg_off, unsigned int ack_off)
+{
+	u32 reg;
+
+	writel_relaxed(val, smmu->base + reg_off);
+	return readl_relaxed_poll_timeout(smmu->base + ack_off, reg, reg == val,
+					  1, ARM_SMMU_POLL_TIMEOUT_US);
+}
+
+/* GBPA is "special" */
+int arm_smmu_update_gbpa(struct arm_smmu_device *smmu, u32 set, u32 clr)
+{
+	int ret;
+	u32 reg, __iomem *gbpa = smmu->base + ARM_SMMU_GBPA;
+
+	ret = readl_relaxed_poll_timeout(gbpa, reg, !(reg & GBPA_UPDATE),
+					 1, ARM_SMMU_POLL_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	reg &= ~clr;
+	reg |= set;
+	writel_relaxed(reg | GBPA_UPDATE, gbpa);
+	ret = readl_relaxed_poll_timeout(gbpa, reg, !(reg & GBPA_UPDATE),
+					 1, ARM_SMMU_POLL_TIMEOUT_US);
+
+	if (ret)
+		dev_err(smmu->dev, "GBPA not responding to update\n");
+	return ret;
+}
+
+int arm_smmu_device_disable(struct arm_smmu_device *smmu)
+{
+	int ret;
+
+	ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_CR0, ARM_SMMU_CR0ACK);
+	if (ret)
+		dev_err(smmu->dev, "failed to clear cr0\n");
+
+	return ret;
+}
+
+struct iommu_group *arm_smmu_device_group(struct device *dev)
+{
+	struct iommu_group *group;
+
+	/*
+	 * We don't support devices sharing stream IDs other than PCI RID
+	pick f473c7c1b189 fixup drv splt * aliases, since the necessary ID-to-device lookup becomes rather
+	 * impractical given a potential sparse 32-bit stream ID space.
+	 */
+	if (dev_is_pci(dev))
+		group = pci_device_group(dev);
+	else
+		group = generic_device_group(dev);
+
+	return group;
+}
+
+int arm_smmu_of_xlate(struct device *dev, const struct of_phandle_args *args)
+{
+	return iommu_fwspec_add_ids(dev, args->args, 1);
+}
+
+void arm_smmu_get_resv_regions(struct device *dev,
+			       struct list_head *head)
+{
+	struct iommu_resv_region *region;
+	int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
+
+	region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
+					 prot, IOMMU_RESV_SW_MSI, GFP_KERNEL);
+	if (!region)
+		return;
+
+	list_add_tail(&region->list, head);
+
+	iommu_dma_get_resv_regions(dev, head);
+}
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 702863c94f91..8741b8f57a8d 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -17,13 +17,11 @@
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io-pgtable.h>
-#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
-#include <linux/pci.h>
 #include <linux/pci-ats.h>
 #include <linux/platform_device.h>
 #include <kunit/visibility.h>
@@ -1914,8 +1912,6 @@ static irqreturn_t arm_smmu_priq_thread(int irq, void *dev)
 	return IRQ_HANDLED;
 }
 
-static int arm_smmu_device_disable(struct arm_smmu_device *smmu);
-
 static irqreturn_t arm_smmu_gerror_handler(int irq, void *dev)
 {
 	u32 gerror, gerrorn, active;
@@ -3361,23 +3357,6 @@ static int arm_smmu_set_dirty_tracking(struct iommu_domain *domain,
 	return 0;
 }
 
-static struct iommu_group *arm_smmu_device_group(struct device *dev)
-{
-	struct iommu_group *group;
-
-	/*
-	 * We don't support devices sharing stream IDs other than PCI RID
-	 * aliases, since the necessary ID-to-device lookup becomes rather
-	 * impractical given a potential sparse 32-bit stream ID space.
-	 */
-	if (dev_is_pci(dev))
-		group = pci_device_group(dev);
-	else
-		group = generic_device_group(dev);
-
-	return group;
-}
-
 static int arm_smmu_enable_nesting(struct iommu_domain *domain)
 {
 	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
@@ -3393,28 +3372,6 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev,
-			     const struct of_phandle_args *args)
-{
-	return iommu_fwspec_add_ids(dev, args->args, 1);
-}
-
-static void arm_smmu_get_resv_regions(struct device *dev,
-				      struct list_head *head)
-{
-	struct iommu_resv_region *region;
-	int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
-
-	region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
-					 prot, IOMMU_RESV_SW_MSI, GFP_KERNEL);
-	if (!region)
-		return;
-
-	list_add_tail(&region->list, head);
-
-	iommu_dma_get_resv_regions(dev, head);
-}
-
 static int arm_smmu_dev_enable_feature(struct device *dev,
 				       enum iommu_dev_features feat)
 {
@@ -3711,38 +3668,6 @@ static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
 	return 0;
 }
 
-static int arm_smmu_write_reg_sync(struct arm_smmu_device *smmu, u32 val,
-				   unsigned int reg_off, unsigned int ack_off)
-{
-	u32 reg;
-
-	writel_relaxed(val, smmu->base + reg_off);
-	return readl_relaxed_poll_timeout(smmu->base + ack_off, reg, reg == val,
-					  1, ARM_SMMU_POLL_TIMEOUT_US);
-}
-
-/* GBPA is "special" */
-static int arm_smmu_update_gbpa(struct arm_smmu_device *smmu, u32 set, u32 clr)
-{
-	int ret;
-	u32 reg, __iomem *gbpa = smmu->base + ARM_SMMU_GBPA;
-
-	ret = readl_relaxed_poll_timeout(gbpa, reg, !(reg & GBPA_UPDATE),
-					 1, ARM_SMMU_POLL_TIMEOUT_US);
-	if (ret)
-		return ret;
-
-	reg &= ~clr;
-	reg |= set;
-	writel_relaxed(reg | GBPA_UPDATE, gbpa);
-	ret = readl_relaxed_poll_timeout(gbpa, reg, !(reg & GBPA_UPDATE),
-					 1, ARM_SMMU_POLL_TIMEOUT_US);
-
-	if (ret)
-		dev_err(smmu->dev, "GBPA not responding to update\n");
-	return ret;
-}
-
 static void arm_smmu_free_msis(void *data)
 {
 	struct device *dev = data;
@@ -3889,17 +3814,6 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 	return 0;
 }
 
-static int arm_smmu_device_disable(struct arm_smmu_device *smmu)
-{
-	int ret;
-
-	ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_CR0, ARM_SMMU_CR0ACK);
-	if (ret)
-		dev_err(smmu->dev, "failed to clear cr0\n");
-
-	return ret;
-}
-
 static void arm_smmu_write_strtab(struct arm_smmu_device *smmu)
 {
 	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
@@ -4057,283 +3971,6 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
 	return 0;
 }
 
-#define IIDR_IMPLEMENTER_ARM		0x43b
-#define IIDR_PRODUCTID_ARM_MMU_600	0x483
-#define IIDR_PRODUCTID_ARM_MMU_700	0x487
-
-static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
-{
-	u32 reg;
-	unsigned int implementer, productid, variant, revision;
-
-	reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR);
-	implementer = FIELD_GET(IIDR_IMPLEMENTER, reg);
-	productid = FIELD_GET(IIDR_PRODUCTID, reg);
-	variant = FIELD_GET(IIDR_VARIANT, reg);
-	revision = FIELD_GET(IIDR_REVISION, reg);
-
-	switch (implementer) {
-	case IIDR_IMPLEMENTER_ARM:
-		switch (productid) {
-		case IIDR_PRODUCTID_ARM_MMU_600:
-			/* Arm erratum 1076982 */
-			if (variant == 0 && revision <= 2)
-				smmu->features &= ~ARM_SMMU_FEAT_SEV;
-			/* Arm erratum 1209401 */
-			if (variant < 2)
-				smmu->features &= ~ARM_SMMU_FEAT_NESTING;
-			break;
-		case IIDR_PRODUCTID_ARM_MMU_700:
-			/* Arm erratum 2812531 */
-			smmu->features &= ~ARM_SMMU_FEAT_BTM;
-			smmu->options |= ARM_SMMU_OPT_CMDQ_FORCE_SYNC;
-			/* Arm errata 2268618, 2812531 */
-			smmu->features &= ~ARM_SMMU_FEAT_NESTING;
-			break;
-		}
-		break;
-	}
-}
-
-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 hw_features = 0;
-
-	switch (FIELD_GET(IDR0_HTTU, reg)) {
-	case IDR0_HTTU_ACCESS_DIRTY:
-		hw_features |= ARM_SMMU_FEAT_HD;
-		fallthrough;
-	case IDR0_HTTU_ACCESS:
-		hw_features |= ARM_SMMU_FEAT_HA;
-	}
-
-	if (smmu->dev->of_node)
-		smmu->features |= hw_features;
-	else if (hw_features != fw_features)
-		/* ACPI IORT sets the HTTU bits */
-		dev_warn(smmu->dev,
-			 "IDR0.HTTU features(0x%x) overridden by FW configuration (0x%x)\n",
-			  hw_features, fw_features);
-}
-
-static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
-{
-	u32 reg;
-	bool coherent = smmu->features & ARM_SMMU_FEAT_COHERENCY;
-
-	/* IDR0 */
-	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0);
-
-	/* 2-level structures */
-	if (FIELD_GET(IDR0_ST_LVL, reg) == IDR0_ST_LVL_2LVL)
-		smmu->features |= ARM_SMMU_FEAT_2_LVL_STRTAB;
-
-	if (reg & IDR0_CD2L)
-		smmu->features |= ARM_SMMU_FEAT_2_LVL_CDTAB;
-
-	/*
-	 * Translation table endianness.
-	 * We currently require the same endianness as the CPU, but this
-	 * could be changed later by adding a new IO_PGTABLE_QUIRK.
-	 */
-	switch (FIELD_GET(IDR0_TTENDIAN, reg)) {
-	case IDR0_TTENDIAN_MIXED:
-		smmu->features |= ARM_SMMU_FEAT_TT_LE | ARM_SMMU_FEAT_TT_BE;
-		break;
-#ifdef __BIG_ENDIAN
-	case IDR0_TTENDIAN_BE:
-		smmu->features |= ARM_SMMU_FEAT_TT_BE;
-		break;
-#else
-	case IDR0_TTENDIAN_LE:
-		smmu->features |= ARM_SMMU_FEAT_TT_LE;
-		break;
-#endif
-	default:
-		dev_err(smmu->dev, "unknown/unsupported TT endianness!\n");
-		return -ENXIO;
-	}
-
-	/* Boolean feature flags */
-	if (IS_ENABLED(CONFIG_PCI_PRI) && reg & IDR0_PRI)
-		smmu->features |= ARM_SMMU_FEAT_PRI;
-
-	if (IS_ENABLED(CONFIG_PCI_ATS) && reg & IDR0_ATS)
-		smmu->features |= ARM_SMMU_FEAT_ATS;
-
-	if (reg & IDR0_SEV)
-		smmu->features |= ARM_SMMU_FEAT_SEV;
-
-	if (reg & IDR0_MSI) {
-		smmu->features |= ARM_SMMU_FEAT_MSI;
-		if (coherent)
-			smmu->options |= ARM_SMMU_OPT_MSIPOLL;
-	}
-
-	if (reg & IDR0_HYP) {
-		smmu->features |= ARM_SMMU_FEAT_HYP;
-		if (cpus_have_cap(ARM64_HAS_VIRT_HOST_EXTN))
-			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.
-	 */
-	if (!!(reg & IDR0_COHACC) != coherent)
-		dev_warn(smmu->dev, "IDR0.COHACC overridden by FW configuration (%s)\n",
-			 coherent ? "true" : "false");
-
-	switch (FIELD_GET(IDR0_STALL_MODEL, reg)) {
-	case IDR0_STALL_MODEL_FORCE:
-		smmu->features |= ARM_SMMU_FEAT_STALL_FORCE;
-		fallthrough;
-	case IDR0_STALL_MODEL_STALL:
-		smmu->features |= ARM_SMMU_FEAT_STALLS;
-	}
-
-	if (reg & IDR0_S1P)
-		smmu->features |= ARM_SMMU_FEAT_TRANS_S1;
-
-	if (reg & IDR0_S2P)
-		smmu->features |= ARM_SMMU_FEAT_TRANS_S2;
-
-	if (!(reg & (IDR0_S1P | IDR0_S2P))) {
-		dev_err(smmu->dev, "no translation support!\n");
-		return -ENXIO;
-	}
-
-	/* We only support the AArch64 table format at present */
-	switch (FIELD_GET(IDR0_TTF, reg)) {
-	case IDR0_TTF_AARCH32_64:
-		smmu->ias = 40;
-		fallthrough;
-	case IDR0_TTF_AARCH64:
-		break;
-	default:
-		dev_err(smmu->dev, "AArch64 table format not supported!\n");
-		return -ENXIO;
-	}
-
-	/* ASID/VMID sizes */
-	smmu->asid_bits = reg & IDR0_ASID16 ? 16 : 8;
-	smmu->vmid_bits = reg & IDR0_VMID16 ? 16 : 8;
-
-	/* IDR1 */
-	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR1);
-	if (reg & (IDR1_TABLES_PRESET | IDR1_QUEUES_PRESET | IDR1_REL)) {
-		dev_err(smmu->dev, "embedded implementation not supported\n");
-		return -ENXIO;
-	}
-
-	if (reg & IDR1_ATTR_TYPES_OVR)
-		smmu->features |= ARM_SMMU_FEAT_ATTR_TYPES_OVR;
-
-	/* Queue sizes, capped to ensure natural alignment */
-	smmu->cmdq.q.llq.max_n_shift = min_t(u32, CMDQ_MAX_SZ_SHIFT,
-					     FIELD_GET(IDR1_CMDQS, reg));
-	if (smmu->cmdq.q.llq.max_n_shift <= ilog2(CMDQ_BATCH_ENTRIES)) {
-		/*
-		 * We don't support splitting up batches, so one batch of
-		 * commands plus an extra sync needs to fit inside the command
-		 * queue. There's also no way we can handle the weird alignment
-		 * restrictions on the base pointer for a unit-length queue.
-		 */
-		dev_err(smmu->dev, "command queue size <= %d entries not supported\n",
-			CMDQ_BATCH_ENTRIES);
-		return -ENXIO;
-	}
-
-	smmu->evtq.q.llq.max_n_shift = min_t(u32, EVTQ_MAX_SZ_SHIFT,
-					     FIELD_GET(IDR1_EVTQS, reg));
-	smmu->priq.q.llq.max_n_shift = min_t(u32, PRIQ_MAX_SZ_SHIFT,
-					     FIELD_GET(IDR1_PRIQS, reg));
-
-	/* SID/SSID sizes */
-	smmu->ssid_bits = FIELD_GET(IDR1_SSIDSIZE, reg);
-	smmu->sid_bits = FIELD_GET(IDR1_SIDSIZE, reg);
-	smmu->iommu.max_pasids = 1UL << smmu->ssid_bits;
-
-	/*
-	 * If the SMMU supports fewer bits than would fill a single L2 stream
-	 * table, use a linear table instead.
-	 */
-	if (smmu->sid_bits <= STRTAB_SPLIT)
-		smmu->features &= ~ARM_SMMU_FEAT_2_LVL_STRTAB;
-
-	/* IDR3 */
-	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR3);
-	if (FIELD_GET(IDR3_RIL, reg))
-		smmu->features |= ARM_SMMU_FEAT_RANGE_INV;
-
-	/* IDR5 */
-	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR5);
-
-	/* Maximum number of outstanding stalls */
-	smmu->evtq.max_stalls = FIELD_GET(IDR5_STALL_MAX, reg);
-
-	/* Page sizes */
-	if (reg & IDR5_GRAN64K)
-		smmu->pgsize_bitmap |= SZ_64K | SZ_512M;
-	if (reg & IDR5_GRAN16K)
-		smmu->pgsize_bitmap |= SZ_16K | SZ_32M;
-	if (reg & IDR5_GRAN4K)
-		smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G;
-
-	/* Input address size */
-	if (FIELD_GET(IDR5_VAX, reg) == IDR5_VAX_52_BIT)
-		smmu->features |= ARM_SMMU_FEAT_VAX;
-
-	/* Output address size */
-	switch (FIELD_GET(IDR5_OAS, reg)) {
-	case IDR5_OAS_32_BIT:
-		smmu->oas = 32;
-		break;
-	case IDR5_OAS_36_BIT:
-		smmu->oas = 36;
-		break;
-	case IDR5_OAS_40_BIT:
-		smmu->oas = 40;
-		break;
-	case IDR5_OAS_42_BIT:
-		smmu->oas = 42;
-		break;
-	case IDR5_OAS_44_BIT:
-		smmu->oas = 44;
-		break;
-	case IDR5_OAS_52_BIT:
-		smmu->oas = 52;
-		smmu->pgsize_bitmap |= 1ULL << 42; /* 4TB */
-		break;
-	default:
-		dev_info(smmu->dev,
-			"unknown output address size. Truncating to 48-bit\n");
-		fallthrough;
-	case IDR5_OAS_48_BIT:
-		smmu->oas = 48;
-	}
-
-	/* Set the DMA mask for our table walker */
-	if (dma_set_mask_and_coherent(smmu->dev, DMA_BIT_MASK(smmu->oas)))
-		dev_warn(smmu->dev,
-			 "failed to set DMA mask for table walker\n");
-
-	smmu->ias = max(smmu->ias, smmu->oas);
-
-	if ((smmu->features & ARM_SMMU_FEAT_TRANS_S1) &&
-	    (smmu->features & ARM_SMMU_FEAT_TRANS_S2))
-		smmu->features |= ARM_SMMU_FEAT_NESTING;
-
-	arm_smmu_device_iidr_probe(smmu);
-
-	dev_info(smmu->dev, "ias %lu-bit, oas %lu-bit (features 0x%08x)\n",
-		 smmu->ias, smmu->oas, smmu->features);
-	return 0;
-}
-
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_TEGRA241_CMDQV
 static void acpi_smmu_dsdt_probe_tegra241_cmdqv(struct acpi_iort_node *node,
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 fc1b8c2af2a2..1ffc8320b846 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -341,6 +341,17 @@ int arm_smmu_set_pasid(struct arm_smmu_master *master,
 		       struct arm_smmu_domain *smmu_domain, ioasid_t pasid,
 		       struct arm_smmu_cd *cd);
 
+int arm_smmu_write_reg_sync(struct arm_smmu_device *smmu, u32 val,
+			    unsigned int reg_off, unsigned int ack_off);
+int arm_smmu_update_gbpa(struct arm_smmu_device *smmu, u32 set, u32 clr);
+int arm_smmu_device_disable(struct arm_smmu_device *smmu);
+struct iommu_group *arm_smmu_device_group(struct device *dev);
+int arm_smmu_of_xlate(struct device *dev, const struct of_phandle_args *args);
+void arm_smmu_get_resv_regions(struct device *dev,
+			       struct list_head *head);
+
+int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu);
+
 void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);
 void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
 				 size_t granule, bool leaf,
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:31 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:31 +0000
Subject: [RFC PATCH v2 07/58] iommu/arm-smmu-v3: Move queue and table
 allocation to arm-smmu-v3-common.c
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-8-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Move more code to arm-smmu-v3-common.c, so that the KVM driver can reuse
it.

Also, make sure that that allocated memory is aligned as it its going
to protected by the hypervisor stage-2.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/include/asm/arm-smmu-v3-common.h   |  29 ++++
 .../arm/arm-smmu-v3/arm-smmu-v3-common.c      | 136 ++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 151 +-----------------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  26 ++-
 4 files changed, 179 insertions(+), 163 deletions(-)

diff --git a/arch/arm64/include/asm/arm-smmu-v3-common.h b/arch/arm64/include/asm/arm-smmu-v3-common.h
index e6e339248816..f2fbd286f674 100644
--- a/arch/arm64/include/asm/arm-smmu-v3-common.h
+++ b/arch/arm64/include/asm/arm-smmu-v3-common.h
@@ -3,6 +3,7 @@
 #define _ARM_SMMU_V3_COMMON_H
 
 #include <linux/bitfield.h>
+#include <linux/bits.h>
 
 /* MMIO registers */
 #define ARM_SMMU_IDR0			0x0
@@ -198,6 +199,22 @@ struct arm_smmu_strtab_l1 {
 };
 #define STRTAB_MAX_L1_ENTRIES		(1 << 17)
 
+struct arm_smmu_strtab_cfg {
+	union {
+		struct {
+			struct arm_smmu_ste *table;
+			dma_addr_t ste_dma;
+			unsigned int num_ents;
+		} linear;
+		struct {
+			struct arm_smmu_strtab_l1 *l1tab;
+			struct arm_smmu_strtab_l2 **l2ptrs;
+			dma_addr_t l1_dma;
+			unsigned int num_l1_ents;
+		} l2;
+	};
+};
+
 static inline u32 arm_smmu_strtab_l1_idx(u32 sid)
 {
 	return sid / STRTAB_NUM_L2_STES;
@@ -208,6 +225,18 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
 	return sid % STRTAB_NUM_L2_STES;
 }
 
+static inline void arm_smmu_write_strtab_l1_desc(struct arm_smmu_strtab_l1 *dst,
+						 dma_addr_t l2ptr_dma)
+{
+	u64 val = 0;
+
+	val |= FIELD_PREP(STRTAB_L1_DESC_SPAN, STRTAB_SPLIT + 1);
+	val |= l2ptr_dma & STRTAB_L1_DESC_L2PTR_MASK;
+
+	/* The HW has 64 bit atomicity with stores to the L2 STE table */
+	WRITE_ONCE(dst->l2ptr, cpu_to_le64(val));
+}
+
 #define STRTAB_STE_0_V			(1UL << 0)
 #define STRTAB_STE_0_CFG		GENMASK_ULL(3, 1)
 #define STRTAB_STE_0_CFG_ABORT		0
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 cfd5ba69e67e..80ac13b0dc06 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
@@ -348,6 +348,7 @@ int arm_smmu_of_xlate(struct device *dev, const struct of_phandle_args *args)
 	return iommu_fwspec_add_ids(dev, args->args, 1);
 }
 
+
 void arm_smmu_get_resv_regions(struct device *dev,
 			       struct list_head *head)
 {
@@ -363,3 +364,138 @@ void arm_smmu_get_resv_regions(struct device *dev,
 
 	iommu_dma_get_resv_regions(dev, head);
 }
+
+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, PAGE_ALIGN(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 int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
+{
+	u32 l1size;
+	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
+	unsigned int last_sid_idx =
+		arm_smmu_strtab_l1_idx((1 << smmu->sid_bits) - 1);
+
+	/* Calculate the L1 size, capped to the SIDSIZE. */
+	cfg->l2.num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES);
+	if (cfg->l2.num_l1_ents <= last_sid_idx)
+		dev_warn(smmu->dev,
+			 "2-level strtab only covers %u/%u bits of SID\n",
+			 ilog2(cfg->l2.num_l1_ents * STRTAB_NUM_L2_STES),
+			 smmu->sid_bits);
+
+	l1size = cfg->l2.num_l1_ents * sizeof(struct arm_smmu_strtab_l1);
+	cfg->l2.l1tab = dmam_alloc_coherent(smmu->dev, PAGE_ALIGN(l1size), &cfg->l2.l1_dma,
+					    GFP_KERNEL);
+	if (!cfg->l2.l1tab) {
+		dev_err(smmu->dev,
+			"failed to allocate l1 stream table (%u bytes)\n",
+			l1size);
+		return -ENOMEM;
+	}
+
+	cfg->l2.l2ptrs = devm_kcalloc(smmu->dev, cfg->l2.num_l1_ents,
+				      sizeof(*cfg->l2.l2ptrs), GFP_KERNEL);
+	if (!cfg->l2.l2ptrs)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
+{
+	u32 size;
+	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
+
+	size = (1 << smmu->sid_bits) * sizeof(struct arm_smmu_ste);
+	cfg->linear.table = dmam_alloc_coherent(smmu->dev, PAGE_ALIGN(size),
+						&cfg->linear.ste_dma,
+						GFP_KERNEL);
+	if (!cfg->linear.table) {
+		dev_err(smmu->dev,
+			"failed to allocate linear stream table (%u bytes)\n",
+			size);
+		return -ENOMEM;
+	}
+	cfg->linear.num_ents = 1 << smmu->sid_bits;
+
+	return 0;
+}
+
+int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
+{
+	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;
+
+	ida_init(&smmu->vmid_map);
+
+	return 0;
+}
+
+void arm_smmu_write_strtab(struct arm_smmu_device *smmu)
+{
+	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
+	dma_addr_t dma;
+	u32 reg;
+
+	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
+		reg = FIELD_PREP(STRTAB_BASE_CFG_FMT,
+				 STRTAB_BASE_CFG_FMT_2LVL) |
+		      FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE,
+				 ilog2(cfg->l2.num_l1_ents) + STRTAB_SPLIT) |
+		      FIELD_PREP(STRTAB_BASE_CFG_SPLIT, STRTAB_SPLIT);
+		dma = cfg->l2.l1_dma;
+	} else {
+		reg = FIELD_PREP(STRTAB_BASE_CFG_FMT,
+				 STRTAB_BASE_CFG_FMT_LINEAR) |
+		      FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits);
+		dma = cfg->linear.ste_dma;
+	}
+	writeq_relaxed((dma & STRTAB_BASE_ADDR_MASK) | STRTAB_BASE_RA,
+		       smmu->base + ARM_SMMU_STRTAB_BASE);
+	writel_relaxed(reg, smmu->base + ARM_SMMU_STRTAB_BASE_CFG);
+}
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 8741b8f57a8d..cfee7f9b5afc 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1483,18 +1483,6 @@ static void arm_smmu_free_cd_tables(struct arm_smmu_master *master)
 }
 
 /* Stream table manipulation functions */
-static void arm_smmu_write_strtab_l1_desc(struct arm_smmu_strtab_l1 *dst,
-					  dma_addr_t l2ptr_dma)
-{
-	u64 val = 0;
-
-	val |= FIELD_PREP(STRTAB_L1_DESC_SPAN, STRTAB_SPLIT + 1);
-	val |= l2ptr_dma & STRTAB_L1_DESC_L2PTR_MASK;
-
-	/* The HW has 64 bit atomicity with stores to the L2 STE table */
-	WRITE_ONCE(dst->l2ptr, cpu_to_le64(val));
-}
-
 struct arm_smmu_ste_writer {
 	struct arm_smmu_entry_writer writer;
 	u32 sid;
@@ -3482,47 +3470,6 @@ static struct iommu_dirty_ops arm_smmu_dirty_ops = {
 };
 
 /* Probing and initialisation functions */
-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;
-}
-
 int arm_smmu_cmdq_init(struct arm_smmu_device *smmu,
 		       struct arm_smmu_cmdq *cmdq)
 {
@@ -3577,76 +3524,6 @@ static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
 				       PRIQ_ENT_DWORDS, "priq");
 }
 
-static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
-{
-	u32 l1size;
-	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
-	unsigned int last_sid_idx =
-		arm_smmu_strtab_l1_idx((1 << smmu->sid_bits) - 1);
-
-	/* Calculate the L1 size, capped to the SIDSIZE. */
-	cfg->l2.num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES);
-	if (cfg->l2.num_l1_ents <= last_sid_idx)
-		dev_warn(smmu->dev,
-			 "2-level strtab only covers %u/%u bits of SID\n",
-			 ilog2(cfg->l2.num_l1_ents * STRTAB_NUM_L2_STES),
-			 smmu->sid_bits);
-
-	l1size = cfg->l2.num_l1_ents * sizeof(struct arm_smmu_strtab_l1);
-	cfg->l2.l1tab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->l2.l1_dma,
-					    GFP_KERNEL);
-	if (!cfg->l2.l1tab) {
-		dev_err(smmu->dev,
-			"failed to allocate l1 stream table (%u bytes)\n",
-			l1size);
-		return -ENOMEM;
-	}
-
-	cfg->l2.l2ptrs = devm_kcalloc(smmu->dev, cfg->l2.num_l1_ents,
-				      sizeof(*cfg->l2.l2ptrs), GFP_KERNEL);
-	if (!cfg->l2.l2ptrs)
-		return -ENOMEM;
-
-	return 0;
-}
-
-static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
-{
-	u32 size;
-	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
-
-	size = (1 << smmu->sid_bits) * sizeof(struct arm_smmu_ste);
-	cfg->linear.table = dmam_alloc_coherent(smmu->dev, size,
-						&cfg->linear.ste_dma,
-						GFP_KERNEL);
-	if (!cfg->linear.table) {
-		dev_err(smmu->dev,
-			"failed to allocate linear stream table (%u bytes)\n",
-			size);
-		return -ENOMEM;
-	}
-	cfg->linear.num_ents = 1 << smmu->sid_bits;
-
-	arm_smmu_init_initial_stes(cfg->linear.table, cfg->linear.num_ents);
-	return 0;
-}
-
-static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
-{
-	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;
-
-	ida_init(&smmu->vmid_map);
-
-	return 0;
-}
-
 static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
 {
 	int ret;
@@ -3662,6 +3539,10 @@ static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
 	if (ret)
 		return ret;
 
+	if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB))
+		arm_smmu_init_initial_stes(smmu->strtab_cfg.linear.table,
+					   smmu->strtab_cfg.linear.num_ents);
+
 	if (smmu->impl_ops && smmu->impl_ops->init_structures)
 		return smmu->impl_ops->init_structures(smmu);
 
@@ -3814,30 +3695,6 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 	return 0;
 }
 
-static void arm_smmu_write_strtab(struct arm_smmu_device *smmu)
-{
-	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
-	dma_addr_t dma;
-	u32 reg;
-
-	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
-		reg = FIELD_PREP(STRTAB_BASE_CFG_FMT,
-				 STRTAB_BASE_CFG_FMT_2LVL) |
-		      FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE,
-				 ilog2(cfg->l2.num_l1_ents) + STRTAB_SPLIT) |
-		      FIELD_PREP(STRTAB_BASE_CFG_SPLIT, STRTAB_SPLIT);
-		dma = cfg->l2.l1_dma;
-	} else {
-		reg = FIELD_PREP(STRTAB_BASE_CFG_FMT,
-				 STRTAB_BASE_CFG_FMT_LINEAR) |
-		      FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits);
-		dma = cfg->linear.ste_dma;
-	}
-	writeq_relaxed((dma & STRTAB_BASE_ADDR_MASK) | STRTAB_BASE_RA,
-		       smmu->base + ARM_SMMU_STRTAB_BASE);
-	writel_relaxed(reg, smmu->base + ARM_SMMU_STRTAB_BASE_CFG);
-}
-
 static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
 {
 	int ret;
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 1ffc8320b846..1a3452554ca8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -156,22 +156,6 @@ struct arm_smmu_s2_cfg {
 	u16				vmid;
 };
 
-struct arm_smmu_strtab_cfg {
-	union {
-		struct {
-			struct arm_smmu_ste *table;
-			dma_addr_t ste_dma;
-			unsigned int num_ents;
-		} linear;
-		struct {
-			struct arm_smmu_strtab_l1 *l1tab;
-			struct arm_smmu_strtab_l2 **l2ptrs;
-			dma_addr_t l1_dma;
-			unsigned int num_l1_ents;
-		} l2;
-	};
-};
-
 struct arm_smmu_impl_ops {
 	int (*device_reset)(struct arm_smmu_device *smmu);
 	void (*device_remove)(struct arm_smmu_device *smmu);
@@ -351,6 +335,16 @@ void arm_smmu_get_resv_regions(struct device *dev,
 			       struct list_head *head);
 
 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_strtab(struct arm_smmu_device *smmu);
+void arm_smmu_write_strtab_l1_desc(struct arm_smmu_strtab_l1 *dst,
+				   dma_addr_t l2ptr_dma);
+void arm_smmu_write_strtab(struct arm_smmu_device *smmu);
 
 void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);
 void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:32 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:32 +0000
Subject: [RFC PATCH v2 08/58] iommu/arm-smmu-v3: Move firmware probe to arm-smmu-v3-common
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-9-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Move the FW probe functions to the common source.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 .../arm/arm-smmu-v3/arm-smmu-v3-common.c      | 146 ++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 142 +----------------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |   3 +
 3 files changed, 150 insertions(+), 141 deletions(-)

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 80ac13b0dc06..04f1e2f1c458 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
@@ -1,11 +1,157 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <linux/acpi.h>
 #include <linux/dma-mapping.h>
 #include <linux/iopoll.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
 #include <linux/pci.h>
+#include <linux/platform_device.h>
 
 #include "arm-smmu-v3.h"
 #include "../../dma-iommu.h"
 
+struct arm_smmu_option_prop {
+	u32 opt;
+	const char *prop;
+};
+
+static struct arm_smmu_option_prop arm_smmu_options[] = {
+	{ ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" },
+	{ ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium,cn9900-broken-page1-regspace"},
+	{ 0, NULL},
+};
+
+static void parse_driver_options(struct arm_smmu_device *smmu)
+{
+	int i = 0;
+
+	do {
+		if (of_property_read_bool(smmu->dev->of_node,
+						arm_smmu_options[i].prop)) {
+			smmu->options |= arm_smmu_options[i].opt;
+			dev_notice(smmu->dev, "option %s\n",
+				arm_smmu_options[i].prop);
+		}
+	} while (arm_smmu_options[++i].opt);
+}
+
+#ifdef CONFIG_ACPI
+#ifdef CONFIG_TEGRA241_CMDQV
+static void acpi_smmu_dsdt_probe_tegra241_cmdqv(struct acpi_iort_node *node,
+						struct arm_smmu_device *smmu)
+{
+	const char *uid = kasprintf(GFP_KERNEL, "%u", node->identifier);
+	struct acpi_device *adev;
+
+	/* Look for an NVDA200C node whose _UID matches the SMMU node ID */
+	adev = acpi_dev_get_first_match_dev("NVDA200C", uid, -1);
+	if (adev) {
+		/* Tegra241 CMDQV driver is responsible for put_device() */
+		smmu->impl_dev = &adev->dev;
+		smmu->options |= ARM_SMMU_OPT_TEGRA241_CMDQV;
+		dev_info(smmu->dev, "found companion CMDQV device: %s\n",
+			 dev_name(smmu->impl_dev));
+	}
+	kfree(uid);
+}
+#else
+static void acpi_smmu_dsdt_probe_tegra241_cmdqv(struct acpi_iort_node *node,
+						struct arm_smmu_device *smmu)
+{
+}
+#endif
+
+static int acpi_smmu_iort_probe_model(struct acpi_iort_node *node,
+				      struct arm_smmu_device *smmu)
+{
+	struct acpi_iort_smmu_v3 *iort_smmu =
+		(struct acpi_iort_smmu_v3 *)node->node_data;
+
+	switch (iort_smmu->model) {
+	case ACPI_IORT_SMMU_V3_CAVIUM_CN99XX:
+		smmu->options |= ARM_SMMU_OPT_PAGE0_REGS_ONLY;
+		break;
+	case ACPI_IORT_SMMU_V3_HISILICON_HI161X:
+		smmu->options |= ARM_SMMU_OPT_SKIP_PREFETCH;
+		break;
+	case ACPI_IORT_SMMU_V3_GENERIC:
+		/*
+		 * Tegra241 implementation stores its SMMU options and impl_dev
+		 * in DSDT. Thus, go through the ACPI tables unconditionally.
+		 */
+		acpi_smmu_dsdt_probe_tegra241_cmdqv(node, smmu);
+		break;
+	}
+
+	dev_notice(smmu->dev, "option mask 0x%x\n", smmu->options);
+	return 0;
+}
+
+static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+				      struct arm_smmu_device *smmu)
+{
+	struct acpi_iort_smmu_v3 *iort_smmu;
+	struct device *dev = smmu->dev;
+	struct acpi_iort_node *node;
+
+	node = *(struct acpi_iort_node **)dev_get_platdata(dev);
+
+	/* Retrieve SMMUv3 specific data */
+	iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+	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 acpi_smmu_iort_probe_model(node, smmu);
+}
+#else
+static inline int arm_smmu_device_acpi_probe(struct platform_device *pdev,
+					     struct arm_smmu_device *smmu)
+{
+	return -ENODEV;
+}
+#endif
+
+static int arm_smmu_device_dt_probe(struct platform_device *pdev,
+				    struct arm_smmu_device *smmu)
+{
+	struct device *dev = &pdev->dev;
+	u32 cells;
+	int ret = -EINVAL;
+
+	if (of_property_read_u32(dev->of_node, "#iommu-cells", &cells))
+		dev_err(dev, "missing #iommu-cells property\n");
+	else if (cells != 1)
+		dev_err(dev, "invalid #iommu-cells value (%d)\n", cells);
+	else
+		ret = 0;
+
+	parse_driver_options(smmu);
+
+	if (of_dma_is_coherent(dev->of_node))
+		smmu->features |= ARM_SMMU_FEAT_COHERENCY;
+
+	return ret;
+}
+
+int arm_smmu_fw_probe(struct platform_device *pdev,
+		      struct arm_smmu_device *smmu)
+{
+	if (smmu->dev->of_node)
+		return arm_smmu_device_dt_probe(pdev, smmu);
+	else
+		return arm_smmu_device_acpi_probe(pdev, smmu);
+}
+
 #define IIDR_IMPLEMENTER_ARM		0x43b
 #define IIDR_PRODUCTID_ARM_MMU_600	0x483
 #define IIDR_PRODUCTID_ARM_MMU_700	0x487
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 cfee7f9b5afc..91f64416900b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -9,7 +9,6 @@
  * This driver is powered by bad coffee and bombay mix.
  */
 
-#include <linux/acpi.h>
 #include <linux/acpi_iort.h>
 #include <linux/bitops.h>
 #include <linux/crash_dump.h>
@@ -19,9 +18,6 @@
 #include <linux/io-pgtable.h>
 #include <linux/module.h>
 #include <linux/msi.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
 #include <linux/pci-ats.h>
 #include <linux/platform_device.h>
 #include <kunit/visibility.h>
@@ -67,38 +63,13 @@ static phys_addr_t arm_smmu_msi_cfg[ARM_SMMU_MAX_MSIS][3] = {
 	},
 };
 
-struct arm_smmu_option_prop {
-	u32 opt;
-	const char *prop;
-};
-
 DEFINE_XARRAY_ALLOC1(arm_smmu_asid_xa);
 DEFINE_MUTEX(arm_smmu_asid_lock);
 
-static struct arm_smmu_option_prop arm_smmu_options[] = {
-	{ ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" },
-	{ ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium,cn9900-broken-page1-regspace"},
-	{ 0, NULL},
-};
-
 static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
 				    struct arm_smmu_device *smmu, u32 flags);
 static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
 
-static void parse_driver_options(struct arm_smmu_device *smmu)
-{
-	int i = 0;
-
-	do {
-		if (of_property_read_bool(smmu->dev->of_node,
-						arm_smmu_options[i].prop)) {
-			smmu->options |= arm_smmu_options[i].opt;
-			dev_notice(smmu->dev, "option %s\n",
-				arm_smmu_options[i].prop);
-		}
-	} while (arm_smmu_options[++i].opt);
-}
-
 /* Low-level queue manipulation functions */
 static bool queue_has_space(struct arm_smmu_ll_queue *q, u32 n)
 {
@@ -3828,113 +3799,6 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
 	return 0;
 }
 
-#ifdef CONFIG_ACPI
-#ifdef CONFIG_TEGRA241_CMDQV
-static void acpi_smmu_dsdt_probe_tegra241_cmdqv(struct acpi_iort_node *node,
-						struct arm_smmu_device *smmu)
-{
-	const char *uid = kasprintf(GFP_KERNEL, "%u", node->identifier);
-	struct acpi_device *adev;
-
-	/* Look for an NVDA200C node whose _UID matches the SMMU node ID */
-	adev = acpi_dev_get_first_match_dev("NVDA200C", uid, -1);
-	if (adev) {
-		/* Tegra241 CMDQV driver is responsible for put_device() */
-		smmu->impl_dev = &adev->dev;
-		smmu->options |= ARM_SMMU_OPT_TEGRA241_CMDQV;
-		dev_info(smmu->dev, "found companion CMDQV device: %s\n",
-			 dev_name(smmu->impl_dev));
-	}
-	kfree(uid);
-}
-#else
-static void acpi_smmu_dsdt_probe_tegra241_cmdqv(struct acpi_iort_node *node,
-						struct arm_smmu_device *smmu)
-{
-}
-#endif
-
-static int acpi_smmu_iort_probe_model(struct acpi_iort_node *node,
-				      struct arm_smmu_device *smmu)
-{
-	struct acpi_iort_smmu_v3 *iort_smmu =
-		(struct acpi_iort_smmu_v3 *)node->node_data;
-
-	switch (iort_smmu->model) {
-	case ACPI_IORT_SMMU_V3_CAVIUM_CN99XX:
-		smmu->options |= ARM_SMMU_OPT_PAGE0_REGS_ONLY;
-		break;
-	case ACPI_IORT_SMMU_V3_HISILICON_HI161X:
-		smmu->options |= ARM_SMMU_OPT_SKIP_PREFETCH;
-		break;
-	case ACPI_IORT_SMMU_V3_GENERIC:
-		/*
-		 * Tegra241 implementation stores its SMMU options and impl_dev
-		 * in DSDT. Thus, go through the ACPI tables unconditionally.
-		 */
-		acpi_smmu_dsdt_probe_tegra241_cmdqv(node, smmu);
-		break;
-	}
-
-	dev_notice(smmu->dev, "option mask 0x%x\n", smmu->options);
-	return 0;
-}
-
-static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
-				      struct arm_smmu_device *smmu)
-{
-	struct acpi_iort_smmu_v3 *iort_smmu;
-	struct device *dev = smmu->dev;
-	struct acpi_iort_node *node;
-
-	node = *(struct acpi_iort_node **)dev_get_platdata(dev);
-
-	/* Retrieve SMMUv3 specific data */
-	iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
-
-	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 acpi_smmu_iort_probe_model(node, smmu);
-}
-#else
-static inline int arm_smmu_device_acpi_probe(struct platform_device *pdev,
-					     struct arm_smmu_device *smmu)
-{
-	return -ENODEV;
-}
-#endif
-
-static int arm_smmu_device_dt_probe(struct platform_device *pdev,
-				    struct arm_smmu_device *smmu)
-{
-	struct device *dev = &pdev->dev;
-	u32 cells;
-	int ret = -EINVAL;
-
-	if (of_property_read_u32(dev->of_node, "#iommu-cells", &cells))
-		dev_err(dev, "missing #iommu-cells property\n");
-	else if (cells != 1)
-		dev_err(dev, "invalid #iommu-cells value (%d)\n", cells);
-	else
-		ret = 0;
-
-	parse_driver_options(smmu);
-
-	if (of_dma_is_coherent(dev->of_node))
-		smmu->features |= ARM_SMMU_FEAT_COHERENCY;
-
-	return ret;
-}
-
 static unsigned long arm_smmu_resource_size(struct arm_smmu_device *smmu)
 {
 	if (smmu->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY)
@@ -4030,11 +3894,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	smmu->dev = dev;
 
-	if (dev->of_node) {
-		ret = arm_smmu_device_dt_probe(pdev, smmu);
-	} else {
-		ret = arm_smmu_device_acpi_probe(pdev, smmu);
-	}
+	ret = arm_smmu_fw_probe(pdev, smmu);
 	if (ret)
 		return ret;
 
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 1a3452554ca8..2d658f15973a 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -334,6 +334,9 @@ int arm_smmu_of_xlate(struct device *dev, const struct of_phandle_args *args);
 void arm_smmu_get_resv_regions(struct device *dev,
 			       struct list_head *head);
 
+struct platform_device;
+int arm_smmu_fw_probe(struct platform_device *pdev,
+		      struct arm_smmu_device *smmu);
 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,
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:33 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:33 +0000
Subject: [RFC PATCH v2 09/58] iommu/arm-smmu-v3: Move IOMMU registration to arm-smmu-v3-common.c
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-10-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

The KVM driver will need to implement a few IOMMU ops, so move the
helpers to arm-smmu-v3-common.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 .../arm/arm-smmu-v3/arm-smmu-v3-common.c      | 27 +++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 17 ++----------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  4 +++
 3 files changed, 33 insertions(+), 15 deletions(-)

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 04f1e2f1c458..b7bcac51cc7d 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
@@ -645,3 +645,30 @@ void arm_smmu_write_strtab(struct arm_smmu_device *smmu)
 		       smmu->base + ARM_SMMU_STRTAB_BASE);
 	writel_relaxed(reg, smmu->base + ARM_SMMU_STRTAB_BASE_CFG);
 }
+
+int arm_smmu_register_iommu(struct arm_smmu_device *smmu,
+			    struct iommu_ops *ops, phys_addr_t ioaddr)
+{
+	int ret;
+	struct device *dev = smmu->dev;
+
+	ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
+				     "smmu3.%pa", &ioaddr);
+	if (ret)
+		return ret;
+
+	ret = iommu_device_register(&smmu->iommu, ops, dev);
+	if (ret) {
+		dev_err(dev, "Failed to register iommu\n");
+		iommu_device_sysfs_remove(&smmu->iommu);
+		return ret;
+	}
+
+	return 0;
+}
+
+void arm_smmu_unregister_iommu(struct arm_smmu_device *smmu)
+{
+	iommu_device_unregister(&smmu->iommu);
+	iommu_device_sysfs_remove(&smmu->iommu);
+}
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 91f64416900b..bcefa361f3d3 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3980,27 +3980,14 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 		return ret;
 
 	/* And we're up. Go go go! */
-	ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
-				     "smmu3.%pa", &ioaddr);
-	if (ret)
-		return ret;
-
-	ret = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev);
-	if (ret) {
-		dev_err(dev, "Failed to register iommu\n");
-		iommu_device_sysfs_remove(&smmu->iommu);
-		return ret;
-	}
-
-	return 0;
+	return arm_smmu_register_iommu(smmu, &arm_smmu_ops, ioaddr);
 }
 
 static void arm_smmu_device_remove(struct platform_device *pdev)
 {
 	struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
 
-	iommu_device_unregister(&smmu->iommu);
-	iommu_device_sysfs_remove(&smmu->iommu);
+	arm_smmu_unregister_iommu(smmu);
 	arm_smmu_device_disable(smmu);
 	iopf_queue_free(smmu->evtq.iopf);
 	ida_destroy(&smmu->vmid_map);
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 2d658f15973a..63545fdf55f9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -349,6 +349,10 @@ void arm_smmu_write_strtab_l1_desc(struct arm_smmu_strtab_l1 *dst,
 				   dma_addr_t l2ptr_dma);
 void arm_smmu_write_strtab(struct arm_smmu_device *smmu);
 
+int arm_smmu_register_iommu(struct arm_smmu_device *smmu,
+			    struct iommu_ops *ops, phys_addr_t ioaddr);
+void arm_smmu_unregister_iommu(struct arm_smmu_device *smmu);
+
 void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);
 void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
 				 size_t granule, bool leaf,
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:34 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:34 +0000
Subject: [RFC PATCH v2 10/58] iommu/arm-smmu-v3: Move common irq code to
 common file
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-11-smostafa@google.com>

Soon, KVM SMMUv3 driver will support irqs, instead of re-implementing
the architectural bits and the firmware bindings, move this code to
the common file shared with KVM.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 .../arm/arm-smmu-v3/arm-smmu-v3-common.c      | 150 +++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 297 +-----------------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   | 159 ++++++++++
 3 files changed, 313 insertions(+), 293 deletions(-)

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 b7bcac51cc7d..d842e592b351 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
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/acpi.h>
 #include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
 #include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -22,6 +23,24 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
 	{ 0, NULL},
 };
 
+static phys_addr_t arm_smmu_msi_cfg[ARM_SMMU_MAX_MSIS][3] = {
+	[EVTQ_MSI_INDEX] = {
+		ARM_SMMU_EVTQ_IRQ_CFG0,
+		ARM_SMMU_EVTQ_IRQ_CFG1,
+		ARM_SMMU_EVTQ_IRQ_CFG2,
+	},
+	[GERROR_MSI_INDEX] = {
+		ARM_SMMU_GERROR_IRQ_CFG0,
+		ARM_SMMU_GERROR_IRQ_CFG1,
+		ARM_SMMU_GERROR_IRQ_CFG2,
+	},
+	[PRIQ_MSI_INDEX] = {
+		ARM_SMMU_PRIQ_IRQ_CFG0,
+		ARM_SMMU_PRIQ_IRQ_CFG1,
+		ARM_SMMU_PRIQ_IRQ_CFG2,
+	},
+};
+
 static void parse_driver_options(struct arm_smmu_device *smmu)
 {
 	int i = 0;
@@ -646,6 +665,137 @@ void arm_smmu_write_strtab(struct arm_smmu_device *smmu)
 	writel_relaxed(reg, smmu->base + ARM_SMMU_STRTAB_BASE_CFG);
 }
 
+static void arm_smmu_free_msis(void *data)
+{
+	struct device *dev = data;
+
+	platform_device_msi_free_irqs_all(dev);
+}
+
+static void arm_smmu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
+{
+	phys_addr_t doorbell;
+	struct device *dev = msi_desc_to_dev(desc);
+	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+	phys_addr_t *cfg = arm_smmu_msi_cfg[desc->msi_index];
+
+	doorbell = (((u64)msg->address_hi) << 32) | msg->address_lo;
+	doorbell &= MSI_CFG0_ADDR_MASK;
+
+	writeq_relaxed(doorbell, smmu->base + cfg[0]);
+	writel_relaxed(msg->data, smmu->base + cfg[1]);
+	writel_relaxed(ARM_SMMU_MEMATTR_DEVICE_nGnRE, smmu->base + cfg[2]);
+}
+
+static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
+{
+	int ret, nvec = ARM_SMMU_MAX_MSIS;
+	struct device *dev = smmu->dev;
+
+	/* Clear the MSI address regs */
+	writeq_relaxed(0, smmu->base + ARM_SMMU_GERROR_IRQ_CFG0);
+	writeq_relaxed(0, smmu->base + ARM_SMMU_EVTQ_IRQ_CFG0);
+
+	if (smmu->features & ARM_SMMU_FEAT_PRI)
+		writeq_relaxed(0, smmu->base + ARM_SMMU_PRIQ_IRQ_CFG0);
+	else
+		nvec--;
+
+	if (!(smmu->features & ARM_SMMU_FEAT_MSI))
+		return;
+
+	if (!dev->msi.domain) {
+		dev_info(smmu->dev, "msi_domain absent - falling back to wired irqs\n");
+		return;
+	}
+
+	/* Allocate MSIs for evtq, gerror and priq. Ignore cmdq */
+	ret = platform_device_msi_init_and_alloc_irqs(dev, nvec, arm_smmu_write_msi_msg);
+	if (ret) {
+		dev_warn(dev, "failed to allocate MSIs - falling back to wired irqs\n");
+		return;
+	}
+
+	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
+	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
+	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
+
+	/* Add callback to free MSIs on teardown */
+	devm_add_action_or_reset(dev, arm_smmu_free_msis, dev);
+}
+
+void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu,
+				irqreturn_t evtqirq(int irq, void *dev),
+				irqreturn_t gerrorirq(int irq, void *dev),
+				irqreturn_t priirq(int irq, void *dev))
+{
+	int irq, ret;
+
+	arm_smmu_setup_msis(smmu);
+
+	/* Request interrupt lines */
+	irq = smmu->evtq.q.irq;
+	if (irq) {
+		ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
+						evtqirq,
+						IRQF_ONESHOT,
+						"arm-smmu-v3-evtq", smmu);
+		if (ret < 0)
+			dev_warn(smmu->dev, "failed to enable evtq irq\n");
+	} else {
+		dev_warn(smmu->dev, "no evtq irq - events will not be reported!\n");
+	}
+
+	irq = smmu->gerr_irq;
+	if (irq) {
+		ret = devm_request_irq(smmu->dev, irq, gerrorirq,
+				       0, "arm-smmu-v3-gerror", smmu);
+		if (ret < 0)
+			dev_warn(smmu->dev, "failed to enable gerror irq\n");
+	} else {
+		dev_warn(smmu->dev, "no gerr irq - errors will not be reported!\n");
+	}
+
+	if (smmu->features & ARM_SMMU_FEAT_PRI) {
+		irq = smmu->priq.q.irq;
+		if (irq) {
+			ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
+							priirq,
+							IRQF_ONESHOT,
+							"arm-smmu-v3-priq",
+							smmu);
+			if (ret < 0)
+				dev_warn(smmu->dev,
+					 "failed to enable priq irq\n");
+		} else {
+			dev_warn(smmu->dev, "no priq irq - PRI will be broken\n");
+		}
+	}
+}
+
+void arm_smmu_probe_irq(struct platform_device *pdev,
+			struct arm_smmu_device *smmu)
+{
+	int irq;
+
+	irq = platform_get_irq_byname_optional(pdev, "combined");
+	if (irq > 0)
+		smmu->combined_irq = irq;
+	else {
+		irq = platform_get_irq_byname_optional(pdev, "eventq");
+		if (irq > 0)
+			smmu->evtq.q.irq = irq;
+
+		irq = platform_get_irq_byname_optional(pdev, "priq");
+		if (irq > 0)
+			smmu->priq.q.irq = irq;
+
+		irq = platform_get_irq_byname_optional(pdev, "gerror");
+		if (irq > 0)
+			smmu->gerr_irq = irq;
+	}
+}
+
 int arm_smmu_register_iommu(struct arm_smmu_device *smmu,
 			    struct iommu_ops *ops, phys_addr_t ioaddr)
 {
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 bcefa361f3d3..8234a9754a04 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -12,7 +12,6 @@
 #include <linux/acpi_iort.h>
 #include <linux/bitops.h>
 #include <linux/crash_dump.h>
-#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io-pgtable.h>
@@ -34,35 +33,10 @@ MODULE_PARM_DESC(disable_msipolling,
 static struct iommu_ops arm_smmu_ops;
 static struct iommu_dirty_ops arm_smmu_dirty_ops;
 
-enum arm_smmu_msi_index {
-	EVTQ_MSI_INDEX,
-	GERROR_MSI_INDEX,
-	PRIQ_MSI_INDEX,
-	ARM_SMMU_MAX_MSIS,
-};
-
 #define NUM_ENTRY_QWORDS 8
 static_assert(sizeof(struct arm_smmu_ste) == NUM_ENTRY_QWORDS * sizeof(u64));
 static_assert(sizeof(struct arm_smmu_cd) == NUM_ENTRY_QWORDS * sizeof(u64));
 
-static phys_addr_t arm_smmu_msi_cfg[ARM_SMMU_MAX_MSIS][3] = {
-	[EVTQ_MSI_INDEX] = {
-		ARM_SMMU_EVTQ_IRQ_CFG0,
-		ARM_SMMU_EVTQ_IRQ_CFG1,
-		ARM_SMMU_EVTQ_IRQ_CFG2,
-	},
-	[GERROR_MSI_INDEX] = {
-		ARM_SMMU_GERROR_IRQ_CFG0,
-		ARM_SMMU_GERROR_IRQ_CFG1,
-		ARM_SMMU_GERROR_IRQ_CFG2,
-	},
-	[PRIQ_MSI_INDEX] = {
-		ARM_SMMU_PRIQ_IRQ_CFG0,
-		ARM_SMMU_PRIQ_IRQ_CFG1,
-		ARM_SMMU_PRIQ_IRQ_CFG2,
-	},
-};
-
 DEFINE_XARRAY_ALLOC1(arm_smmu_asid_xa);
 DEFINE_MUTEX(arm_smmu_asid_lock);
 
@@ -70,149 +44,6 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
 				    struct arm_smmu_device *smmu, u32 flags);
 static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
 
-/* Low-level queue manipulation functions */
-static bool queue_has_space(struct arm_smmu_ll_queue *q, u32 n)
-{
-	u32 space, prod, cons;
-
-	prod = Q_IDX(q, q->prod);
-	cons = Q_IDX(q, q->cons);
-
-	if (Q_WRP(q, q->prod) == Q_WRP(q, q->cons))
-		space = (1 << q->max_n_shift) - (prod - cons);
-	else
-		space = cons - prod;
-
-	return space >= n;
-}
-
-static bool queue_full(struct arm_smmu_ll_queue *q)
-{
-	return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&
-	       Q_WRP(q, q->prod) != Q_WRP(q, q->cons);
-}
-
-static bool queue_empty(struct arm_smmu_ll_queue *q)
-{
-	return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&
-	       Q_WRP(q, q->prod) == Q_WRP(q, q->cons);
-}
-
-static bool queue_consumed(struct arm_smmu_ll_queue *q, u32 prod)
-{
-	return ((Q_WRP(q, q->cons) == Q_WRP(q, prod)) &&
-		(Q_IDX(q, q->cons) > Q_IDX(q, prod))) ||
-	       ((Q_WRP(q, q->cons) != Q_WRP(q, prod)) &&
-		(Q_IDX(q, q->cons) <= Q_IDX(q, prod)));
-}
-
-static void queue_sync_cons_out(struct arm_smmu_queue *q)
-{
-	/*
-	 * Ensure that all CPU accesses (reads and writes) to the queue
-	 * are complete before we update the cons pointer.
-	 */
-	__iomb();
-	writel_relaxed(q->llq.cons, q->cons_reg);
-}
-
-static void queue_inc_cons(struct arm_smmu_ll_queue *q)
-{
-	u32 cons = (Q_WRP(q, q->cons) | Q_IDX(q, q->cons)) + 1;
-	q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons);
-}
-
-static void queue_sync_cons_ovf(struct arm_smmu_queue *q)
-{
-	struct arm_smmu_ll_queue *llq = &q->llq;
-
-	if (likely(Q_OVF(llq->prod) == Q_OVF(llq->cons)))
-		return;
-
-	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
-		      Q_IDX(llq, llq->cons);
-	queue_sync_cons_out(q);
-}
-
-static int queue_sync_prod_in(struct arm_smmu_queue *q)
-{
-	u32 prod;
-	int ret = 0;
-
-	/*
-	 * We can't use the _relaxed() variant here, as we must prevent
-	 * speculative reads of the queue before we have determined that
-	 * prod has indeed moved.
-	 */
-	prod = readl(q->prod_reg);
-
-	if (Q_OVF(prod) != Q_OVF(q->llq.prod))
-		ret = -EOVERFLOW;
-
-	q->llq.prod = prod;
-	return ret;
-}
-
-static u32 queue_inc_prod_n(struct arm_smmu_ll_queue *q, int n)
-{
-	u32 prod = (Q_WRP(q, q->prod) | Q_IDX(q, q->prod)) + n;
-	return Q_OVF(q->prod) | Q_WRP(q, prod) | Q_IDX(q, prod);
-}
-
-static void queue_poll_init(struct arm_smmu_device *smmu,
-			    struct arm_smmu_queue_poll *qp)
-{
-	qp->delay = 1;
-	qp->spin_cnt = 0;
-	qp->wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
-	qp->timeout = ktime_add_us(ktime_get(), ARM_SMMU_POLL_TIMEOUT_US);
-}
-
-static int queue_poll(struct arm_smmu_queue_poll *qp)
-{
-	if (ktime_compare(ktime_get(), qp->timeout) > 0)
-		return -ETIMEDOUT;
-
-	if (qp->wfe) {
-		wfe();
-	} else if (++qp->spin_cnt < ARM_SMMU_POLL_SPIN_COUNT) {
-		cpu_relax();
-	} else {
-		udelay(qp->delay);
-		qp->delay *= 2;
-		qp->spin_cnt = 0;
-	}
-
-	return 0;
-}
-
-static void queue_write(__le64 *dst, u64 *src, size_t n_dwords)
-{
-	int i;
-
-	for (i = 0; i < n_dwords; ++i)
-		*dst++ = cpu_to_le64(*src++);
-}
-
-static void queue_read(u64 *dst, __le64 *src, size_t n_dwords)
-{
-	int i;
-
-	for (i = 0; i < n_dwords; ++i)
-		*dst++ = le64_to_cpu(*src++);
-}
-
-static int queue_remove_raw(struct arm_smmu_queue *q, u64 *ent)
-{
-	if (queue_empty(&q->llq))
-		return -EAGAIN;
-
-	queue_read(ent, Q_ENT(q, q->llq.cons), q->ent_dwords);
-	queue_inc_cons(&q->llq);
-	queue_sync_cons_out(q);
-	return 0;
-}
-
 /* High-level queue accessors */
 static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
 {
@@ -3520,111 +3351,6 @@ static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
 	return 0;
 }
 
-static void arm_smmu_free_msis(void *data)
-{
-	struct device *dev = data;
-
-	platform_device_msi_free_irqs_all(dev);
-}
-
-static void arm_smmu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
-{
-	phys_addr_t doorbell;
-	struct device *dev = msi_desc_to_dev(desc);
-	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
-	phys_addr_t *cfg = arm_smmu_msi_cfg[desc->msi_index];
-
-	doorbell = (((u64)msg->address_hi) << 32) | msg->address_lo;
-	doorbell &= MSI_CFG0_ADDR_MASK;
-
-	writeq_relaxed(doorbell, smmu->base + cfg[0]);
-	writel_relaxed(msg->data, smmu->base + cfg[1]);
-	writel_relaxed(ARM_SMMU_MEMATTR_DEVICE_nGnRE, smmu->base + cfg[2]);
-}
-
-static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
-{
-	int ret, nvec = ARM_SMMU_MAX_MSIS;
-	struct device *dev = smmu->dev;
-
-	/* Clear the MSI address regs */
-	writeq_relaxed(0, smmu->base + ARM_SMMU_GERROR_IRQ_CFG0);
-	writeq_relaxed(0, smmu->base + ARM_SMMU_EVTQ_IRQ_CFG0);
-
-	if (smmu->features & ARM_SMMU_FEAT_PRI)
-		writeq_relaxed(0, smmu->base + ARM_SMMU_PRIQ_IRQ_CFG0);
-	else
-		nvec--;
-
-	if (!(smmu->features & ARM_SMMU_FEAT_MSI))
-		return;
-
-	if (!dev->msi.domain) {
-		dev_info(smmu->dev, "msi_domain absent - falling back to wired irqs\n");
-		return;
-	}
-
-	/* Allocate MSIs for evtq, gerror and priq. Ignore cmdq */
-	ret = platform_device_msi_init_and_alloc_irqs(dev, nvec, arm_smmu_write_msi_msg);
-	if (ret) {
-		dev_warn(dev, "failed to allocate MSIs - falling back to wired irqs\n");
-		return;
-	}
-
-	smmu->evtq.q.irq = msi_get_virq(dev, EVTQ_MSI_INDEX);
-	smmu->gerr_irq = msi_get_virq(dev, GERROR_MSI_INDEX);
-	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
-
-	/* Add callback to free MSIs on teardown */
-	devm_add_action_or_reset(dev, arm_smmu_free_msis, dev);
-}
-
-static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
-{
-	int irq, ret;
-
-	arm_smmu_setup_msis(smmu);
-
-	/* Request interrupt lines */
-	irq = smmu->evtq.q.irq;
-	if (irq) {
-		ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
-						arm_smmu_evtq_thread,
-						IRQF_ONESHOT,
-						"arm-smmu-v3-evtq", smmu);
-		if (ret < 0)
-			dev_warn(smmu->dev, "failed to enable evtq irq\n");
-	} else {
-		dev_warn(smmu->dev, "no evtq irq - events will not be reported!\n");
-	}
-
-	irq = smmu->gerr_irq;
-	if (irq) {
-		ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler,
-				       0, "arm-smmu-v3-gerror", smmu);
-		if (ret < 0)
-			dev_warn(smmu->dev, "failed to enable gerror irq\n");
-	} else {
-		dev_warn(smmu->dev, "no gerr irq - errors will not be reported!\n");
-	}
-
-	if (smmu->features & ARM_SMMU_FEAT_PRI) {
-		irq = smmu->priq.q.irq;
-		if (irq) {
-			ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
-							arm_smmu_priq_thread,
-							IRQF_ONESHOT,
-							"arm-smmu-v3-priq",
-							smmu);
-			if (ret < 0)
-				dev_warn(smmu->dev,
-					 "failed to enable priq irq\n");
-		} else {
-			dev_warn(smmu->dev, "no priq irq - PRI will be broken\n");
-		}
-	}
-}
-
 static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 {
 	int ret, irq;
@@ -3652,7 +3378,8 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 		if (ret < 0)
 			dev_warn(smmu->dev, "failed to enable combined irq\n");
 	} else
-		arm_smmu_setup_unique_irqs(smmu);
+		arm_smmu_setup_unique_irqs(smmu, arm_smmu_evtq_thread,
+					   arm_smmu_gerror_handler, arm_smmu_priq_thread);
 
 	if (smmu->features & ARM_SMMU_FEAT_PRI)
 		irqen_flags |= IRQ_CTRL_PRIQ_IRQEN;
@@ -3883,7 +3610,7 @@ static struct arm_smmu_device *arm_smmu_impl_probe(struct arm_smmu_device *smmu)
 
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
-	int irq, ret;
+	int ret;
 	struct resource *res;
 	resource_size_t ioaddr;
 	struct arm_smmu_device *smmu;
@@ -3929,24 +3656,8 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 		smmu->page1 = smmu->base;
 	}
 
-	/* Interrupt lines */
-
-	irq = platform_get_irq_byname_optional(pdev, "combined");
-	if (irq > 0)
-		smmu->combined_irq = irq;
-	else {
-		irq = platform_get_irq_byname_optional(pdev, "eventq");
-		if (irq > 0)
-			smmu->evtq.q.irq = irq;
+	arm_smmu_probe_irq(pdev, smmu);
 
-		irq = platform_get_irq_byname_optional(pdev, "priq");
-		if (irq > 0)
-			smmu->priq.q.irq = irq;
-
-		irq = platform_get_irq_byname_optional(pdev, "gerror");
-		if (irq > 0)
-			smmu->gerr_irq = irq;
-	}
 	/* Probe the h/w */
 	ret = arm_smmu_device_hw_probe(smmu);
 	if (ret)
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 63545fdf55f9..d91dfe55835d 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -8,6 +8,7 @@
 #ifndef _ARM_SMMU_V3_H
 #define _ARM_SMMU_V3_H
 
+#include <linux/delay.h>
 #include <linux/iommu.h>
 #include <linux/kernel.h>
 #include <linux/mmzone.h>
@@ -349,6 +350,13 @@ void arm_smmu_write_strtab_l1_desc(struct arm_smmu_strtab_l1 *dst,
 				   dma_addr_t l2ptr_dma);
 void arm_smmu_write_strtab(struct arm_smmu_device *smmu);
 
+void arm_smmu_probe_irq(struct platform_device *pdev,
+			struct arm_smmu_device *smmu);
+void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu,
+				irqreturn_t evtqirq(int irq, void *dev),
+				irqreturn_t gerrorirq(int irq, void *dev),
+				irqreturn_t priirq(int irq, void *dev));
+
 int arm_smmu_register_iommu(struct arm_smmu_device *smmu,
 			    struct iommu_ops *ops, phys_addr_t ioaddr);
 void arm_smmu_unregister_iommu(struct arm_smmu_device *smmu);
@@ -425,4 +433,155 @@ tegra241_cmdqv_probe(struct arm_smmu_device *smmu)
 	return ERR_PTR(-ENODEV);
 }
 #endif /* CONFIG_TEGRA241_CMDQV */
+
+/* Queue functions shared with common and kernel drivers */
+static bool __maybe_unused queue_has_space(struct arm_smmu_ll_queue *q, u32 n)
+{
+	u32 space, prod, cons;
+
+	prod = Q_IDX(q, q->prod);
+	cons = Q_IDX(q, q->cons);
+
+	if (Q_WRP(q, q->prod) == Q_WRP(q, q->cons))
+		space = (1 << q->max_n_shift) - (prod - cons);
+	else
+		space = cons - prod;
+
+	return space >= n;
+}
+
+static bool __maybe_unused queue_full(struct arm_smmu_ll_queue *q)
+{
+	return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&
+	       Q_WRP(q, q->prod) != Q_WRP(q, q->cons);
+}
+
+static bool __maybe_unused queue_empty(struct arm_smmu_ll_queue *q)
+{
+	return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&
+	       Q_WRP(q, q->prod) == Q_WRP(q, q->cons);
+}
+
+static bool __maybe_unused queue_consumed(struct arm_smmu_ll_queue *q, u32 prod)
+{
+	return ((Q_WRP(q, q->cons) == Q_WRP(q, prod)) &&
+		(Q_IDX(q, q->cons) > Q_IDX(q, prod))) ||
+	       ((Q_WRP(q, q->cons) != Q_WRP(q, prod)) &&
+		(Q_IDX(q, q->cons) <= Q_IDX(q, prod)));
+}
+
+static void __maybe_unused queue_sync_cons_out(struct arm_smmu_queue *q)
+{
+	/*
+	 * Ensure that all CPU accesses (reads and writes) to the queue
+	 * are complete before we update the cons pointer.
+	 */
+	__iomb();
+	writel_relaxed(q->llq.cons, q->cons_reg);
+}
+
+static void __maybe_unused queue_inc_cons(struct arm_smmu_ll_queue *q)
+{
+	u32 cons = (Q_WRP(q, q->cons) | Q_IDX(q, q->cons)) + 1;
+	q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons);
+}
+
+static void __maybe_unused queue_sync_cons_ovf(struct arm_smmu_queue *q)
+{
+	struct arm_smmu_ll_queue *llq = &q->llq;
+
+	if (likely(Q_OVF(llq->prod) == Q_OVF(llq->cons)))
+		return;
+
+	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
+		    Q_IDX(llq, llq->cons);
+	queue_sync_cons_out(q);
+}
+
+static int __maybe_unused queue_sync_prod_in(struct arm_smmu_queue *q)
+{
+	u32 prod;
+	int ret = 0;
+
+	/*
+	 * We can't use the _relaxed() variant here, as we must prevent
+	 * speculative reads of the queue before we have determined that
+	 * prod has indeed moved.
+	 */
+	prod = readl(q->prod_reg);
+
+	if (Q_OVF(prod) != Q_OVF(q->llq.prod))
+		ret = -EOVERFLOW;
+
+	q->llq.prod = prod;
+	return ret;
+}
+
+static u32 __maybe_unused queue_inc_prod_n(struct arm_smmu_ll_queue *q, int n)
+{
+	u32 prod = (Q_WRP(q, q->prod) | Q_IDX(q, q->prod)) + n;
+	return Q_OVF(q->prod) | Q_WRP(q, prod) | Q_IDX(q, prod);
+}
+
+static void __maybe_unused queue_poll_init(struct arm_smmu_device *smmu,
+					   struct arm_smmu_queue_poll *qp)
+{
+	qp->delay = 1;
+	qp->spin_cnt = 0;
+	qp->wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
+	qp->timeout = ktime_add_us(ktime_get(), ARM_SMMU_POLL_TIMEOUT_US);
+}
+
+static int __maybe_unused queue_poll(struct arm_smmu_queue_poll *qp)
+{
+	if (ktime_compare(ktime_get(), qp->timeout) > 0)
+		return -ETIMEDOUT;
+
+	if (qp->wfe) {
+		wfe();
+	} else if (++qp->spin_cnt < ARM_SMMU_POLL_SPIN_COUNT) {
+		cpu_relax();
+	} else {
+		udelay(qp->delay);
+		qp->delay *= 2;
+		qp->spin_cnt = 0;
+	}
+
+	return 0;
+}
+
+static void __maybe_unused queue_write(__le64 *dst, u64 *src, size_t n_dwords)
+{
+	int i;
+
+	for (i = 0; i < n_dwords; ++i)
+		*dst++ = cpu_to_le64(*src++);
+}
+
+static void __maybe_unused queue_read(u64 *dst, __le64 *src, size_t n_dwords)
+{
+	int i;
+
+	for (i = 0; i < n_dwords; ++i)
+		*dst++ = le64_to_cpu(*src++);
+}
+
+static int __maybe_unused queue_remove_raw(struct arm_smmu_queue *q, u64 *ent)
+{
+	if (queue_empty(&q->llq))
+		return -EAGAIN;
+
+	queue_read(ent, Q_ENT(q, q->llq.cons), q->ent_dwords);
+	queue_inc_cons(&q->llq);
+	queue_sync_cons_out(q);
+	return 0;
+}
+
+enum arm_smmu_msi_index {
+	EVTQ_MSI_INDEX,
+	GERROR_MSI_INDEX,
+	PRIQ_MSI_INDEX,
+	ARM_SMMU_MAX_MSIS,
+};
+
 #endif /* _ARM_SMMU_V3_H */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:35 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:35 +0000
Subject: [RFC PATCH v2 11/58] KVM: arm64: pkvm: Add pkvm_udelay()
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-12-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Add a simple delay loop for drivers.

This could use more work. It should be possible to insert a wfe and save
power, but I haven't studied whether it is safe to do so with the host
in control of the event stream. The SMMU driver will use wfe anyway for
frequent waits (provided the implementation can send command queue
events).

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  3 ++
 arch/arm64/kvm/hyp/nvhe/setup.c        |  4 +++
 arch/arm64/kvm/hyp/nvhe/timer-sr.c     | 42 ++++++++++++++++++++++++++
 3 files changed, 49 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 3b515ce4c433..8a5554615e40 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -143,4 +143,7 @@ int pkvm_load_pvmfw_pages(struct pkvm_hyp_vm *vm, u64 ipa, phys_addr_t phys,
 			  u64 size);
 void pkvm_poison_pvmfw_pages(void);
 
+int pkvm_timer_init(void);
+void pkvm_udelay(unsigned long usecs);
+
 #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index 46dd68161979..9d09f5f471b9 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -356,6 +356,10 @@ void __noreturn __pkvm_init_finalise(void)
 	if (ret)
 		goto out;
 
+	ret = pkvm_timer_init();
+	if (ret)
+		goto out;
+
 	ret = fix_host_ownership();
 	if (ret)
 		goto out;
diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index 3aaab20ae5b4..732beb5fe24b 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -11,6 +11,10 @@
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
 
+#include <nvhe/pkvm.h>
+
+static u32 timer_freq;
+
 void __kvm_timer_set_cntvoff(u64 cntvoff)
 {
 	write_sysreg(cntvoff, cntvoff_el2);
@@ -60,3 +64,41 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
 
 	sysreg_clear_set(cnthctl_el2, clr, set);
 }
+
+static u64 pkvm_ticks_get(void)
+{
+	return __arch_counter_get_cntvct();
+}
+
+#define SEC_TO_US 1000000
+
+int pkvm_timer_init(void)
+{
+	timer_freq = read_sysreg(cntfrq_el0);
+	/*
+	 * TODO: The highest privileged level is supposed to initialize this
+	 * register. But on some systems (which?), this information is only
+	 * contained in the device-tree, so we'll need to find it out some other
+	 * way.
+	 */
+	if (!timer_freq || timer_freq < SEC_TO_US)
+		return -ENODEV;
+	return 0;
+}
+
+#define pkvm_time_us_to_ticks(us) ((u64)(us) * timer_freq / SEC_TO_US)
+
+void pkvm_udelay(unsigned long usecs)
+{
+	u64 ticks = pkvm_time_us_to_ticks(usecs);
+	u64 start = pkvm_ticks_get();
+
+	while (true) {
+		u64 cur = pkvm_ticks_get();
+
+		if ((cur - start) >= ticks || cur < start)
+			break;
+		/* TODO wfe */
+		cpu_relax();
+	}
+}
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:36 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:36 +0000
Subject: [RFC PATCH v2 12/58] KVM: arm64: Add __pkvm_{use, unuse}_dma()
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-13-smostafa@google.com>

When a page is mapped in an IOMMU page table for DMA, it must
not be donated to a guest or the hypervisor we ensure this with:
- Host can only map pages that are OWNED
- Any page that is mapped is refcounted
- Donation/Sharing is prevented from refcount check in
  host_request_owned_transition()
- No MMIO transtion is allowed beyond IOMMU MMIO which
  happens during de-privilege.
In case in the future shared pages are allowed to be mapped,
similar checks are needed in host_request_unshare() and
host_ack_unshare()

Add 2 functions that would be called before each IOMMU map
and after each successful IOMMU unmap.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 +
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 97 +++++++++++++++++++
 2 files changed, 99 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 67466b4941b4..d75e64e59596 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -92,6 +92,8 @@ int __pkvm_remove_ioguard_page(struct pkvm_hyp_vcpu *hyp_vcpu, u64 ipa);
 bool __pkvm_check_ioguard_page(struct pkvm_hyp_vcpu *hyp_vcpu);
 int __pkvm_guest_relinquish_to_host(struct pkvm_hyp_vcpu *vcpu,
 				    u64 ipa, u64 *ppa);
+int __pkvm_host_use_dma(u64 phys_addr, size_t size);
+int __pkvm_host_unuse_dma(u64 phys_addr, size_t size);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index d14f4d63eb8b..0840af20c366 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -513,6 +513,20 @@ bool addr_is_memory(phys_addr_t phys)
 	return !!find_mem_range(phys, &range);
 }
 
+static bool is_range_refcounted(phys_addr_t addr, u64 nr_pages)
+{
+	struct hyp_page *p;
+	int i;
+
+	for (i = 0 ; i < nr_pages ; ++i) {
+		p = hyp_phys_to_page(addr + i * PAGE_SIZE);
+		if (hyp_refcount_get(p->refcount))
+			return true;
+	}
+
+	return false;
+}
+
 static bool addr_is_allowed_memory(phys_addr_t phys)
 {
 	struct memblock_region *reg;
@@ -927,6 +941,9 @@ static int host_request_owned_transition(u64 *completer_addr,
 	u64 size = tx->nr_pages * PAGE_SIZE;
 	u64 addr = tx->initiator.addr;
 
+	if (range_is_memory(addr, addr + size) && is_range_refcounted(addr, tx->nr_pages))
+		return -EINVAL;
+
 	*completer_addr = tx->initiator.host.completer_addr;
 	return __host_check_page_state_range(addr, size, PKVM_PAGE_OWNED);
 }
@@ -938,6 +955,7 @@ static int host_request_unshare(u64 *completer_addr,
 	u64 addr = tx->initiator.addr;
 
 	*completer_addr = tx->initiator.host.completer_addr;
+
 	return __host_check_page_state_range(addr, size, PKVM_PAGE_SHARED_OWNED);
 }
 
@@ -2047,6 +2065,85 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
 	return ret;
 }
 
+static void __pkvm_host_use_dma_page(phys_addr_t phys_addr)
+{
+	struct hyp_page *p = hyp_phys_to_page(phys_addr);
+
+	hyp_page_ref_inc(p);
+}
+
+static void __pkvm_host_unuse_dma_page(phys_addr_t phys_addr)
+{
+	struct hyp_page *p = hyp_phys_to_page(phys_addr);
+
+	hyp_page_ref_dec(p);
+}
+
+/*
+ * __pkvm_host_use_dma - Mark host memory as used for DMA
+ * @phys_addr:	physical address of the DMA region
+ * @size:	size of the DMA region
+ * When a page is mapped in an IOMMU page table for DMA, it must
+ * not be donated to a guest or the hypervisor we ensure this with:
+ * - Host can only map pages that are OWNED
+ * - Any page that is mapped is refcounted
+ * - Donation/Sharing is prevented from refcount check in
+ *   host_request_owned_transition()
+ * - No MMIO transtion is allowed beyond IOMMU MMIO which
+ *   happens during de-privilege.
+ * In case in the future shared pages are allowed to be mapped,
+ * similar checks are needed in host_request_unshare() and
+ * host_ack_unshare()
+ */
+int __pkvm_host_use_dma(phys_addr_t phys_addr, size_t size)
+{
+	int i;
+	int ret = 0;
+	size_t nr_pages = size >> PAGE_SHIFT;
+
+	if (WARN_ON(!PAGE_ALIGNED(phys_addr | size)))
+		return -EINVAL;
+
+	host_lock_component();
+	ret = __host_check_page_state_range(phys_addr, size, PKVM_PAGE_OWNED);
+	if (ret)
+		goto out_ret;
+
+	if (!range_is_memory(phys_addr, phys_addr + size))
+		goto out_ret;
+
+	for (i = 0; i < nr_pages; i++)
+		__pkvm_host_use_dma_page(phys_addr + i * PAGE_SIZE);
+
+out_ret:
+	host_unlock_component();
+	return ret;
+}
+
+int __pkvm_host_unuse_dma(phys_addr_t phys_addr, size_t size)
+{
+	int i;
+	size_t nr_pages = size >> PAGE_SHIFT;
+
+	if (WARN_ON(!PAGE_ALIGNED(phys_addr | size)))
+		return -EINVAL;
+
+	host_lock_component();
+	if (!range_is_memory(phys_addr, phys_addr + size))
+		goto out_ret;
+	/*
+	 * We end up here after the caller successfully unmapped the page from
+	 * the IOMMU table. Which means that a ref is held, the page is shared
+	 * in the host s2, there can be no failure.
+	 */
+	for (i = 0; i < nr_pages; i++)
+		__pkvm_host_unuse_dma_page(phys_addr + i * PAGE_SIZE);
+
+out_ret:
+	host_unlock_component();
+	return 0;
+}
+
 int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
 			    enum kvm_pgtable_prot prot)
 {
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:37 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:37 +0000
Subject: [RFC PATCH v2 13/58] KVM: arm64: Introduce IOMMU driver infrastructure
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-14-smostafa@google.com>

To establish DMA isolation, KVM needs an IOMMU driver which provide
certain ops, these ops are defined outside of the iommu_ops,
and has 2 components:
- kvm_iommu_driver (kernel): Implements simple interaction with
  the kernel (init, remove,...)
- kvm_iommu_ops (hypervisor): Implements paravirtual interface
  (map, unmap, attach, detach,...)

Only one driver can be used and is registered with
kvm_iommu_register_driver() by passing pointers to both ops.

KVM will initialise the driver after it initialises and before the
de-privilege point, which is a suitable point to establish trusted
interaction between the host and the hypervisor, this also allows
the host kernel to do one initialization from the kernel and avoid
such complexity in the hypervisor as the kernel is still trusted at
this point.

Also, during the registration call, the pointer for the hypervisor
ops will be initialised.

The hypervisor init part is called from the finalise hypercall which
is executed after the kernel kvm IOMMU driver init.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 arch/arm64/include/asm/kvm_host.h       | 11 ++++++
 arch/arm64/kvm/Makefile                 |  2 +-
 arch/arm64/kvm/arm.c                    |  8 ++++-
 arch/arm64/kvm/hyp/include/nvhe/iommu.h | 13 +++++++
 arch/arm64/kvm/hyp/nvhe/Makefile        |  2 +-
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c   | 18 ++++++++++
 arch/arm64/kvm/hyp/nvhe/setup.c         |  5 +++
 arch/arm64/kvm/iommu.c                  | 47 +++++++++++++++++++++++++
 8 files changed, 103 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/iommu.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
 create mode 100644 arch/arm64/kvm/iommu.c

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 53916a7f0def..54416cfea573 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1628,4 +1628,15 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
 
 unsigned long __pkvm_reclaim_hyp_alloc_mgt(unsigned long nr_pages);
 
+struct kvm_iommu_driver {
+	int (*init_driver)(void);
+	void (*remove_driver)(void);
+};
+
+struct kvm_iommu_ops;
+int kvm_iommu_register_driver(struct kvm_iommu_driver *kern_ops,
+			      struct kvm_iommu_ops *el2_ops);
+int kvm_iommu_init_driver(void);
+void kvm_iommu_remove_driver(void);
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index f9e208273031..440897366e88 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -23,7 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-v3.o vgic/vgic-v4.o \
 	 vgic/vgic-mmio.o vgic/vgic-mmio-v2.o \
 	 vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
-	 vgic/vgic-its.o vgic/vgic-debug.o
+	 vgic/vgic-its.o vgic/vgic-debug.o iommu.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
 kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 94b210f36573..4b486323c0c9 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -2510,9 +2510,15 @@ static int __init kvm_hyp_init_protection(u32 hyp_va_bits)
 	if (ret)
 		return ret;
 
+	ret = kvm_iommu_init_driver();
+	if (ret < 0)
+		return ret;
+
 	ret = do_pkvm_init(hyp_va_bits);
-	if (ret)
+	if (ret) {
+		kvm_iommu_remove_driver();
 		return ret;
+	}
 
 	free_hyp_pgds();
 
diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
new file mode 100644
index 000000000000..1ac70cc28a9e
--- /dev/null
+++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ARM64_KVM_NVHE_IOMMU_H__
+#define __ARM64_KVM_NVHE_IOMMU_H__
+
+#include <asm/kvm_host.h>
+
+struct kvm_iommu_ops {
+	int (*init)(void);
+};
+
+int kvm_iommu_init(void);
+
+#endif /* __ARM64_KVM_NVHE_IOMMU_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 415cc51fe391..9e1b74c661d2 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -8,7 +8,7 @@ CFLAGS_switch.nvhe.o += -Wno-override-init
 hyp-obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
 	 hyp-main.o hyp-smp.o psci-relay.o alloc.o early_alloc.o page_alloc.o \
 	 cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o stacktrace.o ffa.o \
-	 serial.o alloc_mgt.o
+	 serial.o alloc_mgt.o iommu/iommu.o
 hyp-obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
 	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
 hyp-obj-$(CONFIG_LIST_HARDENED) += list_debug.o
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
new file mode 100644
index 000000000000..3bd87d2084e9
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU operations for pKVM
+ *
+ * Copyright (C) 2022 Linaro Ltd.
+ */
+#include <nvhe/iommu.h>
+
+/* Only one set of ops supported, similary to the kernel */
+struct kvm_iommu_ops *kvm_iommu_ops;
+
+int kvm_iommu_init(void)
+{
+	if (!kvm_iommu_ops || !kvm_iommu_ops->init)
+		return -ENODEV;
+
+	return kvm_iommu_ops->init();
+}
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index 9d09f5f471b9..4d36616a7f02 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -14,6 +14,7 @@
 #include <nvhe/early_alloc.h>
 #include <nvhe/ffa.h>
 #include <nvhe/gfp.h>
+#include <nvhe/iommu.h>
 #include <nvhe/memory.h>
 #include <nvhe/mem_protect.h>
 #include <nvhe/mm.h>
@@ -360,6 +361,10 @@ void __noreturn __pkvm_init_finalise(void)
 	if (ret)
 		goto out;
 
+	ret = kvm_iommu_init();
+	if (ret)
+		goto out;
+
 	ret = fix_host_ownership();
 	if (ret)
 		goto out;
diff --git a/arch/arm64/kvm/iommu.c b/arch/arm64/kvm/iommu.c
new file mode 100644
index 000000000000..ed77ea0d12bb
--- /dev/null
+++ b/arch/arm64/kvm/iommu.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 Google LLC
+ * Author: Mostafa Saleh <smostafa at google.com>
+ */
+
+#include <asm/kvm_mmu.h>
+#include <linux/kvm_host.h>
+
+struct kvm_iommu_driver *iommu_driver;
+extern struct kvm_iommu_ops *kvm_nvhe_sym(kvm_iommu_ops);
+
+int kvm_iommu_register_driver(struct kvm_iommu_driver *kern_ops, struct kvm_iommu_ops *el2_ops)
+{
+	int ret;
+
+	if (WARN_ON(!kern_ops || !el2_ops))
+		return -EINVAL;
+
+	/*
+	 * Paired with smp_load_acquire(&iommu_driver)
+	 * Ensure memory stores happening during a driver
+	 * init are observed before executing kvm iommu callbacks.
+	 */
+	ret = cmpxchg_release(&iommu_driver, NULL, kern_ops) ? -EBUSY : 0;
+	if (ret)
+		return ret;
+
+	kvm_nvhe_sym(kvm_iommu_ops) = el2_ops;
+	return 0;
+}
+
+int kvm_iommu_init_driver(void)
+{
+	if (WARN_ON(!smp_load_acquire(&iommu_driver))) {
+		kvm_err("pKVM enabled without an IOMMU driver, do not run confidential workloads in virtual machines\n");
+		return -ENODEV;
+	}
+
+	return iommu_driver->init_driver();
+}
+
+void kvm_iommu_remove_driver(void)
+{
+	if (smp_load_acquire(&iommu_driver))
+		iommu_driver->remove_driver();
+}
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:38 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:38 +0000
Subject: [RFC PATCH v2 14/58] KVM: arm64: pkvm: Add IOMMU hypercalls
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-15-smostafa@google.com>

The unprivileged host IOMMU driver forwards some of the IOMMU API calls
to the hypervisor, which installs and populates the page tables.

Note that this is not a stable ABI. Those hypercalls change with the
kernel just like internal function calls.

One thing special about some of the IOMMU hypercalls, that they use
newly added hyp_reqs_smccc_encode() to encode memory requests in
the HVC return, leveraging X1, X2 and X3 registers as allowed SMCCC.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 arch/arm64/include/asm/kvm_asm.h        |  7 ++
 arch/arm64/kvm/hyp/include/nvhe/iommu.h | 14 ++++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      | 89 +++++++++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c   | 40 +++++++++++
 4 files changed, 150 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index e4b391bdfdac..9ea155a04332 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -107,6 +107,13 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_hyp_alloc_mgt_refill,
 	__KVM_HOST_SMCCC_FUNC___pkvm_hyp_alloc_mgt_reclaimable,
 	__KVM_HOST_SMCCC_FUNC___pkvm_hyp_alloc_mgt_reclaim,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_alloc_domain,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_free_domain,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_attach_dev,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_detach_dev,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_map_pages,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_unmap_pages,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_iova_to_phys,
 
 	/*
 	 * Start of the dynamically registered hypercalls. Start a bit
diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
index 1ac70cc28a9e..908863f07b0b 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
@@ -4,6 +4,20 @@
 
 #include <asm/kvm_host.h>
 
+/* Hypercall handlers */
+int kvm_iommu_alloc_domain(pkvm_handle_t domain_id, int type);
+int kvm_iommu_free_domain(pkvm_handle_t domain_id);
+int kvm_iommu_attach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
+			 u32 endpoint_id, u32 pasid, u32 pasid_bits);
+int kvm_iommu_detach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
+			 u32 endpoint_id, u32 pasid);
+size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
+			   unsigned long iova, phys_addr_t paddr, size_t pgsize,
+			   size_t pgcount, int prot);
+size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
+			     size_t pgsize, size_t pgcount);
+phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova);
+
 struct kvm_iommu_ops {
 	int (*init)(void);
 };
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 08c0ff823a55..9b224842c487 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -19,6 +19,7 @@
 #include <nvhe/alloc.h>
 #include <nvhe/alloc_mgt.h>
 #include <nvhe/ffa.h>
+#include <nvhe/iommu.h>
 #include <nvhe/mem_protect.h>
 #include <nvhe/modules.h>
 #include <nvhe/mm.h>
@@ -1592,6 +1593,87 @@ static void handle___pkvm_hyp_alloc_mgt_reclaim(struct kvm_cpu_context *host_ctx
 	cpu_reg(host_ctxt, 2) = mc.nr_pages;
 }
 
+static void handle___pkvm_host_iommu_alloc_domain(struct kvm_cpu_context *host_ctxt)
+{
+	int ret;
+	DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 1);
+	DECLARE_REG(int, type, host_ctxt, 2);
+
+	ret = kvm_iommu_alloc_domain(domain, type);
+	hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
+}
+
+static void handle___pkvm_host_iommu_free_domain(struct kvm_cpu_context *host_ctxt)
+{
+	int ret;
+	DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 1);
+
+	ret = kvm_iommu_free_domain(domain);
+	hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
+}
+
+static void handle___pkvm_host_iommu_attach_dev(struct kvm_cpu_context *host_ctxt)
+{
+	int ret;
+	DECLARE_REG(pkvm_handle_t, iommu, host_ctxt, 1);
+	DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 2);
+	DECLARE_REG(unsigned int, endpoint, host_ctxt, 3);
+	DECLARE_REG(unsigned int, pasid, host_ctxt, 4);
+	DECLARE_REG(unsigned int, pasid_bits, host_ctxt, 5);
+
+	ret = kvm_iommu_attach_dev(iommu, domain, endpoint,
+				   pasid, pasid_bits);
+	hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
+}
+
+static void handle___pkvm_host_iommu_detach_dev(struct kvm_cpu_context *host_ctxt)
+{
+	int ret;
+	DECLARE_REG(pkvm_handle_t, iommu, host_ctxt, 1);
+	DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 2);
+	DECLARE_REG(unsigned int, endpoint, host_ctxt, 3);
+	DECLARE_REG(unsigned int, pasid, host_ctxt, 4);
+
+	ret = kvm_iommu_detach_dev(iommu, domain, endpoint, pasid);
+	hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
+}
+
+static void handle___pkvm_host_iommu_map_pages(struct kvm_cpu_context *host_ctxt)
+{
+	unsigned long ret;
+	DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 1);
+	DECLARE_REG(unsigned long, iova, host_ctxt, 2);
+	DECLARE_REG(phys_addr_t, paddr, host_ctxt, 3);
+	DECLARE_REG(size_t, pgsize, host_ctxt, 4);
+	DECLARE_REG(size_t, pgcount, host_ctxt, 5);
+	DECLARE_REG(unsigned int, prot, host_ctxt, 6);
+
+	ret = kvm_iommu_map_pages(domain, iova, paddr,
+				  pgsize, pgcount, prot);
+	hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
+}
+
+static void handle___pkvm_host_iommu_unmap_pages(struct kvm_cpu_context *host_ctxt)
+{
+	unsigned long ret;
+	DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 1);
+	DECLARE_REG(unsigned long, iova, host_ctxt, 2);
+	DECLARE_REG(size_t, pgsize, host_ctxt, 3);
+	DECLARE_REG(size_t, pgcount, host_ctxt, 4);
+
+	ret = kvm_iommu_unmap_pages(domain, iova,
+				    pgsize, pgcount);
+	hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
+}
+
+static void handle___pkvm_host_iommu_iova_to_phys(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 1);
+	DECLARE_REG(unsigned long, iova, host_ctxt, 2);
+
+	cpu_reg(host_ctxt, 1) = kvm_iommu_iova_to_phys(domain, iova);
+}
+
 typedef void (*hcall_t)(struct kvm_cpu_context *);
 
 #define HANDLE_FUNC(x)	[__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x
@@ -1649,6 +1731,13 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_hyp_alloc_mgt_refill),
 	HANDLE_FUNC(__pkvm_hyp_alloc_mgt_reclaimable),
 	HANDLE_FUNC(__pkvm_hyp_alloc_mgt_reclaim),
+	HANDLE_FUNC(__pkvm_host_iommu_alloc_domain),
+	HANDLE_FUNC(__pkvm_host_iommu_free_domain),
+	HANDLE_FUNC(__pkvm_host_iommu_attach_dev),
+	HANDLE_FUNC(__pkvm_host_iommu_detach_dev),
+	HANDLE_FUNC(__pkvm_host_iommu_map_pages),
+	HANDLE_FUNC(__pkvm_host_iommu_unmap_pages),
+	HANDLE_FUNC(__pkvm_host_iommu_iova_to_phys),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
index 3bd87d2084e9..9022fd612a49 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -16,3 +16,43 @@ int kvm_iommu_init(void)
 
 	return kvm_iommu_ops->init();
 }
+
+int kvm_iommu_alloc_domain(pkvm_handle_t domain_id, int type)
+{
+	return -ENODEV;
+}
+
+int kvm_iommu_free_domain(pkvm_handle_t domain_id)
+{
+	return -ENODEV;
+}
+
+int kvm_iommu_attach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
+			 u32 endpoint_id, u32 pasid, u32 pasid_bits)
+{
+	return -ENODEV;
+}
+
+int kvm_iommu_detach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
+			 u32 endpoint_id, u32 pasid)
+{
+	return -ENODEV;
+}
+
+size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
+			   unsigned long iova, phys_addr_t paddr, size_t pgsize,
+			   size_t pgcount, int prot)
+{
+	return 0;
+}
+
+size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
+			     size_t pgsize, size_t pgcount)
+{
+	return 0;
+}
+
+phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova)
+{
+	return 0;
+}
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:39 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:39 +0000
Subject: [RFC PATCH v2 15/58] KVM: arm64: iommu: Add a memory pool for the IOMMU
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-16-smostafa@google.com>

This patch defines a new hypervisor allocator which is an instance of
the hyp buddy allocator.
This allocator would be used from the IOMMU drivers to be used for
the page tables, generally these pages have 2 properties:
- Can be multi order
- Can be non-coherent

The interface provide functions and wrappers for those types of
allocations.

The IOMMU hypervisor will leverage the allocator interface which
provides a standardized interface that can be called from the kernel
part of the IOMMU driver to top up the allocator, and can be
reclaimed through the shrinker for pKVM.

Also, the allocation function would automatically create a request
when it fails to allocate memory from the pool, so it?s sufficient
for the driver to return an error code and the kernel part of the
driver should check the requests in the return and fill the
hypervisor allocator.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/include/asm/kvm_host.h       |  1 +
 arch/arm64/kvm/hyp/include/nvhe/iommu.h | 13 ++++
 arch/arm64/kvm/hyp/include/nvhe/mm.h    |  1 +
 arch/arm64/kvm/hyp/nvhe/alloc_mgt.c     |  2 +
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c   | 86 +++++++++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mm.c            | 17 +++++
 6 files changed, 120 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 54416cfea573..a3b5d8dd8995 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1625,6 +1625,7 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
 
 /* Allocator interface IDs. */
 #define HYP_ALLOC_MGT_HEAP_ID		0
+#define HYP_ALLOC_MGT_IOMMU_ID		1
 
 unsigned long __pkvm_reclaim_hyp_alloc_mgt(unsigned long nr_pages);
 
diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
index 908863f07b0b..5f91605cd48a 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
@@ -4,6 +4,8 @@
 
 #include <asm/kvm_host.h>
 
+#include <nvhe/alloc_mgt.h>
+
 /* Hypercall handlers */
 int kvm_iommu_alloc_domain(pkvm_handle_t domain_id, int type);
 int kvm_iommu_free_domain(pkvm_handle_t domain_id);
@@ -18,10 +20,21 @@ size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
 			     size_t pgsize, size_t pgcount);
 phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova);
 
+/* Flags for memory allocation for IOMMU drivers */
+#define IOMMU_PAGE_NOCACHE				BIT(0)
+void *kvm_iommu_donate_pages(u8 order, int flags);
+void kvm_iommu_reclaim_pages(void *p, u8 order);
+
+#define kvm_iommu_donate_page()		kvm_iommu_donate_pages(0, 0)
+#define kvm_iommu_donate_page_nc()	kvm_iommu_donate_pages(0, IOMMU_PAGE_NOCACHE)
+#define kvm_iommu_reclaim_page(p)	kvm_iommu_reclaim_pages(p, 0)
+
 struct kvm_iommu_ops {
 	int (*init)(void);
 };
 
 int kvm_iommu_init(void);
 
+extern struct hyp_mgt_allocator_ops kvm_iommu_allocator_ops;
+
 #endif /* __ARM64_KVM_NVHE_IOMMU_H__ */
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
index 5d33aca7d686..7b425f811efb 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
@@ -37,6 +37,7 @@ int __hyp_allocator_map(unsigned long start, phys_addr_t phys);
 int __pkvm_map_module_page(u64 pfn, void *va, enum kvm_pgtable_prot prot, bool is_protected);
 void __pkvm_unmap_module_page(u64 pfn, void *va);
 void *__pkvm_alloc_module_va(u64 nr_pages);
+int pkvm_remap_range(void *va, int nr_pages, bool nc);
 #ifdef CONFIG_NVHE_EL2_DEBUG
 void assert_in_mod_range(unsigned long addr);
 #else
diff --git a/arch/arm64/kvm/hyp/nvhe/alloc_mgt.c b/arch/arm64/kvm/hyp/nvhe/alloc_mgt.c
index 4a0f33b9820a..cfd903b30427 100644
--- a/arch/arm64/kvm/hyp/nvhe/alloc_mgt.c
+++ b/arch/arm64/kvm/hyp/nvhe/alloc_mgt.c
@@ -7,9 +7,11 @@
 
 #include <nvhe/alloc.h>
 #include <nvhe/alloc_mgt.h>
+#include <nvhe/iommu.h>
 
 static struct hyp_mgt_allocator_ops *registered_allocators[] = {
 	[HYP_ALLOC_MGT_HEAP_ID] = &hyp_alloc_ops,
+	[HYP_ALLOC_MGT_IOMMU_ID] = &kvm_iommu_allocator_ops,
 };
 
 #define MAX_ALLOC_ID		(ARRAY_SIZE(registered_allocators))
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
index 9022fd612a49..af6ae9b4dc51 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -5,15 +5,101 @@
  * Copyright (C) 2022 Linaro Ltd.
  */
 #include <nvhe/iommu.h>
+#include <nvhe/mem_protect.h>
+#include <nvhe/mm.h>
 
 /* Only one set of ops supported, similary to the kernel */
 struct kvm_iommu_ops *kvm_iommu_ops;
 
+/*
+ * Common pool that can be used by IOMMU driver to allocate pages.
+ */
+static struct hyp_pool iommu_host_pool;
+
+DECLARE_PER_CPU(struct kvm_hyp_req, host_hyp_reqs);
+
+static int kvm_iommu_refill(struct kvm_hyp_memcache *host_mc)
+{
+	if (!kvm_iommu_ops)
+		return -EINVAL;
+
+	return refill_hyp_pool(&iommu_host_pool, host_mc);
+}
+
+static void kvm_iommu_reclaim(struct kvm_hyp_memcache *host_mc, int target)
+{
+	if (!kvm_iommu_ops)
+		return;
+
+	reclaim_hyp_pool(&iommu_host_pool, host_mc, target);
+}
+
+static int kvm_iommu_reclaimable(void)
+{
+	if (!kvm_iommu_ops)
+		return 0;
+
+	return hyp_pool_free_pages(&iommu_host_pool);
+}
+
+struct hyp_mgt_allocator_ops kvm_iommu_allocator_ops = {
+	.refill = kvm_iommu_refill,
+	.reclaim = kvm_iommu_reclaim,
+	.reclaimable = kvm_iommu_reclaimable,
+};
+
+void *kvm_iommu_donate_pages(u8 order, int flags)
+{
+	void *p;
+	struct kvm_hyp_req *req = this_cpu_ptr(&host_hyp_reqs);
+	int ret;
+
+	p = hyp_alloc_pages(&iommu_host_pool, order);
+	if (p) {
+		/*
+		 * If page request is non-cacheable remap it as such
+		 * as all pages in the pool are mapped before hand and
+		 * assumed to be cacheable.
+		 */
+		if (flags & IOMMU_PAGE_NOCACHE) {
+			ret = pkvm_remap_range(p, 1 << order, true);
+			if (ret) {
+				hyp_put_page(&iommu_host_pool, p);
+				return NULL;
+			}
+		}
+		return p;
+	}
+
+	req->type = KVM_HYP_REQ_TYPE_MEM;
+	req->mem.dest = REQ_MEM_DEST_HYP_IOMMU;
+	req->mem.sz_alloc = (1 << order) * PAGE_SIZE;
+	req->mem.nr_pages = 1;
+	return NULL;
+}
+
+void kvm_iommu_reclaim_pages(void *p, u8 order)
+{
+	/*
+	 * Remap all pages to cacheable, as we don't know, may be use a flag
+	 * in the vmemmap or trust the driver to pass the cacheability same
+	 * as the allocation on free?
+	 */
+	pkvm_remap_range(p, 1 << order, false);
+	hyp_put_page(&iommu_host_pool, p);
+}
+
 int kvm_iommu_init(void)
 {
+	int ret;
+
 	if (!kvm_iommu_ops || !kvm_iommu_ops->init)
 		return -ENODEV;
 
+	ret = hyp_pool_init_empty(&iommu_host_pool, 64);
+	if (ret)
+		return ret;
+
 	return kvm_iommu_ops->init();
 }
 
diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
index 76bbb4c9012e..7a18b31538ae 100644
--- a/arch/arm64/kvm/hyp/nvhe/mm.c
+++ b/arch/arm64/kvm/hyp/nvhe/mm.c
@@ -564,3 +564,20 @@ int reclaim_hyp_pool(struct hyp_pool *pool, struct kvm_hyp_memcache *host_mc,
 
 	return 0;
 }
+
+/* Remap hyp memory with different cacheability */
+int pkvm_remap_range(void *va, int nr_pages, bool nc)
+{
+	size_t size = nr_pages << PAGE_SHIFT;
+	phys_addr_t phys = hyp_virt_to_phys(va);
+	enum kvm_pgtable_prot prot = PKVM_HOST_MEM_PROT;
+	int ret;
+
+	if (nc)
+		prot |= KVM_PGTABLE_PROT_NORMAL_NC;
+	hyp_spin_lock(&pkvm_pgd_lock);
+	WARN_ON(kvm_pgtable_hyp_unmap(&pkvm_pgtable, (u64)va, size) != size);
+	ret = kvm_pgtable_hyp_map(&pkvm_pgtable, (u64)va, size, phys, prot);
+	hyp_spin_unlock(&pkvm_pgd_lock);
+	return ret;
+}
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:40 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:40 +0000
Subject: [RFC PATCH v2 16/58] KVM: arm64: iommu: Add domains
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-17-smostafa@google.com>

The IOMMU domain abstraction allows to share the same page tables
between multiple devices. That may be necessary due to hardware
constraints, if multiple devices cannot be isolated by the IOMMU
(conventional PCI bus for example). It may also help with optimizing
resource or TLB use. For pKVM in particular, it may be useful to reduce
the amount of memory required for page tables. All devices owned by the
host kernel could be attached to the same domain (though that requires
host changes).

There is one shared domain space with all IOMMUs holding up to 2^16
domains.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/hyp-constants.c      |   1 +
 arch/arm64/kvm/hyp/include/nvhe/iommu.h |   4 +
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c   | 102 +++++++++++++++++++++++-
 arch/arm64/kvm/iommu.c                  |  10 +++
 include/kvm/iommu.h                     |  48 +++++++++++
 5 files changed, 161 insertions(+), 4 deletions(-)
 create mode 100644 include/kvm/iommu.h

diff --git a/arch/arm64/kvm/hyp/hyp-constants.c b/arch/arm64/kvm/hyp/hyp-constants.c
index 5fb26cabd606..96a6b45b424a 100644
--- a/arch/arm64/kvm/hyp/hyp-constants.c
+++ b/arch/arm64/kvm/hyp/hyp-constants.c
@@ -8,5 +8,6 @@
 int main(void)
 {
 	DEFINE(STRUCT_HYP_PAGE_SIZE,	sizeof(struct hyp_page));
+	DEFINE(HYP_SPINLOCK_SIZE,       sizeof(hyp_spinlock_t));
 	return 0;
 }
diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
index 5f91605cd48a..8f619f415d1f 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
@@ -4,6 +4,8 @@
 
 #include <asm/kvm_host.h>
 
+#include <kvm/iommu.h>
+
 #include <nvhe/alloc_mgt.h>
 
 /* Hypercall handlers */
@@ -31,6 +33,8 @@ void kvm_iommu_reclaim_pages(void *p, u8 order);
 
 struct kvm_iommu_ops {
 	int (*init)(void);
+	int (*alloc_domain)(struct kvm_hyp_iommu_domain *domain, int type);
+	void (*free_domain)(struct kvm_hyp_iommu_domain *domain);
 };
 
 int kvm_iommu_init(void);
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
index af6ae9b4dc51..ba2aed52a74f 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -4,12 +4,15 @@
  *
  * Copyright (C) 2022 Linaro Ltd.
  */
+#include <kvm/iommu.h>
+
 #include <nvhe/iommu.h>
 #include <nvhe/mem_protect.h>
 #include <nvhe/mm.h>
 
 /* Only one set of ops supported, similary to the kernel */
 struct kvm_iommu_ops *kvm_iommu_ops;
+void **kvm_hyp_iommu_domains;
 
 /*
  * Common pool that can be used by IOMMU driver to allocate pages.
@@ -18,6 +21,9 @@ static struct hyp_pool iommu_host_pool;
 
 DECLARE_PER_CPU(struct kvm_hyp_req, host_hyp_reqs);
 
+/* Protects domains in kvm_hyp_iommu_domains */
+static DEFINE_HYP_SPINLOCK(kvm_iommu_domain_lock);
+
 static int kvm_iommu_refill(struct kvm_hyp_memcache *host_mc)
 {
 	if (!kvm_iommu_ops)
@@ -89,28 +95,116 @@ void kvm_iommu_reclaim_pages(void *p, u8 order)
 	hyp_put_page(&iommu_host_pool, p);
 }
 
+static struct kvm_hyp_iommu_domain *
+handle_to_domain(pkvm_handle_t domain_id)
+{
+	int idx;
+	struct kvm_hyp_iommu_domain *domains;
+
+	if (domain_id >= KVM_IOMMU_MAX_DOMAINS)
+		return NULL;
+	domain_id = array_index_nospec(domain_id, KVM_IOMMU_MAX_DOMAINS);
+
+	idx = domain_id / KVM_IOMMU_DOMAINS_PER_PAGE;
+	domains = (struct kvm_hyp_iommu_domain *)READ_ONCE(kvm_hyp_iommu_domains[idx]);
+	if (!domains) {
+		domains = kvm_iommu_donate_page();
+		if (!domains)
+			return NULL;
+		/*
+		 * handle_to_domain() does not have to be called under a lock,
+		 * but even though we allocate a leaf in all cases, it's only
+		 * really a valid thing to do under alloc_domain(), which uses a
+		 * lock. Races are therefore a host bug and we don't need to be
+		 * delicate about it.
+		 */
+		if (WARN_ON(cmpxchg64_relaxed(&kvm_hyp_iommu_domains[idx], 0,
+					      (void *)domains) != 0)) {
+			kvm_iommu_reclaim_page(domains);
+			return NULL;
+		}
+	}
+	return &domains[domain_id % KVM_IOMMU_DOMAINS_PER_PAGE];
+}
+
 int kvm_iommu_init(void)
 {
 	int ret;
+	u64 domain_root_pfn = __hyp_pa(kvm_hyp_iommu_domains) >> PAGE_SHIFT;
 
-	if (!kvm_iommu_ops || !kvm_iommu_ops->init)
+	if (!kvm_iommu_ops ||
+	    !kvm_iommu_ops->init ||
+	    !kvm_iommu_ops->alloc_domain ||
+	    !kvm_iommu_ops->free_domain)
 		return -ENODEV;
 
 	ret = hyp_pool_init_empty(&iommu_host_pool, 64);
 	if (ret)
 		return ret;
 
-	return kvm_iommu_ops->init();
+	ret = __pkvm_host_donate_hyp(domain_root_pfn,
+				     KVM_IOMMU_DOMAINS_ROOT_ORDER_NR);
+	if (ret)
+		return ret;
+
+	ret = kvm_iommu_ops->init();
+	if (ret)
+		goto out_reclaim_domain;
+
+	return ret;
+
+out_reclaim_domain:
+	__pkvm_hyp_donate_host(domain_root_pfn, KVM_IOMMU_DOMAINS_ROOT_ORDER_NR);
+	return ret;
 }
 
 int kvm_iommu_alloc_domain(pkvm_handle_t domain_id, int type)
 {
-	return -ENODEV;
+	int ret = -EINVAL;
+	struct kvm_hyp_iommu_domain *domain;
+
+	domain = handle_to_domain(domain_id);
+	if (!domain)
+		return -ENOMEM;
+
+	hyp_spin_lock(&kvm_iommu_domain_lock);
+	if (atomic_read(&domain->refs))
+		goto out_unlock;
+
+	domain->domain_id = domain_id;
+	ret = kvm_iommu_ops->alloc_domain(domain, type);
+	if (ret)
+		goto out_unlock;
+
+	atomic_set_release(&domain->refs, 1);
+out_unlock:
+	hyp_spin_unlock(&kvm_iommu_domain_lock);
+	return ret;
 }
 
 int kvm_iommu_free_domain(pkvm_handle_t domain_id)
 {
-	return -ENODEV;
+	int ret = 0;
+	struct kvm_hyp_iommu_domain *domain;
+
+	domain = handle_to_domain(domain_id);
+	if (!domain)
+		return -EINVAL;
+
+	hyp_spin_lock(&kvm_iommu_domain_lock);
+	if (WARN_ON(atomic_cmpxchg_acquire(&domain->refs, 1, 0) != 1)) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	kvm_iommu_ops->free_domain(domain);
+
+	memset(domain, 0, sizeof(*domain));
+
+out_unlock:
+	hyp_spin_unlock(&kvm_iommu_domain_lock);
+
+	return ret;
 }
 
 int kvm_iommu_attach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
diff --git a/arch/arm64/kvm/iommu.c b/arch/arm64/kvm/iommu.c
index ed77ea0d12bb..af3417e6259d 100644
--- a/arch/arm64/kvm/iommu.c
+++ b/arch/arm64/kvm/iommu.c
@@ -5,6 +5,9 @@
  */
 
 #include <asm/kvm_mmu.h>
+
+#include <kvm/iommu.h>
+
 #include <linux/kvm_host.h>
 
 struct kvm_iommu_driver *iommu_driver;
@@ -37,6 +40,13 @@ int kvm_iommu_init_driver(void)
 		return -ENODEV;
 	}
 
+	kvm_hyp_iommu_domains = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
+				get_order(KVM_IOMMU_DOMAINS_ROOT_SIZE));
+	if (!kvm_hyp_iommu_domains)
+		return -ENOMEM;
+
+	kvm_hyp_iommu_domains = kern_hyp_va(kvm_hyp_iommu_domains);
+
 	return iommu_driver->init_driver();
 }
 
diff --git a/include/kvm/iommu.h b/include/kvm/iommu.h
new file mode 100644
index 000000000000..10ecaae0f6a3
--- /dev/null
+++ b/include/kvm/iommu.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __KVM_IOMMU_H
+#define __KVM_IOMMU_H
+
+#include <asm/kvm_host.h>
+#include <linux/io-pgtable.h>
+#ifdef __KVM_NVHE_HYPERVISOR__
+#include <nvhe/spinlock.h>
+#else
+#include "hyp_constants.h"
+#endif
+
+struct kvm_hyp_iommu_domain {
+	atomic_t		refs;
+	pkvm_handle_t		domain_id;
+	void			*priv;
+};
+
+extern void **kvm_nvhe_sym(kvm_hyp_iommu_domains);
+#define kvm_hyp_iommu_domains kvm_nvhe_sym(kvm_hyp_iommu_domains)
+
+/*
+ * At the moment the number of domains is limited to 2^16
+ * In practice we're rarely going to need a lot of domains. To avoid allocating
+ * a large domain table, we use a two-level table, indexed by domain ID. With
+ * 4kB pages and 16-bytes domains, the leaf table contains 256 domains, and the
+ * root table 256 pointers. With 64kB pages, the leaf table contains 4096
+ * domains and the root table 16 pointers. In this case, or when using 8-bit
+ * VMIDs, it may be more advantageous to use a single level. But using two
+ * levels allows to easily extend the domain size.
+ */
+#define KVM_IOMMU_MAX_DOMAINS	(1 << 16)
+
+/* Number of entries in the level-2 domain table */
+#define KVM_IOMMU_DOMAINS_PER_PAGE \
+	(PAGE_SIZE / sizeof(struct kvm_hyp_iommu_domain))
+
+/* Number of entries in the root domain table */
+#define KVM_IOMMU_DOMAINS_ROOT_ENTRIES \
+	(KVM_IOMMU_MAX_DOMAINS / KVM_IOMMU_DOMAINS_PER_PAGE)
+
+#define KVM_IOMMU_DOMAINS_ROOT_SIZE \
+	(KVM_IOMMU_DOMAINS_ROOT_ENTRIES * sizeof(void *))
+
+#define KVM_IOMMU_DOMAINS_ROOT_ORDER_NR	\
+	(1 << get_order(KVM_IOMMU_DOMAINS_ROOT_SIZE))
+
+#endif /* __KVM_IOMMU_H */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:41 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:41 +0000
Subject: [RFC PATCH v2 17/58] KVM: arm64: iommu: Add {attach, detach}_dev
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-18-smostafa@google.com>

Add attach/detach dev operations which are forwarded to the driver.

To avoid racing between alloc/free domain and attach/detach dev,
the refcount is used.

Although, as IOMMU attach/detach are per-IOMMU and would require
some sort of locking, nothing in the IOMMU core code need the lock
so delegate that to the driver to use locks when needed and the
hypervisor only guarantees no races between alloc/free domain.

Also, add a new function kvm_iommu_init_device() to initialise common
fields of the IOMMU struct, which is only the lock at the moment.
The IOMMU core code will need to use the lock next for power
management.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 arch/arm64/kvm/hyp/include/nvhe/iommu.h | 29 +++++++++++++
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c   | 56 ++++++++++++++++++++++++-
 include/kvm/iommu.h                     |  8 ++++
 3 files changed, 91 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
index 8f619f415d1f..d6d7447fbac8 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
@@ -35,10 +35,39 @@ struct kvm_iommu_ops {
 	int (*init)(void);
 	int (*alloc_domain)(struct kvm_hyp_iommu_domain *domain, int type);
 	void (*free_domain)(struct kvm_hyp_iommu_domain *domain);
+	struct kvm_hyp_iommu *(*get_iommu_by_id)(pkvm_handle_t iommu_id);
+	int (*attach_dev)(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_domain *domain,
+			  u32 endpoint_id, u32 pasid, u32 pasid_bits);
+	int (*detach_dev)(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_domain *domain,
+			  u32 endpoint_id, u32 pasid);
 };
 
 int kvm_iommu_init(void);
 
+int kvm_iommu_init_device(struct kvm_hyp_iommu *iommu);
+
+static inline hyp_spinlock_t *kvm_iommu_get_lock(struct kvm_hyp_iommu *iommu)
+{
+	/* See struct kvm_hyp_iommu */
+	BUILD_BUG_ON(sizeof(iommu->lock) != sizeof(hyp_spinlock_t));
+	return (hyp_spinlock_t *)(&iommu->lock);
+}
+
+static inline void kvm_iommu_lock_init(struct kvm_hyp_iommu *iommu)
+{
+	hyp_spin_lock_init(kvm_iommu_get_lock(iommu));
+}
+
+static inline void kvm_iommu_lock(struct kvm_hyp_iommu *iommu)
+{
+	hyp_spin_lock(kvm_iommu_get_lock(iommu));
+}
+
+static inline void kvm_iommu_unlock(struct kvm_hyp_iommu *iommu)
+{
+	hyp_spin_unlock(kvm_iommu_get_lock(iommu));
+}
+
 extern struct hyp_mgt_allocator_ops kvm_iommu_allocator_ops;
 
 #endif /* __ARM64_KVM_NVHE_IOMMU_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
index ba2aed52a74f..df2dbe4c0121 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -127,6 +127,19 @@ handle_to_domain(pkvm_handle_t domain_id)
 	return &domains[domain_id % KVM_IOMMU_DOMAINS_PER_PAGE];
 }
 
+static int domain_get(struct kvm_hyp_iommu_domain *domain)
+{
+	int old = atomic_fetch_inc_acquire(&domain->refs);
+
+	BUG_ON(!old || (old + 1 < 0));
+	return 0;
+}
+
+static void domain_put(struct kvm_hyp_iommu_domain *domain)
+{
+	BUG_ON(!atomic_dec_return_release(&domain->refs));
+}
+
 int kvm_iommu_init(void)
 {
 	int ret;
@@ -210,13 +223,44 @@ int kvm_iommu_free_domain(pkvm_handle_t domain_id)
 int kvm_iommu_attach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
 			 u32 endpoint_id, u32 pasid, u32 pasid_bits)
 {
-	return -ENODEV;
+	int ret;
+	struct kvm_hyp_iommu *iommu;
+	struct kvm_hyp_iommu_domain *domain;
+
+	iommu = kvm_iommu_ops->get_iommu_by_id(iommu_id);
+	if (!iommu)
+		return -EINVAL;
+
+	domain = handle_to_domain(domain_id);
+	if (!domain || domain_get(domain))
+		return -EINVAL;
+
+	ret = kvm_iommu_ops->attach_dev(iommu, domain, endpoint_id, pasid, pasid_bits);
+	if (ret)
+		domain_put(domain);
+	return ret;
 }
 
 int kvm_iommu_detach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
 			 u32 endpoint_id, u32 pasid)
 {
-	return -ENODEV;
+	int ret;
+	struct kvm_hyp_iommu *iommu;
+	struct kvm_hyp_iommu_domain *domain;
+
+	iommu = kvm_iommu_ops->get_iommu_by_id(iommu_id);
+	if (!iommu)
+		return -EINVAL;
+
+	domain = handle_to_domain(domain_id);
+	if (!domain || atomic_read(&domain->refs) <= 1)
+		return -EINVAL;
+
+	ret = kvm_iommu_ops->detach_dev(iommu, domain, endpoint_id, pasid);
+	if (ret)
+		return ret;
+	domain_put(domain);
+	return ret;
 }
 
 size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
@@ -236,3 +280,11 @@ phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova)
 {
 	return 0;
 }
+
+/* Must be called from the IOMMU driver per IOMMU */
+int kvm_iommu_init_device(struct kvm_hyp_iommu *iommu)
+{
+	kvm_iommu_lock_init(iommu);
+
+	return 0;
+}
diff --git a/include/kvm/iommu.h b/include/kvm/iommu.h
index 10ecaae0f6a3..6ff78d766466 100644
--- a/include/kvm/iommu.h
+++ b/include/kvm/iommu.h
@@ -45,4 +45,12 @@ extern void **kvm_nvhe_sym(kvm_hyp_iommu_domains);
 #define KVM_IOMMU_DOMAINS_ROOT_ORDER_NR	\
 	(1 << get_order(KVM_IOMMU_DOMAINS_ROOT_SIZE))
 
+struct kvm_hyp_iommu {
+#ifdef __KVM_NVHE_HYPERVISOR__
+	hyp_spinlock_t			lock;
+#else
+	u32				unused;
+#endif
+};
+
 #endif /* __KVM_IOMMU_H */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:42 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:42 +0000
Subject: [RFC PATCH v2 18/58] KVM: arm64: iommu: Add map/unmap() operations
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-19-smostafa@google.com>

Handle map(), unmap() and iova_to_phys() hypercalls.

In addition to map/unmap, the hypervisor has to ensure that all
mapped pages are tracked, so be before each map()
__pkvm_host_use_dma() would be called to ensure that.

Similarly, on unmap() we need to decrement the refcount using
__pkvm_host_unuse_dma().

However, doing this in standard way as mentioned in the comments is
challenging, so we leave that to the driver.

Also, the hypervisor only guarantees that there are no races
between alloc/free domain operations using the domain refcount to
avoid using extra locks.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 arch/arm64/kvm/hyp/include/nvhe/iommu.h |  7 +++
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c   | 80 ++++++++++++++++++++++++-
 2 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
index d6d7447fbac8..17f24a8eb1b9 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
@@ -40,6 +40,13 @@ struct kvm_iommu_ops {
 			  u32 endpoint_id, u32 pasid, u32 pasid_bits);
 	int (*detach_dev)(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_domain *domain,
 			  u32 endpoint_id, u32 pasid);
+	int (*map_pages)(struct kvm_hyp_iommu_domain *domain, unsigned long iova,
+			 phys_addr_t paddr, size_t pgsize,
+			 size_t pgcount, int prot, size_t *total_mapped);
+	size_t (*unmap_pages)(struct kvm_hyp_iommu_domain *domain, unsigned long iova,
+			      size_t pgsize, size_t pgcount);
+	phys_addr_t (*iova_to_phys)(struct kvm_hyp_iommu_domain *domain, unsigned long iova);
+
 };
 
 int kvm_iommu_init(void);
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
index df2dbe4c0121..83321cc5f466 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -263,22 +263,96 @@ int kvm_iommu_detach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
 	return ret;
 }
 
+#define IOMMU_PROT_MASK (IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE |\
+			 IOMMU_NOEXEC | IOMMU_MMIO | IOMMU_PRIV)
+
 size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
 			   unsigned long iova, phys_addr_t paddr, size_t pgsize,
 			   size_t pgcount, int prot)
 {
-	return 0;
+	size_t size;
+	int ret;
+	size_t total_mapped = 0;
+	struct kvm_hyp_iommu_domain *domain;
+
+	if (prot & ~IOMMU_PROT_MASK)
+		return 0;
+
+	if (__builtin_mul_overflow(pgsize, pgcount, &size) ||
+	    iova + size < iova || paddr + size < paddr)
+		return 0;
+
+	domain = handle_to_domain(domain_id);
+	if (!domain || domain_get(domain))
+		return 0;
+
+	ret = __pkvm_host_use_dma(paddr, size);
+	if (ret)
+		return 0;
+
+	kvm_iommu_ops->map_pages(domain, iova, paddr, pgsize, pgcount, prot, &total_mapped);
+
+	pgcount -= total_mapped / pgsize;
+	/*
+	 * unuse the bits that haven't been mapped yet. The host calls back
+	 * either to continue mapping, or to unmap and unuse what's been done
+	 * so far.
+	 */
+	if (pgcount)
+		__pkvm_host_unuse_dma(paddr + total_mapped, pgcount * pgsize);
+
+	domain_put(domain);
+	return total_mapped;
 }
 
 size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
 			     size_t pgsize, size_t pgcount)
 {
-	return 0;
+	size_t size;
+	size_t unmapped;
+	struct kvm_hyp_iommu_domain *domain;
+
+	if (!pgsize || !pgcount)
+		return 0;
+
+	if (__builtin_mul_overflow(pgsize, pgcount, &size) ||
+	    iova + size < iova)
+		return 0;
+
+	domain = handle_to_domain(domain_id);
+	if (!domain || domain_get(domain))
+		return 0;
+
+	/*
+	 * Unlike map, the common code doesn't call the __pkvm_host_unuse_dma,
+	 * because this means that we need either walk the table using iova_to_phys
+	 * similar to VFIO then unmap and call this function, or unmap leaf (page or
+	 * block) at a time, where both might be suboptimal.
+	 * For some IOMMU, we can do 2 walks where one only invalidate the pages
+	 * and the other decrement the refcount.
+	 * As, semantics for this might differ between IOMMUs and it's hard to
+	 * standardized, we leave that to the driver.
+	 */
+	unmapped = kvm_iommu_ops->unmap_pages(domain, iova, pgsize,
+						pgcount);
+
+	domain_put(domain);
+	return unmapped;
 }
 
 phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova)
 {
-	return 0;
+	phys_addr_t phys = 0;
+	struct kvm_hyp_iommu_domain *domain;
+
+	domain = handle_to_domain( domain_id);
+
+	if (!domain || domain_get(domain))
+		return 0;
+
+	phys = kvm_iommu_ops->iova_to_phys(domain, iova);
+	domain_put(domain);
+	return phys;
 }
 
 /* Must be called from the IOMMU driver per IOMMU */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:43 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:43 +0000
Subject: [RFC PATCH v2 19/58] KVM: arm64: iommu: support iommu_iotlb_gather
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-20-smostafa@google.com>

To improve unmap performance, we can batch TLB invalidations at the
end of the unmap similarly to what the kernel.

We use the same data structure as the kernel and most of the same
code.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/iommu.h | 11 +++++++++--
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c   | 22 +++++++++++++++++++++-
 include/linux/iommu.h                   | 24 +++++++++++++-----------
 3 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
index 17f24a8eb1b9..06d12b35fa3e 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
@@ -44,15 +44,22 @@ struct kvm_iommu_ops {
 			 phys_addr_t paddr, size_t pgsize,
 			 size_t pgcount, int prot, size_t *total_mapped);
 	size_t (*unmap_pages)(struct kvm_hyp_iommu_domain *domain, unsigned long iova,
-			      size_t pgsize, size_t pgcount);
+			      size_t pgsize, size_t pgcount,
+			      struct iommu_iotlb_gather *gather);
 	phys_addr_t (*iova_to_phys)(struct kvm_hyp_iommu_domain *domain, unsigned long iova);
-
+	void (*iotlb_sync)(struct kvm_hyp_iommu_domain *domain,
+			   struct iommu_iotlb_gather *gather);
 };
 
 int kvm_iommu_init(void);
 
 int kvm_iommu_init_device(struct kvm_hyp_iommu *iommu);
 
+void kvm_iommu_iotlb_gather_add_page(struct kvm_hyp_iommu_domain *domain,
+				     struct iommu_iotlb_gather *gather,
+				     unsigned long iova,
+				     size_t size);
+
 static inline hyp_spinlock_t *kvm_iommu_get_lock(struct kvm_hyp_iommu *iommu)
 {
 	/* See struct kvm_hyp_iommu */
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
index 83321cc5f466..a6e0f3634756 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -305,12 +305,30 @@ size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
 	return total_mapped;
 }
 
+static inline void kvm_iommu_iotlb_sync(struct kvm_hyp_iommu_domain *domain,
+					struct iommu_iotlb_gather *iotlb_gather)
+{
+	if (kvm_iommu_ops->iotlb_sync)
+		kvm_iommu_ops->iotlb_sync(domain, iotlb_gather);
+
+	iommu_iotlb_gather_init(iotlb_gather);
+}
+
+void kvm_iommu_iotlb_gather_add_page(struct kvm_hyp_iommu_domain *domain,
+				     struct iommu_iotlb_gather *gather,
+				     unsigned long iova,
+				     size_t size)
+{
+	_iommu_iotlb_add_page(domain, gather, iova, size, kvm_iommu_iotlb_sync);
+}
+
 size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
 			     size_t pgsize, size_t pgcount)
 {
 	size_t size;
 	size_t unmapped;
 	struct kvm_hyp_iommu_domain *domain;
+	struct iommu_iotlb_gather iotlb_gather;
 
 	if (!pgsize || !pgcount)
 		return 0;
@@ -323,6 +341,7 @@ size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
 	if (!domain || domain_get(domain))
 		return 0;
 
+	iommu_iotlb_gather_init(&iotlb_gather);
 	/*
 	 * Unlike map, the common code doesn't call the __pkvm_host_unuse_dma,
 	 * because this means that we need either walk the table using iova_to_phys
@@ -334,7 +353,8 @@ size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
 	 * standardized, we leave that to the driver.
 	 */
 	unmapped = kvm_iommu_ops->unmap_pages(domain, iova, pgsize,
-						pgcount);
+						pgcount, &iotlb_gather);
+	kvm_iommu_iotlb_sync(domain, &iotlb_gather);
 
 	domain_put(domain);
 	return unmapped;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index bd722f473635..c75877044185 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -911,6 +911,18 @@ static inline void iommu_iotlb_gather_add_range(struct iommu_iotlb_gather *gathe
 		gather->end = end;
 }
 
+/*
+ * If the new page is disjoint from the current range or is mapped at
+ * a different granularity, then sync the TLB so that the gather
+ * structure can be rewritten.
+ */
+#define _iommu_iotlb_add_page(domain, gather, iova, size, sync)		\
+	if (((gather)->pgsize && (gather)->pgsize != (size)) ||		\
+	    iommu_iotlb_gather_is_disjoint((gather), (iova), (size)))	\
+		sync((domain), (gather));				\
+	(gather)->pgsize = (size);					\
+	iommu_iotlb_gather_add_range((gather), (iova), (size))
+
 /**
  * iommu_iotlb_gather_add_page - Gather for page-based TLB invalidation
  * @domain: IOMMU domain to be invalidated
@@ -926,17 +938,7 @@ static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,
 					       struct iommu_iotlb_gather *gather,
 					       unsigned long iova, size_t size)
 {
-	/*
-	 * If the new page is disjoint from the current range or is mapped at
-	 * a different granularity, then sync the TLB so that the gather
-	 * structure can be rewritten.
-	 */
-	if ((gather->pgsize && gather->pgsize != size) ||
-	    iommu_iotlb_gather_is_disjoint(gather, iova, size))
-		iommu_iotlb_sync(domain, gather);
-
-	gather->pgsize = size;
-	iommu_iotlb_gather_add_range(gather, iova, size);
+	_iommu_iotlb_add_page(domain, gather, iova, size, iommu_iotlb_sync);
 }
 
 static inline bool iommu_iotlb_gather_queued(struct iommu_iotlb_gather *gather)
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:44 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:44 +0000
Subject: [RFC PATCH v2 20/58] KVM: arm64: Support power domains
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-21-smostafa@google.com>

Unfortunately, as power management is not widely standardized we have
to work around that.

One implementation we can support is HOST_HVC, where the host
is in control of the power management and it notifies the
hypervisor about the updates.

This adds extra constraints to the IOMMUs, as they must reset to
blocking DMA traffic to be able to use this PD interface.

Unfortunately again, for SMMUv3 which is the only IOMMU currently
supported, there is no architectural way to discover this, so we
rely on enabling this driver when it fits the constraints, also
the driver sets GBPA and assumes that the SMMU retains across
power cycling.

In the next patch SCMI support is added.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 arch/arm64/include/asm/kvm_asm.h       |  1 +
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h | 30 ++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/Makefile       |  2 +-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c     |  9 +++++
 arch/arm64/kvm/hyp/nvhe/power/hvc.c    | 47 ++++++++++++++++++++++++++
 include/kvm/power_domain.h             | 17 ++++++++++
 6 files changed, 105 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/kvm/hyp/nvhe/power/hvc.c
 create mode 100644 include/kvm/power_domain.h

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 9ea155a04332..3dbf30cd10f3 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -114,6 +114,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_map_pages,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_unmap_pages,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_iova_to_phys,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_hvc_pd,
 
 	/*
 	 * Start of the dynamically registered hypercalls. Start a bit
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 8a5554615e40..e4a94696b10e 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -8,6 +8,7 @@
 #define __ARM64_KVM_NVHE_PKVM_H__
 
 #include <asm/kvm_pkvm.h>
+#include <kvm/power_domain.h>
 
 #include <nvhe/gfp.h>
 #include <nvhe/spinlock.h>
@@ -146,4 +147,33 @@ void pkvm_poison_pvmfw_pages(void);
 int pkvm_timer_init(void);
 void pkvm_udelay(unsigned long usecs);
 
+#define MAX_POWER_DOMAINS		32
+
+struct kvm_power_domain_ops {
+	int (*power_on)(struct kvm_power_domain *pd);
+	int (*power_off)(struct kvm_power_domain *pd);
+};
+
+int pkvm_init_hvc_pd(struct kvm_power_domain *pd,
+		     const struct kvm_power_domain_ops *ops);
+
+int pkvm_host_hvc_pd(u64 device_id, u64 on);
+
+/*
+ * Register a power domain. When the hypervisor catches power requests from the
+ * host for this power domain, it calls the power ops with @pd as argument.
+ */
+static inline int pkvm_init_power_domain(struct kvm_power_domain *pd,
+					 const struct kvm_power_domain_ops *ops)
+{
+	switch (pd->type) {
+	case KVM_POWER_DOMAIN_NONE:
+		return 0;
+	case KVM_POWER_DOMAIN_HOST_HVC:
+		return pkvm_init_hvc_pd(pd, ops);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 9e1b74c661d2..950d34ba6e50 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -8,7 +8,7 @@ CFLAGS_switch.nvhe.o += -Wno-override-init
 hyp-obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
 	 hyp-main.o hyp-smp.o psci-relay.o alloc.o early_alloc.o page_alloc.o \
 	 cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o stacktrace.o ffa.o \
-	 serial.o alloc_mgt.o iommu/iommu.o
+	 serial.o alloc_mgt.o iommu/iommu.o power/hvc.o
 hyp-obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
 	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
 hyp-obj-$(CONFIG_LIST_HARDENED) += list_debug.o
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 9b224842c487..5df98bf04ef4 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -1674,6 +1674,14 @@ static void handle___pkvm_host_iommu_iova_to_phys(struct kvm_cpu_context *host_c
 	cpu_reg(host_ctxt, 1) = kvm_iommu_iova_to_phys(domain, iova);
 }
 
+static void handle___pkvm_host_hvc_pd(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, device_id, host_ctxt, 1);
+	DECLARE_REG(u64, on, host_ctxt, 2);
+
+	cpu_reg(host_ctxt, 1) = pkvm_host_hvc_pd(device_id, on);
+}
+
 typedef void (*hcall_t)(struct kvm_cpu_context *);
 
 #define HANDLE_FUNC(x)	[__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x
@@ -1738,6 +1746,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_iommu_map_pages),
 	HANDLE_FUNC(__pkvm_host_iommu_unmap_pages),
 	HANDLE_FUNC(__pkvm_host_iommu_iova_to_phys),
+	HANDLE_FUNC(__pkvm_host_hvc_pd),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/power/hvc.c b/arch/arm64/kvm/hyp/nvhe/power/hvc.c
new file mode 100644
index 000000000000..f4d811847e73
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/power/hvc.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 Google LLC
+ * Author: Mostafa Saleh <smostafa at google.com>
+ */
+
+#include <nvhe/pkvm.h>
+
+struct hvc_power_domain {
+	struct kvm_power_domain			*pd;
+	const struct kvm_power_domain_ops	*ops;
+};
+
+struct hvc_power_domain handlers[MAX_POWER_DOMAINS];
+
+int pkvm_init_hvc_pd(struct kvm_power_domain *pd,
+		     const struct kvm_power_domain_ops *ops)
+{
+	if (pd->device_id >= MAX_POWER_DOMAINS)
+		return -E2BIG;
+
+	handlers[pd->device_id].ops = ops;
+	handlers[pd->device_id].pd = pd;
+
+	return 0;
+}
+
+int pkvm_host_hvc_pd(u64 device_id, u64 on)
+{
+	struct hvc_power_domain *pd;
+
+	if (device_id >= MAX_POWER_DOMAINS)
+		return -E2BIG;
+
+	device_id = array_index_nospec(device_id, MAX_POWER_DOMAINS);
+	pd = &handlers[device_id];
+
+	if (!pd->ops)
+		return -ENOENT;
+
+	if (on)
+		pd->ops->power_on(pd->pd);
+	else
+		pd->ops->power_off(pd->pd);
+
+	return 0;
+}
diff --git a/include/kvm/power_domain.h b/include/kvm/power_domain.h
new file mode 100644
index 000000000000..f6a9c5cdfebb
--- /dev/null
+++ b/include/kvm/power_domain.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __KVM_POWER_DOMAIN_H
+#define __KVM_POWER_DOMAIN_H
+
+enum kvm_power_domain_type {
+	KVM_POWER_DOMAIN_NONE,
+	KVM_POWER_DOMAIN_HOST_HVC,
+};
+
+struct kvm_power_domain {
+	enum kvm_power_domain_type	type;
+	union {
+		u64 device_id; /* HOST_HVC device ID*/
+	};
+};
+
+#endif /* __KVM_POWER_DOMAIN_H */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:45 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:45 +0000
Subject: [RFC PATCH v2 21/58] KVM: arm64: pkvm: Add __pkvm_host_add_remove_page()
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-22-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Add a small helper to remove and add back a page from the host stage-2.
This will be used to temporarily unmap a piece of shared sram (device
memory) from the host while we handle a SCMI request, preventing the
host from modifying the request after it is verified.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index d75e64e59596..c8f49b335093 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -94,6 +94,7 @@ int __pkvm_guest_relinquish_to_host(struct pkvm_hyp_vcpu *vcpu,
 				    u64 ipa, u64 *ppa);
 int __pkvm_host_use_dma(u64 phys_addr, size_t size);
 int __pkvm_host_unuse_dma(u64 phys_addr, size_t size);
+int __pkvm_host_add_remove_page(u64 pfn, bool remove);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 0840af20c366..a428ad9ca871 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -2521,3 +2521,20 @@ int host_stage2_get_leaf(phys_addr_t phys, kvm_pte_t *ptep, s8 *level)
 
 	return ret;
 }
+
+/*
+ * Temporarily unmap a page from the host stage-2, if @remove is true, or put it
+ * back. After restoring the ownership to host, the page will be lazy-mapped.
+ */
+int __pkvm_host_add_remove_page(u64 pfn, bool remove)
+{
+	int ret;
+	u64 host_addr = hyp_pfn_to_phys(pfn);
+	u8 owner = remove ? PKVM_ID_HYP : PKVM_ID_HOST;
+
+	host_lock_component();
+	ret = host_stage2_set_owner_locked(host_addr, PAGE_SIZE, owner);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:46 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:46 +0000
Subject: [RFC PATCH v2 22/58] KVM: arm64: pkvm: Support SCMI power domain
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-23-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

The hypervisor needs to catch power domain changes for devices it owns,
such as the SMMU. Possible reasons:

* Ensure that software and hardware states are consistent. The driver
  does not attempt to modify the state while the device is off.
* Save and restore the device state.
* Enforce dependency between consumers and suppliers. For example ensure
  that endpoints are off before turning the SMMU off, in case a powered
  off SMMU lets DMA through. However this is normally enforced by
  firmware.

Add a SCMI power domain, as the standard method for device power
management on Arm. Other methods can be added to kvm_power_domain later.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/include/asm/kvm_hyp.h              |   2 +
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |   4 +
 .../arm64/kvm/hyp/include/nvhe/trap_handler.h |   2 +
 arch/arm64/kvm/hyp/nvhe/Makefile              |   2 +-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            |   2 +
 arch/arm64/kvm/hyp/nvhe/power/scmi.c          | 231 ++++++++++++++++++
 include/kvm/power_domain.h                    |   7 +
 7 files changed, 249 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/kvm/hyp/nvhe/power/scmi.c

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index ee85c6dfb504..0257e8e37434 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -119,7 +119,9 @@ void __sve_restore_state(void *sve_pffr, u32 *fpsr, int restore_ffr);
 
 u64 __guest_enter(struct kvm_vcpu *vcpu);
 
+
 bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id);
+bool kvm_host_scmi_handler(struct kvm_cpu_context *host_ctxt);
 
 #ifdef __KVM_NVHE_HYPERVISOR__
 void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index e4a94696b10e..4d40c536d26a 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -158,6 +158,8 @@ int pkvm_init_hvc_pd(struct kvm_power_domain *pd,
 		     const struct kvm_power_domain_ops *ops);
 
 int pkvm_host_hvc_pd(u64 device_id, u64 on);
+int pkvm_init_scmi_pd(struct kvm_power_domain *pd,
+		      const struct kvm_power_domain_ops *ops);
 
 /*
  * Register a power domain. When the hypervisor catches power requests from the
@@ -171,6 +173,8 @@ static inline int pkvm_init_power_domain(struct kvm_power_domain *pd,
 		return 0;
 	case KVM_POWER_DOMAIN_HOST_HVC:
 		return pkvm_init_hvc_pd(pd, ops);
+	case KVM_POWER_DOMAIN_ARM_SCMI:
+		return pkvm_init_scmi_pd(pd, ops);
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/arch/arm64/kvm/hyp/include/nvhe/trap_handler.h b/arch/arm64/kvm/hyp/include/nvhe/trap_handler.h
index 1e6d995968a1..0e6bb92ccdb7 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/trap_handler.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/trap_handler.h
@@ -15,4 +15,6 @@
 #define DECLARE_REG(type, name, ctxt, reg)	\
 				type name = (type)cpu_reg(ctxt, (reg))
 
+void __kvm_hyp_host_forward_smc(struct kvm_cpu_context *host_ctxt);
+
 #endif /* __ARM64_KVM_NVHE_TRAP_HANDLER_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 950d34ba6e50..d846962e7246 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -8,7 +8,7 @@ CFLAGS_switch.nvhe.o += -Wno-override-init
 hyp-obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
 	 hyp-main.o hyp-smp.o psci-relay.o alloc.o early_alloc.o page_alloc.o \
 	 cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o stacktrace.o ffa.o \
-	 serial.o alloc_mgt.o iommu/iommu.o power/hvc.o
+	 serial.o alloc_mgt.o iommu/iommu.o power/hvc.o power/scmi.o
 hyp-obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
 	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
 hyp-obj-$(CONFIG_LIST_HARDENED) += list_debug.o
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 5df98bf04ef4..1ab8e5507825 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -1806,6 +1806,8 @@ static void handle_host_smc(struct kvm_cpu_context *host_ctxt)
 	handled = kvm_host_psci_handler(host_ctxt, func_id);
 	if (!handled)
 		handled = kvm_host_ffa_handler(host_ctxt, func_id);
+	if (!handled)
+		handled = kvm_host_scmi_handler(host_ctxt);
 	if (!handled && smp_load_acquire(&default_host_smc_handler))
 		handled = default_host_smc_handler(&host_ctxt->regs);
 	if (!handled) {
diff --git a/arch/arm64/kvm/hyp/nvhe/power/scmi.c b/arch/arm64/kvm/hyp/nvhe/power/scmi.c
new file mode 100644
index 000000000000..7de3feb2f1d9
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/power/scmi.c
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Linaro Ltd.
+ */
+
+#include <linux/bitfield.h>
+
+#include <nvhe/pkvm.h>
+#include <nvhe/mm.h>
+#include <nvhe/mem_protect.h>
+#include <nvhe/trap_handler.h>
+
+/* SCMI protocol */
+#define SCMI_PROTOCOL_POWER_DOMAIN	0x11
+
+/*  shmem registers */
+#define SCMI_SHM_CHANNEL_STATUS		0x4
+#define SCMI_SHM_CHANNEL_FLAGS		0x10
+#define SCMI_SHM_LENGTH			0x14
+#define SCMI_SHM_MESSAGE_HEADER		0x18
+#define SCMI_SHM_MESSAGE_PAYLOAD	0x1c
+
+/*  channel status */
+#define SCMI_CHN_FREE			(1U << 0)
+#define SCMI_CHN_ERROR			(1U << 1)
+
+/*  channel flags */
+#define SCMI_CHN_IRQ			(1U << 0)
+
+/*  message header */
+#define SCMI_HDR_TOKEN			GENMASK(27, 18)
+#define SCMI_HDR_PROTOCOL_ID		GENMASK(17, 10)
+#define SCMI_HDR_MESSAGE_TYPE		GENMASK(9, 8)
+#define SCMI_HDR_MESSAGE_ID		GENMASK(7, 0)
+
+/*  power domain */
+#define SCMI_PD_STATE_SET		0x4
+#define SCMI_PD_STATE_SET_FLAGS		0x0
+#define SCMI_PD_STATE_SET_DOMAIN_ID	0x4
+#define SCMI_PD_STATE_SET_POWER_STATE	0x8
+
+#define SCMI_PD_STATE_SET_STATUS	0x0
+
+#define SCMI_PD_STATE_SET_FLAGS_ASYNC	(1U << 0)
+
+#define SCMI_PD_POWER_ON		0
+#define SCMI_PD_POWER_OFF		(1U << 30)
+
+#define SCMI_SUCCESS			0
+
+
+static struct {
+	u32				smc_id;
+	phys_addr_t			shmem_pfn;
+	size_t				shmem_size;
+	void __iomem			*shmem;
+} scmi_channel;
+
+struct scmi_power_domain {
+	struct kvm_power_domain			*pd;
+	const struct kvm_power_domain_ops	*ops;
+};
+
+static struct scmi_power_domain scmi_power_domains[MAX_POWER_DOMAINS];
+static int scmi_power_domain_count;
+
+#define SCMI_POLL_TIMEOUT_US	1000000 /* 1s! */
+
+/* Forward the command to EL3, and wait for completion */
+static int scmi_run_command(struct kvm_cpu_context *host_ctxt)
+{
+	u32 reg;
+	unsigned long i = 0;
+
+	__kvm_hyp_host_forward_smc(host_ctxt);
+
+	do {
+		reg = readl_relaxed(scmi_channel.shmem + SCMI_SHM_CHANNEL_STATUS);
+		if (reg & SCMI_CHN_FREE)
+			break;
+
+		if (WARN_ON(++i > SCMI_POLL_TIMEOUT_US))
+			return -ETIMEDOUT;
+
+		pkvm_udelay(1);
+	} while (!(reg & (SCMI_CHN_FREE | SCMI_CHN_ERROR)));
+
+	if (reg & SCMI_CHN_ERROR)
+		return -EIO;
+
+	reg = readl_relaxed(scmi_channel.shmem + SCMI_SHM_MESSAGE_PAYLOAD +
+			    SCMI_PD_STATE_SET_STATUS);
+	if (reg != SCMI_SUCCESS)
+		return -EIO;
+
+	return 0;
+}
+
+static void __kvm_host_scmi_handler(struct kvm_cpu_context *host_ctxt)
+{
+	int i;
+	u32 reg;
+	struct scmi_power_domain *scmi_pd = NULL;
+
+	/*
+	 * FIXME: the spec does not really allow for an intermediary filtering
+	 * messages on the channel: as soon as the host clears SCMI_CHN_FREE,
+	 * the server may process the message. It doesn't have to wait for a
+	 * doorbell and could just poll on the shared mem. Unlikely in practice,
+	 * but this code is not correct without a spec change requiring the
+	 * server to observe an SMC before processing the message.
+	 */
+	reg = readl_relaxed(scmi_channel.shmem + SCMI_SHM_CHANNEL_STATUS);
+	if (reg & (SCMI_CHN_FREE | SCMI_CHN_ERROR))
+		return;
+
+	reg = readl_relaxed(scmi_channel.shmem + SCMI_SHM_MESSAGE_HEADER);
+	if (FIELD_GET(SCMI_HDR_PROTOCOL_ID, reg) != SCMI_PROTOCOL_POWER_DOMAIN)
+		goto out_forward_smc;
+
+	if (FIELD_GET(SCMI_HDR_MESSAGE_ID, reg) != SCMI_PD_STATE_SET)
+		goto out_forward_smc;
+
+	reg = readl_relaxed(scmi_channel.shmem + SCMI_SHM_MESSAGE_PAYLOAD +
+			    SCMI_PD_STATE_SET_FLAGS);
+	if (WARN_ON(reg & SCMI_PD_STATE_SET_FLAGS_ASYNC))
+		/* We don't support async requests at the moment */
+		return;
+
+	reg = readl_relaxed(scmi_channel.shmem + SCMI_SHM_MESSAGE_PAYLOAD +
+			    SCMI_PD_STATE_SET_DOMAIN_ID);
+
+	for (i = 0; i < MAX_POWER_DOMAINS; i++) {
+		if (!scmi_power_domains[i].pd)
+			break;
+
+		if (reg == scmi_power_domains[i].pd->arm_scmi.domain_id) {
+			scmi_pd = &scmi_power_domains[i];
+			break;
+		}
+	}
+	if (!scmi_pd)
+		goto out_forward_smc;
+
+	reg = readl_relaxed(scmi_channel.shmem + SCMI_SHM_MESSAGE_PAYLOAD +
+			    SCMI_PD_STATE_SET_POWER_STATE);
+	switch (reg) {
+	case SCMI_PD_POWER_ON:
+		if (scmi_run_command(host_ctxt))
+			break;
+
+		scmi_pd->ops->power_on(scmi_pd->pd);
+		break;
+	case SCMI_PD_POWER_OFF:
+		scmi_pd->ops->power_off(scmi_pd->pd);
+
+		if (scmi_run_command(host_ctxt))
+			scmi_pd->ops->power_on(scmi_pd->pd);
+		break;
+	}
+	return;
+
+out_forward_smc:
+	__kvm_hyp_host_forward_smc(host_ctxt);
+}
+
+bool kvm_host_scmi_handler(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, func_id, host_ctxt, 0);
+
+	if (!scmi_channel.shmem || func_id != scmi_channel.smc_id)
+		return false; /* Unhandled */
+
+	/*
+	 * Prevent the host from modifying the request while it is in flight.
+	 * One page is enough, SCMI messages are smaller than that.
+	 *
+	 * FIXME: the host is allowed to poll the shmem while the request is in
+	 * flight, or read shmem when receiving the SCMI interrupt. Although
+	 * it's unlikely with the SMC-based transport, this too requires some
+	 * tightening in the spec.
+	 */
+	if (WARN_ON(__pkvm_host_add_remove_page(scmi_channel.shmem_pfn, true)))
+		return true;
+
+	__kvm_host_scmi_handler(host_ctxt);
+
+	WARN_ON(__pkvm_host_add_remove_page(scmi_channel.shmem_pfn, false));
+	return true; /* Handled */
+}
+
+int pkvm_init_scmi_pd(struct kvm_power_domain *pd,
+		      const struct kvm_power_domain_ops *ops)
+{
+	int ret;
+
+	if (!IS_ALIGNED(pd->arm_scmi.shmem_base, PAGE_SIZE) ||
+	    pd->arm_scmi.shmem_size < PAGE_SIZE) {
+		return -EINVAL;
+	}
+
+	if (!scmi_channel.shmem) {
+		unsigned long shmem;
+
+		/* FIXME: Do we need to mark those pages shared in the host s2? */
+		ret = __pkvm_create_private_mapping(pd->arm_scmi.shmem_base,
+						    pd->arm_scmi.shmem_size,
+						    PAGE_HYP_DEVICE,
+						    &shmem);
+		if (ret)
+			return ret;
+
+		scmi_channel.smc_id = pd->arm_scmi.smc_id;
+		scmi_channel.shmem_pfn = hyp_phys_to_pfn(pd->arm_scmi.shmem_base);
+		scmi_channel.shmem = (void *)shmem;
+
+	} else if (scmi_channel.shmem_pfn !=
+		   hyp_phys_to_pfn(pd->arm_scmi.shmem_base) ||
+		   scmi_channel.smc_id != pd->arm_scmi.smc_id) {
+		/* We support a single channel at the moment */
+		return -ENXIO;
+	}
+
+	if (scmi_power_domain_count == MAX_POWER_DOMAINS)
+		return -ENOSPC;
+
+	scmi_power_domains[scmi_power_domain_count].pd = pd;
+	scmi_power_domains[scmi_power_domain_count].ops = ops;
+	scmi_power_domain_count++;
+	return 0;
+}
diff --git a/include/kvm/power_domain.h b/include/kvm/power_domain.h
index f6a9c5cdfebb..9ade1d60f5f5 100644
--- a/include/kvm/power_domain.h
+++ b/include/kvm/power_domain.h
@@ -5,12 +5,19 @@
 enum kvm_power_domain_type {
 	KVM_POWER_DOMAIN_NONE,
 	KVM_POWER_DOMAIN_HOST_HVC,
+	KVM_POWER_DOMAIN_ARM_SCMI,
 };
 
 struct kvm_power_domain {
 	enum kvm_power_domain_type	type;
 	union {
 		u64 device_id; /* HOST_HVC device ID*/
+		struct {
+			u32		smc_id;
+			u32		domain_id;
+			phys_addr_t	shmem_base;
+			size_t		shmem_size;
+		} arm_scmi; /*ARM_SCMI channel */
 	};
 };
 
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:47 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:47 +0000
Subject: [RFC PATCH v2 23/58] KVM: arm64: iommu: Support power management
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-24-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Add power domain ops to the hypervisor IOMMU driver. We currently make
these assumptions:

* The register state is retained across power off.
* The TLBs are clean on power on.
* Another privileged software (EL3 or SCP FW) handles dependencies
  between SMMU and endpoints.

So we just need to make sure that the CPU does not touch the SMMU
registers while it is powered off.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c | 33 ++++++++++++++++++++++++++-
 include/kvm/iommu.h                   |  3 +++
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
index a6e0f3634756..fbab335d3490 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -375,10 +375,41 @@ phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova)
 	return phys;
 }
 
+static int iommu_power_on(struct kvm_power_domain *pd)
+{
+	struct kvm_hyp_iommu *iommu = container_of(pd, struct kvm_hyp_iommu,
+						   power_domain);
+
+	/*
+	 * We currently assume that the device retains its architectural state
+	 * across power off, hence no save/restore.
+	 */
+	kvm_iommu_lock(iommu);
+	iommu->power_is_off = false;
+	kvm_iommu_unlock(iommu);
+	return 0;
+}
+
+static int iommu_power_off(struct kvm_power_domain *pd)
+{
+	struct kvm_hyp_iommu *iommu = container_of(pd, struct kvm_hyp_iommu,
+						   power_domain);
+
+	kvm_iommu_lock(iommu);
+	iommu->power_is_off = true;
+	kvm_iommu_unlock(iommu);
+	return 0;
+}
+
+static const struct kvm_power_domain_ops iommu_power_ops = {
+	.power_on	= iommu_power_on,
+	.power_off	= iommu_power_off,
+};
+
 /* Must be called from the IOMMU driver per IOMMU */
 int kvm_iommu_init_device(struct kvm_hyp_iommu *iommu)
 {
 	kvm_iommu_lock_init(iommu);
 
-	return 0;
+	return pkvm_init_power_domain(&iommu->power_domain, &iommu_power_ops);
 }
diff --git a/include/kvm/iommu.h b/include/kvm/iommu.h
index 6ff78d766466..c524ba84a9cf 100644
--- a/include/kvm/iommu.h
+++ b/include/kvm/iommu.h
@@ -3,6 +3,7 @@
 #define __KVM_IOMMU_H
 
 #include <asm/kvm_host.h>
+#include <kvm/power_domain.h>
 #include <linux/io-pgtable.h>
 #ifdef __KVM_NVHE_HYPERVISOR__
 #include <nvhe/spinlock.h>
@@ -51,6 +52,8 @@ struct kvm_hyp_iommu {
 #else
 	u32				unused;
 #endif
+	struct kvm_power_domain		power_domain;
+	bool				power_is_off;
 };
 
 #endif /* __KVM_IOMMU_H */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:48 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:48 +0000
Subject: [RFC PATCH v2 24/58] KVM: arm64: iommu: Support DABT for IOMMU
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-25-smostafa@google.com>

Soon, SMMUv3 driver would be added and it would need to emulate
access to some of its MMIO space.

Add a handler for DABTs for IOMMU drivers to be able to do so.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/iommu.h |  2 ++
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c   | 17 +++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c   | 19 +++++++++++++++++--
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
index 06d12b35fa3e..cff75d67d807 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
@@ -21,6 +21,7 @@ size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
 size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
 			     size_t pgsize, size_t pgcount);
 phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova);
+bool kvm_iommu_host_dabt_handler(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr);
 
 /* Flags for memory allocation for IOMMU drivers */
 #define IOMMU_PAGE_NOCACHE				BIT(0)
@@ -49,6 +50,7 @@ struct kvm_iommu_ops {
 	phys_addr_t (*iova_to_phys)(struct kvm_hyp_iommu_domain *domain, unsigned long iova);
 	void (*iotlb_sync)(struct kvm_hyp_iommu_domain *domain,
 			   struct iommu_iotlb_gather *gather);
+	bool (*dabt_handler)(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr);
 };
 
 int kvm_iommu_init(void);
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
index fbab335d3490..e45dadd0c4aa 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -4,6 +4,10 @@
  *
  * Copyright (C) 2022 Linaro Ltd.
  */
+#include <asm/kvm_hyp.h>
+
+#include <hyp/adjust_pc.h>
+
 #include <kvm/iommu.h>
 
 #include <nvhe/iommu.h>
@@ -375,6 +379,19 @@ phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova)
 	return phys;
 }
 
+bool kvm_iommu_host_dabt_handler(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr)
+{
+	bool ret = false;
+
+	if (kvm_iommu_ops && kvm_iommu_ops->dabt_handler)
+		ret = kvm_iommu_ops->dabt_handler(host_ctxt, esr, addr);
+
+	if (ret)
+		kvm_skip_host_instr();
+
+	return ret;
+}
+
 static int iommu_power_on(struct kvm_power_domain *pd)
 {
 	struct kvm_hyp_iommu *iommu = container_of(pd, struct kvm_hyp_iommu,
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index a428ad9ca871..0fae651107db 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -16,6 +16,7 @@
 #include <hyp/fault.h>
 
 #include <nvhe/gfp.h>
+#include <nvhe/iommu.h>
 #include <nvhe/memory.h>
 #include <nvhe/mem_protect.h>
 #include <nvhe/mm.h>
@@ -799,11 +800,16 @@ static int handle_host_perm_fault(struct kvm_cpu_context *host_ctxt, u64 esr, u6
 	return handled ? 0 : -EPERM;
 }
 
+static bool is_dabt(u64 esr)
+{
+	return ESR_ELx_EC(esr) == ESR_ELx_EC_DABT_LOW;
+}
+
 void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
 {
 	struct kvm_vcpu_fault_info fault;
 	u64 esr, addr;
-	int ret = 0;
+	int ret = -EPERM;
 
 	esr = read_sysreg_el2(SYS_ESR);
 	if (!__get_fault_info(esr, &fault)) {
@@ -817,7 +823,15 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
 	}
 
 	addr = (fault.hpfar_el2 & HPFAR_MASK) << 8;
-	ret = host_stage2_idmap(addr);
+	addr |= fault.far_el2 & FAR_MASK;
+
+	if (is_dabt(esr) && !addr_is_memory(addr) &&
+	    kvm_iommu_host_dabt_handler(host_ctxt, esr, addr))
+		goto return_to_host;
+
+	/* If not handled, attempt to map the page. */
+	if (ret == -EPERM)
+		ret = host_stage2_idmap(addr);
 
 	if ((esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_PERM)
 		ret = handle_host_perm_fault(host_ctxt, esr, addr);
@@ -827,6 +841,7 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
 	else
 		BUG_ON(ret && ret != -EAGAIN);
 
+return_to_host:
 	trace_host_mem_abort(esr, addr);
 }
 
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:49 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:49 +0000
Subject: [RFC PATCH v2 25/58] KVM: arm64: iommu: Add SMMUv3 driver
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-26-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Add the skeleton for an Arm SMMUv3 driver at EL2.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/Makefile            |  2 ++
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 22 +++++++++++++++++++++
 drivers/iommu/Kconfig                       |  9 +++++++++
 include/kvm/arm_smmu_v3.h                   | 18 +++++++++++++++++
 4 files changed, 51 insertions(+)
 create mode 100644 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
 create mode 100644 include/kvm/arm_smmu_v3.h

diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index d846962e7246..edfd8a11ac90 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -16,6 +16,8 @@ hyp-obj-$(CONFIG_TRACING) += clock.o events.o trace.o
 hyp-obj-$(CONFIG_MODULES) += modules.o
 hyp-obj-y += $(lib-objs)
 
+hyp-obj-$(CONFIG_ARM_SMMU_V3_PKVM) += iommu/arm-smmu-v3.o
+
 $(obj)/hyp.lds: $(src)/hyp.lds.S FORCE
 	$(call if_changed_dep,cpp_lds_S)
 
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
new file mode 100644
index 000000000000..d2a570c9f3ec
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pKVM hyp driver for the Arm SMMUv3
+ *
+ * Copyright (C) 2022 Linaro Ltd.
+ */
+#include <asm/kvm_hyp.h>
+#include <kvm/arm_smmu_v3.h>
+#include <nvhe/iommu.h>
+
+size_t __ro_after_init kvm_hyp_arm_smmu_v3_count;
+struct hyp_arm_smmu_v3_device *kvm_hyp_arm_smmu_v3_smmus;
+
+static int smmu_init(void)
+{
+	return -ENOSYS;
+}
+
+/* Shared with the kernel driver in EL1 */
+struct kvm_iommu_ops smmu_ops = {
+	.init				= smmu_init,
+};
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index b3aa1f5d5321..fea5d6a8b90b 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -437,6 +437,15 @@ config TEGRA241_CMDQV
 	  CMDQ-V extension.
 endif
 
+config ARM_SMMU_V3_PKVM
+	bool "ARM SMMUv3 support for protected Virtual Machines"
+	depends on KVM && ARM64
+	help
+	  Enable a SMMUv3 driver in the KVM hypervisor, to protect VMs against
+	  memory accesses from devices owned by the host.
+
+	  Say Y here if you intend to enable KVM in protected mode.
+
 config S390_IOMMU
 	def_bool y if S390 && PCI
 	depends on S390 && PCI
diff --git a/include/kvm/arm_smmu_v3.h b/include/kvm/arm_smmu_v3.h
new file mode 100644
index 000000000000..521028b3ff71
--- /dev/null
+++ b/include/kvm/arm_smmu_v3.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __KVM_ARM_SMMU_V3_H
+#define __KVM_ARM_SMMU_V3_H
+
+#include <asm/kvm_asm.h>
+#include <kvm/iommu.h>
+
+struct hyp_arm_smmu_v3_device {
+	struct kvm_hyp_iommu	iommu;
+};
+
+extern size_t kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count);
+#define kvm_hyp_arm_smmu_v3_count kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count)
+
+extern struct hyp_arm_smmu_v3_device *kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_smmus);
+#define kvm_hyp_arm_smmu_v3_smmus kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_smmus)
+
+#endif /* __KVM_ARM_SMMU_V3_H */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:50 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:50 +0000
Subject: [RFC PATCH v2 26/58] KVM: arm64: smmu-v3: Initialize registers
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-27-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Ensure all writable registers are properly initialized. We do not touch
registers that will not be read by the SMMU due to disabled features.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 130 +++++++++++++++++++-
 include/kvm/arm_smmu_v3.h                   |  11 ++
 2 files changed, 140 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index d2a570c9f3ec..f7e60c188cb0 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -4,16 +4,144 @@
  *
  * Copyright (C) 2022 Linaro Ltd.
  */
+#include <asm/arm-smmu-v3-common.h>
 #include <asm/kvm_hyp.h>
 #include <kvm/arm_smmu_v3.h>
 #include <nvhe/iommu.h>
+#include <nvhe/mem_protect.h>
+#include <nvhe/mm.h>
+#include <nvhe/pkvm.h>
+
+#define ARM_SMMU_POLL_TIMEOUT_US	100000 /* 100ms arbitrary timeout */
 
 size_t __ro_after_init kvm_hyp_arm_smmu_v3_count;
 struct hyp_arm_smmu_v3_device *kvm_hyp_arm_smmu_v3_smmus;
 
+#define for_each_smmu(smmu) \
+	for ((smmu) = kvm_hyp_arm_smmu_v3_smmus; \
+	     (smmu) != &kvm_hyp_arm_smmu_v3_smmus[kvm_hyp_arm_smmu_v3_count]; \
+	     (smmu)++)
+
+/*
+ * Wait until @cond is true.
+ * Return 0 on success, or -ETIMEDOUT
+ */
+#define smmu_wait(_cond)					\
+({								\
+	int __i = 0;						\
+	int __ret = 0;						\
+								\
+	while (!(_cond)) {					\
+		if (++__i > ARM_SMMU_POLL_TIMEOUT_US) {		\
+			__ret = -ETIMEDOUT;			\
+			break;					\
+		}						\
+		pkvm_udelay(1);					\
+	}							\
+	__ret;							\
+})
+
+static int smmu_write_cr0(struct hyp_arm_smmu_v3_device *smmu, u32 val)
+{
+	writel_relaxed(val, smmu->base + ARM_SMMU_CR0);
+	return smmu_wait(readl_relaxed(smmu->base + ARM_SMMU_CR0ACK) == val);
+}
+
+/* Transfer ownership of structures from host to hyp */
+static int smmu_take_pages(u64 phys, size_t size)
+{
+	WARN_ON(!PAGE_ALIGNED(phys) || !PAGE_ALIGNED(size));
+	return __pkvm_host_donate_hyp(phys >> PAGE_SHIFT, size >> PAGE_SHIFT);
+}
+
+static void smmu_reclaim_pages(u64 phys, size_t size)
+{
+	WARN_ON(!PAGE_ALIGNED(phys) || !PAGE_ALIGNED(size));
+	WARN_ON(__pkvm_hyp_donate_host(phys >> PAGE_SHIFT, size >> PAGE_SHIFT));
+}
+
+static int smmu_init_registers(struct hyp_arm_smmu_v3_device *smmu)
+{
+	u64 val, old;
+	int ret;
+
+	if (!(readl_relaxed(smmu->base + ARM_SMMU_GBPA) & GBPA_ABORT))
+		return -EINVAL;
+
+	/* Initialize all RW registers that will be read by the SMMU */
+	ret = smmu_write_cr0(smmu, 0);
+	if (ret)
+		return ret;
+
+	val = FIELD_PREP(CR1_TABLE_SH, ARM_SMMU_SH_ISH) |
+	      FIELD_PREP(CR1_TABLE_OC, CR1_CACHE_WB) |
+	      FIELD_PREP(CR1_TABLE_IC, CR1_CACHE_WB) |
+	      FIELD_PREP(CR1_QUEUE_SH, ARM_SMMU_SH_ISH) |
+	      FIELD_PREP(CR1_QUEUE_OC, CR1_CACHE_WB) |
+	      FIELD_PREP(CR1_QUEUE_IC, CR1_CACHE_WB);
+	writel_relaxed(val, smmu->base + ARM_SMMU_CR1);
+	writel_relaxed(CR2_PTM, smmu->base + ARM_SMMU_CR2);
+	writel_relaxed(0, smmu->base + ARM_SMMU_IRQ_CTRL);
+
+	val = readl_relaxed(smmu->base + ARM_SMMU_GERROR);
+	old = readl_relaxed(smmu->base + ARM_SMMU_GERRORN);
+	/* Service Failure Mode is fatal */
+	if ((val ^ old) & GERROR_SFM_ERR)
+		return -EIO;
+	/* Clear pending errors */
+	writel_relaxed(val, smmu->base + ARM_SMMU_GERRORN);
+
+	return 0;
+}
+
+static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu)
+{
+	int ret;
+
+	if (!PAGE_ALIGNED(smmu->mmio_addr | smmu->mmio_size))
+		return -EINVAL;
+
+	ret = ___pkvm_host_donate_hyp(smmu->mmio_addr >> PAGE_SHIFT,
+				      smmu->mmio_size >> PAGE_SHIFT,
+				      /* accept_mmio */ true);
+	if (ret)
+		return ret;
+
+	smmu->base = hyp_phys_to_virt(smmu->mmio_addr);
+
+	ret = smmu_init_registers(smmu);
+	if (ret)
+		return ret;
+
+	return kvm_iommu_init_device(&smmu->iommu);
+}
+
 static int smmu_init(void)
 {
-	return -ENOSYS;
+	int ret;
+	struct hyp_arm_smmu_v3_device *smmu;
+	size_t smmu_arr_size = PAGE_ALIGN(sizeof(*kvm_hyp_arm_smmu_v3_smmus) *
+					  kvm_hyp_arm_smmu_v3_count);
+	phys_addr_t smmu_arr_phys;
+
+	kvm_hyp_arm_smmu_v3_smmus = kern_hyp_va(kvm_hyp_arm_smmu_v3_smmus);
+
+	smmu_arr_phys = hyp_virt_to_phys(kvm_hyp_arm_smmu_v3_smmus);
+
+	ret = smmu_take_pages(smmu_arr_phys, smmu_arr_size);
+	if (ret)
+		return ret;
+
+	for_each_smmu(smmu) {
+		ret = smmu_init_device(smmu);
+		if (ret)
+			goto out_reclaim_smmu;
+	}
+
+	return 0;
+out_reclaim_smmu:
+	smmu_reclaim_pages(smmu_arr_phys, smmu_arr_size);
+	return ret;
 }
 
 /* Shared with the kernel driver in EL1 */
diff --git a/include/kvm/arm_smmu_v3.h b/include/kvm/arm_smmu_v3.h
index 521028b3ff71..fb24bcef1624 100644
--- a/include/kvm/arm_smmu_v3.h
+++ b/include/kvm/arm_smmu_v3.h
@@ -5,8 +5,19 @@
 #include <asm/kvm_asm.h>
 #include <kvm/iommu.h>
 
+/*
+ * Parameters from the trusted host:
+ * @mmio_addr		base address of the SMMU registers
+ * @mmio_size		size of the registers resource
+ *
+ * Other members are filled and used at runtime by the SMMU driver.
+ */
 struct hyp_arm_smmu_v3_device {
 	struct kvm_hyp_iommu	iommu;
+	phys_addr_t		mmio_addr;
+	size_t			mmio_size;
+
+	void __iomem		*base;
 };
 
 extern size_t kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count);
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:51 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:51 +0000
Subject: [RFC PATCH v2 27/58] KVM: arm64: smmu-v3: Setup command queue
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-28-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Map the command queue allocated by the host into the hypervisor address
space. When the host mappings are finalized, the queue is unmapped from
the host.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 165 ++++++++++++++++++++
 include/kvm/arm_smmu_v3.h                   |   4 +
 2 files changed, 169 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index f7e60c188cb0..e15356509424 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -41,6 +41,15 @@ struct hyp_arm_smmu_v3_device *kvm_hyp_arm_smmu_v3_smmus;
 	__ret;							\
 })
 
+#define smmu_wait_event(_smmu, _cond)				\
+({								\
+	if ((_smmu)->features & ARM_SMMU_FEAT_SEV) {		\
+		while (!(_cond))				\
+			wfe();					\
+	}							\
+	smmu_wait(_cond);					\
+})
+
 static int smmu_write_cr0(struct hyp_arm_smmu_v3_device *smmu, u32 val)
 {
 	writel_relaxed(val, smmu->base + ARM_SMMU_CR0);
@@ -60,6 +69,123 @@ static void smmu_reclaim_pages(u64 phys, size_t size)
 	WARN_ON(__pkvm_hyp_donate_host(phys >> PAGE_SHIFT, size >> PAGE_SHIFT));
 }
 
+#define Q_WRAP(smmu, reg)	((reg) & (1 << (smmu)->cmdq_log2size))
+#define Q_IDX(smmu, reg)	((reg) & ((1 << (smmu)->cmdq_log2size) - 1))
+
+static bool smmu_cmdq_full(struct hyp_arm_smmu_v3_device *smmu)
+{
+	u64 cons = readl_relaxed(smmu->base + ARM_SMMU_CMDQ_CONS);
+
+	return Q_IDX(smmu, smmu->cmdq_prod) == Q_IDX(smmu, cons) &&
+	       Q_WRAP(smmu, smmu->cmdq_prod) != Q_WRAP(smmu, cons);
+}
+
+static bool smmu_cmdq_empty(struct hyp_arm_smmu_v3_device *smmu)
+{
+	u64 cons = readl_relaxed(smmu->base + ARM_SMMU_CMDQ_CONS);
+
+	return Q_IDX(smmu, smmu->cmdq_prod) == Q_IDX(smmu, cons) &&
+	       Q_WRAP(smmu, smmu->cmdq_prod) == Q_WRAP(smmu, cons);
+}
+
+static int smmu_add_cmd(struct hyp_arm_smmu_v3_device *smmu,
+			struct arm_smmu_cmdq_ent *ent)
+{
+	int i;
+	int ret;
+	u64 cmd[CMDQ_ENT_DWORDS] = {};
+	int idx = Q_IDX(smmu, smmu->cmdq_prod);
+	u64 *slot = smmu->cmdq_base + idx * CMDQ_ENT_DWORDS;
+
+	if (smmu->iommu.power_is_off)
+		return -EPIPE;
+
+	ret = smmu_wait_event(smmu, !smmu_cmdq_full(smmu));
+	if (ret)
+		return ret;
+
+	cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
+
+	switch (ent->opcode) {
+	case CMDQ_OP_CFGI_ALL:
+		cmd[1] |= FIELD_PREP(CMDQ_CFGI_1_RANGE, 31);
+		break;
+	case CMDQ_OP_CFGI_CD:
+		cmd[0] |= FIELD_PREP(CMDQ_CFGI_0_SSID, ent->cfgi.ssid);
+		fallthrough;
+	case CMDQ_OP_CFGI_STE:
+		cmd[0] |= FIELD_PREP(CMDQ_CFGI_0_SID, ent->cfgi.sid);
+		cmd[1] |= FIELD_PREP(CMDQ_CFGI_1_LEAF, ent->cfgi.leaf);
+		break;
+	case CMDQ_OP_TLBI_NH_VA:
+		cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
+		cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_NUM, ent->tlbi.num);
+		cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_SCALE, ent->tlbi.scale);
+		cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_ASID, ent->tlbi.asid);
+		cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_LEAF, ent->tlbi.leaf);
+		cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_TTL, ent->tlbi.ttl);
+		cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_TG, ent->tlbi.tg);
+		cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_VA_MASK;
+		break;
+	case CMDQ_OP_TLBI_NSNH_ALL:
+		break;
+	case CMDQ_OP_TLBI_NH_ASID:
+		cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_ASID, ent->tlbi.asid);
+		fallthrough;
+	case CMDQ_OP_TLBI_S12_VMALL:
+		cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
+		break;
+	case CMDQ_OP_TLBI_S2_IPA:
+		cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_NUM, ent->tlbi.num);
+		cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_SCALE, ent->tlbi.scale);
+		cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
+		cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_LEAF, ent->tlbi.leaf);
+		cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_TTL, ent->tlbi.ttl);
+		cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_TG, ent->tlbi.tg);
+		cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_IPA_MASK;
+		break;
+	case CMDQ_OP_CMD_SYNC:
+		cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_CS, CMDQ_SYNC_0_CS_SEV);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	for (i = 0; i < CMDQ_ENT_DWORDS; i++)
+		slot[i] = cpu_to_le64(cmd[i]);
+
+	smmu->cmdq_prod++;
+	writel(Q_IDX(smmu, smmu->cmdq_prod) | Q_WRAP(smmu, smmu->cmdq_prod),
+	       smmu->base + ARM_SMMU_CMDQ_PROD);
+	return 0;
+}
+
+static int smmu_sync_cmd(struct hyp_arm_smmu_v3_device *smmu)
+{
+	int ret;
+	struct arm_smmu_cmdq_ent cmd = {
+		.opcode = CMDQ_OP_CMD_SYNC,
+	};
+
+	ret = smmu_add_cmd(smmu, &cmd);
+	if (ret)
+		return ret;
+
+	return smmu_wait_event(smmu, smmu_cmdq_empty(smmu));
+}
+
+__maybe_unused
+static int smmu_send_cmd(struct hyp_arm_smmu_v3_device *smmu,
+			 struct arm_smmu_cmdq_ent *cmd)
+{
+	int ret = smmu_add_cmd(smmu, cmd);
+
+	if (ret)
+		return ret;
+
+	return smmu_sync_cmd(smmu);
+}
+
 static int smmu_init_registers(struct hyp_arm_smmu_v3_device *smmu)
 {
 	u64 val, old;
@@ -94,6 +220,41 @@ static int smmu_init_registers(struct hyp_arm_smmu_v3_device *smmu)
 	return 0;
 }
 
+static int smmu_init_cmdq(struct hyp_arm_smmu_v3_device *smmu)
+{
+	u64 cmdq_base;
+	size_t cmdq_nr_entries, cmdq_size;
+	int ret;
+	enum kvm_pgtable_prot prot = PAGE_HYP;
+
+	cmdq_base = readq_relaxed(smmu->base + ARM_SMMU_CMDQ_BASE);
+	if (cmdq_base & ~(Q_BASE_RWA | Q_BASE_ADDR_MASK | Q_BASE_LOG2SIZE))
+		return -EINVAL;
+
+	smmu->cmdq_log2size = cmdq_base & Q_BASE_LOG2SIZE;
+	cmdq_nr_entries = 1 << smmu->cmdq_log2size;
+	cmdq_size = cmdq_nr_entries * CMDQ_ENT_DWORDS * 8;
+
+	cmdq_base &= Q_BASE_ADDR_MASK;
+
+	if (!(smmu->features & ARM_SMMU_FEAT_COHERENCY))
+		prot |= KVM_PGTABLE_PROT_NORMAL_NC;
+
+	ret = ___pkvm_host_donate_hyp_prot(cmdq_base >> PAGE_SHIFT,
+					   PAGE_ALIGN(cmdq_size) >> PAGE_SHIFT,
+					   false, prot);
+	if (ret)
+		return ret;
+
+	smmu->cmdq_base = hyp_phys_to_virt(cmdq_base);
+
+	memset(smmu->cmdq_base, 0, cmdq_size);
+	writel_relaxed(0, smmu->base + ARM_SMMU_CMDQ_PROD);
+	writel_relaxed(0, smmu->base + ARM_SMMU_CMDQ_CONS);
+
+	return 0;
+}
+
 static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu)
 {
 	int ret;
@@ -113,6 +274,10 @@ static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu)
 	if (ret)
 		return ret;
 
+	ret = smmu_init_cmdq(smmu);
+	if (ret)
+		return ret;
+
 	return kvm_iommu_init_device(&smmu->iommu);
 }
 
diff --git a/include/kvm/arm_smmu_v3.h b/include/kvm/arm_smmu_v3.h
index fb24bcef1624..393a1a04edba 100644
--- a/include/kvm/arm_smmu_v3.h
+++ b/include/kvm/arm_smmu_v3.h
@@ -16,8 +16,12 @@ struct hyp_arm_smmu_v3_device {
 	struct kvm_hyp_iommu	iommu;
 	phys_addr_t		mmio_addr;
 	size_t			mmio_size;
+	unsigned long		features;
 
 	void __iomem		*base;
+	u32			cmdq_prod;
+	u64			*cmdq_base;
+	size_t			cmdq_log2size;
 };
 
 extern size_t kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count);
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:52 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:52 +0000
Subject: [RFC PATCH v2 28/58] KVM: arm64: smmu-v3: Setup stream table
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-29-smostafa@google.com>

Map the stream table allocated by the host into the hypervisor address
space. When the host mappings are finalized, the table is unmapped from
the host. Depending on the host configuration, the stream table may have
one or two levels. Populate the level-2 stream table lazily.

Also, add accessors for STEs.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 157 +++++++++++++++++++-
 include/kvm/arm_smmu_v3.h                   |   3 +
 2 files changed, 159 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index e15356509424..43d2ce7828c1 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -174,7 +174,6 @@ static int smmu_sync_cmd(struct hyp_arm_smmu_v3_device *smmu)
 	return smmu_wait_event(smmu, smmu_cmdq_empty(smmu));
 }
 
-__maybe_unused
 static int smmu_send_cmd(struct hyp_arm_smmu_v3_device *smmu,
 			 struct arm_smmu_cmdq_ent *cmd)
 {
@@ -186,6 +185,94 @@ static int smmu_send_cmd(struct hyp_arm_smmu_v3_device *smmu,
 	return smmu_sync_cmd(smmu);
 }
 
+__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);
+}
+
+static int smmu_alloc_l2_strtab(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
+{
+	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
+	struct arm_smmu_strtab_l1 *l1_desc;
+	dma_addr_t l2ptr_dma;
+	struct arm_smmu_strtab_l2 *l2table;
+	size_t l2_order = get_order(sizeof(struct arm_smmu_strtab_l2));
+	int flags = 0;
+
+	l1_desc = &cfg->l2.l1tab[arm_smmu_strtab_l1_idx(sid)];
+	if (l1_desc->l2ptr)
+		return 0;
+
+	if (!(smmu->features & ARM_SMMU_FEAT_COHERENCY))
+		flags |= IOMMU_PAGE_NOCACHE;
+
+	l2table = kvm_iommu_donate_pages(l2_order, flags);
+	if (!l2table)
+		return -ENOMEM;
+
+	l2ptr_dma = hyp_virt_to_phys(l2table);
+
+	if (l2ptr_dma & (~STRTAB_L1_DESC_L2PTR_MASK | ~PAGE_MASK)) {
+		kvm_iommu_reclaim_pages(l2table, l2_order);
+		return -EINVAL;
+	}
+
+	/* Ensure the empty stream table is visible before the descriptor write */
+	wmb();
+
+	arm_smmu_write_strtab_l1_desc(l1_desc, l2ptr_dma);
+	return 0;
+}
+
+static struct arm_smmu_ste *
+smmu_get_ste_ptr(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
+{
+	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
+
+	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
+		struct arm_smmu_strtab_l1 *l1_desc =
+					&cfg->l2.l1tab[arm_smmu_strtab_l1_idx(sid)];
+		struct arm_smmu_strtab_l2 *l2ptr;
+
+		if (arm_smmu_strtab_l1_idx(sid) > cfg->l2.num_l1_ents)
+			return NULL;
+		/* L2 should be allocated before calling this. */
+		if (WARN_ON(!l1_desc->l2ptr))
+			return NULL;
+
+		l2ptr = hyp_phys_to_virt(l1_desc->l2ptr & STRTAB_L1_DESC_L2PTR_MASK);
+		/* Two-level walk */
+		return &l2ptr->stes[arm_smmu_strtab_l2_idx(sid)];
+	}
+
+	if (sid > cfg->linear.num_ents)
+		return NULL;
+	/* Simple linear lookup */
+	return &cfg->linear.table[sid];
+}
+
+__maybe_unused
+static struct arm_smmu_ste *
+smmu_get_alloc_ste_ptr(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
+{
+	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
+		int ret = smmu_alloc_l2_strtab(smmu, sid);
+
+		if (ret) {
+			WARN_ON(ret != -ENOMEM);
+			return NULL;
+		}
+	}
+	return smmu_get_ste_ptr(smmu, sid);
+}
+
 static int smmu_init_registers(struct hyp_arm_smmu_v3_device *smmu)
 {
 	u64 val, old;
@@ -255,6 +342,70 @@ static int smmu_init_cmdq(struct hyp_arm_smmu_v3_device *smmu)
 	return 0;
 }
 
+static int smmu_init_strtab(struct hyp_arm_smmu_v3_device *smmu)
+{
+	int ret;
+	u64 strtab_base;
+	size_t strtab_size;
+	u32 strtab_cfg, fmt;
+	int split, log2size;
+	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
+	enum kvm_pgtable_prot prot = PAGE_HYP;
+
+	if (!(smmu->features & ARM_SMMU_FEAT_COHERENCY))
+		prot |= KVM_PGTABLE_PROT_NORMAL_NC;
+
+	strtab_base = readq_relaxed(smmu->base + ARM_SMMU_STRTAB_BASE);
+	if (strtab_base & ~(STRTAB_BASE_ADDR_MASK | STRTAB_BASE_RA))
+		return -EINVAL;
+
+	strtab_cfg = readl_relaxed(smmu->base + ARM_SMMU_STRTAB_BASE_CFG);
+	if (strtab_cfg & ~(STRTAB_BASE_CFG_FMT | STRTAB_BASE_CFG_SPLIT |
+			   STRTAB_BASE_CFG_LOG2SIZE))
+		return -EINVAL;
+
+	fmt = FIELD_GET(STRTAB_BASE_CFG_FMT, strtab_cfg);
+	split = FIELD_GET(STRTAB_BASE_CFG_SPLIT, strtab_cfg);
+	log2size = FIELD_GET(STRTAB_BASE_CFG_LOG2SIZE, strtab_cfg);
+	strtab_base &= STRTAB_BASE_ADDR_MASK;
+
+	switch (fmt) {
+	case STRTAB_BASE_CFG_FMT_LINEAR:
+		if (split)
+			return -EINVAL;
+		cfg->linear.num_ents = 1 << log2size;
+		strtab_size = cfg->linear.num_ents * sizeof(struct arm_smmu_ste);
+		cfg->linear.ste_dma = strtab_base;
+		ret = ___pkvm_host_donate_hyp_prot(strtab_base >> PAGE_SHIFT,
+						   PAGE_ALIGN(strtab_size) >> PAGE_SHIFT,
+						   false, prot);
+		if (ret)
+			return -EINVAL;
+		cfg->linear.table = hyp_phys_to_virt(strtab_base);
+		/* Disable all STEs */
+		memset(cfg->linear.table, 0, strtab_size);
+		break;
+	case STRTAB_BASE_CFG_FMT_2LVL:
+		if (split != STRTAB_SPLIT)
+			return -EINVAL;
+		cfg->l2.num_l1_ents = 1 << max(0, log2size - split);
+		strtab_size = cfg->l2.num_l1_ents * sizeof(struct arm_smmu_strtab_l1);
+		cfg->l2.l1_dma = strtab_base;
+		ret = ___pkvm_host_donate_hyp_prot(strtab_base >> PAGE_SHIFT,
+						   PAGE_ALIGN(strtab_size) >> PAGE_SHIFT,
+						   false, prot);
+		if (ret)
+			return -EINVAL;
+		cfg->l2.l1tab = hyp_phys_to_virt(strtab_base);
+		/* Disable all STEs */
+		memset(cfg->l2.l1tab, 0, strtab_size);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu)
 {
 	int ret;
@@ -278,6 +429,10 @@ static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu)
 	if (ret)
 		return ret;
 
+	ret = smmu_init_strtab(smmu);
+	if (ret)
+		return ret;
+
 	return kvm_iommu_init_device(&smmu->iommu);
 }
 
diff --git a/include/kvm/arm_smmu_v3.h b/include/kvm/arm_smmu_v3.h
index 393a1a04edba..352c1b2dc72a 100644
--- a/include/kvm/arm_smmu_v3.h
+++ b/include/kvm/arm_smmu_v3.h
@@ -2,6 +2,7 @@
 #ifndef __KVM_ARM_SMMU_V3_H
 #define __KVM_ARM_SMMU_V3_H
 
+#include <asm/arm-smmu-v3-common.h>
 #include <asm/kvm_asm.h>
 #include <kvm/iommu.h>
 
@@ -22,6 +23,8 @@ struct hyp_arm_smmu_v3_device {
 	u32			cmdq_prod;
 	u64			*cmdq_base;
 	size_t			cmdq_log2size;
+	/* strtab_cfg.l2.l2ptrs is not used, instead computed from L1 */
+	struct arm_smmu_strtab_cfg strtab_cfg;
 };
 
 extern size_t kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count);
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:53 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:53 +0000
Subject: [RFC PATCH v2 29/58] KVM: arm64: smmu-v3: Setup event queue
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-30-smostafa@google.com>

The host can use the event queue for debuging, and unlike the command
queue, it would be managed by the kernel.
However, it must set in a shared state so it can't be donated to the
hypervisor later.

This relies on the ARM_SMMU_EVTQ_BASE can't be changed after
de-privilege.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 39 +++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index 43d2ce7828c1..5020f74421ad 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -342,6 +342,41 @@ static int smmu_init_cmdq(struct hyp_arm_smmu_v3_device *smmu)
 	return 0;
 }
 
+/*
+ * Event q support is optional and managed by the kernel,
+ * However, it must set in a shared state so it can't be donated
+ * to the hypervisor later.
+ * This relies on the ARM_SMMU_EVTQ_BASE can't be changed after
+ * de-privilege.
+ */
+static int smmu_init_evtq(struct hyp_arm_smmu_v3_device *smmu)
+{
+	u64 evtq_base, evtq_pfn;
+	size_t evtq_nr_entries, evtq_size, evtq_nr_pages;
+	size_t i;
+	int ret;
+
+	evtq_base = readq_relaxed(smmu->base + ARM_SMMU_EVTQ_BASE);
+	if (!evtq_base)
+		return 0;
+
+	if (evtq_base & ~(Q_BASE_RWA | Q_BASE_ADDR_MASK | Q_BASE_LOG2SIZE))
+		return -EINVAL;
+
+	evtq_nr_entries = 1 << (evtq_base & Q_BASE_LOG2SIZE);
+	evtq_size = evtq_nr_entries * EVTQ_ENT_DWORDS * 8;
+	evtq_nr_pages = PAGE_ALIGN(evtq_size) >> PAGE_SHIFT;
+
+	evtq_pfn = PAGE_ALIGN(evtq_base & Q_BASE_ADDR_MASK) >> PAGE_SHIFT;
+
+	for (i = 0 ; i < evtq_nr_pages ; ++i) {
+		ret = __pkvm_host_share_hyp(evtq_pfn + i);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
 static int smmu_init_strtab(struct hyp_arm_smmu_v3_device *smmu)
 {
 	int ret;
@@ -429,6 +464,10 @@ static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu)
 	if (ret)
 		return ret;
 
+	ret = smmu_init_evtq(smmu);
+	if (ret)
+		return ret;
+
 	ret = smmu_init_strtab(smmu);
 	if (ret)
 		return ret;
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:54 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:54 +0000
Subject: [RFC PATCH v2 30/58] KVM: arm64: smmu-v3: Reset the device
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-31-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Now that all structures are initialized, send global invalidations and
reset the SMMUv3 device.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 38 +++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index 5020f74421ad..58662c2c4c97 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -441,6 +441,40 @@ static int smmu_init_strtab(struct hyp_arm_smmu_v3_device *smmu)
 	return 0;
 }
 
+static int smmu_reset_device(struct hyp_arm_smmu_v3_device *smmu)
+{
+	int ret;
+	struct arm_smmu_cmdq_ent cfgi_cmd = {
+		.opcode = CMDQ_OP_CFGI_ALL,
+	};
+	struct arm_smmu_cmdq_ent tlbi_cmd = {
+		.opcode = CMDQ_OP_TLBI_NSNH_ALL,
+	};
+
+	/* Invalidate all cached configs and TLBs */
+	ret = smmu_write_cr0(smmu, CR0_CMDQEN);
+	if (ret)
+		return ret;
+
+	ret = smmu_add_cmd(smmu, &cfgi_cmd);
+	if (ret)
+		goto err_disable_cmdq;
+
+	ret = smmu_add_cmd(smmu, &tlbi_cmd);
+	if (ret)
+		goto err_disable_cmdq;
+
+	ret = smmu_sync_cmd(smmu);
+	if (ret)
+		goto err_disable_cmdq;
+
+	/* Enable translation */
+	return smmu_write_cr0(smmu, CR0_SMMUEN | CR0_CMDQEN | CR0_ATSCHK);
+
+err_disable_cmdq:
+	return smmu_write_cr0(smmu, 0);
+}
+
 static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu)
 {
 	int ret;
@@ -472,6 +506,10 @@ static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu)
 	if (ret)
 		return ret;
 
+	ret = smmu_reset_device(smmu);
+	if (ret)
+		return ret;
+
 	return kvm_iommu_init_device(&smmu->iommu);
 }
 
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:55 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:55 +0000
Subject: [RFC PATCH v2 31/58] KVM: arm64: smmu-v3: Support io-pgtable
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-32-smostafa@google.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

Implement the hypervisor version of io-pgtable allocation functions,
mirroring drivers/iommu/io-pgtable-arm.c. Page allocation uses the
IOMMU pool filled by the host.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/Makefile              |   2 +
 .../arm64/kvm/hyp/nvhe/iommu/io-pgtable-arm.c | 153 ++++++++++++++++++
 include/linux/io-pgtable-arm.h                |  11 ++
 3 files changed, 166 insertions(+)
 create mode 100644 arch/arm64/kvm/hyp/nvhe/iommu/io-pgtable-arm.c

diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index edfd8a11ac90..e4f662b1447f 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -17,6 +17,8 @@ hyp-obj-$(CONFIG_MODULES) += modules.o
 hyp-obj-y += $(lib-objs)
 
 hyp-obj-$(CONFIG_ARM_SMMU_V3_PKVM) += iommu/arm-smmu-v3.o
+hyp-obj-$(CONFIG_ARM_SMMU_V3_PKVM) += iommu/io-pgtable-arm.o \
+	../../../../../drivers/iommu/io-pgtable-arm-common.o
 
 $(obj)/hyp.lds: $(src)/hyp.lds.S FORCE
 	$(call if_changed_dep,cpp_lds_S)
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/io-pgtable-arm.c b/arch/arm64/kvm/hyp/nvhe/iommu/io-pgtable-arm.c
new file mode 100644
index 000000000000..aa5bf7c0ed03
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/io-pgtable-arm.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Arm Ltd.
+ */
+#include <asm/kvm_hyp.h>
+#include <asm/kvm_mmu.h>
+#include <kvm/arm_smmu_v3.h>
+#include <linux/types.h>
+#include <linux/gfp_types.h>
+#include <linux/io-pgtable-arm.h>
+
+#include <nvhe/alloc.h>
+#include <nvhe/iommu.h>
+#include <nvhe/mem_protect.h>
+
+int arm_lpae_map_exists(void)
+{
+	return -EEXIST;
+}
+
+int arm_lpae_unmap_empty(void)
+{
+	return -EEXIST;
+}
+
+void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
+			     struct io_pgtable_cfg *cfg, void *cookie)
+{
+	void *addr;
+
+	if (!PAGE_ALIGNED(size))
+		return NULL;
+
+	addr = kvm_iommu_donate_pages(get_order(size), 0);
+
+	if (addr && !cfg->coherent_walk)
+		kvm_flush_dcache_to_poc(addr, size);
+
+	return addr;
+}
+
+void __arm_lpae_free_pages(void *addr, size_t size, struct io_pgtable_cfg *cfg,
+			   void *cookie)
+{
+	u8 order;
+
+	/*
+	 * It's guaranteed all allocations are aligned, but core code
+	 * might free PGD with it's actual size.
+	 */
+	order = get_order(PAGE_ALIGN(size));
+
+	if (!cfg->coherent_walk)
+		kvm_flush_dcache_to_poc(addr, size);
+
+	kvm_iommu_reclaim_pages(addr, order);
+}
+
+void __arm_lpae_sync_pte(arm_lpae_iopte *ptep, int num_entries,
+			 struct io_pgtable_cfg *cfg)
+{
+	if (!cfg->coherent_walk)
+		kvm_flush_dcache_to_poc(ptep, sizeof(*ptep) * num_entries);
+}
+
+static int kvm_arm_io_pgtable_init(struct io_pgtable_cfg *cfg,
+				   struct arm_lpae_io_pgtable *data)
+{
+	int ret = -EINVAL;
+
+	if (cfg->fmt == ARM_64_LPAE_S2)
+		ret = arm_lpae_init_pgtable_s2(cfg, data);
+	else if (cfg->fmt == ARM_64_LPAE_S1)
+		ret = arm_lpae_init_pgtable_s1(cfg, data);
+
+	if (ret)
+		return ret;
+
+	data->iop.cfg = *cfg;
+	data->iop.fmt	= cfg->fmt;
+
+	return 0;
+}
+
+struct io_pgtable *kvm_arm_io_pgtable_alloc(struct io_pgtable_cfg *cfg,
+					    void *cookie,
+					    int *out_ret)
+{
+	size_t pgd_size, alignment;
+	struct arm_lpae_io_pgtable *data;
+	int ret;
+
+	data = hyp_alloc(sizeof(*data));
+	if (!data) {
+		*out_ret = hyp_alloc_errno();
+		return NULL;
+	}
+
+	ret = kvm_arm_io_pgtable_init(cfg, data);
+	if (ret)
+		goto out_free;
+
+	pgd_size = PAGE_ALIGN(ARM_LPAE_PGD_SIZE(data));
+	data->pgd = __arm_lpae_alloc_pages(pgd_size, 0, &data->iop.cfg, cookie);
+	if (!data->pgd) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+	/*
+	 * If it has eight or more entries, the table must be aligned on
+	 * its size. Otherwise 64 bytes.
+	 */
+	alignment = max(pgd_size, 8 * sizeof(arm_lpae_iopte));
+	if (!IS_ALIGNED(hyp_virt_to_phys(data->pgd), alignment)) {
+		__arm_lpae_free_pages(data->pgd, pgd_size,
+				      &data->iop.cfg, cookie);
+		ret = -EINVAL;
+		goto out_free;
+	}
+
+	data->iop.cookie = cookie;
+	if (cfg->fmt == ARM_64_LPAE_S2)
+		data->iop.cfg.arm_lpae_s2_cfg.vttbr = __arm_lpae_virt_to_phys(data->pgd);
+	else if (cfg->fmt == ARM_64_LPAE_S1)
+		data->iop.cfg.arm_lpae_s1_cfg.ttbr = __arm_lpae_virt_to_phys(data->pgd);
+
+	if (!data->iop.cfg.coherent_walk)
+		kvm_flush_dcache_to_poc(data->pgd, pgd_size);
+
+	/* Ensure the empty pgd is visible before any actual TTBR write */
+	wmb();
+
+	*out_ret = 0;
+	return &data->iop;
+out_free:
+	hyp_free(data);
+	*out_ret = ret;
+	return NULL;
+}
+
+int kvm_arm_io_pgtable_free(struct io_pgtable *iopt)
+{
+	struct arm_lpae_io_pgtable *data = io_pgtable_to_data(iopt);
+	size_t pgd_size = ARM_LPAE_PGD_SIZE(data);
+
+	if (!data->iop.cfg.coherent_walk)
+		kvm_flush_dcache_to_poc(data->pgd, pgd_size);
+
+	io_pgtable_tlb_flush_all(iopt);
+	__arm_lpae_free_pgtable(data, data->start_level, data->pgd);
+	hyp_free(data);
+	return 0;
+}
diff --git a/include/linux/io-pgtable-arm.h b/include/linux/io-pgtable-arm.h
index 337e9254fdbd..88922314157d 100644
--- a/include/linux/io-pgtable-arm.h
+++ b/include/linux/io-pgtable-arm.h
@@ -191,8 +191,19 @@ static inline bool iopte_table(arm_lpae_iopte pte, int lvl)
 	return iopte_type(pte) == ARM_LPAE_PTE_TYPE_TABLE;
 }
 
+#ifdef __KVM_NVHE_HYPERVISOR__
+#include <nvhe/memory.h>
+#define __arm_lpae_virt_to_phys	hyp_virt_to_phys
+#define __arm_lpae_phys_to_virt	hyp_phys_to_virt
+
+struct io_pgtable *kvm_arm_io_pgtable_alloc(struct io_pgtable_cfg *cfg,
+					    void *cookie,
+					    int *out_ret);
+int kvm_arm_io_pgtable_free(struct io_pgtable *iop);
+#else
 #define __arm_lpae_virt_to_phys	__pa
 #define __arm_lpae_phys_to_virt	__va
+#endif
 
 /* Generic functions */
 void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:56 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:56 +0000
Subject: [RFC PATCH v2 32/58] KVM: arm64: smmu-v3: Add {alloc/free}_domain
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-33-smostafa@google.com>

Add SMMUv3 alloc/free domain, as this operations are not
tied to the IOMMU, we can't do much with the io-pgtable
allocation or configuration.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 64 +++++++++++++++++++++
 include/kvm/arm_smmu_v3.h                   |  6 ++
 2 files changed, 70 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index 58662c2c4c97..3181933e9a34 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -7,6 +7,8 @@
 #include <asm/arm-smmu-v3-common.h>
 #include <asm/kvm_hyp.h>
 #include <kvm/arm_smmu_v3.h>
+#include <linux/io-pgtable-arm.h>
+#include <nvhe/alloc.h>
 #include <nvhe/iommu.h>
 #include <nvhe/mem_protect.h>
 #include <nvhe/mm.h>
@@ -50,6 +52,22 @@ struct hyp_arm_smmu_v3_device *kvm_hyp_arm_smmu_v3_smmus;
 	smmu_wait(_cond);					\
 })
 
+/*
+ * SMMUv3 domain:
+ * @domain: Pointer to the IOMMU domain.
+ * @smmu: SMMU instance for this domain.
+ * @type: Type of domain (S1, S2)
+ * @pgt_lock: Lock for page table
+ * @pgtable: io_pgtable instance for this domain
+ */
+struct hyp_arm_smmu_v3_domain {
+	struct kvm_hyp_iommu_domain     *domain;
+	struct hyp_arm_smmu_v3_device	*smmu;
+	u32				type;
+	hyp_spinlock_t			pgt_lock;
+	struct io_pgtable		*pgtable;
+};
+
 static int smmu_write_cr0(struct hyp_arm_smmu_v3_device *smmu, u32 val)
 {
 	writel_relaxed(val, smmu->base + ARM_SMMU_CR0);
@@ -541,7 +559,53 @@ static int smmu_init(void)
 	return ret;
 }
 
+static struct kvm_hyp_iommu *smmu_id_to_iommu(pkvm_handle_t smmu_id)
+{
+	if (smmu_id >= kvm_hyp_arm_smmu_v3_count)
+		return NULL;
+	smmu_id = array_index_nospec(smmu_id, kvm_hyp_arm_smmu_v3_count);
+
+	return &kvm_hyp_arm_smmu_v3_smmus[smmu_id].iommu;
+}
+
+static int smmu_alloc_domain(struct kvm_hyp_iommu_domain *domain, int type)
+{
+	struct hyp_arm_smmu_v3_domain *smmu_domain;
+
+	if (type >= KVM_ARM_SMMU_DOMAIN_MAX)
+		return -EINVAL;
+
+	smmu_domain = hyp_alloc(sizeof(*smmu_domain));
+	if (!smmu_domain)
+		return -ENOMEM;
+
+	/*
+	 * Can't do much without knowing the SMMUv3.
+	 * Page table will be allocated at attach_dev, but can be
+	 * freed from free domain.
+	 */
+	smmu_domain->domain = domain;
+	smmu_domain->type = type;
+	hyp_spin_lock_init(&smmu_domain->pgt_lock);
+	domain->priv = (void *)smmu_domain;
+
+	return 0;
+}
+
+static void smmu_free_domain(struct kvm_hyp_iommu_domain *domain)
+{
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+
+	if (smmu_domain->pgtable)
+		kvm_arm_io_pgtable_free(smmu_domain->pgtable);
+
+	hyp_free(smmu_domain);
+}
+
 /* Shared with the kernel driver in EL1 */
 struct kvm_iommu_ops smmu_ops = {
 	.init				= smmu_init,
+	.get_iommu_by_id		= smmu_id_to_iommu,
+	.alloc_domain			= smmu_alloc_domain,
+	.free_domain			= smmu_free_domain,
 };
diff --git a/include/kvm/arm_smmu_v3.h b/include/kvm/arm_smmu_v3.h
index 352c1b2dc72a..ded98cbaebc1 100644
--- a/include/kvm/arm_smmu_v3.h
+++ b/include/kvm/arm_smmu_v3.h
@@ -33,4 +33,10 @@ extern size_t kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count);
 extern struct hyp_arm_smmu_v3_device *kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_smmus);
 #define kvm_hyp_arm_smmu_v3_smmus kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_smmus)
 
+enum kvm_arm_smmu_domain_type {
+	KVM_ARM_SMMU_DOMAIN_S1,
+	KVM_ARM_SMMU_DOMAIN_S2,
+	KVM_ARM_SMMU_DOMAIN_MAX,
+};
+
 #endif /* __KVM_ARM_SMMU_V3_H */
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:58 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:58 +0000
Subject: [RFC PATCH v2 34/58] KVM: arm64: smmu-v3: Add context descriptor functions
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-35-smostafa@google.com>

Add functions to allocate and access context descriptors that would
be used in stage-1 attach.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 53 +++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index 5f00d5cdf5bc..d58424e45e1d 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -215,6 +215,19 @@ static int smmu_sync_ste(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
 	return smmu_send_cmd(smmu, &cmd);
 }
 
+__maybe_unused
+static int smmu_sync_cd(struct hyp_arm_smmu_v3_device *smmu, u32 sid, u32 ssid)
+{
+	struct arm_smmu_cmdq_ent cmd = {
+		.opcode = CMDQ_OP_CFGI_CD,
+		.cfgi.sid	= sid,
+		.cfgi.ssid	= ssid,
+		.cfgi.leaf = true,
+	};
+
+	return smmu_send_cmd(smmu, &cmd);
+}
+
 static int smmu_alloc_l2_strtab(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
 {
 	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
@@ -291,6 +304,46 @@ smmu_get_alloc_ste_ptr(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
 	return smmu_get_ste_ptr(smmu, sid);
 }
 
+__maybe_unused
+static u64 *smmu_get_cd_ptr(u64 *cdtab, u32 ssid)
+{
+	/* Only linear supported for now. */
+	return cdtab + ssid * CTXDESC_CD_DWORDS;
+}
+
+__maybe_unused
+static u64 *smmu_alloc_cd(struct hyp_arm_smmu_v3_device *smmu, u32 pasid_bits)
+{
+	u64 *cd_table;
+	int flags = 0;
+	u32 requested_order = get_order((1 << pasid_bits) *
+					(CTXDESC_CD_DWORDS << 3));
+
+	/*
+	 * We support max of 64K linear tables only, this should be enough
+	 * for 128 pasids
+	 */
+	if (WARN_ON(requested_order > 4))
+		return NULL;
+
+	if (!(smmu->features & ARM_SMMU_FEAT_COHERENCY))
+		flags |= IOMMU_PAGE_NOCACHE;
+
+	cd_table = kvm_iommu_donate_pages(requested_order, flags);
+	if (!cd_table)
+		return NULL;
+	return (u64 *)hyp_virt_to_phys(cd_table);
+}
+
+__maybe_unused
+static void smmu_free_cd(u64 *cd_table, u32 pasid_bits)
+{
+	u32 order = get_order((1 << pasid_bits) *
+			      (CTXDESC_CD_DWORDS << 3));
+
+	kvm_iommu_reclaim_pages(cd_table, order);
+}
+
 static int smmu_init_registers(struct hyp_arm_smmu_v3_device *smmu)
 {
 	u64 val, old;
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:57 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:57 +0000
Subject: [RFC PATCH v2 33/58] KVM: arm64: smmu-v3: Add TLB ops
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-34-smostafa@google.com>

Add TLB invalidation functions would be used next from the page table
code and attach/detach functions.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 167 ++++++++++++++++++++
 1 file changed, 167 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index 3181933e9a34..5f00d5cdf5bc 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -602,10 +602,177 @@ static void smmu_free_domain(struct kvm_hyp_iommu_domain *domain)
 	hyp_free(smmu_domain);
 }
 
+static void smmu_inv_domain(struct hyp_arm_smmu_v3_domain *smmu_domain)
+{
+	struct kvm_hyp_iommu_domain *domain = smmu_domain->domain;
+	struct hyp_arm_smmu_v3_device *smmu = smmu_domain->smmu;
+	struct arm_smmu_cmdq_ent cmd = {};
+
+	if (smmu_domain->pgtable->cfg.fmt == ARM_64_LPAE_S2) {
+		cmd.opcode = CMDQ_OP_TLBI_S12_VMALL;
+		cmd.tlbi.vmid = domain->domain_id;
+	} else {
+		cmd.opcode = CMDQ_OP_TLBI_NH_ASID;
+		cmd.tlbi.asid = domain->domain_id;
+	}
+
+	if (smmu->iommu.power_is_off)
+		return;
+
+	WARN_ON(smmu_send_cmd(smmu, &cmd));
+}
+
+static void smmu_tlb_flush_all(void *cookie)
+{
+	struct kvm_hyp_iommu_domain *domain = cookie;
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+	struct hyp_arm_smmu_v3_device *smmu = smmu_domain->smmu;
+
+	kvm_iommu_lock(&smmu->iommu);
+	smmu_inv_domain(smmu_domain);
+	kvm_iommu_unlock(&smmu->iommu);
+}
+
+static int smmu_tlb_inv_range_smmu(struct hyp_arm_smmu_v3_device *smmu,
+				   struct kvm_hyp_iommu_domain *domain,
+				   struct arm_smmu_cmdq_ent *cmd,
+				   unsigned long iova, size_t size, size_t granule)
+{
+	int ret = 0;
+	unsigned long end = iova + size, num_pages = 0, tg = 0;
+	size_t inv_range = granule;
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+
+	kvm_iommu_lock(&smmu->iommu);
+	if (smmu->iommu.power_is_off)
+		goto out_ret;
+
+	/* Almost copy-paste from the kernel dirver. */
+	if (smmu->features & ARM_SMMU_FEAT_RANGE_INV) {
+		/* Get the leaf page size */
+		tg = __ffs(smmu_domain->pgtable->cfg.pgsize_bitmap);
+
+		num_pages = size >> tg;
+
+		/* Convert page size of 12,14,16 (log2) to 1,2,3 */
+		cmd->tlbi.tg = (tg - 10) / 2;
+
+		/*
+		 * Determine what level the granule is at. For non-leaf, both
+		 * io-pgtable and SVA pass a nominal last-level granule because
+		 * they don't know what level(s) actually apply, so ignore that
+		 * and leave TTL=0. However for various errata reasons we still
+		 * want to use a range command, so avoid the SVA corner case
+		 * where both scale and num could be 0 as well.
+		 */
+		if (cmd->tlbi.leaf)
+			cmd->tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3));
+		else if ((num_pages & CMDQ_TLBI_RANGE_NUM_MAX) == 1)
+			num_pages++;
+	}
+
+	while (iova < end) {
+		if (smmu->features & ARM_SMMU_FEAT_RANGE_INV) {
+			/*
+			 * On each iteration of the loop, the range is 5 bits
+			 * worth of the aligned size remaining.
+			 * The range in pages is:
+			 *
+			 * range = (num_pages & (0x1f << __ffs(num_pages)))
+			 */
+			unsigned long scale, num;
+
+			/* Determine the power of 2 multiple number of pages */
+			scale = __ffs(num_pages);
+			cmd->tlbi.scale = scale;
+
+			/* Determine how many chunks of 2^scale size we have */
+			num = (num_pages >> scale) & CMDQ_TLBI_RANGE_NUM_MAX;
+			cmd->tlbi.num = num - 1;
+
+			/* range is num * 2^scale * pgsize */
+			inv_range = num << (scale + tg);
+
+			/* Clear out the lower order bits for the next iteration */
+			num_pages -= num << scale;
+		}
+		cmd->tlbi.addr = iova;
+		WARN_ON(smmu_add_cmd(smmu, cmd));
+		BUG_ON(iova + inv_range < iova);
+		iova += inv_range;
+	}
+
+	ret = smmu_sync_cmd(smmu);
+out_ret:
+	kvm_iommu_unlock(&smmu->iommu);
+	return ret;
+}
+
+static void smmu_tlb_inv_range(struct kvm_hyp_iommu_domain *domain,
+			       unsigned long iova, size_t size, size_t granule,
+			       bool leaf)
+{
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+	unsigned long end = iova + size;
+	struct arm_smmu_cmdq_ent cmd;
+
+	cmd.tlbi.leaf = leaf;
+	if (smmu_domain->pgtable->cfg.fmt == ARM_64_LPAE_S2) {
+		cmd.opcode = CMDQ_OP_TLBI_S2_IPA;
+		cmd.tlbi.vmid = domain->domain_id;
+	} else {
+		cmd.opcode = CMDQ_OP_TLBI_NH_VA;
+		cmd.tlbi.asid = domain->domain_id;
+		cmd.tlbi.vmid = 0;
+	}
+	/*
+	 * There are no mappings at high addresses since we don't use TTB1, so
+	 * no overflow possible.
+	 */
+	BUG_ON(end < iova);
+	WARN_ON(smmu_tlb_inv_range_smmu(smmu_domain->smmu, domain,
+					&cmd, iova, size, granule));
+}
+
+static void smmu_tlb_flush_walk(unsigned long iova, size_t size,
+				size_t granule, void *cookie)
+{
+	smmu_tlb_inv_range(cookie, iova, size, granule, false);
+}
+
+static void smmu_tlb_add_page(struct iommu_iotlb_gather *gather,
+			      unsigned long iova, size_t granule,
+			      void *cookie)
+{
+	if (gather)
+		kvm_iommu_iotlb_gather_add_page(cookie, gather, iova, granule);
+	else
+		smmu_tlb_inv_range(cookie, iova, granule, granule, true);
+}
+
+__maybe_unused
+static const struct iommu_flush_ops smmu_tlb_ops = {
+	.tlb_flush_all	= smmu_tlb_flush_all,
+	.tlb_flush_walk = smmu_tlb_flush_walk,
+	.tlb_add_page	= smmu_tlb_add_page,
+};
+
+static void smmu_iotlb_sync(struct kvm_hyp_iommu_domain *domain,
+			    struct iommu_iotlb_gather *gather)
+{
+	size_t size;
+
+	if (!gather->pgsize)
+		return;
+	size = gather->end - gather->start + 1;
+	smmu_tlb_inv_range(domain, gather->start, size,  gather->pgsize, true);
+}
+
 /* Shared with the kernel driver in EL1 */
 struct kvm_iommu_ops smmu_ops = {
 	.init				= smmu_init,
 	.get_iommu_by_id		= smmu_id_to_iommu,
 	.alloc_domain			= smmu_alloc_domain,
 	.free_domain			= smmu_free_domain,
+	.iotlb_sync			= smmu_iotlb_sync,
 };
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:03:59 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:03:59 +0000
Subject: [RFC PATCH v2 35/58] KVM: arm64: smmu-v3: Add attach_dev
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-36-smostafa@google.com>

Add attach_dev HVC code which handles both stage-1 and stage-2.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 244 +++++++++++++++++++-
 include/kvm/arm_smmu_v3.h                   |   4 +
 2 files changed, 242 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index d58424e45e1d..a96eb6625c48 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -68,6 +68,11 @@ struct hyp_arm_smmu_v3_domain {
 	struct io_pgtable		*pgtable;
 };
 
+static struct hyp_arm_smmu_v3_device *to_smmu(struct kvm_hyp_iommu *iommu)
+{
+	return container_of(iommu, struct hyp_arm_smmu_v3_device, iommu);
+}
+
 static int smmu_write_cr0(struct hyp_arm_smmu_v3_device *smmu, u32 val)
 {
 	writel_relaxed(val, smmu->base + ARM_SMMU_CR0);
@@ -203,7 +208,6 @@ static int smmu_send_cmd(struct hyp_arm_smmu_v3_device *smmu,
 	return smmu_sync_cmd(smmu);
 }
 
-__maybe_unused
 static int smmu_sync_ste(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
 {
 	struct arm_smmu_cmdq_ent cmd = {
@@ -215,7 +219,6 @@ static int smmu_sync_ste(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
 	return smmu_send_cmd(smmu, &cmd);
 }
 
-__maybe_unused
 static int smmu_sync_cd(struct hyp_arm_smmu_v3_device *smmu, u32 sid, u32 ssid)
 {
 	struct arm_smmu_cmdq_ent cmd = {
@@ -289,7 +292,6 @@ smmu_get_ste_ptr(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
 	return &cfg->linear.table[sid];
 }
 
-__maybe_unused
 static struct arm_smmu_ste *
 smmu_get_alloc_ste_ptr(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
 {
@@ -304,14 +306,12 @@ smmu_get_alloc_ste_ptr(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
 	return smmu_get_ste_ptr(smmu, sid);
 }
 
-__maybe_unused
 static u64 *smmu_get_cd_ptr(u64 *cdtab, u32 ssid)
 {
 	/* Only linear supported for now. */
 	return cdtab + ssid * CTXDESC_CD_DWORDS;
 }
 
-__maybe_unused
 static u64 *smmu_alloc_cd(struct hyp_arm_smmu_v3_device *smmu, u32 pasid_bits)
 {
 	u64 *cd_table;
@@ -803,7 +803,6 @@ static void smmu_tlb_add_page(struct iommu_iotlb_gather *gather,
 		smmu_tlb_inv_range(cookie, iova, granule, granule, true);
 }
 
-__maybe_unused
 static const struct iommu_flush_ops smmu_tlb_ops = {
 	.tlb_flush_all	= smmu_tlb_flush_all,
 	.tlb_flush_walk = smmu_tlb_flush_walk,
@@ -821,6 +820,238 @@ static void smmu_iotlb_sync(struct kvm_hyp_iommu_domain *domain,
 	smmu_tlb_inv_range(domain, gather->start, size,  gather->pgsize, true);
 }
 
+static int smmu_domain_config_s2(struct kvm_hyp_iommu_domain *domain,
+				 struct arm_smmu_ste *ste)
+{
+	struct io_pgtable_cfg *cfg;
+	u64 ts, sl, ic, oc, sh, tg, ps;
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+
+	cfg = &smmu_domain->pgtable->cfg;
+	ps = cfg->arm_lpae_s2_cfg.vtcr.ps;
+	tg = cfg->arm_lpae_s2_cfg.vtcr.tg;
+	sh = cfg->arm_lpae_s2_cfg.vtcr.sh;
+	oc = cfg->arm_lpae_s2_cfg.vtcr.orgn;
+	ic = cfg->arm_lpae_s2_cfg.vtcr.irgn;
+	sl = cfg->arm_lpae_s2_cfg.vtcr.sl;
+	ts = cfg->arm_lpae_s2_cfg.vtcr.tsz;
+
+	ste->data[0] = STRTAB_STE_0_V |
+		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS);
+	ste->data[1] = FIELD_PREP(STRTAB_STE_1_SHCFG, STRTAB_STE_1_SHCFG_INCOMING);
+	ste->data[2] = FIELD_PREP(STRTAB_STE_2_VTCR,
+			FIELD_PREP(STRTAB_STE_2_VTCR_S2PS, ps) |
+			FIELD_PREP(STRTAB_STE_2_VTCR_S2TG, tg) |
+			FIELD_PREP(STRTAB_STE_2_VTCR_S2SH0, sh) |
+			FIELD_PREP(STRTAB_STE_2_VTCR_S2OR0, oc) |
+			FIELD_PREP(STRTAB_STE_2_VTCR_S2IR0, ic) |
+			FIELD_PREP(STRTAB_STE_2_VTCR_S2SL0, sl) |
+			FIELD_PREP(STRTAB_STE_2_VTCR_S2T0SZ, ts)) |
+		 FIELD_PREP(STRTAB_STE_2_S2VMID, domain->domain_id) |
+		 STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2R;
+	ste->data[3] = cfg->arm_lpae_s2_cfg.vttbr & STRTAB_STE_3_S2TTB_MASK;
+
+	return 0;
+}
+
+static u64 *smmu_domain_config_s1_ste(struct hyp_arm_smmu_v3_device *smmu,
+				      u32 pasid_bits, struct arm_smmu_ste *ste)
+{
+	u64 *cd_table;
+
+	cd_table = smmu_alloc_cd(smmu, pasid_bits);
+	if (!cd_table)
+		return NULL;
+
+	ste->data[1] = 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);
+	ste->data[0] = ((u64)cd_table & STRTAB_STE_0_S1CTXPTR_MASK) |
+		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS) |
+		FIELD_PREP(STRTAB_STE_0_S1CDMAX, pasid_bits) |
+		FIELD_PREP(STRTAB_STE_0_S1FMT, STRTAB_STE_0_S1FMT_LINEAR) |
+		STRTAB_STE_0_V;
+
+	return cd_table;
+}
+
+/*
+ * This function handles configuration for pasid and non-pasid domains
+ * with the following assumptions:
+ * - pasid 0 always attached first, this should be the typicall flow
+ *   for the kernel where attach_dev is always called before set_dev_pasid.
+ *   In that case only pasid 0 is allowed to allocate memory for the CD,
+ *   and other pasids would expect to find the tabel.
+ * - pasid 0 is detached last, also guaranteed from the kernel.
+ */
+static int smmu_domain_config_s1(struct hyp_arm_smmu_v3_device *smmu,
+				 struct kvm_hyp_iommu_domain *domain,
+				 u32 sid, u32 pasid, u32 pasid_bits,
+				 struct arm_smmu_ste *ste)
+{
+	struct arm_smmu_ste *dst;
+	u64 val;
+	u64 *cd_entry, *cd_table;
+	struct io_pgtable_cfg *cfg;
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+
+	cfg = &smmu_domain->pgtable->cfg;
+	dst = smmu_get_ste_ptr(smmu, sid);
+	val = dst->data[0];
+
+	if (FIELD_GET(STRTAB_STE_0_CFG, val) == STRTAB_STE_0_CFG_S2_TRANS)
+		return -EBUSY;
+
+	if (pasid == 0) {
+		cd_table = smmu_domain_config_s1_ste(smmu, pasid_bits, ste);
+		if (!cd_table)
+			return -ENOMEM;
+	} else {
+		u32 nr_entries;
+
+		cd_table = (u64 *)(FIELD_GET(STRTAB_STE_0_S1CTXPTR_MASK, val) << 6);
+		if (!cd_table)
+			return -EINVAL;
+		nr_entries = 1 << FIELD_GET(STRTAB_STE_0_S1CDMAX, val);
+		if (pasid >= nr_entries)
+			return -E2BIG;
+	}
+
+	/* Write CD. */
+	cd_entry = smmu_get_cd_ptr(hyp_phys_to_virt((u64)cd_table), pasid);
+
+	/* CD already used by another device. */
+	if (cd_entry[0])
+		return -EBUSY;
+
+	cd_entry[1] = cpu_to_le64(cfg->arm_lpae_s1_cfg.ttbr & CTXDESC_CD_1_TTB0_MASK);
+	cd_entry[2] = 0;
+	cd_entry[3] = cpu_to_le64(cfg->arm_lpae_s1_cfg.mair);
+
+	/* STE is live. */
+	if (pasid)
+		smmu_sync_cd(smmu, sid, pasid);
+	val =  FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz) |
+	       FIELD_PREP(CTXDESC_CD_0_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
+	       FIELD_PREP(CTXDESC_CD_0_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
+	       FIELD_PREP(CTXDESC_CD_0_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
+	       FIELD_PREP(CTXDESC_CD_0_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
+	       FIELD_PREP(CTXDESC_CD_0_TCR_IPS, cfg->arm_lpae_s1_cfg.tcr.ips) |
+	       CTXDESC_CD_0_TCR_EPD1 | CTXDESC_CD_0_AA64 |
+	       CTXDESC_CD_0_R | CTXDESC_CD_0_A |
+	       CTXDESC_CD_0_ASET |
+	       FIELD_PREP(CTXDESC_CD_0_ASID, domain->domain_id) |
+	       CTXDESC_CD_0_V;
+	WRITE_ONCE(cd_entry[0], cpu_to_le64(val));
+	/* STE is live. */
+	if (pasid)
+		smmu_sync_cd(smmu, sid, pasid);
+	return 0;
+}
+
+static int smmu_domain_finalise(struct hyp_arm_smmu_v3_device *smmu,
+				struct kvm_hyp_iommu_domain *domain)
+{
+	int ret;
+	struct io_pgtable_cfg cfg;
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+
+	if (smmu_domain->type == KVM_ARM_SMMU_DOMAIN_S1) {
+		size_t ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
+
+		cfg = (struct io_pgtable_cfg) {
+			.fmt = ARM_64_LPAE_S1,
+			.pgsize_bitmap = smmu->pgsize_bitmap,
+			.ias = min_t(unsigned long, ias, VA_BITS),
+			.oas = smmu->ias,
+			.coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENCY,
+			.tlb = &smmu_tlb_ops,
+		};
+	} else {
+		cfg = (struct io_pgtable_cfg) {
+			.fmt = ARM_64_LPAE_S2,
+			.pgsize_bitmap = smmu->pgsize_bitmap,
+			.ias = smmu->ias,
+			.oas = smmu->oas,
+			.coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENCY,
+			.tlb = &smmu_tlb_ops,
+		};
+	}
+
+	hyp_spin_lock(&smmu_domain->pgt_lock);
+	smmu_domain->pgtable = kvm_arm_io_pgtable_alloc(&cfg, domain, &ret);
+	hyp_spin_unlock(&smmu_domain->pgt_lock);
+	return ret;
+}
+
+static int smmu_attach_dev(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_domain *domain,
+			   u32 sid, u32 pasid, u32 pasid_bits)
+{
+	int i;
+	int ret;
+	struct arm_smmu_ste *dst;
+	struct arm_smmu_ste ste = {};
+	struct hyp_arm_smmu_v3_device *smmu = to_smmu(iommu);
+	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+
+	kvm_iommu_lock(iommu);
+	dst = smmu_get_alloc_ste_ptr(smmu, sid);
+	if (!dst) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
+
+	if (smmu_domain->smmu && (smmu != smmu_domain->smmu)) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (!smmu_domain->pgtable) {
+		ret = smmu_domain_finalise(smmu, domain);
+		if (ret)
+			goto out_unlock;
+	}
+
+	if (smmu_domain->type == KVM_ARM_SMMU_DOMAIN_S2) {
+		/* Device already attached or pasid for s2. */
+		if (dst->data[0] || pasid) {
+			ret = -EBUSY;
+			goto out_unlock;
+		}
+		ret = smmu_domain_config_s2(domain, &ste);
+	} else {
+		/*
+		 * Allocate and config CD, and update CD if possible.
+		 */
+		pasid_bits = min(pasid_bits, smmu->ssid_bits);
+		ret = smmu_domain_config_s1(smmu, domain, sid, pasid,
+					    pasid_bits, &ste);
+	}
+	smmu_domain->smmu = smmu;
+	/* We don't update STEs for pasid domains. */
+	if (ret || pasid)
+		goto out_unlock;
+
+	/*
+	 * The SMMU may cache a disabled STE.
+	 * Initialize all fields, sync, then enable it.
+	 */
+	for (i = 1; i < STRTAB_STE_DWORDS; i++)
+		dst->data[i] = ste.data[i];
+
+	ret = smmu_sync_ste(smmu, sid);
+	if (ret)
+		goto out_unlock;
+
+	WRITE_ONCE(dst->data[0], ste.data[0]);
+	ret = smmu_sync_ste(smmu, sid);
+	WARN_ON(ret);
+out_unlock:
+	kvm_iommu_unlock(iommu);
+	return ret;
+}
+
 /* Shared with the kernel driver in EL1 */
 struct kvm_iommu_ops smmu_ops = {
 	.init				= smmu_init,
@@ -828,4 +1059,5 @@ struct kvm_iommu_ops smmu_ops = {
 	.alloc_domain			= smmu_alloc_domain,
 	.free_domain			= smmu_free_domain,
 	.iotlb_sync			= smmu_iotlb_sync,
+	.attach_dev			= smmu_attach_dev,
 };
diff --git a/include/kvm/arm_smmu_v3.h b/include/kvm/arm_smmu_v3.h
index ded98cbaebc1..e8616ec5a048 100644
--- a/include/kvm/arm_smmu_v3.h
+++ b/include/kvm/arm_smmu_v3.h
@@ -25,6 +25,10 @@ struct hyp_arm_smmu_v3_device {
 	size_t			cmdq_log2size;
 	/* strtab_cfg.l2.l2ptrs is not used, instead computed from L1 */
 	struct arm_smmu_strtab_cfg strtab_cfg;
+	size_t			oas;
+	size_t			ias;
+	size_t			pgsize_bitmap;
+	size_t			ssid_bits;
 };
 
 extern size_t kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count);
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:20 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:20 +0000
Subject: [RFC PATCH v2 56/58] KVM: arm64: iommu: Add hypercall for map_sg
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-57-smostafa@google.com>

Add a new type struct kvm_iommu_sg, that describes a simple sglist,
and a hypercall that can consume it while calling the map_pages ops.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/include/asm/kvm_asm.h        |  1 +
 arch/arm64/include/asm/kvm_host.h       | 19 ++++++++
 arch/arm64/kvm/hyp/include/nvhe/iommu.h |  2 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      | 14 ++++++
 arch/arm64/kvm/hyp/nvhe/iommu/iommu.c   | 58 +++++++++++++++++++++++++
 arch/arm64/kvm/iommu.c                  | 32 ++++++++++++++
 6 files changed, 126 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 3dbf30cd10f3..f2b86d1a62ed 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -115,6 +115,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_unmap_pages,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_iova_to_phys,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_hvc_pd,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_iommu_map_sg,
 
 	/*
 	 * Start of the dynamically registered hypercalls. Start a bit
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 3cdc99ebdd0d..704648619d28 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1655,4 +1655,23 @@ int kvm_iommu_register_driver(struct kvm_iommu_driver *kern_ops,
 int kvm_iommu_init_driver(void);
 void kvm_iommu_remove_driver(void);
 
+struct kvm_iommu_sg {
+	phys_addr_t phys;
+	size_t pgsize;
+	unsigned int pgcount;
+};
+
+static inline struct kvm_iommu_sg *kvm_iommu_sg_alloc(unsigned int nents, gfp_t gfp)
+{
+	return alloc_pages_exact(PAGE_ALIGN(nents * sizeof(struct kvm_iommu_sg)), gfp);
+}
+
+static inline void kvm_iommu_sg_free(struct kvm_iommu_sg *sg, unsigned int nents)
+{
+	free_pages_exact(sg, PAGE_ALIGN(nents * sizeof(struct kvm_iommu_sg)));
+}
+
+int kvm_iommu_share_hyp_sg(struct kvm_iommu_sg *sg, unsigned int nents);
+int kvm_iommu_unshare_hyp_sg(struct kvm_iommu_sg *sg, unsigned int nents);
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
index cff75d67d807..1004465b680a 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h
@@ -22,6 +22,8 @@ size_t kvm_iommu_unmap_pages(pkvm_handle_t domain_id, unsigned long iova,
 			     size_t pgsize, size_t pgcount);
 phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t domain_id, unsigned long iova);
 bool kvm_iommu_host_dabt_handler(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr);
+size_t kvm_iommu_map_sg(pkvm_handle_t domain, unsigned long iova, struct kvm_iommu_sg *sg,
+			unsigned int nent, unsigned int prot);
 
 /* Flags for memory allocation for IOMMU drivers */
 #define IOMMU_PAGE_NOCACHE				BIT(0)
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 1ab8e5507825..5659aae0c758 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -1682,6 +1682,19 @@ static void handle___pkvm_host_hvc_pd(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) = pkvm_host_hvc_pd(device_id, on);
 }
 
+static void handle___pkvm_host_iommu_map_sg(struct kvm_cpu_context *host_ctxt)
+{
+	unsigned long ret;
+	DECLARE_REG(pkvm_handle_t, domain, host_ctxt, 1);
+	DECLARE_REG(unsigned long, iova, host_ctxt, 2);
+	DECLARE_REG(struct kvm_iommu_sg *, sg, host_ctxt, 3);
+	DECLARE_REG(unsigned int, nent, host_ctxt, 4);
+	DECLARE_REG(unsigned int, prot, host_ctxt, 5);
+
+	ret = kvm_iommu_map_sg(domain, iova, kern_hyp_va(sg), nent, prot);
+	hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
+}
+
 typedef void (*hcall_t)(struct kvm_cpu_context *);
 
 #define HANDLE_FUNC(x)	[__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x
@@ -1747,6 +1760,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_iommu_unmap_pages),
 	HANDLE_FUNC(__pkvm_host_iommu_iova_to_phys),
 	HANDLE_FUNC(__pkvm_host_hvc_pd),
+	HANDLE_FUNC(__pkvm_host_iommu_map_sg),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
index e45dadd0c4aa..b0c9b9086fd1 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
@@ -392,6 +392,64 @@ bool kvm_iommu_host_dabt_handler(struct kvm_cpu_context *host_ctxt, u64 esr, u64
 	return ret;
 }
 
+size_t kvm_iommu_map_sg(pkvm_handle_t domain_id, unsigned long iova, struct kvm_iommu_sg *sg,
+			unsigned int nent, unsigned int prot)
+{
+	int ret;
+	size_t total_mapped = 0, mapped;
+	struct kvm_hyp_iommu_domain *domain;
+	phys_addr_t phys;
+	size_t size, pgsize, pgcount;
+	unsigned int orig_nent = nent;
+	struct kvm_iommu_sg *orig_sg = sg;
+
+	if (!kvm_iommu_ops || !kvm_iommu_ops->map_pages)
+		return 0;
+
+	if (prot & ~IOMMU_PROT_MASK)
+		return 0;
+
+	domain = handle_to_domain(domain_id);
+	if (!domain || domain_get(domain))
+		return 0;
+
+	ret = hyp_pin_shared_mem(sg, sg + nent);
+	if (ret)
+		goto out_put_domain;
+
+	while (nent--) {
+		phys = sg->phys;
+		pgsize = sg->pgsize;
+		pgcount = sg->pgcount;
+
+		if (__builtin_mul_overflow(pgsize, pgcount, &size) ||
+		    iova + size < iova)
+			goto out_unpin_sg;
+
+		ret = __pkvm_host_use_dma(phys, size);
+		if (ret)
+			goto out_unpin_sg;
+
+		mapped = 0;
+		kvm_iommu_ops->map_pages(domain, iova, phys, pgsize, pgcount, prot, &mapped);
+		total_mapped += mapped;
+		phys += mapped;
+		iova += mapped;
+		/* Might need memory */
+		if (mapped != size) {
+			__pkvm_host_unuse_dma(phys, size - mapped);
+			break;
+		}
+		sg++;
+	}
+
+out_unpin_sg:
+	hyp_unpin_shared_mem(orig_sg, orig_sg + orig_nent);
+out_put_domain:
+	domain_put(domain);
+	return total_mapped;
+}
+
 static int iommu_power_on(struct kvm_power_domain *pd)
 {
 	struct kvm_hyp_iommu *iommu = container_of(pd, struct kvm_hyp_iommu,
diff --git a/arch/arm64/kvm/iommu.c b/arch/arm64/kvm/iommu.c
index af3417e6259d..99718af0cba6 100644
--- a/arch/arm64/kvm/iommu.c
+++ b/arch/arm64/kvm/iommu.c
@@ -55,3 +55,35 @@ void kvm_iommu_remove_driver(void)
 	if (smp_load_acquire(&iommu_driver))
 		iommu_driver->remove_driver();
 }
+
+int kvm_iommu_share_hyp_sg(struct kvm_iommu_sg *sg, unsigned int nents)
+{
+	size_t nr_pages = PAGE_ALIGN(sizeof(*sg) * nents) >> PAGE_SHIFT;
+	phys_addr_t sg_pfn = virt_to_phys(sg) >> PAGE_SHIFT;
+	int i;
+	int ret;
+
+	for (i = 0 ; i < nr_pages ; ++i) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp, sg_pfn + i);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+int kvm_iommu_unshare_hyp_sg(struct kvm_iommu_sg *sg, unsigned int nents)
+{
+	size_t nr_pages = PAGE_ALIGN(sizeof(*sg) * nents) >> PAGE_SHIFT;
+	phys_addr_t sg_pfn = virt_to_phys(sg) >> PAGE_SHIFT;
+	int i;
+	int ret;
+
+	for (i = 0 ; i < nr_pages ; ++i) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_hyp, sg_pfn + i);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:21 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:21 +0000
Subject: [RFC PATCH v2 57/58] iommu/arm-smmu-v3-kvm: Implement sg operations
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-58-smostafa@google.com>

Implement the new map_sg ops which mainly populate the kvm_iommu_sg
and pass it in the hypervisor.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c   | 93 +++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index e987c273ff3c..ac45455b384d 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -445,6 +445,96 @@ static phys_addr_t kvm_arm_smmu_iova_to_phys(struct iommu_domain *domain,
 	return kvm_call_hyp_nvhe(__pkvm_host_iommu_iova_to_phys, kvm_smmu_domain->id, iova);
 }
 
+struct kvm_arm_smmu_map_sg {
+	struct iommu_map_cookie_sg cookie;
+	struct kvm_iommu_sg *sg;
+	unsigned int ptr;
+	unsigned long iova;
+	int prot;
+	gfp_t gfp;
+	unsigned int nents;
+};
+
+static struct iommu_map_cookie_sg *kvm_arm_smmu_alloc_cookie_sg(unsigned long iova,
+								int prot,
+								unsigned int nents,
+								gfp_t gfp)
+{
+	int ret;
+	struct kvm_arm_smmu_map_sg *map_sg = kzalloc(sizeof(*map_sg), gfp);
+
+	if (!map_sg)
+		return NULL;
+
+	map_sg->sg = kvm_iommu_sg_alloc(nents, gfp);
+	if (!map_sg->sg)
+		return NULL;
+	map_sg->iova = iova;
+	map_sg->prot = prot;
+	map_sg->gfp = gfp;
+	map_sg->nents = nents;
+	ret = kvm_iommu_share_hyp_sg(map_sg->sg, nents);
+	if (ret) {
+		kvm_iommu_sg_free(map_sg->sg, nents);
+		kfree(map_sg);
+		return NULL;
+	}
+
+	return &map_sg->cookie;
+}
+
+static int kvm_arm_smmu_add_deferred_map_sg(struct iommu_map_cookie_sg *cookie,
+					    phys_addr_t paddr, size_t pgsize, size_t pgcount)
+{
+	struct kvm_arm_smmu_map_sg *map_sg = container_of(cookie, struct kvm_arm_smmu_map_sg,
+							  cookie);
+	struct kvm_iommu_sg *sg = map_sg->sg;
+
+	sg[map_sg->ptr].phys = paddr;
+	sg[map_sg->ptr].pgsize = pgsize;
+	sg[map_sg->ptr].pgcount = pgcount;
+	map_sg->ptr++;
+	return 0;
+}
+
+static int kvm_arm_smmu_consume_deferred_map_sg(struct iommu_map_cookie_sg *cookie)
+{
+	struct kvm_arm_smmu_map_sg *map_sg = container_of(cookie, struct kvm_arm_smmu_map_sg,
+							  cookie);
+	struct kvm_iommu_sg *sg = map_sg->sg;
+	size_t mapped, total_mapped = 0;
+	struct arm_smccc_res res;
+	struct kvm_arm_smmu_domain *kvm_smmu_domain = to_kvm_smmu_domain(map_sg->cookie.domain);
+
+	do {
+		res = kvm_call_hyp_nvhe_smccc(__pkvm_host_iommu_map_sg,
+					      kvm_smmu_domain->id,
+					      map_sg->iova, sg, map_sg->ptr, map_sg->prot);
+		mapped = res.a1;
+		map_sg->iova += mapped;
+		total_mapped += mapped;
+		/* Skip mapped */
+		while (mapped) {
+			if (mapped < (sg->pgsize * sg->pgcount)) {
+				sg->phys += mapped;
+				sg->pgcount -= mapped / sg->pgsize;
+				mapped = 0;
+			} else {
+				mapped -= sg->pgsize * sg->pgcount;
+				sg++;
+				map_sg->ptr--;
+			}
+		}
+
+		kvm_arm_smmu_topup_memcache(&res, map_sg->gfp);
+	} while (map_sg->ptr);
+
+	kvm_iommu_unshare_hyp_sg(sg, map_sg->nents);
+	kvm_iommu_sg_free(sg, map_sg->nents);
+	kfree(map_sg);
+	return 0;
+}
+
 static struct iommu_ops kvm_arm_smmu_ops = {
 	.capable		= kvm_arm_smmu_capable,
 	.device_group		= arm_smmu_device_group,
@@ -463,6 +553,9 @@ static struct iommu_ops kvm_arm_smmu_ops = {
 		.unmap_pages	= kvm_arm_smmu_unmap_pages,
 		.iova_to_phys	= kvm_arm_smmu_iova_to_phys,
 		.set_dev_pasid	= kvm_arm_smmu_set_dev_pasid,
+		.alloc_cookie_sg = kvm_arm_smmu_alloc_cookie_sg,
+		.add_deferred_map_sg = kvm_arm_smmu_add_deferred_map_sg,
+		.consume_deferred_map_sg = kvm_arm_smmu_consume_deferred_map_sg,
 	}
 };
 
-- 
2.47.0.338.g60cca15819-goog



From smostafa at google.com  Thu Dec 12 10:04:22 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 12 Dec 2024 18:04:22 +0000
Subject: [RFC PATCH v2 58/58] iommu/arm-smmu-v3-kvm: Support command queue batching
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212180423.1578358-59-smostafa@google.com>

Similar to the kernel driver, we can batch commands at EL2 to avoid
writing to MMIO space, this is quite noticable if the SMMU doesn't
support range invalidation so it has to invalidate page per page.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 arch/arm64/include/asm/arm-smmu-v3-common.h | 16 ++++
 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 95 ++++++++++++++++-----
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 15 ----
 3 files changed, 88 insertions(+), 38 deletions(-)

diff --git a/arch/arm64/include/asm/arm-smmu-v3-common.h b/arch/arm64/include/asm/arm-smmu-v3-common.h
index f2fbd286f674..2578c8e9202e 100644
--- a/arch/arm64/include/asm/arm-smmu-v3-common.h
+++ b/arch/arm64/include/asm/arm-smmu-v3-common.h
@@ -573,4 +573,20 @@ struct arm_smmu_cmdq_ent {
 	};
 };
 
+#define Q_OVERFLOW_FLAG			(1U << 31)
+#define Q_OVF(p)			((p) & Q_OVERFLOW_FLAG)
+
+/*
+ * This is used to size the command queue and therefore must be at least
+ * BITS_PER_LONG so that the valid_map works correctly (it relies on the
+ * total number of queue entries being a multiple of BITS_PER_LONG).
+ */
+#define CMDQ_BATCH_ENTRIES		BITS_PER_LONG
+
+struct arm_smmu_cmdq_batch {
+	u64				cmds[CMDQ_BATCH_ENTRIES * CMDQ_ENT_DWORDS];
+	struct arm_smmu_cmdq		*cmdq;
+	int				num;
+};
+
 #endif /* _ARM_SMMU_V3_COMMON_H */
diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
index 60f0760f49eb..62760136c6fb 100644
--- a/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
+++ b/arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c
@@ -96,12 +96,20 @@ static void smmu_reclaim_pages(u64 phys, size_t size)
 #define Q_WRAP(smmu, reg)	((reg) & (1 << (smmu)->cmdq_log2size))
 #define Q_IDX(smmu, reg)	((reg) & ((1 << (smmu)->cmdq_log2size) - 1))
 
-static bool smmu_cmdq_full(struct hyp_arm_smmu_v3_device *smmu)
+static bool smmu_cmdq_has_space(struct hyp_arm_smmu_v3_device *smmu, u32 n)
 {
-	u64 cons = readl_relaxed(smmu->base + ARM_SMMU_CMDQ_CONS);
+	u64 smmu_cons = readl_relaxed(smmu->base + ARM_SMMU_CMDQ_CONS);
+	u32 space, prod, cons;
 
-	return Q_IDX(smmu, smmu->cmdq_prod) == Q_IDX(smmu, cons) &&
-	       Q_WRAP(smmu, smmu->cmdq_prod) != Q_WRAP(smmu, cons);
+	prod = Q_IDX(smmu, smmu->cmdq_prod);
+	cons = Q_IDX(smmu, smmu_cons);
+
+	if (Q_WRAP(smmu, smmu->cmdq_prod) == Q_WRAP(smmu, smmu_cons))
+		space = (1 << smmu->cmdq_log2size) - (prod - cons);
+	else
+		space = cons - prod;
+
+	return space >= n;
 }
 
 static bool smmu_cmdq_empty(struct hyp_arm_smmu_v3_device *smmu)
@@ -112,22 +120,8 @@ static bool smmu_cmdq_empty(struct hyp_arm_smmu_v3_device *smmu)
 	       Q_WRAP(smmu, smmu->cmdq_prod) == Q_WRAP(smmu, cons);
 }
 
-static int smmu_add_cmd(struct hyp_arm_smmu_v3_device *smmu,
-			struct arm_smmu_cmdq_ent *ent)
+static int smmu_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
 {
-	int i;
-	int ret;
-	u64 cmd[CMDQ_ENT_DWORDS] = {};
-	int idx = Q_IDX(smmu, smmu->cmdq_prod);
-	u64 *slot = smmu->cmdq_base + idx * CMDQ_ENT_DWORDS;
-
-	if (smmu->iommu.power_is_off)
-		return -EPIPE;
-
-	ret = smmu_wait_event(smmu, !smmu_cmdq_full(smmu));
-	if (ret)
-		return ret;
-
 	cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
 
 	switch (ent->opcode) {
@@ -175,15 +169,49 @@ static int smmu_add_cmd(struct hyp_arm_smmu_v3_device *smmu,
 		return -EINVAL;
 	}
 
-	for (i = 0; i < CMDQ_ENT_DWORDS; i++)
-		slot[i] = cpu_to_le64(cmd[i]);
+	return 0;
+}
+
+static int smmu_issue_cmds(struct hyp_arm_smmu_v3_device *smmu,
+			   u64 *cmds, int n)
+{
+	int idx = Q_IDX(smmu, smmu->cmdq_prod);
+	u64 *slot = smmu->cmdq_base + idx * CMDQ_ENT_DWORDS;
+	int i;
+	int ret;
+	u32 prod;
+
+	if (smmu->iommu.power_is_off)
+		return -EPIPE;
+
+	ret = smmu_wait_event(smmu, smmu_cmdq_has_space(smmu, n));
+	if (ret)
+		return ret;
+
+	for (i = 0; i < CMDQ_ENT_DWORDS * n; i++)
+		slot[i] = cpu_to_le64(cmds[i]);
+
+	prod = (Q_WRAP(smmu, smmu->cmdq_prod) | Q_IDX(smmu, smmu->cmdq_prod)) + n;
+	smmu->cmdq_prod = Q_OVF(smmu->cmdq_prod) | Q_WRAP(smmu, prod) | Q_IDX(smmu, prod);
 
-	smmu->cmdq_prod++;
 	writel(Q_IDX(smmu, smmu->cmdq_prod) | Q_WRAP(smmu, smmu->cmdq_prod),
 	       smmu->base + ARM_SMMU_CMDQ_PROD);
 	return 0;
 }
 
+static int smmu_add_cmd(struct hyp_arm_smmu_v3_device *smmu,
+			struct arm_smmu_cmdq_ent *ent)
+{
+	u64 cmd[CMDQ_ENT_DWORDS] = {};
+	int ret;
+
+	ret = smmu_build_cmd(cmd, ent);
+	if (ret)
+		return ret;
+
+	return smmu_issue_cmds(smmu, cmd, 1);
+}
+
 static int smmu_sync_cmd(struct hyp_arm_smmu_v3_device *smmu)
 {
 	int ret;
@@ -685,6 +713,23 @@ static void smmu_tlb_flush_all(void *cookie)
 	kvm_iommu_unlock(&smmu->iommu);
 }
 
+static void smmu_cmdq_batch_add(struct hyp_arm_smmu_v3_device *smmu,
+				struct arm_smmu_cmdq_batch *cmds,
+				struct arm_smmu_cmdq_ent *cmd)
+{
+	int index;
+
+	if (cmds->num == CMDQ_BATCH_ENTRIES) {
+		smmu_issue_cmds(smmu, cmds->cmds, cmds->num);
+		cmds->num = 0;
+	}
+
+	index = cmds->num * CMDQ_ENT_DWORDS;
+	smmu_build_cmd(&cmds->cmds[index], cmd);
+
+	cmds->num++;
+}
+
 static int smmu_tlb_inv_range_smmu(struct hyp_arm_smmu_v3_device *smmu,
 				   struct kvm_hyp_iommu_domain *domain,
 				   struct arm_smmu_cmdq_ent *cmd,
@@ -694,6 +739,7 @@ static int smmu_tlb_inv_range_smmu(struct hyp_arm_smmu_v3_device *smmu,
 	unsigned long end = iova + size, num_pages = 0, tg = 0;
 	size_t inv_range = granule;
 	struct hyp_arm_smmu_v3_domain *smmu_domain = domain->priv;
+	struct arm_smmu_cmdq_batch cmds;
 
 	kvm_iommu_lock(&smmu->iommu);
 	if (smmu->iommu.power_is_off)
@@ -723,6 +769,8 @@ static int smmu_tlb_inv_range_smmu(struct hyp_arm_smmu_v3_device *smmu,
 			num_pages++;
 	}
 
+	cmds.num = 0;
+
 	while (iova < end) {
 		if (smmu->features & ARM_SMMU_FEAT_RANGE_INV) {
 			/*
@@ -749,11 +797,12 @@ static int smmu_tlb_inv_range_smmu(struct hyp_arm_smmu_v3_device *smmu,
 			num_pages -= num << scale;
 		}
 		cmd->tlbi.addr = iova;
-		WARN_ON(smmu_add_cmd(smmu, cmd));
+		smmu_cmdq_batch_add(smmu, &cmds, cmd);
 		BUG_ON(iova + inv_range < iova);
 		iova += inv_range;
 	}
 
+	WARN_ON(smmu_issue_cmds(smmu, cmds.cmds, cmds.num));
 	ret = smmu_sync_cmd(smmu);
 out_ret:
 	kvm_iommu_unlock(&smmu->iommu);
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 d91dfe55835d..18f878bb7f98 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -20,8 +20,6 @@ struct arm_smmu_device;
 
 #define Q_IDX(llq, p)			((p) & ((1 << (llq)->max_n_shift) - 1))
 #define Q_WRP(llq, p)			((p) & (1 << (llq)->max_n_shift))
-#define Q_OVERFLOW_FLAG			(1U << 31)
-#define Q_OVF(p)			((p) & Q_OVERFLOW_FLAG)
 #define Q_ENT(q, p)			((q)->base +			\
 					 Q_IDX(&((q)->llq), p) *	\
 					 (q)->ent_dwords)
@@ -35,13 +33,6 @@ struct arm_smmu_device;
 
 #define CMDQ_PROD_OWNED_FLAG		Q_OVERFLOW_FLAG
 
-/*
- * This is used to size the command queue and therefore must be at least
- * BITS_PER_LONG so that the valid_map works correctly (it relies on the
- * total number of queue entries being a multiple of BITS_PER_LONG).
- */
-#define CMDQ_BATCH_ENTRIES		BITS_PER_LONG
-
 /* High-level queue structures */
 #define ARM_SMMU_POLL_TIMEOUT_US	1000000 /* 1s! */
 #define ARM_SMMU_POLL_SPIN_COUNT	10
@@ -100,12 +91,6 @@ static inline bool arm_smmu_cmdq_supports_cmd(struct arm_smmu_cmdq *cmdq,
 	return cmdq->supports_cmd ? cmdq->supports_cmd(ent) : true;
 }
 
-struct arm_smmu_cmdq_batch {
-	u64				cmds[CMDQ_BATCH_ENTRIES * CMDQ_ENT_DWORDS];
-	struct arm_smmu_cmdq		*cmdq;
-	int				num;
-};
-
 struct arm_smmu_evtq {
 	struct arm_smmu_queue		q;
 	struct iopf_queue		*iopf;
-- 
2.47.0.338.g60cca15819-goog



From Jason-JH.Lin at mediatek.com  Thu Dec 12 10:06:53 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Thu, 12 Dec 2024 18:06:53 +0000
Subject: [PATCH v2 1/8] dt-bindings: mailbox: mediatek: Add GCE header
 file for MT8196
In-Reply-To: <5d48f335-7b14-487b-ba08-6354d21d8993@kernel.org>
References: <20241211032256.28494-1-jason-jh.lin@mediatek.com>
	 <20241211032256.28494-2-jason-jh.lin@mediatek.com>
	 <ozifi65uycmxc5hqeu4onbths5u7dg532iufjxplsjw4jjmhf6@6bdsaabd7hl7>
	 <04f7bd2a7d69ab7d02c88cf05bda5ae0c4cb6573.camel@mediatek.com>
	 <e9caf0fe-a77f-40cb-9fc3-9da3d95f27ca@kernel.org>
	 <ce68d58f78d12317cab689e0ee1c02dc373d50dc.camel@mediatek.com>
	 <5d48f335-7b14-487b-ba08-6354d21d8993@kernel.org>
Message-ID: <a467a9415a4e0505e95701dd6031f642030fe21f.camel@mediatek.com>

On Thu, 2024-12-12 at 13:23 +0100, Krzysztof Kozlowski wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On 12/12/2024 12:24, Jason-JH Lin (???) wrote:
> > > > > 
> > > > > On Wed, Dec 11, 2024 at 11:22:49AM +0800, Jason-JH.Lin wrote:
> > > > > > Add the Global Command Engine (GCE) header file to define
> > > > > > the
> > > > > > GCE
> > > > > > thread priority, GCE subsys ID and GCE events for MT8196.
> > > > > 
> > > > > This we see from the diff. What we do not see is why priority
> > > > > is
> > > > > a
> > > > > binding. Looking briefly at existing code: it is not a
> > > > > binding,
> > > > > there
> > > > > is
> > > > > no driver user.
> > > > > 
> > > > 
> > > > This priority value is used to configure the priority level for
> > > > each
> > > > GCE hardware thread, so it is a necessary hardware attribute.
> > > 
> > > I did not say these are not "hardware". I said these are not
> > > bindings.
> > > Bring arguments why these are bindings.
> > > 
> > 
> > Not only bringing arguments, we use it to configure each GCE
> > thread's
> > priority.
> > 
> > Please forgive me to ask a trivial question.
> > Do you mean if there is no driver using it directly, then it can
> > not be
> > a binding?
> 
> Here:
> <qqqwdzmcnkuga6qvvszgg7o2myb26sld5i37e4konhln2n4cgc at mwtropwj3ywv>
> 

Your reply in this example is really clear:
Register values are not bindings, they do not bind anything. Bindings
are imaginary numbers starting from 0 or 1 which are used between
drivers and DTS, serving as abstraction layer (or abstraction values)
between these two.

Now I can understand what the binding should be. Thank you very much.

From the description here, the GCE priority is not the imaginary
number, so we can just use the real number priority value in dts
instead of defining it in the binding header.

I thought the only advantage we define it here is to restrict the DTS
using the priority value between the CMDQ_THR_PRIO_LOWEST and
CMDQ_THR_PRIO_HIGHEST.

> > Or could you give me an example for what should be binding and what
> > should not be binding?
> 
> Look at all clock IDs of recent arm64 SoC clock controllers.
> 

I think clock IDs are the same as the actual bit to set into the
hardware register.

> > 
> > 
> > Considering to these 3 points, I think GCE thread priority is
> > suitable
> > to be part of the Device Tree Binding:
> > 
> > 1. Describing Hardware Properties
> > - The Device Tree is a data structure for describing hardware, and
> > GCE
> > thread priority, as part of the hardware, should be described in
> > the
> > Device Tree.
> 
> I thought we talk about bindings, not DeviceTree. Where is any
> Devicetree here? Please point me to the code which is Devicetree in
> this
> patch.
> 
> 
> > 
> > 2. Driver Usage
> > - Device Tree data is used by drivers to initialize and configure
> > hardware, and GCE thread priority is necessary configuration data
> > for
> > the driver. After parsing the mboxes args from DTS, CMDQ driver use
> > it
> > to configure GCE thread.
> 
> We talk about bindings, so why are you describing something else?
> 
> > 
> > 3. Standardization
> > - Device Tree bindings should be standardized, and GCE thread
> > priority
> > should have consistent meaning and usage across different hardware
> > platforms. Looking into the latest header: mediatek,mt8188-gce.h,
> > mediatek,mt6795-gce.h and mt8195-gce.h, they all have defined GCE
> > thread priority.
> 
> None of above arguments have anything related to the talk here. You
> invent some stuff like "standardization" or "driver usage".
> 

I 'm sorry to keep misunderstanding your question.
Please forget about that.

> > 
> > > > 
> > > > It's hard to find where the priority is used in existing driver
> > > > code
> > > > because we parsed it from DTS.
> > > 
> > > So not a binding.
> > > 
> > > > 
> > > > It is used in all mediaTeks' DTS using the GCE.
> > > > For example, in mt8195.dts:
> > > > 
> > > > vdosys0: syscon at 1c01a000 {
> > > >     compatible = "mediatek,mt8195-vdosys0", "mediatek,mt8195-
> > > > mmsys",
> > > > "syscon";
> > > >     reg = <0 0x1c01a000 0 0x1000>;
> > > >     mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
> > > >     #clock-cells = <1>;
> > > >     mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0xa000
> > > > 0x1000>;
> > > > }
> > > > 
> > > > CMDQ driver(mtk-cmdq-mailbox.c) will get the args parsed from
> > > > mboxes
> > > > property in cmdq_xlate() and then it will store CMDQ_THR_PRIO_4
> > > > to
> > > > the
> > > > specific thread structure.
> > > 
> > > So not a binding.
> > > 
> > > > The user of CMDQ driver will send command to CMDQ driver by
> > > > cmdq_mbox_send_data(), and this priority setting will be
> > > > configured
> > > > to
> > > > GCE hardware thread.
> > > 
> > > And other things there are the same, we do not talk only about
> > > this
> > > one
> > > thing. I asked last time to drop which is not a binding.
> > > 
> > > 
> > 
> > I just reference all the previous mediatek,mtXXXX-gce.h to add the
> > same
> > binding. Except for the GPR part I added this time, I don't know
> > what
> > else should be dropped.
> 
> Your commit msg does not help me, either. Why this is supposed to be
> a
> binding? Basically your rationale is: someone added headers, so I
> call
> it binding.
> 
> This is invalid argument.
> 
> Someone added junk, incorrect style or bugs, so you do the same?
> 
> 

Definitely not. I just not understand the meaning of binding.
So I just try to recall your memory why the previous headers are
accepted. Sorry about that.

> > 
> > > ...
> > > 
> > > > > > +
> > > > > > +/*
> > > > > > + * GCE General Purpose Register (GPR) support
> > > > > > + * Leave note for scenario usage here
> > > > > > + */
> > > > > > +/* GCE: write mask */
> > > > > 
> > > > > That's a definite no-go. Register masks are not bindings.
> > > > > 
> > > > 
> > > > I'm sorry to the confusion.
> > > > 
> > > > These defines are the index of GCE General Purpose Register for
> > > > generating instructions, they are not register masks.
> > > 
> > > Index of register is also sounding like register.
> > > 
> > > > 
> > > > The comment "/* GCE: write mask */" is briefly describe that
> > > > the
> > > > usage
> > > > of GCE_GPR_R0 and GCE_GPR_R01 is used to store the register
> > > > mask
> > > > when
> > > > GCE executing the WRITE instruction. And it can also store the
> > > > register
> > > > mask of POLL and READ instruction.
> > > > 
> > > > I will add more words to make this comment clearer, like this:
> > > > /*GCE: store the mask of instruction */
> > > 
> > > Not sure, because I feel you just avoid doing what is right and
> > > keep
> > > pushing your own narrative. Where is it used in the driver?
> > > 
> > > I just looked for "GCE_GPR_R00" - no usage at all. So not a
> > > binding.
> > > 
> > 
> > Currently, GCE_GPR_R15 is used for generating POLL instruction and
> > it
> > has been defined as a MACRO `#define CMDQ_POLL_ADDR_GPR (15)`
> > in mtk-cmdq-helper.c.
> 
> I search for GCE_GPR_R15. No usage at all.
> 

Yes, GCE_GPR_RXX is not used currently. I'll drop them.

> Point me to specific line in your code. Paste it here.
> 
> Above #define does not use.
> 
> I am finishing replying, because you keep avoiding actual answers and
> bring some false proves forcing me to re-iterate the same over and
> over.
> 
> Point to specific line of code and you point to something else and
> then
> claim this is argument in discussion.
> 

Since mt8196.dtsi has not sent to upstream, I will post the same
bindings in mediatek,mt8188-gce.h from DTS to the CMDQ driver code.

Please help me to check if it can be token into account as a binding.

1. include/dt-bindings/mailbox/mediatek,mt8188-gce.h: line 14:
#define CMDQ_THR_PRIO_4 4

arch/arm64/boot/dts/mediatek/mt8188.dtsi: line 2622:
vdosys0: syscon at 1c01d000{
    mboxes = <&gce 0 CMDQ_THR_PRIO_4>;
}

drivers/gpu/drm/mediatek/mtk_crtc.c: line 1069:
mtk_crtc->cmdq_client.chan =
    mbox_request_channel(&mtk_crtc->cmdq_client.client, i);

drivers/mailbox/mailbox.c: line 418:
if (of_parse_phandle_with_args(dev->of_node, "mboxes",
                               "mbox-cells", index, &spec)) {
...
}
chan = mbox->of_xlate(mbox, &spec);

drivers/mailbox/mtk-cmdq-mailbox.c: line 574:
static struct mbox_chan *cmdq_xlate(struct mbox_controller *mbox,
        const struct of_phandle_args *sp){
    thread->priority = sp->arg[1];
}

drivers/mailbox/mtk-cmdq-mailbox.c: line 424:
static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) {
    writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
}


2. include/dt-bindings/mailbox/mediatek,mt8188-gce.h: line 21:
#define SUBSYS_1c00XXXX 3

arch/arm64/boot/dts/mediatek/mt8188.dtsi: line 2490:
ovl0: ovl at 1c000000 {
    mediatek,gce-client-reg = <&gce SUBSYS_1c00XXXX 0x0000 0x1000>;
}

drivers/gpu/drm/mediatek/mtk_disp_ovl.c: line 621:
ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);

drivers/soc/mediatek/mtk-cmdq-helper.c: line 59:
int cmdq_dev_get_client_reg(struct device *dev,
                        struct cmdq_client_reg *client_reg, int idx) {
    client_reg->subsys = (u8)spec.arg[0];
}

drivers/gpu/drm/mediatek/mtk_disp_ovl.c: line 361:
void mtk_ovl_layer_on(struct device *dev, unsigned int idx,
                      struct cmdq_pkt *cmdq_pkt){
    mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &ovl->cmdq_reg, ovl->regs,
                       DISP_REG_OVL_SRC_CON, BIT(idx));
}

drivers/gpu/drm/mediatek/mtk_ddp_comp.c: line 101:
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) {
    cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys,
                        cmdq_reg->offset + offset, value, mask);
}

drivers/soc/mediatek/mtk-cmdq-helper.c: line 177:
cmdq_pkt_write_mask()
cmdq_pkt_write()
cmdq_pkt_append_command() {
// generate instruction to the cmdq buffer that will be executed by GCE
    *cmdq_ptr = inst;
}


3. include/dt-bindings/mailbox/mediatek,mt8188-gce.h: line 526:
#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0 574

arch/arm64/boot/dts/mediatek/mt8188.dtsi: line 2597:
mutex0: mutex at 1c016000 {
    mediatek,gce-events = <CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0>;
}

drivers/gpu/drm/mediatek/mtk_crtc.c: line 1077:
ret = of_property_read_u32_index(priv->mutex_node,
                                 "mediatek,gce-events",
                                 i,
                                 &mtk_crtc->cmdq_event);

drivers/gpu/drm/mediatek/mtk_crtc.c: line 592:
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);

drivers/soc/mediatek/mtk-cmdq-helper.c: line 363:
cmdq_pkt_clear_event(s
truct cmdq_pkt *pkt, u16 event) {
    struct cmdq_instruction inst = {
  
.op = CMDQ_CODE_WFE,
        .value = CMDQ_WFE_UPDATE,
        .event =
event
    };

    if (event >= CMDQ_MAX_EVENT)
        return -EINVAL;

    return cmdq_pkt_append_command(pkt, int);
}

drivers/soc/mediatek/mtk-cmdq-helper.c: line 177:
cmdq_pkt_append_command(struct cmdq_pkt *pkt,
                        struct cmdq_instruction *inst) {
// generate instruction to the cmdq buffer that will be executed by GCE
    *cmdq_ptr = inst;
}


I'm appreciate for your patience. Thanks again.

Regards,
Jason-JH.Lin

> 
> 
> Best regards,
> Krzysztof

From dave.stevenson at raspberrypi.com  Thu Dec 12 10:36:32 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 18:36:32 +0000
Subject: [PATCH v3 5/7] arm64: dts: broadcom: Rename bcm2712 interrupt
 controllers
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v3-5-44a7f3390331@raspberrypi.com>

CHECK_DTBS produces errors on bcm2712-rpi-5-b.dtb and bcm2712-d-rpi-5-b.dtb
of:
intc at 7d508380: $nodename:0: 'intc at 7d508380' does not match '^interrupt-controller(@[0-9a-f,]+)*$'
        from schema $id: http://devicetree.org/schemas/interrupt-controller/brcm,l2-intc.yaml#
intc at 7d508400: $nodename:0: 'intc at 7d508400' does not match '^interrupt-controller(@[0-9a-f,]+)*$'
        from schema $id: http://devicetree.org/schemas/interrupt-controller/brcm,l2-intc.yaml#

Rename the nodes from intc to interrupt-controller.

Fixes: f66b382affd8 ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
index 39305e0869ec..bd78af0211b6 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -336,7 +336,7 @@ ddc1: i2c at 7d508280 {
 			#size-cells = <0>;
 		};
 
-		bsc_irq: intc at 7d508380 {
+		bsc_irq: interrupt-controller at 7d508380 {
 			compatible = "brcm,bcm7271-l2-intc";
 			reg = <0x7d508380 0x10>;
 			interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
@@ -344,7 +344,7 @@ bsc_irq: intc at 7d508380 {
 			#interrupt-cells = <1>;
 		};
 
-		main_irq: intc at 7d508400 {
+		main_irq: interrupt-controller at 7d508400 {
 			compatible = "brcm,bcm7271-l2-intc";
 			reg = <0x7d508400 0x10>;
 			interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;

-- 
2.34.1



From catalin.marinas at arm.com  Thu Dec 12 10:08:03 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 12 Dec 2024 18:08:03 +0000
Subject: [PATCH 0/2] arm64: stacktrace: Fixes
In-Reply-To: <20241211140704.2498712-1-mark.rutland@arm.com>
References: <20241211140704.2498712-1-mark.rutland@arm.com>
Message-ID: <173402687928.3947168.7807121030690406216.b4-ty@arm.com>

On Wed, 11 Dec 2024 14:07:02 +0000, Mark Rutland wrote:
> These patches fix a couple of issues in the arm64 stacktrace code. Both
> address some fallout from the recent changes to unwinding across
> exception boundaries, though the issue in the second patch has been
> latent in the code for a while.
> 
> The first patch was previously posted independently at:
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/2] arm64: stacktrace: Skip reporting LR at exception boundaries
      https://git.kernel.org/arm64/c/32ed1205682e
[2/2] arm64: stacktrace: Don't WARN when unwinding other tasks
      https://git.kernel.org/arm64/c/65ac33bed8b9

-- 
Catalin



From martin at wetterwald.eu  Thu Dec 12 10:13:41 2024
From: martin at wetterwald.eu (Martin Wetterwald)
Date: Thu, 12 Dec 2024 19:13:41 +0100
Subject: Raspberry Pi 3B: Failed to create device link with soc:firmware:gpio
In-Reply-To: <d02a7143-43e7-4851-a06e-d57981362a5a@gmx.net>
References: <CAFERDQ2hLHek+0ViVqbqgOD+4xwC2ZwK1KhgGdLP_zGnonEs4w@mail.gmail.com>
 <d02a7143-43e7-4851-a06e-d57981362a5a@gmx.net>
Message-ID: <CAFERDQ0AUhCp_c0LLRRR9SWyvDON-CdXFvK3eqcLFc_SMhdPRw@mail.gmail.com>

On Thu, Dec 12, 2024 at 2:16?PM Stefan Wahren <wahrenst at gmx.net> wrote:
> What happens if you replace your custom config with arm64/defconfig?
> Does the issue still occurs?

I've just launched a kernel with the arm64 defconfig:

> 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 99, base_baud = 0) is a PL011 rev2
> serial serial0: tty port ttyAMA0 registered
> raspberrypi-firmware soc:firmware: Attached to firmware from 2024-09-13T16:00:01
> hci_uart_bcm serial0-0: supply vbat not found, using dummy regulator
> hci_uart_bcm serial0-0: supply vddio not found, using dummy regulator
> Bluetooth: hci0: BCM: chip id 94
> Bluetooth: hci0: BCM: features 0x2e
> Bluetooth: hci0: BCM43430A1
> Bluetooth: hci0: BCM43430A1 (001.002.009) build 0000

And it worked perfectly. Thanks for your suggestion. It confirmed the problem
came from my kernel config.

I then compared both .config and it appeared I was missing this config flag:

> CONFIG_SERIAL_DEV_CTRL_TTYPORT

I had already enabled CONFIG_SERIAL_DEV_BUS, but not CTRL_TTYPORT.
Nevertheless, that first kernel config item's prompt had been clear about that,
but I missed the advice:

> CONFIG_SERIAL_DEV_BUS
> Core support for devices connected via a serial port.
> Note that you typically also want to enable TTY port controller support.

It's so much better now to see the HCI attachment handled by the kernel
directly!

Thank you for your help.
Martin


From robh at kernel.org  Thu Dec 12 10:14:20 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 12 Dec 2024 12:14:20 -0600
Subject: [PATCH v2 1/7] dt-bindings: display: bcm2711-hdmi: Add
 interrupt details for BCM2712
In-Reply-To: <20241212-dt-bcm2712-fixes-v2-1-35986e04d0f4@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4@raspberrypi.com>
 <20241212-dt-bcm2712-fixes-v2-1-35986e04d0f4@raspberrypi.com>
Message-ID: <173402726027.2935600.12242526873775357219.robh@kernel.org>


On Thu, 12 Dec 2024 16:18:51 +0000, Dave Stevenson wrote:
> Commit 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
> added the compatible strings for BCM2712, but missed out that the
> number of interrupts changed.
> 
> Update the schema to include the interrupt requirements.
> 
> Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  .../bindings/display/brcm,bcm2711-hdmi.yaml        | 107 ++++++++++++++++++---
>  1 file changed, 93 insertions(+), 14 deletions(-)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:
./Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml:59:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
./Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml:67:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
./Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml:76:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
./Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml:84:9: [warning] wrong indentation: expected 10 but found 8 (indentation)

dtschema/dtc warnings/errors:

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241212-dt-bcm2712-fixes-v2-1-35986e04d0f4 at raspberrypi.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 dave.stevenson at raspberrypi.com  Thu Dec 12 10:36:31 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 18:36:31 +0000
Subject: [PATCH v3 4/7] dt-bindings: interrupt-controller:
 brcm,bcm2836-l1-intc: Drop interrupt-controller requirement
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v3-4-44a7f3390331@raspberrypi.com>

Since commit 88bbe85dcd37 ("irqchip: bcm2836: Move SMP startup code to
arch/arm (v2)") the bcm2836-l1-intc block on bcm2711 is only used as a
base address for the smp_boot_secondary hook on 32 bit kernels. It is
not used as an interrupt controller.

Drop the binding requirement for interrupt-controller and interrupt-cells
to satisfy validation on this platform.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml  | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
index 5fda626c80ce..2ff390c1705b 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
@@ -34,8 +34,6 @@ properties:
 required:
   - compatible
   - reg
-  - interrupt-controller
-  - '#interrupt-cells'
 
 additionalProperties: false
 

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Thu Dec 12 10:36:33 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 18:36:33 +0000
Subject: [PATCH v3 6/7] arm64: dts: broadcom: Correct hdmi device node
 names
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v3-6-44a7f3390331@raspberrypi.com>

The names of the hdmi0 and hdmi1 nodes had addresses that
didn't match the reg properties for the nodes.

Fixes: f66b382affd8 ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
index bd78af0211b6..f42fad2d8b37 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -352,7 +352,7 @@ main_irq: interrupt-controller at 7d508400 {
 			#interrupt-cells = <1>;
 		};
 
-		hdmi0: hdmi at 7ef00700 {
+		hdmi0: hdmi at 7c701400 {
 			compatible = "brcm,bcm2712-hdmi0";
 			reg = <0x7c701400 0x300>,
 			      <0x7c701000 0x200>,
@@ -381,7 +381,7 @@ hdmi0: hdmi at 7ef00700 {
 			ddc = <&ddc0>;
 		};
 
-		hdmi1: hdmi at 7ef05700 {
+		hdmi1: hdmi at 7c706400 {
 			compatible = "brcm,bcm2712-hdmi1";
 			reg = <0x7c706400 0x300>,
 			      <0x7c706000 0x200>,

-- 
2.34.1



From florian.fainelli at broadcom.com  Thu Dec 12 10:38:20 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 12 Dec 2024 10:38:20 -0800
Subject: [PATCH v3 3/7] dt-bindings: gpio: brcmstb: permit gpio-line-names
 property
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-3-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
 <20241212-dt-bcm2712-fixes-v3-3-44a7f3390331@raspberrypi.com>
Message-ID: <deed2858-ceaa-42bd-85f0-2b280070437f@broadcom.com>

On 12/12/24 10:36, Dave Stevenson wrote:
> gpio-line-names is a generic property that can be supported by any
> GPIO controller, so permit it through the binding.
> 
> It is permitted to have a variable number of GPIOs per node based
> on brcm,gpio-bank-widths, so define an arbitrary maximum number of
> items based on current users.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>

Acked-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From dave.stevenson at raspberrypi.com  Thu Dec 12 10:36:34 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 18:36:34 +0000
Subject: [PATCH v3 7/7] arm64: dts: broadcom: Remove intc controller on
 BCM2712.
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v3-7-44a7f3390331@raspberrypi.com>

The brcm,bcm2836-l1-intc controller isn't used on this platform.
It is used on 32-bit kernels for the smp_boot_secondary hook, but
BCM2712 can't run a 32-bit kernel.

Remove the node.

Fixes: e1417095a139 ("arm64: dts: broadcom: Add firmware clocks and power nodes to Pi5 DT")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
index f42fad2d8b37..9a426aa27c74 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -221,11 +221,6 @@ mailbox: mailbox at 7c013880 {
 			#mbox-cells = <0>;
 		};
 
-		local_intc: interrupt-controller at 7cd00000 {
-			compatible = "brcm,bcm2836-l1-intc";
-			reg = <0x7cd00000 0x100>;
-		};
-
 		uart10: serial at 7d001000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x7d001000 0x200>;

-- 
2.34.1



From konrad.dybcio at oss.qualcomm.com  Thu Dec 12 10:19:47 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 12 Dec 2024 19:19:47 +0100
Subject: [PATCH v7 3/5] dt-bindings: arm: Add Coresight TMC Control Unit
 hardware
In-Reply-To: <20241210031545.3468561-4-quic_jiegan@quicinc.com>
References: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
 <20241210031545.3468561-4-quic_jiegan@quicinc.com>
Message-ID: <8c60e0dc-531a-47d6-9c40-ea157a24da1b@oss.qualcomm.com>

On 10.12.2024 4:15 AM, Jie Gan wrote:
> Add binding file to specify how to define a Coresight TMC
> Control Unit device in device tree.
> 
> It is responsible for controlling the data filter function
> based on the source device's Trace ID for TMC ETR device.
> The trace data with that Trace id can get into ETR's buffer
> while other trace data gets ignored.
> 
> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> Signed-off-by: Jie Gan <quic_jiegan at quicinc.com>
> ---

[...]

> +
> +properties:
> +  compatible:
> +    enum:
> +      - qcom,sa8775p-ctcu

I don't think anyone asked that question.. Is the TMCCU something unique
to Qualcomm platforms?

Konrad


From Jason-JH.Lin at mediatek.com  Thu Dec 12 10:23:20 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Thu, 12 Dec 2024 18:23:20 +0000
Subject: [PATCH 2/2] dts: arm64: mediatek: mt8188: Update OVL compatible
 from MT8183 to MT8195
In-Reply-To: <6710abd1-128d-48ff-84a1-880053fd9e84@collabora.com>
References: <20241212153344.27408-1-jason-jh.lin@mediatek.com>
	 <20241212153344.27408-3-jason-jh.lin@mediatek.com>
	 <6710abd1-128d-48ff-84a1-880053fd9e84@collabora.com>
Message-ID: <52d88608156c3ced97f3d6b3d5722ab7f1747ea3.camel@mediatek.com>

On Thu, 2024-12-12 at 17:05 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> Il 12/12/24 16:33, Jason-JH.Lin ha scritto:
> > The OVL hardware capabilities have changed starting from MT8195,
> > making the MT8183 compatible no longer applicable.
> > Therefore, it is necessary to update the OVL compatible from MT8183
> > to
> > MT8195.
> > 
> > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> 
> Jason, just so you know - I have patches here adding DSC and merge
> components of
> VDO0, other than all MDP3 components.
> 
> Those are almost ready to send, I only need to finish some testing
> before ;-)
> 
> For this one, anyway:
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> 
> 

Hi Angelo,

Thanks for the notification and review.
It's okay for me to rebase on your patches.

Just let me know if I need to adjust this patch after you sending it.

Regards,
Jason-JH.Lin

> > ---
> >   arch/arm64/boot/dts/mediatek/mt8188.dtsi | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> > b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> > index faccc7f16259..23ec3ff6cad9 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> > +++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> > @@ -2488,7 +2488,7 @@ jpeg_decoder: jpeg-decoder at 1a040000 {
> >               };
> > 
> >               ovl0: ovl at 1c000000 {
> > -                     compatible = "mediatek,mt8188-disp-ovl",
> > "mediatek,mt8183-disp-ovl";
> > +                     compatible = "mediatek,mt8188-disp-ovl",
> > "mediatek,mt8195-disp-ovl";
> >                       reg = <0 0x1c000000 0 0x1000>;
> >                       clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
> >                       interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH
> > 0>;
> 
> 

From Jason-JH.Lin at mediatek.com  Thu Dec 12 10:24:25 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Thu, 12 Dec 2024 18:24:25 +0000
Subject: [PATCH 2/2] dts: arm64: mediatek: mt8188: Update OVL compatible
 from MT8183 to MT8195
In-Reply-To: <6710abd1-128d-48ff-84a1-880053fd9e84@collabora.com>
References: <20241212153344.27408-1-jason-jh.lin@mediatek.com>
	 <20241212153344.27408-3-jason-jh.lin@mediatek.com>
	 <6710abd1-128d-48ff-84a1-880053fd9e84@collabora.com>
Message-ID: <8c30716c526fd3748b6891df864eadd9c2194247.camel@mediatek.com>

On Thu, 2024-12-12 at 17:05 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> Il 12/12/24 16:33, Jason-JH.Lin ha scritto:
> > The OVL hardware capabilities have changed starting from MT8195,
> > making the MT8183 compatible no longer applicable.
> > Therefore, it is necessary to update the OVL compatible from MT8183
> > to
> > MT8195.
> > 
> > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> 
> Jason, just so you know - I have patches here adding DSC and merge
> components of
> VDO0, other than all MDP3 components.
> 
> Those are almost ready to send, I only need to finish some testing
> before ;-)
> 
> For this one, anyway:
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> 
> 
> > ---
> >   arch/arm64/boot/dts/mediatek/mt8188.dtsi | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> > b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> > index faccc7f16259..23ec3ff6cad9 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> > +++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> > @@ -2488,7 +2488,7 @@ jpeg_decoder: jpeg-decoder at 1a040000 {
> >               };
> > 
> >               ovl0: ovl at 1c000000 {
> > -                     compatible = "mediatek,mt8188-disp-ovl",
> > "mediatek,mt8183-disp-ovl";
> > +                     compatible = "mediatek,mt8188-disp-ovl",
> > "mediatek,mt8195-disp-ovl";
> >                       reg = <0 0x1c000000 0 0x1000>;
> >                       clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
> >                       interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH
> > 0>;
> 
> 

From konrad.dybcio at oss.qualcomm.com  Thu Dec 12 10:30:49 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 12 Dec 2024 19:30:49 +0100
Subject: [PATCH v6 2/5] clk: qcom: Add CMN PLL clock controller driver for
 IPQ SoC
In-Reply-To: <20241107-qcom_ipq_cmnpll-v6-2-a5cfe09de485@quicinc.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-2-a5cfe09de485@quicinc.com>
Message-ID: <7f0f2ad6-7895-46f8-8f80-0375dde2e763@oss.qualcomm.com>

On 7.11.2024 10:50 AM, Luo Jie wrote:
> The CMN PLL clock controller supplies clocks to the hardware
> blocks that together make up the Ethernet function on Qualcomm
> IPQ SoCs and to GCC. The driver is initially supported for
> IPQ9574 SoC.
> 
> The CMN PLL clock controller expects a reference input clock
> from the on-board Wi-Fi block acting as clock source. The input
> reference clock needs to be configured to one of the supported
> clock rates.
> 
> The controller supplies a number of fixed-rate output clocks.
> For the IPQ9574, there is one output clock of 353 MHZ to PPE
> (Packet Process Engine) hardware block, three 50 MHZ output
> clocks and an additional 25 MHZ output clock supplied to the
> connected Ethernet devices. The PLL also supplies a 24 MHZ
> clock as XO and a 32 KHZ sleep clock to GCC, and one 31.25
> MHZ clock to PCS.
> 
> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
> ---

[...]

> +	/* Enable PLL locked detect. */
> +	ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_CTRL,
> +				 CMN_PLL_CTRL_LOCK_DETECT_EN,
> +				 CMN_PLL_CTRL_LOCK_DETECT_EN);
> +	if (ret)

you can streamline these with regmap_set/clear_bits

> +		return ret;
> +
> +	/*
> +	 * Reset the CMN PLL block to ensure the updated configurations
> +	 * take effect.
> +	 */
> +	ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
> +				 CMN_ANA_EN_SW_RSTN, 0);
> +	if (ret)
> +		return ret;
> +
> +	usleep_range(1000, 1200);
> +	ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
> +				 CMN_ANA_EN_SW_RSTN, CMN_ANA_EN_SW_RSTN);
> +	if (ret)
> +		return ret;
> +
> +	/* Stability check of CMN PLL output clocks. */
> +	return regmap_read_poll_timeout(cmn_pll->regmap, CMN_PLL_LOCKED, val,
> +					(val & CMN_PLL_CLKS_LOCKED),
> +					100, 100 * USEC_PER_MSEC);
> +}

[...]

> +static int ipq_cmn_pll_clk_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +
> +	ret = devm_pm_runtime_enable(dev);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_pm_clk_create(dev);
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * To access the CMN PLL registers, the GCC AHB & SYSY clocks

SYS?

Konrad


From konrad.dybcio at oss.qualcomm.com  Thu Dec 12 10:32:23 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 12 Dec 2024 19:32:23 +0100
Subject: [PATCH v6 4/5] arm64: dts: qcom: Add CMN PLL node for IPQ9574 SoC
In-Reply-To: <20241107-qcom_ipq_cmnpll-v6-4-a5cfe09de485@quicinc.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-4-a5cfe09de485@quicinc.com>
Message-ID: <22491b41-f081-45cc-8766-6b4c851516f4@oss.qualcomm.com>

On 7.11.2024 10:50 AM, Luo Jie wrote:
> The CMN PLL clock controller allows selection of an input clock rate
> from a defined set of input clock rates. It in-turn supplies fixed
> rate output clocks to the hardware blocks that provide the ethernet
> functions such as PPE (Packet Process Engine) and connected switch or
> PHY, and to GCC.
> 
> The reference clock of CMN PLL is routed from XO to the CMN PLL through
> the internal WiFi block.
> .XO (48 MHZ or 96 MHZ)-->WiFi (multiplier/divider)-->48 MHZ to CMN PLL.
> 
> The reference input clock from WiFi to CMN PLL is fully controlled by
> the bootstrap pins which select the XO frequency (48 MHZ or 96 MHZ).
> Based on this frequency, the divider in the internal Wi-Fi block is
> automatically configured by hardware (1 for 48 MHZ, 2 for 96 MHZ), to
> ensure output clock to CMN PLL is 48 MHZ.
> 
> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
> ---
>  arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 16 ++++++++++++++-
>  arch/arm64/boot/dts/qcom/ipq9574.dtsi            | 26 +++++++++++++++++++++++-
>  2 files changed, 40 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
> index 91e104b0f865..78f6a2e053d5 100644
> --- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
> +++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
> @@ -3,7 +3,7 @@
>   * IPQ9574 RDP board common device tree source
>   *
>   * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
> - * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
>   */
>  
>  /dts-v1/;
> @@ -164,6 +164,20 @@ &usb3 {
>  	status = "okay";
>  };
>  
> +/*
> + * The bootstrap pins for the board select the XO clock frequency,
> + * which automatically enables the right dividers to ensure the
> + * reference clock output from WiFi is 48 MHZ.

I'm a bit puzzled by this comment. Does it mean this clock could
run at some different speeds?

[...]

>  
> +		cmn_pll: clock-controller at 9b000 {
> +			compatible = "qcom,ipq9574-cmn-pll";
> +			reg = <0x0009b000 0x800>;
> +			clocks = <&ref_48mhz_clk>,
> +				 <&gcc GCC_CMN_12GPLL_AHB_CLK>,
> +				 <&gcc GCC_CMN_12GPLL_SYS_CLK>;
> +			clock-names = "ref", "ahb", "sys";
> +			#clock-cells = <1>;
> +			assigned-clocks = <&cmn_pll CMN_PLL_CLK>;
> +			assigned-clock-rates-u64 = /bits/ 64 <12000000000>;

Does devlink not complain about self-referencing the clock here?

Konrad


From konrad.dybcio at oss.qualcomm.com  Thu Dec 12 10:33:14 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 12 Dec 2024 19:33:14 +0100
Subject: [PATCH v6 5/5] arm64: dts: qcom: Update IPQ9574 xo_board_clk to
 use fixed factor clock
In-Reply-To: <20241107-qcom_ipq_cmnpll-v6-5-a5cfe09de485@quicinc.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-5-a5cfe09de485@quicinc.com>
Message-ID: <0776a26e-56cd-4838-9b52-210ae9a1f281@oss.qualcomm.com>

On 7.11.2024 10:50 AM, Luo Jie wrote:
> xo_board_clk is fixed to 24 MHZ, which is routed from WiFi output clock
> 48 MHZ (also being the reference clock of CMN PLL) divided 2 by analog
> block routing channel.
> 
> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
> ---
>  arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 7 ++++++-
>  arch/arm64/boot/dts/qcom/ipq9574.dtsi            | 3 ++-
>  2 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
> index 78f6a2e053d5..9a8692377176 100644
> --- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
> +++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
> @@ -174,8 +174,13 @@ &ref_48mhz_clk {
>  	clock-mult = <1>;
>  };
>  
> +/*
> + * The frequency of xo_board_clk is fixed to 24 MHZ, which is routed
> + * from WiFi output clock 48 MHZ divided by 2.
> + */
>  &xo_board_clk {
> -	clock-frequency = <24000000>;
> +	clock-div = <2>;
> +	clock-mult = <1>;
>  };
>  
>  &xo_clk {
> diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
> index 8246a00a3e3e..25aed33e9358 100644
> --- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
> +++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
> @@ -32,7 +32,8 @@ sleep_clk: sleep-clk {
>  		};
>  
>  		xo_board_clk: xo-board-clk {
> -			compatible = "fixed-clock";
> +			compatible = "fixed-factor-clock";
> +			clocks = <&ref_48mhz_clk>;

This must be squashed with the previous patch, you can't introduce
code and replace it immediately afterwards.

Konrad


From dave.stevenson at raspberrypi.com  Thu Dec 12 10:36:27 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 18:36:27 +0000
Subject: [PATCH v3 0/7] drm/vc4: Fixup DT and DT binding issues from recent
 patchset
Message-ID: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>

I missed the DT errors from the recent patchset[1] (DT patches
in linux-next via Florian, DRM bindings patches on dri-misc-next)
as Rob's bot report got spam filtered, so this is a fixup set.

Largely it was changes to number of interrupts or clocks in the
bindings, so those are now covered.

I've fixed up the missing "interrupt-controller" flags for 2711
and 2712 whilst here.

I can't get my head around what is meant to happen with ranges:
"soc at 107c000000: firmware: 'ranges' is a required property"
The meaning seems obvious.

However if I add it then I get:
"firmware: '#address-cells', '#size-cells', 'dma-ranges', 'ranges' do
not match any of the regexes: 'pinctrl-[0-9]+'
from schema $id: http://devicetree.org/schemas/arm/bcm/raspberrypi,bcm2835-firmware.yaml#

There's obviously some other flag I need to set in the bindings,
but I can't work it out. We have similar errors for all the Pi
platforms for one or more nodes.
Please advise and I'll happily fix them all.

Thanks
  Dave

[1] https://lore.kernel.org/linux-arm-kernel/20241025-drm-vc4-2712-support-v2-0-35efa83c8fc0 at raspberrypi.com/

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
Changes in v3:
- Fixed up indentation on 1/7. (I fixed it once, but obviously reworked
  things and lost it).
- Link to v2: https://lore.kernel.org/r/20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4 at raspberrypi.com

Thanks to Stefan and Krzysztof for their reviews.
Hopefully I've addressed all points raised in the correct manner.

Changes in v2:
- Commits have now be merged from drm-misc-next to linux-next, so all
  commit hashes are valid on linux-next.
- 1/7 Removed references to "previous commit". Fixed up indentation.
  Added maxItems
- 2/7 Defined widest constraints
- 3/7 Added maxItems and removed reference to Linux
- 4/7 Described the errors. Split into two for fix of node name vs addr
  being wrong.
- Added new patch removing "required" for interrupt-controller and
  interrupt-cells for bcm2836-l1-intc
- 5/7 (now 7/7) Removed the intc node for 2712 - it's irrelevant on 64bit systems
- 6/7 dropped as updating the binding is the correct answer
- 7/7 dropped. simple-bus claims ranges is required, but adding it
  creates other errors. I'm unclear as to the right solution.

- Link to v1: https://lore.kernel.org/r/20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a at raspberrypi.com

---
Dave Stevenson (7):
      dt-bindings: display: bcm2711-hdmi: Add interrupt details for BCM2712
      dt-bindings: display: Fix BCM2835 HVS bindings for BCM2712
      dt-bindings: gpio: brcmstb: permit gpio-line-names property
      dt-bindings: interrupt-controller: brcm,bcm2836-l1-intc: Drop interrupt-controller requirement
      arm64: dts: broadcom: Rename bcm2712 interrupt controllers
      arm64: dts: broadcom: Correct hdmi device node names
      arm64: dts: broadcom: Remove intc controller on BCM2712.

 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 107 ++++++++++++++++++---
 .../bindings/display/brcm,bcm2835-hvs.yaml         |  83 +++++++++++++---
 .../bindings/gpio/brcm,brcmstb-gpio.yaml           |   4 +
 .../interrupt-controller/brcm,bcm2836-l1-intc.yaml |   2 -
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi          |  13 +--
 5 files changed, 170 insertions(+), 39 deletions(-)
---
base-commit: 3a6b7ba51f16c093420959ab2bd3476d180547fa
change-id: 20241128-dt-bcm2712-fixes-afb0e8a0a476

Best regards,
-- 
Dave Stevenson <dave.stevenson at raspberrypi.com>



From dave.stevenson at raspberrypi.com  Thu Dec 12 10:36:28 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 18:36:28 +0000
Subject: [PATCH v3 1/7] dt-bindings: display: bcm2711-hdmi: Add interrupt
 details for BCM2712
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v3-1-44a7f3390331@raspberrypi.com>

Commit 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
added the compatible strings for BCM2712, but missed out that the
number of interrupts changed.

Update the schema to include the interrupt requirements.

Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 107 ++++++++++++++++++---
 1 file changed, 93 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
index 6d11f5955b51..dd7dea60183b 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
@@ -56,22 +56,38 @@ properties:
       - const: cec
 
   interrupts:
-    items:
-      - description: CEC TX interrupt
-      - description: CEC RX interrupt
-      - description: CEC stuck at low interrupt
-      - description: Wake-up interrupt
-      - description: Hotplug connected interrupt
-      - description: Hotplug removed interrupt
+    oneOf:
+      - items:
+          - description: CEC TX interrupt
+          - description: CEC RX interrupt
+          - description: CEC stuck at low interrupt
+          - description: Wake-up interrupt
+          - description: Hotplug connected interrupt
+          - description: Hotplug removed interrupt
+
+      - items:
+          - description: CEC TX interrupt
+          - description: CEC RX interrupt
+          - description: CEC stuck at low interrupt
+          - description: Hotplug connected interrupt
+          - description: Hotplug removed interrupt
 
   interrupt-names:
-    items:
-      - const: cec-tx
-      - const: cec-rx
-      - const: cec-low
-      - const: wakeup
-      - const: hpd-connected
-      - const: hpd-removed
+    oneOf:
+      - items:
+          - const: cec-tx
+          - const: cec-rx
+          - const: cec-low
+          - const: wakeup
+          - const: hpd-connected
+          - const: hpd-removed
+
+      - items:
+          - const: cec-tx
+          - const: cec-rx
+          - const: cec-low
+          - const: hpd-connected
+          - const: hpd-removed
 
   ddc:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -112,6 +128,66 @@ required:
 
 additionalProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - brcm,bcm2711-hdmi0
+              - brcm,bcm2711-hdmi1
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: CEC TX interrupt
+            - description: CEC RX interrupt
+            - description: CEC stuck at low interrupt
+            - description: Wake-up interrupt
+            - description: Hotplug connected interrupt
+            - description: Hotplug removed interrupt
+        interrupt-names:
+          items:
+            - const: cec-tx
+            - const: cec-rx
+            - const: cec-low
+            - const: wakeup
+            - const: hpd-connected
+            - const: hpd-removed
+
+
+      required:
+        - interrupts
+        - interrupt-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - brcm,bcm2712-hdmi0
+              - brcm,bcm2712-hdmi1
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: CEC TX interrupt
+            - description: CEC RX interrupt
+            - description: CEC stuck at low interrupt
+            - description: Hotplug connected interrupt
+            - description: Hotplug removed interrupt
+        interrupts-names:
+          items:
+            - const: cec-tx
+            - const: cec-rx
+            - const: cec-low
+            - const: hpd-connected
+            - const: hpd-removed
+
+      required:
+        - interrupts
+        - interrupt-names
+
 examples:
   - |
     hdmi0: hdmi at 7ef00700 {
@@ -136,6 +212,9 @@ examples:
                     "hd";
         clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
         clock-names = "hdmi", "bvb", "audio", "cec";
+        interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
+        interrupt-names = "cec-tx", "cec-rx", "cec-low", "wakeup",
+                "hpd-connected", "hpd-removed";
         resets = <&dvp 0>;
         ddc = <&ddc0>;
     };

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Thu Dec 12 10:36:29 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 18:36:29 +0000
Subject: [PATCH v3 2/7] dt-bindings: display: Fix BCM2835 HVS bindings for
 BCM2712
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v3-2-44a7f3390331@raspberrypi.com>

Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
added the compatible string for BCM2712, but missed out that
the number of interrupts and clocks changed too.

Update to validate clock and interrupts for the variants.

Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2835-hvs.yaml         | 83 ++++++++++++++++++----
 1 file changed, 69 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
index f91c9dce2a44..36bf8eec88a6 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
@@ -20,11 +20,20 @@ properties:
     maxItems: 1
 
   interrupts:
-    maxItems: 1
+    minItems: 1
+    maxItems: 3
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 3
 
   clocks:
-    maxItems: 1
-    description: Core Clock
+    minItems: 1
+    maxItems: 2
+
+  clock-names:
+    minItems: 1
+    maxItems: 2
 
 required:
   - compatible
@@ -33,17 +42,63 @@ required:
 
 additionalProperties: false
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - brcm,bcm2711-hvs
-          - brcm,bcm2712-hvs
-
-then:
-  required:
-    - clocks
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2711-hvs
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Core Clock
+        interrupts:
+          maxItems: 1
+
+      required:
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2712-hvs
+
+    then:
+      properties:
+        clocks:
+          maxItems: 2
+        clock-names:
+          items:
+            - const: core
+            - const: disp
+        interrupts:
+          items:
+            - description: Channel 0 End of frame
+            - description: Channel 1 End of frame
+            - description: Channel 2 End of frame
+        interrupt-names:
+          items:
+            - const: ch0-eof
+            - const: ch1-eof
+            - const: ch2-eof
+      required:
+        - clocks
+        - clock-names
+        - interrupt-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2835-hvs
+
+    then:
+      properties:
+        interrupts:
+          maxItems: 1
 
 examples:
   - |

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Thu Dec 12 10:36:30 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 12 Dec 2024 18:36:30 +0000
Subject: [PATCH v3 3/7] dt-bindings: gpio: brcmstb: permit gpio-line-names
 property
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
Message-ID: <20241212-dt-bcm2712-fixes-v3-3-44a7f3390331@raspberrypi.com>

gpio-line-names is a generic property that can be supported by any
GPIO controller, so permit it through the binding.

It is permitted to have a variable number of GPIOs per node based
on brcm,gpio-bank-widths, so define an arbitrary maximum number of
items based on current users.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
index f096f286da19..fbd69b4cecc7 100644
--- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
@@ -64,6 +64,10 @@ properties:
 
   gpio-ranges: true
 
+  gpio-line-names:
+    minItems: 1
+    maxItems: 128
+
   wakeup-source:
     type: boolean
     description: >

-- 
2.34.1



From acme at kernel.org  Thu Dec 12 10:53:03 2024
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Thu, 12 Dec 2024 15:53:03 -0300
Subject: [PATCH] perf vendor events arm64: Update N2/V2 events from source
In-Reply-To: <CAP-5=fWeJYf4mbSKSonwNhc5smw6_OktRBG2bCObcQiDjy2iAQ@mail.gmail.com>
References: <20241120143739.243728-1-james.clark@linaro.org>
 <CAP-5=fWeJYf4mbSKSonwNhc5smw6_OktRBG2bCObcQiDjy2iAQ@mail.gmail.com>
Message-ID: <Z1sxD-lvXnFKVy3q@x1>

On Wed, Nov 20, 2024 at 10:31:55AM -0800, Ian Rogers wrote:
> On Wed, Nov 20, 2024 at 6:38?AM James Clark <james.clark at linaro.org> wrote:
> >
> > Update using the new data [1] for these changes:
> >
> >   * Scale some metrics like dtlb_walk_ratio to percent so they display
> >     better with Perf's 2 dp precision
> >   * Description typos, grammar and clarifications
> >   * Unnecessary metric formula brackets seem to have been removed in the
> >     source but this is not a functional change
> >   * New sve_all_percentage metric
> >
> > The following command was used to generate this commit:
> >
> > $ telemetry-solution/tools/perf_json_generator/generate.py \
> >   tools/perf/ --telemetry-files \
> >   telemetry-solution/data/pmu/cpu/neoverse/neoverse-v2.json:neoverse-n2-v2
> >
> > [1]: https://gitlab.arm.com/telemetry-solution/telemetry-solution/-/blob/main/data/pmu/cpu/neoverse/neoverse-v2.json
> >
> > Signed-off-by: James Clark <james.clark at linaro.org>
> 
> Reviewed-by: Ian Rogers <irogers at google.com>

Thanks, applied to perf-tools-next,

- Arnaldo


From sebastian.reichel at collabora.com  Thu Dec 12 11:20:33 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Thu, 12 Dec 2024 20:20:33 +0100
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add USB-C support to ROCK 5B
In-Reply-To: <3D830E407DCD15A2+de00ea1d-96d5-4766-9dc5-616fc76f404b@radxa.com>
References: <20241210163615.120594-1-sebastian.reichel@collabora.com>
 <FFD6E87BED20DB1B+38b8064e-9945-4cd8-a30e-7800a8c6f37b@radxa.com>
 <3D830E407DCD15A2+de00ea1d-96d5-4766-9dc5-616fc76f404b@radxa.com>
Message-ID: <iloxbrj7ktqto5yphr7i3tioq3cbecqwu4ovxmezovux3nw7t3@j2siyintvy7j>

Hi Naoki,

On Wed, Dec 11, 2024 at 09:40:13AM +0900, FUKAUMI Naoki wrote:
> I got random reboot during booting kernel/userland...

That is probably related to USB-C PD communication resulting in
another hard reset :( Can you try to get some tcpm_log() data
from debugfs while the board is powered from the GPIO header or
PoE?

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/20241212/e65c12ea/attachment.sig>

From broonie at kernel.org  Thu Dec 12 11:36:32 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 12 Dec 2024 19:36:32 +0000
Subject: [PATCH] arm64: defconfig: Enable Amazon Elastic Network Adaptor
Message-ID: <20241212-arm64-defconfig-graviton-v1-1-86830c3d572b@kernel.org>

The Graviton SoCs available in AWS use a custom network adaptor, enable
support for this in defconfig so standard defconfig builds can be used more
readily in CI. The driver is left as a module since it is relatively
unlikely these will be netbooted.

Signed-off-by: Mark Brown <broonie 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 c62831e6158633f07c1f3532fba62f09b31e7448..b48940b3d100dd03945a29735b8ba26b145d51ad 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -330,6 +330,7 @@ CONFIG_VIRTIO_NET=y
 CONFIG_MHI_NET=m
 CONFIG_NET_DSA_BCM_SF2=m
 CONFIG_NET_DSA_MSCC_FELIX=m
+CONFIG_ENA_ETHERNET=m
 CONFIG_AMD_XGBE=y
 CONFIG_NET_XGENE=y
 CONFIG_ATL1C=m

---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241212-arm64-defconfig-graviton-0eda53e5d19d

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From scclevenger at os.amperecomputing.com  Thu Dec 12 11:38:06 2024
From: scclevenger at os.amperecomputing.com (Steve Clevenger)
Date: Thu, 12 Dec 2024 11:38:06 -0800
Subject: [PATCH] coresight: docs: Remove target sink from examples
In-Reply-To: <24299600-277f-48f4-9be5-cbd65ab6ddb7@linaro.org>
References: <20241210144933.295798-1-james.clark@linaro.org>
 <9e53f5b9-d8a9-46b8-8ff1-7f018e2d9c06@os.amperecomputing.com>
 <24299600-277f-48f4-9be5-cbd65ab6ddb7@linaro.org>
Message-ID: <75ce4def-b0ca-428f-99a5-19ca98e876a0@os.amperecomputing.com>



On 12/12/2024 7:27 AM, James Clark wrote:
> 
> 
> On 11/12/2024 6:01 pm, Steve Clevenger wrote:
>>
>> Hi James,
>>
>> I thought I'd mention this issue with multicore self-hosted trace. The
>> perf command line syntax does not allow a sink "type" to be specified
>> (e.g. @tmc_etf or @tmc_etr). For multicore, it doesn't make sense to
>> specify a processor mapped sink as would be the case for single core
>> trace. A sink "type" should be allowed to avoid the auto select default.
>> In our case, the default is the ETF sink.
>>
>> Thanks,
>> Steve C.
>>
> 
> I'm sure it would be possible to add support for this, but I'm wondering
> if the real issue is that the default selection logic is wrong? Are you
> saying the default you get is ETF but you want ETR? And there is both
> for each ETM? The default selection logic isn't easy to summarize but it
> should prefer ETR (sysmem) over ETF (link sink), see coresight_find_sink().
> 
> It's probably better to fix that rather than add a new sink selection
> feature. Maybe if you shared a diagram of your coresight architecture it
> would help.
> 
> Thanks
> James

Hi James,

It appears the default sink selection is ETF for multicore trace. In any
case, for the Arm? CoreSight Base System Architecture STC Level
compliance, I need to be able to specify the sink type.

The Ampere CoreSight hierarchy is described to the ACPI as follows:


+-----------------+
|                 |
|       ETM       |
|                 |
+--------+--------+
         |
         |
+--------+--------+
|                 |
|       ETF       |
|                 |
+--------+--------+
         |
         |
+--------+--------+
|                 |
|       ETR       |
|                 |
+--------+--------+
         |
         |
+--------+--------+
|                 |
|      CATU       |
|                 |
+--------+--------+

Steve C.



From jgg at ziepe.ca  Thu Dec 12 11:41:19 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Thu, 12 Dec 2024 15:41:19 -0400
Subject: [RFC PATCH v2 00/58] KVM: Arm SMMUv3 driver for pKVM
In-Reply-To: <20241212180423.1578358-1-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
Message-ID: <20241212194119.GA4679@ziepe.ca>

On Thu, Dec 12, 2024 at 06:03:24PM +0000, Mostafa Saleh wrote:

> This series adds a hypervisor driver for the Arm SMMUv3 IOMMU. Since the
> hypervisor part of pKVM (called nVHE here) is minimal, moving the whole
> host SMMU driver into nVHE isn't really an option. It is too large and
> complex and requires infrastructure from all over the kernel. We add a
> reduced nVHE driver that deals with populating the SMMU tables and the
> command queue, and the host driver still deals with probing and some
> initialization.

The cover letter doesn't explain why someone needs page tables in the
guest at all?

If you are able to implement nested support then you can boot the
guest with no-iommu and an effective identity translation through a
hypervisor controlled S2. ie no guest map/unmap. Great DMA
performance.

I thought the point of doing the paravirt here was to allow dynamic
pinning of the guest memory? This is the primary downside with nested.
The entire guest memory has to be pinned down at guest boot.

> 1. Paravirtual I/O page tables
> This is the solution implemented in this series. The host creates
> IOVA->HPA mappings with two hypercalls map_pages() and unmap_pages(), and
> the hypervisor populates the page tables. Page tables are abstracted into
> IOMMU domains, which allow multiple devices to share the same address
> space. Another four hypercalls, alloc_domain(), attach_dev(), detach_dev()
> and free_domain(), manage the domains, the semantics of those hypercalls
> are almost identical to the IOMMU ops which make the kernel driver part
> simpler.

That is re-inventing virtio-iommu. I don't really understand why this
series is hacking up arm-smmuv3 so much, that is not, and should not,
be a paravirt driver. Why not create a clean new pkvm specific driver
for the paravirt?? Or find a way to re-use parts of virtio-iommu?

Shouldn't other arch versions of pkvm be able to re-use the same guest
iommu driver?

> b- Locking: The io-pgtable-arm is lockless under some guarantees of how
>    the IOMMU code behaves. However with pKVM, the kernel is not trusted
>    and a malicious kernel can issue concurrent requests causing memory
>    corruption or UAF, so that it has to be locked in the hypervisor.

? I don't get it, the hypervisor page table has to be private to the
hypervisor. It is not that io-pgtable-arm is lockless, it is that it
relies on a particular kind of caller supplied locking. pkvm's calls
into its private io-pgtable-arm would need pkvm specific locking that
makes sense for it. Where does a malicious guest kernel get into this?

> 2. Nested SMMUv3 translation (with emulation)
> Another approach is to rely on nested translation support which is
> optional in SMMUv3, that requires an architecturally accurate emulation
> of SMMUv3 which can be complicated including cmdq emulation.

The confidential compute folks are going in this direction.

> The trade off between the 2 approaches can be roughly summarised as:
> Paravirtualization:
> - Compatible with more HW (and IOMMUs).
> - Better DMA performance due to shorter table walks/less TLB pressure
> - Needs extra complexity to squeeze the last bit of optimization (around
>   unmap, and map_sg).

It has better straight line DMA performance if the DMAs are all
static. Generally much, much worse performance if the DMAs are
dynamically mapped as you have to trap so much stuff.

The other negative is there is no way to get SVA support with
para-virtualization.

The positive is you don't have to pin the VM's memory.

> Nested Emulation
> - Faster map_pages (not sure about unmap because it requires cmdq
>   emulation for TLB invalidation if DVM not used).

If you can do nested then you can run in identity mode and then you
don't have any performance down side. It is a complete win.

Even if you do non-idenity nested is still likely faster for changing
translation than paravirt approaches. A single cmdq range invalidate
should be about the same broad overhead as a single paravirt call to
unmap except they can be batched under load.

Things like vCMDQ eliminate this overhead entirely, to my mind that is
the future direction of this HW as you obviously need to HW optimize
invalidation...

> - Needs extra complexity for architecturally emulating SMMUv3.

Lots of people have now done this, it is not really so bad. In
exchange you get a full architected feature set, better performance,
and are ready for HW optimizations.

> - Add IDENTITY_DOMAIN support, I already have some patches for that, but
>   didn?t want to complicate this series, I can send them separately.

This seems kind of pointless to me. If you can tolerate identity (ie
pin all memory) then do nested, and maybe don't even bother with a
guest iommu.

If you want most of the guest memory to be swappable/movable/whatever
then paravirt is the only choice, and you really don't want the guest
to have any identiy support at all.

Really, I think you'd want to have both options, there is no "best"
here. It depends what people want to use the VM for.

My advice for merging would be to start with the pkvm side setting up
a fully pinned S2 and do not have a guest driver. Nesting without
emulating smmuv3. Basically you get protected identity DMA support. I
think that would be a much less sprawling patch series. From there it
would be well positioned to add both smmuv3 emulation and a paravirt
iommu flow.

Jason


From jgg at ziepe.ca  Thu Dec 12 11:44:35 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Thu, 12 Dec 2024 15:44:35 -0400
Subject: [RFC PATCH v2 40/58] KVM: arm64: smmu-v3: Add map/unmap pages
 and iova_to_phys
In-Reply-To: <20241212180423.1578358-41-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-41-smostafa@google.com>
Message-ID: <20241212194435.GA5484@ziepe.ca>

On Thu, Dec 12, 2024 at 06:04:04PM +0000, Mostafa Saleh wrote:
> Add map_pages and iova_to_phys HVC code, which
> mainly calls the io-pgtable.
> 
> For unmap_pages, we rely on IO_PGTABLE_QUIRK_UNMAP_INVAL, where the
> driver first calls unmap_pages which invalidate all the pages as
> a typical unmap, issuing all the necessary TLB invalidations.
> Then, we will start a page table with 2 callbacks:
> - visit_leaf: for each unmapped leaf, it would decrement the refcount
>   of the page using __pkvm_host_unuse_dma(), reversing the what IOMMU
>   core does in map.
> - visit_post_table: this would free any invalidated tables as they
>   wouldn't be freed because of the quirk.

I don't know if the timelines will work out, but the pagetable stuff
I'm working on will let you write a much more appropriate
implementation for pkvm's usage than trying to hack it into the
iopgtable code like this.

Even the iommu focused routines I have got now would solve this
problem because they allways spit out a linked list of all the memory
to free after map/unmap and never internally free it..

Jason


From tglx at linutronix.de  Thu Dec 12 11:51:13 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Thu, 12 Dec 2024 20:51:13 +0100
Subject: [PATCH 1/4] irqchip/riscv-imsic: Handle non-atomic MSI updates
 for device
In-Reply-To: <CAK9=C2XEhtB00y6WTMaO0X=7K820T_BSCLA5bw6hJbfvQAD+Pw@mail.gmail.com>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
 <20241208150711.297624-2-apatel@ventanamicro.com> <875xnuq6dc.ffs@tglx>
 <CAK9=C2VqU2mdLL-R20bdgvDHi0WcuNyUSqRo7Pztsu-8X1wVvw@mail.gmail.com>
 <87r06gq2di.ffs@tglx>
 <CAK9=C2XEhtB00y6WTMaO0X=7K820T_BSCLA5bw6hJbfvQAD+Pw@mail.gmail.com>
Message-ID: <877c84ade6.ffs@tglx>

On Thu, Dec 12 2024 at 22:11, Anup Patel wrote:
>> --- a/kernel/irq/chip.c
>> +++ b/kernel/irq/chip.c
>> @@ -47,6 +47,13 @@ int irq_set_chip(unsigned int irq, const
>>                 return -EINVAL;
>>
>>         desc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
>> +
>> +       if (IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS) && chip) {
>> +               if (chip->flags & IRQCHIP_MOVE_DEFERRED)
>> +                       irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
>> +               else
>> +                       irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
>> +       }
>
> We need similar changes in irq_domain_set_hwirq_and_chip()
> because we use IRQ_DOMAIN_HIERARCHY in RISC-V.

Grr, you are right. Let me add that to the base patch.

>>         irq_put_desc_unlock(desc, flags);
>>         /*
>>          * For !CONFIG_SPARSE_IRQ make the irq show up in
>> @@ -1114,16 +1121,21 @@ void irq_modify_status(unsigned int irq,
>>         trigger = irqd_get_trigger_type(&desc->irq_data);
>>
>>         irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
>> -                  IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT);
>> +                  IRQD_TRIGGER_MASK | IRQD_LEVEL);
>>         if (irq_settings_has_no_balance_set(desc))
>>                 irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
>>         if (irq_settings_is_per_cpu(desc))
>>                 irqd_set(&desc->irq_data, IRQD_PER_CPU);
>> -       if (irq_settings_can_move_pcntxt(desc))
>> -               irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
>>         if (irq_settings_is_level(desc))
>>                 irqd_set(&desc->irq_data, IRQD_LEVEL);
>>
>> +       /* Keep this around until x86 is converted over */
>> +       if (!IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS)) {
>> +               irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
>> +               if (irq_settings_can_move_pcntxt(desc))
>> +                       irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
>> +       }
>> +
>
> These changes in irq_modify_status() need to be dropped to support
> the above changes in irq_domain_set_hwirq_and_chip().

Why? With CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS enabled this hunk is
compiled out. So nothing is modifying PCNTXT here. That's the whole
point.

Thanks,

        tglx




From cristian.ciocaltea at collabora.com  Thu Dec 12 12:03:38 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 12 Dec 2024 22:03:38 +0200
Subject: [PATCH v2 7/8] phy: rockchip: samsung-hdptx: Cleanup internal rate
 handling
In-Reply-To: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
References: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
Message-ID: <20241212-phy-sam-hdptx-bpc-v2-7-57e672c7c7c4@collabora.com>

Drop the rate parameter from a bunch of internal helpers and, instead,
make better use of the newly introduced ->tmds_char_rate driver data.

No functional changes intended.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 27 ++++++++++++-----------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index d90d89cfdff561e13ac3db3f143a4eef9cc85a03..bc513ddd5c052763856a113a7f1e58660f7372b8 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -796,14 +796,13 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
 	return rk_hdptx_post_enable_pll(hdptx);
 }
 
-static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
-					   unsigned int rate)
+static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx)
 {
 	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
 
-	if (rate > HDMI14_MAX_RATE / 100) {
+	if (hdptx->tmds_char_rate > HDMI14_MAX_RATE) {
 		/* For 1/40 bitrate clk */
 		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq);
 	} else {
@@ -820,9 +819,9 @@ static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
 	return rk_hdptx_post_enable_lane(hdptx);
 }
 
-static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx,
-				     unsigned int rate)
+static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
 {
+	unsigned long rate;
 	u32 status;
 	int ret;
 
@@ -836,8 +835,9 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx,
 	if (status & HDPTX_O_PLL_LOCK_DONE)
 		dev_warn(hdptx->dev, "PLL locked by unknown consumer!\n");
 
+	rate = hdptx->tmds_char_rate ?: hdptx->rate;
 	if (rate) {
-		ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate);
+		ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100);
 		if (ret)
 			goto dec_usage;
 	}
@@ -879,26 +879,27 @@ static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)
 static int rk_hdptx_phy_power_on(struct phy *phy)
 {
 	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
-	unsigned int rate = hdptx->tmds_char_rate / 100;
 	int ret;
 
-	if (rate == 0) {
+	if (!hdptx->tmds_char_rate) {
 		/*
 		 * FIXME: Temporary workaround to setup TMDS char rate
 		 * from the RK HDMI bridge driver.
 		 * Will be removed as soon the switch to the HDMI PHY
 		 * configuration API has been completed on both ends.
 		 */
-		rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
+		hdptx->tmds_char_rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
+		hdptx->tmds_char_rate *= 100;
 	}
 
-	dev_dbg(hdptx->dev, "%s rate=%u bpc=%u\n", __func__, rate, hdptx->bpc);
+	dev_dbg(hdptx->dev, "%s tmds_rate=%lu bpc=%u\n", __func__,
+		hdptx->tmds_char_rate, hdptx->bpc);
 
-	ret = rk_hdptx_phy_consumer_get(hdptx, rate);
+	ret = rk_hdptx_phy_consumer_get(hdptx);
 	if (ret)
 		return ret;
 
-	ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
+	ret = rk_hdptx_ropll_tmds_mode_config(hdptx);
 	if (ret)
 		rk_hdptx_phy_consumer_put(hdptx, true);
 
@@ -950,7 +951,7 @@ static int rk_hdptx_phy_clk_prepare(struct clk_hw *hw)
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
 
-	return rk_hdptx_phy_consumer_get(hdptx, hdptx->rate / 100);
+	return rk_hdptx_phy_consumer_get(hdptx);
 }
 
 static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Thu Dec 12 12:03:39 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 12 Dec 2024 22:03:39 +0200
Subject: [PATCH v2 8/8] phy: rockchip: samsung-hdptx: Avoid Hz-hHz unit
 conversion overhead
In-Reply-To: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
References: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
Message-ID: <20241212-phy-sam-hdptx-bpc-v2-8-57e672c7c7c4@collabora.com>

The ropll_tmds_cfg table used to identify the configuration params for
the supported rates expects the search keys - bit_rate field - to be
provided in hHz rather than Hz (1 hHz = 100 Hz).  This requires multiple
conversions between these units being performed at runtime.

Improve implementation clarity and efficiency by consistently using the
Hz units throughout driver's internal data structures and functions.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 61 +++++++++++------------
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index bc513ddd5c052763856a113a7f1e58660f7372b8..b6120d9ab24eca093180b3af942d7ce2b204d516 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -196,7 +196,7 @@
 #define HDMI20_MAX_RATE			600000000
 
 struct ropll_config {
-	u32 bit_rate;
+	u32 rate;
 	u8 pms_mdiv;
 	u8 pms_mdiv_afc;
 	u8 pms_pdiv;
@@ -256,45 +256,45 @@ struct rk_hdptx_phy {
 };
 
 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,
+	{ 594000000, 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,
+	{ 371250000, 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,
+	{ 297000000, 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,
+	{ 162000000, 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,
+	{ 185625000, 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,
+	{ 154000000, 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,
+	{ 148500000, 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,
+	{ 146250000, 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,
+	{ 119000000, 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,
+	{ 106500000, 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,
+	{ 108000000, 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,
+	{ 85500000, 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,
+	{ 83500000, 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,
+	{ 92812500, 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,
+	{ 74250000, 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,
+	{ 65000000, 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,
+	{ 33750000, 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,
+	{ 40000000, 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,
+	{ 27000000, 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,
+	{ 25175000, 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, },
 };
 
@@ -656,10 +656,10 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
 	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
 }
 
-static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate,
+static bool rk_hdptx_phy_clk_pll_calc(unsigned long rate,
 				      struct ropll_config *cfg)
 {
-	const unsigned int fout = data_rate / 2, fref = 24000;
+	const unsigned int fout = rate / 200, fref = 24000;
 	unsigned long k = 0, lc, k_sub, lc_sub;
 	unsigned int fvco, sdc;
 	u32 mdiv, sdiv, n = 8;
@@ -729,16 +729,16 @@ static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate,
 }
 
 static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
-					  unsigned int rate)
+					  unsigned long rate)
 {
 	const struct ropll_config *cfg = NULL;
 	struct ropll_config rc = {0};
 	int i;
 
-	hdptx->rate = rate * 100;
+	hdptx->rate = rate;
 
 	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
-		if (rate == ropll_tmds_cfg[i].bit_rate) {
+		if (rate == ropll_tmds_cfg[i].rate) {
 			cfg = &ropll_tmds_cfg[i];
 			break;
 		}
@@ -837,7 +837,7 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
 
 	rate = hdptx->tmds_char_rate ?: hdptx->rate;
 	if (rate) {
-		ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100);
+		ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate);
 		if (ret)
 			goto dec_usage;
 	}
@@ -972,18 +972,17 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
 static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 					unsigned long *parent_rate)
 {
-	u32 bit_rate = rate / 100;
 	int i;
 
 	if (rate > HDMI20_MAX_RATE)
 		return rate;
 
 	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
-		if (bit_rate == ropll_tmds_cfg[i].bit_rate)
+		if (rate == ropll_tmds_cfg[i].rate)
 			break;
 
 	if (i == ARRAY_SIZE(ropll_tmds_cfg) &&
-	    !rk_hdptx_phy_clk_pll_calc(bit_rate, NULL))
+	    !rk_hdptx_phy_clk_pll_calc(rate, NULL))
 		return -EINVAL;
 
 	return rate;
@@ -1004,7 +1003,7 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 		rate = hdptx->tmds_char_rate;
 	}
 
-	return rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100);
+	return rk_hdptx_ropll_tmds_cmn_config(hdptx, rate);
 }
 
 static const struct clk_ops hdptx_phy_clk_ops = {

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Thu Dec 12 12:03:32 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 12 Dec 2024 22:03:32 +0200
Subject: [PATCH v2 1/8] phy: Add HDMI configuration options
In-Reply-To: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
References: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
Message-ID: <20241212-phy-sam-hdptx-bpc-v2-1-57e672c7c7c4@collabora.com>

From: Sandor Yu <Sandor.yu at 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>
Reviewed-by: Maxime Ripard <mripard at kernel.org>
Link: https://lore.kernel.org/r/43757beec6cd418fc17252283de38009d531c7c7.1732627815.git.Sandor.yu at nxp.com
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 include/linux/phy/phy-hdmi.h | 19 +++++++++++++++++++
 include/linux/phy/phy.h      |  7 ++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a696922bc7f29af63d88646701b2c0fcee5c885
--- /dev/null
+++ b/include/linux/phy/phy-hdmi.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022,2024 NXP
+ */
+
+#ifndef __PHY_HDMI_H_
+#define __PHY_HDMI_H_
+
+/**
+ * struct phy_configure_opts_hdmi - HDMI configuration set
+ * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
+ *
+ * This structure is used to represent the configuration state of a HDMI phy.
+ */
+struct phy_configure_opts_hdmi {
+	unsigned long long tmds_char_rate;
+};
+
+#endif /* __PHY_HDMI_H_ */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 03cd5bae92d3f189d739c453fe4c160dd2a5063e..4ac486b101fe4023b8f2a84e907e65a0ff0a5ede 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.47.0



From cristian.ciocaltea at collabora.com  Thu Dec 12 12:03:31 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 12 Dec 2024 22:03:31 +0200
Subject: [PATCH v2 0/8] phy: rockchip: samsung-hdptx: Support high color
 depth management
Message-ID: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>

This series relies on the new HDMI PHY configuration options [1] (patch
included here for convenience) to provide high color depth management
for rockchip-samsung-hdptx, and to introduce a proper solution to setup
the TMDS character rate on this PHY.

[1] https://lore.kernel.org/all/43757beec6cd418fc17252283de38009d531c7c7.1732627815.git.Sandor.yu at nxp.com/

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
Changes in v2:
- Added new patches providing a bug fix and several driver cleanups and
  improvements
- Link to v1: https://lore.kernel.org/r/20241207-phy-sam-hdptx-bpc-v1-0-03c2e4d6d797 at collabora.com

---
Cristian Ciocaltea (7):
      phy: hdmi: Add color depth configuration
      phy: rockchip: samsung-hdptx: Fix clock ratio setup
      phy: rockchip: samsung-hdptx: Drop unused lcpll_config
      phy: rockchip: samsung-hdptx: Setup TMDS char rate via phy_configure_opts_hdmi
      phy: rockchip: samsung-hdptx: Add high color depth management
      phy: rockchip: samsung-hdptx: Cleanup internal rate handling
      phy: rockchip: samsung-hdptx: Avoid Hz-hHz unit conversion overhead

Sandor Yu (1):
      phy: Add HDMI configuration options

 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 169 ++++++++++++----------
 include/linux/phy/phy-hdmi.h                      |  21 +++
 include/linux/phy/phy.h                           |   7 +-
 3 files changed, 118 insertions(+), 79 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241206-phy-sam-hdptx-bpc-3b05c6276fd7



From cristian.ciocaltea at collabora.com  Thu Dec 12 12:03:34 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 12 Dec 2024 22:03:34 +0200
Subject: [PATCH v2 3/8] phy: rockchip: samsung-hdptx: Fix clock ratio setup
In-Reply-To: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
References: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
Message-ID: <20241212-phy-sam-hdptx-bpc-v2-3-57e672c7c7c4@collabora.com>

The switch from 1/10 to 1/40 clock ratio must happen when exceeding the
340 MHz rate limit of HDMI 1.4, i.e. when entering the HDMI 2.0 domain,
and not before.

While at it, introduce a define for this rate limit constant.

Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver")
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index ceab9c71d3b53ae0b746a10c081fcfaa7d5c5ae7..089020df5b4b8f9b44d272fa87a66e0f2c8ccaba 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -192,6 +192,7 @@
 #define LN3_TX_SER_RATE_SEL_HBR2	BIT(3)
 #define LN3_TX_SER_RATE_SEL_HBR3	BIT(2)
 
+#define HDMI14_MAX_RATE			340000000
 #define HDMI20_MAX_RATE			600000000
 
 struct lcpll_config {
@@ -826,7 +827,7 @@ static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
 
-	if (rate >= 3400000) {
+	if (rate > HDMI14_MAX_RATE / 100) {
 		/* For 1/40 bitrate clk */
 		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq);
 	} else {

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Thu Dec 12 12:03:33 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 12 Dec 2024 22:03:33 +0200
Subject: [PATCH v2 2/8] phy: hdmi: Add color depth configuration
In-Reply-To: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
References: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
Message-ID: <20241212-phy-sam-hdptx-bpc-v2-2-57e672c7c7c4@collabora.com>

Extend the HDMI configuration options to allow managing bits per color
channel.  This is required by some PHY drivers such as
rockchip-samsung-hdptx.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 include/linux/phy/phy-hdmi.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
index 6a696922bc7f29af63d88646701b2c0fcee5c885..f0ec963c6e84f1b7728acafc824dff191c6b873d 100644
--- a/include/linux/phy/phy-hdmi.h
+++ b/include/linux/phy/phy-hdmi.h
@@ -9,11 +9,13 @@
 /**
  * struct phy_configure_opts_hdmi - HDMI configuration set
  * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
+ * @bpc: Bits per color channel.
  *
  * This structure is used to represent the configuration state of a HDMI phy.
  */
 struct phy_configure_opts_hdmi {
 	unsigned long long tmds_char_rate;
+	unsigned int bpc;
 };
 
 #endif /* __PHY_HDMI_H_ */

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Thu Dec 12 12:03:35 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 12 Dec 2024 22:03:35 +0200
Subject: [PATCH v2 4/8] phy: rockchip: samsung-hdptx: Drop unused
 lcpll_config
In-Reply-To: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
References: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
Message-ID: <20241212-phy-sam-hdptx-bpc-v2-4-57e672c7c7c4@collabora.com>

This is just a leftover from downstream support for HDMI 2.1.
Remove the unused struct for now.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 31 -----------------------
 1 file changed, 31 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 089020df5b4b8f9b44d272fa87a66e0f2c8ccaba..1f5b7ffc0c5c47def33c93736bb1bd1491cd59d0 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -195,37 +195,6 @@
 #define HDMI14_MAX_RATE			340000000
 #define HDMI20_MAX_RATE			600000000
 
-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;

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Thu Dec 12 12:03:36 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 12 Dec 2024 22:03:36 +0200
Subject: [PATCH v2 5/8] phy: rockchip: samsung-hdptx: Setup TMDS char rate
 via phy_configure_opts_hdmi
In-Reply-To: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
References: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
Message-ID: <20241212-phy-sam-hdptx-bpc-v2-5-57e672c7c7c4@collabora.com>

The current workaround to setup the TMDS character rate relies on the
unconventional usage of phy_set_bus_width().

Make use of the recently introduced HDMI PHY configuration API for this
purpose.  The workaround will be dropped as soon as the switch has been
completed on both ends.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 44 ++++++++++++++++++-----
 1 file changed, 35 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 1f5b7ffc0c5c47def33c93736bb1bd1491cd59d0..bf0c7d74e70b9204c97c571e08cb0c140131acb9 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -244,6 +244,9 @@ struct rk_hdptx_phy {
 	int nr_clks;
 	struct reset_control_bulk_data rsts[RST_MAX];
 
+	/* PHY config opts */
+	unsigned long tmds_char_rate;
+
 	/* clk provider */
 	struct clk_hw hw;
 	unsigned long rate;
@@ -872,18 +875,20 @@ static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)
 static int rk_hdptx_phy_power_on(struct phy *phy)
 {
 	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
-	int bus_width = phy_get_bus_width(hdptx->phy);
+	unsigned int rate = hdptx->tmds_char_rate / 100;
 	int ret;
 
-	/*
-	 * 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;
+	if (rate == 0) {
+		/*
+		 * FIXME: Temporary workaround to setup TMDS char rate
+		 * from the RK HDMI bridge driver.
+		 * Will be removed as soon the switch to the HDMI PHY
+		 * configuration API has been completed on both ends.
+		 */
+		rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
+	}
 
-	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
-		__func__, bus_width, rate);
+	dev_dbg(hdptx->dev, "%s rate=%u\n", __func__, rate);
 
 	ret = rk_hdptx_phy_consumer_get(hdptx, rate);
 	if (ret)
@@ -903,9 +908,20 @@ static int rk_hdptx_phy_power_off(struct phy *phy)
 	return rk_hdptx_phy_consumer_put(hdptx, false);
 }
 
+static int rk_hdptx_phy_configure(struct phy *phy,
+				  union phy_configure_opts *opts)
+{
+	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
+
+	hdptx->tmds_char_rate = opts->hdmi.tmds_char_rate;
+
+	return 0;
+}
+
 static const struct phy_ops rk_hdptx_phy_ops = {
 	.power_on  = rk_hdptx_phy_power_on,
 	.power_off = rk_hdptx_phy_power_off,
+	.configure = rk_hdptx_phy_configure,
 	.owner	   = THIS_MODULE,
 };
 
@@ -961,6 +977,16 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
 
+	/*
+	 * The TMDS char rate set via phy_configure(), if any, has
+	 * precedence over the rate provided via clk_set_rate().
+	 */
+	if (hdptx->tmds_char_rate && hdptx->tmds_char_rate != rate) {
+		dev_dbg(hdptx->dev, "Replaced clk_set_rate=%lu with tmds_char_rate=%lu\n",
+			rate, hdptx->tmds_char_rate);
+		rate = hdptx->tmds_char_rate;
+	}
+
 	return rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100);
 }
 

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Thu Dec 12 12:03:37 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 12 Dec 2024 22:03:37 +0200
Subject: [PATCH v2 6/8] phy: rockchip: samsung-hdptx: Add high color depth
 management
In-Reply-To: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
References: <20241212-phy-sam-hdptx-bpc-v2-0-57e672c7c7c4@collabora.com>
Message-ID: <20241212-phy-sam-hdptx-bpc-v2-6-57e672c7c7c4@collabora.com>

Add support for 8-bit, 10-bit, 12-bit and 16-bit color depth setup.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index bf0c7d74e70b9204c97c571e08cb0c140131acb9..d90d89cfdff561e13ac3db3f143a4eef9cc85a03 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -246,6 +246,7 @@ struct rk_hdptx_phy {
 
 	/* PHY config opts */
 	unsigned long tmds_char_rate;
+	unsigned int bpc;
 
 	/* clk provider */
 	struct clk_hw hw;
@@ -786,6 +787,9 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
 	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_SEL_MASK,
+			   FIELD_PREP(PLL_PCG_CLK_SEL_MASK, (hdptx->bpc - 8) >> 1));
+
 	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN,
 			   PLL_PCG_CLK_EN);
 
@@ -888,7 +892,7 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 		rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
 	}
 
-	dev_dbg(hdptx->dev, "%s rate=%u\n", __func__, rate);
+	dev_dbg(hdptx->dev, "%s rate=%u bpc=%u\n", __func__, rate, hdptx->bpc);
 
 	ret = rk_hdptx_phy_consumer_get(hdptx, rate);
 	if (ret)
@@ -915,6 +919,18 @@ static int rk_hdptx_phy_configure(struct phy *phy,
 
 	hdptx->tmds_char_rate = opts->hdmi.tmds_char_rate;
 
+	switch (opts->hdmi.bpc) {
+	case 8:
+	case 10:
+	case 12:
+	case 16:
+		hdptx->bpc = opts->hdmi.bpc;
+		break;
+	default:
+		dev_warn(hdptx->dev, "Discarded unsupported bpc: %u\n",
+			 opts->hdmi.bpc);
+	};
+
 	return 0;
 }
 
@@ -1062,6 +1078,7 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	hdptx->dev = dev;
+	hdptx->bpc = 8;
 
 	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))

-- 
2.47.0



From shy828301 at gmail.com  Thu Dec 12 12:08:35 2024
From: shy828301 at gmail.com (Yang Shi)
Date: Thu, 12 Dec 2024 12:08:35 -0800
Subject: [PATCH mm-unstable v2 01/16] mm: Introduce generic_mmap_hint()
In-Reply-To: <20241211232754.1583023-2-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com> <20241211232754.1583023-2-kaleshsingh@google.com>
Message-ID: <CAHbLzkovqMsjti1g_G4dFj2mb4hneBPtR2eGTxTZmC717455-A@mail.gmail.com>

On Wed, Dec 11, 2024 at 3:28?PM Kalesh Singh <kaleshsingh at google.com> wrote:
>
> Consolidate the hint searches from both directions (topdown and
> bottomup) into generic_mmap_hint().
>
> No functional change is introduced.
>
> Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
> ---
>
> Changes in v2:
>   - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
>     special case of the hint addr being "enforced", per Yang Shi.
>   - Consolidate error handling in arch_mmap_hint().

Reviewed-by: Yang Shi <shy828301 at gmail.com>

>
>  include/linux/sched/mm.h |  4 +++
>  mm/mmap.c                | 76 ++++++++++++++++++++++++----------------
>  2 files changed, 50 insertions(+), 30 deletions(-)
>
> diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
> index 928a626725e6..edeec19d1708 100644
> --- a/include/linux/sched/mm.h
> +++ b/include/linux/sched/mm.h
> @@ -201,6 +201,10 @@ unsigned long mm_get_unmapped_area_vmflags(struct mm_struct *mm,
>                                            unsigned long flags,
>                                            vm_flags_t vm_flags);
>
> +unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
> +                               unsigned long len, unsigned long pgoff,
> +                               unsigned long flags);
> +
>  unsigned long
>  generic_get_unmapped_area(struct file *filp, unsigned long addr,
>                           unsigned long len, unsigned long pgoff,
> diff --git a/mm/mmap.c b/mm/mmap.c
> index df9154b15ef9..382b4eac5406 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -620,6 +620,47 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)
>         return addr;
>  }
>
> +/*
> + * Look up unmapped area at the requested hint addr
> + *
> + * NOTE: MAP_FIXED is also handled here since it's a special case of
> + * enforcing the hint address.
> + *
> + * Returns:
> + *    ERR_VALUE: If the requested mapping is not valid
> + *    0: If there isn't a sufficiently large hole at the hint addr.
> + *    addr: If sufficient VA space is available at the hint address;
> + *          or MAP_FIXED was specified.
> + */
> +unsigned long generic_mmap_hint(struct file *filp, unsigned long addr,
> +                               unsigned long len, unsigned long pgoff,
> +                               unsigned long flags)
> +{
> +       struct mm_struct *mm = current->mm;
> +       struct vm_area_struct *vma, *prev;
> +       const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
> +
> +       /* requested length too big for entire address space */
> +       if (len > mmap_end - mmap_min_addr)
> +               return -ENOMEM;
> +
> +       if (flags & MAP_FIXED)
> +               return addr;
> +
> +       if (!addr)
> +               return 0;
> +
> +       addr = PAGE_ALIGN(addr);
> +       vma = find_vma_prev(mm, addr, &prev);
> +       if (mmap_end - len >= addr && addr >= mmap_min_addr &&
> +           (!vma || addr + len <= vm_start_gap(vma)) &&
> +           (!prev || addr >= vm_end_gap(prev)))
> +               return addr;
> +
> +       /* Fallback to VA space search */
> +       return 0;
> +}
> +
>  /* Get an address range which is currently unmapped.
>   * For shmat() with addr=0.
>   *
> @@ -637,25 +678,13 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
>                           unsigned long flags, vm_flags_t vm_flags)
>  {
>         struct mm_struct *mm = current->mm;
> -       struct vm_area_struct *vma, *prev;
>         struct vm_unmapped_area_info info = {};
>         const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
>
> -       if (len > mmap_end - mmap_min_addr)
> -               return -ENOMEM;
> -
> -       if (flags & MAP_FIXED)
> +       addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
> +       if (addr)
>                 return addr;
>
> -       if (addr) {
> -               addr = PAGE_ALIGN(addr);
> -               vma = find_vma_prev(mm, addr, &prev);
> -               if (mmap_end - len >= addr && addr >= mmap_min_addr &&
> -                   (!vma || addr + len <= vm_start_gap(vma)) &&
> -                   (!prev || addr >= vm_end_gap(prev)))
> -                       return addr;
> -       }
> -
>         info.length = len;
>         info.low_limit = mm->mmap_base;
>         info.high_limit = mmap_end;
> @@ -685,27 +714,14 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
>                                   unsigned long len, unsigned long pgoff,
>                                   unsigned long flags, vm_flags_t vm_flags)
>  {
> -       struct vm_area_struct *vma, *prev;
>         struct mm_struct *mm = current->mm;
>         struct vm_unmapped_area_info info = {};
>         const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
>
> -       /* requested length too big for entire address space */
> -       if (len > mmap_end - mmap_min_addr)
> -               return -ENOMEM;
> -
> -       if (flags & MAP_FIXED)
> -               return addr;
> -
>         /* requesting a specific address */
> -       if (addr) {
> -               addr = PAGE_ALIGN(addr);
> -               vma = find_vma_prev(mm, addr, &prev);
> -               if (mmap_end - len >= addr && addr >= mmap_min_addr &&
> -                               (!vma || addr + len <= vm_start_gap(vma)) &&
> -                               (!prev || addr >= vm_end_gap(prev)))
> -                       return addr;
> -       }
> +       addr = generic_mmap_hint(filp, addr, len, pgoff, flags);
> +       if (addr)
> +               return addr;
>
>         info.flags = VM_UNMAPPED_AREA_TOPDOWN;
>         info.length = len;
> --
> 2.47.0.338.g60cca15819-goog
>
>


From shy828301 at gmail.com  Thu Dec 12 12:11:51 2024
From: shy828301 at gmail.com (Yang Shi)
Date: Thu, 12 Dec 2024 12:11:51 -0800
Subject: [PATCH mm-unstable v2 16/16] mm: Respect mmap hint before THP
 alignment if allocation is possible
In-Reply-To: <20241211232754.1583023-17-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com> <20241211232754.1583023-17-kaleshsingh@google.com>
Message-ID: <CAHbLzko2Z0-QReXo54H=sd1asXsPKEHf9N4Nmv0=Ry7SM=XX+g@mail.gmail.com>

On Wed, Dec 11, 2024 at 3:31?PM Kalesh Singh <kaleshsingh at google.com> wrote:
>
> Commit 249608ee4713 ("mm: respect mmap hint address when aligning for THP")
> fallsback to PAGE_SIZE alignment instead of THP alignment
> for anonymous mapping as long as a hint address is provided by the user
> -- even if we weren't able to allocate the unmapped area at the hint
> address in the end.
>
> This was done to address the immediate regression in anonymous mappings
> where the hint address were being ignored in some cases; due to commit
> efa7df3e3bb5 ("mm: align larger anonymous mappings on THP boundaries").
>
> It was later pointed out that this issue also existed for file-backed
> mappings from file systems that use thp_get_unmapped_area() for their
> .get_unmapped_area() file operation.
>
> The same fix was not applied for file-backed mappings since it would
> mean any mmap requests that provide a hint address would be only
> PAGE_SIZE-aligned regardless of whether allocation was successful at
> the hint address or not.
>
> Instead, use arch_mmap_hint() to first attempt allocation at the hint
> address and fallback to THP alignment if there isn't sufficient VA space
> to satisfy the allocation at the hint address.
>
> Signed-off-by: Kalesh Singh <kaleshsingh at google.com>

Reviewed-by: Yang Shi <shy828301 at gmail.com>

> ---
>  mm/huge_memory.c | 17 ++++++++++-------
>  mm/mmap.c        |  1 -
>  2 files changed, 10 insertions(+), 8 deletions(-)
>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 2da5520bfe24..426761a30aff 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -1097,6 +1097,16 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
>         loff_t off_align = round_up(off, size);
>         unsigned long len_pad, ret, off_sub;
>
> +       /*
> +        * If allocation at the address hint succeeds; respect the hint and
> +        * don't try to align to THP boundary;
> +        *
> +        * Or if an the requested extent is invalid return the error immediately.
> +        */
> +       addr = arch_mmap_hint(filp, addr, len, off, flags);
> +       if (addr)
> +               return addr;
> +
>         if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall())
>                 return 0;
>
> @@ -1117,13 +1127,6 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,
>         if (IS_ERR_VALUE(ret))
>                 return 0;
>
> -       /*
> -        * Do not try to align to THP boundary if allocation at the address
> -        * hint succeeds.
> -        */
> -       if (ret == addr)
> -               return addr;
> -
>         off_sub = (off - ret) & (size - 1);
>
>         if (test_bit(MMF_TOPDOWN, &current->mm->flags) && !off_sub)
> diff --git a/mm/mmap.c b/mm/mmap.c
> index 76dd6acdf051..3286fdff26f2 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -814,7 +814,6 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
>         if (get_area) {
>                 addr = get_area(file, addr, len, pgoff, flags);
>         } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && !file
> -                  && !addr /* no hint */
>                    && IS_ALIGNED(len, PMD_SIZE)) {
>                 /* Ensures that larger anonymous mappings are THP aligned. */
>                 addr = thp_get_unmapped_area_vmflags(file, addr, len,
> --
> 2.47.0.338.g60cca15819-goog
>
>


From Frank.Li at nxp.com  Thu Dec 12 12:59:59 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 12 Dec 2024 15:59:59 -0500
Subject: [PATCH v3 1/2] dt-bindings: thermal: fsl,imx91-tmu: add bindings
 for NXP i.MX91 thermal module
In-Reply-To: <20241212-imx91tmu-v3-0-85e756b29437@nxp.com>
References: <20241212-imx91tmu-v3-0-85e756b29437@nxp.com>
Message-ID: <20241212-imx91tmu-v3-1-85e756b29437@nxp.com>

From: Pengfei Li <pengfei.li_1 at nxp.com>

Add bindings documentation for i.MX91 thermal modules.

Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v2 to v3
- add ref thermal-sensor
- restrict #thermal-sensor-cells to 0 only
- Change to unevaluatedProperties
---
 .../devicetree/bindings/thermal/fsl,imx91-tmu.yaml | 67 ++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml b/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml
new file mode 100644
index 0000000000000..8411f3233bf44
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/fsl,imx91-tmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX91 Thermal
+
+maintainers:
+  - Pengfei Li <pengfei.li_1 at nxp.com>
+
+description:
+  i.MX91 features a new temperature sensor. It includes programmable
+  temperature threshold comparators for both normal and privileged
+  accesses and allows a programmable measurement frequency for the
+  Periodic One-Shot Measurement mode. Additionally, it provides
+  status registers for indicating the end of measurement and threshold
+  violation events.
+
+properties:
+  compatible:
+    items:
+      - const: fsl,imx91-tmu
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  nvmem-cells:
+    items:
+      - description: Phandle to the trim control 1 provided by ocotp
+      - description: Phandle to the trim control 2 provided by ocotp
+
+  nvmem-cell-names:
+    items:
+      - const: trim1
+      - const: trim2
+
+  "#thermal-sensor-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+allOf:
+  - $ref: thermal-sensor.yaml
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx93-clock.h>
+
+    thermal-sensor at 44482000 {
+        compatible = "fsl,imx91-tmu";
+        reg = <0x44482000 0x1000>;
+        #thermal-sensor-cells = <0>;
+        clocks = <&clk IMX93_CLK_TMC_GATE>;
+        nvmem-cells = <&tmu_trim1>, <&tmu_trim2>;
+        nvmem-cell-names = "trim1", "trim2";
+    };
+
+...

-- 
2.34.1



From Frank.Li at nxp.com  Thu Dec 12 12:59:58 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 12 Dec 2024 15:59:58 -0500
Subject: [PATCH v3 0/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
Message-ID: <20241212-imx91tmu-v3-0-85e756b29437@nxp.com>

- Add binding doc
- Add imx91 thermal driver
- dts part wait for https://lore.kernel.org/imx/Z04W5chGq5TitB9f at lizhi-Precision-Tower-5810/
merged, so not in this serial.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Changes in v3:
- add ref thermal-sensor
- restrict #thermal-sensor-cells to 0 only
- Change to unevaluatedProperties

- add IMX91_TMU_ prefix for register define
- remove unused register define
- fix missed pm_runtime_put() at error path in imx91_tmu_get_temp()
- use dev variable in probe function
- use pm_runtime_set_active() in probe
- move START to imx91_tmu_get_temp()
- use DEFINE_RUNTIME_DEV_PM_OPS()
- keep set reset value because there are not sw "reset" bit in controller,
  uboot may change and enable tmu.

- Link to v2: https://lore.kernel.org/r/20241210-imx91tmu-v2-0-5032aad4d88e at nxp.com

Changes in v2:
- use low case for hexvalue
- combine struct imx91_tmu and tmu_sensor
- simplify imx91_tmu_start() and imx91_tmu_enable()
- use s16 for imx91_tmu_get_temp(), which may negative value
- use reverse christmas tree style
- use run time pm
- use oneshot to sample temp
- register thermal zone after hardware init
- Link to v1: https://lore.kernel.org/r/20241209-imx91tmu-v1-0-7859c5387f31 at nxp.com

---
Pengfei Li (2):
      dt-bindings: thermal: fsl,imx91-tmu: add bindings for NXP i.MX91 thermal module
      thermal: imx91: Add support for i.MX91 thermal monitoring unit

 .../devicetree/bindings/thermal/fsl,imx91-tmu.yaml |  67 ++++++
 drivers/thermal/Kconfig                            |  10 +
 drivers/thermal/Makefile                           |   1 +
 drivers/thermal/imx91_thermal.c                    | 263 +++++++++++++++++++++
 4 files changed, 341 insertions(+)
---
base-commit: d07c576946b2bc440d6d2073998023e8a0bd7568
change-id: 20241209-imx91tmu-af2a7c042d8d

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Thu Dec 12 13:00:00 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 12 Dec 2024 16:00:00 -0500
Subject: [PATCH v3 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241212-imx91tmu-v3-0-85e756b29437@nxp.com>
References: <20241212-imx91tmu-v3-0-85e756b29437@nxp.com>
Message-ID: <20241212-imx91tmu-v3-2-85e756b29437@nxp.com>

From: Pengfei Li <pengfei.li_1 at nxp.com>

Introduce support for the i.MX91 thermal monitoring unit, which features a
single sensor for the CPU. The register layout differs from other chips,
necessitating the creation of a dedicated file for this.

Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
change from v2 to v3
- add IMX91_TMU_ prefix for register define
- remove unused register define
- fix missed pm_runtime_put() at error path in imx91_tmu_get_temp()
- use dev variable in probe function
- use pm_runtime_set_active() in probe
- move START to imx91_tmu_get_temp()
- use DEFINE_RUNTIME_DEV_PM_OPS()
- keep set reset value because there are not sw "reset" bit in controller,
uboot may change and enable tmu.

change from v1 to v2
- use low case for hexvalue
- combine struct imx91_tmu and tmu_sensor
- simplify imx91_tmu_start() and imx91_tmu_enable()
- use s16 for imx91_tmu_get_temp(), which may negative value
- use reverse christmas tree style
- use run time pm
- use oneshot to sample temp
- register thermal zone after hardware init
---
 drivers/thermal/Kconfig         |  10 ++
 drivers/thermal/Makefile        |   1 +
 drivers/thermal/imx91_thermal.c | 263 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 274 insertions(+)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index d3f9686e26e71..da403ed86aeb1 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -296,6 +296,16 @@ config IMX8MM_THERMAL
 	  cpufreq is used as the cooling device to throttle CPUs when the passive
 	  trip is crossed.
 
+config IMX91_THERMAL
+	tristate "Temperature sensor driver for NXP i.MX91 SoC"
+	depends on ARCH_MXC || COMPILE_TEST
+	depends on OF
+	help
+	  Support for Temperature sensor found on NXP i.MX91 SoC.
+	  It supports one critical trip point and one passive trip point. The
+	  cpufreq is used as the cooling device to throttle CPUs when the passive
+	  trip is crossed.
+
 config K3_THERMAL
 	tristate "Texas Instruments K3 thermal support"
 	depends on ARCH_K3 || COMPILE_TEST
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 9abf43a74f2bb..08da241e6a598 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
 obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
 obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
 obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
+obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
 obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
 obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
 obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
new file mode 100644
index 0000000000000..62b579365fd03
--- /dev/null
+++ b/drivers/thermal/imx91_thermal.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2024 NXP.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/thermal.h>
+
+#define IMX91_TMU_STAT0				0x10
+#define IMX91_TMU_STAT0_DRDY0_IF_MASK		BIT(16)
+
+#define IMX91_TMU_DATA0				0x20
+
+#define IMX91_TMU_CTRL1_SET			0x204
+#define IMX91_TMU_CTRL1_CLR			0x208
+#define IMX91_TMU_CTRL1_EN			BIT(31)
+#define IMX91_TMU_CTRL1_START			BIT(30)
+#define IMX91_TMU_CTRL1_STOP			BIT(29)
+#define IMX91_TMU_CTRL1_RES_MASK		GENMASK(19, 18)
+#define IMX91_TMU_CTRL1_MEAS_MODE_MASK		GENMASK(25, 24)
+#define   IMX91_TMU_CTRL1_MEAS_MODE_SINGLE	0
+#define   IMX91_TMU_CTRL1_MEAS_MODE_CONTINUES	1
+#define   IMX91_TMU_CTRL1_MEAS_MODE_PERIODIC	2
+
+#define IMX91_TMU_REF_DIV			0x280
+#define IMX91_TMU_DIV_EN			BIT(31)
+#define IMX91_TMU_DIV_MASK			GENMASK(23, 16)
+#define IMX91_TMU_DIV_MAX			255
+
+#define IMX91_TMU_PUD_ST_CTRL			0x2b0
+#define IMX91_TMU_PUDL_MASK			GENMASK(23, 16)
+
+#define IMX91_TMU_TRIM1				0x2e0
+#define IMX91_TMU_TRIM2				0x2f0
+
+#define IMX91_TMU_TEMP_LOW_LIMIT		-40000
+#define IMX91_TMU_TEMP_HIGH_LIMIT		125000
+
+#define IMX91_TMU_DEFAULT_TRIM1_CONFIG		0xb561bc2d
+#define IMX91_TMU_DEFAULT_TRIM2_CONFIG		0x65d4
+
+struct imx91_tmu {
+	void __iomem *base;
+	struct clk *clk;
+	struct device *dev;
+	struct thermal_zone_device *tzd;
+};
+
+static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
+{
+	u32 val = start ? IMX91_TMU_CTRL1_START : IMX91_TMU_CTRL1_STOP;
+
+	writel_relaxed(val, tmu->base + IMX91_TMU_CTRL1_SET);
+}
+
+static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
+{
+	u32 reg = enable ? IMX91_TMU_CTRL1_SET : IMX91_TMU_CTRL1_CLR;
+
+	writel_relaxed(IMX91_TMU_CTRL1_EN, tmu->base + reg);
+}
+
+static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+	struct imx91_tmu *tmu = thermal_zone_device_priv(tz);
+	s16 data;
+	int ret;
+	u32 val;
+
+	ret = pm_runtime_resume_and_get(tmu->dev);
+	if (ret < 0)
+		return ret;
+
+	imx91_tmu_start(tmu, true);
+
+	ret = readl_relaxed_poll_timeout(tmu->base + IMX91_TMU_STAT0, val,
+					 val & IMX91_TMU_STAT0_DRDY0_IF_MASK, 1000, 40000);
+	if (ret) {
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	/* DATA0 is 16bit signed number */
+	data = readw_relaxed(tmu->base + IMX91_TMU_DATA0);
+	*temp = data * 1000 / 64;
+	if (*temp < IMX91_TMU_TEMP_LOW_LIMIT || *temp > IMX91_TMU_TEMP_HIGH_LIMIT)
+		ret = -EAGAIN;
+
+out:
+	pm_runtime_put(tmu->dev);
+
+	return ret;
+}
+
+static struct thermal_zone_device_ops tmu_tz_ops = {
+	.get_temp = imx91_tmu_get_temp,
+};
+
+static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
+{
+	struct device *dev = tmu->dev;
+	u32 trim1, trim2;
+	int ret;
+
+	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
+	if (ret)
+		return ret;
+
+	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
+	if (ret)
+		return ret;
+
+	if (trim1 == 0 || trim2 == 0)
+		return -EINVAL;
+
+	writel_relaxed(trim1, tmu->base + IMX91_TMU_TRIM1);
+	writel_relaxed(trim2, tmu->base + IMX91_TMU_TRIM2);
+
+	return 0;
+}
+
+static int imx91_tmu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct imx91_tmu *tmu;
+	unsigned long rate;
+	u32 div;
+	int ret;
+
+	tmu = devm_kzalloc(dev, sizeof(struct imx91_tmu), GFP_KERNEL);
+	if (!tmu)
+		return -ENOMEM;
+
+	tmu->dev = dev;
+
+	tmu->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(tmu->base))
+		return dev_err_probe(dev, PTR_ERR(tmu->base), "failed to get io resource");
+
+	tmu->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(tmu->clk))
+		return dev_err_probe(dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
+
+	platform_set_drvdata(pdev, tmu);
+
+	/* disable the monitor during initialization */
+	imx91_tmu_enable(tmu, false);
+	imx91_tmu_start(tmu, false);
+
+	ret = imx91_init_from_nvmem_cells(tmu);
+	if (ret) {
+		writel_relaxed(IMX91_TMU_DEFAULT_TRIM1_CONFIG, tmu->base + IMX91_TMU_TRIM1);
+		writel_relaxed(IMX91_TMU_DEFAULT_TRIM2_CONFIG, tmu->base + IMX91_TMU_TRIM2);
+	}
+
+	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
+	rate = clk_get_rate(tmu->clk);
+	div = (rate / 4000000) - 1;
+	if (div > IMX91_TMU_DIV_MAX)
+		return dev_err_probe(dev, -EINVAL, "clock divider exceed hardware limiation");
+
+	/* Set divider value and enable divider */
+	writel_relaxed(IMX91_TMU_DIV_EN | FIELD_PREP(IMX91_TMU_DIV_MASK, div),
+		       tmu->base + IMX91_TMU_REF_DIV);
+
+	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
+	writel_relaxed(FIELD_PREP(IMX91_TMU_PUDL_MASK, 100U), tmu->base + IMX91_TMU_PUD_ST_CTRL);
+
+	/*
+	 * Set resolution mode
+	 * 00b - Conversion time = 0.59325 ms
+	 * 01b - Conversion time = 1.10525 ms
+	 * 10b - Conversion time = 2.12925 ms
+	 * 11b - Conversion time = 4.17725 ms
+	 */
+	writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_RES_MASK, 0x3), tmu->base + IMX91_TMU_CTRL1_CLR);
+	writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_RES_MASK, 0x1), tmu->base + IMX91_TMU_CTRL1_SET);
+
+	writel_relaxed(IMX91_TMU_CTRL1_MEAS_MODE_MASK, tmu->base + IMX91_TMU_CTRL1_CLR);
+	writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_MEAS_MODE_MASK, IMX91_TMU_CTRL1_MEAS_MODE_SINGLE),
+		       tmu->base + IMX91_TMU_CTRL1_SET);
+
+	imx91_tmu_enable(tmu, true);
+	pm_runtime_set_active(dev);
+	devm_pm_runtime_enable(dev);
+
+	tmu->tzd = devm_thermal_of_zone_register(dev, 0, tmu, &tmu_tz_ops);
+	if (IS_ERR(tmu->tzd))
+		return dev_err_probe(dev, PTR_ERR(tmu->tzd),
+				     "failed to register thermal zone sensor\n");
+
+	pm_runtime_put(dev);
+
+	return 0;
+}
+
+static void imx91_tmu_remove(struct platform_device *pdev)
+{
+	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
+
+	/* disable tmu */
+	imx91_tmu_start(tmu, false);
+	imx91_tmu_enable(tmu, false);
+}
+
+static int imx91_tmu_runtime_suspend(struct device *dev)
+{
+	struct imx91_tmu *tmu = dev_get_drvdata(dev);
+
+	/* disable tmu */
+	imx91_tmu_enable(tmu, false);
+
+	clk_disable_unprepare(tmu->clk);
+
+	return 0;
+}
+
+static int imx91_tmu_runtime_resume(struct device *dev)
+{
+	struct imx91_tmu *tmu = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(tmu->clk);
+	if (ret)
+		return ret;
+
+	imx91_tmu_enable(tmu, true);
+
+	return 0;
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(imx91_tmu_pm_ops, imx91_tmu_runtime_suspend,
+				 imx91_tmu_runtime_resume, NULL);
+
+static const struct of_device_id imx91_tmu_table[] = {
+	{ .compatible = "fsl,imx91-tmu", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, imx91_tmu_table);
+
+static struct platform_driver imx91_tmu = {
+	.driver = {
+		.name	= "imx91_thermal",
+		.pm	= pm_ptr(&imx91_tmu_pm_ops),
+		.of_match_table = imx91_tmu_table,
+	},
+	.probe = imx91_tmu_probe,
+	.remove = imx91_tmu_remove,
+};
+module_platform_driver(imx91_tmu);
+
+MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
+MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From Liam.Howlett at oracle.com  Thu Dec 12 13:02:31 2024
From: Liam.Howlett at oracle.com (Liam R. Howlett)
Date: Thu, 12 Dec 2024 16:02:31 -0500
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <hmuzfspqjzb36xlj2x44keihacrrhzj5madqrfbcnhqouzredv@wo75achgkuh5>


+ Lorenzo

Can you please Cc the people listed in the maintainers on the files you
are submitting against?  You seemed to Cc everyone but the mmap.c file
maintainers?


* Kalesh Singh <kaleshsingh at google.com> [241211 18:28]:
> Hi all,
> 
> This is v2 othe the arch_mmap_hint() series.
> 
> Changes in v2:
>   - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
>     special case of the hint addr being "enforced", per Yang Shi.
>   - Consolidate most of the error handling in arch_mmap_hint().
>   - Patch 16 ("mm: Fallback to generic_mmap_hint()") was folded into
>     Patch 2 ("mm: x86: Introduce arch_mmap_hint()")
> 
> v1: https://lore.kernel.org/r/20241210024119.2488608-1-kaleshsingh at google.com/
> 
> =======
> 
> This series introduces arch_mmap_hint() to handle allocating VA space
> for the hint address.

Why?  Could we get more details in your cover letter please?  This
entire email has as much detail as the subject line.

I don't want more arch_ anything.  If we can do this in a more generic
way, then we should.

> 
> Patches 1-16 introduce this new helper and Patch 17 uses it to fix the
> issue of mmap hint being ignored in some cases due to THP alignment [1]
> 
> [1] https://lore.kernel.org/r/20241118214650.3667577-1-kaleshsingh at google.com/
> 
> Thanks,
> Kalesh
> 
> 
> Kalesh Singh (16):
>   mm: Introduce generic_mmap_hint()
>   mm: x86: Introduce arch_mmap_hint()
>   mm: arm: Introduce arch_mmap_hint()
>   mm: alpha: Introduce arch_mmap_hint()
>   mm: arc: Use generic_mmap_hint()
>   mm: csky: Introduce arch_mmap_hint()
>   mm: loongarch: Introduce arch_mmap_hint()
>   mm: mips: Introduce arch_align_mmap_hint()
>   mm: parisc: Introduce arch_align_mmap_hint()
>   mm: s390: Use generic_mmap_hint()
>   mm: sh: Introduce arch_mmap_hint()
>   mm: sparc32: Introduce arch_mmap_hint()
>   mm: sparc64: Introduce arch_mmap_hint()
>   mm: xtensa: Introduce arch_mmap_hint()
>   mm: powerpc: Introduce arch_mmap_hint()
>   mm: Respect mmap hint before THP alignment if allocation is possible
> 
>  arch/alpha/include/asm/pgtable.h           |   1 +
>  arch/alpha/kernel/osf_sys.c                |  31 +++---
>  arch/arc/include/asm/pgtable.h             |   1 +
>  arch/arc/mm/mmap.c                         |  43 +++++----
>  arch/arm/include/asm/pgtable.h             |   1 +
>  arch/arm/mm/mmap.c                         | 107 +++++++++------------
>  arch/csky/abiv1/inc/abi/pgtable-bits.h     |   1 +
>  arch/csky/abiv1/mmap.c                     |  68 +++++++------
>  arch/loongarch/include/asm/pgtable.h       |   1 +
>  arch/loongarch/mm/mmap.c                   |  49 +++++-----
>  arch/mips/include/asm/pgtable.h            |   1 +
>  arch/mips/mm/mmap.c                        |  50 +++++-----
>  arch/parisc/include/asm/pgtable.h          |   1 +
>  arch/parisc/kernel/sys_parisc.c            |  53 +++++-----
>  arch/powerpc/include/asm/book3s/64/slice.h |   1 +
>  arch/powerpc/mm/book3s64/slice.c           |  31 ++++++
>  arch/s390/include/asm/pgtable.h            |   1 +
>  arch/s390/mm/mmap.c                        |  51 +++++-----
>  arch/sh/include/asm/pgtable.h              |   1 +
>  arch/sh/mm/mmap.c                          |  83 ++++++----------
>  arch/sparc/include/asm/pgtable_32.h        |   1 +
>  arch/sparc/include/asm/pgtable_64.h        |   1 +
>  arch/sparc/kernel/sys_sparc_32.c           |  33 ++++---
>  arch/sparc/kernel/sys_sparc_64.c           |  96 +++++++-----------
>  arch/x86/include/asm/pgtable_64.h          |   1 +
>  arch/x86/kernel/sys_x86_64.c               |  64 ++++++------
>  arch/xtensa/kernel/syscall.c               |  31 ++++--
>  include/linux/sched/mm.h                   |   9 ++
>  mm/huge_memory.c                           |  17 ++--
>  mm/mmap.c                                  |  86 +++++++++++------
>  30 files changed, 491 insertions(+), 424 deletions(-)
> 
> -- 
> 2.47.0.338.g60cca15819-goog
> 
> 


From markuss.broks at gmail.com  Thu Dec 12 13:09:01 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Thu, 12 Dec 2024 23:09:01 +0200
Subject: [PATCH 1/3] dt-bindings: soc: samsung: exynos-speedy: Document
 SPEEDY host controller bindings
In-Reply-To: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
Message-ID: <20241212-speedy-v1-1-544ad7bcfb6a@gmail.com>

Add the schema for the Samsung SPEEDY serial bus host controller.
The bus has 4 bit wide addresses for addressing devices
and 8 bit wide register addressing. Each register is also 8
bit long, so the address can be 0-f (hexadecimal), node name
for child device follows the format: node_name@[0-f].

Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
---
 .../bindings/soc/samsung/exynos-speedy.yaml        | 78 ++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..304b322a74ea70f23d8c072b44b6ca86b7cc807f
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/samsung/exynos-speedy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SPEEDY serial bus host controller
+
+maintainers:
+  - Markuss Broks <markuss.broks at gmail.com>
+
+description:
+  Samsung SPEEDY is a proprietary Samsung serial 1-wire bus.
+  It is used on various Samsung Exynos chips. The bus can
+  address at most 4 bit (16) devices. The devices on the bus
+  have 8 bit long register line, and the registers are also
+  8 bit long each. It is typically used for communicating with
+  Samsung PMICs (s2mps17, s2mps18, ...) and other Samsung chips,
+  such as RF parts.
+
+properties:
+  compatible:
+    - items:
+        - enum:
+            - samsung,exynos9810-speedy
+        - const: samsung,exynos-speedy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    - const: pclk
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+
+patternProperties:
+  "^[a-z][a-z0-9]*@[0-9a-f]$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      reg:
+        maxItems: 1
+
+    required:
+      - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    speedy0: speedy at 141c0000 {
+      compatible = "samsung,exynos9810-speedy",
+                   "samsung-exynos-speedy";
+      reg = <0x141c0000 0x2000>;
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      pmic at 0 {
+        compatible = "samsung,s2mps18-pmic";
+        reg = <0x0>;
+      };
+
+      regulator at 1 {
+        compatible = "samsung,s2mps18-regulator";
+        reg = <0x1>;
+      };
+    };

-- 
2.47.0



From markuss.broks at gmail.com  Thu Dec 12 13:09:02 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Thu, 12 Dec 2024 23:09:02 +0200
Subject: [PATCH 2/3] soc: samsung: Add a driver for Samsung SPEEDY host
 controller
In-Reply-To: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
Message-ID: <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>

Add a driver for Samsung SPEEDY serial bus host controller.
SPEEDY is a proprietary 1 wire serial bus used by Samsung
in various devices (usually mobile), like Samsung Galaxy
phones. It is usually used for connecting PMIC or various
other peripherals, like audio codecs or RF components.

This bus can address at most 1MiB (4 bit device address,
8 bit registers per device, 8 bit wide registers:
256*256*16 = 1MiB of address space.

Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
---
 drivers/soc/samsung/Kconfig               |  13 +
 drivers/soc/samsung/Makefile              |   2 +
 drivers/soc/samsung/exynos-speedy.c       | 457 ++++++++++++++++++++++++++++++
 include/linux/soc/samsung/exynos-speedy.h |  56 ++++
 4 files changed, 528 insertions(+)

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 1a5dfdc978dc4069eb71c4e8eada7ff1913b86b3..a38150fc9999ded1e1e93e2a9ef43b88175d34bd 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -49,6 +49,19 @@ config EXYNOS_PMU_ARM_DRIVERS
 	bool "Exynos PMU ARMv7-specific driver extensions" if COMPILE_TEST
 	depends on EXYNOS_PMU
 
+config EXYNOS_SPEEDY
+	tristate "Exynos SPEEDY host controller driver"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	depends on OF
+	depends on REGMAP_MMIO
+	help
+	  Enable support for Exynos SPEEDY host controller block.
+	  SPEEDY is a 1 wire proprietary Samsung serial bus, found in
+	  modern Samsung Exynos SoCs, like Exynos8895 and newer.
+
+	  Select this if you have a Samsung Exynos device which uses
+	  SPEEDY bus.
+
 config SAMSUNG_PM_CHECK
 	bool "S3C2410 PM Suspend Memory CRC"
 	depends on PM && (ARCH_S3C64XX || ARCH_S5PV210)
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
index 248a33d7754af1a1e5fbbbb79413eb300bbbc8e5..9fe824075be77dbcd22c5f1477c4b34029016ed2 100644
--- a/drivers/soc/samsung/Makefile
+++ b/drivers/soc/samsung/Makefile
@@ -12,4 +12,6 @@ obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
 					exynos5250-pmu.o exynos5420-pmu.o
 obj-$(CONFIG_EXYNOS_REGULATOR_COUPLER) += exynos-regulator-coupler.o
 
+obj-$(CONFIG_EXYNOS_SPEEDY)	+= exynos-speedy.o
+
 obj-$(CONFIG_SAMSUNG_PM_CHECK)	+= s3c-pm-check.o
diff --git a/drivers/soc/samsung/exynos-speedy.c b/drivers/soc/samsung/exynos-speedy.c
new file mode 100644
index 0000000000000000000000000000000000000000..e897b67c80edacee485169ea6dc1ffe0cefdd21f
--- /dev/null
+++ b/drivers/soc/samsung/exynos-speedy.c
@@ -0,0 +1,457 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * exynos-speedy.c - Samsung Exynos SPEEDY Host Controller Driver
+ *
+ * Copyright 2024, Markuss Broks <markuss.broks at gmail.com>
+ * Copyright 2024, Maksym Holovach <nergzd at nergzd723.xyz>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include <linux/soc/samsung/exynos-speedy.h>
+
+/* Speedy MMIO register map */
+#define SPEEDY_CTRL					0x000
+#define SPEEDY_FIFO_CTRL				0x004
+#define SPEEDY_CMD					0x008
+#define SPEEDY_INT_ENABLE				0x00C
+#define SPEEDY_INT_STATUS				0x010
+#define SPEEDY_FIFO_STATUS				0x030
+#define SPEEDY_TX_DATA					0x034
+#define SPEEDY_RX_DATA					0x038
+#define SPEEDY_PACKET_GAP_TIME				0x044
+#define SPEEDY_TIMEOUT_COUNT				0x048
+#define SPEEDY_FIFO_DEBUG				0x100
+#define SPEEDY_CTRL_STATUS				0x104
+
+/* SPEEDY_CTRL register bits */
+#define SPEEDY_ENABLE					(1 << 0)
+#define SPEEDY_TIMEOUT_CMD_DISABLE			(1 << 1)
+#define SPEEDY_TIMEOUT_STANDBY_DISABLE			(1 << 2)
+#define SPEEDY_TIMEOUT_DATA_DISABLE			(1 << 3)
+#define SPEEDY_ALWAYS_PULLUP_EN				(1 << 7)
+#define SPEEDY_DATA_WIDTH_8BIT				(0 << 8)
+#define SPEEDY_REMOTE_RESET_REQ				(1 << 30)
+#define SPEEDY_SW_RST					(1 << 31)
+
+/* SPEEDY_FIFO_CTRL register bits */
+#define SPEEDY_RX_TRIGGER_LEVEL(x)			((x) << 0)
+#define SPEEDY_TX_TRIGGER_LEVEL(x)			((x) << 8)
+#define SPEEDY_FIFO_RESET				(1 << 31)
+
+/* SPEEDY_CMD register bits */
+#define SPEEDY_BURST_LENGTH(x)				((x) << 0)
+#define SPEEDY_BURST_FIXED				(0 << 5)
+#define SPEEDY_BURST_INCR				(1 << 5)
+#define SPEEDY_BURST_EXTENSION				(2 << 5)
+#define SPEEDY_ACCESS_BURST				(0 << 19)
+#define SPEEDY_ACCESS_RANDOM				(1 << 19)
+#define SPEEDY_DIRECTION_READ				(0 << 20)
+#define SPEEDY_DIRECTION_WRITE				(1 << 20)
+
+/* SPEEDY_INT_ENABLE register bits */
+#define SPEEDY_TRANSFER_DONE_EN				(1 << 0)
+#define SPEEDY_TIMEOUT_CMD_EN				(1 << 1)
+#define SPEEDY_TIMEOUT_STANDBY_EN			(1 << 2)
+#define SPEEDY_TIMEOUT_DATA_EN				(1 << 3)
+#define SPEEDY_FIFO_TX_ALMOST_EMPTY_EN			(1 << 4)
+#define SPEEDY_FIFO_RX_ALMOST_FULL_EN			(1 << 8)
+#define SPEEDY_RX_FIFO_INT_TRAILER_EN			(1 << 9)
+#define SPEEDY_RX_MODEBIT_ERR_EN			(1 << 16)
+#define SPEEDY_RX_GLITCH_ERR_EN				(1 << 17)
+#define SPEEDY_RX_ENDBIT_ERR_EN				(1 << 18)
+#define SPEEDY_TX_LINE_BUSY_ERR_EN			(1 << 20)
+#define SPEEDY_TX_STOPBIT_ERR_EN			(1 << 21)
+#define SPEEDY_REMOTE_RESET_REQ_EN			(1 << 31)
+
+/* SPEEDY_INT_STATUS register bits */
+#define SPEEDY_TRANSFER_DONE				(1 << 0)
+#define SPEEDY_TIMEOUT_CMD				(1 << 1)
+#define SPEEDY_TIMEOUT_STANDBY				(1 << 2)
+#define SPEEDY_TIMEOUT_DATA				(1 << 3)
+#define SPEEDY_FIFO_TX_ALMOST_EMPTY			(1 << 4)
+#define SPEEDY_FIFO_RX_ALMOST_FULL			(1 << 8)
+#define SPEEDY_RX_FIFO_INT_TRAILER			(1 << 9)
+#define SPEEDY_RX_MODEBIT_ERR				(1 << 16)
+#define SPEEDY_RX_GLITCH_ERR				(1 << 17)
+#define SPEEDY_RX_ENDBIT_ERR				(1 << 18)
+#define SPEEDY_TX_LINE_BUSY_ERR				(1 << 20)
+#define SPEEDY_TX_STOPBIT_ERR				(1 << 21)
+#define SPEEDY_REMOTE_RESET_REQ_STAT			(1 << 31)
+
+/* SPEEDY_FIFO_STATUS register bits */
+#define SPEEDY_VALID_DATA_CNT				(0 << 0)
+#define SPEEDY_FIFO_FULL				(1 << 5)
+#define SPEEDY_FIFO_EMPTY				(1 << 6)
+
+/* SPEEDY_PACKET_GAP_TIME register bits */
+#define SPEEDY_FIFO_TX_ALMOST_EMPTY			(1 << 4)
+#define SPEEDY_FIFO_RX_ALMOST_FULL			(1 << 8)
+#define SPEEDY_FSM_INIT					(1 << 1)
+#define SPEEDY_FSM_TX_CMD				(1 << 2)
+#define SPEEDY_FSM_STANDBY				(1 << 3)
+#define SPEEDY_FSM_DATA					(1 << 4)
+#define SPEEDY_FSM_TIMEOUT				(1 << 5)
+#define SPEEDY_FSM_TRANS_DONE				(1 << 6)
+#define SPEEDY_FSM_IO_RX_STAT_MASK			(3 << 7)
+#define SPEEDY_FSM_IO_TX_IDLE				(1 << 9)
+#define SPEEDY_FSM_IO_TX_GET_PACKET			(1 << 10)
+#define SPEEDY_FSM_IO_TX_PACKET				(1 << 11)
+#define SPEEDY_FSM_IO_TX_DONE				(1 << 12)
+
+#define SPEEDY_RX_LENGTH(n)				((n) << 0)
+#define SPEEDY_TX_LENGTH(n)				((n) << 8)
+
+#define SPEEDY_DEVICE(x)				((x & 0xf) << 15)
+#define SPEEDY_ADDRESS(x)				((x & 0xff) << 7)
+
+static const struct of_device_id speedy_match[] = {
+	{ .compatible = "samsung,exynos9810-speedy" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, speedy_match);
+
+static const struct regmap_config speedy_map_cfg = {
+	.reg_bits = 32,
+	.val_bits = 32,
+};
+
+/**
+ * speedy_int_clear() - clear interrupt status
+ * @speedy:	pointer to speedy controller struct
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+static int speedy_int_clear(struct speedy_controller *speedy)
+{
+	int ret;
+
+	ret = regmap_set_bits(speedy->map, SPEEDY_INT_STATUS, 0xffffffff);
+	if (ret)
+		return ret;
+
+	udelay(10);
+
+	return 0;
+}
+
+/**
+ * speedy_fifo_reset() - reset FIFO of the controller
+ * @speedy:	pointer to speedy controller struct
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+static int speedy_fifo_reset(struct speedy_controller *speedy)
+{
+	int ret;
+
+	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL, SPEEDY_FIFO_RESET);
+	if (ret)
+		return ret;
+
+	udelay(10);
+
+	return 0;
+}
+
+/**
+ * _speedy_read() - internal speedy read operation
+ * @speedy:	pointer to speedy controller struct
+ * @reg:	address of device on the bus
+ * @addr:       address to read
+ * @val:        pointer to store result
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+static int _speedy_read(struct speedy_controller *speedy, u32 reg, u32 addr, u32 *val)
+{
+	int ret;
+	u32 cmd, int_ctl, int_status;
+
+	mutex_lock(&speedy->io_lock);
+
+	ret = speedy_fifo_reset(speedy);
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
+			      SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
+	if (ret)
+		return ret;
+
+	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_READ |
+	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
+
+	int_ctl = SPEEDY_TRANSFER_DONE_EN | SPEEDY_FIFO_RX_ALMOST_FULL_EN |
+		  SPEEDY_RX_FIFO_INT_TRAILER_EN | SPEEDY_RX_MODEBIT_ERR_EN |
+		  SPEEDY_RX_GLITCH_ERR_EN | SPEEDY_RX_ENDBIT_ERR_EN |
+		  SPEEDY_REMOTE_RESET_REQ_EN;
+
+	ret = speedy_int_clear(speedy);
+	if (ret)
+		return ret;
+
+	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
+	if (ret)
+		return ret;
+
+	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
+	if (ret)
+		return ret;
+
+	/* Wait for xfer done */
+	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
+				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(speedy->map, SPEEDY_RX_DATA, val);
+	if (ret)
+		return ret;
+
+	ret = speedy_int_clear(speedy);
+
+	mutex_unlock(&speedy->io_lock);
+
+	return ret;
+}
+
+int exynos_speedy_read(const struct speedy_device *device, u32 addr, u32 *val)
+{
+	return _speedy_read(device->speedy, device->reg, addr, val);
+}
+EXPORT_SYMBOL_GPL(exynos_speedy_read);
+
+/**
+ * _speedy_write() - internal speedy write operation
+ * @speedy:	pointer to speedy controller struct
+ * @reg:	address of device on the bus
+ * @addr:       address to write
+ * @val:        value to write
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+static int _speedy_write(struct speedy_controller *speedy, u32 reg, u32 addr, u32 val)
+{
+	int ret;
+	u32 cmd, int_ctl, int_status;
+
+	mutex_lock(&speedy->io_lock);
+
+	ret = speedy_fifo_reset(speedy);
+	if (ret)
+		return ret;
+
+	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
+			      SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
+	if (ret)
+		return ret;
+
+	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_WRITE |
+	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
+
+	int_ctl = (SPEEDY_TRANSFER_DONE_EN |
+		   SPEEDY_FIFO_TX_ALMOST_EMPTY_EN |
+		   SPEEDY_TX_LINE_BUSY_ERR_EN |
+		   SPEEDY_TX_STOPBIT_ERR_EN |
+		   SPEEDY_REMOTE_RESET_REQ_EN);
+
+	ret = speedy_int_clear(speedy);
+	if (ret)
+		return ret;
+
+	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
+	if (ret)
+		return ret;
+
+	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
+	if (ret)
+		return ret;
+
+	ret = regmap_write(speedy->map, SPEEDY_TX_DATA, val);
+	if (ret)
+		return ret;
+
+	/* Wait for xfer done */
+	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
+				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
+	if (ret)
+		return ret;
+
+	speedy_int_clear(speedy);
+
+	mutex_unlock(&speedy->io_lock);
+
+	return 0;
+}
+
+int exynos_speedy_write(const struct speedy_device *device, u32 addr, u32 val)
+{
+	return _speedy_write(device->speedy, device->reg, addr, val);
+}
+EXPORT_SYMBOL_GPL(exynos_speedy_write);
+
+static void devm_speedy_release(struct device *dev, void *res)
+{
+	const struct speedy_device **ptr = res;
+	const struct speedy_device *handle = *ptr;
+
+	kfree(handle);
+}
+
+/**
+ * speedy_get_by_phandle() - internal get speedy device handle
+ * @np:	pointer to OF device node of device
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+static const struct speedy_device *speedy_get_device(struct device_node *np)
+{
+	const struct of_device_id *speedy_id;
+	struct device_node *speedy_np;
+	struct platform_device *speedy_pdev;
+	struct speedy_controller *speedy = NULL;
+	struct speedy_device *handle;
+	int ret;
+
+	if (!np) {
+		pr_err("I need a device pointer\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	speedy_np = of_get_parent(np);
+	if (!speedy_np)
+		return ERR_PTR(-ENODEV);
+
+	/* Verify if parent node is a speedy controller */
+	speedy_id = of_match_node(speedy_match, speedy_np);
+	if (!speedy_id) {
+		handle = ERR_PTR(-EINVAL);
+		goto out;
+	}
+
+	/* Get platform device of the speedy controller */
+	speedy_pdev = of_find_device_by_node(speedy_np);
+	if (!speedy_pdev) {
+		handle = ERR_PTR(-EPROBE_DEFER);
+		goto out;
+	}
+
+	/* Get drvdata of speedy controller */
+	speedy = platform_get_drvdata(speedy_pdev);
+	if (!speedy) {
+		handle = ERR_PTR(-EINVAL);
+		goto out;
+	}
+
+	handle = kzalloc(sizeof(struct speedy_device), GFP_KERNEL);
+	if (!handle) {
+		handle = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+	handle->speedy = speedy;
+	ret = of_property_read_u32(np, "reg", &handle->reg);
+	if (ret) {
+		kfree(handle);
+		handle = ERR_PTR(-EINVAL);
+		goto out;
+	}
+
+out:
+	of_node_put(speedy_np);
+	return handle;
+}
+
+const struct speedy_device *devm_speedy_get_device(struct device *dev)
+{
+	const struct speedy_device *handle;
+	const struct speedy_device **ptr;
+
+	ptr = devres_alloc(devm_speedy_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	handle = speedy_get_device(dev_of_node(dev));
+	if (!IS_ERR(handle)) {
+		*ptr = handle;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return handle;
+}
+EXPORT_SYMBOL_GPL(devm_speedy_get_device);
+
+static int speedy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct speedy_controller *speedy;
+	void __iomem *mem;
+	int ret;
+
+	speedy = devm_kzalloc(dev, sizeof(struct speedy_controller), GFP_KERNEL);
+	if (!speedy)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, speedy);
+	speedy->pdev = pdev;
+
+	mutex_init(&speedy->io_lock);
+
+	mem = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(mem))
+		return dev_err_probe(dev, PTR_ERR(mem), "Failed to ioremap memory\n");
+
+	speedy->map = devm_regmap_init_mmio(dev, mem, &speedy_map_cfg);
+	if (IS_ERR(speedy->map))
+		return dev_err_probe(dev, PTR_ERR(speedy->map), "Failed to init the regmap\n");
+
+	/* Clear any interrupt status remaining */
+	ret = speedy_int_clear(speedy);
+	if (ret)
+		return ret;
+
+	/* Reset the controller */
+	ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_SW_RST);
+	if (ret)
+		return ret;
+
+	msleep(20);
+
+	/* Enable the hw */
+	ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_ENABLE);
+	if (ret)
+		return ret;
+
+	msleep(20);
+
+	/* Probe child devices */
+	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev);
+	if (ret)
+		dev_err(dev, "Failed to populate child devices: %d\n", ret);
+
+	return ret;
+}
+
+static struct platform_driver speedy_driver = {
+	.probe = speedy_probe,
+	.driver = {
+		.name = "exynos-speedy",
+		.of_match_table = speedy_match,
+	},
+};
+
+module_platform_driver(speedy_driver);
+
+MODULE_DESCRIPTION("Samsung Exynos SPEEDY host controller driver");
+MODULE_AUTHOR("Markuss Broks <markuss.broks at gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/soc/samsung/exynos-speedy.h b/include/linux/soc/samsung/exynos-speedy.h
new file mode 100644
index 0000000000000000000000000000000000000000..b2857d65d3b50927373866dd8ae1c47e98af6d7b
--- /dev/null
+++ b/include/linux/soc/samsung/exynos-speedy.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2024, Markuss Broks <markuss.broks at gmail.com>
+ * Copyright 2024, Maksym Holovach <nergzd at nergzd723.xyz>
+ */
+
+#ifndef __EXYNOS_SPEEDY_H
+#define __EXYNOS_SPEEDY_H
+
+#include <linux/types.h>
+
+struct device;
+struct mutex;
+struct platform_device;
+struct regmap;
+
+struct speedy_controller {
+	struct mutex io_lock;
+	struct platform_device *pdev;
+	struct regmap *map;
+};
+
+struct speedy_device {
+	u32 reg;
+	struct speedy_controller *speedy;
+};
+
+/**
+ * exynos_speedy_read() - exynos speedy read operation
+ * @device:	pointer to speedy device struct
+ * @addr:       address to read
+ * @val:        pointer to store result
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+int exynos_speedy_read(const struct speedy_device *device, u32 addr, u32 *val);
+
+/**
+ * exynos_speedy_write() - exynos speedy write operation
+ * @device:	pointer to speedy device struct
+ * @addr:       address to write
+ * @val:        value to write
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+int exynos_speedy_write(const struct speedy_device *device, u32 addr, u32 val);
+
+/**
+ * devm_speedy_get_device() - managed get speedy device.
+ * @dev:	device pointer requesting speedy device handle.
+ *
+ * Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
+ */
+const struct speedy_device *devm_speedy_get_device(struct device *dev);
+
+#endif /* __EXYNOS_SPEEDY_H */

-- 
2.47.0



From markuss.broks at gmail.com  Thu Dec 12 13:09:03 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Thu, 12 Dec 2024 23:09:03 +0200
Subject: [PATCH 3/3] MAINTAINERS: Add entry for the Samsung Exynos SPEEDY
 host controller
In-Reply-To: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
Message-ID: <20241212-speedy-v1-3-544ad7bcfb6a@gmail.com>

Add an entry adding myself as a maintainer of the Exynos SPEEDY
host controller driver.

Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bf2dcd4e0261785add520b5eac747ceac523e112..14041c5373df76c7a7093f106dded1080b5d8664 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20754,6 +20754,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/rng/samsung,exynos4-rng.yaml
 F:	drivers/crypto/exynos-rng.c
 
+SAMSUNG EXYNOS SPEEDY SERIAL HOST CONTROLLER DRIVER
+M:	Markuss Broks <markuss.broks at gmail.com>
+L:	linux-samsung-soc at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml
+F:	drivers/soc/samsung/exynos-speedy.c
+
 SAMSUNG EXYNOS TRUE RANDOM NUMBER GENERATOR (TRNG) DRIVER
 M:	?ukasz Stelmach <l.stelmach at samsung.com>
 L:	linux-samsung-soc at vger.kernel.org

-- 
2.47.0



From markuss.broks at gmail.com  Thu Dec 12 13:09:00 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Thu, 12 Dec 2024 23:09:00 +0200
Subject: [PATCH 0/3] Add Samsung SPEEDY serial bus host controller driver
Message-ID: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>

Hey,

This series adds support for the Samsung SPEEDY serial bus host
controller. Samsung SPEEDY (actually an acronym) is a proprietary
Samsung 1 wire serial bus, which is used on various Samsung devices.

This driver adds support for the version of controller without the
IP_BATCHER block. It appears that block is a small MCU attached to
the SPEEDY controller to offload the SPEEDY I/O tasks from the AP.
IP_BATCHER is found on Exynos7885, but not found on Exynos9810 and
Exynos8895. This version of driver should still work on Exynos7885
though, but the IP_BATCHER is not supported at the moment.

On Exynos9810, SPEEDY controllers are also mapped into MMIO space
of other processors on the CPU. For example, APM also has a window
to the SPEEDY IP, and it uses it for power-management related things.
During testing however, it seems that if APM is not active the AP can
access the SPEEDY controller freely and without interference from APM
firmware.

Things to improve:

- SPEEDY host controller has an interrupt line to the AP, but current
implementation uses polling instead,
- add support for handling IP_BATCHER block,
- add support for bulk transfers,
- test on other SoCs (Exynos9820, 9830, 9840, ...).
- runtime PM

- Markuss

To: Rob Herring <robh at kernel.org>
To: Krzysztof Kozlowski <krzk+dt at kernel.org>
To: Conor Dooley <conor+dt at kernel.org>
To: Alim Akhtar <alim.akhtar at samsung.com>
To: Krzysztof Kozlowski <krzk at kernel.org>
Cc: linux-samsung-soc 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: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>

Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
---
Markuss Broks (3):
      dt-bindings: soc: samsung: exynos-speedy: Document SPEEDY host controller bindings
      soc: samsung: Add a driver for Samsung SPEEDY host controller
      MAINTAINERS: Add entry for the Samsung Exynos SPEEDY host controller

 .../bindings/soc/samsung/exynos-speedy.yaml        |  78 ++++
 MAINTAINERS                                        |   7 +
 drivers/soc/samsung/Kconfig                        |  13 +
 drivers/soc/samsung/Makefile                       |   2 +
 drivers/soc/samsung/exynos-speedy.c                | 457 +++++++++++++++++++++
 include/linux/soc/samsung/exynos-speedy.h          |  56 +++
 6 files changed, 613 insertions(+)
---
base-commit: 1b2ab8149928c1cea2d7eca30cd35bb7fe014053
change-id: 20241210-speedy-e43f5df2b1d6

Best regards,
-- 
Markuss Broks <markuss.broks at gmail.com>



From nicolinc at nvidia.com  Thu Dec 12 13:10:41 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 12 Dec 2024 13:10:41 -0800
Subject: [PATCH v2 01/13] iommufd/fault: Add an iommufd_fault_init()
 helper
In-Reply-To: <BN9PR11MB5276A65935F9E6339FBA49918C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <3bc49512a42b88130cf447a7ac10acf5c02e056c.1733263737.git.nicolinc@nvidia.com>
 <BN9PR11MB5276A65935F9E6339FBA49918C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <Z1tRUWZrSWJRW4J7@Asurada-Nvidia>

On Wed, Dec 11, 2024 at 07:27:40AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc at nvidia.com>
> > Sent: Wednesday, December 4, 2024 6:10 AM
> > 
> > +static int iommufd_fault_init(struct iommufd_fault *fault, char *name,
> > +			      struct iommufd_ctx *ictx)
> > +{
> > +	struct file *filep;
> > +	int fdno;
> > +
> > +	fault->ictx = ictx;
> 
> while at it could you move this line behind iommufd_ctx_get(fault->ictx).
> usually we want the two together.

Sure. Consider it done.

> Reviewed-by: Kevin Tian <kevin.tian at intel.com>

Thanks!
Nic


From Liam.Howlett at oracle.com  Thu Dec 12 13:13:46 2024
From: Liam.Howlett at oracle.com (Liam R. Howlett)
Date: Thu, 12 Dec 2024 16:13:46 -0500
Subject: [PATCH mm-unstable v2 05/16] mm: arc: Use generic_mmap_hint()
In-Reply-To: <20241211232754.1583023-6-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
 <20241211232754.1583023-6-kaleshsingh@google.com>
Message-ID: <z2jiw4hnmzh6wuutxsbquap4whtbv7qax7usvnmoqephqrirsp@dk2zfods6xvm>

* Kalesh Singh <kaleshsingh at google.com> [241211 18:28]:
> Introduce arc arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
> This is a preparatory patch, no functional change is introduced.

You have changed the order of the map fixed check and the len check.

I *think* what you have done is correct, but your comment is certainly
wrong.

Your generic call also has more checks than exist in this version of the
code - which, again is probably good, but a functional change surely?

> 
> Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
> ---
> 
> Changes in v2:
>   - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
>     special case of the hint addr being "enforced", per Yang Shi.
>   - Consolidate error handling in arch_mmap_hint().
> 
>  arch/arc/include/asm/pgtable.h |  1 +
>  arch/arc/mm/mmap.c             | 43 +++++++++++++++++-----------------
>  2 files changed, 23 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
> index 4cf45a99fd79..af3210ea4888 100644
> --- a/arch/arc/include/asm/pgtable.h
> +++ b/arch/arc/include/asm/pgtable.h
> @@ -28,6 +28,7 @@ extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
>  
>  /* to cope with aliasing VIPT cache */
>  #define HAVE_ARCH_UNMAPPED_AREA
> +#define HAVE_ARCH_MMAP_HINT
>  
>  #endif /* __ASSEMBLY__ */
>  
> diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c
> index 2185afe8d59f..df01d4d9964b 100644
> --- a/arch/arc/mm/mmap.c
> +++ b/arch/arc/mm/mmap.c
> @@ -14,6 +14,26 @@
>  
>  #include <asm/cacheflush.h>
>  
> +unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
> +			     unsigned long len, unsigned long pgoff,
> +			     unsigned long flags)
> +{
> +	if (len > TASK_SIZE)
> +		return -ENOMEM;
> +
> +	/*
> +	 * We enforce the MAP_FIXED case.
> +	 */
> +	if (flags & MAP_FIXED) {
> +		if (flags & MAP_SHARED &&
> +		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
> +			return -EINVAL;
> +		return addr;
> +	}
> +
> +	return generic_mmap_hint(filp, addr, len, pgoff, flags);
> +}
> +
>  /*
>   * Ensure that shared mappings are correctly aligned to
>   * avoid aliasing issues with VIPT caches.
> @@ -27,30 +47,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
>  		unsigned long flags, vm_flags_t vm_flags)
>  {
>  	struct mm_struct *mm = current->mm;
> -	struct vm_area_struct *vma;
>  	struct vm_unmapped_area_info info = {};
>  
> -	/*
> -	 * We enforce the MAP_FIXED case.
> -	 */
> -	if (flags & MAP_FIXED) {
> -		if (flags & MAP_SHARED &&
> -		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
> -			return -EINVAL;
> +	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
> +	if (addr)
>  		return addr;
> -	}
> -
> -	if (len > TASK_SIZE)
> -		return -ENOMEM;
> -
> -	if (addr) {
> -		addr = PAGE_ALIGN(addr);
> -
> -		vma = find_vma(mm, addr);
> -		if (TASK_SIZE - len >= addr &&
> -		    (!vma || addr + len <= vm_start_gap(vma)))
> -			return addr;
> -	}
>  
>  	info.length = len;
>  	info.low_limit = mm->mmap_base;
> -- 
> 2.47.0.338.g60cca15819-goog
> 
> 


From nicolinc at nvidia.com  Thu Dec 12 13:15:43 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 12 Dec 2024 13:15:43 -0800
Subject: [PATCH v2 03/13] iommufd: Rename IOMMUFD_OBJ_FAULT to
 IOMMUFD_OBJ_EVENTQ_IOPF
In-Reply-To: <BN9PR11MB5276F92171A516C2A17839458C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <2e2dc5c9cd8013147d4a8ee0d6c9d59c9ebe1954.1733263737.git.nicolinc@nvidia.com>
 <BN9PR11MB5276F92171A516C2A17839458C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <Z1tSf+z0fvl2wTGU@Asurada-Nvidia>

On Wed, Dec 11, 2024 at 07:40:52AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc at nvidia.com>
> > Sent: Wednesday, December 4, 2024 6:10 AM
> > 
> > The fault object was designed exclusively for hwpt's IO page faults (PRI).
> > But its implementation can actually be reused for other purposes too, such
> > as hardware IRQ and event injections to user space.
> > 
> > Meanwhile, a fault object holds a list of faults. So it's more accurate to
> > call it a "fault queue". Combining the reusing idea above, a "fault queue"
> > can further rephrase to an "Event Queue for IOPF".
> > 
> > Rename the struct iommufd_fault to struct iommufd_eventq_iopf that holds
> > a
> > common Event Queue struct, similar to hwpt_paging holding a common
> > hwpt.
> > 
> > Roll out a minimal level of renamings to all the related functions.
> 
> could we keep iommufd_fault? Internally it will use the new eventq
> common struct but external facing names are all still around fault.
> the size of changed lines will be much smaller.
> 
> Then later for virq it could be iommufd_viommu_virq instead of
> iommufd_eventq_virq to explicitly draw its connection to viommu.
> 
> this is unlike hwpt where 'paging' or 'nested' is just decorative while
> 'fault' or 'virq' is noun on its own. 

It's a personal preference, though I don't have a strong opinion
about it. I can change them to iommufd_fault and iommufd_virq --
feels nicer to align with the other iommufd_v*: iommufd_vdevice,
iommufd_vqueue..

> > +static ssize_t iommufd_eventq_fops_read(struct file *filep, char __user *buf,
> > +					size_t count, loff_t *ppos)
> > +{
> > +	struct iommufd_eventq *eventq = filep->private_data;
> > +
> > +	if (!eventq->ops || !eventq->ops->read)
> > +		return -EOPNOTSUPP;
> > +	return eventq->ops->read(eventq, buf, count, ppos);
> > +}
> 
> the check on ops can be done in iommufd_eventq_init()

Ack. I think that's fine since we don't have a !ops->read case.

Thanks
Nic


From nicolinc at nvidia.com  Thu Dec 12 13:20:13 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 12 Dec 2024 13:20:13 -0800
Subject: [PATCH v2 05/13] iommufd: Add IOMMUFD_OBJ_EVENTQ_VIRQ and
 IOMMUFD_CMD_VIRQ_ALLOC
In-Reply-To: <BN9PR11MB52767F481C7D05EB1BDFD7D48C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <7f5f7adc2493c7bca7edf76ca15b377c8dc0d397.1733263737.git.nicolinc@nvidia.com>
 <BN9PR11MB52767F481C7D05EB1BDFD7D48C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <Z1tTjaJ2dyueFjWy@Asurada-Nvidia>

On Wed, Dec 11, 2024 at 07:55:53AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc at nvidia.com>
> > Sent: Wednesday, December 4, 2024 6:10 AM
> > +
> > +/* An iommufd_virq represents a vIOMMU interrupt in an eventq_virq
> > queue */
> > +struct iommufd_virq {
> > +	struct iommufd_eventq_virq *eventq_virq;
> > +	struct list_head node;
> > +	ssize_t irq_len;
> > +	void *irq_data;
> > +};
> 
> looks the only use of eventq_virq is in below:
> 
> > +
> > +static inline int iommufd_eventq_virq_handler(struct iommufd_virq *virq)
> > +{
> > +	return iommufd_eventq_notify(&virq->eventq_virq->common,
> > &virq->node);
> > +}
> 
> If there is no other intended usages upon that field, it's simpler to
> remove it and directly pass the pointer in when the handler is 
> called. Anyway iommufd_viommu_report_irq() needs to find the
> eventq first before calling it.

OK.

> > +/**
> > + * struct iommu_virq_alloc - ioctl(IOMMU_VIRQ_ALLOC)
> > + * @size: sizeof(struct iommu_virq_alloc)
> > + * @flags: Must be 0
> > + * @viommu: virtual IOMMU ID to associate the virtual IRQ with
> > + * @type: Type of the virtual IRQ. Must be defined in enum
> > iommu_virq_type
> > + * @out_virq_id: The ID of the new virtual IRQ
> > + * @out_fault_fd: The fd of the new virtual IRQ. User space must close the
> > + *                successfully returned fd after using it
> 
> s/out_fault_fd/out_virq_fd/
> 
> > + *
> > + * Explicitly allocate a virtual IRQ handler for a vIOMMU. A vIOMMU can
> > have
> > + * multiple FDs for different @type, but is confined to one FD per @type.
> > + */
> 
> s/handler/interface/
> 
> > +
> > +	eventq_virq->irq_wq = alloc_workqueue("viommu_irq/%d",
> > WQ_UNBOUND, 0,
> > +					      eventq_virq->common.obj.id);
> > +	if (!eventq_virq->irq_wq) {
> > +		rc = -ENOMEM;
> > +		goto out_put_fdno;
> > +	}
> 
> there is no use of this wq

Oops. Looks like I forgot to clean it up.

> > @@ -335,6 +335,8 @@ static const struct iommufd_ioctl_op
> > iommufd_ioctl_ops[] = {
> >  	IOCTL_OP(IOMMU_DESTROY, iommufd_destroy, struct
> > iommu_destroy, id),
> >  	IOCTL_OP(IOMMU_FAULT_QUEUE_ALLOC,
> > iommufd_eventq_iopf_alloc,
> >  		 struct iommu_fault_alloc, out_fault_fd),
> > +	IOCTL_OP(IOMMU_VIRQ_ALLOC, iommufd_eventq_virq_alloc,
> > +		 struct iommu_virq_alloc, out_virq_fd),
> 
> sort it in alphabetical order.

Ack.

Thanks
Nic


From nicolinc at nvidia.com  Thu Dec 12 13:21:10 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 12 Dec 2024 13:21:10 -0800
Subject: [PATCH v2 06/13] iommufd/viommu: Add iommufd_viommu_get_vdev_id
 helper
In-Reply-To: <BN9PR11MB52769AB45C92A820CC5233068C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <d1e5f16d2fa4e9950e9caa93c5f98a5115c1580f.1733263737.git.nicolinc@nvidia.com>
 <BN9PR11MB52769AB45C92A820CC5233068C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <Z1tTxmgLhIQkAyTj@Asurada-Nvidia>

On Wed, Dec 11, 2024 at 08:02:48AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc at nvidia.com>
> > Sent: Wednesday, December 4, 2024 6:10 AM
> > 
> > +/* Return 0 if device is not associated to the vIOMMU */
> > +unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu
> > *viommu,
> > +					 struct device *dev)
> > +{
> > +	struct iommufd_vdevice *vdev;
> > +	unsigned long vdev_id = 0;
> > +	unsigned long index;
> > +
> > +	xa_lock(&viommu->vdevs);
> > +	xa_for_each(&viommu->vdevs, index, vdev) {
> > +		if (vdev && vdev->dev == dev)
> 
> xa_for_each only find valid entries, so if (vdev) is redundant?
> 
> > +			vdev_id = (unsigned long)vdev->id;
> 
> break out of the loop if hit.

Yea, missed that.

Thanks!
Nic


From nicolinc at nvidia.com  Thu Dec 12 13:23:31 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 12 Dec 2024 13:23:31 -0800
Subject: [PATCH v2 07/13] iommufd/viommu: Add iommufd_viommu_report_irq
 helper
In-Reply-To: <BN9PR11MB52768F3CBE04513D1536EB9B8C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <7e9842376e6235d9e3471356d035afe2bfe8f33b.1733263737.git.nicolinc@nvidia.com>
 <BN9PR11MB52768F3CBE04513D1536EB9B8C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <Z1tUU1Nfvyr5zrtf@Asurada-Nvidia>

On Wed, Dec 11, 2024 at 08:05:45AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc at nvidia.com>
> > Sent: Wednesday, December 4, 2024 6:10 AM
> > 
> > +/* Typically called in driver's threaded IRQ handler */
> > +int iommufd_viommu_report_irq(struct iommufd_viommu *viommu,
> > unsigned int type,
> > +			      void *irq_ptr, size_t irq_len)
> > +{
> > +	struct iommufd_eventq_virq *eventq_virq;
> > +	struct iommufd_virq *virq;
> > +	int rc = 0;
> > +
> > +	might_sleep();
> 
> why is it required here but not in the iopf path?

It might not be that *required* as there is a might_sleep inside
the down_read(). So, I can drop this.

> > +
> > +	if (!viommu)
> > +		return -ENODEV;
> > +	if (WARN_ON_ONCE(!irq_len || !irq_ptr))
> > +		return -EINVAL;
> > +
> > +	down_read(&viommu->virqs_rwsem);
> > +
> > +	eventq_virq = iommufd_viommu_find_eventq_virq(viommu, type);
> > +	if (!eventq_virq) {
> > +		rc = -EOPNOTSUPP;
> > +		goto out_unlock_vdev_ids;
> 
> s/out_unlock_vdev_ids/out_unlock_virqs/

Yes..

Thanks!
Nic


From nicolinc at nvidia.com  Thu Dec 12 13:28:08 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 12 Dec 2024 13:28:08 -0800
Subject: [PATCH v2 11/13] Documentation: userspace-api: iommufd: Update
 EVENTQ_IOPF and EVENTQ_VIRQ
In-Reply-To: <BN9PR11MB5276E09D5F2206804A7C15968C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <a5025cbbd16f9c12dcaae7a14868419f17ce1d16.1733263737.git.nicolinc@nvidia.com>
 <BN9PR11MB5276E09D5F2206804A7C15968C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <Z1tVaIdD4lAjpP8e@Asurada-Nvidia>

On Wed, Dec 11, 2024 at 08:11:03AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc at nvidia.com>
> > Sent: Wednesday, December 4, 2024 6:10 AM
> > 
> > With the introduction of the new objects, update the doc to reflect that.
> > 
> > Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
> > ---
> >  Documentation/userspace-api/iommufd.rst | 19 +++++++++++++++++++
> >  1 file changed, 19 insertions(+)
> > 
> > diff --git a/Documentation/userspace-api/iommufd.rst
> > b/Documentation/userspace-api/iommufd.rst
> > index 70289d6815d2..798520d9344d 100644
> > --- a/Documentation/userspace-api/iommufd.rst
> > +++ b/Documentation/userspace-api/iommufd.rst
> > @@ -63,6 +63,14 @@ Following IOMMUFD objects are exposed to userspace:
> >    space usually has mappings from guest-level I/O virtual addresses to guest-
> >    level physical addresses.
> > 
> > +- IOMMUFD_OBJ_EVENTQ_IOPF, representing a software queue for an
> > HWPT_NESTED
> 
> now it can be used on paging hwpt too

Oh, that's why it's in the common path in the hwpt allocator...

Seems that we are missing its selftest coverage for paging hwpt?

> > +  reporting IO Page Fault using the IOMMU HW's PRI (Page Request
> > Interface).
> > +  This queue object provides user space an FD to poll the page fault events
> > +  and also to respond to those events. An EVENTQ_IOPF object must be
> > created
> > +  first to get a fault_id that could be then used to allocate an HWPT_NESTED
> > +  via the IOMMU_HWPT_ALLOC command setting
> > IOMMU_HWPT_FAULT_ID_VALID set in
> > +  its flags field.
> > +
> >  - IOMMUFD_OBJ_VIOMMU, representing a slice of the physical IOMMU
> > instance,
> >    passed to or shared with a VM. It may be some HW-accelerated
> > virtualization
> >    features and some SW resources used by the VM. For examples:
> > @@ -109,6 +117,15 @@ Following IOMMUFD objects are exposed to
> > userspace:
> >    vIOMMU, which is a separate ioctl call from attaching the same device to an
> >    HWPT_PAGING that the vIOMMU holds.
> > 
> > +- IOMMUFD_OBJ_EVENTQ_VIRQ, representing a software queue for
> > IOMMUFD_OBJ_VIOMMU
> > +  reporting its non-affiliated events, such as translation faults occurred to a
> 
> non-affiliated is only mentioned here. It's not a standard term in this
> area. Sticking to the later examples in 'such as' is straightforward.

OK.

> > +  nested stage-1 and HW-specific events/irqs e.g. events to invalidation
> > queues
> > +  that are assigned to VMs via vIOMMUs. This queue object provides user
> 
> vcmdq is not supported yet. add it later.

Ack.

Thanks
Nic


From nicolinc at nvidia.com  Thu Dec 12 13:31:14 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 12 Dec 2024 13:31:14 -0800
Subject: [PATCH v2 12/13] iommu/arm-smmu-v3: Introduce struct
 arm_smmu_vmaster
In-Reply-To: <BN9PR11MB527669503B30B7C67907DE398C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <6270c905fc8537ffc51f6f2ab2db0601c9f08a8d.1733263737.git.nicolinc@nvidia.com>
 <BN9PR11MB527669503B30B7C67907DE398C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <Z1tWIuiEFJyfSGEq@Asurada-Nvidia>

On Wed, Dec 11, 2024 at 08:15:35AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc at nvidia.com>
> > Sent: Wednesday, December 4, 2024 6:10 AM
> > 
> > Use it to store all vSMMU-related data. The vsid (Virtual Stream ID) will
> > be the first use case. Then, add a rw_semaphore to protect it.
> > 
> > Also add a pair of arm_smmu_attach_prepare/commit_vmaster helpers and
> > put
> > them in the existing arm_smmu_attach_prepare/commit(). Note that identity
> > and blocked ops don't call arm_smmu_attach_prepare/commit(), thus
> > simply
> > call the new helpers at the top.
> 
> Probably a dumb question. viommu is tied to a nested parent domain
> which cannot be identity or blocked. Why do we need to change them
> too?

For identity/blocked domains, prepare() would return 0 without
allocating a vmaster pointer, so later on commit() would update
master->vmaster with a NULL, i.e. it's a cleanup routine when
switching from a paging/dma domain to an identity/blocked one.

I will update the commit message to make this clear.

Thanks
Nic


From nicolinc at nvidia.com  Thu Dec 12 13:34:22 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 12 Dec 2024 13:34:22 -0800
Subject: [PATCH v2 13/13] iommu/arm-smmu-v3: Report IRQs that belong to
 devices attached to vIOMMU
In-Reply-To: <BN9PR11MB5276EE81D21EC5E4156EB7D58C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <cover.1733263737.git.nicolinc@nvidia.com>
 <d335936fdeccfcf785589800b7e5d9b1b26a766d.1733263737.git.nicolinc@nvidia.com>
 <BN9PR11MB5276EE81D21EC5E4156EB7D58C3E2@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <Z1tW3sZgrJfUzP1e@Asurada-Nvidia>

On Wed, Dec 11, 2024 at 08:21:42AM +0000, Tian, Kevin wrote:
> > From: Nicolin Chen <nicolinc at nvidia.com>
> > Sent: Wednesday, December 4, 2024 6:10 AM
> > 
> > +
> > +/**
> > + * struct iommu_virq_arm_smmuv3 - ARM SMMUv3 Virtual IRQ
> > + *                                (IOMMU_VIRQ_TYPE_ARM_SMMUV3)
> > + * @evt: 256-bit ARM SMMUv3 Event record, little-endian.
> > + *
> > + * StreamID field reports a virtual device ID. To receive a virtual IRQ for a
> > + * device, a vDEVICE must be allocated via IOMMU_VDEVICE_ALLOC.
> > + */
> 
> similar to what's provided for iommu_hw_info_arm_smmuv3, it'd be
> good to refer to a section in smmu spec for bit definitions.

Ack.

> >  	mutex_lock(&smmu->streams_mutex);
> >  	master = arm_smmu_find_master(smmu, sid);
> >  	if (!master) {
> > @@ -1813,7 +1786,40 @@ static int arm_smmu_handle_evt(struct
> > arm_smmu_device *smmu, u64 *evt)
> >  		goto out_unlock;
> >  	}
> > 
> > -	ret = iommu_report_device_fault(master->dev, &fault_evt);
> > +	down_read(&master->vmaster_rwsem);
> 
> this lock is not required if event is EVTQ_1_STALL?

No. It only protects master->vmaster. Perhaps I can rewrite this
piece to exclude the lock from the EVTQ_1_STALL chunk.

> > +	if (evt[1] & EVTQ_1_STALL) {
> > +		if (evt[1] & EVTQ_1_RnW)
> > +			perm |= IOMMU_FAULT_PERM_READ;
> > +		else
> > +			perm |= IOMMU_FAULT_PERM_WRITE;
> > +
> > +		if (evt[1] & EVTQ_1_InD)
> > +			perm |= IOMMU_FAULT_PERM_EXEC;
> > +
> > +		if (evt[1] & EVTQ_1_PnU)
> > +			perm |= IOMMU_FAULT_PERM_PRIV;
> > +
> > +		flt->type = IOMMU_FAULT_PAGE_REQ;
> > +		flt->prm = (struct iommu_fault_page_request){
> > +			.flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
> > +			.grpid = FIELD_GET(EVTQ_1_STAG, evt[1]),
> > +			.perm = perm,
> > +			.addr = FIELD_GET(EVTQ_2_ADDR, evt[2]),
> > +		};
> > +
> > +		if (ssid_valid) {
> > +			flt->prm.flags |=
> > IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
> > +			flt->prm.pasid = FIELD_GET(EVTQ_0_SSID, evt[0]);
> > +		}
> > +
> > +		ret = iommu_report_device_fault(master->dev, &fault_evt);
> > +	} else if (master->vmaster && !(evt[1] & EVTQ_1_S2)) {
> > +		ret = arm_vmaster_report_event(master->vmaster, evt);

Thanks
Nic


From ebiggers at kernel.org  Thu Dec 12 13:36:52 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Thu, 12 Dec 2024 13:36:52 -0800
Subject: [PATCH v2 00/12] Wire up CRC-T10DIF library functions to
 arch-optimized code
In-Reply-To: <20241202012056.209768-1-ebiggers@kernel.org>
References: <20241202012056.209768-1-ebiggers@kernel.org>
Message-ID: <20241212213652.GA39696@sol.localdomain>

On Sun, Dec 01, 2024 at 05:20:44PM -0800, Eric Biggers wrote:
> This patchset is also available in git via:
> 
>     git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git crc-t10dif-lib-v2
> 
> This patchset updates the kernel's CRC-T10DIF library functions to be
> directly optimized for x86, arm, arm64, and powerpc without taking an
> unnecessary and inefficient detour through the crypto API.  It follows
> the same approach that I'm taking for CRC32 in the patchset
> https://lore.kernel.org/lkml/20241202010844.144356-1-ebiggers at kernel.org/
> 
> This patchset also adds a CRC KUnit test suite that covers multiple CRC
> variants, and deletes some older ad-hoc tests that are obsoleted by it.
> 
> This patchset applies to v6.13-rc1 plus my CRC32 patchset.  It can be
> retrieved from git using above command.  This is targeting 6.14.
> 
> Changed in v2:
>   - Rebased onto v6.13-rc1.
>   - Tweaked crc_t10dif_arch() for arm32 and arm64 to not call
>     crypto_simd_usable() more times than is necessary.
>   - Added patch removing redundant crc16_kunit.c which got added in v6.13-rc1.
>   - Made some small tweaks to crc_kunit.c.
>   - Listed Ard as a reviewer in the MAINTAINERS entry.
>   - Dropped scripts/crc from MAINTAINERS entry, as it hasn't been added yet.
>   - Clarified a commit message.
>   - Added Reviewed-by and Acked-by's.

FYI, this patchset is now in linux-next via the crc-next branch in my repo.
Additional reviews and acks would always be appreciated, of course.

- Eric


From ebiggers at kernel.org  Thu Dec 12 13:37:34 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Thu, 12 Dec 2024 13:37:34 -0800
Subject: [PATCH v4 00/19] Wire up CRC32 library functions to
 arch-optimized code
In-Reply-To: <20241202010844.144356-1-ebiggers@kernel.org>
References: <20241202010844.144356-1-ebiggers@kernel.org>
Message-ID: <20241212213734.GB39696@sol.localdomain>

On Sun, Dec 01, 2024 at 05:08:25PM -0800, Eric Biggers wrote:
> This patchset applies to v6.13-rc1 and is also available in git via:
> 
>     git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git crc32-lib-v4
> 
> CRC32 is a family of common non-cryptographic integrity check algorithms
> that are fairly fast with a portable C implementation and become far
> faster still with the CRC32 or carryless multiplication instructions
> that most CPUs have.  9 architectures already have optimized code for at
> least some CRC32 variants; however, except for arm64 this optimized code
> was only accessible through the crypto API, not the library functions.
> 
> This patchset fixes that so that the CRC32 library functions use the
> optimized code.  This allows users to just use the library instead of
> the crypto API.  This is much simpler and also improves performance due
> to eliminating the crypto API overhead including an indirect call.  Some
> examples of updating users are included at the end of the patchset.

FYI, this patchset is now in linux-next via the crc-next branch in my repo.
Additional reviews and acks would always be appreciated, of course.

- Eric


From Liam.Howlett at oracle.com  Thu Dec 12 13:40:10 2024
From: Liam.Howlett at oracle.com (Liam R. Howlett)
Date: Thu, 12 Dec 2024 16:40:10 -0500
Subject: [PATCH mm-unstable v2 06/16] mm: csky: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-7-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
 <20241211232754.1583023-7-kaleshsingh@google.com>
Message-ID: <vc2uhcysgosapznbuookcj5677w43a4kzxbotwqub237ccawww@i3pbqiacdwsx>

* Kalesh Singh <kaleshsingh at google.com> [241211 18:28]:
> Introduce csky arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
> This is a preparatory patch, no functional change is introduced.

This also looks like it has changed the validation order and potentially
introduced functional changes?

All these stem from the same cloned code (sparc32 iirc), but were not
updated when the cloned code was updated.  This is why I am against
arch_* code.  We should find a better way to unify the code so that
there is nothing different.  You seem to have gotten some of the shared
code together, but some still exists.

In the addresses, there are upper and lower limits, and sometimes
"colours".  Could we not just define the upper/lower limits in each arch
and if colour is used?  Maybe this is complicated with 32/64 handled
both in the 64 bit code.

Is there any plan to unite this code further?

We have had errors for many years in cloned but not updated code.  I
really wish there was more information in the cover letter on what is
going on here.  I'd like to try and reduce the arch_ code to, basically
nothing.

I was also disappointed that I wasn't Cc'ed because I've spent a lot of
time in this code and this area.  I am probably the last one to crawl
through and change any of this.


> 
> Signed-off-by: Kalesh Singh <kaleshsingh at google.com>
> ---
> 
> Changes in v2:
>   - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
>     special case of the hint addr being "enforced", per Yang Shi.
>   - Consolidate error handling in arch_mmap_hint().
> 
>  arch/csky/abiv1/inc/abi/pgtable-bits.h |  1 +
>  arch/csky/abiv1/mmap.c                 | 68 ++++++++++++++------------
>  2 files changed, 38 insertions(+), 31 deletions(-)
> 
> diff --git a/arch/csky/abiv1/inc/abi/pgtable-bits.h b/arch/csky/abiv1/inc/abi/pgtable-bits.h
> index ae7a2f76dd42..c346a9fcb522 100644
> --- a/arch/csky/abiv1/inc/abi/pgtable-bits.h
> +++ b/arch/csky/abiv1/inc/abi/pgtable-bits.h
> @@ -51,5 +51,6 @@
>  					((offset) << 10)})
>  
>  #define HAVE_ARCH_UNMAPPED_AREA
> +#define HAVE_ARCH_MMAP_HINT
>  
>  #endif /* __ASM_CSKY_PGTABLE_BITS_H */
> diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c
> index 1047865e82a9..0c5c51a081e4 100644
> --- a/arch/csky/abiv1/mmap.c
> +++ b/arch/csky/abiv1/mmap.c
> @@ -13,6 +13,39 @@
>  	((((addr)+SHMLBA-1)&~(SHMLBA-1)) +	\
>  	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
>  
> +unsigned long arch_mmap_hint(struct file *filp, unsigned long addr,
> +			     unsigned long len, unsigned long pgoff,
> +			     unsigned long flags)
> +{
> +	bool do_align;
> +
> +	if (len > TASK_SIZE)
> +		return -ENOMEM;
> +
> +	/*
> +	 * We only need to do colour alignment if either the I or D
> +	 * caches alias.
> +	 */
> +	do_align = filp || (flags & MAP_SHARED);
> +
> +	/*
> +	 * We enforce the MAP_FIXED case.
> +	 */
> +	if (flags & MAP_FIXED) {
> +		if (flags & MAP_SHARED &&
> +		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
> +			return -EINVAL;
> +		return addr;
> +	}
> +
> +	if (do_align)
> +		addr = COLOUR_ALIGN(addr, pgoff);
> +	else
> +		addr = PAGE_ALIGN(addr);
> +
> +	return generic_mmap_hint(filp, addr, len, pgoff, flags);
> +}
> +
>  /*
>   * We need to ensure that shared mappings are correctly aligned to
>   * avoid aliasing issues with VIPT caches.  We need to ensure that
> @@ -27,8 +60,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
>  		unsigned long flags, vm_flags_t vm_flags)
>  {
>  	struct mm_struct *mm = current->mm;
> -	struct vm_area_struct *vma;
> -	int do_align = 0;
> +	bool do_align;
>  	struct vm_unmapped_area_info info = {
>  		.length = len,
>  		.low_limit = mm->mmap_base,
> @@ -36,37 +68,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
>  		.align_offset = pgoff << PAGE_SHIFT
>  	};
>  
> -	/*
> -	 * We only need to do colour alignment if either the I or D
> -	 * caches alias.
> -	 */

This seems like useful information to keep around?

> -	do_align = filp || (flags & MAP_SHARED);
> -
> -	/*
> -	 * We enforce the MAP_FIXED case.
> -	 */
> -	if (flags & MAP_FIXED) {
> -		if (flags & MAP_SHARED &&
> -		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
> -			return -EINVAL;
> +	addr = arch_mmap_hint(filp, addr, len, pgoff, flags);
> +	if (addr)
>  		return addr;
> -	}
> -
> -	if (len > TASK_SIZE)
> -		return -ENOMEM;
> -
> -	if (addr) {
> -		if (do_align)
> -			addr = COLOUR_ALIGN(addr, pgoff);
> -		else
> -			addr = PAGE_ALIGN(addr);
> -
> -		vma = find_vma(mm, addr);
> -		if (TASK_SIZE - len >= addr &&
> -		    (!vma || addr + len <= vm_start_gap(vma)))
> -			return addr;
> -	}
>  
> +	do_align = filp || (flags & MAP_SHARED);
>  	info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
>  	return vm_unmapped_area(&info);
>  }
> -- 
> 2.47.0.338.g60cca15819-goog
> 
> 


From ninad at linux.ibm.com  Thu Dec 12 13:49:02 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Thu, 12 Dec 2024 15:49:02 -0600
Subject: [PATCH v1 3/4] dt-bindings: hwmon: intel,crps185: Add to trivial
In-Reply-To: <20241212214927.3586509-1-ninad@linux.ibm.com>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
Message-ID: <20241212214927.3586509-4-ninad@linux.ibm.com>

Add INTEL Common Redundant Power Supply Versions crps185 bindings as
trivial.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index 73a49d50c4ef..7d07b08b1459 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -151,6 +151,8 @@ properties:
           - injoinic,ip5306
             # Inspur Power System power supply unit version 1
           - inspur,ipsps1
+            # Intel common redudant power supply crps185
+          - intel,crps185
             # Intersil ISL29028 Ambient Light and Proximity Sensor
           - isil,isl29028
             # Intersil ISL29030 Ambient Light and Proximity Sensor
-- 
2.43.0



From ninad at linux.ibm.com  Thu Dec 12 13:49:01 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Thu, 12 Dec 2024 15:49:01 -0600
Subject: [PATCH v1 2/4] hwmon: (pmbus/crps) Add Intel CRPS185 power supply
In-Reply-To: <20241212214927.3586509-1-ninad@linux.ibm.com>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
Message-ID: <20241212214927.3586509-3-ninad@linux.ibm.com>

Add the driver to monitor Intel common redundant power supply (crps185)
with hwmon over pmbus.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 Documentation/hwmon/crps.rst |  95 +++++++++++
 MAINTAINERS                  |   7 +
 drivers/hwmon/pmbus/Kconfig  |   9 ++
 drivers/hwmon/pmbus/Makefile |   1 +
 drivers/hwmon/pmbus/crps.c   | 299 +++++++++++++++++++++++++++++++++++
 5 files changed, 411 insertions(+)
 create mode 100644 Documentation/hwmon/crps.rst
 create mode 100644 drivers/hwmon/pmbus/crps.c

diff --git a/Documentation/hwmon/crps.rst b/Documentation/hwmon/crps.rst
new file mode 100644
index 000000000000..81d5dfd68a46
--- /dev/null
+++ b/Documentation/hwmon/crps.rst
@@ -0,0 +1,95 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver crps
+========================
+
+Supported chips:
+
+  * Intel CRPS185
+
+    Prefix: 'crps185'
+
+    Addresses scanned: -
+
+Authors:
+    Ninad Palsule <ninad at linux.ibm.com>
+
+
+Description
+-----------
+
+This driver implements support for Common Redundant Power supply with PMBus
+support.
+
+The driver is a client driver to the core PMBus driver.
+Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers.
+
+
+Usage Notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices.rst for
+details.
+
+
+Sysfs entries
+-------------
+
+======================= ======================================================
+curr1_label		"iin"
+curr1_input		Measured input current
+curr1_max		Maximum input current
+curr1_max_alarm         Input maximum current high alarm
+curr1_crit              Critial high input current
+curr1_crit_alarm        Input critical current high alarm
+curr1_rated_max		Maximum rated input current
+
+curr2_label		"iout1"
+curr2_input		Measured output current
+curr2_max		Maximum output current
+curr2_max_alarm         Output maximum current high alarm
+curr2_crit	        Critial high output current
+curr2_crit_alarm        Output critical current high alarm
+curr2_rated_max		Maximum rated output current
+
+in1_label		"vin"
+in1_input		Measured input voltage
+in1_crit                Critical input over voltage
+in1_crit_alarm          Critical input over voltage alarm
+in1_max                 Maximum input over voltage
+in1_max_alarm           Maximum input over voltage alarm
+in1_rated_min		Minimum rated input voltage
+in1_rated_max		Maximum rated input voltage
+
+in2_label		"vout1"
+in2_input		Measured input voltage
+in2_crit                Critical input over voltage
+in2_crit_alarm          Critical input over voltage alarm
+in2_lcrit               Critical input under voltage fault
+in2_lcrit_alarm         Critical input under voltage fault alarm
+in2_max                 Maximum input over voltage
+in2_max_alarm           Maximum input over voltage alarm
+in2_min                 Minimum input under voltage warning
+in2_min_alarm           Minimum input under voltage warning alarm
+in2_rated_min		Minimum rated input voltage
+in2_rated_max		Maximum rated input voltage
+
+power1_label		"pin"
+power1_input		Measured input power
+power1_alarm		Input power high alarm
+power1_max  		Maximum input power
+power1_rated_max        Maximum rated input power
+
+temp[1-2]_input		Measured temperature
+temp[1-2]_crit 		Critical temperature
+temp[1-2]_crit_alarm    Critical temperature alarm
+temp[1-2]_max  		Maximum temperature
+temp[1-2]_max_alarm     Maximum temperature alarm
+temp[1-2]_rated_max     Maximum rated temperature
+
+fan1_alarm		Fan 1 warning.
+fan1_fault		Fan 1 fault.
+fan1_input		Fan 1 speed in RPM.
+fan1_target             Fan 1 target.
+======================= ======================================================
diff --git a/MAINTAINERS b/MAINTAINERS
index 637ddd44245f..6b31d545f0f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6100,6 +6100,13 @@ L:	linux-input at vger.kernel.org
 S:	Maintained
 F:	drivers/hid/hid-creative-sb0540.c
 
+CRPS COMMON REDUNDANT PSU DRIVER
+M:	Ninad Palsule <ninad at linux.ibm.com>
+L:	linux-hwmon at vger.kernel.org
+S:	Maintained
+F:	Documentation/hwmon/crps.rst
+F:	drivers/hwmon/pmbus/crps.c
+
 CRYPTO API
 M:	Herbert Xu <herbert at gondor.apana.org.au>
 M:	"David S. Miller" <davem at davemloft.net>
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 22418a05ced0..56c4eb4b846e 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -85,6 +85,15 @@ config SENSORS_BPA_RS600
 	  This driver can also be built as a module. If so, the module will
 	  be called bpa-rs600.
 
+config SENSORS_CRPS
+	tristate "Common Redundant Power Supply"
+	help
+	  If you say yes here you get hardware monitoring support for the Common
+	  Redundant Power Supply.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called crps.
+
 config SENSORS_DELTA_AHE50DC_FAN
 	tristate "Delta AHE-50DC fan control module"
 	help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 3d3183f8d2a7..c7eb7739b7f8 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -62,3 +62,4 @@ obj-$(CONFIG_SENSORS_XDPE122)	+= xdpe12284.o
 obj-$(CONFIG_SENSORS_XDPE152)	+= xdpe152c4.o
 obj-$(CONFIG_SENSORS_ZL6100)	+= zl6100.o
 obj-$(CONFIG_SENSORS_PIM4328)	+= pim4328.o
+obj-$(CONFIG_SENSORS_CRPS)	+= crps.o
diff --git a/drivers/hwmon/pmbus/crps.c b/drivers/hwmon/pmbus/crps.c
new file mode 100644
index 000000000000..44d309f81803
--- /dev/null
+++ b/drivers/hwmon/pmbus/crps.c
@@ -0,0 +1,299 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2024 IBM Corp.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/pmbus.h>
+
+#include "pmbus.h"
+
+/* Intel crps185 specific commands. */
+#define CRPS185_MFR_IOUT_MAX		0xA6
+#define CRPS185_MFR_POUT_MAX		0xA7
+
+enum {
+	CRPS_DEBUGFS_PMBUS_REVISION = 0,
+	CRPS_DEBUGFS_MAX_POWER_OUT,
+	CRPS_DEBUGFS_MAX_CURRENT_OUT,
+	CRPS_DEBUGFS_NUM_ENTRIES
+};
+
+enum models { crps185 = 1, crps_unknown };
+
+struct crps {
+	enum models version;
+	struct i2c_client *client;
+
+	int debugfs_entries[CRPS_DEBUGFS_NUM_ENTRIES];
+};
+
+#define to_psu(x, y) container_of((x), struct crps, debugfs_entries[(y)])
+
+static struct pmbus_platform_data crps_pdata = {
+	.flags = PMBUS_SKIP_STATUS_CHECK,
+};
+
+static const struct i2c_device_id crps_id[] = {
+	{ "intel_crps185", crps185 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, crps_id);
+
+/*
+ * Convert linear format word to machine format. 11 LSB side bits are two's
+ * complement integer mantissa and 5 MSB side bits are two's complement
+ * exponent
+ */
+static int crps_convert_linear(int rc)
+{
+	s16 exponent;
+	s32 mantissa;
+	s64 val;
+
+	exponent = ((s16)rc) >> 11;
+	mantissa = ((s16)((rc & 0x7ff) << 5)) >> 5;
+
+	val = mantissa;
+	if (exponent >= 0)
+		val <<= exponent;
+	else
+		val >>= -exponent;
+
+	return (int)val;
+}
+
+static ssize_t crps_debugfs_read(struct file *file, char __user *buf,
+				 size_t count, loff_t *ppos)
+{
+	int rc;
+	int *idxp = file->private_data;
+	int idx = *idxp;
+	struct crps *psu = to_psu(idxp, idx);
+	char data[2 * I2C_SMBUS_BLOCK_MAX] = { 0 };
+
+	rc = pmbus_lock_interruptible(psu->client);
+	if (rc)
+		return rc;
+
+	rc = pmbus_set_page(psu->client, 0, 0xff);
+	if (rc)
+		goto unlock;
+
+	switch (idx) {
+	case CRPS_DEBUGFS_PMBUS_REVISION:
+		rc = i2c_smbus_read_byte_data(psu->client, PMBUS_REVISION);
+		if (rc >= 0) {
+			if (psu->version == crps185) {
+				if (rc == 0)
+					rc = sprintf(data, "%s", "1.0");
+				else if (rc == 0x11)
+					rc = sprintf(data, "%s", "1.1");
+				else if (rc == 0x22)
+					rc = sprintf(data, "%s", "1.2");
+				else
+					rc = snprintf(data, 3, "0x%02x", rc);
+			} else {
+				rc = snprintf(data, 3, "%02x", rc);
+			}
+		}
+		break;
+	case CRPS_DEBUGFS_MAX_POWER_OUT:
+		rc = i2c_smbus_read_word_data(psu->client, PMBUS_MFR_POUT_MAX);
+		if (rc >= 0) {
+			rc = crps_convert_linear(rc);
+			rc = snprintf(data, I2C_SMBUS_BLOCK_MAX, "%d", rc);
+		}
+		break;
+	case CRPS_DEBUGFS_MAX_CURRENT_OUT:
+		rc = i2c_smbus_read_word_data(psu->client, PMBUS_MFR_IOUT_MAX);
+		if (rc >= 0) {
+			rc = crps_convert_linear(rc);
+			rc = snprintf(data, I2C_SMBUS_BLOCK_MAX, "%d", rc);
+		}
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+unlock:
+	pmbus_unlock(psu->client);
+	if (rc < 0)
+		return rc;
+
+	data[rc] = '\n';
+	rc += 2;
+
+	return simple_read_from_buffer(buf, count, ppos, data, rc);
+}
+
+static const struct file_operations crps_debugfs_fops = {
+	.llseek = noop_llseek,
+	.read = crps_debugfs_read,
+	.open = simple_open,
+};
+
+static int crps_read_word_data(struct i2c_client *client, int page,
+				int phase, int reg)
+{
+	int rc;
+
+	switch (reg) {
+	case PMBUS_STATUS_WORD:
+		rc = pmbus_read_word_data(client, page, phase, reg);
+		if (rc < 0)
+			return rc;
+		break;
+	case PMBUS_OT_WARN_LIMIT:
+		rc = pmbus_read_word_data(client, page, phase,
+					  PMBUS_MFR_MAX_TEMP_1);
+		if (rc < 0)
+			return rc;
+		break;
+	case PMBUS_IOUT_OC_WARN_LIMIT:
+		rc = pmbus_read_word_data(client, page, phase,
+					  CRPS185_MFR_IOUT_MAX);
+		if (rc < 0)
+			return rc;
+		break;
+	case PMBUS_POUT_OP_WARN_LIMIT:
+		rc = pmbus_read_word_data(client, page, phase,
+					  CRPS185_MFR_POUT_MAX);
+		if (rc < 0)
+			return rc;
+		break;
+	default:
+		rc = -ENODATA;
+		break;
+	}
+
+	return rc;
+}
+
+static struct pmbus_driver_info crps_info[] = {
+	[crps185] = {
+		.pages = 1,
+		/* PSU uses default linear data format. */
+		.func[0] = PMBUS_HAVE_PIN | PMBUS_HAVE_IOUT |
+			PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_IIN |
+			PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
+			PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+			PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
+			PMBUS_HAVE_STATUS_TEMP |
+			PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
+		.read_word_data = crps_read_word_data,
+	},
+};
+
+#define to_psu(x, y) container_of((x), struct crps, debugfs_entries[(y)])
+
+static void crps_init_debugfs(struct crps *psu)
+{
+	struct i2c_client *client = psu->client;
+	struct dentry *debugfs;
+	int i;
+
+	/* Don't fail the probe if we can't create debugfs */
+	debugfs = pmbus_get_debugfs_dir(client);
+	if (!debugfs)
+		return;
+
+	for (i = 0; i < CRPS_DEBUGFS_NUM_ENTRIES; ++i)
+		psu->debugfs_entries[i] = i;
+
+	debugfs_create_file("pmbus_revision", 0444, debugfs,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_PMBUS_REVISION],
+			    &crps_debugfs_fops);
+	debugfs_create_file("max_power_out", 0444, debugfs,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MAX_POWER_OUT],
+			    &crps_debugfs_fops);
+	debugfs_create_file("max_current_out", 0444, debugfs,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MAX_CURRENT_OUT],
+			    &crps_debugfs_fops);
+}
+
+static int crps_probe(struct i2c_client *client)
+{
+	int rc;
+	struct device *dev = &client->dev;
+	enum models vs = crps_unknown;
+	struct crps *psu;
+	const void *md = of_device_get_match_data(&client->dev);
+	const struct i2c_device_id *id = NULL;
+	char buf[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
+
+	if (md) {
+		vs = (uintptr_t)md;
+	} else {
+		id = i2c_match_id(crps_id, client);
+		if (id)
+			vs = (enum models)id->driver_data;
+	}
+
+	if (!vs || vs >= crps_unknown) {
+		dev_err(dev, "Version %d not supported\n", vs);
+		return -EINVAL;
+	}
+
+	rc = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
+	if (rc < 0) {
+		dev_err(dev, "Failed to read PMBUS_MFR_MODEL\n");
+		return rc;
+	}
+	if (strncmp(buf, "03NK260", 7)) {
+		buf[rc] = '\0';
+		dev_err(dev, "Model '%s' not supported\n", buf);
+		return -ENODEV;
+	}
+
+	client->dev.platform_data = &crps_pdata;
+	rc = pmbus_do_probe(client, &crps_info[vs]);
+	if (rc) {
+		dev_err(dev, "Failed to probe %d\n", rc);
+		return rc;
+	}
+
+	/*
+	 * Don't fail the probe if there isn't enough memory for debugfs.
+	 */
+	psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
+	if (!psu) {
+		dev_warn(dev, "Failed to allocate memory. debugfs are not supported.\n");
+		return 0;
+	}
+
+	psu->version = vs;
+	psu->client = client;
+
+	crps_init_debugfs(psu);
+
+	return 0;
+}
+
+static const struct of_device_id crps_of_match[] = {
+	{
+		.compatible = "intel,crps185",
+		.data = (void *)crps185
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, crps_of_match);
+
+static struct i2c_driver crps_driver = {
+	.driver = {
+		.name = "crps",
+		.of_match_table = crps_of_match,
+	},
+	.probe = crps_probe,
+	.id_table = crps_id,
+};
+
+module_i2c_driver(crps_driver);
+
+MODULE_AUTHOR("Ninad Palsule");
+MODULE_DESCRIPTION("PMBus driver for Common Redundant power supplies");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("PMBUS");
-- 
2.43.0



From ninad at linux.ibm.com  Thu Dec 12 13:49:00 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Thu, 12 Dec 2024 15:49:00 -0600
Subject: [PATCH v1 1/4] hwmon: pmbus-core: Add label for fan and temp
In-Reply-To: <20241212214927.3586509-1-ninad@linux.ibm.com>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
Message-ID: <20241212214927.3586509-2-ninad@linux.ibm.com>

Adding label files for fan and temperature sensors in the power supply.
The openbmc application dbus-sensor(psusensor) requires those files to
consfigure those sensors.
Note that prefix for temp label is temp[A..C] used instead of temp[1..3]
as dbus-sensor(psusensor) application calculate index based on last
digit in the name so we do not want to make index double digit after
appending page index.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 drivers/hwmon/pmbus/pmbus_core.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index a7000314e5ad..149b3c5f3a4c 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -2144,6 +2144,7 @@ static const struct pmbus_sensor_attr temp_attributes[] = {
 	{
 		.reg = PMBUS_READ_TEMPERATURE_1,
 		.class = PSC_TEMPERATURE,
+		.label = "tempA",
 		.paged = true,
 		.update = true,
 		.compare = true,
@@ -2156,6 +2157,7 @@ static const struct pmbus_sensor_attr temp_attributes[] = {
 	}, {
 		.reg = PMBUS_READ_TEMPERATURE_2,
 		.class = PSC_TEMPERATURE,
+		.label = "tempB",
 		.paged = true,
 		.update = true,
 		.compare = true,
@@ -2168,6 +2170,7 @@ static const struct pmbus_sensor_attr temp_attributes[] = {
 	}, {
 		.reg = PMBUS_READ_TEMPERATURE_3,
 		.class = PSC_TEMPERATURE,
+		.label = "tempC",
 		.paged = true,
 		.update = true,
 		.compare = true,
@@ -2282,6 +2285,17 @@ static int pmbus_add_fan_attributes(struct i2c_client *client,
 					     PSC_FAN, true, true, true) == NULL)
 				return -ENOMEM;
 
+			/*
+			 * Add fan label.
+			 * Assuming paged attributes while passing page index
+			 */
+			ret = pmbus_add_label(data, "fan", index, "fan",
+					      page + 1, 0xff);
+			if (ret) {
+				dev_err(data->dev, "Fan label add failed ret=%d\n", ret);
+				return ret;
+			}
+
 			/* Fan control */
 			if (pmbus_check_word_register(client, page,
 					pmbus_fan_command_registers[f])) {
-- 
2.43.0



From ninad at linux.ibm.com  Thu Dec 12 13:48:59 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Thu, 12 Dec 2024 15:48:59 -0600
Subject: [PATCH v1 0/4] Add support for Intel CRPS PSU
Message-ID: <20241212214927.3586509-1-ninad@linux.ibm.com>

Hello,

Please review the changes for Intel CRPS power supply driver.
I need to add label in the pmbus core as new application like PSUSensor
requires it.

Ninad Palsule (4):
  hwmon: pmbus-core: Add label for fan and temp
  hwmon: (pmbus/crps) Add Intel CRPS185 power supply
  dt-bindings: hwmon: intel,crps185: Add to trivial
  ARM: dts: aspeed: system1: Use crps PSU driver

 .../devicetree/bindings/trivial-devices.yaml  |   2 +
 Documentation/hwmon/crps.rst                  |  95 ++++++
 MAINTAINERS                                   |   7 +
 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     |   8 +-
 drivers/hwmon/pmbus/Kconfig                   |   9 +
 drivers/hwmon/pmbus/Makefile                  |   1 +
 drivers/hwmon/pmbus/crps.c                    | 299 ++++++++++++++++++
 drivers/hwmon/pmbus/pmbus_core.c              |  14 +
 8 files changed, 431 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/hwmon/crps.rst
 create mode 100644 drivers/hwmon/pmbus/crps.c

-- 
2.43.0



From ninad at linux.ibm.com  Thu Dec 12 13:49:03 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Thu, 12 Dec 2024 15:49:03 -0600
Subject: [PATCH v1 4/4] ARM: dts: aspeed: system1: Use crps PSU driver
In-Reply-To: <20241212214927.3586509-1-ninad@linux.ibm.com>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
Message-ID: <20241212214927.3586509-5-ninad@linux.ibm.com>

The system1 uses Intel common redundant (crps185) power supplies so move
to correct new crps driver.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index 8f77bc9e860c..360b9ce3c850 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -681,22 +681,22 @@ &i2c2 {
 	status = "okay";
 
 	power-supply at 58 {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x58>;
 	};
 
 	power-supply at 59 {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x59>;
 	};
 
 	power-supply at 5a {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x5a>;
 	};
 
 	power-supply at 5b {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x5b>;
 	};
 };
-- 
2.43.0



From willy at infradead.org  Thu Dec 12 14:01:12 2024
From: willy at infradead.org (Matthew Wilcox)
Date: Thu, 12 Dec 2024 22:01:12 +0000
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
In-Reply-To: <20241211232754.1583023-1-kaleshsingh@google.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
Message-ID: <Z1tdKHFfz-tMTXit@casper.infradead.org>

On Wed, Dec 11, 2024 at 03:27:38PM -0800, Kalesh Singh wrote:
> Hi all,
> 
> This is v2 othe the arch_mmap_hint() series.
> 
> Changes in v2:
>   - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
>     special case of the hint addr being "enforced", per Yang Shi.
>   - Consolidate most of the error handling in arch_mmap_hint().
>   - Patch 16 ("mm: Fallback to generic_mmap_hint()") was folded into
>     Patch 2 ("mm: x86: Introduce arch_mmap_hint()")
> 
> v1: https://lore.kernel.org/r/20241210024119.2488608-1-kaleshsingh at google.com/
> 
> =======
> 
> This series introduces arch_mmap_hint() to handle allocating VA space
> for the hint address.

But why?  You're basically forcing me to read the entire series to
figure out what you're doing and why.  I decline.

> Patches 1-16 introduce this new helper and Patch 17 uses it to fix the
> issue of mmap hint being ignored in some cases due to THP alignment [1]
> 
> [1] https://lore.kernel.org/r/20241118214650.3667577-1-kaleshsingh at google.com/
> 
> Thanks,
> Kalesh
> 
> 
> Kalesh Singh (16):
>   mm: Introduce generic_mmap_hint()
>   mm: x86: Introduce arch_mmap_hint()
>   mm: arm: Introduce arch_mmap_hint()
>   mm: alpha: Introduce arch_mmap_hint()
>   mm: arc: Use generic_mmap_hint()
>   mm: csky: Introduce arch_mmap_hint()
>   mm: loongarch: Introduce arch_mmap_hint()
>   mm: mips: Introduce arch_align_mmap_hint()
>   mm: parisc: Introduce arch_align_mmap_hint()
>   mm: s390: Use generic_mmap_hint()
>   mm: sh: Introduce arch_mmap_hint()
>   mm: sparc32: Introduce arch_mmap_hint()
>   mm: sparc64: Introduce arch_mmap_hint()
>   mm: xtensa: Introduce arch_mmap_hint()
>   mm: powerpc: Introduce arch_mmap_hint()
>   mm: Respect mmap hint before THP alignment if allocation is possible
> 
>  arch/alpha/include/asm/pgtable.h           |   1 +
>  arch/alpha/kernel/osf_sys.c                |  31 +++---
>  arch/arc/include/asm/pgtable.h             |   1 +
>  arch/arc/mm/mmap.c                         |  43 +++++----
>  arch/arm/include/asm/pgtable.h             |   1 +
>  arch/arm/mm/mmap.c                         | 107 +++++++++------------
>  arch/csky/abiv1/inc/abi/pgtable-bits.h     |   1 +
>  arch/csky/abiv1/mmap.c                     |  68 +++++++------
>  arch/loongarch/include/asm/pgtable.h       |   1 +
>  arch/loongarch/mm/mmap.c                   |  49 +++++-----
>  arch/mips/include/asm/pgtable.h            |   1 +
>  arch/mips/mm/mmap.c                        |  50 +++++-----
>  arch/parisc/include/asm/pgtable.h          |   1 +
>  arch/parisc/kernel/sys_parisc.c            |  53 +++++-----
>  arch/powerpc/include/asm/book3s/64/slice.h |   1 +
>  arch/powerpc/mm/book3s64/slice.c           |  31 ++++++
>  arch/s390/include/asm/pgtable.h            |   1 +
>  arch/s390/mm/mmap.c                        |  51 +++++-----
>  arch/sh/include/asm/pgtable.h              |   1 +
>  arch/sh/mm/mmap.c                          |  83 ++++++----------
>  arch/sparc/include/asm/pgtable_32.h        |   1 +
>  arch/sparc/include/asm/pgtable_64.h        |   1 +
>  arch/sparc/kernel/sys_sparc_32.c           |  33 ++++---
>  arch/sparc/kernel/sys_sparc_64.c           |  96 +++++++-----------
>  arch/x86/include/asm/pgtable_64.h          |   1 +
>  arch/x86/kernel/sys_x86_64.c               |  64 ++++++------
>  arch/xtensa/kernel/syscall.c               |  31 ++++--
>  include/linux/sched/mm.h                   |   9 ++
>  mm/huge_memory.c                           |  17 ++--
>  mm/mmap.c                                  |  86 +++++++++++------
>  30 files changed, 491 insertions(+), 424 deletions(-)
> 
> -- 
> 2.47.0.338.g60cca15819-goog
> 
> 


From linux at roeck-us.net  Thu Dec 12 14:06:09 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 12 Dec 2024 14:06:09 -0800
Subject: [PATCH v1 1/4] hwmon: pmbus-core: Add label for fan and temp
In-Reply-To: <20241212214927.3586509-2-ninad@linux.ibm.com>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
 <20241212214927.3586509-2-ninad@linux.ibm.com>
Message-ID: <f9d881b7-7301-476e-b281-0380dfcf0e10@roeck-us.net>

On 12/12/24 13:49, Ninad Palsule wrote:
> Adding label files for fan and temperature sensors in the power supply.
> The openbmc application dbus-sensor(psusensor) requires those files to
> consfigure those sensors.
> Note that prefix for temp label is temp[A..C] used instead of temp[1..3]
> as dbus-sensor(psusensor) application calculate index based on last
> digit in the name so we do not want to make index double digit after
> appending page index.
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>

We are not going to fix userspace problems in the kernel.

Guenter

> ---
>   drivers/hwmon/pmbus/pmbus_core.c | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
> index a7000314e5ad..149b3c5f3a4c 100644
> --- a/drivers/hwmon/pmbus/pmbus_core.c
> +++ b/drivers/hwmon/pmbus/pmbus_core.c
> @@ -2144,6 +2144,7 @@ static const struct pmbus_sensor_attr temp_attributes[] = {
>   	{
>   		.reg = PMBUS_READ_TEMPERATURE_1,
>   		.class = PSC_TEMPERATURE,
> +		.label = "tempA",
>   		.paged = true,
>   		.update = true,
>   		.compare = true,
> @@ -2156,6 +2157,7 @@ static const struct pmbus_sensor_attr temp_attributes[] = {
>   	}, {
>   		.reg = PMBUS_READ_TEMPERATURE_2,
>   		.class = PSC_TEMPERATURE,
> +		.label = "tempB",
>   		.paged = true,
>   		.update = true,
>   		.compare = true,
> @@ -2168,6 +2170,7 @@ static const struct pmbus_sensor_attr temp_attributes[] = {
>   	}, {
>   		.reg = PMBUS_READ_TEMPERATURE_3,
>   		.class = PSC_TEMPERATURE,
> +		.label = "tempC",
>   		.paged = true,
>   		.update = true,
>   		.compare = true,
> @@ -2282,6 +2285,17 @@ static int pmbus_add_fan_attributes(struct i2c_client *client,
>   					     PSC_FAN, true, true, true) == NULL)
>   				return -ENOMEM;
>   
> +			/*
> +			 * Add fan label.
> +			 * Assuming paged attributes while passing page index
> +			 */
> +			ret = pmbus_add_label(data, "fan", index, "fan",
> +					      page + 1, 0xff);
> +			if (ret) {
> +				dev_err(data->dev, "Fan label add failed ret=%d\n", ret);
> +				return ret;
> +			}
> +
>   			/* Fan control */
>   			if (pmbus_check_word_register(client, page,
>   					pmbus_fan_command_registers[f])) {



From robh at kernel.org  Thu Dec 12 14:30:25 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 12 Dec 2024 16:30:25 -0600
Subject: [PATCH 1/3] dt-bindings: soc: samsung: exynos-speedy: Document
 SPEEDY host controller bindings
In-Reply-To: <20241212-speedy-v1-1-544ad7bcfb6a@gmail.com>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
 <20241212-speedy-v1-1-544ad7bcfb6a@gmail.com>
Message-ID: <173404262581.3370297.1817961099331187454.robh@kernel.org>


On Thu, 12 Dec 2024 23:09:01 +0200, Markuss Broks wrote:
> Add the schema for the Samsung SPEEDY serial bus host controller.
> The bus has 4 bit wide addresses for addressing devices
> and 8 bit wide register addressing. Each register is also 8
> bit long, so the address can be 0-f (hexadecimal), node name
> for child device follows the format: node_name@[0-f].
> 
> Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
> Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
> Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
> ---
>  .../bindings/soc/samsung/exynos-speedy.yaml        | 78 ++++++++++++++++++++++
>  1 file changed, 78 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml: ignoring, error in schema: properties: clock-names
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml: properties:compatible: [{'items': [{'enum': ['samsung,exynos9810-speedy']}, {'const': 'samsung,exynos-speedy'}]}] 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/soc/samsung/exynos-speedy.yaml: properties:clock-names: [{'const': 'pclk'}] 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/soc/samsung/exynos-speedy.yaml: properties:compatible: [{'items': [{'enum': ['samsung,exynos9810-speedy']}, {'const': 'samsung,exynos-speedy'}]}] 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/soc/samsung/exynos-speedy.yaml: properties:clock-names: [{'const': 'pclk'}] is not of type 'object', 'boolean'
	from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
Documentation/devicetree/bindings/soc/samsung/exynos-speedy.example.dtb: /example-0/speedy at 141c0000: failed to match any schema with compatible: ['samsung,exynos9810-speedy', 'samsung-exynos-speedy']
Documentation/devicetree/bindings/soc/samsung/exynos-speedy.example.dtb: /example-0/speedy at 141c0000: failed to match any schema with compatible: ['samsung,exynos9810-speedy', 'samsung-exynos-speedy']
Documentation/devicetree/bindings/soc/samsung/exynos-speedy.example.dtb: /example-0/speedy at 141c0000/pmic at 0: failed to match any schema with compatible: ['samsung,s2mps18-pmic']
Documentation/devicetree/bindings/soc/samsung/exynos-speedy.example.dtb: /example-0/speedy at 141c0000/regulator at 1: failed to match any schema with compatible: ['samsung,s2mps18-regulator']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241212-speedy-v1-1-544ad7bcfb6a 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 ilkka at os.amperecomputing.com  Thu Dec 12 14:35:17 2024
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Thu, 12 Dec 2024 14:35:17 -0800 (PST)
Subject: [PATCH] perf/arm-cmn: Permit more exhaustive groups
In-Reply-To: <20241211215139.GE17486@willie-the-truck>
References: <bdfd1e58dac449e407c5cacfd6bf8577dc0a5899.1733943898.git.robin.murphy@arm.com> <20241211215139.GE17486@willie-the-truck>
Message-ID: <e5216abc-584f-a047-ca55-735e8d93999d@os.amperecomputing.com>


On Wed, 11 Dec 2024, Will Deacon wrote:
>
> [+ Ilkka for comments/testing]
>
> On Wed, Dec 11, 2024 at 07:04:58PM +0000, Robin Murphy wrote:
>> The group validation logic still somewhat assumes the original CMN-600
>> case of events counting globally, such that if one tries to group 9
>> events where the first 8 target a single DTC domain, the 9th will be
>> rejected because *a* DTC domain is full, even though it might only
>> target other non-overlapping domains and thus still be schedulable.
>> Improve matters by only counting the DTCs that the new event actually
>> needs (as arm_cmn_val_add_event() was already clever enough to do).
>>
>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Good catch, I must have missed that one. I did some quick tests on 
AmpereOne and everything seemed to work fine.

   Reviewed-and-tested-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>


FYI, I'll take the rest of the year off and will be back online in the 
beginning of January.

Cheers, Ilkka

>> ---
>>  drivers/perf/arm-cmn.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
>> index edefb51ac90a..b49e353e10ab 100644
>> --- a/drivers/perf/arm-cmn.c
>> +++ b/drivers/perf/arm-cmn.c
>> @@ -1779,8 +1779,8 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event)
>>  		goto done;
>>  	}
>>
>> -	for (i = 0; i < CMN_MAX_DTCS; i++)
>> -		if (val->dtc_count[i] == CMN_DT_NUM_COUNTERS)
>> +	for_each_hw_dtc_idx(hw, dtc, idx)
>> +		if (val->dtc_count[dtc] == CMN_DT_NUM_COUNTERS)
>>  			goto done;
>>
>>  	for_each_hw_dn(hw, dn, i) {
>> --
>> 2.39.2.101.g768bb238c484.dirty
>>
>


From lorenzo.stoakes at oracle.com  Thu Dec 12 14:51:34 2024
From: lorenzo.stoakes at oracle.com (Lorenzo Stoakes)
Date: Thu, 12 Dec 2024 22:51:34 +0000
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
In-Reply-To: <hmuzfspqjzb36xlj2x44keihacrrhzj5madqrfbcnhqouzredv@wo75achgkuh5>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
 <hmuzfspqjzb36xlj2x44keihacrrhzj5madqrfbcnhqouzredv@wo75achgkuh5>
Message-ID: <1818e2ea-f170-4a9c-8d93-2a24f2755a41@lucifer.local>

NACK.

Resend this _as an RFC_, _with the correct maintainers and reviewers cc'd_.

You've fundamentally violated kernel process and etiquette. I'd be more
forgiving, but this is at v2 and you've not cc'd KEY people. Twice. This is
totally unacceptable. See [0] if you are unsure of how to do so.

You've also sent a 16 patch series (!) immediately prior to the holidays
(!!) introducing an arch hook (!!!), which is strictly something we want to
try to avoid or lessen in future, which you'd know, had you followed basic
kernel etiquette and process and cc'd us on v1.

Any discussion that will be had here with others we won't be cc'd on, it's
16 patches, this isn't workable.

I'm on holiday from next week, it's not really fair to put this all on Liam
immediately prior to Christmas, so let's just examine this as an RFC first.

I hate to think that I need to set lei rules to catch stuff like this, but
clearly, I do. I will be updating these to check on all relevant
files. Sigh.

[0]: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#select-the-recipients-for-your-patch

On Thu, Dec 12, 2024 at 04:02:31PM -0500, Liam R. Howlett wrote:
>
> + Lorenzo
>
> Can you please Cc the people listed in the maintainers on the files you
> are submitting against?  You seemed to Cc everyone but the mmap.c file
> maintainers?

Thanks Liam.

Also +Jann, another reviewer Kalesh missed (he only got Vlastimil and
Andrew so 2/5... of those required...)

>
>
> * Kalesh Singh <kaleshsingh at google.com> [241211 18:28]:
> > Hi all,
> >
> > This is v2 othe the arch_mmap_hint() series.
> >
> > Changes in v2:
> >   - MAP_FIXED case is also handled in arch_mmap_hint() since this is just a
> >     special case of the hint addr being "enforced", per Yang Shi.
> >   - Consolidate most of the error handling in arch_mmap_hint().
> >   - Patch 16 ("mm: Fallback to generic_mmap_hint()") was folded into
> >     Patch 2 ("mm: x86: Introduce arch_mmap_hint()")
> >
> > v1: https://lore.kernel.org/r/20241210024119.2488608-1-kaleshsingh at google.com/
> >
> > =======
> >
> > This series introduces arch_mmap_hint() to handle allocating VA space
> > for the hint address.
>
> Why?  Could we get more details in your cover letter please?  This
> entire email has as much detail as the subject line.

Yes the cover letter is ridiculously small for what that is doing.

>
> I don't want more arch_ anything.  If we can do this in a more generic
> way, then we should.

ENTIRELY agreed.

>
> >
> > Patches 1-16 introduce this new helper and Patch 17 uses it to fix the
> > issue of mmap hint being ignored in some cases due to THP alignment [1]
> >
> > [1] https://lore.kernel.org/r/20241118214650.3667577-1-kaleshsingh at google.com/
> >
> > Thanks,
> > Kalesh
> >
> >
> > Kalesh Singh (16):
> >   mm: Introduce generic_mmap_hint()
> >   mm: x86: Introduce arch_mmap_hint()
> >   mm: arm: Introduce arch_mmap_hint()
> >   mm: alpha: Introduce arch_mmap_hint()
> >   mm: arc: Use generic_mmap_hint()
> >   mm: csky: Introduce arch_mmap_hint()
> >   mm: loongarch: Introduce arch_mmap_hint()
> >   mm: mips: Introduce arch_align_mmap_hint()
> >   mm: parisc: Introduce arch_align_mmap_hint()
> >   mm: s390: Use generic_mmap_hint()
> >   mm: sh: Introduce arch_mmap_hint()
> >   mm: sparc32: Introduce arch_mmap_hint()
> >   mm: sparc64: Introduce arch_mmap_hint()
> >   mm: xtensa: Introduce arch_mmap_hint()
> >   mm: powerpc: Introduce arch_mmap_hint()
> >   mm: Respect mmap hint before THP alignment if allocation is possible
> >
> >  arch/alpha/include/asm/pgtable.h           |   1 +
> >  arch/alpha/kernel/osf_sys.c                |  31 +++---
> >  arch/arc/include/asm/pgtable.h             |   1 +
> >  arch/arc/mm/mmap.c                         |  43 +++++----
> >  arch/arm/include/asm/pgtable.h             |   1 +
> >  arch/arm/mm/mmap.c                         | 107 +++++++++------------
> >  arch/csky/abiv1/inc/abi/pgtable-bits.h     |   1 +
> >  arch/csky/abiv1/mmap.c                     |  68 +++++++------
> >  arch/loongarch/include/asm/pgtable.h       |   1 +
> >  arch/loongarch/mm/mmap.c                   |  49 +++++-----
> >  arch/mips/include/asm/pgtable.h            |   1 +
> >  arch/mips/mm/mmap.c                        |  50 +++++-----
> >  arch/parisc/include/asm/pgtable.h          |   1 +
> >  arch/parisc/kernel/sys_parisc.c            |  53 +++++-----
> >  arch/powerpc/include/asm/book3s/64/slice.h |   1 +
> >  arch/powerpc/mm/book3s64/slice.c           |  31 ++++++
> >  arch/s390/include/asm/pgtable.h            |   1 +
> >  arch/s390/mm/mmap.c                        |  51 +++++-----
> >  arch/sh/include/asm/pgtable.h              |   1 +
> >  arch/sh/mm/mmap.c                          |  83 ++++++----------
> >  arch/sparc/include/asm/pgtable_32.h        |   1 +
> >  arch/sparc/include/asm/pgtable_64.h        |   1 +
> >  arch/sparc/kernel/sys_sparc_32.c           |  33 ++++---
> >  arch/sparc/kernel/sys_sparc_64.c           |  96 +++++++-----------
> >  arch/x86/include/asm/pgtable_64.h          |   1 +
> >  arch/x86/kernel/sys_x86_64.c               |  64 ++++++------
> >  arch/xtensa/kernel/syscall.c               |  31 ++++--
> >  include/linux/sched/mm.h                   |   9 ++
> >  mm/huge_memory.c                           |  17 ++--
> >  mm/mmap.c                                  |  86 +++++++++++------
> >  30 files changed, 491 insertions(+), 424 deletions(-)

Yuck. Is this copy/paste really necessary...

> >
> > --
> > 2.47.0.338.g60cca15819-goog
> >
> >


From sebastian.reichel at collabora.com  Thu Dec 12 15:09:08 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 13 Dec 2024 00:09:08 +0100
Subject: (subset) [PATCH v8 0/9] Add support for sam9x7 SoC family
In-Reply-To: <20241010120142.92057-1-varshini.rajendran@microchip.com>
References: <20241010120142.92057-1-varshini.rajendran@microchip.com>
Message-ID: <173404494870.2565720.7657048690139336001.b4-ty@collabora.com>


On Thu, 10 Oct 2024 17:31:42 +0530, Varshini Rajendran wrote:
> This patch series adds support for the new SoC family - sam9x7.
>  - The device tree, configs and drivers are added
>  - Clock driver for sam9x7 is added
>  - Support for basic peripherals is added
>  - Target board SAM9X75 Curiosity is added
> 
>  Changes in v8:
>  --------------
> 
> [...]

Applied, thanks!

[2/9] power: reset: at91-poweroff: lookup for proper pmc dt node for sam9x7
      commit: 2a16675e254a35f13203c6738a1137093c773056
[3/9] power: reset: at91-reset: add reset support for sam9x7 SoC
      commit: ef4f3ac4be990511a2c958443744d0c0c97deb5b
[4/9] power: reset: at91-reset: add sdhwc support for sam9x7 SoC
      commit: 250bbd612bb1103745ea6c891a2a1d5f5e1576a3
[6/9] dt-bindings: power: reset: atmel,sama5d2-shdwc: add sam9x7
      commit: 2d656827a0fc9ca4982c245f1bec3b606fab30d8

Best regards,
-- 
Sebastian Reichel <sebastian.reichel at collabora.com>



From linus.walleij at linaro.org  Thu Dec 12 16:27:00 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 13 Dec 2024 01:27:00 +0100
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <20241211152257.Igx3aT2Y@linutronix.de>
References: <20241210160556.2341497-1-arnd@kernel.org> <20241210160556.2341497-3-arnd@kernel.org>
 <CACRpkdZaoD2vqbCi1AFUa6mF2_=c3Nu4R0CvxFAep0VMgtMtOQ@mail.gmail.com> <20241211152257.Igx3aT2Y@linutronix.de>
Message-ID: <CACRpkdbYU=Txm0zUWDWvNXA0JHRNGpy1ccy0zQdiBb2Ya+UBFA@mail.gmail.com>

On Wed, Dec 11, 2024 at 4:22?PM Sebastian Andrzej Siewior
<bigeasy at linutronix.de> wrote:
> On 2024-12-11 14:29:29 [+0100], Linus Walleij wrote:
> > So fast GUP is supposed to be lockless, and should just not
> > have this problem. So it can't be addressing gup_fast_pgd_range()
> > right?
> ?
> > I'm more asking if HIGHPTE even acquires a spinlock anymore
> > as it is supposed to be "fast"/lockless. If it does, it is clearly violating
> > the "fast" promise of the fast GUP API and should not exist.
>
> This is lockless on x86. The problem is ARM's
> arch_kmap_local_high_get(). This is where the lock is from.

Aha that calls down to kmap_high_get() that that issues
lock_kmap_any(flags).

But is it really sound that the "fast" API does this? It feels
like a violation of the whole design of the fast stuff.

Yours,
Linus Walleij


From charlie at rivosinc.com  Thu Dec 12 16:32:55 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:55 -0800
Subject: [PATCH v2 05/16] perf tools: sh: Support syscall headers
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-5-f8ca984ffe40@rivosinc.com>

sh uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
 .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
 tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 472 +++++++++++++++++++++
 tools/perf/arch/sh/include/syscall_table.h         |   2 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 483 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 3093cf90e76d3627e9ef842ea1a24dbeb6f56422..e7b7257f014e2e58130edf5312bf89d5f7681eef 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 01a6cd630396204c9119b12bb1fe26b6133fa5d2..9ea1d7284fa7a161352121e904b933e34e07dc7f 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/sh/entry/syscalls/Kbuild b/tools/perf/arch/sh/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..25080390e4ed49ae56f314ad712007e674a9168e
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 +=
+syscalltbl = $(srctree)/tools/perf/arch/sh/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sh/entry/syscalls/syscall.tbl b/tools/perf/arch/sh/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..c8cad33bf250ea110de37bd1407f5a43ec5e38f2
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/syscall.tbl
@@ -0,0 +1,472 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for sh
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	restart_syscall			sys_restart_syscall
+1	common	exit				sys_exit
+2	common	fork				sys_fork
+3	common	read				sys_read
+4	common	write				sys_write
+5	common	open				sys_open
+6	common	close				sys_close
+7	common	waitpid				sys_waitpid
+8	common	creat				sys_creat
+9	common	link				sys_link
+10	common	unlink				sys_unlink
+11	common	execve				sys_execve
+12	common	chdir				sys_chdir
+13	common	time				sys_time32
+14	common	mknod				sys_mknod
+15	common	chmod				sys_chmod
+16	common	lchown				sys_lchown16
+# 17 was break
+18	common	oldstat				sys_stat
+19	common	lseek				sys_lseek
+20	common	getpid				sys_getpid
+21	common	mount				sys_mount
+22	common	umount				sys_oldumount
+23	common	setuid				sys_setuid16
+24	common	getuid				sys_getuid16
+25	common	stime				sys_stime32
+26	common	ptrace				sys_ptrace
+27	common	alarm				sys_alarm
+28	common	oldfstat			sys_fstat
+29	common	pause				sys_pause
+30	common	utime				sys_utime32
+# 31 was stty
+# 32 was gtty
+33	common	access				sys_access
+34	common	nice				sys_nice
+# 35 was ftime
+36	common	sync				sys_sync
+37	common	kill				sys_kill
+38	common	rename				sys_rename
+39	common	mkdir				sys_mkdir
+40	common	rmdir				sys_rmdir
+41	common	dup				sys_dup
+42	common	pipe				sys_sh_pipe
+43	common	times				sys_times
+# 44 was prof
+45	common	brk				sys_brk
+46	common	setgid				sys_setgid16
+47	common	getgid				sys_getgid16
+48	common	signal				sys_signal
+49	common	geteuid				sys_geteuid16
+50	common	getegid				sys_getegid16
+51	common	acct				sys_acct
+52	common	umount2				sys_umount
+# 53 was lock
+54	common	ioctl				sys_ioctl
+55	common	fcntl				sys_fcntl
+# 56 was mpx
+57	common	setpgid				sys_setpgid
+# 58 was ulimit
+# 59 was olduname
+60	common	umask				sys_umask
+61	common	chroot				sys_chroot
+62	common	ustat				sys_ustat
+63	common	dup2				sys_dup2
+64	common	getppid				sys_getppid
+65	common	getpgrp				sys_getpgrp
+66	common	setsid				sys_setsid
+67	common	sigaction			sys_sigaction
+68	common	sgetmask			sys_sgetmask
+69	common	ssetmask			sys_ssetmask
+70	common	setreuid			sys_setreuid16
+71	common	setregid			sys_setregid16
+72	common	sigsuspend			sys_sigsuspend
+73	common	sigpending			sys_sigpending
+74	common	sethostname			sys_sethostname
+75	common	setrlimit			sys_setrlimit
+76	common	getrlimit			sys_old_getrlimit
+77	common	getrusage			sys_getrusage
+78	common	gettimeofday			sys_gettimeofday
+79	common	settimeofday			sys_settimeofday
+80	common	getgroups			sys_getgroups16
+81	common	setgroups			sys_setgroups16
+# 82 was select
+83	common	symlink				sys_symlink
+84	common	oldlstat			sys_lstat
+85	common	readlink			sys_readlink
+86	common	uselib				sys_uselib
+87	common	swapon				sys_swapon
+88	common	reboot				sys_reboot
+89	common	readdir				sys_old_readdir
+90	common	mmap				old_mmap
+91	common	munmap				sys_munmap
+92	common	truncate			sys_truncate
+93	common	ftruncate			sys_ftruncate
+94	common	fchmod				sys_fchmod
+95	common	fchown				sys_fchown16
+96	common	getpriority			sys_getpriority
+97	common	setpriority			sys_setpriority
+# 98 was profil
+99	common	statfs				sys_statfs
+100	common	fstatfs				sys_fstatfs
+# 101 was ioperm
+102	common	socketcall			sys_socketcall
+103	common	syslog				sys_syslog
+104	common	setitimer			sys_setitimer
+105	common	getitimer			sys_getitimer
+106	common	stat				sys_newstat
+107	common	lstat				sys_newlstat
+108	common	fstat				sys_newfstat
+109	common	olduname			sys_uname
+# 110 was iopl
+111	common	vhangup				sys_vhangup
+# 112 was idle
+# 113 was vm86old
+114	common	wait4				sys_wait4
+115	common	swapoff				sys_swapoff
+116	common	sysinfo				sys_sysinfo
+117	common	ipc				sys_ipc
+118	common	fsync				sys_fsync
+119	common	sigreturn			sys_sigreturn
+120	common	clone				sys_clone
+121	common	setdomainname			sys_setdomainname
+122	common	uname				sys_newuname
+123	common	cacheflush			sys_cacheflush
+124	common	adjtimex			sys_adjtimex_time32
+125	common	mprotect			sys_mprotect
+126	common	sigprocmask			sys_sigprocmask
+# 127 was create_module
+128	common	init_module			sys_init_module
+129	common	delete_module			sys_delete_module
+# 130 was get_kernel_syms
+131	common	quotactl			sys_quotactl
+132	common	getpgid				sys_getpgid
+133	common	fchdir				sys_fchdir
+134	common	bdflush				sys_ni_syscall
+135	common	sysfs				sys_sysfs
+136	common	personality			sys_personality
+# 137 was afs_syscall
+138	common	setfsuid			sys_setfsuid16
+139	common	setfsgid			sys_setfsgid16
+140	common	_llseek				sys_llseek
+141	common	getdents			sys_getdents
+142	common	_newselect			sys_select
+143	common	flock				sys_flock
+144	common	msync				sys_msync
+145	common	readv				sys_readv
+146	common	writev				sys_writev
+147	common	getsid				sys_getsid
+148	common	fdatasync			sys_fdatasync
+149	common	_sysctl				sys_ni_syscall
+150	common	mlock				sys_mlock
+151	common	munlock				sys_munlock
+152	common	mlockall			sys_mlockall
+153	common	munlockall			sys_munlockall
+154	common	sched_setparam			sys_sched_setparam
+155	common	sched_getparam			sys_sched_getparam
+156	common	sched_setscheduler		sys_sched_setscheduler
+157	common	sched_getscheduler		sys_sched_getscheduler
+158	common	sched_yield			sys_sched_yield
+159	common	sched_get_priority_max		sys_sched_get_priority_max
+160	common	sched_get_priority_min		sys_sched_get_priority_min
+161	common	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+162	common	nanosleep			sys_nanosleep_time32
+163	common	mremap				sys_mremap
+164	common	setresuid			sys_setresuid16
+165	common	getresuid			sys_getresuid16
+# 166 was vm86
+# 167 was query_module
+168	common	poll				sys_poll
+169	common	nfsservctl			sys_ni_syscall
+170	common	setresgid			sys_setresgid16
+171	common	getresgid			sys_getresgid16
+172	common	prctl				sys_prctl
+173	common	rt_sigreturn			sys_rt_sigreturn
+174	common	rt_sigaction			sys_rt_sigaction
+175	common	rt_sigprocmask			sys_rt_sigprocmask
+176	common	rt_sigpending			sys_rt_sigpending
+177	common	rt_sigtimedwait			sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+179	common	rt_sigsuspend			sys_rt_sigsuspend
+180	common	pread64				sys_pread_wrapper
+181	common	pwrite64			sys_pwrite_wrapper
+182	common	chown				sys_chown16
+183	common	getcwd				sys_getcwd
+184	common	capget				sys_capget
+185	common	capset				sys_capset
+186	common	sigaltstack			sys_sigaltstack
+187	common	sendfile			sys_sendfile
+# 188 is reserved for getpmsg
+# 189 is reserved for putpmsg
+190	common	vfork				sys_vfork
+191	common	ugetrlimit			sys_getrlimit
+192	common	mmap2				sys_mmap2
+193	common	truncate64			sys_truncate64
+194	common	ftruncate64			sys_ftruncate64
+195	common	stat64				sys_stat64
+196	common	lstat64				sys_lstat64
+197	common	fstat64				sys_fstat64
+198	common	lchown32			sys_lchown
+199	common	getuid32			sys_getuid
+200	common	getgid32			sys_getgid
+201	common	geteuid32			sys_geteuid
+202	common	getegid32			sys_getegid
+203	common	setreuid32			sys_setreuid
+204	common	setregid32			sys_setregid
+205	common	getgroups32			sys_getgroups
+206	common	setgroups32			sys_setgroups
+207	common	fchown32			sys_fchown
+208	common	setresuid32			sys_setresuid
+209	common	getresuid32			sys_getresuid
+210	common	setresgid32			sys_setresgid
+211	common	getresgid32			sys_getresgid
+212	common	chown32				sys_chown
+213	common	setuid32			sys_setuid
+214	common	setgid32			sys_setgid
+215	common	setfsuid32			sys_setfsuid
+216	common	setfsgid32			sys_setfsgid
+217	common	pivot_root			sys_pivot_root
+218	common	mincore				sys_mincore
+219	common	madvise				sys_madvise
+220	common	getdents64			sys_getdents64
+221	common	fcntl64				sys_fcntl64
+# 222 is reserved for tux
+# 223 is unused
+224	common	gettid				sys_gettid
+225	common	readahead			sys_readahead
+226	common	setxattr			sys_setxattr
+227	common	lsetxattr			sys_lsetxattr
+228	common	fsetxattr			sys_fsetxattr
+229	common	getxattr			sys_getxattr
+230	common	lgetxattr			sys_lgetxattr
+231	common	fgetxattr			sys_fgetxattr
+232	common	listxattr			sys_listxattr
+233	common	llistxattr			sys_llistxattr
+234	common	flistxattr			sys_flistxattr
+235	common	removexattr			sys_removexattr
+236	common	lremovexattr			sys_lremovexattr
+237	common	fremovexattr			sys_fremovexattr
+238	common	tkill				sys_tkill
+239	common	sendfile64			sys_sendfile64
+240	common	futex				sys_futex_time32
+241	common	sched_setaffinity		sys_sched_setaffinity
+242	common	sched_getaffinity		sys_sched_getaffinity
+# 243 is reserved for set_thread_area
+# 244 is reserved for get_thread_area
+245	common	io_setup			sys_io_setup
+246	common	io_destroy			sys_io_destroy
+247	common	io_getevents			sys_io_getevents_time32
+248	common	io_submit			sys_io_submit
+249	common	io_cancel			sys_io_cancel
+250	common	fadvise64			sys_fadvise64
+# 251 is unused
+252	common	exit_group			sys_exit_group
+253	common	lookup_dcookie			sys_ni_syscall
+254	common	epoll_create			sys_epoll_create
+255	common	epoll_ctl			sys_epoll_ctl
+256	common	epoll_wait			sys_epoll_wait
+257	common	remap_file_pages		sys_remap_file_pages
+258	common	set_tid_address			sys_set_tid_address
+259	common	timer_create			sys_timer_create
+260	common	timer_settime			sys_timer_settime32
+261	common	timer_gettime			sys_timer_gettime32
+262	common	timer_getoverrun		sys_timer_getoverrun
+263	common	timer_delete			sys_timer_delete
+264	common	clock_settime			sys_clock_settime32
+265	common	clock_gettime			sys_clock_gettime32
+266	common	clock_getres			sys_clock_getres_time32
+267	common	clock_nanosleep			sys_clock_nanosleep_time32
+268	common	statfs64			sys_statfs64
+269	common	fstatfs64			sys_fstatfs64
+270	common	tgkill				sys_tgkill
+271	common	utimes				sys_utimes_time32
+272	common	fadvise64_64			sys_fadvise64_64_wrapper
+# 273 is reserved for vserver
+274	common	mbind				sys_mbind
+275	common	get_mempolicy			sys_get_mempolicy
+276	common	set_mempolicy			sys_set_mempolicy
+277	common	mq_open				sys_mq_open
+278	common	mq_unlink			sys_mq_unlink
+279	common	mq_timedsend			sys_mq_timedsend_time32
+280	common	mq_timedreceive			sys_mq_timedreceive_time32
+281	common	mq_notify			sys_mq_notify
+282	common	mq_getsetattr			sys_mq_getsetattr
+283	common	kexec_load			sys_kexec_load
+284	common	waitid				sys_waitid
+285	common	add_key				sys_add_key
+286	common	request_key			sys_request_key
+287	common	keyctl				sys_keyctl
+288	common	ioprio_set			sys_ioprio_set
+289	common	ioprio_get			sys_ioprio_get
+290	common	inotify_init			sys_inotify_init
+291	common	inotify_add_watch		sys_inotify_add_watch
+292	common	inotify_rm_watch		sys_inotify_rm_watch
+# 293 is unused
+294	common	migrate_pages			sys_migrate_pages
+295	common	openat				sys_openat
+296	common	mkdirat				sys_mkdirat
+297	common	mknodat				sys_mknodat
+298	common	fchownat			sys_fchownat
+299	common	futimesat			sys_futimesat_time32
+300	common	fstatat64			sys_fstatat64
+301	common	unlinkat			sys_unlinkat
+302	common	renameat			sys_renameat
+303	common	linkat				sys_linkat
+304	common	symlinkat			sys_symlinkat
+305	common	readlinkat			sys_readlinkat
+306	common	fchmodat			sys_fchmodat
+307	common	faccessat			sys_faccessat
+308	common	pselect6			sys_pselect6_time32
+309	common	ppoll				sys_ppoll_time32
+310	common	unshare				sys_unshare
+311	common	set_robust_list			sys_set_robust_list
+312	common	get_robust_list			sys_get_robust_list
+313	common	splice				sys_splice
+314	common	sync_file_range			sys_sh_sync_file_range6
+315	common	tee				sys_tee
+316	common	vmsplice			sys_vmsplice
+317	common	move_pages			sys_move_pages
+318	common	getcpu				sys_getcpu
+319	common	epoll_pwait			sys_epoll_pwait
+320	common	utimensat			sys_utimensat_time32
+321	common	signalfd			sys_signalfd
+322	common	timerfd_create			sys_timerfd_create
+323	common	eventfd				sys_eventfd
+324	common	fallocate			sys_fallocate
+325	common	timerfd_settime			sys_timerfd_settime32
+326	common	timerfd_gettime			sys_timerfd_gettime32
+327	common	signalfd4			sys_signalfd4
+328	common	eventfd2			sys_eventfd2
+329	common	epoll_create1			sys_epoll_create1
+330	common	dup3				sys_dup3
+331	common	pipe2				sys_pipe2
+332	common	inotify_init1			sys_inotify_init1
+333	common	preadv				sys_preadv
+334	common	pwritev				sys_pwritev
+335	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+336	common	perf_event_open			sys_perf_event_open
+337	common	fanotify_init			sys_fanotify_init
+338	common	fanotify_mark			sys_fanotify_mark
+339	common	prlimit64			sys_prlimit64
+340	common	socket				sys_socket
+341	common	bind				sys_bind
+342	common	connect				sys_connect
+343	common	listen				sys_listen
+344	common	accept				sys_accept
+345	common	getsockname			sys_getsockname
+346	common	getpeername			sys_getpeername
+347	common	socketpair			sys_socketpair
+348	common	send				sys_send
+349	common	sendto				sys_sendto
+350	common	recv				sys_recv
+351	common	recvfrom			sys_recvfrom
+352	common	shutdown			sys_shutdown
+353	common	setsockopt			sys_setsockopt
+354	common	getsockopt			sys_getsockopt
+355	common	sendmsg				sys_sendmsg
+356	common	recvmsg				sys_recvmsg
+357	common	recvmmsg			sys_recvmmsg_time32
+358	common	accept4				sys_accept4
+359	common	name_to_handle_at		sys_name_to_handle_at
+360	common	open_by_handle_at		sys_open_by_handle_at
+361	common	clock_adjtime			sys_clock_adjtime32
+362	common	syncfs				sys_syncfs
+363	common	sendmmsg			sys_sendmmsg
+364	common	setns				sys_setns
+365	common	process_vm_readv		sys_process_vm_readv
+366	common	process_vm_writev		sys_process_vm_writev
+367	common	kcmp				sys_kcmp
+368	common	finit_module			sys_finit_module
+369	common	sched_getattr			sys_sched_getattr
+370	common	sched_setattr			sys_sched_setattr
+371	common	renameat2			sys_renameat2
+372	common	seccomp				sys_seccomp
+373	common	getrandom			sys_getrandom
+374	common	memfd_create			sys_memfd_create
+375	common	bpf				sys_bpf
+376	common	execveat			sys_execveat
+377	common	userfaultfd			sys_userfaultfd
+378	common	membarrier			sys_membarrier
+379	common	mlock2				sys_mlock2
+380	common	copy_file_range			sys_copy_file_range
+381	common	preadv2				sys_preadv2
+382	common	pwritev2			sys_pwritev2
+383	common	statx				sys_statx
+384	common	pkey_mprotect			sys_pkey_mprotect
+385	common	pkey_alloc			sys_pkey_alloc
+386	common	pkey_free			sys_pkey_free
+387	common	rseq				sys_rseq
+388	common	sync_file_range2		sys_sync_file_range2
+# room for arch specific syscalls
+393	common	semget				sys_semget
+394	common	semctl				sys_semctl
+395	common	shmget				sys_shmget
+396	common	shmctl				sys_shmctl
+397	common	shmat				sys_shmat
+398	common	shmdt				sys_shmdt
+399	common	msgget				sys_msgget
+400	common	msgsnd				sys_msgsnd
+401	common	msgrcv				sys_msgrcv
+402	common	msgctl				sys_msgctl
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+# 435 reserved for clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/sh/include/syscall_table.h b/tools/perf/arch/sh/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/sh/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 542f3bee1501c751a831df460c4e585ab756c8fc..2f1b42bf337b3d601f0f2e792bd79413f46e583a 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -203,6 +203,7 @@ check_2 tools/perf/arch/powerpc/entry/syscalls/syscall.tbl arch/powerpc/kernel/s
 check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
+check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:32:56 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:56 -0800
Subject: [PATCH v2 06/16] perf tools: sparc: Support syscall headers
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-6-f8ca984ffe40@rivosinc.com>

sparc uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
 .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 514 +++++++++++++++++++++
 tools/perf/arch/sparc/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 533 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index e7b7257f014e2e58130edf5312bf89d5f7681eef..ee67e39be17215847a2cc85e141938a77bac1b97 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 9ea1d7284fa7a161352121e904b933e34e07dc7f..773f9d1913b02abf526054bcabbec9197fd86c28 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/sparc/entry/syscalls/Kbuild b/tools/perf/arch/sparc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..212c1800b64477c615b8963176d873db5ccabe0c
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscall_abis_64  +=
+syscalltbl = $(srctree)/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sparc/entry/syscalls/syscall.tbl b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..727f99d333b304b3db0711953a3d91ece18a28eb
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
@@ -0,0 +1,514 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for sparc
+#
+# The format is:
+# <number> <abi> <name> <entry point> <compat entry point>
+#
+# The <abi> can be common, 64, or 32 for this file.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	32	exit			sys_exit			sparc_exit
+1	64	exit			sparc_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open			compat_sys_open
+6	common	close			sys_close
+7	common	wait4			sys_wait4			compat_sys_wait4
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	32	execv			sunos_execv
+11	64	execv			sys_nis_syscall
+12	common	chdir			sys_chdir
+13	32    	chown			sys_chown16
+13	64	chown			sys_chown
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	32	lchown			sys_lchown16
+16	64	lchown			sys_lchown
+17	common	brk			sys_brk
+18	common	perfctr			sys_nis_syscall
+19	common	lseek			sys_lseek			compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	capget			sys_capget
+22	common	capset			sys_capset
+23	32    	setuid			sys_setuid16
+23	64    	setuid			sys_setuid
+24	32	getuid			sys_getuid16
+24	64   	getuid			sys_getuid
+25	common	vmsplice		sys_vmsplice
+26	common	ptrace			sys_ptrace			compat_sys_ptrace
+27	common	alarm			sys_alarm
+28	common	sigaltstack		sys_sigaltstack			compat_sys_sigaltstack
+29	32    	pause			sys_pause
+29	64    	pause			sys_nis_syscall
+30	32	utime			sys_utime32
+30	64	utime			sys_utime
+31	32    	lchown32		sys_lchown
+32	32    	fchown32		sys_fchown
+33	common	access			sys_access
+34	common	nice			sys_nice
+35	32    	chown32			sys_chown
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	stat			sys_newstat			compat_sys_newstat
+39	32	sendfile		sys_sendfile			compat_sys_sendfile
+39	64	sendfile		sys_sendfile64
+40	common	lstat			sys_newlstat			compat_sys_newlstat
+41	common	dup			sys_dup
+42	common	pipe			sys_sparc_pipe
+43	common	times			sys_times			compat_sys_times
+44	32    	getuid32		sys_getuid
+45	common	umount2			sys_umount
+46	32	setgid			sys_setgid16
+46	64	setgid			sys_setgid
+47	32	getgid			sys_getgid16
+47	64	getgid			sys_getgid
+48	common	signal			sys_signal
+49	32	geteuid			sys_geteuid16
+49	64	geteuid			sys_geteuid
+50	32	getegid			sys_getegid16
+50	64	getegid			sys_getegid
+51	common	acct			sys_acct
+52	64	memory_ordering		sys_memory_ordering
+53	32	getgid32		sys_getgid
+54	common	ioctl			sys_ioctl			compat_sys_ioctl
+55	common	reboot			sys_reboot
+56	32    	mmap2			sys_mmap2			sys32_mmap2
+57	common	symlink			sys_symlink
+58	common	readlink		sys_readlink
+59	32	execve			sys_execve			sys32_execve
+59	64	execve			sys64_execve
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	fstat			sys_newfstat			compat_sys_newfstat
+63	common	fstat64			sys_fstat64			compat_sys_fstat64
+64	common	getpagesize		sys_getpagesize
+65	common	msync			sys_msync
+66	common	vfork			sys_vfork
+67	common	pread64			sys_pread64			compat_sys_pread64
+68	common	pwrite64		sys_pwrite64			compat_sys_pwrite64
+69	32    	geteuid32		sys_geteuid
+70	32	getegid32		sys_getegid
+71	common	mmap			sys_mmap
+72	32	setreuid32		sys_setreuid
+73	32	munmap			sys_munmap
+73	64	munmap			sys_64_munmap
+74	common	mprotect		sys_mprotect
+75	common	madvise			sys_madvise
+76	common	vhangup			sys_vhangup
+77	32	truncate64		sys_truncate64			compat_sys_truncate64
+78	common	mincore			sys_mincore
+79	32	getgroups		sys_getgroups16
+79	64	getgroups		sys_getgroups
+80	32	setgroups		sys_setgroups16
+80	64	setgroups		sys_setgroups
+81	common	getpgrp			sys_getpgrp
+82	32	setgroups32		sys_setgroups
+83	common	setitimer		sys_setitimer			compat_sys_setitimer
+84	32	ftruncate64		sys_ftruncate64			compat_sys_ftruncate64
+85	common	swapon			sys_swapon
+86	common	getitimer		sys_getitimer			compat_sys_getitimer
+87	32	setuid32		sys_setuid
+88	common	sethostname		sys_sethostname
+89	32	setgid32		sys_setgid
+90	common	dup2			sys_dup2
+91	32	setfsuid32		sys_setfsuid
+92	common	fcntl			sys_fcntl			compat_sys_fcntl
+93	common	select			sys_select			compat_sys_select
+94	32	setfsgid32		sys_setfsgid
+95	common	fsync			sys_fsync
+96	common	setpriority		sys_setpriority
+97	common	socket			sys_socket
+98	common	connect			sys_connect
+99	common	accept			sys_accept
+100	common	getpriority		sys_getpriority
+101	common	rt_sigreturn		sys_rt_sigreturn		sys32_rt_sigreturn
+102	common	rt_sigaction		sys_rt_sigaction		compat_sys_rt_sigaction
+103	common	rt_sigprocmask		sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+104	common	rt_sigpending		sys_rt_sigpending		compat_sys_rt_sigpending
+105	32	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+105	64	rt_sigtimedwait		sys_rt_sigtimedwait
+106	common	rt_sigqueueinfo		sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+107	common	rt_sigsuspend		sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+108	32	setresuid32		sys_setresuid
+108	64	setresuid		sys_setresuid
+109	32	getresuid32		sys_getresuid
+109	64	getresuid		sys_getresuid
+110	32	setresgid32		sys_setresgid
+110	64	setresgid		sys_setresgid
+111	32	getresgid32		sys_getresgid
+111	64	getresgid		sys_getresgid
+112	32	setregid32		sys_setregid
+113	common	recvmsg			sys_recvmsg			compat_sys_recvmsg
+114	common	sendmsg			sys_sendmsg			compat_sys_sendmsg
+115	32	getgroups32		sys_getgroups
+116	common	gettimeofday		sys_gettimeofday		compat_sys_gettimeofday
+117	common	getrusage		sys_getrusage			compat_sys_getrusage
+118	common	getsockopt		sys_getsockopt			sys_getsockopt
+119	common	getcwd			sys_getcwd
+120	common	readv			sys_readv
+121	common	writev			sys_writev
+122	common	settimeofday		sys_settimeofday		compat_sys_settimeofday
+123	32	fchown			sys_fchown16
+123	64	fchown			sys_fchown
+124	common	fchmod			sys_fchmod
+125	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
+126	32	setreuid		sys_setreuid16
+126	64	setreuid		sys_setreuid
+127	32	setregid		sys_setregid16
+127	64	setregid		sys_setregid
+128	common	rename			sys_rename
+129	common	truncate		sys_truncate			compat_sys_truncate
+130	common	ftruncate		sys_ftruncate			compat_sys_ftruncate
+131	common	flock			sys_flock
+132	common	lstat64			sys_lstat64			compat_sys_lstat64
+133	common	sendto			sys_sendto
+134	common	shutdown		sys_shutdown
+135	common	socketpair		sys_socketpair
+136	common	mkdir			sys_mkdir
+137	common	rmdir			sys_rmdir
+138	32	utimes			sys_utimes_time32
+138	64	utimes			sys_utimes
+139	common	stat64			sys_stat64			compat_sys_stat64
+140	common	sendfile64		sys_sendfile64
+141	common	getpeername		sys_getpeername
+142	32	futex			sys_futex_time32
+142	64	futex			sys_futex
+143	common	gettid			sys_gettid
+144	common	getrlimit		sys_getrlimit			compat_sys_getrlimit
+145	common	setrlimit		sys_setrlimit			compat_sys_setrlimit
+146	common	pivot_root		sys_pivot_root
+147	common	prctl			sys_prctl
+148	common	pciconfig_read		sys_pciconfig_read
+149	common	pciconfig_write		sys_pciconfig_write
+150	common	getsockname		sys_getsockname
+151	common	inotify_init		sys_inotify_init
+152	common	inotify_add_watch	sys_inotify_add_watch
+153	common	poll			sys_poll
+154	common	getdents64		sys_getdents64
+155	32	fcntl64			sys_fcntl64			compat_sys_fcntl64
+156	common	inotify_rm_watch	sys_inotify_rm_watch
+157	common	statfs			sys_statfs			compat_sys_statfs
+158	common	fstatfs			sys_fstatfs			compat_sys_fstatfs
+159	common	umount			sys_oldumount
+160	common	sched_set_affinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+161	common	sched_get_affinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+162	common	getdomainname		sys_getdomainname
+163	common	setdomainname		sys_setdomainname
+164	64	utrap_install		sys_utrap_install
+165	common	quotactl		sys_quotactl
+166	common	set_tid_address		sys_set_tid_address
+167	common	mount			sys_mount
+168	common	ustat			sys_ustat			compat_sys_ustat
+169	common	setxattr		sys_setxattr
+170	common	lsetxattr		sys_lsetxattr
+171	common	fsetxattr		sys_fsetxattr
+172	common	getxattr		sys_getxattr
+173	common	lgetxattr		sys_lgetxattr
+174	common	getdents		sys_getdents			compat_sys_getdents
+175	common	setsid			sys_setsid
+176	common	fchdir			sys_fchdir
+177	common	fgetxattr		sys_fgetxattr
+178	common	listxattr		sys_listxattr
+179	common	llistxattr		sys_llistxattr
+180	common	flistxattr		sys_flistxattr
+181	common	removexattr		sys_removexattr
+182	common	lremovexattr		sys_lremovexattr
+183	32	sigpending		sys_sigpending			compat_sys_sigpending
+183	64	sigpending		sys_nis_syscall
+184	common	query_module		sys_ni_syscall
+185	common	setpgid			sys_setpgid
+186	common	fremovexattr		sys_fremovexattr
+187	common	tkill			sys_tkill
+188	32	exit_group		sys_exit_group			sparc_exit_group
+188	64	exit_group		sparc_exit_group
+189	common	uname			sys_newuname
+190	common	init_module		sys_init_module
+191	32	personality		sys_personality			sys_sparc64_personality
+191	64	personality		sys_sparc64_personality
+192	32	remap_file_pages	sys_sparc_remap_file_pages	sys_remap_file_pages
+192	64	remap_file_pages	sys_remap_file_pages
+193	common	epoll_create		sys_epoll_create
+194	common	epoll_ctl		sys_epoll_ctl
+195	common	epoll_wait		sys_epoll_wait
+196	common	ioprio_set		sys_ioprio_set
+197	common	getppid			sys_getppid
+198	32	sigaction		sys_sparc_sigaction		compat_sys_sparc_sigaction
+198	64	sigaction		sys_nis_syscall
+199	common	sgetmask		sys_sgetmask
+200	common	ssetmask		sys_ssetmask
+201	32	sigsuspend		sys_sigsuspend
+201	64	sigsuspend		sys_nis_syscall
+202	common	oldlstat		sys_newlstat			compat_sys_newlstat
+203	common	uselib			sys_uselib
+204	32	readdir			sys_old_readdir			compat_sys_old_readdir
+204	64	readdir			sys_nis_syscall
+205	common	readahead		sys_readahead			compat_sys_readahead
+206	common	socketcall		sys_socketcall			compat_sys_socketcall
+207	common	syslog			sys_syslog
+208	common	lookup_dcookie		sys_ni_syscall
+209	common	fadvise64		sys_fadvise64			compat_sys_fadvise64
+210	common	fadvise64_64		sys_fadvise64_64		compat_sys_fadvise64_64
+211	common	tgkill			sys_tgkill
+212	common	waitpid			sys_waitpid
+213	common	swapoff			sys_swapoff
+214	common	sysinfo			sys_sysinfo			compat_sys_sysinfo
+215	32	ipc			sys_ipc				compat_sys_ipc
+215	64	ipc			sys_sparc_ipc
+216	32	sigreturn		sys_sigreturn			sys32_sigreturn
+216	64	sigreturn		sys_nis_syscall
+217	common	clone			sys_clone
+218	common	ioprio_get		sys_ioprio_get
+219	32	adjtimex		sys_adjtimex_time32
+219	64	adjtimex		sys_sparc_adjtimex
+220	32	sigprocmask		sys_sigprocmask			compat_sys_sigprocmask
+220	64	sigprocmask		sys_nis_syscall
+221	common	create_module		sys_ni_syscall
+222	common	delete_module		sys_delete_module
+223	common	get_kernel_syms		sys_ni_syscall
+224	common	getpgid			sys_getpgid
+225	common	bdflush			sys_ni_syscall
+226	common	sysfs			sys_sysfs
+227	common	afs_syscall		sys_nis_syscall
+228	common	setfsuid		sys_setfsuid16
+229	common	setfsgid		sys_setfsgid16
+230	common	_newselect		sys_select			compat_sys_select
+231	32	time			sys_time32
+232	common	splice			sys_splice
+233	32	stime			sys_stime32
+233	64	stime			sys_stime
+234	common	statfs64		sys_statfs64			compat_sys_statfs64
+235	common	fstatfs64		sys_fstatfs64			compat_sys_fstatfs64
+236	common	_llseek			sys_llseek
+237	common	mlock			sys_mlock
+238	common	munlock			sys_munlock
+239	common	mlockall		sys_mlockall
+240	common	munlockall		sys_munlockall
+241	common	sched_setparam		sys_sched_setparam
+242	common	sched_getparam		sys_sched_getparam
+243	common	sched_setscheduler	sys_sched_setscheduler
+244	common	sched_getscheduler	sys_sched_getscheduler
+245	common	sched_yield		sys_sched_yield
+246	common	sched_get_priority_max	sys_sched_get_priority_max
+247	common	sched_get_priority_min	sys_sched_get_priority_min
+248	32	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+248	64	sched_rr_get_interval	sys_sched_rr_get_interval
+249	32	nanosleep		sys_nanosleep_time32
+249	64	nanosleep		sys_nanosleep
+250	32	mremap			sys_mremap
+250	64	mremap			sys_64_mremap
+251	common	_sysctl			sys_ni_syscall
+252	common	getsid			sys_getsid
+253	common	fdatasync		sys_fdatasync
+254	32	nfsservctl		sys_ni_syscall			sys_nis_syscall
+254	64	nfsservctl		sys_nis_syscall
+255	common	sync_file_range		sys_sync_file_range		compat_sys_sync_file_range
+256	32	clock_settime		sys_clock_settime32
+256	64	clock_settime		sys_clock_settime
+257	32	clock_gettime		sys_clock_gettime32
+257	64	clock_gettime		sys_clock_gettime
+258	32	clock_getres		sys_clock_getres_time32
+258	64	clock_getres		sys_clock_getres
+259	32	clock_nanosleep		sys_clock_nanosleep_time32
+259	64	clock_nanosleep		sys_clock_nanosleep
+260	common	sched_getaffinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+261	common	sched_setaffinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+262	32	timer_settime		sys_timer_settime32
+262	64	timer_settime		sys_timer_settime
+263	32	timer_gettime		sys_timer_gettime32
+263	64	timer_gettime		sys_timer_gettime
+264	common	timer_getoverrun	sys_timer_getoverrun
+265	common	timer_delete		sys_timer_delete
+266	common	timer_create		sys_timer_create		compat_sys_timer_create
+# 267 was vserver
+267	common	vserver			sys_nis_syscall
+268	common	io_setup		sys_io_setup			compat_sys_io_setup
+269	common	io_destroy		sys_io_destroy
+270	common	io_submit		sys_io_submit			compat_sys_io_submit
+271	common	io_cancel		sys_io_cancel
+272	32	io_getevents		sys_io_getevents_time32
+272	64	io_getevents		sys_io_getevents
+273	common	mq_open			sys_mq_open			compat_sys_mq_open
+274	common	mq_unlink		sys_mq_unlink
+275	32	mq_timedsend		sys_mq_timedsend_time32
+275	64	mq_timedsend		sys_mq_timedsend
+276	32	mq_timedreceive		sys_mq_timedreceive_time32
+276	64	mq_timedreceive		sys_mq_timedreceive
+277	common	mq_notify		sys_mq_notify			compat_sys_mq_notify
+278	common	mq_getsetattr		sys_mq_getsetattr		compat_sys_mq_getsetattr
+279	common	waitid			sys_waitid			compat_sys_waitid
+280	common	tee			sys_tee
+281	common	add_key			sys_add_key
+282	common	request_key		sys_request_key
+283	common	keyctl			sys_keyctl			compat_sys_keyctl
+284	common	openat			sys_openat			compat_sys_openat
+285	common	mkdirat			sys_mkdirat
+286	common	mknodat			sys_mknodat
+287	common	fchownat		sys_fchownat
+288	32	futimesat		sys_futimesat_time32
+288	64	futimesat		sys_futimesat
+289	common	fstatat64		sys_fstatat64			compat_sys_fstatat64
+290	common	unlinkat		sys_unlinkat
+291	common	renameat		sys_renameat
+292	common	linkat			sys_linkat
+293	common	symlinkat		sys_symlinkat
+294	common	readlinkat		sys_readlinkat
+295	common	fchmodat		sys_fchmodat
+296	common	faccessat		sys_faccessat
+297	32	pselect6		sys_pselect6_time32		compat_sys_pselect6_time32
+297	64	pselect6		sys_pselect6
+298	32	ppoll			sys_ppoll_time32		compat_sys_ppoll_time32
+298	64	ppoll			sys_ppoll
+299	common	unshare			sys_unshare
+300	common	set_robust_list		sys_set_robust_list		compat_sys_set_robust_list
+301	common	get_robust_list		sys_get_robust_list		compat_sys_get_robust_list
+302	common	migrate_pages		sys_migrate_pages
+303	common	mbind			sys_mbind
+304	common	get_mempolicy		sys_get_mempolicy
+305	common	set_mempolicy		sys_set_mempolicy
+306	common	kexec_load		sys_kexec_load			compat_sys_kexec_load
+307	common	move_pages		sys_move_pages
+308	common	getcpu			sys_getcpu
+309	common	epoll_pwait		sys_epoll_pwait			compat_sys_epoll_pwait
+310	32	utimensat		sys_utimensat_time32
+310	64	utimensat		sys_utimensat
+311	common	signalfd		sys_signalfd			compat_sys_signalfd
+312	common	timerfd_create		sys_timerfd_create
+313	common	eventfd			sys_eventfd
+314	common	fallocate		sys_fallocate			compat_sys_fallocate
+315	32	timerfd_settime		sys_timerfd_settime32
+315	64	timerfd_settime		sys_timerfd_settime
+316	32	timerfd_gettime		sys_timerfd_gettime32
+316	64	timerfd_gettime		sys_timerfd_gettime
+317	common	signalfd4		sys_signalfd4			compat_sys_signalfd4
+318	common	eventfd2		sys_eventfd2
+319	common	epoll_create1		sys_epoll_create1
+320	common	dup3			sys_dup3
+321	common	pipe2			sys_pipe2
+322	common	inotify_init1		sys_inotify_init1
+323	common	accept4			sys_accept4
+324	common	preadv			sys_preadv			compat_sys_preadv
+325	common	pwritev			sys_pwritev			compat_sys_pwritev
+326	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+327	common	perf_event_open		sys_perf_event_open
+328	32	recvmmsg		sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+328	64	recvmmsg		sys_recvmmsg
+329	common	fanotify_init		sys_fanotify_init
+330	common	fanotify_mark		sys_fanotify_mark		compat_sys_fanotify_mark
+331	common	prlimit64		sys_prlimit64
+332	common	name_to_handle_at	sys_name_to_handle_at
+333	common	open_by_handle_at	sys_open_by_handle_at		compat_sys_open_by_handle_at
+334	32	clock_adjtime		sys_clock_adjtime32
+334	64	clock_adjtime		sys_sparc_clock_adjtime
+335	common	syncfs			sys_syncfs
+336	common	sendmmsg		sys_sendmmsg			compat_sys_sendmmsg
+337	common	setns			sys_setns
+338	common	process_vm_readv	sys_process_vm_readv
+339	common	process_vm_writev	sys_process_vm_writev
+340	32	kern_features		sys_ni_syscall			sys_kern_features
+340	64	kern_features		sys_kern_features
+341	common	kcmp			sys_kcmp
+342	common	finit_module		sys_finit_module
+343	common	sched_setattr		sys_sched_setattr
+344	common	sched_getattr		sys_sched_getattr
+345	common	renameat2		sys_renameat2
+346	common	seccomp			sys_seccomp
+347	common	getrandom		sys_getrandom
+348	common	memfd_create		sys_memfd_create
+349	common	bpf			sys_bpf
+350	32	execveat		sys_execveat			sys32_execveat
+350	64	execveat		sys64_execveat
+351	common	membarrier		sys_membarrier
+352	common	userfaultfd		sys_userfaultfd
+353	common	bind			sys_bind
+354	common	listen			sys_listen
+355	common	setsockopt		sys_setsockopt			sys_setsockopt
+356	common	mlock2			sys_mlock2
+357	common	copy_file_range		sys_copy_file_range
+358	common	preadv2			sys_preadv2			compat_sys_preadv2
+359	common	pwritev2		sys_pwritev2			compat_sys_pwritev2
+360	common	statx			sys_statx
+361	32	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+361	64	io_pgetevents		sys_io_pgetevents
+362	common	pkey_mprotect		sys_pkey_mprotect
+363	common	pkey_alloc		sys_pkey_alloc
+364	common	pkey_free		sys_pkey_free
+365	common	rseq			sys_rseq
+# room for arch specific syscalls
+392	64	semtimedop			sys_semtimedop
+393	common	semget			sys_semget
+394	common	semctl			sys_semctl			compat_sys_semctl
+395	common	shmget			sys_shmget
+396	common	shmctl			sys_shmctl			compat_sys_shmctl
+397	common	shmat			sys_shmat			compat_sys_shmat
+398	common	shmdt			sys_shmdt
+399	common	msgget			sys_msgget
+400	common	msgsnd			sys_msgsnd			compat_sys_msgsnd
+401	common	msgrcv			sys_msgrcv			compat_sys_msgrcv
+402	common	msgctl			sys_msgctl			compat_sys_msgctl
+403	32	clock_gettime64			sys_clock_gettime		sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime		sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime		sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime		sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime		sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat			sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop			sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+# 435 reserved for clone3
+436	common	close_range			sys_close_range
+437	common	openat2			sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal 				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/sparc/include/syscall_table.h b/tools/perf/arch/sparc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/sparc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 2f1b42bf337b3d601f0f2e792bd79413f46e583a..99a278a3f1b5bf44132c817ed1f2623a232d3dc5 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -204,6 +204,7 @@ check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscall
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:32:57 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:57 -0800
Subject: [PATCH v2 07/16] perf tools: xtensa: Support syscall header
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-7-f8ca984ffe40@rivosinc.com>

xtensa uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
 .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 439 +++++++++++++++++++++
 tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 450 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index ee67e39be17215847a2cc85e141938a77bac1b97..9348c1e72bf00f43faf1c9aadab171236e6c3621 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 773f9d1913b02abf526054bcabbec9197fd86c28..c7e1c6b7f8d97dddf07eab122a169b379ec43a19 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Kbuild b/tools/perf/arch/xtensa/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls b/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..d4aa2358460c13945a8299b6513c93d35a5c5ea4
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscalltbl = $(srctree)/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..37effc1b134eea061f2c350c1d68b4436b65a4dd
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
@@ -0,0 +1,439 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for xtensa
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	spill				sys_ni_syscall
+1	common	xtensa				sys_ni_syscall
+2	common	available4			sys_ni_syscall
+3	common	available5			sys_ni_syscall
+4	common	available6			sys_ni_syscall
+5	common	available7			sys_ni_syscall
+6	common	available8			sys_ni_syscall
+7	common	available9			sys_ni_syscall
+# File Operations
+8	common	open				sys_open
+9	common	close				sys_close
+10	common	dup				sys_dup
+11	common	dup2				sys_dup2
+12	common	read				sys_read
+13	common	write				sys_write
+14	common	select				sys_select
+15	common	lseek				sys_lseek
+16	common	poll				sys_poll
+17	common	_llseek				sys_llseek
+18	common	epoll_wait			sys_epoll_wait
+19	common	epoll_ctl			sys_epoll_ctl
+20	common	epoll_create			sys_epoll_create
+21	common	creat				sys_creat
+22	common	truncate			sys_truncate
+23	common	ftruncate			sys_ftruncate
+24	common	readv				sys_readv
+25	common	writev				sys_writev
+26	common	fsync				sys_fsync
+27	common	fdatasync			sys_fdatasync
+28	common	truncate64			sys_truncate64
+29	common	ftruncate64			sys_ftruncate64
+30	common	pread64				sys_pread64
+31	common	pwrite64			sys_pwrite64
+32	common	link				sys_link
+33	common	rename				sys_rename
+34	common	symlink				sys_symlink
+35	common	readlink			sys_readlink
+36	common	mknod				sys_mknod
+37	common	pipe				sys_pipe
+38	common	unlink				sys_unlink
+39	common	rmdir				sys_rmdir
+40	common	mkdir				sys_mkdir
+41	common	chdir				sys_chdir
+42	common	fchdir				sys_fchdir
+43	common	getcwd				sys_getcwd
+44	common	chmod				sys_chmod
+45	common	chown				sys_chown
+46	common	stat				sys_newstat
+47	common	stat64				sys_stat64
+48	common	lchown				sys_lchown
+49	common	lstat				sys_newlstat
+50	common	lstat64				sys_lstat64
+51	common	available51			sys_ni_syscall
+52	common	fchmod				sys_fchmod
+53	common	fchown				sys_fchown
+54	common	fstat				sys_newfstat
+55	common	fstat64				sys_fstat64
+56	common	flock				sys_flock
+57	common	access				sys_access
+58	common	umask				sys_umask
+59	common	getdents			sys_getdents
+60	common	getdents64			sys_getdents64
+61	common	fcntl64				sys_fcntl64
+62	common	fallocate			sys_fallocate
+63	common	fadvise64_64			xtensa_fadvise64_64
+64	common	utime				sys_utime32
+65	common	utimes				sys_utimes_time32
+66	common	ioctl				sys_ioctl
+67	common	fcntl				sys_fcntl
+68	common	setxattr			sys_setxattr
+69	common	getxattr			sys_getxattr
+70	common	listxattr			sys_listxattr
+71	common	removexattr			sys_removexattr
+72	common	lsetxattr			sys_lsetxattr
+73	common	lgetxattr			sys_lgetxattr
+74	common	llistxattr			sys_llistxattr
+75	common	lremovexattr			sys_lremovexattr
+76	common	fsetxattr			sys_fsetxattr
+77	common	fgetxattr			sys_fgetxattr
+78	common	flistxattr			sys_flistxattr
+79	common	fremovexattr			sys_fremovexattr
+# File Map / Shared Memory Operations
+80	common	mmap2				sys_mmap_pgoff
+81	common	munmap				sys_munmap
+82	common	mprotect			sys_mprotect
+83	common	brk				sys_brk
+84	common	mlock				sys_mlock
+85	common	munlock				sys_munlock
+86	common	mlockall			sys_mlockall
+87	common	munlockall			sys_munlockall
+88	common	mremap				sys_mremap
+89	common	msync				sys_msync
+90	common	mincore				sys_mincore
+91	common	madvise				sys_madvise
+92	common	shmget				sys_shmget
+93	common	shmat				xtensa_shmat
+94	common	shmctl				sys_old_shmctl
+95	common	shmdt				sys_shmdt
+# Socket Operations
+96	common	socket				sys_socket
+97	common	setsockopt			sys_setsockopt
+98	common	getsockopt			sys_getsockopt
+99	common	shutdown			sys_shutdown
+100	common	bind				sys_bind
+101	common	connect				sys_connect
+102	common	listen				sys_listen
+103	common	accept				sys_accept
+104	common	getsockname			sys_getsockname
+105	common	getpeername			sys_getpeername
+106	common	sendmsg				sys_sendmsg
+107	common	recvmsg				sys_recvmsg
+108	common	send				sys_send
+109	common	recv				sys_recv
+110	common	sendto				sys_sendto
+111	common	recvfrom			sys_recvfrom
+112	common	socketpair			sys_socketpair
+113	common	sendfile			sys_sendfile
+114	common	sendfile64			sys_sendfile64
+115	common	sendmmsg			sys_sendmmsg
+# Process Operations
+116	common	clone				sys_clone
+117	common	execve				sys_execve
+118	common	exit				sys_exit
+119	common	exit_group			sys_exit_group
+120	common	getpid				sys_getpid
+121	common	wait4				sys_wait4
+122	common	waitid				sys_waitid
+123	common	kill				sys_kill
+124	common	tkill				sys_tkill
+125	common	tgkill				sys_tgkill
+126	common	set_tid_address			sys_set_tid_address
+127	common	gettid				sys_gettid
+128	common	setsid				sys_setsid
+129	common	getsid				sys_getsid
+130	common	prctl				sys_prctl
+131	common	personality			sys_personality
+132	common	getpriority			sys_getpriority
+133	common	setpriority			sys_setpriority
+134	common	setitimer			sys_setitimer
+135	common	getitimer			sys_getitimer
+136	common	setuid				sys_setuid
+137	common	getuid				sys_getuid
+138	common	setgid				sys_setgid
+139	common	getgid				sys_getgid
+140	common	geteuid				sys_geteuid
+141	common	getegid				sys_getegid
+142	common	setreuid			sys_setreuid
+143	common	setregid			sys_setregid
+144	common	setresuid			sys_setresuid
+145	common	getresuid			sys_getresuid
+146	common	setresgid			sys_setresgid
+147	common	getresgid			sys_getresgid
+148	common	setpgid				sys_setpgid
+149	common	getpgid				sys_getpgid
+150	common	getppid				sys_getppid
+151	common	getpgrp				sys_getpgrp
+# 152 was set_thread_area
+152	common	reserved152			sys_ni_syscall
+# 153 was get_thread_area
+153	common	reserved153			sys_ni_syscall
+154	common	times				sys_times
+155	common	acct				sys_acct
+156	common	sched_setaffinity		sys_sched_setaffinity
+157	common	sched_getaffinity		sys_sched_getaffinity
+158	common	capget				sys_capget
+159	common	capset				sys_capset
+160	common	ptrace				sys_ptrace
+161	common	semtimedop			sys_semtimedop_time32
+162	common	semget				sys_semget
+163	common	semop				sys_semop
+164	common	semctl				sys_old_semctl
+165	common	available165			sys_ni_syscall
+166	common	msgget				sys_msgget
+167	common	msgsnd				sys_msgsnd
+168	common	msgrcv				sys_msgrcv
+169	common	msgctl				sys_old_msgctl
+170	common	available170			sys_ni_syscall
+# File System
+171	common	umount2				sys_umount
+172	common	mount				sys_mount
+173	common	swapon				sys_swapon
+174	common	chroot				sys_chroot
+175	common	pivot_root			sys_pivot_root
+176	common	umount				sys_oldumount
+177	common	swapoff				sys_swapoff
+178	common	sync				sys_sync
+179	common	syncfs				sys_syncfs
+180	common	setfsuid			sys_setfsuid
+181	common	setfsgid			sys_setfsgid
+182	common	sysfs				sys_sysfs
+183	common	ustat				sys_ustat
+184	common	statfs				sys_statfs
+185	common	fstatfs				sys_fstatfs
+186	common	statfs64			sys_statfs64
+187	common	fstatfs64			sys_fstatfs64
+# System
+188	common	setrlimit			sys_setrlimit
+189	common	getrlimit			sys_getrlimit
+190	common	getrusage			sys_getrusage
+191	common	futex				sys_futex_time32
+192	common	gettimeofday			sys_gettimeofday
+193	common	settimeofday			sys_settimeofday
+194	common	adjtimex			sys_adjtimex_time32
+195	common	nanosleep			sys_nanosleep_time32
+196	common	getgroups			sys_getgroups
+197	common	setgroups			sys_setgroups
+198	common	sethostname			sys_sethostname
+199	common	setdomainname			sys_setdomainname
+200	common	syslog				sys_syslog
+201	common	vhangup				sys_vhangup
+202	common	uselib				sys_uselib
+203	common	reboot				sys_reboot
+204	common	quotactl			sys_quotactl
+# 205 was old nfsservctl
+205	common	nfsservctl			sys_ni_syscall
+206	common	_sysctl				sys_ni_syscall
+207	common	bdflush				sys_ni_syscall
+208	common	uname				sys_newuname
+209	common	sysinfo				sys_sysinfo
+210	common	init_module			sys_init_module
+211	common	delete_module			sys_delete_module
+212	common	sched_setparam			sys_sched_setparam
+213	common	sched_getparam			sys_sched_getparam
+214	common	sched_setscheduler		sys_sched_setscheduler
+215	common	sched_getscheduler		sys_sched_getscheduler
+216	common	sched_get_priority_max		sys_sched_get_priority_max
+217	common	sched_get_priority_min		sys_sched_get_priority_min
+218	common	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+219	common	sched_yield			sys_sched_yield
+222	common	available222			sys_ni_syscall
+# Signal Handling
+223	common	restart_syscall			sys_restart_syscall
+224	common	sigaltstack			sys_sigaltstack
+225	common	rt_sigreturn			xtensa_rt_sigreturn
+226	common	rt_sigaction			sys_rt_sigaction
+227	common	rt_sigprocmask			sys_rt_sigprocmask
+228	common	rt_sigpending			sys_rt_sigpending
+229	common	rt_sigtimedwait			sys_rt_sigtimedwait_time32
+230	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+231	common	rt_sigsuspend			sys_rt_sigsuspend
+# Message
+232	common	mq_open				sys_mq_open
+233	common	mq_unlink			sys_mq_unlink
+234	common	mq_timedsend			sys_mq_timedsend_time32
+235	common	mq_timedreceive			sys_mq_timedreceive_time32
+236	common	mq_notify			sys_mq_notify
+237	common	mq_getsetattr			sys_mq_getsetattr
+238	common	available238			sys_ni_syscall
+239	common	io_setup			sys_io_setup
+# IO
+240	common	io_destroy			sys_io_destroy
+241	common	io_submit			sys_io_submit
+242	common	io_getevents			sys_io_getevents_time32
+243	common	io_cancel			sys_io_cancel
+244	common	clock_settime			sys_clock_settime32
+245	common	clock_gettime			sys_clock_gettime32
+246	common	clock_getres			sys_clock_getres_time32
+247	common	clock_nanosleep			sys_clock_nanosleep_time32
+# Timer
+248	common	timer_create			sys_timer_create
+249	common	timer_delete			sys_timer_delete
+250	common	timer_settime			sys_timer_settime32
+251	common	timer_gettime			sys_timer_gettime32
+252	common	timer_getoverrun		sys_timer_getoverrun
+# System
+253	common	reserved253			sys_ni_syscall
+254	common	lookup_dcookie			sys_ni_syscall
+255	common	available255			sys_ni_syscall
+256	common	add_key				sys_add_key
+257	common	request_key			sys_request_key
+258	common	keyctl				sys_keyctl
+259	common	available259			sys_ni_syscall
+260	common	readahead			sys_readahead
+261	common	remap_file_pages		sys_remap_file_pages
+262	common	migrate_pages			sys_migrate_pages
+263	common	mbind				sys_mbind
+264	common	get_mempolicy			sys_get_mempolicy
+265	common	set_mempolicy			sys_set_mempolicy
+266	common	unshare				sys_unshare
+267	common	move_pages			sys_move_pages
+268	common	splice				sys_splice
+269	common	tee				sys_tee
+270	common	vmsplice			sys_vmsplice
+271	common	available271			sys_ni_syscall
+272	common	pselect6			sys_pselect6_time32
+273	common	ppoll				sys_ppoll_time32
+274	common	epoll_pwait			sys_epoll_pwait
+275	common	epoll_create1			sys_epoll_create1
+276	common	inotify_init			sys_inotify_init
+277	common	inotify_add_watch		sys_inotify_add_watch
+278	common	inotify_rm_watch		sys_inotify_rm_watch
+279	common	inotify_init1			sys_inotify_init1
+280	common	getcpu				sys_getcpu
+281	common	kexec_load			sys_ni_syscall
+282	common	ioprio_set			sys_ioprio_set
+283	common	ioprio_get			sys_ioprio_get
+284	common	set_robust_list			sys_set_robust_list
+285	common	get_robust_list			sys_get_robust_list
+286	common	available286			sys_ni_syscall
+287	common	available287			sys_ni_syscall
+# Relative File Operations
+288	common	openat				sys_openat
+289	common	mkdirat				sys_mkdirat
+290	common	mknodat				sys_mknodat
+291	common	unlinkat			sys_unlinkat
+292	common	renameat			sys_renameat
+293	common	linkat				sys_linkat
+294	common	symlinkat			sys_symlinkat
+295	common	readlinkat			sys_readlinkat
+296	common	utimensat			sys_utimensat_time32
+297	common	fchownat			sys_fchownat
+298	common	futimesat			sys_futimesat_time32
+299	common	fstatat64			sys_fstatat64
+300	common	fchmodat			sys_fchmodat
+301	common	faccessat			sys_faccessat
+302	common	available302			sys_ni_syscall
+303	common	available303			sys_ni_syscall
+304	common	signalfd			sys_signalfd
+# 305 was timerfd
+306	common	eventfd				sys_eventfd
+307	common	recvmmsg			sys_recvmmsg_time32
+308	common	setns				sys_setns
+309	common	signalfd4			sys_signalfd4
+310	common	dup3				sys_dup3
+311	common	pipe2				sys_pipe2
+312	common	timerfd_create			sys_timerfd_create
+313	common	timerfd_settime			sys_timerfd_settime32
+314	common	timerfd_gettime			sys_timerfd_gettime32
+315	common	available315			sys_ni_syscall
+316	common	eventfd2			sys_eventfd2
+317	common	preadv				sys_preadv
+318	common	pwritev				sys_pwritev
+319	common	available319			sys_ni_syscall
+320	common	fanotify_init			sys_fanotify_init
+321	common	fanotify_mark			sys_fanotify_mark
+322	common	process_vm_readv		sys_process_vm_readv
+323	common	process_vm_writev		sys_process_vm_writev
+324	common	name_to_handle_at		sys_name_to_handle_at
+325	common	open_by_handle_at		sys_open_by_handle_at
+326	common	sync_file_range2		sys_sync_file_range2
+327	common	perf_event_open			sys_perf_event_open
+328	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+329	common	clock_adjtime			sys_clock_adjtime32
+330	common	prlimit64			sys_prlimit64
+331	common	kcmp				sys_kcmp
+332	common	finit_module			sys_finit_module
+333	common	accept4				sys_accept4
+334	common	sched_setattr			sys_sched_setattr
+335	common	sched_getattr			sys_sched_getattr
+336	common	renameat2			sys_renameat2
+337	common	seccomp				sys_seccomp
+338	common	getrandom			sys_getrandom
+339	common	memfd_create			sys_memfd_create
+340	common	bpf				sys_bpf
+341	common	execveat			sys_execveat
+342	common	userfaultfd			sys_userfaultfd
+343	common	membarrier			sys_membarrier
+344	common	mlock2				sys_mlock2
+345	common	copy_file_range			sys_copy_file_range
+346	common	preadv2				sys_preadv2
+347	common	pwritev2			sys_pwritev2
+348	common	pkey_mprotect			sys_pkey_mprotect
+349	common	pkey_alloc			sys_pkey_alloc
+350	common	pkey_free			sys_pkey_free
+351	common	statx				sys_statx
+352	common	rseq				sys_rseq
+# 353 through 402 are unassigned to sync up with generic numbers
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal 				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/xtensa/include/syscall_table.h b/tools/perf/arch/xtensa/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/xtensa/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 99a278a3f1b5bf44132c817ed1f2623a232d3dc5..e9e352579e6d33085a1d863441432c81d2353f49 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -205,6 +205,7 @@ check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/sys
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:32:58 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:58 -0800
Subject: [PATCH v2 08/16] perf tools: x86: Use generic syscall scripts
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-8-f8ca984ffe40@rivosinc.com>

Use the generic scripts to generate headers from the syscall table for
both 32- and 64-bit x86.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  5 ++-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/x86/Build                          |  1 -
 tools/perf/arch/x86/Makefile                       | 25 -------------
 tools/perf/arch/x86/entry/syscalls/Kbuild          |  3 ++
 .../perf/arch/x86/entry/syscalls/Makefile.syscalls |  6 ++++
 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   | 42 ----------------------
 tools/perf/arch/x86/include/syscall_table.h        |  8 +++++
 tools/perf/util/syscalltbl.c                       | 10 +-----
 9 files changed, 21 insertions(+), 81 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 9348c1e72bf00f43faf1c9aadab171236e6c3621..ada51e0dc17fbf5012e606ffc0b580c6993ebe64 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 powerpc arm64 s390 mips loongarch riscv))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips loongarch))
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
@@ -56,7 +56,6 @@ endif
 # Additional ARCH settings for x86
 ifeq ($(SRCARCH),x86)
   $(call detected,CONFIG_X86)
-  CFLAGS += -I$(OUTPUT)arch/x86/include/generated
   ifeq (${IS_64_BIT}, 1)
     CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT
     ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c7e1c6b7f8d97dddf07eab122a169b379ec43a19..efce35bb535b8ce4c20ee0a9250a548e4af1fbce 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/x86/Build b/tools/perf/arch/x86/Build
index 87d0574913431b7c4505caf78f41d48b180a2fbc..02a1ca780a2071d322f75fb2885c3a36bc278e8d 100644
--- a/tools/perf/arch/x86/Build
+++ b/tools/perf/arch/x86/Build
@@ -2,7 +2,6 @@ perf-util-y += util/
 perf-test-y += tests/
 
 ifdef SHELLCHECK
-  SHELL_TESTS := entry/syscalls/syscalltbl.sh
   TEST_LOGS := $(SHELL_TESTS:%=%.shellcheck_log)
 else
   SHELL_TESTS :=
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index a6b6e0a9308a8e401c65eb802e5815a41fbdefe9..a295a80ea078199547e816d18531820bfdba7961 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -1,28 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
-
-###
-# Syscall table generation
-#
-
-generated := $(OUTPUT)arch/x86/include/generated
-out       := $(generated)/asm
-header    := $(out)/syscalls_64.c
-header_32 := $(out)/syscalls_32.c
-sys       := $(srctree)/tools/perf/arch/x86/entry/syscalls
-systbl    := $(sys)/syscalltbl.sh
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sys)/syscall_64.tbl $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
-
-$(header_32): $(sys)/syscall_32.tbl $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_32.tbl 'x86' > $@
-
-clean::
-	$(call QUIET_CLEAN, x86) $(RM) -r $(header) $(generated)
-
-archheaders: $(header) $(header_32)
diff --git a/tools/perf/arch/x86/entry/syscalls/Kbuild b/tools/perf/arch/x86/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls b/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..db3d5d6d4e5699d338afc55f6415612ef924d985
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += i386
+syscall_abis_64 +=
+
+syscalltbl = $(srctree)/tools/perf/arch/x86/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh b/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
deleted file mode 100755
index 2b71f99933a549607b0c18aa2b8be16b860f603c..0000000000000000000000000000000000000000
--- a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-in="$1"
-arch="$2"
-
-syscall_macro() {
-    nr="$1"
-    name="$2"
-
-    echo "	[$nr] = \"$name\","
-}
-
-emit() {
-    nr="$1"
-    entry="$2"
-
-    syscall_macro "$nr" "$entry"
-}
-
-echo "static const char *const syscalltbl_${arch}[] = {"
-
-sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
-grep '^[0-9]' "$in" | sort -n > $sorted_table
-
-max_nr=0
-# the params are: nr abi name entry compat
-# use _ for intentionally unused variables according to SC2034
-while read nr _ name _ _; do
-    if [ $nr -ge 512 ] ; then # discard compat sycalls
-        break
-    fi
-
-    emit "$nr" "$name"
-    max_nr=$nr
-done < $sorted_table
-
-rm -f $sorted_table
-
-echo "};"
-
-echo "#define SYSCALLTBL_${arch}_MAX_ID ${max_nr}"
diff --git a/tools/perf/arch/x86/include/syscall_table.h b/tools/perf/arch/x86/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/x86/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index ccf234a54366f9921c3b9a02ffb0a365d17244bc..02f23483bfff83809c4e649a2d054dba6975d12c 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -14,15 +14,7 @@
 #include <string.h>
 #include "string2.h"
 
-#if defined(__x86_64__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_x86_64;
-#elif defined(__i386__)
-#include <asm/syscalls_32.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_x86_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_x86;
-#elif defined(__s390x__)
+#if defined(__s390x__)
 #include <asm/syscalls_64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_s390_64;

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:32:59 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:59 -0800
Subject: [PATCH v2 09/16] perf tools: alpha: Support syscall header
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-9-f8ca984ffe40@rivosinc.com>

alpha uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
 .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 +++++++++++++++++++++
 tools/perf/arch/alpha/include/syscall_table.h      |   2 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 516 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index ada51e0dc17fbf5012e606ffc0b580c6993ebe64..802a8aa3a4fcd91ef7b7400373ce40736dfae0a1 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index efce35bb535b8ce4c20ee0a9250a548e4af1fbce..178a96bfc50e78f7c843f67d850b7cc323e163b6 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/alpha/entry/syscalls/Kbuild b/tools/perf/arch/alpha/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls b/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..690168aac34db9f1b96346210993675defcfc300
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64  +=
+
+syscalltbl = $(srctree)/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/alpha/entry/syscalls/syscall.tbl b/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..74720667fe091768800a22fd4ce68b5324abff09
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
@@ -0,0 +1,504 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for alpha
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	osf_syscall			alpha_syscall_zero
+1	common	exit				sys_exit
+2	common	fork				alpha_fork
+3	common	read				sys_read
+4	common	write				sys_write
+5	common	osf_old_open			sys_ni_syscall
+6	common	close				sys_close
+7	common	osf_wait4			sys_osf_wait4
+8	common	osf_old_creat			sys_ni_syscall
+9	common	link				sys_link
+10	common	unlink				sys_unlink
+11	common	osf_execve			sys_ni_syscall
+12	common	chdir				sys_chdir
+13	common	fchdir				sys_fchdir
+14	common	mknod				sys_mknod
+15	common	chmod				sys_chmod
+16	common	chown				sys_chown
+17	common	brk				sys_osf_brk
+18	common	osf_getfsstat			sys_ni_syscall
+19	common	lseek				sys_lseek
+20	common	getxpid				sys_getxpid
+21	common	osf_mount			sys_osf_mount
+22	common	umount2				sys_umount
+23	common	setuid				sys_setuid
+24	common	getxuid				sys_getxuid
+25	common	exec_with_loader		sys_ni_syscall
+26	common	ptrace				sys_ptrace
+27	common	osf_nrecvmsg			sys_ni_syscall
+28	common	osf_nsendmsg			sys_ni_syscall
+29	common	osf_nrecvfrom			sys_ni_syscall
+30	common	osf_naccept			sys_ni_syscall
+31	common	osf_ngetpeername		sys_ni_syscall
+32	common	osf_ngetsockname		sys_ni_syscall
+33	common	access				sys_access
+34	common	osf_chflags			sys_ni_syscall
+35	common	osf_fchflags			sys_ni_syscall
+36	common	sync				sys_sync
+37	common	kill				sys_kill
+38	common	osf_old_stat			sys_ni_syscall
+39	common	setpgid				sys_setpgid
+40	common	osf_old_lstat			sys_ni_syscall
+41	common	dup				sys_dup
+42	common	pipe				sys_alpha_pipe
+43	common	osf_set_program_attributes	sys_osf_set_program_attributes
+44	common	osf_profil			sys_ni_syscall
+45	common	open				sys_open
+46	common	osf_old_sigaction		sys_ni_syscall
+47	common	getxgid				sys_getxgid
+48	common	osf_sigprocmask			sys_osf_sigprocmask
+49	common	osf_getlogin			sys_ni_syscall
+50	common	osf_setlogin			sys_ni_syscall
+51	common	acct				sys_acct
+52	common	sigpending			sys_sigpending
+54	common	ioctl				sys_ioctl
+55	common	osf_reboot			sys_ni_syscall
+56	common	osf_revoke			sys_ni_syscall
+57	common	symlink				sys_symlink
+58	common	readlink			sys_readlink
+59	common	execve				sys_execve
+60	common	umask				sys_umask
+61	common	chroot				sys_chroot
+62	common	osf_old_fstat			sys_ni_syscall
+63	common	getpgrp				sys_getpgrp
+64	common	getpagesize			sys_getpagesize
+65	common	osf_mremap			sys_ni_syscall
+66	common	vfork				alpha_vfork
+67	common	stat				sys_newstat
+68	common	lstat				sys_newlstat
+69	common	osf_sbrk			sys_ni_syscall
+70	common	osf_sstk			sys_ni_syscall
+71	common	mmap				sys_osf_mmap
+72	common	osf_old_vadvise			sys_ni_syscall
+73	common	munmap				sys_munmap
+74	common	mprotect			sys_mprotect
+75	common	madvise				sys_madvise
+76	common	vhangup				sys_vhangup
+77	common	osf_kmodcall			sys_ni_syscall
+78	common	osf_mincore			sys_ni_syscall
+79	common	getgroups			sys_getgroups
+80	common	setgroups			sys_setgroups
+81	common	osf_old_getpgrp			sys_ni_syscall
+82	common	setpgrp				sys_setpgid
+83	common	osf_setitimer			compat_sys_setitimer
+84	common	osf_old_wait			sys_ni_syscall
+85	common	osf_table			sys_ni_syscall
+86	common	osf_getitimer			compat_sys_getitimer
+87	common	gethostname			sys_gethostname
+88	common	sethostname			sys_sethostname
+89	common	getdtablesize			sys_getdtablesize
+90	common	dup2				sys_dup2
+91	common	fstat				sys_newfstat
+92	common	fcntl				sys_fcntl
+93	common	osf_select			sys_osf_select
+94	common	poll				sys_poll
+95	common	fsync				sys_fsync
+96	common	setpriority			sys_setpriority
+97	common	socket				sys_socket
+98	common	connect				sys_connect
+99	common	accept				sys_accept
+100	common	getpriority			sys_osf_getpriority
+101	common	send				sys_send
+102	common	recv				sys_recv
+103	common	sigreturn			sys_sigreturn
+104	common	bind				sys_bind
+105	common	setsockopt			sys_setsockopt
+106	common	listen				sys_listen
+107	common	osf_plock			sys_ni_syscall
+108	common	osf_old_sigvec			sys_ni_syscall
+109	common	osf_old_sigblock		sys_ni_syscall
+110	common	osf_old_sigsetmask		sys_ni_syscall
+111	common	sigsuspend			sys_sigsuspend
+112	common	osf_sigstack			sys_osf_sigstack
+113	common	recvmsg				sys_recvmsg
+114	common	sendmsg				sys_sendmsg
+115	common	osf_old_vtrace			sys_ni_syscall
+116	common	osf_gettimeofday		sys_osf_gettimeofday
+117	common	osf_getrusage			sys_osf_getrusage
+118	common	getsockopt			sys_getsockopt
+120	common	readv				sys_readv
+121	common	writev				sys_writev
+122	common	osf_settimeofday		sys_osf_settimeofday
+123	common	fchown				sys_fchown
+124	common	fchmod				sys_fchmod
+125	common	recvfrom			sys_recvfrom
+126	common	setreuid			sys_setreuid
+127	common	setregid			sys_setregid
+128	common	rename				sys_rename
+129	common	truncate			sys_truncate
+130	common	ftruncate			sys_ftruncate
+131	common	flock				sys_flock
+132	common	setgid				sys_setgid
+133	common	sendto				sys_sendto
+134	common	shutdown			sys_shutdown
+135	common	socketpair			sys_socketpair
+136	common	mkdir				sys_mkdir
+137	common	rmdir				sys_rmdir
+138	common	osf_utimes			sys_osf_utimes
+139	common	osf_old_sigreturn		sys_ni_syscall
+140	common	osf_adjtime			sys_ni_syscall
+141	common	getpeername			sys_getpeername
+142	common	osf_gethostid			sys_ni_syscall
+143	common	osf_sethostid			sys_ni_syscall
+144	common	getrlimit			sys_getrlimit
+145	common	setrlimit			sys_setrlimit
+146	common	osf_old_killpg			sys_ni_syscall
+147	common	setsid				sys_setsid
+148	common	quotactl			sys_quotactl
+149	common	osf_oldquota			sys_ni_syscall
+150	common	getsockname			sys_getsockname
+153	common	osf_pid_block			sys_ni_syscall
+154	common	osf_pid_unblock			sys_ni_syscall
+156	common	sigaction			sys_osf_sigaction
+157	common	osf_sigwaitprim			sys_ni_syscall
+158	common	osf_nfssvc			sys_ni_syscall
+159	common	osf_getdirentries		sys_osf_getdirentries
+160	common	osf_statfs			sys_osf_statfs
+161	common	osf_fstatfs			sys_osf_fstatfs
+163	common	osf_asynch_daemon		sys_ni_syscall
+164	common	osf_getfh			sys_ni_syscall
+165	common	osf_getdomainname		sys_osf_getdomainname
+166	common	setdomainname			sys_setdomainname
+169	common	osf_exportfs			sys_ni_syscall
+181	common	osf_alt_plock			sys_ni_syscall
+184	common	osf_getmnt			sys_ni_syscall
+187	common	osf_alt_sigpending		sys_ni_syscall
+188	common	osf_alt_setsid			sys_ni_syscall
+199	common	osf_swapon			sys_swapon
+200	common	msgctl				sys_old_msgctl
+201	common	msgget				sys_msgget
+202	common	msgrcv				sys_msgrcv
+203	common	msgsnd				sys_msgsnd
+204	common	semctl				sys_old_semctl
+205	common	semget				sys_semget
+206	common	semop				sys_semop
+207	common	osf_utsname			sys_osf_utsname
+208	common	lchown				sys_lchown
+209	common	shmat				sys_shmat
+210	common	shmctl				sys_old_shmctl
+211	common	shmdt				sys_shmdt
+212	common	shmget				sys_shmget
+213	common	osf_mvalid			sys_ni_syscall
+214	common	osf_getaddressconf		sys_ni_syscall
+215	common	osf_msleep			sys_ni_syscall
+216	common	osf_mwakeup			sys_ni_syscall
+217	common	msync				sys_msync
+218	common	osf_signal			sys_ni_syscall
+219	common	osf_utc_gettime			sys_ni_syscall
+220	common	osf_utc_adjtime			sys_ni_syscall
+222	common	osf_security			sys_ni_syscall
+223	common	osf_kloadcall			sys_ni_syscall
+224	common	osf_stat			sys_osf_stat
+225	common	osf_lstat			sys_osf_lstat
+226	common	osf_fstat			sys_osf_fstat
+227	common	osf_statfs64			sys_osf_statfs64
+228	common	osf_fstatfs64			sys_osf_fstatfs64
+233	common	getpgid				sys_getpgid
+234	common	getsid				sys_getsid
+235	common	sigaltstack			sys_sigaltstack
+236	common	osf_waitid			sys_ni_syscall
+237	common	osf_priocntlset			sys_ni_syscall
+238	common	osf_sigsendset			sys_ni_syscall
+239	common	osf_set_speculative		sys_ni_syscall
+240	common	osf_msfs_syscall		sys_ni_syscall
+241	common	osf_sysinfo			sys_osf_sysinfo
+242	common	osf_uadmin			sys_ni_syscall
+243	common	osf_fuser			sys_ni_syscall
+244	common	osf_proplist_syscall		sys_osf_proplist_syscall
+245	common	osf_ntp_adjtime			sys_ni_syscall
+246	common	osf_ntp_gettime			sys_ni_syscall
+247	common	osf_pathconf			sys_ni_syscall
+248	common	osf_fpathconf			sys_ni_syscall
+250	common	osf_uswitch			sys_ni_syscall
+251	common	osf_usleep_thread		sys_osf_usleep_thread
+252	common	osf_audcntl			sys_ni_syscall
+253	common	osf_audgen			sys_ni_syscall
+254	common	sysfs				sys_sysfs
+255	common	osf_subsys_info			sys_ni_syscall
+256	common	osf_getsysinfo			sys_osf_getsysinfo
+257	common	osf_setsysinfo			sys_osf_setsysinfo
+258	common	osf_afs_syscall			sys_ni_syscall
+259	common	osf_swapctl			sys_ni_syscall
+260	common	osf_memcntl			sys_ni_syscall
+261	common	osf_fdatasync			sys_ni_syscall
+300	common	bdflush				sys_ni_syscall
+301	common	sethae				sys_sethae
+302	common	mount				sys_mount
+303	common	old_adjtimex			sys_old_adjtimex
+304	common	swapoff				sys_swapoff
+305	common	getdents			sys_getdents
+306	common	create_module			sys_ni_syscall
+307	common	init_module			sys_init_module
+308	common	delete_module			sys_delete_module
+309	common	get_kernel_syms			sys_ni_syscall
+310	common	syslog				sys_syslog
+311	common	reboot				sys_reboot
+312	common	clone				alpha_clone
+313	common	uselib				sys_uselib
+314	common	mlock				sys_mlock
+315	common	munlock				sys_munlock
+316	common	mlockall			sys_mlockall
+317	common	munlockall			sys_munlockall
+318	common	sysinfo				sys_sysinfo
+319	common	_sysctl				sys_ni_syscall
+# 320 was sys_idle
+321	common	oldumount			sys_oldumount
+322	common	swapon				sys_swapon
+323	common	times				sys_times
+324	common	personality			sys_personality
+325	common	setfsuid			sys_setfsuid
+326	common	setfsgid			sys_setfsgid
+327	common	ustat				sys_ustat
+328	common	statfs				sys_statfs
+329	common	fstatfs				sys_fstatfs
+330	common	sched_setparam			sys_sched_setparam
+331	common	sched_getparam			sys_sched_getparam
+332	common	sched_setscheduler		sys_sched_setscheduler
+333	common	sched_getscheduler		sys_sched_getscheduler
+334	common	sched_yield			sys_sched_yield
+335	common	sched_get_priority_max		sys_sched_get_priority_max
+336	common	sched_get_priority_min		sys_sched_get_priority_min
+337	common	sched_rr_get_interval		sys_sched_rr_get_interval
+338	common	afs_syscall			sys_ni_syscall
+339	common	uname				sys_newuname
+340	common	nanosleep			sys_nanosleep
+341	common	mremap				sys_mremap
+342	common	nfsservctl			sys_ni_syscall
+343	common	setresuid			sys_setresuid
+344	common	getresuid			sys_getresuid
+345	common	pciconfig_read			sys_pciconfig_read
+346	common	pciconfig_write			sys_pciconfig_write
+347	common	query_module			sys_ni_syscall
+348	common	prctl				sys_prctl
+349	common	pread64				sys_pread64
+350	common	pwrite64			sys_pwrite64
+351	common	rt_sigreturn			sys_rt_sigreturn
+352	common	rt_sigaction			sys_rt_sigaction
+353	common	rt_sigprocmask			sys_rt_sigprocmask
+354	common	rt_sigpending			sys_rt_sigpending
+355	common	rt_sigtimedwait			sys_rt_sigtimedwait
+356	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+357	common	rt_sigsuspend			sys_rt_sigsuspend
+358	common	select				sys_select
+359	common	gettimeofday			sys_gettimeofday
+360	common	settimeofday			sys_settimeofday
+361	common	getitimer			sys_getitimer
+362	common	setitimer			sys_setitimer
+363	common	utimes				sys_utimes
+364	common	getrusage			sys_getrusage
+365	common	wait4				sys_wait4
+366	common	adjtimex			sys_adjtimex
+367	common	getcwd				sys_getcwd
+368	common	capget				sys_capget
+369	common	capset				sys_capset
+370	common	sendfile			sys_sendfile64
+371	common	setresgid			sys_setresgid
+372	common	getresgid			sys_getresgid
+373	common	dipc				sys_ni_syscall
+374	common	pivot_root			sys_pivot_root
+375	common	mincore				sys_mincore
+376	common	pciconfig_iobase		sys_pciconfig_iobase
+377	common	getdents64			sys_getdents64
+378	common	gettid				sys_gettid
+379	common	readahead			sys_readahead
+# 380 is unused
+381	common	tkill				sys_tkill
+382	common	setxattr			sys_setxattr
+383	common	lsetxattr			sys_lsetxattr
+384	common	fsetxattr			sys_fsetxattr
+385	common	getxattr			sys_getxattr
+386	common	lgetxattr			sys_lgetxattr
+387	common	fgetxattr			sys_fgetxattr
+388	common	listxattr			sys_listxattr
+389	common	llistxattr			sys_llistxattr
+390	common	flistxattr			sys_flistxattr
+391	common	removexattr			sys_removexattr
+392	common	lremovexattr			sys_lremovexattr
+393	common	fremovexattr			sys_fremovexattr
+394	common	futex				sys_futex
+395	common	sched_setaffinity		sys_sched_setaffinity
+396	common	sched_getaffinity		sys_sched_getaffinity
+397	common	tuxcall				sys_ni_syscall
+398	common	io_setup			sys_io_setup
+399	common	io_destroy			sys_io_destroy
+400	common	io_getevents			sys_io_getevents
+401	common	io_submit			sys_io_submit
+402	common	io_cancel			sys_io_cancel
+405	common	exit_group			sys_exit_group
+406	common	lookup_dcookie			sys_ni_syscall
+407	common	epoll_create			sys_epoll_create
+408	common	epoll_ctl			sys_epoll_ctl
+409	common	epoll_wait			sys_epoll_wait
+410	common	remap_file_pages		sys_remap_file_pages
+411	common	set_tid_address			sys_set_tid_address
+412	common	restart_syscall			sys_restart_syscall
+413	common	fadvise64			sys_fadvise64
+414	common	timer_create			sys_timer_create
+415	common	timer_settime			sys_timer_settime
+416	common	timer_gettime			sys_timer_gettime
+417	common	timer_getoverrun		sys_timer_getoverrun
+418	common	timer_delete			sys_timer_delete
+419	common	clock_settime			sys_clock_settime
+420	common	clock_gettime			sys_clock_gettime
+421	common	clock_getres			sys_clock_getres
+422	common	clock_nanosleep			sys_clock_nanosleep
+423	common	semtimedop			sys_semtimedop
+424	common	tgkill				sys_tgkill
+425	common	stat64				sys_stat64
+426	common	lstat64				sys_lstat64
+427	common	fstat64				sys_fstat64
+428	common	vserver				sys_ni_syscall
+429	common	mbind				sys_ni_syscall
+430	common	get_mempolicy			sys_ni_syscall
+431	common	set_mempolicy			sys_ni_syscall
+432	common	mq_open				sys_mq_open
+433	common	mq_unlink			sys_mq_unlink
+434	common	mq_timedsend			sys_mq_timedsend
+435	common	mq_timedreceive			sys_mq_timedreceive
+436	common	mq_notify			sys_mq_notify
+437	common	mq_getsetattr			sys_mq_getsetattr
+438	common	waitid				sys_waitid
+439	common	add_key				sys_add_key
+440	common	request_key			sys_request_key
+441	common	keyctl				sys_keyctl
+442	common	ioprio_set			sys_ioprio_set
+443	common	ioprio_get			sys_ioprio_get
+444	common	inotify_init			sys_inotify_init
+445	common	inotify_add_watch		sys_inotify_add_watch
+446	common	inotify_rm_watch		sys_inotify_rm_watch
+447	common	fdatasync			sys_fdatasync
+448	common	kexec_load			sys_kexec_load
+449	common	migrate_pages			sys_migrate_pages
+450	common	openat				sys_openat
+451	common	mkdirat				sys_mkdirat
+452	common	mknodat				sys_mknodat
+453	common	fchownat			sys_fchownat
+454	common	futimesat			sys_futimesat
+455	common	fstatat64			sys_fstatat64
+456	common	unlinkat			sys_unlinkat
+457	common	renameat			sys_renameat
+458	common	linkat				sys_linkat
+459	common	symlinkat			sys_symlinkat
+460	common	readlinkat			sys_readlinkat
+461	common	fchmodat			sys_fchmodat
+462	common	faccessat			sys_faccessat
+463	common	pselect6			sys_pselect6
+464	common	ppoll				sys_ppoll
+465	common	unshare				sys_unshare
+466	common	set_robust_list			sys_set_robust_list
+467	common	get_robust_list			sys_get_robust_list
+468	common	splice				sys_splice
+469	common	sync_file_range			sys_sync_file_range
+470	common	tee				sys_tee
+471	common	vmsplice			sys_vmsplice
+472	common	move_pages			sys_move_pages
+473	common	getcpu				sys_getcpu
+474	common	epoll_pwait			sys_epoll_pwait
+475	common	utimensat			sys_utimensat
+476	common	signalfd			sys_signalfd
+477	common	timerfd				sys_ni_syscall
+478	common	eventfd				sys_eventfd
+479	common	recvmmsg			sys_recvmmsg
+480	common	fallocate			sys_fallocate
+481	common	timerfd_create			sys_timerfd_create
+482	common	timerfd_settime			sys_timerfd_settime
+483	common	timerfd_gettime			sys_timerfd_gettime
+484	common	signalfd4			sys_signalfd4
+485	common	eventfd2			sys_eventfd2
+486	common	epoll_create1			sys_epoll_create1
+487	common	dup3				sys_dup3
+488	common	pipe2				sys_pipe2
+489	common	inotify_init1			sys_inotify_init1
+490	common	preadv				sys_preadv
+491	common	pwritev				sys_pwritev
+492	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+493	common	perf_event_open			sys_perf_event_open
+494	common	fanotify_init			sys_fanotify_init
+495	common	fanotify_mark			sys_fanotify_mark
+496	common	prlimit64			sys_prlimit64
+497	common	name_to_handle_at		sys_name_to_handle_at
+498	common	open_by_handle_at		sys_open_by_handle_at
+499	common	clock_adjtime			sys_clock_adjtime
+500	common	syncfs				sys_syncfs
+501	common	setns				sys_setns
+502	common	accept4				sys_accept4
+503	common	sendmmsg			sys_sendmmsg
+504	common	process_vm_readv		sys_process_vm_readv
+505	common	process_vm_writev		sys_process_vm_writev
+506	common	kcmp				sys_kcmp
+507	common	finit_module			sys_finit_module
+508	common	sched_setattr			sys_sched_setattr
+509	common	sched_getattr			sys_sched_getattr
+510	common	renameat2			sys_renameat2
+511	common	getrandom			sys_getrandom
+512	common	memfd_create			sys_memfd_create
+513	common	execveat			sys_execveat
+514	common	seccomp				sys_seccomp
+515	common	bpf				sys_bpf
+516	common	userfaultfd			sys_userfaultfd
+517	common	membarrier			sys_membarrier
+518	common	mlock2				sys_mlock2
+519	common	copy_file_range			sys_copy_file_range
+520	common	preadv2				sys_preadv2
+521	common	pwritev2			sys_pwritev2
+522	common	statx				sys_statx
+523	common	io_pgetevents			sys_io_pgetevents
+524	common	pkey_mprotect			sys_pkey_mprotect
+525	common	pkey_alloc			sys_pkey_alloc
+526	common	pkey_free			sys_pkey_free
+527	common	rseq				sys_rseq
+528	common	statfs64			sys_statfs64
+529	common	fstatfs64			sys_fstatfs64
+530	common	getegid				sys_getegid
+531	common	geteuid				sys_geteuid
+532	common	getppid				sys_getppid
+# all other architectures have common numbers for new syscall, alpha
+# is the exception.
+534	common	pidfd_send_signal		sys_pidfd_send_signal
+535	common	io_uring_setup			sys_io_uring_setup
+536	common	io_uring_enter			sys_io_uring_enter
+537	common	io_uring_register		sys_io_uring_register
+538	common	open_tree			sys_open_tree
+539	common	move_mount			sys_move_mount
+540	common	fsopen				sys_fsopen
+541	common	fsconfig			sys_fsconfig
+542	common	fsmount				sys_fsmount
+543	common	fspick				sys_fspick
+544	common	pidfd_open			sys_pidfd_open
+545	common	clone3				alpha_clone3
+546	common	close_range			sys_close_range
+547	common	openat2				sys_openat2
+548	common	pidfd_getfd			sys_pidfd_getfd
+549	common	faccessat2			sys_faccessat2
+550	common	process_madvise			sys_process_madvise
+551	common	epoll_pwait2			sys_epoll_pwait2
+552	common	mount_setattr			sys_mount_setattr
+553	common	quotactl_fd			sys_quotactl_fd
+554	common	landlock_create_ruleset		sys_landlock_create_ruleset
+555	common	landlock_add_rule		sys_landlock_add_rule
+556	common	landlock_restrict_self		sys_landlock_restrict_self
+# 557 reserved for memfd_secret
+558	common	process_mrelease		sys_process_mrelease
+559	common  futex_waitv                     sys_futex_waitv
+560	common	set_mempolicy_home_node		sys_ni_syscall
+561	common	cachestat			sys_cachestat
+562	common	fchmodat2			sys_fchmodat2
+563	common	map_shadow_stack		sys_map_shadow_stack
+564	common	futex_wake			sys_futex_wake
+565	common	futex_wait			sys_futex_wait
+566	common	futex_requeue			sys_futex_requeue
+567	common	statmount			sys_statmount
+568	common	listmount			sys_listmount
+569	common	lsm_get_self_attr		sys_lsm_get_self_attr
+570	common	lsm_set_self_attr		sys_lsm_set_self_attr
+571	common	lsm_list_modules		sys_lsm_list_modules
+572	common  mseal				sys_mseal
diff --git a/tools/perf/arch/alpha/include/syscall_table.h b/tools/perf/arch/alpha/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..b53e31c15805319a01719c22d489c4037378b02b
--- /dev/null
+++ b/tools/perf/arch/alpha/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index e9e352579e6d33085a1d863441432c81d2353f49..a821df1fd4c0e78c9706304e5b8974cbc5ef4437 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -206,6 +206,7 @@ check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tb
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:33:00 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:33:00 -0800
Subject: [PATCH v2 10/16] perf tools: parisc: Support syscall header
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-10-f8ca984ffe40@rivosinc.com>

parisc uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
 .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
 tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++++
 tools/perf/arch/parisc/include/syscall_table.h     |   8 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 483 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 802a8aa3a4fcd91ef7b7400373ce40736dfae0a1..bf88840528a2e700983bd6ca4ca8b199ce93bc21 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 178a96bfc50e78f7c843f67d850b7cc323e163b6..b64d06a999f679b64a158d73a213954f30ae4702 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/parisc/entry/syscalls/Kbuild b/tools/perf/arch/parisc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..ae326fecb83b307fb5b0a885ae109480aafd586f
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscall_abis_64  +=
+
+syscalltbl = $(srctree)/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/parisc/entry/syscalls/syscall.tbl b/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..66dc406b12e4482832b0e8836b8267b0fb37a5ed
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
@@ -0,0 +1,463 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for parisc
+#
+# The format is:
+# <number> <abi> <name> <entry point> <compat entry point>
+#
+# The <abi> can be common, 64, or 32 for this file.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork_wrapper
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open			compat_sys_open
+6	common	close			sys_close
+7	common	waitpid			sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve			compat_sys_execve
+12	common	chdir			sys_chdir
+13	32	time			sys_time32
+13	64	time			sys_time
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown
+17	common	socket			sys_socket
+18	common	stat			sys_newstat			compat_sys_newstat
+19	common	lseek			sys_lseek			compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+22	common	bind			sys_bind
+23	common	setuid			sys_setuid
+24	common	getuid			sys_getuid
+25	32	stime			sys_stime32
+25	64	stime			sys_stime
+26	common	ptrace			sys_ptrace			compat_sys_ptrace
+27	common	alarm			sys_alarm
+28	common	fstat			sys_newfstat			compat_sys_newfstat
+29	common	pause			sys_pause
+30	32	utime			sys_utime32
+30	64	utime			sys_utime
+31	common	connect			sys_connect
+32	common	listen			sys_listen
+33	common	access			sys_access
+34	common	nice			sys_nice
+35	common	accept			sys_accept
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times			compat_sys_times
+44	common	getsockname		sys_getsockname
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid
+47	common	getgid			sys_getgid
+48	common	signal			sys_signal
+49	common	geteuid			sys_geteuid
+50	common	getegid			sys_getegid
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+53	common	getpeername		sys_getpeername
+54	common	ioctl			sys_ioctl			compat_sys_ioctl
+55	common	fcntl			sys_fcntl			compat_sys_fcntl
+56	common	socketpair		sys_socketpair
+57	common	setpgid			sys_setpgid
+58	common	send			sys_send
+59	common	uname			sys_newuname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat			compat_sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	pivot_root		sys_pivot_root
+68	common	sgetmask		sys_sgetmask			sys32_unimplemented
+69	common	ssetmask		sys_ssetmask			sys32_unimplemented
+70	common	setreuid		sys_setreuid
+71	common	setregid		sys_setregid
+72	common	mincore			sys_mincore
+73	common	sigpending		sys_sigpending			compat_sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit			compat_sys_setrlimit
+76	common	getrlimit		sys_getrlimit			compat_sys_getrlimit
+77	common	getrusage		sys_getrusage			compat_sys_getrusage
+78	common	gettimeofday		sys_gettimeofday		compat_sys_gettimeofday
+79	common	settimeofday		sys_settimeofday		compat_sys_settimeofday
+80	common	getgroups		sys_getgroups
+81	common	setgroups		sys_setgroups
+82	common	sendto			sys_sendto
+83	common	symlink			sys_symlink
+84	common	lstat			sys_newlstat			compat_sys_newlstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_ni_syscall
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+89	common	mmap2			sys_mmap2
+90	common	mmap			sys_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate			compat_sys_truncate
+93	common	ftruncate		sys_ftruncate			compat_sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+98	common	recv			sys_recv			compat_sys_recv
+99	common	statfs			sys_statfs			compat_sys_statfs
+100	common	fstatfs			sys_fstatfs			compat_sys_fstatfs
+101	common	stat64			sys_stat64
+# 102 was socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer			compat_sys_setitimer
+105	common	getitimer		sys_getitimer			compat_sys_getitimer
+106	common	capget			sys_capget
+107	common	capset			sys_capset
+108	32	pread64			parisc_pread64
+108	64	pread64			sys_pread64
+109	32	pwrite64		parisc_pwrite64
+109	64	pwrite64		sys_pwrite64
+110	common	getcwd			sys_getcwd
+111	common	vhangup			sys_vhangup
+112	common	fstat64			sys_fstat64
+113	common	vfork			sys_vfork_wrapper
+114	common	wait4			sys_wait4			compat_sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo			compat_sys_sysinfo
+117	common	shutdown		sys_shutdown
+118	common	fsync			sys_fsync
+119	common	madvise			parisc_madvise
+120	common	clone			sys_clone_wrapper
+121	common	setdomainname		sys_setdomainname
+122	common	sendfile		sys_sendfile			compat_sys_sendfile
+123	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
+124	32	adjtimex		sys_adjtimex_time32
+124	64	adjtimex		sys_adjtimex
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask			compat_sys_sigprocmask
+# 127 was create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	32	personality		parisc_personality
+136	64	personality		sys_personality
+# 137 was afs_syscall
+138	common	setfsuid		sys_setfsuid
+139	common	setfsgid		sys_setfsgid
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents			compat_sys_getdents
+142	common	_newselect		sys_select			compat_sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	32	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+161	64	sched_rr_get_interval	sys_sched_rr_get_interval
+162	32	nanosleep		sys_nanosleep_time32
+162	64	nanosleep		sys_nanosleep
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid
+165	common	getresuid		sys_getresuid
+166	common	sigaltstack		sys_sigaltstack			compat_sys_sigaltstack
+# 167 was query_module
+168	common	poll			sys_poll
+# 169 was nfsservctl
+170	common	setresgid		sys_setresgid
+171	common	getresgid		sys_getresgid
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper
+174	common	rt_sigaction		sys_rt_sigaction		compat_sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending		compat_sys_rt_sigpending
+177	32	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+177	64	rt_sigtimedwait		sys_rt_sigtimedwait
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+180	common	chown			sys_chown
+181	common	setsockopt		sys_setsockopt			sys_setsockopt
+182	common	getsockopt		sys_getsockopt			sys_getsockopt
+183	common	sendmsg			sys_sendmsg			compat_sys_sendmsg
+184	common	recvmsg			sys_recvmsg			compat_sys_recvmsg
+185	common	semop			sys_semop
+186	common	semget			sys_semget
+187	common	semctl			sys_semctl			compat_sys_semctl
+188	common	msgsnd			sys_msgsnd			compat_sys_msgsnd
+189	common	msgrcv			sys_msgrcv			compat_sys_msgrcv
+190	common	msgget			sys_msgget
+191	common	msgctl			sys_msgctl			compat_sys_msgctl
+192	common	shmat			sys_shmat			compat_sys_shmat
+193	common	shmdt			sys_shmdt
+194	common	shmget			sys_shmget
+195	common	shmctl			sys_shmctl			compat_sys_shmctl
+# 196 was getpmsg
+# 197 was putpmsg
+198	common	lstat64			sys_lstat64
+199	32	truncate64		parisc_truncate64
+199	64	truncate64		sys_truncate64
+200	32	ftruncate64		parisc_ftruncate64
+200	64	ftruncate64		sys_ftruncate64
+201	common	getdents64		sys_getdents64
+202	common	fcntl64			sys_fcntl64			compat_sys_fcntl64
+# 203 was attrctl
+# 204 was acl_get
+# 205 was acl_set
+206	common	gettid			sys_gettid
+207	32	readahead		parisc_readahead
+207	64	readahead		sys_readahead
+208	common	tkill			sys_tkill
+209	common	sendfile64		sys_sendfile64			compat_sys_sendfile64
+210	32	futex			sys_futex_time32
+210	64	futex			sys_futex
+211	common	sched_setaffinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+212	common	sched_getaffinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+# 213 was set_thread_area
+# 214 was get_thread_area
+215	common	io_setup		sys_io_setup			compat_sys_io_setup
+216	common	io_destroy		sys_io_destroy
+217	32	io_getevents		sys_io_getevents_time32
+217	64	io_getevents		sys_io_getevents
+218	common	io_submit		sys_io_submit			compat_sys_io_submit
+219	common	io_cancel		sys_io_cancel
+# 220 was alloc_hugepages
+# 221 was free_hugepages
+222	common	exit_group		sys_exit_group
+223	common	lookup_dcookie		sys_ni_syscall
+224	common	epoll_create		sys_epoll_create
+225	common	epoll_ctl		sys_epoll_ctl
+226	common	epoll_wait		sys_epoll_wait
+227	common	remap_file_pages	sys_remap_file_pages
+228	32	semtimedop		sys_semtimedop_time32
+228	64	semtimedop		sys_semtimedop
+229	common	mq_open			sys_mq_open			compat_sys_mq_open
+230	common	mq_unlink		sys_mq_unlink
+231	32	mq_timedsend		sys_mq_timedsend_time32
+231	64	mq_timedsend		sys_mq_timedsend
+232	32	mq_timedreceive		sys_mq_timedreceive_time32
+232	64	mq_timedreceive		sys_mq_timedreceive
+233	common	mq_notify		sys_mq_notify			compat_sys_mq_notify
+234	common	mq_getsetattr		sys_mq_getsetattr		compat_sys_mq_getsetattr
+235	common	waitid			sys_waitid			compat_sys_waitid
+236	32	fadvise64_64		parisc_fadvise64_64
+236	64	fadvise64_64		sys_fadvise64_64
+237	common	set_tid_address		sys_set_tid_address
+238	common	setxattr		sys_setxattr
+239	common	lsetxattr		sys_lsetxattr
+240	common	fsetxattr		sys_fsetxattr
+241	common	getxattr		sys_getxattr
+242	common	lgetxattr		sys_lgetxattr
+243	common	fgetxattr		sys_fgetxattr
+244	common	listxattr		sys_listxattr
+245	common	llistxattr		sys_llistxattr
+246	common	flistxattr		sys_flistxattr
+247	common	removexattr		sys_removexattr
+248	common	lremovexattr		sys_lremovexattr
+249	common	fremovexattr		sys_fremovexattr
+250	common	timer_create		sys_timer_create		compat_sys_timer_create
+251	32	timer_settime		sys_timer_settime32
+251	64	timer_settime		sys_timer_settime
+252	32	timer_gettime		sys_timer_gettime32
+252	64	timer_gettime		sys_timer_gettime
+253	common	timer_getoverrun	sys_timer_getoverrun
+254	common	timer_delete		sys_timer_delete
+255	32	clock_settime		sys_clock_settime32
+255	64	clock_settime		sys_clock_settime
+256	32	clock_gettime		sys_clock_gettime32
+256	64	clock_gettime		sys_clock_gettime
+257	32	clock_getres		sys_clock_getres_time32
+257	64	clock_getres		sys_clock_getres
+258	32	clock_nanosleep		sys_clock_nanosleep_time32
+258	64	clock_nanosleep		sys_clock_nanosleep
+259	common	tgkill			sys_tgkill
+260	common	mbind			sys_mbind
+261	common	get_mempolicy		sys_get_mempolicy
+262	common	set_mempolicy		sys_set_mempolicy
+# 263 was vserver
+264	common	add_key			sys_add_key
+265	common	request_key		sys_request_key
+266	common	keyctl			sys_keyctl			compat_sys_keyctl
+267	common	ioprio_set		sys_ioprio_set
+268	common	ioprio_get		sys_ioprio_get
+269	common	inotify_init		sys_inotify_init
+270	common	inotify_add_watch	sys_inotify_add_watch
+271	common	inotify_rm_watch	sys_inotify_rm_watch
+272	common	migrate_pages		sys_migrate_pages
+273	32	pselect6		sys_pselect6_time32		compat_sys_pselect6_time32
+273	64	pselect6		sys_pselect6
+274	32	ppoll			sys_ppoll_time32		compat_sys_ppoll_time32
+274	64	ppoll			sys_ppoll
+275	common	openat			sys_openat			compat_sys_openat
+276	common	mkdirat			sys_mkdirat
+277	common	mknodat			sys_mknodat
+278	common	fchownat		sys_fchownat
+279	32	futimesat		sys_futimesat_time32
+279	64	futimesat		sys_futimesat
+280	common	fstatat64		sys_fstatat64
+281	common	unlinkat		sys_unlinkat
+282	common	renameat		sys_renameat
+283	common	linkat			sys_linkat
+284	common	symlinkat		sys_symlinkat
+285	common	readlinkat		sys_readlinkat
+286	common	fchmodat		sys_fchmodat
+287	common	faccessat		sys_faccessat
+288	common	unshare			sys_unshare
+289	common	set_robust_list		sys_set_robust_list		compat_sys_set_robust_list
+290	common	get_robust_list		sys_get_robust_list		compat_sys_get_robust_list
+291	common	splice			sys_splice
+292	32	sync_file_range		parisc_sync_file_range
+292	64	sync_file_range		sys_sync_file_range
+293	common	tee			sys_tee
+294	common	vmsplice		sys_vmsplice
+295	common	move_pages		sys_move_pages
+296	common	getcpu			sys_getcpu
+297	common	epoll_pwait		sys_epoll_pwait			compat_sys_epoll_pwait
+298	common	statfs64		sys_statfs64			compat_sys_statfs64
+299	common	fstatfs64		sys_fstatfs64			compat_sys_fstatfs64
+300	common	kexec_load		sys_kexec_load			compat_sys_kexec_load
+301	32	utimensat		sys_utimensat_time32
+301	64	utimensat		sys_utimensat
+302	common	signalfd		sys_signalfd			compat_sys_signalfd
+# 303 was timerfd
+304	common	eventfd			sys_eventfd
+305	32	fallocate		parisc_fallocate
+305	64	fallocate		sys_fallocate
+306	common	timerfd_create		parisc_timerfd_create
+307	32	timerfd_settime		sys_timerfd_settime32
+307	64	timerfd_settime		sys_timerfd_settime
+308	32	timerfd_gettime		sys_timerfd_gettime32
+308	64	timerfd_gettime		sys_timerfd_gettime
+309	common	signalfd4		parisc_signalfd4		parisc_compat_signalfd4
+310	common	eventfd2		parisc_eventfd2
+311	common	epoll_create1		sys_epoll_create1
+312	common	dup3			sys_dup3
+313	common	pipe2			parisc_pipe2
+314	common	inotify_init1		parisc_inotify_init1
+315	common	preadv	sys_preadv	compat_sys_preadv
+316	common	pwritev	sys_pwritev	compat_sys_pwritev
+317	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+318	common	perf_event_open		sys_perf_event_open
+319	32	recvmmsg		sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+319	64	recvmmsg		sys_recvmmsg
+320	common	accept4			sys_accept4
+321	common	prlimit64		sys_prlimit64
+322	common	fanotify_init		sys_fanotify_init
+323	common	fanotify_mark		sys_fanotify_mark		compat_sys_fanotify_mark
+324	32	clock_adjtime		sys_clock_adjtime32
+324	64	clock_adjtime		sys_clock_adjtime
+325	common	name_to_handle_at	sys_name_to_handle_at
+326	common	open_by_handle_at	sys_open_by_handle_at		compat_sys_open_by_handle_at
+327	common	syncfs			sys_syncfs
+328	common	setns			sys_setns
+329	common	sendmmsg		sys_sendmmsg			compat_sys_sendmmsg
+330	common	process_vm_readv	sys_process_vm_readv
+331	common	process_vm_writev	sys_process_vm_writev
+332	common	kcmp			sys_kcmp
+333	common	finit_module		sys_finit_module
+334	common	sched_setattr		sys_sched_setattr
+335	common	sched_getattr		sys_sched_getattr
+336	32	utimes			sys_utimes_time32
+336	64	utimes			sys_utimes
+337	common	renameat2		sys_renameat2
+338	common	seccomp			sys_seccomp
+339	common	getrandom		sys_getrandom
+340	common	memfd_create		sys_memfd_create
+341	common	bpf			sys_bpf
+342	common	execveat		sys_execveat			compat_sys_execveat
+343	common	membarrier		sys_membarrier
+344	common	userfaultfd		parisc_userfaultfd
+345	common	mlock2			sys_mlock2
+346	common	copy_file_range		sys_copy_file_range
+347	common	preadv2			sys_preadv2			compat_sys_preadv2
+348	common	pwritev2		sys_pwritev2			compat_sys_pwritev2
+349	common	statx			sys_statx
+350	32	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+350	64	io_pgetevents		sys_io_pgetevents
+351	common	pkey_mprotect		sys_pkey_mprotect
+352	common	pkey_alloc		sys_pkey_alloc
+353	common	pkey_free		sys_pkey_free
+354	common	rseq			sys_rseq
+355	common	kexec_file_load		sys_kexec_file_load		sys_kexec_file_load
+356	common	cacheflush		sys_cacheflush
+# up to 402 is unassigned and reserved for arch specific syscalls
+403	32	clock_gettime64			sys_clock_gettime		sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime		sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime		sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime		sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime		sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat			sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop			sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3_wrapper
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/parisc/include/syscall_table.h b/tools/perf/arch/parisc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/parisc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index a821df1fd4c0e78c9706304e5b8974cbc5ef4437..ae9f00ae79f34fec75ef2c91300ccd771c030529 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -207,6 +207,7 @@ check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/sy
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
+check_2 tools/perf/arch/parisc/entry/syscalls/syscall.tbl arch/parisc/entry/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:33:01 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:33:01 -0800
Subject: [PATCH v2 11/16] perf tools: arm64: Use syscall table
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-11-f8ca984ffe40@rivosinc.com>

arm64 uses a syscall table, use that in perf instead of using unistd.h.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   5 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/arm64/Makefile                     |  22 -
 tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
 .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
 .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++++
 .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
 tools/perf/arch/arm64/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   2 +
 tools/perf/util/syscalltbl.c                       |   4 -
 11 files changed, 499 insertions(+), 76 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index bf88840528a2e700983bd6ca4ca8b199ce93bc21..aefcbed7cdfac7c2a5d8db5cb111513f2d7c74ed 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips loongarch))
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
@@ -71,7 +71,6 @@ ifeq ($(SRCARCH),arm)
 endif
 
 ifeq ($(SRCARCH),arm64)
-  CFLAGS += -I$(OUTPUT)arch/arm64/include/generated
   LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
 endif
 
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index b64d06a999f679b64a158d73a213954f30ae4702..6a287f15fa1da5e8957558ee0a73b297d347f00d 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
index 91570d5d428e401d940e1c31332ebb40c4b998d8..087e099fb453a9236db34878077a51f711881ce0 100644
--- a/tools/perf/arch/arm64/Makefile
+++ b/tools/perf/arch/arm64/Makefile
@@ -1,25 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/arm64/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/arm64/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, arm64) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/arm64/entry/syscalls/Kbuild b/tools/perf/arch/arm64/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..e7e78c2d1c025b6954a1a22d44a744012e1ca3d4
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 +=
+syscall_abis_64 += renameat rlimit memfd_secret
+
+syscalltbl = $(srctree)/tools/perf/arch/arm64/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 27d747c92d44c04f26ce7aef766a50e3f896f5ff..0000000000000000000000000000000000000000
--- a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-# Changed by: Kim Phillips <kim.phillips at arm.com>
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_ARM64_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_arm64[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl b/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..9a37930d4e26f0c6cb8fe78f76bb1a4f32cbea16
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl
@@ -0,0 +1,476 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# AArch32 (compat) system call definitions.
+#
+# Copyright (C) 2001-2005 Russell King
+# Copyright (C) 2012 ARM Ltd.
+#
+# This file corresponds to arch/arm/tools/syscall.tbl
+# for the native EABI syscalls and should be kept in sync
+# Instead of the OABI syscalls, it contains pointers to
+# the compat entry points where they differ from the native
+# syscalls.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open		compat_sys_open
+6	common	close			sys_close
+# 7 was sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve		compat_sys_execve
+12	common	chdir			sys_chdir
+# 13 was sys_time
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19	common	lseek			sys_lseek		compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+# 22 was sys_umount
+23	common	setuid			sys_setuid16
+24	common	getuid			sys_getuid16
+# 25 was sys_stime
+26	common	ptrace			sys_ptrace		compat_sys_ptrace
+# 27 was sys_alarm
+# 28 was sys_fstat
+29	common	pause			sys_pause
+# 30 was sys_utime
+# 31 was sys_stty
+# 32 was sys_gtty
+33	common	access			sys_access
+34	common	nice			sys_nice
+# 35 was sys_ftime
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times		compat_sys_times
+# 44 was sys_prof
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid16
+47	common	getgid			sys_getgid16
+# 48 was sys_signal
+49	common	geteuid			sys_geteuid16
+50	common	getegid			sys_getegid16
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+# 53 was sys_lock
+54	common	ioctl			sys_ioctl		compat_sys_ioctl
+55	common	fcntl			sys_fcntl		compat_sys_fcntl
+# 56 was sys_mpx
+57	common	setpgid			sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat		compat_sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	sigaction		sys_sigaction		compat_sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70	common	setreuid		sys_setreuid16
+71	common	setregid		sys_setregid16
+72	common	sigsuspend		sys_sigsuspend
+73	common	sigpending		sys_sigpending		compat_sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit		compat_sys_setrlimit
+# 76 was compat_sys_getrlimit
+77	common	getrusage		sys_getrusage		compat_sys_getrusage
+78	common	gettimeofday		sys_gettimeofday	compat_sys_gettimeofday
+79	common	settimeofday		sys_settimeofday	compat_sys_settimeofday
+80	common	getgroups		sys_getgroups16
+81	common	setgroups		sys_setgroups16
+# 82 was compat_sys_select
+83	common	symlink			sys_symlink
+# 84 was sys_lstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_uselib
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+# 89 was sys_readdir
+# 90 was sys_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate		compat_sys_truncate
+93	common	ftruncate		sys_ftruncate		compat_sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown16
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+# 98 was sys_profil
+99	common	statfs			sys_statfs		compat_sys_statfs
+100	common	fstatfs			sys_fstatfs		compat_sys_fstatfs
+# 101 was sys_ioperm
+# 102 was sys_socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer		compat_sys_setitimer
+105	common	getitimer		sys_getitimer		compat_sys_getitimer
+106	common	stat			sys_newstat		compat_sys_newstat
+107	common	lstat			sys_newlstat		compat_sys_newlstat
+108	common	fstat			sys_newfstat		compat_sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111	common	vhangup			sys_vhangup
+# 112 was sys_idle
+# 113 was sys_syscall
+114	common	wait4			sys_wait4		compat_sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo		compat_sys_sysinfo
+# 117 was sys_ipc
+118	common	fsync			sys_fsync
+119	common	sigreturn		sys_sigreturn_wrapper	compat_sys_sigreturn
+120	common	clone			sys_clone
+121	common	setdomainname		sys_setdomainname
+122	common	uname			sys_newuname
+# 123 was sys_modify_ldt
+124	common	adjtimex		sys_adjtimex_time32
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask		compat_sys_sigprocmask
+# 127 was sys_create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was sys_get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	common	personality		sys_personality
+# 137 was sys_afs_syscall
+138	common	setfsuid		sys_setfsuid16
+139	common	setfsgid		sys_setfsgid16
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents		compat_sys_getdents
+142	common	_newselect		sys_select		compat_sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	common	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+162	common	nanosleep		sys_nanosleep_time32
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid16
+165	common	getresuid		sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168	common	poll			sys_poll
+169	common	nfsservctl		sys_ni_syscall
+170	common	setresgid		sys_setresgid16
+171	common	getresgid		sys_getresgid16
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper	compat_sys_rt_sigreturn
+174	common	rt_sigaction		sys_rt_sigaction	compat_sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask	compat_sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending	compat_sys_rt_sigpending
+177	common	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo	compat_sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend	compat_sys_rt_sigsuspend
+180	common	pread64			sys_pread64		compat_sys_aarch32_pread64
+181	common	pwrite64		sys_pwrite64		compat_sys_aarch32_pwrite64
+182	common	chown			sys_chown16
+183	common	getcwd			sys_getcwd
+184	common	capget			sys_capget
+185	common	capset			sys_capset
+186	common	sigaltstack		sys_sigaltstack		compat_sys_sigaltstack
+187	common	sendfile		sys_sendfile		compat_sys_sendfile
+# 188 reserved
+# 189 reserved
+190	common	vfork			sys_vfork
+# SuS compliant getrlimit
+191	common	ugetrlimit		sys_getrlimit		compat_sys_getrlimit
+192	common	mmap2			sys_mmap2		compat_sys_aarch32_mmap2
+193	common	truncate64		sys_truncate64		compat_sys_aarch32_truncate64
+194	common	ftruncate64		sys_ftruncate64		compat_sys_aarch32_ftruncate64
+195	common	stat64			sys_stat64
+196	common	lstat64			sys_lstat64
+197	common	fstat64			sys_fstat64
+198	common	lchown32		sys_lchown
+199	common	getuid32		sys_getuid
+200	common	getgid32		sys_getgid
+201	common	geteuid32		sys_geteuid
+202	common	getegid32		sys_getegid
+203	common	setreuid32		sys_setreuid
+204	common	setregid32		sys_setregid
+205	common	getgroups32		sys_getgroups
+206	common	setgroups32		sys_setgroups
+207	common	fchown32		sys_fchown
+208	common	setresuid32		sys_setresuid
+209	common	getresuid32		sys_getresuid
+210	common	setresgid32		sys_setresgid
+211	common	getresgid32		sys_getresgid
+212	common	chown32			sys_chown
+213	common	setuid32		sys_setuid
+214	common	setgid32		sys_setgid
+215	common	setfsuid32		sys_setfsuid
+216	common	setfsgid32		sys_setfsgid
+217	common	getdents64		sys_getdents64
+218	common	pivot_root		sys_pivot_root
+219	common	mincore			sys_mincore
+220	common	madvise			sys_madvise
+221	common	fcntl64			sys_fcntl64		compat_sys_fcntl64
+# 222 for tux
+# 223 is unused
+224	common	gettid			sys_gettid
+225	common	readahead		sys_readahead		compat_sys_aarch32_readahead
+226	common	setxattr		sys_setxattr
+227	common	lsetxattr		sys_lsetxattr
+228	common	fsetxattr		sys_fsetxattr
+229	common	getxattr		sys_getxattr
+230	common	lgetxattr		sys_lgetxattr
+231	common	fgetxattr		sys_fgetxattr
+232	common	listxattr		sys_listxattr
+233	common	llistxattr		sys_llistxattr
+234	common	flistxattr		sys_flistxattr
+235	common	removexattr		sys_removexattr
+236	common	lremovexattr		sys_lremovexattr
+237	common	fremovexattr		sys_fremovexattr
+238	common	tkill			sys_tkill
+239	common	sendfile64		sys_sendfile64
+240	common	futex			sys_futex_time32
+241	common	sched_setaffinity	sys_sched_setaffinity	compat_sys_sched_setaffinity
+242	common	sched_getaffinity	sys_sched_getaffinity	compat_sys_sched_getaffinity
+243	common	io_setup		sys_io_setup		compat_sys_io_setup
+244	common	io_destroy		sys_io_destroy
+245	common	io_getevents		sys_io_getevents_time32
+246	common	io_submit		sys_io_submit		compat_sys_io_submit
+247	common	io_cancel		sys_io_cancel
+248	common	exit_group		sys_exit_group
+249	common	lookup_dcookie		sys_ni_syscall
+250	common	epoll_create		sys_epoll_create
+251	common	epoll_ctl		sys_epoll_ctl
+252	common	epoll_wait		sys_epoll_wait
+253	common	remap_file_pages	sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256	common	set_tid_address		sys_set_tid_address
+257	common	timer_create		sys_timer_create	compat_sys_timer_create
+258	common	timer_settime		sys_timer_settime32
+259	common	timer_gettime		sys_timer_gettime32
+260	common	timer_getoverrun	sys_timer_getoverrun
+261	common	timer_delete		sys_timer_delete
+262	common	clock_settime		sys_clock_settime32
+263	common	clock_gettime		sys_clock_gettime32
+264	common	clock_getres		sys_clock_getres_time32
+265	common	clock_nanosleep		sys_clock_nanosleep_time32
+266	common	statfs64		sys_statfs64_wrapper	compat_sys_aarch32_statfs64
+267	common	fstatfs64		sys_fstatfs64_wrapper	compat_sys_aarch32_fstatfs64
+268	common	tgkill			sys_tgkill
+269	common	utimes			sys_utimes_time32
+270	common	arm_fadvise64_64	sys_arm_fadvise64_64	compat_sys_aarch32_fadvise64_64
+271	common	pciconfig_iobase	sys_pciconfig_iobase
+272	common	pciconfig_read		sys_pciconfig_read
+273	common	pciconfig_write		sys_pciconfig_write
+274	common	mq_open			sys_mq_open		compat_sys_mq_open
+275	common	mq_unlink		sys_mq_unlink
+276	common	mq_timedsend		sys_mq_timedsend_time32
+277	common	mq_timedreceive		sys_mq_timedreceive_time32
+278	common	mq_notify		sys_mq_notify		compat_sys_mq_notify
+279	common	mq_getsetattr		sys_mq_getsetattr	compat_sys_mq_getsetattr
+280	common	waitid			sys_waitid		compat_sys_waitid
+281	common	socket			sys_socket
+282	common	bind			sys_bind
+283	common	connect			sys_connect
+284	common	listen			sys_listen
+285	common	accept			sys_accept
+286	common	getsockname		sys_getsockname
+287	common	getpeername		sys_getpeername
+288	common	socketpair		sys_socketpair
+289	common	send			sys_send
+290	common	sendto			sys_sendto
+291	common	recv			sys_recv		compat_sys_recv
+292	common	recvfrom		sys_recvfrom		compat_sys_recvfrom
+293	common	shutdown		sys_shutdown
+294	common	setsockopt		sys_setsockopt
+295	common	getsockopt		sys_getsockopt
+296	common	sendmsg			sys_sendmsg		compat_sys_sendmsg
+297	common	recvmsg			sys_recvmsg		compat_sys_recvmsg
+298	common	semop			sys_semop
+299	common	semget			sys_semget
+300	common	semctl			sys_old_semctl		compat_sys_old_semctl
+301	common	msgsnd			sys_msgsnd		compat_sys_msgsnd
+302	common	msgrcv			sys_msgrcv		compat_sys_msgrcv
+303	common	msgget			sys_msgget
+304	common	msgctl			sys_old_msgctl		compat_sys_old_msgctl
+305	common	shmat			sys_shmat		compat_sys_shmat
+306	common	shmdt			sys_shmdt
+307	common	shmget			sys_shmget
+308	common	shmctl			sys_old_shmctl		compat_sys_old_shmctl
+309	common	add_key			sys_add_key
+310	common	request_key		sys_request_key
+311	common	keyctl			sys_keyctl		compat_sys_keyctl
+312	common	semtimedop		sys_semtimedop_time32
+313	common	vserver			sys_ni_syscall
+314	common	ioprio_set		sys_ioprio_set
+315	common	ioprio_get		sys_ioprio_get
+316	common	inotify_init		sys_inotify_init
+317	common	inotify_add_watch	sys_inotify_add_watch
+318	common	inotify_rm_watch	sys_inotify_rm_watch
+319	common	mbind			sys_mbind
+320	common	get_mempolicy		sys_get_mempolicy
+321	common	set_mempolicy		sys_set_mempolicy
+322	common	openat			sys_openat		compat_sys_openat
+323	common	mkdirat			sys_mkdirat
+324	common	mknodat			sys_mknodat
+325	common	fchownat		sys_fchownat
+326	common	futimesat		sys_futimesat_time32
+327	common	fstatat64		sys_fstatat64
+328	common	unlinkat		sys_unlinkat
+329	common	renameat		sys_renameat
+330	common	linkat			sys_linkat
+331	common	symlinkat		sys_symlinkat
+332	common	readlinkat		sys_readlinkat
+333	common	fchmodat		sys_fchmodat
+334	common	faccessat		sys_faccessat
+335	common	pselect6		sys_pselect6_time32	compat_sys_pselect6_time32
+336	common	ppoll			sys_ppoll_time32	compat_sys_ppoll_time32
+337	common	unshare			sys_unshare
+338	common	set_robust_list		sys_set_robust_list	compat_sys_set_robust_list
+339	common	get_robust_list		sys_get_robust_list	compat_sys_get_robust_list
+340	common	splice			sys_splice
+341	common	arm_sync_file_range	sys_sync_file_range2	compat_sys_aarch32_sync_file_range2
+342	common	tee			sys_tee
+343	common	vmsplice		sys_vmsplice
+344	common	move_pages		sys_move_pages
+345	common	getcpu			sys_getcpu
+346	common	epoll_pwait		sys_epoll_pwait		compat_sys_epoll_pwait
+347	common	kexec_load		sys_kexec_load		compat_sys_kexec_load
+348	common	utimensat		sys_utimensat_time32
+349	common	signalfd		sys_signalfd		compat_sys_signalfd
+350	common	timerfd_create		sys_timerfd_create
+351	common	eventfd			sys_eventfd
+352	common	fallocate		sys_fallocate		compat_sys_aarch32_fallocate
+353	common	timerfd_settime		sys_timerfd_settime32
+354	common	timerfd_gettime		sys_timerfd_gettime32
+355	common	signalfd4		sys_signalfd4		compat_sys_signalfd4
+356	common	eventfd2		sys_eventfd2
+357	common	epoll_create1		sys_epoll_create1
+358	common	dup3			sys_dup3
+359	common	pipe2			sys_pipe2
+360	common	inotify_init1		sys_inotify_init1
+361	common	preadv			sys_preadv		compat_sys_preadv
+362	common	pwritev			sys_pwritev		compat_sys_pwritev
+363	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo	compat_sys_rt_tgsigqueueinfo
+364	common	perf_event_open		sys_perf_event_open
+365	common	recvmmsg		sys_recvmmsg_time32	compat_sys_recvmmsg_time32
+366	common	accept4			sys_accept4
+367	common	fanotify_init		sys_fanotify_init
+368	common	fanotify_mark		sys_fanotify_mark	compat_sys_fanotify_mark
+369	common	prlimit64		sys_prlimit64
+370	common	name_to_handle_at	sys_name_to_handle_at
+371	common	open_by_handle_at	sys_open_by_handle_at	compat_sys_open_by_handle_at
+372	common	clock_adjtime		sys_clock_adjtime32
+373	common	syncfs			sys_syncfs
+374	common	sendmmsg		sys_sendmmsg		compat_sys_sendmmsg
+375	common	setns			sys_setns
+376	common	process_vm_readv	sys_process_vm_readv
+377	common	process_vm_writev	sys_process_vm_writev
+378	common	kcmp			sys_kcmp
+379	common	finit_module		sys_finit_module
+380	common	sched_setattr		sys_sched_setattr
+381	common	sched_getattr		sys_sched_getattr
+382	common	renameat2		sys_renameat2
+383	common	seccomp			sys_seccomp
+384	common	getrandom		sys_getrandom
+385	common	memfd_create		sys_memfd_create
+386	common	bpf			sys_bpf
+387	common	execveat		sys_execveat		compat_sys_execveat
+388	common	userfaultfd		sys_userfaultfd
+389	common	membarrier		sys_membarrier
+390	common	mlock2			sys_mlock2
+391	common	copy_file_range		sys_copy_file_range
+392	common	preadv2			sys_preadv2		compat_sys_preadv2
+393	common	pwritev2		sys_pwritev2		compat_sys_pwritev2
+394	common	pkey_mprotect		sys_pkey_mprotect
+395	common	pkey_alloc		sys_pkey_alloc
+396	common	pkey_free		sys_pkey_free
+397	common	statx			sys_statx
+398	common	rseq			sys_rseq
+399	common	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+400	common	migrate_pages		sys_migrate_pages
+401	common	kexec_file_load		sys_kexec_file_load
+# 402 is unused
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	common	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	common	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	common	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl b/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl
new file mode 120000
index 0000000000000000000000000000000000000000..4fdd58f10c155ee45b8d4f6ab1ca4e36ea677c75
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl
@@ -0,0 +1 @@
+../../../../../scripts/syscall.tbl
\ No newline at end of file
diff --git a/tools/perf/arch/arm64/include/syscall_table.h b/tools/perf/arch/arm64/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/arm64/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index ae9f00ae79f34fec75ef2c91300ccd771c030529..d3c6e10dce73f122cfbaa6ca75ea82bec38c6a16 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -208,6 +208,8 @@ check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/sysca
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
 check_2 tools/perf/arch/parisc/entry/syscalls/syscall.tbl arch/parisc/entry/syscalls/syscall.tbl
+check_2 tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl arch/arm64/entry/syscalls/syscall_32.tbl
+check_2 tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl arch/arm64/entry/syscalls/syscall_64.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 02f23483bfff83809c4e649a2d054dba6975d12c..b7c0a4b9245a94b3b245fea59af79081b1f91081 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -26,10 +26,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
 #include <asm/syscalls_32.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
-#elif defined(__aarch64__)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_arm64;
 #elif defined(__mips__)
 #include <asm/syscalls_n64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:33:02 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:33:02 -0800
Subject: [PATCH v2 12/16] perf tools: loongarch: Use syscall table
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-12-f8ca984ffe40@rivosinc.com>

loongarch uses a syscall table, use that in perf instead of using unistd.h.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  5 +--
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/loongarch/Makefile                 | 22 -----------
 tools/perf/arch/loongarch/entry/syscalls/Kbuild    |  2 +
 .../loongarch/entry/syscalls/Makefile.syscalls     |  3 ++
 .../arch/loongarch/entry/syscalls/mksyscalltbl     | 45 ----------------------
 tools/perf/arch/loongarch/include/syscall_table.h  |  2 +
 tools/perf/util/syscalltbl.c                       |  4 --
 8 files changed, 10 insertions(+), 75 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index aefcbed7cdfac7c2a5d8db5cb111513f2d7c74ed..84ed266ce54f5291af5c59c02ccb06bfe17d840f 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips))
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
@@ -75,7 +75,6 @@ ifeq ($(SRCARCH),arm64)
 endif
 
 ifeq ($(SRCARCH),loongarch)
-  CFLAGS += -I$(OUTPUT)arch/loongarch/include/generated
   LIBUNWIND_LIBS = -lunwind -lunwind-loongarch64
 endif
 
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 6a287f15fa1da5e8957558ee0a73b297d347f00d..7fefeea1799231af61e77c9372318e025bed078a 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/loongarch/Makefile b/tools/perf/arch/loongarch/Makefile
index 52544d59245bab5a0fb2baa1e962b2ad4bf25332..087e099fb453a9236db34878077a51f711881ce0 100644
--- a/tools/perf/arch/loongarch/Makefile
+++ b/tools/perf/arch/loongarch/Makefile
@@ -1,25 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/loongarch/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/loongarch/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/loongarch/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, loongarch) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Kbuild b/tools/perf/arch/loongarch/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/loongarch/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls b/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..47d32da2aed8d67a7ac026271600e84723031a6b
--- /dev/null
+++ b/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 +=
diff --git a/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl b/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
deleted file mode 100755
index c10ad3580aef25e48ff0682eca4217cbafdfa333..0000000000000000000000000000000000000000
--- a/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Author(s):  Ming Wang <wangming01 at loongson.cn>
-# Author(s):  Huacai Chen <chenhuacai at loongson.cn>
-# Copyright (C) 2020-2023 Loongson Technology Corporation Limited
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_LOONGARCH_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_loongarch[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/loongarch/include/syscall_table.h b/tools/perf/arch/loongarch/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d0646d3455cdaf1a3db8c8565af8eba9a8df8c6
--- /dev/null
+++ b/tools/perf/arch/loongarch/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscall_table_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index b7c0a4b9245a94b3b245fea59af79081b1f91081..3001386e13a502be5279aa6e4742af0b96202b35 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -30,10 +30,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
 #include <asm/syscalls_n64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_mips_n64;
-#elif defined(__loongarch__)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_loongarch;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:32:50 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:50 -0800
Subject: [PATCH v2 00/16] perf tools: Use generic syscall scripts for all
 archs
Message-ID: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>

Standardize the generation of syscall headers around syscall tables.
Previously each architecture independently selected how syscall headers
would be generated, or would not define a way and fallback onto
libaudit. Convert all architectures to use a standard syscall header
generation script and allow each architecture to override the syscall
table to use if they do not use the generic table.

As a result of these changes, no architecture will require libaudit, and
so the fallback case of using libaudit is removed by this series.

Testing:

I have tested that the syscall mappings of id to name generation works
as expected for every architecture, but I have only validated that perf
trace compiles and runs as expected on riscv, arm64, and x86_64.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
Changes in v2:
- Rebase onto 6.13-rc2
- Fix output path so it generates to /tools/perf/arch properly
- Link to v1: https://lore.kernel.org/r/20241104-perf_syscalltbl-v1-0-9adae5c761ef at rivosinc.com

---
Charlie Jenkins (16):
      perf tools: Create generic syscall table support
      perf tools: arc: Support generic syscall headers
      perf tools: csky: Support generic syscall headers
      perf tools: arm: Support syscall headers
      perf tools: sh: Support syscall headers
      perf tools: sparc: Support syscall headers
      perf tools: xtensa: Support syscall header
      perf tools: x86: Use generic syscall scripts
      perf tools: alpha: Support syscall header
      perf tools: parisc: Support syscall header
      perf tools: arm64: Use syscall table
      perf tools: loongarch: Use syscall table
      perf tools: mips: Use generic syscall scripts
      perf tools: powerpc: Use generic syscall table scripts
      perf tools: s390: Use generic syscall table scripts
      perf tools: Remove dependency on libaudit

 Documentation/admin-guide/workload-tracing.rst     |   2 +-
 tools/build/feature/Makefile                       |   4 -
 tools/build/feature/test-libaudit.c                |  11 -
 tools/perf/Documentation/perf-check.txt            |   1 -
 tools/perf/Makefile.config                         |  39 +-
 tools/perf/Makefile.perf                           |  12 +-
 tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
 .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 ++++++++++++++++++++
 tools/perf/arch/alpha/include/syscall_table.h      |   2 +
 tools/perf/arch/arc/entry/syscalls/Kbuild          |   2 +
 .../perf/arch/arc/entry/syscalls/Makefile.syscalls |   3 +
 tools/perf/arch/arc/include/syscall_table.h        |   2 +
 tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
 .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
 tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 483 +++++++++++++++++++
 tools/perf/arch/arm/include/syscall_table.h        |   2 +
 tools/perf/arch/arm64/Makefile                     |  22 -
 tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
 .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
 .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++
 .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
 tools/perf/arch/arm64/include/syscall_table.h      |   8 +
 tools/perf/arch/csky/entry/syscalls/Kbuild         |   2 +
 .../arch/csky/entry/syscalls/Makefile.syscalls     |   3 +
 tools/perf/arch/csky/include/syscall_table.h       |   2 +
 tools/perf/arch/loongarch/Makefile                 |  22 -
 tools/perf/arch/loongarch/entry/syscalls/Kbuild    |   2 +
 .../loongarch/entry/syscalls/Makefile.syscalls     |   3 +
 .../arch/loongarch/entry/syscalls/mksyscalltbl     |  45 --
 tools/perf/arch/loongarch/include/syscall_table.h  |   2 +
 tools/perf/arch/mips/entry/syscalls/Kbuild         |   2 +
 .../arch/mips/entry/syscalls/Makefile.syscalls     |   5 +
 tools/perf/arch/mips/entry/syscalls/mksyscalltbl   |  32 --
 tools/perf/arch/mips/include/syscall_table.h       |   2 +
 tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
 .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
 tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++
 tools/perf/arch/parisc/include/syscall_table.h     |   8 +
 tools/perf/arch/powerpc/Makefile                   |  25 -
 tools/perf/arch/powerpc/entry/syscalls/Kbuild      |   3 +
 .../arch/powerpc/entry/syscalls/Makefile.syscalls  |   6 +
 .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  |  39 --
 tools/perf/arch/powerpc/include/syscall_table.h    |   8 +
 tools/perf/arch/riscv/Makefile                     |  22 -
 tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
 .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
 tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 --
 tools/perf/arch/riscv/include/syscall_table.h      |   8 +
 tools/perf/arch/s390/Makefile                      |  21 -
 tools/perf/arch/s390/entry/syscalls/Kbuild         |   2 +
 .../arch/s390/entry/syscalls/Makefile.syscalls     |   5 +
 tools/perf/arch/s390/entry/syscalls/mksyscalltbl   |  32 --
 tools/perf/arch/s390/include/syscall_table.h       |   2 +
 tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
 .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
 tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 472 +++++++++++++++++++
 tools/perf/arch/sh/include/syscall_table.h         |   2 +
 tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
 .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 514 +++++++++++++++++++++
 tools/perf/arch/sparc/include/syscall_table.h      |   8 +
 tools/perf/arch/x86/Build                          |   1 -
 tools/perf/arch/x86/Makefile                       |  25 -
 tools/perf/arch/x86/entry/syscalls/Kbuild          |   3 +
 .../perf/arch/x86/entry/syscalls/Makefile.syscalls |   6 +
 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   |  42 --
 tools/perf/arch/x86/include/syscall_table.h        |   8 +
 tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
 .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 439 ++++++++++++++++++
 tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
 tools/perf/builtin-check.c                         |   1 -
 tools/perf/builtin-help.c                          |   2 -
 tools/perf/builtin-trace.c                         |  30 --
 tools/perf/check-headers.sh                        |   9 +
 tools/perf/perf.c                                  |   6 +-
 tools/perf/scripts/Makefile.syscalls               |  60 +++
 tools/perf/scripts/syscalltbl.sh                   |  86 ++++
 tools/perf/tests/make                              |   7 +-
 tools/perf/util/env.c                              |   4 +-
 tools/perf/util/generate-cmdlist.sh                |   4 +-
 tools/perf/util/syscalltbl.c                       |  91 +---
 tools/scripts/syscall.tbl                          | 409 ++++++++++++++++
 85 files changed, 4101 insertions(+), 620 deletions(-)
---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20240913-perf_syscalltbl-6f98defcc6f5
-- 
- Charlie



From charlie at rivosinc.com  Thu Dec 12 16:32:51 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:51 -0800
Subject: [PATCH v2 01/16] perf tools: Create generic syscall table support
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-1-f8ca984ffe40@rivosinc.com>

Currently each architecture in perf independently generates syscall
headers. Adapt the work that has gone into unifying syscall header
implementations in the kernel to work with perf tools. Introduce this
framework with riscv at first. riscv previously relied on libaudit, but
with this change, perf tools for riscv no longer needs this external
dependency.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  11 +-
 tools/perf/Makefile.perf                           |   4 +
 tools/perf/arch/riscv/Makefile                     |  22 --
 tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
 .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
 tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 ---
 tools/perf/arch/riscv/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   1 +
 tools/perf/scripts/Makefile.syscalls               |  60 +++
 tools/perf/scripts/syscalltbl.sh                   |  86 +++++
 tools/perf/util/syscalltbl.c                       |   8 +-
 tools/scripts/syscall.tbl                          | 409 +++++++++++++++++++++
 12 files changed, 585 insertions(+), 77 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 2916d59c88cd08b299202a48ddb42fa32aac04a6..a72f25162714f0117a88d94474da336814d4f030 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -35,6 +35,13 @@ ifneq ($(NO_SYSCALL_TABLE),1)
     NO_SYSCALL_TABLE := 0
   endif
 
+  # architectures that use the generic syscall table scripts
+  ifeq ($(SRCARCH),riscv)
+    NO_SYSCALL_TABLE := 0
+    CFLAGS += -DGENERIC_SYSCALL_TABLE
+    CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
+  endif
+
   ifneq ($(NO_SYSCALL_TABLE),1)
     CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
   endif
@@ -83,10 +90,6 @@ ifeq ($(ARCH),mips)
   LIBUNWIND_LIBS = -lunwind -lunwind-mips
 endif
 
-ifeq ($(ARCH),riscv)
-  CFLAGS += -I$(OUTPUT)arch/riscv/include/generated
-endif
-
 # So far there's only x86 and arm libdw unwind support merged in perf.
 # Disable it on all other architectures in case libdw unwind
 # support is detected in system. Add supported architectures
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index d74241a151313bd09101aabb5d765a5a0a6efc84..f5278ed9f778f928436693a14e016c5c3c5171c1 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -310,6 +310,10 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
 FEATURE_TESTS := all
 endif
 endif
+# architectures that use the generic syscall table
+ifeq ($(SRCARCH),riscv)
+include $(srctree)/tools/perf/scripts/Makefile.syscalls
+endif
 include Makefile.config
 endif
 
diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
index 18ad078000e2bba595f92efc5d97a63fdb83ef45..087e099fb453a9236db34878077a51f711881ce0 100644
--- a/tools/perf/arch/riscv/Makefile
+++ b/tools/perf/arch/riscv/Makefile
@@ -1,25 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/riscv/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/riscv/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/riscv/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, riscv) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/riscv/entry/syscalls/Kbuild b/tools/perf/arch/riscv/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/riscv/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..9668fd1faf60e828ed2786c2ee84739ac1f153fc
--- /dev/null
+++ b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += riscv memfd_secret
+syscall_abis_64 += riscv rlimit memfd_secret
diff --git a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl b/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
deleted file mode 100755
index c59f5e852b97712a9a879b89e6ef6999ed4b6cd7..0000000000000000000000000000000000000000
--- a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-# Changed by: Kim Phillips <kim.phillips at arm.com>
-# Changed by: Bj?rn T?pel <bjorn at rivosinc.com>
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_RISCV_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_riscv[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/riscv/include/syscall_table.h b/tools/perf/arch/riscv/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/riscv/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index a05c1c105c51bf1bd18a59195220894598eb7461..692f48db810ccbef229e240db29261f0c60db632 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -71,6 +71,7 @@ FILES=(
   "include/uapi/asm-generic/ioctls.h"
   "include/uapi/asm-generic/mman-common.h"
   "include/uapi/asm-generic/unistd.h"
+  "scripts/syscall.tbl"
 )
 
 declare -a SYNC_CHECK_FILES
diff --git a/tools/perf/scripts/Makefile.syscalls b/tools/perf/scripts/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..e2b0c4b513d5c42c8e9ac51a9ea774c34a1311b7
--- /dev/null
+++ b/tools/perf/scripts/Makefile.syscalls
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: GPL-2.0
+# This Makefile generates tools/perf/arch/$(SRCARCH)/include/generated/asm from
+# the generic syscall table if that is supported by the architecture, otherwise
+# from the architecture's defined syscall table.
+
+PHONY := all
+all:
+
+obj := $(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated/asm
+
+syscall_abis_32  += common,32
+syscall_abis_64  += common,64
+syscalltbl := $(srctree)/tools/scripts/syscall.tbl
+
+# let architectures override $(syscall_abis_%) and $(syscalltbl)
+-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Makefile.syscalls
+include $(srctree)/scripts/Kbuild.include
+-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Kbuild
+
+systbl := $(srctree)/tools/perf/scripts/syscalltbl.sh
+
+syscall-y   := $(addprefix $(obj)/, $(syscall-y))
+
+# Remove stale wrappers when the corresponding files are removed from generic-y
+old-headers := $(wildcard $(obj)/*.c)
+unwanted    := $(filter-out $(syscall-y),$(old-headers))
+
+quiet_cmd_remove = REMOVE  $(unwanted)
+      cmd_remove = rm -f $(unwanted)
+
+quiet_cmd_systbl = SYSTBL  $@
+      cmd_systbl = $(CONFIG_SHELL) $(systbl) \
+		   $(if $(systbl-args-$*),$(systbl-args-$*),$(systbl-args)) \
+		   --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \
+		   $< $@
+
+all: $(syscall-y)
+	$(if $(unwanted),$(call cmd,remove))
+	@:
+
+$(obj)/syscalls_%.h: $(syscalltbl) $(systbl) FORCE
+	$(call if_changed,systbl)
+
+targets := $(syscall-y)
+
+# Create output directory. Skip it if at least one old header exists
+# since we know the output directory already exists.
+ifeq ($(old-headers),)
+$(shell mkdir -p $(obj))
+endif
+
+PHONY += FORCE
+
+FORCE:
+
+existing-targets := $(wildcard $(sort $(targets)))
+
+-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
+
+.PHONY: $(PHONY)
diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1ce0d5aa8b506427a66be50f0f441cf6e9705b33
--- /dev/null
+++ b/tools/perf/scripts/syscalltbl.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generate a syscall table header.
+#
+# Each line of the syscall table should have the following format:
+#
+# NR ABI NAME [NATIVE] [COMPAT]
+#
+# NR       syscall number
+# ABI      ABI name
+# NAME     syscall name
+# NATIVE   native entry point (optional)
+# COMPAT   compat entry point (optional)
+
+set -e
+
+usage() {
+	echo >&2 "usage: $0 [--abis ABIS] INFILE OUTFILE" >&2
+	echo >&2
+	echo >&2 "  INFILE    input syscall table"
+	echo >&2 "  OUTFILE   output header file"
+	echo >&2
+	echo >&2 "options:"
+	echo >&2 "  --abis ABIS        ABI(s) to handle (By default, all lines are handled)"
+	exit 1
+}
+
+# default unless specified by options
+abis=
+
+while [ $# -gt 0 ]
+do
+	case $1 in
+	--abis)
+		abis=$(echo "($2)" | tr ',' '|')
+		shift 2;;
+	-*)
+		echo "$1: unknown option" >&2
+		usage;;
+	*)
+		break;;
+	esac
+done
+
+if [ $# -ne 2 ]; then
+	usage
+fi
+
+infile="$1"
+outfile="$2"
+
+nxt=0
+
+syscall_macro() {
+    nr="$1"
+    name="$2"
+
+    echo "	[$nr] = \"$name\","
+}
+
+emit() {
+    nr="$1"
+    entry="$2"
+
+    syscall_macro "$nr" "$entry"
+}
+
+echo "static const char *const syscalltbl[] = {" > $outfile
+
+sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
+grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table
+
+max_nr=0
+# the params are: nr abi name entry compat
+# use _ for intentionally unused variables according to SC2034
+while read nr _ name _ _; do
+    emit "$nr" "$name" >> $outfile
+    max_nr=$nr
+done < $sorted_table
+
+rm -f $sorted_table
+
+echo "};" >> $outfile
+
+echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 69d8dcf5cf28c4e8a0e403153c92bd6436e2a0b2..ccf234a54366f9921c3b9a02ffb0a365d17244bc 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -46,10 +46,10 @@ static const char *const *syscalltbl_native = syscalltbl_mips_n64;
 #include <asm/syscalls.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_loongarch;
-#elif defined(__riscv)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_RISCV_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_riscv;
+#elif defined(GENERIC_SYSCALL_TABLE)
+#include <syscall_table.h>
+const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
+static const char *const *syscalltbl_native = syscalltbl;
 #else
 const int syscalltbl_native_max_id = 0;
 static const char *const syscalltbl_native[] = {
diff --git a/tools/scripts/syscall.tbl b/tools/scripts/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..ebbdb3c42e9f74613b003014c0baf44c842bb756
--- /dev/null
+++ b/tools/scripts/syscall.tbl
@@ -0,0 +1,409 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# This file contains the system call numbers for all of the
+# more recently added architectures.
+#
+# As a basic principle, no duplication of functionality
+# should be added, e.g. we don't use lseek when llseek
+# is present. New architectures should use this file
+# and implement the less feature-full calls in user space.
+#
+0	common	io_setup			sys_io_setup			compat_sys_io_setup
+1	common	io_destroy			sys_io_destroy
+2	common	io_submit			sys_io_submit			compat_sys_io_submit
+3	common	io_cancel			sys_io_cancel
+4	time32	io_getevents			sys_io_getevents_time32
+4	64	io_getevents			sys_io_getevents
+5	common	setxattr			sys_setxattr
+6	common	lsetxattr			sys_lsetxattr
+7	common	fsetxattr			sys_fsetxattr
+8	common	getxattr			sys_getxattr
+9	common	lgetxattr			sys_lgetxattr
+10	common	fgetxattr			sys_fgetxattr
+11	common	listxattr			sys_listxattr
+12	common	llistxattr			sys_llistxattr
+13	common	flistxattr			sys_flistxattr
+14	common	removexattr			sys_removexattr
+15	common	lremovexattr			sys_lremovexattr
+16	common	fremovexattr			sys_fremovexattr
+17	common	getcwd				sys_getcwd
+18	common	lookup_dcookie			sys_ni_syscall
+19	common	eventfd2			sys_eventfd2
+20	common	epoll_create1			sys_epoll_create1
+21	common	epoll_ctl			sys_epoll_ctl
+22	common	epoll_pwait			sys_epoll_pwait			compat_sys_epoll_pwait
+23	common	dup				sys_dup
+24	common	dup3				sys_dup3
+25	32	fcntl64				sys_fcntl64			compat_sys_fcntl64
+25	64	fcntl				sys_fcntl
+26	common	inotify_init1			sys_inotify_init1
+27	common	inotify_add_watch		sys_inotify_add_watch
+28	common	inotify_rm_watch		sys_inotify_rm_watch
+29	common	ioctl				sys_ioctl			compat_sys_ioctl
+30	common	ioprio_set			sys_ioprio_set
+31	common	ioprio_get			sys_ioprio_get
+32	common	flock				sys_flock
+33	common	mknodat				sys_mknodat
+34	common	mkdirat				sys_mkdirat
+35	common	unlinkat			sys_unlinkat
+36	common	symlinkat			sys_symlinkat
+37	common	linkat				sys_linkat
+# renameat is superseded with flags by renameat2
+38	renameat renameat			sys_renameat
+39	common	umount2				sys_umount
+40	common	mount				sys_mount
+41	common	pivot_root			sys_pivot_root
+42	common	nfsservctl			sys_ni_syscall
+43	32	statfs64			sys_statfs64			compat_sys_statfs64
+43	64	statfs				sys_statfs
+44	32	fstatfs64			sys_fstatfs64			compat_sys_fstatfs64
+44	64	fstatfs				sys_fstatfs
+45	32	truncate64			sys_truncate64			compat_sys_truncate64
+45	64	truncate			sys_truncate
+46	32	ftruncate64			sys_ftruncate64			compat_sys_ftruncate64
+46	64	ftruncate			sys_ftruncate
+47	common	fallocate			sys_fallocate			compat_sys_fallocate
+48	common	faccessat			sys_faccessat
+49	common	chdir				sys_chdir
+50	common	fchdir				sys_fchdir
+51	common	chroot				sys_chroot
+52	common	fchmod				sys_fchmod
+53	common	fchmodat			sys_fchmodat
+54	common	fchownat			sys_fchownat
+55	common	fchown				sys_fchown
+56	common	openat				sys_openat
+57	common	close				sys_close
+58	common	vhangup				sys_vhangup
+59	common	pipe2				sys_pipe2
+60	common	quotactl			sys_quotactl
+61	common	getdents64			sys_getdents64
+62	32	llseek				sys_llseek
+62	64	lseek				sys_lseek
+63	common	read				sys_read
+64	common	write				sys_write
+65	common	readv				sys_readv			sys_readv
+66	common	writev				sys_writev			sys_writev
+67	common	pread64				sys_pread64			compat_sys_pread64
+68	common	pwrite64			sys_pwrite64			compat_sys_pwrite64
+69	common	preadv				sys_preadv			compat_sys_preadv
+70	common	pwritev				sys_pwritev			compat_sys_pwritev
+71	32	sendfile64			sys_sendfile64
+71	64	sendfile			sys_sendfile64
+72	time32	pselect6			sys_pselect6_time32		compat_sys_pselect6_time32
+72	64	pselect6			sys_pselect6
+73	time32	ppoll				sys_ppoll_time32		compat_sys_ppoll_time32
+73	64	ppoll				sys_ppoll
+74	common	signalfd4			sys_signalfd4			compat_sys_signalfd4
+75	common	vmsplice			sys_vmsplice
+76	common	splice				sys_splice
+77	common	tee				sys_tee
+78	common	readlinkat			sys_readlinkat
+79	stat64	fstatat64			sys_fstatat64
+79	64	newfstatat			sys_newfstatat
+80	stat64	fstat64				sys_fstat64
+80	64	fstat				sys_newfstat
+81	common	sync				sys_sync
+82	common	fsync				sys_fsync
+83	common	fdatasync			sys_fdatasync
+84	common	sync_file_range			sys_sync_file_range		compat_sys_sync_file_range
+85	common	timerfd_create			sys_timerfd_create
+86	time32	timerfd_settime			sys_timerfd_settime32
+86	64	timerfd_settime			sys_timerfd_settime
+87	time32	timerfd_gettime			sys_timerfd_gettime32
+87	64	timerfd_gettime			sys_timerfd_gettime
+88	time32	utimensat			sys_utimensat_time32
+88	64	utimensat			sys_utimensat
+89	common	acct				sys_acct
+90	common	capget				sys_capget
+91	common	capset				sys_capset
+92	common	personality			sys_personality
+93	common	exit				sys_exit
+94	common	exit_group			sys_exit_group
+95	common	waitid				sys_waitid			compat_sys_waitid
+96	common	set_tid_address			sys_set_tid_address
+97	common	unshare				sys_unshare
+98	time32	futex				sys_futex_time32
+98	64	futex				sys_futex
+99	common	set_robust_list			sys_set_robust_list		compat_sys_set_robust_list
+100	common	get_robust_list			sys_get_robust_list		compat_sys_get_robust_list
+101	time32	nanosleep			sys_nanosleep_time32
+101	64	nanosleep			sys_nanosleep
+102	common	getitimer			sys_getitimer			compat_sys_getitimer
+103	common	setitimer			sys_setitimer			compat_sys_setitimer
+104	common	kexec_load			sys_kexec_load			compat_sys_kexec_load
+105	common	init_module			sys_init_module
+106	common	delete_module			sys_delete_module
+107	common	timer_create			sys_timer_create		compat_sys_timer_create
+108	time32	timer_gettime			sys_timer_gettime32
+108	64	timer_gettime			sys_timer_gettime
+109	common	timer_getoverrun		sys_timer_getoverrun
+110	time32	timer_settime			sys_timer_settime32
+110	64	timer_settime			sys_timer_settime
+111	common	timer_delete			sys_timer_delete
+112	time32	clock_settime			sys_clock_settime32
+112	64	clock_settime			sys_clock_settime
+113	time32	clock_gettime			sys_clock_gettime32
+113	64	clock_gettime			sys_clock_gettime
+114	time32	clock_getres			sys_clock_getres_time32
+114	64	clock_getres			sys_clock_getres
+115	time32	clock_nanosleep			sys_clock_nanosleep_time32
+115	64	clock_nanosleep			sys_clock_nanosleep
+116	common	syslog				sys_syslog
+117	common	ptrace				sys_ptrace			compat_sys_ptrace
+118	common	sched_setparam			sys_sched_setparam
+119	common	sched_setscheduler		sys_sched_setscheduler
+120	common	sched_getscheduler		sys_sched_getscheduler
+121	common	sched_getparam			sys_sched_getparam
+122	common	sched_setaffinity		sys_sched_setaffinity		compat_sys_sched_setaffinity
+123	common	sched_getaffinity		sys_sched_getaffinity		compat_sys_sched_getaffinity
+124	common	sched_yield			sys_sched_yield
+125	common	sched_get_priority_max		sys_sched_get_priority_max
+126	common	sched_get_priority_min		sys_sched_get_priority_min
+127	time32	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+127	64	sched_rr_get_interval		sys_sched_rr_get_interval
+128	common	restart_syscall			sys_restart_syscall
+129	common	kill				sys_kill
+130	common	tkill				sys_tkill
+131	common	tgkill				sys_tgkill
+132	common	sigaltstack			sys_sigaltstack			compat_sys_sigaltstack
+133	common	rt_sigsuspend			sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+134	common	rt_sigaction			sys_rt_sigaction		compat_sys_rt_sigaction
+135	common	rt_sigprocmask			sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+136	common	rt_sigpending			sys_rt_sigpending		compat_sys_rt_sigpending
+137	time32	rt_sigtimedwait			sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+137	64	rt_sigtimedwait			sys_rt_sigtimedwait
+138	common	rt_sigqueueinfo			sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+139	common	rt_sigreturn			sys_rt_sigreturn		compat_sys_rt_sigreturn
+140	common	setpriority			sys_setpriority
+141	common	getpriority			sys_getpriority
+142	common	reboot				sys_reboot
+143	common	setregid			sys_setregid
+144	common	setgid				sys_setgid
+145	common	setreuid			sys_setreuid
+146	common	setuid				sys_setuid
+147	common	setresuid			sys_setresuid
+148	common	getresuid			sys_getresuid
+149	common	setresgid			sys_setresgid
+150	common	getresgid			sys_getresgid
+151	common	setfsuid			sys_setfsuid
+152	common	setfsgid			sys_setfsgid
+153	common	times				sys_times			compat_sys_times
+154	common	setpgid				sys_setpgid
+155	common	getpgid				sys_getpgid
+156	common	getsid				sys_getsid
+157	common	setsid				sys_setsid
+158	common	getgroups			sys_getgroups
+159	common	setgroups			sys_setgroups
+160	common	uname				sys_newuname
+161	common	sethostname			sys_sethostname
+162	common	setdomainname			sys_setdomainname
+# getrlimit and setrlimit are superseded with prlimit64
+163	rlimit	getrlimit			sys_getrlimit			compat_sys_getrlimit
+164	rlimit	setrlimit			sys_setrlimit			compat_sys_setrlimit
+165	common	getrusage			sys_getrusage			compat_sys_getrusage
+166	common	umask				sys_umask
+167	common	prctl				sys_prctl
+168	common	getcpu				sys_getcpu
+169	time32	gettimeofday			sys_gettimeofday		compat_sys_gettimeofday
+169	64	gettimeofday			sys_gettimeofday
+170	time32	settimeofday			sys_settimeofday		compat_sys_settimeofday
+170	64	settimeofday			sys_settimeofday
+171	time32	adjtimex			sys_adjtimex_time32
+171	64	adjtimex			sys_adjtimex
+172	common	getpid				sys_getpid
+173	common	getppid				sys_getppid
+174	common	getuid				sys_getuid
+175	common	geteuid				sys_geteuid
+176	common	getgid				sys_getgid
+177	common	getegid				sys_getegid
+178	common	gettid				sys_gettid
+179	common	sysinfo				sys_sysinfo			compat_sys_sysinfo
+180	common	mq_open				sys_mq_open			compat_sys_mq_open
+181	common	mq_unlink			sys_mq_unlink
+182	time32	mq_timedsend			sys_mq_timedsend_time32
+182	64	mq_timedsend			sys_mq_timedsend
+183	time32	mq_timedreceive			sys_mq_timedreceive_time32
+183	64	mq_timedreceive			sys_mq_timedreceive
+184	common	mq_notify			sys_mq_notify			compat_sys_mq_notify
+185	common	mq_getsetattr			sys_mq_getsetattr		compat_sys_mq_getsetattr
+186	common	msgget				sys_msgget
+187	common	msgctl				sys_msgctl			compat_sys_msgctl
+188	common	msgrcv				sys_msgrcv			compat_sys_msgrcv
+189	common	msgsnd				sys_msgsnd			compat_sys_msgsnd
+190	common	semget				sys_semget
+191	common	semctl				sys_semctl			compat_sys_semctl
+192	time32	semtimedop			sys_semtimedop_time32
+192	64	semtimedop			sys_semtimedop
+193	common	semop				sys_semop
+194	common	shmget				sys_shmget
+195	common	shmctl				sys_shmctl			compat_sys_shmctl
+196	common	shmat				sys_shmat			compat_sys_shmat
+197	common	shmdt				sys_shmdt
+198	common	socket				sys_socket
+199	common	socketpair			sys_socketpair
+200	common	bind				sys_bind
+201	common	listen				sys_listen
+202	common	accept				sys_accept
+203	common	connect				sys_connect
+204	common	getsockname			sys_getsockname
+205	common	getpeername			sys_getpeername
+206	common	sendto				sys_sendto
+207	common	recvfrom			sys_recvfrom			compat_sys_recvfrom
+208	common	setsockopt			sys_setsockopt			sys_setsockopt
+209	common	getsockopt			sys_getsockopt			sys_getsockopt
+210	common	shutdown			sys_shutdown
+211	common	sendmsg				sys_sendmsg			compat_sys_sendmsg
+212	common	recvmsg				sys_recvmsg			compat_sys_recvmsg
+213	common	readahead			sys_readahead			compat_sys_readahead
+214	common	brk				sys_brk
+215	common	munmap				sys_munmap
+216	common	mremap				sys_mremap
+217	common	add_key				sys_add_key
+218	common	request_key			sys_request_key
+219	common	keyctl				sys_keyctl			compat_sys_keyctl
+220	common	clone				sys_clone
+221	common	execve				sys_execve			compat_sys_execve
+222	32	mmap2				sys_mmap2
+222	64	mmap				sys_mmap
+223	32	fadvise64_64			sys_fadvise64_64		compat_sys_fadvise64_64
+223	64	fadvise64			sys_fadvise64_64
+224	common	swapon				sys_swapon
+225	common	swapoff				sys_swapoff
+226	common	mprotect			sys_mprotect
+227	common	msync				sys_msync
+228	common	mlock				sys_mlock
+229	common	munlock				sys_munlock
+230	common	mlockall			sys_mlockall
+231	common	munlockall			sys_munlockall
+232	common	mincore				sys_mincore
+233	common	madvise				sys_madvise
+234	common	remap_file_pages		sys_remap_file_pages
+235	common	mbind				sys_mbind
+236	common	get_mempolicy			sys_get_mempolicy
+237	common	set_mempolicy			sys_set_mempolicy
+238	common	migrate_pages			sys_migrate_pages
+239	common	move_pages			sys_move_pages
+240	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+241	common	perf_event_open			sys_perf_event_open
+242	common	accept4				sys_accept4
+243	time32	recvmmsg			sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+243	64	recvmmsg			sys_recvmmsg
+# Architectures may provide up to 16 syscalls of their own between 244 and 259
+244	arc	cacheflush			sys_cacheflush
+245	arc	arc_settls			sys_arc_settls
+246	arc	arc_gettls			sys_arc_gettls
+247	arc	sysfs				sys_sysfs
+248	arc	arc_usr_cmpxchg			sys_arc_usr_cmpxchg
+
+244	csky	set_thread_area			sys_set_thread_area
+245	csky	cacheflush			sys_cacheflush
+
+244	nios2	cacheflush			sys_cacheflush
+
+244	or1k	or1k_atomic			sys_or1k_atomic
+
+258	riscv	riscv_hwprobe			sys_riscv_hwprobe
+259	riscv	riscv_flush_icache		sys_riscv_flush_icache
+
+260	time32	wait4				sys_wait4			compat_sys_wait4
+260	64	wait4				sys_wait4
+261	common	prlimit64			sys_prlimit64
+262	common	fanotify_init			sys_fanotify_init
+263	common	fanotify_mark			sys_fanotify_mark
+264	common	name_to_handle_at		sys_name_to_handle_at
+265	common	open_by_handle_at		sys_open_by_handle_at
+266	time32	clock_adjtime			sys_clock_adjtime32
+266	64	clock_adjtime			sys_clock_adjtime
+267	common	syncfs				sys_syncfs
+268	common	setns				sys_setns
+269	common	sendmmsg			sys_sendmmsg			compat_sys_sendmmsg
+270	common	process_vm_readv		sys_process_vm_readv
+271	common	process_vm_writev		sys_process_vm_writev
+272	common	kcmp				sys_kcmp
+273	common	finit_module			sys_finit_module
+274	common	sched_setattr			sys_sched_setattr
+275	common	sched_getattr			sys_sched_getattr
+276	common	renameat2			sys_renameat2
+277	common	seccomp				sys_seccomp
+278	common	getrandom			sys_getrandom
+279	common	memfd_create			sys_memfd_create
+280	common	bpf				sys_bpf
+281	common	execveat			sys_execveat			compat_sys_execveat
+282	common	userfaultfd			sys_userfaultfd
+283	common	membarrier			sys_membarrier
+284	common	mlock2				sys_mlock2
+285	common	copy_file_range			sys_copy_file_range
+286	common	preadv2				sys_preadv2			compat_sys_preadv2
+287	common	pwritev2			sys_pwritev2			compat_sys_pwritev2
+288	common	pkey_mprotect			sys_pkey_mprotect
+289	common	pkey_alloc			sys_pkey_alloc
+290	common	pkey_free			sys_pkey_free
+291	common	statx				sys_statx
+292	time32	io_pgetevents			sys_io_pgetevents_time32	compat_sys_io_pgetevents
+292	64	io_pgetevents			sys_io_pgetevents
+293	common	rseq				sys_rseq
+294	common	kexec_file_load			sys_kexec_file_load
+# 295 through 402 are unassigned to sync up with generic numbers don't use
+403	32	clock_gettime64			sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+447	memfd_secret	memfd_secret		sys_memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:32:52 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:52 -0800
Subject: [PATCH v2 02/16] perf tools: arc: Support generic syscall headers
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-2-f8ca984ffe40@rivosinc.com>

Arc uses the generic syscall table, use that in perf instead of
requiring libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                           | 2 +-
 tools/perf/Makefile.perf                             | 2 +-
 tools/perf/arch/arc/entry/syscalls/Kbuild            | 2 ++
 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls | 3 +++
 tools/perf/arch/arc/include/syscall_table.h          | 2 ++
 5 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index a72f25162714f0117a88d94474da336814d4f030..3959a9c9972999f6d1bb85e8c1d7dc5dce92fd09 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),riscv)
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f5278ed9f778f928436693a14e016c5c3c5171c1..3b463b42b0e3982e74056e672b2ee6adad5a3f0e 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),riscv)
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/arc/entry/syscalls/Kbuild b/tools/perf/arch/arc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/arc/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..391d30ab7a831b72d2ed3f2e7966fdbf558a9ed7
--- /dev/null
+++ b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += arc time32 renameat stat64 rlimit
diff --git a/tools/perf/arch/arc/include/syscall_table.h b/tools/perf/arch/arc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/arc/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:32:53 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:53 -0800
Subject: [PATCH v2 03/16] perf tools: csky: Support generic syscall headers
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-3-f8ca984ffe40@rivosinc.com>

csky uses the generic syscall table, use that in perf instead of
requiring libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                            | 2 +-
 tools/perf/Makefile.perf                              | 2 +-
 tools/perf/arch/csky/entry/syscalls/Kbuild            | 2 ++
 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls | 3 +++
 tools/perf/arch/csky/include/syscall_table.h          | 2 ++
 5 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 3959a9c9972999f6d1bb85e8c1d7dc5dce92fd09..6fcaa051a47621b818b4c9d967eeed050056e400 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 3b463b42b0e3982e74056e672b2ee6adad5a3f0e..407f589046e032c4103c3b6b82c9d044560c5bac 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/csky/entry/syscalls/Kbuild b/tools/perf/arch/csky/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/csky/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls b/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..ea2dd10d0571df464574a9c0232ada0ac1f79a3f
--- /dev/null
+++ b/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += csky time32 stat64 rlimit
diff --git a/tools/perf/arch/csky/include/syscall_table.h b/tools/perf/arch/csky/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/csky/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:32:54 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:32:54 -0800
Subject: [PATCH v2 04/16] perf tools: arm: Support syscall headers
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-4-f8ca984ffe40@rivosinc.com>

arm uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
 .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
 tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 483 +++++++++++++++++++++
 tools/perf/arch/arm/include/syscall_table.h        |   2 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 494 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 6fcaa051a47621b818b4c9d967eeed050056e400..3093cf90e76d3627e9ef842ea1a24dbeb6f56422 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 407f589046e032c4103c3b6b82c9d044560c5bac..01a6cd630396204c9119b12bb1fe26b6133fa5d2 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/arm/entry/syscalls/Kbuild b/tools/perf/arch/arm/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9d777540f08987908a6532c5ece66553dffc52df
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/Kbuild
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += oabi
+syscalltbl = $(srctree)/tools/perf/arch/arm/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arm/entry/syscalls/syscall.tbl b/tools/perf/arch/arm/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..49eeb2ad8dbd8e074c6240417693f23fb328afa8
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/syscall.tbl
@@ -0,0 +1,483 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# Linux system call numbers and entry vectors
+#
+# The format is:
+# <num>	<abi>	<name>			[<entry point>			[<oabi compat entry point>]]
+#
+# Where abi is:
+#  common - for system calls shared between oabi and eabi (may have compat)
+#  oabi   - for oabi-only system calls (may have compat)
+#  eabi   - for eabi-only system calls
+#
+# For each syscall number, "common" is mutually exclusive with oabi and eabi
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open
+6	common	close			sys_close
+# 7 was sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve
+12	common	chdir			sys_chdir
+13	oabi	time			sys_time32
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19	common	lseek			sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+22	oabi	umount			sys_oldumount
+23	common	setuid			sys_setuid16
+24	common	getuid			sys_getuid16
+25	oabi	stime			sys_stime32
+26	common	ptrace			sys_ptrace
+27	oabi	alarm			sys_alarm
+# 28 was sys_fstat
+29	common	pause			sys_pause
+30	oabi	utime			sys_utime32
+# 31 was sys_stty
+# 32 was sys_gtty
+33	common	access			sys_access
+34	common	nice			sys_nice
+# 35 was sys_ftime
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times
+# 44 was sys_prof
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid16
+47	common	getgid			sys_getgid16
+# 48 was sys_signal
+49	common	geteuid			sys_geteuid16
+50	common	getegid			sys_getegid16
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+# 53 was sys_lock
+54	common	ioctl			sys_ioctl
+55	common	fcntl			sys_fcntl
+# 56 was sys_mpx
+57	common	setpgid			sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	sigaction		sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70	common	setreuid		sys_setreuid16
+71	common	setregid		sys_setregid16
+72	common	sigsuspend		sys_sigsuspend
+73	common	sigpending		sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit
+# Back compat 2GB limited rlimit
+76	oabi	getrlimit		sys_old_getrlimit
+77	common	getrusage		sys_getrusage
+78	common	gettimeofday		sys_gettimeofday
+79	common	settimeofday		sys_settimeofday
+80	common	getgroups		sys_getgroups16
+81	common	setgroups		sys_setgroups16
+82	oabi	select			sys_old_select
+83	common	symlink			sys_symlink
+# 84 was sys_lstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_uselib
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+89	oabi	readdir			sys_old_readdir
+90	oabi	mmap			sys_old_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate
+93	common	ftruncate		sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown16
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+# 98 was sys_profil
+99	common	statfs			sys_statfs
+100	common	fstatfs			sys_fstatfs
+# 101 was sys_ioperm
+102	oabi	socketcall		sys_socketcall		sys_oabi_socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer
+105	common	getitimer		sys_getitimer
+106	common	stat			sys_newstat
+107	common	lstat			sys_newlstat
+108	common	fstat			sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111	common	vhangup			sys_vhangup
+# 112 was sys_idle
+# syscall to call a syscall!
+113	oabi	syscall			sys_syscall
+114	common	wait4			sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo
+117	oabi	ipc			sys_ipc			sys_oabi_ipc
+118	common	fsync			sys_fsync
+119	common	sigreturn		sys_sigreturn_wrapper
+120	common	clone			sys_clone
+121	common	setdomainname		sys_setdomainname
+122	common	uname			sys_newuname
+# 123 was sys_modify_ldt
+124	common	adjtimex		sys_adjtimex_time32
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask
+# 127 was sys_create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was sys_get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	common	personality		sys_personality
+# 137 was sys_afs_syscall
+138	common	setfsuid		sys_setfsuid16
+139	common	setfsgid		sys_setfsgid16
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents
+142	common	_newselect		sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	common	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+162	common	nanosleep		sys_nanosleep_time32
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid16
+165	common	getresuid		sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168	common	poll			sys_poll
+169	common	nfsservctl
+170	common	setresgid		sys_setresgid16
+171	common	getresgid		sys_getresgid16
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper
+174	common	rt_sigaction		sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending
+177	common	rt_sigtimedwait		sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend
+180	common	pread64			sys_pread64		sys_oabi_pread64
+181	common	pwrite64		sys_pwrite64		sys_oabi_pwrite64
+182	common	chown			sys_chown16
+183	common	getcwd			sys_getcwd
+184	common	capget			sys_capget
+185	common	capset			sys_capset
+186	common	sigaltstack		sys_sigaltstack
+187	common	sendfile		sys_sendfile
+# 188 reserved
+# 189 reserved
+190	common	vfork			sys_vfork
+# SuS compliant getrlimit
+191	common	ugetrlimit		sys_getrlimit
+192	common	mmap2			sys_mmap2
+193	common	truncate64		sys_truncate64		sys_oabi_truncate64
+194	common	ftruncate64		sys_ftruncate64		sys_oabi_ftruncate64
+195	common	stat64			sys_stat64		sys_oabi_stat64
+196	common	lstat64			sys_lstat64		sys_oabi_lstat64
+197	common	fstat64			sys_fstat64		sys_oabi_fstat64
+198	common	lchown32		sys_lchown
+199	common	getuid32		sys_getuid
+200	common	getgid32		sys_getgid
+201	common	geteuid32		sys_geteuid
+202	common	getegid32		sys_getegid
+203	common	setreuid32		sys_setreuid
+204	common	setregid32		sys_setregid
+205	common	getgroups32		sys_getgroups
+206	common	setgroups32		sys_setgroups
+207	common	fchown32		sys_fchown
+208	common	setresuid32		sys_setresuid
+209	common	getresuid32		sys_getresuid
+210	common	setresgid32		sys_setresgid
+211	common	getresgid32		sys_getresgid
+212	common	chown32			sys_chown
+213	common	setuid32		sys_setuid
+214	common	setgid32		sys_setgid
+215	common	setfsuid32		sys_setfsuid
+216	common	setfsgid32		sys_setfsgid
+217	common	getdents64		sys_getdents64
+218	common	pivot_root		sys_pivot_root
+219	common	mincore			sys_mincore
+220	common	madvise			sys_madvise
+221	common	fcntl64			sys_fcntl64		sys_oabi_fcntl64
+# 222 for tux
+# 223 is unused
+224	common	gettid			sys_gettid
+225	common	readahead		sys_readahead		sys_oabi_readahead
+226	common	setxattr		sys_setxattr
+227	common	lsetxattr		sys_lsetxattr
+228	common	fsetxattr		sys_fsetxattr
+229	common	getxattr		sys_getxattr
+230	common	lgetxattr		sys_lgetxattr
+231	common	fgetxattr		sys_fgetxattr
+232	common	listxattr		sys_listxattr
+233	common	llistxattr		sys_llistxattr
+234	common	flistxattr		sys_flistxattr
+235	common	removexattr		sys_removexattr
+236	common	lremovexattr		sys_lremovexattr
+237	common	fremovexattr		sys_fremovexattr
+238	common	tkill			sys_tkill
+239	common	sendfile64		sys_sendfile64
+240	common	futex			sys_futex_time32
+241	common	sched_setaffinity	sys_sched_setaffinity
+242	common	sched_getaffinity	sys_sched_getaffinity
+243	common	io_setup		sys_io_setup
+244	common	io_destroy		sys_io_destroy
+245	common	io_getevents		sys_io_getevents_time32
+246	common	io_submit		sys_io_submit
+247	common	io_cancel		sys_io_cancel
+248	common	exit_group		sys_exit_group
+249	common	lookup_dcookie		sys_ni_syscall
+250	common	epoll_create		sys_epoll_create
+251	common	epoll_ctl		sys_epoll_ctl		sys_oabi_epoll_ctl
+252	common	epoll_wait		sys_epoll_wait
+253	common	remap_file_pages	sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256	common	set_tid_address		sys_set_tid_address
+257	common	timer_create		sys_timer_create
+258	common	timer_settime		sys_timer_settime32
+259	common	timer_gettime		sys_timer_gettime32
+260	common	timer_getoverrun	sys_timer_getoverrun
+261	common	timer_delete		sys_timer_delete
+262	common	clock_settime		sys_clock_settime32
+263	common	clock_gettime		sys_clock_gettime32
+264	common	clock_getres		sys_clock_getres_time32
+265	common	clock_nanosleep		sys_clock_nanosleep_time32
+266	common	statfs64		sys_statfs64_wrapper
+267	common	fstatfs64		sys_fstatfs64_wrapper
+268	common	tgkill			sys_tgkill
+269	common	utimes			sys_utimes_time32
+270	common	arm_fadvise64_64	sys_arm_fadvise64_64
+271	common	pciconfig_iobase	sys_pciconfig_iobase
+272	common	pciconfig_read		sys_pciconfig_read
+273	common	pciconfig_write		sys_pciconfig_write
+274	common	mq_open			sys_mq_open
+275	common	mq_unlink		sys_mq_unlink
+276	common	mq_timedsend		sys_mq_timedsend_time32
+277	common	mq_timedreceive		sys_mq_timedreceive_time32
+278	common	mq_notify		sys_mq_notify
+279	common	mq_getsetattr		sys_mq_getsetattr
+280	common	waitid			sys_waitid
+281	common	socket			sys_socket
+282	common	bind			sys_bind		sys_oabi_bind
+283	common	connect			sys_connect		sys_oabi_connect
+284	common	listen			sys_listen
+285	common	accept			sys_accept
+286	common	getsockname		sys_getsockname
+287	common	getpeername		sys_getpeername
+288	common	socketpair		sys_socketpair
+289	common	send			sys_send
+290	common	sendto			sys_sendto		sys_oabi_sendto
+291	common	recv			sys_recv
+292	common	recvfrom		sys_recvfrom
+293	common	shutdown		sys_shutdown
+294	common	setsockopt		sys_setsockopt
+295	common	getsockopt		sys_getsockopt
+296	common	sendmsg			sys_sendmsg		sys_oabi_sendmsg
+297	common	recvmsg			sys_recvmsg
+298	common	semop			sys_semop		sys_oabi_semop
+299	common	semget			sys_semget
+300	common	semctl			sys_old_semctl
+301	common	msgsnd			sys_msgsnd
+302	common	msgrcv			sys_msgrcv
+303	common	msgget			sys_msgget
+304	common	msgctl			sys_old_msgctl
+305	common	shmat			sys_shmat
+306	common	shmdt			sys_shmdt
+307	common	shmget			sys_shmget
+308	common	shmctl			sys_old_shmctl
+309	common	add_key			sys_add_key
+310	common	request_key		sys_request_key
+311	common	keyctl			sys_keyctl
+312	common	semtimedop		sys_semtimedop_time32	sys_oabi_semtimedop
+313	common	vserver
+314	common	ioprio_set		sys_ioprio_set
+315	common	ioprio_get		sys_ioprio_get
+316	common	inotify_init		sys_inotify_init
+317	common	inotify_add_watch	sys_inotify_add_watch
+318	common	inotify_rm_watch	sys_inotify_rm_watch
+319	common	mbind			sys_mbind
+320	common	get_mempolicy		sys_get_mempolicy
+321	common	set_mempolicy		sys_set_mempolicy
+322	common	openat			sys_openat
+323	common	mkdirat			sys_mkdirat
+324	common	mknodat			sys_mknodat
+325	common	fchownat		sys_fchownat
+326	common	futimesat		sys_futimesat_time32
+327	common	fstatat64		sys_fstatat64		sys_oabi_fstatat64
+328	common	unlinkat		sys_unlinkat
+329	common	renameat		sys_renameat
+330	common	linkat			sys_linkat
+331	common	symlinkat		sys_symlinkat
+332	common	readlinkat		sys_readlinkat
+333	common	fchmodat		sys_fchmodat
+334	common	faccessat		sys_faccessat
+335	common	pselect6		sys_pselect6_time32
+336	common	ppoll			sys_ppoll_time32
+337	common	unshare			sys_unshare
+338	common	set_robust_list		sys_set_robust_list
+339	common	get_robust_list		sys_get_robust_list
+340	common	splice			sys_splice
+341	common	arm_sync_file_range	sys_sync_file_range2
+342	common	tee			sys_tee
+343	common	vmsplice		sys_vmsplice
+344	common	move_pages		sys_move_pages
+345	common	getcpu			sys_getcpu
+346	common	epoll_pwait		sys_epoll_pwait
+347	common	kexec_load		sys_kexec_load
+348	common	utimensat		sys_utimensat_time32
+349	common	signalfd		sys_signalfd
+350	common	timerfd_create		sys_timerfd_create
+351	common	eventfd			sys_eventfd
+352	common	fallocate		sys_fallocate
+353	common	timerfd_settime		sys_timerfd_settime32
+354	common	timerfd_gettime		sys_timerfd_gettime32
+355	common	signalfd4		sys_signalfd4
+356	common	eventfd2		sys_eventfd2
+357	common	epoll_create1		sys_epoll_create1
+358	common	dup3			sys_dup3
+359	common	pipe2			sys_pipe2
+360	common	inotify_init1		sys_inotify_init1
+361	common	preadv			sys_preadv
+362	common	pwritev			sys_pwritev
+363	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo
+364	common	perf_event_open		sys_perf_event_open
+365	common	recvmmsg		sys_recvmmsg_time32
+366	common	accept4			sys_accept4
+367	common	fanotify_init		sys_fanotify_init
+368	common	fanotify_mark		sys_fanotify_mark
+369	common	prlimit64		sys_prlimit64
+370	common	name_to_handle_at	sys_name_to_handle_at
+371	common	open_by_handle_at	sys_open_by_handle_at
+372	common	clock_adjtime		sys_clock_adjtime32
+373	common	syncfs			sys_syncfs
+374	common	sendmmsg		sys_sendmmsg
+375	common	setns			sys_setns
+376	common	process_vm_readv	sys_process_vm_readv
+377	common	process_vm_writev	sys_process_vm_writev
+378	common	kcmp			sys_kcmp
+379	common	finit_module		sys_finit_module
+380	common	sched_setattr		sys_sched_setattr
+381	common	sched_getattr		sys_sched_getattr
+382	common	renameat2		sys_renameat2
+383	common	seccomp			sys_seccomp
+384	common	getrandom		sys_getrandom
+385	common	memfd_create		sys_memfd_create
+386	common	bpf			sys_bpf
+387	common	execveat		sys_execveat
+388	common	userfaultfd		sys_userfaultfd
+389	common	membarrier		sys_membarrier
+390	common	mlock2			sys_mlock2
+391	common	copy_file_range		sys_copy_file_range
+392	common	preadv2			sys_preadv2
+393	common	pwritev2		sys_pwritev2
+394	common	pkey_mprotect		sys_pkey_mprotect
+395	common	pkey_alloc		sys_pkey_alloc
+396	common	pkey_free		sys_pkey_free
+397	common	statx			sys_statx
+398	common	rseq			sys_rseq
+399	common	io_pgetevents		sys_io_pgetevents_time32
+400	common	migrate_pages		sys_migrate_pages
+401	common	kexec_file_load		sys_kexec_file_load
+# 402 is unused
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/arm/include/syscall_table.h b/tools/perf/arch/arm/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/arm/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 692f48db810ccbef229e240db29261f0c60db632..542f3bee1501c751a831df460c4e585ab756c8fc 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -202,6 +202,7 @@ check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscall
 check_2 tools/perf/arch/powerpc/entry/syscalls/syscall.tbl arch/powerpc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
+check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:33:03 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:33:03 -0800
Subject: [PATCH v2 13/16] perf tools: mips: Use generic syscall scripts
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-13-f8ca984ffe40@rivosinc.com>

Use the generic scripts to generate headers from the syscall table for
mips.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  5 ++--
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/mips/entry/syscalls/Kbuild         |  2 ++
 .../arch/mips/entry/syscalls/Makefile.syscalls     |  5 ++++
 tools/perf/arch/mips/entry/syscalls/mksyscalltbl   | 32 ----------------------
 tools/perf/arch/mips/include/syscall_table.h       |  2 ++
 tools/perf/util/syscalltbl.c                       |  4 ---
 7 files changed, 12 insertions(+), 40 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 84ed266ce54f5291af5c59c02ccb06bfe17d840f..09c4bb713648a9ca3c5223910bd7634fe8234e52 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390))
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
@@ -83,7 +83,6 @@ ifeq ($(ARCH),s390)
 endif
 
 ifeq ($(ARCH),mips)
-  CFLAGS += -I$(OUTPUT)arch/mips/include/generated
   LIBUNWIND_LIBS = -lunwind -lunwind-mips
 endif
 
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 7fefeea1799231af61e77c9372318e025bed078a..b5a5f04a373e174269fe5ae8a7e8707e0b7e5835 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/mips/entry/syscalls/Kbuild b/tools/perf/arch/mips/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/mips/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls b/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..9ee914bdfb05860fdd37a49f1ced03fcf2c9ed78
--- /dev/null
+++ b/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 += n64
+
+syscalltbl = $(srctree)/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
diff --git a/tools/perf/arch/mips/entry/syscalls/mksyscalltbl b/tools/perf/arch/mips/entry/syscalls/mksyscalltbl
deleted file mode 100644
index c0d93f959c4e1b8c12edcb5624bbc131231df7e3..0000000000000000000000000000000000000000
--- a/tools/perf/arch/mips/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# s390 script.
-#
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Tiezhu Yang <yangtiezhu at loongson.cn>
-
-SYSCALL_TBL=$1
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local max_nr nr abi sc discard
-
-	echo 'static const char *const syscalltbl_mips_n64[] = {'
-	while read nr abi sc discard; do
-		printf '\t[%d] = "%s",\n' $nr $sc
-		max_nr=$nr
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_MIPS_N64_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(n64)" $SYSCALL_TBL	\
-	|sort -k1 -n					\
-	|create_table
diff --git a/tools/perf/arch/mips/include/syscall_table.h b/tools/perf/arch/mips/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..b53e31c15805319a01719c22d489c4037378b02b
--- /dev/null
+++ b/tools/perf/arch/mips/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 3001386e13a502be5279aa6e4742af0b96202b35..675702d686d0d1b53dd3ee2017cc9695686b9c63 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -26,10 +26,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
 #include <asm/syscalls_32.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
-#elif defined(__mips__)
-#include <asm/syscalls_n64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_mips_n64;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:33:06 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:33:06 -0800
Subject: [PATCH v2 16/16] perf tools: Remove dependency on libaudit
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-16-f8ca984ffe40@rivosinc.com>

All architectures now support HAVE_SYSCALL_TABLE_SUPPORT, so the flag is
no longer needed. With the removal of the flag, the related
GENERIC_SYSCALL_TABLE can also be removed. libaudit was only used as a
fallback for when HAVE_SYSCALL_TABLE_SUPPORT was not defined, so
libaudit is also no longer needed for any architecture.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 Documentation/admin-guide/workload-tracing.rst |  2 +-
 tools/build/feature/Makefile                   |  4 --
 tools/build/feature/test-libaudit.c            | 11 ------
 tools/perf/Documentation/perf-check.txt        |  1 -
 tools/perf/Makefile.config                     | 31 +--------------
 tools/perf/Makefile.perf                       | 14 -------
 tools/perf/builtin-check.c                     |  1 -
 tools/perf/builtin-help.c                      |  2 -
 tools/perf/builtin-trace.c                     | 30 ---------------
 tools/perf/perf.c                              |  6 +--
 tools/perf/tests/make                          |  7 +---
 tools/perf/util/env.c                          |  4 +-
 tools/perf/util/generate-cmdlist.sh            |  4 +-
 tools/perf/util/syscalltbl.c                   | 53 --------------------------
 14 files changed, 10 insertions(+), 160 deletions(-)

diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
index b2e254ec8ee846afe78eede74a825b51c6ab119b..6be38c1b9c5bb4be899fd261c6d2911abcf959dc 100644
--- a/Documentation/admin-guide/workload-tracing.rst
+++ b/Documentation/admin-guide/workload-tracing.rst
@@ -83,7 +83,7 @@ scripts/ver_linux is a good way to check if your system already has
 the necessary tools::
 
   sudo apt-get build-essentials flex bison yacc
-  sudo apt install libelf-dev systemtap-sdt-dev libaudit-dev libslang2-dev libperl-dev libdw-dev
+  sudo apt install libelf-dev systemtap-sdt-dev libslang2-dev libperl-dev libdw-dev
 
 cscope is a good tool to browse kernel sources. Let's install it now::
 
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 043dfd00fce72d8f651ccd9b3265a0183f500e5c..e0b63e9d0251abe6d5eafc6d2f26b940918b16ee 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -13,7 +13,6 @@ FILES=                                          \
          test-gtk2.bin                          \
          test-gtk2-infobar.bin                  \
          test-hello.bin                         \
-         test-libaudit.bin                      \
          test-libbfd.bin                        \
          test-libbfd-buildid.bin		\
          test-disassembler-four-args.bin        \
@@ -228,9 +227,6 @@ $(OUTPUT)test-libunwind-debug-frame-arm.bin:
 $(OUTPUT)test-libunwind-debug-frame-aarch64.bin:
 	$(BUILD) -lelf -llzma -lunwind-aarch64
 
-$(OUTPUT)test-libaudit.bin:
-	$(BUILD) -laudit
-
 $(OUTPUT)test-libslang.bin:
 	$(BUILD) -lslang
 
diff --git a/tools/build/feature/test-libaudit.c b/tools/build/feature/test-libaudit.c
deleted file mode 100644
index f5b0863fa1ec240795339428d8deed98a946d405..0000000000000000000000000000000000000000
--- a/tools/build/feature/test-libaudit.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <libaudit.h>
-
-extern int printf(const char *format, ...);
-
-int main(void)
-{
-	printf("error message: %s\n", audit_errno_to_name(0));
-
-	return audit_open();
-}
diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt
index 31741499e7867c9b712227f31a2958fd641d474a..e6d2ceeb2ca7de850f41b1baa0375b6f984bb08f 100644
--- a/tools/perf/Documentation/perf-check.txt
+++ b/tools/perf/Documentation/perf-check.txt
@@ -51,7 +51,6 @@ feature::
                 dwarf_getlocations      /  HAVE_LIBDW_SUPPORT
                 dwarf-unwind            /  HAVE_DWARF_UNWIND_SUPPORT
                 auxtrace                /  HAVE_AUXTRACE_SUPPORT
-                libaudit                /  HAVE_LIBAUDIT_SUPPORT
                 libbfd                  /  HAVE_LIBBFD_SUPPORT
                 libcapstone             /  HAVE_LIBCAPSTONE_SUPPORT
                 libcrypto               /  HAVE_LIBCRYPTO_SUPPORT
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index c62622b4eb3dcbdfbd49ad371f15b92bfa4a6c43..732961687177da414fb250dc1f6815d186a2343f 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -28,20 +28,7 @@ include $(srctree)/tools/scripts/Makefile.arch
 
 $(call detected_var,SRCARCH)
 
-ifneq ($(NO_SYSCALL_TABLE),1)
-  NO_SYSCALL_TABLE := 1
-
-  # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390))
-    NO_SYSCALL_TABLE := 0
-    CFLAGS += -DGENERIC_SYSCALL_TABLE
-    CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
-  endif
-
-  ifneq ($(NO_SYSCALL_TABLE),1)
-    CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
-  endif
-endif
+CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
 
 # Additional ARCH settings for ppc
 ifeq ($(SRCARCH),powerpc)
@@ -755,21 +742,7 @@ ifndef NO_LIBUNWIND
 endif
 
 ifneq ($(NO_LIBTRACEEVENT),1)
-  ifeq ($(NO_SYSCALL_TABLE),0)
-    $(call detected,CONFIG_TRACE)
-  else
-    ifndef NO_LIBAUDIT
-      $(call feature_check,libaudit)
-      ifneq ($(feature-libaudit), 1)
-        $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev)
-        NO_LIBAUDIT := 1
-      else
-        CFLAGS += -DHAVE_LIBAUDIT_SUPPORT
-        EXTLIBS += -laudit
-        $(call detected,CONFIG_TRACE)
-      endif
-    endif
-  endif
+  $(call detected,CONFIG_TRACE)
 endif
 
 ifndef NO_LIBCRYPTO
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 1f3262c1f9d44261be0315c693837cfdfb3071de..ab2d075ff3a23350a5eea12508cf0376f1d9f4e8 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -59,8 +59,6 @@ include ../scripts/utilities.mak
 #
 # Define NO_LIBNUMA if you do not want numa perf benchmark
 #
-# Define NO_LIBAUDIT if you do not want libaudit support
-#
 # Define NO_LIBBIONIC if you do not want bionic support
 #
 # Define NO_LIBCRYPTO if you do not want libcrypto (openssl) support
@@ -119,10 +117,6 @@ include ../scripts/utilities.mak
 #
 # Define LIBBPF_DYNAMIC to enable libbpf dynamic linking.
 #
-# Define NO_SYSCALL_TABLE=1 to disable the use of syscall id to/from name tables
-# generated from the kernel .tbl or unistd.h files and use, if available, libaudit
-# for doing the conversions to/from strings/id.
-#
 # Define NO_LIBPFM4 to disable libpfm4 events extension.
 #
 # Define NO_LIBDEBUGINFOD if you do not want support debuginfod
@@ -310,10 +304,7 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
 FEATURE_TESTS := all
 endif
 endif
-# architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
-endif
 include Makefile.config
 endif
 
@@ -1098,11 +1089,6 @@ endif
 		$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 	$(call QUIET_INSTALL, perf-iostat) \
 		$(INSTALL) $(OUTPUT)perf-iostat -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
-ifndef NO_LIBAUDIT
-	$(call QUIET_INSTALL, strace/groups) \
-		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'; \
-		$(INSTALL) trace/strace/groups/* -m 644 -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'
-endif
 ifndef NO_LIBPERL
 	$(call QUIET_INSTALL, perl-scripts) \
 		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
index 2346536a5ee14f91ecd10bd130a64676e871e1b2..7aed7b9f4f5270527ee1d36327eb6a01f196a46a 100644
--- a/tools/perf/builtin-check.c
+++ b/tools/perf/builtin-check.c
@@ -31,7 +31,6 @@ struct feature_status supported_features[] = {
 	FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT),
 	FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT),
 	FEATURE_STATUS("auxtrace", HAVE_AUXTRACE_SUPPORT),
-	FEATURE_STATUS("libaudit", HAVE_LIBAUDIT_SUPPORT),
 	FEATURE_STATUS("libbfd", HAVE_LIBBFD_SUPPORT),
 	FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT),
 	FEATURE_STATUS("libcrypto", HAVE_LIBCRYPTO_SUPPORT),
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 0854d3cd9f6a304cd9cb50ad430d5706d91df0e9..7be6fb6df595923c15ae51747d5bf17d867ae785 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -447,9 +447,7 @@ int cmd_help(int argc, const char **argv)
 #ifdef HAVE_LIBELF_SUPPORT
 		"probe",
 #endif
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
 		"trace",
-#endif
 	NULL };
 	const char *builtin_help_usage[] = {
 		"perf help [--all] [--man|--web|--info] [command]",
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 6a1a128fe645014d0347ad4ec3e0c9e77ec59aee..0fddf34458db4fe4896d25f427f2ae29cb3aa15f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2069,30 +2069,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
 	const char *name = syscalltbl__name(trace->sctbl, id);
 	int err;
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 	if (trace->syscalls.table == NULL) {
 		trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc));
 		if (trace->syscalls.table == NULL)
 			return -ENOMEM;
 	}
-#else
-	if (id > trace->sctbl->syscalls.max_id || (id == 0 && trace->syscalls.table == NULL)) {
-		// When using libaudit we don't know beforehand what is the max syscall id
-		struct syscall *table = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
-
-		if (table == NULL)
-			return -ENOMEM;
-
-		// Need to memset from offset 0 and +1 members if brand new
-		if (trace->syscalls.table == NULL)
-			memset(table, 0, (id + 1) * sizeof(*sc));
-		else
-			memset(table + trace->sctbl->syscalls.max_id + 1, 0, (id - trace->sctbl->syscalls.max_id) * sizeof(*sc));
-
-		trace->syscalls.table	      = table;
-		trace->sctbl->syscalls.max_id = id;
-	}
-#endif
 	sc = trace->syscalls.table + id;
 	if (sc->nonexistent)
 		return -EEXIST;
@@ -2439,18 +2420,7 @@ static struct syscall *trace__syscall_info(struct trace *trace,
 
 	err = -EINVAL;
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 	if (id > trace->sctbl->syscalls.max_id) {
-#else
-	if (id >= trace->sctbl->syscalls.max_id) {
-		/*
-		 * With libaudit we don't know beforehand what is the max_id,
-		 * so we let trace__read_syscall_info() figure that out as we
-		 * go on reading syscalls.
-		 */
-		err = trace__read_syscall_info(trace, id);
-		if (err)
-#endif
 		goto out_cant_read;
 	}
 
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index a2987f2cfe1a3958f53239ed1a4eec3f87d7466a..f0617cc41f5fe638986e5d8316a6b3056c2c4bc5 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -84,7 +84,7 @@ static struct cmd_struct commands[] = {
 #endif
 	{ "kvm",	cmd_kvm,	0 },
 	{ "test",	cmd_test,	0 },
-#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))
+#if defined(HAVE_LIBTRACEEVENT)
 	{ "trace",	cmd_trace,	0 },
 #endif
 	{ "inject",	cmd_inject,	0 },
@@ -514,10 +514,6 @@ int main(int argc, const char **argv)
 		fprintf(stderr,
 			"trace command not available: missing libtraceevent devel package at build time.\n");
 		goto out;
-#elif !defined(HAVE_LIBAUDIT_SUPPORT) && !defined(HAVE_SYSCALL_TABLE_SUPPORT)
-		fprintf(stderr,
-			"trace command not available: missing audit-libs devel package at build time.\n");
-		goto out;
 #else
 		setup_path();
 		argv[0] = "trace";
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index a7fcbd589752a90459815bd21075528c6dfa4d94..0ee94caf9ec19820a94a87dd46a7ccf1cefb844a 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -86,7 +86,6 @@ make_no_libdw_dwarf_unwind := NO_LIBDW_DWARF_UNWIND=1
 make_no_backtrace   := NO_BACKTRACE=1
 make_no_libcapstone := NO_CAPSTONE=1
 make_no_libnuma     := NO_LIBNUMA=1
-make_no_libaudit    := NO_LIBAUDIT=1
 make_no_libbionic   := NO_LIBBIONIC=1
 make_no_auxtrace    := NO_AUXTRACE=1
 make_no_libbpf	    := NO_LIBBPF=1
@@ -97,7 +96,6 @@ make_no_libllvm     := NO_LIBLLVM=1
 make_with_babeltrace:= LIBBABELTRACE=1
 make_with_coresight := CORESIGHT=1
 make_no_sdt	    := NO_SDT=1
-make_no_syscall_tbl := NO_SYSCALL_TABLE=1
 make_no_libpfm4     := NO_LIBPFM4=1
 make_with_gtk2      := GTK2=1
 make_refcnt_check   := EXTRA_CFLAGS="-DREFCNT_CHECKING=1"
@@ -122,10 +120,10 @@ make_static         := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX3
 # all the NO_* variable combined
 make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_GTK2=1
 make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_BACKTRACE=1
-make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
+make_minimal        += NO_LIBNUMA=1 NO_LIBBIONIC=1
 make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
 make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
-make_minimal        += NO_LIBCAP=1 NO_SYSCALL_TABLE=1 NO_CAPSTONE=1
+make_minimal        += NO_LIBCAP=1 NO_CAPSTONE=1
 
 # $(run) contains all available tests
 run := make_pure
@@ -158,7 +156,6 @@ run += make_no_libdw_dwarf_unwind
 run += make_no_backtrace
 run += make_no_libcapstone
 run += make_no_libnuma
-run += make_no_libaudit
 run += make_no_libbionic
 run += make_no_auxtrace
 run += make_no_libbpf
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index e2843ca2edd92ea5fa1c020ae92b183c496e975e..e9a694350671910d537de599071dbe7fcc18ced4 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -474,13 +474,13 @@ const char *perf_env__arch(struct perf_env *env)
 
 const char *perf_env__arch_strerrno(struct perf_env *env __maybe_unused, int err __maybe_unused)
 {
-#if defined(HAVE_SYSCALL_TABLE_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#if defined(HAVE_LIBTRACEEVENT)
 	if (env->arch_strerrno == NULL)
 		env->arch_strerrno = arch_syscalls__strerrno_function(perf_env__arch(env));
 
 	return env->arch_strerrno ? env->arch_strerrno(err) : "no arch specific strerrno function";
 #else
-	return "!(HAVE_SYSCALL_TABLE_SUPPORT && HAVE_LIBTRACEEVENT)";
+	return "!HAVE_LIBTRACEEVENT";
 #endif
 }
 
diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh
index 1b5140e5ce9975fac87b2674dc694f9d4e439a5f..6a73c903d69050df69267a8aeaeeac1ed170efe1 100755
--- a/tools/perf/util/generate-cmdlist.sh
+++ b/tools/perf/util/generate-cmdlist.sh
@@ -38,7 +38,7 @@ do
 done
 echo "#endif /* HAVE_LIBELF_SUPPORT */"
 
-echo "#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))"
+echo "#if defined(HAVE_LIBTRACEEVENT)"
 sed -n -e 's/^perf-\([^ 	]*\)[ 	].* audit*/\1/p' command-list.txt |
 sort |
 while read cmd
@@ -51,7 +51,7 @@ do
 	    p
      }' "Documentation/perf-$cmd.txt"
 done
-echo "#endif /* HAVE_LIBTRACEEVENT && (HAVE_LIBAUDIT_SUPPORT || HAVE_SYSCALL_TABLE_SUPPORT) */"
+echo "#endif /* HAVE_LIBTRACEEVENT */"
 
 echo "#ifdef HAVE_LIBTRACEEVENT"
 sed -n -e 's/^perf-\([^ 	]*\)[ 	].* traceevent.*/\1/p' command-list.txt |
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 210f61b0a7a264a427ebb602185d3a9da2f426f4..7e24e4164da9c7d60352b77b5724e6e8dac034f4 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -9,21 +9,12 @@
 #include <stdlib.h>
 #include <linux/compiler.h>
 #include <linux/zalloc.h>
-
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 #include <string.h>
 #include "string2.h"
 
-#if defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl;
-#else
-const int syscalltbl_native_max_id = 0;
-static const char *const syscalltbl_native[] = {
-	[0] = "unknown",
-};
-#endif
 
 struct syscall {
 	int id;
@@ -131,47 +122,3 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
 	*idx = -1;
 	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 }
-
-#else /* HAVE_SYSCALL_TABLE_SUPPORT */
-
-#include <libaudit.h>
-
-struct syscalltbl *syscalltbl__new(void)
-{
-	struct syscalltbl *tbl = zalloc(sizeof(*tbl));
-	if (tbl)
-		tbl->audit_machine = audit_detect_machine();
-	return tbl;
-}
-
-void syscalltbl__delete(struct syscalltbl *tbl)
-{
-	free(tbl);
-}
-
-const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
-{
-	return audit_syscall_to_name(id, tbl->audit_machine);
-}
-
-int syscalltbl__id(struct syscalltbl *tbl, const char *name)
-{
-	return audit_name_to_syscall(name, tbl->audit_machine);
-}
-
-int syscalltbl__id_at_idx(struct syscalltbl *tbl __maybe_unused, int idx)
-{
-	return idx;
-}
-
-int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
-				  const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
-{
-	return -1;
-}
-
-int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
-{
-	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
-}
-#endif /* HAVE_SYSCALL_TABLE_SUPPORT */

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:33:04 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:33:04 -0800
Subject: [PATCH v2 14/16] perf tools: powerpc: Use generic syscall table
 scripts
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-14-f8ca984ffe40@rivosinc.com>

Use the generic scripts to generate headers from the syscall table
instead of the custom ones for powerpc.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  5 ++-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/powerpc/Makefile                   | 25 --------------
 tools/perf/arch/powerpc/entry/syscalls/Kbuild      |  3 ++
 .../arch/powerpc/entry/syscalls/Makefile.syscalls  |  6 ++++
 .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  | 39 ----------------------
 tools/perf/arch/powerpc/include/syscall_table.h    |  8 +++++
 tools/perf/util/syscalltbl.c                       |  8 -----
 8 files changed, 20 insertions(+), 76 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 09c4bb713648a9ca3c5223910bd7634fe8234e52..1ca8c9814cbffbc4bbed3b40e0d6e53f0f9b77f1 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390))
+  ifeq ($(SRCARCH),s390)
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
@@ -49,7 +49,6 @@ endif
 
 # Additional ARCH settings for ppc
 ifeq ($(SRCARCH),powerpc)
-  CFLAGS += -I$(OUTPUT)arch/powerpc/include/generated
   LIBUNWIND_LIBS := -lunwind -lunwind-ppc64
 endif
 
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index b5a5f04a373e174269fe5ae8a7e8707e0b7e5835..45bccc88e0087b57e4d9549e281cdbafc152a2fd 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index dc8f4fb8e324ab6679d78b5fee3636ba7d2ff7c0..a295a80ea078199547e816d18531820bfdba7961 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -1,28 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/powerpc/include/generated/asm
-header32 := $(out)/syscalls_32.c
-header64 := $(out)/syscalls_64.c
-sysprf := $(srctree)/tools/perf/arch/powerpc/entry/syscalls
-sysdef := $(sysprf)/syscall.tbl
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header64): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '64' $(sysdef) > $@
-
-$(header32): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '32' $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, powerpc) $(RM) $(header32) $(header64)
-
-archheaders: $(header32) $(header64)
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Kbuild b/tools/perf/arch/powerpc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/powerpc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..f7e87a61401c14a1d3a8a04fe2c8ecc8bedcc1b0
--- /dev/null
+++ b/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += spu nospu
+syscall_abis_64 += spu nospu
+
+syscalltbl = $(srctree)/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl b/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 0eb316fe6dd1175a86035f76f9f3cf7501c376bd..0000000000000000000000000000000000000000
--- a/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# s390 script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-
-wordsize=$1
-SYSCALL_TBL=$2
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local wordsize=$1
-	local max_nr nr abi sc discard
-	max_nr=-1
-	nr=0
-
-	echo "static const char *const syscalltbl_powerpc_${wordsize}[] = {"
-	while read nr abi sc discard; do
-		if [ "$max_nr" -lt "$nr" ]; then
-			printf '\t[%d] = "%s",\n' $nr $sc
-			max_nr=$nr
-		fi
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_POWERPC_${wordsize}_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(common|spu|nospu|${wordsize})" $SYSCALL_TBL \
-	|sort -k1 -n                                                           \
-	|create_table ${wordsize}
diff --git a/tools/perf/arch/powerpc/include/syscall_table.h b/tools/perf/arch/powerpc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/powerpc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 675702d686d0d1b53dd3ee2017cc9695686b9c63..8869fed1a58946c590484816354d8c74aff52ee3 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -18,14 +18,6 @@
 #include <asm/syscalls_64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_s390_64;
-#elif defined(__powerpc64__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
-#elif defined(__powerpc__)
-#include <asm/syscalls_32.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Thu Dec 12 16:33:05 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 12 Dec 2024 16:33:05 -0800
Subject: [PATCH v2 15/16] perf tools: s390: Use generic syscall table
 scripts
In-Reply-To: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
Message-ID: <20241212-perf_syscalltbl-v2-15-f8ca984ffe40@rivosinc.com>

Use the generic scripts to generate headers from the syscall table
instead of the custom ones for s390.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  8 ++----
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/s390/Makefile                      | 21 --------------
 tools/perf/arch/s390/entry/syscalls/Kbuild         |  2 ++
 .../arch/s390/entry/syscalls/Makefile.syscalls     |  5 ++++
 tools/perf/arch/s390/entry/syscalls/mksyscalltbl   | 32 ----------------------
 tools/perf/arch/s390/include/syscall_table.h       |  2 ++
 tools/perf/util/syscalltbl.c                       |  6 +---
 8 files changed, 13 insertions(+), 65 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 1ca8c9814cbffbc4bbed3b40e0d6e53f0f9b77f1..c62622b4eb3dcbdfbd49ad371f15b92bfa4a6c43 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,8 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),s390)
-    NO_SYSCALL_TABLE := 0
-  endif
-
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
@@ -78,7 +74,7 @@ ifeq ($(SRCARCH),loongarch)
 endif
 
 ifeq ($(ARCH),s390)
-  CFLAGS += -fPIC -I$(OUTPUT)arch/s390/include/generated
+  CFLAGS += -fPIC
 endif
 
 ifeq ($(ARCH),mips)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 45bccc88e0087b57e4d9549e281cdbafc152a2fd..1f3262c1f9d44261be0315c693837cfdfb3071de 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
index c431c21b11ef824535c1b9fb6ca4246d666fc97b..0033698a65ce5d5d7ebcc280399957561dd9d2c6 100644
--- a/tools/perf/arch/s390/Makefile
+++ b/tools/perf/arch/s390/Makefile
@@ -1,24 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/s390/include/generated/asm
-header := $(out)/syscalls_64.c
-sysprf := $(srctree)/tools/perf/arch/s390/entry/syscalls
-sysdef := $(sysprf)/syscall.tbl
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, s390) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/s390/entry/syscalls/Kbuild b/tools/perf/arch/s390/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/s390/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls b/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..9762d7abf17c3f79a6213e7306a5f7b56e833a78
--- /dev/null
+++ b/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 += renameat rlimit memfd_secret
+
+syscalltbl = $(srctree)/tools/perf/arch/s390/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl b/tools/perf/arch/s390/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 52eb88a77c94727aeb8c15427cdd43dfe5f9f2bd..0000000000000000000000000000000000000000
--- a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf
-#
-# Copyright IBM Corp. 2017, 2018
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-#
-
-SYSCALL_TBL=$1
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local max_nr nr abi sc discard
-
-	echo 'static const char *const syscalltbl_s390_64[] = {'
-	while read nr abi sc discard; do
-		printf '\t[%d] = "%s",\n' $nr $sc
-		max_nr=$nr
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_S390_64_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(common|64)" $SYSCALL_TBL	\
-	|sort -k1 -n					\
-	|create_table
diff --git a/tools/perf/arch/s390/include/syscall_table.h b/tools/perf/arch/s390/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..b53e31c15805319a01719c22d489c4037378b02b
--- /dev/null
+++ b/tools/perf/arch/s390/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 8869fed1a58946c590484816354d8c74aff52ee3..210f61b0a7a264a427ebb602185d3a9da2f426f4 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -14,11 +14,7 @@
 #include <string.h>
 #include "string2.h"
 
-#if defined(__s390x__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_s390_64;
-#elif defined(GENERIC_SYSCALL_TABLE)
+#if defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl;

-- 
2.34.1



From kuninori.morimoto.gx at renesas.com  Thu Dec 12 16:40:11 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Fri, 13 Dec 2024 00:40:11 +0000
Subject: [PATCH v2 3/5] ASoC: dt-bindings: audio-graph-card2: add widgets and hp-det-gpios support
In-Reply-To: <1fc1f1ae-766d-4266-84ec-11dbd67a608a@gmail.com>
References: <20241113195240.3699-1-laurentiumihalcea111@gmail.com>
	<20241113195240.3699-4-laurentiumihalcea111@gmail.com>
	<ZzUH3n50Vw6RhmNJ@lizhi-Precision-Tower-5810>
	<1fc1f1ae-766d-4266-84ec-11dbd67a608a@gmail.com>
Message-ID: <87cyhw8lg5.wl-kuninori.morimoto.gx@renesas.com>


Hi

> >> diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml
> >> index f943f90d8b15..94588353f852 100644
> >> --- a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml
> >> +++ b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml
> >> @@ -37,6 +37,10 @@ properties:
> >>    codec2codec:
> >>      type: object
> >>      description: Codec to Codec node
> >> +  hp-det-gpios:
> >> +    $ref: audio-graph.yaml#/properties/hp-det-gpios
> >> +  widgets:
> >> +    $ref: audio-graph.yaml#/properties/widgets
>
> > why not direct ref Documentation/devicetree/bindings/sound/audio-graph.yaml
> > and define these again here.
>
> We don't actually want all the properties from 'audio-graph.yaml'
> (for the moment at least). Also ref-ing 'audio-graph.yaml' will make the
> 'dais' property required, which is not targeted in this patch.
> Maybe Kuninori Morimoto can comment more on this.

I'm not a DT yaml expert, but audio-graph.yaml is for audio-graph-card and
its custom card. unfortunately audio-graph-card2 is using different style,
so ref audio-graph.yaml on audio-graph-card2 is impossible, or makes yaml
more complex.

Thank you for your help !!

Best regards
---
Kuninori Morimoto


From zmw12306 at gmail.com  Thu Dec 12 17:09:48 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Thu, 12 Dec 2024 20:09:48 -0500
Subject: [PATCH v4] pinctrl: stm32: Add check for clk_enable()
Message-ID: <20241213010948.2623382-1-zmw12306@gmail.com>

Convert the driver to clk_bulk*() API.
Add check for the return value of clk_bulk_enable() to catch
the potential error.

Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
Changelog:

v3 -> v4:
1. Add initialization for  pctl->clks.
2. Adjust alignment.

v2 -> v3:

1. Convert clk_disable_unprepare to clk_bulk_disable
and clk_bulk_unprepare.

v1 -> v2:

1. Move int ret declaration into if block.
---
 drivers/pinctrl/stm32/pinctrl-stm32.c | 37 +++++++++++++++------------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index 5b7fa77c1184..427749d4f6a5 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -86,7 +86,6 @@ struct stm32_pinctrl_group {
 
 struct stm32_gpio_bank {
 	void __iomem *base;
-	struct clk *clk;
 	struct reset_control *rstc;
 	spinlock_t lock;
 	struct gpio_chip gpio_chip;
@@ -108,6 +107,7 @@ struct stm32_pinctrl {
 	unsigned ngroups;
 	const char **grp_names;
 	struct stm32_gpio_bank *banks;
+	struct clk_bulk_data *clks;
 	unsigned nbanks;
 	const struct stm32_pinctrl_match_data *match_data;
 	struct irq_domain	*domain;
@@ -1308,7 +1308,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	if (IS_ERR(bank->base))
 		return PTR_ERR(bank->base);
 
-	err = clk_prepare_enable(bank->clk);
+	err = clk_prepare_enable(pctl->clks[pctl->nbanks].clk);
 	if (err) {
 		dev_err(dev, "failed to prepare_enable clk (%d)\n", err);
 		return err;
@@ -1397,7 +1397,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	return 0;
 
 err_clk:
-	clk_disable_unprepare(bank->clk);
+	clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);
 	return err;
 }
 
@@ -1617,10 +1617,18 @@ int stm32_pctl_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 	pctl->banks = devm_kcalloc(dev, banks, sizeof(*pctl->banks),
-			GFP_KERNEL);
+				   GFP_KERNEL);
 	if (!pctl->banks)
 		return -ENOMEM;
 
+	pctl->clks = devm_kcalloc(dev, banks, sizeof(*pctl->clks),
+				  GFP_KERNEL);
+	if (!pctl->clks)
+		return -ENOMEM;
+
+	for (i = 0; i < banks; ++i)
+		pctl->clks[i].id = "";
+
 	i = 0;
 	for_each_gpiochip_node(dev, child) {
 		struct stm32_gpio_bank *bank = &pctl->banks[i];
@@ -1631,11 +1639,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
 			fwnode_handle_put(child);
 			return -EPROBE_DEFER;
 		}
-
-		bank->clk = of_clk_get_by_name(np, NULL);
-		if (IS_ERR(bank->clk)) {
+		pctl->clks[i].clk = of_clk_get_by_name(np, NULL);
+		if (IS_ERR(pctl->clks[i].clk)) {
 			fwnode_handle_put(child);
-			return dev_err_probe(dev, PTR_ERR(bank->clk),
+			return dev_err_probe(dev, PTR_ERR(pctl->clks[i].clk),
 					     "failed to get clk\n");
 		}
 		i++;
@@ -1646,8 +1653,7 @@ int stm32_pctl_probe(struct platform_device *pdev)
 		if (ret) {
 			fwnode_handle_put(child);
 
-			for (i = 0; i < pctl->nbanks; i++)
-				clk_disable_unprepare(pctl->banks[i].clk);
+			clk_bulk_disable_unprepare(pctl->nbanks, pctl->clks);
 
 			return ret;
 		}
@@ -1726,10 +1732,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
 int __maybe_unused stm32_pinctrl_suspend(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
-	int i;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_disable(pctl->banks[i].clk);
+	clk_bulk_disable(pctl->nbanks, pctl->clks);
 
 	return 0;
 }
@@ -1738,10 +1742,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
 	struct stm32_pinctrl_group *g = pctl->groups;
-	int i;
+	int i, ret;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_enable(pctl->banks[i].clk);
+	ret = clk_bulk_enable(pctl->nbanks, pctl->clks);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < pctl->ngroups; i++, g++)
 		stm32_pinctrl_restore_gpio_regs(pctl, g->pin);
-- 
2.34.1



From zmw12306 at gmail.com  Thu Dec 12 17:11:37 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Thu, 12 Dec 2024 20:11:37 -0500
Subject: [Linux-stm32] [PATCH v3] pinctrl: stm32: Add check for clk_enable()
In-Reply-To: <21f4927382a3cf3bb433bc1f1d7d4ad9ea1a2a5e.camel@foss.st.com>
References: <20241206214315.3385033-1-zmw12306@gmail.com> <21f4927382a3cf3bb433bc1f1d7d4ad9ea1a2a5e.camel@foss.st.com>
Message-ID: <CAN4iqtTcdZ8tqwPx=WeG6j6k17OHF3rj_YcXUgJAwseoTUKDeQ@mail.gmail.com>

Hi Antonio,

On Sat, Dec 7, 2024 at 9:25?AM Antonio Borneo
<antonio.borneo at foss.st.com> wrote:
>
> On Fri, 2024-12-06 at 16:43 -0500, Mingwei Zheng wrote:
> > Convert the driver to clk_bulk*() API.
> > Add check for the return value of clk_bulk_enable() to catch
> > the potential error.
> >
> > Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
> > Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> > Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
> > ---
> > Changelog:
> >
> > v2 -> v3:
> >
> > 1. Convert clk_disable_unprepare to clk_bulk_disable
> > and clk_bulk_unprepare.
> >
> > v1 -> v2:
> >
> > 1. Move int ret declaration into if block.
> > ---
> >  drivers/pinctrl/stm32/pinctrl-stm32.c | 28 +++++++++++++--------------
> >  1 file changed, 13 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
> > index 5b7fa77c1184..0ef912e82736 100644
> > --- a/drivers/pinctrl/stm32/pinctrl-stm32.c
> > +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
> > @@ -86,7 +86,6 @@ struct stm32_pinctrl_group {
> >
> >  struct stm32_gpio_bank {
> >         void __iomem *base;
> > -       struct clk *clk;
> >         struct reset_control *rstc;
> >         spinlock_t lock;
> >         struct gpio_chip gpio_chip;
> > @@ -108,6 +107,7 @@ struct stm32_pinctrl {
> >         unsigned ngroups;
> >         const char **grp_names;
> >         struct stm32_gpio_bank *banks;
>
> Thanks for your patch!
> While it's growing wider than your initial scope, it looks as a nice improvement.
>
> > +       struct clk_bulk_data *clks;
>
> Maybe I've missed it but, where does this array get allocated?
> There exist clk_bulk_get_all() and devm_clk_bulk_get_all() that do the allocation for you, but they require all the clocks to be listed in the same "clocks" property, while this driver has a clock in
> each DT subnode!
> Some suggestion below.
>
> >         unsigned nbanks;
> >         const struct stm32_pinctrl_match_data *match_data;
> >         struct irq_domain       *domain;
> > @@ -1308,7 +1308,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
> >         if (IS_ERR(bank->base))
> >                 return PTR_ERR(bank->base);
> >
> > -       err = clk_prepare_enable(bank->clk);
> > +       err = clk_prepare_enable(pctl->clks[pctl->nbanks].clk);
> >         if (err) {
> >                 dev_err(dev, "failed to prepare_enable clk (%d)\n", err);
> >                 return err;
> > @@ -1397,7 +1397,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
> >         return 0;
> >
> >  err_clk:
> > -       clk_disable_unprepare(bank->clk);
> > +       clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);
> >         return err;
> >  }
> >
> > @@ -1631,11 +1631,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
> >                         fwnode_handle_put(child);
> >                         return -EPROBE_DEFER;
> >                 }
> > -
> > -               bank->clk = of_clk_get_by_name(np, NULL);
> > -               if (IS_ERR(bank->clk)) {
> > +               pctl->clks[i].clk = of_clk_get_by_name(np, NULL);
>
> This is the first time the array is used, during stm32_pctl_probe(), so the array should be already allocated before this line.
> The number of banks pctl->nbanks is computed few lines below, so it should be anticipated, or being replaced by a simpler
>   pctl->nbanks = gpiochip_node_count(dev);
>
> then allocation could be done with
>   pctl->clks = devm_kmalloc_array(dev, pctl->nbanks, sizeof(*pctl->clks), GFP_KERNEL);
>
> Also, you never assign `pctl->clks[i].id` which is then used by the error messages in, e.g., clk_bulk_enable().
> We don't mandate the property "clock-names" in the DT subnodes, so no way to get a reasonable value from the DT.
> I presume it's fine to set it to NULL... to be tested.
>
> Regards,
> Antonio
>
>

Thanks for your suggestion. We used devm_kcalloc to allocate clk. We
set `pctl->clks[i].id` to "".

Best,
Mingwei

> > +               if (IS_ERR(pctl->clks[i].clk)) {
> >                         fwnode_handle_put(child);
> > -                       return dev_err_probe(dev, PTR_ERR(bank->clk),
> > +                       return dev_err_probe(dev, PTR_ERR(pctl->clks[i].clk),
> >                                              "failed to get clk\n");
> >                 }
> >                 i++;
> > @@ -1646,8 +1645,8 @@ int stm32_pctl_probe(struct platform_device *pdev)
> >                 if (ret) {
> >                         fwnode_handle_put(child);
> >
> > -                       for (i = 0; i < pctl->nbanks; i++)
> > -                               clk_disable_unprepare(pctl->banks[i].clk);
> > +                       clk_bulk_disable(pctl->nbanks, pctl->clks);
> > +                       clk_bulk_unprepare(pctl->nbanks, pctl->clks);
> >
> >                         return ret;
> >                 }
> > @@ -1726,10 +1725,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
> >  int __maybe_unused stm32_pinctrl_suspend(struct device *dev)
> >  {
> >         struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
> > -       int i;
> >
> > -       for (i = 0; i < pctl->nbanks; i++)
> > -               clk_disable(pctl->banks[i].clk);
> > +       clk_bulk_disable(pctl->nbanks, pctl->clks);
> >
> >         return 0;
> >  }
> > @@ -1738,10 +1735,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
> >  {
> >         struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
> >         struct stm32_pinctrl_group *g = pctl->groups;
> > -       int i;
> > +       int i, ret;
> >
> > -       for (i = 0; i < pctl->nbanks; i++)
> > -               clk_enable(pctl->banks[i].clk);
> > +       ret = clk_bulk_enable(pctl->nbanks, pctl->clks);
> > +       if (ret)
> > +               return ret;
> >
> >         for (i = 0; i < pctl->ngroups; i++, g++)
> >                 stm32_pinctrl_restore_gpio_regs(pctl, g->pin);


From zmw12306 at gmail.com  Thu Dec 12 17:13:07 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Thu, 12 Dec 2024 20:13:07 -0500
Subject: [PATCH v3] pinctrl: stm32: Add check for clk_enable()
In-Reply-To: <9830993d-943b-4079-b31d-7c77ee83d306@denx.de>
References: <20241206214315.3385033-1-zmw12306@gmail.com> <9830993d-943b-4079-b31d-7c77ee83d306@denx.de>
Message-ID: <CAN4iqtRk4g2q-1c3eTjELeKTTtfcV-MU-_36QkRa76+dsE4y1A@mail.gmail.com>

Hi Marek,

On Sat, Dec 7, 2024 at 7:59?AM Marek Vasut <marex at denx.de> wrote:
>
> On 12/6/24 10:43 PM, Mingwei Zheng wrote:
>
> [...]
>
> > @@ -1646,8 +1645,8 @@ int stm32_pctl_probe(struct platform_device *pdev)
> >               if (ret) {
> >                       fwnode_handle_put(child);
> >
> > -                     for (i = 0; i < pctl->nbanks; i++)
> > -                             clk_disable_unprepare(pctl->banks[i].clk);
> > +                     clk_bulk_disable(pctl->nbanks, pctl->clks);
> > +                     clk_bulk_unprepare(pctl->nbanks, pctl->clks);
>
> Use clk_bulk_disable_unprepare()
>
> include/linux/clk.h:static inline void clk_bulk_disable_unprepare(int
> num_clks,

Thanks! We used clk_bulk_disable_unprepare() in the patch v4.

Best,
Mingwei

>
> It looks pretty good otherwise, thanks !


From linux at roeck-us.net  Thu Dec 12 17:29:51 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 12 Dec 2024 17:29:51 -0800
Subject: [PATCH v1 2/4] hwmon: (pmbus/crps) Add Intel CRPS185 power supply
In-Reply-To: <20241212214927.3586509-3-ninad@linux.ibm.com>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
 <20241212214927.3586509-3-ninad@linux.ibm.com>
Message-ID: <5b095371-f835-4c23-aa43-deefa33123bb@roeck-us.net>

On 12/12/24 13:49, Ninad Palsule wrote:
> Add the driver to monitor Intel common redundant power supply (crps185)
> with hwmon over pmbus.
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
> ---
>   Documentation/hwmon/crps.rst |  95 +++++++++++

Documentation/hwmon/index.rst needs to be updated.

>   MAINTAINERS                  |   7 +
>   drivers/hwmon/pmbus/Kconfig  |   9 ++
>   drivers/hwmon/pmbus/Makefile |   1 +
>   drivers/hwmon/pmbus/crps.c   | 299 +++++++++++++++++++++++++++++++++++
>   5 files changed, 411 insertions(+)
>   create mode 100644 Documentation/hwmon/crps.rst
>   create mode 100644 drivers/hwmon/pmbus/crps.c
> 
> diff --git a/Documentation/hwmon/crps.rst b/Documentation/hwmon/crps.rst
> new file mode 100644
> index 000000000000..81d5dfd68a46
> --- /dev/null
> +++ b/Documentation/hwmon/crps.rst
> @@ -0,0 +1,95 @@
> +.. SPDX-License-Identifier: GPL-2.0-or-later
> +
> +Kernel driver crps
> +========================

I am quite sure that this triggers a documentation warning.

> +
> +Supported chips:
> +
> +  * Intel CRPS185
> +
> +    Prefix: 'crps185'
> +
> +    Addresses scanned: -
> +
> +Authors:
> +    Ninad Palsule <ninad at linux.ibm.com>
> +
> +

Is the documentation available somewhere ?
If yes, please add a reference. If not, add a comment explaining that
it is not available to the public.

> +Description
> +-----------
> +
> +This driver implements support for Common Redundant Power supply with PMBus

For _Intel_ ...

> +support.
> +
> +The driver is a client driver to the core PMBus driver.
> +Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers.
> +
> +
> +Usage Notes
> +-----------
> +
> +This driver does not auto-detect devices. You will have to instantiate the
> +devices explicitly. Please see Documentation/i2c/instantiating-devices.rst for
> +details.
> +
> +
> +Sysfs entries
> +-------------
> +
> +======================= ======================================================
> +curr1_label		"iin"
> +curr1_input		Measured input current
> +curr1_max		Maximum input current
> +curr1_max_alarm         Input maximum current high alarm
> +curr1_crit              Critial high input current
> +curr1_crit_alarm        Input critical current high alarm
> +curr1_rated_max		Maximum rated input current
> +
> +curr2_label		"iout1"
> +curr2_input		Measured output current
> +curr2_max		Maximum output current
> +curr2_max_alarm         Output maximum current high alarm
> +curr2_crit	        Critial high output current
> +curr2_crit_alarm        Output critical current high alarm
> +curr2_rated_max		Maximum rated output current
> +
> +in1_label		"vin"
> +in1_input		Measured input voltage
> +in1_crit                Critical input over voltage
> +in1_crit_alarm          Critical input over voltage alarm
> +in1_max                 Maximum input over voltage
> +in1_max_alarm           Maximum input over voltage alarm
> +in1_rated_min		Minimum rated input voltage
> +in1_rated_max		Maximum rated input voltage
> +
> +in2_label		"vout1"
> +in2_input		Measured input voltage
> +in2_crit                Critical input over voltage
> +in2_crit_alarm          Critical input over voltage alarm
> +in2_lcrit               Critical input under voltage fault
> +in2_lcrit_alarm         Critical input under voltage fault alarm
> +in2_max                 Maximum input over voltage
> +in2_max_alarm           Maximum input over voltage alarm
> +in2_min                 Minimum input under voltage warning
> +in2_min_alarm           Minimum input under voltage warning alarm
> +in2_rated_min		Minimum rated input voltage
> +in2_rated_max		Maximum rated input voltage
> +
> +power1_label		"pin"
> +power1_input		Measured input power
> +power1_alarm		Input power high alarm
> +power1_max  		Maximum input power
> +power1_rated_max        Maximum rated input power
> +
> +temp[1-2]_input		Measured temperature
> +temp[1-2]_crit 		Critical temperature
> +temp[1-2]_crit_alarm    Critical temperature alarm
> +temp[1-2]_max  		Maximum temperature
> +temp[1-2]_max_alarm     Maximum temperature alarm
> +temp[1-2]_rated_max     Maximum rated temperature
> +
> +fan1_alarm		Fan 1 warning.
> +fan1_fault		Fan 1 fault.
> +fan1_input		Fan 1 speed in RPM.
> +fan1_target             Fan 1 target.
> +======================= ======================================================
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 637ddd44245f..6b31d545f0f1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6100,6 +6100,13 @@ L:	linux-input at vger.kernel.org
>   S:	Maintained
>   F:	drivers/hid/hid-creative-sb0540.c
>   
> +CRPS COMMON REDUNDANT PSU DRIVER

This is _INTEL_ CRPS.

> +M:	Ninad Palsule <ninad at linux.ibm.com>
> +L:	linux-hwmon at vger.kernel.org
> +S:	Maintained
> +F:	Documentation/hwmon/crps.rst
> +F:	drivers/hwmon/pmbus/crps.c
> +
>   CRYPTO API
>   M:	Herbert Xu <herbert at gondor.apana.org.au>
>   M:	"David S. Miller" <davem at davemloft.net>
> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
> index 22418a05ced0..56c4eb4b846e 100644
> --- a/drivers/hwmon/pmbus/Kconfig
> +++ b/drivers/hwmon/pmbus/Kconfig
> @@ -85,6 +85,15 @@ config SENSORS_BPA_RS600
>   	  This driver can also be built as a module. If so, the module will
>   	  be called bpa-rs600.
>   
> +config SENSORS_CRPS
> +	tristate "Common Redundant Power Supply"

Again, this is an Intel product.

> +	help
> +	  If you say yes here you get hardware monitoring support for the Common
> +	  Redundant Power Supply.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called crps.
> +
>   config SENSORS_DELTA_AHE50DC_FAN
>   	tristate "Delta AHE-50DC fan control module"
>   	help
> diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
> index 3d3183f8d2a7..c7eb7739b7f8 100644
> --- a/drivers/hwmon/pmbus/Makefile
> +++ b/drivers/hwmon/pmbus/Makefile
> @@ -62,3 +62,4 @@ obj-$(CONFIG_SENSORS_XDPE122)	+= xdpe12284.o
>   obj-$(CONFIG_SENSORS_XDPE152)	+= xdpe152c4.o
>   obj-$(CONFIG_SENSORS_ZL6100)	+= zl6100.o
>   obj-$(CONFIG_SENSORS_PIM4328)	+= pim4328.o
> +obj-$(CONFIG_SENSORS_CRPS)	+= crps.o
> diff --git a/drivers/hwmon/pmbus/crps.c b/drivers/hwmon/pmbus/crps.c
> new file mode 100644
> index 000000000000..44d309f81803
> --- /dev/null
> +++ b/drivers/hwmon/pmbus/crps.c
> @@ -0,0 +1,299 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright 2024 IBM Corp.
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/i2c.h>
> +#include <linux/of.h>
> +#include <linux/pmbus.h>
> +
> +#include "pmbus.h"
> +
> +/* Intel crps185 specific commands. */
> +#define CRPS185_MFR_IOUT_MAX		0xA6
> +#define CRPS185_MFR_POUT_MAX		0xA7
> +

I fail to see the point in those defines, even more so since
PMBUS_MFR_POUT_MAX and PMBUS_MFR_IOUT_MAX are used below.

> +enum {
> +	CRPS_DEBUGFS_PMBUS_REVISION = 0,
> +	CRPS_DEBUGFS_MAX_POWER_OUT,
> +	CRPS_DEBUGFS_MAX_CURRENT_OUT,
> +	CRPS_DEBUGFS_NUM_ENTRIES
> +};
> +
> +enum models { crps185 = 1, crps_unknown };

Pointless enum. The driver only supports a single power supply.

> +
> +struct crps {
> +	enum models version;
> +	struct i2c_client *client;
> +
> +	int debugfs_entries[CRPS_DEBUGFS_NUM_ENTRIES];
> +};
> +
> +#define to_psu(x, y) container_of((x), struct crps, debugfs_entries[(y)])
> +
> +static struct pmbus_platform_data crps_pdata = {
> +	.flags = PMBUS_SKIP_STATUS_CHECK,
> +};

Did you confirm that it is needed ? If so, explain why it is needed.

> +
> +static const struct i2c_device_id crps_id[] = {
> +	{ "intel_crps185", crps185 },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(i2c, crps_id);
> +
> +/*
> + * Convert linear format word to machine format. 11 LSB side bits are two's
> + * complement integer mantissa and 5 MSB side bits are two's complement
> + * exponent
> + */
> +static int crps_convert_linear(int rc)
> +{
> +	s16 exponent;
> +	s32 mantissa;
> +	s64 val;
> +
> +	exponent = ((s16)rc) >> 11;
> +	mantissa = ((s16)((rc & 0x7ff) << 5)) >> 5;
> +
> +	val = mantissa;
> +	if (exponent >= 0)
> +		val <<= exponent;
> +	else
> +		val >>= -exponent;
> +
> +	return (int)val;
> +}
> +
> +static ssize_t crps_debugfs_read(struct file *file, char __user *buf,
> +				 size_t count, loff_t *ppos)
> +{
> +	int rc;
> +	int *idxp = file->private_data;
> +	int idx = *idxp;
> +	struct crps *psu = to_psu(idxp, idx);
> +	char data[2 * I2C_SMBUS_BLOCK_MAX] = { 0 };
> +
> +	rc = pmbus_lock_interruptible(psu->client);
> +	if (rc)
> +		return rc;
> +
> +	rc = pmbus_set_page(psu->client, 0, 0xff);
> +	if (rc)
> +		goto unlock;
> +
> +	switch (idx) {
> +	case CRPS_DEBUGFS_PMBUS_REVISION:
> +		rc = i2c_smbus_read_byte_data(psu->client, PMBUS_REVISION);
> +		if (rc >= 0) {
> +			if (psu->version == crps185) {
> +				if (rc == 0)
> +					rc = sprintf(data, "%s", "1.0");
> +				else if (rc == 0x11)
> +					rc = sprintf(data, "%s", "1.1");
> +				else if (rc == 0x22)
> +					rc = sprintf(data, "%s", "1.2");
> +				else
> +					rc = snprintf(data, 3, "0x%02x", rc);
> +			} else {
> +				rc = snprintf(data, 3, "%02x", rc);
> +			}
> +		}

This attribute should be added into the PMBus core.

> +		break;
> +	case CRPS_DEBUGFS_MAX_POWER_OUT:
> +		rc = i2c_smbus_read_word_data(psu->client, PMBUS_MFR_POUT_MAX);
> +		if (rc >= 0) {
> +			rc = crps_convert_linear(rc);
> +			rc = snprintf(data, I2C_SMBUS_BLOCK_MAX, "%d", rc);
> +		}
> +		break;
> +	case CRPS_DEBUGFS_MAX_CURRENT_OUT:
> +		rc = i2c_smbus_read_word_data(psu->client, PMBUS_MFR_IOUT_MAX);
> +		if (rc >= 0) {
> +			rc = crps_convert_linear(rc);
> +			rc = snprintf(data, I2C_SMBUS_BLOCK_MAX, "%d", rc);
> +		}
> +		break;

What is the point of those two attributes ? There are already
standard sysfs attributes reporting those values.

> +	default:
> +		rc = -EINVAL;
> +		break;
> +	}
> +
> +unlock:
> +	pmbus_unlock(psu->client);
> +	if (rc < 0)
> +		return rc;
> +
> +	data[rc] = '\n';
> +	rc += 2;
> +
> +	return simple_read_from_buffer(buf, count, ppos, data, rc);
> +}
> +
> +static const struct file_operations crps_debugfs_fops = {
> +	.llseek = noop_llseek,
> +	.read = crps_debugfs_read,
> +	.open = simple_open,
> +};
> +
> +static int crps_read_word_data(struct i2c_client *client, int page,
> +				int phase, int reg)
> +{
> +	int rc;
> +
> +	switch (reg) {
> +	case PMBUS_STATUS_WORD:
> +		rc = pmbus_read_word_data(client, page, phase, reg);
> +		if (rc < 0)
> +			return rc;
> +		break;

Why is this needed ?

> +	case PMBUS_OT_WARN_LIMIT:
> +		rc = pmbus_read_word_data(client, page, phase,
> +					  PMBUS_MFR_MAX_TEMP_1);
> +		if (rc < 0)
> +			return rc;
> +		break;
> +	case PMBUS_IOUT_OC_WARN_LIMIT:
> +		rc = pmbus_read_word_data(client, page, phase,
> +					  CRPS185_MFR_IOUT_MAX);
> +		if (rc < 0)
> +			return rc;
> +		break;
> +	case PMBUS_POUT_OP_WARN_LIMIT:
> +		rc = pmbus_read_word_data(client, page, phase,
> +					  CRPS185_MFR_POUT_MAX);
> +		if (rc < 0)
> +			return rc;
> +		break;

The above three values are more than odd. They duplicate the respective
standard rated_max attributes as warning limits. Why ?

On top of that, on writes, the actual warning limits are overwritten.
That makes even less sense.

> +	default:
> +		rc = -ENODATA;
> +		break;
> +	}
> +
> +	return rc;
> +}
> +
> +static struct pmbus_driver_info crps_info[] = {
> +	[crps185] = {
> +		.pages = 1,
> +		/* PSU uses default linear data format. */
> +		.func[0] = PMBUS_HAVE_PIN | PMBUS_HAVE_IOUT |
> +			PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_IIN |
> +			PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
> +			PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
> +			PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
> +			PMBUS_HAVE_STATUS_TEMP |
> +			PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
> +		.read_word_data = crps_read_word_data,
> +	},
> +};
> +
> +#define to_psu(x, y) container_of((x), struct crps, debugfs_entries[(y)])
> +
> +static void crps_init_debugfs(struct crps *psu)
> +{
> +	struct i2c_client *client = psu->client;
> +	struct dentry *debugfs;
> +	int i;
> +
> +	/* Don't fail the probe if we can't create debugfs */
> +	debugfs = pmbus_get_debugfs_dir(client);
> +	if (!debugfs)
> +		return;
> +
> +	for (i = 0; i < CRPS_DEBUGFS_NUM_ENTRIES; ++i)
> +		psu->debugfs_entries[i] = i;
> +
> +	debugfs_create_file("pmbus_revision", 0444, debugfs,
> +			    &psu->debugfs_entries[CRPS_DEBUGFS_PMBUS_REVISION],
> +			    &crps_debugfs_fops);
> +	debugfs_create_file("max_power_out", 0444, debugfs,
> +			    &psu->debugfs_entries[CRPS_DEBUGFS_MAX_POWER_OUT],
> +			    &crps_debugfs_fops);
> +	debugfs_create_file("max_current_out", 0444, debugfs,
> +			    &psu->debugfs_entries[CRPS_DEBUGFS_MAX_CURRENT_OUT],
> +			    &crps_debugfs_fops);
> +}
> +
> +static int crps_probe(struct i2c_client *client)
> +{
> +	int rc;
> +	struct device *dev = &client->dev;
> +	enum models vs = crps_unknown;
> +	struct crps *psu;
> +	const void *md = of_device_get_match_data(&client->dev);
> +	const struct i2c_device_id *id = NULL;
> +	char buf[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
> +
> +	if (md) {
> +		vs = (uintptr_t)md;
> +	} else {
> +		id = i2c_match_id(crps_id, client);
> +		if (id)
> +			vs = (enum models)id->driver_data;
> +	}
> +
Consider using i2c_get_match_data().

> +	if (!vs || vs >= crps_unknown) {
> +		dev_err(dev, "Version %d not supported\n", vs);
> +		return -EINVAL;
> +	}

This is very much pointless. The driver would not be instantiated withut match.

> +
> +	rc = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
> +	if (rc < 0) {
> +		dev_err(dev, "Failed to read PMBUS_MFR_MODEL\n");
> +		return rc;

dev_err_probe().

> +	}
> +	if (strncmp(buf, "03NK260", 7)) {

This should also check and ensure that rc == 7.

> +		buf[rc] = '\0';
> +		dev_err(dev, "Model '%s' not supported\n", buf);

dev_err_probe()

> +		return -ENODEV;
> +	}
> +
> +	client->dev.platform_data = &crps_pdata;
> +	rc = pmbus_do_probe(client, &crps_info[vs]);
> +	if (rc) {
> +		dev_err(dev, "Failed to probe %d\n", rc);
> +		return rc;

dev_err_probe().

> +	}
> +
> +	/*
> +	 * Don't fail the probe if there isn't enough memory for debugfs.
> +	 */
> +	psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
> +	if (!psu) {
> +		dev_warn(dev, "Failed to allocate memory. debugfs are not supported.\n");
> +		return 0;
> +	}
> +
> +	psu->version = vs;
> +	psu->client = client;
> +

Drop all this. Add the PMBus version as standard debugfs attribute to the PMBus core
if needed/wanted. The rest is already provided as standard sysfs attributes, and
reporting the same value in debugfs files adds no value.

> +	crps_init_debugfs(psu);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id crps_of_match[] = {
> +	{
> +		.compatible = "intel,crps185",
> +		.data = (void *)crps185
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, crps_of_match);
> +
> +static struct i2c_driver crps_driver = {
> +	.driver = {
> +		.name = "crps",
> +		.of_match_table = crps_of_match,
> +	},
> +	.probe = crps_probe,
> +	.id_table = crps_id,
> +};
> +
> +module_i2c_driver(crps_driver);
> +
> +MODULE_AUTHOR("Ninad Palsule");
> +MODULE_DESCRIPTION("PMBus driver for Common Redundant power supplies");

Again, this is for _Intel_ power supplies.

> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS("PMBUS");



From akpm at linux-foundation.org  Thu Dec 12 17:36:09 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Thu, 12 Dec 2024 17:36:09 -0800
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
In-Reply-To: <1818e2ea-f170-4a9c-8d93-2a24f2755a41@lucifer.local>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
	<hmuzfspqjzb36xlj2x44keihacrrhzj5madqrfbcnhqouzredv@wo75achgkuh5>
	<1818e2ea-f170-4a9c-8d93-2a24f2755a41@lucifer.local>
Message-ID: <20241212173609.afd41d1dffbefe0d731ed4ed@linux-foundation.org>

On Thu, 12 Dec 2024 22:51:34 +0000 Lorenzo Stoakes <lorenzo.stoakes at oracle.com> wrote:

> You've fundamentally violated kernel process and etiquette. I'd be more
> forgiving, but this is at v2 and you've not cc'd KEY people. Twice. This is
> totally unacceptable. See [0] if you are unsure of how to do so.

This feels excessive to me.  linux-mm averages a mere 140 mesages/day
and it seems reasonable to assume that key people are spending their 5
minutes to scroll through the email subjects.


From akpm at linux-foundation.org  Thu Dec 12 17:39:34 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Thu, 12 Dec 2024 17:39:34 -0800
Subject: [PATCH mm-unstable v2 06/16] mm: csky: Introduce
 arch_mmap_hint()
In-Reply-To: <vc2uhcysgosapznbuookcj5677w43a4kzxbotwqub237ccawww@i3pbqiacdwsx>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
	<20241211232754.1583023-7-kaleshsingh@google.com>
	<vc2uhcysgosapznbuookcj5677w43a4kzxbotwqub237ccawww@i3pbqiacdwsx>
Message-ID: <20241212173934.4dc429716acd4c71a76e15c2@linux-foundation.org>

On Thu, 12 Dec 2024 16:40:10 -0500 "Liam R. Howlett" <Liam.Howlett at oracle.com> wrote:

> * Kalesh Singh <kaleshsingh at google.com> [241211 18:28]:
> > Introduce csky arch_mmap_hint() and define HAVE_ARCH_MMAP_HINT.
> > This is a preparatory patch, no functional change is introduced.
> 
> This also looks like it has changed the validation order and potentially
> introduced functional changes?
> 
> All these stem from the same cloned code (sparc32 iirc), but were not
> updated when the cloned code was updated.  This is why I am against
> arch_* code.  We should find a better way to unify the code so that
> there is nothing different.  You seem to have gotten some of the shared
> code together, but some still exists.
> 
> In the addresses, there are upper and lower limits, and sometimes
> "colours".  Could we not just define the upper/lower limits in each arch
> and if colour is used?  Maybe this is complicated with 32/64 handled
> both in the 64 bit code.
> 
> Is there any plan to unite this code further?
> 
> We have had errors for many years in cloned but not updated code.  I
> really wish there was more information in the cover letter on what is
> going on here.  I'd like to try and reduce the arch_ code to, basically
> nothing.
> 
> I was also disappointed that I wasn't Cc'ed because I've spent a lot of
> time in this code and this area.  I am probably the last one to crawl
> through and change any of this.

Thanks, I removed this version of this series from mm-unstable.


From quic_jiegan at quicinc.com  Thu Dec 12 17:39:29 2024
From: quic_jiegan at quicinc.com (Jie Gan)
Date: Fri, 13 Dec 2024 09:39:29 +0800
Subject: [PATCH v7 3/5] dt-bindings: arm: Add Coresight TMC Control Unit
 hardware
In-Reply-To: <8c60e0dc-531a-47d6-9c40-ea157a24da1b@oss.qualcomm.com>
References: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
 <20241210031545.3468561-4-quic_jiegan@quicinc.com>
 <8c60e0dc-531a-47d6-9c40-ea157a24da1b@oss.qualcomm.com>
Message-ID: <767e2a81-17a6-48ae-932b-314cdfa8005a@quicinc.com>



On 12/13/2024 2:19 AM, Konrad Dybcio wrote:
> On 10.12.2024 4:15 AM, Jie Gan wrote:
>> Add binding file to specify how to define a Coresight TMC
>> Control Unit device in device tree.
>>
>> It is responsible for controlling the data filter function
>> based on the source device's Trace ID for TMC ETR device.
>> The trace data with that Trace id can get into ETR's buffer
>> while other trace data gets ignored.
>>
>> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
>> Signed-off-by: Jie Gan <quic_jiegan at quicinc.com>
>> ---
> 
> [...]
> 
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - qcom,sa8775p-ctcu
> 
> I don't think anyone asked that question.. Is the TMCCU something unique
> to Qualcomm platforms?

Yes, only presents on Qualcomm platforms. That's why we try to upstream 
the driver.

> 
> Konrad

Thanks,
Jie



From jinjian.song at fibocom.com  Thu Dec 12 18:55:55 2024
From: jinjian.song at fibocom.com (Jinjian Song)
Date: Fri, 13 Dec 2024 10:55:55 +0800
Subject: [net-next v1] net: wwan: t7xx: Fix FSM command timeout issue
In-Reply-To: <b409c23a-0b6f-458c-8e34-039338e799c0@intel.com>
References: <20241212105555.10364-1-jinjian.song@fibocom.com>
Message-ID: <20241213025555.113779-1-jinjian.song@fibocom.com>

From: Mateusz Polchlopek <mateusz.polchlopek at intel.com>

>On 12/12/2024 11:55 AM, Jinjian Song wrote:
>> When driver processes the internal state change command, it use
>> asynchronous thread to process the command operation. If the main
>> thread detects that the task has timed out, the asynchronous thread
>> will panic when executing te completion notification because the
>> main thread completion object is released.
>> 
>[...]

>If this is a fix then should be targeted to net and not net-next
>and probably should have Fixes: tag.

Hi Mateusz,

Please let me request to net and add the Fixes: tag.

Thanks.

Jinjian,
Best Regards.


From jinjian.song at fibocom.com  Thu Dec 12 18:57:00 2024
From: jinjian.song at fibocom.com (Jinjian Song)
Date: Fri, 13 Dec 2024 10:57:00 +0800
Subject: [net-next v1] net: wwan: t7xx: Fix FSM command timeout issue
In-Reply-To: <20241212161524.GA3345429@bhelgaas>
References: <20241212161524.GA3345429@bhelgaas>
Message-ID: <20241212161524.GA3345429@bhelgaas>

>On Thu, Dec 12, 2024 at 06:55:55PM +0800, Jinjian Song wrote:
>> When driver processes the internal state change command, it use
>> asynchronous thread to process the command operation. If the main
>> thread detects that the task has timed out, the asynchronous thread
>> will panic when executing te completion notification because the
>> main thread completion object is released.
>
>s/it use/it uses an/
>s/te/the/
>s/is released/has been released/
>
Hi Bjorn,

Got it, please let me to correct these errors.

Thanks.

Jinjian,
Best Regards.


From 0x1207 at gmail.com  Thu Dec 12 19:00:06 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Fri, 13 Dec 2024 11:00:06 +0800
Subject: [PATCH net-next v1] net: stmmac: TSO: Simplify the code flow of DMA descriptor allocations
Message-ID: <20241213030006.337695-1-0x1207@gmail.com>

The DMA AXI address width of DWMAC cores can be configured to
32-bit/40-bit/48-bit, then the format of DMA transmit descriptors
get a little different between 32-bit and 40-bit/48-bit.
Current driver code checks priv->dma_cap.addr64 to use certain format
with certain configuration.

This patch converts the format of DMA transmit descriptors on platforms
that the DMA AXI address width is configured to 32-bit (as described by
function comments of stmmac_tso_xmit() in current code) to a more generic
format (see the updated function comments after this patch) which is
actually already used on 40-bit/48-bit platforms to provide better
compatibility and make code flow cleaner.

Tested and verified on:
DWMAC CORE 5.10a with 32-bit DMA AXI address width
DWXGMAC CORE 3.20a with 40-bit DMA AXI address width

Signed-off-by: Furong Xu <0x1207 at gmail.com>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 60 ++++++++-----------
 1 file changed, 24 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 16b8bcfa8b11..a48b7cf74a29 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4121,11 +4121,7 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, dma_addr_t des,
 			desc = &tx_q->dma_tx[tx_q->cur_tx];
 
 		curr_addr = des + (total_len - tmp_len);
-		if (priv->dma_cap.addr64 <= 32)
-			desc->des0 = cpu_to_le32(curr_addr);
-		else
-			stmmac_set_desc_addr(priv, desc, curr_addr);
-
+		stmmac_set_desc_addr(priv, desc, curr_addr);
 		buff_size = tmp_len >= TSO_MAX_BUFF_SIZE ?
 			    TSO_MAX_BUFF_SIZE : tmp_len;
 
@@ -4171,17 +4167,27 @@ static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue)
  *  First Descriptor
  *   --------
  *   | DES0 |---> buffer1 = L2/L3/L4 header
- *   | DES1 |---> TCP Payload (can continue on next descr...)
- *   | DES2 |---> buffer 1 and 2 len
+ *   | DES1 |---> can be used as buffer2 for TCP Payload if the DMA AXI address
+ *   |      |     width is 32-bit, but we never use it.
+ *   |      |     Also can be used as the most-significant 8-bits or 16-bits of
+ *   |      |     buffer1 address pointer if the DMA AXI address width is 40-bit
+ *   |      |     or 48-bit, and we always use it.
+ *   | DES2 |---> buffer1 len
  *   | DES3 |---> must set TSE, TCP hdr len-> [22:19]. TCP payload len [17:0]
  *   --------
+ *   --------
+ *   | DES0 |---> buffer1 = TCP Payload (can continue on next descr...)
+ *   | DES1 |---> same as the First Descriptor
+ *   | DES2 |---> buffer1 len
+ *   | DES3 |
+ *   --------
  *	|
  *     ...
  *	|
  *   --------
- *   | DES0 | --| Split TCP Payload on Buffers 1 and 2
- *   | DES1 | --|
- *   | DES2 | --> buffer 1 and 2 len
+ *   | DES0 |---> buffer1 = Split TCP Payload
+ *   | DES1 |---> same as the First Descriptor
+ *   | DES2 |---> buffer1 len
  *   | DES3 |
  *   --------
  *
@@ -4191,15 +4197,14 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct dma_desc *desc, *first, *mss_desc = NULL;
 	struct stmmac_priv *priv = netdev_priv(dev);
-	int tmp_pay_len = 0, first_tx, nfrags;
 	unsigned int first_entry, tx_packets;
 	struct stmmac_txq_stats *txq_stats;
 	struct stmmac_tx_queue *tx_q;
 	u32 pay_len, mss, queue;
-	dma_addr_t tso_des, des;
+	int i, first_tx, nfrags;
 	u8 proto_hdr_len, hdr;
+	dma_addr_t des;
 	bool set_ic;
-	int i;
 
 	/* Always insert VLAN tag to SKB payload for TSO frames.
 	 *
@@ -4284,24 +4289,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (dma_mapping_error(priv->device, des))
 		goto dma_map_err;
 
-	if (priv->dma_cap.addr64 <= 32) {
-		first->des0 = cpu_to_le32(des);
-
-		/* Fill start of payload in buff2 of first descriptor */
-		if (pay_len)
-			first->des1 = cpu_to_le32(des + proto_hdr_len);
-
-		/* If needed take extra descriptors to fill the remaining payload */
-		tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
-		tso_des = des;
-	} else {
-		stmmac_set_desc_addr(priv, first, des);
-		tmp_pay_len = pay_len;
-		tso_des = des + proto_hdr_len;
-		pay_len = 0;
-	}
-
-	stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
+	stmmac_set_desc_addr(priv, first, des);
+	stmmac_tso_allocator(priv, des + proto_hdr_len, pay_len,
+			     (nfrags == 0), queue);
 
 	/* In case two or more DMA transmit descriptors are allocated for this
 	 * non-paged SKB data, the DMA buffer address should be saved to
@@ -4405,11 +4395,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	/* Complete the first descriptor before granting the DMA */
-	stmmac_prepare_tso_tx_desc(priv, first, 1,
-			proto_hdr_len,
-			pay_len,
-			1, tx_q->tx_skbuff_dma[first_entry].last_segment,
-			hdr / 4, (skb->len - proto_hdr_len));
+	stmmac_prepare_tso_tx_desc(priv, first, 1, proto_hdr_len, 0, 1,
+				   tx_q->tx_skbuff_dma[first_entry].last_segment,
+				   hdr / 4, (skb->len - proto_hdr_len));
 
 	/* If context desc is used to change MSS */
 	if (mss_desc) {
-- 
2.34.1



From quic_pkondeti at quicinc.com  Thu Dec 12 19:05:27 2024
From: quic_pkondeti at quicinc.com (Pavan Kondeti)
Date: Fri, 13 Dec 2024 08:35:27 +0530
Subject: [PATCH] drm/msm/a6xx: Skip gpu secure fw load in EL2 mode
In-Reply-To: <Z1q9rnzOlB9J5dXb@J2N7QTR9R3>
References: <20241209-drm-msm-kvm-support-v1-1-1c983a8a8087@quicinc.com>
 <87ed2fs03w.wl-maz@kernel.org>
 <92cee905-a505-4ce9-9bbc-6fba4cea1d80@quicinc.com>
 <86sequsdtp.wl-maz@kernel.org>
 <c197264b-3791-493a-b717-3dfd844de922@quicinc.com>
 <87bjxhs2t7.wl-maz@kernel.org>
 <Z1q9rnzOlB9J5dXb@J2N7QTR9R3>
Message-ID: <b71d89f9-fb72-405a-b5bf-a09a796561bb@quicinc.com>

On Thu, Dec 12, 2024 at 10:40:46AM +0000, Mark Rutland wrote:
> On Thu, Dec 12, 2024 at 08:50:12AM +0000, Marc Zyngier wrote:
> > On Thu, 12 Dec 2024 05:31:00 +0000,
> > Pavan Kondeti <quic_pkondeti at quicinc.com> wrote:
> > > 
> > > On Wed, Dec 11, 2024 at 10:40:02AM +0000, Marc Zyngier wrote:
> > > > On Wed, 11 Dec 2024 00:37:34 +0000,
> > > > Pavan Kondeti <quic_pkondeti at quicinc.com> wrote:
> > > > > 
> > > > > On Tue, Dec 10, 2024 at 09:24:03PM +0000, Marc Zyngier wrote:
> > > > > > > +static int a6xx_switch_secure_mode(struct msm_gpu *gpu)
> > > > > > > +{
> > > > > > > +	int ret;
> > > > > > > +
> > > > > > > +#ifdef CONFIG_ARM64
> > > > > > > +	/*
> > > > > > > +	 * We can access SECVID_TRUST_CNTL register when kernel is booted in EL2 mode. So, use it
> > > > > > > +	 * to switch the secure mode to avoid the dependency on zap shader.
> > > > > > > +	 */
> > > > > > > +	if (is_kernel_in_hyp_mode())
> > > > > > > +		goto direct_switch;
> > > > > > 
> > > > > > No, please. To check whether you are *booted* at EL2, you need to
> > > > > > check for is_hyp_available(). Whether the kernel runs at EL1 or EL2 is
> > > > > > none of the driver's business, really. This is still absolutely
> > > > > > disgusting from an abstraction perspective, but I guess we don't have
> > > > > > much choice here.
> > > > > > 
> > > > > 
> > > > > Thanks Marc. Any suggestions on how we can make is_hyp_mode_available()
> > > > > available for modules? Do you prefer exporting
> > > > > kvm_protected_mode_initialized and __boot_cpu_mode symbols directly or
> > > > > try something like [1]?
> > > > 
> > > > Ideally, neither. These were bad ideas nine years ago, and they still
> > > > are. The least ugly hack I can come up with is the patch below, and
> > > > you'd write something like:
> > > > 
> > > > 	if (cpus_have_cap(ARM64_HAS_EL2_OWNERSHIP))
> > > > 		blah();
> > > > 
> > > > This is obviously completely untested.
> > > > 
> > > 
> > > I have tested your patch. It works as intended. Thanks Marc.
> > 
> > Note that you will probably get some push-back from the arm64
> > maintainers on this front, because this is a fairly incomplete (and
> > fragile) solution.
> > 
> > It would be much better if the discriminant came from the device tree.
> > After all, the hypervisor is fscking-up^W^Wchanging the programming
> > model of the GPU, and that should be reflected in the DT. Because for
> > all intent and purposes, this is not the same hardware anymore.
> 
> FWIW I agree 100%, this should be described in DT.
> 
> The cpucap doesn't describe the actual property we care about, and it
> cannot in general (e.g. for nested virt). I would strongly prefer to not
> have that as it's setting ourselves up for failure.
> 
Thanks for the feedback. I understand that EL2 detection in kernel is
not going to cover cases like bare metal EL1, nested virtualization. We
plan to take the DT approach. 

Thanks,
Pavan


From peng.fan at oss.nxp.com  Thu Dec 12 20:11:00 2024
From: peng.fan at oss.nxp.com (Peng Fan)
Date: Fri, 13 Dec 2024 12:11:00 +0800
Subject: [PATCH 2/2] nvmem: imx-ocotp-ele: Support accessing controller
 for i.MX9
In-Reply-To: <Z1shTD5QLRXB1wAk@lizhi-Precision-Tower-5810>
References: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>
 <20241212-imx-ocotp-v1-2-198bb0af86a0@nxp.com>
 <Z1shTD5QLRXB1wAk@lizhi-Precision-Tower-5810>
Message-ID: <20241213041100.GA6948@localhost.localdomain>

On Thu, Dec 12, 2024 at 12:45:48PM -0500, Frank Li wrote:
>On Thu, Dec 12, 2024 at 04:24:42PM +0800, Peng Fan (OSS) wrote:
>> From: Peng Fan <peng.fan at nxp.com>
>>
>> i.MX9 OCOTP supports a specific peripheral or function being fused
>> which means disabled, so
>>  - Introduce ocotp_access_gates to be container of efuse gate info
>>  - Iterate each node under '/soc' to check accessing permission. If not
>>    allowed to be accessed, detach the node
>>
>> Signed-off-by: Peng Fan <peng.fan at nxp.com>
>> ---
>>  drivers/nvmem/imx-ocotp-ele.c | 187 +++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 186 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
>> index ca6dd71d8a2e29888c6e556aaea116c1a967cb5f..542539b86efd2d38be2903c1d0ea72f918ff5b75 100644
>> --- a/drivers/nvmem/imx-ocotp-ele.c
>> +++ b/drivers/nvmem/imx-ocotp-ele.c
>> @@ -5,6 +5,8 @@
>>   * Copyright 2023 NXP
>>   */
>>
>> +#include <dt-bindings/nvmem/fsl,imx93-ocotp.h>
>> +#include <dt-bindings/nvmem/fsl,imx95-ocotp.h>
>>  #include <linux/device.h>
>>  #include <linux/io.h>
>>  #include <linux/module.h>
>> @@ -27,6 +29,7 @@ struct ocotp_map_entry {
>>  };
>>
>>  struct ocotp_devtype_data {
>> +	const struct ocotp_access_gates *access_gates;
>>  	u32 reg_off;
>>  	char *name;
>>  	u32 size;
>> @@ -36,11 +39,26 @@ struct ocotp_devtype_data {
>>  	struct ocotp_map_entry entry[];
>>  };
>>
>> +#define OCOTP_MAX_NUM_GATE_WORDS 4
>> +#define IMX93_OCOTP_NUM_GATES 17
>> +#define IMX95_OCOTP_NUM_GATES 36
>> +
>> +struct ocotp_access_gates {
>> +	u32 num_words;
>> +	u32 words[OCOTP_MAX_NUM_GATE_WORDS];
>> +	u32 num_gates;
>> +	struct access_gate {
>> +		u32 word;
>> +		u32 mask;
>> +	} gates[];
>> +};
>> +
>>  struct imx_ocotp_priv {
>>  	struct device *dev;
>>  	void __iomem *base;
>>  	struct nvmem_config config;
>>  	struct mutex lock;
>> +	u32 value[OCOTP_MAX_NUM_GATE_WORDS];
>>  	const struct ocotp_devtype_data *data;
>>  };
>>
>> @@ -131,6 +149,100 @@ static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
>>  	cell->read_post_process = imx_ocotp_cell_pp;
>>  }
>>
>> +static int imx_ele_ocotp_check_access(struct platform_device *pdev, u32 id)
>> +{
>> +	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
>> +	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
>> +	u32 word, mask;
>> +
>> +	if (id >= access_gates->num_gates) {
>> +		dev_err(&pdev->dev, "Index %d too large\n", id);
>> +		return -EACCES;
>> +	}
>> +
>> +	word = access_gates->gates[id].word;
>> +	mask = access_gates->gates[id].mask;
>> +
>> +	dev_dbg(&pdev->dev, "id:%d word:%d mask:0x%08x\n", id, word, mask);
>> +	/* true means not allow access */
>> +	if (priv->value[word] & mask)
>> +		return -EACCES;
>> +
>> +	return 0;
>> +}
>> +
>> +static int imx_ele_ocotp_grant_access(struct platform_device *pdev, struct device_node *parent)
>> +{
>> +	struct device_node *child;
>> +	struct device *dev = &pdev->dev;
>> +
>> +	for_each_available_child_of_node(parent, child) {
>> +		struct of_phandle_iterator it;
>> +		int err;
>> +		u32 id;
>> +
>> +		of_for_each_phandle(&it, err, child, "access-controllers",
>> +				    "#access-controller-cells", 0) {
>> +			struct of_phandle_args provider_args;
>> +			struct device_node *provider = it.node;
>> +
>> +			if (err) {
>> +				dev_err(dev, "Unable to get access-controllers property for node %s\n, err: %d",
>> +					child->full_name, err);
>> +				of_node_put(provider);
>> +				return err;
>> +			}
>> +
>> +			/* Only support one cell */
>> +			if (of_phandle_iterator_args(&it, provider_args.args, 1) != 1) {
>> +				dev_err(dev, "wrong args count\n");
>> +				return -EINVAL;
>> +			}
>> +
>> +			id = provider_args.args[0];
>> +
>> +			dev_dbg(dev, "Checking node: %s gate: %d\n", child->full_name, id);
>> +
>> +			if (imx_ele_ocotp_check_access(pdev, id)) {
>> +				of_detach_node(child);
>> +				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
>> +					child->full_name);
>> +			}
>> +		}
>> +
>> +		imx_ele_ocotp_grant_access(pdev, child);
>> +	}
>
>Does it mean ocopt driver have to probe before other driver probe?

Yes. devlink could make sure ocotp being probed before other drivers which
needs access control check.

Regards,
Peng.

>
>Frank
>


From ck.hu at mediatek.com  Thu Dec 12 19:21:15 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 13 Dec 2024 03:21:15 +0000
Subject: [PATCH 1/2] dt-bindings: display: mediatek: ovl: Modify rules for
 MT8195/MT8188
In-Reply-To: <20241212153344.27408-2-jason-jh.lin@mediatek.com>
References: <20241212153344.27408-1-jason-jh.lin@mediatek.com>
	 <20241212153344.27408-2-jason-jh.lin@mediatek.com>
Message-ID: <4cadf749736b39872f122096512eff033c9b50c7.camel@mediatek.com>

Hi, Jason:

On Thu, 2024-12-12 at 23:33 +0800, Jason-JH.Lin wrote:
> From: Hsiao Chien Sung <shawn.sung at mediatek.com>
> 
> Modify rules for both MT8195 and MT8188.
> Hardware capabilities include color formats and AFBC are
> changed since MT8195, stop using the settings of MT8183.

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

> 
> Acked-by: Rob Herring <robh at kernel.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> ---
>  .../bindings/display/mediatek/mediatek,ovl.yaml           | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> index 9ea796a033b2..0ace12bbb623 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> @@ -36,16 +36,14 @@ properties:
>            - enum:
>                - mediatek,mt6795-disp-ovl
>            - const: mediatek,mt8173-disp-ovl
> -      - items:
> -          - enum:
> -              - mediatek,mt8188-disp-ovl
> -              - mediatek,mt8195-disp-ovl
> -          - const: mediatek,mt8183-disp-ovl
>        - items:
>            - enum:
>                - mediatek,mt8186-disp-ovl
>                - mediatek,mt8365-disp-ovl
>            - const: mediatek,mt8192-disp-ovl
> +      - items:
> +          - const: mediatek,mt8188-disp-ovl
> +          - const: mediatek,mt8195-disp-ovl
>  
>    reg:
>      maxItems: 1


From victor.liu at nxp.com  Thu Dec 12 19:40:22 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Fri, 13 Dec 2024 11:40:22 +0800
Subject: [PATCH v6 01/19] dt-bindings: display: imx: Add i.MX8qxp Display
 Controller processing units
In-Reply-To: <20241211145541.GA2837320-robh@kernel.org>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
 <20241209033923.3009629-2-victor.liu@nxp.com>
 <20241210221508.GA550635-robh@kernel.org>
 <30924a9e-7d01-46f6-9e47-405c08acdde3@nxp.com>
 <20241211145541.GA2837320-robh@kernel.org>
Message-ID: <6548eb6e-d4c3-495b-b59e-5fdbcb6ca398@nxp.com>

On 12/11/2024, Rob Herring wrote:
> On Wed, Dec 11, 2024 at 11:05:52AM +0800, Liu Ying wrote:
>> On 12/11/2024, Rob Herring wrote:
>>> On Mon, Dec 09, 2024 at 11:39:05AM +0800, Liu Ying wrote:
>>>> Freescale i.MX8qxp Display Controller is implemented as construction set of
>>>> building blocks with unified concept and standardized interfaces.  Document
>>>> all existing processing units.
>>>>
>>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>>>> ---
>>>> v6:
>>>> * No change.
>>>>
>>>> v5:
>>>> * Document aliases for processing units which have multiple instances in
>>>>   the Display Controller.  Drop Rob's previous R-b tag. (Maxime)
>>>>
>>>> v4:
>>>> * Collect Rob's R-b tag.
>>>>
>>>> v3:
>>>> * Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
>>>>   fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
>>>>   into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
>>>> * Document all processing units. (Rob)
>>>>
>>>> v2:
>>>> * Drop fsl,dc-*-id DT properties. (Krzysztof)
>>>> * Add port property to fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
>>>> * Fix register range sizes in examples.
>>>>
>>>>  .../display/imx/fsl,imx8qxp-dc-blitblend.yaml |  46 ++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-clut.yaml      |  49 ++++++
>>>>  .../imx/fsl,imx8qxp-dc-constframe.yaml        |  49 ++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-dither.yaml    |  49 ++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-extdst.yaml    |  77 +++++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 ++++++++++++++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-filter.yaml    |  47 ++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-framegen.yaml  |  68 ++++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-gammacor.yaml  |  38 +++++
>>>>  .../imx/fsl,imx8qxp-dc-layerblend.yaml        |  45 ++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-matrix.yaml    |  48 ++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-rop.yaml       |  48 ++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++++
>>>>  .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  89 +++++++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-signature.yaml |  58 +++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-store.yaml     | 100 ++++++++++++
>>>>  .../display/imx/fsl,imx8qxp-dc-tcon.yaml      |  50 ++++++
>>>>  17 files changed, 1042 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
>>>> new file mode 100644
>>>> index 000000000000..7f800e72c3f3
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend.yaml
>>>> @@ -0,0 +1,46 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blitblend.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Freescale i.MX8qxp Display Controller Blit Blend Unit
>>>> +
>>>> +description: |
>>>> +  Combines two input frames to a single output frame, all frames having the
>>>> +  same dimension.
>>>> +
>>>> +  Each Blit Blend Unit device should have an alias in the aliases node, in the
>>>> +  form of dc<x>-blitblend<y>, where <x> is an integer specifying the Display
>>>> +  Controller instance and <y> is an integer specifying the Blit Blend Unit
>>>> +  device instance.
>>>
>>> That's really an abuse of aliases. If you need to describe connections 
>>> between components, use the graph binding like everyone else does for 
>>> display path components.
>>
>> I need to describe components' instance numbers which imply the connections
>> between components but not vice versa. If I use the graph binding, I cannot
>> get the instance numbers(0 or 1) of the two display engines(documented by
>> fsl,imx8qxp-dc-display-engine.yaml). If you have no objections, I may add the
>> instance numbers to compatible strings, like brcm,bcm2835-pixelvalve0.yaml.
>> What do you think?
> 
> You could have dc<x> and blitblend<y> aliases and use the graph to 
> define the connections. But I'm not really a fan of adding custom 
> aliases either. Why are the instance numbers important?
> 
> Are the programming models or features of the instances different? If 
> so, then a different compatible or property describing the feature may 
> be appropriate.

The instances numbers are important mainly because the four ExtDsts(0/1/4/5)
belong to content or safety streams of the two Display Engines, plus the four
LayerBlends(0/1/2/3) in Pixel Engine have different numbers of input ports to
connect with the outputs of other LayerBlends, though the reason for LBs is
weak since the input ports can be expressed by the graph binding.

                                           CF0/1/4/5
                           PE               | | | |
                                            V V V V  primary layer cross bar
                          +------------------------------------------+
                          |                                          |
4 FUs + (VS4/5 + HS4/5) =>|               LB0/1/2/3                  |
   secondary layer        |                                          |
   cross bar              +------------------------------------------+
                             |          |              |          |
                             V          V              V          V
                          +-----+    +-----+        +-----+    +-----+
                          | ED0 |    | ED4 |        | ED5 |    | ED1 |
                          +-----+    +-----+        +-----+    +-----+
-----------------------------|----------|--------------|----------|-------------
                          content     safety        content     safety
                          stream0    stream0        stream1    stream1
                             |          |              |          |
                             |  DE0     V              V    DE1   |
                             |       +-----+        +-----+       |
                              ------>| FG0 |        | FG1 |<------
                                     +-----+        +-----+
                                        |              |
                                        V              V
                                       ...            ...

(Safety stream still is supposed to still function when content stream fails
over.)

LayerBlend primary layer selections:
static const enum dc_link_id prim_sels[] = {                                     
        /* common options */                                                     
        LINK_ID_NONE,                                                            
        LINK_ID_CONSTFRAME0,                                                     
        LINK_ID_CONSTFRAME1,                                                     
        LINK_ID_CONSTFRAME4,                                                     
        LINK_ID_CONSTFRAME5,                                                     
        /*                                                                       
         * special options:                                                      
         * layerblend(n) has n special options,                                  
         * from layerblend0 to layerblend(n - 1), e.g.,                          
         * layerblend3 has 3 special options -                                   
         * layerblend0/1/2.                                                      
         */                                                                      
        LINK_ID_LAYERBLEND0,                                                     
        LINK_ID_LAYERBLEND1,                                                     
        LINK_ID_LAYERBLEND2,                                                     
        LINK_ID_LAYERBLEND3,                                                     
};

People may argue that ED instance number is also not that important, because
content/safety stream can be inferred from FG input port numbers.  That's
true, but the connections between the internal devices are too complex and
I'm afraid it's an over-kill to use the graph binding. I list LB2 primary
layer selections and ED0 input selections here as examples:

--8<--
Selection of the source for the prim input of the layerblend2 module
0: disable      
10: blitblend9  
12: constframe0 
16: constframe1 
14: constframe4 
18: constframe5 
27: matrix4     
28: hscaler4    
29: vscaler4    
30: matrix5     
31: hscaler5    
32: vscaler5    
34: layerblend1 
33: layerblend0 
--8<--

--8<--
Selection of the source for the src input of the extdst0 module
0: disable      
10: blitblend9  
12: constframe0 
16: constframe1 
14: constframe4 
18: constframe5 
27: matrix4     
28: hscaler4    
29: vscaler4    
30: matrix5     
31: hscaler5    
32: vscaler5    
36: layerblend3 
35: layerblend2 
34: layerblend1 
33: layerblend0 
--8<--

TL;DR: I'd like to get instance numbers because of an appropriate programming
model _and_ different features of EDs and LBs(content/safety steam for EDs +
different input selections for LBs).  If no objections, I'll add instance
numbers to compatible strings in next version.

> 
> Rob

-- 
Regards,
Liu Ying


From treapking at chromium.org  Thu Dec 12 19:41:41 2024
From: treapking at chromium.org (Pin-yen Lin)
Date: Fri, 13 Dec 2024 11:41:41 +0800
Subject: [PATCH 1/2] dt-bindings: display: mediatek: ovl: Modify rules for MT8195/MT8188
In-Reply-To: <20241212153344.27408-2-jason-jh.lin@mediatek.com>
References: <20241212153344.27408-1-jason-jh.lin@mediatek.com> <20241212153344.27408-2-jason-jh.lin@mediatek.com>
Message-ID: <CAEXTbpfc0ybrvMCuJkKAUwXXTtpZ=vU9MLfU=4CzgdTd-ck4qw@mail.gmail.com>

Hi Jason,

On Thu, Dec 12, 2024 at 11:33?PM Jason-JH.Lin <jason-jh.lin at mediatek.com> wrote:
>
> From: Hsiao Chien Sung <shawn.sung at mediatek.com>
>
> Modify rules for both MT8195 and MT8188.
> Hardware capabilities include color formats and AFBC are
> changed since MT8195, stop using the settings of MT8183.
>
> Acked-by: Rob Herring <robh at kernel.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> Reviewed-by: CK Hu <ck.hu at mediatek.com>
> ---
>  .../bindings/display/mediatek/mediatek,ovl.yaml           | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> index 9ea796a033b2..0ace12bbb623 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> @@ -36,16 +36,14 @@ properties:
>            - enum:
>                - mediatek,mt6795-disp-ovl
>            - const: mediatek,mt8173-disp-ovl
> -      - items:
> -          - enum:
> -              - mediatek,mt8188-disp-ovl
> -              - mediatek,mt8195-disp-ovl
> -          - const: mediatek,mt8183-disp-ovl

This breaks the schema check for mt8195.dtsi, which is currently using
`compatible = "mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-ovl";`

IIUC this is supposed to be a RESEND of [1], which actually added a
binding for "mediatek,mt8195-disp-ovl". However [1] still breaks
mt8195.dtsi because it only allows `compatible =
"mediatek,mt8195-disp-ovl"` But not `compatible =
"mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-ovl"`.

If "mediatek,mt8183-disp-ovl" is a reasonable fallback for
"mediatek,mt8195-disp-ovl", please keep a binding like:

      - items:
          - const: mediatek,mt8195-disp-ovl
          - const: mediatek,mt8183-disp-ovl

Or, fix mt8195.dtsi instead in the same series.

[1]: https://patchwork.kernel.org/project/linux-mediatek/patch/20231212121957.19231-4-shawn.sung at mediatek.com/
>        - items:
>            - enum:
>                - mediatek,mt8186-disp-ovl
>                - mediatek,mt8365-disp-ovl
>            - const: mediatek,mt8192-disp-ovl
> +      - items:
> +          - const: mediatek,mt8188-disp-ovl
> +          - const: mediatek,mt8195-disp-ovl
>
>    reg:
>      maxItems: 1

Regards,
Pin-yen


From yuanhsinte at chromium.org  Thu Dec 12 20:56:11 2024
From: yuanhsinte at chromium.org (Hsin-Te Yuan)
Date: Fri, 13 Dec 2024 04:56:11 +0000
Subject: [PATCH v3] arm64: dts: mediatek: mt8183: Switch to Elan
 touchscreen driver
Message-ID: <20241213-post-reset-v3-1-ec30df9b9381@chromium.org>

After commit 2be404486c05 ("HID: i2c-hid-of: Add reset GPIO support to
i2c-hid-of"), the i2c-hid-of driver used by some mt8183 devices resets
the touchscreen without having enough post-reset delay. This makes those
touchscreen fail to get probed.

Switch to Elan touchscreen driver, which has enough post-reset delay.

Fixes: 2be404486c05 ("HID: i2c-hid-of: Add reset GPIO support to i2c-hid-of")
Signed-off-by: Hsin-Te Yuan <yuanhsinte at chromium.org>
---
After commit 2be404486c05 ("HID: i2c-hid-of: Add reset GPIO support to
i2c-hid-of"), i2c-hid-of driver resets the touchscreen without having
proper post-reset delay on OF platform.  From the commit message of that
commit, not to decribe poset-reset delay in device tree is intended.
Instead, describing the delay in platform data and changing to use
specialized driver is more preferable solution.
---
Changes in v3:
- Remove patches related to the race condition of pinctrl since they are
  not needed anymore.
- Link to v2: https://lore.kernel.org/r/20241018-post-reset-v2-0-28d539d79e18 at chromium.org

Changes in v2:
- Add second source touchscreen patches since they should based on the
  first patch of this series.
- Link to v1: https://lore.kernel.org/r/20241018-post-reset-v1-0-5aadb7550037 at chromium.org
---
 arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts       | 9 +++------
 .../arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts | 8 ++------
 .../arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts | 8 ++------
 .../arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts | 8 ++------
 4 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
index 65860b33c01fe832f3a4b2e21d24ea6b4f0cba2b..b226dfee22669d596e5b45a7cc02133ee4aaa828 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
@@ -14,16 +14,13 @@ / {
 };
 
 &touchscreen {
-	status = "okay";
+	compatible = "elan,ekth6a12nay";
 
-	compatible = "hid-over-i2c";
-	reg = <0x10>;
-	interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&touchscreen_pins>;
 
-	post-power-on-delay-ms = <10>;
-	hid-descr-addr = <0x0001>;
+	vcc33-supply = <&pp3300_alw>;
+	vccio-supply = <&pp1800_alw>;
 };
 
 &qca_wifi {
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts
index 72852b7600383972d98d9b0edd40b6e99e34a85b..863f3e403de8577da41b17b144cdb17c578b2027 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku1.dts
@@ -27,16 +27,12 @@ &cros_ec_pwm {
 };
 
 &touchscreen {
-	status = "okay";
+	compatible = "elan,ekth6a12nay";
 
-	compatible = "hid-over-i2c";
-	reg = <0x10>;
-	interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&touchscreen_pins>;
 
-	post-power-on-delay-ms = <10>;
-	hid-descr-addr = <0x0001>;
+	vcc33-supply = <&pp3300_alw>;
 };
 
 &qca_wifi {
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts
index 757d0afd14fb064fc1de4608e65eb1a561c4dfa6..e0a583ce4a0bb18095a77d23ab8409bb80898979 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku6.dts
@@ -14,16 +14,12 @@ / {
 };
 
 &touchscreen {
-	status = "okay";
+	compatible = "elan,ekth6a12nay";
 
-	compatible = "hid-over-i2c";
-	reg = <0x10>;
-	interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&touchscreen_pins>;
 
-	post-power-on-delay-ms = <10>;
-	hid-descr-addr = <0x0001>;
+	vcc33-supply = <&pp3300_alw>;
 };
 
 
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts
index 6641b087e7c5f3a957e43ac985137dfd84ac7878..7874c9a20e124c65ace3f90e2ec5bcaf59b69c40 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel-sku7.dts
@@ -14,16 +14,12 @@ / {
 };
 
 &touchscreen {
-	status = "okay";
+	compatible = "elan,ekth6a12nay";
 
-	compatible = "hid-over-i2c";
-	reg = <0x10>;
-	interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&touchscreen_pins>;
 
-	post-power-on-delay-ms = <10>;
-	hid-descr-addr = <0x0001>;
+	vcc33-supply = <&pp3300_alw>;
 };
 
 

---
base-commit: eefa7a9c069908412f8f5d15833901d1b46ae1b2
change-id: 20241018-post-reset-ac66b0351613

Best regards,
-- 
Hsin-Te Yuan <yuanhsinte at chromium.org>



From hchauhan at ventanamicro.com  Thu Dec 12 21:03:43 2024
From: hchauhan at ventanamicro.com (Himanshu Chauhan)
Date: Fri, 13 Dec 2024 10:33:43 +0530
Subject: [PATCH v3 3/4] drivers: firmware: add riscv SSE support
In-Reply-To: <20241206163102.843505-4-cleger@rivosinc.com>
References: <20241206163102.843505-1-cleger@rivosinc.com>
 <20241206163102.843505-4-cleger@rivosinc.com>
Message-ID: <Z1vALzeks+6Fkf9/@ventana>

Hi Clement,

On Fri, Dec 06, 2024 at 05:30:59PM +0100, Cl?ment L?ger wrote:
> Add driver level interface to use RISC-V SSE arch support. This interface
> allows registering SSE handlers, and receive them. This will be used by
> PMU and GHES driver.
> 
> Signed-off-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
> Co-developed-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
> Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
> ---
>  MAINTAINERS                        |  14 +
>  drivers/firmware/Kconfig           |   1 +
>  drivers/firmware/Makefile          |   1 +
>  drivers/firmware/riscv/Kconfig     |  15 +
>  drivers/firmware/riscv/Makefile    |   3 +
>  drivers/firmware/riscv/riscv_sse.c | 691 +++++++++++++++++++++++++++++
>  include/linux/riscv_sse.h          |  56 +++
>  7 files changed, 781 insertions(+)
>  create mode 100644 drivers/firmware/riscv/Kconfig
>  create mode 100644 drivers/firmware/riscv/Makefile
>  create mode 100644 drivers/firmware/riscv/riscv_sse.c
>  create mode 100644 include/linux/riscv_sse.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 686109008d8e..a3ddde7fe9fb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -20125,6 +20125,13 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
>  F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
>  F:	drivers/iommu/riscv/
>  
> +RISC-V FIRMWARE DRIVERS
> +M:	Conor Dooley <conor at kernel.org>
> +L:	linux-riscv at lists.infradead.org
> +S:	Maintained
> +T:	git git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git
> +F:	drivers/firmware/riscv/*
> +
>  RISC-V MICROCHIP FPGA SUPPORT
>  M:	Conor Dooley <conor.dooley at microchip.com>
>  M:	Daire McNamara <daire.mcnamara at microchip.com>
> @@ -20177,6 +20184,13 @@ F:	drivers/perf/riscv_pmu.c
>  F:	drivers/perf/riscv_pmu_legacy.c
>  F:	drivers/perf/riscv_pmu_sbi.c
>  
> +RISC-V SSE DRIVER
> +M:	Cl?ment L?ger <cleger at rivosinc.com>
> +L:	linux-riscv at lists.infradead.org
> +S:	Maintained
> +F:	drivers/firmware/riscv/riscv_sse.c
> +F:	include/linux/riscv_sse.h
> +

I request you to add me as a reviewer to these SSE files.
Himanshu Chauhan <himanshu at thechauhan.dev>

Thanks
Regards
Himanshu

>  RISC-V THEAD SoC SUPPORT
>  M:	Drew Fustini <drew at pdp7.com>
>  M:	Guo Ren <guoren at kernel.org>
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> index 71d8b26c4103..9e996a1fd511 100644
> --- a/drivers/firmware/Kconfig
> +++ b/drivers/firmware/Kconfig
> @@ -267,6 +267,7 @@ source "drivers/firmware/meson/Kconfig"
>  source "drivers/firmware/microchip/Kconfig"
>  source "drivers/firmware/psci/Kconfig"
>  source "drivers/firmware/qcom/Kconfig"
> +source "drivers/firmware/riscv/Kconfig"
>  source "drivers/firmware/smccc/Kconfig"
>  source "drivers/firmware/tegra/Kconfig"
>  source "drivers/firmware/xilinx/Kconfig"
> diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
> index 7a8d486e718f..c0f5009949a8 100644
> --- a/drivers/firmware/Makefile
> +++ b/drivers/firmware/Makefile
> @@ -33,6 +33,7 @@ obj-y				+= efi/
>  obj-y				+= imx/
>  obj-y				+= psci/
>  obj-y				+= qcom/
> +obj-y				+= riscv/
>  obj-y				+= smccc/
>  obj-y				+= tegra/
>  obj-y				+= xilinx/
> diff --git a/drivers/firmware/riscv/Kconfig b/drivers/firmware/riscv/Kconfig
> new file mode 100644
> index 000000000000..8056ed3262d9
> --- /dev/null
> +++ b/drivers/firmware/riscv/Kconfig
> @@ -0,0 +1,15 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +menu "Risc-V Specific firmware drivers"
> +depends on RISCV
> +
> +config RISCV_SSE
> +	bool "Enable SBI Supervisor Software Events support"
> +	depends on RISCV_SBI
> +	default y
> +	help
> +	  The Supervisor Software Events support allow the SBI to deliver
> +	  NMI-like notifications to the supervisor mode software. When enable,
> +	  this option provides support to register callbacks on specific SSE
> +	  events.
> +
> +endmenu
> diff --git a/drivers/firmware/riscv/Makefile b/drivers/firmware/riscv/Makefile
> new file mode 100644
> index 000000000000..4ccfcbbc28ea
> --- /dev/null
> +++ b/drivers/firmware/riscv/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_RISCV_SSE)		+= riscv_sse.o
> diff --git a/drivers/firmware/riscv/riscv_sse.c b/drivers/firmware/riscv/riscv_sse.c
> new file mode 100644
> index 000000000000..c165e32cc9a5
> --- /dev/null
> +++ b/drivers/firmware/riscv/riscv_sse.c
> @@ -0,0 +1,691 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2024 Rivos Inc.
> + */
> +
> +#define pr_fmt(fmt) "sse: " fmt
> +
> +#include <linux/cpu.h>
> +#include <linux/cpuhotplug.h>
> +#include <linux/cpu_pm.h>
> +#include <linux/hardirq.h>
> +#include <linux/list.h>
> +#include <linux/percpu-defs.h>
> +#include <linux/reboot.h>
> +#include <linux/riscv_sse.h>
> +#include <linux/slab.h>
> +
> +#include <asm/sbi.h>
> +#include <asm/sse.h>
> +
> +struct sse_event {
> +	struct list_head list;
> +	u32 evt;
> +	u32 priority;
> +	sse_event_handler *handler;
> +	void *handler_arg;
> +	bool is_enabled;
> +	/* Only valid for global events */
> +	unsigned int cpu;
> +
> +	union {
> +		struct sse_registered_event *global;
> +		struct sse_registered_event __percpu *local;
> +	};
> +};
> +
> +static int sse_hp_state;
> +static bool sse_available;
> +static DEFINE_SPINLOCK(events_list_lock);
> +static LIST_HEAD(events);
> +static DEFINE_MUTEX(sse_mutex);
> +
> +struct sse_registered_event {
> +	struct sse_event_arch_data arch;
> +	struct sse_event *evt;
> +	unsigned long attr_buf;
> +};
> +
> +void sse_handle_event(struct sse_event_arch_data *arch_event,
> +		      struct pt_regs *regs)
> +{
> +	int ret;
> +	struct sse_registered_event *reg_evt =
> +		container_of(arch_event, struct sse_registered_event, arch);
> +	struct sse_event *evt = reg_evt->evt;
> +
> +	ret = evt->handler(evt->evt, evt->handler_arg, regs);
> +	if (ret)
> +		pr_warn("event %x handler failed with error %d\n", evt->evt,
> +			ret);
> +}
> +
> +static bool sse_event_is_global(u32 evt)
> +{
> +	return !!(evt & SBI_SSE_EVENT_GLOBAL);
> +}
> +
> +static
> +struct sse_event *sse_event_get(u32 evt)
> +{
> +	struct sse_event *sse_evt = NULL, *tmp;
> +
> +	scoped_guard(spinlock, &events_list_lock) {
> +		list_for_each_entry(tmp, &events, list) {
> +			if (tmp->evt == evt) {
> +				return sse_evt;
> +			}
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +static phys_addr_t sse_event_get_phys(struct sse_registered_event *reg_evt,
> +				      void *addr)
> +{
> +	phys_addr_t phys;
> +
> +	if (sse_event_is_global(reg_evt->evt->evt))
> +		phys = virt_to_phys(addr);
> +	else
> +		phys = per_cpu_ptr_to_phys(addr);
> +
> +	return phys;
> +}
> +
> +static int sse_sbi_event_func(struct sse_event *event, unsigned long func)
> +{
> +	struct sbiret ret;
> +	u32 evt = event->evt;
> +
> +	ret = sbi_ecall(SBI_EXT_SSE, func, evt, 0, 0, 0, 0, 0);
> +	if (ret.error)
> +		pr_debug("Failed to execute func %lx, event %x, error %ld\n",
> +			 func, evt, ret.error);
> +
> +	return sbi_err_map_linux_errno(ret.error);
> +}
> +
> +static int sse_sbi_disable_event(struct sse_event *event)
> +{
> +	return sse_sbi_event_func(event, SBI_SSE_EVENT_DISABLE);
> +}
> +
> +static int sse_sbi_enable_event(struct sse_event *event)
> +{
> +	return sse_sbi_event_func(event, SBI_SSE_EVENT_ENABLE);
> +}
> +
> +static int sse_event_attr_get_no_lock(struct sse_registered_event *reg_evt,
> +				      unsigned long attr_id, unsigned long *val)
> +{
> +	struct sbiret sret;
> +	u32 evt = reg_evt->evt->evt;
> +	unsigned long phys;
> +
> +	phys = sse_event_get_phys(reg_evt, &reg_evt->attr_buf);
> +
> +	sret = sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_ATTR_READ, evt,
> +				     attr_id, 1, phys, 0, 0);
> +	if (sret.error) {
> +		pr_debug("Failed to get event %x attr %lx, error %ld\n", evt,
> +			 attr_id, sret.error);
> +		return sbi_err_map_linux_errno(sret.error);
> +	}
> +
> +	*val = reg_evt->attr_buf;
> +
> +	return 0;
> +}
> +
> +static int sse_event_attr_set_nolock(struct sse_registered_event *reg_evt,
> +				     unsigned long attr_id, unsigned long val)
> +{
> +	struct sbiret sret;
> +	u32 evt = reg_evt->evt->evt;
> +	unsigned long phys;
> +
> +	reg_evt->attr_buf = val;
> +	phys = sse_event_get_phys(reg_evt, &reg_evt->attr_buf);
> +
> +	sret = sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_ATTR_WRITE, evt,
> +				     attr_id, 1, phys, 0, 0);
> +	if (sret.error && sret.error != SBI_ERR_INVALID_STATE) {
> +		pr_debug("Failed to set event %x attr %lx, error %ld\n", evt,
> +			 attr_id, sret.error);
> +		return sbi_err_map_linux_errno(sret.error);
> +	}
> +
> +	return 0;
> +}
> +
> +static int sse_event_set_target_cpu_nolock(struct sse_event *event,
> +					   unsigned int cpu)
> +{
> +	unsigned int hart_id = cpuid_to_hartid_map(cpu);
> +	struct sse_registered_event *reg_evt = event->global;
> +	u32 evt = event->evt;
> +	bool was_enabled;
> +	int ret;
> +
> +	if (!sse_event_is_global(evt))
> +		return -EINVAL;
> +
> +	was_enabled = event->is_enabled;
> +	if (was_enabled)
> +		sse_sbi_disable_event(event);
> +	do {
> +		ret = sse_event_attr_set_nolock(reg_evt,
> +						SBI_SSE_ATTR_PREFERRED_HART,
> +						hart_id);
> +	} while (ret == -EINVAL);
> +
> +	if (ret == 0)
> +		event->cpu = cpu;
> +
> +	if (was_enabled)
> +		sse_sbi_enable_event(event);
> +
> +	return 0;
> +}
> +
> +int sse_event_set_target_cpu(struct sse_event *event, unsigned int cpu)
> +{
> +	int ret;
> +
> +	scoped_guard(mutex, &sse_mutex) {
> +		cpus_read_lock();
> +
> +		if (!cpu_online(cpu))
> +			return -EINVAL;
> +
> +		ret = sse_event_set_target_cpu_nolock(event, cpu);
> +
> +		cpus_read_unlock();
> +	}
> +
> +	return ret;
> +}
> +
> +static int sse_event_init_registered(unsigned int cpu,
> +				     struct sse_registered_event *reg_evt,
> +				     struct sse_event *event)
> +{
> +	reg_evt->evt = event;
> +	arch_sse_init_event(&reg_evt->arch, event->evt, cpu);
> +
> +	return 0;
> +}
> +
> +static void sse_event_free_registered(struct sse_registered_event *reg_evt)
> +{
> +	arch_sse_free_event(&reg_evt->arch);
> +}
> +
> +static int sse_event_alloc_global(struct sse_event *event)
> +{
> +	int err;
> +	struct sse_registered_event *reg_evt;
> +
> +	reg_evt = kzalloc(sizeof(*reg_evt), GFP_KERNEL);
> +	if (!reg_evt)
> +		return -ENOMEM;
> +
> +	event->global = reg_evt;
> +	err = sse_event_init_registered(smp_processor_id(), reg_evt,
> +					event);
> +	if (err)
> +		kfree(reg_evt);
> +
> +	return err;
> +}
> +
> +static int sse_event_alloc_local(struct sse_event *event)
> +{
> +	int err;
> +	unsigned int cpu, err_cpu;
> +	struct sse_registered_event *reg_evt;
> +	struct sse_registered_event __percpu *reg_evts;
> +
> +	reg_evts = alloc_percpu(struct sse_registered_event);
> +	if (!reg_evts)
> +		return -ENOMEM;
> +
> +	event->local = reg_evts;
> +
> +	for_each_possible_cpu(cpu) {
> +		reg_evt = per_cpu_ptr(reg_evts, cpu);
> +		err = sse_event_init_registered(cpu, reg_evt, event);
> +		if (err) {
> +			err_cpu = cpu;
> +			goto err_free_per_cpu;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_free_per_cpu:
> +	for_each_possible_cpu(cpu) {
> +		if (cpu == err_cpu)
> +			break;
> +		reg_evt = per_cpu_ptr(reg_evts, cpu);
> +		sse_event_free_registered(reg_evt);
> +	}
> +
> +	free_percpu(reg_evts);
> +
> +	return err;
> +}
> +
> +static struct sse_event *sse_event_alloc(u32 evt,
> +					 u32 priority,
> +					 sse_event_handler *handler, void *arg)
> +{
> +	int err;
> +	struct sse_event *event;
> +
> +	event = kzalloc(sizeof(*event), GFP_KERNEL);
> +	if (!event)
> +		return ERR_PTR(-ENOMEM);
> +
> +	event->evt = evt;
> +	event->priority = priority;
> +	event->handler_arg = arg;
> +	event->handler = handler;
> +
> +	if (sse_event_is_global(evt)) {
> +		err = sse_event_alloc_global(event);
> +		if (err)
> +			goto err_alloc_reg_evt;
> +	} else {
> +		err = sse_event_alloc_local(event);
> +		if (err)
> +			goto err_alloc_reg_evt;
> +	}
> +
> +	return event;
> +
> +err_alloc_reg_evt:
> +	kfree(event);
> +
> +	return ERR_PTR(err);
> +}
> +
> +static int sse_sbi_register_event(struct sse_event *event,
> +				  struct sse_registered_event *reg_evt)
> +{
> +	int ret;
> +
> +	ret = sse_event_attr_set_nolock(reg_evt, SBI_SSE_ATTR_PRIO,
> +					event->priority);
> +	if (ret)
> +		return ret;
> +
> +	return arch_sse_register_event(&reg_evt->arch);
> +}
> +
> +static int sse_event_register_local(struct sse_event *event)
> +{
> +	int ret;
> +	struct sse_registered_event *reg_evt = per_cpu_ptr(event->local,
> +							   smp_processor_id());
> +
> +	ret = sse_sbi_register_event(event, reg_evt);
> +	if (ret)
> +		pr_debug("Failed to register event %x: err %d\n", event->evt,
> +			 ret);
> +
> +	return ret;
> +}
> +
> +
> +static int sse_sbi_unregister_event(struct sse_event *event)
> +{
> +	return sse_sbi_event_func(event, SBI_SSE_EVENT_UNREGISTER);
> +}
> +
> +struct sse_per_cpu_evt {
> +	struct sse_event *event;
> +	unsigned long func;
> +	atomic_t error;
> +};
> +
> +static void sse_event_per_cpu_func(void *info)
> +{
> +	int ret;
> +	struct sse_per_cpu_evt *cpu_evt = info;
> +
> +	if (cpu_evt->func == SBI_SSE_EVENT_REGISTER)
> +		ret = sse_event_register_local(cpu_evt->event);
> +	else
> +		ret = sse_sbi_event_func(cpu_evt->event, cpu_evt->func);
> +
> +	if (ret)
> +		atomic_set(&cpu_evt->error, ret);
> +}
> +
> +static void sse_event_free(struct sse_event *event)
> +{
> +	unsigned int cpu;
> +	struct sse_registered_event *reg_evt;
> +
> +	if (sse_event_is_global(event->evt)) {
> +		sse_event_free_registered(event->global);
> +		kfree(event->global);
> +	} else {
> +		for_each_possible_cpu(cpu) {
> +			reg_evt = per_cpu_ptr(event->local, cpu);
> +			sse_event_free_registered(reg_evt);
> +		}
> +		free_percpu(event->local);
> +	}
> +
> +	kfree(event);
> +}
> +
> +int sse_event_enable(struct sse_event *event)
> +{
> +	int ret = 0;
> +	struct sse_per_cpu_evt cpu_evt;
> +
> +	scoped_guard(mutex, &sse_mutex) {
> +		cpus_read_lock();
> +		if (sse_event_is_global(event->evt)) {
> +			ret = sse_sbi_enable_event(event);
> +		} else {
> +			cpu_evt.event = event;
> +			atomic_set(&cpu_evt.error, 0);
> +			cpu_evt.func = SBI_SSE_EVENT_ENABLE;
> +			on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
> +			ret = atomic_read(&cpu_evt.error);
> +			if (ret) {
> +				cpu_evt.func = SBI_SSE_EVENT_DISABLE;
> +				on_each_cpu(sse_event_per_cpu_func, &cpu_evt,
> +					    1);
> +			}
> +		}
> +		cpus_read_unlock();
> +
> +		if (ret == 0)
> +			event->is_enabled = true;
> +	}
> +
> +	return ret;
> +}
> +
> +static void sse_events_mask(void)
> +{
> +	sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_HART_MASK, 0, 0, 0, 0, 0, 0);
> +}
> +
> +static void sse_events_unmask(void)
> +{
> +	sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_HART_UNMASK, 0, 0, 0, 0, 0, 0);
> +}
> +
> +static void sse_event_disable_nolock(struct sse_event *event)
> +{
> +	struct sse_per_cpu_evt cpu_evt;
> +
> +	if (sse_event_is_global(event->evt)) {
> +		sse_sbi_disable_event(event);
> +	} else {
> +		cpu_evt.event = event;
> +		cpu_evt.func = SBI_SSE_EVENT_DISABLE;
> +		on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
> +	}
> +}
> +
> +void sse_event_disable(struct sse_event *event)
> +{
> +	scoped_guard(mutex, &sse_mutex) {
> +		cpus_read_lock();
> +		sse_event_disable_nolock(event);
> +		event->is_enabled = false;
> +		cpus_read_unlock();
> +	}
> +}
> +
> +struct sse_event *sse_event_register(u32 evt, u32 priority,
> +				     sse_event_handler *handler, void *arg)
> +{
> +	struct sse_per_cpu_evt cpu_evt;
> +	struct sse_event *event;
> +	int ret = 0;
> +
> +	if (!sse_available)
> +		return ERR_PTR(-EOPNOTSUPP);
> +
> +	mutex_lock(&sse_mutex);
> +	if (sse_event_get(evt)) {
> +		pr_debug("Event %x already registered\n", evt);
> +		ret = -EEXIST;
> +		goto out_unlock;
> +	}
> +
> +	event = sse_event_alloc(evt, priority, handler, arg);
> +	if (IS_ERR(event)) {
> +		ret = PTR_ERR(event);
> +		goto out_unlock;
> +	}
> +
> +	cpus_read_lock();
> +	if (sse_event_is_global(evt)) {
> +		unsigned long preferred_hart;
> +
> +		ret = sse_event_attr_get_no_lock(event->global,
> +						 SBI_SSE_ATTR_PREFERRED_HART,
> +						 &preferred_hart);
> +		if (ret)
> +			goto err_event_free;
> +		event->cpu = riscv_hartid_to_cpuid(preferred_hart);
> +
> +		ret = sse_sbi_register_event(event, event->global);
> +		if (ret)
> +			goto err_event_free;
> +
> +	} else {
> +		cpu_evt.event = event;
> +		atomic_set(&cpu_evt.error, 0);
> +		cpu_evt.func = SBI_SSE_EVENT_REGISTER;
> +		on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
> +		ret = atomic_read(&cpu_evt.error);
> +		if (ret) {
> +			cpu_evt.func = SBI_SSE_EVENT_UNREGISTER;
> +			on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
> +			goto err_event_free;
> +		}
> +	}
> +	cpus_read_unlock();
> +
> +	scoped_guard(spinlock, &events_list_lock)
> +		list_add(&event->list, &events);
> +
> +	mutex_unlock(&sse_mutex);
> +
> +	return event;
> +
> +err_event_free:
> +	cpus_read_unlock();
> +	sse_event_free(event);
> +out_unlock:
> +	mutex_unlock(&sse_mutex);
> +
> +	return ERR_PTR(ret);
> +}
> +
> +static void sse_event_unregister_nolock(struct sse_event *event)
> +{
> +	struct sse_per_cpu_evt cpu_evt;
> +
> +	if (sse_event_is_global(event->evt)) {
> +		sse_sbi_unregister_event(event);
> +	} else {
> +		cpu_evt.event = event;
> +		cpu_evt.func = SBI_SSE_EVENT_UNREGISTER;
> +		on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
> +	}
> +}
> +
> +void sse_event_unregister(struct sse_event *event)
> +{
> +	scoped_guard(mutex, &sse_mutex) {
> +		cpus_read_lock();
> +		sse_event_unregister_nolock(event);
> +		cpus_read_unlock();
> +
> +		scoped_guard(spinlock, &events_list_lock)
> +			list_del(&event->list);
> +
> +		sse_event_free(event);
> +	}
> +}
> +
> +static int sse_cpu_online(unsigned int cpu)
> +{
> +	struct sse_event *sse_evt;
> +
> +	scoped_guard(spinlock, &events_list_lock) {
> +		list_for_each_entry(sse_evt, &events, list) {
> +			if (sse_event_is_global(sse_evt->evt))
> +				continue;
> +
> +			sse_event_register_local(sse_evt);
> +			if (sse_evt->is_enabled)
> +				sse_sbi_enable_event(sse_evt);
> +		}
> +	}
> +
> +	/* Ready to handle events. Unmask SSE. */
> +	sse_events_unmask();
> +
> +	return 0;
> +}
> +
> +static int sse_cpu_teardown(unsigned int cpu)
> +{
> +	unsigned int next_cpu;
> +	struct sse_event *sse_evt;
> +
> +	/* Mask the sse events */
> +	sse_events_mask();
> +
> +	scoped_guard(spinlock, &events_list_lock) {
> +		list_for_each_entry(sse_evt, &events, list) {
> +			if (!sse_event_is_global(sse_evt->evt)) {
> +
> +				if (sse_evt->is_enabled)
> +					sse_sbi_disable_event(sse_evt);
> +
> +				sse_sbi_unregister_event(sse_evt);
> +				continue;
> +			}
> +
> +			if (sse_evt->cpu != smp_processor_id())
> +				continue;
> +
> +			/* Update destination hart for global event */
> +			next_cpu = cpumask_any_but(cpu_online_mask, cpu);
> +			sse_event_set_target_cpu_nolock(sse_evt, next_cpu);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static void sse_reset(void)
> +{
> +	struct sse_event *event = NULL;
> +
> +	list_for_each_entry(event, &events, list) {
> +		sse_event_disable_nolock(event);
> +		sse_event_unregister_nolock(event);
> +	}
> +}
> +
> +static int sse_pm_notifier(struct notifier_block *nb, unsigned long action,
> +			   void *data)
> +{
> +	WARN_ON_ONCE(preemptible());
> +
> +	switch (action) {
> +	case CPU_PM_ENTER:
> +		sse_events_mask();
> +		break;
> +	case CPU_PM_EXIT:
> +	case CPU_PM_ENTER_FAILED:
> +		sse_events_unmask();
> +		break;
> +	default:
> +		return NOTIFY_DONE;
> +	}
> +
> +	return NOTIFY_OK;
> +}
> +
> +static struct notifier_block sse_pm_nb = {
> +	.notifier_call = sse_pm_notifier,
> +};
> +
> +/*
> + * Mask all CPUs and unregister all events on panic, reboot or kexec.
> + */
> +static int sse_reboot_notifier(struct notifier_block *nb, unsigned long action,
> +				void *data)
> +{
> +	cpuhp_remove_state(sse_hp_state);
> +
> +	sse_reset();
> +
> +	return NOTIFY_OK;
> +}
> +
> +static struct notifier_block sse_reboot_nb = {
> +	.notifier_call = sse_reboot_notifier,
> +};
> +
> +static int __init sse_init(void)
> +{
> +	int cpu, ret;
> +
> +	if (sbi_probe_extension(SBI_EXT_SSE) <= 0) {
> +		pr_err("Missing SBI SSE extension\n");
> +		return -EOPNOTSUPP;
> +	}
> +	pr_info("SBI SSE extension detected\n");
> +
> +	for_each_possible_cpu(cpu)
> +		INIT_LIST_HEAD(&events);
> +
> +	ret = cpu_pm_register_notifier(&sse_pm_nb);
> +	if (ret) {
> +		pr_warn("Failed to register CPU PM notifier...\n");
> +		return ret;
> +	}
> +
> +	ret = register_reboot_notifier(&sse_reboot_nb);
> +	if (ret) {
> +		pr_warn("Failed to register reboot notifier...\n");
> +		goto remove_cpupm;
> +	}
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "riscv/sse:online",
> +				sse_cpu_online, sse_cpu_teardown);
> +	if (ret < 0)
> +		goto remove_reboot;
> +
> +	sse_hp_state = ret;
> +	sse_available = true;
> +
> +	return 0;
> +
> +remove_reboot:
> +	unregister_reboot_notifier(&sse_reboot_nb);
> +
> +remove_cpupm:
> +	cpu_pm_unregister_notifier(&sse_pm_nb);
> +
> +	return ret;
> +}
> +arch_initcall(sse_init);
> diff --git a/include/linux/riscv_sse.h b/include/linux/riscv_sse.h
> new file mode 100644
> index 000000000000..c73184074b8c
> --- /dev/null
> +++ b/include/linux/riscv_sse.h
> @@ -0,0 +1,56 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2024 Rivos Inc.
> + */
> +
> +#ifndef __LINUX_RISCV_SSE_H
> +#define __LINUX_RISCV_SSE_H
> +
> +#include <linux/types.h>
> +#include <linux/linkage.h>
> +
> +struct sse_event;
> +struct pt_regs;
> +
> +typedef int (sse_event_handler)(u32 event_num, void *arg, struct pt_regs *regs);
> +
> +#ifdef CONFIG_RISCV_SSE
> +
> +struct sse_event *sse_event_register(u32 event_num, u32 priority,
> +				     sse_event_handler *handler, void *arg);
> +
> +void sse_event_unregister(struct sse_event *evt);
> +
> +int sse_event_set_target_cpu(struct sse_event *sse_evt, unsigned int cpu);
> +
> +int sse_event_enable(struct sse_event *sse_evt);
> +
> +void sse_event_disable(struct sse_event *sse_evt);
> +
> +#else
> +static inline struct sse_event *sse_event_register(u32 event_num, u32 priority,
> +						   sse_event_handler *handler,
> +						   void *arg)
> +{
> +	return ERR_PTR(-EOPNOTSUPP);
> +}
> +
> +static inline void sse_event_unregister(struct sse_event *evt) {}
> +
> +static inline int sse_event_set_target_cpu(struct sse_event *sse_evt,
> +					   unsigned int cpu)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int sse_event_enable(struct sse_event *sse_evt)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline void sse_event_disable(struct sse_event *sse_evt) {}
> +
> +
> +#endif
> +
> +#endif /* __LINUX_RISCV_SSE_H */
> -- 
> 2.45.2
> 


From andrew at codeconstruct.com.au  Thu Dec 12 21:07:52 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Fri, 13 Dec 2024 15:37:52 +1030
Subject: [PATCH v3 0/6] Introduce ASPEED AST27XX BMC SoC
In-Reply-To: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
Message-ID: <5d91b7a7169e6db27b2493213d0df2b77699a49e.camel@codeconstruct.com.au>

Hi Kevin,

On Thu, 2024-12-12 at 23:52 +0800, Kevin Chen wrote:
> ---
> v3:
> ? - Split clk and reset driver to other commits, which are in series
> of
> ??? "Add support for AST2700 clk driver".
> ? - For BMC console by UART12, add uart12 using ASPEED INTC
> architecture.
> 
> aspeed,ast2700-intc.yaml
> ? - Add minItems to 1 to fix the warning by "make dtbs_check W=1".
> ? - Add intc1 into example.
> 
> Kconfig.platforms
> ? - Remove MACH_ASPEED_G7.
> 
> Kevin Chen (6):
> ? dt-bindings: interrupt-controller: Refine size/interrupt-cell
> usage.
> ? dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
> ? arm64: aspeed: Add support for ASPEED AST27XX BMC SoC
> ? arm64: dts: aspeed: Add initial AST27XX device tree
> ? arm64: dts: aspeed: Add initial AST2700 EVB device tree
> ? arm64: defconfig: Add ASPEED AST2700 family support

Do you mind sending a v4, because I received a confusing arrangement of
patches:

[PATCH v3 1/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
[PATCH v3 1/6] dt-bindings: interrupt-controller: Refine size/interrupt-cell usage.
[PATCH v3 2/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
[PATCH v3 2/6] dt-bindings: interrupt-controller: Fix the size-cells in ast2700-intc
...

Where the content of 

   [PATCH v3 1/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
   
and

   [PATCH v3 2/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
   
Differs, as does the content of

   [PATCH v3 1/6] dt-bindings: interrupt-controller: Refine size/interrupt-cell usage.
   
and

   [PATCH v3 2/6] dt-bindings: interrupt-controller: Fix the size-cells in ast2700-intc

Despite sounding like they might have the same intent

Andrew


From yuanhsinte at chromium.org  Thu Dec 12 21:27:48 2024
From: yuanhsinte at chromium.org (Hsin-Te Yuan)
Date: Fri, 13 Dec 2024 05:27:48 +0000
Subject: [PATCH v3 2/2] arm64: dts: mediatek: mt8183: willow: Support
 second source touchscreen
In-Reply-To: <20241213-touchscreen-v3-0-7c1f670913f9@chromium.org>
References: <20241213-touchscreen-v3-0-7c1f670913f9@chromium.org>
Message-ID: <20241213-touchscreen-v3-2-7c1f670913f9@chromium.org>

Some willow devices use second source touchscreen.

Fixes: f006bcf1c972 ("arm64: dts: mt8183: Add kukui-jacuzzi-willow board")
Signed-off-by: Hsin-Te Yuan <yuanhsinte at chromium.org>
---
 .../boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi    | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi
index 76d33540166f900c99c419c4f97ca0a56cf658f5..c942e461a177efe1e711a978c3bfb9f852f1b0ee 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi
@@ -6,6 +6,21 @@
 /dts-v1/;
 #include "mt8183-kukui-jacuzzi.dtsi"
 
+&i2c0 {
+	touchscreen at 40 {
+		compatible = "hid-over-i2c";
+		reg = <0x40>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&touchscreen_pins>;
+
+		interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>;
+
+		post-power-on-delay-ms = <70>;
+		hid-descr-addr = <0x0001>;
+	};
+};
+
 &i2c2 {
 	trackpad at 2c {
 		compatible = "hid-over-i2c";

-- 
2.47.1.613.gc27f4b7a9f-goog



From andrew at codeconstruct.com.au  Thu Dec 12 21:28:28 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Fri, 13 Dec 2024 15:58:28 +1030
Subject: [PATCH v1 0/4] Revise Meta (Facebook) Minerva BMC
In-Reply-To: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
References: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
Message-ID: <173406770843.422541.3788323988670647121.b4-ty@codeconstruct.com.au>

On Thu, 12 Dec 2024 21:32:22 +0800, Yang Chen wrote:
> Revise the linux device tree entry related to Meta (Facebook) Minerva
> specific devices connected to BMC (AST2600) SoC.
> 
> Base on:
> https://lore.kernel.org/all/172722509817.374662.7338401100529556748.b4-ty at codeconstruct.com.au/
> 
> Yang Chen (4):
>   ARM: dts: aspeed: minerva: add i/o expanders on bus 0
>   ARM: dts: aspeed: minerva: add i/o expanders on each FCB
>   ARM: dts: aspeed: minerva: add bmc ready led setting
>   ARM: dts: aspeed: minerva: add second source RTC
> 
> [...]

Thanks, I've applied this to be picked up through the BMC tree.

--
Andrew Jeffery <andrew at codeconstruct.com.au>



From wenst at chromium.org  Thu Dec 12 21:26:55 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Fri, 13 Dec 2024 13:26:55 +0800
Subject: [PATCH 1/2] arm64: dts: mediatek: mt8183: Disable DPI display
 output by default
In-Reply-To: <173381930438.18469.15845444123528821647.b4-ty@collabora.com>
References: <20241025075630.3917458-1-wenst@chromium.org> <173381930438.18469.15845444123528821647.b4-ty@collabora.com>
Message-ID: <CAGXv+5HY4s+0Yn35BezRWLKPnYkURhgg59eSVED1_6Z3QyQHiw@mail.gmail.com>

On Tue, Dec 10, 2024 at 4:28?PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> On Fri, 25 Oct 2024 15:56:27 +0800, Chen-Yu Tsai wrote:
> > This reverts commit 377548f05bd0905db52a1d50e5b328b9b4eb049d.
> >
> > Most SoC dtsi files have the display output interfaces disabled by
> > default, and only enabled on boards that utilize them. The MT8183
> > has it backwards: the display outputs are left enabled by default,
> > and only disabled at the board level.
> >
> > [...]
>
> Applied to v6.13-next/dts64, thanks!
>
> [1/2] arm64: dts: mediatek: mt8183: Disable DPI display output by default
>       commit: 93a680af46436780fd64f4e856a4cfa8b393be6e
> [2/2] arm64: dts: mediatek: mt8183: Disable DSI display output by default
>       commit: 26f6e91fa29a58fdc76b47f94f8f6027944a490c

Thanks! It seems you haven't updated the for-next branch, so it isn't
appearing in linux-next yet.

ChenYu


From yuanhsinte at chromium.org  Thu Dec 12 21:27:46 2024
From: yuanhsinte at chromium.org (Hsin-Te Yuan)
Date: Fri, 13 Dec 2024 05:27:46 +0000
Subject: [PATCH v3 0/2] Adding second source touchscreen used by some
 mt8183 devices
Message-ID: <20241213-touchscreen-v3-0-7c1f670913f9@chromium.org>


---
Changes in v3:
- Split from the v2 series
- Link to v2: https://lore.kernel.org/r/20241018-post-reset-v2-0-28d539d79e18 at chromium.org
Changes in v2:
- Add second source touchscreen patches since they should based on the
  first patch of this series.
- Link to v1: https://lore.kernel.org/r/20241018-post-reset-v1-0-5aadb7550037 at chromium.org

Signed-off-by: Hsin-Te Yuan <yuanhsinte at chromium.org>

---
Hsin-Te Yuan (2):
      arm64: dts: mediatek: mt8183: kenzo: Support second source touchscreen
      arm64: dts: mediatek: mt8183: willow: Support second source touchscreen

 .../boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts      | 15 +++++++++++++++
 .../boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi    | 15 +++++++++++++++
 2 files changed, 30 insertions(+)
---
base-commit: eefa7a9c069908412f8f5d15833901d1b46ae1b2
change-id: 20241213-touchscreen-fca4a52bff58

Best regards,
-- 
Hsin-Te Yuan <yuanhsinte at chromium.org>



From yuanhsinte at chromium.org  Thu Dec 12 21:27:47 2024
From: yuanhsinte at chromium.org (Hsin-Te Yuan)
Date: Fri, 13 Dec 2024 05:27:47 +0000
Subject: [PATCH v3 1/2] arm64: dts: mediatek: mt8183: kenzo: Support second
 source touchscreen
In-Reply-To: <20241213-touchscreen-v3-0-7c1f670913f9@chromium.org>
References: <20241213-touchscreen-v3-0-7c1f670913f9@chromium.org>
Message-ID: <20241213-touchscreen-v3-1-7c1f670913f9@chromium.org>

Some kenzo devices use second source touchscreen.

Fixes: 0a9cefe21aec ("arm64: dts: mt8183: Add kukui-jacuzzi-kenzo board")
Signed-off-by: Hsin-Te Yuan <yuanhsinte at chromium.org>
---
 .../boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts      | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
index e8241587949b2bc238ffa85f8fa6b6ca78b1d6f5..561770fcf69e66341c080687e2efaa6e98c550a8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
@@ -12,3 +12,18 @@ / {
 	chassis-type = "laptop";
 	compatible = "google,juniper-sku17", "google,juniper", "mediatek,mt8183";
 };
+
+&i2c0 {
+	touchscreen at 40 {
+		compatible = "hid-over-i2c";
+		reg = <0x40>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&touchscreen_pins>;
+
+		interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>;
+
+		post-power-on-delay-ms = <70>;
+		hid-descr-addr = <0x0001>;
+	};
+};

-- 
2.47.1.613.gc27f4b7a9f-goog



From shijie at os.amperecomputing.com  Thu Dec 12 21:30:49 2024
From: shijie at os.amperecomputing.com (Huang Shijie)
Date: Fri, 13 Dec 2024 13:30:49 +0800
Subject: [PATCH v4 1/2 fix] arm64: refactor the rodata=xxx
In-Reply-To: <20241212082426.4110-2-shijie@os.amperecomputing.com>
References: <20241212082426.4110-2-shijie@os.amperecomputing.com>
Message-ID: <20241213053049.7592-1-shijie@os.amperecomputing.com>

As per admin guide documentation, "rodata=on" should be the default on
platforms. Documentation/admin-guide/kernel-parameters.txt describes
these options as

   rodata=         [KNL,EARLY]
           on      Mark read-only kernel memory as read-only (default).
           off     Leave read-only kernel memory writable for debugging.
           full    Mark read-only kernel memory and aliases as read-only
                   [arm64]

But on arm64 platform, "rodata=full" is the default instead. This patch
implements the following changes.

 - Make "rodata=on" behaviour same as the original "rodata=full"
 - Make "rodata=noalias" (new) behaviour same as the original "rodata=on"
 - Drop the original "rodata=full"
 - Add comment for arch_parse_debug_rodata()
 - Update kernel-parameters.txt as required

After this patch, the "rodata=on" will be the default on arm64 platform
as well.

Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
---
Add more descriptions for "noalias":
  It is not a security feature yet.
---
 .../admin-guide/kernel-parameters.txt         |  3 ++-
 arch/arm64/include/asm/setup.h                | 27 +++++++++++++++++--
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index a22b7e621007..f5db01eecbd3 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5901,7 +5901,8 @@
 	rodata=		[KNL,EARLY]
 		on	Mark read-only kernel memory as read-only (default).
 		off	Leave read-only kernel memory writable for debugging.
-		full	Mark read-only kernel memory and aliases as read-only
+		noalias	Use more block mappings,may have better performance.
+			But this is not a security feature.
 		        [arm64]
 
 	rockchip.usb_uart
diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
index ba269a7a3201..0ef57d19fc2a 100644
--- a/arch/arm64/include/asm/setup.h
+++ b/arch/arm64/include/asm/setup.h
@@ -13,6 +13,29 @@
 extern phys_addr_t __fdt_pointer __initdata;
 extern u64 __cacheline_aligned boot_args[4];
 
+/*
+ * rodata=on (default)
+ *
+ *    This applies read-only attributes to VM areas and to the linear
+ *    alias of the backing pages as well. This prevents code or read-
+ *    only data from being modified (inadvertently or intentionally),
+ *    via another mapping for the same memory page.
+ *
+ *    But this might cause linear map region to be mapped down to base
+ *    pages, which may adversely affect performance in some cases.
+ *
+ * rodata=off
+ *
+ *    This provides more block mappings and contiguous hints for linear
+ *    map region which would minimize TLB footprint. This also leaves
+ *    read-only kernel memory writable for debugging.
+ *
+ * rodata=noalias
+ *
+ *    This provides more block mappings and contiguous hints for linear
+ *    map region which would minimize TLB footprint. This is not a
+ *    security feature yet.
+ */
 static inline bool arch_parse_debug_rodata(char *arg)
 {
 	extern bool rodata_enabled;
@@ -21,7 +44,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
 	if (!arg)
 		return false;
 
-	if (!strcmp(arg, "full")) {
+	if (!strcmp(arg, "on")) {
 		rodata_enabled = rodata_full = true;
 		return true;
 	}
@@ -31,7 +54,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
 		return true;
 	}
 
-	if (!strcmp(arg, "on")) {
+	if (!strcmp(arg, "noalias")) {
 		rodata_enabled = true;
 		rodata_full = false;
 		return true;
-- 
2.40.1



From lcherian at marvell.com  Thu Dec 12 21:50:01 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Fri, 13 Dec 2024 11:20:01 +0530
Subject: [PATCH v12 5/8] coresight: tmc: Add support for reading crash
 data
In-Reply-To: <b56cbd79-61a4-49c3-82ce-12ca55a40991@arm.com>
References: <20241129084714.3057080-1-lcherian@marvell.com>
 <20241129084714.3057080-6-lcherian@marvell.com>
 <b56cbd79-61a4-49c3-82ce-12ca55a40991@arm.com>
Message-ID: <20241213055001.GA1224111@hyd1403.caveonetworks.com>

Hi Suzuki,

On 2024-12-05 at 22:31:51, Suzuki K Poulose (suzuki.poulose at arm.com) wrote:
> Hi Linu,
> 
> On 29/11/2024 08:47, Linu Cherian wrote:
> > * Add support for reading crashdata using special device files.
> >    The special device files /dev/crash_tmc_xxx would be available
> >    for read file operation only when the crash data is valid.
> > 
> > * User can read the crash data as below
> > 
> >    For example, for reading crash data from tmc_etf sink
> > 
> >    #dd if=/dev/crash_tmc_etfXX of=~/cstrace.bin
> > 
> 
> Unfortunately there is still a bug that I picked up, see below for the
> barrier_packet insertion.
> 
> > Signed-off-by: Anil Kumar Reddy <areddy3 at marvell.com>
> > Signed-off-by: Tanmay Jagdale <tanmay at marvell.com>
> > Signed-off-by: Linu Cherian <lcherian at marvell.com>
> > ---
> >   .../hwtracing/coresight/coresight-tmc-core.c  | 231 +++++++++++++++++-
> >   .../hwtracing/coresight/coresight-tmc-etr.c   |  19 +-
> >   drivers/hwtracing/coresight/coresight-tmc.h   |  13 +-
> >   3 files changed, 260 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> > index 1e3938ec12cb..5f3789314c4d 100644
> > --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> > @@ -105,6 +105,151 @@ u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata)
> >   	return mask;
> >   }
> > +bool is_tmc_crashdata_valid(struct tmc_drvdata *drvdata)
> > +{
> > +	struct tmc_crash_metadata *mdata;
> > +
> > +	if (!tmc_has_reserved_buffer(drvdata) ||
> > +	    !tmc_has_crash_mdata_buffer(drvdata))
> > +		return false;
> > +
> > +	mdata = drvdata->crash_mdata.vaddr;
> > +
> > +	/* Check version match */
> > +	if (mdata->version != CS_CRASHDATA_VERSION)
> > +		return false;
> > +
> > +	/* Check for valid metadata */
> > +	if (!mdata->valid) {
> > +		dev_dbg(&drvdata->csdev->dev,
> > +			"Data invalid in tmc crash metadata\n");
> > +		return false;
> > +	}
> > +
> > +	/*
> > +	 * Buffer address given by metadata for retrieval of trace data
> > +	 * from previous boot is expected to be same as the reserved
> > +	 * trace buffer memory region provided through DTS
> > +	 */
> > +	if (drvdata->resrv_buf.paddr != mdata->trace_paddr) {
> > +		dev_dbg(&drvdata->csdev->dev,
> > +			"Trace buffer address of previous boot invalid\n");
> > +		return false;
> > +	}
> > +
> > +	/* Check data integrity of metadata */
> > +	if (mdata->crc32_mdata != find_crash_metadata_crc(mdata)) {
> > +		dev_dbg(&drvdata->csdev->dev,
> > +			"CRC mismatch in tmc crash metadata\n");
> > +		return false;
> > +	}
> > +	/* Check data integrity of tracedata */
> > +	if (mdata->crc32_tdata != find_crash_tracedata_crc(drvdata, mdata)) {
> > +		dev_dbg(&drvdata->csdev->dev,
> > +			"CRC mismatch in tmc crash tracedata\n");
> > +		return false;
> > +	}
> > +
> > +	return true;
> > +}
> > +
> > +int tmc_read_prepare_crashdata(struct tmc_drvdata *drvdata)
> > +{
> > +	int ret = 0;
> > +	u32 status, size;
> > +	u64 rrp, rwp, dba;
> > +	unsigned long flags;
> > +	struct tmc_resrv_buf *rbuf;
> > +	struct tmc_crash_metadata *mdata;
> > +
> > +	spin_lock_irqsave(&drvdata->spinlock, flags);
> > +
> > +	if (drvdata->reading) {
> > +		ret = -EBUSY;
> > +		goto out;
> > +	}
> > +
> > +	if (!is_tmc_crashdata_valid(drvdata)) {
> > +		ret = -ENXIO;
> > +		goto out;
> > +	}
> > +
> > +	mdata = drvdata->crash_mdata.vaddr;
> > +	rbuf = &drvdata->resrv_buf;
> > +
> > +	rrp = mdata->tmc_rrp;
> > +	rwp = mdata->tmc_rwp;
> > +	dba = mdata->tmc_dba;
> > +	status = mdata->tmc_sts;
> > +	size = mdata->tmc_ram_size << 2;
> > +
> > +	/* Sync the buffer pointers */
> > +	rbuf->offset = rrp - dba;
> > +	if (status & TMC_STS_FULL)
> > +		rbuf->len = size;
> > +	else
> > +		rbuf->len = rwp - rrp;
> > +
> 
> I believe all of the above can be done one time probe and don't need to
> be repeated every time we do a read_prepare() ?

Ack. Will do that change.

> 
> 
> > +	/* Additional sanity checks for validating metadata */
> > +	if ((rbuf->offset > size) ||
> > +	    (rbuf->len > size)) {
> > +		dev_dbg(&drvdata->csdev->dev,
> > +			"Offset and length invalid in tmc crash metadata\n");
> > +		return -EINVAL;
> > +	}
> 
> Ideally this should also be done once and "don't expose" crash_tmc
> device if the above is invalid in metada.


Will remove the invocation of this function during tmc_crashdata_read
and move it to tmc_probe .

+       if (is_tmc_crashdata_valid(drvdata) &&
+           !tmc_prepare_crashdata(drvdata))
+               register_crash_dev_interface(drvdata, desc.name);
        return ret;
 }


> 
> 
> > +
> > +	if (status & 0x1)
> 
> minor nit: s/0x1/TMC_STS_FULL ?

Ack.

> 
> > +		coresight_insert_barrier_packet(drvdata->buf);
> 
> And this looks completely out of nowhere and corrupting the drvdata->buf ?
> drvdata->buf is for active sessions, which we haven't set here ?

Thanks for pointing this out. Somehow missed this.

> 
> 
> > +
> > +	drvdata->reading = true;
> 
> Also, we agreed to not overload "drvdata->reading" ?

> 
> See
> https://lkml.kernel.org/r/20241017114054.GC896339 at hyd1403.caveonetworks.com
> 
> We are allowed to the ETR (which drvdata->reading prevents from btw) while
> crash data is being read. You could instead move it to
> drvdata->resrv_buf->reading ?

Ack.

> 
> 
> 
> Suzuki
> 
> 
> > +out:
> > +	spin_unlock_irqrestore(&drvdata->spinlock, flags);
> > +	return ret;
> > +}
> > +
> > +int tmc_read_unprepare_crashdata(struct tmc_drvdata *drvdata)
> > +{
> > +	unsigned long flags;
> > +	struct tmc_resrv_buf *rbuf;
> > +
> > +	spin_lock_irqsave(&drvdata->spinlock, flags);
> > +
> > +	rbuf = &drvdata->resrv_buf;
> > +	/* Reset valid length */
> > +	rbuf->len = 0;
> > +
> > +	drvdata->reading = false;
> > +	spin_unlock_irqrestore(&drvdata->spinlock, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static inline ssize_t tmc_get_resvbuf_trace(struct tmc_drvdata *drvdata,
> > +					  loff_t pos, size_t len, char **bufpp)
> > +{
> > +	s64 offset;
> > +	ssize_t actual = len;
> > +	struct tmc_resrv_buf *rbuf = &drvdata->resrv_buf;
> > +
> > +	if (pos + actual > rbuf->len)
> > +		actual = rbuf->len - pos;
> > +	if (actual <= 0)
> > +		return 0;
> > +
> > +	/* Compute the offset from which we read the data */
> > +	offset = rbuf->offset + pos;
> > +	if (offset >= rbuf->size)
> > +		offset -= rbuf->size;
> > +
> > +	/* Adjust the length to limit this transaction to end of buffer */
> > +	actual = (actual < (rbuf->size - offset)) ?
> > +		actual : rbuf->size - offset;
> > +
> > +	*bufpp = (char *)rbuf->vaddr + offset;
> > +
> > +	return actual;
> > +}
> > +
> >   static int tmc_read_prepare(struct tmc_drvdata *drvdata)
> >   {
> >   	int ret = 0;
> > @@ -223,6 +368,69 @@ static const struct file_operations tmc_fops = {
> >   	.release	= tmc_release,
> >   };
> > +static int tmc_crashdata_open(struct inode *inode, struct file *file)
> > +{
> > +	int ret;
> > +	struct tmc_drvdata *drvdata = container_of(file->private_data,
> > +						   struct tmc_drvdata,
> > +						   crashdev);
> > +
> > +	ret = tmc_read_prepare_crashdata(drvdata);
> > +	if (ret)
> > +		return ret;
> > +
> > +	nonseekable_open(inode, file);
> > +
> > +	dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__);
> > +	return 0;
> > +}
> > +
> > +static ssize_t tmc_crashdata_read(struct file *file, char __user *data,
> > +				  size_t len, loff_t *ppos)
> > +{
> > +	char *bufp;
> > +	ssize_t actual;
> > +	struct tmc_drvdata *drvdata = container_of(file->private_data,
> > +						   struct tmc_drvdata,
> > +						   crashdev);
> > +
> > +	actual = tmc_get_resvbuf_trace(drvdata, *ppos, len, &bufp);
> > +	if (actual <= 0)
> > +		return 0;
> > +
> > +	if (copy_to_user(data, bufp, actual)) {
> > +		dev_dbg(&drvdata->csdev->dev,
> > +			"%s: copy_to_user failed\n", __func__);
> > +		return -EFAULT;
> > +	}
> > +
> > +	*ppos += actual;
> > +	dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
> > +
> > +	return actual;
> > +
> > +}
> > +
> > +static int tmc_crashdata_release(struct inode *inode, struct file *file)
> > +{
> > +	int ret = 0;
> > +	struct tmc_drvdata *drvdata = container_of(file->private_data,
> > +						   struct tmc_drvdata,
> > +						   crashdev);
> > +
> > +	ret = tmc_read_unprepare_crashdata(drvdata);
> > +
> > +	dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__);
> > +	return ret;
> > +}
> > +
> > +static const struct file_operations tmc_crashdata_fops = {
> > +	.owner		= THIS_MODULE,
> > +	.open		= tmc_crashdata_open,
> > +	.read		= tmc_crashdata_read,
> > +	.release	= tmc_crashdata_release,
> > +};
> > +
> >   static enum tmc_mem_intf_width tmc_get_memwidth(u32 devid)
> >   {
> >   	enum tmc_mem_intf_width memwidth;
> > @@ -532,6 +740,20 @@ static u32 tmc_etr_get_max_burst_size(struct device *dev)
> >   	return burst_size;
> >   }
> > +static void register_crash_dev_interface(struct tmc_drvdata *drvdata,
> > +					 const char *name)
> > +{
> > +	drvdata->crashdev.name =
> > +		devm_kasprintf(&drvdata->csdev->dev, GFP_KERNEL, "%s_%s", "crash", name);
> > +	drvdata->crashdev.minor = MISC_DYNAMIC_MINOR;
> > +	drvdata->crashdev.fops = &tmc_crashdata_fops;
> > +	if (misc_register(&drvdata->crashdev)) {
> > +		dev_dbg(&drvdata->csdev->dev,
> > +			"Failed to setup user interface for crashdata\n");
> > +		drvdata->crashdev.fops = NULL;
> > +	}
> > +}
> > +
> >   static int __tmc_probe(struct device *dev, struct resource *res)
> >   {
> >   	int ret = 0;
> > @@ -632,8 +854,13 @@ static int __tmc_probe(struct device *dev, struct resource *res)
> >   	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
> >   	drvdata->miscdev.fops = &tmc_fops;
> >   	ret = misc_register(&drvdata->miscdev);
> > -	if (ret)
> > +	if (ret) {
> >   		coresight_unregister(drvdata->csdev);
> > +		goto out;
> > +	}
> > +
> > +	if (is_tmc_crashdata_valid(drvdata))
> > +		register_crash_dev_interface(drvdata, desc.name);
> >   out:
> >   	return ret;
> >   }
> > @@ -687,6 +914,8 @@ static void __tmc_remove(struct device *dev)
> >   	 * handler to this device is closed.
> >   	 */
> >   	misc_deregister(&drvdata->miscdev);
> > +	if (drvdata->crashdev.fops)
> > +		misc_deregister(&drvdata->crashdev);
> >   	coresight_unregister(drvdata->csdev);
> >   }
> > diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> > index fb944a68a11c..18752f58dfa6 100644
> > --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> > +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> > @@ -2012,6 +2012,23 @@ static ssize_t buf_mode_preferred_show(struct device *dev,
> >   	return sysfs_emit(buf, "%s\n", buf_modes_str[drvdata->etr_mode]);
> >   }
> > +static int buf_mode_set_resrv(struct tmc_drvdata *drvdata)
> > +{
> > +	unsigned long flags;
> > +	int err = 0;
> > +
> > +	/* Ensure there are no active crashdata read sessions */
> > +	spin_lock_irqsave(&drvdata->spinlock, flags);
> > +	if (!drvdata->reading) {
> > +		tmc_crashdata_set_invalid(drvdata);
> > +		drvdata->etr_mode = ETR_MODE_RESRV;
> > +
> > +	} else
> > +		err = -1;
> > +	spin_unlock_irqrestore(&drvdata->spinlock, flags);
> > +	return err;
> > +}
> > +
> >   static ssize_t buf_mode_preferred_store(struct device *dev,
> >   					  struct device_attribute *attr,
> >   					  const char *buf, size_t size)
> > @@ -2027,7 +2044,7 @@ static ssize_t buf_mode_preferred_store(struct device *dev,
> >   	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_CATU]) && buf_hw.has_catu)
> >   		drvdata->etr_mode = ETR_MODE_CATU;
> >   	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_RESRV]) && buf_hw.has_resrv)
> > -		drvdata->etr_mode = ETR_MODE_RESRV;
> > +		return buf_mode_set_resrv(drvdata) ? -EBUSY : size;
> >   	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_AUTO]))
> >   		drvdata->etr_mode = ETR_MODE_AUTO;
> >   	else
> > diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> > index d76e83fc840b..2ece44e09911 100644
> > --- a/drivers/hwtracing/coresight/coresight-tmc.h
> > +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> > @@ -195,11 +195,15 @@ struct etr_buf {
> >    * @paddr	: Start address of reserved memory region.
> >    * @vaddr	: Corresponding CPU virtual address.
> >    * @size	: Size of reserved memory region.
> > + * @offset	: Offset of the trace data in the buffer for consumption.
> > + * @len	: Available trace data @buf (may round up to the beginning).
> >    */
> >   struct tmc_resrv_buf {
> >   	phys_addr_t     paddr;
> >   	void		*vaddr;
> >   	size_t		size;
> > +	unsigned long	offset;
> > +	s64		len;
> >   };
> >   /**
> > @@ -208,6 +212,8 @@ struct tmc_resrv_buf {
> >    * @base:	memory mapped base address for this component.
> >    * @csdev:	component vitals needed by the framework.
> >    * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
> > + * @crashdev:	specifics to handle "/dev/crash_tmc_xyz" entry for reading
> > + *		crash tracedata.
> >    * @spinlock:	only one at a time pls.
> >    * @pid:	Process ID of the process that owns the session that is using
> >    *		this component. For example this would be the pid of the Perf
> > @@ -227,7 +233,7 @@ struct tmc_resrv_buf {
> >    * @idr_mutex:	Access serialisation for idr.
> >    * @sysfs_buf:	SYSFS buffer for ETR.
> >    * @perf_buf:	PERF buffer for ETR.
> > - * @resrv_buf:	Used by ETR as hardware trace buffer and for trace data
> > + * @resrv_buf:  Used by ETR as hardware trace buffer and for trace data
> >    *		retention (after crash) only when ETR_MODE_RESRV buffer
> >    *		mode is enabled. Used by ETF for trace data retention
> >    *		(after crash) by default.
> > @@ -239,6 +245,7 @@ struct tmc_drvdata {
> >   	void __iomem		*base;
> >   	struct coresight_device	*csdev;
> >   	struct miscdevice	miscdev;
> > +	struct miscdevice	crashdev;
> >   	spinlock_t		spinlock;
> >   	pid_t			pid;
> >   	bool			reading;
> > @@ -309,6 +316,8 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata);
> >   void tmc_enable_hw(struct tmc_drvdata *drvdata);
> >   void tmc_disable_hw(struct tmc_drvdata *drvdata);
> >   u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata);
> > +int tmc_read_prepare_crashdata(struct tmc_drvdata *drvdata);
> > +int tmc_read_unprepare_crashdata(struct tmc_drvdata *drvdata);
> >   /* ETB/ETF functions */
> >   int tmc_read_prepare_etb(struct tmc_drvdata *drvdata);
> > @@ -371,6 +380,8 @@ void tmc_sg_table_sync_data_range(struct tmc_sg_table *table,
> >   				  u64 offset, u64 size);
> >   ssize_t tmc_sg_table_get_data(struct tmc_sg_table *sg_table,
> >   			      u64 offset, size_t len, char **bufpp);
> > +
> > +bool is_tmc_crashdata_valid(struct tmc_drvdata *drvdata);
> >   static inline unsigned long
> >   tmc_sg_table_buf_size(struct tmc_sg_table *sg_table)
> >   {
> 
> 


From Liju-clr.Chen at mediatek.com  Thu Dec 12 21:57:31 2024
From: Liju-clr.Chen at mediatek.com (=?utf-8?B?TGlqdS1jbHIgQ2hlbiAo6Zmz6bqX5aaCKQ==?=)
Date: Fri, 13 Dec 2024 05:57:31 +0000
Subject: [PATCH v13 01/25] virt: geniezone: enable gzvm-ko in defconfig
In-Reply-To: <1ecf2e8c-86cd-4ba2-832b-014a05a80d26@kernel.org>
References: <20241114100802.4116-1-liju-clr.chen@mediatek.com>
	 <20241114100802.4116-2-liju-clr.chen@mediatek.com>
	 <1ecf2e8c-86cd-4ba2-832b-014a05a80d26@kernel.org>
Message-ID: <d711de9ef517cc85fbb16a30ac21bd4c44c8f863.camel@mediatek.com>

On Wed, 2024-12-11 at 09:38 +0100, Krzysztof Kozlowski wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On 14/11/2024 11:07, Liju-clr Chen wrote:
> > From: Yingshiuan Pan <yingshiuan.pan at mediatek.com>
> > 
> 
> 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.
> 
> 
> > Add config in defconfig to enable gzvm driver by default
> 
> This we see from the diff. You must explain why we want it.
> 
> > 
> > Signed-off-by: Yingshiuan Pan <yingshiuan.pan at mediatek.com>
> > Signed-off-by: Yi-De Wu <yi-de.wu at mediatek.com>
> > Signed-off-by: Liju Chen <liju-clr.chen at mediatek.com>
> > ---
> >  arch/arm64/configs/defconfig | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/arch/arm64/configs/defconfig
> > b/arch/arm64/configs/defconfig
> > index d13218d0c30f..0f63d4837b61 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -1733,3 +1733,5 @@ CONFIG_CORESIGHT_STM=m
> >  CONFIG_CORESIGHT_CPU_DEBUG=m
> >  CONFIG_CORESIGHT_CTI=m
> >  CONFIG_MEMTEST=y
> > +CONFIG_VIRT_DRIVERS=y
> > +CONFIG_MTK_GZVM=m
> 
> Does not look like placed correctly, according to savedefconfig.
> 
> I still do not see any reason to have it enabled.
> 
> Your patches have weird order or this is just wrong. There is no such
> thing as "MTK_GZVM". Use git grep, if you do not believe me.
> 
> 
> Best regards,
> Krzysztof

Hi Krzysztof,
Thank you for your comments. I agree with your suggestions.
We will remove this patch in the next version.

Best regards,
Liju Chen

From lbulwahn at redhat.com  Thu Dec 12 22:00:11 2024
From: lbulwahn at redhat.com (Lukas Bulwahn)
Date: Fri, 13 Dec 2024 07:00:11 +0100
Subject: [PATCH] MAINTAINERS: repair file entry in MEDIA DRIVERS FOR STM32 - CSI
Message-ID: <20241213060011.67797-1-lukas.bulwahn@redhat.com>

From: Lukas Bulwahn <lukas.bulwahn at redhat.com>

Commit dcb0f4c16be5 ("media: stm32: csi: addition of the STM32 CSI driver")
adds a new driver at drivers/media/platform/st/stm32/stm32-csi.c, but
creates a new MAINTAINERS section MEDIA DRIVERS FOR STM32 - CSI with a file
entry pointing to drivers/media/platform/stm32/stm32-csi.c. Note that the
file entry is missing the ?st? directory in its path.

Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a
broken reference. Repair this file entry in MEDIA DRIVERS FOR STM32 - CSI.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at redhat.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index bff3d35f80b5..230b7a4ee95f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14551,7 +14551,7 @@ L:	linux-media at vger.kernel.org
 S:	Supported
 T:	git git://linuxtv.org/media_tree.git
 F:	Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
-F:	drivers/media/platform/stm32/stm32-csi.c
+F:	drivers/media/platform/st/stm32/stm32-csi.c
 
 MEDIA DRIVERS FOR STM32 - DCMI / DCMIPP
 M:	Hugues Fruchet <hugues.fruchet at foss.st.com>
-- 
2.47.1



From victor.liu at nxp.com  Thu Dec 12 22:07:25 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Fri, 13 Dec 2024 14:07:25 +0800
Subject: [PATCH v6 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <q6pdop6ucowtoxxr66czq7yooujyvp6qs5vcg6gpmi3q4rs4l3@szyqt5pxteoz>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
 <20241209033923.3009629-13-victor.liu@nxp.com>
 <3j4fguv4oienfaj4fghpiqpmnq3aczu4azhdo5jzvywc5mawm5@hh33p3dhf6xa>
 <db4d9d4e-855f-4647-9b93-ccc5ec0202b3@nxp.com>
 <q6pdop6ucowtoxxr66czq7yooujyvp6qs5vcg6gpmi3q4rs4l3@szyqt5pxteoz>
Message-ID: <b02fb998-9420-4954-8e48-82447493bbb7@nxp.com>

On 12/12/2024, Dmitry Baryshkov wrote:
> On Wed, Dec 11, 2024 at 03:43:20PM +0800, Liu Ying wrote:
>> On 12/10/2024, Dmitry Baryshkov wrote:
>>> On Mon, Dec 09, 2024 at 11:39:16AM +0800, Liu Ying wrote:
>>>> i.MX8qxp Display Controller(DC) is comprised of three main components that
>>>> include a blit engine for 2D graphics accelerations, display controller for
>>>> display output processing, as well as a command sequencer.  Add kernel
>>>> mode setting support for the display controller part with two CRTCs and
>>>> two primary planes(backed by FetchLayer and FetchWarp respectively).  The
>>>> registers of the display controller are accessed without command sequencer
>>>> involved, instead just by using CPU.  The command sequencer is supposed to
>>>> be used by the blit engine.
>>>>
>>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>>>> ---
>>>> v6:
>>>> * No change.
>>>>
>>>> v5:
>>>> * Replace .remove_new with .remove in dc-drv.c. (Uwe)
>>>>
>>>> v4:
>>>> * Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
>>>>   function calls from KMS routine to initialization stage. (Dmitry)
>>>> * Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
>>>>   appropriate .h header files or .c source files. (Dmitry)
>>>> * Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
>>>> * Drop dc_drm->pe_rpm_count. (Dmitry)
>>>> * Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
>>>> * Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
>>>>   Instead, put it in struct dc_crtc.  (Dmitry)
>>>> * Call devm_request_irq() to request IRQs, instead of using drmm action.
>>>>   (Dmitry)
>>>> * Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
>>>> * Select DRM_CLIENT_SELECTION due to rebase.
>>>> * Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
>>>> * Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
>>>> * Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
>>>>   rebase.
>>>> * Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
>>>>   register dc_drm_component_unbind_all() action.
>>>> * Request interrupts in dc_crtc_post_init() after encoder initialization to
>>>>   make sure next bridge is found first.
>>>>
>>>> v3:
>>>> * No change.
>>>>
>>>> v2:
>>>> * Find next bridge from TCon's port.
>>>> * Drop drm/drm_module.h include from dc-drv.c.
>>>>
>>>>  drivers/gpu/drm/imx/dc/Kconfig    |   5 +
>>>>  drivers/gpu/drm/imx/dc/Makefile   |   5 +-
>>>>  drivers/gpu/drm/imx/dc/dc-crtc.c  | 558 ++++++++++++++++++++++++++++++
>>>>  drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
>>>>  drivers/gpu/drm/imx/dc/dc-drv.c   | 244 +++++++++++++
>>>>  drivers/gpu/drm/imx/dc/dc-drv.h   |  19 +
>>>>  drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
>>>>  drivers/gpu/drm/imx/dc/dc-kms.h   |  58 ++++
>>>>  drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
>>>>  9 files changed, 1274 insertions(+), 2 deletions(-)
>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
>>>>
>>>> diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
>>>> index 1fc84c7475de..415993207f2e 100644
>>>> --- a/drivers/gpu/drm/imx/dc/Kconfig
>>>> +++ b/drivers/gpu/drm/imx/dc/Kconfig
>>>> @@ -1,6 +1,11 @@
>>>>  config DRM_IMX8_DC
>>>>  	tristate "Freescale i.MX8 Display Controller Graphics"
>>>>  	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
>>>> +	select DRM_CLIENT_SELECTION
>>>> +	select DRM_GEM_DMA_HELPER
>>>> +	select DRM_KMS_HELPER
>>>> +	select DRM_DISPLAY_HELPER
>>>> +	select DRM_BRIDGE_CONNECTOR
>>>>  	select GENERIC_IRQ_CHIP
>>>>  	select REGMAP
>>>>  	select REGMAP_MMIO
>>>> diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
>>>> index 1ce3e8a8db22..b9d33c074984 100644
>>>> --- a/drivers/gpu/drm/imx/dc/Makefile
>>>> +++ b/drivers/gpu/drm/imx/dc/Makefile
>>>> @@ -1,6 +1,7 @@
>>>>  # SPDX-License-Identifier: GPL-2.0
>>>>  
>>>> -imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
>>>> -		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
>>>> +imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
>>>> +		    dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
>>>> +		    dc-plane.o dc-tc.o
>>>>  
>>>>  obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
>>>> new file mode 100644
>>>> index 000000000000..fd6daa1807d8
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
>>>> @@ -0,0 +1,558 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +/*
>>>> + * Copyright 2024 NXP
>>>> + */
>>>> +
>>>> +#include <linux/completion.h>
>>>> +#include <linux/container_of.h>
>>>> +#include <linux/interrupt.h>
>>>> +#include <linux/irqreturn.h>
>>>> +#include <linux/pm_runtime.h>
>>>> +#include <linux/spinlock.h>
>>>> +
>>>> +#include <drm/drm_atomic.h>
>>>> +#include <drm/drm_atomic_helper.h>
>>>> +#include <drm/drm_atomic_state_helper.h>
>>>> +#include <drm/drm_crtc.h>
>>>> +#include <drm/drm_device.h>
>>>> +#include <drm/drm_drv.h>
>>>> +#include <drm/drm_modes.h>
>>>> +#include <drm/drm_modeset_helper_vtables.h>
>>>> +#include <drm/drm_plane.h>
>>>> +#include <drm/drm_print.h>
>>>> +#include <drm/drm_vblank.h>
>>>> +
>>>> +#include "dc-de.h"
>>>> +#include "dc-drv.h"
>>>> +#include "dc-kms.h"
>>>> +#include "dc-pe.h"
>>>> +
>>>> +#define dc_crtc_dbg(crtc, fmt, ...)					\
>>>> +do {									\
>>>> +	typeof(crtc) _crtc = (crtc);					\
>>>
>>> Use exact type instead of typeof.
>>
>> Will do.
>>
>>>
>>>> +	drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
>>>> +		    _crtc->base.id, _crtc->name, ##__VA_ARGS__);	\
>>>> +} while (0)
>>>> +
>>>> +#define dc_crtc_err(crtc, fmt, ...)					\
>>>> +do {									\
>>>> +	typeof(crtc) _crtc = (crtc);					\
>>>> +	drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
>>>> +		_crtc->base.id, _crtc->name, ##__VA_ARGS__);		\
>>>> +} while (0)
>>>> +
>>>> +#define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c)				\
>>>> +do {									\
>>>> +	unsigned long ret;						\
>>>> +	ret = wait_for_completion_timeout(&dc_crtc->c, HZ);		\
>>>> +	if (ret == 0)							\
>>>> +		dc_crtc_err(crtc, "%s: wait for " #c " timeout\n",	\
>>>> +							__func__);	\
>>>> +} while (0)
>>>> +
>>>> +#define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg)					\
>>>> +do {									\
>>>> +	typeof(fg) _fg = (fg);						\
>>>> +	if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) {		\
>>>> +		dc_fg_secondary_clear_channel_status(_fg);		\
>>>> +		dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n",		\
>>>> +							__func__);	\
>>>> +	}								\
>>>> +} while (0)
>>>> +
>>>> +#define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg)			\
>>>> +do {									\
>>>> +	if (dc_fg_wait_for_secondary_syncup(fg))			\
>>>> +		dc_crtc_err(crtc,					\
>>>> +			"%s: FrameGen secondary channel isn't syncup\n",\
>>>> +							__func__);	\
>>>> +} while (0)
>>>> +
>>>> +static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
>>>> +{
>>>> +	return container_of(crtc, struct dc_crtc, base);
>>>> +}
>>>> +
>>>> +static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +
>>>> +	return dc_fg_get_frame_index(dc_crtc->fg);
>>>> +}
>>>> +
>>>> +static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +
>>>> +	enable_irq(dc_crtc->irq_dec_framecomplete);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +
>>>> +	disable_irq_nosync(dc_crtc->irq_dec_framecomplete);
>>>
>>> Why is it _nosync?
>>
>> Because disable_irq() can only be called from preemptible code according to
>> it's kerneldoc. If I use disable_irq() here, I get this with
>> CONFIG_DEBUG_ATOMIC_SLEEP enabled:
> 
> Please add a one-line comment, like "nosync because of the atomic
> context"

Will do.

> 
>>
>> [   50.607503] BUG: sleeping function called from invalid context at kernel/irq/manage.c:738
>> [   50.615691] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/0
>> [   50.623527] preempt_count: 10003, expected: 0
>> [   50.627888] RCU nest depth: 0, expected: 0
>> [   50.631993] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.13.0-rc2-next-20241209-00026-g800cb5b7df74 #1407
>> [   50.642092] Hardware name: Freescale i.MX8QXP MEK (DT)
>> [   50.647237] Call trace:
>> [   50.649687]  show_stack+0x18/0x24 (C)
>> [   50.653369]  dump_stack_lvl+0x80/0xb4
>> [   50.657043]  dump_stack+0x18/0x24
>> [   50.660370]  __might_resched+0x114/0x170
>> [   50.664306]  __might_sleep+0x48/0x98
>> [   50.667894]  disable_irq+0x24/0x60
>> [   50.671308]  dc_crtc_disable_vblank+0x14/0x20 [imx8_dc_drm]
>> [   50.676912]  drm_vblank_disable_and_save+0xc0/0x108 [drm]
>> [   50.682533]  vblank_disable_fn+0x78/0x9c [drm]
>> [   50.687146]  drm_handle_vblank+0x238/0x2e8 [drm]
>> [   50.691932]  drm_crtc_handle_vblank+0x1c/0x28 [drm]
>> [   50.696980]  dc_crtc_irq_handler_dec_framecomplete+0x1c/0x6c [imx8_dc_drm]
>> [   50.703886]  __handle_irq_event_percpu+0x60/0x14c
>> [   50.708604]  handle_irq_event+0x4c/0xac
>> [   50.712443]  handle_level_irq+0xc0/0x1b0
>> [   50.716379]  generic_handle_irq+0x34/0x4c
>> [   50.720392]  dc_ic_irq_handler+0x128/0x160 [imx8_dc_drm]
>> [   50.725727]  generic_handle_domain_irq+0x2c/0x44
>> [   50.730357]  imx_irqsteer_irq_handler+0xc0/0x1a0
>> [   50.734987]  generic_handle_domain_irq+0x2c/0x44
>> [   50.739609]  gic_handle_irq+0x4c/0x114
>> [   50.743362]  call_on_irq_stack+0x24/0x4c
>> [   50.747298]  do_interrupt_handler+0x80/0x84
>> [   50.751494]  el1_interrupt+0x34/0x68
>> [   50.755082]  el1h_64_irq_handler+0x18/0x24
>> [   50.759191]  el1h_64_irq+0x6c/0x70
>> [   50.762597]  default_idle_call+0x28/0x3c (P)
>> [   50.766879]  default_idle_call+0x24/0x3c (L)
>> [   50.771163]  do_idle+0x200/0x25c
>> [   50.774403]  cpu_startup_entry+0x34/0x3c
>> [   50.778338]  kernel_init+0x0/0x1d8
>> [   50.781752]  start_kernel+0x5c4/0x70c
>> [   50.785427]  __primary_switched+0x88/0x90
>>
>>>
>>>> +}
>>>> +
>>>> +static irqreturn_t
>>>> +dc_crtc_dec_framecomplete_irq_handler(int irq, void *dev_id)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = dev_id;
>>>> +	struct drm_crtc *crtc = &dc_crtc->base;
>>>> +	unsigned long flags;
>>>> +
>>>> +	drm_crtc_handle_vblank(crtc);
>>>> +
>>>> +	spin_lock_irqsave(&crtc->dev->event_lock, flags);
>>>> +	if (dc_crtc->event) {
>>>> +		drm_crtc_send_vblank_event(crtc, dc_crtc->event);
>>>> +		dc_crtc->event = NULL;
>>>> +		drm_crtc_vblank_put(crtc);
>>>> +	}
>>>> +	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
>>>> +
>>>> +	return IRQ_HANDLED;
>>>> +}
>>>> +
>>>> +static irqreturn_t dc_crtc_common_irq_handler(int irq, void *dev_id)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = dev_id;
>>>> +
>>>> +	if (irq == dc_crtc->irq_dec_seqcomplete)
>>>> +		complete(&dc_crtc->dec_seqcomplete_done);
>>>> +	else if (irq == dc_crtc->irq_dec_shdld)
>>>> +		complete(&dc_crtc->dec_shdld_done);
>>>> +	else if (irq == dc_crtc->irq_ed_cont_shdld)
>>>> +		complete(&dc_crtc->ed_cont_shdld_done);
>>>> +	else if (irq == dc_crtc->irq_ed_safe_shdld)
>>>> +		complete(&dc_crtc->ed_safe_shdld_done);
>>>
>>> Is there any reason to have a single multiplex handler instead of having
>>> 4 separate handlers, each doing one simple thing?
>>
>> Just thought that one irq handler is feasible to implement the common
>> handling logic. It's also ok to use 4 separate handlers with a little
>> performance improvement. I may change to use 4 separate handlers by
>> introducing a DEFINE_DC_CRTC_IRQ_HANDLER() marco.
> 
> Just define them one by one, there is no need for a macro.

Will do.

> 
>>
>>>
>>>> +
>>>> +	return IRQ_HANDLED;
>>>> +}
>>>> +
>>>> +static const struct drm_crtc_funcs dc_crtc_funcs = {
>>>> +	.reset			= drm_atomic_helper_crtc_reset,
>>>> +	.destroy		= drm_crtc_cleanup,
>>>> +	.set_config		= drm_atomic_helper_set_config,
>>>> +	.page_flip		= drm_atomic_helper_page_flip,
>>>> +	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
>>>> +	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
>>>> +	.get_vblank_counter	= dc_crtc_get_vblank_counter,
>>>> +	.enable_vblank		= dc_crtc_enable_vblank,
>>>> +	.disable_vblank		= dc_crtc_disable_vblank,
>>>> +	.get_vblank_timestamp	= drm_crtc_vblank_helper_get_vblank_timestamp,
>>>> +};
>>>> +
>>>> +static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
>>>> +{
>>>> +	struct drm_crtc *crtc = crtc_state->crtc;
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +
>>>> +	spin_lock_irq(&crtc->dev->event_lock);
>>>> +	if (crtc_state->event) {
>>>> +		WARN_ON(drm_crtc_vblank_get(crtc));
>>>> +		WARN_ON(dc_crtc->event);
>>>> +		dc_crtc->event = crtc_state->event;
>>>> +		crtc_state->event = NULL;
>>>> +	}
>>>> +	spin_unlock_irq(&crtc->dev->event_lock);
>>>> +}
>>>> +
>>>> +static enum drm_mode_status
>>>> +dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
>>>> +{
>>>> +	return dc_fg_check_clock(dc_crtc->fg, clk_khz);
>>>> +}
>>>
>>> inline
>>
>> Will do.
>>
>>>
>>>> +
>>>> +static enum drm_mode_status
>>>> +dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +	enum drm_mode_status status;
>>>> +
>>>> +	status = dc_crtc_check_clock(dc_crtc, mode->clock);
>>>> +	if (status != MODE_OK)
>>>> +		return status;
>>>> +
>>>> +	if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
>>>> +		return MODE_CLOCK_HIGH;
>>>> +
>>>> +	return MODE_OK;
>>>> +}
>>>> +
>>>> +static int
>>>> +dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>> +{
>>>> +	struct drm_crtc_state *new_crtc_state =
>>>> +				drm_atomic_get_new_crtc_state(state, crtc);
>>>> +	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +	enum drm_mode_status status;
>>>> +
>>>> +	status = dc_crtc_check_clock(dc_crtc, adj->clock);
>>>> +	if (status != MODE_OK)
>>>> +		return -EINVAL;
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static void
>>>> +dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>> +{
>>>> +	struct drm_crtc_state *new_crtc_state =
>>>> +				drm_atomic_get_new_crtc_state(state, crtc);
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +	int idx, ret;
>>>> +
>>>> +	if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
>>>> +	    !new_crtc_state->active)
>>>> +		return;
>>>> +
>>>> +	if (!drm_dev_enter(crtc->dev, &idx))
>>>> +		return;
>>>> +
>>>> +	/* request pixel engine power-on when CRTC starts to be active */
>>>> +	ret = pm_runtime_resume_and_get(dc_crtc->pe->dev);
>>>> +	if (ret)
>>>> +		dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
>>>> +			    ret);
>>>> +
>>>> +	drm_dev_exit(idx);
>>>> +}
>>>> +
>>>> +static void
>>>> +dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>> +{
>>>> +	struct drm_crtc_state *old_crtc_state =
>>>> +				drm_atomic_get_old_crtc_state(state, crtc);
>>>> +	struct drm_crtc_state *new_crtc_state =
>>>> +				drm_atomic_get_new_crtc_state(state, crtc);
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +	int idx;
>>>> +
>>>> +	if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
>>>> +	    (!old_crtc_state->active && !new_crtc_state->active))
>>>> +		return;
>>>> +
>>>> +	if (!drm_dev_enter(crtc->dev, &idx))
>>>> +		goto out;
>>>> +
>>>> +	enable_irq(dc_crtc->irq_ed_cont_shdld);
>>>> +
>>>> +	/* flush plane update out to display */
>>>> +	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
>>>> +
>>>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
>>>> +
>>>> +	disable_irq(dc_crtc->irq_ed_cont_shdld);
>>>> +
>>>> +	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
>>>> +
>>>> +	drm_dev_exit(idx);
>>>> +
>>>> +out:
>>>> +	dc_crtc_queue_state_event(new_crtc_state);
>>>> +}
>>>> +
>>>> +static void
>>>> +dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>> +{
>>>> +	struct drm_crtc_state *new_crtc_state =
>>>> +				drm_atomic_get_new_crtc_state(state, crtc);
>>>> +	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +	enum dc_link_id cf_link;
>>>> +	int idx, ret;
>>>> +
>>>> +	dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
>>>> +
>>>> +	drm_crtc_vblank_on(crtc);
>>>> +
>>>> +	if (!drm_dev_enter(crtc->dev, &idx))
>>>> +		goto out;
>>>> +
>>>> +	/* request display engine power-on when CRTC is enabled */
>>>> +	ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
>>>> +	if (ret < 0)
>>>> +		dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
>>>> +			    ret);
>>>> +
>>>> +	enable_irq(dc_crtc->irq_dec_shdld);
>>>> +	enable_irq(dc_crtc->irq_ed_cont_shdld);
>>>> +	enable_irq(dc_crtc->irq_ed_safe_shdld);
>>>> +
>>>> +	dc_fg_cfg_videomode(dc_crtc->fg, adj);
>>>> +
>>>> +	dc_cf_framedimensions(dc_crtc->cf_cont,
>>>> +			      adj->crtc_hdisplay, adj->crtc_vdisplay);
>>>> +	dc_cf_framedimensions(dc_crtc->cf_safe,
>>>> +			      adj->crtc_hdisplay, adj->crtc_vdisplay);
>>>> +
>>>> +	/* constframe in safety stream shows blue frame */
>>>> +	dc_cf_constantcolor_blue(dc_crtc->cf_safe);
>>>> +	cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
>>>> +	dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
>>>> +
>>>> +	/* show CRTC background if no plane is enabled */
>>>> +	if (new_crtc_state->plane_mask == 0) {
>>>> +		/* constframe in content stream shows black frame */
>>>> +		dc_cf_constantcolor_black(dc_crtc->cf_cont);
>>>> +
>>>> +		cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
>>>> +		dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
>>>> +	}
>>>> +
>>>> +	dc_fg_enable_clock(dc_crtc->fg);
>>>> +	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
>>>> +	dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
>>>> +	dc_fg_shdtokgen(dc_crtc->fg);
>>>> +	dc_fg_enable(dc_crtc->fg);
>>>> +
>>>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdld_done);
>>>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
>>>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdld_done);
>>>> +
>>>> +	disable_irq(dc_crtc->irq_ed_safe_shdld);
>>>> +	disable_irq(dc_crtc->irq_ed_cont_shdld);
>>>> +	disable_irq(dc_crtc->irq_dec_shdld);
>>>> +
>>>> +	DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
>>>> +
>>>> +	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
>>>> +
>>>> +	drm_dev_exit(idx);
>>>> +
>>>> +out:
>>>> +	dc_crtc_queue_state_event(new_crtc_state);
>>>> +}
>>>> +
>>>> +static void
>>>> +dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>> +{
>>>> +	struct drm_crtc_state *new_crtc_state =
>>>> +				drm_atomic_get_new_crtc_state(state, crtc);
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +	int idx, ret;
>>>> +
>>>> +	if (!drm_dev_enter(crtc->dev, &idx))
>>>> +		goto out;
>>>> +
>>>> +	enable_irq(dc_crtc->irq_dec_seqcomplete);
>>>> +	dc_fg_disable(dc_crtc->fg);
>>>> +	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
>>>> +	disable_irq(dc_crtc->irq_dec_seqcomplete);
>>>> +
>>>> +	dc_fg_disable_clock(dc_crtc->fg);
>>>> +
>>>> +	/* request pixel engine power-off as plane is off too */
>>>> +	ret = pm_runtime_put(dc_crtc->pe->dev);
>>>> +	if (ret)
>>>> +		dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
>>>> +			    ret);
>>>> +
>>>> +	/* request display engine power-off when CRTC is disabled */
>>>> +	ret = pm_runtime_put(dc_crtc->de->dev);
>>>
>>> Can this be expressed as a devlink between PE and DE?
>>
>> Looking at struct dc_{pe,de}, PE and DE are not dependent with each other,
>> i.e., no consumer/supplier relationship(note that blit engine in PE can work
>> by itself without DE) between them. So, it doesn't look right to link the two
>> devices.
> 
> Ack
> 
>>
>>>
>>>> +	if (ret < 0)
>>>> +		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
>>>> +			    ret);
>>>> +
>>>> +	drm_dev_exit(idx);
>>>> +
>>>> +out:
>>>> +	drm_crtc_vblank_off(crtc);
>>>> +
>>>> +	spin_lock_irq(&crtc->dev->event_lock);
>>>> +	if (new_crtc_state->event && !new_crtc_state->active) {
>>>> +		drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
>>>> +		new_crtc_state->event = NULL;
>>>> +	}
>>>> +	spin_unlock_irq(&crtc->dev->event_lock);
>>>> +}
>>>> +
>>>> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +	int ret;
>>>> +
>>>> +	if (!dc_fg_wait_for_frame_index_moving(dc_crtc->fg))
>>>> +		return;
>>>> +
>>>> +	dc_fg_disable_clock(dc_crtc->fg);
>>>> +
>>>> +	if (pm_runtime_active(dc_crtc->pe->dev)) {
>>>> +		ret = pm_runtime_put_sync(dc_crtc->pe->dev);
>>>> +		if (ret)
>>>> +			dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
>>>> +				    ret);
>>>> +	}
>>>> +
>>>> +	ret = pm_runtime_put_sync(dc_crtc->de->dev);
>>>> +	if (ret < 0)
>>>> +		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
>>>> +			    ret);
>>>> +}
>>>> +
>>>> +static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
>>>> +					 bool in_vblank_irq,
>>>> +					 int *vpos, int *hpos,
>>>> +					 ktime_t *stime, ktime_t *etime,
>>>> +					 const struct drm_display_mode *mode)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>> +	int vdisplay = mode->crtc_vdisplay;
>>>> +	int vtotal = mode->crtc_vtotal;
>>>> +	bool reliable;
>>>> +	int line;
>>>> +	int idx;
>>>> +
>>>> +	if (stime)
>>>> +		*stime = ktime_get();
>>>> +
>>>> +	if (!drm_dev_enter(crtc->dev, &idx)) {
>>>> +		reliable = false;
>>>> +		*vpos = 0;
>>>> +		*hpos = 0;
>>>> +		goto out;
>>>> +	}
>>>> +
>>>> +	/* line index starts with 0 for the first active output line */
>>>> +	line = dc_fg_get_line_index(dc_crtc->fg);
>>>> +
>>>> +	if (line < vdisplay)
>>>> +		/* active scanout area - positive */
>>>> +		*vpos = line + 1;
>>>> +	else
>>>> +		/* inside vblank - negative */
>>>> +		*vpos = line - (vtotal - 1);
>>>> +
>>>> +	*hpos = 0;
>>>> +
>>>> +	reliable = true;
>>>> +
>>>> +	drm_dev_exit(idx);
>>>> +out:
>>>> +	if (etime)
>>>> +		*etime = ktime_get();
>>>> +
>>>> +	return reliable;
>>>> +}
>>>> +
>>>> +static const struct drm_crtc_helper_funcs dc_helper_funcs = {
>>>> +	.mode_valid		= dc_crtc_mode_valid,
>>>> +	.atomic_check		= dc_crtc_atomic_check,
>>>> +	.atomic_begin		= dc_crtc_atomic_begin,
>>>> +	.atomic_flush		= dc_crtc_atomic_flush,
>>>> +	.atomic_enable		= dc_crtc_atomic_enable,
>>>> +	.atomic_disable		= dc_crtc_atomic_disable,
>>>> +	.get_scanout_position	= dc_crtc_get_scanout_position,
>>>> +};
>>>> +
>>>> +static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
>>>> +{
>>>> +	struct {
>>>> +		struct device *dev;
>>>> +		unsigned int irq;
>>>> +		irqreturn_t (*irq_handler)(int irq, void *dev_id);
>>>> +	} irqs[DC_CRTC_IRQS] = {
>>>> +		{
>>>> +			dc_crtc->de->dev,
>>>> +			dc_crtc->irq_dec_framecomplete,
>>>> +			dc_crtc_dec_framecomplete_irq_handler,
>>>> +		}, {
>>>> +			dc_crtc->de->dev,
>>>> +			dc_crtc->irq_dec_seqcomplete,
>>>> +			dc_crtc_common_irq_handler,
>>>> +		}, {
>>>> +			dc_crtc->de->dev,
>>>> +			dc_crtc->irq_dec_shdld,
>>>> +			dc_crtc_common_irq_handler,
>>>> +		}, {
>>>> +			dc_crtc->ed_cont->dev,
>>>> +			dc_crtc->irq_ed_cont_shdld,
>>>> +			dc_crtc_common_irq_handler,
>>>> +		}, {
>>>> +			dc_crtc->ed_safe->dev,
>>>> +			dc_crtc->irq_ed_safe_shdld,
>>>> +			dc_crtc_common_irq_handler,
>>>> +		},
>>>> +	};
>>>> +	int i, ret;
>>>> +
>>>> +	for (i = 0; i < DC_CRTC_IRQS; i++) {
>>>> +		struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
>>>> +
>>>> +		ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
>>>> +				       irqs[i].irq_handler, IRQF_NO_AUTOEN,
>>>> +				       dev_name(irqs[i].dev), dc_crtc);
>>>> +		if (ret) {
>>>> +			dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
>>>> +				irqs[i].irq, ret);
>>>> +			return ret;
>>>> +		}
>>>> +
>>>> +		irq->dc_crtc = dc_crtc;
>>>> +		irq->irq = irqs[i].irq;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
>>>> +	struct drm_device *drm = &dc_drm->base;
>>>> +	struct dc_de *de = dc_drm->de[crtc_index];
>>>> +	struct dc_pe *pe = dc_drm->pe;
>>>> +	struct dc_plane *dc_primary;
>>>> +	int ret;
>>>> +
>>>> +	dc_crtc->de = de;
>>>> +	dc_crtc->pe = pe;
>>>> +
>>>> +	init_completion(&dc_crtc->dec_seqcomplete_done);
>>>> +	init_completion(&dc_crtc->dec_shdld_done);
>>>> +	init_completion(&dc_crtc->ed_cont_shdld_done);
>>>> +	init_completion(&dc_crtc->ed_safe_shdld_done);
>>>> +
>>>> +	dc_crtc->cf_cont = pe->cf_cont[crtc_index];
>>>> +	dc_crtc->cf_safe = pe->cf_safe[crtc_index];
>>>> +	dc_crtc->ed_cont = pe->ed_cont[crtc_index];
>>>> +	dc_crtc->ed_safe = pe->ed_safe[crtc_index];
>>>> +	dc_crtc->fg = de->fg;
>>>> +
>>>> +	dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
>>>> +	dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
>>>> +	dc_crtc->irq_dec_shdld = de->irq_shdld;
>>>> +	dc_crtc->irq_ed_safe_shdld = dc_crtc->ed_safe->irq_shdld;
>>>> +	dc_crtc->irq_ed_cont_shdld = dc_crtc->ed_cont->irq_shdld;
>>>> +
>>>> +	dc_primary = &dc_drm->dc_primary[crtc_index];
>>>> +	ret = dc_plane_init(dc_drm, dc_primary);
>>>> +	if (ret) {
>>>> +		dev_err(drm->dev,
>>>> +			"failed to init primary plane for display engine%u: %d\n",
>>>> +			de->id, ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
>>>> +
>>>> +	ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
>>>> +					NULL, &dc_crtc_funcs, NULL);
>>>> +	if (ret)
>>>> +		dev_err(drm->dev,
>>>> +			"failed to add CRTC for display engine%u: %d\n",
>>>> +			de->id, ret);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
>>>> +	struct drm_device *drm = &dc_drm->base;
>>>> +
>>>> +	return dc_crtc_request_irqs(drm, dc_crtc);
>>>> +}
>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
>>>> index 17a44362118e..8a7b6c03a222 100644
>>>> --- a/drivers/gpu/drm/imx/dc/dc-de.h
>>>> +++ b/drivers/gpu/drm/imx/dc/dc-de.h
>>>> @@ -13,6 +13,9 @@
>>>>  
>>>>  #define DC_DISPLAYS	2
>>>>  
>>>> +#define DC_FRAMEGEN_MAX_FRAME_INDEX	0x3ffff
>>>> +#define DC_FRAMEGEN_MAX_CLOCK_KHZ	300000
>>>> +
>>>>  struct dc_fg {
>>>>  	struct device *dev;
>>>>  	struct regmap *reg;
>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
>>>> index fd68861f770a..1e4b8afa3eec 100644
>>>> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
>>>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
>>>> @@ -3,11 +3,254 @@
>>>>   * Copyright 2024 NXP
>>>>   */
>>>>  
>>>> +#include <linux/clk.h>
>>>> +#include <linux/component.h>
>>>> +#include <linux/device.h>
>>>> +#include <linux/dma-mapping.h>
>>>> +#include <linux/mod_devicetable.h>
>>>>  #include <linux/module.h>
>>>> +#include <linux/of.h>
>>>> +#include <linux/of_platform.h>
>>>>  #include <linux/platform_device.h>
>>>> +#include <linux/pm.h>
>>>> +#include <linux/pm_runtime.h>
>>>>  
>>>> +#include <drm/drm_atomic_helper.h>
>>>> +#include <drm/drm_client_setup.h>
>>>> +#include <drm/drm_crtc.h>
>>>> +#include <drm/drm_drv.h>
>>>> +#include <drm/drm_fbdev_dma.h>
>>>> +#include <drm/drm_fourcc.h>
>>>> +#include <drm/drm_gem_dma_helper.h>
>>>> +#include <drm/drm_managed.h>
>>>> +#include <drm/drm_modeset_helper.h>
>>>> +#include <drm/drm_of.h>
>>>> +
>>>> +#include "dc-de.h"
>>>>  #include "dc-drv.h"
>>>>  
>>>> +struct dc_priv {
>>>> +	struct drm_device *drm;
>>>> +	struct clk *clk_cfg;
>>>> +};
>>>> +
>>>> +DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
>>>> +
>>>> +static struct drm_driver dc_drm_driver = {
>>>> +	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
>>>> +	DRM_GEM_DMA_DRIVER_OPS,
>>>> +	DRM_FBDEV_DMA_DRIVER_OPS,
>>>> +	.fops = &dc_drm_driver_fops,
>>>> +	.name = "imx8-dc",
>>>> +	.desc = "i.MX8 DC DRM graphics",
>>>> +	.date = "20240530",
>>>> +	.major = 1,
>>>> +	.minor = 0,
>>>> +	.patchlevel = 0,
>>>> +};
>>>> +
>>>> +static void
>>>> +dc_add_components(struct device *dev, struct component_match **matchptr)
>>>> +{
>>>> +	struct device_node *child, *grandchild;
>>>> +
>>>> +	for_each_available_child_of_node(dev->of_node, child) {
>>>> +		/* The interrupt controller is not a component. */
>>>> +		if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
>>>> +			continue;
>>>> +
>>>> +		drm_of_component_match_add(dev, matchptr, component_compare_of,
>>>> +					   child);
>>>> +
>>>> +		for_each_available_child_of_node(child, grandchild)
>>>> +			drm_of_component_match_add(dev, matchptr,
>>>> +						   component_compare_of,
>>>> +						   grandchild);
>>>> +	}
>>>> +}
>>>> +
>>>> +static void dc_drm_component_unbind_all(void *ptr)
>>>> +{
>>>> +	struct dc_drm_device *dc_drm = ptr;
>>>> +	struct drm_device *drm = &dc_drm->base;
>>>> +
>>>> +	component_unbind_all(drm->dev, dc_drm);
>>>> +}
>>>> +
>>>> +static int dc_drm_bind(struct device *dev)
>>>> +{
>>>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>>>> +	struct dc_drm_device *dc_drm;
>>>> +	struct drm_device *drm;
>>>> +	int ret;
>>>> +
>>>> +	dc_drm = devm_drm_dev_alloc(dev, &dc_drm_driver, struct dc_drm_device,
>>>> +				    base);
>>>> +	if (IS_ERR(dc_drm))
>>>> +		return PTR_ERR(dc_drm);
>>>> +
>>>> +	drm = &dc_drm->base;
>>>> +
>>>> +	ret = component_bind_all(dev, dc_drm);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = devm_add_action_or_reset(dev, dc_drm_component_unbind_all,
>>>> +				       dc_drm);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = dc_kms_init(dc_drm);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = drm_dev_register(drm, 0);
>>>> +	if (ret) {
>>>> +		dev_err(dev, "failed to register drm device: %d\n", ret);
>>>> +		goto err;
>>>> +	}
>>>> +
>>>> +	drm_client_setup_with_fourcc(drm, DRM_FORMAT_XRGB8888);
>>>> +
>>>> +	priv->drm = drm;
>>>> +
>>>> +	return 0;
>>>> +
>>>> +err:
>>>> +	dc_kms_uninit(dc_drm);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +static void dc_drm_unbind(struct device *dev)
>>>> +{
>>>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>>>> +	struct dc_drm_device *dc_drm = to_dc_drm_device(priv->drm);
>>>> +	struct drm_device *drm = &dc_drm->base;
>>>> +	struct drm_crtc *crtc;
>>>> +
>>>> +	priv->drm = NULL;
>>>> +	drm_dev_unplug(drm);
>>>> +	dc_kms_uninit(dc_drm);
>>>> +	drm_atomic_helper_shutdown(drm);
>>>> +
>>>> +	drm_for_each_crtc(crtc, drm)
>>>> +		dc_crtc_disable_at_unbind(crtc);
>>>
>>> There should be no need for that. drm_atomic_helper_shutdown() should
>>> disable all the CRTCs.
>>
>> In case DRM device is unplugged, drm_atomic_helper_shutdown does not
>> effectively disable the CRTCs due to the bypassed logics wrapped by
>> drm_dev_{enter,exit}.  That's why dc_crtc_disable_at_unbind() is called
>> here to effectively disable the CRTCs.
> 
> I see. I haven't faced drm_dev_unplug() earlier. I checked, the "not
> disabled" behaviour is documented and all other drivers don't perform
> any kind of cleanup afterwards. Thus I think it's safe to drop the
> dc_crtc_disable_at_unbind() unless it causes any kind of HW issues.

IMHO, it's a bit safer to set the HWs backing the CRTCs to a known state
at the unbind stage by properly disabling them, in case there is any
unknown SW or HW issue.  Plus, i.MX8qm/qxp SoCs don't provide reset
signals to the Display Controllers(the resets DT property is optional),
otherwise, this disablement function can be dropped(at least for now).

> 
>>
>>>
>>> Also, who is going to do drm_dev_unregister()? I don't see it in the
>>> code.
>>
>> drm_dev_unplug() right above calls drm_dev_unregister().
>>
>>>
>>>> +}
>>>> +
>>>> +static const struct component_master_ops dc_drm_ops = {
>>>> +	.bind = dc_drm_bind,
>>>> +	.unbind = dc_drm_unbind,
>>>> +};
>>>> +
>>>> +static int dc_probe(struct platform_device *pdev)
>>>> +{
>>>> +	struct component_match *match = NULL;
>>>> +	struct dc_priv *priv;
>>>> +	int ret;
>>>> +
>>>> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>>>> +	if (!priv)
>>>> +		return -ENOMEM;
>>>> +
>>>> +	priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
>>>> +	if (IS_ERR(priv->clk_cfg))
>>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
>>>> +				     "failed to get cfg clock\n");
>>>> +
>>>> +	dev_set_drvdata(&pdev->dev, priv);
>>>> +
>>>> +	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = devm_pm_runtime_enable(&pdev->dev);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = devm_of_platform_populate(&pdev->dev);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	dc_add_components(&pdev->dev, &match);
>>>> +
>>>> +	ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
>>>> +	if (ret)
>>>> +		return dev_err_probe(&pdev->dev, ret,
>>>> +				     "failed to add component master\n");
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static void dc_remove(struct platform_device *pdev)
>>>> +{
>>>> +	component_master_del(&pdev->dev, &dc_drm_ops);
>>>> +}
>>>> +
>>>> +static int dc_runtime_suspend(struct device *dev)
>>>> +{
>>>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>>>> +
>>>> +	clk_disable_unprepare(priv->clk_cfg);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int dc_runtime_resume(struct device *dev)
>>>> +{
>>>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>>>> +	int ret;
>>>> +
>>>> +	ret = clk_prepare_enable(priv->clk_cfg);
>>>> +	if (ret)
>>>> +		dev_err(dev, "failed to enable cfg clock: %d\n", ret);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +static int dc_suspend(struct device *dev)
>>>> +{
>>>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>>>> +
>>>> +	return drm_mode_config_helper_suspend(priv->drm);
>>>> +}
>>>> +
>>>> +static int dc_resume(struct device *dev)
>>>> +{
>>>> +	struct dc_priv *priv = dev_get_drvdata(dev);
>>>> +
>>>> +	return drm_mode_config_helper_resume(priv->drm);
>>>> +}
>>>> +
>>>> +static void dc_shutdown(struct platform_device *pdev)
>>>> +{
>>>> +	struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
>>>> +
>>>> +	drm_atomic_helper_shutdown(priv->drm);
>>>> +}
>>>> +
>>>> +static const struct dev_pm_ops dc_pm_ops = {
>>>> +	RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
>>>> +	SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
>>>> +};
>>>> +
>>>> +static const struct of_device_id dc_dt_ids[] = {
>>>> +	{ .compatible = "fsl,imx8qxp-dc", },
>>>> +	{ /* sentinel */ }
>>>> +};
>>>> +MODULE_DEVICE_TABLE(of, dc_dt_ids);
>>>> +
>>>> +static struct platform_driver dc_driver = {
>>>> +	.probe = dc_probe,
>>>> +	.remove = dc_remove,
>>>> +	.shutdown = dc_shutdown,
>>>> +	.driver = {
>>>> +		.name = "imx8-dc",
>>>> +		.of_match_table	= dc_dt_ids,
>>>> +		.pm = pm_sleep_ptr(&dc_pm_ops),
>>>> +	},
>>>> +};
>>>> +
>>>>  static struct platform_driver * const dc_drivers[] = {
>>>>  	&dc_cf_driver,
>>>>  	&dc_de_driver,
>>>> @@ -19,6 +262,7 @@ static struct platform_driver * const dc_drivers[] = {
>>>>  	&dc_lb_driver,
>>>>  	&dc_pe_driver,
>>>>  	&dc_tc_driver,
>>>> +	&dc_driver,
>>>>  };
>>>>  
>>>>  static int __init dc_drm_init(void)
>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
>>>> index 3b11f4862c6c..39a771a13933 100644
>>>> --- a/drivers/gpu/drm/imx/dc/dc-drv.h
>>>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.h
>>>> @@ -6,19 +6,38 @@
>>>>  #ifndef __DC_DRV_H__
>>>>  #define __DC_DRV_H__
>>>>  
>>>> +#include <linux/container_of.h>
>>>>  #include <linux/platform_device.h>
>>>>  
>>>>  #include <drm/drm_device.h>
>>>> +#include <drm/drm_encoder.h>
>>>>  
>>>>  #include "dc-de.h"
>>>> +#include "dc-kms.h"
>>>>  #include "dc-pe.h"
>>>>  
>>>>  struct dc_drm_device {
>>>>  	struct drm_device base;
>>>> +	struct dc_crtc dc_crtc[DC_DISPLAYS];
>>>> +	struct dc_plane dc_primary[DC_DISPLAYS];
>>>> +	struct drm_encoder encoder[DC_DISPLAYS];
>>>>  	struct dc_de *de[DC_DISPLAYS];
>>>>  	struct dc_pe *pe;
>>>>  };
>>>>  
>>>> +static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
>>>> +{
>>>> +	return container_of(drm, struct dc_drm_device, base);
>>>> +}
>>>> +
>>>> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
>>>> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
>>>> +
>>>> +int dc_kms_init(struct dc_drm_device *dc_drm);
>>>> +void dc_kms_uninit(struct dc_drm_device *dc_drm);
>>>> +
>>>> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
>>>> +
>>>>  extern struct platform_driver dc_cf_driver;
>>>>  extern struct platform_driver dc_ed_driver;
>>>>  extern struct platform_driver dc_de_driver;
>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
>>>> new file mode 100644
>>>> index 000000000000..2b18aa37a4a8
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/imx/dc/dc-kms.c
>>>> @@ -0,0 +1,143 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +/*
>>>> + * Copyright 2024 NXP
>>>> + */
>>>> +
>>>> +#include <linux/of.h>
>>>> +#include <linux/of_graph.h>
>>>> +
>>>> +#include <drm/drm_atomic_helper.h>
>>>> +#include <drm/drm_bridge.h>
>>>> +#include <drm/drm_bridge_connector.h>
>>>> +#include <drm/drm_connector.h>
>>>> +#include <drm/drm_crtc.h>
>>>> +#include <drm/drm_device.h>
>>>> +#include <drm/drm_encoder.h>
>>>> +#include <drm/drm_gem_framebuffer_helper.h>
>>>> +#include <drm/drm_mode_config.h>
>>>> +#include <drm/drm_print.h>
>>>> +#include <drm/drm_probe_helper.h>
>>>> +#include <drm/drm_simple_kms_helper.h>
>>>> +#include <drm/drm_vblank.h>
>>>> +
>>>> +#include "dc-de.h"
>>>> +#include "dc-drv.h"
>>>> +#include "dc-kms.h"
>>>> +
>>>> +static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
>>>> +	.fb_create = drm_gem_fb_create,
>>>> +	.atomic_check = drm_atomic_helper_check,
>>>> +	.atomic_commit = drm_atomic_helper_commit,
>>>> +};
>>>> +
>>>> +static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
>>>> +					int crtc_index)
>>>> +{
>>>> +	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
>>>> +	struct drm_device *drm = &dc_drm->base;
>>>> +	struct drm_crtc *crtc = &dc_crtc->base;
>>>> +	struct drm_connector *connector;
>>>> +	struct device *dev = drm->dev;
>>>> +	struct drm_encoder *encoder;
>>>> +	struct drm_bridge *bridge;
>>>> +	int ret;
>>>> +
>>>> +	bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
>>>> +					0, 0);
>>>> +	if (IS_ERR(bridge)) {
>>>> +		ret = PTR_ERR(bridge);
>>>> +		if (ret == -ENODEV)
>>>> +			return 0;
>>>> +
>>>> +		return dev_err_probe(dev, ret,
>>>> +				     "failed to find bridge for CRTC%u\n",
>>>> +				     crtc->index);
>>>> +	}
>>>> +
>>>> +	encoder = &dc_drm->encoder[crtc_index];
>>>> +	ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
>>>> +	if (ret) {
>>>> +		dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
>>>> +			crtc->index, ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	encoder->possible_crtcs = drm_crtc_mask(crtc);
>>>> +
>>>> +	ret = drm_bridge_attach(encoder, bridge, NULL,
>>>> +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>> +	if (ret) {
>>>> +		dev_err(dev,
>>>> +			"failed to attach bridge to encoder for CRTC%u: %d\n",
>>>> +			crtc->index, ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	connector = drm_bridge_connector_init(drm, encoder);
>>>> +	if (IS_ERR(connector)) {
>>>> +		ret = PTR_ERR(connector);
>>>> +		dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
>>>> +			crtc->index, ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	ret = drm_connector_attach_encoder(connector, encoder);
>>>> +	if (ret)
>>>> +		dev_err(dev,
>>>> +			"failed to attach encoder to connector for CRTC%u: %d\n",
>>>> +			crtc->index, ret);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +int dc_kms_init(struct dc_drm_device *dc_drm)
>>>> +{
>>>> +	struct drm_device *drm = &dc_drm->base;
>>>> +	int ret, i;
>>>> +
>>>> +	ret = drmm_mode_config_init(drm);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	drm->mode_config.min_width = 60;
>>>> +	drm->mode_config.min_height = 60;
>>>> +	drm->mode_config.max_width = 8192;
>>>> +	drm->mode_config.max_height = 8192;
>>>> +	drm->mode_config.funcs = &dc_drm_mode_config_funcs;
>>>> +
>>>> +	drm->vblank_disable_immediate = true;
>>>> +	drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
>>>> +
>>>> +	for (i = 0; i < DC_DISPLAYS; i++) {
>>>> +		ret = dc_crtc_init(dc_drm, i);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +
>>>> +		ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +	}
>>>> +
>>>> +	for (i = 0; i < DC_DISPLAYS; i++) {
>>>> +		ret = dc_crtc_post_init(dc_drm, i);
>>>
>>> Can you use .late_register for this?
>>
>> Kerneldoc of struct drm_crtc_funcs::late_register says it's used to register
>> additional userspace interfaces like debugfs interfaces. And, it seems that
>> everyone implementing this uses it to add debugfs interfaces. So, it will
>> kind of abuse it to do CRTC post initialization.
> 
> Why can't they be requested earlier then?

If I request them earlier in dc_crtc_init(), then they cannot be freed by
devm_irq_release() when devm_drm_of_get_bridge() called by
dc_kms_init_encoder_per_crtc() returns -EPROBE_DEFER(which means failing
to find the first DRM bridge for the CRTC).  Why can't they be freed by
devm_irq_release()?  Because they are requested by the devices of ExtDsts
and Display Engines and their drivers are not removed during the probe
deferral dance.  Furthermore, -EPROBE_DEFER won't be returned after
dc_crtc_post_init() since the later called drm_vblank_init() doesn't
return -EPROBE_DEFER anyway, so it's fine to call dc_crtc_post_init() here.

I met the irq free issue on my i.MX8qxp MEK board before, i.e., -EBUSY is
returned when requesting them again, so it's tested.

> 
>>
>>>
>>>> +		if (ret)
>>>> +			return ret;
>>>> +	}
>>>> +
>>>> +	ret = drm_vblank_init(drm, DC_DISPLAYS);
>>>> +	if (ret) {
>>>> +		dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	drm_mode_config_reset(drm);
>>>> +
>>>> +	drm_kms_helper_poll_init(drm);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +void dc_kms_uninit(struct dc_drm_device *dc_drm)
>>>> +{
>>>> +	drm_kms_helper_poll_fini(&dc_drm->base);
>>>> +}
>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
>>>> new file mode 100644
>>>> index 000000000000..57f6e0c15f57
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/imx/dc/dc-kms.h
>>>> @@ -0,0 +1,58 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>>> +/*
>>>> + * Copyright 2024 NXP
>>>> + */
>>>> +
>>>> +#ifndef __DC_KMS_H__
>>>> +#define __DC_KMS_H__
>>>> +
>>>> +#include <linux/completion.h>
>>>> +
>>>> +#include <drm/drm_crtc.h>
>>>> +#include <drm/drm_plane.h>
>>>> +#include <drm/drm_vblank.h>
>>>> +
>>>> +#include "dc-de.h"
>>>> +#include "dc-fu.h"
>>>> +#include "dc-pe.h"
>>>> +
>>>> +#define DC_CRTC_IRQS	5
>>>> +
>>>> +struct dc_crtc_irq {
>>>> +	struct dc_crtc *dc_crtc;
>>>> +	unsigned int irq;
>>>> +};
>>>> +
>>>
>>> Please provide some documentation for the structure in the form of the
>>> kerneldoc. E.g. what is the difference between ed_cont and ed_safe?
>>
>> Will add kerneldoc for struct dc_{crtc,plane,drm_device} and tell the
>> difference between ed_cont(content stream) and ed_safe(safety stream).
>>
>>> The de and fg pointers are global, please don't cache them
>>> unnecessarily.
>>
>> Global? I don't catch your meaning, sorry. To me, it's handy to access de
>> and fg via the two pointers in struct dc_crtc.
> 
> I had to spend some time understanding if they are per-CRTC or if there
> are a single instances of those subdevices. Thus I suggest to access

They are per-CRTC.  One Display Controller contains two Display Engines,
hence two CRTCs.

> them through dc_drm_device. You can ignore this suggestion though.

I'll ignore this.  Thanks anyway.

> 
>>
>>>
>>>> +struct dc_crtc {
>>>> +	struct drm_crtc base;
>>>> +	struct dc_de *de;
>>>> +	struct dc_pe *pe;
>>>> +	struct dc_cf *cf_cont;
>>>> +	struct dc_cf *cf_safe;
>>>> +	struct dc_ed *ed_cont;
>>>> +	struct dc_ed *ed_safe;
>>>> +	struct dc_fg *fg;
>>>> +	unsigned int irq_dec_framecomplete;
>>>> +	unsigned int irq_dec_seqcomplete;
>>>> +	unsigned int irq_dec_shdld;
>>>> +	unsigned int irq_ed_cont_shdld;
>>>> +	unsigned int irq_ed_safe_shdld;
>>>> +	struct completion dec_seqcomplete_done;
>>>> +	struct completion dec_shdld_done;
>>>> +	struct completion ed_safe_shdld_done;
>>>> +	struct completion ed_cont_shdld_done;
>>>> +	struct drm_pending_vblank_event *event;
>>>> +	struct dc_crtc_irq irqs[DC_CRTC_IRQS];
>>>> +};
>>>> +
>>>> +struct dc_plane {
>>>> +	struct drm_plane base;
>>>> +	struct dc_fu *fu;
>>>> +	struct dc_cf *cf;
>>>> +	struct dc_lb *lb;
>>>> +	struct dc_ed *ed;
>>>> +};
>>>> +
>>>> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc);
>>>> +
>>>> +#endif /* __DC_KMS_H__ */
>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
>>>> new file mode 100644
>>>> index 000000000000..78d0d2cd3451
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/imx/dc/dc-plane.c
>>>> @@ -0,0 +1,241 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +/*
>>>> + * Copyright 2024 NXP
>>>> + */
>>>> +
>>>> +#include <linux/container_of.h>
>>>> +
>>>> +#include <drm/drm_atomic.h>
>>>> +#include <drm/drm_atomic_helper.h>
>>>> +#include <drm/drm_atomic_state_helper.h>
>>>> +#include <drm/drm_crtc.h>
>>>> +#include <drm/drm_drv.h>
>>>> +#include <drm/drm_fb_dma_helper.h>
>>>> +#include <drm/drm_fourcc.h>
>>>> +#include <drm/drm_framebuffer.h>
>>>> +#include <drm/drm_gem_atomic_helper.h>
>>>> +#include <drm/drm_plane_helper.h>
>>>> +#include <drm/drm_print.h>
>>>> +
>>>> +#include "dc-drv.h"
>>>> +#include "dc-fu.h"
>>>> +#include "dc-kms.h"
>>>> +
>>>> +#define DC_PLANE_MAX_PITCH	0x10000
>>>> +#define DC_PLANE_MAX_PIX_CNT	8192
>>>> +
>>>> +#define dc_plane_dbg(plane, fmt, ...)					\
>>>> +do {									\
>>>> +	typeof(plane) _plane = (plane);					\
>>>> +	drm_dbg_kms(_plane->dev, "[PLANE:%d:%s] " fmt,			\
>>>> +		    _plane->base.id, _plane->name, ##__VA_ARGS__);	\
>>>> +} while (0)
>>>> +
>>>> +static const uint32_t dc_plane_formats[] = {
>>>> +	DRM_FORMAT_XRGB8888,
>>>> +};
>>>> +
>>>> +static const struct drm_plane_funcs dc_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,
>>>> +};
>>>> +
>>>> +static inline struct dc_plane *to_dc_plane(struct drm_plane *plane)
>>>> +{
>>>> +	return container_of(plane, struct dc_plane, base);
>>>> +}
>>>> +
>>>> +static int dc_plane_check_no_off_screen(struct drm_plane_state *state,
>>>> +					struct drm_crtc_state *crtc_state)
>>>> +{
>>>> +	if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
>>>> +	    state->dst.x2 > crtc_state->adjusted_mode.hdisplay ||
>>>> +	    state->dst.y2 > crtc_state->adjusted_mode.vdisplay) {
>>>> +		dc_plane_dbg(state->plane, "no off screen\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int dc_plane_check_max_source_resolution(struct drm_plane_state *state)
>>>> +{
>>>> +	int src_h = drm_rect_height(&state->src) >> 16;
>>>> +	int src_w = drm_rect_width(&state->src) >> 16;
>>>> +
>>>> +	if (src_w > DC_PLANE_MAX_PIX_CNT || src_h > DC_PLANE_MAX_PIX_CNT) {
>>>> +		dc_plane_dbg(state->plane, "invalid source resolution\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int dc_plane_check_fb(struct drm_plane_state *state)
>>>> +{
>>>> +	struct drm_framebuffer *fb = state->fb;
>>>> +	dma_addr_t baseaddr = drm_fb_dma_get_gem_addr(fb, state, 0);
>>>> +
>>>> +	/* base address alignment */
>>>> +	if (baseaddr & 0x3) {
>>>> +		dc_plane_dbg(state->plane, "fb bad baddr alignment\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	/* pitches[0] range */
>>>> +	if (fb->pitches[0] > DC_PLANE_MAX_PITCH) {
>>>> +		dc_plane_dbg(state->plane, "fb pitches[0] is out of range\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	/* pitches[0] alignment */
>>>> +	if (fb->pitches[0] & 0x3) {
>>>> +		dc_plane_dbg(state->plane, "fb bad pitches[0] alignment\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int
>>>> +dc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
>>>> +{
>>>> +	struct drm_plane_state *plane_state =
>>>> +				drm_atomic_get_new_plane_state(state, plane);
>>>> +	struct drm_crtc_state *crtc_state;
>>>> +	int ret;
>>>> +
>>>> +	/* ok to disable */
>>>> +	if (!plane_state->fb)
>>>> +		return 0;
>>>> +
>>>> +	if (!plane_state->crtc) {
>>>> +		dc_plane_dbg(plane, "no CRTC in plane state\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	crtc_state =
>>>> +		drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
>>>> +	if (WARN_ON(!crtc_state))
>>>> +		return -EINVAL;
>>>> +
>>>> +	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
>>>> +						  DRM_PLANE_NO_SCALING,
>>>> +						  DRM_PLANE_NO_SCALING,
>>>> +						  true, false);
>>>> +	if (ret) {
>>>> +		dc_plane_dbg(plane, "failed to check plane state: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	ret = dc_plane_check_no_off_screen(plane_state, crtc_state);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = dc_plane_check_max_source_resolution(plane_state);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	return dc_plane_check_fb(plane_state);
>>>> +}
>>>> +
>>>> +static void
>>>> +dc_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state)
>>>> +{
>>>> +	struct drm_plane_state *new_state =
>>>> +				drm_atomic_get_new_plane_state(state, plane);
>>>> +	struct dc_plane *dplane = to_dc_plane(plane);
>>>> +	struct drm_framebuffer *fb = new_state->fb;
>>>> +	const struct dc_fu_ops *fu_ops;
>>>> +	struct dc_lb *lb = dplane->lb;
>>>> +	struct dc_fu *fu = dplane->fu;
>>>> +	dma_addr_t baseaddr;
>>>> +	int src_w, src_h;
>>>> +	int idx;
>>>> +
>>>> +	if (!drm_dev_enter(plane->dev, &idx))
>>>> +		return;
>>>> +
>>>> +	src_w = drm_rect_width(&new_state->src) >> 16;
>>>> +	src_h = drm_rect_height(&new_state->src) >> 16;
>>>> +
>>>> +	baseaddr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
>>>> +
>>>> +	fu_ops = dc_fu_get_ops(dplane->fu);
>>>> +
>>>> +	fu_ops->set_layerblend(fu, lb);
>>>> +	fu_ops->set_burstlength(fu, baseaddr);
>>>> +	fu_ops->set_src_stride(fu, DC_FETCHUNIT_FRAC0, fb->pitches[0]);
>>>> +	fu_ops->set_src_buf_dimensions(fu, DC_FETCHUNIT_FRAC0, src_w, src_h);
>>>> +	fu_ops->set_fmt(fu, DC_FETCHUNIT_FRAC0, fb->format);
>>>> +	fu_ops->set_framedimensions(fu, src_w, src_h);
>>>> +	fu_ops->set_baseaddress(fu, DC_FETCHUNIT_FRAC0, baseaddr);
>>>> +	fu_ops->enable_src_buf(fu, DC_FETCHUNIT_FRAC0);
>>>> +
>>>> +	dc_plane_dbg(plane, "uses %s\n", fu_ops->get_name(fu));
>>>> +
>>>> +	dc_lb_pec_dynamic_prim_sel(lb, dc_cf_get_link_id(dplane->cf));
>>>> +	dc_lb_pec_dynamic_sec_sel(lb, fu_ops->get_link_id(fu));
>>>> +	dc_lb_mode(lb, LB_BLEND);
>>>> +	dc_lb_position(lb, new_state->dst.x1, new_state->dst.y1);
>>>> +	dc_lb_pec_clken(lb, CLKEN_AUTOMATIC);
>>>> +
>>>> +	dc_plane_dbg(plane, "uses LayerBlend%u\n", dc_lb_get_id(lb));
>>>> +
>>>> +	/* set ExtDst's source to LayerBlend */
>>>> +	dc_ed_pec_src_sel(dplane->ed, dc_lb_get_link_id(lb));
>>>> +
>>>> +	drm_dev_exit(idx);
>>>> +}
>>>> +
>>>> +static void dc_plane_atomic_disable(struct drm_plane *plane,
>>>> +				    struct drm_atomic_state *state)
>>>> +{
>>>> +	struct dc_plane *dplane = to_dc_plane(plane);
>>>> +	const struct dc_fu_ops *fu_ops;
>>>> +	int idx;
>>>> +
>>>> +	if (!drm_dev_enter(plane->dev, &idx))
>>>> +		return;
>>>> +
>>>> +	/* disable fetchunit in shadow */
>>>> +	fu_ops = dc_fu_get_ops(dplane->fu);
>>>> +	fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
>>>> +
>>>> +	/* set ExtDst's source to ConstFrame */
>>>> +	dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
>>>> +
>>>> +	drm_dev_exit(idx);
>>>> +}
>>>> +
>>>> +static const struct drm_plane_helper_funcs dc_plane_helper_funcs = {
>>>> +	.atomic_check = dc_plane_atomic_check,
>>>> +	.atomic_update = dc_plane_atomic_update,
>>>> +	.atomic_disable = dc_plane_atomic_disable,
>>>> +};
>>>> +
>>>> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
>>>> +{
>>>> +	struct drm_plane *plane = &dc_plane->base;
>>>> +	int ret;
>>>> +
>>>> +	ret = drm_universal_plane_init(&dc_drm->base, plane, 0, &dc_plane_funcs,
>>>> +				       dc_plane_formats,
>>>> +				       ARRAY_SIZE(dc_plane_formats),
>>>> +				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	drm_plane_helper_add(plane, &dc_plane_helper_funcs);
>>>> +
>>>> +	dc_plane->fu = dc_drm->pe->fu_disp[plane->index];
>>>> +	dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
>>>> +	dc_plane->lb = dc_drm->pe->lb[plane->index];
>>>> +	dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
>>>> +
>>>> +	return 0;
>>>> +}
>>>> -- 
>>>> 2.34.1
>>>>
>>>
>>
>> -- 
>> Regards,
>> Liu Ying
> 

-- 
Regards,
Liu Ying


From Jason-JH.Lin at mediatek.com  Thu Dec 12 22:22:47 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Fri, 13 Dec 2024 06:22:47 +0000
Subject: [PATCH 1/2] dt-bindings: display: mediatek: ovl: Modify rules for
 MT8195/MT8188
In-Reply-To: <CAEXTbpfc0ybrvMCuJkKAUwXXTtpZ=vU9MLfU=4CzgdTd-ck4qw@mail.gmail.com>
References: <20241212153344.27408-1-jason-jh.lin@mediatek.com>
	 <20241212153344.27408-2-jason-jh.lin@mediatek.com>
	 <CAEXTbpfc0ybrvMCuJkKAUwXXTtpZ=vU9MLfU=4CzgdTd-ck4qw@mail.gmail.com>
Message-ID: <8b010e16175217d0668b97e206c5059c59e6e414.camel@mediatek.com>

Hi Pin-yen,

Thanks for the reviews.

On Fri, 2024-12-13 at 11:41 +0800, Pin-yen Lin wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> Hi Jason,
> 
> On Thu, Dec 12, 2024 at 11:33?PM Jason-JH.Lin <
> jason-jh.lin at mediatek.com> wrote:
> > 
> > From: Hsiao Chien Sung <shawn.sung at mediatek.com>
> > 
> > Modify rules for both MT8195 and MT8188.
> > Hardware capabilities include color formats and AFBC are
> > changed since MT8195, stop using the settings of MT8183.
> > 
> > Acked-by: Rob Herring <robh at kernel.org>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno at collabora.com>
> > Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> > Reviewed-by: CK Hu <ck.hu at mediatek.com>
> > ---
> >  .../bindings/display/mediatek/mediatek,ovl.yaml           | 8 +++-
> > ----
> >  1 file changed, 3 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.y
> > aml
> > index 9ea796a033b2..0ace12bbb623 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.y
> > aml
> > @@ -36,16 +36,14 @@ properties:
> >            - enum:
> >                - mediatek,mt6795-disp-ovl
> >            - const: mediatek,mt8173-disp-ovl
> > -      - items:
> > -          - enum:
> > -              - mediatek,mt8188-disp-ovl
> > -              - mediatek,mt8195-disp-ovl
> > -          - const: mediatek,mt8183-disp-ovl
> 
> This breaks the schema check for mt8195.dtsi, which is currently
> using
> `compatible = "mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-
> ovl";`
> 
> IIUC this is supposed to be a RESEND of [1], which actually added a
> binding for "mediatek,mt8195-disp-ovl". However [1] still breaks
> mt8195.dtsi because it only allows `compatible =
> "mediatek,mt8195-disp-ovl"` But not `compatible =
> "mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-ovl"`.
> 

Yes, I lost the "mediatek,mt8195-disp-ovl" in [1] at the beginning of
compatible property.
I'll add it to the next version.

> If "mediatek,mt8183-disp-ovl" is a reasonable fallback for
> "mediatek,mt8195-disp-ovl", please keep a binding like:
> 
>       - items:
>           - const: mediatek,mt8195-disp-ovl
>           - const: mediatek,mt8183-disp-ovl
> 
> Or, fix mt8195.dtsi instead in the same series.

Yes, I think the OVL in mt8195.dtsi should remove the "mediatek,mt8183-
disp-ovl" because it's not compatible anymore.

I'll add that path in the same series.

Regards,
Jason-JH.Lin


From jinjian.song at fibocom.com  Thu Dec 12 22:47:20 2024
From: jinjian.song at fibocom.com (Jinjian Song)
Date: Fri, 13 Dec 2024 14:47:20 +0800
Subject: [net v2] net: wwan: t7xx: Fix FSM command timeout issue
Message-ID: <20241213064720.122615-1-jinjian.song@fibocom.com>

When driver processes the internal state change command, it use an
asynchronous thread to process the command operation. If the main
thread detects that the task has timed out, the asynchronous thread
will panic when executing the completion notification because the
main thread completion object has been released.

BUG: unable to handle page fault for address: fffffffffffffff8
PGD 1f283a067 P4D 1f283a067 PUD 1f283c067 PMD 0
Oops: 0000 [#1] PREEMPT SMP NOPTI
RIP: 0010:complete_all+0x3e/0xa0
[...]
Call Trace:
 <TASK>
 ? __die_body+0x68/0xb0
 ? page_fault_oops+0x379/0x3e0
 ? exc_page_fault+0x69/0xa0
 ? asm_exc_page_fault+0x22/0x30
 ? complete_all+0x3e/0xa0
 fsm_main_thread+0xa3/0x9c0 [mtk_t7xx (HASH:1400 5)]
 ? __pfx_autoremove_wake_function+0x10/0x10
 kthread+0xd8/0x110
 ? __pfx_fsm_main_thread+0x10/0x10 [mtk_t7xx (HASH:1400 5)]
 ? __pfx_kthread+0x10/0x10
 ret_from_fork+0x38/0x50
 ? __pfx_kthread+0x10/0x10
 ret_from_fork_asm+0x1b/0x30
 </TASK>
[...]
CR2: fffffffffffffff8
---[ end trace 0000000000000000 ]---

After the main thread determines that the task has timed out, mark
the completion invalid, and add judgment in the asynchronous task.

Fixes: d785ed945de6 ("net: wwan: t7xx: PCIe reset rescan")
Signed-off-by: Jinjian Song <jinjian.song at fibocom.com>
---
 drivers/net/wwan/t7xx/t7xx_state_monitor.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
index 3931c7a13f5a..57f1a7730fff 100644
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
@@ -108,7 +108,8 @@ static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command
 {
 	if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
 		*cmd->ret = result;
-		complete_all(cmd->done);
+		if (cmd->done)
+			complete_all(cmd->done);
 	}
 
 	kfree(cmd);
@@ -503,8 +504,10 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id
 
 		wait_ret = wait_for_completion_timeout(&done,
 						       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
-		if (!wait_ret)
+		if (!wait_ret) {
+			cmd->done = NULL;
 			return -ETIMEDOUT;
+		}
 
 		return ret;
 	}
-- 
2.34.1



From andrej.picej at norik.com  Thu Dec 12 22:57:30 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Fri, 13 Dec 2024 07:57:30 +0100
Subject: [PATCH v6 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <45f90007-3136-4b59-a3fc-6fc0147b8ad8@wanadoo.fr>
References: <20241212121712.214639-1-andrej.picej@norik.com>
 <20241212121712.214639-3-andrej.picej@norik.com>
 <45f90007-3136-4b59-a3fc-6fc0147b8ad8@wanadoo.fr>
Message-ID: <cdf8cff7-543c-4a28-bf2e-bc7f331d0db5@norik.com>

Hi Christophe,

On 12. 12. 24 13:33, Christophe JAILLET wrote:
> Le 12/12/2024 ? 13:17, Andrej Picej a ?crit?:
>> Add a optional properties to change LVDS output voltage. This should not
>> be static as this depends mainly on the connected display voltage
>> requirement. We have three properties:
>> - "ti,lvds-termination-ohms", which sets near end termination,
>> - "ti,lvds-vod-swing-data-microvolt" and
>> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
>> output voltage for data and clock lanes. They are defined as an array
>> with min and max values. The appropriate bitfield will be set if
>> selected constraints can be met.
>>
>> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
>> end termination will be used. Selecting only one:
>> "ti,lvds-vod-swing-data-microvolt" or
>> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
>> constraint for only data/clock lanes will be met. Setting both is
>> recommended.
> 
> ...
> 
>> +static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
>> +??? u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
>> +{
>> +??? int i;
>> +
>> +??? for (i = 0; i <= 3; i++) {
>> +??????? if (lvds_vod_swing_data_table[lvds_term][i][0] >= 
>> lvds_vod_swing_data[0] &&
>> +??????? lvds_vod_swing_data_table[lvds_term][i][1] <= 
>> lvds_vod_swing_data[1] &&
>> +??????? lvds_vod_swing_clock_table[lvds_term][i][0] >= 
>> lvds_vod_swing_clk[0] &&
>> +??????? lvds_vod_swing_clock_table[lvds_term][i][1] <= 
>> lvds_vod_swing_clk[1])
> 
> Adding a few spaces to align things would help reading.

Ok, that makes sense, will fix.

> 
>> +??????????? return i;
>> +??? }
>> +
>> +??? dev_err(dev, "failed to find appropriate LVDS_VOD_SWING 
>> configuration\n");
>> +??? return -EINVAL;
>> +}
>> +
>> +static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int 
>> channel)
>> +{
>> +??? struct device *dev = ctx->dev;
>> +??? struct device_node *endpoint;
>> +??? int endpoint_reg;
>> +??? /* Set so the property can be freely selected if not defined */
>> +??? u32 lvds_vod_swing_data[2] = { 0, 1000000 };
>> +??? u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
>> +??? /* Set default near end terminataion to 200 Ohm */
>> +??? u32 lvds_term = 200;
>> +??? int lvds_vod_swing_conf;
>> +??? int ret = 0;
>> +??? int ret_data;
>> +??? int ret_clock;
>> +
>> +??? if (channel == CHANNEL_A)
>> +??????? endpoint_reg = 2;
>> +??? else
>> +??????? endpoint_reg = 3;
>> +
>> +??? endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 
>> endpoint_reg, -1);
>> +
>> +??? of_property_read_u32(endpoint, "ti,lvds-termination-ohms", 
>> &lvds_term);
>> +??? if (lvds_term == 100)
>> +??????? ctx->lvds_term_conf[channel] = OHM_100;
>> +??? else if (lvds_term == 200)
>> +??????? ctx->lvds_term_conf[channel] = OHM_200;
>> +??? else
>> +??????? return -EINVAL;
> 
> Should it be:
>  ????else {
>  ??????? ret = -EINVAL;
>  ??????? goto exit;
>  ????}
> ?

Of course, good catch. Thanks.

Best regards,
Andrej.

> 
>> +
>> +??? ret_data = of_property_read_u32_array(endpoint, 
>> "ti,lvds-vod-swing-data-microvolt",
>> +??????????????????? lvds_vod_swing_data, 
>> ARRAY_SIZE(lvds_vod_swing_data));
>> +??? if (ret_data != 0 && ret_data != -EINVAL) {
>> +??????? ret = ret_data;
>> +??????? goto exit;
>> +??? }
>> +
>> +??? ret_clock = of_property_read_u32_array(endpoint, 
>> "ti,lvds-vod-swing-clock-microvolt",
>> +??????????????????? lvds_vod_swing_clk, ARRAY_SIZE(lvds_vod_swing_clk));
>> +??? if (ret_clock != 0 && ret_clock != -EINVAL) {
>> +??????? ret = ret_clock;
>> +??????? goto exit;
>> +??? }
>> +
>> +??? /* Use default value if both properties are NOT defined. */
>> +??? if (ret_data == -EINVAL && ret_clock == -EINVAL)
>> +??????? lvds_vod_swing_conf = 0x1;
>> +
>> +??? /* Use lookup table if any of the two properties is defined. */
>> +??? if (!ret_data || !ret_clock) {
>> +??????? lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev, 
>> lvds_vod_swing_data,
>> +??????????????????????? lvds_vod_swing_clk, 
>> ctx->lvds_term_conf[channel]);
>> +??????? if (lvds_vod_swing_conf < 0) {
>> +??????????? ret = lvds_vod_swing_conf;
>> +??????????? goto exit;
>> +??????? }
>> +??? }
>> +
>> +??? ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
>> +??? ret = 0;
>> +exit:
>> +??? of_node_put(endpoint);
>> +??? return ret;
>> +}
> 
> ...
> 
> CJ


From christophe.leroy2 at cs-soprasteria.com  Thu Dec 12 23:27:03 2024
From: christophe.leroy2 at cs-soprasteria.com (LEROY Christophe)
Date: Fri, 13 Dec 2024 07:27:03 +0000
Subject: [PATCH 06/19] soc/qman: test: Use kthread_run_on_cpu()
In-Reply-To: <20241211154035.75565-7-frederic@kernel.org>
References: <20241211154035.75565-1-frederic@kernel.org>
 <20241211154035.75565-7-frederic@kernel.org>
Message-ID: <986fee5c-8537-498f-83ec-65a7c7c7a71c@cs-soprasteria.com>



Le 11/12/2024 ? 16:40, Frederic Weisbecker a ?crit?:
> Use the proper API instead of open coding it.
> 
> However it looks like kthreads here could be replaced by the use of a
> per-cpu workqueue instead.
> 
> Signed-off-by: Frederic Weisbecker <frederic at kernel.org>

Acked-by: Christophe Leroy <christophe.leroy at csgroup.eu>

> ---
>   drivers/soc/fsl/qbman/qman_test_stash.c | 6 ++----
>   1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qbman/qman_test_stash.c b/drivers/soc/fsl/qbman/qman_test_stash.c
> index b7e8e5ec884c..f4d3c2146f4f 100644
> --- a/drivers/soc/fsl/qbman/qman_test_stash.c
> +++ b/drivers/soc/fsl/qbman/qman_test_stash.c
> @@ -108,14 +108,12 @@ static int on_all_cpus(int (*fn)(void))
>   			.fn = fn,
>   			.started = ATOMIC_INIT(0)
>   		};
> -		struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
> -			"hotpotato%d", cpu);
> +		struct task_struct *k = kthread_run_on_cpu(bstrap_fn, &bstrap,
> +							   cpu, "hotpotato%d");
>   		int ret;
>   
>   		if (IS_ERR(k))
>   			return -ENOMEM;
> -		kthread_bind(k, cpu);
> -		wake_up_process(k);
>   		/*
>   		 * If we call kthread_stop() before the "wake up" has had an
>   		 * effect, then the thread may exit with -EINTR without ever


From ardb at kernel.org  Thu Dec 12 23:30:53 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 13 Dec 2024 08:30:53 +0100
Subject: [PATCH v4 1/2 fix] arm64: refactor the rodata=xxx
In-Reply-To: <20241213053049.7592-1-shijie@os.amperecomputing.com>
References: <20241212082426.4110-2-shijie@os.amperecomputing.com> <20241213053049.7592-1-shijie@os.amperecomputing.com>
Message-ID: <CAMj1kXF=1Hr9G4ZjnEVzJ1snn0V4L-=+bMU4bn=m0UbYLyBqGA@mail.gmail.com>

Hello Huang Shije,

On Fri, 13 Dec 2024 at 06:32, Huang Shijie
<shijie at os.amperecomputing.com> wrote:
>
> As per admin guide documentation, "rodata=on" should be the default on
> platforms. Documentation/admin-guide/kernel-parameters.txt describes
> these options as
>
>    rodata=         [KNL,EARLY]
>            on      Mark read-only kernel memory as read-only (default).
>            off     Leave read-only kernel memory writable for debugging.
>            full    Mark read-only kernel memory and aliases as read-only
>                    [arm64]
>
> But on arm64 platform, "rodata=full" is the default instead. This patch
> implements the following changes.
>
>  - Make "rodata=on" behaviour same as the original "rodata=full"
>  - Make "rodata=noalias" (new) behaviour same as the original "rodata=on"
>  - Drop the original "rodata=full"
>  - Add comment for arch_parse_debug_rodata()
>  - Update kernel-parameters.txt as required
>
> After this patch, the "rodata=on" will be the default on arm64 platform
> as well.
>
> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
> ---
> Add more descriptions for "noalias":
>   It is not a security feature yet.

Why did you add that?

How do you envisage 'noalias' becoming a security feature? The point
of 'full' rodata was to harden the read-only regions in the vmalloc
space against inadvertent modification via the writeable linear alias,
so 'noalias' is less secure than rodata=full, and should be documented
as such.

> ---
>  .../admin-guide/kernel-parameters.txt         |  3 ++-
>  arch/arm64/include/asm/setup.h                | 27 +++++++++++++++++--
>  2 files changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index a22b7e621007..f5db01eecbd3 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -5901,7 +5901,8 @@
>         rodata=         [KNL,EARLY]
>                 on      Mark read-only kernel memory as read-only (default).
>                 off     Leave read-only kernel memory writable for debugging.
> -               full    Mark read-only kernel memory and aliases as read-only
> +               noalias Use more block mappings,may have better performance.
> +                       But this is not a security feature.
>                         [arm64]
>
>         rockchip.usb_uart
> diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
> index ba269a7a3201..0ef57d19fc2a 100644
> --- a/arch/arm64/include/asm/setup.h
> +++ b/arch/arm64/include/asm/setup.h
> @@ -13,6 +13,29 @@
>  extern phys_addr_t __fdt_pointer __initdata;
>  extern u64 __cacheline_aligned boot_args[4];
>
> +/*
> + * rodata=on (default)
> + *
> + *    This applies read-only attributes to VM areas and to the linear
> + *    alias of the backing pages as well. This prevents code or read-
> + *    only data from being modified (inadvertently or intentionally),
> + *    via another mapping for the same memory page.
> + *
> + *    But this might cause linear map region to be mapped down to base
> + *    pages, which may adversely affect performance in some cases.
> + *
> + * rodata=off
> + *
> + *    This provides more block mappings and contiguous hints for linear
> + *    map region which would minimize TLB footprint. This also leaves
> + *    read-only kernel memory writable for debugging.
> + *
> + * rodata=noalias
> + *
> + *    This provides more block mappings and contiguous hints for linear
> + *    map region which would minimize TLB footprint. This is not a
> + *    security feature yet.

Better replace the last sentence with

"This leaves the linear alias of read-only mappings in the vmalloc
space writeable, making them susceptible to inadvertent modification
by software."


From krzk at kernel.org  Thu Dec 12 23:40:33 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 08:40:33 +0100
Subject: [PATCH 1/3] dt-bindings: soc: samsung: exynos-speedy: Document
 SPEEDY host controller bindings
In-Reply-To: <20241212-speedy-v1-1-544ad7bcfb6a@gmail.com>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
 <20241212-speedy-v1-1-544ad7bcfb6a@gmail.com>
Message-ID: <207354ad-e363-4156-ba6b-86dbaa13ab95@kernel.org>

On 12/12/2024 22:09, Markuss Broks wrote:
> Add the schema for the Samsung SPEEDY serial bus host controller.
> The bus has 4 bit wide addresses for addressing devices
> and 8 bit wide register addressing. Each register is also 8
> bit long, so the address can be 0-f (hexadecimal), node name
> for child device follows the format: node_name@[0-f].


This wasn't tested so limited review.

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

> 
> Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
> Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
> Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
> ---
>  .../bindings/soc/samsung/exynos-speedy.yaml        | 78 ++++++++++++++++++++++

Filename must match compatible.

>  1 file changed, 78 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..304b322a74ea70f23d8c072b44b6ca86b7cc807f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml
> @@ -0,0 +1,78 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/samsung/exynos-speedy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung Exynos SPEEDY serial bus host controller

Speedy or SPEEDY?

> +
> +maintainers:
> +  - Markuss Broks <markuss.broks at gmail.com>
> +
> +description:
> +  Samsung SPEEDY is a proprietary Samsung serial 1-wire bus.

1-wire? But not compatible with w1 (onwire)?

> +  It is used on various Samsung Exynos chips. The bus can
> +  address at most 4 bit (16) devices. The devices on the bus
> +  have 8 bit long register line, and the registers are also
> +  8 bit long each. It is typically used for communicating with
> +  Samsung PMICs (s2mps17, s2mps18, ...) and other Samsung chips,
> +  such as RF parts.
> +
> +properties:
> +  compatible:
> +    - items:
> +        - enum:
> +            - samsung,exynos9810-speedy
> +        - const: samsung,exynos-speedy

Drop last compatible and use only SoC specific.

> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    - const: pclk

Drop clock-names, not needed for one entry.

> +
> +  interrupts:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#address-cells"
> +  - "#size-cells"

You do not have them in the properties, anyway required goes before
additionalProperties

> +
> +patternProperties:
> +  "^[a-z][a-z0-9]*@[0-9a-f]$":

That's odd regex. Look at other bus bindings.

> +    type: object
> +    additionalProperties: true
> +
> +    properties:
> +      reg:
> +        maxItems: 1

maximum: 15

> +
> +    required:
> +      - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    speedy0: speedy at 141c0000 {

Drop unused label.

> +      compatible = "samsung,exynos9810-speedy",
> +                   "samsung-exynos-speedy";
> +      reg = <0x141c0000 0x2000>;
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +

No resources? No clocks? No interrupts?



Best regards,
Krzysztof


From ming.qian at oss.nxp.com  Thu Dec 12 23:46:46 2024
From: ming.qian at oss.nxp.com (Ming Qian)
Date: Fri, 13 Dec 2024 16:46:46 +0900
Subject: [PATCH] media: amphion: Support dmabuf and v4l2 buffer without binding
Message-ID: <20241213074646.2859784-1-ming.qian@oss.nxp.com>

From: Ming Qian <ming.qian at nxp.com>

When using VB2_DMABUF, the relationship between dma-buf and v4l2 buffer
may not one-to-one, a single dma-buf may be queued via different
v4l2 buffers, and different dma-bufs may be queued via the same
v4l2 buffer, so it's not appropriate to use the v4l2 buffer index
as the frame store id.

We can generate a frame store id according to the dma address.
Then for a given dma-buf, the id is fixed.

Driver now manages the frame store and vb2-buffer states independently.

When a dmabuf is queued via another v4l2 buffer before the buffer is
released by firmware, need to pend it until firmware release it.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
---
 drivers/media/platform/amphion/vdec.c     | 232 ++++++++++++++++++----
 drivers/media/platform/amphion/vpu.h      |   7 +-
 drivers/media/platform/amphion/vpu_dbg.c  |  14 +-
 drivers/media/platform/amphion/vpu_v4l2.c |  11 +
 4 files changed, 217 insertions(+), 47 deletions(-)

diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
index 61d5598ee6a1..a26cb0c264c9 100644
--- a/drivers/media/platform/amphion/vdec.c
+++ b/drivers/media/platform/amphion/vdec.c
@@ -26,6 +26,7 @@
 #include "vpu_cmds.h"
 #include "vpu_rpc.h"
 
+#define VDEC_SLOT_CNT_DFT		32
 #define VDEC_MIN_BUFFER_CAP		8
 #define VDEC_MIN_BUFFER_OUT		8
 
@@ -41,6 +42,14 @@ struct vdec_fs_info {
 	u32 tag;
 };
 
+struct vdec_frame_store_t {
+	struct vpu_vb2_buffer *curr;
+	struct vpu_vb2_buffer *pend;
+	dma_addr_t addr;
+	unsigned int state;
+	u32 tag;
+};
+
 struct vdec_t {
 	u32 seq_hdr_found;
 	struct vpu_buffer udata;
@@ -48,7 +57,8 @@ struct vdec_t {
 	struct vpu_dec_codec_info codec_info;
 	enum vpu_codec_state state;
 
-	struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];
+	struct vdec_frame_store_t *slots;
+	u32 slot_count;
 	u32 req_frame_count;
 	struct vdec_fs_info mbi;
 	struct vdec_fs_info dcp;
@@ -289,6 +299,64 @@ static int vdec_ctrl_init(struct vpu_inst *inst)
 	return 0;
 }
 
+static void vdec_attach_frame_store(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+	struct vdec_t *vdec = inst->priv;
+	struct vdec_frame_store_t *new_slots = NULL;
+	dma_addr_t addr;
+	int i;
+
+	addr = vpu_get_vb_phy_addr(vb, 0);
+	for (i = 0; i < vdec->slot_count; i++) {
+		if (addr == vdec->slots[i].addr) {
+			if (vdec->slots[i].curr && vdec->slots[i].curr != vpu_buf) {
+				vpu_set_buffer_state(vbuf, VPU_BUF_STATE_CHANGED);
+				vdec->slots[i].pend = vpu_buf;
+			} else {
+				vpu_set_buffer_state(vbuf, vdec->slots[i].state);
+			}
+			vpu_buf->fs_id = i;
+			return;
+		}
+	}
+
+	for (i = 0; i < vdec->slot_count; i++) {
+		if (!vdec->slots[i].addr) {
+			vdec->slots[i].addr = addr;
+			vpu_buf->fs_id = i;
+			return;
+		}
+	}
+
+	new_slots = vzalloc(sizeof(*vdec->slots) * vdec->slot_count * 2);
+	if (!vdec->slots) {
+		dev_err(inst->dev, "fail to alloc frame store\n");
+		vpu_set_buffer_state(vbuf, VPU_BUF_STATE_ERROR);
+		return;
+	}
+
+	memcpy(new_slots, vdec->slots, sizeof(*vdec->slots) * vdec->slot_count);
+	vfree(vdec->slots);
+	vdec->slots = new_slots;
+	vdec->slot_count *= 2;
+
+	vdec->slots[i].addr = addr;
+	vpu_buf->fs_id = i;
+}
+
+static void vdec_reset_frame_store(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!vdec->slots || !vdec->slot_count)
+		return;
+
+	vpu_trace(inst->dev, "inst[%d] reset slots\n", inst->id);
+	memset(vdec->slots, 0, sizeof(*vdec->slots) * vdec->slot_count);
+}
+
 static void vdec_handle_resolution_change(struct vpu_inst *inst)
 {
 	struct vdec_t *vdec = inst->priv;
@@ -745,11 +813,11 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
 	struct vb2_v4l2_buffer *src_buf;
 	int ret = 0;
 
-	if (!info || info->id >= ARRAY_SIZE(vdec->slots))
+	if (!info || info->id >= vdec->slot_count)
 		return -EINVAL;
 
 	vpu_inst_lock(inst);
-	vpu_buf = vdec->slots[info->id];
+	vpu_buf = vdec->slots[info->id].curr;
 	if (!vpu_buf) {
 		dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id);
 		ret = -EINVAL;
@@ -770,11 +838,13 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
 	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)
 		dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
 	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
+	vdec->slots[info->id].state = VPU_BUF_STATE_DECODED;
 	vdec->decoded_frame_count++;
 	if (vdec->params.display_delay_enable) {
 		struct vpu_format *cur_fmt;
 
 		cur_fmt = vpu_get_format(inst, inst->cap_format.type);
+		vdec->slots[info->id].state = VPU_BUF_STATE_READY;
 		vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
 		for (int i = 0; i < vbuf->vb2_buf.num_planes; i++)
 			vb2_set_plane_payload(&vbuf->vb2_buf,
@@ -797,11 +867,11 @@ static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma)
 	struct vdec_t *vdec = inst->priv;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
-		if (!vdec->slots[i])
+	for (i = 0; i < vdec->slot_count; i++) {
+		if (!vdec->slots[i].curr)
 			continue;
-		if (luma == vdec->slots[i]->luma)
-			return vdec->slots[i];
+		if (luma == vdec->slots[i].addr)
+			return vdec->slots[i].curr;
 	}
 
 	return NULL;
@@ -835,11 +905,11 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
 
 	cur_fmt = vpu_get_format(inst, inst->cap_format.type);
 	vbuf = &vpu_buf->m2m_buf.vb;
-	if (vbuf->vb2_buf.index != frame->id)
-		dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n",
-			inst->id, vbuf->vb2_buf.index, frame->id);
+	if (vpu_buf->fs_id != frame->id)
+		dev_err(inst->dev, "[%d] buffer id(%d(%d), %d) dismatch\n",
+			inst->id, vpu_buf->fs_id, vbuf->vb2_buf.index, frame->id);
 
-	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_READY && vdec->params.display_delay_enable)
+	if (vdec->params.display_delay_enable)
 		return;
 
 	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED)
@@ -852,10 +922,11 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
 	vbuf->sequence = vdec->sequence;
 	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
 
-	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
 	vpu_inst_lock(inst);
+	vdec->slots[vpu_buf->fs_id].state = VPU_BUF_STATE_READY;
 	vdec->display_frame_count++;
 	vpu_inst_unlock(inst);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
 	dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n",
 		inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence);
 }
@@ -1083,18 +1154,30 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb
 	if (!vbuf)
 		return -EINVAL;
 
-	if (vdec->slots[vbuf->vb2_buf.index]) {
-		dev_err(inst->dev, "[%d] repeat alloc fs %d\n",
-			inst->id, vbuf->vb2_buf.index);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	if (vpu_buf->fs_id < 0 || vpu_buf->fs_id >= vdec->slot_count) {
+		dev_err(inst->dev, "invalid fs %d for v4l2 buffer %d\n",
+			vpu_buf->fs_id, vbuf->vb2_buf.index);
 		return -EINVAL;
 	}
 
+	if (vdec->slots[vpu_buf->fs_id].curr) {
+		if (vdec->slots[vpu_buf->fs_id].curr != vpu_buf) {
+			vpu_set_buffer_state(vbuf, VPU_BUF_STATE_CHANGED);
+			vdec->slots[vpu_buf->fs_id].pend = vpu_buf;
+		} else {
+			vpu_set_buffer_state(vbuf, vdec->slots[vpu_buf->fs_id].state);
+		}
+		dev_err(inst->dev, "[%d] repeat alloc fs %d (v4l2 index %d)\n",
+			inst->id, vpu_buf->fs_id, vbuf->vb2_buf.index);
+		return -EAGAIN;
+	}
+
 	dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n",
 		inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag);
-	vpu_buf = to_vpu_vb2_buffer(vbuf);
 
 	memset(&info, 0, sizeof(info));
-	info.id = vbuf->vb2_buf.index;
+	info.id = vpu_buf->fs_id;
 	info.type = MEM_RES_FRAME;
 	info.tag = vdec->seq_tag;
 	info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);
@@ -1109,12 +1192,13 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb
 	if (ret)
 		return ret;
 
-	vpu_buf->tag = info.tag;
 	vpu_buf->luma = info.luma_addr;
 	vpu_buf->chroma_u = info.chroma_addr;
 	vpu_buf->chroma_v = 0;
 	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
-	vdec->slots[info.id] = vpu_buf;
+	vdec->slots[info.id].tag = info.tag;
+	vdec->slots[info.id].curr = vpu_buf;
+	vdec->slots[info.id].state = VPU_BUF_STATE_INUSE;
 	vdec->req_frame_count--;
 
 	return 0;
@@ -1175,25 +1259,47 @@ static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *v
 	v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
 }
 
-static void vdec_clear_slots(struct vpu_inst *inst)
+static void vdec_release_curr_frame_store(struct vpu_inst *inst, u32 id)
 {
 	struct vdec_t *vdec = inst->priv;
 	struct vpu_vb2_buffer *vpu_buf;
 	struct vb2_v4l2_buffer *vbuf;
+
+	if (id >= vdec->slot_count)
+		return;
+	if (!vdec->slots[id].curr)
+		return;
+
+	vpu_buf = vdec->slots[id].curr;
+	vbuf = &vpu_buf->m2m_buf.vb;
+
+	vdec_response_fs_release(inst, id, vdec->slots[id].tag);
+	if (vpu_buf->fs_id == id) {
+		if (vpu_buf->state != VPU_BUF_STATE_READY)
+			vdec_recycle_buffer(inst, vbuf);
+		vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	}
+
+	vdec->slots[id].curr = NULL;
+	vdec->slots[id].state = VPU_BUF_STATE_IDLE;
+
+	if (vdec->slots[id].pend) {
+		vpu_set_buffer_state(&vdec->slots[id].pend->m2m_buf.vb, VPU_BUF_STATE_IDLE);
+		vdec->slots[id].pend = NULL;
+	}
+}
+
+static void vdec_clear_slots(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
-		if (!vdec->slots[i])
+	for (i = 0; i < vdec->slot_count; i++) {
+		if (!vdec->slots[i].curr)
 			continue;
 
-		vpu_buf = vdec->slots[i];
-		vbuf = &vpu_buf->m2m_buf.vb;
-
 		vpu_trace(inst->dev, "clear slot %d\n", i);
-		vdec_response_fs_release(inst, i, vpu_buf->tag);
-		vdec_recycle_buffer(inst, vbuf);
-		vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
-		vdec->slots[i] = NULL;
+		vdec_release_curr_frame_store(inst, i);
 	}
 }
 
@@ -1324,39 +1430,29 @@ static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
 static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
 {
 	struct vdec_t *vdec = inst->priv;
-	struct vpu_vb2_buffer *vpu_buf;
-	struct vb2_v4l2_buffer *vbuf;
 
-	if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))
+	if (!fs || fs->id >= vdec->slot_count)
 		return;
 	if (fs->type != MEM_RES_FRAME)
 		return;
 
-	if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {
+	if (fs->id >= vdec->slot_count) {
 		dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id);
 		return;
 	}
 
 	vpu_inst_lock(inst);
-	vpu_buf = vdec->slots[fs->id];
-	vdec->slots[fs->id] = NULL;
-
-	if (!vpu_buf) {
+	if (!vdec->slots[fs->id].curr) {
 		dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id);
 		goto exit;
 	}
 
-	vbuf = &vpu_buf->m2m_buf.vb;
-	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED) {
+	if (vdec->slots[fs->id].state == VPU_BUF_STATE_DECODED) {
 		dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
 		vdec->sequence++;
 	}
 
-	vdec_response_fs_release(inst, fs->id, vpu_buf->tag);
-	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_READY)
-		vdec_recycle_buffer(inst, vbuf);
-
-	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	vdec_release_curr_frame_store(inst, fs->id);
 	vpu_process_capture_buffer(inst);
 
 exit:
@@ -1552,6 +1648,11 @@ static void vdec_cleanup(struct vpu_inst *inst)
 		return;
 
 	vdec = inst->priv;
+	if (vdec) {
+		vfree(vdec->slots);
+		vdec->slots = NULL;
+		vdec->slot_count = 0;
+	}
 	vfree(vdec);
 	inst->priv = NULL;
 	vfree(inst);
@@ -1683,6 +1784,38 @@ static int vdec_stop_session(struct vpu_inst *inst, u32 type)
 	return 0;
 }
 
+static int vdec_get_slot_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	int num = -1;
+
+	vpu_inst_lock(inst);
+	if (i >= vdec->slot_count || !vdec->slots[i].addr)
+		goto exit;
+
+	vpu_buf = vdec->slots[i].curr;
+
+	num = scnprintf(str, size, "slot[%2d] :", i);
+	if (vpu_buf) {
+		num += scnprintf(str + num, size - num, " %2d",
+				 vpu_buf->m2m_buf.vb.vb2_buf.index);
+		num += scnprintf(str + num, size - num, "; state = %d", vdec->slots[i].state);
+	} else {
+		num += scnprintf(str + num, size - num, " -1");
+	}
+
+	if (vdec->slots[i].pend)
+		num += scnprintf(str + num, size - num, "; %d",
+				 vdec->slots[i].pend->m2m_buf.vb.vb2_buf.index);
+
+	num += scnprintf(str + num, size - num, "\n");
+exit:
+	vpu_inst_unlock(inst);
+
+	return num;
+}
+
 static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
 {
 	struct vdec_t *vdec = inst->priv;
@@ -1741,6 +1874,7 @@ static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i
 				vdec->codec_info.vui_present);
 		break;
 	default:
+		num = vdec_get_slot_debug_info(inst, str, size, i - 10);
 		break;
 	}
 
@@ -1764,6 +1898,8 @@ static struct vpu_inst_ops vdec_inst_ops = {
 	.get_debug_info = vdec_get_debug_info,
 	.wait_prepare = vpu_inst_unlock,
 	.wait_finish = vpu_inst_lock,
+	.attach_frame_store = vdec_attach_frame_store,
+	.reset_frame_store = vdec_reset_frame_store,
 };
 
 static void vdec_init(struct file *file)
@@ -1804,6 +1940,14 @@ static int vdec_open(struct file *file)
 		return -ENOMEM;
 	}
 
+	vdec->slots = vzalloc(sizeof(*vdec->slots) * VDEC_SLOT_CNT_DFT);
+	if (!vdec->slots) {
+		vfree(vdec);
+		vfree(inst);
+		return -ENOMEM;
+	}
+	vdec->slot_count = VDEC_SLOT_CNT_DFT;
+
 	inst->ops = &vdec_inst_ops;
 	inst->formats = vdec_formats;
 	inst->type = VPU_CORE_TYPE_DEC;
diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
index 22f0da26ccec..76bfd6b26170 100644
--- a/drivers/media/platform/amphion/vpu.h
+++ b/drivers/media/platform/amphion/vpu.h
@@ -223,6 +223,8 @@ struct vpu_inst_ops {
 	int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i);
 	void (*wait_prepare)(struct vpu_inst *inst);
 	void (*wait_finish)(struct vpu_inst *inst);
+	void (*attach_frame_store)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	void (*reset_frame_store)(struct vpu_inst *inst);
 };
 
 struct vpu_inst {
@@ -296,7 +298,8 @@ enum {
 	VPU_BUF_STATE_DECODED,
 	VPU_BUF_STATE_READY,
 	VPU_BUF_STATE_SKIP,
-	VPU_BUF_STATE_ERROR
+	VPU_BUF_STATE_ERROR,
+	VPU_BUF_STATE_CHANGED
 };
 
 struct vpu_vb2_buffer {
@@ -305,8 +308,8 @@ struct vpu_vb2_buffer {
 	dma_addr_t chroma_u;
 	dma_addr_t chroma_v;
 	unsigned int state;
-	u32 tag;
 	u32 average_qp;
+	s32 fs_id;
 };
 
 void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val);
diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c
index 940e5bda5fa3..246b7d91d083 100644
--- a/drivers/media/platform/amphion/vpu_dbg.c
+++ b/drivers/media/platform/amphion/vpu_dbg.c
@@ -48,6 +48,7 @@ static char *vpu_stat_name[] = {
 	[VPU_BUF_STATE_READY] = "ready",
 	[VPU_BUF_STATE_SKIP] = "skip",
 	[VPU_BUF_STATE_ERROR] = "error",
+	[VPU_BUF_STATE_CHANGED] = "changed",
 };
 
 static inline const char *to_vpu_stat_name(int state)
@@ -164,6 +165,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data)
 	for (i = 0; i < vb2_get_num_buffers(vq); i++) {
 		struct vb2_buffer *vb;
 		struct vb2_v4l2_buffer *vbuf;
+		struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
 
 		vb = vb2_get_buffer(vq, i);
 		if (!vb)
@@ -175,11 +177,21 @@ static int vpu_dbg_instance(struct seq_file *s, void *data)
 		vbuf = to_vb2_v4l2_buffer(vb);
 
 		num = scnprintf(str, sizeof(str),
-				"capture[%2d] state = %10s, %8s\n",
+				"capture[%2d] state = %10s, %8s",
 				i, vb2_stat_name[vb->state],
 				to_vpu_stat_name(vpu_get_buffer_state(vbuf)));
 		if (seq_write(s, str, num))
 			return 0;
+
+		if (vpu_buf->fs_id >= 0) {
+			num = scnprintf(str, sizeof(str), "; fs %d", vpu_buf->fs_id);
+			if (seq_write(s, str, num))
+				return 0;
+		}
+
+		num = scnprintf(str, sizeof(str), "\n");
+		if (seq_write(s, str, num))
+			return 0;
 	}
 
 	num = scnprintf(str, sizeof(str), "sequence = %d\n", inst->sequence);
diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
index 45707931bc4f..74668fa362e2 100644
--- a/drivers/media/platform/amphion/vpu_v4l2.c
+++ b/drivers/media/platform/amphion/vpu_v4l2.c
@@ -501,14 +501,25 @@ static int vpu_vb2_queue_setup(struct vb2_queue *vq,
 		call_void_vop(inst, release);
 	}
 
+	if (V4L2_TYPE_IS_CAPTURE(vq->type))
+		call_void_vop(inst, reset_frame_store);
+
 	return 0;
 }
 
 static int vpu_vb2_buf_init(struct vb2_buffer *vb)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
 
+	vpu_buf->fs_id = -1;
 	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+
+	if (!inst->ops->attach_frame_store || V4L2_TYPE_IS_OUTPUT(vb->type))
+		return 0;
+
+	call_void_vop(inst, attach_frame_store, vb);
 	return 0;
 }
 
-- 
2.43.0-rc1



From krzk at kernel.org  Thu Dec 12 23:49:10 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 08:49:10 +0100
Subject: [PATCH 2/3] soc: samsung: Add a driver for Samsung SPEEDY host
 controller
In-Reply-To: <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
 <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
Message-ID: <f08b068e-bc6b-4d9d-9839-370883309b88@kernel.org>

On 12/12/2024 22:09, Markuss Broks wrote:
> Add a driver for Samsung SPEEDY serial bus host controller.
> SPEEDY is a proprietary 1 wire serial bus used by Samsung
> in various devices (usually mobile), like Samsung Galaxy
> phones. It is usually used for connecting PMIC or various
> other peripherals, like audio codecs or RF components.
> 
> This bus can address at most 1MiB (4 bit device address,
> 8 bit registers per device, 8 bit wide registers:
> 256*256*16 = 1MiB of address space.
> 
> Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
> Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
> Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
> ---
>  drivers/soc/samsung/Kconfig               |  13 +
>  drivers/soc/samsung/Makefile              |   2 +
>  drivers/soc/samsung/exynos-speedy.c       | 457 ++++++++++++++++++++++++++++++
>  include/linux/soc/samsung/exynos-speedy.h |  56 ++++
>  4 files changed, 528 insertions(+)
> 
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 1a5dfdc978dc4069eb71c4e8eada7ff1913b86b3..a38150fc9999ded1e1e93e2a9ef43b88175d34bd 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -49,6 +49,19 @@ config EXYNOS_PMU_ARM_DRIVERS
>  	bool "Exynos PMU ARMv7-specific driver extensions" if COMPILE_TEST
>  	depends on EXYNOS_PMU
>  
> +config EXYNOS_SPEEDY
> +	tristate "Exynos SPEEDY host controller driver"
> +	depends on ARCH_EXYNOS || COMPILE_TEST
> +	depends on OF
> +	depends on REGMAP_MMIO
> +	help
> +	  Enable support for Exynos SPEEDY host controller block.
> +	  SPEEDY is a 1 wire proprietary Samsung serial bus, found in
> +	  modern Samsung Exynos SoCs, like Exynos8895 and newer.


I did not check that much but this looks like 1wire for which we have
subsystem. Please investigate more and figure out the differences.

> +
> +	  Select this if you have a Samsung Exynos device which uses
> +	  SPEEDY bus.
> +


> +
> +/* SPEEDY_PACKET_GAP_TIME register bits */
> +#define SPEEDY_FIFO_TX_ALMOST_EMPTY			(1 << 4)
> +#define SPEEDY_FIFO_RX_ALMOST_FULL			(1 << 8)
> +#define SPEEDY_FSM_INIT					(1 << 1)
> +#define SPEEDY_FSM_TX_CMD				(1 << 2)
> +#define SPEEDY_FSM_STANDBY				(1 << 3)
> +#define SPEEDY_FSM_DATA					(1 << 4)
> +#define SPEEDY_FSM_TIMEOUT				(1 << 5)
> +#define SPEEDY_FSM_TRANS_DONE				(1 << 6)
> +#define SPEEDY_FSM_IO_RX_STAT_MASK			(3 << 7)
> +#define SPEEDY_FSM_IO_TX_IDLE				(1 << 9)
> +#define SPEEDY_FSM_IO_TX_GET_PACKET			(1 << 10)
> +#define SPEEDY_FSM_IO_TX_PACKET				(1 << 11)
> +#define SPEEDY_FSM_IO_TX_DONE				(1 << 12)
> +
> +#define SPEEDY_RX_LENGTH(n)				((n) << 0)
> +#define SPEEDY_TX_LENGTH(n)				((n) << 8)
> +
> +#define SPEEDY_DEVICE(x)				((x & 0xf) << 15)
> +#define SPEEDY_ADDRESS(x)				((x & 0xff) << 7)
> +
> +static const struct of_device_id speedy_match[] = {
> +	{ .compatible = "samsung,exynos9810-speedy" },
> +	{ /* Sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, speedy_match);

This is never at top of the file, but immediately before driver
structure. Look at other drivers.

> +
> +static const struct regmap_config speedy_map_cfg = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +};
> +
> +/**
> + * speedy_int_clear() - clear interrupt status
> + * @speedy:	pointer to speedy controller struct
> + *
> + * Return: 0 on success, -errno otherwise
> + */
> +static int speedy_int_clear(struct speedy_controller *speedy)
> +{
> +	int ret;
> +
> +	ret = regmap_set_bits(speedy->map, SPEEDY_INT_STATUS, 0xffffffff);
> +	if (ret)
> +		return ret;
> +
> +	udelay(10);
> +
> +	return 0;
> +}
> +
> +/**
> + * speedy_fifo_reset() - reset FIFO of the controller
> + * @speedy:	pointer to speedy controller struct
> + *
> + * Return: 0 on success, -errno otherwise
> + */
> +static int speedy_fifo_reset(struct speedy_controller *speedy)
> +{
> +	int ret;
> +
> +	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL, SPEEDY_FIFO_RESET);
> +	if (ret)
> +		return ret;
> +
> +	udelay(10);
> +
> +	return 0;
> +}
> +
> +/**
> + * _speedy_read() - internal speedy read operation
> + * @speedy:	pointer to speedy controller struct
> + * @reg:	address of device on the bus
> + * @addr:       address to read
> + * @val:        pointer to store result
> + *
> + * Return: 0 on success, -errno otherwise
> + */
> +static int _speedy_read(struct speedy_controller *speedy, u32 reg, u32 addr, u32 *val)
> +{
> +	int ret;
> +	u32 cmd, int_ctl, int_status;
> +
> +	mutex_lock(&speedy->io_lock);
> +
> +	ret = speedy_fifo_reset(speedy);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
> +			      SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
> +	if (ret)
> +		return ret;
> +
> +	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_READ |
> +	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
> +
> +	int_ctl = SPEEDY_TRANSFER_DONE_EN | SPEEDY_FIFO_RX_ALMOST_FULL_EN |
> +		  SPEEDY_RX_FIFO_INT_TRAILER_EN | SPEEDY_RX_MODEBIT_ERR_EN |
> +		  SPEEDY_RX_GLITCH_ERR_EN | SPEEDY_RX_ENDBIT_ERR_EN |
> +		  SPEEDY_REMOTE_RESET_REQ_EN;
> +
> +	ret = speedy_int_clear(speedy);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
> +	if (ret)
> +		return ret;
> +
> +	/* Wait for xfer done */
> +	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
> +				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_read(speedy->map, SPEEDY_RX_DATA, val);
> +	if (ret)
> +		return ret;
> +
> +	ret = speedy_int_clear(speedy);
> +
> +	mutex_unlock(&speedy->io_lock);
> +
> +	return ret;
> +}
> +
> +int exynos_speedy_read(const struct speedy_device *device, u32 addr, u32 *val)
> +{
> +	return _speedy_read(device->speedy, device->reg, addr, val);
> +}
> +EXPORT_SYMBOL_GPL(exynos_speedy_read);

Nope, drop, unused.

> +
> +/**
> + * _speedy_write() - internal speedy write operation
> + * @speedy:	pointer to speedy controller struct
> + * @reg:	address of device on the bus
> + * @addr:       address to write
> + * @val:        value to write
> + *
> + * Return: 0 on success, -errno otherwise
> + */
> +static int _speedy_write(struct speedy_controller *speedy, u32 reg, u32 addr, u32 val)
> +{
> +	int ret;
> +	u32 cmd, int_ctl, int_status;
> +
> +	mutex_lock(&speedy->io_lock);
> +
> +	ret = speedy_fifo_reset(speedy);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
> +			      SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
> +	if (ret)
> +		return ret;
> +
> +	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_WRITE |
> +	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
> +
> +	int_ctl = (SPEEDY_TRANSFER_DONE_EN |
> +		   SPEEDY_FIFO_TX_ALMOST_EMPTY_EN |
> +		   SPEEDY_TX_LINE_BUSY_ERR_EN |
> +		   SPEEDY_TX_STOPBIT_ERR_EN |
> +		   SPEEDY_REMOTE_RESET_REQ_EN);
> +
> +	ret = speedy_int_clear(speedy);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_TX_DATA, val);
> +	if (ret)
> +		return ret;
> +
> +	/* Wait for xfer done */
> +	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
> +				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
> +	if (ret)
> +		return ret;
> +
> +	speedy_int_clear(speedy);
> +
> +	mutex_unlock(&speedy->io_lock);
> +
> +	return 0;
> +}
> +
> +int exynos_speedy_write(const struct speedy_device *device, u32 addr, u32 val)
> +{
> +	return _speedy_write(device->speedy, device->reg, addr, val);

Just write the function here and drop _.

> +}
> +EXPORT_SYMBOL_GPL(exynos_speedy_write);
> +
> +static void devm_speedy_release(struct device *dev, void *res)
> +{
> +	const struct speedy_device **ptr = res;
> +	const struct speedy_device *handle = *ptr;
> +
> +	kfree(handle);
> +}
> +
> +/**
> + * speedy_get_by_phandle() - internal get speedy device handle
> + * @np:	pointer to OF device node of device
> + *
> + * Return: 0 on success, -errno otherwise
> + */
> +static const struct speedy_device *speedy_get_device(struct device_node *np)
> +{
> +	const struct of_device_id *speedy_id;
> +	struct device_node *speedy_np;
> +	struct platform_device *speedy_pdev;
> +	struct speedy_controller *speedy = NULL;
> +	struct speedy_device *handle;
> +	int ret;
> +
> +	if (!np) {
> +		pr_err("I need a device pointer\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	speedy_np = of_get_parent(np);
> +	if (!speedy_np)
> +		return ERR_PTR(-ENODEV);
> +
> +	/* Verify if parent node is a speedy controller */
> +	speedy_id = of_match_node(speedy_match, speedy_np);
> +	if (!speedy_id) {
> +		handle = ERR_PTR(-EINVAL);
> +		goto out;
> +	}
> +
> +	/* Get platform device of the speedy controller */
> +	speedy_pdev = of_find_device_by_node(speedy_np);
> +	if (!speedy_pdev) {
> +		handle = ERR_PTR(-EPROBE_DEFER);
> +		goto out;
> +	}
> +
> +	/* Get drvdata of speedy controller */
> +	speedy = platform_get_drvdata(speedy_pdev);
> +	if (!speedy) {
> +		handle = ERR_PTR(-EINVAL);
> +		goto out;
> +	}
> +
> +	handle = kzalloc(sizeof(struct speedy_device), GFP_KERNEL);
> +	if (!handle) {
> +		handle = ERR_PTR(-ENOMEM);
> +		goto out;
> +	}
> +	handle->speedy = speedy;
> +	ret = of_property_read_u32(np, "reg", &handle->reg);
> +	if (ret) {
> +		kfree(handle);
> +		handle = ERR_PTR(-EINVAL);
> +		goto out;
> +	}
> +
> +out:
> +	of_node_put(speedy_np);
> +	return handle;
> +}
> +
> +const struct speedy_device *devm_speedy_get_device(struct device *dev)

Not used, drop function.

> +{
> +	const struct speedy_device *handle;
> +	const struct speedy_device **ptr;
> +
> +	ptr = devres_alloc(devm_speedy_release, sizeof(*ptr), GFP_KERNEL);
> +	if (!ptr)
> +		return ERR_PTR(-ENOMEM);
> +
> +	handle = speedy_get_device(dev_of_node(dev));
> +	if (!IS_ERR(handle)) {
> +		*ptr = handle;
> +		devres_add(dev, ptr);
> +	} else {
> +		devres_free(ptr);
> +	}
> +
> +	return handle;
> +}
> +EXPORT_SYMBOL_GPL(devm_speedy_get_device);

Not used, drop.



> +
> +static int speedy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct speedy_controller *speedy;
> +	void __iomem *mem;
> +	int ret;
> +
> +	speedy = devm_kzalloc(dev, sizeof(struct speedy_controller), GFP_KERNEL);

sizeof(*) everywhere. You need to clean the downstream code when
upstreaming.

> +	if (!speedy)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, speedy);
> +	speedy->pdev = pdev;
> +
> +	mutex_init(&speedy->io_lock);
> +
> +	mem = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(mem))
> +		return dev_err_probe(dev, PTR_ERR(mem), "Failed to ioremap memory\n");
> +
> +	speedy->map = devm_regmap_init_mmio(dev, mem, &speedy_map_cfg);
> +	if (IS_ERR(speedy->map))
> +		return dev_err_probe(dev, PTR_ERR(speedy->map), "Failed to init the regmap\n");

Wrap at 80.

> +
> +	/* Clear any interrupt status remaining */
> +	ret = speedy_int_clear(speedy);
> +	if (ret)
> +		return ret;
> +
> +	/* Reset the controller */
> +	ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_SW_RST);
> +	if (ret)
> +		return ret;
> +
> +	msleep(20);
> +
> +	/* Enable the hw */
> +	ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_ENABLE);
> +	if (ret)
> +		return ret;
> +
> +	msleep(20);
> +
> +	/* Probe child devices */
> +	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev);
> +	if (ret)
> +		dev_err(dev, "Failed to populate child devices: %d\n", ret);
> +
> +	return ret;

Missing cleanup in remove().

> +}
> +
> +static struct platform_driver speedy_driver = {
> +	.probe = speedy_probe,
> +	.driver = {
> +		.name = "exynos-speedy",
> +		.of_match_table = speedy_match,
> +	},
> +};
> +
> +module_platform_driver(speedy_driver);
> +
> +MODULE_DESCRIPTION("Samsung Exynos SPEEDY host controller driver");
> +MODULE_AUTHOR("Markuss Broks <markuss.broks at gmail.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/soc/samsung/exynos-speedy.h b/include/linux/soc/samsung/exynos-speedy.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..b2857d65d3b50927373866dd8ae1c47e98af6d7b
> --- /dev/null
> +++ b/include/linux/soc/samsung/exynos-speedy.h

Drop the header, not used.



Best regards,
Krzysztof


From krzk at kernel.org  Thu Dec 12 23:52:49 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 08:52:49 +0100
Subject: [PATCH 2/2] nvmem: imx-ocotp-ele: Support accessing controller
 for i.MX9
In-Reply-To: <20241212-imx-ocotp-v1-2-198bb0af86a0@nxp.com>
References: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>
 <20241212-imx-ocotp-v1-2-198bb0af86a0@nxp.com>
Message-ID: <cf153dd6-f82c-47d9-9ab4-f247437d607e@kernel.org>

On 12/12/2024 09:24, Peng Fan (OSS) wrote:
> +
> +			if (imx_ele_ocotp_check_access(pdev, id)) {
> +				of_detach_node(child);
> +				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
> +					child->full_name);
> +			}
> +		}
> +
> +		imx_ele_ocotp_grant_access(pdev, child);
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx_ele_ocotp_access_control(struct platform_device *pdev)
> +{
> +	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
> +	struct device_node *soc __free(device_node) = of_find_node_by_path("/soc");

No, you just created undocumented ABI on the name.

Drop/replace or express the ABI (which is impossible, so basically: drop).


Best regards,
Krzysztof


From krzk at kernel.org  Thu Dec 12 23:56:04 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 08:56:04 +0100
Subject: [PATCH v3 1/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
In-Reply-To: <20241212155237.848336-2-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-2-kevin_chen@aspeedtech.com>
Message-ID: <7aaeacd1-ecff-49ad-828c-1dcb22d11f05@kernel.org>

On 12/12/2024 16:52, Kevin Chen wrote:
> Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
> ---
Please run scripts/checkpatch.pl and fix reported warnings. Then please
run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

Best regards,
Krzysztof


From krzk at kernel.org  Thu Dec 12 23:59:44 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 08:59:44 +0100
Subject: [PATCH v3 2/6] dt-bindings: interrupt-controller: Fix the
 size-cells in ast2700-intc
In-Reply-To: <20241212155237.848336-5-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-5-kevin_chen@aspeedtech.com>
Message-ID: <7a1244db-7ab7-4374-b44d-e55a25d766a2@kernel.org>

On 12/12/2024 16:52, Kevin Chen wrote:
> It is no need to let size-cells to 2 for the ASPEED AST27XX INTC. Modify
> the ast2700-intc example usage.

Why?

This just looks useless.

> 
> Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
> ---
>  .../bindings/interrupt-controller/aspeed,ast2700-intc.yaml    | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 


Best regards,
Krzysztof


From krzk at kernel.org  Thu Dec 12 23:58:48 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 08:58:48 +0100
Subject: [PATCH v3 1/6] dt-bindings: interrupt-controller: Refine
 size/interrupt-cell usage.
In-Reply-To: <20241212155237.848336-3-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-3-kevin_chen@aspeedtech.com>
Message-ID: <11ad5a97-b066-4bea-8829-50e0416cea9d@kernel.org>

On 12/12/2024 16:52, Kevin Chen wrote:
> 1. Because size-cells is no need to use 2, modify to 1 for use.

???

> 2. Add minItems to 1 for interrupts for intc1.

???

> 3. Add 1 interrupt of intc1 example into yaml file.

> 4. Add intc1 sub-module of uart12 as example using the intc0 and intc1.

What is all this?

BTW, there was no such patch in previous version and your changelog is
silent about it.

Subject: drop all full stops. Subject never ends with full stop.

> ---
>  .../aspeed,ast2700-intc.yaml                  | 60 +++++++++++++++----
>  1 file changed, 47 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
> index 55636d06a674..eadfbc45326b 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
> +++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
> @@ -31,6 +31,7 @@ properties:
>        type as defined in interrupt.txt in this directory.
>  
>    interrupts:
> +    minItems: 1

Nope, not explained, not constrained. Your schema is supposed to be
constrained.


>      maxItems: 6
>      description: |
>        Depend to which INTC0 or INTC1 used.
> @@ -68,19 +69,52 @@ examples:
>      #include <dt-bindings/interrupt-controller/arm-gic.h>
>  
>      bus {
> +      #address-cells = <2>;
> +      #size-cells = <1>;
> +
> +      intc0: interrupt-controller at 12100000 {
> +        compatible = "simple-mfd";
> +        reg = <0 0x12100000 0x4000>;
> +        ranges = <0x0 0x0 0x0 0x12100000 0x4000>;
>          #address-cells = <2>;
> -        #size-cells = <2>;
> -
> -        interrupt-controller at 12101b00 {
> -            compatible = "aspeed,ast2700-intc-ic";
> -            reg = <0 0x12101b00 0 0x10>;
> -            #interrupt-cells = <2>;
> -            interrupt-controller;
> -            interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
> -                         <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>,
> -                         <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>,
> -                         <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>,
> -                         <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
> -                         <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;


I don't understand what is all this.

> +        #size-cells = <1>;
> +
> +        intc0_11: interrupt-controller at 1b00 {
> +          compatible = "aspeed,ast2700-intc-ic";
> +          reg = <0 0x12101b00 0x10>;
> +          #interrupt-cells = <2>;
> +          interrupt-controller;
> +          interrupts = <GIC_SPI 192 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +                       <GIC_SPI 193 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +                       <GIC_SPI 194 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +                       <GIC_SPI 195 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +                       <GIC_SPI 196 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +                       <GIC_SPI 197 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
>          };
> +      };
> +
> +      intc1: interrupt-controller at 14c18000 {
> +        compatible = "simple-mfd";
> +        reg = <0 0x14c18000 0x400>;
> +        ranges = <0x0 0x0 0x0 0x14c18000 0x400>;
> +        #address-cells = <2>;
> +        #size-cells = <1>;
> +
> +        intc1_4: interrupt-controller at 140 {
> +          compatible = "aspeed,ast2700-intc-ic";
> +          reg = <0x0 0x140 0x10>;
> +          #interrupt-cells = <2>;
> +          interrupt-controller;
> +          interrupts-extended = <&intc0_11 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> +        };
> +      };
> +
> +      uart12: serial at 14c33b00 {
> +        compatible = "ns16550a";
> +        reg = <0x0 0x14c33b00 0x100>;
> +        interrupts-extended = <&intc1_4 18 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> +        reg-shift = <2>;
> +        reg-io-width = <4>;
> +        no-loopback-test;
> +      };

And above is not related at all. Don't add entirely unrelated changes. Drop.


Best regards,
Krzysztof


From krzk at kernel.org  Thu Dec 12 23:59:15 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 08:59:15 +0100
Subject: [PATCH v3 2/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
In-Reply-To: <20241212155237.848336-4-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-4-kevin_chen@aspeedtech.com>
Message-ID: <7289a50a-e139-453f-a512-3dd68a0839a2@kernel.org>

On 12/12/2024 16:52, Kevin Chen wrote:
> Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
> ---
>  Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> index 2f92b8ab08fa..20191fee1f5b 100644
> --- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> +++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> @@ -101,4 +101,10 @@ properties:
>                - ufispace,ncplite-bmc
>            - const: aspeed,ast2600
>  
> +      - description: AST2700 based boards
> +        items:
> +          - enum:
> +              - aspeed,ast2700-evb
> +          - const: aspeed,ast2700
> +
>  additionalProperties: true



This patchset is just corrupted. You already sent it as patch #1.

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

Best regards,
Krzysztof


From krzk at kernel.org  Fri Dec 13 00:01:46 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 09:01:46 +0100
Subject: [PATCH v3 4/6] arm64: dts: aspeed: Add initial AST27XX device
 tree
In-Reply-To: <20241212155237.848336-7-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-7-kevin_chen@aspeedtech.com>
Message-ID: <dbfe7c42-cc9b-4471-93ed-846260db42e6@kernel.org>

On 12/12/2024 16:52, Kevin Chen wrote:
> Add aspeed-g7.dtsi to be AST27XX device tree.
> 
> Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>

Where are all the bindings? Why are you silent about this? The patchset
adding new SoC DTS, when separate, is supposed to explain where we can
find the bindings.

> ---
>  arch/arm64/boot/dts/Makefile              |   1 +
>  arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi | 236 ++++++++++++++++++++++
>  2 files changed, 237 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/aspeed/aspeed-g7.


Best regards,
Krzysztof


From krzk at kernel.org  Fri Dec 13 00:03:04 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 09:03:04 +0100
Subject: [PATCH v3 5/6] arm64: dts: aspeed: Add initial AST2700 EVB device
 tree
In-Reply-To: <20241212155237.848336-8-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-8-kevin_chen@aspeedtech.com>
Message-ID: <3e5346a3-ad00-46e2-8af5-1ac5d60c27c8@kernel.org>

On 12/12/2024 16:52, Kevin Chen wrote:
> Add EVB board of AST2700 in ASPEED Architecture.
> 
> Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
> ---
>  arch/arm64/boot/dts/aspeed/Makefile        |  4 ++
>  arch/arm64/boot/dts/aspeed/ast2700-evb.dts | 57 ++++++++++++++++++++++
>  2 files changed, 61 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/aspeed/Makefile
>  create mode 100644 arch/arm64/boot/dts/aspeed/ast2700-evb.dts
> 
> diff --git a/arch/arm64/boot/dts/aspeed/Makefile b/arch/arm64/boot/dts/aspeed/Makefile
> new file mode 100644
> index 000000000000..ffe7e15017cc
> --- /dev/null
> +++ b/arch/arm64/boot/dts/aspeed/Makefile
> @@ -0,0 +1,4 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +dtb-$(CONFIG_ARCH_ASPEED) += \
> +	ast2700-evb.dtb
> diff --git a/arch/arm64/boot/dts/aspeed/ast2700-evb.dts b/arch/arm64/boot/dts/aspeed/ast2700-evb.dts
> new file mode 100644
> index 000000000000..6dad88c98ce0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/aspeed/ast2700-evb.dts
> @@ -0,0 +1,57 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +/dts-v1/;
> +
> +#include "aspeed-g7.dtsi"
> +#include <dt-bindings/gpio/aspeed-gpio.h>
> +
> +/ {
> +	model = "AST2700A1-EVB";
> +	compatible = "aspeed,ast2700-evb", "aspeed,ast2700";
> +
> +	aliases {
> +		serial12 = &uart12;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS12,115200n8";
> +		stdout-path = &uart12;

Nothing improved. You keep ignoring my comments: not responding, not
addressing, not fixing the code.

> +	};
> +
> +	firmware {
> +		optee: optee {
> +			compatible = "linaro,optee-tz";
> +			method = "smc";
> +		};
> +	};
> +
> +	memory at 400000000 {
> +		device_type = "memory";
> +		reg = <0x4 0x00000000 0x40000000>;
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		mcu_fw: mcu-firmware at 42fe00000 {
> +			reg = <0x4 0x2fe00000 0x200000>;
> +			no-map;
> +		};
> +
> +		atf: trusted-firmware-a at 430000000 {
> +			reg = <0x4 0x30000000 0x80000>;
> +			no-map;
> +		};
> +
> +		optee_core: optee_core at 430080000 {

Follow DTS Coding style document. That's the same comment as before.


Best regards,
Krzysztof


From krzk at kernel.org  Fri Dec 13 00:03:46 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 09:03:46 +0100
Subject: [PATCH v3 2/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
In-Reply-To: <7289a50a-e139-453f-a512-3dd68a0839a2@kernel.org>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-4-kevin_chen@aspeedtech.com>
 <7289a50a-e139-453f-a512-3dd68a0839a2@kernel.org>
Message-ID: <7b991fca-6e2f-454f-a94d-6a583854769b@kernel.org>

On 13/12/2024 08:59, Krzysztof Kozlowski wrote:
> On 12/12/2024 16:52, Kevin Chen wrote:
>> Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
>> ---
>>  Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
>> index 2f92b8ab08fa..20191fee1f5b 100644
>> --- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
>> +++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
>> @@ -101,4 +101,10 @@ properties:
>>                - ufispace,ncplite-bmc
>>            - const: aspeed,ast2600
>>  
>> +      - description: AST2700 based boards
>> +        items:
>> +          - enum:
>> +              - aspeed,ast2700-evb
>> +          - const: aspeed,ast2700
>> +
>>  additionalProperties: true
> 
> 
> 
> This patchset is just corrupted. You already sent it as patch #1.
> 
> Please run scripts/checkpatch.pl and fix reported warnings. Then please
> run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
> Some warnings can be ignored, especially from --strict run, but the code
> here looks like it needs a fix. Feel free to get in touch if the warning
> is not clear.
BTW, you already got here same comments before and this is third time
you send exactly the same without implementing what we asked you.

Three times same issue.

NAK

Best regards,
Krzysztof


From tudor.ambarus at linaro.org  Fri Dec 13 00:13:07 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 13 Dec 2024 08:13:07 +0000
Subject: [PATCH v4 1/3] dt-bindings: mailbox: add google,gs101-mbox
 bindings
In-Reply-To: <90720b8f-340f-4f27-ae51-df98b2e5e820@linaro.org>
References: <20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf@linaro.org>
 <20241212-acpm-v4-upstream-mbox-v4-1-02f8de92cfaf@linaro.org>
 <173402453635.2828943.15564980222849076434.robh@kernel.org>
 <90720b8f-340f-4f27-ae51-df98b2e5e820@linaro.org>
Message-ID: <467966de-ae91-417f-b315-62459af93b7d@linaro.org>



On 12/12/24 5:53 PM, Tudor Ambarus wrote:
> 
> 
> On 12/12/24 5:28 PM, Rob Herring (Arm) wrote:
>> My bot found errors running 'make dt_binding_check' on your patch:
>>
>> yamllint warnings/errors:
>>
>> dtschema/dtc warnings/errors:
>> Documentation/devicetree/bindings/mailbox/google,gs101-mbox.example.dtb:
>>  /example-0/soc/mailbox at 17610000: failed to match any schema with 
>> compatible: ['google,gs101-acpm-mbox']
> 

It seems I had an outdated dtschema (2023.11) and couldn't see the
error. Updated to dtschema-2024.11 and now I see it.

The takeover is that I shall periodically check for updates, or maybe to
try to upgrade dtschema and dependencies before each test.

> ugh, I remember I fixed this, compatible in the example needs to be
> updated to 'google,gs101-mbox'. I'll send a new version tomorrow.
> 
> Thanks,
> ta


From xu.yang_2 at nxp.com  Fri Dec 13 00:17:29 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Fri, 13 Dec 2024 16:17:29 +0800
Subject: [PATCH] ARM: dts: nxp: imx6qdl: add dr_mode to usbotg
In-Reply-To: <20241212043126.73045-1-hui.wang@canonical.com>
References: <20241212043126.73045-1-hui.wang@canonical.com>
Message-ID: <20241213081729.ohgs7tyyzywd4uyc@hippo>

Hi,

On Thu, Dec 12, 2024 at 12:31:26PM +0800, Hui Wang wrote:
> For the chipidea usb driver, if the dr_mode is not set, it will set
> the device to otg mode by default, so here the dr_mode has not been
> set for a long time. But some testcases need to parse the dr_mode from
> DT and decide the follow-up test strategy, here set the dr_mode to otg
> explicitly for QA's testcases.

The dr_mode is board specific property, so we normally don't put it in
dtsi file. Also, imx6qdl.dtsi is a common dtsi, therefore it's not a
correct place. I wonder you don't set dr_mode in other dts file which
include will imx6qdl.dtsi?

Thanks,
Xu Yang

> 
> Signed-off-by: Hui Wang <hui.wang at canonical.com>
> ---
>  arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
> index d2200c9db25a..285fb7314a88 100644
> --- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
> +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
> @@ -982,6 +982,7 @@ usbotg: usb at 2184000 {
>  				clocks = <&clks IMX6QDL_CLK_USBOH3>;
>  				fsl,usbphy = <&usbphy1>;
>  				fsl,usbmisc = <&usbmisc 0>;
> +				dr_mode = "otg";
>  				ahb-burst-config = <0x0>;
>  				tx-burst-size-dword = <0x10>;
>  				rx-burst-size-dword = <0x10>;
> -- 
> 2.34.1
> 


From shijie at amperemail.onmicrosoft.com  Fri Dec 13 00:22:41 2024
From: shijie at amperemail.onmicrosoft.com (Shijie Huang)
Date: Fri, 13 Dec 2024 16:22:41 +0800
Subject: [PATCH v4 1/2 fix] arm64: refactor the rodata=xxx
In-Reply-To: <CAMj1kXF=1Hr9G4ZjnEVzJ1snn0V4L-=+bMU4bn=m0UbYLyBqGA@mail.gmail.com>
References: <20241212082426.4110-2-shijie@os.amperecomputing.com>
 <20241213053049.7592-1-shijie@os.amperecomputing.com>
 <CAMj1kXF=1Hr9G4ZjnEVzJ1snn0V4L-=+bMU4bn=m0UbYLyBqGA@mail.gmail.com>
Message-ID: <be0d7423-ca33-416d-a410-3ff303493261@amperemail.onmicrosoft.com>

Hi Ard,

On 2024/12/13 15:30, Ard Biesheuvel wrote:
> Hello Huang Shije,
>
> On Fri, 13 Dec 2024 at 06:32, Huang Shijie
> <shijie at os.amperecomputing.com> wrote:
>> As per admin guide documentation, "rodata=on" should be the default on
>> platforms. Documentation/admin-guide/kernel-parameters.txt describes
>> these options as
>>
>>     rodata=         [KNL,EARLY]
>>             on      Mark read-only kernel memory as read-only (default).
>>             off     Leave read-only kernel memory writable for debugging.
>>             full    Mark read-only kernel memory and aliases as read-only
>>                     [arm64]
>>
>> But on arm64 platform, "rodata=full" is the default instead. This patch
>> implements the following changes.
>>
>>   - Make "rodata=on" behaviour same as the original "rodata=full"
>>   - Make "rodata=noalias" (new) behaviour same as the original "rodata=on"
>>   - Drop the original "rodata=full"
>>   - Add comment for arch_parse_debug_rodata()
>>   - Update kernel-parameters.txt as required
>>
>> After this patch, the "rodata=on" will be the default on arm64 platform
>> as well.
>>
>> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
>> ---
>> Add more descriptions for "noalias":
>>    It is not a security feature yet.
> Why did you add that?
The following is the current status of "rodata=noalias" by checking the 
kernel page table in my machine:

 ?? 1) the kernel code keeps read-only in both the "vmalloc area" and 
the "linear area".

 ?? 2) But there is a read-only memory range which is read-only in 
"vmalloc area", but its linear alias is read-write in the "linear area".


Maybe the "security" is not a proper word.


>
> How do you envisage 'noalias' becoming a security feature? The point

for the case 2) above, if its linear alias is also mapped as read-only,

can we think it is safe as the original "rodata=full"?


> of 'full' rodata was to harden the read-only regions in the vmalloc
> space against inadvertent modification via the writeable linear alias,
> so 'noalias' is less secure than rodata=full, and should be documented
> as such.


>> ---
>>   .../admin-guide/kernel-parameters.txt         |  3 ++-
>>   arch/arm64/include/asm/setup.h                | 27 +++++++++++++++++--
>>   2 files changed, 27 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
>> index a22b7e621007..f5db01eecbd3 100644
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -5901,7 +5901,8 @@
>>          rodata=         [KNL,EARLY]
>>                  on      Mark read-only kernel memory as read-only (default).
>>                  off     Leave read-only kernel memory writable for debugging.
>> -               full    Mark read-only kernel memory and aliases as read-only
>> +               noalias Use more block mappings,may have better performance.
>> +                       But this is not a security feature.
>>                          [arm64]

What's about change it to:

 ?? diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index a22b7e621007..3d4aef0d0811 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5901,7 +5901,8 @@
 ??????? rodata=???????? [KNL,EARLY]
 ? ? ???????????? on????? Mark read-only kernel memory as read-only 
(default).
 ?? ????????????? off???? Leave read-only kernel memory writable for 
debugging.
-?????????????? full? ?? Mark read-only kernel memory and aliases as 
read-only
+?????????????? noalias Use more block mappings,may have better performance.
+??????????????????????? It is less secure then "rodata=on".
 ??????????????????????? [arm64]



>>
>>          rockchip.usb_uart
>> diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
>> index ba269a7a3201..0ef57d19fc2a 100644
>> --- a/arch/arm64/include/asm/setup.h
>> +++ b/arch/arm64/include/asm/setup.h
>> @@ -13,6 +13,29 @@
>>   extern phys_addr_t __fdt_pointer __initdata;
>>   extern u64 __cacheline_aligned boot_args[4];
>>
>> +/*
>> + * rodata=on (default)
>> + *
>> + *    This applies read-only attributes to VM areas and to the linear
>> + *    alias of the backing pages as well. This prevents code or read-
>> + *    only data from being modified (inadvertently or intentionally),
>> + *    via another mapping for the same memory page.
>> + *
>> + *    But this might cause linear map region to be mapped down to base
>> + *    pages, which may adversely affect performance in some cases.
>> + *
>> + * rodata=off
>> + *
>> + *    This provides more block mappings and contiguous hints for linear
>> + *    map region which would minimize TLB footprint. This also leaves
>> + *    read-only kernel memory writable for debugging.
>> + *
>> + * rodata=noalias
>> + *
>> + *    This provides more block mappings and contiguous hints for linear
>> + *    map region which would minimize TLB footprint. This is not a
>> + *    security feature yet.
> Better replace the last sentence with
>
> "This leaves the linear alias of read-only mappings in the vmalloc
> space writeable, making them susceptible to inadvertent modification
> by software."

No problem.


Thanks

Huang Shijie



From ardb at kernel.org  Fri Dec 13 00:26:14 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 13 Dec 2024 09:26:14 +0100
Subject: [PATCH v4 1/2 fix] arm64: refactor the rodata=xxx
In-Reply-To: <be0d7423-ca33-416d-a410-3ff303493261@amperemail.onmicrosoft.com>
References: <20241212082426.4110-2-shijie@os.amperecomputing.com>
 <20241213053049.7592-1-shijie@os.amperecomputing.com> <CAMj1kXF=1Hr9G4ZjnEVzJ1snn0V4L-=+bMU4bn=m0UbYLyBqGA@mail.gmail.com>
 <be0d7423-ca33-416d-a410-3ff303493261@amperemail.onmicrosoft.com>
Message-ID: <CAMj1kXHXeiPiksuOabp-NXu0ORmmP1Jd1wZPmgAi09jsjaDAsQ@mail.gmail.com>

On Fri, 13 Dec 2024 at 09:23, Shijie Huang
<shijie at amperemail.onmicrosoft.com> wrote:
>
> Hi Ard,
>
> On 2024/12/13 15:30, Ard Biesheuvel wrote:
> > Hello Huang Shije,
> >
> > On Fri, 13 Dec 2024 at 06:32, Huang Shijie
> > <shijie at os.amperecomputing.com> wrote:
> >> As per admin guide documentation, "rodata=on" should be the default on
> >> platforms. Documentation/admin-guide/kernel-parameters.txt describes
> >> these options as
> >>
> >>     rodata=         [KNL,EARLY]
> >>             on      Mark read-only kernel memory as read-only (default).
> >>             off     Leave read-only kernel memory writable for debugging.
> >>             full    Mark read-only kernel memory and aliases as read-only
> >>                     [arm64]
> >>
> >> But on arm64 platform, "rodata=full" is the default instead. This patch
> >> implements the following changes.
> >>
> >>   - Make "rodata=on" behaviour same as the original "rodata=full"
> >>   - Make "rodata=noalias" (new) behaviour same as the original "rodata=on"
> >>   - Drop the original "rodata=full"
> >>   - Add comment for arch_parse_debug_rodata()
> >>   - Update kernel-parameters.txt as required
> >>
> >> After this patch, the "rodata=on" will be the default on arm64 platform
> >> as well.
> >>
> >> Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
> >> ---
> >> Add more descriptions for "noalias":
> >>    It is not a security feature yet.
> > Why did you add that?
> The following is the current status of "rodata=noalias" by checking the
> kernel page table in my machine:
>
>     1) the kernel code keeps read-only in both the "vmalloc area" and
> the "linear area".
>
>     2) But there is a read-only memory range which is read-only in
> "vmalloc area", but its linear alias is read-write in the "linear area".
>
>
> Maybe the "security" is not a proper word.
>

There is nothing wrong with the word 'security' as long as you are
clear about the fact that rodata=noalias decreases it.

>
> >
> > How do you envisage 'noalias' becoming a security feature? The point
>
> for the case 2) above, if its linear alias is also mapped as read-only,
>
> can we think it is safe as the original "rodata=full"?
>

No, it is not. Why would we bother with rodata=full (which is costly
in terms of TLB pressure) if rodata=noalias is equally safe?


From arnd at kernel.org  Fri Dec 13 00:30:51 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Fri, 13 Dec 2024 09:30:51 +0100
Subject: [PATCH] phy: mediatek: phy-mtk-hdmi: add regulator dependency
Message-ID: <20241213083056.2596499-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

The driver no longer builds when regulator support is unavailable:

arm-linux-gnueabi-ld: drivers/phy/mediatek/phy-mtk-hdmi.o: in function `mtk_hdmi_phy_register_regulators':
phy-mtk-hdmi.c:(.text.unlikely+0x3e): undefined reference to `devm_regulator_register'
arm-linux-gnueabi-ld: drivers/phy/mediatek/phy-mtk-hdmi-mt8195.o: in function `mtk_hdmi_phy_pwr5v_is_enabled':
phy-mtk-hdmi-mt8195.c:(.text+0x326): undefined reference to `rdev_get_drvdata'
arm-linux-gnueabi-ld: drivers/phy/mediatek/phy-mtk-hdmi-mt8195.o: in function `mtk_hdmi_phy_pwr5v_disable':
phy-mtk-hdmi-mt8195.c:(.text+0x346): undefined reference to `rdev_get_drvdata'
arm-linux-gnueabi-ld: drivers/phy/mediatek/phy-mtk-hdmi-mt8195.o: in function `mtk_hdmi_phy_pwr5v_enable':

Fixes: 49393b2da1cd ("phy: mediatek: phy-mtk-hdmi: Register PHY provided regulator")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/phy/mediatek/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index 60e00057e8bc..ba6461350951 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -65,6 +65,7 @@ config PHY_MTK_HDMI
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 	depends on COMMON_CLK
 	depends on OF
+	depends on REGULATOR
 	select GENERIC_PHY
 	help
 	  Support HDMI PHY for Mediatek SoCs.
-- 
2.39.5



From cleger at rivosinc.com  Fri Dec 13 00:33:14 2024
From: cleger at rivosinc.com (=?UTF-8?B?Q2zDqW1lbnQgTMOpZ2Vy?=)
Date: Fri, 13 Dec 2024 09:33:14 +0100
Subject: [PATCH v3 3/4] drivers: firmware: add riscv SSE support
In-Reply-To: <Z1vALzeks+6Fkf9/@ventana>
References: <20241206163102.843505-1-cleger@rivosinc.com>
 <20241206163102.843505-4-cleger@rivosinc.com> <Z1vALzeks+6Fkf9/@ventana>
Message-ID: <20575689-a129-4295-80f9-0d3d9ec9d59b@rivosinc.com>



On 13/12/2024 06:03, Himanshu Chauhan wrote:
> Hi Clement,
> 
> On Fri, Dec 06, 2024 at 05:30:59PM +0100, Cl?ment L?ger wrote:
>> Add driver level interface to use RISC-V SSE arch support. This interface
>> allows registering SSE handlers, and receive them. This will be used by
>> PMU and GHES driver.
>>
>> Signed-off-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
>> Co-developed-by: Himanshu Chauhan <hchauhan at ventanamicro.com>
>> Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
>> ---
>>  MAINTAINERS                        |  14 +
>>  drivers/firmware/Kconfig           |   1 +
>>  drivers/firmware/Makefile          |   1 +
>>  drivers/firmware/riscv/Kconfig     |  15 +
>>  drivers/firmware/riscv/Makefile    |   3 +
>>  drivers/firmware/riscv/riscv_sse.c | 691 +++++++++++++++++++++++++++++
>>  include/linux/riscv_sse.h          |  56 +++
>>  7 files changed, 781 insertions(+)
>>  create mode 100644 drivers/firmware/riscv/Kconfig
>>  create mode 100644 drivers/firmware/riscv/Makefile
>>  create mode 100644 drivers/firmware/riscv/riscv_sse.c
>>  create mode 100644 include/linux/riscv_sse.h
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 686109008d8e..a3ddde7fe9fb 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -20125,6 +20125,13 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
>>  F:	Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
>>  F:	drivers/iommu/riscv/
>>  
>> +RISC-V FIRMWARE DRIVERS
>> +M:	Conor Dooley <conor at kernel.org>
>> +L:	linux-riscv at lists.infradead.org
>> +S:	Maintained
>> +T:	git git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git
>> +F:	drivers/firmware/riscv/*
>> +
>>  RISC-V MICROCHIP FPGA SUPPORT
>>  M:	Conor Dooley <conor.dooley at microchip.com>
>>  M:	Daire McNamara <daire.mcnamara at microchip.com>
>> @@ -20177,6 +20184,13 @@ F:	drivers/perf/riscv_pmu.c
>>  F:	drivers/perf/riscv_pmu_legacy.c
>>  F:	drivers/perf/riscv_pmu_sbi.c
>>  
>> +RISC-V SSE DRIVER
>> +M:	Cl?ment L?ger <cleger at rivosinc.com>
>> +L:	linux-riscv at lists.infradead.org
>> +S:	Maintained
>> +F:	drivers/firmware/riscv/riscv_sse.c
>> +F:	include/linux/riscv_sse.h
>> +
> 
> I request you to add me as a reviewer to these SSE files.
> Himanshu Chauhan <himanshu at thechauhan.dev>

Oh yes sure !

Thanks,

Cl?ment

> 
> Thanks
> Regards
> Himanshu
> 
>>  RISC-V THEAD SoC SUPPORT
>>  M:	Drew Fustini <drew at pdp7.com>
>>  M:	Guo Ren <guoren at kernel.org>
>> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
>> index 71d8b26c4103..9e996a1fd511 100644
>> --- a/drivers/firmware/Kconfig
>> +++ b/drivers/firmware/Kconfig
>> @@ -267,6 +267,7 @@ source "drivers/firmware/meson/Kconfig"
>>  source "drivers/firmware/microchip/Kconfig"
>>  source "drivers/firmware/psci/Kconfig"
>>  source "drivers/firmware/qcom/Kconfig"
>> +source "drivers/firmware/riscv/Kconfig"
>>  source "drivers/firmware/smccc/Kconfig"
>>  source "drivers/firmware/tegra/Kconfig"
>>  source "drivers/firmware/xilinx/Kconfig"
>> diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
>> index 7a8d486e718f..c0f5009949a8 100644
>> --- a/drivers/firmware/Makefile
>> +++ b/drivers/firmware/Makefile
>> @@ -33,6 +33,7 @@ obj-y				+= efi/
>>  obj-y				+= imx/
>>  obj-y				+= psci/
>>  obj-y				+= qcom/
>> +obj-y				+= riscv/
>>  obj-y				+= smccc/
>>  obj-y				+= tegra/
>>  obj-y				+= xilinx/
>> diff --git a/drivers/firmware/riscv/Kconfig b/drivers/firmware/riscv/Kconfig
>> new file mode 100644
>> index 000000000000..8056ed3262d9
>> --- /dev/null
>> +++ b/drivers/firmware/riscv/Kconfig
>> @@ -0,0 +1,15 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +menu "Risc-V Specific firmware drivers"
>> +depends on RISCV
>> +
>> +config RISCV_SSE
>> +	bool "Enable SBI Supervisor Software Events support"
>> +	depends on RISCV_SBI
>> +	default y
>> +	help
>> +	  The Supervisor Software Events support allow the SBI to deliver
>> +	  NMI-like notifications to the supervisor mode software. When enable,
>> +	  this option provides support to register callbacks on specific SSE
>> +	  events.
>> +
>> +endmenu
>> diff --git a/drivers/firmware/riscv/Makefile b/drivers/firmware/riscv/Makefile
>> new file mode 100644
>> index 000000000000..4ccfcbbc28ea
>> --- /dev/null
>> +++ b/drivers/firmware/riscv/Makefile
>> @@ -0,0 +1,3 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +
>> +obj-$(CONFIG_RISCV_SSE)		+= riscv_sse.o
>> diff --git a/drivers/firmware/riscv/riscv_sse.c b/drivers/firmware/riscv/riscv_sse.c
>> new file mode 100644
>> index 000000000000..c165e32cc9a5
>> --- /dev/null
>> +++ b/drivers/firmware/riscv/riscv_sse.c
>> @@ -0,0 +1,691 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (C) 2024 Rivos Inc.
>> + */
>> +
>> +#define pr_fmt(fmt) "sse: " fmt
>> +
>> +#include <linux/cpu.h>
>> +#include <linux/cpuhotplug.h>
>> +#include <linux/cpu_pm.h>
>> +#include <linux/hardirq.h>
>> +#include <linux/list.h>
>> +#include <linux/percpu-defs.h>
>> +#include <linux/reboot.h>
>> +#include <linux/riscv_sse.h>
>> +#include <linux/slab.h>
>> +
>> +#include <asm/sbi.h>
>> +#include <asm/sse.h>
>> +
>> +struct sse_event {
>> +	struct list_head list;
>> +	u32 evt;
>> +	u32 priority;
>> +	sse_event_handler *handler;
>> +	void *handler_arg;
>> +	bool is_enabled;
>> +	/* Only valid for global events */
>> +	unsigned int cpu;
>> +
>> +	union {
>> +		struct sse_registered_event *global;
>> +		struct sse_registered_event __percpu *local;
>> +	};
>> +};
>> +
>> +static int sse_hp_state;
>> +static bool sse_available;
>> +static DEFINE_SPINLOCK(events_list_lock);
>> +static LIST_HEAD(events);
>> +static DEFINE_MUTEX(sse_mutex);
>> +
>> +struct sse_registered_event {
>> +	struct sse_event_arch_data arch;
>> +	struct sse_event *evt;
>> +	unsigned long attr_buf;
>> +};
>> +
>> +void sse_handle_event(struct sse_event_arch_data *arch_event,
>> +		      struct pt_regs *regs)
>> +{
>> +	int ret;
>> +	struct sse_registered_event *reg_evt =
>> +		container_of(arch_event, struct sse_registered_event, arch);
>> +	struct sse_event *evt = reg_evt->evt;
>> +
>> +	ret = evt->handler(evt->evt, evt->handler_arg, regs);
>> +	if (ret)
>> +		pr_warn("event %x handler failed with error %d\n", evt->evt,
>> +			ret);
>> +}
>> +
>> +static bool sse_event_is_global(u32 evt)
>> +{
>> +	return !!(evt & SBI_SSE_EVENT_GLOBAL);
>> +}
>> +
>> +static
>> +struct sse_event *sse_event_get(u32 evt)
>> +{
>> +	struct sse_event *sse_evt = NULL, *tmp;
>> +
>> +	scoped_guard(spinlock, &events_list_lock) {
>> +		list_for_each_entry(tmp, &events, list) {
>> +			if (tmp->evt == evt) {
>> +				return sse_evt;
>> +			}
>> +		}
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +static phys_addr_t sse_event_get_phys(struct sse_registered_event *reg_evt,
>> +				      void *addr)
>> +{
>> +	phys_addr_t phys;
>> +
>> +	if (sse_event_is_global(reg_evt->evt->evt))
>> +		phys = virt_to_phys(addr);
>> +	else
>> +		phys = per_cpu_ptr_to_phys(addr);
>> +
>> +	return phys;
>> +}
>> +
>> +static int sse_sbi_event_func(struct sse_event *event, unsigned long func)
>> +{
>> +	struct sbiret ret;
>> +	u32 evt = event->evt;
>> +
>> +	ret = sbi_ecall(SBI_EXT_SSE, func, evt, 0, 0, 0, 0, 0);
>> +	if (ret.error)
>> +		pr_debug("Failed to execute func %lx, event %x, error %ld\n",
>> +			 func, evt, ret.error);
>> +
>> +	return sbi_err_map_linux_errno(ret.error);
>> +}
>> +
>> +static int sse_sbi_disable_event(struct sse_event *event)
>> +{
>> +	return sse_sbi_event_func(event, SBI_SSE_EVENT_DISABLE);
>> +}
>> +
>> +static int sse_sbi_enable_event(struct sse_event *event)
>> +{
>> +	return sse_sbi_event_func(event, SBI_SSE_EVENT_ENABLE);
>> +}
>> +
>> +static int sse_event_attr_get_no_lock(struct sse_registered_event *reg_evt,
>> +				      unsigned long attr_id, unsigned long *val)
>> +{
>> +	struct sbiret sret;
>> +	u32 evt = reg_evt->evt->evt;
>> +	unsigned long phys;
>> +
>> +	phys = sse_event_get_phys(reg_evt, &reg_evt->attr_buf);
>> +
>> +	sret = sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_ATTR_READ, evt,
>> +				     attr_id, 1, phys, 0, 0);
>> +	if (sret.error) {
>> +		pr_debug("Failed to get event %x attr %lx, error %ld\n", evt,
>> +			 attr_id, sret.error);
>> +		return sbi_err_map_linux_errno(sret.error);
>> +	}
>> +
>> +	*val = reg_evt->attr_buf;
>> +
>> +	return 0;
>> +}
>> +
>> +static int sse_event_attr_set_nolock(struct sse_registered_event *reg_evt,
>> +				     unsigned long attr_id, unsigned long val)
>> +{
>> +	struct sbiret sret;
>> +	u32 evt = reg_evt->evt->evt;
>> +	unsigned long phys;
>> +
>> +	reg_evt->attr_buf = val;
>> +	phys = sse_event_get_phys(reg_evt, &reg_evt->attr_buf);
>> +
>> +	sret = sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_ATTR_WRITE, evt,
>> +				     attr_id, 1, phys, 0, 0);
>> +	if (sret.error && sret.error != SBI_ERR_INVALID_STATE) {
>> +		pr_debug("Failed to set event %x attr %lx, error %ld\n", evt,
>> +			 attr_id, sret.error);
>> +		return sbi_err_map_linux_errno(sret.error);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int sse_event_set_target_cpu_nolock(struct sse_event *event,
>> +					   unsigned int cpu)
>> +{
>> +	unsigned int hart_id = cpuid_to_hartid_map(cpu);
>> +	struct sse_registered_event *reg_evt = event->global;
>> +	u32 evt = event->evt;
>> +	bool was_enabled;
>> +	int ret;
>> +
>> +	if (!sse_event_is_global(evt))
>> +		return -EINVAL;
>> +
>> +	was_enabled = event->is_enabled;
>> +	if (was_enabled)
>> +		sse_sbi_disable_event(event);
>> +	do {
>> +		ret = sse_event_attr_set_nolock(reg_evt,
>> +						SBI_SSE_ATTR_PREFERRED_HART,
>> +						hart_id);
>> +	} while (ret == -EINVAL);
>> +
>> +	if (ret == 0)
>> +		event->cpu = cpu;
>> +
>> +	if (was_enabled)
>> +		sse_sbi_enable_event(event);
>> +
>> +	return 0;
>> +}
>> +
>> +int sse_event_set_target_cpu(struct sse_event *event, unsigned int cpu)
>> +{
>> +	int ret;
>> +
>> +	scoped_guard(mutex, &sse_mutex) {
>> +		cpus_read_lock();
>> +
>> +		if (!cpu_online(cpu))
>> +			return -EINVAL;
>> +
>> +		ret = sse_event_set_target_cpu_nolock(event, cpu);
>> +
>> +		cpus_read_unlock();
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static int sse_event_init_registered(unsigned int cpu,
>> +				     struct sse_registered_event *reg_evt,
>> +				     struct sse_event *event)
>> +{
>> +	reg_evt->evt = event;
>> +	arch_sse_init_event(&reg_evt->arch, event->evt, cpu);
>> +
>> +	return 0;
>> +}
>> +
>> +static void sse_event_free_registered(struct sse_registered_event *reg_evt)
>> +{
>> +	arch_sse_free_event(&reg_evt->arch);
>> +}
>> +
>> +static int sse_event_alloc_global(struct sse_event *event)
>> +{
>> +	int err;
>> +	struct sse_registered_event *reg_evt;
>> +
>> +	reg_evt = kzalloc(sizeof(*reg_evt), GFP_KERNEL);
>> +	if (!reg_evt)
>> +		return -ENOMEM;
>> +
>> +	event->global = reg_evt;
>> +	err = sse_event_init_registered(smp_processor_id(), reg_evt,
>> +					event);
>> +	if (err)
>> +		kfree(reg_evt);
>> +
>> +	return err;
>> +}
>> +
>> +static int sse_event_alloc_local(struct sse_event *event)
>> +{
>> +	int err;
>> +	unsigned int cpu, err_cpu;
>> +	struct sse_registered_event *reg_evt;
>> +	struct sse_registered_event __percpu *reg_evts;
>> +
>> +	reg_evts = alloc_percpu(struct sse_registered_event);
>> +	if (!reg_evts)
>> +		return -ENOMEM;
>> +
>> +	event->local = reg_evts;
>> +
>> +	for_each_possible_cpu(cpu) {
>> +		reg_evt = per_cpu_ptr(reg_evts, cpu);
>> +		err = sse_event_init_registered(cpu, reg_evt, event);
>> +		if (err) {
>> +			err_cpu = cpu;
>> +			goto err_free_per_cpu;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +
>> +err_free_per_cpu:
>> +	for_each_possible_cpu(cpu) {
>> +		if (cpu == err_cpu)
>> +			break;
>> +		reg_evt = per_cpu_ptr(reg_evts, cpu);
>> +		sse_event_free_registered(reg_evt);
>> +	}
>> +
>> +	free_percpu(reg_evts);
>> +
>> +	return err;
>> +}
>> +
>> +static struct sse_event *sse_event_alloc(u32 evt,
>> +					 u32 priority,
>> +					 sse_event_handler *handler, void *arg)
>> +{
>> +	int err;
>> +	struct sse_event *event;
>> +
>> +	event = kzalloc(sizeof(*event), GFP_KERNEL);
>> +	if (!event)
>> +		return ERR_PTR(-ENOMEM);
>> +
>> +	event->evt = evt;
>> +	event->priority = priority;
>> +	event->handler_arg = arg;
>> +	event->handler = handler;
>> +
>> +	if (sse_event_is_global(evt)) {
>> +		err = sse_event_alloc_global(event);
>> +		if (err)
>> +			goto err_alloc_reg_evt;
>> +	} else {
>> +		err = sse_event_alloc_local(event);
>> +		if (err)
>> +			goto err_alloc_reg_evt;
>> +	}
>> +
>> +	return event;
>> +
>> +err_alloc_reg_evt:
>> +	kfree(event);
>> +
>> +	return ERR_PTR(err);
>> +}
>> +
>> +static int sse_sbi_register_event(struct sse_event *event,
>> +				  struct sse_registered_event *reg_evt)
>> +{
>> +	int ret;
>> +
>> +	ret = sse_event_attr_set_nolock(reg_evt, SBI_SSE_ATTR_PRIO,
>> +					event->priority);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return arch_sse_register_event(&reg_evt->arch);
>> +}
>> +
>> +static int sse_event_register_local(struct sse_event *event)
>> +{
>> +	int ret;
>> +	struct sse_registered_event *reg_evt = per_cpu_ptr(event->local,
>> +							   smp_processor_id());
>> +
>> +	ret = sse_sbi_register_event(event, reg_evt);
>> +	if (ret)
>> +		pr_debug("Failed to register event %x: err %d\n", event->evt,
>> +			 ret);
>> +
>> +	return ret;
>> +}
>> +
>> +
>> +static int sse_sbi_unregister_event(struct sse_event *event)
>> +{
>> +	return sse_sbi_event_func(event, SBI_SSE_EVENT_UNREGISTER);
>> +}
>> +
>> +struct sse_per_cpu_evt {
>> +	struct sse_event *event;
>> +	unsigned long func;
>> +	atomic_t error;
>> +};
>> +
>> +static void sse_event_per_cpu_func(void *info)
>> +{
>> +	int ret;
>> +	struct sse_per_cpu_evt *cpu_evt = info;
>> +
>> +	if (cpu_evt->func == SBI_SSE_EVENT_REGISTER)
>> +		ret = sse_event_register_local(cpu_evt->event);
>> +	else
>> +		ret = sse_sbi_event_func(cpu_evt->event, cpu_evt->func);
>> +
>> +	if (ret)
>> +		atomic_set(&cpu_evt->error, ret);
>> +}
>> +
>> +static void sse_event_free(struct sse_event *event)
>> +{
>> +	unsigned int cpu;
>> +	struct sse_registered_event *reg_evt;
>> +
>> +	if (sse_event_is_global(event->evt)) {
>> +		sse_event_free_registered(event->global);
>> +		kfree(event->global);
>> +	} else {
>> +		for_each_possible_cpu(cpu) {
>> +			reg_evt = per_cpu_ptr(event->local, cpu);
>> +			sse_event_free_registered(reg_evt);
>> +		}
>> +		free_percpu(event->local);
>> +	}
>> +
>> +	kfree(event);
>> +}
>> +
>> +int sse_event_enable(struct sse_event *event)
>> +{
>> +	int ret = 0;
>> +	struct sse_per_cpu_evt cpu_evt;
>> +
>> +	scoped_guard(mutex, &sse_mutex) {
>> +		cpus_read_lock();
>> +		if (sse_event_is_global(event->evt)) {
>> +			ret = sse_sbi_enable_event(event);
>> +		} else {
>> +			cpu_evt.event = event;
>> +			atomic_set(&cpu_evt.error, 0);
>> +			cpu_evt.func = SBI_SSE_EVENT_ENABLE;
>> +			on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
>> +			ret = atomic_read(&cpu_evt.error);
>> +			if (ret) {
>> +				cpu_evt.func = SBI_SSE_EVENT_DISABLE;
>> +				on_each_cpu(sse_event_per_cpu_func, &cpu_evt,
>> +					    1);
>> +			}
>> +		}
>> +		cpus_read_unlock();
>> +
>> +		if (ret == 0)
>> +			event->is_enabled = true;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static void sse_events_mask(void)
>> +{
>> +	sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_HART_MASK, 0, 0, 0, 0, 0, 0);
>> +}
>> +
>> +static void sse_events_unmask(void)
>> +{
>> +	sbi_ecall(SBI_EXT_SSE, SBI_SSE_EVENT_HART_UNMASK, 0, 0, 0, 0, 0, 0);
>> +}
>> +
>> +static void sse_event_disable_nolock(struct sse_event *event)
>> +{
>> +	struct sse_per_cpu_evt cpu_evt;
>> +
>> +	if (sse_event_is_global(event->evt)) {
>> +		sse_sbi_disable_event(event);
>> +	} else {
>> +		cpu_evt.event = event;
>> +		cpu_evt.func = SBI_SSE_EVENT_DISABLE;
>> +		on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
>> +	}
>> +}
>> +
>> +void sse_event_disable(struct sse_event *event)
>> +{
>> +	scoped_guard(mutex, &sse_mutex) {
>> +		cpus_read_lock();
>> +		sse_event_disable_nolock(event);
>> +		event->is_enabled = false;
>> +		cpus_read_unlock();
>> +	}
>> +}
>> +
>> +struct sse_event *sse_event_register(u32 evt, u32 priority,
>> +				     sse_event_handler *handler, void *arg)
>> +{
>> +	struct sse_per_cpu_evt cpu_evt;
>> +	struct sse_event *event;
>> +	int ret = 0;
>> +
>> +	if (!sse_available)
>> +		return ERR_PTR(-EOPNOTSUPP);
>> +
>> +	mutex_lock(&sse_mutex);
>> +	if (sse_event_get(evt)) {
>> +		pr_debug("Event %x already registered\n", evt);
>> +		ret = -EEXIST;
>> +		goto out_unlock;
>> +	}
>> +
>> +	event = sse_event_alloc(evt, priority, handler, arg);
>> +	if (IS_ERR(event)) {
>> +		ret = PTR_ERR(event);
>> +		goto out_unlock;
>> +	}
>> +
>> +	cpus_read_lock();
>> +	if (sse_event_is_global(evt)) {
>> +		unsigned long preferred_hart;
>> +
>> +		ret = sse_event_attr_get_no_lock(event->global,
>> +						 SBI_SSE_ATTR_PREFERRED_HART,
>> +						 &preferred_hart);
>> +		if (ret)
>> +			goto err_event_free;
>> +		event->cpu = riscv_hartid_to_cpuid(preferred_hart);
>> +
>> +		ret = sse_sbi_register_event(event, event->global);
>> +		if (ret)
>> +			goto err_event_free;
>> +
>> +	} else {
>> +		cpu_evt.event = event;
>> +		atomic_set(&cpu_evt.error, 0);
>> +		cpu_evt.func = SBI_SSE_EVENT_REGISTER;
>> +		on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
>> +		ret = atomic_read(&cpu_evt.error);
>> +		if (ret) {
>> +			cpu_evt.func = SBI_SSE_EVENT_UNREGISTER;
>> +			on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
>> +			goto err_event_free;
>> +		}
>> +	}
>> +	cpus_read_unlock();
>> +
>> +	scoped_guard(spinlock, &events_list_lock)
>> +		list_add(&event->list, &events);
>> +
>> +	mutex_unlock(&sse_mutex);
>> +
>> +	return event;
>> +
>> +err_event_free:
>> +	cpus_read_unlock();
>> +	sse_event_free(event);
>> +out_unlock:
>> +	mutex_unlock(&sse_mutex);
>> +
>> +	return ERR_PTR(ret);
>> +}
>> +
>> +static void sse_event_unregister_nolock(struct sse_event *event)
>> +{
>> +	struct sse_per_cpu_evt cpu_evt;
>> +
>> +	if (sse_event_is_global(event->evt)) {
>> +		sse_sbi_unregister_event(event);
>> +	} else {
>> +		cpu_evt.event = event;
>> +		cpu_evt.func = SBI_SSE_EVENT_UNREGISTER;
>> +		on_each_cpu(sse_event_per_cpu_func, &cpu_evt, 1);
>> +	}
>> +}
>> +
>> +void sse_event_unregister(struct sse_event *event)
>> +{
>> +	scoped_guard(mutex, &sse_mutex) {
>> +		cpus_read_lock();
>> +		sse_event_unregister_nolock(event);
>> +		cpus_read_unlock();
>> +
>> +		scoped_guard(spinlock, &events_list_lock)
>> +			list_del(&event->list);
>> +
>> +		sse_event_free(event);
>> +	}
>> +}
>> +
>> +static int sse_cpu_online(unsigned int cpu)
>> +{
>> +	struct sse_event *sse_evt;
>> +
>> +	scoped_guard(spinlock, &events_list_lock) {
>> +		list_for_each_entry(sse_evt, &events, list) {
>> +			if (sse_event_is_global(sse_evt->evt))
>> +				continue;
>> +
>> +			sse_event_register_local(sse_evt);
>> +			if (sse_evt->is_enabled)
>> +				sse_sbi_enable_event(sse_evt);
>> +		}
>> +	}
>> +
>> +	/* Ready to handle events. Unmask SSE. */
>> +	sse_events_unmask();
>> +
>> +	return 0;
>> +}
>> +
>> +static int sse_cpu_teardown(unsigned int cpu)
>> +{
>> +	unsigned int next_cpu;
>> +	struct sse_event *sse_evt;
>> +
>> +	/* Mask the sse events */
>> +	sse_events_mask();
>> +
>> +	scoped_guard(spinlock, &events_list_lock) {
>> +		list_for_each_entry(sse_evt, &events, list) {
>> +			if (!sse_event_is_global(sse_evt->evt)) {
>> +
>> +				if (sse_evt->is_enabled)
>> +					sse_sbi_disable_event(sse_evt);
>> +
>> +				sse_sbi_unregister_event(sse_evt);
>> +				continue;
>> +			}
>> +
>> +			if (sse_evt->cpu != smp_processor_id())
>> +				continue;
>> +
>> +			/* Update destination hart for global event */
>> +			next_cpu = cpumask_any_but(cpu_online_mask, cpu);
>> +			sse_event_set_target_cpu_nolock(sse_evt, next_cpu);
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void sse_reset(void)
>> +{
>> +	struct sse_event *event = NULL;
>> +
>> +	list_for_each_entry(event, &events, list) {
>> +		sse_event_disable_nolock(event);
>> +		sse_event_unregister_nolock(event);
>> +	}
>> +}
>> +
>> +static int sse_pm_notifier(struct notifier_block *nb, unsigned long action,
>> +			   void *data)
>> +{
>> +	WARN_ON_ONCE(preemptible());
>> +
>> +	switch (action) {
>> +	case CPU_PM_ENTER:
>> +		sse_events_mask();
>> +		break;
>> +	case CPU_PM_EXIT:
>> +	case CPU_PM_ENTER_FAILED:
>> +		sse_events_unmask();
>> +		break;
>> +	default:
>> +		return NOTIFY_DONE;
>> +	}
>> +
>> +	return NOTIFY_OK;
>> +}
>> +
>> +static struct notifier_block sse_pm_nb = {
>> +	.notifier_call = sse_pm_notifier,
>> +};
>> +
>> +/*
>> + * Mask all CPUs and unregister all events on panic, reboot or kexec.
>> + */
>> +static int sse_reboot_notifier(struct notifier_block *nb, unsigned long action,
>> +				void *data)
>> +{
>> +	cpuhp_remove_state(sse_hp_state);
>> +
>> +	sse_reset();
>> +
>> +	return NOTIFY_OK;
>> +}
>> +
>> +static struct notifier_block sse_reboot_nb = {
>> +	.notifier_call = sse_reboot_notifier,
>> +};
>> +
>> +static int __init sse_init(void)
>> +{
>> +	int cpu, ret;
>> +
>> +	if (sbi_probe_extension(SBI_EXT_SSE) <= 0) {
>> +		pr_err("Missing SBI SSE extension\n");
>> +		return -EOPNOTSUPP;
>> +	}
>> +	pr_info("SBI SSE extension detected\n");
>> +
>> +	for_each_possible_cpu(cpu)
>> +		INIT_LIST_HEAD(&events);
>> +
>> +	ret = cpu_pm_register_notifier(&sse_pm_nb);
>> +	if (ret) {
>> +		pr_warn("Failed to register CPU PM notifier...\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = register_reboot_notifier(&sse_reboot_nb);
>> +	if (ret) {
>> +		pr_warn("Failed to register reboot notifier...\n");
>> +		goto remove_cpupm;
>> +	}
>> +
>> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "riscv/sse:online",
>> +				sse_cpu_online, sse_cpu_teardown);
>> +	if (ret < 0)
>> +		goto remove_reboot;
>> +
>> +	sse_hp_state = ret;
>> +	sse_available = true;
>> +
>> +	return 0;
>> +
>> +remove_reboot:
>> +	unregister_reboot_notifier(&sse_reboot_nb);
>> +
>> +remove_cpupm:
>> +	cpu_pm_unregister_notifier(&sse_pm_nb);
>> +
>> +	return ret;
>> +}
>> +arch_initcall(sse_init);
>> diff --git a/include/linux/riscv_sse.h b/include/linux/riscv_sse.h
>> new file mode 100644
>> index 000000000000..c73184074b8c
>> --- /dev/null
>> +++ b/include/linux/riscv_sse.h
>> @@ -0,0 +1,56 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Copyright (C) 2024 Rivos Inc.
>> + */
>> +
>> +#ifndef __LINUX_RISCV_SSE_H
>> +#define __LINUX_RISCV_SSE_H
>> +
>> +#include <linux/types.h>
>> +#include <linux/linkage.h>
>> +
>> +struct sse_event;
>> +struct pt_regs;
>> +
>> +typedef int (sse_event_handler)(u32 event_num, void *arg, struct pt_regs *regs);
>> +
>> +#ifdef CONFIG_RISCV_SSE
>> +
>> +struct sse_event *sse_event_register(u32 event_num, u32 priority,
>> +				     sse_event_handler *handler, void *arg);
>> +
>> +void sse_event_unregister(struct sse_event *evt);
>> +
>> +int sse_event_set_target_cpu(struct sse_event *sse_evt, unsigned int cpu);
>> +
>> +int sse_event_enable(struct sse_event *sse_evt);
>> +
>> +void sse_event_disable(struct sse_event *sse_evt);
>> +
>> +#else
>> +static inline struct sse_event *sse_event_register(u32 event_num, u32 priority,
>> +						   sse_event_handler *handler,
>> +						   void *arg)
>> +{
>> +	return ERR_PTR(-EOPNOTSUPP);
>> +}
>> +
>> +static inline void sse_event_unregister(struct sse_event *evt) {}
>> +
>> +static inline int sse_event_set_target_cpu(struct sse_event *sse_evt,
>> +					   unsigned int cpu)
>> +{
>> +	return -EOPNOTSUPP;
>> +}
>> +
>> +static inline int sse_event_enable(struct sse_event *sse_evt)
>> +{
>> +	return -EOPNOTSUPP;
>> +}
>> +
>> +static inline void sse_event_disable(struct sse_event *sse_evt) {}
>> +
>> +
>> +#endif
>> +
>> +#endif /* __LINUX_RISCV_SSE_H */
>> -- 
>> 2.45.2
>>



From krzk at kernel.org  Fri Dec 13 00:42:57 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 09:42:57 +0100
Subject: [PATCH 0/3] Add Samsung SPEEDY serial bus host controller driver
In-Reply-To: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
Message-ID: <0ff6f05f-fe6f-4433-a489-0447a165c8d0@kernel.org>

On 12/12/2024 22:09, Markuss Broks wrote:
> Hey,
> 
> This series adds support for the Samsung SPEEDY serial bus host
> controller. Samsung SPEEDY (actually an acronym) is a proprietary
> Samsung 1 wire serial bus, which is used on various Samsung devices.
> 
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.

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).

Please run standard kernel tools for static analysis, like coccinelle,
smatch and sparse, and fix reported warnings. Also please check for
warnings when building with W=1. Most of these commands (checks or W=1
build) can build specific targets, like some directory, to narrow the
scope to only your code. The code here looks like it needs a fix. Feel
free to get in touch if the warning is not clear.

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

Best regards,
Krzysztof


From ck.hu at mediatek.com  Fri Dec 13 00:43:57 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 13 Dec 2024 08:43:57 +0000
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
Message-ID: <47a462d2fe848d3d23811a554516bec1b0424821.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static int mtk_hdmi_probe(struct platform_device *pdev)
> +{
> +       struct mtk_hdmi *hdmi;
> 
> -       ret = mtk_hdmi_clk_enable_audio(hdmi);
> -       if (ret) {
> -               drm_bridge_remove(&hdmi->bridge);
> -               return dev_err_probe(dev, ret,
> -                                    "Failed to enable audio clocks\n");
> -       }
> +       hdmi = mtk_hdmi_common_probe(pdev);
> +       if (IS_ERR(hdmi))
> +               return PTR_ERR(hdmi);

In original v1 driver, update_plugged_status_lock is init in probe.
I can not find the init in this patch.
It's better that moving common code seldom change the order in a function,
so you could easily to compare that moving does not change any thing.
In this patch, you not only moving code, but also change the order in a function,
so it's not easy to find something lost.

That's why I like you to separate this patch into two patches. One is adding version config and the other one is moving common code.
When I review the moving common code part, I would like a function before moving is almost same as after moving,
so it's easy to find out something lost.

Regards,
CK

> 
> -       return 0;
> +       return mtk_hdmi_clk_enable_audio(hdmi);
>  }
> 

[snip]

> +struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
> +{
> +       const struct mtk_hdmi_ver_conf *ver_conf;
> +       struct device *dev = &pdev->dev;
> +       struct mtk_hdmi *hdmi;
> +       int ret;
> +
> +       hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
> +       if (!hdmi)
> +               return ERR_PTR(-ENOMEM);
> +
> +       hdmi->dev = dev;
> +       hdmi->conf = of_device_get_match_data(dev);
> +       ver_conf = hdmi->conf->ver_conf;
> +
> +       hdmi->clk = devm_kcalloc(dev, ver_conf->num_clocks, sizeof(*hdmi->clk), GFP_KERNEL);
> +       if (!hdmi->clk)
> +               return ERR_PTR(-ENOMEM);
> +
> +       hdmi->phy = devm_phy_get(dev, "hdmi");
> +       if (IS_ERR(hdmi->phy))
> +               return dev_err_cast_probe(dev, hdmi->phy, "Failed to get HDMI PHY\n");
> +
> +       ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, ver_conf->mtk_hdmi_clock_names,
> +                                     ver_conf->num_clocks);
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       platform_set_drvdata(pdev, hdmi);
> +
> +       ret = mtk_hdmi_register_audio_driver(dev);
> +       if (ret)
> +               return dev_err_ptr_probe(dev, ret, "Cannot register HDMI Audio driver\n");
> +
> +       hdmi->bridge.funcs = ver_conf->bridge_funcs;
> +       hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
> +       hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
> +       hdmi->bridge.of_node = pdev->dev.of_node;
> +
> +       ret = devm_drm_bridge_add(dev, &hdmi->bridge);
> +       if (ret)
> +               return dev_err_ptr_probe(dev, ret, "Failed to add bridge\n");
> +
> +       return hdmi;
> +}
> +



From shijie at amperemail.onmicrosoft.com  Fri Dec 13 00:46:31 2024
From: shijie at amperemail.onmicrosoft.com (Shijie Huang)
Date: Fri, 13 Dec 2024 16:46:31 +0800
Subject: [PATCH v4 1/2 fix] arm64: refactor the rodata=xxx
In-Reply-To: <CAMj1kXHXeiPiksuOabp-NXu0ORmmP1Jd1wZPmgAi09jsjaDAsQ@mail.gmail.com>
References: <20241212082426.4110-2-shijie@os.amperecomputing.com>
 <20241213053049.7592-1-shijie@os.amperecomputing.com>
 <CAMj1kXF=1Hr9G4ZjnEVzJ1snn0V4L-=+bMU4bn=m0UbYLyBqGA@mail.gmail.com>
 <be0d7423-ca33-416d-a410-3ff303493261@amperemail.onmicrosoft.com>
 <CAMj1kXHXeiPiksuOabp-NXu0ORmmP1Jd1wZPmgAi09jsjaDAsQ@mail.gmail.com>
Message-ID: <56f10526-ea50-4d24-a042-d05b305e019e@amperemail.onmicrosoft.com>


On 2024/12/13 16:26, Ard Biesheuvel wrote:
>>> How do you envisage 'noalias' becoming a security feature? The point
>> for the case 2) above, if its linear alias is also mapped as read-only,
>>
>> can we think it is safe as the original "rodata=full"?
>>
> No, it is not. Why would we bother with rodata=full (which is costly
> in terms of TLB pressure) if rodata=noalias is equally safe?

okay, thanks.

I will wait for two days, and send out the new patch if there no other 
comment.


Thanks

Huang Shijie



From krzk at kernel.org  Fri Dec 13 00:57:34 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 09:57:34 +0100
Subject: [PATCH v4 1/3] dt-bindings: firmware: add google,gs101-acpm-ipc
 binding
In-Reply-To: <20241212-b4-acpm-v4-upstream-firmware-v4-1-3f18ca64f1b9@linaro.org>
References: <20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9@linaro.org>
 <20241212-b4-acpm-v4-upstream-firmware-v4-1-3f18ca64f1b9@linaro.org>
Message-ID: <qwwd2hqcqtk27kw3f4jtnxwu2joebr5ysyusomqlnsdu3wbcco@ldurbcu5ymr6>

On Thu, Dec 12, 2024 at 03:46:22PM +0000, Tudor Ambarus wrote:
> +properties:
> +  compatible:
> +    const: google,gs101-acpm-ipc
> +
> +  mboxes:
> +    maxItems: 1
> +
> +  shmem:
> +    description:
> +      List of phandle pointing to the shared memory (SHM) area. The memory
> +      contains channels configuration data and the TX/RX ring buffers that
> +      are used for passing messages to/from the ACPM firmware.
> +    maxItems: 1
> +
> +

If there is going to be new version, just one blank line above.

Anyway, wearing DT hat:

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

(I'll review drivers a bit later)

Best regards,
Krzysztof



From lorenzo.stoakes at oracle.com  Fri Dec 13 00:59:53 2024
From: lorenzo.stoakes at oracle.com (Lorenzo Stoakes)
Date: Fri, 13 Dec 2024 08:59:53 +0000
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
In-Reply-To: <20241212173609.afd41d1dffbefe0d731ed4ed@linux-foundation.org>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
 <hmuzfspqjzb36xlj2x44keihacrrhzj5madqrfbcnhqouzredv@wo75achgkuh5>
 <1818e2ea-f170-4a9c-8d93-2a24f2755a41@lucifer.local>
 <20241212173609.afd41d1dffbefe0d731ed4ed@linux-foundation.org>
Message-ID: <695eabb8-ba28-4031-bc4d-66dc4f1d096f@lucifer.local>

On Thu, Dec 12, 2024 at 05:36:09PM -0800, Andrew Morton wrote:
> On Thu, 12 Dec 2024 22:51:34 +0000 Lorenzo Stoakes <lorenzo.stoakes at oracle.com> wrote:
>
> > You've fundamentally violated kernel process and etiquette. I'd be more
> > forgiving, but this is at v2 and you've not cc'd KEY people. Twice. This is
> > totally unacceptable. See [0] if you are unsure of how to do so.
>
> This feels excessive to me.  linux-mm averages a mere 140 mesages/day
> and it seems reasonable to assume that key people are spending their 5
> minutes to scroll through the email subjects.

In practice we did all miss it, and I don't think it's unreasonable to ask
people to run get_maintainers.pl to avoid this.

In any case, I truly do think this series works better as RFC, I mean Liam
has already voiced the kind of disagreements I share with it, and we need
to rethink how to approach it in general.

So if this is simply sent as RFC with the correct cc's (and ideally with
some review feedback applied - a better cover letter, etc.) then it makes
everything easier.

As mentioned the timing is unfortunate here, this is a series we really
want to make sure is properly reviewed before any chance of merge so again
this points to RFC being the way forward.


From maxime.chevallier at bootlin.com  Fri Dec 13 01:05:25 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 13 Dec 2024 10:05:25 +0100
Subject: [PATCH net-next 2/2] net: stmmac: dwmac-socfpga: Set interface modes from Lynx PCS as supported
In-Reply-To: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
Message-ID: <20241213090526.71516-3-maxime.chevallier@bootlin.com>

On Socfpga, the dwmac controller uses a variation of the Lynx PCS to get
additional support for SGMII and 1000BaseX. The switch between these
modes may occur at runtime (e.g. when the interface is wired to an SFP
cage). In such case, phylink will validate the newly selected interface
between the MAC and SFP based on the internal "supported_interfaces"
field.

For now in stmmac, this field is populated based on :
 - The interface specified in firmware (DT)
 - The interfaces supported by XPCS, when XPCS is in use.

In our case, the PCS in Lynx and not XPCS.

This commit makes so that the .pcs_init() implementation of
dwmac-socfpga populates the supported_interface when the Lynx PCS was
successfully initialized.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 8c7b82d29fd1..ff9a30afd7e1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -425,6 +425,17 @@ static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv)
 		return PTR_ERR(pcs);
 
 	priv->hw->phylink_pcs = pcs;
+
+	/* Having a Lynx PCS means we can use SGMII and 1000BaseX. Phylink's
+	 * supported_interface is populated according to what's found in
+	 * devicetree, but as we can dynamically switch between both modes at
+	 * runtime, make sure both modes are marked as supported
+	 */
+	__set_bit(PHY_INTERFACE_MODE_1000BASEX,
+		  priv->phylink_config.supported_interfaces);
+	__set_bit(PHY_INTERFACE_MODE_SGMII,
+		  priv->phylink_config.supported_interfaces);
+
 	return 0;
 }
 
-- 
2.47.1



From maxime.chevallier at bootlin.com  Fri Dec 13 01:05:23 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 13 Dec 2024 10:05:23 +0100
Subject: [PATCH net-next 0/2] net: stmmac: dwmac-socfpga: Allow using 1000BaseX
Message-ID: <20241213090526.71516-1-maxime.chevallier@bootlin.com>

Hello everyone,

This short series enables 1000BaseX support in dwmac-socfpga. The support
for this mode is coming from the Lync PCS, however some internal
configuration is also needed in dwmac-socfpga as well.

Patch 1 makes so that we enable the "sgmii_adapter" when using 1000BaseX
as well. The name is a bit misleading for that field, as this is merely
a GMII serializer, the 1000BaseX vs SGMII differences are handled in the
Lynx PCS.

Patch 2 makes so that both 1000BaseX and SGMII are set in the phylink
supported_interfaces. The supported_interfaces are populated by what's
set in DT, which isn't enough for SFP use-cases as the interface mode
will change based on the inserted module, thus failing the validation of
the new interface if it's not the one specified in DT.

When XPCS is used, the interfaces list if populated by asking XPCS for
its supported interfaces. I considered using the same kind of approach
(asking Lynx for the supported modes), but dwmac-socfpga would be the
sole user for that, and this would also need modifying Lynx so that the
driver would maintain different sets of capabilities depending on how
it's integrated (it only supports SGMII/1000BaseX in dwmac-socfpga, but
other modes are supported on other devices that use Lynx).

I've chosen to "just" populate the interfaces in .pcs_init() from
stmmac, which is called before phylink_create() so we should be good in
that regard.

Thanks,

Maxime

Maxime Chevallier (2):
  net: stmmac: dwmac-socfpga: Add support for 1000BaseX
  net: stmmac: dwmac-socfpga: Set interface modes from Lynx PCS as
    supported

 .../ethernet/stmicro/stmmac/dwmac-socfpga.c   | 20 +++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

-- 
2.47.1



From maxime.chevallier at bootlin.com  Fri Dec 13 01:05:24 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 13 Dec 2024 10:05:24 +0100
Subject: [PATCH net-next 1/2] net: stmmac: dwmac-socfpga: Add support for 1000BaseX
In-Reply-To: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
Message-ID: <20241213090526.71516-2-maxime.chevallier@bootlin.com>

The dwmac-socfpga found on altera socfpga SoCs can use 1000BaseX or
SGMII. The IP integrates a variation of the Lynx PCS, which the driver
supports well. However, there's some internal circuitry that needs
enabling when using SGMII or 1000BaseX through the "sgmii_adapter" in
the socfpga wrapper. So far, this is only enabled when SGMII is used as
the interface mode. Make so that 1000BaseX also enables that block.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 16020b72dec8..8c7b82d29fd1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -258,6 +258,7 @@ static int socfpga_set_phy_mode_common(int phymode, u32 *val)
 	case PHY_INTERFACE_MODE_MII:
 	case PHY_INTERFACE_MODE_GMII:
 	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_1000BASEX:
 		*val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
 		break;
 	case PHY_INTERFACE_MODE_RMII:
@@ -300,6 +301,7 @@ static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
 	if (dwmac->f2h_ptp_ref_clk ||
 	    phymode == PHY_INTERFACE_MODE_MII ||
 	    phymode == PHY_INTERFACE_MODE_GMII ||
+	    phymode == PHY_INTERFACE_MODE_1000BASEX ||
 	    phymode == PHY_INTERFACE_MODE_SGMII) {
 		regmap_read(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG,
 			    &module);
@@ -321,7 +323,8 @@ static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
 	 */
 	reset_control_deassert(dwmac->stmmac_ocp_rst);
 	reset_control_deassert(dwmac->stmmac_rst);
-	if (phymode == PHY_INTERFACE_MODE_SGMII)
+	if (phymode == PHY_INTERFACE_MODE_SGMII ||
+	    phymode == PHY_INTERFACE_MODE_1000BASEX)
 		socfpga_sgmii_config(dwmac, true);
 
 	return 0;
@@ -356,6 +359,7 @@ static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac)
 	if (dwmac->f2h_ptp_ref_clk ||
 	    phymode == PHY_INTERFACE_MODE_MII ||
 	    phymode == PHY_INTERFACE_MODE_GMII ||
+	    phymode == PHY_INTERFACE_MODE_1000BASEX ||
 	    phymode == PHY_INTERFACE_MODE_SGMII) {
 		ctrl |= SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK;
 		regmap_read(sys_mgr_base_addr, SYSMGR_FPGAINTF_EMAC_REG,
@@ -374,7 +378,8 @@ static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac)
 	 */
 	reset_control_deassert(dwmac->stmmac_ocp_rst);
 	reset_control_deassert(dwmac->stmmac_rst);
-	if (phymode == PHY_INTERFACE_MODE_SGMII)
+	if (phymode == PHY_INTERFACE_MODE_SGMII ||
+	    phymode == PHY_INTERFACE_MODE_1000BASEX)
 		socfpga_sgmii_config(dwmac, true);
 	return 0;
 }
-- 
2.47.1



From angelogioacchino.delregno at collabora.com  Fri Dec 13 01:12:42 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 13 Dec 2024 10:12:42 +0100
Subject: [PATCH] phy: mediatek: phy-mtk-hdmi: add regulator dependency
In-Reply-To: <20241213083056.2596499-1-arnd@kernel.org>
References: <20241213083056.2596499-1-arnd@kernel.org>
Message-ID: <7f2949bc-55ff-4d62-b310-6240f70a1673@collabora.com>

Il 13/12/24 09:30, Arnd Bergmann ha scritto:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> The driver no longer builds when regulator support is unavailable:
> 
> arm-linux-gnueabi-ld: drivers/phy/mediatek/phy-mtk-hdmi.o: in function `mtk_hdmi_phy_register_regulators':
> phy-mtk-hdmi.c:(.text.unlikely+0x3e): undefined reference to `devm_regulator_register'
> arm-linux-gnueabi-ld: drivers/phy/mediatek/phy-mtk-hdmi-mt8195.o: in function `mtk_hdmi_phy_pwr5v_is_enabled':
> phy-mtk-hdmi-mt8195.c:(.text+0x326): undefined reference to `rdev_get_drvdata'
> arm-linux-gnueabi-ld: drivers/phy/mediatek/phy-mtk-hdmi-mt8195.o: in function `mtk_hdmi_phy_pwr5v_disable':
> phy-mtk-hdmi-mt8195.c:(.text+0x346): undefined reference to `rdev_get_drvdata'
> arm-linux-gnueabi-ld: drivers/phy/mediatek/phy-mtk-hdmi-mt8195.o: in function `mtk_hdmi_phy_pwr5v_enable':
> 
> Fixes: 49393b2da1cd ("phy: mediatek: phy-mtk-hdmi: Register PHY provided regulator")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Sorry about the miss.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From richard.xnu.clark at gmail.com  Fri Dec 13 01:13:03 2024
From: richard.xnu.clark at gmail.com (Richard Clark)
Date: Fri, 13 Dec 2024 17:13:03 +0800
Subject: Question about interrupt prioriyt of ARM GICv3/4
In-Reply-To: <86ldwlryzz.wl-maz@kernel.org>
References: <CAJNi4rMfhZOCT+7Ki14vUs+dZbv9cxCZ0s+jgn6=_om4NTgo_A@mail.gmail.com>
 <86cyi5tanz.wl-maz@kernel.org>
 <CAJNi4rPDVXS3Ft3nHLXvMzHmn9d10Nz4Pxeduoe+v5HaK=CEAg@mail.gmail.com>
 <86ldwlryzz.wl-maz@kernel.org>
Message-ID: <Z1v6n6c6GB2_pFiR@MBC02GN1V4Q05P>

Hi M,

On Thu, Dec 12, 2024 at 10:12:32AM +0000, Marc Zyngier wrote:
> On Thu, 12 Dec 2024 09:18:56 +0000,
> richard clark <richard.xnu.clark at gmail.com> wrote:
> > 
> > Hi M,
> 
> Hi r,
> 
> > 
> > On Fri, Dec 6, 2024 at 5:37?PM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > On Fri, 06 Dec 2024 08:33:11 +0000,
> > > richard clark <richard.xnu.clark at gmail.com> wrote:
> > > >
> > > > Hi,
> > > > Currently seems the GICv3/4 irqchip configures all the interrupts as
> > > > the same priority, I am thinking about to minimize the latency of the
> > > > interrupt for a particular device, e.g, the arm arch_timer in the RTL
> > > > system. The question is,
> > > > 1. Why don't we provide a /proc or /sys interface for the enduser to
> > > > set the priority of a specific interrupt(SPI/PPI)?
> > >
> > > I'm afraid this really has nothing to do with any particular interrupt
> > > architecture.
> > >
> > > Before thinking of exposing the interrupt priority to userspace, you
> > > should look at what this translates into for the kernel once you allow
> > > interrupts to be preempted by another one with a higher priority.
> > >
> > Interrupt priority doesn't necessarily mean the preemption, seems
> > you're talking about the interrupt preemption harm according to your
> > statement followed.Frankly I am just thinking higher priority will win
> > the lower ones in case massive external interrupts received in the GIC
> > level (you see I am still talking about GIC, not kernel)
> 
> As I stated at the end of my email, the GIC only gives guarantee that
> you will ack the highest priority interrupt in finite time. Not right
> when it is made pending. Yes, it has the concept of HPPI. But that
> from the PoV of the CPU interface, not that of the distributor. Factor
> in the Stream interface, and you realise that expecting to always ack
> the highest priority pending interrupt is akin to expecting no
> reordering of packets in a network.
> 

I am trying to figure out a meticulous way to verify if the priority really work
or not, all we're here is talk abou like the 'technically', we'd show the
statistic data collected. Except that the stress-ng to stress massive interrupts
to the cpu0, another way I can see is a kmod to remote cross cpu call targeting
the cpu0 from other cpus. From the current data collected, I do see some gain of
latency, still it's not finalized yet. Be patient baby :)

> > >
> > > This means that at every point where you would normally see a
> > > local_irq_save(), spinlock_irqsave() or equivalent, you would need to
> > > explicitly specify the priority that you allow for preemption. You
> > > should then make sure that any code that can be run during an
> > > interrupt is reentrant. You need to define which data structures can
> > > be manipulated at which priority level... The list goes on.
> > >
> > irqsave just masks the interrupt from the point of cpu, I don't think
> > it will mess things up if preemption really happens (no? then what the
> > side-effect is for the nested interrupt handling in the softirq part.
> > damage the semantic of the lock primitives?)
> > >
> > > If you want a small taste of the complexity, just look at what
> > > handling NMIs (or even pseudo-NMIs in the case of GICv3) means, and
> > > generalise it to not just two, but an arbitrary range of priorities.
> > >
> > > If you want the full blown experience, look at the BSDs and their use
> > > of spl*(). I don't think anyone has any plan to get there, and the RT
> > > patches have shown that there is little need for it.
> > >
> > As supplement?the fiq is suggested to be used as an alternative to the
> > higher priority in the RT area...
> 
> <PulpFiction>
> FIQ's dead, baby. FIQ's dead.
> </PulpFiction>
> 

As an advice too...

> > >
> > > > 2. Is there any way to verify the higher priority interrupt will have
> > > > more dominant to be selected to the CPU (IOW, the priority is really
> > > > working) in case of multiple different interrupts asserted to the GIC
> > > > at the same time(some debug registers of GIC like GICD_REEMPT_CNT :-)
> > > > to record higher priority wins)?
> > >
> > > The GIC architecture makes no promise that the interrupt you
> > > acknowledge is the highest priority pending interrupt, because this is
> > > by definition a very racy process.
> > >
> > > Also, even on busy systems, you will very rarely see two interrupts
> > > targeting the same CPU being made pending at the same time, so that
> > > the interrupt delivery system would have to arbitrate between the two.
> > > That's because interrupts are vanishingly rare in the grand scheme of
> > > things.
> > >
> > 1. I am trying to stress the external interrupts to the core#0 via the
> > stress-ng tool with one of interrupt being configured as higher
> > priority to see the benchmark data, it's time consuming as you can
> > image, still is in progress(BTW, I can't see any lockup similar hang
> > in the system with a higher priority configured)
> 
> If you don't have preemption, I don't think anything wrong will
> happen. But I don't expect any benefit either.
>

As a said before in this eamil, real statistic data is needed as evaluation,
WIP through now.

> 
> > 2. This raises a very interesting question and I am also very curious
> > about is, what is the purpose for the GIC to introduce the interrupt
> > priority features, a placeholder feature reserved for the future? Ah,
> > hardware prefer to provide more functionalities than its being
> > actually used by software, any other justification except that?
> 
> You realise that the HW is not exclusively designed for Linux, right?
> 
I realize, but it will be better if you can point is there any other OS
kernels make use of these interrupt priority of GIC but Linux, if no then
what the rational is for GIC to support these priority features...

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


From linux at armlinux.org.uk  Fri Dec 13 01:11:57 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 09:11:57 +0000
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <CACRpkdbYU=Txm0zUWDWvNXA0JHRNGpy1ccy0zQdiBb2Ya+UBFA@mail.gmail.com>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-3-arnd@kernel.org>
 <CACRpkdZaoD2vqbCi1AFUa6mF2_=c3Nu4R0CvxFAep0VMgtMtOQ@mail.gmail.com>
 <20241211152257.Igx3aT2Y@linutronix.de>
 <CACRpkdbYU=Txm0zUWDWvNXA0JHRNGpy1ccy0zQdiBb2Ya+UBFA@mail.gmail.com>
Message-ID: <Z1v6XcaSK97Sa9Tz@shell.armlinux.org.uk>

On Fri, Dec 13, 2024 at 01:27:00AM +0100, Linus Walleij wrote:
> On Wed, Dec 11, 2024 at 4:22?PM Sebastian Andrzej Siewior
> <bigeasy at linutronix.de> wrote:
> > On 2024-12-11 14:29:29 [+0100], Linus Walleij wrote:
> > > So fast GUP is supposed to be lockless, and should just not
> > > have this problem. So it can't be addressing gup_fast_pgd_range()
> > > right?
> > ?
> > > I'm more asking if HIGHPTE even acquires a spinlock anymore
> > > as it is supposed to be "fast"/lockless. If it does, it is clearly violating
> > > the "fast" promise of the fast GUP API and should not exist.
> >
> > This is lockless on x86. The problem is ARM's
> > arch_kmap_local_high_get(). This is where the lock is from.
> 
> Aha that calls down to kmap_high_get() that that issues
> lock_kmap_any(flags).
> 
> But is it really sound that the "fast" API does this? It feels
> like a violation of the whole design of the fast stuff.

If there's no way to do it lockless, then it has to take the lock.

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


From krzk at kernel.org  Fri Dec 13 01:10:54 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 10:10:54 +0100
Subject: [PATCH v3 1/6] dt-bindings: interrupt-controller: Refine
 size/interrupt-cell usage.
In-Reply-To: <20241212155237.848336-3-kevin_chen@aspeedtech.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-3-kevin_chen@aspeedtech.com>
Message-ID: <k7jftzlih6ss4yaxrv7r4dudhcu43iyu2qvkl2thb5wiaszto7@evzmwfxxzzt6>

On Thu, Dec 12, 2024 at 11:52:31PM +0800, Kevin Chen wrote:
> 1. Because size-cells is no need to use 2, modify to 1 for use.
> 2. Add minItems to 1 for interrupts for intc1.
> 3. Add 1 interrupt of intc1 example into yaml file.
> 4. Add intc1 sub-module of uart12 as example using the intc0 and intc1.
> ---
>  .../aspeed,ast2700-intc.yaml                  | 60 +++++++++++++++----
>  1 file changed, 47 insertions(+), 13 deletions(-)
> 

As with all your patches, repeating since v1 the same comment, so one
more last time:

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

Best regards,
Krzysztof



From ming.qian at oss.nxp.com  Fri Dec 13 01:10:30 2024
From: ming.qian at oss.nxp.com (Ming Qian)
Date: Fri, 13 Dec 2024 18:10:30 +0900
Subject: [PATCH v2] media: amphion: Support dmabuf and v4l2 buffer without binding
Message-ID: <20241213091030.2936864-1-ming.qian@oss.nxp.com>

From: Ming Qian <ming.qian at nxp.com>

When using VB2_DMABUF, the relationship between dma-buf and v4l2 buffer
may not one-to-one, a single dma-buf may be queued via different
v4l2 buffers, and different dma-bufs may be queued via the same
v4l2 buffer, so it's not appropriate to use the v4l2 buffer index
as the frame store id.

We can generate a frame store id according to the dma address.
Then for a given dma-buf, the id is fixed.

Driver now manages the frame store and vb2-buffer states independently.

When a dmabuf is queued via another v4l2 buffer before the buffer is
released by firmware, need to pend it until firmware release it.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
---
v2
-- fix an uninitialized issue reported by media-ci

 drivers/media/platform/amphion/vdec.c     | 232 ++++++++++++++++++----
 drivers/media/platform/amphion/vpu.h      |   7 +-
 drivers/media/platform/amphion/vpu_dbg.c  |  15 +-
 drivers/media/platform/amphion/vpu_v4l2.c |  11 +
 4 files changed, 218 insertions(+), 47 deletions(-)

diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
index 61d5598ee6a1..a26cb0c264c9 100644
--- a/drivers/media/platform/amphion/vdec.c
+++ b/drivers/media/platform/amphion/vdec.c
@@ -26,6 +26,7 @@
 #include "vpu_cmds.h"
 #include "vpu_rpc.h"
 
+#define VDEC_SLOT_CNT_DFT		32
 #define VDEC_MIN_BUFFER_CAP		8
 #define VDEC_MIN_BUFFER_OUT		8
 
@@ -41,6 +42,14 @@ struct vdec_fs_info {
 	u32 tag;
 };
 
+struct vdec_frame_store_t {
+	struct vpu_vb2_buffer *curr;
+	struct vpu_vb2_buffer *pend;
+	dma_addr_t addr;
+	unsigned int state;
+	u32 tag;
+};
+
 struct vdec_t {
 	u32 seq_hdr_found;
 	struct vpu_buffer udata;
@@ -48,7 +57,8 @@ struct vdec_t {
 	struct vpu_dec_codec_info codec_info;
 	enum vpu_codec_state state;
 
-	struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];
+	struct vdec_frame_store_t *slots;
+	u32 slot_count;
 	u32 req_frame_count;
 	struct vdec_fs_info mbi;
 	struct vdec_fs_info dcp;
@@ -289,6 +299,64 @@ static int vdec_ctrl_init(struct vpu_inst *inst)
 	return 0;
 }
 
+static void vdec_attach_frame_store(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+	struct vdec_t *vdec = inst->priv;
+	struct vdec_frame_store_t *new_slots = NULL;
+	dma_addr_t addr;
+	int i;
+
+	addr = vpu_get_vb_phy_addr(vb, 0);
+	for (i = 0; i < vdec->slot_count; i++) {
+		if (addr == vdec->slots[i].addr) {
+			if (vdec->slots[i].curr && vdec->slots[i].curr != vpu_buf) {
+				vpu_set_buffer_state(vbuf, VPU_BUF_STATE_CHANGED);
+				vdec->slots[i].pend = vpu_buf;
+			} else {
+				vpu_set_buffer_state(vbuf, vdec->slots[i].state);
+			}
+			vpu_buf->fs_id = i;
+			return;
+		}
+	}
+
+	for (i = 0; i < vdec->slot_count; i++) {
+		if (!vdec->slots[i].addr) {
+			vdec->slots[i].addr = addr;
+			vpu_buf->fs_id = i;
+			return;
+		}
+	}
+
+	new_slots = vzalloc(sizeof(*vdec->slots) * vdec->slot_count * 2);
+	if (!vdec->slots) {
+		dev_err(inst->dev, "fail to alloc frame store\n");
+		vpu_set_buffer_state(vbuf, VPU_BUF_STATE_ERROR);
+		return;
+	}
+
+	memcpy(new_slots, vdec->slots, sizeof(*vdec->slots) * vdec->slot_count);
+	vfree(vdec->slots);
+	vdec->slots = new_slots;
+	vdec->slot_count *= 2;
+
+	vdec->slots[i].addr = addr;
+	vpu_buf->fs_id = i;
+}
+
+static void vdec_reset_frame_store(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!vdec->slots || !vdec->slot_count)
+		return;
+
+	vpu_trace(inst->dev, "inst[%d] reset slots\n", inst->id);
+	memset(vdec->slots, 0, sizeof(*vdec->slots) * vdec->slot_count);
+}
+
 static void vdec_handle_resolution_change(struct vpu_inst *inst)
 {
 	struct vdec_t *vdec = inst->priv;
@@ -745,11 +813,11 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
 	struct vb2_v4l2_buffer *src_buf;
 	int ret = 0;
 
-	if (!info || info->id >= ARRAY_SIZE(vdec->slots))
+	if (!info || info->id >= vdec->slot_count)
 		return -EINVAL;
 
 	vpu_inst_lock(inst);
-	vpu_buf = vdec->slots[info->id];
+	vpu_buf = vdec->slots[info->id].curr;
 	if (!vpu_buf) {
 		dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id);
 		ret = -EINVAL;
@@ -770,11 +838,13 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
 	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)
 		dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
 	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
+	vdec->slots[info->id].state = VPU_BUF_STATE_DECODED;
 	vdec->decoded_frame_count++;
 	if (vdec->params.display_delay_enable) {
 		struct vpu_format *cur_fmt;
 
 		cur_fmt = vpu_get_format(inst, inst->cap_format.type);
+		vdec->slots[info->id].state = VPU_BUF_STATE_READY;
 		vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
 		for (int i = 0; i < vbuf->vb2_buf.num_planes; i++)
 			vb2_set_plane_payload(&vbuf->vb2_buf,
@@ -797,11 +867,11 @@ static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma)
 	struct vdec_t *vdec = inst->priv;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
-		if (!vdec->slots[i])
+	for (i = 0; i < vdec->slot_count; i++) {
+		if (!vdec->slots[i].curr)
 			continue;
-		if (luma == vdec->slots[i]->luma)
-			return vdec->slots[i];
+		if (luma == vdec->slots[i].addr)
+			return vdec->slots[i].curr;
 	}
 
 	return NULL;
@@ -835,11 +905,11 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
 
 	cur_fmt = vpu_get_format(inst, inst->cap_format.type);
 	vbuf = &vpu_buf->m2m_buf.vb;
-	if (vbuf->vb2_buf.index != frame->id)
-		dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n",
-			inst->id, vbuf->vb2_buf.index, frame->id);
+	if (vpu_buf->fs_id != frame->id)
+		dev_err(inst->dev, "[%d] buffer id(%d(%d), %d) dismatch\n",
+			inst->id, vpu_buf->fs_id, vbuf->vb2_buf.index, frame->id);
 
-	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_READY && vdec->params.display_delay_enable)
+	if (vdec->params.display_delay_enable)
 		return;
 
 	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED)
@@ -852,10 +922,11 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
 	vbuf->sequence = vdec->sequence;
 	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
 
-	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
 	vpu_inst_lock(inst);
+	vdec->slots[vpu_buf->fs_id].state = VPU_BUF_STATE_READY;
 	vdec->display_frame_count++;
 	vpu_inst_unlock(inst);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
 	dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n",
 		inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence);
 }
@@ -1083,18 +1154,30 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb
 	if (!vbuf)
 		return -EINVAL;
 
-	if (vdec->slots[vbuf->vb2_buf.index]) {
-		dev_err(inst->dev, "[%d] repeat alloc fs %d\n",
-			inst->id, vbuf->vb2_buf.index);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	if (vpu_buf->fs_id < 0 || vpu_buf->fs_id >= vdec->slot_count) {
+		dev_err(inst->dev, "invalid fs %d for v4l2 buffer %d\n",
+			vpu_buf->fs_id, vbuf->vb2_buf.index);
 		return -EINVAL;
 	}
 
+	if (vdec->slots[vpu_buf->fs_id].curr) {
+		if (vdec->slots[vpu_buf->fs_id].curr != vpu_buf) {
+			vpu_set_buffer_state(vbuf, VPU_BUF_STATE_CHANGED);
+			vdec->slots[vpu_buf->fs_id].pend = vpu_buf;
+		} else {
+			vpu_set_buffer_state(vbuf, vdec->slots[vpu_buf->fs_id].state);
+		}
+		dev_err(inst->dev, "[%d] repeat alloc fs %d (v4l2 index %d)\n",
+			inst->id, vpu_buf->fs_id, vbuf->vb2_buf.index);
+		return -EAGAIN;
+	}
+
 	dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n",
 		inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag);
-	vpu_buf = to_vpu_vb2_buffer(vbuf);
 
 	memset(&info, 0, sizeof(info));
-	info.id = vbuf->vb2_buf.index;
+	info.id = vpu_buf->fs_id;
 	info.type = MEM_RES_FRAME;
 	info.tag = vdec->seq_tag;
 	info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);
@@ -1109,12 +1192,13 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb
 	if (ret)
 		return ret;
 
-	vpu_buf->tag = info.tag;
 	vpu_buf->luma = info.luma_addr;
 	vpu_buf->chroma_u = info.chroma_addr;
 	vpu_buf->chroma_v = 0;
 	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
-	vdec->slots[info.id] = vpu_buf;
+	vdec->slots[info.id].tag = info.tag;
+	vdec->slots[info.id].curr = vpu_buf;
+	vdec->slots[info.id].state = VPU_BUF_STATE_INUSE;
 	vdec->req_frame_count--;
 
 	return 0;
@@ -1175,25 +1259,47 @@ static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *v
 	v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
 }
 
-static void vdec_clear_slots(struct vpu_inst *inst)
+static void vdec_release_curr_frame_store(struct vpu_inst *inst, u32 id)
 {
 	struct vdec_t *vdec = inst->priv;
 	struct vpu_vb2_buffer *vpu_buf;
 	struct vb2_v4l2_buffer *vbuf;
+
+	if (id >= vdec->slot_count)
+		return;
+	if (!vdec->slots[id].curr)
+		return;
+
+	vpu_buf = vdec->slots[id].curr;
+	vbuf = &vpu_buf->m2m_buf.vb;
+
+	vdec_response_fs_release(inst, id, vdec->slots[id].tag);
+	if (vpu_buf->fs_id == id) {
+		if (vpu_buf->state != VPU_BUF_STATE_READY)
+			vdec_recycle_buffer(inst, vbuf);
+		vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	}
+
+	vdec->slots[id].curr = NULL;
+	vdec->slots[id].state = VPU_BUF_STATE_IDLE;
+
+	if (vdec->slots[id].pend) {
+		vpu_set_buffer_state(&vdec->slots[id].pend->m2m_buf.vb, VPU_BUF_STATE_IDLE);
+		vdec->slots[id].pend = NULL;
+	}
+}
+
+static void vdec_clear_slots(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
-		if (!vdec->slots[i])
+	for (i = 0; i < vdec->slot_count; i++) {
+		if (!vdec->slots[i].curr)
 			continue;
 
-		vpu_buf = vdec->slots[i];
-		vbuf = &vpu_buf->m2m_buf.vb;
-
 		vpu_trace(inst->dev, "clear slot %d\n", i);
-		vdec_response_fs_release(inst, i, vpu_buf->tag);
-		vdec_recycle_buffer(inst, vbuf);
-		vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
-		vdec->slots[i] = NULL;
+		vdec_release_curr_frame_store(inst, i);
 	}
 }
 
@@ -1324,39 +1430,29 @@ static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
 static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
 {
 	struct vdec_t *vdec = inst->priv;
-	struct vpu_vb2_buffer *vpu_buf;
-	struct vb2_v4l2_buffer *vbuf;
 
-	if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))
+	if (!fs || fs->id >= vdec->slot_count)
 		return;
 	if (fs->type != MEM_RES_FRAME)
 		return;
 
-	if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {
+	if (fs->id >= vdec->slot_count) {
 		dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id);
 		return;
 	}
 
 	vpu_inst_lock(inst);
-	vpu_buf = vdec->slots[fs->id];
-	vdec->slots[fs->id] = NULL;
-
-	if (!vpu_buf) {
+	if (!vdec->slots[fs->id].curr) {
 		dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id);
 		goto exit;
 	}
 
-	vbuf = &vpu_buf->m2m_buf.vb;
-	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED) {
+	if (vdec->slots[fs->id].state == VPU_BUF_STATE_DECODED) {
 		dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
 		vdec->sequence++;
 	}
 
-	vdec_response_fs_release(inst, fs->id, vpu_buf->tag);
-	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_READY)
-		vdec_recycle_buffer(inst, vbuf);
-
-	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	vdec_release_curr_frame_store(inst, fs->id);
 	vpu_process_capture_buffer(inst);
 
 exit:
@@ -1552,6 +1648,11 @@ static void vdec_cleanup(struct vpu_inst *inst)
 		return;
 
 	vdec = inst->priv;
+	if (vdec) {
+		vfree(vdec->slots);
+		vdec->slots = NULL;
+		vdec->slot_count = 0;
+	}
 	vfree(vdec);
 	inst->priv = NULL;
 	vfree(inst);
@@ -1683,6 +1784,38 @@ static int vdec_stop_session(struct vpu_inst *inst, u32 type)
 	return 0;
 }
 
+static int vdec_get_slot_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	int num = -1;
+
+	vpu_inst_lock(inst);
+	if (i >= vdec->slot_count || !vdec->slots[i].addr)
+		goto exit;
+
+	vpu_buf = vdec->slots[i].curr;
+
+	num = scnprintf(str, size, "slot[%2d] :", i);
+	if (vpu_buf) {
+		num += scnprintf(str + num, size - num, " %2d",
+				 vpu_buf->m2m_buf.vb.vb2_buf.index);
+		num += scnprintf(str + num, size - num, "; state = %d", vdec->slots[i].state);
+	} else {
+		num += scnprintf(str + num, size - num, " -1");
+	}
+
+	if (vdec->slots[i].pend)
+		num += scnprintf(str + num, size - num, "; %d",
+				 vdec->slots[i].pend->m2m_buf.vb.vb2_buf.index);
+
+	num += scnprintf(str + num, size - num, "\n");
+exit:
+	vpu_inst_unlock(inst);
+
+	return num;
+}
+
 static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
 {
 	struct vdec_t *vdec = inst->priv;
@@ -1741,6 +1874,7 @@ static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i
 				vdec->codec_info.vui_present);
 		break;
 	default:
+		num = vdec_get_slot_debug_info(inst, str, size, i - 10);
 		break;
 	}
 
@@ -1764,6 +1898,8 @@ static struct vpu_inst_ops vdec_inst_ops = {
 	.get_debug_info = vdec_get_debug_info,
 	.wait_prepare = vpu_inst_unlock,
 	.wait_finish = vpu_inst_lock,
+	.attach_frame_store = vdec_attach_frame_store,
+	.reset_frame_store = vdec_reset_frame_store,
 };
 
 static void vdec_init(struct file *file)
@@ -1804,6 +1940,14 @@ static int vdec_open(struct file *file)
 		return -ENOMEM;
 	}
 
+	vdec->slots = vzalloc(sizeof(*vdec->slots) * VDEC_SLOT_CNT_DFT);
+	if (!vdec->slots) {
+		vfree(vdec);
+		vfree(inst);
+		return -ENOMEM;
+	}
+	vdec->slot_count = VDEC_SLOT_CNT_DFT;
+
 	inst->ops = &vdec_inst_ops;
 	inst->formats = vdec_formats;
 	inst->type = VPU_CORE_TYPE_DEC;
diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
index 22f0da26ccec..76bfd6b26170 100644
--- a/drivers/media/platform/amphion/vpu.h
+++ b/drivers/media/platform/amphion/vpu.h
@@ -223,6 +223,8 @@ struct vpu_inst_ops {
 	int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i);
 	void (*wait_prepare)(struct vpu_inst *inst);
 	void (*wait_finish)(struct vpu_inst *inst);
+	void (*attach_frame_store)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	void (*reset_frame_store)(struct vpu_inst *inst);
 };
 
 struct vpu_inst {
@@ -296,7 +298,8 @@ enum {
 	VPU_BUF_STATE_DECODED,
 	VPU_BUF_STATE_READY,
 	VPU_BUF_STATE_SKIP,
-	VPU_BUF_STATE_ERROR
+	VPU_BUF_STATE_ERROR,
+	VPU_BUF_STATE_CHANGED
 };
 
 struct vpu_vb2_buffer {
@@ -305,8 +308,8 @@ struct vpu_vb2_buffer {
 	dma_addr_t chroma_u;
 	dma_addr_t chroma_v;
 	unsigned int state;
-	u32 tag;
 	u32 average_qp;
+	s32 fs_id;
 };
 
 void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val);
diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c
index 940e5bda5fa3..497ae4e8a229 100644
--- a/drivers/media/platform/amphion/vpu_dbg.c
+++ b/drivers/media/platform/amphion/vpu_dbg.c
@@ -48,6 +48,7 @@ static char *vpu_stat_name[] = {
 	[VPU_BUF_STATE_READY] = "ready",
 	[VPU_BUF_STATE_SKIP] = "skip",
 	[VPU_BUF_STATE_ERROR] = "error",
+	[VPU_BUF_STATE_CHANGED] = "changed",
 };
 
 static inline const char *to_vpu_stat_name(int state)
@@ -164,6 +165,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data)
 	for (i = 0; i < vb2_get_num_buffers(vq); i++) {
 		struct vb2_buffer *vb;
 		struct vb2_v4l2_buffer *vbuf;
+		struct vpu_vb2_buffer *vpu_buf;
 
 		vb = vb2_get_buffer(vq, i);
 		if (!vb)
@@ -173,13 +175,24 @@ static int vpu_dbg_instance(struct seq_file *s, void *data)
 			continue;
 
 		vbuf = to_vb2_v4l2_buffer(vb);
+		vpu_buf = to_vpu_vb2_buffer(vbuf);
 
 		num = scnprintf(str, sizeof(str),
-				"capture[%2d] state = %10s, %8s\n",
+				"capture[%2d] state = %10s, %8s",
 				i, vb2_stat_name[vb->state],
 				to_vpu_stat_name(vpu_get_buffer_state(vbuf)));
 		if (seq_write(s, str, num))
 			return 0;
+
+		if (vpu_buf->fs_id >= 0) {
+			num = scnprintf(str, sizeof(str), "; fs %d", vpu_buf->fs_id);
+			if (seq_write(s, str, num))
+				return 0;
+		}
+
+		num = scnprintf(str, sizeof(str), "\n");
+		if (seq_write(s, str, num))
+			return 0;
 	}
 
 	num = scnprintf(str, sizeof(str), "sequence = %d\n", inst->sequence);
diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
index 45707931bc4f..74668fa362e2 100644
--- a/drivers/media/platform/amphion/vpu_v4l2.c
+++ b/drivers/media/platform/amphion/vpu_v4l2.c
@@ -501,14 +501,25 @@ static int vpu_vb2_queue_setup(struct vb2_queue *vq,
 		call_void_vop(inst, release);
 	}
 
+	if (V4L2_TYPE_IS_CAPTURE(vq->type))
+		call_void_vop(inst, reset_frame_store);
+
 	return 0;
 }
 
 static int vpu_vb2_buf_init(struct vb2_buffer *vb)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
 
+	vpu_buf->fs_id = -1;
 	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+
+	if (!inst->ops->attach_frame_store || V4L2_TYPE_IS_OUTPUT(vb->type))
+		return 0;
+
+	call_void_vop(inst, attach_frame_store, vb);
 	return 0;
 }
 
-- 
2.43.0-rc1



From kevin.brodsky at arm.com  Fri Dec 13 01:15:15 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri, 13 Dec 2024 10:15:15 +0100
Subject: [PATCH v2] arm64: signal: Ensure signal delivery failure is
 recoverable
In-Reply-To: <Z1siulo_PKdI3xC_@arm.com>
References: <20241210160940.2031997-1-kevin.brodsky@arm.com>
 <5db7f7a0-1d3c-4bbd-ad2b-124bf54f49ef@sirena.org.uk>
 <Z1sY9tIsAZ84W93-@arm.com>
 <a70cd007-a2c8-477f-972e-fa1e9c362604@sirena.org.uk>
 <Z1siulo_PKdI3xC_@arm.com>
Message-ID: <b2b0f73e-ba2b-4402-afa6-4960814ea1fd@arm.com>

On 12/12/2024 18:51, Catalin Marinas wrote:
> On Thu, Dec 12, 2024 at 05:26:47PM +0000, Mark Brown wrote:
>> On Thu, Dec 12, 2024 at 05:10:14PM +0000, Catalin Marinas wrote:
>>> On Thu, Dec 12, 2024 at 04:47:46PM +0000, Mark Brown wrote:
>>>>> Fixes: eaf62ce1563b ("arm64/signal: Set up and restore the GCS context for signal handlers")
>>>> Presumably we also need a Fixes for whatever introduced the above copy.
>>> Hmm, it was like this from the beginning. If we are to do a cc stable to
>>> the oldest maintained LTS, I'd rather have a separate patch for
>>> copy_siginfo_to_user(), it doesn't make much sense to backport a GCS
>>> patch to early kernels.
>> Hrm, good point about it triggering backports.  I'm not sure it's worth
>> doing that TBH.
> I had the same thoughts. I think this was mostly triggered by the
> POR_EL0 changes when Will raised the point that the kernel might return
> with a more privileged value in this sysreg.

I don't think backporting would be worth it either, referencing the
original commit implementing signal support felt like overkill. The
copy_siginfo_to_user() issue is such a corner case that I doubt anyone
ever ran into it.

- Kevin


From krzk at kernel.org  Fri Dec 13 01:18:12 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 10:18:12 +0100
Subject: [PATCH v3 1/7] dt-bindings: display: bcm2711-hdmi: Add interrupt
 details for BCM2712
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-1-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
 <20241212-dt-bcm2712-fixes-v3-1-44a7f3390331@raspberrypi.com>
Message-ID: <cjf4n2tg5qcqpik3j6ufesl4lf2fftyccrqmurb2xvib6iyt2d@fbhkwoiwfjuy>

On Thu, Dec 12, 2024 at 06:36:28PM +0000, Dave Stevenson wrote:
> Commit 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
> added the compatible strings for BCM2712, but missed out that the
> number of interrupts changed.
> 
> Update the schema to include the interrupt requirements.
> 
> Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  .../bindings/display/brcm,bcm2711-hdmi.yaml        | 107 ++++++++++++++++++---
>  1 file changed, 93 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> index 6d11f5955b51..dd7dea60183b 100644
> --- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> @@ -56,22 +56,38 @@ properties:
>        - const: cec
>  
>    interrupts:

> -    items:
> -      - description: CEC TX interrupt
> -      - description: CEC RX interrupt
> -      - description: CEC stuck at low interrupt
> -      - description: Wake-up interrupt
> -      - description: Hotplug connected interrupt
> -      - description: Hotplug removed interrupt
> +    oneOf:
> +      - items:
> +          - description: CEC TX interrupt
> +          - description: CEC RX interrupt
> +          - description: CEC stuck at low interrupt
> +          - description: Wake-up interrupt
> +          - description: Hotplug connected interrupt
> +          - description: Hotplug removed interrupt
> +
> +      - items:
> +          - description: CEC TX interrupt
> +          - description: CEC RX interrupt
> +          - description: CEC stuck at low interrupt
> +          - description: Hotplug connected interrupt
> +          - description: Hotplug removed interrupt

You have chosen unusual syntax. There are no bindings doing this way, so
I really do not get which file you used as template.

Expected here are minItems and maxItems. These are the widest
constraints. Otherwise you are repeating the same in allOf:if:then. And
then the allOf:if:then: defines the items.

You can do the opposite - define the items here then just choose
constraints in if:then:. Less popular if you have list without common
part (so no minItems here), but sure, if you insist... yet you chosen
some third way of duplicating it in both places.

Look:
https://elixir.bootlin.com/linux/v6.11-rc6/source/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml#L127
https://elixir.bootlin.com/linux/v6.11-rc6/source/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml#L39
https://elixir.bootlin.com/linux/v5.19/source/Documentation/devicetree/bindings/example-schema.yaml#L91

There is nowhere syntax like here, with duplicating everything twice.

BTW, drop the full stop from your subjects in some other patches.
Subject never ends with full stop.


Best regards,
Krzysztof



From quic_yuanfang at quicinc.com  Fri Dec 13 01:18:14 2024
From: quic_yuanfang at quicinc.com (Yuanfang Zhang)
Date: Fri, 13 Dec 2024 17:18:14 +0800
Subject: [PATCH v2] coresight-etm4x: add isb() before reading the TRCSTATR
In-Reply-To: <20241204151650.GA1976757@e132581.arm.com>
References: <20241204112332.3706137-1-quic_yuanfang@quicinc.com>
 <20241204151650.GA1976757@e132581.arm.com>
Message-ID: <1e99294f-b528-4cf7-a0e0-3d78221e6982@quicinc.com>



On 12/4/2024 11:16 PM, Leo Yan wrote:
> Hi Yuanfang,
> 
> Recently I just acrossed this part, so some comments.
> 
> On Wed, Dec 04, 2024 at 07:23:32PM +0800, yuanfang zhang wrote:
>>
>> From: Yuanfang Zhang <quic_yuanfang at quicinc.com>
>>
>> As recommended by section 4.3.7 ("Synchronization when using system
>> instructions to progrom the trace unit") of ARM IHI 0064H.b, the
>> self-hosted trace analyzer must perform a Context synchronization
>> event between writing to the TRCPRGCTLR and reading the TRCSTATR.
>>
>> Fixes: ebddaad09e10 ("coresight: etm4x: Add missing single-shot control API to sysfs")
>> Signed-off-by: Yuanfang Zhang <quic_yuanfang at quicinc.com>
>> ---
>> Change in V2:
>> Added comments in the code.
>>  drivers/hwtracing/coresight/coresight-etm4x-core.c | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index 66d44a404ad0..decb3a87e27e 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -906,6 +906,13 @@ static void etm4_disable_hw(void *info)
>>         tsb_csync();
>>         etm4x_relaxed_write32(csa, control, TRCPRGCTLR);
>>
>> +       /*
>> +        * As recommended by section 4.3.7 ("Synchronization when using system
>> +        * instructions to progrom the trace unit") of ARM IHI 0064H.b, the
>> +        * self-hosted trace analyzer must perform a Context synchronization
>> +        * event between writing to the TRCPRGCTLR and reading the TRCSTATR.
>> +        */
>> +       isb();
> 
> As described in the doc, the "isb" is only required for system
> instructions case.  It is good to only apply the ISB on system
> register case:
> 
>         if (!csa->io_mem)
>                 isb();
> 

updated in PATCH V3.

>>         /* wait for TRCSTATR.PMSTABLE to go to '1' */
>>         if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1))
>>                 dev_err(etm_dev,
> 
> As mentioned in system register case: "Arm recommends that the
> self-hosted trace analyzer always executes an ISB instruction after
> programming the trace unit registers, to ensure that all updates are
> committed to the trace unit before normal code execution resumes."
> 
> And for MMIO case:
> 
> "When the memory is marked as Device-nGnRE or stronger.
>  ...
>  - Poll TRCSTATR to ensure the previous write has completed.
>  ? Execute an ISB operation."
> 
> Thus we need to add an ISB after polling.
> 
>         isb();
> 

updated in PATCH V3.

> For consistent behaviour, a relevant thing is the dsb(sy) in
> etm4_enable_hw().  I do not think the dsb(sy) is necessary, as the
> driver uses the sequence "write TRCPRGCTLR + polling TRCSTATR" to
> ensure the data has been populated to trace unit, the polling
> operations somehow act as a read back.  And the ETM manual does not
> mention the requirement for DSB when enabling trace unit.  Thus, we
> should remove dsb(sy) (maybe use a separte patch).
> 

updated in PATCH V3.

> Mike / Suzuki / James, please confirm if my conclusions are valid.
> 
> Thanks,
> Leo



From krzk at kernel.org  Fri Dec 13 01:19:48 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 10:19:48 +0100
Subject: [PATCH v3 2/7] dt-bindings: display: Fix BCM2835 HVS bindings
 for BCM2712
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-2-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
 <20241212-dt-bcm2712-fixes-v3-2-44a7f3390331@raspberrypi.com>
Message-ID: <yz2wl72uagxbwbqnvfrspwy2bgrrljzg7b5zwqcg6llajybnfv@hugmruxvngxr>

On Thu, Dec 12, 2024 at 06:36:29PM +0000, Dave Stevenson wrote:
> Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> added the compatible string for BCM2712, but missed out that
> the number of interrupts and clocks changed too.
> 
> Update to validate clock and interrupts for the variants.
> 
> Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  .../bindings/display/brcm,bcm2835-hvs.yaml         | 83 ++++++++++++++++++----
>  1 file changed, 69 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> index f91c9dce2a44..36bf8eec88a6 100644
> --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> @@ -20,11 +20,20 @@ properties:
>      maxItems: 1
>  
>    interrupts:
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 3
> +
> +  interrupt-names:
> +    minItems: 1
> +    maxItems: 3
>  
>    clocks:
> -    maxItems: 1
> -    description: Core Clock
> +    minItems: 1
> +    maxItems: 2
> +
> +  clock-names:
> +    minItems: 1
> +    maxItems: 2
>  
>  required:
>    - compatible
> @@ -33,17 +42,63 @@ required:
>  
>  additionalProperties: false
>  
> -if:
> -  properties:
> -    compatible:
> -      contains:
> -        enum:
> -          - brcm,bcm2711-hvs
> -          - brcm,bcm2712-hvs
> -
> -then:
> -  required:
> -    - clocks
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: brcm,bcm2711-hvs
> +
> +    then:
> +      properties:
> +        clocks:
> +          items:
> +            - description: Core Clock
> +        interrupts:
> +          maxItems: 1
> +
> +      required:
> +        - clocks
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: brcm,bcm2712-hvs
> +
> +    then:
> +      properties:
> +        clocks:

minItems: 2

> +          maxItems: 2
> +        clock-names:
> +          items:
> +            - const: core
> +            - const: disp
> +        interrupts:
> +          items:
> +            - description: Channel 0 End of frame
> +            - description: Channel 1 End of frame
> +            - description: Channel 2 End of frame
> +        interrupt-names:
> +          items:
> +            - const: ch0-eof
> +            - const: ch1-eof
> +            - const: ch2-eof
> +      required:
> +        - clocks
> +        - clock-names
> +        - interrupt-names

Why requiring last two names? Commit msg does not explain that.

Best regards,
Krzysztof



From krzk at kernel.org  Fri Dec 13 01:20:21 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 10:20:21 +0100
Subject: [PATCH v3 4/7] dt-bindings: interrupt-controller:
 brcm,bcm2836-l1-intc: Drop interrupt-controller requirement
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-4-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
 <20241212-dt-bcm2712-fixes-v3-4-44a7f3390331@raspberrypi.com>
Message-ID: <n2ib4ofkijx36hak54i2vv5y5gh6pycsicnvjx4bzinsfoxr4l@ipefwfyxrpqa>

On Thu, Dec 12, 2024 at 06:36:31PM +0000, Dave Stevenson wrote:
> Since commit 88bbe85dcd37 ("irqchip: bcm2836: Move SMP startup code to
> arch/arm (v2)") the bcm2836-l1-intc block on bcm2711 is only used as a
> base address for the smp_boot_secondary hook on 32 bit kernels. It is
> not used as an interrupt controller.
> 
> Drop the binding requirement for interrupt-controller and interrupt-cells
> to satisfy validation on this platform.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  .../devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml  | 2 --
>  1 file changed, 2 deletions(-)

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

Best regards,
Krzysztof



From krzk at kernel.org  Fri Dec 13 01:19:59 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 10:19:59 +0100
Subject: [PATCH v3 3/7] dt-bindings: gpio: brcmstb: permit
 gpio-line-names property
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-3-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
 <20241212-dt-bcm2712-fixes-v3-3-44a7f3390331@raspberrypi.com>
Message-ID: <atzraxqm7z7trpagw2kj4xraghb323zry5cztwadqsowfafkmm@gejykzp4hjoo>

On Thu, Dec 12, 2024 at 06:36:30PM +0000, Dave Stevenson wrote:
> gpio-line-names is a generic property that can be supported by any
> GPIO controller, so permit it through the binding.
> 
> It is permitted to have a variable number of GPIOs per node based
> on brcm,gpio-bank-widths, so define an arbitrary maximum number of
> items based on current users.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml | 4 ++++
>  1 file changed, 4 insertions(+)

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

Best regards,
Krzysztof



From krzk at kernel.org  Fri Dec 13 01:22:15 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 10:22:15 +0100
Subject: [PATCH v3 1/2] dt-bindings: thermal: fsl,imx91-tmu: add bindings
 for NXP i.MX91 thermal module
In-Reply-To: <20241212-imx91tmu-v3-1-85e756b29437@nxp.com>
References: <20241212-imx91tmu-v3-0-85e756b29437@nxp.com>
 <20241212-imx91tmu-v3-1-85e756b29437@nxp.com>
Message-ID: <kb2mekvslpkj23a3ymdfwcpugvlscn736kjfwst24xqdgyqrfn@jozxo7o7enbi>

On Thu, Dec 12, 2024 at 03:59:59PM -0500, Frank Li wrote:
> From: Pengfei Li <pengfei.li_1 at nxp.com>
> 
> Add bindings documentation for i.MX91 thermal modules.
> 
> Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

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

Best regards,
Krzysztof



From richard.xnu.clark at gmail.com  Fri Dec 13 01:27:02 2024
From: richard.xnu.clark at gmail.com (Richard Clark)
Date: Fri, 13 Dec 2024 17:27:02 +0800
Subject: Question about interrupt prioriyt of ARM GICv3/4
In-Reply-To: <871pydxde2.fsf@bloch.sibelius.xs4all.nl>
References: <CAJNi4rMfhZOCT+7Ki14vUs+dZbv9cxCZ0s+jgn6=_om4NTgo_A@mail.gmail.com>
 <86cyi5tanz.wl-maz@kernel.org>
 <CAJNi4rPDVXS3Ft3nHLXvMzHmn9d10Nz4Pxeduoe+v5HaK=CEAg@mail.gmail.com>
 <86ldwlryzz.wl-maz@kernel.org>
 <871pydxde2.fsf@bloch.sibelius.xs4all.nl>
Message-ID: <Z1v9GKkghPjpnvp6@MBC02GN1V4Q05P>

Hi Mark,

On Thu, Dec 12, 2024 at 02:02:45PM +0100, Mark Kettenis wrote:
> > Date: Thu, 12 Dec 2024 10:12:32 +0000
> > From: Marc Zyngier <maz at kernel.org>
> 
> Hi Marc, Richard,
> 
> > On Thu, 12 Dec 2024 09:18:56 +0000,
> > richard clark <richard.xnu.clark at gmail.com> wrote:
> > > 
> > > Hi M,
> > 
> > Hi r,
> > 
> > > 
> > > On Fri, Dec 6, 2024 at 5:37?PM Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > On Fri, 06 Dec 2024 08:33:11 +0000,
> > > > richard clark <richard.xnu.clark at gmail.com> wrote:
> > > > >
> > > > > Hi,
> > > > > Currently seems the GICv3/4 irqchip configures all the interrupts as
> > > > > the same priority, I am thinking about to minimize the latency of the
> > > > > interrupt for a particular device, e.g, the arm arch_timer in the RTL
> > > > > system. The question is,
> > > > > 1. Why don't we provide a /proc or /sys interface for the enduser to
> > > > > set the priority of a specific interrupt(SPI/PPI)?
> > > >
> > > > I'm afraid this really has nothing to do with any particular interrupt
> > > > architecture.
> > > >
> > > > Before thinking of exposing the interrupt priority to userspace, you
> > > > should look at what this translates into for the kernel once you allow
> > > > interrupts to be preempted by another one with a higher priority.
> > > >
> > > Interrupt priority doesn't necessarily mean the preemption, seems
> > > you're talking about the interrupt preemption harm according to your
> > > statement followed.Frankly I am just thinking higher priority will win
> > > the lower ones in case massive external interrupts received in the GIC
> > > level (you see I am still talking about GIC, not kernel)
> > 
> > As I stated at the end of my email, the GIC only gives guarantee that
> > you will ack the highest priority interrupt in finite time. Not right
> > when it is made pending. Yes, it has the concept of HPPI. But that
> > from the PoV of the CPU interface, not that of the distributor. Factor
> > in the Stream interface, and you realise that expecting to always ack
> > the highest priority pending interrupt is akin to expecting no
> > reordering of packets in a network.
> > 
> > > >
> > > > This means that at every point where you would normally see a
> > > > local_irq_save(), spinlock_irqsave() or equivalent, you would need to
> > > > explicitly specify the priority that you allow for preemption. You
> > > > should then make sure that any code that can be run during an
> > > > interrupt is reentrant. You need to define which data structures can
> > > > be manipulated at which priority level... The list goes on.
> > > >
> > > irqsave just masks the interrupt from the point of cpu, I don't think
> > > it will mess things up if preemption really happens (no? then what the
> > > side-effect is for the nested interrupt handling in the softirq part.
> > > damage the semantic of the lock primitives?)
> > > >
> > > > If you want a small taste of the complexity, just look at what
> > > > handling NMIs (or even pseudo-NMIs in the case of GICv3) means, and
> > > > generalise it to not just two, but an arbitrary range of priorities.
> > > >
> > > > If you want the full blown experience, look at the BSDs and their use
> > > > of spl*(). I don't think anyone has any plan to get there, and the RT
> > > > patches have shown that there is little need for it.
> > > >
> > > As supplement?the fiq is suggested to be used as an alternative to the
> > > higher priority in the RT area...
> > 
> > <PulpFiction>
> > FIQ's dead, baby. FIQ's dead.
> > </PulpFiction>
> 
> Hah, tell that to Apple! ;).
>
Suppose you're kiding, seems neither Apple employee nor working on its HW :)
> 
> > > > > 2. Is there any way to verify the higher priority interrupt will have
> > > > > more dominant to be selected to the CPU (IOW, the priority is really
> > > > > working) in case of multiple different interrupts asserted to the GIC
> > > > > at the same time(some debug registers of GIC like GICD_REEMPT_CNT :-)
> > > > > to record higher priority wins)?
> > > >
> > > > The GIC architecture makes no promise that the interrupt you
> > > > acknowledge is the highest priority pending interrupt, because this is
> > > > by definition a very racy process.
> > > >
> > > > Also, even on busy systems, you will very rarely see two interrupts
> > > > targeting the same CPU being made pending at the same time, so that
> > > > the interrupt delivery system would have to arbitrate between the two.
> > > > That's because interrupts are vanishingly rare in the grand scheme of
> > > > things.
> > > >
> > > 1. I am trying to stress the external interrupts to the core#0 via the
> > > stress-ng tool with one of interrupt being configured as higher
> > > priority to see the benchmark data, it's time consuming as you can
> > > image, still is in progress(BTW, I can't see any lockup similar hang
> > > in the system with a higher priority configured)
> > 
> > If you don't have preemption, I don't think anything wrong will
> > happen. But I don't expect any benefit either.
> 
> Based on my experience with OpenBSD, I'm not even sure there is much
> benefit even if you have preemtion.
>
is OpenBSD has this priority feature supported? or do you have some related perf
data on BSP...
> 
> And regarding anything wrong happening: there is an interesting bug in
> the RK3399 GIC integration where it gets the priorities wrong:
> 
> https://github.com/openbsd/src/blob/feb3ea439d8f49b3c0e33f54c34631a611b98e21/sys/arch/arm64/dev/agintc.c#L395
> 
> (that comment is my interpretation of what's happening; I might be
> misinterpreting what's really going on)
> 
> As far as I can tell the Linux code doesn't handle that quirk.
> Probably it doesn't matter because Linux only uses the priority
> mechanisms to implement pseudo-NMI functionality and/or doesn't do
> preemption of interrupts.
>
seems the BSP has the priority support but encounter the bug/quirk, correct me if I am wrong. Frankly I have no
time to read the code of your link

	r.

> 
> > > 2. This raises a very interesting question and I am also very curious
> > > about is, what is the purpose for the GIC to introduce the interrupt
> > > priority features, a placeholder feature reserved for the future? Ah,
> > > hardware prefer to provide more functionalities than its being
> > > actually used by software, any other justification except that?
> > 
> > You realise that the HW is not exclusively designed for Linux, right?
> > 
> > 	M.
> > 
> > -- 
> > Without deviation from the norm, progress is not possible.
> > 
> > 


From yuanhsinte at chromium.org  Fri Dec 13 01:29:22 2024
From: yuanhsinte at chromium.org (Hsin-Te Yuan)
Date: Fri, 13 Dec 2024 09:29:22 +0000
Subject: [PATCH] arm64: dts: mediatek: mt8188: Add GPU speed bin NVMEM
 cells
Message-ID: <20241213-speedbin-v1-1-a0053ead9477@chromium.org>

On the MT8188, the chip is binned for different GPU voltages at the
highest OPPs. The binning value is stored in the efuse.

Add the NVMEM cell, and tie it to the GPU.

Signed-off-by: Hsin-Te Yuan <yuanhsinte at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8188.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index cd27966d2e3c05833f11294cfa8f6a984d4e0dbc..0e865f5083b475c6e33cf6a0ce51d2b615af7850 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -1752,6 +1752,11 @@ efuse: efuse at 11f20000 {
 			lvts_efuse_data1: lvts1-calib at 1ac {
 				reg = <0x1ac 0x40>;
 			};
+
+			gpu_speedbin: gpu-speedbin at 581 {
+				reg = <0x581 0x1>;
+				bits = <0 3>;
+			};
 		};
 
 		gpu: gpu at 13000000 {
@@ -1763,6 +1768,8 @@ gpu: gpu at 13000000 {
 				     <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH 0>,
 				     <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>;
 			interrupt-names = "job", "mmu", "gpu";
+			nvmem-cells = <&gpu_speedbin>;
+			nvmem-cell-names = "speed-bin";
 			operating-points-v2 = <&gpu_opp_table>;
 			power-domains = <&spm MT8188_POWER_DOMAIN_MFG2>,
 					<&spm MT8188_POWER_DOMAIN_MFG3>,

---
base-commit: 1488143f901e04e132722cb093613e8d019a4ec6
change-id: 20241213-speedbin-f339c2648ff0

Best regards,
-- 
Hsin-Te Yuan <yuanhsinte at chromium.org>



From lpieralisi at kernel.org  Fri Dec 13 01:32:28 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Fri, 13 Dec 2024 10:32:28 +0100
Subject: [PATCH v8 2/2] PCI: imx6: Add IOMMU and ITS MSI support for
 i.MX95
In-Reply-To: <Z1sdbH7N1Ly9eXc0@lizhi-Precision-Tower-5810>
References: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
 <20241210-imx95_lut-v8-2-2e730b2e5fde@nxp.com>
 <Z1sTUaoA5yk9RcIc@lpieralisi>
 <Z1sdbH7N1Ly9eXc0@lizhi-Precision-Tower-5810>
Message-ID: <Z1v/LCHsGOgnasuf@lpieralisi>

On Thu, Dec 12, 2024 at 12:29:16PM -0500, Frank Li wrote:
> On Thu, Dec 12, 2024 at 05:46:09PM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Dec 10, 2024 at 05:48:59PM -0500, Frank Li wrote:
> > > For the i.MX95, configuration of a LUT is necessary to convert Bus Device
> > > Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
> > > This involves checking msi-map and iommu-map device tree properties to
> > > ensure consistent mapping of PCI BDF to the same stream IDs. Subsequently,
> > > LUT-related registers are configured. In the absence of an msi-map, the
> > > built-in MSI controller is utilized as a fallback.
> >
> > This is wrong information. What you want to say is that if an msi-map
> > isn't detected this means that the platform relies on DWC built-in
> > controller for MSIs (that does not need streamIDs handling).
> >
> > That's quite different from what you are writing here.
> 
> How about ?
> 
> "If an msi-map isn't detected, platform relies on DWC built-in controller
> for MSIs that does not need streamdIDs"

Right. Question: what happens if DT shows that there are SMMU and/or
ITS bindings/mappings but the SMMU driver and ITS driver are either not
enabled or have not probed ?

I assume the LUT programming makes no difference (it is useless yes but
should be harmless too) in this case but wanted to check with you.

Thanks,
Lorenzo

> 
> >
> > >
> > > Register a PCI bus callback function to handle enable_device() and
> > > disable_device() operations, setting up the LUT whenever a new PCI device
> > > is enabled.
> > >
> > > Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
> > > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> 
> [...]
> 
> > > +	int err_i, err_m;
> > > +	u32 sid;
> > > +
> > > +	dev = imx_pcie->pci->dev;
> > > +
> > > +	target = NULL;
> > > +	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
> > > +	if (target) {
> > > +		of_node_put(target);
> > > +	} else {
> > > +		/*
> > > +		 * "target == NULL && err_i == 0" means use 1:1 map RID to
> >
> > Is it what it means ? Or does it mean that the iommu-map property was found
> > and RID is out of range ?
> 
> yes, if this happen, sid_i will be equal to RID.
> 
> >
> > Could you point me at a sample dts for this host bridge please ?
> 
> https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/boot/dts/freescale/imx95.dtsi
> 
> /* 0x10~0x17 stream id for pci0 */
>    iommu-map = <0x000 &smmu 0x10 0x1>,
>                <0x100 &smmu 0x11 0x7>;
> 
> /* msi part */
>    msi-map = <0x000 &its 0x10 0x1>,
>              <0x100 &its 0x11 0x7>;
> 
> >
> > > +		 * stream ID. Hardware can't support this because stream ID
> > > +		 * only 5bits
> >
> > It is 5 or 6 bits ? From GENMASK(5, 0) above it should be 6.
> 
> Sorry for typo. it is 6bits.
> 
> >
> > > +		 */
> > > +		err_i = -EINVAL;
> > > +	}
> > > +
> > > +	target = NULL;
> > > +	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
> > > +
> > > +	/*
> > > +	 *   err_m      target
> > > +	 *	0	NULL		Use 1:1 map RID to stream ID,
> >
> > Again, is that what it really means ?
> >
> > > +	 *				Current hardware can't support it,
> > > +	 *				So return -EINVAL.
> > > +	 *      != 0    NULL		msi-map not exist, use built-in MSI.
> >
> > does not exist.
> >
> > > +	 *	0	!= NULL		Get correct streamID from RID.
> > > +	 *	!= 0	!= NULL		Unexisted case, never happen.
> >
> > "Invalid combination"
> >
> > > +	 */
> > > +	if (!err_m && !target)
> > > +		return -EINVAL;
> > > +	else if (target)
> > > +		of_node_put(target); /* Find stream ID map entry for RID in msi-map */
> > > +
> > > +	/*
> > > +	 * msi-map        iommu-map
> > > +	 *   N                N            DWC MSI Ctrl
> > > +	 *   Y                Y            ITS + SMMU, require the same sid
> > > +	 *   Y                N            ITS
> > > +	 *   N                Y            DWC MSI Ctrl + SMMU
> > > +	 */
> > > +	if (err_i && err_m)
> > > +		return 0;
> > > +
> > > +	if (!err_i && !err_m) {
> > > +		/*
> > > +		 * MSI glue layer auto add 2 bits controller ID ahead of stream
> >
> > What's "MSI glue layer" ?
> 
> It is common term for IC desgin, which connect IP's signal to platform with
> some simple logic. Inside chip, when connect LUT output 6bit streamIDs
> to MSI controller, there are 2bits hardcode controller ID information
> append to 6 bits streamID.
> 
>            Glue Layer
>           <==========>
> ???????                  ????????????
> ? LUT ? 6bit stream ID   ?          ?
> ?     ????????????????????  MSI     ?
> ???????    2bit ctrl ID  ?          ?
>             ??????????????          ?
>             ?            ?          ?
>  00 PCIe0   ?            ?          ?
>  01 ENETC   ?            ?          ?
>  10 PCIe1   ?            ?          ?
>             ?            ????????????
> 
> >
> > > +		 * ID, so mask this 2bits to get stream ID.
> > > +		 * But IOMMU glue layer doesn't do that.
> >
> > and "IOMMU glue layer" ?
> 
> See above.
> 
> Frank
> 
> >
> > > +		 */
> > > +		if (sid_i != (sid_m & IMX95_SID_MASK)) {
> > > +			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
> > > +			return -EINVAL;
> > > +		}
> > > +	}
> > > +
> > > +	sid = sid_i;
> >
> > err_i could be != 0 here, I understand that the end result is
> > fine given how the code is written but it is misleading.
> >
> > 	if (!err_i)
> > 	else if (!err_m)
> 
> Okay
> 
> >
> > > +	if (!err_m)
> > > +		sid = sid_m & IMX95_SID_MASK;
> > > +
> > > +	return imx_pcie_add_lut(imx_pcie, rid, sid);
> > > +}
> > > +
> > > +static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> > > +{
> > > +	struct imx_pcie *imx_pcie;
> > > +
> > > +	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> > > +	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
> > > +}
> > > +
> > >  static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> > >  {
> > >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > @@ -946,6 +1122,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> > >  		}
> > >  	}
> > >
> > > +	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
> > > +		pp->bridge->enable_device = imx_pcie_enable_device;
> > > +		pp->bridge->disable_device = imx_pcie_disable_device;
> > > +	}
> > > +
> > >  	imx_pcie_assert_core_reset(imx_pcie);
> > >
> > >  	if (imx_pcie->drvdata->init_phy)
> > > @@ -1330,6 +1511,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
> > >  	imx_pcie->pci = pci;
> > >  	imx_pcie->drvdata = of_device_get_match_data(dev);
> > >
> > > +	mutex_init(&imx_pcie->lock);
> > > +
> > >  	/* Find the PHY if one is defined, only imx7d uses it */
> > >  	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
> > >  	if (np) {
> > > @@ -1627,7 +1810,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
> > >  	},
> > >  	[IMX95] = {
> > >  		.variant = IMX95,
> > > -		.flags = IMX_PCIE_FLAG_HAS_SERDES,
> > > +		.flags = IMX_PCIE_FLAG_HAS_SERDES |
> > > +			 IMX_PCIE_FLAG_HAS_LUT,
> > >  		.clk_names = imx8mq_clks,
> > >  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> > >  		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> > >
> > > --
> > > 2.34.1
> > >


From markuss.broks at gmail.com  Fri Dec 13 01:42:04 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Fri, 13 Dec 2024 11:42:04 +0200
Subject: [PATCH 2/3] soc: samsung: Add a driver for Samsung SPEEDY host
 controller
In-Reply-To: <f08b068e-bc6b-4d9d-9839-370883309b88@kernel.org>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
 <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
 <f08b068e-bc6b-4d9d-9839-370883309b88@kernel.org>
Message-ID: <2a7f71b6-0967-40ee-9d0f-d7144eafcd5a@gmail.com>

Hi Krzysztof,

On 12/13/24 9:49 AM, Krzysztof Kozlowski wrote:
> On 12/12/2024 22:09, Markuss Broks wrote:
>> Add a driver for Samsung SPEEDY serial bus host controller.
>> SPEEDY is a proprietary 1 wire serial bus used by Samsung
>> in various devices (usually mobile), like Samsung Galaxy
>> phones. It is usually used for connecting PMIC or various
>> other peripherals, like audio codecs or RF components.
>>
>> This bus can address at most 1MiB (4 bit device address,
>> 8 bit registers per device, 8 bit wide registers:
>> 256*256*16 = 1MiB of address space.
>>
>> Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
>> Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
>> Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
>> ---
>>   drivers/soc/samsung/Kconfig               |  13 +
>>   drivers/soc/samsung/Makefile              |   2 +
>>   drivers/soc/samsung/exynos-speedy.c       | 457 ++++++++++++++++++++++++++++++
>>   include/linux/soc/samsung/exynos-speedy.h |  56 ++++
>>   4 files changed, 528 insertions(+)
>>
>> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
>> index 1a5dfdc978dc4069eb71c4e8eada7ff1913b86b3..a38150fc9999ded1e1e93e2a9ef43b88175d34bd 100644
>> --- a/drivers/soc/samsung/Kconfig
>> +++ b/drivers/soc/samsung/Kconfig
>> @@ -49,6 +49,19 @@ config EXYNOS_PMU_ARM_DRIVERS
>>   	bool "Exynos PMU ARMv7-specific driver extensions" if COMPILE_TEST
>>   	depends on EXYNOS_PMU
>>   
>> +config EXYNOS_SPEEDY
>> +	tristate "Exynos SPEEDY host controller driver"
>> +	depends on ARCH_EXYNOS || COMPILE_TEST
>> +	depends on OF
>> +	depends on REGMAP_MMIO
>> +	help
>> +	  Enable support for Exynos SPEEDY host controller block.
>> +	  SPEEDY is a 1 wire proprietary Samsung serial bus, found in
>> +	  modern Samsung Exynos SoCs, like Exynos8895 and newer.
>
> I did not check that much but this looks like 1wire for which we have
> subsystem. Please investigate more and figure out the differences.

This is not compatible with Dallas Semi 1-Wire bus. There are several 
differences but the phy level is not compatible, looking at the Samsung 
patent. [1] The most obvious difference is that 1-Wire is discoverable, 
and this bus isn't. I'm pretty sure this is Samsung's own solution to a 
serial interface through only one wire.

>
>> +
>> +	  Select this if you have a Samsung Exynos device which uses
>> +	  SPEEDY bus.
>> +
>
>> +
>> +/* SPEEDY_PACKET_GAP_TIME register bits */
>> +#define SPEEDY_FIFO_TX_ALMOST_EMPTY			(1 << 4)
>> +#define SPEEDY_FIFO_RX_ALMOST_FULL			(1 << 8)
>> +#define SPEEDY_FSM_INIT					(1 << 1)
>> +#define SPEEDY_FSM_TX_CMD				(1 << 2)
>> +#define SPEEDY_FSM_STANDBY				(1 << 3)
>> +#define SPEEDY_FSM_DATA					(1 << 4)
>> +#define SPEEDY_FSM_TIMEOUT				(1 << 5)
>> +#define SPEEDY_FSM_TRANS_DONE				(1 << 6)
>> +#define SPEEDY_FSM_IO_RX_STAT_MASK			(3 << 7)
>> +#define SPEEDY_FSM_IO_TX_IDLE				(1 << 9)
>> +#define SPEEDY_FSM_IO_TX_GET_PACKET			(1 << 10)
>> +#define SPEEDY_FSM_IO_TX_PACKET				(1 << 11)
>> +#define SPEEDY_FSM_IO_TX_DONE				(1 << 12)
>> +
>> +#define SPEEDY_RX_LENGTH(n)				((n) << 0)
>> +#define SPEEDY_TX_LENGTH(n)				((n) << 8)
>> +
>> +#define SPEEDY_DEVICE(x)				((x & 0xf) << 15)
>> +#define SPEEDY_ADDRESS(x)				((x & 0xff) << 7)
>> +
>> +static const struct of_device_id speedy_match[] = {
>> +	{ .compatible = "samsung,exynos9810-speedy" },
>> +	{ /* Sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, speedy_match);
> This is never at top of the file, but immediately before driver
> structure. Look at other drivers.
The function speedy_get_device uses this to match the compatible, do I 
just leave the prototype here?
>
>> +
>> +static const struct regmap_config speedy_map_cfg = {
>> +	.reg_bits = 32,
>> +	.val_bits = 32,
>> +};
>> +
>> +/**
>> + * speedy_int_clear() - clear interrupt status
>> + * @speedy:	pointer to speedy controller struct
>> + *
>> + * Return: 0 on success, -errno otherwise
>> + */
>> +static int speedy_int_clear(struct speedy_controller *speedy)
>> +{
>> +	int ret;
>> +
>> +	ret = regmap_set_bits(speedy->map, SPEEDY_INT_STATUS, 0xffffffff);
>> +	if (ret)
>> +		return ret;
>> +
>> +	udelay(10);
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * speedy_fifo_reset() - reset FIFO of the controller
>> + * @speedy:	pointer to speedy controller struct
>> + *
>> + * Return: 0 on success, -errno otherwise
>> + */
>> +static int speedy_fifo_reset(struct speedy_controller *speedy)
>> +{
>> +	int ret;
>> +
>> +	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL, SPEEDY_FIFO_RESET);
>> +	if (ret)
>> +		return ret;
>> +
>> +	udelay(10);
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * _speedy_read() - internal speedy read operation
>> + * @speedy:	pointer to speedy controller struct
>> + * @reg:	address of device on the bus
>> + * @addr:       address to read
>> + * @val:        pointer to store result
>> + *
>> + * Return: 0 on success, -errno otherwise
>> + */
>> +static int _speedy_read(struct speedy_controller *speedy, u32 reg, u32 addr, u32 *val)
>> +{
>> +	int ret;
>> +	u32 cmd, int_ctl, int_status;
>> +
>> +	mutex_lock(&speedy->io_lock);
>> +
>> +	ret = speedy_fifo_reset(speedy);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
>> +			      SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
>> +	if (ret)
>> +		return ret;
>> +
>> +	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_READ |
>> +	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
>> +
>> +	int_ctl = SPEEDY_TRANSFER_DONE_EN | SPEEDY_FIFO_RX_ALMOST_FULL_EN |
>> +		  SPEEDY_RX_FIFO_INT_TRAILER_EN | SPEEDY_RX_MODEBIT_ERR_EN |
>> +		  SPEEDY_RX_GLITCH_ERR_EN | SPEEDY_RX_ENDBIT_ERR_EN |
>> +		  SPEEDY_REMOTE_RESET_REQ_EN;
>> +
>> +	ret = speedy_int_clear(speedy);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* Wait for xfer done */
>> +	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
>> +				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = regmap_read(speedy->map, SPEEDY_RX_DATA, val);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = speedy_int_clear(speedy);
>> +
>> +	mutex_unlock(&speedy->io_lock);
>> +
>> +	return ret;
>> +}
>> +
>> +int exynos_speedy_read(const struct speedy_device *device, u32 addr, u32 *val)
>> +{
>> +	return _speedy_read(device->speedy, device->reg, addr, val);
>> +}
>> +EXPORT_SYMBOL_GPL(exynos_speedy_read);
> Nope, drop, unused.
This is intended to be used with other device drivers, this driver in 
itself doesn't do anything, it only configures the controller and makes 
it ready for transmitting data, it's other drivers that will come (e.g. 
S2MPS18 PMIC, which uses SPEEDY for communication with the SoC) that 
will utilize those functions.
>
>> +
>> +/**
>> + * _speedy_write() - internal speedy write operation
>> + * @speedy:	pointer to speedy controller struct
>> + * @reg:	address of device on the bus
>> + * @addr:       address to write
>> + * @val:        value to write
>> + *
>> + * Return: 0 on success, -errno otherwise
>> + */
>> +static int _speedy_write(struct speedy_controller *speedy, u32 reg, u32 addr, u32 val)
>> +{
>> +	int ret;
>> +	u32 cmd, int_ctl, int_status;
>> +
>> +	mutex_lock(&speedy->io_lock);
>> +
>> +	ret = speedy_fifo_reset(speedy);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
>> +			      SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
>> +	if (ret)
>> +		return ret;
>> +
>> +	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_WRITE |
>> +	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
>> +
>> +	int_ctl = (SPEEDY_TRANSFER_DONE_EN |
>> +		   SPEEDY_FIFO_TX_ALMOST_EMPTY_EN |
>> +		   SPEEDY_TX_LINE_BUSY_ERR_EN |
>> +		   SPEEDY_TX_STOPBIT_ERR_EN |
>> +		   SPEEDY_REMOTE_RESET_REQ_EN);
>> +
>> +	ret = speedy_int_clear(speedy);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = regmap_write(speedy->map, SPEEDY_TX_DATA, val);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* Wait for xfer done */
>> +	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
>> +				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
>> +	if (ret)
>> +		return ret;
>> +
>> +	speedy_int_clear(speedy);
>> +
>> +	mutex_unlock(&speedy->io_lock);
>> +
>> +	return 0;
>> +}
>> +
>> +int exynos_speedy_write(const struct speedy_device *device, u32 addr, u32 val)
>> +{
>> +	return _speedy_write(device->speedy, device->reg, addr, val);
> Just write the function here and drop _.
>
>> +}
>> +EXPORT_SYMBOL_GPL(exynos_speedy_write);
>> +
>> +static void devm_speedy_release(struct device *dev, void *res)
>> +{
>> +	const struct speedy_device **ptr = res;
>> +	const struct speedy_device *handle = *ptr;
>> +
>> +	kfree(handle);
>> +}
>> +
>> +/**
>> + * speedy_get_by_phandle() - internal get speedy device handle
>> + * @np:	pointer to OF device node of device
>> + *
>> + * Return: 0 on success, -errno otherwise
>> + */
>> +static const struct speedy_device *speedy_get_device(struct device_node *np)
>> +{
>> +	const struct of_device_id *speedy_id;
>> +	struct device_node *speedy_np;
>> +	struct platform_device *speedy_pdev;
>> +	struct speedy_controller *speedy = NULL;
>> +	struct speedy_device *handle;
>> +	int ret;
>> +
>> +	if (!np) {
>> +		pr_err("I need a device pointer\n");
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>> +	speedy_np = of_get_parent(np);
>> +	if (!speedy_np)
>> +		return ERR_PTR(-ENODEV);
>> +
>> +	/* Verify if parent node is a speedy controller */
>> +	speedy_id = of_match_node(speedy_match, speedy_np);
>> +	if (!speedy_id) {
>> +		handle = ERR_PTR(-EINVAL);
>> +		goto out;
>> +	}
>> +
>> +	/* Get platform device of the speedy controller */
>> +	speedy_pdev = of_find_device_by_node(speedy_np);
>> +	if (!speedy_pdev) {
>> +		handle = ERR_PTR(-EPROBE_DEFER);
>> +		goto out;
>> +	}
>> +
>> +	/* Get drvdata of speedy controller */
>> +	speedy = platform_get_drvdata(speedy_pdev);
>> +	if (!speedy) {
>> +		handle = ERR_PTR(-EINVAL);
>> +		goto out;
>> +	}
>> +
>> +	handle = kzalloc(sizeof(struct speedy_device), GFP_KERNEL);
>> +	if (!handle) {
>> +		handle = ERR_PTR(-ENOMEM);
>> +		goto out;
>> +	}
>> +	handle->speedy = speedy;
>> +	ret = of_property_read_u32(np, "reg", &handle->reg);
>> +	if (ret) {
>> +		kfree(handle);
>> +		handle = ERR_PTR(-EINVAL);
>> +		goto out;
>> +	}
>> +
>> +out:
>> +	of_node_put(speedy_np);
>> +	return handle;
>> +}
>> +
>> +const struct speedy_device *devm_speedy_get_device(struct device *dev)
> Not used, drop function.
>
>> +{
>> +	const struct speedy_device *handle;
>> +	const struct speedy_device **ptr;
>> +
>> +	ptr = devres_alloc(devm_speedy_release, sizeof(*ptr), GFP_KERNEL);
>> +	if (!ptr)
>> +		return ERR_PTR(-ENOMEM);
>> +
>> +	handle = speedy_get_device(dev_of_node(dev));
>> +	if (!IS_ERR(handle)) {
>> +		*ptr = handle;
>> +		devres_add(dev, ptr);
>> +	} else {
>> +		devres_free(ptr);
>> +	}
>> +
>> +	return handle;
>> +}
>> +EXPORT_SYMBOL_GPL(devm_speedy_get_device);
> Not used, drop.
>
>
>
>> +
>> +static int speedy_probe(struct platform_device *pdev)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	struct speedy_controller *speedy;
>> +	void __iomem *mem;
>> +	int ret;
>> +
>> +	speedy = devm_kzalloc(dev, sizeof(struct speedy_controller), GFP_KERNEL);
> sizeof(*) everywhere. You need to clean the downstream code when
> upstreaming.
Oh, okay, sorry, missed it.
>
>> +	if (!speedy)
>> +		return -ENOMEM;
>> +
>> +	platform_set_drvdata(pdev, speedy);
>> +	speedy->pdev = pdev;
>> +
>> +	mutex_init(&speedy->io_lock);
>> +
>> +	mem = devm_platform_ioremap_resource(pdev, 0);
>> +	if (IS_ERR(mem))
>> +		return dev_err_probe(dev, PTR_ERR(mem), "Failed to ioremap memory\n");
>> +
>> +	speedy->map = devm_regmap_init_mmio(dev, mem, &speedy_map_cfg);
>> +	if (IS_ERR(speedy->map))
>> +		return dev_err_probe(dev, PTR_ERR(speedy->map), "Failed to init the regmap\n");
> Wrap at 80.
>
>> +
>> +	/* Clear any interrupt status remaining */
>> +	ret = speedy_int_clear(speedy);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* Reset the controller */
>> +	ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_SW_RST);
>> +	if (ret)
>> +		return ret;
>> +
>> +	msleep(20);
>> +
>> +	/* Enable the hw */
>> +	ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_ENABLE);
>> +	if (ret)
>> +		return ret;
>> +
>> +	msleep(20);
>> +
>> +	/* Probe child devices */
>> +	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev);
>> +	if (ret)
>> +		dev_err(dev, "Failed to populate child devices: %d\n", ret);
>> +
>> +	return ret;
> Missing cleanup in remove().
Will be done.
>
>> +}
>> +
>> +static struct platform_driver speedy_driver = {
>> +	.probe = speedy_probe,
>> +	.driver = {
>> +		.name = "exynos-speedy",
>> +		.of_match_table = speedy_match,
>> +	},
>> +};
>> +
>> +module_platform_driver(speedy_driver);
>> +
>> +MODULE_DESCRIPTION("Samsung Exynos SPEEDY host controller driver");
>> +MODULE_AUTHOR("Markuss Broks <markuss.broks at gmail.com>");
>> +MODULE_LICENSE("GPL");
>> diff --git a/include/linux/soc/samsung/exynos-speedy.h b/include/linux/soc/samsung/exynos-speedy.h
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..b2857d65d3b50927373866dd8ae1c47e98af6d7b
>> --- /dev/null
>> +++ b/include/linux/soc/samsung/exynos-speedy.h
> Drop the header, not used.
Same here, please clarify how this should be handled. This driver 
implements the devm_speedy_get_device and read/write functions for its 
child devices in that header, future drivers for e.g. PMIC would use 
this header and call devm_speedy_get_device to get a speedy_device 
pointer and then use read/write functions to read/write from the bus.
>
>
>
> Best regards,
> Krzysztof

- Markuss


[1] https://patents.google.com/patent/US9882711B1/en



From krzk at kernel.org  Fri Dec 13 01:41:57 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 10:41:57 +0100
Subject: [PATCH stm32-next 2/2] ARM: dts: stm32: lxa-fairytux2: add Linux
 Automation GmbH FairyTux 2
In-Reply-To: <20241210-lxa-fairytux-v1-2-9aea01cdb83e@pengutronix.de>
References: <20241210-lxa-fairytux-v1-0-9aea01cdb83e@pengutronix.de>
 <20241210-lxa-fairytux-v1-2-9aea01cdb83e@pengutronix.de>
Message-ID: <lqw5blalkc2e4owzds5qs6bntsk6oh5jq5o6si3ugpa4sm7wu7@ssg4l3da6mww>

On Tue, Dec 10, 2024 at 10:32:28AM +0100, Marc Kleine-Budde wrote:
> +&gpiof {
> +	gpio-line-names = "GPIO1", "GPIO2", "", "", "", /*  0 */
> +	"", "", "", "", "",                             /*  5 */

That's not really readable. Fix the alignment with opening ", see DTS
coding style.

> +	"", "", "", "", "",                             /* 10 */
> +	"";                                             /* 15 */
> +};
> +
> +&gpioh {
> +	gpio-line-names = "", "", "", "", "LCD_RESET", /*  0 */
> +	"", "", "", "", "",                            /*  5 */
> +	"", "", "", "GPIO3", "",                       /* 10 */
> +	"";                                            /* 15 */
> +};
> +
> +&gpioi {
> +	gpio-line-names = "", "", "", "", "", /*  0 */
> +	"", "", "", "ETH_", "",               /*  5 */
> +	"", "USER_BTN1";                      /* 10 */
> +};
> +
> +&i2c1 {
> +	pinctrl-names = "default", "sleep";
> +	pinctrl-0 = <&i2c1_pins_b>;
> +	pinctrl-1 = <&i2c1_sleep_pins_b>;
> +	status = "okay";
> +
> +	io_board_gpio: tca6408 at 20 {

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 = "ti,tca6408";
> +		reg = <0x20>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		vcc-supply = <&v3v3_hdmi>;
> +		gpio-line-names = "LED1_GA_YK", "LED2_GA_YK", "LED1_GK_YA", "LED2_GK_YA",
> +		"RS485_EN", "RS485_120R", "", "CAN_120R";
> +	};
> +};
> +
> +&led_controller_io {
> +	/*
> +	 * led-2 and led-3 are internally connected antiparallel to one
> +	 * another inside the ethernet jack like this:
> +	 * GPIO1 ---+---|led-2|>--+--- GPIO3
> +	 *          +--<|led-3|---+
> +	 * E.g. only one of the LEDs can be illuminated at a time while
> +	 * the other output must be driven low.
> +	 * This should likely be implemented using a multi color LED
> +	 * driver for antiparallel LEDs.
> +	 */
> +	led-2 {
> +		label = "fairytux2:green:act";

Drop "fairytux2" and rather use color and function properties.

> +		gpios = <&io_board_gpio 1 GPIO_ACTIVE_HIGH>;
> +	};
> +
> +	led-3 {
> +		label = "fairytux2:orange:act";
> +		gpios = <&io_board_gpio 3 GPIO_ACTIVE_HIGH>;
> +	};
> +};
> +
> +&usart3 {
> +	/*
> +	 * On Gen 1 FairyTux 2 only RTS can be used and not CTS as well,
> +	 * Because pins PD11 (CTS) and PI11 (USER_BTN1) share the same
> +	 * interrupt and only one of them can be used at a time.
> +	 */
> +	rts-gpios = <&gpiod 12 GPIO_ACTIVE_LOW>;
> +};
> +
> +&usbotg_hs {
> +	dr_mode = "peripheral";
> +};
> diff --git a/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2-gen2.dts b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2-gen2.dts
> new file mode 100644
> index 0000000000000000000000000000000000000000..c84f83a75731f70165c240812f7f4230bf9bfbb0
> --- /dev/null
> +++ b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2-gen2.dts
> @@ -0,0 +1,146 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
> +/*
> + * Copyright (C) 2024 Leonard G?hrs, Pengutronix
> + */
> +
> +/dts-v1/;
> +
> +#include "stm32mp153c-lxa-fairytux2.dtsi"
> +
> +/ {
> +	model = "Linux Automation GmbH FairyTux 2 Gen 2";
> +	compatible = "lxa,stm32mp153c-fairytux2-gen2", "oct,stm32mp153x-osd32", "st,stm32mp153";
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +
> +		button-left {
> +			label = "USER_BTN1";
> +			linux,code = <KEY_ESC>;
> +			gpios = <&gpioi 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
> +		};
> +
> +		button-right {
> +			label = "USER_BTN2";
> +			linux,code = <KEY_HOME>;
> +			gpios = <&gpioe 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
> +		};
> +	};
> +};
> +
> +&gpiof {
> +	gpio-line-names = "", "", "", "", "", /*  0 */
> +	"", "", "", "", "",                   /*  5 */
> +	"", "", "", "", "",                   /* 10 */
> +	"";                                   /* 15 */
> +};
> +
> +&gpioh {
> +	gpio-line-names = "", "", "", "", "LCD_RESET", /*  0 */
> +	"", "", "", "", "",                            /*  5 */
> +	"", "", "GPIO1", "GPIO_INT", "",               /* 10 */
> +	"";                                            /* 15 */
> +};
> +
> +&gpioi {
> +	gpio-line-names = "GPIO2", "", "", "", "", /*  0 */
> +	"", "", "", "ETH_", "",                    /*  5 */
> +	"", "USER_BTN1";                           /* 10 */
> +};
> +
> +&i2c1 {
> +	pinctrl-names = "default", "sleep";
> +	pinctrl-0 = <&i2c1_pins_b>;
> +	pinctrl-1 = <&i2c1_sleep_pins_b>;
> +	status = "okay";
> +
> +	io_board_gpio: tca6408 at 20 {

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 = "ti,tca6408";
> +		reg = <0x20>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		interrupt-parent = <&gpioh>;
> +		interrupts = <13 IRQ_TYPE_LEVEL_LOW>;
> +		interrupt-controller;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&board_tca6408_pins>;
> +		#interrupt-cells = <2>;
> +		vcc-supply = <&v3v3_hdmi>;
> +		gpio-line-names = "LED1_GA_YK", "LED2_GA_YK", "LED1_GK_YA", "USB_CC_ALERT",
> +		"RS485_EN", "RS485_120R", "USB_CC_RESET", "CAN_120R";

Messed alignment.

> +	};
> +
> +	usb_c: stusb1600 at 28 {

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 = "st,stusb1600";
> +		reg = <0x28>;
> +		interrupt-parent = <&io_board_gpio>;
> +		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
> +		vdd-supply = <&reg_5v>;
> +		vsys-supply = <&v3v3_hdmi>;
> +
> +		connector {
> +			compatible = "usb-c-connector";
> +			label = "USB-C";
> +			power-role = "dual";
> +			typec-power-opmode = "default";
> +
> +			port {
> +				con_usbotg_hs_ep: endpoint {
> +					remote-endpoint = <&usbotg_hs_ep>;
> +				};
> +			};
> +		};
> +	};
> +
> +	io_board_eeprom: eeprom at 56 {
> +		compatible = "atmel,24c04";
> +		reg = <0x56>;
> +		vcc-supply = <&v3v3_hdmi>;
> +	};
> +
> +	temperature-sensor at 48 {
> +		compatible = "national,lm75a";
> +		reg = <0x48>;
> +		/*
> +		 * The sensor itself is powered by a voltage divider from the
> +		 * always-on 5V supply.
> +		 * The required pull-up resistors however are on v3v3_hdmi.
> +		 */
> +		vs-supply = <&v3v3_hdmi>;
> +	};
> +};
> +
> +&rtc {
> +	status = "okay";
> +};
> +
> +&led_controller_io {
> +	led-2 {
> +		label = "fairytux2:orange:act";
> +		gpios = <&io_board_gpio 1 GPIO_ACTIVE_LOW>;
> +	};
> +};
> +
> +&usart3 {
> +	rts-gpios = <&gpiod 12 GPIO_ACTIVE_LOW>;
> +	cts-gpios = <&gpiod 11 GPIO_ACTIVE_LOW>;
> +};
> +
> +&usbotg_hs {
> +	usb-role-switch;
> +
> +	port {
> +		usbotg_hs_ep: endpoint {
> +			remote-endpoint = <&con_usbotg_hs_ep>;
> +		};
> +	};
> +};
> +
> +&pinctrl {
> +	board_tca6408_pins: stusb1600-0 {
> +		pins {
> +			pinmux = <STM32_PINMUX('H', 13, GPIO)>;
> +			bias-pull-up;
> +		};
> +	};
> +};
> diff --git a/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi
> new file mode 100644
> index 0000000000000000000000000000000000000000..0e0e1b36cb087dfbfb47e383094c6044786a2c6a
> --- /dev/null
> +++ b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi
> @@ -0,0 +1,394 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
> +/*
> + * Copyright (C) 2020 STMicroelectronics - All Rights Reserved
> + * Copyright (C) 2021 Rouven Czerwinski, Pengutronix
> + * Copyright (C) 2023, 2024 Leonard G?hrs, Pengutronix
> + */
> +
> +#include "stm32mp153.dtsi"
> +#include "stm32mp15xc.dtsi"
> +#include "stm32mp15xx-osd32.dtsi"
> +#include "stm32mp15xxac-pinctrl.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/leds/common.h>
> +#include <dt-bindings/pwm/pwm.h>
> +
> +/ {
> +	aliases {
> +		can0 = &m_can1;
> +		ethernet0 = &ethernet0;
> +		i2c0 = &i2c1;
> +		i2c1 = &i2c4;
> +		mmc1 = &sdmmc2;
> +		serial0 = &uart4;
> +		serial1 = &usart3;
> +		spi0 = &spi4;
> +	};
> +
> +	chosen {
> +		stdout-path = &uart4;
> +	};
> +
> +	backlight: backlight {
> +		compatible = "pwm-backlight";
> +		power-supply = <&v3v3>;
> +
> +		brightness-levels = <0 31 63 95 127 159 191 223 255>;
> +		default-brightness-level = <7>;
> +		pwms = <&led_pwm 3 1000000 0>;
> +	};
> +
> +	led-controller-cpu {
> +		compatible = "gpio-leds";
> +
> +		led-0 {
> +			label = "fairytux2:green:status";

Same comment.

> +			gpios = <&gpioa 13 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "heartbeat";
> +		};
> +	};
> +
> +	led_controller_io: led-controller-io {
> +		compatible = "gpio-leds";
> +
> +		/*
> +		 * led-0 and led-1 are internally connected antiparallel to one
> +		 * another inside the ethernet jack like this:
> +		 * GPIO0 ---+---|led-0|>--+--- GPIO2
> +		 *          +--<|led-1|---+
> +		 * E.g. only one of the LEDs can be illuminated at a time while
> +		 * the other output must be driven low.
> +		 * This should likely be implemented using a multi color LED
> +		 * driver for antiparallel LEDs.
> +		 */
> +		led-0 {
> +			label = "fairytux2:green:link";
> +			gpios = <&io_board_gpio 0 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led-1 {
> +			label = "fairytux2:orange:link";
> +			gpios = <&io_board_gpio 2 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +
> +	reg_5v: regulator-5v {
> +		compatible = "regulator-fixed";
> +		regulator-name = "5V";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;
> +	};
> +
> +	reg_1v2: regulator-1v2 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "1V2";
> +		regulator-min-microvolt = <1200000>;
> +		regulator-max-microvolt = <1200000>;
> +		regulator-always-on;
> +		vin-supply = <&reg_5v>;
> +	};
> +};
> +
> +baseboard_eeprom: &sip_eeprom {
> +};
> +
> +&crc1 {
> +	status = "okay";
> +};
> +
> +&cryp1 {
> +	status = "okay";
> +};
> +
> +&dts {
> +	status = "okay";
> +};
> +
> +&ethernet0 {
> +	assigned-clocks = <&rcc ETHCK_K>, <&rcc PLL4_P>;
> +	assigned-clock-parents = <&rcc PLL4_P>;
> +	assigned-clock-rates = <125000000>; /* Clock PLL4 to 750Mhz in ATF */
> +
> +	pinctrl-names = "default", "sleep";
> +	pinctrl-0 = <&ethernet0_rgmii_pins_b>;
> +	pinctrl-1 = <&ethernet0_rgmii_sleep_pins_b>;
> +
> +	st,eth-clk-sel;
> +	phy-mode = "rgmii-id";
> +	phy-handle = <&ethphy>;
> +	status = "okay";
> +
> +	mdio {
> +		compatible = "snps,dwmac-mdio";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		ethphy: ethernet-phy at 3 { /* KSZ9031RN */
> +			reg = <3>;
> +			reset-gpios = <&gpioe 11 GPIO_ACTIVE_LOW>; /* ETH_RST# */
> +			interrupt-parent = <&gpioa>;
> +			interrupts = <6 IRQ_TYPE_EDGE_FALLING>; /* ETH_MDINT# */
> +			reset-assert-us = <10000>;
> +			reset-deassert-us = <300>;
> +			micrel,force-master;
> +		};
> +	};
> +};
> +
> +&gpioa {
> +	gpio-line-names = "", "", "", "", "", /*  0 */
> +	"", "ETH_INT", "", "", "",            /*  5 */

Really unreadable indentation. See DTS coding style.

Best regards,
Krzysztof



From krzk at kernel.org  Fri Dec 13 01:42:14 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 10:42:14 +0100
Subject: [PATCH stm32-next 1/2] dt-bindings: arm: stm32: add compatible
 strings for Linux Automation GmbH LXA FairyTux 2
In-Reply-To: <20241210-lxa-fairytux-v1-1-9aea01cdb83e@pengutronix.de>
References: <20241210-lxa-fairytux-v1-0-9aea01cdb83e@pengutronix.de>
 <20241210-lxa-fairytux-v1-1-9aea01cdb83e@pengutronix.de>
Message-ID: <h5gcnt6g5py4shyjpxlr77njkihwepdrn62poii6vyoyvwximv@fmb4becmsvwq>

On Tue, Dec 10, 2024 at 10:32:27AM +0100, Marc Kleine-Budde wrote:
> From: Leonard G?hrs <l.goehrs at pengutronix.de>
> 
> The Linux Automation GmbH FairyTux2 is a small Linux device based on
> an Octavo Systems OSD32MP153c SiP, that occupies just two slots on a
> DIN rail.
> 
> Add compatible for the generation 1 and 2 based on the STM32MP153c.
> 
> Signed-off-by: Leonard G?hrs <l.goehrs at pengutronix.de>
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  Documentation/devicetree/bindings/arm/stm32/stm32.yaml | 2 ++
>  1 file changed, 2 insertions(+)

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

Best regards,
Krzysztof



From markuss.broks at gmail.com  Fri Dec 13 01:47:33 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Fri, 13 Dec 2024 11:47:33 +0200
Subject: [PATCH 1/3] dt-bindings: soc: samsung: exynos-speedy: Document
 SPEEDY host controller bindings
In-Reply-To: <207354ad-e363-4156-ba6b-86dbaa13ab95@kernel.org>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
 <20241212-speedy-v1-1-544ad7bcfb6a@gmail.com>
 <207354ad-e363-4156-ba6b-86dbaa13ab95@kernel.org>
Message-ID: <7753293a-0ab1-48b1-abcd-a9cd544cc356@gmail.com>

Hi Krzysztof,

On 12/13/24 9:40 AM, Krzysztof Kozlowski wrote:
> On 12/12/2024 22:09, Markuss Broks wrote:
>> Add the schema for the Samsung SPEEDY serial bus host controller.
>> The bus has 4 bit wide addresses for addressing devices
>> and 8 bit wide register addressing. Each register is also 8
>> bit long, so the address can be 0-f (hexadecimal), node name
>> for child device follows the format: node_name@[0-f].
>
> This wasn't tested so limited review.
>
> 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
>
>> Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
>> Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
>> Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
>> ---
>>   .../bindings/soc/samsung/exynos-speedy.yaml        | 78 ++++++++++++++++++++++
> Filename must match compatible.
>
>>   1 file changed, 78 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..304b322a74ea70f23d8c072b44b6ca86b7cc807f
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-speedy.yaml
>> @@ -0,0 +1,78 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/soc/samsung/exynos-speedy.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Samsung Exynos SPEEDY serial bus host controller
> Speedy or SPEEDY?
Technically it's an acronym (Serial Protocol in an EffEctive Digital 
waY), but we could agree on if we use the capitalized or uncapitalised 
version and use it consistently throughout.
>
>> +
>> +maintainers:
>> +  - Markuss Broks <markuss.broks at gmail.com>
>> +
>> +description:
>> +  Samsung SPEEDY is a proprietary Samsung serial 1-wire bus.
> 1-wire? But not compatible with w1 (onwire)?
Nope, I suppose this requires more clarification, as explained in the 
previous letter, there are several differences between the protocols, 
looking at the Samsung patent. [1]
>
>> +  It is used on various Samsung Exynos chips. The bus can
>> +  address at most 4 bit (16) devices. The devices on the bus
>> +  have 8 bit long register line, and the registers are also
>> +  8 bit long each. It is typically used for communicating with
>> +  Samsung PMICs (s2mps17, s2mps18, ...) and other Samsung chips,
>> +  such as RF parts.
>> +
>> +properties:
>> +  compatible:
>> +    - items:
>> +        - enum:
>> +            - samsung,exynos9810-speedy
>> +        - const: samsung,exynos-speedy
> Drop last compatible and use only SoC specific.
Makes sense, for some reason I didn't realise it doesn't make much sense.
>
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    maxItems: 1
>> +
>> +  clock-names:
>> +    - const: pclk
> Drop clock-names, not needed for one entry.
>
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - "#address-cells"
>> +  - "#size-cells"
> You do not have them in the properties, anyway required goes before
> additionalProperties
>
>> +
>> +patternProperties:
>> +  "^[a-z][a-z0-9]*@[0-9a-f]$":
> That's odd regex. Look at other bus bindings.
Okay, I'll look into it.
>
>> +    type: object
>> +    additionalProperties: true
>> +
>> +    properties:
>> +      reg:
>> +        maxItems: 1
> maximum: 15
>
>> +
>> +    required:
>> +      - reg
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    speedy0: speedy at 141c0000 {
> Drop unused label.
>
>> +      compatible = "samsung,exynos9810-speedy",
>> +                   "samsung-exynos-speedy";
>> +      reg = <0x141c0000 0x2000>;
>> +      #address-cells = <1>;
>> +      #size-cells = <0>;
>> +
> No resources? No clocks? No interrupts?
Will extend the example.
>
>
>
> Best regards,
> Krzysztof

- Markuss


[1] https://patents.google.com/patent/US9882711B1/en



From neil.armstrong at linaro.org  Fri Dec 13 01:50:22 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 13 Dec 2024 10:50:22 +0100
Subject: (subset) [PATCH v2 1/2] dt-bindings: display: panel-lvds: Add
 compatible for AUO G084SN05 V9
In-Reply-To: <20241210105705.116116-1-festevam@gmail.com>
References: <20241210105705.116116-1-festevam@gmail.com>
Message-ID: <173408342200.146926.12035228317678634165.b4-ty@linaro.org>

Hi,

On Tue, 10 Dec 2024 07:57:04 -0300, Fabio Estevam wrote:
> The AUO G084SN05 V9 is an 8.4" 800x600 LVDS display.
> 
> Add a compatible entry for this LVDS display model.
> 
> 

Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next)

[1/2] dt-bindings: display: panel-lvds: Add compatible for AUO G084SN05 V9
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/1c64605fd976cd2c7e4f30d826818a8c27924c32

-- 
Neil



From jason-jh.lin at mediatek.com  Fri Dec 13 01:50:42 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 13 Dec 2024 17:50:42 +0800
Subject: [PATCH v2 1/3] dt-bindings: display: mediatek: ovl: Modify rules for MT8195/MT8188
In-Reply-To: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
Message-ID: <20241213095044.23757-2-jason-jh.lin@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.com>

Modify rules for both MT8195 and MT8188.
Hardware capabilities include color formats and AFBC are
changed since MT8195, stop using the settings of MT8183.

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 .../bindings/display/mediatek/mediatek,ovl.yaml          | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index 9ea796a033b2..8ca8e5966b9a 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -26,6 +26,7 @@ properties:
           - mediatek,mt8173-disp-ovl
           - mediatek,mt8183-disp-ovl
           - mediatek,mt8192-disp-ovl
+          - mediatek,mt8195-disp-ovl
           - mediatek,mt8195-mdp3-ovl
       - items:
           - enum:
@@ -36,16 +37,14 @@ properties:
           - enum:
               - mediatek,mt6795-disp-ovl
           - const: mediatek,mt8173-disp-ovl
-      - items:
-          - enum:
-              - mediatek,mt8188-disp-ovl
-              - mediatek,mt8195-disp-ovl
-          - const: mediatek,mt8183-disp-ovl
       - items:
           - enum:
               - mediatek,mt8186-disp-ovl
               - mediatek,mt8365-disp-ovl
           - const: mediatek,mt8192-disp-ovl
+      - items:
+          - const: mediatek,mt8188-disp-ovl
+          - const: mediatek,mt8195-disp-ovl
 
   reg:
     maxItems: 1
-- 
2.43.0



From jason-jh.lin at mediatek.com  Fri Dec 13 01:50:41 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 13 Dec 2024 17:50:41 +0800
Subject: [PATCH v2 0/3] Update MT8188 OVL compatible from MT8183 to MT8195
Message-ID: <20241213095044.23757-1-jason-jh.lin@mediatek.com>

This patch series updates the compatible strings for the MediaTek OVL
in the MT8188 dts and the corresponding dt-binding.
The changes ensure that the MT8188 OVL device is correctly identified
and managed by the appropriate drivers.

The 1st patch is resending the reviewed and acked patch from:
- https://lore.kernel.org/all/5d9e6f6c-604d-4e2d-a448-fc5b8bd24a75 at collabora.com/
and rebase it to the latest linux-next-20241212.

The 2nd and the 3rd patches are updating the mt8188.dtsi and mt8195.dtsi
according to the 1st patch.

---

Change in v2:
1. Add missing mt8195 compatible in the beginning of compatible property.
2. Add fix patch to mt8195.

---

Hsiao Chien Sung (1):
  dt-bindings: display: mediatek: ovl: Modify rules for MT8195/MT8188

Jason-JH.Lin (2):
  dts: arm64: mediatek: mt8188: Update OVL compatible from MT8183 to
    MT8195
  dts: arm64: mediatek: mt8195: Remove MT8183 compatible for OVL

 .../bindings/display/mediatek/mediatek,ovl.yaml          | 9 ++++-----
 arch/arm64/boot/dts/mediatek/mt8188.dtsi                 | 2 +-
 arch/arm64/boot/dts/mediatek/mt8195.dtsi                 | 2 +-
 3 files changed, 6 insertions(+), 7 deletions(-)

-- 
2.43.0



From jason-jh.lin at mediatek.com  Fri Dec 13 01:50:43 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 13 Dec 2024 17:50:43 +0800
Subject: [PATCH v2 2/3] dts: arm64: mediatek: mt8188: Update OVL compatible from MT8183 to MT8195
In-Reply-To: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
Message-ID: <20241213095044.23757-3-jason-jh.lin@mediatek.com>

The OVL hardware capabilities have changed starting from MT8195,
making the MT8183 compatible no longer applicable.
Therefore, it is necessary to update the OVL compatible from MT8183 to
MT8195.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8188.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index faccc7f16259..23ec3ff6cad9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -2488,7 +2488,7 @@ jpeg_decoder: jpeg-decoder at 1a040000 {
 		};
 
 		ovl0: ovl at 1c000000 {
-			compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8183-disp-ovl";
+			compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8195-disp-ovl";
 			reg = <0 0x1c000000 0 0x1000>;
 			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
 			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
-- 
2.43.0



From jason-jh.lin at mediatek.com  Fri Dec 13 01:50:44 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 13 Dec 2024 17:50:44 +0800
Subject: [PATCH v2 3/3] dts: arm64: mediatek: mt8195: Remove MT8183 compatible for OVL
In-Reply-To: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
Message-ID: <20241213095044.23757-4-jason-jh.lin@mediatek.com>

The OVL hardware capabilities have changed starting from MT8195,
making the MT8183 compatible no longer applicable.
Therefore, it is necessary to remove the MT8183 compatible for OVL.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index ade685ed2190..137ee8929e01 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -3138,7 +3138,7 @@ larb20: larb at 1b010000 {
 		};
 
 		ovl0: ovl at 1c000000 {
-			compatible = "mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-ovl";
+			compatible = "mediatek,mt8195-disp-ovl";
 			reg = <0 0x1c000000 0 0x1000>;
 			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
 			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
-- 
2.43.0



From jakobunt at gmail.com  Fri Dec 13 01:54:58 2024
From: jakobunt at gmail.com (Jakob Unterwurzacher)
Date: Fri, 13 Dec 2024 10:54:58 +0100
Subject: [PATCH v4] arm64: dts: rockchip: increase gmac rx_delay on
 rk3399-puma
Message-ID: <20241213-puma_rx_delay-v4-1-8e8e11cc6ed7@cherry.de>

During mass manufacturing, we noticed the mmc_rx_crc_error counter,
as reported by "ethtool -S eth0 | grep mmc_rx_crc_error", to increase
above zero during nuttcp speedtests. Most of the time, this did not
affect the achieved speed, but it prompted this investigation.

Cycling through the rx_delay range on six boards (see table below) of
various ages shows that there is a large good region from 0x12 to 0x35
where we see zero crc errors on all tested boards.

The old rx_delay value (0x10) seems to have always been on the edge for
the KSZ9031RNX that is usually placed on Puma.

Choose "rx_delay = 0x23" to put us smack in the middle of the good
region. This works fine as well with the KSZ9131RNX PHY that was used
for a small number of boards during the COVID chip shortages.

	Board S/N        PHY        rx_delay good region
	---------        ---        --------------------
	Puma TT0069903   KSZ9031RNX 0x11 0x35
	Puma TT0157733   KSZ9031RNX 0x11 0x35
	Puma TT0681551   KSZ9031RNX 0x12 0x37
	Puma TT0681156   KSZ9031RNX 0x10 0x38
	Puma 17496030079 KSZ9031RNX 0x10 0x37 (Puma v1.2 from 2017)
	Puma TT0681720   KSZ9131RNX 0x02 0x39 (alternative PHY used in very few boards)

	Intersection of good regions = 0x12 0x35
	Middle of good region = 0x23

Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")
Cc: stable at vger.kernel.org
Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>
Tested-by: Quentin Schulz <quentin.schulz at cherry.de> # Puma v2.1 and v2.3 with KSZ9031
Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at cherry.de>
---
v4: drop internal Relates-to tag, add Tested-by, rebase to Linus master, send with b4
v3: use rx_delay = 0x23 instead of 0x11, which was not enough.
v2: cc stable, add "Fixes:", add omitted "there" to commit msg,
v1: initial submission
---
 arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
index d12e661dfd9917f820284477a215389c16205f46..995b30a7aae01a0326e9f80d6be930f227968539 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
@@ -182,7 +182,7 @@ &gmac {
 	snps,reset-active-low;
 	snps,reset-delays-us = <0 10000 50000>;
 	tx_delay = <0x10>;
-	rx_delay = <0x10>;
+	rx_delay = <0x23>;
 	status = "okay";
 };
 

---
base-commit: f932fb9b40749d1c9a539d89bb3e288c077aafe5
change-id: 20241213-puma_rx_delay-fadbcdf09783

Best regards,
-- 
Jakob Unterwurzacher <jakob.unterwurzacher at cherry.de>



From jbrunet at baylibre.com  Fri Dec 13 02:03:23 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 13 Dec 2024 11:03:23 +0100
Subject: [PATCH] clk: amlogic: g12a: fix mmc A peripheral clock
Message-ID: <20241213-amlogic-clk-g12a-mmca-fix-v1-1-5af421f58b64@baylibre.com>

The bit index of the peripheral clock for mmc A is wrong
This was probably not a problem for mmc A as the peripheral is likely left
enabled by the bootloader.

No issues has been reported so far but it could be a problem, most likely
some form of conflict between the ethernet and mmc A clock, breaking
ethernet on init.

Use the value provided by the documentation for mmc A before this
becomes an actual problem.

Fixes: 085a4ea93d54 ("clk: meson: g12a: add peripheral clock controller")
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/clk/meson/g12a.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index d3539fe9f7af5538201a78ce560f662ddb3935f2..20be7b037c07535bd2115f6e70404a95a7832756 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -4311,7 +4311,7 @@ static MESON_GATE(g12a_spicc_1,			HHI_GCLK_MPEG0,	14);
 static MESON_GATE(g12a_hiu_reg,			HHI_GCLK_MPEG0,	19);
 static MESON_GATE(g12a_mipi_dsi_phy,		HHI_GCLK_MPEG0,	20);
 static MESON_GATE(g12a_assist_misc,		HHI_GCLK_MPEG0,	23);
-static MESON_GATE(g12a_emmc_a,			HHI_GCLK_MPEG0,	4);
+static MESON_GATE(g12a_emmc_a,			HHI_GCLK_MPEG0,	24);
 static MESON_GATE(g12a_emmc_b,			HHI_GCLK_MPEG0,	25);
 static MESON_GATE(g12a_emmc_c,			HHI_GCLK_MPEG0,	26);
 static MESON_GATE(g12a_audio_codec,		HHI_GCLK_MPEG0,	28);

---
base-commit: 52fd1709e41d3a85b48bcfe2404a024ebaf30c3b
change-id: 20241213-amlogic-clk-g12a-mmca-fix-c9ebacf34d9c

Best regards,
-- 
Jerome



From quic_taozha at quicinc.com  Fri Dec 13 02:07:27 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 13 Dec 2024 18:07:27 +0800
Subject: [PATCH v7 0/4] source filtering for multi-port output
Message-ID: <20241213100731.25914-1-quic_taozha@quicinc.com>

In our hardware design, by combining a funnel and a replicator, it
implement a hardware device with one-to-one correspondence between
output ports and input ports. The programming usage on this device
is the same as funnel. The software uses a funnel and a static
replicator to implement the driver of this device. Since original
funnels only support a single output connection and original
replicator only support a single input connection, the code needs
to be modified to support this new feature. The following is a
typical topology diagram of multi-port output mechanism.
|----------|     |---------|     |----------|   |---------|
|  TPDM 0  |     | Source0 |     | Source 1 |   | TPDM 1  |
|----------|     |---------|     |----------|   |---------|
      |                |                |             |
      |                |                |             |
      |      --------- |                |             |
      |      |                          |             |
      |      |                          |             |
      |      |                          |             |
   \-------------/ ----------------------             |
    \  Funnel 0 /  |                                  |
     -----------   |     ------------------------------
          |        |     |
          |        |     |
        \------------------/
         \    Funnel 1    /     ----|
          \--------------/          |
                  |                 |----> Combine a funnel and a
                  |                 |      static replicator
          /-----------------\       |
         /    replicator 0   \  ----|
        /---------------------\
             |     |      |
             |     |      |-----------|
             |     |---------|        |
             |               |TPDM0   |TPDM1
             |            \-----------------/
             |             \   TPDA 0      /
             |              \-------------/
             |                    |
             |                    |
             |Source0/1           |
          \-------------------------------/
           \           Funnel 2          /
            \---------------------------/

Changes in V7:
1. Correct the use of incorrect characters.
-- Suzuki K Poulose
2. Rebase the series on v6.13-rc1
-- Suzuki K Poulose

Changes in V6:
1. Optimize the prompt content of the warning log
when the filter handle is not a trace source.
-- Suzuki K Poulose
2. Reset the filter device and fwnode if it is not
a trace source.
-- Suzuki K Poulose

Changes in V5:
1. Replace "filter-src" with "filter-source" in the
dt-binding document.
-- Suzuki K Poulose
2. Optimize the comments of the patch "coresight:
Add support for trace filtering by source" due to bad
example.
-- Suzuki K Poulose
3. Correct spelling errors in the patch "coresight:
Add support for trace filtering by source".
-- Suzuki K Poulose
4. Optimize the function "coresight_blocks_source".
-- Suzuki K Poulose
5. Add { } in the function "of_coresight_parse_endpoint".
-- Suzuki K Poulose
6. Adjust the order of the patches.
-- Suzuki K Poulose
7. Adjust the alignment in "coresight-platform.c".
-- Suzuki K Poulose

Changes in V4:
1. Use "coresight_get_source(path)" in the function
"coresight_disable_path_from" instead of explicitly
passing the source.
-- Suzuki K Poulose
2. Optimize the order of the input parameters for
"_coresight_build_path".
-- Suzuki K Poulose
3. Reuse the method "coresight_block_source" in
"_coresight_build_path".
-- Suzuki K Poulose
4. Remove the unnecessary () in "coresight_build_path".
-- Suzuki K Poulose
5. Add a helper to check if a device is SOURCE.
-- Suzuki K Poulose
6. Adjust the posistion of setting "still_orphan" in
"coresight_build_path".
-- Suzuki K Poulose

Changes in V3:
1. Rename the function "coresight_source_filter" to
"coresight_block_source". And refine this function.
-- Suzuki K Poulose
2. Rename the parameters of the function
"coresight_find_out_connection" to avoid confusion.
-- Suzuki K Poulose
3. Get the source of path in "coresight_enable_path" and
"coresight_disable_path".
-- Suzuki K Poulose
4. Fix filter source device before skip the port in
"coresight_orphan_match".
-- Suzuki K Poulose
5. Make sure the device still orphan if whter is a filter
source firmware node but the filter source device is null.
-- Suzuki K Poulose
6. Walk through the entire coresight bus and fixup the
"filter_src_dev" if the source is being removed.
-- Suzuki K Poulose
7. Refine the commit description of patch#2.
-- Suzuki K Poulose
8. Fix the warning reported by kernel test robot.
-- kernel test robot.
9. Use the source device directly if the port has a
hardcoded filter in "tpda_get_element_size".
-- Suzuki K Poulose

Changes in V2:
1. Change the reference for endpoint property in dt-binding.
-- Krzysztof Kozlowski
2. Change the property name "filter_src" to "filter-src".
-- Krzysztof Kozlowski
3. Fix the errors in running 'make dt_binding_check'.
-- Rob Herring
4. Pass in the source parameter instead of path.
-- Suzuki K Poulose
5. Reset the "filter_src_dev" if the "src" csdev is being removed.
-- Suzuki K Poulose
6. Add a warning if the "filter_src_dev" is of not the
type DEV_TYPE_SOURCE.
-- Suzuki K Poulose
7. Optimize the procedure for handling all possible cases.
-- Suzuki K Poulose

Changes in V1:
1. Add a static replicator connect to a funnel to implement the
correspondence between the output ports and the input ports on
funnels.
-- Suzuki K Poulose
2. Add filter_src_dev and filter_src_dev phandle to
"coresight_connection" struct, and populate them if there is one.
-- Suzuki K Poulose
3. To look at the phandle and then fixup/remove the filter_src
device in fixup/remove connections.
-- Suzuki K Poulose
4. When TPDA reads DSB/CMB element size, it is implemented by
looking up filter src device in the connections.
-- Suzuki K Poulose

Tao Zhang (4):
  dt-bindings: arm: qcom,coresight-static-replicator: Add property for
    source filtering
  coresight: Add a helper to check if a device is source
  coresight: Add support for trace filtering by source
  coresight-tpda: Optimize the function of reading element size

 .../arm/arm,coresight-static-replicator.yaml  |  19 ++-
 drivers/hwtracing/coresight/coresight-core.c  | 113 +++++++++++++++---
 .../hwtracing/coresight/coresight-platform.c  |  21 ++++
 drivers/hwtracing/coresight/coresight-tpda.c  |  13 +-
 include/linux/coresight.h                     |  12 +-
 5 files changed, 155 insertions(+), 23 deletions(-)

-- 
2.17.1



From quic_taozha at quicinc.com  Fri Dec 13 02:07:28 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 13 Dec 2024 18:07:28 +0800
Subject: [PATCH v7 1/4] dt-bindings: arm: qcom,coresight-static-replicator: Add property for source filtering
In-Reply-To: <20241213100731.25914-1-quic_taozha@quicinc.com>
References: <20241213100731.25914-1-quic_taozha@quicinc.com>
Message-ID: <20241213100731.25914-2-quic_taozha@quicinc.com>

The is some "magic" hard coded filtering in the replicators,
which only passes through trace from a particular "source". Add
a new property "filter-source" to label a phandle to the coresight
trace source device matching the hard coded filtering for the port.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../arm/arm,coresight-static-replicator.yaml  | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
index 1892a091ac35..a6f793ea03b6 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
@@ -45,7 +45,22 @@ properties:
     patternProperties:
       '^port@[01]$':
         description: Output connections to CoreSight Trace bus
-        $ref: /schemas/graph.yaml#/properties/port
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+
+        properties:
+          endpoint:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            unevaluatedProperties: false
+
+            properties:
+              filter-source:
+                $ref: /schemas/types.yaml#/definitions/phandle
+                description:
+                  phandle to the coresight trace source device matching the
+                  hard coded filtering for this port
+
+              remote-endpoint: true
 
 required:
   - compatible
@@ -72,6 +87,7 @@ examples:
                 reg = <0>;
                 replicator_out_port0: endpoint {
                     remote-endpoint = <&etb_in_port>;
+                    filter-source = <&tpdm_video>;
                 };
             };
 
@@ -79,6 +95,7 @@ examples:
                 reg = <1>;
                 replicator_out_port1: endpoint {
                     remote-endpoint = <&tpiu_in_port>;
+                    filter-source = <&tpdm_mdss>;
                 };
             };
         };
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Dec 13 02:07:29 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 13 Dec 2024 18:07:29 +0800
Subject: [PATCH v7 2/4] coresight: Add a helper to check if a device is source
In-Reply-To: <20241213100731.25914-1-quic_taozha@quicinc.com>
References: <20241213100731.25914-1-quic_taozha@quicinc.com>
Message-ID: <20241213100731.25914-3-quic_taozha@quicinc.com>

Since there are a lot of places in the code to check whether the
device is source, add a helper to check it.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpda.c | 2 +-
 include/linux/coresight.h                    | 7 ++++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 4ec676bea1ce..ab94067c0ed3 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -24,7 +24,7 @@ DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda");
 
 static bool coresight_device_is_tpdm(struct coresight_device *csdev)
 {
-	return (csdev->type == CORESIGHT_DEV_TYPE_SOURCE) &&
+	return (coresight_is_device_source(csdev)) &&
 	       (csdev->subtype.source_subtype ==
 			CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
 }
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 055ce5cd5c44..c50d128e8d93 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -588,9 +588,14 @@ static inline void csdev_access_write64(struct csdev_access *csa, u64 val, u32 o
 }
 #endif	/* CONFIG_64BIT */
 
+static inline bool coresight_is_device_source(struct coresight_device *csdev)
+{
+	return csdev && (csdev->type == CORESIGHT_DEV_TYPE_SOURCE);
+}
+
 static inline bool coresight_is_percpu_source(struct coresight_device *csdev)
 {
-	return csdev && (csdev->type == CORESIGHT_DEV_TYPE_SOURCE) &&
+	return csdev && coresight_is_device_source(csdev) &&
 	       (csdev->subtype.source_subtype == CORESIGHT_DEV_SUBTYPE_SOURCE_PROC);
 }
 
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Dec 13 02:07:31 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 13 Dec 2024 18:07:31 +0800
Subject: [PATCH v7 4/4] coresight-tpda: Optimize the function of reading element size
In-Reply-To: <20241213100731.25914-1-quic_taozha@quicinc.com>
References: <20241213100731.25914-1-quic_taozha@quicinc.com>
Message-ID: <20241213100731.25914-5-quic_taozha@quicinc.com>

Since the new funnel device supports multi-port output scenarios,
there may be more than one TPDM connected to one TPDA. In this
way, when reading the element size of the TPDM, TPDA driver needs
to find the expected TPDM corresponding to the filter source.
When TPDA finds a TPDM or a filter source from a input connection,
it will read the Devicetree to get the expected TPDM's element
size.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpda.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index ab94067c0ed3..189a4abc2561 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -110,6 +110,16 @@ static int tpda_get_element_size(struct tpda_drvdata *drvdata,
 		    csdev->pdata->in_conns[i]->dest_port != inport)
 			continue;
 
+		/*
+		 * If this port has a hardcoded filter, use the source
+		 * device directly.
+		 */
+		if (csdev->pdata->in_conns[i]->filter_src_fwnode) {
+			in = csdev->pdata->in_conns[i]->filter_src_dev;
+			if (!in)
+				continue;
+		}
+
 		if (coresight_device_is_tpdm(in)) {
 			if (drvdata->dsb_esize || drvdata->cmb_esize)
 				return -EEXIST;
@@ -124,7 +134,6 @@ static int tpda_get_element_size(struct tpda_drvdata *drvdata,
 		}
 	}
 
-
 	return rc;
 }
 
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Dec 13 02:07:30 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 13 Dec 2024 18:07:30 +0800
Subject: [PATCH v7 3/4] coresight: Add support for trace filtering by source
In-Reply-To: <20241213100731.25914-1-quic_taozha@quicinc.com>
References: <20241213100731.25914-1-quic_taozha@quicinc.com>
Message-ID: <20241213100731.25914-4-quic_taozha@quicinc.com>

Some replicators have hard coded filtering of "trace" data, based on the
source device. This is different from the trace filtering based on
TraceID, available in the standard programmable replicators. e.g.,
Qualcomm replicators have filtering based on custom trace protocol
format and is not programmable.

The source device could be connected to the replicator via intermediate
components (e.g., a funnel). Thus we need platform information from
the firmware tables to decide the source device corresponding to a
given output port from the replicator. Given this affects "trace
path building" and traversing the path back from the sink to source,
add the concept of "filtering by source" to the generic coresight
connection.

The specified source will be marked like below in the Devicetree.
test-replicator {
    ... ... ... ...
    out-ports {
        ... ... ... ...
        port at 0 {
            reg = <0>;
            xyz: endpoint {
                remote-endpoint = <&zyx>;
                filter-source = <&source_1>; <-- To specify the source to
            };                           be filtered out here.
        };

        port at 1 {
            reg = <1>;
            abc: endpoint {
                remote-endpoint = <&cba>;
                filter-source = <&source_2>; <-- To specify the source to
            };                           be filtered out here.
        };
    };
};

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-core.c  | 113 +++++++++++++++---
 .../hwtracing/coresight/coresight-platform.c  |  21 ++++
 include/linux/coresight.h                     |   5 +
 3 files changed, 120 insertions(+), 19 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index ea38ecf26fcb..0a9380350fb5 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -75,22 +75,54 @@ struct coresight_device *coresight_get_percpu_sink(int cpu)
 }
 EXPORT_SYMBOL_GPL(coresight_get_percpu_sink);
 
+static struct coresight_device *coresight_get_source(struct list_head *path)
+{
+	struct coresight_device *csdev;
+
+	if (!path)
+		return NULL;
+
+	csdev = list_first_entry(path, struct coresight_node, link)->csdev;
+	if (!coresight_is_device_source(csdev))
+		return NULL;
+
+	return csdev;
+}
+
+/**
+ * coresight_blocks_source - checks whether the connection matches the source
+ * of path if connection is bound to specific source.
+ * @src:	The source device of the trace path
+ * @conn:	The connection of one outport
+ *
+ * Return false if the connection doesn't have a source binded or source of the
+ * path matches the source binds to connection.
+ */
+static bool coresight_blocks_source(struct coresight_device *src,
+				    struct coresight_connection *conn)
+{
+	return conn->filter_src_fwnode && (conn->filter_src_dev != src);
+}
+
 static struct coresight_connection *
-coresight_find_out_connection(struct coresight_device *src_dev,
-			      struct coresight_device *dest_dev)
+coresight_find_out_connection(struct coresight_device *csdev,
+			      struct coresight_device *out_dev,
+			      struct coresight_device *trace_src)
 {
 	int i;
 	struct coresight_connection *conn;
 
-	for (i = 0; i < src_dev->pdata->nr_outconns; i++) {
-		conn = src_dev->pdata->out_conns[i];
-		if (conn->dest_dev == dest_dev)
+	for (i = 0; i < csdev->pdata->nr_outconns; i++) {
+		conn = csdev->pdata->out_conns[i];
+		if (coresight_blocks_source(trace_src, conn))
+			continue;
+		if (conn->dest_dev == out_dev)
 			return conn;
 	}
 
-	dev_err(&src_dev->dev,
-		"couldn't find output connection, src_dev: %s, dest_dev: %s\n",
-		dev_name(&src_dev->dev), dev_name(&dest_dev->dev));
+	dev_err(&csdev->dev,
+		"couldn't find output connection, csdev: %s, out_dev: %s\n",
+		dev_name(&csdev->dev), dev_name(&out_dev->dev));
 
 	return ERR_PTR(-ENODEV);
 }
@@ -251,7 +283,8 @@ static void coresight_disable_sink(struct coresight_device *csdev)
 
 static int coresight_enable_link(struct coresight_device *csdev,
 				 struct coresight_device *parent,
-				 struct coresight_device *child)
+				 struct coresight_device *child,
+				 struct coresight_device *source)
 {
 	int link_subtype;
 	struct coresight_connection *inconn, *outconn;
@@ -259,8 +292,8 @@ static int coresight_enable_link(struct coresight_device *csdev,
 	if (!parent || !child)
 		return -EINVAL;
 
-	inconn = coresight_find_out_connection(parent, csdev);
-	outconn = coresight_find_out_connection(csdev, child);
+	inconn = coresight_find_out_connection(parent, csdev, source);
+	outconn = coresight_find_out_connection(csdev, child, source);
 	link_subtype = csdev->subtype.link_subtype;
 
 	if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && IS_ERR(inconn))
@@ -273,15 +306,16 @@ static int coresight_enable_link(struct coresight_device *csdev,
 
 static void coresight_disable_link(struct coresight_device *csdev,
 				   struct coresight_device *parent,
-				   struct coresight_device *child)
+				   struct coresight_device *child,
+				   struct coresight_device *source)
 {
 	struct coresight_connection *inconn, *outconn;
 
 	if (!parent || !child)
 		return;
 
-	inconn = coresight_find_out_connection(parent, csdev);
-	outconn = coresight_find_out_connection(csdev, child);
+	inconn = coresight_find_out_connection(parent, csdev, source);
+	outconn = coresight_find_out_connection(csdev, child, source);
 
 	link_ops(csdev)->disable(csdev, inconn, outconn);
 }
@@ -375,7 +409,8 @@ static void coresight_disable_path_from(struct list_head *path,
 		case CORESIGHT_DEV_TYPE_LINK:
 			parent = list_prev_entry(nd, link)->csdev;
 			child = list_next_entry(nd, link)->csdev;
-			coresight_disable_link(csdev, parent, child);
+			coresight_disable_link(csdev, parent, child,
+					       coresight_get_source(path));
 			break;
 		default:
 			break;
@@ -418,7 +453,9 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
 	u32 type;
 	struct coresight_node *nd;
 	struct coresight_device *csdev, *parent, *child;
+	struct coresight_device *source;
 
+	source = coresight_get_source(path);
 	list_for_each_entry_reverse(nd, path, link) {
 		csdev = nd->csdev;
 		type = csdev->type;
@@ -456,7 +493,7 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
 		case CORESIGHT_DEV_TYPE_LINK:
 			parent = list_prev_entry(nd, link)->csdev;
 			child = list_next_entry(nd, link)->csdev;
-			ret = coresight_enable_link(csdev, parent, child);
+			ret = coresight_enable_link(csdev, parent, child, source);
 			if (ret)
 				goto err;
 			break;
@@ -619,6 +656,7 @@ static void coresight_drop_device(struct coresight_device *csdev)
 /**
  * _coresight_build_path - recursively build a path from a @csdev to a sink.
  * @csdev:	The device to start from.
+ * @source:	The trace source device of the path.
  * @sink:	The final sink we want in this path.
  * @path:	The list to add devices to.
  *
@@ -628,6 +666,7 @@ static void coresight_drop_device(struct coresight_device *csdev)
  * the source is the first device and the sink the last one.
  */
 static int _coresight_build_path(struct coresight_device *csdev,
+				 struct coresight_device *source,
 				 struct coresight_device *sink,
 				 struct list_head *path)
 {
@@ -641,7 +680,7 @@ static int _coresight_build_path(struct coresight_device *csdev,
 
 	if (coresight_is_percpu_source(csdev) && coresight_is_percpu_sink(sink) &&
 	    sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) {
-		if (_coresight_build_path(sink, sink, path) == 0) {
+		if (_coresight_build_path(sink, source, sink, path) == 0) {
 			found = true;
 			goto out;
 		}
@@ -652,8 +691,12 @@ static int _coresight_build_path(struct coresight_device *csdev,
 		struct coresight_device *child_dev;
 
 		child_dev = csdev->pdata->out_conns[i]->dest_dev;
+
+		if (coresight_blocks_source(source, csdev->pdata->out_conns[i]))
+			continue;
+
 		if (child_dev &&
-		    _coresight_build_path(child_dev, sink, path) == 0) {
+		    _coresight_build_path(child_dev, source, sink, path) == 0) {
 			found = true;
 			break;
 		}
@@ -698,7 +741,7 @@ struct list_head *coresight_build_path(struct coresight_device *source,
 
 	INIT_LIST_HEAD(path);
 
-	rc = _coresight_build_path(source, sink, path);
+	rc = _coresight_build_path(source, source, sink, path);
 	if (rc) {
 		kfree(path);
 		return ERR_PTR(rc);
@@ -927,6 +970,16 @@ static int coresight_orphan_match(struct device *dev, void *data)
 	for (i = 0; i < src_csdev->pdata->nr_outconns; i++) {
 		conn = src_csdev->pdata->out_conns[i];
 
+		/* Fix filter source device before skip the port */
+		if (conn->filter_src_fwnode && !conn->filter_src_dev) {
+			if (dst_csdev &&
+			    (conn->filter_src_fwnode == dst_csdev->dev.fwnode) &&
+			    !WARN_ON_ONCE(!coresight_is_device_source(dst_csdev)))
+				conn->filter_src_dev = dst_csdev;
+			else
+				still_orphan = true;
+		}
+
 		/* Skip the port if it's already connected. */
 		if (conn->dest_dev)
 			continue;
@@ -977,18 +1030,40 @@ static int coresight_fixup_orphan_conns(struct coresight_device *csdev)
 			 csdev, coresight_orphan_match);
 }
 
+static int coresight_clear_filter_source(struct device *dev, void *data)
+{
+	int i;
+	struct coresight_device *source = data;
+	struct coresight_device *csdev = to_coresight_device(dev);
+
+	for (i = 0; i < csdev->pdata->nr_outconns; ++i) {
+		if (csdev->pdata->out_conns[i]->filter_src_dev == source)
+			csdev->pdata->out_conns[i]->filter_src_dev = NULL;
+	}
+	return 0;
+}
+
 /* coresight_remove_conns - Remove other device's references to this device */
 static void coresight_remove_conns(struct coresight_device *csdev)
 {
 	int i, j;
 	struct coresight_connection *conn;
 
+	if (coresight_is_device_source(csdev))
+		bus_for_each_dev(&coresight_bustype, NULL, csdev,
+				 coresight_clear_filter_source);
+
 	/*
 	 * Remove the input connection references from the destination device
 	 * for each output connection.
 	 */
 	for (i = 0; i < csdev->pdata->nr_outconns; i++) {
 		conn = csdev->pdata->out_conns[i];
+		if (conn->filter_src_fwnode) {
+			conn->filter_src_dev = NULL;
+			fwnode_handle_put(conn->filter_src_fwnode);
+		}
+
 		if (!conn->dest_dev)
 			continue;
 
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
index 633d96b9577a..8192ba3279f0 100644
--- a/drivers/hwtracing/coresight/coresight-platform.c
+++ b/drivers/hwtracing/coresight/coresight-platform.c
@@ -243,6 +243,27 @@ static int of_coresight_parse_endpoint(struct device *dev,
 		conn.dest_fwnode = fwnode_handle_get(rdev_fwnode);
 		conn.dest_port = rendpoint.port;
 
+		/*
+		 * Get the firmware node of the filter source through the
+		 * reference. This could be used to filter the source in
+		 * building path.
+		 */
+		conn.filter_src_fwnode =
+			fwnode_find_reference(&ep->fwnode, "filter-source", 0);
+		if (IS_ERR(conn.filter_src_fwnode)) {
+			conn.filter_src_fwnode = NULL;
+		} else {
+			conn.filter_src_dev =
+			 coresight_find_csdev_by_fwnode(conn.filter_src_fwnode);
+			if (conn.filter_src_dev &&
+			    !coresight_is_device_source(conn.filter_src_dev)) {
+				dev_warn(dev, "port %d: Filter handle is not a trace source : %s\n",
+					 conn.src_port, dev_name(&conn.filter_src_dev->dev));
+				conn.filter_src_dev = NULL;
+				conn.filter_src_fwnode = NULL;
+			}
+		}
+
 		new_conn = coresight_add_out_conn(dev, pdata, &conn);
 		if (IS_ERR_VALUE(new_conn)) {
 			fwnode_handle_put(conn.dest_fwnode);
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index c50d128e8d93..17276965ff1d 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -172,6 +172,9 @@ struct coresight_desc {
  * @dest_dev:	a @coresight_device representation of the component
 		connected to @src_port. NULL until the device is created
  * @link: Representation of the connection as a sysfs link.
+ * @filter_src_fwnode: filter source component's fwnode handle.
+ * @filter_src_dev: a @coresight_device representation of the component that
+		needs to be filtered.
  *
  * The full connection structure looks like this, where in_conns store
  * references to same connection as the source device's out_conns.
@@ -200,6 +203,8 @@ struct coresight_connection {
 	struct coresight_device *dest_dev;
 	struct coresight_sysfs_link *link;
 	struct coresight_device *src_dev;
+	struct fwnode_handle *filter_src_fwnode;
+	struct coresight_device *filter_src_dev;
 	int src_refcnt;
 	int dest_refcnt;
 };
-- 
2.17.1



From quic_luoj at quicinc.com  Fri Dec 13 02:19:40 2024
From: quic_luoj at quicinc.com (Jie Luo)
Date: Fri, 13 Dec 2024 18:19:40 +0800
Subject: [PATCH v6 2/5] clk: qcom: Add CMN PLL clock controller driver for
 IPQ SoC
In-Reply-To: <7f0f2ad6-7895-46f8-8f80-0375dde2e763@oss.qualcomm.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-2-a5cfe09de485@quicinc.com>
 <7f0f2ad6-7895-46f8-8f80-0375dde2e763@oss.qualcomm.com>
Message-ID: <a3ddacc9-73cd-4214-9a39-5aaaa91fc93e@quicinc.com>



On 12/13/2024 2:30 AM, Konrad Dybcio wrote:
> On 7.11.2024 10:50 AM, Luo Jie wrote:
>> The CMN PLL clock controller supplies clocks to the hardware
>> blocks that together make up the Ethernet function on Qualcomm
>> IPQ SoCs and to GCC. The driver is initially supported for
>> IPQ9574 SoC.
>>
>> The CMN PLL clock controller expects a reference input clock
>> from the on-board Wi-Fi block acting as clock source. The input
>> reference clock needs to be configured to one of the supported
>> clock rates.
>>
>> The controller supplies a number of fixed-rate output clocks.
>> For the IPQ9574, there is one output clock of 353 MHZ to PPE
>> (Packet Process Engine) hardware block, three 50 MHZ output
>> clocks and an additional 25 MHZ output clock supplied to the
>> connected Ethernet devices. The PLL also supplies a 24 MHZ
>> clock as XO and a 32 KHZ sleep clock to GCC, and one 31.25
>> MHZ clock to PCS.
>>
>> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
>> ---
> 
> [...]
> 
>> +	/* Enable PLL locked detect. */
>> +	ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_CTRL,
>> +				 CMN_PLL_CTRL_LOCK_DETECT_EN,
>> +				 CMN_PLL_CTRL_LOCK_DETECT_EN);
>> +	if (ret)
> 
> you can streamline these with regmap_set/clear_bits

Ok, thanks, I will update to use it.

> 
>> +		return ret;
>> +
>> +	/*
>> +	 * Reset the CMN PLL block to ensure the updated configurations
>> +	 * take effect.
>> +	 */
>> +	ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
>> +				 CMN_ANA_EN_SW_RSTN, 0);
>> +	if (ret)
>> +		return ret;
>> +
>> +	usleep_range(1000, 1200);
>> +	ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
>> +				 CMN_ANA_EN_SW_RSTN, CMN_ANA_EN_SW_RSTN);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* Stability check of CMN PLL output clocks. */
>> +	return regmap_read_poll_timeout(cmn_pll->regmap, CMN_PLL_LOCKED, val,
>> +					(val & CMN_PLL_CLKS_LOCKED),
>> +					100, 100 * USEC_PER_MSEC);
>> +}
> 
> [...]
> 
>> +static int ipq_cmn_pll_clk_probe(struct platform_device *pdev)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	int ret;
>> +
>> +	ret = devm_pm_runtime_enable(dev);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = devm_pm_clk_create(dev);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/*
>> +	 * To access the CMN PLL registers, the GCC AHB & SYSY clocks
> 
> SYS?
> 
> Konrad

Yes, I will correct it.



From treapking at chromium.org  Fri Dec 13 02:26:23 2024
From: treapking at chromium.org (Pin-yen Lin)
Date: Fri, 13 Dec 2024 18:26:23 +0800
Subject: [PATCH v2 2/3] dts: arm64: mediatek: mt8188: Update OVL
 compatible from MT8183 to MT8195
In-Reply-To: <20241213095044.23757-3-jason-jh.lin@mediatek.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com> <20241213095044.23757-3-jason-jh.lin@mediatek.com>
Message-ID: <CAEXTbpcp31oWOCh2c41QbWOc5F_gpD1Bia0NiZeVyDbqKo98Lw@mail.gmail.com>

Hi Jason,

On Fri, Dec 13, 2024 at 5:50?PM Jason-JH.Lin <jason-jh.lin at mediatek.com> wrote:
>
> The OVL hardware capabilities have changed starting from MT8195,
> making the MT8183 compatible no longer applicable.
> Therefore, it is necessary to update the OVL compatible from MT8183 to
> MT8195.

This probably doesn't need an (immediate) respin, but this patch needs:

Fixes: 7075b21d1a8e ("arm64: dts: mediatek: mt8188: Add display nodes
for vdosys0")
>
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt8188.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> index faccc7f16259..23ec3ff6cad9 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
> @@ -2488,7 +2488,7 @@ jpeg_decoder: jpeg-decoder at 1a040000 {
>                 };
>
>                 ovl0: ovl at 1c000000 {
> -                       compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8183-disp-ovl";
> +                       compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8195-disp-ovl";
>                         reg = <0 0x1c000000 0 0x1000>;
>                         clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
>                         interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
> --
> 2.43.0
>

Regards,
Pin-yen


From treapking at chromium.org  Fri Dec 13 02:27:27 2024
From: treapking at chromium.org (Pin-yen Lin)
Date: Fri, 13 Dec 2024 18:27:27 +0800
Subject: [PATCH v2 3/3] dts: arm64: mediatek: mt8195: Remove MT8183
 compatible for OVL
In-Reply-To: <20241213095044.23757-4-jason-jh.lin@mediatek.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com> <20241213095044.23757-4-jason-jh.lin@mediatek.com>
Message-ID: <CAEXTbpfOv876s3NLTO3oMTtVi_BwBtgb-816Gt5ZjKMjTZZKQg@mail.gmail.com>

Hi Jason,

On Fri, Dec 13, 2024 at 5:50?PM Jason-JH.Lin <jason-jh.lin at mediatek.com> wrote:
>
> The OVL hardware capabilities have changed starting from MT8195,
> making the MT8183 compatible no longer applicable.
> Therefore, it is necessary to remove the MT8183 compatible for OVL.

Similar to patch 2/3, we need a:

Fixes: b852ee68fd72 ("arm64: dts: mt8195: Add display node for vdosys0")

>
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt8195.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> index ade685ed2190..137ee8929e01 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> @@ -3138,7 +3138,7 @@ larb20: larb at 1b010000 {
>                 };
>
>                 ovl0: ovl at 1c000000 {
> -                       compatible = "mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-ovl";
> +                       compatible = "mediatek,mt8195-disp-ovl";
>                         reg = <0 0x1c000000 0 0x1000>;
>                         interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
>                         power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> --
> 2.43.0
>

Regards,
Pin-yen


From quic_luoj at quicinc.com  Fri Dec 13 02:28:39 2024
From: quic_luoj at quicinc.com (Jie Luo)
Date: Fri, 13 Dec 2024 18:28:39 +0800
Subject: [PATCH v6 4/5] arm64: dts: qcom: Add CMN PLL node for IPQ9574 SoC
In-Reply-To: <22491b41-f081-45cc-8766-6b4c851516f4@oss.qualcomm.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-4-a5cfe09de485@quicinc.com>
 <22491b41-f081-45cc-8766-6b4c851516f4@oss.qualcomm.com>
Message-ID: <0b9a1e91-a3bb-4cff-96b8-7c5e853354a1@quicinc.com>



On 12/13/2024 2:32 AM, Konrad Dybcio wrote:
> On 7.11.2024 10:50 AM, Luo Jie wrote:
>> The CMN PLL clock controller allows selection of an input clock rate
>> from a defined set of input clock rates. It in-turn supplies fixed
>> rate output clocks to the hardware blocks that provide the ethernet
>> functions such as PPE (Packet Process Engine) and connected switch or
>> PHY, and to GCC.
>>
>> The reference clock of CMN PLL is routed from XO to the CMN PLL through
>> the internal WiFi block.
>> .XO (48 MHZ or 96 MHZ)-->WiFi (multiplier/divider)-->48 MHZ to CMN PLL.
>>
>> The reference input clock from WiFi to CMN PLL is fully controlled by
>> the bootstrap pins which select the XO frequency (48 MHZ or 96 MHZ).
>> Based on this frequency, the divider in the internal Wi-Fi block is
>> automatically configured by hardware (1 for 48 MHZ, 2 for 96 MHZ), to
>> ensure output clock to CMN PLL is 48 MHZ.
>>
>> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
>> ---
>>   arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 16 ++++++++++++++-
>>   arch/arm64/boot/dts/qcom/ipq9574.dtsi            | 26 +++++++++++++++++++++++-
>>   2 files changed, 40 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>> index 91e104b0f865..78f6a2e053d5 100644
>> --- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>> @@ -3,7 +3,7 @@
>>    * IPQ9574 RDP board common device tree source
>>    *
>>    * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
>> - * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
>> + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
>>    */
>>   
>>   /dts-v1/;
>> @@ -164,6 +164,20 @@ &usb3 {
>>   	status = "okay";
>>   };
>>   
>> +/*
>> + * The bootstrap pins for the board select the XO clock frequency,
>> + * which automatically enables the right dividers to ensure the
>> + * reference clock output from WiFi is 48 MHZ.
> 
> I'm a bit puzzled by this comment. Does it mean this clock could
> run at some different speeds?

The reference clock of CMN PLL is routed from XO to the CMN PLL through
the internal WiFi block.

.XO (48 MHZ or 96 MHZ)-->WiFi (multiplier/divider)-->48 MHZ to CMN PLL.

The CMN PLL reference clock from WiFi always runs at 48 MHZ on IPQ9574,
but the XO clock could be 48 MHZ or 96 MHZ on different IPQ9574 boards.
The bootstrap pins select the right divider to ensure eventual clock
rate from Wi-Fi is always 48 MHZ.

To avoid confusion, I will update this comment to mention that the
XO clock frequency could run at 48 MHZ or 96 MHZ.

> 
> [...]
> 
>>   
>> +		cmn_pll: clock-controller at 9b000 {
>> +			compatible = "qcom,ipq9574-cmn-pll";
>> +			reg = <0x0009b000 0x800>;
>> +			clocks = <&ref_48mhz_clk>,
>> +				 <&gcc GCC_CMN_12GPLL_AHB_CLK>,
>> +				 <&gcc GCC_CMN_12GPLL_SYS_CLK>;
>> +			clock-names = "ref", "ahb", "sys";
>> +			#clock-cells = <1>;
>> +			assigned-clocks = <&cmn_pll CMN_PLL_CLK>;
>> +			assigned-clock-rates-u64 = /bits/ 64 <12000000000>;
> 
> Does devlink not complain about self-referencing the clock here?
> 
> Konrad

This code is validated on IPQ9574 RDP433 reference board, there is no
complaint reported about this self-referencing the clock of the clock
supplier DT node. It seems the API of_clk_set_defaults(struct
device_node *node, bool clk_supplier) called by this DT property
"assigned-clocks" allows this kind of self-reference.



From quic_luoj at quicinc.com  Fri Dec 13 02:30:25 2024
From: quic_luoj at quicinc.com (Jie Luo)
Date: Fri, 13 Dec 2024 18:30:25 +0800
Subject: [PATCH v6 5/5] arm64: dts: qcom: Update IPQ9574 xo_board_clk to
 use fixed factor clock
In-Reply-To: <0776a26e-56cd-4838-9b52-210ae9a1f281@oss.qualcomm.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-5-a5cfe09de485@quicinc.com>
 <0776a26e-56cd-4838-9b52-210ae9a1f281@oss.qualcomm.com>
Message-ID: <8063460d-18ad-4e54-8232-716bad9d37c3@quicinc.com>



On 12/13/2024 2:33 AM, Konrad Dybcio wrote:
> On 7.11.2024 10:50 AM, Luo Jie wrote:
>> xo_board_clk is fixed to 24 MHZ, which is routed from WiFi output clock
>> 48 MHZ (also being the reference clock of CMN PLL) divided 2 by analog
>> block routing channel.
>>
>> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
>> ---
>>   arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 7 ++++++-
>>   arch/arm64/boot/dts/qcom/ipq9574.dtsi            | 3 ++-
>>   2 files changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>> index 78f6a2e053d5..9a8692377176 100644
>> --- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>> @@ -174,8 +174,13 @@ &ref_48mhz_clk {
>>   	clock-mult = <1>;
>>   };
>>   
>> +/*
>> + * The frequency of xo_board_clk is fixed to 24 MHZ, which is routed
>> + * from WiFi output clock 48 MHZ divided by 2.
>> + */
>>   &xo_board_clk {
>> -	clock-frequency = <24000000>;
>> +	clock-div = <2>;
>> +	clock-mult = <1>;
>>   };
>>   
>>   &xo_clk {
>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>> index 8246a00a3e3e..25aed33e9358 100644
>> --- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>> @@ -32,7 +32,8 @@ sleep_clk: sleep-clk {
>>   		};
>>   
>>   		xo_board_clk: xo-board-clk {
>> -			compatible = "fixed-clock";
>> +			compatible = "fixed-factor-clock";
>> +			clocks = <&ref_48mhz_clk>;
> 
> This must be squashed with the previous patch, you can't introduce
> code and replace it immediately afterwards.
> 
> Konrad

Ok, I will update the patch series with this patch dislodged, and push
this single patch in next update. Thanks.



From angelogioacchino.delregno at collabora.com  Fri Dec 13 02:33:04 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 13 Dec 2024 11:33:04 +0100
Subject: [PATCH v2 3/3] dts: arm64: mediatek: mt8195: Remove MT8183
 compatible for OVL
In-Reply-To: <CAEXTbpfOv876s3NLTO3oMTtVi_BwBtgb-816Gt5ZjKMjTZZKQg@mail.gmail.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
 <20241213095044.23757-4-jason-jh.lin@mediatek.com>
 <CAEXTbpfOv876s3NLTO3oMTtVi_BwBtgb-816Gt5ZjKMjTZZKQg@mail.gmail.com>
Message-ID: <980d28d6-52f0-4430-954b-da673fcd92df@collabora.com>

Il 13/12/24 11:27, Pin-yen Lin ha scritto:
> Hi Jason,
> 
> On Fri, Dec 13, 2024 at 5:50?PM Jason-JH.Lin <jason-jh.lin at mediatek.com> wrote:
>>
>> The OVL hardware capabilities have changed starting from MT8195,
>> making the MT8183 compatible no longer applicable.
>> Therefore, it is necessary to remove the MT8183 compatible for OVL.
> 
> Similar to patch 2/3, we need a:
> 
> Fixes: b852ee68fd72 ("arm64: dts: mt8195: Add display node for vdosys0")
> 

No, we don't, for reasons that are similar to the ones that I explained in the
MT8188 commit.

Besides, this one was already featureful before this commit, so really this is
not worth backporting at all.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

>>
>> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
>> ---
>>   arch/arm64/boot/dts/mediatek/mt8195.dtsi | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
>> index ade685ed2190..137ee8929e01 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
>> +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
>> @@ -3138,7 +3138,7 @@ larb20: larb at 1b010000 {
>>                  };
>>
>>                  ovl0: ovl at 1c000000 {
>> -                       compatible = "mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-ovl";
>> +                       compatible = "mediatek,mt8195-disp-ovl";
>>                          reg = <0 0x1c000000 0 0x1000>;
>>                          interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
>>                          power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
>> --
>> 2.43.0
>>
> 
> Regards,
> Pin-yen




From angelogioacchino.delregno at collabora.com  Fri Dec 13 02:33:01 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 13 Dec 2024 11:33:01 +0100
Subject: [PATCH v2 2/3] dts: arm64: mediatek: mt8188: Update OVL
 compatible from MT8183 to MT8195
In-Reply-To: <CAEXTbpcp31oWOCh2c41QbWOc5F_gpD1Bia0NiZeVyDbqKo98Lw@mail.gmail.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
 <20241213095044.23757-3-jason-jh.lin@mediatek.com>
 <CAEXTbpcp31oWOCh2c41QbWOc5F_gpD1Bia0NiZeVyDbqKo98Lw@mail.gmail.com>
Message-ID: <e1909a09-f871-4c8b-825e-835605ff92a5@collabora.com>

Il 13/12/24 11:26, Pin-yen Lin ha scritto:
> Hi Jason,
> 
> On Fri, Dec 13, 2024 at 5:50?PM Jason-JH.Lin <jason-jh.lin at mediatek.com> wrote:
>>
>> The OVL hardware capabilities have changed starting from MT8195,
>> making the MT8183 compatible no longer applicable.
>> Therefore, it is necessary to update the OVL compatible from MT8183 to
>> MT8195.
> 
> This probably doesn't need an (immediate) respin, but this patch needs:
> 
> Fixes: 7075b21d1a8e ("arm64: dts: mediatek: mt8188: Add display nodes
> for vdosys0")

No, because the binding must otherwise get a Fixes tag.

This is not a fix anyway, and is technically adding new features to the MT8188
OVL; without the additional features, the MT8188 is still compatible with the
MT8183 OVL, as much as MT8195.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

>>
>> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
>> ---
>>   arch/arm64/boot/dts/mediatek/mt8188.dtsi | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
>> index faccc7f16259..23ec3ff6cad9 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
>> +++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
>> @@ -2488,7 +2488,7 @@ jpeg_decoder: jpeg-decoder at 1a040000 {
>>                  };
>>
>>                  ovl0: ovl at 1c000000 {
>> -                       compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8183-disp-ovl";
>> +                       compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8195-disp-ovl";
>>                          reg = <0 0x1c000000 0 0x1000>;
>>                          clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
>>                          interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
>> --
>> 2.43.0
>>
> 
> Regards,
> Pin-yen



From neil.armstrong at linaro.org  Fri Dec 13 02:34:31 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 13 Dec 2024 11:34:31 +0100
Subject: [PATCH] clk: amlogic: g12a: fix mmc A peripheral clock
In-Reply-To: <20241213-amlogic-clk-g12a-mmca-fix-v1-1-5af421f58b64@baylibre.com>
References: <20241213-amlogic-clk-g12a-mmca-fix-v1-1-5af421f58b64@baylibre.com>
Message-ID: <cbf51c06-2183-4423-ab61-65a93f903a04@linaro.org>

On 13/12/2024 11:03, Jerome Brunet wrote:
> The bit index of the peripheral clock for mmc A is wrong
> This was probably not a problem for mmc A as the peripheral is likely left
> enabled by the bootloader.
> 
> No issues has been reported so far but it could be a problem, most likely
> some form of conflict between the ethernet and mmc A clock, breaking
> ethernet on init.
> 
> Use the value provided by the documentation for mmc A before this
> becomes an actual problem.
> 
> Fixes: 085a4ea93d54 ("clk: meson: g12a: add peripheral clock controller")
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
>   drivers/clk/meson/g12a.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
> index d3539fe9f7af5538201a78ce560f662ddb3935f2..20be7b037c07535bd2115f6e70404a95a7832756 100644
> --- a/drivers/clk/meson/g12a.c
> +++ b/drivers/clk/meson/g12a.c
> @@ -4311,7 +4311,7 @@ static MESON_GATE(g12a_spicc_1,			HHI_GCLK_MPEG0,	14);
>   static MESON_GATE(g12a_hiu_reg,			HHI_GCLK_MPEG0,	19);
>   static MESON_GATE(g12a_mipi_dsi_phy,		HHI_GCLK_MPEG0,	20);
>   static MESON_GATE(g12a_assist_misc,		HHI_GCLK_MPEG0,	23);
> -static MESON_GATE(g12a_emmc_a,			HHI_GCLK_MPEG0,	4);
> +static MESON_GATE(g12a_emmc_a,			HHI_GCLK_MPEG0,	24);
>   static MESON_GATE(g12a_emmc_b,			HHI_GCLK_MPEG0,	25);
>   static MESON_GATE(g12a_emmc_c,			HHI_GCLK_MPEG0,	26);
>   static MESON_GATE(g12a_audio_codec,		HHI_GCLK_MPEG0,	28);
> 
> ---
> base-commit: 52fd1709e41d3a85b48bcfe2404a024ebaf30c3b
> change-id: 20241213-amlogic-clk-g12a-mmca-fix-c9ebacf34d9c
> 
> Best regards,

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From alain.volmat at foss.st.com  Fri Dec 13 02:49:24 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Fri, 13 Dec 2024 11:49:24 +0100
Subject: [PATCH] MAINTAINERS: repair file entry in MEDIA DRIVERS FOR
 STM32 - CSI
In-Reply-To: <20241213060011.67797-1-lukas.bulwahn@redhat.com>
References: <20241213060011.67797-1-lukas.bulwahn@redhat.com>
Message-ID: <20241213104924.GA3662210@gnbcxd0016.gnb.st.com>

Hi Lukas,

Indeed, thank you for the fix.

Reviewed-by: Alain Volmat <alain.volmat at foss.st.com>

Regards,
Alain

On Fri, Dec 13, 2024 at 07:00:11AM +0100, Lukas Bulwahn wrote:
> From: Lukas Bulwahn <lukas.bulwahn at redhat.com>
> 
> Commit dcb0f4c16be5 ("media: stm32: csi: addition of the STM32 CSI driver")
> adds a new driver at drivers/media/platform/st/stm32/stm32-csi.c, but
> creates a new MAINTAINERS section MEDIA DRIVERS FOR STM32 - CSI with a file
> entry pointing to drivers/media/platform/stm32/stm32-csi.c. Note that the
> file entry is missing the ?st? directory in its path.
> 
> Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a
> broken reference. Repair this file entry in MEDIA DRIVERS FOR STM32 - CSI.
> 
> Signed-off-by: Lukas Bulwahn <lukas.bulwahn at redhat.com>
> ---
>  MAINTAINERS | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index bff3d35f80b5..230b7a4ee95f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14551,7 +14551,7 @@ L:	linux-media at vger.kernel.org
>  S:	Supported
>  T:	git git://linuxtv.org/media_tree.git
>  F:	Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> -F:	drivers/media/platform/stm32/stm32-csi.c
> +F:	drivers/media/platform/st/stm32/stm32-csi.c
>  
>  MEDIA DRIVERS FOR STM32 - DCMI / DCMIPP
>  M:	Hugues Fruchet <hugues.fruchet at foss.st.com>
> -- 
> 2.47.1
> 


From linux at armlinux.org.uk  Fri Dec 13 02:59:54 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 10:59:54 +0000
Subject: [PATCH net-next 2/7] net: stmmac: move tx_lpi_timer tracking to
 phylib
In-Reply-To: <E1tLkSX-006qfS-Rx@rmk-PC.armlinux.org.uk>
References: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
 <E1tLkSX-006qfS-Rx@rmk-PC.armlinux.org.uk>
Message-ID: <Z1wTqh-BnvPYLqU8@shell.armlinux.org.uk>

On Thu, Dec 12, 2024 at 02:46:33PM +0000, Russell King (Oracle) wrote:
> @@ -1092,6 +1092,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
>  			phy_init_eee(phy, !(priv->plat->flags &
>  				STMMAC_FLAG_RX_CLK_RUNS_IN_LPI)) >= 0;
>  		priv->eee_enabled = stmmac_eee_init(priv);
> +		priv->tx_lpi_timer = phy->eee_cfg.tx_lpi_timer;
>  		priv->tx_lpi_enabled = priv->eee_enabled;
>  		stmmac_set_eee_pls(priv, priv->hw, true);
>  	}

While looking deeper at stmmac, there's a bug in the above hunk -
stmmac_eee_init() makes use of priv->tx_lpi_timer, so this member
needs to be set before calling this function. I'll post a v2 shortly.

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


From krzk at kernel.org  Fri Dec 13 03:08:48 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 12:08:48 +0100
Subject: [PATCH v1 3/4] dt-bindings: hwmon: intel,crps185: Add to trivial
In-Reply-To: <20241212214927.3586509-4-ninad@linux.ibm.com>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
 <20241212214927.3586509-4-ninad@linux.ibm.com>
Message-ID: <au4mmpxa6tbznu3pcxeu7tri4elvcoyy7l5m5ujdpj7ah3xqrz@ule3ymdiisyj>

On Thu, Dec 12, 2024 at 03:49:02PM -0600, Ninad Palsule wrote:
> Add INTEL Common Redundant Power Supply Versions crps185 bindings as
> trivial.

becuse they are trivial or you don't care? Some broader context would be
useful here.

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

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Dec 13 03:13:00 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 12:13:00 +0100
Subject: [PATCH v1 0/4] Revise Meta (Facebook) Minerva BMC
In-Reply-To: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
References: <20241212133226.342937-1-yangchen.openbmc@gmail.com>
Message-ID: <17435684-a1f5-44cd-ac25-7e8efe88c754@linaro.org>

On 12/12/2024 14:32, Yang Chen wrote:
> Revise the linux device tree entry related to Meta (Facebook) Minerva
> specific devices connected to BMC (AST2600) SoC.
> 
> Base on:
> https://lore.kernel.org/all/172722509817.374662.7338401100529556748.b4-ty at codeconstruct.com.au/
> 

I don't believe. You are working on some old kernel. There is no way you
can get my address like this. It's impossible.

Form letter:

You CC-ed an address, which suggests you do not work on mainline kernel
or you do not use get_maintainers.pl/b4/patman. Please rebase and always
work on mainline or start using mentioned tools, so correct addresses
will be used.


Best regards,
Krzysztof


From konrad.dybcio at oss.qualcomm.com  Fri Dec 13 03:17:30 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 13 Dec 2024 12:17:30 +0100
Subject: [PATCH v8 4/5] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <20241206191900.2545069-5-quic_vikramsa@quicinc.com>
References: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
 <20241206191900.2545069-5-quic_vikramsa@quicinc.com>
Message-ID: <f38e0aa3-e10e-4e5a-923a-76686baf2482@oss.qualcomm.com>

On 6.12.2024 8:18 PM, Vikram Sharma wrote:
> Add changes to support the camera subsystem on the SC7280.
> 
> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> Tested-by: Luca Weiss <luca.weiss at fairphone.com>
> ---
>  arch/arm64/boot/dts/qcom/sc7280.dtsi | 178 +++++++++++++++++++++++++++
>  1 file changed, 178 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> index 55db1c83ef55..afe7113df4af 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> @@ -4426,6 +4426,184 @@ cci1_i2c1: i2c-bus at 1 {
>  			};
>  		};
>  
> +		camss: isp at acb3000 {
> +			compatible = "qcom,sc7280-camss";
> +
> +			reg = <0x0 0x0acb3000 0x0 0x1000>,
> +			      <0x0 0x0acba000 0x0 0x1000>,
> +			      <0x0 0x0acc1000 0x0 0x1000>,
> +			      <0x0 0x0acc8000 0x0 0x1000>,
> +			      <0x0 0x0accf000 0x0 0x1000>,
> +			      <0x0 0x0ace0000 0x0 0x2000>,
> +			      <0x0 0x0ace2000 0x0 0x2000>,
> +			      <0x0 0x0ace4000 0x0 0x2000>,
> +			      <0x0 0x0ace6000 0x0 0x2000>,
> +			      <0x0 0x0ace8000 0x0 0x2000>,
> +			      <0x0 0x0acaf000 0x0 0x4000>,
> +			      <0x0 0x0acb6000 0x0 0x4000>,
> +			      <0x0 0x0acbd000 0x0 0x4000>,
> +			      <0x0 0x0acc4000 0x0 0x4000>,
> +			      <0x0 0x0accb000 0x0 0x4000>;
> +			reg-names = "csid0",
> +				    "csid1",
> +				    "csid2",
> +				    "csid_lite0",
> +				    "csid_lite1",
> +				    "csiphy0",
> +				    "csiphy1",
> +				    "csiphy2",
> +				    "csiphy3",
> +				    "csiphy4",
> +				    "vfe0",
> +				    "vfe1",
> +				    "vfe2",
> +				    "vfe_lite0",
> +				    "vfe_lite1";
> +
> +			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
> +				 <&camcc CAM_CC_CPAS_AHB_CLK>,
> +				 <&camcc CAM_CC_CSIPHY0_CLK>,
> +				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
> +				 <&camcc CAM_CC_CSIPHY1_CLK>,
> +				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
> +				 <&camcc CAM_CC_CSIPHY2_CLK>,
> +				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
> +				 <&camcc CAM_CC_CSIPHY3_CLK>,
> +				 <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
> +				 <&camcc CAM_CC_CSIPHY4_CLK>,
> +				 <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
> +				 <&gcc GCC_CAMERA_AHB_CLK>,

This one's permanently enabled, you can drop it

> +				 <&gcc GCC_CAMERA_HF_AXI_CLK>,

Is GCC_CAMERA_SF_AXI_CLK required too?

> +				 <&camcc CAM_CC_ICP_AHB_CLK>,
> +				 <&camcc CAM_CC_IFE_0_CLK>,
> +				 <&camcc CAM_CC_IFE_0_AXI_CLK>,
> +				 <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_0_CSID_CLK>,
> +				 <&camcc CAM_CC_IFE_1_CLK>,
> +				 <&camcc CAM_CC_IFE_1_AXI_CLK>,
> +				 <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_1_CSID_CLK>,
> +				 <&camcc CAM_CC_IFE_2_CLK>,
> +				 <&camcc CAM_CC_IFE_2_AXI_CLK>,
> +				 <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_2_CSID_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_0_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_1_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
> +				 <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>;
> +			clock-names = "camnoc_axi",
> +				      "cpas_ahb",
> +				      "csiphy0",
> +				      "csiphy0_timer",
> +				      "csiphy1",
> +				      "csiphy1_timer",
> +				      "csiphy2",
> +				      "csiphy2_timer",
> +				      "csiphy3",
> +				      "csiphy3_timer",
> +				      "csiphy4",
> +				      "csiphy4_timer",
> +				      "gcc_camera_ahb",
> +				      "gcc_cam_hf_axi",

No other binding calls it that, please use `gcc_axi_hf` for
consistency

Other than that, looks good

Konrad


From konrad.dybcio at oss.qualcomm.com  Fri Dec 13 03:18:50 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 13 Dec 2024 12:18:50 +0100
Subject: [PATCH v8 5/5] arm64: dts: qcom:
 qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <20241206191900.2545069-6-quic_vikramsa@quicinc.com>
References: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
 <20241206191900.2545069-6-quic_vikramsa@quicinc.com>
Message-ID: <d397065d-80fb-467e-bf41-0f5aad882a15@oss.qualcomm.com>

On 6.12.2024 8:19 PM, Vikram Sharma wrote:
> The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
> Enable the IMX577 on the vision mezzanine.
> 
> An example media-ctl pipeline for the imx577 is:
> 
> media-ctl --reset
> media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
> media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
> media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
> media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
> media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
> media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
> 
> yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0
> 
> Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

Konrad


From clement.legoffic at foss.st.com  Fri Dec 13 03:16:33 2024
From: clement.legoffic at foss.st.com (Clement LE GOFFIC)
Date: Fri, 13 Dec 2024 12:16:33 +0100
Subject: [Linux-stm32] [PATCH v4] pinctrl: stm32: Add check for
 clk_enable()
In-Reply-To: <20241213010948.2623382-1-zmw12306@gmail.com>
References: <20241213010948.2623382-1-zmw12306@gmail.com>
Message-ID: <6d893831-7a2e-4a9a-a519-2e257e249f0f@foss.st.com>


On 12/13/24 02:09, Mingwei Zheng wrote:
> Convert the driver to clk_bulk*() API.
> Add check for the return value of clk_bulk_enable() to catch
> the potential error.
> 
> Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
> ---
> Changelog:
> 
> v3 -> v4:
> 1. Add initialization for  pctl->clks.
> 2. Adjust alignment.
> 
> v2 -> v3:
> 
> 1. Convert clk_disable_unprepare to clk_bulk_disable
> and clk_bulk_unprepare.
> 
> v1 -> v2:
> 
> 1. Move int ret declaration into if block.
> ---
>   drivers/pinctrl/stm32/pinctrl-stm32.c | 37 +++++++++++++++------------
>   1 file changed, 21 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
> index 5b7fa77c1184..427749d4f6a5 100644
> --- a/drivers/pinctrl/stm32/pinctrl-stm32.c
> +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
> @@ -86,7 +86,6 @@ struct stm32_pinctrl_group {
>   
>   struct stm32_gpio_bank {
>   	void __iomem *base;
> -	struct clk *clk;
>   	struct reset_control *rstc;
>   	spinlock_t lock;
>   	struct gpio_chip gpio_chip;
> @@ -108,6 +107,7 @@ struct stm32_pinctrl {
>   	unsigned ngroups;
>   	const char **grp_names;
>   	struct stm32_gpio_bank *banks;
> +	struct clk_bulk_data *clks;
>   	unsigned nbanks;
>   	const struct stm32_pinctrl_match_data *match_data;
>   	struct irq_domain	*domain;
> @@ -1308,7 +1308,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
>   	if (IS_ERR(bank->base))
>   		return PTR_ERR(bank->base);
>   
> -	err = clk_prepare_enable(bank->clk);
> +	err = clk_prepare_enable(pctl->clks[pctl->nbanks].clk);
>   	if (err) {
>   		dev_err(dev, "failed to prepare_enable clk (%d)\n", err);
>   		return err;
> @@ -1397,7 +1397,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
>   	return 0;
>   
>   err_clk:
> -	clk_disable_unprepare(bank->clk);
> +	clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);
>   	return err;
>   }
>   
> @@ -1617,10 +1617,18 @@ int stm32_pctl_probe(struct platform_device *pdev)
>   		return -EINVAL;
>   	}
>   	pctl->banks = devm_kcalloc(dev, banks, sizeof(*pctl->banks),
> -			GFP_KERNEL);
> +				   GFP_KERNEL);
>   	if (!pctl->banks)
>   		return -ENOMEM;
>   
> +	pctl->clks = devm_kcalloc(dev, banks, sizeof(*pctl->clks),
> +				  GFP_KERNEL);
> +	if (!pctl->clks)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < banks; ++i)
> +		pctl->clks[i].id = "";
> +
>   	i = 0;
>   	for_each_gpiochip_node(dev, child) {
>   		struct stm32_gpio_bank *bank = &pctl->banks[i];
> @@ -1631,11 +1639,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
>   			fwnode_handle_put(child);
>   			return -EPROBE_DEFER;
>   		}
> -
> -		bank->clk = of_clk_get_by_name(np, NULL);
> -		if (IS_ERR(bank->clk)) {
> +		pctl->clks[i].clk = of_clk_get_by_name(np, NULL);
> +		if (IS_ERR(pctl->clks[i].clk)) {
>   			fwnode_handle_put(child);
> -			return dev_err_probe(dev, PTR_ERR(bank->clk),
> +			return dev_err_probe(dev, PTR_ERR(pctl->clks[i].clk),
>   					     "failed to get clk\n");
>   		}
>   		i++;
> @@ -1646,8 +1653,7 @@ int stm32_pctl_probe(struct platform_device *pdev)
>   		if (ret) {
>   			fwnode_handle_put(child);
>   
> -			for (i = 0; i < pctl->nbanks; i++)
> -				clk_disable_unprepare(pctl->banks[i].clk);
> +			clk_bulk_disable_unprepare(pctl->nbanks, pctl->clks);
>   
>   			return ret;
>   		}
> @@ -1726,10 +1732,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
>   int __maybe_unused stm32_pinctrl_suspend(struct device *dev)
>   {
>   	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
> -	int i;
>   
> -	for (i = 0; i < pctl->nbanks; i++)
> -		clk_disable(pctl->banks[i].clk);
> +	clk_bulk_disable(pctl->nbanks, pctl->clks);
>   
>   	return 0;
>   }
> @@ -1738,10 +1742,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
>   {
>   	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
>   	struct stm32_pinctrl_group *g = pctl->groups;
> -	int i;
> +	int i, ret;
>   
> -	for (i = 0; i < pctl->nbanks; i++)
> -		clk_enable(pctl->banks[i].clk);
> +	ret = clk_bulk_enable(pctl->nbanks, pctl->clks);
> +	if (ret)
> +		return ret;
>   
>   	for (i = 0; i < pctl->ngroups; i++, g++)
>   		stm32_pinctrl_restore_gpio_regs(pctl, g->pin);


Tested-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>


From antonio.borneo at foss.st.com  Fri Dec 13 03:24:47 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 13 Dec 2024 12:24:47 +0100
Subject: [PATCH v4] pinctrl: stm32: Add check for clk_enable()
In-Reply-To: <20241213010948.2623382-1-zmw12306@gmail.com>
References: <20241213010948.2623382-1-zmw12306@gmail.com>
Message-ID: <799c111fbae0b707ac76348f4fd8c9c3bbafcdc0.camel@foss.st.com>

On Thu, 2024-12-12 at 20:09 -0500, Mingwei Zheng wrote:
> Convert the driver to clk_bulk*() API.
> Add check for the return value of clk_bulk_enable() to catch
> the potential error.
> 
> Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
> ---

Rewiewed-by: Antonio Borneo <antonio.borneo at foss.st.com>

Thanks!


From hui.wang at canonical.com  Fri Dec 13 03:25:32 2024
From: hui.wang at canonical.com (Hui Wang)
Date: Fri, 13 Dec 2024 19:25:32 +0800
Subject: [PATCH] ARM: dts: nxp: imx6qdl: add dr_mode to usbotg
In-Reply-To: <20241213081729.ohgs7tyyzywd4uyc@hippo>
References: <20241212043126.73045-1-hui.wang@canonical.com>
 <20241213081729.ohgs7tyyzywd4uyc@hippo>
Message-ID: <cb6c7f8d-6244-4370-944f-a1a2beac3a79@canonical.com>


On 12/13/24 16:17, Xu Yang wrote:
> Hi,
>
> On Thu, Dec 12, 2024 at 12:31:26PM +0800, Hui Wang wrote:
>> For the chipidea usb driver, if the dr_mode is not set, it will set
>> the device to otg mode by default, so here the dr_mode has not been
>> set for a long time. But some testcases need to parse the dr_mode from
>> DT and decide the follow-up test strategy, here set the dr_mode to otg
>> explicitly for QA's testcases.
> The dr_mode is board specific property, so we normally don't put it in
> dtsi file. Also, imx6qdl.dtsi is a common dtsi, therefore it's not a
> correct place. I wonder you don't set dr_mode in other dts file which
> include will imx6qdl.dtsi?

Yes, our QA reported this issue against the imx6q-sabresd board, I 
thought dr_mode could be overwritten if board dts set the dr_mode, so 
this change will not impact existing boards. But as you said "we 
normally don't put it in dtsi file", I will move it to imx6q-sabresd.dts.

Thanks,

Hui.

> Thanks,
> Xu Yang
>
>> Signed-off-by: Hui Wang <hui.wang at canonical.com>
>> ---
>>   arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
>> index d2200c9db25a..285fb7314a88 100644
>> --- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
>> +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
>> @@ -982,6 +982,7 @@ usbotg: usb at 2184000 {
>>   				clocks = <&clks IMX6QDL_CLK_USBOH3>;
>>   				fsl,usbphy = <&usbphy1>;
>>   				fsl,usbmisc = <&usbmisc 0>;
>> +				dr_mode = "otg";
>>   				ahb-burst-config = <0x0>;
>>   				tx-burst-size-dword = <0x10>;
>>   				rx-burst-size-dword = <0x10>;
>> -- 
>> 2.34.1
>>


From etienne.carriere at foss.st.com  Fri Dec 13 03:24:30 2024
From: etienne.carriere at foss.st.com (Etienne CARRIERE - foss)
Date: Fri, 13 Dec 2024 11:24:30 +0000
Subject: [PATCH v2 2/2] firmware: arm_scmi: round rate bisecting in
 discrete rates
In-Reply-To: <aac4c00dc3ba4599aaa91392dac71d6d@foss.st.com>
References: <20241203173908.3148794-1-etienne.carriere@foss.st.com>
 <20241203173908.3148794-3-etienne.carriere@foss.st.com>
 <Z1bKlOeHJFHpe9ZU@bogus>
 <ed164b6704ab4086b2fb22ae51658f31@foss.st.com>,<Z1ck5tFkb41wReZP@bogus>,<aac4c00dc3ba4599aaa91392dac71d6d@foss.st.com>
Message-ID: <24d1fce2660a4d8296dd7c699020932a@foss.st.com>

On Tuesday, December 10, 2024, Etienne CARRIERE - foss wrote:
> On Monday, December 9, 2024, Sudeep Holla wrote:
> > On Mon, Dec 09, 2024 at 12:59:58PM +0000, Etienne CARRIERE - foss wrote:
> (...)
> > > > I would like to avoid this extra query if not required which you seem to
> > > > have made an attempt but I just want to be thorough and make sure that's
> > > > what we need w.r.t the specification.
> > >
> > > Sure, I indeed prefer clear and robust implementation in the long term,
> > > being the one I propose here or another one.
> > >
> >
> > Good then, we can work towards achieving that. If you can specify how slow
> > or memory hungry is it without these changes and how much this change helps
> > your platform, we can take it up with spec authors and see if they are happy
> > to provide some alternative to deal with this in a generic way.
> 
> The platforms we target usually have plenty of RAM, lets say hundreds of MBytes.
> Not that much for some system but enough I guess to store a few hundreds of
> clock rates for a few dozen of clocks (few kByte of RAM).

During last SCMI monthly meeting [1], there was a suggestion to use a lazy
query of the full clock discrete rates list: the first time clk_round_rate()
is requested on an SCMI clock with discrete rates, we can allocated and get
the full rate list once in struct scmi_clock_info. It will be ease to locally bisect
or scan into these supported rates for clk_round_rate() operations.

It would prevent to store the full discrete rates list for all SCMI clocks when
clk_round_rate() is queried only for a very few of them.

Do you think it would be a good compromise? 

[1] https://linaro.atlassian.net/wiki/spaces/SCMI/overview#Meetings

BR,
Etienne

> 
> That said, thinking more and more about this, I really belive a dedicate SCMI
> clock protocol command would better fit platform needs in the long term.
> 
> BR,
> Etienne
> 
> >
> > --
> > Regards,
> > Sudeep
> >
> 


From horms at kernel.org  Fri Dec 13 03:28:29 2024
From: horms at kernel.org (Simon Horman)
Date: Fri, 13 Dec 2024 11:28:29 +0000
Subject: [PATCH net-next v1] net: stmmac: Drop redundant dwxgmac_tc_ops
 variable
In-Reply-To: <20241212033325.282817-1-0x1207@gmail.com>
References: <20241212033325.282817-1-0x1207@gmail.com>
Message-ID: <20241213112829.GN2110@kernel.org>

On Thu, Dec 12, 2024 at 11:33:25AM +0800, Furong Xu wrote:
> dwmac510_tc_ops and dwxgmac_tc_ops are completely identical,
> keep dwmac510_tc_ops to provide better backward compatibility.
> 
> Signed-off-by: Furong Xu <0x1207 at gmail.com>

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



From marex at denx.de  Fri Dec 13 03:45:19 2024
From: marex at denx.de (Marek Vasut)
Date: Fri, 13 Dec 2024 12:45:19 +0100
Subject: [PATCH v4] pinctrl: stm32: Add check for clk_enable()
In-Reply-To: <20241213010948.2623382-1-zmw12306@gmail.com>
References: <20241213010948.2623382-1-zmw12306@gmail.com>
Message-ID: <a47b567d-96a6-4a87-9f60-33a311c281ae@denx.de>

On 12/13/24 2:09 AM, Mingwei Zheng wrote:

[...]

> @@ -1397,7 +1397,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
>   	return 0;
>   
>   err_clk:
> -	clk_disable_unprepare(bank->clk);
> +	clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);


Should this be

-clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);
+clk_disable_unprepare(pctl->clks[bank->bank_nr].clk);
                                   ^^^^^^^^^^^^^

?

>   	return err;
>   }
>   
> @@ -1617,10 +1617,18 @@ int stm32_pctl_probe(struct platform_device *pdev)
>   		return -EINVAL;
>   	}
>   	pctl->banks = devm_kcalloc(dev, banks, sizeof(*pctl->banks),
> -			GFP_KERNEL);
> +				   GFP_KERNEL);
>   	if (!pctl->banks)
>   		return -ENOMEM;
>   
> +	pctl->clks = devm_kcalloc(dev, banks, sizeof(*pctl->clks),
> +				  GFP_KERNEL);
> +	if (!pctl->clks)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < banks; ++i)

i++


From frederic at kernel.org  Fri Dec 13 03:46:22 2024
From: frederic at kernel.org (Frederic Weisbecker)
Date: Fri, 13 Dec 2024 12:46:22 +0100
Subject: [PATCH 06/19] soc/qman: test: Use kthread_run_on_cpu()
In-Reply-To: <986fee5c-8537-498f-83ec-65a7c7c7a71c@cs-soprasteria.com>
References: <20241211154035.75565-1-frederic@kernel.org>
 <20241211154035.75565-7-frederic@kernel.org>
 <986fee5c-8537-498f-83ec-65a7c7c7a71c@cs-soprasteria.com>
Message-ID: <Z1wejvFpGLFMhLJ9@localhost.localdomain>

Le Fri, Dec 13, 2024 at 07:27:03AM +0000, LEROY Christophe a ?crit :
> 
> 
> Le 11/12/2024 ? 16:40, Frederic Weisbecker a ?crit?:
> > Use the proper API instead of open coding it.
> > 
> > However it looks like kthreads here could be replaced by the use of a
> > per-cpu workqueue instead.
> > 
> > Signed-off-by: Frederic Weisbecker <frederic at kernel.org>
> 
> Acked-by: Christophe Leroy <christophe.leroy at csgroup.eu>

Thanks! Feel free to apply this patch to your tree as it's a pretty
standalone change.


From kirill at shutemov.name  Fri Dec 13 03:59:12 2024
From: kirill at shutemov.name (Kirill A. Shutemov)
Date: Fri, 13 Dec 2024 13:59:12 +0200
Subject: [PATCHv2 2/2] x86/mm: Make memremap(MEMREMAP_WB) map memory as
 encrypted by default
In-Reply-To: <079cb87c-78aa-5fb5-b28f-e7a54e51aa78@amd.com>
References: <20241021105723.2707507-1-kirill.shutemov@linux.intel.com>
 <20241021105723.2707507-3-kirill.shutemov@linux.intel.com>
 <20241118164616.GAZztvWGs9cOV8t20_@fat_crate.local>
 <s4frmqwtuvclinuu7ttyzfpe7bj7hju5xgt6sxzy3gyt3prr62@rrgvhkv4lgwv>
 <20241121114952.GCZz8eYEVa3yubYQzO@fat_crate.local>
 <bz3vlh3lri7yfckdkddopwhsgvkmizhw5q6ecomgeba7q22ufp@ntu2kugiho4o>
 <079cb87c-78aa-5fb5-b28f-e7a54e51aa78@amd.com>
Message-ID: <myzpconz5z7xf4j7fnofb5zgxv7fc3evxhcys6wnqlao2c3xkj@aoapggj7lchq>

On Thu, Dec 12, 2024 at 08:23:07AM -0600, Tom Lendacky wrote:
> On 12/10/24 07:26, Kirill A. Shutemov wrote:
> > On Thu, Nov 21, 2024 at 12:49:52PM +0100, Borislav Petkov wrote:
> >> On Tue, Nov 19, 2024 at 10:21:05AM +0200, Kirill A. Shutemov wrote:
> >>> Sure, we can workaround every place that touches such ranges.
> >>
> >> Every place? Which every place? I thought this is only an EISA issue?
> > 
> > I looked at other places where we call memremap(MEMREMAP_WB) such as
> > acpi_wakeup_cpu(). We actually get encrypted/private mapping for this
> > callsite despite __ioremap_caller() being called encrypted == false.
> > This happens because of IORES_MAP_ENCRYPTED check in __ioremap_caller().
> > 
> > So we depend on the BIOS here. The EISA problem happens because the
> > target memory is in !IORES_MAP_ENCRYPTED memory.
> > 
> > It's hard to say if any other memremap(MEMREMAP_WB) would trigger the
> > issue. And what will happen after next BIOS update.
> > 
> >> Then clearly your changelogs need to expand considerably more what we're
> >> *really* addressing here.
> >>
> >>> Or we can address problem at the root and make creating decrypted/shared
> >>> mappings explicit.
> >>
> >> What is the problem? That KVM implicitly converts memory to shared? Why does
> >> KVM do that an can it be fixed not to?
> >>
> >> Doesn't sound like the guest's problem.
> > 
> > Well, the problem is on the both sides.
> > 
> > VMM behaviour on such accesses is not specified in any spec. AFAIK all
> > current VMM implementations do this implicit conversion.
> > 
> > I think it has to be fixed. VMMs (not only KVM) should not silently
> > convert memory to shared. But VMMs cannot make memory access to go away.
> > The only option they have is to inject #VE instead indicating bogus
> > access. At this point it becomes a guest problem.
> > 
> > It will get fixed in VMMs naturally when TDX Connect gets enabled.
> > With a secure device assigned to a TD, VMM would loose the ability to
> > convert memory on its own. The guest would have to unlock the memory
> > first. This will make implicit conversion impossible.
> > 
> > But it also means guest should never initiate shared access without
> > explicit conversion. Otherwise #VE will crash it.
> > 
> >> Or maybe this needs a lot more explanation what we're fixing here.
> >>
> >>> Such mappings have both functional (as we see here) and security
> >>> implications (VMM can manipulate the guest memory range). We should not
> >>> create decrypted mappings by default on legacy interfaces.
> >>
> >> So we're getting closer.
> >>
> >> The changes themselves are fine but your text is missing a lot about what
> >> we're fixing here. When I asked, I barely scratched the surface. So can we
> >> elaborate here pls?
> > 
> > What about this:
> > 
> > x86/mm: Make memremap(MEMREMAP_WB) map memory as encrypted by default
> > 
> > Currently memremap(MEMREMAP_WB) can produce decrypted/shared mapping:
> > 
> > memremap(MEMREMAP_WB)
> >   arch_memremap_wb()
> >     ioremap_cache()
> >       __ioremap_caller(.encrytped = false)
> 
> That's because try_ram_remap() invokes arch_memremap_can_ram_remap()
> which is returning false (for some reason).

In EISA case try_ram_remap() is not called. is_ram is REGION_DISJOINT

> When arch_memremap_can_ram_remap() returns false, ioremap_cache() is
> invoked. ioremap() should provide shared mappings unless specifically
> requested to provide an encrypted mapping (via encrypted parameter) or
> if __ioremap_check_mem() determines that an encrypted mapping is needed.

I don't propose changing ioremap() behaviour. It's about memremap().

> Can logic be added to arch_memremap_can_ram_remap() to return true for
> the cases that TDX is having issues with?

It will not help EISA case, because we don't get this path.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


From mateusz.polchlopek at intel.com  Fri Dec 13 04:04:04 2024
From: mateusz.polchlopek at intel.com (Mateusz Polchlopek)
Date: Fri, 13 Dec 2024 13:04:04 +0100
Subject: [PATCH net-next v1] net: stmmac: Drop redundant dwxgmac_tc_ops
 variable
In-Reply-To: <20241212033325.282817-1-0x1207@gmail.com>
References: <20241212033325.282817-1-0x1207@gmail.com>
Message-ID: <bc9fe988-76f5-4106-b063-96941b5fc7fe@intel.com>



On 12/12/2024 4:33 AM, Furong Xu wrote:
> dwmac510_tc_ops and dwxgmac_tc_ops are completely identical,
> keep dwmac510_tc_ops to provide better backward compatibility.
> 
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
>   drivers/net/ethernet/stmicro/stmmac/hwif.c      |  4 ++--
>   drivers/net/ethernet/stmicro/stmmac/hwif.h      |  1 -
>   drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 11 -----------
>   3 files changed, 2 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
> index 4bd79de2e222..31bdbab9a46c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
> @@ -267,7 +267,7 @@ static const struct stmmac_hwif_entry {
>   		.hwtimestamp = &stmmac_ptp,
>   		.ptp = &stmmac_ptp_clock_ops,
>   		.mode = NULL,
> -		.tc = &dwxgmac_tc_ops,
> +		.tc = &dwmac510_tc_ops,
>   		.mmc = &dwxgmac_mmc_ops,
>   		.est = &dwmac510_est_ops,
>   		.setup = dwxgmac2_setup,
> @@ -290,7 +290,7 @@ static const struct stmmac_hwif_entry {
>   		.hwtimestamp = &stmmac_ptp,
>   		.ptp = &stmmac_ptp_clock_ops,
>   		.mode = NULL,
> -		.tc = &dwxgmac_tc_ops,
> +		.tc = &dwmac510_tc_ops,
>   		.mmc = &dwxgmac_mmc_ops,
>   		.est = &dwmac510_est_ops,
>   		.setup = dwxlgmac2_setup,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
> index e428c82b7d31..2f7295b6c1c5 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
> @@ -685,7 +685,6 @@ extern const struct stmmac_dma_ops dwmac410_dma_ops;
>   extern const struct stmmac_ops dwmac510_ops;
>   extern const struct stmmac_tc_ops dwmac4_tc_ops;
>   extern const struct stmmac_tc_ops dwmac510_tc_ops;
> -extern const struct stmmac_tc_ops dwxgmac_tc_ops;
>   
>   #define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
>   #define GMAC4_VERSION		0x00000110	/* GMAC4+ CORE Version */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
> index 6a79e6a111ed..694d6ee14381 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
> @@ -1284,14 +1284,3 @@ const struct stmmac_tc_ops dwmac510_tc_ops = {
>   	.query_caps = tc_query_caps,
>   	.setup_mqprio = tc_setup_dwmac510_mqprio,
>   };
> -
> -const struct stmmac_tc_ops dwxgmac_tc_ops = {
> -	.init = tc_init,
> -	.setup_cls_u32 = tc_setup_cls_u32,
> -	.setup_cbs = tc_setup_cbs,
> -	.setup_cls = tc_setup_cls,
> -	.setup_taprio = tc_setup_taprio,
> -	.setup_etf = tc_setup_etf,
> -	.query_caps = tc_query_caps,
> -	.setup_mqprio = tc_setup_dwmac510_mqprio,
> -};

Reviewed-by: Mateusz Polchlopek <mateusz.polchlopek at intel.com>



From m-malladi at ti.com  Fri Dec 13 04:22:29 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Fri, 13 Dec 2024 17:52:29 +0530
Subject: [EXTERNAL] Re: [PATCH net v4 2/2] net: ti: icssg-prueth: Fix
 clearing of IEP_CMP_CFG registers during iep_init
In-Reply-To: <3b0b84f9-d51b-4075-9d1a-5c2042ee6c4e@stanley.mountain>
References: <20241211135941.1800240-1-m-malladi@ti.com>
 <20241211135941.1800240-3-m-malladi@ti.com>
 <3b0b84f9-d51b-4075-9d1a-5c2042ee6c4e@stanley.mountain>
Message-ID: <57545831-836c-4105-be59-212d01965110@ti.com>



On 11/12/24 20:13, Dan Carpenter wrote:
> On Wed, Dec 11, 2024 at 07:?29:?41PM +0530, Meghana Malladi wrote: > 
> drivers/net/ethernet/ti/icssg/icss_iep.?c | 9 +++++++++ > 1 file 
> changed, 9 insertions(+) > > diff --git 
> a/drivers/net/ethernet/ti/icssg/icss_iep.?c 
> b/drivers/net/ethernet/ti/icssg/icss_iep.?c
> ZjQcmQRYFpfptBannerStart
> This message was sent from outside of Texas Instruments.
> Do not click links or open attachments unless you recognize the source 
> of this email and know the content is safe.
> Report?Suspicious
> <https://us-phishalarm-ewt.proofpoint.com/EWT/v1/G3vK!uldqd1eFN22R6yXOvHOpn5WAo9_VFQH5-v8XYKsQLuIl9SMCOgfm9hmv8Rr9Y_bMWd5wpdH9mAXBiUbw5VhHCnva7cOtZgfLcnsXKK4$>
> ZjQcmQRYFpfptBannerEnd
> 
> On Wed, Dec 11, 2024 at 07:29:41PM +0530, Meghana Malladi wrote:
>>  drivers/net/ethernet/ti/icssg/icss_iep.c | 9 +++++++++
>>  1 file changed, 9 insertions(+)
>> 
>> diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c
>> index 5d6d1cf78e93..a96861debbe3 100644
>> --- a/drivers/net/ethernet/ti/icssg/icss_iep.c
>> +++ b/drivers/net/ethernet/ti/icssg/icss_iep.c
>> @@ -215,6 +215,10 @@ static void icss_iep_enable_shadow_mode(struct icss_iep *iep)
>>  	for (cmp = IEP_MIN_CMP; cmp < IEP_MAX_CMP; cmp++) {
>>  		regmap_update_bits(iep->map, ICSS_IEP_CMP_STAT_REG,
>>  				   IEP_CMP_STATUS(cmp), IEP_CMP_STATUS(cmp));
>> +
>> +		regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
>> +				   IEP_CMP_CFG_CMP_EN(cmp), 0);
>> +
> 
> Don't add this blank line.
> 
> You won't detect this by running checkpatch on the patch, but if you
> apply the patch and re-run checkpatch on the file then it will complain
> about this.
> 

I see, I will remove the blank line then.

>>  	}
>>  
>>  	/* enable reset counter on CMP0 event */
>> @@ -780,6 +784,11 @@ int icss_iep_exit(struct icss_iep *iep)
>>  	}
>>  	icss_iep_disable(iep);
>>  
>> +	if (iep->pps_enabled)
>> +		icss_iep_pps_enable(iep, false);
>> +	else if (iep->perout_enabled)
>> +		icss_iep_perout_enable(iep, NULL, false);
> 
> 
> Do we need the else?  Could be written as:
> 
> 	if (iep->pps_enabled)
> 		icss_iep_pps_enable(iep, false);
> 	if (iep->perout_enabled)
> 		icss_iep_perout_enable(iep, NULL, false);
> 

pps and perout and mutually exclusive, hence used if and else if.

> regards,
> dan carpenter
> 
> 


From linux at armlinux.org.uk  Fri Dec 13 04:22:45 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 12:22:45 +0000
Subject: [PATCH net-next 2/2] net: stmmac: dwmac-socfpga: Set interface
 modes from Lynx PCS as supported
In-Reply-To: <20241213090526.71516-3-maxime.chevallier@bootlin.com>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
 <20241213090526.71516-3-maxime.chevallier@bootlin.com>
Message-ID: <Z1wnFXlgEU84VX8F@shell.armlinux.org.uk>

On Fri, Dec 13, 2024 at 10:05:25AM +0100, Maxime Chevallier wrote:
> On Socfpga, the dwmac controller uses a variation of the Lynx PCS to get
> additional support for SGMII and 1000BaseX. The switch between these
> modes may occur at runtime (e.g. when the interface is wired to an SFP
> cage). In such case, phylink will validate the newly selected interface
> between the MAC and SFP based on the internal "supported_interfaces"
> field.
> 
> For now in stmmac, this field is populated based on :
>  - The interface specified in firmware (DT)
>  - The interfaces supported by XPCS, when XPCS is in use.
> 
> In our case, the PCS in Lynx and not XPCS.
> 
> This commit makes so that the .pcs_init() implementation of
> dwmac-socfpga populates the supported_interface when the Lynx PCS was
> successfully initialized.

I think it would also be worth adding this to Lynx, so phylink also
gets to know (via its validation) which PHY interface modes the PCS
can support.

However, maybe at this point we need to introduce an interface bitmap
into struct phylink_pcs so that these kinds of checks can be done in
phylink itself when it has the PCS, and it would also mean that stmmac
could do something like:

	struct phylink_pcs *pcs;

	if (priv->hw->xpcs)
		pcs = xpcs_to_phylink_pcs(priv->hw->xpcs);
	else
		pcs = priv->hw->phylink_pcs;

	if (pcs)
		phy_interface_or(priv->phylink_config.supported_interfaces,
				 priv->phylink_config.supported_interfaces,
				 pcs->supported_interfaces);

and not have to worry about this from individual PCS or platform code.

8<===
From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>
Subject: [PATCH net-next] net: pcs: lynx: implement pcs_validate()

Implement .pcs_validate() to restrict the interfaces to those which the
Lynx PCS supports.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/pcs/pcs-lynx.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/net/pcs/pcs-lynx.c b/drivers/net/pcs/pcs-lynx.c
index 767a8c0714ac..fd2e06dba92e 100644
--- a/drivers/net/pcs/pcs-lynx.c
+++ b/drivers/net/pcs/pcs-lynx.c
@@ -326,7 +326,22 @@ static void lynx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
 	}
 }
 
+static int lynx_pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
+			     const struct phylink_link_state *state)
+{
+	if (state->interface != PHY_INTERFACE_MODE_SGMII &&
+	    state->interface != PHY_INTERFACE_MODE_QSGMII &&
+	    state->interface != PHY_INTERFACE_MODE_1000BASEX &&
+	    state->interface != PHY_INTERFACE_MODE_2500BASEX &&
+	    state->interface != PHY_INTERFACE_MODE_10GBASER &&
+	    state->interface != PHY_INTERFACE_MODE_USXGMII)
+		return -EINVAL;
+
+	return 0;
+}
+
 static const struct phylink_pcs_ops lynx_pcs_phylink_ops = {
+	.pcs_validate = lynx_pcs_validate,
 	.pcs_inband_caps = lynx_pcs_inband_caps,
 	.pcs_get_state = lynx_pcs_get_state,
 	.pcs_config = lynx_pcs_config,
-- 
2.30.2

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


From m-malladi at ti.com  Fri Dec 13 04:26:52 2024
From: m-malladi at ti.com (Meghana Malladi)
Date: Fri, 13 Dec 2024 17:56:52 +0530
Subject: [EXTERNAL] Re: [PATCH net v4 1/2] net: ti: icssg-prueth: Fix
 firmware load sequence.
In-Reply-To: <304870d9-10c7-43b3-8255-8f2b0422d759@stanley.mountain>
References: <20241211135941.1800240-1-m-malladi@ti.com>
 <20241211135941.1800240-2-m-malladi@ti.com>
 <304870d9-10c7-43b3-8255-8f2b0422d759@stanley.mountain>
Message-ID: <5ed274f9-ca25-40a7-96c6-43b36b7663af@ti.com>



On 11/12/24 21:16, Dan Carpenter wrote:
> On Wed, Dec 11, 2024 at 07:?29:?40PM +0530, Meghana Malladi wrote: > 
> -static int prueth_emac_start(struct prueth *prueth, struct prueth_emac 
> *emac) > +static int prueth_emac_start(struct prueth *prueth, int slice) 
>  > { > struct icssg_firmwares
> ZjQcmQRYFpfptBannerStart
> This message was sent from outside of Texas Instruments.
> Do not click links or open attachments unless you recognize the source 
> of this email and know the content is safe.
> Report?Suspicious
> <https://us-phishalarm-ewt.proofpoint.com/EWT/v1/G3vK!uldqfRcOdo0RqyXEHNnjPxku43QuA2sRmrlczDVj-denyMX3qWPEeHokm6IS-fNmWZGSvK3Wn7nSFeNotanVMDOTlZZjZ8Ausf9AkMk$>
> ZjQcmQRYFpfptBannerEnd
> 
> On Wed, Dec 11, 2024 at 07:29:40PM +0530, Meghana Malladi wrote:
>> -static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>> +static int prueth_emac_start(struct prueth *prueth, int slice)
>>  {
>>  	struct icssg_firmwares *firmwares;
>>  	struct device *dev = prueth->dev;
>> -	int slice, ret;
>> +	int ret;
>>  
>>  	if (prueth->is_switch_mode)
>>  		firmwares = icssg_switch_firmwares;
>> @@ -177,16 +177,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>  	else
>>  		firmwares = icssg_emac_firmwares;
>>  
>> -	slice = prueth_emac_slice(emac);
>> -	if (slice < 0) {
>> -		netdev_err(emac->ndev, "invalid port\n");
>> -		return -EINVAL;
>> -	}
>> -
>> -	ret = icssg_config(prueth, emac, slice);
>> -	if (ret)
>> -		return ret;
>> -
>>  	ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
>>  	ret = rproc_boot(prueth->pru[slice]);
> 
> This isn't introduced by this patch but eventually Colin King is going to
> get annoyed with you for setting ret twice in a row.
> 

Yeah ok, I will fix this as part of this patch.

>>  	if (ret) {
>> @@ -208,7 +198,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>  		goto halt_rtu;
>>  	}
>>  
>> -	emac->fw_running = 1;
>>  	return 0;
>>  
>>  halt_rtu:
>> @@ -220,6 +209,78 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
>>  	return ret;
>>  }
>>  
>> +static int prueth_emac_common_start(struct prueth *prueth)
>> +{
>> +	struct prueth_emac *emac;
>> +	int ret = 0;
>> +	int slice;
>> +
>> +	if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1])
>> +		return -EINVAL;
>> +
>> +	/* clear SMEM and MSMC settings for all slices */
>> +	memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
>> +	memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
>> +
>> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false);
>> +	icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false);
>> +
>> +	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
>> +		icssg_init_fw_offload_mode(prueth);
>> +	else
>> +		icssg_init_emac_mode(prueth);
>> +
>> +	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
>> +		emac = prueth->emac[slice];
>> +		if (emac) {
>> +			ret |= icssg_config(prueth, emac, slice);
>> +			if (ret)
>> +				return ret;
> 
> Here we return directly.
> 
>> +		}
>> +		ret |= prueth_emac_start(prueth, slice);
> 
> Here we continue.  Generally, I would expect there to be some clean up
> on this error path like this:
> 
> 		ret = prueth_emac_start(prueth, slice);
> 		if (ret)
> 			goto unwind_slices;
> 
> 	...
> 
> 	return 0;
> 
> unwind_slices:
> 	while (--slice >= 0)
> 		prueth_emac_stop(prueth, slice);
> 
> 	return ret;
> 
> I dread to see how the cleanup is handled on this path...
> 
> Ok.  I've looked at it and, nope, it doesn't work.  This is freed in
> prueth_emac_common_stop() but partial allocations are not freed.
> Also the prueth_emac_stop() is open coded as three calls to
> rproc_shutdown() which is ugly.
> 
> I've written a blog which describes a system for writing error
> handling code.  If each function cleans up after itself by freeing
> its own partial allocations then you don't need to have a variable
> like "prueth->prus_running = 1;" to track how far the allocation
> process went before failing.
> https://urldefense.com/v3/__https://staticthinking.wordpress.com/2022/04/28/free-the-last-thing-style/__;!!G3vK!T5VCna8tMLVZNSL49zSwJOQBnoAQEa2xqXUUsIYY78CYm5mEH2wAdMX9CDEfMHXWsjTn0sG4mwKevVIOrgfAuQ$  <https://urldefense.com/v3/__https://staticthinking.wordpress.com/2022/04/28/free-the-last-thing-style/__;!!G3vK!T5VCna8tMLVZNSL49zSwJOQBnoAQEa2xqXUUsIYY78CYm5mEH2wAdMX9CDEfMHXWsjTn0sG4mwKevVIOrgfAuQ$>
> 

I agree that current error handling is all over the place. But I wasn't 
sure what would be the cleanest approach here. Thanks for sharing the 
blog, I have looked into it and looks very promising. I will try this 
approach and get back to you.

thanks & regards,
Meghana Malladi.

> regards,
> dan carpenter
> 


From ross.burton at arm.com  Fri Dec 13 04:27:49 2024
From: ross.burton at arm.com (Ross Burton)
Date: Fri, 13 Dec 2024 12:27:49 +0000
Subject: [PATCH] arm64: defconfig: remove obsolete CONFIG_SM_DISPCC_8650
Message-ID: <20241213122749.2132488-1-ross.burton@arm.com>

This option was removed from the Kconfig in commit 802b83205519 ("clk:
qcom: fold dispcc-sm8650 info dispcc-sm8550") but it was not removed
from the defconfig.

Fixes: 802b83205519 ("clk: qcom: fold dispcc-sm8650 info dispcc-sm8550")
Signed-off-by: Ross Burton <ross.burton at arm.com>
---
 arch/arm64/configs/defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e615863..c6d6a31a8f48c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1352,7 +1352,6 @@ CONFIG_SM_DISPCC_6115=m
 CONFIG_SM_DISPCC_8250=y
 CONFIG_SM_DISPCC_8450=m
 CONFIG_SM_DISPCC_8550=m
-CONFIG_SM_DISPCC_8650=m
 CONFIG_SM_GCC_4450=y
 CONFIG_SM_GCC_6115=y
 CONFIG_SM_GCC_8350=y
-- 
2.43.0



From syzbot+e13e654d315d4da1277c at syzkaller.appspotmail.com  Fri Dec 13 04:30:24 2024
From: syzbot+e13e654d315d4da1277c at syzkaller.appspotmail.com (syzbot)
Date: Fri, 13 Dec 2024 04:30:24 -0800
Subject: [syzbot] [arm?] WARNING in delayed_work_timer_fn
In-Reply-To: <00000000000046efb605fec3def0@google.com>
Message-ID: <675c28e0.050a0220.17d782.000d.GAE@google.com>

syzbot has found a reproducer for the following issue on:

HEAD commit:    2e7aff49b5da Merge branches 'for-next/core' and 'for-next/..
git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-kernelci
console output: https://syzkaller.appspot.com/x/log.txt?x=11ed5be8580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=696fb014d05da3a3
dashboard link: https://syzkaller.appspot.com/bug?extid=e13e654d315d4da1277c
compiler:       Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
userspace arch: arm64
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=10192d44580000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/ef408f67fde3/disk-2e7aff49.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/414ac17a20dc/vmlinux-2e7aff49.xz
kernel image: https://storage.googleapis.com/syzbot-assets/a93415d2a7e7/Image-2e7aff49.gz.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+e13e654d315d4da1277c at syzkaller.appspotmail.com

------------[ cut here ]------------
WARNING: CPU: 1 PID: 6023 at kernel/workqueue.c:2257 current_wq_worker kernel/workqueue_internal.h:69 [inline]
WARNING: CPU: 1 PID: 6023 at kernel/workqueue.c:2257 is_chained_work kernel/workqueue.c:2199 [inline]
WARNING: CPU: 1 PID: 6023 at kernel/workqueue.c:2257 __queue_work+0xe50/0x1308 kernel/workqueue.c:2256
Modules linked in:
CPU: 1 UID: 0 PID: 6023 Comm: klogd Not tainted 6.13.0-rc2-syzkaller-g2e7aff49b5da #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
pstate: 404000c5 (nZcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : __queue_work+0xe50/0x1308 kernel/workqueue_internal.h:69
lr : current_wq_worker kernel/workqueue_internal.h:69 [inline]
lr : is_chained_work kernel/workqueue.c:2199 [inline]
lr : __queue_work+0xe50/0x1308 kernel/workqueue.c:2256
sp : ffff800080017b40
x29: ffff800080017b90 x28: dfff800000000000 x27: ffff700010002f88
x26: dfff800000000000 x25: ffff0000d1c63800 x24: 0000000000000008
x23: 1fffe0001b14d791 x22: ffff0000d1c639c0 x21: 0000000000000100
x20: ffff0000d8a6bc80 x19: ffff0000da2f0930 x18: 1fffe000366c5e7e
x17: ffff800123d64000 x16: ffff80008326d65c x15: 0000000000000002
x14: 1ffff00011f300ca x13: dfff800000000000 x12: 00000000b1aebe1c
x11: 00000000beaa9035 x10: 0000000000ff0100 x9 : 0000000000000000
x8 : ffff0000d8a6bc80 x7 : ffff8000805819c0 x6 : 0000000000000000
x5 : 0000000000000001 x4 : 0000000000000001 x3 : ffff80008df6a320
x2 : ffff0000da2f0930 x1 : 0000000000000100 x0 : 0000000000000000
Call trace:
 current_wq_worker kernel/workqueue_internal.h:69 [inline] (P)
 is_chained_work kernel/workqueue.c:2199 [inline] (P)
 __queue_work+0xe50/0x1308 kernel/workqueue.c:2256 (P)
 current_wq_worker kernel/workqueue_internal.h:69 [inline] (L)
 is_chained_work kernel/workqueue.c:2199 [inline] (L)
 __queue_work+0xe50/0x1308 kernel/workqueue.c:2256 (L)
 delayed_work_timer_fn+0x74/0x90 kernel/workqueue.c:2485
 call_timer_fn+0x1b4/0x8b8 kernel/time/timer.c:1793
 expire_timers kernel/time/timer.c:1839 [inline]
 __run_timers kernel/time/timer.c:2418 [inline]
 __run_timer_base+0x59c/0x7b4 kernel/time/timer.c:2430
 run_timer_base kernel/time/timer.c:2439 [inline]
 run_timer_softirq+0xcc/0x194 kernel/time/timer.c:2449
 handle_softirqs+0x320/0xd34 kernel/softirq.c:554
 __do_softirq+0x14/0x20 kernel/softirq.c:588
 ____do_softirq+0x14/0x20 arch/arm64/kernel/irq.c:81
 call_on_irq_stack+0x24/0x4c arch/arm64/kernel/entry.S:891
 do_softirq_own_stack+0x20/0x2c arch/arm64/kernel/irq.c:86
 invoke_softirq kernel/softirq.c:435 [inline]
 __irq_exit_rcu+0x1d8/0x544 kernel/softirq.c:655
 irq_exit_rcu+0x14/0x84 kernel/softirq.c:671
 __el1_irq arch/arm64/kernel/entry-common.c:561 [inline]
 el1_interrupt+0x38/0x68 arch/arm64/kernel/entry-common.c:575
 el1h_64_irq_handler+0x18/0x24 arch/arm64/kernel/entry-common.c:580
 el1h_64_irq+0x6c/0x70 arch/arm64/kernel/entry.S:596
 __daif_local_irq_enable arch/arm64/include/asm/irqflags.h:26 [inline] (P)
 arch_local_irq_enable arch/arm64/include/asm/irqflags.h:48 [inline] (P)
 raw_spin_rq_unlock_irq kernel/sched/sched.h:1526 [inline] (P)
 finish_lock_switch+0xc0/0x1e4 kernel/sched/core.c:5123 (P)
 raw_spin_rq_unlock_irq kernel/sched/sched.h:1526 [inline] (L)
 finish_lock_switch+0xbc/0x1e4 kernel/sched/core.c:5123 (L)
 finish_task_switch+0x120/0x608 kernel/sched/core.c:5241
 context_switch kernel/sched/core.c:5372 [inline]
 __schedule+0x1748/0x27f0 kernel/sched/core.c:6756
 preempt_schedule_irq+0x80/0x188 kernel/sched/core.c:7078
 arm64_preempt_schedule_irq arch/arm64/kernel/entry-common.c:301 [inline]
 __el1_irq arch/arm64/kernel/entry-common.c:563 [inline]
 el1_interrupt+0x4c/0x68 arch/arm64/kernel/entry-common.c:575
 el1h_64_irq_handler+0x18/0x24 arch/arm64/kernel/entry-common.c:580
 el1h_64_irq+0x6c/0x70 arch/arm64/kernel/entry.S:596
 __daif_local_irq_enable arch/arm64/include/asm/irqflags.h:26 [inline] (P)
 arch_local_irq_enable arch/arm64/include/asm/irqflags.h:48 [inline] (P)
 do_notify_resume+0x5c/0x1f4 arch/arm64/kernel/entry-common.c:133 (P)
 do_notify_resume+0x58/0x1f4 arch/arm64/kernel/entry-common.c:133 (L)
 exit_to_user_mode_prepare arch/arm64/kernel/entry-common.c:169 [inline]
 exit_to_user_mode arch/arm64/kernel/entry-common.c:178 [inline]
 el0_interrupt+0xc8/0x248 arch/arm64/kernel/entry-common.c:832
 __el0_irq_handler_common+0x18/0x24 arch/arm64/kernel/entry-common.c:837
 el0t_64_irq_handler+0x10/0x1c arch/arm64/kernel/entry-common.c:842
 el0t_64_irq+0x198/0x19c arch/arm64/kernel/entry.S:601
irq event stamp: 35689
hardirqs last  enabled at (35688): [<ffff80008b687f2c>] __exit_to_kernel_mode arch/arm64/kernel/entry-common.c:85 [inline]
hardirqs last  enabled at (35688): [<ffff80008b687f2c>] exit_to_kernel_mode+0xdc/0x10c arch/arm64/kernel/entry-common.c:95
hardirqs last disabled at (35689): [<ffff80008b6a9b44>] __raw_spin_lock_irq include/linux/spinlock_api_smp.h:117 [inline]
hardirqs last disabled at (35689): [<ffff80008b6a9b44>] _raw_spin_lock_irq+0x28/0x70 kernel/locking/spinlock.c:170
softirqs last  enabled at (34558): [<ffff800080129934>] local_bh_enable+0x10/0x34 include/linux/bottom_half.h:32
softirqs last disabled at (35685): [<ffff800080020db4>] __do_softirq+0x14/0x20 kernel/softirq.c:588
---[ end trace 0000000000000000 ]---


---
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.


From linyunsheng at huawei.com  Fri Dec 13 04:27:31 2024
From: linyunsheng at huawei.com (Yunsheng Lin)
Date: Fri, 13 Dec 2024 20:27:31 +0800
Subject: [PATCH RFCv5 0/8] fix two bugs related to page_pool
Message-ID: <20241213122739.4050137-1-linyunsheng@huawei.com>

This version is mainly to see if using page_pool_item metadata
to keep track of all pages is the correct way to fix the dma
API misuse problem.

Note, it is not based on the latest net-next tree yet, but based
on the below commit in net-next:
commit da4fa00abe56 ("Merge branch 'mitigate-the-two-reallocations-issue-for-iptunnels'")

>From the below performance data, the overhead is avoided as much as possible
for time_bench_page_pool01_fast_path() and time_bench_page_pool02_ptr_ring,
and there is about 20ns overhead for time_bench_page_pool03_slow() for fixing
the bug.

Before this patchset:
root@(none)$ insmod bench_page_pool_simple.ko
root@(none)$ insmod bench_page_pool_simple.ko
[   67.667196] bench_page_pool_simple: Loaded
[   67.748321] time_bench: Type:for_loop Per elem: 0 cycles(tsc) 0.769 ns (step:0) - (measurement period time:0.076977910 sec time_interval:76977910) - (invoke count:100000000 tsc_interval:7697783)
[   69.851812] time_bench: Type:atomic_inc Per elem: 2 cycles(tsc) 20.862 ns (step:0) - (measurement period time:2.086207700 sec time_interval:2086207700) - (invoke count:100000000 tsc_interval:208620764)
[   70.019852] time_bench: Type:lock Per elem: 1 cycles(tsc) 15.015 ns (step:0) - (measurement period time:0.150151600 sec time_interval:150151600) - (invoke count:10000000 tsc_interval:15015154)
[   70.691100] time_bench: Type:rcu Per elem: 0 cycles(tsc) 6.541 ns (step:0) - (measurement period time:0.654142450 sec time_interval:654142450) - (invoke count:100000000 tsc_interval:65414239)
[   70.708119] bench_page_pool_simple: time_bench_page_pool01_fast_path(): Cannot use page_pool fast-path
[   70.975262] time_bench: Type:no-softirq-page_pool01 Per elem: 2 cycles(tsc) 25.785 ns (step:0) - (measurement period time:0.257850110 sec time_interval:257850110) - (invoke count:10000000 tsc_interval:25785005)
[   70.993931] bench_page_pool_simple: time_bench_page_pool02_ptr_ring(): Cannot use page_pool fast-path
[   71.575053] time_bench: Type:no-softirq-page_pool02 Per elem: 5 cycles(tsc) 57.191 ns (step:0) - (measurement period time:0.571916900 sec time_interval:571916900) - (invoke count:10000000 tsc_interval:57191684)
[   71.593722] bench_page_pool_simple: time_bench_page_pool03_slow(): Cannot use page_pool fast-path
[   73.384560] time_bench: Type:no-softirq-page_pool03 Per elem: 17 cycles(tsc) 178.197 ns (step:0) - (measurement period time:1.781979820 sec time_interval:1781979820) - (invoke count:10000000 tsc_interval:178197975)
[   73.403581] bench_page_pool_simple: pp_tasklet_handler(): in_serving_softirq fast-path
[   73.411485] bench_page_pool_simple: time_bench_page_pool01_fast_path(): in_serving_softirq fast-path
[   73.678410] time_bench: Type:tasklet_page_pool01_fast_path Per elem: 2 cycles(tsc) 25.780 ns (step:0) - (measurement period time:0.257807630 sec time_interval:257807630) - (invoke count:10000000 tsc_interval:25780758)
[   73.697686] bench_page_pool_simple: time_bench_page_pool02_ptr_ring(): in_serving_softirq fast-path
[   74.242807] time_bench: Type:tasklet_page_pool02_ptr_ring Per elem: 5 cycles(tsc) 53.608 ns (step:0) - (measurement period time:0.536089620 sec time_interval:536089620) - (invoke count:10000000 tsc_interval:53608957)
[   74.261996] bench_page_pool_simple: time_bench_page_pool03_slow(): in_serving_softirq fast-path
[   76.115762] time_bench: Type:tasklet_page_pool03_slow Per elem: 18 cycles(tsc) 184.508 ns (step:0) - (measurement period time:1.845082100 sec time_interval:1845082100) - (invoke count:10000000 tsc_interval:184508203)

After this patchset:
root@(none)$ insmod bench_page_pool_simple.ko
[   88.665991] bench_page_pool_simple: Loaded
[   88.747105] time_bench: Type:for_loop Per elem: 0 cycles(tsc) 0.769 ns (step:0) - (measurement period time:0.076981170 sec time_interval:76981170) - (invoke count:100000000 tsc_interval:7698109)
[   91.585102] time_bench: Type:atomic_inc Per elem: 2 cycles(tsc) 28.206 ns (step:0) - (measurement period time:2.820699360 sec time_interval:2820699360) - (invoke count:100000000 tsc_interval:282069929)
[   91.753048] time_bench: Type:lock Per elem: 1 cycles(tsc) 15.005 ns (step:0) - (measurement period time:0.150057320 sec time_interval:150057320) - (invoke count:10000000 tsc_interval:15005727)
[   92.424306] time_bench: Type:rcu Per elem: 0 cycles(tsc) 6.541 ns (step:0) - (measurement period time:0.654151520 sec time_interval:654151520) - (invoke count:100000000 tsc_interval:65415145)
[   92.441325] bench_page_pool_simple: time_bench_page_pool01_fast_path(): Cannot use page_pool fast-path
[   92.696225] time_bench: Type:no-softirq-page_pool01 Per elem: 2 cycles(tsc) 24.560 ns (step:0) - (measurement period time:0.245607210 sec time_interval:245607210) - (invoke count:10000000 tsc_interval:24560715)
[   92.714893] bench_page_pool_simple: time_bench_page_pool02_ptr_ring(): Cannot use page_pool fast-path
[   93.336550] time_bench: Type:no-softirq-page_pool02 Per elem: 6 cycles(tsc) 61.245 ns (step:0) - (measurement period time:0.612451380 sec time_interval:612451380) - (invoke count:10000000 tsc_interval:61245127)
[   93.355219] bench_page_pool_simple: time_bench_page_pool03_slow(): Cannot use page_pool fast-path
[   95.402370] time_bench: Type:no-softirq-page_pool03 Per elem: 20 cycles(tsc) 203.828 ns (step:0) - (measurement period time:2.038286740 sec time_interval:2038286740) - (invoke count:10000000 tsc_interval:203828660)
[   95.421395] bench_page_pool_simple: pp_tasklet_handler(): in_serving_softirq fast-path
[   95.429301] bench_page_pool_simple: time_bench_page_pool01_fast_path(): in_serving_softirq fast-path
[   95.684025] time_bench: Type:tasklet_page_pool01_fast_path Per elem: 2 cycles(tsc) 24.560 ns (step:0) - (measurement period time:0.245605490 sec time_interval:245605490) - (invoke count:10000000 tsc_interval:24560544)
[   95.703301] bench_page_pool_simple: time_bench_page_pool02_ptr_ring(): in_serving_softirq fast-path
[   96.401877] time_bench: Type:tasklet_page_pool02_ptr_ring Per elem: 6 cycles(tsc) 68.954 ns (step:0) - (measurement period time:0.689544160 sec time_interval:689544160) - (invoke count:10000000 tsc_interval:68954410)
[   96.421065] bench_page_pool_simple: time_bench_page_pool03_slow(): in_serving_softirq fast-path
[   98.496283] time_bench: Type:tasklet_page_pool03_slow Per elem: 20 cycles(tsc) 206.653 ns (step:0) - (measurement period time:2.066533210 sec time_interval:2066533210) - (invoke count:10000000 tsc_interval:206653316)

1. https://lore.kernel.org/lkml/8067f204-1380-4d37-8ffd-007fc6f26738 at kernel.org/T/

CC: Alexander Lobakin <aleksander.lobakin at intel.com>
CC: Robin Murphy <robin.murphy at arm.com>
CC: Alexander Duyck <alexander.duyck at gmail.com>
CC: Andrew Morton <akpm at linux-foundation.org>
CC: IOMMU <iommu at lists.linux.dev>
CC: MM <linux-mm at kvack.org>

Change log:
V5:
  1. Support unlimit inflight pages.
  2. Add some optimization to avoid the overhead of fixing bug.

V4:
  1. use scanning to do the unmapping
  2. spilt dma sync skipping into separate patch

V3:
  1. Target net-next tree instead of net tree.
  2. Narrow the rcu lock as the discussion in v2.
  3. Check the ummapping cnt against the inflight cnt.

V2:
  1. Add a item_full stat.
  2. Use container_of() for page_pool_to_pp().

Yunsheng Lin (8):
  page_pool: introduce page_pool_to_pp() API
  page_pool: fix timing for checking and disabling napi_local
  page_pool: fix IOMMU crash when driver has already unbound
  page_pool: support unlimited number of inflight pages
  page_pool: skip dma sync operation for inflight pages
  page_pool: use list instead of ptr_ring for ring cache
  page_pool: batch refilling pages to reduce atomic operation
  page_pool: use list instead of array for alloc cache

 drivers/net/ethernet/freescale/fec_main.c     |   8 +-
 .../ethernet/google/gve/gve_buffer_mgmt_dqo.c |   2 +-
 drivers/net/ethernet/intel/iavf/iavf_txrx.c   |   6 +-
 drivers/net/ethernet/intel/idpf/idpf_txrx.c   |  14 +-
 drivers/net/ethernet/intel/libeth/rx.c        |   2 +-
 .../net/ethernet/mellanox/mlx5/core/en/xdp.c  |   3 +-
 drivers/net/netdevsim/netdev.c                |   6 +-
 drivers/net/wireless/mediatek/mt76/mt76.h     |   2 +-
 include/linux/mm_types.h                      |   2 +-
 include/linux/skbuff.h                        |   1 +
 include/net/libeth/rx.h                       |   3 +-
 include/net/netmem.h                          |  10 +-
 include/net/page_pool/helpers.h               |  11 +
 include/net/page_pool/types.h                 |  57 +-
 net/core/devmem.c                             |   4 +-
 net/core/netmem_priv.h                        |   5 +-
 net/core/page_pool.c                          | 660 ++++++++++++++----
 net/core/page_pool_priv.h                     |  12 +-
 net/core/skbuff.c                             |   3 +-
 net/core/xdp.c                                |   3 +-
 20 files changed, 650 insertions(+), 164 deletions(-)

-- 
2.33.0



From linyunsheng at huawei.com  Fri Dec 13 04:27:32 2024
From: linyunsheng at huawei.com (Yunsheng Lin)
Date: Fri, 13 Dec 2024 20:27:32 +0800
Subject: [PATCH RFCv5 1/8] page_pool: introduce page_pool_to_pp() API
In-Reply-To: <20241213122739.4050137-1-linyunsheng@huawei.com>
References: <20241213122739.4050137-1-linyunsheng@huawei.com>
Message-ID: <20241213122739.4050137-2-linyunsheng@huawei.com>

introduce page_pool_to_pp() API to avoid caller accessing
page->pp directly.

Signed-off-by: Yunsheng Lin <linyunsheng at huawei.com>
---
 drivers/net/ethernet/freescale/fec_main.c          |  8 +++++---
 .../net/ethernet/google/gve/gve_buffer_mgmt_dqo.c  |  2 +-
 drivers/net/ethernet/intel/iavf/iavf_txrx.c        |  6 ++++--
 drivers/net/ethernet/intel/idpf/idpf_txrx.c        | 14 +++++++++-----
 drivers/net/ethernet/intel/libeth/rx.c             |  2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c   |  3 ++-
 drivers/net/netdevsim/netdev.c                     |  6 ++++--
 drivers/net/wireless/mediatek/mt76/mt76.h          |  2 +-
 include/net/libeth/rx.h                            |  3 ++-
 include/net/page_pool/helpers.h                    |  5 +++++
 net/core/skbuff.c                                  |  3 ++-
 net/core/xdp.c                                     |  3 ++-
 12 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 1b55047c0237..98fce41d088c 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1009,7 +1009,8 @@ static void fec_enet_bd_init(struct net_device *dev)
 				struct page *page = txq->tx_buf[i].buf_p;
 
 				if (page)
-					page_pool_put_page(page->pp, page, 0, false);
+					page_pool_put_page(page_pool_to_pp(page),
+							   page, 0, false);
 			}
 
 			txq->tx_buf[i].buf_p = NULL;
@@ -1549,7 +1550,7 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
 			xdp_return_frame_rx_napi(xdpf);
 		} else { /* recycle pages of XDP_TX frames */
 			/* The dma_sync_size = 0 as XDP_TX has already synced DMA for_device */
-			page_pool_put_page(page->pp, page, 0, true);
+			page_pool_put_page(page_pool_to_pp(page), page, 0, true);
 		}
 
 		txq->tx_buf[index].buf_p = NULL;
@@ -3311,7 +3312,8 @@ static void fec_enet_free_buffers(struct net_device *ndev)
 			} else {
 				struct page *page = txq->tx_buf[i].buf_p;
 
-				page_pool_put_page(page->pp, page, 0, false);
+				page_pool_put_page(page_pool_to_pp(page),
+						   page, 0, false);
 			}
 
 			txq->tx_buf[i].buf_p = NULL;
diff --git a/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c b/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c
index 403f0f335ba6..db5926152c72 100644
--- a/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c
+++ b/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c
@@ -210,7 +210,7 @@ void gve_free_to_page_pool(struct gve_rx_ring *rx,
 	if (!page)
 		return;
 
-	page_pool_put_full_page(page->pp, page, allow_direct);
+	page_pool_put_full_page(page_pool_to_pp(page), page, allow_direct);
 	buf_state->page_info.page = NULL;
 }
 
diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
index 26b424fd6718..658d8f9a6abb 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
@@ -1050,7 +1050,8 @@ static void iavf_add_rx_frag(struct sk_buff *skb,
 			     const struct libeth_fqe *rx_buffer,
 			     unsigned int size)
 {
-	u32 hr = rx_buffer->page->pp->p.offset;
+	struct page_pool *pool = page_pool_to_pp(rx_buffer->page);
+	u32 hr = pool->p.offset;
 
 	skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page,
 			rx_buffer->offset + hr, size, rx_buffer->truesize);
@@ -1067,7 +1068,8 @@ static void iavf_add_rx_frag(struct sk_buff *skb,
 static struct sk_buff *iavf_build_skb(const struct libeth_fqe *rx_buffer,
 				      unsigned int size)
 {
-	u32 hr = rx_buffer->page->pp->p.offset;
+	struct page_pool *pool = page_pool_to_pp(rx_buffer->page);
+	u32 hr = pool->p.offset;
 	struct sk_buff *skb;
 	void *va;
 
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
index da2a5becf62f..38ad32678bcc 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -385,7 +385,8 @@ static void idpf_rx_page_rel(struct libeth_fqe *rx_buf)
 	if (unlikely(!rx_buf->page))
 		return;
 
-	page_pool_put_full_page(rx_buf->page->pp, rx_buf->page, false);
+	page_pool_put_full_page(page_pool_to_pp(rx_buf->page), rx_buf->page,
+				false);
 
 	rx_buf->page = NULL;
 	rx_buf->offset = 0;
@@ -3097,7 +3098,8 @@ idpf_rx_process_skb_fields(struct idpf_rx_queue *rxq, struct sk_buff *skb,
 void idpf_rx_add_frag(struct idpf_rx_buf *rx_buf, struct sk_buff *skb,
 		      unsigned int size)
 {
-	u32 hr = rx_buf->page->pp->p.offset;
+	struct page_pool *pool = page_pool_to_pp(rx_buf->page);
+	u32 hr = pool->p.offset;
 
 	skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buf->page,
 			rx_buf->offset + hr, size, rx_buf->truesize);
@@ -3129,8 +3131,10 @@ static u32 idpf_rx_hsplit_wa(const struct libeth_fqe *hdr,
 	if (!libeth_rx_sync_for_cpu(buf, copy))
 		return 0;
 
-	dst = page_address(hdr->page) + hdr->offset + hdr->page->pp->p.offset;
-	src = page_address(buf->page) + buf->offset + buf->page->pp->p.offset;
+	dst = page_address(hdr->page) + hdr->offset +
+		page_pool_to_pp(hdr->page)->p.offset;
+	src = page_address(buf->page) + buf->offset +
+		page_pool_to_pp(buf->page)->p.offset;
 	memcpy(dst, src, LARGEST_ALIGN(copy));
 
 	buf->offset += copy;
@@ -3148,7 +3152,7 @@ static u32 idpf_rx_hsplit_wa(const struct libeth_fqe *hdr,
  */
 struct sk_buff *idpf_rx_build_skb(const struct libeth_fqe *buf, u32 size)
 {
-	u32 hr = buf->page->pp->p.offset;
+	u32 hr = page_pool_to_pp(buf->page)->p.offset;
 	struct sk_buff *skb;
 	void *va;
 
diff --git a/drivers/net/ethernet/intel/libeth/rx.c b/drivers/net/ethernet/intel/libeth/rx.c
index f20926669318..385afca0e61d 100644
--- a/drivers/net/ethernet/intel/libeth/rx.c
+++ b/drivers/net/ethernet/intel/libeth/rx.c
@@ -207,7 +207,7 @@ EXPORT_SYMBOL_NS_GPL(libeth_rx_fq_destroy, LIBETH);
  */
 void libeth_rx_recycle_slow(struct page *page)
 {
-	page_pool_recycle_direct(page->pp, page);
+	page_pool_recycle_direct(page_pool_to_pp(page), page);
 }
 EXPORT_SYMBOL_NS_GPL(libeth_rx_recycle_slow, LIBETH);
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
index 94b291662087..78866b5473da 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
@@ -716,7 +716,8 @@ static void mlx5e_free_xdpsq_desc(struct mlx5e_xdpsq *sq,
 				/* No need to check ((page->pp_magic & ~0x3UL) == PP_SIGNATURE)
 				 * as we know this is a page_pool page.
 				 */
-				page_pool_recycle_direct(page->pp, page);
+				page_pool_recycle_direct(page_pool_to_pp(page),
+							 page);
 			} while (++n < num);
 
 			break;
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 0be47fed4efc..088f4836a0e2 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -632,7 +632,8 @@ nsim_pp_hold_write(struct file *file, const char __user *data,
 		if (!ns->page)
 			ret = -ENOMEM;
 	} else {
-		page_pool_put_full_page(ns->page->pp, ns->page, false);
+		page_pool_put_full_page(page_pool_to_pp(ns->page), ns->page,
+					false);
 		ns->page = NULL;
 	}
 	rtnl_unlock();
@@ -831,7 +832,8 @@ void nsim_destroy(struct netdevsim *ns)
 
 	/* Put this intentionally late to exercise the orphaning path */
 	if (ns->page) {
-		page_pool_put_full_page(ns->page->pp, ns->page, false);
+		page_pool_put_full_page(page_pool_to_pp(ns->page), ns->page,
+					false);
 		ns->page = NULL;
 	}
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 0b75a45ad2e8..94a277290909 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -1688,7 +1688,7 @@ static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
 {
 	struct page *page = virt_to_head_page(buf);
 
-	page_pool_put_full_page(page->pp, page, allow_direct);
+	page_pool_put_full_page(page_pool_to_pp(page), page, allow_direct);
 }
 
 static inline void *
diff --git a/include/net/libeth/rx.h b/include/net/libeth/rx.h
index 43574bd6612f..beee7ddd77a5 100644
--- a/include/net/libeth/rx.h
+++ b/include/net/libeth/rx.h
@@ -137,7 +137,8 @@ static inline bool libeth_rx_sync_for_cpu(const struct libeth_fqe *fqe,
 		return false;
 	}
 
-	page_pool_dma_sync_for_cpu(page->pp, page, fqe->offset, len);
+	page_pool_dma_sync_for_cpu(page_pool_to_pp(page), page, fqe->offset,
+				   len);
 
 	return true;
 }
diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index 793e6fd78bc5..1659f1995985 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -83,6 +83,11 @@ static inline u64 *page_pool_ethtool_stats_get(u64 *data, const void *stats)
 }
 #endif
 
+static inline struct page_pool *page_pool_to_pp(struct page *page)
+{
+	return page->pp;
+}
+
 /**
  * page_pool_dev_alloc_pages() - allocate a page.
  * @pool:	pool from which to allocate
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6841e61a6bd0..54e8e7cf2bc9 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1033,7 +1033,8 @@ bool napi_pp_put_page(netmem_ref netmem)
 	if (unlikely(!is_pp_netmem(netmem)))
 		return false;
 
-	page_pool_put_full_netmem(netmem_get_pp(netmem), netmem, false);
+	page_pool_put_full_netmem(page_pool_to_pp(netmem_to_page(netmem)),
+				  netmem, false);
 
 	return true;
 }
diff --git a/net/core/xdp.c b/net/core/xdp.c
index bcc5551c6424..e8582036b411 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -384,7 +384,8 @@ void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct,
 		/* No need to check ((page->pp_magic & ~0x3UL) == PP_SIGNATURE)
 		 * as mem->type knows this a page_pool page
 		 */
-		page_pool_put_full_page(page->pp, page, napi_direct);
+		page_pool_put_full_page(page_pool_to_pp(page), page,
+					napi_direct);
 		break;
 	case MEM_TYPE_PAGE_SHARED:
 		page_frag_free(data);
-- 
2.33.0



From xu.yang_2 at nxp.com  Fri Dec 13 04:55:28 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Fri, 13 Dec 2024 20:55:28 +0800
Subject: [PATCH] ARM: dts: nxp: imx6qdl: add dr_mode to usbotg
In-Reply-To: <cb6c7f8d-6244-4370-944f-a1a2beac3a79@canonical.com>
References: <20241212043126.73045-1-hui.wang@canonical.com>
 <20241213081729.ohgs7tyyzywd4uyc@hippo>
 <cb6c7f8d-6244-4370-944f-a1a2beac3a79@canonical.com>
Message-ID: <20241213125528.m2skucuhqtrc5f4s@hippo>

On Fri, Dec 13, 2024 at 07:25:32PM +0800, Hui Wang wrote:
> 
> On 12/13/24 16:17, Xu Yang wrote:
> > Hi,
> > 
> > On Thu, Dec 12, 2024 at 12:31:26PM +0800, Hui Wang wrote:
> > > For the chipidea usb driver, if the dr_mode is not set, it will set
> > > the device to otg mode by default, so here the dr_mode has not been
> > > set for a long time. But some testcases need to parse the dr_mode from
> > > DT and decide the follow-up test strategy, here set the dr_mode to otg
> > > explicitly for QA's testcases.
> > The dr_mode is board specific property, so we normally don't put it in
> > dtsi file. Also, imx6qdl.dtsi is a common dtsi, therefore it's not a
> > correct place. I wonder you don't set dr_mode in other dts file which
> > include will imx6qdl.dtsi?
> 
> Yes, our QA reported this issue against the imx6q-sabresd board, I thought
> dr_mode could be overwritten if board dts set the dr_mode, so this change
> will not impact existing boards. But as you said "we normally don't put it
> in dtsi file", I will move it to imx6q-sabresd.dts.

Okay. You can move it to imx6qdl-sabresd.dtsi too. Then you can reuse
&usbotg {}.

Thanks,
Xu Yang

> 
> Thanks,
> 
> Hui.
> 
> > Thanks,
> > Xu Yang
> > 
> > > Signed-off-by: Hui Wang <hui.wang at canonical.com>
> > > ---
> > >   arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 1 +
> > >   1 file changed, 1 insertion(+)
> > > 
> > > diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
> > > index d2200c9db25a..285fb7314a88 100644
> > > --- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
> > > +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
> > > @@ -982,6 +982,7 @@ usbotg: usb at 2184000 {
> > >   				clocks = <&clks IMX6QDL_CLK_USBOH3>;
> > >   				fsl,usbphy = <&usbphy1>;
> > >   				fsl,usbmisc = <&usbmisc 0>;
> > > +				dr_mode = "otg";
> > >   				ahb-burst-config = <0x0>;
> > >   				tx-burst-size-dword = <0x10>;
> > >   				rx-burst-size-dword = <0x10>;
> > > -- 
> > > 2.34.1
> > > 


From konrad.dybcio at oss.qualcomm.com  Fri Dec 13 05:08:48 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 13 Dec 2024 14:08:48 +0100
Subject: [PATCH 1/2] arm64: dts: qcom: x1e80100-crd: Add USB multiport
 fingerprint readery
In-Reply-To: <Z08sMkbLF0b1DZTp@linaro.org>
References: <20241118-x1e80100-crd-fp-v1-0-ec6b553a2e53@linaro.org>
 <20241118-x1e80100-crd-fp-v1-1-ec6b553a2e53@linaro.org>
 <Z07bgH5vVk44zuEH@hovoldconsulting.com> <Z07r3Upr50vLluyn@linaro.org>
 <41106fd7-5348-4d21-9ae7-8466f5634b4c@oss.qualcomm.com>
 <Z08sMkbLF0b1DZTp@linaro.org>
Message-ID: <04e489be-231a-43b8-a701-1173ea744bae@oss.qualcomm.com>

On 3.12.2024 5:05 PM, Stephan Gerhold wrote:
> On Tue, Dec 03, 2024 at 09:07:22PM +0530, Krishna Kurapati wrote:
>> On 12/3/2024 5:00 PM, Stephan Gerhold wrote:
>>> On Tue, Dec 03, 2024 at 11:20:48AM +0100, Johan Hovold wrote:
>>>> [ +CC: Krishna, Thinh and the USB list ]
>>>>
>>>> On Mon, Nov 18, 2024 at 11:34:29AM +0100, Stephan Gerhold wrote:
>>>>> The X1E80100 CRD has a Goodix fingerprint reader connected to the USB
>>>>> multiport controller on eUSB6. All other ports (including USB super-speed
>>>>> pins) are unused.
>>>>>
>>>>> Set it up in the device tree together with the NXP PTN3222 repeater.
>>>>>
>>>>> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
>>>>> ---
>>>>>   arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 48 +++++++++++++++++++++++++++++++
>>>>>   1 file changed, 48 insertions(+)
>>>>>
>>>>> diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>>>>> index 39f9d9cdc10d..44942931c18f 100644
>>>>> --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>>>>> +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
>>>>> @@ -735,6 +735,26 @@ keyboard at 3a {
>>>>> [...]
>>>>> @@ -1260,3 +1288,23 @@ &usb_1_ss2_dwc3_hs {
>>>>>   &usb_1_ss2_qmpphy_out {
>>>>>   	remote-endpoint = <&pmic_glink_ss2_ss_in>;
>>>>>   };
>>>>> +
>>>>> +&usb_mp {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&usb_mp_dwc3 {
>>>>> +	/* Limit to USB 2.0 and single port */
>>>>> +	maximum-speed = "high-speed";
>>>>> +	phys = <&usb_mp_hsphy1>;
>>>>> +	phy-names = "usb2-1";
>>>>> +};
>>>>
>>>> The dwc3 driver determines (and acts on) the number of ports based on
>>>> the port interrupts in DT and controller capabilities.
>>>>
>>>> I'm not sure we can (should) just drop the other HS PHY and the SS PHYs
>>>> that would still be there in the SoC (possibly initialised by the boot
>>>> firmware).
>>>>
>>>> I had a local patch to enable the multiport controller (for the suspend
>>>> work) and I realise that you'd currently need to specify a repeater also
>>>> for the HS PHY which does not have one, but that should be possible to
>>>> fix somehow.
>>>>
>>>
>>> I think there are two separate questions here:
>>>
>>>   1. Should we (or do we even need to) enable unused PHYs?
>>>   2. Do we need to power off unused PHYs left enabled by the firmware?
>>>
>>> For (1), I'm not not sure if there is a technical reason that requires
>>> us to. And given that PHYs typically consume quite a bit of power, I'm
>>> not sure if we should. Perhaps it's not worth spending effort on this
>>> minor optimization now, but then the device tree would ideally still
>>> tell us which PHYs are actually used (for future optimizations).
>>>
>>> For (2), yes, we probably need to. But my impression so far is that this
>>> might be a larger problem that we need to handle on the SoC level. I
>>> have seen some firmware versions that blindly power up all USB
>>> controllers, even completely unused ones. Ideally we would power down
>>> unused components during startup and then leave them off.
>>>
>>
>> This question might be a dumb one, if so please ignore it.
>>
>> But if we skip adding unused phys in DTS node, the core driver wouldn't have
>> access to all phys and we wouldn't be able to get references to unused ones
>> (un-mentioned ones in DTS). So how can we power them off from core driver if
>> we don't have reference to them ?
>>
> 
> The question is not dumb at all, it's a very valid one. :-)
> 
> Perhaps it's easier if we keep them all listed on the USB controllers
> and have something else to mark them as unused. The downside of that
> option is that we might not be able to have a complete description of
> the PHY with all resources. For example on the CRD there is no eUSB
> repeater we could model for the first USB port (usb2-0), but it's needed
> to enable the qcom,x1e80100-snps-eusb2-phy.

So we have the choice between a silent failure or a loud non-failure wrt
acquiring the repeater.. not sure which one is better

Konrad 


From dmitry.baryshkov at linaro.org  Fri Dec 13 05:28:52 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 13 Dec 2024 15:28:52 +0200
Subject: [PATCH v6 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <b02fb998-9420-4954-8e48-82447493bbb7@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com> <20241209033923.3009629-13-victor.liu@nxp.com>
 <3j4fguv4oienfaj4fghpiqpmnq3aczu4azhdo5jzvywc5mawm5@hh33p3dhf6xa>
 <db4d9d4e-855f-4647-9b93-ccc5ec0202b3@nxp.com> <q6pdop6ucowtoxxr66czq7yooujyvp6qs5vcg6gpmi3q4rs4l3@szyqt5pxteoz>
 <b02fb998-9420-4954-8e48-82447493bbb7@nxp.com>
Message-ID: <CAA8EJppBpeMA3aSzk025tvzfTW-bFxeZS4kj0Ujk_AuCyoxnEg@mail.gmail.com>

On Fri, 13 Dec 2024 at 08:06, Liu Ying <victor.liu at nxp.com> wrote:
>
> On 12/12/2024, Dmitry Baryshkov wrote:
> > On Wed, Dec 11, 2024 at 03:43:20PM +0800, Liu Ying wrote:
> >> On 12/10/2024, Dmitry Baryshkov wrote:
> >>> On Mon, Dec 09, 2024 at 11:39:16AM +0800, Liu Ying wrote:
> >>>> i.MX8qxp Display Controller(DC) is comprised of three main components that
> >>>> include a blit engine for 2D graphics accelerations, display controller for
> >>>> display output processing, as well as a command sequencer.  Add kernel
> >>>> mode setting support for the display controller part with two CRTCs and
> >>>> two primary planes(backed by FetchLayer and FetchWarp respectively).  The
> >>>> registers of the display controller are accessed without command sequencer
> >>>> involved, instead just by using CPU.  The command sequencer is supposed to
> >>>> be used by the blit engine.
> >>>>
> >>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> >>>> ---
> >>>> v6:
> >>>> * No change.
> >>>>
> >>>> v5:
> >>>> * Replace .remove_new with .remove in dc-drv.c. (Uwe)
> >>>>
> >>>> v4:
> >>>> * Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
> >>>>   function calls from KMS routine to initialization stage. (Dmitry)
> >>>> * Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
> >>>>   appropriate .h header files or .c source files. (Dmitry)
> >>>> * Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
> >>>> * Drop dc_drm->pe_rpm_count. (Dmitry)
> >>>> * Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
> >>>> * Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
> >>>>   Instead, put it in struct dc_crtc.  (Dmitry)
> >>>> * Call devm_request_irq() to request IRQs, instead of using drmm action.
> >>>>   (Dmitry)
> >>>> * Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
> >>>> * Select DRM_CLIENT_SELECTION due to rebase.
> >>>> * Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
> >>>> * Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
> >>>> * Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
> >>>>   rebase.
> >>>> * Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
> >>>>   register dc_drm_component_unbind_all() action.
> >>>> * Request interrupts in dc_crtc_post_init() after encoder initialization to
> >>>>   make sure next bridge is found first.
> >>>>
> >>>> v3:
> >>>> * No change.
> >>>>
> >>>> v2:
> >>>> * Find next bridge from TCon's port.
> >>>> * Drop drm/drm_module.h include from dc-drv.c.
> >>>>
> >>>>  drivers/gpu/drm/imx/dc/Kconfig    |   5 +
> >>>>  drivers/gpu/drm/imx/dc/Makefile   |   5 +-
> >>>>  drivers/gpu/drm/imx/dc/dc-crtc.c  | 558 ++++++++++++++++++++++++++++++
> >>>>  drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
> >>>>  drivers/gpu/drm/imx/dc/dc-drv.c   | 244 +++++++++++++
> >>>>  drivers/gpu/drm/imx/dc/dc-drv.h   |  19 +
> >>>>  drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
> >>>>  drivers/gpu/drm/imx/dc/dc-kms.h   |  58 ++++
> >>>>  drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
> >>>>  9 files changed, 1274 insertions(+), 2 deletions(-)
> >>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
> >>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
> >>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
> >>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
> >>>>
> >>>> diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
> >>>> index 1fc84c7475de..415993207f2e 100644
> >>>> --- a/drivers/gpu/drm/imx/dc/Kconfig
> >>>> +++ b/drivers/gpu/drm/imx/dc/Kconfig
> >>>> @@ -1,6 +1,11 @@
> >>>>  config DRM_IMX8_DC
> >>>>    tristate "Freescale i.MX8 Display Controller Graphics"
> >>>>    depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
> >>>> +  select DRM_CLIENT_SELECTION
> >>>> +  select DRM_GEM_DMA_HELPER
> >>>> +  select DRM_KMS_HELPER
> >>>> +  select DRM_DISPLAY_HELPER
> >>>> +  select DRM_BRIDGE_CONNECTOR
> >>>>    select GENERIC_IRQ_CHIP
> >>>>    select REGMAP
> >>>>    select REGMAP_MMIO
> >>>> diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
> >>>> index 1ce3e8a8db22..b9d33c074984 100644
> >>>> --- a/drivers/gpu/drm/imx/dc/Makefile
> >>>> +++ b/drivers/gpu/drm/imx/dc/Makefile
> >>>> @@ -1,6 +1,7 @@
> >>>>  # SPDX-License-Identifier: GPL-2.0
> >>>>
> >>>> -imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
> >>>> -              dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
> >>>> +imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
> >>>> +              dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
> >>>> +              dc-plane.o dc-tc.o
> >>>>
> >>>>  obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
> >>>> diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
> >>>> new file mode 100644
> >>>> index 000000000000..fd6daa1807d8
> >>>> --- /dev/null
> >>>> +++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
> >>>> @@ -0,0 +1,558 @@
> >>>> +// SPDX-License-Identifier: GPL-2.0+
> >>>> +/*
> >>>> + * Copyright 2024 NXP
> >>>> + */
> >>>> +
> >>>> +#include <linux/completion.h>
> >>>> +#include <linux/container_of.h>
> >>>> +#include <linux/interrupt.h>
> >>>> +#include <linux/irqreturn.h>
> >>>> +#include <linux/pm_runtime.h>
> >>>> +#include <linux/spinlock.h>
> >>>> +
> >>>> +#include <drm/drm_atomic.h>
> >>>> +#include <drm/drm_atomic_helper.h>
> >>>> +#include <drm/drm_atomic_state_helper.h>
> >>>> +#include <drm/drm_crtc.h>
> >>>> +#include <drm/drm_device.h>
> >>>> +#include <drm/drm_drv.h>
> >>>> +#include <drm/drm_modes.h>
> >>>> +#include <drm/drm_modeset_helper_vtables.h>
> >>>> +#include <drm/drm_plane.h>
> >>>> +#include <drm/drm_print.h>
> >>>> +#include <drm/drm_vblank.h>
> >>>> +
> >>>> +#include "dc-de.h"
> >>>> +#include "dc-drv.h"
> >>>> +#include "dc-kms.h"
> >>>> +#include "dc-pe.h"
> >>>> +
> >>>> +#define dc_crtc_dbg(crtc, fmt, ...)                                       \
> >>>> +do {                                                                      \
> >>>> +  typeof(crtc) _crtc = (crtc);                                    \
> >>>
> >>> Use exact type instead of typeof.
> >>
> >> Will do.
> >>
> >>>
> >>>> +  drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt,                    \
> >>>> +              _crtc->base.id, _crtc->name, ##__VA_ARGS__);        \
> >>>> +} while (0)
> >>>> +
> >>>> +#define dc_crtc_err(crtc, fmt, ...)                                       \
> >>>> +do {                                                                      \
> >>>> +  typeof(crtc) _crtc = (crtc);                                    \
> >>>> +  drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt,                        \
> >>>> +          _crtc->base.id, _crtc->name, ##__VA_ARGS__);            \
> >>>> +} while (0)
> >>>> +
> >>>> +#define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c)                            \
> >>>> +do {                                                                      \
> >>>> +  unsigned long ret;                                              \
> >>>> +  ret = wait_for_completion_timeout(&dc_crtc->c, HZ);             \
> >>>> +  if (ret == 0)                                                   \
> >>>> +          dc_crtc_err(crtc, "%s: wait for " #c " timeout\n",      \
> >>>> +                                                  __func__);      \
> >>>> +} while (0)
> >>>> +
> >>>> +#define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg)                                   \
> >>>> +do {                                                                      \
> >>>> +  typeof(fg) _fg = (fg);                                          \
> >>>> +  if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) {         \
> >>>> +          dc_fg_secondary_clear_channel_status(_fg);              \
> >>>> +          dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n",          \
> >>>> +                                                  __func__);      \
> >>>> +  }                                                               \
> >>>> +} while (0)
> >>>> +
> >>>> +#define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg)                    \
> >>>> +do {                                                                      \
> >>>> +  if (dc_fg_wait_for_secondary_syncup(fg))                        \
> >>>> +          dc_crtc_err(crtc,                                       \
> >>>> +                  "%s: FrameGen secondary channel isn't syncup\n",\
> >>>> +                                                  __func__);      \
> >>>> +} while (0)
> >>>> +
> >>>> +static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
> >>>> +{
> >>>> +  return container_of(crtc, struct dc_crtc, base);
> >>>> +}
> >>>> +
> >>>> +static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +
> >>>> +  return dc_fg_get_frame_index(dc_crtc->fg);
> >>>> +}
> >>>> +
> >>>> +static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +
> >>>> +  enable_irq(dc_crtc->irq_dec_framecomplete);
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +
> >>>> +  disable_irq_nosync(dc_crtc->irq_dec_framecomplete);
> >>>
> >>> Why is it _nosync?
> >>
> >> Because disable_irq() can only be called from preemptible code according to
> >> it's kerneldoc. If I use disable_irq() here, I get this with
> >> CONFIG_DEBUG_ATOMIC_SLEEP enabled:
> >
> > Please add a one-line comment, like "nosync because of the atomic
> > context"
>
> Will do.
>
> >
> >>
> >> [   50.607503] BUG: sleeping function called from invalid context at kernel/irq/manage.c:738
> >> [   50.615691] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/0
> >> [   50.623527] preempt_count: 10003, expected: 0
> >> [   50.627888] RCU nest depth: 0, expected: 0
> >> [   50.631993] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.13.0-rc2-next-20241209-00026-g800cb5b7df74 #1407
> >> [   50.642092] Hardware name: Freescale i.MX8QXP MEK (DT)
> >> [   50.647237] Call trace:
> >> [   50.649687]  show_stack+0x18/0x24 (C)
> >> [   50.653369]  dump_stack_lvl+0x80/0xb4
> >> [   50.657043]  dump_stack+0x18/0x24
> >> [   50.660370]  __might_resched+0x114/0x170
> >> [   50.664306]  __might_sleep+0x48/0x98
> >> [   50.667894]  disable_irq+0x24/0x60
> >> [   50.671308]  dc_crtc_disable_vblank+0x14/0x20 [imx8_dc_drm]
> >> [   50.676912]  drm_vblank_disable_and_save+0xc0/0x108 [drm]
> >> [   50.682533]  vblank_disable_fn+0x78/0x9c [drm]
> >> [   50.687146]  drm_handle_vblank+0x238/0x2e8 [drm]
> >> [   50.691932]  drm_crtc_handle_vblank+0x1c/0x28 [drm]
> >> [   50.696980]  dc_crtc_irq_handler_dec_framecomplete+0x1c/0x6c [imx8_dc_drm]
> >> [   50.703886]  __handle_irq_event_percpu+0x60/0x14c
> >> [   50.708604]  handle_irq_event+0x4c/0xac
> >> [   50.712443]  handle_level_irq+0xc0/0x1b0
> >> [   50.716379]  generic_handle_irq+0x34/0x4c
> >> [   50.720392]  dc_ic_irq_handler+0x128/0x160 [imx8_dc_drm]
> >> [   50.725727]  generic_handle_domain_irq+0x2c/0x44
> >> [   50.730357]  imx_irqsteer_irq_handler+0xc0/0x1a0
> >> [   50.734987]  generic_handle_domain_irq+0x2c/0x44
> >> [   50.739609]  gic_handle_irq+0x4c/0x114
> >> [   50.743362]  call_on_irq_stack+0x24/0x4c
> >> [   50.747298]  do_interrupt_handler+0x80/0x84
> >> [   50.751494]  el1_interrupt+0x34/0x68
> >> [   50.755082]  el1h_64_irq_handler+0x18/0x24
> >> [   50.759191]  el1h_64_irq+0x6c/0x70
> >> [   50.762597]  default_idle_call+0x28/0x3c (P)
> >> [   50.766879]  default_idle_call+0x24/0x3c (L)
> >> [   50.771163]  do_idle+0x200/0x25c
> >> [   50.774403]  cpu_startup_entry+0x34/0x3c
> >> [   50.778338]  kernel_init+0x0/0x1d8
> >> [   50.781752]  start_kernel+0x5c4/0x70c
> >> [   50.785427]  __primary_switched+0x88/0x90
> >>
> >>>
> >>>> +}
> >>>> +
> >>>> +static irqreturn_t
> >>>> +dc_crtc_dec_framecomplete_irq_handler(int irq, void *dev_id)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = dev_id;
> >>>> +  struct drm_crtc *crtc = &dc_crtc->base;
> >>>> +  unsigned long flags;
> >>>> +
> >>>> +  drm_crtc_handle_vblank(crtc);
> >>>> +
> >>>> +  spin_lock_irqsave(&crtc->dev->event_lock, flags);
> >>>> +  if (dc_crtc->event) {
> >>>> +          drm_crtc_send_vblank_event(crtc, dc_crtc->event);
> >>>> +          dc_crtc->event = NULL;
> >>>> +          drm_crtc_vblank_put(crtc);
> >>>> +  }
> >>>> +  spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> >>>> +
> >>>> +  return IRQ_HANDLED;
> >>>> +}
> >>>> +
> >>>> +static irqreturn_t dc_crtc_common_irq_handler(int irq, void *dev_id)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = dev_id;
> >>>> +
> >>>> +  if (irq == dc_crtc->irq_dec_seqcomplete)
> >>>> +          complete(&dc_crtc->dec_seqcomplete_done);
> >>>> +  else if (irq == dc_crtc->irq_dec_shdld)
> >>>> +          complete(&dc_crtc->dec_shdld_done);
> >>>> +  else if (irq == dc_crtc->irq_ed_cont_shdld)
> >>>> +          complete(&dc_crtc->ed_cont_shdld_done);
> >>>> +  else if (irq == dc_crtc->irq_ed_safe_shdld)
> >>>> +          complete(&dc_crtc->ed_safe_shdld_done);
> >>>
> >>> Is there any reason to have a single multiplex handler instead of having
> >>> 4 separate handlers, each doing one simple thing?
> >>
> >> Just thought that one irq handler is feasible to implement the common
> >> handling logic. It's also ok to use 4 separate handlers with a little
> >> performance improvement. I may change to use 4 separate handlers by
> >> introducing a DEFINE_DC_CRTC_IRQ_HANDLER() marco.
> >
> > Just define them one by one, there is no need for a macro.
>
> Will do.
>
> >
> >>
> >>>
> >>>> +
> >>>> +  return IRQ_HANDLED;
> >>>> +}
> >>>> +
> >>>> +static const struct drm_crtc_funcs dc_crtc_funcs = {
> >>>> +  .reset                  = drm_atomic_helper_crtc_reset,
> >>>> +  .destroy                = drm_crtc_cleanup,
> >>>> +  .set_config             = drm_atomic_helper_set_config,
> >>>> +  .page_flip              = drm_atomic_helper_page_flip,
> >>>> +  .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> >>>> +  .atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
> >>>> +  .get_vblank_counter     = dc_crtc_get_vblank_counter,
> >>>> +  .enable_vblank          = dc_crtc_enable_vblank,
> >>>> +  .disable_vblank         = dc_crtc_disable_vblank,
> >>>> +  .get_vblank_timestamp   = drm_crtc_vblank_helper_get_vblank_timestamp,
> >>>> +};
> >>>> +
> >>>> +static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
> >>>> +{
> >>>> +  struct drm_crtc *crtc = crtc_state->crtc;
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +
> >>>> +  spin_lock_irq(&crtc->dev->event_lock);
> >>>> +  if (crtc_state->event) {
> >>>> +          WARN_ON(drm_crtc_vblank_get(crtc));
> >>>> +          WARN_ON(dc_crtc->event);
> >>>> +          dc_crtc->event = crtc_state->event;
> >>>> +          crtc_state->event = NULL;
> >>>> +  }
> >>>> +  spin_unlock_irq(&crtc->dev->event_lock);
> >>>> +}
> >>>> +
> >>>> +static enum drm_mode_status
> >>>> +dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
> >>>> +{
> >>>> +  return dc_fg_check_clock(dc_crtc->fg, clk_khz);
> >>>> +}
> >>>
> >>> inline
> >>
> >> Will do.
> >>
> >>>
> >>>> +
> >>>> +static enum drm_mode_status
> >>>> +dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +  enum drm_mode_status status;
> >>>> +
> >>>> +  status = dc_crtc_check_clock(dc_crtc, mode->clock);
> >>>> +  if (status != MODE_OK)
> >>>> +          return status;
> >>>> +
> >>>> +  if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
> >>>> +          return MODE_CLOCK_HIGH;
> >>>> +
> >>>> +  return MODE_OK;
> >>>> +}
> >>>> +
> >>>> +static int
> >>>> +dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >>>> +{
> >>>> +  struct drm_crtc_state *new_crtc_state =
> >>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
> >>>> +  struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +  enum drm_mode_status status;
> >>>> +
> >>>> +  status = dc_crtc_check_clock(dc_crtc, adj->clock);
> >>>> +  if (status != MODE_OK)
> >>>> +          return -EINVAL;
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static void
> >>>> +dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >>>> +{
> >>>> +  struct drm_crtc_state *new_crtc_state =
> >>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +  int idx, ret;
> >>>> +
> >>>> +  if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
> >>>> +      !new_crtc_state->active)
> >>>> +          return;
> >>>> +
> >>>> +  if (!drm_dev_enter(crtc->dev, &idx))
> >>>> +          return;
> >>>> +
> >>>> +  /* request pixel engine power-on when CRTC starts to be active */
> >>>> +  ret = pm_runtime_resume_and_get(dc_crtc->pe->dev);
> >>>> +  if (ret)
> >>>> +          dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
> >>>> +                      ret);
> >>>> +
> >>>> +  drm_dev_exit(idx);
> >>>> +}
> >>>> +
> >>>> +static void
> >>>> +dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >>>> +{
> >>>> +  struct drm_crtc_state *old_crtc_state =
> >>>> +                          drm_atomic_get_old_crtc_state(state, crtc);
> >>>> +  struct drm_crtc_state *new_crtc_state =
> >>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +  int idx;
> >>>> +
> >>>> +  if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
> >>>> +      (!old_crtc_state->active && !new_crtc_state->active))
> >>>> +          return;
> >>>> +
> >>>> +  if (!drm_dev_enter(crtc->dev, &idx))
> >>>> +          goto out;
> >>>> +
> >>>> +  enable_irq(dc_crtc->irq_ed_cont_shdld);
> >>>> +
> >>>> +  /* flush plane update out to display */
> >>>> +  dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
> >>>> +
> >>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
> >>>> +
> >>>> +  disable_irq(dc_crtc->irq_ed_cont_shdld);
> >>>> +
> >>>> +  DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
> >>>> +
> >>>> +  drm_dev_exit(idx);
> >>>> +
> >>>> +out:
> >>>> +  dc_crtc_queue_state_event(new_crtc_state);
> >>>> +}
> >>>> +
> >>>> +static void
> >>>> +dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >>>> +{
> >>>> +  struct drm_crtc_state *new_crtc_state =
> >>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
> >>>> +  struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +  enum dc_link_id cf_link;
> >>>> +  int idx, ret;
> >>>> +
> >>>> +  dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
> >>>> +
> >>>> +  drm_crtc_vblank_on(crtc);
> >>>> +
> >>>> +  if (!drm_dev_enter(crtc->dev, &idx))
> >>>> +          goto out;
> >>>> +
> >>>> +  /* request display engine power-on when CRTC is enabled */
> >>>> +  ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
> >>>> +  if (ret < 0)
> >>>> +          dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
> >>>> +                      ret);
> >>>> +
> >>>> +  enable_irq(dc_crtc->irq_dec_shdld);
> >>>> +  enable_irq(dc_crtc->irq_ed_cont_shdld);
> >>>> +  enable_irq(dc_crtc->irq_ed_safe_shdld);
> >>>> +
> >>>> +  dc_fg_cfg_videomode(dc_crtc->fg, adj);
> >>>> +
> >>>> +  dc_cf_framedimensions(dc_crtc->cf_cont,
> >>>> +                        adj->crtc_hdisplay, adj->crtc_vdisplay);
> >>>> +  dc_cf_framedimensions(dc_crtc->cf_safe,
> >>>> +                        adj->crtc_hdisplay, adj->crtc_vdisplay);
> >>>> +
> >>>> +  /* constframe in safety stream shows blue frame */
> >>>> +  dc_cf_constantcolor_blue(dc_crtc->cf_safe);
> >>>> +  cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
> >>>> +  dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
> >>>> +
> >>>> +  /* show CRTC background if no plane is enabled */
> >>>> +  if (new_crtc_state->plane_mask == 0) {
> >>>> +          /* constframe in content stream shows black frame */
> >>>> +          dc_cf_constantcolor_black(dc_crtc->cf_cont);
> >>>> +
> >>>> +          cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
> >>>> +          dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
> >>>> +  }
> >>>> +
> >>>> +  dc_fg_enable_clock(dc_crtc->fg);
> >>>> +  dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
> >>>> +  dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
> >>>> +  dc_fg_shdtokgen(dc_crtc->fg);
> >>>> +  dc_fg_enable(dc_crtc->fg);
> >>>> +
> >>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdld_done);
> >>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
> >>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdld_done);
> >>>> +
> >>>> +  disable_irq(dc_crtc->irq_ed_safe_shdld);
> >>>> +  disable_irq(dc_crtc->irq_ed_cont_shdld);
> >>>> +  disable_irq(dc_crtc->irq_dec_shdld);
> >>>> +
> >>>> +  DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
> >>>> +
> >>>> +  DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
> >>>> +
> >>>> +  drm_dev_exit(idx);
> >>>> +
> >>>> +out:
> >>>> +  dc_crtc_queue_state_event(new_crtc_state);
> >>>> +}
> >>>> +
> >>>> +static void
> >>>> +dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
> >>>> +{
> >>>> +  struct drm_crtc_state *new_crtc_state =
> >>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +  int idx, ret;
> >>>> +
> >>>> +  if (!drm_dev_enter(crtc->dev, &idx))
> >>>> +          goto out;
> >>>> +
> >>>> +  enable_irq(dc_crtc->irq_dec_seqcomplete);
> >>>> +  dc_fg_disable(dc_crtc->fg);
> >>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
> >>>> +  disable_irq(dc_crtc->irq_dec_seqcomplete);
> >>>> +
> >>>> +  dc_fg_disable_clock(dc_crtc->fg);
> >>>> +
> >>>> +  /* request pixel engine power-off as plane is off too */
> >>>> +  ret = pm_runtime_put(dc_crtc->pe->dev);
> >>>> +  if (ret)
> >>>> +          dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
> >>>> +                      ret);
> >>>> +
> >>>> +  /* request display engine power-off when CRTC is disabled */
> >>>> +  ret = pm_runtime_put(dc_crtc->de->dev);
> >>>
> >>> Can this be expressed as a devlink between PE and DE?
> >>
> >> Looking at struct dc_{pe,de}, PE and DE are not dependent with each other,
> >> i.e., no consumer/supplier relationship(note that blit engine in PE can work
> >> by itself without DE) between them. So, it doesn't look right to link the two
> >> devices.
> >
> > Ack
> >
> >>
> >>>
> >>>> +  if (ret < 0)
> >>>> +          dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
> >>>> +                      ret);
> >>>> +
> >>>> +  drm_dev_exit(idx);
> >>>> +
> >>>> +out:
> >>>> +  drm_crtc_vblank_off(crtc);
> >>>> +
> >>>> +  spin_lock_irq(&crtc->dev->event_lock);
> >>>> +  if (new_crtc_state->event && !new_crtc_state->active) {
> >>>> +          drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
> >>>> +          new_crtc_state->event = NULL;
> >>>> +  }
> >>>> +  spin_unlock_irq(&crtc->dev->event_lock);
> >>>> +}
> >>>> +
> >>>> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +  int ret;
> >>>> +
> >>>> +  if (!dc_fg_wait_for_frame_index_moving(dc_crtc->fg))
> >>>> +          return;
> >>>> +
> >>>> +  dc_fg_disable_clock(dc_crtc->fg);
> >>>> +
> >>>> +  if (pm_runtime_active(dc_crtc->pe->dev)) {
> >>>> +          ret = pm_runtime_put_sync(dc_crtc->pe->dev);
> >>>> +          if (ret)
> >>>> +                  dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
> >>>> +                              ret);
> >>>> +  }
> >>>> +
> >>>> +  ret = pm_runtime_put_sync(dc_crtc->de->dev);
> >>>> +  if (ret < 0)
> >>>> +          dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
> >>>> +                      ret);
> >>>> +}
> >>>> +
> >>>> +static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
> >>>> +                                   bool in_vblank_irq,
> >>>> +                                   int *vpos, int *hpos,
> >>>> +                                   ktime_t *stime, ktime_t *etime,
> >>>> +                                   const struct drm_display_mode *mode)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> >>>> +  int vdisplay = mode->crtc_vdisplay;
> >>>> +  int vtotal = mode->crtc_vtotal;
> >>>> +  bool reliable;
> >>>> +  int line;
> >>>> +  int idx;
> >>>> +
> >>>> +  if (stime)
> >>>> +          *stime = ktime_get();
> >>>> +
> >>>> +  if (!drm_dev_enter(crtc->dev, &idx)) {
> >>>> +          reliable = false;
> >>>> +          *vpos = 0;
> >>>> +          *hpos = 0;
> >>>> +          goto out;
> >>>> +  }
> >>>> +
> >>>> +  /* line index starts with 0 for the first active output line */
> >>>> +  line = dc_fg_get_line_index(dc_crtc->fg);
> >>>> +
> >>>> +  if (line < vdisplay)
> >>>> +          /* active scanout area - positive */
> >>>> +          *vpos = line + 1;
> >>>> +  else
> >>>> +          /* inside vblank - negative */
> >>>> +          *vpos = line - (vtotal - 1);
> >>>> +
> >>>> +  *hpos = 0;
> >>>> +
> >>>> +  reliable = true;
> >>>> +
> >>>> +  drm_dev_exit(idx);
> >>>> +out:
> >>>> +  if (etime)
> >>>> +          *etime = ktime_get();
> >>>> +
> >>>> +  return reliable;
> >>>> +}
> >>>> +
> >>>> +static const struct drm_crtc_helper_funcs dc_helper_funcs = {
> >>>> +  .mode_valid             = dc_crtc_mode_valid,
> >>>> +  .atomic_check           = dc_crtc_atomic_check,
> >>>> +  .atomic_begin           = dc_crtc_atomic_begin,
> >>>> +  .atomic_flush           = dc_crtc_atomic_flush,
> >>>> +  .atomic_enable          = dc_crtc_atomic_enable,
> >>>> +  .atomic_disable         = dc_crtc_atomic_disable,
> >>>> +  .get_scanout_position   = dc_crtc_get_scanout_position,
> >>>> +};
> >>>> +
> >>>> +static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
> >>>> +{
> >>>> +  struct {
> >>>> +          struct device *dev;
> >>>> +          unsigned int irq;
> >>>> +          irqreturn_t (*irq_handler)(int irq, void *dev_id);
> >>>> +  } irqs[DC_CRTC_IRQS] = {
> >>>> +          {
> >>>> +                  dc_crtc->de->dev,
> >>>> +                  dc_crtc->irq_dec_framecomplete,
> >>>> +                  dc_crtc_dec_framecomplete_irq_handler,
> >>>> +          }, {
> >>>> +                  dc_crtc->de->dev,
> >>>> +                  dc_crtc->irq_dec_seqcomplete,
> >>>> +                  dc_crtc_common_irq_handler,
> >>>> +          }, {
> >>>> +                  dc_crtc->de->dev,
> >>>> +                  dc_crtc->irq_dec_shdld,
> >>>> +                  dc_crtc_common_irq_handler,
> >>>> +          }, {
> >>>> +                  dc_crtc->ed_cont->dev,
> >>>> +                  dc_crtc->irq_ed_cont_shdld,
> >>>> +                  dc_crtc_common_irq_handler,
> >>>> +          }, {
> >>>> +                  dc_crtc->ed_safe->dev,
> >>>> +                  dc_crtc->irq_ed_safe_shdld,
> >>>> +                  dc_crtc_common_irq_handler,
> >>>> +          },
> >>>> +  };
> >>>> +  int i, ret;
> >>>> +
> >>>> +  for (i = 0; i < DC_CRTC_IRQS; i++) {
> >>>> +          struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
> >>>> +
> >>>> +          ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
> >>>> +                                 irqs[i].irq_handler, IRQF_NO_AUTOEN,
> >>>> +                                 dev_name(irqs[i].dev), dc_crtc);
> >>>> +          if (ret) {
> >>>> +                  dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
> >>>> +                          irqs[i].irq, ret);
> >>>> +                  return ret;
> >>>> +          }
> >>>> +
> >>>> +          irq->dc_crtc = dc_crtc;
> >>>> +          irq->irq = irqs[i].irq;
> >>>> +  }
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> >>>> +  struct drm_device *drm = &dc_drm->base;
> >>>> +  struct dc_de *de = dc_drm->de[crtc_index];
> >>>> +  struct dc_pe *pe = dc_drm->pe;
> >>>> +  struct dc_plane *dc_primary;
> >>>> +  int ret;
> >>>> +
> >>>> +  dc_crtc->de = de;
> >>>> +  dc_crtc->pe = pe;
> >>>> +
> >>>> +  init_completion(&dc_crtc->dec_seqcomplete_done);
> >>>> +  init_completion(&dc_crtc->dec_shdld_done);
> >>>> +  init_completion(&dc_crtc->ed_cont_shdld_done);
> >>>> +  init_completion(&dc_crtc->ed_safe_shdld_done);
> >>>> +
> >>>> +  dc_crtc->cf_cont = pe->cf_cont[crtc_index];
> >>>> +  dc_crtc->cf_safe = pe->cf_safe[crtc_index];
> >>>> +  dc_crtc->ed_cont = pe->ed_cont[crtc_index];
> >>>> +  dc_crtc->ed_safe = pe->ed_safe[crtc_index];
> >>>> +  dc_crtc->fg = de->fg;
> >>>> +
> >>>> +  dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
> >>>> +  dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
> >>>> +  dc_crtc->irq_dec_shdld = de->irq_shdld;
> >>>> +  dc_crtc->irq_ed_safe_shdld = dc_crtc->ed_safe->irq_shdld;
> >>>> +  dc_crtc->irq_ed_cont_shdld = dc_crtc->ed_cont->irq_shdld;
> >>>> +
> >>>> +  dc_primary = &dc_drm->dc_primary[crtc_index];
> >>>> +  ret = dc_plane_init(dc_drm, dc_primary);
> >>>> +  if (ret) {
> >>>> +          dev_err(drm->dev,
> >>>> +                  "failed to init primary plane for display engine%u: %d\n",
> >>>> +                  de->id, ret);
> >>>> +          return ret;
> >>>> +  }
> >>>> +
> >>>> +  drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
> >>>> +
> >>>> +  ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
> >>>> +                                  NULL, &dc_crtc_funcs, NULL);
> >>>> +  if (ret)
> >>>> +          dev_err(drm->dev,
> >>>> +                  "failed to add CRTC for display engine%u: %d\n",
> >>>> +                  de->id, ret);
> >>>> +
> >>>> +  return ret;
> >>>> +}
> >>>> +
> >>>> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> >>>> +  struct drm_device *drm = &dc_drm->base;
> >>>> +
> >>>> +  return dc_crtc_request_irqs(drm, dc_crtc);
> >>>> +}
> >>>> diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
> >>>> index 17a44362118e..8a7b6c03a222 100644
> >>>> --- a/drivers/gpu/drm/imx/dc/dc-de.h
> >>>> +++ b/drivers/gpu/drm/imx/dc/dc-de.h
> >>>> @@ -13,6 +13,9 @@
> >>>>
> >>>>  #define DC_DISPLAYS       2
> >>>>
> >>>> +#define DC_FRAMEGEN_MAX_FRAME_INDEX       0x3ffff
> >>>> +#define DC_FRAMEGEN_MAX_CLOCK_KHZ 300000
> >>>> +
> >>>>  struct dc_fg {
> >>>>    struct device *dev;
> >>>>    struct regmap *reg;
> >>>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
> >>>> index fd68861f770a..1e4b8afa3eec 100644
> >>>> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
> >>>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
> >>>> @@ -3,11 +3,254 @@
> >>>>   * Copyright 2024 NXP
> >>>>   */
> >>>>
> >>>> +#include <linux/clk.h>
> >>>> +#include <linux/component.h>
> >>>> +#include <linux/device.h>
> >>>> +#include <linux/dma-mapping.h>
> >>>> +#include <linux/mod_devicetable.h>
> >>>>  #include <linux/module.h>
> >>>> +#include <linux/of.h>
> >>>> +#include <linux/of_platform.h>
> >>>>  #include <linux/platform_device.h>
> >>>> +#include <linux/pm.h>
> >>>> +#include <linux/pm_runtime.h>
> >>>>
> >>>> +#include <drm/drm_atomic_helper.h>
> >>>> +#include <drm/drm_client_setup.h>
> >>>> +#include <drm/drm_crtc.h>
> >>>> +#include <drm/drm_drv.h>
> >>>> +#include <drm/drm_fbdev_dma.h>
> >>>> +#include <drm/drm_fourcc.h>
> >>>> +#include <drm/drm_gem_dma_helper.h>
> >>>> +#include <drm/drm_managed.h>
> >>>> +#include <drm/drm_modeset_helper.h>
> >>>> +#include <drm/drm_of.h>
> >>>> +
> >>>> +#include "dc-de.h"
> >>>>  #include "dc-drv.h"
> >>>>
> >>>> +struct dc_priv {
> >>>> +  struct drm_device *drm;
> >>>> +  struct clk *clk_cfg;
> >>>> +};
> >>>> +
> >>>> +DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
> >>>> +
> >>>> +static struct drm_driver dc_drm_driver = {
> >>>> +  .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
> >>>> +  DRM_GEM_DMA_DRIVER_OPS,
> >>>> +  DRM_FBDEV_DMA_DRIVER_OPS,
> >>>> +  .fops = &dc_drm_driver_fops,
> >>>> +  .name = "imx8-dc",
> >>>> +  .desc = "i.MX8 DC DRM graphics",
> >>>> +  .date = "20240530",
> >>>> +  .major = 1,
> >>>> +  .minor = 0,
> >>>> +  .patchlevel = 0,
> >>>> +};
> >>>> +
> >>>> +static void
> >>>> +dc_add_components(struct device *dev, struct component_match **matchptr)
> >>>> +{
> >>>> +  struct device_node *child, *grandchild;
> >>>> +
> >>>> +  for_each_available_child_of_node(dev->of_node, child) {
> >>>> +          /* The interrupt controller is not a component. */
> >>>> +          if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
> >>>> +                  continue;
> >>>> +
> >>>> +          drm_of_component_match_add(dev, matchptr, component_compare_of,
> >>>> +                                     child);
> >>>> +
> >>>> +          for_each_available_child_of_node(child, grandchild)
> >>>> +                  drm_of_component_match_add(dev, matchptr,
> >>>> +                                             component_compare_of,
> >>>> +                                             grandchild);
> >>>> +  }
> >>>> +}
> >>>> +
> >>>> +static void dc_drm_component_unbind_all(void *ptr)
> >>>> +{
> >>>> +  struct dc_drm_device *dc_drm = ptr;
> >>>> +  struct drm_device *drm = &dc_drm->base;
> >>>> +
> >>>> +  component_unbind_all(drm->dev, dc_drm);
> >>>> +}
> >>>> +
> >>>> +static int dc_drm_bind(struct device *dev)
> >>>> +{
> >>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>> +  struct dc_drm_device *dc_drm;
> >>>> +  struct drm_device *drm;
> >>>> +  int ret;
> >>>> +
> >>>> +  dc_drm = devm_drm_dev_alloc(dev, &dc_drm_driver, struct dc_drm_device,
> >>>> +                              base);
> >>>> +  if (IS_ERR(dc_drm))
> >>>> +          return PTR_ERR(dc_drm);
> >>>> +
> >>>> +  drm = &dc_drm->base;
> >>>> +
> >>>> +  ret = component_bind_all(dev, dc_drm);
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  ret = devm_add_action_or_reset(dev, dc_drm_component_unbind_all,
> >>>> +                                 dc_drm);
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  ret = dc_kms_init(dc_drm);
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  ret = drm_dev_register(drm, 0);
> >>>> +  if (ret) {
> >>>> +          dev_err(dev, "failed to register drm device: %d\n", ret);
> >>>> +          goto err;
> >>>> +  }
> >>>> +
> >>>> +  drm_client_setup_with_fourcc(drm, DRM_FORMAT_XRGB8888);
> >>>> +
> >>>> +  priv->drm = drm;
> >>>> +
> >>>> +  return 0;
> >>>> +
> >>>> +err:
> >>>> +  dc_kms_uninit(dc_drm);
> >>>> +
> >>>> +  return ret;
> >>>> +}
> >>>> +
> >>>> +static void dc_drm_unbind(struct device *dev)
> >>>> +{
> >>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>> +  struct dc_drm_device *dc_drm = to_dc_drm_device(priv->drm);
> >>>> +  struct drm_device *drm = &dc_drm->base;
> >>>> +  struct drm_crtc *crtc;
> >>>> +
> >>>> +  priv->drm = NULL;
> >>>> +  drm_dev_unplug(drm);
> >>>> +  dc_kms_uninit(dc_drm);
> >>>> +  drm_atomic_helper_shutdown(drm);
> >>>> +
> >>>> +  drm_for_each_crtc(crtc, drm)
> >>>> +          dc_crtc_disable_at_unbind(crtc);
> >>>
> >>> There should be no need for that. drm_atomic_helper_shutdown() should
> >>> disable all the CRTCs.
> >>
> >> In case DRM device is unplugged, drm_atomic_helper_shutdown does not
> >> effectively disable the CRTCs due to the bypassed logics wrapped by
> >> drm_dev_{enter,exit}.  That's why dc_crtc_disable_at_unbind() is called
> >> here to effectively disable the CRTCs.
> >
> > I see. I haven't faced drm_dev_unplug() earlier. I checked, the "not
> > disabled" behaviour is documented and all other drivers don't perform
> > any kind of cleanup afterwards. Thus I think it's safe to drop the
> > dc_crtc_disable_at_unbind() unless it causes any kind of HW issues.
>
> IMHO, it's a bit safer to set the HWs backing the CRTCs to a known state
> at the unbind stage by properly disabling them, in case there is any
> unknown SW or HW issue.  Plus, i.MX8qm/qxp SoCs don't provide reset
> signals to the Display Controllers(the resets DT property is optional),
> otherwise, this disablement function can be dropped(at least for now).

I'd say, a rule of thumb is "Behave similarly" to the existing
drivers. We've had a long-standing TODO item expressed in the DRM
docs: the drm_dev_unplug() vs drm_atomic_helper_shutdown(). I think
your issue should be solved in a generic way. One random idea would be
to have a sepecial drm_dev_unplug() version which is intended for the
normal shutdown path, it should mark the device as unavailable after
disabling the outputs and unregistering it from userspace.

>
> >
> >>
> >>>
> >>> Also, who is going to do drm_dev_unregister()? I don't see it in the
> >>> code.
> >>
> >> drm_dev_unplug() right above calls drm_dev_unregister().
> >>
> >>>
> >>>> +}
> >>>> +
> >>>> +static const struct component_master_ops dc_drm_ops = {
> >>>> +  .bind = dc_drm_bind,
> >>>> +  .unbind = dc_drm_unbind,
> >>>> +};
> >>>> +
> >>>> +static int dc_probe(struct platform_device *pdev)
> >>>> +{
> >>>> +  struct component_match *match = NULL;
> >>>> +  struct dc_priv *priv;
> >>>> +  int ret;
> >>>> +
> >>>> +  priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> >>>> +  if (!priv)
> >>>> +          return -ENOMEM;
> >>>> +
> >>>> +  priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
> >>>> +  if (IS_ERR(priv->clk_cfg))
> >>>> +          return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
> >>>> +                               "failed to get cfg clock\n");
> >>>> +
> >>>> +  dev_set_drvdata(&pdev->dev, priv);
> >>>> +
> >>>> +  ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  ret = devm_pm_runtime_enable(&pdev->dev);
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  ret = devm_of_platform_populate(&pdev->dev);
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  dc_add_components(&pdev->dev, &match);
> >>>> +
> >>>> +  ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
> >>>> +  if (ret)
> >>>> +          return dev_err_probe(&pdev->dev, ret,
> >>>> +                               "failed to add component master\n");
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static void dc_remove(struct platform_device *pdev)
> >>>> +{
> >>>> +  component_master_del(&pdev->dev, &dc_drm_ops);
> >>>> +}
> >>>> +
> >>>> +static int dc_runtime_suspend(struct device *dev)
> >>>> +{
> >>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>> +
> >>>> +  clk_disable_unprepare(priv->clk_cfg);
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static int dc_runtime_resume(struct device *dev)
> >>>> +{
> >>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>> +  int ret;
> >>>> +
> >>>> +  ret = clk_prepare_enable(priv->clk_cfg);
> >>>> +  if (ret)
> >>>> +          dev_err(dev, "failed to enable cfg clock: %d\n", ret);
> >>>> +
> >>>> +  return ret;
> >>>> +}
> >>>> +
> >>>> +static int dc_suspend(struct device *dev)
> >>>> +{
> >>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>> +
> >>>> +  return drm_mode_config_helper_suspend(priv->drm);
> >>>> +}
> >>>> +
> >>>> +static int dc_resume(struct device *dev)
> >>>> +{
> >>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>> +
> >>>> +  return drm_mode_config_helper_resume(priv->drm);
> >>>> +}
> >>>> +
> >>>> +static void dc_shutdown(struct platform_device *pdev)
> >>>> +{
> >>>> +  struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
> >>>> +
> >>>> +  drm_atomic_helper_shutdown(priv->drm);
> >>>> +}
> >>>> +
> >>>> +static const struct dev_pm_ops dc_pm_ops = {
> >>>> +  RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
> >>>> +  SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
> >>>> +};
> >>>> +
> >>>> +static const struct of_device_id dc_dt_ids[] = {
> >>>> +  { .compatible = "fsl,imx8qxp-dc", },
> >>>> +  { /* sentinel */ }
> >>>> +};
> >>>> +MODULE_DEVICE_TABLE(of, dc_dt_ids);
> >>>> +
> >>>> +static struct platform_driver dc_driver = {
> >>>> +  .probe = dc_probe,
> >>>> +  .remove = dc_remove,
> >>>> +  .shutdown = dc_shutdown,
> >>>> +  .driver = {
> >>>> +          .name = "imx8-dc",
> >>>> +          .of_match_table = dc_dt_ids,
> >>>> +          .pm = pm_sleep_ptr(&dc_pm_ops),
> >>>> +  },
> >>>> +};
> >>>> +
> >>>>  static struct platform_driver * const dc_drivers[] = {
> >>>>    &dc_cf_driver,
> >>>>    &dc_de_driver,
> >>>> @@ -19,6 +262,7 @@ static struct platform_driver * const dc_drivers[] = {
> >>>>    &dc_lb_driver,
> >>>>    &dc_pe_driver,
> >>>>    &dc_tc_driver,
> >>>> +  &dc_driver,
> >>>>  };
> >>>>
> >>>>  static int __init dc_drm_init(void)
> >>>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
> >>>> index 3b11f4862c6c..39a771a13933 100644
> >>>> --- a/drivers/gpu/drm/imx/dc/dc-drv.h
> >>>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.h
> >>>> @@ -6,19 +6,38 @@
> >>>>  #ifndef __DC_DRV_H__
> >>>>  #define __DC_DRV_H__
> >>>>
> >>>> +#include <linux/container_of.h>
> >>>>  #include <linux/platform_device.h>
> >>>>
> >>>>  #include <drm/drm_device.h>
> >>>> +#include <drm/drm_encoder.h>
> >>>>
> >>>>  #include "dc-de.h"
> >>>> +#include "dc-kms.h"
> >>>>  #include "dc-pe.h"
> >>>>
> >>>>  struct dc_drm_device {
> >>>>    struct drm_device base;
> >>>> +  struct dc_crtc dc_crtc[DC_DISPLAYS];
> >>>> +  struct dc_plane dc_primary[DC_DISPLAYS];
> >>>> +  struct drm_encoder encoder[DC_DISPLAYS];
> >>>>    struct dc_de *de[DC_DISPLAYS];
> >>>>    struct dc_pe *pe;
> >>>>  };
> >>>>
> >>>> +static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
> >>>> +{
> >>>> +  return container_of(drm, struct dc_drm_device, base);
> >>>> +}
> >>>> +
> >>>> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
> >>>> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
> >>>> +
> >>>> +int dc_kms_init(struct dc_drm_device *dc_drm);
> >>>> +void dc_kms_uninit(struct dc_drm_device *dc_drm);
> >>>> +
> >>>> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
> >>>> +
> >>>>  extern struct platform_driver dc_cf_driver;
> >>>>  extern struct platform_driver dc_ed_driver;
> >>>>  extern struct platform_driver dc_de_driver;
> >>>> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
> >>>> new file mode 100644
> >>>> index 000000000000..2b18aa37a4a8
> >>>> --- /dev/null
> >>>> +++ b/drivers/gpu/drm/imx/dc/dc-kms.c
> >>>> @@ -0,0 +1,143 @@
> >>>> +// SPDX-License-Identifier: GPL-2.0+
> >>>> +/*
> >>>> + * Copyright 2024 NXP
> >>>> + */
> >>>> +
> >>>> +#include <linux/of.h>
> >>>> +#include <linux/of_graph.h>
> >>>> +
> >>>> +#include <drm/drm_atomic_helper.h>
> >>>> +#include <drm/drm_bridge.h>
> >>>> +#include <drm/drm_bridge_connector.h>
> >>>> +#include <drm/drm_connector.h>
> >>>> +#include <drm/drm_crtc.h>
> >>>> +#include <drm/drm_device.h>
> >>>> +#include <drm/drm_encoder.h>
> >>>> +#include <drm/drm_gem_framebuffer_helper.h>
> >>>> +#include <drm/drm_mode_config.h>
> >>>> +#include <drm/drm_print.h>
> >>>> +#include <drm/drm_probe_helper.h>
> >>>> +#include <drm/drm_simple_kms_helper.h>
> >>>> +#include <drm/drm_vblank.h>
> >>>> +
> >>>> +#include "dc-de.h"
> >>>> +#include "dc-drv.h"
> >>>> +#include "dc-kms.h"
> >>>> +
> >>>> +static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
> >>>> +  .fb_create = drm_gem_fb_create,
> >>>> +  .atomic_check = drm_atomic_helper_check,
> >>>> +  .atomic_commit = drm_atomic_helper_commit,
> >>>> +};
> >>>> +
> >>>> +static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
> >>>> +                                  int crtc_index)
> >>>> +{
> >>>> +  struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> >>>> +  struct drm_device *drm = &dc_drm->base;
> >>>> +  struct drm_crtc *crtc = &dc_crtc->base;
> >>>> +  struct drm_connector *connector;
> >>>> +  struct device *dev = drm->dev;
> >>>> +  struct drm_encoder *encoder;
> >>>> +  struct drm_bridge *bridge;
> >>>> +  int ret;
> >>>> +
> >>>> +  bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
> >>>> +                                  0, 0);
> >>>> +  if (IS_ERR(bridge)) {
> >>>> +          ret = PTR_ERR(bridge);
> >>>> +          if (ret == -ENODEV)
> >>>> +                  return 0;
> >>>> +
> >>>> +          return dev_err_probe(dev, ret,
> >>>> +                               "failed to find bridge for CRTC%u\n",
> >>>> +                               crtc->index);
> >>>> +  }
> >>>> +
> >>>> +  encoder = &dc_drm->encoder[crtc_index];
> >>>> +  ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
> >>>> +  if (ret) {
> >>>> +          dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
> >>>> +                  crtc->index, ret);
> >>>> +          return ret;
> >>>> +  }
> >>>> +
> >>>> +  encoder->possible_crtcs = drm_crtc_mask(crtc);
> >>>> +
> >>>> +  ret = drm_bridge_attach(encoder, bridge, NULL,
> >>>> +                          DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>> +  if (ret) {
> >>>> +          dev_err(dev,
> >>>> +                  "failed to attach bridge to encoder for CRTC%u: %d\n",
> >>>> +                  crtc->index, ret);
> >>>> +          return ret;
> >>>> +  }
> >>>> +
> >>>> +  connector = drm_bridge_connector_init(drm, encoder);
> >>>> +  if (IS_ERR(connector)) {
> >>>> +          ret = PTR_ERR(connector);
> >>>> +          dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
> >>>> +                  crtc->index, ret);
> >>>> +          return ret;
> >>>> +  }
> >>>> +
> >>>> +  ret = drm_connector_attach_encoder(connector, encoder);
> >>>> +  if (ret)
> >>>> +          dev_err(dev,
> >>>> +                  "failed to attach encoder to connector for CRTC%u: %d\n",
> >>>> +                  crtc->index, ret);
> >>>> +
> >>>> +  return ret;
> >>>> +}
> >>>> +
> >>>> +int dc_kms_init(struct dc_drm_device *dc_drm)
> >>>> +{
> >>>> +  struct drm_device *drm = &dc_drm->base;
> >>>> +  int ret, i;
> >>>> +
> >>>> +  ret = drmm_mode_config_init(drm);
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  drm->mode_config.min_width = 60;
> >>>> +  drm->mode_config.min_height = 60;
> >>>> +  drm->mode_config.max_width = 8192;
> >>>> +  drm->mode_config.max_height = 8192;
> >>>> +  drm->mode_config.funcs = &dc_drm_mode_config_funcs;
> >>>> +
> >>>> +  drm->vblank_disable_immediate = true;
> >>>> +  drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
> >>>> +
> >>>> +  for (i = 0; i < DC_DISPLAYS; i++) {
> >>>> +          ret = dc_crtc_init(dc_drm, i);
> >>>> +          if (ret)
> >>>> +                  return ret;
> >>>> +
> >>>> +          ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
> >>>> +          if (ret)
> >>>> +                  return ret;
> >>>> +  }
> >>>> +
> >>>> +  for (i = 0; i < DC_DISPLAYS; i++) {
> >>>> +          ret = dc_crtc_post_init(dc_drm, i);
> >>>
> >>> Can you use .late_register for this?
> >>
> >> Kerneldoc of struct drm_crtc_funcs::late_register says it's used to register
> >> additional userspace interfaces like debugfs interfaces. And, it seems that
> >> everyone implementing this uses it to add debugfs interfaces. So, it will
> >> kind of abuse it to do CRTC post initialization.
> >
> > Why can't they be requested earlier then?
>
> If I request them earlier in dc_crtc_init(), then they cannot be freed by
> devm_irq_release() when devm_drm_of_get_bridge() called by
> dc_kms_init_encoder_per_crtc() returns -EPROBE_DEFER(which means failing
> to find the first DRM bridge for the CRTC).  Why can't they be freed by
> devm_irq_release()?  Because they are requested by the devices of ExtDsts
> and Display Engines and their drivers are not removed during the probe
> deferral dance.  Furthermore, -EPROBE_DEFER won't be returned after
> dc_crtc_post_init() since the later called drm_vblank_init() doesn't
> return -EPROBE_DEFER anyway, so it's fine to call dc_crtc_post_init() here.
>
> I met the irq free issue on my i.MX8qxp MEK board before, i.e., -EBUSY is
> returned when requesting them again, so it's tested.

A typical solution is to request all resources before binding the
device as a component. Don't tell me that your interrupt controller is
another component of the DRM device :-)

>
> >
> >>
> >>>
> >>>> +          if (ret)
> >>>> +                  return ret;
> >>>> +  }
> >>>> +
> >>>> +  ret = drm_vblank_init(drm, DC_DISPLAYS);
> >>>> +  if (ret) {
> >>>> +          dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
> >>>> +          return ret;
> >>>> +  }
> >>>> +
> >>>> +  drm_mode_config_reset(drm);
> >>>> +
> >>>> +  drm_kms_helper_poll_init(drm);
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +void dc_kms_uninit(struct dc_drm_device *dc_drm)
> >>>> +{
> >>>> +  drm_kms_helper_poll_fini(&dc_drm->base);
> >>>> +}
> >>>> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
> >>>> new file mode 100644
> >>>> index 000000000000..57f6e0c15f57
> >>>> --- /dev/null
> >>>> +++ b/drivers/gpu/drm/imx/dc/dc-kms.h
> >>>> @@ -0,0 +1,58 @@
> >>>> +/* SPDX-License-Identifier: GPL-2.0+ */
> >>>> +/*
> >>>> + * Copyright 2024 NXP
> >>>> + */
> >>>> +
> >>>> +#ifndef __DC_KMS_H__
> >>>> +#define __DC_KMS_H__
> >>>> +
> >>>> +#include <linux/completion.h>
> >>>> +
> >>>> +#include <drm/drm_crtc.h>
> >>>> +#include <drm/drm_plane.h>
> >>>> +#include <drm/drm_vblank.h>
> >>>> +
> >>>> +#include "dc-de.h"
> >>>> +#include "dc-fu.h"
> >>>> +#include "dc-pe.h"
> >>>> +
> >>>> +#define DC_CRTC_IRQS      5
> >>>> +
> >>>> +struct dc_crtc_irq {
> >>>> +  struct dc_crtc *dc_crtc;
> >>>> +  unsigned int irq;
> >>>> +};
> >>>> +
> >>>
> >>> Please provide some documentation for the structure in the form of the
> >>> kerneldoc. E.g. what is the difference between ed_cont and ed_safe?
> >>
> >> Will add kerneldoc for struct dc_{crtc,plane,drm_device} and tell the
> >> difference between ed_cont(content stream) and ed_safe(safety stream).
> >>
> >>> The de and fg pointers are global, please don't cache them
> >>> unnecessarily.
> >>
> >> Global? I don't catch your meaning, sorry. To me, it's handy to access de
> >> and fg via the two pointers in struct dc_crtc.
> >
> > I had to spend some time understanding if they are per-CRTC or if there
> > are a single instances of those subdevices. Thus I suggest to access
>
> They are per-CRTC.  One Display Controller contains two Display Engines,
> hence two CRTCs.

I'm sorry, I probably meant PE here. DE (and consequently FG) are
per-CRTC indeed.

>
> > them through dc_drm_device. You can ignore this suggestion though.
>
> I'll ignore this.  Thanks anyway.
>
> >
> >>
> >>>
> >>>> +struct dc_crtc {
> >>>> +  struct drm_crtc base;
> >>>> +  struct dc_de *de;
> >>>> +  struct dc_pe *pe;
> >>>> +  struct dc_cf *cf_cont;
> >>>> +  struct dc_cf *cf_safe;
> >>>> +  struct dc_ed *ed_cont;
> >>>> +  struct dc_ed *ed_safe;
> >>>> +  struct dc_fg *fg;
> >>>> +  unsigned int irq_dec_framecomplete;
> >>>> +  unsigned int irq_dec_seqcomplete;
> >>>> +  unsigned int irq_dec_shdld;
> >>>> +  unsigned int irq_ed_cont_shdld;
> >>>> +  unsigned int irq_ed_safe_shdld;
> >>>> +  struct completion dec_seqcomplete_done;
> >>>> +  struct completion dec_shdld_done;
> >>>> +  struct completion ed_safe_shdld_done;
> >>>> +  struct completion ed_cont_shdld_done;
> >>>> +  struct drm_pending_vblank_event *event;
> >>>> +  struct dc_crtc_irq irqs[DC_CRTC_IRQS];
> >>>> +};
> >>>> +
> >>>> +struct dc_plane {
> >>>> +  struct drm_plane base;
> >>>> +  struct dc_fu *fu;
> >>>> +  struct dc_cf *cf;
> >>>> +  struct dc_lb *lb;
> >>>> +  struct dc_ed *ed;
> >>>> +};
> >>>> +
> >>>> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc);
> >>>> +
> >>>> +#endif /* __DC_KMS_H__ */
> >>>> diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
> >>>> new file mode 100644
> >>>> index 000000000000..78d0d2cd3451
> >>>> --- /dev/null
> >>>> +++ b/drivers/gpu/drm/imx/dc/dc-plane.c
> >>>> @@ -0,0 +1,241 @@
> >>>> +// SPDX-License-Identifier: GPL-2.0+
> >>>> +/*
> >>>> + * Copyright 2024 NXP
> >>>> + */
> >>>> +
> >>>> +#include <linux/container_of.h>
> >>>> +
> >>>> +#include <drm/drm_atomic.h>
> >>>> +#include <drm/drm_atomic_helper.h>
> >>>> +#include <drm/drm_atomic_state_helper.h>
> >>>> +#include <drm/drm_crtc.h>
> >>>> +#include <drm/drm_drv.h>
> >>>> +#include <drm/drm_fb_dma_helper.h>
> >>>> +#include <drm/drm_fourcc.h>
> >>>> +#include <drm/drm_framebuffer.h>
> >>>> +#include <drm/drm_gem_atomic_helper.h>
> >>>> +#include <drm/drm_plane_helper.h>
> >>>> +#include <drm/drm_print.h>
> >>>> +
> >>>> +#include "dc-drv.h"
> >>>> +#include "dc-fu.h"
> >>>> +#include "dc-kms.h"
> >>>> +
> >>>> +#define DC_PLANE_MAX_PITCH        0x10000
> >>>> +#define DC_PLANE_MAX_PIX_CNT      8192
> >>>> +
> >>>> +#define dc_plane_dbg(plane, fmt, ...)                                     \
> >>>> +do {                                                                      \
> >>>> +  typeof(plane) _plane = (plane);                                 \
> >>>> +  drm_dbg_kms(_plane->dev, "[PLANE:%d:%s] " fmt,                  \
> >>>> +              _plane->base.id, _plane->name, ##__VA_ARGS__);      \
> >>>> +} while (0)
> >>>> +
> >>>> +static const uint32_t dc_plane_formats[] = {
> >>>> +  DRM_FORMAT_XRGB8888,
> >>>> +};
> >>>> +
> >>>> +static const struct drm_plane_funcs dc_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,
> >>>> +};
> >>>> +
> >>>> +static inline struct dc_plane *to_dc_plane(struct drm_plane *plane)
> >>>> +{
> >>>> +  return container_of(plane, struct dc_plane, base);
> >>>> +}
> >>>> +
> >>>> +static int dc_plane_check_no_off_screen(struct drm_plane_state *state,
> >>>> +                                  struct drm_crtc_state *crtc_state)
> >>>> +{
> >>>> +  if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
> >>>> +      state->dst.x2 > crtc_state->adjusted_mode.hdisplay ||
> >>>> +      state->dst.y2 > crtc_state->adjusted_mode.vdisplay) {
> >>>> +          dc_plane_dbg(state->plane, "no off screen\n");
> >>>> +          return -EINVAL;
> >>>> +  }
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static int dc_plane_check_max_source_resolution(struct drm_plane_state *state)
> >>>> +{
> >>>> +  int src_h = drm_rect_height(&state->src) >> 16;
> >>>> +  int src_w = drm_rect_width(&state->src) >> 16;
> >>>> +
> >>>> +  if (src_w > DC_PLANE_MAX_PIX_CNT || src_h > DC_PLANE_MAX_PIX_CNT) {
> >>>> +          dc_plane_dbg(state->plane, "invalid source resolution\n");
> >>>> +          return -EINVAL;
> >>>> +  }
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static int dc_plane_check_fb(struct drm_plane_state *state)
> >>>> +{
> >>>> +  struct drm_framebuffer *fb = state->fb;
> >>>> +  dma_addr_t baseaddr = drm_fb_dma_get_gem_addr(fb, state, 0);
> >>>> +
> >>>> +  /* base address alignment */
> >>>> +  if (baseaddr & 0x3) {
> >>>> +          dc_plane_dbg(state->plane, "fb bad baddr alignment\n");
> >>>> +          return -EINVAL;
> >>>> +  }
> >>>> +
> >>>> +  /* pitches[0] range */
> >>>> +  if (fb->pitches[0] > DC_PLANE_MAX_PITCH) {
> >>>> +          dc_plane_dbg(state->plane, "fb pitches[0] is out of range\n");
> >>>> +          return -EINVAL;
> >>>> +  }
> >>>> +
> >>>> +  /* pitches[0] alignment */
> >>>> +  if (fb->pitches[0] & 0x3) {
> >>>> +          dc_plane_dbg(state->plane, "fb bad pitches[0] alignment\n");
> >>>> +          return -EINVAL;
> >>>> +  }
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>> +static int
> >>>> +dc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
> >>>> +{
> >>>> +  struct drm_plane_state *plane_state =
> >>>> +                          drm_atomic_get_new_plane_state(state, plane);
> >>>> +  struct drm_crtc_state *crtc_state;
> >>>> +  int ret;
> >>>> +
> >>>> +  /* ok to disable */
> >>>> +  if (!plane_state->fb)
> >>>> +          return 0;
> >>>> +
> >>>> +  if (!plane_state->crtc) {
> >>>> +          dc_plane_dbg(plane, "no CRTC in plane state\n");
> >>>> +          return -EINVAL;
> >>>> +  }
> >>>> +
> >>>> +  crtc_state =
> >>>> +          drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
> >>>> +  if (WARN_ON(!crtc_state))
> >>>> +          return -EINVAL;
> >>>> +
> >>>> +  ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
> >>>> +                                            DRM_PLANE_NO_SCALING,
> >>>> +                                            DRM_PLANE_NO_SCALING,
> >>>> +                                            true, false);
> >>>> +  if (ret) {
> >>>> +          dc_plane_dbg(plane, "failed to check plane state: %d\n", ret);
> >>>> +          return ret;
> >>>> +  }
> >>>> +
> >>>> +  ret = dc_plane_check_no_off_screen(plane_state, crtc_state);
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  ret = dc_plane_check_max_source_resolution(plane_state);
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  return dc_plane_check_fb(plane_state);
> >>>> +}
> >>>> +
> >>>> +static void
> >>>> +dc_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state)
> >>>> +{
> >>>> +  struct drm_plane_state *new_state =
> >>>> +                          drm_atomic_get_new_plane_state(state, plane);
> >>>> +  struct dc_plane *dplane = to_dc_plane(plane);
> >>>> +  struct drm_framebuffer *fb = new_state->fb;
> >>>> +  const struct dc_fu_ops *fu_ops;
> >>>> +  struct dc_lb *lb = dplane->lb;
> >>>> +  struct dc_fu *fu = dplane->fu;
> >>>> +  dma_addr_t baseaddr;
> >>>> +  int src_w, src_h;
> >>>> +  int idx;
> >>>> +
> >>>> +  if (!drm_dev_enter(plane->dev, &idx))
> >>>> +          return;
> >>>> +
> >>>> +  src_w = drm_rect_width(&new_state->src) >> 16;
> >>>> +  src_h = drm_rect_height(&new_state->src) >> 16;
> >>>> +
> >>>> +  baseaddr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
> >>>> +
> >>>> +  fu_ops = dc_fu_get_ops(dplane->fu);
> >>>> +
> >>>> +  fu_ops->set_layerblend(fu, lb);
> >>>> +  fu_ops->set_burstlength(fu, baseaddr);
> >>>> +  fu_ops->set_src_stride(fu, DC_FETCHUNIT_FRAC0, fb->pitches[0]);
> >>>> +  fu_ops->set_src_buf_dimensions(fu, DC_FETCHUNIT_FRAC0, src_w, src_h);
> >>>> +  fu_ops->set_fmt(fu, DC_FETCHUNIT_FRAC0, fb->format);
> >>>> +  fu_ops->set_framedimensions(fu, src_w, src_h);
> >>>> +  fu_ops->set_baseaddress(fu, DC_FETCHUNIT_FRAC0, baseaddr);
> >>>> +  fu_ops->enable_src_buf(fu, DC_FETCHUNIT_FRAC0);
> >>>> +
> >>>> +  dc_plane_dbg(plane, "uses %s\n", fu_ops->get_name(fu));
> >>>> +
> >>>> +  dc_lb_pec_dynamic_prim_sel(lb, dc_cf_get_link_id(dplane->cf));
> >>>> +  dc_lb_pec_dynamic_sec_sel(lb, fu_ops->get_link_id(fu));
> >>>> +  dc_lb_mode(lb, LB_BLEND);
> >>>> +  dc_lb_position(lb, new_state->dst.x1, new_state->dst.y1);
> >>>> +  dc_lb_pec_clken(lb, CLKEN_AUTOMATIC);
> >>>> +
> >>>> +  dc_plane_dbg(plane, "uses LayerBlend%u\n", dc_lb_get_id(lb));
> >>>> +
> >>>> +  /* set ExtDst's source to LayerBlend */
> >>>> +  dc_ed_pec_src_sel(dplane->ed, dc_lb_get_link_id(lb));
> >>>> +
> >>>> +  drm_dev_exit(idx);
> >>>> +}
> >>>> +
> >>>> +static void dc_plane_atomic_disable(struct drm_plane *plane,
> >>>> +                              struct drm_atomic_state *state)
> >>>> +{
> >>>> +  struct dc_plane *dplane = to_dc_plane(plane);
> >>>> +  const struct dc_fu_ops *fu_ops;
> >>>> +  int idx;
> >>>> +
> >>>> +  if (!drm_dev_enter(plane->dev, &idx))
> >>>> +          return;
> >>>> +
> >>>> +  /* disable fetchunit in shadow */
> >>>> +  fu_ops = dc_fu_get_ops(dplane->fu);
> >>>> +  fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
> >>>> +
> >>>> +  /* set ExtDst's source to ConstFrame */
> >>>> +  dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
> >>>> +
> >>>> +  drm_dev_exit(idx);
> >>>> +}
> >>>> +
> >>>> +static const struct drm_plane_helper_funcs dc_plane_helper_funcs = {
> >>>> +  .atomic_check = dc_plane_atomic_check,
> >>>> +  .atomic_update = dc_plane_atomic_update,
> >>>> +  .atomic_disable = dc_plane_atomic_disable,
> >>>> +};
> >>>> +
> >>>> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
> >>>> +{
> >>>> +  struct drm_plane *plane = &dc_plane->base;
> >>>> +  int ret;
> >>>> +
> >>>> +  ret = drm_universal_plane_init(&dc_drm->base, plane, 0, &dc_plane_funcs,
> >>>> +                                 dc_plane_formats,
> >>>> +                                 ARRAY_SIZE(dc_plane_formats),
> >>>> +                                 NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
> >>>> +  if (ret)
> >>>> +          return ret;
> >>>> +
> >>>> +  drm_plane_helper_add(plane, &dc_plane_helper_funcs);
> >>>> +
> >>>> +  dc_plane->fu = dc_drm->pe->fu_disp[plane->index];
> >>>> +  dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
> >>>> +  dc_plane->lb = dc_drm->pe->lb[plane->index];
> >>>> +  dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> --
> >>>> 2.34.1
> >>>>
> >>>
> >>
> >> --
> >> Regards,
> >> Liu Ying
> >
>
> --
> Regards,
> Liu Ying



-- 
With best wishes
Dmitry


From daniel.machon at microchip.com  Fri Dec 13 05:40:59 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:40:59 +0100
Subject: [PATCH net-next v4 0/9] net: lan969x: add RGMII support
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>

== Description:

This series is the fourth of a multi-part series, that prepares and adds
support for the new lan969x switch driver.

The upstreaming efforts is split into multiple series (might change a
bit as we go along):

        1) Prepare the Sparx5 driver for lan969x (merged)

        2) Add support for lan969x (same basic features as Sparx5
           provides excl. FDMA and VCAP, merged).

        3) Add lan969x VCAP functionality (merged).

    --> 4) Add RGMII support.

        5) Add FDMA support.

== RGMII support:

The lan969x switch device includes two RGMII port interfaces (port 28
and 29) supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps.

== Patch breakdown:

Patch #1 does some preparation work.

Patch #2 adds new function: is_port_rgmii() to the match data ops.

Patch #3 uses the is_port_rgmii() in a number of places.

Patch #4 makes sure that we do not configure an RGMII device as a
         low-speed device, when doing a port config.

Patch #5 makes sure we only return the PCS if the port mode requires
         it.

Patch #6 adds checks for RGMII PHY modes in sparx5_verify_speeds().

Patch #7 adds registers required to configure RGMII.

Patch #8 adds RGMII implementation.

Patch #9 documents RGMII delays in the dt-bindings.

Details are in the commit description of the individual patches

To: UNGLinuxDriver at microchip.com
To: Andrew Lunn <andrew+netdev at lunn.ch>
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>
To: Lars Povlsen <lars.povlsen at microchip.com>
To: Steen Hegelund <Steen.Hegelund at microchip.com>
To: Horatiu Vultur <horatiu.vultur at microchip.com>
To: Russell King <linux at armlinux.org.uk>
To: jacob.e.keller at intel.com
To: robh at kernel.org
To: krzk+dt at kernel.org
To: conor+dt at kernel.org
Cc: devicetree at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: robert.marko at sartura.hr

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
Changes in v4:

- Split patch #4 in v3 into two patches, where the new patch #5 handles
  PCS selection, by returning the PCS only for ports that require it.

- Got rid of the '|' symbol for {rx,tx}-internal-delay-ps property
  description in the dt-bindings (patch #9).

- Link to v3: https://lore.kernel.org/r/20241118-sparx5-lan969x-switch-driver-4-v3-0-3cefee5e7e3a at microchip.com

Changes in v3:

v2 was kindly tested by Robert Marko. Not carrying the tag to v3 since
we have changes to the handling of the delays.

- Modified lan969x_rgmii_delay_config() to not apply any MAC delay when
  the {rx,tx}-internal-delay-ps properties are missing or set to 0
  (patch #7).

- Removed 'required' constraint from {rx-tx}-internal-delay-ps
  properties. Also added description and default value (Patch #8).

- Link to v2: https://lore.kernel.org/r/20241113-sparx5-lan969x-switch-driver-4-v2-0-0db98ac096d1 at microchip.com

Changes in v2:

  Most changes are in patch #7. RGMII implementation has been moved to
  it's own file lan969x_rgmii.c.

  Details:

    - Use ETH_P_8021Q and ETH_P_8021AD instead of the Sparx5 provided
      equivalents (patch #7).
    - Configure MAC delays through "{rx,tx}-internal-delay-ps"
      properties (patch #7).
    - Add selectors for all the phase shifts that the hardware supports
      (instead of only 2.0 ns, patch #7).
    - Add selectors for all the port speeds (instead of only 1000 mbps.)
    - Document RGMII delays in dt-bindings.

  - Link to v1: https://lore.kernel.org/r/20241106-sparx5-lan969x-switch-driver-4-v1-0-f7f7316436bd at microchip.com

---
Daniel Machon (9):
      net: sparx5: do some preparation work
      net: sparx5: add function for RGMII port check
      net: sparx5: use is_port_rgmii() throughout
      net: sparx5: skip low-speed configuration when port is RGMII
      net: sparx5: only return PCS for modes that require it
      net: sparx5: verify RGMII speeds
      net: lan969x: add RGMII registers
      net: lan969x: add RGMII implementation
      dt-bindings: net: sparx5: document RGMII delays

 .../bindings/net/microchip,sparx5-switch.yaml      |  18 ++
 drivers/net/ethernet/microchip/sparx5/Makefile     |   3 +-
 .../ethernet/microchip/sparx5/lan969x/lan969x.c    |   5 +
 .../ethernet/microchip/sparx5/lan969x/lan969x.h    |  10 +
 .../microchip/sparx5/lan969x/lan969x_rgmii.c       | 224 +++++++++++++++++++++
 .../net/ethernet/microchip/sparx5/sparx5_main.c    |  29 ++-
 .../net/ethernet/microchip/sparx5/sparx5_main.h    |   3 +
 .../ethernet/microchip/sparx5/sparx5_main_regs.h   | 145 +++++++++++++
 .../net/ethernet/microchip/sparx5/sparx5_phylink.c |  14 +-
 .../net/ethernet/microchip/sparx5/sparx5_port.c    |  57 ++++--
 .../net/ethernet/microchip/sparx5/sparx5_port.h    |   5 +
 11 files changed, 484 insertions(+), 29 deletions(-)
---
base-commit: 2c27c7663390d28bc71e97500eb68e0ce2a7223f
change-id: 20241104-sparx5-lan969x-switch-driver-4-d59b7820485a

Best regards,
-- 
Daniel Machon <daniel.machon at microchip.com>



From daniel.machon at microchip.com  Fri Dec 13 05:41:01 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:41:01 +0100
Subject: [PATCH net-next v4 2/9] net: sparx5: add function for RGMII port
 check
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-2-d1a72c9c4714@microchip.com>

The lan969x device contains two RGMII port interfaces, sitting at port
28 and 29. Add function: is_port_rgmii() to the match data ops, that
checks if a given port is an RGMII port or not. For Sparx5, this
function always returns false.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c | 1 +
 drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h | 5 +++++
 drivers/net/ethernet/microchip/sparx5/sparx5_main.c     | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_main.h     | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_port.h     | 5 +++++
 5 files changed, 13 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
index c2afa2176b08..76f0c8635eb9 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
@@ -329,6 +329,7 @@ static const struct sparx5_ops lan969x_ops = {
 	.is_port_5g              = &lan969x_port_is_5g,
 	.is_port_10g             = &lan969x_port_is_10g,
 	.is_port_25g             = &lan969x_port_is_25g,
+	.is_port_rgmii           = &lan969x_port_is_rgmii,
 	.get_port_dev_index      = &lan969x_port_dev_mapping,
 	.get_port_dev_bit        = &lan969x_get_dev_mode_bit,
 	.get_hsch_max_group_rate = &lan969x_get_hsch_max_group_rate,
diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
index 2489d0d32dfd..4b91c47d6d21 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
@@ -59,6 +59,11 @@ static inline bool lan969x_port_is_25g(int portno)
 	return false;
 }
 
+static inline bool lan969x_port_is_rgmii(int portno)
+{
+	return portno == 28 || portno == 29;
+}
+
 /* lan969x_calendar.c */
 int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
 			      struct sparx5_calendar_data *data);
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index f61aa15beab7..4be717ba7d37 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -1072,6 +1072,7 @@ static const struct sparx5_ops sparx5_ops = {
 	.is_port_5g              = &sparx5_port_is_5g,
 	.is_port_10g             = &sparx5_port_is_10g,
 	.is_port_25g             = &sparx5_port_is_25g,
+	.is_port_rgmii           = &sparx5_port_is_rgmii,
 	.get_port_dev_index      = &sparx5_port_dev_mapping,
 	.get_port_dev_bit        = &sparx5_port_dev_mapping,
 	.get_hsch_max_group_rate = &sparx5_get_hsch_max_group_rate,
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index d5dd953b0a71..c58d7841638e 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -313,6 +313,7 @@ struct sparx5_ops {
 	bool (*is_port_5g)(int portno);
 	bool (*is_port_10g)(int portno);
 	bool (*is_port_25g)(int portno);
+	bool (*is_port_rgmii)(int portno);
 	u32  (*get_port_dev_index)(struct sparx5 *sparx5, int port);
 	u32  (*get_port_dev_bit)(struct sparx5 *sparx5, int port);
 	u32  (*get_hsch_max_group_rate)(int grp);
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
index 9b9bcc6834bc..c8a37468a3d1 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
@@ -40,6 +40,11 @@ static inline bool sparx5_port_is_25g(int portno)
 	return portno >= 56 && portno <= 63;
 }
 
+static inline bool sparx5_port_is_rgmii(int portno)
+{
+	return false;
+}
+
 static inline u32 sparx5_to_high_dev(struct sparx5 *sparx5, int port)
 {
 	const struct sparx5_ops *ops = sparx5->data->ops;

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 13 05:41:02 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:41:02 +0100
Subject: [PATCH net-next v4 3/9] net: sparx5: use is_port_rgmii()
 throughout
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-3-d1a72c9c4714@microchip.com>

Now that we can check if a given port is an RGMII port, use it in the
following cases:

 - To set RGMII PHY modes for RGMII port devices.

 - To avoid checking for a SerDes node in the devicetree, when the port
   is an RGMII port.

 - To bail out of sparx5_port_init() when the common configuration is
   done.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 .../net/ethernet/microchip/sparx5/sparx5_main.c    | 28 +++++++++++++++-------
 .../net/ethernet/microchip/sparx5/sparx5_port.c    |  3 +++
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 4be717ba7d37..e68277c38adc 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -313,10 +313,13 @@ static int sparx5_create_port(struct sparx5 *sparx5,
 			      struct initial_port_config *config)
 {
 	struct sparx5_port *spx5_port;
+	const struct sparx5_ops *ops;
 	struct net_device *ndev;
 	struct phylink *phylink;
 	int err;
 
+	ops = sparx5->data->ops;
+
 	ndev = sparx5_create_netdev(sparx5, config->portno);
 	if (IS_ERR(ndev)) {
 		dev_err(sparx5->dev, "Could not create net device: %02u\n",
@@ -357,6 +360,9 @@ static int sparx5_create_port(struct sparx5 *sparx5,
 		MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD |
 		MAC_2500FD | MAC_5000FD | MAC_10000FD | MAC_25000FD;
 
+	if (ops->is_port_rgmii(spx5_port->portno))
+		phy_interface_set_rgmii(spx5_port->phylink_config.supported_interfaces);
+
 	__set_bit(PHY_INTERFACE_MODE_SGMII,
 		  spx5_port->phylink_config.supported_interfaces);
 	__set_bit(PHY_INTERFACE_MODE_QSGMII,
@@ -830,6 +836,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 	struct initial_port_config *configs, *config;
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *ports, *portnp;
+	const struct sparx5_ops *ops;
 	struct reset_control *reset;
 	struct sparx5 *sparx5;
 	int idx = 0, err = 0;
@@ -851,6 +858,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	regs = sparx5->data->regs;
+	ops = sparx5->data->ops;
 
 	/* Do switch core reset if available */
 	reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
@@ -880,7 +888,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 
 	for_each_available_child_of_node(ports, portnp) {
 		struct sparx5_port_config *conf;
-		struct phy *serdes;
+		struct phy *serdes = NULL;
 		u32 portno;
 
 		err = of_property_read_u32(portnp, "reg", &portno);
@@ -910,13 +918,17 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 			conf->sd_sgpio = ~0;
 		else
 			sparx5->sd_sgpio_remapping = true;
-		serdes = devm_of_phy_get(sparx5->dev, portnp, NULL);
-		if (IS_ERR(serdes)) {
-			err = dev_err_probe(sparx5->dev, PTR_ERR(serdes),
-					    "port %u: missing serdes\n",
-					    portno);
-			of_node_put(portnp);
-			goto cleanup_config;
+		/* There is no SerDes node for RGMII ports. */
+		if (!ops->is_port_rgmii(portno)) {
+			serdes = devm_of_phy_get(sparx5->dev, portnp, NULL);
+			if (IS_ERR(serdes)) {
+				err = dev_err_probe(sparx5->dev,
+						    PTR_ERR(serdes),
+						    "port %u: missing serdes\n",
+						    portno);
+				of_node_put(portnp);
+				goto cleanup_config;
+			}
 		}
 		config->portno = portno;
 		config->node = portnp;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index f39bf4878e11..996dc4343019 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1090,6 +1090,9 @@ int sparx5_port_init(struct sparx5 *sparx5,
 		 ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
 		 sparx5, ANA_CL_FILTER_CTRL(port->portno));
 
+	if (ops->is_port_rgmii(port->portno))
+		return 0; /* RGMII device - nothing more to configure */
+
 	/* Configure MAC vlan awareness */
 	err = sparx5_port_max_tags_set(sparx5, port);
 	if (err)

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 13 05:41:03 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:41:03 +0100
Subject: [PATCH net-next v4 4/9] net: sparx5: skip low-speed configuration
 when port is RGMII
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-4-d1a72c9c4714@microchip.com>

When doing a port config, we configure low-speed port devices, among
other things. We have a check to ensure, that the device is indeed a
low-speed device, an not a high-speed device. Add an additional check,
to ensure that the device is not an RGMII device.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 996dc4343019..0a1374422ccb 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -994,6 +994,7 @@ int sparx5_port_config(struct sparx5 *sparx5,
 		       struct sparx5_port *port,
 		       struct sparx5_port_config *conf)
 {
+	bool rgmii = phy_interface_mode_is_rgmii(conf->phy_mode);
 	bool high_speed_dev = sparx5_is_baser(conf->portmode);
 	const struct sparx5_ops *ops = sparx5->data->ops;
 	int err, urgency, stop_wm;
@@ -1003,7 +1004,7 @@ int sparx5_port_config(struct sparx5 *sparx5,
 		return err;
 
 	/* high speed device is already configured */
-	if (!high_speed_dev)
+	if (!rgmii && !high_speed_dev)
 		sparx5_port_config_low_set(sparx5, port, conf);
 
 	/* Configure flow control */

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 13 05:41:04 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:41:04 +0100
Subject: [PATCH net-next v4 5/9] net: sparx5: only return PCS for modes
 that require it
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-5-d1a72c9c4714@microchip.com>

The RGMII ports have no PCS to configure. Make sure we only return the
PCS for port modes that require it.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
index f8562c1a894d..035d2f1bea0d 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
@@ -32,7 +32,19 @@ sparx5_phylink_mac_select_pcs(struct phylink_config *config,
 {
 	struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));
 
-	return &port->phylink_pcs;
+	/* Return the PCS for all the modes that require it. */
+	switch (interface) {
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_QSGMII:
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_25GBASER:
+		return &port->phylink_pcs;
+	default:
+		return NULL;
+	}
 }
 
 static void sparx5_phylink_mac_config(struct phylink_config *config,

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 13 05:41:00 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:41:00 +0100
Subject: [PATCH net-next v4 1/9] net: sparx5: do some preparation work
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-1-d1a72c9c4714@microchip.com>

The sparx5_port_init() does initial configuration of a variety of
different features and options for each port. Some are shared for all
types of devices, some are not. As it is now, common configuration is
done after configuration of low-speed devices. This will not work when
adding RGMII support in a subsequent patch.

In preparation for lan969x RGMII support, move a block of code, that
configures 2g5 devices, down. This ensures that the configuration common
to all devices is done before configuration of 2g5, 5g, 10g and 25g
devices.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 .../net/ethernet/microchip/sparx5/sparx5_port.c    | 36 +++++++++++-----------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index f9d1a6bb9bff..f39bf4878e11 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1067,24 +1067,6 @@ int sparx5_port_init(struct sparx5 *sparx5,
 	if (err)
 		return err;
 
-	/* Configure MAC vlan awareness */
-	err = sparx5_port_max_tags_set(sparx5, port);
-	if (err)
-		return err;
-
-	/* Set Max Length */
-	spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
-		 DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
-		 sparx5,
-		 DEV2G5_MAC_MAXLEN_CFG(port->portno));
-
-	/* 1G/2G5: Signal Detect configuration */
-	spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
-		DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
-		DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
-		sparx5,
-		DEV2G5_PCS1G_SD_CFG(port->portno));
-
 	/* Set Pause WM hysteresis */
 	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_START_SET(pause_start) |
 		 QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop) |
@@ -1108,6 +1090,24 @@ int sparx5_port_init(struct sparx5 *sparx5,
 		 ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
 		 sparx5, ANA_CL_FILTER_CTRL(port->portno));
 
+	/* Configure MAC vlan awareness */
+	err = sparx5_port_max_tags_set(sparx5, port);
+	if (err)
+		return err;
+
+	/* Set Max Length */
+	spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
+		 DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
+		 sparx5,
+		 DEV2G5_MAC_MAXLEN_CFG(port->portno));
+
+	/* 1G/2G5: Signal Detect configuration */
+	spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
+		DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
+		DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
+		sparx5,
+		DEV2G5_PCS1G_SD_CFG(port->portno));
+
 	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII ||
 	    conf->portmode == PHY_INTERFACE_MODE_SGMII) {
 		err = sparx5_serdes_set(sparx5, port, conf);

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 13 05:41:06 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:41:06 +0100
Subject: [PATCH net-next v4 7/9] net: lan969x: add RGMII registers
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-7-d1a72c9c4714@microchip.com>

Configuration of RGMII is done by configuring the GPIO and clock
settings in the HSIOWRAP target, and configuring the RGMII port devices
in the DEVRGMII target. Both targets contain registers replicated for
the number of RGMII port devices, which is two.

Add said targets and register macros required to configure RGMII.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 .../ethernet/microchip/sparx5/lan969x/lan969x.c    |   3 +
 .../ethernet/microchip/sparx5/sparx5_main_regs.h   | 145 +++++++++++++++++++++
 2 files changed, 148 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
index 76f0c8635eb9..be49a99556fe 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
@@ -90,9 +90,12 @@ static const struct sparx5_main_io_resource lan969x_main_iomap[] =  {
 	{ TARGET_DEV2G5 + 27,         0x30d8000, 1 }, /* 0xe30d8000 */
 	{ TARGET_DEV10G +  9,         0x30dc000, 1 }, /* 0xe30dc000 */
 	{ TARGET_PCS10G_BR +  9,      0x30e0000, 1 }, /* 0xe30e0000 */
+	{ TARGET_DEVRGMII,            0x30e4000, 1 }, /* 0xe30e4000 */
+	{ TARGET_DEVRGMII +  1,       0x30e8000, 1 }, /* 0xe30e8000 */
 	{ TARGET_DSM,                 0x30ec000, 1 }, /* 0xe30ec000 */
 	{ TARGET_PORT_CONF,           0x30f0000, 1 }, /* 0xe30f0000 */
 	{ TARGET_ASM,                 0x3200000, 1 }, /* 0xe3200000 */
+	{ TARGET_HSIO_WRAP,           0x3408000, 1 }, /* 0xe3408000 */
 };
 
 static struct sparx5_sdlb_group lan969x_sdlb_groups[LAN969X_SDLB_GRP_CNT] = {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
index 561344f19062..d9ef4ef137b8 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
@@ -37,6 +37,7 @@ enum sparx5_target {
 	TARGET_FDMA = 117,
 	TARGET_GCB = 118,
 	TARGET_HSCH = 119,
+	TARGET_HSIO_WRAP = 120,
 	TARGET_LRN = 122,
 	TARGET_PCEP = 129,
 	TARGET_PCS10G_BR = 132,
@@ -54,6 +55,7 @@ enum sparx5_target {
 	TARGET_VCAP_SUPER = 326,
 	TARGET_VOP = 327,
 	TARGET_XQS = 331,
+	TARGET_DEVRGMII = 392,
 	NUM_TARGETS = 517
 };
 
@@ -5367,6 +5369,69 @@ extern const struct sparx5_regs *regs;
 #define HSCH_TAS_STATEMACHINE_CFG_REVISIT_DLY_GET(x)\
 	FIELD_GET(HSCH_TAS_STATEMACHINE_CFG_REVISIT_DLY, x)
 
+/* LAN969X ONLY */
+/* HSIOWRAP:XMII_CFG:XMII_CFG */
+#define HSIO_WRAP_XMII_CFG(g)                                                  \
+	__REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 0, 0, 1, 4)
+
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG         GENMASK(2, 1)
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_SET(x)\
+	FIELD_PREP(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG, x)
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_GET(x)\
+	FIELD_GET(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG, x)
+
+/* LAN969X ONLY */
+/* HSIOWRAP:XMII_CFG:RGMII_CFG */
+#define HSIO_WRAP_RGMII_CFG(g)                                                 \
+	__REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 4, 0, 1, 4)
+
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG           GENMASK(4, 2)
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_SET(x)\
+	FIELD_PREP(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG, x)
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_GET(x)\
+	FIELD_GET(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG, x)
+
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST         BIT(1)
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_SET(x)\
+	FIELD_PREP(HSIO_WRAP_RGMII_CFG_RGMII_TX_RST, x)
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_GET(x)\
+	FIELD_GET(HSIO_WRAP_RGMII_CFG_RGMII_TX_RST, x)
+
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST         BIT(0)
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_SET(x)\
+	FIELD_PREP(HSIO_WRAP_RGMII_CFG_RGMII_RX_RST, x)
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_GET(x)\
+	FIELD_GET(HSIO_WRAP_RGMII_CFG_RGMII_RX_RST, x)
+
+/* LAN969X ONLY */
+/* HSIOWRAP:XMII_CFG:DLL_CFG */
+#define HSIO_WRAP_DLL_CFG(g, r)                                                \
+	__REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 12, r, 2, 4)
+
+#define HSIO_WRAP_DLL_CFG_DLL_ENA                BIT(19)
+#define HSIO_WRAP_DLL_CFG_DLL_ENA_SET(x)\
+	FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_ENA, x)
+#define HSIO_WRAP_DLL_CFG_DLL_ENA_GET(x)\
+	FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_ENA, x)
+
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA            BIT(18)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(x)\
+	FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_CLK_ENA, x)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_GET(x)\
+	FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_CLK_ENA, x)
+
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL            GENMASK(17, 15)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(x)\
+	FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_CLK_SEL, x)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_GET(x)\
+	FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_CLK_SEL, x)
+
+#define HSIO_WRAP_DLL_CFG_DLL_RST                BIT(0)
+#define HSIO_WRAP_DLL_CFG_DLL_RST_SET(x)\
+	FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_RST, x)
+#define HSIO_WRAP_DLL_CFG_DLL_RST_GET(x)\
+	FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_RST, x)
+
 /* LRN:COMMON:COMMON_ACCESS_CTRL */
 #define LRN_COMMON_ACCESS_CTRL                                                 \
 	__REG(TARGET_LRN, 0, 1, 0, 0, 1, 72, 0, 0, 1, 4)
@@ -8110,4 +8175,84 @@ extern const struct sparx5_regs *regs;
 #define XQS_CNT(g)                                                             \
 	__REG(TARGET_XQS, 0, 1, 0, g, 1024, 4, 0, 0, 1, 4)
 
+/* LAN969X ONLY */
+/* DEV1G:DEV_CFG_STATUS:DEV_RST_CTRL */
+#define DEVRGMII_DEV_RST_CTRL(t)                                               \
+	__REG(TARGET_DEVRGMII, t, 2, 0, 0, 1, 36, 0, 0, 1, 4)
+
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL          GENMASK(22, 20)
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL_SET(x)\
+	FIELD_PREP(DEVRGMII_DEV_RST_CTRL_SPEED_SEL, x)
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL_GET(x)\
+	FIELD_GET(DEVRGMII_DEV_RST_CTRL_SPEED_SEL, x)
+
+/* LAN969X ONLY */
+/* DEV1G:MAC_CFG_STATUS:MAC_ENA_CFG */
+#define DEVRGMII_MAC_ENA_CFG(t)                                                \
+	__REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 0, 0, 1, 4)
+
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA              BIT(4)
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_ENA_CFG_RX_ENA, x)
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_ENA_CFG_RX_ENA, x)
+
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA              BIT(0)
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_ENA_CFG_TX_ENA, x)
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_ENA_CFG_TX_ENA, x)
+
+/* LAN969X ONLY */
+/* DEV1G:MAC_CFG_STATUS:MAC_TAGS_CFG */
+#define DEVRGMII_MAC_TAGS_CFG(t)                                               \
+	__REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 12, 0, 1, 4)
+
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID             GENMASK(31, 16)
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_TAG_ID, x)
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_TAGS_CFG_TAG_ID, x)
+
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA   BIT(3)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, x)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, x)
+
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA             GENMASK(2, 1)
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_PB_ENA, x)
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_TAGS_CFG_PB_ENA, x)
+
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA       BIT(0)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
+
+/* LAN969X ONLY */
+/* DEV1G:MAC_CFG_STATUS:MAC_IFG_CFG */
+#define DEVRGMII_MAC_IFG_CFG(t)                                                \
+	__REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 24, 0, 1, 4)
+
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG              GENMASK(12, 8)
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_IFG_CFG_TX_IFG, x)
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_IFG_CFG_TX_IFG, x)
+
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2             GENMASK(7, 4)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_IFG_CFG_RX_IFG2, x)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_IFG_CFG_RX_IFG2, x)
+
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1             GENMASK(3, 0)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_IFG_CFG_RX_IFG1, x)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_IFG_CFG_RX_IFG1, x)
+
 #endif /* _SPARX5_MAIN_REGS_H_ */

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 13 05:41:05 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:41:05 +0100
Subject: [PATCH net-next v4 6/9] net: sparx5: verify RGMII speeds
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-6-d1a72c9c4714@microchip.com>

When doing a port config, we verify the port speed against the PHY mode
and supported speeds of that PHY mode. Add checks for the four RGMII phy
modes: RGMII, RGMII_ID, RGMII_TXID and RGMII_RXID.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 0a1374422ccb..86d6c9e9ec7c 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -257,6 +257,15 @@ static int sparx5_port_verify_speed(struct sparx5 *sparx5,
 		     conf->speed != SPEED_25000))
 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
 		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		if (conf->speed != SPEED_1000 &&
+		    conf->speed != SPEED_100 &&
+		    conf->speed != SPEED_10)
+			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
+		break;
 	default:
 		return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
 	}

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 13 05:41:07 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:41:07 +0100
Subject: [PATCH net-next v4 8/9] net: lan969x: add RGMII implementation
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-8-d1a72c9c4714@microchip.com>

The lan969x switch device includes two RGMII port interfaces (port 28
and 29) supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps. MAC
level delays are configurable through the HSIO_WRAP target, by choosing
a phase shift selector, corresponding to a certain time delay in nano
seconds.

Add new file: lan969x_rgmii.c that contains the implementation for
configuring the RGMII port devices. MAC level delays are configured
using the "{rx,tx}-internal-delay-ps" properties. These properties must
be specified independently of the phy-mode. If missing, or set to zero,
the MAC will not apply any delay.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/Makefile     |   3 +-
 .../ethernet/microchip/sparx5/lan969x/lan969x.c    |   1 +
 .../ethernet/microchip/sparx5/lan969x/lan969x.h    |   5 +
 .../microchip/sparx5/lan969x/lan969x_rgmii.c       | 224 +++++++++++++++++++++
 .../net/ethernet/microchip/sparx5/sparx5_main.h    |   2 +
 .../net/ethernet/microchip/sparx5/sparx5_port.c    |   6 +
 6 files changed, 240 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/Makefile b/drivers/net/ethernet/microchip/sparx5/Makefile
index 4bf2a885a9da..3f34e83246a0 100644
--- a/drivers/net/ethernet/microchip/sparx5/Makefile
+++ b/drivers/net/ethernet/microchip/sparx5/Makefile
@@ -20,7 +20,8 @@ sparx5-switch-$(CONFIG_LAN969X_SWITCH) += lan969x/lan969x_regs.o \
 					  lan969x/lan969x.o \
 					  lan969x/lan969x_calendar.o \
 					  lan969x/lan969x_vcap_ag_api.o \
-					  lan969x/lan969x_vcap_impl.o
+					  lan969x/lan969x_vcap_impl.o \
+					  lan969x/lan969x_rgmii.o
 
 # Provide include files
 ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
index be49a99556fe..396f76b6eea5 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
@@ -340,6 +340,7 @@ static const struct sparx5_ops lan969x_ops = {
 	.set_port_mux            = &lan969x_port_mux_set,
 	.ptp_irq_handler         = &lan969x_ptp_irq_handler,
 	.dsm_calendar_calc       = &lan969x_dsm_calendar_calc,
+	.port_config_rgmii       = &lan969x_port_config_rgmii,
 };
 
 const struct sparx5_match_data lan969x_desc = {
diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
index 4b91c47d6d21..9a7ddebecf1e 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
@@ -67,4 +67,9 @@ static inline bool lan969x_port_is_rgmii(int portno)
 /* lan969x_calendar.c */
 int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
 			      struct sparx5_calendar_data *data);
+
+/* lan969x_rgmii.c */
+int lan969x_port_config_rgmii(struct sparx5_port *port,
+			      struct sparx5_port_config *conf);
+
 #endif
diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_rgmii.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_rgmii.c
new file mode 100644
index 000000000000..4e422ca50828
--- /dev/null
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_rgmii.c
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Microchip lan969x Switch driver
+ *
+ * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries.
+ */
+
+#include "lan969x.h"
+
+/* Tx clock selectors */
+#define LAN969X_RGMII_TX_CLK_SEL_125MHZ 1  /* 1000Mbps */
+#define LAN969X_RGMII_TX_CLK_SEL_25MHZ  2  /* 100Mbps */
+#define LAN969X_RGMII_TX_CLK_SEL_2M5MHZ 3  /* 10Mbps */
+
+/* Port speed selectors */
+#define LAN969X_RGMII_SPEED_SEL_10 0   /* Select 10Mbps speed */
+#define LAN969X_RGMII_SPEED_SEL_100 1  /* Select 100Mbps speed */
+#define LAN969X_RGMII_SPEED_SEL_1000 2 /* Select 1000Mbps speed */
+
+/* Clock delay selectors */
+#define LAN969X_RGMII_CLK_DELAY_SEL_1_0_NS 2  /* Phase shift 45deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_1_7_NS 3  /* Phase shift 77deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_2_0_NS 4  /* Phase shift 90deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_2_5_NS 5  /* Phase shift 112deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_3_0_NS 6  /* Phase shift 135deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_3_3_NS 7  /* Phase shift 147deg */
+
+#define LAN969X_RGMII_PORT_START_IDX 28 /* Index of the first RGMII port */
+#define LAN969X_RGMII_IFG_TX 4          /* TX Inter Frame Gap value */
+#define LAN969X_RGMII_IFG_RX1 5         /* RX1 Inter Frame Gap value */
+#define LAN969X_RGMII_IFG_RX2 1         /* RX2 Inter Frame Gap value */
+
+#define RGMII_PORT_IDX(port) ((port)->portno - LAN969X_RGMII_PORT_START_IDX)
+
+/* Get the tx clock selector based on the port speed. */
+static int lan969x_rgmii_get_clk_sel(int speed)
+{
+	return (speed == SPEED_10  ? LAN969X_RGMII_TX_CLK_SEL_2M5MHZ :
+		speed == SPEED_100 ? LAN969X_RGMII_TX_CLK_SEL_25MHZ :
+				     LAN969X_RGMII_TX_CLK_SEL_125MHZ);
+}
+
+/* Get the port speed selector based on the port speed. */
+static int lan969x_rgmii_get_speed_sel(int speed)
+{
+	return (speed == SPEED_10  ? LAN969X_RGMII_SPEED_SEL_10 :
+		speed == SPEED_100 ? LAN969X_RGMII_SPEED_SEL_100 :
+				     LAN969X_RGMII_SPEED_SEL_1000);
+}
+
+/* Get the clock delay selector based on the clock delay in picoseconds. */
+static int lan969x_rgmii_get_clk_delay_sel(struct sparx5_port *port,
+					   u32 delay_ps, u32 *clk_delay_sel)
+{
+	switch (delay_ps) {
+	case 0:
+		/* Hardware default selector. */
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_2_5_NS;
+		break;
+	case 1000:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_1_0_NS;
+		break;
+	case 1700:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_1_7_NS;
+		break;
+	case 2000:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_2_0_NS;
+		break;
+	case 2500:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_2_5_NS;
+		break;
+	case 3000:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_3_0_NS;
+		break;
+	case 3300:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_3_3_NS;
+		break;
+	default:
+		dev_err(port->sparx5->dev, "Invalid RGMII delay: %u", delay_ps);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Configure the RGMII tx clock frequency. */
+static void lan969x_rgmii_tx_clk_config(struct sparx5_port *port,
+					struct sparx5_port_config *conf)
+{
+	u32 clk_sel = lan969x_rgmii_get_clk_sel(conf->speed);
+	u32 idx = RGMII_PORT_IDX(port);
+
+	/* Take the RGMII clock domain out of reset and set tx clock
+	 * frequency.
+	 */
+	spx5_rmw(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_SET(clk_sel) |
+		 HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_SET(0) |
+		 HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_SET(0),
+		 HSIO_WRAP_RGMII_CFG_TX_CLK_CFG |
+		 HSIO_WRAP_RGMII_CFG_RGMII_TX_RST |
+		 HSIO_WRAP_RGMII_CFG_RGMII_RX_RST,
+		 port->sparx5, HSIO_WRAP_RGMII_CFG(idx));
+}
+
+/* Configure the RGMII port device. */
+static void lan969x_rgmii_port_device_config(struct sparx5_port *port,
+					     struct sparx5_port_config *conf)
+{
+	u32 dtag, dotag, etype, speed_sel, idx = RGMII_PORT_IDX(port);
+
+	speed_sel = lan969x_rgmii_get_speed_sel(conf->speed);
+
+	etype = (port->vlan_type == SPX5_VLAN_PORT_TYPE_S_CUSTOM ?
+		 port->custom_etype :
+		 port->vlan_type == SPX5_VLAN_PORT_TYPE_C ?
+		 ETH_P_8021Q : ETH_P_8021AD);
+
+	dtag = port->max_vlan_tags == SPX5_PORT_MAX_TAGS_TWO;
+	dotag = port->max_vlan_tags != SPX5_PORT_MAX_TAGS_NONE;
+
+	/* Enable the MAC. */
+	spx5_wr(DEVRGMII_MAC_ENA_CFG_RX_ENA_SET(1) |
+		DEVRGMII_MAC_ENA_CFG_TX_ENA_SET(1),
+		port->sparx5, DEVRGMII_MAC_ENA_CFG(idx));
+
+	/* Configure the Inter Frame Gap. */
+	spx5_wr(DEVRGMII_MAC_IFG_CFG_TX_IFG_SET(LAN969X_RGMII_IFG_TX) |
+		DEVRGMII_MAC_IFG_CFG_RX_IFG1_SET(LAN969X_RGMII_IFG_RX1) |
+		DEVRGMII_MAC_IFG_CFG_RX_IFG2_SET(LAN969X_RGMII_IFG_RX2),
+		port->sparx5, DEVRGMII_MAC_IFG_CFG(idx));
+
+	/* Configure port data rate. */
+	spx5_wr(DEVRGMII_DEV_RST_CTRL_SPEED_SEL_SET(speed_sel),
+		port->sparx5, DEVRGMII_DEV_RST_CTRL(idx));
+
+	/* Configure VLAN awareness. */
+	spx5_wr(DEVRGMII_MAC_TAGS_CFG_TAG_ID_SET(etype) |
+		DEVRGMII_MAC_TAGS_CFG_PB_ENA_SET(dtag) |
+		DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(dotag) |
+		DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(dotag),
+		port->sparx5,
+		DEVRGMII_MAC_TAGS_CFG(idx));
+}
+
+/* Configure the RGMII delay lines in the MAC.
+ *
+ * We use the rx-internal-delay-ps" and "tx-internal-delay-ps" properties to
+ * configure the rx and tx delays for the MAC. If these properties are missing
+ * or set to zero, the MAC will not apply any delay.
+ *
+ * The PHY side delays are determined by the PHY mode
+ * (e.g. PHY_INTERFACE_MODE_RGMII_{ID, RXID, TXID}), and ignored by the MAC side
+ * entirely.
+ */
+static int lan969x_rgmii_delay_config(struct sparx5_port *port,
+				      struct sparx5_port_config *conf)
+{
+	u32 tx_clk_sel, rx_clk_sel, tx_delay_ps = 0, rx_delay_ps = 0;
+	u32 idx = RGMII_PORT_IDX(port);
+	int err;
+
+	of_property_read_u32(port->of_node, "rx-internal-delay-ps",
+			     &rx_delay_ps);
+
+	of_property_read_u32(port->of_node, "tx-internal-delay-ps",
+			     &tx_delay_ps);
+
+	err = lan969x_rgmii_get_clk_delay_sel(port, rx_delay_ps, &rx_clk_sel);
+	if (err)
+		return err;
+
+	err = lan969x_rgmii_get_clk_delay_sel(port, tx_delay_ps, &tx_clk_sel);
+	if (err)
+		return err;
+
+	/* Configure rx delay. */
+	spx5_rmw(HSIO_WRAP_DLL_CFG_DLL_RST_SET(0) |
+		 HSIO_WRAP_DLL_CFG_DLL_ENA_SET(1) |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(!!rx_delay_ps) |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(rx_clk_sel),
+		 HSIO_WRAP_DLL_CFG_DLL_RST |
+		 HSIO_WRAP_DLL_CFG_DLL_ENA |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_ENA |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_SEL,
+		 port->sparx5, HSIO_WRAP_DLL_CFG(idx, 0));
+
+	/* Configure tx delay. */
+	spx5_rmw(HSIO_WRAP_DLL_CFG_DLL_RST_SET(0) |
+		 HSIO_WRAP_DLL_CFG_DLL_ENA_SET(1) |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(!!tx_delay_ps) |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(tx_clk_sel),
+		 HSIO_WRAP_DLL_CFG_DLL_RST |
+		 HSIO_WRAP_DLL_CFG_DLL_ENA |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_ENA |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_SEL,
+		 port->sparx5, HSIO_WRAP_DLL_CFG(idx, 1));
+
+	return 0;
+}
+
+/* Configure GPIO's to be used as RGMII interface. */
+static void lan969x_rgmii_gpio_config(struct sparx5_port *port)
+{
+	u32 idx = RGMII_PORT_IDX(port);
+
+	/* Enable the RGMII on the GPIOs. */
+	spx5_wr(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_SET(1), port->sparx5,
+		HSIO_WRAP_XMII_CFG(!idx));
+}
+
+int lan969x_port_config_rgmii(struct sparx5_port *port,
+			      struct sparx5_port_config *conf)
+{
+	int err;
+
+	err = lan969x_rgmii_delay_config(port, conf);
+	if (err)
+		return err;
+
+	lan969x_rgmii_tx_clk_config(port, conf);
+	lan969x_rgmii_gpio_config(port);
+	lan969x_rgmii_port_device_config(port, conf);
+
+	return 0;
+}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index c58d7841638e..3ae760da17e2 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -324,6 +324,8 @@ struct sparx5_ops {
 	irqreturn_t (*ptp_irq_handler)(int irq, void *args);
 	int (*dsm_calendar_calc)(struct sparx5 *sparx5, u32 taxi,
 				 struct sparx5_calendar_data *data);
+	int (*port_config_rgmii)(struct sparx5_port *port,
+				 struct sparx5_port_config *conf);
 };
 
 struct sparx5_main_io_resource {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 86d6c9e9ec7c..04bc8fffaf96 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1012,6 +1012,12 @@ int sparx5_port_config(struct sparx5 *sparx5,
 	if (err)
 		return err;
 
+	if (rgmii) {
+		err = ops->port_config_rgmii(port, conf);
+		if (err)
+			return err;
+	}
+
 	/* high speed device is already configured */
 	if (!rgmii && !high_speed_dev)
 		sparx5_port_config_low_set(sparx5, port, conf);

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 13 05:41:08 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 13 Dec 2024 14:41:08 +0100
Subject: [PATCH net-next v4 9/9] dt-bindings: net: sparx5: document RGMII
 delays
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241213-sparx5-lan969x-switch-driver-4-v4-9-d1a72c9c4714@microchip.com>

The lan969x switch device supports two RGMII port interfaces that can be
configured for MAC level rx and tx delays. Document two new properties
{rx,tx}-internal-delay-ps in the bindings, used to select these delays.

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 .../bindings/net/microchip,sparx5-switch.yaml          | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml b/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
index dedfad526666..a73fc5036905 100644
--- a/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
+++ b/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
@@ -129,6 +129,24 @@ properties:
             minimum: 0
             maximum: 383
 
+          rx-internal-delay-ps:
+            description:
+              RGMII Receive Clock Delay defined in pico seconds, used to select
+              the DLL phase shift between 1000 ps (45 degree shift at 1Gbps) and
+              3300 ps (147 degree shift at 1Gbps). A value of 0 ps will disable
+              any delay. The Default is no delay.
+            enum: [0, 1000, 1700, 2000, 2500, 3000, 3300]
+            default: 0
+
+          tx-internal-delay-ps:
+            description:
+              RGMII Transmit Clock Delay defined in pico seconds, used to select
+              the DLL phase shift between 1000 ps (45 degree shift at 1Gbps) and
+              3300 ps (147 degree shift at 1Gbps). A value of 0 ps will disable
+              any delay. The Default is no delay.
+            enum: [0, 1000, 1700, 2000, 2500, 3000, 3300]
+            default: 0
+
         required:
           - reg
           - phys

-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Dec 13 05:43:18 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 13 Dec 2024 14:43:18 +0100
Subject: [PATCH v4] pinctrl: stm32: Add check for clk_enable()
In-Reply-To: <a47b567d-96a6-4a87-9f60-33a311c281ae@denx.de>
References: <20241213010948.2623382-1-zmw12306@gmail.com>
	 <a47b567d-96a6-4a87-9f60-33a311c281ae@denx.de>
Message-ID: <05081f6ebe19ce3e0e989aebf415c9ff86a39e3d.camel@foss.st.com>

On Fri, 2024-12-13 at 12:45 +0100, Marek Vasut wrote:
> On 12/13/24 2:09 AM, Mingwei Zheng wrote:
> 
> [...]
> 
> > @@ -1397,7 +1397,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
> > ????????return 0;
> > ? 
> > ? err_clk:
> > -???????clk_disable_unprepare(bank->clk);
> > +???????clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);
> 
> 
> Should this be
> 
> -clk_disable_unprepare(pctl->clks[pctl->nbanks].clk);
> +clk_disable_unprepare(pctl->clks[bank->bank_nr].clk);
> ?????????????????????????????????? ^^^^^^^^^^^^^
> 

No Marek,
pctl->nbanks is the progressive index of the bank's subnode, that is also the index for pctl->clks[].
Instead bank->bank_nr can be computed from gpio-ranges, and there is no guarantee it would match the index for pctl->clks[].

Actually this is quite confusing; I think it would be much cleaner dropping the clock handling from stm32_gpiolib_register_bank() and moving it to its caller.
In stm32_pctl_probe() we can just call clk_bulk_prepare_enable() and, in case of error, clk_bulk_disable_unprepare()

Antonio

> ?
> 
> > ????????return err;
> > ? }
> > ? 
> > @@ -1617,10 +1617,18 @@ int stm32_pctl_probe(struct platform_device *pdev)
> > ????????????????return -EINVAL;
> > ????????}
> > ????????pctl->banks = devm_kcalloc(dev, banks, sizeof(*pctl->banks),
> > -???????????????????????GFP_KERNEL);
> > +????????????????????????????????? GFP_KERNEL);
> > ????????if (!pctl->banks)
> > ????????????????return -ENOMEM;
> > ? 
> > +???????pctl->clks = devm_kcalloc(dev, banks, sizeof(*pctl->clks),
> > +???????????????????????????????? GFP_KERNEL);
> > +???????if (!pctl->clks)
> > +???????????????return -ENOMEM;
> > +
> > +???????for (i = 0; i < banks; ++i)
> 
> i++


From krzk at kernel.org  Fri Dec 13 05:55:38 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 14:55:38 +0100
Subject: [PATCH 2/3] soc: samsung: Add a driver for Samsung SPEEDY host
 controller
In-Reply-To: <2a7f71b6-0967-40ee-9d0f-d7144eafcd5a@gmail.com>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
 <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
 <f08b068e-bc6b-4d9d-9839-370883309b88@kernel.org>
 <2a7f71b6-0967-40ee-9d0f-d7144eafcd5a@gmail.com>
Message-ID: <c0d58c4d-e3dc-445d-93c4-a2aed07af143@kernel.org>

On 13/12/2024 10:42, Markuss Broks wrote:
> Hi Krzysztof,
> 
> On 12/13/24 9:49 AM, Krzysztof Kozlowski wrote:
>> On 12/12/2024 22:09, Markuss Broks wrote:
>>> Add a driver for Samsung SPEEDY serial bus host controller.
>>> SPEEDY is a proprietary 1 wire serial bus used by Samsung
>>> in various devices (usually mobile), like Samsung Galaxy
>>> phones. It is usually used for connecting PMIC or various
>>> other peripherals, like audio codecs or RF components.
>>>
>>> This bus can address at most 1MiB (4 bit device address,
>>> 8 bit registers per device, 8 bit wide registers:
>>> 256*256*16 = 1MiB of address space.
>>>
>>> Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
>>> Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
>>> Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
>>> ---
>>>   drivers/soc/samsung/Kconfig               |  13 +
>>>   drivers/soc/samsung/Makefile              |   2 +
>>>   drivers/soc/samsung/exynos-speedy.c       | 457 ++++++++++++++++++++++++++++++
>>>   include/linux/soc/samsung/exynos-speedy.h |  56 ++++
>>>   4 files changed, 528 insertions(+)
>>>
>>> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
>>> index 1a5dfdc978dc4069eb71c4e8eada7ff1913b86b3..a38150fc9999ded1e1e93e2a9ef43b88175d34bd 100644
>>> --- a/drivers/soc/samsung/Kconfig
>>> +++ b/drivers/soc/samsung/Kconfig
>>> @@ -49,6 +49,19 @@ config EXYNOS_PMU_ARM_DRIVERS
>>>   	bool "Exynos PMU ARMv7-specific driver extensions" if COMPILE_TEST
>>>   	depends on EXYNOS_PMU
>>>   
>>> +config EXYNOS_SPEEDY
>>> +	tristate "Exynos SPEEDY host controller driver"
>>> +	depends on ARCH_EXYNOS || COMPILE_TEST
>>> +	depends on OF
>>> +	depends on REGMAP_MMIO
>>> +	help
>>> +	  Enable support for Exynos SPEEDY host controller block.
>>> +	  SPEEDY is a 1 wire proprietary Samsung serial bus, found in
>>> +	  modern Samsung Exynos SoCs, like Exynos8895 and newer.
>>
>> I did not check that much but this looks like 1wire for which we have
>> subsystem. Please investigate more and figure out the differences.
> 
> This is not compatible with Dallas Semi 1-Wire bus. There are several 
> differences but the phy level is not compatible, looking at the Samsung 
> patent. [1] The most obvious difference is that 1-Wire is discoverable, 
> and this bus isn't. I'm pretty sure this is Samsung's own solution to a 
> serial interface through only one wire.
> 

It's fine then.

>>
>>> +
>>> +	  Select this if you have a Samsung Exynos device which uses
>>> +	  SPEEDY bus.
>>> +
>>
>>> +
>>> +/* SPEEDY_PACKET_GAP_TIME register bits */
>>> +#define SPEEDY_FIFO_TX_ALMOST_EMPTY			(1 << 4)
>>> +#define SPEEDY_FIFO_RX_ALMOST_FULL			(1 << 8)
>>> +#define SPEEDY_FSM_INIT					(1 << 1)
>>> +#define SPEEDY_FSM_TX_CMD				(1 << 2)
>>> +#define SPEEDY_FSM_STANDBY				(1 << 3)
>>> +#define SPEEDY_FSM_DATA					(1 << 4)
>>> +#define SPEEDY_FSM_TIMEOUT				(1 << 5)
>>> +#define SPEEDY_FSM_TRANS_DONE				(1 << 6)
>>> +#define SPEEDY_FSM_IO_RX_STAT_MASK			(3 << 7)
>>> +#define SPEEDY_FSM_IO_TX_IDLE				(1 << 9)
>>> +#define SPEEDY_FSM_IO_TX_GET_PACKET			(1 << 10)
>>> +#define SPEEDY_FSM_IO_TX_PACKET				(1 << 11)
>>> +#define SPEEDY_FSM_IO_TX_DONE				(1 << 12)
>>> +
>>> +#define SPEEDY_RX_LENGTH(n)				((n) << 0)
>>> +#define SPEEDY_TX_LENGTH(n)				((n) << 8)
>>> +
>>> +#define SPEEDY_DEVICE(x)				((x & 0xf) << 15)
>>> +#define SPEEDY_ADDRESS(x)				((x & 0xff) << 7)
>>> +
>>> +static const struct of_device_id speedy_match[] = {
>>> +	{ .compatible = "samsung,exynos9810-speedy" },
>>> +	{ /* Sentinel */ }
>>> +};
>>> +MODULE_DEVICE_TABLE(of, speedy_match);
>> This is never at top of the file, but immediately before driver
>> structure. Look at other drivers.
> The function speedy_get_device uses this to match the compatible, do I 
> just leave the prototype here?


1. Entire speedy_get_device() is unused so it will be removed.
2. Even if it stays, speedy_get_device() is not supposed to match
anything. How are you supposed to use Samsung PMIC on different
controller? These things should not be tied.


>>
>>> +
>>> +static const struct regmap_config speedy_map_cfg = {
>>> +	.reg_bits = 32,
>>> +	.val_bits = 32,
>>> +};


...

>>> +	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_READ |
>>> +	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
>>> +
>>> +	int_ctl = SPEEDY_TRANSFER_DONE_EN | SPEEDY_FIFO_RX_ALMOST_FULL_EN |
>>> +		  SPEEDY_RX_FIFO_INT_TRAILER_EN | SPEEDY_RX_MODEBIT_ERR_EN |
>>> +		  SPEEDY_RX_GLITCH_ERR_EN | SPEEDY_RX_ENDBIT_ERR_EN |
>>> +		  SPEEDY_REMOTE_RESET_REQ_EN;
>>> +
>>> +	ret = speedy_int_clear(speedy);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	/* Wait for xfer done */
>>> +	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
>>> +				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	ret = regmap_read(speedy->map, SPEEDY_RX_DATA, val);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	ret = speedy_int_clear(speedy);
>>> +
>>> +	mutex_unlock(&speedy->io_lock);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +int exynos_speedy_read(const struct speedy_device *device, u32 addr, u32 *val)
>>> +{
>>> +	return _speedy_read(device->speedy, device->reg, addr, val);
>>> +}
>>> +EXPORT_SYMBOL_GPL(exynos_speedy_read);
>> Nope, drop, unused.
> This is intended to be used with other device drivers, this driver in 
> itself doesn't do anything, it only configures the controller and makes 
> it ready for transmitting data, it's other drivers that will come (e.g. 
> S2MPS18 PMIC, which uses SPEEDY for communication with the SoC) that 
> will utilize those functions.

Post entire series, so we see users of this API. If you post API without
users, it won't be accepted simply because there are no users and we do
not want dead, unused code.

Anyway we must see how you intend to use that interface to properly
review it.

>>
>>> +
>>> +/**
>>> + * _speedy_write() - internal speedy write operation
>>> + * @speedy:	pointer to speedy controller struct
>>> + * @reg:	address of device on the bus
>>> + * @addr:       address to write
>>> + * @val:        value to write
>>> + *


...

>>> +}
>>> +
>>> +static struct platform_driver speedy_driver = {
>>> +	.probe = speedy_probe,
>>> +	.driver = {
>>> +		.name = "exynos-speedy",
>>> +		.of_match_table = speedy_match,
>>> +	},
>>> +};
>>> +
>>> +module_platform_driver(speedy_driver);
>>> +
>>> +MODULE_DESCRIPTION("Samsung Exynos SPEEDY host controller driver");
>>> +MODULE_AUTHOR("Markuss Broks <markuss.broks at gmail.com>");
>>> +MODULE_LICENSE("GPL");
>>> diff --git a/include/linux/soc/samsung/exynos-speedy.h b/include/linux/soc/samsung/exynos-speedy.h
>>> new file mode 100644
>>> index 0000000000000000000000000000000000000000..b2857d65d3b50927373866dd8ae1c47e98af6d7b
>>> --- /dev/null
>>> +++ b/include/linux/soc/samsung/exynos-speedy.h
>> Drop the header, not used.
> Same here, please clarify how this should be handled. This driver 
> implements the devm_speedy_get_device and read/write functions for its 
> child devices in that header, future drivers for e.g. PMIC would use 
> this header and call devm_speedy_get_device to get a speedy_device 
> pointer and then use read/write functions to read/write from the bus.

This needs to be proper bus with proper speedy_driver clients. See how
other buses - struct bus_type. Recent example of bus using platform
drivers for devices would be pwrseq (power/sequence). Not so old other
bus using its own xxx_driver for devices could be cxl or ffa (arm_ffa).
This current non-bus approach, could also work if this is really Samsung
specific. See memory/ for examples of MMIO buses and MMIO clients.

I don't know good examples of non-MMIO buses not using bus_type and I am
not sure whether this is accepted in general. I'll ask on IRC, maybe
someone will give some hints.


Best regards,
Krzysztof


From krzk at kernel.org  Fri Dec 13 05:58:22 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 14:58:22 +0100
Subject: [PATCH] arm64: defconfig: remove obsolete CONFIG_SM_DISPCC_8650
In-Reply-To: <20241213122749.2132488-1-ross.burton@arm.com>
References: <20241213122749.2132488-1-ross.burton@arm.com>
Message-ID: <8ae0c041-afad-4e00-8a4c-611bfb01840b@kernel.org>

On 13/12/2024 13:27, Ross Burton wrote:
> This option was removed from the Kconfig in commit 802b83205519 ("clk:
> qcom: fold dispcc-sm8650 info dispcc-sm8550") but it was not removed
> from the defconfig.
> 
> Fixes: 802b83205519 ("clk: qcom: fold dispcc-sm8650 info dispcc-sm8550")
> Signed-off-by: Ross Burton <ross.burton at arm.com>
> ---
This won't be applied if you do not send it to proper folks. See soc
maintainer profile for explanation. TLDR, get maintainers on SoC
subsystem this belongs to.

Please resend to proper addresses with:

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

Best regards,
Krzysztof


From avromanov at salutedevices.com  Fri Dec 13 06:07:40 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:40 +0300
Subject: [PATCH v11 07/22] crypto: amlogic - Move algs definition and cipher API to cipher.c
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-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>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 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 9259ad0417d1..106d4ee2e5e9 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -64,66 +64,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;
@@ -137,20 +77,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);
@@ -227,19 +155,20 @@ 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++) {
+		algs[i].mc = mc;
+		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;
@@ -249,16 +178,17 @@ static int meson_register_algs(struct meson_dev *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;
 		}
 	}
@@ -288,9 +218,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;
@@ -304,8 +234,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;
@@ -319,7 +247,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 0dde7662ae37..f0ccd28545aa 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -163,10 +163,12 @@ int meson_get_engine_number(struct meson_dev *mc);
 
 void meson_dma_start(struct meson_dev *mc, int flow);
 
-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  Fri Dec 13 06:07:39 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:39 +0300
Subject: [PATCH v11 06/22] crypto: amlogic - Drop status field from meson_flow
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-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>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 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 44e71e917e5e..9259ad0417d1 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -53,7 +53,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 cb70277c3a31..0dde7662ae37 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  Fri Dec 13 06:07:34 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:34 +0300
Subject: [PATCH v11 01/22] crypto: amlogic - Don't hardcode IRQ count
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-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 1c18a5b8470e..dc35d7304eb0 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)
@@ -250,19 +268,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");
@@ -292,7 +297,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;
 }
@@ -307,7 +312,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 d68094ffb70a..9f1ef87333ae 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  Fri Dec 13 06:07:35 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:35 +0300
Subject: [PATCH v11 02/22] crypto: amlogic - Add platform data
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-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   | 22 +++++++++++++++++----
 drivers/crypto/amlogic/amlogic-gxl.h        | 11 +++++++++++
 3 files changed, 30 insertions(+), 5 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 dc35d7304eb0..d7e455f73c04 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;
@@ -254,6 +256,10 @@ static int meson_crypto_probe(struct platform_device *pdev)
 	if (!mc)
 		return -ENOMEM;
 
+	mc->pdata = of_device_get_match_data(&pdev->dev);
+	if (!mc->pdata)
+		return -EINVAL;
+
 	mc->dev = &pdev->dev;
 	platform_set_drvdata(pdev, mc);
 
@@ -317,9 +323,17 @@ static void meson_crypto_remove(struct platform_device *pdev)
 	clk_disable_unprepare(mc->busclk);
 }
 
+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", },
-	{}
+	{
+		.compatible = "amlogic,gxl-crypto",
+		.data = &meson_gxl_pdata,
+	},
+	{},
 };
 MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
 
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 9f1ef87333ae..e0bc5c39bf2c 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  Fri Dec 13 06:07:36 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:36 +0300
Subject: [PATCH v11 03/22] crypto: amlogic - Remove clock input
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-4-avromanov@salutedevices.com>

Amlogic crypto IP, which uses DMA crypto engine,
doesn't take a clock input.

Fixes: 48fe583fe541 ("crypto: amlogic - Add crypto accelerator for amlogic GXL")
Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-core.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index d7e455f73c04..90b539401b71 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -9,7 +9,6 @@
 
 #include <crypto/engine.h>
 #include <crypto/internal/skcipher.h>
-#include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
@@ -267,19 +266,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
 	if (IS_ERR(mc->base))
 		return PTR_ERR(mc->base);
 
-	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;
-	}
-
 	err = meson_allocate_chanlist(mc);
 	if (err)
 		goto error_flow;
@@ -304,7 +290,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;
 }
 
@@ -319,8 +304,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 const struct meson_pdata meson_gxl_pdata = {
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:41 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:41 +0300
Subject: [PATCH v11 08/22] crypto: amlogic - Cleanup defines
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-9-avromanov@salutedevices.com>

It is bad to use hardcoded values directly in the code.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 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 f0ccd28545aa..8f20903842ec 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 GENMASK(16, 0)
+
 #define DESC_LAST BIT(18)
 #define DESC_ENCRYPTION BIT(28)
 #define DESC_OWN BIT(31)
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:33 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:33 +0300
Subject: [PATCH v11 00/22] Support more Amlogic SoC families in crypto driver
Message-ID: <20241213140755.1298323-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 GXL, 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.

Changes V4 -> V5 [5]:

- Tested on GXL board:
  1. Fix panic detected by Corentin Labbe [6].
  2. Disable hasher backend for GXL: in its current realization
     is doesn't work. And there are no examples or docs in the
     vendor SDK.
- Fix AES-CTR realization: legacy boards (gxl, g12, axg) requires
  inversion of the keyiv at keys setup stage.
- A1 now uses its own compatible string.
- S4 uses A1 compatible as fallback.
- Code fixes based on comments Neil Atrmstrong and Rob Herring.
- Style fixes (set correct indentations)

Changes V5 -> V6 [7]:

- Fix DMA sync warning reported by Corentin Labbe [8].
- Remove CLK input from driver. Remove clk definition
  and second interrput line from crypto node inside GXL dtsi.

Changes V6 -> V7 [9]:

- Fix dt-schema: power domain now required only for A1.
- Use crypto_skcipher_ctx_dma() helper for cipher instead of
  ____cacheline_aligned.
- Add import/export functions for hasher.
- Fix commit message for patch 17, acorrding to discussion [10].

Changes V7 -> V8 [11]:

- Test patchset with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS: fix some bugs
  in hasher logic.
- Use crypto crypto_ahash_ctx_dma in hasher code.
- Correct clock definition: clk81 is required for all SoC's.
- Add fixed-clock (clk81) definition for A1/S4.
- Add information (in commit messages) why different compatibles are used.

Changes V8 -> V9 [12]:

- Remove required field clk-names from dt-schema according to Rob Herring
recommendation [13].
- Fix commit order: all dt-bindings schema commits now located earlier
than any changes in device tree.
- Fix typos and add more clarifications in dt-schema patches.

Changes V9 -> V10 [14]:

- Rebased over linux-next (20241106).
- Remove patches with AES-CTR support. This was a dishonest implementation of CTR algo.
- Update commit headers in accordance with the accepted rules in each
  of the subsystems.
- Moved adding power-domains (dt-bindings) in desired commit.

Changes V10 -> V11 [15]:

- Rebased over linux-next (20241213).
- Fix unused variable warnings reported by kernel test robot [16].
- Fix dts warnings reported by kernel test robot [17].
- Add Rob Herring RvB tags for dt-bindings patches.
- Remove ____cacheline_aligned macro. Use crypto_ahash/tfm_ctx_dma(),
  crypto_ahash_set_reqsize_dma() and crypto_dma_align() instead.

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/
  - [5] https://lore.kernel.org/all/20240212135108.549755-1-avromanov at salutedevices.com/
  - [6] https://lore.kernel.org/all/ZcsYaPIUrBSg8iXu at Red/
  - [7] https://lore.kernel.org/all/20240301132936.621238-1-avromanov at salutedevices.com/
  - [8] https://lore.kernel.org/all/Zf1BAlYtiwPOG-Os at Red/
  - [9] https://lore.kernel.org/all/20240326153219.2915080-1-avromanov at salutedevices.com/
  - [10] https://lore.kernel.org/all/20240329-dotted-illusive-9f0593805a05 at wendy/
  - [11] https://lore.kernel.org/all/20240411133832.2896463-1-avromanov at salutedevices.com/
  - [12] https://lore.kernel.org/all/20240607141242.2616580-1-avromanov at salutedevices.com/
  - [13] https://lore.kernel.org/all/20240610222827.GA3166929-robh at kernel.org/
  - [14] https://lore.kernel.org/all/20240820145623.3500864-1-avromanov at salutedevices.com/
  - [15] https://lore.kernel.org/all/20241108102907.1788584-1-avromanov at salutedevices.com/
  - [16] https://lore.kernel.org/all/202411090235.a7vEgZQo-lkp at intel.com/
  - [17] https://lore.kernel.org/all/202411090619.fQTDHg7w-lkp at intel.com/

Alexey Romanov (22):
  crypto: amlogic - Don't hardcode IRQ count
  crypto: amlogic - Add platform data
  crypto: amlogic - Remove clock input
  crypto: amlogic - Add MMIO helpers
  crypto: amlogic - Move get_engine_number()
  crypto: amlogic - Drop status field from meson_flow
  crypto: amlogic - Move algs definition and cipher API to cipher.c
  crypto: amlogic - Cleanup defines
  crypto: amlogic - Process more than MAXDESCS descriptors
  crypto: amlogic - Avoid kzalloc in engine thread
  crypto: amlogic - Introduce hasher
  crypto: amlogic - Use fallback for 192-bit keys
  crypto: amlogic - Add support for G12-series
  crypto: amlogic - Add support for AXG-series
  crypto: amlogic - Add support for A1-series
  dt-bindings: crypto: amlogic,gxl-crypto: correct clk and interrupt
    lines
  dt-bindings: crypto: amlogic,gxl-crypto: support new SoC's
  arm64: dts: amlogic: gxl: correct crypto node definition
  arm64: dts: amlogic: a1: add crypto node
  arm64: dts: amlogic: s4: add crypto node
  arm64: dts: amlogic: g12: add crypto node
  arm64: dts: amlogic: axg: add crypto node

 .../bindings/crypto/amlogic,gxl-crypto.yaml   |  32 +-
 arch/arm64/boot/dts/amlogic/meson-a1.dtsi     |  14 +
 arch/arm64/boot/dts/amlogic/meson-axg.dtsi    |   7 +
 .../boot/dts/amlogic/meson-g12-common.dtsi    |   7 +
 arch/arm64/boot/dts/amlogic/meson-gxl.dtsi    |   6 +-
 arch/arm64/boot/dts/amlogic/meson-s4.dtsi     |  13 +
 drivers/crypto/amlogic/Makefile               |   2 +-
 drivers/crypto/amlogic/amlogic-gxl-cipher.c   | 587 ++++++++++++------
 drivers/crypto/amlogic/amlogic-gxl-core.c     | 289 +++++----
 drivers/crypto/amlogic/amlogic-gxl-hasher.c   | 509 +++++++++++++++
 drivers/crypto/amlogic/amlogic-gxl.h          | 111 +++-
 11 files changed, 1215 insertions(+), 362 deletions(-)
 create mode 100644 drivers/crypto/amlogic/amlogic-gxl-hasher.c

-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:44 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:44 +0300
Subject: [PATCH v11 11/22] crypto: amlogic - Introduce hasher
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-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   |  25 +-
 drivers/crypto/amlogic/amlogic-gxl-hasher.c | 509 ++++++++++++++++++++
 drivers/crypto/amlogic/amlogic-gxl.h        |  48 ++
 4 files changed, 582 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 c1c445239549..706db22b9f65 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -19,6 +19,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;
 		}
 	}
 
@@ -190,6 +202,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;
 		}
 	}
 }
@@ -227,13 +242,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;
@@ -256,6 +278,7 @@ static const struct meson_pdata meson_gxl_pdata = {
 	.descs_reg = 0x0,
 	.status_reg = 0x4,
 	.setup_desc_cnt = 3,
+	.hasher_supported = false,
 };
 
 static const struct of_device_id meson_crypto_of_match_table[] = {
diff --git a/drivers/crypto/amlogic/amlogic-gxl-hasher.c b/drivers/crypto/amlogic/amlogic-gxl-hasher.c
new file mode 100644
index 000000000000..e08fc09f0273
--- /dev/null
+++ b/drivers/crypto/amlogic/amlogic-gxl-hasher.c
@@ -0,0 +1,509 @@
+// 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_dma(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_dma(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_dma(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_sha_digest(struct ahash_request *req)
+{
+	struct crypto_wait wait;
+	int ret;
+
+	crypto_init_wait(&wait);
+	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
+					CRYPTO_TFM_REQ_MAY_BACKLOG,
+					crypto_req_done, &wait);
+
+	meson_sha_init(req);
+
+	ret = crypto_wait_req(meson_sha_update(req), &wait);
+	if (ret)
+		return ret;
+
+	return crypto_wait_req(meson_sha_final(req), &wait);
+}
+
+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_dma(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_dma(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_dma(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_dma(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_dma(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_dma(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_dma(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 = rctx->final_req ? 0 : 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_export(struct ahash_request *req, void *out)
+{
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+
+	memcpy(out, rctx, sizeof(*rctx));
+	return 0;
+}
+
+static int meson_hasher_import(struct ahash_request *req, const void *in)
+{
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+
+	memcpy(rctx, in, sizeof(*rctx));
+	return 0;
+}
+
+static int meson_hasher_init(struct crypto_tfm *tfm)
+{
+	struct meson_hasher_tfm_ctx *tctx = crypto_tfm_ctx_dma(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_dma(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_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,
+		.digest = meson_sha_digest,
+		.export = meson_hasher_export,
+		.import = meson_hasher_import,
+	},
+	.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_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,
+		.digest = meson_sha_digest,
+		.export = meson_hasher_export,
+		.import = meson_hasher_import,
+	},
+	.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_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,
+		.digest = meson_sha_digest,
+		.export = meson_hasher_export,
+		.import = meson_hasher_import,
+	},
+	.alg.ahash.op = {
+		.do_one_request = meson_hasher_do_one_request,
+	},
+},
+};
+
+int meson_hasher_register(struct meson_dev *mc)
+{
+	int i;
+
+	if (!mc->pdata->hasher_supported) {
+		pr_info("amlogic-gxl-hasher: hasher not supported at current platform");
+		return 0;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
+		struct hash_alg_common *alg = &mc_algs[i].alg.ahash.base.halg;
+
+		alg->base.cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx) + crypto_dma_padding();
+	}
+
+	return meson_register_algs(mc, mc_algs, ARRAY_SIZE(mc_algs));
+}
+
+void meson_hasher_unregister(struct meson_dev *mc)
+{
+	if (!mc->pdata->hasher_supported)
+		return;
+
+	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 aca0bbb9badc..409141851cae 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,22 @@
 
 #define DESC_OPMODE_ECB (0 << 26)
 #define DESC_OPMODE_CBC (1 << 26)
+#define DESC_OPMODE_SHA (0 << 26)
 
 #define DESC_MAXLEN GENMASK(16, 0)
 
+#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)
+
 /*
  * struct meson_desc - Descriptor for DMA operations
  * Note that without datasheet, some are unknown
@@ -83,11 +93,13 @@ struct meson_flow {
  * @reg_descs:	offset to descriptors register
  * @reg_status:	offset to status register
  * @setup_desc_cnt:	number of setup descriptor to configure.
+ * @hasher_supported:	indecates whether hasher is supported.
  */
 struct meson_pdata {
 	u32 descs_reg;
 	u32 status_reg;
 	u32 setup_desc_cnt;
+	bool hasher_supported;
 };
 
 /*
@@ -141,6 +153,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];
+	u8 partial[SHA256_BLOCK_SIZE];
+	unsigned int partial_size;
+	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
@@ -155,6 +199,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
@@ -176,3 +221,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  Fri Dec 13 06:07:42 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:42 +0300
Subject: [PATCH v11 09/22] crypto: amlogic - Process more than MAXDESCS descriptors
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-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 | 446 ++++++++++++--------
 drivers/crypto/amlogic/amlogic-gxl-core.c   |   1 +
 drivers/crypto/amlogic/amlogic-gxl.h        |   2 +
 3 files changed, 284 insertions(+), 165 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index c662c4b86e97..cb6b959bb1f9 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,184 +82,294 @@ static int meson_cipher_do_fallback(struct skcipher_request *areq)
 	return err;
 }
 
-static int meson_cipher(struct skcipher_request *areq)
+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)
 {
-	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
-	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
-	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(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);
-
-	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u flow=%d\n", __func__,
-		crypto_tfm_alg_name(areq->base.tfm),
-		areq->cryptlen,
-		rctx->op_dir, crypto_skcipher_ivsize(tfm),
-		op->keylen, flow);
-
-#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
-	algt->stat_req++;
-	mc->chanlist[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)
-		return -ENOMEM;
-
-	memcpy(bkeyiv, op->key, op->keylen);
-	keyivlen = op->keylen;
-
-	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,
-				  DMA_TO_DEVICE);
-	err = dma_mapping_error(mc->dev, phykeyiv);
-	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;
+			return -EINVAL;
 		}
-		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) {
+		if (!nr_sgs) {
 			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
-			err = -EINVAL;
-			goto theend;
+			return -EINVAL;
 		}
+
 		nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
 				    DMA_FROM_DEVICE);
-		if (!nr_sgd || nr_sgd > MAXDESC - 3) {
+		if (!nr_sgd) {
+			dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
 			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
-			err = -EINVAL;
-			goto theend;
+			return -EINVAL;
 		}
 	}
 
-	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);
+	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);
 	}
+}
 
-	reinit_completion(&mc->chanlist[flow].complete);
-	meson_dma_start(mc, flow);
+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);
+		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++;
+	}
+}
 
-	err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
+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;
+	struct scatterlist *sg_head;
+	void *new_iv;
+	int err;
+
+	if (blockmode == DESC_OPMODE_CBC) {
+		struct scatterlist *sg_current;
+		unsigned int offset;
+
+		if (rctx->op_dir == MESON_ENCRYPT) {
+			sg_current = ctx->dst_sg;
+			sg_head = ctx->areq->dst;
+			offset = ctx->dst_offset;
+			new_iv_dir = DMA_FROM_DEVICE;
+		} else {
+			sg_current = ctx->src_sg;
+			sg_head = ctx->areq->src;
+			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_current) + offset;
+	}
+
+	if (blockmode == DESC_OPMODE_CBC &&
+	    rctx->op_dir == MESON_DECRYPT) {
+		dma_sync_sg_for_cpu(mc->dev, sg_head,
+				    sg_nents(sg_head), 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", flow);
-		err = -EINVAL;
+		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);
-	} else {
-		/* No error */
-		err = 0;
+		return err;
 	}
 
-	dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
+	if (blockmode == DESC_OPMODE_CBC &&
+	    rctx->op_dir == MESON_ENCRYPT) {
+		dma_sync_sg_for_cpu(mc->dev, sg_head,
+				    sg_nents(sg_head), new_iv_dir);
+		memcpy(ctx->areq->iv, new_iv, ivsize);
+	}
 
-	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);
+	ctx->tloffset = 0;
+
+	return 0;
+}
+
+static int meson_cipher(struct skcipher_request *areq)
+{
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
+	struct meson_dev *mc = op->mc;
+	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+	struct meson_alg_template *algt;
+	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 ctx.flow=%d\n", __func__,
+		crypto_tfm_alg_name(areq->base.tfm),
+		areq->cryptlen,
+		rctx->op_dir, crypto_skcipher_ivsize(tfm),
+		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[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,
+					DMA_TO_DEVICE);
+	err = dma_mapping_error(mc->dev, ctx.keyiv.addr);
+	if (err) {
+		dev_err(mc->dev, "Cannot DMA MAP KEY IV\n");
+		goto free_keyiv;
 	}
 
-	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);
+	err = meson_map_scatterlist(areq, mc);
+	if (err)
+		goto unmap_keyiv;
+
+	ctx.tloffset = 0;
+
+	while (ctx.cryptlen) {
+		meson_setup_keyiv_descs(&ctx);
+
+		if (meson_setup_data_descs(&ctx)) {
+			err = meson_kick_hardware(&ctx);
+			if (err)
+				break;
+		}
+
+		if (ctx.src_offset == sg_dma_len(ctx.src_sg)) {
+			ctx.src_offset = 0;
+			ctx.src_sg = sg_next(ctx.src_sg);
+		}
+
+		if (ctx.dst_offset == sg_dma_len(ctx.dst_sg)) {
+			ctx.dst_offset = 0;
+			ctx.dst_sg = sg_next(ctx.dst_sg);
 		}
 	}
-theend:
-	kfree_sensitive(bkeyiv);
-	kfree_sensitive(backup_iv);
+
+	meson_unmap_scatterlist(areq, mc);
+
+unmap_keyiv:
+	dma_unmap_single(mc->dev, ctx.keyiv.addr, ctx.keyiv.len, DMA_TO_DEVICE);
+
+free_keyiv:
+	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 106d4ee2e5e9..c1c445239549 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -255,6 +255,7 @@ static void meson_crypto_remove(struct platform_device *pdev)
 static const struct meson_pdata meson_gxl_pdata = {
 	.descs_reg = 0x0,
 	.status_reg = 0x4,
+	.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 8f20903842ec..9fbe5ab44877 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
+ * @setup_desc_cnt:	number of setup descriptor to configure.
  */
 struct meson_pdata {
 	u32 descs_reg;
 	u32 status_reg;
+	u32 setup_desc_cnt;
 };
 
 /*
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:45 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:45 +0300
Subject: [PATCH v11 12/22] crypto: amlogic - Use fallback for 192-bit keys
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-13-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 df42940f1112..6070ee6b488e 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_dma(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 706db22b9f65..0f4b3db85031 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -279,6 +279,7 @@ static const struct meson_pdata meson_gxl_pdata = {
 	.status_reg = 0x4,
 	.setup_desc_cnt = 3,
 	.hasher_supported = false,
+	.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 409141851cae..9c74f70df068 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -94,12 +94,14 @@ struct meson_flow {
  * @reg_status:	offset to status register
  * @setup_desc_cnt:	number of setup descriptor to configure.
  * @hasher_supported:	indecates whether hasher is supported.
+ * @support_192bit_key:	indicates whether platform support AES 192-bit key
  */
 struct meson_pdata {
 	u32 descs_reg;
 	u32 status_reg;
 	u32 setup_desc_cnt;
 	bool hasher_supported;
+	bool support_192bit_key;
 };
 
 /*
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:43 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:43 +0300
Subject: [PATCH v11 10/22] crypto: amlogic - Avoid kzalloc in engine thread
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-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>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 60 ++++++++++-----------
 drivers/crypto/amlogic/amlogic-gxl.h        |  4 +-
 2 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index cb6b959bb1f9..df42940f1112 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -59,7 +59,7 @@ static bool meson_cipher_need_fallback(struct skcipher_request *areq)
 static int meson_cipher_do_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_cipher_tfm_ctx *op = crypto_skcipher_ctx_dma(tfm);
 	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
 	int err;
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
@@ -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;
@@ -147,7 +146,7 @@ static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
 	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_cipher_tfm_ctx *op = crypto_skcipher_ctx_dma(tfm);
 	struct meson_dev *mc = op->mc;
 	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
 	unsigned int blockmode = algt->blockmode;
@@ -157,7 +156,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);
+		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);
 	}
@@ -179,7 +178,7 @@ 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 meson_cipher_tfm_ctx *op = crypto_skcipher_ctx_dma(tfm);
 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
 	struct meson_alg_template *algt = container_of(alg,
 						       struct meson_alg_template,
@@ -222,7 +221,7 @@ 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 meson_cipher_tfm_ctx *op = crypto_skcipher_ctx_dma(tfm);
 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
 	struct meson_alg_template *algt = container_of(alg,
 						       struct meson_alg_template,
@@ -292,7 +291,7 @@ static int meson_kick_hardware(struct cipher_ctx *ctx)
 static int meson_cipher(struct skcipher_request *areq)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
-	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx_dma(tfm);
 	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
 	struct meson_dev *mc = op->mc;
 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
@@ -305,6 +304,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__,
@@ -320,21 +320,21 @@ 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) {
 		dev_err(mc->dev, "Cannot DMA MAP KEY IV\n");
-		goto free_keyiv;
+		return err;
 	}
 
 	err = meson_map_scatterlist(areq, mc);
@@ -368,9 +368,6 @@ static int meson_cipher(struct skcipher_request *areq)
 unmap_keyiv:
 	dma_unmap_single(mc->dev, ctx.keyiv.addr, ctx.keyiv.len, DMA_TO_DEVICE);
 
-free_keyiv:
-	kfree_sensitive(ctx.bkeyiv);
-
 	return err;
 }
 
@@ -390,7 +387,7 @@ int meson_handle_cipher_request(struct crypto_engine *engine, void *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);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx_dma(tfm);
 	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
 	struct crypto_engine *engine;
 	int e;
@@ -408,7 +405,7 @@ static int meson_skdecrypt(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);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx_dma(tfm);
 	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
 	struct crypto_engine *engine;
 	int e;
@@ -425,7 +422,7 @@ static int meson_skencrypt(struct skcipher_request *areq)
 
 static int meson_cipher_init(struct crypto_tfm *tfm)
 {
-	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
+	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx_dma(tfm);
 	struct meson_alg_template *algt;
 	const char *name = crypto_tfm_alg_name(tfm);
 	struct crypto_skcipher *sktfm = __crypto_skcipher_cast(tfm);
@@ -443,7 +440,7 @@ static int meson_cipher_init(struct crypto_tfm *tfm)
 		return PTR_ERR(op->fallback_tfm);
 	}
 
-	crypto_skcipher_set_reqsize(sktfm, sizeof(struct meson_cipher_req_ctx) +
+	crypto_skcipher_set_reqsize_dma(sktfm, sizeof(struct meson_cipher_req_ctx) +
 				    crypto_skcipher_reqsize(op->fallback_tfm));
 
 	return 0;
@@ -451,16 +448,15 @@ static int meson_cipher_init(struct crypto_tfm *tfm)
 
 static void meson_cipher_exit(struct crypto_tfm *tfm)
 {
-	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
+	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx_dma(tfm);
 
-	kfree_sensitive(op->key);
 	crypto_free_skcipher(op->fallback_tfm);
 }
 
 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_cipher_tfm_ctx *op = crypto_skcipher_ctx_dma(tfm);
 	struct meson_dev *mc = op->mc;
 
 	switch (keylen) {
@@ -477,11 +473,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);
 }
@@ -499,7 +493,6 @@ static struct meson_alg_template algs[] = {
 			.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,
@@ -528,7 +521,6 @@ static struct meson_alg_template algs[] = {
 			.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,
@@ -548,6 +540,14 @@ static struct meson_alg_template algs[] = {
 
 int meson_cipher_register(struct meson_dev *mc)
 {
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(algs); i++) {
+		struct skcipher_alg *alg = &algs[i].alg.skcipher.base;
+
+		alg->base.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx) + crypto_dma_padding();
+	}
+
 	return meson_register_algs(mc, algs, ARRAY_SIZE(algs));
 }
 
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 9fbe5ab44877..aca0bbb9badc 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -127,14 +127,14 @@ 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;
+	u8 keyiv[AES_MAX_KEY_SIZE + AES_BLOCK_SIZE];
 	u32 keylen;
 	u32 keymode;
 	struct meson_dev *mc;
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:46 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:46 +0300
Subject: [PATCH v11 13/22] crypto: amlogic - Add support for G12-series
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-14-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 0f4b3db85031..6529ae24b75f 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -282,11 +282,23 @@ 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,
+	.setup_desc_cnt = 1,
+	.hasher_supported = true,
+	.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,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:48 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:48 +0300
Subject: [PATCH v11 15/22] crypto: amlogic - Add support for A1-series
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-16-avromanov@salutedevices.com>

This platform data also can be used for 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 | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 9452f05d2f10..55a35697c0d7 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -298,6 +298,14 @@ static const struct meson_pdata meson_axg_pdata = {
 	.support_192bit_key = true,
 };
 
+static const struct meson_pdata meson_a1_pdata = {
+	.descs_reg = 0x0,
+	.status_reg = 0x8,
+	.setup_desc_cnt = 1,
+	.hasher_supported = true,
+	.support_192bit_key = false,
+};
+
 static const struct of_device_id meson_crypto_of_match_table[] = {
 	{
 		.compatible = "amlogic,gxl-crypto",
@@ -311,6 +319,14 @@ static const struct of_device_id meson_crypto_of_match_table[] = {
 		.compatible = "amlogic,axg-crypto",
 		.data = &meson_axg_pdata,
 	},
+	{
+		.compatible = "amlogic,a1-crypto",
+		.data = &meson_a1_pdata,
+	},
+	{
+		.compatible = "amlogic,s4-crypto",
+		.data = &meson_a1_pdata,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:47 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:47 +0300
Subject: [PATCH v11 14/22] crypto: amlogic - Add support for AXG-series
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-15-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 6529ae24b75f..9452f05d2f10 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -290,6 +290,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,
+	.setup_desc_cnt = 3,
+	.hasher_supported = true,
+	.support_192bit_key = true,
+};
+
 static const struct of_device_id meson_crypto_of_match_table[] = {
 	{
 		.compatible = "amlogic,gxl-crypto",
@@ -299,6 +307,10 @@ static const struct of_device_id meson_crypto_of_match_table[] = {
 		.compatible = "amlogic,g12a-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  Fri Dec 13 06:07:49 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:49 +0300
Subject: [PATCH v11 16/22] dt-bindings: crypto: amlogic,gxl-crypto: correct clk and interrupt lines
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-17-avromanov@salutedevices.com>

GXL and newer SoC's uses the DMA engine (not blkmv) for crypto HW.
Crypto HW doesn't actually use the blkmv clk. At RTL level, crypto
engine is hard-wired to a clk81 (CLKID_CLK81). Drop clock-names
field from schema: name "blkmv" is invalid and "clk81" is confusing
and sounds like something global.

Also, GXL crypto IP isn't connected to the second interrupt line.
This binding is useless, there are no users of this line.
We must remove it from dt-bindings.

Fixes: 7f7d115dfb51 ("dt-bindings: crypto: Add DT bindings documentation for amlogic-crypto")
Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
 .../devicetree/bindings/crypto/amlogic,gxl-crypto.yaml | 10 ++--------
 1 file changed, 2 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..fdc39797a2a9 100644
--- a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
+++ b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
@@ -20,20 +20,15 @@ properties:
   interrupts:
     items:
       - description: Interrupt for flow 0
-      - description: Interrupt for flow 1
 
   clocks:
     maxItems: 1
 
-  clock-names:
-    const: blkmv
-
 required:
   - compatible
   - reg
   - interrupts
   - clocks
-  - clock-names
 
 additionalProperties: false
 
@@ -46,7 +41,6 @@ examples:
     crypto: crypto-engine at c883e000 {
         compatible = "amlogic,gxl-crypto";
         reg = <0xc883e000 0x36>;
-        interrupts = <GIC_SPI 188 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 189 IRQ_TYPE_EDGE_RISING>;
-        clocks = <&clkc CLKID_BLKMV>;
-        clock-names = "blkmv";
+        interrupts = <GIC_SPI 188 IRQ_TYPE_EDGE_RISING>;
+        clocks = <&clkc CLKID_CLK81>;
     };
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:50 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:50 +0300
Subject: [PATCH v11 17/22] dt-bindings: crypto: amlogic,gxl-crypto: support new SoC's
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-18-avromanov@salutedevices.com>

Now crypto module available at G12A/G12B/S4/A1/SM1/AXG.

1. Add new compatibles:
  - amlogic,g12a-crypto
  - amlogic,axg-crypto
  - amlogic,a1-crypto
  - amlogic,s4-crypto (uses a1-crypto as fallback)

Difference between this compatibles:
 * Different registers offset and the number of setup descriptors.
 * GXL doesn't support hashing like the others.
 * G12A/B and A1/S4 crypto HW don't support 192 AES key.
 * GXL, G12A/B and AXG require a reverse IV key before processing.

2. Add power-domains in schema, which is required only for A1.
This is specific vendor design: in old SoC's power domain for
crypto HW was not configurable, but in A1-series it is configurable.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
 .../bindings/crypto/amlogic,gxl-crypto.yaml   | 24 +++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
index fdc39797a2a9..106a9d1fed69 100644
--- a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
+++ b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
@@ -11,8 +11,16 @@ maintainers:
 
 properties:
   compatible:
-    items:
-      - const: amlogic,gxl-crypto
+    oneOf:
+      - items:
+          - enum:
+              - amlogic,s4-crypto
+          - const: amlogic,a1-crypto
+      - enum:
+          - amlogic,gxl-crypto
+          - amlogic,axg-crypto
+          - amlogic,g12a-crypto
+          - amlogic,a1-crypto
 
   reg:
     maxItems: 1
@@ -24,12 +32,24 @@ properties:
   clocks:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
   - interrupts
   - clocks
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          const: amlogic,a1-crypto
+    then:
+      required:
+        - power-domains
+
 additionalProperties: false
 
 examples:
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:51 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:51 +0300
Subject: [PATCH v11 18/22] arm64: dts: amlogic: gxl: correct crypto node definition
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-19-avromanov@salutedevices.com>

GXL and newer SoC's uses the DMA engine (not blkmv) for crypto HW.
Crypto HW doesn't actually use the blkmv clk. At RTL level, crypto
engine is hard weired to clk81 (CLKID_CLK81). And remove clock-names
field: according to the new dt-binding, it is no longer required.

Also, GXL crypto IP isn't to seconnd interrput line. So we must
remove it from dt-bindings.

Fixes: c4a0457eb858 ("ARM64: dts: amlogic: adds crypto hardware node")
Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index f58d1790de1c..628d30fd5fcb 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -68,10 +68,8 @@ acodec: audio-controller at c8832000 {
 		crypto: crypto at c883e000 {
 			compatible = "amlogic,gxl-crypto";
 			reg = <0x0 0xc883e000 0x0 0x36>;
-			interrupts = <GIC_SPI 188 IRQ_TYPE_EDGE_RISING>,
-				     <GIC_SPI 189 IRQ_TYPE_EDGE_RISING>;
-			clocks = <&clkc CLKID_BLKMV>;
-			clock-names = "blkmv";
+			interrupts = <GIC_SPI 188 IRQ_TYPE_EDGE_RISING>;
+			clocks = <&clkc CLKID_CLK81>;
 			status = "okay";
 		};
 	};
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:52 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:52 +0300
Subject: [PATCH v11 19/22] arm64: dts: amlogic: a1: add crypto node
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-20-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 | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
index 1eba0afb3fd9..7734dd84c8f8 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
@@ -664,6 +664,14 @@ sd_emmc: mmc at 10000 {
 				power-domains = <&pwrc PWRC_SD_EMMC_ID>;
 				status = "disabled";
 			};
+
+			crypto: crypto at 6000 {
+				compatible = "amlogic,a1-crypto";
+				reg = <0x0 0x6000 0x0 0x48>;
+				interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clk81>;
+				power-domains = <&pwrc PWRC_DMA_ID>;
+			};
 		};
 
 		usb: usb at fe004400 {
@@ -745,4 +753,10 @@ xtal: xtal-clk {
 		clock-output-names = "xtal";
 		#clock-cells = <0>;
 	};
+
+	clk81: clk81 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <64000000>;
+	};
 };
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:53 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:53 +0300
Subject: [PATCH v11 20/22] arm64: dts: amlogic: s4: add crypto node
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-21-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 | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
index 957577d986c0..846b9d1481ba 100644
--- a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -66,6 +66,12 @@ xtal: xtal-clk {
 		#clock-cells = <0>;
 	};
 
+	clk81: clk81 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <166000000>;
+	};
+
 	firmware {
 		sm: secure-monitor {
 			compatible = "amlogic,meson-gxbb-sm";
@@ -586,6 +592,13 @@ mux {
 
 			};
 
+			crypto: crypto at 440400 {
+				compatible = "amlogic,s4-crypto", "amlogic,a1-crypto";
+				reg = <0x0 0x440400 0x0 0x48>;
+				interrupts = <GIC_SPI 24 IRQ_TYPE_EDGE_RISING>;
+				clocks = <&clk81>;
+			};
+
 			gpio_intc: interrupt-controller at 4080 {
 				compatible = "amlogic,meson-s4-gpio-intc",
 					     "amlogic,meson-gpio-intc";
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:54 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:54 +0300
Subject: [PATCH v11 21/22] arm64: dts: amlogic: g12: add crypto node
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-22-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 | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 49b51c54013f..97c5c8464948 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1733,6 +1733,13 @@ 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>;
+				clocks = <&clkc CLKID_CLK81>;
+			};
 		};
 
 		aobus: bus at ff800000 {
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:55 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:55 +0300
Subject: [PATCH v11 22/22] arm64: dts: amlogic: axg: add crypto node
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-23-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 | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index e9b22868983d..20a5fff3cda5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -294,6 +294,13 @@ 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>;
+			clocks = <&clkc CLKID_CLK81>;
+		};
+
 		pcie_phy: phy at ff644000 {
 			compatible = "amlogic,axg-pcie-phy";
 			reg = <0x0 0xff644000 0x0 0x1c>;
-- 
2.34.1



From maz at kernel.org  Fri Dec 13 06:10:37 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 13 Dec 2024 14:10:37 +0000
Subject: [PATCH] irqchip/gic-v3: Work around insecure GIC integrations
Message-ID: <20241213141037.3995049-1-maz@kernel.org>

It appears that the relatively popular RK3399 SoC has been put together
using a large amount of illicit substances, as experiments reveal
that its integration of GIC500 exposes the *secure* programming
interface to non-secure.

This has some pretty bad effects on the way priorities are handled,
and results in a dead machine if booting with pseudo-NMI enabled
(irqchip.gicv3_pseudo_nmi=1) if the kernel contains 18fdb6348c480
("arm64: irqchip/gic-v3: Select priorities at boot time"), which
relies on the priorities being programmed using the NS view.

Let's restore some sanity by going one step further and disable
security altogether in this case. This is not any worse, and
puts us in a mode where priorities actually make some sense.

Huge thanks to Mark Kettenis who initially identified this issue
on OpenBSD, and to Chen-Yu Tsai who reported the problem in
Linux.

Fixes: 18fdb6348c480 ("arm64: irqchip/gic-v3: Select priorities at boot time")
Reported-by: Mark Kettenis <mark.kettenis at xs4all.nl>
Reported-by: Chen-Yu Tsai <wenst at chromium.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: stable at vger.kernel.org
---
 drivers/irqchip/irq-gic-v3.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 34db379d066a5..79d8cc80693c3 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -161,7 +161,22 @@ static bool cpus_have_group0 __ro_after_init;
 
 static void __init gic_prio_init(void)
 {
-	cpus_have_security_disabled = gic_dist_security_disabled();
+	bool ds;
+
+	ds = gic_dist_security_disabled();
+	if (!ds) {
+		u32 val;
+
+		val = readl_relaxed(gic_data.dist_base + GICD_CTLR);
+		val |= GICD_CTLR_DS;
+		writel_relaxed(val, gic_data.dist_base + GICD_CTLR);
+
+		ds = gic_dist_security_disabled();
+		if (ds)
+			pr_warn("Broken GIC integration, security disabled");
+	}
+
+	cpus_have_security_disabled = ds;
 	cpus_have_group0 = gic_has_group0();
 
 	/*
-- 
2.39.2



From maz at kernel.org  Fri Dec 13 06:22:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 13 Dec 2024 14:22:03 +0000
Subject: Question about interrupt prioriyt of ARM GICv3/4
In-Reply-To: <871pydxde2.fsf@bloch.sibelius.xs4all.nl>
References: <CAJNi4rMfhZOCT+7Ki14vUs+dZbv9cxCZ0s+jgn6=_om4NTgo_A@mail.gmail.com>
	<86cyi5tanz.wl-maz@kernel.org>
	<CAJNi4rPDVXS3Ft3nHLXvMzHmn9d10Nz4Pxeduoe+v5HaK=CEAg@mail.gmail.com>
	<86ldwlryzz.wl-maz@kernel.org>
	<871pydxde2.fsf@bloch.sibelius.xs4all.nl>
Message-ID: <86frmrslx0.wl-maz@kernel.org>

On Thu, 12 Dec 2024 13:02:45 +0000,
Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
> 
> Based on my experience with OpenBSD, I'm not even sure there is much
> benefit even if you have preemtion.
> 
> And regarding anything wrong happening: there is an interesting bug in
> the RK3399 GIC integration where it gets the priorities wrong:
> 
> https://github.com/openbsd/src/blob/feb3ea439d8f49b3c0e33f54c34631a611b98e21/sys/arch/arm64/dev/agintc.c#L395
> 
> (that comment is my interpretation of what's happening; I might be
> misinterpreting what's really going on)
> 
> As far as I can tell the Linux code doesn't handle that quirk.
> Probably it doesn't matter because Linux only uses the priority
> mechanisms to implement pseudo-NMI functionality and/or doesn't do
> preemption of interrupts.

Ah, beautiful! We actually do preemption with pseudo-NMI, and as it
turns out, I just had a report of 6.11 being broken on that SoC when
pNMIs are enabled.

My "solution" for this is to just disable security at the distributor
level, and let things rip, see [1].

Thanks for the heads up!

	M.

[1] https://lore.kernel.org/r/20241213141037.3995049-1-maz at kernel.org

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


From ciprianmarian.costea at oss.nxp.com  Fri Dec 13 06:22:50 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri, 13 Dec 2024 16:22:50 +0200
Subject: [PATCH v2] arm64: dts: s32g: add I2C support
Message-ID: <20241213142250.2532559-1-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

Add the I2C Devicetree nodes and pinmux for S32G2 and S32G3 SoCs.

With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
(rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
are quite similar. The common part for the EVB revisions will be
centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
be placed in 's32gxxa-rdb.dtsi' file.

This refactor will also serve for other modules in the future, such as
FlexCAN, DSPI.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 arch/arm64/boot/dts/freescale/s32g2.dtsi      |  45 ++++++
 .../arm64/boot/dts/freescale/s32g274a-evb.dts |   1 +
 .../boot/dts/freescale/s32g274a-rdb2.dts      |   1 +
 arch/arm64/boot/dts/freescale/s32g3.dtsi      |  50 ++++++
 .../boot/dts/freescale/s32g399a-rdb3.dts      |   9 ++
 .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
 .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 126 +++++++++++++++
 7 files changed, 382 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi

diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
index 7be430b78c83..0e6c847ab0c3 100644
--- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -333,6 +333,33 @@ uart1: serial at 401cc000 {
 			status = "disabled";
 		};
 
+		i2c0: i2c at 401e4000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x401e4000 0x1000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c1: i2c at 401e8000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x401e8000 0x1000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c2: i2c at 401ec000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x401ec000 0x1000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		uart2: serial at 402bc000 {
 			compatible = "nxp,s32g2-linflexuart",
 				     "fsl,s32v234-linflexuart";
@@ -341,6 +368,24 @@ uart2: serial at 402bc000 {
 			status = "disabled";
 		};
 
+		i2c3: i2c at 402d8000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x402d8000 0x1000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c4: i2c at 402dc000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x402dc000 0x1000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		usdhc0: mmc at 402f0000 {
 			compatible = "nxp,s32g2-usdhc";
 			reg = <0x402f0000 0x1000>;
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
index b9a119eea2b7..c4a195dd67bf 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s32g2.dtsi"
+#include "s32gxxxa-evb.dtsi"
 
 / {
 	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
index aaa61a8ad0da..b5ba51696f43 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s32g2.dtsi"
+#include "s32gxxxa-rdb.dtsi"
 
 / {
 	model = "NXP S32G2 Reference Design Board 2 (S32G-VNP-RDB2)";
diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
index 6c572ffe37ca..666e4029e588 100644
--- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
@@ -390,6 +390,36 @@ uart1: serial at 401cc000 {
 			status = "disabled";
 		};
 
+		i2c0: i2c at 401e4000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x401e4000 0x1000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c1: i2c at 401e8000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x401e8000 0x1000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c2: i2c at 401ec000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x401ec000 0x1000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		uart2: serial at 402bc000 {
 			compatible = "nxp,s32g3-linflexuart",
 				     "fsl,s32v234-linflexuart";
@@ -398,6 +428,26 @@ uart2: serial at 402bc000 {
 			status = "disabled";
 		};
 
+		i2c3: i2c at 402d8000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x402d8000 0x1000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c4: i2c at 402dc000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x402dc000 0x1000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		usdhc0: mmc at 402f0000 {
 			compatible = "nxp,s32g3-usdhc",
 				     "nxp,s32g2-usdhc";
diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
index 828e353455b5..5f8739c068c6 100644
--- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
+++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
@@ -8,6 +8,7 @@
 /dts-v1/;
 
 #include "s32g3.dtsi"
+#include "s32gxxxa-rdb.dtsi"
 
 / {
 	model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
@@ -39,6 +40,14 @@ &uart1 {
 	status = "okay";
 };
 
+&i2c4 {
+	ina231 at 40 {
+		compatible = "ti,ina231";
+		reg = <0x40>;
+		shunt-resistor = <1000>;
+	};
+};
+
 &usdhc0 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz";
 	pinctrl-0 = <&pinctrl_usdhc0>;
diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
new file mode 100644
index 000000000000..a44eff28073a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2024 NXP
+ *
+ * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
+ *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
+ *          Larisa Grigore <larisa.grigore at nxp.com>
+ */
+
+&pinctrl {
+	i2c0_pins: i2c0-pins {
+		i2c0-grp0 {
+			pinmux = <0x101>, <0x111>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-grp1 {
+			pinmux = <0x2352>, <0x2362>;
+		};
+	};
+
+	i2c0_gpio_pins: i2c0-gpio-pins {
+		i2c0-gpio-grp0 {
+			pinmux = <0x100>, <0x110>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-gpio-grp1 {
+			pinmux = <0x2350>, <0x2360>;
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		i2c1-grp0 {
+			pinmux = <0x131>, <0x141>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c1-grp1 {
+			pinmux = <0x2cd2>, <0x2ce2>;
+		};
+	};
+
+	i2c1_gpio_pins: i2c1-gpio-pins {
+		i2c1-gpio-grp0 {
+			pinmux = <0x130>, <0x140>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c1-gpio-grp1 {
+			pinmux = <0x2cd0>, <0x2ce0>;
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		i2c2-grp0 {
+			pinmux = <0x151>, <0x161>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-grp1 {
+			pinmux = <0x2cf2>, <0x2d02>;
+		};
+	};
+
+	i2c2_gpio_pins: i2c2-gpio-pins {
+		i2c2-gpio-grp0 {
+			pinmux = <0x150>, <0x160>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-gpio-grp1 {
+			pinmux = <0x2cf0>, <0x2d00>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		i2c4-grp0 {
+			pinmux = <0x211>, <0x222>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-grp1 {
+			pinmux = <0x2d43>, <0x2d33>;
+		};
+	};
+
+	i2c4_gpio_pins: i2c4-gpio-pins {
+		i2c4-gpio-grp0 {
+			pinmux = <0x210>, <0x220>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-gpio-grp1 {
+			pinmux = <0x2d40>, <0x2d30>;
+		};
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-1 = <&i2c0_gpio_pins>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c1_pins>;
+	pinctrl-1 = <&i2c1_gpio_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_gpio_pins>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-1 = <&i2c4_gpio_pins>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
new file mode 100644
index 000000000000..50fe6aaa1605
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2024 NXP
+ *
+ * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
+ *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
+ *          Larisa Grigore <larisa.grigore at nxp.com>
+ */
+
+&pinctrl {
+	i2c0_pins: i2c0-pins {
+		i2c0-grp0 {
+			pinmux = <0x1f2>, <0x201>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-grp1 {
+			pinmux = <0x2353>, <0x2363>;
+		};
+	};
+
+	i2c0_gpio_pins: i2c0-gpio-pins {
+		i2c0-gpio-grp0 {
+			pinmux = <0x1f0>, <0x200>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-gpio-grp1 {
+			pinmux = <0x2350>, <0x2360>;
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		i2c2-grp0 {
+			pinmux = <0x151>, <0x161>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-grp1 {
+			pinmux = <0x2cf2>, <0x2d02>;
+		};
+	};
+
+	i2c2_gpio_pins: i2c2-gpio-pins {
+		i2c2-gpio-grp0 {
+			pinmux = <0x2cf0>, <0x2d00>;
+		};
+
+		i2c2-gpio-grp1 {
+			pinmux = <0x150>, <0x160>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		i2c4-grp0 {
+			pinmux = <0x211>, <0x222>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-grp1 {
+			pinmux = <0x2d43>, <0x2d33>;
+		};
+	};
+
+	i2c4_gpio_pins: i2c4-gpio-pins {
+		i2c4-gpio-grp0 {
+			pinmux = <0x210>, <0x220>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-gpio-grp1 {
+			pinmux = <0x2d40>, <0x2d30>;
+		};
+	};
+};
+
+&i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-1 = <&i2c0_gpio_pins>;
+	status = "okay";
+
+	pcal6524: gpio-expander at 22 {
+		compatible = "nxp,pcal6524";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_gpio_pins>;
+	status = "okay";
+};
+
+&i2c4 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-1 = <&i2c4_gpio_pins>;
+	status = "okay";
+};
-- 
2.45.2



From avromanov at salutedevices.com  Fri Dec 13 06:07:37 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:37 +0300
Subject: [PATCH v11 04/22] crypto: amlogic - Add MMIO helpers
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-5-avromanov@salutedevices.com>

Add MMIO access helpers: meson_dma_start() and meson_dma_ready().

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 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 90b539401b71..e617dddf5e2b 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -22,18 +22,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 e0bc5c39bf2c..0ccf6542995f 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -161,6 +161,8 @@ struct meson_alg_template {
 #endif
 };
 
+void meson_dma_start(struct meson_dev *mc, int flow);
+
 int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 		     unsigned int keylen);
 int meson_cipher_init(struct crypto_tfm *tfm);
-- 
2.34.1



From avromanov at salutedevices.com  Fri Dec 13 06:07:38 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Fri, 13 Dec 2024 17:07:38 +0300
Subject: [PATCH v11 05/22] crypto: amlogic - Move get_engine_number()
In-Reply-To: <20241213140755.1298323-1-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
Message-ID: <20241213140755.1298323-6-avromanov@salutedevices.com>

Move get_engine_number() function from cipher.c to core.c

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 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 e617dddf5e2b..44e71e917e5e 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -22,6 +22,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 0ccf6542995f..cb70277c3a31 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -161,6 +161,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_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
-- 
2.34.1



From jbrunet at baylibre.com  Fri Dec 13 06:30:17 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 13 Dec 2024 15:30:17 +0100
Subject: [PATCH] clk: amlogic: g12b: fix cluster A parent data
Message-ID: <20241213-amlogic-clk-g12a-cpua-parent-fix-v1-1-d8c0f41865fe@baylibre.com>

Several clocks used by both g12a and g12b use the g12a cpu A clock hw
pointer as clock parent. This is incorrect on g12b since the parents of
cluster A cpu clock are different. Also the hw clock provided as parent to
these children is not even registered clock on g12b.

Fix the problem by reverting to the global namespace and let CCF pick
the appropriate, as it is already done for other clocks, such as
cpu_clk_trace_div.

Fixes: 25e682a02d91 ("clk: meson: g12a: migrate to the new parent description method")
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/clk/meson/g12a.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index 20be7b037c07535bd2115f6e70404a95a7832756..4e6584377e43fa7c9956017ddfcd3f295fafd686 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -1137,8 +1137,18 @@ static struct clk_regmap g12a_cpu_clk_div16_en = {
 	.hw.init = &(struct clk_init_data) {
 		.name = "cpu_clk_div16_en",
 		.ops = &clk_regmap_gate_ro_ops,
-		.parent_hws = (const struct clk_hw *[]) {
-			&g12a_cpu_clk.hw
+		.parent_data = &(const struct clk_parent_data) {
+			/*
+			 * Note:
+			 * G12A and G12B have different cpu clocks (with
+			 * different struct clk_hw). We fallback to the global
+			 * naming string mechanism so this clock picks
+			 * up the appropriate one. Same goes for the other
+			 * clock using cpu cluster A clock output and present
+			 * on both G12 variant.
+			 */
+			.name = "cpu_clk",
+			.index = -1,
 		},
 		.num_parents = 1,
 		/*
@@ -1203,7 +1213,10 @@ static struct clk_regmap g12a_cpu_clk_apb_div = {
 	.hw.init = &(struct clk_init_data){
 		.name = "cpu_clk_apb_div",
 		.ops = &clk_regmap_divider_ro_ops,
-		.parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			.name = "cpu_clk",
+			.index = -1,
+		},
 		.num_parents = 1,
 	},
 };
@@ -1237,7 +1250,10 @@ static struct clk_regmap g12a_cpu_clk_atb_div = {
 	.hw.init = &(struct clk_init_data){
 		.name = "cpu_clk_atb_div",
 		.ops = &clk_regmap_divider_ro_ops,
-		.parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			.name = "cpu_clk",
+			.index = -1,
+		},
 		.num_parents = 1,
 	},
 };
@@ -1271,7 +1287,10 @@ static struct clk_regmap g12a_cpu_clk_axi_div = {
 	.hw.init = &(struct clk_init_data){
 		.name = "cpu_clk_axi_div",
 		.ops = &clk_regmap_divider_ro_ops,
-		.parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			.name = "cpu_clk",
+			.index = -1,
+		},
 		.num_parents = 1,
 	},
 };
@@ -1306,13 +1325,6 @@ static struct clk_regmap g12a_cpu_clk_trace_div = {
 		.name = "cpu_clk_trace_div",
 		.ops = &clk_regmap_divider_ro_ops,
 		.parent_data = &(const struct clk_parent_data) {
-			/*
-			 * Note:
-			 * G12A and G12B have different cpu_clks (with
-			 * different struct clk_hw). We fallback to the global
-			 * naming string mechanism so cpu_clk_trace_div picks
-			 * up the appropriate one.
-			 */
 			.name = "cpu_clk",
 			.index = -1,
 		},

---
base-commit: 799ce46951dcc75682223cdab12fdc905f2fe735
change-id: 20241213-amlogic-clk-g12a-cpua-parent-fix-64362495fc9b

Best regards,
-- 
Jerome



From ninad at linux.ibm.com  Fri Dec 13 06:50:30 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 08:50:30 -0600
Subject: [PATCH v1 4/8] ARM: dts: aspeed: system1: Reduce sgpio speed
In-Reply-To: <20241213145037.3784931-1-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
Message-ID: <20241213145037.3784931-5-ninad@linux.ibm.com>

From: NINAD PALSULE <ninadpalsule at us.ibm.com>

Reduce sgpio speed to improve stability with the current PCB layout.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index 775a95470f5c..ebbb14241256 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -401,7 +401,7 @@ &emmc {
 &sgpiom0 {
 	status = "okay";
 	ngpios = <128>;
-	bus-frequency = <1000000>;
+	bus-frequency = <500000>;
 };
 
 &ibt {
-- 
2.43.0



From ninad at linux.ibm.com  Fri Dec 13 06:50:34 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 08:50:34 -0600
Subject: [PATCH v1 8/8] ARM: dts: aspeed: system1: Disable gpio pull down
In-Reply-To: <20241213145037.3784931-1-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
Message-ID: <20241213145037.3784931-9-ninad@linux.ibm.com>

Disable internal pull down for the following GPIO lines.
- GPIOL4 - Reset PCH registers in the rtc.
- GPIOL5 - Reset portition of Intel ME
- GPIOL6 - FM smi active
- GPIOL7 - psu all dc power good.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index be0cd6152c61..c9575dd59b03 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -355,7 +355,35 @@ &uhci {
 	status = "okay";
 };
 
+&pinctrl {
+	pinctrl_gpiol4_unbiased: gpiol4 {
+		pins = "C15";
+		bias-disable;
+	};
+
+	pinctrl_gpiol5_unbiased: gpiol5 {
+		pins = "F15";
+		bias-disable;
+	};
+
+	pinctrl_gpiol6_unbiased: gpiol6 {
+		pins = "B14";
+		bias-disable;
+	};
+
+	pinctrl_gpiol7_unbiased: gpiol7 {
+		pins = "C14";
+		bias-disable;
+	};
+};
+
 &gpio0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpiol4_unbiased
+		&pinctrl_gpiol5_unbiased
+		&pinctrl_gpiol6_unbiased
+		&pinctrl_gpiol7_unbiased>;
+
 	gpio-line-names =
 	/*A0-A7*/	"","","","","","","","",
 	/*B0-B7*/	"","","","","bmc-tpm-reset","","","",
-- 
2.43.0



From ninad at linux.ibm.com  Fri Dec 13 06:50:33 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 08:50:33 -0600
Subject: [PATCH v1 7/8] ARM: dts: aspeed: system1: Mark GPIO line high/low
In-Reply-To: <20241213145037.3784931-1-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
Message-ID: <20241213145037.3784931-8-ninad@linux.ibm.com>

From: NINAD PALSULE <ninadpalsule at us.ibm.com>

- Mark following GPIO lines as input high:
  - GPIOL4 (reset PCH registers)
  - GPIOL5 (reset portition of intel ME)
- Mark isolate errors from cpu1 gpio (GPIOO6) as active low output.
- The fan controller reset line should be active high.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index ca2d4a292687..be0cd6152c61 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -383,6 +383,34 @@ &gpio0 {
 	/*X0-X7*/	"fpga-pgood","power-chassis-good","pch-pgood","","","","","",
 	/*Y0-Y7*/	"","","","","","","","",
 	/*Z0-Z7*/	"","","","","","","","";
+
+	rtc_reset {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(L, 4) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "RST_RTCRST_N";
+	};
+
+	srtc_reset {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(L, 5) GPIO_ACTIVE_HIGH>;
+		input;
+		line-name = "RST_SRTCRST_N";
+	};
+
+	fan_controller_reset {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(L, 6) GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "BMC_FAN_E3_SVC_PEX_INT_N";
+	};
+
+	isolate_errs_cpu1 {
+		gpio-hog;
+		gpios = <ASPEED_GPIO(O, 6) GPIO_ACTIVE_LOW>;
+		output-low;
+		line-name = "isolate_errs_cpu1";
+	};
 };
 
 &emmc_controller {
-- 
2.43.0



From catalin.marinas at arm.com  Fri Dec 13 06:55:19 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 13 Dec 2024 14:55:19 +0000
Subject: [PATCH v2] arm64: signal: Ensure signal delivery failure is recoverable
In-Reply-To: <20241210160940.2031997-1-kevin.brodsky@arm.com>
References: <20241210160940.2031997-1-kevin.brodsky@arm.com>
Message-ID: <173410171664.5468.16391474217431387071.b4-ty@arm.com>

On Tue, 10 Dec 2024 16:09:40 +0000, Kevin Brodsky wrote:
> Commit eaf62ce1563b ("arm64/signal: Set up and restore the GCS
> context for signal handlers") introduced a potential failure point
> at the end of setup_return(). This is unfortunate as it is too late
> to deliver a SIGSEGV: if that SIGSEGV is handled, the subsequent
> sigreturn will end up returning to the original handler, which is
> not the intention (since we failed to deliver that signal).
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: signal: Ensure signal delivery failure is recoverable
      https://git.kernel.org/arm64/c/a3b4647e2f9a

-- 
Catalin



From ubizjak at gmail.com  Fri Dec 13 06:57:52 2024
From: ubizjak at gmail.com (Uros Bizjak)
Date: Fri, 13 Dec 2024 15:57:52 +0100
Subject: [PATCH 1/3] KVM: arm64: timers: Fix percpu address space issues in kvm_timer_hyp_init()
Message-ID: <20241213145809.2918-1-ubizjak@gmail.com>

Cast return value from kvm_get_running_vcpus() in the __percpu
address space to the generic address space via uintptr_t [1]
to fix a couple of:

arch_timer.c:1395:66: warning: incorrect type in argument 2 (different address spaces)
arch_timer.c:1395:66:    expected void *vcpu_info
arch_timer.c:1395:66:    got struct kvm_vcpu *[noderef] __percpu *

sparse warnings.

There were no changes in the resulting object files.

[1] https://sparse.docs.kernel.org/en/latest/annotations.html#address-space-name

Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
Cc: Joey Gouly <joey.gouly 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>
---
 arch/arm64/kvm/arch_timer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 1215df590418..a13bb9e8dc19 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -1392,7 +1392,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
 
 	if (has_gic) {
 		err = irq_set_vcpu_affinity(host_vtimer_irq,
-					    kvm_get_running_vcpus());
+					    (void *)(uintptr_t)kvm_get_running_vcpus());
 		if (err) {
 			kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
 			goto out_free_vtimer_irq;
@@ -1416,7 +1416,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
 
 		if (has_gic) {
 			err = irq_set_vcpu_affinity(host_ptimer_irq,
-						    kvm_get_running_vcpus());
+						    (void *)(uintptr_t)kvm_get_running_vcpus());
 			if (err) {
 				kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
 				goto out_free_ptimer_irq;
-- 
2.42.0



From ubizjak at gmail.com  Fri Dec 13 06:57:53 2024
From: ubizjak at gmail.com (Uros Bizjak)
Date: Fri, 13 Dec 2024 15:57:53 +0100
Subject: [PATCH 2/3] irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
In-Reply-To: <20241213145809.2918-1-ubizjak@gmail.com>
References: <20241213145809.2918-1-ubizjak@gmail.com>
Message-ID: <20241213145809.2918-2-ubizjak@gmail.com>

percpu_base is used in various percpu functions that expect variable in
__percpu address space. Correct the declaration of percpu_base to

void __iomem * __percpu *percpu_base;

to declare the variable as __percpu pointer.

The patch fixes several sparse warnings:

irq-gic.c:1172:44: warning: incorrect type in assignment (different address spaces)
irq-gic.c:1172:44:    expected void [noderef] __percpu *[noderef] __iomem *percpu_base
irq-gic.c:1172:44:    got void [noderef] __iomem *[noderef] __percpu *
...
irq-gic.c:1184:26: warning: incorrect type in initializer (different address spaces)
irq-gic.c:1184:26:    expected void const [noderef] __percpu *__vpp_verify
irq-gic.c:1184:26:    got void [noderef] __percpu *[noderef] __iomem *
...
irq-gic.c:1184:71: warning: incorrect type in assignment (different address spaces)
irq-gic.c:1184:71:    expected void [noderef] __percpu *
irq-gic.c:1184:71:    got void [noderef] __iomem *
...
irq-gic.c:1231:43: warning: incorrect type in argument 1 (different address spaces)
irq-gic.c:1231:43:    expected void [noderef] __percpu *__pdata
irq-gic.c:1231:43:    got void [noderef] __percpu *[noderef] __iomem *percpu_base

There were no changes in the resulting object files.

Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
---
 drivers/irqchip/irq-gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 8fae6dc01024..6503573557fd 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -64,7 +64,7 @@ static void gic_check_cpu_features(void)
 
 union gic_base {
 	void __iomem *common_base;
-	void __percpu * __iomem *percpu_base;
+	void __iomem * __percpu *percpu_base;
 };
 
 struct gic_chip_data {
-- 
2.42.0



From ubizjak at gmail.com  Fri Dec 13 06:57:54 2024
From: ubizjak at gmail.com (Uros Bizjak)
Date: Fri, 13 Dec 2024 15:57:54 +0100
Subject: [PATCH 3/3] mailbox: zynqmp: Remove invalid __percpu annotation in zynqmp_ipi_probe()
In-Reply-To: <20241213145809.2918-1-ubizjak@gmail.com>
References: <20241213145809.2918-1-ubizjak@gmail.com>
Message-ID: <20241213145809.2918-3-ubizjak@gmail.com>

struct zynqmp_ipi_pdata __percpu *pdata is not a per-cpu variable,
so it shoul not be annotated with __percpu annotation.

Remove invalid __percpu annotation to fix several

zynqmp-ipi-mailbox.c:920:15: warning: incorrect type in assignment (different address spaces)
zynqmp-ipi-mailbox.c:920:15:    expected struct zynqmp_ipi_pdata [noderef] __percpu *pdata
zynqmp-ipi-mailbox.c:920:15:    got void *
zynqmp-ipi-mailbox.c:927:56: warning: incorrect type in argument 3 (different address spaces)
zynqmp-ipi-mailbox.c:927:56:    expected unsigned int [usertype] *out_value
zynqmp-ipi-mailbox.c:927:56:    got unsigned int [noderef] __percpu *
...

and several

drivers/mailbox/zynqmp-ipi-mailbox.c:924:9: warning: dereference of noderef expression
...

sparse warnings.

There were no changes in the resulting object files.

Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Cc: Jassi Brar <jassisinghbrar at gmail.com>
Cc: Michal Simek <michal.simek at amd.com>
---
 drivers/mailbox/zynqmp-ipi-mailbox.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index aa5249da59b2..0c143beaafda 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -905,7 +905,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *nc, *np = pdev->dev.of_node;
-	struct zynqmp_ipi_pdata __percpu *pdata;
+	struct zynqmp_ipi_pdata *pdata;
 	struct of_phandle_args out_irq;
 	struct zynqmp_ipi_mbox *mbox;
 	int num_mboxes, ret = -EINVAL;
-- 
2.42.0



From mike.leach at linaro.org  Fri Dec 13 06:49:16 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 13 Dec 2024 14:49:16 +0000
Subject: [PATCH v2 0/3] Extend logging on TMC start / stop errors
Message-ID: <20241213144919.110642-1-mike.leach@linaro.org>

Extend logging on TMC start / stop errors

Recent issues with trying to debug TMC timeouts and flush issues shows
a general lack of logging and context around the possible errors

Add logging to general wait for stop coresight routines and return values of
watched registers.

Update TMC to use this logging.

Changes since v1:
Rebase to coresight/next (kernel 6.13-rc2)

Mike Leach (3):
  coresight: Update timeout functions to allow return of test register
    value
  coresight: tmc: Update error logging in tmc common functions
  coresight: etf: etr: Update logging around flush_and_stop() errors

 drivers/hwtracing/coresight/coresight-core.c  | 50 +++++++++++++++----
 .../hwtracing/coresight/coresight-tmc-core.c  | 37 +++++++++++---
 .../hwtracing/coresight/coresight-tmc-etf.c   | 12 +++--
 .../hwtracing/coresight/coresight-tmc-etr.c   |  8 ++-
 drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
 include/linux/coresight.h                     |  2 +
 6 files changed, 86 insertions(+), 25 deletions(-)

-- 
2.25.1



From mike.leach at linaro.org  Fri Dec 13 06:49:17 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 13 Dec 2024 14:49:17 +0000
Subject: [PATCH v2 1/3] coresight: Update timeout functions to allow return of test register value
In-Reply-To: <20241213144919.110642-1-mike.leach@linaro.org>
References: <20241213144919.110642-1-mike.leach@linaro.org>
Message-ID: <20241213144919.110642-2-mike.leach@linaro.org>

Current coresight_timeout function spins on a bit on a test register,
till bit value achieved or timeout hit.

Add another function to return the full value of the register being
tested.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
---
 drivers/hwtracing/coresight/coresight-core.c | 50 +++++++++++++++-----
 include/linux/coresight.h                    |  2 +
 2 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index ea38ecf26fcb..feb1a1db355f 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1017,32 +1017,37 @@ static void coresight_remove_conns(struct coresight_device *csdev)
 }
 
 /**
- * coresight_timeout - loop until a bit has changed to a specific register
- *			state.
+ * coresight_timeout_retval - loop until a bit has changed to a specific register
+ *			      state. Return final register value
  * @csa: coresight device access for the device
  * @offset: Offset of the register from the base of the device.
  * @position: the position of the bit of interest.
  * @value: the value the bit should have.
+ * @rval:  the last read value of the register being tested.
  *
  * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
  * TIMEOUT_US has elapsed, which ever happens first.
  */
-int coresight_timeout(struct csdev_access *csa, u32 offset,
-		      int position, int value)
+int coresight_timeout_retval(struct csdev_access *csa, u32 offset,
+			     int position, int value, u32 *rval)
 {
-	int i;
-	u32 val;
+	int i, rc = -EAGAIN;
+	u32 val = 0;
 
 	for (i = TIMEOUT_US; i > 0; i--) {
 		val = csdev_access_read32(csa, offset);
 		/* waiting on the bit to go from 0 to 1 */
 		if (value) {
-			if (val & BIT(position))
-				return 0;
+			if (val & BIT(position)) {
+				rc = 0;
+				goto return_rval;
+			}
 		/* waiting on the bit to go from 1 to 0 */
 		} else {
-			if (!(val & BIT(position)))
-				return 0;
+			if (!(val & BIT(position))) {
+				rc = 0;
+				goto return_rval;
+			}
 		}
 
 		/*
@@ -1054,7 +1059,30 @@ int coresight_timeout(struct csdev_access *csa, u32 offset,
 			udelay(1);
 	}
 
-	return -EAGAIN;
+return_rval:
+	*rval = val;
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(coresight_timeout_retval);
+
+/**
+ * coresight_timeout - loop until a bit has changed to a specific register
+ *		       state
+ * @csa: coresight device access for the device
+ * @offset: Offset of the register from the base of the device.
+ * @position: the position of the bit of interest.
+ * @value: the value the bit should have.
+ *
+ * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
+ * TIMEOUT_US has elapsed, which ever happens first.
+ */
+int coresight_timeout(struct csdev_access *csa, u32 offset,
+		      int position, int value)
+{
+	u32 rval = 0;
+
+	return coresight_timeout_retval(csa, offset, position, value, &rval);
 }
 EXPORT_SYMBOL_GPL(coresight_timeout);
 
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 055ce5cd5c44..29cb71e82b0b 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -639,6 +639,8 @@ extern int coresight_enable_sysfs(struct coresight_device *csdev);
 extern void coresight_disable_sysfs(struct coresight_device *csdev);
 extern int coresight_timeout(struct csdev_access *csa, u32 offset,
 			     int position, int value);
+extern int coresight_timeout_retval(struct csdev_access *csa, u32 offset,
+				    int position, int value, u32 *rval);
 
 extern int coresight_claim_device(struct coresight_device *csdev);
 extern int coresight_claim_device_unlocked(struct coresight_device *csdev);
-- 
2.25.1



From mike.leach at linaro.org  Fri Dec 13 06:49:18 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 13 Dec 2024 14:49:18 +0000
Subject: [PATCH v2 2/3] coresight: tmc: Update error logging in tmc common functions
In-Reply-To: <20241213144919.110642-1-mike.leach@linaro.org>
References: <20241213144919.110642-1-mike.leach@linaro.org>
Message-ID: <20241213144919.110642-3-mike.leach@linaro.org>

Enhance the error logging in the tmc_wait_for_tmcready() and
tmc_flush_and_stop() to print key tmc  register values on error
conditions to improve hardware debug information.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
---
 .../hwtracing/coresight/coresight-tmc-core.c  | 37 +++++++++++++++----
 drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index e9876252a789..1a9299adae93 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -34,25 +34,36 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
 DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
 DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
 
+#define TMC_WAIT_READY_FMT_STR "timeout while waiting for TMC to be Ready [STS=0x%04x]\n"
+
 int tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
 	struct csdev_access *csa = &csdev->access;
+	u32 tmc_sts = 0;
 
 	/* Ensure formatter, unformatter and hardware fifo are empty */
-	if (coresight_timeout(csa, TMC_STS, TMC_STS_TMCREADY_BIT, 1)) {
-		dev_err(&csdev->dev,
-			"timeout while waiting for TMC to be Ready\n");
+	if (coresight_timeout_retval(csa, TMC_STS, TMC_STS_TMCREADY_BIT, 1,
+				     &tmc_sts)) {
+		dev_err(&csdev->dev, TMC_WAIT_READY_FMT_STR, tmc_sts);
 		return -EBUSY;
 	}
 	return 0;
 }
 
-void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
+int tmc_flush_and_stop(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
 	struct csdev_access *csa = &csdev->access;
-	u32 ffcr;
+	u32 ffcr, ffsr, tmc_sts;
+	int rc = 0;
+
+	/* note any MemErr present when stopping TMC */
+	tmc_sts = readl_relaxed(drvdata->base + TMC_STS);
+	if (tmc_sts & TMC_STS_MEMERR)
+		dev_err(&csdev->dev,
+			"MemErr detected before Manual Flush; STS[0x%02x]\n",
+			tmc_sts);
 
 	ffcr = readl_relaxed(drvdata->base + TMC_FFCR);
 	ffcr |= TMC_FFCR_STOP_ON_FLUSH;
@@ -60,12 +71,22 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
 	ffcr |= BIT(TMC_FFCR_FLUSHMAN_BIT);
 	writel_relaxed(ffcr, drvdata->base + TMC_FFCR);
 	/* Ensure flush completes */
-	if (coresight_timeout(csa, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0)) {
+	if (coresight_timeout_retval(csa, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0,
+				     &ffcr)) {
+		ffsr = readl_relaxed(drvdata->base + TMC_FFSR);
 		dev_err(&csdev->dev,
-		"timeout while waiting for completion of Manual Flush\n");
+			"timeout while waiting for completion of Manual Flush\n");
+		dev_err(&csdev->dev,
+			"regs: FFCR[0x%02x] FFSR[0x%02x] STS[0x%02x]\n",
+			ffcr, ffsr, tmc_sts);
+		rc = -EBUSY;
 	}
 
-	tmc_wait_for_tmcready(drvdata);
+	if (tmc_wait_for_tmcready(drvdata)) {
+		dev_err(&csdev->dev, "TMC ready error after Manual flush\n");
+		rc = -EBUSY;
+	}
+	return rc;
 }
 
 void tmc_enable_hw(struct tmc_drvdata *drvdata)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 2671926be62a..34513f07c3aa 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -259,7 +259,7 @@ struct tmc_sg_table {
 
 /* Generic functions */
 int tmc_wait_for_tmcready(struct tmc_drvdata *drvdata);
-void tmc_flush_and_stop(struct tmc_drvdata *drvdata);
+int tmc_flush_and_stop(struct tmc_drvdata *drvdata);
 void tmc_enable_hw(struct tmc_drvdata *drvdata);
 void tmc_disable_hw(struct tmc_drvdata *drvdata);
 u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata);
-- 
2.25.1



From mike.leach at linaro.org  Fri Dec 13 06:49:19 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 13 Dec 2024 14:49:19 +0000
Subject: [PATCH v2 3/3] coresight: etf: etr: Update logging around flush_and_stop() errors
In-Reply-To: <20241213144919.110642-1-mike.leach@linaro.org>
References: <20241213144919.110642-1-mike.leach@linaro.org>
Message-ID: <20241213144919.110642-4-mike.leach@linaro.org>

Insert additional context around tmc_flush_and_stop() errors.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
---
 drivers/hwtracing/coresight/coresight-tmc-etf.c | 12 +++++++++---
 drivers/hwtracing/coresight/coresight-tmc-etr.c |  8 ++++++--
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index d4f641cd9de6..62b4b685c1a1 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -84,7 +84,9 @@ static void __tmc_etb_disable_hw(struct tmc_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&drvdata->csdev->dev,
+			"Flush and stop error disabling ETB\n");
 	/*
 	 * When operating in sysFS mode the content of the buffer needs to be
 	 * read before the TMC is disabled.
@@ -146,7 +148,9 @@ static void tmc_etf_disable_hw(struct tmc_drvdata *drvdata)
 
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&drvdata->csdev->dev,
+			"Flush and stop error disabling ETF\n");
 	tmc_disable_hw(drvdata);
 	coresight_disclaim_device_unlocked(csdev);
 	CS_LOCK(drvdata->base);
@@ -496,7 +500,9 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
 
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&drvdata->csdev->dev,
+			"Flush and stop error updating perf buffer\n");
 
 	read_ptr = tmc_read_rrp(drvdata);
 	write_ptr = tmc_read_rwp(drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..122a067d1bb8 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1139,7 +1139,9 @@ static void __tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&drvdata->csdev->dev,
+			"Flush and stop error disabling ETR\n");
 	/*
 	 * When operating in sysFS mode the content of the buffer needs to be
 	 * read before the TMC is disabled.
@@ -1578,7 +1580,9 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
 
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&csdev->dev,
+			"Flush and Stop error updating perf buffer\n");
 	tmc_sync_etr_buf(drvdata);
 
 	CS_LOCK(drvdata->base);
-- 
2.25.1



From ninad at linux.ibm.com  Fri Dec 13 06:50:26 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 08:50:26 -0600
Subject: [PATCH v1 0/8] DTS updates for system1 BMC
Message-ID: <20241213145037.3784931-1-ninad@linux.ibm.com>

Hello

Please review the patch set. It has various device tree changes for
system1 BMC after hardware testing.

NINAD PALSULE (7):
  ARM: dts: aspeed: system1: Add IPMB device
  ARM: dts: aspeed: system1: Add GPIO line name
  ARM: dts: aspeed: system1: Add RGMII support
  ARM: dts: aspeed: system1: Reduce sgpio speed
  ARM: dts: aspeed: system1: Update LED gpio name
  ARM: dts: aspeed: system1: Remove VRs max8952
  ARM: dts: aspeed: system1: Mark GPIO line high/low

Ninad Palsule (1):
  ARM: dts: aspeed: system1: Disable gpio pull down

 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     | 178 ++++++++++++------
 1 file changed, 119 insertions(+), 59 deletions(-)

-- 
2.43.0



From ninad at linux.ibm.com  Fri Dec 13 06:50:27 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 08:50:27 -0600
Subject: [PATCH v1 1/8] ARM: dts: aspeed: system1: Add IPMB device
In-Reply-To: <20241213145037.3784931-1-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
Message-ID: <20241213145037.3784931-2-ninad@linux.ibm.com>

From: NINAD PALSULE <ninadpalsule at us.ibm.com>

Add IPMB device sitting behind PCH module

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index 8f77bc9e860c..51a116d7041a 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -763,6 +763,16 @@ i2c3mux0chn7: i2c at 7 {
 
 &i2c4 {
 	status = "okay";
+	multi-master;
+	bus-frequency = <1000000>;
+
+	//Set bmc' slave address;
+	bmc_slave at 10 {
+		compatible = "ipmb-dev";
+		reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+
+		i2c-protocol;
+	};
 };
 
 &i2c5 {
-- 
2.43.0



From ninad at linux.ibm.com  Fri Dec 13 06:50:29 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 08:50:29 -0600
Subject: [PATCH v1 3/8] ARM: dts: aspeed: system1: Add RGMII support
In-Reply-To: <20241213145037.3784931-1-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
Message-ID: <20241213145037.3784931-4-ninad@linux.ibm.com>

From: NINAD PALSULE <ninadpalsule at us.ibm.com>

system1 has 2 transceiver connected through the RGMII interfaces. Added
device tree entry to enable RGMII support.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     | 38 ++++++++++++++++---
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index db4b9fb674fe..775a95470f5c 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -425,14 +425,42 @@ &lpc_ctrl {
 	memory-region = <&flash_memory>;
 };
 
+&mdio0 {
+	status = "okay";
+
+	ethphy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0>;
+	};
+};
+
+&mdio2 {
+	status = "okay";
+
+	ethphy2: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0>;
+	};
+};
+
+&mac0 {
+	status = "okay";
+
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&ethphy0>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rgmii1_default>;
+};
+
 &mac2 {
 	status = "okay";
+
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy2>;
+
 	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_rmii3_default>;
-	clocks = <&syscon ASPEED_CLK_GATE_MAC3CLK>,
-		 <&syscon ASPEED_CLK_MAC3RCLK>;
-	clock-names = "MACCLK", "RCLK";
-	use-ncsi;
+	pinctrl-0 = <&pinctrl_rgmii3_default>;
 };
 
 &mac3 {
-- 
2.43.0



From ninad at linux.ibm.com  Fri Dec 13 06:50:31 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 08:50:31 -0600
Subject: [PATCH v1 5/8] ARM: dts: aspeed: system1: Update LED gpio name
In-Reply-To: <20241213145037.3784931-1-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
Message-ID: <20241213145037.3784931-6-ninad@linux.ibm.com>

From: NINAD PALSULE <ninadpalsule at us.ibm.com>

Rename LEDs with meaningful names for easier identification.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     | 36 +++++++++----------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index ebbb14241256..149b9ad23dbb 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -116,63 +116,63 @@ vga_memory: region at bf000000 {
 	leds {
 		compatible = "gpio-leds";
 
-		led-0 {
+		led-bmc-ready {
 			gpios = <&gpio0 ASPEED_GPIO(L, 7) GPIO_ACTIVE_HIGH>;
 		};
 
-		led-1 {
+		led-bmc-hb {
 			gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_HIGH>;
 		};
 
-		led-2 {
+		led-rear-enc-fault0 {
 			gpios = <&gpio0 ASPEED_GPIO(S, 6) GPIO_ACTIVE_HIGH>;
 		};
 
-		led-3 {
+		led-rear-enc-id0 {
 			gpios = <&gpio0 ASPEED_GPIO(S, 7) GPIO_ACTIVE_HIGH>;
 		};
 
-		led-4 {
+		led-fan0-fault {
 			gpios = <&pca3 5 GPIO_ACTIVE_LOW>;
 		};
 
-		led-5 {
+		led-fan1-fault {
 			gpios = <&pca3 6 GPIO_ACTIVE_LOW>;
 		};
 
-		led-6 {
+		led-fan2-fault {
 			gpios = <&pca3 7 GPIO_ACTIVE_LOW>;
 		};
 
-		led-7 {
+		led-fan3-fault {
 			gpios = <&pca3 8 GPIO_ACTIVE_LOW>;
 		};
 
-		led-8 {
+		led-fan4-fault {
 			gpios = <&pca3 9 GPIO_ACTIVE_LOW>;
 		};
 
-		led-9 {
+		led-fan5-fault {
 			gpios = <&pca3 10 GPIO_ACTIVE_LOW>;
 		};
 
-		led-a {
+		led-fan6-fault {
 			gpios = <&pca3 11 GPIO_ACTIVE_LOW>;
 		};
 
-		led-b {
+		led-nvmed0-fault {
 			gpios = <&pca4 4 GPIO_ACTIVE_HIGH>;
 		};
 
-		led-c {
+		led-nvmed1-fault {
 			gpios = <&pca4 5 GPIO_ACTIVE_HIGH>;
 		};
 
-		led-d {
+		led-nvmed2-fault {
 			gpios = <&pca4 6 GPIO_ACTIVE_HIGH>;
 		};
 
-		led-e {
+		led-nvmed3-fault {
 			gpios = <&pca4 7 GPIO_ACTIVE_HIGH>;
 		};
 	};
@@ -368,14 +368,14 @@ &gpio0 {
 	/*I0-I7*/	"","","","","","","","",
 	/*J0-J7*/	"","","","","","","","",
 	/*K0-K7*/	"","","","","","","","",
-	/*L0-L7*/	"","","","","","","","bmc-ready",
+	/*L0-L7*/	"","","","","","","","led-bmc-ready",
 	/*M0-M7*/	"","","","","","","","",
 	/*N0-N7*/	"pch-reset","","","","","flash-write-override","","",
 	/*O0-O7*/	"","","","","","","","",
-	/*P0-P7*/	"","","","","","","","bmc-hb",
+	/*P0-P7*/	"","","","","","","","led-bmc-hb",
 	/*Q0-Q7*/	"","","","","","","pch-ready","",
 	/*R0-R7*/	"","","","","","","","",
-	/*S0-S7*/	"","","","","","","rear-enc-fault0","rear-enc-id0",
+	/*S0-S7*/	"","","","","","","led-rear-enc-fault0","led-rear-enc-id0",
 	/*T0-T7*/	"","","","","","","","",
 	/*U0-U7*/	"","","","","","","","",
 	/*V0-V7*/	"","rtc-battery-voltage-read-enable","","power-chassis-control","","","","",
-- 
2.43.0



From ninad at linux.ibm.com  Fri Dec 13 06:50:32 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 08:50:32 -0600
Subject: [PATCH v1 6/8] ARM: dts: aspeed: system1: Remove VRs max8952
In-Reply-To: <20241213145037.3784931-1-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
Message-ID: <20241213145037.3784931-7-ninad@linux.ibm.com>

From: NINAD PALSULE <ninadpalsule at us.ibm.com>

Removing voltage regulators max8952 from device tree. Those are fully
controlled by hardware and firmware should not thouch them.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     | 34 -------------------
 1 file changed, 34 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index 149b9ad23dbb..ca2d4a292687 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -514,23 +514,6 @@ eeprom at 50 {
 		compatible = "atmel,24c64";
 		reg = <0x50>;
 	};
-
-	regulator at 60 {
-		compatible = "maxim,max8952";
-		reg = <0x60>;
-
-		max8952,default-mode = <0>;
-		max8952,dvs-mode-microvolt = <1250000>, <1200000>,
-						<1050000>, <950000>;
-		max8952,sync-freq = <0>;
-		max8952,ramp-speed = <0>;
-
-		regulator-name = "VR_v77_1v4";
-		regulator-min-microvolt = <770000>;
-		regulator-max-microvolt = <1400000>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
 };
 
 &i2c1 {
@@ -1227,23 +1210,6 @@ eeprom at 50 {
 		compatible = "atmel,24c64";
 		reg = <0x50>;
 	};
-
-	regulator at 60 {
-		compatible = "maxim,max8952";
-		reg = <0x60>;
-
-		max8952,default-mode = <0>;
-		max8952,dvs-mode-microvolt = <1250000>, <1200000>,
-						<1050000>, <950000>;
-		max8952,sync-freq = <0>;
-		max8952,ramp-speed = <0>;
-
-		regulator-name = "VR_v77_1v4";
-		regulator-min-microvolt = <770000>;
-		regulator-max-microvolt = <1400000>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
 };
 
 &i2c11 {
-- 
2.43.0



From ninad at linux.ibm.com  Fri Dec 13 06:50:28 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 08:50:28 -0600
Subject: [PATCH v1 2/8] ARM: dts: aspeed: system1: Add GPIO line name
In-Reply-To: <20241213145037.3784931-1-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
Message-ID: <20241213145037.3784931-3-ninad@linux.ibm.com>

From: NINAD PALSULE <ninadpalsule at us.ibm.com>

Add following GPIO line name so that userspace can control them
    - Flash write override
    - pch-reset

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index 51a116d7041a..db4b9fb674fe 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -370,7 +370,7 @@ &gpio0 {
 	/*K0-K7*/	"","","","","","","","",
 	/*L0-L7*/	"","","","","","","","bmc-ready",
 	/*M0-M7*/	"","","","","","","","",
-	/*N0-N7*/	"fpga-debug-enable","","","","","","","",
+	/*N0-N7*/	"pch-reset","","","","","flash-write-override","","",
 	/*O0-O7*/	"","","","","","","","",
 	/*P0-P7*/	"","","","","","","","bmc-hb",
 	/*Q0-Q7*/	"","","","","","","pch-ready","",
-- 
2.43.0



From michal.simek at amd.com  Fri Dec 13 07:05:59 2024
From: michal.simek at amd.com (Michal Simek)
Date: Fri, 13 Dec 2024 16:05:59 +0100
Subject: [PATCH 3/3] mailbox: zynqmp: Remove invalid __percpu annotation
 in zynqmp_ipi_probe()
In-Reply-To: <20241213145809.2918-3-ubizjak@gmail.com>
References: <20241213145809.2918-1-ubizjak@gmail.com>
 <20241213145809.2918-3-ubizjak@gmail.com>
Message-ID: <cd2e2945-1b62-4fce-82fb-68f0692bf053@amd.com>



On 12/13/24 15:57, Uros Bizjak wrote:
> struct zynqmp_ipi_pdata __percpu *pdata is not a per-cpu variable,
> so it shoul not be annotated with __percpu annotation.

typo here.

> 
> Remove invalid __percpu annotation to fix several
> 
> zynqmp-ipi-mailbox.c:920:15: warning: incorrect type in assignment (different address spaces)
> zynqmp-ipi-mailbox.c:920:15:    expected struct zynqmp_ipi_pdata [noderef] __percpu *pdata
> zynqmp-ipi-mailbox.c:920:15:    got void *
> zynqmp-ipi-mailbox.c:927:56: warning: incorrect type in argument 3 (different address spaces)
> zynqmp-ipi-mailbox.c:927:56:    expected unsigned int [usertype] *out_value
> zynqmp-ipi-mailbox.c:927:56:    got unsigned int [noderef] __percpu *
> ...
> 
> and several
> 
> drivers/mailbox/zynqmp-ipi-mailbox.c:924:9: warning: dereference of noderef expression
> ...
> 
> sparse warnings.
> 
> There were no changes in the resulting object files.
> 
> Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
> Cc: Jassi Brar <jassisinghbrar at gmail.com>
> Cc: Michal Simek <michal.simek at amd.com>
> ---
>   drivers/mailbox/zynqmp-ipi-mailbox.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
> index aa5249da59b2..0c143beaafda 100644
> --- a/drivers/mailbox/zynqmp-ipi-mailbox.c
> +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
> @@ -905,7 +905,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
>   	struct device_node *nc, *np = pdev->dev.of_node;
> -	struct zynqmp_ipi_pdata __percpu *pdata;
> +	struct zynqmp_ipi_pdata *pdata;
>   	struct of_phandle_args out_irq;
>   	struct zynqmp_ipi_mbox *mbox;
>   	int num_mboxes, ret = -EINVAL;


Feel free to also find commit which introduced this issue and add
Fixes and cc: stable to v2.

Thanks,
Michal


From kaleshsingh at google.com  Fri Dec 13 07:06:55 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Fri, 13 Dec 2024 10:06:55 -0500
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
In-Reply-To: <695eabb8-ba28-4031-bc4d-66dc4f1d096f@lucifer.local>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
 <hmuzfspqjzb36xlj2x44keihacrrhzj5madqrfbcnhqouzredv@wo75achgkuh5>
 <1818e2ea-f170-4a9c-8d93-2a24f2755a41@lucifer.local> <20241212173609.afd41d1dffbefe0d731ed4ed@linux-foundation.org>
 <695eabb8-ba28-4031-bc4d-66dc4f1d096f@lucifer.local>
Message-ID: <CAC_TJvcdz854DmBoVRkb_B5j+u-t=4zHkLtHVeB5RJ=bXcBJag@mail.gmail.com>

On Fri, Dec 13, 2024 at 4:00?AM Lorenzo Stoakes
<lorenzo.stoakes at oracle.com> wrote:
>
> On Thu, Dec 12, 2024 at 05:36:09PM -0800, Andrew Morton wrote:
> > On Thu, 12 Dec 2024 22:51:34 +0000 Lorenzo Stoakes <lorenzo.stoakes at oracle.com> wrote:
> >
> > > You've fundamentally violated kernel process and etiquette. I'd be more
> > > forgiving, but this is at v2 and you've not cc'd KEY people. Twice. This is
> > > totally unacceptable. See [0] if you are unsure of how to do so.
> >
> > This feels excessive to me.  linux-mm averages a mere 140 mesages/day
> > and it seems reasonable to assume that key people are spending their 5
> > minutes to scroll through the email subjects.
>
> In practice we did all miss it, and I don't think it's unreasonable to ask
> people to run get_maintainers.pl to avoid this.
>
> In any case, I truly do think this series works better as RFC, I mean Liam
> has already voiced the kind of disagreements I share with it, and we need
> to rethink how to approach it in general.
>
> So if this is simply sent as RFC with the correct cc's (and ideally with
> some review feedback applied - a better cover letter, etc.) then it makes
> everything easier.
>
> As mentioned the timing is unfortunate here, this is a series we really
> want to make sure is properly reviewed before any chance of merge so again
> this points to RFC being the way forward.

Hi everyone,

Sorry for the delayed response -- I was traveling and didn?t have
access to email.

Thank you for the feedback. I realize I missed some key reviewers in
the CC list for this patch.
When I ran get_maintainer.pl, it returned a large list of recipients.
To avoid over-CC?ing people (which has been an issue for me in the
past), I tried to trim it down to maintainers and a few others I
thought would be interested. Clearly, I got it wrong and missed some
key folks. That was not my intention, and I?ll make sure to fix it
when I resend the patch as an RFC.

On the technical side, Liam is right that the copy-pasted arch code
has inconsistencies (missing checks, order of checks, ...). I agree
there?s room for further consolidation. I?ll take another stab at it
and resend it as an RFC with an updated cover letter, as Lorenzo and
others suggested.

Thanks,
Kalesh


From wens at kernel.org  Fri Dec 13 07:10:11 2024
From: wens at kernel.org (Chen-Yu Tsai)
Date: Fri, 13 Dec 2024 23:10:11 +0800
Subject: [PATCH] irqchip/gic-v3: Work around insecure GIC integrations
In-Reply-To: <20241213141037.3995049-1-maz@kernel.org>
References: <20241213141037.3995049-1-maz@kernel.org>
Message-ID: <CAGb2v67vgoZr_1T579SrwG9UvNs0eRfT37Qk_g2k7Z-mRfEXNg@mail.gmail.com>

On Fri, Dec 13, 2024 at 10:34?PM Marc Zyngier <maz at kernel.org> wrote:
>
> It appears that the relatively popular RK3399 SoC has been put together
> using a large amount of illicit substances, as experiments reveal
> that its integration of GIC500 exposes the *secure* programming
> interface to non-secure.
>
> This has some pretty bad effects on the way priorities are handled,
> and results in a dead machine if booting with pseudo-NMI enabled
> (irqchip.gicv3_pseudo_nmi=1) if the kernel contains 18fdb6348c480
> ("arm64: irqchip/gic-v3: Select priorities at boot time"), which
> relies on the priorities being programmed using the NS view.
>
> Let's restore some sanity by going one step further and disable
> security altogether in this case. This is not any worse, and
> puts us in a mode where priorities actually make some sense.
>
> Huge thanks to Mark Kettenis who initially identified this issue
> on OpenBSD, and to Chen-Yu Tsai who reported the problem in
> Linux.
>
> Fixes: 18fdb6348c480 ("arm64: irqchip/gic-v3: Select priorities at boot time")
> Reported-by: Mark Kettenis <mark.kettenis at xs4all.nl>
> Reported-by: Chen-Yu Tsai <wenst at chromium.org>

Should be

Reported-by: Chen-Yu Tsai <wens at csie.org>

(I know it's confusing, I even mix up inboxes at work.)

> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Cc: stable at vger.kernel.org

Tested-by: Chen-Yu Tsai <wens at csie.org>

My RK3399 boots normally with pseudo NMI enabled with this patch now.
Also tried NMI backtraces through sysrq, though I'm not sure that
always goes through the pseudo NMI path?

> ---
>  drivers/irqchip/irq-gic-v3.c | 17 ++++++++++++++++-
>  1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 34db379d066a5..79d8cc80693c3 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -161,7 +161,22 @@ static bool cpus_have_group0 __ro_after_init;
>
>  static void __init gic_prio_init(void)
>  {
> -       cpus_have_security_disabled = gic_dist_security_disabled();
> +       bool ds;
> +
> +       ds = gic_dist_security_disabled();
> +       if (!ds) {
> +               u32 val;
> +
> +               val = readl_relaxed(gic_data.dist_base + GICD_CTLR);
> +               val |= GICD_CTLR_DS;
> +               writel_relaxed(val, gic_data.dist_base + GICD_CTLR);
> +
> +               ds = gic_dist_security_disabled();
> +               if (ds)
> +                       pr_warn("Broken GIC integration, security disabled");
> +       }
> +
> +       cpus_have_security_disabled = ds;
>         cpus_have_group0 = gic_has_group0();
>
>         /*
> --
> 2.39.2
>
>


From lorenzo.stoakes at oracle.com  Fri Dec 13 07:16:23 2024
From: lorenzo.stoakes at oracle.com (Lorenzo Stoakes)
Date: Fri, 13 Dec 2024 15:16:23 +0000
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
In-Reply-To: <CAC_TJvcdz854DmBoVRkb_B5j+u-t=4zHkLtHVeB5RJ=bXcBJag@mail.gmail.com>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
 <hmuzfspqjzb36xlj2x44keihacrrhzj5madqrfbcnhqouzredv@wo75achgkuh5>
 <1818e2ea-f170-4a9c-8d93-2a24f2755a41@lucifer.local>
 <20241212173609.afd41d1dffbefe0d731ed4ed@linux-foundation.org>
 <695eabb8-ba28-4031-bc4d-66dc4f1d096f@lucifer.local>
 <CAC_TJvcdz854DmBoVRkb_B5j+u-t=4zHkLtHVeB5RJ=bXcBJag@mail.gmail.com>
Message-ID: <9675c409-b495-46a5-a90c-c952892b4121@lucifer.local>

On Fri, Dec 13, 2024 at 10:06:55AM -0500, Kalesh Singh wrote:
> On Fri, Dec 13, 2024 at 4:00?AM Lorenzo Stoakes
> <lorenzo.stoakes at oracle.com> wrote:
> >
> > On Thu, Dec 12, 2024 at 05:36:09PM -0800, Andrew Morton wrote:
> > > On Thu, 12 Dec 2024 22:51:34 +0000 Lorenzo Stoakes <lorenzo.stoakes at oracle.com> wrote:
> > >
> > > > You've fundamentally violated kernel process and etiquette. I'd be more
> > > > forgiving, but this is at v2 and you've not cc'd KEY people. Twice. This is
> > > > totally unacceptable. See [0] if you are unsure of how to do so.
> > >
> > > This feels excessive to me.  linux-mm averages a mere 140 mesages/day
> > > and it seems reasonable to assume that key people are spending their 5
> > > minutes to scroll through the email subjects.
> >
> > In practice we did all miss it, and I don't think it's unreasonable to ask
> > people to run get_maintainers.pl to avoid this.
> >
> > In any case, I truly do think this series works better as RFC, I mean Liam
> > has already voiced the kind of disagreements I share with it, and we need
> > to rethink how to approach it in general.
> >
> > So if this is simply sent as RFC with the correct cc's (and ideally with
> > some review feedback applied - a better cover letter, etc.) then it makes
> > everything easier.
> >
> > As mentioned the timing is unfortunate here, this is a series we really
> > want to make sure is properly reviewed before any chance of merge so again
> > this points to RFC being the way forward.
>
> Hi everyone,
>
> Sorry for the delayed response -- I was traveling and didn?t have
> access to email.

Ack.

>
> Thank you for the feedback. I realize I missed some key reviewers in
> the CC list for this patch.
> When I ran get_maintainer.pl, it returned a large list of recipients.
> To avoid over-CC?ing people (which has been an issue for me in the
> past), I tried to trim it down to maintainers and a few others I
> thought would be interested. Clearly, I got it wrong and missed some
> key folks. That was not my intention, and I?ll make sure to fix it
> when I resend the patch as an RFC.

Sure thanks :) Much appreciated. Sorry to be so curt there, just I think
important to underline.

We just want to make sure we can find a way to get this series sorted out
so we can get it merged in a form that makes sense overall, ultimately! :)

>
> On the technical side, Liam is right that the copy-pasted arch code
> has inconsistencies (missing checks, order of checks, ...). I agree
> there?s room for further consolidation. I?ll take another stab at it
> and resend it as an RFC with an updated cover letter, as Lorenzo and
> others suggested.

The most useful thing here as well to help us understand would be to write
more in the cover letter to expand on what it is you ultimately what to
achieve here - it seems like an extension on the existing THP work on a
per-arch basis (I may be wrong)? So adding more detail would be super
useful here! :)

We do hope to avoid arch hooks if at all possible explicitly for the reason
that they can be applied at unfortunate times in terms of locking/whether
the objects in question are fully/partially instantiated, VMA visibility
etc. etc. based on having had issues in these areas before.

Also if a hook means 'anything' can happen at a certain point, it means we
can't make any assumptions about what has/hasn't and have to account for
anything which seriously complicates things.

Ideally we'd find a means to achieve the same thing while also exposing us
as little as possible to what may be mutated.

>
> Thanks,
> Kalesh

Thanks!


From apatel at ventanamicro.com  Fri Dec 13 07:43:52 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Fri, 13 Dec 2024 21:13:52 +0530
Subject: [PATCH 1/4] irqchip/riscv-imsic: Handle non-atomic MSI updates
 for device
In-Reply-To: <877c84ade6.ffs@tglx>
References: <20241208150711.297624-1-apatel@ventanamicro.com>
 <20241208150711.297624-2-apatel@ventanamicro.com> <875xnuq6dc.ffs@tglx>
 <CAK9=C2VqU2mdLL-R20bdgvDHi0WcuNyUSqRo7Pztsu-8X1wVvw@mail.gmail.com>
 <87r06gq2di.ffs@tglx> <CAK9=C2XEhtB00y6WTMaO0X=7K820T_BSCLA5bw6hJbfvQAD+Pw@mail.gmail.com>
 <877c84ade6.ffs@tglx>
Message-ID: <CAK9=C2Xyqk1WRHTXa_74s1uWuuMP5d=RBpnoSREvuF=C3OWW_A@mail.gmail.com>

On Fri, Dec 13, 2024 at 1:21?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Thu, Dec 12 2024 at 22:11, Anup Patel wrote:
> >> --- a/kernel/irq/chip.c
> >> +++ b/kernel/irq/chip.c
> >> @@ -47,6 +47,13 @@ int irq_set_chip(unsigned int irq, const
> >>                 return -EINVAL;
> >>
> >>         desc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
> >> +
> >> +       if (IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS) && chip) {
> >> +               if (chip->flags & IRQCHIP_MOVE_DEFERRED)
> >> +                       irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
> >> +               else
> >> +                       irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
> >> +       }
> >
> > We need similar changes in irq_domain_set_hwirq_and_chip()
> > because we use IRQ_DOMAIN_HIERARCHY in RISC-V.
>
> Grr, you are right. Let me add that to the base patch.
>
> >>         irq_put_desc_unlock(desc, flags);
> >>         /*
> >>          * For !CONFIG_SPARSE_IRQ make the irq show up in
> >> @@ -1114,16 +1121,21 @@ void irq_modify_status(unsigned int irq,
> >>         trigger = irqd_get_trigger_type(&desc->irq_data);
> >>
> >>         irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
> >> -                  IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT);
> >> +                  IRQD_TRIGGER_MASK | IRQD_LEVEL);
> >>         if (irq_settings_has_no_balance_set(desc))
> >>                 irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
> >>         if (irq_settings_is_per_cpu(desc))
> >>                 irqd_set(&desc->irq_data, IRQD_PER_CPU);
> >> -       if (irq_settings_can_move_pcntxt(desc))
> >> -               irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
> >>         if (irq_settings_is_level(desc))
> >>                 irqd_set(&desc->irq_data, IRQD_LEVEL);
> >>
> >> +       /* Keep this around until x86 is converted over */
> >> +       if (!IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS)) {
> >> +               irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
> >> +               if (irq_settings_can_move_pcntxt(desc))
> >> +                       irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
> >> +       }
> >> +
> >
> > These changes in irq_modify_status() need to be dropped to support
> > the above changes in irq_domain_set_hwirq_and_chip().
>
> Why? With CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS enabled this hunk is
> compiled out. So nothing is modifying PCNTXT here. That's the whole
> point.
>

Understood, please ignore my previous comment.

I was using irq_set_status_flags() in irq_domain_set_hwirq_and_chip()
which did not work because irq_modify_status() did not modify PCNTXT.

Regards,
Anup


From maz at kernel.org  Fri Dec 13 07:44:23 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 13 Dec 2024 15:44:23 +0000
Subject: [PATCH] irqchip/gic-v3: Work around insecure GIC integrations
In-Reply-To: <CAGb2v67vgoZr_1T579SrwG9UvNs0eRfT37Qk_g2k7Z-mRfEXNg@mail.gmail.com>
References: <20241213141037.3995049-1-maz@kernel.org>
	<CAGb2v67vgoZr_1T579SrwG9UvNs0eRfT37Qk_g2k7Z-mRfEXNg@mail.gmail.com>
Message-ID: <86ed2bsi3s.wl-maz@kernel.org>

On Fri, 13 Dec 2024 15:10:11 +0000,
Chen-Yu Tsai <wens at kernel.org> wrote:
> 
> On Fri, Dec 13, 2024 at 10:34?PM Marc Zyngier <maz at kernel.org> wrote:
> >
> > It appears that the relatively popular RK3399 SoC has been put together
> > using a large amount of illicit substances, as experiments reveal
> > that its integration of GIC500 exposes the *secure* programming
> > interface to non-secure.
> >
> > This has some pretty bad effects on the way priorities are handled,
> > and results in a dead machine if booting with pseudo-NMI enabled
> > (irqchip.gicv3_pseudo_nmi=1) if the kernel contains 18fdb6348c480
> > ("arm64: irqchip/gic-v3: Select priorities at boot time"), which
> > relies on the priorities being programmed using the NS view.
> >
> > Let's restore some sanity by going one step further and disable
> > security altogether in this case. This is not any worse, and
> > puts us in a mode where priorities actually make some sense.
> >
> > Huge thanks to Mark Kettenis who initially identified this issue
> > on OpenBSD, and to Chen-Yu Tsai who reported the problem in
> > Linux.
> >
> > Fixes: 18fdb6348c480 ("arm64: irqchip/gic-v3: Select priorities at boot time")
> > Reported-by: Mark Kettenis <mark.kettenis at xs4all.nl>
> > Reported-by: Chen-Yu Tsai <wenst at chromium.org>
> 
> Should be
> 
> Reported-by: Chen-Yu Tsai <wens at csie.org>
> 
> (I know it's confusing, I even mix up inboxes at work.)

Ah, fair enough. Given that the report was on IRC, I had just used the
first address git log gave me.

> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > Cc: stable at vger.kernel.org
> 
> Tested-by: Chen-Yu Tsai <wens at csie.org>
> 
> My RK3399 boots normally with pseudo NMI enabled with this patch now.
> Also tried NMI backtraces through sysrq, though I'm not sure that
> always goes through the pseudo NMI path?

Should do, according to arch/arm64/kernel/smp::ipi_setup().

Thanks for having tested it.

	M.

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


From krzk at kernel.org  Fri Dec 13 07:48:45 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 16:48:45 +0100
Subject: [PATCH v1 1/8] ARM: dts: aspeed: system1: Add IPMB device
In-Reply-To: <20241213145037.3784931-2-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
 <20241213145037.3784931-2-ninad@linux.ibm.com>
Message-ID: <45b55b4b-25e4-4e8b-8c95-8c3129e72227@kernel.org>

On 13/12/2024 15:50, Ninad Palsule wrote:
> From: NINAD PALSULE <ninadpalsule at us.ibm.com>
> 
> Add IPMB device sitting behind PCH module
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
> ---
>  arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
> index 8f77bc9e860c..51a116d7041a 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
> @@ -763,6 +763,16 @@ i2c3mux0chn7: i2c at 7 {
>  
>  &i2c4 {
>  	status = "okay";
> +	multi-master;
> +	bus-frequency = <1000000>;
> +
> +	//Set bmc' slave address;

Is this relevant/useful comment? Why is it even here?

> +	bmc_slave at 10 {

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

Also: use DTS coding style (there are no underscores in node names) and
use preferred naming scheme (see general kernel coding style / naming).



Best regards,
Krzysztof


From krzk at kernel.org  Fri Dec 13 07:49:13 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Dec 2024 16:49:13 +0100
Subject: [PATCH v1 7/8] ARM: dts: aspeed: system1: Mark GPIO line high/low
In-Reply-To: <20241213145037.3784931-8-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
 <20241213145037.3784931-8-ninad@linux.ibm.com>
Message-ID: <de59078c-8410-4c4f-bfce-db402e92635c@kernel.org>

On 13/12/2024 15:50, Ninad Palsule wrote:
> From: NINAD PALSULE <ninadpalsule at us.ibm.com>
> 
> - Mark following GPIO lines as input high:
>   - GPIOL4 (reset PCH registers)
>   - GPIOL5 (reset portition of intel ME)
> - Mark isolate errors from cpu1 gpio (GPIOO6) as active low output.
> - The fan controller reset line should be active high.
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
> ---
>  .../dts/aspeed/aspeed-bmc-ibm-system1.dts     | 28 +++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
> index ca2d4a292687..be0cd6152c61 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
> @@ -383,6 +383,34 @@ &gpio0 {
>  	/*X0-X7*/	"fpga-pgood","power-chassis-good","pch-pgood","","","","","",
>  	/*Y0-Y7*/	"","","","","","","","",
>  	/*Z0-Z7*/	"","","","","","","","";
> +
> +	rtc_reset {
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

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).
Maybe you need to update your dtschema and yamllint. Don't rely on
distro packages for dtschema and be sure you are using the latest
released dtschema.

Best regards,
Krzysztof


From devnull+ross.burton.arm.com at kernel.org  Fri Dec 13 08:12:58 2024
From: devnull+ross.burton.arm.com at kernel.org (Ross Burton via B4 Relay)
Date: Fri, 13 Dec 2024 16:12:58 +0000
Subject: [PATCH] arm64: defconfig: remove obsolete CONFIG_SM_DISPCC_8650
Message-ID: <20241213-clkmaster-v1-1-dcbf7fad37b1@arm.com>

From: Ross Burton <ross.burton at arm.com>

This option was removed from the Kconfig in commit 802b83205519 ("clk:
qcom: fold dispcc-sm8650 info dispcc-sm8550") but it was not removed
from the defconfig.

Fixes: 802b83205519 ("clk: qcom: fold dispcc-sm8650 info dispcc-sm8550")
Signed-off-by: Ross Burton <ross.burton at arm.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/configs/defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e6158633f07c1f3532fba62f09b31e7448..c6d6a31a8f48c7ce9c9ca74e29db3b8835bfd556 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1352,7 +1352,6 @@ CONFIG_SM_DISPCC_6115=m
 CONFIG_SM_DISPCC_8250=y
 CONFIG_SM_DISPCC_8450=m
 CONFIG_SM_DISPCC_8550=m
-CONFIG_SM_DISPCC_8650=m
 CONFIG_SM_GCC_4450=y
 CONFIG_SM_GCC_6115=y
 CONFIG_SM_GCC_8350=y

---
base-commit: 231825b2e1ff6ba799c5eaf396d3ab2354e37c6b
change-id: 20241213-clkmaster-558e5d7c966c

Best regards,
-- 
Ross Burton <ross.burton at arm.com>




From ninad at linux.ibm.com  Fri Dec 13 08:12:41 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Fri, 13 Dec 2024 10:12:41 -0600
Subject: [PATCH v1 1/4] hwmon: pmbus-core: Add label for fan and temp
In-Reply-To: <f9d881b7-7301-476e-b281-0380dfcf0e10@roeck-us.net>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
 <20241212214927.3586509-2-ninad@linux.ibm.com>
 <f9d881b7-7301-476e-b281-0380dfcf0e10@roeck-us.net>
Message-ID: <c7717f89-65cc-4668-a3e0-ee042cdcd426@linux.ibm.com>

Hello Guenter,

On 12/12/24 16:06, Guenter Roeck wrote:
> On 12/12/24 13:49, Ninad Palsule wrote:
>> Adding label files for fan and temperature sensors in the power supply.
>> The openbmc application dbus-sensor(psusensor) requires those files to
>> consfigure those sensors.
>> Note that prefix for temp label is temp[A..C] used instead of temp[1..3]
>> as dbus-sensor(psusensor) application calculate index based on last
>> digit in the name so we do not want to make index double digit after
>> appending page index.
>>
>> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
>
> We are not going to fix userspace problems in the kernel.
>
> Guenter
>

Thanks for the quick review.

Sorry I am not clear on this. I feel that it is better to support labels 
for temperature

sensors and fans like other. Are you saying we should not support these 
labels or

I need update in the patch to support them better?

Please let me know.

Thanks & Regards,

Ninad Palsule




From miko.lenczewski at arm.com  Fri Dec 13 08:17:26 2024
From: miko.lenczewski at arm.com (=?utf-8?Q?Miko=C5=82aj?= Lenczewski)
Date: Fri, 13 Dec 2024 16:17:26 +0000
Subject: [RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <20241211210243.GA17155@willie-the-truck>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
 <20241211154611.40395-3-miko.lenczewski@arm.com>
 <20241211210243.GA17155@willie-the-truck>
Message-ID: <20241213161726.GA30314@mazurka.cambridge.arm.com>

> > +static int do_conflict_abort(unsigned long far, unsigned long esr,
> > +			     struct pt_regs *regs)
> > +{
> > +	if (!system_supports_bbml2())
> > +		return do_bad(far, esr, regs);
> > +
> > +	/* if we receive a TLB conflict abort, we know that there are multiple
> > +	 * TLB entries that translate the same address range. the minimum set
> > +	 * of invalidations to clear these entries is implementation defined.
> > +	 * the maximum set is defined as either tlbi(vmalls12e1) or tlbi(alle1).
> > +	 *
> > +	 * if el2 is enabled and stage 2 translation enabled, this may be
> > +	 * raised as a stage 2 abort. if el2 is enabled but stage 2 translation
> > +	 * disabled, or if el2 is disabled, it will be raised as a stage 1
> > +	 * abort.
> > +	 *
> > +	 * local_flush_tlb_all() does a tlbi(vmalle1), which is enough to
> > +	 * handle a stage 1 abort.
> > +	 */
> > +
> > +	local_flush_tlb_all();
> > +
> > +	return 0;
> > +}
> 
> Can we actually guarantee that we make it this far without taking another
> abort? Given that I'm yet to see one of these things in the wild, I'm
> fairly opposed to pretending that we can handle them. We'd be much better
> off only violating BBM on CPUs that are known to handle the conflict
> gracefully. Judging by your later patch, this is practically keyed off
> the MIDR _anyway_...
> 
> Will

Thanks for reviewing. Apologies for the delay in responding, and for
spam (replied instead of group-replied).

There should not be an option to take another fault while performing the
handler, as long as the mappings covering the fault handler table or any
code in this path are not screwed with. This is discussed further in the
resent patch series [1].

The MIDR revisions will be fixed. I was confused as to which revisions
were affected on an earlier version of the series, and had missed
updating them. The kconfig workarounds should be correct in this regard.

[1]: https://lore.kernel.org/all/084c5ada-51af-4c1a-b50a-4401e62ddbd6 at arm.com/


From catalin.marinas at arm.com  Fri Dec 13 08:17:48 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 13 Dec 2024 16:17:48 +0000
Subject: [PATCH] arm64/signal: Silence spurious sparse warning storing
 GCSPR_EL0
In-Reply-To: <6d839dfb-0a85-44c5-90cc-2b2426353a5f@sirena.org.uk>
References: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
 <Z1hU0Ii-Sm9NHnhj@J2N7QTR9R3>
 <20c12aac-193e-43ae-9418-39db1af4ede9@sirena.org.uk>
 <Z1ht7X2LRw34pMJK@J2N7QTR9R3>
 <6d839dfb-0a85-44c5-90cc-2b2426353a5f@sirena.org.uk>
Message-ID: <Z1xeLCKoSWyn2sko@arm.com>

On Tue, Dec 10, 2024 at 04:52:49PM +0000, Mark Brown wrote:
> On Tue, Dec 10, 2024 at 04:35:57PM +0000, Mark Rutland wrote:
> > On Tue, Dec 10, 2024 at 03:44:29PM +0000, Mark Brown wrote:
> > > The spuriousness is arguable, from my point of view it's spurious in
> > > that we don't have the type of the system register we're writing to.
> 
> > All that I'm asking for here is a trivial rewording; make the title say
> > something like:
> 
> Yes, I had already removed the references to spurious and false positive
> locally and changed the unsigned long cast to a __force u64 cast.

I still have a slight preference for treating a sysreg value as an
integer and cast it to pointer when needed rather than using __force.

> > > With map_shadow_stack() it's a bit of an issue with letting users
> > > specify a size but yeah, we could do better there.
> 
> > I don't follow. The only place where size interacts with cap_ptr is when
> > we initialize cap_ptr, and there we're adding size to an integer type:
> 
> > 	cap_ptr = (unsigned long __user *)(addr + size -
> > 					   (cap_offset * sizeof(unsigned long)));
> 
> Ugh, addr is also not a pointer which I'd not noticed but still.

'addr' should stay as long in map_shadow_stack(). This matches mmap(),
mremap(), brk() etc. as they handle address space layout manipulation
(these functions also do not accept tagged pointers). map_shadow_stack()
does write a cap to memory but its primary functionality is not user
buffer access but rather memory layout management.

-- 
Catalin


From miko.lenczewski at arm.com  Fri Dec 13 08:21:03 2024
From: miko.lenczewski at arm.com (=?utf-8?Q?Miko=C5=82aj?= Lenczewski)
Date: Fri, 13 Dec 2024 16:21:03 +0000
Subject: [RFC PATCH v1 3/5] arm64: Add errata and workarounds for systems
 with broken BBML2
In-Reply-To: <86pllyrwke.wl-maz@kernel.org>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
 <20241211154611.40395-4-miko.lenczewski@arm.com>
 <86pllyrwke.wl-maz@kernel.org>
Message-ID: <20241213162103.GB30314@mazurka.cambridge.arm.com>

On Wed, Dec 11, 2024 at 04:52:49PM +0000, Marc Zyngier wrote:
> On Wed, 11 Dec 2024 15:45:04 +0000,
> Miko?aj Lenczewski <miko.lenczewski at arm.com> wrote:
> > 
> > There are systems which claim support for BBML2, but whose
> > implementation of this support is broken. Add a Kconfig erratum for each
> > of these systems, and a cpufeature workaround that forces the supported
> > BBM level on these systems to 0.
> > 
> > Signed-off-by: Miko?aj Lenczewski <miko.lenczewski at arm.com>
> > ---
> >  Documentation/arch/arm64/silicon-errata.rst |  32 ++++
> >  arch/arm64/Kconfig                          | 164 ++++++++++++++++++++
> >  arch/arm64/kernel/cpufeature.c              |  32 +++-
> >  3 files changed, 227 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index 100570a048c5..9ef8418e8410 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -1127,6 +1127,170 @@ config ARM64_ERRATUM_3194386
> >  
> >  	  If unsure, say Y.
> >  
> > +config ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
> > +	bool
> > +
> > +config ARM64_ERRATUM_3696250
> > +	bool "Neoverse-N2: workaround for broken BBM level 2 support"
> > +	default y
> > +	select ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT
> > +	help
> > +	  Affected Neoverse-N2 cores (r0p0, r0p1, r0p2, r0p3) declare
> 
> So you list a number of affected revisions...
> 
> [...]
> 
> > +static bool has_bbml2(const struct arm64_cpu_capabilities *entry,
> > +		      int scope)
> > +{
> > +	if (IS_ENABLED(CONFIG_ARM64_WORKAROUND_BROKEN_BBML2_SUPPORT)) {
> > +		static const struct midr_range broken_bbml2_list[] = {
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
> > +			MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
> > +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
> > +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> > +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
> > +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
> > +			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
> > +			{}
> 
> ... and yet you flag all versions as broken? So which one is it? If it
> is really the case that all versions are broken, then the text should
> be simplified. Otherwise, this should really list the broken versions.
> 
> The other thing is that I find it incredibly dangerous to rely on
> some config option to disable a feature that will absolutely eat your
> data if it is broken. I'd rather see the whole BBM-L2 being behind an
> option, and unconditionally check for b0rken CPUs.
> 
> Specially when it looks like there isn't a single CPU on the planet
> that implemented the feature correctly... :-/
> 
> Thanks,
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.

Thanks for reviewing. Apologies for the delay in responding, and for
spam (replied instead of group-replied).

The workaround kconfig entries should be correct here. The MIDR
revisions will be fixed in the next respin.

I agree that having a BBML2 option and unconditionally guarding against
broken cpus is better, will make that change.


From miko.lenczewski at arm.com  Fri Dec 13 08:24:36 2024
From: miko.lenczewski at arm.com (=?utf-8?Q?Miko=C5=82aj?= Lenczewski)
Date: Fri, 13 Dec 2024 16:24:36 +0000
Subject: [RESEND RFC PATCH v1 1/5] arm64: Add TLB Conflict Abort
 Exception handler to KVM
In-Reply-To: <86o71irucr.wl-maz@kernel.org>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-2-miko.lenczewski@arm.com>
 <86o71irucr.wl-maz@kernel.org>
Message-ID: <20241213162436.GC30314@mazurka.cambridge.arm.com>

Apologies again for spam (replied instead of group-replied).

On Wed, Dec 11, 2024 at 05:40:36PM +0000, Marc Zyngier wrote:
> On Wed, 11 Dec 2024 16:01:37 +0000,
> Miko?aj Lenczewski <miko.lenczewski at arm.com> wrote:
> > 
> > Currently, KVM does not handle the case of a stage 2 TLB conflict abort
> > exception. The Arm ARM specifies that the worst-case handling of such an
> > exception requires a `tlbi vmalls12e1`.
> 
> Not quite. It says (I_JCCRT):
> 
> <quote>
> * For the EL1&0 translation regime, when stage 2 translations are in
>   use, either VMALLS12E1 or ALLE1.
> </quote>
> 
> > Perform such an invalidation when this exception is encountered.
> 
> What you fail to describe is *why* this is needed. You know it, I know
> it, but not everybody does. A reference to the ARM ARM would
> definitely be helpful.
> 

You are correct. Will update the commit message.

> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index c9d46ad57e52..c8c6f5a97a1b 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -1756,6 +1756,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
> >  	ipa = fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
> >  	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
> >  
> > +	if (esr_fsc_is_tlb_conflict_abort(esr)) {
> > +		// does a `tlbi vmalls12e1is`
> 
> nit: this isn't a very useful comment.
> 

Will remove it.

> > +		__kvm_tlb_flush_vmid(&vcpu->kvm->arch.mmu);
> > +		return 1;
> > +	}
> 
> That's not enough, unfortunately. A nested VM has *many* VMIDs (the
> flattening of all translation contexts that the guest uses).
> 
> So you can either iterate over all the valid VMIDs owned by this
> guest, or more simply issue a TLBI ALLE1, which will do the trick in a
> much more efficient way.
> 
> The other thing is that you are using an IS invalidation, which is
> farther reaching than necessary. Why would you invalidate the TLBs for
> CPUs that are only innocent bystanders? A non-shareable invalidation
> seems preferable to me.
>

You are completely correct here. I had forgotten about nested VMs, and
agree that issuing a `tlbi alle1` is simpler and more efficient. I agree
also on not using an IS invalidation.


From catalin.marinas at arm.com  Fri Dec 13 08:26:40 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 13 Dec 2024 16:26:40 +0000
Subject: [PATCH v2] arm64/signal: Silence sparse warning storing GCSPR_EL0
In-Reply-To: <20241211-arm64-gcs-signal-sparse-v2-1-c22f37216135@kernel.org>
References: <20241211-arm64-gcs-signal-sparse-v2-1-c22f37216135@kernel.org>
Message-ID: <Z1xgQGNZzR6h0Uly@arm.com>

On Wed, Dec 11, 2024 at 01:00:35AM +0000, Mark Brown wrote:
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 14ac6fdb872b9672e4b16a097f1b577aae8dec50..08d51fabdb9d47c848f14c9b25d6be04f109c2ee 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -39,7 +39,7 @@
>  #ifdef CONFIG_ARM64_GCS
>  #define GCS_SIGNAL_CAP(addr) (((unsigned long)addr) & GCS_CAP_ADDR_MASK)
>  
> -static bool gcs_signal_cap_valid(u64 addr, u64 val)
> +static bool gcs_signal_cap_valid(unsigned long __user *addr, u64 val)
>  {
>  	return val == GCS_SIGNAL_CAP(addr);
>  }

Another personal preference - addresses should be (unsigned long),
pointer to be accessed (... __user *). But we could even scrap this
function, there's a single caller to a one-line function.

> @@ -1094,15 +1094,15 @@ static int gcs_restore_signal(void)
>  	/*
>  	 * Check that the cap is the actual GCS before replacing it.
>  	 */
> -	if (!gcs_signal_cap_valid((u64)gcspr_el0, cap))
> +	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);
> +	put_user_gcs(0, gcspr_el0, &ret);
>  	if (ret != 0)
>  		return -EFAULT;
>  
> -	write_sysreg_s(gcspr_el0 + 1, SYS_GCSPR_EL0);
> +	write_sysreg_s((__force u64)(gcspr_el0 + 1), SYS_GCSPR_EL0);
>  
>  	return 0;
>  }

Looking through the code, do we have a similar problem in
gcs_signal_entry()? Or do we rely on sparse ignoring (unsigned long)
casts?

Whichever way we go, I think we should have consistency between these
two functions.

-- 
Catalin


From catalin.marinas at arm.com  Fri Dec 13 08:29:06 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 13 Dec 2024 16:29:06 +0000
Subject: [PATCH v2] kselftest/arm64: abi: fix SVCR detection
In-Reply-To: <20241211111639.12344-1-o451686892@gmail.com>
References: <20241211111639.12344-1-o451686892@gmail.com>
Message-ID: <173410734417.60926.833029036075275376.b4-ty@arm.com>

On Wed, 11 Dec 2024 19:16:39 +0800, Weizhao Ouyang wrote:
> When using svcr_in to check ZA and Streaming Mode, we should make sure
> that the value in x2 is correct, otherwise it may trigger an Illegal
> instruction if FEAT_SVE and !FEAT_SME.
> 
> 

Applied to arm64 (for-next/fixes), thanks!

[1/1] kselftest/arm64: abi: fix SVCR detection
      https://git.kernel.org/arm64/c/ce03573a1917

-- 
Catalin



From sebott at redhat.com  Fri Dec 13 08:31:44 2024
From: sebott at redhat.com (Sebastian Ott)
Date: Fri, 13 Dec 2024 17:31:44 +0100 (CET)
Subject: [PATCH v3 2/3] KVM: arm64: Introduce hypercall support for
 retrieving target implementations
In-Reply-To: <20241209115311.40496-3-shameerali.kolothum.thodi@huawei.com>
References: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com> <20241209115311.40496-3-shameerali.kolothum.thodi@huawei.com>
Message-ID: <0610c537-292a-1720-34d7-438524009cd4@redhat.com>

On Mon, 9 Dec 2024, Shameer Kolothum wrote:

> If the Guest requires migration to multiple targets, this hypercall
> will provide a way to retrieve the target CPU implementations from
> the user space VMM.
>
> Subsequent patch will use this to enable the associated errata.
>
> Suggested-by: Oliver Upton <oliver.upton at linux.dev>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>

Reviewed-by: Sebastian Ott <sebott at redhat.com>



From sebott at redhat.com  Fri Dec 13 08:31:19 2024
From: sebott at redhat.com (Sebastian Ott)
Date: Fri, 13 Dec 2024 17:31:19 +0100 (CET)
Subject: [PATCH v3 1/3] arm64: Modify _midr_range() functions to read
 MIDR/REVIDR internally
In-Reply-To: <20241209115311.40496-2-shameerali.kolothum.thodi@huawei.com>
References: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com> <20241209115311.40496-2-shameerali.kolothum.thodi@huawei.com>
Message-ID: <fa044f16-bfd1-7807-0810-301965e0f60a@redhat.com>

On Mon, 9 Dec 2024, Shameer Kolothum wrote:
> These changes lay the groundwork for adding support for guest kernels,
> allowing them to leverage target CPU implementations provided by the
> VMM.
>
> No functional changes intended.
>
> Suggested-by: Oliver Upton <oliver.upton at linux.dev>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>

Reviewed-by: Sebastian Ott <sebott at redhat.com>



From neil.armstrong at linaro.org  Fri Dec 13 08:32:20 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 13 Dec 2024 17:32:20 +0100
Subject: [PATCH] arm64: defconfig: remove obsolete CONFIG_SM_DISPCC_8650
In-Reply-To: <20241213-clkmaster-v1-1-dcbf7fad37b1@arm.com>
References: <20241213-clkmaster-v1-1-dcbf7fad37b1@arm.com>
Message-ID: <335fb7ff-35a0-44bb-981f-757204d829a8@linaro.org>

+ linux-arm-msm

On 13/12/2024 17:12, Ross Burton via B4 Relay wrote:
> From: Ross Burton <ross.burton at arm.com>
> 
> This option was removed from the Kconfig in commit 802b83205519 ("clk:
> qcom: fold dispcc-sm8650 info dispcc-sm8550") but it was not removed
> from the defconfig.
> 
> Fixes: 802b83205519 ("clk: qcom: fold dispcc-sm8650 info dispcc-sm8550")
> Signed-off-by: Ross Burton <ross.burton at arm.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>   arch/arm64/configs/defconfig | 1 -
>   1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index c62831e6158633f07c1f3532fba62f09b31e7448..c6d6a31a8f48c7ce9c9ca74e29db3b8835bfd556 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -1352,7 +1352,6 @@ CONFIG_SM_DISPCC_6115=m
>   CONFIG_SM_DISPCC_8250=y
>   CONFIG_SM_DISPCC_8450=m
>   CONFIG_SM_DISPCC_8550=m
> -CONFIG_SM_DISPCC_8650=m
>   CONFIG_SM_GCC_4450=y
>   CONFIG_SM_GCC_6115=y
>   CONFIG_SM_GCC_8350=y
> 
> ---
> base-commit: 231825b2e1ff6ba799c5eaf396d3ab2354e37c6b
> change-id: 20241213-clkmaster-558e5d7c966c
> 
> Best regards,

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From suzuki.poulose at arm.com  Fri Dec 13 08:38:06 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 13 Dec 2024 16:38:06 +0000
Subject: [PATCH v2 1/3] coresight: Update timeout functions to allow
 return of test register value
In-Reply-To: <20241213144919.110642-2-mike.leach@linaro.org>
References: <20241213144919.110642-1-mike.leach@linaro.org>
 <20241213144919.110642-2-mike.leach@linaro.org>
Message-ID: <0c13fbf6-3023-4f9e-9571-a9e8ca6e3402@arm.com>

Hi Mike

On 13/12/2024 14:49, Mike Leach wrote:
> Current coresight_timeout function spins on a bit on a test register,
> till bit value achieved or timeout hit.
> 
> Add another function to return the full value of the register being
> tested.
> 

The patch looks good to me. However, this change doesn't bring much 
value, other than avoiding a read at the caller side. I guess it is
simpler to leave things as is and let the caller read the register value
while logging rather than providing another variant.

I am inclined to keep the interface simpler.


> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>   drivers/hwtracing/coresight/coresight-core.c | 50 +++++++++++++++-----
>   include/linux/coresight.h                    |  2 +
>   2 files changed, 41 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index ea38ecf26fcb..feb1a1db355f 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -1017,32 +1017,37 @@ static void coresight_remove_conns(struct coresight_device *csdev)
>   }
>   
>   /**
> - * coresight_timeout - loop until a bit has changed to a specific register
> - *			state.
> + * coresight_timeout_retval - loop until a bit has changed to a specific register
> + *			      state. Return final register value
>    * @csa: coresight device access for the device
>    * @offset: Offset of the register from the base of the device.
>    * @position: the position of the bit of interest.
>    * @value: the value the bit should have.
> + * @rval:  the last read value of the register being tested.
>    *
>    * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
>    * TIMEOUT_US has elapsed, which ever happens first.
>    */
> -int coresight_timeout(struct csdev_access *csa, u32 offset,
> -		      int position, int value)
> +int coresight_timeout_retval(struct csdev_access *csa, u32 offset,
> +			     int position, int value, u32 *rval)
>   {
> -	int i;
> -	u32 val;
> +	int i, rc = -EAGAIN;
> +	u32 val = 0;
>   
>   	for (i = TIMEOUT_US; i > 0; i--) {
>   		val = csdev_access_read32(csa, offset);
>   		/* waiting on the bit to go from 0 to 1 */
>   		if (value) {
> -			if (val & BIT(position))
> -				return 0;
> +			if (val & BIT(position)) {
> +				rc = 0;
> +				goto return_rval;
> +			}
>   		/* waiting on the bit to go from 1 to 0 */
>   		} else {
> -			if (!(val & BIT(position)))
> -				return 0;
> +			if (!(val & BIT(position))) {
> +				rc = 0;
> +				goto return_rval;
> +			}
>   		}
>   
>   		/*
> @@ -1054,7 +1059,30 @@ int coresight_timeout(struct csdev_access *csa, u32 offset,
>   			udelay(1);
>   	}
>   
> -	return -EAGAIN;
> +return_rval:
> +	*rval = val;

super minor nit: we could be flexible in accepting a "NULL" rval and 
thus keep the normal variants pass the NULL straight in. i.e,

	if (rval)
		*rval = val;

> +
> +	return rc;
> +}
> +EXPORT_SYMBOL_GPL(coresight_timeout_retval);
> +
> +/**
> + * coresight_timeout - loop until a bit has changed to a specific register
> + *		       state
> + * @csa: coresight device access for the device
> + * @offset: Offset of the register from the base of the device.
> + * @position: the position of the bit of interest.
> + * @value: the value the bit should have.
> + *
> + * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
> + * TIMEOUT_US has elapsed, which ever happens first.
> + */
> +int coresight_timeout(struct csdev_access *csa, u32 offset,
> +		      int position, int value)
> +{
> +	u32 rval = 0;
> +
> +	return coresight_timeout_retval(csa, offset, position, value, &rval);

	return core_timeout_retval(csa, offset, position, value, NULL);

Suzuki

>   }
>   EXPORT_SYMBOL_GPL(coresight_timeout);
>   
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 055ce5cd5c44..29cb71e82b0b 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -639,6 +639,8 @@ extern int coresight_enable_sysfs(struct coresight_device *csdev);
>   extern void coresight_disable_sysfs(struct coresight_device *csdev);
>   extern int coresight_timeout(struct csdev_access *csa, u32 offset,
>   			     int position, int value);
> +extern int coresight_timeout_retval(struct csdev_access *csa, u32 offset,
> +				    int position, int value, u32 *rval);
>   
>   extern int coresight_claim_device(struct coresight_device *csdev);
>   extern int coresight_claim_device_unlocked(struct coresight_device *csdev);



From peter.griffin at linaro.org  Fri Dec 13 08:44:37 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 13 Dec 2024 16:44:37 +0000
Subject: [PATCH 0/4] Fix Google Tensor GS101 CPU hotplug support
Message-ID: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>

Hi folks,

As part of an effort to make suspend to RAM functional upstream on
Pixel 6 I noticed that CPU hotplug leads to a system hang.

After debugging and comparing with downstream drivers it became clear
that some extra register writes are required to make CPU hotplug
functional on these older devices which use the el3mon firmware.

This series adds support for programming the CPU_INFORM register hint
required by the firmware and also adds support for the pmu-intr-gen
register region. This is achieved using cpuhp_setup_state() to setup
a cpu hotplug state. This is similar to soc/xilinx/xlnx_event_manager.c
and soc/fsl/qbman/bman_portal.c drivers.

With these changes CPU hotplug is now functional :)

It can be tested with commands such as

echo 0 > /sys/devices/system/cpu/cpu6/online
echo 1 > /sys/devices/system/cpu/cpu6/online
[   15.880597][    T0] Detected PIPT I-cache on CPU6
[   15.880638][    T0] GICv3: CPU6: found redistributor 600 region 0:0x0000000010500000
[   15.880685][    T0] CPU6: Booted secondary processor 0x0000000600 [0x411fd440]

This would (prior to this series) hang the system.

Note 1: It is highly likely that similar changes are required for other
Exynos based SoCs using el3mon. For anyone following along who is
accustomed to looking at downstream Exynos based drivers this replaces
register writes defined in 

drivers/soc/<google|samsung>/cal-if/<socname>/flexpmu_cal_cpu_<socname>.h

Which are used by files in the cal-if folder and exynos-cpupm.c driver.

For the moment I've used the GS101 CPU inform register offsets directly
but these can be moved to driver data once we've established other SoCs
benefit from this.

Note 2: To ensure older DTs which don't define pmu-intr-gen register
region still work. The driver only issues a warning if the registers
can't be mapped, and the behaviour remains the same as today (system
boots, but CPU hotplug will not be functional).

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
Peter Griffin (4):
      dt-bindings: soc: samsung: exynos-pmu: gs101: add pmu-intr-gen reg region
      dt-bindings: mfd: syscon: allow two reg regions for gs101-pmu
      arm64: dts: exynos: gs101: add pmu-intr-gen regs to the PMU node
      soc: samsung: exynos-pmu: enable CPU hotplug support for gs101

 .../devicetree/bindings/mfd/syscon-common.yaml     | 10 +++
 .../bindings/soc/samsung/exynos-pmu.yaml           | 29 ++++++++-
 arch/arm64/boot/dts/exynos/google/gs101.dtsi       |  4 +-
 drivers/soc/samsung/exynos-pmu.c                   | 73 +++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h                   |  1 +
 include/linux/soc/samsung/exynos-regs-pmu.h        | 11 ++++
 6 files changed, 125 insertions(+), 3 deletions(-)
---
base-commit: ed9a4ad6e5bd3a443e81446476718abebee47e82
change-id: 20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-1f7ad4c45901

Best regards,
-- 
Peter Griffin <peter.griffin at linaro.org>



From peter.griffin at linaro.org  Fri Dec 13 08:44:38 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 13 Dec 2024 16:44:38 +0000
Subject: [PATCH 1/4] dt-bindings: soc: samsung: exynos-pmu: gs101: add
 pmu-intr-gen reg region
In-Reply-To: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
References: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
Message-ID: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-1-c72978f63713@linaro.org>

gs101 also requires access to the pmu interrupt generation register region.
Update the exynos-pmu bindings documentation to reflect this.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 .../bindings/soc/samsung/exynos-pmu.yaml           | 29 +++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
index 6cdfe7e059a3..5ac4864e4cde 100644
--- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
+++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
@@ -73,7 +73,11 @@ properties:
           - const: syscon
 
   reg:
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
+
+  reg-names:
+    maxItems: 2
 
   '#clock-cells':
     const: 1
@@ -186,6 +190,29 @@ allOf:
       properties:
         dp-phy: false
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - google,gs101-pmu
+    then:
+      properties:
+        reg:
+          items:
+            - description: PMU register region
+            - description: PMU Interrupt Generation register region
+        reg-names:
+          items:
+            - const: pmu
+            - const: pmu-intr-gen
+    else:
+      properties:
+        reg:
+          maxItems: 1
+        reg-name:
+          maxItems: 1
+
 examples:
   - |
     #include <dt-bindings/clock/exynos5250.h>

-- 
2.47.1.613.gc27f4b7a9f-goog



From peter.griffin at linaro.org  Fri Dec 13 08:44:39 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 13 Dec 2024 16:44:39 +0000
Subject: [PATCH 2/4] dt-bindings: mfd: syscon: allow two reg regions for
 gs101-pmu
In-Reply-To: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
References: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
Message-ID: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-2-c72978f63713@linaro.org>

To avoid dtschema warnings allow google,gs101-pmu to have
two reg regions.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
I don't really like this patch, but also didn't want to submit the series
with a dtschema warning ;-)

Possibly a better solution is when Robs patch
`mfd: syscon: Allow syscon nodes without a "syscon" compatible` [1]

gets updated with a v2, we could remove syscon compatible from
gs101.dtsi (an ABI issue). If I understood his patch correctly,
it would mean this yaml update would then no longer be required.

Let me know your thoughts

[1] https://lore.kernel.org/lkml/20241211-syscon-fixes-v1-0-b5ac8c219e96 at kernel.org/T/#m5ad1ed5c69f693d2a5cc54342a87fbdf3df756d2
---
 Documentation/devicetree/bindings/mfd/syscon-common.yaml | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/syscon-common.yaml b/Documentation/devicetree/bindings/mfd/syscon-common.yaml
index 451cbad467a3..9cd9739d5e97 100644
--- a/Documentation/devicetree/bindings/mfd/syscon-common.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon-common.yaml
@@ -59,6 +59,16 @@ allOf:
         compatible:
           minItems: 3
           maxItems: 5
+  - if:
+      properties:
+        compatible:
+          contains:
+            const:
+              - google,gs101-pmu
+  then:
+    properties:
+      reg:
+        maxItems: 2
 
 additionalProperties: true
 

-- 
2.47.1.613.gc27f4b7a9f-goog



From peter.griffin at linaro.org  Fri Dec 13 08:44:40 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 13 Dec 2024 16:44:40 +0000
Subject: [PATCH 3/4] arm64: dts: exynos: gs101: add pmu-intr-gen regs to
 the PMU node
In-Reply-To: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
References: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
Message-ID: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-3-c72978f63713@linaro.org>

These registers are required for cpu hotplug.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 302c5beb224a..93db14e16246 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -1393,7 +1393,9 @@ sysreg_apm: syscon at 174204e0 {
 
 		pmu_system_controller: system-controller at 17460000 {
 			compatible = "google,gs101-pmu", "syscon";
-			reg = <0x17460000 0x10000>;
+			reg = <0x17460000 0x10000>,
+			      <0x17470000 0x10000>;
+			reg-names = "pmu", "pmu-intr-gen";
 
 			poweroff: syscon-poweroff {
 				compatible = "syscon-poweroff";

-- 
2.47.1.613.gc27f4b7a9f-goog



From peter.griffin at linaro.org  Fri Dec 13 08:44:41 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 13 Dec 2024 16:44:41 +0000
Subject: [PATCH 4/4] soc: samsung: exynos-pmu: enable CPU hotplug support
 for gs101
In-Reply-To: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
References: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
Message-ID: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-4-c72978f63713@linaro.org>

Some additional register writes are required when hotplugging CPUs
on gs101, without these the system hangs when hotplugging.

Specifically a CPU_INFORM register needs to be programmed with
a hint value which is used by the EL3 firmware (el3mon) and the
pmu-intr-gen registers need to be programmed.

With this patch applied, and corresponding DT update CPU hotplug
now works as expected. e.g.

echo 0 > /sys/devices/system/cpu/cpu6/online
echo 1 > /sys/devices/system/cpu/cpu6/online

Note: to maintain compatibility with older DTs that didn't specify
pmu-intr-gen register region only a warning is issued if the
registers can't be mapped, and the old behaviour is maintained.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/soc/samsung/exynos-pmu.c            | 73 ++++++++++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h            |  1 +
 include/linux/soc/samsung/exynos-regs-pmu.h | 11 +++++
 3 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index d8c53cec7f37..68eb4eb3813b 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -6,6 +6,7 @@
 // Exynos - CPU PMU(Power Management Unit) support
 
 #include <linux/arm-smccc.h>
+#include <linux/cpuhotplug.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/mfd/core.h>
@@ -32,6 +33,7 @@ struct exynos_pmu_context {
 	struct device *dev;
 	const struct exynos_pmu_data *pmu_data;
 	struct regmap *pmureg;
+	void __iomem *pmuintrgen_base;
 };
 
 void __iomem *pmu_base_addr;
@@ -221,7 +223,8 @@ static const struct regmap_config regmap_smccfg = {
 };
 
 static const struct exynos_pmu_data gs101_pmu_data = {
-	.pmu_secure = true
+	.pmu_secure = true,
+	.pmu_cpuhp = true,
 };
 
 /*
@@ -325,6 +328,52 @@ struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
 
+/*
+ * CPU_INFORM register hint values which are used by
+ * EL3 firmware (el3mon).
+ */
+#define CPU_INFORM_CLEAR	0
+#define CPU_INFORM_C2		1
+
+static int cpuhp_pmu_online(unsigned int cpu)
+{
+	void __iomem *base = pmu_context->pmuintrgen_base;
+	u32 reg;
+	u32 mask;
+
+	/* clear cpu inform hint */
+	regmap_write(pmu_context->pmureg, GS101_CPU_INFORM(cpu),
+		     CPU_INFORM_CLEAR);
+
+	mask = (1 << cpu);
+
+	writel(((0 << cpu) & mask), base + GS101_GRP2_INTR_BID_ENABLE);
+
+	reg = readl(base + GS101_GRP2_INTR_BID_UPEND) & mask;
+	writel(reg & mask, base + GS101_GRP2_INTR_BID_CLEAR);
+
+	return 0;
+}
+
+static int cpuhp_pmu_offline(unsigned int cpu)
+{
+	void __iomem *base = pmu_context->pmuintrgen_base;
+	u32 reg, mask;
+
+	/* set cpu inform hint */
+	regmap_write(pmu_context->pmureg, GS101_CPU_INFORM(cpu),
+		     CPU_INFORM_C2);
+
+	writel((1 << cpu), base + GS101_GRP2_INTR_BID_ENABLE);
+
+	mask = ((1 << cpu) | (1 << (cpu+8)));
+
+	reg = readl(base + GS101_GRP1_INTR_BID_UPEND) & mask;
+	writel(reg & mask, base + GS101_GRP1_INTR_BID_CLEAR);
+
+	return 0;
+}
+
 static int exynos_pmu_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -377,6 +426,28 @@ static int exynos_pmu_probe(struct platform_device *pdev)
 	pmu_context->pmureg = regmap;
 	pmu_context->dev = dev;
 
+	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_cpuhp) {
+
+		pmu_context->pmuintrgen_base =
+			devm_platform_ioremap_resource_byname(pdev, "pmu-intr-gen");
+		/*
+		 * To maintain support for older DTs that didn't specify pmu-intr-gen
+		 * register region, just issue a warning rather than fail to probe.
+		 */
+		if (IS_ERR(pmu_context->pmuintrgen_base)) {
+			dev_warn(&pdev->dev,
+				 "failed to map pmu-intr-gen registers\n");
+		} else {
+			cpuhp_setup_state(CPUHP_BP_PREPARE_DYN,
+					"soc/exynos-pmu:prepare",
+					cpuhp_pmu_online, NULL);
+
+			cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
+					"soc/exynos-pmu:online",
+					NULL, cpuhp_pmu_offline);
+		}
+	}
+
 	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 0a49a2c9a08e..0938bb4fe15f 100644
--- a/drivers/soc/samsung/exynos-pmu.h
+++ b/drivers/soc/samsung/exynos-pmu.h
@@ -22,6 +22,7 @@ struct exynos_pmu_data {
 	const struct exynos_pmu_conf *pmu_config;
 	const struct exynos_pmu_conf *pmu_config_extra;
 	bool pmu_secure;
+	bool pmu_cpuhp;
 
 	void (*pmu_init)(void);
 	void (*powerdown_conf)(enum sys_powerdown);
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index ce1a3790d6fb..0d5a17ea8fb8 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -658,9 +658,20 @@
 #define EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION		(0x32A8)
 
 /* For Tensor GS101 */
+/* PMU ALIVE */
 #define GS101_SYSIP_DAT0					(0x810)
+#define GS101_CPU0_INFORM					(0x860)
+#define GS101_CPU_INFORM(cpu)	\
+			(GS101_CPU0_INFORM + (cpu*4))
 #define GS101_SYSTEM_CONFIGURATION				(0x3A00)
 #define GS101_PHY_CTRL_USB20					(0x3EB0)
 #define GS101_PHY_CTRL_USBDP					(0x3EB4)
 
+/* PMU INTR GEN */
+#define GS101_GRP1_INTR_BID_UPEND				(0x0108)
+#define GS101_GRP1_INTR_BID_CLEAR				(0x010c)
+#define GS101_GRP2_INTR_BID_ENABLE				(0x0200)
+#define GS101_GRP2_INTR_BID_UPEND				(0x0208)
+#define GS101_GRP2_INTR_BID_CLEAR				(0x020c)
+
 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */

-- 
2.47.1.613.gc27f4b7a9f-goog



From sebott at redhat.com  Fri Dec 13 08:45:52 2024
From: sebott at redhat.com (Sebastian Ott)
Date: Fri, 13 Dec 2024 17:45:52 +0100 (CET)
Subject: [PATCH v3 3/3] arm64: paravirt: Enable errata based on implementation
 CPUs
In-Reply-To: <20241209115311.40496-4-shameerali.kolothum.thodi@huawei.com>
References: <20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com> <20241209115311.40496-4-shameerali.kolothum.thodi@huawei.com>
Message-ID: <09f590eb-fb3e-6a5c-512a-440613d79c5b@redhat.com>

On Mon, 9 Dec 2024, Shameer Kolothum wrote:

> Retrieve any migration target implementation CPUs using the hypercall
> and enable associated errata.
>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
> Note:
>
> One thing I am not sure here is how to handle the hypercall error.
> Do we need to fail the Guest boot or just carry on without any
> target implementation CPU support? At the moment it just carries on.
>

I vote for keeping the current behavior. This way the vmm could just
decide to never migrate this vm and if the vmm figures that the issue
is so severe that the vm should not continue it has the power to do so.

Reviewed-by: Sebastian Ott <sebott at redhat.com>



From Liam.Howlett at oracle.com  Fri Dec 13 08:45:32 2024
From: Liam.Howlett at oracle.com (Liam R. Howlett)
Date: Fri, 13 Dec 2024 11:45:32 -0500
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
In-Reply-To: <9675c409-b495-46a5-a90c-c952892b4121@lucifer.local>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
 <hmuzfspqjzb36xlj2x44keihacrrhzj5madqrfbcnhqouzredv@wo75achgkuh5>
 <1818e2ea-f170-4a9c-8d93-2a24f2755a41@lucifer.local>
 <20241212173609.afd41d1dffbefe0d731ed4ed@linux-foundation.org>
 <695eabb8-ba28-4031-bc4d-66dc4f1d096f@lucifer.local>
 <CAC_TJvcdz854DmBoVRkb_B5j+u-t=4zHkLtHVeB5RJ=bXcBJag@mail.gmail.com>
 <9675c409-b495-46a5-a90c-c952892b4121@lucifer.local>
Message-ID: <x2y7rewvmri25wj72qaeuunqqsqj7pqcliahoxkprcbfxg5owv@icvnojkhrdch>

* Lorenzo Stoakes <lorenzo.stoakes at oracle.com> [241213 10:16]:
> On Fri, Dec 13, 2024 at 10:06:55AM -0500, Kalesh Singh wrote:
> > On Fri, Dec 13, 2024 at 4:00?AM Lorenzo Stoakes
> > <lorenzo.stoakes at oracle.com> wrote:

...

> >
> > On the technical side, Liam is right that the copy-pasted arch code
> > has inconsistencies (missing checks, order of checks, ...). I agree
> > there?s room for further consolidation. I?ll take another stab at it
> > and resend it as an RFC with an updated cover letter, as Lorenzo and
> > others suggested.

Thanks.  Can you please include what platforms you have tested in your
cover letter (and level of testing - booting, running something, etc).

If you have not tested them, then it might be worth it to have it as an
RFC to point this out - at least initially.  Some of these are very
difficult to set up for testing, but it is also possible that you did
that and the maintainers/people who usually test these things will
assume it's fine if you don't spell out what's going on.

> 
> The most useful thing here as well to help us understand would be to write
> more in the cover letter to expand on what it is you ultimately what to
> achieve here - it seems like an extension on the existing THP work on a
> per-arch basis (I may be wrong)? So adding more detail would be super
> useful here! :)
> 
> We do hope to avoid arch hooks if at all possible explicitly for the reason
> that they can be applied at unfortunate times in terms of locking/whether
> the objects in question are fully/partially instantiated, VMA visibility
> etc. etc. based on having had issues in these areas before.
> 
> Also if a hook means 'anything' can happen at a certain point, it means we
> can't make any assumptions about what has/hasn't and have to account for
> anything which seriously complicates things.
> 
> Ideally we'd find a means to achieve the same thing while also exposing us
> as little as possible to what may be mutated.


Yes, I'm not sure of what your plans are, but I would like to see all of
these custom functions removed, if at all possible.

Thanks,
Liam


From miko.lenczewski at arm.com  Fri Dec 13 08:49:39 2024
From: miko.lenczewski at arm.com (=?utf-8?Q?Miko=C5=82aj?= Lenczewski)
Date: Fri, 13 Dec 2024 16:49:39 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <87cyhxs3xq.wl-maz@kernel.org>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-3-miko.lenczewski@arm.com>
 <87cyhxs3xq.wl-maz@kernel.org>
Message-ID: <20241213164939.GD30314@mazurka.cambridge.arm.com>

On Thu, Dec 12, 2024 at 08:25:53AM +0000, Marc Zyngier wrote:
> Ah, so this is where this is hiding. I missed it in my review of patch
> #1 yesterday.
> 
> On Wed, 11 Dec 2024 16:01:38 +0000,
> Miko?aj Lenczewski <miko.lenczewski at arm.com> wrote:
> > 
> > The Break-Before-Make cpu feature supports multiple levels (levels 0-2),
> > and this commit adds a dedicated BBML2 cpufeature to test against
> > support for.
> > 
> > In supporting BBM level 2, we open ourselves up to potential TLB
> > Conflict Abort Exceptions during expected execution, instead of only
> > in exceptional circumstances. In the case of an abort, it is
> > implementation defined at what stage the abort is generated, and
> 
> *IF* stage-2 is enabled. Also, in the case of the EL2&0 translation
> regime, no stage-2 applies, so it can only be a stage-1 abort.
> 
> > the minimal set of required invalidations is also implementation
> > defined. The maximal set of invalidations is to do a `tlbi vmalle1`
> > or `tlbi vmalls12e1`, depending on the stage.
> > 
> > Such aborts should not occur on Arm hardware, and were not seen in
> > benchmarked systems, so unless performance concerns arise, implementing
> 
> Which systems? Given that you have deny-listed *all* half recent ARM
> Ltd implementations, I'm a bit puzzled.
> 

I had tested on an earlier series of the patchset that didn't introduce
the MIDR checks (has_bbml2() only read the claimed level of support),
but otherwise had the same implementation.

> >
> > +static inline bool system_supports_bbml2(void)
> > +{
> > +	/* currently, BBM is only relied on by code touching the userspace page
> > +	 * tables, and as such we are guaranteed that caps have been finalised.
> > +	 *
> > +	 * if later we want to use BBM for kernel mappings, particularly early
> > +	 * in the kernel, this may return 0 even if BBML2 is actually supported,
> > +	 * which means unnecessary break-before-make sequences, but is still
> > +	 * correct
> 
> Comment style, capitalisation, punctuation.
> 
> > +	if (!system_supports_bbml2())
> > +		return do_bad(far, esr, regs);
> > +
> > +	/* if we receive a TLB conflict abort, we know that there are multiple
> > +	 * TLB entries that translate the same address range. the minimum set
> > +	 * of invalidations to clear these entries is implementation defined.
> > +	 * the maximum set is defined as either tlbi(vmalls12e1) or tlbi(alle1).
> > +	 *
> > +	 * if el2 is enabled and stage 2 translation enabled, this may be
> > +	 * raised as a stage 2 abort. if el2 is enabled but stage 2 translation
> > +	 * disabled, or if el2 is disabled, it will be raised as a stage 1
> > +	 * abort.
> > +	 *
> > +	 * local_flush_tlb_all() does a tlbi(vmalle1), which is enough to
> > +	 * handle a stage 1 abort.
> 
> Same comment about comments.
> 

Will fix.

Kind regard,
Miko?aj


From broonie at kernel.org  Fri Dec 13 08:45:04 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 13 Dec 2024 16:45:04 +0000
Subject: [PATCH v2] arm64/signal: Silence sparse warning storing GCSPR_EL0
In-Reply-To: <Z1xgQGNZzR6h0Uly@arm.com>
References: <20241211-arm64-gcs-signal-sparse-v2-1-c22f37216135@kernel.org>
 <Z1xgQGNZzR6h0Uly@arm.com>
Message-ID: <418e279e-0628-473f-bd3c-4aa5e2d4dbcc@sirena.org.uk>

On Fri, Dec 13, 2024 at 04:26:40PM +0000, Catalin Marinas wrote:
> On Wed, Dec 11, 2024 at 01:00:35AM +0000, Mark Brown wrote:

> > -static bool gcs_signal_cap_valid(u64 addr, u64 val)
> > +static bool gcs_signal_cap_valid(unsigned long __user *addr, u64 val)
> >  {
> >  	return val == GCS_SIGNAL_CAP(addr);
> >  }

> Another personal preference - addresses should be (unsigned long),
> pointer to be accessed (... __user *). But we could even scrap this
> function, there's a single caller to a one-line function.

I'm not sure I follow what you're saying here - the pointer here is an
unsigned long __user *?  The value in val is not a pointer or address,
it's a cap value derived from a pointer.  But yeah, we could inline and
render it moot.

> > -	write_sysreg_s(gcspr_el0 + 1, SYS_GCSPR_EL0);
> > +	write_sysreg_s((__force u64)(gcspr_el0 + 1), SYS_GCSPR_EL0);

> Looking through the code, do we have a similar problem in
> gcs_signal_entry()? Or do we rely on sparse ignoring (unsigned long)
> casts?

> Whichever way we go, I think we should have consistency between these
> two functions.

It's not coming up since there's a cast to unsigned long in there which
sparse likes, I can adjust that to a cast to __force u64 in there since
people didn't seem to like the cast to unsigned long.
-------------- 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/20241213/1fd7f350/attachment.sig>

From miko.lenczewski at arm.com  Fri Dec 13 08:53:09 2024
From: miko.lenczewski at arm.com (=?utf-8?Q?Miko=C5=82aj?= Lenczewski)
Date: Fri, 13 Dec 2024 16:53:09 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <86h678sy00.wl-maz@kernel.org>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-3-miko.lenczewski@arm.com>
 <87cyhxs3xq.wl-maz@kernel.org>
 <084c5ada-51af-4c1a-b50a-4401e62ddbd6@arm.com>
 <86ikrprn7w.wl-maz@kernel.org>
 <2b1cc228-a8d5-4383-ab25-abbbcccd2e2c@arm.com>
 <86h678sy00.wl-maz@kernel.org>
Message-ID: <20241213165309.GE30314@mazurka.cambridge.arm.com>

> > 
> > From the ARM:
> > """
> > RFCPSG: If level 1 or level 2 is supported and the Contiguous bit in a set of
> > Block descriptors or Page descriptors is changed, then a TLB conflict abort can
> > be generated because multiple translation table entries might exist within a TLB
> > that translates the same IA.
> > """
> > 
> > Although I guess it's not totally explicit, I've interpretted that as saying
> > that conflicting TLB entries can only arise for the IA range for which the
> > contiguous bits have been modified in the translation tables.
> 
> Right, that's reassuring, thanks for digging that one.
> 

Thanks Ryan, will improve the comment and commit messages to make this
clearer and to include references to this information.

> > > If anything, this should absolutely check for FAR_EL1 and assert that
> > > this is indeed caused by such change.
> > 
> > I'm not really sure how we would check this reliably? Without patch 5, the
> > problem is somewhat constrained; we could have as many changes in flight as
> > there are CPUs so we could keep a list of all the {mm_struct, VA-range} that are
> > being modified. But if patch 5 is confirmed to be architecturally sound, then
> > there is no "terminating tlbi" so there is no bound on the set of {mm_struct,
> > VA-range}'s that could legitimately cause a conflict abort.
> 
> I didn't mean to imply that we should identify the exact cause of the
> abort. I was hoping to simply check that FAR_EL1 reports a userspace
> VA. Why wouldn't that work?
> 

Will do so.

Kind regards,
Miko?aj


From maz at kernel.org  Fri Dec 13 09:05:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 13 Dec 2024 17:05:03 +0000
Subject: [PATCH 2/3] irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
In-Reply-To: <20241213145809.2918-2-ubizjak@gmail.com>
References: <20241213145809.2918-1-ubizjak@gmail.com>
	<20241213145809.2918-2-ubizjak@gmail.com>
Message-ID: <86cyhvsedc.wl-maz@kernel.org>

On Fri, 13 Dec 2024 14:57:53 +0000,
Uros Bizjak <ubizjak at gmail.com> wrote:
> 
> percpu_base is used in various percpu functions that expect variable in
> __percpu address space. Correct the declaration of percpu_base to
> 
> void __iomem * __percpu *percpu_base;
> 
> to declare the variable as __percpu pointer.
> 
> The patch fixes several sparse warnings:
> 
> irq-gic.c:1172:44: warning: incorrect type in assignment (different address spaces)
> irq-gic.c:1172:44:    expected void [noderef] __percpu *[noderef] __iomem *percpu_base
> irq-gic.c:1172:44:    got void [noderef] __iomem *[noderef] __percpu *
> ...
> irq-gic.c:1184:26: warning: incorrect type in initializer (different address spaces)
> irq-gic.c:1184:26:    expected void const [noderef] __percpu *__vpp_verify
> irq-gic.c:1184:26:    got void [noderef] __percpu *[noderef] __iomem *
> ...
> irq-gic.c:1184:71: warning: incorrect type in assignment (different address spaces)
> irq-gic.c:1184:71:    expected void [noderef] __percpu *
> irq-gic.c:1184:71:    got void [noderef] __iomem *
> ...
> irq-gic.c:1231:43: warning: incorrect type in argument 1 (different address spaces)
> irq-gic.c:1231:43:    expected void [noderef] __percpu *__pdata
> irq-gic.c:1231:43:    got void [noderef] __percpu *[noderef] __iomem *percpu_base
> 
> There were no changes in the resulting object files.
> 
> Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> ---
>  drivers/irqchip/irq-gic.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 8fae6dc01024..6503573557fd 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -64,7 +64,7 @@ static void gic_check_cpu_features(void)
>  
>  union gic_base {
>  	void __iomem *common_base;
> -	void __percpu * __iomem *percpu_base;
> +	void __iomem * __percpu *percpu_base;
>  };
>  
>  struct gic_chip_data {

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

	M.

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


From linux at roeck-us.net  Fri Dec 13 09:08:30 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Fri, 13 Dec 2024 09:08:30 -0800
Subject: [PATCH v1 1/4] hwmon: pmbus-core: Add label for fan and temp
In-Reply-To: <c7717f89-65cc-4668-a3e0-ee042cdcd426@linux.ibm.com>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
 <20241212214927.3586509-2-ninad@linux.ibm.com>
 <f9d881b7-7301-476e-b281-0380dfcf0e10@roeck-us.net>
 <c7717f89-65cc-4668-a3e0-ee042cdcd426@linux.ibm.com>
Message-ID: <2713e85d-f88a-49d6-8221-151e8631758c@roeck-us.net>

On 12/13/24 08:12, Ninad Palsule wrote:
> Hello Guenter,
> 
> On 12/12/24 16:06, Guenter Roeck wrote:
>> On 12/12/24 13:49, Ninad Palsule wrote:
>>> Adding label files for fan and temperature sensors in the power supply.
>>> The openbmc application dbus-sensor(psusensor) requires those files to
>>> consfigure those sensors.
>>> Note that prefix for temp label is temp[A..C] used instead of temp[1..3]
>>> as dbus-sensor(psusensor) application calculate index based on last
>>> digit in the name so we do not want to make index double digit after
>>> appending page index.
>>>
>>> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
>>
>> We are not going to fix userspace problems in the kernel.
>>
>> Guenter
>>
> 
> Thanks for the quick review.
> 
> Sorry I am not clear on this. I feel that it is better to support labels for temperature
> 
> sensors and fans like other. Are you saying we should not support these labels or
> 
> I need update in the patch to support them better?
> 

There should be no such labels. Labels are supposed to have specific meanings,
such as "this is the CPU temperature sensor", not vague meanings such as "tempA".

Guenter



From kaleshsingh at google.com  Fri Dec 13 09:08:18 2024
From: kaleshsingh at google.com (Kalesh Singh)
Date: Fri, 13 Dec 2024 12:08:18 -0500
Subject: [PATCH mm-unstable v2 00/16] mm: Introduce arch_mmap_hint()
In-Reply-To: <x2y7rewvmri25wj72qaeuunqqsqj7pqcliahoxkprcbfxg5owv@icvnojkhrdch>
References: <20241211232754.1583023-1-kaleshsingh@google.com>
 <hmuzfspqjzb36xlj2x44keihacrrhzj5madqrfbcnhqouzredv@wo75achgkuh5>
 <1818e2ea-f170-4a9c-8d93-2a24f2755a41@lucifer.local> <20241212173609.afd41d1dffbefe0d731ed4ed@linux-foundation.org>
 <695eabb8-ba28-4031-bc4d-66dc4f1d096f@lucifer.local> <CAC_TJvcdz854DmBoVRkb_B5j+u-t=4zHkLtHVeB5RJ=bXcBJag@mail.gmail.com>
 <9675c409-b495-46a5-a90c-c952892b4121@lucifer.local> <x2y7rewvmri25wj72qaeuunqqsqj7pqcliahoxkprcbfxg5owv@icvnojkhrdch>
Message-ID: <CAC_TJvdZxQ0-O3Y1bzH0-XdjQYuJPkkpn-umVan--Z6As-tSow@mail.gmail.com>

On Fri, Dec 13, 2024 at 11:45?AM 'Liam R. Howlett' via kernel-team
<kernel-team at android.com> wrote:
>
> * Lorenzo Stoakes <lorenzo.stoakes at oracle.com> [241213 10:16]:
> > On Fri, Dec 13, 2024 at 10:06:55AM -0500, Kalesh Singh wrote:
> > > On Fri, Dec 13, 2024 at 4:00?AM Lorenzo Stoakes
> > > <lorenzo.stoakes at oracle.com> wrote:
>
> ...
>
> > >
> > > On the technical side, Liam is right that the copy-pasted arch code
> > > has inconsistencies (missing checks, order of checks, ...). I agree
> > > there?s room for further consolidation. I?ll take another stab at it
> > > and resend it as an RFC with an updated cover letter, as Lorenzo and
> > > others suggested.
>
> Thanks.  Can you please include what platforms you have tested in your
> cover letter (and level of testing - booting, running something, etc).
>
> If you have not tested them, then it might be worth it to have it as an
> RFC to point this out - at least initially.  Some of these are very
> difficult to set up for testing, but it is also possible that you did
> that and the maintainers/people who usually test these things will
> assume it's fine if you don't spell out what's going on.
>

I build-tested most of these except (csky and loongarch) and ran
android runtime (ART) tests on arm64 and x86. I can try to spin up a
few of the others and will add it to the description.

> >
> > The most useful thing here as well to help us understand would be to write
> > more in the cover letter to expand on what it is you ultimately what to
> > achieve here - it seems like an extension on the existing THP work on a
> > per-arch basis (I may be wrong)? So adding more detail would be super
> > useful here! :)
> >
> > We do hope to avoid arch hooks if at all possible explicitly for the reason
> > that they can be applied at unfortunate times in terms of locking/whether
> > the objects in question are fully/partially instantiated, VMA visibility
> > etc. etc. based on having had issues in these areas before.
> >
> > Also if a hook means 'anything' can happen at a certain point, it means we
> > can't make any assumptions about what has/hasn't and have to account for
> > anything which seriously complicates things.
> >
> > Ideally we'd find a means to achieve the same thing while also exposing us
> > as little as possible to what may be mutated.
>
>
> Yes, I'm not sure of what your plans are, but I would like to see all of
> these custom functions removed, if at all possible.

Initially I think we can remove the mmap hint portion of the logic;
and follow up with removing arch_get_unmapped_area[_topdown](). Some
of those may not make sense to consolidate e.g. powerpc's
slice_get_unmapped_area() which doesn't share much in common with the
rest.

Thanks,
Kalesh

>
> Thanks,
> Liam
>
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe at android.com.
>


From maz at kernel.org  Fri Dec 13 09:15:27 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 13 Dec 2024 17:15:27 +0000
Subject: [PATCH 1/3] KVM: arm64: timers: Fix percpu address space issues in kvm_timer_hyp_init()
In-Reply-To: <20241213145809.2918-1-ubizjak@gmail.com>
References: <20241213145809.2918-1-ubizjak@gmail.com>
Message-ID: <86bjxfsdw0.wl-maz@kernel.org>

On Fri, 13 Dec 2024 14:57:52 +0000,
Uros Bizjak <ubizjak at gmail.com> wrote:
> 
> Cast return value from kvm_get_running_vcpus() in the __percpu
> address space to the generic address space via uintptr_t [1]
> to fix a couple of:
> 
> arch_timer.c:1395:66: warning: incorrect type in argument 2 (different address spaces)
> arch_timer.c:1395:66:    expected void *vcpu_info
> arch_timer.c:1395:66:    got struct kvm_vcpu *[noderef] __percpu *
> 
> sparse warnings.
> 
> There were no changes in the resulting object files.
> 
> [1] https://sparse.docs.kernel.org/en/latest/annotations.html#address-space-name
> 
> Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oliver.upton at linux.dev>
> Cc: Joey Gouly <joey.gouly 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>
> ---
>  arch/arm64/kvm/arch_timer.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 1215df590418..a13bb9e8dc19 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -1392,7 +1392,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
>  
>  	if (has_gic) {
>  		err = irq_set_vcpu_affinity(host_vtimer_irq,
> -					    kvm_get_running_vcpus());
> +					    (void *)(uintptr_t)kvm_get_running_vcpus());
>  		if (err) {
>  			kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
>  			goto out_free_vtimer_irq;
> @@ -1416,7 +1416,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
>  
>  		if (has_gic) {
>  			err = irq_set_vcpu_affinity(host_ptimer_irq,
> -						    kvm_get_running_vcpus());
> +						    (void *)(uintptr_t)kvm_get_running_vcpus());
>  			if (err) {
>  				kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
>  				goto out_free_ptimer_irq;

I think the fix is worse than the current code, because there is no
real semantics behind the pointer being passed to
irq_set_vcpu_affinity(). All that is required is that it is a non-NULL
pointer.

I expect the following hack to work just as well and not suffer from
any sparse indigestion. Untested though.

	M.

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 1215df5904185..8058d92048fb4 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -1391,8 +1391,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
 	}
 
 	if (has_gic) {
-		err = irq_set_vcpu_affinity(host_vtimer_irq,
-					    kvm_get_running_vcpus());
+		err = irq_set_vcpu_affinity(host_vtimer_irq, info);
 		if (err) {
 			kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
 			goto out_free_vtimer_irq;
@@ -1415,8 +1414,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
 		}
 
 		if (has_gic) {
-			err = irq_set_vcpu_affinity(host_ptimer_irq,
-						    kvm_get_running_vcpus());
+			err = irq_set_vcpu_affinity(host_ptimer_irq, info);
 			if (err) {
 				kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
 				goto out_free_ptimer_irq;

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


From lee at kernel.org  Fri Dec 13 09:15:29 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 13 Dec 2024 17:15:29 +0000
Subject: [PATCH v6 2/7] mfd: nxp-siul2: add support for NXP SIUL2
In-Reply-To: <3b090335-20b4-4d73-aabc-ddac98311e33@sirena.org.uk>
References: <20241113101124.1279648-1-andrei.stefanescu@oss.nxp.com>
 <20241113101124.1279648-3-andrei.stefanescu@oss.nxp.com>
 <20241211124454.GE7139@google.com>
 <3b090335-20b4-4d73-aabc-ddac98311e33@sirena.org.uk>
Message-ID: <20241213171529.GF2418536@google.com>

On Wed, 11 Dec 2024, Mark Brown wrote:

> On Wed, Dec 11, 2024 at 12:45:56PM +0000, Lee Jones wrote:
> 
> > Seeing as the vast majority of this 400 line driver pertains to Regmap
> > handling (!), would you be kind enough to cast your expert eye over it
> > please?
> 
> Is there something specific you're concerned about there?  It looks like
> it's just data which should be fine.

Just the mass of complex hoop-jumping to get all of these Regmaps
registered.  But if nothing stands out to you, then it's probably okay.

Still, I can't review / take this until it's a proper MFD.

-- 
Lee Jones [???]


From Frank.li at nxp.com  Fri Dec 13 09:20:40 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 13 Dec 2024 12:20:40 -0500
Subject: [PATCH v8 2/2] PCI: imx6: Add IOMMU and ITS MSI support for
 i.MX95
In-Reply-To: <Z1v/LCHsGOgnasuf@lpieralisi>
References: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
 <20241210-imx95_lut-v8-2-2e730b2e5fde@nxp.com>
 <Z1sTUaoA5yk9RcIc@lpieralisi>
 <Z1sdbH7N1Ly9eXc0@lizhi-Precision-Tower-5810>
 <Z1v/LCHsGOgnasuf@lpieralisi>
Message-ID: <Z1xs6GkcdTg2c73F@lizhi-Precision-Tower-5810>

On Fri, Dec 13, 2024 at 10:32:28AM +0100, Lorenzo Pieralisi wrote:
> On Thu, Dec 12, 2024 at 12:29:16PM -0500, Frank Li wrote:
> > On Thu, Dec 12, 2024 at 05:46:09PM +0100, Lorenzo Pieralisi wrote:
> > > On Tue, Dec 10, 2024 at 05:48:59PM -0500, Frank Li wrote:
> > > > For the i.MX95, configuration of a LUT is necessary to convert Bus Device
> > > > Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
> > > > This involves checking msi-map and iommu-map device tree properties to
> > > > ensure consistent mapping of PCI BDF to the same stream IDs. Subsequently,
> > > > LUT-related registers are configured. In the absence of an msi-map, the
> > > > built-in MSI controller is utilized as a fallback.
> > >
> > > This is wrong information. What you want to say is that if an msi-map
> > > isn't detected this means that the platform relies on DWC built-in
> > > controller for MSIs (that does not need streamIDs handling).
> > >
> > > That's quite different from what you are writing here.
> >
> > How about ?
> >
> > "If an msi-map isn't detected, platform relies on DWC built-in controller
> > for MSIs that does not need streamdIDs"
>
> Right. Question: what happens if DT shows that there are SMMU and/or
> ITS bindings/mappings but the SMMU driver and ITS driver are either not
> enabled or have not probed ?

It is little bit complex.
iommu:
Case 1:
	iommu{
		status = "disabled"
	};

	PCI driver normal probed. if RID is in range of iommu-map, not
any functional impact and harmless.
	If RID is out of range of iommu-map, "false alarm" will return.
enable PCI EP device failure, but actually it can work without IOMMU.

Case 2:
	iommu {
		status = "Okay"
	}
	but iommu driver have not probed yet.  PCI Host bridge driver
should defer till iommu probed.

Worst case is "false alarm". But this happen is very rare if DTS is
correct.

MSI:
case 1:
	msi-controller {
		status = "disabled";
	}
	Whole all dwc drivers will be broken.

case 2:
	msi-controller {
		status = "Okay"
	}
	if msi driver have not probed yet, PCI Host bridge driver will
defer.

Frank

>
> I assume the LUT programming makes no difference (it is useless yes but
> should be harmless too) in this case but wanted to check with you.
>
> Thanks,
> Lorenzo
>
> >
> > >
> > > >
> > > > Register a PCI bus callback function to handle enable_device() and
> > > > disable_device() operations, setting up the LUT whenever a new PCI device
> > > > is enabled.
> > > >
> > > > Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
> > > > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> >
> > [...]
> >
> > > > +	int err_i, err_m;
> > > > +	u32 sid;
> > > > +
> > > > +	dev = imx_pcie->pci->dev;
> > > > +
> > > > +	target = NULL;
> > > > +	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
> > > > +	if (target) {
> > > > +		of_node_put(target);
> > > > +	} else {
> > > > +		/*
> > > > +		 * "target == NULL && err_i == 0" means use 1:1 map RID to
> > >
> > > Is it what it means ? Or does it mean that the iommu-map property was found
> > > and RID is out of range ?
> >
> > yes, if this happen, sid_i will be equal to RID.
> >
> > >
> > > Could you point me at a sample dts for this host bridge please ?
> >
> > https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/boot/dts/freescale/imx95.dtsi
> >
> > /* 0x10~0x17 stream id for pci0 */
> >    iommu-map = <0x000 &smmu 0x10 0x1>,
> >                <0x100 &smmu 0x11 0x7>;
> >
> > /* msi part */
> >    msi-map = <0x000 &its 0x10 0x1>,
> >              <0x100 &its 0x11 0x7>;
> >
> > >
> > > > +		 * stream ID. Hardware can't support this because stream ID
> > > > +		 * only 5bits
> > >
> > > It is 5 or 6 bits ? From GENMASK(5, 0) above it should be 6.
> >
> > Sorry for typo. it is 6bits.
> >
> > >
> > > > +		 */
> > > > +		err_i = -EINVAL;
> > > > +	}
> > > > +
> > > > +	target = NULL;
> > > > +	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
> > > > +
> > > > +	/*
> > > > +	 *   err_m      target
> > > > +	 *	0	NULL		Use 1:1 map RID to stream ID,
> > >
> > > Again, is that what it really means ?
> > >
> > > > +	 *				Current hardware can't support it,
> > > > +	 *				So return -EINVAL.
> > > > +	 *      != 0    NULL		msi-map not exist, use built-in MSI.
> > >
> > > does not exist.
> > >
> > > > +	 *	0	!= NULL		Get correct streamID from RID.
> > > > +	 *	!= 0	!= NULL		Unexisted case, never happen.
> > >
> > > "Invalid combination"
> > >
> > > > +	 */
> > > > +	if (!err_m && !target)
> > > > +		return -EINVAL;
> > > > +	else if (target)
> > > > +		of_node_put(target); /* Find stream ID map entry for RID in msi-map */
> > > > +
> > > > +	/*
> > > > +	 * msi-map        iommu-map
> > > > +	 *   N                N            DWC MSI Ctrl
> > > > +	 *   Y                Y            ITS + SMMU, require the same sid
> > > > +	 *   Y                N            ITS
> > > > +	 *   N                Y            DWC MSI Ctrl + SMMU
> > > > +	 */
> > > > +	if (err_i && err_m)
> > > > +		return 0;
> > > > +
> > > > +	if (!err_i && !err_m) {
> > > > +		/*
> > > > +		 * MSI glue layer auto add 2 bits controller ID ahead of stream
> > >
> > > What's "MSI glue layer" ?
> >
> > It is common term for IC desgin, which connect IP's signal to platform with
> > some simple logic. Inside chip, when connect LUT output 6bit streamIDs
> > to MSI controller, there are 2bits hardcode controller ID information
> > append to 6 bits streamID.
> >
> >            Glue Layer
> >           <==========>
> > ???????                  ????????????
> > ? LUT ? 6bit stream ID   ?          ?
> > ?     ????????????????????  MSI     ?
> > ???????    2bit ctrl ID  ?          ?
> >             ??????????????          ?
> >             ?            ?          ?
> >  00 PCIe0   ?            ?          ?
> >  01 ENETC   ?            ?          ?
> >  10 PCIe1   ?            ?          ?
> >             ?            ????????????
> >
> > >
> > > > +		 * ID, so mask this 2bits to get stream ID.
> > > > +		 * But IOMMU glue layer doesn't do that.
> > >
> > > and "IOMMU glue layer" ?
> >
> > See above.
> >
> > Frank
> >
> > >
> > > > +		 */
> > > > +		if (sid_i != (sid_m & IMX95_SID_MASK)) {
> > > > +			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
> > > > +			return -EINVAL;
> > > > +		}
> > > > +	}
> > > > +
> > > > +	sid = sid_i;
> > >
> > > err_i could be != 0 here, I understand that the end result is
> > > fine given how the code is written but it is misleading.
> > >
> > > 	if (!err_i)
> > > 	else if (!err_m)
> >
> > Okay
> >
> > >
> > > > +	if (!err_m)
> > > > +		sid = sid_m & IMX95_SID_MASK;
> > > > +
> > > > +	return imx_pcie_add_lut(imx_pcie, rid, sid);
> > > > +}
> > > > +
> > > > +static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> > > > +{
> > > > +	struct imx_pcie *imx_pcie;
> > > > +
> > > > +	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> > > > +	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
> > > > +}
> > > > +
> > > >  static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> > > >  {
> > > >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > > @@ -946,6 +1122,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> > > >  		}
> > > >  	}
> > > >
> > > > +	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
> > > > +		pp->bridge->enable_device = imx_pcie_enable_device;
> > > > +		pp->bridge->disable_device = imx_pcie_disable_device;
> > > > +	}
> > > > +
> > > >  	imx_pcie_assert_core_reset(imx_pcie);
> > > >
> > > >  	if (imx_pcie->drvdata->init_phy)
> > > > @@ -1330,6 +1511,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
> > > >  	imx_pcie->pci = pci;
> > > >  	imx_pcie->drvdata = of_device_get_match_data(dev);
> > > >
> > > > +	mutex_init(&imx_pcie->lock);
> > > > +
> > > >  	/* Find the PHY if one is defined, only imx7d uses it */
> > > >  	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
> > > >  	if (np) {
> > > > @@ -1627,7 +1810,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
> > > >  	},
> > > >  	[IMX95] = {
> > > >  		.variant = IMX95,
> > > > -		.flags = IMX_PCIE_FLAG_HAS_SERDES,
> > > > +		.flags = IMX_PCIE_FLAG_HAS_SERDES |
> > > > +			 IMX_PCIE_FLAG_HAS_LUT,
> > > >  		.clk_names = imx8mq_clks,
> > > >  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> > > >  		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> > > >
> > > > --
> > > > 2.34.1
> > > >


From broonie at kernel.org  Fri Dec 13 09:21:50 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 13 Dec 2024 17:21:50 +0000
Subject: [PATCH] arm64/signal: Silence spurious sparse warning storing
 GCSPR_EL0
In-Reply-To: <Z1xeLCKoSWyn2sko@arm.com>
References: <20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89@kernel.org>
 <Z1hU0Ii-Sm9NHnhj@J2N7QTR9R3>
 <20c12aac-193e-43ae-9418-39db1af4ede9@sirena.org.uk>
 <Z1ht7X2LRw34pMJK@J2N7QTR9R3>
 <6d839dfb-0a85-44c5-90cc-2b2426353a5f@sirena.org.uk>
 <Z1xeLCKoSWyn2sko@arm.com>
Message-ID: <e9259a94-652c-470b-8ad0-b6fd2dcdc0c8@sirena.org.uk>

On Fri, Dec 13, 2024 at 04:17:48PM +0000, Catalin Marinas wrote:
> On Tue, Dec 10, 2024 at 04:52:49PM +0000, Mark Brown wrote:

> > Yes, I had already removed the references to spurious and false positive
> > locally and changed the unsigned long cast to a __force u64 cast.

> I still have a slight preference for treating a sysreg value as an
> integer and cast it to pointer when needed rather than using __force.

I've now changed to that and will send it later - TBH I'm having a very
hard time seeing it as an improvement, especially with the update to
gcs_signal_entry() where we do two writes.
-------------- 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/20241213/f4578710/attachment.sig>

From maxime.chevallier at bootlin.com  Fri Dec 13 09:29:04 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 13 Dec 2024 18:29:04 +0100
Subject: [PATCH net-next 2/2] net: stmmac: dwmac-socfpga: Set interface
 modes from Lynx PCS as supported
In-Reply-To: <Z1wnFXlgEU84VX8F@shell.armlinux.org.uk>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
	<20241213090526.71516-3-maxime.chevallier@bootlin.com>
	<Z1wnFXlgEU84VX8F@shell.armlinux.org.uk>
Message-ID: <20241213182904.55eb2504@fedora.home>

Hi Russell,

On Fri, 13 Dec 2024 12:22:45 +0000
"Russell King (Oracle)" <linux at armlinux.org.uk> wrote:

> On Fri, Dec 13, 2024 at 10:05:25AM +0100, Maxime Chevallier wrote:
> > On Socfpga, the dwmac controller uses a variation of the Lynx PCS to get
> > additional support for SGMII and 1000BaseX. The switch between these
> > modes may occur at runtime (e.g. when the interface is wired to an SFP
> > cage). In such case, phylink will validate the newly selected interface
> > between the MAC and SFP based on the internal "supported_interfaces"
> > field.
> > 
> > For now in stmmac, this field is populated based on :
> >  - The interface specified in firmware (DT)
> >  - The interfaces supported by XPCS, when XPCS is in use.
> > 
> > In our case, the PCS in Lynx and not XPCS.
> > 
> > This commit makes so that the .pcs_init() implementation of
> > dwmac-socfpga populates the supported_interface when the Lynx PCS was
> > successfully initialized.  
> 
> I think it would also be worth adding this to Lynx, so phylink also
> gets to know (via its validation) which PHY interface modes the PCS
> can support.
> 
> However, maybe at this point we need to introduce an interface bitmap
> into struct phylink_pcs so that these kinds of checks can be done in
> phylink itself when it has the PCS, and it would also mean that stmmac
> could do something like:
> 
> 	struct phylink_pcs *pcs;
> 
> 	if (priv->hw->xpcs)
> 		pcs = xpcs_to_phylink_pcs(priv->hw->xpcs);
> 	else
> 		pcs = priv->hw->phylink_pcs;
> 
> 	if (pcs)
> 		phy_interface_or(priv->phylink_config.supported_interfaces,
> 				 priv->phylink_config.supported_interfaces,
> 				 pcs->supported_interfaces);
> 
> and not have to worry about this from individual PCS or platform code.

I like the idea, I will give it a go and send a series for that if
that's ok :)

Thanks,

Maxime


From catalin.marinas at arm.com  Fri Dec 13 09:41:38 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 13 Dec 2024 17:41:38 +0000
Subject: [GIT PULL] arm64 fixes for 6.13-rc3
Message-ID: <Z1xx0ha7lbKkdhRC@arm.com>

Hi Linus,

Please pull the arm64 fixes below. Thanks.

The following changes since commit fac04efc5c793dccbd07e2d59af9f90b7fc0dca4:

  Linux 6.13-rc2 (2024-12-08 14:03:39 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

for you to fetch changes up to ce03573a1917532da06057da9f8e74a2ee9e2ac9:

  kselftest/arm64: abi: fix SVCR detection (2024-12-13 14:59:37 +0000)

----------------------------------------------------------------
arm64 fixes for 6.13-rc3:

- arm64 stacktrace: address some fallout from the recent changes to
  unwinding across exception boundaries

- Ensure the arm64 signal delivery failure is recoverable - only
  override the return registers after all the user accesses took place

- Fix the arm64 kselftest access to SVCR - only when SME is detected

----------------------------------------------------------------
Kevin Brodsky (1):
      arm64: signal: Ensure signal delivery failure is recoverable

Mark Rutland (2):
      arm64: stacktrace: Skip reporting LR at exception boundaries
      arm64: stacktrace: Don't WARN when unwinding other tasks

Weizhao Ouyang (1):
      kselftest/arm64: abi: fix SVCR detection

 arch/arm64/kernel/signal.c                         | 48 +++++++++++++++-------
 arch/arm64/kernel/stacktrace.c                     | 32 ++++-----------
 .../testing/selftests/arm64/abi/syscall-abi-asm.S  | 32 +++++++--------
 3 files changed, 55 insertions(+), 57 deletions(-)

-- 
Catalin


From shimrrashai at gmail.com  Fri Dec 13 10:08:53 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Fri, 13 Dec 2024 12:08:53 -0600
Subject: [PATCH v2 0/2] arm64: dts: rockchip: Add Firefly ITX-3588J Board
Message-ID: <20241213180855.16472-1-shimrrashai@gmail.com>

NOTE: This is a resubmit of a previous submission with corrected
recipients list and some small changes to make it more suited for the
general kernel (e.g. eMMC is enabled now).

---

I am proposing a Device Tree Blob for the Firefly ITX-3588J board.
This is another Mini-ITX form-factor board for the Rockchip RK3588
SoC, along with the ROCK 5 ITX. This version still has some outstanding
issues, however, so I am unsure if it is ready for incorporation in this
state and I have not yet found a fix for them as of now. I invite any
comments.

Issues outstanding:
 * Suspend does not work.
 * The USB-C port does not work.
 * Unsure how to get control over the main LED; the commented part
   seems to cause a failure.
 * Audio output on the back green port does not seem to work; but I
   found this may be due to slight inadequacy of the still-new ES8323
   driver - can suggest a patch for that too separately.
 * Not sure if there are other board features that could still be enabled
   with the present kernel drivers.

Thanks,
Shimrra

Shimrra Shai (2):
  arm64: dts: rockchip: add DTs for Firefly ITX-3588J
  dt-bindings: arm: rockchip: Add Firefly ITX-3588J board

 .../devicetree/bindings/arm/rockchip.yaml     |    5 +
 arch/arm64/boot/dts/rockchip/Makefile         |    1 +
 .../dts/rockchip/rk3588-firefly-itx-3588j.dts | 1133 +++++++++++++++++
 .../boot/dts/rockchip/rockchip-pca9555.h      |   31 +
 4 files changed, 1170 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rockchip-pca9555.h

-- 
2.45.2



From shimrrashai at gmail.com  Fri Dec 13 10:08:54 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Fri, 13 Dec 2024 12:08:54 -0600
Subject: [PATCH v2 1/2] arm64: dts: rockchip: add DTs for Firefly ITX-3588J
In-Reply-To: <20241213180855.16472-1-shimrrashai@gmail.com>
References: <20241213180855.16472-1-shimrrashai@gmail.com>
Message-ID: <20241213180855.16472-2-shimrrashai@gmail.com>

Main DTS for the board and Makefile addition.

Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |    1 +
 .../dts/rockchip/rk3588-firefly-itx-3588j.dts | 1133 +++++++++++++++++
 .../boot/dts/rockchip/rockchip-pca9555.h      |   31 +
 3 files changed, 1165 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rockchip-pca9555.h

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 86cc418a2..3f2eebd1f 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -137,6 +137,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-wifi.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-firefly-itx-3588j.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-friendlyelec-cm3588-nas.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts b/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
new file mode 100644
index 000000000..a99c007c7
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
@@ -0,0 +1,1133 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "dt-bindings/usb/pd.h"
+#include "rockchip-pca9555.h"
+#include "rk3588.dtsi"
+
+/ {
+	model = "Firefly ITX-3588J";
+	compatible = "firefly,itx-3588j", "rockchip,rk3588";
+
+	aliases {
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
+		mmc0 = &sdhci;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	/* NB: There are also a "Reset" and "Mask ROM" button but I don't
+	 * know the right settings for these. - Shimrra Shai
+	 */
+	adc-keys-1 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-recovery {
+			label = "Recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <2000>;
+		};
+	};
+
+	analog-sound {
+		compatible = "simple-audio-card";
+		pinctrl-0 = <&hp_detect>;
+		pinctrl-names = "default";
+		simple-audio-card,aux-devs = <&amp_headphones>, <&amp_speaker>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,hp-det-gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>;
+		simple-audio-card,mclk-fs = <384>;
+		simple-audio-card,name = "rockchip_es8323";
+		simple-audio-card,pin-switches = "Headphones", "Speaker";
+		simple-audio-card,routing =
+			"Speaker Amplifier INL", "LOUT2",
+			"Speaker Amplifier INR", "ROUT2",
+			"Speaker", "Speaker Amplifier OUTL",
+			"Speaker", "Speaker Amplifier OUTR",
+			"Headphones Amplifier INL", "LOUT1",
+			"Headphones Amplifier INR", "ROUT1",
+			"Headphones", "Headphones Amplifier OUTL",
+			"Headphones", "Headphones Amplifier OUTR",
+			"LINPUT1", "Microphone Jack",
+			"RINPUT1", "Microphone Jack",
+			"LINPUT2", "Onboard Microphone",
+			"RINPUT2", "Onboard Microphone";
+		simple-audio-card,widgets =
+			"Microphone", "Microphone Jack",
+			"Microphone", "Onboard Microphone",
+			"Headphone", "Headphones",
+			"Speaker", "Speaker";
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s0_8ch>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&es8323>;
+			system-clock-frequency = <12288000>;
+		};
+	};
+
+	/* note: this does not seem to be a proper "amplifier" but is just
+	 * a way to control the GPIO pins to switch on or off the given
+	 * sound output device
+	 */
+	amp_headphones: headphones-audio-amplifier {
+		compatible = "simple-audio-amplifier";
+		enable-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&headphone_amplifier_en>;
+		sound-name-prefix = "Headphones Amplifier";
+	};
+
+	amp_speaker: speaker-audio-amplifier {
+		compatible = "simple-audio-amplifier";
+		enable-gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&speaker_amplifier_en>;
+		sound-name-prefix = "Speaker Amplifier";
+	};
+
+	fan: pwm-fan {
+		compatible = "pwm-fan";
+		#cooling-cells = <2>;
+		cooling-levels = <0 120 150 180 210 240 255>;
+		fan-supply = <&vcc12v_dcin>;
+		pwms = <&pwm15 0 50000 1>;
+	};
+
+	hdmi0-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi0_con_in: endpoint {
+				remote-endpoint = <&hdmi0_out_con>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		/* NB: This Power LED control does not seem to work for
+		 * some reason. - Shimrra Shai
+		 */
+#if 0
+		power_led: led-0 {
+			gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "default-on";
+		};
+#endif
+
+		user_led: led-1 {
+			gpios = <&pca9555 PCA_IO0_3 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "disk-activity";
+		};
+	};
+
+	pcie30_avdd0v75: pcie30-avdd0v75 {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie30_avdd0v75";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <750000>;
+		regulator-max-microvolt = <750000>;
+		vin-supply = <&avdd_0v75_s0>;
+	};
+
+	vbus5v0_typec_pwr_en: vbus5v0-typec-pwr-en-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vbus5v0_typec_pwr_en";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&pca9555 PCA_IO1_4 GPIO_ACTIVE_HIGH>;  //PCA_IO 14
+	};
+
+	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>;
+	};
+
+	vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_pcie30";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pcie3_vcc3v3_en>;
+		gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <5000>;
+		vin-supply = <&vcc12v_dcin>;
+		status = "okay";
+	};
+
+	vcc5v0_host: vcc5v0-host-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		status = "okay";
+		gpio = <&pca9555 PCA_IO0_5 GPIO_ACTIVE_HIGH>;
+		regulator-name = "vcc5v0_host";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-boot-on;
+		regulator-always-on;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_host3: vcc5v0-host3-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_host3";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&pca9555 PCA_IO0_7 GPIO_ACTIVE_HIGH>;  //PCA_IO 07
+		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_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 = <&vcc12v_dcin>;
+	};
+
+	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>;
+	};
+
+	vcc_fan_pwr_en: vcc-fan-pwr-en-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_fan_pwr_en";
+		regulator-boot-on;
+		regulator-always-on;
+		enable-active-high;
+		gpio = <&pca9555 PCA_IO1_3 GPIO_ACTIVE_HIGH>;  //PCA_IO 13
+	};
+
+	vcc_hub_reset: vcc-hub-reset-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_hub_reset";
+		regulator-boot-on;
+		regulator-always-on;
+		enable-active-high;
+		gpio = <&pca9555 PCA_IO0_4 GPIO_ACTIVE_HIGH>;  //PCA_IO 04
+	};
+
+	vcc_hub3_reset: vcc-hub3-reset-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_hub3_reset";
+		regulator-always-on;
+		enable-active-high;
+		gpio = <&pca9555 PCA_IO0_6 GPIO_ACTIVE_HIGH>;  //PCA_IO 06
+	};
+
+	vcc_sata_pwr_en: vcc-sata-pwr-en-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sata_pwr_en";
+		regulator-boot-on;
+		regulator-always-on;
+		enable-active-high;
+		gpio = <&pca9555 PCA_IO1_2 GPIO_ACTIVE_HIGH>;  //PCA_IO 12
+	};
+};
+
+&combphy0_ps {
+	status = "okay";
+};
+
+&combphy1_ps {
+	status = "okay";
+};
+
+&combphy2_psu {
+	status = "okay";
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+	mem-supply = <&vdd_cpu_big0_mem_s0>;
+};
+
+&cpu_b1 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+	mem-supply = <&vdd_cpu_big1_mem_s0>;
+};
+
+&cpu_b3 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+	mem-supply = <&vdd_cpu_lit_mem_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>;
+};
+
+&display_subsystem {
+	clocks = <&hdptxphy_hdmi0>;
+	clock-names = "hdmi0_phy_pll";
+};
+
+&gmac0 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy0>;
+	phy-mode = "rgmii-rxid";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+	tx_delay = <0x45>;
+	rx_delay = <0x4a>;
+	status = "okay";
+};
+
+&gmac1 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii-rxid";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac1_miim
+		     &gmac1_tx_bus2
+		     &gmac1_rx_bus2
+		     &gmac1_rgmii_clk
+		     &gmac1_rgmii_bus>;
+	tx_delay = <0x42>;
+	rx_delay = <0x4f>;
+	status = "okay";
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu_s0>;
+	sram-supply = <&vdd_gpu_mem_s0>;
+	status = "okay";
+};
+
+&hdmi0 {
+	status = "okay";
+};
+
+&hdmi0_in {
+	hdmi0_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi0>;
+	};
+};
+
+&hdmi0_out {
+	hdmi0_out_con: endpoint {
+		remote-endpoint = <&hdmi0_con_in>;
+	};
+};
+
+&hdptxphy_hdmi0 {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0m2_xfer>;
+	status = "okay";
+
+	vdd_cpu_big0_s0: vdd_cpu_big0_mem_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: vdd_cpu_big1_mem_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;
+		};
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1m2_xfer>;
+	status = "okay";
+
+	vdd_npu_s0: vdd_npu_mem_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_npu_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <950000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&i2c3 {
+	status = "okay";
+
+	/* note: in the Firefly BSP source this was confusingly called an
+	 * "ES8388" - it actually seems to be an ES8323 and the drivers
+	 * for that work best
+	 */
+	es8323: audio-codec at 11 {
+		compatible = "everest,es8323";
+		reg = <0x11>;
+		assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+		assigned-clock-rates = <12288000>;
+		clocks = <&cru I2S0_8CH_MCLKOUT>;
+		clock-names = "mclk";
+		#sound-dai-cells = <0>;
+	};
+};
+
+&i2c6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c6m0_xfer>;
+	status = "okay";
+
+	pca9555: gpio at 21 {
+		compatible = "nxp,pca9555";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	usbc0: usb-typec at 22 {
+		compatible = "fcs,fusb302";
+		reg = <0x22>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbc0_int>;
+		vbus-supply = <&vbus5v0_typec_pwr_en>;
+		status = "okay";
+
+		usb_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			op-sink-microwatt = <1000000>;
+			power-role = "dual";
+			sink-pdos =
+				<PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
+			source-pdos =
+				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			try-power-role = "source";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_orien_sw: endpoint {
+						remote-endpoint = <&usbdp_phy0_orientation_switch>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_role_sw: endpoint {
+						remote-endpoint = <&dwc3_0_role_switch>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+
+					dp_altmode_mux: endpoint {
+						remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+					};
+				};
+			};
+		};
+	};
+
+	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_PB0 IRQ_TYPE_LEVEL_LOW>;
+		wakeup-source;
+	};
+};
+
+&i2s0_8ch {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s0_lrck
+		     &i2s0_mclk
+		     &i2s0_sclk
+		     &i2s0_sdi0
+		     &i2s0_sdo0>;
+	status = "okay";
+};
+
+&mdio0 {
+	rgmii_phy0: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+	};
+};
+
+&pcie2x1l0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2_0_rst>;
+	reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>;
+	rockchip,skip-scan-in-resume;
+	status = "okay";
+};
+
+&pcie30phy {
+	status = "okay";
+};
+
+&pcie3x4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie3_rst>;
+	reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_pcie30>;
+	status = "okay";
+};
+
+&pinctrl {
+	dp {
+		dp1_hpd: dp1-hpd {
+			 rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	hym8563 {
+		hym8563_int: hym8563-int {
+			rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	gpio-leds {
+		sys_led_pin: sys-led-pin {
+			rockchip,pins =
+				<1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pcie2 {
+		pcie2_0_rst: pcie2-0-rst {
+			rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pcie3 {
+		pcie3_rst: pcie3-rst {
+			rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		pcie3_vcc3v3_en: pcie3-vcc3v3-en {
+			rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sound {
+		hp_detect: hp-detect {
+			rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		headphone_amplifier_en: headphone-amplifier-en {
+			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		speaker_amplifier_en: speaker-amplifier-en {
+			rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		usbc0_int: usbc0-int {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&pwm15 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm15m2_pins>;
+	status = "okay";
+};
+
+&sata0 {
+	status = "okay";
+};
+
+&sata1 {
+	status = "okay";
+};
+
+&sata2 {
+	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", "pmic-power-off";
+		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+		pinctrl-1 = <&rk806_dvs1_pwrdn>;
+
+		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_dvs1_pwrdn: rk806_dvs1_pwrdn {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun2";
+		};
+
+		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-on-in-suspend; // for fan when deep sleep
+					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-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-on-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-on-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;
+				};
+			};
+
+			avcc_3v3_s0: pldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "avcc_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>;
+				};
+			};
+
+			avdd_ddr_pll_s0: nldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "avdd_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;
+				};
+			};
+
+			avdd_0v85_s0: nldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "avdd_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;
+				};
+			};
+		};
+	};
+};
+
+/* uart/232/485 */
+&uart0 {
+	pinctrl-0 = <&uart0m2_xfer>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-0 = <&uart1m1_xfer>;
+	status = "okay";
+};
+
+/* rk3588 preferred debug out */
+&uart2 {
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
+
+&u2phy0 {
+	status = "okay";
+};
+
+&u2phy0_otg {
+	status = "okay";
+};
+
+&u2phy1 {
+	status = "okay";
+};
+
+&u2phy1_otg {
+	phy-supply = <&vcc5v0_host>;
+	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_host0_xhci {
+	usb-role-switch;
+	dr_mode = "otg";
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dwc3_0_role_switch: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&usbc0_role_sw>;
+		};
+	};
+};
+
+&usb_host1_xhci {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usb_host2_xhci {
+	status = "okay";
+};
+
+&usbdp_phy0 {
+	orientation-switch;
+	sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
+	sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usbdp_phy0_orientation_switch: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&usbc0_orien_sw>;
+		};
+
+		usbdp_phy0_dp_altmode_mux: endpoint at 1 {
+			reg = <1>;
+			remote-endpoint = <&dp_altmode_mux>;
+		};
+	};
+};
+
+&usbdp_phy1 {
+	rockchip,dp-lane-mux = <2 3>;
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
+
+&vop {
+	status = "okay";
+};
+
+&vp0 {
+	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi0_in_vp0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/rockchip/rockchip-pca9555.h b/arch/arm64/boot/dts/rockchip/rockchip-pca9555.h
new file mode 100644
index 000000000..c4c9a2471
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rockchip-pca9555.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * Bindings for the PCA9555 GPIO extender used on some Rockchip devices, e.g.
+ * Firefly.
+ *
+ * Copyright (c) 2013 MundoReader S.L.
+ * Authors: Heiko Stuebner <heiko at sntech.de>
+ *          Shimrra Shai <shimrrashai at gmail.com>
+ */
+
+#ifndef __RK_PCA9555_H__
+#define __RK_PCA9555_H__
+
+#define PCA_IO0_0          0
+#define PCA_IO0_1          1
+#define PCA_IO0_2          2
+#define PCA_IO0_3          3
+#define PCA_IO0_4          4
+#define PCA_IO0_5          5
+#define PCA_IO0_6          6
+#define PCA_IO0_7          7
+#define PCA_IO1_0          8
+#define PCA_IO1_1          9
+#define PCA_IO1_2          10
+#define PCA_IO1_3          11
+#define PCA_IO1_4          12
+#define PCA_IO1_5          13
+#define PCA_IO1_6          14
+#define PCA_IO1_7          15
+
+#endif
-- 
2.45.2



From shimrrashai at gmail.com  Fri Dec 13 10:08:55 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Fri, 13 Dec 2024 12:08:55 -0600
Subject: [PATCH v2 2/2] dt-bindings: arm: rockchip: Add Firefly ITX-3588J board
In-Reply-To: <20241213180855.16472-1-shimrrashai@gmail.com>
References: <20241213180855.16472-1-shimrrashai@gmail.com>
Message-ID: <20241213180855.16472-3-shimrrashai@gmail.com>

Document the compatibles for the new board.

Signed-off-by: Shimrra Shai <shimrrashai at gmail.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 753199a12..9ee96acdc 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -190,6 +190,11 @@ properties:
           - const: firefly,firefly-rk3399
           - const: rockchip,rk3399
 
+      - description: Firefly ITX-3588J
+        items:
+          - const: firefly,itx-3588j
+          - const: rockchip,rk3588
+
       - description: Firefly ROC-RK3308-CC
         items:
           - const: firefly,roc-rk3308-cc
-- 
2.45.2



From heiko at sntech.de  Fri Dec 13 10:22:52 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 13 Dec 2024 19:22:52 +0100
Subject: [PATCH v2 2/2] dt-bindings: arm: rockchip: Add Firefly ITX-3588J board
In-Reply-To: <20241213180855.16472-3-shimrrashai@gmail.com>
References: <20241213180855.16472-1-shimrrashai@gmail.com>
 <20241213180855.16472-3-shimrrashai@gmail.com>
Message-ID: <1908542.tdWV9SEqCh@diego>

Hi,

Am Freitag, 13. Dezember 2024, 19:08:55 CET schrieb Shimrra Shai:
> Document the compatibles for the new board.
> 
> Signed-off-by: Shimrra Shai <shimrrashai at gmail.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 753199a12..9ee96acdc 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> @@ -190,6 +190,11 @@ properties:
>            - const: firefly,firefly-rk3399
>            - const: rockchip,rk3399
>  
> +      - description: Firefly ITX-3588J
> +        items:
> +          - const: firefly,itx-3588j
> +          - const: rockchip,rk3588
> +

looking at the product-page, this is not _one_ complete board. Instead
it seems to be a system-on-module + baseboard design.

It looks like it uses the Core-3588J system-on-module [0].

We already have a number of those in the binding file to take as example
on how to structure that. For example FriendlyElec CM3588-based boards .

So you could do

      - description: Firefly Core-3588J-based boards
        items:
          - enum:
              - firefly,itx-3588j
          - const: firefly,core-rk3588j
          - const: rockchip,rk3588


Thanks
Heiko



[0] https://en.t-firefly.com/product/core/core3588j




From robh at kernel.org  Fri Dec 13 10:26:25 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 13 Dec 2024 12:26:25 -0600
Subject: [PATCH 2/4] dt-bindings: mfd: syscon: allow two reg regions
 for gs101-pmu
In-Reply-To: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-2-c72978f63713@linaro.org>
References: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
 <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-2-c72978f63713@linaro.org>
Message-ID: <173411438555.1847522.16456703753774291235.robh@kernel.org>


On Fri, 13 Dec 2024 16:44:39 +0000, Peter Griffin wrote:
> To avoid dtschema warnings allow google,gs101-pmu to have
> two reg regions.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
> I don't really like this patch, but also didn't want to submit the series
> with a dtschema warning ;-)
> 
> Possibly a better solution is when Robs patch
> `mfd: syscon: Allow syscon nodes without a "syscon" compatible` [1]
> 
> gets updated with a v2, we could remove syscon compatible from
> gs101.dtsi (an ABI issue). If I understood his patch correctly,
> it would mean this yaml update would then no longer be required.
> 
> Let me know your thoughts
> 
> [1] https://lore.kernel.org/lkml/20241211-syscon-fixes-v1-0-b5ac8c219e96 at kernel.org/T/#m5ad1ed5c69f693d2a5cc54342a87fbdf3df756d2
> ---
>  Documentation/devicetree/bindings/mfd/syscon-common.yaml | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:
./Documentation/devicetree/bindings/mfd/syscon-common.yaml:68:3: [error] syntax error: expected <block end>, but found '?' (syntax)
./Documentation/devicetree/bindings/mfd/syscon-common.yaml:69:5: [warning] wrong indentation: expected 6 but found 4 (indentation)

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mfd/syscon-common.yaml: ignoring, error parsing file
make[2]: *** Deleting file 'Documentation/devicetree/bindings/mfd/syscon-common.example.dts'
Documentation/devicetree/bindings/mfd/syscon-common.yaml:68:3: expected <block end>, but found '?'
make[2]: *** [Documentation/devicetree/bindings/Makefile:26: Documentation/devicetree/bindings/mfd/syscon-common.example.dts] Error 1
make[2]: *** Waiting for unfinished jobs....
./Documentation/devicetree/bindings/mfd/syscon-common.yaml:68:3: expected <block end>, but found '?'
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1506: dt_binding_check] Error 2
make: *** [Makefile:251: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-2-c72978f63713 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 detlev.casanova at collabora.com  Fri Dec 13 10:34:03 2024
From: detlev.casanova at collabora.com (Detlev Casanova)
Date: Fri, 13 Dec 2024 13:34:03 -0500
Subject: [PATCH v5 05/18] drm/rockchip: vop2: Set AXI id for rk3588
In-Reply-To: <3f1eace4.75cf.193b9daf585.Coremail.andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com> <5843712.DvuYhMxLoT@bootstrap>
 <3f1eace4.75cf.193b9daf585.Coremail.andyshrk@163.com>
Message-ID: <13660005.uLZWGnKmhe@bootstrap>

On Thursday, 12 December 2024 02:52:34 EST Andy Yan wrote:
> Hi Detlev,
> 
> At 2024-12-11 23:45:01, "Detlev Casanova" <detlev.casanova at collabora.com> 
wrote:
> >On Wednesday, 11 December 2024 01:34:34 EST Andy Yan wrote:
> >> Hi Detlev,
> >> 
> >> At 2024-12-11 02:40:14, "Detlev Casanova" <detlev.casanova at collabora.com>
> >
> >wrote:
> >> >Hi Andy,
> >> >
> >> >On Monday, 9 December 2024 07:29:18 EST Andy Yan wrote:
> >> >> From: Andy Yan <andy.yan at rock-chips.com>
> >> >> 
> >> >> There are two AXI bus in vop2, windows attached on the same bus must
> >> >> have a unique channel YUV and RGB channel ID.
> >> >> 
> >> >> The default IDs will conflict with each other on the rk3588, so they
> >> >> need to be reassigned.
> >> >> 
> >> >> Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
> >> >> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
> >> >> Tested-by: Derek Foreman <derek.foreman at collabora.com>
> >> >> 
> >> >> ---
> >> >> 
> >> >> Changes in v5:
> >> >> - Added in V5
> >> >> 
> >> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 14 +++++++++++
> >> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  9 +++++++
> >> >>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 26
> >> >>  +++++++++++++++++++-
> >> >>  3 files changed, 48 insertions(+), 1 deletion(-)
> >> >> 
> >> >> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> >> >> b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index
> >> >> dc4edd65bc9e..8b9ca046eeeb 100644
> >> >> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> >> >> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> >> >> @@ -1426,6 +1426,12 @@ static void vop2_plane_atomic_update(struct
> >> >> drm_plane *plane, &fb->format->format,
> >> >> 
> >> >>  		afbc_en ? "AFBC" : "", &yrgb_mst);
> >> >> 
> >> >> +	if (vop2->data->soc_id > 3568) {
> >> >
> >> >Shouldn't this be done only for rk3588, as specified in the comments
> >> >below
> >> >? The test we did before showed that it is failing on rk3576 and 3576 is
> >> >>
> >> >3588.
> >> 
> >> I think this is because you tested before with the patch I gave Derek
> >> without axi id assigned for rk3576.
> >> I assigned axi id for rk3576 in this version 18/18?The new ID assignment
> >> can adapt to more application scenarios.?, can you test it with the
> >> whole V5 version again?
> >
> >Yes, I will do that. But patch 18 mentions:
> >+       /* Read only bit on rk3576*/
> >+       [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
> >
> >And the bit is being written here. If it is indeed writable, then I would
> >drop that comment.
> 
> The AXI_BUS_ID for two Cluster windows on RK3576 are fixed by hardware, that
> means whether we write it or not, it won't change anything.
> But the AXI_BUS_ID for Esmart windows on rk3576 and  AXI_YRGB/UV_R_ID for
> all cluster/esmart windows on rk3576 are writeable.
> I think we directly write it here as the current code can make things easy.

I see, saying it is read only may be a bit confusing then, but it makes sense. 
You could be more specific adding that writing has no effect.

Anyway, I tested this and it works as expected:

Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

Regards,
Detlev.

> >> >I suggest
> >> >
> >> >	if (vop2->data->soc_id == 3588) {
> >> >
> >> >Regards,
> >> >Detlev
> >> >
> >> >> +		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data-
> >> >>
> >> >>axi_bus_id);
> >> >>
> >> >> +		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data-
> >> >>
> >> >>axi_yrgb_r_id);
> >> >>
> >> >> +		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data-
> >> >>
> >> >>axi_uv_r_id);
> >> >>
> >> >> +	}
> >> >> +
> >> >> 
> >> >>  	if (vop2_cluster_window(win))
> >> >>  	
> >> >>  		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN,
> >> >
> >> >half_block_en);
> >
> >Detlev.
> >
> >
> >
> >_______________________________________________
> >Linux-rockchip mailing list
> >Linux-rockchip at lists.infradead.org
> >http://lists.infradead.org/mailman/listinfo/linux-rockchip






From heiko at sntech.de  Fri Dec 13 10:34:36 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 13 Dec 2024 19:34:36 +0100
Subject: [PATCH v2 1/2] arm64: dts: rockchip: add DTs for Firefly ITX-3588J
In-Reply-To: <20241213180855.16472-2-shimrrashai@gmail.com>
References: <20241213180855.16472-1-shimrrashai@gmail.com>
 <20241213180855.16472-2-shimrrashai@gmail.com>
Message-ID: <10578885.nUPlyArG6x@diego>

Am Freitag, 13. Dezember 2024, 19:08:54 CET schrieb Shimrra Shai:
> Main DTS for the board and Makefile addition.
> 
> Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>

> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts b/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
> new file mode 100644
> index 000000000..a99c007c7
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
> @@ -0,0 +1,1133 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/leds/common.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include <dt-bindings/pwm/pwm.h>
> +#include <dt-bindings/soc/rockchip,vop2.h>
> +#include "dt-bindings/usb/pd.h"
> +#include "rockchip-pca9555.h"
> +#include "rk3588.dtsi"

in line with my comment in the binding, please split the system-on-module
parts into a rk3588-firefly-core-3588j.dtsi and then include that file here.


> +
> +/ {
> +	model = "Firefly ITX-3588J";
> +	compatible = "firefly,itx-3588j", "rockchip,rk3588";
> +
> +	aliases {
> +		ethernet0 = &gmac0;
> +		ethernet1 = &gmac1;
> +		mmc0 = &sdhci;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial2:1500000n8";
> +	};
> +
> +	/* NB: There are also a "Reset" and "Mask ROM" button but I don't
> +	 * know the right settings for these. - Shimrra Shai
> +	 */

same comment-style as below, plus

/*
 * There are additional Reset and Maskrom keys connected, but their
 * settings are still unknown right now.
 */

> +	adc-keys-1 {

why is it adc-keys-1 ? (where is -0 ?)

> +		compatible = "adc-keys";
> +		io-channels = <&saradc 1>;
> +		io-channel-names = "buttons";
> +		keyup-threshold-microvolt = <1800000>;
> +		poll-interval = <100>;
> +
> +		button-recovery {
> +			label = "Recovery";
> +			linux,code = <KEY_VENDOR>;
> +			press-threshold-microvolt = <2000>;
> +		};
> +	};
> +
> +	analog-sound {
> +		compatible = "simple-audio-card";
> +		pinctrl-0 = <&hp_detect>;
> +		pinctrl-names = "default";
> +		simple-audio-card,aux-devs = <&amp_headphones>, <&amp_speaker>;
> +		simple-audio-card,format = "i2s";
> +		simple-audio-card,hp-det-gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>;
> +		simple-audio-card,mclk-fs = <384>;
> +		simple-audio-card,name = "rockchip_es8323";
> +		simple-audio-card,pin-switches = "Headphones", "Speaker";
> +		simple-audio-card,routing =
> +			"Speaker Amplifier INL", "LOUT2",
> +			"Speaker Amplifier INR", "ROUT2",
> +			"Speaker", "Speaker Amplifier OUTL",
> +			"Speaker", "Speaker Amplifier OUTR",
> +			"Headphones Amplifier INL", "LOUT1",
> +			"Headphones Amplifier INR", "ROUT1",
> +			"Headphones", "Headphones Amplifier OUTL",
> +			"Headphones", "Headphones Amplifier OUTR",
> +			"LINPUT1", "Microphone Jack",
> +			"RINPUT1", "Microphone Jack",
> +			"LINPUT2", "Onboard Microphone",
> +			"RINPUT2", "Onboard Microphone";
> +		simple-audio-card,widgets =
> +			"Microphone", "Microphone Jack",
> +			"Microphone", "Onboard Microphone",
> +			"Headphone", "Headphones",
> +			"Speaker", "Speaker";
> +
> +		simple-audio-card,cpu {
> +			sound-dai = <&i2s0_8ch>;
> +		};
> +
> +		simple-audio-card,codec {
> +			sound-dai = <&es8323>;
> +			system-clock-frequency = <12288000>;
> +		};
> +	};
> +
> +	/* note: this does not seem to be a proper "amplifier" but is just

	/*
	 * note: this does not seem to be a proper "amplifier" but is just

comment formatting please

> +	 * a way to control the GPIO pins to switch on or off the given
> +	 * sound output device
> +	 */
> +	amp_headphones: headphones-audio-amplifier {
> +		compatible = "simple-audio-amplifier";
> +		enable-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&headphone_amplifier_en>;
> +		sound-name-prefix = "Headphones Amplifier";
> +	};

> +	leds {
> +		compatible = "gpio-leds";
> +
> +		/* NB: This Power LED control does not seem to work for
> +		 * some reason. - Shimrra Shai
> +		 */
> +#if 0
> +		power_led: led-0 {
> +			gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "default-on";
> +		};
> +#endif

please don't add dead code

> +
> +		user_led: led-1 {
> +			gpios = <&pca9555 PCA_IO0_3 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "disk-activity";
> +		};
> +	};
> +
> +	vcc_sata_pwr_en: vcc-sata-pwr-en-regulator {

vcc_sata_pwr_en: regulator-vcc-sata-pwr-en

Applied to all regulator nodes

> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_sata_pwr_en";
> +		regulator-boot-on;
> +		regulator-always-on;
> +		enable-active-high;
> +		gpio = <&pca9555 PCA_IO1_2 GPIO_ACTIVE_HIGH>;  //PCA_IO 12

please sort properties (compatible, regs, [alphabetically], status) and please
drop those comments at the end.

Applied to all regulator nodes

> +	};

[...]

> +&cpu_l0 {
> +	cpu-supply = <&vdd_cpu_lit_s0>;
> +	mem-supply = <&vdd_cpu_lit_mem_s0>;

that mem-supply property is not specified and also is not necessary here.
Same for the other cases above.

> +};

[...]

> +	usbc0: usb-typec at 22 {
> +		compatible = "fcs,fusb302";
> +		reg = <0x22>;
> +		interrupt-parent = <&gpio0>;
> +		interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&usbc0_int>;
> +		vbus-supply = <&vbus5v0_typec_pwr_en>;
> +		status = "okay";

default status is always "okay", so no need to add it for new nodes.
Same for possible other places in this file.


> diff --git a/arch/arm64/boot/dts/rockchip/rockchip-pca9555.h b/arch/arm64/boot/dts/rockchip/rockchip-pca9555.h
> new file mode 100644
> index 000000000..c4c9a2471
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rockchip-pca9555.h

if anything, that include needs to live in include/dt-bindings/something
and needs to be a separate patch, if you really need that

> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
> +/*
> + * Bindings for the PCA9555 GPIO extender used on some Rockchip devices, e.g.
> + * Firefly.
> + *
> + * Copyright (c) 2013 MundoReader S.L.
> + * Authors: Heiko Stuebner <heiko at sntech.de>

where does this copyright come from? I don't remember being involved
in a binding header for that expander?


> + *          Shimrra Shai <shimrrashai at gmail.com>
> + */
> +
> +#ifndef __RK_PCA9555_H__
> +#define __RK_PCA9555_H__
> +
> +#define PCA_IO0_0          0
> +#define PCA_IO0_1          1
> +#define PCA_IO0_2          2
> +#define PCA_IO0_3          3
> +#define PCA_IO0_4          4
> +#define PCA_IO0_5          5
> +#define PCA_IO0_6          6
> +#define PCA_IO0_7          7
> +#define PCA_IO1_0          8
> +#define PCA_IO1_1          9
> +#define PCA_IO1_2          10
> +#define PCA_IO1_3          11
> +#define PCA_IO1_4          12
> +#define PCA_IO1_5          13
> +#define PCA_IO1_6          14
> +#define PCA_IO1_7          15
> +
> +#endif
> 

Heiko




From mike.leach at linaro.org  Fri Dec 13 10:53:42 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 13 Dec 2024 18:53:42 +0000
Subject: [PATCH v2 1/3] coresight: Update timeout functions to allow
 return of test register value
In-Reply-To: <0c13fbf6-3023-4f9e-9571-a9e8ca6e3402@arm.com>
References: <20241213144919.110642-1-mike.leach@linaro.org>
 <20241213144919.110642-2-mike.leach@linaro.org> <0c13fbf6-3023-4f9e-9571-a9e8ca6e3402@arm.com>
Message-ID: <CAJ9a7VjC2AioY8S6qrgDkStn4pLnUm+2QUKTppYm1XXuOVRGbQ@mail.gmail.com>

Hi Suzuki,

On Fri, 13 Dec 2024 at 16:38, Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>
> Hi Mike
>
> On 13/12/2024 14:49, Mike Leach wrote:
> > Current coresight_timeout function spins on a bit on a test register,
> > till bit value achieved or timeout hit.
> >
> > Add another function to return the full value of the register being
> > tested.
> >
>
> The patch looks good to me. However, this change doesn't bring much
> value, other than avoiding a read at the caller side. I guess it is
> simpler to leave things as is and let the caller read the register value
> while logging rather than providing another variant.
>

The reason for returning the register value is that you get the exact
read value used at the time of the test - not potentially a different
value read later.


> I am inclined to keep the interface simpler.
>
>
> > Signed-off-by: Mike Leach <mike.leach at linaro.org>
> > ---
> >   drivers/hwtracing/coresight/coresight-core.c | 50 +++++++++++++++-----
> >   include/linux/coresight.h                    |  2 +
> >   2 files changed, 41 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> > index ea38ecf26fcb..feb1a1db355f 100644
> > --- a/drivers/hwtracing/coresight/coresight-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-core.c
> > @@ -1017,32 +1017,37 @@ static void coresight_remove_conns(struct coresight_device *csdev)
> >   }
> >
> >   /**
> > - * coresight_timeout - loop until a bit has changed to a specific register
> > - *                   state.
> > + * coresight_timeout_retval - loop until a bit has changed to a specific register
> > + *                         state. Return final register value
> >    * @csa: coresight device access for the device
> >    * @offset: Offset of the register from the base of the device.
> >    * @position: the position of the bit of interest.
> >    * @value: the value the bit should have.
> > + * @rval:  the last read value of the register being tested.
> >    *
> >    * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
> >    * TIMEOUT_US has elapsed, which ever happens first.
> >    */
> > -int coresight_timeout(struct csdev_access *csa, u32 offset,
> > -                   int position, int value)
> > +int coresight_timeout_retval(struct csdev_access *csa, u32 offset,
> > +                          int position, int value, u32 *rval)
> >   {
> > -     int i;
> > -     u32 val;
> > +     int i, rc = -EAGAIN;
> > +     u32 val = 0;
> >
> >       for (i = TIMEOUT_US; i > 0; i--) {
> >               val = csdev_access_read32(csa, offset);
> >               /* waiting on the bit to go from 0 to 1 */
> >               if (value) {
> > -                     if (val & BIT(position))
> > -                             return 0;
> > +                     if (val & BIT(position)) {
> > +                             rc = 0;
> > +                             goto return_rval;
> > +                     }
> >               /* waiting on the bit to go from 1 to 0 */
> >               } else {
> > -                     if (!(val & BIT(position)))
> > -                             return 0;
> > +                     if (!(val & BIT(position))) {
> > +                             rc = 0;
> > +                             goto return_rval;
> > +                     }
> >               }
> >
> >               /*
> > @@ -1054,7 +1059,30 @@ int coresight_timeout(struct csdev_access *csa, u32 offset,
> >                       udelay(1);
> >       }
> >
> > -     return -EAGAIN;
> > +return_rval:
> > +     *rval = val;
>
> super minor nit: we could be flexible in accepting a "NULL" rval and
> thus keep the normal variants pass the NULL straight in. i.e,
>
>         if (rval)
>                 *rval = val;
>

Sure.

Mike
> > +
> > +     return rc;
> > +}
> > +EXPORT_SYMBOL_GPL(coresight_timeout_retval);
> > +
> > +/**
> > + * coresight_timeout - loop until a bit has changed to a specific register
> > + *                  state
> > + * @csa: coresight device access for the device
> > + * @offset: Offset of the register from the base of the device.
> > + * @position: the position of the bit of interest.
> > + * @value: the value the bit should have.
> > + *
> > + * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
> > + * TIMEOUT_US has elapsed, which ever happens first.
> > + */
> > +int coresight_timeout(struct csdev_access *csa, u32 offset,
> > +                   int position, int value)
> > +{
> > +     u32 rval = 0;
> > +
> > +     return coresight_timeout_retval(csa, offset, position, value, &rval);
>
>         return core_timeout_retval(csa, offset, position, value, NULL);
>
> Suzuki
>
> >   }
> >   EXPORT_SYMBOL_GPL(coresight_timeout);
> >
> > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > index 055ce5cd5c44..29cb71e82b0b 100644
> > --- a/include/linux/coresight.h
> > +++ b/include/linux/coresight.h
> > @@ -639,6 +639,8 @@ extern int coresight_enable_sysfs(struct coresight_device *csdev);
> >   extern void coresight_disable_sysfs(struct coresight_device *csdev);
> >   extern int coresight_timeout(struct csdev_access *csa, u32 offset,
> >                            int position, int value);
> > +extern int coresight_timeout_retval(struct csdev_access *csa, u32 offset,
> > +                                 int position, int value, u32 *rval);
> >
> >   extern int coresight_claim_device(struct coresight_device *csdev);
> >   extern int coresight_claim_device_unlocked(struct coresight_device *csdev);
>


-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From Frank.li at nxp.com  Fri Dec 13 11:11:05 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 13 Dec 2024 14:11:05 -0500
Subject: [PATCH 2/2] nvmem: imx-ocotp-ele: Support accessing controller
 for i.MX9
In-Reply-To: <cf153dd6-f82c-47d9-9ab4-f247437d607e@kernel.org>
References: <20241212-imx-ocotp-v1-0-198bb0af86a0@nxp.com>
 <20241212-imx-ocotp-v1-2-198bb0af86a0@nxp.com>
 <cf153dd6-f82c-47d9-9ab4-f247437d607e@kernel.org>
Message-ID: <Z1yGycDxf329m3bC@lizhi-Precision-Tower-5810>

On Fri, Dec 13, 2024 at 08:52:49AM +0100, Krzysztof Kozlowski wrote:
> On 12/12/2024 09:24, Peng Fan (OSS) wrote:
> > +
> > +			if (imx_ele_ocotp_check_access(pdev, id)) {
> > +				of_detach_node(child);
> > +				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
> > +					child->full_name);
> > +			}
> > +		}
> > +
> > +		imx_ele_ocotp_grant_access(pdev, child);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx_ele_ocotp_access_control(struct platform_device *pdev)
> > +{
> > +	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
> > +	struct device_node *soc __free(device_node) = of_find_node_by_path("/soc");
>
> No, you just created undocumented ABI on the name.
>
> Drop/replace or express the ABI (which is impossible, so basically: drop).

How about iterate whole tree by use bfs method? So no undocumented ABI.

Frank

>
>
> Best regards,
> Krzysztof


From Frank.li at nxp.com  Fri Dec 13 11:15:56 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 13 Dec 2024 14:15:56 -0500
Subject: [PATCH v2] arm64: dts: s32g: add I2C support
In-Reply-To: <20241213142250.2532559-1-ciprianmarian.costea@oss.nxp.com>
References: <20241213142250.2532559-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <Z1yH7BFbYuJ++Vd1@lizhi-Precision-Tower-5810>

On Fri, Dec 13, 2024 at 04:22:50PM +0200, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>
> Add the I2C Devicetree nodes and pinmux for S32G2 and S32G3 SoCs.
>
> With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
> (rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
> are quite similar. The common part for the EVB revisions will be
> centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
> be placed in 's32gxxa-rdb.dtsi' file.
>
> This refactor will also serve for other modules in the future, such as
> FlexCAN, DSPI.
>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> ---

Change log here!

>  arch/arm64/boot/dts/freescale/s32g2.dtsi      |  45 ++++++
>  .../arm64/boot/dts/freescale/s32g274a-evb.dts |   1 +

Shawn require board dts should be seperate patch

>  .../boot/dts/freescale/s32g274a-rdb2.dts      |   1 +
>  arch/arm64/boot/dts/freescale/s32g3.dtsi      |  50 ++++++
>  .../boot/dts/freescale/s32g399a-rdb3.dts      |   9 ++
>  .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
>  .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 126 +++++++++++++++
>  7 files changed, 382 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>
> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> index 7be430b78c83..0e6c847ab0c3 100644
> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> @@ -333,6 +333,33 @@ uart1: serial at 401cc000 {
>  			status = "disabled";
>  		};
>
> +		i2c0: i2c at 401e4000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x401e4000 0x1000>;
> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c1: i2c at 401e8000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x401e8000 0x1000>;
> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c2: i2c at 401ec000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x401ec000 0x1000>;
> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		uart2: serial at 402bc000 {
>  			compatible = "nxp,s32g2-linflexuart",
>  				     "fsl,s32v234-linflexuart";
> @@ -341,6 +368,24 @@ uart2: serial at 402bc000 {
>  			status = "disabled";
>  		};
>
> +		i2c3: i2c at 402d8000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x402d8000 0x1000>;
> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c4: i2c at 402dc000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x402dc000 0x1000>;
> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		usdhc0: mmc at 402f0000 {
>  			compatible = "nxp,s32g2-usdhc";
>  			reg = <0x402f0000 0x1000>;
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> index b9a119eea2b7..c4a195dd67bf 100644
> --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> @@ -7,6 +7,7 @@
>  /dts-v1/;
>
>  #include "s32g2.dtsi"
> +#include "s32gxxxa-evb.dtsi"
>
>  / {
>  	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> index aaa61a8ad0da..b5ba51696f43 100644
> --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> @@ -7,6 +7,7 @@
>  /dts-v1/;
>
>  #include "s32g2.dtsi"
> +#include "s32gxxxa-rdb.dtsi"
>
>  / {
>  	model = "NXP S32G2 Reference Design Board 2 (S32G-VNP-RDB2)";
> diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> index 6c572ffe37ca..666e4029e588 100644
> --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> @@ -390,6 +390,36 @@ uart1: serial at 401cc000 {
>  			status = "disabled";
>  		};
>
> +		i2c0: i2c at 401e4000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x401e4000 0x1000>;
> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c1: i2c at 401e8000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x401e8000 0x1000>;
> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c2: i2c at 401ec000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x401ec000 0x1000>;
> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		uart2: serial at 402bc000 {
>  			compatible = "nxp,s32g3-linflexuart",
>  				     "fsl,s32v234-linflexuart";
> @@ -398,6 +428,26 @@ uart2: serial at 402bc000 {
>  			status = "disabled";
>  		};
>
> +		i2c3: i2c at 402d8000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x402d8000 0x1000>;
> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c4: i2c at 402dc000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x402dc000 0x1000>;
> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		usdhc0: mmc at 402f0000 {
>  			compatible = "nxp,s32g3-usdhc",
>  				     "nxp,s32g2-usdhc";
> diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> index 828e353455b5..5f8739c068c6 100644
> --- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> @@ -8,6 +8,7 @@
>  /dts-v1/;
>
>  #include "s32g3.dtsi"
> +#include "s32gxxxa-rdb.dtsi"
>
>  / {
>  	model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
> @@ -39,6 +40,14 @@ &uart1 {
>  	status = "okay";
>  };
>
> +&i2c4 {
> +	ina231 at 40 {
> +		compatible = "ti,ina231";
> +		reg = <0x40>;
> +		shunt-resistor = <1000>;
> +	};
> +};
> +
>  &usdhc0 {
>  	pinctrl-names = "default", "state_100mhz", "state_200mhz";
>  	pinctrl-0 = <&pinctrl_usdhc0>;
> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
> new file mode 100644
> index 000000000000..a44eff28073a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
> @@ -0,0 +1,150 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> +/*
> + * Copyright 2024 NXP
> + *
> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
> + *          Larisa Grigore <larisa.grigore at nxp.com>
> + */
> +
> +&pinctrl {
> +	i2c0_pins: i2c0-pins {
> +		i2c0-grp0 {
> +			pinmux = <0x101>, <0x111>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-grp1 {
> +			pinmux = <0x2352>, <0x2362>;
> +		};
> +	};
> +
> +	i2c0_gpio_pins: i2c0-gpio-pins {
> +		i2c0-gpio-grp0 {
> +			pinmux = <0x100>, <0x110>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-gpio-grp1 {
> +			pinmux = <0x2350>, <0x2360>;
> +		};
> +	};
> +
> +	i2c1_pins: i2c1-pins {
> +		i2c1-grp0 {
> +			pinmux = <0x131>, <0x141>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c1-grp1 {
> +			pinmux = <0x2cd2>, <0x2ce2>;
> +		};
> +	};
> +
> +	i2c1_gpio_pins: i2c1-gpio-pins {
> +		i2c1-gpio-grp0 {
> +			pinmux = <0x130>, <0x140>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c1-gpio-grp1 {
> +			pinmux = <0x2cd0>, <0x2ce0>;
> +		};
> +	};
> +
> +	i2c2_pins: i2c2-pins {
> +		i2c2-grp0 {
> +			pinmux = <0x151>, <0x161>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c2-grp1 {
> +			pinmux = <0x2cf2>, <0x2d02>;
> +		};
> +	};
> +
> +	i2c2_gpio_pins: i2c2-gpio-pins {
> +		i2c2-gpio-grp0 {
> +			pinmux = <0x150>, <0x160>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c2-gpio-grp1 {
> +			pinmux = <0x2cf0>, <0x2d00>;
> +		};
> +	};
> +
> +	i2c4_pins: i2c4-pins {
> +		i2c4-grp0 {
> +			pinmux = <0x211>, <0x222>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-grp1 {
> +			pinmux = <0x2d43>, <0x2d33>;
> +		};
> +	};
> +
> +	i2c4_gpio_pins: i2c4-gpio-pins {
> +		i2c4-gpio-grp0 {
> +			pinmux = <0x210>, <0x220>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-gpio-grp1 {
> +			pinmux = <0x2d40>, <0x2d30>;
> +		};
> +	};
> +};
> +
> +&i2c0 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c0_pins>;
> +	pinctrl-1 = <&i2c0_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c1 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c1_pins>;
> +	pinctrl-1 = <&i2c1_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c2_pins>;
> +	pinctrl-1 = <&i2c2_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c4 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c4_pins>;
> +	pinctrl-1 = <&i2c4_gpio_pins>;
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
> new file mode 100644
> index 000000000000..50fe6aaa1605
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
> @@ -0,0 +1,126 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> +/*
> + * Copyright 2024 NXP
> + *
> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
> + *          Larisa Grigore <larisa.grigore at nxp.com>
> + */
> +
> +&pinctrl {
> +	i2c0_pins: i2c0-pins {
> +		i2c0-grp0 {
> +			pinmux = <0x1f2>, <0x201>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-grp1 {
> +			pinmux = <0x2353>, <0x2363>;
> +		};
> +	};
> +
> +	i2c0_gpio_pins: i2c0-gpio-pins {
> +		i2c0-gpio-grp0 {
> +			pinmux = <0x1f0>, <0x200>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-gpio-grp1 {
> +			pinmux = <0x2350>, <0x2360>;
> +		};
> +	};
> +
> +	i2c2_pins: i2c2-pins {
> +		i2c2-grp0 {
> +			pinmux = <0x151>, <0x161>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c2-grp1 {
> +			pinmux = <0x2cf2>, <0x2d02>;
> +		};
> +	};
> +
> +	i2c2_gpio_pins: i2c2-gpio-pins {
> +		i2c2-gpio-grp0 {
> +			pinmux = <0x2cf0>, <0x2d00>;
> +		};
> +
> +		i2c2-gpio-grp1 {
> +			pinmux = <0x150>, <0x160>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +	};
> +
> +	i2c4_pins: i2c4-pins {
> +		i2c4-grp0 {
> +			pinmux = <0x211>, <0x222>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-grp1 {
> +			pinmux = <0x2d43>, <0x2d33>;
> +		};
> +	};
> +
> +	i2c4_gpio_pins: i2c4-gpio-pins {
> +		i2c4-gpio-grp0 {
> +			pinmux = <0x210>, <0x220>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-gpio-grp1 {
> +			pinmux = <0x2d40>, <0x2d30>;
> +		};
> +	};
> +};
> +
> +&i2c0 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;

I remember I have said "#address-cells" and "#size-cells" should be in
dtsi to avoid copy it at each board dts file.

Frank

> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c0_pins>;
> +	pinctrl-1 = <&i2c0_gpio_pins>;
> +	status = "okay";
> +
> +	pcal6524: gpio-expander at 22 {
> +		compatible = "nxp,pcal6524";
> +		reg = <0x22>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c2_pins>;
> +	pinctrl-1 = <&i2c2_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c4 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c4_pins>;
> +	pinctrl-1 = <&i2c4_gpio_pins>;
> +	status = "okay";
> +};
> --
> 2.45.2
>


From linux at armlinux.org.uk  Fri Dec 13 11:21:38 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 19:21:38 +0000
Subject: [PATCH net-next 2/2] net: stmmac: dwmac-socfpga: Set interface
 modes from Lynx PCS as supported
In-Reply-To: <20241213182904.55eb2504@fedora.home>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
 <20241213090526.71516-3-maxime.chevallier@bootlin.com>
 <Z1wnFXlgEU84VX8F@shell.armlinux.org.uk>
 <20241213182904.55eb2504@fedora.home>
Message-ID: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>

On Fri, Dec 13, 2024 at 06:29:04PM +0100, Maxime Chevallier wrote:
> Hi Russell,
> 
> On Fri, 13 Dec 2024 12:22:45 +0000
> "Russell King (Oracle)" <linux at armlinux.org.uk> wrote:
> 
> > On Fri, Dec 13, 2024 at 10:05:25AM +0100, Maxime Chevallier wrote:
> > > On Socfpga, the dwmac controller uses a variation of the Lynx PCS to get
> > > additional support for SGMII and 1000BaseX. The switch between these
> > > modes may occur at runtime (e.g. when the interface is wired to an SFP
> > > cage). In such case, phylink will validate the newly selected interface
> > > between the MAC and SFP based on the internal "supported_interfaces"
> > > field.
> > > 
> > > For now in stmmac, this field is populated based on :
> > >  - The interface specified in firmware (DT)
> > >  - The interfaces supported by XPCS, when XPCS is in use.
> > > 
> > > In our case, the PCS in Lynx and not XPCS.
> > > 
> > > This commit makes so that the .pcs_init() implementation of
> > > dwmac-socfpga populates the supported_interface when the Lynx PCS was
> > > successfully initialized.  
> > 
> > I think it would also be worth adding this to Lynx, so phylink also
> > gets to know (via its validation) which PHY interface modes the PCS
> > can support.
> > 
> > However, maybe at this point we need to introduce an interface bitmap
> > into struct phylink_pcs so that these kinds of checks can be done in
> > phylink itself when it has the PCS, and it would also mean that stmmac
> > could do something like:
> > 
> > 	struct phylink_pcs *pcs;
> > 
> > 	if (priv->hw->xpcs)
> > 		pcs = xpcs_to_phylink_pcs(priv->hw->xpcs);
> > 	else
> > 		pcs = priv->hw->phylink_pcs;
> > 
> > 	if (pcs)
> > 		phy_interface_or(priv->phylink_config.supported_interfaces,
> > 				 priv->phylink_config.supported_interfaces,
> > 				 pcs->supported_interfaces);
> > 
> > and not have to worry about this from individual PCS or platform code.
> 
> I like the idea, I will give it a go and send a series for that if
> that's ok :)

I've actually already created that series!

-- 
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  Fri Dec 13 11:35:01 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 19:35:01 +0000
Subject: [PATCH net-next 3/5] net: pcs: mtk-lynxi: fill in PCS
 supported_interfaces
In-Reply-To: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
Message-ID: <E1tMBRF-006vae-WC@rmk-PC.armlinux.org.uk>

Fill in the new PCS supported_interfaces member with the interfaces
that the Mediatek LynxI supports.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/pcs/pcs-mtk-lynxi.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 7de804535229..1377fb78eaa1 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -306,6 +306,11 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
 	mpcs->pcs.poll = true;
 	mpcs->interface = PHY_INTERFACE_MODE_NA;
 
+	__set_bit(PHY_INTERFACE_MODE_SGMII, mpcs->pcs.supported_interfaces);
+	__set_bit(PHY_INTERFACE_MODE_QSGMII, mpcs->pcs.supported_interfaces);
+	__set_bit(PHY_INTERFACE_MODE_1000BASEX, mpcs->pcs.supported_interfaces);
+	__set_bit(PHY_INTERFACE_MODE_2500BASEX, mpcs->pcs.supported_interfaces);
+
 	return &mpcs->pcs;
 }
 EXPORT_SYMBOL(mtk_pcs_lynxi_create);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Fri Dec 13 11:35:07 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 19:35:07 +0000
Subject: [PATCH net-next 4/5] net: pcs: lynx: fill in PCS supported_interfaces
In-Reply-To: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
Message-ID: <E1tMBRL-006van-3c@rmk-PC.armlinux.org.uk>

Fill in the new PCS supported_interfaces member with the interfaces
that Lynx supports.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/pcs/pcs-lynx.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/net/pcs/pcs-lynx.c b/drivers/net/pcs/pcs-lynx.c
index 767a8c0714ac..6457190ec6e7 100644
--- a/drivers/net/pcs/pcs-lynx.c
+++ b/drivers/net/pcs/pcs-lynx.c
@@ -334,9 +334,19 @@ static const struct phylink_pcs_ops lynx_pcs_phylink_ops = {
 	.pcs_link_up = lynx_pcs_link_up,
 };
 
+static const phy_interface_t lynx_interfaces[] = {
+	PHY_INTERFACE_MODE_SGMII,
+	PHY_INTERFACE_MODE_QSGMII,
+	PHY_INTERFACE_MODE_1000BASEX,
+	PHY_INTERFACE_MODE_2500BASEX,
+	PHY_INTERFACE_MODE_10GBASER,
+	PHY_INTERFACE_MODE_USXGMII,
+};
+
 static struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
 {
 	struct lynx_pcs *lynx;
+	int i;
 
 	lynx = kzalloc(sizeof(*lynx), GFP_KERNEL);
 	if (!lynx)
@@ -348,6 +358,9 @@ static struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
 	lynx->pcs.neg_mode = true;
 	lynx->pcs.poll = true;
 
+	for (i = 0; i < ARRAY_SIZE(lynx_interfaces); i++)
+		__set_bit(lynx_interfaces[i], lynx->pcs.supported_interfaces);
+
 	return lynx_to_phylink_pcs(lynx);
 }
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Fri Dec 13 11:35:12 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 19:35:12 +0000
Subject: [PATCH net-next 5/5] net: stmmac: use PCS supported_interfaces
In-Reply-To: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
Message-ID: <E1tMBRQ-006vat-7F@rmk-PC.armlinux.org.uk>

Use the PCS' supported_interfaces member to build the MAC level
supported_interfaces bitmap.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d45fd7a3acd5..0e45c4a48bb5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1206,6 +1206,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 	struct stmmac_mdio_bus_data *mdio_bus_data;
 	int mode = priv->plat->phy_interface;
 	struct fwnode_handle *fwnode;
+	struct phylink_pcs *pcs;
 	struct phylink *phylink;
 
 	priv->phylink_config.dev = &priv->dev->dev;
@@ -1227,8 +1228,14 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 
 	/* If we have an xpcs, it defines which PHY interfaces are supported. */
 	if (priv->hw->xpcs)
-		xpcs_get_interfaces(priv->hw->xpcs,
-				    priv->phylink_config.supported_interfaces);
+		pcs = xpcs_to_phylink_pcs(priv->hw->xpcs);
+	else
+		pcs = priv->hw->phylink_pcs;
+
+	if (pcs)
+		phy_interface_or(priv->phylink_config.supported_interfaces,
+				 priv->phylink_config.supported_interfaces,
+				 pcs->supported_interfaces);
 
 	fwnode = priv->plat->port_node;
 	if (!fwnode)
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Fri Dec 13 11:34:51 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 19:34:51 +0000
Subject: [PATCH net-next 1/5] net: phylink: add support for PCS
 supported_interfaces bitmap
In-Reply-To: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
Message-ID: <E1tMBR5-006vaS-Ou@rmk-PC.armlinux.org.uk>

Add support for the PCS to specify which interfaces it supports, which
can be used by MAC drivers to build the main supported_interfaces
bitmap. Phylink also validates that the PCS returned by the MAC driver
supports the interface that the MAC was asked for.

An empty supported_interfaces bitmap from the PCS indicates that it
does not provide this information, and we handle that appropriately.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/phy/phylink.c | 11 +++++++++++
 include/linux/phylink.h   |  3 +++
 2 files changed, 14 insertions(+)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 95fbc363f9a6..3e9960f54550 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -691,6 +691,17 @@ static int phylink_validate_mac_and_pcs(struct phylink *pl,
 			return -EINVAL;
 		}
 
+		/* Ensure that this PCS supports the interface which the MAC
+		 * returned it for. It is an error for the MAC to return a PCS
+		 * that does not support the interface mode.
+		 */
+		if (!phy_interface_empty(pcs->supported_interfaces) &&
+		    !test_bit(state->interface, pcs->supported_interfaces)) {
+			phylink_err(pl, "MAC returned PCS which does not support %s\n",
+				    phy_modes(state->interface));
+			return -EINVAL;
+		}
+
 		/* Validate the link parameters with the PCS */
 		if (pcs->ops->pcs_validate) {
 			ret = pcs->ops->pcs_validate(pcs, supported, state);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 5462cc6a37dc..4b7a20620b49 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -393,6 +393,8 @@ struct phylink_pcs_ops;
 
 /**
  * struct phylink_pcs - PHYLINK PCS instance
+ * @supported_interfaces: describing which PHY_INTERFACE_MODE_xxx
+ *                        are supported by this PCS.
  * @ops: a pointer to the &struct phylink_pcs_ops structure
  * @phylink: pointer to &struct phylink_config
  * @neg_mode: provide PCS neg mode via "mode" argument
@@ -409,6 +411,7 @@ struct phylink_pcs_ops;
  * the PCS driver.
  */
 struct phylink_pcs {
+	DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
 	const struct phylink_pcs_ops *ops;
 	struct phylink *phylink;
 	bool neg_mode;
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Fri Dec 13 11:34:56 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 19:34:56 +0000
Subject: [PATCH net-next 2/5] net: pcs: xpcs: fill in PCS supported_interfaces
In-Reply-To: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
Message-ID: <E1tMBRA-006vaY-Sv@rmk-PC.armlinux.org.uk>

Fill in the new PCS supported_interfaces member with the interfaces
that XPCS supports.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/pcs/pcs-xpcs.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index f70ca39f0905..cf41dc5e74e8 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -1446,6 +1446,8 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev)
 	if (ret)
 		goto out_clear_clks;
 
+	xpcs_get_interfaces(xpcs, xpcs->pcs.supported_interfaces);
+
 	if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
 		xpcs->pcs.poll = false;
 	else
-- 
2.30.2



From smostafa at google.com  Fri Dec 13 11:39:04 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Fri, 13 Dec 2024 19:39:04 +0000
Subject: [RFC PATCH v2 00/58] KVM: Arm SMMUv3 driver for pKVM
In-Reply-To: <20241212194119.GA4679@ziepe.ca>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212194119.GA4679@ziepe.ca>
Message-ID: <Z1yNWI9lBNIZg6Le@google.com>

Hi Jason,

Thanks a lot for taking the time to review this, I tried to reply to all
points. However I think a main source of confusion was that this is only
for the host kernel not guests, with this series guests still have no
access to DMA under pKVM. I hope that clarifies some of the points.

On Thu, Dec 12, 2024 at 03:41:19PM -0400, Jason Gunthorpe wrote:
> On Thu, Dec 12, 2024 at 06:03:24PM +0000, Mostafa Saleh wrote:
> 
> > This series adds a hypervisor driver for the Arm SMMUv3 IOMMU. Since the
> > hypervisor part of pKVM (called nVHE here) is minimal, moving the whole
> > host SMMU driver into nVHE isn't really an option. It is too large and
> > complex and requires infrastructure from all over the kernel. We add a
> > reduced nVHE driver that deals with populating the SMMU tables and the
> > command queue, and the host driver still deals with probing and some
> > initialization.
> 
> The cover letter doesn't explain why someone needs page tables in the
> guest at all?

This is not for guests but for the host, the hypervisor needs to
establish DMA isolation between the host and the hypervisor/guests.
Before these patches; as mentioned, a host can program a DMA device
to read/write any memory (that has nothing to do with whether the
guest has DMA access or not).

So it?s mandatory for pKVM to establish DMA isolation, otherwise
it can be easily defeated.

However, guest DMA support is optional and only needed for device
passthrough, I have some patches to support that in pKVM also(only with
vfio-platform), but it?s unlikely to be posted upstream before merging a
host DMA isolation solution first as it?s mandatory.

> 
> If you are able to implement nested support then you can boot the
> guest with no-iommu and an effective identity translation through a
> hypervisor controlled S2. ie no guest map/unmap. Great DMA
> performance.

We can do that for the host also, which is discussed in the v1 cover
letter. However, we try to keep feature parity with the normal (VHE)
KVM arm64 support, so constraining KVM support to not have IOVA spaces
for devices seems too much and impractical on modern systems (phones for
example).

> 
> I thought the point of doing the paravirt here was to allow dynamic
> pinning of the guest memory? This is the primary downside with nested.
> The entire guest memory has to be pinned down at guest boot.

As this is for the host, memory pinning is not really an issue (However,
with nesting and shared CPU stage-2 there are other challenges as
mentioned).

> 
> > 1. Paravirtual I/O page tables
> > This is the solution implemented in this series. The host creates
> > IOVA->HPA mappings with two hypercalls map_pages() and unmap_pages(), and
> > the hypervisor populates the page tables. Page tables are abstracted into
> > IOMMU domains, which allow multiple devices to share the same address
> > space. Another four hypercalls, alloc_domain(), attach_dev(), detach_dev()
> > and free_domain(), manage the domains, the semantics of those hypercalls
> > are almost identical to the IOMMU ops which make the kernel driver part
> > simpler.
> 
> That is re-inventing virtio-iommu. I don't really understand why this
> series is hacking up arm-smmuv3 so much, that is not, and should not,
> be a paravirt driver. Why not create a clean new pkvm specific driver
> for the paravirt?? Or find a way to re-use parts of virtio-iommu?
> 
> Shouldn't other arch versions of pkvm be able to re-use the same guest
> iommu driver?

As mentioned, this is for the host kernel not the guest. However the
hypervisor/kernel interface is not IOMMU specific. And it can be extended
to other IOMMUs/archs.

There is no hacking for the arm-smmu-v3 driver, but mostly splitting
the driver so it can be re-used + introduction for a separate hypervisor
driver, it?s similar to how SVA re-use part of the driver also but just
on a bigger scale.

> 
> > b- Locking: The io-pgtable-arm is lockless under some guarantees of how
> >    the IOMMU code behaves. However with pKVM, the kernel is not trusted
> >    and a malicious kernel can issue concurrent requests causing memory
> >    corruption or UAF, so that it has to be locked in the hypervisor.
> 
> ? I don't get it, the hypervisor page table has to be private to the
> hypervisor. It is not that io-pgtable-arm is lockless, it is that it
> relies on a particular kind of caller supplied locking. pkvm's calls
> into its private io-pgtable-arm would need pkvm specific locking that
> makes sense for it. Where does a malicious guest kernel get into this?

At the moment when the kernel driver uses the io-pgtable-arm, it doesn?t
protect it with any locks under some assumptions, for example, unmapping
a table with block size and a leaf inside it with page size concurrently
can cause a UAF, but the DMA API never does that.

With pKVM, the host kernel is not trusted, and if compromised it can
instrument such attacks to corrupt hypervisor memory, so the hypervisor
would lock io-pgtable-arm operations in EL2 to avoid that.

> 
> > 2. Nested SMMUv3 translation (with emulation)
> > Another approach is to rely on nested translation support which is
> > optional in SMMUv3, that requires an architecturally accurate emulation
> > of SMMUv3 which can be complicated including cmdq emulation.
> 
> The confidential compute folks are going in this direction.

I see, but one key advantage for pKVM that it requires minimum hardware,
with the paravirtual approach we can support single stage SMMUv3 or even
non-architected IOMMUs, that + the DMA performance, might give it slight
edge, but as I mentioned I plan to do more throughout comparison with
nesting and maybe discuss it in a conference this year.

> 
> > The trade off between the 2 approaches can be roughly summarised as:
> > Paravirtualization:
> > - Compatible with more HW (and IOMMUs).
> > - Better DMA performance due to shorter table walks/less TLB pressure
> > - Needs extra complexity to squeeze the last bit of optimization (around
> >   unmap, and map_sg).
> 
> It has better straight line DMA performance if the DMAs are all
> static. Generally much, much worse performance if the DMAs are
> dynamically mapped as you have to trap so much stuff.

I agree it?s not that clear, I will finish the nested implementation
and run some standard IO benchmarks.

> 
> The other negative is there is no way to get SVA support with
> para-virtualization.
> 
Yeah, SVA is tricky, I guess for that we would have to use nesting,
but tbh, I don?t think it?s a deal breaker for now.

> The positive is you don't have to pin the VM's memory.
> 
> > Nested Emulation
> > - Faster map_pages (not sure about unmap because it requires cmdq
> >   emulation for TLB invalidation if DVM not used).
> 
> If you can do nested then you can run in identity mode and then you
> don't have any performance down side. It is a complete win.

Unfortunately, as mentioned above it?s not that practical, many devices
in mobile space expect IO translation capability.

> 
> Even if you do non-idenity nested is still likely faster for changing
> translation than paravirt approaches. A single cmdq range invalidate
> should be about the same broad overhead as a single paravirt call to
> unmap except they can be batched under load.
> 
> Things like vCMDQ eliminate this overhead entirely, to my mind that is
> the future direction of this HW as you obviously need to HW optimize
> invalidation...
> 
> > - Needs extra complexity for architecturally emulating SMMUv3.
> 
> Lots of people have now done this, it is not really so bad. In
> exchange you get a full architected feature set, better performance,
> and are ready for HW optimizations.

It?s not impossible, it?s just more complicated doing it in the
hypervisor which has limited features compared to the kernel + I haven?t
seen any open source implementation for that except for Qemu which is in
userspace.

> 
> > - Add IDENTITY_DOMAIN support, I already have some patches for that, but
> >   didn?t want to complicate this series, I can send them separately.
> 
> This seems kind of pointless to me. If you can tolerate identity (ie
> pin all memory) then do nested, and maybe don't even bother with a
> guest iommu.

As mentioned, the choice for para-virt was not only to avoid pinning,
as this is the host, for IDENTITY_DOMAIN we either share the page table,
then we have to deal with lazy mapping (SMMU features, BBM...) or mirror
the table in a shadow SMMU only identity page table.

> 
> If you want most of the guest memory to be swappable/movable/whatever
> then paravirt is the only choice, and you really don't want the guest
> to have any identiy support at all.
> 
> Really, I think you'd want to have both options, there is no "best"
> here. It depends what people want to use the VM for.
> 
> My advice for merging would be to start with the pkvm side setting up
> a fully pinned S2 and do not have a guest driver. Nesting without
> emulating smmuv3. Basically you get protected identity DMA support. I
> think that would be a much less sprawling patch series. From there it
> would be well positioned to add both smmuv3 emulation and a paravirt
> iommu flow.
> 

I am open to any suggestions, but I believe any solution considered for
merge, should have enough features to be usable on actual systems (translating
IOMMU can be used for example) so either para-virt as this series or full
nesting as the PoC above (or maybe both?), which IMO comes down to the
trade-off mentioned above.

Thanks,
Mostafa

> Jason


From linux at armlinux.org.uk  Fri Dec 13 11:45:17 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 19:45:17 +0000
Subject: [PATCH net-next v4 5/9] net: sparx5: only return PCS for modes
 that require it
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-5-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
 <20241213-sparx5-lan969x-switch-driver-4-v4-5-d1a72c9c4714@microchip.com>
Message-ID: <Z1yOzaL-gwXIE94O@shell.armlinux.org.uk>

On Fri, Dec 13, 2024 at 02:41:04PM +0100, Daniel Machon wrote:
> The RGMII ports have no PCS to configure. Make sure we only return the
> PCS for port modes that require it.
> 
> Signed-off-by: Daniel Machon <daniel.machon at microchip.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 smostafa at google.com  Fri Dec 13 11:48:52 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Fri, 13 Dec 2024 19:48:52 +0000
Subject: [RFC PATCH v2 40/58] KVM: arm64: smmu-v3: Add map/unmap pages
 and iova_to_phys
In-Reply-To: <20241212194435.GA5484@ziepe.ca>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-41-smostafa@google.com>
 <20241212194435.GA5484@ziepe.ca>
Message-ID: <Z1yPpEn_MElCRzLG@google.com>

Hi Jason,

On Thu, Dec 12, 2024 at 03:44:35PM -0400, Jason Gunthorpe wrote:
> On Thu, Dec 12, 2024 at 06:04:04PM +0000, Mostafa Saleh wrote:
> > Add map_pages and iova_to_phys HVC code, which
> > mainly calls the io-pgtable.
> > 
> > For unmap_pages, we rely on IO_PGTABLE_QUIRK_UNMAP_INVAL, where the
> > driver first calls unmap_pages which invalidate all the pages as
> > a typical unmap, issuing all the necessary TLB invalidations.
> > Then, we will start a page table with 2 callbacks:
> > - visit_leaf: for each unmapped leaf, it would decrement the refcount
> >   of the page using __pkvm_host_unuse_dma(), reversing the what IOMMU
> >   core does in map.
> > - visit_post_table: this would free any invalidated tables as they
> >   wouldn't be freed because of the quirk.
> 
> I don't know if the timelines will work out, but the pagetable stuff
> I'm working on will let you write a much more appropriate
> implementation for pkvm's usage than trying to hack it into the
> iopgtable code like this.

I didn?t check your new page table patches yet, but I would say it?s
more likely your patches would land first, because as mentioned in the
cover letter, there are still many dependencies for pKVM before IOMMU
support lands, so I don?t mind converging if possible.

Thanks,
Mostafa

> 
> Even the iommu focused routines I have got now would solve this
> problem because they allways spit out a linked list of all the memory
> to free after map/unmap and never internally free it..

> 
> Jason


From linux at armlinux.org.uk  Fri Dec 13 11:48:59 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 19:48:59 +0000
Subject: [PATCH net-next v4 6/9] net: sparx5: verify RGMII speeds
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-6-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
 <20241213-sparx5-lan969x-switch-driver-4-v4-6-d1a72c9c4714@microchip.com>
Message-ID: <Z1yPq6OEziTNjWHK@shell.armlinux.org.uk>

On Fri, Dec 13, 2024 at 02:41:05PM +0100, Daniel Machon wrote:
> When doing a port config, we verify the port speed against the PHY mode
> and supported speeds of that PHY mode. Add checks for the four RGMII phy
> modes: RGMII, RGMII_ID, RGMII_TXID and RGMII_RXID.
> 
> Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
> Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
> Signed-off-by: Daniel Machon <daniel.machon at microchip.com>

You do realise that phylink knows what speeds each interface supports
(see phylink_get_capabilities()) and restricts the media advertisement
to ensure that ethtool link modes that can't be supported by the MAC
capabilities and set of interfaces that would be used are not
advertised.

This should mean none of your verification ever triggers. If it does,
then I'd like to know 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 Hermann.Lauer at uni-heidelberg.de  Fri Dec 13 11:54:33 2024
From: Hermann.Lauer at uni-heidelberg.de (Hermann.Lauer at uni-heidelberg.de)
Date: Fri, 13 Dec 2024 20:54:33 +0100
Subject: [PATCH v2] ARM: dts: sun8i-r40: remove unused GPIO regulator
Message-ID: <20241213195433.GA1568@lemon.iwr.uni-heidelberg.de>

Subject: [PATCH v2] ARM: dts: sun8i-r40: remove unused GPIO regulator

Banana Pi M2 Ultra V1.1 board resets immediately when the usb core tries
to setup PH23 GPIO. It turned out that the V1.0 board USB-A ports are
always power supplied and according to the board scheme PH23 is simply
not connected.

So remove the PH23 setup: Doesn't harm V1.0 (with R40) and let V1.1
(with A40i) start.

Signed-off-by: Hermann Lauer <Hermann.Lauer at uni-heidelberg.de>
---
V2: shorten subject, rm dangerous PH23 regulator completely

diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
--- a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
+++ b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
@@ -91,15 +91,6 @@
 		};
 	};
 
-	reg_vcc5v0: vcc5v0 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc5v0";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>; /* PH23 */
-		enable-active-high;
-	};
-
 	wifi_pwrseq: pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */
@@ -347,7 +338,5 @@
 };
 
 &usbphy {
-	usb1_vbus-supply = <&reg_vcc5v0>;
-	usb2_vbus-supply = <&reg_vcc5v0>;
 	status = "okay";
 };


From robert.marko at sartura.hr  Fri Dec 13 11:54:29 2024
From: robert.marko at sartura.hr (Robert Marko)
Date: Fri, 13 Dec 2024 20:54:29 +0100
Subject: [PATCH net-next v4 0/9] net: lan969x: add RGMII support
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <CA+HBbNG0k24fO5OG42jw-7trWbT3iVTdo6Hh=55s1MaTh28p-A@mail.gmail.com>

On Fri, Dec 13, 2024 at 2:41?PM Daniel Machon
<daniel.machon at microchip.com> wrote:
>
> == Description:
>
> This series is the fourth of a multi-part series, that prepares and adds
> support for the new lan969x switch driver.
>
> The upstreaming efforts is split into multiple series (might change a
> bit as we go along):
>
>         1) Prepare the Sparx5 driver for lan969x (merged)
>
>         2) Add support for lan969x (same basic features as Sparx5
>            provides excl. FDMA and VCAP, merged).
>
>         3) Add lan969x VCAP functionality (merged).
>
>     --> 4) Add RGMII support.
>
>         5) Add FDMA support.
>
> == RGMII support:
>
> The lan969x switch device includes two RGMII port interfaces (port 28
> and 29) supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps.
>
> == Patch breakdown:
>
> Patch #1 does some preparation work.
>
> Patch #2 adds new function: is_port_rgmii() to the match data ops.
>
> Patch #3 uses the is_port_rgmii() in a number of places.
>
> Patch #4 makes sure that we do not configure an RGMII device as a
>          low-speed device, when doing a port config.
>
> Patch #5 makes sure we only return the PCS if the port mode requires
>          it.
>
> Patch #6 adds checks for RGMII PHY modes in sparx5_verify_speeds().
>
> Patch #7 adds registers required to configure RGMII.
>
> Patch #8 adds RGMII implementation.
>
> Patch #9 documents RGMII delays in the dt-bindings.
>
> Details are in the commit description of the individual patches
>
> To: UNGLinuxDriver at microchip.com
> To: Andrew Lunn <andrew+netdev at lunn.ch>
> 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>
> To: Lars Povlsen <lars.povlsen at microchip.com>
> To: Steen Hegelund <Steen.Hegelund at microchip.com>
> To: Horatiu Vultur <horatiu.vultur at microchip.com>
> To: Russell King <linux at armlinux.org.uk>
> To: jacob.e.keller at intel.com
> To: robh at kernel.org
> To: krzk+dt at kernel.org
> To: conor+dt at kernel.org
> Cc: devicetree at vger.kernel.org
> Cc: netdev at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: robert.marko at sartura.hr
>
> Signed-off-by: Daniel Machon <daniel.machon at microchip.com>

Tested-by: Robert Marko <robert.marko at sartura.hr>

> ---
> Changes in v4:
>
> - Split patch #4 in v3 into two patches, where the new patch #5 handles
>   PCS selection, by returning the PCS only for ports that require it.
>
> - Got rid of the '|' symbol for {rx,tx}-internal-delay-ps property
>   description in the dt-bindings (patch #9).
>
> - Link to v3: https://lore.kernel.org/r/20241118-sparx5-lan969x-switch-driver-4-v3-0-3cefee5e7e3a at microchip.com
>
> Changes in v3:
>
> v2 was kindly tested by Robert Marko. Not carrying the tag to v3 since
> we have changes to the handling of the delays.
>
> - Modified lan969x_rgmii_delay_config() to not apply any MAC delay when
>   the {rx,tx}-internal-delay-ps properties are missing or set to 0
>   (patch #7).
>
> - Removed 'required' constraint from {rx-tx}-internal-delay-ps
>   properties. Also added description and default value (Patch #8).
>
> - Link to v2: https://lore.kernel.org/r/20241113-sparx5-lan969x-switch-driver-4-v2-0-0db98ac096d1 at microchip.com
>
> Changes in v2:
>
>   Most changes are in patch #7. RGMII implementation has been moved to
>   it's own file lan969x_rgmii.c.
>
>   Details:
>
>     - Use ETH_P_8021Q and ETH_P_8021AD instead of the Sparx5 provided
>       equivalents (patch #7).
>     - Configure MAC delays through "{rx,tx}-internal-delay-ps"
>       properties (patch #7).
>     - Add selectors for all the phase shifts that the hardware supports
>       (instead of only 2.0 ns, patch #7).
>     - Add selectors for all the port speeds (instead of only 1000 mbps.)
>     - Document RGMII delays in dt-bindings.
>
>   - Link to v1: https://lore.kernel.org/r/20241106-sparx5-lan969x-switch-driver-4-v1-0-f7f7316436bd at microchip.com
>
> ---
> Daniel Machon (9):
>       net: sparx5: do some preparation work
>       net: sparx5: add function for RGMII port check
>       net: sparx5: use is_port_rgmii() throughout
>       net: sparx5: skip low-speed configuration when port is RGMII
>       net: sparx5: only return PCS for modes that require it
>       net: sparx5: verify RGMII speeds
>       net: lan969x: add RGMII registers
>       net: lan969x: add RGMII implementation
>       dt-bindings: net: sparx5: document RGMII delays
>
>  .../bindings/net/microchip,sparx5-switch.yaml      |  18 ++
>  drivers/net/ethernet/microchip/sparx5/Makefile     |   3 +-
>  .../ethernet/microchip/sparx5/lan969x/lan969x.c    |   5 +
>  .../ethernet/microchip/sparx5/lan969x/lan969x.h    |  10 +
>  .../microchip/sparx5/lan969x/lan969x_rgmii.c       | 224 +++++++++++++++++++++
>  .../net/ethernet/microchip/sparx5/sparx5_main.c    |  29 ++-
>  .../net/ethernet/microchip/sparx5/sparx5_main.h    |   3 +
>  .../ethernet/microchip/sparx5/sparx5_main_regs.h   | 145 +++++++++++++
>  .../net/ethernet/microchip/sparx5/sparx5_phylink.c |  14 +-
>  .../net/ethernet/microchip/sparx5/sparx5_port.c    |  57 ++++--
>  .../net/ethernet/microchip/sparx5/sparx5_port.h    |   5 +
>  11 files changed, 484 insertions(+), 29 deletions(-)
> ---
> base-commit: 2c27c7663390d28bc71e97500eb68e0ce2a7223f
> change-id: 20241104-sparx5-lan969x-switch-driver-4-d59b7820485a
>
> Best regards,
> --
> Daniel Machon <daniel.machon at microchip.com>
>


-- 
Robert Marko
Staff Embedded Linux Engineer
Sartura d.d.
Lendavska ulica 16a
10000 Zagreb, Croatia
Email: robert.marko at sartura.hr
Web: www.sartura.hr


From linux at armlinux.org.uk  Fri Dec 13 12:06:22 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 13 Dec 2024 20:06:22 +0000
Subject: [PATCH net-next 2/7] net: stmmac: move tx_lpi_timer tracking to
 phylib
In-Reply-To: <Z1wTqh-BnvPYLqU8@shell.armlinux.org.uk>
References: <Z1r3MWZOt36SgGxf@shell.armlinux.org.uk>
 <E1tLkSX-006qfS-Rx@rmk-PC.armlinux.org.uk>
 <Z1wTqh-BnvPYLqU8@shell.armlinux.org.uk>
Message-ID: <Z1yTviYUZ8sbNOsK@shell.armlinux.org.uk>

On Fri, Dec 13, 2024 at 10:59:54AM +0000, Russell King (Oracle) wrote:
> On Thu, Dec 12, 2024 at 02:46:33PM +0000, Russell King (Oracle) wrote:
> > @@ -1092,6 +1092,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
> >  			phy_init_eee(phy, !(priv->plat->flags &
> >  				STMMAC_FLAG_RX_CLK_RUNS_IN_LPI)) >= 0;
> >  		priv->eee_enabled = stmmac_eee_init(priv);
> > +		priv->tx_lpi_timer = phy->eee_cfg.tx_lpi_timer;
> >  		priv->tx_lpi_enabled = priv->eee_enabled;
> >  		stmmac_set_eee_pls(priv, priv->hw, true);
> >  	}
> 
> While looking deeper at stmmac, there's a bug in the above hunk -
> stmmac_eee_init() makes use of priv->tx_lpi_timer, so this member
> needs to be set before calling this function. I'll post a v2 shortly.

I'm going to hold off v2, there's a lot more that can be cleaned up
here - the EEE code is rather horrid in stmmac, and there's definitely
one race, and one logical error in it (e.g. why mark software EEE mode
*enabled* when EEE mode is being disabled - which can lead to the EEE
timer being added back onto the timer list.)

There's also weirdness with dwmac4's EEE register fiddling.

The stmmac driver uses hardware timed LPI entry if the timer is small
enough to be programmed into hardware, otherwise it uses software mode.

When software mode wants to enter LPI mode, it sets both:

	GMAC4_LPI_CTRL_STATUS_LPIEN (LPI enable)
	GMAC4_LPI_CTRL_STATUS_LPITXA (LPI TX Automate)

When software mode wants to exit LPI mode, it clears both of these
two bits.

In hardware mode, when enabling LPI generation, we set the hardware LPI
entry timer (separate register) to a non-zero value, and then set:

	GMAC4_LPI_CTRL_STATUS_LPIEN (LPI enable)
	GMAC4_LPI_CTRL_STATUS_LPITXA (LPI TX Automate)
	GMAC4_LPI_CTRL_STATUS_LPIATE (LPI Timer enable)

That seems logical. However, in hardware mode, when we want to then
disable hardware LPI generation, we set the hardware LPI entry timer to
zero, the following bits:

	GMAC4_LPI_CTRL_STATUS_LPIEN (LPI enable)
	GMAC4_LPI_CTRL_STATUS_LPITXA (LPI TX Automate)

and clear:

	GMAC4_LPI_CTRL_STATUS_LPIATE (LPI Timer enable)

So, hardware mode, disabled, ends up setting the same bits as
software mode wanting to generate LPI state on the transmit side.
This makes no sense to me, and looks like another bug in this driver.

Can anyone suggest any hardware that I could source which uses the
dwmac4 code and which supports EEE please, so that I have hardware to
run some tests on.

Thanks.

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


From Frank.li at nxp.com  Fri Dec 13 13:23:12 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 13 Dec 2024 16:23:12 -0500
Subject: [PATCH] arm64: dts: imx8mn-bsh-smm-s2pro: Remove invalid audio
 codec clock
In-Reply-To: <CAOf5uwmg83-TVQvbNOCnzBh9JdQAC=5hpgbCeT-6qJ=+YBrssg@mail.gmail.com>
References: <20240821143420.2564869-1-festevam@gmail.com>
 <CAOf5uwnUPDPVzM7vNPn-tGrt2ENuuUzVfKh1q7AiORcAMZm0UA@mail.gmail.com>
 <CAOMZO5DVy7x62zfX5UbDZUi=c8nbSHfD=Q39faZTBz87bz3W=g@mail.gmail.com>
 <CAOf5uwmg83-TVQvbNOCnzBh9JdQAC=5hpgbCeT-6qJ=+YBrssg@mail.gmail.com>
Message-ID: <Z1ylwPiSt/jRJV8w@lizhi-Precision-Tower-5810>

On Thu, Oct 17, 2024 at 01:50:13PM +0200, Michael Nazzareno Trimarchi wrote:
> Hi Fabio
>
> On Thu, Oct 17, 2024 at 1:43?PM Fabio Estevam <festevam at gmail.com> wrote:
> >
> > Hi Michael,
> >
> > On Tue, Aug 27, 2024 at 9:03?AM Michael Nazzareno Trimarchi
> > <michael at amarulasolutions.com> wrote:
> > >
> > > Hi Fabio
> > >
> > > On Wed, Aug 21, 2024 at 4:34?PM Fabio Estevam <festevam at gmail.com> wrote:
> > > >
> > > > From: Fabio Estevam <festevam at denx.de>
> > > >
> > > > According to ti,tlv320dac3100.yaml, 'clocks' is not a valid
> > > > property.
> > > >
> > > > Remove it to fix the following dt-schema warning:
> > > >
> > > > Unevaluated properties are not allowed ('clocks' was unexpected)
> > > >
> > > > Signed-off-by: Fabio Estevam <festevam at denx.de>
> > > > ---
> > > >  arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2pro.dts | 1 -
> > > >  1 file changed, 1 deletion(-)
> > > >
> > > > diff --git a/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2pro.dts b/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2pro.dts
> > > > index c6ad65becc97..475cbf9e0d1e 100644
> > > > --- a/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2pro.dts
> > > > +++ b/arch/arm64/boot/dts/freescale/imx8mn-bsh-smm-s2pro.dts
> > > > @@ -64,7 +64,6 @@ tlv320dac3101: audio-codec at 18 {
> > > >                 DVDD-supply = <&buck5_reg>;
> > > >                 reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
> > > >                 ai31xx-micbias-vg = <MICBIAS_AVDDV>;
> > > > -               clocks = <&clk IMX8MN_CLK_SAI3_ROOT>;
> > > >         };
> > > >  };
> > >
> > > Let's just give a test to the board
> >
> > Have you had a chance to test it?
>
> I will test on monday ;). Is that ok?

Any update ?

Frank

>
> Michael
>
> --
> Michael Nazzareno Trimarchi
> Co-Founder & Chief Executive Officer
> M. +39 347 913 2170
> michael at amarulasolutions.com
> __________________________________
>
> Amarula Solutions BV
> Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
> T. +31 (0)85 111 9172
> info at amarulasolutions.com
> www.amarulasolutions.com


From saravanak at google.com  Fri Dec 13 14:02:10 2024
From: saravanak at google.com (Saravana Kannan)
Date: Fri, 13 Dec 2024 14:02:10 -0800
Subject: Raspberry Pi 3B: Failed to create device link with soc:firmware:gpio
In-Reply-To: <CAFERDQ0AUhCp_c0LLRRR9SWyvDON-CdXFvK3eqcLFc_SMhdPRw@mail.gmail.com>
References: <CAFERDQ2hLHek+0ViVqbqgOD+4xwC2ZwK1KhgGdLP_zGnonEs4w@mail.gmail.com>
 <d02a7143-43e7-4851-a06e-d57981362a5a@gmx.net> <CAFERDQ0AUhCp_c0LLRRR9SWyvDON-CdXFvK3eqcLFc_SMhdPRw@mail.gmail.com>
Message-ID: <CAGETcx-NWnBDfVq7hwrS7dQDdbEeBaVOuS=YzAfTyS6e6xCUCQ@mail.gmail.com>

On Thu, Dec 12, 2024 at 10:13?AM Martin Wetterwald <martin at wetterwald.eu> wrote:
>
> On Thu, Dec 12, 2024 at 2:16?PM Stefan Wahren <wahrenst at gmx.net> wrote:
> > What happens if you replace your custom config with arm64/defconfig?
> > Does the issue still occurs?
>
> I've just launched a kernel with the arm64 defconfig:
>
> > 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 99, base_baud = 0) is a PL011 rev2
> > serial serial0: tty port ttyAMA0 registered
> > raspberrypi-firmware soc:firmware: Attached to firmware from 2024-09-13T16:00:01
> > hci_uart_bcm serial0-0: supply vbat not found, using dummy regulator
> > hci_uart_bcm serial0-0: supply vddio not found, using dummy regulator
> > Bluetooth: hci0: BCM: chip id 94
> > Bluetooth: hci0: BCM: features 0x2e
> > Bluetooth: hci0: BCM43430A1
> > Bluetooth: hci0: BCM43430A1 (001.002.009) build 0000
>
> And it worked perfectly. Thanks for your suggestion. It confirmed the problem
> came from my kernel config.
>
> I then compared both .config and it appeared I was missing this config flag:
>
> > CONFIG_SERIAL_DEV_CTRL_TTYPORT
>
> I had already enabled CONFIG_SERIAL_DEV_BUS, but not CTRL_TTYPORT.
> Nevertheless, that first kernel config item's prompt had been clear about that,
> but I missed the advice:
>
> > CONFIG_SERIAL_DEV_BUS
> > Core support for devices connected via a serial port.
> > Note that you typically also want to enable TTY port controller support.
>
> It's so much better now to see the HCI attachment handled by the kernel
> directly!

Glad this got sorted out without my help :) Thanks Stefan!


-Saravana


From andrew at lunn.ch  Fri Dec 13 14:03:11 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 13 Dec 2024 23:03:11 +0100
Subject: [PATCH v1 3/8] ARM: dts: aspeed: system1: Add RGMII support
In-Reply-To: <20241213145037.3784931-4-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
 <20241213145037.3784931-4-ninad@linux.ibm.com>
Message-ID: <4a8788c1-8424-40f6-a9da-bf135acad29b@lunn.ch>

> +&mac0 {
> +	status = "okay";
> +
> +	phy-mode = "rgmii-rxid";

Why is everybody getting RGMII wrong this week?

Do you have an extra long clock line on the PCB for the TX clock?

> +	phy-handle = <&ethphy0>;
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_rgmii1_default>;
> +};
> +
>  &mac2 {
>  	status = "okay";
> +
> +	phy-mode = "rgmii";

Do you have extra long clock lines on the PCB for both Rx and Tx
clock?

I suspect you don't and the RGMII delays are messed up somehow.

	Andrew


From pr-tracker-bot at kernel.org  Fri Dec 13 14:34:51 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 13 Dec 2024 22:34:51 +0000
Subject: [GIT PULL] arm64 fixes for 6.13-rc3
In-Reply-To: <Z1xx0ha7lbKkdhRC@arm.com>
References: <Z1xx0ha7lbKkdhRC@arm.com>
Message-ID: <173412929121.3178864.3766212521863822880.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 13 Dec 2024 17:41:38 +0000:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/01af50af760b5b796794282d997a3610f74039da

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From yang at os.amperecomputing.com  Fri Dec 13 14:34:57 2024
From: yang at os.amperecomputing.com (Yang Shi)
Date: Fri, 13 Dec 2024 14:34:57 -0800
Subject: [RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <20241213161726.GA30314@mazurka.cambridge.arm.com>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
 <20241211154611.40395-3-miko.lenczewski@arm.com>
 <20241211210243.GA17155@willie-the-truck>
 <20241213161726.GA30314@mazurka.cambridge.arm.com>
Message-ID: <21e72a5d-d488-4011-9abc-9f717e1c6643@os.amperecomputing.com>



On 12/13/24 8:17 AM, Miko?aj Lenczewski wrote:
>>> +static int do_conflict_abort(unsigned long far, unsigned long esr,
>>> +			     struct pt_regs *regs)
>>> +{
>>> +	if (!system_supports_bbml2())
>>> +		return do_bad(far, esr, regs);
>>> +
>>> +	/* if we receive a TLB conflict abort, we know that there are multiple
>>> +	 * TLB entries that translate the same address range. the minimum set
>>> +	 * of invalidations to clear these entries is implementation defined.
>>> +	 * the maximum set is defined as either tlbi(vmalls12e1) or tlbi(alle1).
>>> +	 *
>>> +	 * if el2 is enabled and stage 2 translation enabled, this may be
>>> +	 * raised as a stage 2 abort. if el2 is enabled but stage 2 translation
>>> +	 * disabled, or if el2 is disabled, it will be raised as a stage 1
>>> +	 * abort.
>>> +	 *
>>> +	 * local_flush_tlb_all() does a tlbi(vmalle1), which is enough to
>>> +	 * handle a stage 1 abort.
>>> +	 */
>>> +
>>> +	local_flush_tlb_all();
>>> +
>>> +	return 0;
>>> +}
>> Can we actually guarantee that we make it this far without taking another
>> abort? Given that I'm yet to see one of these things in the wild, I'm
>> fairly opposed to pretending that we can handle them. We'd be much better
>> off only violating BBM on CPUs that are known to handle the conflict
>> gracefully. Judging by your later patch, this is practically keyed off
>> the MIDR _anyway_...
>>
>> Will

Hi Miko?aj,

> Thanks for reviewing. Apologies for the delay in responding, and for
> spam (replied instead of group-replied).
>
> There should not be an option to take another fault while performing the
> handler, as long as the mappings covering the fault handler table or any
> code in this path are not screwed with. This is discussed further in the
> resent patch series [1].

Will lead me to this thread when we discussed about my series 
(https://lore.kernel.org/lkml/20241211223034.GA17836 at willie-the-truck/#t). 
My series tried to use large mapping for kernel linear mapping when 
rodata=full. The common part of the both series is BBM lv2 support. My 
series depends on BBM lv2 to change page table block size when changing 
permission for kernel linear mapping.

Handling TLB conflict should be ok for your usecase since the conflict 
should just happen in user address space. But it may be not fine for my 
usecase. At least the TLB conflict handler needs to depend on 
CONFIG_VMAP_STACK otherwise the kernel stack pointer points to kernel 
linear address space. I'm not quite sure whether there is any other 
corner case which can trigger recursive abort in the path or not, maybe 
bad stack handler? So Will suggested MIDR based lookup. IIUC, he 
suggested just enable BBM lv2 support on the CPUs which can handle TLB 
conflict gracefully. This should make our lives easier. But the downside 
is maybe fewer CPUs can actually advertise BBM lv2 support.

Thanks,
Yang

> The MIDR revisions will be fixed. I was confused as to which revisions
> were affected on an earlier version of the series, and had missed
> updating them. The kconfig workarounds should be correct in this regard.
>
> [1]:https://lore.kernel.org/all/084c5ada-51af-4c1a-b50a-4401e62ddbd6 at arm.com/
>



From marex at denx.de  Fri Dec 13 14:36:25 2024
From: marex at denx.de (Marek Vasut)
Date: Fri, 13 Dec 2024 23:36:25 +0100
Subject: [PATCH] ARM: dts: stm32: Swap USART3 and UART8 alias on STM32MP15xx DHCOM SoM
Message-ID: <20241213223658.99802-1-marex@denx.de>

Swap USART3 and UART8 aliases on STM32MP15xx DHCOM SoM,
make sure UART8 is listed first, USART3 second, because
the UART8 is labeled as UART2 on the SoM pinout, while
USART3 is labeled as UART3 on the SoM pinout.

Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board")
Signed-off-by: Marek Vasut <marex at denx.de>
---
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Christoph Niedermaier <cniedermaier at dh-electronics.com>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt at kernel.org>
Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
Cc: Rob Herring <robh at kernel.org>
Cc: devicetree at vger.kernel.org
Cc: kernel at dh-electronics.com
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
---
 arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
index 086d3a60ccce2..142d4a8731f8d 100644
--- a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
@@ -15,8 +15,8 @@ aliases {
 		rtc0 = &hwrtc;
 		rtc1 = &rtc;
 		serial0 = &uart4;
-		serial1 = &usart3;
-		serial2 = &uart8;
+		serial1 = &uart8;
+		serial2 = &usart3;
 	};
 
 	chosen {
-- 
2.45.2



From namhyung at kernel.org  Fri Dec 13 15:22:53 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 13 Dec 2024 15:22:53 -0800
Subject: [PATCH v2 01/16] perf tools: Create generic syscall table support
In-Reply-To: <20241212-perf_syscalltbl-v2-1-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
 <20241212-perf_syscalltbl-v2-1-f8ca984ffe40@rivosinc.com>
Message-ID: <Z1zBzTgEYXw1DbEL@google.com>

Hello,

On Thu, Dec 12, 2024 at 04:32:51PM -0800, Charlie Jenkins wrote:
> Currently each architecture in perf independently generates syscall
> headers. Adapt the work that has gone into unifying syscall header
> implementations in the kernel to work with perf tools. Introduce this
> framework with riscv at first. riscv previously relied on libaudit, but
> with this change, perf tools for riscv no longer needs this external
> dependency.

Nice work!

> 
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> ---
>  tools/perf/Makefile.config                         |  11 +-
>  tools/perf/Makefile.perf                           |   4 +
>  tools/perf/arch/riscv/Makefile                     |  22 --
>  tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
>  .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
>  tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 ---
>  tools/perf/arch/riscv/include/syscall_table.h      |   8 +
>  tools/perf/check-headers.sh                        |   1 +
>  tools/perf/scripts/Makefile.syscalls               |  60 +++
>  tools/perf/scripts/syscalltbl.sh                   |  86 +++++
>  tools/perf/util/syscalltbl.c                       |   8 +-
>  tools/scripts/syscall.tbl                          | 409 +++++++++++++++++++++
>  12 files changed, 585 insertions(+), 77 deletions(-)
> 
> diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> index 2916d59c88cd08b299202a48ddb42fa32aac04a6..a72f25162714f0117a88d94474da336814d4f030 100644
> --- a/tools/perf/Makefile.config
> +++ b/tools/perf/Makefile.config
> @@ -35,6 +35,13 @@ ifneq ($(NO_SYSCALL_TABLE),1)
>      NO_SYSCALL_TABLE := 0
>    endif
>  
> +  # architectures that use the generic syscall table scripts
> +  ifeq ($(SRCARCH),riscv)
> +    NO_SYSCALL_TABLE := 0
> +    CFLAGS += -DGENERIC_SYSCALL_TABLE
> +    CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
> +  endif
> +
>    ifneq ($(NO_SYSCALL_TABLE),1)
>      CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
>    endif
> @@ -83,10 +90,6 @@ ifeq ($(ARCH),mips)
>    LIBUNWIND_LIBS = -lunwind -lunwind-mips
>  endif
>  
> -ifeq ($(ARCH),riscv)
> -  CFLAGS += -I$(OUTPUT)arch/riscv/include/generated
> -endif
> -
>  # So far there's only x86 and arm libdw unwind support merged in perf.
>  # Disable it on all other architectures in case libdw unwind
>  # support is detected in system. Add supported architectures
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index d74241a151313bd09101aabb5d765a5a0a6efc84..f5278ed9f778f928436693a14e016c5c3c5171c1 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -310,6 +310,10 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
>  FEATURE_TESTS := all
>  endif
>  endif
> +# architectures that use the generic syscall table
> +ifeq ($(SRCARCH),riscv)
> +include $(srctree)/tools/perf/scripts/Makefile.syscalls
> +endif
>  include Makefile.config
>  endif
>  
> diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
> index 18ad078000e2bba595f92efc5d97a63fdb83ef45..087e099fb453a9236db34878077a51f711881ce0 100644
> --- a/tools/perf/arch/riscv/Makefile
> +++ b/tools/perf/arch/riscv/Makefile
> @@ -1,25 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0
>  PERF_HAVE_JITDUMP := 1
>  HAVE_KVM_STAT_SUPPORT := 1
> -
> -#
> -# Syscall table generation for perf
> -#
> -
> -out    := $(OUTPUT)arch/riscv/include/generated/asm
> -header := $(out)/syscalls.c
> -incpath := $(srctree)/tools
> -sysdef := $(srctree)/tools/arch/riscv/include/uapi/asm/unistd.h
> -sysprf := $(srctree)/tools/perf/arch/riscv/entry/syscalls/
> -systbl := $(sysprf)/mksyscalltbl
> -
> -# Create output directory if not already present
> -$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
> -
> -$(header): $(sysdef) $(systbl)
> -	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
> -
> -clean::
> -	$(call QUIET_CLEAN, riscv) $(RM) $(header)
> -
> -archheaders: $(header)
> diff --git a/tools/perf/arch/riscv/entry/syscalls/Kbuild b/tools/perf/arch/riscv/entry/syscalls/Kbuild
> new file mode 100644
> index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
> --- /dev/null
> +++ b/tools/perf/arch/riscv/entry/syscalls/Kbuild
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +syscall-y += syscalls_64.h
> diff --git a/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> new file mode 100644
> index 0000000000000000000000000000000000000000..9668fd1faf60e828ed2786c2ee84739ac1f153fc
> --- /dev/null
> +++ b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> @@ -0,0 +1,4 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +syscall_abis_32 += riscv memfd_secret
> +syscall_abis_64 += riscv rlimit memfd_secret
> diff --git a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl b/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
> deleted file mode 100755
> index c59f5e852b97712a9a879b89e6ef6999ed4b6cd7..0000000000000000000000000000000000000000
> --- a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
> +++ /dev/null
> @@ -1,47 +0,0 @@
> -#!/bin/sh
> -# SPDX-License-Identifier: GPL-2.0
> -#
> -# Generate system call table for perf. Derived from
> -# powerpc script.
> -#
> -# Copyright IBM Corp. 2017
> -# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
> -# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
> -# Changed by: Kim Phillips <kim.phillips at arm.com>
> -# Changed by: Bj?rn T?pel <bjorn at rivosinc.com>
> -
> -gcc=$1
> -hostcc=$2
> -incpath=$3
> -input=$4
> -
> -if ! test -r $input; then
> -	echo "Could not read input file" >&2
> -	exit 1
> -fi
> -
> -create_sc_table()
> -{
> -	local sc nr max_nr
> -
> -	while read sc nr; do
> -		printf "%s\n" "	[$nr] = \"$sc\","
> -		max_nr=$nr
> -	done
> -
> -	echo "#define SYSCALLTBL_RISCV_MAX_ID $max_nr"
> -}
> -
> -create_table()
> -{
> -	echo "#include \"$input\""
> -	echo "static const char *const syscalltbl_riscv[] = {"
> -	create_sc_table
> -	echo "};"
> -}
> -
> -$gcc -E -dM -x c -I $incpath/include/uapi $input \
> -	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
> -		sub("^#define __NR(3264)?_", "");
> -		print | "sort -k2 -n"}' \
> -	|create_table
> diff --git a/tools/perf/arch/riscv/include/syscall_table.h b/tools/perf/arch/riscv/include/syscall_table.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
> --- /dev/null
> +++ b/tools/perf/arch/riscv/include/syscall_table.h
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <asm/bitsperlong.h>
> +
> +#if __BITS_PER_LONG == 64
> +#include <asm/syscalls_64.h>
> +#else
> +#include <asm/syscalls_32.h>
> +#endif
> diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
> index a05c1c105c51bf1bd18a59195220894598eb7461..692f48db810ccbef229e240db29261f0c60db632 100755
> --- a/tools/perf/check-headers.sh
> +++ b/tools/perf/check-headers.sh
> @@ -71,6 +71,7 @@ FILES=(
>    "include/uapi/asm-generic/ioctls.h"
>    "include/uapi/asm-generic/mman-common.h"
>    "include/uapi/asm-generic/unistd.h"
> +  "scripts/syscall.tbl"
>  )
>  
>  declare -a SYNC_CHECK_FILES
> diff --git a/tools/perf/scripts/Makefile.syscalls b/tools/perf/scripts/Makefile.syscalls
> new file mode 100644
> index 0000000000000000000000000000000000000000..e2b0c4b513d5c42c8e9ac51a9ea774c34a1311b7
> --- /dev/null
> +++ b/tools/perf/scripts/Makefile.syscalls
> @@ -0,0 +1,60 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# This Makefile generates tools/perf/arch/$(SRCARCH)/include/generated/asm from
> +# the generic syscall table if that is supported by the architecture, otherwise
> +# from the architecture's defined syscall table.
> +
> +PHONY := all
> +all:
> +
> +obj := $(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated/asm
> +
> +syscall_abis_32  += common,32
> +syscall_abis_64  += common,64

Couldn't it be := instead of += ?


> +syscalltbl := $(srctree)/tools/scripts/syscall.tbl
> +
> +# let architectures override $(syscall_abis_%) and $(syscalltbl)
> +-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Makefile.syscalls
> +include $(srctree)/scripts/Kbuild.include
> +-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Kbuild
> +
> +systbl := $(srctree)/tools/perf/scripts/syscalltbl.sh
> +
> +syscall-y   := $(addprefix $(obj)/, $(syscall-y))
> +
> +# Remove stale wrappers when the corresponding files are removed from generic-y
> +old-headers := $(wildcard $(obj)/*.c)
> +unwanted    := $(filter-out $(syscall-y),$(old-headers))

Can you elaborate?  What's the stable wrappers?

I think syscall-y and old-headers have .h files but the wildcard above
is called for .c files?

Thanks,
Namhyung

> +
> +quiet_cmd_remove = REMOVE  $(unwanted)
> +      cmd_remove = rm -f $(unwanted)
> +
> +quiet_cmd_systbl = SYSTBL  $@
> +      cmd_systbl = $(CONFIG_SHELL) $(systbl) \
> +		   $(if $(systbl-args-$*),$(systbl-args-$*),$(systbl-args)) \
> +		   --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \
> +		   $< $@
> +
> +all: $(syscall-y)
> +	$(if $(unwanted),$(call cmd,remove))
> +	@:
> +
> +$(obj)/syscalls_%.h: $(syscalltbl) $(systbl) FORCE
> +	$(call if_changed,systbl)
> +
> +targets := $(syscall-y)
> +
> +# Create output directory. Skip it if at least one old header exists
> +# since we know the output directory already exists.
> +ifeq ($(old-headers),)
> +$(shell mkdir -p $(obj))
> +endif
> +
> +PHONY += FORCE
> +
> +FORCE:
> +
> +existing-targets := $(wildcard $(sort $(targets)))
> +
> +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
> +
> +.PHONY: $(PHONY)


From namhyung at kernel.org  Fri Dec 13 15:51:48 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 13 Dec 2024 15:51:48 -0800
Subject: [PATCH v2 02/16] perf tools: arc: Support generic syscall headers
In-Reply-To: <20241212-perf_syscalltbl-v2-2-f8ca984ffe40@rivosinc.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
 <20241212-perf_syscalltbl-v2-2-f8ca984ffe40@rivosinc.com>
Message-ID: <Z1zIlKq19lAXMoGs@google.com>

On Thu, Dec 12, 2024 at 04:32:52PM -0800, Charlie Jenkins wrote:
> Arc uses the generic syscall table, use that in perf instead of
> requiring libaudit.
> 
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> ---
>  tools/perf/Makefile.config                           | 2 +-
>  tools/perf/Makefile.perf                             | 2 +-
>  tools/perf/arch/arc/entry/syscalls/Kbuild            | 2 ++
>  tools/perf/arch/arc/entry/syscalls/Makefile.syscalls | 3 +++
>  tools/perf/arch/arc/include/syscall_table.h          | 2 ++
>  5 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> index a72f25162714f0117a88d94474da336814d4f030..3959a9c9972999f6d1bb85e8c1d7dc5dce92fd09 100644
> --- a/tools/perf/Makefile.config
> +++ b/tools/perf/Makefile.config
> @@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
>    endif
>  
>    # architectures that use the generic syscall table scripts
> -  ifeq ($(SRCARCH),riscv)
> +  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))

This might work as well.

  ifneq ($(filter $(SRCARCH), riscv arc),)

And maybe you can add a variable for supported archs.

Thanks,
Namhyung


>      NO_SYSCALL_TABLE := 0
>      CFLAGS += -DGENERIC_SYSCALL_TABLE
>      CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index f5278ed9f778f928436693a14e016c5c3c5171c1..3b463b42b0e3982e74056e672b2ee6adad5a3f0e 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -311,7 +311,7 @@ FEATURE_TESTS := all
>  endif
>  endif
>  # architectures that use the generic syscall table
> -ifeq ($(SRCARCH),riscv)
> +ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
>  include $(srctree)/tools/perf/scripts/Makefile.syscalls
>  endif
>  include Makefile.config
> diff --git a/tools/perf/arch/arc/entry/syscalls/Kbuild b/tools/perf/arch/arc/entry/syscalls/Kbuild
> new file mode 100644
> index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
> --- /dev/null
> +++ b/tools/perf/arch/arc/entry/syscalls/Kbuild
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +syscall-y += syscalls_32.h
> diff --git a/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> new file mode 100644
> index 0000000000000000000000000000000000000000..391d30ab7a831b72d2ed3f2e7966fdbf558a9ed7
> --- /dev/null
> +++ b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +syscall_abis_32 += arc time32 renameat stat64 rlimit
> diff --git a/tools/perf/arch/arc/include/syscall_table.h b/tools/perf/arch/arc/include/syscall_table.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
> --- /dev/null
> +++ b/tools/perf/arch/arc/include/syscall_table.h
> @@ -0,0 +1,2 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <asm/syscalls_32.h>
> 
> -- 
> 2.34.1
> 


From bryan.odonoghue at linaro.org  Fri Dec 13 16:49:52 2024
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Sat, 14 Dec 2024 00:49:52 +0000
Subject: [PATCH v8 0/5] media: qcom: camss: Add sc7280 support
In-Reply-To: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
References: <20241206191900.2545069-1-quic_vikramsa@quicinc.com>
Message-ID: <08241f60-a6a1-4b69-bdb9-c9b83ec504f3@linaro.org>

On 06/12/2024 19:18, Vikram Sharma wrote:
> SC7280 is a Qualcomm SoC. This series adds support to bring up the CSIPHY,
> CSID, VFE/RDI interfaces in SC7280.
> 
> SC7280 provides
> 
> - 3 x VFE, 3 RDI per VFE
> - 2 x VFE Lite, 4 RDI per VFE
> - 3 x CSID
> - 2 x CSID Lite
> - 5 x CSI PHY
> 
> We have tested this on qcs6490-rb3gen2-vision-mezzanine board having IMX577
> sensor. Verified both TPG and IMX577 sensor.
> 
> Used following tools for the sanity check of these changes.
You should state in your cover-letter that you depend on a prior series.

Unfortunately I found a bug in your depends series:

https://lore.kernel.org/linux-arm-msm/1a570c17-c501-4a29-a4f7-020f41563f3d at linaro.org

v9 will have to be gated on that series being fixed.

---
bod


From dianders at chromium.org  Fri Dec 13 16:52:02 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Fri, 13 Dec 2024 16:52:02 -0800
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_ vulnerable to Spectre BHB
In-Reply-To: <20241214005248.198803-1-dianders@chromium.org>
References: <20241214005248.198803-1-dianders@chromium.org>
Message-ID: <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>

The code for detecting CPUs that are vulnerable to Spectre BHB was
based on a hardcoded list of CPU IDs that were known to be affected.
Unfortunately, the list mostly only contained the IDs of standard ARM
cores. The IDs for many cores that are minor variants of the standard
ARM cores (like many Qualcomm Kyro CPUs) weren't listed. This led the
code to assume that those variants were not affected.

Flip the code on its head and instead list CPU IDs for cores that are
known to be _not_ affected. Now CPUs will be assumed vulnerable until
added to the list saying that they're safe.

As of right now, the only CPU IDs added to the "unaffected" list are
ARM Cortex A35, A53, and A55. This list was created by looking at
older cores listed in cputype.h that weren't listed in the "affected"
list previously.

Unfortunately, while this solution is better than what we had before,
it's still an imperfect solution. Specifically there are two ways to
mitigate Spectre BHB and one of those ways is parameterized with a "k"
value indicating how many loops are needed to mitigate. If we have an
unknown CPU ID then we've got to guess about how to mitigate it. Since
more cores seem to be mitigated by looping (and because it's unlikely
that the needed FW code will be in place for FW mitigation for unknown
cores), we'll choose looping for unknown CPUs and choose the highest
"k" value of 32.

The downside of our guessing is that some CPUs may now report as
"mitigated" when in reality they should need a firmware mitigation.
We'll choose to put a WARN_ON splat in the logs in this case any time
we had to make a guess since guessing the right mitigation is pretty
awful. Hopefully this will encourage CPU vendors to add their CPU IDs
to the list.


Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels")
Cc: stable at vger.kernel.org
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

Changes in v2:
- New

 arch/arm64/kernel/proton-pack.c | 46 +++++++++++++++++++++++++++------
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index da53722f95d4..39c5573c7527 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -841,13 +841,31 @@ enum bhb_mitigation_bits {
 };
 static unsigned long system_bhb_mitigations;
 
+static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
+	{},
+};
+
+static const struct midr_range spectre_bhb_safe_list[] = {
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A35),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A53),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
+	{},
+};
+
 /*
  * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
  * SCOPE_SYSTEM call will give the right answer.
+ *
+ * NOTE: Unknown CPUs are reported as affected. In order to make this work
+ * and still keep the list short, only handle CPUs where:
+ * - supports_csv2p3() returned false
+ * - supports_clearbhb() returned false.
  */
 u8 spectre_bhb_loop_affected(int scope)
 {
-	u8 k = 0;
+	u8 k;
 	static u8 max_bhb_k;
 
 	if (scope == SCOPE_LOCAL_CPU) {
@@ -886,6 +904,16 @@ u8 spectre_bhb_loop_affected(int scope)
 			k = 11;
 		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
 			k =  8;
+		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_safe_list) ||
+			 is_midr_in_range_list(read_cpuid_id(), spectre_bhb_firmware_mitigated_list))
+			k =  0;
+		else {
+			WARN_ONCE(true,
+				 "Unrecognized CPU %#010x, assuming Spectre BHB vulnerable\n",
+				 read_cpuid_id());
+			/* Hopefully k = 32 handles the worst case for unknown CPUs */
+			k = 32;
+		}
 
 		max_bhb_k = max(max_bhb_k, k);
 	} else {
@@ -916,24 +944,26 @@ static enum mitigation_state spectre_bhb_get_cpu_fw_mitigation_state(void)
 	}
 }
 
+/*
+ * NOTE: Unknown CPUs are reported as affected. In order to make this work
+ * and still keep the list short, only handle CPUs where:
+ * - supports_csv2p3() returned false
+ * - supports_clearbhb() returned false.
+ * - spectre_bhb_loop_affected() returned 0.
+ */
 static bool is_spectre_bhb_fw_affected(int scope)
 {
 	static bool system_affected;
 	enum mitigation_state fw_state;
 	bool has_smccc = arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_NONE;
-	static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
-		MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
-		MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
-		{},
-	};
 	bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
-					 spectre_bhb_firmware_mitigated_list);
+						 spectre_bhb_safe_list);
 
 	if (scope != SCOPE_LOCAL_CPU)
 		return system_affected;
 
 	fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
-	if (cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) {
+	if (!cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) {
 		system_affected = true;
 		return true;
 	}
-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Fri Dec 13 16:52:03 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Fri, 13 Dec 2024 16:52:03 -0800
Subject: [PATCH v2 2/6] arm64: errata: Add KRYO 2XX/3XX/4XX silver cores to Spectre safe list
In-Reply-To: <20241214005248.198803-1-dianders@chromium.org>
References: <20241214005248.198803-1-dianders@chromium.org>
Message-ID: <20241213165201.v2.2.Iab8dbfb5c9b1e143e7a29f410bce5f9525a0ba32@changeid>

The 2XX cores appear to be based on ARM Cortex A53. The 3XX and 4XX
cores appear to be based on ARM Cortex A55. Both of those cores appear
to be "safe" from a Spectre point of view. While it would be nice to
get confirmation from Qualcomm, it seems hard to believe that they
made big enough changes to these cores to affect the Spectre BHB
vulnerability status. Add them to the safe list.


Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels")
Cc: stable at vger.kernel.org
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

Changes in v2:
- New

 arch/arm64/kernel/proton-pack.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 39c5573c7527..012485b75019 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -851,6 +851,9 @@ static const struct midr_range spectre_bhb_safe_list[] = {
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A35),
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A53),
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
+	MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_SILVER),
+	MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER),
+	MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER),
 	{},
 };
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Fri Dec 13 16:52:04 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Fri, 13 Dec 2024 16:52:04 -0800
Subject: [PATCH v2 3/6] arm64: errata: Add QCOM_KRYO_4XX_GOLD to the spectre_bhb_k24_list
In-Reply-To: <20241214005248.198803-1-dianders@chromium.org>
References: <20241214005248.198803-1-dianders@chromium.org>
Message-ID: <20241213165201.v2.3.Ie4ef54abe02e7eb0eee50f830575719bf23bda48@changeid>

Qualcomm Kryo 400-series Gold cores appear to have a derivative of an
ARM Cortex A76 in them. Since A76 needs Spectre mitigation via looping
then the Kyro 400-series Gold cores also should need Spectre
mitigation via looping.

Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels")
Cc: stable at vger.kernel.org
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
The "k" value here really should come from analysis by Qualcomm, but
until we can get that analysis let's choose the same value as A76: 24.

Ideally someone from Qualcomm can confirm that this mitigation is
needed and confirm / provide the proper "k" value.

...or do people think that this should go in the k32 list to be
safe. At least adding it to the list of CPUs we don't warn about seems
like a good idea since it seems very unlikely that it needs a FW
mitigation when the A76 it's based on doesn't.

...or should we just drop this until Qualcomm tells us the right "k"
value here?

Changes in v2:
- Slight change to wording and notes of KRYO_4XX_GOLD patch

 arch/arm64/kernel/proton-pack.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 012485b75019..04c3f0567999 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -887,6 +887,7 @@ u8 spectre_bhb_loop_affected(int scope)
 			MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
 			MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
 			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+			MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
 			{},
 		};
 		static const struct midr_range spectre_bhb_k11_list[] = {
-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Fri Dec 13 16:52:05 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Fri, 13 Dec 2024 16:52:05 -0800
Subject: [PATCH v2 4/6] arm64: errata: Add QCOM_KRYO_2XX_GOLD to the spectre_bhb_firmware_mitigated_list
In-Reply-To: <20241214005248.198803-1-dianders@chromium.org>
References: <20241214005248.198803-1-dianders@chromium.org>
Message-ID: <20241213165201.v2.4.Ia3dfc0afadbfbee81bb2efb0672262470973dd08@changeid>

Qualcomm Kryo 200-series Gold cores appear to have a derivative of an
ARM Cortex A73 in them. Since A73 needs Spectre mitigation via
firmware then the Kyro 200-series Gold cores also should need Spectre
mitigation via firmware.

Unless devices with a Kryo 2XX gold core have a firmware that provides
ARM_SMCCC_ARCH_WORKAROUND_3 (which seems unlikely at the time this
patch is posted), this will make devices with these cores report that
they are vulnerable to Spectre BHB with no mitigation in place. This
patch will also cause them not to do a WARN splat at boot about an
unknown CPU ID and to stop trying to do a "loop" mitigation for these
cores which is (presumably) not reliable for them.

Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels")
Cc: stable at vger.kernel.org
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
I don't really have any good way to test this patch but it seems
likely it's needed. If nothing else the claim is that that Qualcomm
Kyro 280 CPU is vulnerable [1] but I don't see any mitigations in the
kernel for it.

NOTE: presumably this patch won't actually do much on its own because
(I believe) it requires a firmware update (one adding
ARM_SMCCC_ARCH_WORKAROUND_3) to go with it.

[1] https://spectreattack.com/spectre.pdf

Changes in v2:
- Rebased / reworded QCOM_KRYO_2XX_GOLD patch

 arch/arm64/kernel/proton-pack.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 04c3f0567999..3b179a1bf815 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -844,6 +844,7 @@ static unsigned long system_bhb_mitigations;
 static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
+	MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_GOLD),
 	{},
 };
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Fri Dec 13 16:52:06 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Fri, 13 Dec 2024 16:52:06 -0800
Subject: [PATCH v2 5/6] arm64: cputype: Add QCOM_CPU_PART_KRYO_3XX_GOLD
In-Reply-To: <20241214005248.198803-1-dianders@chromium.org>
References: <20241214005248.198803-1-dianders@chromium.org>
Message-ID: <20241213165201.v2.5.I18e0288742871393228249a768e5d56ea65d93dc@changeid>

Add a definition for the Qualcomm Kryo 300-series Gold cores.

Cc: stable at vger.kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

(no changes since v1)

 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 488f8e751349..c8058f91a5bd 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -119,6 +119,7 @@
 #define QCOM_CPU_PART_KRYO		0x200
 #define QCOM_CPU_PART_KRYO_2XX_GOLD	0x800
 #define QCOM_CPU_PART_KRYO_2XX_SILVER	0x801
+#define QCOM_CPU_PART_KRYO_3XX_GOLD	0x802
 #define QCOM_CPU_PART_KRYO_3XX_SILVER	0x803
 #define QCOM_CPU_PART_KRYO_4XX_GOLD	0x804
 #define QCOM_CPU_PART_KRYO_4XX_SILVER	0x805
@@ -195,6 +196,7 @@
 #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO)
 #define MIDR_QCOM_KRYO_2XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_GOLD)
 #define MIDR_QCOM_KRYO_2XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_SILVER)
+#define MIDR_QCOM_KRYO_3XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_GOLD)
 #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER)
 #define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD)
 #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
-- 
2.47.1.613.gc27f4b7a9f-goog



From broonie at kernel.org  Fri Dec 13 16:52:08 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 14 Dec 2024 00:52:08 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
Message-ID: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>

In commit 892f7237b3ff ("arm64: Delay initialisation of
cpuinfo_arm64::reg_{zcr,smcr}") we moved access to ZCR, SMCR and SMIDR
later in the boot process in order to ensure that we don't attempt to
interact with them if SVE or SME is disabled on the command line.
Unfortunately when initialising the boot CPU in init_cpu_features() we work
on a copy of the struct cpuinfo_arm64 for the boot CPU used only during
boot, not the percpu copy used by the sysfs code.

Fix this by moving the handling for SMIDR_EL1 for the boot CPU to
cpuinfo_store_boot_cpu() so it can operate on the percpu copy of the data.
This reduces the potential for error that could come from having both the
percpu and boot CPU copies in init_cpu_features().

This issue wasn't apparent when testing on emulated platforms that do not
report values in this ID register.

Fixes: 892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")
Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: stable at vger.kernel.org
---
 arch/arm64/kernel/cpufeature.c |  6 ------
 arch/arm64/kernel/cpuinfo.c    | 11 +++++++++++
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed84f9056196bb21bbfac61c9687e30..b88102fd2c20f77e25af6df513fda09a484e882e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1167,12 +1167,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
 		unsigned long cpacr = cpacr_save_enable_kernel_sme();
 
-		/*
-		 * We mask out SMPS since even if the hardware
-		 * supports priorities the kernel does not at present
-		 * and we block access to them.
-		 */
-		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
 		vec_init_vq_map(ARM64_VEC_SME);
 
 		cpacr_restore(cpacr);
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index d79e88fccdfce427507e7a34c5959ce6309cbd12..b7d403da71e5a01ed3943eb37e7a00af238771a2 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -499,4 +499,15 @@ void __init cpuinfo_store_boot_cpu(void)
 
 	boot_cpu_data = *info;
 	init_cpu_features(&boot_cpu_data);
+
+	/* SMIDR_EL1 needs to be stored in the percpu data for sysfs */
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
+		/*
+		 * We mask out SMPS since even if the hardware
+		 * supports priorities the kernel does not at present
+		 * and we block access to them.
+		 */
+		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
+	}
 }

---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241213-arm64-fix-boot-cpu-smidr-386b8db292b2

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From dianders at chromium.org  Fri Dec 13 16:52:07 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Fri, 13 Dec 2024 16:52:07 -0800
Subject: [PATCH v2 6/6] arm64: errata: Add QCOM_KRYO_3XX_GOLD to the spectre_bhb_firmware_mitigated_list
In-Reply-To: <20241214005248.198803-1-dianders@chromium.org>
References: <20241214005248.198803-1-dianders@chromium.org>
Message-ID: <20241213165201.v2.6.Ic6fdf0e43851269d10596da7e6ceae959431f9fa@changeid>

Qualcomm Kryo 200-series Gold cores appear to have a derivative of an
ARM Cortex A75 in them. Since A75 needs Spectre mitigation via
firmware then the Kyro 300-series Gold cores also should need Spectre
mitigation via firmware.

Unless devices with a Kryo 3XX gold core have a firmware that provides
ARM_SMCCC_ARCH_WORKAROUND_3 (which seems unlikely at the time this
patch is posted), this will make devices with these cores report that
they are vulnerable to Spectre BHB with no mitigation in place. This
patch will also cause them not to do a WARN splat at boot about an
unknown CPU ID and to stop trying to do a "loop" mitigation for these
cores which is (presumably) not reliable for them.

Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels")
Cc: stable at vger.kernel.org
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
I don't really have any good way to test this patch but it seems
likely it's needed.

NOTE: presumably this patch won't actually do much on its own because
(I believe) it requires a firmware update (one adding
ARM_SMCCC_ARCH_WORKAROUND_3) to go with it.

Changes in v2:
- Rebased / reworded QCOM_KRYO_3XX_GOLD patch

 arch/arm64/kernel/proton-pack.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 3b179a1bf815..f8e0d87d9e2d 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -845,6 +845,7 @@ static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
 	MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_GOLD),
+	MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_GOLD),
 	{},
 };
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Fri Dec 13 16:53:25 2024
From: dianders at chromium.org (Doug Anderson)
Date: Fri, 13 Dec 2024 16:53:25 -0800
Subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the spectre_bhb_k24_list
In-Reply-To: <l5rqbbxn6hktlcxooolkvi5n3arkht6zzhrvdjf6kis322nsup@5hsrak4cgteq>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid> <l5rqbbxn6hktlcxooolkvi5n3arkht6zzhrvdjf6kis322nsup@5hsrak4cgteq>
Message-ID: <CAD=FV=WQf+ig21u316WvQh0DoKsdKAmZgqPn5LB-myDXsJtXig@mail.gmail.com>

Hi,

On Mon, Dec 9, 2024 at 3:07?PM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Mon, Dec 09, 2024 at 09:43:15AM -0800, Douglas Anderson wrote:
> > Qualcomm Kryo 500-series Gold cores appear to have a derivative of an
> > ARM Cortex A77 in them. Since A77 needs Spectre mitigation then the
> > Kyro 500-series Gold cores also should need Spectre mitigation.
> >
> > Signed-off-by: Douglas Anderson <dianders at chromium.org>
> > ---
> > Yes. I know. This patch DOESN'T COMPILE because
> > MIDR_QCOM_KRYO_5XX_GOLD is not defined. That value needs to come from
> > Qualcomm or from testing on hardware, which I don't have. Qualcomm
> > needs to chime in to confirm that this Spectre mitigation is correct
> > anyway, though. I'm including this patch so it's obvious that I think
> > these cores also need the mitigation.
>
> Kryo 5xx (SM8250) identify themselves as 0x41/0xd0d (Gold, Prime) and
> 0x51/0x805 (Silver)

Interesting. So the Gold/Prime are actually IDing themselves as
straight Cortex A77. The Silver is IDing itself the same as
KRYO_4XX_SILVER. ...so in that sense there's nothing to do here for
those cores.


-Doug


From dianders at chromium.org  Fri Dec 13 16:52:01 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Fri, 13 Dec 2024 16:52:01 -0800
Subject: [PATCH v2 0/6] arm64: errata: Rework Spectre BHB mitigations to not assume "safe"
Message-ID: <20241214005248.198803-1-dianders@chromium.org>


Recently I realized that a device with some Qualcomm Kryo 4xx cores
reported in `lscpu` that it was _not_ vulnerable to Spectre BHB. This
seemed unlikely to me.

I wrote up a patch series to attempt (with a lot of guesswork) to add
Qualcomm cores to the tables governing how the Spectre BHB mitigation
worked.

In response to that patch, Will suggested that I flip the mitigation
on its head and assume things are vulnerable until we find that
they're not [1]. This patch series _attempts_ to accomplish that.

I've tried to do the right thing for ARM Cores and for Qualcomm
cores. I _think_ most of this likely to be right except that I don't
have a lot of confidence in the "k" value for the Kryo 4XX cores.

This patch series is _expected_ to cause some WARN splats for other
ARM CPU variants. Sorry, but there's no way to make this "default
assume affected" but not cause problems for ARM CPU variants that
weren't previously listed. I hope the WARNing here is better than just
slowing your cores down pointlessly or assuming the incorrect
mitigation. If your core is mitigated by "loop" hopefully it's easy to
just add your core to the list. If your core it mitigated by
"firmware" you can add your core to the list and get rid of the WARN
splat and you'll be left with the kernel reporting you as vulnerable
until you can get a FW update out.

In case it's not obvious, v2 of this patch series is pretty different
than v1 because it flips the logic on its head. Some of the patches
carried over, though.

As a last caveat, I'll note that I am certainly no expert on
Spectre. Mostly I ended up here running `lscpu` on a device and
noticing that it thought that it wasn't affected by Spectre v2 when I
thought it was.

Link to prev versions:
v1: https://lore.kernel.org/r/20241209174430.2904353-1-dianders at chromium.org/

[1] https://lore.kernel.org/r/20241211213410.GB17486 at willie-the-truck

Changes in v2:
- arm64: errata: Assume that unknown CPUs _are_ vulnerable to Spectre BHB
- arm64: errata: Add KRYO 2XX/3XX/4XX silver cores to Spectre safe list
- Slight change to wording and notes of KRYO_4XX_GOLD patch
- Rebased / reworded QCOM_KRYO_2XX_GOLD patch
- Rebased / reworded QCOM_KRYO_3XX_GOLD patch

Douglas Anderson (6):
  arm64: errata: Assume that unknown CPUs _are_ vulnerable to Spectre
    BHB
  arm64: errata: Add KRYO 2XX/3XX/4XX silver cores to Spectre safe list
  arm64: errata: Add QCOM_KRYO_4XX_GOLD to the spectre_bhb_k24_list
  arm64: errata: Add QCOM_KRYO_2XX_GOLD to the
    spectre_bhb_firmware_mitigated_list
  arm64: cputype: Add QCOM_CPU_PART_KRYO_3XX_GOLD
  arm64: errata: Add QCOM_KRYO_3XX_GOLD to the
    spectre_bhb_firmware_mitigated_list

 arch/arm64/include/asm/cputype.h |  2 ++
 arch/arm64/kernel/proton-pack.c  | 52 +++++++++++++++++++++++++++-----
 2 files changed, 46 insertions(+), 8 deletions(-)

-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Fri Dec 13 16:53:34 2024
From: dianders at chromium.org (Doug Anderson)
Date: Fri, 13 Dec 2024 16:53:34 -0800
Subject: [PATCH 6/6] arm64: errata: Add QCOM_KRYO_6XX_GOLD/PRIME to the spectre_bhb_k32_list
In-Reply-To: <tx7vtur7yea6ruefrkpkccqptahgmxnsrudwdz5uzcfxnng25b@afrr5bmdk2xa>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.6.I722621804be859e4ae4b7479ce191c5e3367b37c@changeid> <tx7vtur7yea6ruefrkpkccqptahgmxnsrudwdz5uzcfxnng25b@afrr5bmdk2xa>
Message-ID: <CAD=FV=XxL=HjA8pgpQjY8AQAkJns3H0BMV8nO9jKUxiuu2vKqA@mail.gmail.com>

Hi,

On Mon, Dec 9, 2024 at 3:09?PM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Mon, Dec 09, 2024 at 09:43:16AM -0800, Douglas Anderson wrote:
> > Qualcomm Kryo 600-series Gold cores appear to have a derivative of an
> > ARM Cortex A78 / ARM Cortex X1 in them. Since these need Spectre
> > mitigation then the Kyro 600-series Gold/Prime cores also should need
> > Spectre mitigation.
> >
> > Signed-off-by: Douglas Anderson <dianders at chromium.org>
> > ---
> > Yes. I know. This patch DOESN'T COMPILE because
> > MIDR_QCOM_KRYO_6XX_GOLD and MIDR_QCOM_KRYO_6XX_PRIME are not
> > defined. Those value needs to come from Qualcomm or from testing on
> > hardware, which I don't have. Qualcomm needs to chime in to confirm
> > that this Spectre mitigation is correct anyway, though. I'm including
> > this patch so it's obvious that I think these cores also need the
> > mitigation.
>
> SM8350 (Kryo 680) identifies itself as 0x41/0xd44 (Prime), 0x41/0xd41
> (Gold) and 0x41/0xd05 (Silver)

Wow, all standard ARM cores. OK, I guess we can drop this patch too then. Nice!


-Doug


From andre.przywara at arm.com  Fri Dec 13 17:16:12 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sat, 14 Dec 2024 01:16:12 +0000
Subject: [PATCH v2] ARM: dts: sun8i-r40: remove unused GPIO regulator
In-Reply-To: <20241213195433.GA1568@lemon.iwr.uni-heidelberg.de>
References: <20241213195433.GA1568@lemon.iwr.uni-heidelberg.de>
Message-ID: <20241214011612.4fd9e4bf@minigeek.lan>

On Fri, 13 Dec 2024 20:54:33 +0100
Hermann.Lauer at uni-heidelberg.de wrote:

Hi,

CC:ing Icenowy, who added the regulator originally, with commit
0ca12c1ee43c ("ARM: sun8i: r40: add 5V regulator for Banana Pi M2
Ultra").

Icenowy: can you clarify what "newer" version this was referring to in
that commit message? That commit in itself doesn't seem to do anything,
as the regulator isn't referenced, and it's not always-on. It's only
later when the USB nodes were added that it got used?
So was PH23 really necessary? As Hermann reports, setting PH23 on a v1.1
makes it reboot.

> Subject: [PATCH v2] ARM: dts: sun8i-r40: remove unused GPIO regulator

Hermann, this looks like an extra subject line here?

> Banana Pi M2 Ultra V1.1 board resets immediately when the usb core tries
> to setup PH23 GPIO. It turned out that the V1.0 board USB-A ports are
> always power supplied and according to the board scheme PH23 is simply
> not connected.
> 
> So remove the PH23 setup: Doesn't harm V1.0 (with R40) and let V1.1
> (with A40i) start.
> 
> Signed-off-by: Hermann Lauer <Hermann.Lauer at uni-heidelberg.de>

The patch itself looks good to me, but it would be good to clarify the
situation with the "older newer" version.

Just in case:
Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre
 
> ---
> V2: shorten subject, rm dangerous PH23 regulator completely
> 
> diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
> --- a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
> +++ b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
> @@ -91,15 +91,6 @@
>  		};
>  	};
>  
> -	reg_vcc5v0: vcc5v0 {
> -		compatible = "regulator-fixed";
> -		regulator-name = "vcc5v0";
> -		regulator-min-microvolt = <5000000>;
> -		regulator-max-microvolt = <5000000>;
> -		gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>; /* PH23 */
> -		enable-active-high;
> -	};
> -
>  	wifi_pwrseq: pwrseq {
>  		compatible = "mmc-pwrseq-simple";
>  		reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */
> @@ -347,7 +338,5 @@
>  };
>  
>  &usbphy {
> -	usb1_vbus-supply = <&reg_vcc5v0>;
> -	usb2_vbus-supply = <&reg_vcc5v0>;
>  	status = "okay";
>  };
> 



From jwerner at chromium.org  Fri Dec 13 17:28:55 2024
From: jwerner at chromium.org (Julius Werner)
Date: Fri, 13 Dec 2024 17:28:55 -0800
Subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the spectre_bhb_k24_list
In-Reply-To: <CAD=FV=WQf+ig21u316WvQh0DoKsdKAmZgqPn5LB-myDXsJtXig@mail.gmail.com>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>
 <l5rqbbxn6hktlcxooolkvi5n3arkht6zzhrvdjf6kis322nsup@5hsrak4cgteq> <CAD=FV=WQf+ig21u316WvQh0DoKsdKAmZgqPn5LB-myDXsJtXig@mail.gmail.com>
Message-ID: <CAODwPW919K+XdxjUe3aPgxsv0CEWwx0P_Hxvf=VniLhk8eagkQ@mail.gmail.com>

> Interesting. So the Gold/Prime are actually IDing themselves as
> straight Cortex A77. The Silver is IDing itself the same as
> KRYO_4XX_SILVER. ...so in that sense there's nothing to do here for
> those cores.

Should we add some comments to cputype.h to record which other
products are matched under the same ID?


From dan.j.williams at intel.com  Fri Dec 13 17:39:49 2024
From: dan.j.williams at intel.com (Dan Williams)
Date: Fri, 13 Dec 2024 17:39:49 -0800
Subject: [PATCH v3 00/25] fs/dax: Fix ZONE_DEVICE page reference counts
In-Reply-To: <cover.e1ebdd6cab9bde0d232c1810deacf0bae25e6707.1732239628.git-series.apopple@nvidia.com>
References: <cover.e1ebdd6cab9bde0d232c1810deacf0bae25e6707.1732239628.git-series.apopple@nvidia.com>
Message-ID: <675ce1e5a3d68_fad0294d0@dwillia2-xfh.jf.intel.com.notmuch>

[ add akpm and sfr for next steps ]

Alistair Popple wrote:
> Main updates since v2:
> 
>  - Rename the DAX specific dax_insert_XXX functions to vmf_insert_XXX
>    and have them pass the vmf struct.
> 
>  - Seperate out the device DAX changes.
> 
>  - Restore the page share mapping counting and associated warnings.
> 
>  - Rework truncate to require file-systems to have previously called
>    dax_break_layout() to remove the address space mapping for a
>    page. This found several bugs which are fixed by the first half of
>    the series. The motivation for this was initially to allow the FS
>    DAX page-cache mappings to hold a reference on the page.
> 
>    However that turned out to be a dead-end (see the comments on patch
>    21), but it found several bugs and I think overall it is an
>    improvement so I have left it here.
> 
> Device and FS DAX pages have always maintained their own page
> reference counts without following the normal rules for page reference
> counting. In particular pages are considered free when the refcount
> hits one rather than zero and refcounts are not added when mapping the
> page.
> 
> Tracking this requires special PTE bits (PTE_DEVMAP) and a secondary
> mechanism for allowing GUP to hold references on the page (see
> get_dev_pagemap). However there doesn't seem to be any reason why FS
> DAX pages need their own reference counting scheme.
> 
> By treating the refcounts on these pages the same way as normal pages
> we can remove a lot of special checks. In particular pXd_trans_huge()
> becomes the same as pXd_leaf(), although I haven't made that change
> here. It also frees up a valuable SW define PTE bit on architectures
> that have devmap PTE bits defined.
> 
> It also almost certainly allows further clean-up of the devmap managed
> functions, but I have left that as a future improvment. It also
> enables support for compound ZONE_DEVICE pages which is one of my
> primary motivators for doing this work.

So this is feeling ready for -next exposure, and ideally merged for v6.14. I
see the comments from John and Bjorn and that you were going to respin for
that, but if it's just those details things they can probably be handled
incrementally.

Alistair, are you ready for this to hit -next?

As for which tree...

Andrew, we could take this through -mm, but my first instinct would be to try
to take it through nvdimm.git mainly to offload any conflict wrangling work and
small fixups which are likely to be an ongoing trickle.

However, I am not going to put up much of a fight if others prefer this go
through -mm.

Thoughts?

Here is the current conflict diff vs -next:


commit 2f678b756ddf2c4a0fad7819442c09d3c8b52e4e
Merge: 4176cf5c5651 0f26a45ef326
Author: Dan Williams <dan.j.williams at intel.com>
Date:   Fri Dec 13 17:37:32 2024 -0800

    Merge branch 'for-6.14/dax' into for-6.14/dax-next
    
    Fixup conflicts with pte_devmap removal and other misc conflicts.

diff --cc arch/arm64/Kconfig
index 39310a484d2d,1d90ab98af3c..81855d1c822c
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@@ -40,8 -38,6 +40,7 @@@ config ARM6
  	select ARCH_HAS_MEM_ENCRYPT
  	select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
  	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 +	select ARCH_HAS_NONLEAF_PMD_YOUNG if ARM64_HAFT
- 	select ARCH_HAS_PTE_DEVMAP
  	select ARCH_HAS_PTE_SPECIAL
  	select ARCH_HAS_HW_PTE_YOUNG
  	select ARCH_HAS_SETUP_DMA_OPS
diff --cc arch/riscv/Kconfig
index 7d5718667e39,2475c5b63c34..c285250a8ea8
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@@ -41,9 -39,7 +41,8 @@@ config RISC
  	select ARCH_HAS_MMIOWB
  	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
  	select ARCH_HAS_PMEM_API
 +	select ARCH_HAS_PREEMPT_LAZY
  	select ARCH_HAS_PREPARE_SYNC_CORE_CMD
- 	select ARCH_HAS_PTE_DEVMAP if 64BIT && MMU
  	select ARCH_HAS_PTE_SPECIAL
  	select ARCH_HAS_SET_DIRECT_MAP if MMU
  	select ARCH_HAS_SET_MEMORY if MMU
diff --cc arch/x86/Kconfig
index 77f001c6a567,6a1a06f6a98a..acac373f5097
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@@ -96,8 -93,6 +96,7 @@@ config X8
  	select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
  	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
  	select ARCH_HAS_PMEM_API		if X86_64
 +	select ARCH_HAS_PREEMPT_LAZY
- 	select ARCH_HAS_PTE_DEVMAP		if X86_64
  	select ARCH_HAS_PTE_SPECIAL
  	select ARCH_HAS_HW_PTE_YOUNG
  	select ARCH_HAS_NONLEAF_PMD_YOUNG	if PGTABLE_LEVELS > 2
diff --cc arch/x86/include/asm/pgtable_types.h
index 4b804531b03c,4a13b76b9b97..e4c7b519d962
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@@ -33,15 -33,12 +33,14 @@@
  #define _PAGE_BIT_CPA_TEST	_PAGE_BIT_SOFTW1
  #define _PAGE_BIT_UFFD_WP	_PAGE_BIT_SOFTW2 /* userfaultfd wrprotected */
  #define _PAGE_BIT_SOFT_DIRTY	_PAGE_BIT_SOFTW3 /* software dirty tracking */
- #define _PAGE_BIT_DEVMAP	_PAGE_BIT_SOFTW4
  
  #ifdef CONFIG_X86_64
 -#define _PAGE_BIT_SAVED_DIRTY	_PAGE_BIT_SOFTW5 /* Saved Dirty bit */
 +#define _PAGE_BIT_SAVED_DIRTY	_PAGE_BIT_SOFTW5 /* Saved Dirty bit (leaf) */
 +#define _PAGE_BIT_NOPTISHADOW	_PAGE_BIT_SOFTW5 /* No PTI shadow (root PGD) */
  #else
  /* Shared with _PAGE_BIT_UFFD_WP which is not supported on 32 bit */
 -#define _PAGE_BIT_SAVED_DIRTY	_PAGE_BIT_SOFTW2 /* Saved Dirty bit */
 +#define _PAGE_BIT_SAVED_DIRTY	_PAGE_BIT_SOFTW2 /* Saved Dirty bit (leaf) */
 +#define _PAGE_BIT_NOPTISHADOW	_PAGE_BIT_SOFTW2 /* No PTI shadow (root PGD) */
  #endif
  
  /* If _PAGE_BIT_PRESENT is clear, we use these: */
diff --cc include/linux/rmap.h
index 683a04088f3f,4a811c5e9294..07a99abcaf2f
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@@ -192,10 -192,11 +192,11 @@@ typedef int __bitwise rmap_t
  enum rmap_level {
  	RMAP_LEVEL_PTE = 0,
  	RMAP_LEVEL_PMD,
+ 	RMAP_LEVEL_PUD,
  };
  
 -static inline void __folio_rmap_sanity_checks(struct folio *folio,
 -		struct page *page, int nr_pages, enum rmap_level level)
 +static inline void __folio_rmap_sanity_checks(const struct folio *folio,
 +		const struct page *page, int nr_pages, enum rmap_level level)
  {
  	/* hugetlb folios are handled separately. */
  	VM_WARN_ON_FOLIO(folio_test_hugetlb(folio), folio);
diff --cc mm/internal.h
index 39227887e47b,50ff42f7b783..c4df0ad37423
--- a/mm/internal.h
+++ b/mm/internal.h
@@@ -733,9 -687,8 +733,7 @@@ static inline void prep_compound_tail(s
  	set_page_private(p, 0);
  }
  
- extern void prep_compound_page(struct page *page, unsigned int order);
- 
 -extern void post_alloc_hook(struct page *page, unsigned int order,
 -					gfp_t gfp_flags);
 +void post_alloc_hook(struct page *page, unsigned int order, gfp_t gfp_flags);
  extern bool free_pages_prepare(struct page *page, unsigned int order);
  
  extern int user_min_free_kbytes;
diff --cc mm/madvise.c
index 49f3a75046f6,ff139e57cca2..1f4c99ee5c82
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@@ -1030,214 -1017,6 +1030,214 @@@ static long madvise_remove(struct vm_ar
  	return error;
  }
  
 +static bool is_valid_guard_vma(struct vm_area_struct *vma, bool allow_locked)
 +{
 +	vm_flags_t disallowed = VM_SPECIAL | VM_HUGETLB;
 +
 +	/*
 +	 * A user could lock after setting a guard range but that's fine, as
 +	 * they'd not be able to fault in. The issue arises when we try to zap
 +	 * existing locked VMAs. We don't want to do that.
 +	 */
 +	if (!allow_locked)
 +		disallowed |= VM_LOCKED;
 +
 +	if (!vma_is_anonymous(vma))
 +		return false;
 +
 +	if ((vma->vm_flags & (VM_MAYWRITE | disallowed)) != VM_MAYWRITE)
 +		return false;
 +
 +	return true;
 +}
 +
 +static bool is_guard_pte_marker(pte_t ptent)
 +{
 +	return is_pte_marker(ptent) &&
 +		is_guard_swp_entry(pte_to_swp_entry(ptent));
 +}
 +
 +static int guard_install_pud_entry(pud_t *pud, unsigned long addr,
 +				   unsigned long next, struct mm_walk *walk)
 +{
 +	pud_t pudval = pudp_get(pud);
 +
 +	/* If huge return >0 so we abort the operation + zap. */
- 	return pud_trans_huge(pudval) || pud_devmap(pudval);
++	return pud_trans_huge(pudval);
 +}
 +
 +static int guard_install_pmd_entry(pmd_t *pmd, unsigned long addr,
 +				   unsigned long next, struct mm_walk *walk)
 +{
 +	pmd_t pmdval = pmdp_get(pmd);
 +
 +	/* If huge return >0 so we abort the operation + zap. */
- 	return pmd_trans_huge(pmdval) || pmd_devmap(pmdval);
++	return pmd_trans_huge(pmdval);
 +}
 +
 +static int guard_install_pte_entry(pte_t *pte, unsigned long addr,
 +				   unsigned long next, struct mm_walk *walk)
 +{
 +	pte_t pteval = ptep_get(pte);
 +	unsigned long *nr_pages = (unsigned long *)walk->private;
 +
 +	/* If there is already a guard page marker, we have nothing to do. */
 +	if (is_guard_pte_marker(pteval)) {
 +		(*nr_pages)++;
 +
 +		return 0;
 +	}
 +
 +	/* If populated return >0 so we abort the operation + zap. */
 +	return 1;
 +}
 +
 +static int guard_install_set_pte(unsigned long addr, unsigned long next,
 +				 pte_t *ptep, struct mm_walk *walk)
 +{
 +	unsigned long *nr_pages = (unsigned long *)walk->private;
 +
 +	/* Simply install a PTE marker, this causes segfault on access. */
 +	*ptep = make_pte_marker(PTE_MARKER_GUARD);
 +	(*nr_pages)++;
 +
 +	return 0;
 +}
 +
 +static const struct mm_walk_ops guard_install_walk_ops = {
 +	.pud_entry		= guard_install_pud_entry,
 +	.pmd_entry		= guard_install_pmd_entry,
 +	.pte_entry		= guard_install_pte_entry,
 +	.install_pte		= guard_install_set_pte,
 +	.walk_lock		= PGWALK_RDLOCK,
 +};
 +
 +static long madvise_guard_install(struct vm_area_struct *vma,
 +				 struct vm_area_struct **prev,
 +				 unsigned long start, unsigned long end)
 +{
 +	long err;
 +	int i;
 +
 +	*prev = vma;
 +	if (!is_valid_guard_vma(vma, /* allow_locked = */false))
 +		return -EINVAL;
 +
 +	/*
 +	 * If we install guard markers, then the range is no longer
 +	 * empty from a page table perspective and therefore it's
 +	 * appropriate to have an anon_vma.
 +	 *
 +	 * This ensures that on fork, we copy page tables correctly.
 +	 */
 +	err = anon_vma_prepare(vma);
 +	if (err)
 +		return err;
 +
 +	/*
 +	 * Optimistically try to install the guard marker pages first. If any
 +	 * non-guard pages are encountered, give up and zap the range before
 +	 * trying again.
 +	 *
 +	 * We try a few times before giving up and releasing back to userland to
 +	 * loop around, releasing locks in the process to avoid contention. This
 +	 * would only happen if there was a great many racing page faults.
 +	 *
 +	 * In most cases we should simply install the guard markers immediately
 +	 * with no zap or looping.
 +	 */
 +	for (i = 0; i < MAX_MADVISE_GUARD_RETRIES; i++) {
 +		unsigned long nr_pages = 0;
 +
 +		/* Returns < 0 on error, == 0 if success, > 0 if zap needed. */
 +		err = walk_page_range_mm(vma->vm_mm, start, end,
 +					 &guard_install_walk_ops, &nr_pages);
 +		if (err < 0)
 +			return err;
 +
 +		if (err == 0) {
 +			unsigned long nr_expected_pages = PHYS_PFN(end - start);
 +
 +			VM_WARN_ON(nr_pages != nr_expected_pages);
 +			return 0;
 +		}
 +
 +		/*
 +		 * OK some of the range have non-guard pages mapped, zap
 +		 * them. This leaves existing guard pages in place.
 +		 */
 +		zap_page_range_single(vma, start, end - start, NULL);
 +	}
 +
 +	/*
 +	 * We were unable to install the guard pages due to being raced by page
 +	 * faults. This should not happen ordinarily. We return to userspace and
 +	 * immediately retry, relieving lock contention.
 +	 */
 +	return restart_syscall();
 +}
 +
 +static int guard_remove_pud_entry(pud_t *pud, unsigned long addr,
 +				  unsigned long next, struct mm_walk *walk)
 +{
 +	pud_t pudval = pudp_get(pud);
 +
 +	/* If huge, cannot have guard pages present, so no-op - skip. */
- 	if (pud_trans_huge(pudval) || pud_devmap(pudval))
++	if (pud_trans_huge(pudval))
 +		walk->action = ACTION_CONTINUE;
 +
 +	return 0;
 +}
 +
 +static int guard_remove_pmd_entry(pmd_t *pmd, unsigned long addr,
 +				  unsigned long next, struct mm_walk *walk)
 +{
 +	pmd_t pmdval = pmdp_get(pmd);
 +
 +	/* If huge, cannot have guard pages present, so no-op - skip. */
- 	if (pmd_trans_huge(pmdval) || pmd_devmap(pmdval))
++	if (pmd_trans_huge(pmdval))
 +		walk->action = ACTION_CONTINUE;
 +
 +	return 0;
 +}
 +
 +static int guard_remove_pte_entry(pte_t *pte, unsigned long addr,
 +				  unsigned long next, struct mm_walk *walk)
 +{
 +	pte_t ptent = ptep_get(pte);
 +
 +	if (is_guard_pte_marker(ptent)) {
 +		/* Simply clear the PTE marker. */
 +		pte_clear_not_present_full(walk->mm, addr, pte, false);
 +		update_mmu_cache(walk->vma, addr, pte);
 +	}
 +
 +	return 0;
 +}
 +
 +static const struct mm_walk_ops guard_remove_walk_ops = {
 +	.pud_entry		= guard_remove_pud_entry,
 +	.pmd_entry		= guard_remove_pmd_entry,
 +	.pte_entry		= guard_remove_pte_entry,
 +	.walk_lock		= PGWALK_RDLOCK,
 +};
 +
 +static long madvise_guard_remove(struct vm_area_struct *vma,
 +				 struct vm_area_struct **prev,
 +				 unsigned long start, unsigned long end)
 +{
 +	*prev = vma;
 +	/*
 +	 * We're ok with removing guards in mlock()'d ranges, as this is a
 +	 * non-destructive action.
 +	 */
 +	if (!is_valid_guard_vma(vma, /* allow_locked = */true))
 +		return -EINVAL;
 +
 +	return walk_page_range(vma->vm_mm, start, end,
 +			       &guard_remove_walk_ops, NULL);
 +}
 +
  /*
   * Apply an madvise behavior to a region of a vma.  madvise_update_vma
   * will handle splitting a vm area into separate areas, each area with its own
diff --cc mm/pagewalk.c
index e478777c86e1,576ff14b118f..a85c3319c6d5
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@@ -133,25 -109,18 +133,24 @@@ again
  
  		if (walk->action == ACTION_AGAIN)
  			goto again;
 -
 -		/*
 -		 * Check this here so we only break down trans_huge
 -		 * pages when we _need_ to
 -		 */
 -		if ((!walk->vma && (pmd_leaf(*pmd) || !pmd_present(*pmd))) ||
 -		    walk->action == ACTION_CONTINUE ||
 -		    !(ops->pte_entry))
 +		if (walk->action == ACTION_CONTINUE)
  			continue;
  
 +		if (!has_handler) { /* No handlers for lower page tables. */
 +			if (!has_install)
 +				continue; /* Nothing to do. */
 +			/*
 +			 * We are ONLY installing, so avoid unnecessarily
 +			 * splitting a present huge page.
 +			 */
- 			if (pmd_present(*pmd) &&
- 			    (pmd_trans_huge(*pmd) || pmd_devmap(*pmd)))
++			if (pmd_present(*pmd) && pmd_trans_huge(*pmd))
 +				continue;
 +		}
 +
  		if (walk->vma)
  			split_huge_pmd(walk->vma, pmd, addr);
 +		else if (pmd_leaf(*pmd) || !pmd_present(*pmd))
 +			continue; /* Nothing to do. */
  
  		err = walk_pte_range(pmd, addr, next, walk);
  		if (err)
@@@ -200,26 -164,14 +199,25 @@@ static int walk_pud_range(p4d_t *p4d, u
  
  		if (walk->action == ACTION_AGAIN)
  			goto again;
 -
 -		if ((!walk->vma && (pud_leaf(*pud) || !pud_present(*pud))) ||
 -		    walk->action == ACTION_CONTINUE ||
 -		    !(ops->pmd_entry || ops->pte_entry))
 +		if (walk->action == ACTION_CONTINUE)
  			continue;
  
 +		if (!has_handler) { /* No handlers for lower page tables. */
 +			if (!has_install)
 +				continue; /* Nothing to do. */
 +			/*
 +			 * We are ONLY installing, so avoid unnecessarily
 +			 * splitting a present huge page.
 +			 */
- 			if (pud_present(*pud) &&
- 			    (pud_trans_huge(*pud) || pud_devmap(*pud)))
++			if (pud_present(*pud) && pud_trans_huge(*pud))
 +				continue;
 +		}
 +
  		if (walk->vma)
  			split_huge_pud(walk->vma, pud, addr);
 +		else if (pud_leaf(*pud) || !pud_present(*pud))
 +			continue; /* Nothing to do. */
 +
  		if (pud_none(*pud))
  			goto again;
  
@@@ -868,11 -753,7 +866,11 @@@ struct folio *folio_walk_start(struct f
  		fw->pudp = pudp;
  		fw->pud = pud;
  
 +		/*
 +		 * TODO: FW_MIGRATION support for PUD migration entries
 +		 * once there are relevant users.
 +		 */
- 		if (!pud_present(pud) || pud_devmap(pud) || pud_special(pud)) {
+ 		if (!pud_present(pud) || pud_special(pud)) {
  			spin_unlock(ptl);
  			goto not_found;
  		} else if (!pud_leaf(pud)) {
diff --cc mm/truncate.c
index 7c304d2f0052,ee2f890dedde..cb29feac4624
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@@ -73,34 -83,51 +73,47 @@@ static void truncate_folio_batch_except
  		if (xa_is_value(fbatch->folios[j]))
  			break;
  
 -	if (j == folio_batch_count(fbatch))
 +	if (j == nr)
  		return;
  
 -	dax = dax_mapping(mapping);
 -	if (!dax) {
 -		spin_lock(&mapping->host->i_lock);
 -		xa_lock_irq(&mapping->i_pages);
 -	}
 -
 -	for (i = j; i < folio_batch_count(fbatch); i++) {
 -		struct folio *folio = fbatch->folios[i];
 -		pgoff_t index = indices[i];
 +	if (dax_mapping(mapping)) {
 +		for (i = j; i < nr; i++) {
- 			if (xa_is_value(fbatch->folios[i]))
++			if (xa_is_value(fbatch->folios[i])) {
++				/*
++			 	* File systems should already have called
++			 	* dax_break_mapping_entry() to remove all DAX entries
++			 	* while holding a lock to prevent establishing new
++			 	* entries. Therefore we shouldn't find any here.
++			 	*/
++				WARN_ON_ONCE(1);
+ 
 -		if (!xa_is_value(folio)) {
 -			fbatch->folios[j++] = folio;
 -			continue;
++				/*
++			 	* Delete the mapping so truncate_pagecache() doesn't
++			 	* loop forever.
++			 	*/
 +				dax_delete_mapping_entry(mapping, indices[i]);
++			}
  		}
 +		goto out;
 +	}
  
 -		if (unlikely(dax)) {
 -			/*
 -			 * File systems should already have called
 -			 * dax_break_mapping_entry() to remove all DAX entries
 -			 * while holding a lock to prevent establishing new
 -			 * entries. Therefore we shouldn't find any here.
 -			 */
 -			WARN_ON_ONCE(1);
 +	xas_set(&xas, indices[j]);
 +	xas_set_update(&xas, workingset_update_node);
  
 -			/*
 -			 * Delete the mapping so truncate_pagecache() doesn't
 -			 * loop forever.
 -			 */
 -			dax_delete_mapping_entry(mapping, index);
 -			continue;
 -		}
 +	spin_lock(&mapping->host->i_lock);
 +	xas_lock_irq(&xas);
  
 -		__clear_shadow_entry(mapping, index, folio);
 +	xas_for_each(&xas, folio, indices[nr-1]) {
 +		if (xa_is_value(folio))
 +			xas_store(&xas, NULL);
  	}
  
 -	if (!dax) {
 -		xa_unlock_irq(&mapping->i_pages);
 -		if (mapping_shrinkable(mapping))
 -			inode_add_lru(mapping->host);
 -		spin_unlock(&mapping->host->i_lock);
 -	}
 -	fbatch->nr = j;
 +	xas_unlock_irq(&xas);
 +	if (mapping_shrinkable(mapping))
 +		inode_add_lru(mapping->host);
 +	spin_unlock(&mapping->host->i_lock);
 +out:
 +	folio_batch_remove_exceptionals(fbatch);
  }
  
  /**
diff --cc mm/vmscan.c
index 78e9360a20aa,34ff5a6635b4..f0c8eac63972
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@@ -3362,12 -3303,9 +3362,12 @@@ static unsigned long get_pte_pfn(pte_t 
  	if (!pte_present(pte) || is_zero_pfn(pfn))
  		return -1;
  
- 	if (WARN_ON_ONCE(pte_devmap(pte) || pte_special(pte)))
+ 	if (WARN_ON_ONCE(pte_special(pte)))
  		return -1;
  
 +	if (!pte_young(pte) && !mm_has_notifiers(vma->vm_mm))
 +		return -1;
 +
  	if (WARN_ON_ONCE(!pfn_valid(pfn)))
  		return -1;
  
@@@ -3387,12 -3321,6 +3387,9 @@@ static unsigned long get_pmd_pfn(pmd_t 
  	if (!pmd_present(pmd) || is_huge_zero_pmd(pmd))
  		return -1;
  
- 	if (WARN_ON_ONCE(pmd_devmap(pmd)))
- 		return -1;
- 
 +	if (!pmd_young(pmd) && !mm_has_notifiers(vma->vm_mm))
 +		return -1;
 +
  	if (WARN_ON_ONCE(!pfn_valid(pfn)))
  		return -1;
  


From broonie at kernel.org  Fri Dec 13 18:12:06 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 14 Dec 2024 02:12:06 +0000
Subject: [PATCH v3] arm64/signal: Silence sparse warning storing GCSPR_EL0
Message-ID: <20241214-arm64-gcs-signal-sparse-v3-1-5e8d18fffc0c@kernel.org>

We are seeing a sparse warning in gcs_restore_signal():

  arch/arm64/kernel/signal.c:1054:9: sparse: sparse: cast removes address space '__user' of expression

when storing the final GCSPR_EL0 value back into the register, caused by
the fact that write_sysreg_s() casts the value it writes to a u64 which
sparse sees as discarding the __userness of the pointer.

Avoid this by treating the address as an integer, casting to a pointer only
when using it to write to userspace.

While we're at it also inline gcs_signal_cap_valid() into it's one user
and make equivalent updates to gcs_signal_entry().

Reported-by: kernel test robot <lkp at intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202412082005.OBJ0BbWs-lkp at intel.com/
Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v3:
- Switch to working with u64 instead of pointers, adding casts to
  pointers.
- Inline gcs_signal_cap_valid()
- Link to v2: https://lore.kernel.org/r/20241211-arm64-gcs-signal-sparse-v2-1-c22f37216135 at kernel.org

Changes in v2:
- Use __force u64 rather than unsigned long.
- Tweak commit message.
- Link to v1: https://lore.kernel.org/r/20241210-arm64-gcs-signal-sparse-v1-1-26888bcd6f89 at kernel.org
---
 arch/arm64/kernel/signal.c | 35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 14ac6fdb872b9672e4b16a097f1b577aae8dec50..928bdaa51df19583e77b8480e8b9094fe5563c35 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -36,15 +36,8 @@
 #include <asm/traps.h>
 #include <asm/vdso.h>
 
-#ifdef CONFIG_ARM64_GCS
 #define GCS_SIGNAL_CAP(addr) (((unsigned long)addr) & GCS_CAP_ADDR_MASK)
 
-static bool gcs_signal_cap_valid(u64 addr, u64 val)
-{
-	return val == GCS_SIGNAL_CAP(addr);
-}
-#endif
-
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
  */
@@ -1062,8 +1055,7 @@ static int restore_sigframe(struct pt_regs *regs,
 #ifdef CONFIG_ARM64_GCS
 static int gcs_restore_signal(void)
 {
-	unsigned long __user *gcspr_el0;
-	u64 cap;
+	u64 gcspr_el0, cap;
 	int ret;
 
 	if (!system_supports_gcs())
@@ -1072,7 +1064,7 @@ static int gcs_restore_signal(void)
 	if (!(current->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE))
 		return 0;
 
-	gcspr_el0 = (unsigned long __user *)read_sysreg_s(SYS_GCSPR_EL0);
+	gcspr_el0 = read_sysreg_s(SYS_GCSPR_EL0);
 
 	/*
 	 * Ensure that any changes to the GCS done via GCS operations
@@ -1087,22 +1079,23 @@ static int gcs_restore_signal(void)
 	 * then faults will be generated on GCS operations - the main
 	 * concern is to protect GCS pages.
 	 */
-	ret = copy_from_user(&cap, gcspr_el0, sizeof(cap));
+	ret = copy_from_user(&cap, (unsigned long __user *)gcspr_el0,
+			     sizeof(cap));
 	if (ret)
 		return -EFAULT;
 
 	/*
 	 * Check that the cap is the actual GCS before replacing it.
 	 */
-	if (!gcs_signal_cap_valid((u64)gcspr_el0, cap))
+	if (cap != GCS_SIGNAL_CAP(gcspr_el0))
 		return -EINVAL;
 
 	/* Invalidate the token to prevent reuse */
-	put_user_gcs(0, (__user void*)gcspr_el0, &ret);
+	put_user_gcs(0, (unsigned long __user *)gcspr_el0, &ret);
 	if (ret != 0)
 		return -EFAULT;
 
-	write_sysreg_s(gcspr_el0 + 1, SYS_GCSPR_EL0);
+	write_sysreg_s(gcspr_el0 + 8, SYS_GCSPR_EL0);
 
 	return 0;
 }
@@ -1421,7 +1414,7 @@ static int get_sigframe(struct rt_sigframe_user_layout *user,
 
 static int gcs_signal_entry(__sigrestore_t sigtramp, struct ksignal *ksig)
 {
-	unsigned long __user *gcspr_el0;
+	u64 gcspr_el0;
 	int ret = 0;
 
 	if (!system_supports_gcs())
@@ -1434,18 +1427,20 @@ static int gcs_signal_entry(__sigrestore_t sigtramp, struct ksignal *ksig)
 	 * We are entering a signal handler, current register state is
 	 * active.
 	 */
-	gcspr_el0 = (unsigned long __user *)read_sysreg_s(SYS_GCSPR_EL0);
+	gcspr_el0 = 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);
+	put_user_gcs((unsigned long)sigtramp,
+		     (unsigned long __user *)(gcspr_el0 - 16), &ret);
+	put_user_gcs(GCS_SIGNAL_CAP(gcspr_el0 - 8),
+		     (unsigned long __user *)(gcspr_el0 - 8), &ret);
 	if (ret != 0)
 		return ret;
 
-	gcspr_el0 -= 2;
-	write_sysreg_s((unsigned long)gcspr_el0, SYS_GCSPR_EL0);
+	gcspr_el0 -= 16;
+	write_sysreg_s(gcspr_el0, SYS_GCSPR_EL0);
 
 	return 0;
 }

---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241209-arm64-gcs-signal-sparse-53fa9cad67f7

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From jwerner at chromium.org  Fri Dec 13 18:25:34 2024
From: jwerner at chromium.org (Julius Werner)
Date: Fri, 13 Dec 2024 18:25:34 -0800
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
References: <20241214005248.198803-1-dianders@chromium.org> <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
Message-ID: <CAODwPW_c+Ycu_zhiDOKN-fH2FEWf2pxr+FcugpqEjLX-nVjQrg@mail.gmail.com>

I feel like this patch is maybe taking a bit of a wrong angle at
achieving what you're trying to do. The code seems to be structured in
a way that it has separate functions to test for each of the possible
mitigation options one at a time, and pushing the default case into
spectre_bhb_loop_affected() feels like a bit of a layering violation.
I think it would work the way you wrote it, but it depends heavily on
the order functions are called in is_spectre_bhb_affected(), which
seems counter-intuitive with the way the functions seem to be designed
as independent checks.

What do you think about an approach like this instead:

- Refactor max_bhb_k in spectre_bhb_loop_affected() to be a global
instead, which starts out as zero, is updated by
spectre_bhb_loop_affected(), and is directly read by
spectre_bhb_patch_loop_iter() (could probably remove the `scope`
argument from spectre_bhb_loop_affected() then).

- Add a function is_spectre_bhb_safe() that just checks if the MIDR is
in the new list you're adding

- Add an `if (is_spectre_bhb_safe()) return false;` to the top of
is_spectre_bhb_affected

- Change the `return false` into `return true` at the end of
is_spectre_bhb_affected (in fact, you can probably take out some of
the other calls that result in returning true as well then)

- In spectre_bhb_enable_mitigations(), at the end of the long if-else
chain, put a last else block that prints your WARN_ONCE(), sets the
max_bhb_k global to 32, and then does the same stuff that the `if
(spectre_bhb_loop_affected())` block would have installed (maybe
factoring that out into a helper function called from both cases).

I think that should implement the same "assume unsafe by default
unless explicitly listed as safe, check for all other mitigations
first, then default to k=32 loop if none found" approach, but makes it
a bit more obvious in the code.


From patchwork-bot+netdevbpf at kernel.org  Fri Dec 13 19:40:31 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Sat, 14 Dec 2024 03:40:31 +0000
Subject: [PATCH net-next v1] net: stmmac: Drop redundant dwxgmac_tc_ops
 variable
In-Reply-To: <20241212033325.282817-1-0x1207@gmail.com>
References: <20241212033325.282817-1-0x1207@gmail.com>
Message-ID: <173414763174.3237238.13876454174821375749.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Thu, 12 Dec 2024 11:33:25 +0800 you wrote:
> dwmac510_tc_ops and dwxgmac_tc_ops are completely identical,
> keep dwmac510_tc_ops to provide better backward compatibility.
> 
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/hwif.c      |  4 ++--
>  drivers/net/ethernet/stmicro/stmmac/hwif.h      |  1 -
>  drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 11 -----------
>  3 files changed, 2 insertions(+), 14 deletions(-)

Here is the summary with links:
  - [net-next,v1] net: stmmac: Drop redundant dwxgmac_tc_ops variable
    https://git.kernel.org/netdev/net-next/c/9bc5c9515b48

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From anarsoul at gmail.com  Fri Dec 13 22:29:51 2024
From: anarsoul at gmail.com (Vasily Khoruzhick)
Date: Fri, 13 Dec 2024 22:29:51 -0800
Subject: [PATCH v4 1/4] clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux
In-Reply-To: <20230505052110.67514-2-me@crly.cz>
References: <20230505052110.67514-1-me@crly.cz> <20230505052110.67514-2-me@crly.cz>
Message-ID: <CA+E=qVcSV7H4=-fT2FUdNd5sneCO0GsA-qKrvQxy8PF89knckw@mail.gmail.com>

On Thu, May 4, 2023 at 10:34?PM Roman Beranek <me at crly.cz> wrote:
>
> TCON0's source clock can be fed from either PLL_MIPI, or PLL_VIDEO0(2X),
> however MIPI DSI output only seems to work when PLL_MIPI is selected and
> thus the choice must be hardcoded in.
>
> Currently, this driver can't propagate rate change from N-K-M clocks
> (such as PLL_MIPI) upwards. This prevents PLL_VIDEO0 from participating
> in setting of the TCON0 data clock rate, limiting the precision with
> which a target pixel clock can be matched.
>
> For outputs with fixed TCON0 divider, that is DSI and LVDS, the dotclock
> can deviate up to 8% off target.

Hi Roman,

I'm a bit late, but this patch breaks the LCD on Pine64 Pinebook. When
TCON0 parent is pll-mipi, the panel is blank and I get vblank timeouts.

With this patch reverted it works if I force pll-video-2x as a parent for TCON0.

So for me RGB output doesn't seem to work with PLL_MIPI, but works
only with PLL_VIDEO0_2X. Any ideas on how to fix it?

Regards,
Vasily



> Signed-off-by: Roman Beranek <me at crly.cz>
> ---
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> index 41519185600a..eb36f8f77d55 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> @@ -528,11 +528,18 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
>                                  0x104, 0, 4, 24, 3, BIT(31),
>                                  CLK_SET_RATE_PARENT);
>
> +/*
> + * DSI output seems to work only when PLL_MIPI selected. Set it and prevent
> + * the mux from reparenting.
> + */
> +#define SUN50I_A64_TCON0_CLK_REG       0x118
> +
>  static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
>  static const u8 tcon0_table[] = { 0, 2, };
>  static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
>                                      tcon0_table, 0x118, 24, 3, BIT(31),
> -                                    CLK_SET_RATE_PARENT);
> +                                    CLK_SET_RATE_PARENT |
> +                                    CLK_SET_RATE_NO_REPARENT);
>
>  static const char * const tcon1_parents[] = { "pll-video0", "pll-video1" };
>  static const u8 tcon1_table[] = { 0, 2, };
> @@ -953,6 +960,11 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
>
>         writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
>
> +       /* Set PLL MIPI as parent for TCON0 */
> +       val = readl(reg + SUN50I_A64_TCON0_CLK_REG);
> +       val &= ~GENMASK(26, 24);
> +       writel(val | (0 << 24), reg + SUN50I_A64_TCON0_CLK_REG);
> +
>         ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc);
>         if (ret)
>                 return ret;
> --
> 2.32.0 (Apple Git-132)
>
>


From uwu at icenowy.me  Fri Dec 13 23:13:23 2024
From: uwu at icenowy.me (Icenowy Zheng)
Date: Sat, 14 Dec 2024 15:13:23 +0800
Subject: [PATCH v2] ARM: dts: sun8i-r40: remove unused GPIO regulator
In-Reply-To: <20241214011612.4fd9e4bf@minigeek.lan>
References: <20241213195433.GA1568@lemon.iwr.uni-heidelberg.de>
	 <20241214011612.4fd9e4bf@minigeek.lan>
Message-ID: <e61c927a4dfe909f4ede4a07dffd9dcd762875be.camel@icenowy.me>

? 2024-12-14???? 01:16 +0000?Andre Przywara???
> On Fri, 13 Dec 2024 20:54:33 +0100
> Hermann.Lauer at uni-heidelberg.de?wrote:
> 
> Hi,
> 
> CC:ing Icenowy, who added the regulator originally, with commit
> 0ca12c1ee43c ("ARM: sun8i: r40: add 5V regulator for Banana Pi M2
> Ultra").
> 
> Icenowy: can you clarify what "newer" version this was referring to
> in
> that commit message? That commit in itself doesn't seem to do
> anything,
> as the regulator isn't referenced, and it's not always-on. It's only
> later when the USB nodes were added that it got used?
> So was PH23 really necessary? As Hermann reports, setting PH23 on a
> v1.1
> makes it reboot.

I am not sure, the schematics I have here (which says V1.0) have PH23
as NC... Well, the M2 Berry schematics have PH23 as 5V EN, maybe I
messed up M2U and M2B when developing?

Sorry but I think the data retention situation of my memory looks bad
here, maybe it needs a shorter refresh interval ;-)

> 
> > Subject: [PATCH v2] ARM: dts: sun8i-r40: remove unused GPIO
> > regulator
> 
> Hermann, this looks like an extra subject line here?
> 
> > Banana Pi M2 Ultra V1.1 board resets immediately when the usb core
> > tries
> > to setup PH23 GPIO. It turned out that the V1.0 board USB-A ports
> > are
> > always power supplied and according to the board scheme PH23 is
> > simply
> > not connected.
> > 
> > So remove the PH23 setup: Doesn't harm V1.0 (with R40) and let V1.1
> > (with A40i) start.
> > 
> > Signed-off-by: Hermann Lauer <Hermann.Lauer at uni-heidelberg.de>
> 
> The patch itself looks good to me, but it would be good to clarify
> the
> situation with the "older newer" version.
> 
> Just in case:
> Reviewed-by: Andre Przywara <andre.przywara at arm.com>
> 
> Cheers,
> Andre
> ?
> > ---
> > V2: shorten subject, rm dangerous PH23 regulator completely
> > 
> > diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-
> > ultra.dts b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-
> > ultra.dts
> > --- a/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
> > +++ b/arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
> > @@ -91,15 +91,6 @@
> > ????????????????};
> > ????????};
> > ?
> > -???????reg_vcc5v0: vcc5v0 {
> > -???????????????compatible = "regulator-fixed";
> > -???????????????regulator-name = "vcc5v0";
> > -???????????????regulator-min-microvolt = <5000000>;
> > -???????????????regulator-max-microvolt = <5000000>;
> > -???????????????gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>; /* PH23 */
> > -???????????????enable-active-high;
> > -???????};
> > -
> > ????????wifi_pwrseq: pwrseq {
> > ????????????????compatible = "mmc-pwrseq-simple";
> > ????????????????reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10
> > WIFI_EN */
> > @@ -347,7 +338,5 @@
> > ?};
> > ?
> > ?&usbphy {
> > -???????usb1_vbus-supply = <&reg_vcc5v0>;
> > -???????usb2_vbus-supply = <&reg_vcc5v0>;
> > ????????status = "okay";
> > ?};
> > 
> 
> 



From anarsoul at gmail.com  Fri Dec 13 23:31:38 2024
From: anarsoul at gmail.com (Vasily Khoruzhick)
Date: Fri, 13 Dec 2024 23:31:38 -0800
Subject: [PATCH v4 1/4] clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux
In-Reply-To: <CA+E=qVcSV7H4=-fT2FUdNd5sneCO0GsA-qKrvQxy8PF89knckw@mail.gmail.com>
References: <20230505052110.67514-1-me@crly.cz> <20230505052110.67514-2-me@crly.cz>
 <CA+E=qVcSV7H4=-fT2FUdNd5sneCO0GsA-qKrvQxy8PF89knckw@mail.gmail.com>
Message-ID: <CA+E=qVeroOt_L-r--K7uYrS+039x-BtgciVqoez5CmOtmYyqVg@mail.gmail.com>

On Fri, Dec 13, 2024 at 10:29?PM Vasily Khoruzhick <anarsoul at gmail.com> wrote:
>
> On Thu, May 4, 2023 at 10:34?PM Roman Beranek <me at crly.cz> wrote:
> >
> > TCON0's source clock can be fed from either PLL_MIPI, or PLL_VIDEO0(2X),
> > however MIPI DSI output only seems to work when PLL_MIPI is selected and
> > thus the choice must be hardcoded in.
> >
> > Currently, this driver can't propagate rate change from N-K-M clocks
> > (such as PLL_MIPI) upwards. This prevents PLL_VIDEO0 from participating
> > in setting of the TCON0 data clock rate, limiting the precision with
> > which a target pixel clock can be matched.
> >
> > For outputs with fixed TCON0 divider, that is DSI and LVDS, the dotclock
> > can deviate up to 8% off target.
>
> Hi Roman,
>
> I'm a bit late, but this patch breaks the LCD on Pine64 Pinebook. When
> TCON0 parent is pll-mipi, the panel is blank and I get vblank timeouts.
>
> With this patch reverted it works if I force pll-video-2x as a parent for TCON0.

And changing TCON0 parent in runtime by poking CCU registers also
fixes the issue (even though pll-video-2x is *much* slower than
pll-mipi), i.e. if I do "devmem2 0x01c20118 w 0x82000000" the picture
appears on the screen.

> So for me RGB output doesn't seem to work with PLL_MIPI, but works
> only with PLL_VIDEO0_2X. Any ideas on how to fix it?
>
> Regards,
> Vasily
>
>
>
> > Signed-off-by: Roman Beranek <me at crly.cz>
> > ---
> >  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 14 +++++++++++++-
> >  1 file changed, 13 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> > index 41519185600a..eb36f8f77d55 100644
> > --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> > @@ -528,11 +528,18 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
> >                                  0x104, 0, 4, 24, 3, BIT(31),
> >                                  CLK_SET_RATE_PARENT);
> >
> > +/*
> > + * DSI output seems to work only when PLL_MIPI selected. Set it and prevent
> > + * the mux from reparenting.
> > + */
> > +#define SUN50I_A64_TCON0_CLK_REG       0x118
> > +
> >  static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
> >  static const u8 tcon0_table[] = { 0, 2, };
> >  static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
> >                                      tcon0_table, 0x118, 24, 3, BIT(31),
> > -                                    CLK_SET_RATE_PARENT);
> > +                                    CLK_SET_RATE_PARENT |
> > +                                    CLK_SET_RATE_NO_REPARENT);
> >
> >  static const char * const tcon1_parents[] = { "pll-video0", "pll-video1" };
> >  static const u8 tcon1_table[] = { 0, 2, };
> > @@ -953,6 +960,11 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
> >
> >         writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
> >
> > +       /* Set PLL MIPI as parent for TCON0 */
> > +       val = readl(reg + SUN50I_A64_TCON0_CLK_REG);
> > +       val &= ~GENMASK(26, 24);
> > +       writel(val | (0 << 24), reg + SUN50I_A64_TCON0_CLK_REG);
> > +
> >         ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc);
> >         if (ret)
> >                 return ret;
> > --
> > 2.32.0 (Apple Git-132)
> >
> >


From andyshrk at 163.com  Sat Dec 14 00:01:11 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:01:11 +0800 (CST)
Subject: [PATCH v5 05/18] drm/rockchip: vop2: Set AXI id for rk3588
In-Reply-To: <13660005.uLZWGnKmhe@bootstrap>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <5843712.DvuYhMxLoT@bootstrap>
 <3f1eace4.75cf.193b9daf585.Coremail.andyshrk@163.com>
 <13660005.uLZWGnKmhe@bootstrap>
Message-ID: <56a01c0e.20d5.193c42f8f9b.Coremail.andyshrk@163.com>

Hi Detlev,

At 2024-12-14 02:34:03, "Detlev Casanova" <detlev.casanova at collabora.com> wrote:
>On Thursday, 12 December 2024 02:52:34 EST Andy Yan wrote:
>> Hi Detlev,
>> 
>> At 2024-12-11 23:45:01, "Detlev Casanova" <detlev.casanova at collabora.com> 
>wrote:
>> >On Wednesday, 11 December 2024 01:34:34 EST Andy Yan wrote:
>> >> Hi Detlev,
>> >> 
>> >> At 2024-12-11 02:40:14, "Detlev Casanova" <detlev.casanova at collabora.com>
>> >
>> >wrote:
>> >> >Hi Andy,
>> >> >
>> >> >On Monday, 9 December 2024 07:29:18 EST Andy Yan wrote:
>> >> >> From: Andy Yan <andy.yan at rock-chips.com>
>> >> >> 
>> >> >> There are two AXI bus in vop2, windows attached on the same bus must
>> >> >> have a unique channel YUV and RGB channel ID.
>> >> >> 
>> >> >> The default IDs will conflict with each other on the rk3588, so they
>> >> >> need to be reassigned.
>> >> >> 
>> >> >> Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
>> >> >> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>> >> >> Tested-by: Derek Foreman <derek.foreman at collabora.com>
>> >> >> 
>> >> >> ---
>> >> >> 
>> >> >> Changes in v5:
>> >> >> - Added in V5
>> >> >> 
>> >> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 14 +++++++++++
>> >> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  9 +++++++
>> >> >>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 26
>> >> >>  +++++++++++++++++++-
>> >> >>  3 files changed, 48 insertions(+), 1 deletion(-)
>> >> >> 
>> >> >> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> >> >> b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index
>> >> >> dc4edd65bc9e..8b9ca046eeeb 100644
>> >> >> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> >> >> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> >> >> @@ -1426,6 +1426,12 @@ static void vop2_plane_atomic_update(struct
>> >> >> drm_plane *plane, &fb->format->format,
>> >> >> 
>> >> >>  		afbc_en ? "AFBC" : "", &yrgb_mst);
>> >> >> 
>> >> >> +	if (vop2->data->soc_id > 3568) {
>> >> >
>> >> >Shouldn't this be done only for rk3588, as specified in the comments
>> >> >below
>> >> >? The test we did before showed that it is failing on rk3576 and 3576 is
>> >> >>
>> >> >3588.
>> >> 
>> >> I think this is because you tested before with the patch I gave Derek
>> >> without axi id assigned for rk3576.
>> >> I assigned axi id for rk3576 in this version 18/18?The new ID assignment
>> >> can adapt to more application scenarios.?, can you test it with the
>> >> whole V5 version again?
>> >
>> >Yes, I will do that. But patch 18 mentions:
>> >+       /* Read only bit on rk3576*/
>> >+       [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
>> >
>> >And the bit is being written here. If it is indeed writable, then I would
>> >drop that comment.
>> 
>> The AXI_BUS_ID for two Cluster windows on RK3576 are fixed by hardware, that
>> means whether we write it or not, it won't change anything.
>> But the AXI_BUS_ID for Esmart windows on rk3576 and  AXI_YRGB/UV_R_ID for
>> all cluster/esmart windows on rk3576 are writeable.
>> I think we directly write it here as the current code can make things easy.
>
>I see, saying it is read only may be a bit confusing then, but it makes sense. 
>You could be more specific adding that writing has no effect.

Okay,  I will add more specific explanation in v6

>
>Anyway, I tested this and it works as expected:
>
>Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
>
>Regards,
>Detlev.
>
>> >> >I suggest
>> >> >
>> >> >	if (vop2->data->soc_id == 3588) {
>> >> >
>> >> >Regards,
>> >> >Detlev
>> >> >
>> >> >> +		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data-
>> >> >>
>> >> >>axi_bus_id);
>> >> >>
>> >> >> +		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data-
>> >> >>
>> >> >>axi_yrgb_r_id);
>> >> >>
>> >> >> +		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data-
>> >> >>
>> >> >>axi_uv_r_id);
>> >> >>
>> >> >> +	}
>> >> >> +
>> >> >> 
>> >> >>  	if (vop2_cluster_window(win))
>> >> >>  	
>> >> >>  		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN,
>> >> >
>> >> >half_block_en);
>> >
>> >Detlev.
>> >
>> >
>> >
>> >_______________________________________________
>> >Linux-rockchip mailing list
>> >Linux-rockchip at lists.infradead.org
>> >http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
>
>

From andyshrk at 163.com  Sat Dec 14 00:15:18 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:18 +0800
Subject: [PATCH v6 10/16] drm/rockchip: vop2: Support for different layer select configuration between VPs
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-11-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP for rk3576, every VP has it's own LAYER_SEL
register, and the configuration value of each VP for the same
window maybe different, so extend the layer_sel_id to array,
let it can descption the layer select configuration value for
different VP.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v4)

Changes in v4:
- Typo fix: selet->select

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  4 +--
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 38 ++++++++++----------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 265bb5bfa27d..af3cd92e6815 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -166,9 +166,9 @@ struct vop2_win_data {
 	const unsigned int supported_rotations;
 
 	/**
-	 * @layer_sel_id: defined by register OVERLAY_LAYER_SEL of VOP2
+	 * @layer_sel_id: defined by register OVERLAY_LAYER_SEL or PORTn_LAYER_SEL
 	 */
-	unsigned int layer_sel_id;
+	unsigned int layer_sel_id[ROCKCHIP_MAX_CRTC];
 	uint64_t feature;
 
 	uint8_t axi_bus_id;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index a2e0126a31a0..01336ef2482a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -350,7 +350,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
-		.layer_sel_id = 3,
+		/* 0xf means this layer can't attached to this VP */
+		.layer_sel_id = { 3, 3, 3, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -363,7 +364,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1e00,
-		.layer_sel_id = 7,
+		.layer_sel_id = { 7, 7, 7, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -376,7 +377,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = 6,
+		.layer_sel_id = { 6, 6, 6, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -389,7 +390,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1800,
-		.layer_sel_id = 2,
+		.layer_sel_id = { 2, 2, 2, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -402,7 +403,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 0,
+		.layer_sel_id = { 0, 0, 0, 0xf },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.max_upscale_factor = 4,
@@ -417,7 +418,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 1,
+		.layer_sel_id = { 1, 1, 1, 0xf },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
@@ -582,7 +583,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 0,
+		.layer_sel_id = { 0, 0, 0, 0 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.axi_bus_id = 0,
@@ -600,7 +601,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 1,
+		.layer_sel_id = { 1, 1, 1, 1 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -618,7 +619,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 4,
+		.layer_sel_id = { 4, 4, 4, 4 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -636,7 +637,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 5,
+		.layer_sel_id =  { 5, 5, 5, 5 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -654,7 +655,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1800,
-		.layer_sel_id = 2,
+		.layer_sel_id = { 2, 2, 2, 2 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 0,
@@ -670,7 +671,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = 3,
+		.layer_sel_id = { 3, 3, 3, 3 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 0,
@@ -686,7 +687,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
-		.layer_sel_id = 6,
+		.layer_sel_id =  { 6, 6, 6, 6 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 1,
@@ -702,7 +703,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1e00,
-		.layer_sel_id = 7,
+		.layer_sel_id =  { 7, 7, 7, 7 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 1,
@@ -1454,7 +1455,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		 */
 		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
 			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
-			if (layer_sel_id == win->data->layer_sel_id)
+			if (layer_sel_id == win->data->layer_sel_id[vp->id])
 				break;
 		}
 
@@ -1464,7 +1465,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		for (i = 0; i < vop2->data->win_size; i++) {
 			old_win = &vop2->win[i];
 			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
-			if (layer_sel_id == old_win->data->layer_sel_id)
+			if (layer_sel_id == old_win->data->layer_sel_id[vp->id])
 				break;
 		}
 
@@ -1512,13 +1513,14 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		}
 
 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id[vp->id]);
 		/*
 		 * When we bind a window from layerM to layerN, we also need to move the old
 		 * window on layerN to layerM to avoid one window selected by two or more layers.
 		 */
 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id,
+			     old_win->data->layer_sel_id[vp->id]);
 	}
 
 	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:09 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:09 +0800
Subject: [PATCH v6 01/16] drm/rockchip: vop2: Add debugfs support
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-2-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

/sys/kernel/debug/dri/vop2/summary:  dump vop display state
/sys/kernel/debug/dri/vop2/regs: dump whole vop registers
/sys/kernel/debug/dri/vop2/active_regs: only dump the registers of
activated modules

Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

Changes in v6:
- Remove an unnecessary blank line.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 259 +++++++++++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  11 +
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 191 ++++++++++++++
 3 files changed, 461 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 2d5e2e298b86..698e40cea3fa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -24,9 +24,11 @@
 #include <drm/drm_atomic_uapi.h>
 #include <drm/drm_blend.h>
 #include <drm/drm_crtc.h>
+#include <linux/debugfs.h>
 #include <drm/drm_debugfs.h>
 #include <drm/drm_flip_work.h>
 #include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
@@ -186,6 +188,7 @@ struct vop2 {
 	 */
 	u32 registered_num_wins;
 
+	struct resource *res;
 	void __iomem *regs;
 	struct regmap *map;
 
@@ -237,6 +240,37 @@ struct vop2 {
 
 #define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
 
+
+/*
+ * bus-format types.
+ */
+struct drm_bus_format_enum_list {
+	int type;
+	const char *name;
+};
+
+static const struct drm_bus_format_enum_list drm_bus_format_enum_list[] = {
+	{ DRM_MODE_CONNECTOR_Unknown, "Unknown" },
+	{ MEDIA_BUS_FMT_RGB565_1X16, "RGB565_1X16" },
+	{ MEDIA_BUS_FMT_RGB666_1X18, "RGB666_1X18" },
+	{ MEDIA_BUS_FMT_RGB666_1X24_CPADHI, "RGB666_1X24_CPADHI" },
+	{ MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, "RGB666_1X7X3_SPWG" },
+	{ MEDIA_BUS_FMT_YUV8_1X24, "YUV8_1X24" },
+	{ MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
+	{ MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
+	{ MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
+	{ MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
+	{ MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
+	{ MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, "RGB888_1X7X4_SPWG" },
+	{ MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, "RGB888_1X7X4_JEIDA" },
+	{ MEDIA_BUS_FMT_UYVY8_2X8, "UYVY8_2X8" },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, "YUYV8_1X16" },
+	{ MEDIA_BUS_FMT_UYVY8_1X16, "UYVY8_1X16" },
+	{ MEDIA_BUS_FMT_RGB101010_1X30, "RGB101010_1X30" },
+	{ MEDIA_BUS_FMT_YUYV10_1X20, "YUYV10_1X20" },
+};
+static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
+
 static const struct regmap_config vop2_regmap_config;
 
 static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
@@ -2718,6 +2752,229 @@ static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
 	.atomic_disable = vop2_crtc_atomic_disable,
 };
 
+static void vop2_dump_connector_on_crtc(struct drm_crtc *crtc, struct seq_file *s)
+{
+	struct drm_connector_list_iter conn_iter;
+	struct drm_connector *connector;
+
+	drm_connector_list_iter_begin(crtc->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
+		if (crtc->state->connector_mask & drm_connector_mask(connector))
+			seq_printf(s, "    Connector: %s\n", connector->name);
+
+	}
+	drm_connector_list_iter_end(&conn_iter);
+}
+
+static int vop2_plane_state_dump(struct seq_file *s, struct drm_plane *plane)
+{
+	struct vop2_win *win = to_vop2_win(plane);
+	struct drm_plane_state *pstate = plane->state;
+	struct drm_rect *src, *dst;
+	struct drm_framebuffer *fb;
+	struct drm_gem_object *obj;
+	struct rockchip_gem_object *rk_obj;
+	bool xmirror;
+	bool ymirror;
+	bool rotate_270;
+	bool rotate_90;
+	dma_addr_t fb_addr;
+	int i;
+
+	seq_printf(s, "    %s: %s\n", win->data->name, !pstate ?
+		   "DISABLED" : pstate->crtc ? "ACTIVE" : "DISABLED");
+
+	if (!pstate || !pstate->fb)
+		return 0;
+
+	fb = pstate->fb;
+	src = &pstate->src;
+	dst = &pstate->dst;
+	xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
+	ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
+	rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
+	rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
+
+	seq_printf(s, "\twin_id: %d\n", win->win_id);
+
+	seq_printf(s, "\tformat: %p4cc%s glb_alpha[0x%x]\n",
+		   &fb->format->format,
+		   drm_is_afbc(fb->modifier) ? "[AFBC]" : "",
+		   pstate->alpha >> 8);
+	seq_printf(s, "\trotate: xmirror: %d ymirror: %d rotate_90: %d rotate_270: %d\n",
+		   xmirror, ymirror, rotate_90, rotate_270);
+	seq_printf(s, "\tzpos: %d\n", pstate->normalized_zpos);
+	seq_printf(s, "\tsrc: pos[%d, %d] rect[%d x %d]\n", src->x1 >> 16,
+		   src->y1 >> 16, drm_rect_width(src) >> 16,
+		   drm_rect_height(src) >> 16);
+	seq_printf(s, "\tdst: pos[%d, %d] rect[%d x %d]\n", dst->x1, dst->y1,
+		   drm_rect_width(dst), drm_rect_height(dst));
+
+	for (i = 0; i < fb->format->num_planes; i++) {
+		obj = fb->obj[i];
+		rk_obj = to_rockchip_obj(obj);
+		fb_addr = rk_obj->dma_addr + fb->offsets[i];
+
+		seq_printf(s, "\tbuf[%d]: addr: %pad pitch: %d offset: %d\n",
+			   i, &fb_addr, fb->pitches[i], fb->offsets[i]);
+	}
+
+	return 0;
+}
+
+static int vop2_crtc_state_dump(struct drm_crtc *crtc, struct seq_file *s)
+{
+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct drm_crtc_state *cstate = crtc->state;
+	struct rockchip_crtc_state *vcstate;
+	struct drm_display_mode *mode;
+	struct drm_plane *plane;
+	bool interlaced;
+
+	seq_printf(s, "Video Port%d: %s\n", vp->id, !cstate ?
+		   "DISABLED" : cstate->active ? "ACTIVE" : "DISABLED");
+
+	if (!cstate || !cstate->active)
+		return 0;
+
+	mode = &crtc->state->adjusted_mode;
+	vcstate = to_rockchip_crtc_state(cstate);
+	interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+
+	vop2_dump_connector_on_crtc(crtc, s);
+	seq_printf(s, "\tbus_format[%x]: %s\n", vcstate->bus_format,
+		    drm_get_bus_format_name(vcstate->bus_format));
+	seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode);
+	seq_printf(s, " color_space[%d]\n", vcstate->color_space);
+	seq_printf(s, "    Display mode: %dx%d%s%d\n",
+		    mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
+		    drm_mode_vrefresh(mode));
+	seq_printf(s, "\tclk[%d] real_clk[%d] type[%x] flag[%x]\n",
+		    mode->clock, mode->crtc_clock, mode->type, mode->flags);
+	seq_printf(s, "\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
+		    mode->hsync_end, mode->htotal);
+	seq_printf(s, "\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
+		    mode->vsync_end, mode->vtotal);
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		vop2_plane_state_dump(s, plane);
+	}
+
+	return 0;
+}
+
+static int vop2_summary_show(struct seq_file *s, void *data)
+{
+	struct drm_info_node *node = s->private;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *drm_dev = minor->dev;
+	struct drm_crtc *crtc;
+
+	drm_modeset_lock_all(drm_dev);
+	drm_for_each_crtc(crtc, drm_dev) {
+		vop2_crtc_state_dump(crtc, s);
+	}
+	drm_modeset_unlock_all(drm_dev);
+
+	return 0;
+}
+
+static void vop2_regs_print(struct vop2 *vop2, struct seq_file *s,
+			    const struct vop2_regs_dump *dump, bool active_only)
+{
+	resource_size_t start;
+	u32 val;
+	int i;
+
+	if (dump->en_mask && active_only) {
+		val = vop2_readl(vop2, dump->base + dump->en_reg);
+		if ((val & dump->en_mask) != dump->en_val)
+			return;
+	}
+
+	seq_printf(s, "\n%s:\n", dump->name);
+
+	start = vop2->res->start + dump->base;
+	for (i = 0; i < dump->size >> 2; i += 4) {
+		seq_printf(s, "%08x:  %08x %08x %08x %08x\n", (u32)start + i * 4,
+			   vop2_readl(vop2, dump->base + (4 * i)),
+			   vop2_readl(vop2, dump->base + (4 * (i + 1))),
+			   vop2_readl(vop2, dump->base + (4 * (i + 2))),
+			   vop2_readl(vop2, dump->base + (4 * (i + 3))));
+	}
+}
+
+static void __vop2_regs_dump(struct seq_file *s, bool active_only)
+{
+	struct drm_info_node *node = s->private;
+	struct vop2 *vop2 = node->info_ent->data;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *drm_dev = minor->dev;
+	const struct vop2_regs_dump *dump;
+	unsigned int i;
+
+	drm_modeset_lock_all(drm_dev);
+
+	regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
+
+	if (vop2->enable_count) {
+		for (i = 0; i < vop2->data->regs_dump_size; i++) {
+			dump = &vop2->data->regs_dump[i];
+			vop2_regs_print(vop2, s, dump, active_only);
+		}
+	} else {
+		seq_printf(s, "VOP disabled\n");
+	}
+	drm_modeset_unlock_all(drm_dev);
+}
+
+static int vop2_regs_show(struct seq_file *s, void *arg)
+{
+	__vop2_regs_dump(s, false);
+
+	return 0;
+}
+
+static int vop2_active_regs_show(struct seq_file *s, void *data)
+{
+	__vop2_regs_dump(s, true);
+
+	return 0;
+}
+
+static struct drm_info_list vop2_debugfs_list[] = {
+	{ "summary", vop2_summary_show, 0, NULL },
+	{ "active_regs", vop2_active_regs_show,   0, NULL },
+	{ "regs", vop2_regs_show,   0, NULL },
+};
+
+static void vop2_debugfs_init(struct vop2 *vop2, struct drm_minor *minor)
+{
+	struct dentry *root;
+	unsigned int i;
+
+	root = debugfs_create_dir("vop2", minor->debugfs_root);
+	if (!IS_ERR(root)) {
+		for (i = 0; i < ARRAY_SIZE(vop2_debugfs_list); i++)
+			vop2_debugfs_list[i].data = vop2;
+
+		drm_debugfs_create_files(vop2_debugfs_list,
+					 ARRAY_SIZE(vop2_debugfs_list),
+					 root, minor);
+	}
+}
+
+static int vop2_crtc_late_register(struct drm_crtc *crtc)
+{
+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct vop2 *vop2 = vp->vop2;
+
+	if (drm_crtc_index(crtc) == 0)
+		vop2_debugfs_init(vop2, crtc->dev->primary);
+
+	return 0;
+}
+
 static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc)
 {
 	struct rockchip_crtc_state *vcstate;
@@ -2767,6 +3024,7 @@ static const struct drm_crtc_funcs vop2_crtc_funcs = {
 	.atomic_destroy_state = vop2_crtc_destroy_state,
 	.enable_vblank = vop2_crtc_enable_vblank,
 	.disable_vblank = vop2_crtc_disable_vblank,
+	.late_register = vop2_crtc_late_register,
 };
 
 static irqreturn_t vop2_isr(int irq, void *data)
@@ -3316,6 +3574,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 		return -EINVAL;
 	}
 
+	vop2->res = res;
 	vop2->regs = devm_ioremap_resource(dev, res);
 	if (IS_ERR(vop2->regs))
 		return PTR_ERR(vop2->regs);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 22c43a50caf0..2cb7b6b40c77 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -122,6 +122,15 @@ enum vop2_win_regs {
 	VOP2_WIN_MAX_REG,
 };
 
+struct vop2_regs_dump {
+	const char *name;
+	u32 base;
+	u32 size;
+	u32 en_reg;
+	u32 en_val;
+	u32 en_mask;
+};
+
 struct vop2_win_data {
 	const char *name;
 	unsigned int phys_id;
@@ -160,10 +169,12 @@ struct vop2_data {
 	u64 feature;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
+	const struct vop2_regs_dump *regs_dump;
 	struct vop_rect max_input;
 	struct vop_rect max_output;
 
 	unsigned int win_size;
+	unsigned int regs_dump_size;
 	unsigned int soc_id;
 };
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 008b70fbc33a..9247f94343f2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -258,6 +258,88 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	},
 };
 
+static const struct vop2_regs_dump rk3568_regs_dump[] = {
+	{
+		.name = "SYS",
+		.base = RK3568_REG_CFG_DONE,
+		.size = 0x100,
+		.en_reg  = 0,
+		.en_val = 0,
+		.en_mask = 0
+	}, {
+		.name = "OVL",
+		.base = RK3568_OVL_CTRL,
+		.size = 0x100,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "VP0",
+		.base = RK3568_VP0_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP1",
+		.base = RK3568_VP1_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP2",
+		.base = RK3568_VP2_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+
+	}, {
+		.name = "Cluster0",
+		.base = RK3568_CLUSTER0_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster1",
+		.base = RK3568_CLUSTER1_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Esmart0",
+		.base = RK3568_ESMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart1",
+		.base = RK3568_ESMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart0",
+		.base = RK3568_SMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart1",
+		.base = RK3568_SMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	},
+};
+
 static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -438,6 +520,109 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	},
 };
 
+static const struct vop2_regs_dump rk3588_regs_dump[] = {
+	{
+		.name = "SYS",
+		.base = RK3568_REG_CFG_DONE,
+		.size = 0x100,
+		.en_reg  = 0,
+		.en_val = 0,
+		.en_mask = 0
+	}, {
+		.name = "OVL",
+		.base = RK3568_OVL_CTRL,
+		.size = 0x100,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "VP0",
+		.base = RK3568_VP0_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP1",
+		.base = RK3568_VP1_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP2",
+		.base = RK3568_VP2_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+
+	}, {
+		.name = "VP3",
+		.base = RK3588_VP3_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "Cluster0",
+		.base = RK3568_CLUSTER0_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster1",
+		.base = RK3568_CLUSTER1_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster2",
+		.base = RK3588_CLUSTER2_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster3",
+		.base = RK3588_CLUSTER3_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Esmart0",
+		.base = RK3568_ESMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart1",
+		.base = RK3568_ESMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart2",
+		.base = RK3588_ESMART2_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart3",
+		.base = RK3588_ESMART3_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	},
+};
+
 static const struct vop2_data rk3566_vop = {
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
@@ -446,6 +631,8 @@ static const struct vop2_data rk3566_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.regs_dump = rk3568_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
 	.soc_id = 3566,
 };
 
@@ -457,6 +644,8 @@ static const struct vop2_data rk3568_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.regs_dump = rk3568_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
 	.soc_id = 3568,
 };
 
@@ -469,6 +658,8 @@ static const struct vop2_data rk3588_vop = {
 	.vp = rk3588_vop_video_ports,
 	.win = rk3588_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
+	.regs_dump = rk3588_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
 	.soc_id = 3588,
 };
 
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:10 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:10 +0800
Subject: [PATCH v6 02/16] drm/rockchip: vop2: Fix the windows switch between different layers
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-3-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Every layer of vop2 should bind a window, and we also need to make
sure that this window is not used by other layer.

0x5 is a reserved layer sel value on rk3568, but it will select
Cluster3 on rk3588, configure unused layers to 0x5  will lead
alpha blending error on rk3588.

When we bind a window from layerM to layerN, we move the old window
on layerN to layerM.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Tested-by: Derek Foreman <derek.foreman at collabora.com>
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>

---

Changes in v6:
- Limit line length not exceeds 100

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 47 ++++++++++++++------
 1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 698e40cea3fa..81207a79530c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2541,7 +2541,10 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
 	struct drm_plane *plane;
 	u32 layer_sel = 0;
 	u32 port_sel;
-	unsigned int nlayer, ofs;
+	u8 layer_id;
+	u8 old_layer_id;
+	u8 layer_sel_id;
+	unsigned int ofs;
 	u32 ovl_ctrl;
 	int i;
 	struct vop2_video_port *vp0 = &vop2->vps[0];
@@ -2585,9 +2588,30 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
 	for (i = 0; i < vp->id; i++)
 		ofs += vop2->vps[i].nlayers;
 
-	nlayer = 0;
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
 		struct vop2_win *win = to_vop2_win(plane);
+		struct vop2_win *old_win;
+
+		layer_id = (u8)(plane->state->normalized_zpos + ofs);
+
+		/*
+		 * Find the layer this win bind in old state.
+		 */
+		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
+			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
+			if (layer_sel_id == win->data->layer_sel_id)
+				break;
+		}
+
+		/*
+		 * Find the win bind to this layer in old state
+		 */
+		for (i = 0; i < vop2->data->win_size; i++) {
+			old_win = &vop2->win[i];
+			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
+			if (layer_sel_id == old_win->data->layer_sel_id)
+				break;
+		}
 
 		switch (win->data->phys_id) {
 		case ROCKCHIP_VOP2_CLUSTER0:
@@ -2632,17 +2656,14 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
 			break;
 		}
 
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
-							  0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
-							 win->data->layer_sel_id);
-		nlayer++;
-	}
-
-	/* configure unused layers to 0x5 (reserved) */
-	for (; nlayer < vp->nlayers; nlayer++) {
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 5);
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
+		/*
+		 * When we bind a window from layerM to layerN, we also need to move the old
+		 * window on layerN to layerM to avoid one window selected by two or more layers.
+		 */
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
 	}
 
 	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:11 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:11 +0800
Subject: [PATCH v6 03/16] drm/rockchip: vop2: Set AXI id for rk3588
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-4-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

There are two AXI bus in vop2, windows attached on the same bus must
have a unique channel YUV and RGB channel ID.

The default IDs will conflict with each other on the rk3588, so they
need to be reassigned.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Derek Foreman <derek.foreman at collabora.com>
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v5)

Changes in v5:
- Added in V5

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 14 +++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  9 +++++++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 26 +++++++++++++++++++-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 81207a79530c..0723a7606cb1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1426,6 +1426,12 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		&fb->format->format,
 		afbc_en ? "AFBC" : "", &yrgb_mst);
 
+	if (vop2->data->soc_id > 3568) {
+		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
+		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
+		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
+	}
+
 	if (vop2_cluster_window(win))
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
@@ -3354,6 +3360,10 @@ static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
 	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
 	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
+	/* RK3588 only, reserved bit on rk3568*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
 
 	/* Scale */
 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
@@ -3446,6 +3456,10 @@ static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
 	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
 	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	/* RK3588 only, reserved register on rk3568 */
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
 
 	/* Scale */
 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 2cb7b6b40c77..f4724a402ac2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -78,6 +78,9 @@ enum vop2_win_regs {
 	VOP2_WIN_COLOR_KEY,
 	VOP2_WIN_COLOR_KEY_EN,
 	VOP2_WIN_DITHER_UP,
+	VOP2_WIN_AXI_BUS_ID,
+	VOP2_WIN_AXI_YRGB_R_ID,
+	VOP2_WIN_AXI_UV_R_ID,
 
 	/* scale regs */
 	VOP2_WIN_SCALE_YRGB_X,
@@ -149,6 +152,10 @@ struct vop2_win_data {
 	unsigned int layer_sel_id;
 	uint64_t feature;
 
+	uint8_t axi_bus_id;
+	uint8_t axi_yrgb_r_id;
+	uint8_t axi_uv_r_id;
+
 	unsigned int max_upscale_factor;
 	unsigned int max_downscale_factor;
 	const u8 dly[VOP2_DLY_MODE_MAX];
@@ -319,6 +326,7 @@ enum dst_factor_mode {
 
 #define RK3568_CLUSTER_WIN_CTRL0		0x00
 #define RK3568_CLUSTER_WIN_CTRL1		0x04
+#define RK3568_CLUSTER_WIN_CTRL2		0x08
 #define RK3568_CLUSTER_WIN_YRGB_MST		0x10
 #define RK3568_CLUSTER_WIN_CBR_MST		0x14
 #define RK3568_CLUSTER_WIN_VIR			0x18
@@ -341,6 +349,7 @@ enum dst_factor_mode {
 /* (E)smart register definition, offset relative to window base */
 #define RK3568_SMART_CTRL0			0x00
 #define RK3568_SMART_CTRL1			0x04
+#define RK3588_SMART_AXI_CTRL			0x08
 #define RK3568_SMART_REGION0_CTRL		0x10
 #define RK3568_SMART_REGION0_YRGB_MST		0x14
 #define RK3568_SMART_REGION0_CBR_MST		0x18
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 9247f94343f2..65a88f489693 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -395,7 +395,7 @@ static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
  * AXI1 is a read only bus.
  *
  * Every window on a AXI bus must assigned two unique
- * read id(yrgb_id/uv_id, valid id are 0x1~0xe).
+ * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe).
  *
  * AXI0:
  * Cluster0/1, Esmart0/1, WriteBack
@@ -415,6 +415,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 0,
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 2,
+		.axi_uv_r_id = 3,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -431,6 +434,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -446,6 +452,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 2,
+		.axi_uv_r_id = 3,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -461,6 +470,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -475,6 +487,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 2,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -488,6 +503,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 3,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x01,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -501,6 +519,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 6,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -514,6 +535,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 7,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x0d,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:15 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:15 +0800
Subject: [PATCH v6 07/16] drm/rockchip: vop2: include rockchip_drm_drv.h
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-8-andyshrk@163.com>

From: Min-Hua Chen <minhuadotchen at gmail.com>

Move rockchip_drm_drv.h in rockchip_drm_vop2.h to fix the follow
sparse warning:

ARCH=arm64 LLVM=1 make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
mrproper defconfig all  -j12

drivers/gpu/drm/rockchip/rockchip_vop2_reg.c:502:24: sparse:
warning: symbol 'vop2_platform_driver' was not declared. Should it
be static?

It is also beneficial for the upcoming support for rk3576.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Signed-off-by: Min-Hua Chen <minhuadotchen at gmail.com>

---

(no changes since v3)

Changes in v3:
- Split it from 10/15, as it fix a exiting compile warning.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 85d281edfbfe..b5f35839d5e8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -35,7 +35,6 @@
 #include <uapi/linux/videodev2.h>
 #include <dt-bindings/soc/rockchip,vop2.h>
 
-#include "rockchip_drm_drv.h"
 #include "rockchip_drm_gem.h"
 #include "rockchip_drm_vop2.h"
 #include "rockchip_rgb.h"
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index f4724a402ac2..29cc7fb8f6d8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -9,6 +9,7 @@
 
 #include <linux/regmap.h>
 #include <drm/drm_modes.h>
+#include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
 #define VOP2_VP_FEATURE_OUTPUT_10BIT        BIT(0)
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:12 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:12 +0800
Subject: [PATCH v6 04/16] drm/rockchip: vop2: Setup delay cycle for Esmart2/3
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-5-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Each layer needs to set the correct delay cycle to display properly
without unexpected offset on screen.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Derek Foreman <derek.foreman at collabora.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0723a7606cb1..f143df2b13a1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2704,9 +2704,11 @@ static void vop2_setup_dly_for_windows(struct vop2 *vop2)
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART0:
+		case ROCKCHIP_VOP2_ESMART2:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART3:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
 			break;
 		}
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:16 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:16 +0800
Subject: [PATCH v6 08/16] drm/rockchip: vop2: Support 32x8 superblock afbc
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-9-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

This is the only afbc format supported by the upcoming
VOP for rk3576.

Add support for it.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v2)

Changes in v2:
- split it from main patch add support for rk3576

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index b5f35839d5e8..efe7d0cbe155 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1454,16 +1454,18 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
 	if (afbc_en) {
-		u32 stride;
+		u32 stride, block_w;
+
+		/* the afbc superblock is 16 x 16 or 32 x 8 */
+		block_w = fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ? 32 : 16;
 
-		/* the afbc superblock is 16 x 16 */
 		afbc_format = vop2_convert_afbc_format(fb->format->format);
 
 		/* Enable color transform for YTR */
 		if (fb->modifier & AFBC_FORMAT_MOD_YTR)
 			afbc_format |= (1 << 4);
 
-		afbc_tile_num = ALIGN(actual_w, 16) >> 4;
+		afbc_tile_num = ALIGN(actual_w, block_w) / block_w;
 
 		/*
 		 * AFBC pic_vir_width is count by pixel, this is different
@@ -1474,6 +1476,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 			drm_dbg_kms(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n",
 				    vp->id, win->data->name, stride);
 
+		 /* It's for head stride, each head size is 16 byte */
+		stride = ALIGN(stride, block_w) / block_w * 16;
+
 		uv_swap = vop2_afbc_uv_swap(fb->format->format);
 		/*
 		 * This is a workaround for crazy IC design, Cluster
@@ -1504,7 +1509,11 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1);
 
-		vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
+		if (fb->modifier & AFBC_FORMAT_MOD_SPLIT)
+			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 1);
+		else
+			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
+
 		transform_offset = vop2_afbc_transform_offset(pstate, half_block_en);
 		vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
 		vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:04 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:04 +0800
Subject: [PATCH v6 05/16] drm/rockchip: vop2: Check linear format for Cluster windows on rk3566/8
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-6-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The Cluster windows on rk3566/8 only support afbc mode.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>

---

Changes in v6:
- Move the linear check to format_mod_supported() hook

Changes in v5:
- Added in V5

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index f143df2b13a1..94f77faf14d1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -593,6 +593,16 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
 	if (modifier == DRM_FORMAT_MOD_INVALID)
 		return false;
 
+	if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
+		if (vop2_cluster_window(win)) {
+			if (modifier == DRM_FORMAT_MOD_LINEAR) {
+				drm_dbg_kms(vop2->drm,
+					    "Cluster window only support format with afbc\n");
+				return false;
+			}
+		}
+	}
+
 	if (modifier == DRM_FORMAT_MOD_LINEAR)
 		return true;
 
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:08 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:08 +0800
Subject: [PATCH v6 09/16] drm/rockchip: vop2: Add platform specific callback
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-10-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The VOP interface mux, overlay, background delay cycle configuration
of different SOC are much different. Add platform specific callback
ops to let the core driver look cleaner and more refined.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v2)

Changes in v2:
- Add platform specific callback

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1145 +-----------------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  168 +++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c |  992 +++++++++++++++
 3 files changed, 1180 insertions(+), 1125 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index efe7d0cbe155..fded1e931c9a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -33,7 +33,6 @@
 #include <drm/drm_vblank.h>
 
 #include <uapi/linux/videodev2.h>
-#include <dt-bindings/soc/rockchip,vop2.h>
 
 #include "rockchip_drm_gem.h"
 #include "rockchip_drm_vop2.h"
@@ -102,143 +101,6 @@ enum vop2_afbc_format {
 	VOP2_AFBC_FMT_INVALID = -1,
 };
 
-union vop2_alpha_ctrl {
-	u32 val;
-	struct {
-		/* [0:1] */
-		u32 color_mode:1;
-		u32 alpha_mode:1;
-		/* [2:3] */
-		u32 blend_mode:2;
-		u32 alpha_cal_mode:1;
-		/* [5:7] */
-		u32 factor_mode:3;
-		/* [8:9] */
-		u32 alpha_en:1;
-		u32 src_dst_swap:1;
-		u32 reserved:6;
-		/* [16:23] */
-		u32 glb_alpha:8;
-	} bits;
-};
-
-struct vop2_alpha {
-	union vop2_alpha_ctrl src_color_ctrl;
-	union vop2_alpha_ctrl dst_color_ctrl;
-	union vop2_alpha_ctrl src_alpha_ctrl;
-	union vop2_alpha_ctrl dst_alpha_ctrl;
-};
-
-struct vop2_alpha_config {
-	bool src_premulti_en;
-	bool dst_premulti_en;
-	bool src_pixel_alpha_en;
-	bool dst_pixel_alpha_en;
-	u16 src_glb_alpha_value;
-	u16 dst_glb_alpha_value;
-};
-
-struct vop2_win {
-	struct vop2 *vop2;
-	struct drm_plane base;
-	const struct vop2_win_data *data;
-	struct regmap_field *reg[VOP2_WIN_MAX_REG];
-
-	/**
-	 * @win_id: graphic window id, a cluster may be split into two
-	 * graphics windows.
-	 */
-	u8 win_id;
-	u8 delay;
-	u32 offset;
-
-	enum drm_plane_type type;
-};
-
-struct vop2_video_port {
-	struct drm_crtc crtc;
-	struct vop2 *vop2;
-	struct clk *dclk;
-	unsigned int id;
-	const struct vop2_video_port_data *data;
-
-	struct completion dsp_hold_completion;
-
-	/**
-	 * @win_mask: Bitmask of windows attached to the video port;
-	 */
-	u32 win_mask;
-
-	struct vop2_win *primary_plane;
-	struct drm_pending_vblank_event *event;
-
-	unsigned int nlayers;
-};
-
-struct vop2 {
-	struct device *dev;
-	struct drm_device *drm;
-	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
-
-	const struct vop2_data *data;
-	/*
-	 * Number of windows that are registered as plane, may be less than the
-	 * total number of hardware windows.
-	 */
-	u32 registered_num_wins;
-
-	struct resource *res;
-	void __iomem *regs;
-	struct regmap *map;
-
-	struct regmap *sys_grf;
-	struct regmap *vop_grf;
-	struct regmap *vo1_grf;
-	struct regmap *sys_pmu;
-
-	/* physical map length of vop2 register */
-	u32 len;
-
-	void __iomem *lut_regs;
-
-	/* protects crtc enable/disable */
-	struct mutex vop2_lock;
-
-	int irq;
-
-	/*
-	 * Some global resources are shared between all video ports(crtcs), so
-	 * we need a ref counter here.
-	 */
-	unsigned int enable_count;
-	struct clk *hclk;
-	struct clk *aclk;
-	struct clk *pclk;
-
-	/* optional internal rgb encoder */
-	struct rockchip_rgb *rgb;
-
-	/* must be put at the end of the struct */
-	struct vop2_win win[];
-};
-
-#define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
-					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
-
-#define vop2_output_if_is_dp(x)		((x) == ROCKCHIP_VOP2_EP_DP0 || \
-					 (x) == ROCKCHIP_VOP2_EP_DP1)
-
-#define vop2_output_if_is_edp(x)	((x) == ROCKCHIP_VOP2_EP_EDP0 || \
-					 (x) == ROCKCHIP_VOP2_EP_EDP1)
-
-#define vop2_output_if_is_mipi(x)	((x) == ROCKCHIP_VOP2_EP_MIPI0 || \
-					 (x) == ROCKCHIP_VOP2_EP_MIPI1)
-
-#define vop2_output_if_is_lvds(x)	((x) == ROCKCHIP_VOP2_EP_LVDS0 || \
-					 (x) == ROCKCHIP_VOP2_EP_LVDS1)
-
-#define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
-
 
 /*
  * bus-format types.
@@ -272,15 +134,6 @@ static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
 
 static const struct regmap_config vop2_regmap_config;
 
-static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
-{
-	return container_of(crtc, struct vop2_video_port, crtc);
-}
-
-static struct vop2_win *to_vop2_win(struct drm_plane *p)
-{
-	return container_of(p, struct vop2_win, base);
-}
 
 static void vop2_lock(struct vop2 *vop2)
 {
@@ -292,44 +145,6 @@ static void vop2_unlock(struct vop2 *vop2)
 	mutex_unlock(&vop2->vop2_lock);
 }
 
-static void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
-{
-	regmap_write(vop2->map, offset, v);
-}
-
-static void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
-{
-	regmap_write(vp->vop2->map, vp->data->offset + offset, v);
-}
-
-static u32 vop2_readl(struct vop2 *vop2, u32 offset)
-{
-	u32 val;
-
-	regmap_read(vop2->map, offset, &val);
-
-	return val;
-}
-
-static u32 vop2_vp_read(struct vop2_video_port *vp, u32 offset)
-{
-	u32 val;
-
-	regmap_read(vp->vop2->map, vp->data->offset + offset, &val);
-
-	return val;
-}
-
-static void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
-{
-	regmap_field_write(win->reg[reg], v);
-}
-
-static bool vop2_cluster_window(const struct vop2_win *win)
-{
-	return win->data->feature & WIN_FEATURE_CLUSTER;
-}
-
 /*
  * Note:
  * The write mask function is documented but missing on rk3566/8, writes
@@ -1724,6 +1539,7 @@ static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
 static void vop2_post_config(struct drm_crtc *crtc)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct vop2 *vop2 = vp->vop2;
 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 	u16 vtotal = mode->crtc_vtotal;
 	u16 hdisplay = mode->crtc_hdisplay;
@@ -1734,18 +1550,10 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	u32 top_margin = 100, bottom_margin = 100;
 	u16 hsize = hdisplay * (left_margin + right_margin) / 200;
 	u16 vsize = vdisplay * (top_margin + bottom_margin) / 200;
-	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
 	u16 hact_end, vact_end;
 	u32 val;
-	u32 bg_dly;
-	u32 pre_scan_dly;
-
-	bg_dly = vp->data->pre_scan_max_dly[3];
-	vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
-		    FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
 
-	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
-	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+	vop2->ops->setup_bg_dly(vp);
 
 	vsize = rounddown(vsize, 2);
 	hsize = rounddown(hsize, 2);
@@ -1781,347 +1589,6 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
 }
 
-static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_crtc *crtc = &vp->crtc;
-	u32 die, dip;
-
-	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
-	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
-
-	switch (id) {
-	case ROCKCHIP_VOP2_EP_RGB0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_RGB |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		if (polflags & POLFLAG_DCLK_INV)
-			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
-		else
-			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
-		break;
-	case ROCKCHIP_VOP2_EP_HDMI0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_EDP0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_EDP |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI1:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_LVDS0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_LVDS1:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		break;
-	default:
-		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
-		return 0;
-	}
-
-	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
-
-	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
-	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
-
-	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
-}
-
-/*
- * calc the dclk on rk3588
- * the available div of dclk is 1, 2, 4
- */
-static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
-{
-	if (child_clk * 4 <= max_dclk)
-		return child_clk * 4;
-	else if (child_clk * 2 <= max_dclk)
-		return child_clk * 2;
-	else if (child_clk <= max_dclk)
-		return child_clk;
-	else
-		return 0;
-}
-
-/*
- * 4 pixclk/cycle on rk3588
- * RGB/eDP/HDMI: if_pixclk >= dclk_core
- * DP: dp_pixclk = dclk_out <= dclk_core
- * DSI: mipi_pixclk <= dclk_out <= dclk_core
- */
-static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
-					 int *dclk_core_div, int *dclk_out_div,
-					 int *if_pixclk_div, int *if_dclk_div)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_crtc *crtc = &vp->crtc;
-	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
-	int output_mode = vcstate->output_mode;
-	unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
-	unsigned long dclk_core_rate = v_pixclk >> 2;
-	unsigned long dclk_rate = v_pixclk;
-	unsigned long dclk_out_rate;
-	unsigned long if_pixclk_rate;
-	int K = 1;
-
-	if (vop2_output_if_is_hdmi(id)) {
-		/*
-		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
-		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
-		 */
-		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
-			dclk_rate = dclk_rate >> 1;
-			K = 2;
-		}
-
-		if_pixclk_rate = (dclk_core_rate << 1) / K;
-		/*
-		 * if_dclk_rate = dclk_core_rate / K;
-		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
-		 * *if_dclk_div = dclk_rate / if_dclk_rate;
-		 */
-		*if_pixclk_div = 2;
-		*if_dclk_div = 4;
-	} else if (vop2_output_if_is_edp(id)) {
-		/*
-		 * edp_pixclk = edp_dclk > dclk_core
-		 */
-		if_pixclk_rate = v_pixclk / K;
-		dclk_rate = if_pixclk_rate * K;
-		/*
-		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
-		 * *if_dclk_div = *if_pixclk_div;
-		 */
-		*if_pixclk_div = K;
-		*if_dclk_div = K;
-	} else if (vop2_output_if_is_dp(id)) {
-		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
-			dclk_out_rate = v_pixclk >> 3;
-		else
-			dclk_out_rate = v_pixclk >> 2;
-
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
-		if (!dclk_rate) {
-			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n",
-				dclk_out_rate);
-			return 0;
-		}
-		*dclk_out_div = dclk_rate / dclk_out_rate;
-	} else if (vop2_output_if_is_mipi(id)) {
-		if_pixclk_rate = dclk_core_rate / K;
-		/*
-		 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
-		 */
-		dclk_out_rate = if_pixclk_rate;
-		/*
-		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
-		 * we get a little factor here
-		 */
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
-		if (!dclk_rate) {
-			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n",
-				dclk_out_rate);
-			return 0;
-		}
-		*dclk_out_div = dclk_rate / dclk_out_rate;
-		/*
-		 * mipi pixclk == dclk_out
-		 */
-		*if_pixclk_div = 1;
-	} else if (vop2_output_if_is_dpi(id)) {
-		dclk_rate = v_pixclk;
-	}
-
-	*dclk_core_div = dclk_rate / dclk_core_rate;
-	*if_pixclk_div = ilog2(*if_pixclk_div);
-	*if_dclk_div = ilog2(*if_dclk_div);
-	*dclk_core_div = ilog2(*dclk_core_div);
-	*dclk_out_div = ilog2(*dclk_out_div);
-
-	drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
-		dclk_rate, *if_pixclk_div, *if_dclk_div);
-
-	return dclk_rate;
-}
-
-/*
- * MIPI port mux on rk3588:
- * 0: Video Port2
- * 1: Video Port3
- * 3: Video Port 1(MIPI1 only)
- */
-static u32 rk3588_get_mipi_port_mux(int vp_id)
-{
-	if (vp_id == 1)
-		return 3;
-	else if (vp_id == 3)
-		return 1;
-	else
-		return 0;
-}
-
-static u32 rk3588_get_hdmi_pol(u32 flags)
-{
-	u32 val;
-
-	val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
-	val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
-
-	return val;
-}
-
-static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
-	unsigned long clock;
-	u32 die, dip, div, vp_clk_div, val;
-
-	clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
-				    &if_pixclk_div, &if_dclk_div);
-	if (!clock)
-		return 0;
-
-	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
-	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
-
-	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
-	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
-	div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
-
-	switch (id) {
-	case ROCKCHIP_VOP2_EP_HDMI0:
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
-			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
-		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
-		break;
-	case ROCKCHIP_VOP2_EP_HDMI1:
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
-			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
-		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
-		break;
-	case ROCKCHIP_VOP2_EP_EDP0:
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
-		break;
-	case ROCKCHIP_VOP2_EP_EDP1:
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI0:
-		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
-		val = rk3588_get_mipi_port_mux(vp->id);
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI1:
-		div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		val = rk3588_get_mipi_port_mux(vp->id);
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
-		break;
-	case ROCKCHIP_VOP2_EP_DP0:
-		die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
-		dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
-		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_DP1:
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
-		dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
-		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
-		break;
-	default:
-		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
-		return 0;
-	}
-
-	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
-
-	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
-	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
-	vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
-	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
-
-	return clock;
-}
-
-static unsigned long vop2_set_intf_mux(struct vop2_video_port *vp, int ep_id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-
-	if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568)
-		return rk3568_set_intf_mux(vp, ep_id, polflags);
-	else if (vop2->data->soc_id == 3588)
-		return rk3588_set_intf_mux(vp, ep_id, polflags);
-	else
-		return 0;
-}
-
 static int us_to_vertical_line(struct drm_display_mode *mode, int us)
 {
 	return us * mode->clock / mode->htotal / 1000;
@@ -2194,7 +1661,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
 		 * process multi(1/2/4/8) pixels per cycle, so the dclk feed by the
 		 * system cru may be the 1/2 or 1/4 of mode->clock.
 		 */
-		clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
+		clock = vop2->ops->setup_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
 	}
 
 	if (!clock) {
@@ -2323,454 +1790,13 @@ static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
 	return 0;
 }
 
-static bool is_opaque(u16 alpha)
-{
-	return (alpha >> 8) == 0xff;
-}
-
-static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
-			     struct vop2_alpha *alpha)
-{
-	int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
-	int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
-	int src_color_mode = alpha_config->src_premulti_en ?
-				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
-	int dst_color_mode = alpha_config->dst_premulti_en ?
-				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
-
-	alpha->src_color_ctrl.val = 0;
-	alpha->dst_color_ctrl.val = 0;
-	alpha->src_alpha_ctrl.val = 0;
-	alpha->dst_alpha_ctrl.val = 0;
-
-	if (!alpha_config->src_pixel_alpha_en)
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
-	else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
-	else
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
-
-	alpha->src_color_ctrl.bits.alpha_en = 1;
-
-	if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
-		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
-	} else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
-		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
-	} else {
-		alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
-	}
-	alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
-	alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-
-	alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-	alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
-	alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
-	alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
-	alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
-
-	alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
-	alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-	alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
-
-	alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
-		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
-	else
-		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
-	alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
-	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
-}
-
-static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
-{
-	struct vop2_video_port *vp;
-	int used_layer = 0;
-	int i;
-
-	for (i = 0; i < port_id; i++) {
-		vp = &vop2->vps[i];
-		used_layer += hweight32(vp->win_mask);
-	}
-
-	return used_layer;
-}
-
-static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
-{
-	struct vop2_alpha_config alpha_config;
-	struct vop2_alpha alpha;
-	struct drm_plane_state *bottom_win_pstate;
-	bool src_pixel_alpha_en = false;
-	u16 src_glb_alpha_val, dst_glb_alpha_val;
-	bool premulti_en = false;
-	bool swap = false;
-	u32 offset = 0;
-
-	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
-	bottom_win_pstate = main_win->base.state;
-	src_glb_alpha_val = 0;
-	dst_glb_alpha_val = main_win->base.state->alpha;
-
-	if (!bottom_win_pstate->fb)
-		return;
-
-	alpha_config.src_premulti_en = premulti_en;
-	alpha_config.dst_premulti_en = false;
-	alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
-	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
-	alpha_config.src_glb_alpha_value = src_glb_alpha_val;
-	alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
-	vop2_parse_alpha(&alpha_config, &alpha);
-
-	alpha.src_color_ctrl.bits.src_dst_swap = swap;
-
-	switch (main_win->data->phys_id) {
-	case ROCKCHIP_VOP2_CLUSTER0:
-		offset = 0x0;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER1:
-		offset = 0x10;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER2:
-		offset = 0x20;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER3:
-		offset = 0x30;
-		break;
-	}
-
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
-		    alpha.src_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
-		    alpha.dst_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
-		    alpha.src_alpha_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
-		    alpha.dst_alpha_ctrl.val);
-}
-
-static void vop2_setup_alpha(struct vop2_video_port *vp)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_framebuffer *fb;
-	struct vop2_alpha_config alpha_config;
-	struct vop2_alpha alpha;
-	struct drm_plane *plane;
-	int pixel_alpha_en;
-	int premulti_en, gpremulti_en = 0;
-	int mixer_id;
-	u32 offset;
-	bool bottom_layer_alpha_en = false;
-	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
-
-	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
-	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-
-		if (plane->state->normalized_zpos == 0 &&
-		    !is_opaque(plane->state->alpha) &&
-		    !vop2_cluster_window(win)) {
-			/*
-			 * If bottom layer have global alpha effect [except cluster layer,
-			 * because cluster have deal with bottom layer global alpha value
-			 * at cluster mix], bottom layer mix need deal with global alpha.
-			 */
-			bottom_layer_alpha_en = true;
-			dst_global_alpha = plane->state->alpha;
-		}
-	}
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-		int zpos = plane->state->normalized_zpos;
-
-		/*
-		 * Need to configure alpha from second layer.
-		 */
-		if (zpos == 0)
-			continue;
-
-		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
-			premulti_en = 1;
-		else
-			premulti_en = 0;
-
-		plane = &win->base;
-		fb = plane->state->fb;
-
-		pixel_alpha_en = fb->format->has_alpha;
-
-		alpha_config.src_premulti_en = premulti_en;
-
-		if (bottom_layer_alpha_en && zpos == 1) {
-			gpremulti_en = premulti_en;
-			/* Cd = Cs + (1 - As) * Cd * Agd */
-			alpha_config.dst_premulti_en = false;
-			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
-			alpha_config.src_glb_alpha_value = plane->state->alpha;
-			alpha_config.dst_glb_alpha_value = dst_global_alpha;
-		} else if (vop2_cluster_window(win)) {
-			/* Mix output data only have pixel alpha */
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = true;
-			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-		} else {
-			/* Cd = Cs + (1 - As) * Cd */
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
-			alpha_config.src_glb_alpha_value = plane->state->alpha;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-		}
-
-		vop2_parse_alpha(&alpha_config, &alpha);
-
-		offset = (mixer_id + zpos - 1) * 0x10;
-		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
-			    alpha.src_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
-			    alpha.dst_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
-			    alpha.src_alpha_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
-			    alpha.dst_alpha_ctrl.val);
-	}
-
-	if (vp->id == 0) {
-		if (bottom_layer_alpha_en) {
-			/* Transfer pixel alpha to hdr mix */
-			alpha_config.src_premulti_en = gpremulti_en;
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = true;
-			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			vop2_parse_alpha(&alpha_config, &alpha);
-
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
-				    alpha.src_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
-				    alpha.dst_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
-				    alpha.src_alpha_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
-				    alpha.dst_alpha_ctrl.val);
-		} else {
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
-		}
-	}
-}
-
-static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_plane *plane;
-	u32 layer_sel = 0;
-	u32 port_sel;
-	u8 layer_id;
-	u8 old_layer_id;
-	u8 layer_sel_id;
-	unsigned int ofs;
-	u32 ovl_ctrl;
-	int i;
-	struct vop2_video_port *vp0 = &vop2->vps[0];
-	struct vop2_video_port *vp1 = &vop2->vps[1];
-	struct vop2_video_port *vp2 = &vop2->vps[2];
-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
-
-	ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
-	ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
-	if (vcstate->yuv_overlay)
-		ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
-	else
-		ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
-
-	vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
-
-	port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
-	port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
-
-	if (vp0->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
-				     vp0->nlayers - 1);
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
-
-	if (vp1->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
-				     (vp0->nlayers + vp1->nlayers - 1));
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
-
-	if (vp2->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
-			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
-
-	layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
-
-	ofs = 0;
-	for (i = 0; i < vp->id; i++)
-		ofs += vop2->vps[i].nlayers;
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-		struct vop2_win *old_win;
-
-		layer_id = (u8)(plane->state->normalized_zpos + ofs);
-
-		/*
-		 * Find the layer this win bind in old state.
-		 */
-		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
-			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
-			if (layer_sel_id == win->data->layer_sel_id)
-				break;
-		}
-
-		/*
-		 * Find the win bind to this layer in old state
-		 */
-		for (i = 0; i < vop2->data->win_size; i++) {
-			old_win = &vop2->win[i];
-			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
-			if (layer_sel_id == old_win->data->layer_sel_id)
-				break;
-		}
-
-		switch (win->data->phys_id) {
-		case ROCKCHIP_VOP2_CLUSTER0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER2:
-			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER3:
-			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART2:
-			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART3:
-			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
-			break;
-		case ROCKCHIP_VOP2_SMART0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_SMART1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
-			break;
-		}
-
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
-		/*
-		 * When we bind a window from layerM to layerN, we also need to move the old
-		 * window on layerN to layerM to avoid one window selected by two or more layers.
-		 */
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
-	}
-
-	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-	vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
-}
-
-static void vop2_setup_dly_for_windows(struct vop2 *vop2)
-{
-	struct vop2_win *win;
-	int i = 0;
-	u32 cdly = 0, sdly = 0;
-
-	for (i = 0; i < vop2->data->win_size; i++) {
-		u32 dly;
-
-		win = &vop2->win[i];
-		dly = win->delay;
-
-		switch (win->data->phys_id) {
-		case ROCKCHIP_VOP2_CLUSTER0:
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER1:
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
-			break;
-		case ROCKCHIP_VOP2_ESMART0:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
-			break;
-		case ROCKCHIP_VOP2_ESMART1:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
-			break;
-		case ROCKCHIP_VOP2_SMART0:
-		case ROCKCHIP_VOP2_ESMART2:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
-			break;
-		case ROCKCHIP_VOP2_SMART1:
-		case ROCKCHIP_VOP2_ESMART3:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
-			break;
-		}
-	}
-
-	vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
-	vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
-}
-
 static void vop2_crtc_atomic_begin(struct drm_crtc *crtc,
 				   struct drm_atomic_state *state)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
 	struct vop2 *vop2 = vp->vop2;
-	struct drm_plane *plane;
-
-	vp->win_mask = 0;
-
-	drm_atomic_crtc_for_each_plane(plane, crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-
-		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
-
-		vp->win_mask |= BIT(win->data->phys_id);
 
-		if (vop2_cluster_window(win))
-			vop2_setup_cluster_alpha(vop2, win);
-	}
-
-	if (!vp->win_mask)
-		return;
-
-	vop2_setup_layer_mixer(vp);
-	vop2_setup_alpha(vp);
-	vop2_setup_dly_for_windows(vop2);
+	vop2->ops->setup_overlay(vp);
 }
 
 static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
@@ -3373,182 +2399,50 @@ static int vop2_find_rgb_encoder(struct vop2 *vop2)
 	return -ENOENT;
 }
 
-static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
-	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
-	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
-	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
-	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
-	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
-	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
-	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
-	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
-	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
-	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
-	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
-	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
-	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
-	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
-	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
-	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
-	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
-	/* RK3588 only, reserved bit on rk3568*/
-	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
-
-	/* Scale */
-	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
-	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
-	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
-	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
-	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
-	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
-	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
-
-	/* cluster regs */
-	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
-	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
-	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
-
-	/* afbc regs */
-	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
-	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
-	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
-	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
-	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
-	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
-	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
-	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
-	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
-	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
-	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
-	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
-	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
-	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
-	[VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
-	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
-	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
-	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
-	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
-};
-
 static int vop2_cluster_init(struct vop2_win *win)
 {
 	struct vop2 *vop2 = win->vop2;
 	struct reg_field *cluster_regs;
 	int ret, i;
 
-	cluster_regs = kmemdup(vop2_cluster_regs, sizeof(vop2_cluster_regs),
+	cluster_regs = kmemdup(vop2->data->cluster_reg,
+			       sizeof(struct reg_field) * vop2->data->nr_cluster_regs,
 			       GFP_KERNEL);
 	if (!cluster_regs)
 		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(vop2_cluster_regs); i++)
+	for (i = 0; i < vop2->data->nr_cluster_regs; i++)
 		if (cluster_regs[i].reg != 0xffffffff)
 			cluster_regs[i].reg += win->offset;
 
 	ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
 					   cluster_regs,
-					   ARRAY_SIZE(vop2_cluster_regs));
-
+					   vop2->data->nr_cluster_regs);
 	kfree(cluster_regs);
 
 	return ret;
 };
 
-static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
-	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
-	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
-	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
-	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
-	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
-	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
-	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
-	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
-	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
-	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
-	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
-	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
-	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
-	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
-	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
-	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
-	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
-	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
-	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
-	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
-	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
-	/* RK3588 only, reserved register on rk3568 */
-	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
-
-	/* Scale */
-	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
-	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
-	[VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
-	[VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
-	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
-	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
-	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
-	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
-	[VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
-	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
-	[VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
-	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
-	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
-	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
-	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
-	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
-	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
-	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
-	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
-};
-
 static int vop2_esmart_init(struct vop2_win *win)
 {
 	struct vop2 *vop2 = win->vop2;
-	struct reg_field *esmart_regs;
+	struct reg_field *smart_regs;
 	int ret, i;
 
-	esmart_regs = kmemdup(vop2_esmart_regs, sizeof(vop2_esmart_regs),
-			      GFP_KERNEL);
-	if (!esmart_regs)
+	smart_regs = kmemdup(vop2->data->smart_reg,
+			     sizeof(struct reg_field) * vop2->data->nr_smart_regs,
+			     GFP_KERNEL);
+	if (!smart_regs)
 		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(vop2_esmart_regs); i++)
-		if (esmart_regs[i].reg != 0xffffffff)
-			esmart_regs[i].reg += win->offset;
+	for (i = 0; i < vop2->data->nr_smart_regs; i++)
+		if (smart_regs[i].reg != 0xffffffff)
+			smart_regs[i].reg += win->offset;
 
 	ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
-					   esmart_regs,
-					   ARRAY_SIZE(vop2_esmart_regs));
-
-	kfree(esmart_regs);
+					   smart_regs,
+					   vop2->data->nr_smart_regs);
+	kfree(smart_regs);
 
 	return ret;
 };
@@ -3628,6 +2522,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 
 	vop2->dev = dev;
 	vop2->data = vop2_data;
+	vop2->ops = vop2_data->ops;
 	vop2->drm = drm;
 
 	dev_set_drvdata(dev, vop2);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 29cc7fb8f6d8..265bb5bfa27d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -9,6 +9,7 @@
 
 #include <linux/regmap.h>
 #include <drm/drm_modes.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
@@ -58,6 +59,23 @@ enum vop2_scale_down_mode {
 #define VOP2_PD_DSC_4K		BIT(6)
 #define VOP2_PD_ESMART		BIT(7)
 
+#define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
+					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
+
+#define vop2_output_if_is_dp(x)		((x) == ROCKCHIP_VOP2_EP_DP0 || \
+					 (x) == ROCKCHIP_VOP2_EP_DP1)
+
+#define vop2_output_if_is_edp(x)	((x) == ROCKCHIP_VOP2_EP_EDP0 || \
+					 (x) == ROCKCHIP_VOP2_EP_EDP1)
+
+#define vop2_output_if_is_mipi(x)	((x) == ROCKCHIP_VOP2_EP_MIPI0 || \
+					 (x) == ROCKCHIP_VOP2_EP_MIPI1)
+
+#define vop2_output_if_is_lvds(x)	((x) == ROCKCHIP_VOP2_EP_LVDS0 || \
+					 (x) == ROCKCHIP_VOP2_EP_LVDS1)
+
+#define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
+
 enum vop2_win_regs {
 	VOP2_WIN_ENABLE,
 	VOP2_WIN_FORMAT,
@@ -162,6 +180,23 @@ struct vop2_win_data {
 	const u8 dly[VOP2_DLY_MODE_MAX];
 };
 
+struct vop2_win {
+	struct vop2 *vop2;
+	struct drm_plane base;
+	const struct vop2_win_data *data;
+	struct regmap_field *reg[VOP2_WIN_MAX_REG];
+
+	/**
+	 * @win_id: graphic window id, a cluster may be split into two
+	 * graphics windows.
+	 */
+	u8 win_id;
+	u8 delay;
+	u32 offset;
+
+	enum drm_plane_type type;
+};
+
 struct vop2_video_port_data {
 	unsigned int id;
 	u32 feature;
@@ -172,20 +207,105 @@ struct vop2_video_port_data {
 	unsigned int offset;
 };
 
+struct vop2_video_port {
+	struct drm_crtc crtc;
+	struct vop2 *vop2;
+	struct clk *dclk;
+	unsigned int id;
+	const struct vop2_video_port_data *data;
+
+	struct completion dsp_hold_completion;
+
+	/**
+	 * @win_mask: Bitmask of windows attached to the video port;
+	 */
+	u32 win_mask;
+
+	struct vop2_win *primary_plane;
+	struct drm_pending_vblank_event *event;
+
+	unsigned int nlayers;
+};
+
+/**
+ * struct vop2_ops - helper operations for vop2 hardware
+ *
+ * These hooks are used by the common part of the vop2 driver to
+ * implement the proper behaviour of different variants.
+ */
+struct vop2_ops {
+	unsigned long (*setup_intf_mux)(struct vop2_video_port *vp, int ep_id, u32 polflags);
+	void (*setup_bg_dly)(struct vop2_video_port *vp);
+	void (*setup_overlay)(struct vop2_video_port *vp);
+};
+
 struct vop2_data {
 	u8 nr_vps;
 	u64 feature;
+	const struct vop2_ops *ops;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
+	const struct reg_field *cluster_reg;
+	const struct reg_field *smart_reg;
 	const struct vop2_regs_dump *regs_dump;
 	struct vop_rect max_input;
 	struct vop_rect max_output;
 
+	unsigned int nr_cluster_regs;
+	unsigned int nr_smart_regs;
 	unsigned int win_size;
 	unsigned int regs_dump_size;
 	unsigned int soc_id;
 };
 
+struct vop2 {
+	struct device *dev;
+	struct drm_device *drm;
+	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
+
+	const struct vop2_data *data;
+	const struct vop2_ops *ops;
+	/*
+	 * Number of windows that are registered as plane, may be less than the
+	 * total number of hardware windows.
+	 */
+	u32 registered_num_wins;
+
+	struct resource *res;
+	void __iomem *regs;
+	struct regmap *map;
+
+	struct regmap *sys_grf;
+	struct regmap *vop_grf;
+	struct regmap *vo1_grf;
+	struct regmap *sys_pmu;
+
+	/* physical map length of vop2 register */
+	u32 len;
+
+	void __iomem *lut_regs;
+
+	/* protects crtc enable/disable */
+	struct mutex vop2_lock;
+
+	int irq;
+
+	/*
+	 * Some global resources are shared between all video ports(crtcs), so
+	 * we need a ref counter here.
+	 */
+	unsigned int enable_count;
+	struct clk *hclk;
+	struct clk *aclk;
+	struct clk *pclk;
+
+	/* optional internal rgb encoder */
+	struct rockchip_rgb *rgb;
+
+	/* must be put at the end of the struct */
+	struct vop2_win win[];
+};
+
 /* interrupt define */
 #define FS_NEW_INTR			BIT(4)
 #define ADDR_SAME_INTR			BIT(5)
@@ -560,4 +680,52 @@ enum vop2_layer_phy_id {
 
 extern const struct component_ops vop2_component_ops;
 
+static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
+{
+	regmap_write(vop2->map, offset, v);
+}
+
+static inline void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
+{
+	regmap_write(vp->vop2->map, vp->data->offset + offset, v);
+}
+
+static inline u32 vop2_readl(struct vop2 *vop2, u32 offset)
+{
+	u32 val;
+
+	regmap_read(vop2->map, offset, &val);
+
+	return val;
+}
+
+static inline u32 vop2_vp_read(struct vop2_video_port *vp, u32 offset)
+{
+	u32 val;
+
+	regmap_read(vp->vop2->map, vp->data->offset + offset, &val);
+
+	return val;
+}
+
+static inline void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
+{
+	regmap_field_write(win->reg[reg], v);
+}
+
+static inline bool vop2_cluster_window(const struct vop2_win *win)
+{
+	return win->data->feature & WIN_FEATURE_CLUSTER;
+}
+
+static inline struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct vop2_video_port, crtc);
+}
+
+static inline struct vop2_win *to_vop2_win(struct drm_plane *p)
+{
+	return container_of(p, struct vop2_win, base);
+}
+
 #endif /* _ROCKCHIP_DRM_VOP2_H */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 65a88f489693..a2e0126a31a0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -9,12 +9,50 @@
 #include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
+#include <drm/drm_blend.h>
 #include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
 #include <drm/drm_plane.h>
 #include <drm/drm_print.h>
 
 #include "rockchip_drm_vop2.h"
 
+union vop2_alpha_ctrl {
+	u32 val;
+	struct {
+		/* [0:1] */
+		u32 color_mode:1;
+		u32 alpha_mode:1;
+		/* [2:3] */
+		u32 blend_mode:2;
+		u32 alpha_cal_mode:1;
+		/* [5:7] */
+		u32 factor_mode:3;
+		/* [8:9] */
+		u32 alpha_en:1;
+		u32 src_dst_swap:1;
+		u32 reserved:6;
+		/* [16:23] */
+		u32 glb_alpha:8;
+	} bits;
+};
+
+struct vop2_alpha {
+	union vop2_alpha_ctrl src_color_ctrl;
+	union vop2_alpha_ctrl dst_color_ctrl;
+	union vop2_alpha_ctrl src_alpha_ctrl;
+	union vop2_alpha_ctrl dst_alpha_ctrl;
+};
+
+struct vop2_alpha_config {
+	bool src_premulti_en;
+	bool dst_premulti_en;
+	bool src_pixel_alpha_en;
+	bool dst_pixel_alpha_en;
+	u16 src_glb_alpha_value;
+	u16 dst_glb_alpha_value;
+};
+
 static const uint32_t formats_cluster[] = {
 	DRM_FORMAT_XRGB2101010,
 	DRM_FORMAT_XBGR2101010,
@@ -131,6 +169,138 @@ static const uint64_t format_modifiers_afbc[] = {
 	DRM_FORMAT_MOD_INVALID,
 };
 
+static const struct reg_field rk3568_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
+	/* RK3588 only, reserved bit on rk3568*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
+
+	/* cluster regs */
+	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
+	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
+	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
+
+	/* afbc regs */
+	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
+	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
+	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
+	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
+	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
+	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
+	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
+	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
+	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
+	[VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
+};
+
+static const struct reg_field rk3568_vop_smart_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
+	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
+	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	/* RK3588 only, reserved register on rk3568 */
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
+	[VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
+	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
+	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
+	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
+};
+
 static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -647,6 +817,813 @@ static const struct vop2_regs_dump rk3588_regs_dump[] = {
 	},
 };
 
+static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	u32 die, dip;
+
+	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
+	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_RGB0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_RGB |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		if (polflags & POLFLAG_DCLK_INV)
+			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
+		else
+			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
+		break;
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_EDP |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI1:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_LVDS0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_LVDS1:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
+
+	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
+	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
+
+	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
+}
+
+/*
+ * calc the dclk on rk3588
+ * the available div of dclk is 1, 2, 4
+ */
+static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
+{
+	if (child_clk * 4 <= max_dclk)
+		return child_clk * 4;
+	else if (child_clk * 2 <= max_dclk)
+		return child_clk * 2;
+	else if (child_clk <= max_dclk)
+		return child_clk;
+	else
+		return 0;
+}
+
+/*
+ * 4 pixclk/cycle on rk3588
+ * RGB/eDP/HDMI: if_pixclk >= dclk_core
+ * DP: dp_pixclk = dclk_out <= dclk_core
+ * DSI: mipi_pixclk <= dclk_out <= dclk_core
+ */
+static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
+					 int *dclk_core_div, int *dclk_out_div,
+					 int *if_pixclk_div, int *if_dclk_div)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
+	int output_mode = vcstate->output_mode;
+	unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
+	unsigned long dclk_core_rate = v_pixclk >> 2;
+	unsigned long dclk_rate = v_pixclk;
+	unsigned long dclk_out_rate;
+	unsigned long if_pixclk_rate;
+	int K = 1;
+
+	if (vop2_output_if_is_hdmi(id)) {
+		/*
+		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
+		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
+		 */
+		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
+			dclk_rate = dclk_rate >> 1;
+			K = 2;
+		}
+
+		if_pixclk_rate = (dclk_core_rate << 1) / K;
+		/*
+		 * if_dclk_rate = dclk_core_rate / K;
+		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
+		 * *if_dclk_div = dclk_rate / if_dclk_rate;
+		 */
+		*if_pixclk_div = 2;
+		*if_dclk_div = 4;
+	} else if (vop2_output_if_is_edp(id)) {
+		/*
+		 * edp_pixclk = edp_dclk > dclk_core
+		 */
+		if_pixclk_rate = v_pixclk / K;
+		dclk_rate = if_pixclk_rate * K;
+		/*
+		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
+		 * *if_dclk_div = *if_pixclk_div;
+		 */
+		*if_pixclk_div = K;
+		*if_dclk_div = K;
+	} else if (vop2_output_if_is_dp(id)) {
+		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
+			dclk_out_rate = v_pixclk >> 3;
+		else
+			dclk_out_rate = v_pixclk >> 2;
+
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000);
+		if (!dclk_rate) {
+			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld KHZ\n",
+				dclk_out_rate);
+			return 0;
+		}
+		*dclk_out_div = dclk_rate / dclk_out_rate;
+	} else if (vop2_output_if_is_mipi(id)) {
+		if_pixclk_rate = dclk_core_rate / K;
+		/*
+		 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
+		 */
+		dclk_out_rate = if_pixclk_rate;
+		/*
+		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
+		 * we get a little factor here
+		 */
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000);
+		if (!dclk_rate) {
+			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld KHZ\n",
+				dclk_out_rate);
+			return 0;
+		}
+		*dclk_out_div = dclk_rate / dclk_out_rate;
+		/*
+		 * mipi pixclk == dclk_out
+		 */
+		*if_pixclk_div = 1;
+	} else if (vop2_output_if_is_dpi(id)) {
+		dclk_rate = v_pixclk;
+	}
+
+	*dclk_core_div = dclk_rate / dclk_core_rate;
+	*if_pixclk_div = ilog2(*if_pixclk_div);
+	*if_dclk_div = ilog2(*if_dclk_div);
+	*dclk_core_div = ilog2(*dclk_core_div);
+	*dclk_out_div = ilog2(*dclk_out_div);
+
+	drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
+		dclk_rate, *if_pixclk_div, *if_dclk_div);
+
+	return dclk_rate;
+}
+
+/*
+ * MIPI port mux on rk3588:
+ * 0: Video Port2
+ * 1: Video Port3
+ * 3: Video Port 1(MIPI1 only)
+ */
+static u32 rk3588_get_mipi_port_mux(int vp_id)
+{
+	if (vp_id == 1)
+		return 3;
+	else if (vp_id == 3)
+		return 1;
+	else
+		return 0;
+}
+
+static u32 rk3588_get_hdmi_pol(u32 flags)
+{
+	u32 val;
+
+	val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
+	val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
+
+	return val;
+}
+
+static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
+	unsigned long clock;
+	u32 die, dip, div, vp_clk_div, val;
+
+	clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
+				    &if_pixclk_div, &if_dclk_div);
+	if (!clock)
+		return 0;
+
+	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
+	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
+
+	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
+	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
+	div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
+			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
+		val = rk3588_get_hdmi_pol(polflags);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
+		break;
+	case ROCKCHIP_VOP2_EP_HDMI1:
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
+			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
+		val = rk3588_get_hdmi_pol(polflags);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
+		break;
+	case ROCKCHIP_VOP2_EP_EDP1:
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
+		val = rk3588_get_mipi_port_mux(vp->id);
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI1:
+		div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		val = rk3588_get_mipi_port_mux(vp->id);
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
+		break;
+	case ROCKCHIP_VOP2_EP_DP0:
+		die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
+		dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
+		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_DP1:
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
+		dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
+		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
+
+	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
+	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
+	vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
+	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
+
+	return clock;
+}
+
+static bool is_opaque(u16 alpha)
+{
+	return (alpha >> 8) == 0xff;
+}
+
+static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
+			     struct vop2_alpha *alpha)
+{
+	int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
+	int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
+	int src_color_mode = alpha_config->src_premulti_en ?
+				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
+	int dst_color_mode = alpha_config->dst_premulti_en ?
+				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
+
+	alpha->src_color_ctrl.val = 0;
+	alpha->dst_color_ctrl.val = 0;
+	alpha->src_alpha_ctrl.val = 0;
+	alpha->dst_alpha_ctrl.val = 0;
+
+	if (!alpha_config->src_pixel_alpha_en)
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
+	else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
+	else
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
+
+	alpha->src_color_ctrl.bits.alpha_en = 1;
+
+	if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
+		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
+	} else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
+		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
+	} else {
+		alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
+	}
+	alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
+	alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+
+	alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+	alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
+	alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
+	alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
+	alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
+
+	alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
+	alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+	alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
+
+	alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
+		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
+	else
+		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
+	alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
+	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
+}
+
+static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
+{
+	struct vop2_video_port *vp;
+	int used_layer = 0;
+	int i;
+
+	for (i = 0; i < port_id; i++) {
+		vp = &vop2->vps[i];
+		used_layer += hweight32(vp->win_mask);
+	}
+
+	return used_layer;
+}
+
+static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
+{
+	struct vop2_alpha_config alpha_config;
+	struct vop2_alpha alpha;
+	struct drm_plane_state *bottom_win_pstate;
+	bool src_pixel_alpha_en = false;
+	u16 src_glb_alpha_val, dst_glb_alpha_val;
+	u32 offset = 0;
+	bool premulti_en = false;
+	bool swap = false;
+
+	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
+	bottom_win_pstate = main_win->base.state;
+	src_glb_alpha_val = 0;
+	dst_glb_alpha_val = main_win->base.state->alpha;
+
+	if (!bottom_win_pstate->fb)
+		return;
+
+	alpha_config.src_premulti_en = premulti_en;
+	alpha_config.dst_premulti_en = false;
+	alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
+	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
+	alpha_config.src_glb_alpha_value = src_glb_alpha_val;
+	alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
+	vop2_parse_alpha(&alpha_config, &alpha);
+
+	alpha.src_color_ctrl.bits.src_dst_swap = swap;
+
+	switch (main_win->data->phys_id) {
+	case ROCKCHIP_VOP2_CLUSTER0:
+		offset = 0x0;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER1:
+		offset = 0x10;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER2:
+		offset = 0x20;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER3:
+		offset = 0x30;
+		break;
+	}
+
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
+		    alpha.src_color_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
+		    alpha.dst_color_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
+		    alpha.src_alpha_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
+		    alpha.dst_alpha_ctrl.val);
+}
+
+static void vop2_setup_alpha(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_framebuffer *fb;
+	struct vop2_alpha_config alpha_config;
+	struct vop2_alpha alpha;
+	struct drm_plane *plane;
+	int pixel_alpha_en;
+	int premulti_en, gpremulti_en = 0;
+	int mixer_id;
+	u32 offset;
+	bool bottom_layer_alpha_en = false;
+	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
+
+	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		if (plane->state->normalized_zpos == 0 &&
+		    !is_opaque(plane->state->alpha) &&
+		    !vop2_cluster_window(win)) {
+			/*
+			 * If bottom layer have global alpha effect [except cluster layer,
+			 * because cluster have deal with bottom layer global alpha value
+			 * at cluster mix], bottom layer mix need deal with global alpha.
+			 */
+			bottom_layer_alpha_en = true;
+			dst_global_alpha = plane->state->alpha;
+		}
+	}
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+		int zpos = plane->state->normalized_zpos;
+
+		/*
+		 * Need to configure alpha from second layer.
+		 */
+		if (zpos == 0)
+			continue;
+
+		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
+			premulti_en = 1;
+		else
+			premulti_en = 0;
+
+		plane = &win->base;
+		fb = plane->state->fb;
+
+		pixel_alpha_en = fb->format->has_alpha;
+
+		alpha_config.src_premulti_en = premulti_en;
+
+		if (bottom_layer_alpha_en && zpos == 1) {
+			gpremulti_en = premulti_en;
+			/* Cd = Cs + (1 - As) * Cd * Agd */
+			alpha_config.dst_premulti_en = false;
+			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
+			alpha_config.src_glb_alpha_value = plane->state->alpha;
+			alpha_config.dst_glb_alpha_value = dst_global_alpha;
+		} else if (vop2_cluster_window(win)) {
+			/* Mix output data only have pixel alpha */
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = true;
+			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+		} else {
+			/* Cd = Cs + (1 - As) * Cd */
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
+			alpha_config.src_glb_alpha_value = plane->state->alpha;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+		}
+
+		vop2_parse_alpha(&alpha_config, &alpha);
+
+		offset = (mixer_id + zpos - 1) * 0x10;
+		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
+			    alpha.src_color_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
+			    alpha.dst_color_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
+			    alpha.src_alpha_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
+			    alpha.dst_alpha_ctrl.val);
+	}
+
+	if (vp->id == 0) {
+		if (bottom_layer_alpha_en) {
+			/* Transfer pixel alpha to hdr mix */
+			alpha_config.src_premulti_en = gpremulti_en;
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = true;
+			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			vop2_parse_alpha(&alpha_config, &alpha);
+
+			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
+				    alpha.src_color_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
+				    alpha.dst_color_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
+				    alpha.src_alpha_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
+				    alpha.dst_alpha_ctrl.val);
+		} else {
+			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
+		}
+	}
+}
+
+static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_plane *plane;
+	u32 layer_sel = 0;
+	u32 port_sel;
+	u8 layer_id;
+	u8 old_layer_id;
+	u8 layer_sel_id;
+	unsigned int ofs;
+	u32 ovl_ctrl;
+	int i;
+	struct vop2_video_port *vp0 = &vop2->vps[0];
+	struct vop2_video_port *vp1 = &vop2->vps[1];
+	struct vop2_video_port *vp2 = &vop2->vps[2];
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
+
+	ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
+	ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
+	if (vcstate->yuv_overlay)
+		ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
+	else
+		ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
+
+	vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
+
+	port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
+	port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
+
+	if (vp0->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
+				     vp0->nlayers - 1);
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
+
+	if (vp1->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
+				     (vp0->nlayers + vp1->nlayers - 1));
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
+
+	if (vp2->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
+			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
+
+	layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
+
+	ofs = 0;
+	for (i = 0; i < vp->id; i++)
+		ofs += vop2->vps[i].nlayers;
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+		struct vop2_win *old_win;
+
+		layer_id = (u8)(plane->state->normalized_zpos + ofs);
+		/*
+		 * Find the layer this win bind in old state.
+		 */
+		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
+			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
+			if (layer_sel_id == win->data->layer_sel_id)
+				break;
+		}
+
+		/*
+		 * Find the win bind to this layer in old state
+		 */
+		for (i = 0; i < vop2->data->win_size; i++) {
+			old_win = &vop2->win[i];
+			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
+			if (layer_sel_id == old_win->data->layer_sel_id)
+				break;
+		}
+
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_CLUSTER0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER2:
+			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER3:
+			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART2:
+			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART3:
+			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
+			break;
+		case ROCKCHIP_VOP2_SMART0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_SMART1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
+			break;
+		}
+
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
+		/*
+		 * When we bind a window from layerM to layerN, we also need to move the old
+		 * window on layerN to layerM to avoid one window selected by two or more layers.
+		 */
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
+	}
+
+	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
+	vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
+}
+
+static void rk3568_vop2_setup_dly_for_windows(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct vop2_win *win;
+	int i = 0;
+	u32 cdly = 0, sdly = 0;
+
+	for (i = 0; i < vop2->data->win_size; i++) {
+		u32 dly;
+
+		win = &vop2->win[i];
+		dly = win->delay;
+
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_CLUSTER0:
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER1:
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
+			break;
+		case ROCKCHIP_VOP2_ESMART0:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
+			break;
+		case ROCKCHIP_VOP2_ESMART1:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
+			break;
+		case ROCKCHIP_VOP2_SMART0:
+		case ROCKCHIP_VOP2_ESMART2:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
+			break;
+		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART3:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
+			break;
+		}
+	}
+
+	vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
+	vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
+}
+
+static void rk3568_vop2_setup_overlay(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_plane *plane;
+
+	vp->win_mask = 0;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
+
+		vp->win_mask |= BIT(win->data->phys_id);
+
+		if (vop2_cluster_window(win))
+			vop2_setup_cluster_alpha(vop2, win);
+	}
+
+	if (!vp->win_mask)
+		return;
+
+	rk3568_vop2_setup_layer_mixer(vp);
+	vop2_setup_alpha(vp);
+	rk3568_vop2_setup_dly_for_windows(vp);
+}
+
+static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
+{
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	u16 hdisplay = mode->crtc_hdisplay;
+	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+	u32 bg_dly;
+	u32 pre_scan_dly;
+
+	bg_dly = vp->data->pre_scan_max_dly[3];
+	vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
+		    FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
+
+	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
+	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+}
+
+static const struct vop2_ops rk3568_vop_ops = {
+	.setup_intf_mux = rk3568_set_intf_mux,
+	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
+	.setup_overlay = rk3568_vop2_setup_overlay,
+};
+
+static const struct vop2_ops rk3588_vop_ops = {
+	.setup_intf_mux = rk3588_set_intf_mux,
+	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
+	.setup_overlay = rk3568_vop2_setup_overlay,
+};
+
 static const struct vop2_data rk3566_vop = {
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
@@ -655,8 +1632,13 @@ static const struct vop2_data rk3566_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3568_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
+	.ops = &rk3568_vop_ops,
 	.soc_id = 3566,
 };
 
@@ -668,8 +1650,13 @@ static const struct vop2_data rk3568_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3568_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
+	.ops = &rk3568_vop_ops,
 	.soc_id = 3568,
 };
 
@@ -682,8 +1669,13 @@ static const struct vop2_data rk3588_vop = {
 	.vp = rk3588_vop_video_ports,
 	.win = rk3588_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3588_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
+	.ops = &rk3588_vop_ops,
 	.soc_id = 3588,
 };
 
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:18:30 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:18:30 +0800
Subject: [PATCH v6 11/16] drm/rockchip: vop2: Introduce vop hardware version
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081831.3330714-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

There is a version number hardcoded in the VOP VERSION_INFO
register, and the version number increments sequentially based
on the production order of the SOC.

So using this version number to distinguish different VOP features
will simplify the code.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

Changes in v6:
- Add a blank line after hardware version check code

Changes in v3:
- Add comments for why we should treat rk3566 with special care.
- Add hardware version check

Changes in v2:
- Introduce vop hardware version

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 26 ++++++++++++++------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 11 +++++++++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c |  3 +++
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index fded1e931c9a..c87c98a8fb3a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -354,7 +354,7 @@ static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode)
 
 static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format)
 {
-	if (vop2->data->soc_id == 3588) {
+	if (vop2->version == VOP_VERSION_RK3588) {
 		if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
 		    bus_format == MEDIA_BUS_FMT_YUV10_1X30)
 			return true;
@@ -407,7 +407,7 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
 	if (modifier == DRM_FORMAT_MOD_INVALID)
 		return false;
 
-	if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
+	if (vop2->version == VOP_VERSION_RK3568) {
 		if (vop2_cluster_window(win)) {
 			if (modifier == DRM_FORMAT_MOD_LINEAR) {
 				drm_dbg_kms(vop2->drm,
@@ -418,7 +418,7 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
 	}
 
 	if (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010) {
-		if (vop2->data->soc_id == 3588) {
+		if (vop2->version == VOP_VERSION_RK3588) {
 			if (!rockchip_afbc(plane, modifier)) {
 				drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n");
 				return false;
@@ -817,6 +817,7 @@ static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
 static void vop2_enable(struct vop2 *vop2)
 {
 	int ret;
+	u32 version;
 
 	ret = pm_runtime_resume_and_get(vop2->dev);
 	if (ret < 0) {
@@ -836,10 +837,20 @@ static void vop2_enable(struct vop2 *vop2)
 		return;
 	}
 
+	version = vop2_readl(vop2, RK3568_VERSION_INFO);
+	if (version != vop2->version) {
+		drm_err(vop2->drm, "Hardware version(0x%08x) mismatch\n", version);
+		return;
+	}
+
+	/*
+	 * rk3566 share the same vop version with rk3568, so
+	 * wen need to use soc_id for identification here.
+	 */
 	if (vop2->data->soc_id == 3566)
 		vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
 
-	if (vop2->data->soc_id == 3588)
+	if (vop2->version == VOP_VERSION_RK3588)
 		rk3588_vop2_power_domain_enable_all(vop2);
 
 	vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
@@ -920,7 +931,7 @@ static void vop2_vp_dsp_lut_update_enable(struct vop2_video_port *vp)
 
 static inline bool vop2_supports_seamless_gamma_lut_update(struct vop2 *vop2)
 {
-	return (vop2->data->soc_id != 3566 && vop2->data->soc_id != 3568);
+	return vop2->version != VOP_VERSION_RK3568;
 }
 
 static bool vop2_gamma_lut_in_use(struct vop2 *vop2, struct vop2_video_port *vp)
@@ -1259,7 +1270,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		&fb->format->format,
 		afbc_en ? "AFBC" : "", &yrgb_mst);
 
-	if (vop2->data->soc_id > 3568) {
+	if (vop2->version > VOP_VERSION_RK3568) {
 		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
 		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
 		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
@@ -1319,7 +1330,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		 * this bit is gating disable, we should write 1 to
 		 * disable gating when enable afbc.
 		 */
-		if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568)
+		if (vop2->version == VOP_VERSION_RK3568)
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0);
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1);
@@ -2523,6 +2534,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 	vop2->dev = dev;
 	vop2->data = vop2_data;
 	vop2->ops = vop2_data->ops;
+	vop2->version = vop2_data->version;
 	vop2->drm = drm;
 
 	dev_set_drvdata(dev, vop2);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index af3cd92e6815..21464d107bd3 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -13,6 +13,15 @@
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
+#define VOP2_VERSION(major, minor, build)	((major) << 24 | (minor) << 16 | (build))
+
+/* The new SOC VOP version is bigger than the old */
+#define VOP_VERSION_RK3568	VOP2_VERSION(0x40, 0x15, 0x8023)
+#define VOP_VERSION_RK3588	VOP2_VERSION(0x40, 0x17, 0x6786)
+#define VOP_VERSION_RK3528	VOP2_VERSION(0x50, 0x17, 0x1263)
+#define VOP_VERSION_RK3562	VOP2_VERSION(0x50, 0x17, 0x4350)
+#define VOP_VERSION_RK3576	VOP2_VERSION(0x50, 0x19, 0x9765)
+
 #define VOP2_VP_FEATURE_OUTPUT_10BIT        BIT(0)
 
 #define VOP2_FEATURE_HAS_SYS_GRF	BIT(0)
@@ -242,6 +251,7 @@ struct vop2_ops {
 struct vop2_data {
 	u8 nr_vps;
 	u64 feature;
+	u32 version;
 	const struct vop2_ops *ops;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
@@ -259,6 +269,7 @@ struct vop2_data {
 };
 
 struct vop2 {
+	u32 version;
 	struct device *dev;
 	struct drm_device *drm;
 	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 01336ef2482a..e311af7e3a1a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -1627,6 +1627,7 @@ static const struct vop2_ops rk3588_vop_ops = {
 };
 
 static const struct vop2_data rk3566_vop = {
+	.version = VOP_VERSION_RK3568,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
 	.max_input = { 4096, 2304 },
@@ -1645,6 +1646,7 @@ static const struct vop2_data rk3566_vop = {
 };
 
 static const struct vop2_data rk3568_vop = {
+	.version = VOP_VERSION_RK3568,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
 	.max_input = { 4096, 2304 },
@@ -1663,6 +1665,7 @@ static const struct vop2_data rk3568_vop = {
 };
 
 static const struct vop2_data rk3588_vop = {
+	.version = VOP_VERSION_RK3588,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
 		   VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU,
 	.nr_vps = 4,
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:01 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:01 +0800
Subject: [PATCH v6 02/16] drm/rockchip: vop2: Fix the windows switch between different layers
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-3-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Every layer of vop2 should bind a window, and we also need to make
sure that this window is not used by other layer.

0x5 is a reserved layer sel value on rk3568, but it will select
Cluster3 on rk3588, configure unused layers to 0x5  will lead
alpha blending error on rk3588.

When we bind a window from layerM to layerN, we move the old window
on layerN to layerM.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Tested-by: Derek Foreman <derek.foreman at collabora.com>
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>

---

Changes in v6:
- Limit line length not exceeds 100

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 47 ++++++++++++++------
 1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 698e40cea3fa..81207a79530c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2541,7 +2541,10 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
 	struct drm_plane *plane;
 	u32 layer_sel = 0;
 	u32 port_sel;
-	unsigned int nlayer, ofs;
+	u8 layer_id;
+	u8 old_layer_id;
+	u8 layer_sel_id;
+	unsigned int ofs;
 	u32 ovl_ctrl;
 	int i;
 	struct vop2_video_port *vp0 = &vop2->vps[0];
@@ -2585,9 +2588,30 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
 	for (i = 0; i < vp->id; i++)
 		ofs += vop2->vps[i].nlayers;
 
-	nlayer = 0;
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
 		struct vop2_win *win = to_vop2_win(plane);
+		struct vop2_win *old_win;
+
+		layer_id = (u8)(plane->state->normalized_zpos + ofs);
+
+		/*
+		 * Find the layer this win bind in old state.
+		 */
+		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
+			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
+			if (layer_sel_id == win->data->layer_sel_id)
+				break;
+		}
+
+		/*
+		 * Find the win bind to this layer in old state
+		 */
+		for (i = 0; i < vop2->data->win_size; i++) {
+			old_win = &vop2->win[i];
+			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
+			if (layer_sel_id == old_win->data->layer_sel_id)
+				break;
+		}
 
 		switch (win->data->phys_id) {
 		case ROCKCHIP_VOP2_CLUSTER0:
@@ -2632,17 +2656,14 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
 			break;
 		}
 
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
-							  0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
-							 win->data->layer_sel_id);
-		nlayer++;
-	}
-
-	/* configure unused layers to 0x5 (reserved) */
-	for (; nlayer < vp->nlayers; nlayer++) {
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 5);
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
+		/*
+		 * When we bind a window from layerM to layerN, we also need to move the old
+		 * window on layerN to layerM to avoid one window selected by two or more layers.
+		 */
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
 	}
 
 	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:03 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:03 +0800
Subject: [PATCH v6 04/16] drm/rockchip: vop2: Setup delay cycle for Esmart2/3
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-5-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Each layer needs to set the correct delay cycle to display properly
without unexpected offset on screen.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Derek Foreman <derek.foreman at collabora.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0723a7606cb1..f143df2b13a1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2704,9 +2704,11 @@ static void vop2_setup_dly_for_windows(struct vop2 *vop2)
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART0:
+		case ROCKCHIP_VOP2_ESMART2:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART3:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
 			break;
 		}
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:00 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:00 +0800
Subject: [PATCH v6 01/16] drm/rockchip: vop2: Add debugfs support
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-2-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

/sys/kernel/debug/dri/vop2/summary:  dump vop display state
/sys/kernel/debug/dri/vop2/regs: dump whole vop registers
/sys/kernel/debug/dri/vop2/active_regs: only dump the registers of
activated modules

Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

Changes in v6:
- Remove an unnecessary blank line.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 259 +++++++++++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  11 +
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 191 ++++++++++++++
 3 files changed, 461 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 2d5e2e298b86..698e40cea3fa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -24,9 +24,11 @@
 #include <drm/drm_atomic_uapi.h>
 #include <drm/drm_blend.h>
 #include <drm/drm_crtc.h>
+#include <linux/debugfs.h>
 #include <drm/drm_debugfs.h>
 #include <drm/drm_flip_work.h>
 #include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
@@ -186,6 +188,7 @@ struct vop2 {
 	 */
 	u32 registered_num_wins;
 
+	struct resource *res;
 	void __iomem *regs;
 	struct regmap *map;
 
@@ -237,6 +240,37 @@ struct vop2 {
 
 #define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
 
+
+/*
+ * bus-format types.
+ */
+struct drm_bus_format_enum_list {
+	int type;
+	const char *name;
+};
+
+static const struct drm_bus_format_enum_list drm_bus_format_enum_list[] = {
+	{ DRM_MODE_CONNECTOR_Unknown, "Unknown" },
+	{ MEDIA_BUS_FMT_RGB565_1X16, "RGB565_1X16" },
+	{ MEDIA_BUS_FMT_RGB666_1X18, "RGB666_1X18" },
+	{ MEDIA_BUS_FMT_RGB666_1X24_CPADHI, "RGB666_1X24_CPADHI" },
+	{ MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, "RGB666_1X7X3_SPWG" },
+	{ MEDIA_BUS_FMT_YUV8_1X24, "YUV8_1X24" },
+	{ MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
+	{ MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
+	{ MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
+	{ MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
+	{ MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
+	{ MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, "RGB888_1X7X4_SPWG" },
+	{ MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, "RGB888_1X7X4_JEIDA" },
+	{ MEDIA_BUS_FMT_UYVY8_2X8, "UYVY8_2X8" },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, "YUYV8_1X16" },
+	{ MEDIA_BUS_FMT_UYVY8_1X16, "UYVY8_1X16" },
+	{ MEDIA_BUS_FMT_RGB101010_1X30, "RGB101010_1X30" },
+	{ MEDIA_BUS_FMT_YUYV10_1X20, "YUYV10_1X20" },
+};
+static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
+
 static const struct regmap_config vop2_regmap_config;
 
 static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
@@ -2718,6 +2752,229 @@ static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
 	.atomic_disable = vop2_crtc_atomic_disable,
 };
 
+static void vop2_dump_connector_on_crtc(struct drm_crtc *crtc, struct seq_file *s)
+{
+	struct drm_connector_list_iter conn_iter;
+	struct drm_connector *connector;
+
+	drm_connector_list_iter_begin(crtc->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
+		if (crtc->state->connector_mask & drm_connector_mask(connector))
+			seq_printf(s, "    Connector: %s\n", connector->name);
+
+	}
+	drm_connector_list_iter_end(&conn_iter);
+}
+
+static int vop2_plane_state_dump(struct seq_file *s, struct drm_plane *plane)
+{
+	struct vop2_win *win = to_vop2_win(plane);
+	struct drm_plane_state *pstate = plane->state;
+	struct drm_rect *src, *dst;
+	struct drm_framebuffer *fb;
+	struct drm_gem_object *obj;
+	struct rockchip_gem_object *rk_obj;
+	bool xmirror;
+	bool ymirror;
+	bool rotate_270;
+	bool rotate_90;
+	dma_addr_t fb_addr;
+	int i;
+
+	seq_printf(s, "    %s: %s\n", win->data->name, !pstate ?
+		   "DISABLED" : pstate->crtc ? "ACTIVE" : "DISABLED");
+
+	if (!pstate || !pstate->fb)
+		return 0;
+
+	fb = pstate->fb;
+	src = &pstate->src;
+	dst = &pstate->dst;
+	xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
+	ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
+	rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
+	rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
+
+	seq_printf(s, "\twin_id: %d\n", win->win_id);
+
+	seq_printf(s, "\tformat: %p4cc%s glb_alpha[0x%x]\n",
+		   &fb->format->format,
+		   drm_is_afbc(fb->modifier) ? "[AFBC]" : "",
+		   pstate->alpha >> 8);
+	seq_printf(s, "\trotate: xmirror: %d ymirror: %d rotate_90: %d rotate_270: %d\n",
+		   xmirror, ymirror, rotate_90, rotate_270);
+	seq_printf(s, "\tzpos: %d\n", pstate->normalized_zpos);
+	seq_printf(s, "\tsrc: pos[%d, %d] rect[%d x %d]\n", src->x1 >> 16,
+		   src->y1 >> 16, drm_rect_width(src) >> 16,
+		   drm_rect_height(src) >> 16);
+	seq_printf(s, "\tdst: pos[%d, %d] rect[%d x %d]\n", dst->x1, dst->y1,
+		   drm_rect_width(dst), drm_rect_height(dst));
+
+	for (i = 0; i < fb->format->num_planes; i++) {
+		obj = fb->obj[i];
+		rk_obj = to_rockchip_obj(obj);
+		fb_addr = rk_obj->dma_addr + fb->offsets[i];
+
+		seq_printf(s, "\tbuf[%d]: addr: %pad pitch: %d offset: %d\n",
+			   i, &fb_addr, fb->pitches[i], fb->offsets[i]);
+	}
+
+	return 0;
+}
+
+static int vop2_crtc_state_dump(struct drm_crtc *crtc, struct seq_file *s)
+{
+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct drm_crtc_state *cstate = crtc->state;
+	struct rockchip_crtc_state *vcstate;
+	struct drm_display_mode *mode;
+	struct drm_plane *plane;
+	bool interlaced;
+
+	seq_printf(s, "Video Port%d: %s\n", vp->id, !cstate ?
+		   "DISABLED" : cstate->active ? "ACTIVE" : "DISABLED");
+
+	if (!cstate || !cstate->active)
+		return 0;
+
+	mode = &crtc->state->adjusted_mode;
+	vcstate = to_rockchip_crtc_state(cstate);
+	interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+
+	vop2_dump_connector_on_crtc(crtc, s);
+	seq_printf(s, "\tbus_format[%x]: %s\n", vcstate->bus_format,
+		    drm_get_bus_format_name(vcstate->bus_format));
+	seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode);
+	seq_printf(s, " color_space[%d]\n", vcstate->color_space);
+	seq_printf(s, "    Display mode: %dx%d%s%d\n",
+		    mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
+		    drm_mode_vrefresh(mode));
+	seq_printf(s, "\tclk[%d] real_clk[%d] type[%x] flag[%x]\n",
+		    mode->clock, mode->crtc_clock, mode->type, mode->flags);
+	seq_printf(s, "\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
+		    mode->hsync_end, mode->htotal);
+	seq_printf(s, "\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
+		    mode->vsync_end, mode->vtotal);
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		vop2_plane_state_dump(s, plane);
+	}
+
+	return 0;
+}
+
+static int vop2_summary_show(struct seq_file *s, void *data)
+{
+	struct drm_info_node *node = s->private;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *drm_dev = minor->dev;
+	struct drm_crtc *crtc;
+
+	drm_modeset_lock_all(drm_dev);
+	drm_for_each_crtc(crtc, drm_dev) {
+		vop2_crtc_state_dump(crtc, s);
+	}
+	drm_modeset_unlock_all(drm_dev);
+
+	return 0;
+}
+
+static void vop2_regs_print(struct vop2 *vop2, struct seq_file *s,
+			    const struct vop2_regs_dump *dump, bool active_only)
+{
+	resource_size_t start;
+	u32 val;
+	int i;
+
+	if (dump->en_mask && active_only) {
+		val = vop2_readl(vop2, dump->base + dump->en_reg);
+		if ((val & dump->en_mask) != dump->en_val)
+			return;
+	}
+
+	seq_printf(s, "\n%s:\n", dump->name);
+
+	start = vop2->res->start + dump->base;
+	for (i = 0; i < dump->size >> 2; i += 4) {
+		seq_printf(s, "%08x:  %08x %08x %08x %08x\n", (u32)start + i * 4,
+			   vop2_readl(vop2, dump->base + (4 * i)),
+			   vop2_readl(vop2, dump->base + (4 * (i + 1))),
+			   vop2_readl(vop2, dump->base + (4 * (i + 2))),
+			   vop2_readl(vop2, dump->base + (4 * (i + 3))));
+	}
+}
+
+static void __vop2_regs_dump(struct seq_file *s, bool active_only)
+{
+	struct drm_info_node *node = s->private;
+	struct vop2 *vop2 = node->info_ent->data;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *drm_dev = minor->dev;
+	const struct vop2_regs_dump *dump;
+	unsigned int i;
+
+	drm_modeset_lock_all(drm_dev);
+
+	regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
+
+	if (vop2->enable_count) {
+		for (i = 0; i < vop2->data->regs_dump_size; i++) {
+			dump = &vop2->data->regs_dump[i];
+			vop2_regs_print(vop2, s, dump, active_only);
+		}
+	} else {
+		seq_printf(s, "VOP disabled\n");
+	}
+	drm_modeset_unlock_all(drm_dev);
+}
+
+static int vop2_regs_show(struct seq_file *s, void *arg)
+{
+	__vop2_regs_dump(s, false);
+
+	return 0;
+}
+
+static int vop2_active_regs_show(struct seq_file *s, void *data)
+{
+	__vop2_regs_dump(s, true);
+
+	return 0;
+}
+
+static struct drm_info_list vop2_debugfs_list[] = {
+	{ "summary", vop2_summary_show, 0, NULL },
+	{ "active_regs", vop2_active_regs_show,   0, NULL },
+	{ "regs", vop2_regs_show,   0, NULL },
+};
+
+static void vop2_debugfs_init(struct vop2 *vop2, struct drm_minor *minor)
+{
+	struct dentry *root;
+	unsigned int i;
+
+	root = debugfs_create_dir("vop2", minor->debugfs_root);
+	if (!IS_ERR(root)) {
+		for (i = 0; i < ARRAY_SIZE(vop2_debugfs_list); i++)
+			vop2_debugfs_list[i].data = vop2;
+
+		drm_debugfs_create_files(vop2_debugfs_list,
+					 ARRAY_SIZE(vop2_debugfs_list),
+					 root, minor);
+	}
+}
+
+static int vop2_crtc_late_register(struct drm_crtc *crtc)
+{
+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct vop2 *vop2 = vp->vop2;
+
+	if (drm_crtc_index(crtc) == 0)
+		vop2_debugfs_init(vop2, crtc->dev->primary);
+
+	return 0;
+}
+
 static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc)
 {
 	struct rockchip_crtc_state *vcstate;
@@ -2767,6 +3024,7 @@ static const struct drm_crtc_funcs vop2_crtc_funcs = {
 	.atomic_destroy_state = vop2_crtc_destroy_state,
 	.enable_vblank = vop2_crtc_enable_vblank,
 	.disable_vblank = vop2_crtc_disable_vblank,
+	.late_register = vop2_crtc_late_register,
 };
 
 static irqreturn_t vop2_isr(int irq, void *data)
@@ -3316,6 +3574,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 		return -EINVAL;
 	}
 
+	vop2->res = res;
 	vop2->regs = devm_ioremap_resource(dev, res);
 	if (IS_ERR(vop2->regs))
 		return PTR_ERR(vop2->regs);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 22c43a50caf0..2cb7b6b40c77 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -122,6 +122,15 @@ enum vop2_win_regs {
 	VOP2_WIN_MAX_REG,
 };
 
+struct vop2_regs_dump {
+	const char *name;
+	u32 base;
+	u32 size;
+	u32 en_reg;
+	u32 en_val;
+	u32 en_mask;
+};
+
 struct vop2_win_data {
 	const char *name;
 	unsigned int phys_id;
@@ -160,10 +169,12 @@ struct vop2_data {
 	u64 feature;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
+	const struct vop2_regs_dump *regs_dump;
 	struct vop_rect max_input;
 	struct vop_rect max_output;
 
 	unsigned int win_size;
+	unsigned int regs_dump_size;
 	unsigned int soc_id;
 };
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 008b70fbc33a..9247f94343f2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -258,6 +258,88 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	},
 };
 
+static const struct vop2_regs_dump rk3568_regs_dump[] = {
+	{
+		.name = "SYS",
+		.base = RK3568_REG_CFG_DONE,
+		.size = 0x100,
+		.en_reg  = 0,
+		.en_val = 0,
+		.en_mask = 0
+	}, {
+		.name = "OVL",
+		.base = RK3568_OVL_CTRL,
+		.size = 0x100,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "VP0",
+		.base = RK3568_VP0_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP1",
+		.base = RK3568_VP1_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP2",
+		.base = RK3568_VP2_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+
+	}, {
+		.name = "Cluster0",
+		.base = RK3568_CLUSTER0_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster1",
+		.base = RK3568_CLUSTER1_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Esmart0",
+		.base = RK3568_ESMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart1",
+		.base = RK3568_ESMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart0",
+		.base = RK3568_SMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart1",
+		.base = RK3568_SMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	},
+};
+
 static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -438,6 +520,109 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	},
 };
 
+static const struct vop2_regs_dump rk3588_regs_dump[] = {
+	{
+		.name = "SYS",
+		.base = RK3568_REG_CFG_DONE,
+		.size = 0x100,
+		.en_reg  = 0,
+		.en_val = 0,
+		.en_mask = 0
+	}, {
+		.name = "OVL",
+		.base = RK3568_OVL_CTRL,
+		.size = 0x100,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "VP0",
+		.base = RK3568_VP0_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP1",
+		.base = RK3568_VP1_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP2",
+		.base = RK3568_VP2_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+
+	}, {
+		.name = "VP3",
+		.base = RK3588_VP3_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "Cluster0",
+		.base = RK3568_CLUSTER0_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster1",
+		.base = RK3568_CLUSTER1_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster2",
+		.base = RK3588_CLUSTER2_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster3",
+		.base = RK3588_CLUSTER3_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Esmart0",
+		.base = RK3568_ESMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart1",
+		.base = RK3568_ESMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart2",
+		.base = RK3588_ESMART2_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart3",
+		.base = RK3588_ESMART3_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	},
+};
+
 static const struct vop2_data rk3566_vop = {
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
@@ -446,6 +631,8 @@ static const struct vop2_data rk3566_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.regs_dump = rk3568_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
 	.soc_id = 3566,
 };
 
@@ -457,6 +644,8 @@ static const struct vop2_data rk3568_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.regs_dump = rk3568_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
 	.soc_id = 3568,
 };
 
@@ -469,6 +658,8 @@ static const struct vop2_data rk3588_vop = {
 	.vp = rk3588_vop_video_ports,
 	.win = rk3588_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
+	.regs_dump = rk3588_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
 	.soc_id = 3588,
 };
 
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:05 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:05 +0800
Subject: [PATCH v6 06/16] drm/rockchip: vop2: Add check for 32 bpp format for rk3588
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-7-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

RK3588 only support DRM_FORMAT_XRGB2101010/XBGR2101010 in afbc mode.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>

---

Changes in v6:
- Move 32 bpp check to format_mod_supported() hook

Changes in v5:
- Added in V5

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 94f77faf14d1..85d281edfbfe 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -603,6 +603,15 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
 		}
 	}
 
+	if (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010) {
+		if (vop2->data->soc_id == 3588) {
+			if (!rockchip_afbc(plane, modifier)) {
+				drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n");
+				return false;
+			}
+		}
+	}
+
 	if (modifier == DRM_FORMAT_MOD_LINEAR)
 		return true;
 
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:16:59 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:16:59 +0800
Subject: [PATCH v6 00/16] VOP Support for rk3576
Message-ID: <20241214081719.3330518-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>


Thanks for the basic work from Collabora, I can bringup a HDMI
display out on rk3576.

PATCH 1 is a carryover from the working when add support for
    rk3588[0], is very usefull when some people want me
    help debug some issue online, so I really hope it can
    be merged at this round.
PATCH 2~8 are bugfix of rk3588 alpha blending which report and
    test by Derek
PATCH 9~13 are preparations for rk3576 support
PATCH 17~18 are real support for rk376

I test it with a 1080P/4K HDMI output with modetest and weston
output.

If there are some one want to have a try, I have a tree based on
Linux 6.13-rc2 here[1]

[0]https://patchwork.kernel.org/project/linux-rockchip/cover/20231211115547.1784587-1-andyshrk at 163.com/
[1]https://github.com/andyshrk/linux/tree/rk3576-vop2-upstream-v5

Changes in v6:
- Remove unnecessary blank line.
- Limit line length not exceeds 100
- Move the linear check to format_mod_supported() hook
- Move 32 bpp check to format_mod_supported() hook
- Add a blank line after hardware version check code
-  More specific explanation about the AXI_BUS_ID register bit of
   cluster window.
- Collect Tested-by

Changes in v5:
- Added in V5
- Added in V5
- Added in V5
- Add axi id configuration
- Remove the non-existent CBCR scale register.

Changes in v4:
- Typo fix: selet->select

Changes in v3:
- Split it from 10/15, as it fix a exiting compile warning.
- Add comments for why we should treat rk3566 with special care.
- Add hardware version check
- Add comments for why we should treat rk3566 with special care.
- ordered by soc name
- Add description for newly added interrupt
- Share the alpha setup function with rk3568
- recoder the code block by soc

Changes in v2:
- split it from main patch add support for rk3576
- Add platform specific callback
- Introduce vop hardware version
- Add dt bindings
- Add platform specific callback

Andy Yan (15):
  drm/rockchip: vop2: Add debugfs support
  drm/rockchip: vop2: Fix the windows switch between different layers
  drm/rockchip: vop2: Set AXI id for rk3588
  drm/rockchip: vop2: Setup delay cycle for Esmart2/3
  drm/rockchip: vop2: Check linear format for Cluster windows on
    rk3566/8
  drm/rockchip: vop2: Add check for 32 bpp format for rk3588
  drm/rockchip: vop2: Support 32x8 superblock afbc
  drm/rockchip: vop2: Add platform specific callback
  drm/rockchip: vop2: Support for different layer select configuration
    between VPs
  drm/rockchip: vop2: Introduce vop hardware version
  drm/rockchip: vop2: Register the primary plane and overlay plane
    separately
  drm/rockchip: vop2: Set plane possible crtcs by possible vp mask
  drm/rockchip: vop2: Add uv swap for cluster window
  dt-bindings: display: vop2: Add rk3576 support
  drm/rockchip: vop2: Add support for rk3576

Min-Hua Chen (1):
  drm/rockchip: vop2: include rockchip_drm_drv.h

 .../display/rockchip/rockchip-vop2.yaml       |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  | 1638 ++++----------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h  |  292 ++-
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c  | 2014 ++++++++++++++++-
 4 files changed, 2793 insertions(+), 1164 deletions(-)

-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:07 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:07 +0800
Subject: [PATCH v6 08/16] drm/rockchip: vop2: Support 32x8 superblock afbc
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-9-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

This is the only afbc format supported by the upcoming
VOP for rk3576.

Add support for it.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v2)

Changes in v2:
- split it from main patch add support for rk3576

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index b5f35839d5e8..efe7d0cbe155 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1454,16 +1454,18 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
 	if (afbc_en) {
-		u32 stride;
+		u32 stride, block_w;
+
+		/* the afbc superblock is 16 x 16 or 32 x 8 */
+		block_w = fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ? 32 : 16;
 
-		/* the afbc superblock is 16 x 16 */
 		afbc_format = vop2_convert_afbc_format(fb->format->format);
 
 		/* Enable color transform for YTR */
 		if (fb->modifier & AFBC_FORMAT_MOD_YTR)
 			afbc_format |= (1 << 4);
 
-		afbc_tile_num = ALIGN(actual_w, 16) >> 4;
+		afbc_tile_num = ALIGN(actual_w, block_w) / block_w;
 
 		/*
 		 * AFBC pic_vir_width is count by pixel, this is different
@@ -1474,6 +1476,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 			drm_dbg_kms(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n",
 				    vp->id, win->data->name, stride);
 
+		 /* It's for head stride, each head size is 16 byte */
+		stride = ALIGN(stride, block_w) / block_w * 16;
+
 		uv_swap = vop2_afbc_uv_swap(fb->format->format);
 		/*
 		 * This is a workaround for crazy IC design, Cluster
@@ -1504,7 +1509,11 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1);
 
-		vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
+		if (fb->modifier & AFBC_FORMAT_MOD_SPLIT)
+			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 1);
+		else
+			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
+
 		transform_offset = vop2_afbc_transform_offset(pstate, half_block_en);
 		vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
 		vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:02 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:02 +0800
Subject: [PATCH v6 03/16] drm/rockchip: vop2: Set AXI id for rk3588
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-4-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

There are two AXI bus in vop2, windows attached on the same bus must
have a unique channel YUV and RGB channel ID.

The default IDs will conflict with each other on the rk3588, so they
need to be reassigned.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Derek Foreman <derek.foreman at collabora.com>
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v5)

Changes in v5:
- Added in V5

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 14 +++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  9 +++++++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 26 +++++++++++++++++++-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 81207a79530c..0723a7606cb1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1426,6 +1426,12 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		&fb->format->format,
 		afbc_en ? "AFBC" : "", &yrgb_mst);
 
+	if (vop2->data->soc_id > 3568) {
+		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
+		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
+		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
+	}
+
 	if (vop2_cluster_window(win))
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
@@ -3354,6 +3360,10 @@ static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
 	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
 	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
+	/* RK3588 only, reserved bit on rk3568*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
 
 	/* Scale */
 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
@@ -3446,6 +3456,10 @@ static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
 	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
 	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	/* RK3588 only, reserved register on rk3568 */
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
 
 	/* Scale */
 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 2cb7b6b40c77..f4724a402ac2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -78,6 +78,9 @@ enum vop2_win_regs {
 	VOP2_WIN_COLOR_KEY,
 	VOP2_WIN_COLOR_KEY_EN,
 	VOP2_WIN_DITHER_UP,
+	VOP2_WIN_AXI_BUS_ID,
+	VOP2_WIN_AXI_YRGB_R_ID,
+	VOP2_WIN_AXI_UV_R_ID,
 
 	/* scale regs */
 	VOP2_WIN_SCALE_YRGB_X,
@@ -149,6 +152,10 @@ struct vop2_win_data {
 	unsigned int layer_sel_id;
 	uint64_t feature;
 
+	uint8_t axi_bus_id;
+	uint8_t axi_yrgb_r_id;
+	uint8_t axi_uv_r_id;
+
 	unsigned int max_upscale_factor;
 	unsigned int max_downscale_factor;
 	const u8 dly[VOP2_DLY_MODE_MAX];
@@ -319,6 +326,7 @@ enum dst_factor_mode {
 
 #define RK3568_CLUSTER_WIN_CTRL0		0x00
 #define RK3568_CLUSTER_WIN_CTRL1		0x04
+#define RK3568_CLUSTER_WIN_CTRL2		0x08
 #define RK3568_CLUSTER_WIN_YRGB_MST		0x10
 #define RK3568_CLUSTER_WIN_CBR_MST		0x14
 #define RK3568_CLUSTER_WIN_VIR			0x18
@@ -341,6 +349,7 @@ enum dst_factor_mode {
 /* (E)smart register definition, offset relative to window base */
 #define RK3568_SMART_CTRL0			0x00
 #define RK3568_SMART_CTRL1			0x04
+#define RK3588_SMART_AXI_CTRL			0x08
 #define RK3568_SMART_REGION0_CTRL		0x10
 #define RK3568_SMART_REGION0_YRGB_MST		0x14
 #define RK3568_SMART_REGION0_CBR_MST		0x18
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 9247f94343f2..65a88f489693 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -395,7 +395,7 @@ static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
  * AXI1 is a read only bus.
  *
  * Every window on a AXI bus must assigned two unique
- * read id(yrgb_id/uv_id, valid id are 0x1~0xe).
+ * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe).
  *
  * AXI0:
  * Cluster0/1, Esmart0/1, WriteBack
@@ -415,6 +415,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 0,
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 2,
+		.axi_uv_r_id = 3,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -431,6 +434,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -446,6 +452,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 2,
+		.axi_uv_r_id = 3,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -461,6 +470,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -475,6 +487,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 2,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -488,6 +503,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 3,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x01,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -501,6 +519,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 6,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -514,6 +535,9 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.layer_sel_id = 7,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x0d,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:09 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:09 +0800
Subject: [PATCH v6 10/16] drm/rockchip: vop2: Support for different layer select configuration between VPs
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-11-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP for rk3576, every VP has it's own LAYER_SEL
register, and the configuration value of each VP for the same
window maybe different, so extend the layer_sel_id to array,
let it can descption the layer select configuration value for
different VP.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v4)

Changes in v4:
- Typo fix: selet->select

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  4 +--
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 38 ++++++++++----------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 265bb5bfa27d..af3cd92e6815 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -166,9 +166,9 @@ struct vop2_win_data {
 	const unsigned int supported_rotations;
 
 	/**
-	 * @layer_sel_id: defined by register OVERLAY_LAYER_SEL of VOP2
+	 * @layer_sel_id: defined by register OVERLAY_LAYER_SEL or PORTn_LAYER_SEL
 	 */
-	unsigned int layer_sel_id;
+	unsigned int layer_sel_id[ROCKCHIP_MAX_CRTC];
 	uint64_t feature;
 
 	uint8_t axi_bus_id;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index a2e0126a31a0..01336ef2482a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -350,7 +350,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
-		.layer_sel_id = 3,
+		/* 0xf means this layer can't attached to this VP */
+		.layer_sel_id = { 3, 3, 3, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -363,7 +364,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1e00,
-		.layer_sel_id = 7,
+		.layer_sel_id = { 7, 7, 7, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -376,7 +377,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = 6,
+		.layer_sel_id = { 6, 6, 6, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -389,7 +390,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1800,
-		.layer_sel_id = 2,
+		.layer_sel_id = { 2, 2, 2, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -402,7 +403,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 0,
+		.layer_sel_id = { 0, 0, 0, 0xf },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.max_upscale_factor = 4,
@@ -417,7 +418,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 1,
+		.layer_sel_id = { 1, 1, 1, 0xf },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
@@ -582,7 +583,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 0,
+		.layer_sel_id = { 0, 0, 0, 0 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.axi_bus_id = 0,
@@ -600,7 +601,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 1,
+		.layer_sel_id = { 1, 1, 1, 1 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -618,7 +619,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 4,
+		.layer_sel_id = { 4, 4, 4, 4 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -636,7 +637,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 5,
+		.layer_sel_id =  { 5, 5, 5, 5 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -654,7 +655,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1800,
-		.layer_sel_id = 2,
+		.layer_sel_id = { 2, 2, 2, 2 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 0,
@@ -670,7 +671,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = 3,
+		.layer_sel_id = { 3, 3, 3, 3 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 0,
@@ -686,7 +687,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
-		.layer_sel_id = 6,
+		.layer_sel_id =  { 6, 6, 6, 6 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 1,
@@ -702,7 +703,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1e00,
-		.layer_sel_id = 7,
+		.layer_sel_id =  { 7, 7, 7, 7 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 1,
@@ -1454,7 +1455,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		 */
 		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
 			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
-			if (layer_sel_id == win->data->layer_sel_id)
+			if (layer_sel_id == win->data->layer_sel_id[vp->id])
 				break;
 		}
 
@@ -1464,7 +1465,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		for (i = 0; i < vop2->data->win_size; i++) {
 			old_win = &vop2->win[i];
 			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
-			if (layer_sel_id == old_win->data->layer_sel_id)
+			if (layer_sel_id == old_win->data->layer_sel_id[vp->id])
 				break;
 		}
 
@@ -1512,13 +1513,14 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		}
 
 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id[vp->id]);
 		/*
 		 * When we bind a window from layerM to layerN, we also need to move the old
 		 * window on layerN to layerM to avoid one window selected by two or more layers.
 		 */
 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id,
+			     old_win->data->layer_sel_id[vp->id]);
 	}
 
 	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:17:06 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:17:06 +0800
Subject: [PATCH v6 07/16] drm/rockchip: vop2: include rockchip_drm_drv.h
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081719.3330518-8-andyshrk@163.com>

From: Min-Hua Chen <minhuadotchen at gmail.com>

Move rockchip_drm_drv.h in rockchip_drm_vop2.h to fix the follow
sparse warning:

ARCH=arm64 LLVM=1 make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
mrproper defconfig all  -j12

drivers/gpu/drm/rockchip/rockchip_vop2_reg.c:502:24: sparse:
warning: symbol 'vop2_platform_driver' was not declared. Should it
be static?

It is also beneficial for the upcoming support for rk3576.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Signed-off-by: Min-Hua Chen <minhuadotchen at gmail.com>

---

(no changes since v3)

Changes in v3:
- Split it from 10/15, as it fix a exiting compile warning.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 85d281edfbfe..b5f35839d5e8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -35,7 +35,6 @@
 #include <uapi/linux/videodev2.h>
 #include <dt-bindings/soc/rockchip,vop2.h>
 
-#include "rockchip_drm_drv.h"
 #include "rockchip_drm_gem.h"
 #include "rockchip_drm_vop2.h"
 #include "rockchip_rgb.h"
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index f4724a402ac2..29cc7fb8f6d8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -9,6 +9,7 @@
 
 #include <linux/regmap.h>
 #include <drm/drm_modes.h>
+#include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
 #define VOP2_VP_FEATURE_OUTPUT_10BIT        BIT(0)
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:18:42 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:18:42 +0800
Subject: [PATCH v6 12/16] drm/rockchip: vop2: Register the primary plane and overlay plane separately
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081843.3330756-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP of rk3576, a Window cannot attach to all Video Ports,
so make sure all VP find it's suitable primary plane, then register the
remain windows as overlay plane will make code easier.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v3)

Changes in v3:
- Add comments for why we should treat rk3566 with special care.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 100 +++++++++++--------
 1 file changed, 61 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index c87c98a8fb3a..e588d5d01e0a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2223,22 +2223,29 @@ static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win,
 	return 0;
 }
 
-static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2)
+/*
+ * On RK3566 these windows don't have an independent
+ * framebuffer. They can only share/mirror the framebuffer
+ * with smart0, esmart0 and cluster0 respectively.
+ * And RK3566 share the same vop version with Rk3568, so we
+ * need to use soc_id for identification here.
+ */
+static bool vop2_is_mirror_win(struct vop2_win *win)
 {
-	int i;
-
-	for (i = 0; i < vop2->data->nr_vps; i++) {
-		struct vop2_video_port *vp = &vop2->vps[i];
-
-		if (!vp->crtc.port)
-			continue;
-		if (vp->primary_plane)
-			continue;
+	struct vop2 *vop2 = win->vop2;
 
-		return vp;
+	if (vop2->data->soc_id == 3566) {
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART1:
+		case ROCKCHIP_VOP2_CLUSTER1:
+			return true;
+		default:
+			return false;
+		}
+	} else {
+		return false;
 	}
-
-	return NULL;
 }
 
 static int vop2_create_crtcs(struct vop2 *vop2)
@@ -2249,7 +2256,9 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 	struct drm_plane *plane;
 	struct device_node *port;
 	struct vop2_video_port *vp;
-	int i, nvp, nvps = 0;
+	struct vop2_win *win;
+	u32 possible_crtcs;
+	int i, j, nvp, nvps = 0;
 	int ret;
 
 	for (i = 0; i < vop2_data->nr_vps; i++) {
@@ -2288,42 +2297,55 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 	}
 
 	nvp = 0;
-	for (i = 0; i < vop2->registered_num_wins; i++) {
-		struct vop2_win *win = &vop2->win[i];
-		u32 possible_crtcs = 0;
-
-		if (vop2->data->soc_id == 3566) {
-			/*
-			 * On RK3566 these windows don't have an independent
-			 * framebuffer. They share the framebuffer with smart0,
-			 * esmart0 and cluster0 respectively.
-			 */
-			switch (win->data->phys_id) {
-			case ROCKCHIP_VOP2_SMART1:
-			case ROCKCHIP_VOP2_ESMART1:
-			case ROCKCHIP_VOP2_CLUSTER1:
+	/* Register a primary plane for every crtc */
+	for (i = 0; i < vop2_data->nr_vps; i++) {
+		vp = &vop2->vps[i];
+
+		if (!vp->crtc.port)
+			continue;
+
+		for (j = 0; j < vop2->registered_num_wins; j++) {
+			win = &vop2->win[j];
+
+			/* Aready registered as primary plane */
+			if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
+				continue;
+
+			if (vop2_is_mirror_win(win))
 				continue;
-			}
-		}
 
-		if (win->type == DRM_PLANE_TYPE_PRIMARY) {
-			vp = find_vp_without_primary(vop2);
-			if (vp) {
+			if (win->type == DRM_PLANE_TYPE_PRIMARY) {
 				possible_crtcs = BIT(nvp);
 				vp->primary_plane = win;
+				ret = vop2_plane_init(vop2, win, possible_crtcs);
+				if (ret) {
+					drm_err(vop2->drm, "failed to init primary plane %s: %d\n",
+						win->data->name, ret);
+					return ret;
+				}
 				nvp++;
-			} else {
-				/* change the unused primary window to overlay window */
-				win->type = DRM_PLANE_TYPE_OVERLAY;
+				break;
 			}
 		}
+	}
+
+	/* Register all unused window as overlay plane */
+	for (i = 0; i < vop2->registered_num_wins; i++) {
+		win = &vop2->win[i];
+
+		/* Aready registered as primary plane */
+		if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
+			continue;
+
+		if (vop2_is_mirror_win(win))
+			continue;
 
-		if (win->type == DRM_PLANE_TYPE_OVERLAY)
-			possible_crtcs = (1 << nvps) - 1;
+		win->type = DRM_PLANE_TYPE_OVERLAY;
 
+		possible_crtcs = (1 << nvps) - 1;
 		ret = vop2_plane_init(vop2, win, possible_crtcs);
 		if (ret) {
-			drm_err(vop2->drm, "failed to init plane %s: %d\n",
+			drm_err(vop2->drm, "failed to init overlay plane %s: %d\n",
 				win->data->name, ret);
 			return ret;
 		}
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:18:54 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:18:54 +0800
Subject: [PATCH v6 13/16] drm/rockchip: vop2: Set plane possible crtcs by possible vp mask
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081855.3330798-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP of rk3576, a window cannot attach to all Video
Ports, we introduce a possible_vp_mask for every window to indicate
which Video Ports this window can attach to.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 18 +++++++++++++++++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  1 +
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 14 ++++++++++++++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index e588d5d01e0a..0b79f2006836 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2311,6 +2311,10 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 			if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
 				continue;
 
+			/* If this win can not attached to this VP */
+			if (!(win->data->possible_vp_mask & BIT(vp->id)))
+				continue;
+
 			if (vop2_is_mirror_win(win))
 				continue;
 
@@ -2342,7 +2346,19 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 
 		win->type = DRM_PLANE_TYPE_OVERLAY;
 
-		possible_crtcs = (1 << nvps) - 1;
+		possible_crtcs = 0;
+		nvp = 0;
+		for (j = 0; j < vop2_data->nr_vps; j++) {
+			vp = &vop2->vps[j];
+
+			if (!vp->crtc.port)
+				continue;
+
+			if (win->data->possible_vp_mask & BIT(vp->id))
+				possible_crtcs |= BIT(nvp);
+			nvp++;
+		}
+
 		ret = vop2_plane_init(vop2, win, possible_crtcs);
 		if (ret) {
 			drm_err(vop2->drm, "failed to init overlay plane %s: %d\n",
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 21464d107bd3..3c9caf13749d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -167,6 +167,7 @@ struct vop2_win_data {
 	unsigned int phys_id;
 
 	u32 base;
+	u32 possible_vp_mask;
 	enum drm_plane_type type;
 
 	u32 nformats;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index e311af7e3a1a..85c15dd396aa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -347,6 +347,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.name = "Smart0-win0",
 		.phys_id = ROCKCHIP_VOP2_SMART0,
 		.base = 0x1c00,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
@@ -360,6 +361,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	}, {
 		.name = "Smart1-win0",
 		.phys_id = ROCKCHIP_VOP2_SMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
@@ -373,6 +375,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	}, {
 		.name = "Esmart1-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_rk356x_esmart,
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
@@ -386,6 +389,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	}, {
 		.name = "Esmart0-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_rk356x_esmart,
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
@@ -400,6 +404,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.name = "Cluster0-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
 		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -415,6 +420,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.name = "Cluster1-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
 		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -580,6 +586,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster0-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
 		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -598,6 +605,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster1-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
 		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -616,6 +624,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster2-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER2,
 		.base = 0x1400,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -634,6 +643,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster3-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER3,
 		.base = 0x1600,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -651,6 +661,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	}, {
 		.name = "Esmart0-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
@@ -667,6 +678,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	}, {
 		.name = "Esmart1-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
@@ -684,6 +696,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Esmart2-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART2,
 		.base = 0x1c00,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
@@ -699,6 +712,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	}, {
 		.name = "Esmart3-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART3,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:19:06 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:19:06 +0800
Subject: [PATCH v6 14/16] drm/rockchip: vop2: Add uv swap for cluster window
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081908.3330839-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The Cluster windows of upcoming VOP on rk3576 also support
linear YUV support, we need to set uv swap bit for it.

As the VOP2_WIN_UV_SWA register defined on rk3568/rk3588 is
0xffffffff, so this register will not be touched on these
two platforms.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0b79f2006836..0ddfafa3c208 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1373,10 +1373,8 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 
 	rb_swap = vop2_win_rb_swap(fb->format->format);
 	vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap);
-	if (!vop2_cluster_window(win)) {
-		uv_swap = vop2_win_uv_swap(fb->format->format);
-		vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap);
-	}
+	uv_swap = vop2_win_uv_swap(fb->format->format);
+	vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap);
 
 	if (fb->format->is_yuv) {
 		vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4));
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:19:18 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:19:18 +0800
Subject: [PATCH v6 15/16] dt-bindings: display: vop2: Add rk3576 support
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081919.3330879-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Add vop found on rk3576, the main difference between rk3576 and the
previous vop is that each VP has its own interrupt line.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>

---

(no changes since v3)

Changes in v3:
- ordered by soc name
- Add description for newly added interrupt

Changes in v2:
- Add dt bindings

 .../bindings/display/rockchip/rockchip-vop2.yaml    | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
index 2531726af306..a44964b6c36a 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -20,6 +20,7 @@ properties:
     enum:
       - rockchip,rk3566-vop
       - rockchip,rk3568-vop
+      - rockchip,rk3576-vop
       - rockchip,rk3588-vop
 
   reg:
@@ -37,10 +38,14 @@ properties:
       - const: gamma-lut
 
   interrupts:
-    maxItems: 1
-    description:
-      The VOP interrupt is shared by several interrupt sources, such as
-      frame start (VSYNC), line flag and other status interrupts.
+    minItems: 1
+    items:
+      - description:
+          vop system interrupt, such as bus error, and vsync for vop version under
+          rk3576.
+      - description:
+          independent interrupts for each video port, such as vsync and other video
+          port related error interrupts.
 
   # See compatible-specific constraints below.
   clocks:
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:13 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:13 +0800
Subject: [PATCH v6 05/16] drm/rockchip: vop2: Check linear format for Cluster windows on rk3566/8
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-6-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The Cluster windows on rk3566/8 only support afbc mode.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>

---

Changes in v6:
- Move the linear check to format_mod_supported() hook

Changes in v5:
- Added in V5

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index f143df2b13a1..94f77faf14d1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -593,6 +593,16 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
 	if (modifier == DRM_FORMAT_MOD_INVALID)
 		return false;
 
+	if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
+		if (vop2_cluster_window(win)) {
+			if (modifier == DRM_FORMAT_MOD_LINEAR) {
+				drm_dbg_kms(vop2->drm,
+					    "Cluster window only support format with afbc\n");
+				return false;
+			}
+		}
+	}
+
 	if (modifier == DRM_FORMAT_MOD_LINEAR)
 		return true;
 
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:14 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:14 +0800
Subject: [PATCH v6 06/16] drm/rockchip: vop2: Add check for 32 bpp format for rk3588
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-7-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

RK3588 only support DRM_FORMAT_XRGB2101010/XBGR2101010 in afbc mode.

Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>

---

Changes in v6:
- Move 32 bpp check to format_mod_supported() hook

Changes in v5:
- Added in V5

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 94f77faf14d1..85d281edfbfe 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -603,6 +603,15 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
 		}
 	}
 
+	if (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010) {
+		if (vop2->data->soc_id == 3588) {
+			if (!rockchip_afbc(plane, modifier)) {
+				drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n");
+				return false;
+			}
+		}
+	}
+
 	if (modifier == DRM_FORMAT_MOD_LINEAR)
 		return true;
 
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:08 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:08 +0800
Subject: [PATCH v6 00/16] VOP Support for rk3576
In-Reply-To: <20241209122943.2781431-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>


Thanks for the basic work from Collabora, I can bringup a HDMI
display out on rk3576.

PATCH 1 is a carryover from the working when add support for
    rk3588[0], is very usefull when some people want me
    help debug some issue online, so I really hope it can
    be merged at this round.
PATCH 2~8 are bugfix of rk3588 alpha blending which report and
    test by Derek
PATCH 9~13 are preparations for rk3576 support
PATCH 17~18 are real support for rk376

I test it with a 1080P/4K HDMI output with modetest and weston
output.

If there are some one want to have a try, I have a tree based on
Linux 6.13-rc2 here[1]

[0]https://patchwork.kernel.org/project/linux-rockchip/cover/20231211115547.1784587-1-andyshrk at 163.com/
[1]https://github.com/andyshrk/linux/tree/rk3576-vop2-upstream-v5

Changes in v6:
- Remove unnecessary blank line.
- Limit line length not exceeds 100
- Move the linear check to format_mod_supported() hook
- Move 32 bpp check to format_mod_supported() hook
- Add a blank line after hardware version check code
-  More specific explanation about the AXI_BUS_ID register bit of
   cluster window.
- Collect Tested-by

Changes in v5:
- Added in V5
- Added in V5
- Added in V5
- Add axi id configuration
- Remove the non-existent CBCR scale register.

Changes in v4:
- Typo fix: selet->select

Changes in v3:
- Split it from 10/15, as it fix a exiting compile warning.
- Add comments for why we should treat rk3566 with special care.
- Add hardware version check
- Add comments for why we should treat rk3566 with special care.
- ordered by soc name
- Add description for newly added interrupt
- Share the alpha setup function with rk3568
- recoder the code block by soc

Changes in v2:
- split it from main patch add support for rk3576
- Add platform specific callback
- Introduce vop hardware version
- Add dt bindings
- Add platform specific callback

Andy Yan (15):
  drm/rockchip: vop2: Add debugfs support
  drm/rockchip: vop2: Fix the windows switch between different layers
  drm/rockchip: vop2: Set AXI id for rk3588
  drm/rockchip: vop2: Setup delay cycle for Esmart2/3
  drm/rockchip: vop2: Check linear format for Cluster windows on
    rk3566/8
  drm/rockchip: vop2: Add check for 32 bpp format for rk3588
  drm/rockchip: vop2: Support 32x8 superblock afbc
  drm/rockchip: vop2: Add platform specific callback
  drm/rockchip: vop2: Support for different layer select configuration
    between VPs
  drm/rockchip: vop2: Introduce vop hardware version
  drm/rockchip: vop2: Register the primary plane and overlay plane
    separately
  drm/rockchip: vop2: Set plane possible crtcs by possible vp mask
  drm/rockchip: vop2: Add uv swap for cluster window
  dt-bindings: display: vop2: Add rk3576 support
  drm/rockchip: vop2: Add support for rk3576

Min-Hua Chen (1):
  drm/rockchip: vop2: include rockchip_drm_drv.h

 .../display/rockchip/rockchip-vop2.yaml       |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  | 1638 ++++----------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h  |  292 ++-
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c  | 2014 ++++++++++++++++-
 4 files changed, 2793 insertions(+), 1164 deletions(-)

-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:15:17 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:15:17 +0800
Subject: [PATCH v6 09/16] drm/rockchip: vop2: Add platform specific callback
In-Reply-To: <20241214081529.3330243-1-andyshrk@163.com>
References: <20241209122943.2781431-1-andyshrk@163.com>
 <20241214081529.3330243-1-andyshrk@163.com>
Message-ID: <20241214081529.3330243-10-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The VOP interface mux, overlay, background delay cycle configuration
of different SOC are much different. Add platform specific callback
ops to let the core driver look cleaner and more refined.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v2)

Changes in v2:
- Add platform specific callback

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1145 +-----------------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  168 +++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c |  992 +++++++++++++++
 3 files changed, 1180 insertions(+), 1125 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index efe7d0cbe155..fded1e931c9a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -33,7 +33,6 @@
 #include <drm/drm_vblank.h>
 
 #include <uapi/linux/videodev2.h>
-#include <dt-bindings/soc/rockchip,vop2.h>
 
 #include "rockchip_drm_gem.h"
 #include "rockchip_drm_vop2.h"
@@ -102,143 +101,6 @@ enum vop2_afbc_format {
 	VOP2_AFBC_FMT_INVALID = -1,
 };
 
-union vop2_alpha_ctrl {
-	u32 val;
-	struct {
-		/* [0:1] */
-		u32 color_mode:1;
-		u32 alpha_mode:1;
-		/* [2:3] */
-		u32 blend_mode:2;
-		u32 alpha_cal_mode:1;
-		/* [5:7] */
-		u32 factor_mode:3;
-		/* [8:9] */
-		u32 alpha_en:1;
-		u32 src_dst_swap:1;
-		u32 reserved:6;
-		/* [16:23] */
-		u32 glb_alpha:8;
-	} bits;
-};
-
-struct vop2_alpha {
-	union vop2_alpha_ctrl src_color_ctrl;
-	union vop2_alpha_ctrl dst_color_ctrl;
-	union vop2_alpha_ctrl src_alpha_ctrl;
-	union vop2_alpha_ctrl dst_alpha_ctrl;
-};
-
-struct vop2_alpha_config {
-	bool src_premulti_en;
-	bool dst_premulti_en;
-	bool src_pixel_alpha_en;
-	bool dst_pixel_alpha_en;
-	u16 src_glb_alpha_value;
-	u16 dst_glb_alpha_value;
-};
-
-struct vop2_win {
-	struct vop2 *vop2;
-	struct drm_plane base;
-	const struct vop2_win_data *data;
-	struct regmap_field *reg[VOP2_WIN_MAX_REG];
-
-	/**
-	 * @win_id: graphic window id, a cluster may be split into two
-	 * graphics windows.
-	 */
-	u8 win_id;
-	u8 delay;
-	u32 offset;
-
-	enum drm_plane_type type;
-};
-
-struct vop2_video_port {
-	struct drm_crtc crtc;
-	struct vop2 *vop2;
-	struct clk *dclk;
-	unsigned int id;
-	const struct vop2_video_port_data *data;
-
-	struct completion dsp_hold_completion;
-
-	/**
-	 * @win_mask: Bitmask of windows attached to the video port;
-	 */
-	u32 win_mask;
-
-	struct vop2_win *primary_plane;
-	struct drm_pending_vblank_event *event;
-
-	unsigned int nlayers;
-};
-
-struct vop2 {
-	struct device *dev;
-	struct drm_device *drm;
-	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
-
-	const struct vop2_data *data;
-	/*
-	 * Number of windows that are registered as plane, may be less than the
-	 * total number of hardware windows.
-	 */
-	u32 registered_num_wins;
-
-	struct resource *res;
-	void __iomem *regs;
-	struct regmap *map;
-
-	struct regmap *sys_grf;
-	struct regmap *vop_grf;
-	struct regmap *vo1_grf;
-	struct regmap *sys_pmu;
-
-	/* physical map length of vop2 register */
-	u32 len;
-
-	void __iomem *lut_regs;
-
-	/* protects crtc enable/disable */
-	struct mutex vop2_lock;
-
-	int irq;
-
-	/*
-	 * Some global resources are shared between all video ports(crtcs), so
-	 * we need a ref counter here.
-	 */
-	unsigned int enable_count;
-	struct clk *hclk;
-	struct clk *aclk;
-	struct clk *pclk;
-
-	/* optional internal rgb encoder */
-	struct rockchip_rgb *rgb;
-
-	/* must be put at the end of the struct */
-	struct vop2_win win[];
-};
-
-#define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
-					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
-
-#define vop2_output_if_is_dp(x)		((x) == ROCKCHIP_VOP2_EP_DP0 || \
-					 (x) == ROCKCHIP_VOP2_EP_DP1)
-
-#define vop2_output_if_is_edp(x)	((x) == ROCKCHIP_VOP2_EP_EDP0 || \
-					 (x) == ROCKCHIP_VOP2_EP_EDP1)
-
-#define vop2_output_if_is_mipi(x)	((x) == ROCKCHIP_VOP2_EP_MIPI0 || \
-					 (x) == ROCKCHIP_VOP2_EP_MIPI1)
-
-#define vop2_output_if_is_lvds(x)	((x) == ROCKCHIP_VOP2_EP_LVDS0 || \
-					 (x) == ROCKCHIP_VOP2_EP_LVDS1)
-
-#define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
-
 
 /*
  * bus-format types.
@@ -272,15 +134,6 @@ static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
 
 static const struct regmap_config vop2_regmap_config;
 
-static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
-{
-	return container_of(crtc, struct vop2_video_port, crtc);
-}
-
-static struct vop2_win *to_vop2_win(struct drm_plane *p)
-{
-	return container_of(p, struct vop2_win, base);
-}
 
 static void vop2_lock(struct vop2 *vop2)
 {
@@ -292,44 +145,6 @@ static void vop2_unlock(struct vop2 *vop2)
 	mutex_unlock(&vop2->vop2_lock);
 }
 
-static void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
-{
-	regmap_write(vop2->map, offset, v);
-}
-
-static void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
-{
-	regmap_write(vp->vop2->map, vp->data->offset + offset, v);
-}
-
-static u32 vop2_readl(struct vop2 *vop2, u32 offset)
-{
-	u32 val;
-
-	regmap_read(vop2->map, offset, &val);
-
-	return val;
-}
-
-static u32 vop2_vp_read(struct vop2_video_port *vp, u32 offset)
-{
-	u32 val;
-
-	regmap_read(vp->vop2->map, vp->data->offset + offset, &val);
-
-	return val;
-}
-
-static void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
-{
-	regmap_field_write(win->reg[reg], v);
-}
-
-static bool vop2_cluster_window(const struct vop2_win *win)
-{
-	return win->data->feature & WIN_FEATURE_CLUSTER;
-}
-
 /*
  * Note:
  * The write mask function is documented but missing on rk3566/8, writes
@@ -1724,6 +1539,7 @@ static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
 static void vop2_post_config(struct drm_crtc *crtc)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct vop2 *vop2 = vp->vop2;
 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 	u16 vtotal = mode->crtc_vtotal;
 	u16 hdisplay = mode->crtc_hdisplay;
@@ -1734,18 +1550,10 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	u32 top_margin = 100, bottom_margin = 100;
 	u16 hsize = hdisplay * (left_margin + right_margin) / 200;
 	u16 vsize = vdisplay * (top_margin + bottom_margin) / 200;
-	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
 	u16 hact_end, vact_end;
 	u32 val;
-	u32 bg_dly;
-	u32 pre_scan_dly;
-
-	bg_dly = vp->data->pre_scan_max_dly[3];
-	vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
-		    FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
 
-	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
-	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+	vop2->ops->setup_bg_dly(vp);
 
 	vsize = rounddown(vsize, 2);
 	hsize = rounddown(hsize, 2);
@@ -1781,347 +1589,6 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
 }
 
-static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_crtc *crtc = &vp->crtc;
-	u32 die, dip;
-
-	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
-	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
-
-	switch (id) {
-	case ROCKCHIP_VOP2_EP_RGB0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_RGB |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		if (polflags & POLFLAG_DCLK_INV)
-			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
-		else
-			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
-		break;
-	case ROCKCHIP_VOP2_EP_HDMI0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_EDP0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_EDP |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI1:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_LVDS0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_LVDS1:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		break;
-	default:
-		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
-		return 0;
-	}
-
-	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
-
-	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
-	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
-
-	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
-}
-
-/*
- * calc the dclk on rk3588
- * the available div of dclk is 1, 2, 4
- */
-static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
-{
-	if (child_clk * 4 <= max_dclk)
-		return child_clk * 4;
-	else if (child_clk * 2 <= max_dclk)
-		return child_clk * 2;
-	else if (child_clk <= max_dclk)
-		return child_clk;
-	else
-		return 0;
-}
-
-/*
- * 4 pixclk/cycle on rk3588
- * RGB/eDP/HDMI: if_pixclk >= dclk_core
- * DP: dp_pixclk = dclk_out <= dclk_core
- * DSI: mipi_pixclk <= dclk_out <= dclk_core
- */
-static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
-					 int *dclk_core_div, int *dclk_out_div,
-					 int *if_pixclk_div, int *if_dclk_div)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_crtc *crtc = &vp->crtc;
-	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
-	int output_mode = vcstate->output_mode;
-	unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
-	unsigned long dclk_core_rate = v_pixclk >> 2;
-	unsigned long dclk_rate = v_pixclk;
-	unsigned long dclk_out_rate;
-	unsigned long if_pixclk_rate;
-	int K = 1;
-
-	if (vop2_output_if_is_hdmi(id)) {
-		/*
-		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
-		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
-		 */
-		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
-			dclk_rate = dclk_rate >> 1;
-			K = 2;
-		}
-
-		if_pixclk_rate = (dclk_core_rate << 1) / K;
-		/*
-		 * if_dclk_rate = dclk_core_rate / K;
-		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
-		 * *if_dclk_div = dclk_rate / if_dclk_rate;
-		 */
-		*if_pixclk_div = 2;
-		*if_dclk_div = 4;
-	} else if (vop2_output_if_is_edp(id)) {
-		/*
-		 * edp_pixclk = edp_dclk > dclk_core
-		 */
-		if_pixclk_rate = v_pixclk / K;
-		dclk_rate = if_pixclk_rate * K;
-		/*
-		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
-		 * *if_dclk_div = *if_pixclk_div;
-		 */
-		*if_pixclk_div = K;
-		*if_dclk_div = K;
-	} else if (vop2_output_if_is_dp(id)) {
-		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
-			dclk_out_rate = v_pixclk >> 3;
-		else
-			dclk_out_rate = v_pixclk >> 2;
-
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
-		if (!dclk_rate) {
-			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n",
-				dclk_out_rate);
-			return 0;
-		}
-		*dclk_out_div = dclk_rate / dclk_out_rate;
-	} else if (vop2_output_if_is_mipi(id)) {
-		if_pixclk_rate = dclk_core_rate / K;
-		/*
-		 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
-		 */
-		dclk_out_rate = if_pixclk_rate;
-		/*
-		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
-		 * we get a little factor here
-		 */
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
-		if (!dclk_rate) {
-			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n",
-				dclk_out_rate);
-			return 0;
-		}
-		*dclk_out_div = dclk_rate / dclk_out_rate;
-		/*
-		 * mipi pixclk == dclk_out
-		 */
-		*if_pixclk_div = 1;
-	} else if (vop2_output_if_is_dpi(id)) {
-		dclk_rate = v_pixclk;
-	}
-
-	*dclk_core_div = dclk_rate / dclk_core_rate;
-	*if_pixclk_div = ilog2(*if_pixclk_div);
-	*if_dclk_div = ilog2(*if_dclk_div);
-	*dclk_core_div = ilog2(*dclk_core_div);
-	*dclk_out_div = ilog2(*dclk_out_div);
-
-	drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
-		dclk_rate, *if_pixclk_div, *if_dclk_div);
-
-	return dclk_rate;
-}
-
-/*
- * MIPI port mux on rk3588:
- * 0: Video Port2
- * 1: Video Port3
- * 3: Video Port 1(MIPI1 only)
- */
-static u32 rk3588_get_mipi_port_mux(int vp_id)
-{
-	if (vp_id == 1)
-		return 3;
-	else if (vp_id == 3)
-		return 1;
-	else
-		return 0;
-}
-
-static u32 rk3588_get_hdmi_pol(u32 flags)
-{
-	u32 val;
-
-	val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
-	val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
-
-	return val;
-}
-
-static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
-	unsigned long clock;
-	u32 die, dip, div, vp_clk_div, val;
-
-	clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
-				    &if_pixclk_div, &if_dclk_div);
-	if (!clock)
-		return 0;
-
-	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
-	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
-
-	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
-	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
-	div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
-
-	switch (id) {
-	case ROCKCHIP_VOP2_EP_HDMI0:
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
-			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
-		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
-		break;
-	case ROCKCHIP_VOP2_EP_HDMI1:
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
-			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
-		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
-		break;
-	case ROCKCHIP_VOP2_EP_EDP0:
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
-		break;
-	case ROCKCHIP_VOP2_EP_EDP1:
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI0:
-		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
-		val = rk3588_get_mipi_port_mux(vp->id);
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI1:
-		div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		val = rk3588_get_mipi_port_mux(vp->id);
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
-		break;
-	case ROCKCHIP_VOP2_EP_DP0:
-		die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
-		dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
-		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_DP1:
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
-		dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
-		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
-		break;
-	default:
-		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
-		return 0;
-	}
-
-	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
-
-	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
-	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
-	vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
-	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
-
-	return clock;
-}
-
-static unsigned long vop2_set_intf_mux(struct vop2_video_port *vp, int ep_id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-
-	if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568)
-		return rk3568_set_intf_mux(vp, ep_id, polflags);
-	else if (vop2->data->soc_id == 3588)
-		return rk3588_set_intf_mux(vp, ep_id, polflags);
-	else
-		return 0;
-}
-
 static int us_to_vertical_line(struct drm_display_mode *mode, int us)
 {
 	return us * mode->clock / mode->htotal / 1000;
@@ -2194,7 +1661,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
 		 * process multi(1/2/4/8) pixels per cycle, so the dclk feed by the
 		 * system cru may be the 1/2 or 1/4 of mode->clock.
 		 */
-		clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
+		clock = vop2->ops->setup_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
 	}
 
 	if (!clock) {
@@ -2323,454 +1790,13 @@ static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
 	return 0;
 }
 
-static bool is_opaque(u16 alpha)
-{
-	return (alpha >> 8) == 0xff;
-}
-
-static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
-			     struct vop2_alpha *alpha)
-{
-	int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
-	int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
-	int src_color_mode = alpha_config->src_premulti_en ?
-				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
-	int dst_color_mode = alpha_config->dst_premulti_en ?
-				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
-
-	alpha->src_color_ctrl.val = 0;
-	alpha->dst_color_ctrl.val = 0;
-	alpha->src_alpha_ctrl.val = 0;
-	alpha->dst_alpha_ctrl.val = 0;
-
-	if (!alpha_config->src_pixel_alpha_en)
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
-	else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
-	else
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
-
-	alpha->src_color_ctrl.bits.alpha_en = 1;
-
-	if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
-		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
-	} else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
-		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
-	} else {
-		alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
-	}
-	alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
-	alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-
-	alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-	alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
-	alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
-	alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
-	alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
-
-	alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
-	alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-	alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
-
-	alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
-		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
-	else
-		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
-	alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
-	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
-}
-
-static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
-{
-	struct vop2_video_port *vp;
-	int used_layer = 0;
-	int i;
-
-	for (i = 0; i < port_id; i++) {
-		vp = &vop2->vps[i];
-		used_layer += hweight32(vp->win_mask);
-	}
-
-	return used_layer;
-}
-
-static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
-{
-	struct vop2_alpha_config alpha_config;
-	struct vop2_alpha alpha;
-	struct drm_plane_state *bottom_win_pstate;
-	bool src_pixel_alpha_en = false;
-	u16 src_glb_alpha_val, dst_glb_alpha_val;
-	bool premulti_en = false;
-	bool swap = false;
-	u32 offset = 0;
-
-	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
-	bottom_win_pstate = main_win->base.state;
-	src_glb_alpha_val = 0;
-	dst_glb_alpha_val = main_win->base.state->alpha;
-
-	if (!bottom_win_pstate->fb)
-		return;
-
-	alpha_config.src_premulti_en = premulti_en;
-	alpha_config.dst_premulti_en = false;
-	alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
-	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
-	alpha_config.src_glb_alpha_value = src_glb_alpha_val;
-	alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
-	vop2_parse_alpha(&alpha_config, &alpha);
-
-	alpha.src_color_ctrl.bits.src_dst_swap = swap;
-
-	switch (main_win->data->phys_id) {
-	case ROCKCHIP_VOP2_CLUSTER0:
-		offset = 0x0;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER1:
-		offset = 0x10;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER2:
-		offset = 0x20;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER3:
-		offset = 0x30;
-		break;
-	}
-
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
-		    alpha.src_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
-		    alpha.dst_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
-		    alpha.src_alpha_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
-		    alpha.dst_alpha_ctrl.val);
-}
-
-static void vop2_setup_alpha(struct vop2_video_port *vp)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_framebuffer *fb;
-	struct vop2_alpha_config alpha_config;
-	struct vop2_alpha alpha;
-	struct drm_plane *plane;
-	int pixel_alpha_en;
-	int premulti_en, gpremulti_en = 0;
-	int mixer_id;
-	u32 offset;
-	bool bottom_layer_alpha_en = false;
-	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
-
-	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
-	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-
-		if (plane->state->normalized_zpos == 0 &&
-		    !is_opaque(plane->state->alpha) &&
-		    !vop2_cluster_window(win)) {
-			/*
-			 * If bottom layer have global alpha effect [except cluster layer,
-			 * because cluster have deal with bottom layer global alpha value
-			 * at cluster mix], bottom layer mix need deal with global alpha.
-			 */
-			bottom_layer_alpha_en = true;
-			dst_global_alpha = plane->state->alpha;
-		}
-	}
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-		int zpos = plane->state->normalized_zpos;
-
-		/*
-		 * Need to configure alpha from second layer.
-		 */
-		if (zpos == 0)
-			continue;
-
-		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
-			premulti_en = 1;
-		else
-			premulti_en = 0;
-
-		plane = &win->base;
-		fb = plane->state->fb;
-
-		pixel_alpha_en = fb->format->has_alpha;
-
-		alpha_config.src_premulti_en = premulti_en;
-
-		if (bottom_layer_alpha_en && zpos == 1) {
-			gpremulti_en = premulti_en;
-			/* Cd = Cs + (1 - As) * Cd * Agd */
-			alpha_config.dst_premulti_en = false;
-			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
-			alpha_config.src_glb_alpha_value = plane->state->alpha;
-			alpha_config.dst_glb_alpha_value = dst_global_alpha;
-		} else if (vop2_cluster_window(win)) {
-			/* Mix output data only have pixel alpha */
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = true;
-			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-		} else {
-			/* Cd = Cs + (1 - As) * Cd */
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
-			alpha_config.src_glb_alpha_value = plane->state->alpha;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-		}
-
-		vop2_parse_alpha(&alpha_config, &alpha);
-
-		offset = (mixer_id + zpos - 1) * 0x10;
-		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
-			    alpha.src_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
-			    alpha.dst_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
-			    alpha.src_alpha_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
-			    alpha.dst_alpha_ctrl.val);
-	}
-
-	if (vp->id == 0) {
-		if (bottom_layer_alpha_en) {
-			/* Transfer pixel alpha to hdr mix */
-			alpha_config.src_premulti_en = gpremulti_en;
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = true;
-			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			vop2_parse_alpha(&alpha_config, &alpha);
-
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
-				    alpha.src_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
-				    alpha.dst_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
-				    alpha.src_alpha_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
-				    alpha.dst_alpha_ctrl.val);
-		} else {
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
-		}
-	}
-}
-
-static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_plane *plane;
-	u32 layer_sel = 0;
-	u32 port_sel;
-	u8 layer_id;
-	u8 old_layer_id;
-	u8 layer_sel_id;
-	unsigned int ofs;
-	u32 ovl_ctrl;
-	int i;
-	struct vop2_video_port *vp0 = &vop2->vps[0];
-	struct vop2_video_port *vp1 = &vop2->vps[1];
-	struct vop2_video_port *vp2 = &vop2->vps[2];
-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
-
-	ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
-	ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
-	if (vcstate->yuv_overlay)
-		ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
-	else
-		ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
-
-	vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
-
-	port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
-	port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
-
-	if (vp0->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
-				     vp0->nlayers - 1);
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
-
-	if (vp1->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
-				     (vp0->nlayers + vp1->nlayers - 1));
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
-
-	if (vp2->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
-			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
-
-	layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
-
-	ofs = 0;
-	for (i = 0; i < vp->id; i++)
-		ofs += vop2->vps[i].nlayers;
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-		struct vop2_win *old_win;
-
-		layer_id = (u8)(plane->state->normalized_zpos + ofs);
-
-		/*
-		 * Find the layer this win bind in old state.
-		 */
-		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
-			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
-			if (layer_sel_id == win->data->layer_sel_id)
-				break;
-		}
-
-		/*
-		 * Find the win bind to this layer in old state
-		 */
-		for (i = 0; i < vop2->data->win_size; i++) {
-			old_win = &vop2->win[i];
-			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
-			if (layer_sel_id == old_win->data->layer_sel_id)
-				break;
-		}
-
-		switch (win->data->phys_id) {
-		case ROCKCHIP_VOP2_CLUSTER0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER2:
-			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER3:
-			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART2:
-			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART3:
-			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
-			break;
-		case ROCKCHIP_VOP2_SMART0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_SMART1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
-			break;
-		}
-
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
-		/*
-		 * When we bind a window from layerM to layerN, we also need to move the old
-		 * window on layerN to layerM to avoid one window selected by two or more layers.
-		 */
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
-	}
-
-	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-	vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
-}
-
-static void vop2_setup_dly_for_windows(struct vop2 *vop2)
-{
-	struct vop2_win *win;
-	int i = 0;
-	u32 cdly = 0, sdly = 0;
-
-	for (i = 0; i < vop2->data->win_size; i++) {
-		u32 dly;
-
-		win = &vop2->win[i];
-		dly = win->delay;
-
-		switch (win->data->phys_id) {
-		case ROCKCHIP_VOP2_CLUSTER0:
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER1:
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
-			break;
-		case ROCKCHIP_VOP2_ESMART0:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
-			break;
-		case ROCKCHIP_VOP2_ESMART1:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
-			break;
-		case ROCKCHIP_VOP2_SMART0:
-		case ROCKCHIP_VOP2_ESMART2:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
-			break;
-		case ROCKCHIP_VOP2_SMART1:
-		case ROCKCHIP_VOP2_ESMART3:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
-			break;
-		}
-	}
-
-	vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
-	vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
-}
-
 static void vop2_crtc_atomic_begin(struct drm_crtc *crtc,
 				   struct drm_atomic_state *state)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
 	struct vop2 *vop2 = vp->vop2;
-	struct drm_plane *plane;
-
-	vp->win_mask = 0;
-
-	drm_atomic_crtc_for_each_plane(plane, crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-
-		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
-
-		vp->win_mask |= BIT(win->data->phys_id);
 
-		if (vop2_cluster_window(win))
-			vop2_setup_cluster_alpha(vop2, win);
-	}
-
-	if (!vp->win_mask)
-		return;
-
-	vop2_setup_layer_mixer(vp);
-	vop2_setup_alpha(vp);
-	vop2_setup_dly_for_windows(vop2);
+	vop2->ops->setup_overlay(vp);
 }
 
 static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
@@ -3373,182 +2399,50 @@ static int vop2_find_rgb_encoder(struct vop2 *vop2)
 	return -ENOENT;
 }
 
-static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
-	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
-	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
-	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
-	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
-	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
-	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
-	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
-	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
-	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
-	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
-	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
-	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
-	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
-	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
-	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
-	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
-	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
-	/* RK3588 only, reserved bit on rk3568*/
-	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
-
-	/* Scale */
-	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
-	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
-	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
-	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
-	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
-	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
-	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
-
-	/* cluster regs */
-	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
-	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
-	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
-
-	/* afbc regs */
-	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
-	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
-	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
-	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
-	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
-	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
-	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
-	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
-	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
-	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
-	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
-	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
-	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
-	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
-	[VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
-	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
-	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
-	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
-	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
-};
-
 static int vop2_cluster_init(struct vop2_win *win)
 {
 	struct vop2 *vop2 = win->vop2;
 	struct reg_field *cluster_regs;
 	int ret, i;
 
-	cluster_regs = kmemdup(vop2_cluster_regs, sizeof(vop2_cluster_regs),
+	cluster_regs = kmemdup(vop2->data->cluster_reg,
+			       sizeof(struct reg_field) * vop2->data->nr_cluster_regs,
 			       GFP_KERNEL);
 	if (!cluster_regs)
 		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(vop2_cluster_regs); i++)
+	for (i = 0; i < vop2->data->nr_cluster_regs; i++)
 		if (cluster_regs[i].reg != 0xffffffff)
 			cluster_regs[i].reg += win->offset;
 
 	ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
 					   cluster_regs,
-					   ARRAY_SIZE(vop2_cluster_regs));
-
+					   vop2->data->nr_cluster_regs);
 	kfree(cluster_regs);
 
 	return ret;
 };
 
-static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
-	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
-	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
-	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
-	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
-	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
-	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
-	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
-	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
-	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
-	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
-	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
-	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
-	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
-	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
-	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
-	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
-	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
-	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
-	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
-	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
-	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
-	/* RK3588 only, reserved register on rk3568 */
-	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
-
-	/* Scale */
-	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
-	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
-	[VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
-	[VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
-	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
-	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
-	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
-	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
-	[VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
-	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
-	[VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
-	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
-	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
-	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
-	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
-	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
-	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
-	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
-	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
-};
-
 static int vop2_esmart_init(struct vop2_win *win)
 {
 	struct vop2 *vop2 = win->vop2;
-	struct reg_field *esmart_regs;
+	struct reg_field *smart_regs;
 	int ret, i;
 
-	esmart_regs = kmemdup(vop2_esmart_regs, sizeof(vop2_esmart_regs),
-			      GFP_KERNEL);
-	if (!esmart_regs)
+	smart_regs = kmemdup(vop2->data->smart_reg,
+			     sizeof(struct reg_field) * vop2->data->nr_smart_regs,
+			     GFP_KERNEL);
+	if (!smart_regs)
 		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(vop2_esmart_regs); i++)
-		if (esmart_regs[i].reg != 0xffffffff)
-			esmart_regs[i].reg += win->offset;
+	for (i = 0; i < vop2->data->nr_smart_regs; i++)
+		if (smart_regs[i].reg != 0xffffffff)
+			smart_regs[i].reg += win->offset;
 
 	ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
-					   esmart_regs,
-					   ARRAY_SIZE(vop2_esmart_regs));
-
-	kfree(esmart_regs);
+					   smart_regs,
+					   vop2->data->nr_smart_regs);
+	kfree(smart_regs);
 
 	return ret;
 };
@@ -3628,6 +2522,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 
 	vop2->dev = dev;
 	vop2->data = vop2_data;
+	vop2->ops = vop2_data->ops;
 	vop2->drm = drm;
 
 	dev_set_drvdata(dev, vop2);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 29cc7fb8f6d8..265bb5bfa27d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -9,6 +9,7 @@
 
 #include <linux/regmap.h>
 #include <drm/drm_modes.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
@@ -58,6 +59,23 @@ enum vop2_scale_down_mode {
 #define VOP2_PD_DSC_4K		BIT(6)
 #define VOP2_PD_ESMART		BIT(7)
 
+#define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
+					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
+
+#define vop2_output_if_is_dp(x)		((x) == ROCKCHIP_VOP2_EP_DP0 || \
+					 (x) == ROCKCHIP_VOP2_EP_DP1)
+
+#define vop2_output_if_is_edp(x)	((x) == ROCKCHIP_VOP2_EP_EDP0 || \
+					 (x) == ROCKCHIP_VOP2_EP_EDP1)
+
+#define vop2_output_if_is_mipi(x)	((x) == ROCKCHIP_VOP2_EP_MIPI0 || \
+					 (x) == ROCKCHIP_VOP2_EP_MIPI1)
+
+#define vop2_output_if_is_lvds(x)	((x) == ROCKCHIP_VOP2_EP_LVDS0 || \
+					 (x) == ROCKCHIP_VOP2_EP_LVDS1)
+
+#define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
+
 enum vop2_win_regs {
 	VOP2_WIN_ENABLE,
 	VOP2_WIN_FORMAT,
@@ -162,6 +180,23 @@ struct vop2_win_data {
 	const u8 dly[VOP2_DLY_MODE_MAX];
 };
 
+struct vop2_win {
+	struct vop2 *vop2;
+	struct drm_plane base;
+	const struct vop2_win_data *data;
+	struct regmap_field *reg[VOP2_WIN_MAX_REG];
+
+	/**
+	 * @win_id: graphic window id, a cluster may be split into two
+	 * graphics windows.
+	 */
+	u8 win_id;
+	u8 delay;
+	u32 offset;
+
+	enum drm_plane_type type;
+};
+
 struct vop2_video_port_data {
 	unsigned int id;
 	u32 feature;
@@ -172,20 +207,105 @@ struct vop2_video_port_data {
 	unsigned int offset;
 };
 
+struct vop2_video_port {
+	struct drm_crtc crtc;
+	struct vop2 *vop2;
+	struct clk *dclk;
+	unsigned int id;
+	const struct vop2_video_port_data *data;
+
+	struct completion dsp_hold_completion;
+
+	/**
+	 * @win_mask: Bitmask of windows attached to the video port;
+	 */
+	u32 win_mask;
+
+	struct vop2_win *primary_plane;
+	struct drm_pending_vblank_event *event;
+
+	unsigned int nlayers;
+};
+
+/**
+ * struct vop2_ops - helper operations for vop2 hardware
+ *
+ * These hooks are used by the common part of the vop2 driver to
+ * implement the proper behaviour of different variants.
+ */
+struct vop2_ops {
+	unsigned long (*setup_intf_mux)(struct vop2_video_port *vp, int ep_id, u32 polflags);
+	void (*setup_bg_dly)(struct vop2_video_port *vp);
+	void (*setup_overlay)(struct vop2_video_port *vp);
+};
+
 struct vop2_data {
 	u8 nr_vps;
 	u64 feature;
+	const struct vop2_ops *ops;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
+	const struct reg_field *cluster_reg;
+	const struct reg_field *smart_reg;
 	const struct vop2_regs_dump *regs_dump;
 	struct vop_rect max_input;
 	struct vop_rect max_output;
 
+	unsigned int nr_cluster_regs;
+	unsigned int nr_smart_regs;
 	unsigned int win_size;
 	unsigned int regs_dump_size;
 	unsigned int soc_id;
 };
 
+struct vop2 {
+	struct device *dev;
+	struct drm_device *drm;
+	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
+
+	const struct vop2_data *data;
+	const struct vop2_ops *ops;
+	/*
+	 * Number of windows that are registered as plane, may be less than the
+	 * total number of hardware windows.
+	 */
+	u32 registered_num_wins;
+
+	struct resource *res;
+	void __iomem *regs;
+	struct regmap *map;
+
+	struct regmap *sys_grf;
+	struct regmap *vop_grf;
+	struct regmap *vo1_grf;
+	struct regmap *sys_pmu;
+
+	/* physical map length of vop2 register */
+	u32 len;
+
+	void __iomem *lut_regs;
+
+	/* protects crtc enable/disable */
+	struct mutex vop2_lock;
+
+	int irq;
+
+	/*
+	 * Some global resources are shared between all video ports(crtcs), so
+	 * we need a ref counter here.
+	 */
+	unsigned int enable_count;
+	struct clk *hclk;
+	struct clk *aclk;
+	struct clk *pclk;
+
+	/* optional internal rgb encoder */
+	struct rockchip_rgb *rgb;
+
+	/* must be put at the end of the struct */
+	struct vop2_win win[];
+};
+
 /* interrupt define */
 #define FS_NEW_INTR			BIT(4)
 #define ADDR_SAME_INTR			BIT(5)
@@ -560,4 +680,52 @@ enum vop2_layer_phy_id {
 
 extern const struct component_ops vop2_component_ops;
 
+static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
+{
+	regmap_write(vop2->map, offset, v);
+}
+
+static inline void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
+{
+	regmap_write(vp->vop2->map, vp->data->offset + offset, v);
+}
+
+static inline u32 vop2_readl(struct vop2 *vop2, u32 offset)
+{
+	u32 val;
+
+	regmap_read(vop2->map, offset, &val);
+
+	return val;
+}
+
+static inline u32 vop2_vp_read(struct vop2_video_port *vp, u32 offset)
+{
+	u32 val;
+
+	regmap_read(vp->vop2->map, vp->data->offset + offset, &val);
+
+	return val;
+}
+
+static inline void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
+{
+	regmap_field_write(win->reg[reg], v);
+}
+
+static inline bool vop2_cluster_window(const struct vop2_win *win)
+{
+	return win->data->feature & WIN_FEATURE_CLUSTER;
+}
+
+static inline struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct vop2_video_port, crtc);
+}
+
+static inline struct vop2_win *to_vop2_win(struct drm_plane *p)
+{
+	return container_of(p, struct vop2_win, base);
+}
+
 #endif /* _ROCKCHIP_DRM_VOP2_H */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 65a88f489693..a2e0126a31a0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -9,12 +9,50 @@
 #include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
+#include <drm/drm_blend.h>
 #include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
 #include <drm/drm_plane.h>
 #include <drm/drm_print.h>
 
 #include "rockchip_drm_vop2.h"
 
+union vop2_alpha_ctrl {
+	u32 val;
+	struct {
+		/* [0:1] */
+		u32 color_mode:1;
+		u32 alpha_mode:1;
+		/* [2:3] */
+		u32 blend_mode:2;
+		u32 alpha_cal_mode:1;
+		/* [5:7] */
+		u32 factor_mode:3;
+		/* [8:9] */
+		u32 alpha_en:1;
+		u32 src_dst_swap:1;
+		u32 reserved:6;
+		/* [16:23] */
+		u32 glb_alpha:8;
+	} bits;
+};
+
+struct vop2_alpha {
+	union vop2_alpha_ctrl src_color_ctrl;
+	union vop2_alpha_ctrl dst_color_ctrl;
+	union vop2_alpha_ctrl src_alpha_ctrl;
+	union vop2_alpha_ctrl dst_alpha_ctrl;
+};
+
+struct vop2_alpha_config {
+	bool src_premulti_en;
+	bool dst_premulti_en;
+	bool src_pixel_alpha_en;
+	bool dst_pixel_alpha_en;
+	u16 src_glb_alpha_value;
+	u16 dst_glb_alpha_value;
+};
+
 static const uint32_t formats_cluster[] = {
 	DRM_FORMAT_XRGB2101010,
 	DRM_FORMAT_XBGR2101010,
@@ -131,6 +169,138 @@ static const uint64_t format_modifiers_afbc[] = {
 	DRM_FORMAT_MOD_INVALID,
 };
 
+static const struct reg_field rk3568_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
+	/* RK3588 only, reserved bit on rk3568*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
+
+	/* cluster regs */
+	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
+	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
+	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
+
+	/* afbc regs */
+	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
+	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
+	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
+	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
+	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
+	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
+	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
+	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
+	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
+	[VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
+};
+
+static const struct reg_field rk3568_vop_smart_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
+	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
+	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	/* RK3588 only, reserved register on rk3568 */
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
+	[VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
+	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
+	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
+	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
+};
+
 static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -647,6 +817,813 @@ static const struct vop2_regs_dump rk3588_regs_dump[] = {
 	},
 };
 
+static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	u32 die, dip;
+
+	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
+	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_RGB0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_RGB |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		if (polflags & POLFLAG_DCLK_INV)
+			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
+		else
+			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
+		break;
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_EDP |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI1:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_LVDS0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_LVDS1:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
+
+	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
+	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
+
+	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
+}
+
+/*
+ * calc the dclk on rk3588
+ * the available div of dclk is 1, 2, 4
+ */
+static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
+{
+	if (child_clk * 4 <= max_dclk)
+		return child_clk * 4;
+	else if (child_clk * 2 <= max_dclk)
+		return child_clk * 2;
+	else if (child_clk <= max_dclk)
+		return child_clk;
+	else
+		return 0;
+}
+
+/*
+ * 4 pixclk/cycle on rk3588
+ * RGB/eDP/HDMI: if_pixclk >= dclk_core
+ * DP: dp_pixclk = dclk_out <= dclk_core
+ * DSI: mipi_pixclk <= dclk_out <= dclk_core
+ */
+static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
+					 int *dclk_core_div, int *dclk_out_div,
+					 int *if_pixclk_div, int *if_dclk_div)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
+	int output_mode = vcstate->output_mode;
+	unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
+	unsigned long dclk_core_rate = v_pixclk >> 2;
+	unsigned long dclk_rate = v_pixclk;
+	unsigned long dclk_out_rate;
+	unsigned long if_pixclk_rate;
+	int K = 1;
+
+	if (vop2_output_if_is_hdmi(id)) {
+		/*
+		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
+		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
+		 */
+		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
+			dclk_rate = dclk_rate >> 1;
+			K = 2;
+		}
+
+		if_pixclk_rate = (dclk_core_rate << 1) / K;
+		/*
+		 * if_dclk_rate = dclk_core_rate / K;
+		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
+		 * *if_dclk_div = dclk_rate / if_dclk_rate;
+		 */
+		*if_pixclk_div = 2;
+		*if_dclk_div = 4;
+	} else if (vop2_output_if_is_edp(id)) {
+		/*
+		 * edp_pixclk = edp_dclk > dclk_core
+		 */
+		if_pixclk_rate = v_pixclk / K;
+		dclk_rate = if_pixclk_rate * K;
+		/*
+		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
+		 * *if_dclk_div = *if_pixclk_div;
+		 */
+		*if_pixclk_div = K;
+		*if_dclk_div = K;
+	} else if (vop2_output_if_is_dp(id)) {
+		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
+			dclk_out_rate = v_pixclk >> 3;
+		else
+			dclk_out_rate = v_pixclk >> 2;
+
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000);
+		if (!dclk_rate) {
+			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld KHZ\n",
+				dclk_out_rate);
+			return 0;
+		}
+		*dclk_out_div = dclk_rate / dclk_out_rate;
+	} else if (vop2_output_if_is_mipi(id)) {
+		if_pixclk_rate = dclk_core_rate / K;
+		/*
+		 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
+		 */
+		dclk_out_rate = if_pixclk_rate;
+		/*
+		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
+		 * we get a little factor here
+		 */
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000);
+		if (!dclk_rate) {
+			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld KHZ\n",
+				dclk_out_rate);
+			return 0;
+		}
+		*dclk_out_div = dclk_rate / dclk_out_rate;
+		/*
+		 * mipi pixclk == dclk_out
+		 */
+		*if_pixclk_div = 1;
+	} else if (vop2_output_if_is_dpi(id)) {
+		dclk_rate = v_pixclk;
+	}
+
+	*dclk_core_div = dclk_rate / dclk_core_rate;
+	*if_pixclk_div = ilog2(*if_pixclk_div);
+	*if_dclk_div = ilog2(*if_dclk_div);
+	*dclk_core_div = ilog2(*dclk_core_div);
+	*dclk_out_div = ilog2(*dclk_out_div);
+
+	drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
+		dclk_rate, *if_pixclk_div, *if_dclk_div);
+
+	return dclk_rate;
+}
+
+/*
+ * MIPI port mux on rk3588:
+ * 0: Video Port2
+ * 1: Video Port3
+ * 3: Video Port 1(MIPI1 only)
+ */
+static u32 rk3588_get_mipi_port_mux(int vp_id)
+{
+	if (vp_id == 1)
+		return 3;
+	else if (vp_id == 3)
+		return 1;
+	else
+		return 0;
+}
+
+static u32 rk3588_get_hdmi_pol(u32 flags)
+{
+	u32 val;
+
+	val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
+	val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
+
+	return val;
+}
+
+static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
+	unsigned long clock;
+	u32 die, dip, div, vp_clk_div, val;
+
+	clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
+				    &if_pixclk_div, &if_dclk_div);
+	if (!clock)
+		return 0;
+
+	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
+	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
+
+	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
+	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
+	div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
+			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
+		val = rk3588_get_hdmi_pol(polflags);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
+		break;
+	case ROCKCHIP_VOP2_EP_HDMI1:
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
+			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
+		val = rk3588_get_hdmi_pol(polflags);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
+		break;
+	case ROCKCHIP_VOP2_EP_EDP1:
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
+		val = rk3588_get_mipi_port_mux(vp->id);
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI1:
+		div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		val = rk3588_get_mipi_port_mux(vp->id);
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
+		break;
+	case ROCKCHIP_VOP2_EP_DP0:
+		die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
+		dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
+		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_DP1:
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
+		dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
+		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
+
+	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
+	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
+	vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
+	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
+
+	return clock;
+}
+
+static bool is_opaque(u16 alpha)
+{
+	return (alpha >> 8) == 0xff;
+}
+
+static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
+			     struct vop2_alpha *alpha)
+{
+	int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
+	int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
+	int src_color_mode = alpha_config->src_premulti_en ?
+				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
+	int dst_color_mode = alpha_config->dst_premulti_en ?
+				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
+
+	alpha->src_color_ctrl.val = 0;
+	alpha->dst_color_ctrl.val = 0;
+	alpha->src_alpha_ctrl.val = 0;
+	alpha->dst_alpha_ctrl.val = 0;
+
+	if (!alpha_config->src_pixel_alpha_en)
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
+	else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
+	else
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
+
+	alpha->src_color_ctrl.bits.alpha_en = 1;
+
+	if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
+		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
+	} else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
+		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
+	} else {
+		alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
+	}
+	alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
+	alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+
+	alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+	alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
+	alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
+	alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
+	alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
+
+	alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
+	alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+	alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
+
+	alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
+		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
+	else
+		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
+	alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
+	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
+}
+
+static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
+{
+	struct vop2_video_port *vp;
+	int used_layer = 0;
+	int i;
+
+	for (i = 0; i < port_id; i++) {
+		vp = &vop2->vps[i];
+		used_layer += hweight32(vp->win_mask);
+	}
+
+	return used_layer;
+}
+
+static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
+{
+	struct vop2_alpha_config alpha_config;
+	struct vop2_alpha alpha;
+	struct drm_plane_state *bottom_win_pstate;
+	bool src_pixel_alpha_en = false;
+	u16 src_glb_alpha_val, dst_glb_alpha_val;
+	u32 offset = 0;
+	bool premulti_en = false;
+	bool swap = false;
+
+	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
+	bottom_win_pstate = main_win->base.state;
+	src_glb_alpha_val = 0;
+	dst_glb_alpha_val = main_win->base.state->alpha;
+
+	if (!bottom_win_pstate->fb)
+		return;
+
+	alpha_config.src_premulti_en = premulti_en;
+	alpha_config.dst_premulti_en = false;
+	alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
+	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
+	alpha_config.src_glb_alpha_value = src_glb_alpha_val;
+	alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
+	vop2_parse_alpha(&alpha_config, &alpha);
+
+	alpha.src_color_ctrl.bits.src_dst_swap = swap;
+
+	switch (main_win->data->phys_id) {
+	case ROCKCHIP_VOP2_CLUSTER0:
+		offset = 0x0;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER1:
+		offset = 0x10;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER2:
+		offset = 0x20;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER3:
+		offset = 0x30;
+		break;
+	}
+
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
+		    alpha.src_color_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
+		    alpha.dst_color_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
+		    alpha.src_alpha_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
+		    alpha.dst_alpha_ctrl.val);
+}
+
+static void vop2_setup_alpha(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_framebuffer *fb;
+	struct vop2_alpha_config alpha_config;
+	struct vop2_alpha alpha;
+	struct drm_plane *plane;
+	int pixel_alpha_en;
+	int premulti_en, gpremulti_en = 0;
+	int mixer_id;
+	u32 offset;
+	bool bottom_layer_alpha_en = false;
+	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
+
+	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		if (plane->state->normalized_zpos == 0 &&
+		    !is_opaque(plane->state->alpha) &&
+		    !vop2_cluster_window(win)) {
+			/*
+			 * If bottom layer have global alpha effect [except cluster layer,
+			 * because cluster have deal with bottom layer global alpha value
+			 * at cluster mix], bottom layer mix need deal with global alpha.
+			 */
+			bottom_layer_alpha_en = true;
+			dst_global_alpha = plane->state->alpha;
+		}
+	}
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+		int zpos = plane->state->normalized_zpos;
+
+		/*
+		 * Need to configure alpha from second layer.
+		 */
+		if (zpos == 0)
+			continue;
+
+		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
+			premulti_en = 1;
+		else
+			premulti_en = 0;
+
+		plane = &win->base;
+		fb = plane->state->fb;
+
+		pixel_alpha_en = fb->format->has_alpha;
+
+		alpha_config.src_premulti_en = premulti_en;
+
+		if (bottom_layer_alpha_en && zpos == 1) {
+			gpremulti_en = premulti_en;
+			/* Cd = Cs + (1 - As) * Cd * Agd */
+			alpha_config.dst_premulti_en = false;
+			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
+			alpha_config.src_glb_alpha_value = plane->state->alpha;
+			alpha_config.dst_glb_alpha_value = dst_global_alpha;
+		} else if (vop2_cluster_window(win)) {
+			/* Mix output data only have pixel alpha */
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = true;
+			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+		} else {
+			/* Cd = Cs + (1 - As) * Cd */
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
+			alpha_config.src_glb_alpha_value = plane->state->alpha;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+		}
+
+		vop2_parse_alpha(&alpha_config, &alpha);
+
+		offset = (mixer_id + zpos - 1) * 0x10;
+		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
+			    alpha.src_color_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
+			    alpha.dst_color_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
+			    alpha.src_alpha_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
+			    alpha.dst_alpha_ctrl.val);
+	}
+
+	if (vp->id == 0) {
+		if (bottom_layer_alpha_en) {
+			/* Transfer pixel alpha to hdr mix */
+			alpha_config.src_premulti_en = gpremulti_en;
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = true;
+			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			vop2_parse_alpha(&alpha_config, &alpha);
+
+			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
+				    alpha.src_color_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
+				    alpha.dst_color_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
+				    alpha.src_alpha_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
+				    alpha.dst_alpha_ctrl.val);
+		} else {
+			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
+		}
+	}
+}
+
+static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_plane *plane;
+	u32 layer_sel = 0;
+	u32 port_sel;
+	u8 layer_id;
+	u8 old_layer_id;
+	u8 layer_sel_id;
+	unsigned int ofs;
+	u32 ovl_ctrl;
+	int i;
+	struct vop2_video_port *vp0 = &vop2->vps[0];
+	struct vop2_video_port *vp1 = &vop2->vps[1];
+	struct vop2_video_port *vp2 = &vop2->vps[2];
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
+
+	ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
+	ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
+	if (vcstate->yuv_overlay)
+		ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
+	else
+		ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
+
+	vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
+
+	port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
+	port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
+
+	if (vp0->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
+				     vp0->nlayers - 1);
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
+
+	if (vp1->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
+				     (vp0->nlayers + vp1->nlayers - 1));
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
+
+	if (vp2->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
+			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
+
+	layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
+
+	ofs = 0;
+	for (i = 0; i < vp->id; i++)
+		ofs += vop2->vps[i].nlayers;
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+		struct vop2_win *old_win;
+
+		layer_id = (u8)(plane->state->normalized_zpos + ofs);
+		/*
+		 * Find the layer this win bind in old state.
+		 */
+		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
+			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
+			if (layer_sel_id == win->data->layer_sel_id)
+				break;
+		}
+
+		/*
+		 * Find the win bind to this layer in old state
+		 */
+		for (i = 0; i < vop2->data->win_size; i++) {
+			old_win = &vop2->win[i];
+			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
+			if (layer_sel_id == old_win->data->layer_sel_id)
+				break;
+		}
+
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_CLUSTER0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER2:
+			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER3:
+			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART2:
+			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART3:
+			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
+			break;
+		case ROCKCHIP_VOP2_SMART0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_SMART1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
+			break;
+		}
+
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
+		/*
+		 * When we bind a window from layerM to layerN, we also need to move the old
+		 * window on layerN to layerM to avoid one window selected by two or more layers.
+		 */
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
+	}
+
+	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
+	vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
+}
+
+static void rk3568_vop2_setup_dly_for_windows(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct vop2_win *win;
+	int i = 0;
+	u32 cdly = 0, sdly = 0;
+
+	for (i = 0; i < vop2->data->win_size; i++) {
+		u32 dly;
+
+		win = &vop2->win[i];
+		dly = win->delay;
+
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_CLUSTER0:
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER1:
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
+			break;
+		case ROCKCHIP_VOP2_ESMART0:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
+			break;
+		case ROCKCHIP_VOP2_ESMART1:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
+			break;
+		case ROCKCHIP_VOP2_SMART0:
+		case ROCKCHIP_VOP2_ESMART2:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
+			break;
+		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART3:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
+			break;
+		}
+	}
+
+	vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
+	vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
+}
+
+static void rk3568_vop2_setup_overlay(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_plane *plane;
+
+	vp->win_mask = 0;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
+
+		vp->win_mask |= BIT(win->data->phys_id);
+
+		if (vop2_cluster_window(win))
+			vop2_setup_cluster_alpha(vop2, win);
+	}
+
+	if (!vp->win_mask)
+		return;
+
+	rk3568_vop2_setup_layer_mixer(vp);
+	vop2_setup_alpha(vp);
+	rk3568_vop2_setup_dly_for_windows(vp);
+}
+
+static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
+{
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	u16 hdisplay = mode->crtc_hdisplay;
+	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+	u32 bg_dly;
+	u32 pre_scan_dly;
+
+	bg_dly = vp->data->pre_scan_max_dly[3];
+	vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
+		    FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
+
+	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
+	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+}
+
+static const struct vop2_ops rk3568_vop_ops = {
+	.setup_intf_mux = rk3568_set_intf_mux,
+	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
+	.setup_overlay = rk3568_vop2_setup_overlay,
+};
+
+static const struct vop2_ops rk3588_vop_ops = {
+	.setup_intf_mux = rk3588_set_intf_mux,
+	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
+	.setup_overlay = rk3568_vop2_setup_overlay,
+};
+
 static const struct vop2_data rk3566_vop = {
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
@@ -655,8 +1632,13 @@ static const struct vop2_data rk3566_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3568_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
+	.ops = &rk3568_vop_ops,
 	.soc_id = 3566,
 };
 
@@ -668,8 +1650,13 @@ static const struct vop2_data rk3568_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3568_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
+	.ops = &rk3568_vop_ops,
 	.soc_id = 3568,
 };
 
@@ -682,8 +1669,13 @@ static const struct vop2_data rk3588_vop = {
 	.vp = rk3588_vop_video_ports,
 	.win = rk3588_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3588_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
+	.ops = &rk3588_vop_ops,
 	.soc_id = 3588,
 };
 
-- 
2.34.1



From andyshrk at 163.com  Sat Dec 14 00:19:28 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 14 Dec 2024 16:19:28 +0800
Subject: [PATCH v6 16/16] drm/rockchip: vop2: Add support for rk3576
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <20241214081929.3330919-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

VOP2 on rk3576:
Three video ports:
VP0 Max 4096x2160
VP1 Max 2560x1600
VP2 Max 1920x1080

2 4K Cluster windows with AFBC/RFBC, line RGB and YUV
4 Esmart windows with line RGB/YUV support:
Esmart0/1: 4K
Esmart2/3: 2k, or worked together as a single 4K plane at shared
line buffer mode.

Compared to the previous VOP, another difference is that each VP
has its own independent vsync interrupt number.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

Changes in v6:
-  More specific explanation about the AXI_BUS_ID register bit of
   cluster window.

Changes in v5:
- Add axi id configuration
- Remove the non-existent CBCR scale register.

Changes in v3:
- Share the alpha setup function with rk3568
- recoder the code block by soc

Changes in v2:
- Add platform specific callback

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 144 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  87 ++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 950 +++++++++++++++++--
 3 files changed, 1056 insertions(+), 125 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0ddfafa3c208..e6327879b6b7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1276,6 +1276,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
 	}
 
+	if (vop2->version >= VOP_VERSION_RK3576)
+		vop2_win_write(win, VOP2_WIN_VP_SEL, vp->id);
+
 	if (vop2_cluster_window(win))
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
@@ -1340,6 +1343,11 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
 
+		if (vop2->version >= VOP_VERSION_RK3576) {
+			vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET_EN, 1);
+			vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET, yrgb_mst);
+		}
+
 		transform_offset = vop2_afbc_transform_offset(pstate, half_block_en);
 		vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
 		vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
@@ -2118,6 +2126,56 @@ static const struct drm_crtc_funcs vop2_crtc_funcs = {
 	.late_register = vop2_crtc_late_register,
 };
 
+static irqreturn_t rk3576_vp_isr(int irq, void *data)
+{
+	struct vop2_video_port *vp = data;
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	uint32_t irqs;
+	int ret = IRQ_NONE;
+
+	/*
+	 * The irq is shared with the iommu. If the runtime-pm state of the
+	 * vop2-device is disabled the irq has to be targeted at the iommu.
+	 */
+	if (!pm_runtime_get_if_in_use(vop2->dev))
+		return IRQ_NONE;
+
+	irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
+	vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
+
+	if (irqs & VP_INT_DSP_HOLD_VALID) {
+		complete(&vp->dsp_hold_completion);
+		ret = IRQ_HANDLED;
+	}
+
+	if (irqs & VP_INT_FS_FIELD) {
+		drm_crtc_handle_vblank(crtc);
+		spin_lock(&crtc->dev->event_lock);
+		if (vp->event) {
+			u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
+
+			if (!(val & BIT(vp->id))) {
+				drm_crtc_send_vblank_event(crtc, vp->event);
+				vp->event = NULL;
+				drm_crtc_vblank_put(crtc);
+			}
+		}
+		spin_unlock(&crtc->dev->event_lock);
+
+		ret = IRQ_HANDLED;
+	}
+
+	if (irqs & VP_INT_POST_BUF_EMPTY) {
+		drm_err_ratelimited(vop2->drm, "POST_BUF_EMPTY irq err at vp%d\n", vp->id);
+		ret = IRQ_HANDLED;
+	}
+
+	pm_runtime_put(vop2->dev);
+
+	return ret;
+}
+
 static irqreturn_t vop2_isr(int irq, void *data)
 {
 	struct vop2 *vop2 = data;
@@ -2133,41 +2191,43 @@ static irqreturn_t vop2_isr(int irq, void *data)
 	if (!pm_runtime_get_if_in_use(vop2->dev))
 		return IRQ_NONE;
 
-	for (i = 0; i < vop2_data->nr_vps; i++) {
-		struct vop2_video_port *vp = &vop2->vps[i];
-		struct drm_crtc *crtc = &vp->crtc;
-		u32 irqs;
+	if (vop2->version < VOP_VERSION_RK3576) {
+		for (i = 0; i < vop2_data->nr_vps; i++) {
+			struct vop2_video_port *vp = &vop2->vps[i];
+			struct drm_crtc *crtc = &vp->crtc;
+			u32 irqs;
 
-		irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
-		vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
+			irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
+			vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
 
-		if (irqs & VP_INT_DSP_HOLD_VALID) {
-			complete(&vp->dsp_hold_completion);
-			ret = IRQ_HANDLED;
-		}
-
-		if (irqs & VP_INT_FS_FIELD) {
-			drm_crtc_handle_vblank(crtc);
-			spin_lock(&crtc->dev->event_lock);
-			if (vp->event) {
-				u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
+			if (irqs & VP_INT_DSP_HOLD_VALID) {
+				complete(&vp->dsp_hold_completion);
+				ret = IRQ_HANDLED;
+			}
 
-				if (!(val & BIT(vp->id))) {
-					drm_crtc_send_vblank_event(crtc, vp->event);
-					vp->event = NULL;
-					drm_crtc_vblank_put(crtc);
+			if (irqs & VP_INT_FS_FIELD) {
+				drm_crtc_handle_vblank(crtc);
+				spin_lock(&crtc->dev->event_lock);
+				if (vp->event) {
+					u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
+
+					if (!(val & BIT(vp->id))) {
+						drm_crtc_send_vblank_event(crtc, vp->event);
+						vp->event = NULL;
+						drm_crtc_vblank_put(crtc);
+					}
 				}
-			}
-			spin_unlock(&crtc->dev->event_lock);
+				spin_unlock(&crtc->dev->event_lock);
 
-			ret = IRQ_HANDLED;
-		}
+				ret = IRQ_HANDLED;
+			}
 
-		if (irqs & VP_INT_POST_BUF_EMPTY) {
-			drm_err_ratelimited(vop2->drm,
-					    "POST_BUF_EMPTY irq err at vp%d\n",
-					    vp->id);
-			ret = IRQ_HANDLED;
+			if (irqs & VP_INT_POST_BUF_EMPTY) {
+				drm_err_ratelimited(vop2->drm,
+						    "POST_BUF_EMPTY irq err at vp%d\n",
+						    vp->id);
+				ret = IRQ_HANDLED;
+			}
 		}
 	}
 
@@ -2659,6 +2719,32 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 	if (ret)
 		return ret;
 
+	if (vop2->version >= VOP_VERSION_RK3576) {
+		struct drm_crtc *crtc;
+
+		drm_for_each_crtc(crtc, drm) {
+			struct vop2_video_port *vp = to_vop2_video_port(crtc);
+			int vp_irq;
+			const char *irq_name = devm_kasprintf(dev, GFP_KERNEL, "vop-vp%d", vp->id);
+
+			if (!irq_name)
+				return -ENOMEM;
+
+			vp_irq = platform_get_irq_byname(pdev, irq_name);
+			if (vp_irq < 0) {
+				DRM_DEV_ERROR(dev, "cannot find irq for vop2 vp%d\n", vp->id);
+				return vp_irq;
+			}
+
+			ret = devm_request_irq(dev, vp_irq, rk3576_vp_isr, IRQF_SHARED, irq_name,
+					       vp);
+			if (ret) {
+				DRM_DEV_ERROR(dev, "request irq for vop2 vp%d failed\n", vp->id);
+				return ret;
+			}
+		}
+	}
+
 	ret = vop2_find_rgb_encoder(vop2);
 	if (ret >= 0) {
 		vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 3c9caf13749d..ca3f1613d51c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -44,6 +44,13 @@ enum win_dly_mode {
 	VOP2_DLY_MODE_MAX,
 };
 
+enum vop2_dly_module {
+	VOP2_DLY_WIN,           /** Win delay cycle for this VP */
+	VOP2_DLY_LAYER_MIX,     /** Layer Mix delay cycle for this VP */
+	VOP2_DLY_HDR_MIX,       /** HDR delay cycle for this VP */
+	VOP2_DLY_MAX,
+};
+
 enum vop2_scale_up_mode {
 	VOP2_SCALE_UP_NRST_NBOR,
 	VOP2_SCALE_UP_BIL,
@@ -140,16 +147,22 @@ enum vop2_win_regs {
 	VOP2_WIN_AFBC_UV_SWAP,
 	VOP2_WIN_AFBC_AUTO_GATING_EN,
 	VOP2_WIN_AFBC_BLOCK_SPLIT_EN,
+	VOP2_WIN_AFBC_PLD_OFFSET_EN,
 	VOP2_WIN_AFBC_PIC_VIR_WIDTH,
 	VOP2_WIN_AFBC_TILE_NUM,
 	VOP2_WIN_AFBC_PIC_OFFSET,
 	VOP2_WIN_AFBC_PIC_SIZE,
 	VOP2_WIN_AFBC_DSP_OFFSET,
+	VOP2_WIN_AFBC_PLD_OFFSET,
 	VOP2_WIN_AFBC_TRANSFORM_OFFSET,
 	VOP2_WIN_AFBC_HDR_PTR,
 	VOP2_WIN_AFBC_HALF_BLOCK_EN,
 	VOP2_WIN_AFBC_ROTATE_270,
 	VOP2_WIN_AFBC_ROTATE_90,
+
+	VOP2_WIN_VP_SEL,
+	VOP2_WIN_DLY_NUM,
+
 	VOP2_WIN_MAX_REG,
 };
 
@@ -215,6 +228,10 @@ struct vop2_video_port_data {
 	struct vop_rect max_output;
 	const u8 pre_scan_max_dly[4];
 	unsigned int offset;
+	/**
+	 * @pixel_rate: pixel per cycle
+	 */
+	u8 pixel_rate;
 };
 
 struct vop2_video_port {
@@ -372,10 +389,13 @@ enum dst_factor_mode {
 #define RK3568_REG_CFG_DONE			0x000
 #define RK3568_VERSION_INFO			0x004
 #define RK3568_SYS_AUTO_GATING_CTRL		0x008
+#define RK3576_SYS_MMU_CTRL_IMD			0x020
 #define RK3568_SYS_AXI_LUT_CTRL			0x024
 #define RK3568_DSP_IF_EN			0x028
+#define RK3576_SYS_PORT_CTRL_IMD		0x028
 #define RK3568_DSP_IF_CTRL			0x02c
 #define RK3568_DSP_IF_POL			0x030
+#define RK3576_SYS_CLUSTER_PD_CTRL_IMD		0x030
 #define RK3588_SYS_PD_CTRL			0x034
 #define RK3568_WB_CTRL				0x40
 #define RK3568_WB_XSCAL_FACTOR			0x44
@@ -395,6 +415,55 @@ enum dst_factor_mode {
 #define RK3568_VP_INT_CLR(vp)			(0xA4 + (vp) * 0x10)
 #define RK3568_VP_INT_STATUS(vp)		(0xA8 + (vp) * 0x10)
 #define RK3568_VP_INT_RAW_STATUS(vp)		(0xAC + (vp) * 0x10)
+#define RK3576_WB_CTRL				0x100
+#define RK3576_WB_XSCAL_FACTOR			0x104
+#define RK3576_WB_YRGB_MST			0x108
+#define RK3576_WB_CBR_MST			0x10C
+#define RK3576_WB_VIR_STRIDE			0x110
+#define RK3576_WB_TIMEOUT_CTRL			0x114
+#define RK3576_MIPI0_IF_CTRL			0x180
+#define RK3576_HDMI0_IF_CTRL			0x184
+#define RK3576_EDP0_IF_CTRL			0x188
+#define RK3576_DP0_IF_CTRL			0x18C
+#define RK3576_RGB_IF_CTRL			0x194
+#define RK3576_DP1_IF_CTRL			0x1A4
+#define RK3576_DP2_IF_CTRL			0x1B0
+
+/* Extra OVL register definition */
+#define RK3576_SYS_EXTRA_ALPHA_CTRL		0x500
+#define RK3576_CLUSTER0_MIX_SRC_COLOR_CTRL	0x530
+#define RK3576_CLUSTER0_MIX_DST_COLOR_CTRL	0x534
+#define RK3576_CLUSTER0_MIX_SRC_ALPHA_CTRL	0x538
+#define RK3576_CLUSTER0_MIX_DST_ALPHA_CTRL	0x53c
+#define RK3576_CLUSTER1_MIX_SRC_COLOR_CTRL	0x540
+#define RK3576_CLUSTER1_MIX_DST_COLOR_CTRL	0x544
+#define RK3576_CLUSTER1_MIX_SRC_ALPHA_CTRL	0x548
+#define RK3576_CLUSTER1_MIX_DST_ALPHA_CTRL	0x54c
+
+/* OVL registers for Video Port definition */
+#define RK3576_OVL_CTRL(vp)			(0x600 + (vp) * 0x100)
+#define RK3576_OVL_LAYER_SEL(vp)		(0x604 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_SRC_COLOR_CTRL(vp)	(0x620 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_DST_COLOR_CTRL(vp)	(0x624 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_SRC_ALPHA_CTRL(vp)	(0x628 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_DST_ALPHA_CTRL(vp)	(0x62C + (vp) * 0x100)
+#define RK3576_OVL_MIX1_SRC_COLOR_CTRL(vp)	(0x630 + (vp) * 0x100)
+#define RK3576_OVL_MIX1_DST_COLOR_CTRL(vp)	(0x634 + (vp) * 0x100)
+#define RK3576_OVL_MIX1_SRC_ALPHA_CTRL(vp)	(0x638 + (vp) * 0x100)
+#define RK3576_OVL_MIX1_DST_ALPHA_CTRL(vp)	(0x63C + (vp) * 0x100)
+#define RK3576_OVL_MIX2_SRC_COLOR_CTRL(vp)	(0x640 + (vp) * 0x100)
+#define RK3576_OVL_MIX2_DST_COLOR_CTRL(vp)	(0x644 + (vp) * 0x100)
+#define RK3576_OVL_MIX2_SRC_ALPHA_CTRL(vp)	(0x648 + (vp) * 0x100)
+#define RK3576_OVL_MIX2_DST_ALPHA_CTRL(vp)	(0x64C + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_SRC_COLOR_CTRL(vp)	(0x650 + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_DST_COLOR_CTRL(vp)	(0x654 + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_SRC_ALPHA_CTRL(vp)	(0x658 + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_DST_ALPHA_CTRL(vp)	(0x65C + (vp) * 0x100)
+#define RK3576_OVL_HDR_SRC_COLOR_CTRL(vp)	(0x660 + (vp) * 0x100)
+#define RK3576_OVL_HDR_DST_COLOR_CTRL(vp)	(0x664 + (vp) * 0x100)
+#define RK3576_OVL_HDR_SRC_ALPHA_CTRL(vp)	(0x668 + (vp) * 0x100)
+#define RK3576_OVL_HDR_DST_ALPHA_CTRL(vp)	(0x66C + (vp) * 0x100)
+#define RK3576_OVL_BG_MIX_CTRL(vp)		(0x670 + (vp) * 0x100)
 
 /* Video Port registers definition */
 #define RK3568_VP0_CTRL_BASE			0x0C00
@@ -477,7 +546,11 @@ enum dst_factor_mode {
 #define RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET	0x68
 #define RK3568_CLUSTER_WIN_AFBCD_CTRL		0x6C
 
+#define RK3576_CLUSTER_WIN_AFBCD_PLD_PTR_OFFSET	0x78
+
 #define RK3568_CLUSTER_CTRL			0x100
+#define RK3576_CLUSTER_PORT_SEL_IMD		0x1F4
+#define RK3576_CLUSTER_DLY_NUM			0x1F8
 
 /* (E)smart register definition, offset relative to window base */
 #define RK3568_SMART_CTRL0			0x00
@@ -528,6 +601,9 @@ enum dst_factor_mode {
 #define RK3568_SMART_REGION3_SCL_FACTOR_CBR	0xC8
 #define RK3568_SMART_REGION3_SCL_OFFSET		0xCC
 #define RK3568_SMART_COLOR_KEY_CTRL		0xD0
+#define RK3576_SMART_ALPHA_MAP			0xD8
+#define RK3576_SMART_PORT_SEL_IMD		0xF4
+#define RK3576_SMART_DLY_NUM			0xF8
 
 /* HDR register definition */
 #define RK3568_HDR_LUT_CTRL			0x2000
@@ -676,6 +752,17 @@ enum dst_factor_mode {
 
 #define POLFLAG_DCLK_INV	BIT(3)
 
+#define RK3576_OVL_CTRL__YUV_MODE			BIT(0)
+#define RK3576_OVL_BG_MIX_CTRL__BG_DLY			GENMASK(31, 24)
+
+#define RK3576_DSP_IF_CFG_DONE_IMD			BIT(31)
+#define RK3576_DSP_IF_DCLK_SEL_OUT			BIT(21)
+#define RK3576_DSP_IF_PCLK_DIV				BIT(20)
+#define RK3576_DSP_IF_PIN_POL				GENMASK(5, 4)
+#define RK3576_DSP_IF_MUX				GENMASK(3, 2)
+#define RK3576_DSP_IF_CLK_OUT_EN			BIT(1)
+#define RK3576_DSP_IF_EN				BIT(0)
+
 enum vop2_layer_phy_id {
 	ROCKCHIP_VOP2_CLUSTER0 = 0,
 	ROCKCHIP_VOP2_CLUSTER1,
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 85c15dd396aa..ddcd6a1277f7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -70,6 +70,37 @@ static const uint32_t formats_cluster[] = {
 	DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */
 };
 
+/*
+ * The cluster windows on rk3576 support:
+ * RGB: linear mode and afbc
+ * YUV: linear mode and rfbc
+ * rfbc is a rockchip defined non-linear mode, produced by
+ * Video decoder
+ */
+static const uint32_t formats_rk3576_cluster[] = {
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_ABGR2101010,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
+};
+
 static const uint32_t formats_esmart[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -116,6 +147,41 @@ static const uint32_t formats_rk356x_esmart[] = {
 	DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
 };
 
+/*
+ * Add XRGB2101010/ARGB2101010ARGB1555/XRGB1555
+ */
+static const uint32_t formats_rk3576_esmart[] = {
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_ABGR2101010,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_ABGR1555,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_XBGR1555,
+	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */
+	DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
+	DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */
+	DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */
+};
+
 static const uint32_t formats_smart[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -169,6 +235,48 @@ static const uint64_t format_modifiers_afbc[] = {
 	DRM_FORMAT_MOD_INVALID,
 };
 
+/* used from rk3576, afbc 32*8 half mode */
+static const uint64_t format_modifiers_rk3576_afbc[] = {
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	/* SPLIT mandates SPARSE, RGB modes mandates YTR */
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID,
+};
+
 static const struct reg_field rk3568_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
 	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
@@ -301,6 +409,146 @@ static const struct reg_field rk3568_vop_smart_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
 };
 
+static const struct reg_field rk3576_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 17, 17),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 4),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 9),
+	/* Read only bit on rk3576, writing on this bit have no effect.*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
+
+	[VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_CLUSTER_PORT_SEL_IMD, 0, 1),
+	[VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_CLUSTER_DLY_NUM, 0, 7),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 22, 23),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
+
+	/* cluster regs */
+	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
+	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
+	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
+
+	/* afbc regs */
+	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
+	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
+	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
+	[VOP2_WIN_AFBC_PLD_OFFSET_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 16, 16),
+	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
+	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
+	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
+	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_PLD_OFFSET] = REG_FIELD(RK3576_CLUSTER_WIN_AFBCD_PLD_PTR_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
+	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
+	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
+	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
+};
+
+static const struct reg_field rk3576_vop_smart_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
+	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
+	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_SMART_PORT_SEL_IMD, 0, 1),
+	[VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_SMART_DLY_NUM, 0, 7),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
+	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
+	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
+	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
+
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff }, /* CBCR share the same scale factor as YRGB */
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff},
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff},
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff},
+
+	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
+};
+
 static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -355,98 +603,385 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.layer_sel_id = { 3, 3, 3, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
-		.max_upscale_factor = 8,
-		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Smart1-win0",
+		.phys_id = ROCKCHIP_VOP2_SMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_smart,
+		.nformats = ARRAY_SIZE(formats_smart),
+		.format_modifiers = format_modifiers,
+		.base = 0x1e00,
+		.layer_sel_id = { 7, 7, 7, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Esmart1-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_rk356x_esmart,
+		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
+		.format_modifiers = format_modifiers,
+		.base = 0x1a00,
+		.layer_sel_id = { 6, 6, 6, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Esmart0-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_rk356x_esmart,
+		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
+		.format_modifiers = format_modifiers,
+		.base = 0x1800,
+		.layer_sel_id = { 2, 2, 2, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Cluster0-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
+		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_cluster,
+		.nformats = ARRAY_SIZE(formats_cluster),
+		.format_modifiers = format_modifiers_afbc,
+		.layer_sel_id = { 0, 0, 0, 0xf },
+		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
+					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.dly = { 0, 27, 21 },
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+	}, {
+		.name = "Cluster1-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
+		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_cluster,
+		.nformats = ARRAY_SIZE(formats_cluster),
+		.format_modifiers = format_modifiers_afbc,
+		.layer_sel_id = { 1, 1, 1, 0xf },
+		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
+					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.dly = { 0, 27, 21 },
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+	},
+};
+
+static const struct vop2_regs_dump rk3568_regs_dump[] = {
+	{
+		.name = "SYS",
+		.base = RK3568_REG_CFG_DONE,
+		.size = 0x100,
+		.en_reg  = 0,
+		.en_val = 0,
+		.en_mask = 0
+	}, {
+		.name = "OVL",
+		.base = RK3568_OVL_CTRL,
+		.size = 0x100,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "VP0",
+		.base = RK3568_VP0_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP1",
+		.base = RK3568_VP1_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP2",
+		.base = RK3568_VP2_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+
+	}, {
+		.name = "Cluster0",
+		.base = RK3568_CLUSTER0_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster1",
+		.base = RK3568_CLUSTER1_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Esmart0",
+		.base = RK3568_ESMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart1",
+		.base = RK3568_ESMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart0",
+		.base = RK3568_SMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart1",
+		.base = RK3568_SMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	},
+};
+
+static const struct vop2_video_port_data rk3576_vop_video_ports[] = {
+	{
+		.id = 0,
+		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
+		.gamma_lut_len = 1024,
+		.cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
+		.max_output = { 4096, 2304 },
+		/* win layer_mix hdr  */
+		.pre_scan_max_dly = { 10, 8, 2, 0 },
+		.offset = 0xc00,
+		.pixel_rate = 2,
+	}, {
+		.id = 1,
+		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
+		.gamma_lut_len = 1024,
+		.cubic_lut_len = 729, /* 9x9x9 */
+		.max_output = { 2560, 1600 },
+		/* win layer_mix hdr  */
+		.pre_scan_max_dly = { 10, 6, 0, 0 },
+		.offset = 0xd00,
+		.pixel_rate = 1,
+	}, {
+		.id = 2,
+		.gamma_lut_len = 1024,
+		.max_output = { 1920, 1080 },
+		/* win layer_mix hdr  */
+		.pre_scan_max_dly = { 10, 6, 0, 0 },
+		.offset = 0xe00,
+		.pixel_rate = 1,
+	},
+};
+
+/*
+ * rk3576 vop with 2 cluster, 4 esmart win.
+ * Every cluster can work as 4K win or split into two 2K win.
+ * All win in cluster support AFBCD.
+ *
+ * Every esmart win support 4 Multi-region.
+ *
+ * VP0 can use Cluster0/1 and Esmart0/2
+ * VP1 can use Cluster0/1 and Esmart1/3
+ * VP2 can use Esmart0/1/2/3
+ *
+ * Scale filter mode:
+ *
+ * * Cluster:
+ * * Support prescale down:
+ * * H/V: gt2/avg2 or gt4/avg4
+ * * After prescale down:
+ *	* nearest-neighbor/bilinear/multi-phase filter for scale up
+ *	* nearest-neighbor/bilinear/multi-phase filter for scale down
+ *
+ * * Esmart:
+ * * Support prescale down:
+ * * H: gt2/avg2 or gt4/avg4
+ * * V: gt2 or gt4
+ * * After prescale down:
+ *	* nearest-neighbor/bilinear/bicubic for scale up
+ *	* nearest-neighbor/bilinear for scale down
+ *
+ * AXI config::
+ *
+ * * Cluster0 win0: 0xa,  0xb       [AXI0]
+ * * Cluster0 win1: 0xc,  0xd       [AXI0]
+ * * Cluster1 win0: 0x6,  0x7       [AXI0]
+ * * Cluster1 win1: 0x8,  0x9       [AXI0]
+ * * Esmart0:       0x10, 0x11      [AXI0]
+ * * Esmart1:       0x12, 0x13      [AXI0]
+ * * Esmart2:       0xa,  0xb       [AXI1]
+ * * Esmart3:       0xc,  0xd       [AXI1]
+ * * Lut dma rid:   0x1,  0x2,  0x3 [AXI0]
+ * * DCI dma rid:   0x4             [AXI0]
+ * * Metadata rid:  0x5             [AXI0]
+ *
+ * * Limit:
+ * * (1) Cluster0/1 are fixed on AXI0 by IC design
+ * * (2) 0x0 and 0xf can't be used;
+ * * (3) 5 Bits ID for eache axi bus
+ * * (3) cluster and lut/dci/metadata rid must smaller than 0xf,
+ * *     if Cluster rid is bigger than 0xf, VOP will dead at the
+ * *     system bandwidth very terrible scene.
+ */
+static const struct vop2_win_data rk3576_vop_win_data[] = {
+	{
+		.name = "Cluster0-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
+		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1),
+		.formats = formats_rk3576_cluster,
+		.nformats = ARRAY_SIZE(formats_rk3576_cluster),
+		.format_modifiers = format_modifiers_rk3576_afbc,
+		.layer_sel_id = { 0, 0, 0xf, 0xf },
+		.supported_rotations =  DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0xa,
+		.axi_uv_r_id = 0xb,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
 	}, {
-		.name = "Smart1-win0",
-		.phys_id = ROCKCHIP_VOP2_SMART1,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_smart,
-		.nformats = ARRAY_SIZE(formats_smart),
+		.name = "Cluster1-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
+		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1),
+		.formats = formats_rk3576_cluster,
+		.nformats = ARRAY_SIZE(formats_rk3576_cluster),
+		.format_modifiers = format_modifiers_rk3576_afbc,
+		.layer_sel_id = { 1, 1, 0xf, 0xf },
+		.supported_rotations =  DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+	}, {
+		.name = "Esmart0-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.base = 0x1800,
+		.possible_vp_mask = BIT(0) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
 		.format_modifiers = format_modifiers,
-		.base = 0x1e00,
-		.layer_sel_id = { 7, 7, 7, 0xf },
+		.layer_sel_id = { 2, 0xf, 0, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
-		.type = DRM_PLANE_TYPE_PRIMARY,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x10,
+		.axi_uv_r_id = 0x11,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
 	}, {
 		.name = "Esmart1-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART1,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_rk356x_esmart,
-		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
-		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = { 6, 6, 6, 0xf },
+		.possible_vp_mask = BIT(1) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
+		.format_modifiers = format_modifiers,
+		.layer_sel_id = { 0xf, 2, 1, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
-		.type = DRM_PLANE_TYPE_PRIMARY,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x12,
+		.axi_uv_r_id = 0x13,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
 	}, {
-		.name = "Esmart0-win0",
-		.phys_id = ROCKCHIP_VOP2_ESMART0,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_rk356x_esmart,
-		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
+		.name = "Esmart2-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART2,
+		.base = 0x1c00,
+		.possible_vp_mask = BIT(0) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
 		.format_modifiers = format_modifiers,
-		.base = 0x1800,
-		.layer_sel_id = { 2, 2, 2, 0xf },
+		.layer_sel_id = { 3, 0xf, 2, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
-		.type = DRM_PLANE_TYPE_PRIMARY,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
-	}, {
-		.name = "Cluster0-win0",
-		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
-		.base = 0x1000,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_cluster,
-		.nformats = ARRAY_SIZE(formats_cluster),
-		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = { 0, 0, 0, 0xf },
-		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
-					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
-		.max_upscale_factor = 4,
-		.max_downscale_factor = 4,
-		.dly = { 0, 27, 21 },
-		.type = DRM_PLANE_TYPE_OVERLAY,
-		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
 	}, {
-		.name = "Cluster1-win0",
-		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
-		.base = 0x1200,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_cluster,
-		.nformats = ARRAY_SIZE(formats_cluster),
-		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = { 1, 1, 1, 0xf },
-		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
-					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.name = "Esmart3-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART3,
+		.base = 0x1e00,
+		.possible_vp_mask = BIT(1) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
+		.format_modifiers = format_modifiers,
+		.layer_sel_id = { 0xf, 3, 3, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
-		.max_upscale_factor = 4,
-		.max_downscale_factor = 4,
-		.dly = { 0, 27, 21 },
-		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x0d,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
 	},
 };
 
-static const struct vop2_regs_dump rk3568_regs_dump[] = {
+static const struct vop2_regs_dump rk3576_regs_dump[] = {
 	{
 		.name = "SYS",
 		.base = RK3568_REG_CFG_DONE,
-		.size = 0x100,
+		.size = 0x200,
 		.en_reg  = 0,
 		.en_val = 0,
 		.en_mask = 0
 	}, {
-		.name = "OVL",
-		.base = RK3568_OVL_CTRL,
-		.size = 0x100,
+		.name = "OVL_SYS",
+		.base = RK3576_SYS_EXTRA_ALPHA_CTRL,
+		.size = 0x50,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "OVL_VP0",
+		.base = RK3576_OVL_CTRL(0),
+		.size = 0x80,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "OVL_VP1",
+		.base = RK3576_OVL_CTRL(1),
+		.size = 0x80,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "OVL_VP2",
+		.base = RK3576_OVL_CTRL(2),
+		.size = 0x80,
 		.en_reg = 0,
 		.en_val = 0,
 		.en_mask = 0,
@@ -471,18 +1006,17 @@ static const struct vop2_regs_dump rk3568_regs_dump[] = {
 		.en_reg = RK3568_VP_DSP_CTRL,
 		.en_val = 0,
 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
-
 	}, {
 		.name = "Cluster0",
 		.base = RK3568_CLUSTER0_CTRL_BASE,
-		.size = 0x110,
+		.size = 0x200,
 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
 	}, {
 		.name = "Cluster1",
 		.base = RK3568_CLUSTER1_CTRL_BASE,
-		.size = 0x110,
+		.size = 0x200,
 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
@@ -501,15 +1035,15 @@ static const struct vop2_regs_dump rk3568_regs_dump[] = {
 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 	}, {
-		.name = "Smart0",
-		.base = RK3568_SMART0_CTRL_BASE,
+		.name = "Esmart2",
+		.base = RK3588_ESMART2_CTRL_BASE,
 		.size = 0xf0,
 		.en_reg = RK3568_SMART_REGION0_CTRL,
 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 	}, {
-		.name = "Smart1",
-		.base = RK3568_SMART1_CTRL_BASE,
+		.name = "Esmart3",
+		.base = RK3588_ESMART3_CTRL_BASE,
 		.size = 0xf0,
 		.en_reg = RK3568_SMART_REGION0_CTRL,
 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
@@ -908,6 +1442,84 @@ static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32
 	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
 }
 
+static unsigned long rk3576_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
+	u8 port_pix_rate = vp->data->pixel_rate;
+	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_sel;
+	u32 ctrl, vp_clk_div, reg, dclk_div;
+	unsigned long dclk_in_rate, dclk_core_rate;
+
+	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420 || adjusted_mode->crtc_clock > 600000)
+		dclk_div = 2;
+	else
+		dclk_div = 1;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
+		dclk_core_rate = adjusted_mode->crtc_clock / 2;
+	else
+		dclk_core_rate = adjusted_mode->crtc_clock / port_pix_rate;
+
+	dclk_in_rate = adjusted_mode->crtc_clock / dclk_div;
+
+	dclk_core_div = dclk_in_rate > dclk_core_rate ? 1 : 0;
+
+	if (vop2_output_if_is_edp(id))
+		if_pixclk_div = port_pix_rate == 2 ? RK3576_DSP_IF_PCLK_DIV : 0;
+	else
+		if_pixclk_div = port_pix_rate == 1 ? RK3576_DSP_IF_PCLK_DIV : 0;
+
+	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420) {
+		if_dclk_sel = RK3576_DSP_IF_DCLK_SEL_OUT;
+		dclk_out_div = 1;
+	} else {
+		if_dclk_sel = 0;
+		dclk_out_div = 0;
+	}
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		reg = RK3576_HDMI0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		reg = RK3576_EDP0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		reg = RK3576_MIPI0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_DP0:
+		reg = RK3576_DP0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_DP1:
+		reg = RK3576_DP1_IF_CTRL;
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	ctrl = vop2_readl(vop2, reg);
+	ctrl &= ~RK3576_DSP_IF_DCLK_SEL_OUT;
+	ctrl &= ~RK3576_DSP_IF_PCLK_DIV;
+	ctrl &= ~RK3576_DSP_IF_MUX;
+	ctrl |= RK3576_DSP_IF_CFG_DONE_IMD;
+	ctrl |= if_dclk_sel | if_pixclk_div;
+	ctrl |= RK3576_DSP_IF_CLK_OUT_EN | RK3576_DSP_IF_EN;
+	ctrl |= FIELD_PREP(RK3576_DSP_IF_MUX, vp->id);
+	ctrl |= FIELD_PREP(RK3576_DSP_IF_PIN_POL, polflags);
+	vop2_writel(vop2, reg, ctrl);
+
+	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
+	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
+
+	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
+
+	return dclk_in_rate * 1000LL;
+}
+
 /*
  * calc the dclk on rk3588
  * the available div of dclk is 1, 2, 4
@@ -1246,6 +1858,7 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi
 	struct drm_plane_state *bottom_win_pstate;
 	bool src_pixel_alpha_en = false;
 	u16 src_glb_alpha_val, dst_glb_alpha_val;
+	u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg;
 	u32 offset = 0;
 	bool premulti_en = false;
 	bool swap = false;
@@ -1283,14 +1896,22 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi
 		break;
 	}
 
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
-		    alpha.src_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
-		    alpha.dst_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
-		    alpha.src_alpha_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
-		    alpha.dst_alpha_ctrl.val);
+	if (vop2->version <= VOP_VERSION_RK3588) {
+		src_color_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL;
+		dst_color_ctrl_reg = RK3568_CLUSTER0_MIX_DST_COLOR_CTRL;
+		src_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL;
+		dst_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL;
+	} else {
+		src_color_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_COLOR_CTRL;
+		dst_color_ctrl_reg = RK3576_CLUSTER0_MIX_DST_COLOR_CTRL;
+		src_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_ALPHA_CTRL;
+		dst_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_DST_ALPHA_CTRL;
+	}
+
+	vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val);
+	vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val);
+	vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val);
+	vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val);
 }
 
 static void vop2_setup_alpha(struct vop2_video_port *vp)
@@ -1303,11 +1924,16 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 	int pixel_alpha_en;
 	int premulti_en, gpremulti_en = 0;
 	int mixer_id;
+	u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg;
 	u32 offset;
 	bool bottom_layer_alpha_en = false;
 	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
 
-	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	if (vop2->version <= VOP_VERSION_RK3588)
+		mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	else
+		mixer_id = 0;
+
 	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
 
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
@@ -1326,6 +1952,18 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 		}
 	}
 
+	if (vop2->version <= VOP_VERSION_RK3588) {
+		src_color_ctrl_reg = RK3568_MIX0_SRC_COLOR_CTRL;
+		dst_color_ctrl_reg = RK3568_MIX0_DST_COLOR_CTRL;
+		src_alpha_ctrl_reg = RK3568_MIX0_SRC_ALPHA_CTRL;
+		dst_alpha_ctrl_reg = RK3568_MIX0_DST_ALPHA_CTRL;
+	} else {
+		src_color_ctrl_reg = RK3576_OVL_MIX0_SRC_COLOR_CTRL(vp->id);
+		dst_color_ctrl_reg = RK3576_OVL_MIX0_DST_COLOR_CTRL(vp->id);
+		src_alpha_ctrl_reg = RK3576_OVL_MIX0_SRC_ALPHA_CTRL(vp->id);
+		dst_alpha_ctrl_reg = RK3576_OVL_MIX0_DST_ALPHA_CTRL(vp->id);
+	}
+
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
 		struct vop2_win *win = to_vop2_win(plane);
 		int zpos = plane->state->normalized_zpos;
@@ -1372,17 +2010,26 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 		vop2_parse_alpha(&alpha_config, &alpha);
 
 		offset = (mixer_id + zpos - 1) * 0x10;
-		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
-			    alpha.src_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
-			    alpha.dst_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
-			    alpha.src_alpha_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
-			    alpha.dst_alpha_ctrl.val);
+
+		vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val);
+		vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val);
+		vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val);
+		vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val);
 	}
 
 	if (vp->id == 0) {
+		if (vop2->version <= VOP_VERSION_RK3588) {
+			src_color_ctrl_reg = RK3568_HDR0_SRC_COLOR_CTRL;
+			dst_color_ctrl_reg = RK3568_HDR0_DST_COLOR_CTRL;
+			src_alpha_ctrl_reg = RK3568_HDR0_SRC_ALPHA_CTRL;
+			dst_alpha_ctrl_reg = RK3568_HDR0_DST_ALPHA_CTRL;
+		} else {
+			src_color_ctrl_reg = RK3576_OVL_HDR_SRC_COLOR_CTRL(vp->id);
+			dst_color_ctrl_reg = RK3576_OVL_HDR_DST_COLOR_CTRL(vp->id);
+			src_alpha_ctrl_reg = RK3576_OVL_HDR_SRC_ALPHA_CTRL(vp->id);
+			dst_alpha_ctrl_reg = RK3576_OVL_HDR_DST_ALPHA_CTRL(vp->id);
+		}
+
 		if (bottom_layer_alpha_en) {
 			/* Transfer pixel alpha to hdr mix */
 			alpha_config.src_premulti_en = gpremulti_en;
@@ -1390,18 +2037,15 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 			alpha_config.src_pixel_alpha_en = true;
 			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
 			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+
 			vop2_parse_alpha(&alpha_config, &alpha);
 
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
-				    alpha.src_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
-				    alpha.dst_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
-				    alpha.src_alpha_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
-				    alpha.dst_alpha_ctrl.val);
+			vop2_writel(vop2, src_color_ctrl_reg, alpha.src_color_ctrl.val);
+			vop2_writel(vop2, dst_color_ctrl_reg, alpha.dst_color_ctrl.val);
+			vop2_writel(vop2, src_alpha_ctrl_reg, alpha.src_alpha_ctrl.val);
+			vop2_writel(vop2, dst_alpha_ctrl_reg, alpha.dst_alpha_ctrl.val);
 		} else {
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
+			vop2_writel(vop2, src_color_ctrl_reg, 0);
 		}
 	}
 }
@@ -1611,6 +2255,72 @@ static void rk3568_vop2_setup_overlay(struct vop2_video_port *vp)
 	rk3568_vop2_setup_dly_for_windows(vp);
 }
 
+static void rk3576_vop2_setup_layer_mixer(struct vop2_video_port *vp)
+{
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_plane *plane;
+	u32 layer_sel = 0xffff; /* 0xf means this layer is disabled */
+	u32 ovl_ctrl;
+
+	ovl_ctrl = vop2_readl(vop2, RK3576_OVL_CTRL(vp->id));
+	if (vcstate->yuv_overlay)
+		ovl_ctrl |= RK3576_OVL_CTRL__YUV_MODE;
+	else
+		ovl_ctrl &= ~RK3576_OVL_CTRL__YUV_MODE;
+
+	vop2_writel(vop2, RK3576_OVL_CTRL(vp->id), ovl_ctrl);
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos,
+							  0xf);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos,
+							 win->data->layer_sel_id[vp->id]);
+	}
+
+	vop2_writel(vop2, RK3576_OVL_LAYER_SEL(vp->id), layer_sel);
+}
+
+static void rk3576_vop2_setup_dly_for_windows(struct vop2_video_port *vp)
+{
+	struct drm_plane *plane;
+	struct vop2_win *win;
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		win = to_vop2_win(plane);
+		vop2_win_write(win, VOP2_WIN_DLY_NUM, 0);
+	}
+}
+
+static void rk3576_vop2_setup_overlay(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_plane *plane;
+
+	vp->win_mask = 0;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
+
+		vp->win_mask |= BIT(win->data->phys_id);
+
+		if (vop2_cluster_window(win))
+			vop2_setup_cluster_alpha(vop2, win);
+	}
+
+	if (!vp->win_mask)
+		return;
+
+	rk3576_vop2_setup_layer_mixer(vp);
+	vop2_setup_alpha(vp);
+	rk3576_vop2_setup_dly_for_windows(vp);
+}
+
 static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
 {
 	struct drm_crtc *crtc = &vp->crtc;
@@ -1628,12 +2338,38 @@ static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
 	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
 }
 
+static void rk3576_vop2_setup_bg_dly(struct vop2_video_port *vp)
+{
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	u16 hdisplay = mode->crtc_hdisplay;
+	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+	u32 bg_dly;
+	u32 pre_scan_dly;
+
+	bg_dly = vp->data->pre_scan_max_dly[VOP2_DLY_WIN] +
+		 vp->data->pre_scan_max_dly[VOP2_DLY_LAYER_MIX] +
+		 vp->data->pre_scan_max_dly[VOP2_DLY_HDR_MIX];
+
+	vop2_writel(vp->vop2, RK3576_OVL_BG_MIX_CTRL(vp->id),
+		    FIELD_PREP(RK3576_OVL_BG_MIX_CTRL__BG_DLY, bg_dly));
+
+	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
+	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+}
+
 static const struct vop2_ops rk3568_vop_ops = {
 	.setup_intf_mux = rk3568_set_intf_mux,
 	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
 	.setup_overlay = rk3568_vop2_setup_overlay,
 };
 
+static const struct vop2_ops rk3576_vop_ops = {
+	.setup_intf_mux = rk3576_set_intf_mux,
+	.setup_bg_dly = rk3576_vop2_setup_bg_dly,
+	.setup_overlay = rk3576_vop2_setup_overlay,
+};
+
 static const struct vop2_ops rk3588_vop_ops = {
 	.setup_intf_mux = rk3588_set_intf_mux,
 	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
@@ -1678,6 +2414,25 @@ static const struct vop2_data rk3568_vop = {
 	.soc_id = 3568,
 };
 
+static const struct vop2_data rk3576_vop = {
+	.version = VOP_VERSION_RK3576,
+	.feature = VOP2_FEATURE_HAS_SYS_PMU,
+	.nr_vps = 3,
+	.max_input = { 4096, 4320 },
+	.max_output = { 4096, 4320 },
+	.vp = rk3576_vop_video_ports,
+	.win = rk3576_vop_win_data,
+	.win_size = ARRAY_SIZE(rk3576_vop_win_data),
+	.cluster_reg = rk3576_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3576_vop_cluster_regs),
+	.smart_reg = rk3576_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3576_vop_smart_regs),
+	.regs_dump = rk3576_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3576_regs_dump),
+	.ops = &rk3576_vop_ops,
+	.soc_id = 3576,
+};
+
 static const struct vop2_data rk3588_vop = {
 	.version = VOP_VERSION_RK3588,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
@@ -1705,6 +2460,9 @@ static const struct of_device_id vop2_dt_match[] = {
 	}, {
 		.compatible = "rockchip,rk3568-vop",
 		.data = &rk3568_vop,
+	}, {
+		.compatible = "rockchip,rk3576-vop",
+		.data = &rk3576_vop,
 	}, {
 		.compatible = "rockchip,rk3588-vop",
 		.data = &rk3588_vop
-- 
2.34.1



From zhengqi.arch at bytedance.com  Sat Dec 14 01:02:52 2024
From: zhengqi.arch at bytedance.com (Qi Zheng)
Date: Sat, 14 Dec 2024 17:02:52 +0800
Subject: [PATCH 06/12] arm: pgtable: move pagetable_dtor() to __tlb_remove_table()
In-Reply-To: <cover.1734164094.git.zhengqi.arch@bytedance.com>
References: <cover.1734164094.git.zhengqi.arch@bytedance.com>
Message-ID: <59fd7e0364e8dd293132d81b91b28694e70263e2.1734164094.git.zhengqi.arch@bytedance.com>

Move pagetable_dtor() to __tlb_remove_table(), so that ptlock and page
table pages can be freed together (regardless of whether RCU is used).
This prevents the use-after-free problem where the ptlock is freed
immediately but the page table pages is freed later via RCU.

Page tables shouldn't have swap cache, so use pagetable_free() instead of
free_page_and_swap_cache() to free page table pages.

Signed-off-by: Qi Zheng <zhengqi.arch at bytedance.com>
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/include/asm/tlb.h | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index ef79bf1e8563f..264ab635e807a 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -26,12 +26,14 @@
 
 #else /* !CONFIG_MMU */
 
-#include <linux/swap.h>
 #include <asm/tlbflush.h>
 
 static inline void __tlb_remove_table(void *_table)
 {
-	free_page_and_swap_cache((struct page *)_table);
+	struct ptdesc *ptdesc = (struct ptdesc *)_table;
+
+	pagetable_dtor(ptdesc);
+	pagetable_free(ptdesc);
 }
 
 #include <asm-generic/tlb.h>
@@ -41,8 +43,6 @@ __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long addr)
 {
 	struct ptdesc *ptdesc = page_ptdesc(pte);
 
-	pagetable_dtor(ptdesc);
-
 #ifndef CONFIG_ARM_LPAE
 	/*
 	 * With the classic ARM MMU, a pte page has two corresponding pmd
@@ -61,7 +61,6 @@ __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr)
 #ifdef CONFIG_ARM_LPAE
 	struct ptdesc *ptdesc = virt_to_ptdesc(pmdp);
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 #endif
 }
-- 
2.20.1



From zhengqi.arch at bytedance.com  Sat Dec 14 01:02:49 2024
From: zhengqi.arch at bytedance.com (Qi Zheng)
Date: Sat, 14 Dec 2024 17:02:49 +0800
Subject: [PATCH 03/12] arm64: pgtable: use mmu gather to free p4d level page table
In-Reply-To: <cover.1734164094.git.zhengqi.arch@bytedance.com>
References: <cover.1734164094.git.zhengqi.arch@bytedance.com>
Message-ID: <fd2faee37876dc6ea93d0b8dcd001e13d77c3272.1734164094.git.zhengqi.arch@bytedance.com>

Like other levels of page tables, also use mmu gather mechanism to free
p4d level page table.

Signed-off-by: Qi Zheng <zhengqi.arch at bytedance.com>
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/include/asm/pgalloc.h |  2 --
 arch/arm64/include/asm/tlb.h     | 14 ++++++++++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 679c530549327..58cc260b6bee8 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -100,8 +100,6 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
 	if (pgtable_l5_enabled())
 		__p4d_free(mm, 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)
 {
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index a947c6e784ed2..445282cde9afb 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -111,4 +111,18 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
 }
 #endif
 
+#if CONFIG_PGTABLE_LEVELS > 4
+static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4dp,
+				  unsigned long addr)
+{
+	struct ptdesc *ptdesc = virt_to_ptdesc(p4dp);
+
+	if (!pgtable_l5_enabled())
+		return;
+
+	pagetable_p4d_dtor(ptdesc);
+	tlb_remove_ptdesc(tlb, ptdesc);
+}
+#endif
+
 #endif
-- 
2.20.1



From zhengqi.arch at bytedance.com  Sat Dec 14 01:02:53 2024
From: zhengqi.arch at bytedance.com (Qi Zheng)
Date: Sat, 14 Dec 2024 17:02:53 +0800
Subject: [PATCH 07/12] arm64: pgtable: move pagetable_dtor() to __tlb_remove_table()
In-Reply-To: <cover.1734164094.git.zhengqi.arch@bytedance.com>
References: <cover.1734164094.git.zhengqi.arch@bytedance.com>
Message-ID: <1781d3bab60aade7d64fbeb6682b9e73bd673d3c.1734164094.git.zhengqi.arch@bytedance.com>

Move pagetable_dtor() to __tlb_remove_table(), so that ptlock and page
table pages can be freed together (regardless of whether RCU is used).
This prevents the use-after-free problem where the ptlock is freed
immediately but the page table pages is freed later via RCU.

Page tables shouldn't have swap cache, so use pagetable_free() instead of
free_page_and_swap_cache() to free page table pages.

Signed-off-by: Qi Zheng <zhengqi.arch at bytedance.com>
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/include/asm/tlb.h | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 408d0f36a8a8f..93591a80b5bfb 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -9,11 +9,13 @@
 #define __ASM_TLB_H
 
 #include <linux/pagemap.h>
-#include <linux/swap.h>
 
 static inline void __tlb_remove_table(void *_table)
 {
-	free_page_and_swap_cache((struct page *)_table);
+	struct ptdesc *ptdesc = (struct ptdesc *)_table;
+
+	pagetable_dtor(ptdesc);
+	pagetable_free(ptdesc);
 }
 
 #define tlb_flush tlb_flush
@@ -82,7 +84,6 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 {
 	struct ptdesc *ptdesc = page_ptdesc(pte);
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 }
 
@@ -92,7 +93,6 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
 {
 	struct ptdesc *ptdesc = virt_to_ptdesc(pmdp);
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 }
 #endif
@@ -106,7 +106,6 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
 	if (!pgtable_l4_enabled())
 		return;
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 }
 #endif
@@ -120,7 +119,6 @@ static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4dp,
 	if (!pgtable_l5_enabled())
 		return;
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 }
 #endif
-- 
2.20.1



From ubizjak at gmail.com  Sat Dec 14 01:12:59 2024
From: ubizjak at gmail.com (Uros Bizjak)
Date: Sat, 14 Dec 2024 10:12:59 +0100
Subject: [PATCH v2] mailbox: zynqmp: Remove invalid __percpu annotation in zynqmp_ipi_probe()
Message-ID: <20241214091327.4716-1-ubizjak@gmail.com>

struct zynqmp_ipi_pdata __percpu *pdata is not a per-cpu variable,
so it should not be annotated with __percpu annotation.

Remove invalid __percpu annotation to fix several

zynqmp-ipi-mailbox.c:920:15: warning: incorrect type in assignment (different address spaces)
zynqmp-ipi-mailbox.c:920:15:    expected struct zynqmp_ipi_pdata [noderef] __percpu *pdata
zynqmp-ipi-mailbox.c:920:15:    got void *
zynqmp-ipi-mailbox.c:927:56: warning: incorrect type in argument 3 (different address spaces)
zynqmp-ipi-mailbox.c:927:56:    expected unsigned int [usertype] *out_value
zynqmp-ipi-mailbox.c:927:56:    got unsigned int [noderef] __percpu *
...

and several

drivers/mailbox/zynqmp-ipi-mailbox.c:924:9: warning: dereference of noderef expression
...

sparse warnings.

There were no changes in the resulting object file.

Cc: stable at vger.kernel.org
Fixes: 6ffb1635341b ("mailbox: zynqmp: handle SGI for shared IPI")
Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Cc: Jassi Brar <jassisinghbrar at gmail.com>
Cc: Michal Simek <michal.simek at amd.com>
Cc: Tanmay Shah <tanmay.shah at amd.com>
---
v2: - Fix typo in commit message
    - Add Fixes and Cc: stable.
---
 drivers/mailbox/zynqmp-ipi-mailbox.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index aa5249da59b2..0c143beaafda 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -905,7 +905,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *nc, *np = pdev->dev.of_node;
-	struct zynqmp_ipi_pdata __percpu *pdata;
+	struct zynqmp_ipi_pdata *pdata;
 	struct of_phandle_args out_irq;
 	struct zynqmp_ipi_mbox *mbox;
 	int num_mboxes, ret = -EINVAL;
-- 
2.42.0



From lsahn at ooseel.net  Sat Dec 14 01:19:36 2024
From: lsahn at ooseel.net (Leesoo Ahn)
Date: Sat, 14 Dec 2024 18:19:36 +0900
Subject: [PATCH] arm64: mm: fault: replace the behavior of fault_info[18]
Message-ID: <20241214091937.203842-1-lsahn@ooseel.net>

Replace the behavior of 18th element of fault_info with the 'fn' member to
do_sea(..) and 'name' to 'level -2 (translation table walk)' based on
the information[1] of the latest reference manual[2].

The information has described in the chapter, D24.2.40 of [2] and
DFSC[5:0] bit (stands for Data Fault Status Code).

[1]: Synchronous External abort on translation table walk, level -2
[2]: Arm Architecture Reference Manual, for A-profile architecture

Signed-off-by: Leesoo Ahn <lsahn at ooseel.net>
---
 arch/arm64/mm/fault.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index ef63651099a9..b1c08289a5cc 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -863,7 +863,7 @@ static const struct fault_info fault_info[] = {
 	{ 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_sea,		SIGKILL, SI_KERNEL,	"level -2 (translation table walk)"	},
 	{ 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)"	},
-- 
2.46.1



From lsahn at ooseel.net  Sat Dec 14 01:38:04 2024
From: lsahn at ooseel.net (Leesoo Ahn)
Date: Sat, 14 Dec 2024 18:38:04 +0900
Subject: [PATCH] arm64: mm: fault: replace the behavior of fault_info[18]
In-Reply-To: <20241214091937.203842-1-lsahn@ooseel.net>
References: <20241214091937.203842-1-lsahn@ooseel.net>
Message-ID: <CANTT7qi=wZvOQP4PFEi7300MbNjsJ2q=WXceHch1BUrtL-WFDQ@mail.gmail.com>

I just figured out that do_sea(..) isn't the right function to deal
with VMSAv9-128.
Please ignore this patch.

BR
Leesoo

2024? 12? 14? (?) ?? 6:20, Leesoo Ahn <lsahn at ooseel.net>?? ??:
>
> Replace the behavior of 18th element of fault_info with the 'fn' member to
> do_sea(..) and 'name' to 'level -2 (translation table walk)' based on
> the information[1] of the latest reference manual[2].
>
> The information has described in the chapter, D24.2.40 of [2] and
> DFSC[5:0] bit (stands for Data Fault Status Code).
>
> [1]: Synchronous External abort on translation table walk, level -2
> [2]: Arm Architecture Reference Manual, for A-profile architecture
>
> Signed-off-by: Leesoo Ahn <lsahn at ooseel.net>
> ---
>  arch/arm64/mm/fault.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index ef63651099a9..b1c08289a5cc 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -863,7 +863,7 @@ static const struct fault_info fault_info[] = {
>         { 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_sea,               SIGKILL, SI_KERNEL,     "level -2 (translation table walk)"     },
>         { 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)"      },
> --
> 2.46.1
>


From krzysztof.kozlowski at linaro.org  Sat Dec 14 02:40:08 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 14 Dec 2024 11:40:08 +0100
Subject: [PATCH v4 0/3] clk: samsung: Introduce Exynos990 clock support
In-Reply-To: <20241209-exynos990-cmu-v4-0-57f07080f9e4@mentallysanemainliners.org>
References: <20241209-exynos990-cmu-v4-0-57f07080f9e4@mentallysanemainliners.org>
Message-ID: <173417280888.20557.1392916695437038027.b4-ty@linaro.org>


On Mon, 09 Dec 2024 15:45:20 +0100, Igor Belwon wrote:
> This patchset adds support for the Clock Management Unit found in the
> Exynos990 SoC. This CMU allows for clocking peripherals such as USB, UFS,
> MCT, et cetera.
> 
> Currently there are two blocks implemented, CMU_TOP which
> generates clocks for other blocks, and CMU_HSI0, which generates clocks
> for USB. More blocks will be added (hopefully soon), like HSI1 for UFS.
> 
> [...]

Applied, thanks!

[1/3] dt-bindings: clock: Add Exynos990 SoC CMU bindings
      https://git.kernel.org/krzk/linux/c/5feae3e79dbe2d357b223fc48ae907ba0aedb271
[2/3] clk: samsung: clk-pll: Add support for pll_{0717x, 0718x, 0732x}
      https://git.kernel.org/krzk/linux/c/4a450ed26c580316d720154e7ffb5e9b4763a11a
[3/3] clk: samsung: Introduce Exynos990 clock controller driver
      https://git.kernel.org/krzk/linux/c/bdd03ebf721f70df1458a720b25998a489f63297

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



From krzysztof.kozlowski at linaro.org  Sat Dec 14 02:49:51 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 14 Dec 2024 11:49:51 +0100
Subject: [PATCH v2 0/1] arm64: dts: exynos8895: Add m2-pmu, poweroff
 and reboot
In-Reply-To: <20241211162942.450525-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241211162942.450525-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <173417339174.24605.17029736808266427756.b4-ty@linaro.org>


On Wed, 11 Dec 2024 18:29:41 +0200, Ivaylo Ivanov wrote:
> Hey folks,
> 
> This series adds support for the mongoose cluster PMU in DT hence
> a compatible for that was recently added.
> 
> After this patchset, I'm planning to submit patches for more hardware
> support.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: exynos8895: Add a PMU node for the second cluster
      https://git.kernel.org/krzk/linux/c/8749e19c133e6790254252d6dc4fd16d67f7edee

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



From krzysztof.kozlowski at linaro.org  Sat Dec 14 02:49:53 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 14 Dec 2024 11:49:53 +0100
Subject: [PATCH v2] arm64: dts: exynosautov920: Add DMA nodes
In-Reply-To: <20241212115709.1724-1-faraz.ata@samsung.com>
References: <CGME20241212115815epcas5p29fdba4ddb93d08035f422444cb826ec3@epcas5p2.samsung.com>
 <20241212115709.1724-1-faraz.ata@samsung.com>
Message-ID: <173417339330.24605.2885183556743988867.b4-ty@linaro.org>


On Thu, 12 Dec 2024 17:27:05 +0530, Faraz Ata wrote:
> ExynosAutov920 SoC has 7 DMA controllers. Two secure DMAC
> (SPDMA0 & SPDMA1) and five non-secure DMAC (PDMA0 to PDMA4).
> Add the required dt nodes for the same.
> 
> 

Applied, thanks!

[1/1] arm64: dts: exynosautov920: Add DMA nodes
      https://git.kernel.org/krzk/linux/c/de7a4e01055b040b303d01d709262b7ce9d818ff

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



From maz at kernel.org  Sat Dec 14 02:56:13 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 14 Dec 2024 10:56:13 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to __cpuinfo_store_cpu()
In-Reply-To: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
Message-ID: <87a5cysfci.wl-maz@kernel.org>

[+ Mark]
On Sat, 14 Dec 2024 00:52:08 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> In commit 892f7237b3ff ("arm64: Delay initialisation of
> cpuinfo_arm64::reg_{zcr,smcr}") we moved access to ZCR, SMCR and SMIDR
> later in the boot process in order to ensure that we don't attempt to
> interact with them if SVE or SME is disabled on the command line.
> Unfortunately when initialising the boot CPU in init_cpu_features() we work
> on a copy of the struct cpuinfo_arm64 for the boot CPU used only during
> boot, not the percpu copy used by the sysfs code.
> 
> Fix this by moving the handling for SMIDR_EL1 for the boot CPU to
> cpuinfo_store_boot_cpu() so it can operate on the percpu copy of the data.
> This reduces the potential for error that could come from having both the
> percpu and boot CPU copies in init_cpu_features().
> 
> This issue wasn't apparent when testing on emulated platforms that do not
> report values in this ID register.
> 
> Fixes: 892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")
> Signed-off-by: Mark Brown <broonie at kernel.org>
> Cc: stable at vger.kernel.org
> ---
>  arch/arm64/kernel/cpufeature.c |  6 ------
>  arch/arm64/kernel/cpuinfo.c    | 11 +++++++++++
>  2 files changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 6ce71f444ed84f9056196bb21bbfac61c9687e30..b88102fd2c20f77e25af6df513fda09a484e882e 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1167,12 +1167,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
>  	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
>  		unsigned long cpacr = cpacr_save_enable_kernel_sme();
>  
> -		/*
> -		 * We mask out SMPS since even if the hardware
> -		 * supports priorities the kernel does not at present
> -		 * and we block access to them.
> -		 */
> -		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
>  		vec_init_vq_map(ARM64_VEC_SME);
>  
>  		cpacr_restore(cpacr);
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index d79e88fccdfce427507e7a34c5959ce6309cbd12..b7d403da71e5a01ed3943eb37e7a00af238771a2 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -499,4 +499,15 @@ void __init cpuinfo_store_boot_cpu(void)
>  
>  	boot_cpu_data = *info;
>  	init_cpu_features(&boot_cpu_data);
> +
> +	/* SMIDR_EL1 needs to be stored in the percpu data for sysfs */
> +	if (IS_ENABLED(CONFIG_ARM64_SME) &&
> +	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
> +		/*
> +		 * We mask out SMPS since even if the hardware
> +		 * supports priorities the kernel does not at present
> +		 * and we block access to them.
> +		 */
> +		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
> +	}
>  }

I don't understand the need to single out SMIDR_EL1. It seems to only
make things even more fragile than they already are by adding more
synchronisation phases.

Why isn't the following a good enough fix? It makes it plain that
boot_cpu_data is only a copy of CPU0's initial boot state.

diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index d79e88fccdfce..0cbb42fd48850 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -497,6 +497,6 @@ void __init cpuinfo_store_boot_cpu(void)
 	struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0);
 	__cpuinfo_store_cpu(info);
 
+	init_cpu_features(info);
 	boot_cpu_data = *info;
-	init_cpu_features(&boot_cpu_data);
 }


Thanks,

	M.

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


From dmitry.baryshkov at linaro.org  Sat Dec 14 03:39:35 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 14 Dec 2024 13:39:35 +0200
Subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the
 spectre_bhb_k24_list
In-Reply-To: <CAODwPW919K+XdxjUe3aPgxsv0CEWwx0P_Hxvf=VniLhk8eagkQ@mail.gmail.com>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>
 <l5rqbbxn6hktlcxooolkvi5n3arkht6zzhrvdjf6kis322nsup@5hsrak4cgteq>
 <CAD=FV=WQf+ig21u316WvQh0DoKsdKAmZgqPn5LB-myDXsJtXig@mail.gmail.com>
 <CAODwPW919K+XdxjUe3aPgxsv0CEWwx0P_Hxvf=VniLhk8eagkQ@mail.gmail.com>
Message-ID: <2qx75syaojhnsqt256li6sinafml4gohohvld6uw3zhejrayuj@biiep5dvko7t>

On Fri, Dec 13, 2024 at 05:28:55PM -0800, Julius Werner wrote:
> > Interesting. So the Gold/Prime are actually IDing themselves as
> > straight Cortex A77. The Silver is IDing itself the same as
> > KRYO_4XX_SILVER. ...so in that sense there's nothing to do here for
> > those cores.
> 
> Should we add some comments to cputype.h to record which other
> products are matched under the same ID?

I'd say, yes.

-- 
With best wishes
Dmitry


From umer.uddin at mentallysanemainliners.org  Sat Dec 14 03:58:55 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Sat, 14 Dec 2024 11:58:55 +0000
Subject: [PATCH v1 1/1] arm64: dts: exynos990: Add a PMU node for the third cluster
In-Reply-To: <20241214115855.49138-1-umer.uddin@mentallysanemainliners.org>
References: <20241214115855.49138-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <20241214115855.49138-2-umer.uddin@mentallysanemainliners.org>

Since we have a PMU compatiable for Samsung's Mongoose cores now, drop
the comment that explains the lack of it and define the node.

Signed-off-by: Umer Uddin <umer.uddin at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/exynos990.dtsi | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos990.dtsi b/arch/arm64/boot/dts/exynos/exynos990.dtsi
index 2619f821b..c53df5d7c 100644
--- a/arch/arm64/boot/dts/exynos/exynos990.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos990.dtsi
@@ -46,7 +46,14 @@ arm-a76-pmu {
 				     <&cpu5>;
 	};
 
-	/* There's no PMU model for cluster2, which are the Mongoose cores. */
+	mongoose-m5-pmu {
+		compatible = "samsung,mongoose-pmu";
+		interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+
+		interrupt-affinity = <&cpu6>,
+				     <&cpu7>;
+	};
 
 	cpus {
 		#address-cells = <1>;
-- 
2.47.1



From umer.uddin at mentallysanemainliners.org  Sat Dec 14 03:58:54 2024
From: umer.uddin at mentallysanemainliners.org (Umer Uddin)
Date: Sat, 14 Dec 2024 11:58:54 +0000
Subject: [PATCH v1 0/1] arm64: dts: exynos990: Add m5-pmu
Message-ID: <20241214115855.49138-1-umer.uddin@mentallysanemainliners.org>

Hi guys,

This series adds support for the mongoose cluster PMU in DT via
a compatible for it that was recently added.

This change was tested on my Samsung Galaxy S20 5G (x1s) and is
confirmed to be working.

Kind regards,
Umer.

Umer Uddin (1):
  arm64: dts: exynos990: Add a PMU node for the third cluster

 arch/arm64/boot/dts/exynos/exynos990.dtsi | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

-- 
2.47.1



From markuss.broks at gmail.com  Sat Dec 14 04:06:14 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Sat, 14 Dec 2024 14:06:14 +0200
Subject: [PATCH 2/3] soc: samsung: Add a driver for Samsung SPEEDY host
 controller
In-Reply-To: <c0d58c4d-e3dc-445d-93c4-a2aed07af143@kernel.org>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
 <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
 <f08b068e-bc6b-4d9d-9839-370883309b88@kernel.org>
 <2a7f71b6-0967-40ee-9d0f-d7144eafcd5a@gmail.com>
 <c0d58c4d-e3dc-445d-93c4-a2aed07af143@kernel.org>
Message-ID: <0fdc56cc-c912-45c8-b90d-e5bc1d7c1e35@gmail.com>

Hi Krzysztof,

On 12/13/24 3:55 PM, Krzysztof Kozlowski wrote:
> On 13/12/2024 10:42, Markuss Broks wrote:
>> Hi Krzysztof,
>>
>> On 12/13/24 9:49 AM, Krzysztof Kozlowski wrote:
>>> On 12/12/2024 22:09, Markuss Broks wrote:
>>>> Add a driver for Samsung SPEEDY serial bus host controller.
>>>> SPEEDY is a proprietary 1 wire serial bus used by Samsung
>>>> in various devices (usually mobile), like Samsung Galaxy
>>>> phones. It is usually used for connecting PMIC or various
>>>> other peripherals, like audio codecs or RF components.
>>>>
>>>> This bus can address at most 1MiB (4 bit device address,
>>>> 8 bit registers per device, 8 bit wide registers:
>>>> 256*256*16 = 1MiB of address space.
>>>>
>>>> Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
>>>> Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
>>>> Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
>>>> ---
>>>>    drivers/soc/samsung/Kconfig               |  13 +
>>>>    drivers/soc/samsung/Makefile              |   2 +
>>>>    drivers/soc/samsung/exynos-speedy.c       | 457 ++++++++++++++++++++++++++++++
>>>>    include/linux/soc/samsung/exynos-speedy.h |  56 ++++
>>>>    4 files changed, 528 insertions(+)
>>>>
>>>> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
>>>> index 1a5dfdc978dc4069eb71c4e8eada7ff1913b86b3..a38150fc9999ded1e1e93e2a9ef43b88175d34bd 100644
>>>> --- a/drivers/soc/samsung/Kconfig
>>>> +++ b/drivers/soc/samsung/Kconfig
>>>> @@ -49,6 +49,19 @@ config EXYNOS_PMU_ARM_DRIVERS
>>>>    	bool "Exynos PMU ARMv7-specific driver extensions" if COMPILE_TEST
>>>>    	depends on EXYNOS_PMU
>>>>    
>>>> +config EXYNOS_SPEEDY
>>>> +	tristate "Exynos SPEEDY host controller driver"
>>>> +	depends on ARCH_EXYNOS || COMPILE_TEST
>>>> +	depends on OF
>>>> +	depends on REGMAP_MMIO
>>>> +	help
>>>> +	  Enable support for Exynos SPEEDY host controller block.
>>>> +	  SPEEDY is a 1 wire proprietary Samsung serial bus, found in
>>>> +	  modern Samsung Exynos SoCs, like Exynos8895 and newer.
>>> I did not check that much but this looks like 1wire for which we have
>>> subsystem. Please investigate more and figure out the differences.
>> This is not compatible with Dallas Semi 1-Wire bus. There are several
>> differences but the phy level is not compatible, looking at the Samsung
>> patent. [1] The most obvious difference is that 1-Wire is discoverable,
>> and this bus isn't. I'm pretty sure this is Samsung's own solution to a
>> serial interface through only one wire.
>>
> It's fine then.
>
>>>> +
>>>> +	  Select this if you have a Samsung Exynos device which uses
>>>> +	  SPEEDY bus.
>>>> +
>>>> +
>>>> +/* SPEEDY_PACKET_GAP_TIME register bits */
>>>> +#define SPEEDY_FIFO_TX_ALMOST_EMPTY			(1 << 4)
>>>> +#define SPEEDY_FIFO_RX_ALMOST_FULL			(1 << 8)
>>>> +#define SPEEDY_FSM_INIT					(1 << 1)
>>>> +#define SPEEDY_FSM_TX_CMD				(1 << 2)
>>>> +#define SPEEDY_FSM_STANDBY				(1 << 3)
>>>> +#define SPEEDY_FSM_DATA					(1 << 4)
>>>> +#define SPEEDY_FSM_TIMEOUT				(1 << 5)
>>>> +#define SPEEDY_FSM_TRANS_DONE				(1 << 6)
>>>> +#define SPEEDY_FSM_IO_RX_STAT_MASK			(3 << 7)
>>>> +#define SPEEDY_FSM_IO_TX_IDLE				(1 << 9)
>>>> +#define SPEEDY_FSM_IO_TX_GET_PACKET			(1 << 10)
>>>> +#define SPEEDY_FSM_IO_TX_PACKET				(1 << 11)
>>>> +#define SPEEDY_FSM_IO_TX_DONE				(1 << 12)
>>>> +
>>>> +#define SPEEDY_RX_LENGTH(n)				((n) << 0)
>>>> +#define SPEEDY_TX_LENGTH(n)				((n) << 8)
>>>> +
>>>> +#define SPEEDY_DEVICE(x)				((x & 0xf) << 15)
>>>> +#define SPEEDY_ADDRESS(x)				((x & 0xff) << 7)
>>>> +
>>>> +static const struct of_device_id speedy_match[] = {
>>>> +	{ .compatible = "samsung,exynos9810-speedy" },
>>>> +	{ /* Sentinel */ }
>>>> +};
>>>> +MODULE_DEVICE_TABLE(of, speedy_match);
>>> This is never at top of the file, but immediately before driver
>>> structure. Look at other drivers.
>> The function speedy_get_device uses this to match the compatible, do I
>> just leave the prototype here?
>
> 1. Entire speedy_get_device() is unused so it will be removed.
> 2. Even if it stays, speedy_get_device() is not supposed to match
> anything. How are you supposed to use Samsung PMIC on different
> controller? These things should not be tied.


speedy_get_device was my approach to not make it a proper bus driver, 
since I've thought it would be overkill for the purposes. 
speedy_get_device() is supposed to be called by a child device through 
the devm_ helper, and what it does is: it gets the parent node, verifies 
if that node matches the speedy compatible, then if it does it gets the 
platform_device and crafts a new struct speedy_device for the child 
device to use. This approach is perhaps hacky, but it helps simplify 
things a bit by not implementing the whole bus logic properly, let me 
know if it's too hacky...

Actually, one of my other concerns is that S2MPS18 has both SPEEDY and 
I2C interface for communicating with host, and with current approach 
it's going to be hacky if we want to support both. I've not seen S2MPS18 
used with I2C on any real boards, but it should really be trivial to 
support both, and with current hacky approach it might be not trivial at 
all...

>
>
>>>> +
>>>> +static const struct regmap_config speedy_map_cfg = {
>>>> +	.reg_bits = 32,
>>>> +	.val_bits = 32,
>>>> +};
>
> ...
>
>>>> +	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_READ |
>>>> +	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
>>>> +
>>>> +	int_ctl = SPEEDY_TRANSFER_DONE_EN | SPEEDY_FIFO_RX_ALMOST_FULL_EN |
>>>> +		  SPEEDY_RX_FIFO_INT_TRAILER_EN | SPEEDY_RX_MODEBIT_ERR_EN |
>>>> +		  SPEEDY_RX_GLITCH_ERR_EN | SPEEDY_RX_ENDBIT_ERR_EN |
>>>> +		  SPEEDY_REMOTE_RESET_REQ_EN;
>>>> +
>>>> +	ret = speedy_int_clear(speedy);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	/* Wait for xfer done */
>>>> +	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
>>>> +				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = regmap_read(speedy->map, SPEEDY_RX_DATA, val);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = speedy_int_clear(speedy);
>>>> +
>>>> +	mutex_unlock(&speedy->io_lock);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +int exynos_speedy_read(const struct speedy_device *device, u32 addr, u32 *val)
>>>> +{
>>>> +	return _speedy_read(device->speedy, device->reg, addr, val);
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(exynos_speedy_read);
>>> Nope, drop, unused.
>> This is intended to be used with other device drivers, this driver in
>> itself doesn't do anything, it only configures the controller and makes
>> it ready for transmitting data, it's other drivers that will come (e.g.
>> S2MPS18 PMIC, which uses SPEEDY for communication with the SoC) that
>> will utilize those functions.
> Post entire series, so we see users of this API. If you post API without
> users, it won't be accepted simply because there are no users and we do
> not want dead, unused code.
>
> Anyway we must see how you intend to use that interface to properly
> review it.


Sure!

>
>>>> +
>>>> +/**
>>>> + * _speedy_write() - internal speedy write operation
>>>> + * @speedy:	pointer to speedy controller struct
>>>> + * @reg:	address of device on the bus
>>>> + * @addr:       address to write
>>>> + * @val:        value to write
>>>> + *
>
> ...
>
>>>> +}
>>>> +
>>>> +static struct platform_driver speedy_driver = {
>>>> +	.probe = speedy_probe,
>>>> +	.driver = {
>>>> +		.name = "exynos-speedy",
>>>> +		.of_match_table = speedy_match,
>>>> +	},
>>>> +};
>>>> +
>>>> +module_platform_driver(speedy_driver);
>>>> +
>>>> +MODULE_DESCRIPTION("Samsung Exynos SPEEDY host controller driver");
>>>> +MODULE_AUTHOR("Markuss Broks <markuss.broks at gmail.com>");
>>>> +MODULE_LICENSE("GPL");
>>>> diff --git a/include/linux/soc/samsung/exynos-speedy.h b/include/linux/soc/samsung/exynos-speedy.h
>>>> new file mode 100644
>>>> index 0000000000000000000000000000000000000000..b2857d65d3b50927373866dd8ae1c47e98af6d7b
>>>> --- /dev/null
>>>> +++ b/include/linux/soc/samsung/exynos-speedy.h
>>> Drop the header, not used.
>> Same here, please clarify how this should be handled. This driver
>> implements the devm_speedy_get_device and read/write functions for its
>> child devices in that header, future drivers for e.g. PMIC would use
>> this header and call devm_speedy_get_device to get a speedy_device
>> pointer and then use read/write functions to read/write from the bus.
> This needs to be proper bus with proper speedy_driver clients. See how
> other buses - struct bus_type. Recent example of bus using platform
> drivers for devices would be pwrseq (power/sequence). Not so old other
> bus using its own xxx_driver for devices could be cxl or ffa (arm_ffa).
> This current non-bus approach, could also work if this is really Samsung
> specific. See memory/ for examples of MMIO buses and MMIO clients.


Let me know if the current approach is acceptable or not, it is fine in 
my eyes if it needs to be a full-fledged bus driver, but in my opinion 
it's a lot of effort and additional logic for a niche samsung-specific 
usecase. Although I've heard that they're still using SPEEDY in newer 
devices as well, perhaps for more advanced purposes than just an 
interface for PMIC, which would mean additional things to consider...

I'll be glad to hear how you think it should be implemented, because I 
myself do not know a lot about kernel drivers like this...

>
> I don't know good examples of non-MMIO buses not using bus_type and I am
> not sure whether this is accepted in general. I'll ask on IRC, maybe
> someone will give some hints.
>
>
> Best regards,
> Krzysztof

Thanks,

- Markuss



From Markus.Elfring at web.de  Sat Dec 14 06:43:41 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Sat, 14 Dec 2024 15:43:41 +0100
Subject: [PATCH 2/3] soc: samsung: Add a driver for Samsung SPEEDY host
 controller
In-Reply-To: <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
References: <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
Message-ID: <44419be4-65b3-41eb-a696-cfefae84a423@web.de>

?
> SPEEDY is a proprietary 1 wire serial bus used by Samsung
> in various devices ?

You may occasionally put more than 57 characters into text lines
of such a change description.


?
> +++ b/drivers/soc/samsung/exynos-speedy.c
> @@ -0,0 +1,457 @@
?
> +static int _speedy_read(struct speedy_controller *speedy, u32 reg, u32 addr, u32 *val)
> +{
> +	int ret;
> +	u32 cmd, int_ctl, int_status;
> +
> +	mutex_lock(&speedy->io_lock);
?
> +	ret = speedy_int_clear(speedy);
> +
> +	mutex_unlock(&speedy->io_lock);
> +
> +	return ret;
> +}
?

Under which circumstances would you become interested to apply a statement
like ?guard(mutex)(&speedy->io_lock);??
https://elixir.bootlin.com/linux/v6.13-rc2/source/include/linux/mutex.h#L201

Regards,
Markus


From markuss.broks at gmail.com  Sat Dec 14 06:56:46 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Sat, 14 Dec 2024 16:56:46 +0200
Subject: [PATCH RESEND v4 1/2] arm64: dts: exynos: Add Exynos9810 SoC
 support
In-Reply-To: <20241214-exynos9810-v4-0-4e91fbbc2133@gmail.com>
References: <20241214-exynos9810-v4-0-4e91fbbc2133@gmail.com>
Message-ID: <20241214-exynos9810-v4-1-4e91fbbc2133@gmail.com>

Exynos 9810 is an ARMv8 mobile SoC found in various Samsung devices,
such as Samsung Galaxy S9 (starlte), S9 Plus (star2lte),
Note 9 (crownlte) and perhaps others.

Add minimal support for this SoC, including basic stuff like:
- PSCI for bringing up secondary cores
- ARMv8 generic timer
- GPIO and pinctrl.

The firmware coming with the devices based on this SoC is buggy
and doesn't configure CNTFRQ_EL0, as required by spec, so it's
needed to hardcode the frequency in the timer node.

Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
---
 arch/arm64/boot/dts/exynos/exynos9810-pinctrl.dtsi | 503 +++++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos9810.dtsi         | 273 +++++++++++
 2 files changed, 776 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos9810-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos9810-pinctrl.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..88091bf09e4e91b05801cafe956283984d564449
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos9810-pinctrl.dtsi
@@ -0,0 +1,503 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung's Exynos 9810 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2024 Markuss Broks <markuss.broks at gmail.com>
+ * Copyright (c) 2024 Maksym Holovach <nergzd at nergzd723.xyz>
+ */
+
+#include "exynos-pinctrl.h"
+
+&pinctrl_alive {
+	etc1: etc1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpa0: gpa0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+		#interrupt-cells = <2>;
+	};
+
+	gpa1: gpa1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+		#interrupt-cells = <2>;
+	};
+
+	gpa2: gpa2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+		#interrupt-cells = <2>;
+	};
+
+	gpa3: gpa3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+		#interrupt-cells = <2>;
+	};
+
+	gpa4: gpa4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpq0: gpq0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_aud {
+	gpb0: gpb0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb1: gpb1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb2: gpb2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_chub {
+	gph0: gph0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gph1: gph1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_cmgp {
+	gpm0: gpm0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm1: gpm1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm2: gpm2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm3: gpm3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm4: gpm4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm5: gpm5-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm6: gpm6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm7: gpm7-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm10: gpm10-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm11: gpm11-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm12: gpm12-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm13: gpm13-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm14: gpm14-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm15: gpm15-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm16: gpm16-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm17: gpm17-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm40: gpm40-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm41: gpm41-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm42: gpm42-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm43: gpm43-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
+
+&pinctrl_fsys0 {
+	gpf0: gpf0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_fsys1 {
+	gpf1: gpf1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf2: gpf2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_peric0 {
+	gpg0: gpg0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp0: gpp0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp1: gpp1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp2: gpp2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp3: gpp3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_peric1 {
+	gpc0: gpc0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc1: gpc1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd0: gpd0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp4: gpp4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp5: gpp5-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp6: gpp6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_vts {
+	gpt0: gpt0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos9810.dtsi b/arch/arm64/boot/dts/exynos/exynos9810.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..70b67b2574d5b66eb5fa421a87dd6f4e49f8f54e
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos9810.dtsi
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Exynos 9810 SoC device tree source
+ *
+ * Copyright (c) 2024 Markuss Broks <markuss.broks at gmail.com>
+ * Copyright (c) 2024 Maksym Holovach <nergzd at nergzd723.xyz>
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "samsung,exynos9810";
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	interrupt-parent = <&gic>;
+
+	aliases {
+		pinctrl0 = &pinctrl_alive;
+		pinctrl1 = &pinctrl_aud;
+		pinctrl2 = &pinctrl_chub;
+		pinctrl3 = &pinctrl_cmgp;
+		pinctrl4 = &pinctrl_fsys0;
+		pinctrl5 = &pinctrl_fsys1;
+		pinctrl6 = &pinctrl_peric0;
+		pinctrl7 = &pinctrl_peric1;
+		pinctrl8 = &pinctrl_vts;
+	};
+
+	arm-a55-pmu {
+		compatible = "arm,cortex-a55-pmu";
+		interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>,
+				     <&cpu1>,
+				     <&cpu2>,
+				     <&cpu3>;
+	};
+
+	mongoose-m3-pmu {
+		compatible = "samsung,mongoose-pmu";
+		interrupts = <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>;
+		interrupt-affinity = <&cpu4>,
+				     <&cpu5>,
+				     <&cpu6>,
+				     <&cpu7>;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+				core2 {
+					cpu = <&cpu2>;
+				};
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+				core1 {
+					cpu = <&cpu5>;
+				};
+				core2 {
+					cpu = <&cpu6>;
+				};
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x1>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x2>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x3>;
+			enable-method = "psci";
+		};
+
+		cpu4: cpu at 100 {
+			device_type = "cpu";
+			compatible = "samsung,mongoose-m3";
+			reg = <0x100>;
+			enable-method = "psci";
+		};
+
+		cpu5: cpu at 101 {
+			device_type = "cpu";
+			compatible = "samsung,mongoose-m3";
+			reg = <0x101>;
+			enable-method = "psci";
+		};
+
+		cpu6: cpu at 102 {
+			device_type = "cpu";
+			compatible = "samsung,mongoose-m3";
+			reg = <0x102>;
+			enable-method = "psci";
+		};
+
+		cpu7: cpu at 103 {
+			device_type = "cpu";
+			compatible = "samsung,mongoose-m3";
+			reg = <0x103>;
+			enable-method = "psci";
+		};
+	};
+
+	oscclk: osc-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-output-names = "oscclk";
+	};
+
+	psci {
+		compatible = "arm,psci";
+		method = "smc";
+		cpu_off = <0x84000002>;
+		cpu_on = <0xc4000003>;
+		cpu_suspend = <0xc4000001>;
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+		ranges = <0x0 0x0 0x0 0x20000000>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		chipid at 10000000 {
+			compatible = "samsung,exynos9810-chipid",
+				     "samsung,exynos850-chipid";
+			reg = <0x10000000 0x100>;
+		};
+
+		gic: interrupt-controller at 10101000 {
+			compatible = "arm,gic-400";
+			reg = <0x10101000 0x1000>,
+			      <0x10102000 0x1000>,
+			      <0x10104000 0x2000>,
+			      <0x10106000 0x2000>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) |
+						 IRQ_TYPE_LEVEL_HIGH)>;
+			#address-cells = <0>;
+			#size-cells = <1>;
+		};
+
+		pinctrl_peric0: pinctrl at 10430000 {
+			compatible = "samsung,exynos9810-pinctrl";
+			reg = <0x10430000 0x1000>;
+			interrupts = <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_peric1: pinctrl at 10830000 {
+			compatible = "samsung,exynos9810-pinctrl";
+			reg = <0x10830000 0x1000>;
+			interrupts = <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_fsys0: pinctrl at 11050000 {
+			compatible = "samsung,exynos9810-pinctrl";
+			reg = <0x11050000 0x1000>;
+			interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_fsys1: pinctrl at 11430000 {
+			compatible = "samsung,exynos9810-pinctrl";
+			reg = <0x11430000 0x1000>;
+			interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_vts: pinctrl at 13880000 {
+			compatible = "samsung,exynos9810-pinctrl";
+			reg = <0x13880000 0x1000>;
+		};
+
+		pinctrl_chub: pinctrl at 13a80000 {
+			compatible = "samsung,exynos9810-pinctrl";
+			reg = <0x13a80000 0x1000>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_alive: pinctrl at 14050000 {
+			compatible = "samsung,exynos9810-pinctrl";
+			reg = <0x14050000 0x1000>;
+
+			wakeup-interrupt-controller {
+				compatible = "samsung,exynos9810-wakeup-eint",
+					     "samsung,exynos850-wakeup-eint",
+					     "samsung,exynos7-wakeup-eint";
+			};
+		};
+
+		pmu_system_controller: system-controller at 14060000 {
+			compatible = "samsung,exynos9810-pmu",
+				     "samsung,exynos7-pmu", "syscon";
+			reg = <0x14060000 0x10000>;
+		};
+
+		pinctrl_cmgp: pinctrl at 14220000 {
+			compatible = "samsung,exynos9810-pinctrl";
+			reg = <0x14220000 0x1000>;
+
+			wakeup-interrupt-controller {
+				compatible = "samsung,exynos9810-wakeup-eint",
+					     "samsung,exynos850-wakeup-eint",
+					     "samsung,exynos7-wakeup-eint";
+			};
+		};
+
+		pinctrl_aud: pinctrl at 17c60000 {
+			compatible = "samsung,exynos9810-pinctrl";
+			reg = <0x17c60000 0x1000>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		/* Hypervisor Virtual Timer interrupt is not wired to GIC */
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+		/*
+		 * Non-updatable, broken stock Samsung bootloader does not
+		 * configure CNTFRQ_EL0
+		 */
+		clock-frequency = <26000000>;
+	};
+};
+
+#include "exynos9810-pinctrl.dtsi"
+#include "arm/samsung/exynos-syscon-restart.dtsi"

-- 
2.47.0



From markuss.broks at gmail.com  Sat Dec 14 06:56:45 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Sat, 14 Dec 2024 16:56:45 +0200
Subject: [PATCH RESEND v4 0/2] Add support for Exynos9810 SoC and Samsung
 Galaxy S9 (SM-G960F)
Message-ID: <20241214-exynos9810-v4-0-4e91fbbc2133@gmail.com>

Hello,

This series adds initial SoC support for the Samsung Exynos 9810
SoC and initial board support for Samsung Galaxy S9 phone (SM-G960F),
codenamed starlte.

The Exynos 9810 SoC is also used in S9 Plus (star2lte), Note 9 (crownlte),
and perhaps more devices. Currently only Galaxy S9 DTS file is added but it
should be fairly simple to add support for other devices based on this SoC,
considering they're quite similar.

The support added in this series includes:
- cpus
- pinctrl and gpio
- simple-framebuffer

This is enough to boot to a minimal initramfs shell.

The preferred way to boot this device is by using a small shim bl called
uniLoader [1], which packages the mainline kernel and DT and jumps to
the kernel. This is done in order to work around some issues caused by
the stock, and non-replacable Samsung S-Boot bootloader. For example,
S-Boot leaves the decon trigger control unset, which causes the framebuffer
to not refresh, so simple-framebuffer wouldn't work without a secondary loader.
Ideally, there'll be a kernel driver for the display subsystem some day to
resolve this issue.

[1] https://github.com/ivoszbg/uniLoader

Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
---
Changes in v4 RESEND:
- dropped applied patches
- Link to v4: https://lore.kernel.org/r/20241028-exynos9810-v4-0-6191f9d0c0f1 at gmail.com

Changes in v4:
- make DTS build again [typo, misplaced ;] (krzk)
- lowercase hex in pinctrl (ivo)
- removed the perf patchset from dependencies (krzk)
- Link to v3: https://lore.kernel.org/r/20241026-exynos9810-v3-0-b89de9441ea8 at gmail.com

Changes in v3:
- fix a blank line between tags (krzk)
- align with the opening " in eint-controller (krzk)
- sort the memory node (ivo)
- drop the \n (ivo)
- drop the perf patches into separate series (krzk)
- elaborate a bit more on dt-bindings (krzk)
- Link to v2: https://lore.kernel.org/r/20241025-exynos9810-v2-0-99ca3f316e21 at gmail.com

Changes in v2:
- sort the pinctrl nodes alphabetically (ivo)
- move the interrupts from pinctrl file to SoC dtsi (krzk)
- move the wakeup-eint from pinctrl file to SoC dtsi (krzk)
- sort gpio-keys pinctrl-0 and pinctrl-names (ivo)
- rename the bixby key node to "wink" (ivo)
- sort gpio-keys subnodes (ivo)
- sort pinctrl_alive gpio-keys pin descriptions (ivo)
- fix the Co-developed-by tags and add a signoff (krzk)

- Link to v1: https://lore.kernel.org/r/20241024-exynos9810-v1-0-ed14d0d60d08 at gmail.com

---
Markuss Broks (2):
      arm64: dts: exynos: Add Exynos9810 SoC support
      arm64: dts: exynos: Add initial support for Samsung Galaxy S9 (SM-G960F)

 arch/arm64/boot/dts/exynos/Makefile                |   1 +
 arch/arm64/boot/dts/exynos/exynos9810-pinctrl.dtsi | 503 +++++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos9810-starlte.dts  | 119 +++++
 arch/arm64/boot/dts/exynos/exynos9810.dtsi         | 273 +++++++++++
 4 files changed, 896 insertions(+)
---
base-commit: 1b2ab8149928c1cea2d7eca30cd35bb7fe014053
change-id: 20241024-exynos9810-b3eed995b0b9

Best regards,
-- 
Markuss Broks <markuss.broks at gmail.com>



From markuss.broks at gmail.com  Sat Dec 14 06:56:47 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Sat, 14 Dec 2024 16:56:47 +0200
Subject: [PATCH RESEND v4 2/2] arm64: dts: exynos: Add initial support for
 Samsung Galaxy S9 (SM-G960F)
In-Reply-To: <20241214-exynos9810-v4-0-4e91fbbc2133@gmail.com>
References: <20241214-exynos9810-v4-0-4e91fbbc2133@gmail.com>
Message-ID: <20241214-exynos9810-v4-2-4e91fbbc2133@gmail.com>

Samsung Galaxy S9 (SM-G960F), codenamed starlte, is a mobile phone
released in 2017. It has 4GB of RAM, 64GB of UFS storage, Exynos9810
SoC and 1440x2960 Super AMOLED display.

This initial device tree enables the framebuffer pre-initialised
by bootloader and physical buttons of the device, with more support
to come in the future.

Co-developed-by: Maksym Holovach <nergzd at nergzd723.xyz>
Signed-off-by: Maksym Holovach <nergzd at nergzd723.xyz>
Signed-off-by: Markuss Broks <markuss.broks at gmail.com>
---
 arch/arm64/boot/dts/exynos/Makefile               |   1 +
 arch/arm64/boot/dts/exynos/exynos9810-starlte.dts | 119 ++++++++++++++++++++++
 2 files changed, 120 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index ee73e1a2db7ea64a0b8e9067a1a264e366f59bc3..f6f4bc650a94db0bc6bc017432e2e3dbba90e8c3 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += \
 	exynos7885-jackpotlte.dtb	\
 	exynos850-e850-96.dtb		\
 	exynos8895-dreamlte.dtb		\
+	exynos9810-starlte.dtb		\
 	exynos990-c1s.dtb		\
 	exynos990-r8s.dtb               \
 	exynos990-x1s.dtb		\
diff --git a/arch/arm64/boot/dts/exynos/exynos9810-starlte.dts b/arch/arm64/boot/dts/exynos/exynos9810-starlte.dts
new file mode 100644
index 0000000000000000000000000000000000000000..fc0ddfee4cd63d2fc53cae3d7447f66d39c134e9
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos9810-starlte.dts
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Samsung Galaxy S9 (starlte/SM-G960F) device tree source
+ *
+ * Copyright (c) 2024 Markuss Broks <markuss.broks at gmail.com>
+ * Copyright (c) 2024 Maksym Holovach <nergzd at nergzd723.xyz>
+ */
+
+/dts-v1/;
+#include "exynos9810.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Samsung Galaxy S9 (SM-G960F)";
+	compatible = "samsung,starlte", "samsung,exynos9810";
+	chassis-type = "handset";
+
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		framebuffer at cc000000 {
+			compatible = "simple-framebuffer";
+			reg = <0x0 0xcc000000 (1440 * 2960 * 4)>;
+			width = <1440>;
+			height = <2960>;
+			stride = <(1440 * 4)>;
+			format = "a8r8g8b8";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&key_power &key_voldown &key_volup &key_wink>;
+		pinctrl-names = "default";
+
+		power-key {
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpa2 4 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+
+		voldown-key {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			gpios = <&gpa0 4 GPIO_ACTIVE_LOW>;
+		};
+
+		volup-key {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
+		};
+
+		/* In stock firmware used for assistant. Map it as a camera button for now */
+		wink-key {
+			label = "Camera";
+			linux,code = <KEY_CAMERA>;
+			gpios = <&gpa0 6 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x3c800000>,
+		      <0x0 0xc0000000 0x20000000>,
+		      <0x0 0xe1900000 0x1e700000>,
+		      <0x8 0x80000000 0x80000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		framebuffer at cc000000 {
+			reg = <0x0 0xcc000000 (1440 * 2960 * 4)>;
+			no-map;
+		};
+	};
+};
+
+&oscclk {
+	clock-frequency = <26000000>;
+};
+
+&pinctrl_alive {
+	key_power: key-power-pins {
+		samsung,pins = "gpa2-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_voldown: key-voldown-pins {
+		samsung,pins = "gpa0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_volup: key-volup-pins {
+		samsung,pins = "gpa0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_wink: key-wink-pins {
+		samsung,pins = "gpa0-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};

-- 
2.47.0



From ansuelsmth at gmail.com  Sat Dec 14 07:11:54 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sat, 14 Dec 2024 16:11:54 +0100
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <20241210234803.pzm7fxrve4dastth@skbuf>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241210211529.osgzd54flq646bcr@skbuf>
 <6758c174.050a0220.52a35.06bc@mx.google.com>
 <20241210234803.pzm7fxrve4dastth@skbuf>
Message-ID: <675da041.050a0220.a8e65.af0e@mx.google.com>

On Wed, Dec 11, 2024 at 01:48:03AM +0200, Vladimir Oltean wrote:
> On Tue, Dec 10, 2024 at 11:32:17PM +0100, Christian Marangi wrote:
> > Doesn't regmap add lots of overhead tho? Maybe I should really change
> > the switch regmap to apply a save/restore logic?
> > 
> > With an implementation like that current_page is not needed anymore.
> > And I feel additional read/write are ok for switch OP.
> > 
> > On mdio I can use the parent-mdio-bus property to get the bus directly
> > without using MFD priv.
> > 
> > What do you think?
> 
> If performance is a relevant factor at all, it will be hard to measure it, other
> than with synthetic tests (various mixes of switch and PHY register access).
> Though since you mention it, it would be interesting to see a comparison of the
> 3 arbitration methods. This could probably be all done from the an8855_mfd_probe()
> calling context: read a switch register and a PHY register 100K times and see how
> long it took, then read 2 switch registers and a PHY register 100K times, then
> 3 switch registers.... At some point, we should start seeing the penalty of the
> page restoration in Andrew's proposal, because that will be done after each switch
> register read. Just curious to put it into perspective and see how soon it starts
> to make a difference. And this test will also answer the regmap overhead issue.

Ok sorry for the delay as I had to tackle an annoying crypto driver...

I was also curious about this and I hope I tested this correctly...

The testing code is this. Following Vladimir testing and simple time
comparision before and after. I used 100 times as 100k was very big.
>From the results we can derive our conclusions.

static void test(struct an8855_mfd_priv *priv, struct regmap *regmap, struct regmap *regmap_phy)
{
	ktime_t start_time, end_time;
	// struct mii_bus *bus = priv->bus;
    	s64 elapsed_ns;
	u32 val;
	int times = 1;
	int i, j;

	start_time = ktime_get();
	for (i = 0; i < 100; i++) {
		for (j = 0; j < times; j++) {
			regmap_read(regmap, 0x10005000, &val);
		}
		// mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
		// // an8855_mii_set_page(priv, priv->switch_addr, 0);
		// __mdiobus_read(bus, priv->switch_addr, 0x1);
		// mutex_unlock(&bus->mdio_lock);
		regmap_read(regmap_phy,
			   FIELD_PREP(GENMASK(20, 16), priv->switch_addr) |
			   FIELD_PREP(GENMASK(15, 0), 0x1),
			   &val);
		times++;
	}

	end_time = ktime_get();

	elapsed_ns = ktime_to_ns(ktime_sub(end_time, start_time));

	pr_info("Time spent in the code block: %lld ns\n", elapsed_ns);
}

With the code changed accordingly.

switch regmap + page (proposed implementation)
Time spent in the code block:  866179846 ns

switch regmap + phy regmap (proposed implementation + PHY regmap)
Time spent in the code block:  861326846 ns

switch regmap restore (switch regmap read/set/restore page)
Time spent in the code block: 1151011308 ns

switch regmap restore + phy regmap (switch regmap read/set/restore pgae
+ PHY regmap)
Time spent in the code block: 1147400462 ns

We can see that:
- as suggested regmap doesn't cause any performance penality. It does
  even produce better result.
- the read/set/restore implementation gives worse performance.

So I guess I will follow the path of regmap + cache page. What do you
think?

-- 
	Ansuel


From lkp at intel.com  Sat Dec 14 07:21:15 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 14 Dec 2024 23:21:15 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS
 f578281000c50cae991c40e1f68b2fc0b1b9e60e
Message-ID: <202412142302.4BOR5CWl-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: f578281000c50cae991c40e1f68b2fc0b1b9e60e  Merge tag 'ffa-fix-6.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes

elapsed time: 1457m

configs tested: 71
configs skipped: 1

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

tested configs:
arc                  randconfig-001-20241214    gcc-13.2.0
arc                  randconfig-002-20241214    gcc-13.2.0
arm                  randconfig-001-20241214    gcc-14.2.0
arm                  randconfig-002-20241214    clang-15
arm                  randconfig-003-20241214    gcc-14.2.0
arm                  randconfig-004-20241214    gcc-14.2.0
arm64                randconfig-001-20241214    clang-15
arm64                randconfig-002-20241214    clang-20
arm64                randconfig-003-20241214    clang-15
arm64                randconfig-004-20241214    gcc-14.2.0
csky                 randconfig-001-20241214    gcc-14.2.0
csky                 randconfig-002-20241214    gcc-14.2.0
hexagon              randconfig-001-20241214    clang-20
hexagon              randconfig-002-20241214    clang-14
i386                             allnoconfig    gcc-12
i386       buildonly-randconfig-001-20241213    clang-19
i386       buildonly-randconfig-001-20241214    gcc-12
i386       buildonly-randconfig-002-20241213    gcc-12
i386       buildonly-randconfig-002-20241214    gcc-12
i386       buildonly-randconfig-003-20241213    gcc-12
i386       buildonly-randconfig-003-20241214    clang-19
i386       buildonly-randconfig-004-20241213    clang-19
i386       buildonly-randconfig-004-20241214    clang-19
i386       buildonly-randconfig-005-20241213    gcc-12
i386       buildonly-randconfig-005-20241214    gcc-11
i386       buildonly-randconfig-006-20241213    gcc-12
i386       buildonly-randconfig-006-20241214    gcc-12
loongarch            randconfig-001-20241214    gcc-14.2.0
loongarch            randconfig-002-20241214    gcc-14.2.0
nios2                randconfig-001-20241214    gcc-14.2.0
nios2                randconfig-002-20241214    gcc-14.2.0
openrisc                         allnoconfig    gcc-14.2.0
parisc                           allnoconfig    gcc-14.2.0
parisc               randconfig-001-20241214    gcc-14.2.0
parisc               randconfig-002-20241214    gcc-14.2.0
powerpc                          allnoconfig    gcc-14.2.0
powerpc              randconfig-001-20241214    clang-20
powerpc              randconfig-002-20241214    clang-15
powerpc              randconfig-003-20241214    clang-20
powerpc64            randconfig-001-20241214    gcc-14.2.0
powerpc64            randconfig-003-20241214    clang-20
riscv                            allnoconfig    gcc-14.2.0
riscv                randconfig-001-20241214    clang-20
riscv                randconfig-002-20241214    clang-20
s390                            allmodconfig    clang-19
s390                             allnoconfig    clang-20
s390                            allyesconfig    gcc-14.2.0
s390                 randconfig-001-20241214    gcc-14.2.0
s390                 randconfig-002-20241214    gcc-14.2.0
sh                              allmodconfig    gcc-14.2.0
sh                              allyesconfig    gcc-14.2.0
sh                   randconfig-001-20241214    gcc-14.2.0
sh                   randconfig-002-20241214    gcc-14.2.0
sparc                           allmodconfig    gcc-14.2.0
sparc                randconfig-001-20241214    gcc-14.2.0
sparc                randconfig-002-20241214    gcc-14.2.0
sparc64              randconfig-001-20241214    gcc-14.2.0
sparc64              randconfig-002-20241214    gcc-14.2.0
um                               allnoconfig    clang-18
um                   randconfig-001-20241214    clang-20
um                   randconfig-002-20241214    clang-17
x86_64                           allnoconfig    clang-19
x86_64     buildonly-randconfig-001-20241214    gcc-11
x86_64     buildonly-randconfig-002-20241214    clang-19
x86_64     buildonly-randconfig-003-20241214    gcc-12
x86_64     buildonly-randconfig-004-20241214    gcc-12
x86_64     buildonly-randconfig-005-20241214    gcc-12
x86_64     buildonly-randconfig-006-20241214    clang-19
x86_64                             defconfig    gcc-11
xtensa               randconfig-001-20241214    gcc-14.2.0
xtensa               randconfig-002-20241214    gcc-14.2.0

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


From david at redhat.com  Sat Dec 14 07:22:58 2024
From: david at redhat.com (David Hildenbrand)
Date: Sat, 14 Dec 2024 16:22:58 +0100
Subject: [PATCH v3 00/25] fs/dax: Fix ZONE_DEVICE page reference counts
In-Reply-To: <675ce1e5a3d68_fad0294d0@dwillia2-xfh.jf.intel.com.notmuch>
References: <cover.e1ebdd6cab9bde0d232c1810deacf0bae25e6707.1732239628.git-series.apopple@nvidia.com>
 <675ce1e5a3d68_fad0294d0@dwillia2-xfh.jf.intel.com.notmuch>
Message-ID: <45555f72-e82a-4196-94af-22d05d6ac947@redhat.com>

On 14.12.24 02:39, Dan Williams wrote:
> [ add akpm and sfr for next steps ]
> 
> Alistair Popple wrote:
>> Main updates since v2:
>>
>>   - Rename the DAX specific dax_insert_XXX functions to vmf_insert_XXX
>>     and have them pass the vmf struct.
>>
>>   - Seperate out the device DAX changes.
>>
>>   - Restore the page share mapping counting and associated warnings.
>>
>>   - Rework truncate to require file-systems to have previously called
>>     dax_break_layout() to remove the address space mapping for a
>>     page. This found several bugs which are fixed by the first half of
>>     the series. The motivation for this was initially to allow the FS
>>     DAX page-cache mappings to hold a reference on the page.
>>
>>     However that turned out to be a dead-end (see the comments on patch
>>     21), but it found several bugs and I think overall it is an
>>     improvement so I have left it here.
>>
>> Device and FS DAX pages have always maintained their own page
>> reference counts without following the normal rules for page reference
>> counting. In particular pages are considered free when the refcount
>> hits one rather than zero and refcounts are not added when mapping the
>> page.
>>
>> Tracking this requires special PTE bits (PTE_DEVMAP) and a secondary
>> mechanism for allowing GUP to hold references on the page (see
>> get_dev_pagemap). However there doesn't seem to be any reason why FS
>> DAX pages need their own reference counting scheme.
>>
>> By treating the refcounts on these pages the same way as normal pages
>> we can remove a lot of special checks. In particular pXd_trans_huge()
>> becomes the same as pXd_leaf(), although I haven't made that change
>> here. It also frees up a valuable SW define PTE bit on architectures
>> that have devmap PTE bits defined.
>>
>> It also almost certainly allows further clean-up of the devmap managed
>> functions, but I have left that as a future improvment. It also
>> enables support for compound ZONE_DEVICE pages which is one of my
>> primary motivators for doing this work.
> 
> So this is feeling ready for -next exposure, and ideally merged for v6.14. I
> see the comments from John and Bjorn and that you were going to respin for
> that, but if it's just those details things they can probably be handled
> incrementally.
> 
> Alistair, are you ready for this to hit -next?
> 
> As for which tree...
> 
> Andrew, we could take this through -mm, but my first instinct would be to try
> to take it through nvdimm.git mainly to offload any conflict wrangling work and
> small fixups which are likely to be an ongoing trickle.
> 
> However, I am not going to put up much of a fight if others prefer this go
> through -mm.
> 
> Thoughts?

I'm in the process of preparing v2 of [1] that will result in conflicts 
with this series in the rmap code (in particular [PATCH v3 14/25] 
huge_memory: Allow mappings of PUD sized pages).

I'll be away for 2 weeks over Christmas, but I assume I'll manage to 
post v2 shortly.

Which reminds me that I still have to take a closer look at some things 
in this series :) Especially also #14 regarding accounting.

I wonder if we could split out the rmap changes in #14, and have that 
patch simply in two trees? No idea.

[1] 
https://lore.kernel.org/all/20240829165627.2256514-1-david at redhat.com/T/#u

-- 
Cheers,

David / dhildenb



From david at redhat.com  Sat Dec 14 07:32:00 2024
From: david at redhat.com (David Hildenbrand)
Date: Sat, 14 Dec 2024 16:32:00 +0100
Subject: [PATCH v3 14/25] huge_memory: Allow mappings of PUD sized pages
In-Reply-To: <dd86249dee026991b1a996a8ab551b1b1fdd32a4.1732239628.git-series.apopple@nvidia.com>
References: <cover.e1ebdd6cab9bde0d232c1810deacf0bae25e6707.1732239628.git-series.apopple@nvidia.com>
 <dd86249dee026991b1a996a8ab551b1b1fdd32a4.1732239628.git-series.apopple@nvidia.com>
Message-ID: <fc83a855-bb3f-4374-8896-579420732b25@redhat.com>

On 22.11.24 02:40, Alistair Popple wrote:
> Currently DAX folio/page reference counts are managed differently to
> normal pages. To allow these to be managed the same as normal pages
> introduce vmf_insert_folio_pud. This will map the entire PUD-sized folio
> and take references as it would for a normally mapped page.
> 
> This is distinct from the current mechanism, vmf_insert_pfn_pud, which
> simply inserts a special devmap PUD entry into the page table without
> holding a reference to the page for the mapping.
> 
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> ---

Hi,

The patch subject of this (and especially the next patch) is misleading. 
Likely you meant to have it as:

"mm/huge_memory: add vmf_insert_folio_pud() for mapping PUD sized pages"

>   	for (i = 0; i < nr_pages; i++) {
> @@ -1523,6 +1531,26 @@ void folio_add_file_rmap_pmd(struct folio *folio, struct page *page,
>   #endif
>   }
>   
> +/**
> + * folio_add_file_rmap_pud - add a PUD mapping to a page range of a folio
> + * @folio:	The folio to add the mapping to
> + * @page:	The first page to add
> + * @vma:	The vm area in which the mapping is added
> + *
> + * The page range of the folio is defined by [page, page + HPAGE_PUD_NR)
> + *
> + * The caller needs to hold the page table lock.
> + */
> +void folio_add_file_rmap_pud(struct folio *folio, struct page *page,
> +		struct vm_area_struct *vma)
> +{
> +#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
> +	__folio_add_file_rmap(folio, page, HPAGE_PUD_NR, vma, RMAP_LEVEL_PUD);
> +#else
> +	WARN_ON_ONCE(true);
> +#endif
> +}
> +
>   static __always_inline void __folio_remove_rmap(struct folio *folio,
>   		struct page *page, int nr_pages, struct vm_area_struct *vma,
>   		enum rmap_level level)
> @@ -1552,6 +1580,7 @@ static __always_inline void __folio_remove_rmap(struct folio *folio,
>   		partially_mapped = nr && atomic_read(mapped);
>   		break;
>   	case RMAP_LEVEL_PMD:
> +	case RMAP_LEVEL_PUD:
>   		atomic_dec(&folio->_large_mapcount);
>   		last = atomic_add_negative(-1, &folio->_entire_mapcount);
>   		if (last) {

If you simply reuse that code (here and on the adding path), you will 
end up effectively setting nr_pmdmapped to a very large value and 
passing that into __folio_mod_stat().

There, we will adjust NR_SHMEM_PMDMAPPED/NR_FILE_PMDMAPPED, which is 
wrong (it's PUD mapped ;) ).

It's probably best to split out the rmap changes from the other things 
in this patch.


-- 
Cheers,

David / dhildenb



From christophe.jaillet at wanadoo.fr  Sat Dec 14 07:52:35 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 14 Dec 2024 16:52:35 +0100
Subject: [PATCH 2/3] soc: samsung: Add a driver for Samsung SPEEDY host
 controller
In-Reply-To: <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
 <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
Message-ID: <3c067b26-cfe8-4939-afce-5c8753767715@wanadoo.fr>

Le 12/12/2024 ? 22:09, Markuss Broks a ?crit?:
> Add a driver for Samsung SPEEDY serial bus host controller.
> SPEEDY is a proprietary 1 wire serial bus used by Samsung
> in various devices (usually mobile), like Samsung Galaxy
> phones. It is usually used for connecting PMIC or various
> other peripherals, like audio codecs or RF components.
> 
> This bus can address at most 1MiB (4 bit device address,
> 8 bit registers per device, 8 bit wide registers:
> 256*256*16 = 1MiB of address space.

...

> +static int _speedy_read(struct speedy_controller *speedy, u32 reg, u32 addr, u32 *val)
> +{
> +	int ret;
> +	u32 cmd, int_ctl, int_status;
> +
> +	mutex_lock(&speedy->io_lock);

All error handling paths fail to release the mutex.
guard(mutex) would help here.

> +
> +	ret = speedy_fifo_reset(speedy);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
> +			      SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
> +	if (ret)
> +		return ret;
> +
> +	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_READ |
> +	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
> +
> +	int_ctl = SPEEDY_TRANSFER_DONE_EN | SPEEDY_FIFO_RX_ALMOST_FULL_EN |
> +		  SPEEDY_RX_FIFO_INT_TRAILER_EN | SPEEDY_RX_MODEBIT_ERR_EN |
> +		  SPEEDY_RX_GLITCH_ERR_EN | SPEEDY_RX_ENDBIT_ERR_EN |
> +		  SPEEDY_REMOTE_RESET_REQ_EN;
> +
> +	ret = speedy_int_clear(speedy);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
> +	if (ret)
> +		return ret;
> +
> +	/* Wait for xfer done */
> +	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
> +				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_read(speedy->map, SPEEDY_RX_DATA, val);
> +	if (ret)
> +		return ret;
> +
> +	ret = speedy_int_clear(speedy);
> +
> +	mutex_unlock(&speedy->io_lock);
> +
> +	return ret;
> +}

...

> +static int _speedy_write(struct speedy_controller *speedy, u32 reg, u32 addr, u32 val)
> +{
> +	int ret;
> +	u32 cmd, int_ctl, int_status;
> +
> +	mutex_lock(&speedy->io_lock);
> +
> +	ret = speedy_fifo_reset(speedy);
> +	if (ret)
> +		return ret;

All error handling paths fail to release the mutex.
guard(mutex) would help here.

> +
> +	ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
> +			      SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
> +	if (ret)
> +		return ret;
> +
> +	cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_WRITE |
> +	      SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
> +
> +	int_ctl = (SPEEDY_TRANSFER_DONE_EN |
> +		   SPEEDY_FIFO_TX_ALMOST_EMPTY_EN |
> +		   SPEEDY_TX_LINE_BUSY_ERR_EN |
> +		   SPEEDY_TX_STOPBIT_ERR_EN |
> +		   SPEEDY_REMOTE_RESET_REQ_EN);
> +
> +	ret = speedy_int_clear(speedy);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_write(speedy->map, SPEEDY_TX_DATA, val);
> +	if (ret)
> +		return ret;
> +
> +	/* Wait for xfer done */
> +	ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, int_status,
> +				       int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
> +	if (ret)
> +		return ret;
> +
> +	speedy_int_clear(speedy);
> +
> +	mutex_unlock(&speedy->io_lock);
> +
> +	return 0;
> +}

...

> +/**
> + * speedy_get_by_phandle() - internal get speedy device handle
> + * @np:	pointer to OF device node of device
> + *
> + * Return: 0 on success, -errno otherwise

On success, a handle is returned, not 0.

> + */
> +static const struct speedy_device *speedy_get_device(struct device_node *np)
> +{
...

> +out:
> +	of_node_put(speedy_np);
> +	return handle;
> +}

...

> +static int speedy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct speedy_controller *speedy;
> +	void __iomem *mem;
> +	int ret;
> +
> +	speedy = devm_kzalloc(dev, sizeof(struct speedy_controller), GFP_KERNEL);
> +	if (!speedy)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, speedy);
> +	speedy->pdev = pdev;
> +
> +	mutex_init(&speedy->io_lock);
> +
> +	mem = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(mem))
> +		return dev_err_probe(dev, PTR_ERR(mem), "Failed to ioremap memory\n");
> +
> +	speedy->map = devm_regmap_init_mmio(dev, mem, &speedy_map_cfg);
> +	if (IS_ERR(speedy->map))
> +		return dev_err_probe(dev, PTR_ERR(speedy->map), "Failed to init the regmap\n");
> +
> +	/* Clear any interrupt status remaining */
> +	ret = speedy_int_clear(speedy);
> +	if (ret)
> +		return ret;
> +
> +	/* Reset the controller */
> +	ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_SW_RST);
> +	if (ret)
> +		return ret;
> +
> +	msleep(20);
> +
> +	/* Enable the hw */
> +	ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_ENABLE);
> +	if (ret)
> +		return ret;
> +
> +	msleep(20);
> +
> +	/* Probe child devices */
> +	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev);
> +	if (ret)
> +		dev_err(dev, "Failed to populate child devices: %d\n", ret);

Could be dev_err_probe() as well, at least for consistency.

> +
> +	return ret;
> +}

...

CJ


From francesco at dolcini.it  Sat Dec 14 08:00:29 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Sat, 14 Dec 2024 17:00:29 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am62l: add initial infrastructure
In-Reply-To: <20241117-am62lx-v1-1-4e71e42d781d@ti.com>
References: <20241117-am62lx-v1-0-4e71e42d781d@ti.com>
 <20241117-am62lx-v1-1-4e71e42d781d@ti.com>
Message-ID: <Z12rnZiCXQxtMWlf@livingston.pivistrello.it>

On Sun, Nov 17, 2024 at 11:34:07PM -0600, Bryan Brattlof wrote:
> From: Vignesh Raghavendra <vigneshr at ti.com>
> 
> Add the initial infrastructure needed for the AM62L. All of which can be
> found in the Technical Reference Manual (TRM) located here:
> 
>     https://www.ti.com/lit/ug/sprujb4/sprujb4.pdf
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
> Signed-off-by: Bryan Brattlof <bb at ti.com>
> ---
>  Documentation/devicetree/bindings/arm/ti/k3.yaml |  6 ++
>  arch/arm64/boot/dts/ti/Makefile                  |  3 +
>  arch/arm64/boot/dts/ti/k3-am62l-main.dtsi        | 52 ++++++++++++++
>  arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi      | 33 +++++++++
>  arch/arm64/boot/dts/ti/k3-am62l.dtsi             | 89 ++++++++++++++++++++++++
>  arch/arm64/boot/dts/ti/k3-am62l3.dtsi            | 67 ++++++++++++++++++
>  arch/arm64/boot/dts/ti/k3-pinctrl.h              |  2 +
>  7 files changed, 252 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
> index 18f155cd06c84..b109e854879cb 100644
> --- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
> +++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
> @@ -31,6 +31,12 @@ properties:
>            - const: phytec,am62a-phycore-som
>            - const: ti,am62a7
>  
> +      - description: K3 AM62L3 SoC and Boards
> +        items:
> +          - enum:
> +              - ti,am62l3-evm
> +          - const: ti,am62l3
> +

can you clarify the differences between AM62L and AM62L3? you have a mix of names in this series. I assume that
AM62L is the SOC family / product name, while AM62L3 is a specific part number.

Francesco



From lkp at intel.com  Sat Dec 14 08:26:07 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 15 Dec 2024 00:26:07 +0800
Subject: [soc:soc/newsoc] BUILD SUCCESS
 d4c0d167b1f6535da7183783688850b8c51e3c44
Message-ID: <202412150001.cNMrfMVU-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/newsoc
branch HEAD: d4c0d167b1f6535da7183783688850b8c51e3c44  MAINTAINER: Add entry for Blaize SoC

elapsed time: 1448m

configs tested: 65
configs skipped: 1

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

tested configs:
arc                  randconfig-001-20241214    gcc-13.2.0
arc                  randconfig-002-20241214    gcc-13.2.0
arm                  randconfig-001-20241214    gcc-14.2.0
arm                  randconfig-002-20241214    clang-15
arm                  randconfig-003-20241214    gcc-14.2.0
arm                  randconfig-004-20241214    gcc-14.2.0
arm64                randconfig-001-20241214    clang-15
arm64                randconfig-002-20241214    clang-20
arm64                randconfig-003-20241214    clang-15
arm64                randconfig-004-20241214    gcc-14.2.0
csky                 randconfig-001-20241214    gcc-14.2.0
csky                 randconfig-002-20241214    gcc-14.2.0
hexagon              randconfig-001-20241214    clang-20
hexagon              randconfig-002-20241214    clang-14
i386                             allnoconfig    gcc-12
i386       buildonly-randconfig-001-20241214    gcc-12
i386       buildonly-randconfig-002-20241214    gcc-12
i386       buildonly-randconfig-003-20241214    clang-19
i386       buildonly-randconfig-004-20241214    clang-19
i386       buildonly-randconfig-005-20241214    gcc-11
i386       buildonly-randconfig-006-20241214    gcc-12
loongarch            randconfig-001-20241214    gcc-14.2.0
loongarch            randconfig-002-20241214    gcc-14.2.0
nios2                randconfig-001-20241214    gcc-14.2.0
nios2                randconfig-002-20241214    gcc-14.2.0
openrisc                         allnoconfig    gcc-14.2.0
parisc                           allnoconfig    gcc-14.2.0
parisc               randconfig-001-20241214    gcc-14.2.0
parisc               randconfig-002-20241214    gcc-14.2.0
powerpc                          allnoconfig    gcc-14.2.0
powerpc              randconfig-001-20241214    clang-20
powerpc              randconfig-002-20241214    clang-15
powerpc              randconfig-003-20241214    clang-20
powerpc64            randconfig-001-20241214    gcc-14.2.0
powerpc64            randconfig-003-20241214    clang-20
riscv                            allnoconfig    gcc-14.2.0
riscv                randconfig-001-20241214    clang-20
riscv                randconfig-002-20241214    clang-20
s390                            allmodconfig    clang-19
s390                             allnoconfig    clang-20
s390                            allyesconfig    gcc-14.2.0
s390                 randconfig-001-20241214    gcc-14.2.0
s390                 randconfig-002-20241214    gcc-14.2.0
sh                              allmodconfig    gcc-14.2.0
sh                              allyesconfig    gcc-14.2.0
sh                   randconfig-001-20241214    gcc-14.2.0
sh                   randconfig-002-20241214    gcc-14.2.0
sparc                           allmodconfig    gcc-14.2.0
sparc                randconfig-001-20241214    gcc-14.2.0
sparc                randconfig-002-20241214    gcc-14.2.0
sparc64              randconfig-001-20241214    gcc-14.2.0
sparc64              randconfig-002-20241214    gcc-14.2.0
um                               allnoconfig    clang-18
um                   randconfig-001-20241214    clang-20
um                   randconfig-002-20241214    clang-17
x86_64                           allnoconfig    clang-19
x86_64     buildonly-randconfig-001-20241214    gcc-11
x86_64     buildonly-randconfig-002-20241214    clang-19
x86_64     buildonly-randconfig-003-20241214    gcc-12
x86_64     buildonly-randconfig-004-20241214    gcc-12
x86_64     buildonly-randconfig-005-20241214    gcc-12
x86_64     buildonly-randconfig-006-20241214    clang-19
x86_64                             defconfig    gcc-11
xtensa               randconfig-001-20241214    gcc-14.2.0
xtensa               randconfig-002-20241214    gcc-14.2.0

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


From apatel at ventanamicro.com  Sat Dec 14 09:25:38 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:38 +0530
Subject: [PATCH v2 00/11] RISC-V IMSIC driver improvements
Message-ID: <20241214172549.8842-1-apatel@ventanamicro.com>

This series is based on recent discussion on LKML:
https://lore.kernel.org/lkml/20241114161845.502027-18-ajones at ventanamicro.com/

It primarily focuses on moving to RISC-V IMSIC driver use common MSI
lib and GENERIC_PENDING_IRQ.

PATCH1: Fix for handling non-atomic MSI updates
PATCH2 & PATCH3: Preparatory patches
PATCH4: Main patch which updates IMSIC driver to use MSI lib
PATCH5 & PATCH6: Preparatory patches for moving to GENERIC_PENDING_IRQ
PATCH7 to PATCH11: Patches use GENERIC_PENDING_IRQ in IMSIC driver

These patches can also be found in the riscv_imsic_imp_v2 branch at:
https://github.com/avpatel/linux.git

Changes since v1:
 - Changed series subject
 - Expand this series to use GENERIC_PENDING_IRQ in IMSIC driver

Andrew Jones (1):
  irqchip/riscv-imsic: Set irq_set_affinity for IMSIC base

Anup Patel (7):
  irqchip/riscv-imsic: Handle non-atomic MSI updates for device
  genirq: Introduce common irq_force_complete_move() implementation
  RISC-V: Enable GENERIC_PENDING_IRQ and GENERIC_PENDING_IRQ_CHIPFLAGS
  irqchip/riscv-imsic: Separate next and previous pointers in IMSIC
    vector
  irqchip/riscv-imsic: Implement irq_force_complete_move() for IMSIC
  irqchip/riscv-imsic: Replace hwirq with irq in the IMSIC vector
  irqchip/riscv-imsic: Use IRQCHIP_MOVE_DEFERRED flag for PCI devices

Thomas Gleixner (3):
  irqchip/irq-msi-lib: Optionally set default irq_eoi/irq_ack
  irqchip/riscv-imsic: Move to common MSI lib
  genirq: Introduce kconfig option GENERIC_PENDING_IRQ_CHIPFLAGS

 arch/riscv/Kconfig                         |   2 +
 drivers/irqchip/Kconfig                    |   8 +-
 drivers/irqchip/irq-gic-v2m.c              |   1 +
 drivers/irqchip/irq-imx-mu-msi.c           |   1 +
 drivers/irqchip/irq-msi-lib.c              |  11 +-
 drivers/irqchip/irq-mvebu-gicp.c           |   1 +
 drivers/irqchip/irq-mvebu-odmi.c           |   1 +
 drivers/irqchip/irq-mvebu-sei.c            |   1 +
 drivers/irqchip/irq-riscv-imsic-early.c    |  14 +-
 drivers/irqchip/irq-riscv-imsic-platform.c | 177 +++++++++------------
 drivers/irqchip/irq-riscv-imsic-state.c    | 110 +++++++++----
 drivers/irqchip/irq-riscv-imsic-state.h    |  12 +-
 include/linux/irq.h                        |  15 ++
 include/linux/msi.h                        |  11 ++
 kernel/irq/Kconfig                         |   4 +
 kernel/irq/chip.c                          |  39 ++++-
 kernel/irq/irqdomain.c                     |   1 +
 kernel/irq/migration.c                     |   9 ++
 18 files changed, 262 insertions(+), 156 deletions(-)

-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:39 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:39 +0530
Subject: [PATCH v2 01/11] irqchip/riscv-imsic: Handle non-atomic MSI updates for device
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-2-apatel@ventanamicro.com>

Device having non-atomic MSI update might see an intermediate
state when changing target IMSIC vector from one CPU to another.

To handle such intermediate device state, update MSI address
and MSI data through separate MSI writes to the device.

Fixes: 027e125acdba ("irqchip/riscv-imsic: Add device MSI domain support for platform devices")
Suggested-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-early.c    |  8 +++-
 drivers/irqchip/irq-riscv-imsic-platform.c | 27 ++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.c    | 50 ++++++++++++++--------
 drivers/irqchip/irq-riscv-imsic-state.h    |  2 +-
 4 files changed, 68 insertions(+), 19 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
index c5c2e6929a2f..73a93ce8668f 100644
--- a/drivers/irqchip/irq-riscv-imsic-early.c
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -77,6 +77,12 @@ static void imsic_handle_irq(struct irq_desc *desc)
 	struct imsic_vector *vec;
 	unsigned long local_id;
 
+	/*
+	 * First process pending IMSIC vector enable, disable and movement
+	 * on the current CPU.
+	 */
+	imsic_local_sync_all(false);
+
 	chained_irq_enter(chip, desc);
 
 	while ((local_id = csr_swap(CSR_TOPEI, 0))) {
@@ -120,7 +126,7 @@ static int imsic_starting_cpu(unsigned int 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();
+	imsic_local_sync_all(true);
 
 	/* Enable local interrupt delivery */
 	imsic_local_delivery(true);
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index c708780e8760..b44eb0b3990b 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -97,6 +97,7 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 {
 	struct imsic_vector *old_vec, *new_vec;
 	struct irq_data *pd = d->parent_data;
+	struct imsic_vector tmp_vec;
 
 	old_vec = irq_data_get_irq_chip_data(pd);
 	if (WARN_ON(!old_vec))
@@ -115,6 +116,32 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 	if (!new_vec)
 		return -ENOSPC;
 
+	/*
+	 * Device having non-atomic MSI update might see an intermediate
+	 * state when changing target IMSIC vector from one CPU to another.
+	 *
+	 * To avoid losing interrupt to some intermediate state, do the
+	 * following (just like x86 APIC):
+	 *
+	 * 1) First write a temporary IMSIC vector to the device which
+	 * has MSI address same as the old IMSIC vector but MSI data
+	 * matches the new IMSIC vector.
+	 *
+	 * 2) Next write the new IMSIC vector to the device.
+	 *
+	 * Based on the above, the __imsic_local_sync() must check both
+	 * old MSI data and new MSI data on the old CPU for pending
+	 */
+
+	if (new_vec->local_id != old_vec->local_id) {
+		/* Setup temporary vector */
+		tmp_vec.cpu = old_vec->cpu;
+		tmp_vec.local_id = new_vec->local_id;
+
+		/* Point device to the temporary vector */
+		imsic_msi_update_msg(d, &tmp_vec);
+	}
+
 	/* Point device to the new vector */
 	imsic_msi_update_msg(d, new_vec);
 
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index b97e6cd89ed7..a8645084bd8f 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -126,21 +126,21 @@ void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend,
 
 static void __imsic_local_sync(struct imsic_local_priv *lpriv)
 {
-	struct imsic_local_config *mlocal;
-	struct imsic_vector *vec, *mvec;
+	struct imsic_local_config *tlocal, *mlocal;
+	struct imsic_vector *vec, *tvec, *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;
+			continue;
 		vec = &lpriv->vectors[i];
 
 		if (READ_ONCE(vec->enable))
-			__imsic_id_set_enable(i);
+			__imsic_id_set_enable(vec->local_id);
 		else
-			__imsic_id_clear_enable(i);
+			__imsic_id_clear_enable(vec->local_id);
 
 		/*
 		 * If the ID was being moved to a new ID on some other CPU
@@ -151,26 +151,47 @@ static void __imsic_local_sync(struct imsic_local_priv *lpriv)
 		mvec = READ_ONCE(vec->move);
 		WRITE_ONCE(vec->move, NULL);
 		if (mvec && mvec != vec) {
-			if (__imsic_id_read_clear_pending(i)) {
+			/*
+			 * Device having non-atomic MSI update might see an
+			 * intermediate state so check both old ID and new ID
+			 * for pending interrupts.
+			 *
+			 * For details, refer imsic_irq_set_affinity().
+			 */
+
+			tvec = vec->local_id == mvec->local_id ?
+			       NULL : &lpriv->vectors[mvec->local_id];
+			if (tvec && __imsic_id_read_clear_pending(tvec->local_id)) {
+				/* Retrigger temporary vector if it was already in-use */
+				if (READ_ONCE(tvec->enable)) {
+					tlocal = per_cpu_ptr(imsic->global.local, tvec->cpu);
+					writel_relaxed(tvec->local_id, tlocal->msi_va);
+				}
+
 				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
 				writel_relaxed(mvec->local_id, mlocal->msi_va);
 			}
 
-			imsic_vector_free(&lpriv->vectors[i]);
+			if (__imsic_id_read_clear_pending(vec->local_id)) {
+				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
+				writel_relaxed(mvec->local_id, mlocal->msi_va);
+			}
+
+			imsic_vector_free(vec);
 		}
 
-skip:
-		bitmap_clear(lpriv->dirty_bitmap, i, 1);
+		bitmap_clear(lpriv->dirty_bitmap, vec->local_id, 1);
 	}
 }
 
-void imsic_local_sync_all(void)
+void imsic_local_sync_all(bool force_all)
 {
 	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);
+	if (force_all)
+		bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
 	__imsic_local_sync(lpriv);
 	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
 }
@@ -190,12 +211,7 @@ void imsic_local_delivery(bool enable)
 #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);
+	imsic_local_sync_all(false);
 }
 
 static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 391e44280827..8fae6c99b019 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -74,7 +74,7 @@ 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_sync_all(bool force_all);
 void imsic_local_delivery(bool enable);
 
 void imsic_vector_mask(struct imsic_vector *vec);
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:40 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:40 +0530
Subject: [PATCH v2 02/11] irqchip/irq-msi-lib: Optionally set default irq_eoi/irq_ack
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-3-apatel@ventanamicro.com>

From: Thomas Gleixner <tglx at linutronix.de>

Introduce chip_flags in struct msi_parent_ops. This allows
msi_lib_init_dev_msi_info() set default irq_eoi/irq_ack
callbacks only when the corresponding flags are set in
the chip_flags.

Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-gic-v2m.c    |  1 +
 drivers/irqchip/irq-imx-mu-msi.c |  1 +
 drivers/irqchip/irq-msi-lib.c    | 11 ++++++-----
 drivers/irqchip/irq-mvebu-gicp.c |  1 +
 drivers/irqchip/irq-mvebu-odmi.c |  1 +
 drivers/irqchip/irq-mvebu-sei.c  |  1 +
 include/linux/msi.h              | 11 +++++++++++
 7 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index be35c5349986..1e3476c335ca 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -255,6 +255,7 @@ static void __init gicv2m_teardown(void)
 static struct msi_parent_ops gicv2m_msi_parent_ops = {
 	.supported_flags	= GICV2M_MSI_FLAGS_SUPPORTED,
 	.required_flags		= GICV2M_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
 	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
 	.prefix			= "GICv2m-",
diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c
index 4342a21de1eb..69aacdfc8bef 100644
--- a/drivers/irqchip/irq-imx-mu-msi.c
+++ b/drivers/irqchip/irq-imx-mu-msi.c
@@ -214,6 +214,7 @@ static void imx_mu_msi_irq_handler(struct irq_desc *desc)
 static const struct msi_parent_ops imx_mu_msi_parent_ops = {
 	.supported_flags	= IMX_MU_MSI_FLAGS_SUPPORTED,
 	.required_flags		= IMX_MU_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_token       = DOMAIN_BUS_NEXUS,
 	.bus_select_mask	= MATCH_PLATFORM_MSI,
 	.prefix			= "MU-MSI-",
diff --git a/drivers/irqchip/irq-msi-lib.c b/drivers/irqchip/irq-msi-lib.c
index d8e29fc0d406..51464c6257f3 100644
--- a/drivers/irqchip/irq-msi-lib.c
+++ b/drivers/irqchip/irq-msi-lib.c
@@ -28,6 +28,7 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 			       struct msi_domain_info *info)
 {
 	const struct msi_parent_ops *pops = real_parent->msi_parent_ops;
+	struct irq_chip *chip = info->chip;
 	u32 required_flags;
 
 	/* Parent ops available? */
@@ -92,10 +93,10 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 	info->flags			|= required_flags;
 
 	/* Chip updates for all child bus types */
-	if (!info->chip->irq_eoi)
-		info->chip->irq_eoi	= irq_chip_eoi_parent;
-	if (!info->chip->irq_ack)
-		info->chip->irq_ack	= irq_chip_ack_parent;
+	if (!chip->irq_eoi && (pops->chip_flags & MSI_CHIP_FLAG_SET_EOI))
+		chip->irq_eoi = irq_chip_eoi_parent;
+	if (!chip->irq_ack && (pops->chip_flags & MSI_CHIP_FLAG_SET_ACK))
+		chip->irq_ack = irq_chip_ack_parent;
 
 	/*
 	 * The device MSI domain can never have a set affinity callback. It
@@ -105,7 +106,7 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 	 * device MSI domain aside of mask/unmask which is provided e.g. by
 	 * PCI/MSI device domains.
 	 */
-	info->chip->irq_set_affinity	= msi_domain_set_affinity;
+	chip->irq_set_affinity = msi_domain_set_affinity;
 	return true;
 }
 EXPORT_SYMBOL_GPL(msi_lib_init_dev_msi_info);
diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c
index 2b6183919ea4..d67f93f6d750 100644
--- a/drivers/irqchip/irq-mvebu-gicp.c
+++ b/drivers/irqchip/irq-mvebu-gicp.c
@@ -161,6 +161,7 @@ static const struct irq_domain_ops gicp_domain_ops = {
 static const struct msi_parent_ops gicp_msi_parent_ops = {
 	.supported_flags	= GICP_MSI_FLAGS_SUPPORTED,
 	.required_flags		= GICP_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_token       = DOMAIN_BUS_GENERIC_MSI,
 	.bus_select_mask	= MATCH_PLATFORM_MSI,
 	.prefix			= "GICP-",
diff --git a/drivers/irqchip/irq-mvebu-odmi.c b/drivers/irqchip/irq-mvebu-odmi.c
index ff19bfd258dc..28f7e81df94f 100644
--- a/drivers/irqchip/irq-mvebu-odmi.c
+++ b/drivers/irqchip/irq-mvebu-odmi.c
@@ -157,6 +157,7 @@ static const struct irq_domain_ops odmi_domain_ops = {
 static const struct msi_parent_ops odmi_msi_parent_ops = {
 	.supported_flags	= ODMI_MSI_FLAGS_SUPPORTED,
 	.required_flags		= ODMI_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_token	= DOMAIN_BUS_GENERIC_MSI,
 	.bus_select_mask	= MATCH_PLATFORM_MSI,
 	.prefix			= "ODMI-",
diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c
index 065166ab5dbc..ebd4a9014e8d 100644
--- a/drivers/irqchip/irq-mvebu-sei.c
+++ b/drivers/irqchip/irq-mvebu-sei.c
@@ -356,6 +356,7 @@ static void mvebu_sei_reset(struct mvebu_sei *sei)
 static const struct msi_parent_ops sei_msi_parent_ops = {
 	.supported_flags	= SEI_MSI_FLAGS_SUPPORTED,
 	.required_flags		= SEI_MSI_FLAGS_REQUIRED,
+	.chip_flags		= MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_mask	= MATCH_PLATFORM_MSI,
 	.bus_select_token	= DOMAIN_BUS_GENERIC_MSI,
 	.prefix			= "SEI-",
diff --git a/include/linux/msi.h b/include/linux/msi.h
index b10093c4d00e..9abef442c146 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -558,11 +558,21 @@ enum {
 	MSI_FLAG_NO_AFFINITY		= (1 << 21),
 };
 
+/*
+ * Flags for msi_parent_ops::chip_flags
+ */
+enum {
+	MSI_CHIP_FLAG_SET_EOI		= (1 << 0),
+	MSI_CHIP_FLAG_SET_ACK		= (1 << 1),
+};
+
 /**
  * struct msi_parent_ops - MSI parent domain callbacks and configuration info
  *
  * @supported_flags:	Required: The supported MSI flags of the parent domain
  * @required_flags:	Optional: The required MSI flags of the parent MSI domain
+ * @chip_flags:		Optional: Select MSI chip callbacks to update with defaults
+ *			in msi_lib_init_dev_msi_info().
  * @bus_select_token:	Optional: The bus token of the real parent domain for
  *			irq_domain::select()
  * @bus_select_mask:	Optional: A mask of supported BUS_DOMAINs for
@@ -575,6 +585,7 @@ enum {
 struct msi_parent_ops {
 	u32		supported_flags;
 	u32		required_flags;
+	u32		chip_flags;
 	u32		bus_select_token;
 	u32		bus_select_mask;
 	const char	*prefix;
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:41 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:41 +0530
Subject: [PATCH v2 03/11] irqchip/riscv-imsic: Set irq_set_affinity for IMSIC base
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-4-apatel@ventanamicro.com>

From: Andrew Jones <ajones at ventanamicro.com>

Instead of using imsic_irq_set_affinity() for leaf MSI domains,
use imsic_irq_set_affinity() for the non-leaf IMSIC base domain
and use irq_chip_set_affinity_parent() for leaf MSI domains.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index b44eb0b3990b..dc6f63f657e4 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -96,10 +96,9 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 				  bool force)
 {
 	struct imsic_vector *old_vec, *new_vec;
-	struct irq_data *pd = d->parent_data;
 	struct imsic_vector tmp_vec;
 
-	old_vec = irq_data_get_irq_chip_data(pd);
+	old_vec = irq_data_get_irq_chip_data(d);
 	if (WARN_ON(!old_vec))
 		return -ENOENT;
 
@@ -139,17 +138,17 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 		tmp_vec.local_id = new_vec->local_id;
 
 		/* Point device to the temporary vector */
-		imsic_msi_update_msg(d, &tmp_vec);
+		imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec);
 	}
 
 	/* Point device to the new vector */
-	imsic_msi_update_msg(d, new_vec);
+	imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec);
 
 	/* Update irq descriptors with the new vector */
-	pd->chip_data = new_vec;
+	d->chip_data = new_vec;
 
-	/* Update effective affinity of parent irq data */
-	irq_data_update_effective_affinity(pd, cpumask_of(new_vec->cpu));
+	/* Update effective affinity */
+	irq_data_update_effective_affinity(d, cpumask_of(new_vec->cpu));
 
 	/* Move state of the old vector to the new vector */
 	imsic_vector_move(old_vec, new_vec);
@@ -162,6 +161,9 @@ static struct irq_chip imsic_irq_base_chip = {
 	.name			= "IMSIC",
 	.irq_mask		= imsic_irq_mask,
 	.irq_unmask		= imsic_irq_unmask,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= imsic_irq_set_affinity,
+#endif
 	.irq_retrigger		= imsic_irq_retrigger,
 	.irq_compose_msi_msg	= imsic_irq_compose_msg,
 	.flags			= IRQCHIP_SKIP_SET_WAKE |
@@ -272,7 +274,7 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 		if (WARN_ON_ONCE(domain != real_parent))
 			return false;
 #ifdef CONFIG_SMP
-		info->chip->irq_set_affinity = imsic_irq_set_affinity;
+		info->chip->irq_set_affinity = irq_chip_set_affinity_parent;
 #endif
 		break;
 	default:
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:42 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:42 +0530
Subject: [PATCH v2 04/11] irqchip/riscv-imsic: Move to common MSI lib
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-5-apatel@ventanamicro.com>

From: Thomas Gleixner <tglx at linutronix.de>

Simplify the leaf MSI domain handling in the RISC-V IMSIC driver by
using msi_lib_init_dev_msi_info() and msi_lib_irq_domain_select()
provided by common MSI lib.

Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                    |   8 +-
 drivers/irqchip/irq-riscv-imsic-platform.c | 114 +--------------------
 2 files changed, 6 insertions(+), 116 deletions(-)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 55d7122121e2..6b767b8c974f 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -587,13 +587,7 @@ config RISCV_IMSIC
 	select IRQ_DOMAIN_HIERARCHY
 	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
+	select IRQ_MSI_LIB
 
 config SIFIVE_PLIC
 	bool
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index dc6f63f657e4..2fab20d2ce3e 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/smp.h>
 
+#include "irq-msi-lib.h"
 #include "irq-riscv-imsic-state.h"
 
 static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
@@ -201,22 +202,6 @@ static void imsic_irq_domain_free(struct irq_domain *domain, unsigned int virq,
 	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)
@@ -233,110 +218,21 @@ static void imsic_irq_debug_show(struct seq_file *m, struct irq_domain *d,
 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,
+	.select		= msi_lib_irq_domain_select,
 #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
 	.debug_show	= imsic_irq_debug_show,
 #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,
-				    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 = irq_chip_set_affinity_parent;
-#endif
-		break;
-	default:
-		WARN_ON_ONCE(1);
-		return false;
-	}
-
-	/* 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
-		 * 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 |
 				  MSI_FLAG_PCI_MSIX,
 	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
-				  MSI_FLAG_USE_DEF_CHIP_OPS,
+				  MSI_FLAG_USE_DEF_CHIP_OPS |
+				  MSI_FLAG_PCI_MSI_MASK_PARENT,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
 	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
-	.init_dev_msi_info	= imsic_init_dev_msi_info,
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
 
 int imsic_irqdomain_init(void)
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:43 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:43 +0530
Subject: [PATCH v2 05/11] genirq: Introduce kconfig option GENERIC_PENDING_IRQ_CHIPFLAGS
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-6-apatel@ventanamicro.com>

From: Thomas Gleixner <tglx at linutronix.de>

Introduce kconfig option GENERIC_PENDING_IRQ_CHIPFLAGS which allows
irq core to set IRQD_MOVE_PCNTXT flag based on IRQCHIP_MOVE_DEFERRED
flag.

This kconfig option will help architectures such as x86 and RISC-V
to mark top-level irqchip instances where irqs can't be moved in
the process context.

Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 include/linux/irq.h    | 10 ++++++++++
 kernel/irq/Kconfig     |  4 ++++
 kernel/irq/chip.c      | 39 ++++++++++++++++++++++++++++++++++++---
 kernel/irq/irqdomain.c |  1 +
 4 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index fa711f80957b..b689c8fe8d60 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -567,6 +567,7 @@ struct irq_chip {
  *                                    in the suspend path if they are in disabled state
  * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
  * IRQCHIP_IMMUTABLE:		      Don't ever change anything in this chip
+ * IRQCHIP_MOVE_DEFERRED:             Move the interrupt in actual interrupt context
  */
 enum {
 	IRQCHIP_SET_TYPE_MASKED			= (1 <<  0),
@@ -581,6 +582,7 @@ enum {
 	IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND	= (1 <<  9),
 	IRQCHIP_AFFINITY_PRE_STARTUP		= (1 << 10),
 	IRQCHIP_IMMUTABLE			= (1 << 11),
+	IRQCHIP_MOVE_DEFERRED			= (1 << 12),
 };
 
 #include <linux/irqdesc.h>
@@ -634,6 +636,14 @@ static inline void irq_move_masked_irq(struct irq_data *data) { }
 static inline void irq_force_complete_move(struct irq_desc *desc) { }
 #endif
 
+#if defined(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS)
+void irq_update_pcntxt_flag(unsigned int irq, const struct irq_chip *chip);
+#else
+static inline void irq_update_pcntxt_flag(unsigned int irq, const struct irq_chip *chip)
+{
+}
+#endif
+
 extern int no_irq_affinity;
 
 #ifdef CONFIG_HARDIRQS_SW_RESEND
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 529adb1f5859..6d85a47fbf41 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -31,6 +31,10 @@ config GENERIC_IRQ_EFFECTIVE_AFF_MASK
 config GENERIC_PENDING_IRQ
 	bool
 
+# Deduce delayed migration from top-level interrupt chip flags
+config GENERIC_PENDING_IRQ_CHIPFLAGS
+	bool
+
 # Support for generic irq migrating off cpu before the cpu is offline.
 config GENERIC_IRQ_MIGRATION
 	bool
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 271e9139de77..623959a24464 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -33,6 +33,33 @@ struct irqaction chained_action = {
 	.handler = bad_chained_irq,
 };
 
+#ifdef CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS
+static void __irq_update_pcntxt_flag(struct irq_desc *desc,
+				     const struct irq_chip *chip)
+{
+	if (chip) {
+		if (chip->flags & IRQCHIP_MOVE_DEFERRED)
+			irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
+		else
+			irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
+	}
+}
+
+void irq_update_pcntxt_flag(unsigned int irq, const struct irq_chip *chip)
+{
+	unsigned long flags;
+	struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+
+	__irq_update_pcntxt_flag(desc, chip);
+	irq_put_desc_unlock(desc, flags);
+}
+#else
+static inline void __irq_update_pcntxt_flag(struct irq_desc *desc,
+					    const struct irq_chip *chip)
+{
+}
+#endif
+
 /**
  *	irq_set_chip - set the irq chip for an irq
  *	@irq:	irq number
@@ -47,6 +74,7 @@ int irq_set_chip(unsigned int irq, const struct irq_chip *chip)
 		return -EINVAL;
 
 	desc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
+	__irq_update_pcntxt_flag(desc, chip);
 	irq_put_desc_unlock(desc, flags);
 	/*
 	 * For !CONFIG_SPARSE_IRQ make the irq show up in
@@ -1114,16 +1142,21 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
 	trigger = irqd_get_trigger_type(&desc->irq_data);
 
 	irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
-		   IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT);
+		   IRQD_TRIGGER_MASK | IRQD_LEVEL);
 	if (irq_settings_has_no_balance_set(desc))
 		irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
 	if (irq_settings_is_per_cpu(desc))
 		irqd_set(&desc->irq_data, IRQD_PER_CPU);
-	if (irq_settings_can_move_pcntxt(desc))
-		irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
 	if (irq_settings_is_level(desc))
 		irqd_set(&desc->irq_data, IRQD_LEVEL);
 
+	/* Keep this around until x86 is converted over */
+	if (!IS_ENABLED(CONFIG_GENERIC_PENDING_IRQ_CHIPFLAGS)) {
+		irqd_clear(&desc->irq_data, IRQD_MOVE_PCNTXT);
+		if (irq_settings_can_move_pcntxt(desc))
+			irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
+	}
+
 	tmp = irq_settings_get_trigger_mask(desc);
 	if (tmp != IRQ_TYPE_NONE)
 		trigger = tmp;
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index ec6d8e72d980..ec5fc1d8cebe 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1508,6 +1508,7 @@ int irq_domain_set_hwirq_and_chip(struct irq_domain *domain, unsigned int virq,
 	irq_data->hwirq = hwirq;
 	irq_data->chip = (struct irq_chip *)(chip ? chip : &no_irq_chip);
 	irq_data->chip_data = chip_data;
+	irq_update_pcntxt_flag(virq, chip);
 
 	return 0;
 }
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:44 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:44 +0530
Subject: [PATCH v2 06/11] genirq: Introduce common irq_force_complete_move() implementation
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-7-apatel@ventanamicro.com>

The GENERIC_PENDING_IRQ requires an arch specific implementation
of irq_force_complete_move(). At the moment, only x86 implements
this but for RISC-V the irq_force_complete_move() is only needed
when RISC-V IMSIC driver is in use and not needed otherwise.

To address the above, introduce common weak implementation of
the irq_force_complete_move() which lets irqchip do the actual
irq_force_complete_move().

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 include/linux/irq.h    | 5 +++++
 kernel/irq/migration.c | 9 +++++++++
 2 files changed, 14 insertions(+)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index b689c8fe8d60..509c0ee4ef38 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -496,6 +496,7 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
  * @ipi_send_mask:	send an IPI to destination cpus in cpumask
  * @irq_nmi_setup:	function called from core code before enabling an NMI
  * @irq_nmi_teardown:	function called from core code after disabling an NMI
+ * @irq_force_complete_move:	optional function to force complete pending irq move
  * @flags:		chip specific flags
  */
 struct irq_chip {
@@ -547,6 +548,10 @@ struct irq_chip {
 	int		(*irq_nmi_setup)(struct irq_data *data);
 	void		(*irq_nmi_teardown)(struct irq_data *data);
 
+#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
+	void		(*irq_force_complete_move)(struct irq_data *data);
+#endif
+
 	unsigned long	flags;
 };
 
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index eb150afd671f..2920024475a3 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -5,6 +5,15 @@
 
 #include "internals.h"
 
+void __weak irq_force_complete_move(struct irq_desc *desc)
+{
+	struct irq_data *d = irq_desc_get_irq_data(desc);
+	struct irq_chip *chip = irq_data_get_irq_chip(d);
+
+	if (chip && chip->irq_force_complete_move)
+		chip->irq_force_complete_move(d);
+}
+
 /**
  * irq_fixup_move_pending - Cleanup irq move pending from a dying CPU
  * @desc:		Interrupt descriptor to clean up
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:45 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:45 +0530
Subject: [PATCH v2 07/11] RISC-V: Enable GENERIC_PENDING_IRQ and GENERIC_PENDING_IRQ_CHIPFLAGS
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-8-apatel@ventanamicro.com>

Enable GENERIC_PENDING_IRQ and GENERIC_PENDING_IRQ_CHIPFLAGS for RISC-V
so that RISC-V irqchips can support delayed irq mirgration in the
interrupt context.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 arch/riscv/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index d4a7ca0388c0..adc878f029fb 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -110,6 +110,8 @@ config RISCV
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IRQ_SHOW_LEVEL
 	select GENERIC_LIB_DEVMEM_IS_ALLOWED
+	select GENERIC_PENDING_IRQ if SMP
+	select GENERIC_PENDING_IRQ_CHIPFLAGS if SMP
 	select GENERIC_PCI_IOMAP
 	select GENERIC_PTDUMP if MMU
 	select GENERIC_SCHED_CLOCK
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:46 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:46 +0530
Subject: [PATCH v2 08/11] irqchip/riscv-imsic: Separate next and previous pointers in IMSIC vector
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-9-apatel@ventanamicro.com>

Currently, there is only one "move" pointer in the struct imsic_vector
so during vector movement the old vector points to the new vector and
new vector points to itself.

To support force cleanup of old vector, add separate "move_next" and
"move_prev" pointers in the struct imsic_vector where during vector
movement the "move_next" pointer of the old vector points to the
new vector and the "move_prev" pointer of the new vector points to
the old vector. Both "move_next" pointers are cleared separately
by __imsic_local_sync() on the old and new CPUs respectively.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-state.c | 60 +++++++++++++++++++------
 drivers/irqchip/irq-riscv-imsic-state.h |  5 ++-
 2 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index a8645084bd8f..da49a160ea09 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -124,10 +124,11 @@ void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend,
 	}
 }
 
-static void __imsic_local_sync(struct imsic_local_priv *lpriv)
+static bool __imsic_local_sync(struct imsic_local_priv *lpriv)
 {
 	struct imsic_local_config *tlocal, *mlocal;
 	struct imsic_vector *vec, *tvec, *mvec;
+	bool ret = true;
 	int i;
 
 	lockdep_assert_held(&lpriv->lock);
@@ -142,15 +143,33 @@ static void __imsic_local_sync(struct imsic_local_priv *lpriv)
 		else
 			__imsic_id_clear_enable(vec->local_id);
 
+		/*
+		 * If the ID was being moved from an existing ID on some
+		 * other CPU then we clear the pervious vector pointer
+		 * only after the movement is complete.
+		 */
+		mvec = READ_ONCE(vec->move_prev);
+		if (mvec) {
+			/*
+			 * If the old IMSIC vector has not been updated then
+			 * try again in the next sync-up call.
+			 */
+			if (READ_ONCE(mvec->move_next)) {
+				ret = false;
+				continue;
+			}
+
+			WRITE_ONCE(vec->move_prev, NULL);
+		}
+
 		/*
 		 * 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) {
+		mvec = READ_ONCE(vec->move_next);
+		if (mvec) {
 			/*
 			 * Device having non-atomic MSI update might see an
 			 * intermediate state so check both old ID and new ID
@@ -177,11 +196,14 @@ static void __imsic_local_sync(struct imsic_local_priv *lpriv)
 				writel_relaxed(mvec->local_id, mlocal->msi_va);
 			}
 
+			WRITE_ONCE(vec->move_next, NULL);
 			imsic_vector_free(vec);
 		}
 
 		bitmap_clear(lpriv->dirty_bitmap, vec->local_id, 1);
 	}
+
+	return ret;
 }
 
 void imsic_local_sync_all(bool force_all)
@@ -190,9 +212,16 @@ void imsic_local_sync_all(bool force_all)
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&lpriv->lock, flags);
+
 	if (force_all)
 		bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
-	__imsic_local_sync(lpriv);
+	if (!__imsic_local_sync(lpriv)) {
+		if (!timer_pending(&lpriv->timer)) {
+			lpriv->timer.expires = jiffies + 1;
+			add_timer_on(&lpriv->timer, smp_processor_id());
+		}
+	}
+
 	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
 }
 
@@ -232,8 +261,8 @@ static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu
 	 */
 	if (cpu_online(cpu)) {
 		if (cpu == smp_processor_id()) {
-			__imsic_local_sync(lpriv);
-			return;
+			if (__imsic_local_sync(lpriv))
+				return;
 		}
 
 		if (!timer_pending(&lpriv->timer)) {
@@ -294,8 +323,9 @@ void imsic_vector_unmask(struct imsic_vector *vec)
 	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)
+static bool imsic_vector_move_update(struct imsic_local_priv *lpriv,
+				     struct imsic_vector *vec, bool is_old_vec,
+				     bool new_enable, struct imsic_vector *move_vec)
 {
 	unsigned long flags;
 	bool enabled;
@@ -305,7 +335,10 @@ static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsi
 	/* Update enable and move details */
 	enabled = READ_ONCE(vec->enable);
 	WRITE_ONCE(vec->enable, new_enable);
-	WRITE_ONCE(vec->move, new_move);
+	if (is_old_vec)
+		WRITE_ONCE(vec->move_next, move_vec);
+	else
+		WRITE_ONCE(vec->move_prev, move_vec);
 
 	/* Mark the vector as dirty and synchronize */
 	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
@@ -338,8 +371,8 @@ void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_ve
 	 * 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);
+	enabled = imsic_vector_move_update(old_lpriv, old_vec, true, false, new_vec);
+	imsic_vector_move_update(new_lpriv, new_vec, false, enabled, old_vec);
 }
 
 #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
@@ -402,7 +435,8 @@ struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask
 	vec = &lpriv->vectors[local_id];
 	vec->hwirq = hwirq;
 	vec->enable = false;
-	vec->move = NULL;
+	vec->move_next = NULL;
+	vec->move_prev = NULL;
 
 	return vec;
 }
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 8fae6c99b019..f02842b84ed5 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -23,7 +23,8 @@ struct imsic_vector {
 	unsigned int				hwirq;
 	/* Details accessed using local lock held */
 	bool					enable;
-	struct imsic_vector			*move;
+	struct imsic_vector			*move_next;
+	struct imsic_vector			*move_prev;
 };
 
 struct imsic_local_priv {
@@ -87,7 +88,7 @@ static inline bool imsic_vector_isenabled(struct imsic_vector *vec)
 
 static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec)
 {
-	return READ_ONCE(vec->move);
+	return READ_ONCE(vec->move_prev);
 }
 
 void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec);
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:47 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:47 +0530
Subject: [PATCH v2 09/11] irqchip/riscv-imsic: Implement irq_force_complete_move() for IMSIC
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-10-apatel@ventanamicro.com>

Implement irq_force_complete_move() for IMSIC driver so that in-flight
vector movements on a CPU can be cleaned-up when the CPU goes down.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 32 ++++++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.c    | 17 ++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h    |  1 +
 3 files changed, 50 insertions(+)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 2fab20d2ce3e..fae47b8ccf73 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -156,6 +156,37 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 
 	return IRQ_SET_MASK_OK_DONE;
 }
+
+static void imsic_irq_force_complete_move(struct irq_data *d)
+{
+	struct imsic_vector *mvec, *vec = irq_data_get_irq_chip_data(d);
+	unsigned int cpu = smp_processor_id();
+
+	if (WARN_ON(!vec))
+		return;
+
+	/* Do nothing if there is no in-flight move */
+	mvec = imsic_vector_get_move(vec);
+	if (!mvec)
+		return;
+
+	/* Do nothing if the old IMSIC vector does not belong to current CPU */
+	if (mvec->cpu != cpu)
+		return;
+
+	/*
+	 * The best we can do is force cleanup the old IMSIC vector.
+	 *
+	 * The challenges over here are same as x86 vector domain so
+	 * refer to the comments in irq_force_complete_move() function
+	 * implemented at arch/x86/kernel/apic/vector.c.
+	 */
+
+	/* Force cleanup in-flight move */
+	pr_info("IRQ fixup: irq %d move in progress, old vector cpu %d local_id %d\n",
+		d->irq, mvec->cpu, mvec->local_id);
+	imsic_vector_force_move_cleanup(vec);
+}
 #endif
 
 static struct irq_chip imsic_irq_base_chip = {
@@ -164,6 +195,7 @@ static struct irq_chip imsic_irq_base_chip = {
 	.irq_unmask		= imsic_irq_unmask,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= imsic_irq_set_affinity,
+	.irq_force_complete_move = imsic_irq_force_complete_move,
 #endif
 	.irq_retrigger		= imsic_irq_retrigger,
 	.irq_compose_msi_msg	= imsic_irq_compose_msg,
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index da49a160ea09..c915a5cf4187 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -323,6 +323,23 @@ void imsic_vector_unmask(struct imsic_vector *vec)
 	raw_spin_unlock(&lpriv->lock);
 }
 
+void imsic_vector_force_move_cleanup(struct imsic_vector *vec)
+{
+	struct imsic_local_priv *lpriv;
+	struct imsic_vector *mvec;
+	unsigned long flags;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+
+	mvec = READ_ONCE(vec->move_prev);
+	WRITE_ONCE(vec->move_prev, NULL);
+	if (mvec)
+		imsic_vector_free(mvec);
+
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+}
+
 static bool imsic_vector_move_update(struct imsic_local_priv *lpriv,
 				     struct imsic_vector *vec, bool is_old_vec,
 				     bool new_enable, struct imsic_vector *move_vec)
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index f02842b84ed5..19dea0c77738 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -91,6 +91,7 @@ static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *ve
 	return READ_ONCE(vec->move_prev);
 }
 
+void imsic_vector_force_move_cleanup(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);
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:48 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:48 +0530
Subject: [PATCH v2 10/11] irqchip/riscv-imsic: Replace hwirq with irq in the IMSIC vector
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-11-apatel@ventanamicro.com>

Currently, the imsic_handle_irq() uses generic_handle_domain_irq() to
handle the irq which internally has an extra step of resolving hwirq
using domain. This extra step can be avoided by replacing hwirq with
irq in the IMSIC vector and directly calling generic_handle_irq().

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-early.c    | 6 ++----
 drivers/irqchip/irq-riscv-imsic-platform.c | 2 +-
 drivers/irqchip/irq-riscv-imsic-state.c    | 8 ++++----
 drivers/irqchip/irq-riscv-imsic-state.h    | 4 ++--
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
index 73a93ce8668f..0c94ce8ce580 100644
--- a/drivers/irqchip/irq-riscv-imsic-early.c
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -73,7 +73,7 @@ static int __init imsic_ipi_domain_init(void) { return 0; }
 static void imsic_handle_irq(struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int err, cpu = smp_processor_id();
+	int cpu = smp_processor_id();
 	struct imsic_vector *vec;
 	unsigned long local_id;
 
@@ -103,9 +103,7 @@ static void imsic_handle_irq(struct irq_desc *desc)
 			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);
+		generic_handle_irq(vec->irq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index fae47b8ccf73..e6c81718ba78 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -112,7 +112,7 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 		return -EBUSY;
 
 	/* Get a new vector on the desired set of CPUs */
-	new_vec = imsic_vector_alloc(old_vec->hwirq, mask_val);
+	new_vec = imsic_vector_alloc(old_vec->irq, mask_val);
 	if (!new_vec)
 		return -ENOSPC;
 
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index c915a5cf4187..aca769d915bf 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -434,7 +434,7 @@ struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int l
 	return &lpriv->vectors[local_id];
 }
 
-struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask)
+struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask)
 {
 	struct imsic_vector *vec = NULL;
 	struct imsic_local_priv *lpriv;
@@ -450,7 +450,7 @@ struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask
 
 	lpriv = per_cpu_ptr(imsic->lpriv, cpu);
 	vec = &lpriv->vectors[local_id];
-	vec->hwirq = hwirq;
+	vec->irq = irq;
 	vec->enable = false;
 	vec->move_next = NULL;
 	vec->move_prev = NULL;
@@ -463,7 +463,7 @@ void imsic_vector_free(struct imsic_vector *vec)
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
-	vec->hwirq = UINT_MAX;
+	vec->irq = 0;
 	irq_matrix_free(imsic->matrix, vec->cpu, vec->local_id, false);
 	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
 }
@@ -522,7 +522,7 @@ static int __init imsic_local_init(void)
 			vec = &lpriv->vectors[i];
 			vec->cpu = cpu;
 			vec->local_id = i;
-			vec->hwirq = UINT_MAX;
+			vec->irq = 0;
 		}
 	}
 
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 19dea0c77738..3202ffa4e849 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -20,7 +20,7 @@ struct imsic_vector {
 	unsigned int				cpu;
 	unsigned int				local_id;
 	/* Details saved by driver in the vector */
-	unsigned int				hwirq;
+	unsigned int				irq;
 	/* Details accessed using local lock held */
 	bool					enable;
 	struct imsic_vector			*move_next;
@@ -96,7 +96,7 @@ void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_ve
 
 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);
+struct imsic_vector *imsic_vector_alloc(unsigned int irq, 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);
-- 
2.43.0



From apatel at ventanamicro.com  Sat Dec 14 09:25:49 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 14 Dec 2024 22:55:49 +0530
Subject: [PATCH v2 11/11] irqchip/riscv-imsic: Use IRQCHIP_MOVE_DEFERRED flag for PCI devices
In-Reply-To: <20241214172549.8842-1-apatel@ventanamicro.com>
References: <20241214172549.8842-1-apatel@ventanamicro.com>
Message-ID: <20241214172549.8842-12-apatel@ventanamicro.com>

Devices (such as PCI) which have non-atomic MSI update should
migrate irq in the interrupt-context so use IRQCHIP_MOVE_DEFERRED
flag for corresponding irqchips.

The use of IRQCHIP_MOVE_DEFERRED further simplifies IMSIC vector
movement as follows:

1) No need to handle the intermediate state seen by devices with
   non-atomic MSI update because imsic_irq_set_affinity() is called
   in the interrupt-context with interrupt masked.
2) No need to check temporary vector when completing vector movement
   on the old CPU in __imsic_local_sync().
3) No need to call imsic_local_sync_all() from imsic_handle_irq()

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 74 ++++++++++++++--------
 drivers/irqchip/irq-riscv-imsic-state.c    | 25 +-------
 2 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index e6c81718ba78..eac7f358bbba 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -64,6 +64,11 @@ static int imsic_irq_retrigger(struct irq_data *d)
 	return 0;
 }
 
+static void imsic_irq_ack(struct irq_data *d)
+{
+	irq_move_irq(d);
+}
+
 static void imsic_irq_compose_vector_msg(struct imsic_vector *vec, struct msi_msg *msg)
 {
 	phys_addr_t msi_addr;
@@ -97,7 +102,20 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 				  bool force)
 {
 	struct imsic_vector *old_vec, *new_vec;
-	struct imsic_vector tmp_vec;
+
+	/*
+	 * Requirements for the downstream irqdomains (or devices):
+	 *
+	 * 1) Downstream irqdomains (or devices) with atomic MSI update can
+	 *    happily do imsic_irq_set_affinity() in the process-context on
+	 *    any CPU so the irqchip of such irqdomains must not set the
+	 *    IRQCHIP_MOVE_DEFERRED flag.
+	 *
+	 * 2) Downstream irqdomains (or devices) with non-atomic MSI update
+	 *    must do imsic_irq_set_affinity() in the interrupt-context upon
+	 *    next interrupt so the irqchip of such irqdomains must set the
+	 *    IRQCHIP_MOVE_DEFERRED flag.
+	 */
 
 	old_vec = irq_data_get_irq_chip_data(d);
 	if (WARN_ON(!old_vec))
@@ -117,31 +135,13 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 		return -ENOSPC;
 
 	/*
-	 * Device having non-atomic MSI update might see an intermediate
-	 * state when changing target IMSIC vector from one CPU to another.
-	 *
-	 * To avoid losing interrupt to some intermediate state, do the
-	 * following (just like x86 APIC):
-	 *
-	 * 1) First write a temporary IMSIC vector to the device which
-	 * has MSI address same as the old IMSIC vector but MSI data
-	 * matches the new IMSIC vector.
-	 *
-	 * 2) Next write the new IMSIC vector to the device.
-	 *
-	 * Based on the above, the __imsic_local_sync() must check both
-	 * old MSI data and new MSI data on the old CPU for pending
+	 * Downstream irqdomains (or devices) with non-atomic MSI update
+	 * may see an intermediate state when changing target IMSIC vector
+	 * from one CPU to another but using the IRQCHIP_MOVE_DEFERRED
+	 * flag this is taken care because imsic_irq_set_affinity() is
+	 * called in the interrupt-context with interrupt masked.
 	 */
 
-	if (new_vec->local_id != old_vec->local_id) {
-		/* Setup temporary vector */
-		tmp_vec.cpu = old_vec->cpu;
-		tmp_vec.local_id = new_vec->local_id;
-
-		/* Point device to the temporary vector */
-		imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec);
-	}
-
 	/* Point device to the new vector */
 	imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec);
 
@@ -198,6 +198,7 @@ static struct irq_chip imsic_irq_base_chip = {
 	.irq_force_complete_move = imsic_irq_force_complete_move,
 #endif
 	.irq_retrigger		= imsic_irq_retrigger,
+	.irq_ack		= imsic_irq_ack,
 	.irq_compose_msi_msg	= imsic_irq_compose_msg,
 	.flags			= IRQCHIP_SKIP_SET_WAKE |
 				  IRQCHIP_MASK_ON_SUSPEND,
@@ -217,7 +218,7 @@ static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 		return -ENOSPC;
 
 	irq_domain_set_info(domain, virq, virq, &imsic_irq_base_chip, vec,
-			    handle_simple_irq, NULL, NULL);
+			    handle_edge_irq, NULL, NULL);
 	irq_set_noprobe(virq);
 	irq_set_affinity(virq, cpu_online_mask);
 	irq_data_update_effective_affinity(irq_get_irq_data(virq), cpumask_of(vec->cpu));
@@ -256,15 +257,36 @@ static const struct irq_domain_ops imsic_base_domain_ops = {
 #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)
+{
+	if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
+		return false;
+
+	switch (info->bus_token) {
+	case DOMAIN_BUS_PCI_DEVICE_MSI:
+	case DOMAIN_BUS_PCI_DEVICE_MSIX:
+		info->chip->flags |= IRQCHIP_MOVE_DEFERRED;
+		break;
+	default:
+		break;
+	}
+
+	return true;
+}
+
 static const struct msi_parent_ops imsic_msi_parent_ops = {
 	.supported_flags	= MSI_GENERIC_FLAGS_MASK |
 				  MSI_FLAG_PCI_MSIX,
 	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
 				  MSI_FLAG_USE_DEF_CHIP_OPS |
 				  MSI_FLAG_PCI_MSI_MASK_PARENT,
+	.chip_flags		= MSI_CHIP_FLAG_SET_ACK,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
 	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
-	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
+	.init_dev_msi_info	= imsic_init_dev_msi_info,
 };
 
 int imsic_irqdomain_init(void)
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index aca769d915bf..c7649fb6bbe6 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -126,8 +126,8 @@ void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend,
 
 static bool __imsic_local_sync(struct imsic_local_priv *lpriv)
 {
-	struct imsic_local_config *tlocal, *mlocal;
-	struct imsic_vector *vec, *tvec, *mvec;
+	struct imsic_local_config *mlocal;
+	struct imsic_vector *vec, *mvec;
 	bool ret = true;
 	int i;
 
@@ -170,27 +170,6 @@ static bool __imsic_local_sync(struct imsic_local_priv *lpriv)
 		 */
 		mvec = READ_ONCE(vec->move_next);
 		if (mvec) {
-			/*
-			 * Device having non-atomic MSI update might see an
-			 * intermediate state so check both old ID and new ID
-			 * for pending interrupts.
-			 *
-			 * For details, refer imsic_irq_set_affinity().
-			 */
-
-			tvec = vec->local_id == mvec->local_id ?
-			       NULL : &lpriv->vectors[mvec->local_id];
-			if (tvec && __imsic_id_read_clear_pending(tvec->local_id)) {
-				/* Retrigger temporary vector if it was already in-use */
-				if (READ_ONCE(tvec->enable)) {
-					tlocal = per_cpu_ptr(imsic->global.local, tvec->cpu);
-					writel_relaxed(tvec->local_id, tlocal->msi_va);
-				}
-
-				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
-				writel_relaxed(mvec->local_id, mlocal->msi_va);
-			}
-
 			if (__imsic_id_read_clear_pending(vec->local_id)) {
 				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
 				writel_relaxed(mvec->local_id, mlocal->msi_va);
-- 
2.43.0



From David.Laight at ACULAB.COM  Sat Dec 14 09:30:53 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sat, 14 Dec 2024 17:30:53 +0000
Subject: [PATCH net-next] Fix clamp() of ip_vs_conn_tab on small memory
 systems.
Message-ID: <24a6bfd0811b4931b6ef40098b33c9ee@AcuMS.aculab.com>

The 'max_avail' value is calculated from the system memory
size using order_base_2().
order_base_2(x) is defined as '(x) ? fn(x) : 0'.
The compiler generates two copies of the code that follows
and then expands clamp(max, min, PAGE_SHIFT - 12) (11 on 32bit).
This triggers a compile-time assert since min is 5.

In reality a system would have to have less than 512MB memory
for the bounds passed to clamp to be reversed.

Swap the order of the arguments to clamp() to avoid the warning.

Replace the clamp_val() on the line below with clamp().
clamp_val() is just 'an accident waiting to happen' and not needed here.

Detected by compile time checks added to clamp(), specifically:
minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()

Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>
Closes: https://lore.kernel.org/all/CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g at mail.gmail.com/
Fixes: 4f325e26277b ("ipvs: dynamically limit the connection hash table")
Tested-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Signed-off-by: David Laight <david.laight at aculab.com>
---

Julian seems to be waiting for a 'v2' from me.
Changed target tree to 'net-next'.
I've re-written the commit message.
Copied Andrew Morton - he might want to take the change through the 'mm' tree.
Plausibly the 'fixes' tag should refer to the minmax.h change?
This will need back-porting if the minmax set get back-ported.

I'm not sure whether there ought to be an attribution to Dan Carpenter <dan.carpenter at linaro.org>

 net/netfilter/ipvs/ip_vs_conn.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 98d7dbe3d787..c0289f83f96d 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -1495,8 +1495,8 @@ int __init ip_vs_conn_init(void)
 	max_avail -= 2;		/* ~4 in hash row */
 	max_avail -= 1;		/* IPVS up to 1/2 of mem */
 	max_avail -= order_base_2(sizeof(struct ip_vs_conn));
-	max = clamp(max, min, max_avail);
-	ip_vs_conn_tab_bits = clamp_val(ip_vs_conn_tab_bits, min, max);
+	max = clamp(max_avail, min, max);
+	ip_vs_conn_tab_bits = clamp(ip_vs_conn_tab_bits, min, max);
 	ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
 	ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
 
-- 
2.17.1

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From lkp at intel.com  Sat Dec 14 09:40:16 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 15 Dec 2024 01:40:16 +0800
Subject: [soc:soc/defconfig] BUILD SUCCESS
 160825131614bbf0afaee837180391e313d9d08b
Message-ID: <202412150110.TsOzD253-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/defconfig
branch HEAD: 160825131614bbf0afaee837180391e313d9d08b  arm64: defconfig: Enable Amazon Elastic Network Adaptor

elapsed time: 1446m

configs tested: 4
configs skipped: 120

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

tested configs:
arm64  randconfig-001-20241214    clang-15
arm64  randconfig-002-20241214    clang-20
arm64  randconfig-003-20241214    clang-15
arm64  randconfig-004-20241214    gcc-14.2.0

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


From lkp at intel.com  Sat Dec 14 09:42:04 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 15 Dec 2024 01:42:04 +0800
Subject: [soc:soc/dt] BUILD SUCCESS
 b589fbc3f413c94b2f279c04ee802a008692a7fe
Message-ID: <202412150158.MpLg3nHH-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/dt
branch HEAD: b589fbc3f413c94b2f279c04ee802a008692a7fe  ARM: dts: nuvoton: Fix at24 EEPROM node names

elapsed time: 1448m

configs tested: 4
configs skipped: 120

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

tested configs:
arm  randconfig-001-20241214    gcc-14.2.0
arm  randconfig-002-20241214    clang-15
arm  randconfig-003-20241214    gcc-14.2.0
arm  randconfig-004-20241214    gcc-14.2.0

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


From lkp at intel.com  Sat Dec 14 09:43:25 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 15 Dec 2024 01:43:25 +0800
Subject: [soc:for-next] BUILD SUCCESS
 6c2bb9f225bc1cbe7275c0dbb21254f41dd0d1e0
Message-ID: <202412150119.arfwweBH-lkp@intel.com>

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

elapsed time: 1450m

configs tested: 56
configs skipped: 2

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

tested configs:
arc                  randconfig-001-20241214    gcc-13.2.0
arc                  randconfig-002-20241214    gcc-13.2.0
arm                  randconfig-001-20241214    gcc-14.2.0
arm                  randconfig-002-20241214    clang-15
arm                  randconfig-003-20241214    gcc-14.2.0
arm                  randconfig-004-20241214    gcc-14.2.0
arm64                randconfig-001-20241214    clang-15
arm64                randconfig-002-20241214    clang-20
arm64                randconfig-003-20241214    clang-15
arm64                randconfig-004-20241214    gcc-14.2.0
csky                 randconfig-001-20241214    gcc-14.2.0
csky                 randconfig-002-20241214    gcc-14.2.0
hexagon              randconfig-001-20241214    clang-20
hexagon              randconfig-002-20241214    clang-14
i386       buildonly-randconfig-001-20241214    gcc-12
i386       buildonly-randconfig-002-20241214    gcc-12
i386       buildonly-randconfig-003-20241214    clang-19
i386       buildonly-randconfig-004-20241214    clang-19
i386       buildonly-randconfig-005-20241214    gcc-11
i386       buildonly-randconfig-006-20241214    gcc-12
loongarch            randconfig-001-20241214    gcc-14.2.0
loongarch            randconfig-002-20241214    gcc-14.2.0
nios2                randconfig-001-20241214    gcc-14.2.0
nios2                randconfig-002-20241214    gcc-14.2.0
parisc               randconfig-001-20241214    gcc-14.2.0
parisc               randconfig-002-20241214    gcc-14.2.0
powerpc              randconfig-001-20241214    clang-20
powerpc              randconfig-002-20241214    clang-15
powerpc              randconfig-003-20241214    clang-20
powerpc64            randconfig-001-20241214    gcc-14.2.0
powerpc64            randconfig-003-20241214    clang-20
riscv                randconfig-001-20241214    clang-20
riscv                randconfig-002-20241214    clang-20
s390                            allmodconfig    clang-19
s390                            allyesconfig    gcc-14.2.0
s390                 randconfig-001-20241214    gcc-14.2.0
s390                 randconfig-002-20241214    gcc-14.2.0
sh                              allmodconfig    gcc-14.2.0
sh                              allyesconfig    gcc-14.2.0
sh                   randconfig-001-20241214    gcc-14.2.0
sh                   randconfig-002-20241214    gcc-14.2.0
sparc                           allmodconfig    gcc-14.2.0
sparc                randconfig-001-20241214    gcc-14.2.0
sparc                randconfig-002-20241214    gcc-14.2.0
sparc64              randconfig-001-20241214    gcc-14.2.0
sparc64              randconfig-002-20241214    gcc-14.2.0
um                   randconfig-001-20241214    clang-20
um                   randconfig-002-20241214    clang-17
x86_64     buildonly-randconfig-001-20241214    gcc-11
x86_64     buildonly-randconfig-002-20241214    clang-19
x86_64     buildonly-randconfig-003-20241214    gcc-12
x86_64     buildonly-randconfig-004-20241214    gcc-12
x86_64     buildonly-randconfig-005-20241214    gcc-12
x86_64     buildonly-randconfig-006-20241214    clang-19
xtensa               randconfig-001-20241214    gcc-14.2.0
xtensa               randconfig-002-20241214    gcc-14.2.0

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


From David.Laight at ACULAB.COM  Sat Dec 14 10:40:11 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sat, 14 Dec 2024 18:40:11 +0000
Subject: [PATCH 3/4] ARM: drop CONFIG_HIGHPTE support
In-Reply-To: <20241210160556.2341497-4-arnd@kernel.org>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-4-arnd@kernel.org>
Message-ID: <d54e11cf3f4d4216b5cecf29b761cd45@AcuMS.aculab.com>

From: Arnd Bergmann
> Sent: 10 December 2024 16:06
...
> Since Arm is the last architecture remaining that uses this, and almost
> no 32-bit machines support more than 4GB of RAM, the cost of continuing
> to maintain HIGHPTE seems unjustified, so remove it here to allow
> simplifying the generic page table handling.

'Picking at nits' 'highmem' support was needed for systems with 4GB of RAM
in order to use more than 3GB or 3.5GB (depending on the bios) because
of the physical addresses that are reserved for PCI (and other MMIO).

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From David.Laight at ACULAB.COM  Sat Dec 14 13:21:12 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Sat, 14 Dec 2024 21:21:12 +0000
Subject: [PATCH] watchdog: aspeed: replace mdelay with msleep
In-Reply-To: <3fe75eab-e700-4ae2-984b-42342ec7d784@roeck-us.net>
References: <20241212113014.1075414-1-phil@zankapfel.net>
 <3fe75eab-e700-4ae2-984b-42342ec7d784@roeck-us.net>
Message-ID: <d7ab80332def4a328cb9492fddcb8bef@AcuMS.aculab.com>

From: Guenter Roeck
> Sent: 12 December 2024 13:56
> To: Phil Eichinger <phil at zankapfel.net>; wim at linux-watchdog.org; joel at jms.id.au;
> andrew at codeconstruct.com.au; linux-watchdog at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-aspeed at lists.ozlabs.org; linux-kernel at vger.kernel.org
> Subject: Re: [PATCH] watchdog: aspeed: replace mdelay with msleep
> 
> On 12/12/24 03:30, Phil Eichinger wrote:
> > Since it is not called in an atomic context the mdelay function
> > can be replaced with msleep to avoid busy wait.
> >
> > Signed-off-by: Phil Eichinger <phil at zankapfel.net>
> > ---
> >   drivers/watchdog/aspeed_wdt.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
> > index b4773a6aaf8c..98ef341408f7 100644
> > --- a/drivers/watchdog/aspeed_wdt.c
> > +++ b/drivers/watchdog/aspeed_wdt.c
> > @@ -208,7 +208,7 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
> >   	wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY;
> >   	aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000);
> >
> > -	mdelay(1000);
> > +	msleep(1000);
> >
> >   	return 0;
> >   }
> This is a _restart_ handler. The only purpose of the delay is to wait
> for the reset to trigger. It is not supposed to sleep.

With the recent scheduler changes isn't the code likely to get
pre-empted?
Which (effectively) converts is to a sleep?

	David
 
> 
> NACK.
> 
> Guenter
> 
> 
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From linux at roeck-us.net  Sat Dec 14 13:46:36 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 14 Dec 2024 13:46:36 -0800
Subject: [PATCH] watchdog: aspeed: replace mdelay with msleep
In-Reply-To: <d7ab80332def4a328cb9492fddcb8bef@AcuMS.aculab.com>
References: <20241212113014.1075414-1-phil@zankapfel.net>
 <3fe75eab-e700-4ae2-984b-42342ec7d784@roeck-us.net>
 <d7ab80332def4a328cb9492fddcb8bef@AcuMS.aculab.com>
Message-ID: <927f2063-4587-423f-8c75-441f55e17671@roeck-us.net>

On 12/14/24 13:21, David Laight wrote:
> From: Guenter Roeck
>> Sent: 12 December 2024 13:56
>> To: Phil Eichinger <phil at zankapfel.net>; wim at linux-watchdog.org; joel at jms.id.au;
>> andrew at codeconstruct.com.au; linux-watchdog at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>> linux-aspeed at lists.ozlabs.org; linux-kernel at vger.kernel.org
>> Subject: Re: [PATCH] watchdog: aspeed: replace mdelay with msleep
>>
>> On 12/12/24 03:30, Phil Eichinger wrote:
>>> Since it is not called in an atomic context the mdelay function
>>> can be replaced with msleep to avoid busy wait.
>>>
>>> Signed-off-by: Phil Eichinger <phil at zankapfel.net>
>>> ---
>>>    drivers/watchdog/aspeed_wdt.c | 2 +-
>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
>>> index b4773a6aaf8c..98ef341408f7 100644
>>> --- a/drivers/watchdog/aspeed_wdt.c
>>> +++ b/drivers/watchdog/aspeed_wdt.c
>>> @@ -208,7 +208,7 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
>>>    	wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY;
>>>    	aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000);
>>>
>>> -	mdelay(1000);
>>> +	msleep(1000);
>>>
>>>    	return 0;
>>>    }
>> This is a _restart_ handler. The only purpose of the delay is to wait
>> for the reset to trigger. It is not supposed to sleep.
> 
> With the recent scheduler changes isn't the code likely to get
> pre-empted?
> Which (effectively) converts is to a sleep?
> 

This code is called from do_kernel_restart(), which in turn is called from
machine_restart(). I'd think that the kernel has a severe problem if it
decides to preempt that function.

Guenter



From bb at ti.com  Sat Dec 14 13:56:24 2024
From: bb at ti.com (Bryan Brattlof)
Date: Sat, 14 Dec 2024 15:56:24 -0600
Subject: [PATCH 1/2] arm64: dts: ti: k3-am62l: add initial infrastructure
In-Reply-To: <Z12rnZiCXQxtMWlf@livingston.pivistrello.it>
References: <20241117-am62lx-v1-0-4e71e42d781d@ti.com>
 <20241117-am62lx-v1-1-4e71e42d781d@ti.com>
 <Z12rnZiCXQxtMWlf@livingston.pivistrello.it>
Message-ID: <20241214215624.e372oju6eserpf4f@bryanbrattlof.com>

On December 14, 2024 thus sayeth Francesco Dolcini:
> On Sun, Nov 17, 2024 at 11:34:07PM -0600, Bryan Brattlof wrote:
> > From: Vignesh Raghavendra <vigneshr at ti.com>
> > 
> > Add the initial infrastructure needed for the AM62L. All of which can be
> > found in the Technical Reference Manual (TRM) located here:
> > 
> >     https://www.ti.com/lit/ug/sprujb4/sprujb4.pdf
> > 
> > Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
> > Signed-off-by: Bryan Brattlof <bb at ti.com>
> > ---
> >  Documentation/devicetree/bindings/arm/ti/k3.yaml |  6 ++
> >  arch/arm64/boot/dts/ti/Makefile                  |  3 +
> >  arch/arm64/boot/dts/ti/k3-am62l-main.dtsi        | 52 ++++++++++++++
> >  arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi      | 33 +++++++++
> >  arch/arm64/boot/dts/ti/k3-am62l.dtsi             | 89 ++++++++++++++++++++++++
> >  arch/arm64/boot/dts/ti/k3-am62l3.dtsi            | 67 ++++++++++++++++++
> >  arch/arm64/boot/dts/ti/k3-pinctrl.h              |  2 +
> >  7 files changed, 252 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
> > index 18f155cd06c84..b109e854879cb 100644
> > --- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
> > +++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
> > @@ -31,6 +31,12 @@ properties:
> >            - const: phytec,am62a-phycore-som
> >            - const: ti,am62a7
> >  
> > +      - description: K3 AM62L3 SoC and Boards
> > +        items:
> > +          - enum:
> > +              - ti,am62l3-evm
> > +          - const: ti,am62l3
> > +
> 
> can you clarify the differences between AM62L and AM62L3? you have a mix of names in this series. I assume that
> AM62L is the SOC family / product name, while AM62L3 is a specific 
> part number.
>

Absolutely! I found the naming a bit confusing myself. 

We (the baseport teams) have kinda coalesced into using less digits as a 
way to describe all devices included in the subgroup. So for example AM6 
would be all Sitara class MPUs in the K3 generation. AM62L would be all 
parts in K3 in the 'lite' derivative. AM62L32 would be all AM62L parts 
with display and dual cores.

But I should probably decode everything as these part numbers are really 
opaque in my eye if you don't see them every day. 

The full orderable part number for this part is the XAM62L32AOGHAANB

    'X' is the production status. If you see an 'X' here it just means 
    it's a pre-production sample that hasn't gone through validation. 
    Most of the time (outside of TI) this will be blank

    'AM' is the prefix which indicates a Sitara class of SoC. The AM68 
    and AM69 being originally a Jacinto class part kinda makes this more 
    confusing but back in the day i think it used to stand for ARM 
    Microprocessors so that's what I've been telling people.

    '62' is the generation and family of the part. So this example the 6 
    indicates the K3 generation of SoCs and the 2 means it's an MPU 
    family with 2k display or 2k camera support among other things.

    'L' is the derivative of the family. This is mostly a marketing 
    thing to indicate the target market for the SoC:

      AM62  (or blank) would be the general base class
      AM62A is for the analytics derivative
      AM62D is for DSP
      AM62P is for Plus
      AM62L is for Lite

    '3' is the configuration. This really depends on what the business 
    teams find feasible. Some of the family/derivative combinations
    don't make sense to have. For example an AM62L9 which would just be 
    the base AM62 derivative, so some configurations may not exist.

      0 = No Display / No ISP
      1 = No Display with ISP
      2 = No Display with ISP and Analytics
      3 = Display / No ISP
      4 = Display / No ISP with Analytics
      5 = Display / No ISP with GPU
      6 = Display with ISP
      7 = Display with ISP and Analytics
      8 = Display with ISP and GPU
      9 = includes everything

    '2' is the core count. AM62L32 would be the dual core option.

The rest of the digits get into stuff we try to do automatically via our 
bootloaders so you wont see any mention of them in Linux, but I kinda 
wanted to continue decoding this :)

    'A' is the silicon revision. A = SR 1.0 

    'O' is the speed grade. (there is a table somewhere with all the 
    speed grades we support. The two I know about are.

      O = 1.25GHz
      E = 833MHz

    'G' is the feature set. Because the derivative is 'L' (or lite) we 
    probably won't have options other than G which is the baseline

    'H' is the security & functional safety value

      'G' is non secure no functional safety. (like the beagleplay)
      '1-9' are dummy key devices with no functional safety
      'H-R' are production key HS devices with no function safety 
      'S-Z' are production key HS devices with function safety
        
'H-Z' is probably the most common security you will see TI make now. 
There are ways (by talking to sales) you can purchase other variants for 
special use cases (like aviation) but I think these are all special use 
cases with unique regulatory or security issues.

    'A' is the temperature rating
     
      'A' = -40C to 105C
      'I' = -40C to 125C

    'ANB' is the package: 11.9mm x 11.9mm with 0.5 BGA

There can be a total of 18 digits which can vary when decoding the 
family (AM65, AM64) but generally this decoding scheme will hold. I only 
really see those weird parts with our vertically integrated customers 
with their own sales teams.

Sorry for the essay. I went though our catalog one day and had the very 
same question you did so I wanted to dump as much as I could.

~Bryan


From pgwipeout at gmail.com  Sat Dec 14 13:58:02 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Sat, 14 Dec 2024 21:58:02 +0000
Subject: [PATCH v2] pmdomain: rockchip: fix rockchip_pd_power error handling
Message-ID: <20241214215802.23989-1-pgwipeout@gmail.com>

The calls rockchip_pd_power makes to rockchip_pmu_set_idle_request lack
any return error handling, causing device drivers to incorrectly believe
the hardware idle requests succeed when they may have failed. This leads
to software possibly accessing hardware that is powered off and the
subsequent SError panic that follows.

Add error checking and return errors to the calling function to prevent
such crashes.

gst-launch-1.0 videotestsrc num-buffers=2000 ! v4l2jpegenc ! fakesink
Setting pipeline to PAUSED ...er-x64
Pipeline is PREROLLING ...
Redistribute latency...
rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack on domain 'hevc', val=0x98260
SError Interrupt on CPU2, code 0x00000000bf000002 -- SError

Signed-off-by: Peter Geis <pgwipeout at gmail.com>

---
I have pulled this patch out to be standalone and rebased it on
Sebastian's pmdomain work. It is now dependent on their series [1].

[1] https://lore.kernel.org/linux-rockchip/20241211143044.9550-1-sebastian.reichel at collabora.com/T/#t

Changes in v2:
- Rebase on Sebastian's pmdomain work.
- Handle clock cleanup.
- Clean up commit message.
- Pull this patch from the series and submit alone.

 drivers/pmdomain/rockchip/pm-domains.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
index 31c71b6fddf1..9f6640063fda 100644
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -602,26 +602,29 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
 		rockchip_pmu_save_qos(pd);
 
 		/* if powering down, idle request to NIU first */
-		rockchip_pmu_set_idle_request(pd, true);
+		ret = rockchip_pmu_set_idle_request(pd, true);
+		if (ret < 0)
+			goto out;
 	}
 
 	ret = rockchip_do_pmu_set_power_domain(pd, power_on);
-	if (ret < 0) {
-		clk_bulk_disable(pd->num_clks, pd->clks);
-		return ret;
-	}
+	if (ret < 0)
+		goto out;
 
 	if (power_on) {
 		/* if powering up, leave idle mode */
-		rockchip_pmu_set_idle_request(pd, false);
+		ret = rockchip_pmu_set_idle_request(pd, false);
+		if (ret < 0)
+			goto out;
 
 		rockchip_pmu_restore_qos(pd);
 	}
 
+out:
 	rockchip_pmu_ungate_clk(pd, false);
 	clk_bulk_disable(pd->num_clks, pd->clks);
 
-	return 0;
+	return ret;
 }
 
 static int rockchip_pd_regulator_disable(struct rockchip_pm_domain *pd)
-- 
2.39.5



From ivo.ivanov.ivanov1 at gmail.com  Sat Dec 14 14:04:17 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Sun, 15 Dec 2024 00:04:17 +0200
Subject: [PATCH v1 0/2] i2c: exynos5: Add support for Exynos8895 SoC
Message-ID: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>

Hey folks,

This series adds HSI2C support for Exynos8895 to i2c-exynos5. HSI2C
buses here are mostly available implemented in USIv1 blocks, with 5
available externally - hsi2c_0 to 4. hsi2c_0 is available for PMIC
(although I've never seen it used) and it uses BUSC clocks, which are
still not implemented in the current clock driver, so I've decided to
leave it out for now.

In the next few patchsets support for USIv1 will be added to the
exynos-usi driver and with that the rest of the I2C buses will be made
available.

Kind regards,
Ivo

Ivaylo Ivanov (2):
  dt-bindings: i2c: exynos5: Add samsung,exynos8895-hsi2c compatible
  i2c: exynos5: Add support for Exynos8895 SoC

 .../devicetree/bindings/i2c/i2c-exynos5.yaml  | 26 ++++++++++++++--
 drivers/i2c/busses/i2c-exynos5.c              | 31 +++++++++++++++++--
 2 files changed, 52 insertions(+), 5 deletions(-)

-- 
2.43.0



From ivo.ivanov.ivanov1 at gmail.com  Sat Dec 14 14:04:19 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Sun, 15 Dec 2024 00:04:19 +0200
Subject: [PATCH v1 2/2] i2c: exynos5: Add support for Exynos8895 SoC
In-Reply-To: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <20241214220419.723100-3-ivo.ivanov.ivanov1@gmail.com>

Exynos8895 functioning logic mostly follows I2C_TYPE_EXYNOS7, but timing
and temp calculations are slightly changed according to the following
logic:

FPCLK / FI2C = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 2 *
((FLT_CYCLE + 3) - (FLT_CYCLE + 3) % (CLK_DIV + 1))

temp := (FPCLK / FI2C) - (FLT_CYCLE + 3) * 2

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
---
 drivers/i2c/busses/i2c-exynos5.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index e33001508..8d8ee42ba 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -168,6 +168,7 @@ enum i2c_type_exynos {
 	I2C_TYPE_EXYNOS5,
 	I2C_TYPE_EXYNOS7,
 	I2C_TYPE_EXYNOSAUTOV9,
+	I2C_TYPE_EXYNOS8895,
 };
 
 struct exynos5_i2c {
@@ -240,6 +241,11 @@ static const struct exynos_hsi2c_variant exynosautov9_hsi2c_data = {
 	.hw		= I2C_TYPE_EXYNOSAUTOV9,
 };
 
+static const struct exynos_hsi2c_variant exynos8895_hsi2c_data = {
+	.fifo_depth	= 64,
+	.hw		= I2C_TYPE_EXYNOS8895,
+};
+
 static const struct of_device_id exynos5_i2c_match[] = {
 	{
 		.compatible = "samsung,exynos5-hsi2c",
@@ -256,6 +262,9 @@ static const struct of_device_id exynos5_i2c_match[] = {
 	}, {
 		.compatible = "samsung,exynosautov9-hsi2c",
 		.data = &exynosautov9_hsi2c_data
+	}, {
+		.compatible = "samsung,exynos8895-hsi2c",
+		.data = &exynos8895_hsi2c_data
 	}, {},
 };
 MODULE_DEVICE_TABLE(of, exynos5_i2c_match);
@@ -331,6 +340,14 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
 	 * clk_cycle := TSCLK_L + TSCLK_H
 	 * temp := (CLK_DIV + 1) * (clk_cycle + 2)
 	 *
+	 * In case of HSI2C controllers in Exynos8895
+	 * FPCLK / FI2C =
+	 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) +
+	 * 2 * ((FLT_CYCLE + 3) - (FLT_CYCLE + 3) % (CLK_DIV + 1))
+	 *
+	 * clk_cycle := TSCLK_L + TSCLK_H
+	 * temp := (FPCLK / FI2C) - (FLT_CYCLE + 3) * 2
+	 *
 	 * Constraints: 4 <= temp, 0 <= CLK_DIV < 256, 2 <= clk_cycle <= 510
 	 *
 	 * To split SCL clock into low, high periods appropriately, one
@@ -352,11 +369,19 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
 	 *
 	 */
 	t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
-	temp = clkin / op_clk - 8 - t_ftl_cycle;
+	if (i2c->variant->hw == I2C_TYPE_EXYNOS8895)
+		temp = clkin / op_clk - (t_ftl_cycle + 3) * 2;
+	else
+		temp = clkin / op_clk - 8 - t_ftl_cycle;
 	if (i2c->variant->hw != I2C_TYPE_EXYNOS7)
 		temp -= t_ftl_cycle;
 	div = temp / 512;
-	clk_cycle = temp / (div + 1) - 2;
+
+	if (i2c->variant->hw == I2C_TYPE_EXYNOS8895)
+		clk_cycle = (temp + ((t_ftl_cycle + 3) % (div + 1)) * 2) /
+			    (div + 1) - 2;
+	else
+		clk_cycle = temp / (div + 1) - 2;
 	if (temp < 4 || div >= 256 || clk_cycle < 2) {
 		dev_err(i2c->dev, "%s clock set-up failed\n",
 			hs_timings ? "HS" : "FS");
@@ -491,6 +516,8 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
 	switch (i2c->variant->hw) {
 	case I2C_TYPE_EXYNOSAUTOV9:
 		fallthrough;
+	case I2C_TYPE_EXYNOS8895:
+		fallthrough;
 	case I2C_TYPE_EXYNOS7:
 		if (int_status & HSI2C_INT_TRANS_DONE) {
 			i2c->trans_done = 1;
-- 
2.43.0



From ivo.ivanov.ivanov1 at gmail.com  Sat Dec 14 14:04:18 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Sun, 15 Dec 2024 00:04:18 +0200
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add samsung,exynos8895-hsi2c compatible
In-Reply-To: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>

Add samsung,exynos8895-hsi2c dedicated compatible for representing
I2C of Exynos8895 SoC. Since there are I2C buses that aren't implemented
as a part of USIv1 blocks, they only require a single clock.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
---
 .../devicetree/bindings/i2c/i2c-exynos5.yaml  | 26 ++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
index cc8bba553..b029be88e 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
+++ b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
@@ -25,6 +25,7 @@ properties:
           - samsung,exynos5250-hsi2c    # Exynos5250 and Exynos5420
           - samsung,exynos5260-hsi2c    # Exynos5260
           - samsung,exynos7-hsi2c       # Exynos7
+          - samsung,exynos8895-hsi2c
           - samsung,exynosautov9-hsi2c
       - items:
           - enum:
@@ -94,9 +95,28 @@ allOf:
         - clock-names
 
     else:
-      properties:
-        clocks:
-          maxItems: 1
+      if:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - samsung,exynos8895-hsi2c
+
+      then:
+        properties:
+          clocks:
+            maxItems: 2
+
+          clock-names:
+            maxItems: 2
+
+        required:
+          - clock-names
+
+      else:
+        properties:
+          clocks:
+            maxItems: 1
 
 unevaluatedProperties: false
 
-- 
2.43.0



From ivo.ivanov.ivanov1 at gmail.com  Sat Dec 14 14:07:50 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Sun, 15 Dec 2024 00:07:50 +0200
Subject: [PATCH v1] arm64: dts: exynos8895: Add camera hsi2c nodes
Message-ID: <20241214220750.723354-1-ivo.ivanov.ivanov1@gmail.com>

Add nodes for hsi2c1-4 (CAM0-3), which allows using them.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
---
 arch/arm64/boot/dts/exynos/exynos8895.dtsi | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos8895.dtsi b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
index 90b318b2f..36657abfc 100644
--- a/arch/arm64/boot/dts/exynos/exynos8895.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
@@ -292,6 +292,50 @@ pinctrl_peric1: pinctrl at 10980000 {
 			interrupts = <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		hsi2c_1: i2c at 10990000 {
+			compatible = "samsung,exynos8895-hsi2c";
+			reg = <0x10990000 0x1000>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_HSI2C_CAM0_IPCLK>;
+			clock-names = "hsi2c";
+			interrupts = <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-0 = <&hsi2c1_bus>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
+		hsi2c_2: i2c at 109a0000 {
+			compatible = "samsung,exynos8895-hsi2c";
+			reg = <0x109a0000 0x1000>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_HSI2C_CAM1_IPCLK>;
+			clock-names = "hsi2c";
+			interrupts = <GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-0 = <&hsi2c2_bus>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
+		hsi2c_3: i2c at 109b0000 {
+			compatible = "samsung,exynos8895-hsi2c";
+			reg = <0x109b0000 0x1000>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_HSI2C_CAM2_IPCLK>;
+			clock-names = "hsi2c";
+			interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-0 = <&hsi2c3_bus>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
+		hsi2c_4: i2c at 109c0000 {
+			compatible = "samsung,exynos8895-hsi2c";
+			reg = <0x109c0000 0x1000>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_HSI2C_CAM3_IPCLK>;
+			clock-names = "hsi2c";
+			interrupts = <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-0 = <&hsi2c4_bus>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
 		spi_0: spi at 109d0000 {
 			compatible = "samsung,exynos8895-spi",
 				     "samsung,exynos850-spi";
-- 
2.43.0



From willy at infradead.org  Sat Dec 14 14:11:07 2024
From: willy at infradead.org (Matthew Wilcox)
Date: Sat, 14 Dec 2024 22:11:07 +0000
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <Z1v6XcaSK97Sa9Tz@shell.armlinux.org.uk>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-3-arnd@kernel.org>
 <CACRpkdZaoD2vqbCi1AFUa6mF2_=c3Nu4R0CvxFAep0VMgtMtOQ@mail.gmail.com>
 <20241211152257.Igx3aT2Y@linutronix.de>
 <CACRpkdbYU=Txm0zUWDWvNXA0JHRNGpy1ccy0zQdiBb2Ya+UBFA@mail.gmail.com>
 <Z1v6XcaSK97Sa9Tz@shell.armlinux.org.uk>
Message-ID: <Z14Ce7cziCn5Fluq@casper.infradead.org>

On Fri, Dec 13, 2024 at 09:11:57AM +0000, Russell King (Oracle) wrote:
> On Fri, Dec 13, 2024 at 01:27:00AM +0100, Linus Walleij wrote:
> > On Wed, Dec 11, 2024 at 4:22?PM Sebastian Andrzej Siewior
> > <bigeasy at linutronix.de> wrote:
> > > On 2024-12-11 14:29:29 [+0100], Linus Walleij wrote:
> > > > So fast GUP is supposed to be lockless, and should just not
> > > > have this problem. So it can't be addressing gup_fast_pgd_range()
> > > > right?
> > > ?
> > > > I'm more asking if HIGHPTE even acquires a spinlock anymore
> > > > as it is supposed to be "fast"/lockless. If it does, it is clearly violating
> > > > the "fast" promise of the fast GUP API and should not exist.
> > >
> > > This is lockless on x86. The problem is ARM's
> > > arch_kmap_local_high_get(). This is where the lock is from.
> > 
> > Aha that calls down to kmap_high_get() that that issues
> > lock_kmap_any(flags).
> > 
> > But is it really sound that the "fast" API does this? It feels
> > like a violation of the whole design of the fast stuff.
> 
> If there's no way to do it lockless, then it has to take the lock.

Well, no, it's allowed to fail.  It could trylock and fail if it can't
get the lock.


From konrad.dybcio at oss.qualcomm.com  Sat Dec 14 14:21:15 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Sat, 14 Dec 2024 23:21:15 +0100
Subject: [PATCH v7 4/5] Coresight: Add Coresight TMC Control Unit driver
In-Reply-To: <20241210031545.3468561-5-quic_jiegan@quicinc.com>
References: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
 <20241210031545.3468561-5-quic_jiegan@quicinc.com>
Message-ID: <d09097da-a07a-4dfa-9c0d-567b329b64ac@oss.qualcomm.com>

On 10.12.2024 4:15 AM, Jie Gan wrote:
> The Coresight TMC Control Unit hosts miscellaneous configuration registers
> which control various features related to TMC ETR sink.
> 
> Based on the trace ID, which is programmed in the related CTCU ATID
> register of a specific ETR, trace data with that trace ID gets into
> the ETR buffer, while other trace data gets dropped.
> 
> Enabling source device sets one bit of the ATID register based on
> source device's trace ID.
> Disabling source device resets the bit according to the source
> device's trace ID.
> 
> Signed-off-by: Jie Gan <quic_jiegan at quicinc.com>
> ---

[...]

> +static int __ctcu_set_etr_traceid(struct coresight_device *csdev,
> +				  u8 traceid,
> +				  int port_num,
> +				  bool enable)
> +{
> +	uint32_t atid_offset;
> +	struct ctcu_drvdata *drvdata;
> +	unsigned long flags;
> +	uint32_t reg_offset;
> +	int bit;
> +	uint32_t val;
> +
> +	if (!IS_VALID_CS_TRACE_ID(traceid) || port_num < 0)
> +		return -EINVAL;
> +
> +	drvdata = dev_get_drvdata(csdev->dev.parent);
> +	if (IS_ERR_OR_NULL(drvdata))
> +		return -EINVAL;
> +
> +	atid_offset = drvdata->atid_offset[port_num];
> +	if (atid_offset == 0)
> +		return -EINVAL;
> +
> +	spin_lock_irqsave(&drvdata->spin_lock, flags);

guard(raw_spinlock_irqsave)(&drvdata->spin_lock);

and drop the unlocks

> +	CS_UNLOCK(drvdata->base);
> +
> +	reg_offset = CTCU_ATID_REG_OFFSET(traceid, atid_offset);
> +	bit = CTCU_ATID_REG_BIT(traceid);
> +	if (reg_offset - atid_offset >= CTCU_ATID_REG_SIZE ||
> +	    bit >= CORESIGHT_TRACE_IDS_MAX) {
> +		CS_LOCK(drvdata);
> +		spin_unlock_irqrestore(&drvdata->spin_lock, flags);
> +		return -EINVAL;
> +	}
> +
> +	val = ctcu_readl(drvdata, reg_offset);
> +	if (enable)
> +		val = val | BIT(bit);
> +	else
> +		val = val & ~BIT(bit);
> +	ctcu_writel(drvdata, val, reg_offset);
> +
> +	CS_LOCK(drvdata->base);
> +	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
> +
> +	return 0;
> +}
> +
> +static int ctcu_get_active_port(struct coresight_device *sink, struct coresight_device *helper)
> +{
> +	int port, i;
> +
> +	for (i = 0; i < sink->pdata->nr_outconns; ++i) {
> +		if (sink->pdata->out_conns[i]->dest_dev) {
> +			port = sink->pdata->out_conns[i]->dest_port;
> +			return port;

Return sink->....

> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +/*
> + * ctcu_set_etr_traceid: Retrieve the ATID offset and trace ID.
> + *
> + * Returns 0 indicates success. None-zero result means failure.
> + */
> +static int ctcu_set_etr_traceid(struct coresight_device *csdev,
> +				struct cs_sink_data *sink_data,
> +				bool enable)
> +{
> +	int port_num;
> +
> +	if (!IS_VALID_CS_TRACE_ID(sink_data->traceid) ||
> +	    (csdev == NULL) ||

I'm not sure this can be null by the time it reaches this function

> +	    (sink_data->sink == NULL)) {
> +		dev_dbg(&csdev->dev, "Invalid parameters\n");

dev_err?

> +		return -EINVAL;
> +	}
> +
> +	port_num = ctcu_get_active_port(sink_data->sink, csdev);
> +	if (port_num < 0)
> +		return -EINVAL;
> +
> +	dev_dbg(&csdev->dev, "traceid is %d\n", sink_data->traceid);
> +
> +	return __ctcu_set_etr_traceid(csdev, sink_data->traceid, port_num, enable);
> +}
> +
> +static int ctcu_enable(struct coresight_device *csdev, enum cs_mode mode,
> +		       void *data)
> +{
> +	int ret = 0;

Unnecessary initialization (you instantly overwrite it), also below

> +	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
> +
> +	ret = ctcu_set_etr_traceid(csdev, sink_data, true);
> +	if (ret)
> +		dev_dbg(&csdev->dev, "enable data filter failed\n");

Since the this function returns an int, maybe return ctcu_set_etr_traceid()
and let the upper layer throw an error (also for some other functions in this
file)

> +
> +	return 0;
> +}
> +
> +static int ctcu_disable(struct coresight_device *csdev, void *data)
> +{> +	int ret = 0;
> +	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
> +
> +	ret = ctcu_set_etr_traceid(csdev, sink_data, false);
> +	if (ret)
> +		dev_dbg(&csdev->dev, "disable data filter failed\n");
> +
> +	return 0;
> +}

[...]

>  enum coresight_dev_subtype_helper {
>  	CORESIGHT_DEV_SUBTYPE_HELPER_CATU,
> -	CORESIGHT_DEV_SUBTYPE_HELPER_ECT_CTI
> +	CORESIGHT_DEV_SUBTYPE_HELPER_ECT_CTI,
> +	CORESIGHT_DEV_SUBTYPE_HELPER_CTCU

Please add a comma here too, so that future additions will be
less noisy


From pgwipeout at gmail.com  Sat Dec 14 14:43:39 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Sat, 14 Dec 2024 22:43:39 +0000
Subject: [PATCH] arm64: dts: rockchip: add hevc power domain clock to rk3328
Message-ID: <20241214224339.24674-1-pgwipeout@gmail.com>

There is a race condition at startup between disabling power domains not
used and disabling clocks not used on the rk3328. When the clocks are
disabled first, the hevc power domain fails to shut off leading to a
splat of failures. Add the hevc core clock to the rk3328 power domain
node to prevent this condition.

rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-.... }
1087 jiffies s: 89 root: 0x8/.
rcu: blocking rcu_node structures (internal RCU debug):
Sending NMI from CPU 0 to CPUs 3:
NMI backtrace for cpu 3
CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53
Hardware name: Firefly ROC-RK3328-CC (DT)
Workqueue: pm genpd_power_off_work_fn
pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : regmap_unlock_spinlock+0x18/0x30
lr : regmap_read+0x60/0x88
sp : ffff800081123c00
x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000
x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040
x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74
x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000
x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d
x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431
x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0
x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b
x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40
x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000
Call trace:
regmap_unlock_spinlock+0x18/0x30
rockchip_pmu_set_idle_request+0xac/0x2c0
rockchip_pd_power+0x144/0x5f8
rockchip_pd_power_off+0x1c/0x30
_genpd_power_off+0x9c/0x180
genpd_power_off.part.0.isra.0+0x130/0x2a8
genpd_power_off_work_fn+0x6c/0x98
process_one_work+0x170/0x3f0
worker_thread+0x290/0x4a8
kthread+0xec/0xf8
ret_from_fork+0x10/0x20
rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack on domain 'hevc', val=0x88220

Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for RK3328 SoCs")
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
Reviewed-by: Dragan Simic <dsimic at manjaro.org>

---
I am pulling this patch out and submitting it standalone. Otherwise
there are no changes from the first submission.

This was found via educated guessing and extensive testing. This clock
is sufficient to permit the power domain to function, but additional
clock work will be needed if the hevc block is ever enabled on rk3328.

For anyone wishing to attempt enabling the hevc or h265 blocks:
Currently the assigned clocks in downstream are not sufficent and the
board hard locks if accessed unless clk_ignore_unused is applied.
Notes from the rk3328 and rk3228h TRMs show the HEVC and H265 blocks
share common clocks and domains, along with a shared sram block that
also needs to be enabled.

 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0597de415fe0..7d992c3c01ce 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -333,6 +333,7 @@ power: power-controller {
 
 			power-domain at RK3328_PD_HEVC {
 				reg = <RK3328_PD_HEVC>;
+				clocks = <&cru SCLK_VENC_CORE>;
 				#power-domain-cells = <0>;
 			};
 			power-domain at RK3328_PD_VIDEO {
-- 
2.39.5



From lkp at intel.com  Sat Dec 14 14:46:45 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 15 Dec 2024 06:46:45 +0800
Subject: [PATCH v1 10/13] KVM: selftests: Add KVM Userfault mode to
 demand_paging_test
In-Reply-To: <20241204191349.1730936-11-jthoughton@google.com>
References: <20241204191349.1730936-11-jthoughton@google.com>
Message-ID: <202412150600.wLk8rmZf-lkp@intel.com>

Hi James,

kernel test robot noticed the following build errors:

[auto build test ERROR on 4d911c7abee56771b0219a9fbf0120d06bdc9c14]

url:    https://github.com/intel-lab-lkp/linux/commits/James-Houghton/KVM-Add-KVM_MEM_USERFAULT-memslot-flag-and-bitmap/20241205-032516
base:   4d911c7abee56771b0219a9fbf0120d06bdc9c14
patch link:    https://lore.kernel.org/r/20241204191349.1730936-11-jthoughton%40google.com
patch subject: [PATCH v1 10/13] KVM: selftests: Add KVM Userfault mode to demand_paging_test
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241215/202412150600.wLk8rmZf-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/202412150600.wLk8rmZf-lkp at intel.com/

All errors (new ones prefixed by >>):

>> demand_paging_test.c:220:2: error: address argument to atomic operation must be a pointer to _Atomic type ('unsigned long *' invalid)
     220 |         atomic_fetch_and_explicit(bitmap_chunk,
         |         ^                         ~~~~~~~~~~~~
   /opt/cross/clang-ab51eccf88/lib/clang/19/include/stdatomic.h:169:35: note: expanded from macro 'atomic_fetch_and_explicit'
     169 | #define atomic_fetch_and_explicit __c11_atomic_fetch_and
         |                                   ^
   1 error generated.

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


From heiko at sntech.de  Sat Dec 14 14:48:19 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 14 Dec 2024 23:48:19 +0100
Subject: [PATCH] clk: rockchip: rk3588: make refclko25m_ethX critical
Message-ID: <20241214224820.200665-1-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at cherry.de>

Ethernet phys normally need a 25MHz refclk input. On a lot of boards
this is done with a dedicated 25MHz crystal. But the rk3588 CRU also
provides a means for that via the refclko25m_ethX clock outputs that
can be used for that function.

The mdio bus normally probes devices on the bus at runtime, by reading
specific phy registers. This requires the phy to be running and thus
also being supplied by its reference clock.

While there exist the possibility and dt-binding to declare these
input clocks for each phy in the phy-dt-node, this is only relevant
_after_ the phy has been detected and during the drivers probe-run.

This results in a chicken-and-egg-problem. The refclks in the CRU are
running on boot of course, but phy-probing can very well happen after
clk_disable_unused has run.

In the past I tried to make clock-handling part of the mdio bus code [0]
but that wasn't very well received, due to it being specific to OF and
clocks with the consensus being that resources needed for detection
need to be enabled before.

So to make probing ethernet phys using the internal refclks possible,
make those 2 clocks critical.

[0] https://lore.kernel.org/netdev/13590315.F0gNSz5aLb at diego/T/

Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>
---
 drivers/clk/rockchip/clk-rk3588.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
index 0ffaf639f807..2f63985a6d07 100644
--- a/drivers/clk/rockchip/clk-rk3588.c
+++ b/drivers/clk/rockchip/clk-rk3588.c
@@ -792,10 +792,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
 	COMPOSITE(MCLK_GMAC0_OUT, "mclk_gmac0_out", gpll_cpll_p, 0,
 			RK3588_CLKSEL_CON(15), 7, 1, MFLAGS, 0, 7, DFLAGS,
 			RK3588_CLKGATE_CON(5), 3, GFLAGS),
-	COMPOSITE(REFCLKO25M_ETH0_OUT, "refclko25m_eth0_out", gpll_cpll_p, 0,
+	COMPOSITE(REFCLKO25M_ETH0_OUT, "refclko25m_eth0_out", gpll_cpll_p, CLK_IS_CRITICAL,
 			RK3588_CLKSEL_CON(15), 15, 1, MFLAGS, 8, 7, DFLAGS,
 			RK3588_CLKGATE_CON(5), 4, GFLAGS),
-	COMPOSITE(REFCLKO25M_ETH1_OUT, "refclko25m_eth1_out", gpll_cpll_p, 0,
+	COMPOSITE(REFCLKO25M_ETH1_OUT, "refclko25m_eth1_out", gpll_cpll_p, CLK_IS_CRITICAL,
 			RK3588_CLKSEL_CON(16), 7, 1, MFLAGS, 0, 7, DFLAGS,
 			RK3588_CLKGATE_CON(5), 5, GFLAGS),
 	COMPOSITE(CLK_CIFOUT_OUT, "clk_cifout_out", gpll_cpll_24m_spll_p, 0,
-- 
2.45.2



From heiko at sntech.de  Sat Dec 14 15:11:07 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 15 Dec 2024 00:11:07 +0100
Subject: (subset) [PATCH v6 00/16] VOP Support for rk3576
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <173421785408.212079.5671999900653465901.b4-ty@sntech.de>


On Sat, 14 Dec 2024 16:16:59 +0800, Andy Yan wrote:
> Thanks for the basic work from Collabora, I can bringup a HDMI
> display out on rk3576.
> 
> PATCH 1 is a carryover from the working when add support for
>     rk3588[0], is very usefull when some people want me
>     help debug some issue online, so I really hope it can
>     be merged at this round.
> PATCH 2~8 are bugfix of rk3588 alpha blending which report and
>     test by Derek
> PATCH 9~13 are preparations for rk3576 support
> PATCH 17~18 are real support for rk376
> 
> [...]

Applied, thanks!

[01/16] drm/rockchip: vop2: Add debugfs support
        commit: 779964556c64cd3d76ddfeb34738ef78020fae84
[02/16] drm/rockchip: vop2: Fix the windows switch between different layers
        commit: 0ca953ac226eaffbe1a795f5e517095a8d494921

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From naoki at radxa.com  Sat Dec 14 17:44:12 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 15 Dec 2024 10:44:12 +0900
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add USB-C support to ROCK 5B
In-Reply-To: <iloxbrj7ktqto5yphr7i3tioq3cbecqwu4ovxmezovux3nw7t3@j2siyintvy7j>
References: <20241210163615.120594-1-sebastian.reichel@collabora.com>
 <FFD6E87BED20DB1B+38b8064e-9945-4cd8-a30e-7800a8c6f37b@radxa.com>
 <3D830E407DCD15A2+de00ea1d-96d5-4766-9dc5-616fc76f404b@radxa.com>
 <iloxbrj7ktqto5yphr7i3tioq3cbecqwu4ovxmezovux3nw7t3@j2siyintvy7j>
Message-ID: <93E0AA29EA05399F+f0e8d224-c30d-4190-9649-413c00e8f2fa@radxa.com>

Hi Sebastian,

On 12/13/24 04:20, Sebastian Reichel wrote:
> Hi Naoki,
> 
> On Wed, Dec 11, 2024 at 09:40:13AM +0900, FUKAUMI Naoki wrote:
>> I got random reboot during booting kernel/userland...
> 
> That is probably related to USB-C PD communication resulting in
> another hard reset :( Can you try to get some tcpm_log() data
> from debugfs while the board is powered from the GPIO header or
> PoE?

Unfortunately I don't have such a tool...

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Greetings,
> 
> -- Sebastian




From ryazanov.s.a at gmail.com  Sat Dec 14 18:17:39 2024
From: ryazanov.s.a at gmail.com (Sergey Ryazanov)
Date: Sun, 15 Dec 2024 04:17:39 +0200
Subject: [net v2] net: wwan: t7xx: Fix FSM command timeout issue
In-Reply-To: <20241213064720.122615-1-jinjian.song@fibocom.com>
References: <20241213064720.122615-1-jinjian.song@fibocom.com>
Message-ID: <da90f64c-260a-4329-87bf-1f9ff20a5951@gmail.com>

Hello Jinjian,

Nice catch! Suddenly, the proposed fix is not complete, we still have 
issues with memory use after free. Please find details below.

On 13.12.2024 08:47, Jinjian Song wrote:
> When driver processes the internal state change command, it use an
> asynchronous thread to process the command operation. If the main
> thread detects that the task has timed out, the asynchronous thread
> will panic when executing the completion notification because the
> main thread completion object has been released.
> 
> BUG: unable to handle page fault for address: fffffffffffffff8
> PGD 1f283a067 P4D 1f283a067 PUD 1f283c067 PMD 0
> Oops: 0000 [#1] PREEMPT SMP NOPTI
> RIP: 0010:complete_all+0x3e/0xa0
> [...]
> Call Trace:
>   <TASK>
>   ? __die_body+0x68/0xb0
>   ? page_fault_oops+0x379/0x3e0
>   ? exc_page_fault+0x69/0xa0
>   ? asm_exc_page_fault+0x22/0x30
>   ? complete_all+0x3e/0xa0
>   fsm_main_thread+0xa3/0x9c0 [mtk_t7xx (HASH:1400 5)]
>   ? __pfx_autoremove_wake_function+0x10/0x10
>   kthread+0xd8/0x110
>   ? __pfx_fsm_main_thread+0x10/0x10 [mtk_t7xx (HASH:1400 5)]
>   ? __pfx_kthread+0x10/0x10
>   ret_from_fork+0x38/0x50
>   ? __pfx_kthread+0x10/0x10
>   ret_from_fork_asm+0x1b/0x30
>   </TASK>
> [...]
> CR2: fffffffffffffff8
> ---[ end trace 0000000000000000 ]---
> 
> After the main thread determines that the task has timed out, mark
> the completion invalid, and add judgment in the asynchronous task.
> 
> Fixes: d785ed945de6 ("net: wwan: t7xx: PCIe reset rescan")

The completion waiting was introduced in a different commit. I believe, 
the fix tag should be 13e920d93e37 ("net: wwan: t7xx: Add core components")

> Signed-off-by: Jinjian Song <jinjian.song at fibocom.com>
> ---
>   drivers/net/wwan/t7xx/t7xx_state_monitor.c | 7 +++++--
>   1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
> index 3931c7a13f5a..57f1a7730fff 100644
> --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
> +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
> @@ -108,7 +108,8 @@ static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command
>   {
>   	if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
>   		*cmd->ret = result;

The memory for the result storage is allocated on the stack as well. And 
writing it unconditionally can cause unexpected consequences.

> -		complete_all(cmd->done);
> +		if (cmd->done)
> +			complete_all(cmd->done);
>   	}
>   
>   	kfree(cmd);
> @@ -503,8 +504,10 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id
>   
>   		wait_ret = wait_for_completion_timeout(&done,
>   						       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
> -		if (!wait_ret)
> +		if (!wait_ret) {
> +			cmd->done = NULL;

We cannot access the command memory here, since fsm_finish_command() 
could release it already.

>   			return -ETIMEDOUT;
> +		}
>   
>   		return ret;
>   	}

Here we have an ownership transfer problem and a driver author has tried 
to solve it, but as noticed, we are still experiencing issues in case of 
timeout.

The command completion routine should not release the command memory 
unconditionally. Looks like the references counting approach should help 
us here. E.g.
1. grab a reference before we put a command into the queue
1.1. grab an extra reference if we are going to wait the completion
2. release the reference as soon as we are done with the command execution
3. in case of completion waiting release the reference as soon as we are 
done with waiting due to completion or timeout

Could you try the following patch? Please note, besides the reference 
counter introduction it also moves completion and result storage inside 
the command structure as advised by the completion documentation.


--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
@@ -109,8 +109,9 @@ struct t7xx_fsm_command {
  	struct list_head	entry;
  	enum t7xx_fsm_cmd_state	cmd_id;
  	unsigned int		flag;
-	struct completion	*done;
-	int			*ret;
+	struct completion	done;
+	int			result;
+	struct struct kref	refcnt;
  };

  struct t7xx_fsm_notifier {
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
@@ -97,14 +97,20 @@ void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl 
*ctl, enum md_state state)
  	fsm_state_notify(ctl->md, state);
  }

+static void fsm_release_command(struct kref *ref)
+{
+	struct t7xx_fsm_command *cmd = container_of(ref, typeof(*cmd), refcnt);
+	kfree(cmd);
+}
+
  static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct 
t7xx_fsm_command *cmd, int result)
  {
  	if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
-		*cmd->ret = result;
+		cmd->result = result;
  		complete_all(cmd->done);
  	}

-	kfree(cmd);
+	kref_put(&cmd->refcnt, fsm_release_command);
  }

  static void fsm_del_kf_event(struct t7xx_fsm_event *event)
@@ -396,7 +402,6 @@ static int fsm_main_thread(void *data)

  int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum 
t7xx_fsm_cmd_state cmd_id, unsigned int flag)
  {
-	DECLARE_COMPLETION_ONSTACK(done);
  	struct t7xx_fsm_command *cmd;
  	unsigned long flags;
  	int ret;
@@ -408,11 +413,13 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, 
enum t7xx_fsm_cmd_state cmd_id
  	INIT_LIST_HEAD(&cmd->entry);
  	cmd->cmd_id = cmd_id;
  	cmd->flag = flag;
+	kref_init(&cmd->refcnt);
  	if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
-		cmd->done = &done;
-		cmd->ret = &ret;
+		init_completion(&cmd->done);
+		kref_get(&cmd->refcnt);
  	}

+	kref_get(&cmd->refcnt);
  	spin_lock_irqsave(&ctl->command_lock, flags);
  	list_add_tail(&cmd->entry, &ctl->command_queue);
  	spin_unlock_irqrestore(&ctl->command_lock, flags);
@@ -422,10 +429,10 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, 
enum t7xx_fsm_cmd_state cmd_id
  	if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
  		unsigned long wait_ret;

-		wait_ret = wait_for_completion_timeout(&done,
+		wait_ret = wait_for_completion_timeout(&cmd->done,
  						       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
-		if (!wait_ret)
-			return -ETIMEDOUT;
+		ret = wait_ret ? cmd->result : -ETIMEDOUT;
+		kref_put(&cmd->refcnt, fsm_release_command);

  		return ret;
  	}

--
Sergey


From damon.ding at rock-chips.com  Sat Dec 14 18:32:38 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Sun, 15 Dec 2024 10:32:38 +0800
Subject: [PATCH v1 00/10] Add eDP support for RK3588
In-Reply-To: <5939852.zQ0Gbyo6oJ@diego>
References: <20241127075157.856029-1-damon.ding@rock-chips.com>
 <5939852.zQ0Gbyo6oJ@diego>
Message-ID: <e1f0610d-bb63-4b11-88a2-29432529b9f4@rock-chips.com>

Hi Heiko,

On 2024/12/6 22:35, Heiko St?bner wrote:
> Hi Daemon,
> 
> Am Mittwoch, 27. November 2024, 08:51:47 CET schrieb Damon Ding:
>> These patchs have been tested with a 1536x2048p60 eDP panel on
>> RK3588S EVB1 board, and HDMI 1080P/4K display also has been verified
>> on RK3588 EVB1 board.
>>
>> Patch 1~3 are the RK3588 eDP support of Rockchip analogix_dp driver.
>> Patch 4   is the eDP mode support of samsung hdptx phy driver.
>> Patch 5~6 are the Rk3588 eDP support of Aanalogix DP driver. Add phy
>>            interfaces is to configure the HDMI/eDP TX Combo PHY.
>> Patch 7~8 are the renaming of hdptxphy node. It is not only used by
>>            HDMI display but also for the eDP display.
>> Patch 9   is the addition of RK3588 eDP0 node.
>> Patch 10  is to enable the eDP0 display on RK3588S EVB1 board.
> 
> Could you maybe also bring over functionality for real bridge-handling?
> That way we'd have support for things like the dp-connector bridge.
> 
> In the 6.1 vendor-tree I've found commits
> 94e598190128 ("drm/rockchip: analogix_dp: Add support for external bridge")
> 437e0a901b14 ("drm/bridge: analogix_dp: Support split mode for bridge chain")
> 
> needing a bit of cleanup of course, but that would get rid of the driver
> not handling the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag too.
> 
> With a bit of streamlining, we could maybe even get rid of the panel-part
> completely, similar to how the dw-dsi controllers do it [0]
> 
> 

Indeed, the patches related to the bridge support have not been included 
in this series. My intention was to first implement the basic display 
functionality, and then gradually add other features, including the 
support for bridge-handling. Otherwise, this series of patches may be 
too large. :-)

What's more, RK3576 SoC also supports the eDP display, so the subsequent 
patch series will come soon.

> 
> [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c#n335
> devm_drm_of_get_bridge() combines drm_of_find_panel_or_bridge()
> with devm_drm_panel_bridge_add(), so indepent of it being either a
> panel or other bridge, the driver below only needs to handle bridges.
> 
>> Damon Ding (10):
>>    drm/rockchip: analogix_dp: Use formalized struct definition for grf
>>      field
>>    dt-bindings: display: rockchip: analogix-dp: Add support for RK3588
>>    drm/rockchip: analogix_dp: Add support for RK3588
>>    phy: phy-rockchip-samsung-hdptx: Add support for eDP mode
>>    drm/bridge: analogix_dp: add support for RK3588
>>    drm/bridge: analogix_dp: Add support for phy configuration.
>>    dt-bindings: display: rockchip: Fix label name of hdptxphy for RK3588
>>      HDMI TX Controller
>>    arm64: dts: rockchip: Fix label name of hdptxphy for RK3588
>>    arm64: dts: rockchip: Add eDP0 node for RK3588
>>    arch64: dts: rockchip: Enable eDP0 display on RK3588S EVB1 board
>>
>>   .../rockchip/rockchip,analogix-dp.yaml        |   1 +
>>   .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml  |   2 +-
>>   arch/arm64/boot/dts/rockchip/rk3588-base.dtsi |  33 +-
>>   .../dts/rockchip/rk3588-coolpi-cm5-evb.dts    |   2 +-
>>   .../rockchip/rk3588-coolpi-cm5-genbook.dts    |   2 +-
>>   .../boot/dts/rockchip/rk3588-evb1-v10.dts     |   2 +-
>>   .../rk3588-friendlyelec-cm3588-nas.dts        |   2 +-
>>   .../arm64/boot/dts/rockchip/rk3588-jaguar.dts |   2 +-
>>   .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi   |   2 +-
>>   .../dts/rockchip/rk3588-orangepi-5-plus.dts   |   2 +-
>>   .../boot/dts/rockchip/rk3588-rock-5b.dts      |   2 +-
>>   .../boot/dts/rockchip/rk3588-tiger-haikou.dts |   2 +-
>>   .../boot/dts/rockchip/rk3588s-coolpi-4b.dts   |   2 +-
>>   .../boot/dts/rockchip/rk3588s-evb1-v10.dts    |  84 ++
>>   .../dts/rockchip/rk3588s-indiedroid-nova.dts  |   2 +-
>>   .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi  |   2 +-
>>   .../boot/dts/rockchip/rk3588s-odroid-m2.dts   |   2 +-
>>   .../boot/dts/rockchip/rk3588s-orangepi-5.dtsi |   2 +-
>>   .../boot/dts/rockchip/rk3588s-rock-5a.dts     |   2 +-
>>   .../boot/dts/rockchip/rk3588s-rock-5c.dts     |   2 +-
>>   .../drm/bridge/analogix/analogix_dp_core.c    |   8 +-
>>   .../drm/bridge/analogix/analogix_dp_core.h    |   2 +
>>   .../gpu/drm/bridge/analogix/analogix_dp_reg.c |  90 ++
>>   .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 112 ++-
>>   .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 936 +++++++++++++++++-
>>   include/drm/bridge/analogix_dp.h              |   3 +-
>>   26 files changed, 1206 insertions(+), 97 deletions(-)
>>
>>
> 
> 
> 
> 
> 
> 
Best regards,
Damon




From shimrrashai at gmail.com  Sat Dec 14 19:24:54 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Sat, 14 Dec 2024 21:24:54 -0600
Subject: [PATCH v3 2/3] dt-bindings: pinctrl: add header for PCA9555 GPIO extender bindings on some Rockchip-based devices
In-Reply-To: <20241215032507.4739-1-shimrrashai@gmail.com>
References: <20241215032507.4739-1-shimrrashai@gmail.com>
Message-ID: <20241215032507.4739-3-shimrrashai@gmail.com>

It seemed a bit disputed whether this was actually necessary, but I am
including it nonetheless. It makes it slightly clearer how the pins on the
PCA9555 GPIO extender used on the board are actuated than would be evident
from the numbers alone, since according to the spec sheets for it by NXP:

https://www.nxp.com/docs/en/data-sheet/PCA9555.pdf

there are two banks of controllable pins, IO0 and IO1, which are labeled
equivalently to the labels provided below.

Also sorry @Heiko St?bner for adding your name on it; I had cut this off a
BSP source file that was longer. Since this file contains only this
isolated section, which was written by someone else, I put their authorship
on it instead. Unfortunately I do not know who "daijh" is, only that they
used that handle on GitLab to submit this code piece and I got the
indicated email address.

Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
---
 .../dt-bindings/pinctrl/rockchip-pca9555.h    | 31 +++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 include/dt-bindings/pinctrl/rockchip-pca9555.h

diff --git a/include/dt-bindings/pinctrl/rockchip-pca9555.h b/include/dt-bindings/pinctrl/rockchip-pca9555.h
new file mode 100644
index 000000000..21ca99488
--- /dev/null
+++ b/include/dt-bindings/pinctrl/rockchip-pca9555.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * Bindings for the PCA9555 GPIO extender used on some Rockchip devices, e.g.
+ * Firefly.
+ *
+ * Copyright (C) 2022 Zhongshan Tianqi Intelligent Technology Co., Ltd.
+ * Authors: daijh <djh at t-chip.com.cn>
+ *          Shimrra Shai <shimrrashai at gmail.com>
+ */
+
+#ifndef __ROCKCHIP_PCA9555_H__
+#define __ROCKCHIP_PCA9555_H__
+
+#define PCA_IO0_0          0
+#define PCA_IO0_1          1
+#define PCA_IO0_2          2
+#define PCA_IO0_3          3
+#define PCA_IO0_4          4
+#define PCA_IO0_5          5
+#define PCA_IO0_6          6
+#define PCA_IO0_7          7
+#define PCA_IO1_0          8
+#define PCA_IO1_1          9
+#define PCA_IO1_2          10
+#define PCA_IO1_3          11
+#define PCA_IO1_4          12
+#define PCA_IO1_5          13
+#define PCA_IO1_6          14
+#define PCA_IO1_7          15
+
+#endif
-- 
2.45.2



From shimrrashai at gmail.com  Sat Dec 14 19:24:52 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Sat, 14 Dec 2024 21:24:52 -0600
Subject: [PATCH v3 0/3] arm64: dts: rockchip: Add Firefly ITX-3588J Board
Message-ID: <20241215032507.4739-1-shimrrashai@gmail.com>

This is the 3rd draft of the device tree proposal for the Firefly ITX-3588J
board. The same functionality issues as before are still outstanding;
however I have cleaned up the style and structure as per the comments by
Heiko St?bner on version 2. Of particular note is the splitting of the
device tree source into two files because this platform actually consists
of two boards: the ITX-3588J baseboard and a single Core-3588J compute
module stuck in a slot on it.

 - Shimrra Shai.

Shimrra Shai (3):
  arm64: dts: rockchip: add DTs for Firefly ITX-3588J and its Core-3588J
    SoM
  dt-bindings: pinctrl: add header for PCA9555 GPIO extender bindings on
    some Rockchip-based devices
  dt-bindings: arm: rockchip: Add Firefly ITX-3588J board

 .../devicetree/bindings/arm/rockchip.yaml     |   7 +
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../rockchip/rk3588-firefly-core-3588j.dtsi   | 453 +++++++++++
 .../dts/rockchip/rk3588-firefly-itx-3588j.dts | 712 ++++++++++++++++++
 .../dt-bindings/pinctrl/rockchip-pca9555.h    |  31 +
 5 files changed, 1204 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
 create mode 100644 include/dt-bindings/pinctrl/rockchip-pca9555.h

-- 
2.45.2



From shimrrashai at gmail.com  Sat Dec 14 19:24:53 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Sat, 14 Dec 2024 21:24:53 -0600
Subject: [PATCH v3 1/3] arm64: dts: rockchip: add DTs for Firefly ITX-3588J and its Core-3588J SoM
In-Reply-To: <20241215032507.4739-1-shimrrashai@gmail.com>
References: <20241215032507.4739-1-shimrrashai@gmail.com>
Message-ID: <20241215032507.4739-2-shimrrashai@gmail.com>

Main DTS for the boards and Makefile addition.

Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../rockchip/rk3588-firefly-core-3588j.dtsi   | 453 +++++++++++
 .../dts/rockchip/rk3588-firefly-itx-3588j.dts | 712 ++++++++++++++++++
 3 files changed, 1166 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 86cc418a2..3f2eebd1f 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -137,6 +137,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-wifi.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-firefly-itx-3588j.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-friendlyelec-cm3588-nas.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
new file mode 100644
index 000000000..e911a6472
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
@@ -0,0 +1,453 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+#include "rk3588.dtsi"
+
+/ {
+	compatible = "firefly,core-3588j", "rockchip,rk3588";
+
+	aliases {
+		mmc0 = &sdhci;
+	};
+};
+
+&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-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-name = "vdd_cpu_big0_s0";
+		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;
+		};
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1m2_xfer>;
+	status = "okay";
+
+	vdd_npu_s0: vdd_npu_mem_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <950000>;
+		regulator-name = "vdd_npu_s0";
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&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", "pmic-power-off";
+		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+		pinctrl-1 = <&rk806_dvs1_pwrdn>;
+
+		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_dvs1_pwrdn: rk806_dvs1_pwrdn {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun2";
+		};
+
+		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-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;
+				};
+			};
+
+			avcc_3v3_s0: pldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "avcc_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>;
+				};
+			};
+
+			avdd_ddr_pll_s0: nldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "avdd_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;
+				};
+			};
+
+			avdd_0v85_s0: nldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "avdd_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;
+				};
+			};
+		};
+	};
+};
+
+/* rk3588 preferred debug out */
+&uart2 {
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts b/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
new file mode 100644
index 000000000..a523d3862
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
@@ -0,0 +1,712 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/pinctrl/rockchip-pca9555.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "dt-bindings/usb/pd.h"
+
+#include "rk3588-firefly-core-3588j.dtsi"
+
+/ {
+	model = "Firefly ITX-3588J";
+	compatible = "firefly,itx-3588j", "firefly,core-3588j", "rockchip,rk3588";
+
+	aliases {
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
+		mmc0 = &sdhci;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	/*
+	 * there are also a "Reset" and "Mask ROM" button, but the needed
+	 * settings are unknown at this time
+	 */
+	adc-keys-0 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-recovery {
+			label = "Recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <2000>;
+		};
+	};
+
+	analog-sound {
+		compatible = "simple-audio-card";
+		pinctrl-0 = <&hp_detect>;
+		pinctrl-names = "default";
+		simple-audio-card,aux-devs = <&amp_headphones>, <&amp_speaker>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,hp-det-gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>;
+		simple-audio-card,mclk-fs = <384>;
+		simple-audio-card,name = "rockchip_es8323";
+		simple-audio-card,pin-switches = "Headphones", "Speaker";
+		simple-audio-card,routing =
+			"Speaker Amplifier INL", "LOUT2",
+			"Speaker Amplifier INR", "ROUT2",
+			"Speaker", "Speaker Amplifier OUTL",
+			"Speaker", "Speaker Amplifier OUTR",
+			"Headphones Amplifier INL", "LOUT1",
+			"Headphones Amplifier INR", "ROUT1",
+			"Headphones", "Headphones Amplifier OUTL",
+			"Headphones", "Headphones Amplifier OUTR",
+			"LINPUT1", "Microphone Jack",
+			"RINPUT1", "Microphone Jack",
+			"LINPUT2", "Onboard Microphone",
+			"RINPUT2", "Onboard Microphone";
+		simple-audio-card,widgets =
+			"Microphone", "Microphone Jack",
+			"Microphone", "Onboard Microphone",
+			"Headphone", "Headphones",
+			"Speaker", "Speaker";
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s0_8ch>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&es8323>;
+			system-clock-frequency = <12288000>;
+		};
+	};
+
+	/*
+	 * this does not seem to be a proper "amplifier" but is just
+	 * a way to control the GPIO pins to switch on or off the given
+	 * sound output device
+	 */
+	amp_headphones: headphones-audio-amplifier {
+		compatible = "simple-audio-amplifier";
+		enable-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&headphone_amplifier_en>;
+		sound-name-prefix = "Headphones Amplifier";
+	};
+
+	amp_speaker: speaker-audio-amplifier {
+		compatible = "simple-audio-amplifier";
+		enable-gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&speaker_amplifier_en>;
+		sound-name-prefix = "Speaker Amplifier";
+	};
+
+	fan: pwm-fan {
+		compatible = "pwm-fan";
+		#cooling-cells = <2>;
+		cooling-levels = <0 120 150 180 210 240 255>;
+		fan-supply = <&vcc12v_dcin>;
+		pwms = <&pwm15 0 50000 1>;
+	};
+
+	hdmi0-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi0_con_in: endpoint {
+				remote-endpoint = <&hdmi0_out_con>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		/*
+		 * There is also a Power LED control @ RK_PB3 on
+		 * GPIO1 but for some reason it doesn't seem to work right
+		 */
+
+		user_led: led-1 {
+			gpios = <&pca9555 PCA_IO0_3 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "disk-activity";
+		};
+	};
+
+	pcie30_avdd0v75: pcie30-avdd0v75 {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <750000>;
+		regulator-max-microvolt = <750000>;
+		regulator-name = "pcie30_avdd0v75";
+		vin-supply = <&avdd_0v75_s0>;
+	};
+
+	vbus5v0_typec_pwr_en: regulator-vbus5v0-typec-pwr-en {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 PCA_IO1_4 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-name = "vbus5v0_typec_pwr_en";
+	};
+
+	vcc12v_dcin: regulator-vcc12v-dcin {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-name = "vcc12v_dcin";
+	};
+
+	vcc3v3_pcie30: regulator-vcc3v3-pcie30 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pcie3_vcc3v3_en>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-name = "vcc3v3_pcie30";
+		startup-delay-us = <5000>;
+		vin-supply = <&vcc12v_dcin>;
+		status = "okay";
+	};
+
+	vcc5v0_host: regulator-vcc5v0-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 PCA_IO0_5 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-name = "vcc5v0_host";
+		vin-supply = <&vcc5v0_usb>;
+		status = "okay";
+	};
+
+	vcc5v0_host3: regulator-vcc5v0-host3 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 PCA_IO0_7 GPIO_ACTIVE_HIGH>;
+		regulator-name = "vcc5v0_host3";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_sys: regulator-vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-name = "vcc5v0_sys";
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usb: regulator-vcc5v0-usb {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-name = "vcc5v0_usb";
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		regulator-name = "vcc_1v1_nldo_s3";
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc_fan_pwr_en: regulator-vcc-fan-pwr-en {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 PCA_IO1_3 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-name = "vcc_fan_pwr_en";
+	};
+
+	vcc_hub_reset: regulator-vcc-hub-reset {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 PCA_IO0_4 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-name = "vcc_hub_reset";
+	};
+
+	vcc_hub3_reset: regulator-vcc-hub3-reset {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 PCA_IO0_6 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-name = "vcc_hub3_reset";
+	};
+
+	vcc_sata_pwr_en: regulator-vcc-sata-pwr-en {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 PCA_IO1_2 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-name = "vcc_sata_pwr_en";
+	};
+};
+
+&avcc_1v8_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+	};
+};
+
+&combphy0_ps {
+	status = "okay";
+};
+
+&combphy1_ps {
+	status = "okay";
+};
+
+&combphy2_psu {
+	status = "okay";
+};
+
+&display_subsystem {
+	clocks = <&hdptxphy_hdmi0>;
+	clock-names = "hdmi0_phy_pll";
+};
+
+&gmac0 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy0>;
+	phy-mode = "rgmii-rxid";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+	tx_delay = <0x45>;
+	rx_delay = <0x4a>;
+	status = "okay";
+};
+
+&gmac1 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii-rxid";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac1_miim
+		     &gmac1_tx_bus2
+		     &gmac1_rx_bus2
+		     &gmac1_rgmii_clk
+		     &gmac1_rgmii_bus>;
+	tx_delay = <0x42>;
+	rx_delay = <0x4f>;
+	status = "okay";
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu_s0>;
+	sram-supply = <&vdd_gpu_mem_s0>;
+	status = "okay";
+};
+
+&hdmi0 {
+	status = "okay";
+};
+
+&hdmi0_in {
+	hdmi0_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi0>;
+	};
+};
+
+&hdmi0_out {
+	hdmi0_out_con: endpoint {
+		remote-endpoint = <&hdmi0_con_in>;
+	};
+};
+
+&hdptxphy_hdmi0 {
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+
+	/*
+	 * in the Firefly BSP source this was confusingly called an
+	 * "ES8388" - it actually seems to be an ES8323 and the drivers
+	 * for that work best
+	 */
+	es8323: audio-codec at 11 {
+		compatible = "everest,es8323";
+		reg = <0x11>;
+		assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+		assigned-clock-rates = <12288000>;
+		clocks = <&cru I2S0_8CH_MCLKOUT>;
+		clock-names = "mclk";
+		#sound-dai-cells = <0>;
+	};
+};
+
+&i2c6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c6m0_xfer>;
+	status = "okay";
+
+	pca9555: gpio at 21 {
+		compatible = "nxp,pca9555";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	usbc0: usb-typec at 22 {
+		compatible = "fcs,fusb302";
+		reg = <0x22>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbc0_int>;
+		vbus-supply = <&vbus5v0_typec_pwr_en>;
+
+		usb_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			op-sink-microwatt = <1000000>;
+			power-role = "dual";
+			sink-pdos =
+				<PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
+			source-pdos =
+				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			try-power-role = "source";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_orien_sw: endpoint {
+						remote-endpoint = <&usbdp_phy0_orientation_switch>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_role_sw: endpoint {
+						remote-endpoint = <&dwc3_0_role_switch>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+
+					dp_altmode_mux: endpoint {
+						remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+					};
+				};
+			};
+		};
+	};
+
+	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_PB0 IRQ_TYPE_LEVEL_LOW>;
+		wakeup-source;
+	};
+};
+
+&i2s0_8ch {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s0_lrck
+		     &i2s0_mclk
+		     &i2s0_sclk
+		     &i2s0_sdi0
+		     &i2s0_sdo0>;
+	status = "okay";
+};
+
+&mdio0 {
+	rgmii_phy0: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+	};
+};
+
+&pcie2x1l0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2_0_rst>;
+	reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>;
+	rockchip,skip-scan-in-resume;
+	status = "okay";
+};
+
+&pcie30phy {
+	status = "okay";
+};
+
+&pcie3x4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie3_rst>;
+	reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_pcie30>;
+	status = "okay";
+};
+
+&pinctrl {
+	dp {
+		dp1_hpd: dp1-hpd {
+			 rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	hym8563 {
+		hym8563_int: hym8563-int {
+			rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	gpio-leds {
+		sys_led_pin: sys-led-pin {
+			rockchip,pins =
+				<1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pcie2 {
+		pcie2_0_rst: pcie2-0-rst {
+			rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pcie3 {
+		pcie3_rst: pcie3-rst {
+			rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		pcie3_vcc3v3_en: pcie3-vcc3v3-en {
+			rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sound {
+		hp_detect: hp-detect {
+			rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		headphone_amplifier_en: headphone-amplifier-en {
+			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		speaker_amplifier_en: speaker-amplifier-en {
+			rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		usbc0_int: usbc0-int {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&pwm15 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm15m2_pins>;
+	status = "okay";
+};
+
+&sata0 {
+	status = "okay";
+};
+
+&sata1 {
+	status = "okay";
+};
+
+&sata2 {
+	status = "okay";
+};
+
+/* uart/232/485 */
+&uart0 {
+	pinctrl-0 = <&uart0m2_xfer>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-0 = <&uart1m1_xfer>;
+	status = "okay";
+};
+
+/* usb enable */
+&u2phy0 {
+	status = "okay";
+};
+
+&u2phy0_otg {
+	status = "okay";
+};
+
+&u2phy1 {
+	status = "okay";
+};
+
+&u2phy1_otg {
+	phy-supply = <&vcc5v0_host>;
+	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_host0_xhci {
+	usb-role-switch;
+	dr_mode = "otg";
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dwc3_0_role_switch: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&usbc0_role_sw>;
+		};
+	};
+};
+
+&usb_host1_xhci {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usb_host2_xhci {
+	status = "okay";
+};
+
+&usbdp_phy0 {
+	orientation-switch;
+	sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
+	sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usbdp_phy0_orientation_switch: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&usbc0_orien_sw>;
+		};
+
+		usbdp_phy0_dp_altmode_mux: endpoint at 1 {
+			reg = <1>;
+			remote-endpoint = <&dp_altmode_mux>;
+		};
+	};
+};
+
+&usbdp_phy1 {
+	rockchip,dp-lane-mux = <2 3>;
+	status = "okay";
+};
+
+&vcc_1v8_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+		regulator-suspend-microvolt = <1800000>;
+	};
+};
+
+/* for fan when deep sleep */
+&vdd_log_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+		regulator-suspend-microvolt = <750000>;
+	};
+};
+
+/* display generator */
+&vop_mmu {
+	status = "okay";
+};
+
+&vop {
+	status = "okay";
+};
+
+&vp0 {
+	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi0_in_vp0>;
+	};
+};
-- 
2.45.2



From shimrrashai at gmail.com  Sat Dec 14 19:24:55 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Sat, 14 Dec 2024 21:24:55 -0600
Subject: [PATCH v3 3/3] dt-bindings: arm: rockchip: Add Firefly ITX-3588J board
In-Reply-To: <20241215032507.4739-1-shimrrashai@gmail.com>
References: <20241215032507.4739-1-shimrrashai@gmail.com>
Message-ID: <20241215032507.4739-4-shimrrashai@gmail.com>

Updated DT binding documentation per @Heiko St?bner's suggestion, to
reflect the bipartite nature of the board.

Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 753199a12..fc7ee86e2 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -167,6 +167,13 @@ properties:
           - const: engicam,px30-core
           - const: rockchip,px30
 
+      - description: Firefly Core-3588J-based boards
+        items:
+          - enum:
+              - firefly,itx-3588j
+          - const: firefly,core-3588j
+          - const: rockchip,rk3588
+
       - description: Firefly Core-PX30-JD4 on MB-JD4-PX30 baseboard
         items:
           - const: firefly,px30-jd4-core-mb
-- 
2.45.2



From anarsoul at gmail.com  Sat Dec 14 21:34:58 2024
From: anarsoul at gmail.com (Vasily Khoruzhick)
Date: Sat, 14 Dec 2024 21:34:58 -0800
Subject: [PATCH 2/3] arm64: dts: allwinner: a64: explicitly assign clock parent for TCON0
In-Reply-To: <20241215053639.738890-1-anarsoul@gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
Message-ID: <20241215053639.738890-3-anarsoul@gmail.com>

TCON0 seems to need a different clock parent depending on output type.
For RGB it has to be PLL-VIDEO0-2X, while for DSI it has to be PLL-MIPI

Video output doesn't work if incorrect clock is assigned.

On my Pinebook I manually configured PLL-VIDEO0-2X and PLL-MIPI to the same
rate, and while video output works fine with PLL-VIDEO0-2X, it doesn't
work at all (as in no picture) with PLL-MIPI.

Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts | 2 ++
 arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts  | 2 ++
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi         | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
index 379c2c8466f5..86d44349e095 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
@@ -390,6 +390,8 @@ &sound {
 &tcon0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&lcd_rgb666_pins>;
+	assigned-clocks = <&ccu CLK_TCON0>;
+	assigned-clock-parents = <&ccu CLK_PLL_VIDEO0_2X>;
 
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
index b407e1dd08a7..ec055510af8b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
@@ -369,6 +369,8 @@ &sound {
 &tcon0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&lcd_rgb666_pins>;
+	assigned-clocks = <&ccu CLK_TCON0>;
+	assigned-clock-parents = <&ccu CLK_PLL_VIDEO0_2X>;
 
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index a5c3920e0f04..0fecf0abb204 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -445,6 +445,8 @@ tcon0: lcd-controller at 1c0c000 {
 			clock-names = "ahb", "tcon-ch0";
 			clock-output-names = "tcon-data-clock";
 			#clock-cells = <0>;
+			assigned-clocks = <&ccu CLK_TCON0>;
+			assigned-clock-parents = <&ccu CLK_PLL_MIPI>;
 			resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>;
 			reset-names = "lcd", "lvds";
 
-- 
2.47.1



From anarsoul at gmail.com  Sat Dec 14 21:34:56 2024
From: anarsoul at gmail.com (Vasily Khoruzhick)
Date: Sat, 14 Dec 2024 21:34:56 -0800
Subject: [PATCH 0/3] arm64: allwinner: a64: fix video output on Pinebook
Message-ID: <20241215053639.738890-1-anarsoul@gmail.com>

Since commit ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux"),
TCON0 clock parent is always set to PLL_MIPI, but unfortunately it breaks
video output on Pinebook.

I did an experiment: I manually configured PLL_MIPI and PLL_VIDEO0_2X
to the same clock rate and flipped the switch with devmem. Experiment clearly
showed that whenever PLL_MIPI is selected as TCON0 clock parent, the video
output stops working.

To fix the issue, I partially reverted mentioned commit and added explicit
TCON0 clock parent assignment to device tree. By default, it will be
PLL_MIPI, and the only users with RGB output - Pinebook and Teres-I will
override it in their dts.

Vasily Khoruzhick (3):
  dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
  arm64: dts: allwinner: a64: explicitly assign clock parent for TCON0
  clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent

 arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts |  2 ++
 arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts  |  2 ++
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi         |  2 ++
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c                 | 11 -----------
 drivers/clk/sunxi-ng/ccu-sun50i-a64.h                 |  2 --
 include/dt-bindings/clock/sun50i-a64-ccu.h            |  2 ++
 6 files changed, 8 insertions(+), 13 deletions(-)

-- 
2.47.1



From anarsoul at gmail.com  Sat Dec 14 21:34:57 2024
From: anarsoul at gmail.com (Vasily Khoruzhick)
Date: Sat, 14 Dec 2024 21:34:57 -0800
Subject: [PATCH 1/3] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
In-Reply-To: <20241215053639.738890-1-anarsoul@gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
Message-ID: <20241215053639.738890-2-anarsoul@gmail.com>

These will be used to explicitly select TCON0 clock parent in dts

Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.h      | 2 --
 include/dt-bindings/clock/sun50i-a64-ccu.h | 2 ++
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
index a8c11c0b4e06..dfba88a5ad0f 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
@@ -21,7 +21,6 @@
 
 /* PLL_VIDEO0 exported for HDMI PHY */
 
-#define CLK_PLL_VIDEO0_2X		8
 #define CLK_PLL_VE			9
 #define CLK_PLL_DDR0			10
 
@@ -32,7 +31,6 @@
 #define CLK_PLL_PERIPH1_2X		14
 #define CLK_PLL_VIDEO1			15
 #define CLK_PLL_GPU			16
-#define CLK_PLL_MIPI			17
 #define CLK_PLL_HSIC			18
 #define CLK_PLL_DE			19
 #define CLK_PLL_DDR1			20
diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h
index 175892189e9d..4f220ea7a23c 100644
--- a/include/dt-bindings/clock/sun50i-a64-ccu.h
+++ b/include/dt-bindings/clock/sun50i-a64-ccu.h
@@ -44,7 +44,9 @@
 #define _DT_BINDINGS_CLK_SUN50I_A64_H_
 
 #define CLK_PLL_VIDEO0		7
+#define CLK_PLL_VIDEO0_2X	8
 #define CLK_PLL_PERIPH0		11
+#define CLK_PLL_MIPI		17
 
 #define CLK_CPUX		21
 #define CLK_BUS_MIPI_DSI	28
-- 
2.47.1



From anarsoul at gmail.com  Sat Dec 14 21:34:59 2024
From: anarsoul at gmail.com (Vasily Khoruzhick)
Date: Sat, 14 Dec 2024 21:34:59 -0800
Subject: [PATCH 3/3] clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent
In-Reply-To: <20241215053639.738890-1-anarsoul@gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
Message-ID: <20241215053639.738890-4-anarsoul@gmail.com>

Force selecting PLL-MIPI as TCON0 parent breaks video output on Pinebook
that uses RGB to eDP bridge.

TCON0 clock parent will be selected in the device tree instead.

Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 3a7d61c81667..cc8de0bfbc67 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -534,12 +534,6 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
 				 0x104, 0, 4, 24, 3, BIT(31),
 				 CLK_SET_RATE_PARENT);
 
-/*
- * DSI output seems to work only when PLL_MIPI selected. Set it and prevent
- * the mux from reparenting.
- */
-#define SUN50I_A64_TCON0_CLK_REG	0x118
-
 static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
 static const u8 tcon0_table[] = { 0, 2, };
 static SUNXI_CCU_MUX_TABLE_WITH_GATE_CLOSEST(tcon0_clk, "tcon0", tcon0_parents,
@@ -959,11 +953,6 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
 
 	writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
 
-	/* Set PLL MIPI as parent for TCON0 */
-	val = readl(reg + SUN50I_A64_TCON0_CLK_REG);
-	val &= ~GENMASK(26, 24);
-	writel(val | (0 << 24), reg + SUN50I_A64_TCON0_CLK_REG);
-
 	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc);
 	if (ret)
 		return ret;
-- 
2.47.1



From dsimic at manjaro.org  Sat Dec 14 23:55:27 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Sun, 15 Dec 2024 08:55:27 +0100
Subject: [PATCH 1/3] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and
 PLL_MIPI
In-Reply-To: <20241215053639.738890-2-anarsoul@gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
 <20241215053639.738890-2-anarsoul@gmail.com>
Message-ID: <1f400eec0f0583335ad8b40fcbf1b5d4@manjaro.org>

Hello Vasily,

On 2024-12-15 06:34, Vasily Khoruzhick wrote:
> These will be used to explicitly select TCON0 clock parent in dts
> 
> Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in 
> TCON0 mux")
> Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>

Looking good to me, as a preparatory patch.  Please feel free
to include

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

> ---
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.h      | 2 --
>  include/dt-bindings/clock/sun50i-a64-ccu.h | 2 ++
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
> b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
> index a8c11c0b4e06..dfba88a5ad0f 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
> @@ -21,7 +21,6 @@
> 
>  /* PLL_VIDEO0 exported for HDMI PHY */
> 
> -#define CLK_PLL_VIDEO0_2X		8
>  #define CLK_PLL_VE			9
>  #define CLK_PLL_DDR0			10
> 
> @@ -32,7 +31,6 @@
>  #define CLK_PLL_PERIPH1_2X		14
>  #define CLK_PLL_VIDEO1			15
>  #define CLK_PLL_GPU			16
> -#define CLK_PLL_MIPI			17
>  #define CLK_PLL_HSIC			18
>  #define CLK_PLL_DE			19
>  #define CLK_PLL_DDR1			20
> diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h
> b/include/dt-bindings/clock/sun50i-a64-ccu.h
> index 175892189e9d..4f220ea7a23c 100644
> --- a/include/dt-bindings/clock/sun50i-a64-ccu.h
> +++ b/include/dt-bindings/clock/sun50i-a64-ccu.h
> @@ -44,7 +44,9 @@
>  #define _DT_BINDINGS_CLK_SUN50I_A64_H_
> 
>  #define CLK_PLL_VIDEO0		7
> +#define CLK_PLL_VIDEO0_2X	8
>  #define CLK_PLL_PERIPH0		11
> +#define CLK_PLL_MIPI		17
> 
>  #define CLK_CPUX		21
>  #define CLK_BUS_MIPI_DSI	28


From dsimic at manjaro.org  Sun Dec 15 00:00:23 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Sun, 15 Dec 2024 09:00:23 +0100
Subject: [PATCH 2/3] arm64: dts: allwinner: a64: explicitly assign clock
 parent for TCON0
In-Reply-To: <20241215053639.738890-3-anarsoul@gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
 <20241215053639.738890-3-anarsoul@gmail.com>
Message-ID: <bab2e7c53385da06a44b449077c7241a@manjaro.org>

Hello Vasily,

On 2024-12-15 06:34, Vasily Khoruzhick wrote:
> TCON0 seems to need a different clock parent depending on output type.
> For RGB it has to be PLL-VIDEO0-2X, while for DSI it has to be PLL-MIPI
> 
> Video output doesn't work if incorrect clock is assigned.
> 
> On my Pinebook I manually configured PLL-VIDEO0-2X and PLL-MIPI to the 
> same
> rate, and while video output works fine with PLL-VIDEO0-2X, it doesn't
> work at all (as in no picture) with PLL-MIPI.
> 
> Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in 
> TCON0 mux")
> Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>

Thanks for fixing this issue!  I've been banging my head for a while
about how to fix it without introducing new DT properties, and I hope
that the maintainers will like your approach.

I'd suggest that the patch description is improved further a bit, by
incorporating some parts of the good description of the issue that's
already in the cover letter.  With that addressed, please feel free
to include

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

> ---
>  arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts | 2 ++
>  arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts  | 2 ++
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi         | 2 ++
>  3 files changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
> b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
> index 379c2c8466f5..86d44349e095 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
> @@ -390,6 +390,8 @@ &sound {
>  &tcon0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&lcd_rgb666_pins>;
> +	assigned-clocks = <&ccu CLK_TCON0>;
> +	assigned-clock-parents = <&ccu CLK_PLL_VIDEO0_2X>;
> 
>  	status = "okay";
>  };
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
> b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
> index b407e1dd08a7..ec055510af8b 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
> @@ -369,6 +369,8 @@ &sound {
>  &tcon0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&lcd_rgb666_pins>;
> +	assigned-clocks = <&ccu CLK_TCON0>;
> +	assigned-clock-parents = <&ccu CLK_PLL_VIDEO0_2X>;
> 
>  	status = "okay";
>  };
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index a5c3920e0f04..0fecf0abb204 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -445,6 +445,8 @@ tcon0: lcd-controller at 1c0c000 {
>  			clock-names = "ahb", "tcon-ch0";
>  			clock-output-names = "tcon-data-clock";
>  			#clock-cells = <0>;
> +			assigned-clocks = <&ccu CLK_TCON0>;
> +			assigned-clock-parents = <&ccu CLK_PLL_MIPI>;
>  			resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>;
>  			reset-names = "lcd", "lvds";


From dsimic at manjaro.org  Sun Dec 15 00:08:53 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Sun, 15 Dec 2024 09:08:53 +0100
Subject: [PATCH 3/3] clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as
 TCON0 parent
In-Reply-To: <20241215053639.738890-4-anarsoul@gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
 <20241215053639.738890-4-anarsoul@gmail.com>
Message-ID: <32683972639853c626d46fa4374d1558@manjaro.org>

Hello Vasily,

On 2024-12-15 06:34, Vasily Khoruzhick wrote:
> Force selecting PLL-MIPI as TCON0 parent breaks video output on 
> Pinebook
> that uses RGB to eDP bridge.
> 
> TCON0 clock parent will be selected in the device tree instead.
> 
> Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in 
> TCON0 mux")
> Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>

Looking good to me, as a patch that completes the panel bugfix.
Thanks once again for the patches!

I'd suggest that the patch description is improved further a bit,
by incorporating some parts of the good description of the issue
that's already in the cover letter.  In particular, I'd suggest
that you describe that the patch partially reverts an earlier
commit, etc.

Additionally, I'd suggest that the comment block deleted below is
actually adjusted and copied to the addition to the A64 SoC dtsi,
which is performed in the first patch in your series.  That might
be of high value later.

With that addressed, please feel free to include

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

> ---
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 11 -----------
>  1 file changed, 11 deletions(-)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> index 3a7d61c81667..cc8de0bfbc67 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> @@ -534,12 +534,6 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", 
> de_parents,
>  				 0x104, 0, 4, 24, 3, BIT(31),
>  				 CLK_SET_RATE_PARENT);
> 
> -/*
> - * DSI output seems to work only when PLL_MIPI selected. Set it and 
> prevent
> - * the mux from reparenting.
> - */
> -#define SUN50I_A64_TCON0_CLK_REG	0x118
> -
>  static const char * const tcon0_parents[] = { "pll-mipi", 
> "pll-video0-2x" };
>  static const u8 tcon0_table[] = { 0, 2, };
>  static SUNXI_CCU_MUX_TABLE_WITH_GATE_CLOSEST(tcon0_clk, "tcon0", 
> tcon0_parents,
> @@ -959,11 +953,6 @@ static int sun50i_a64_ccu_probe(struct
> platform_device *pdev)
> 
>  	writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
> 
> -	/* Set PLL MIPI as parent for TCON0 */
> -	val = readl(reg + SUN50I_A64_TCON0_CLK_REG);
> -	val &= ~GENMASK(26, 24);
> -	writel(val | (0 << 24), reg + SUN50I_A64_TCON0_CLK_REG);
> -
>  	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc);
>  	if (ret)
>  		return ret;


From wens at csie.org  Sun Dec 15 00:14:57 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Sun, 15 Dec 2024 16:14:57 +0800
Subject: [PATCH 0/3] arm64: allwinner: a64: fix video output on Pinebook
In-Reply-To: <20241215053639.738890-1-anarsoul@gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
Message-ID: <CAGb2v65odTCjkC493e=q57ikeKHWrKYS26N7-0Hjc=S_d6ELyQ@mail.gmail.com>

On Sun, Dec 15, 2024 at 1:36?PM Vasily Khoruzhick <anarsoul at gmail.com> wrote:
>
> Since commit ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux"),
> TCON0 clock parent is always set to PLL_MIPI, but unfortunately it breaks
> video output on Pinebook.
>
> I did an experiment: I manually configured PLL_MIPI and PLL_VIDEO0_2X
> to the same clock rate and flipped the switch with devmem. Experiment clearly
> showed that whenever PLL_MIPI is selected as TCON0 clock parent, the video
> output stops working.
>
> To fix the issue, I partially reverted mentioned commit and added explicit
> TCON0 clock parent assignment to device tree. By default, it will be
> PLL_MIPI, and the only users with RGB output - Pinebook and Teres-I will
> override it in their dts.
>
> Vasily Khoruzhick (3):
>   dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
>   arm64: dts: allwinner: a64: explicitly assign clock parent for TCON0
>   clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent

Looks good to me.

Reviewed-by: Chen-Yu Tsai <wens at csie.org>

I'll wait for a bit for Andre to comment.

>  arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts |  2 ++
>  arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts  |  2 ++
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi         |  2 ++
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c                 | 11 -----------
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.h                 |  2 --
>  include/dt-bindings/clock/sun50i-a64-ccu.h            |  2 ++
>  6 files changed, 8 insertions(+), 13 deletions(-)
>
> --
> 2.47.1
>


From amadeus at jmu.edu.cn  Sun Dec 15 00:38:05 2024
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sun, 15 Dec 2024 16:38:05 +0800
Subject: [PATCH 1/1] arm64: dts: rockchip: default to host mode for USB on Radxa E25
Message-ID: <20241215083805.1461902-1-amadeus@jmu.edu.cn>

The Radxa E25 board has only one USB3.0 Type A connector,
changing it to host mode is more appropriate.

Cc: FUKAUMI Naoki <naoki at radxa.com>
Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
index 98cfa3abb809..90a3cb54fd47 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
@@ -218,6 +218,7 @@ &usb_host0_ohci {
 };
 
 &usb_host0_xhci {
+	dr_mode = "host";
 	status = "okay";
 };
 
-- 
2.25.1



From gregkh at linuxfoundation.org  Sun Dec 15 01:22:53 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Sun, 15 Dec 2024 10:22:53 +0100
Subject: [PATCH 6.6 v1] KVM: arm64: Disable MPAM visibility by default
 and ignore VMM writes
In-Reply-To: <20241212151406.1436382-1-joey.gouly@arm.com>
References: <20241212151406.1436382-1-joey.gouly@arm.com>
Message-ID: <2024121528-refurbish-plausibly-31c7@gregkh>

On Thu, Dec 12, 2024 at 03:14:06PM +0000, Joey Gouly wrote:
> From: James Morse <james.morse at arm.com>
> 
> commit 6685f5d572c22e1003e7c0d089afe1c64340ab1f upstream.
> 
> commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits in
> ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to guests,
> but didn't add trap handling. A previous patch supplied the missing trap
> handling.
> 
> Existing VMs that have the MPAM field of ID_AA64PFR0_EL1 set need to
> be migratable, but there is little point enabling the MPAM CPU
> interface on new VMs until there is something a guest can do with it.
> 
> Clear the MPAM field from the guest's ID_AA64PFR0_EL1 and on hardware
> that supports MPAM, politely ignore the VMMs attempts to set this bit.
> 
> Guests exposed to this bug have the sanitised value of the MPAM field,
> so only the correct value needs to be ignored. This means the field
> can continue to be used to block migration to incompatible hardware
> (between MPAM=1 and MPAM=5), and the VMM can't rely on the field
> being ignored.
> 
> Signed-off-by: James Morse <james.morse at arm.com>
> Co-developed-by: Joey Gouly <joey.gouly at arm.com>
> Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> Reviewed-by: Gavin Shan <gshan at redhat.com>
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Reviewed-by: Marc Zyngier <maz at kernel.org>
> Link: https://lore.kernel.org/r/20241030160317.2528209-7-joey.gouly at arm.com
> Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> [ joey: fixed up merge conflict, no ID_FILTERED macro in 6.6 ]
> Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> Cc: stable at vger.kernel.org # 6.6.x
> Cc: Vitaly Chikunov <vt at altlinux.org>
> Link: https://lore.kernel.org/linux-arm-kernel/20241202045830.e4yy3nkvxtzaybxk at altlinux.org/
> ---
> 
> This fixes an issue seen when using KVM with a 6.6 host kernel, and
> newer (6.13+) kernels in the guest.
> 
> Tested with a stripped down version of set_id_regs from the original
> patch series.

What about 6.12.y?  You can't just skip a stable tree, otherwise you
will get a regression when you upgrade to 6.12.y, right?

thanks,

greg k-h


From francesco at dolcini.it  Sun Dec 15 03:06:23 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Sun, 15 Dec 2024 12:06:23 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am62l: add initial infrastructure
In-Reply-To: <20241214215624.e372oju6eserpf4f@bryanbrattlof.com>
References: <20241117-am62lx-v1-0-4e71e42d781d@ti.com>
 <20241117-am62lx-v1-1-4e71e42d781d@ti.com>
 <Z12rnZiCXQxtMWlf@livingston.pivistrello.it>
 <20241214215624.e372oju6eserpf4f@bryanbrattlof.com>
Message-ID: <Z164Lyg-AH8KBTYZ@livingston.pivistrello.it>

Hello Bryan,

On Sat, Dec 14, 2024 at 03:56:24PM -0600, Bryan Brattlof wrote:
> On December 14, 2024 thus sayeth Francesco Dolcini:
> > On Sun, Nov 17, 2024 at 11:34:07PM -0600, Bryan Brattlof wrote:
> > > From: Vignesh Raghavendra <vigneshr at ti.com>
> > > 
> > > Add the initial infrastructure needed for the AM62L. All of which can be
> > > found in the Technical Reference Manual (TRM) located here:
> > > 
> > >     https://www.ti.com/lit/ug/sprujb4/sprujb4.pdf
> > > 
> > > Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
> > > Signed-off-by: Bryan Brattlof <bb at ti.com>
> > > ---
> > >  Documentation/devicetree/bindings/arm/ti/k3.yaml |  6 ++
> > >  arch/arm64/boot/dts/ti/Makefile                  |  3 +
> > >  arch/arm64/boot/dts/ti/k3-am62l-main.dtsi        | 52 ++++++++++++++
> > >  arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi      | 33 +++++++++
> > >  arch/arm64/boot/dts/ti/k3-am62l.dtsi             | 89 ++++++++++++++++++++++++
> > >  arch/arm64/boot/dts/ti/k3-am62l3.dtsi            | 67 ++++++++++++++++++
> > >  arch/arm64/boot/dts/ti/k3-pinctrl.h              |  2 +
> > >  7 files changed, 252 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
> > > index 18f155cd06c84..b109e854879cb 100644
> > > --- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
> > > +++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
> > > @@ -31,6 +31,12 @@ properties:
> > >            - const: phytec,am62a-phycore-som
> > >            - const: ti,am62a7
> > >  
> > > +      - description: K3 AM62L3 SoC and Boards
> > > +        items:
> > > +          - enum:
> > > +              - ti,am62l3-evm
> > > +          - const: ti,am62l3
> > > +
> > 
> > can you clarify the differences between AM62L and AM62L3? you have a mix of names in this series. I assume that
> > AM62L is the SOC family / product name, while AM62L3 is a specific 
> > part number.
> >
> 
> Absolutely! I found the naming a bit confusing myself. 

Thanks for the clarification, having ti,am62l3 is consistent with what
you did with AM62, in which you have ti,am625.

Francesco




From sakari.ailus at iki.fi  Sun Dec 15 04:18:42 2024
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Sun, 15 Dec 2024 12:18:42 +0000
Subject: [PATCH v4 02/15] dt-bindings: media: add description of stm32 csi
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-2-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
 <20241212-csi_dcmipp_mp25-v4-2-fbeb55a05ed7@foss.st.com>
Message-ID: <Z17JItE-98IIrnMv@valkosipuli.retiisi.eu>

Hi Alain,

On Thu, Dec 12, 2024 at 10:17:26AM +0100, Alain Volmat wrote:
> Add the stm32 csi controller description.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> ---
> v2:
>   - rename into st,stm32mp25-csi.yaml to match compatible
>   - correct port / data-lanes (remove useless lines &
>     use data-lanes 1 and 2 instead of 0 and 1)
>   - correct commit log
> ---
>  .../bindings/media/st,stm32mp25-csi.yaml           | 125 +++++++++++++++++++++
>  1 file changed, 125 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> new file mode 100644
> index 000000000000..33bedfe41924
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> @@ -0,0 +1,125 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/st,stm32mp25-csi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: STMicroelectronics STM32 CSI controller
> +
> +description:
> +  The STM32 CSI controller allows connecting a CSI based
> +  camera to the DCMIPP camera pipeline.

CSI-2 I presume?

You should also document it here it has D-PHY...

> +
> +maintainers:
> +  - Alain Volmat <alain.volmat at foss.st.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - st,stm32mp25-csi
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 3
> +
> +  clock-names:
> +    items:
> +      - const: pclk
> +      - const: txesc
> +      - const: csi2phy
> +
> +  resets:
> +    maxItems: 1
> +
> +  vdd-supply:
> +    description: Digital core power supply (0.91V)
> +
> +  vdda18-supply:
> +    description: System analog power supply (1.8V)
> +
> +  access-controllers:
> +    minItems: 1
> +    maxItems: 2
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Input port node
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +
> +            properties:
> +              data-lanes:
> +                minItems: 1
> +                items:
> +                  - const: 1
> +                  - const: 2
> +
> +            required:
> +              - data-lanes
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Output port node
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - resets
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/media/video-interfaces.h>
> +    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
> +    csi at 48020000 {
> +        compatible = "st,stm32mp25-csi";
> +        reg = <0x48020000 0x2000>;
> +        interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
> +        resets = <&rcc CSI_R>;
> +        clocks = <&rcc CK_KER_CSI>, <&rcc CK_KER_CSITXESC>, <&rcc CK_KER_CSIPHY>;
> +        clock-names = "pclk", "txesc", "csi2phy";
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +            port at 0 {
> +                reg = <0>;
> +                endpoint {
> +                    remote-endpoint = <&imx335_ep>;
> +                    data-lanes = <1 2>;
> +                    bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;

...and drop bus-type property.

> +                };
> +            };
> +
> +            port at 1 {
> +                reg = <1>;
> +                endpoint {
> +                    remote-endpoint = <&dcmipp_0>;
> +                };
> +            };
> +        };
> +    };
> +
> +...
> 

-- 
Kind regards,

Sakari Ailus


From peng.fan at oss.nxp.com  Sun Dec 15 05:26:40 2024
From: peng.fan at oss.nxp.com (Peng Fan)
Date: Sun, 15 Dec 2024 21:26:40 +0800
Subject: [PATCH] PCI: check bridge->bus in pci_host_common_remove
In-Reply-To: <CAL_Jsq+R39jtCeDecpEHbKq+4N-uirMQmsuNG1NaVe1Vnnnv3Q@mail.gmail.com>
References: <20241028084644.3778081-1-peng.fan@oss.nxp.com>
 <20241115062005.6ifvr6ens2qnrrrf@thinkpad>
 <PAXPR04MB8459D1507CA69498D8C38E0488242@PAXPR04MB8459.eurprd04.prod.outlook.com>
 <20241115144720.ovsyq2ani47norby@thinkpad>
 <20241127195650.GA4132105-robh@kernel.org>
 <20241202092902.rp6xb3f64llpabbi@thinkpad>
 <CAL_Jsq+R39jtCeDecpEHbKq+4N-uirMQmsuNG1NaVe1Vnnnv3Q@mail.gmail.com>
Message-ID: <20241215132640.GA2476@localhost.localdomain>

Hi Rob,

On Mon, Dec 02, 2024 at 07:55:27AM -0600, Rob Herring wrote:
>On Mon, Dec 2, 2024 at 3:29?AM Manivannan Sadhasivam
><manivannan.sadhasivam at linaro.org> wrote:
>>
>> On Wed, Nov 27, 2024 at 01:56:50PM -0600, Rob Herring wrote:
>> > On Fri, Nov 15, 2024 at 08:17:20PM +0530, Manivannan Sadhasivam wrote:
>> > > On Fri, Nov 15, 2024 at 10:14:10AM +0000, Peng Fan wrote:
>> > > > Hi Manivannan,
>> > > >
>> > > > > Subject: Re: [PATCH] PCI: check bridge->bus in
>> > > > > pci_host_common_remove
>> > > > >
>> > > > > On Mon, Oct 28, 2024 at 04:46:43PM +0800, Peng Fan (OSS) wrote:
>> > > > > > From: Peng Fan <peng.fan at nxp.com>
>> > > > > >
>> > > > > > When PCI node was created using an overlay and the overlay is
>> > > > > > reverted/destroyed, the "linux,pci-domain" property no longer exists,
>> > > > > > so of_get_pci_domain_nr will return failure. Then
>> > > > > > of_pci_bus_release_domain_nr will actually use the dynamic IDA,
>> > > > > even
>> > > > > > if the IDA was allocated in static IDA. So the flow is as below:
>> > > > > > A: of_changeset_revert
>> > > > > >     pci_host_common_remove
>> > > > > >      pci_bus_release_domain_nr
>> > > > > >        of_pci_bus_release_domain_nr
>> > > > > >          of_get_pci_domain_nr      # fails because overlay is gone
>> > > > > >          ida_free(&pci_domain_nr_dynamic_ida)
>> > > > > >
>> > > > > > With driver calls pci_host_common_remove explicity, the flow
>> > > > > becomes:
>> > > > > > B pci_host_common_remove
>> > > > > >    pci_bus_release_domain_nr
>> > > > > >     of_pci_bus_release_domain_nr
>> > > > > >      of_get_pci_domain_nr      # succeeds in this order
>> > > > > >       ida_free(&pci_domain_nr_static_ida)
>> > > > > > A of_changeset_revert
>> > > > > >    pci_host_common_remove
>> > > > > >
>> > > > > > With updated flow, the pci_host_common_remove will be called
>> > > > > twice, so
>> > > > > > need to check 'bridge->bus' to avoid accessing invalid pointer.
>> > > > > >
>> > > > > > Fixes: c14f7ccc9f5d ("PCI: Assign PCI domain IDs by ida_alloc()")
>> > > > > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
>> > > > >
>> > > > > I went through the previous discussion [1] and I couldn't see an
>> > > > > agreement on the point raised by Bjorn on 'removing the host bridge
>> > > > > before the overlay'.
>> > > >
>> > > > This patch is an agreement to Bjorn's idea.
>> > > >
>> > > > I have added pci_host_common_remove to remove host bridge
>> > > > before removing overlay as I wrote in commit log.
>> > > >
>> > > > But of_changeset_revert will still runs into pci_host_
>> > > > common_remove to remove the host bridge again. Per
>> > > > my view, the design of of_changeset_revert to remove
>> > > > the device tree node will trigger device remove, so even
>> > > > pci_host_common_remove was explicitly used before
>> > > > of_changeset_revert. The following call to of_changeset_revert
>> > > > will still call pci_host_common_remove.
>> > > >
>> > > > So I did this patch to add a check of 'bus' to avoid remove again.
>> > > >
>> > >
>> > > Ok. I think there was a misunderstanding. Bjorn's example driver,
>> > > 'i2c-demux-pinctrl' applies the changeset, then adds the i2c adapter for its
>> > > own. And in remove(), it does the reverse.
>> > >
>> > > But in your case, the issue is with the host bridge driver that gets probed
>> > > because of the changeset. While with 'i2c-demux-pinctrl' driver, it only
>> > > applies the changeset. So we cannot compare both drivers. I believe in your
>> > > case, 'i2c-demux-pinctrl' becomes 'jailhouse', isn't it?
>> > >
>> > > So in your case, changeset is applied by jailhouse and that causes the
>> > > platform device to be created for the host bridge and then the host bridge
>> > > driver gets probed. So during destroy(), you call of_changeset_revert() that
>> > > removes the platform device and during that process it removes the host bridge
>> > > driver. The issue happens because during host bridge remove, it calls
>> > > pci_remove_root_bus() and that tries to remove the domain_nr using
>> > > pci_bus_release_domain_nr().
>> > >
>> > > But pci_bus_release_domain_nr() uses DT node to check whether to free the
>> > > domain_nr from static IDA or dynamic IDA. And because there is no DT node exist
>> > > at this time (it was already removed by of_changeset_revert()), it forces
>> > > pci_bus_release_domain_nr() to use dynamic IDA even though the IDA was initially
>> > > allocated from static IDA.
>> >
>> > Putting linux,pci-domain in an overlay is the same problem as aliases in
>> > overlays[1]. It's not going to work well.
>> >
>> > IMO, you can have overlays, or you can have static domains. You can't
>> > have both.
>> >
>>
>> Okay.
>>
>> > > I think a neat way to solve this issue would be by removing the OF node only
>> > > after removing all platform devices/drivers associated with that node. But I
>> > > honestly do not know whether that is possible or not. Otherwise, any other
>> > > driver that relies on the OF node in its remove() callback, could suffer from
>> > > the same issue. And whatever fix we may come up with in PCI core, it will be a
>> > > band-aid only.
>> > >
>> > > I'd like to check with Rob first about his opinion.
>> >
>> > If the struct device has an of_node set, there should be a reference
>> > count on that node. But I think that only prevents the node from being
>> > freed. It does not prevent the overlay from being detached. This is one
>> > of many of the issues with overlays Frank painstakingly documented[2].
>> >
>>
>> Ah, I do remember this page as Frank ended up creating it based on my
>> continuous nudge to add CONFIG_FS interface for applying overlays.
>>
>> So why are we applying overlays in kernel now?
>
>That's been the case for some time. Mostly it's been for fixups of old
>to new bindings, but those all got dropped at some point. The in
>kernel users are very specific use cases where we know something about
>what's in the overlay. In contrast, configfs interface allows for any
>change to any node or property with no control over it by the kernel.
>Never say never, but I just don't see that ever happening upstream.

So should I switch to use configfs for jailhouse case? Currently
we use overlay to add a virtual pci node to kernel device tree.

Thanks
Peng

>
>Rob


From naoki at radxa.com  Sun Dec 15 04:36:19 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 15 Dec 2024 21:36:19 +0900
Subject: [PATCH 1/1] arm64: dts: rockchip: default to host mode for USB on
 Radxa E25
In-Reply-To: <20241215083805.1461902-1-amadeus@jmu.edu.cn>
References: <20241215083805.1461902-1-amadeus@jmu.edu.cn>
Message-ID: <6EFDC4E74A617E25+ed534e8a-fef0-4f09-a24b-a536b7f2f13b@radxa.com>

Hi Chukun,

Could you check Product Brief P.4?

  https://dl.radxa.com/cm3i/e25/radxa_e25_product_brief.pdf

There is "USB3.0 OTG Switch".

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 12/15/24 17:38, Chukun Pan wrote:
> The Radxa E25 board has only one USB3.0 Type A connector,
> changing it to host mode is more appropriate.
> 
> Cc: FUKAUMI Naoki <naoki at radxa.com>
> Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
> ---
>   arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
> index 98cfa3abb809..90a3cb54fd47 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
> @@ -218,6 +218,7 @@ &usb_host0_ohci {
>   };
>   
>   &usb_host0_xhci {
> +	dr_mode = "host";
>   	status = "okay";
>   };
>   




From sakari.ailus at iki.fi  Sun Dec 15 04:40:39 2024
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Sun, 15 Dec 2024 12:40:39 +0000
Subject: [PATCH v4 03/15] media: stm32: csi: addition of the STM32 CSI
 driver
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-3-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
 <20241212-csi_dcmipp_mp25-v4-3-fbeb55a05ed7@foss.st.com>
Message-ID: <Z17OR258tjFZJq9K@valkosipuli.retiisi.eu>

Hi Alain,

On Thu, Dec 12, 2024 at 10:17:27AM +0100, Alain Volmat wrote:
> The STM32 CSI controller is tightly coupled with the DCMIPP and act as an
> input stage to receive data coming from the sensor and transferring
> them into the DCMIPP.
> 
> Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> 
> ---
> v3: get reset controller within probe function and remove it
>     from the driver structure
>     use devm_clk_bulk apis rather 3 separate clks
> 
> v2: correct data-lanes handling, using values 1 & 2
>     update yaml filename in MAINTAINERS
> ---
>  MAINTAINERS                                 |    8 +
>  drivers/media/platform/st/stm32/Kconfig     |   14 +
>  drivers/media/platform/st/stm32/Makefile    |    1 +
>  drivers/media/platform/st/stm32/stm32-csi.c | 1137 +++++++++++++++++++++++++++
>  4 files changed, 1160 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1e930c7a58b1..2ffa10e38e52 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14495,6 +14495,14 @@ W:	https://linuxtv.org
>  T:	git git://linuxtv.org/media.git
>  F:	drivers/media/dvb-frontends/stv6111*
>  
> +MEDIA DRIVERS FOR STM32 - CSI
> +M:	Alain Volmat <alain.volmat at foss.st.com>
> +L:	linux-media at vger.kernel.org
> +S:	Supported
> +T:	git git://linuxtv.org/media_tree.git
> +F:	Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> +F:	drivers/media/platform/stm32/stm32-csi.c
> +
>  MEDIA DRIVERS FOR STM32 - DCMI / DCMIPP
>  M:	Hugues Fruchet <hugues.fruchet at foss.st.com>
>  M:	Alain Volmat <alain.volmat at foss.st.com>
> diff --git a/drivers/media/platform/st/stm32/Kconfig b/drivers/media/platform/st/stm32/Kconfig
> index 9df9a2a17728..f12e67bcc9bc 100644
> --- a/drivers/media/platform/st/stm32/Kconfig
> +++ b/drivers/media/platform/st/stm32/Kconfig
> @@ -1,6 +1,20 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  
>  # V4L drivers
> +config VIDEO_STM32_CSI
> +	tristate "STM32 Camera Serial Interface (CSI) support"
> +	depends on V4L_PLATFORM_DRIVERS
> +	depends on VIDEO_DEV && OF
> +	depends on ARCH_STM32 || COMPILE_TEST
> +	select MEDIA_CONTROLLER
> +	select V4L2_FWNODE
> +	help
> +	  This module makes the STM32 Camera Serial Interface (CSI)
> +	  available as a v4l2 device.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called stm32-csi.
> +
>  config VIDEO_STM32_DCMI
>  	tristate "STM32 Digital Camera Memory Interface (DCMI) support"
>  	depends on V4L_PLATFORM_DRIVERS
> diff --git a/drivers/media/platform/st/stm32/Makefile b/drivers/media/platform/st/stm32/Makefile
> index 7ed8297b9b19..9ae57897f030 100644
> --- a/drivers/media/platform/st/stm32/Makefile
> +++ b/drivers/media/platform/st/stm32/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_VIDEO_STM32_CSI) += stm32-csi.o
>  obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32-dcmi.o
>  obj-$(CONFIG_VIDEO_STM32_DCMIPP) += stm32-dcmipp/
>  stm32-dma2d-objs := dma2d/dma2d.o dma2d/dma2d-hw.o
> diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
> new file mode 100644
> index 000000000000..48941aae8c9b
> --- /dev/null
> +++ b/drivers/media/platform/st/stm32/stm32-csi.c
> @@ -0,0 +1,1137 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for STM32 Camera Serial Interface
> + *
> + * Copyright (C) STMicroelectronics SA 2024
> + * Author: Alain Volmat <alain.volmat at foss.st.com>
> + * for STMicroelectronics.
> + */
> +
> +#include <linux/clk.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>
> +#include <linux/reset.h>
> +#include <linux/slab.h>
> +
> +#include <media/mipi-csi2.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +
> +#define STM32_CSI_CR				0x0000
> +#define STM32_CSI_CR_CSIEN			BIT(0)
> +#define STM32_CSI_CR_VCXSTART(x)		BIT(2 + ((x) * 4))
> +#define STM32_CSI_CR_VCXSTOP(x)			BIT(3 + ((x) * 4))
> +#define STM32_CSI_PCR				0x0004
> +#define STM32_CSI_PCR_DL1EN			BIT(3)
> +#define STM32_CSI_PCR_DL0EN			BIT(2)
> +#define STM32_CSI_PCR_CLEN			BIT(1)
> +#define STM32_CSI_PCR_PWRDOWN			BIT(0)
> +#define STM32_CSI_VCXCFGR1(x)			((((x) + 1) * 0x0010) + 0x0)
> +#define STM32_CSI_VCXCFGR1_ALLDT		BIT(0)
> +#define STM32_CSI_VCXCFGR1_DT0EN		BIT(1)
> +#define STM32_CSI_VCXCFGR1_DT1EN		BIT(2)
> +#define STM32_CSI_VCXCFGR1_CDTFT_SHIFT		8
> +#define STM32_CSI_VCXCFGR1_DT0_SHIFT		16
> +#define STM32_CSI_VCXCFGR1_DT0FT_SHIFT		24
> +#define STM32_CSI_VCXCFGR2(x)			((((x) + 1) * 0x0010) + 0x4)
> +#define STM32_CSI_VCXCFGR2_DT1_SHIFT		0
> +#define STM32_CSI_VCXCFGR2_DT1FT_SHIFT		8
> +#define STM32_CSI_INPUT_BPP8			2
> +#define STM32_CSI_INPUT_BPP10			3
> +#define STM32_CSI_INPUT_BPP12			4
> +#define STM32_CSI_INPUT_BPP14			5
> +#define STM32_CSI_LMCFGR			0x0070
> +#define STM32_CSI_LMCFGR_LANENB_SHIFT		8
> +#define STM32_CSI_LMCFGR_DLMAP_SHIFT		16
> +#define STM32_CSI_IER0				0x0080
> +#define STM32_CSI_IER1				0x0084
> +#define STM32_CSI_SR0				0x0090
> +#define STM32_CSI_SR0_SYNCERRF			BIT(30)
> +#define STM32_CSI_SR0_SPKTERRF			BIT(28)
> +#define STM32_CSI_SR0_IDERRF			BIT(27)
> +#define STM32_CSI_SR0_CECCERRF			BIT(26)
> +#define STM32_CSI_SR0_ECCERRF			BIT(25)
> +#define STM32_CSI_SR0_CRCERRF			BIT(24)
> +#define STM32_CSI_SR0_CCFIFOFF			BIT(21)
> +#define STM32_CSI_SR0_VCXSTATEF(x)		BIT(17 + (x))
> +#define STM32_CSI_SR1				0x0094
> +#define STM32_CSI_SR1_ECTRLDL1F			BIT(12)
> +#define STM32_CSI_SR1_ESYNCESCDL1F		BIT(11)
> +#define STM32_CSI_SR1_EESCDL1F			BIT(10)
> +#define STM32_CSI_SR1_ESOTSYNCDL1F		BIT(9)
> +#define STM32_CSI_SR1_ESOTDL1F			BIT(8)
> +#define STM32_CSI_SR1_ECTRLDL0F			BIT(4)
> +#define STM32_CSI_SR1_ESYNCESCDL0F		BIT(3)
> +#define STM32_CSI_SR1_EESCDL0F			BIT(2)
> +#define STM32_CSI_SR1_ESOTSYNCDL0F		BIT(1)
> +#define STM32_CSI_SR1_ESOTDL0F			BIT(0)
> +#define STM32_CSI_FCR0				0x0100
> +#define STM32_CSI_FCR1				0x0104
> +#define STM32_CSI_SPDFR				0x0110
> +#define STM32_CSI_DT_MASK			0x3f
> +#define STM32_CSI_VC_MASK			0x03
> +#define STM32_CSI_ERR1				0x0114
> +#define STM32_CSI_ERR1_IDVCERR_SHIFT		22
> +#define STM32_CSI_ERR1_IDDTERR_SHIFT		16
> +#define STM32_CSI_ERR1_CECCVCERR_SHIFT		14
> +#define STM32_CSI_ERR1_CECCDTERR_SHIFT		8
> +#define STM32_CSI_ERR1_CRCVCERR_SHIFT		6
> +#define STM32_CSI_ERR1_CRCDTERR_SHIFT		0
> +#define STM32_CSI_ERR2				0x0118
> +#define STM32_CSI_ERR2_SYNCVCERR_SHIFT		18
> +#define STM32_CSI_ERR2_SPKTVCERR_SHIFT		6
> +#define STM32_CSI_ERR2_SPKTDTERR_SHIFT		0
> +#define STM32_CSI_PRCR				0x1000
> +#define STM32_CSI_PRCR_PEN			BIT(1)
> +#define STM32_CSI_PMCR				0x1004
> +#define STM32_CSI_PFCR				0x1008
> +#define STM32_CSI_PFCR_CCFR_MASK		GENMASK(5, 0)
> +#define STM32_CSI_PFCR_CCFR_SHIFT		0
> +#define STM32_CSI_PFCR_HSFR_MASK		GENMASK(14, 8)
> +#define STM32_CSI_PFCR_HSFR_SHIFT		8
> +#define STM32_CSI_PFCR_DLD			BIT(16)
> +#define STM32_CSI_PTCR0				0x1010
> +#define STM32_CSI_PTCR0_TCKEN			BIT(0)
> +#define STM32_CSI_PTCR1				0x1014
> +#define STM32_CSI_PTCR1_TWM			BIT(16)
> +#define STM32_CSI_PTCR1_TDI_MASK		GENMASK(7, 0)
> +#define STM32_CSI_PTCR1_TDI_SHIFT		0
> +#define STM32_CSI_PTSR				0x1018
> +
> +#define STM32_CSI_LANES_MAX	2
> +
> +#define STM32_CSI_SR0_ERRORS	(STM32_CSI_SR0_SYNCERRF | STM32_CSI_SR0_SPKTERRF |\
> +				 STM32_CSI_SR0_IDERRF | STM32_CSI_SR0_CECCERRF |\
> +				 STM32_CSI_SR0_ECCERRF | STM32_CSI_SR0_CRCERRF |\
> +				 STM32_CSI_SR0_CCFIFOFF)
> +#define STM32_CSI_SR1_DL0_ERRORS	(STM32_CSI_SR1_ECTRLDL0F | STM32_CSI_SR1_ESYNCESCDL0F |\
> +				 STM32_CSI_SR1_EESCDL0F | STM32_CSI_SR1_ESOTSYNCDL0F |\
> +				 STM32_CSI_SR1_ESOTDL0F)
> +#define STM32_CSI_SR1_DL1_ERRORS	(STM32_CSI_SR1_ECTRLDL1F | STM32_CSI_SR1_ESYNCESCDL1F |\
> +				 STM32_CSI_SR1_EESCDL1F | STM32_CSI_SR1_ESOTSYNCDL1F |\
> +				 STM32_CSI_SR1_ESOTDL1F)
> +#define STM32_CSI_SR1_ERRORS	(STM32_CSI_SR1_DL0_ERRORS | STM32_CSI_SR1_DL1_ERRORS)
> +
> +enum stm32_csi_pads {
> +	STM32_CSI_PAD_SINK,
> +	STM32_CSI_PAD_SOURCE,
> +	STM32_CSI_PAD_MAX,
> +};
> +
> +struct stm32_csi_event {
> +	u32 mask;
> +	const char * const name;
> +};
> +
> +static const struct stm32_csi_event stm32_csi_events_sr0[] = {
> +	{STM32_CSI_SR0_SYNCERRF,	"Synchronization error"},
> +	{STM32_CSI_SR0_SPKTERRF,	"Short packet error"},
> +	{STM32_CSI_SR0_IDERRF,		"Data type ID error"},
> +	{STM32_CSI_SR0_CECCERRF,	"Corrected ECC error"},
> +	{STM32_CSI_SR0_ECCERRF,		"ECC error"},
> +	{STM32_CSI_SR0_CRCERRF,		"CRC error"},
> +	{STM32_CSI_SR0_CCFIFOFF,	"Clk changer FIFO full error"},
> +};
> +
> +#define STM32_CSI_NUM_SR0_EVENTS ARRAY_SIZE(stm32_csi_events_sr0)
> +
> +static const struct stm32_csi_event stm32_csi_events_sr1[] = {
> +	{STM32_CSI_SR1_ECTRLDL1F,	"L1: D-PHY control error"},
> +	{STM32_CSI_SR1_ESYNCESCDL1F,
> +		"L1: D-PHY low power data transmission synchro error"},
> +	{STM32_CSI_SR1_EESCDL1F,	"L1: D-PHY escape entry error"},
> +	{STM32_CSI_SR1_ESOTSYNCDL1F,
> +		"L1: Start of transmission synchro error"},
> +	{STM32_CSI_SR1_ESOTDL1F,	"L1: Start of transmission error"},
> +	{STM32_CSI_SR1_ECTRLDL0F,	"L0: D-PHY control error"},
> +	{STM32_CSI_SR1_ESYNCESCDL0F,
> +		"L0: D-PHY low power data transmission synchro error"},
> +	{STM32_CSI_SR1_EESCDL0F,	"L0: D-PHY escape entry error"},
> +	{STM32_CSI_SR1_ESOTSYNCDL0F,
> +		"L0: Start of transmission synchro error"},
> +	{STM32_CSI_SR1_ESOTDL0F,	"L0: Start of transmission error"},
> +};
> +
> +#define STM32_CSI_NUM_SR1_EVENTS ARRAY_SIZE(stm32_csi_events_sr1)
> +
> +enum stm32_csi_clk {
> +	STM32_CSI_CLK_PCLK,
> +	STM32_CSI_CLK_TXESC,
> +	STM32_CSI_CLK_CSI2PHY,
> +	STM32_CSI_CLK_NB,
> +};
> +
> +static const char * const stm32_csi_clks_id[] = {
> +	"pclk",
> +	"txesc",
> +	"csi2phy",
> +};
> +
> +struct stm32_csi_dev {
> +	struct device			*dev;
> +
> +	void __iomem			*base;
> +
> +	struct clk_bulk_data		clks[STM32_CSI_CLK_NB];
> +	struct regulator_bulk_data	supplies[2];
> +
> +	u8				lanes[STM32_CSI_LANES_MAX];
> +	u8				num_lanes;
> +
> +	/*
> +	 * spinlock slock is used to protect to srX_counters tables being
> +	 * accessed from log_status and interrupt context
> +	 */
> +	spinlock_t			slock;
> +
> +	u32				sr0_counters[STM32_CSI_NUM_SR0_EVENTS];
> +	u32				sr1_counters[STM32_CSI_NUM_SR1_EVENTS];
> +
> +	struct v4l2_subdev		sd;
> +	struct v4l2_async_notifier	notifier;
> +	struct media_pad		pads[STM32_CSI_PAD_MAX];
> +
> +	/* Remote source */
> +	struct v4l2_subdev		*s_subdev;
> +	u32				s_subdev_pad_nb;
> +};
> +
> +struct stm32_csi_fmts {
> +	u32 code;
> +	u32 datatype;
> +	u32 input_fmt;
> +	u8 bpp;
> +};
> +
> +#define FMT_MBUS_DT_DTFMT_BPP(mbus, dt, input, byteperpixel)		\
> +	{								\
> +		.code = MEDIA_BUS_FMT_##mbus,				\
> +		.datatype = MIPI_CSI2_DT_##dt,				\
> +		.input_fmt = STM32_CSI_INPUT_##input,	\
> +		.bpp = byteperpixel,					\
> +	}
> +static const struct stm32_csi_fmts stm32_csi_formats[] = {
> +	/* YUV 422 8 bit */
> +	FMT_MBUS_DT_DTFMT_BPP(UYVY8_1X16, YUV422_8B, BPP8, 8),
> +	FMT_MBUS_DT_DTFMT_BPP(YUYV8_1X16, YUV422_8B, BPP8, 8),
> +	FMT_MBUS_DT_DTFMT_BPP(YVYU8_1X16, YUV422_8B, BPP8, 8),
> +	FMT_MBUS_DT_DTFMT_BPP(VYUY8_1X16, YUV422_8B, BPP8, 8),
> +
> +	/* Raw Bayer */
> +	/* 8 bit */
> +	FMT_MBUS_DT_DTFMT_BPP(SBGGR8_1X8, RAW8, BPP8, 8),
> +	FMT_MBUS_DT_DTFMT_BPP(SGBRG8_1X8, RAW8, BPP8, 8),
> +	FMT_MBUS_DT_DTFMT_BPP(SGRBG8_1X8, RAW8, BPP8, 8),
> +	FMT_MBUS_DT_DTFMT_BPP(SRGGB8_1X8, RAW8, BPP8, 8),
> +	/* 10 bit */
> +	FMT_MBUS_DT_DTFMT_BPP(SRGGB10_1X10, RAW10, BPP10, 10),
> +	FMT_MBUS_DT_DTFMT_BPP(SGBRG10_1X10, RAW10, BPP10, 10),
> +	FMT_MBUS_DT_DTFMT_BPP(SGRBG10_1X10, RAW10, BPP10, 10),
> +	FMT_MBUS_DT_DTFMT_BPP(SRGGB10_1X10, RAW10, BPP10, 10),
> +	/* 12 bit */
> +	FMT_MBUS_DT_DTFMT_BPP(SRGGB12_1X12, RAW12, BPP12, 12),
> +	FMT_MBUS_DT_DTFMT_BPP(SGBRG12_1X12, RAW12, BPP12, 12),
> +	FMT_MBUS_DT_DTFMT_BPP(SGRBG12_1X12, RAW12, BPP12, 12),
> +	FMT_MBUS_DT_DTFMT_BPP(SRGGB12_1X12, RAW12, BPP12, 12),
> +	/* 14 bit */
> +	FMT_MBUS_DT_DTFMT_BPP(SRGGB14_1X14, RAW14, BPP14, 14),
> +	FMT_MBUS_DT_DTFMT_BPP(SGBRG14_1X14, RAW14, BPP14, 14),
> +	FMT_MBUS_DT_DTFMT_BPP(SGRBG14_1X14, RAW14, BPP14, 14),
> +	FMT_MBUS_DT_DTFMT_BPP(SRGGB14_1X14, RAW14, BPP14, 14),
> +
> +	/* RGB 565 */
> +	FMT_MBUS_DT_DTFMT_BPP(RGB565_1X16, RGB565, BPP8, 8),
> +
> +	/* JPEG (datatype isn't used) */
> +	FMT_MBUS_DT_DTFMT_BPP(JPEG_1X8, NULL, BPP8, 8),
> +};
> +
> +struct stm32_csi_mbps_phy_reg {
> +	unsigned int mbps;
> +	unsigned int hsfreqrange;
> +	unsigned int osc_freq_target;
> +};
> +
> +/*
> + * Table describing configuration of the PHY depending on the
> + * intended Bit Rate. From table 5-8 Frequency Ranges and Defaults
> + * of the Synopsis DWC MIPI PHY databook
> + */
> +static const struct stm32_csi_mbps_phy_reg snps_stm32mp25[] = {
> +	{ .mbps =   80,	.hsfreqrange = 0x00,	.osc_freq_target = 460 },
> +	{ .mbps =   90, .hsfreqrange = 0x10,	.osc_freq_target = 460 },
> +	{ .mbps =  100, .hsfreqrange = 0x20,	.osc_freq_target = 460 },
> +	{ .mbps =  110, .hsfreqrange = 0x30,	.osc_freq_target = 460 },
> +	{ .mbps =  120, .hsfreqrange = 0x01,	.osc_freq_target = 460 },
> +	{ .mbps =  130, .hsfreqrange = 0x11,	.osc_freq_target = 460 },
> +	{ .mbps =  140, .hsfreqrange = 0x21,	.osc_freq_target = 460 },
> +	{ .mbps =  150, .hsfreqrange = 0x31,	.osc_freq_target = 460 },
> +	{ .mbps =  160, .hsfreqrange = 0x02,	.osc_freq_target = 460 },
> +	{ .mbps =  170, .hsfreqrange = 0x12,	.osc_freq_target = 460 },
> +	{ .mbps =  180, .hsfreqrange = 0x22,	.osc_freq_target = 460 },
> +	{ .mbps =  190, .hsfreqrange = 0x32,	.osc_freq_target = 460 },
> +	{ .mbps =  205, .hsfreqrange = 0x03,	.osc_freq_target = 460 },
> +	{ .mbps =  220, .hsfreqrange = 0x13,	.osc_freq_target = 460 },
> +	{ .mbps =  235, .hsfreqrange = 0x23,	.osc_freq_target = 460 },
> +	{ .mbps =  250, .hsfreqrange = 0x33,	.osc_freq_target = 460 },
> +	{ .mbps =  275, .hsfreqrange = 0x04,	.osc_freq_target = 460 },
> +	{ .mbps =  300, .hsfreqrange = 0x14,	.osc_freq_target = 460 },
> +	{ .mbps =  325, .hsfreqrange = 0x25,	.osc_freq_target = 460 },
> +	{ .mbps =  350, .hsfreqrange = 0x35,	.osc_freq_target = 460 },
> +	{ .mbps =  400, .hsfreqrange = 0x05,	.osc_freq_target = 460 },
> +	{ .mbps =  450, .hsfreqrange = 0x16,	.osc_freq_target = 460 },
> +	{ .mbps =  500, .hsfreqrange = 0x26,	.osc_freq_target = 460 },
> +	{ .mbps =  550, .hsfreqrange = 0x37,	.osc_freq_target = 460 },
> +	{ .mbps =  600, .hsfreqrange = 0x07,	.osc_freq_target = 460 },
> +	{ .mbps =  650, .hsfreqrange = 0x18,	.osc_freq_target = 460 },
> +	{ .mbps =  700, .hsfreqrange = 0x28,	.osc_freq_target = 460 },
> +	{ .mbps =  750, .hsfreqrange = 0x39,	.osc_freq_target = 460 },
> +	{ .mbps =  800, .hsfreqrange = 0x09,	.osc_freq_target = 460 },
> +	{ .mbps =  850, .hsfreqrange = 0x19,	.osc_freq_target = 460 },
> +	{ .mbps =  900, .hsfreqrange = 0x29,	.osc_freq_target = 460 },
> +	{ .mbps =  950, .hsfreqrange = 0x3a,	.osc_freq_target = 460 },
> +	{ .mbps = 1000, .hsfreqrange = 0x0a,	.osc_freq_target = 460 },
> +	{ .mbps = 1050, .hsfreqrange = 0x1a,	.osc_freq_target = 460 },
> +	{ .mbps = 1100, .hsfreqrange = 0x2a,	.osc_freq_target = 460 },
> +	{ .mbps = 1150, .hsfreqrange = 0x3b,	.osc_freq_target = 460 },
> +	{ .mbps = 1200, .hsfreqrange = 0x0b,	.osc_freq_target = 460 },
> +	{ .mbps = 1250, .hsfreqrange = 0x1b,	.osc_freq_target = 460 },
> +	{ .mbps = 1300, .hsfreqrange = 0x2b,	.osc_freq_target = 460 },
> +	{ .mbps = 1350, .hsfreqrange = 0x3c,	.osc_freq_target = 460 },
> +	{ .mbps = 1400, .hsfreqrange = 0x0c,	.osc_freq_target = 460 },
> +	{ .mbps = 1450, .hsfreqrange = 0x1c,	.osc_freq_target = 460 },
> +	{ .mbps = 1500, .hsfreqrange = 0x2c,	.osc_freq_target = 460 },
> +	{ .mbps = 1550, .hsfreqrange = 0x3d,	.osc_freq_target = 285 },
> +	{ .mbps = 1600, .hsfreqrange = 0x0d,	.osc_freq_target = 295 },
> +	{ .mbps = 1650, .hsfreqrange = 0x1d,	.osc_freq_target = 304 },
> +	{ .mbps = 1700, .hsfreqrange = 0x2e,	.osc_freq_target = 313 },
> +	{ .mbps = 1750, .hsfreqrange = 0x3e,	.osc_freq_target = 322 },
> +	{ .mbps = 1800, .hsfreqrange = 0x0e,	.osc_freq_target = 331 },
> +	{ .mbps = 1850, .hsfreqrange = 0x1e,	.osc_freq_target = 341 },
> +	{ .mbps = 1900, .hsfreqrange = 0x2f,	.osc_freq_target = 350 },
> +	{ .mbps = 1950, .hsfreqrange = 0x3f,	.osc_freq_target = 359 },
> +	{ .mbps = 2000, .hsfreqrange = 0x0f,	.osc_freq_target = 368 },
> +	{ .mbps = 2050, .hsfreqrange = 0x40,	.osc_freq_target = 377 },
> +	{ .mbps = 2100, .hsfreqrange = 0x41,	.osc_freq_target = 387 },
> +	{ .mbps = 2150, .hsfreqrange = 0x42,	.osc_freq_target = 396 },
> +	{ .mbps = 2200, .hsfreqrange = 0x43,	.osc_freq_target = 405 },
> +	{ .mbps = 2250, .hsfreqrange = 0x44,	.osc_freq_target = 414 },
> +	{ .mbps = 2300, .hsfreqrange = 0x45,	.osc_freq_target = 423 },
> +	{ .mbps = 2350, .hsfreqrange = 0x46,	.osc_freq_target = 432 },
> +	{ .mbps = 2400, .hsfreqrange = 0x47,	.osc_freq_target = 442 },
> +	{ .mbps = 2450, .hsfreqrange = 0x48,	.osc_freq_target = 451 },
> +	{ .mbps = 2500, .hsfreqrange = 0x49,	.osc_freq_target = 460 },
> +	{ /* sentinel */ }
> +};
> +
> +static const struct v4l2_mbus_framefmt fmt_default = {
> +	.width = 640,
> +	.height = 480,
> +	.code = MEDIA_BUS_FMT_RGB565_1X16,
> +	.field = V4L2_FIELD_NONE,
> +	.colorspace = V4L2_COLORSPACE_REC709,
> +	.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
> +	.quantization = V4L2_QUANTIZATION_DEFAULT,
> +	.xfer_func = V4L2_XFER_FUNC_DEFAULT,
> +};
> +
> +static const struct stm32_csi_fmts *stm32_csi_code_to_fmt(unsigned int code)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(stm32_csi_formats); i++)
> +		if (stm32_csi_formats[i].code == code)
> +			return &stm32_csi_formats[i];
> +
> +	return NULL;
> +}
> +
> +static inline struct stm32_csi_dev *to_csidev(struct v4l2_subdev *sd)
> +{
> +	return container_of(sd, struct stm32_csi_dev, sd);
> +}
> +
> +static int stm32_csi_setup_lane_merger(struct stm32_csi_dev *csidev)
> +{
> +	u32 lmcfgr = 0;
> +	int i;

unsigned int i?

> +
> +	for (i = 0; i < csidev->num_lanes; i++) {
> +		if (!csidev->lanes[i] || csidev->lanes[i] > STM32_CSI_LANES_MAX) {
> +			dev_err(csidev->dev, "Invalid lane id (%d)\n", csidev->lanes[i]);
> +			return -EINVAL;
> +		}
> +		lmcfgr |= (csidev->lanes[i] << ((i * 4) + STM32_CSI_LMCFGR_DLMAP_SHIFT));
> +	}
> +
> +	lmcfgr |= (csidev->num_lanes << STM32_CSI_LMCFGR_LANENB_SHIFT);
> +
> +	writel_relaxed(lmcfgr, csidev->base + STM32_CSI_LMCFGR);
> +
> +	return 0;
> +}
> +
> +static void stm32_csi_phy_reg_write(struct stm32_csi_dev *csidev,
> +				    u32 addr, u32 val)
> +{
> +	/* Based on sequence described at section 5.2.3.2 of DesignWave document */
> +	/* For writing the 4-bit testcode MSBs */
> +	/* Set testen to high */
> +	writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1);
> +
> +	/* Set testclk to high */
> +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> +
> +	/* Place 0x00 in testdin */
> +	writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1);
> +
> +	/*
> +	 * Set testclk to low (with the falling edge on testclk, the testdin
> +	 * signal content is latched internally)
> +	 */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> +
> +	/* Set testen to low */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR1);
> +
> +	/* Place the 8-bit word corresponding to the testcode MSBs in testdin */
> +	writel_relaxed(((addr >> 8) & STM32_CSI_PTCR1_TDI_MASK) << STM32_CSI_PTCR1_TDI_SHIFT,
> +		       csidev->base + STM32_CSI_PTCR1);
> +
> +	/* Set testclk to high */
> +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> +
> +	/* For writing the 8-bit testcode LSBs */
> +	/* Set testclk to low */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> +
> +	/* Set testen to high */
> +	writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1);
> +
> +	/* Set testclk to high */
> +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> +
> +	/* Place the 8-bit word test data in testdin */
> +	writel_relaxed((addr & STM32_CSI_PTCR1_TDI_MASK) <<
> +		       STM32_CSI_PTCR1_TDI_SHIFT | STM32_CSI_PTCR1_TWM,
> +		       csidev->base + STM32_CSI_PTCR1);
> +
> +	/*
> +	 * Set testclk to low (with the falling edge on testclk, the testdin
> +	 * signal content is latched internally)
> +	 */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> +
> +	/* Set testen to low */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR1);
> +
> +	/* For writing the data */
> +	/* Place the 8-bit word corresponding to the page offset in testdin */
> +	writel_relaxed((val & STM32_CSI_PTCR1_TDI_MASK) << STM32_CSI_PTCR1_TDI_SHIFT,
> +		       csidev->base + STM32_CSI_PTCR1);
> +
> +	/* Set testclk to high (test data is programmed internally */
> +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> +
> +	/* Finish by setting testclk to low */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> +}
> +
> +static int stm32_csi_start(struct stm32_csi_dev *csidev,
> +			   struct v4l2_subdev_state *state)
> +{
> +	const struct stm32_csi_mbps_phy_reg *phy_regs;
> +	struct v4l2_mbus_framefmt *sink_fmt;
> +	const struct stm32_csi_fmts *fmt;
> +	unsigned long phy_clk_frate;
> +	unsigned int mbps;
> +	u32 lanes_ie = 0;
> +	u32 lanes_en = 0;
> +	s64 link_freq;
> +	int ret;
> +	u32 ccfr;
> +
> +	dev_dbg(csidev->dev, "Starting the CSI2\n");
> +
> +	/* Get the bpp value on pad0 (input of CSI) */
> +	sink_fmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SINK);
> +	fmt = stm32_csi_code_to_fmt(sink_fmt->code);
> +
> +	/* Get the remote sensor link frequency */
> +	if (!csidev->s_subdev)
> +		return -EIO;
> +
> +	link_freq = v4l2_get_link_freq(csidev->s_subdev->ctrl_handler,
> +				       fmt->bpp, 2 * csidev->num_lanes);

You'll be able to pass sub-device to the function soon, see e.g.
<URL:https://git.linuxtv.org/sailus/media_tree.git/commit/?h=devel&id=ac10f4525fd5f48ad33a79d9f261539dcc800039>.
I intend to send a PR with that early next week.

> +	if (link_freq < 0)
> +		return link_freq;
> +
> +	/* MBPS is expressed in Mbps, hence link_freq / 100000 * 2 */
> +	mbps = div_s64(link_freq, 500000);
> +	dev_dbg(csidev->dev, "Computed Mbps: %u\n", mbps);
> +
> +	for (phy_regs = snps_stm32mp25; phy_regs->mbps != 0; phy_regs++)

I'd use ARRAY_SIZE() there instead. There's also bsearch.

> +		if (phy_regs->mbps >= mbps)
> +			break;
> +
> +	if (!phy_regs->mbps) {
> +		dev_err(csidev->dev, "Unsupported PHY speed (%u Mbps)", mbps);
> +		return -ERANGE;
> +	}
> +
> +	dev_dbg(csidev->dev, "PHY settings: (%u Mbps, %u HS FRange, %u OSC Freq)\n",
> +		phy_regs->mbps, phy_regs->hsfreqrange,
> +		phy_regs->osc_freq_target);
> +
> +	/* Prepare lanes related configuration bits */
> +	lanes_ie |= STM32_CSI_SR1_DL0_ERRORS;
> +	lanes_en |= STM32_CSI_PCR_DL0EN;

You could initialise these here instead of in variable declaration.

> +	if (csidev->num_lanes == 2) {
> +		lanes_ie |= STM32_CSI_SR1_DL1_ERRORS;
> +		lanes_en |= STM32_CSI_PCR_DL1EN;
> +	}
> +
> +	ret = pm_runtime_get_sync(csidev->dev);
> +	if (ret < 0)

This requires pm_runtime_put(). Or alternatively, use
pm_runtime_resume_and_get().

In the first case I'd add a label for handling this, considering you have
already two other cases doign more than returning the error code.

> +		return ret;
> +
> +	/* Retrieve CSI2PHY clock rate to compute CCFR value */
> +	phy_clk_frate = clk_get_rate(csidev->clks[STM32_CSI_CLK_CSI2PHY].clk);
> +	if (!phy_clk_frate) {
> +		pm_runtime_put(csidev->dev);
> +		dev_err(csidev->dev, "CSI2PHY clock rate invalid (0)\n");
> +		return ret;
> +	}
> +
> +	ret = stm32_csi_setup_lane_merger(csidev);
> +	if (ret) {
> +		pm_runtime_put(csidev->dev);
> +		return ret;
> +	}
> +
> +	/* Enable the CSI */
> +	writel_relaxed(STM32_CSI_CR_CSIEN, csidev->base + STM32_CSI_CR);
> +
> +	/* Enable some global CSI related interrupts - bits are same as SR0 */
> +	writel_relaxed(STM32_CSI_SR0_ERRORS, csidev->base + STM32_CSI_IER0);
> +
> +	/* Enable lanes related error interrupts */
> +	writel_relaxed(lanes_ie, csidev->base + STM32_CSI_IER1);
> +
> +	/* Initialization of the D-PHY */
> +	/* Stop the D-PHY */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PRCR);
> +
> +	/* Keep the D-PHY in power down state */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PCR);
> +
> +	/* Enable testclr clock during 15ns */
> +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> +	udelay(1);
> +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> +
> +	/* Set hsfreqrange */
> +	phy_clk_frate /= 1000000;
> +	ccfr = (phy_clk_frate - 17) * 4;
> +	writel_relaxed((ccfr << STM32_CSI_PFCR_CCFR_SHIFT) |
> +		       (phy_regs->hsfreqrange << STM32_CSI_PFCR_HSFR_SHIFT),
> +		       csidev->base + STM32_CSI_PFCR);
> +
> +	/* set reg @08 deskew_polarity_rw 1'b1 */
> +	stm32_csi_phy_reg_write(csidev, 0x08, 0x38);
> +
> +	/* set reg @0xE4 counter_for_des_en_config_if_rx 0x10 + DLL prog EN */
> +	/* This is because 13<= cfgclkfreqrange[5:0]<=38 */
> +	stm32_csi_phy_reg_write(csidev, 0xe4, 0x11);
> +
> +	/* set reg @0xe2 & reg @0xe3 value DLL target oscilation freq */
> +	/* Based on the table page 77, osc_freq_target */
> +	stm32_csi_phy_reg_write(csidev, 0xe2, phy_regs->osc_freq_target & 0xFF);
> +	stm32_csi_phy_reg_write(csidev, 0xe3, (phy_regs->osc_freq_target >> 8) & 0x0F);
> +
> +	writel_relaxed(STM32_CSI_PFCR_DLD | readl_relaxed(csidev->base + STM32_CSI_PFCR),
> +		       csidev->base + STM32_CSI_PFCR);
> +
> +	/* Enable Lanes */
> +	writel_relaxed(lanes_en | STM32_CSI_PCR_CLEN, csidev->base + STM32_CSI_PCR);
> +	writel_relaxed(lanes_en | STM32_CSI_PCR_CLEN | STM32_CSI_PCR_PWRDOWN,
> +		       csidev->base + STM32_CSI_PCR);
> +
> +	writel_relaxed(STM32_CSI_PRCR_PEN, csidev->base + STM32_CSI_PRCR);
> +
> +	/* Remove the force */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PMCR);
> +
> +	return ret;
> +}
> +
> +static void stm32_csi_stop(struct stm32_csi_dev *csidev)
> +{
> +	dev_dbg(csidev->dev, "Stopping the CSI2\n");
> +
> +	/* Disable the D-PHY */
> +	writel_relaxed(0, csidev->base + STM32_CSI_PCR);
> +
> +	/* Disable ITs */
> +	writel_relaxed(0, csidev->base + STM32_CSI_IER0);
> +	writel_relaxed(0, csidev->base + STM32_CSI_IER1);
> +
> +	/* Disable the CSI */
> +	writel_relaxed(0, csidev->base + STM32_CSI_CR);
> +
> +	pm_runtime_put(csidev->dev);
> +}
> +
> +static int stm32_csi_start_vc(struct stm32_csi_dev *csidev,
> +			      struct v4l2_subdev_state *state, u32 vc)
> +{
> +	struct v4l2_mbus_framefmt *mbus_fmt;
> +	const struct stm32_csi_fmts *fmt;
> +	u32 cfgr1 = 0;
> +	int ret = 0;

Redundant initialisation.

> +	u32 status;
> +
> +	mbus_fmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SOURCE);
> +	fmt = stm32_csi_code_to_fmt(mbus_fmt->code);
> +
> +	/* If the mbus code is JPEG, don't enable filtering */
> +	if (mbus_fmt->code == MEDIA_BUS_FMT_JPEG_1X8) {
> +		cfgr1 |= STM32_CSI_VCXCFGR1_ALLDT;
> +		cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_CDTFT_SHIFT;
> +		dev_dbg(csidev->dev, "VC%d: enable AllDT mode\n", vc);
> +	} else {
> +		cfgr1 |= fmt->datatype << STM32_CSI_VCXCFGR1_DT0_SHIFT;
> +		cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_DT0FT_SHIFT;
> +		cfgr1 |= STM32_CSI_VCXCFGR1_DT0EN;
> +		dev_dbg(csidev->dev, "VC%d: enable DT0(0x%x)/DT0FT(0x%x)\n",
> +			vc, fmt->datatype, fmt->input_fmt);
> +	}
> +	writel_relaxed(cfgr1, csidev->base + STM32_CSI_VCXCFGR1(vc));
> +
> +	/* Enable processing of the virtual-channel and wait for its status */
> +	writel_relaxed(STM32_CSI_CR_VCXSTART(vc) | STM32_CSI_CR_CSIEN,
> +		       csidev->base + STM32_CSI_CR);
> +
> +	ret = readl_relaxed_poll_timeout(csidev->base + STM32_CSI_SR0,
> +					 status,
> +					 status & STM32_CSI_SR0_VCXSTATEF(vc),
> +					 1000, 1000000);
> +	if (ret) {
> +		dev_err(csidev->dev, "failed to start VC(%d)\n", vc);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int stm32_csi_stop_vc(struct stm32_csi_dev *csidev, u32 vc)
> +{
> +	int ret = 0;

Redundant initialisation.

> +	u32 status;
> +
> +	/* Stop the Virtual Channel */
> +	writel_relaxed(STM32_CSI_CR_VCXSTOP(vc) | STM32_CSI_CR_CSIEN,
> +		       csidev->base + STM32_CSI_CR);
> +
> +	ret = readl_relaxed_poll_timeout(csidev->base + STM32_CSI_SR0,
> +					 status,
> +					 !(status & STM32_CSI_SR0_VCXSTATEF(vc)),
> +					 1000, 1000000);
> +	if (ret) {
> +		dev_err(csidev->dev, "failed to stop VC(%d)\n", vc);
> +		return ret;
> +	}
> +
> +	/* Disable all DTs */
> +	writel_relaxed(0, csidev->base + STM32_CSI_VCXCFGR1(vc));
> +	writel_relaxed(0, csidev->base + STM32_CSI_VCXCFGR2(vc));
> +
> +	return 0;
> +}
> +
> +static int stm32_csi_disable_streams(struct v4l2_subdev *sd,
> +				     struct v4l2_subdev_state *state, u32 pad,
> +				     u64 streams_mask)
> +{
> +	struct stm32_csi_dev *csidev = to_csidev(sd);
> +	int ret;
> +
> +	ret = v4l2_subdev_disable_streams(csidev->s_subdev,
> +					  csidev->s_subdev_pad_nb, BIT_ULL(0));
> +	if (ret)
> +		return ret;
> +
> +	/* Stop the VC0 */
> +	ret = stm32_csi_stop_vc(csidev, 0);
> +	if (ret)
> +		dev_err(csidev->dev, "Failed to stop VC0\n");
> +
> +	stm32_csi_stop(csidev);
> +
> +	return 0;
> +}
> +
> +static int stm32_csi_enable_streams(struct v4l2_subdev *sd,
> +				    struct v4l2_subdev_state *state, u32 pad,
> +				    u64 streams_mask)
> +{
> +	struct stm32_csi_dev *csidev = to_csidev(sd);
> +	int ret;
> +
> +	ret = stm32_csi_start(csidev, state);
> +	if (ret)
> +		return ret;
> +
> +	/* Configure & start the VC0 */
> +	ret = stm32_csi_start_vc(csidev, state, 0);
> +	if (ret) {
> +		dev_err(csidev->dev, "Failed to start VC0\n");
> +		stm32_csi_stop(csidev);
> +		return ret;
> +	}
> +
> +	ret = v4l2_subdev_enable_streams(csidev->s_subdev,
> +					 csidev->s_subdev_pad_nb, BIT_ULL(0));
> +	if (ret) {
> +		stm32_csi_stop_vc(csidev, 0);
> +		stm32_csi_stop(csidev);

Maybe a label or a few could be useful here?

> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int stm32_csi_init_state(struct v4l2_subdev *sd,
> +				struct v4l2_subdev_state *state)
> +{
> +	int i;

unsigned int i

> +
> +	for (i = 0; i < sd->entity.num_pads; i++)
> +		*v4l2_subdev_state_get_format(state, i) = fmt_default;
> +
> +	return 0;
> +}
> +
> +static int stm32_csi_enum_mbus_code(struct v4l2_subdev *sd,
> +				    struct v4l2_subdev_state *state,
> +				    struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	if (code->index >= ARRAY_SIZE(stm32_csi_formats))
> +		return -EINVAL;
> +
> +	code->code = stm32_csi_formats[code->index].code;
> +	return 0;
> +}
> +
> +static int stm32_csi_set_pad_format(struct v4l2_subdev *sd,
> +				    struct v4l2_subdev_state *state,
> +				    struct v4l2_subdev_format *format)
> +{
> +	struct stm32_csi_dev *csidev = to_csidev(sd);
> +	struct v4l2_mbus_framefmt *framefmt;
> +	const struct stm32_csi_fmts *fmt;
> +
> +	fmt = stm32_csi_code_to_fmt(format->format.code);
> +	if (!fmt) {
> +		dev_dbg(csidev->dev, "Unsupported code %d, use default\n",
> +			format->format.code);
> +		format->format.code = fmt_default.code;
> +	}
> +
> +	framefmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SINK);
> +
> +	if (format->pad == STM32_CSI_PAD_SOURCE)
> +		format->format = *framefmt;
> +	else
> +		*framefmt = format->format;
> +
> +	framefmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SOURCE);
> +	*framefmt = format->format;
> +
> +	return 0;
> +}
> +
> +static int stm32_csi_log_status(struct v4l2_subdev *sd)
> +{
> +	struct stm32_csi_dev *csidev = to_csidev(sd);
> +	unsigned long flags;
> +	unsigned int i;
> +
> +	spin_lock_irqsave(&csidev->slock, flags);
> +
> +	for (i = 0; i < STM32_CSI_NUM_SR0_EVENTS; i++) {
> +		if (csidev->sr0_counters[i])
> +			dev_info(csidev->dev, "%s events: %d\n",
> +				 stm32_csi_events_sr0[i].name,
> +				 csidev->sr0_counters[i]);
> +	}
> +
> +	for (i = 0; i < STM32_CSI_NUM_SR1_EVENTS; i++) {
> +		if (csidev->sr1_counters[i])
> +			dev_info(csidev->dev, "%s events: %d\n",
> +				 stm32_csi_events_sr1[i].name,
> +				 csidev->sr1_counters[i]);
> +	}
> +
> +	spin_unlock_irqrestore(&csidev->slock, flags);
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_subdev_core_ops stm32_csi_core_ops = {
> +	.log_status = stm32_csi_log_status,
> +};
> +
> +static const struct v4l2_subdev_video_ops stm32_csi_video_ops = {
> +	.s_stream = v4l2_subdev_s_stream_helper,
> +};
> +
> +static const struct v4l2_subdev_pad_ops stm32_csi_pad_ops = {
> +	.enum_mbus_code = stm32_csi_enum_mbus_code,
> +	.set_fmt = stm32_csi_set_pad_format,
> +	.get_fmt = v4l2_subdev_get_fmt,
> +	.enable_streams = stm32_csi_enable_streams,
> +	.disable_streams = stm32_csi_disable_streams,
> +};
> +
> +static const struct v4l2_subdev_ops stm32_csi_subdev_ops = {
> +	.core		= &stm32_csi_core_ops,
> +	.pad		= &stm32_csi_pad_ops,
> +	.video		= &stm32_csi_video_ops,
> +};
> +
> +static const struct v4l2_subdev_internal_ops stm32_csi_subdev_internal_ops = {
> +	.init_state = stm32_csi_init_state,
> +};
> +
> +static int stm32_csi_async_bound(struct v4l2_async_notifier *notifier,
> +				 struct v4l2_subdev *s_subdev,
> +				 struct v4l2_async_connection *asd)
> +{
> +	struct v4l2_subdev *sd = notifier->sd;
> +	struct stm32_csi_dev *csidev = to_csidev(sd);
> +	int remote_pad;
> +
> +	remote_pad = media_entity_get_fwnode_pad(&s_subdev->entity,
> +						 s_subdev->fwnode,
> +						 MEDIA_PAD_FL_SOURCE);
> +	if (remote_pad < 0) {
> +		dev_err(csidev->dev, "Couldn't find output pad for subdev %s\n",
> +			s_subdev->name);
> +		return remote_pad;
> +	}
> +
> +	csidev->s_subdev = s_subdev;
> +	csidev->s_subdev_pad_nb = remote_pad;
> +
> +	return media_create_pad_link(&csidev->s_subdev->entity,
> +				     remote_pad, &csidev->sd.entity,
> +				     STM32_CSI_PAD_SINK,
> +				     MEDIA_LNK_FL_ENABLED |
> +				     MEDIA_LNK_FL_IMMUTABLE);
> +}
> +
> +static const struct v4l2_async_notifier_operations stm32_csi_notifier_ops = {
> +	.bound		= stm32_csi_async_bound,
> +};
> +
> +static irqreturn_t stm32_csi_irq_thread(int irq, void *arg)
> +{
> +	struct stm32_csi_dev *csidev = arg;
> +	unsigned long flags;
> +	u32 sr0, sr1;
> +	int i;
> +
> +	sr0 = readl_relaxed(csidev->base + STM32_CSI_SR0);
> +	sr1 = readl_relaxed(csidev->base + STM32_CSI_SR1);
> +
> +	/* Clear interrupt */
> +	writel_relaxed(sr0 & STM32_CSI_SR0_ERRORS,
> +		       csidev->base + STM32_CSI_FCR0);
> +	writel_relaxed(sr1 & STM32_CSI_SR1_ERRORS,
> +		       csidev->base + STM32_CSI_FCR1);
> +
> +	spin_lock_irqsave(&csidev->slock, flags);
> +
> +	for (i = 0; i < STM32_CSI_NUM_SR0_EVENTS; i++)
> +		if (sr0 & stm32_csi_events_sr0[i].mask)
> +			csidev->sr0_counters[i]++;
> +
> +	for (i = 0; i < STM32_CSI_NUM_SR1_EVENTS; i++)
> +		if (sr1 & stm32_csi_events_sr1[i].mask)
> +			csidev->sr1_counters[i]++;
> +
> +	spin_unlock_irqrestore(&csidev->slock, flags);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int stm32_csi_get_resources(struct stm32_csi_dev *csidev,
> +				   struct platform_device *pdev)
> +{
> +	int irq, ret, i;

unsigned int i

?

> +
> +	csidev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
> +	if (IS_ERR(csidev->base))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(csidev->base),
> +				     "Failed to ioremap resource\n");
> +
> +	for (i = 0; i < STM32_CSI_CLK_NB; i++)
> +		csidev->clks[i].id = stm32_csi_clks_id[i];
> +
> +	ret = devm_clk_bulk_get(&pdev->dev, STM32_CSI_CLK_NB,
> +				csidev->clks);

Fits on the previous line.

> +	if (ret < 0)
> +		return dev_err_probe(&pdev->dev, ret, "Couldn't get clks\n");
> +
> +	csidev->supplies[0].supply = "vdd";
> +	csidev->supplies[1].supply = "vdda18";
> +	ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(csidev->supplies),
> +				      csidev->supplies);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret,
> +				     "Failed to request regulator vdd\n");
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0)
> +		return irq;
> +
> +	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
> +					stm32_csi_irq_thread, IRQF_ONESHOT,
> +					dev_name(&pdev->dev), csidev);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret,
> +				     "Unable to request irq");
> +
> +	return 0;
> +}
> +
> +static int stm32_csi_parse_dt(struct stm32_csi_dev *csidev)
> +{
> +	struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
> +	struct v4l2_async_connection *asd;
> +	struct fwnode_handle *ep;
> +	int ret;
> +
> +	/* Get bus characteristics from devicetree */
> +	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csidev->dev), 0, 0,
> +					     FWNODE_GRAPH_ENDPOINT_NEXT);
> +	if (!ep) {
> +		dev_err(csidev->dev, "Could not find the endpoint\n");
> +		return -ENODEV;
> +	}
> +
> +	ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
> +	fwnode_handle_put(ep);
> +	if (ret) {
> +		dev_err(csidev->dev, "Could not parse v4l2 endpoint\n");
> +		return ret;
> +	}
> +
> +	csidev->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
> +	if (csidev->num_lanes > STM32_CSI_LANES_MAX) {
> +		dev_err(csidev->dev, "Unsupported number of data-lanes: %d\n",
> +			csidev->num_lanes);
> +		return -EINVAL;
> +	}
> +
> +	memcpy(csidev->lanes, v4l2_ep.bus.mipi_csi2.data_lanes,
> +	       sizeof(csidev->lanes));
> +
> +	ep = fwnode_graph_get_next_endpoint(dev_fwnode(csidev->dev), NULL);

How about:

	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csidev->dev), 1, 0,
					     FWNODE_GRAPH_ENDPOINT_NEXT);

> +	if (!ep) {
> +		dev_err(csidev->dev, "Failed to get next endpoint\n");
> +		return -EINVAL;
> +	}
> +
> +	v4l2_async_subdev_nf_init(&csidev->notifier, &csidev->sd);
> +
> +	asd = v4l2_async_nf_add_fwnode_remote(&csidev->notifier, ep,
> +					      struct v4l2_async_connection);
> +
> +	fwnode_handle_put(ep);
> +
> +	if (IS_ERR(asd)) {
> +		dev_err(csidev->dev, "Failed to add fwnode remote subdev\n");
> +		return PTR_ERR(asd);
> +	}
> +
> +	csidev->notifier.ops = &stm32_csi_notifier_ops;
> +
> +	ret = v4l2_async_nf_register(&csidev->notifier);
> +	if (ret) {
> +		dev_err(csidev->dev, "Failed to register notifier\n");
> +		v4l2_async_nf_cleanup(&csidev->notifier);
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +static int stm32_csi_probe(struct platform_device *pdev)
> +{
> +	struct stm32_csi_dev *csidev;
> +	struct reset_control *rstc;
> +	int ret;
> +
> +	csidev = devm_kzalloc(&pdev->dev, sizeof(*csidev), GFP_KERNEL);
> +	if (!csidev)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, csidev);
> +	csidev->dev = &pdev->dev;
> +
> +	spin_lock_init(&csidev->slock);
> +
> +	ret = stm32_csi_get_resources(csidev, pdev);
> +	if (ret)

You could just return the error here. The label naming is misleading, too.
Same below.

> +		goto err_free_priv;
> +
> +	ret = stm32_csi_parse_dt(csidev);
> +	if (ret)
> +		goto err_free_priv;
> +
> +	csidev->sd.owner = THIS_MODULE;
> +	csidev->sd.dev = &pdev->dev;
> +	csidev->sd.internal_ops = &stm32_csi_subdev_internal_ops;
> +	v4l2_subdev_init(&csidev->sd, &stm32_csi_subdev_ops);
> +	v4l2_set_subdevdata(&csidev->sd, &pdev->dev);
> +	snprintf(csidev->sd.name, sizeof(csidev->sd.name), "%s",
> +		 dev_name(&pdev->dev));
> +
> +	/* Create our media pads */
> +	csidev->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
> +	csidev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	csidev->pads[STM32_CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> +	csidev->pads[STM32_CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
> +
> +	ret = media_entity_pads_init(&csidev->sd.entity, STM32_CSI_PAD_MAX,
> +				     csidev->pads);
> +	if (ret)
> +		goto err_cleanup;
> +
> +	ret = v4l2_subdev_init_finalize(&csidev->sd);
> +	if (ret < 0)
> +		goto err_cleanup;
> +
> +	ret = v4l2_async_register_subdev(&csidev->sd);
> +	if (ret < 0)
> +		goto err_cleanup;

You should hold registering the async sub-device until all initialisation
has been done. Otherwise, you may get callbacks that end up accessing
what has not been set up yet (below).

> +
> +	/* Reset device */
> +	rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> +	if (IS_ERR(rstc)) {
> +		ret = dev_err_probe(&pdev->dev, PTR_ERR(rstc),
> +				    "Couldn't get reset control\n");
> +		goto err_cleanup;
> +	}
> +
> +	ret = reset_control_assert(rstc);
> +	if (ret) {
> +		ret = dev_err_probe(&pdev->dev, ret,
> +				    "Failed to assert the reset line\n");
> +		goto err_cleanup;
> +	}
> +
> +	usleep_range(3000, 5000);
> +
> +	ret = reset_control_deassert(rstc);
> +	if (ret) {
> +		ret = dev_err_probe(&pdev->dev, ret,
> +				    "Failed to deassert the reset line\n");
> +		goto err_cleanup;
> +	}
> +
> +	pm_runtime_enable(&pdev->dev);
> +
> +	dev_info(&pdev->dev,
> +		 "Probed CSI with %u lanes\n", csidev->num_lanes);
> +
> +	return 0;
> +
> +err_cleanup:
> +	v4l2_async_nf_cleanup(&csidev->notifier);
> +err_free_priv:
> +	return ret;
> +}
> +
> +static void stm32_csi_remove(struct platform_device *pdev)
> +{
> +	struct stm32_csi_dev *csidev = platform_get_drvdata(pdev);
> +
> +	v4l2_async_unregister_subdev(&csidev->sd);
> +
> +	pm_runtime_disable(&pdev->dev);
> +}
> +
> +static int stm32_csi_runtime_suspend(struct device *dev)
> +{
> +	struct stm32_csi_dev *csidev = dev_get_drvdata(dev);
> +	int ret;
> +
> +	clk_bulk_disable_unprepare(STM32_CSI_CLK_NB, csidev->clks);
> +
> +	ret = regulator_bulk_disable(ARRAY_SIZE(csidev->supplies),
> +				     csidev->supplies);
> +	if (ret < 0)
> +		dev_err(dev, "cannot disable regulators %d\n", ret);
> +
> +	return 0;
> +}
> +
> +static int stm32_csi_runtime_resume(struct device *dev)
> +{
> +	struct stm32_csi_dev *csidev = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ARRAY_SIZE(csidev->supplies),
> +				    csidev->supplies);
> +	if (ret)
> +		goto error_out;
> +
> +	ret = clk_bulk_prepare_enable(STM32_CSI_CLK_NB, csidev->clks);
> +	if (ret)
> +		goto error_disable_supplies;
> +
> +	return 0;
> +
> +error_disable_supplies:
> +	ret = regulator_bulk_disable(ARRAY_SIZE(csidev->supplies), csidev->supplies);

Over 80, please wrap.

> +	if (ret < 0)
> +		dev_err(dev, "cannot disable regulators %d\n", ret);
> +error_out:
> +	dev_err(csidev->dev, "Failed to resume: %d\n", ret);
> +
> +	return ret;
> +}
> +
> +static const struct of_device_id stm32_csi_of_table[] = {
> +	{ .compatible = "st,stm32mp25-csi", },
> +	{ /* end node */ },
> +};
> +MODULE_DEVICE_TABLE(of, stm32_csi_of_table);
> +
> +static const struct dev_pm_ops stm32_csi_pm_ops = {
> +	RUNTIME_PM_OPS(stm32_csi_runtime_suspend,
> +		       stm32_csi_runtime_resume, NULL)
> +};
> +
> +static struct platform_driver stm32_csi_driver = {
> +	.driver	= {
> +		.name = "stm32-csi",
> +		.of_match_table = stm32_csi_of_table,
> +		.pm = pm_ptr(&stm32_csi_pm_ops),
> +	},
> +	.probe	= stm32_csi_probe,
> +	.remove = stm32_csi_remove,
> +};
> +
> +module_platform_driver(stm32_csi_driver);
> +
> +MODULE_AUTHOR("Alain Volmat <alain.volmat at foss.st.com>");
> +MODULE_DESCRIPTION("STM32 CSI controller");
> +MODULE_LICENSE("GPL");
> 

-- 
Kind regards,

Sakari Ailus


From karprzy7 at gmail.com  Sun Dec 15 04:53:55 2024
From: karprzy7 at gmail.com (Karol Przybylski)
Date: Sun, 15 Dec 2024 13:53:55 +0100
Subject: [PATCHv3] drm: zynqmp_dp: Fix integer overflow in zynqmp_dp_rate_get()
Message-ID: <20241215125355.938953-1-karprzy7@gmail.com>

This patch fixes a potential integer overflow in the zynqmp_dp_rate_get()

The issue comes up when the expression
drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000 is evaluated using 32-bit
Now the constant is a compatible 64-bit type.

Resolves coverity issues: CID 1636340 and CID 1635811

Cc: stable at vger.kernel.org
Fixes: 28edaacb821c6 ("drm: zynqmp_dp: Add debugfs interface for compliance testing")
Signed-off-by: Karol Przybylski <karprzy7 at gmail.com>
---
Changes from previous versions:
Added Fixes tag
Added Cc for stable kernel version
Fixed formatting

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

diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 25c5dc61ee88..56a261a40ea3 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -2190,7 +2190,7 @@ static int zynqmp_dp_rate_get(void *data, u64 *val)
 	struct zynqmp_dp *dp = data;
 
 	mutex_lock(&dp->lock);
-	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000;
+	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000ULL;
 	mutex_unlock(&dp->lock);
 	return 0;
 }
-- 
2.34.1



From sakari.ailus at iki.fi  Sun Dec 15 04:55:39 2024
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Sun, 15 Dec 2024 12:55:39 +0000
Subject: [PATCH v4 13/15] media: stm32: dcmipp: add core support for the
 stm32mp25
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-13-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
 <20241212-csi_dcmipp_mp25-v4-13-fbeb55a05ed7@foss.st.com>
Message-ID: <Z17Ry6Z9OMqP1MV-@valkosipuli.retiisi.eu>

Hi Alain,

On Thu, Dec 12, 2024 at 10:17:37AM +0100, Alain Volmat wrote:
> The stm32mp25 supports both parallel & csi inputs.
> An additional clock control is necessary.
> Skeleton of the subdev structures for the stm32mp25 is added,
> identical for the time being to the stm32mp13 however more subdeves
> will be added in further commits.
> 
> Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> ---
> v4:
>   - correct clock handling within dcmipp_runtime_resume
> ---
>  .../platform/st/stm32/stm32-dcmipp/dcmipp-core.c   | 104 +++++++++++++++++----
>  1 file changed, 85 insertions(+), 19 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 62dd17e0488d..71acf539e1f3 100644
> --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
> +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
> @@ -40,6 +40,7 @@ struct dcmipp_device {
>  
>  	/* Hardware resources */
>  	void __iomem			*regs;
> +	struct clk			*mclk;
>  	struct clk			*kclk;
>  
>  	/* The pipeline configuration */
> @@ -132,6 +133,40 @@ static const struct dcmipp_pipeline_config stm32mp13_pipe_cfg = {
>  	.hw_revision	= DCMIPP_STM32MP13_VERR
>  };
>  
> +static const struct dcmipp_ent_config stm32mp25_ent_config[] = {
> +	{
> +		.name = "dcmipp_input",
> +		.init = dcmipp_inp_ent_init,
> +		.release = dcmipp_inp_ent_release,
> +	},
> +	{
> +		.name = "dcmipp_dump_postproc",
> +		.init = dcmipp_byteproc_ent_init,
> +		.release = dcmipp_byteproc_ent_release,
> +	},
> +	{
> +		.name = "dcmipp_dump_capture",
> +		.init = dcmipp_bytecap_ent_init,
> +		.release = dcmipp_bytecap_ent_release,
> +	},
> +};
> +
> +static const struct dcmipp_ent_link stm32mp25_ent_links[] = {
> +	DCMIPP_ENT_LINK(ID_INPUT, 1, ID_DUMP_BYTEPROC, 0,
> +			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
> +	DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE,  0,
> +			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
> +};
> +
> +#define DCMIPP_STM32MP25_VERR  0x30
> +static const struct dcmipp_pipeline_config stm32mp25_pipe_cfg = {
> +	.ents		= stm32mp25_ent_config,
> +	.num_ents	= ARRAY_SIZE(stm32mp25_ent_config),
> +	.links		= stm32mp25_ent_links,
> +	.num_links	= ARRAY_SIZE(stm32mp25_ent_links),
> +	.hw_revision    = DCMIPP_STM32MP25_VERR
> +};
> +
>  #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\
>  			     (f) == MEDIA_LNK_FL_ENABLED ? "ENABLED" :\
>  			     (f) == MEDIA_LNK_FL_IMMUTABLE ? "IMMUTABLE" :\
> @@ -212,6 +247,7 @@ static int dcmipp_create_subdevs(struct dcmipp_device *dcmipp)
>  
>  static const struct of_device_id dcmipp_of_match[] = {
>  	{ .compatible = "st,stm32mp13-dcmipp", .data = &stm32mp13_pipe_cfg },
> +	{ .compatible = "st,stm32mp25-dcmipp", .data = &stm32mp25_pipe_cfg },
>  	{ /* end node */ },
>  };
>  MODULE_DEVICE_TABLE(of, dcmipp_of_match);
> @@ -261,13 +297,22 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
>  {
>  	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
>  	unsigned int ret;
> -	int src_pad;
> +	int src_pad, i;

unsigned int?

>  	struct dcmipp_ent_device *sink;
> -	struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL };
> +	struct v4l2_fwnode_endpoint vep = { 0 };
>  	struct fwnode_handle *ep;
> +	enum v4l2_mbus_type supported_types[] = {
> +		V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, V4L2_MBUS_CSI2_DPHY
> +	};
> +	int supported_types_nb = ARRAY_SIZE(supported_types);
>  
>  	dev_dbg(dcmipp->dev, "Subdev \"%s\" bound\n", subdev->name);
>  
> +	/* Only MP25 supports CSI input */
> +	if (!of_device_is_compatible(dcmipp->dev->of_node,
> +				     "st,stm32mp25-dcmipp"))

This would be much cleaner with match data. You seem to already be using it
for other purposes. 

> +		supported_types_nb--;
> +
>  	/*
>  	 * Link this sub-device to DCMIPP, it could be
>  	 * a parallel camera sensor or a CSI-2 to parallel bridge
> @@ -284,21 +329,23 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
>  		return -ENODEV;
>  	}
>  
> -	/* Check for parallel bus-type first, then bt656 */
> -	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> -	if (ret) {
> -		vep.bus_type = V4L2_MBUS_BT656;
> +	/* Check for supported MBUS type */
> +	for (i = 0; i < supported_types_nb; i++) {
> +		vep.bus_type = supported_types[i];
>  		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> -		if (ret) {
> -			dev_err(dcmipp->dev, "Could not parse the endpoint\n");
> -			fwnode_handle_put(ep);
> -			return ret;
> -		}
> +		if (!ret)
> +			break;
>  	}
>  
>  	fwnode_handle_put(ep);
>  
> -	if (vep.bus.parallel.bus_width == 0) {
> +	if (ret) {
> +		dev_err(dcmipp->dev, "Could not parse the endpoint\n");
> +		return ret;
> +	}
> +
> +	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY &&
> +	    vep.bus.parallel.bus_width == 0) {
>  		dev_err(dcmipp->dev, "Invalid parallel interface bus-width\n");
>  		return -ENODEV;
>  	}
> @@ -311,11 +358,13 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
>  		return -ENODEV;
>  	}
>  
> -	/* Parallel input device detected, connect it to parallel subdev */
> +	/* Connect input device to the dcmipp_input subdev */
>  	sink = dcmipp->entity[ID_INPUT];
> -	sink->bus.flags = vep.bus.parallel.flags;
> -	sink->bus.bus_width = vep.bus.parallel.bus_width;
> -	sink->bus.data_shift = vep.bus.parallel.data_shift;
> +	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) {
> +		sink->bus.flags = vep.bus.parallel.flags;
> +		sink->bus.bus_width = vep.bus.parallel.bus_width;
> +		sink->bus.data_shift = vep.bus.parallel.data_shift;
> +	}
>  	sink->bus_type = vep.bus_type;
>  	ret = media_create_pad_link(&subdev->entity, src_pad, sink->ent, 0,
>  				    MEDIA_LNK_FL_IMMUTABLE |
> @@ -414,7 +463,7 @@ static int dcmipp_graph_init(struct dcmipp_device *dcmipp)
>  static int dcmipp_probe(struct platform_device *pdev)
>  {
>  	struct dcmipp_device *dcmipp;
> -	struct clk *kclk;
> +	struct clk *kclk, *mclk;
>  	const struct dcmipp_pipeline_config *pipe_cfg;
>  	struct reset_control *rstc;
>  	int irq;
> @@ -474,12 +523,20 @@ static int dcmipp_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> -	kclk = devm_clk_get(&pdev->dev, NULL);
> +	kclk = devm_clk_get(&pdev->dev, "kclk");
>  	if (IS_ERR(kclk))
>  		return dev_err_probe(&pdev->dev, PTR_ERR(kclk),
>  				     "Unable to get kclk\n");
>  	dcmipp->kclk = kclk;
>  
> +	if (!of_device_is_compatible(pdev->dev.of_node, "st,stm32mp13-dcmipp")) {

Same here.

> +		mclk = devm_clk_get(&pdev->dev, "mclk");
> +		if (IS_ERR(mclk))
> +			return dev_err_probe(&pdev->dev, PTR_ERR(mclk),
> +					     "Unable to get mclk\n");
> +		dcmipp->mclk = mclk;
> +	}
> +
>  	dcmipp->entity = devm_kcalloc(&pdev->dev, dcmipp->pipe_cfg->num_ents,
>  				      sizeof(*dcmipp->entity), GFP_KERNEL);
>  	if (!dcmipp->entity)
> @@ -542,6 +599,7 @@ static int dcmipp_runtime_suspend(struct device *dev)
>  	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
>  
>  	clk_disable_unprepare(dcmipp->kclk);
> +	clk_disable_unprepare(dcmipp->mclk);
>  
>  	return 0;
>  }
> @@ -551,9 +609,17 @@ static int dcmipp_runtime_resume(struct device *dev)
>  	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
>  	int ret;
>  
> +	ret = clk_prepare_enable(dcmipp->mclk);
> +	if (ret) {
> +		dev_err(dev, "%s: Failed to prepare_enable mclk\n", __func__);
> +		return ret;
> +	}
> +
>  	ret = clk_prepare_enable(dcmipp->kclk);
> -	if (ret)
> +	if (ret) {
> +		clk_disable_unprepare(dcmipp->mclk);
>  		dev_err(dev, "%s: Failed to prepare_enable kclk\n", __func__);
> +	}
>  
>  	return ret;
>  }
> 
> 

-- 
Kind regards,

Sakari Ailus


From laurent.pinchart at ideasonboard.com  Sun Dec 15 05:12:58 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sun, 15 Dec 2024 15:12:58 +0200
Subject: [PATCHv3] drm: zynqmp_dp: Fix integer overflow in
 zynqmp_dp_rate_get()
In-Reply-To: <20241215125355.938953-1-karprzy7@gmail.com>
References: <20241215125355.938953-1-karprzy7@gmail.com>
Message-ID: <20241215131258.GC25852@pendragon.ideasonboard.com>

Ho Karol,

Thank you for the patch.

On Sun, Dec 15, 2024 at 01:53:55PM +0100, Karol Przybylski wrote:
> This patch fixes a potential integer overflow in the zynqmp_dp_rate_get()
> 
> The issue comes up when the expression
> drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000 is evaluated using 32-bit
> Now the constant is a compatible 64-bit type.
> 
> Resolves coverity issues: CID 1636340 and CID 1635811
> 
> Cc: stable at vger.kernel.org
> Fixes: 28edaacb821c6 ("drm: zynqmp_dp: Add debugfs interface for compliance testing")
> Signed-off-by: Karol Przybylski <karprzy7 at gmail.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
> Changes from previous versions:
> Added Fixes tag
> Added Cc for stable kernel version
> Fixed formatting
> 
>  drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index 25c5dc61ee88..56a261a40ea3 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -2190,7 +2190,7 @@ static int zynqmp_dp_rate_get(void *data, u64 *val)
>  	struct zynqmp_dp *dp = data;
>  
>  	mutex_lock(&dp->lock);
> -	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000;
> +	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000ULL;
>  	mutex_unlock(&dp->lock);
>  	return 0;
>  }

-- 
Regards,

Laurent Pinchart


From andre.przywara at arm.com  Sun Dec 15 05:39:50 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun, 15 Dec 2024 13:39:50 +0000
Subject: [PATCH 0/3] arm64: allwinner: a64: fix video output on Pinebook
In-Reply-To: <20241215053639.738890-1-anarsoul@gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
Message-ID: <20241215133950.27e5877a@minigeek.lan>

On Sat, 14 Dec 2024 21:34:56 -0800
Vasily Khoruzhick <anarsoul at gmail.com> wrote:

Hi Vasily,

thanks for tracking this issue down and sending the fixes!

> Since commit ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux"),
> TCON0 clock parent is always set to PLL_MIPI, but unfortunately it breaks
> video output on Pinebook.
> 
> I did an experiment: I manually configured PLL_MIPI and PLL_VIDEO0_2X
> to the same clock rate and flipped the switch with devmem. Experiment clearly
> showed that whenever PLL_MIPI is selected as TCON0 clock parent, the video
> output stops working.

That is good info, together with what Roman reported in that patch
mentioned above it seems to confirm that the parent clock selection
also determines the output path of TCON0.
Since there does not seem to be another register or switch setting
the path (ignoring the pinmux), I think a DT solution is appropriate
here, and assigned-clock-parents is the right way to go.

So the patch series looks good to me in general, but we thought that of
Roman's series as well, so I would really like to see a Tested-by: from
a Pinephone user and ideally a confirmation from Roman that this still
works for him.

Also I second Dragan's comments about copying the rationale into at
least the commit messages (if not in comments). Having explanations
in the cover letter is good, but having it in the git repo is much
better - as the cover letter will only be in the email archives.

Cheers,
Andre
 
> 
> To fix the issue, I partially reverted mentioned commit and added explicit
> TCON0 clock parent assignment to device tree. By default, it will be
> PLL_MIPI, and the only users with RGB output - Pinebook and Teres-I will
> override it in their dts.
> 
> Vasily Khoruzhick (3):
>   dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
>   arm64: dts: allwinner: a64: explicitly assign clock parent for TCON0
>   clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent
> 
>  arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts |  2 ++
>  arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts  |  2 ++
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi         |  2 ++
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c                 | 11 -----------
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.h                 |  2 --
>  include/dt-bindings/clock/sun50i-a64-ccu.h            |  2 ++
>  6 files changed, 8 insertions(+), 13 deletions(-)
> 



From igor.belwon at mentallysanemainliners.org  Sun Dec 15 08:33:21 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Sun, 15 Dec 2024 17:33:21 +0100
Subject: [PATCH v1 0/1] arm64: dts: exynos990: Add m5-pmu
In-Reply-To: <20241214115855.49138-1-umer.uddin@mentallysanemainliners.org>
Message-ID: <D6CF3DHQWEPR.3J1JM27L0JUKO@mentallysanemainliners.org>

Hi Umer,

Tested-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>

M5 PMU got succesfully enabled on c1s.

Best regards,
Igor


From sashal at kernel.org  Sun Dec 15 09:06:19 2024
From: sashal at kernel.org (Sasha Levin)
Date: Sun, 15 Dec 2024 12:06:19 -0500
Subject: [GIT PULL] arm64 fixes for 6.13-rc3
In-Reply-To: <Z1xx0ha7lbKkdhRC@arm.com>
References: <Z1xx0ha7lbKkdhRC@arm.com>
Message-ID: <Z18MixiGByAqDYLC@lappy>

On Fri, Dec 13, 2024 at 05:41:38PM +0000, Catalin Marinas wrote:
>- arm64 stacktrace: address some fallout from the recent changes to
>  unwinding across exception boundaries

Hi Catalin, Mark,

It seems that kselftests can hit a warning that was addressed in the
commit above:

<12>[   74.172204] kselftest: Running tests in ftrace
TAP version 13
1..1
# timeout set to 0
# selftests: ftrace: ftracetest-ktap
# unlink: cannot unlink '/opt/kselftests/default-in-kernel/ftrace/logs/latest': No such file or directory
# TAP version 13
# 1..145
# ok 1 Basic trace file check
<4>[  108.427656] hrtimer: interrupt took 13044036 ns
<4>[  161.249175] sched: DL replenish lagged too much
<4>[  163.845977] ------------[ cut here ]------------
<4>[  163.851787] WARNING: CPU: 1 PID: 31 at arch/arm64/kernel/stacktrace.c:141 arch_stack_walk+0x4a0/0x4b0
<4>[  163.861012] Modules linked in: crct10dif_ce sm3_ce sm3 sha3_ce sha512_ce sha512_arm64 fuse drm backlight ip_tables x_tables
<4>[  163.890268] CPU: 1 UID: 0 PID: 31 Comm: kworker/1:1 Not tainted 6.13.0-rc2 #1
<4>[  163.897386] Hardware name: linux,dummy-virt (DT)
<4>[  163.904217] Workqueue:  0x0 (mm_percpu_wq)
<4>[  163.915526] pstate: 624020c9 (nZCv daIF +PAN -UAO +TCO -DIT -SSBS BTYPE=--)
<4>[  163.924218] pc : arch_stack_walk+0x4a0/0x4b0
<4>[  163.930593] lr : arch_stack_walk+0x2bc/0x4b0
<4>[  163.937101] sp : ffff80008000b920
<4>[  163.942456] x29: ffff80008000b9d0 x28: fff00000ff6d9400 x27: fff00000ff6d9928
<4>[  163.954275] x26: 0000000000000001 x25: 00000000000000c0 x24: ffffae003d389d40
<4>[  163.967208] x23: 09cfae003ae216b4 x22: ffffae003ae2e4b0 x21: ffffae003ae35c70
<4>[  163.978823] x20: ffff80008000ba10 x19: ffffae003ae216f0 x18: 0000000000000014
<4>[  163.989751] x17: 0000000000000000 x16: ffff800080008000 x15: 00000000b5b23a12
<4>[  164.000780] x14: 000000005865dcaf x13: 00000000b77eca6d x12: 0000959eae5a34e8
<4>[  164.011592] x11: ffffae003d44a670 x10: ffff80008000b920 x9 : ffffae003ae2e4b0
<4>[  164.022498] x8 : ffff800080043e00 x7 : fff00000c682c000 x6 : 00000000ffffffff
<4>[  164.033396] x5 : fff00000c682c000 x4 : 0000000000000000 x3 : ffff80008000bda0
<4>[  164.045100] x2 : ffffae003ae2e4b0 x1 : ffffae003ae2e4b0 x0 : ffffae003ae2e4b0
<4>[  164.057084] Call trace:
<4>[  164.061489]  arch_stack_walk+0x4a0/0x4b0 (P)
<4>[  164.067225]  arch_stack_walk+0x2bc/0x4b0 (L)
<4>[  164.073009]  profile_pc+0x44/0x80
<4>[  164.078489]  profile_tick+0x50/0x80 (F)
<4>[  164.085151]  tick_nohz_handler+0xcc/0x160 (F)
<4>[  164.091427]  __hrtimer_run_queues+0x2c4/0x358 (F)
<4>[  164.098138]  hrtimer_interrupt+0xf4/0x268 (F)
<4>[  164.105401]  arch_timer_handler_phys+0x34/0x58 (F)
<4>[  164.114958]  handle_percpu_devid_irq+0x8c/0x218 (F)
<4>[  164.120914]  generic_handle_domain_irq+0x34/0x58 (F)
<4>[  164.127570]  gic_handle_irq+0x54/0x128 (F)
<4>[  164.135008]  do_interrupt_handler+0x58/0x98 (F)
<4>[  164.140769]  el1_interrupt+0x34/0x68 (F)
<4>[  164.146665]  el1h_64_irq_handler+0x18/0x28
<4>[  164.151813]  el1h_64_irq+0x6c/0x70
<4>[  164.160007]  _raw_spin_unlock_irq+0x28/0x58 (PF)
<4>[  164.176292] ------------[ cut here ]------------
<4>[  164.187816] WARNING: CPU: 1 PID: 31 at arch/arm64/kernel/stacktrace.c:141 dump_backtrace+0x620/0x660
<4>[  164.209007] Modules linked in: crct10dif_ce sm3_ce sm3 sha3_ce sha512_ce sha512_arm64 fuse drm backlight ip_tables x_tables
<4>[  164.252638] CPU: 1 UID: 0 PID: 31 Comm: kworker/1:1 Not tainted 6.13.0-rc2 #1
<4>[  164.260491] Hardware name: linux,dummy-virt (DT)
<4>[  164.266531] Workqueue:  0x0 (mm_percpu_wq)
<4>[  164.275972] pstate: 624023c9 (nZCv DAIF +PAN -UAO +TCO -DIT -SSBS BTYPE=--)
<4>[  164.282685] pc : dump_backtrace+0x620/0x660
<4>[  164.288093] lr : dump_backtrace+0x410/0x660
<4>[  164.293392] sp : ffff80008000b510
<4>[  164.297983] x29: ffff80008000b5c0 x28: fff00000c08c91c0 x27: fff00000ff6d9928
<4>[  164.309075] x26: ffff80008000bda0 x25: ffffae003cd0c000 x24: ffffae003cedfaa0
<4>[  164.320534] x23: ffffae003cce90b8 x22: ffffae003ae35c70 x21: ffffae003ccd80a8
<4>[  164.331352] x20: ffffae003cd1fd38 x19: fff00000c08c91c0 x18: 0000000000000006
<4>[  164.343050] x17: 0000000000000000 x16: ffff800080008000 x15: ffff80008000af40
<4>[  164.354100] x14: ffff80010000b0fa x13: ffff80008000b102 x12: ffffae003d410098
<4>[  164.366177] x11: ffffae003d44a670 x10: ffff80008000b350 x9 : ffffae003ae2e4b0
<4>[  164.378146] x8 : ffff800080043e00 x7 : fff00000c682c000 x6 : 00000000ffffffff
<4>[  164.389041] x5 : fff00000c682c000 x4 : 0000000000000000 x3 : ffff80008000bda0
<4>[  164.400262] x2 : ffffae003ae2e4b0 x1 : ffffae003ae2e4b0 x0 : ffffae003ae2e4b0
<4>[  164.411526] Call trace:
<4>[  164.415800]  dump_backtrace+0x620/0x660 (P)
<4>[  164.421415]  dump_backtrace+0x410/0x660 (L)
<4>[  164.427393]  show_regs+0x34/0x50 (F)
<4>[  164.434342]  __warn+0x98/0x198 (F)
<4>[  164.439610]  report_bug+0x1dc/0x200 (F)
<4>[  164.444981]  bug_handler+0x2c/0x90
<4>[  164.450151]  call_break_hook+0x6c/0x88 (F)
<4>[  164.455802]  brk_handler+0x24/0x70 (F)
<4>[  164.460935]  do_debug_exception+0x74/0x118 (F)
<4>[  164.466742]  el1_dbg+0x70/0x90 (F)
<4>[  164.471595]  el1h_64_sync_handler+0xd4/0x120
<4>[  164.477225]  el1h_64_sync+0x6c/0x70
<4>[  164.482730]  arch_stack_walk+0x4a0/0x4b0 (P)
<4>[  164.488313]  arch_stack_walk+0x2bc/0x4b0 (L)
<4>[  164.494329]  profile_pc+0x44/0x80
<4>[  164.499430]  profile_tick+0x50/0x80 (F)
<4>[  164.504776]  tick_nohz_handler+0xcc/0x160 (F)
<4>[  164.511508]  __hrtimer_run_queues+0x2c4/0x358 (F)
<4>[  164.519213]  hrtimer_interrupt+0xf4/0x268 (F)
<4>[  164.525536]  arch_timer_handler_phys+0x34/0x58 (F)
<4>[  164.531384]  handle_percpu_devid_irq+0x8c/0x218 (F)
<4>[  164.537153]  generic_handle_domain_irq+0x34/0x58 (F)
<4>[  164.543448]  gic_handle_irq+0x54/0x128 (F)
<4>[  164.548744]  do_interrupt_handler+0x58/0x98 (F)
<4>[  164.555359]  el1_interrupt+0x34/0x68 (F)
<4>[  164.561123]  el1h_64_irq_handler+0x18/0x28
<4>[  164.567261]  el1h_64_irq+0x6c/0x70
<4>[  164.573197]  _raw_spin_unlock_irq+0x28/0x58 (PF)
<4>[  164.580018] ---[ end trace 0000000000000000 ]---
<4>[  164.585812] ---[ end trace 0000000000000000 ]---

-- 
Thanks,
Sasha


From igor.belwon at mentallysanemainliners.org  Sun Dec 15 09:08:02 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Sun, 15 Dec 2024 18:08:02 +0100
Subject: [PATCH v2 0/1] arm64: dts: exynos990: Add cmu nodes
Message-ID: <20241215170803.1756850-1-igor.belwon@mentallysanemainliners.org>

Hi all,

This patchset adds device tree nodes for Exynos990 CMUs (TOP and HSI0).

This allows the first two implemented CMU blocks to be used.

Changes since v1:
- Fix clock-names formatting (Thanks, Krzysztof!)
- Remove stray blank line (Thanks, Krzysztof!)
- Make clock-names conform with the binding style

Best regards,
Igor

Igor Belwon (1):
  arm64: dts: exynos990: Add clock management unit nodes

 arch/arm64/boot/dts/exynos/exynos990.dtsi | 28 +++++++++++++++++++++++
 1 file changed, 28 insertions(+)

-- 
2.45.2



From igor.belwon at mentallysanemainliners.org  Sun Dec 15 09:08:03 2024
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Sun, 15 Dec 2024 18:08:03 +0100
Subject: [PATCH v2 1/1] arm64: dts: exynos990: Add clock management unit nodes
In-Reply-To: <20241215170803.1756850-1-igor.belwon@mentallysanemainliners.org>
References: <20241215170803.1756850-1-igor.belwon@mentallysanemainliners.org>
Message-ID: <20241215170803.1756850-2-igor.belwon@mentallysanemainliners.org>

Add CMU nodes for:
- cmu_top: provides clocks for other blocks
- cmu_hsi0: provides clocks for usb31

Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
---
 arch/arm64/boot/dts/exynos/exynos990.dtsi | 28 +++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos990.dtsi b/arch/arm64/boot/dts/exynos/exynos990.dtsi
index 2619f821bc7c..d6a8c04e6602 100644
--- a/arch/arm64/boot/dts/exynos/exynos990.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos990.dtsi
@@ -5,6 +5,7 @@
  * Copyright (c) 2024, Igor Belwon <igor.belwon at mentallysanemainliners.org>
  */
 
+#include <dt-bindings/clock/samsung,exynos990.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
@@ -199,6 +200,24 @@ pinctrl_peric1: pinctrl at 10730000 {
 			interrupts = <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		cmu_hsi0: clock-controller at 10a00000 {
+			compatible = "samsung,exynos990-cmu-hsi0";
+			reg = <0x10a00000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>,
+				 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
+				 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
+				 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
+				 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
+			clock-names = "oscclk",
+				      "bus",
+				      "usb31drd",
+				      "usbdp_debug",
+				      "dpgtc";
+
+		};
+
 		pinctrl_hsi1: pinctrl at 13040000 {
 			compatible = "samsung,exynos990-pinctrl";
 			reg = <0x13040000 0x1000>;
@@ -245,6 +264,15 @@ pinctrl_cmgp: pinctrl at 15c30000 {
 			compatible = "samsung,exynos990-pinctrl";
 			reg = <0x15c30000 0x1000>;
 		};
+
+		cmu_top: clock-controller at 1a330000 {
+			compatible = "samsung,exynos990-cmu-top";
+			reg = <0x1a330000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>;
+			clock-names = "oscclk";
+		};
 	};
 
 	timer {
-- 
2.45.2



From lorenzo at kernel.org  Sun Dec 15 09:36:35 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Sun, 15 Dec 2024 18:36:35 +0100
Subject: [PATCH net-next] net: airoha: Fix error patch in airoha_probe()
Message-ID: <20241215-airoha_probe-error-path-fix-v1-1-dd299122d343@kernel.org>

Do not run napi_disable if airoha_hw_init() fails since Tx/Rx napi
has not been started yet. In order to fix the issue, introduce
airoha_qdma_disable_napi routine and remove napi_disable in
airoha_hw_cleanup().

Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 drivers/net/ethernet/mediatek/airoha_eth.c | 33 ++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 6c683a12d5aa52dd9d966df123509075a989c0b3..5bbf5fee2802135ff6083233d0bda78f2ba5606a 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -2138,17 +2138,14 @@ static void airoha_hw_cleanup(struct airoha_qdma *qdma)
 		if (!qdma->q_rx[i].ndesc)
 			continue;
 
-		napi_disable(&qdma->q_rx[i].napi);
 		netif_napi_del(&qdma->q_rx[i].napi);
 		airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
 		if (qdma->q_rx[i].page_pool)
 			page_pool_destroy(qdma->q_rx[i].page_pool);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
-		napi_disable(&qdma->q_tx_irq[i].napi);
+	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
 		netif_napi_del(&qdma->q_tx_irq[i].napi);
-	}
 
 	for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
 		if (!qdma->q_tx[i].ndesc)
@@ -2173,6 +2170,21 @@ static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
 	}
 }
 
+static void airoha_qdma_disable_napi(struct airoha_qdma *qdma)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
+		napi_disable(&qdma->q_tx_irq[i].napi);
+
+	for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+		if (!qdma->q_rx[i].ndesc)
+			continue;
+
+		napi_disable(&qdma->q_rx[i].napi);
+	}
+}
+
 static void airoha_update_hw_stats(struct airoha_gdm_port *port)
 {
 	struct airoha_eth *eth = port->qdma->eth;
@@ -2738,7 +2750,7 @@ static int airoha_probe(struct platform_device *pdev)
 
 	err = airoha_hw_init(pdev, eth);
 	if (err)
-		goto error;
+		goto error_hw_cleanup;
 
 	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
 		airoha_qdma_start_napi(&eth->qdma[i]);
@@ -2753,13 +2765,16 @@ static int airoha_probe(struct platform_device *pdev)
 		err = airoha_alloc_gdm_port(eth, np);
 		if (err) {
 			of_node_put(np);
-			goto error;
+			goto error_napi_disable;
 		}
 	}
 
 	return 0;
 
-error:
+error_napi_disable:
+	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+		airoha_qdma_disable_napi(&eth->qdma[i]);
+error_hw_cleanup:
 	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
 		airoha_hw_cleanup(&eth->qdma[i]);
 
@@ -2780,8 +2795,10 @@ static void airoha_remove(struct platform_device *pdev)
 	struct airoha_eth *eth = platform_get_drvdata(pdev);
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
+		airoha_qdma_disable_napi(&eth->qdma[i]);
 		airoha_hw_cleanup(&eth->qdma[i]);
+	}
 
 	for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
 		struct airoha_gdm_port *port = eth->ports[i];

---
base-commit: 2c2b61d2138f472e50b5531ec0cb4a1485837e21
change-id: 20241215-airoha_probe-error-path-fix-5bc6bed0e20e

Best regards,
-- 
Lorenzo Bianconi <lorenzo at kernel.org>



From smostafa at google.com  Sun Dec 15 12:04:11 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Sun, 15 Dec 2024 20:04:11 +0000
Subject: [PATCH] iommu/io-pgtable-arm: Fix cfg reading in arm_lpae_concat_mandatory()
Message-ID: <20241215200412.561400-1-smostafa@google.com>

I messed up the newly introduced function arm_lpae_concat_mandatory()
where ias/oas are read from the io_pgtable_cfg copy in arm_lpae_io_pgtable.

However, this copy is set later in alloc_io_pgtable_ops() after alloc()
function was called.

I didn?t catch that with my selftesting as arm_lpae_io_pgtable is
allocated from kmalloc, which was caching old configs.

While at it, fix a couple of spaces.

Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
 drivers/iommu/io-pgtable-arm.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index c1b62c7d81ba..7e53ee51270b 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -232,12 +232,13 @@ static inline int arm_lpae_max_entries(int i, struct arm_lpae_io_pgtable *data)
  *   c) 42 bits PA size with 4K: use level 1 instead of level 0 (8 tables for ias = oas)
  *   d) 48 bits PA size with 16K: use level 1 instead of level 0 (2 tables for ias = oas)
  */
-static inline bool arm_lpae_concat_mandatory(struct arm_lpae_io_pgtable *data)
+static inline bool arm_lpae_concat_mandatory(struct io_pgtable_cfg *cfg,
+					     struct arm_lpae_io_pgtable *data)
 {
-	unsigned int ias = data->iop.cfg.ias;
-	unsigned int oas = data->iop.cfg.oas;
+	unsigned int ias = cfg->ias;
+	unsigned int oas = cfg->oas;
 
-	/* Covers 1  and 2.d */
+	/* Covers 1 and 2.d */
 	if ((ARM_LPAE_GRANULE(data) == SZ_16K) && (data->start_level == 0))
 		return (oas == 48) || (ias == 48);
 
@@ -1033,7 +1034,7 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 	if (!data)
 		return NULL;
 
-	if (arm_lpae_concat_mandatory(data))  {
+	if (arm_lpae_concat_mandatory(cfg, data)) {
 		if (WARN_ON((ARM_LPAE_PGD_SIZE(data) / sizeof(arm_lpae_iopte)) >
 			    ARM_LPAE_S2_MAX_CONCAT_PAGES))
 			return NULL;
-- 
2.47.1.613.gc27f4b7a9f-goog



From john.madieu.xa at bp.renesas.com  Sun Dec 15 12:33:44 2024
From: john.madieu.xa at bp.renesas.com (John Madieu)
Date: Sun, 15 Dec 2024 21:33:44 +0100
Subject: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible
In-Reply-To: <20241211-syscon-fixes-v1-3-b5ac8c219e96@kernel.org>
References: <20241211-syscon-fixes-v1-3-b5ac8c219e96@kernel.org>
Message-ID: <20241215203344.46158-1-john.madieu.xa@bp.renesas.com>

Hi Rob,

On Wed, 11 Dec 2024 14:57:14 -0600 Rob Herring wrote:
> diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> index bfb1f69fcff1..e6df2825c14d 100644
> --- a/drivers/mfd/syscon.c
> +++ b/drivers/mfd/syscon.c
> @@ -171,8 +171,10 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
> 			break;
> 		}
> 
> -	if (!syscon)
> +	if (!syscon && of_device_is_compatible(np, "syscon"))
> 		syscon = of_syscon_register(np, check_res);
> +	else
> +		syscon = ERR_PTR(-EINVAL);

The current modification will make device_node_get_regmap() return -EINVAL even 
for syscons that were already found in the syscon_list, which I believe is not 
the intended behavior.

I suggest modifying it this way to maintain lookup functionality for registered 
syscons while implementing your intended changes:

static struct regmap *device_node_get_regmap(struct device_node *np,
					     bool check_res)
{
	struct syscon *entry, *syscon = NULL;
	struct regmap *regmap;

	mutex_lock(&syscon_list_lock);

	list_for_each_entry(entry, &syscon_list, list)
		if (entry->np == np) {
			syscon = entry;
			break;
		}

	if (syscon) {
		regmap = syscon->regmap;
		mutex_unlock(&syscon_list_lock);
		return regmap;
	}

	if (of_device_is_compatible(np, "syscon")) {
		syscon = of_syscon_register(np, check_res);
		mutex_unlock(&syscon_list_lock);
		if (IS_ERR(syscon))
			return ERR_CAST(syscon);
		return syscon->regmap;
	}

	mutex_unlock(&syscon_list_lock);
	return ERR_PTR(-EINVAL);
}

The above is the resulting working function I've obtained while testing with
different scenarios. This ensures that:

 1. Already registered syscons are found and returned correctly
 2. New syscons with "syscon" compatible are registered as before
 3. Nodes without "syscon" compatible return -EINVAL only if not found in the list

This has been tested with my v1 syscon work [1] and with v2, where I remove the
"syscon" compatible string for custom regmap initialization, aligning with your
goals for this series.

Let me know if I should add this series as a dependency of my v2 or how I should proceed.

Thanks,

John Madieu

[1] https://lore.kernel.org/all/20241206212559.192705-2-john.madieu.xa at bp.renesas.com



From zmw12306 at gmail.com  Sun Dec 15 12:40:14 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Sun, 15 Dec 2024 15:40:14 -0500
Subject: [PATCH v5] pinctrl: stm32: Add check for clk_enable()
Message-ID: <20241215204014.4076659-1-zmw12306@gmail.com>

Convert the driver to clk_bulk*() API.
Add check for the return value of clk_bulk_enable() to catch
the potential error.

Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
Changelog:

v4 -> v5:
1. Move the clock handling from stm32_gpiolib_register_bank() 
and moving it to its caller.
2. Call clk_bulk_prepare_enable() in stm32_pctl_probe() 
and clk_bulk_disable_unprepare() for error.

v3 -> v4:
1. Add initialization for  pctl->clks.
2. Adjust alignment.

v2 -> v3:

1. Convert clk_disable_unprepare to clk_bulk_disable
and clk_bulk_unprepare.

v1 -> v2:

1. Move int ret declaration into if block.
---
 drivers/pinctrl/stm32/pinctrl-stm32.c | 70 ++++++++++++---------------
 1 file changed, 32 insertions(+), 38 deletions(-)

diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index 5b7fa77c1184..5874a054dc48 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -86,7 +86,6 @@ struct stm32_pinctrl_group {
 
 struct stm32_gpio_bank {
 	void __iomem *base;
-	struct clk *clk;
 	struct reset_control *rstc;
 	spinlock_t lock;
 	struct gpio_chip gpio_chip;
@@ -108,6 +107,7 @@ struct stm32_pinctrl {
 	unsigned ngroups;
 	const char **grp_names;
 	struct stm32_gpio_bank *banks;
+	struct clk_bulk_data *clks;
 	unsigned nbanks;
 	const struct stm32_pinctrl_match_data *match_data;
 	struct irq_domain	*domain;
@@ -1308,12 +1308,6 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	if (IS_ERR(bank->base))
 		return PTR_ERR(bank->base);
 
-	err = clk_prepare_enable(bank->clk);
-	if (err) {
-		dev_err(dev, "failed to prepare_enable clk (%d)\n", err);
-		return err;
-	}
-
 	bank->gpio_chip = stm32_gpio_template;
 
 	fwnode_property_read_string(fwnode, "st,bank-name", &bank->gpio_chip.label);
@@ -1360,26 +1354,21 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 							   bank->fwnode, &stm32_gpio_domain_ops,
 							   bank);
 
-		if (!bank->domain) {
-			err = -ENODEV;
-			goto err_clk;
-		}
+		if (!bank->domain)
+			return -ENODEV;
 	}
 
 	names = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL);
-	if (!names) {
-		err = -ENOMEM;
-		goto err_clk;
-	}
+	if (!names)
+		return -ENOMEM;
 
 	for (i = 0; i < npins; i++) {
 		stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i);
 		if (stm32_pin && stm32_pin->pin.name) {
 			names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name);
-			if (!names[i]) {
-				err = -ENOMEM;
-				goto err_clk;
-			}
+			if (!names[i])
+				return -ENOMEM;
+
 		} else {
 			names[i] = NULL;
 		}
@@ -1390,15 +1379,11 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	err = gpiochip_add_data(&bank->gpio_chip, bank);
 	if (err) {
 		dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_nr);
-		goto err_clk;
+		return err;
 	}
 
 	dev_info(dev, "%s bank added\n", bank->gpio_chip.label);
 	return 0;
-
-err_clk:
-	clk_disable_unprepare(bank->clk);
-	return err;
 }
 
 static struct irq_domain *stm32_pctrl_get_irq_domain(struct platform_device *pdev)
@@ -1617,10 +1602,18 @@ int stm32_pctl_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 	pctl->banks = devm_kcalloc(dev, banks, sizeof(*pctl->banks),
-			GFP_KERNEL);
+				   GFP_KERNEL);
 	if (!pctl->banks)
 		return -ENOMEM;
 
+	pctl->clks = devm_kcalloc(dev, banks, sizeof(*pctl->clks),
+				  GFP_KERNEL);
+	if (!pctl->clks)
+		return -ENOMEM;
+
+	for (i = 0; i < banks; ++i)
+		pctl->clks[i].id = "";
+
 	i = 0;
 	for_each_gpiochip_node(dev, child) {
 		struct stm32_gpio_bank *bank = &pctl->banks[i];
@@ -1631,11 +1624,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
 			fwnode_handle_put(child);
 			return -EPROBE_DEFER;
 		}
-
-		bank->clk = of_clk_get_by_name(np, NULL);
-		if (IS_ERR(bank->clk)) {
+		pctl->clks[i].clk = of_clk_get_by_name(np, NULL);
+		if (IS_ERR(pctl->clks[i].clk)) {
 			fwnode_handle_put(child);
-			return dev_err_probe(dev, PTR_ERR(bank->clk),
+			return dev_err_probe(dev, PTR_ERR(pctl->clks[i].clk),
 					     "failed to get clk\n");
 		}
 		i++;
@@ -1646,15 +1638,18 @@ int stm32_pctl_probe(struct platform_device *pdev)
 		if (ret) {
 			fwnode_handle_put(child);
 
-			for (i = 0; i < pctl->nbanks; i++)
-				clk_disable_unprepare(pctl->banks[i].clk);
-
 			return ret;
 		}
 
 		pctl->nbanks++;
 	}
 
+	ret = clk_bulk_prepare_enable(pctl->nbanks, pctl->clks);
+	if (ret) {
+		dev_err(dev, "failed to prepare_enable clk (%d)\n", ret);
+		return ret;
+	}
+
 	dev_info(dev, "Pinctrl STM32 initialized\n");
 
 	return 0;
@@ -1726,10 +1721,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
 int __maybe_unused stm32_pinctrl_suspend(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
-	int i;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_disable(pctl->banks[i].clk);
+	clk_bulk_disable(pctl->nbanks, pctl->clks);
 
 	return 0;
 }
@@ -1738,10 +1731,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
 	struct stm32_pinctrl_group *g = pctl->groups;
-	int i;
+	int i, ret;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_enable(pctl->banks[i].clk);
+	ret = clk_bulk_enable(pctl->nbanks, pctl->clks);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < pctl->ngroups; i++, g++)
 		stm32_pinctrl_restore_gpio_regs(pctl, g->pin);
-- 
2.34.1



From kabel at kernel.org  Sun Dec 15 13:23:29 2024
From: kabel at kernel.org (Marek =?utf-8?B?QmVow7pu?=)
Date: Sun, 15 Dec 2024 22:23:29 +0100
Subject: [PATCH] cpufreq: enable 1200Mhz clock speed for armada-37xx
In-Reply-To: <20241212070712.txkxgmiugzji3doz@vireshk-i7>
References: <20241125211452.14987-1-ben@bens.haus>
 <20241212070712.txkxgmiugzji3doz@vireshk-i7>
Message-ID: <fjdblv62k3nhqgy7decdldtieo4zyv6phxofx72dreyq7jbm4f@qmkp3e2wyplb>

On Thu, Dec 12, 2024 at 12:37:12PM +0530, Viresh Kumar wrote:
> Marek,

...

> Any inputs on this before I apply it ?

Viresh, let me try to test it this week on Turris Mox.

Marek


From andre.przywara at arm.com  Sun Dec 15 13:25:33 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun, 15 Dec 2024 21:25:33 +0000
Subject: [PATCH] arm64: dts: allwinner: h313: enable DVFS for Tanix TX1
Message-ID: <20241215212533.12707-1-andre.przywara@arm.com>

The merging of the Tanix TX1 .dts file overlapped with the introduction
of the CPU OPP .dtsi file, so the TX1 wasn't covered by the patch
enabling DVFS for all boards.

Add the missing include of that OPP .dtsi file, to allow the box to run
at up to 1.3GHz, and enable power saving by using lower OPPs.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts
index bb2cde59bd03..622f4290057a 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
-- 
2.25.1



From agordeev at linux.ibm.com  Sun Dec 15 14:09:27 2024
From: agordeev at linux.ibm.com (Alexander Gordeev)
Date: Sun, 15 Dec 2024 23:09:27 +0100
Subject: [PATCH 11/14] selftests/mm: Use sys_pkey helpers consistently
In-Reply-To: <20241209095019.1732120-12-kevin.brodsky@arm.com>
References: <20241209095019.1732120-1-kevin.brodsky@arm.com>
 <20241209095019.1732120-12-kevin.brodsky@arm.com>
Message-ID: <Z19Tl30BuKTfL629@tuxmaker.boeblingen.de.ibm.com>

On Mon, Dec 09, 2024 at 09:50:16AM +0000, Kevin Brodsky wrote:

Hi Kevin, Andrew,

> diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
> index 814b17a43385..1f0743d9459d 100644
> --- a/tools/testing/selftests/mm/Makefile
> +++ b/tools/testing/selftests/mm/Makefile
> @@ -147,8 +147,8 @@ TEST_FILES += write_hugetlb_memory.sh
>  
>  include ../lib.mk
>  
> -$(TEST_GEN_PROGS): vm_util.c thp_settings.c
> -$(TEST_GEN_FILES): vm_util.c thp_settings.c
> +$(TEST_GEN_PROGS): vm_util.c thp_settings.c pkey_util.c
> +$(TEST_GEN_FILES): vm_util.c thp_settings.c pkey_util.c

This patch breaks s390 in -next with the below error messages:

In file included from pkey_util.c:5:
pkey-helpers.h:109:2: error: #error Architecture not supported
  109 | #error Architecture not supported
      |  ^~~~~
pkey-helpers.h: In function ?set_pkey_bits?:
pkey-helpers.h:126:21: error: implicit declaration of function ?pkey_bit_position? [-Wimplicit-function-declaration]
  126 |         u32 shift = pkey_bit_position(pkey);
      |                     ^~~~~~~~~~~~~~~~~
pkey-helpers.h: In function ?_read_pkey_reg?:
pkey-helpers.h:151:24: error: implicit declaration of function ?__read_pkey_reg?; did you mean ?_read_pkey_reg?? [-Wimplicit-function-declaration]
  151 |         u64 pkey_reg = __read_pkey_reg();
      |                        ^~~~~~~~~~~~~~~
      |                        _read_pkey_reg
pkey-helpers.h: In function ?write_pkey_reg?:
pkey-helpers.h:165:18: warning: format ?%llx? expects argument of type ?long long unsigned int?, but argument 3 has type ?int? [-Wformat=]
  165 |         dprintf4("%s() changing %016llx to %016llx\n", __func__,
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  166 |                         __read_pkey_reg(), pkey_reg);
      |                         ~~~~~~~~~~~~~~~~~
      |                         |
      |                         int
pkey-helpers.h:62:32: note: in definition of macro ?dprintf_level?
   62 |                 sigsafe_printf(args);           \
      |                                ^~~~
pkey-helpers.h:165:9: note: in expansion of macro ?dprintf4?
  165 |         dprintf4("%s() changing %016llx to %016llx\n", __func__,
      |         ^~~~~~~~
pkey-helpers.h:165:39: note: format string is defined here
  165 |         dprintf4("%s() changing %016llx to %016llx\n", __func__,
      |                                 ~~~~~~^
      |                                       |
      |                                       long long unsigned int
      |                                 %016x
pkey-helpers.h:169:9: error: implicit declaration of function ?__write_pkey_reg?; did you mean ?write_pkey_reg?? [-Wimplicit-function-declaration]
  169 |         __write_pkey_reg(pkey_reg);
      |         ^~~~~~~~~~~~~~~~
      |         write_pkey_reg
pkey-helpers.h:171:18: warning: format ?%llx? expects argument of type ?long long unsigned int?, but argument 4 has type ?int? [-Wformat=]
  171 |         dprintf4("%s(%016llx) pkey_reg: %016llx\n", __func__,
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  172 |                         pkey_reg, __read_pkey_reg());
      |                                   ~~~~~~~~~~~~~~~~~
      |                                   |
      |                                   int
pkey-helpers.h:62:32: note: in definition of macro ?dprintf_level?
   62 |                 sigsafe_printf(args);           \
      |                                ^~~~
pkey-helpers.h:171:9: note: in expansion of macro ?dprintf4?
  171 |         dprintf4("%s(%016llx) pkey_reg: %016llx\n", __func__,
      |         ^~~~~~~~
pkey-helpers.h:171:47: note: format string is defined here
  171 |         dprintf4("%s(%016llx) pkey_reg: %016llx\n", __func__,
      |                                         ~~~~~~^
      |                                               |
      |                                               long long unsigned int
      |                                         %016x
pkey-helpers.h: In function ?is_pkeys_supported?:
pkey-helpers.h:207:14: error: implicit declaration of function ?cpu_has_pkeys?; did you mean ?kernel_has_pkeys?? [-Wimplicit-function-declaration]
  207 |         if (!cpu_has_pkeys()) {
      |              ^~~~~~~~~~~~~
      |              kernel_has_pkeys

Please, let me know if I am missing something.

>  $(OUTPUT)/uffd-stress: uffd-common.c
>  $(OUTPUT)/uffd-unit-tests: uffd-common.c

Thanks!


From daniel at makrotopia.org  Sun Dec 15 14:09:41 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 15 Dec 2024 22:09:41 +0000
Subject: [PATCH] drm/mediatek: only touch DISP_REG_OVL_PITCH_MSB if AFBC is
 supported
Message-ID: <8c001c8e70d93d64d3ee6bf7dc5078d2783d4e32.1734300345.git.daniel@makrotopia.org>

Touching DISP_REG_OVL_PITCH_MSB leads to video overlay on MT2701, MT7623N
and probably other older SoCs being broken.

Only touching it on hardware which actually supports AFBC like it was
before commit c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek
DRM driver") fixes it.

Fixes: c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek DRM driver")
Cc: stable at vger.kernel.org
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index f731d4fbe8b6..321b40a387cd 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -545,7 +545,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
 		mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
 				      DISP_REG_OVL_HDR_PITCH(ovl, idx));
-	} else {
+	} else if (ovl->data->supports_afbc) {
 		mtk_ddp_write_relaxed(cmdq_pkt,
 				      overlay_pitch.split_pitch.msb,
 				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
-- 
2.47.1



From daniel at makrotopia.org  Sun Dec 15 14:14:11 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 15 Dec 2024 22:14:11 +0000
Subject: [PATCH 2/5] clk: mediatek: mt2701-aud: fix conversion to
 mtk_clk_simple_probe
In-Reply-To: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
Message-ID: <a07584d803af57b9ce4b5df5e122c09bf5a56ac9.1734300668.git.daniel@makrotopia.org>

Some of the audio subsystem clocks defined in clk-mt2701.h aren't
actually used by the driver. This broke conversion to
mtk_clk_simple_probe which expects that the highest possible clk id is
defined by the ARRAY_SIZE.

Add additional dummy clocks to fill the gaps and remain compatible with
the existing DT bindings.

Fixes: 0f69a423c458 ("clk: mediatek: Switch to mtk_clk_simple_probe() where possible")
Cc: stable at vger.kernel.org
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/clk/mediatek/clk-mt2701-aud.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mt2701-aud.c b/drivers/clk/mediatek/clk-mt2701-aud.c
index 425c69cfb105..e103121cf58e 100644
--- a/drivers/clk/mediatek/clk-mt2701-aud.c
+++ b/drivers/clk/mediatek/clk-mt2701-aud.c
@@ -55,10 +55,16 @@ static const struct mtk_gate audio_clks[] = {
 	GATE_DUMMY(CLK_DUMMY, "aud_dummy"),
 	/* AUDIO0 */
 	GATE_AUDIO0(CLK_AUD_AFE, "audio_afe", "aud_intbus_sel", 2),
+	GATE_DUMMY(CLK_AUD_LRCK_DETECT, "audio_lrck_detect_dummy"),
+	GATE_DUMMY(CLK_AUD_I2S, "audio_i2c_dummy"),
+	GATE_DUMMY(CLK_AUD_APLL_TUNER, "audio_apll_tuner_dummy"),
 	GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi", "audpll_sel", 20),
 	GATE_AUDIO0(CLK_AUD_SPDF, "audio_spdf", "audpll_sel", 21),
 	GATE_AUDIO0(CLK_AUD_SPDF2, "audio_spdf2", "audpll_sel", 22),
 	GATE_AUDIO0(CLK_AUD_APLL, "audio_apll", "audpll_sel", 23),
+	GATE_DUMMY(CLK_AUD_TML, "audio_tml_dummy"),
+	GATE_DUMMY(CLK_AUD_AHB_IDLE_EXT, "audio_ahb_idle_ext_dummy"),
+	GATE_DUMMY(CLK_AUD_AHB_IDLE_INT, "audio_ahb_idle_int_dummy"),
 	/* AUDIO1 */
 	GATE_AUDIO1(CLK_AUD_I2SIN1, "audio_i2sin1", "aud_mux1_sel", 0),
 	GATE_AUDIO1(CLK_AUD_I2SIN2, "audio_i2sin2", "aud_mux1_sel", 1),
@@ -76,10 +82,12 @@ static const struct mtk_gate audio_clks[] = {
 	GATE_AUDIO1(CLK_AUD_ASRCI2, "audio_asrci2", "asm_h_sel", 13),
 	GATE_AUDIO1(CLK_AUD_ASRCO1, "audio_asrco1", "asm_h_sel", 14),
 	GATE_AUDIO1(CLK_AUD_ASRCO2, "audio_asrco2", "asm_h_sel", 15),
+	GATE_DUMMY(CLK_AUD_HDMIRX, "audio_hdmirx_dummy"),
 	GATE_AUDIO1(CLK_AUD_INTDIR, "audio_intdir", "intdir_sel", 20),
 	GATE_AUDIO1(CLK_AUD_A1SYS, "audio_a1sys", "aud_mux1_sel", 21),
 	GATE_AUDIO1(CLK_AUD_A2SYS, "audio_a2sys", "aud_mux2_sel", 22),
 	GATE_AUDIO1(CLK_AUD_AFE_CONN, "audio_afe_conn", "aud_mux1_sel", 23),
+	GATE_DUMMY(CLK_AUD_AFE_PCMIF, "audio_afe_pcmif_dummy"),
 	GATE_AUDIO1(CLK_AUD_AFE_MRGIF, "audio_afe_mrgif", "aud_mux1_sel", 25),
 	/* AUDIO2 */
 	GATE_AUDIO2(CLK_AUD_MMIF_UL1, "audio_ul1", "aud_mux1_sel", 0),
@@ -100,6 +108,8 @@ static const struct mtk_gate audio_clks[] = {
 	GATE_AUDIO2(CLK_AUD_MMIF_AWB2, "audio_awb2", "aud_mux1_sel", 15),
 	GATE_AUDIO2(CLK_AUD_MMIF_DAI, "audio_dai", "aud_mux1_sel", 16),
 	/* AUDIO3 */
+	GATE_DUMMY(CLK_AUD_DMIC1, "audio_dmic1_dummy"),
+	GATE_DUMMY(CLK_AUD_DMIC2, "audio_dmic2_dummy"),
 	GATE_AUDIO3(CLK_AUD_ASRCI3, "audio_asrci3", "asm_h_sel", 2),
 	GATE_AUDIO3(CLK_AUD_ASRCI4, "audio_asrci4", "asm_h_sel", 3),
 	GATE_AUDIO3(CLK_AUD_ASRCI5, "audio_asrci5", "asm_h_sel", 4),
-- 
2.47.1


From daniel at makrotopia.org  Sun Dec 15 14:14:24 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 15 Dec 2024 22:14:24 +0000
Subject: [PATCH 3/5] clk: mediatek: mt2701-bdp: add missing dummy clk
In-Reply-To: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
Message-ID: <b8526c882a50f2b158df0eccb4a165956fd8fa13.1734300668.git.daniel@makrotopia.org>

Add dummy clk for index 0 which was missed during the conversion to
mtk_clk_simple_probe().

Fixes: 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver")
Cc: stable at vger.kernel.org
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/clk/mediatek/clk-mt2701-bdp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/mediatek/clk-mt2701-bdp.c b/drivers/clk/mediatek/clk-mt2701-bdp.c
index 5da3eabffd3e..f11c7a4fa37b 100644
--- a/drivers/clk/mediatek/clk-mt2701-bdp.c
+++ b/drivers/clk/mediatek/clk-mt2701-bdp.c
@@ -31,6 +31,7 @@ static const struct mtk_gate_regs bdp1_cg_regs = {
 	GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
 
 static const struct mtk_gate bdp_clks[] = {
+	GATE_DUMMY(CLK_DUMMY, "bdp_dummy"),
 	GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
 	GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
 	GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),
-- 
2.47.1


From daniel at makrotopia.org  Sun Dec 15 14:14:34 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 15 Dec 2024 22:14:34 +0000
Subject: [PATCH 4/5] clk: mediatek: mt2701-mm: add missing dummy clk
In-Reply-To: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
Message-ID: <9de23440fcba1ffef9e77d58c9f505105e57a250.1734300668.git.daniel@makrotopia.org>

Add dummy clk which was missed during the conversion to
mtk_clk_pdev_probe() and is required for the existing DT bindings to
keep working.

Fixes: 65c10c50c9c7 ("clk: mediatek: Migrate to mtk_clk_pdev_probe() for multimedia clocks")
Cc: stable at vger.kernel.org
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/clk/mediatek/clk-mt2701-mm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/mediatek/clk-mt2701-mm.c b/drivers/clk/mediatek/clk-mt2701-mm.c
index bc68fa718878..474d87d62e83 100644
--- a/drivers/clk/mediatek/clk-mt2701-mm.c
+++ b/drivers/clk/mediatek/clk-mt2701-mm.c
@@ -31,6 +31,7 @@ static const struct mtk_gate_regs disp1_cg_regs = {
 	GATE_MTK(_id, _name, _parent, &disp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
 static const struct mtk_gate mm_clks[] = {
+	GATE_DUMMY(CLK_DUMMY, "mm_dummy"),
 	GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0),
 	GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
 	GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2),
-- 
2.47.1


From daniel at makrotopia.org  Sun Dec 15 14:13:49 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 15 Dec 2024 22:13:49 +0000
Subject: [PATCH 1/5] clk: mediatek: mt2701-vdec: fix conversion to
 mtk_clk_simple_probe
Message-ID: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>

Commit 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to
simplify driver") broke DT bindings as the highest index was reduced by
1 because the id count starts from 1 and not from 0.

Fix this, like for other drivers which had the same issue, by adding a
dummy clk at index 0.

Fixes: 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver")
Cc: stable at vger.kernel.org
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/clk/mediatek/clk-mt2701-vdec.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/mediatek/clk-mt2701-vdec.c b/drivers/clk/mediatek/clk-mt2701-vdec.c
index 94db86f8d0a4..5299d92f3aba 100644
--- a/drivers/clk/mediatek/clk-mt2701-vdec.c
+++ b/drivers/clk/mediatek/clk-mt2701-vdec.c
@@ -31,6 +31,7 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
 	GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
 
 static const struct mtk_gate vdec_clks[] = {
+	GATE_DUMMY(CLK_DUMMY, "vdec_dummy"),
 	GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
 	GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0),
 };
-- 
2.47.1


From daniel at makrotopia.org  Sun Dec 15 14:14:48 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 15 Dec 2024 22:14:48 +0000
Subject: [PATCH 5/5] clk: mediatek: mt2701-img: add missing dummy clk
In-Reply-To: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
Message-ID: <d677486a5c563fe5c47aa995841adc2aaa183b8a.1734300668.git.daniel@makrotopia.org>

Add dummy clk for index 0 which was missed during the conversion to
mtk_clk_simple_probe().

Fixes: 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver")
Cc: stable at vger.kernel.org
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/clk/mediatek/clk-mt2701-img.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/mediatek/clk-mt2701-img.c b/drivers/clk/mediatek/clk-mt2701-img.c
index 875594bc9dcb..c158e54c4652 100644
--- a/drivers/clk/mediatek/clk-mt2701-img.c
+++ b/drivers/clk/mediatek/clk-mt2701-img.c
@@ -22,6 +22,7 @@ static const struct mtk_gate_regs img_cg_regs = {
 	GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
 static const struct mtk_gate img_clks[] = {
+	GATE_DUMMY(CLK_DUMMY, "img_dummy"),
 	GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
 	GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1),
 	GATE_IMG(CLK_IMG_JPGDEC_SMI, "img_jpgdec_smi", "mm_sel", 5),
-- 
2.47.1


From zmw12306 at gmail.com  Sun Dec 15 14:47:52 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Sun, 15 Dec 2024 17:47:52 -0500
Subject: [PATCH] pwm: stm32: Add check for clk_enable()
Message-ID: <20241215224752.220318-1-zmw12306@gmail.com>

Add check for the return value of clk_enable() to catch the potential
error.

Fixes: 19f1016ea960 ("pwm: stm32: Fix enable count for clk in .probe()")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
 drivers/pwm/pwm-stm32.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index b889e64522c3..b94d186e3c0c 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -858,8 +858,11 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 	chip->ops = &stm32pwm_ops;
 
 	/* Initialize clock refcount to number of enabled PWM channels. */
-	for (i = 0; i < num_enabled; i++)
-		clk_enable(priv->clk);
+	for (i = 0; i < num_enabled; i++) {
+		ret = clk_enable(priv->clk);
+		if (ret)
+			return ret;
+	}
 
 	ret = devm_pwmchip_add(dev, chip);
 	if (ret < 0)
-- 
2.34.1



From marex at denx.de  Sun Dec 15 15:41:43 2024
From: marex at denx.de (Marek Vasut)
Date: Mon, 16 Dec 2024 00:41:43 +0100
Subject: [PATCH v5] pinctrl: stm32: Add check for clk_enable()
In-Reply-To: <20241215204014.4076659-1-zmw12306@gmail.com>
References: <20241215204014.4076659-1-zmw12306@gmail.com>
Message-ID: <9745b3ee-ae89-4edb-8ff7-b20096dbe1de@denx.de>

On 12/15/24 9:40 PM, Mingwei Zheng wrote:

[...]

> @@ -1617,10 +1602,18 @@ int stm32_pctl_probe(struct platform_device *pdev)
>   		return -EINVAL;
>   	}
>   	pctl->banks = devm_kcalloc(dev, banks, sizeof(*pctl->banks),
> -			GFP_KERNEL);
> +				   GFP_KERNEL);

Please drop this one change.

>   	if (!pctl->banks)
>   		return -ENOMEM;
>   
> +	pctl->clks = devm_kcalloc(dev, banks, sizeof(*pctl->clks),
> +				  GFP_KERNEL);
> +	if (!pctl->clks)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < banks; ++i)
> +		pctl->clks[i].id = "";

Is this ^ assignment necessary ? If so, why ?

[...]


From apopple at nvidia.com  Sun Dec 15 16:55:30 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Mon, 16 Dec 2024 11:55:30 +1100
Subject: [PATCH v3 00/25] fs/dax: Fix ZONE_DEVICE page reference counts
In-Reply-To: <45555f72-e82a-4196-94af-22d05d6ac947@redhat.com>
References: <cover.e1ebdd6cab9bde0d232c1810deacf0bae25e6707.1732239628.git-series.apopple@nvidia.com>
 <675ce1e5a3d68_fad0294d0@dwillia2-xfh.jf.intel.com.notmuch>
 <45555f72-e82a-4196-94af-22d05d6ac947@redhat.com>
Message-ID: <wysuus23bqmjtwkfu3zutqtmkse3ki3erf45x32yezlrl24qto@xlqt7qducyld>

On Sat, Dec 14, 2024 at 04:22:58PM +0100, David Hildenbrand wrote:
> On 14.12.24 02:39, Dan Williams wrote:
> > [ add akpm and sfr for next steps ]
> > 
> > Alistair Popple wrote:
> > > Main updates since v2:
> > > 
> > >   - Rename the DAX specific dax_insert_XXX functions to vmf_insert_XXX
> > >     and have them pass the vmf struct.
> > > 
> > >   - Seperate out the device DAX changes.
> > > 
> > >   - Restore the page share mapping counting and associated warnings.
> > > 
> > >   - Rework truncate to require file-systems to have previously called
> > >     dax_break_layout() to remove the address space mapping for a
> > >     page. This found several bugs which are fixed by the first half of
> > >     the series. The motivation for this was initially to allow the FS
> > >     DAX page-cache mappings to hold a reference on the page.
> > > 
> > >     However that turned out to be a dead-end (see the comments on patch
> > >     21), but it found several bugs and I think overall it is an
> > >     improvement so I have left it here.
> > > 
> > > Device and FS DAX pages have always maintained their own page
> > > reference counts without following the normal rules for page reference
> > > counting. In particular pages are considered free when the refcount
> > > hits one rather than zero and refcounts are not added when mapping the
> > > page.
> > > 
> > > Tracking this requires special PTE bits (PTE_DEVMAP) and a secondary
> > > mechanism for allowing GUP to hold references on the page (see
> > > get_dev_pagemap). However there doesn't seem to be any reason why FS
> > > DAX pages need their own reference counting scheme.
> > > 
> > > By treating the refcounts on these pages the same way as normal pages
> > > we can remove a lot of special checks. In particular pXd_trans_huge()
> > > becomes the same as pXd_leaf(), although I haven't made that change
> > > here. It also frees up a valuable SW define PTE bit on architectures
> > > that have devmap PTE bits defined.
> > > 
> > > It also almost certainly allows further clean-up of the devmap managed
> > > functions, but I have left that as a future improvment. It also
> > > enables support for compound ZONE_DEVICE pages which is one of my
> > > primary motivators for doing this work.
> > 
> > So this is feeling ready for -next exposure, and ideally merged for v6.14. I
> > see the comments from John and Bjorn and that you were going to respin for
> > that, but if it's just those details things they can probably be handled
> > incrementally.
> > 
> > Alistair, are you ready for this to hit -next?

Yeah, I'm pretty happy with the series now. It "feels" right.

There's a couple of dumb build bot errors, so I was going to respin to fix
those as well. I got caught up with a few other things so was just letting this
sit awaiting feedback, but I should be able to post a respin early this week.

> > As for which tree...
> > 
> > Andrew, we could take this through -mm, but my first instinct would be to try
> > to take it through nvdimm.git mainly to offload any conflict wrangling work and
> > small fixups which are likely to be an ongoing trickle.
> > 
> > However, I am not going to put up much of a fight if others prefer this go
> > through -mm.
> > 
> > Thoughts?
> 
> I'm in the process of preparing v2 of [1] that will result in conflicts with
> this series in the rmap code (in particular [PATCH v3 14/25] huge_memory:
> Allow mappings of PUD sized pages).
> 
> I'll be away for 2 weeks over Christmas, but I assume I'll manage to post v2
> shortly.
> 
> Which reminds me that I still have to take a closer look at some things in
> this series :) Especially also #14 regarding accounting.
> 
> I wonder if we could split out the rmap changes in #14, and have that patch
> simply in two trees? No idea.

I could split out the first half (patches 1 - 8) into a series to go via
nvdimm.git, because they are actually standalone clean ups that I think are
worthwhile anyway.

The remainder are more -mm focussed. However they do depend on the fs/dax
cleanups in the first half so the trick would be making sure Andrew only takes
them if the nvdimm.git changes have made it into -next. I'm happy with either
approach, so let me know if I should split the series or not.

 - Alistair

> [1]
> https://lore.kernel.org/all/20240829165627.2256514-1-david at redhat.com/T/#u
> 
> -- 
> Cheers,
> 
> David / dhildenb
> 


From hui.wang at canonical.com  Sun Dec 15 17:07:00 2024
From: hui.wang at canonical.com (Hui Wang)
Date: Mon, 16 Dec 2024 09:07:00 +0800
Subject: [PATCH] ARM: dts: nxp: imx6qdl: add dr_mode to usbotg
In-Reply-To: <20241213125528.m2skucuhqtrc5f4s@hippo>
References: <20241212043126.73045-1-hui.wang@canonical.com>
 <20241213081729.ohgs7tyyzywd4uyc@hippo>
 <cb6c7f8d-6244-4370-944f-a1a2beac3a79@canonical.com>
 <20241213125528.m2skucuhqtrc5f4s@hippo>
Message-ID: <53d8c4e9-0047-40f5-9142-2b3e8e723100@canonical.com>


On 12/13/24 20:55, Xu Yang wrote:
> On Fri, Dec 13, 2024 at 07:25:32PM +0800, Hui Wang wrote:
>> On 12/13/24 16:17, Xu Yang wrote:
>>> Hi,
>>>
>>> On Thu, Dec 12, 2024 at 12:31:26PM +0800, Hui Wang wrote:
>>>> For the chipidea usb driver, if the dr_mode is not set, it will set
>>>> the device to otg mode by default, so here the dr_mode has not been
>>>> set for a long time. But some testcases need to parse the dr_mode from
>>>> DT and decide the follow-up test strategy, here set the dr_mode to otg
>>>> explicitly for QA's testcases.
>>> The dr_mode is board specific property, so we normally don't put it in
>>> dtsi file. Also, imx6qdl.dtsi is a common dtsi, therefore it's not a
>>> correct place. I wonder you don't set dr_mode in other dts file which
>>> include will imx6qdl.dtsi?
>> Yes, our QA reported this issue against the imx6q-sabresd board, I thought
>> dr_mode could be overwritten if board dts set the dr_mode, so this change
>> will not impact existing boards. But as you said "we normally don't put it
>> in dtsi file", I will move it to imx6q-sabresd.dts.
> Okay. You can move it to imx6qdl-sabresd.dtsi too. Then you can reuse
> &usbotg {}.

Yes, for sure.

Thanks,

Hui.

> Thanks,
> Xu Yang
>
>> Thanks,
>>
>> Hui.
>>
>>> Thanks,
>>> Xu Yang
>>>
>>>> Signed-off-by: Hui Wang <hui.wang at canonical.com>
>>>> ---
>>>>    arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 1 +
>>>>    1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
>>>> index d2200c9db25a..285fb7314a88 100644
>>>> --- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
>>>> +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
>>>> @@ -982,6 +982,7 @@ usbotg: usb at 2184000 {
>>>>    				clocks = <&clks IMX6QDL_CLK_USBOH3>;
>>>>    				fsl,usbphy = <&usbphy1>;
>>>>    				fsl,usbmisc = <&usbmisc 0>;
>>>> +				dr_mode = "otg";
>>>>    				ahb-burst-config = <0x0>;
>>>>    				tx-burst-size-dword = <0x10>;
>>>>    				rx-burst-size-dword = <0x10>;
>>>> -- 
>>>> 2.34.1
>>>>


From kaihengf at nvidia.com  Sun Dec 15 18:25:29 2024
From: kaihengf at nvidia.com (Kai-Heng Feng)
Date: Mon, 16 Dec 2024 10:25:29 +0800
Subject: [PATCH] irqchip/gic-v3: Allow unused SGIs for drivers/modules
In-Reply-To: <Zrs2i9Iyrlqc-a4K@bogus>
References: <20240813033925.925947-1-sdonthineni@nvidia.com>
 <86zfpgztmt.wl-maz@kernel.org> <Zrs2i9Iyrlqc-a4K@bogus>
Message-ID: <1885f74b-5bfb-46a3-a65f-521d974d023f@nvidia.com>

Hi Sudeep,

On 2024/8/13 6:33 PM, Sudeep Holla wrote:
> On Tue, Aug 13, 2024 at 09:58:34AM +0100, Marc Zyngier wrote:
>> On Tue, 13 Aug 2024 04:39:25 +0100,
>> Shanker Donthineni <sdonthineni at nvidia.com> wrote:
>>>
>>> The commit 897e9e60c016 ("firmware: arm_ffa: Initial support for scheduler
>>> receiver interrupt") adds support for SGI interrupts in the FFA driver.
>>> However, the validation for SGIs in the GICv3 is too strict, causing the
>>> driver probe to fail.
>>
>> It probably is a good thing that I wasn't on Cc for this patch,
>> because I would have immediately NAK'd it. Sudeep, please consider
>> this a retrospective NAK!
>>
> 
> Sure, I am happy to work on any suggestions to replace it with better/cleaner
> solution.
> 
>>>
>>> This patch relaxes the SGI validation check, allowing callers to use SGIs
>>> if the requested SGI number is greater than or equal to MAX_IPI, which
>>> fixes the TFA driver probe failure.
>>>
>>> This issue is observed on NVIDIA server platform with FFA-v1.1.
>>>   [    7.918099] PTP clock support registered
>>>   [    7.922110] EDAC MC: Ver: 3.0.0
>>>   [    7.945063] ARM FF-A: Driver version 1.1
>>>   [    7.949068] ARM FF-A: Firmware version 1.1 found
>>>   [    7.977832] GICv3: [Firmware Bug]: Illegal GSI8 translation request
>>>   [    7.984237] ARM FF-A: Failed to create IRQ mapping!
>>>   [    7.989220] ARM FF-A: Notification setup failed -61, not enabled
>>>   [    8.000198] ARM FF-A: Failed to register driver sched callback -95
>>>   [    8.011322] scmi_core: SCMI protocol bus registered
>>>
>>> Signed-off-by: Shanker Donthineni <sdonthineni at nvidia.com>
>>> ---
>>>   arch/arm64/include/asm/arch_gicv3.h | 17 +++++++++++++++++
>>>   arch/arm64/kernel/smp.c             | 17 -----------------
>>>   drivers/irqchip/irq-gic-v3.c        |  2 +-
>>>   3 files changed, 18 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
>>> index 9e96f024b2f19..ecf81df2915c7 100644
>>> --- a/arch/arm64/include/asm/arch_gicv3.h
>>> +++ b/arch/arm64/include/asm/arch_gicv3.h
>>> @@ -188,5 +188,22 @@ static inline bool gic_has_relaxed_pmr_sync(void)
>>>   	return cpus_have_cap(ARM64_HAS_GIC_PRIO_RELAXED_SYNC);
>>>   }
>>>   
>>> +enum ipi_msg_type {
>>> +	IPI_RESCHEDULE,
>>> +	IPI_CALL_FUNC,
>>> +	IPI_CPU_STOP,
>>> +	IPI_CPU_CRASH_STOP,
>>> +	IPI_TIMER,
>>> +	IPI_IRQ_WORK,
>>> +	NR_IPI,
>>> +	/*
>>> +	 * Any enum >= NR_IPI and < MAX_IPI is special and not tracable
>>> +	 * with trace_ipi_*
>>> +	 */
>>> +	IPI_CPU_BACKTRACE = NR_IPI,
>>> +	IPI_KGDB_ROUNDUP,
>>> +	MAX_IPI
>>> +};
>>> +
>>>   #endif /* __ASSEMBLY__ */
>>>   #endif /* __ASM_ARCH_GICV3_H */
>>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>>> index 5e18fbcee9a20..373cd815d9a43 100644
>>> --- a/arch/arm64/kernel/smp.c
>>> +++ b/arch/arm64/kernel/smp.c
>>> @@ -64,23 +64,6 @@ struct secondary_data secondary_data;
>>>   /* Number of CPUs which aren't online, but looping in kernel text. */
>>>   static int cpus_stuck_in_kernel;
>>>   
>>> -enum ipi_msg_type {
>>> -	IPI_RESCHEDULE,
>>> -	IPI_CALL_FUNC,
>>> -	IPI_CPU_STOP,
>>> -	IPI_CPU_CRASH_STOP,
>>> -	IPI_TIMER,
>>> -	IPI_IRQ_WORK,
>>> -	NR_IPI,
>>> -	/*
>>> -	 * Any enum >= NR_IPI and < MAX_IPI is special and not tracable
>>> -	 * with trace_ipi_*
>>> -	 */
>>> -	IPI_CPU_BACKTRACE = NR_IPI,
>>> -	IPI_KGDB_ROUNDUP,
>>> -	MAX_IPI
>>> -};
>>> -
>>>   static int ipi_irq_base __ro_after_init;
>>>   static int nr_ipi __ro_after_init = NR_IPI;
>>>   static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init;
>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>> index c19083bfb9432..0d2038d8cd311 100644
>>> --- a/drivers/irqchip/irq-gic-v3.c
>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>> @@ -1655,7 +1655,7 @@ static int gic_irq_domain_translate(struct irq_domain *d,
>>>   		if(fwspec->param_count != 2)
>>>   			return -EINVAL;
>>>
>>> -		if (fwspec->param[0] < 16) {
>>> +		if (fwspec->param[0] < MAX_IPI) {
>>>   			pr_err(FW_BUG "Illegal GSI%d translation request\n",
>>>   			       fwspec->param[0]);
>>>   			return -EINVAL;
>>
>> No. This is the wrong approach, and leads to inconsistent behaviour if
>> we ever change this MAX_IPI value. It also breaks 32 bit builds, and
>> makes things completely inconsistent between ACPI and DT.
>>
>> I don't know how the FFA code was tested, because I cannot see how it
>> can work.
>>
>> *IF* we are going to allow random SGIs being requested by random
>> drivers, we need to be able to do it properly. Not as a side hack like
>> this.
> 
> I am open for any ideas as FF-A spec authors/architects decided to allow
> secure world to donate one of its SGI to the normal world for FF-A
> notifications.

Is there any progression on this issue? Do you think it's reasonable to revert 
commit 897e9e60c016 as a temporary measure?

Kai-Heng

> 
> --
> Regards,
> Sudeep
> 



From damon.ding at rock-chips.com  Sun Dec 15 19:12:16 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:16 +0800
Subject: [PATCH v2 02/11] dt-bindings: display: rockchip: analogix-dp: Add support for RK3588
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-3-damon.ding@rock-chips.com>

Compared with RK3288/RK3399, the HBR2 link rate support is the main
improvement of RK3588 eDP TX controller, and there are also two
independent eDP display interfaces on RK3588 Soc.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Add the main defferences of the RK3588 eDP and the previous versions
  in commit message
---
 .../bindings/display/rockchip/rockchip,analogix-dp.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
index 60dedf9b2be7..b82b693532e1 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
@@ -15,6 +15,7 @@ properties:
     enum:
       - rockchip,rk3288-dp
       - rockchip,rk3399-edp
+      - rockchip,rk3588-edp
 
   clocks:
     minItems: 2
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:14 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:14 +0800
Subject: [PATCH v2 00/11] Add eDP support for RK3588
Message-ID: <20241216031225.3746-1-damon.ding@rock-chips.com>

These patchs have been tested with a 1536x2048p60 eDP panel on
RK3588S EVB1 board, and HDMI 1080P/4K display also has been verified
on RK3588 EVB1 board.

Patch 1~3 are the RK3588 eDP support of Rockchip analogix_dp driver.
Patch 4   is the eDP mode support of samsung hdptx phy driver.
Patch 5~6 are the Rk3588 eDP support of Aanalogix DP driver. Add phy
          interfaces is to configure the HDMI/eDP TX Combo PHY.
Patch 7~8 are the renaming of hdptxphy node. It is not only used by
          HDMI display but also for the eDP display.
Patch 9   is the addition of RK3588 eDP0 node.
Patch 10  is to enable the eDP0 display on RK3588S EVB1 board.
Patch 11  is to add the eDP1 related nodes for RK3588 SoC.

Damon Ding (11):
  drm/rockchip: analogix_dp: Use formalized struct definition for grf
    field
  dt-bindings: display: rockchip: analogix-dp: Add support for RK3588
  drm/rockchip: analogix_dp: Add support for RK3588
  phy: phy-rockchip-samsung-hdptx: Add support for eDP mode
  drm/bridge: analogix_dp: add support for RK3588
  drm/bridge: analogix_dp: Add support for phy configuration.
  dt-bindings: display: rockchip: Fix label name of hdptxphy for RK3588
    HDMI TX Controller
  arm64: dts: rockchip: Fix label name of hdptxphy for RK3588
  arm64: dts: rockchip: Add eDP0 node for RK3588
  arm64: dts: rockchip: Enable eDP0 display on RK3588S EVB1 board
  arm64: dts: rockchip: Add nodes related to eDP1 for RK3588

 .../rockchip/rockchip,analogix-dp.yaml        |   1 +
 .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml  |   2 +-
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi |  33 +-
 .../dts/rockchip/rk3588-coolpi-cm5-evb.dts    |   2 +-
 .../rockchip/rk3588-coolpi-cm5-genbook.dts    |   2 +-
 .../boot/dts/rockchip/rk3588-evb1-v10.dts     |   2 +-
 .../arm64/boot/dts/rockchip/rk3588-extra.dtsi |  55 +
 .../rk3588-friendlyelec-cm3588-nas.dts        |   2 +-
 .../arm64/boot/dts/rockchip/rk3588-jaguar.dts |   2 +-
 .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi   |   2 +-
 .../dts/rockchip/rk3588-orangepi-5-plus.dts   |   2 +-
 .../boot/dts/rockchip/rk3588-rock-5b.dts      |   2 +-
 .../boot/dts/rockchip/rk3588-tiger-haikou.dts |   2 +-
 .../boot/dts/rockchip/rk3588s-coolpi-4b.dts   |   2 +-
 .../boot/dts/rockchip/rk3588s-evb1-v10.dts    |  50 +
 .../dts/rockchip/rk3588s-indiedroid-nova.dts  |   2 +-
 .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi  |   2 +-
 .../boot/dts/rockchip/rk3588s-odroid-m2.dts   |   2 +-
 .../boot/dts/rockchip/rk3588s-orangepi-5.dtsi |   2 +-
 .../boot/dts/rockchip/rk3588s-rock-5a.dts     |   2 +-
 .../boot/dts/rockchip/rk3588s-rock-5c.dts     |   2 +-
 .../drm/bridge/analogix/analogix_dp_core.c    |   5 +
 .../gpu/drm/bridge/analogix/analogix_dp_reg.c |  56 ++
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 149 ++-
 .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 937 +++++++++++++++++-
 include/drm/bridge/analogix_dp.h              |   3 +-
 26 files changed, 1223 insertions(+), 100 deletions(-)

-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:20 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:20 +0800
Subject: [PATCH v2 06/11] drm/bridge: analogix_dp: Add support for phy configuration.
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-7-damon.ding@rock-chips.com>

Add support to configurate link rate, lane count, voltage swing and
pre-emphasis with phy_configure(). It is helpful in application scenarios
where analogix controller is mixed with the phy of other vendors.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- remove needless assignments for phy_configure()
- remove unnecessary changes for phy_power_on()/phy_power_off()
---
 .../drm/bridge/analogix/analogix_dp_core.c    |  1 +
 .../gpu/drm/bridge/analogix/analogix_dp_reg.c | 56 +++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 6f10d88a34c5..9429c50cc1bc 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1696,6 +1696,7 @@ int analogix_dp_resume(struct analogix_dp_device *dp)
 	if (dp->plat_data->power_on)
 		dp->plat_data->power_on(dp->plat_data);
 
+	phy_set_mode(dp->phy, PHY_MODE_DP);
 	phy_power_on(dp->phy);
 
 	analogix_dp_init_dp(dp);
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 3afc73c858c4..613ce504bea6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -11,6 +11,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/phy/phy.h>
 
 #include <drm/bridge/analogix_dp.h>
 
@@ -513,10 +514,25 @@ void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
 void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
 {
 	u32 reg;
+	int ret;
 
 	reg = bwtype;
 	if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
 		writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
+
+	if (dp->phy) {
+		union phy_configure_opts phy_cfg = {0};
+
+		phy_cfg.dp.lanes = dp->link_train.lane_count;
+		phy_cfg.dp.link_rate =
+			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
+		phy_cfg.dp.set_rate = true;
+		ret = phy_configure(dp->phy, &phy_cfg);
+		if (ret && ret != -EOPNOTSUPP) {
+			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
+			return;
+		}
+	}
 }
 
 void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
@@ -530,9 +546,22 @@ void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
 void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
 {
 	u32 reg;
+	int ret;
 
 	reg = count;
 	writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
+
+	if (dp->phy) {
+		union phy_configure_opts phy_cfg = {0};
+
+		phy_cfg.dp.lanes = dp->link_train.lane_count;
+		phy_cfg.dp.set_lanes = true;
+		ret = phy_configure(dp->phy, &phy_cfg);
+		if (ret && ret != -EOPNOTSUPP) {
+			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
+			return;
+		}
+	}
 }
 
 void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
@@ -546,10 +575,37 @@ void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
 void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp)
 {
 	u8 lane;
+	int ret;
 
 	for (lane = 0; lane < dp->link_train.lane_count; lane++)
 		writel(dp->link_train.training_lane[lane],
 		       dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane);
+
+	if (dp->phy) {
+		union phy_configure_opts phy_cfg = {0};
+
+		for (lane = 0; lane < dp->link_train.lane_count; lane++) {
+			u8 training_lane = dp->link_train.training_lane[lane];
+			u8 vs, pe;
+
+			vs = (training_lane & DP_TRAIN_VOLTAGE_SWING_MASK) >>
+			     DP_TRAIN_VOLTAGE_SWING_SHIFT;
+			pe = (training_lane & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+			     DP_TRAIN_PRE_EMPHASIS_SHIFT;
+			phy_cfg.dp.voltage[lane] = vs;
+			phy_cfg.dp.pre[lane] = pe;
+		}
+
+		phy_cfg.dp.lanes = dp->link_train.lane_count;
+		phy_cfg.dp.link_rate =
+			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
+		phy_cfg.dp.set_voltages = true;
+		ret = phy_configure(dp->phy, &phy_cfg);
+		if (ret && ret != -EOPNOTSUPP) {
+			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
+			return;
+		}
+	}
 }
 
 u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane)
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:18 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:18 +0800
Subject: [PATCH v2 04/11] phy: phy-rockchip-samsung-hdptx: Add support for eDP mode
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-5-damon.ding@rock-chips.com>

Add basic support for RBR/HBR/HBR2 link rates, and the voltage swing and
pre-emphasis configurations of each link rate have been verified according
to the eDP 1.3 requirements.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Add the module author
---
 .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 937 +++++++++++++++++-
 1 file changed, 894 insertions(+), 43 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 9f084697dd05..8dd0de267d10 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -25,6 +25,7 @@
 #define HDPTX_I_PLL_EN			BIT(7)
 #define HDPTX_I_BIAS_EN			BIT(6)
 #define HDPTX_I_BGR_EN			BIT(5)
+#define HDPTX_MODE_SEL			BIT(0)
 #define GRF_HDPTX_STATUS		0x80
 #define HDPTX_O_PLL_LOCK_DONE		BIT(3)
 #define HDPTX_O_PHY_CLK_RDY		BIT(2)
@@ -44,6 +45,7 @@
 #define LANE_REG(n)			HDTPX_REG(n, 0300, 062d)
 
 /* CMN_REG(0008) */
+#define OVRD_LCPLL_EN_MASK		BIT(7)
 #define LCPLL_EN_MASK			BIT(6)
 #define LCPLL_LCVCO_MODE_EN_MASK	BIT(4)
 /* CMN_REG(001e) */
@@ -61,49 +63,110 @@
 /* CMN_REG(002f) */
 #define LCPLL_SDC_DENOMINATOR_MASK	GENMASK(7, 2)
 #define LCPLL_SDC_NDIV_RSTN		BIT(0)
+/* CMN_REG(003c) */
+#define ANA_LCPLL_RESERVED7_MASK	BIT(7)
 /* CMN_REG(003d) */
+#define OVRD_ROPLL_EN_MASK		BIT(7)
+#define ROPLL_EN_MASK			BIT(6)
 #define ROPLL_LCVCO_EN			BIT(4)
+/* CMN_REG(0046) */
+#define ROPLL_ANA_CPP_CTRL_COARSE_MASK	GENMASK(7, 4)
+#define ROPLL_ANA_CPP_CTRL_FINE_MASK	GENMASK(3, 0)
+/* CMN_REG(0047) */
+#define ROPLL_ANA_LPF_C_SEL_COARSE_MASK	GENMASK(5, 3)
+#define ROPLL_ANA_LPF_C_SEL_FINE_MASK	GENMASK(2, 0)
 /* CMN_REG(004e) */
 #define ROPLL_PI_EN			BIT(5)
+/* CMN_REG(0051) */
+#define ROPLL_PMS_MDIV_MASK		GENMASK(7, 0)
+/* CMN_REG(0055) */
+#define ROPLL_PMS_MDIV_AFC_MASK		GENMASK(7, 0)
+/* CMN_REG(0059) */
+#define ANA_ROPLL_PMS_PDIV_MASK		GENMASK(7, 4)
+#define ANA_ROPLL_PMS_REFDIV_MASK	GENMASK(3, 0)
+/* CMN_REG(005a) */
+#define ROPLL_PMS_SDIV_RBR_MASK		GENMASK(7, 4)
+#define ROPLL_PMS_SDIV_HBR_MASK		GENMASK(3, 0)
+/* CMN_REG(005b) */
+#define ROPLL_PMS_SDIV_HBR2_MASK	GENMASK(7, 4)
 /* 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)
+#define OVRD_ROPLL_SDM_RSTN_MASK	BIT(5)
+#define ROPLL_SDM_RSTN_MASK		BIT(4)
+#define ROPLL_SDC_FRAC_EN_RBR_MASK	BIT(3)
+#define ROPLL_SDC_FRAC_EN_HBR_MASK	BIT(2)
+#define ROPLL_SDC_FRAC_EN_HBR2_MASK	BIT(1)
+/* CMN_REG(005f) */
+#define OVRD_ROPLL_SDC_RSTN_MASK	BIT(5)
+#define ROPLL_SDC_RSTN_MASK		BIT(4)
+/* CMN_REG(0060)  */
+#define ROPLL_SDM_DENOMINATOR_MASK	GENMASK(7, 0)
 /* CMN_REG(0064) */
 #define ROPLL_SDM_NUM_SIGN_RBR_MASK	BIT(3)
+#define ROPLL_SDM_NUM_SIGN_HBR_MASK	BIT(2)
+#define ROPLL_SDM_NUM_SIGN_HBR2_MASK	BIT(1)
+/* CMN_REG(0065) */
+#define ROPLL_SDM_NUM_MASK		GENMASK(7, 0)
 /* CMN_REG(0069) */
 #define ROPLL_SDC_N_RBR_MASK		GENMASK(2, 0)
+/* CMN_REG(006a) */
+#define ROPLL_SDC_N_HBR_MASK		GENMASK(5, 3)
+#define ROPLL_SDC_N_HBR2_MASK		GENMASK(2, 0)
+/* CMN_REG(006b) */
+#define ROPLL_SDC_N_HBR3_MASK		GENMASK(3, 1)
+/* CMN_REG(006c) */
+#define ROPLL_SDC_NUM_MASK		GENMASK(5, 0)
+/* cmn_reg0070 */
+#define ROPLL_SDC_DENO_MASK		GENMASK(5, 0)
 /* CMN_REG(0074) */
-#define ROPLL_SDC_NDIV_RSTN		BIT(2)
-#define ROPLL_SSC_EN			BIT(0)
+#define OVRD_ROPLL_SDC_NDIV_RSTN_MASK	BIT(3)
+#define ROPLL_SDC_NDIV_RSTN_MASK	BIT(2)
+#define OVRD_ROPLL_SSC_EN_MASK		BIT(1)
+#define ROPLL_SSC_EN_MASK		BIT(0)
+/* CMN_REG(0075) */
+#define ANA_ROPLL_SSC_FM_DEVIATION_MASK	GENMASK(5, 0)
+/* CMN_REG(0076) */
+#define ANA_ROPLL_SSC_FM_FREQ_MASK	GENMASK(6, 2)
+/* CMN_REG(0077) */
+#define ANA_ROPLL_SSC_CLK_DIV_SEL_MASK	GENMASK(6, 3)
 /* CMN_REG(0081) */
-#define OVRD_PLL_CD_CLK_EN		BIT(8)
-#define PLL_CD_HSCLK_EAST_EN		BIT(0)
+#define ANA_PLL_CD_TX_SER_RATE_SEL_MASK	BIT(3)
+#define ANA_PLL_CD_HSCLK_WEST_EN_MASK	BIT(1)
+#define ANA_PLL_CD_HSCLK_EAST_EN_MASK	BIT(0)
+/* CMN_REG(0082) */
+#define ANA_PLL_CD_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
+/* CMN_REG(0083) */
+#define ANA_PLL_CD_VREG_ICTRL_MASK	GENMASK(6, 5)
+/* CMN_REG(0084) */
+#define PLL_LCRO_CLK_SEL_MASK		BIT(5)
+/* CMN_REG(0085) */
+#define ANA_PLL_SYNC_LOSS_DET_MODE_MASK	GENMASK(1, 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)
+#define ANA_PLL_FRL_MODE_EN_MASK	BIT(3)
+#define ANA_PLL_TX_HS_CLK_EN_MASK	BIT(2)
 /* CMN_REG(0089) */
 #define LCPLL_ALONE_MODE		BIT(1)
+/* CMN_REG(0095) */
+#define DP_TX_LINK_BW_MASK		GENMASK(1, 0)
 /* CMN_REG(0097) */
-#define DIG_CLK_SEL			BIT(1)
-#define ROPLL_REF			BIT(1)
-#define LCPLL_REF			0
+#define DIG_CLK_SEL_MASK		BIT(1)
+#define LCPLL_REF			BIT(1)
+#define ROPLL_REF			0
 /* CMN_REG(0099) */
+#define SSC_EN_MASK			GENMASK(7, 6)
 #define CMN_ROPLL_ALONE_MODE		BIT(2)
 #define ROPLL_ALONE_MODE		BIT(2)
 /* CMN_REG(009a) */
-#define HS_SPEED_SEL			BIT(0)
+#define HS_SPEED_SEL_MASK		BIT(0)
 #define DIV_10_CLOCK			BIT(0)
 /* CMN_REG(009b) */
-#define IS_SPEED_SEL			BIT(4)
+#define LS_SPEED_SEL_MASK		BIT(4)
 #define LINK_SYMBOL_CLOCK		BIT(4)
 #define LINK_SYMBOL_CLOCK1_2		0
 
@@ -118,6 +181,8 @@
 /* SB_REG(0104) */
 #define OVRD_SB_EN_MASK			BIT(5)
 #define SB_EN_MASK			BIT(4)
+#define OVRD_SB_AUX_EN_MASK		BIT(1)
+#define SB_AUX_EN_MASK			BIT(0)
 /* SB_REG(0105) */
 #define OVRD_SB_EARC_CMDC_EN_MASK	BIT(6)
 #define SB_EARC_CMDC_EN_MASK		BIT(5)
@@ -126,6 +191,8 @@
 #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(010d) */
+#define ANA_SB_DMRX_LPBK_DATA_MASK	BIT(4)
 /* SB_REG(010f) */
 #define OVRD_SB_VREG_EN_MASK		BIT(7)
 #define SB_VREG_EN_MASK			BIT(6)
@@ -133,6 +200,7 @@
 #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_OUT_SEL_MASK	BIT(1)
 #define ANA_SB_VREG_REF_SEL_MASK	BIT(0)
 /* SB_REG(0113) */
 #define SB_RX_RCAL_OPT_CODE_MASK	GENMASK(5, 4)
@@ -147,13 +215,24 @@
 #define AFC_RSTN_DELAY_TIME_MASK	GENMASK(6, 4)
 /* SB_REG(0117) */
 #define FAST_PULSE_TIME_MASK		GENMASK(3, 0)
+/* SB_REG(0118) */
+#define SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK	GENMASK(7, 0)
+/* SB_REG(011a) */
+#define SB_TG_CNT_RUN_NO_7_0_MASK	GENMASK(7, 0)
 /* SB_REG(011b) */
 #define SB_EARC_SIG_DET_BYPASS_MASK	BIT(4)
 #define SB_AFC_TOL_MASK			GENMASK(3, 0)
+/* SB_REG(011c) */
+#define SB_AFC_STB_NUM_MASK		GENMASK(3, 0)
+/* SB_REG(011d) */
+#define SB_TG_OSC_CNT_MIN_MASK		GENMASK(7, 0)
+/* SB_REG(011e) */
+#define SB_TG_OSC_CNT_MAX_MASK		GENMASK(7, 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_AUX_EN_IN_MASK		BIT(7)
 #define SB_EARC_EN_MASK			BIT(1)
 #define SB_EARC_AFC_EN_MASK		BIT(2)
 /* SB_REG(0123) */
@@ -165,35 +244,65 @@
 #define HDMI_MODE			BIT(2)
 #define HDMI_TMDS_FRL_SEL		BIT(1)
 /* LNTOP_REG(0206) */
-#define DATA_BUS_SEL			BIT(0)
+#define DATA_BUS_WIDTH_MASK		GENMASK(2, 1)
+#define DATA_BUS_WIDTH_SEL_MASK		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)
+/* LANE_REG(0301) */
+#define OVRD_LN_TX_DRV_EI_EN_MASK	BIT(7)
+#define LN_TX_DRV_EI_EN_MASK		BIT(6)
+/* LANE_REG(0303) */
+#define OVRD_LN_TX_DRV_LVL_CTRL_MASK	BIT(5)
+#define LN_TX_DRV_LVL_CTRL_MASK		GENMASK(4, 0)
+/* LANE_REG(0304)  */
+#define OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK	BIT(4)
+#define LN_TX_DRV_POST_LVL_CTRL_MASK	GENMASK(3, 0)
+/* LANE_REG(0305) */
+#define OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK	BIT(6)
+#define LN_TX_DRV_PRE_LVL_CTRL_MASK	GENMASK(5, 2)
+/* LANE_REG(0306) */
+#define LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK	GENMASK(7, 5)
+#define LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK	GENMASK(4, 2)
+#define LN_ANA_TX_DRV_ACCDRV_EN_MASK	BIT(0)
+/* LANE_REG(0307) */
+#define LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK	BIT(6)
+#define LN_ANA_TX_DRV_ACCDRV_CTRL_MASK	GENMASK(5, 3)
+/* LANE_REG(030a) */
+#define LN_ANA_TX_JEQ_EN_MASK		BIT(4)
+#define LN_TX_JEQ_EVEN_CTRL_RBR_MASK	GENMASK(3, 0)
+/* LANE_REG(030b) */
+#define LN_TX_JEQ_EVEN_CTRL_HBR_MASK	GENMASK(7, 4)
+#define LN_TX_JEQ_EVEN_CTRL_HBR2_MASK	GENMASK(3, 0)
+/* LANE_REG(030c) */
+#define LN_TX_JEQ_ODD_CTRL_RBR_MASK	GENMASK(3, 0)
+/* LANE_REG(030d) */
+#define LN_TX_JEQ_ODD_CTRL_HBR_MASK	GENMASK(7, 4)
+#define LN_TX_JEQ_ODD_CTRL_HBR2_MASK	GENMASK(3, 0)
+/* LANE_REG(0310) */
+#define LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK	GENMASK(1, 0)
+/* LANE_REG(0311) */
+#define LN_TX_SER_40BIT_EN_RBR_MASK	BIT(3)
+#define LN_TX_SER_40BIT_EN_HBR_MASK	BIT(2)
+#define LN_TX_SER_40BIT_EN_HBR2_MASK	BIT(1)
+/* LANE_REG(0316) */
+#define LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
+/* LANE_REG(031B) */
+#define LN_ANA_TX_RESERVED_MASK		GENMASK(7, 0)
+/* LANE_REG(031e) */
+#define LN_POLARITY_INV_MASK		BIT(2)
+#define LN_LANE_MODE_MASK		BIT(1)
 
 #define HDMI20_MAX_RATE			600000000
 
+enum dp_link_rate {
+	DP_BW_RBR,
+	DP_BW_HBR,
+	DP_BW_HBR2,
+};
+
 struct lcpll_config {
 	u32 bit_rate;
 	u8 lcvco_mode_en;
@@ -255,6 +364,19 @@ struct ropll_config {
 	u8 cd_tx_ser_rate_sel;
 };
 
+struct tx_drv_ctrl {
+	u8 tx_drv_lvl_ctrl;
+	u8 tx_drv_post_lvl_ctrl;
+	u8 ana_tx_drv_idrv_idn_ctrl;
+	u8 ana_tx_drv_idrv_iup_ctrl;
+	u8 ana_tx_drv_accdrv_en;
+	u8 ana_tx_drv_accdrv_ctrl;
+	u8 tx_drv_pre_lvl_ctrl;
+	u8 ana_tx_jeq_en;
+	u8 tx_jeq_even_ctrl;
+	u8 tx_jeq_odd_ctrl;
+};
+
 enum rk_hdptx_reset {
 	RST_PHY = 0,
 	RST_APB,
@@ -560,6 +682,90 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0606), 0x1c),
 };
 
+static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = {
+	/* voltage swing 0, pre-emphasis 0->3 */
+	{
+		{ 0x2, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0x4, 0x3, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0x7, 0x6, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 1, pre-emphasis 0->2 */
+	{
+		{ 0x4, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0x9, 0x5, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xc, 0x8, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 2, pre-emphasis 0->1 */
+	{
+		{ 0x8, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xc, 0x5, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 3, pre-emphasis 0 */
+	{
+		{ 0xb, 0x0, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
+	}
+};
+
+static struct tx_drv_ctrl tx_drv_ctrl_hbr[4][4] = {
+	/* voltage swing 0, pre-emphasis 0->3 */
+	{
+		{ 0x2, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0x5, 0x4, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0x9, 0x8, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 1, pre-emphasis 0->2 */
+	{
+		{ 0x6, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xa, 0x6, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xc, 0x8, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 2, pre-emphasis 0->1 */
+	{
+		{ 0x9, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xd, 0x6, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 3, pre-emphasis 0 */
+	{
+		{ 0xc, 0x1, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
+	}
+};
+
+static struct tx_drv_ctrl tx_drv_ctrl_hbr2[4][4] = {
+	/* voltage swing 0, pre-emphasis 0->3 */
+	{
+		{ 0x2, 0x1, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0x5, 0x4, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0x9, 0x8, 0x4, 0x6, 0x1, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 1, pre-emphasis 0->2 */
+	{
+		{ 0x6, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xb, 0x7, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xd, 0x9, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 2, pre-emphasis 0->1 */
+	{
+		{ 0x8, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xc, 0x6, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 3, pre-emphasis 0 */
+	{
+		{ 0xb, 0x0, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
+	}
+};
+
 static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
@@ -911,11 +1117,297 @@ static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)
 	return ret;
 }
 
+static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx)
+{
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+	reset_control_assert(hdptx->rsts[RST_APB].rstc);
+	udelay(10);
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(0301),
+			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
+			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0401),
+			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
+			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0501),
+			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
+			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0601),
+			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
+			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x0));
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x0));
+}
+
+static void rk_hdptx_dp_pll_init(struct rk_hdptx_phy *hdptx)
+{
+	regmap_update_bits(hdptx->regmap, CMN_REG(003c), ANA_LCPLL_RESERVED7_MASK,
+			   FIELD_PREP(ANA_LCPLL_RESERVED7_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0046),
+			   ROPLL_ANA_CPP_CTRL_COARSE_MASK | ROPLL_ANA_CPP_CTRL_FINE_MASK,
+			   FIELD_PREP(ROPLL_ANA_CPP_CTRL_COARSE_MASK, 0xe) |
+			   FIELD_PREP(ROPLL_ANA_CPP_CTRL_FINE_MASK, 0xe));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0047),
+			   ROPLL_ANA_LPF_C_SEL_COARSE_MASK |
+			   ROPLL_ANA_LPF_C_SEL_FINE_MASK,
+			   FIELD_PREP(ROPLL_ANA_LPF_C_SEL_COARSE_MASK, 0x4) |
+			   FIELD_PREP(ROPLL_ANA_LPF_C_SEL_FINE_MASK, 0x4));
+
+	regmap_write(hdptx->regmap, CMN_REG(0051), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x87));
+	regmap_write(hdptx->regmap, CMN_REG(0052), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x71));
+	regmap_write(hdptx->regmap, CMN_REG(0053), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x71));
+
+	regmap_write(hdptx->regmap, CMN_REG(0055),
+		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x87));
+	regmap_write(hdptx->regmap, CMN_REG(0056),
+		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x71));
+	regmap_write(hdptx->regmap, CMN_REG(0057),
+		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x71));
+
+	regmap_write(hdptx->regmap, CMN_REG(0059),
+		     FIELD_PREP(ANA_ROPLL_PMS_PDIV_MASK, 0x1) |
+		     FIELD_PREP(ANA_ROPLL_PMS_REFDIV_MASK, 0x1));
+	regmap_write(hdptx->regmap, CMN_REG(005a),
+		     FIELD_PREP(ROPLL_PMS_SDIV_RBR_MASK, 0x3) |
+		     FIELD_PREP(ROPLL_PMS_SDIV_HBR_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005b), ROPLL_PMS_SDIV_HBR2_MASK,
+			   FIELD_PREP(ROPLL_PMS_SDIV_HBR2_MASK, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,
+			   FIELD_PREP(ROPLL_SDM_EN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e),
+			   OVRD_ROPLL_SDM_RSTN_MASK | ROPLL_SDM_RSTN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_SDM_RSTN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDM_RSTN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_RBR_MASK,
+			   FIELD_PREP(ROPLL_SDC_FRAC_EN_RBR_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_HBR_MASK,
+			   FIELD_PREP(ROPLL_SDC_FRAC_EN_HBR_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_HBR2_MASK,
+			   FIELD_PREP(ROPLL_SDC_FRAC_EN_HBR2_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(005f),
+			   OVRD_ROPLL_SDC_RSTN_MASK | ROPLL_SDC_RSTN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_SDC_RSTN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDC_RSTN_MASK, 0x1));
+	regmap_write(hdptx->regmap, CMN_REG(0060),
+		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x21));
+	regmap_write(hdptx->regmap, CMN_REG(0061),
+		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x27));
+	regmap_write(hdptx->regmap, CMN_REG(0062),
+		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x27));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0064),
+			   ROPLL_SDM_NUM_SIGN_RBR_MASK |
+			   ROPLL_SDM_NUM_SIGN_HBR_MASK |
+			   ROPLL_SDM_NUM_SIGN_HBR2_MASK,
+			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, 0x0) |
+			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_HBR_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_HBR2_MASK, 0x1));
+	regmap_write(hdptx->regmap, CMN_REG(0065),
+		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0x0));
+	regmap_write(hdptx->regmap, CMN_REG(0066),
+		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0xd));
+	regmap_write(hdptx->regmap, CMN_REG(0067),
+		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0xd));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
+			   FIELD_PREP(ROPLL_SDC_N_RBR_MASK, 0x2));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(006a),
+			   ROPLL_SDC_N_HBR_MASK | ROPLL_SDC_N_HBR2_MASK,
+			   FIELD_PREP(ROPLL_SDC_N_HBR_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDC_N_HBR2_MASK, 0x1));
+
+	regmap_write(hdptx->regmap, CMN_REG(006c),
+		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x3));
+	regmap_write(hdptx->regmap, CMN_REG(006d),
+		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x7));
+	regmap_write(hdptx->regmap, CMN_REG(006e),
+		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x7));
+
+	regmap_write(hdptx->regmap, CMN_REG(0070),
+		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x8));
+	regmap_write(hdptx->regmap, CMN_REG(0071),
+		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x18));
+	regmap_write(hdptx->regmap, CMN_REG(0072),
+		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x18));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0074),
+			   OVRD_ROPLL_SDC_NDIV_RSTN_MASK | ROPLL_SDC_NDIV_RSTN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_SDC_NDIV_RSTN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDC_NDIV_RSTN_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0077), ANA_ROPLL_SSC_CLK_DIV_SEL_MASK,
+			   FIELD_PREP(ANA_ROPLL_SSC_CLK_DIV_SEL_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0081), ANA_PLL_CD_TX_SER_RATE_SEL_MASK,
+			   FIELD_PREP(ANA_PLL_CD_TX_SER_RATE_SEL_MASK, 0x0));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0081),
+			   ANA_PLL_CD_HSCLK_EAST_EN_MASK | ANA_PLL_CD_HSCLK_WEST_EN_MASK,
+			   FIELD_PREP(ANA_PLL_CD_HSCLK_EAST_EN_MASK, 0x1) |
+			   FIELD_PREP(ANA_PLL_CD_HSCLK_WEST_EN_MASK, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0082), ANA_PLL_CD_VREG_GAIN_CTRL_MASK,
+			   FIELD_PREP(ANA_PLL_CD_VREG_GAIN_CTRL_MASK, 0x4));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0083), ANA_PLL_CD_VREG_ICTRL_MASK,
+			   FIELD_PREP(ANA_PLL_CD_VREG_ICTRL_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0084), PLL_LCRO_CLK_SEL_MASK,
+			   FIELD_PREP(PLL_LCRO_CLK_SEL_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0085), ANA_PLL_SYNC_LOSS_DET_MODE_MASK,
+			   FIELD_PREP(ANA_PLL_SYNC_LOSS_DET_MODE_MASK, 0x3));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0087), ANA_PLL_TX_HS_CLK_EN_MASK,
+			   FIELD_PREP(ANA_PLL_TX_HS_CLK_EN_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0097), DIG_CLK_SEL_MASK,
+			   FIELD_PREP(DIG_CLK_SEL_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0099), CMN_ROPLL_ALONE_MODE,
+			   FIELD_PREP(CMN_ROPLL_ALONE_MODE, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(009a), HS_SPEED_SEL_MASK,
+			   FIELD_PREP(HS_SPEED_SEL_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(009b), LS_SPEED_SEL_MASK,
+			   FIELD_PREP(LS_SPEED_SEL_MASK, 0x1));
+}
+
+static int rk_hdptx_dp_aux_init(struct rk_hdptx_phy *hdptx)
+{
+	u32 status;
+	int ret;
+
+	regmap_update_bits(hdptx->regmap, SB_REG(0102), ANA_SB_RXTERM_OFFSP_MASK,
+			   FIELD_PREP(ANA_SB_RXTERM_OFFSP_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(0103), ANA_SB_RXTERM_OFFSN_MASK,
+			   FIELD_PREP(ANA_SB_RXTERM_OFFSN_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_AUX_EN_MASK,
+			   FIELD_PREP(SB_AUX_EN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0105), ANA_SB_TX_HLVL_PROG_MASK,
+			   FIELD_PREP(ANA_SB_TX_HLVL_PROG_MASK, 0x7));
+	regmap_update_bits(hdptx->regmap, SB_REG(0106), ANA_SB_TX_LLVL_PROG_MASK,
+			   FIELD_PREP(ANA_SB_TX_LLVL_PROG_MASK, 0x7));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(010d), ANA_SB_DMRX_LPBK_DATA_MASK,
+			   FIELD_PREP(ANA_SB_DMRX_LPBK_DATA_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(010f), ANA_SB_VREG_GAIN_CTRL_MASK,
+			   FIELD_PREP(ANA_SB_VREG_GAIN_CTRL_MASK, 0x0));
+	regmap_update_bits(hdptx->regmap, SB_REG(0110),
+			   ANA_SB_VREG_OUT_SEL_MASK | ANA_SB_VREG_REF_SEL_MASK,
+			   FIELD_PREP(ANA_SB_VREG_OUT_SEL_MASK, 0x1) |
+			   FIELD_PREP(ANA_SB_VREG_REF_SEL_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(0113),
+			   SB_RX_RCAL_OPT_CODE_MASK | SB_RX_RTERM_CTRL_MASK,
+			   FIELD_PREP(SB_RX_RCAL_OPT_CODE_MASK, 0x1) |
+			   FIELD_PREP(SB_RX_RTERM_CTRL_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(0114),
+			   SB_TG_SB_EN_DELAY_TIME_MASK | SB_TG_RXTERM_EN_DELAY_TIME_MASK,
+			   FIELD_PREP(SB_TG_SB_EN_DELAY_TIME_MASK, 0x2) |
+			   FIELD_PREP(SB_TG_RXTERM_EN_DELAY_TIME_MASK, 0x2));
+	regmap_update_bits(hdptx->regmap, SB_REG(0115),
+			   SB_READY_DELAY_TIME_MASK | SB_TG_OSC_EN_DELAY_TIME_MASK,
+			   FIELD_PREP(SB_READY_DELAY_TIME_MASK, 0x2) |
+			   FIELD_PREP(SB_TG_OSC_EN_DELAY_TIME_MASK, 0x2));
+	regmap_update_bits(hdptx->regmap, SB_REG(0116),
+			   AFC_RSTN_DELAY_TIME_MASK,
+			   FIELD_PREP(AFC_RSTN_DELAY_TIME_MASK, 0x2));
+	regmap_update_bits(hdptx->regmap, SB_REG(0117),
+			   FAST_PULSE_TIME_MASK,
+			   FIELD_PREP(FAST_PULSE_TIME_MASK, 0x4));
+	regmap_update_bits(hdptx->regmap, SB_REG(0118),
+			   SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK,
+			   FIELD_PREP(SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK, 0xa));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(011a), SB_TG_CNT_RUN_NO_7_0_MASK,
+			   FIELD_PREP(SB_TG_CNT_RUN_NO_7_0_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(011b),
+			   SB_EARC_SIG_DET_BYPASS_MASK | SB_AFC_TOL_MASK,
+			   FIELD_PREP(SB_EARC_SIG_DET_BYPASS_MASK, 0x1) |
+			   FIELD_PREP(SB_AFC_TOL_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(011c), SB_AFC_STB_NUM_MASK,
+			   FIELD_PREP(SB_AFC_STB_NUM_MASK, 0x4));
+	regmap_update_bits(hdptx->regmap, SB_REG(011d), SB_TG_OSC_CNT_MIN_MASK,
+			   FIELD_PREP(SB_TG_OSC_CNT_MIN_MASK, 0x67));
+	regmap_update_bits(hdptx->regmap, SB_REG(011e), SB_TG_OSC_CNT_MAX_MASK,
+			   FIELD_PREP(SB_TG_OSC_CNT_MAX_MASK, 0x6a));
+	regmap_update_bits(hdptx->regmap, SB_REG(011f), SB_PWM_AFC_CTRL_MASK,
+			   FIELD_PREP(SB_PWM_AFC_CTRL_MASK, 0x5));
+	regmap_update_bits(hdptx->regmap, SB_REG(011f), SB_RCAL_RSTN_MASK,
+			   FIELD_PREP(SB_RCAL_RSTN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0120), SB_AUX_EN_IN_MASK,
+			   FIELD_PREP(SB_AUX_EN_IN_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(0102), OVRD_SB_RXTERM_EN_MASK,
+			   FIELD_PREP(OVRD_SB_RXTERM_EN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK,
+			   FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_EN_MASK,
+			   FIELD_PREP(OVRD_SB_EN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_AUX_EN_MASK,
+			   FIELD_PREP(OVRD_SB_AUX_EN_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(010f), OVRD_SB_VREG_EN_MASK,
+			   FIELD_PREP(OVRD_SB_VREG_EN_MASK, 0x1));
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x1));
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x1));
+	usleep_range(20, 25);
+
+	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+	usleep_range(20, 25);
+	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+	usleep_range(20, 25);
+
+	regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK,
+			   FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 0x1));
+	usleep_range(100, 110);
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_EN_MASK,
+			   FIELD_PREP(SB_EN_MASK, 0x1));
+	usleep_range(100, 110);
+	regmap_update_bits(hdptx->regmap, SB_REG(0102), SB_RXTERM_EN_MASK,
+			   FIELD_PREP(SB_RXTERM_EN_MASK, 0x1));
+	usleep_range(20, 25);
+	regmap_update_bits(hdptx->regmap, SB_REG(010f), SB_VREG_EN_MASK,
+			   FIELD_PREP(SB_VREG_EN_MASK, 0x1));
+	usleep_range(20, 25);
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_AUX_EN_MASK,
+			   FIELD_PREP(SB_AUX_EN_MASK, 0x1));
+	usleep_range(100, 110);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
+				       status, FIELD_GET(HDPTX_O_SB_RDY, status),
+				       50, 1000);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get phy sb ready: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int rk_hdptx_phy_power_on(struct phy *phy)
 {
 	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
 	int bus_width = phy_get_bus_width(hdptx->phy);
-	int ret;
+	enum phy_mode mode = phy_get_mode(phy);
+	int ret, lane;
 
 	/*
 	 * FIXME: Temporary workaround to pass pixel_clk_rate
@@ -927,13 +1419,43 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
 		__func__, bus_width, rate);
 
-	ret = rk_hdptx_phy_consumer_get(hdptx, rate);
-	if (ret)
-		return ret;
+	if (mode == PHY_MODE_DP) {
+		rk_hdptx_dp_reset(hdptx);
 
-	ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
-	if (ret)
-		rk_hdptx_phy_consumer_put(hdptx, true);
+		for (lane = 0; lane < 4; lane++) {
+			regmap_update_bits(hdptx->regmap, LANE_REG(031e) + 0x400 * lane,
+					   LN_POLARITY_INV_MASK | LN_LANE_MODE_MASK,
+					   FIELD_PREP(LN_POLARITY_INV_MASK, 0) |
+					   FIELD_PREP(LN_LANE_MODE_MASK, 1));
+		}
+
+		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x1));
+
+		regmap_update_bits(hdptx->regmap, LNTOP_REG(0200), PROTOCOL_SEL,
+				   FIELD_PREP(PROTOCOL_SEL, 0x0));
+		regmap_update_bits(hdptx->regmap, LNTOP_REG(0206), DATA_BUS_WIDTH_MASK,
+				   FIELD_PREP(DATA_BUS_WIDTH_MASK, 0x1));
+		regmap_update_bits(hdptx->regmap, LNTOP_REG(0206), DATA_BUS_WIDTH_SEL_MASK,
+				   FIELD_PREP(DATA_BUS_WIDTH_SEL_MASK, 0x0));
+
+		rk_hdptx_dp_pll_init(hdptx);
+
+		ret = rk_hdptx_dp_aux_init(hdptx);
+		if (ret)
+			pm_runtime_put(hdptx->dev);
+	} else {
+		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
+
+		ret = rk_hdptx_phy_consumer_get(hdptx, rate);
+		if (ret)
+			return ret;
+
+		ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
+		if (ret)
+			rk_hdptx_phy_consumer_put(hdptx, true);
+	}
 
 	return ret;
 }
@@ -945,9 +1467,337 @@ static int rk_hdptx_phy_power_off(struct phy *phy)
 	return rk_hdptx_phy_consumer_put(hdptx, false);
 }
 
+static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode,
+				 int submode)
+{
+	return 0;
+}
+
+static int rk_hdptx_phy_verify_config(struct rk_hdptx_phy *hdptx,
+				      struct phy_configure_opts_dp *dp)
+{
+	int i;
+
+	if (dp->set_rate) {
+		switch (dp->link_rate) {
+		case 1620:
+		case 2700:
+		case 5400:
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	if (dp->set_lanes) {
+		switch (dp->lanes) {
+		case 0:
+		case 1:
+		case 2:
+		case 4:
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	if (dp->set_voltages) {
+		for (i = 0; i < dp->lanes; i++) {
+			if (dp->voltage[i] > 3 || dp->pre[i] > 3)
+				return -EINVAL;
+
+			if (dp->voltage[i] + dp->pre[i] > 3)
+				return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int rk_hdptx_phy_set_rate(struct rk_hdptx_phy *hdptx,
+				 struct phy_configure_opts_dp *dp)
+{
+	u32 bw, status;
+	int ret;
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
+
+	switch (dp->link_rate) {
+	case 1620:
+		bw = DP_BW_RBR;
+		break;
+	case 2700:
+		bw = DP_BW_HBR;
+		break;
+	case 5400:
+		bw = DP_BW_HBR2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0008), OVRD_LCPLL_EN_MASK | LCPLL_EN_MASK,
+			   FIELD_PREP(OVRD_LCPLL_EN_MASK, 0x1) |
+			   FIELD_PREP(LCPLL_EN_MASK, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(003d), OVRD_ROPLL_EN_MASK | ROPLL_EN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_EN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_EN_MASK, 0x1));
+
+	if (dp->ssc) {
+		regmap_update_bits(hdptx->regmap, CMN_REG(0074),
+				   OVRD_ROPLL_SSC_EN_MASK | ROPLL_SSC_EN_MASK,
+				   FIELD_PREP(OVRD_ROPLL_SSC_EN_MASK, 0x1) |
+				   FIELD_PREP(ROPLL_SSC_EN_MASK, 0x1));
+		regmap_write(hdptx->regmap, CMN_REG(0075),
+			     FIELD_PREP(ANA_ROPLL_SSC_FM_DEVIATION_MASK, 0xc));
+		regmap_update_bits(hdptx->regmap, CMN_REG(0076),
+				   ANA_ROPLL_SSC_FM_FREQ_MASK,
+				   FIELD_PREP(ANA_ROPLL_SSC_FM_FREQ_MASK, 0x1f));
+
+		regmap_update_bits(hdptx->regmap, CMN_REG(0099), SSC_EN_MASK,
+				   FIELD_PREP(SSC_EN_MASK, 0x2));
+	} else {
+		regmap_update_bits(hdptx->regmap, CMN_REG(0074),
+				   OVRD_ROPLL_SSC_EN_MASK | ROPLL_SSC_EN_MASK,
+				   FIELD_PREP(OVRD_ROPLL_SSC_EN_MASK, 0x1) |
+				   FIELD_PREP(ROPLL_SSC_EN_MASK, 0x0));
+		regmap_write(hdptx->regmap, CMN_REG(0075),
+			     FIELD_PREP(ANA_ROPLL_SSC_FM_DEVIATION_MASK, 0x20));
+		regmap_update_bits(hdptx->regmap, CMN_REG(0076),
+				   ANA_ROPLL_SSC_FM_FREQ_MASK,
+				   FIELD_PREP(ANA_ROPLL_SSC_FM_FREQ_MASK, 0xc));
+
+		regmap_update_bits(hdptx->regmap, CMN_REG(0099), SSC_EN_MASK,
+				   FIELD_PREP(SSC_EN_MASK, 0x0));
+	}
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0095), DP_TX_LINK_BW_MASK,
+			   FIELD_PREP(DP_TX_LINK_BW_MASK, bw));
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x1));
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
+				       status, FIELD_GET(HDPTX_O_PLL_LOCK_DONE, status),
+				       50, 1000);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get phy pll lock: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void rk_hdptx_phy_lane_disable(struct rk_hdptx_phy *hdptx)
+{
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+
+	regmap_update_bits(hdptx->regmap, LNTOP_REG(0207), LANE_EN,
+			   FIELD_PREP(LANE_EN, 0x0));
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0008), OVRD_LCPLL_EN_MASK | LCPLL_EN_MASK,
+			   FIELD_PREP(OVRD_LCPLL_EN_MASK, 0x1) |
+			   FIELD_PREP(LCPLL_EN_MASK, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(003d), OVRD_ROPLL_EN_MASK | ROPLL_EN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_EN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_EN_MASK, 0x0));
+}
+
+static int rk_hdptx_phy_set_lanes(struct rk_hdptx_phy *hdptx,
+				  struct phy_configure_opts_dp *dp)
+{
+	if (!dp->lanes) {
+		rk_hdptx_phy_lane_disable(hdptx);
+		return 0;
+	}
+
+	regmap_update_bits(hdptx->regmap, LNTOP_REG(0207), LANE_EN,
+			   FIELD_PREP(LANE_EN, GENMASK(dp->lanes - 1, 0)));
+
+	return 0;
+}
+
+static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
+				     struct phy_configure_opts_dp *dp,
+				     u8 lane)
+{
+	const struct tx_drv_ctrl *ctrl;
+	u32 offset = lane * 0x400;
+
+	switch (dp->link_rate) {
+	case 1620:
+		ctrl = &tx_drv_ctrl_rbr[dp->voltage[lane]][dp->pre[lane]];
+		regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
+				   LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
+				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
+				   ctrl->tx_jeq_even_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(030c) + offset,
+				   LN_TX_JEQ_ODD_CTRL_RBR_MASK,
+				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_RBR_MASK,
+				   ctrl->tx_jeq_odd_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
+				   LN_TX_SER_40BIT_EN_RBR_MASK,
+				   FIELD_PREP(LN_TX_SER_40BIT_EN_RBR_MASK, 0x1));
+		break;
+	case 2700:
+		ctrl = &tx_drv_ctrl_hbr[dp->voltage[lane]][dp->pre[lane]];
+		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
+				   LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
+				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
+				   ctrl->tx_jeq_even_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
+				   LN_TX_JEQ_ODD_CTRL_HBR_MASK,
+				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR_MASK,
+				   ctrl->tx_jeq_odd_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
+				   LN_TX_SER_40BIT_EN_HBR_MASK,
+				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR_MASK, 0x1));
+		break;
+	case 5400:
+	default:
+		ctrl = &tx_drv_ctrl_hbr2[dp->voltage[lane]][dp->pre[lane]];
+		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
+				   LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
+				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
+				   ctrl->tx_jeq_even_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
+				   LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
+				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
+				   ctrl->tx_jeq_odd_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
+				   LN_TX_SER_40BIT_EN_HBR2_MASK,
+				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1));
+		break;
+	}
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(0303) + offset,
+			   OVRD_LN_TX_DRV_LVL_CTRL_MASK | LN_TX_DRV_LVL_CTRL_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_LVL_CTRL_MASK, 0x1) |
+			   FIELD_PREP(LN_TX_DRV_LVL_CTRL_MASK,
+				      ctrl->tx_drv_lvl_ctrl));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0304) + offset,
+			   OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK |
+			   LN_TX_DRV_POST_LVL_CTRL_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK, 0x1) |
+			   FIELD_PREP(LN_TX_DRV_POST_LVL_CTRL_MASK,
+				      ctrl->tx_drv_post_lvl_ctrl));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0305) + offset,
+			   OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK |
+			   LN_TX_DRV_PRE_LVL_CTRL_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK, 0x1) |
+			   FIELD_PREP(LN_TX_DRV_PRE_LVL_CTRL_MASK,
+				      ctrl->tx_drv_pre_lvl_ctrl));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0306) + offset,
+			   LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK |
+			   LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK |
+			   LN_ANA_TX_DRV_ACCDRV_EN_MASK,
+			   FIELD_PREP(LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK,
+				      ctrl->ana_tx_drv_idrv_idn_ctrl) |
+			   FIELD_PREP(LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK,
+				      ctrl->ana_tx_drv_idrv_iup_ctrl) |
+			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_EN_MASK,
+				      ctrl->ana_tx_drv_accdrv_en));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0307) + offset,
+			   LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK |
+			   LN_ANA_TX_DRV_ACCDRV_CTRL_MASK,
+			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK, 0x1) |
+			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_CTRL_MASK,
+				      ctrl->ana_tx_drv_accdrv_ctrl));
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
+			   LN_ANA_TX_JEQ_EN_MASK,
+			   FIELD_PREP(LN_ANA_TX_JEQ_EN_MASK, ctrl->ana_tx_jeq_en));
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(0310) + offset,
+			   LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK,
+			   FIELD_PREP(LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK, 0x3));
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(0316) + offset,
+			   LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK,
+			   FIELD_PREP(LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK, 0x2));
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(031b) + offset,
+			   LN_ANA_TX_RESERVED_MASK,
+			   FIELD_PREP(LN_ANA_TX_RESERVED_MASK, 0x1));
+}
+
+static int rk_hdptx_phy_set_voltages(struct rk_hdptx_phy *hdptx,
+				     struct phy_configure_opts_dp *dp)
+{
+	u8 lane;
+	u32 status;
+	int ret;
+
+	for (lane = 0; lane < dp->lanes; lane++)
+		rk_hdptx_phy_set_voltage(hdptx, dp, lane);
+
+	reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
+				       status, FIELD_GET(HDPTX_O_PHY_RDY, status),
+				       50, 5000);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get phy ready: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
+	enum phy_mode mode = phy_get_mode(phy);
+	int ret;
+
+	if (mode != PHY_MODE_DP)
+		return -EINVAL;
+
+	ret = rk_hdptx_phy_verify_config(hdptx, &opts->dp);
+	if (ret) {
+		dev_err(hdptx->dev, "invalid params for phy configure\n");
+		return ret;
+	}
+
+	if (opts->dp.set_rate) {
+		ret = rk_hdptx_phy_set_rate(hdptx, &opts->dp);
+		if (ret) {
+			dev_err(hdptx->dev, "failed to set rate: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (opts->dp.set_lanes) {
+		ret = rk_hdptx_phy_set_lanes(hdptx, &opts->dp);
+		if (ret) {
+			dev_err(hdptx->dev, "failed to set lanes: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (opts->dp.set_voltages) {
+		ret = rk_hdptx_phy_set_voltages(hdptx, &opts->dp);
+		if (ret) {
+			dev_err(hdptx->dev, "failed to set voltages: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static const struct phy_ops rk_hdptx_phy_ops = {
 	.power_on  = rk_hdptx_phy_power_on,
 	.power_off = rk_hdptx_phy_power_off,
+	.set_mode  = rk_hdptx_phy_set_mode,
+	.configure = rk_hdptx_phy_configure,
 	.owner	   = THIS_MODULE,
 };
 
@@ -1164,5 +2014,6 @@ 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_AUTHOR("Damon Ding <damon.ding at rock-chips.com>");
 MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");
 MODULE_LICENSE("GPL");
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:21 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:21 +0800
Subject: [PATCH v2 07/11] dt-bindings: display: rockchip: Fix label name of hdptxphy for RK3588 HDMI TX Controller
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-8-damon.ding@rock-chips.com>

The hdptxphy is a combo transmit-PHY for HDMI2.1 TMDS Link, FRL Link, DP
and eDP Link. Therefore, it is better to name it hdptxphy0 other than
hdptxphy_hdmi0, which will be referenced by both hdmi0 and edp0 nodes.

Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 .../bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
index d8e761865f27..7a1ae31cc535 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
@@ -156,7 +156,7 @@ examples:
                      <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>,
                      <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>;
         interrupt-names = "avp", "cec", "earc", "main", "hpd";
-        phys = <&hdptxphy_hdmi0>;
+        phys = <&hdptxphy0>;
         power-domains = <&power RK3588_PD_VO1>;
         resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>;
         reset-names = "ref", "hdp";
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:22 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:22 +0800
Subject: [PATCH v2 08/11] arm64: dts: rockchip: Fix label name of hdptxphy for RK3588
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-9-damon.ding@rock-chips.com>

The hdptxphy is a combo transmit-PHY for HDMI2.1 TMDS Link, FRL Link, DP
and eDP Link. Therefore, it is better to name it hdptxphy0 other than
hdptxphy_hdmi0, which will be referenced by both hdmi0 and edp0 nodes.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi                 | 4 ++--
 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts        | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts    | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts              | 2 +-
 .../boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts      | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts                | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi            | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts       | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts               | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts          | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts            | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts      | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi           | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts            | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi          | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts              | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts              | 2 +-
 17 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index a337f3fb8377..7e125897b0cd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1386,7 +1386,7 @@ hdmi0: hdmi at fde80000 {
 			     <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>,
 			     <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "avp", "cec", "earc", "main", "hpd";
-		phys = <&hdptxphy_hdmi0>;
+		phys = <&hdptxphy0>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd
 			     &hdmim0_tx0_scl &hdmim0_tx0_sda>;
@@ -2806,7 +2806,7 @@ dmac2: dma-controller at fed10000 {
 		#dma-cells = <1>;
 	};
 
-	hdptxphy_hdmi0: phy at fed60000 {
+	hdptxphy0: phy at fed60000 {
 		compatible = "rockchip,rk3588-hdptx-phy";
 		reg = <0x0 0xfed60000 0x0 0x2000>;
 		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
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 9d525c8ff725..9eda69722665 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
@@ -129,7 +129,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
index 92f0ed83c990..d1be72eb63a4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
@@ -166,7 +166,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
index d6e464cdc536..094235d22cd1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
@@ -328,7 +328,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
index b3a04ca370bb..8171fbfd819a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
@@ -335,7 +335,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
index 90f823b2c219..ef56380530f9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
@@ -303,7 +303,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
index cb350727d116..0d9b5020acc0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
@@ -360,7 +360,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
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 9f5a38b290bf..f14e96d96207 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
@@ -296,7 +296,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index c44d001da169..a047c579c93d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -220,7 +220,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
index 3187b4918a30..795d8175e654 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
@@ -189,7 +189,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
index 9c394f733bbf..f471baca6d31 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
@@ -236,7 +236,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index 4a3aa80f2226..74a4f03e05e3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -278,7 +278,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
index 76a6e8e517e9..482f5917043f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
@@ -251,7 +251,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
index 8f034c6d494c..1463bd36b1b2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
@@ -264,7 +264,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi
index d86aeacca238..9e16960b8705 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi
@@ -197,7 +197,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 70a43432bdc5..676cc4fec269 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -334,7 +334,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 9b14d5383cdc..bf74789e3f51 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -278,7 +278,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:23 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:23 +0800
Subject: [PATCH v2 09/11] arm64: dts: rockchip: Add eDP0 node for RK3588
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-10-damon.ding@rock-chips.com>

Add support for the eDP0 output on RK3588 SoC.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 29 +++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 7e125897b0cd..240b0103c957 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1411,6 +1411,35 @@ hdmi0_out: port at 1 {
 		};
 	};
 
+	edp0: edp at fdec0000 {
+		compatible = "rockchip,rk3588-edp";
+		reg = <0x0 0xfdec0000 0x0 0x1000>;
+		clocks = <&cru CLK_EDP0_24M>, <&cru PCLK_EDP0>, <&cru CLK_EDP0_200M>;
+		clock-names = "dp", "pclk", "spdif";
+		interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>;
+		phys = <&hdptxphy0>;
+		phy-names = "dp";
+		power-domains = <&power RK3588_PD_VO1>;
+		resets = <&cru SRST_EDP0_24M>, <&cru SRST_P_EDP0>;
+		reset-names = "dp", "apb";
+		rockchip,grf = <&vo1_grf>;
+		#sound-dai-cells = <1>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			edp0_in: port at 0 {
+				reg = <0>;
+			};
+
+			edp0_out: port at 1 {
+				reg = <1>;
+			};
+		};
+	};
+
 	qos_gpu_m0: qos at fdf35000 {
 		compatible = "rockchip,rk3588-qos", "syscon";
 		reg = <0x0 0xfdf35000 0x0 0x20>;
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:17 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:17 +0800
Subject: [PATCH v2 03/11] drm/rockchip: analogix_dp: Add support for RK3588
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-4-damon.ding@rock-chips.com>

RK3588 integrates the analogix eDP 1.3 TX controller IP and the HDMI/eDP
TX Combo PHY based on a Samsung IP block, and there are also two
independent eDP display interface on RK3588 Soc.

Add just the basic support for now, i.e. RGB output up to 4K at 60Hz, without
the tests of audio, PSR and other eDP 1.3 specific features.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Add support for the other eDP output edp1
---
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 82 ++++++++++++++++---
 include/drm/bridge/analogix_dp.h              |  3 +-
 2 files changed, 74 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 871606a31ef1..4c9a55776ada 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -51,10 +51,12 @@ struct rockchip_grf_reg_field {
 /**
  * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
  * @lcdc_sel: grf register field of lcdc_sel
+ * @edp_mode: grf register field of edp_mode
  * @chip_type: specific chip type
  */
 struct rockchip_dp_chip_data {
 	const struct rockchip_grf_reg_field lcdc_sel;
+	const struct rockchip_grf_reg_field edp_mode;
 	u32	chip_type;
 };
 
@@ -134,12 +136,21 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
 		return ret;
 	}
 
+	ret = rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 1);
+	if (ret != 0)
+		DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);
+
 	return ret;
 }
 
 static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
 {
 	struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
+	int ret;
+
+	ret = rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 0);
+	if (ret != 0)
+		DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);
 
 	clk_disable_unprepare(dp->pclk);
 
@@ -203,6 +214,10 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
 	struct rockchip_dp_device *dp = encoder_to_dp(encoder);
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state;
+	struct of_endpoint endpoint;
+	struct device_node *remote_port, *remote_port_parent;
+	char name[32];
+	u32 port_id;
 	int ret;
 
 	crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
@@ -220,13 +235,27 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
 		return;
 	}
 
-	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
+	ret = drm_of_encoder_active_endpoint(dp->dev->of_node, encoder, &endpoint);
 	if (ret < 0)
 		return;
 
-	DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
+	remote_port_parent = of_graph_get_remote_port_parent(endpoint.local_node);
+	if (remote_port_parent) {
+		if (of_get_child_by_name(remote_port_parent, "ports")) {
+			remote_port = of_graph_get_remote_port(endpoint.local_node);
+			of_property_read_u32(remote_port, "reg", &port_id);
+			of_node_put(remote_port);
+			sprintf(name, "%s vp%d", remote_port_parent->full_name, port_id);
+		} else {
+			sprintf(name, "%s %s",
+				remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
+		}
+		of_node_put(remote_port_parent);
+
+		DRM_DEV_DEBUG(dp->dev, "%s output to edp\n", name);
+	}
 
-	ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, ret);
+	ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, endpoint.id);
 	if (ret != 0)
 		DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
 
@@ -396,6 +425,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
 	const struct rockchip_dp_chip_data *dp_data;
 	struct drm_panel *panel = NULL;
 	struct rockchip_dp_device *dp;
+	int id, i;
 	int ret;
 
 	dp_data = of_device_get_match_data(dev);
@@ -410,9 +440,22 @@ static int rockchip_dp_probe(struct platform_device *pdev)
 	if (!dp)
 		return -ENOMEM;
 
+	id = of_alias_get_id(dev->of_node, "edp");
+	if (id < 0)
+		id = 0;
+
+	i = 0;
+	while (is_rockchip(dp_data[i].chip_type))
+		i++;
+
+	if (id >= i) {
+		DRM_DEV_ERROR(dev, "invalid edp id: %d\n", id);
+		return -ENODEV;
+	}
+
 	dp->dev = dev;
 	dp->adp = ERR_PTR(-ENODEV);
-	dp->data = dp_data;
+	dp->data = &dp_data[id];
 	dp->plat_data.panel = panel;
 	dp->plat_data.dev_type = dp->data->chip_type;
 	dp->plat_data.power_on = rockchip_dp_poweron;
@@ -464,19 +507,38 @@ static int rockchip_dp_resume(struct device *dev)
 static DEFINE_RUNTIME_DEV_PM_OPS(rockchip_dp_pm_ops, rockchip_dp_suspend,
 		rockchip_dp_resume, NULL);
 
-static const struct rockchip_dp_chip_data rk3399_edp = {
-	.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
-	.chip_type = RK3399_EDP,
+static const struct rockchip_dp_chip_data rk3399_edp[] = {
+	{
+		.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
+		.chip_type = RK3399_EDP,
+	},
+	{ /* sentinel */ }
+};
+
+static const struct rockchip_dp_chip_data rk3288_dp[] = {
+	{
+		.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
+		.chip_type = RK3288_DP,
+	},
+	{ /* sentinel */ }
 };
 
-static const struct rockchip_dp_chip_data rk3288_dp = {
-	.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
-	.chip_type = RK3288_DP,
+static const struct rockchip_dp_chip_data rk3588_edp[] = {
+	{
+		.edp_mode = GRF_REG_FIELD(0x0000, 0, 0),
+		.chip_type = RK3588_EDP,
+	},
+	{
+		.edp_mode = GRF_REG_FIELD(0x0004, 0, 0),
+		.chip_type = RK3588_EDP,
+	},
+	{ /* sentinel */ }
 };
 
 static const struct of_device_id rockchip_dp_dt_ids[] = {
 	{.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp },
 	{.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp },
+	{.compatible = "rockchip,rk3588-edp", .data = &rk3588_edp },
 	{}
 };
 MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 6002c5666031..54086cb2d97d 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -15,11 +15,12 @@ enum analogix_dp_devtype {
 	EXYNOS_DP,
 	RK3288_DP,
 	RK3399_EDP,
+	RK3588_EDP,
 };
 
 static inline bool is_rockchip(enum analogix_dp_devtype type)
 {
-	return type == RK3288_DP || type == RK3399_EDP;
+	return type == RK3288_DP || type == RK3399_EDP || type == RK3588_EDP;
 }
 
 struct analogix_dp_plat_data {
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:24 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:24 +0800
Subject: [PATCH v2 10/11] arm64: dts: rockchip: Enable eDP0 display on RK3588S EVB1 board
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-11-damon.ding@rock-chips.com>

Add the necessary DT changes to enable eDP0 on RK3588S EVB1 board:
- Add edp-panel node
- Set pinctrl of pwm12 for backlight
- Enable edp0/hdptxphy0/vp2

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Remove brightness-levels and default-brightness-level properties in
  backlight node.
- Add the detail DT changes to commit message.
---
 .../boot/dts/rockchip/rk3588s-evb1-v10.dts    | 50 +++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
index bc4077575beb..5c1ea25b6524 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
@@ -9,6 +9,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include <dt-bindings/usb/pd.h>
 #include "rk3588s.dtsi"
 
@@ -120,6 +121,18 @@ backlight: backlight {
 		pwms = <&pwm12 0 25000 0>;
 	};
 
+	edp_panel: edp-panel {
+		compatible = "lg,lp079qx1-sp0v";
+		backlight = <&backlight>;
+		power-supply = <&vcc3v3_lcd_edp>;
+
+		port {
+			panel_in_edp: endpoint {
+				remote-endpoint = <&edp_out_panel>;
+			};
+		};
+	};
+
 	combophy_avdd0v85: regulator-combophy-avdd0v85 {
 		compatible = "regulator-fixed";
 		regulator-name = "combophy_avdd0v85";
@@ -238,6 +251,27 @@ &combphy2_psu {
 	status = "okay";
 };
 
+&edp0 {
+	force-hpd;
+	status = "okay";
+};
+
+&edp0_in {
+	edp0_in_vp2: endpoint {
+		remote-endpoint = <&vp2_out_edp0>;
+	};
+};
+
+&edp0_out {
+	edp_out_panel: endpoint {
+		remote-endpoint = <&panel_in_edp>;
+	};
+};
+
+&hdptxphy0 {
+	status = "okay";
+};
+
 &i2c3 {
 	status = "okay";
 
@@ -399,6 +433,7 @@ usbc0_int: usbc0-int {
 };
 
 &pwm12 {
+	pinctrl-0 = <&pwm12m1_pins>;
 	status = "okay";
 };
 
@@ -1168,3 +1203,18 @@ usbdp_phy0_dp_altmode_mux: endpoint at 1 {
 		};
 	};
 };
+
+&vop_mmu {
+	status = "okay";
+};
+
+&vop {
+	status = "okay";
+};
+
+&vp2 {
+	vp2_out_edp0: endpoint at ROCKCHIP_VOP2_EP_EDP0 {
+		reg = <ROCKCHIP_VOP2_EP_EDP0>;
+		remote-endpoint = <&edp0_in_vp2>;
+	};
+};
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:19 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:19 +0800
Subject: [PATCH v2 05/11] drm/bridge: analogix_dp: add support for RK3588
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-6-damon.ding@rock-chips.com>

Add max_link_rate and max_lane_count configs for RK3588.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index bfa88409a7ff..6f10d88a34c5 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1513,6 +1513,10 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
 		video_info->max_link_rate = 0x0A;
 		video_info->max_lane_count = 0x04;
 		break;
+	case RK3588_EDP:
+		video_info->max_link_rate = 0x14;
+		video_info->max_lane_count = 0x04;
+		break;
 	case EXYNOS_DP:
 		/*
 		 * NOTE: those property parseing code is used for
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:15 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:15 +0800
Subject: [PATCH v2 01/11] drm/rockchip: analogix_dp: Use formalized struct definition for grf field
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-2-damon.ding@rock-chips.com>

The formalized struct definition will makes grf field operations more
concise and easier to extend.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Initialize struct rockchip_dp_chip_data rk3399_edp/rk3288_dp in order
  of its members
---
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 77 +++++++++++--------
 1 file changed, 45 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index d3341edfe4f4..871606a31ef1 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -32,26 +32,29 @@
 
 #include "rockchip_drm_drv.h"
 
-#define RK3288_GRF_SOC_CON6		0x25c
-#define RK3288_EDP_LCDC_SEL		BIT(5)
-#define RK3399_GRF_SOC_CON20		0x6250
-#define RK3399_EDP_LCDC_SEL		BIT(5)
-
-#define HIWORD_UPDATE(val, mask)	(val | (mask) << 16)
-
 #define PSR_WAIT_LINE_FLAG_TIMEOUT_MS	100
 
+#define GRF_REG_FIELD(_reg, _lsb, _msb) {	\
+				.reg = _reg,	\
+				.lsb = _lsb,	\
+				.msb = _msb,	\
+				.valid = true,	\
+				}
+
+struct rockchip_grf_reg_field {
+	u32 reg;
+	u32 lsb;
+	u32 msb;
+	bool valid;
+};
+
 /**
  * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
- * @lcdsel_grf_reg: grf register offset of lcdc select
- * @lcdsel_big: reg value of selecting vop big for eDP
- * @lcdsel_lit: reg value of selecting vop little for eDP
+ * @lcdc_sel: grf register field of lcdc_sel
  * @chip_type: specific chip type
  */
 struct rockchip_dp_chip_data {
-	u32	lcdsel_grf_reg;
-	u32	lcdsel_big;
-	u32	lcdsel_lit;
+	const struct rockchip_grf_reg_field lcdc_sel;
 	u32	chip_type;
 };
 
@@ -84,6 +87,26 @@ static struct rockchip_dp_device *pdata_encoder_to_dp(struct analogix_dp_plat_da
 	return container_of(plat_data, struct rockchip_dp_device, plat_data);
 }
 
+static int rockchip_grf_write(struct regmap *grf, u32 reg, u32 mask, u32 val)
+{
+	return regmap_write(grf, reg, (mask << 16) | (val & mask));
+}
+
+static int rockchip_grf_field_write(struct regmap *grf,
+				    const struct rockchip_grf_reg_field *field,
+				    u32 val)
+{
+	u32 mask;
+
+	if (!field->valid)
+		return 0;
+
+	mask = GENMASK(field->msb, field->lsb);
+	val <<= field->lsb;
+
+	return rockchip_grf_write(grf, field->reg, mask, val);
+}
+
 static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
 {
 	reset_control_assert(dp->rst);
@@ -181,7 +204,6 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state;
 	int ret;
-	u32 val;
 
 	crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
 	if (!crtc)
@@ -192,24 +214,19 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
 	if (old_crtc_state && old_crtc_state->self_refresh_active)
 		return;
 
-	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
-	if (ret < 0)
-		return;
-
-	if (ret)
-		val = dp->data->lcdsel_lit;
-	else
-		val = dp->data->lcdsel_big;
-
-	DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
-
 	ret = clk_prepare_enable(dp->grfclk);
 	if (ret < 0) {
 		DRM_DEV_ERROR(dp->dev, "failed to enable grfclk %d\n", ret);
 		return;
 	}
 
-	ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
+	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
+	if (ret < 0)
+		return;
+
+	DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
+
+	ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, ret);
 	if (ret != 0)
 		DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
 
@@ -448,16 +465,12 @@ static DEFINE_RUNTIME_DEV_PM_OPS(rockchip_dp_pm_ops, rockchip_dp_suspend,
 		rockchip_dp_resume, NULL);
 
 static const struct rockchip_dp_chip_data rk3399_edp = {
-	.lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
-	.lcdsel_big = HIWORD_UPDATE(0, RK3399_EDP_LCDC_SEL),
-	.lcdsel_lit = HIWORD_UPDATE(RK3399_EDP_LCDC_SEL, RK3399_EDP_LCDC_SEL),
+	.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
 	.chip_type = RK3399_EDP,
 };
 
 static const struct rockchip_dp_chip_data rk3288_dp = {
-	.lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
-	.lcdsel_big = HIWORD_UPDATE(0, RK3288_EDP_LCDC_SEL),
-	.lcdsel_lit = HIWORD_UPDATE(RK3288_EDP_LCDC_SEL, RK3288_EDP_LCDC_SEL),
+	.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
 	.chip_type = RK3288_DP,
 };
 
-- 
2.34.1



From damon.ding at rock-chips.com  Sun Dec 15 19:12:25 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 11:12:25 +0800
Subject: [PATCH v2 11/11] arm64: dts: rockchip: Add nodes related to eDP1 for RK3588
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <20241216031225.3746-12-damon.ding@rock-chips.com>

The related nodes are hdptxphy1_grf, hdptxphy1 and edp1. And the
aliases edp0 and edp1 are added to separate two independent eDP
devices.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 .../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 55 +++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
index 0ce0934ec6b7..17cc0b619744 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -7,6 +7,11 @@
 #include "rk3588-extra-pinctrl.dtsi"
 
 / {
+	aliases {
+		edp0 = &edp0;
+		edp1 = &edp1;
+	};
+
 	usb_host1_xhci: usb at fc400000 {
 		compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
 		reg = <0x0 0xfc400000 0x0 0x400000>;
@@ -67,6 +72,11 @@ u2phy1_otg: otg-port {
 		};
 	};
 
+	hdptxphy1_grf: syscon at fd5e4000 {
+		compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
+		reg = <0x0 0xfd5e4000 0x0 0x100>;
+	};
+
 	i2s8_8ch: i2s at fddc8000 {
 		compatible = "rockchip,rk3588-i2s-tdm";
 		reg = <0x0 0xfddc8000 0x0 0x1000>;
@@ -135,6 +145,35 @@ i2s10_8ch: i2s at fde00000 {
 		status = "disabled";
 	};
 
+	edp1: edp at fded0000 {
+		compatible = "rockchip,rk3588-edp";
+		reg = <0x0 0xfded0000 0x0 0x1000>;
+		clocks = <&cru CLK_EDP1_24M>, <&cru PCLK_EDP1>, <&cru CLK_EDP1_200M>;
+		clock-names = "dp", "pclk", "spdif";
+		interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH 0>;
+		phys = <&hdptxphy1>;
+		phy-names = "dp";
+		power-domains = <&power RK3588_PD_VO1>;
+		resets = <&cru SRST_EDP1_24M>, <&cru SRST_P_EDP1>;
+		reset-names = "dp", "apb";
+		rockchip,grf = <&vo1_grf>;
+		#sound-dai-cells = <1>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			edp1_in: port at 0 {
+				reg = <0>;
+			};
+
+			edp1_out: port at 1 {
+				reg = <1>;
+			};
+		};
+	};
+
 	pcie3x4: pcie at fe150000 {
 		compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
 		#address-cells = <3>;
@@ -395,6 +434,22 @@ sata-port at 0 {
 		};
 	};
 
+	hdptxphy1: phy at fed70000 {
+		compatible = "rockchip,rk3588-hdptx-phy";
+		reg = <0x0 0xfed70000 0x0 0x2000>;
+		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>;
+		clock-names = "ref", "apb";
+		#phy-cells = <0>;
+		resets = <&cru SRST_HDPTX1>, <&cru SRST_P_HDPTX1>,
+			 <&cru SRST_HDPTX1_INIT>, <&cru SRST_HDPTX1_CMN>,
+			 <&cru SRST_HDPTX1_LANE>, <&cru SRST_HDPTX1_ROPLL>,
+			 <&cru SRST_HDPTX1_LCPLL>;
+		reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
+			      "lcpll";
+		rockchip,grf = <&hdptxphy1_grf>;
+		status = "disabled";
+	};
+
 	usbdp_phy1: phy at fed90000 {
 		compatible = "rockchip,rk3588-usbdp-phy";
 		reg = <0x0 0xfed90000 0x0 0x10000>;
-- 
2.34.1



From kevin_chen at aspeedtech.com  Sun Dec 15 19:34:52 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Mon, 16 Dec 2024 03:34:52 +0000
Subject: [PATCH v3 0/6] Introduce ASPEED AST27XX BMC SoC
In-Reply-To: <5d91b7a7169e6db27b2493213d0df2b77699a49e.camel@codeconstruct.com.au>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <5d91b7a7169e6db27b2493213d0df2b77699a49e.camel@codeconstruct.com.au>
Message-ID: <PSAPR06MB49493DBCC874A32174E3C180893B2@PSAPR06MB4949.apcprd06.prod.outlook.com>

Hi,

> > ---
> > v3:
> > ? - Split clk and reset driver to other commits, which are in series
> > of
> > ??? "Add support for AST2700 clk driver".
> > ? - For BMC console by UART12, add uart12 using ASPEED INTC
> > architecture.
> >
> > aspeed,ast2700-intc.yaml
> > ? - Add minItems to 1 to fix the warning by "make dtbs_check W=1".
> > ? - Add intc1 into example.
> >
> > Kconfig.platforms
> > ? - Remove MACH_ASPEED_G7.
> >
> > Kevin Chen (6):
> > ? dt-bindings: interrupt-controller: Refine size/interrupt-cell usage.
> > ? dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
> > ? arm64: aspeed: Add support for ASPEED AST27XX BMC SoC
> > ? arm64: dts: aspeed: Add initial AST27XX device tree
> > ? arm64: dts: aspeed: Add initial AST2700 EVB device tree
> > ? arm64: defconfig: Add ASPEED AST2700 family support
> 
> Do you mind sending a v4, because I received a confusing arrangement of
> patches:
OK. I put a mixed commits in our send-mail server. I will try to send v4 patches.
Thanks for your reminder.

> 
> [PATCH v3 1/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC [PATCH v3
> 1/6] dt-bindings: interrupt-controller: Refine size/interrupt-cell usage.
> [PATCH v3 2/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC [PATCH v3
> 2/6] dt-bindings: interrupt-controller: Fix the size-cells in ast2700-intc ...
> 
> Where the content of
> 
>    [PATCH v3 1/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
> 
> and
> 
>    [PATCH v3 2/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
> 
> Differs, as does the content of
> 
>    [PATCH v3 1/6] dt-bindings: interrupt-controller: Refine size/interrupt-cell
> usage.
> 
> and
> 
>    [PATCH v3 2/6] dt-bindings: interrupt-controller: Fix the size-cells in
> ast2700-intc
> 
> Despite sounding like they might have the same intent
> 
> Andrew

From kevin_chen at aspeedtech.com  Sun Dec 15 19:50:24 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Mon, 16 Dec 2024 03:50:24 +0000
Subject: [PATCH v3 1/6] dt-bindings: interrupt-controller: Refine
 size/interrupt-cell usage.
In-Reply-To: <k7jftzlih6ss4yaxrv7r4dudhcu43iyu2qvkl2thb5wiaszto7@evzmwfxxzzt6>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-3-kevin_chen@aspeedtech.com>
 <k7jftzlih6ss4yaxrv7r4dudhcu43iyu2qvkl2thb5wiaszto7@evzmwfxxzzt6>
Message-ID: <PSAPR06MB494997E9578D2E2E745AC90B893B2@PSAPR06MB4949.apcprd06.prod.outlook.com>

Hi,

> > 1. Because size-cells is no need to use 2, modify to 1 for use.
> > 2. Add minItems to 1 for interrupts for intc1.
> > 3. Add 1 interrupt of intc1 example into yaml file.
> > 4. Add intc1 sub-module of uart12 as example using the intc0 and intc1.
> > ---
> >  .../aspeed,ast2700-intc.yaml                  | 60
> +++++++++++++++----
> >  1 file changed, 47 insertions(+), 13 deletions(-)
> >
> 
> As with all your patches, repeating since v1 the same comment, so one more
> last time:
> 
> Please run scripts/checkpatch.pl and fix reported warnings. Then please run
> 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
> Some warnings can be ignored, especially from --strict run, but the code here
> looks like it needs a fix. Feel free to get in touch if the warning is not clear.
OK.
I need to wait the Ryan's series of " "Add support for AST2700 clk driver"" for clk and reset drivers.
I will wait for his commits to be merged with the warnings fixed.


> 
> Best regards,
> Krzysztof


From kevin_chen at aspeedtech.com  Sun Dec 15 19:58:21 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Mon, 16 Dec 2024 03:58:21 +0000
Subject: [PATCH v3 5/6] arm64: dts: aspeed: Add initial AST2700 EVB device
 tree
In-Reply-To: <3e5346a3-ad00-46e2-8af5-1ac5d60c27c8@kernel.org>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-8-kevin_chen@aspeedtech.com>
 <3e5346a3-ad00-46e2-8af5-1ac5d60c27c8@kernel.org>
Message-ID: <PSAPR06MB4949384985104E0CFFB5234B893B2@PSAPR06MB4949.apcprd06.prod.outlook.com>

Hi Krzk,

> > Add EVB board of AST2700 in ASPEED Architecture.
> >
> > Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
> > ---
> >  arch/arm64/boot/dts/aspeed/Makefile        |  4 ++
> >  arch/arm64/boot/dts/aspeed/ast2700-evb.dts | 57
> > ++++++++++++++++++++++
> >  2 files changed, 61 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/aspeed/Makefile
> >  create mode 100644 arch/arm64/boot/dts/aspeed/ast2700-evb.dts
> >
> > diff --git a/arch/arm64/boot/dts/aspeed/Makefile
> > b/arch/arm64/boot/dts/aspeed/Makefile
> > new file mode 100644
> > index 000000000000..ffe7e15017cc
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/aspeed/Makefile
> > @@ -0,0 +1,4 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +dtb-$(CONFIG_ARCH_ASPEED) += \
> > +	ast2700-evb.dtb
> > diff --git a/arch/arm64/boot/dts/aspeed/ast2700-evb.dts
> > b/arch/arm64/boot/dts/aspeed/ast2700-evb.dts
> > new file mode 100644
> > index 000000000000..6dad88c98ce0
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/aspeed/ast2700-evb.dts
> > @@ -0,0 +1,57 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +
> > +/dts-v1/;
> > +
> > +#include "aspeed-g7.dtsi"
> > +#include <dt-bindings/gpio/aspeed-gpio.h>
> > +
> > +/ {
> > +	model = "AST2700A1-EVB";
> > +	compatible = "aspeed,ast2700-evb", "aspeed,ast2700";
> > +
> > +	aliases {
> > +		serial12 = &uart12;
> > +	};
> > +
> > +	chosen {
> > +		bootargs = "console=ttyS12,115200n8";
> > +		stdout-path = &uart12;
> 
> Nothing improved. You keep ignoring my comments: not responding, not
> addressing, not fixing the code.
OK. I will remove the bootargs.

> 
> > +	};
> > +
> > +	firmware {
> > +		optee: optee {
> > +			compatible = "linaro,optee-tz";
> > +			method = "smc";
> > +		};
> > +	};
> > +
> > +	memory at 400000000 {
> > +		device_type = "memory";
> > +		reg = <0x4 0x00000000 0x40000000>;
> > +	};
> > +
> > +	reserved-memory {
> > +		#address-cells = <2>;
> > +		#size-cells = <1>;
> > +		ranges;
> > +
> > +		mcu_fw: mcu-firmware at 42fe00000 {
> > +			reg = <0x4 0x2fe00000 0x200000>;
> > +			no-map;
> > +		};
> > +
> > +		atf: trusted-firmware-a at 430000000 {
> > +			reg = <0x4 0x30000000 0x80000>;
> > +			no-map;
> > +		};
> > +
> > +		optee_core: optee_core at 430080000 {
> 
> Follow DTS Coding style document. That's the same comment as before.
OK. I will fix to optee-core:optee-core at 430080000 {

> 
> 
> Best regards,
> Krzysztof

From hui.wang at canonical.com  Sun Dec 15 20:07:22 2024
From: hui.wang at canonical.com (Hui Wang)
Date: Mon, 16 Dec 2024 12:07:22 +0800
Subject: [PATCH v2] ARM: dts: nxp: imx6qdl-sabresd: add dr_mode to usbotg
Message-ID: <20241216040722.21738-1-hui.wang@canonical.com>

Currently there are 3 type of boards (imx6q|imx6qp|imx6dl-sabresd)
based on imx6qdl-sabresd.dtsi, they all do not set the dr_mode for
usbotg device node. The chipidea usb driver will configure it to otg
mode by default if the dr_mode is not set, but some testcases need to
parse the dr_mode from DT and decide the follow-up test strategy, here
set the dr_mode to otg explicitly for these 3 imx6qdl-sabresd based
boards.

Signed-off-by: Hui Wang <hui.wang at canonical.com>
---
in the v2:
 adding the dr_mode in imx6qdl-sabresd.dtsi rather than imx6qdl.dtsi

 arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
index dc8298f6db34..914c129b09a5 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
@@ -804,6 +804,7 @@ &usbotg {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usbotg>;
 	disable-over-current;
+	dr_mode = "otg";
 	status = "okay";
 };
 
-- 
2.34.1



From anshuman.khandual at arm.com  Sun Dec 15 20:08:28 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 16 Dec 2024 09:38:28 +0530
Subject: [PATCH V3 4/7] arm64/sysreg: Add register fields for HDFGWTR2_EL2
In-Reply-To: <20241216040831.2448257-1-anshuman.khandual@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
Message-ID: <20241216040831.2448257-5-anshuman.khandual@arm.com>

This adds register fields for HDFGWTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a9dc5e4f9d97..8bf22f3904bd 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2586,6 +2586,34 @@ Field	1	nPMIAR_EL1
 Field	0	nPMECR_EL1
 EndSysreg
 
+Sysreg HDFGWTR2_EL2	3	4	3	1	1
+Res0	63:25
+Field	24	nPMBMAR_EL1
+Field	23	nMDSTEPOP_EL1
+Field	22	nTRBMPAM_EL1
+Field	21	nPMZR_EL0
+Field	20	nTRCITECR_EL1
+Field	19	nPMSDSFR_EL1
+Res0	18:17
+Field	16	nSPMSCR_EL1
+Field	15	nSPMACCESSR_EL1
+Field	14	nSPMCR_EL0
+Field	13	nSPMOVS
+Field	12	nSPMINTEN
+Field	11	nSPMCNTEN
+Field	10	nSPMSELR_EL0
+Field	9	nSPMEVTYPERn_EL0
+Field	8	nSPMEVCNTRn_EL0
+Field	7	nPMSSCR_EL1
+Res0	6
+Field	5	nMDSELR_EL1
+Field	4	nPMUACR_EL1
+Field	3	nPMICFILTR_EL0
+Field	2	nPMICNTR_EL0
+Field	1	nPMIAR_EL1
+Field	0	nPMECR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Dec 15 20:08:29 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 16 Dec 2024 09:38:29 +0530
Subject: [PATCH V3 5/7] arm64/cpufeature: Add field details for ID_AA64DFR1_EL1 register
In-Reply-To: <20241216040831.2448257-1-anshuman.khandual@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
Message-ID: <20241216040831.2448257-6-anshuman.khandual@arm.com>

This adds required field details for ID_AA64DFR1_EL1, and also drops dummy
ftr_raz[] array which is now redundant. These register fields will be used
to enable increased breakpoint and watchpoint registers via FEAT_Debugv8p9
later. The register fields have been marked as FTR_STRICT, unless there is
a known variation in practice.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
cc: Mark Brown <broonie at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V3:

- Updated the commit message
- Marked ID_AA64DFR1_EL1.ABLE as FTR_NONSTRICT in ftr_id_aa64dfr1[]

 arch/arm64/kernel/cpufeature.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed8..0dc22fde104e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -534,6 +534,21 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
 	ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_id_aa64dfr1[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABL_CMPs_SHIFT, 8, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_DPFZS_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_EBEP_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ITE_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABLE_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_PMICNTR_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SPMU_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_CTX_CMPs_SHIFT, 8, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_WRPs_SHIFT, 8, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_BRPs_SHIFT, 8, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SYSPMUID_SHIFT, 8, 0),
+	ARM64_FTR_END,
+};
+
 static const struct arm64_ftr_bits ftr_mvfr0[] = {
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_EL1_FPRound_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_EL1_FPShVec_SHIFT, 4, 0),
@@ -720,10 +735,6 @@ static const struct arm64_ftr_bits ftr_single32[] = {
 	ARM64_FTR_END,
 };
 
-static const struct arm64_ftr_bits ftr_raz[] = {
-	ARM64_FTR_END,
-};
-
 #define __ARM64_FTR_REG_OVERRIDE(id_str, id, table, ovr) {	\
 		.sys_id = id,					\
 		.reg = 	&(struct arm64_ftr_reg){		\
@@ -796,7 +807,7 @@ static const struct __ftr_reg_entry {
 
 	/* Op1 = 0, CRn = 0, CRm = 5 */
 	ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
-	ARM64_FTR_REG(SYS_ID_AA64DFR1_EL1, ftr_raz),
+	ARM64_FTR_REG(SYS_ID_AA64DFR1_EL1, ftr_id_aa64dfr1),
 
 	/* Op1 = 0, CRn = 0, CRm = 6 */
 	ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0),
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Dec 15 20:08:30 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 16 Dec 2024 09:38:30 +0530
Subject: [PATCH V3 6/7] arm64/boot: Enable EL2 requirements for FEAT_Debugv8p9
In-Reply-To: <20241216040831.2448257-1-anshuman.khandual@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
Message-ID: <20241216040831.2448257-7-anshuman.khandual@arm.com>

Fine grained trap control for MDSELR_EL1 register needs to be configured in
HDFGRTR2_EL2, and HDFGWTR2_EL2 registers when kernel enters at EL1, but EL2
is also present. This adds a new helper __init_el2_fgt2() initializing this
new FEAT_FGT2 based fine grained registers.

MDCR_EL2.EBWE needs to be enabled for additional (beyond 16) breakpoint and
watchpoint exceptions when kernel enters at EL1, but EL2 is also present.
This updates __init_el2_debug() as required for FEAT_Debugv8p9.

While here, also update booting.rst with MDCR_EL3 and SCR_EL3 requirements.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Jonathan Corbet <corbet at lwn.net>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: kvmarm at lists.linux.dev
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V3:

- Dropped MDCR_EL3.TDA boot requirement from documentation (separate series)
- Dropped MDCR_EL2_EBWE definition as MDCR_EL2 is now defined in tools sysreg

https://lore.kernel.org/all/20241211065425.1106683-1-anshuman.khandual at arm.com/

 Documentation/arch/arm64/booting.rst | 18 ++++++++++++++++++
 arch/arm64/include/asm/el2_setup.h   | 26 ++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
index 3278fb4bf219..054cfe1cad18 100644
--- a/Documentation/arch/arm64/booting.rst
+++ b/Documentation/arch/arm64/booting.rst
@@ -288,6 +288,12 @@ Before jumping into the kernel, the following conditions must be met:
 
     - SCR_EL3.FGTEn (bit 27) must be initialised to 0b1.
 
+  For CPUs with the Fine Grained Traps (FEAT_FGT2) extension present:
+
+  - If EL3 is present and the kernel is entered at EL2:
+
+    - SCR_EL3.FGTEn2 (bit 59) must be initialised to 0b1.
+
   For CPUs with support for HCRX_EL2 (FEAT_HCX) present:
 
   - If EL3 is present and the kernel is entered at EL2:
@@ -322,6 +328,18 @@ Before jumping into the kernel, the following conditions must be met:
     - ZCR_EL2.LEN must be initialised to the same value for all CPUs the
       kernel will execute on.
 
+  For CPUs with FEAT_Debugv8p9 extension present:
+
+  - If the kernel is entered at EL1 and EL2 is present:
+
+    - HDFGRTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1
+    - HDFGWTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1
+    - MDCR_EL2.EBWE (bit 43) must be initialized to 0b1
+
+  - If EL3 is present:
+
+    - MDCR_EL3.EBWE (bit 43) must be initialized to 0b1
+
   For CPUs with the Scalable Matrix Extension (FEAT_SME):
 
   - If EL3 is present:
diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 4ef52d7245bb..2fbfe27d38b5 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -105,6 +105,13 @@
 						// to own it.
 
 .Lskip_trace_\@:
+	mrs	x1, id_aa64dfr0_el1
+	ubfx	x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
+	cmp	x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
+	b.lt	.Lskip_dbg_v8p9_\@
+
+	orr	x2, x2, #MDCR_EL2_EBWE
+.Lskip_dbg_v8p9_\@:
 	msr	mdcr_el2, x2			// Configure debug traps
 .endm
 
@@ -244,6 +251,24 @@
 .Lskip_gcs_\@:
 .endm
 
+.macro __init_el2_fgt2
+	mrs	x1, id_aa64mmfr0_el1
+	ubfx	x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
+	cmp	x1, #ID_AA64MMFR0_EL1_FGT_FGT2
+	b.lt	.Lskip_fgt2_\@
+
+	mrs	x1, id_aa64dfr0_el1
+	ubfx	x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
+	cmp	x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
+	b.lt	.Lskip_dbg_v8p9_\@
+
+	mov_q   x0, HDFGWTR2_EL2_nMDSELR_EL1
+	msr_s	SYS_HDFGWTR2_EL2, x0
+	msr_s	SYS_HDFGRTR2_EL2, x0
+.Lskip_dbg_v8p9_\@:
+.Lskip_fgt2_\@:
+.endm
+
 .macro __init_el2_nvhe_prepare_eret
 	mov	x0, #INIT_PSTATE_EL1
 	msr	spsr_el2, x0
@@ -283,6 +308,7 @@
 	__init_el2_nvhe_idregs
 	__init_el2_cptr
 	__init_el2_fgt
+	__init_el2_fgt2
         __init_el2_gcs
 .endm
 
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Dec 15 20:08:27 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 16 Dec 2024 09:38:27 +0530
Subject: [PATCH V3 3/7] arm64/sysreg: Add register fields for HDFGRTR2_EL2
In-Reply-To: <20241216040831.2448257-1-anshuman.khandual@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
Message-ID: <20241216040831.2448257-4-anshuman.khandual@arm.com>

This adds register fields for HDFGRTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index fe878eb194a0..a9dc5e4f9d97 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2557,6 +2557,35 @@ Field	1	ICIALLU
 Field	0	ICIALLUIS
 EndSysreg
 
+Sysreg HDFGRTR2_EL2	3	4	3	1	0
+Res0	63:25
+Field	24	nPMBMAR_EL1
+Field	23	nMDSTEPOP_EL1
+Field	22	nTRBMPAM_EL1
+Res0	21
+Field	20	nTRCITECR_EL1
+Field	19	nPMSDSFR_EL1
+Field	18	nSPMDEVAFF_EL1
+Field	17	nSPMID
+Field	16	nSPMSCR_EL1
+Field	15	nSPMACCESSR_EL1
+Field	14	nSPMCR_EL0
+Field	13	nSPMOVS
+Field	12	nSPMINTEN
+Field	11	nSPMCNTEN
+Field	10	nSPMSELR_EL0
+Field	9	nSPMEVTYPERn_EL0
+Field	8	nSPMEVCNTRn_EL0
+Field	7	nPMSSCR_EL1
+Field	6	nPMSSDATA
+Field	5	nMDSELR_EL1
+Field	4	nPMUACR_EL1
+Field	3	nPMICFILTR_EL0
+Field	2	nPMICNTR_EL0
+Field	1	nPMIAR_EL1
+Field	0	nPMECR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Dec 15 20:08:31 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 16 Dec 2024 09:38:31 +0530
Subject: [PATCH V3 7/7] arm64/hw_breakpoint: Enable FEAT_Debugv8p9
In-Reply-To: <20241216040831.2448257-1-anshuman.khandual@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
Message-ID: <20241216040831.2448257-8-anshuman.khandual@arm.com>

Currently there can be maximum 16 breakpoints, and 16 watchpoints available
on a given platform - as detected from ID_AA64DFR0_EL1.[BRPs|WRPs] register
fields. But these breakpoint, and watchpoints can be extended further up to
64 via a new arch feature FEAT_Debugv8p9.

This first enables banked access for the breakpoint and watchpoint register
set via MDSELR_EL1, extended exceptions via MDSCR_EL1.EMBWE and determining
available breakpoints and watchpoints in the platform from ID_AA64DFR1_EL1,
when FEAT_Debugv8p9 is enabled.

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 V3:

- Used SYS_FIELD_PREP() in read_wb_reg() and write_wb_reg()
- Added MAX_PER_BANK based BUILD_BUG_ON() tests in arch_hw_breakpoint_init()
- Dropped local variables i.e mdsel_bank and index
- Derived bank and index from MAX_PER_BANK as required

 arch/arm64/include/asm/debug-monitors.h |  1 +
 arch/arm64/include/asm/hw_breakpoint.h  | 47 ++++++++++++++++++------
 arch/arm64/kernel/debug-monitors.c      | 15 +++++---
 arch/arm64/kernel/hw_breakpoint.c       | 48 +++++++++++++++++++++++--
 4 files changed, 95 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index 8f6ba31b8658..56b89a582a0d 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -20,6 +20,7 @@
 #define DBG_MDSCR_KDE		(1 << 13)
 #define DBG_MDSCR_MDE		(1 << 15)
 #define DBG_MDSCR_MASK		~(DBG_MDSCR_KDE | DBG_MDSCR_MDE)
+#define DBG_MDSCR_EMBWE		(1UL << 32)
 
 #define	DBG_ESR_EVT(x)		(((x) >> 27) & 0x7)
 
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index bd81cf17744a..e48273b64109 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -79,8 +79,9 @@ static inline void decode_ctrl_reg(u32 reg,
  * Limits.
  * Changing these will require modifications to the register accessors.
  */
-#define ARM_MAX_BRP		16
-#define ARM_MAX_WRP		16
+#define ARM_MAX_BRP		64
+#define ARM_MAX_WRP		64
+#define MAX_PER_BANK		16
 
 /* Virtual debug register bases. */
 #define AARCH64_DBG_REG_BVR	0
@@ -94,6 +95,14 @@ static inline void decode_ctrl_reg(u32 reg,
 #define AARCH64_DBG_REG_NAME_WVR	wvr
 #define AARCH64_DBG_REG_NAME_WCR	wcr
 
+static inline bool is_debug_v8p9_enabled(void)
+{
+	u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
+	int dver = cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_DebugVer_SHIFT);
+
+	return dver == ID_AA64DFR0_EL1_DebugVer_V8P9;
+}
+
 /* Accessor macros for the debug registers. */
 #define AARCH64_DBG_READ(N, REG, VAL) do {\
 	VAL = read_sysreg(dbg##REG##N##_el1);\
@@ -138,19 +147,37 @@ static inline void ptrace_hw_copy_thread(struct task_struct *task)
 /* Determine number of BRP registers available. */
 static inline int get_num_brps(void)
 {
-	u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
-	return 1 +
-		cpuid_feature_extract_unsigned_field(dfr0,
-						ID_AA64DFR0_EL1_BRPs_SHIFT);
+	u64 dfr0, dfr1;
+	int dver, brps;
+
+	dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
+	dver = cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_DebugVer_SHIFT);
+	if (dver == ID_AA64DFR0_EL1_DebugVer_V8P9) {
+		dfr1 = read_sanitised_ftr_reg(SYS_ID_AA64DFR1_EL1);
+		brps = cpuid_feature_extract_unsigned_field_width(dfr1,
+								  ID_AA64DFR1_EL1_BRPs_SHIFT, 8);
+	} else {
+		brps = cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_BRPs_SHIFT);
+	}
+	return 1 + brps;
 }
 
 /* Determine number of WRP registers available. */
 static inline int get_num_wrps(void)
 {
-	u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
-	return 1 +
-		cpuid_feature_extract_unsigned_field(dfr0,
-						ID_AA64DFR0_EL1_WRPs_SHIFT);
+	u64 dfr0, dfr1;
+	int dver, wrps;
+
+	dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
+	dver = cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_DebugVer_SHIFT);
+	if (dver == ID_AA64DFR0_EL1_DebugVer_V8P9) {
+		dfr1 = read_sanitised_ftr_reg(SYS_ID_AA64DFR1_EL1);
+		wrps = cpuid_feature_extract_unsigned_field_width(dfr1,
+								  ID_AA64DFR1_EL1_WRPs_SHIFT, 8);
+	} else {
+		wrps = cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_WRPs_SHIFT);
+	}
+	return 1 + wrps;
 }
 
 #ifdef CONFIG_CPU_PM
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index 58f047de3e1c..50779c68f11e 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -21,6 +21,7 @@
 #include <asm/cputype.h>
 #include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
+#include <asm/hw_breakpoint.h>
 #include <asm/system_misc.h>
 #include <asm/traps.h>
 
@@ -34,7 +35,7 @@ u8 debug_monitors_arch(void)
 /*
  * MDSCR access routines.
  */
-static void mdscr_write(u32 mdscr)
+static void mdscr_write(u64 mdscr)
 {
 	unsigned long flags;
 	flags = local_daif_save();
@@ -43,7 +44,7 @@ static void mdscr_write(u32 mdscr)
 }
 NOKPROBE_SYMBOL(mdscr_write);
 
-static u32 mdscr_read(void)
+static u64 mdscr_read(void)
 {
 	return read_sysreg(mdscr_el1);
 }
@@ -79,7 +80,7 @@ static DEFINE_PER_CPU(int, kde_ref_count);
 
 void enable_debug_monitors(enum dbg_active_el el)
 {
-	u32 mdscr, enable = 0;
+	u64 mdscr, enable = 0;
 
 	WARN_ON(preemptible());
 
@@ -90,6 +91,9 @@ void enable_debug_monitors(enum dbg_active_el el)
 	    this_cpu_inc_return(kde_ref_count) == 1)
 		enable |= DBG_MDSCR_KDE;
 
+	if (is_debug_v8p9_enabled())
+		enable |= DBG_MDSCR_EMBWE;
+
 	if (enable && debug_enabled) {
 		mdscr = mdscr_read();
 		mdscr |= enable;
@@ -100,7 +104,7 @@ NOKPROBE_SYMBOL(enable_debug_monitors);
 
 void disable_debug_monitors(enum dbg_active_el el)
 {
-	u32 mdscr, disable = 0;
+	u64 mdscr, disable = 0;
 
 	WARN_ON(preemptible());
 
@@ -111,6 +115,9 @@ void disable_debug_monitors(enum dbg_active_el el)
 	    this_cpu_dec_return(kde_ref_count) == 0)
 		disable &= ~DBG_MDSCR_KDE;
 
+	if (is_debug_v8p9_enabled())
+		disable &= ~DBG_MDSCR_EMBWE;
+
 	if (disable) {
 		mdscr = mdscr_read();
 		mdscr &= disable;
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 722ac45f9f7b..e9c87fb0e772 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -103,7 +103,7 @@ int hw_breakpoint_slots(int type)
 	WRITE_WB_REG_CASE(OFF, 14, REG, VAL);	\
 	WRITE_WB_REG_CASE(OFF, 15, REG, VAL)
 
-static u64 read_wb_reg(int reg, int n)
+static u64 __read_wb_reg(int reg, int n)
 {
 	u64 val = 0;
 
@@ -118,9 +118,31 @@ static u64 read_wb_reg(int reg, int n)
 
 	return val;
 }
+
+static u64 read_wb_reg(int reg, int n)
+{
+	unsigned long flags;
+	u64 val;
+
+	if (!is_debug_v8p9_enabled())
+		return __read_wb_reg(reg, n);
+
+	/*
+	 * Bank selection in MDSELR_EL1, followed by an indexed read from
+	 * breakpoint (or watchpoint) registers cannot be interrupted, as
+	 * that might cause misread from the wrong targets instead. Hence
+	 * this requires mutual exclusion.
+	 */
+	local_irq_save(flags);
+	write_sysreg_s(SYS_FIELD_PREP(MDSELR_EL1, BANK, n / MAX_PER_BANK), SYS_MDSELR_EL1);
+	isb();
+	val = __read_wb_reg(reg, n % MAX_PER_BANK);
+	local_irq_restore(flags);
+	return val;
+}
 NOKPROBE_SYMBOL(read_wb_reg);
 
-static void write_wb_reg(int reg, int n, u64 val)
+static void __write_wb_reg(int reg, int n, u64 val)
 {
 	switch (reg + n) {
 	GEN_WRITE_WB_REG_CASES(AARCH64_DBG_REG_BVR, AARCH64_DBG_REG_NAME_BVR, val);
@@ -132,6 +154,26 @@ static void write_wb_reg(int reg, int n, u64 val)
 	}
 	isb();
 }
+
+static void write_wb_reg(int reg, int n, u64 val)
+{
+	unsigned long flags;
+
+	if (!is_debug_v8p9_enabled())
+		return __write_wb_reg(reg, n, val);
+
+	/*
+	 * Bank selection in MDSELR_EL1, followed by an indexed read from
+	 * breakpoint (or watchpoint) registers cannot be interrupted, as
+	 * that might cause misread from the wrong targets instead. Hence
+	 * this requires mutual exclusion.
+	 */
+	local_irq_save(flags);
+	write_sysreg_s(SYS_FIELD_PREP(MDSELR_EL1, BANK, n / MAX_PER_BANK), SYS_MDSELR_EL1);
+	isb();
+	__write_wb_reg(reg, n % MAX_PER_BANK, val);
+	local_irq_restore(flags);
+}
 NOKPROBE_SYMBOL(write_wb_reg);
 
 /*
@@ -1005,6 +1047,8 @@ static int __init arch_hw_breakpoint_init(void)
 
 	/* Register cpu_suspend hw breakpoint restore hook */
 	cpu_suspend_set_dbg_restorer(hw_breakpoint_reset);
+	BUILD_BUG_ON((ARM_MAX_BRP % MAX_PER_BANK) != 0);
+	BUILD_BUG_ON((ARM_MAX_WRP % MAX_PER_BANK) != 0);
 
 	return ret;
 }
-- 
2.25.1



From w.egorov at phytec.de  Sun Dec 15 20:14:39 2024
From: w.egorov at phytec.de (Wadim Egorov)
Date: Mon, 16 Dec 2024 05:14:39 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am62l: add initial infrastructure
In-Reply-To: <20241214215624.e372oju6eserpf4f@bryanbrattlof.com>
References: <20241117-am62lx-v1-0-4e71e42d781d@ti.com>
 <20241117-am62lx-v1-1-4e71e42d781d@ti.com>
 <Z12rnZiCXQxtMWlf@livingston.pivistrello.it>
 <20241214215624.e372oju6eserpf4f@bryanbrattlof.com>
Message-ID: <8b3ed680-bc14-42a3-92d2-2167213954a5@phytec.de>

Am 14.12.24 um 22:56 schrieb Bryan Brattlof:
> On December 14, 2024 thus sayeth Francesco Dolcini:
>> On Sun, Nov 17, 2024 at 11:34:07PM -0600, Bryan Brattlof wrote:
>>> From: Vignesh Raghavendra <vigneshr at ti.com>
>>>
>>> Add the initial infrastructure needed for the AM62L. All of which can be
>>> found in the Technical Reference Manual (TRM) located here:
>>>
>>>      https://www.ti.com/lit/ug/sprujb4/sprujb4.pdf
>>>
>>> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
>>> Signed-off-by: Bryan Brattlof <bb at ti.com>
>>> ---
>>>   Documentation/devicetree/bindings/arm/ti/k3.yaml |  6 ++
>>>   arch/arm64/boot/dts/ti/Makefile                  |  3 +
>>>   arch/arm64/boot/dts/ti/k3-am62l-main.dtsi        | 52 ++++++++++++++
>>>   arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi      | 33 +++++++++
>>>   arch/arm64/boot/dts/ti/k3-am62l.dtsi             | 89 ++++++++++++++++++++++++
>>>   arch/arm64/boot/dts/ti/k3-am62l3.dtsi            | 67 ++++++++++++++++++
>>>   arch/arm64/boot/dts/ti/k3-pinctrl.h              |  2 +
>>>   7 files changed, 252 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
>>> index 18f155cd06c84..b109e854879cb 100644
>>> --- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
>>> +++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
>>> @@ -31,6 +31,12 @@ properties:
>>>             - const: phytec,am62a-phycore-som
>>>             - const: ti,am62a7
>>>   
>>> +      - description: K3 AM62L3 SoC and Boards
>>> +        items:
>>> +          - enum:
>>> +              - ti,am62l3-evm
>>> +          - const: ti,am62l3
>>> +
>>
>> can you clarify the differences between AM62L and AM62L3? you have a mix of names in this series. I assume that
>> AM62L is the SOC family / product name, while AM62L3 is a specific
>> part number.
>>
> 
> Absolutely! I found the naming a bit confusing myself.
> 
> We (the baseport teams) have kinda coalesced into using less digits as a
> way to describe all devices included in the subgroup. So for example AM6
> would be all Sitara class MPUs in the K3 generation. AM62L would be all
> parts in K3 in the 'lite' derivative. AM62L32 would be all AM62L parts
> with display and dual cores.
> 
> But I should probably decode everything as these part numbers are really
> opaque in my eye if you don't see them every day.
> 
> The full orderable part number for this part is the XAM62L32AOGHAANB
> 
>      'X' is the production status. If you see an 'X' here it just means
>      it's a pre-production sample that hasn't gone through validation.
>      Most of the time (outside of TI) this will be blank
> 
>      'AM' is the prefix which indicates a Sitara class of SoC. The AM68
>      and AM69 being originally a Jacinto class part kinda makes this more
>      confusing but back in the day i think it used to stand for ARM
>      Microprocessors so that's what I've been telling people.
> 
>      '62' is the generation and family of the part. So this example the 6
>      indicates the K3 generation of SoCs and the 2 means it's an MPU
>      family with 2k display or 2k camera support among other things.
> 
>      'L' is the derivative of the family. This is mostly a marketing
>      thing to indicate the target market for the SoC:
> 
>        AM62  (or blank) would be the general base class
>        AM62A is for the analytics derivative
>        AM62D is for DSP
>        AM62P is for Plus
>        AM62L is for Lite
> 
>      '3' is the configuration. This really depends on what the business
>      teams find feasible. Some of the family/derivative combinations
>      don't make sense to have. For example an AM62L9 which would just be
>      the base AM62 derivative, so some configurations may not exist.
> 
>        0 = No Display / No ISP
>        1 = No Display with ISP
>        2 = No Display with ISP and Analytics
>        3 = Display / No ISP
>        4 = Display / No ISP with Analytics
>        5 = Display / No ISP with GPU
>        6 = Display with ISP
>        7 = Display with ISP and Analytics
>        8 = Display with ISP and GPU
>        9 = includes everything
> 
>      '2' is the core count. AM62L32 would be the dual core option.
> 
> The rest of the digits get into stuff we try to do automatically via our
> bootloaders so you wont see any mention of them in Linux, but I kinda
> wanted to continue decoding this :)
> 
>      'A' is the silicon revision. A = SR 1.0
> 
>      'O' is the speed grade. (there is a table somewhere with all the
>      speed grades we support. The two I know about are.
> 
>        O = 1.25GHz
>        E = 833MHz
> 
>      'G' is the feature set. Because the derivative is 'L' (or lite) we
>      probably won't have options other than G which is the baseline
> 
>      'H' is the security & functional safety value
> 
>        'G' is non secure no functional safety. (like the beagleplay)
>        '1-9' are dummy key devices with no functional safety
>        'H-R' are production key HS devices with no function safety
>        'S-Z' are production key HS devices with function safety
>          
> 'H-Z' is probably the most common security you will see TI make now.
> There are ways (by talking to sales) you can purchase other variants for
> special use cases (like aviation) but I think these are all special use
> cases with unique regulatory or security issues.
> 
>      'A' is the temperature rating
>       
>        'A' = -40C to 105C
>        'I' = -40C to 125C
> 
>      'ANB' is the package: 11.9mm x 11.9mm with 0.5 BGA
> 
> There can be a total of 18 digits which can vary when decoding the
> family (AM65, AM64) but generally this decoding scheme will hold. I only
> really see those weird parts with our vertically integrated customers
> with their own sales teams.
> 
> Sorry for the essay. I went though our catalog one day and had the very
> same question you did so I wanted to dump as much as I could.

Thank you for this write up! Will save this mail for future reference.



> 
> ~Bryan
> 



From anshuman.khandual at arm.com  Sun Dec 15 20:08:26 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 16 Dec 2024 09:38:26 +0530
Subject: [PATCH V3 2/7] arm64/sysreg: Add register fields for MDSELR_EL1
In-Reply-To: <20241216040831.2448257-1-anshuman.khandual@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
Message-ID: <20241216040831.2448257-3-anshuman.khandual@arm.com>

This adds register fields for MDSELR_EL1 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a6cbe0dcd63b..fe878eb194a0 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -93,6 +93,17 @@ Res0	63:32
 Field	31:0	DTRTX
 EndSysreg
 
+Sysreg	MDSELR_EL1	2	0	0	4	2
+Res0	63:6
+Enum	5:4	BANK
+	0b00	BANK_0
+	0b01	BANK_1
+	0b10	BANK_2
+	0b11	BANK_3
+EndEnum
+Res0	3:0
+EndSysreg
+
 Sysreg	OSECCR_EL1	2	0	0	6	2
 Res0	63:32
 Field	31:0	EDECCR
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Dec 15 20:08:25 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 16 Dec 2024 09:38:25 +0530
Subject: [PATCH V3 1/7] arm64/sysreg: Update register fields for ID_AA64MMFR0_EL1
In-Reply-To: <20241216040831.2448257-1-anshuman.khandual@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
Message-ID: <20241216040831.2448257-2-anshuman.khandual@arm.com>

This updates ID_AA64MMFR0_EL1 register fields as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Mark Brown <broonie at 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 b081b54d6d22..a6cbe0dcd63b 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1591,6 +1591,7 @@ EndEnum
 UnsignedEnum	59:56	FGT
 	0b0000	NI
 	0b0001	IMP
+	0b0010	FGT2
 EndEnum
 Res0	55:48
 UnsignedEnum	47:44	EXS
@@ -1652,6 +1653,7 @@ Enum	3:0	PARANGE
 	0b0100	44
 	0b0101	48
 	0b0110	52
+	0b0111	56
 EndEnum
 EndSysreg
 
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Dec 15 20:08:24 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 16 Dec 2024 09:38:24 +0530
Subject: [PATCH V3 0/7] arm64/hw_breakpoint: Enable FEAT_Debugv8p9
Message-ID: <20241216040831.2448257-1-anshuman.khandual@arm.com>

This series enables FEAT_Debugv8p9 thus extending breakpoint and watchpoint
support upto 64. This series is based on v6.13-rc3 although this depends on
FEAT_FGT2 FGU series posted earlier, for MDSELR_EL1 handling in various KVM
guest configurations.

https://lore.kernel.org/all/20241210055311.780688-3-anshuman.khandual at arm.com/

Cc: Jonathan Corbet <corbet at lwn.net>
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: Mark Brown <broonie at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.linux.dev
Cc: linux-kernel at vger.kernel.org

Changes in V3:

- Marked ID_AA64DFR1_EL1.ABLE as FTR_NONSTRICT in ftr_id_aa64dfr1[]
- Dropped MDCR_EL3.TDA boot requirement from documentation (separate series)
- Dropped MDCR_EL2_EBWE definition as MDCR_EL2 is now defined in tools sysreg
- Used SYS_FIELD_PREP() in read_wb_reg() and write_wb_reg()
- Added MAX_PER_BANK based BUILD_BUG_ON() tests in arch_hw_breakpoint_init()
- Dropped local variables i.e mdsel_bank and index
- Derived bank and index from MAX_PER_BANK as required

Changes in V2:

https://lore.kernel.org/all/20241028053426.2486633-1-anshuman.khandual at arm.com/

Following changes have been made per review comments from Mark Rutland

- Orr MDCR_EL2_EBWE directly without an intermittent register
- Alphabetically order header files in debug-monitors.c
- Dropped embwe_ref_count mechanism
- Dropped preempt_enable() from AARCH64_DBG_READ
- Dropped preempt_disable() from AARCH64_DBG_WRITE
- Dropped set_bank_index()
- Renamed read/write_wb_reg() as __read/__write_wb_reg()
- Modified read/write_wb_reg() to have MDSELR_E1 based banked read/write
- Added required sysreg tools patches from KVM FEAT_FGT2 series for build

Changes in V1:

https://lore.kernel.org/all/20241001043602.1116991-1-anshuman.khandual at arm.com/

- Changed FTR_STRICT to FTR_NONSTRICT for the following ID_AA64DFR1_EL1
  register fields - ABL_CMPs, DPFZS, PMICNTR, CTX_CMPs, WRPs and BRPs

Changes in RFC V2:

https://lore.kernel.org/linux-arm-kernel/20240620092607.267132-1-anshuman.khandual at arm.com/

- This series has been split from RFC V1 dealing only with arm64 breakpoints
- Restored back DBG_MDSCR_MASK definition (unrelated change)
- Added preempt_disable()/enable() blocks between selecting banks and registers

Changes in RFC:

https://lore.kernel.org/all/20240405080008.1225223-1-anshuman.khandual at arm.com/


Anshuman Khandual (7):
  arm64/sysreg: Update register fields for ID_AA64MMFR0_EL1
  arm64/sysreg: Add register fields for MDSELR_EL1
  arm64/sysreg: Add register fields for HDFGRTR2_EL2
  arm64/sysreg: Add register fields for HDFGWTR2_EL2
  arm64/cpufeature: Add field details for ID_AA64DFR1_EL1 register
  arm64/boot: Enable EL2 requirements for FEAT_Debugv8p9
  arm64/hw_breakpoint: Enable FEAT_Debugv8p9

 Documentation/arch/arm64/booting.rst    | 18 +++++++
 arch/arm64/include/asm/debug-monitors.h |  1 +
 arch/arm64/include/asm/el2_setup.h      | 26 +++++++++
 arch/arm64/include/asm/hw_breakpoint.h  | 47 +++++++++++++----
 arch/arm64/kernel/cpufeature.c          | 21 ++++++--
 arch/arm64/kernel/debug-monitors.c      | 15 ++++--
 arch/arm64/kernel/hw_breakpoint.c       | 48 ++++++++++++++++-
 arch/arm64/tools/sysreg                 | 70 +++++++++++++++++++++++++
 8 files changed, 225 insertions(+), 21 deletions(-)

-- 
2.25.1



From anshuman.khandual at arm.com  Sun Dec 15 20:31:55 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 16 Dec 2024 10:01:55 +0530
Subject: [PATCH] arm64: mm: fault: replace the behavior of fault_info[18]
In-Reply-To: <CANTT7qi=wZvOQP4PFEi7300MbNjsJ2q=WXceHch1BUrtL-WFDQ@mail.gmail.com>
References: <20241214091937.203842-1-lsahn@ooseel.net>
 <CANTT7qi=wZvOQP4PFEi7300MbNjsJ2q=WXceHch1BUrtL-WFDQ@mail.gmail.com>
Message-ID: <1bd6db20-7012-49d5-9e9f-38a84c3946a5@arm.com>



On 12/14/24 15:08, Leesoo Ahn wrote:
> I just figured out that do_sea(..) isn't the right function to deal
> with VMSAv9-128.
> Please ignore this patch.

Right, actual handling needs to be sorted out when 128 bit PTE is enabled.
For example, following change might be required to handle 128 bit related
faults but the handlers such as do_sea(), do_bad(), do_translation_fault()
need to be changed and tested for 128 bit PTE format.

--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -415,7 +415,8 @@ static inline bool esr_fsc_is_translation_fault(unsigned long esr)
               (esr == ESR_ELx_FSC_FAULT_L(2)) ||
               (esr == ESR_ELx_FSC_FAULT_L(1)) ||
               (esr == ESR_ELx_FSC_FAULT_L(0)) ||
-              (esr == ESR_ELx_FSC_FAULT_L(-1));
+              (esr == ESR_ELx_FSC_FAULT_L(-1)) ||
+              (esr == ESR_ELx_FSC_FAULT_L(-2));
 }
 
 static inline bool esr_fsc_is_permission_fault(unsigned long esr)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 8b281cf308b3..3a35c580395e 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -823,7 +823,7 @@ static const struct fault_info fault_info[] = {
        { 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_sea,               SIGKILL, SI_KERNEL,     "level -2 (translation table walk)"     },
        { 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)"      },
@@ -847,9 +847,9 @@ static const struct fault_info fault_info[] = {
        { do_bad,               SIGKILL, SI_KERNEL,     "unknown 39"                    },
        { do_bad,               SIGKILL, SI_KERNEL,     "unknown 40"                    },
        { do_bad,               SIGKILL, SI_KERNEL,     "level -1 address size fault"   },
-       { do_bad,               SIGKILL, SI_KERNEL,     "unknown 42"                    },
+       { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level -2 translation fault"    },
        { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level -1 translation fault"    },
-       { do_bad,               SIGKILL, SI_KERNEL,     "unknown 44"                    },
+       { do_bad,               SIGKILL, SI_KERNEL,     "level -2 address size fault"   },
        { do_bad,               SIGKILL, SI_KERNEL,     "unknown 45"                    },
        { do_bad,               SIGKILL, SI_KERNEL,     "unknown 46"                    },
        { do_bad,               SIGKILL, SI_KERNEL,     "unknown 47"                    },


> 
> BR
> Leesoo
> 
> 2024? 12? 14? (?) ?? 6:20, Leesoo Ahn <lsahn at ooseel.net>?? ??:
>>
>> Replace the behavior of 18th element of fault_info with the 'fn' member to
>> do_sea(..) and 'name' to 'level -2 (translation table walk)' based on
>> the information[1] of the latest reference manual[2].
>>
>> The information has described in the chapter, D24.2.40 of [2] and
>> DFSC[5:0] bit (stands for Data Fault Status Code).
>>
>> [1]: Synchronous External abort on translation table walk, level -2
>> [2]: Arm Architecture Reference Manual, for A-profile architecture
>>
>> Signed-off-by: Leesoo Ahn <lsahn at ooseel.net>
>> ---
>>  arch/arm64/mm/fault.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>> index ef63651099a9..b1c08289a5cc 100644
>> --- a/arch/arm64/mm/fault.c
>> +++ b/arch/arm64/mm/fault.c
>> @@ -863,7 +863,7 @@ static const struct fault_info fault_info[] = {
>>         { 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_sea,               SIGKILL, SI_KERNEL,     "level -2 (translation table walk)"     },
>>         { 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)"      },
>> --
>> 2.46.1
>>
> 


From manivannan.sadhasivam at linaro.org  Sun Dec 15 21:08:29 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Mon, 16 Dec 2024 10:38:29 +0530
Subject: [PATCH] PCI: check bridge->bus in pci_host_common_remove
In-Reply-To: <20241215132640.GA2476@localhost.localdomain>
References: <20241028084644.3778081-1-peng.fan@oss.nxp.com>
 <20241115062005.6ifvr6ens2qnrrrf@thinkpad>
 <PAXPR04MB8459D1507CA69498D8C38E0488242@PAXPR04MB8459.eurprd04.prod.outlook.com>
 <20241115144720.ovsyq2ani47norby@thinkpad>
 <20241127195650.GA4132105-robh@kernel.org>
 <20241202092902.rp6xb3f64llpabbi@thinkpad>
 <CAL_Jsq+R39jtCeDecpEHbKq+4N-uirMQmsuNG1NaVe1Vnnnv3Q@mail.gmail.com>
 <20241215132640.GA2476@localhost.localdomain>
Message-ID: <20241216050829.m4f5wqnzstsqqfcj@thinkpad>

On Sun, Dec 15, 2024 at 09:26:40PM +0800, Peng Fan wrote:
> Hi Rob,
> 
> On Mon, Dec 02, 2024 at 07:55:27AM -0600, Rob Herring wrote:
> >On Mon, Dec 2, 2024 at 3:29?AM Manivannan Sadhasivam
> ><manivannan.sadhasivam at linaro.org> wrote:
> >>
> >> On Wed, Nov 27, 2024 at 01:56:50PM -0600, Rob Herring wrote:
> >> > On Fri, Nov 15, 2024 at 08:17:20PM +0530, Manivannan Sadhasivam wrote:
> >> > > On Fri, Nov 15, 2024 at 10:14:10AM +0000, Peng Fan wrote:
> >> > > > Hi Manivannan,
> >> > > >
> >> > > > > Subject: Re: [PATCH] PCI: check bridge->bus in
> >> > > > > pci_host_common_remove
> >> > > > >
> >> > > > > On Mon, Oct 28, 2024 at 04:46:43PM +0800, Peng Fan (OSS) wrote:
> >> > > > > > From: Peng Fan <peng.fan at nxp.com>
> >> > > > > >
> >> > > > > > When PCI node was created using an overlay and the overlay is
> >> > > > > > reverted/destroyed, the "linux,pci-domain" property no longer exists,
> >> > > > > > so of_get_pci_domain_nr will return failure. Then
> >> > > > > > of_pci_bus_release_domain_nr will actually use the dynamic IDA,
> >> > > > > even
> >> > > > > > if the IDA was allocated in static IDA. So the flow is as below:
> >> > > > > > A: of_changeset_revert
> >> > > > > >     pci_host_common_remove
> >> > > > > >      pci_bus_release_domain_nr
> >> > > > > >        of_pci_bus_release_domain_nr
> >> > > > > >          of_get_pci_domain_nr      # fails because overlay is gone
> >> > > > > >          ida_free(&pci_domain_nr_dynamic_ida)
> >> > > > > >
> >> > > > > > With driver calls pci_host_common_remove explicity, the flow
> >> > > > > becomes:
> >> > > > > > B pci_host_common_remove
> >> > > > > >    pci_bus_release_domain_nr
> >> > > > > >     of_pci_bus_release_domain_nr
> >> > > > > >      of_get_pci_domain_nr      # succeeds in this order
> >> > > > > >       ida_free(&pci_domain_nr_static_ida)
> >> > > > > > A of_changeset_revert
> >> > > > > >    pci_host_common_remove
> >> > > > > >
> >> > > > > > With updated flow, the pci_host_common_remove will be called
> >> > > > > twice, so
> >> > > > > > need to check 'bridge->bus' to avoid accessing invalid pointer.
> >> > > > > >
> >> > > > > > Fixes: c14f7ccc9f5d ("PCI: Assign PCI domain IDs by ida_alloc()")
> >> > > > > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> >> > > > >
> >> > > > > I went through the previous discussion [1] and I couldn't see an
> >> > > > > agreement on the point raised by Bjorn on 'removing the host bridge
> >> > > > > before the overlay'.
> >> > > >
> >> > > > This patch is an agreement to Bjorn's idea.
> >> > > >
> >> > > > I have added pci_host_common_remove to remove host bridge
> >> > > > before removing overlay as I wrote in commit log.
> >> > > >
> >> > > > But of_changeset_revert will still runs into pci_host_
> >> > > > common_remove to remove the host bridge again. Per
> >> > > > my view, the design of of_changeset_revert to remove
> >> > > > the device tree node will trigger device remove, so even
> >> > > > pci_host_common_remove was explicitly used before
> >> > > > of_changeset_revert. The following call to of_changeset_revert
> >> > > > will still call pci_host_common_remove.
> >> > > >
> >> > > > So I did this patch to add a check of 'bus' to avoid remove again.
> >> > > >
> >> > >
> >> > > Ok. I think there was a misunderstanding. Bjorn's example driver,
> >> > > 'i2c-demux-pinctrl' applies the changeset, then adds the i2c adapter for its
> >> > > own. And in remove(), it does the reverse.
> >> > >
> >> > > But in your case, the issue is with the host bridge driver that gets probed
> >> > > because of the changeset. While with 'i2c-demux-pinctrl' driver, it only
> >> > > applies the changeset. So we cannot compare both drivers. I believe in your
> >> > > case, 'i2c-demux-pinctrl' becomes 'jailhouse', isn't it?
> >> > >
> >> > > So in your case, changeset is applied by jailhouse and that causes the
> >> > > platform device to be created for the host bridge and then the host bridge
> >> > > driver gets probed. So during destroy(), you call of_changeset_revert() that
> >> > > removes the platform device and during that process it removes the host bridge
> >> > > driver. The issue happens because during host bridge remove, it calls
> >> > > pci_remove_root_bus() and that tries to remove the domain_nr using
> >> > > pci_bus_release_domain_nr().
> >> > >
> >> > > But pci_bus_release_domain_nr() uses DT node to check whether to free the
> >> > > domain_nr from static IDA or dynamic IDA. And because there is no DT node exist
> >> > > at this time (it was already removed by of_changeset_revert()), it forces
> >> > > pci_bus_release_domain_nr() to use dynamic IDA even though the IDA was initially
> >> > > allocated from static IDA.
> >> >
> >> > Putting linux,pci-domain in an overlay is the same problem as aliases in
> >> > overlays[1]. It's not going to work well.
> >> >
> >> > IMO, you can have overlays, or you can have static domains. You can't
> >> > have both.
> >> >
> >>
> >> Okay.
> >>
> >> > > I think a neat way to solve this issue would be by removing the OF node only
> >> > > after removing all platform devices/drivers associated with that node. But I
> >> > > honestly do not know whether that is possible or not. Otherwise, any other
> >> > > driver that relies on the OF node in its remove() callback, could suffer from
> >> > > the same issue. And whatever fix we may come up with in PCI core, it will be a
> >> > > band-aid only.
> >> > >
> >> > > I'd like to check with Rob first about his opinion.
> >> >
> >> > If the struct device has an of_node set, there should be a reference
> >> > count on that node. But I think that only prevents the node from being
> >> > freed. It does not prevent the overlay from being detached. This is one
> >> > of many of the issues with overlays Frank painstakingly documented[2].
> >> >
> >>
> >> Ah, I do remember this page as Frank ended up creating it based on my
> >> continuous nudge to add CONFIG_FS interface for applying overlays.
> >>
> >> So why are we applying overlays in kernel now?
> >
> >That's been the case for some time. Mostly it's been for fixups of old
> >to new bindings, but those all got dropped at some point. The in
> >kernel users are very specific use cases where we know something about
> >what's in the overlay. In contrast, configfs interface allows for any
> >change to any node or property with no control over it by the kernel.
> >Never say never, but I just don't see that ever happening upstream.
> 
> So should I switch to use configfs for jailhouse case? Currently
> we use overlay to add a virtual pci node to kernel device tree.
> 

Not at all. I think you have 2 options:

1. Get rid of 'linux,pci-domain' from overlay and rely on static id allocation.
2. Make sure the driver is unbind for each device before removing the overlays.

Options 1 is to avoid your issue and option 2 is to fix your issue. You can
decide which one to opt for :)

- Mani

-- 
????????? ????????


From lcherian at marvell.com  Sun Dec 15 21:30:06 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:00:06 +0530
Subject: [PATCH v13 0/8] Coresight for Kernel panic and watchdog reset
Message-ID: <20241216053014.3427909-1-lcherian@marvell.com>

This patch series is rebased on coresight-next-v6.12.rc4

* Patches 1 & 2 adds support for allocation of trace buffer pages from
  reserved RAM
* Patches 3 & 4 adds support for saving metadata at the time of kernel panic 
* Patch 5 adds support for reading trace data captured at the time of panic
* Patches 6 & 7 adds support for disabling coresight blocks at the time of panic
* Patch 8: Gives the full description about this feature as part of documentation 

v12 is posted here,
https://lore.kernel.org/linux-arm-kernel/20241129084714.3057080-1-lcherian at marvell.com/   

Changelog from v12:
* Fixed wrong buffer pointer passed to coresigh_insert_barrier_packet  
* tmc_read_prepare/unprepare_crashdata need to be called only once and
  hence removed from read path and added to tmc_probe
* tmc_read_prepare_crashdata renamed to tmc_prepare_crashdata and
  avoid taking locks  as its moved to probe function.
* Introduced read status flag, "reading" specific to reserved buffer to keep the
  reserved buffer reading independent of the regular buffer.
* open/release ops for reserved buffer has to take care only about the
  set/unset the "reading" status flag as the reserved buffer is prepared
  during the probe time itself.  
* Few other trivial changes  

Changelog from v11:
Convert all commands to literal code blocks, that was missed out in v11.
No other code changes.

Changelog from v10:
* Converted all csdev_access_* to readl functions in tmc_panic_sync_*
* Added "tmc" prefix for register snapshots in struct tmc_crash_metadata
* Converted dev_info to dev_dbg in panic handlers 
* Converted dsb to dmb in panic handlers 
* Fixed marking metadata as invalid when a user is trying to use the
  reserved buffer. Earlier this was wrongly set at the time of reading
  reserved trace buffer.
* Moved common validation checks to is_tmc_crashdata_valid and minor
  code rearrangements for efficiency
* Got rid of sink specific prepare/unprepare invocations  
* Got rid of full from struct tmc_resrv_buf
* While reading crashdata, size is now calculated from metadata instead 
  of relying on reserved buffer size populated by dtb 
* Minor documenation fixes

Changelog from v9:
* Add common helper function of_tmc_get_reserved_resource_by_name
  for better code reuse
* Reserved buffer validity and crashdata validity has been separated to
  avoid interdependence
* New fields added to crash metadata: version, ffcr, ffsr, mode
* Version checks added for metadata validation
* Special file /dev/crash_tmc_xxx would be available only when
  crash metadata is valid
* Removed READ_CRASHDATA mode meant for special casing crashdata reads.
  Instead, dedicated read function added for crashdata reads from reserved
  buffer which is common for both ETR and ETF sinks as well.
* Documentation added to Documentation/tracing/coresight/panic.rst

Changelog from v8:
* Added missing exit path on error in __tmc_probe.
* Few whitespace fixes, checkpatch fixes.
* With perf sessions honouring stop_on_flush sysfs attribute, 
  removed redundant variable stop_on_flush_en. 

Changelog from v7:
* Fixed breakage on perf test -vvvv  "arm coresight".
  No issues seen with and without "resrv" buffer mode
* Moved the crashdev registration into a separate function.
* Removed redundant variable in tmc_etr_setup_crashdata_buf
* Avoided a redundant memcpy in tmc_panic_sync_etf.
* Tested kernel panic with trace session started uisng perf.   
  Please see the title "Perf based testing" below for details.
  For this, stop_on_flush sysfs attribute is taken into 
  consideration while starting perf sessions as well. 

Changelog from v6:
* Added special device files for reading crashdata, so that
  read_prevboot mode flag is removed. 
* Added new sysfs TMC device attribute, stop_on_flush.
  Stop on flush trigger event is disabled by default. 
  User need to explicitly enable this from sysfs for panic stop
  to work.
* Address parameter for panicstop ETM configuration is   
  chosen as kernel "panic" address by default.
* Added missing tmc_wait_for_tmcready during panic handling
* Few other misc code rearrangements. 

Changelog from v5:
* Fixed issues reported by CONFIG_DEBUG_ATOMIC_SLEEP
* Fixed a memory leak while reading data from /dev/tmc_etrx in
  READ_PREVBOOT mode
* Tested reading trace data from crashdump kernel

Changelog from v4:
* Device tree binding
  - Description is made more explicit on the usage of reserved memory
    region
  - Mismatch in memory region names in dts binding and driver fixed
  - Removed "mem" suffix from the memory region names
* Rename "struct tmc_register_snapshot" ->  "struct tmc_crash_metadata",
  since it contains more than register snapshot.
  Related variables are named accordingly.
* Rename struct tmc_drvdata members
   resrv_buf -> crash_tbuf
   metadata  -> crash_mdata
* Size field in metadata refers to RSZ register and hence indicates the
  size in 32 bit words. ETR metadata follows this convention, the same
  has been extended to ETF metadata as well.
* Added crc32 for more robust metadata and tracedata validation.
* Added/modified dev_dbg messages during metadata validation
* Fixed a typo in patch 5 commit description

Changelog from v3:
* Converted the Coresight ETM driver change to a named configuration.
  RFC tag has been removed with this change.
* Fixed yaml issues reported by "make dt_binding_check"
* Added names for reserved memory regions 0 and 1
* Added prevalidation checks for metadata processing
* Fixed a regression introduced in RFC v3
  - TMC Status register was getting saved wrongly
* Reverted memremap attribute changes from _WB to _WC to match
  with the dma map attributes
* Introduced reserved buffer mode specific .sync op.
  This fixes a possible crash when reserved buffer mode was used in
  normal trace capture, due to unwanted dma maintenance operations.




Linu Cherian (8):
  dt-bindings: arm: coresight-tmc: Add "memory-region" property
  coresight: tmc-etr: Add support to use reserved trace memory
  coresight: core: Add provision for panic callbacks
  coresight: tmc: Enable panic sync handling
  coresight: tmc: Add support for reading crash data
  coresight: tmc: Stop trace capture on FlIn
  coresight: config: Add preloaded configuration
  Documentation: coresight: Panic support

 .../bindings/arm/arm,coresight-tmc.yaml       |  26 ++
 Documentation/trace/coresight/panic.rst       | 362 ++++++++++++++++++
 drivers/hwtracing/coresight/Makefile          |   2 +-
 .../coresight/coresight-cfg-preload.c         |   2 +
 .../coresight/coresight-cfg-preload.h         |   2 +
 .../hwtracing/coresight/coresight-cfg-pstop.c |  83 ++++
 drivers/hwtracing/coresight/coresight-core.c  |  42 ++
 .../hwtracing/coresight/coresight-tmc-core.c  | 308 ++++++++++++++-
 .../hwtracing/coresight/coresight-tmc-etf.c   |  92 ++++-
 .../hwtracing/coresight/coresight-tmc-etr.c   | 184 ++++++++-
 drivers/hwtracing/coresight/coresight-tmc.h   | 105 +++++
 include/linux/coresight.h                     |  12 +
 12 files changed, 1208 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/trace/coresight/panic.rst
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pstop.c

-- 
2.34.1



From lcherian at marvell.com  Sun Dec 15 21:30:07 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:00:07 +0530
Subject: [PATCH v13 1/8] dt-bindings: arm: coresight-tmc: Add "memory-region" property
In-Reply-To: <20241216053014.3427909-1-lcherian@marvell.com>
References: <20241216053014.3427909-1-lcherian@marvell.com>
Message-ID: <20241216053014.3427909-2-lcherian@marvell.com>

memory-region 0: Reserved trace buffer memory

  TMC ETR: When available, use this reserved memory region for
  trace data capture. Same region is used for trace data
  retention after a panic or watchdog reset.

  TMC ETF: When available, use this reserved memory region for
  trace data retention synced from internal SRAM after a panic or
  watchdog reset.

memory-region 1: Reserved meta data memory

  TMC ETR, ETF: When available, use this memory for register
  snapshot retention synced from hardware registers after a panic
  or watchdog reset.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Linu Cherian <lcherian at marvell.com>
---
Changelog from v12:
No changes

 .../bindings/arm/arm,coresight-tmc.yaml       | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
index cb8dceaca70e..4787d7c6bac2 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
@@ -101,6 +101,29 @@ properties:
           and ETF configurations.
         $ref: /schemas/graph.yaml#/properties/port
 
+  memory-region:
+    items:
+      - description: Reserved trace buffer memory for ETR and ETF sinks.
+          For ETR, this reserved memory region is used for trace data capture.
+          Same region is used for trace data retention as well after a panic
+          or watchdog reset.
+          This reserved memory region is used as trace buffer or used for trace
+          data retention only if specifically selected by the user in sysfs
+          interface.
+          The default memory usage models for ETR in sysfs/perf modes are
+          otherwise unaltered.
+
+          For ETF, this reserved memory region is used by default for
+          retention of trace data synced from internal SRAM after a panic
+          or watchdog reset.
+      - description: Reserved meta data memory. Used for ETR and ETF sinks
+          for storing metadata.
+
+  memory-region-names:
+    items:
+      - const: tracedata
+      - const: metadata
+
 required:
   - compatible
   - reg
@@ -115,6 +138,9 @@ examples:
     etr at 20070000 {
         compatible = "arm,coresight-tmc", "arm,primecell";
         reg = <0x20070000 0x1000>;
+        memory-region = <&etr_trace_mem_reserved>,
+                       <&etr_mdata_mem_reserved>;
+        memory-region-names = "tracedata", "metadata";
 
         clocks = <&oscclk6a>;
         clock-names = "apb_pclk";
-- 
2.34.1



From lcherian at marvell.com  Sun Dec 15 21:30:08 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:00:08 +0530
Subject: [PATCH v13 2/8] coresight: tmc-etr: Add support to use reserved trace memory
In-Reply-To: <20241216053014.3427909-1-lcherian@marvell.com>
References: <20241216053014.3427909-1-lcherian@marvell.com>
Message-ID: <20241216053014.3427909-3-lcherian@marvell.com>

Add support to use reserved memory for coresight ETR trace buffer.

Introduce a new ETR buffer mode called ETR_MODE_RESRV, which
becomes available when ETR device tree node is supplied with a valid
reserved memory region.

ETR_MODE_RESRV can be selected only by explicit user request.

$ echo resrv >/sys/bus/coresight/devices/tmc_etr<N>/buf_mode_preferred

Signed-off-by: Anil Kumar Reddy <areddy3 at marvell.com>
Signed-off-by: Linu Cherian <lcherian at marvell.com>
Reviewed-by: James Clark <james.clark at arm.com>
---
Changelog from v12:
No changes.

 .../hwtracing/coresight/coresight-tmc-core.c  | 50 ++++++++++++
 .../hwtracing/coresight/coresight-tmc-etr.c   | 79 +++++++++++++++++++
 drivers/hwtracing/coresight/coresight-tmc.h   | 25 ++++++
 3 files changed, 154 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 3a482fd2cb22..248989833b20 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
 #include <linux/platform_device.h>
@@ -398,6 +399,53 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
 
 static const struct amba_id tmc_ids[];
 
+static int of_tmc_get_reserved_resource_by_name(struct device *dev,
+						const char *name,
+						struct resource *res)
+{
+	int index, rc = -ENODEV;
+	struct device_node *node;
+
+	if (!is_of_node(dev->fwnode))
+		return -ENODEV;
+
+	index = of_property_match_string(dev->of_node, "memory-region-names",
+					 name);
+	if (index < 0)
+		return rc;
+
+	node = of_parse_phandle(dev->of_node, "memory-region", index);
+	if (!node)
+		return rc;
+
+	if (!of_address_to_resource(node, 0, res) &&
+	    res->start != 0 && resource_size(res) != 0)
+		rc = 0;
+	of_node_put(node);
+
+	return rc;
+}
+
+static void tmc_get_reserved_region(struct device *parent)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
+	struct resource res;
+
+	if (of_tmc_get_reserved_resource_by_name(parent, "tracedata", &res))
+		return;
+
+	drvdata->resrv_buf.vaddr = memremap(res.start,
+						resource_size(&res),
+						MEMREMAP_WC);
+	if (IS_ERR_OR_NULL(drvdata->resrv_buf.vaddr)) {
+		dev_err(parent, "Reserved trace buffer mapping failed\n");
+		return;
+	}
+
+	drvdata->resrv_buf.paddr = res.start;
+	drvdata->resrv_buf.size  = resource_size(&res);
+}
+
 /* Detect and initialise the capabilities of a TMC ETR */
 static int tmc_etr_setup_caps(struct device *parent, u32 devid,
 			      struct csdev_access *access)
@@ -508,6 +556,8 @@ static int __tmc_probe(struct device *dev, struct resource *res)
 		drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4;
 	}
 
+	tmc_get_reserved_region(dev);
+
 	desc.dev = dev;
 
 	switch (drvdata->config_type) {
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..8bca5b36334a 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -30,6 +30,7 @@ struct etr_buf_hw {
 	bool	has_iommu;
 	bool	has_etr_sg;
 	bool	has_catu;
+	bool	has_resrv;
 };
 
 /*
@@ -695,6 +696,75 @@ static const struct etr_buf_operations etr_flat_buf_ops = {
 	.get_data = tmc_etr_get_data_flat_buf,
 };
 
+/*
+ * tmc_etr_alloc_resrv_buf: Allocate a contiguous DMA buffer from reserved region.
+ */
+static int tmc_etr_alloc_resrv_buf(struct tmc_drvdata *drvdata,
+				  struct etr_buf *etr_buf, int node,
+				  void **pages)
+{
+	struct etr_flat_buf *resrv_buf;
+	struct device *real_dev = drvdata->csdev->dev.parent;
+
+	/* We cannot reuse existing pages for resrv buf */
+	if (pages)
+		return -EINVAL;
+
+	resrv_buf = kzalloc(sizeof(*resrv_buf), GFP_KERNEL);
+	if (!resrv_buf)
+		return -ENOMEM;
+
+	resrv_buf->daddr = dma_map_resource(real_dev, drvdata->resrv_buf.paddr,
+					   drvdata->resrv_buf.size,
+					   DMA_FROM_DEVICE, 0);
+	if (dma_mapping_error(real_dev, resrv_buf->daddr)) {
+		dev_err(real_dev, "failed to map source buffer address\n");
+		kfree(resrv_buf);
+		return -ENOMEM;
+	}
+
+	resrv_buf->vaddr = drvdata->resrv_buf.vaddr;
+	resrv_buf->size = etr_buf->size = drvdata->resrv_buf.size;
+	resrv_buf->dev = &drvdata->csdev->dev;
+	etr_buf->hwaddr = resrv_buf->daddr;
+	etr_buf->mode = ETR_MODE_RESRV;
+	etr_buf->private = resrv_buf;
+	return 0;
+}
+
+static void tmc_etr_free_resrv_buf(struct etr_buf *etr_buf)
+{
+	struct etr_flat_buf *resrv_buf = etr_buf->private;
+
+	if (resrv_buf && resrv_buf->daddr) {
+		struct device *real_dev = resrv_buf->dev->parent;
+
+		dma_unmap_resource(real_dev, resrv_buf->daddr,
+				resrv_buf->size, DMA_FROM_DEVICE, 0);
+	}
+	kfree(resrv_buf);
+}
+
+static void tmc_etr_sync_resrv_buf(struct etr_buf *etr_buf, u64 rrp, u64 rwp)
+{
+	/*
+	 * Adjust the buffer to point to the beginning of the trace data
+	 * and update the available trace data.
+	 */
+	etr_buf->offset = rrp - etr_buf->hwaddr;
+	if (etr_buf->full)
+		etr_buf->len = etr_buf->size;
+	else
+		etr_buf->len = rwp - rrp;
+}
+
+static const struct etr_buf_operations etr_resrv_buf_ops = {
+	.alloc = tmc_etr_alloc_resrv_buf,
+	.free = tmc_etr_free_resrv_buf,
+	.sync = tmc_etr_sync_resrv_buf,
+	.get_data = tmc_etr_get_data_flat_buf,
+};
+
 /*
  * tmc_etr_alloc_sg_buf: Allocate an SG buf @etr_buf. Setup the parameters
  * appropriately.
@@ -801,6 +871,7 @@ static const struct etr_buf_operations *etr_buf_ops[] = {
 	[ETR_MODE_FLAT] = &etr_flat_buf_ops,
 	[ETR_MODE_ETR_SG] = &etr_sg_buf_ops,
 	[ETR_MODE_CATU] = NULL,
+	[ETR_MODE_RESRV] = &etr_resrv_buf_ops
 };
 
 void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu)
@@ -826,6 +897,7 @@ static inline int tmc_etr_mode_alloc_buf(int mode,
 	case ETR_MODE_FLAT:
 	case ETR_MODE_ETR_SG:
 	case ETR_MODE_CATU:
+	case ETR_MODE_RESRV:
 		if (etr_buf_ops[mode] && etr_buf_ops[mode]->alloc)
 			rc = etr_buf_ops[mode]->alloc(drvdata, etr_buf,
 						      node, pages);
@@ -844,6 +916,7 @@ static void get_etr_buf_hw(struct device *dev, struct etr_buf_hw *buf_hw)
 	buf_hw->has_iommu = iommu_get_domain_for_dev(dev->parent);
 	buf_hw->has_etr_sg = tmc_etr_has_cap(drvdata, TMC_ETR_SG);
 	buf_hw->has_catu = !!tmc_etr_get_catu_device(drvdata);
+	buf_hw->has_resrv = tmc_has_reserved_buffer(drvdata);
 }
 
 static bool etr_can_use_flat_mode(struct etr_buf_hw *buf_hw, ssize_t etr_buf_size)
@@ -1831,6 +1904,7 @@ static const char *const buf_modes_str[] = {
 	[ETR_MODE_FLAT]		= "flat",
 	[ETR_MODE_ETR_SG]	= "tmc-sg",
 	[ETR_MODE_CATU]		= "catu",
+	[ETR_MODE_RESRV]	= "resrv",
 	[ETR_MODE_AUTO]		= "auto",
 };
 
@@ -1849,6 +1923,9 @@ static ssize_t buf_modes_available_show(struct device *dev,
 	if (buf_hw.has_catu)
 		size += sysfs_emit_at(buf, size, "%s ", buf_modes_str[ETR_MODE_CATU]);
 
+	if (buf_hw.has_resrv)
+		size += sysfs_emit_at(buf, size, "%s ", buf_modes_str[ETR_MODE_RESRV]);
+
 	size += sysfs_emit_at(buf, size, "\n");
 	return size;
 }
@@ -1876,6 +1953,8 @@ static ssize_t buf_mode_preferred_store(struct device *dev,
 		drvdata->etr_mode = ETR_MODE_ETR_SG;
 	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_CATU]) && buf_hw.has_catu)
 		drvdata->etr_mode = ETR_MODE_CATU;
+	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_RESRV]) && buf_hw.has_resrv)
+		drvdata->etr_mode = ETR_MODE_RESRV;
 	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_AUTO]))
 		drvdata->etr_mode = ETR_MODE_AUTO;
 	else
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 2671926be62a..d2261eddab71 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -135,6 +135,7 @@ enum etr_mode {
 	ETR_MODE_FLAT,		/* Uses contiguous flat buffer */
 	ETR_MODE_ETR_SG,	/* Uses in-built TMC ETR SG mechanism */
 	ETR_MODE_CATU,		/* Use SG mechanism in CATU */
+	ETR_MODE_RESRV,		/* Use reserved region contiguous buffer */
 	ETR_MODE_AUTO,		/* Use the default mechanism */
 };
 
@@ -164,6 +165,17 @@ struct etr_buf {
 	void				*private;
 };
 
+/**
+ * @paddr	: Start address of reserved memory region.
+ * @vaddr	: Corresponding CPU virtual address.
+ * @size	: Size of reserved memory region.
+ */
+struct tmc_resrv_buf {
+	phys_addr_t     paddr;
+	void		*vaddr;
+	size_t		size;
+};
+
 /**
  * struct tmc_drvdata - specifics associated to an TMC component
  * @pclk:	APB clock if present, otherwise NULL
@@ -189,6 +201,10 @@ struct etr_buf {
  * @idr_mutex:	Access serialisation for idr.
  * @sysfs_buf:	SYSFS buffer for ETR.
  * @perf_buf:	PERF buffer for ETR.
+ * @resrv_buf:	Used by ETR as hardware trace buffer and for trace data
+ *		retention (after crash) only when ETR_MODE_RESRV buffer
+ *		mode is enabled. Used by ETF for trace data retention
+ *		(after crash) by default.
  */
 struct tmc_drvdata {
 	struct clk		*pclk;
@@ -214,6 +230,7 @@ struct tmc_drvdata {
 	struct mutex		idr_mutex;
 	struct etr_buf		*sysfs_buf;
 	struct etr_buf		*perf_buf;
+	struct tmc_resrv_buf	resrv_buf;
 };
 
 struct etr_buf_operations {
@@ -331,6 +348,14 @@ tmc_sg_table_buf_size(struct tmc_sg_table *sg_table)
 	return (unsigned long)sg_table->data_pages.nr_pages << PAGE_SHIFT;
 }
 
+static inline bool tmc_has_reserved_buffer(struct tmc_drvdata *drvdata)
+{
+	if (drvdata->resrv_buf.vaddr &&
+	    drvdata->resrv_buf.size)
+		return true;
+	return false;
+}
+
 struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);
 
 void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu);
-- 
2.34.1



From lcherian at marvell.com  Sun Dec 15 21:30:09 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:00:09 +0530
Subject: [PATCH v13 3/8] coresight: core: Add provision for panic callbacks
In-Reply-To: <20241216053014.3427909-1-lcherian@marvell.com>
References: <20241216053014.3427909-1-lcherian@marvell.com>
Message-ID: <20241216053014.3427909-4-lcherian@marvell.com>

Panic callback handlers allows coresight device drivers to sync
relevant trace data and trace metadata to reserved memory
regions so that they can be retrieved later in the subsequent
boot or in the crashdump kernel.

Signed-off-by: Linu Cherian <lcherian at marvell.com>
Reviewed-by: James Clark <james.clark at arm.com>
---
Changelog from v12:
No changes.

 drivers/hwtracing/coresight/coresight-core.c | 42 ++++++++++++++++++++
 include/linux/coresight.h                    | 12 ++++++
 2 files changed, 54 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index ea38ecf26fcb..8c5fb66911a5 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -19,6 +19,7 @@
 #include <linux/property.h>
 #include <linux/delay.h>
 #include <linux/pm_runtime.h>
+#include <linux/panic_notifier.h>
 
 #include "coresight-etm-perf.h"
 #include "coresight-priv.h"
@@ -1378,6 +1379,36 @@ const struct bus_type coresight_bustype = {
 	.name	= "coresight",
 };
 
+static int coresight_panic_sync(struct device *dev, void *data)
+{
+	int mode;
+	struct coresight_device *csdev;
+
+	/* Run through panic sync handlers for all enabled devices */
+	csdev = container_of(dev, struct coresight_device, dev);
+	mode = coresight_get_mode(csdev);
+
+	if ((mode == CS_MODE_SYSFS) || (mode == CS_MODE_PERF)) {
+		if (panic_ops(csdev))
+			panic_ops(csdev)->sync(csdev);
+	}
+
+	return 0;
+}
+
+static int coresight_panic_cb(struct notifier_block *self,
+			       unsigned long v, void *p)
+{
+	bus_for_each_dev(&coresight_bustype, NULL, NULL,
+				 coresight_panic_sync);
+
+	return 0;
+}
+
+static struct notifier_block coresight_notifier = {
+	.notifier_call = coresight_panic_cb,
+};
+
 static int __init coresight_init(void)
 {
 	int ret;
@@ -1390,11 +1421,20 @@ static int __init coresight_init(void)
 	if (ret)
 		goto exit_bus_unregister;
 
+	/* Register function to be called for panic */
+	ret = atomic_notifier_chain_register(&panic_notifier_list,
+					     &coresight_notifier);
+	if (ret)
+		goto exit_perf;
+
 	/* initialise the coresight syscfg API */
 	ret = cscfg_init();
 	if (!ret)
 		return 0;
 
+	atomic_notifier_chain_unregister(&panic_notifier_list,
+					     &coresight_notifier);
+exit_perf:
 	etm_perf_exit();
 exit_bus_unregister:
 	bus_unregister(&coresight_bustype);
@@ -1404,6 +1444,8 @@ static int __init coresight_init(void)
 static void __exit coresight_exit(void)
 {
 	cscfg_exit();
+	atomic_notifier_chain_unregister(&panic_notifier_list,
+					     &coresight_notifier);
 	etm_perf_exit();
 	bus_unregister(&coresight_bustype);
 }
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index c13342594278..2e63f7614551 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -335,6 +335,7 @@ enum cs_mode {
 #define link_ops(csdev)		csdev->ops->link_ops
 #define helper_ops(csdev)	csdev->ops->helper_ops
 #define ect_ops(csdev)		csdev->ops->ect_ops
+#define panic_ops(csdev)	csdev->ops->panic_ops
 
 /**
  * struct coresight_ops_sink - basic operations for a sink
@@ -404,11 +405,22 @@ struct coresight_ops_helper {
 	int (*disable)(struct coresight_device *csdev, void *data);
 };
 
+
+/**
+ * struct coresight_ops_panic - Generic device ops for panic handing
+ *
+ * @sync	: Sync the device register state/trace data
+ */
+struct coresight_ops_panic {
+	int (*sync)(struct coresight_device *csdev);
+};
+
 struct coresight_ops {
 	const struct coresight_ops_sink *sink_ops;
 	const struct coresight_ops_link *link_ops;
 	const struct coresight_ops_source *source_ops;
 	const struct coresight_ops_helper *helper_ops;
+	const struct coresight_ops_panic *panic_ops;
 };
 
 static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa,
-- 
2.34.1



From lcherian at marvell.com  Sun Dec 15 21:30:10 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:00:10 +0530
Subject: [PATCH v13 4/8] coresight: tmc: Enable panic sync handling
In-Reply-To: <20241216053014.3427909-1-lcherian@marvell.com>
References: <20241216053014.3427909-1-lcherian@marvell.com>
Message-ID: <20241216053014.3427909-5-lcherian@marvell.com>

- Get reserved region from device tree node for metadata
- Define metadata format for TMC
- Add TMC ETR panic sync handler that syncs register snapshot
  to metadata region
- Add TMC ETF panic sync handler that syncs register snapshot
  to metadata region and internal SRAM to reserved trace buffer
  region.

Signed-off-by: Linu Cherian <lcherian at marvell.com>
Reviewed-by: James Clark <james.clark at arm.com>
---
Changelog from v12:
No changes.

 .../hwtracing/coresight/coresight-tmc-core.c  | 14 ++++
 .../hwtracing/coresight/coresight-tmc-etf.c   | 80 +++++++++++++++++++
 .../hwtracing/coresight/coresight-tmc-etr.c   | 73 +++++++++++++++++
 drivers/hwtracing/coresight/coresight-tmc.h   | 66 +++++++++++++++
 4 files changed, 233 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 248989833b20..1e3938ec12cb 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -444,6 +444,20 @@ static void tmc_get_reserved_region(struct device *parent)
 
 	drvdata->resrv_buf.paddr = res.start;
 	drvdata->resrv_buf.size  = resource_size(&res);
+
+	if (of_tmc_get_reserved_resource_by_name(parent, "metadata", &res))
+		return;
+
+	drvdata->crash_mdata.vaddr = memremap(res.start,
+					       resource_size(&res),
+					       MEMREMAP_WC);
+	if (IS_ERR_OR_NULL(drvdata->crash_mdata.vaddr)) {
+		dev_err(parent, "Metadata memory mapping failed\n");
+		return;
+	}
+
+	drvdata->crash_mdata.paddr = res.start;
+	drvdata->crash_mdata.size  = resource_size(&res);
 }
 
 /* Detect and initialise the capabilities of a TMC ETR */
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index d4f641cd9de6..0f9155a10ac2 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -590,6 +590,81 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
 	return to_read;
 }
 
+static int tmc_panic_sync_etf(struct coresight_device *csdev)
+{
+	u32 val;
+	struct tmc_crash_metadata *mdata;
+	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	mdata = (struct tmc_crash_metadata *)drvdata->crash_mdata.vaddr;
+
+	/* Make sure we have valid reserved memory */
+	if (!tmc_has_reserved_buffer(drvdata) ||
+	    !tmc_has_crash_mdata_buffer(drvdata))
+		return 0;
+
+	tmc_crashdata_set_invalid(drvdata);
+
+	CS_UNLOCK(drvdata->base);
+
+	/* Proceed only if ETF is enabled or configured as sink */
+	val = readl(drvdata->base + TMC_CTL);
+	if (!(val & TMC_CTL_CAPT_EN))
+		goto out;
+	val = readl(drvdata->base + TMC_MODE);
+	if (val != TMC_MODE_CIRCULAR_BUFFER)
+		goto out;
+
+	val = readl(drvdata->base + TMC_FFSR);
+	/* Do manual flush and stop only if its not auto-stopped */
+	if (!(val & TMC_FFSR_FT_STOPPED)) {
+		dev_dbg(&csdev->dev,
+			 "%s: Triggering manual flush\n", __func__);
+		tmc_flush_and_stop(drvdata);
+	} else
+		tmc_wait_for_tmcready(drvdata);
+
+	/* Sync registers from hardware to metadata region */
+	mdata->tmc_sts = readl(drvdata->base + TMC_STS);
+	mdata->tmc_mode = readl(drvdata->base + TMC_MODE);
+	mdata->tmc_ffcr = readl(drvdata->base + TMC_FFCR);
+	mdata->tmc_ffsr = readl(drvdata->base + TMC_FFSR);
+
+	/* Sync Internal SRAM to reserved trace buffer region */
+	drvdata->buf = drvdata->resrv_buf.vaddr;
+	tmc_etb_dump_hw(drvdata);
+	/* Store as per RSZ register convention */
+	mdata->tmc_ram_size = drvdata->len >> 2;
+
+	/* Other fields for processing trace buffer reads */
+	mdata->tmc_rrp = 0;
+	mdata->tmc_dba = 0;
+	mdata->tmc_rwp = drvdata->len;
+	mdata->trace_paddr = drvdata->resrv_buf.paddr;
+
+	mdata->version = CS_CRASHDATA_VERSION;
+
+	/*
+	 * Make sure all previous writes are ordered,
+	 * before we mark valid
+	 */
+	dmb(sy);
+	mdata->valid = true;
+	/*
+	 * Below order need to maintained, since crc of metadata
+	 * is dependent on first
+	 */
+	mdata->crc32_tdata = find_crash_tracedata_crc(drvdata, mdata);
+	mdata->crc32_mdata = find_crash_metadata_crc(mdata);
+
+	tmc_disable_hw(drvdata);
+
+	dev_dbg(&csdev->dev, "%s: success\n", __func__);
+out:
+	CS_UNLOCK(drvdata->base);
+	return 0;
+}
+
 static const struct coresight_ops_sink tmc_etf_sink_ops = {
 	.enable		= tmc_enable_etf_sink,
 	.disable	= tmc_disable_etf_sink,
@@ -603,6 +678,10 @@ static const struct coresight_ops_link tmc_etf_link_ops = {
 	.disable	= tmc_disable_etf_link,
 };
 
+static const struct coresight_ops_panic tmc_etf_sync_ops = {
+	.sync		= tmc_panic_sync_etf,
+};
+
 const struct coresight_ops tmc_etb_cs_ops = {
 	.sink_ops	= &tmc_etf_sink_ops,
 };
@@ -610,6 +689,7 @@ const struct coresight_ops tmc_etb_cs_ops = {
 const struct coresight_ops tmc_etf_cs_ops = {
 	.sink_ops	= &tmc_etf_sink_ops,
 	.link_ops	= &tmc_etf_link_ops,
+	.panic_ops	= &tmc_etf_sync_ops,
 };
 
 int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 8bca5b36334a..fb944a68a11c 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1814,6 +1814,74 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
 	return 0;
 }
 
+static int tmc_panic_sync_etr(struct coresight_device *csdev)
+{
+	u32 val;
+	struct tmc_crash_metadata *mdata;
+	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	mdata = (struct tmc_crash_metadata *)drvdata->crash_mdata.vaddr;
+
+	if (!drvdata->etr_buf)
+		return 0;
+
+	/* Being in RESRV mode implies valid reserved memory as well */
+	if (drvdata->etr_buf->mode != ETR_MODE_RESRV)
+		return 0;
+
+	if (!tmc_has_crash_mdata_buffer(drvdata))
+		return 0;
+
+	CS_UNLOCK(drvdata->base);
+
+	/* Proceed only if ETR is enabled */
+	val = readl(drvdata->base + TMC_CTL);
+	if (!(val & TMC_CTL_CAPT_EN))
+		goto out;
+
+	val = readl(drvdata->base + TMC_FFSR);
+	/* Do manual flush and stop only if its not auto-stopped */
+	if (!(val & TMC_FFSR_FT_STOPPED)) {
+		dev_dbg(&csdev->dev,
+			 "%s: Triggering manual flush\n", __func__);
+		tmc_flush_and_stop(drvdata);
+	} else
+		tmc_wait_for_tmcready(drvdata);
+
+	/* Sync registers from hardware to metadata region */
+	mdata->tmc_ram_size = readl(drvdata->base + TMC_RSZ);
+	mdata->tmc_sts = readl(drvdata->base + TMC_STS);
+	mdata->tmc_mode = readl(drvdata->base + TMC_MODE);
+	mdata->tmc_ffcr = readl(drvdata->base + TMC_FFCR);
+	mdata->tmc_ffsr = readl(drvdata->base + TMC_FFSR);
+	mdata->tmc_rrp = tmc_read_rrp(drvdata);
+	mdata->tmc_rwp = tmc_read_rwp(drvdata);
+	mdata->tmc_dba = tmc_read_dba(drvdata);
+	mdata->trace_paddr = drvdata->resrv_buf.paddr;
+	mdata->version = CS_CRASHDATA_VERSION;
+
+	/*
+	 * Make sure all previous writes are ordered,
+	 * before we mark valid
+	 */
+	dmb(sy);
+	mdata->valid = true;
+	/*
+	 * Below order need to maintained, since crc of metadata
+	 * is dependent on first
+	 */
+	mdata->crc32_tdata = find_crash_tracedata_crc(drvdata, mdata);
+	mdata->crc32_mdata = find_crash_metadata_crc(mdata);
+
+	tmc_disable_hw(drvdata);
+
+	dev_dbg(&csdev->dev, "%s: success\n", __func__);
+out:
+	CS_UNLOCK(drvdata->base);
+
+	return 0;
+}
+
 static const struct coresight_ops_sink tmc_etr_sink_ops = {
 	.enable		= tmc_enable_etr_sink,
 	.disable	= tmc_disable_etr_sink,
@@ -1822,8 +1890,13 @@ static const struct coresight_ops_sink tmc_etr_sink_ops = {
 	.free_buffer	= tmc_free_etr_buffer,
 };
 
+static const struct coresight_ops_panic tmc_etr_sync_ops = {
+	.sync		= tmc_panic_sync_etr,
+};
+
 const struct coresight_ops tmc_etr_cs_ops = {
 	.sink_ops	= &tmc_etr_sink_ops,
+	.panic_ops	= &tmc_etr_sync_ops,
 };
 
 int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index d2261eddab71..d76e83fc840b 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -12,6 +12,7 @@
 #include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/refcount.h>
+#include <linux/crc32.h>
 
 #define TMC_RSZ			0x004
 #define TMC_STS			0x00c
@@ -76,6 +77,9 @@
 #define TMC_AXICTL_AXCACHE_OS	(0xf << 2)
 #define TMC_AXICTL_ARCACHE_OS	(0xf << 16)
 
+/* TMC_FFSR - 0x300 */
+#define TMC_FFSR_FT_STOPPED	BIT(1)
+
 /* TMC_FFCR - 0x304 */
 #define TMC_FFCR_FLUSHMAN_BIT	6
 #define TMC_FFCR_EN_FMT		BIT(0)
@@ -94,6 +98,9 @@
 
 #define TMC_AUTH_NSID_MASK	GENMASK(1, 0)
 
+/* Major version 1 Minor version 0 */
+#define CS_CRASHDATA_VERSION	(1 << 16)
+
 enum tmc_config_type {
 	TMC_CONFIG_TYPE_ETB,
 	TMC_CONFIG_TYPE_ETR,
@@ -131,6 +138,25 @@ enum tmc_mem_intf_width {
 #define CORESIGHT_SOC_600_ETR_CAPS	\
 	(TMC_ETR_SAVE_RESTORE | TMC_ETR_AXI_ARCACHE)
 
+/* TMC metadata region for ETR and ETF configurations */
+struct tmc_crash_metadata {
+	uint32_t crc32_mdata;	/* crc of metadata */
+	uint32_t crc32_tdata;	/* crc of tracedata */
+	uint32_t version;	/* 31:16 Major version, 15:0 Minor version */
+	uint32_t valid;         /* Indicate if this ETF/ETR was enabled */
+	uint32_t tmc_ram_size;  /* Ram Size register */
+	uint32_t tmc_sts;       /* Status register */
+	uint32_t tmc_mode;	/* Mode register */
+	uint32_t tmc_ffcr;	/* Formatter and flush control register */
+	uint32_t tmc_ffsr;	/* Formatter and flush status register */
+	uint32_t reserved32;
+	uint64_t tmc_rrp;       /* Ram Read pointer register */
+	uint64_t tmc_rwp;       /* Ram Write pointer register */
+	uint64_t tmc_dba;	/* Data buffer address register */
+	uint64_t trace_paddr;	/* Phys address of trace buffer */
+	uint64_t reserved64[3];
+};
+
 enum etr_mode {
 	ETR_MODE_FLAT,		/* Uses contiguous flat buffer */
 	ETR_MODE_ETR_SG,	/* Uses in-built TMC ETR SG mechanism */
@@ -205,6 +231,8 @@ struct tmc_resrv_buf {
  *		retention (after crash) only when ETR_MODE_RESRV buffer
  *		mode is enabled. Used by ETF for trace data retention
  *		(after crash) by default.
+ * @crash_mdata: Reserved memory for storing tmc crash metadata.
+ *		 Used by ETR/ETF.
  */
 struct tmc_drvdata {
 	struct clk		*pclk;
@@ -231,6 +259,7 @@ struct tmc_drvdata {
 	struct etr_buf		*sysfs_buf;
 	struct etr_buf		*perf_buf;
 	struct tmc_resrv_buf	resrv_buf;
+	struct tmc_resrv_buf	crash_mdata;
 };
 
 struct etr_buf_operations {
@@ -356,6 +385,43 @@ static inline bool tmc_has_reserved_buffer(struct tmc_drvdata *drvdata)
 	return false;
 }
 
+static inline bool tmc_has_crash_mdata_buffer(struct tmc_drvdata *drvdata)
+{
+	if (drvdata->crash_mdata.vaddr &&
+	    drvdata->crash_mdata.size)
+		return true;
+	return false;
+}
+
+static inline void tmc_crashdata_set_invalid(struct tmc_drvdata *drvdata)
+{
+	struct tmc_crash_metadata *mdata;
+
+	mdata = (struct tmc_crash_metadata *)drvdata->crash_mdata.vaddr;
+
+	if (tmc_has_crash_mdata_buffer(drvdata))
+		mdata->valid = false;
+}
+
+static inline uint32_t find_crash_metadata_crc(struct tmc_crash_metadata *md)
+{
+	unsigned long crc_size;
+
+	crc_size = sizeof(struct tmc_crash_metadata) -
+		offsetof(struct tmc_crash_metadata, crc32_tdata);
+	return crc32_le(0, (void *)&md->crc32_tdata, crc_size);
+}
+
+static inline uint32_t find_crash_tracedata_crc(struct tmc_drvdata *drvdata,
+						struct tmc_crash_metadata *md)
+{
+	unsigned long crc_size;
+
+	/* Take CRC of configured buffer size to keep it simple */
+	crc_size = md->tmc_ram_size << 2;
+	return crc32_le(0, (void *)drvdata->resrv_buf.vaddr, crc_size);
+}
+
 struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);
 
 void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu);
-- 
2.34.1



From lcherian at marvell.com  Sun Dec 15 21:30:11 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:00:11 +0530
Subject: [PATCH v13 5/8] coresight: tmc: Add support for reading crash data
In-Reply-To: <20241216053014.3427909-1-lcherian@marvell.com>
References: <20241216053014.3427909-1-lcherian@marvell.com>
Message-ID: <20241216053014.3427909-6-lcherian@marvell.com>

* Add support for reading crashdata using special device files.
  The special device files /dev/crash_tmc_xxx would be available
  for read file operation only when the crash data is valid.

* User can read the crash data as below

  For example, for reading crash data from tmc_etf sink

  #dd if=/dev/crash_tmc_etfXX of=~/cstrace.bin

Signed-off-by: Anil Kumar Reddy <areddy3 at marvell.com>
Signed-off-by: Tanmay Jagdale <tanmay at marvell.com>
Signed-off-by: Linu Cherian <lcherian at marvell.com>
---
Changelog from v12:
* Fixed wrong buffer pointer passed to coresight_insert_barrier_packet  
* tmc_read_prepare_crashdata need to be called only once and
  hence removed from read path and added to tmc_probe.
  As as side effect, tmc_read_unprepare_crashdata is removed as well. 
* tmc_read_prepare_crashdata renamed to tmc_prepare_crashdata and
  avoided taking locks as its called from probe function alone.
* Introduced read status flag, "reading" specific to reserved buffer to keep the
  reserved buffer reading independent of the regular buffer and updated
  during tmc_crashdata_open/release functions
* is_tmc_crashdata_valid is made static as its used only within
  coresight-tmc-core.c
* tmc_get_resvbuf_trace definition moved up before the first invocation
  from tmc_prepare_crashdata
* Replaced constant with TMC_STS_FULL

 .../hwtracing/coresight/coresight-tmc-core.c  | 213 +++++++++++++++++-
 .../hwtracing/coresight/coresight-tmc-etr.c   |  22 +-
 drivers/hwtracing/coresight/coresight-tmc.h   |  14 +-
 3 files changed, 246 insertions(+), 3 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 1e3938ec12cb..6ef68b56de22 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -105,6 +105,124 @@ u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata)
 	return mask;
 }
 
+static bool is_tmc_crashdata_valid(struct tmc_drvdata *drvdata)
+{
+	struct tmc_crash_metadata *mdata;
+
+	if (!tmc_has_reserved_buffer(drvdata) ||
+	    !tmc_has_crash_mdata_buffer(drvdata))
+		return false;
+
+	mdata = drvdata->crash_mdata.vaddr;
+
+	/* Check version match */
+	if (mdata->version != CS_CRASHDATA_VERSION)
+		return false;
+
+	/* Check for valid metadata */
+	if (!mdata->valid) {
+		dev_dbg(&drvdata->csdev->dev,
+			"Data invalid in tmc crash metadata\n");
+		return false;
+	}
+
+	/*
+	 * Buffer address given by metadata for retrieval of trace data
+	 * from previous boot is expected to be same as the reserved
+	 * trace buffer memory region provided through DTS
+	 */
+	if (drvdata->resrv_buf.paddr != mdata->trace_paddr) {
+		dev_dbg(&drvdata->csdev->dev,
+			"Trace buffer address of previous boot invalid\n");
+		return false;
+	}
+
+	/* Check data integrity of metadata */
+	if (mdata->crc32_mdata != find_crash_metadata_crc(mdata)) {
+		dev_dbg(&drvdata->csdev->dev,
+			"CRC mismatch in tmc crash metadata\n");
+		return false;
+	}
+	/* Check data integrity of tracedata */
+	if (mdata->crc32_tdata != find_crash_tracedata_crc(drvdata, mdata)) {
+		dev_dbg(&drvdata->csdev->dev,
+			"CRC mismatch in tmc crash tracedata\n");
+		return false;
+	}
+
+	return true;
+}
+
+static inline ssize_t tmc_get_resvbuf_trace(struct tmc_drvdata *drvdata,
+					  loff_t pos, size_t len, char **bufpp)
+{
+	s64 offset;
+	ssize_t actual = len;
+	struct tmc_resrv_buf *rbuf = &drvdata->resrv_buf;
+
+	if (pos + actual > rbuf->len)
+		actual = rbuf->len - pos;
+	if (actual <= 0)
+		return 0;
+
+	/* Compute the offset from which we read the data */
+	offset = rbuf->offset + pos;
+	if (offset >= rbuf->size)
+		offset -= rbuf->size;
+
+	/* Adjust the length to limit this transaction to end of buffer */
+	actual = (actual < (rbuf->size - offset)) ?
+		actual : rbuf->size - offset;
+
+	*bufpp = (char *)rbuf->vaddr + offset;
+
+	return actual;
+}
+
+static int tmc_prepare_crashdata(struct tmc_drvdata *drvdata)
+{
+	char *bufp;
+	int ret = 0;
+	ssize_t len;
+	u32 status, size;
+	u64 rrp, rwp, dba;
+	struct tmc_resrv_buf *rbuf;
+	struct tmc_crash_metadata *mdata;
+
+	mdata = drvdata->crash_mdata.vaddr;
+	rbuf = &drvdata->resrv_buf;
+
+	rrp = mdata->tmc_rrp;
+	rwp = mdata->tmc_rwp;
+	dba = mdata->tmc_dba;
+	status = mdata->tmc_sts;
+	size = mdata->tmc_ram_size << 2;
+
+	/* Sync the buffer pointers */
+	rbuf->offset = rrp - dba;
+	if (status & TMC_STS_FULL)
+		rbuf->len = size;
+	else
+		rbuf->len = rwp - rrp;
+
+	/* Additional sanity checks for validating metadata */
+	if ((rbuf->offset > size) ||
+	    (rbuf->len > size)) {
+		dev_dbg(&drvdata->csdev->dev,
+			"Offset and length invalid in tmc crash metadata\n");
+		return -EINVAL;
+	}
+
+	if (status & TMC_STS_FULL) {
+		len = tmc_get_resvbuf_trace(drvdata, 0x0,
+					    CORESIGHT_BARRIER_PKT_SIZE, &bufp);
+		if (len >= CORESIGHT_BARRIER_PKT_SIZE)
+			coresight_insert_barrier_packet(bufp);
+	}
+
+	return ret;
+}
+
 static int tmc_read_prepare(struct tmc_drvdata *drvdata)
 {
 	int ret = 0;
@@ -223,6 +341,77 @@ static const struct file_operations tmc_fops = {
 	.release	= tmc_release,
 };
 
+static int tmc_crashdata_open(struct inode *inode, struct file *file)
+{
+	unsigned long flags;
+	struct tmc_resrv_buf *rbuf;
+	struct tmc_drvdata *drvdata = container_of(file->private_data,
+						   struct tmc_drvdata,
+						   crashdev);
+
+	rbuf = &drvdata->resrv_buf;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	rbuf->reading = true;
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	nonseekable_open(inode, file);
+
+	dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__);
+	return 0;
+}
+
+static ssize_t tmc_crashdata_read(struct file *file, char __user *data,
+				  size_t len, loff_t *ppos)
+{
+	char *bufp;
+	ssize_t actual;
+	struct tmc_drvdata *drvdata = container_of(file->private_data,
+						   struct tmc_drvdata,
+						   crashdev);
+
+	actual = tmc_get_resvbuf_trace(drvdata, *ppos, len, &bufp);
+	if (actual <= 0)
+		return 0;
+
+	if (copy_to_user(data, bufp, actual)) {
+		dev_dbg(&drvdata->csdev->dev,
+			"%s: copy_to_user failed\n", __func__);
+		return -EFAULT;
+	}
+
+	*ppos += actual;
+	dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
+
+	return actual;
+
+}
+
+static int tmc_crashdata_release(struct inode *inode, struct file *file)
+{
+	int ret = 0;
+	unsigned long flags;
+	struct tmc_resrv_buf *rbuf;
+	struct tmc_drvdata *drvdata = container_of(file->private_data,
+						   struct tmc_drvdata,
+						   crashdev);
+
+	rbuf = &drvdata->resrv_buf;
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	rbuf->reading = false;
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__);
+	return ret;
+}
+
+static const struct file_operations tmc_crashdata_fops = {
+	.owner		= THIS_MODULE,
+	.open		= tmc_crashdata_open,
+	.read		= tmc_crashdata_read,
+	.release	= tmc_crashdata_release,
+};
+
 static enum tmc_mem_intf_width tmc_get_memwidth(u32 devid)
 {
 	enum tmc_mem_intf_width memwidth;
@@ -532,6 +721,20 @@ static u32 tmc_etr_get_max_burst_size(struct device *dev)
 	return burst_size;
 }
 
+static void register_crash_dev_interface(struct tmc_drvdata *drvdata,
+					 const char *name)
+{
+	drvdata->crashdev.name =
+		devm_kasprintf(&drvdata->csdev->dev, GFP_KERNEL, "%s_%s", "crash", name);
+	drvdata->crashdev.minor = MISC_DYNAMIC_MINOR;
+	drvdata->crashdev.fops = &tmc_crashdata_fops;
+	if (misc_register(&drvdata->crashdev)) {
+		dev_dbg(&drvdata->csdev->dev,
+			"Failed to setup user interface for crashdata\n");
+		drvdata->crashdev.fops = NULL;
+	}
+}
+
 static int __tmc_probe(struct device *dev, struct resource *res)
 {
 	int ret = 0;
@@ -632,9 +835,15 @@ static int __tmc_probe(struct device *dev, struct resource *res)
 	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
 	drvdata->miscdev.fops = &tmc_fops;
 	ret = misc_register(&drvdata->miscdev);
-	if (ret)
+	if (ret) {
 		coresight_unregister(drvdata->csdev);
+		goto out;
+	}
+
 out:
+	if (is_tmc_crashdata_valid(drvdata) &&
+	    !tmc_prepare_crashdata(drvdata))
+		register_crash_dev_interface(drvdata, desc.name);
 	return ret;
 }
 
@@ -687,6 +896,8 @@ static void __tmc_remove(struct device *dev)
 	 * handler to this device is closed.
 	 */
 	misc_deregister(&drvdata->miscdev);
+	if (drvdata->crashdev.fops)
+		misc_deregister(&drvdata->crashdev);
 	coresight_unregister(drvdata->csdev);
 }
 
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index fb944a68a11c..0ca01d5c9581 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -2012,6 +2012,26 @@ static ssize_t buf_mode_preferred_show(struct device *dev,
 	return sysfs_emit(buf, "%s\n", buf_modes_str[drvdata->etr_mode]);
 }
 
+static int buf_mode_set_resrv(struct tmc_drvdata *drvdata)
+{
+	int err = 0;
+	unsigned long flags;
+	struct tmc_resrv_buf *rbuf;
+
+	rbuf = &drvdata->resrv_buf;
+
+	/* Ensure there are no active crashdata read sessions */
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	if (!rbuf->reading) {
+		tmc_crashdata_set_invalid(drvdata);
+		drvdata->etr_mode = ETR_MODE_RESRV;
+
+	} else
+		err = -1;
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	return err;
+}
+
 static ssize_t buf_mode_preferred_store(struct device *dev,
 					  struct device_attribute *attr,
 					  const char *buf, size_t size)
@@ -2027,7 +2047,7 @@ static ssize_t buf_mode_preferred_store(struct device *dev,
 	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_CATU]) && buf_hw.has_catu)
 		drvdata->etr_mode = ETR_MODE_CATU;
 	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_RESRV]) && buf_hw.has_resrv)
-		drvdata->etr_mode = ETR_MODE_RESRV;
+		return buf_mode_set_resrv(drvdata) ? -EBUSY : size;
 	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_AUTO]))
 		drvdata->etr_mode = ETR_MODE_AUTO;
 	else
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index d76e83fc840b..e3707b69abff 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -195,11 +195,17 @@ struct etr_buf {
  * @paddr	: Start address of reserved memory region.
  * @vaddr	: Corresponding CPU virtual address.
  * @size	: Size of reserved memory region.
+ * @offset	: Offset of the trace data in the buffer for consumption.
+ * @reading	: Flag to indicate if reading is active
+ * @len	: Available trace data @buf (may round up to the beginning).
  */
 struct tmc_resrv_buf {
 	phys_addr_t     paddr;
 	void		*vaddr;
 	size_t		size;
+	unsigned long	offset;
+	bool		reading;
+	s64		len;
 };
 
 /**
@@ -208,6 +214,8 @@ struct tmc_resrv_buf {
  * @base:	memory mapped base address for this component.
  * @csdev:	component vitals needed by the framework.
  * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
+ * @crashdev:	specifics to handle "/dev/crash_tmc_xyz" entry for reading
+ *		crash tracedata.
  * @spinlock:	only one at a time pls.
  * @pid:	Process ID of the process that owns the session that is using
  *		this component. For example this would be the pid of the Perf
@@ -227,7 +235,7 @@ struct tmc_resrv_buf {
  * @idr_mutex:	Access serialisation for idr.
  * @sysfs_buf:	SYSFS buffer for ETR.
  * @perf_buf:	PERF buffer for ETR.
- * @resrv_buf:	Used by ETR as hardware trace buffer and for trace data
+ * @resrv_buf:  Used by ETR as hardware trace buffer and for trace data
  *		retention (after crash) only when ETR_MODE_RESRV buffer
  *		mode is enabled. Used by ETF for trace data retention
  *		(after crash) by default.
@@ -239,6 +247,7 @@ struct tmc_drvdata {
 	void __iomem		*base;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
+	struct miscdevice	crashdev;
 	spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
@@ -309,6 +318,8 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata);
 void tmc_enable_hw(struct tmc_drvdata *drvdata);
 void tmc_disable_hw(struct tmc_drvdata *drvdata);
 u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata);
+int tmc_read_prepare_crashdata(struct tmc_drvdata *drvdata);
+int tmc_read_unprepare_crashdata(struct tmc_drvdata *drvdata);
 
 /* ETB/ETF functions */
 int tmc_read_prepare_etb(struct tmc_drvdata *drvdata);
@@ -371,6 +382,7 @@ void tmc_sg_table_sync_data_range(struct tmc_sg_table *table,
 				  u64 offset, u64 size);
 ssize_t tmc_sg_table_get_data(struct tmc_sg_table *sg_table,
 			      u64 offset, size_t len, char **bufpp);
+
 static inline unsigned long
 tmc_sg_table_buf_size(struct tmc_sg_table *sg_table)
 {
-- 
2.34.1



From lcherian at marvell.com  Sun Dec 15 21:30:12 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:00:12 +0530
Subject: [PATCH v13 6/8] coresight: tmc: Stop trace capture on FlIn
In-Reply-To: <20241216053014.3427909-1-lcherian@marvell.com>
References: <20241216053014.3427909-1-lcherian@marvell.com>
Message-ID: <20241216053014.3427909-7-lcherian@marvell.com>

Configure TMC ETR and ETF to flush and stop trace capture
on FlIn event based on sysfs attribute,
/sys/bus/coresight/devices/tmc_etXn/stop_on_flush.

Signed-off-by: Linu Cherian <lcherian at marvell.com>
---
Changelog from v12:
No changes.

 .../hwtracing/coresight/coresight-tmc-core.c  | 31 +++++++++++++++++++
 .../hwtracing/coresight/coresight-tmc-etf.c   | 12 ++++---
 .../hwtracing/coresight/coresight-tmc-etr.c   | 12 ++++---
 drivers/hwtracing/coresight/coresight-tmc.h   |  2 ++
 4 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 6ef68b56de22..7cd138c9af6d 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -521,9 +521,40 @@ static ssize_t buffer_size_store(struct device *dev,
 
 static DEVICE_ATTR_RW(buffer_size);
 
+static ssize_t stop_on_flush_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sprintf(buf, "%#x\n", drvdata->stop_on_flush);
+}
+
+static ssize_t stop_on_flush_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t size)
+{
+	int ret;
+	u8 val;
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	ret = kstrtou8(buf, 0, &val);
+	if (ret)
+		return ret;
+	if (val)
+		drvdata->stop_on_flush = true;
+	else
+		drvdata->stop_on_flush = false;
+
+	return size;
+}
+
+static DEVICE_ATTR_RW(stop_on_flush);
+
+
 static struct attribute *coresight_tmc_attrs[] = {
 	&dev_attr_trigger_cntr.attr,
 	&dev_attr_buffer_size.attr,
+	&dev_attr_stop_on_flush.attr,
 	NULL,
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index 0f9155a10ac2..bdc3a7e9ba06 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -19,6 +19,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
 static int __tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
 {
 	int rc = 0;
+	u32 ffcr;
 
 	CS_UNLOCK(drvdata->base);
 
@@ -32,10 +33,12 @@ static int __tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
 	}
 
 	writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE);
-	writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI |
-		       TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT |
-		       TMC_FFCR_TRIGON_TRIGIN,
-		       drvdata->base + TMC_FFCR);
+
+	ffcr = TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI | TMC_FFCR_FON_FLIN |
+		TMC_FFCR_FON_TRIG_EVT | TMC_FFCR_TRIGON_TRIGIN;
+	if (drvdata->stop_on_flush)
+		ffcr |= TMC_FFCR_STOP_ON_FLUSH;
+	writel_relaxed(ffcr, drvdata->base + TMC_FFCR);
 
 	writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG);
 	tmc_enable_hw(drvdata);
@@ -225,7 +228,6 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 		used = true;
 		drvdata->buf = buf;
 	}
-
 	ret = tmc_etb_enable_hw(drvdata);
 	if (!ret) {
 		coresight_set_mode(csdev, CS_MODE_SYSFS);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 0ca01d5c9581..bd7279a2dbd3 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1060,7 +1060,7 @@ static void tmc_sync_etr_buf(struct tmc_drvdata *drvdata)
 
 static int __tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
 {
-	u32 axictl, sts;
+	u32 axictl, sts, ffcr;
 	struct etr_buf *etr_buf = drvdata->etr_buf;
 	int rc = 0;
 
@@ -1106,10 +1106,12 @@ static int __tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
 		writel_relaxed(sts, drvdata->base + TMC_STS);
 	}
 
-	writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI |
-		       TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT |
-		       TMC_FFCR_TRIGON_TRIGIN,
-		       drvdata->base + TMC_FFCR);
+	ffcr = TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI | TMC_FFCR_FON_FLIN |
+		TMC_FFCR_FON_TRIG_EVT | TMC_FFCR_TRIGON_TRIGIN;
+	if (drvdata->stop_on_flush)
+		ffcr |= TMC_FFCR_STOP_ON_FLUSH;
+	writel_relaxed(ffcr, drvdata->base + TMC_FFCR);
+
 	writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG);
 	tmc_enable_hw(drvdata);
 
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index e3707b69abff..482a425faa41 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -220,6 +220,7 @@ struct tmc_resrv_buf {
  * @pid:	Process ID of the process that owns the session that is using
  *		this component. For example this would be the pid of the Perf
  *		process.
+ * @stop_on_flush: Stop on flush trigger user configuration.
  * @buf:	Snapshot of the trace data for ETF/ETB.
  * @etr_buf:	details of buffer used in TMC-ETR
  * @len:	size of the available trace for ETF/ETB.
@@ -251,6 +252,7 @@ struct tmc_drvdata {
 	spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
+	bool			stop_on_flush;
 	union {
 		char		*buf;		/* TMC ETB */
 		struct etr_buf	*etr_buf;	/* TMC ETR */
-- 
2.34.1



From lcherian at marvell.com  Sun Dec 15 21:30:13 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:00:13 +0530
Subject: [PATCH v13 7/8] coresight: config: Add preloaded configuration
In-Reply-To: <20241216053014.3427909-1-lcherian@marvell.com>
References: <20241216053014.3427909-1-lcherian@marvell.com>
Message-ID: <20241216053014.3427909-8-lcherian@marvell.com>

Add a preloaded configuration for generating
external trigger on address match. This can be
used by CTI and ETR blocks to stop trace capture
on kernel panic.

Kernel address for "panic" function is used as the
default trigger address.

This new configuration is available as,
/sys/kernel/config/cs-syscfg/configurations/panicstop

Signed-off-by: Linu Cherian <lcherian at marvell.com>
Reviewed-by: James Clark <james.clark at arm.com>
---
Changelog from v12:
No changes.

 drivers/hwtracing/coresight/Makefile          |  2 +-
 .../coresight/coresight-cfg-preload.c         |  2 +
 .../coresight/coresight-cfg-preload.h         |  2 +
 .../hwtracing/coresight/coresight-cfg-pstop.c | 83 +++++++++++++++++++
 4 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pstop.c

diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 4ba478211b31..46ce7f39d05f 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -25,7 +25,7 @@ subdir-ccflags-y += $(condflags)
 obj-$(CONFIG_CORESIGHT) += coresight.o
 coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
 		coresight-sysfs.o coresight-syscfg.o coresight-config.o \
-		coresight-cfg-preload.o coresight-cfg-afdo.o \
+		coresight-cfg-preload.o coresight-cfg-afdo.o coresight-cfg-pstop.o \
 		coresight-syscfg-configfs.o coresight-trace-id.o
 obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
 coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.c b/drivers/hwtracing/coresight/coresight-cfg-preload.c
index e237a4edfa09..4980e68483c5 100644
--- a/drivers/hwtracing/coresight/coresight-cfg-preload.c
+++ b/drivers/hwtracing/coresight/coresight-cfg-preload.c
@@ -13,6 +13,7 @@
 static struct cscfg_feature_desc *preload_feats[] = {
 #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
 	&strobe_etm4x,
+	&gen_etrig_etm4x,
 #endif
 	NULL
 };
@@ -20,6 +21,7 @@ static struct cscfg_feature_desc *preload_feats[] = {
 static struct cscfg_config_desc *preload_cfgs[] = {
 #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
 	&afdo_etm4x,
+	&pstop_etm4x,
 #endif
 	NULL
 };
diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.h b/drivers/hwtracing/coresight/coresight-cfg-preload.h
index 21299e175477..291ba530a6a5 100644
--- a/drivers/hwtracing/coresight/coresight-cfg-preload.h
+++ b/drivers/hwtracing/coresight/coresight-cfg-preload.h
@@ -10,4 +10,6 @@
 #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
 extern struct cscfg_feature_desc strobe_etm4x;
 extern struct cscfg_config_desc afdo_etm4x;
+extern struct cscfg_feature_desc gen_etrig_etm4x;
+extern struct cscfg_config_desc pstop_etm4x;
 #endif
diff --git a/drivers/hwtracing/coresight/coresight-cfg-pstop.c b/drivers/hwtracing/coresight/coresight-cfg-pstop.c
new file mode 100644
index 000000000000..c2bfbd07bfaf
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-cfg-pstop.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2023  Marvell.
+ * Based on coresight-cfg-afdo.c
+ */
+
+#include "coresight-config.h"
+
+/* ETMv4 includes and features */
+#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
+#include "coresight-etm4x-cfg.h"
+
+/* preload configurations and features */
+
+/* preload in features for ETMv4 */
+
+/* panic_stop feature */
+static struct cscfg_parameter_desc gen_etrig_params[] = {
+	{
+		.name = "address",
+		.value = (u64)panic,
+	},
+};
+
+static struct cscfg_regval_desc gen_etrig_regs[] = {
+	/* resource selector */
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE,
+		.offset = TRCRSCTLRn(2),
+		.hw_info = ETM4_CFG_RES_SEL,
+		.val32 = 0x40001,
+	},
+	/* single address comparator */
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_64BIT |
+			CS_CFG_REG_TYPE_VAL_PARAM,
+		.offset =  TRCACVRn(0),
+		.val32 = 0x0,
+	},
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE,
+		.offset = TRCACATRn(0),
+		.val64 = 0xf00,
+	},
+	/* Driver external output[0] with comparator out */
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE,
+		.offset = TRCEVENTCTL0R,
+		.val32 = 0x2,
+	},
+	/* end of regs */
+};
+
+struct cscfg_feature_desc gen_etrig_etm4x = {
+	.name = "gen_etrig",
+	.description = "Generate external trigger on address match\n"
+		       "parameter \'address\': address of kernel address\n",
+	.match_flags = CS_CFG_MATCH_CLASS_SRC_ETM4,
+	.nr_params = ARRAY_SIZE(gen_etrig_params),
+	.params_desc = gen_etrig_params,
+	.nr_regs = ARRAY_SIZE(gen_etrig_regs),
+	.regs_desc = gen_etrig_regs,
+};
+
+/* create a panic stop configuration */
+
+/* the total number of parameters in used features */
+#define PSTOP_NR_PARAMS	ARRAY_SIZE(gen_etrig_params)
+
+static const char *pstop_ref_names[] = {
+	"gen_etrig",
+};
+
+struct cscfg_config_desc pstop_etm4x = {
+	.name = "panicstop",
+	.description = "Stop ETM on kernel panic\n",
+	.nr_feat_refs = ARRAY_SIZE(pstop_ref_names),
+	.feat_ref_names = pstop_ref_names,
+	.nr_total_params = PSTOP_NR_PARAMS,
+};
+
+/* end of ETM4x configurations */
+#endif	/* IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) */
-- 
2.34.1



From lcherian at marvell.com  Sun Dec 15 21:30:14 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:00:14 +0530
Subject: [PATCH v13 8/8] Documentation: coresight: Panic support
In-Reply-To: <20241216053014.3427909-1-lcherian@marvell.com>
References: <20241216053014.3427909-1-lcherian@marvell.com>
Message-ID: <20241216053014.3427909-9-lcherian@marvell.com>

Add documentation on using coresight during panic
and watchdog.

Signed-off-by: Linu Cherian <lcherian at marvell.com>
---
Changelog from v12:
No changes.

 Documentation/trace/coresight/panic.rst | 362 ++++++++++++++++++++++++
 1 file changed, 362 insertions(+)
 create mode 100644 Documentation/trace/coresight/panic.rst

diff --git a/Documentation/trace/coresight/panic.rst b/Documentation/trace/coresight/panic.rst
new file mode 100644
index 000000000000..a58aa914c241
--- /dev/null
+++ b/Documentation/trace/coresight/panic.rst
@@ -0,0 +1,362 @@
+===================================================
+Using Coresight for Kernel panic and Watchdog reset
+===================================================
+
+Introduction
+------------
+This documentation is about using Linux coresight trace support to
+debug kernel panic and watchdog reset scenarios.
+
+Coresight trace during Kernel panic
+-----------------------------------
+From the coresight driver point of view, addressing the kernel panic
+situation has four main requirements.
+
+a. Support for allocation of trace buffer pages from reserved memory area.
+   Platform can advertise this using a new device tree property added to
+   relevant coresight nodes.
+
+b. Support for stopping coresight blocks at the time of panic
+
+c. Saving required metadata in the specified format
+
+d. Support for reading trace data captured at the time of panic
+
+Allocation of trace buffer pages from reserved RAM
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A new optional device tree property "memory-region" is added to the
+Coresight TMC device nodes, that would give the base address and size of trace
+buffer.
+
+Static allocation of trace buffers would ensure that both IOMMU enabled
+and disabled cases are handled. Also, platforms that support persistent
+RAM will allow users to read trace data in the subsequent boot without
+booting the crashdump kernel.
+
+Note:
+For ETR sink devices, this reserved region will be used for both trace
+capture and trace data retrieval.
+For ETF sink devices, internal SRAM would be used for trace capture,
+and they would be synced to reserved region for retrieval.
+
+
+Disabling coresight blocks at the time of panic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In order to avoid the situation of losing relevant trace data after a
+kernel panic, it would be desirable to stop the coresight blocks at the
+time of panic.
+
+This can be achieved by configuring the comparator, CTI and sink
+devices as below::
+
+           Trigger on panic
+    Comparator --->External out --->CTI -->External In---->ETR/ETF stop
+
+Saving metadata at the time of kernel panic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Coresight metadata involves all additional data that are required for a
+successful trace decode in addition to the trace data. This involves
+ETR/ETF/ETB register snapshot etc.
+
+A new optional device property "memory-region" is added to
+the ETR/ETF/ETB device nodes for this.
+
+Reading trace data captured at the time of panic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Trace data captured at the time of panic, can be read from rebooted kernel
+or from crashdump kernel using a special device file /dev/crash_tmc_xxx.
+This device file is created only when there is a valid crashdata available.
+
+General flow of trace capture and decode incase of kernel panic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+1. Enable source and sink on all the cores using the sysfs interface.
+   ETR sinks should have trace buffers allocated from reserved memory,
+   by selecting "resrv" buffer mode from sysfs.
+
+2. Run relevant tests.
+
+3. On a kernel panic, all coresight blocks are disabled, necessary
+   metadata is synced by kernel panic handler.
+
+   System would eventually reboot or boot a crashdump kernel.
+
+4. For  platforms that supports crashdump kernel, raw trace data can be
+   dumped using the coresight sysfs interface from the crashdump kernel
+   itself. Persistent RAM is not a requirement in this case.
+
+5. For platforms that supports persistent RAM, trace data can be dumped
+   using the coresight sysfs interface in the subsequent Linux boot.
+   Crashdump kernel is not a requirement in this case. Persistent RAM
+   ensures that trace data is intact across reboot.
+
+Coresight trace during Watchdog reset
+-------------------------------------
+The main difference between addressing the watchdog reset and kernel panic
+case are below,
+
+a. Saving coresight metadata need to be taken care by the
+   SCP(system control processor) firmware in the specified format,
+   instead of kernel.
+
+b. Reserved memory region given by firmware for trace buffer and metadata
+   has to be in persistent RAM.
+   Note: This is a requirement for watchdog reset case but optional
+   in kernel panic case.
+
+Watchdog reset can be supported only on platforms that meet the above
+two requirements.
+
+Sample commands for testing a Kernel panic case with ETR sink
+-------------------------------------------------------------
+
+1. Boot Linux kernel with "crash_kexec_post_notifiers" added to the kernel
+   bootargs. This is mandatory if the user would like to read the tracedata
+   from the crashdump kernel.
+
+2. Enable the preloaded ETM configuration::
+
+    #echo 1 > /sys/kernel/config/cs-syscfg/configurations/panicstop/enable
+
+3. Configure CTI using sysfs interface::
+
+    #./cti_setup.sh
+
+    #cat cti_setup.sh
+
+
+    cd /sys/bus/coresight/devices/
+
+    ap_cti_config () {
+      #ETM trig out[0] trigger to Channel 0
+      echo 0 4 > channels/trigin_attach
+    }
+
+    etf_cti_config () {
+      #ETF Flush in trigger from Channel 0
+      echo 0 1 > channels/trigout_attach
+      echo 1 > channels/trig_filter_enable
+    }
+
+    etr_cti_config () {
+      #ETR Flush in from Channel 0
+      echo 0 1 > channels/trigout_attach
+      echo 1 > channels/trig_filter_enable
+    }
+
+    ctidevs=`find . -name "cti*"`
+
+    for i in $ctidevs
+    do
+            cd $i
+
+            connection=`find . -name "ete*"`
+            if [ ! -z "$connection" ]
+            then
+                    echo "AP CTI config for $i"
+                    ap_cti_config
+            fi
+
+            connection=`find . -name "tmc_etf*"`
+            if [ ! -z "$connection" ]
+            then
+                    echo "ETF CTI config for $i"
+                    etf_cti_config
+            fi
+
+            connection=`find . -name "tmc_etr*"`
+            if [ ! -z "$connection" ]
+            then
+                    echo "ETR CTI config for $i"
+                    etr_cti_config
+            fi
+
+            cd ..
+    done
+
+Note: CTI connections are SOC specific and hence the above script is
+added just for reference.
+
+4. Choose reserved buffer mode for ETR buffer::
+
+    #echo "resrv" > /sys/bus/coresight/devices/tmc_etr0/buf_mode_preferred
+
+5. Enable stop on flush trigger configuration::
+
+    #echo 1 > /sys/bus/coresight/devices/tmc_etr0/stop_on_flush
+
+6. Start Coresight tracing on cores 1 and 2 using sysfs interface
+
+7. Run some application on core 1::
+
+    #taskset -c 1 dd if=/dev/urandom of=/dev/null &
+
+8. Invoke kernel panic on core 2::
+
+    #echo 1 > /proc/sys/kernel/panic
+    #taskset -c 2 echo c > /proc/sysrq-trigger
+
+9. From rebooted kernel or crashdump kernel, read crashdata::
+
+    #dd if=/dev/crash_tmc_etr0 of=/trace/cstrace.bin
+
+10. Run opencsd decoder tools/scripts to generate the instruction trace.
+
+Sample instruction trace dump
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Core1 dump::
+
+    A                                  etm4_enable_hw: ffff800008ae1dd4
+    CONTEXT EL2                        etm4_enable_hw: ffff800008ae1dd4
+    I                                  etm4_enable_hw: ffff800008ae1dd4:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1dd8:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1ddc:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1de0:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1de4:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1de8:
+    d503233f   paciasp
+    I                                  etm4_enable_hw: ffff800008ae1dec:
+    a9be7bfd   stp     x29, x30, [sp, #-32]!
+    I                                  etm4_enable_hw: ffff800008ae1df0:
+    910003fd   mov     x29, sp
+    I                                  etm4_enable_hw: ffff800008ae1df4:
+    a90153f3   stp     x19, x20, [sp, #16]
+    I                                  etm4_enable_hw: ffff800008ae1df8:
+    2a0003f4   mov     w20, w0
+    I                                  etm4_enable_hw: ffff800008ae1dfc:
+    900085b3   adrp    x19, ffff800009b95000 <reserved_mem+0xc48>
+    I                                  etm4_enable_hw: ffff800008ae1e00:
+    910f4273   add     x19, x19, #0x3d0
+    I                                  etm4_enable_hw: ffff800008ae1e04:
+    f8747a60   ldr     x0, [x19, x20, lsl #3]
+    E                                  etm4_enable_hw: ffff800008ae1e08:
+    b4000140   cbz     x0, ffff800008ae1e30 <etm4_starting_cpu+0x50>
+    I    149.039572921                 etm4_enable_hw: ffff800008ae1e30:
+    a94153f3   ldp     x19, x20, [sp, #16]
+    I    149.039572921                 etm4_enable_hw: ffff800008ae1e34:
+    52800000   mov     w0, #0x0                        // #0
+    I    149.039572921                 etm4_enable_hw: ffff800008ae1e38:
+    a8c27bfd   ldp     x29, x30, [sp], #32
+
+    ..snip
+
+        149.052324811           chacha_block_generic: ffff800008642d80:
+    9100a3e0   add     x0,
+    I    149.052324811           chacha_block_generic: ffff800008642d84:
+    b86178a2   ldr     w2, [x5, x1, lsl #2]
+    I    149.052324811           chacha_block_generic: ffff800008642d88:
+    8b010803   add     x3, x0, x1, lsl #2
+    I    149.052324811           chacha_block_generic: ffff800008642d8c:
+    b85fc063   ldur    w3, [x3, #-4]
+    I    149.052324811           chacha_block_generic: ffff800008642d90:
+    0b030042   add     w2, w2, w3
+    I    149.052324811           chacha_block_generic: ffff800008642d94:
+    b8217882   str     w2, [x4, x1, lsl #2]
+    I    149.052324811           chacha_block_generic: ffff800008642d98:
+    91000421   add     x1, x1, #0x1
+    I    149.052324811           chacha_block_generic: ffff800008642d9c:
+    f100443f   cmp     x1, #0x11
+
+
+Core 2 dump::
+
+    A                                  etm4_enable_hw: ffff800008ae1dd4
+    CONTEXT EL2                        etm4_enable_hw: ffff800008ae1dd4
+    I                                  etm4_enable_hw: ffff800008ae1dd4:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1dd8:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1ddc:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1de0:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1de4:
+    d503201f   nop
+    I                                  etm4_enable_hw: ffff800008ae1de8:
+    d503233f   paciasp
+    I                                  etm4_enable_hw: ffff800008ae1dec:
+    a9be7bfd   stp     x29, x30, [sp, #-32]!
+    I                                  etm4_enable_hw: ffff800008ae1df0:
+    910003fd   mov     x29, sp
+    I                                  etm4_enable_hw: ffff800008ae1df4:
+    a90153f3   stp     x19, x20, [sp, #16]
+    I                                  etm4_enable_hw: ffff800008ae1df8:
+    2a0003f4   mov     w20, w0
+    I                                  etm4_enable_hw: ffff800008ae1dfc:
+    900085b3   adrp    x19, ffff800009b95000 <reserved_mem+0xc48>
+    I                                  etm4_enable_hw: ffff800008ae1e00:
+    910f4273   add     x19, x19, #0x3d0
+    I                                  etm4_enable_hw: ffff800008ae1e04:
+    f8747a60   ldr     x0, [x19, x20, lsl #3]
+    E                                  etm4_enable_hw: ffff800008ae1e08:
+    b4000140   cbz     x0, ffff800008ae1e30 <etm4_starting_cpu+0x50>
+    I    149.046243445                 etm4_enable_hw: ffff800008ae1e30:
+    a94153f3   ldp     x19, x20, [sp, #16]
+    I    149.046243445                 etm4_enable_hw: ffff800008ae1e34:
+    52800000   mov     w0, #0x0                        // #0
+    I    149.046243445                 etm4_enable_hw: ffff800008ae1e38:
+    a8c27bfd   ldp     x29, x30, [sp], #32
+    I    149.046243445                 etm4_enable_hw: ffff800008ae1e3c:
+    d50323bf   autiasp
+    E    149.046243445                 etm4_enable_hw: ffff800008ae1e40:
+    d65f03c0   ret
+    A                                ete_sysreg_write: ffff800008adfa18
+
+    ..snip
+
+    I     149.05422547                          panic: ffff800008096300:
+    a90363f7   stp     x23, x24, [sp, #48]
+    I     149.05422547                          panic: ffff800008096304:
+    6b00003f   cmp     w1, w0
+    I     149.05422547                          panic: ffff800008096308:
+    3a411804   ccmn    w0, #0x1, #0x4, ne  // ne = any
+    N     149.05422547                          panic: ffff80000809630c:
+    540001e0   b.eq    ffff800008096348 <panic+0xe0>  // b.none
+    I     149.05422547                          panic: ffff800008096310:
+    f90023f9   str     x25, [sp, #64]
+    E     149.05422547                          panic: ffff800008096314:
+    97fe44ef   bl      ffff8000080276d0 <panic_smp_self_stop>
+    A                                           panic: ffff80000809634c
+    I     149.05422547                          panic: ffff80000809634c:
+    910102d5   add     x21, x22, #0x40
+    I     149.05422547                          panic: ffff800008096350:
+    52800020   mov     w0, #0x1                        // #1
+    E     149.05422547                          panic: ffff800008096354:
+    94166b8b   bl      ffff800008631180 <bust_spinlocks>
+    N    149.054225518                 bust_spinlocks: ffff800008631180:
+    340000c0   cbz     w0, ffff800008631198 <bust_spinlocks+0x18>
+    I    149.054225518                 bust_spinlocks: ffff800008631184:
+    f000a321   adrp    x1, ffff800009a98000 <pbufs.0+0xbb8>
+    I    149.054225518                 bust_spinlocks: ffff800008631188:
+    b9405c20   ldr     w0, [x1, #92]
+    I    149.054225518                 bust_spinlocks: ffff80000863118c:
+    11000400   add     w0, w0, #0x1
+    I    149.054225518                 bust_spinlocks: ffff800008631190:
+    b9005c20   str     w0, [x1, #92]
+    E    149.054225518                 bust_spinlocks: ffff800008631194:
+    d65f03c0   ret
+    A                                           panic: ffff800008096358
+
+Perf based testing
+------------------
+
+Starting perf session
+~~~~~~~~~~~~~~~~~~~~~
+ETF::
+
+    perf record -e cs_etm/panicstop, at tmc_etf1/ -C 1
+    perf record -e cs_etm/panicstop, at tmc_etf2/ -C 2
+
+ETR::
+
+    perf record -e cs_etm/panicstop, at tmc_etr0/ -C 1,2
+
+Reading trace data after panic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Same sysfs based method explained above can be used to retrieve and
+decode the trace data after the reboot on kernel panic.
-- 
2.34.1



From lcherian at marvell.com  Sun Dec 15 21:35:03 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:05:03 +0530
Subject: [PATCH] selftests: arm coresight: sysfsmode testing
In-Reply-To: <115bb206-8401-4475-977d-7dd98a2b872c@linuxfoundation.org>
References: <20241129083813.3056909-1-lcherian@marvell.com>
 <115bb206-8401-4475-977d-7dd98a2b872c@linuxfoundation.org>
Message-ID: <20241216053503.GB1224111@hyd1403.caveonetworks.com>

Hi,

On 2024-12-04 at 05:53:56, Shuah Khan (skhan at linuxfoundation.org) wrote:
> On 11/29/24 01:38, Linu Cherian wrote:
> > Add sysfs mode selftest for ARM Coresight hardware tracer.
> 
> Please add details on what this test does in here. Include
> the output from the test?

Ack. Will add test descripion here. 

> 
> Does this test have dependencies on config? If it does, does
> this test detect and skip if config isn't enabled?

Will add dependency.

Thanks.

> 
> > 
> > Signed-off-by: Linu Cherian <lcherian at marvell.com>
> > ---
> >   .../drivers/hwtracing/coresight/Makefile      |   5 +
> >   .../hwtracing/coresight/sysfs_test_trace.sh   | 144 ++++++++++++++++++
> >   2 files changed, 149 insertions(+)
> >   create mode 100644 tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> >   create mode 100755 tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> > 
> > diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/Makefile b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> > new file mode 100644
> > index 000000000000..7dc68ae1c0a9
> > --- /dev/null
> > +++ b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> > @@ -0,0 +1,5 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +TEST_PROGS = sysfs_test_trace.sh
> > +
> > +include ../../../lib.mk
> > diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> > new file mode 100755
> > index 000000000000..0d6307fff1d2
> > --- /dev/null
> > +++ b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> > @@ -0,0 +1,144 @@
> > +#!/bin/sh
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (C) 2024 Marvell.
> > +
> > +# Test Arm CoreSight trace capture in sysfs mode
> > +# Based on tools/perf/tests/shell/test_arm_coresight.sh
> > +
> > +glb_err=0
> > +
> > +arm_cs_report() {
> > +	if [ $2 != 0 ]; then
> > +		echo "$1: FAIL"
> > +		glb_err=$2
> > +	else
> > +		echo "$1: PASS"
> > +	fi
> > +}
> > +
> > +is_device_sink() {
> > +	# If the node of "enable_sink" is existed under the device path, this
> > +	# means the device is a sink device.
> > +
> > +	if [ -e "$1/enable_sink" ]; then
> > +
> > +		return 0
> > +	else
> > +		return 1
> > +	fi
> > +}
> > +
> > +# Configure sink for buffer mode
> > +cfg_sink_buf_mode() {
> > +	sink_dev=$1
> > +	mode=$2
> > +	# Set buffer mode if supported
> > +	if [ -e "$sink_dev/buf_modes_available" ]; then
> > +		cat $sink_dev/buf_modes_available | grep -E -q $mode
> > +		if [ $? -eq 0 ]; then
> > +			echo $mode > $sink_dev/buf_mode_preferred
> > +			return 0
> > +		fi
> > +	fi
> > +
> > +	return 1
> > +}
> > +
> > +run_app() {
> > +
> > +	taskset -c $1 dd if=/dev/urandom  of=/dev/null bs=1M count=64
> > +}
> > +
> > +sysfs_trace() {
> > +	src_dev=$1
> > +	sink_dev=$2
> > +	cpu=$3
> > +
> > +	# Enable sink device
> > +	echo 1 > $sink_dev/enable_sink
> > +	# Enable source device
> > +	echo 1 > $src_dev/enable_source
> > +
> > +	# Run app to be traced
> > +	run_app $cpu
> > +
> > +	# Read back trace data
> > +	dd if=/dev/$sink_dev_name of=/tmp/tracedata
> > +
> > +	# Verify if read is successful
> > +	err=$?
> > +
> > +	# Disable source device
> > +	echo 0 > $src_dev/enable_source
> > +
> > +	# Diskable sink device
> > +	echo 0 > $sink_dev/enable_sink
> > +
> > +	arm_cs_report "CoreSight path testing (CPU$cpu -> $sink_dev_name)" $err
> > +}
> > +
> > +try_sysfs_trace_resrv_buf() {
> > +	src_dev=$1
> > +	sink_dev=$2
> > +	cpu=$3
> > +
> > +	# Configure the resrved buffer mode if available
> > +	cfg_sink_buf_mode $sink_dev "resrv"
> > +	if [ $? -eq 0 ]; then
> > +		echo "Running sysfs trace with resrv buf mode"
> > +		sysfs_trace $src_dev $sink_dev $cpu
> > +		# Restore buffer mode
> > +		cfg_sink_buf_mode $sink_dev "auto"
> > +		if [ $? -eq 1 ]; then
> > +			echo "Failed to restore default buf mode"
> > +		fi
> > +	fi
> > +}
> > +
> > +arm_cs_iterate_devices() {
> > +	src_dev=$1
> > +	cpu=$3
> > +	for cdev in $2/connections/out\:*; do
> > +
> > +		# Skip testing if it's not a directory
> > +		! [ -d $cdev ] && continue;
> > +
> > +		# Read out its symbol link file name
> > +		sink_dev=`readlink -f $cdev`
> > +
> > +		# Extract device name from path, e.g.
> > +		#   sink_dev = '/sys/devices/platform/20010000.etf/tmc_etf0'
> > +		#     `> sink_dev_name = 'tmc_etf0'
> > +		sink_dev_name=$(basename $sink_dev)
> > +
> > +		if is_device_sink $sink_dev; then
> > +			# Run trace with resrv buf mode (if available)
> > +			try_sysfs_trace_resrv_buf $src_dev $sink_dev $cpu
> > +
> > +			# Run the default mode
> > +			echo "Running sysfs trace with default settings"
> > +			sysfs_trace $src_dev $sink_dev $cpu
> > +		fi
> > +
> > +		arm_cs_iterate_devices $src_dev $cdev $cpu
> > +
> > +	done
> > +}
> > +
> > +arm_cs_etm_traverse_path_test() {
> > +	# Iterate for every ETM device
> > +	for dev in /sys/bus/event_source/devices/cs_etm/cpu*; do
> > +		# Canonicalize the path
> > +		dev=`readlink -f $dev`
> > +
> > +		# Find the ETM device belonging to which CPU
> > +		cpu=`cat $dev/cpu`
> > +
> > +		# Use depth-first search (DFS) to iterate outputs
> > +		arm_cs_iterate_devices $dev $dev $cpu
> > +	done
> > +}
> > +
> > +arm_cs_etm_traverse_path_test
> > +
> > +exit $glb_err
> 
> thanks,
> -- Shuah
> 


From lcherian at marvell.com  Sun Dec 15 21:35:41 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:05:41 +0530
Subject: [PATCH] selftests: arm coresight: sysfsmode testing
In-Reply-To: <1b7aaa17-48b7-45cd-b468-ef54ca048e31@linaro.org>
References: <20241129083813.3056909-1-lcherian@marvell.com>
 <1b7aaa17-48b7-45cd-b468-ef54ca048e31@linaro.org>
Message-ID: <20241216053541.GC1224111@hyd1403.caveonetworks.com>

Hi James,

On 2024-12-04 at 16:45:42, James Clark (james.clark at linaro.org) wrote:
> 
> 
> On 29/11/2024 8:38 am, Linu Cherian wrote:
> > Add sysfs mode selftest for ARM Coresight hardware tracer.
> > 
> > Signed-off-by: Linu Cherian <lcherian at marvell.com>
> > ---
> >   .../drivers/hwtracing/coresight/Makefile      |   5 +
> >   .../hwtracing/coresight/sysfs_test_trace.sh   | 144 ++++++++++++++++++
> >   2 files changed, 149 insertions(+)
> >   create mode 100644 tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> 
> Hi Linu,
> 
> You need to add this path into TARGETS for make install to work:
> 
>  TARGETS += drivers/dma-buf
> +TARGETS += drivers/hwtracing/coresight
>  TARGETS += drivers/s390x/uvdevice


Sure will add that.
Thanks.

> 
> 
> >   create mode 100755 tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> > 
> > diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/Makefile b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> > new file mode 100644
> > index 000000000000..7dc68ae1c0a9
> > --- /dev/null
> > +++ b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> > @@ -0,0 +1,5 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +TEST_PROGS = sysfs_test_trace.sh
> > +
> > +include ../../../lib.mk
> > diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> > new file mode 100755
> > index 000000000000..0d6307fff1d2
> > --- /dev/null
> > +++ b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> > @@ -0,0 +1,144 @@
> > +#!/bin/sh
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (C) 2024 Marvell.
> > +
> > +# Test Arm CoreSight trace capture in sysfs mode
> > +# Based on tools/perf/tests/shell/test_arm_coresight.sh
> > +
> > +glb_err=0
> > +
> > +arm_cs_report() {
> > +	if [ $2 != 0 ]; then
> > +		echo "$1: FAIL"
> > +		glb_err=$2
> > +	else
> > +		echo "$1: PASS"
> > +	fi
> > +}
> > +
> > +is_device_sink() {
> > +	# If the node of "enable_sink" is existed under the device path, this
> > +	# means the device is a sink device.
> > +
> 
> Looks like you still need the skip for TPIU here the same as the Perf test.
> It's an external sink and doesn't have a readable file so the test fails.
> 
> With those changes, looks good. Thanks for adding the first sysfs test.
> Hopefully we can expand them more in the future.
> 
> Reviewed-by: James Clark <james.clark at linaro.org>
> 
> 


From kaihengf at nvidia.com  Sun Dec 15 21:43:02 2024
From: kaihengf at nvidia.com (Kai-Heng Feng)
Date: Mon, 16 Dec 2024 13:43:02 +0800
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <20241206135600.4083965-2-beata.michalska@arm.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
Message-ID: <3f19c5a8-9ee6-42fe-8b4c-3a66c65c8d35@nvidia.com>

Hi Beata,

On 2024/12/6 9:55 PM, Beata Michalska wrote:
> Currently the CPUFreq core exposes two sysfs attributes that can be used
> to query current frequency of a given CPU(s): namely cpuinfo_cur_freq
> and scaling_cur_freq. Both provide slightly different view on the
> subject and they do come with their own drawbacks.
> 
> cpuinfo_cur_freq provides higher precision though at a cost of being
> rather expensive. Moreover, the information retrieved via this attribute
> is somewhat short lived as frequency can change at any point of time
> making it difficult to reason from.
> 
> scaling_cur_freq, on the other hand, tends to be less accurate but then
> the actual level of precision (and source of information) varies between
> architectures making it a bit ambiguous.
> 
> The new attribute, cpuinfo_avg_freq, is intended to provide more stable,
> distinct interface, exposing an average frequency of a given CPU(s), as
> reported by the hardware, over a time frame spanning no more than a few
> milliseconds. As it requires appropriate hardware support, this
> interface is optional.
> 
> Note that under the hood, the new attribute relies on the information
> provided by arch_freq_get_on_cpu, which, up to this point, has been
> feeding data for scaling_cur_freq attribute, being the source of
> ambiguity when it comes to interpretation. This has been amended by
> restoring the intended behavior for scaling_cur_freq, with a new
> dedicated config option to maintain status quo for those, who may need
> it.
> 
> CC: Jonathan Corbet <corbet at lwn.net>
> CC: Thomas Gleixner <tglx at linutronix.de>
> CC: Ingo Molnar <mingo at redhat.com>
> CC: Borislav Petkov <bp at alien8.de>
> CC: Dave Hansen <dave.hansen at linux.intel.com>
> CC: H. Peter Anvin <hpa at zytor.com>
> CC: Phil Auld <pauld at redhat.com>
> CC: x86 at kernel.org
> CC: linux-doc at vger.kernel.org
> Signed-off-by: Beata Michalska <beata.michalska at arm.com>
> ---
>   Documentation/admin-guide/pm/cpufreq.rst | 16 ++++++++++-
>   arch/x86/kernel/cpu/aperfmperf.c         |  2 +-
>   arch/x86/kernel/cpu/proc.c               |  7 +++--
>   drivers/cpufreq/Kconfig.x86              | 12 ++++++++
>   drivers/cpufreq/cpufreq.c                | 36 +++++++++++++++++++++---
>   include/linux/cpufreq.h                  |  2 +-
>   6 files changed, 66 insertions(+), 9 deletions(-)
> 
> diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst
> index fe1be4ad88cb..76f3835afe01 100644
> --- a/Documentation/admin-guide/pm/cpufreq.rst
> +++ b/Documentation/admin-guide/pm/cpufreq.rst
> @@ -248,6 +248,19 @@ are the following:
>   	If that frequency cannot be determined, this attribute should not
>   	be present.
>   
> +``cpuinfo_avg_freq``
> +        An average frequency (in KHz) of all CPUs belonging to a given policy,
> +        derived from a hardware provided feedback and reported on a time frame
> +        spanning at most few milliseconds.
> +
> +        This is expected to be based on the frequency the hardware actually runs
> +        at and, as such, might require specialised hardware support (such as AMU
> +        extension on ARM). If one cannot be determined, this attribute should
> +        not be present.
> +
> +        Note, that failed attempt to retrieve current frequency for a given
> +        CPU(s) will result in an appropriate error.
> +
>   ``cpuinfo_max_freq``
>   	Maximum possible operating frequency the CPUs belonging to this policy
>   	can run at (in kHz).
> @@ -293,7 +306,8 @@ are the following:
>   	Some architectures (e.g. ``x86``) may attempt to provide information
>   	more precisely reflecting the current CPU frequency through this
>   	attribute, but that still may not be the exact current CPU frequency as
> -	seen by the hardware at the moment.
> +	seen by the hardware at the moment. This behavior though, is only
> +	available via c:macro:``CPUFREQ_ARCH_CUR_FREQ`` option.
>   
>   ``scaling_driver``
>   	The scaling driver currently in use.
> diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
> index 0b69bfbf345d..a00059139ca4 100644
> --- a/arch/x86/kernel/cpu/aperfmperf.c
> +++ b/arch/x86/kernel/cpu/aperfmperf.c
> @@ -413,7 +413,7 @@ void arch_scale_freq_tick(void)
>    */
>   #define MAX_SAMPLE_AGE	((unsigned long)HZ / 50)
>   
> -unsigned int arch_freq_get_on_cpu(int cpu)
> +int arch_freq_get_on_cpu(int cpu)
>   {
>   	struct aperfmperf *s = per_cpu_ptr(&cpu_samples, cpu);
>   	unsigned int seq, freq;
> diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
> index e65fae63660e..34d8fb93fb70 100644
> --- a/arch/x86/kernel/cpu/proc.c
> +++ b/arch/x86/kernel/cpu/proc.c
> @@ -86,9 +86,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
>   		seq_printf(m, "microcode\t: 0x%x\n", c->microcode);
>   
>   	if (cpu_has(c, X86_FEATURE_TSC)) {
> -		unsigned int freq = arch_freq_get_on_cpu(cpu);
> +		int freq = arch_freq_get_on_cpu(cpu);
>   
> -		seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 1000));
> +		if (freq <= 0)
> +			seq_puts(m, "cpu MHz\t\t: Unknown\n");
> +		else
> +			seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 1000));
>   	}
>   
>   	/* Cache size */
> diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
> index 97c2d4f15d76..212e1b9afe21 100644
> --- a/drivers/cpufreq/Kconfig.x86
> +++ b/drivers/cpufreq/Kconfig.x86
> @@ -340,3 +340,15 @@ config X86_SPEEDSTEP_RELAXED_CAP_CHECK
>   	  option lets the probing code bypass some of those checks if the
>   	  parameter "relaxed_check=1" is passed to the module.
>   
> +config CPUFREQ_ARCH_CUR_FREQ
> +	default y
> +	bool "Current frequency derived from HW provided feedback"
> +	help
> +	  This determines whether the scaling_cur_freq sysfs attribute returns
> +	  the last requested frequency or a more precise value based on hardware
> +	  provided feedback (as architected counters).
> +	  Given that a more precise frequency can now be provided via the
> +	  cpuinfo_avg_cur_freq attribute, by enabling this option,
> +	  scaling_cur_freq maintains the provision of a counter based frequency,
> +	  for compatibility reasons.
> +
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 04fc786dd2c0..70df2a24437b 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -747,9 +747,14 @@ show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
>   show_one(scaling_min_freq, min);
>   show_one(scaling_max_freq, max);
>   
> -__weak unsigned int arch_freq_get_on_cpu(int cpu)
> +__weak int arch_freq_get_on_cpu(int cpu)
>   {
> -	return 0;
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline bool cpufreq_avg_freq_supported(struct cpufreq_policy *policy)
> +{
> +	return arch_freq_get_on_cpu(policy->cpu) != -EOPNOTSUPP;
>   }
>   
>   static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
> @@ -757,8 +762,11 @@ static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
>   	ssize_t ret;
>   	unsigned int freq;
>   
> -	freq = arch_freq_get_on_cpu(policy->cpu);
> -	if (freq)
> +	freq = IS_ENABLED(CONFIG_CPUFREQ_ARCH_CUR_FREQ)
> +		? arch_freq_get_on_cpu(policy->cpu)
> +		: 0;
> +
> +	if (freq > 0)
>   		ret = sysfs_emit(buf, "%u\n", freq);
>   	else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
>   		ret = sysfs_emit(buf, "%u\n", cpufreq_driver->get(policy->cpu));
> @@ -802,6 +810,19 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
>   	return sysfs_emit(buf, "<unknown>\n");
>   }
>   
> +/*
> + * show_cpuinfo_avg_freq - average CPU frequency as detected by hardware
> + */
> +static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
> +				     char *buf)
> +{
> +	int avg_freq = arch_freq_get_on_cpu(policy->cpu);

We are seeing issues when reading cpuinfo_avg_freq on an ARM64 system:

$ cat /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq
cat: /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq: Resource 
temporarily unavailable

The CPU is in idle state, so arch_freq_get_on_cpu() can't find a good 
alternative source for frequency info.

One way to resolve this is to have fallback methods in show_cpuinfo_avg_freq() 
so it will look like this:

static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
                                      char *buf)
{
         int avg_freq = arch_freq_get_on_cpu(policy->cpu);
         int ret;

         if (avg_freq > 0)
                 ret = sysfs_emit(buf, "%u\n", avg_freq);
         else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
                 ret = sysfs_emit(buf, "%u\n", cpufreq_driver->get(policy->cpu));
         else
                 ret = sysfs_emit(buf, "%u\n", policy->cur);
         return ret;
}

But that also makes show_cpuinfo_avg_freq() pretty much the same as 
show_scaling_cur_freq().

So is it possible to consolidate show_cpuinfo_avg_freq() into 
show_scaling_cur_freq(), by making CONFIG_CPUFREQ_ARCH_CUR_FREQ also available 
to ARM64?

Kai-Heng

> +
> +	if (avg_freq > 0)
> +		return sysfs_emit(buf, "%u\n", avg_freq);
> +	return avg_freq != 0 ? avg_freq : -EINVAL;
> +}
> +
>   /*
>    * show_scaling_governor - show the current policy for the specified CPU
>    */
> @@ -964,6 +985,7 @@ static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
>   }
>   
>   cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
> +cpufreq_freq_attr_ro(cpuinfo_avg_freq);
>   cpufreq_freq_attr_ro(cpuinfo_min_freq);
>   cpufreq_freq_attr_ro(cpuinfo_max_freq);
>   cpufreq_freq_attr_ro(cpuinfo_transition_latency);
> @@ -1091,6 +1113,12 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy)
>   			return ret;
>   	}
>   
> +	if (cpufreq_avg_freq_supported(policy)) {
> +		ret = sysfs_create_file(&policy->kobj, &cpuinfo_avg_freq.attr);
> +		if (ret)
> +			return ret;
> +	}
> +
>   	ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
>   	if (ret)
>   		return ret;
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index d4d2f4d1d7cb..a7b6c0ccf9bc 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -1194,7 +1194,7 @@ static inline int of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_
>   }
>   #endif
>   
> -extern unsigned int arch_freq_get_on_cpu(int cpu);
> +extern int arch_freq_get_on_cpu(int cpu);
>   
>   #ifndef arch_set_freq_scale
>   static __always_inline



From xueshuai at linux.alibaba.com  Sun Dec 15 21:46:30 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Mon, 16 Dec 2024 13:46:30 +0800
Subject: [PATCH v17 0/3] ACPI: APEI: handle synchronous errors in task
 work
In-Reply-To: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
Message-ID: <290a8ac7-4d4b-472d-a77d-a0c76d7b963e@linux.alibaba.com>



? 2024/12/2 11:05, Shuai Xue ??:
> changes singce v16:
> - add reviewed-by tag for patch 1 and patch 2 from Yazen
> - rewrite warning message for force kill (per Yazen)
> - warn with dev_err in ghes (per Jarkko)
> - add return value -ENXIO in memory_failure comments  (per Yazen)
> - Link: https://lore.kernel.org/lkml/20241104015430.98599-1-xueshuai at linux.alibaba.com/
> 
> changes singce v15:
> - add HW_ERR and GHES_PFX prefix per Yazen
> 
> changes since v14:
> - add reviewed-by tags from Jarkko and Jonathan
> - remove local variable and use twcb->pfn
> 
> changes since v13:
> - add reviewed-by tag from Jarkko
> - rename task_work to ghes_task_work (per Jarkko)
> 
> changes since v12:
> - tweak error message for force kill (per Jarkko)
> - fix comments style (per Jarkko)
> - fix commit log typo (per Jarko)
> 
> changes since v11:
> - rebase to Linux 6.11-rc6
> - fix grammer and typo in commit log (per Borislav)
> - remove `sync_` perfix of `sync_task_work`  (per Borislav)
> - comments flags and description of `task_work`  (per Borislav)
> 
> changes since v10:
> - rebase to v6.8-rc2
> 
> changes since v9:
> - split patch 2 to address exactly one issue in one patch (per Borislav)
> - rewrite commit log according to template (per Borislav)
> - pickup reviewed-by tag of patch 1 from James Morse
> - alloc and free twcb through gen_pool_{alloc, free) (Per James)
> - rewrite cover letter
> 
> changes since v8:
> - remove the bug fix tag of patch 2 (per Jarkko Sakkinen)
> - remove the declaration of memory_failure_queue_kick (per Naoya Horiguchi)
> - rewrite the return value comments of memory_failure (per Naoya Horiguchi)
> 
> changes since v7:
> - rebase to Linux v6.6-rc2 (no code changed)
> - rewritten the cover letter to explain the motivation of this patchset
> 
> changes since v6:
> - add more explicty error message suggested by Xiaofei
> - pick up reviewed-by tag from Xiaofei
> - pick up internal reviewed-by tag from Baolin
> 
> changes since v5 by addressing comments from Kefeng:
> - document return value of memory_failure()
> - drop redundant comments in call site of memory_failure()
> - make ghes_do_proc void and handle abnormal case within it
> - pick up reviewed-by tag from Kefeng Wang
> 
> changes since v4 by addressing comments from Xiaofei:
> - do a force kill only for abnormal sync errors
> 
> changes since v3 by addressing comments from Xiaofei:
> - do a force kill for abnormal memory failure error such as invalid PA,
> unexpected severity, OOM, etc
> - pcik up tested-by tag from Ma Wupeng
> 
> changes since v2 by addressing comments from Naoya:
> - rename mce_task_work to sync_task_work
> - drop ACPI_HEST_NOTIFY_MCE case in is_hest_sync_notify()
> - add steps to reproduce this problem in cover letter
> 
> changes since v1:
> - synchronous events by notify type
> - Link: https://lore.kernel.org/lkml/20221206153354.92394-3-xueshuai at linux.alibaba.com/
> 
> ## Cover Letter
> 
> There are two major types of uncorrected recoverable (UCR) errors :
> 
> - Synchronous error: The error is detected and raised at the point of the
>    consumption in the execution flow, e.g. when a CPU tries to access
>    a poisoned cache line. The CPU will take a synchronous error exception
>    such as Synchronous External Abort (SEA) on Arm64 and Machine Check
>    Exception (MCE) on X86. OS requires to take action (for example, offline
>    failure page/kill failure thread) to recover this uncorrectable error.
> 
> - Asynchronous error: The error is detected out of processor execution
>    context, e.g. when an error is detected by a background scrubber. Some data
>    in the memory are corrupted. But the data have not been consumed. OS is
>    optional to take action to recover this uncorrectable error.
> 
> Currently, both synchronous and asynchronous error use
> memory_failure_queue() to schedule memory_failure() exectute in kworker
> context. As a result, when a user-space process is accessing a poisoned
> data, a data abort is taken and the memory_failure() is executed in the
> kworker context:
> 
>    - will send wrong si_code by SIGBUS signal in early_kill mode, and
>    - can not kill the user-space in some cases resulting a synchronous
>      error infinite loop
> 
> Issue 1: send wrong si_code in early_kill mode
> 
> Since commit a70297d22132 ("ACPI: APEI: set memory failure flags as
> MF_ACTION_REQUIRED on synchronous events")', the flag MF_ACTION_REQUIRED
> could be used to determine whether a synchronous exception occurs on
> ARM64 platform.  When a synchronous exception is detected, the kernel is
> expected to terminate the current process which has accessed poisoned
> page. This is done by sending a SIGBUS signal with an error code
> BUS_MCEERR_AR, indicating an action-required machine check error on
> read.
> 
> However, when kill_proc() is called to terminate the processes who have
> the poisoned page mapped, it sends the incorrect SIGBUS error code
> BUS_MCEERR_AO because the context in which it operates is not the one
> where the error was triggered.
> 
> To reproduce this problem:
> 
>    # STEP1: enable early kill mode
>    #sysctl -w vm.memory_failure_early_kill=1
>    vm.memory_failure_early_kill = 1
> 
>    # STEP2: inject an UCE error and consume it to trigger a synchronous error
>    #einj_mem_uc single
>    0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>    injecting ...
>    triggering ...
>    signal 7 code 5 addr 0xffffb0d75000
>    page not present
>    Test passed
> 
> The si_code (code 5) from einj_mem_uc indicates that it is BUS_MCEERR_AO
> error and it is not fact.
> 
> To fix it, queue memory_failure() as a task_work so that it runs in
> the context of the process that is actually consuming the poisoned data.
> 
> After this patch set:
> 
>    # STEP1: enable early kill mode
>    #sysctl -w vm.memory_failure_early_kill=1
>    vm.memory_failure_early_kill = 1
> 
>    # STEP2: inject an UCE error and consume it to trigger a synchronous error
>    #einj_mem_uc single
>    0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>    injecting ...
>    triggering ...
>    signal 7 code 4 addr 0xffffb0d75000
>    page not present
>    Test passed
> 
> The si_code (code 4) from einj_mem_uc indicates that it is BUS_MCEERR_AR
> error as we expected.
> 
> Issue 2: a synchronous error infinite loop due to memory_failure() failed
> 
> If a user-space process, e.g. devmem, a poisoned page which has been set
> HWPosion flag, kill_accessing_process() is called to send SIGBUS to the
> current processs with error info. Because the memory_failure() is
> executed in the kworker contex, it will just do nothing but return
> EFAULT. So, devmem will access the posioned page and trigger an
> excepction again, resulting in a synchronous error infinite loop. Such
> loop may cause platform firmware to exceed some threshold and reboot
> when Linux could have recovered from this error.
> 
> To reproduce this problem:
> 
>    # STEP 1: inject an UCE error, and kernel will set HWPosion flag for related page
>    #einj_mem_uc single
>    0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>    injecting ...
>    triggering ...
>    signal 7 code 4 addr 0xffffb0d75000
>    page not present
>    Test passed
> 
>    # STEP 2: access the same page and it will trigger a synchronous error infinite loop
>    devmem 0x4092d55b400
> 
> To fix it, if memory_failure() failed, perform a force kill to current process.
> 
> Issue 3: a synchronous error infinite loop due to no memory_failure() queued
> 
> No memory_failure() work is queued unless all bellow preconditions check passed:
> 
> - `if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))` in ghes_handle_memory_failure()
> - `if (flags == -1)` in ghes_handle_memory_failure()
> - `if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))` in ghes_do_memory_failure()
> - `if (!pfn_valid(pfn) && !arch_is_platform_page(physical_addr)) ` in ghes_do_memory_failure()
> 
> If the preconditions are not passed, the user-space process will trigger SEA again.
> This loop can potentially exceed the platform firmware threshold or even
> trigger a kernel hard lockup, leading to a system reboot.
> 
> To fix it, if no memory_failure() queued, perform a force kill to current process.
> 
> And the the memory errors triggered in kernel-mode[5], also relies on this
> patchset to kill the failure thread.
> 
> Lv Ying and XiuQi from Huawei also proposed to address similar problem[2][4].
> Acknowledge to discussion with them.
> 
> [1] Add ARMv8 RAS virtualization support in QEMU https://patchew.org/QEMU/20200512030609.19593-1-gengdongjiu at huawei.com/
> [2] https://lore.kernel.org/lkml/20221205115111.131568-3-lvying6 at huawei.com/
> [3] https://lkml.kernel.org/r/20220914064935.7851-1-xueshuai at linux.alibaba.com
> [4] https://lore.kernel.org/lkml/20221209095407.383211-1-lvying6 at huawei.com/
> [5] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20240528085915.1955987-1-tongtiangen at huawei.com/
> 
> Shuai Xue (3):
>    ACPI: APEI: send SIGBUS to current task if synchronous memory error
>      not recovered
>    mm: memory-failure: move return value documentation to function
>      declaration
>    ACPI: APEI: handle synchronous exceptions in task work
> 
>   arch/x86/kernel/cpu/mce/core.c |  7 ---
>   drivers/acpi/apei/ghes.c       | 86 +++++++++++++++++++++-------------
>   include/acpi/ghes.h            |  3 --
>   include/linux/mm.h             |  1 -
>   mm/memory-failure.c            | 23 +++------
>   5 files changed, 61 insertions(+), 59 deletions(-)
> 

Hi, Rafael,

I hope this message finds you well.

I am writing to provide an update on the current status of the patch set, now
at *revision 17*. Each patch has been thoroughly reviewed by 3-5 reviewers, and
their feedback has been incorporated to address any concerns.

Given the extensive review and iterations the patch set has undergone, I would
like to inquire that are you happy to queue this patch set?

Best Regards,
Shuai


From lcherian at marvell.com  Sun Dec 15 21:50:10 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Mon, 16 Dec 2024 11:20:10 +0530
Subject: [PATCH] selftests: arm coresight: sysfsmode testing
In-Reply-To: <1b7aaa17-48b7-45cd-b468-ef54ca048e31@linaro.org>
References: <20241129083813.3056909-1-lcherian@marvell.com>
 <1b7aaa17-48b7-45cd-b468-ef54ca048e31@linaro.org>
Message-ID: <20241216055010.GA1237565@hyd1403.caveonetworks.com>

On 2024-12-04 at 16:45:42, James Clark (james.clark at linaro.org) wrote:
> 
> 
> On 29/11/2024 8:38 am, Linu Cherian wrote:
> > Add sysfs mode selftest for ARM Coresight hardware tracer.
> > 
> > Signed-off-by: Linu Cherian <lcherian at marvell.com>
> > ---
> >   .../drivers/hwtracing/coresight/Makefile      |   5 +
> >   .../hwtracing/coresight/sysfs_test_trace.sh   | 144 ++++++++++++++++++
> >   2 files changed, 149 insertions(+)
> >   create mode 100644 tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> 
> Hi Linu,
> 
> You need to add this path into TARGETS for make install to work:
> 
>  TARGETS += drivers/dma-buf
> +TARGETS += drivers/hwtracing/coresight
>  TARGETS += drivers/s390x/uvdevice
> 
> 
> >   create mode 100755 tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> > 
> > diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/Makefile b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> > new file mode 100644
> > index 000000000000..7dc68ae1c0a9
> > --- /dev/null
> > +++ b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
> > @@ -0,0 +1,5 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +TEST_PROGS = sysfs_test_trace.sh
> > +
> > +include ../../../lib.mk
> > diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> > new file mode 100755
> > index 000000000000..0d6307fff1d2
> > --- /dev/null
> > +++ b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
> > @@ -0,0 +1,144 @@
> > +#!/bin/sh
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (C) 2024 Marvell.
> > +
> > +# Test Arm CoreSight trace capture in sysfs mode
> > +# Based on tools/perf/tests/shell/test_arm_coresight.sh
> > +
> > +glb_err=0
> > +
> > +arm_cs_report() {
> > +	if [ $2 != 0 ]; then
> > +		echo "$1: FAIL"
> > +		glb_err=$2
> > +	else
> > +		echo "$1: PASS"
> > +	fi
> > +}
> > +
> > +is_device_sink() {
> > +	# If the node of "enable_sink" is existed under the device path, this
> > +	# means the device is a sink device.
> > +
> 
> Looks like you still need the skip for TPIU here the same as the Perf test.
> It's an external sink and doesn't have a readable file so the test fails.
> 

Okay will skip.

> With those changes, looks good. Thanks for adding the first sysfs test.
> Hopefully we can expand them more in the future.
> 
> Reviewed-by: James Clark <james.clark at linaro.org>
> 

Thanks.
Linu Cherian.
 


From ck.hu at mediatek.com  Sun Dec 15 22:05:33 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 16 Dec 2024 06:05:33 +0000
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
Message-ID: <4e18327e7ab92fd987d379110cfa36f33666e015.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static void mtk_hdmi_unregister_audio_driver(void *data)
> +{
> +       platform_device_unregister(data);
> +}
> +
> +static int mtk_hdmi_register_audio_driver(struct device *dev)
> +{
> +       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +       struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> +       struct hdmi_codec_pdata codec_data = {
> +               .i2s = 1,
> +               .max_i2s_channels = 2,
> +               .data = hdmi,
> +               .ops = hdmi->conf->ver_conf->codec_ops
> +       };
> +       int ret;
> +
> +       aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +       aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +       aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> +       aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> +       aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> +       aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;

You squash mtk_hdmi_outout_init() into this function.
I'm not sure this is necessary or not.
If it's necessary, I would like this modification to be a separate patch and it's easier to review.
I want this patch is simply moving common code.

And this patch remove hdmi->csp and it is really not necessary.
Let removing hdmi->csp be a clean up patch.

> +
> +       hdmi->audio_pdev = platform_device_register_data(dev,
> +                                                        HDMI_CODEC_DRV_NAME,
> +                                                        PLATFORM_DEVID_AUTO,
> +                                                        &codec_data,
> +                                                        sizeof(codec_data));
> +       if (IS_ERR(hdmi->audio_pdev))
> +               return PTR_ERR(hdmi->audio_pdev);
> +
> +       ret = devm_add_action_or_reset(dev, mtk_hdmi_unregister_audio_driver,
> +                                      hdmi->audio_pdev);

This adding action or reset is other than moving common function.
So separate this to a refinement patch.

Regards,
CK

> +       if (ret) {
> +               platform_device_unregister(hdmi->audio_pdev);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +



From akpm at linux-foundation.org  Sun Dec 15 22:26:55 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Sun, 15 Dec 2024 22:26:55 -0800
Subject: [PATCH v3 00/25] fs/dax: Fix ZONE_DEVICE page reference counts
In-Reply-To: <wysuus23bqmjtwkfu3zutqtmkse3ki3erf45x32yezlrl24qto@xlqt7qducyld>
References: <cover.e1ebdd6cab9bde0d232c1810deacf0bae25e6707.1732239628.git-series.apopple@nvidia.com>
	<675ce1e5a3d68_fad0294d0@dwillia2-xfh.jf.intel.com.notmuch>
	<45555f72-e82a-4196-94af-22d05d6ac947@redhat.com>
	<wysuus23bqmjtwkfu3zutqtmkse3ki3erf45x32yezlrl24qto@xlqt7qducyld>
Message-ID: <20241215222655.ef0b15148120a2e2b06b2234@linux-foundation.org>

On Mon, 16 Dec 2024 11:55:30 +1100 Alistair Popple <apopple at nvidia.com> wrote:

> The remainder are more -mm focussed. However they do depend on the fs/dax
> cleanups in the first half so the trick would be making sure Andrew only takes
> them if the nvdimm.git changes have made it into -next. I'm happy with either
> approach, so let me know if I should split the series or not.

My inclination is to put it all into the nvdimm tree, with appropriate
MM developer acks.

But I'm having difficulty determining how practical that is because the
v3 series is almost a month old so my test merging was quite ugly.

Perhaps you could prepare a new-doesn't-need-to-be-final version for
people to look at and to aid with this head-scratching?


From victor.liu at nxp.com  Sun Dec 15 22:29:10 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 16 Dec 2024 14:29:10 +0800
Subject: [PATCH v6 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <CAA8EJppBpeMA3aSzk025tvzfTW-bFxeZS4kj0Ujk_AuCyoxnEg@mail.gmail.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com>
 <20241209033923.3009629-13-victor.liu@nxp.com>
 <3j4fguv4oienfaj4fghpiqpmnq3aczu4azhdo5jzvywc5mawm5@hh33p3dhf6xa>
 <db4d9d4e-855f-4647-9b93-ccc5ec0202b3@nxp.com>
 <q6pdop6ucowtoxxr66czq7yooujyvp6qs5vcg6gpmi3q4rs4l3@szyqt5pxteoz>
 <b02fb998-9420-4954-8e48-82447493bbb7@nxp.com>
 <CAA8EJppBpeMA3aSzk025tvzfTW-bFxeZS4kj0Ujk_AuCyoxnEg@mail.gmail.com>
Message-ID: <95a5c779-941a-4942-8988-65fbe1c4cf82@nxp.com>

On 12/13/2024, Dmitry Baryshkov wrote:
> On Fri, 13 Dec 2024 at 08:06, Liu Ying <victor.liu at nxp.com> wrote:
>>
>> On 12/12/2024, Dmitry Baryshkov wrote:
>>> On Wed, Dec 11, 2024 at 03:43:20PM +0800, Liu Ying wrote:
>>>> On 12/10/2024, Dmitry Baryshkov wrote:
>>>>> On Mon, Dec 09, 2024 at 11:39:16AM +0800, Liu Ying wrote:
>>>>>> i.MX8qxp Display Controller(DC) is comprised of three main components that
>>>>>> include a blit engine for 2D graphics accelerations, display controller for
>>>>>> display output processing, as well as a command sequencer.  Add kernel
>>>>>> mode setting support for the display controller part with two CRTCs and
>>>>>> two primary planes(backed by FetchLayer and FetchWarp respectively).  The
>>>>>> registers of the display controller are accessed without command sequencer
>>>>>> involved, instead just by using CPU.  The command sequencer is supposed to
>>>>>> be used by the blit engine.
>>>>>>
>>>>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>>>>>> ---
>>>>>> v6:
>>>>>> * No change.
>>>>>>
>>>>>> v5:
>>>>>> * Replace .remove_new with .remove in dc-drv.c. (Uwe)
>>>>>>
>>>>>> v4:
>>>>>> * Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
>>>>>>   function calls from KMS routine to initialization stage. (Dmitry)
>>>>>> * Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
>>>>>>   appropriate .h header files or .c source files. (Dmitry)
>>>>>> * Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
>>>>>> * Drop dc_drm->pe_rpm_count. (Dmitry)
>>>>>> * Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
>>>>>> * Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
>>>>>>   Instead, put it in struct dc_crtc.  (Dmitry)
>>>>>> * Call devm_request_irq() to request IRQs, instead of using drmm action.
>>>>>>   (Dmitry)
>>>>>> * Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
>>>>>> * Select DRM_CLIENT_SELECTION due to rebase.
>>>>>> * Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
>>>>>> * Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
>>>>>> * Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
>>>>>>   rebase.
>>>>>> * Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
>>>>>>   register dc_drm_component_unbind_all() action.
>>>>>> * Request interrupts in dc_crtc_post_init() after encoder initialization to
>>>>>>   make sure next bridge is found first.
>>>>>>
>>>>>> v3:
>>>>>> * No change.
>>>>>>
>>>>>> v2:
>>>>>> * Find next bridge from TCon's port.
>>>>>> * Drop drm/drm_module.h include from dc-drv.c.
>>>>>>
>>>>>>  drivers/gpu/drm/imx/dc/Kconfig    |   5 +
>>>>>>  drivers/gpu/drm/imx/dc/Makefile   |   5 +-
>>>>>>  drivers/gpu/drm/imx/dc/dc-crtc.c  | 558 ++++++++++++++++++++++++++++++
>>>>>>  drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
>>>>>>  drivers/gpu/drm/imx/dc/dc-drv.c   | 244 +++++++++++++
>>>>>>  drivers/gpu/drm/imx/dc/dc-drv.h   |  19 +
>>>>>>  drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
>>>>>>  drivers/gpu/drm/imx/dc/dc-kms.h   |  58 ++++
>>>>>>  drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
>>>>>>  9 files changed, 1274 insertions(+), 2 deletions(-)
>>>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
>>>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
>>>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
>>>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
>>>>>> index 1fc84c7475de..415993207f2e 100644
>>>>>> --- a/drivers/gpu/drm/imx/dc/Kconfig
>>>>>> +++ b/drivers/gpu/drm/imx/dc/Kconfig
>>>>>> @@ -1,6 +1,11 @@
>>>>>>  config DRM_IMX8_DC
>>>>>>    tristate "Freescale i.MX8 Display Controller Graphics"
>>>>>>    depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
>>>>>> +  select DRM_CLIENT_SELECTION
>>>>>> +  select DRM_GEM_DMA_HELPER
>>>>>> +  select DRM_KMS_HELPER
>>>>>> +  select DRM_DISPLAY_HELPER
>>>>>> +  select DRM_BRIDGE_CONNECTOR
>>>>>>    select GENERIC_IRQ_CHIP
>>>>>>    select REGMAP
>>>>>>    select REGMAP_MMIO
>>>>>> diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
>>>>>> index 1ce3e8a8db22..b9d33c074984 100644
>>>>>> --- a/drivers/gpu/drm/imx/dc/Makefile
>>>>>> +++ b/drivers/gpu/drm/imx/dc/Makefile
>>>>>> @@ -1,6 +1,7 @@
>>>>>>  # SPDX-License-Identifier: GPL-2.0
>>>>>>
>>>>>> -imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
>>>>>> -              dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
>>>>>> +imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
>>>>>> +              dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
>>>>>> +              dc-plane.o dc-tc.o
>>>>>>
>>>>>>  obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
>>>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
>>>>>> new file mode 100644
>>>>>> index 000000000000..fd6daa1807d8
>>>>>> --- /dev/null
>>>>>> +++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
>>>>>> @@ -0,0 +1,558 @@
>>>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>>>> +/*
>>>>>> + * Copyright 2024 NXP
>>>>>> + */
>>>>>> +
>>>>>> +#include <linux/completion.h>
>>>>>> +#include <linux/container_of.h>
>>>>>> +#include <linux/interrupt.h>
>>>>>> +#include <linux/irqreturn.h>
>>>>>> +#include <linux/pm_runtime.h>
>>>>>> +#include <linux/spinlock.h>
>>>>>> +
>>>>>> +#include <drm/drm_atomic.h>
>>>>>> +#include <drm/drm_atomic_helper.h>
>>>>>> +#include <drm/drm_atomic_state_helper.h>
>>>>>> +#include <drm/drm_crtc.h>
>>>>>> +#include <drm/drm_device.h>
>>>>>> +#include <drm/drm_drv.h>
>>>>>> +#include <drm/drm_modes.h>
>>>>>> +#include <drm/drm_modeset_helper_vtables.h>
>>>>>> +#include <drm/drm_plane.h>
>>>>>> +#include <drm/drm_print.h>
>>>>>> +#include <drm/drm_vblank.h>
>>>>>> +
>>>>>> +#include "dc-de.h"
>>>>>> +#include "dc-drv.h"
>>>>>> +#include "dc-kms.h"
>>>>>> +#include "dc-pe.h"
>>>>>> +
>>>>>> +#define dc_crtc_dbg(crtc, fmt, ...)                                       \
>>>>>> +do {                                                                      \
>>>>>> +  typeof(crtc) _crtc = (crtc);                                    \
>>>>>
>>>>> Use exact type instead of typeof.
>>>>
>>>> Will do.
>>>>
>>>>>
>>>>>> +  drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt,                    \
>>>>>> +              _crtc->base.id, _crtc->name, ##__VA_ARGS__);        \
>>>>>> +} while (0)
>>>>>> +
>>>>>> +#define dc_crtc_err(crtc, fmt, ...)                                       \
>>>>>> +do {                                                                      \
>>>>>> +  typeof(crtc) _crtc = (crtc);                                    \
>>>>>> +  drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt,                        \
>>>>>> +          _crtc->base.id, _crtc->name, ##__VA_ARGS__);            \
>>>>>> +} while (0)
>>>>>> +
>>>>>> +#define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c)                            \
>>>>>> +do {                                                                      \
>>>>>> +  unsigned long ret;                                              \
>>>>>> +  ret = wait_for_completion_timeout(&dc_crtc->c, HZ);             \
>>>>>> +  if (ret == 0)                                                   \
>>>>>> +          dc_crtc_err(crtc, "%s: wait for " #c " timeout\n",      \
>>>>>> +                                                  __func__);      \
>>>>>> +} while (0)
>>>>>> +
>>>>>> +#define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg)                                   \
>>>>>> +do {                                                                      \
>>>>>> +  typeof(fg) _fg = (fg);                                          \
>>>>>> +  if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) {         \
>>>>>> +          dc_fg_secondary_clear_channel_status(_fg);              \
>>>>>> +          dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n",          \
>>>>>> +                                                  __func__);      \
>>>>>> +  }                                                               \
>>>>>> +} while (0)
>>>>>> +
>>>>>> +#define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg)                    \
>>>>>> +do {                                                                      \
>>>>>> +  if (dc_fg_wait_for_secondary_syncup(fg))                        \
>>>>>> +          dc_crtc_err(crtc,                                       \
>>>>>> +                  "%s: FrameGen secondary channel isn't syncup\n",\
>>>>>> +                                                  __func__);      \
>>>>>> +} while (0)
>>>>>> +
>>>>>> +static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
>>>>>> +{
>>>>>> +  return container_of(crtc, struct dc_crtc, base);
>>>>>> +}
>>>>>> +
>>>>>> +static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +
>>>>>> +  return dc_fg_get_frame_index(dc_crtc->fg);
>>>>>> +}
>>>>>> +
>>>>>> +static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +
>>>>>> +  enable_irq(dc_crtc->irq_dec_framecomplete);
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +
>>>>>> +  disable_irq_nosync(dc_crtc->irq_dec_framecomplete);
>>>>>
>>>>> Why is it _nosync?
>>>>
>>>> Because disable_irq() can only be called from preemptible code according to
>>>> it's kerneldoc. If I use disable_irq() here, I get this with
>>>> CONFIG_DEBUG_ATOMIC_SLEEP enabled:
>>>
>>> Please add a one-line comment, like "nosync because of the atomic
>>> context"
>>
>> Will do.
>>
>>>
>>>>
>>>> [   50.607503] BUG: sleeping function called from invalid context at kernel/irq/manage.c:738
>>>> [   50.615691] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/0
>>>> [   50.623527] preempt_count: 10003, expected: 0
>>>> [   50.627888] RCU nest depth: 0, expected: 0
>>>> [   50.631993] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.13.0-rc2-next-20241209-00026-g800cb5b7df74 #1407
>>>> [   50.642092] Hardware name: Freescale i.MX8QXP MEK (DT)
>>>> [   50.647237] Call trace:
>>>> [   50.649687]  show_stack+0x18/0x24 (C)
>>>> [   50.653369]  dump_stack_lvl+0x80/0xb4
>>>> [   50.657043]  dump_stack+0x18/0x24
>>>> [   50.660370]  __might_resched+0x114/0x170
>>>> [   50.664306]  __might_sleep+0x48/0x98
>>>> [   50.667894]  disable_irq+0x24/0x60
>>>> [   50.671308]  dc_crtc_disable_vblank+0x14/0x20 [imx8_dc_drm]
>>>> [   50.676912]  drm_vblank_disable_and_save+0xc0/0x108 [drm]
>>>> [   50.682533]  vblank_disable_fn+0x78/0x9c [drm]
>>>> [   50.687146]  drm_handle_vblank+0x238/0x2e8 [drm]
>>>> [   50.691932]  drm_crtc_handle_vblank+0x1c/0x28 [drm]
>>>> [   50.696980]  dc_crtc_irq_handler_dec_framecomplete+0x1c/0x6c [imx8_dc_drm]
>>>> [   50.703886]  __handle_irq_event_percpu+0x60/0x14c
>>>> [   50.708604]  handle_irq_event+0x4c/0xac
>>>> [   50.712443]  handle_level_irq+0xc0/0x1b0
>>>> [   50.716379]  generic_handle_irq+0x34/0x4c
>>>> [   50.720392]  dc_ic_irq_handler+0x128/0x160 [imx8_dc_drm]
>>>> [   50.725727]  generic_handle_domain_irq+0x2c/0x44
>>>> [   50.730357]  imx_irqsteer_irq_handler+0xc0/0x1a0
>>>> [   50.734987]  generic_handle_domain_irq+0x2c/0x44
>>>> [   50.739609]  gic_handle_irq+0x4c/0x114
>>>> [   50.743362]  call_on_irq_stack+0x24/0x4c
>>>> [   50.747298]  do_interrupt_handler+0x80/0x84
>>>> [   50.751494]  el1_interrupt+0x34/0x68
>>>> [   50.755082]  el1h_64_irq_handler+0x18/0x24
>>>> [   50.759191]  el1h_64_irq+0x6c/0x70
>>>> [   50.762597]  default_idle_call+0x28/0x3c (P)
>>>> [   50.766879]  default_idle_call+0x24/0x3c (L)
>>>> [   50.771163]  do_idle+0x200/0x25c
>>>> [   50.774403]  cpu_startup_entry+0x34/0x3c
>>>> [   50.778338]  kernel_init+0x0/0x1d8
>>>> [   50.781752]  start_kernel+0x5c4/0x70c
>>>> [   50.785427]  __primary_switched+0x88/0x90
>>>>
>>>>>
>>>>>> +}
>>>>>> +
>>>>>> +static irqreturn_t
>>>>>> +dc_crtc_dec_framecomplete_irq_handler(int irq, void *dev_id)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = dev_id;
>>>>>> +  struct drm_crtc *crtc = &dc_crtc->base;
>>>>>> +  unsigned long flags;
>>>>>> +
>>>>>> +  drm_crtc_handle_vblank(crtc);
>>>>>> +
>>>>>> +  spin_lock_irqsave(&crtc->dev->event_lock, flags);
>>>>>> +  if (dc_crtc->event) {
>>>>>> +          drm_crtc_send_vblank_event(crtc, dc_crtc->event);
>>>>>> +          dc_crtc->event = NULL;
>>>>>> +          drm_crtc_vblank_put(crtc);
>>>>>> +  }
>>>>>> +  spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
>>>>>> +
>>>>>> +  return IRQ_HANDLED;
>>>>>> +}
>>>>>> +
>>>>>> +static irqreturn_t dc_crtc_common_irq_handler(int irq, void *dev_id)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = dev_id;
>>>>>> +
>>>>>> +  if (irq == dc_crtc->irq_dec_seqcomplete)
>>>>>> +          complete(&dc_crtc->dec_seqcomplete_done);
>>>>>> +  else if (irq == dc_crtc->irq_dec_shdld)
>>>>>> +          complete(&dc_crtc->dec_shdld_done);
>>>>>> +  else if (irq == dc_crtc->irq_ed_cont_shdld)
>>>>>> +          complete(&dc_crtc->ed_cont_shdld_done);
>>>>>> +  else if (irq == dc_crtc->irq_ed_safe_shdld)
>>>>>> +          complete(&dc_crtc->ed_safe_shdld_done);
>>>>>
>>>>> Is there any reason to have a single multiplex handler instead of having
>>>>> 4 separate handlers, each doing one simple thing?
>>>>
>>>> Just thought that one irq handler is feasible to implement the common
>>>> handling logic. It's also ok to use 4 separate handlers with a little
>>>> performance improvement. I may change to use 4 separate handlers by
>>>> introducing a DEFINE_DC_CRTC_IRQ_HANDLER() marco.
>>>
>>> Just define them one by one, there is no need for a macro.
>>
>> Will do.
>>
>>>
>>>>
>>>>>
>>>>>> +
>>>>>> +  return IRQ_HANDLED;
>>>>>> +}
>>>>>> +
>>>>>> +static const struct drm_crtc_funcs dc_crtc_funcs = {
>>>>>> +  .reset                  = drm_atomic_helper_crtc_reset,
>>>>>> +  .destroy                = drm_crtc_cleanup,
>>>>>> +  .set_config             = drm_atomic_helper_set_config,
>>>>>> +  .page_flip              = drm_atomic_helper_page_flip,
>>>>>> +  .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
>>>>>> +  .atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
>>>>>> +  .get_vblank_counter     = dc_crtc_get_vblank_counter,
>>>>>> +  .enable_vblank          = dc_crtc_enable_vblank,
>>>>>> +  .disable_vblank         = dc_crtc_disable_vblank,
>>>>>> +  .get_vblank_timestamp   = drm_crtc_vblank_helper_get_vblank_timestamp,
>>>>>> +};
>>>>>> +
>>>>>> +static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
>>>>>> +{
>>>>>> +  struct drm_crtc *crtc = crtc_state->crtc;
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +
>>>>>> +  spin_lock_irq(&crtc->dev->event_lock);
>>>>>> +  if (crtc_state->event) {
>>>>>> +          WARN_ON(drm_crtc_vblank_get(crtc));
>>>>>> +          WARN_ON(dc_crtc->event);
>>>>>> +          dc_crtc->event = crtc_state->event;
>>>>>> +          crtc_state->event = NULL;
>>>>>> +  }
>>>>>> +  spin_unlock_irq(&crtc->dev->event_lock);
>>>>>> +}
>>>>>> +
>>>>>> +static enum drm_mode_status
>>>>>> +dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
>>>>>> +{
>>>>>> +  return dc_fg_check_clock(dc_crtc->fg, clk_khz);
>>>>>> +}
>>>>>
>>>>> inline
>>>>
>>>> Will do.
>>>>
>>>>>
>>>>>> +
>>>>>> +static enum drm_mode_status
>>>>>> +dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +  enum drm_mode_status status;
>>>>>> +
>>>>>> +  status = dc_crtc_check_clock(dc_crtc, mode->clock);
>>>>>> +  if (status != MODE_OK)
>>>>>> +          return status;
>>>>>> +
>>>>>> +  if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
>>>>>> +          return MODE_CLOCK_HIGH;
>>>>>> +
>>>>>> +  return MODE_OK;
>>>>>> +}
>>>>>> +
>>>>>> +static int
>>>>>> +dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>>>> +{
>>>>>> +  struct drm_crtc_state *new_crtc_state =
>>>>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
>>>>>> +  struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +  enum drm_mode_status status;
>>>>>> +
>>>>>> +  status = dc_crtc_check_clock(dc_crtc, adj->clock);
>>>>>> +  if (status != MODE_OK)
>>>>>> +          return -EINVAL;
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static void
>>>>>> +dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>>>> +{
>>>>>> +  struct drm_crtc_state *new_crtc_state =
>>>>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +  int idx, ret;
>>>>>> +
>>>>>> +  if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
>>>>>> +      !new_crtc_state->active)
>>>>>> +          return;
>>>>>> +
>>>>>> +  if (!drm_dev_enter(crtc->dev, &idx))
>>>>>> +          return;
>>>>>> +
>>>>>> +  /* request pixel engine power-on when CRTC starts to be active */
>>>>>> +  ret = pm_runtime_resume_and_get(dc_crtc->pe->dev);
>>>>>> +  if (ret)
>>>>>> +          dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
>>>>>> +                      ret);
>>>>>> +
>>>>>> +  drm_dev_exit(idx);
>>>>>> +}
>>>>>> +
>>>>>> +static void
>>>>>> +dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>>>> +{
>>>>>> +  struct drm_crtc_state *old_crtc_state =
>>>>>> +                          drm_atomic_get_old_crtc_state(state, crtc);
>>>>>> +  struct drm_crtc_state *new_crtc_state =
>>>>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +  int idx;
>>>>>> +
>>>>>> +  if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
>>>>>> +      (!old_crtc_state->active && !new_crtc_state->active))
>>>>>> +          return;
>>>>>> +
>>>>>> +  if (!drm_dev_enter(crtc->dev, &idx))
>>>>>> +          goto out;
>>>>>> +
>>>>>> +  enable_irq(dc_crtc->irq_ed_cont_shdld);
>>>>>> +
>>>>>> +  /* flush plane update out to display */
>>>>>> +  dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
>>>>>> +
>>>>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
>>>>>> +
>>>>>> +  disable_irq(dc_crtc->irq_ed_cont_shdld);
>>>>>> +
>>>>>> +  DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
>>>>>> +
>>>>>> +  drm_dev_exit(idx);
>>>>>> +
>>>>>> +out:
>>>>>> +  dc_crtc_queue_state_event(new_crtc_state);
>>>>>> +}
>>>>>> +
>>>>>> +static void
>>>>>> +dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>>>> +{
>>>>>> +  struct drm_crtc_state *new_crtc_state =
>>>>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
>>>>>> +  struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +  enum dc_link_id cf_link;
>>>>>> +  int idx, ret;
>>>>>> +
>>>>>> +  dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
>>>>>> +
>>>>>> +  drm_crtc_vblank_on(crtc);
>>>>>> +
>>>>>> +  if (!drm_dev_enter(crtc->dev, &idx))
>>>>>> +          goto out;
>>>>>> +
>>>>>> +  /* request display engine power-on when CRTC is enabled */
>>>>>> +  ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
>>>>>> +  if (ret < 0)
>>>>>> +          dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
>>>>>> +                      ret);
>>>>>> +
>>>>>> +  enable_irq(dc_crtc->irq_dec_shdld);
>>>>>> +  enable_irq(dc_crtc->irq_ed_cont_shdld);
>>>>>> +  enable_irq(dc_crtc->irq_ed_safe_shdld);
>>>>>> +
>>>>>> +  dc_fg_cfg_videomode(dc_crtc->fg, adj);
>>>>>> +
>>>>>> +  dc_cf_framedimensions(dc_crtc->cf_cont,
>>>>>> +                        adj->crtc_hdisplay, adj->crtc_vdisplay);
>>>>>> +  dc_cf_framedimensions(dc_crtc->cf_safe,
>>>>>> +                        adj->crtc_hdisplay, adj->crtc_vdisplay);
>>>>>> +
>>>>>> +  /* constframe in safety stream shows blue frame */
>>>>>> +  dc_cf_constantcolor_blue(dc_crtc->cf_safe);
>>>>>> +  cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
>>>>>> +  dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
>>>>>> +
>>>>>> +  /* show CRTC background if no plane is enabled */
>>>>>> +  if (new_crtc_state->plane_mask == 0) {
>>>>>> +          /* constframe in content stream shows black frame */
>>>>>> +          dc_cf_constantcolor_black(dc_crtc->cf_cont);
>>>>>> +
>>>>>> +          cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
>>>>>> +          dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
>>>>>> +  }
>>>>>> +
>>>>>> +  dc_fg_enable_clock(dc_crtc->fg);
>>>>>> +  dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
>>>>>> +  dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
>>>>>> +  dc_fg_shdtokgen(dc_crtc->fg);
>>>>>> +  dc_fg_enable(dc_crtc->fg);
>>>>>> +
>>>>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdld_done);
>>>>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
>>>>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdld_done);
>>>>>> +
>>>>>> +  disable_irq(dc_crtc->irq_ed_safe_shdld);
>>>>>> +  disable_irq(dc_crtc->irq_ed_cont_shdld);
>>>>>> +  disable_irq(dc_crtc->irq_dec_shdld);
>>>>>> +
>>>>>> +  DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
>>>>>> +
>>>>>> +  DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
>>>>>> +
>>>>>> +  drm_dev_exit(idx);
>>>>>> +
>>>>>> +out:
>>>>>> +  dc_crtc_queue_state_event(new_crtc_state);
>>>>>> +}
>>>>>> +
>>>>>> +static void
>>>>>> +dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
>>>>>> +{
>>>>>> +  struct drm_crtc_state *new_crtc_state =
>>>>>> +                          drm_atomic_get_new_crtc_state(state, crtc);
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +  int idx, ret;
>>>>>> +
>>>>>> +  if (!drm_dev_enter(crtc->dev, &idx))
>>>>>> +          goto out;
>>>>>> +
>>>>>> +  enable_irq(dc_crtc->irq_dec_seqcomplete);
>>>>>> +  dc_fg_disable(dc_crtc->fg);
>>>>>> +  DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
>>>>>> +  disable_irq(dc_crtc->irq_dec_seqcomplete);
>>>>>> +
>>>>>> +  dc_fg_disable_clock(dc_crtc->fg);
>>>>>> +
>>>>>> +  /* request pixel engine power-off as plane is off too */
>>>>>> +  ret = pm_runtime_put(dc_crtc->pe->dev);
>>>>>> +  if (ret)
>>>>>> +          dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
>>>>>> +                      ret);
>>>>>> +
>>>>>> +  /* request display engine power-off when CRTC is disabled */
>>>>>> +  ret = pm_runtime_put(dc_crtc->de->dev);
>>>>>
>>>>> Can this be expressed as a devlink between PE and DE?
>>>>
>>>> Looking at struct dc_{pe,de}, PE and DE are not dependent with each other,
>>>> i.e., no consumer/supplier relationship(note that blit engine in PE can work
>>>> by itself without DE) between them. So, it doesn't look right to link the two
>>>> devices.
>>>
>>> Ack
>>>
>>>>
>>>>>
>>>>>> +  if (ret < 0)
>>>>>> +          dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
>>>>>> +                      ret);
>>>>>> +
>>>>>> +  drm_dev_exit(idx);
>>>>>> +
>>>>>> +out:
>>>>>> +  drm_crtc_vblank_off(crtc);
>>>>>> +
>>>>>> +  spin_lock_irq(&crtc->dev->event_lock);
>>>>>> +  if (new_crtc_state->event && !new_crtc_state->active) {
>>>>>> +          drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
>>>>>> +          new_crtc_state->event = NULL;
>>>>>> +  }
>>>>>> +  spin_unlock_irq(&crtc->dev->event_lock);
>>>>>> +}
>>>>>> +
>>>>>> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +  int ret;
>>>>>> +
>>>>>> +  if (!dc_fg_wait_for_frame_index_moving(dc_crtc->fg))
>>>>>> +          return;
>>>>>> +
>>>>>> +  dc_fg_disable_clock(dc_crtc->fg);
>>>>>> +
>>>>>> +  if (pm_runtime_active(dc_crtc->pe->dev)) {
>>>>>> +          ret = pm_runtime_put_sync(dc_crtc->pe->dev);
>>>>>> +          if (ret)
>>>>>> +                  dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
>>>>>> +                              ret);
>>>>>> +  }
>>>>>> +
>>>>>> +  ret = pm_runtime_put_sync(dc_crtc->de->dev);
>>>>>> +  if (ret < 0)
>>>>>> +          dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
>>>>>> +                      ret);
>>>>>> +}
>>>>>> +
>>>>>> +static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
>>>>>> +                                   bool in_vblank_irq,
>>>>>> +                                   int *vpos, int *hpos,
>>>>>> +                                   ktime_t *stime, ktime_t *etime,
>>>>>> +                                   const struct drm_display_mode *mode)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>>>>>> +  int vdisplay = mode->crtc_vdisplay;
>>>>>> +  int vtotal = mode->crtc_vtotal;
>>>>>> +  bool reliable;
>>>>>> +  int line;
>>>>>> +  int idx;
>>>>>> +
>>>>>> +  if (stime)
>>>>>> +          *stime = ktime_get();
>>>>>> +
>>>>>> +  if (!drm_dev_enter(crtc->dev, &idx)) {
>>>>>> +          reliable = false;
>>>>>> +          *vpos = 0;
>>>>>> +          *hpos = 0;
>>>>>> +          goto out;
>>>>>> +  }
>>>>>> +
>>>>>> +  /* line index starts with 0 for the first active output line */
>>>>>> +  line = dc_fg_get_line_index(dc_crtc->fg);
>>>>>> +
>>>>>> +  if (line < vdisplay)
>>>>>> +          /* active scanout area - positive */
>>>>>> +          *vpos = line + 1;
>>>>>> +  else
>>>>>> +          /* inside vblank - negative */
>>>>>> +          *vpos = line - (vtotal - 1);
>>>>>> +
>>>>>> +  *hpos = 0;
>>>>>> +
>>>>>> +  reliable = true;
>>>>>> +
>>>>>> +  drm_dev_exit(idx);
>>>>>> +out:
>>>>>> +  if (etime)
>>>>>> +          *etime = ktime_get();
>>>>>> +
>>>>>> +  return reliable;
>>>>>> +}
>>>>>> +
>>>>>> +static const struct drm_crtc_helper_funcs dc_helper_funcs = {
>>>>>> +  .mode_valid             = dc_crtc_mode_valid,
>>>>>> +  .atomic_check           = dc_crtc_atomic_check,
>>>>>> +  .atomic_begin           = dc_crtc_atomic_begin,
>>>>>> +  .atomic_flush           = dc_crtc_atomic_flush,
>>>>>> +  .atomic_enable          = dc_crtc_atomic_enable,
>>>>>> +  .atomic_disable         = dc_crtc_atomic_disable,
>>>>>> +  .get_scanout_position   = dc_crtc_get_scanout_position,
>>>>>> +};
>>>>>> +
>>>>>> +static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
>>>>>> +{
>>>>>> +  struct {
>>>>>> +          struct device *dev;
>>>>>> +          unsigned int irq;
>>>>>> +          irqreturn_t (*irq_handler)(int irq, void *dev_id);
>>>>>> +  } irqs[DC_CRTC_IRQS] = {
>>>>>> +          {
>>>>>> +                  dc_crtc->de->dev,
>>>>>> +                  dc_crtc->irq_dec_framecomplete,
>>>>>> +                  dc_crtc_dec_framecomplete_irq_handler,
>>>>>> +          }, {
>>>>>> +                  dc_crtc->de->dev,
>>>>>> +                  dc_crtc->irq_dec_seqcomplete,
>>>>>> +                  dc_crtc_common_irq_handler,
>>>>>> +          }, {
>>>>>> +                  dc_crtc->de->dev,
>>>>>> +                  dc_crtc->irq_dec_shdld,
>>>>>> +                  dc_crtc_common_irq_handler,
>>>>>> +          }, {
>>>>>> +                  dc_crtc->ed_cont->dev,
>>>>>> +                  dc_crtc->irq_ed_cont_shdld,
>>>>>> +                  dc_crtc_common_irq_handler,
>>>>>> +          }, {
>>>>>> +                  dc_crtc->ed_safe->dev,
>>>>>> +                  dc_crtc->irq_ed_safe_shdld,
>>>>>> +                  dc_crtc_common_irq_handler,
>>>>>> +          },
>>>>>> +  };
>>>>>> +  int i, ret;
>>>>>> +
>>>>>> +  for (i = 0; i < DC_CRTC_IRQS; i++) {
>>>>>> +          struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
>>>>>> +
>>>>>> +          ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
>>>>>> +                                 irqs[i].irq_handler, IRQF_NO_AUTOEN,
>>>>>> +                                 dev_name(irqs[i].dev), dc_crtc);
>>>>>> +          if (ret) {
>>>>>> +                  dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
>>>>>> +                          irqs[i].irq, ret);
>>>>>> +                  return ret;
>>>>>> +          }
>>>>>> +
>>>>>> +          irq->dc_crtc = dc_crtc;
>>>>>> +          irq->irq = irqs[i].irq;
>>>>>> +  }
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
>>>>>> +  struct drm_device *drm = &dc_drm->base;
>>>>>> +  struct dc_de *de = dc_drm->de[crtc_index];
>>>>>> +  struct dc_pe *pe = dc_drm->pe;
>>>>>> +  struct dc_plane *dc_primary;
>>>>>> +  int ret;
>>>>>> +
>>>>>> +  dc_crtc->de = de;
>>>>>> +  dc_crtc->pe = pe;
>>>>>> +
>>>>>> +  init_completion(&dc_crtc->dec_seqcomplete_done);
>>>>>> +  init_completion(&dc_crtc->dec_shdld_done);
>>>>>> +  init_completion(&dc_crtc->ed_cont_shdld_done);
>>>>>> +  init_completion(&dc_crtc->ed_safe_shdld_done);
>>>>>> +
>>>>>> +  dc_crtc->cf_cont = pe->cf_cont[crtc_index];
>>>>>> +  dc_crtc->cf_safe = pe->cf_safe[crtc_index];
>>>>>> +  dc_crtc->ed_cont = pe->ed_cont[crtc_index];
>>>>>> +  dc_crtc->ed_safe = pe->ed_safe[crtc_index];
>>>>>> +  dc_crtc->fg = de->fg;
>>>>>> +
>>>>>> +  dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
>>>>>> +  dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
>>>>>> +  dc_crtc->irq_dec_shdld = de->irq_shdld;
>>>>>> +  dc_crtc->irq_ed_safe_shdld = dc_crtc->ed_safe->irq_shdld;
>>>>>> +  dc_crtc->irq_ed_cont_shdld = dc_crtc->ed_cont->irq_shdld;
>>>>>> +
>>>>>> +  dc_primary = &dc_drm->dc_primary[crtc_index];
>>>>>> +  ret = dc_plane_init(dc_drm, dc_primary);
>>>>>> +  if (ret) {
>>>>>> +          dev_err(drm->dev,
>>>>>> +                  "failed to init primary plane for display engine%u: %d\n",
>>>>>> +                  de->id, ret);
>>>>>> +          return ret;
>>>>>> +  }
>>>>>> +
>>>>>> +  drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
>>>>>> +
>>>>>> +  ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
>>>>>> +                                  NULL, &dc_crtc_funcs, NULL);
>>>>>> +  if (ret)
>>>>>> +          dev_err(drm->dev,
>>>>>> +                  "failed to add CRTC for display engine%u: %d\n",
>>>>>> +                  de->id, ret);
>>>>>> +
>>>>>> +  return ret;
>>>>>> +}
>>>>>> +
>>>>>> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
>>>>>> +  struct drm_device *drm = &dc_drm->base;
>>>>>> +
>>>>>> +  return dc_crtc_request_irqs(drm, dc_crtc);
>>>>>> +}
>>>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
>>>>>> index 17a44362118e..8a7b6c03a222 100644
>>>>>> --- a/drivers/gpu/drm/imx/dc/dc-de.h
>>>>>> +++ b/drivers/gpu/drm/imx/dc/dc-de.h
>>>>>> @@ -13,6 +13,9 @@
>>>>>>
>>>>>>  #define DC_DISPLAYS       2
>>>>>>
>>>>>> +#define DC_FRAMEGEN_MAX_FRAME_INDEX       0x3ffff
>>>>>> +#define DC_FRAMEGEN_MAX_CLOCK_KHZ 300000
>>>>>> +
>>>>>>  struct dc_fg {
>>>>>>    struct device *dev;
>>>>>>    struct regmap *reg;
>>>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
>>>>>> index fd68861f770a..1e4b8afa3eec 100644
>>>>>> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
>>>>>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
>>>>>> @@ -3,11 +3,254 @@
>>>>>>   * Copyright 2024 NXP
>>>>>>   */
>>>>>>
>>>>>> +#include <linux/clk.h>
>>>>>> +#include <linux/component.h>
>>>>>> +#include <linux/device.h>
>>>>>> +#include <linux/dma-mapping.h>
>>>>>> +#include <linux/mod_devicetable.h>
>>>>>>  #include <linux/module.h>
>>>>>> +#include <linux/of.h>
>>>>>> +#include <linux/of_platform.h>
>>>>>>  #include <linux/platform_device.h>
>>>>>> +#include <linux/pm.h>
>>>>>> +#include <linux/pm_runtime.h>
>>>>>>
>>>>>> +#include <drm/drm_atomic_helper.h>
>>>>>> +#include <drm/drm_client_setup.h>
>>>>>> +#include <drm/drm_crtc.h>
>>>>>> +#include <drm/drm_drv.h>
>>>>>> +#include <drm/drm_fbdev_dma.h>
>>>>>> +#include <drm/drm_fourcc.h>
>>>>>> +#include <drm/drm_gem_dma_helper.h>
>>>>>> +#include <drm/drm_managed.h>
>>>>>> +#include <drm/drm_modeset_helper.h>
>>>>>> +#include <drm/drm_of.h>
>>>>>> +
>>>>>> +#include "dc-de.h"
>>>>>>  #include "dc-drv.h"
>>>>>>
>>>>>> +struct dc_priv {
>>>>>> +  struct drm_device *drm;
>>>>>> +  struct clk *clk_cfg;
>>>>>> +};
>>>>>> +
>>>>>> +DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
>>>>>> +
>>>>>> +static struct drm_driver dc_drm_driver = {
>>>>>> +  .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
>>>>>> +  DRM_GEM_DMA_DRIVER_OPS,
>>>>>> +  DRM_FBDEV_DMA_DRIVER_OPS,
>>>>>> +  .fops = &dc_drm_driver_fops,
>>>>>> +  .name = "imx8-dc",
>>>>>> +  .desc = "i.MX8 DC DRM graphics",
>>>>>> +  .date = "20240530",
>>>>>> +  .major = 1,
>>>>>> +  .minor = 0,
>>>>>> +  .patchlevel = 0,
>>>>>> +};
>>>>>> +
>>>>>> +static void
>>>>>> +dc_add_components(struct device *dev, struct component_match **matchptr)
>>>>>> +{
>>>>>> +  struct device_node *child, *grandchild;
>>>>>> +
>>>>>> +  for_each_available_child_of_node(dev->of_node, child) {
>>>>>> +          /* The interrupt controller is not a component. */
>>>>>> +          if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
>>>>>> +                  continue;
>>>>>> +
>>>>>> +          drm_of_component_match_add(dev, matchptr, component_compare_of,
>>>>>> +                                     child);
>>>>>> +
>>>>>> +          for_each_available_child_of_node(child, grandchild)
>>>>>> +                  drm_of_component_match_add(dev, matchptr,
>>>>>> +                                             component_compare_of,
>>>>>> +                                             grandchild);
>>>>>> +  }
>>>>>> +}
>>>>>> +
>>>>>> +static void dc_drm_component_unbind_all(void *ptr)
>>>>>> +{
>>>>>> +  struct dc_drm_device *dc_drm = ptr;
>>>>>> +  struct drm_device *drm = &dc_drm->base;
>>>>>> +
>>>>>> +  component_unbind_all(drm->dev, dc_drm);
>>>>>> +}
>>>>>> +
>>>>>> +static int dc_drm_bind(struct device *dev)
>>>>>> +{
>>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
>>>>>> +  struct dc_drm_device *dc_drm;
>>>>>> +  struct drm_device *drm;
>>>>>> +  int ret;
>>>>>> +
>>>>>> +  dc_drm = devm_drm_dev_alloc(dev, &dc_drm_driver, struct dc_drm_device,
>>>>>> +                              base);
>>>>>> +  if (IS_ERR(dc_drm))
>>>>>> +          return PTR_ERR(dc_drm);
>>>>>> +
>>>>>> +  drm = &dc_drm->base;
>>>>>> +
>>>>>> +  ret = component_bind_all(dev, dc_drm);
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  ret = devm_add_action_or_reset(dev, dc_drm_component_unbind_all,
>>>>>> +                                 dc_drm);
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  ret = dc_kms_init(dc_drm);
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  ret = drm_dev_register(drm, 0);
>>>>>> +  if (ret) {
>>>>>> +          dev_err(dev, "failed to register drm device: %d\n", ret);
>>>>>> +          goto err;
>>>>>> +  }
>>>>>> +
>>>>>> +  drm_client_setup_with_fourcc(drm, DRM_FORMAT_XRGB8888);
>>>>>> +
>>>>>> +  priv->drm = drm;
>>>>>> +
>>>>>> +  return 0;
>>>>>> +
>>>>>> +err:
>>>>>> +  dc_kms_uninit(dc_drm);
>>>>>> +
>>>>>> +  return ret;
>>>>>> +}
>>>>>> +
>>>>>> +static void dc_drm_unbind(struct device *dev)
>>>>>> +{
>>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
>>>>>> +  struct dc_drm_device *dc_drm = to_dc_drm_device(priv->drm);
>>>>>> +  struct drm_device *drm = &dc_drm->base;
>>>>>> +  struct drm_crtc *crtc;
>>>>>> +
>>>>>> +  priv->drm = NULL;
>>>>>> +  drm_dev_unplug(drm);
>>>>>> +  dc_kms_uninit(dc_drm);
>>>>>> +  drm_atomic_helper_shutdown(drm);
>>>>>> +
>>>>>> +  drm_for_each_crtc(crtc, drm)
>>>>>> +          dc_crtc_disable_at_unbind(crtc);
>>>>>
>>>>> There should be no need for that. drm_atomic_helper_shutdown() should
>>>>> disable all the CRTCs.
>>>>
>>>> In case DRM device is unplugged, drm_atomic_helper_shutdown does not
>>>> effectively disable the CRTCs due to the bypassed logics wrapped by
>>>> drm_dev_{enter,exit}.  That's why dc_crtc_disable_at_unbind() is called
>>>> here to effectively disable the CRTCs.
>>>
>>> I see. I haven't faced drm_dev_unplug() earlier. I checked, the "not
>>> disabled" behaviour is documented and all other drivers don't perform
>>> any kind of cleanup afterwards. Thus I think it's safe to drop the
>>> dc_crtc_disable_at_unbind() unless it causes any kind of HW issues.
>>
>> IMHO, it's a bit safer to set the HWs backing the CRTCs to a known state
>> at the unbind stage by properly disabling them, in case there is any
>> unknown SW or HW issue.  Plus, i.MX8qm/qxp SoCs don't provide reset
>> signals to the Display Controllers(the resets DT property is optional),
>> otherwise, this disablement function can be dropped(at least for now).
> 
> I'd say, a rule of thumb is "Behave similarly" to the existing
> drivers. We've had a long-standing TODO item expressed in the DRM
> docs: the drm_dev_unplug() vs drm_atomic_helper_shutdown(). I think
> your issue should be solved in a generic way. One random idea would be
> to have a sepecial drm_dev_unplug() version which is intended for the
> normal shutdown path, it should mark the device as unavailable after
> disabling the outputs and unregistering it from userspace.

I'll drop dc_crtc_disable_at_unbind() in next version to "behave similarly"
to the existing drivers.

> 
>>
>>>
>>>>
>>>>>
>>>>> Also, who is going to do drm_dev_unregister()? I don't see it in the
>>>>> code.
>>>>
>>>> drm_dev_unplug() right above calls drm_dev_unregister().
>>>>
>>>>>
>>>>>> +}
>>>>>> +
>>>>>> +static const struct component_master_ops dc_drm_ops = {
>>>>>> +  .bind = dc_drm_bind,
>>>>>> +  .unbind = dc_drm_unbind,
>>>>>> +};
>>>>>> +
>>>>>> +static int dc_probe(struct platform_device *pdev)
>>>>>> +{
>>>>>> +  struct component_match *match = NULL;
>>>>>> +  struct dc_priv *priv;
>>>>>> +  int ret;
>>>>>> +
>>>>>> +  priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>>>>>> +  if (!priv)
>>>>>> +          return -ENOMEM;
>>>>>> +
>>>>>> +  priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
>>>>>> +  if (IS_ERR(priv->clk_cfg))
>>>>>> +          return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
>>>>>> +                               "failed to get cfg clock\n");
>>>>>> +
>>>>>> +  dev_set_drvdata(&pdev->dev, priv);
>>>>>> +
>>>>>> +  ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  ret = devm_pm_runtime_enable(&pdev->dev);
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  ret = devm_of_platform_populate(&pdev->dev);
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  dc_add_components(&pdev->dev, &match);
>>>>>> +
>>>>>> +  ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
>>>>>> +  if (ret)
>>>>>> +          return dev_err_probe(&pdev->dev, ret,
>>>>>> +                               "failed to add component master\n");
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static void dc_remove(struct platform_device *pdev)
>>>>>> +{
>>>>>> +  component_master_del(&pdev->dev, &dc_drm_ops);
>>>>>> +}
>>>>>> +
>>>>>> +static int dc_runtime_suspend(struct device *dev)
>>>>>> +{
>>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
>>>>>> +
>>>>>> +  clk_disable_unprepare(priv->clk_cfg);
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static int dc_runtime_resume(struct device *dev)
>>>>>> +{
>>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
>>>>>> +  int ret;
>>>>>> +
>>>>>> +  ret = clk_prepare_enable(priv->clk_cfg);
>>>>>> +  if (ret)
>>>>>> +          dev_err(dev, "failed to enable cfg clock: %d\n", ret);
>>>>>> +
>>>>>> +  return ret;
>>>>>> +}
>>>>>> +
>>>>>> +static int dc_suspend(struct device *dev)
>>>>>> +{
>>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
>>>>>> +
>>>>>> +  return drm_mode_config_helper_suspend(priv->drm);
>>>>>> +}
>>>>>> +
>>>>>> +static int dc_resume(struct device *dev)
>>>>>> +{
>>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
>>>>>> +
>>>>>> +  return drm_mode_config_helper_resume(priv->drm);
>>>>>> +}
>>>>>> +
>>>>>> +static void dc_shutdown(struct platform_device *pdev)
>>>>>> +{
>>>>>> +  struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
>>>>>> +
>>>>>> +  drm_atomic_helper_shutdown(priv->drm);
>>>>>> +}
>>>>>> +
>>>>>> +static const struct dev_pm_ops dc_pm_ops = {
>>>>>> +  RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
>>>>>> +  SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
>>>>>> +};
>>>>>> +
>>>>>> +static const struct of_device_id dc_dt_ids[] = {
>>>>>> +  { .compatible = "fsl,imx8qxp-dc", },
>>>>>> +  { /* sentinel */ }
>>>>>> +};
>>>>>> +MODULE_DEVICE_TABLE(of, dc_dt_ids);
>>>>>> +
>>>>>> +static struct platform_driver dc_driver = {
>>>>>> +  .probe = dc_probe,
>>>>>> +  .remove = dc_remove,
>>>>>> +  .shutdown = dc_shutdown,
>>>>>> +  .driver = {
>>>>>> +          .name = "imx8-dc",
>>>>>> +          .of_match_table = dc_dt_ids,
>>>>>> +          .pm = pm_sleep_ptr(&dc_pm_ops),
>>>>>> +  },
>>>>>> +};
>>>>>> +
>>>>>>  static struct platform_driver * const dc_drivers[] = {
>>>>>>    &dc_cf_driver,
>>>>>>    &dc_de_driver,
>>>>>> @@ -19,6 +262,7 @@ static struct platform_driver * const dc_drivers[] = {
>>>>>>    &dc_lb_driver,
>>>>>>    &dc_pe_driver,
>>>>>>    &dc_tc_driver,
>>>>>> +  &dc_driver,
>>>>>>  };
>>>>>>
>>>>>>  static int __init dc_drm_init(void)
>>>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
>>>>>> index 3b11f4862c6c..39a771a13933 100644
>>>>>> --- a/drivers/gpu/drm/imx/dc/dc-drv.h
>>>>>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.h
>>>>>> @@ -6,19 +6,38 @@
>>>>>>  #ifndef __DC_DRV_H__
>>>>>>  #define __DC_DRV_H__
>>>>>>
>>>>>> +#include <linux/container_of.h>
>>>>>>  #include <linux/platform_device.h>
>>>>>>
>>>>>>  #include <drm/drm_device.h>
>>>>>> +#include <drm/drm_encoder.h>
>>>>>>
>>>>>>  #include "dc-de.h"
>>>>>> +#include "dc-kms.h"
>>>>>>  #include "dc-pe.h"
>>>>>>
>>>>>>  struct dc_drm_device {
>>>>>>    struct drm_device base;
>>>>>> +  struct dc_crtc dc_crtc[DC_DISPLAYS];
>>>>>> +  struct dc_plane dc_primary[DC_DISPLAYS];
>>>>>> +  struct drm_encoder encoder[DC_DISPLAYS];
>>>>>>    struct dc_de *de[DC_DISPLAYS];
>>>>>>    struct dc_pe *pe;
>>>>>>  };
>>>>>>
>>>>>> +static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
>>>>>> +{
>>>>>> +  return container_of(drm, struct dc_drm_device, base);
>>>>>> +}
>>>>>> +
>>>>>> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
>>>>>> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
>>>>>> +
>>>>>> +int dc_kms_init(struct dc_drm_device *dc_drm);
>>>>>> +void dc_kms_uninit(struct dc_drm_device *dc_drm);
>>>>>> +
>>>>>> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
>>>>>> +
>>>>>>  extern struct platform_driver dc_cf_driver;
>>>>>>  extern struct platform_driver dc_ed_driver;
>>>>>>  extern struct platform_driver dc_de_driver;
>>>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
>>>>>> new file mode 100644
>>>>>> index 000000000000..2b18aa37a4a8
>>>>>> --- /dev/null
>>>>>> +++ b/drivers/gpu/drm/imx/dc/dc-kms.c
>>>>>> @@ -0,0 +1,143 @@
>>>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>>>> +/*
>>>>>> + * Copyright 2024 NXP
>>>>>> + */
>>>>>> +
>>>>>> +#include <linux/of.h>
>>>>>> +#include <linux/of_graph.h>
>>>>>> +
>>>>>> +#include <drm/drm_atomic_helper.h>
>>>>>> +#include <drm/drm_bridge.h>
>>>>>> +#include <drm/drm_bridge_connector.h>
>>>>>> +#include <drm/drm_connector.h>
>>>>>> +#include <drm/drm_crtc.h>
>>>>>> +#include <drm/drm_device.h>
>>>>>> +#include <drm/drm_encoder.h>
>>>>>> +#include <drm/drm_gem_framebuffer_helper.h>
>>>>>> +#include <drm/drm_mode_config.h>
>>>>>> +#include <drm/drm_print.h>
>>>>>> +#include <drm/drm_probe_helper.h>
>>>>>> +#include <drm/drm_simple_kms_helper.h>
>>>>>> +#include <drm/drm_vblank.h>
>>>>>> +
>>>>>> +#include "dc-de.h"
>>>>>> +#include "dc-drv.h"
>>>>>> +#include "dc-kms.h"
>>>>>> +
>>>>>> +static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
>>>>>> +  .fb_create = drm_gem_fb_create,
>>>>>> +  .atomic_check = drm_atomic_helper_check,
>>>>>> +  .atomic_commit = drm_atomic_helper_commit,
>>>>>> +};
>>>>>> +
>>>>>> +static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
>>>>>> +                                  int crtc_index)
>>>>>> +{
>>>>>> +  struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
>>>>>> +  struct drm_device *drm = &dc_drm->base;
>>>>>> +  struct drm_crtc *crtc = &dc_crtc->base;
>>>>>> +  struct drm_connector *connector;
>>>>>> +  struct device *dev = drm->dev;
>>>>>> +  struct drm_encoder *encoder;
>>>>>> +  struct drm_bridge *bridge;
>>>>>> +  int ret;
>>>>>> +
>>>>>> +  bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
>>>>>> +                                  0, 0);
>>>>>> +  if (IS_ERR(bridge)) {
>>>>>> +          ret = PTR_ERR(bridge);
>>>>>> +          if (ret == -ENODEV)
>>>>>> +                  return 0;
>>>>>> +
>>>>>> +          return dev_err_probe(dev, ret,
>>>>>> +                               "failed to find bridge for CRTC%u\n",
>>>>>> +                               crtc->index);
>>>>>> +  }
>>>>>> +
>>>>>> +  encoder = &dc_drm->encoder[crtc_index];
>>>>>> +  ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
>>>>>> +  if (ret) {
>>>>>> +          dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
>>>>>> +                  crtc->index, ret);
>>>>>> +          return ret;
>>>>>> +  }
>>>>>> +
>>>>>> +  encoder->possible_crtcs = drm_crtc_mask(crtc);
>>>>>> +
>>>>>> +  ret = drm_bridge_attach(encoder, bridge, NULL,
>>>>>> +                          DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>>> +  if (ret) {
>>>>>> +          dev_err(dev,
>>>>>> +                  "failed to attach bridge to encoder for CRTC%u: %d\n",
>>>>>> +                  crtc->index, ret);
>>>>>> +          return ret;
>>>>>> +  }
>>>>>> +
>>>>>> +  connector = drm_bridge_connector_init(drm, encoder);
>>>>>> +  if (IS_ERR(connector)) {
>>>>>> +          ret = PTR_ERR(connector);
>>>>>> +          dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
>>>>>> +                  crtc->index, ret);
>>>>>> +          return ret;
>>>>>> +  }
>>>>>> +
>>>>>> +  ret = drm_connector_attach_encoder(connector, encoder);
>>>>>> +  if (ret)
>>>>>> +          dev_err(dev,
>>>>>> +                  "failed to attach encoder to connector for CRTC%u: %d\n",
>>>>>> +                  crtc->index, ret);
>>>>>> +
>>>>>> +  return ret;
>>>>>> +}
>>>>>> +
>>>>>> +int dc_kms_init(struct dc_drm_device *dc_drm)
>>>>>> +{
>>>>>> +  struct drm_device *drm = &dc_drm->base;
>>>>>> +  int ret, i;
>>>>>> +
>>>>>> +  ret = drmm_mode_config_init(drm);
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  drm->mode_config.min_width = 60;
>>>>>> +  drm->mode_config.min_height = 60;
>>>>>> +  drm->mode_config.max_width = 8192;
>>>>>> +  drm->mode_config.max_height = 8192;
>>>>>> +  drm->mode_config.funcs = &dc_drm_mode_config_funcs;
>>>>>> +
>>>>>> +  drm->vblank_disable_immediate = true;
>>>>>> +  drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
>>>>>> +
>>>>>> +  for (i = 0; i < DC_DISPLAYS; i++) {
>>>>>> +          ret = dc_crtc_init(dc_drm, i);
>>>>>> +          if (ret)
>>>>>> +                  return ret;
>>>>>> +
>>>>>> +          ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
>>>>>> +          if (ret)
>>>>>> +                  return ret;
>>>>>> +  }
>>>>>> +
>>>>>> +  for (i = 0; i < DC_DISPLAYS; i++) {
>>>>>> +          ret = dc_crtc_post_init(dc_drm, i);
>>>>>
>>>>> Can you use .late_register for this?
>>>>
>>>> Kerneldoc of struct drm_crtc_funcs::late_register says it's used to register
>>>> additional userspace interfaces like debugfs interfaces. And, it seems that
>>>> everyone implementing this uses it to add debugfs interfaces. So, it will
>>>> kind of abuse it to do CRTC post initialization.
>>>
>>> Why can't they be requested earlier then?
>>
>> If I request them earlier in dc_crtc_init(), then they cannot be freed by
>> devm_irq_release() when devm_drm_of_get_bridge() called by
>> dc_kms_init_encoder_per_crtc() returns -EPROBE_DEFER(which means failing
>> to find the first DRM bridge for the CRTC).  Why can't they be freed by
>> devm_irq_release()?  Because they are requested by the devices of ExtDsts
>> and Display Engines and their drivers are not removed during the probe
>> deferral dance.  Furthermore, -EPROBE_DEFER won't be returned after
>> dc_crtc_post_init() since the later called drm_vblank_init() doesn't
>> return -EPROBE_DEFER anyway, so it's fine to call dc_crtc_post_init() here.
>>
>> I met the irq free issue on my i.MX8qxp MEK board before, i.e., -EBUSY is
>> returned when requesting them again, so it's tested.
> 
> A typical solution is to request all resources before binding the
> device as a component. Don't tell me that your interrupt controller is
> another component of the DRM device :-)

The IRQ handlers are _highly_ related to the CRTC driver(especially the
dc_crtc_dec_framecomplete_irq_handler() where vblank is handled), so maybe
it's more appropriate to request the IRQs and implement the IRQ handlers in
dc-crtc.c instead of doing them in dc-{de,ed}.c. No?

> 
>>
>>>
>>>>
>>>>>
>>>>>> +          if (ret)
>>>>>> +                  return ret;
>>>>>> +  }
>>>>>> +
>>>>>> +  ret = drm_vblank_init(drm, DC_DISPLAYS);
>>>>>> +  if (ret) {
>>>>>> +          dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
>>>>>> +          return ret;
>>>>>> +  }
>>>>>> +
>>>>>> +  drm_mode_config_reset(drm);
>>>>>> +
>>>>>> +  drm_kms_helper_poll_init(drm);
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>> +void dc_kms_uninit(struct dc_drm_device *dc_drm)
>>>>>> +{
>>>>>> +  drm_kms_helper_poll_fini(&dc_drm->base);
>>>>>> +}
>>>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
>>>>>> new file mode 100644
>>>>>> index 000000000000..57f6e0c15f57
>>>>>> --- /dev/null
>>>>>> +++ b/drivers/gpu/drm/imx/dc/dc-kms.h
>>>>>> @@ -0,0 +1,58 @@
>>>>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>>>>> +/*
>>>>>> + * Copyright 2024 NXP
>>>>>> + */
>>>>>> +
>>>>>> +#ifndef __DC_KMS_H__
>>>>>> +#define __DC_KMS_H__
>>>>>> +
>>>>>> +#include <linux/completion.h>
>>>>>> +
>>>>>> +#include <drm/drm_crtc.h>
>>>>>> +#include <drm/drm_plane.h>
>>>>>> +#include <drm/drm_vblank.h>
>>>>>> +
>>>>>> +#include "dc-de.h"
>>>>>> +#include "dc-fu.h"
>>>>>> +#include "dc-pe.h"
>>>>>> +
>>>>>> +#define DC_CRTC_IRQS      5
>>>>>> +
>>>>>> +struct dc_crtc_irq {
>>>>>> +  struct dc_crtc *dc_crtc;
>>>>>> +  unsigned int irq;
>>>>>> +};
>>>>>> +
>>>>>
>>>>> Please provide some documentation for the structure in the form of the
>>>>> kerneldoc. E.g. what is the difference between ed_cont and ed_safe?
>>>>
>>>> Will add kerneldoc for struct dc_{crtc,plane,drm_device} and tell the
>>>> difference between ed_cont(content stream) and ed_safe(safety stream).
>>>>
>>>>> The de and fg pointers are global, please don't cache them
>>>>> unnecessarily.
>>>>
>>>> Global? I don't catch your meaning, sorry. To me, it's handy to access de
>>>> and fg via the two pointers in struct dc_crtc.
>>>
>>> I had to spend some time understanding if they are per-CRTC or if there
>>> are a single instances of those subdevices. Thus I suggest to access
>>
>> They are per-CRTC.  One Display Controller contains two Display Engines,
>> hence two CRTCs.
> 
> I'm sorry, I probably meant PE here. DE (and consequently FG) are
> per-CRTC indeed.

Alright, I'll drop PE from struct dc_crtc and access it via
struct dc_drm_device in next version.

> 
>>
>>> them through dc_drm_device. You can ignore this suggestion though.
>>
>> I'll ignore this.  Thanks anyway.
>>
>>>
>>>>
>>>>>
>>>>>> +struct dc_crtc {
>>>>>> +  struct drm_crtc base;
>>>>>> +  struct dc_de *de;
>>>>>> +  struct dc_pe *pe;
>>>>>> +  struct dc_cf *cf_cont;
>>>>>> +  struct dc_cf *cf_safe;
>>>>>> +  struct dc_ed *ed_cont;
>>>>>> +  struct dc_ed *ed_safe;
>>>>>> +  struct dc_fg *fg;
>>>>>> +  unsigned int irq_dec_framecomplete;
>>>>>> +  unsigned int irq_dec_seqcomplete;
>>>>>> +  unsigned int irq_dec_shdld;
>>>>>> +  unsigned int irq_ed_cont_shdld;
>>>>>> +  unsigned int irq_ed_safe_shdld;
>>>>>> +  struct completion dec_seqcomplete_done;
>>>>>> +  struct completion dec_shdld_done;
>>>>>> +  struct completion ed_safe_shdld_done;
>>>>>> +  struct completion ed_cont_shdld_done;
>>>>>> +  struct drm_pending_vblank_event *event;
>>>>>> +  struct dc_crtc_irq irqs[DC_CRTC_IRQS];
>>>>>> +};
>>>>>> +
>>>>>> +struct dc_plane {
>>>>>> +  struct drm_plane base;
>>>>>> +  struct dc_fu *fu;
>>>>>> +  struct dc_cf *cf;
>>>>>> +  struct dc_lb *lb;
>>>>>> +  struct dc_ed *ed;
>>>>>> +};
>>>>>> +
>>>>>> +void dc_crtc_disable_at_unbind(struct drm_crtc *crtc);
>>>>>> +
>>>>>> +#endif /* __DC_KMS_H__ */
>>>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
>>>>>> new file mode 100644
>>>>>> index 000000000000..78d0d2cd3451
>>>>>> --- /dev/null
>>>>>> +++ b/drivers/gpu/drm/imx/dc/dc-plane.c
>>>>>> @@ -0,0 +1,241 @@
>>>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>>>> +/*
>>>>>> + * Copyright 2024 NXP
>>>>>> + */
>>>>>> +
>>>>>> +#include <linux/container_of.h>
>>>>>> +
>>>>>> +#include <drm/drm_atomic.h>
>>>>>> +#include <drm/drm_atomic_helper.h>
>>>>>> +#include <drm/drm_atomic_state_helper.h>
>>>>>> +#include <drm/drm_crtc.h>
>>>>>> +#include <drm/drm_drv.h>
>>>>>> +#include <drm/drm_fb_dma_helper.h>
>>>>>> +#include <drm/drm_fourcc.h>
>>>>>> +#include <drm/drm_framebuffer.h>
>>>>>> +#include <drm/drm_gem_atomic_helper.h>
>>>>>> +#include <drm/drm_plane_helper.h>
>>>>>> +#include <drm/drm_print.h>
>>>>>> +
>>>>>> +#include "dc-drv.h"
>>>>>> +#include "dc-fu.h"
>>>>>> +#include "dc-kms.h"
>>>>>> +
>>>>>> +#define DC_PLANE_MAX_PITCH        0x10000
>>>>>> +#define DC_PLANE_MAX_PIX_CNT      8192
>>>>>> +
>>>>>> +#define dc_plane_dbg(plane, fmt, ...)                                     \
>>>>>> +do {                                                                      \
>>>>>> +  typeof(plane) _plane = (plane);                                 \
>>>>>> +  drm_dbg_kms(_plane->dev, "[PLANE:%d:%s] " fmt,                  \
>>>>>> +              _plane->base.id, _plane->name, ##__VA_ARGS__);      \
>>>>>> +} while (0)
>>>>>> +
>>>>>> +static const uint32_t dc_plane_formats[] = {
>>>>>> +  DRM_FORMAT_XRGB8888,
>>>>>> +};
>>>>>> +
>>>>>> +static const struct drm_plane_funcs dc_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,
>>>>>> +};
>>>>>> +
>>>>>> +static inline struct dc_plane *to_dc_plane(struct drm_plane *plane)
>>>>>> +{
>>>>>> +  return container_of(plane, struct dc_plane, base);
>>>>>> +}
>>>>>> +
>>>>>> +static int dc_plane_check_no_off_screen(struct drm_plane_state *state,
>>>>>> +                                  struct drm_crtc_state *crtc_state)
>>>>>> +{
>>>>>> +  if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
>>>>>> +      state->dst.x2 > crtc_state->adjusted_mode.hdisplay ||
>>>>>> +      state->dst.y2 > crtc_state->adjusted_mode.vdisplay) {
>>>>>> +          dc_plane_dbg(state->plane, "no off screen\n");
>>>>>> +          return -EINVAL;
>>>>>> +  }
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static int dc_plane_check_max_source_resolution(struct drm_plane_state *state)
>>>>>> +{
>>>>>> +  int src_h = drm_rect_height(&state->src) >> 16;
>>>>>> +  int src_w = drm_rect_width(&state->src) >> 16;
>>>>>> +
>>>>>> +  if (src_w > DC_PLANE_MAX_PIX_CNT || src_h > DC_PLANE_MAX_PIX_CNT) {
>>>>>> +          dc_plane_dbg(state->plane, "invalid source resolution\n");
>>>>>> +          return -EINVAL;
>>>>>> +  }
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static int dc_plane_check_fb(struct drm_plane_state *state)
>>>>>> +{
>>>>>> +  struct drm_framebuffer *fb = state->fb;
>>>>>> +  dma_addr_t baseaddr = drm_fb_dma_get_gem_addr(fb, state, 0);
>>>>>> +
>>>>>> +  /* base address alignment */
>>>>>> +  if (baseaddr & 0x3) {
>>>>>> +          dc_plane_dbg(state->plane, "fb bad baddr alignment\n");
>>>>>> +          return -EINVAL;
>>>>>> +  }
>>>>>> +
>>>>>> +  /* pitches[0] range */
>>>>>> +  if (fb->pitches[0] > DC_PLANE_MAX_PITCH) {
>>>>>> +          dc_plane_dbg(state->plane, "fb pitches[0] is out of range\n");
>>>>>> +          return -EINVAL;
>>>>>> +  }
>>>>>> +
>>>>>> +  /* pitches[0] alignment */
>>>>>> +  if (fb->pitches[0] & 0x3) {
>>>>>> +          dc_plane_dbg(state->plane, "fb bad pitches[0] alignment\n");
>>>>>> +          return -EINVAL;
>>>>>> +  }
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static int
>>>>>> +dc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
>>>>>> +{
>>>>>> +  struct drm_plane_state *plane_state =
>>>>>> +                          drm_atomic_get_new_plane_state(state, plane);
>>>>>> +  struct drm_crtc_state *crtc_state;
>>>>>> +  int ret;
>>>>>> +
>>>>>> +  /* ok to disable */
>>>>>> +  if (!plane_state->fb)
>>>>>> +          return 0;
>>>>>> +
>>>>>> +  if (!plane_state->crtc) {
>>>>>> +          dc_plane_dbg(plane, "no CRTC in plane state\n");
>>>>>> +          return -EINVAL;
>>>>>> +  }
>>>>>> +
>>>>>> +  crtc_state =
>>>>>> +          drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
>>>>>> +  if (WARN_ON(!crtc_state))
>>>>>> +          return -EINVAL;
>>>>>> +
>>>>>> +  ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
>>>>>> +                                            DRM_PLANE_NO_SCALING,
>>>>>> +                                            DRM_PLANE_NO_SCALING,
>>>>>> +                                            true, false);
>>>>>> +  if (ret) {
>>>>>> +          dc_plane_dbg(plane, "failed to check plane state: %d\n", ret);
>>>>>> +          return ret;
>>>>>> +  }
>>>>>> +
>>>>>> +  ret = dc_plane_check_no_off_screen(plane_state, crtc_state);
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  ret = dc_plane_check_max_source_resolution(plane_state);
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  return dc_plane_check_fb(plane_state);
>>>>>> +}
>>>>>> +
>>>>>> +static void
>>>>>> +dc_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state)
>>>>>> +{
>>>>>> +  struct drm_plane_state *new_state =
>>>>>> +                          drm_atomic_get_new_plane_state(state, plane);
>>>>>> +  struct dc_plane *dplane = to_dc_plane(plane);
>>>>>> +  struct drm_framebuffer *fb = new_state->fb;
>>>>>> +  const struct dc_fu_ops *fu_ops;
>>>>>> +  struct dc_lb *lb = dplane->lb;
>>>>>> +  struct dc_fu *fu = dplane->fu;
>>>>>> +  dma_addr_t baseaddr;
>>>>>> +  int src_w, src_h;
>>>>>> +  int idx;
>>>>>> +
>>>>>> +  if (!drm_dev_enter(plane->dev, &idx))
>>>>>> +          return;
>>>>>> +
>>>>>> +  src_w = drm_rect_width(&new_state->src) >> 16;
>>>>>> +  src_h = drm_rect_height(&new_state->src) >> 16;
>>>>>> +
>>>>>> +  baseaddr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
>>>>>> +
>>>>>> +  fu_ops = dc_fu_get_ops(dplane->fu);
>>>>>> +
>>>>>> +  fu_ops->set_layerblend(fu, lb);
>>>>>> +  fu_ops->set_burstlength(fu, baseaddr);
>>>>>> +  fu_ops->set_src_stride(fu, DC_FETCHUNIT_FRAC0, fb->pitches[0]);
>>>>>> +  fu_ops->set_src_buf_dimensions(fu, DC_FETCHUNIT_FRAC0, src_w, src_h);
>>>>>> +  fu_ops->set_fmt(fu, DC_FETCHUNIT_FRAC0, fb->format);
>>>>>> +  fu_ops->set_framedimensions(fu, src_w, src_h);
>>>>>> +  fu_ops->set_baseaddress(fu, DC_FETCHUNIT_FRAC0, baseaddr);
>>>>>> +  fu_ops->enable_src_buf(fu, DC_FETCHUNIT_FRAC0);
>>>>>> +
>>>>>> +  dc_plane_dbg(plane, "uses %s\n", fu_ops->get_name(fu));
>>>>>> +
>>>>>> +  dc_lb_pec_dynamic_prim_sel(lb, dc_cf_get_link_id(dplane->cf));
>>>>>> +  dc_lb_pec_dynamic_sec_sel(lb, fu_ops->get_link_id(fu));
>>>>>> +  dc_lb_mode(lb, LB_BLEND);
>>>>>> +  dc_lb_position(lb, new_state->dst.x1, new_state->dst.y1);
>>>>>> +  dc_lb_pec_clken(lb, CLKEN_AUTOMATIC);
>>>>>> +
>>>>>> +  dc_plane_dbg(plane, "uses LayerBlend%u\n", dc_lb_get_id(lb));
>>>>>> +
>>>>>> +  /* set ExtDst's source to LayerBlend */
>>>>>> +  dc_ed_pec_src_sel(dplane->ed, dc_lb_get_link_id(lb));
>>>>>> +
>>>>>> +  drm_dev_exit(idx);
>>>>>> +}
>>>>>> +
>>>>>> +static void dc_plane_atomic_disable(struct drm_plane *plane,
>>>>>> +                              struct drm_atomic_state *state)
>>>>>> +{
>>>>>> +  struct dc_plane *dplane = to_dc_plane(plane);
>>>>>> +  const struct dc_fu_ops *fu_ops;
>>>>>> +  int idx;
>>>>>> +
>>>>>> +  if (!drm_dev_enter(plane->dev, &idx))
>>>>>> +          return;
>>>>>> +
>>>>>> +  /* disable fetchunit in shadow */
>>>>>> +  fu_ops = dc_fu_get_ops(dplane->fu);
>>>>>> +  fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
>>>>>> +
>>>>>> +  /* set ExtDst's source to ConstFrame */
>>>>>> +  dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
>>>>>> +
>>>>>> +  drm_dev_exit(idx);
>>>>>> +}
>>>>>> +
>>>>>> +static const struct drm_plane_helper_funcs dc_plane_helper_funcs = {
>>>>>> +  .atomic_check = dc_plane_atomic_check,
>>>>>> +  .atomic_update = dc_plane_atomic_update,
>>>>>> +  .atomic_disable = dc_plane_atomic_disable,
>>>>>> +};
>>>>>> +
>>>>>> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
>>>>>> +{
>>>>>> +  struct drm_plane *plane = &dc_plane->base;
>>>>>> +  int ret;
>>>>>> +
>>>>>> +  ret = drm_universal_plane_init(&dc_drm->base, plane, 0, &dc_plane_funcs,
>>>>>> +                                 dc_plane_formats,
>>>>>> +                                 ARRAY_SIZE(dc_plane_formats),
>>>>>> +                                 NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
>>>>>> +  if (ret)
>>>>>> +          return ret;
>>>>>> +
>>>>>> +  drm_plane_helper_add(plane, &dc_plane_helper_funcs);
>>>>>> +
>>>>>> +  dc_plane->fu = dc_drm->pe->fu_disp[plane->index];
>>>>>> +  dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
>>>>>> +  dc_plane->lb = dc_drm->pe->lb[plane->index];
>>>>>> +  dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> --
>>>>>> 2.34.1
>>>>>>
>>>>>
>>>>
>>>> --
>>>> Regards,
>>>> Liu Ying
>>>
>>
>> --
>> Regards,
>> Liu Ying
> 
> 
> 

-- 
Regards,
Liu Ying


From sumitg at nvidia.com  Sun Dec 15 23:11:04 2024
From: sumitg at nvidia.com (Sumit Gupta)
Date: Mon, 16 Dec 2024 12:41:04 +0530
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <3f19c5a8-9ee6-42fe-8b4c-3a66c65c8d35@nvidia.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
 <3f19c5a8-9ee6-42fe-8b4c-3a66c65c8d35@nvidia.com>
Message-ID: <955a7947-3053-490e-a803-d55699dddd0c@nvidia.com>



On 16/12/24 11:13, Kai-Heng Feng wrote:
> Hi Beata,
> 
> On 2024/12/6 9:55 PM, Beata Michalska wrote:
>> Currently the CPUFreq core exposes two sysfs attributes that can be used
>> to query current frequency of a given CPU(s): namely cpuinfo_cur_freq
>> and scaling_cur_freq. Both provide slightly different view on the
>> subject and they do come with their own drawbacks.
>>
>> cpuinfo_cur_freq provides higher precision though at a cost of being
>> rather expensive. Moreover, the information retrieved via this attribute
>> is somewhat short lived as frequency can change at any point of time
>> making it difficult to reason from.
>>
>> scaling_cur_freq, on the other hand, tends to be less accurate but then
>> the actual level of precision (and source of information) varies between
>> architectures making it a bit ambiguous.
>>
>> The new attribute, cpuinfo_avg_freq, is intended to provide more stable,
>> distinct interface, exposing an average frequency of a given CPU(s), as
>> reported by the hardware, over a time frame spanning no more than a few
>> milliseconds. As it requires appropriate hardware support, this
>> interface is optional.
>>
>> Note that under the hood, the new attribute relies on the information
>> provided by arch_freq_get_on_cpu, which, up to this point, has been
>> feeding data for scaling_cur_freq attribute, being the source of
>> ambiguity when it comes to interpretation. This has been amended by
>> restoring the intended behavior for scaling_cur_freq, with a new
>> dedicated config option to maintain status quo for those, who may need
>> it.
>>
>> CC: Jonathan Corbet <corbet at lwn.net>
>> CC: Thomas Gleixner <tglx at linutronix.de>
>> CC: Ingo Molnar <mingo at redhat.com>
>> CC: Borislav Petkov <bp at alien8.de>
>> CC: Dave Hansen <dave.hansen at linux.intel.com>
>> CC: H. Peter Anvin <hpa at zytor.com>
>> CC: Phil Auld <pauld at redhat.com>
>> CC: x86 at kernel.org
>> CC: linux-doc at vger.kernel.org
>> Signed-off-by: Beata Michalska <beata.michalska at arm.com>
>> ---
>> ? Documentation/admin-guide/pm/cpufreq.rst | 16 ++++++++++-
>> ? arch/x86/kernel/cpu/aperfmperf.c???????? |? 2 +-
>> ? arch/x86/kernel/cpu/proc.c?????????????? |? 7 +++--
>> ? drivers/cpufreq/Kconfig.x86????????????? | 12 ++++++++
>> ? drivers/cpufreq/cpufreq.c??????????????? | 36 +++++++++++++++++++++---
>> ? include/linux/cpufreq.h????????????????? |? 2 +-
>> ? 6 files changed, 66 insertions(+), 9 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/pm/cpufreq.rst 
>> b/Documentation/admin-guide/pm/cpufreq.rst
>> index fe1be4ad88cb..76f3835afe01 100644
>> --- a/Documentation/admin-guide/pm/cpufreq.rst
>> +++ b/Documentation/admin-guide/pm/cpufreq.rst
>> @@ -248,6 +248,19 @@ are the following:
>> ????? If that frequency cannot be determined, this attribute should not
>> ????? be present.
>> +``cpuinfo_avg_freq``
>> +??????? An average frequency (in KHz) of all CPUs belonging to a 
>> given policy,
>> +??????? derived from a hardware provided feedback and reported on a 
>> time frame
>> +??????? spanning at most few milliseconds.
>> +
>> +??????? This is expected to be based on the frequency the hardware 
>> actually runs
>> +??????? at and, as such, might require specialised hardware support 
>> (such as AMU
>> +??????? extension on ARM). If one cannot be determined, this 
>> attribute should
>> +??????? not be present.
>> +
>> +??????? Note, that failed attempt to retrieve current frequency for a 
>> given
>> +??????? CPU(s) will result in an appropriate error.
>> +
>> ? ``cpuinfo_max_freq``
>> ????? Maximum possible operating frequency the CPUs belonging to this 
>> policy
>> ????? can run at (in kHz).
>> @@ -293,7 +306,8 @@ are the following:
>> ????? Some architectures (e.g. ``x86``) may attempt to provide 
>> information
>> ????? more precisely reflecting the current CPU frequency through this
>> ????? attribute, but that still may not be the exact current CPU 
>> frequency as
>> -??? seen by the hardware at the moment.
>> +??? seen by the hardware at the moment. This behavior though, is only
>> +??? available via c:macro:``CPUFREQ_ARCH_CUR_FREQ`` option.
>> ? ``scaling_driver``
>> ????? The scaling driver currently in use.
>> diff --git a/arch/x86/kernel/cpu/aperfmperf.c 
>> b/arch/x86/kernel/cpu/aperfmperf.c
>> index 0b69bfbf345d..a00059139ca4 100644
>> --- a/arch/x86/kernel/cpu/aperfmperf.c
>> +++ b/arch/x86/kernel/cpu/aperfmperf.c
>> @@ -413,7 +413,7 @@ void arch_scale_freq_tick(void)
>> ?? */
>> ? #define MAX_SAMPLE_AGE??? ((unsigned long)HZ / 50)
>> -unsigned int arch_freq_get_on_cpu(int cpu)
>> +int arch_freq_get_on_cpu(int cpu)
>> ? {
>> ????? struct aperfmperf *s = per_cpu_ptr(&cpu_samples, cpu);
>> ????? unsigned int seq, freq;
>> diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
>> index e65fae63660e..34d8fb93fb70 100644
>> --- a/arch/x86/kernel/cpu/proc.c
>> +++ b/arch/x86/kernel/cpu/proc.c
>> @@ -86,9 +86,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
>> ????????? seq_printf(m, "microcode\t: 0x%x\n", c->microcode);
>> ????? if (cpu_has(c, X86_FEATURE_TSC)) {
>> -??????? unsigned int freq = arch_freq_get_on_cpu(cpu);
>> +??????? int freq = arch_freq_get_on_cpu(cpu);
>> -??????? seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 
>> 1000));
>> +??????? if (freq <= 0)
>> +??????????? seq_puts(m, "cpu MHz\t\t: Unknown\n");
>> +??????? else
>> +??????????? seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, 
>> (freq % 1000));
>> ????? }
>> ????? /* Cache size */
>> diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
>> index 97c2d4f15d76..212e1b9afe21 100644
>> --- a/drivers/cpufreq/Kconfig.x86
>> +++ b/drivers/cpufreq/Kconfig.x86
>> @@ -340,3 +340,15 @@ config X86_SPEEDSTEP_RELAXED_CAP_CHECK
>> ??????? option lets the probing code bypass some of those checks if the
>> ??????? parameter "relaxed_check=1" is passed to the module.
>> +config CPUFREQ_ARCH_CUR_FREQ
>> +??? default y
>> +??? bool "Current frequency derived from HW provided feedback"
>> +??? help
>> +????? This determines whether the scaling_cur_freq sysfs attribute 
>> returns
>> +????? the last requested frequency or a more precise value based on 
>> hardware
>> +????? provided feedback (as architected counters).
>> +????? Given that a more precise frequency can now be provided via the
>> +????? cpuinfo_avg_cur_freq attribute, by enabling this option,
>> +????? scaling_cur_freq maintains the provision of a counter based 
>> frequency,
>> +????? for compatibility reasons.
>> +
>> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
>> index 04fc786dd2c0..70df2a24437b 100644
>> --- a/drivers/cpufreq/cpufreq.c
>> +++ b/drivers/cpufreq/cpufreq.c
>> @@ -747,9 +747,14 @@ show_one(cpuinfo_transition_latency, 
>> cpuinfo.transition_latency);
>> ? show_one(scaling_min_freq, min);
>> ? show_one(scaling_max_freq, max);
>> -__weak unsigned int arch_freq_get_on_cpu(int cpu)
>> +__weak int arch_freq_get_on_cpu(int cpu)
>> ? {
>> -??? return 0;
>> +??? return -EOPNOTSUPP;
>> +}
>> +
>> +static inline bool cpufreq_avg_freq_supported(struct cpufreq_policy 
>> *policy)
>> +{
>> +??? return arch_freq_get_on_cpu(policy->cpu) != -EOPNOTSUPP;
>> ? }
>> ? static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, 
>> char *buf)
>> @@ -757,8 +762,11 @@ static ssize_t show_scaling_cur_freq(struct 
>> cpufreq_policy *policy, char *buf)
>> ????? ssize_t ret;
>> ????? unsigned int freq;
>> -??? freq = arch_freq_get_on_cpu(policy->cpu);
>> -??? if (freq)
>> +??? freq = IS_ENABLED(CONFIG_CPUFREQ_ARCH_CUR_FREQ)
>> +??????? ? arch_freq_get_on_cpu(policy->cpu)
>> +??????? : 0;
>> +
>> +??? if (freq > 0)
>> ????????? ret = sysfs_emit(buf, "%u\n", freq);
>> ????? else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
>> ????????? ret = sysfs_emit(buf, "%u\n", 
>> cpufreq_driver->get(policy->cpu));
>> @@ -802,6 +810,19 @@ static ssize_t show_cpuinfo_cur_freq(struct 
>> cpufreq_policy *policy,
>> ????? return sysfs_emit(buf, "<unknown>\n");
>> ? }
>> +/*
>> + * show_cpuinfo_avg_freq - average CPU frequency as detected by hardware
>> + */
>> +static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
>> +???????????????????? char *buf)
>> +{
>> +??? int avg_freq = arch_freq_get_on_cpu(policy->cpu);
> 
> We are seeing issues when reading cpuinfo_avg_freq on an ARM64 system:
> 
> $ cat /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq
> cat: /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq: Resource 
> temporarily unavailable
> 
> The CPU is in idle state, so arch_freq_get_on_cpu() can't find a good 
> alternative source for frequency info.
> 

Hi Kai Heng,
This has already been discussed during v7 in [1] & [2].
In v7, we were returning zero which printed 'unknown'.
The discussion was about printing in more descriptive way or with an 
appropriate error code. In v8 we are returning 'EAGAIN' instead of zero. 
The final decision was of Maintainers.

Viresh,
You have any preference on this?

[1] 
https://lore.kernel.org/lkml/aa254516-968e-4665-bb5b-981c296ffc35 at nvidia.com/#t
[2] https://lore.kernel.org/lkml/Zyh-uVSW-0d0r8oB at arm.com/

Thank you,
Sumit Gupta

> One way to resolve this is to have fallback methods in 
> show_cpuinfo_avg_freq() so it will look like this:
> 
> static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
>  ???????????????????????????????????? char *buf)
> {
>  ??????? int avg_freq = arch_freq_get_on_cpu(policy->cpu);
>  ??????? int ret;
> 
>  ??????? if (avg_freq > 0)
>  ??????????????? ret = sysfs_emit(buf, "%u\n", avg_freq);
>  ??????? else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
>  ??????????????? ret = sysfs_emit(buf, "%u\n", 
> cpufreq_driver->get(policy->cpu));
>  ??????? else
>  ??????????????? ret = sysfs_emit(buf, "%u\n", policy->cur);
>  ??????? return ret;
> }
> 
> But that also makes show_cpuinfo_avg_freq() pretty much the same as 
> show_scaling_cur_freq().
> 
> So is it possible to consolidate show_cpuinfo_avg_freq() into 
> show_scaling_cur_freq(), by making CONFIG_CPUFREQ_ARCH_CUR_FREQ also 
> available to ARM64?
> 
> Kai-Heng
> 
>> +
>> +??? if (avg_freq > 0)
>> +??????? return sysfs_emit(buf, "%u\n", avg_freq);
>> +??? return avg_freq != 0 ? avg_freq : -EINVAL;
>> +}
>> +
>> ? /*
>> ?? * show_scaling_governor - show the current policy for the specified 
>> CPU
>> ?? */
>> @@ -964,6 +985,7 @@ static ssize_t show_bios_limit(struct 
>> cpufreq_policy *policy, char *buf)
>> ? }
>> ? cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
>> +cpufreq_freq_attr_ro(cpuinfo_avg_freq);
>> ? cpufreq_freq_attr_ro(cpuinfo_min_freq);
>> ? cpufreq_freq_attr_ro(cpuinfo_max_freq);
>> ? cpufreq_freq_attr_ro(cpuinfo_transition_latency);
>> @@ -1091,6 +1113,12 @@ static int cpufreq_add_dev_interface(struct 
>> cpufreq_policy *policy)
>> ????????????? return ret;
>> ????? }
>> +??? if (cpufreq_avg_freq_supported(policy)) {
>> +??????? ret = sysfs_create_file(&policy->kobj, &cpuinfo_avg_freq.attr);
>> +??????? if (ret)
>> +??????????? return ret;
>> +??? }
>> +
>> ????? ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
>> ????? if (ret)
>> ????????? return ret;
>> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
>> index d4d2f4d1d7cb..a7b6c0ccf9bc 100644
>> --- a/include/linux/cpufreq.h
>> +++ b/include/linux/cpufreq.h
>> @@ -1194,7 +1194,7 @@ static inline int 
>> of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_
>> ? }
>> ? #endif
>> -extern unsigned int arch_freq_get_on_cpu(int cpu);
>> +extern int arch_freq_get_on_cpu(int cpu);
>> ? #ifndef arch_set_freq_scale
>> ? static __always_inline
> 


From michal.simek at amd.com  Sun Dec 15 23:16:05 2024
From: michal.simek at amd.com (Michal Simek)
Date: Mon, 16 Dec 2024 08:16:05 +0100
Subject: [PATCH v2] mailbox: zynqmp: Remove invalid __percpu annotation in
 zynqmp_ipi_probe()
In-Reply-To: <20241214091327.4716-1-ubizjak@gmail.com>
References: <20241214091327.4716-1-ubizjak@gmail.com>
Message-ID: <25eb1e35-83b0-46f4-9a9c-138c89665e05@amd.com>



On 12/14/24 10:12, Uros Bizjak wrote:
> struct zynqmp_ipi_pdata __percpu *pdata is not a per-cpu variable,
> so it should not be annotated with __percpu annotation.
> 
> Remove invalid __percpu annotation to fix several
> 
> zynqmp-ipi-mailbox.c:920:15: warning: incorrect type in assignment (different address spaces)
> zynqmp-ipi-mailbox.c:920:15:    expected struct zynqmp_ipi_pdata [noderef] __percpu *pdata
> zynqmp-ipi-mailbox.c:920:15:    got void *
> zynqmp-ipi-mailbox.c:927:56: warning: incorrect type in argument 3 (different address spaces)
> zynqmp-ipi-mailbox.c:927:56:    expected unsigned int [usertype] *out_value
> zynqmp-ipi-mailbox.c:927:56:    got unsigned int [noderef] __percpu *
> ...
> 
> and several
> 
> drivers/mailbox/zynqmp-ipi-mailbox.c:924:9: warning: dereference of noderef expression
> ...
> 
> sparse warnings.
> 
> There were no changes in the resulting object file.
> 
> Cc: stable at vger.kernel.org
> Fixes: 6ffb1635341b ("mailbox: zynqmp: handle SGI for shared IPI")
> Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
> Cc: Jassi Brar <jassisinghbrar at gmail.com>
> Cc: Michal Simek <michal.simek at amd.com>
> Cc: Tanmay Shah <tanmay.shah at amd.com>
> ---
> v2: - Fix typo in commit message
>      - Add Fixes and Cc: stable.
> ---
>   drivers/mailbox/zynqmp-ipi-mailbox.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
> index aa5249da59b2..0c143beaafda 100644
> --- a/drivers/mailbox/zynqmp-ipi-mailbox.c
> +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
> @@ -905,7 +905,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
>   	struct device_node *nc, *np = pdev->dev.of_node;
> -	struct zynqmp_ipi_pdata __percpu *pdata;
> +	struct zynqmp_ipi_pdata *pdata;
>   	struct of_phandle_args out_irq;
>   	struct zynqmp_ipi_mbox *mbox;
>   	int num_mboxes, ret = -EINVAL;

Tanmay: Please take a look

I think this patch is correct. Pdata structure is allocated only once not for 
every CPU and marking here is not correct. Information from zynqmp_ipi_pdata are 
likely fixed and the same for every CPU. Only IRQ handling is done per cpu basis 
but that's it.

Reviewed-by: Michal Simek <michal.simek at amd.com>

Thanks,
Michal



From michal.swiatkowski at linux.intel.com  Sun Dec 15 23:15:42 2024
From: michal.swiatkowski at linux.intel.com (Michal Swiatkowski)
Date: Mon, 16 Dec 2024 08:15:42 +0100
Subject: [PATCH net-next] net: airoha: Fix error patch in airoha_probe()
In-Reply-To: <20241215-airoha_probe-error-path-fix-v1-1-dd299122d343@kernel.org>
References: <20241215-airoha_probe-error-path-fix-v1-1-dd299122d343@kernel.org>
Message-ID: <Z1/Tng80hii4dBQU@mev-dev.igk.intel.com>

On Sun, Dec 15, 2024 at 06:36:35PM +0100, Lorenzo Bianconi wrote:
> Do not run napi_disable if airoha_hw_init() fails since Tx/Rx napi
> has not been started yet. In order to fix the issue, introduce
> airoha_qdma_disable_napi routine and remove napi_disable in
> airoha_hw_cleanup().
> 
> Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
> Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
> ---
>  drivers/net/ethernet/mediatek/airoha_eth.c | 33 ++++++++++++++++++++++--------
>  1 file changed, 25 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
> index 6c683a12d5aa52dd9d966df123509075a989c0b3..5bbf5fee2802135ff6083233d0bda78f2ba5606a 100644
> --- a/drivers/net/ethernet/mediatek/airoha_eth.c
> +++ b/drivers/net/ethernet/mediatek/airoha_eth.c
> @@ -2138,17 +2138,14 @@ static void airoha_hw_cleanup(struct airoha_qdma *qdma)
>  		if (!qdma->q_rx[i].ndesc)
>  			continue;
>  
> -		napi_disable(&qdma->q_rx[i].napi);
>  		netif_napi_del(&qdma->q_rx[i].napi);
>  		airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
>  		if (qdma->q_rx[i].page_pool)
>  			page_pool_destroy(qdma->q_rx[i].page_pool);
>  	}
>  
> -	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
> -		napi_disable(&qdma->q_tx_irq[i].napi);
> +	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
>  		netif_napi_del(&qdma->q_tx_irq[i].napi);
> -	}
>  
>  	for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
>  		if (!qdma->q_tx[i].ndesc)
> @@ -2173,6 +2170,21 @@ static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
>  	}
>  }
>  
> +static void airoha_qdma_disable_napi(struct airoha_qdma *qdma)
Nit: similar function for enabling napi is named airoha_qdma_start_napi()
maybe stop here or enable there to be consistent.

Reviewed-by: Michal Swiatkowski <michal.swiatkowski at linux.intel.com>

Thanks

> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
> +		napi_disable(&qdma->q_tx_irq[i].napi);
> +
> +	for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
> +		if (!qdma->q_rx[i].ndesc)
> +			continue;
> +
> +		napi_disable(&qdma->q_rx[i].napi);
> +	}
> +}
> +

[...]


From geoffrey_chien at pegatron.corp-partner.google.com  Sun Dec 15 23:35:12 2024
From: geoffrey_chien at pegatron.corp-partner.google.com (Geoffrey Chien)
Date: Mon, 16 Dec 2024 15:35:12 +0800
Subject: [PATCH] arm64: dts: mt8186: Add mt8186-skitty
Message-ID: <20241216-skitty_kernel-v1-1-bc75dcdfeb57@pegatron.corp-partner.google.com>

Add Skitty initial device tree.
Support second source Synaptics trackpad
Support US2 keyboard.
Enhance touch screen timing for ELAN
Based on experiment, set drive-strength to 6mA (default = 8mA)
Modify sbs battery reg to 0x0f

Signed-off-by: Geoffrey Chien <geoffrey_chien at pegatron.corp-partner.google.com>
---
 .../devicetree/bindings/arm/mediatek.yaml          |  8 +++
 arch/arm64/boot/dts/mediatek/Makefile              |  4 ++
 .../dts/mediatek/mt8186-corsola-skitty-sku1.dts    | 23 +++++++
 .../dts/mediatek/mt8186-corsola-skitty-sku2.dts    | 13 ++++
 .../dts/mediatek/mt8186-corsola-skitty-sku3.dts    | 40 ++++++++++++
 .../dts/mediatek/mt8186-corsola-skitty-sku4.dts    | 30 +++++++++
 .../boot/dts/mediatek/mt8186-corsola-skitty.dtsi   | 76 ++++++++++++++++++++++
 7 files changed, 194 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 1d4bb50fcd8d9aadb7b77e144a474b79da005056..29e7555569a772ba042e29af01ea98fdd3be1525 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -224,6 +224,14 @@ properties:
               - google,pico-sku2
           - const: google,pico
           - const: mediatek,mt8183
+      - description: Google Skitty (HP Chromebook G1m 11 inch)
+        items:
+          - const: google,skitty-sku1
+          - const: google,skitty-sku2
+          - const: google,skitty-sku3
+          - const: google,skitty-sku4
+          - const: google,skitty
+          - const: mediatek,mt8186
       - description: Google Willow (Acer Chromebook 311 C722/C722T)
         items:
           - enum:
diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 8fd7b2bb7a1590341e7bb4ea1ecf039ae3e8eb0d..328e1ee444bd81b5a2aa3d21acb7a5c5a3318a87 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -59,6 +59,10 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-rusty-sku196608.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku1.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku2.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku3.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku4.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131072.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131073.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327681.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku1.dts
new file mode 100644
index 0000000000000000000000000000000000000000..a0e7b10445333d6f83fc4c461ce8f8d75ffaa697
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku1.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-skitty.dtsi"
+
+/ {
+	model = "Google Skitty sku1 board";
+	compatible = "google,skitty-sku1",
+		"google,skitty", "google,corsola", "mediatek,mt8186";
+};
+
+&i2c1 {
+	/delete-node/ touchscreen at 10;
+	touchscreen: touchscreen at 10 {
+		compatible = "elan,ekth3500";
+		reg = <0x10>;
+		interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+		status = "okay";
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku2.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku2.dts
new file mode 100644
index 0000000000000000000000000000000000000000..c071c1b8952b50eacfc2d48dbb9450e9b358ef0e
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku2.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-skitty.dtsi"
+
+/ {
+	model = "Google Skitty sku2 board";
+	compatible = "google,skitty-sku2",
+		"google,skitty", "google,corsola", "mediatek,mt8186";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku3.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku3.dts
new file mode 100644
index 0000000000000000000000000000000000000000..09b4b26aba93c0e65b5fbef6eb81edbe414daa0b
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku3.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-skitty.dtsi"
+
+/ {
+	model = "Google Skitty sku3 board";
+	compatible = "google,skitty-sku3",
+		"google,skitty", "google,corsola", "mediatek,mt8186";
+};
+
+&i2c1 {
+	/delete-node/ touchscreen at 10;
+	touchscreen: touchscreen at 10 {
+		compatible = "elan,ekth3500";
+		reg = <0x10>;
+		interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+		status = "okay";
+	};
+};
+
+&keyboard_controller {
+	linux,keymap = <
+		MATRIX_KEY(0x00, 0x02, KEY_BACK)
+		MATRIX_KEY(0x03, 0x02, KEY_REFRESH)
+		MATRIX_KEY(0x02, 0x02, KEY_ZOOM)
+		MATRIX_KEY(0x01, 0x02, KEY_SCALE)
+		MATRIX_KEY(0x03, 0x04, KEY_SYSRQ)
+		MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN)
+		MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP)
+		MATRIX_KEY(0x02, 0x09, KEY_MUTE)
+		MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN)
+		MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP)
+		CROS_STD_MAIN_KEYMAP
+		MATRIX_KEY(0x04, 0x00, KEY_102ND)
+	>;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku4.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku4.dts
new file mode 100644
index 0000000000000000000000000000000000000000..c3e2dbd0120f32062dba6a2f6f9e8ee31db02588
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku4.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-skitty.dtsi"
+
+/ {
+	model = "Google Skitty sku4 board";
+	compatible = "google,skitty-sku4",
+		"google,skitty", "google,corsola", "mediatek,mt8186";
+};
+
+&keyboard_controller {
+	linux,keymap = <
+		MATRIX_KEY(0x00, 0x02, KEY_BACK)
+		MATRIX_KEY(0x03, 0x02, KEY_REFRESH)
+		MATRIX_KEY(0x02, 0x02, KEY_ZOOM)
+		MATRIX_KEY(0x01, 0x02, KEY_SCALE)
+		MATRIX_KEY(0x03, 0x04, KEY_SYSRQ)
+		MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN)
+		MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP)
+		MATRIX_KEY(0x02, 0x09, KEY_MUTE)
+		MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN)
+		MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP)
+		CROS_STD_MAIN_KEYMAP
+		MATRIX_KEY(0x04, 0x00, KEY_102ND)
+	>;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..51a05f96191b4e40ad1f77e6a8ea23c99af3b279
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty.dtsi
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2024 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-krabby.dtsi"
+
+&keyboard_controller {
+	function-row-physmap = <
+		MATRIX_KEY(0x00, 0x02, 0)	/* T1 */
+		MATRIX_KEY(0x03, 0x02, 0)	/* T2 */
+		MATRIX_KEY(0x02, 0x02, 0)	/* T3 */
+		MATRIX_KEY(0x01, 0x02, 0)	/* T4 */
+		MATRIX_KEY(0x03, 0x04, 0)	/* T5 */
+		MATRIX_KEY(0x02, 0x04, 0)	/* T6 */
+		MATRIX_KEY(0x01, 0x04, 0)	/* T7 */
+		MATRIX_KEY(0x02, 0x09, 0)	/* T8 */
+		MATRIX_KEY(0x01, 0x09, 0)	/* T9 */
+		MATRIX_KEY(0x00, 0x04, 0)	/* T10 */
+	>;
+
+	linux,keymap = <
+		MATRIX_KEY(0x00, 0x02, KEY_BACK)
+		MATRIX_KEY(0x03, 0x02, KEY_REFRESH)
+		MATRIX_KEY(0x02, 0x02, KEY_ZOOM)
+		MATRIX_KEY(0x01, 0x02, KEY_SCALE)
+		MATRIX_KEY(0x03, 0x04, KEY_SYSRQ)
+		MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSDOWN)
+		MATRIX_KEY(0x01, 0x04, KEY_BRIGHTNESSUP)
+		MATRIX_KEY(0x02, 0x09, KEY_MUTE)
+		MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN)
+		MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP)
+		CROS_STD_MAIN_KEYMAP
+	>;
+};
+
+&usb_c1 {
+	status = "disabled";
+};
+
+&target {
+	temperature = <76000>;
+};
+
+&i2c2 {
+	touchpad at 2c {
+		compatible = "hid-over-i2c";
+		reg = <0x2c>;
+		hid-descr-addr = <0x20>;
+		interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>;
+		vcc-supply = <&pp3300_s3>;
+		wakeup-source;
+	};
+};
+
+&mmc1_pins_uhs {
+	pins-clk {
+		drive-strength = <MTK_DRIVE_6mA>;
+	};
+
+	pins-cmd-dat {
+		drive-strength = <MTK_DRIVE_6mA>;
+	};
+};
+
+&i2c_tunnel {
+	/delete-node/ sbs-battery at b;
+
+	battery: sbs-battery at f {
+		compatible = "sbs,sbs-battery";
+		reg = <0xf>;
+		sbs,i2c-retry-count = <2>;
+		sbs,poll-retry-count = <1>;
+	};
+};

---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241216-skitty_kernel-6e330a493d51

Best regards,
-- 
Geoffrey Chien <geoffrey_chien at pegatron.corp-partner.google.com>



From guomin_chen at sina.com  Sun Dec 15 23:37:45 2024
From: guomin_chen at sina.com (guomin_chen at sina.com)
Date: Mon, 16 Dec 2024 15:37:45 +0800
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless scmi_bus_id.
Message-ID: <20241216073745.2973317-1-guomin_chen@sina.com>

From: guomin chen <guomin_chen at sina.com>

Currently, scmi_bus_id is only used to set scmi_dev.id,
which in turn sets the SCMI device name. After removing
scmi_bus_id, it is clearer and more meaningful to directly
use the unique tuple [Parent name,device name, protocol] to 
set the SCMI device name.

Signed-off-by: guomin chen <guomin_chen at sina.com>
---
 drivers/firmware/arm_scmi/bus.c    | 17 +++--------------
 drivers/firmware/arm_scmi/driver.c |  4 ++--
 2 files changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 157172a5f2b5..800e8ec9357c 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -20,7 +20,6 @@
 BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
 EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
 
-static DEFINE_IDA(scmi_bus_id);
 
 static DEFINE_IDR(scmi_requested_devices);
 /* Protect access to scmi_requested_devices */
@@ -341,7 +340,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
 	if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
 		atomic_set(&scmi_syspower_registered, 0);
 
-	ida_free(&scmi_bus_id, scmi_dev->id);
 	device_unregister(&scmi_dev->dev);
 }
 
@@ -349,7 +347,7 @@ static struct scmi_device *
 __scmi_device_create(struct device_node *np, struct device *parent,
 		     int protocol, const char *name)
 {
-	int id, retval;
+	int retval;
 	struct scmi_device *scmi_dev;
 
 	/*
@@ -387,20 +385,13 @@ __scmi_device_create(struct device_node *np, struct device *parent,
 		return NULL;
 	}
 
-	id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
-	if (id < 0) {
-		kfree_const(scmi_dev->name);
-		kfree(scmi_dev);
-		return NULL;
-	}
-
-	scmi_dev->id = id;
 	scmi_dev->protocol_id = protocol;
 	scmi_dev->dev.parent = parent;
 	device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
 	scmi_dev->dev.bus = &scmi_bus_type;
 	scmi_dev->dev.release = scmi_device_release;
-	dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
+	dev_set_name(&scmi_dev->dev, "scmi_dev.%s.%s.%d", dev_name(parent),
+			scmi_dev->name, protocol);
 
 	retval = device_register(&scmi_dev->dev);
 	if (retval)
@@ -413,7 +404,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
 	return scmi_dev;
 put_dev:
 	put_device(&scmi_dev->dev);
-	ida_free(&scmi_bus_id, id);
 	return NULL;
 }
 
@@ -526,7 +516,6 @@ static void __exit scmi_bus_exit(void)
 	 */
 	scmi_devices_unregister();
 	bus_unregister(&scmi_bus_type);
-	ida_destroy(&scmi_bus_id);
 }
 module_exit(scmi_bus_exit);
 
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 1b5fb2c4ce86..bbf1f05f2be3 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2641,8 +2641,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
 	cinfo->max_msg_size = info->desc->max_msg_size;
 
 	/* Create a unique name for this transport device */
-	snprintf(name, 32, "__scmi_transport_device_%s_%02X",
-		 idx ? "rx" : "tx", prot_id);
+	snprintf(name, 32, "__scmi_transport_device_%s",
+		 idx ? "rx" : "tx");
 	/* Create a uniquely named, dedicated transport device for this chan */
 	tdev = scmi_device_create(of_node, info->dev, prot_id, name);
 	if (!tdev) {
-- 
2.47.1



From ubizjak at gmail.com  Sun Dec 15 23:37:28 2024
From: ubizjak at gmail.com (Uros Bizjak)
Date: Mon, 16 Dec 2024 08:37:28 +0100
Subject: [PATCH 1/3] KVM: arm64: timers: Fix percpu address space issues
 in kvm_timer_hyp_init()
In-Reply-To: <86bjxfsdw0.wl-maz@kernel.org>
References: <20241213145809.2918-1-ubizjak@gmail.com> <86bjxfsdw0.wl-maz@kernel.org>
Message-ID: <CAFULd4YY0BvbjtF=6wG9CoZo7ZLpAOFCk_fzuQ5gVOQ2D3SR=A@mail.gmail.com>

On Fri, Dec 13, 2024 at 6:15?PM Marc Zyngier <maz at kernel.org> wrote:
>
> On Fri, 13 Dec 2024 14:57:52 +0000,
> Uros Bizjak <ubizjak at gmail.com> wrote:
> >
> > Cast return value from kvm_get_running_vcpus() in the __percpu
> > address space to the generic address space via uintptr_t [1]
> > to fix a couple of:
> >
> > arch_timer.c:1395:66: warning: incorrect type in argument 2 (different address spaces)
> > arch_timer.c:1395:66:    expected void *vcpu_info
> > arch_timer.c:1395:66:    got struct kvm_vcpu *[noderef] __percpu *
> >
> > sparse warnings.
> >
> > There were no changes in the resulting object files.
> >
> > [1] https://sparse.docs.kernel.org/en/latest/annotations.html#address-space-name
> >
> > Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
> > Cc: Marc Zyngier <maz at kernel.org>
> > Cc: Oliver Upton <oliver.upton at linux.dev>
> > Cc: Joey Gouly <joey.gouly 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>
> > ---
> >  arch/arm64/kvm/arch_timer.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> > index 1215df590418..a13bb9e8dc19 100644
> > --- a/arch/arm64/kvm/arch_timer.c
> > +++ b/arch/arm64/kvm/arch_timer.c
> > @@ -1392,7 +1392,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
> >
> >       if (has_gic) {
> >               err = irq_set_vcpu_affinity(host_vtimer_irq,
> > -                                         kvm_get_running_vcpus());
> > +                                         (void *)(uintptr_t)kvm_get_running_vcpus());
> >               if (err) {
> >                       kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
> >                       goto out_free_vtimer_irq;
> > @@ -1416,7 +1416,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
> >
> >               if (has_gic) {
> >                       err = irq_set_vcpu_affinity(host_ptimer_irq,
> > -                                                 kvm_get_running_vcpus());
> > +                                                 (void *)(uintptr_t)kvm_get_running_vcpus());
> >                       if (err) {
> >                               kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
> >                               goto out_free_ptimer_irq;
>
> I think the fix is worse than the current code, because there is no
> real semantics behind the pointer being passed to
> irq_set_vcpu_affinity(). All that is required is that it is a non-NULL
> pointer.
>
> I expect the following hack to work just as well and not suffer from
> any sparse indigestion. Untested though.

The proposed hack also fixes sparse warnings and fixes my percpu
checker errors, but as a functional change, I have no means of testing
the proposed change on a target processor. So, I can just give:

Acked-by: Uros Bizjak <ubizjak at gmail.com>

from a percpu checker perspective.

Thanks,
Uros.


From ck.hu at mediatek.com  Sun Dec 15 23:38:59 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 16 Dec 2024 07:38:59 +0000
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
Message-ID: <ef02d09ce33ab249e877e779f75c3980f5a5939a.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> -struct mtk_hdmi {
> -       struct drm_bridge bridge;
> -       struct drm_bridge *next_bridge;
> -       struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */
> -       struct device *dev;
> -       const struct mtk_hdmi_conf *conf;
> -       struct phy *phy;
> -       struct device *cec_dev;
> -       struct i2c_adapter *ddc_adpt;
> -       struct clk *clk[MTK_HDMI_CLK_COUNT];
> -       struct drm_display_mode mode;
> -       bool dvi_mode;
> -       u32 min_clock;
> -       u32 max_clock;
> -       u32 max_hdisplay;
> -       u32 max_vdisplay;
> -       u32 ibias;
> -       u32 ibias_up;
> -       struct regmap *sys_regmap;
> -       unsigned int sys_offset;
> -       struct regmap *regs;
> -       enum hdmi_colorspace csp;
> -       struct hdmi_audio_param aud_param;
> -       bool audio_enable;
> -       bool powered;
> -       bool enabled;
> -       hdmi_codec_plugged_cb plugged_cb;
> -       struct device *codec_dev;
> -       struct mutex update_plugged_status_lock;
> };
> 
> +struct mtk_hdmi {
> +       struct drm_bridge bridge;
> +       struct device *dev;
> +       const struct mtk_hdmi_conf *conf;
> +       struct phy *phy;
> +       struct i2c_adapter *ddc_adpt;
> +       struct clk **clk;
> +       struct drm_display_mode mode;
> +       bool dvi_mode;
> +       struct regmap *sys_regmap;
> +       unsigned int sys_offset;
> +       struct regmap *regs;
> +
> +       bool powered;
> +       bool enabled;
> +       unsigned int irq;

You add something which is used in v2 but not in v1.
Move these to the v2 patch, or separate them to a precondition patch of v2.

> +       enum hdmi_hpd_state hpd;
> +
> +       /* Audio */
> +       struct platform_device *audio_pdev;
> +       struct hdmi_audio_param aud_param;
> +       bool audio_enable;
> +
> +       struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */
> +       struct mutex update_plugged_status_lock;
> +       struct device *cec_dev;
> +       struct device *codec_dev;
> +       hdmi_codec_plugged_cb plugged_cb;
> +       struct drm_bridge *next_bridge;

I don't know why you reorder these.
If it's necessary, separate these reorder to a refinement patch.

Regards,
CK

> +};
> +


From krzk at kernel.org  Mon Dec 16 00:10:15 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 09:10:15 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am62l: add initial infrastructure
In-Reply-To: <20241117-am62lx-v1-1-4e71e42d781d@ti.com>
References: <20241117-am62lx-v1-0-4e71e42d781d@ti.com>
 <20241117-am62lx-v1-1-4e71e42d781d@ti.com>
Message-ID: <d4b4d357-f1f5-4e75-938b-e6742d1d3674@kernel.org>

On 18/11/2024 06:34, Bryan Brattlof wrote:
> From: Vignesh Raghavendra <vigneshr at ti.com>
> 
> Add the initial infrastructure needed for the AM62L. All of which can be
> found in the Technical Reference Manual (TRM) located here:
> 
>     https://www.ti.com/lit/ug/sprujb4/sprujb4.pdf
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
> Signed-off-by: Bryan Brattlof <bb at ti.com>
> ---
>  Documentation/devicetree/bindings/arm/ti/k3.yaml |  6 ++
Please run scripts/checkpatch.pl and fix reported warnings. Then please
run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec 16 00:11:18 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 09:11:18 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am62l: add initial infrastructure
In-Reply-To: <d4b4d357-f1f5-4e75-938b-e6742d1d3674@kernel.org>
References: <20241117-am62lx-v1-0-4e71e42d781d@ti.com>
 <20241117-am62lx-v1-1-4e71e42d781d@ti.com>
 <d4b4d357-f1f5-4e75-938b-e6742d1d3674@kernel.org>
Message-ID: <d0424774-b7af-456f-b76d-fe5e39d0d483@kernel.org>

On 16/12/2024 09:10, Krzysztof Kozlowski wrote:
> On 18/11/2024 06:34, Bryan Brattlof wrote:
>> From: Vignesh Raghavendra <vigneshr at ti.com>
>>
>> Add the initial infrastructure needed for the AM62L. All of which can be
>> found in the Technical Reference Manual (TRM) located here:
>>
>>     https://www.ti.com/lit/ug/sprujb4/sprujb4.pdf
>>
>> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
>> Signed-off-by: Bryan Brattlof <bb at ti.com>
>> ---
>>  Documentation/devicetree/bindings/arm/ti/k3.yaml |  6 ++
> Please run scripts/checkpatch.pl and fix reported warnings. Then please
> run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
> Some warnings can be ignored, especially from --strict run, but the code
> here looks like it needs a fix. Feel free to get in touch if the warning
> is not clear.

Apologies for digging this old thread, some other reply bumped it to top
of my inbox.

Best regards,
Krzysztof


From maxime.chevallier at bootlin.com  Mon Dec 16 00:42:24 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Mon, 16 Dec 2024 09:42:24 +0100
Subject: [PATCH net-next 2/2] net: stmmac: dwmac-socfpga: Set interface
 modes from Lynx PCS as supported
In-Reply-To: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
	<20241213090526.71516-3-maxime.chevallier@bootlin.com>
	<Z1wnFXlgEU84VX8F@shell.armlinux.org.uk>
	<20241213182904.55eb2504@fedora.home>
	<Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
Message-ID: <20241216094224.199e8df7@fedora.home>

Hello Russell,

On Fri, 13 Dec 2024 19:21:38 +0000
"Russell King (Oracle)" <linux at armlinux.org.uk> wrote:

> > > However, maybe at this point we need to introduce an interface bitmap
> > > into struct phylink_pcs so that these kinds of checks can be done in
> > > phylink itself when it has the PCS, and it would also mean that stmmac
> > > could do something like:

[...]

> > > and not have to worry about this from individual PCS or platform code.  
> > 
> > I like the idea, I will give it a go and send a series for that if
> > that's ok :)  
> 
> I've actually already created that series!

Woaw that was fast ! I'll review and give it a test on my setup then.

Maybe one thing to clarify with the net maintainers is that this work
you've done doesn't replace the series this thread is replying to,
which still makes sense (we need the
stmmac_priv->phylink_config.supported_interfaces to be correctly
populated on socfpga).

Thanks a lot for that work Russell,

Maxime

Thanks a lot,

Maxime


From ukleinek at kernel.org  Mon Dec 16 00:23:03 2024
From: ukleinek at kernel.org (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Mon, 16 Dec 2024 09:23:03 +0100
Subject: [PATCH] pwm: stm32: Add check for clk_enable()
In-Reply-To: <20241215224752.220318-1-zmw12306@gmail.com>
References: <20241215224752.220318-1-zmw12306@gmail.com>
Message-ID: <24zcihiin4lkfhahxmn4nx4t7v5hlvxhlcjzeyrz2kizcqkaop@b5yq44j4vozj>

Hello,

On Sun, Dec 15, 2024 at 05:47:52PM -0500, Mingwei Zheng wrote:
> Add check for the return value of clk_enable() to catch the potential
> error.
> 
> Fixes: 19f1016ea960 ("pwm: stm32: Fix enable count for clk in .probe()")
> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
> ---
>  drivers/pwm/pwm-stm32.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
> index b889e64522c3..b94d186e3c0c 100644
> --- a/drivers/pwm/pwm-stm32.c
> +++ b/drivers/pwm/pwm-stm32.c
> @@ -858,8 +858,11 @@ static int stm32_pwm_probe(struct platform_device *pdev)
>  	chip->ops = &stm32pwm_ops;
>  
>  	/* Initialize clock refcount to number of enabled PWM channels. */
> -	for (i = 0; i < num_enabled; i++)
> -		clk_enable(priv->clk);
> +	for (i = 0; i < num_enabled; i++) {
> +		ret = clk_enable(priv->clk);
> +		if (ret)
> +			return ret;
> +	}

I wondered for some time if we could still improve more here. If the
(say) second clk_enable() or devm_pwmchip_add() fails, the clk_enable()
calls are leaked. However disabling the clk also might have downsides
(as it might stop a running PWM). OTOH the only expected failure point
is the first clk_enable() as the following are just software operations
and devm_pwmchip_add() only fails on memory pressure. So proper cleanup
doesn't really matter.

So I think the patch is fine as is and I will apply it.

Best regards
Uwe
-------------- 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/20241216/67dff588/attachment.sig>

From dan.carpenter at linaro.org  Mon Dec 16 00:31:00 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Mon, 16 Dec 2024 11:31:00 +0300
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless
 scmi_bus_id.
In-Reply-To: <20241216073745.2973317-1-guomin_chen@sina.com>
References: <20241216073745.2973317-1-guomin_chen@sina.com>
Message-ID: <e6a19d60-8e39-406a-8426-5fbec50c4b3c@stanley.mountain>

On Mon, Dec 16, 2024 at 03:37:45PM +0800, guomin_chen at sina.com wrote:
> From: guomin chen <guomin_chen at sina.com>
> 
> Currently, scmi_bus_id is only used to set scmi_dev.id,
> which in turn sets the SCMI device name. After removing
> scmi_bus_id, it is clearer and more meaningful to directly
> use the unique tuple [Parent name,device name, protocol] to 
> set the SCMI device name.
> 
> Signed-off-by: guomin chen <guomin_chen at sina.com>
> ---
>  drivers/firmware/arm_scmi/bus.c    | 17 +++--------------
>  drivers/firmware/arm_scmi/driver.c |  4 ++--
>  2 files changed, 5 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
> index 157172a5f2b5..800e8ec9357c 100644
> --- a/drivers/firmware/arm_scmi/bus.c
> +++ b/drivers/firmware/arm_scmi/bus.c
> @@ -20,7 +20,6 @@
>  BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
>  EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
>  
> -static DEFINE_IDA(scmi_bus_id);
>  

You'll want to delet the blank line to avoid a checkpatch warning.
(checkpatch doesn't warn about the patch, but if you re-run it on
the file later, it will warn).

>  static DEFINE_IDR(scmi_requested_devices);
>  /* Protect access to scmi_requested_devices */
> @@ -341,7 +340,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
>  	if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
>  		atomic_set(&scmi_syspower_registered, 0);
>  
> -	ida_free(&scmi_bus_id, scmi_dev->id);
>  	device_unregister(&scmi_dev->dev);
>  }
>  
> @@ -349,7 +347,7 @@ static struct scmi_device *
>  __scmi_device_create(struct device_node *np, struct device *parent,
>  		     int protocol, const char *name)
>  {
> -	int id, retval;
> +	int retval;
>  	struct scmi_device *scmi_dev;
>  
>  	/*
> @@ -387,20 +385,13 @@ __scmi_device_create(struct device_node *np, struct device *parent,
>  		return NULL;
>  	}
>  
> -	id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
> -	if (id < 0) {
> -		kfree_const(scmi_dev->name);
> -		kfree(scmi_dev);
> -		return NULL;
> -	}
> -
> -	scmi_dev->id = id;
>  	scmi_dev->protocol_id = protocol;
>  	scmi_dev->dev.parent = parent;
>  	device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
>  	scmi_dev->dev.bus = &scmi_bus_type;
>  	scmi_dev->dev.release = scmi_device_release;
> -	dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
> +	dev_set_name(&scmi_dev->dev, "scmi_dev.%s.%s.%d", dev_name(parent),
> +			scmi_dev->name, protocol);
>  
>  	retval = device_register(&scmi_dev->dev);
>  	if (retval)
> @@ -413,7 +404,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
>  	return scmi_dev;
>  put_dev:
>  	put_device(&scmi_dev->dev);
> -	ida_free(&scmi_bus_id, id);
>  	return NULL;
>  }
>  
> @@ -526,7 +516,6 @@ static void __exit scmi_bus_exit(void)
>  	 */
>  	scmi_devices_unregister();
>  	bus_unregister(&scmi_bus_type);
> -	ida_destroy(&scmi_bus_id);
>  }
>  module_exit(scmi_bus_exit);
>  
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index 1b5fb2c4ce86..bbf1f05f2be3 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -2641,8 +2641,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
>  	cinfo->max_msg_size = info->desc->max_msg_size;
>  
>  	/* Create a unique name for this transport device */

This comment should be updated.

> -	snprintf(name, 32, "__scmi_transport_device_%s_%02X",
> -		 idx ? "rx" : "tx", prot_id);
> +	snprintf(name, 32, "__scmi_transport_device_%s",
> +		 idx ? "rx" : "tx");

We used to create new transport devices for each port, but now we
only we only create one for recieve and one for transmit.  This is
unrelated to the commit message and needs to be done in separate commit
if at all.

regards,
dan carpenter



From kaihengf at nvidia.com  Mon Dec 16 00:33:28 2024
From: kaihengf at nvidia.com (Kai-Heng Feng)
Date: Mon, 16 Dec 2024 16:33:28 +0800
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <955a7947-3053-490e-a803-d55699dddd0c@nvidia.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
 <3f19c5a8-9ee6-42fe-8b4c-3a66c65c8d35@nvidia.com>
 <955a7947-3053-490e-a803-d55699dddd0c@nvidia.com>
Message-ID: <e3284392-4f57-4b5f-a79d-40b588e6c70e@nvidia.com>

Hi Sumit,

On 2024/12/16 3:11 PM, Sumit Gupta wrote:
> 
> 
> On 16/12/24 11:13, Kai-Heng Feng wrote:
>> Hi Beata,
>>
>> On 2024/12/6 9:55 PM, Beata Michalska wrote:
>>> Currently the CPUFreq core exposes two sysfs attributes that can be used
>>> to query current frequency of a given CPU(s): namely cpuinfo_cur_freq
>>> and scaling_cur_freq. Both provide slightly different view on the
>>> subject and they do come with their own drawbacks.
>>>
>>> cpuinfo_cur_freq provides higher precision though at a cost of being
>>> rather expensive. Moreover, the information retrieved via this attribute
>>> is somewhat short lived as frequency can change at any point of time
>>> making it difficult to reason from.
>>>
>>> scaling_cur_freq, on the other hand, tends to be less accurate but then
>>> the actual level of precision (and source of information) varies between
>>> architectures making it a bit ambiguous.
>>>
>>> The new attribute, cpuinfo_avg_freq, is intended to provide more stable,
>>> distinct interface, exposing an average frequency of a given CPU(s), as
>>> reported by the hardware, over a time frame spanning no more than a few
>>> milliseconds. As it requires appropriate hardware support, this
>>> interface is optional.
>>>
>>> Note that under the hood, the new attribute relies on the information
>>> provided by arch_freq_get_on_cpu, which, up to this point, has been
>>> feeding data for scaling_cur_freq attribute, being the source of
>>> ambiguity when it comes to interpretation. This has been amended by
>>> restoring the intended behavior for scaling_cur_freq, with a new
>>> dedicated config option to maintain status quo for those, who may need
>>> it.
>>>
>>> CC: Jonathan Corbet <corbet at lwn.net>
>>> CC: Thomas Gleixner <tglx at linutronix.de>
>>> CC: Ingo Molnar <mingo at redhat.com>
>>> CC: Borislav Petkov <bp at alien8.de>
>>> CC: Dave Hansen <dave.hansen at linux.intel.com>
>>> CC: H. Peter Anvin <hpa at zytor.com>
>>> CC: Phil Auld <pauld at redhat.com>
>>> CC: x86 at kernel.org
>>> CC: linux-doc at vger.kernel.org
>>> Signed-off-by: Beata Michalska <beata.michalska at arm.com>
>>> ---
>>> ? Documentation/admin-guide/pm/cpufreq.rst | 16 ++++++++++-
>>> ? arch/x86/kernel/cpu/aperfmperf.c???????? |? 2 +-
>>> ? arch/x86/kernel/cpu/proc.c?????????????? |? 7 +++--
>>> ? drivers/cpufreq/Kconfig.x86????????????? | 12 ++++++++
>>> ? drivers/cpufreq/cpufreq.c??????????????? | 36 +++++++++++++++++++++---
>>> ? include/linux/cpufreq.h????????????????? |? 2 +-
>>> ? 6 files changed, 66 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin- 
>>> guide/pm/cpufreq.rst
>>> index fe1be4ad88cb..76f3835afe01 100644
>>> --- a/Documentation/admin-guide/pm/cpufreq.rst
>>> +++ b/Documentation/admin-guide/pm/cpufreq.rst
>>> @@ -248,6 +248,19 @@ are the following:
>>> ????? If that frequency cannot be determined, this attribute should not
>>> ????? be present.
>>> +``cpuinfo_avg_freq``
>>> +??????? An average frequency (in KHz) of all CPUs belonging to a given policy,
>>> +??????? derived from a hardware provided feedback and reported on a time frame
>>> +??????? spanning at most few milliseconds.
>>> +
>>> +??????? This is expected to be based on the frequency the hardware actually 
>>> runs
>>> +??????? at and, as such, might require specialised hardware support (such as 
>>> AMU
>>> +??????? extension on ARM). If one cannot be determined, this attribute should
>>> +??????? not be present.
>>> +
>>> +??????? Note, that failed attempt to retrieve current frequency for a given
>>> +??????? CPU(s) will result in an appropriate error.
>>> +
>>> ? ``cpuinfo_max_freq``
>>> ????? Maximum possible operating frequency the CPUs belonging to this policy
>>> ????? can run at (in kHz).
>>> @@ -293,7 +306,8 @@ are the following:
>>> ????? Some architectures (e.g. ``x86``) may attempt to provide information
>>> ????? more precisely reflecting the current CPU frequency through this
>>> ????? attribute, but that still may not be the exact current CPU frequency as
>>> -??? seen by the hardware at the moment.
>>> +??? seen by the hardware at the moment. This behavior though, is only
>>> +??? available via c:macro:``CPUFREQ_ARCH_CUR_FREQ`` option.
>>> ? ``scaling_driver``
>>> ????? The scaling driver currently in use.
>>> diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
>>> index 0b69bfbf345d..a00059139ca4 100644
>>> --- a/arch/x86/kernel/cpu/aperfmperf.c
>>> +++ b/arch/x86/kernel/cpu/aperfmperf.c
>>> @@ -413,7 +413,7 @@ void arch_scale_freq_tick(void)
>>> ?? */
>>> ? #define MAX_SAMPLE_AGE??? ((unsigned long)HZ / 50)
>>> -unsigned int arch_freq_get_on_cpu(int cpu)
>>> +int arch_freq_get_on_cpu(int cpu)
>>> ? {
>>> ????? struct aperfmperf *s = per_cpu_ptr(&cpu_samples, cpu);
>>> ????? unsigned int seq, freq;
>>> diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
>>> index e65fae63660e..34d8fb93fb70 100644
>>> --- a/arch/x86/kernel/cpu/proc.c
>>> +++ b/arch/x86/kernel/cpu/proc.c
>>> @@ -86,9 +86,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
>>> ????????? seq_printf(m, "microcode\t: 0x%x\n", c->microcode);
>>> ????? if (cpu_has(c, X86_FEATURE_TSC)) {
>>> -??????? unsigned int freq = arch_freq_get_on_cpu(cpu);
>>> +??????? int freq = arch_freq_get_on_cpu(cpu);
>>> -??????? seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 1000));
>>> +??????? if (freq <= 0)
>>> +??????????? seq_puts(m, "cpu MHz\t\t: Unknown\n");
>>> +??????? else
>>> +??????????? seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 
>>> 1000));
>>> ????? }
>>> ????? /* Cache size */
>>> diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
>>> index 97c2d4f15d76..212e1b9afe21 100644
>>> --- a/drivers/cpufreq/Kconfig.x86
>>> +++ b/drivers/cpufreq/Kconfig.x86
>>> @@ -340,3 +340,15 @@ config X86_SPEEDSTEP_RELAXED_CAP_CHECK
>>> ??????? option lets the probing code bypass some of those checks if the
>>> ??????? parameter "relaxed_check=1" is passed to the module.
>>> +config CPUFREQ_ARCH_CUR_FREQ
>>> +??? default y
>>> +??? bool "Current frequency derived from HW provided feedback"
>>> +??? help
>>> +????? This determines whether the scaling_cur_freq sysfs attribute returns
>>> +????? the last requested frequency or a more precise value based on hardware
>>> +????? provided feedback (as architected counters).
>>> +????? Given that a more precise frequency can now be provided via the
>>> +????? cpuinfo_avg_cur_freq attribute, by enabling this option,
>>> +????? scaling_cur_freq maintains the provision of a counter based frequency,
>>> +????? for compatibility reasons.
>>> +
>>> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
>>> index 04fc786dd2c0..70df2a24437b 100644
>>> --- a/drivers/cpufreq/cpufreq.c
>>> +++ b/drivers/cpufreq/cpufreq.c
>>> @@ -747,9 +747,14 @@ show_one(cpuinfo_transition_latency, 
>>> cpuinfo.transition_latency);
>>> ? show_one(scaling_min_freq, min);
>>> ? show_one(scaling_max_freq, max);
>>> -__weak unsigned int arch_freq_get_on_cpu(int cpu)
>>> +__weak int arch_freq_get_on_cpu(int cpu)
>>> ? {
>>> -??? return 0;
>>> +??? return -EOPNOTSUPP;
>>> +}
>>> +
>>> +static inline bool cpufreq_avg_freq_supported(struct cpufreq_policy *policy)
>>> +{
>>> +??? return arch_freq_get_on_cpu(policy->cpu) != -EOPNOTSUPP;
>>> ? }
>>> ? static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
>>> @@ -757,8 +762,11 @@ static ssize_t show_scaling_cur_freq(struct 
>>> cpufreq_policy *policy, char *buf)
>>> ????? ssize_t ret;
>>> ????? unsigned int freq;
>>> -??? freq = arch_freq_get_on_cpu(policy->cpu);
>>> -??? if (freq)
>>> +??? freq = IS_ENABLED(CONFIG_CPUFREQ_ARCH_CUR_FREQ)
>>> +??????? ? arch_freq_get_on_cpu(policy->cpu)
>>> +??????? : 0;
>>> +
>>> +??? if (freq > 0)
>>> ????????? ret = sysfs_emit(buf, "%u\n", freq);
>>> ????? else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
>>> ????????? ret = sysfs_emit(buf, "%u\n", cpufreq_driver->get(policy->cpu));
>>> @@ -802,6 +810,19 @@ static ssize_t show_cpuinfo_cur_freq(struct 
>>> cpufreq_policy *policy,
>>> ????? return sysfs_emit(buf, "<unknown>\n");
>>> ? }
>>> +/*
>>> + * show_cpuinfo_avg_freq - average CPU frequency as detected by hardware
>>> + */
>>> +static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
>>> +???????????????????? char *buf)
>>> +{
>>> +??? int avg_freq = arch_freq_get_on_cpu(policy->cpu);
>>
>> We are seeing issues when reading cpuinfo_avg_freq on an ARM64 system:
>>
>> $ cat /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq
>> cat: /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq: Resource 
>> temporarily unavailable
>>
>> The CPU is in idle state, so arch_freq_get_on_cpu() can't find a good 
>> alternative source for frequency info.
>>
> 
> Hi Kai Heng,
> This has already been discussed during v7 in [1] & [2].

Thanks for the info!

> In v7, we were returning zero which printed 'unknown'.
> The discussion was about printing in more descriptive way or with an appropriate 
> error code. In v8 we are returning 'EAGAIN' instead of zero. The final decision 
> was of Maintainers.

Is there any cpufreq driver that prints "unknown" or error when CPU is in idle?

I think it's more unsurprising to print the lowest CPU frequency when CPU is in 
idle state, instead of any other error code.

Kai-Heng

> 
> Viresh,
> You have any preference on this?
> 
> [1] https://lore.kernel.org/lkml/aa254516-968e-4665-bb5b-981c296ffc35 at nvidia.com/#t
> [2] https://lore.kernel.org/lkml/Zyh-uVSW-0d0r8oB at arm.com/
> 
> Thank you,
> Sumit Gupta
> 
>> One way to resolve this is to have fallback methods in show_cpuinfo_avg_freq() 
>> so it will look like this:
>>
>> static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
>> ????????????????????????????????????? char *buf)
>> {
>> ???????? int avg_freq = arch_freq_get_on_cpu(policy->cpu);
>> ???????? int ret;
>>
>> ???????? if (avg_freq > 0)
>> ???????????????? ret = sysfs_emit(buf, "%u\n", avg_freq);
>> ???????? else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
>> ???????????????? ret = sysfs_emit(buf, "%u\n", cpufreq_driver->get(policy->cpu));
>> ???????? else
>> ???????????????? ret = sysfs_emit(buf, "%u\n", policy->cur);
>> ???????? return ret;
>> }
>>
>> But that also makes show_cpuinfo_avg_freq() pretty much the same as 
>> show_scaling_cur_freq().
>>
>> So is it possible to consolidate show_cpuinfo_avg_freq() into 
>> show_scaling_cur_freq(), by making CONFIG_CPUFREQ_ARCH_CUR_FREQ also available 
>> to ARM64?
>>
>> Kai-Heng
>>
>>> +
>>> +??? if (avg_freq > 0)
>>> +??????? return sysfs_emit(buf, "%u\n", avg_freq);
>>> +??? return avg_freq != 0 ? avg_freq : -EINVAL;
>>> +}
>>> +
>>> ? /*
>>> ?? * show_scaling_governor - show the current policy for the specified CPU
>>> ?? */
>>> @@ -964,6 +985,7 @@ static ssize_t show_bios_limit(struct cpufreq_policy 
>>> *policy, char *buf)
>>> ? }
>>> ? cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
>>> +cpufreq_freq_attr_ro(cpuinfo_avg_freq);
>>> ? cpufreq_freq_attr_ro(cpuinfo_min_freq);
>>> ? cpufreq_freq_attr_ro(cpuinfo_max_freq);
>>> ? cpufreq_freq_attr_ro(cpuinfo_transition_latency);
>>> @@ -1091,6 +1113,12 @@ static int cpufreq_add_dev_interface(struct 
>>> cpufreq_policy *policy)
>>> ????????????? return ret;
>>> ????? }
>>> +??? if (cpufreq_avg_freq_supported(policy)) {
>>> +??????? ret = sysfs_create_file(&policy->kobj, &cpuinfo_avg_freq.attr);
>>> +??????? if (ret)
>>> +??????????? return ret;
>>> +??? }
>>> +
>>> ????? ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
>>> ????? if (ret)
>>> ????????? return ret;
>>> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
>>> index d4d2f4d1d7cb..a7b6c0ccf9bc 100644
>>> --- a/include/linux/cpufreq.h
>>> +++ b/include/linux/cpufreq.h
>>> @@ -1194,7 +1194,7 @@ static inline int 
>>> of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_
>>> ? }
>>> ? #endif
>>> -extern unsigned int arch_freq_get_on_cpu(int cpu);
>>> +extern int arch_freq_get_on_cpu(int cpu);
>>> ? #ifndef arch_set_freq_scale
>>> ? static __always_inline
>>



From krzk at kernel.org  Mon Dec 16 00:44:58 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 09:44:58 +0100
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>

On 14/12/2024 23:04, Ivaylo Ivanov wrote:
> Add samsung,exynos8895-hsi2c dedicated compatible for representing
> I2C of Exynos8895 SoC. Since there are I2C buses that aren't implemented
> as a part of USIv1 blocks, they only require a single clock.
> 
> Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
> ---
>  .../devicetree/bindings/i2c/i2c-exynos5.yaml  | 26 ++++++++++++++++---
>  1 file changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
> index cc8bba553..b029be88e 100644
> --- a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
> +++ b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
> @@ -25,6 +25,7 @@ properties:
>            - samsung,exynos5250-hsi2c    # Exynos5250 and Exynos5420
>            - samsung,exynos5260-hsi2c    # Exynos5260
>            - samsung,exynos7-hsi2c       # Exynos7
> +          - samsung,exynos8895-hsi2c
>            - samsung,exynosautov9-hsi2c
>        - items:
>            - enum:
> @@ -94,9 +95,28 @@ allOf:
>          - clock-names
>  
>      else:
> -      properties:
> -        clocks:
> -          maxItems: 1
> +      if:
> +        properties:
> +          compatible:
> +            contains:
> +              enum:
> +                - samsung,exynos8895-hsi2c
> +
> +      then:
> +        properties:
> +          clocks:

Missing minItems

> +            maxItems: 2
> +
> +          clock-names:

Ditto

> +            maxItems: 2
> +
> +        required:
> +          - clock-names
I don't understand why do you need second, same branch in if, basically
duplicating previous. But regardless of that, no nesting of ifs. Define
clocks for all variants explicitly.

Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec 16 00:46:02 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 09:46:02 +0100
Subject: [PATCH v1] arm64: dts: exynos8895: Add camera hsi2c nodes
In-Reply-To: <20241214220750.723354-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241214220750.723354-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <d75a63c9-5bfe-48b7-bb8f-bae415897f3b@kernel.org>

On 14/12/2024 23:07, Ivaylo Ivanov wrote:
> Add nodes for hsi2c1-4 (CAM0-3), which allows using them.
> 
> Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
> ---
>  arch/arm64/boot/dts/exynos/exynos8895.dtsi | 44 ++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos8895.dtsi b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
> index 90b318b2f..36657abfc 100644
> --- a/arch/arm64/boot/dts/exynos/exynos8895.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
> @@ -292,6 +292,50 @@ pinctrl_peric1: pinctrl at 10980000 {
>  			interrupts = <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>;
>  		};
>  
> +		hsi2c_1: i2c at 10990000 {
> +			compatible = "samsung,exynos8895-hsi2c";



There is no such compatible. Your changelog part or cover letter must
always explain where the missing bindings are.

Best regards,
Krzysztof


From maz at kernel.org  Mon Dec 16 00:51:38 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 16 Dec 2024 08:51:38 +0000
Subject: [PATCH 6.6 v1] KVM: arm64: Disable MPAM visibility by default and ignore VMM writes
In-Reply-To: <2024121528-refurbish-plausibly-31c7@gregkh>
References: <20241212151406.1436382-1-joey.gouly@arm.com>
	<2024121528-refurbish-plausibly-31c7@gregkh>
Message-ID: <86a5cwrox1.wl-maz@kernel.org>

On Sun, 15 Dec 2024 09:22:53 +0000,
Greg KH <gregkh at linuxfoundation.org> wrote:
> 
> On Thu, Dec 12, 2024 at 03:14:06PM +0000, Joey Gouly wrote:
> > From: James Morse <james.morse at arm.com>
> > 
> > commit 6685f5d572c22e1003e7c0d089afe1c64340ab1f upstream.
> > 
> > commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits in
> > ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to guests,
> > but didn't add trap handling. A previous patch supplied the missing trap
> > handling.
> > 
> > Existing VMs that have the MPAM field of ID_AA64PFR0_EL1 set need to
> > be migratable, but there is little point enabling the MPAM CPU
> > interface on new VMs until there is something a guest can do with it.
> > 
> > Clear the MPAM field from the guest's ID_AA64PFR0_EL1 and on hardware
> > that supports MPAM, politely ignore the VMMs attempts to set this bit.
> > 
> > Guests exposed to this bug have the sanitised value of the MPAM field,
> > so only the correct value needs to be ignored. This means the field
> > can continue to be used to block migration to incompatible hardware
> > (between MPAM=1 and MPAM=5), and the VMM can't rely on the field
> > being ignored.
> > 
> > Signed-off-by: James Morse <james.morse at arm.com>
> > Co-developed-by: Joey Gouly <joey.gouly at arm.com>
> > Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> > Reviewed-by: Gavin Shan <gshan at redhat.com>
> > Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> > Reviewed-by: Marc Zyngier <maz at kernel.org>
> > Link: https://lore.kernel.org/r/20241030160317.2528209-7-joey.gouly at arm.com
> > Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> > [ joey: fixed up merge conflict, no ID_FILTERED macro in 6.6 ]
> > Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> > Cc: stable at vger.kernel.org # 6.6.x
> > Cc: Vitaly Chikunov <vt at altlinux.org>
> > Link: https://lore.kernel.org/linux-arm-kernel/20241202045830.e4yy3nkvxtzaybxk at altlinux.org/
> > ---
> > 
> > This fixes an issue seen when using KVM with a 6.6 host kernel, and
> > newer (6.13+) kernels in the guest.
> > 
> > Tested with a stripped down version of set_id_regs from the original
> > patch series.
> 
> What about 6.12.y?  You can't just skip a stable tree, otherwise you
> will get a regression when you upgrade to 6.12.y, right?

Posted as [1].

	M.

[1] https://lore.kernel.org/r/20241216085002.334880-1-maz at kernel.org

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


From maz at kernel.org  Mon Dec 16 00:50:02 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 16 Dec 2024 08:50:02 +0000
Subject: [PATCH v6.12] KVM: arm64: Disable MPAM visibility by default and ignore VMM writes
Message-ID: <20241216085002.334880-1-maz@kernel.org>

From: James Morse <james.morse at arm.com>

commit 6685f5d572c22e1003e7c0d089afe1c64340ab1f upstream.

commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits in
ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to guests,
but didn't add trap handling. A previous patch supplied the missing trap
handling.

Existing VMs that have the MPAM field of ID_AA64PFR0_EL1 set need to
be migratable, but there is little point enabling the MPAM CPU
interface on new VMs until there is something a guest can do with it.

Clear the MPAM field from the guest's ID_AA64PFR0_EL1 and on hardware
that supports MPAM, politely ignore the VMMs attempts to set this bit.

Guests exposed to this bug have the sanitised value of the MPAM field,
so only the correct value needs to be ignored. This means the field
can continue to be used to block migration to incompatible hardware
(between MPAM=1 and MPAM=5), and the VMM can't rely on the field
being ignored.

Signed-off-by: James Morse <james.morse at arm.com>
Co-developed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Reviewed-by: Gavin Shan <gshan at redhat.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/r/20241030160317.2528209-7-joey.gouly at arm.com
Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
[maz: adapted to lack of ID_FILTERED()]
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: stable at vger.kernel.org
---
 arch/arm64/kvm/sys_regs.c | 55 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 52 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ff8c4e1b847ed..fbed433283c9b 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1535,6 +1535,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
 		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTEX);
 		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_DF2);
 		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_PFAR);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MPAM_frac);
 		break;
 	case SYS_ID_AA64PFR2_EL1:
 		/* We only expose FPMR */
@@ -1724,6 +1725,13 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
 
 	val &= ~ID_AA64PFR0_EL1_AMU_MASK;
 
+	/*
+	 * MPAM is disabled by default as KVM also needs a set of PARTID to
+	 * program the MPAMVPMx_EL2 PARTID remapping registers with. But some
+	 * older kernels let the guest see the ID bit.
+	 */
+	val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
+
 	return val;
 }
 
@@ -1834,6 +1842,42 @@ static int set_id_dfr0_el1(struct kvm_vcpu *vcpu,
 	return set_id_reg(vcpu, rd, val);
 }
 
+static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
+			       const struct sys_reg_desc *rd, u64 user_val)
+{
+	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+	u64 mpam_mask = ID_AA64PFR0_EL1_MPAM_MASK;
+
+	/*
+	 * Commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits
+	 * in ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to
+	 * guests, but didn't add trap handling. KVM doesn't support MPAM and
+	 * always returns an UNDEF for these registers. The guest must see 0
+	 * for this field.
+	 *
+	 * But KVM must also accept values from user-space that were provided
+	 * by KVM. On CPUs that support MPAM, permit user-space to write
+	 * the sanitizied value to ID_AA64PFR0_EL1.MPAM, but ignore this field.
+	 */
+	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
+		user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
+
+	return set_id_reg(vcpu, rd, user_val);
+}
+
+static int set_id_aa64pfr1_el1(struct kvm_vcpu *vcpu,
+			       const struct sys_reg_desc *rd, u64 user_val)
+{
+	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
+	u64 mpam_mask = ID_AA64PFR1_EL1_MPAM_frac_MASK;
+
+	/* See set_id_aa64pfr0_el1 for comment about MPAM */
+	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
+		user_val &= ~ID_AA64PFR1_EL1_MPAM_frac_MASK;
+
+	return set_id_reg(vcpu, rd, user_val);
+}
+
 /*
  * cpufeature ID register user accessors
  *
@@ -2377,7 +2421,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_ID_AA64PFR0_EL1),
 	  .access = access_id_reg,
 	  .get_user = get_id_reg,
-	  .set_user = set_id_reg,
+	  .set_user = set_id_aa64pfr0_el1,
 	  .reset = read_sanitised_id_aa64pfr0_el1,
 	  .val = ~(ID_AA64PFR0_EL1_AMU |
 		   ID_AA64PFR0_EL1_MPAM |
@@ -2385,7 +2429,12 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 		   ID_AA64PFR0_EL1_RAS |
 		   ID_AA64PFR0_EL1_AdvSIMD |
 		   ID_AA64PFR0_EL1_FP), },
-	ID_WRITABLE(ID_AA64PFR1_EL1, ~(ID_AA64PFR1_EL1_PFAR |
+	{ SYS_DESC(SYS_ID_AA64PFR1_EL1),
+	  .access	= access_id_reg,
+	  .get_user	= get_id_reg,
+	  .set_user	= set_id_aa64pfr1_el1,
+	  .reset	= kvm_read_sanitised_id_reg,
+	  .val		=	     ~(ID_AA64PFR1_EL1_PFAR |
 				       ID_AA64PFR1_EL1_DF2 |
 				       ID_AA64PFR1_EL1_MTEX |
 				       ID_AA64PFR1_EL1_THE |
@@ -2397,7 +2446,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 				       ID_AA64PFR1_EL1_RES0 |
 				       ID_AA64PFR1_EL1_MPAM_frac |
 				       ID_AA64PFR1_EL1_RAS_frac |
-				       ID_AA64PFR1_EL1_MTE)),
+				       ID_AA64PFR1_EL1_MTE), },
 	ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR),
 	ID_UNALLOCATED(4,3),
 	ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0),
-- 
2.39.2



From cristian.marussi at arm.com  Mon Dec 16 00:50:26 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 16 Dec 2024 08:50:26 +0000
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless
 scmi_bus_id.
In-Reply-To: <20241216073745.2973317-1-guomin_chen@sina.com>
References: <20241216073745.2973317-1-guomin_chen@sina.com>
Message-ID: <Z1_p0nU93PHJ4Sg_@pluto>

On Mon, Dec 16, 2024 at 03:37:45PM +0800, guomin_chen at sina.com wrote:
> From: guomin chen <guomin_chen at sina.com>
> 
> Currently, scmi_bus_id is only used to set scmi_dev.id,
> which in turn sets the SCMI device name. After removing
> scmi_bus_id, it is clearer and more meaningful to directly
> use the unique tuple [Parent name,device name, protocol] to 
> set the SCMI device name.
> 

Hi Guomin,

this same pTCH was NACKed(Rejected) a few days ago:

https://lore.kernel.org/arm-scmi/20241211134505.2218386-1-guomin_chen at sina.com/T/#u

...and you agreed that is not a simplification we can do (not to break
multuple instances...)...

..so why you are posting V2 now ?

Thanks,
Cristian

> Signed-off-by: guomin chen <guomin_chen at sina.com>
> ---
>  drivers/firmware/arm_scmi/bus.c    | 17 +++--------------
>  drivers/firmware/arm_scmi/driver.c |  4 ++--
>  2 files changed, 5 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
> index 157172a5f2b5..800e8ec9357c 100644
> --- a/drivers/firmware/arm_scmi/bus.c
> +++ b/drivers/firmware/arm_scmi/bus.c
> @@ -20,7 +20,6 @@
>  BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
>  EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
>  
> -static DEFINE_IDA(scmi_bus_id);
>  
>  static DEFINE_IDR(scmi_requested_devices);
>  /* Protect access to scmi_requested_devices */
> @@ -341,7 +340,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
>  	if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
>  		atomic_set(&scmi_syspower_registered, 0);
>  
> -	ida_free(&scmi_bus_id, scmi_dev->id);
>  	device_unregister(&scmi_dev->dev);
>  }
>  
> @@ -349,7 +347,7 @@ static struct scmi_device *
>  __scmi_device_create(struct device_node *np, struct device *parent,
>  		     int protocol, const char *name)
>  {
> -	int id, retval;
> +	int retval;
>  	struct scmi_device *scmi_dev;
>  
>  	/*
> @@ -387,20 +385,13 @@ __scmi_device_create(struct device_node *np, struct device *parent,
>  		return NULL;
>  	}
>  
> -	id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
> -	if (id < 0) {
> -		kfree_const(scmi_dev->name);
> -		kfree(scmi_dev);
> -		return NULL;
> -	}
> -
> -	scmi_dev->id = id;
>  	scmi_dev->protocol_id = protocol;
>  	scmi_dev->dev.parent = parent;
>  	device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
>  	scmi_dev->dev.bus = &scmi_bus_type;
>  	scmi_dev->dev.release = scmi_device_release;
> -	dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
> +	dev_set_name(&scmi_dev->dev, "scmi_dev.%s.%s.%d", dev_name(parent),
> +			scmi_dev->name, protocol);
>  
>  	retval = device_register(&scmi_dev->dev);
>  	if (retval)
> @@ -413,7 +404,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
>  	return scmi_dev;
>  put_dev:
>  	put_device(&scmi_dev->dev);
> -	ida_free(&scmi_bus_id, id);
>  	return NULL;
>  }
>  
> @@ -526,7 +516,6 @@ static void __exit scmi_bus_exit(void)
>  	 */
>  	scmi_devices_unregister();
>  	bus_unregister(&scmi_bus_type);
> -	ida_destroy(&scmi_bus_id);
>  }
>  module_exit(scmi_bus_exit);
>  
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index 1b5fb2c4ce86..bbf1f05f2be3 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -2641,8 +2641,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
>  	cinfo->max_msg_size = info->desc->max_msg_size;
>  
>  	/* Create a unique name for this transport device */
> -	snprintf(name, 32, "__scmi_transport_device_%s_%02X",
> -		 idx ? "rx" : "tx", prot_id);
> +	snprintf(name, 32, "__scmi_transport_device_%s",
> +		 idx ? "rx" : "tx");
>  	/* Create a uniquely named, dedicated transport device for this chan */
>  	tdev = scmi_device_create(of_node, info->dev, prot_id, name);
>  	if (!tdev) {
> -- 
> 2.47.1
> 


From maz at kernel.org  Mon Dec 16 00:52:04 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 16 Dec 2024 08:52:04 +0000
Subject: [PATCH 6.6 v1] KVM: arm64: Disable MPAM visibility by default and ignore VMM writes
In-Reply-To: <20241212151406.1436382-1-joey.gouly@arm.com>
References: <20241212151406.1436382-1-joey.gouly@arm.com>
Message-ID: <868qsgrowb.wl-maz@kernel.org>

On Thu, 12 Dec 2024 15:14:06 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> From: James Morse <james.morse at arm.com>
> 
> commit 6685f5d572c22e1003e7c0d089afe1c64340ab1f upstream.
> 
> commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits in
> ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to guests,
> but didn't add trap handling. A previous patch supplied the missing trap
> handling.
> 
> Existing VMs that have the MPAM field of ID_AA64PFR0_EL1 set need to
> be migratable, but there is little point enabling the MPAM CPU
> interface on new VMs until there is something a guest can do with it.
> 
> Clear the MPAM field from the guest's ID_AA64PFR0_EL1 and on hardware
> that supports MPAM, politely ignore the VMMs attempts to set this bit.
> 
> Guests exposed to this bug have the sanitised value of the MPAM field,
> so only the correct value needs to be ignored. This means the field
> can continue to be used to block migration to incompatible hardware
> (between MPAM=1 and MPAM=5), and the VMM can't rely on the field
> being ignored.
> 
> Signed-off-by: James Morse <james.morse at arm.com>
> Co-developed-by: Joey Gouly <joey.gouly at arm.com>
> Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> Reviewed-by: Gavin Shan <gshan at redhat.com>
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Reviewed-by: Marc Zyngier <maz at kernel.org>
> Link: https://lore.kernel.org/r/20241030160317.2528209-7-joey.gouly at arm.com
> Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> [ joey: fixed up merge conflict, no ID_FILTERED macro in 6.6 ]
> Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> Cc: stable at vger.kernel.org # 6.6.x
> Cc: Vitaly Chikunov <vt at altlinux.org>
> Link: https://lore.kernel.org/linux-arm-kernel/20241202045830.e4yy3nkvxtzaybxk at altlinux.org/

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

	M.

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


From patryk.wysocki at analyticsservices.pl  Mon Dec 16 01:01:01 2024
From: patryk.wysocki at analyticsservices.pl (Patryk Wysocki)
Date: Mon, 16 Dec 2024 09:01:01 GMT
Subject: Zapytanie ofertowe 
Message-ID: <20241216084501-0.1.i.3o3y.0.elqawmhfo0@analyticsservices.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
Patryk Wysocki


From andrej.picej at norik.com  Mon Dec 16 00:54:08 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 16 Dec 2024 09:54:08 +0100
Subject: [PATCH v7 1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for ti,lvds-vod-swing
In-Reply-To: <20241216085410.1968634-1-andrej.picej@norik.com>
References: <20241216085410.1968634-1-andrej.picej@norik.com>
Message-ID: <20241216085410.1968634-2-andrej.picej@norik.com>

Add properties which can be used to specify LVDS differential output
voltage. Since this also depends on near-end signal termination also
include property which sets this. LVDS differential output voltage is
specified with an array (min, max), which should match the one from
connected device.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes in v7:
- no change
Changes in v6:
- no change
Changes in v5:
- added Krzysztof's reviewed-by tag
Changes in v4:
- removed "additionalProperties: true" from the patch as it is not needed
Changes in v3:
- no change
Changes in v2:
- move LVDS port schema to a $defs and reference it from there
- properties are now defined in microvolts/ohms
- use 1 property for data-lane and 1 for clock-lane LVDS voltage swing
- add 1 property which sets LVDS near-end termination
- since major change was done change the authorship to myself
---
 .../bindings/display/bridge/ti,sn65dsi83.yaml | 34 +++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
index 48a97bb3e2e0..bad6f5c81b06 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
@@ -80,12 +80,12 @@ properties:
                   - const: 4
 
       port at 2:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-A output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
       port at 3:
-        $ref: /schemas/graph.yaml#/properties/port
         description: Video port for LVDS Channel-B output (panel or bridge).
+        $ref: '#/$defs/lvds-port'
 
     required:
       - port at 0
@@ -96,6 +96,36 @@ required:
   - reg
   - ports
 
+$defs:
+  lvds-port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    unevaluatedProperties: false
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          ti,lvds-termination-ohms:
+            description: The value of near end differential termination in ohms.
+            enum: [100, 200]
+            default: 200
+
+          ti,lvds-vod-swing-clock-microvolt:
+            description: LVDS diferential output voltage <min max> for clock
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
+          ti,lvds-vod-swing-data-microvolt:
+            description: LVDS diferential output voltage <min max> for data
+              lanes in microvolts.
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            minItems: 2
+            maxItems: 2
+
 allOf:
   - if:
       properties:
-- 
2.34.1



From andrej.picej at norik.com  Mon Dec 16 00:54:09 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 16 Dec 2024 09:54:09 +0100
Subject: [PATCH v7 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
In-Reply-To: <20241216085410.1968634-1-andrej.picej@norik.com>
References: <20241216085410.1968634-1-andrej.picej@norik.com>
Message-ID: <20241216085410.1968634-3-andrej.picej@norik.com>

Add a optional properties to change LVDS output voltage. This should not
be static as this depends mainly on the connected display voltage
requirement. We have three properties:
- "ti,lvds-termination-ohms", which sets near end termination,
- "ti,lvds-vod-swing-data-microvolt" and
- "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
output voltage for data and clock lanes. They are defined as an array
with min and max values. The appropriate bitfield will be set if
selected constraints can be met.

If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
end termination will be used. Selecting only one:
"ti,lvds-vod-swing-data-microvolt" or
"ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
constraint for only data/clock lanes will be met. Setting both is
recommended.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v7:
- decrement refcount of the endpoint in all error cases,
- add spaces to improve the readability of the long if statement conditions in
sn65dsi83_select_lvds_vod_swing.
Changes in v6:
- rework termination resistor logic, default is now set by resistor value, not
reg value,
- move setting lvds_vod_swing_conf to default value of 0x1 inside if statement
which checks if both properties are not set
Changes in v5:
- specify default values in sn65dsi83_parse_lvds_endpoint,
- move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
Changes in v4:
- fix typo in commit message bitfiled -> bitfield
- use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
of separate variables for channel A/B
- add more checks on return value of "of_property_read_u32_array"
Changes in v3:
- use microvolts for default array values 1000 mV -> 1000000 uV.
Changes in v2:
- use datasheet tables to get the proper configuration
- since major change was done change the authorship to myself
---
 drivers/gpu/drm/bridge/ti-sn65dsi83.c | 145 +++++++++++++++++++++++++-
 1 file changed, 142 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 57a7ed13f996..61019eec6e25 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -132,6 +132,16 @@
 #define  REG_IRQ_STAT_CHA_SOT_BIT_ERR		BIT(2)
 #define  REG_IRQ_STAT_CHA_PLL_UNLOCK		BIT(0)
 
+enum sn65dsi83_channel {
+	CHANNEL_A,
+	CHANNEL_B
+};
+
+enum sn65dsi83_lvds_term {
+	OHM_100,
+	OHM_200
+};
+
 enum sn65dsi83_model {
 	MODEL_SN65DSI83,
 	MODEL_SN65DSI84,
@@ -147,6 +157,8 @@ struct sn65dsi83 {
 	struct regulator		*vcc;
 	bool				lvds_dual_link;
 	bool				lvds_dual_link_even_odd_swap;
+	int				lvds_vod_swing_conf[2];
+	int				lvds_term_conf[2];
 };
 
 static const struct regmap_range sn65dsi83_readable_ranges[] = {
@@ -237,6 +249,36 @@ static const struct regmap_config sn65dsi83_regmap_config = {
 	.max_register = REG_IRQ_STAT,
 };
 
+static const int lvds_vod_swing_data_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 180000, 313000 },
+		{ 215000, 372000 },
+		{ 250000, 430000 },
+		{ 290000, 488000 },
+	},
+	{	/* 200 Ohm */
+		{ 150000, 261000 },
+		{ 200000, 346000 },
+		{ 250000, 428000 },
+		{ 300000, 511000 },
+	},
+};
+
+static const int lvds_vod_swing_clock_table[2][4][2] = {
+	{	/* 100 Ohm */
+		{ 140000, 244000 },
+		{ 168000, 290000 },
+		{ 195000, 335000 },
+		{ 226000, 381000 },
+	},
+	{	/* 200 Ohm */
+		{ 117000, 204000 },
+		{ 156000, 270000 },
+		{ 195000, 334000 },
+		{ 234000, 399000 },
+	},
+};
+
 static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
 {
 	return container_of(bridge, struct sn65dsi83, bridge);
@@ -435,12 +477,16 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
 		val |= REG_LVDS_FMT_LVDS_LINK_CFG;
 
 	regmap_write(ctx->regmap, REG_LVDS_FMT, val);
-	regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05);
+	regmap_write(ctx->regmap, REG_LVDS_VCOM,
+			REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
+			REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
 	regmap_write(ctx->regmap, REG_LVDS_LANE,
 		     (ctx->lvds_dual_link_even_odd_swap ?
 		      REG_LVDS_LANE_EVEN_ODD_SWAP : 0) |
-		     REG_LVDS_LANE_CHA_LVDS_TERM |
-		     REG_LVDS_LANE_CHB_LVDS_TERM);
+		     (ctx->lvds_term_conf[CHANNEL_A] ?
+			  REG_LVDS_LANE_CHA_LVDS_TERM : 0) |
+		     (ctx->lvds_term_conf[CHANNEL_B] ?
+			  REG_LVDS_LANE_CHB_LVDS_TERM : 0));
 	regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
 
 	le16val = cpu_to_le16(mode->hdisplay);
@@ -576,10 +622,103 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
 	.atomic_get_input_bus_fmts = sn65dsi83_atomic_get_input_bus_fmts,
 };
 
+static int sn65dsi83_select_lvds_vod_swing(struct device *dev,
+	u32 lvds_vod_swing_data[2], u32 lvds_vod_swing_clk[2], u8 lvds_term)
+{
+	int i;
+
+	for (i = 0; i <= 3; i++) {
+		if (lvds_vod_swing_data_table[lvds_term][i][0]  >= lvds_vod_swing_data[0] &&
+		    lvds_vod_swing_data_table[lvds_term][i][1]  <= lvds_vod_swing_data[1] &&
+		    lvds_vod_swing_clock_table[lvds_term][i][0] >= lvds_vod_swing_clk[0] &&
+		    lvds_vod_swing_clock_table[lvds_term][i][1] <= lvds_vod_swing_clk[1])
+			return i;
+	}
+
+	dev_err(dev, "failed to find appropriate LVDS_VOD_SWING configuration\n");
+	return -EINVAL;
+}
+
+static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
+{
+	struct device *dev = ctx->dev;
+	struct device_node *endpoint;
+	int endpoint_reg;
+	/* Set so the property can be freely selected if not defined */
+	u32 lvds_vod_swing_data[2] = { 0, 1000000 };
+	u32 lvds_vod_swing_clk[2] = { 0, 1000000 };
+	/* Set default near end terminataion to 200 Ohm */
+	u32 lvds_term = 200;
+	int lvds_vod_swing_conf;
+	int ret = 0;
+	int ret_data;
+	int ret_clock;
+
+	if (channel == CHANNEL_A)
+		endpoint_reg = 2;
+	else
+		endpoint_reg = 3;
+
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
+
+	of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
+	if (lvds_term == 100)
+		ctx->lvds_term_conf[channel] = OHM_100;
+	else if (lvds_term == 200)
+		ctx->lvds_term_conf[channel] = OHM_200;
+	else {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret_data = of_property_read_u32_array(endpoint, "ti,lvds-vod-swing-data-microvolt",
+					lvds_vod_swing_data, ARRAY_SIZE(lvds_vod_swing_data));
+	if (ret_data != 0 && ret_data != -EINVAL) {
+		ret = ret_data;
+		goto exit;
+	}
+
+	ret_clock = of_property_read_u32_array(endpoint, "ti,lvds-vod-swing-clock-microvolt",
+					lvds_vod_swing_clk, ARRAY_SIZE(lvds_vod_swing_clk));
+	if (ret_clock != 0 && ret_clock != -EINVAL) {
+		ret = ret_clock;
+		goto exit;
+	}
+
+	/* Use default value if both properties are NOT defined. */
+	if (ret_data == -EINVAL && ret_clock == -EINVAL)
+		lvds_vod_swing_conf = 0x1;
+
+	/* Use lookup table if any of the two properties is defined. */
+	if (!ret_data || !ret_clock) {
+		lvds_vod_swing_conf = sn65dsi83_select_lvds_vod_swing(dev, lvds_vod_swing_data,
+						lvds_vod_swing_clk, ctx->lvds_term_conf[channel]);
+		if (lvds_vod_swing_conf < 0) {
+			ret = lvds_vod_swing_conf;
+			goto exit;
+		}
+	}
+
+	ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
+	ret = 0;
+exit:
+	of_node_put(endpoint);
+	return ret;
+}
+
 static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
 {
 	struct drm_bridge *panel_bridge;
 	struct device *dev = ctx->dev;
+	int ret;
+
+	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A);
+	if (ret < 0)
+		return ret;
+
+	ret = sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_B);
+	if (ret < 0)
+		return ret;
 
 	ctx->lvds_dual_link = false;
 	ctx->lvds_dual_link_even_odd_swap = false;
-- 
2.34.1



From lorenzo at kernel.org  Mon Dec 16 00:54:54 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Mon, 16 Dec 2024 09:54:54 +0100
Subject: [PATCH net-next] net: airoha: Fix error patch in airoha_probe()
In-Reply-To: <Z1/Tng80hii4dBQU@mev-dev.igk.intel.com>
References: <20241215-airoha_probe-error-path-fix-v1-1-dd299122d343@kernel.org>
 <Z1/Tng80hii4dBQU@mev-dev.igk.intel.com>
Message-ID: <Z1_q3tnwtRBq-fQE@lore-desk>

> On Sun, Dec 15, 2024 at 06:36:35PM +0100, Lorenzo Bianconi wrote:
> > Do not run napi_disable if airoha_hw_init() fails since Tx/Rx napi
> > has not been started yet. In order to fix the issue, introduce
> > airoha_qdma_disable_napi routine and remove napi_disable in
> > airoha_hw_cleanup().
> > 
> > Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
> > Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
> > ---
> >  drivers/net/ethernet/mediatek/airoha_eth.c | 33 ++++++++++++++++++++++--------
> >  1 file changed, 25 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
> > index 6c683a12d5aa52dd9d966df123509075a989c0b3..5bbf5fee2802135ff6083233d0bda78f2ba5606a 100644
> > --- a/drivers/net/ethernet/mediatek/airoha_eth.c
> > +++ b/drivers/net/ethernet/mediatek/airoha_eth.c
> > @@ -2138,17 +2138,14 @@ static void airoha_hw_cleanup(struct airoha_qdma *qdma)
> >  		if (!qdma->q_rx[i].ndesc)
> >  			continue;
> >  
> > -		napi_disable(&qdma->q_rx[i].napi);
> >  		netif_napi_del(&qdma->q_rx[i].napi);
> >  		airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
> >  		if (qdma->q_rx[i].page_pool)
> >  			page_pool_destroy(qdma->q_rx[i].page_pool);
> >  	}
> >  
> > -	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
> > -		napi_disable(&qdma->q_tx_irq[i].napi);
> > +	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
> >  		netif_napi_del(&qdma->q_tx_irq[i].napi);
> > -	}
> >  
> >  	for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
> >  		if (!qdma->q_tx[i].ndesc)
> > @@ -2173,6 +2170,21 @@ static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
> >  	}
> >  }
> >  
> > +static void airoha_qdma_disable_napi(struct airoha_qdma *qdma)
> Nit: similar function for enabling napi is named airoha_qdma_start_napi()
> maybe stop here or enable there to be consistent.
> 
> Reviewed-by: Michal Swiatkowski <michal.swiatkowski at linux.intel.com>
> 
> Thanks

ack, I will fix it in v2.

Regards,
Lorenzo

> 
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
> > +		napi_disable(&qdma->q_tx_irq[i].napi);
> > +
> > +	for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
> > +		if (!qdma->q_rx[i].ndesc)
> > +			continue;
> > +
> > +		napi_disable(&qdma->q_rx[i].napi);
> > +	}
> > +}
> > +
> 
> [...]
-------------- 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/20241216/392865ae/attachment.sig>

From andrej.picej at norik.com  Mon Dec 16 00:54:10 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 16 Dec 2024 09:54:10 +0100
Subject: [PATCH v7 3/3] arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing
In-Reply-To: <20241216085410.1968634-1-andrej.picej@norik.com>
References: <20241216085410.1968634-1-andrej.picej@norik.com>
Message-ID: <20241216085410.1968634-4-andrej.picej@norik.com>

Set custom differential output voltage for LVDS, to fulfill requirements
of the connected display. LVDS differential voltage for data-lanes and
clock output has to be between 200 mV and 600 mV.
Driver sets 200 Ohm near-end termination by default.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
Changes in v7:
- no change
Changes in v6:
- no change
Changes in v5:
- no change
Changes in v4:
- no change
Changes in v3:
- no change
Changes in v2:
- use new properties from previous patches
---
 .../boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso     | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
index a9de42cf14be..8bf9cc553bea 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-peb-av-10.dtso
@@ -186,6 +186,8 @@ port at 2 {
 			reg = <2>;
 			bridge_out: endpoint {
 				remote-endpoint = <&panel_in>;
+				ti,lvds-vod-swing-clock-microvolt = <200000 600000>;
+				ti,lvds-vod-swing-data-microvolt = <200000 600000>;
 			};
 		};
 	};
-- 
2.34.1



From andrej.picej at norik.com  Mon Dec 16 00:54:07 2024
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 16 Dec 2024 09:54:07 +0100
Subject: [PATCH v7 0/3] SN65DSI83/4 lvds_vod_swing properties
Message-ID: <20241216085410.1968634-1-andrej.picej@norik.com>

Hi all,

The LVDS differential voltage swing can be specified as arrays of min, max
in microvolts. Two arrays, one for data-lanes and one for clock-lane can
be specified. Additionally, because LVDS voltage swing depends on near-end
termination this can now also be specified with separate property.

Driver goes through the tables, taken from datasheet [1] and selects the
appropriate configuration. If appropriate configuration can not be found
the probe fails. If these properties are not defined default values are
used as before.

This patch series depends on the patch
"[PATCH v2 11/15] arm64: dts: imx8mm-phyboard-polis: Add support for PEB-AV-10"
(https://lore.kernel.org/all/20241202072052.2195283-12-andrej.picej at norik.com/)
which is currently under review. Please apply the dependent series first before
applying this one.

v1 is at: https://lore.kernel.org/all/20241127103031.1007893-1-andrej.picej at norik.com/
v2 is at: https://lore.kernel.org/all/20241203085822.2475138-1-andrej.picej at norik.com/
v3 is at: https://lore.kernel.org/all/20241203110054.2506123-1-andrej.picej at norik.com/
v4 is at: https://lore.kernel.org/all/20241205134021.2592013-1-andrej.picej at norik.com/
v5 is at: https://lore.kernel.org/all/20241210091901.83028-1-andrej.picej at norik.com/
v6 is at: https://lore.kernel.org/all/20241212121712.214639-1-andrej.picej at norik.com/

[1] https://www.ti.com/lit/ds/symlink/sn65dsi83.pdf?ts=1732738773429&ref_url=https%253A%252F%252Fwww.mouser.co.uk%252F

Best regards,
Andrej

Andrej Picej (3):
  dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for
    ti,lvds-vod-swing
  drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
  arm64: dts: imx8mm-phyboard-polis-peb-av-10: Set lvds-vod-swing

 .../bindings/display/bridge/ti,sn65dsi83.yaml |  34 +++-
 .../imx8mm-phyboard-polis-peb-av-10.dtso      |   2 +
 drivers/gpu/drm/bridge/ti-sn65dsi83.c         | 145 +++++++++++++++++-
 3 files changed, 176 insertions(+), 5 deletions(-)

-- 
2.34.1



From ck.hu at mediatek.com  Mon Dec 16 00:57:24 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 16 Dec 2024 08:57:24 +0000
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
Message-ID: <803bc2bd802506635dfa9ea9b26a6ca40a7f4912.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit and that also poses a slight
> difference between the V2 and V1 controllers in how they handle
> Hotplug Detection (HPD).
> 
> While the v1 controller was using the CEC controller to check
> HDMI cable connection and disconnection, in this driver the v2
> one does not.
> 
> This is due to the fact that on parts with v2 designs, like the
> MT8195 SoC, there is one CEC controller shared between the HDMI
> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> adding support to use the CEC HW to wake up the HDMI controllers
> it is necessary to have support for one TX, one RX *and* for both
> at the same time.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static int mtk_hdmi_v2_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)
> +{

I would like v1 and v2 has the same behavior.
Why v2 has atomic check but v1 has no?
If this is better to have, add atomic check to v1, and this function would be common function.

Regards,
CK

> +       return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
> +                                                     conn_state->state);
> +}
> +



From dmitry.baryshkov at linaro.org  Mon Dec 16 00:57:41 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 10:57:41 +0200
Subject: [PATCH v2 03/11] drm/rockchip: analogix_dp: Add support for
 RK3588
In-Reply-To: <20241216031225.3746-4-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-4-damon.ding@rock-chips.com>
Message-ID: <gwogudb5vae7wu452zwuqmdlyaibenoso4f5pjmu3uttckhy2w@shndol4mz5n4>

On Mon, Dec 16, 2024 at 11:12:17AM +0800, Damon Ding wrote:
> RK3588 integrates the analogix eDP 1.3 TX controller IP and the HDMI/eDP
> TX Combo PHY based on a Samsung IP block, and there are also two
> independent eDP display interface on RK3588 Soc.
> 
> Add just the basic support for now, i.e. RGB output up to 4K at 60Hz, without
> the tests of audio, PSR and other eDP 1.3 specific features.
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> 
> ---
> 
> Changes in v2:
> - Add support for the other eDP output edp1
> ---
>  .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 82 ++++++++++++++++---
>  include/drm/bridge/analogix_dp.h              |  3 +-
>  2 files changed, 74 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index 871606a31ef1..4c9a55776ada 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -51,10 +51,12 @@ struct rockchip_grf_reg_field {
>  /**
>   * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
>   * @lcdc_sel: grf register field of lcdc_sel
> + * @edp_mode: grf register field of edp_mode
>   * @chip_type: specific chip type
>   */
>  struct rockchip_dp_chip_data {
>  	const struct rockchip_grf_reg_field lcdc_sel;
> +	const struct rockchip_grf_reg_field edp_mode;
>  	u32	chip_type;
>  };
>  
> @@ -134,12 +136,21 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
>  		return ret;
>  	}
>  
> +	ret = rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 1);
> +	if (ret != 0)
> +		DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);

Is it to be called for non-eDP hosts too? Or for older hosts?

> +
>  	return ret;
>  }
>  
>  static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
>  {
>  	struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
> +	int ret;
> +
> +	ret = rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 0);
> +	if (ret != 0)
> +		DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);

Same question.

>  
>  	clk_disable_unprepare(dp->pclk);
>  
> @@ -203,6 +214,10 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
>  	struct rockchip_dp_device *dp = encoder_to_dp(encoder);
>  	struct drm_crtc *crtc;
>  	struct drm_crtc_state *old_crtc_state;
> +	struct of_endpoint endpoint;
> +	struct device_node *remote_port, *remote_port_parent;
> +	char name[32];
> +	u32 port_id;
>  	int ret;
>  
>  	crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
> @@ -220,13 +235,27 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
>  		return;
>  	}
>  
> -	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
> +	ret = drm_of_encoder_active_endpoint(dp->dev->of_node, encoder, &endpoint);
>  	if (ret < 0)
>  		return;
>  
> -	DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
> +	remote_port_parent = of_graph_get_remote_port_parent(endpoint.local_node);
> +	if (remote_port_parent) {
> +		if (of_get_child_by_name(remote_port_parent, "ports")) {
> +			remote_port = of_graph_get_remote_port(endpoint.local_node);
> +			of_property_read_u32(remote_port, "reg", &port_id);
> +			of_node_put(remote_port);
> +			sprintf(name, "%s vp%d", remote_port_parent->full_name, port_id);
> +		} else {
> +			sprintf(name, "%s %s",
> +				remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
> +		}
> +		of_node_put(remote_port_parent);
> +
> +		DRM_DEV_DEBUG(dp->dev, "%s output to edp\n", name);
> +	}

The "output to dp" message got dropped. Is it expected?

>  
> -	ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, ret);
> +	ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, endpoint.id);
>  	if (ret != 0)
>  		DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
>  
> @@ -396,6 +425,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
>  	const struct rockchip_dp_chip_data *dp_data;
>  	struct drm_panel *panel = NULL;
>  	struct rockchip_dp_device *dp;
> +	int id, i;
>  	int ret;
>  
>  	dp_data = of_device_get_match_data(dev);
> @@ -410,9 +440,22 @@ static int rockchip_dp_probe(struct platform_device *pdev)
>  	if (!dp)
>  		return -ENOMEM;
>  
> +	id = of_alias_get_id(dev->of_node, "edp");
> +	if (id < 0)
> +		id = 0;

Alias is not documented.

Please check how other platforms handle device -> ID conversion and
consider following it (yes, the best option currently known is to
hardcode bus addresses into the driver data).

> +
> +	i = 0;
> +	while (is_rockchip(dp_data[i].chip_type))
> +		i++;
> +
> +	if (id >= i) {
> +		DRM_DEV_ERROR(dev, "invalid edp id: %d\n", id);
> +		return -ENODEV;
> +	}

Is it applicable to non-eDP case?

> +
>  	dp->dev = dev;
>  	dp->adp = ERR_PTR(-ENODEV);
> -	dp->data = dp_data;
> +	dp->data = &dp_data[id];
>  	dp->plat_data.panel = panel;
>  	dp->plat_data.dev_type = dp->data->chip_type;
>  	dp->plat_data.power_on = rockchip_dp_poweron;
> @@ -464,19 +507,38 @@ static int rockchip_dp_resume(struct device *dev)
>  static DEFINE_RUNTIME_DEV_PM_OPS(rockchip_dp_pm_ops, rockchip_dp_suspend,
>  		rockchip_dp_resume, NULL);
>  
> -static const struct rockchip_dp_chip_data rk3399_edp = {
> -	.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
> -	.chip_type = RK3399_EDP,
> +static const struct rockchip_dp_chip_data rk3399_edp[] = {
> +	{
> +		.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
> +		.chip_type = RK3399_EDP,
> +	},
> +	{ /* sentinel */ }
> +};
> +
> +static const struct rockchip_dp_chip_data rk3288_dp[] = {
> +	{
> +		.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
> +		.chip_type = RK3288_DP,
> +	},
> +	{ /* sentinel */ }
>  };
>  
> -static const struct rockchip_dp_chip_data rk3288_dp = {
> -	.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
> -	.chip_type = RK3288_DP,
> +static const struct rockchip_dp_chip_data rk3588_edp[] = {
> +	{
> +		.edp_mode = GRF_REG_FIELD(0x0000, 0, 0),
> +		.chip_type = RK3588_EDP,
> +	},
> +	{
> +		.edp_mode = GRF_REG_FIELD(0x0004, 0, 0),
> +		.chip_type = RK3588_EDP,
> +	},
> +	{ /* sentinel */ }
>  };
>  
>  static const struct of_device_id rockchip_dp_dt_ids[] = {
>  	{.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp },
>  	{.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp },
> +	{.compatible = "rockchip,rk3588-edp", .data = &rk3588_edp },
>  	{}
>  };
>  MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
> diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
> index 6002c5666031..54086cb2d97d 100644
> --- a/include/drm/bridge/analogix_dp.h
> +++ b/include/drm/bridge/analogix_dp.h
> @@ -15,11 +15,12 @@ enum analogix_dp_devtype {
>  	EXYNOS_DP,
>  	RK3288_DP,
>  	RK3399_EDP,
> +	RK3588_EDP,
>  };
>  
>  static inline bool is_rockchip(enum analogix_dp_devtype type)
>  {
> -	return type == RK3288_DP || type == RK3399_EDP;
> +	return type == RK3288_DP || type == RK3399_EDP || type == RK3588_EDP;
>  }
>  
>  struct analogix_dp_plat_data {
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Mon Dec 16 01:00:48 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 11:00:48 +0200
Subject: [PATCH v2 04/11] phy: phy-rockchip-samsung-hdptx: Add support
 for eDP mode
In-Reply-To: <20241216031225.3746-5-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-5-damon.ding@rock-chips.com>
Message-ID: <3amy575wrx65kwf2kh5t2vx2f6vugq2bq3t6orpqlmbvnmq7oo@4mvt2lwgg3fh>

On Mon, Dec 16, 2024 at 11:12:18AM +0800, Damon Ding wrote:
> Add basic support for RBR/HBR/HBR2 link rates, and the voltage swing and
> pre-emphasis configurations of each link rate have been verified according
> to the eDP 1.3 requirements.
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> 
> ---
> 
> Changes in v2:
> - Add the module author
> ---
>  .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 937 +++++++++++++++++-
>  1 file changed, 894 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index 9f084697dd05..8dd0de267d10 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -25,6 +25,7 @@
>  #define HDPTX_I_PLL_EN			BIT(7)
>  #define HDPTX_I_BIAS_EN			BIT(6)
>  #define HDPTX_I_BGR_EN			BIT(5)
> +#define HDPTX_MODE_SEL			BIT(0)
>  #define GRF_HDPTX_STATUS		0x80
>  #define HDPTX_O_PLL_LOCK_DONE		BIT(3)
>  #define HDPTX_O_PHY_CLK_RDY		BIT(2)
> @@ -44,6 +45,7 @@
>  #define LANE_REG(n)			HDTPX_REG(n, 0300, 062d)
>  
>  /* CMN_REG(0008) */
> +#define OVRD_LCPLL_EN_MASK		BIT(7)
>  #define LCPLL_EN_MASK			BIT(6)
>  #define LCPLL_LCVCO_MODE_EN_MASK	BIT(4)
>  /* CMN_REG(001e) */
> @@ -61,49 +63,110 @@
>  /* CMN_REG(002f) */
>  #define LCPLL_SDC_DENOMINATOR_MASK	GENMASK(7, 2)
>  #define LCPLL_SDC_NDIV_RSTN		BIT(0)
> +/* CMN_REG(003c) */
> +#define ANA_LCPLL_RESERVED7_MASK	BIT(7)
>  /* CMN_REG(003d) */
> +#define OVRD_ROPLL_EN_MASK		BIT(7)
> +#define ROPLL_EN_MASK			BIT(6)
>  #define ROPLL_LCVCO_EN			BIT(4)
> +/* CMN_REG(0046) */
> +#define ROPLL_ANA_CPP_CTRL_COARSE_MASK	GENMASK(7, 4)
> +#define ROPLL_ANA_CPP_CTRL_FINE_MASK	GENMASK(3, 0)
> +/* CMN_REG(0047) */
> +#define ROPLL_ANA_LPF_C_SEL_COARSE_MASK	GENMASK(5, 3)
> +#define ROPLL_ANA_LPF_C_SEL_FINE_MASK	GENMASK(2, 0)
>  /* CMN_REG(004e) */
>  #define ROPLL_PI_EN			BIT(5)
> +/* CMN_REG(0051) */
> +#define ROPLL_PMS_MDIV_MASK		GENMASK(7, 0)
> +/* CMN_REG(0055) */
> +#define ROPLL_PMS_MDIV_AFC_MASK		GENMASK(7, 0)
> +/* CMN_REG(0059) */
> +#define ANA_ROPLL_PMS_PDIV_MASK		GENMASK(7, 4)
> +#define ANA_ROPLL_PMS_REFDIV_MASK	GENMASK(3, 0)
> +/* CMN_REG(005a) */
> +#define ROPLL_PMS_SDIV_RBR_MASK		GENMASK(7, 4)
> +#define ROPLL_PMS_SDIV_HBR_MASK		GENMASK(3, 0)
> +/* CMN_REG(005b) */
> +#define ROPLL_PMS_SDIV_HBR2_MASK	GENMASK(7, 4)
>  /* 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)

You have mixed the redefinition of existing bitfields with addition of
new ones. Please split them into separate patches: one for each of
corrections (be sure to specify Fixes tag as required), one for generic
renaming and one for the new platform and new registers / new bitfields)

> +#define OVRD_ROPLL_SDM_RSTN_MASK	BIT(5)
> +#define ROPLL_SDM_RSTN_MASK		BIT(4)
> +#define ROPLL_SDC_FRAC_EN_RBR_MASK	BIT(3)
> +#define ROPLL_SDC_FRAC_EN_HBR_MASK	BIT(2)
> +#define ROPLL_SDC_FRAC_EN_HBR2_MASK	BIT(1)
> +/* CMN_REG(005f) */
> +#define OVRD_ROPLL_SDC_RSTN_MASK	BIT(5)
> +#define ROPLL_SDC_RSTN_MASK		BIT(4)
> +/* CMN_REG(0060)  */
> +#define ROPLL_SDM_DENOMINATOR_MASK	GENMASK(7, 0)
>  /* CMN_REG(0064) */
>  #define ROPLL_SDM_NUM_SIGN_RBR_MASK	BIT(3)
> +#define ROPLL_SDM_NUM_SIGN_HBR_MASK	BIT(2)
> +#define ROPLL_SDM_NUM_SIGN_HBR2_MASK	BIT(1)
> +/* CMN_REG(0065) */
> +#define ROPLL_SDM_NUM_MASK		GENMASK(7, 0)
>  /* CMN_REG(0069) */
>  #define ROPLL_SDC_N_RBR_MASK		GENMASK(2, 0)
> +/* CMN_REG(006a) */
> +#define ROPLL_SDC_N_HBR_MASK		GENMASK(5, 3)
> +#define ROPLL_SDC_N_HBR2_MASK		GENMASK(2, 0)
> +/* CMN_REG(006b) */
> +#define ROPLL_SDC_N_HBR3_MASK		GENMASK(3, 1)
> +/* CMN_REG(006c) */
> +#define ROPLL_SDC_NUM_MASK		GENMASK(5, 0)
> +/* cmn_reg0070 */
> +#define ROPLL_SDC_DENO_MASK		GENMASK(5, 0)
>  /* CMN_REG(0074) */
> -#define ROPLL_SDC_NDIV_RSTN		BIT(2)
> -#define ROPLL_SSC_EN			BIT(0)
> +#define OVRD_ROPLL_SDC_NDIV_RSTN_MASK	BIT(3)
> +#define ROPLL_SDC_NDIV_RSTN_MASK	BIT(2)
> +#define OVRD_ROPLL_SSC_EN_MASK		BIT(1)
> +#define ROPLL_SSC_EN_MASK		BIT(0)
> +/* CMN_REG(0075) */
> +#define ANA_ROPLL_SSC_FM_DEVIATION_MASK	GENMASK(5, 0)
> +/* CMN_REG(0076) */
> +#define ANA_ROPLL_SSC_FM_FREQ_MASK	GENMASK(6, 2)
> +/* CMN_REG(0077) */
> +#define ANA_ROPLL_SSC_CLK_DIV_SEL_MASK	GENMASK(6, 3)
>  /* CMN_REG(0081) */
> -#define OVRD_PLL_CD_CLK_EN		BIT(8)
> -#define PLL_CD_HSCLK_EAST_EN		BIT(0)
> +#define ANA_PLL_CD_TX_SER_RATE_SEL_MASK	BIT(3)
> +#define ANA_PLL_CD_HSCLK_WEST_EN_MASK	BIT(1)
> +#define ANA_PLL_CD_HSCLK_EAST_EN_MASK	BIT(0)
> +/* CMN_REG(0082) */
> +#define ANA_PLL_CD_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
> +/* CMN_REG(0083) */
> +#define ANA_PLL_CD_VREG_ICTRL_MASK	GENMASK(6, 5)
> +/* CMN_REG(0084) */
> +#define PLL_LCRO_CLK_SEL_MASK		BIT(5)
> +/* CMN_REG(0085) */
> +#define ANA_PLL_SYNC_LOSS_DET_MODE_MASK	GENMASK(1, 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)
> +#define ANA_PLL_FRL_MODE_EN_MASK	BIT(3)
> +#define ANA_PLL_TX_HS_CLK_EN_MASK	BIT(2)
>  /* CMN_REG(0089) */
>  #define LCPLL_ALONE_MODE		BIT(1)
> +/* CMN_REG(0095) */
> +#define DP_TX_LINK_BW_MASK		GENMASK(1, 0)
>  /* CMN_REG(0097) */
> -#define DIG_CLK_SEL			BIT(1)
> -#define ROPLL_REF			BIT(1)
> -#define LCPLL_REF			0
> +#define DIG_CLK_SEL_MASK		BIT(1)
> +#define LCPLL_REF			BIT(1)
> +#define ROPLL_REF			0
>  /* CMN_REG(0099) */
> +#define SSC_EN_MASK			GENMASK(7, 6)
>  #define CMN_ROPLL_ALONE_MODE		BIT(2)
>  #define ROPLL_ALONE_MODE		BIT(2)
>  /* CMN_REG(009a) */
> -#define HS_SPEED_SEL			BIT(0)
> +#define HS_SPEED_SEL_MASK		BIT(0)
>  #define DIV_10_CLOCK			BIT(0)
>  /* CMN_REG(009b) */
> -#define IS_SPEED_SEL			BIT(4)
> +#define LS_SPEED_SEL_MASK		BIT(4)
>  #define LINK_SYMBOL_CLOCK		BIT(4)
>  #define LINK_SYMBOL_CLOCK1_2		0
>  
> @@ -118,6 +181,8 @@
>  /* SB_REG(0104) */
>  #define OVRD_SB_EN_MASK			BIT(5)
>  #define SB_EN_MASK			BIT(4)
> +#define OVRD_SB_AUX_EN_MASK		BIT(1)
> +#define SB_AUX_EN_MASK			BIT(0)
>  /* SB_REG(0105) */
>  #define OVRD_SB_EARC_CMDC_EN_MASK	BIT(6)
>  #define SB_EARC_CMDC_EN_MASK		BIT(5)
> @@ -126,6 +191,8 @@
>  #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(010d) */
> +#define ANA_SB_DMRX_LPBK_DATA_MASK	BIT(4)
>  /* SB_REG(010f) */
>  #define OVRD_SB_VREG_EN_MASK		BIT(7)
>  #define SB_VREG_EN_MASK			BIT(6)
> @@ -133,6 +200,7 @@
>  #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_OUT_SEL_MASK	BIT(1)
>  #define ANA_SB_VREG_REF_SEL_MASK	BIT(0)
>  /* SB_REG(0113) */
>  #define SB_RX_RCAL_OPT_CODE_MASK	GENMASK(5, 4)
> @@ -147,13 +215,24 @@
>  #define AFC_RSTN_DELAY_TIME_MASK	GENMASK(6, 4)
>  /* SB_REG(0117) */
>  #define FAST_PULSE_TIME_MASK		GENMASK(3, 0)
> +/* SB_REG(0118) */
> +#define SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK	GENMASK(7, 0)
> +/* SB_REG(011a) */
> +#define SB_TG_CNT_RUN_NO_7_0_MASK	GENMASK(7, 0)
>  /* SB_REG(011b) */
>  #define SB_EARC_SIG_DET_BYPASS_MASK	BIT(4)
>  #define SB_AFC_TOL_MASK			GENMASK(3, 0)
> +/* SB_REG(011c) */
> +#define SB_AFC_STB_NUM_MASK		GENMASK(3, 0)
> +/* SB_REG(011d) */
> +#define SB_TG_OSC_CNT_MIN_MASK		GENMASK(7, 0)
> +/* SB_REG(011e) */
> +#define SB_TG_OSC_CNT_MAX_MASK		GENMASK(7, 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_AUX_EN_IN_MASK		BIT(7)
>  #define SB_EARC_EN_MASK			BIT(1)
>  #define SB_EARC_AFC_EN_MASK		BIT(2)
>  /* SB_REG(0123) */
> @@ -165,35 +244,65 @@
>  #define HDMI_MODE			BIT(2)
>  #define HDMI_TMDS_FRL_SEL		BIT(1)
>  /* LNTOP_REG(0206) */
> -#define DATA_BUS_SEL			BIT(0)
> +#define DATA_BUS_WIDTH_MASK		GENMASK(2, 1)
> +#define DATA_BUS_WIDTH_SEL_MASK		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)
> +/* LANE_REG(0301) */
> +#define OVRD_LN_TX_DRV_EI_EN_MASK	BIT(7)
> +#define LN_TX_DRV_EI_EN_MASK		BIT(6)
> +/* LANE_REG(0303) */
> +#define OVRD_LN_TX_DRV_LVL_CTRL_MASK	BIT(5)
> +#define LN_TX_DRV_LVL_CTRL_MASK		GENMASK(4, 0)
> +/* LANE_REG(0304)  */
> +#define OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK	BIT(4)
> +#define LN_TX_DRV_POST_LVL_CTRL_MASK	GENMASK(3, 0)
> +/* LANE_REG(0305) */
> +#define OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK	BIT(6)
> +#define LN_TX_DRV_PRE_LVL_CTRL_MASK	GENMASK(5, 2)
> +/* LANE_REG(0306) */
> +#define LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK	GENMASK(7, 5)
> +#define LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK	GENMASK(4, 2)
> +#define LN_ANA_TX_DRV_ACCDRV_EN_MASK	BIT(0)
> +/* LANE_REG(0307) */
> +#define LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK	BIT(6)
> +#define LN_ANA_TX_DRV_ACCDRV_CTRL_MASK	GENMASK(5, 3)
> +/* LANE_REG(030a) */
> +#define LN_ANA_TX_JEQ_EN_MASK		BIT(4)
> +#define LN_TX_JEQ_EVEN_CTRL_RBR_MASK	GENMASK(3, 0)
> +/* LANE_REG(030b) */
> +#define LN_TX_JEQ_EVEN_CTRL_HBR_MASK	GENMASK(7, 4)
> +#define LN_TX_JEQ_EVEN_CTRL_HBR2_MASK	GENMASK(3, 0)
> +/* LANE_REG(030c) */
> +#define LN_TX_JEQ_ODD_CTRL_RBR_MASK	GENMASK(3, 0)
> +/* LANE_REG(030d) */
> +#define LN_TX_JEQ_ODD_CTRL_HBR_MASK	GENMASK(7, 4)
> +#define LN_TX_JEQ_ODD_CTRL_HBR2_MASK	GENMASK(3, 0)
> +/* LANE_REG(0310) */
> +#define LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK	GENMASK(1, 0)
> +/* LANE_REG(0311) */
> +#define LN_TX_SER_40BIT_EN_RBR_MASK	BIT(3)
> +#define LN_TX_SER_40BIT_EN_HBR_MASK	BIT(2)
> +#define LN_TX_SER_40BIT_EN_HBR2_MASK	BIT(1)
> +/* LANE_REG(0316) */
> +#define LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
> +/* LANE_REG(031B) */
> +#define LN_ANA_TX_RESERVED_MASK		GENMASK(7, 0)
> +/* LANE_REG(031e) */
> +#define LN_POLARITY_INV_MASK		BIT(2)
> +#define LN_LANE_MODE_MASK		BIT(1)
>  
>  #define HDMI20_MAX_RATE			600000000
>  
> +enum dp_link_rate {
> +	DP_BW_RBR,
> +	DP_BW_HBR,
> +	DP_BW_HBR2,
> +};
> +
>  struct lcpll_config {
>  	u32 bit_rate;
>  	u8 lcvco_mode_en;
> @@ -255,6 +364,19 @@ struct ropll_config {
>  	u8 cd_tx_ser_rate_sel;
>  };
>  
> +struct tx_drv_ctrl {
> +	u8 tx_drv_lvl_ctrl;
> +	u8 tx_drv_post_lvl_ctrl;
> +	u8 ana_tx_drv_idrv_idn_ctrl;
> +	u8 ana_tx_drv_idrv_iup_ctrl;
> +	u8 ana_tx_drv_accdrv_en;
> +	u8 ana_tx_drv_accdrv_ctrl;
> +	u8 tx_drv_pre_lvl_ctrl;
> +	u8 ana_tx_jeq_en;
> +	u8 tx_jeq_even_ctrl;
> +	u8 tx_jeq_odd_ctrl;
> +};
> +
>  enum rk_hdptx_reset {
>  	RST_PHY = 0,
>  	RST_APB,
> @@ -560,6 +682,90 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
>  	REG_SEQ0(LANE_REG(0606), 0x1c),
>  };
>  
> +static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = {
> +	/* voltage swing 0, pre-emphasis 0->3 */
> +	{
> +		{ 0x2, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +		{ 0x4, 0x3, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0x7, 0x6, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
> +	},
> +
> +	/* voltage swing 1, pre-emphasis 0->2 */
> +	{
> +		{ 0x4, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +		{ 0x9, 0x5, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0xc, 0x8, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
> +	},
> +
> +	/* voltage swing 2, pre-emphasis 0->1 */
> +	{
> +		{ 0x8, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +		{ 0xc, 0x5, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
> +	},
> +
> +	/* voltage swing 3, pre-emphasis 0 */
> +	{
> +		{ 0xb, 0x0, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +	}
> +};
> +
> +static struct tx_drv_ctrl tx_drv_ctrl_hbr[4][4] = {
> +	/* voltage swing 0, pre-emphasis 0->3 */
> +	{
> +		{ 0x2, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +		{ 0x5, 0x4, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0x9, 0x8, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
> +	},
> +
> +	/* voltage swing 1, pre-emphasis 0->2 */
> +	{
> +		{ 0x6, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +		{ 0xa, 0x6, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0xc, 0x8, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
> +	},
> +
> +	/* voltage swing 2, pre-emphasis 0->1 */
> +	{
> +		{ 0x9, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +		{ 0xd, 0x6, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
> +	},
> +
> +	/* voltage swing 3, pre-emphasis 0 */
> +	{
> +		{ 0xc, 0x1, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +	}
> +};
> +
> +static struct tx_drv_ctrl tx_drv_ctrl_hbr2[4][4] = {
> +	/* voltage swing 0, pre-emphasis 0->3 */
> +	{
> +		{ 0x2, 0x1, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0x5, 0x4, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0x9, 0x8, 0x4, 0x6, 0x1, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
> +	},
> +
> +	/* voltage swing 1, pre-emphasis 0->2 */
> +	{
> +		{ 0x6, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +		{ 0xb, 0x7, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
> +		{ 0xd, 0x9, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
> +	},
> +
> +	/* voltage swing 2, pre-emphasis 0->1 */
> +	{
> +		{ 0x8, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +		{ 0xc, 0x6, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
> +	},
> +
> +	/* voltage swing 3, pre-emphasis 0 */
> +	{
> +		{ 0xb, 0x0, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
> +	}
> +};
> +
>  static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
>  {
>  	switch (reg) {
> @@ -911,11 +1117,297 @@ static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)
>  	return ret;
>  }
>  
> +static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx)
> +{
> +	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
> +	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
> +	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
> +
> +	reset_control_assert(hdptx->rsts[RST_APB].rstc);
> +	udelay(10);
> +	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
> +
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0301),
> +			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
> +			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
> +			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0401),
> +			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
> +			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
> +			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0501),
> +			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
> +			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
> +			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0601),
> +			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
> +			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
> +			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
> +
> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +		     HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x0));
> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +		     HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x0));
> +}
> +
> +static void rk_hdptx_dp_pll_init(struct rk_hdptx_phy *hdptx)
> +{
> +	regmap_update_bits(hdptx->regmap, CMN_REG(003c), ANA_LCPLL_RESERVED7_MASK,
> +			   FIELD_PREP(ANA_LCPLL_RESERVED7_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0046),
> +			   ROPLL_ANA_CPP_CTRL_COARSE_MASK | ROPLL_ANA_CPP_CTRL_FINE_MASK,
> +			   FIELD_PREP(ROPLL_ANA_CPP_CTRL_COARSE_MASK, 0xe) |
> +			   FIELD_PREP(ROPLL_ANA_CPP_CTRL_FINE_MASK, 0xe));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0047),
> +			   ROPLL_ANA_LPF_C_SEL_COARSE_MASK |
> +			   ROPLL_ANA_LPF_C_SEL_FINE_MASK,
> +			   FIELD_PREP(ROPLL_ANA_LPF_C_SEL_COARSE_MASK, 0x4) |
> +			   FIELD_PREP(ROPLL_ANA_LPF_C_SEL_FINE_MASK, 0x4));
> +
> +	regmap_write(hdptx->regmap, CMN_REG(0051), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x87));
> +	regmap_write(hdptx->regmap, CMN_REG(0052), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x71));
> +	regmap_write(hdptx->regmap, CMN_REG(0053), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x71));
> +
> +	regmap_write(hdptx->regmap, CMN_REG(0055),
> +		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x87));
> +	regmap_write(hdptx->regmap, CMN_REG(0056),
> +		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x71));
> +	regmap_write(hdptx->regmap, CMN_REG(0057),
> +		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x71));
> +
> +	regmap_write(hdptx->regmap, CMN_REG(0059),
> +		     FIELD_PREP(ANA_ROPLL_PMS_PDIV_MASK, 0x1) |
> +		     FIELD_PREP(ANA_ROPLL_PMS_REFDIV_MASK, 0x1));
> +	regmap_write(hdptx->regmap, CMN_REG(005a),
> +		     FIELD_PREP(ROPLL_PMS_SDIV_RBR_MASK, 0x3) |
> +		     FIELD_PREP(ROPLL_PMS_SDIV_HBR_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(005b), ROPLL_PMS_SDIV_HBR2_MASK,
> +			   FIELD_PREP(ROPLL_PMS_SDIV_HBR2_MASK, 0x0));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,
> +			   FIELD_PREP(ROPLL_SDM_EN_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e),
> +			   OVRD_ROPLL_SDM_RSTN_MASK | ROPLL_SDM_RSTN_MASK,
> +			   FIELD_PREP(OVRD_ROPLL_SDM_RSTN_MASK, 0x1) |
> +			   FIELD_PREP(ROPLL_SDM_RSTN_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_RBR_MASK,
> +			   FIELD_PREP(ROPLL_SDC_FRAC_EN_RBR_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_HBR_MASK,
> +			   FIELD_PREP(ROPLL_SDC_FRAC_EN_HBR_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_HBR2_MASK,
> +			   FIELD_PREP(ROPLL_SDC_FRAC_EN_HBR2_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(005f),
> +			   OVRD_ROPLL_SDC_RSTN_MASK | ROPLL_SDC_RSTN_MASK,
> +			   FIELD_PREP(OVRD_ROPLL_SDC_RSTN_MASK, 0x1) |
> +			   FIELD_PREP(ROPLL_SDC_RSTN_MASK, 0x1));
> +	regmap_write(hdptx->regmap, CMN_REG(0060),
> +		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x21));
> +	regmap_write(hdptx->regmap, CMN_REG(0061),
> +		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x27));
> +	regmap_write(hdptx->regmap, CMN_REG(0062),
> +		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x27));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0064),
> +			   ROPLL_SDM_NUM_SIGN_RBR_MASK |
> +			   ROPLL_SDM_NUM_SIGN_HBR_MASK |
> +			   ROPLL_SDM_NUM_SIGN_HBR2_MASK,
> +			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, 0x0) |
> +			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_HBR_MASK, 0x1) |
> +			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_HBR2_MASK, 0x1));
> +	regmap_write(hdptx->regmap, CMN_REG(0065),
> +		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0x0));
> +	regmap_write(hdptx->regmap, CMN_REG(0066),
> +		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0xd));
> +	regmap_write(hdptx->regmap, CMN_REG(0067),
> +		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0xd));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
> +			   FIELD_PREP(ROPLL_SDC_N_RBR_MASK, 0x2));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(006a),
> +			   ROPLL_SDC_N_HBR_MASK | ROPLL_SDC_N_HBR2_MASK,
> +			   FIELD_PREP(ROPLL_SDC_N_HBR_MASK, 0x1) |
> +			   FIELD_PREP(ROPLL_SDC_N_HBR2_MASK, 0x1));
> +
> +	regmap_write(hdptx->regmap, CMN_REG(006c),
> +		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x3));
> +	regmap_write(hdptx->regmap, CMN_REG(006d),
> +		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x7));
> +	regmap_write(hdptx->regmap, CMN_REG(006e),
> +		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x7));
> +
> +	regmap_write(hdptx->regmap, CMN_REG(0070),
> +		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x8));
> +	regmap_write(hdptx->regmap, CMN_REG(0071),
> +		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x18));
> +	regmap_write(hdptx->regmap, CMN_REG(0072),
> +		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x18));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0074),
> +			   OVRD_ROPLL_SDC_NDIV_RSTN_MASK | ROPLL_SDC_NDIV_RSTN_MASK,
> +			   FIELD_PREP(OVRD_ROPLL_SDC_NDIV_RSTN_MASK, 0x1) |
> +			   FIELD_PREP(ROPLL_SDC_NDIV_RSTN_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0077), ANA_ROPLL_SSC_CLK_DIV_SEL_MASK,
> +			   FIELD_PREP(ANA_ROPLL_SSC_CLK_DIV_SEL_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0081), ANA_PLL_CD_TX_SER_RATE_SEL_MASK,
> +			   FIELD_PREP(ANA_PLL_CD_TX_SER_RATE_SEL_MASK, 0x0));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0081),
> +			   ANA_PLL_CD_HSCLK_EAST_EN_MASK | ANA_PLL_CD_HSCLK_WEST_EN_MASK,
> +			   FIELD_PREP(ANA_PLL_CD_HSCLK_EAST_EN_MASK, 0x1) |
> +			   FIELD_PREP(ANA_PLL_CD_HSCLK_WEST_EN_MASK, 0x0));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0082), ANA_PLL_CD_VREG_GAIN_CTRL_MASK,
> +			   FIELD_PREP(ANA_PLL_CD_VREG_GAIN_CTRL_MASK, 0x4));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0083), ANA_PLL_CD_VREG_ICTRL_MASK,
> +			   FIELD_PREP(ANA_PLL_CD_VREG_ICTRL_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0084), PLL_LCRO_CLK_SEL_MASK,
> +			   FIELD_PREP(PLL_LCRO_CLK_SEL_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0085), ANA_PLL_SYNC_LOSS_DET_MODE_MASK,
> +			   FIELD_PREP(ANA_PLL_SYNC_LOSS_DET_MODE_MASK, 0x3));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0087), ANA_PLL_TX_HS_CLK_EN_MASK,
> +			   FIELD_PREP(ANA_PLL_TX_HS_CLK_EN_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0097), DIG_CLK_SEL_MASK,
> +			   FIELD_PREP(DIG_CLK_SEL_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0099), CMN_ROPLL_ALONE_MODE,
> +			   FIELD_PREP(CMN_ROPLL_ALONE_MODE, 0x1));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(009a), HS_SPEED_SEL_MASK,
> +			   FIELD_PREP(HS_SPEED_SEL_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, CMN_REG(009b), LS_SPEED_SEL_MASK,
> +			   FIELD_PREP(LS_SPEED_SEL_MASK, 0x1));
> +}
> +
> +static int rk_hdptx_dp_aux_init(struct rk_hdptx_phy *hdptx)
> +{
> +	u32 status;
> +	int ret;
> +
> +	regmap_update_bits(hdptx->regmap, SB_REG(0102), ANA_SB_RXTERM_OFFSP_MASK,
> +			   FIELD_PREP(ANA_SB_RXTERM_OFFSP_MASK, 0x3));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0103), ANA_SB_RXTERM_OFFSN_MASK,
> +			   FIELD_PREP(ANA_SB_RXTERM_OFFSN_MASK, 0x3));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_AUX_EN_MASK,
> +			   FIELD_PREP(SB_AUX_EN_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0105), ANA_SB_TX_HLVL_PROG_MASK,
> +			   FIELD_PREP(ANA_SB_TX_HLVL_PROG_MASK, 0x7));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0106), ANA_SB_TX_LLVL_PROG_MASK,
> +			   FIELD_PREP(ANA_SB_TX_LLVL_PROG_MASK, 0x7));
> +
> +	regmap_update_bits(hdptx->regmap, SB_REG(010d), ANA_SB_DMRX_LPBK_DATA_MASK,
> +			   FIELD_PREP(ANA_SB_DMRX_LPBK_DATA_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, SB_REG(010f), ANA_SB_VREG_GAIN_CTRL_MASK,
> +			   FIELD_PREP(ANA_SB_VREG_GAIN_CTRL_MASK, 0x0));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0110),
> +			   ANA_SB_VREG_OUT_SEL_MASK | ANA_SB_VREG_REF_SEL_MASK,
> +			   FIELD_PREP(ANA_SB_VREG_OUT_SEL_MASK, 0x1) |
> +			   FIELD_PREP(ANA_SB_VREG_REF_SEL_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, SB_REG(0113),
> +			   SB_RX_RCAL_OPT_CODE_MASK | SB_RX_RTERM_CTRL_MASK,
> +			   FIELD_PREP(SB_RX_RCAL_OPT_CODE_MASK, 0x1) |
> +			   FIELD_PREP(SB_RX_RTERM_CTRL_MASK, 0x3));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0114),
> +			   SB_TG_SB_EN_DELAY_TIME_MASK | SB_TG_RXTERM_EN_DELAY_TIME_MASK,
> +			   FIELD_PREP(SB_TG_SB_EN_DELAY_TIME_MASK, 0x2) |
> +			   FIELD_PREP(SB_TG_RXTERM_EN_DELAY_TIME_MASK, 0x2));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0115),
> +			   SB_READY_DELAY_TIME_MASK | SB_TG_OSC_EN_DELAY_TIME_MASK,
> +			   FIELD_PREP(SB_READY_DELAY_TIME_MASK, 0x2) |
> +			   FIELD_PREP(SB_TG_OSC_EN_DELAY_TIME_MASK, 0x2));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0116),
> +			   AFC_RSTN_DELAY_TIME_MASK,
> +			   FIELD_PREP(AFC_RSTN_DELAY_TIME_MASK, 0x2));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0117),
> +			   FAST_PULSE_TIME_MASK,
> +			   FIELD_PREP(FAST_PULSE_TIME_MASK, 0x4));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0118),
> +			   SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK,
> +			   FIELD_PREP(SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK, 0xa));
> +
> +	regmap_update_bits(hdptx->regmap, SB_REG(011a), SB_TG_CNT_RUN_NO_7_0_MASK,
> +			   FIELD_PREP(SB_TG_CNT_RUN_NO_7_0_MASK, 0x3));
> +	regmap_update_bits(hdptx->regmap, SB_REG(011b),
> +			   SB_EARC_SIG_DET_BYPASS_MASK | SB_AFC_TOL_MASK,
> +			   FIELD_PREP(SB_EARC_SIG_DET_BYPASS_MASK, 0x1) |
> +			   FIELD_PREP(SB_AFC_TOL_MASK, 0x3));
> +	regmap_update_bits(hdptx->regmap, SB_REG(011c), SB_AFC_STB_NUM_MASK,
> +			   FIELD_PREP(SB_AFC_STB_NUM_MASK, 0x4));
> +	regmap_update_bits(hdptx->regmap, SB_REG(011d), SB_TG_OSC_CNT_MIN_MASK,
> +			   FIELD_PREP(SB_TG_OSC_CNT_MIN_MASK, 0x67));
> +	regmap_update_bits(hdptx->regmap, SB_REG(011e), SB_TG_OSC_CNT_MAX_MASK,
> +			   FIELD_PREP(SB_TG_OSC_CNT_MAX_MASK, 0x6a));
> +	regmap_update_bits(hdptx->regmap, SB_REG(011f), SB_PWM_AFC_CTRL_MASK,
> +			   FIELD_PREP(SB_PWM_AFC_CTRL_MASK, 0x5));
> +	regmap_update_bits(hdptx->regmap, SB_REG(011f), SB_RCAL_RSTN_MASK,
> +			   FIELD_PREP(SB_RCAL_RSTN_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0120), SB_AUX_EN_IN_MASK,
> +			   FIELD_PREP(SB_AUX_EN_IN_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, SB_REG(0102), OVRD_SB_RXTERM_EN_MASK,
> +			   FIELD_PREP(OVRD_SB_RXTERM_EN_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK,
> +			   FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_EN_MASK,
> +			   FIELD_PREP(OVRD_SB_EN_MASK, 0x1));
> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_AUX_EN_MASK,
> +			   FIELD_PREP(OVRD_SB_AUX_EN_MASK, 0x1));
> +
> +	regmap_update_bits(hdptx->regmap, SB_REG(010f), OVRD_SB_VREG_EN_MASK,
> +			   FIELD_PREP(OVRD_SB_VREG_EN_MASK, 0x1));
> +
> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +		     HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x1));
> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +		     HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x1));
> +	usleep_range(20, 25);
> +
> +	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
> +	usleep_range(20, 25);
> +	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
> +	usleep_range(20, 25);
> +
> +	regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK,
> +			   FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 0x1));
> +	usleep_range(100, 110);
> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_EN_MASK,
> +			   FIELD_PREP(SB_EN_MASK, 0x1));
> +	usleep_range(100, 110);
> +	regmap_update_bits(hdptx->regmap, SB_REG(0102), SB_RXTERM_EN_MASK,
> +			   FIELD_PREP(SB_RXTERM_EN_MASK, 0x1));
> +	usleep_range(20, 25);
> +	regmap_update_bits(hdptx->regmap, SB_REG(010f), SB_VREG_EN_MASK,
> +			   FIELD_PREP(SB_VREG_EN_MASK, 0x1));
> +	usleep_range(20, 25);
> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_AUX_EN_MASK,
> +			   FIELD_PREP(SB_AUX_EN_MASK, 0x1));
> +	usleep_range(100, 110);
> +
> +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
> +				       status, FIELD_GET(HDPTX_O_SB_RDY, status),
> +				       50, 1000);
> +	if (ret) {
> +		dev_err(hdptx->dev, "Failed to get phy sb ready: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
>  static int rk_hdptx_phy_power_on(struct phy *phy)
>  {
>  	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
>  	int bus_width = phy_get_bus_width(hdptx->phy);
> -	int ret;
> +	enum phy_mode mode = phy_get_mode(phy);
> +	int ret, lane;
>  
>  	/*
>  	 * FIXME: Temporary workaround to pass pixel_clk_rate
> @@ -927,13 +1419,43 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
>  	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
>  		__func__, bus_width, rate);
>  
> -	ret = rk_hdptx_phy_consumer_get(hdptx, rate);
> -	if (ret)
> -		return ret;
> +	if (mode == PHY_MODE_DP) {
> +		rk_hdptx_dp_reset(hdptx);
>  
> -	ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
> -	if (ret)
> -		rk_hdptx_phy_consumer_put(hdptx, true);
> +		for (lane = 0; lane < 4; lane++) {
> +			regmap_update_bits(hdptx->regmap, LANE_REG(031e) + 0x400 * lane,
> +					   LN_POLARITY_INV_MASK | LN_LANE_MODE_MASK,
> +					   FIELD_PREP(LN_POLARITY_INV_MASK, 0) |
> +					   FIELD_PREP(LN_LANE_MODE_MASK, 1));
> +		}
> +
> +		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x1));
> +
> +		regmap_update_bits(hdptx->regmap, LNTOP_REG(0200), PROTOCOL_SEL,
> +				   FIELD_PREP(PROTOCOL_SEL, 0x0));
> +		regmap_update_bits(hdptx->regmap, LNTOP_REG(0206), DATA_BUS_WIDTH_MASK,
> +				   FIELD_PREP(DATA_BUS_WIDTH_MASK, 0x1));
> +		regmap_update_bits(hdptx->regmap, LNTOP_REG(0206), DATA_BUS_WIDTH_SEL_MASK,
> +				   FIELD_PREP(DATA_BUS_WIDTH_SEL_MASK, 0x0));
> +
> +		rk_hdptx_dp_pll_init(hdptx);
> +
> +		ret = rk_hdptx_dp_aux_init(hdptx);
> +		if (ret)
> +			pm_runtime_put(hdptx->dev);
> +	} else {
> +		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
> +
> +		ret = rk_hdptx_phy_consumer_get(hdptx, rate);
> +		if (ret)
> +			return ret;
> +
> +		ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
> +		if (ret)
> +			rk_hdptx_phy_consumer_put(hdptx, true);
> +	}
>  
>  	return ret;
>  }
> @@ -945,9 +1467,337 @@ static int rk_hdptx_phy_power_off(struct phy *phy)
>  	return rk_hdptx_phy_consumer_put(hdptx, false);
>  }
>  
> +static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode,
> +				 int submode)
> +{
> +	return 0;
> +}
> +
> +static int rk_hdptx_phy_verify_config(struct rk_hdptx_phy *hdptx,
> +				      struct phy_configure_opts_dp *dp)
> +{
> +	int i;
> +
> +	if (dp->set_rate) {
> +		switch (dp->link_rate) {
> +		case 1620:
> +		case 2700:
> +		case 5400:
> +			break;
> +		default:
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (dp->set_lanes) {
> +		switch (dp->lanes) {
> +		case 0:
> +		case 1:
> +		case 2:
> +		case 4:
> +			break;
> +		default:
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (dp->set_voltages) {
> +		for (i = 0; i < dp->lanes; i++) {
> +			if (dp->voltage[i] > 3 || dp->pre[i] > 3)
> +				return -EINVAL;
> +
> +			if (dp->voltage[i] + dp->pre[i] > 3)
> +				return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int rk_hdptx_phy_set_rate(struct rk_hdptx_phy *hdptx,
> +				 struct phy_configure_opts_dp *dp)
> +{
> +	u32 bw, status;
> +	int ret;
> +
> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
> +
> +	switch (dp->link_rate) {
> +	case 1620:
> +		bw = DP_BW_RBR;
> +		break;
> +	case 2700:
> +		bw = DP_BW_HBR;
> +		break;
> +	case 5400:
> +		bw = DP_BW_HBR2;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0008), OVRD_LCPLL_EN_MASK | LCPLL_EN_MASK,
> +			   FIELD_PREP(OVRD_LCPLL_EN_MASK, 0x1) |
> +			   FIELD_PREP(LCPLL_EN_MASK, 0x0));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(003d), OVRD_ROPLL_EN_MASK | ROPLL_EN_MASK,
> +			   FIELD_PREP(OVRD_ROPLL_EN_MASK, 0x1) |
> +			   FIELD_PREP(ROPLL_EN_MASK, 0x1));
> +
> +	if (dp->ssc) {
> +		regmap_update_bits(hdptx->regmap, CMN_REG(0074),
> +				   OVRD_ROPLL_SSC_EN_MASK | ROPLL_SSC_EN_MASK,
> +				   FIELD_PREP(OVRD_ROPLL_SSC_EN_MASK, 0x1) |
> +				   FIELD_PREP(ROPLL_SSC_EN_MASK, 0x1));
> +		regmap_write(hdptx->regmap, CMN_REG(0075),
> +			     FIELD_PREP(ANA_ROPLL_SSC_FM_DEVIATION_MASK, 0xc));
> +		regmap_update_bits(hdptx->regmap, CMN_REG(0076),
> +				   ANA_ROPLL_SSC_FM_FREQ_MASK,
> +				   FIELD_PREP(ANA_ROPLL_SSC_FM_FREQ_MASK, 0x1f));
> +
> +		regmap_update_bits(hdptx->regmap, CMN_REG(0099), SSC_EN_MASK,
> +				   FIELD_PREP(SSC_EN_MASK, 0x2));
> +	} else {
> +		regmap_update_bits(hdptx->regmap, CMN_REG(0074),
> +				   OVRD_ROPLL_SSC_EN_MASK | ROPLL_SSC_EN_MASK,
> +				   FIELD_PREP(OVRD_ROPLL_SSC_EN_MASK, 0x1) |
> +				   FIELD_PREP(ROPLL_SSC_EN_MASK, 0x0));
> +		regmap_write(hdptx->regmap, CMN_REG(0075),
> +			     FIELD_PREP(ANA_ROPLL_SSC_FM_DEVIATION_MASK, 0x20));
> +		regmap_update_bits(hdptx->regmap, CMN_REG(0076),
> +				   ANA_ROPLL_SSC_FM_FREQ_MASK,
> +				   FIELD_PREP(ANA_ROPLL_SSC_FM_FREQ_MASK, 0xc));
> +
> +		regmap_update_bits(hdptx->regmap, CMN_REG(0099), SSC_EN_MASK,
> +				   FIELD_PREP(SSC_EN_MASK, 0x0));
> +	}
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0095), DP_TX_LINK_BW_MASK,
> +			   FIELD_PREP(DP_TX_LINK_BW_MASK, bw));
> +
> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x1));
> +
> +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
> +				       status, FIELD_GET(HDPTX_O_PLL_LOCK_DONE, status),
> +				       50, 1000);
> +	if (ret) {
> +		dev_err(hdptx->dev, "Failed to get phy pll lock: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static void rk_hdptx_phy_lane_disable(struct rk_hdptx_phy *hdptx)
> +{
> +	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
> +
> +	regmap_update_bits(hdptx->regmap, LNTOP_REG(0207), LANE_EN,
> +			   FIELD_PREP(LANE_EN, 0x0));
> +
> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
> +		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(0008), OVRD_LCPLL_EN_MASK | LCPLL_EN_MASK,
> +			   FIELD_PREP(OVRD_LCPLL_EN_MASK, 0x1) |
> +			   FIELD_PREP(LCPLL_EN_MASK, 0x0));
> +
> +	regmap_update_bits(hdptx->regmap, CMN_REG(003d), OVRD_ROPLL_EN_MASK | ROPLL_EN_MASK,
> +			   FIELD_PREP(OVRD_ROPLL_EN_MASK, 0x1) |
> +			   FIELD_PREP(ROPLL_EN_MASK, 0x0));
> +}
> +
> +static int rk_hdptx_phy_set_lanes(struct rk_hdptx_phy *hdptx,
> +				  struct phy_configure_opts_dp *dp)
> +{
> +	if (!dp->lanes) {
> +		rk_hdptx_phy_lane_disable(hdptx);
> +		return 0;
> +	}
> +
> +	regmap_update_bits(hdptx->regmap, LNTOP_REG(0207), LANE_EN,
> +			   FIELD_PREP(LANE_EN, GENMASK(dp->lanes - 1, 0)));
> +
> +	return 0;
> +}
> +
> +static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
> +				     struct phy_configure_opts_dp *dp,
> +				     u8 lane)
> +{
> +	const struct tx_drv_ctrl *ctrl;
> +	u32 offset = lane * 0x400;
> +
> +	switch (dp->link_rate) {
> +	case 1620:
> +		ctrl = &tx_drv_ctrl_rbr[dp->voltage[lane]][dp->pre[lane]];
> +		regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
> +				   LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
> +				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
> +				   ctrl->tx_jeq_even_ctrl));
> +		regmap_update_bits(hdptx->regmap, LANE_REG(030c) + offset,
> +				   LN_TX_JEQ_ODD_CTRL_RBR_MASK,
> +				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_RBR_MASK,
> +				   ctrl->tx_jeq_odd_ctrl));
> +		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
> +				   LN_TX_SER_40BIT_EN_RBR_MASK,
> +				   FIELD_PREP(LN_TX_SER_40BIT_EN_RBR_MASK, 0x1));
> +		break;
> +	case 2700:
> +		ctrl = &tx_drv_ctrl_hbr[dp->voltage[lane]][dp->pre[lane]];
> +		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
> +				   LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
> +				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
> +				   ctrl->tx_jeq_even_ctrl));
> +		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
> +				   LN_TX_JEQ_ODD_CTRL_HBR_MASK,
> +				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR_MASK,
> +				   ctrl->tx_jeq_odd_ctrl));
> +		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
> +				   LN_TX_SER_40BIT_EN_HBR_MASK,
> +				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR_MASK, 0x1));
> +		break;
> +	case 5400:
> +	default:
> +		ctrl = &tx_drv_ctrl_hbr2[dp->voltage[lane]][dp->pre[lane]];
> +		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
> +				   LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
> +				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
> +				   ctrl->tx_jeq_even_ctrl));
> +		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
> +				   LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
> +				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
> +				   ctrl->tx_jeq_odd_ctrl));
> +		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
> +				   LN_TX_SER_40BIT_EN_HBR2_MASK,
> +				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1));
> +		break;
> +	}
> +
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0303) + offset,
> +			   OVRD_LN_TX_DRV_LVL_CTRL_MASK | LN_TX_DRV_LVL_CTRL_MASK,
> +			   FIELD_PREP(OVRD_LN_TX_DRV_LVL_CTRL_MASK, 0x1) |
> +			   FIELD_PREP(LN_TX_DRV_LVL_CTRL_MASK,
> +				      ctrl->tx_drv_lvl_ctrl));
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0304) + offset,
> +			   OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK |
> +			   LN_TX_DRV_POST_LVL_CTRL_MASK,
> +			   FIELD_PREP(OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK, 0x1) |
> +			   FIELD_PREP(LN_TX_DRV_POST_LVL_CTRL_MASK,
> +				      ctrl->tx_drv_post_lvl_ctrl));
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0305) + offset,
> +			   OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK |
> +			   LN_TX_DRV_PRE_LVL_CTRL_MASK,
> +			   FIELD_PREP(OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK, 0x1) |
> +			   FIELD_PREP(LN_TX_DRV_PRE_LVL_CTRL_MASK,
> +				      ctrl->tx_drv_pre_lvl_ctrl));
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0306) + offset,
> +			   LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK |
> +			   LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK |
> +			   LN_ANA_TX_DRV_ACCDRV_EN_MASK,
> +			   FIELD_PREP(LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK,
> +				      ctrl->ana_tx_drv_idrv_idn_ctrl) |
> +			   FIELD_PREP(LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK,
> +				      ctrl->ana_tx_drv_idrv_iup_ctrl) |
> +			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_EN_MASK,
> +				      ctrl->ana_tx_drv_accdrv_en));
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0307) + offset,
> +			   LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK |
> +			   LN_ANA_TX_DRV_ACCDRV_CTRL_MASK,
> +			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK, 0x1) |
> +			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_CTRL_MASK,
> +				      ctrl->ana_tx_drv_accdrv_ctrl));
> +
> +	regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
> +			   LN_ANA_TX_JEQ_EN_MASK,
> +			   FIELD_PREP(LN_ANA_TX_JEQ_EN_MASK, ctrl->ana_tx_jeq_en));
> +
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0310) + offset,
> +			   LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK,
> +			   FIELD_PREP(LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK, 0x3));
> +
> +	regmap_update_bits(hdptx->regmap, LANE_REG(0316) + offset,
> +			   LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK,
> +			   FIELD_PREP(LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK, 0x2));
> +
> +	regmap_update_bits(hdptx->regmap, LANE_REG(031b) + offset,
> +			   LN_ANA_TX_RESERVED_MASK,
> +			   FIELD_PREP(LN_ANA_TX_RESERVED_MASK, 0x1));
> +}
> +
> +static int rk_hdptx_phy_set_voltages(struct rk_hdptx_phy *hdptx,
> +				     struct phy_configure_opts_dp *dp)
> +{
> +	u8 lane;
> +	u32 status;
> +	int ret;
> +
> +	for (lane = 0; lane < dp->lanes; lane++)
> +		rk_hdptx_phy_set_voltage(hdptx, dp, lane);
> +
> +	reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
> +
> +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
> +				       status, FIELD_GET(HDPTX_O_PHY_RDY, status),
> +				       50, 5000);
> +	if (ret) {
> +		dev_err(hdptx->dev, "Failed to get phy ready: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> +	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
> +	enum phy_mode mode = phy_get_mode(phy);
> +	int ret;
> +
> +	if (mode != PHY_MODE_DP)
> +		return -EINVAL;
> +
> +	ret = rk_hdptx_phy_verify_config(hdptx, &opts->dp);
> +	if (ret) {
> +		dev_err(hdptx->dev, "invalid params for phy configure\n");
> +		return ret;
> +	}
> +
> +	if (opts->dp.set_rate) {
> +		ret = rk_hdptx_phy_set_rate(hdptx, &opts->dp);
> +		if (ret) {
> +			dev_err(hdptx->dev, "failed to set rate: %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	if (opts->dp.set_lanes) {
> +		ret = rk_hdptx_phy_set_lanes(hdptx, &opts->dp);
> +		if (ret) {
> +			dev_err(hdptx->dev, "failed to set lanes: %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	if (opts->dp.set_voltages) {
> +		ret = rk_hdptx_phy_set_voltages(hdptx, &opts->dp);
> +		if (ret) {
> +			dev_err(hdptx->dev, "failed to set voltages: %d\n",
> +				ret);
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static const struct phy_ops rk_hdptx_phy_ops = {
>  	.power_on  = rk_hdptx_phy_power_on,
>  	.power_off = rk_hdptx_phy_power_off,
> +	.set_mode  = rk_hdptx_phy_set_mode,
> +	.configure = rk_hdptx_phy_configure,
>  	.owner	   = THIS_MODULE,
>  };
>  
> @@ -1164,5 +2014,6 @@ 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_AUTHOR("Damon Ding <damon.ding at rock-chips.com>");
>  MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");
>  MODULE_LICENSE("GPL");
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From christian.bruel at foss.st.com  Mon Dec 16 01:00:27 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 16 Dec 2024 10:00:27 +0100
Subject: [PATCH v2 2/5] PCI: stm32: Add PCIe host support for STM32MP25
In-Reply-To: <20241203145244.trgrobtfmumtiwuc@thinkpad>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-3-christian.bruel@foss.st.com>
 <20241203145244.trgrobtfmumtiwuc@thinkpad>
Message-ID: <ced7a55a-d968-497f-abc2-663855882a3f@foss.st.com>

Hi Manivannan,

On 12/3/24 15:52, Manivannan Sadhasivam wrote:
> On Tue, Nov 26, 2024 at 04:51:16PM +0100, Christian Bruel wrote:
>> Add driver for the STM32MP25 SoC PCIe Gen2 controller based on the
>> DesignWare PCIe core.
>>
>> Supports MSI via GICv2m, Single Virtual Channel, Single Function
>>
>> Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
>> ---
>>   drivers/pci/controller/dwc/Kconfig      |  12 +
>>   drivers/pci/controller/dwc/Makefile     |   1 +
>>   drivers/pci/controller/dwc/pcie-stm32.c | 402 ++++++++++++++++++++++++
>>   drivers/pci/controller/dwc/pcie-stm32.h |  15 +
>>   4 files changed, 430 insertions(+)
>>   create mode 100644 drivers/pci/controller/dwc/pcie-stm32.c
>>   create mode 100644 drivers/pci/controller/dwc/pcie-stm32.h
>>
>> diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
>> index b6d6778b0698..0c18879b604c 100644
>> --- a/drivers/pci/controller/dwc/Kconfig
>> +++ b/drivers/pci/controller/dwc/Kconfig
>> @@ -389,6 +389,18 @@ config PCIE_SPEAR13XX
>>   	help
>>   	  Say Y here if you want PCIe support on SPEAr13XX SoCs.
>>   
>> +config PCIE_STM32
>> +	tristate "STMicroelectronics STM32MP25 PCIe Controller (host mode)"
>> +	depends on ARCH_STM32 || COMPILE_TEST
>> +	depends on PCI_MSI
>> +	select PCIE_DW_HOST
>> +	help
>> +	  Enables support for the DesignWare core based PCIe host controller
>> +	  found in STM32MP25 SoC.
>> +
>> +	  This driver can also be built as a module. If so, the module
>> +	  will be called pcie-stm32.
>> +
>>   config PCI_DRA7XX
>>   	tristate
>>   
>> diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
>> index a8308d9ea986..576d99cb3bc5 100644
>> --- a/drivers/pci/controller/dwc/Makefile
>> +++ b/drivers/pci/controller/dwc/Makefile
>> @@ -28,6 +28,7 @@ obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
>>   obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
>>   obj-$(CONFIG_PCIE_VISCONTI_HOST) += pcie-visconti.o
>>   obj-$(CONFIG_PCIE_RCAR_GEN4) += pcie-rcar-gen4.o
>> +obj-$(CONFIG_PCIE_STM32) += pcie-stm32.o
>>   
>>   # The following drivers are for devices that use the generic ACPI
>>   # pci_root.c driver but don't support standard ECAM config access.
>> diff --git a/drivers/pci/controller/dwc/pcie-stm32.c b/drivers/pci/controller/dwc/pcie-stm32.c
>> new file mode 100644
>> index 000000000000..fa787406c0e4
>> --- /dev/null
>> +++ b/drivers/pci/controller/dwc/pcie-stm32.c
>> @@ -0,0 +1,402 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * STMicroelectronics STM32MP25 PCIe root complex driver.
>> + *
>> + * Copyright (C) 2024 STMicroelectronics
>> + * Author: Christian Bruel <christian.bruel at foss.st.com>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/pinctrl/devinfo.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/reset.h>
>> +#include "pcie-designware.h"
>> +#include "pcie-stm32.h"
>> +#include "../../pci.h"
>> +
>> +struct stm32_pcie {
>> +	struct dw_pcie *pci;
>> +	struct regmap *regmap;
>> +	struct reset_control *rst;
>> +	struct phy *phy;
>> +	struct clk *clk;
>> +	struct gpio_desc *perst_gpio;
>> +	struct gpio_desc *wake_gpio;
>> +	unsigned int wake_irq;
>> +	bool link_is_up;
>> +};
>> +
>> +static int stm32_pcie_start_link(struct dw_pcie *pci)
>> +{
>> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
>> +	u32 ret;
>> +
>> +	if (stm32_pcie->perst_gpio) {
> 
> gpiod_set_value() will bail out if 'perst_gpio' is NULL. So no need to add a
> check.

OK

> 
>> +		/* Make sure PERST# is asserted. */
> 
> Why?

Ack. We have GPIOD_OUT_HIGH already thanks devm_gpiod_get_optional, so 
PERST# is asserted already at probe


> 
>> +		gpiod_set_value(stm32_pcie->perst_gpio, 1);
>> +
>> +		fsleep(PCIE_T_PERST_CLK_US);
>> +		gpiod_set_value(stm32_pcie->perst_gpio, 0);
> 
> Why can't you deassert PERST# in stm32_add_pcie_port()?

Code reuse between probe and resume. (Need de-assert PERST# after the 
refclk is stable from both probe or resume_noirq paths).
Can move this from start_link to:
  - probe after the phy_init
  - and resume_no_irq after the phy_init
before dw_pcie_setup_rc

> 
>> +	}
>> +
>> +	ret = regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
>> +				 STM32MP25_PCIECR_LTSSM_EN,
>> +				 STM32MP25_PCIECR_LTSSM_EN);
>> +
>> +	if (stm32_pcie->perst_gpio)
> 
> It doesn't hurt to call msleep() always.

It is optional in the DT. Why wait if we don't have a reset signal ?

> 
>> +		msleep(PCIE_T_RRS_READY_MS);
>> +
>> +	return ret;
>> +}
>> +
>> +static void stm32_pcie_stop_link(struct dw_pcie *pci)
>> +{
>> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
>> +
>> +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
>> +			   STM32MP25_PCIECR_LTSSM_EN, 0);
>> +
>> +	/* Assert PERST# */
>> +	if (stm32_pcie->perst_gpio)
>> +		gpiod_set_value(stm32_pcie->perst_gpio, 1);
> 
> I don't like tying PERST# handling with start/stop link. PERST# should be
> handled based on the power/clock state.

I don't understand your point: We turn off the PHY in suspend_noirq(), 
so that seems a logical place to de-assert in resume_noirq after the 
refclk is ready. PERST# should be kept active until the PHY stablilizes 
the clock in resume. From the PCIe electromechanical specs, PERST# goes 
active while the refclk is not stable/


> 
>> +}
>> +
>> +static int stm32_pcie_suspend(struct device *dev)
>> +{
>> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
>> +
>> +	if (device_may_wakeup(dev) || device_wakeup_path(dev))
>> +		enable_irq_wake(stm32_pcie->wake_irq);
>> +
>> +	return 0;
>> +}
>> +
>> +static int stm32_pcie_resume(struct device *dev)
>> +{
>> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
>> +
>> +	if (device_may_wakeup(dev) || device_wakeup_path(dev))
>> +		disable_irq_wake(stm32_pcie->wake_irq);
>> +
>> +	return 0;
>> +}
>> +
>> +static int stm32_pcie_suspend_noirq(struct device *dev)
>> +{
>> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
>> +
>> +	stm32_pcie->link_is_up = dw_pcie_link_up(stm32_pcie->pci);
>> +
>> +	stm32_pcie_stop_link(stm32_pcie->pci);
> 
> I don't understand how endpoint can wakeup the host if PERST# gets asserted.

The stm32 PCIe doesn't support L2, we don't expect an in-band beacon for 
the wakeup. We support wakeup only from sideband WAKE#, that will 
restart the link from IRQ

> 
>> +	clk_disable_unprepare(stm32_pcie->clk);
>> +
>> +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev))
>> +		phy_exit(stm32_pcie->phy);
>> +
>> +	return pinctrl_pm_select_sleep_state(dev);
>> +}
>> +
>> +static int stm32_pcie_resume_noirq(struct device *dev)
>> +{
>> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
>> +	struct dw_pcie *pci = stm32_pcie->pci;
>> +	struct dw_pcie_rp *pp = &pci->pp;
>> +	int ret;
>> +
>> +	/* init_state must be called first to force clk_req# gpio when no
> 
> CLKREQ#
> 
> Why RC should control CLKREQ#?

REFCLK is gated with CLKREQ#, So we cannot access the core
without CLKREQ# if no device is present. So force it with a init pinmux
the time to init the PHY and the core DBI registers

> 
> Also please use preferred style for multi-line comments:
> 
> 	/*
> 	 * ...
> 	 */
> 
>> +	 * device is plugged.
>> +	 */
>> +	if (!IS_ERR(dev->pins->init_state))
>> +		ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
>> +	else
>> +		ret = pinctrl_pm_select_default_state(dev);
>> +
>> +	if (ret) {
>> +		dev_err(dev, "Failed to activate pinctrl pm state: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev)) {
>> +		ret = phy_init(stm32_pcie->phy);
>> +		if (ret) {
>> +			pinctrl_pm_select_default_state(dev);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	ret = clk_prepare_enable(stm32_pcie->clk);
>> +	if (ret)
>> +		goto clk_err;
> 
> Please name the goto labels of their purpose. Like err_phy_exit.

OK

> 
>> +
>> +	ret = dw_pcie_setup_rc(pp);
>> +	if (ret)
>> +		goto pcie_err;
> 
> This should be, 'err_disable_clk'.
> 
>> +
>> +	if (stm32_pcie->link_is_up) {
> 
> Why do you need this check? You cannot start the link in the absence of an
> endpoint?
> 

It is an optimization to avoid unnecessary "dw_pcie_wait_for_link" if no 
device is present during suspend


>> +		ret = stm32_pcie_start_link(stm32_pcie->pci);
>> +		if (ret)
>> +			goto pcie_err;
>> +
>> +		/* Ignore errors, the link may come up later */
>> +		dw_pcie_wait_for_link(stm32_pcie->pci);
>> +	}
>> +
>> +	pinctrl_pm_select_default_state(dev);
>> +
>> +	return 0;
>> +
>> +pcie_err:
>> +	dw_pcie_host_deinit(pp);
>> +	clk_disable_unprepare(stm32_pcie->clk);
>> +clk_err:
>> +	phy_exit(stm32_pcie->phy);
>> +	pinctrl_pm_select_default_state(dev);
>> +
>> +	return ret;
>> +}
>> +
>> +static const struct dev_pm_ops stm32_pcie_pm_ops = {
>> +	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_pcie_suspend_noirq,
>> +				  stm32_pcie_resume_noirq)
> 
> Can you make use of dw_pcie_{suspend/resume}_noirq() APIs?

dw_pcie_suspend_noirq bails out with read_poll_timeout on ltssm = 
DW_PCIE_LTSS_L2_IDLE. We don't support L2.

> 
>> +	SYSTEM_SLEEP_PM_OPS(stm32_pcie_suspend, stm32_pcie_resume)
>> +};
>> +
>> +static const struct dw_pcie_host_ops stm32_pcie_host_ops = {
>> +};
>> +
>> +static const struct dw_pcie_ops dw_pcie_ops = {
>> +	.start_link = stm32_pcie_start_link,
>> +	.stop_link = stm32_pcie_stop_link
>> +};
>> +
> 
> [...]
> 
>> +	if (device_property_read_bool(dev, "wakeup-source")) {
>> +		stm32_pcie->wake_gpio = devm_gpiod_get_optional(dev, "wake",
>> +								GPIOD_IN);
>> +		if (IS_ERR(stm32_pcie->wake_gpio))
>> +			return dev_err_probe(dev, PTR_ERR(stm32_pcie->wake_gpio),
>> +					     "Failed to get wake GPIO\n");
>> +	}
>> +
>> +	if (stm32_pcie->wake_gpio) {
>> +		stm32_pcie->wake_irq = gpiod_to_irq(stm32_pcie->wake_gpio);
>> +
>> +		ret = devm_request_threaded_irq(&pdev->dev,
>> +						stm32_pcie->wake_irq, NULL,
>> +						stm32_pcie_wake_irq_handler,
>> +						IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
>> +						"wake_irq", stm32_pcie);
>> +
>> +		if (ret)
>> +			return dev_err_probe(dev, ret, "Failed to request WAKE IRQ: %d\n", ret);
>> +	}
> 
> Can we move WAKE# gpio handling to DWC core? There is nothing STM32 specific
> here.
> 

OK

>> +
>> +	ret = devm_pm_runtime_enable(dev);
>> +	if (ret < 0) {
>> +		dev_err(dev, "Failed to enable runtime PM %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = pm_runtime_resume_and_get(dev);
>> +	if (ret < 0) {
>> +		dev_err(dev, "Failed to get runtime PM %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = stm32_add_pcie_port(stm32_pcie, pdev);
>> +	if (ret)  {
>> +		pm_runtime_put_sync(&pdev->dev);
>> +		return ret;
>> +	}
>> +
>> +	if (stm32_pcie->wake_gpio)
>> +		device_set_wakeup_capable(dev, true);
>> +
>> +	return 0;
>> +}
>> +
>> +static void stm32_pcie_remove(struct platform_device *pdev)
>> +{
>> +	struct stm32_pcie *stm32_pcie = platform_get_drvdata(pdev);
>> +	struct dw_pcie_rp *pp = &stm32_pcie->pci->pp;
>> +
>> +	if (stm32_pcie->wake_gpio)
>> +		device_init_wakeup(&pdev->dev, false);
>> +
>> +	dw_pcie_host_deinit(pp);
>> +	clk_disable_unprepare(stm32_pcie->clk);
>> +
>> +	phy_exit(stm32_pcie->phy);
>> +
>> +	pm_runtime_put_sync(&pdev->dev);
>> +}
>> +
>> +static const struct of_device_id stm32_pcie_of_match[] = {
>> +	{ .compatible = "st,stm32mp25-pcie-rc" },
>> +	{},
>> +};
>> +
>> +static struct platform_driver stm32_pcie_driver = {
>> +	.probe = stm32_pcie_probe,
>> +	.remove = stm32_pcie_remove,
>> +	.driver = {
>> +		.name = "stm32-pcie",
>> +		.of_match_table = stm32_pcie_of_match,
>> +		.pm		= &stm32_pcie_pm_ops,
> 
> Just use a single space instead of tab.
> 
> Could you also set PROBE_PREFER_ASYNCHRONOUS to allow async probing of
> controller drivers?

OK

> 
>> +	},
>> +};
>> +
>> +static bool is_stm32_pcie_driver(struct device *dev)
>> +{
>> +	/* PCI bridge */
>> +	dev = get_device(dev);
>> +
>> +	/* Platform driver */
>> +	dev = get_device(dev->parent);
>> +
>> +	return (dev->driver == &stm32_pcie_driver.driver);
>> +}
>> +
>> +/*
>> + * DMA masters can only access the first 4GB of memory space,
>> + * so we setup the bus DMA limit accordingly.
>> + */
>> +static int stm32_dma_limit(struct pci_dev *pdev, void *data)
>> +{
>> +	dev_dbg(&pdev->dev, "disabling DMA DAC for device");
>> +
>> +	pdev->dev.bus_dma_limit = DMA_BIT_MASK(32);
>> +
>> +	return 0;
>> +}
>> +
>> +static void quirk_stm32_dma_mask(struct pci_dev *pci)
>> +{
>> +	struct pci_dev *root_port;
>> +
>> +	root_port = pcie_find_root_port(pci);
>> +
>> +	if (root_port && is_stm32_pcie_driver(root_port->dev.parent))
>> +		pci_walk_bus(pci->bus, stm32_dma_limit, NULL);
>> +}
>> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SYNOPSYS, 0x0550, quirk_stm32_dma_mask);
> 
> This is not the correct way of using DMA masks as Bjorn noted.

Yes, fixed will dma-ranges

thanks

Christian

> 
> - Mani
> 


From dmitry.baryshkov at linaro.org  Mon Dec 16 01:06:03 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 11:06:03 +0200
Subject: [PATCH v2 10/11] arm64: dts: rockchip: Enable eDP0 display on
 RK3588S EVB1 board
In-Reply-To: <20241216031225.3746-11-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-11-damon.ding@rock-chips.com>
Message-ID: <ay2im4itrj3k4p2ksobgsk77b7m4laaxctkfcpffqxj5ttxenm@mzdizmf3mlcb>

On Mon, Dec 16, 2024 at 11:12:24AM +0800, Damon Ding wrote:
> Add the necessary DT changes to enable eDP0 on RK3588S EVB1 board:
> - Add edp-panel node
> - Set pinctrl of pwm12 for backlight
> - Enable edp0/hdptxphy0/vp2
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> 
> ---
> 
> Changes in v2:
> - Remove brightness-levels and default-brightness-level properties in
>   backlight node.
> - Add the detail DT changes to commit message.
> ---
>  .../boot/dts/rockchip/rk3588s-evb1-v10.dts    | 50 +++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
> index bc4077575beb..5c1ea25b6524 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
> @@ -9,6 +9,7 @@
>  #include <dt-bindings/gpio/gpio.h>
>  #include <dt-bindings/input/input.h>
>  #include <dt-bindings/pinctrl/rockchip.h>
> +#include <dt-bindings/soc/rockchip,vop2.h>
>  #include <dt-bindings/usb/pd.h>
>  #include "rk3588s.dtsi"
>  
> @@ -120,6 +121,18 @@ backlight: backlight {
>  		pwms = <&pwm12 0 25000 0>;
>  	};
>  
> +	edp_panel: edp-panel {
> +		compatible = "lg,lp079qx1-sp0v";

Please use aux-bus and a generic "edp-panel" entry for newer platforms
instead of declaring the panel on the platform bus. Placing eDP panels
on the platform bus has been deprecated for quite a while.

> +		backlight = <&backlight>;
> +		power-supply = <&vcc3v3_lcd_edp>;
> +
> +		port {
> +			panel_in_edp: endpoint {
> +				remote-endpoint = <&edp_out_panel>;
> +			};
> +		};
> +	};
> +
>  	combophy_avdd0v85: regulator-combophy-avdd0v85 {
>  		compatible = "regulator-fixed";
>  		regulator-name = "combophy_avdd0v85";

-- 
With best wishes
Dmitry


From brgl at bgdev.pl  Mon Dec 16 01:09:01 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 16 Dec 2024 10:09:01 +0100
Subject: (subset) [PATCH v3 0/7] drm/vc4: Fixup DT and DT binding issues from recent patchset
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
Message-ID: <173434013318.38429.808413721248542013.b4-ty@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>


On Thu, 12 Dec 2024 18:36:27 +0000, Dave Stevenson wrote:
> I missed the DT errors from the recent patchset[1] (DT patches
> in linux-next via Florian, DRM bindings patches on dri-misc-next)
> as Rob's bot report got spam filtered, so this is a fixup set.
> 
> Largely it was changes to number of interrupts or clocks in the
> bindings, so those are now covered.
> 
> [...]

Applied, thanks!

[3/7] dt-bindings: gpio: brcmstb: permit gpio-line-names property
      commit: 83a9752729c455a6bd9b7cf62198506180691931

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski at linaro.org>


From maz at kernel.org  Mon Dec 16 01:09:43 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 16 Dec 2024 09:09:43 +0000
Subject: [syzbot] [kvmarm?] BUG: unable to handle kernel paging request in __hwasan_check_x0_ADDR
In-Reply-To: <675aa352.050a0220.1ac542.0018.GAE@google.com>
References: <675aa352.050a0220.1ac542.0018.GAE@google.com>
Message-ID: <867c80ro2w.wl-maz@kernel.org>

On Thu, 12 Dec 2024 08:48:18 +0000,
syzbot <syzbot+67a9ec5b1706e0184581 at syzkaller.appspotmail.com> wrote:
> 
> Hello,
> 
> syzbot found the following issue on:
> 
> HEAD commit:    5db899a34f75 Merge remote-tracking branch 'kernel/kvmarm/n..
> git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git fuzzme
> console output: https://syzkaller.appspot.com/x/log.txt?x=16db78f8580000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=fde68ab6d6c8c8ab
> dashboard link: https://syzkaller.appspot.com/bug?extid=67a9ec5b1706e0184581
> compiler:       Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
> userspace arch: arm64
> 
> Unfortunately, I don't have any reproducer for this issue yet.
> 
> Downloadable assets:
> disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/384ffdcca292/non_bootable_disk-5db899a3.raw.xz
> vmlinux: https://storage.googleapis.com/syzbot-assets/4938b757ff4a/vmlinux-5db899a3.xz
> kernel image: https://storage.googleapis.com/syzbot-assets/936938b47987/Image-5db899a3.gz.xz
> 
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: syzbot+67a9ec5b1706e0184581 at syzkaller.appspotmail.com
> 
> Unable to handle kernel paging request at virtual address efff800000000137
> KASAN: probably user-memory-access in range [0x0000000000001370-0x000000000000137f]
> 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
> swapper pgtable: 4k pages, 52-bit VAs, pgdp=0000000044a53000
> [efff800000000137] pgd=1000000049992003, p4d=1000000049993003, pud=0000000000000000
> Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
> Modules linked in:
> CPU: 0 UID: 0 PID: 6560 Comm: syz.2.929 Not tainted 6.12.0-rc7-syzkaller-g5db899a34f75 #0
> Hardware name: linux,dummy-virt (DT)
> pstate: 80402009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : __hwasan_check_x0_67043363+0x4/0x30
> lr : vgic_get_irq+0x7c/0x3d4 arch/arm64/kvm/vgic/vgic.c:93
> sp : ffff80008c597650
> x29: ffff80008c597660 x28: 00000000000000e0 x27: 0000000000000004
> x26: 0000000000000002 x25: ffff800083a7fe20 x24: 16f0000014accd90
> x23: 16f0000014acb9a0 x22: 0000000000000000 x21: a9ff80008c583000
> x20: 0000000000000001 x19: efff800000000000 x18: 0000000000000005
> x17: 0000000000000000 x16: 0000000000000137 x15: 0000000000000000
> x14: 0000000000000002 x13: 0000000000000003 x12: 70f000000a33ba80
> x11: 0000000000080000 x10: 0000000000001378 x9 : efff800000000000
> x8 : 0000000000000001 x7 : 0000000000000001 x6 : 0000000000000001
> x5 : ffff80008c597858 x4 : ffff8000800f2b38 x3 : ffff8000800f7a00
> x2 : 0000000000000001 x1 : 0000000000000001 x0 : 0000000000001378
> Call trace:
>  __hwasan_check_x0_67043363+0x4/0x30
>  vgic_mmio_write_invlpi+0xb0/0x174 arch/arm64/kvm/vgic/vgic-mmio-v3.c:546
>  dispatch_mmio_write+0x2a4/0x308
>  kvm_iodevice_write include/kvm/iodev.h:54 [inline]
>  __kvm_io_bus_write+0x290/0x340 virt/kvm/kvm_main.c:5852
>  kvm_io_bus_write+0x100/0x1bc virt/kvm/kvm_main.c:5877
>  io_mem_abort+0x4b8/0x7a0 arch/arm64/kvm/mmio.c:204
>  kvm_handle_guest_abort+0xb4c/0x1c64 arch/arm64/kvm/mmu.c:1880
>  handle_trap_exceptions arch/arm64/kvm/handle_exit.c:351 [inline]
>  handle_exit+0x1a0/0x274 arch/arm64/kvm/handle_exit.c:381
>  kvm_arch_vcpu_ioctl_run+0xbc0/0x15b0 arch/arm64/kvm/arm.c:1279
>  kvm_vcpu_ioctl+0x660/0xf78 virt/kvm/kvm_main.c:4475
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:907 [inline]
>  __se_sys_ioctl fs/ioctl.c:893 [inline]
>  __arm64_sys_ioctl+0x108/0x184 fs/ioctl.c:893
>  __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
>  invoke_syscall+0x78/0x1b8 arch/arm64/kernel/syscall.c:49
>  el0_svc_common+0xe8/0x1b0 arch/arm64/kernel/syscall.c:132
>  do_el0_svc+0x40/0x50 arch/arm64/kernel/syscall.c:151
>  el0_svc+0x54/0x14c arch/arm64/kernel/entry-common.c:712
>  el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730
>  el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
> Code: a90efbfd d2800441 143a3ed3 9344dc10 (38706930)

This seems to be something that is already handled by d561491ba927c
("KVM: arm64: vgic-v3: Sanitise guest writes to GICR_INVLPIR"), which
made it into 6.13-rc1.

The branch you are using doesn't seem to contain that particular
commit. I have now updated it to -rc3, which should plug that issue.

Let me know if it keeps appearing.

Thanks,

	M.

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


From heiko at sntech.de  Mon Dec 16 01:11:54 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 16 Dec 2024 10:11:54 +0100
Subject: [PATCH v2 03/11] drm/rockchip: analogix_dp: Add support for RK3588
In-Reply-To: <gwogudb5vae7wu452zwuqmdlyaibenoso4f5pjmu3uttckhy2w@shndol4mz5n4>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-4-damon.ding@rock-chips.com>
 <gwogudb5vae7wu452zwuqmdlyaibenoso4f5pjmu3uttckhy2w@shndol4mz5n4>
Message-ID: <4395748.ejJDZkT8p0@diego>

Am Montag, 16. Dezember 2024, 09:57:41 CET schrieb Dmitry Baryshkov:
> On Mon, Dec 16, 2024 at 11:12:17AM +0800, Damon Ding wrote:
> > RK3588 integrates the analogix eDP 1.3 TX controller IP and the HDMI/eDP
> > TX Combo PHY based on a Samsung IP block, and there are also two
> > independent eDP display interface on RK3588 Soc.
> > 
> > Add just the basic support for now, i.e. RGB output up to 4K at 60Hz, without
> > the tests of audio, PSR and other eDP 1.3 specific features.
> > 
> > Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - Add support for the other eDP output edp1
> > ---
> >  .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 82 ++++++++++++++++---
> >  include/drm/bridge/analogix_dp.h              |  3 +-
> >  2 files changed, 74 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> > index 871606a31ef1..4c9a55776ada 100644
> > --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> > +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> > @@ -51,10 +51,12 @@ struct rockchip_grf_reg_field {
> >  /**
> >   * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
> >   * @lcdc_sel: grf register field of lcdc_sel
> > + * @edp_mode: grf register field of edp_mode
> >   * @chip_type: specific chip type
> >   */
> >  struct rockchip_dp_chip_data {
> >  	const struct rockchip_grf_reg_field lcdc_sel;
> > +	const struct rockchip_grf_reg_field edp_mode;
> >  	u32	chip_type;
> >  };
> >  
> > @@ -134,12 +136,21 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
> >  		return ret;
> >  	}
> >  
> > +	ret = rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 1);
> > +	if (ret != 0)
> > +		DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);
> 
> Is it to be called for non-eDP hosts too? Or for older hosts?

The implementation of rockchip_grf_field_write (in patch1) seems to
take care of checking if that field actually exists and doing nothing if
not.

I think eDP/DP is more a naming thing, the Analogix controller is called
an eDP controller in all documentation things.

Even back on rk3288, the Analogix-DP, still is called an eDP controller in
documentation, with the only difference being that it does not contain
another additional "dedicated" DP controller

> > @@ -396,6 +425,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
> >  	const struct rockchip_dp_chip_data *dp_data;
> >  	struct drm_panel *panel = NULL;
> >  	struct rockchip_dp_device *dp;
> > +	int id, i;
> >  	int ret;
> >  
> >  	dp_data = of_device_get_match_data(dev);
> > @@ -410,9 +440,22 @@ static int rockchip_dp_probe(struct platform_device *pdev)
> >  	if (!dp)
> >  		return -ENOMEM;
> >  
> > +	id = of_alias_get_id(dev->of_node, "edp");
> > +	if (id < 0)
> > +		id = 0;
> 
> Alias is not documented.

additionally, aliases should never be used to determine actual device
functionionality - e.g. the hw-device-number

> Please check how other platforms handle device -> ID conversion and
> consider following it (yes, the best option currently known is to
> hardcode bus addresses into the driver data).

see for example the dw-dsi + dw-dsi2 for existing implementations.



> > +	i = 0;
> > +	while (is_rockchip(dp_data[i].chip_type))
> > +		i++;
> > +
> > +	if (id >= i) {
> > +		DRM_DEV_ERROR(dev, "invalid edp id: %d\n", id);
> > +		return -ENODEV;
> > +	}
> 
> Is it applicable to non-eDP case?

same as above, it's always called eDP in all pieces of documentation,
(Compliant with DP 1.2 and eDP 1.3)

Heiko

> > +
> >  	dp->dev = dev;
> >  	dp->adp = ERR_PTR(-ENODEV);
> > -	dp->data = dp_data;
> > +	dp->data = &dp_data[id];
> >  	dp->plat_data.panel = panel;
> >  	dp->plat_data.dev_type = dp->data->chip_type;
> >  	dp->plat_data.power_on = rockchip_dp_poweron;
> > @@ -464,19 +507,38 @@ static int rockchip_dp_resume(struct device *dev)
> >  static DEFINE_RUNTIME_DEV_PM_OPS(rockchip_dp_pm_ops, rockchip_dp_suspend,
> >  		rockchip_dp_resume, NULL);
> >  
> > -static const struct rockchip_dp_chip_data rk3399_edp = {
> > -	.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
> > -	.chip_type = RK3399_EDP,
> > +static const struct rockchip_dp_chip_data rk3399_edp[] = {
> > +	{
> > +		.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
> > +		.chip_type = RK3399_EDP,
> > +	},
> > +	{ /* sentinel */ }
> > +};
> > +
> > +static const struct rockchip_dp_chip_data rk3288_dp[] = {
> > +	{
> > +		.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
> > +		.chip_type = RK3288_DP,
> > +	},
> > +	{ /* sentinel */ }
> >  };
> >  
> > -static const struct rockchip_dp_chip_data rk3288_dp = {
> > -	.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
> > -	.chip_type = RK3288_DP,
> > +static const struct rockchip_dp_chip_data rk3588_edp[] = {
> > +	{
> > +		.edp_mode = GRF_REG_FIELD(0x0000, 0, 0),
> > +		.chip_type = RK3588_EDP,
> > +	},
> > +	{
> > +		.edp_mode = GRF_REG_FIELD(0x0004, 0, 0),
> > +		.chip_type = RK3588_EDP,
> > +	},
> > +	{ /* sentinel */ }
> >  };
> >  
> >  static const struct of_device_id rockchip_dp_dt_ids[] = {
> >  	{.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp },
> >  	{.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp },
> > +	{.compatible = "rockchip,rk3588-edp", .data = &rk3588_edp },
> >  	{}
> >  };
> >  MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
> > diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
> > index 6002c5666031..54086cb2d97d 100644
> > --- a/include/drm/bridge/analogix_dp.h
> > +++ b/include/drm/bridge/analogix_dp.h
> > @@ -15,11 +15,12 @@ enum analogix_dp_devtype {
> >  	EXYNOS_DP,
> >  	RK3288_DP,
> >  	RK3399_EDP,
> > +	RK3588_EDP,
> >  };
> >  
> >  static inline bool is_rockchip(enum analogix_dp_devtype type)
> >  {
> > -	return type == RK3288_DP || type == RK3399_EDP;
> > +	return type == RK3288_DP || type == RK3399_EDP || type == RK3588_EDP;
> >  }
> >  
> >  struct analogix_dp_plat_data {
> 
> 






From krzk at kernel.org  Mon Dec 16 01:26:32 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 10:26:32 +0100
Subject: [PATCH v3 2/3] dt-bindings: pinctrl: add header for PCA9555 GPIO
 extender bindings on some Rockchip-based devices
In-Reply-To: <20241215032507.4739-3-shimrrashai@gmail.com>
References: <20241215032507.4739-1-shimrrashai@gmail.com>
 <20241215032507.4739-3-shimrrashai@gmail.com>
Message-ID: <upc5ctukw3vyxjda7fmpjsqttu4w6vj7hm7vpuezzwytotpi5w@eahfui4kc3nj>

On Sat, Dec 14, 2024 at 09:24:54PM -0600, Shimrra Shai wrote:
> It seemed a bit disputed whether this was actually necessary, but I am
> including it nonetheless. It makes it slightly clearer how the pins on the
> PCA9555 GPIO extender used on the board are actuated than would be evident
> from the numbers alone, since according to the spec sheets for it by NXP:
> 
> https://www.nxp.com/docs/en/data-sheet/PCA9555.pdf
> 
> there are two banks of controllable pins, IO0 and IO1, which are labeled
> equivalently to the labels provided below.
> 
> Also sorry @Heiko St?bner for adding your name on it; I had cut this off a
> BSP source file that was longer. Since this file contains only this
> isolated section, which was written by someone else, I put their authorship
> on it instead. Unfortunately I do not know who "daijh" is, only that they
> used that handle on GitLab to submit this code piece and I got the
> indicated email address.
> 
> Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
> ---
>  .../dt-bindings/pinctrl/rockchip-pca9555.h    | 31 +++++++++++++++++++
>  1 file changed, 31 insertions(+)
>  create mode 100644 include/dt-bindings/pinctrl/rockchip-pca9555.h
> 
> diff --git a/include/dt-bindings/pinctrl/rockchip-pca9555.h b/include/dt-bindings/pinctrl/rockchip-pca9555.h
> new file mode 100644
> index 000000000..21ca99488
> --- /dev/null
> +++ b/include/dt-bindings/pinctrl/rockchip-pca9555.h
> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
> +/*
> + * Bindings for the PCA9555 GPIO extender used on some Rockchip devices, e.g.
> + * Firefly.
> + *
> + * Copyright (C) 2022 Zhongshan Tianqi Intelligent Technology Co., Ltd.
> + * Authors: daijh <djh at t-chip.com.cn>
> + *          Shimrra Shai <shimrrashai at gmail.com>
> + */
> +
> +#ifndef __ROCKCHIP_PCA9555_H__
> +#define __ROCKCHIP_PCA9555_H__
> +
> +#define PCA_IO0_0          0

1. There is no user of these bindings.
2. It's meaningless to map 0 to 0...

Drop entire patch.

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec 16 01:26:58 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 10:26:58 +0100
Subject: [PATCH v3 1/3] arm64: dts: rockchip: add DTs for Firefly
 ITX-3588J and its Core-3588J SoM
In-Reply-To: <20241215032507.4739-2-shimrrashai@gmail.com>
References: <20241215032507.4739-1-shimrrashai@gmail.com>
 <20241215032507.4739-2-shimrrashai@gmail.com>
Message-ID: <itsbbexem4wlkbk6tczmawkp5z6ngse477iretyarg2ut5jhi3@atg4o3lr3u6u>

On Sat, Dec 14, 2024 at 09:24:53PM -0600, Shimrra Shai wrote:
> Main DTS for the boards and Makefile addition.
> 
> Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
> ---
>  arch/arm64/boot/dts/rockchip/Makefile         |   1 +
>  .../rockchip/rk3588-firefly-core-3588j.dtsi   | 453 +++++++++++
>  .../dts/rockchip/rk3588-firefly-itx-3588j.dts | 712 ++++++++++++++++++
>  3 files changed, 1166 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
> 
> diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> index 86cc418a2..3f2eebd1f 100644
> --- a/arch/arm64/boot/dts/rockchip/Makefile
> +++ b/arch/arm64/boot/dts/rockchip/Makefile
> @@ -137,6 +137,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-wifi.dtbo
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-firefly-itx-3588j.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-friendlyelec-cm3588-nas.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
> new file mode 100644
> index 000000000..e911a6472
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
> @@ -0,0 +1,453 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +
> +#include "rk3588.dtsi"
> +
> +/ {
> +	compatible = "firefly,core-3588j", "rockchip,rk3588";

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

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).
Maybe you need to update your dtschema and yamllint. Don't rely on
distro packages for dtschema and be sure you are using the latest
released dtschema.

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec 16 01:28:08 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 10:28:08 +0100
Subject: [PATCH v3 3/3] dt-bindings: arm: rockchip: Add Firefly ITX-3588J
 board
In-Reply-To: <20241215032507.4739-4-shimrrashai@gmail.com>
References: <20241215032507.4739-1-shimrrashai@gmail.com>
 <20241215032507.4739-4-shimrrashai@gmail.com>
Message-ID: <x7y24y3bkbj5fzx5pdprjr5umg6egxsy2xscfbj3xgzgzubvdk@ppncjiqoekk7>

On Sat, Dec 14, 2024 at 09:24:55PM -0600, Shimrra Shai wrote:
> Updated DT binding documentation per @Heiko St?bner's suggestion, to
> reflect the bipartite nature of the board.
> 
> Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>  1 file changed, 7 insertions(+)
> 

Order your patches correctly (bindings are always before users), so you
won't receive feedback of undocumented compatibles. See submitting
patches in bindings directory.


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

Best regards,
Krzysztof



From kevin.brodsky at arm.com  Mon Dec 16 01:28:49 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Mon, 16 Dec 2024 09:28:49 +0000
Subject: [PATCH] selftests/mm: fix dependency on pkey_util.c
In-Reply-To: <Z19Tl30BuKTfL629@tuxmaker.boeblingen.de.ibm.com>
References: <Z19Tl30BuKTfL629@tuxmaker.boeblingen.de.ibm.com>
Message-ID: <20241216092849.2140850-1-kevin.brodsky@arm.com>

The pkey* files can only be built on architectures that support
pkeys (pkey-helpers.h #error's otherwise). Adding pkey_util.c as
dependency to all $(TEST_GEN_FILES) is therefore a bad idea. Make it
a dependency of the pkeys tests only.

Those tests are built in 32/64-bit variants on x86_64 so we need to
add an explicit dependency there as well.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---

Hi Alexander,

Thank you for the bug report, that patch indeed breaks all
architectures that don't support pkeys, I should have realised that!
This patch should fix it.

Andrew, it would make sense to squash this patch into the original
("selftests/mm: Use sys_pkey helpers consistently").

Cheers,
- Kevin

Cc: akpm at linux-foundation.org
Cc: aruna.ramakrishna at oracle.com
Cc: catalin.marinas at arm.com
Cc: dave.hansen at linux.intel.com
Cc: joey.gouly at arm.com
Cc: keith.lucas at oracle.com
Cc: ryan.roberts at arm.com
Cc: shuah at kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kselftest at vger.kernel.org
Cc: linux-mm at kvack.org
Cc: x86 at kernel.org
Cc: linux-s390 at vger.kernel.org
---
 tools/testing/selftests/mm/Makefile | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index 1f0743d9459d..18041de1aebf 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -147,16 +147,20 @@ TEST_FILES += write_hugetlb_memory.sh
 
 include ../lib.mk
 
-$(TEST_GEN_PROGS): vm_util.c thp_settings.c pkey_util.c
-$(TEST_GEN_FILES): vm_util.c thp_settings.c pkey_util.c
+$(TEST_GEN_PROGS): vm_util.c thp_settings.c
+$(TEST_GEN_FILES): vm_util.c thp_settings.c
 
 $(OUTPUT)/uffd-stress: uffd-common.c
 $(OUTPUT)/uffd-unit-tests: uffd-common.c
+$(OUTPUT)/protection_keys: pkey_util.c
+$(OUTPUT)/pkey_sighandler_tests: pkey_util.c
 
 ifeq ($(ARCH),x86_64)
 BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32))
 BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64))
 
+$(BINARIES_32) $(BINARIES_64): pkey_util.c
+
 define gen-target-rule-32
 $(1) $(1)_32: $(OUTPUT)/$(1)_32
 .PHONY: $(1) $(1)_32
-- 
2.47.0



From suzuki.poulose at arm.com  Mon Dec 16 01:33:51 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 16 Dec 2024 09:33:51 +0000
Subject: [PATCH v2 2/3] coresight: tmc: Update error logging in tmc common
 functions
In-Reply-To: <20241213144919.110642-3-mike.leach@linaro.org>
References: <20241213144919.110642-1-mike.leach@linaro.org>
 <20241213144919.110642-3-mike.leach@linaro.org>
Message-ID: <9094b068-ed3a-444d-b790-e43a652ab6e9@arm.com>

On 13/12/2024 14:49, Mike Leach wrote:
> Enhance the error logging in the tmc_wait_for_tmcready() and
> tmc_flush_and_stop() to print key tmc  register values on error
> conditions to improve hardware debug information.
> 
> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>   .../hwtracing/coresight/coresight-tmc-core.c  | 37 +++++++++++++++----
>   drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
>   2 files changed, 30 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index e9876252a789..1a9299adae93 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -34,25 +34,36 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>   DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>   DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>   
> +#define TMC_WAIT_READY_FMT_STR "timeout while waiting for TMC to be Ready [STS=0x%04x]\n"
> +
>   int tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>   {
>   	struct coresight_device *csdev = drvdata->csdev;
>   	struct csdev_access *csa = &csdev->access;
> +	u32 tmc_sts = 0;
>   
>   	/* Ensure formatter, unformatter and hardware fifo are empty */
> -	if (coresight_timeout(csa, TMC_STS, TMC_STS_TMCREADY_BIT, 1)) {
> -		dev_err(&csdev->dev,
> -			"timeout while waiting for TMC to be Ready\n");
> +	if (coresight_timeout_retval(csa, TMC_STS, TMC_STS_TMCREADY_BIT, 1,
> +				     &tmc_sts)) {
> +		dev_err(&csdev->dev, TMC_WAIT_READY_FMT_STR, tmc_sts);
>   		return -EBUSY;
>   	}
>   	return 0;
>   }
>   
> -void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
> +int tmc_flush_and_stop(struct tmc_drvdata *drvdata)
>   {
>   	struct coresight_device *csdev = drvdata->csdev;
>   	struct csdev_access *csa = &csdev->access;
> -	u32 ffcr;
> +	u32 ffcr, ffsr, tmc_sts;
> +	int rc = 0;
> +
> +	/* note any MemErr present when stopping TMC */
> +	tmc_sts = readl_relaxed(drvdata->base + TMC_STS);
> +	if (tmc_sts & TMC_STS_MEMERR)
> +		dev_err(&csdev->dev,
> +			"MemErr detected before Manual Flush; STS[0x%02x]\n",
> +			tmc_sts);
>   
>   	ffcr = readl_relaxed(drvdata->base + TMC_FFCR);
>   	ffcr |= TMC_FFCR_STOP_ON_FLUSH;
> @@ -60,12 +71,22 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
>   	ffcr |= BIT(TMC_FFCR_FLUSHMAN_BIT);
>   	writel_relaxed(ffcr, drvdata->base + TMC_FFCR);
>   	/* Ensure flush completes */
> -	if (coresight_timeout(csa, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0)) {
> +	if (coresight_timeout_retval(csa, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0,
> +				     &ffcr)) {
> +		ffsr = readl_relaxed(drvdata->base + TMC_FFSR);
>   		dev_err(&csdev->dev,
> -		"timeout while waiting for completion of Manual Flush\n");
> +			"timeout while waiting for completion of Manual Flush\n");
> +		dev_err(&csdev->dev,
> +			"regs: FFCR[0x%02x] FFSR[0x%02x] STS[0x%02x]\n",
> +			ffcr, ffsr, tmc_sts);
> +		rc = -EBUSY;
>   	}
>   
> -	tmc_wait_for_tmcready(drvdata);
> +	if (tmc_wait_for_tmcready(drvdata)) {
> +		dev_err(&csdev->dev, "TMC ready error after Manual flush\n");
> +		rc = -EBUSY;
> +	}
> +	return rc;
>   }

All of this looks good to me. Do we need to move the MemErr check post 
the flush ? There is a potential chance of hitting a MemERR on flushing
and we could miss reproting those ones ?

Suzuki

>   void tmc_enable_hw(struct tmc_drvdata *drvdata)
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index 2671926be62a..34513f07c3aa 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -259,7 +259,7 @@ struct tmc_sg_table {
>   
>   /* Generic functions */
>   int tmc_wait_for_tmcready(struct tmc_drvdata *drvdata);
> -void tmc_flush_and_stop(struct tmc_drvdata *drvdata);
> +int tmc_flush_and_stop(struct tmc_drvdata *drvdata);
>   void tmc_enable_hw(struct tmc_drvdata *drvdata);
>   void tmc_disable_hw(struct tmc_drvdata *drvdata);
>   u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata);



From nogikh at google.com  Mon Dec 16 01:38:15 2024
From: nogikh at google.com (Aleksandr Nogikh)
Date: Mon, 16 Dec 2024 11:38:15 +0200
Subject: [syzbot] [kvmarm?] BUG: unable to handle kernel paging request in __hwasan_check_x0_ADDR
In-Reply-To: <867c80ro2w.wl-maz@kernel.org>
References: <675aa352.050a0220.1ac542.0018.GAE@google.com> <867c80ro2w.wl-maz@kernel.org>
Message-ID: <CANp29Y6Eu47CvtuKfS7qKqXVcVf7mvVoP7XQstryb_ooakCpcA@mail.gmail.com>

Hi Marc,

Thanks for looking into the report!
Let's tell syzbot about the fixing commit you mentioned:

#syz fix: KVM: arm64: vgic-v3: Sanitise guest writes to GICR_INVLPIR

Syzbot will close the issue once the commit reaches the fuzzed tree.


-- 
Aleksandr

On Mon, Dec 16, 2024 at 11:09?AM 'Marc Zyngier' via syzkaller-bugs
<syzkaller-bugs at googlegroups.com> wrote:
>
> On Thu, 12 Dec 2024 08:48:18 +0000,
> syzbot <syzbot+67a9ec5b1706e0184581 at syzkaller.appspotmail.com> wrote:
> >
> > Hello,
> >
> > syzbot found the following issue on:
> >
> > HEAD commit:    5db899a34f75 Merge remote-tracking branch 'kernel/kvmarm/n..
> > git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git fuzzme
> > console output: https://syzkaller.appspot.com/x/log.txt?x=16db78f8580000
> > kernel config:  https://syzkaller.appspot.com/x/.config?x=fde68ab6d6c8c8ab
> > dashboard link: https://syzkaller.appspot.com/bug?extid=67a9ec5b1706e0184581
> > compiler:       Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
> > userspace arch: arm64
> >
> > Unfortunately, I don't have any reproducer for this issue yet.
> >
> > Downloadable assets:
> > disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/384ffdcca292/non_bootable_disk-5db899a3.raw.xz
> > vmlinux: https://storage.googleapis.com/syzbot-assets/4938b757ff4a/vmlinux-5db899a3.xz
> > kernel image: https://storage.googleapis.com/syzbot-assets/936938b47987/Image-5db899a3.gz.xz
> >
> > IMPORTANT: if you fix the issue, please add the following tag to the commit:
> > Reported-by: syzbot+67a9ec5b1706e0184581 at syzkaller.appspotmail.com
> >
> > Unable to handle kernel paging request at virtual address efff800000000137
> > KASAN: probably user-memory-access in range [0x0000000000001370-0x000000000000137f]
> > 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
> > swapper pgtable: 4k pages, 52-bit VAs, pgdp=0000000044a53000
> > [efff800000000137] pgd=1000000049992003, p4d=1000000049993003, pud=0000000000000000
> > Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
> > Modules linked in:
> > CPU: 0 UID: 0 PID: 6560 Comm: syz.2.929 Not tainted 6.12.0-rc7-syzkaller-g5db899a34f75 #0
> > Hardware name: linux,dummy-virt (DT)
> > pstate: 80402009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > pc : __hwasan_check_x0_67043363+0x4/0x30
> > lr : vgic_get_irq+0x7c/0x3d4 arch/arm64/kvm/vgic/vgic.c:93
> > sp : ffff80008c597650
> > x29: ffff80008c597660 x28: 00000000000000e0 x27: 0000000000000004
> > x26: 0000000000000002 x25: ffff800083a7fe20 x24: 16f0000014accd90
> > x23: 16f0000014acb9a0 x22: 0000000000000000 x21: a9ff80008c583000
> > x20: 0000000000000001 x19: efff800000000000 x18: 0000000000000005
> > x17: 0000000000000000 x16: 0000000000000137 x15: 0000000000000000
> > x14: 0000000000000002 x13: 0000000000000003 x12: 70f000000a33ba80
> > x11: 0000000000080000 x10: 0000000000001378 x9 : efff800000000000
> > x8 : 0000000000000001 x7 : 0000000000000001 x6 : 0000000000000001
> > x5 : ffff80008c597858 x4 : ffff8000800f2b38 x3 : ffff8000800f7a00
> > x2 : 0000000000000001 x1 : 0000000000000001 x0 : 0000000000001378
> > Call trace:
> >  __hwasan_check_x0_67043363+0x4/0x30
> >  vgic_mmio_write_invlpi+0xb0/0x174 arch/arm64/kvm/vgic/vgic-mmio-v3.c:546
> >  dispatch_mmio_write+0x2a4/0x308
> >  kvm_iodevice_write include/kvm/iodev.h:54 [inline]
> >  __kvm_io_bus_write+0x290/0x340 virt/kvm/kvm_main.c:5852
> >  kvm_io_bus_write+0x100/0x1bc virt/kvm/kvm_main.c:5877
> >  io_mem_abort+0x4b8/0x7a0 arch/arm64/kvm/mmio.c:204
> >  kvm_handle_guest_abort+0xb4c/0x1c64 arch/arm64/kvm/mmu.c:1880
> >  handle_trap_exceptions arch/arm64/kvm/handle_exit.c:351 [inline]
> >  handle_exit+0x1a0/0x274 arch/arm64/kvm/handle_exit.c:381
> >  kvm_arch_vcpu_ioctl_run+0xbc0/0x15b0 arch/arm64/kvm/arm.c:1279
> >  kvm_vcpu_ioctl+0x660/0xf78 virt/kvm/kvm_main.c:4475
> >  vfs_ioctl fs/ioctl.c:51 [inline]
> >  __do_sys_ioctl fs/ioctl.c:907 [inline]
> >  __se_sys_ioctl fs/ioctl.c:893 [inline]
> >  __arm64_sys_ioctl+0x108/0x184 fs/ioctl.c:893
> >  __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
> >  invoke_syscall+0x78/0x1b8 arch/arm64/kernel/syscall.c:49
> >  el0_svc_common+0xe8/0x1b0 arch/arm64/kernel/syscall.c:132
> >  do_el0_svc+0x40/0x50 arch/arm64/kernel/syscall.c:151
> >  el0_svc+0x54/0x14c arch/arm64/kernel/entry-common.c:712
> >  el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730
> >  el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
> > Code: a90efbfd d2800441 143a3ed3 9344dc10 (38706930)
>
> This seems to be something that is already handled by d561491ba927c
> ("KVM: arm64: vgic-v3: Sanitise guest writes to GICR_INVLPIR"), which
> made it into 6.13-rc1.
>
> The branch you are using doesn't seem to contain that particular
> commit. I have now updated it to -rc3, which should plug that issue.
>
> Let me know if it keeps appearing.
>
> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.
>
> --
> You received this message because you are subscribed to the Google Groups "syzkaller-bugs" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to syzkaller-bugs+unsubscribe at googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/syzkaller-bugs/867c80ro2w.wl-maz%40kernel.org.


From dmitry.baryshkov at linaro.org  Mon Dec 16 01:44:13 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 11:44:13 +0200
Subject: [PATCH v6 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <95a5c779-941a-4942-8988-65fbe1c4cf82@nxp.com>
References: <20241209033923.3009629-1-victor.liu@nxp.com> <20241209033923.3009629-13-victor.liu@nxp.com>
 <3j4fguv4oienfaj4fghpiqpmnq3aczu4azhdo5jzvywc5mawm5@hh33p3dhf6xa>
 <db4d9d4e-855f-4647-9b93-ccc5ec0202b3@nxp.com> <q6pdop6ucowtoxxr66czq7yooujyvp6qs5vcg6gpmi3q4rs4l3@szyqt5pxteoz>
 <b02fb998-9420-4954-8e48-82447493bbb7@nxp.com> <CAA8EJppBpeMA3aSzk025tvzfTW-bFxeZS4kj0Ujk_AuCyoxnEg@mail.gmail.com>
 <95a5c779-941a-4942-8988-65fbe1c4cf82@nxp.com>
Message-ID: <CAA8EJpoUa9y9nfrrDf47aLs5zr4XKSghySXNLnCGwDyYdOvMog@mail.gmail.com>

On Mon, 16 Dec 2024 at 08:28, Liu Ying <victor.liu at nxp.com> wrote:
>
> On 12/13/2024, Dmitry Baryshkov wrote:
> > On Fri, 13 Dec 2024 at 08:06, Liu Ying <victor.liu at nxp.com> wrote:
> >>
> >> On 12/12/2024, Dmitry Baryshkov wrote:
> >>> On Wed, Dec 11, 2024 at 03:43:20PM +0800, Liu Ying wrote:
> >>>> On 12/10/2024, Dmitry Baryshkov wrote:
> >>>>> On Mon, Dec 09, 2024 at 11:39:16AM +0800, Liu Ying wrote:
> >>>>>> i.MX8qxp Display Controller(DC) is comprised of three main components that
> >>>>>> include a blit engine for 2D graphics accelerations, display controller for
> >>>>>> display output processing, as well as a command sequencer.  Add kernel
> >>>>>> mode setting support for the display controller part with two CRTCs and
> >>>>>> two primary planes(backed by FetchLayer and FetchWarp respectively).  The
> >>>>>> registers of the display controller are accessed without command sequencer
> >>>>>> involved, instead just by using CPU.  The command sequencer is supposed to
> >>>>>> be used by the blit engine.
> >>>>>>
> >>>>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> >>>>>> ---
> >>>>>> v6:
> >>>>>> * No change.
> >>>>>>
> >>>>>> v5:
> >>>>>> * Replace .remove_new with .remove in dc-drv.c. (Uwe)
> >>>>>>
> >>>>>> v4:
> >>>>>> * Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
> >>>>>>   function calls from KMS routine to initialization stage. (Dmitry)
> >>>>>> * Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
> >>>>>>   appropriate .h header files or .c source files. (Dmitry)
> >>>>>> * Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
> >>>>>> * Drop dc_drm->pe_rpm_count. (Dmitry)
> >>>>>> * Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
> >>>>>> * Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
> >>>>>>   Instead, put it in struct dc_crtc.  (Dmitry)
> >>>>>> * Call devm_request_irq() to request IRQs, instead of using drmm action.
> >>>>>>   (Dmitry)
> >>>>>> * Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
> >>>>>> * Select DRM_CLIENT_SELECTION due to rebase.
> >>>>>> * Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
> >>>>>> * Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
> >>>>>> * Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
> >>>>>>   rebase.
> >>>>>> * Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
> >>>>>>   register dc_drm_component_unbind_all() action.
> >>>>>> * Request interrupts in dc_crtc_post_init() after encoder initialization to
> >>>>>>   make sure next bridge is found first.
> >>>>>>
> >>>>>> v3:
> >>>>>> * No change.
> >>>>>>
> >>>>>> v2:
> >>>>>> * Find next bridge from TCon's port.
> >>>>>> * Drop drm/drm_module.h include from dc-drv.c.
> >>>>>>
> >>>>>>  drivers/gpu/drm/imx/dc/Kconfig    |   5 +
> >>>>>>  drivers/gpu/drm/imx/dc/Makefile   |   5 +-
> >>>>>>  drivers/gpu/drm/imx/dc/dc-crtc.c  | 558 ++++++++++++++++++++++++++++++
> >>>>>>  drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
> >>>>>>  drivers/gpu/drm/imx/dc/dc-drv.c   | 244 +++++++++++++
> >>>>>>  drivers/gpu/drm/imx/dc/dc-drv.h   |  19 +
> >>>>>>  drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
> >>>>>>  drivers/gpu/drm/imx/dc/dc-kms.h   |  58 ++++
> >>>>>>  drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
> >>>>>>  9 files changed, 1274 insertions(+), 2 deletions(-)
> >>>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
> >>>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
> >>>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
> >>>>>>  create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
> >>>>>>

> >>>>>
> >>>>>> +}
> >>>>>> +
> >>>>>> +static const struct component_master_ops dc_drm_ops = {
> >>>>>> +  .bind = dc_drm_bind,
> >>>>>> +  .unbind = dc_drm_unbind,
> >>>>>> +};
> >>>>>> +
> >>>>>> +static int dc_probe(struct platform_device *pdev)
> >>>>>> +{
> >>>>>> +  struct component_match *match = NULL;
> >>>>>> +  struct dc_priv *priv;
> >>>>>> +  int ret;
> >>>>>> +
> >>>>>> +  priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> >>>>>> +  if (!priv)
> >>>>>> +          return -ENOMEM;
> >>>>>> +
> >>>>>> +  priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
> >>>>>> +  if (IS_ERR(priv->clk_cfg))
> >>>>>> +          return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
> >>>>>> +                               "failed to get cfg clock\n");
> >>>>>> +
> >>>>>> +  dev_set_drvdata(&pdev->dev, priv);
> >>>>>> +
> >>>>>> +  ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> >>>>>> +  if (ret)
> >>>>>> +          return ret;
> >>>>>> +
> >>>>>> +  ret = devm_pm_runtime_enable(&pdev->dev);
> >>>>>> +  if (ret)
> >>>>>> +          return ret;
> >>>>>> +
> >>>>>> +  ret = devm_of_platform_populate(&pdev->dev);
> >>>>>> +  if (ret)
> >>>>>> +          return ret;
> >>>>>> +
> >>>>>> +  dc_add_components(&pdev->dev, &match);
> >>>>>> +
> >>>>>> +  ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
> >>>>>> +  if (ret)
> >>>>>> +          return dev_err_probe(&pdev->dev, ret,
> >>>>>> +                               "failed to add component master\n");
> >>>>>> +
> >>>>>> +  return 0;
> >>>>>> +}
> >>>>>> +
> >>>>>> +static void dc_remove(struct platform_device *pdev)
> >>>>>> +{
> >>>>>> +  component_master_del(&pdev->dev, &dc_drm_ops);
> >>>>>> +}
> >>>>>> +
> >>>>>> +static int dc_runtime_suspend(struct device *dev)
> >>>>>> +{
> >>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>>>> +
> >>>>>> +  clk_disable_unprepare(priv->clk_cfg);
> >>>>>> +
> >>>>>> +  return 0;
> >>>>>> +}
> >>>>>> +
> >>>>>> +static int dc_runtime_resume(struct device *dev)
> >>>>>> +{
> >>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>>>> +  int ret;
> >>>>>> +
> >>>>>> +  ret = clk_prepare_enable(priv->clk_cfg);
> >>>>>> +  if (ret)
> >>>>>> +          dev_err(dev, "failed to enable cfg clock: %d\n", ret);
> >>>>>> +
> >>>>>> +  return ret;
> >>>>>> +}
> >>>>>> +
> >>>>>> +static int dc_suspend(struct device *dev)
> >>>>>> +{
> >>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>>>> +
> >>>>>> +  return drm_mode_config_helper_suspend(priv->drm);
> >>>>>> +}
> >>>>>> +
> >>>>>> +static int dc_resume(struct device *dev)
> >>>>>> +{
> >>>>>> +  struct dc_priv *priv = dev_get_drvdata(dev);
> >>>>>> +
> >>>>>> +  return drm_mode_config_helper_resume(priv->drm);
> >>>>>> +}
> >>>>>> +
> >>>>>> +static void dc_shutdown(struct platform_device *pdev)
> >>>>>> +{
> >>>>>> +  struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
> >>>>>> +
> >>>>>> +  drm_atomic_helper_shutdown(priv->drm);
> >>>>>> +}
> >>>>>> +
> >>>>>> +static const struct dev_pm_ops dc_pm_ops = {
> >>>>>> +  RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
> >>>>>> +  SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
> >>>>>> +};
> >>>>>> +
> >>>>>> +static const struct of_device_id dc_dt_ids[] = {
> >>>>>> +  { .compatible = "fsl,imx8qxp-dc", },
> >>>>>> +  { /* sentinel */ }
> >>>>>> +};
> >>>>>> +MODULE_DEVICE_TABLE(of, dc_dt_ids);
> >>>>>> +
> >>>>>> +static struct platform_driver dc_driver = {
> >>>>>> +  .probe = dc_probe,
> >>>>>> +  .remove = dc_remove,
> >>>>>> +  .shutdown = dc_shutdown,
> >>>>>> +  .driver = {
> >>>>>> +          .name = "imx8-dc",
> >>>>>> +          .of_match_table = dc_dt_ids,
> >>>>>> +          .pm = pm_sleep_ptr(&dc_pm_ops),
> >>>>>> +  },
> >>>>>> +};
> >>>>>> +
> >>>>>>  static struct platform_driver * const dc_drivers[] = {
> >>>>>>    &dc_cf_driver,
> >>>>>>    &dc_de_driver,
> >>>>>> @@ -19,6 +262,7 @@ static struct platform_driver * const dc_drivers[] = {
> >>>>>>    &dc_lb_driver,
> >>>>>>    &dc_pe_driver,
> >>>>>>    &dc_tc_driver,
> >>>>>> +  &dc_driver,
> >>>>>>  };
> >>>>>>
> >>>>>>  static int __init dc_drm_init(void)
> >>>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
> >>>>>> index 3b11f4862c6c..39a771a13933 100644
> >>>>>> --- a/drivers/gpu/drm/imx/dc/dc-drv.h
> >>>>>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.h
> >>>>>> @@ -6,19 +6,38 @@
> >>>>>>  #ifndef __DC_DRV_H__
> >>>>>>  #define __DC_DRV_H__
> >>>>>>
> >>>>>> +#include <linux/container_of.h>
> >>>>>>  #include <linux/platform_device.h>
> >>>>>>
> >>>>>>  #include <drm/drm_device.h>
> >>>>>> +#include <drm/drm_encoder.h>
> >>>>>>
> >>>>>>  #include "dc-de.h"
> >>>>>> +#include "dc-kms.h"
> >>>>>>  #include "dc-pe.h"
> >>>>>>
> >>>>>>  struct dc_drm_device {
> >>>>>>    struct drm_device base;
> >>>>>> +  struct dc_crtc dc_crtc[DC_DISPLAYS];
> >>>>>> +  struct dc_plane dc_primary[DC_DISPLAYS];
> >>>>>> +  struct drm_encoder encoder[DC_DISPLAYS];
> >>>>>>    struct dc_de *de[DC_DISPLAYS];
> >>>>>>    struct dc_pe *pe;
> >>>>>>  };
> >>>>>>
> >>>>>> +static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
> >>>>>> +{
> >>>>>> +  return container_of(drm, struct dc_drm_device, base);
> >>>>>> +}
> >>>>>> +
> >>>>>> +int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
> >>>>>> +int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
> >>>>>> +
> >>>>>> +int dc_kms_init(struct dc_drm_device *dc_drm);
> >>>>>> +void dc_kms_uninit(struct dc_drm_device *dc_drm);
> >>>>>> +
> >>>>>> +int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
> >>>>>> +
> >>>>>>  extern struct platform_driver dc_cf_driver;
> >>>>>>  extern struct platform_driver dc_ed_driver;
> >>>>>>  extern struct platform_driver dc_de_driver;
> >>>>>> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
> >>>>>> new file mode 100644
> >>>>>> index 000000000000..2b18aa37a4a8
> >>>>>> --- /dev/null
> >>>>>> +++ b/drivers/gpu/drm/imx/dc/dc-kms.c
> >>>>>> @@ -0,0 +1,143 @@
> >>>>>> +// SPDX-License-Identifier: GPL-2.0+
> >>>>>> +/*
> >>>>>> + * Copyright 2024 NXP
> >>>>>> + */
> >>>>>> +
> >>>>>> +#include <linux/of.h>
> >>>>>> +#include <linux/of_graph.h>
> >>>>>> +
> >>>>>> +#include <drm/drm_atomic_helper.h>
> >>>>>> +#include <drm/drm_bridge.h>
> >>>>>> +#include <drm/drm_bridge_connector.h>
> >>>>>> +#include <drm/drm_connector.h>
> >>>>>> +#include <drm/drm_crtc.h>
> >>>>>> +#include <drm/drm_device.h>
> >>>>>> +#include <drm/drm_encoder.h>
> >>>>>> +#include <drm/drm_gem_framebuffer_helper.h>
> >>>>>> +#include <drm/drm_mode_config.h>
> >>>>>> +#include <drm/drm_print.h>
> >>>>>> +#include <drm/drm_probe_helper.h>
> >>>>>> +#include <drm/drm_simple_kms_helper.h>
> >>>>>> +#include <drm/drm_vblank.h>
> >>>>>> +
> >>>>>> +#include "dc-de.h"
> >>>>>> +#include "dc-drv.h"
> >>>>>> +#include "dc-kms.h"
> >>>>>> +
> >>>>>> +static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
> >>>>>> +  .fb_create = drm_gem_fb_create,
> >>>>>> +  .atomic_check = drm_atomic_helper_check,
> >>>>>> +  .atomic_commit = drm_atomic_helper_commit,
> >>>>>> +};
> >>>>>> +
> >>>>>> +static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
> >>>>>> +                                  int crtc_index)
> >>>>>> +{
> >>>>>> +  struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
> >>>>>> +  struct drm_device *drm = &dc_drm->base;
> >>>>>> +  struct drm_crtc *crtc = &dc_crtc->base;
> >>>>>> +  struct drm_connector *connector;
> >>>>>> +  struct device *dev = drm->dev;
> >>>>>> +  struct drm_encoder *encoder;
> >>>>>> +  struct drm_bridge *bridge;
> >>>>>> +  int ret;
> >>>>>> +
> >>>>>> +  bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
> >>>>>> +                                  0, 0);
> >>>>>> +  if (IS_ERR(bridge)) {
> >>>>>> +          ret = PTR_ERR(bridge);
> >>>>>> +          if (ret == -ENODEV)
> >>>>>> +                  return 0;
> >>>>>> +
> >>>>>> +          return dev_err_probe(dev, ret,
> >>>>>> +                               "failed to find bridge for CRTC%u\n",
> >>>>>> +                               crtc->index);
> >>>>>> +  }
> >>>>>> +
> >>>>>> +  encoder = &dc_drm->encoder[crtc_index];
> >>>>>> +  ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
> >>>>>> +  if (ret) {
> >>>>>> +          dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
> >>>>>> +                  crtc->index, ret);
> >>>>>> +          return ret;
> >>>>>> +  }
> >>>>>> +
> >>>>>> +  encoder->possible_crtcs = drm_crtc_mask(crtc);
> >>>>>> +
> >>>>>> +  ret = drm_bridge_attach(encoder, bridge, NULL,
> >>>>>> +                          DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>>> +  if (ret) {
> >>>>>> +          dev_err(dev,
> >>>>>> +                  "failed to attach bridge to encoder for CRTC%u: %d\n",
> >>>>>> +                  crtc->index, ret);
> >>>>>> +          return ret;
> >>>>>> +  }
> >>>>>> +
> >>>>>> +  connector = drm_bridge_connector_init(drm, encoder);
> >>>>>> +  if (IS_ERR(connector)) {
> >>>>>> +          ret = PTR_ERR(connector);
> >>>>>> +          dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
> >>>>>> +                  crtc->index, ret);
> >>>>>> +          return ret;
> >>>>>> +  }
> >>>>>> +
> >>>>>> +  ret = drm_connector_attach_encoder(connector, encoder);
> >>>>>> +  if (ret)
> >>>>>> +          dev_err(dev,
> >>>>>> +                  "failed to attach encoder to connector for CRTC%u: %d\n",
> >>>>>> +                  crtc->index, ret);
> >>>>>> +
> >>>>>> +  return ret;
> >>>>>> +}
> >>>>>> +
> >>>>>> +int dc_kms_init(struct dc_drm_device *dc_drm)
> >>>>>> +{
> >>>>>> +  struct drm_device *drm = &dc_drm->base;
> >>>>>> +  int ret, i;
> >>>>>> +
> >>>>>> +  ret = drmm_mode_config_init(drm);
> >>>>>> +  if (ret)
> >>>>>> +          return ret;
> >>>>>> +
> >>>>>> +  drm->mode_config.min_width = 60;
> >>>>>> +  drm->mode_config.min_height = 60;
> >>>>>> +  drm->mode_config.max_width = 8192;
> >>>>>> +  drm->mode_config.max_height = 8192;
> >>>>>> +  drm->mode_config.funcs = &dc_drm_mode_config_funcs;
> >>>>>> +
> >>>>>> +  drm->vblank_disable_immediate = true;
> >>>>>> +  drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
> >>>>>> +
> >>>>>> +  for (i = 0; i < DC_DISPLAYS; i++) {
> >>>>>> +          ret = dc_crtc_init(dc_drm, i);
> >>>>>> +          if (ret)
> >>>>>> +                  return ret;
> >>>>>> +
> >>>>>> +          ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
> >>>>>> +          if (ret)
> >>>>>> +                  return ret;
> >>>>>> +  }
> >>>>>> +
> >>>>>> +  for (i = 0; i < DC_DISPLAYS; i++) {
> >>>>>> +          ret = dc_crtc_post_init(dc_drm, i);
> >>>>>
> >>>>> Can you use .late_register for this?
> >>>>
> >>>> Kerneldoc of struct drm_crtc_funcs::late_register says it's used to register
> >>>> additional userspace interfaces like debugfs interfaces. And, it seems that
> >>>> everyone implementing this uses it to add debugfs interfaces. So, it will
> >>>> kind of abuse it to do CRTC post initialization.
> >>>
> >>> Why can't they be requested earlier then?
> >>
> >> If I request them earlier in dc_crtc_init(), then they cannot be freed by
> >> devm_irq_release() when devm_drm_of_get_bridge() called by
> >> dc_kms_init_encoder_per_crtc() returns -EPROBE_DEFER(which means failing
> >> to find the first DRM bridge for the CRTC).  Why can't they be freed by
> >> devm_irq_release()?  Because they are requested by the devices of ExtDsts
> >> and Display Engines and their drivers are not removed during the probe
> >> deferral dance.  Furthermore, -EPROBE_DEFER won't be returned after
> >> dc_crtc_post_init() since the later called drm_vblank_init() doesn't
> >> return -EPROBE_DEFER anyway, so it's fine to call dc_crtc_post_init() here.
> >>
> >> I met the irq free issue on my i.MX8qxp MEK board before, i.e., -EBUSY is
> >> returned when requesting them again, so it's tested.
> >
> > A typical solution is to request all resources before binding the
> > device as a component. Don't tell me that your interrupt controller is
> > another component of the DRM device :-)
>
> The IRQ handlers are _highly_ related to the CRTC driver(especially the
> dc_crtc_dec_framecomplete_irq_handler() where vblank is handled), so maybe
> it's more appropriate to request the IRQs and implement the IRQ handlers in
> dc-crtc.c instead of doing them in dc-{de,ed}.c. No?

And CRTCs don't exist before master_bind(). Ack.

-- 
With best wishes
Dmitry


From cristian.marussi at arm.com  Mon Dec 16 01:45:19 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 16 Dec 2024 09:45:19 +0000
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless
 scmi_bus_id.
In-Reply-To: <Z1_p0nU93PHJ4Sg_@pluto>
References: <20241216073745.2973317-1-guomin_chen@sina.com>
 <Z1_p0nU93PHJ4Sg_@pluto>
Message-ID: <Z1_2rxJ7TOEIOMp7@pluto>

On Mon, Dec 16, 2024 at 08:50:26AM +0000, Cristian Marussi wrote:
> On Mon, Dec 16, 2024 at 03:37:45PM +0800, guomin_chen at sina.com wrote:
> > From: guomin chen <guomin_chen at sina.com>
> > 
> > Currently, scmi_bus_id is only used to set scmi_dev.id,
> > which in turn sets the SCMI device name. After removing
> > scmi_bus_id, it is clearer and more meaningful to directly
> > use the unique tuple [Parent name,device name, protocol] to 
> > set the SCMI device name.
> > 
> 
> Hi Guomin,
> 
> this same pTCH was NACKed(Rejected) a few days ago:
> 
> https://lore.kernel.org/arm-scmi/20241211134505.2218386-1-guomin_chen at sina.com/T/#u
> 
> ...and you agreed that is not a simplification we can do (not to break
> multuple instances...)...
> 
> ..so why you are posting V2 now ?

Wait...you changed slightly this indeed....you are using dev_parent...my
bad...but please when you post new version of a patch add a summary of
changes between versions...

> 
> Thanks,
> Cristian
> 
> > Signed-off-by: guomin chen <guomin_chen at sina.com>
> > ---
> >  drivers/firmware/arm_scmi/bus.c    | 17 +++--------------
> >  drivers/firmware/arm_scmi/driver.c |  4 ++--
> >  2 files changed, 5 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
> > index 157172a5f2b5..800e8ec9357c 100644
> > --- a/drivers/firmware/arm_scmi/bus.c
> > +++ b/drivers/firmware/arm_scmi/bus.c
> > @@ -20,7 +20,6 @@
> >  BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
> >  EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
> >  
> > -static DEFINE_IDA(scmi_bus_id);
> >  
> >  static DEFINE_IDR(scmi_requested_devices);
> >  /* Protect access to scmi_requested_devices */
> > @@ -341,7 +340,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
> >  	if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
> >  		atomic_set(&scmi_syspower_registered, 0);
> >  
> > -	ida_free(&scmi_bus_id, scmi_dev->id);
> >  	device_unregister(&scmi_dev->dev);
> >  }
> >  
> > @@ -349,7 +347,7 @@ static struct scmi_device *
> >  __scmi_device_create(struct device_node *np, struct device *parent,
> >  		     int protocol, const char *name)
> >  {
> > -	int id, retval;
> > +	int retval;
> >  	struct scmi_device *scmi_dev;
> >  
> >  	/*
> > @@ -387,20 +385,13 @@ __scmi_device_create(struct device_node *np, struct device *parent,
> >  		return NULL;
> >  	}
> >  
> > -	id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
> > -	if (id < 0) {
> > -		kfree_const(scmi_dev->name);
> > -		kfree(scmi_dev);
> > -		return NULL;
> > -	}
> > -
> > -	scmi_dev->id = id;
> >  	scmi_dev->protocol_id = protocol;
> >  	scmi_dev->dev.parent = parent;
> >  	device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
> >  	scmi_dev->dev.bus = &scmi_bus_type;
> >  	scmi_dev->dev.release = scmi_device_release;
> > -	dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
> > +	dev_set_name(&scmi_dev->dev, "scmi_dev.%s.%s.%d", dev_name(parent),
> > +			scmi_dev->name, protocol);
> >

So now you are using the parent top node SCMI device to create a unique
device...and it probably endup in a name like:

 	scmi-dev.arm-scmi.0.auto.genpd.13

 	scmi-dev.arm-scmi.1.auto.genpd.13

...that certainly is more readable but is bulky and anyway giving unique
IDs to devices is pretty common and you lookup which device is which by
simply looking at the drivers/ link....not suure what's the benefit of
all of this...just to avoid an IDA table ?

> >  	retval = device_register(&scmi_dev->dev);
> >  	if (retval)
> > @@ -413,7 +404,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
> >  	return scmi_dev;
> >  put_dev:
> >  	put_device(&scmi_dev->dev);
> > -	ida_free(&scmi_bus_id, id);
> >  	return NULL;
> >  }
> >  
> > @@ -526,7 +516,6 @@ static void __exit scmi_bus_exit(void)
> >  	 */
> >  	scmi_devices_unregister();
> >  	bus_unregister(&scmi_bus_type);
> > -	ida_destroy(&scmi_bus_id);
> >  }
> >  module_exit(scmi_bus_exit);
> >  
> > diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> > index 1b5fb2c4ce86..bbf1f05f2be3 100644
> > --- a/drivers/firmware/arm_scmi/driver.c
> > +++ b/drivers/firmware/arm_scmi/driver.c
> > @@ -2641,8 +2641,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
> >  	cinfo->max_msg_size = info->desc->max_msg_size;
> >  
> >  	/* Create a unique name for this transport device */
> > -	snprintf(name, 32, "__scmi_transport_device_%s_%02X",
> > -		 idx ? "rx" : "tx", prot_id);
> > +	snprintf(name, 32, "__scmi_transport_device_%s",
> > +		 idx ? "rx" : "tx");

I agree on what Dan said AND also this results in having the same name for different
devices across 2 instances if you have a per-protocol channel because you havent anymore
the protocol_id bit.

All in all, I would drop this patch and keep naming as it is because I dont see a real benefit
here....up to Sudeep decide.

Thanks,
Cristian


From sudeep.holla at arm.com  Mon Dec 16 01:56:30 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 16 Dec 2024 09:56:30 +0000
Subject: [PATCH] irqchip/gic-v3: Allow unused SGIs for drivers/modules
In-Reply-To: <1885f74b-5bfb-46a3-a65f-521d974d023f@nvidia.com>
References: <20240813033925.925947-1-sdonthineni@nvidia.com>
 <86zfpgztmt.wl-maz@kernel.org>
 <Zrs2i9Iyrlqc-a4K@bogus>
 <1885f74b-5bfb-46a3-a65f-521d974d023f@nvidia.com>
Message-ID: <Z1_5TjlvyZl5ynGz@bogus>

On Mon, Dec 16, 2024 at 10:25:29AM +0800, Kai-Heng Feng wrote:
> Hi Sudeep,
> 
> On 2024/8/13 6:33 PM, Sudeep Holla wrote:
> > On Tue, Aug 13, 2024 at 09:58:34AM +0100, Marc Zyngier wrote:
> > > On Tue, 13 Aug 2024 04:39:25 +0100,
> > > Shanker Donthineni <sdonthineni at nvidia.com> wrote:
> > > > 
> > > > The commit 897e9e60c016 ("firmware: arm_ffa: Initial support for scheduler
> > > > receiver interrupt") adds support for SGI interrupts in the FFA driver.
> > > > However, the validation for SGIs in the GICv3 is too strict, causing the
> > > > driver probe to fail.
> > > 
> > > It probably is a good thing that I wasn't on Cc for this patch,
> > > because I would have immediately NAK'd it. Sudeep, please consider
> > > this a retrospective NAK!
> > > 
> > 
> > Sure, I am happy to work on any suggestions to replace it with better/cleaner
> > solution.
> > 
> > > > 
> > > > This patch relaxes the SGI validation check, allowing callers to use SGIs
> > > > if the requested SGI number is greater than or equal to MAX_IPI, which
> > > > fixes the TFA driver probe failure.
> > > > 
> > > > This issue is observed on NVIDIA server platform with FFA-v1.1.
> > > >   [    7.918099] PTP clock support registered
> > > >   [    7.922110] EDAC MC: Ver: 3.0.0
> > > >   [    7.945063] ARM FF-A: Driver version 1.1
> > > >   [    7.949068] ARM FF-A: Firmware version 1.1 found
> > > >   [    7.977832] GICv3: [Firmware Bug]: Illegal GSI8 translation request
> > > >   [    7.984237] ARM FF-A: Failed to create IRQ mapping!
> > > >   [    7.989220] ARM FF-A: Notification setup failed -61, not enabled
> > > >   [    8.000198] ARM FF-A: Failed to register driver sched callback -95
> > > >   [    8.011322] scmi_core: SCMI protocol bus registered
> > > > 
> > > > Signed-off-by: Shanker Donthineni <sdonthineni at nvidia.com>
> > > > ---
> > > >   arch/arm64/include/asm/arch_gicv3.h | 17 +++++++++++++++++
> > > >   arch/arm64/kernel/smp.c             | 17 -----------------
> > > >   drivers/irqchip/irq-gic-v3.c        |  2 +-
> > > >   3 files changed, 18 insertions(+), 18 deletions(-)
> > > > 
> > > > diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
> > > > index 9e96f024b2f19..ecf81df2915c7 100644
> > > > --- a/arch/arm64/include/asm/arch_gicv3.h
> > > > +++ b/arch/arm64/include/asm/arch_gicv3.h
> > > > @@ -188,5 +188,22 @@ static inline bool gic_has_relaxed_pmr_sync(void)
> > > >   	return cpus_have_cap(ARM64_HAS_GIC_PRIO_RELAXED_SYNC);
> > > >   }
> > > > +enum ipi_msg_type {
> > > > +	IPI_RESCHEDULE,
> > > > +	IPI_CALL_FUNC,
> > > > +	IPI_CPU_STOP,
> > > > +	IPI_CPU_CRASH_STOP,
> > > > +	IPI_TIMER,
> > > > +	IPI_IRQ_WORK,
> > > > +	NR_IPI,
> > > > +	/*
> > > > +	 * Any enum >= NR_IPI and < MAX_IPI is special and not tracable
> > > > +	 * with trace_ipi_*
> > > > +	 */
> > > > +	IPI_CPU_BACKTRACE = NR_IPI,
> > > > +	IPI_KGDB_ROUNDUP,
> > > > +	MAX_IPI
> > > > +};
> > > > +
> > > >   #endif /* __ASSEMBLY__ */
> > > >   #endif /* __ASM_ARCH_GICV3_H */
> > > > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> > > > index 5e18fbcee9a20..373cd815d9a43 100644
> > > > --- a/arch/arm64/kernel/smp.c
> > > > +++ b/arch/arm64/kernel/smp.c
> > > > @@ -64,23 +64,6 @@ struct secondary_data secondary_data;
> > > >   /* Number of CPUs which aren't online, but looping in kernel text. */
> > > >   static int cpus_stuck_in_kernel;
> > > > -enum ipi_msg_type {
> > > > -	IPI_RESCHEDULE,
> > > > -	IPI_CALL_FUNC,
> > > > -	IPI_CPU_STOP,
> > > > -	IPI_CPU_CRASH_STOP,
> > > > -	IPI_TIMER,
> > > > -	IPI_IRQ_WORK,
> > > > -	NR_IPI,
> > > > -	/*
> > > > -	 * Any enum >= NR_IPI and < MAX_IPI is special and not tracable
> > > > -	 * with trace_ipi_*
> > > > -	 */
> > > > -	IPI_CPU_BACKTRACE = NR_IPI,
> > > > -	IPI_KGDB_ROUNDUP,
> > > > -	MAX_IPI
> > > > -};
> > > > -
> > > >   static int ipi_irq_base __ro_after_init;
> > > >   static int nr_ipi __ro_after_init = NR_IPI;
> > > >   static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init;
> > > > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > > > index c19083bfb9432..0d2038d8cd311 100644
> > > > --- a/drivers/irqchip/irq-gic-v3.c
> > > > +++ b/drivers/irqchip/irq-gic-v3.c
> > > > @@ -1655,7 +1655,7 @@ static int gic_irq_domain_translate(struct irq_domain *d,
> > > >   		if(fwspec->param_count != 2)
> > > >   			return -EINVAL;
> > > > 
> > > > -		if (fwspec->param[0] < 16) {
> > > > +		if (fwspec->param[0] < MAX_IPI) {
> > > >   			pr_err(FW_BUG "Illegal GSI%d translation request\n",
> > > >   			       fwspec->param[0]);
> > > >   			return -EINVAL;
> > > 
> > > No. This is the wrong approach, and leads to inconsistent behaviour if
> > > we ever change this MAX_IPI value. It also breaks 32 bit builds, and
> > > makes things completely inconsistent between ACPI and DT.
> > > 
> > > I don't know how the FFA code was tested, because I cannot see how it
> > > can work.
> > > 
> > > *IF* we are going to allow random SGIs being requested by random
> > > drivers, we need to be able to do it properly. Not as a side hack like
> > > this.
> > 
> > I am open for any ideas as FF-A spec authors/architects decided to allow
> > secure world to donate one of its SGI to the normal world for FF-A
> > notifications.
> 
> Is there any progression on this issue? Do you think it's reasonable to
> revert commit 897e9e60c016 as a temporary measure?
> 

I haven't started on this yet, but I plan to do that in a week or so.
Revert may not be trivial at this point. We can disable it until it is
fixed properly instead of all possible conflicts with reverts.

-- 
Regards,
Sudeep


From dmitry.baryshkov at linaro.org  Mon Dec 16 01:59:33 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 11:59:33 +0200
Subject: [PATCH v7 2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing
 optional properties
In-Reply-To: <20241216085410.1968634-3-andrej.picej@norik.com>
References: <20241216085410.1968634-1-andrej.picej@norik.com>
 <20241216085410.1968634-3-andrej.picej@norik.com>
Message-ID: <75aewnwpb6y73gqlrqmelzeia7bdar5ihm3ety5gfjaqalkuby@gwv4xjpomoit>

On Mon, Dec 16, 2024 at 09:54:09AM +0100, Andrej Picej wrote:
> Add a optional properties to change LVDS output voltage. This should not
> be static as this depends mainly on the connected display voltage
> requirement. We have three properties:
> - "ti,lvds-termination-ohms", which sets near end termination,
> - "ti,lvds-vod-swing-data-microvolt" and
> - "ti,lvds-vod-swing-clock-microvolt" which both set LVDS differential
> output voltage for data and clock lanes. They are defined as an array
> with min and max values. The appropriate bitfield will be set if
> selected constraints can be met.
> 
> If "ti,lvds-termination-ohms" is not defined the default of 200 Ohm near
> end termination will be used. Selecting only one:
> "ti,lvds-vod-swing-data-microvolt" or
> "ti,lvds-vod-swing-clock-microvolt" can be done, but the output voltage
> constraint for only data/clock lanes will be met. Setting both is
> recommended.
> 
> Signed-off-by: Andrej Picej <andrej.picej at norik.com>
> ---
> Changes in v7:
> - decrement refcount of the endpoint in all error cases,
> - add spaces to improve the readability of the long if statement conditions in
> sn65dsi83_select_lvds_vod_swing.
> Changes in v6:
> - rework termination resistor logic, default is now set by resistor value, not
> reg value,
> - move setting lvds_vod_swing_conf to default value of 0x1 inside if statement
> which checks if both properties are not set
> Changes in v5:
> - specify default values in sn65dsi83_parse_lvds_endpoint,
> - move sn65dsi83_parse_lvds_endpoint for channel B up, outside if,
> Changes in v4:
> - fix typo in commit message bitfiled -> bitfield
> - use arrays (lvds_vod_swing_conf and lvds_term_conf) in private data, instead
> of separate variables for channel A/B
> - add more checks on return value of "of_property_read_u32_array"
> Changes in v3:
> - use microvolts for default array values 1000 mV -> 1000000 uV.
> Changes in v2:
> - use datasheet tables to get the proper configuration
> - since major change was done change the authorship to myself
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi83.c | 145 +++++++++++++++++++++++++-
>  1 file changed, 142 insertions(+), 3 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From danishanwar at ti.com  Mon Dec 16 02:00:42 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 16 Dec 2024 15:30:42 +0530
Subject: [PATCH net-next 2/4] net: ti: icssg-prueth: Add VLAN support in EMAC mode
In-Reply-To: <20241216100044.577489-1-danishanwar@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
Message-ID: <20241216100044.577489-3-danishanwar@ti.com>

Add support for vlan filtering in dual EMAC mode.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 29 +++++++++-----------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index c568c84a032b..e031bccf31dc 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -822,19 +822,18 @@ static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev,
 {
 	struct prueth_emac *emac = netdev_priv(ndev);
 	struct prueth *prueth = emac->prueth;
+	int port_mask = BIT(emac->port_id);
 	int untag_mask = 0;
-	int port_mask;
 
-	if (prueth->is_hsr_offload_mode) {
-		port_mask = BIT(PRUETH_PORT_HOST) | BIT(emac->port_id);
-		untag_mask = 0;
+	if (prueth->is_hsr_offload_mode)
+		port_mask |= BIT(PRUETH_PORT_HOST);
 
-		netdev_dbg(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
-			   vid, port_mask, untag_mask);
+	netdev_err(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
+		   vid, port_mask, untag_mask);
+
+	icssg_vtbl_modify(emac, vid, port_mask, untag_mask, true);
+	icssg_set_pvid(emac->prueth, vid, emac->port_id);
 
-		icssg_vtbl_modify(emac, vid, port_mask, untag_mask, true);
-		icssg_set_pvid(emac->prueth, vid, emac->port_id);
-	}
 	return 0;
 }
 
@@ -843,18 +842,16 @@ static int emac_ndo_vlan_rx_del_vid(struct net_device *ndev,
 {
 	struct prueth_emac *emac = netdev_priv(ndev);
 	struct prueth *prueth = emac->prueth;
+	int port_mask = BIT(emac->port_id);
 	int untag_mask = 0;
-	int port_mask;
 
-	if (prueth->is_hsr_offload_mode) {
+	if (prueth->is_hsr_offload_mode)
 		port_mask = BIT(PRUETH_PORT_HOST);
-		untag_mask = 0;
 
-		netdev_dbg(emac->ndev, "VID del vid:%u port_mask:%X untag_mask  %X\n",
-			   vid, port_mask, untag_mask);
+	netdev_err(emac->ndev, "VID del vid:%u port_mask:%X untag_mask  %X\n",
+		   vid, port_mask, untag_mask);
+	icssg_vtbl_modify(emac, vid, port_mask, untag_mask, false);
 
-		icssg_vtbl_modify(emac, vid, port_mask, untag_mask, false);
-	}
 	return 0;
 }
 
-- 
2.34.1



From danishanwar at ti.com  Mon Dec 16 02:00:43 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 16 Dec 2024 15:30:43 +0530
Subject: [PATCH net-next 3/4] net: ti: icssg-prueth: Add Multicast Filtering support for VLAN in MAC mode
In-Reply-To: <20241216100044.577489-1-danishanwar@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
Message-ID: <20241216100044.577489-4-danishanwar@ti.com>

Add multicast filtering support for VLAN interfaces in dual EMAC mode
for ICSSG driver.

The driver uses vlan_for_each() API to get the list of available
vlans. The driver then sync mc addr of vlan interface with a locally
mainatined list emac->vlan_mcast_list[vid] using __hw_addr_sync_multiple()
API.

The driver then calls the sync / unsync callbacks and based on whether
the ndev is vlan or not, driver passes appropriate vid to FDB helper
functions.

This commit also exports __hw_addr_sync_multiple() in order to use it
from the ICSSG driver.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 69 ++++++++++++++++----
 drivers/net/ethernet/ti/icssg/icssg_prueth.h |  6 ++
 include/linux/netdevice.h                    |  3 +
 net/core/dev_addr_lists.c                    |  7 +-
 4 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index e031bccf31dc..a18773ef6eab 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -472,30 +472,43 @@ const struct icss_iep_clockops prueth_iep_clockops = {
 
 static int icssg_prueth_add_mcast(struct net_device *ndev, const u8 *addr)
 {
-	struct prueth_emac *emac = netdev_priv(ndev);
-	int port_mask = BIT(emac->port_id);
+	struct net_device *real_dev;
+	struct prueth_emac *emac;
+	int port_mask;
+	u8 vlan_id;
 
-	port_mask |= icssg_fdb_lookup(emac, addr, 0);
-	icssg_fdb_add_del(emac, addr, 0, port_mask, true);
-	icssg_vtbl_modify(emac, 0, port_mask, port_mask, true);
+	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
+	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
+	emac = netdev_priv(real_dev);
+
+	port_mask = BIT(emac->port_id) | icssg_fdb_lookup(emac, addr, vlan_id);
+	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, true);
+	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, true);
 
 	return 0;
 }
 
 static int icssg_prueth_del_mcast(struct net_device *ndev, const u8 *addr)
 {
-	struct prueth_emac *emac = netdev_priv(ndev);
-	int port_mask = BIT(emac->port_id);
+	struct net_device *real_dev;
+	struct prueth_emac *emac;
 	int other_port_mask;
+	int port_mask;
+	u8 vlan_id;
+
+	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
+	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
+	emac = netdev_priv(real_dev);
 
-	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, 0);
+	port_mask = BIT(emac->port_id);
+	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, vlan_id);
 
-	icssg_fdb_add_del(emac, addr, 0, port_mask, false);
-	icssg_vtbl_modify(emac, 0, port_mask, port_mask, false);
+	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, false);
+	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, false);
 
 	if (other_port_mask) {
-		icssg_fdb_add_del(emac, addr, 0, other_port_mask, true);
-		icssg_vtbl_modify(emac, 0, other_port_mask, other_port_mask, true);
+		icssg_fdb_add_del(emac, addr, vlan_id, other_port_mask, true);
+		icssg_vtbl_modify(emac, vlan_id, other_port_mask, other_port_mask, true);
 	}
 
 	return 0;
@@ -531,6 +544,28 @@ static int icssg_prueth_hsr_del_mcast(struct net_device *ndev, const u8 *addr)
 	return 0;
 }
 
+static int icssg_update_vlan_mcast(struct net_device *vdev, int vid,
+				   void *args)
+{
+	struct net_device *vport_ndev;
+	struct prueth_emac *emac;
+
+	if (!vdev || !vid)
+		return 0;
+
+	vport_ndev = vlan_dev_real_dev(vdev);
+	emac = netdev_priv(vport_ndev);
+
+	netif_addr_lock_bh(vdev);
+	__hw_addr_sync_multiple(&emac->vlan_mcast_list[vid], &vdev->mc, vdev->addr_len);
+	netif_addr_unlock_bh(vdev);
+
+	__hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
+			   icssg_prueth_add_mcast, icssg_prueth_del_mcast);
+
+	return 0;
+}
+
 /**
  * emac_ndo_open - EMAC device open
  * @ndev: network adapter device
@@ -772,12 +807,17 @@ static void emac_ndo_set_rx_mode_work(struct work_struct *work)
 		return;
 	}
 
-	if (emac->prueth->is_hsr_offload_mode)
+	if (emac->prueth->is_hsr_offload_mode) {
 		__dev_mc_sync(ndev, icssg_prueth_hsr_add_mcast,
 			      icssg_prueth_hsr_del_mcast);
-	else
+	} else {
 		__dev_mc_sync(ndev, icssg_prueth_add_mcast,
 			      icssg_prueth_del_mcast);
+		if (rtnl_trylock()) {
+			vlan_for_each(ndev, icssg_update_vlan_mcast, NULL);
+			rtnl_unlock();
+		}
+	}
 }
 
 /**
@@ -828,6 +868,7 @@ static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev,
 	if (prueth->is_hsr_offload_mode)
 		port_mask |= BIT(PRUETH_PORT_HOST);
 
+	__hw_addr_init(&emac->vlan_mcast_list[vid]);
 	netdev_err(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
 		   vid, port_mask, untag_mask);
 
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index f5c1d473e9f9..4da8b87408b5 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -83,6 +83,10 @@
 #define ICSS_CMD_ADD_FILTER 0x7
 #define ICSS_CMD_ADD_MAC 0x8
 
+/* VLAN Filtering Related MACROs */
+#define PRUETH_DFLT_VLAN_MAC	0
+#define MAX_VLAN_ID		256
+
 /* In switch mode there are 3 real ports i.e. 3 mac addrs.
  * however Linux sees only the host side port. The other 2 ports
  * are the switch ports.
@@ -201,6 +205,8 @@ struct prueth_emac {
 	/* RX IRQ Coalescing Related */
 	struct hrtimer rx_hrtimer;
 	unsigned long rx_pace_timeout_ns;
+
+	struct netdev_hw_addr_list vlan_mcast_list[MAX_VLAN_ID];
 };
 
 /**
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d917949bba03..a5c169b19543 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -4685,6 +4685,9 @@ int devm_register_netdev(struct device *dev, struct net_device *ndev);
 /* General hardware address lists handling functions */
 int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
 		   struct netdev_hw_addr_list *from_list, int addr_len);
+int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
+			    struct netdev_hw_addr_list *from_list,
+			    int addr_len);
 void __hw_addr_unsync(struct netdev_hw_addr_list *to_list,
 		      struct netdev_hw_addr_list *from_list, int addr_len);
 int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 166e404f7c03..90716bd736f3 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -242,9 +242,9 @@ static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list,
 	__hw_addr_del_entry(from_list, ha, false, false);
 }
 
-static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
-				   struct netdev_hw_addr_list *from_list,
-				   int addr_len)
+int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
+			    struct netdev_hw_addr_list *from_list,
+			    int addr_len)
 {
 	int err = 0;
 	struct netdev_hw_addr *ha, *tmp;
@@ -260,6 +260,7 @@ static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
 	}
 	return err;
 }
+EXPORT_SYMBOL(__hw_addr_sync_multiple);
 
 /* This function only works where there is a strict 1-1 relationship
  * between source and destination of they synch. If you ever need to
-- 
2.34.1



From danishanwar at ti.com  Mon Dec 16 02:00:41 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 16 Dec 2024 15:30:41 +0530
Subject: [PATCH net-next 1/4] net: ti: Kconfig: Select HSR for ICSSG Driver
In-Reply-To: <20241216100044.577489-1-danishanwar@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
Message-ID: <20241216100044.577489-2-danishanwar@ti.com>

HSR offloading is supported by ICSSG driver. Select the symbol HSR for
TI_ICSSG_PRUETH. Also select NET_SWITCHDEV instead of depending on it to
remove recursive dependency.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 drivers/net/ethernet/ti/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index 0d5a862cd78a..ad366abfa746 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -187,8 +187,9 @@ config TI_ICSSG_PRUETH
 	select PHYLIB
 	select TI_ICSS_IEP
 	select TI_K3_CPPI_DESC_POOL
+	select NET_SWITCHDEV
+	select HSR
 	depends on PRU_REMOTEPROC
-	depends on NET_SWITCHDEV
 	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
 	depends on PTP_1588_CLOCK_OPTIONAL
 	help
-- 
2.34.1



From danishanwar at ti.com  Mon Dec 16 02:00:44 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 16 Dec 2024 15:30:44 +0530
Subject: [PATCH net-next 4/4] net: ti: icssg-prueth: Add Support for Multicast filtering with VLAN in HSR mode
In-Reply-To: <20241216100044.577489-1-danishanwar@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
Message-ID: <20241216100044.577489-5-danishanwar@ti.com>

Add multicast filtering support for VLAN interfaces in HSR offload mode
for ICSSG driver.

The driver calls vlan_for_each() API on the hsr device's ndev to get the
list of available vlans for the hsr device. The driver then sync mc addr of
vlan interface with a locally mainatined list emac->vlan_mcast_list[vid]
using __hw_addr_sync_multiple() API.

The driver then calls the sync / unsync callbacks.

In the sync / unsync call back, driver checks if the vdev's real dev is
hsr device or not. If the real dev is hsr device, driver gets the per
port device using hsr_get_port_ndev() and then driver passes appropriate
vid to FDB helper functions.

This commit makes below changes in the hsr files.
- Move enum hsr_port_type from net/hsr/hsr_main.h to include/linux/if_hsr.h
  so that the enum can be accessed by drivers using hsr.
- Create hsr_get_port_ndev() API that can be used to get the ndev
  pointer to the slave port from ndev pointer to the hsr net device.
- Export hsr_get_port_ndev() API so that the API can be accessed by
  drivers using hsr.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 88 ++++++++++++++------
 drivers/net/ethernet/ti/icssg/icssg_prueth.h |  2 +
 include/linux/if_hsr.h                       | 16 ++++
 net/hsr/hsr_device.c                         | 12 +++
 net/hsr/hsr_main.h                           |  9 --
 5 files changed, 93 insertions(+), 34 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index a18773ef6eab..4b13787a5fa8 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -514,32 +514,64 @@ static int icssg_prueth_del_mcast(struct net_device *ndev, const u8 *addr)
 	return 0;
 }
 
-static int icssg_prueth_hsr_add_mcast(struct net_device *ndev, const u8 *addr)
+static void icssg_prueth_hsr_fdb_add_del(struct prueth_emac *emac,
+					 const u8 *addr, u8 vid, bool add)
 {
-	struct prueth_emac *emac = netdev_priv(ndev);
-	struct prueth *prueth = emac->prueth;
-
-	icssg_fdb_add_del(emac, addr, prueth->default_vlan,
+	icssg_fdb_add_del(emac, addr, vid,
 			  ICSSG_FDB_ENTRY_P0_MEMBERSHIP |
 			  ICSSG_FDB_ENTRY_P1_MEMBERSHIP |
 			  ICSSG_FDB_ENTRY_P2_MEMBERSHIP |
-			  ICSSG_FDB_ENTRY_BLOCK, true);
+			  ICSSG_FDB_ENTRY_BLOCK, add);
+
+	if (add)
+		icssg_vtbl_modify(emac, vid, BIT(emac->port_id),
+				  BIT(emac->port_id), add);
+}
+
+static int icssg_prueth_hsr_add_mcast(struct net_device *ndev, const u8 *addr)
+{
+	struct net_device *real_dev;
+	struct prueth_emac *emac;
+	u8 vlan_id, i;
+
+	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_HSR;
+	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
+
+	if (is_hsr_master(real_dev)) {
+		for (i = HSR_PT_SLAVE_A; i < HSR_PT_INTERLINK; i++) {
+			emac = netdev_priv(hsr_get_port_ndev(real_dev, i));
+			if (!emac)
+				return -EINVAL;
+			icssg_prueth_hsr_fdb_add_del(emac, addr, vlan_id, true);
+		}
+	} else {
+		emac = netdev_priv(real_dev);
+		icssg_prueth_hsr_fdb_add_del(emac, addr, vlan_id, true);
+	}
 
-	icssg_vtbl_modify(emac, emac->port_vlan, BIT(emac->port_id),
-			  BIT(emac->port_id), true);
 	return 0;
 }
 
 static int icssg_prueth_hsr_del_mcast(struct net_device *ndev, const u8 *addr)
 {
-	struct prueth_emac *emac = netdev_priv(ndev);
-	struct prueth *prueth = emac->prueth;
+	struct net_device *real_dev;
+	struct prueth_emac *emac;
+	u8 vlan_id, i;
 
-	icssg_fdb_add_del(emac, addr, prueth->default_vlan,
-			  ICSSG_FDB_ENTRY_P0_MEMBERSHIP |
-			  ICSSG_FDB_ENTRY_P1_MEMBERSHIP |
-			  ICSSG_FDB_ENTRY_P2_MEMBERSHIP |
-			  ICSSG_FDB_ENTRY_BLOCK, false);
+	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_HSR;
+	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
+
+	if (is_hsr_master(real_dev)) {
+		for (i = HSR_PT_SLAVE_A; i < HSR_PT_INTERLINK; i++) {
+			emac = netdev_priv(hsr_get_port_ndev(real_dev, i));
+			if (!emac)
+				return -EINVAL;
+			icssg_prueth_hsr_fdb_add_del(emac, addr, vlan_id, false);
+		}
+	} else {
+		emac = netdev_priv(real_dev);
+		icssg_prueth_hsr_fdb_add_del(emac, addr, vlan_id, false);
+	}
 
 	return 0;
 }
@@ -547,21 +579,23 @@ static int icssg_prueth_hsr_del_mcast(struct net_device *ndev, const u8 *addr)
 static int icssg_update_vlan_mcast(struct net_device *vdev, int vid,
 				   void *args)
 {
-	struct net_device *vport_ndev;
-	struct prueth_emac *emac;
+	struct prueth_emac *emac = args;
 
 	if (!vdev || !vid)
 		return 0;
 
-	vport_ndev = vlan_dev_real_dev(vdev);
-	emac = netdev_priv(vport_ndev);
-
 	netif_addr_lock_bh(vdev);
 	__hw_addr_sync_multiple(&emac->vlan_mcast_list[vid], &vdev->mc, vdev->addr_len);
 	netif_addr_unlock_bh(vdev);
 
-	__hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
-			   icssg_prueth_add_mcast, icssg_prueth_del_mcast);
+	if (emac->prueth->is_hsr_offload_mode)
+		__hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
+				   icssg_prueth_hsr_add_mcast,
+				   icssg_prueth_hsr_del_mcast);
+	else
+		__hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
+				   icssg_prueth_add_mcast,
+				   icssg_prueth_del_mcast);
 
 	return 0;
 }
@@ -810,11 +844,15 @@ static void emac_ndo_set_rx_mode_work(struct work_struct *work)
 	if (emac->prueth->is_hsr_offload_mode) {
 		__dev_mc_sync(ndev, icssg_prueth_hsr_add_mcast,
 			      icssg_prueth_hsr_del_mcast);
+		if (rtnl_trylock()) {
+			vlan_for_each(emac->prueth->hsr_dev, icssg_update_vlan_mcast, emac);
+			rtnl_unlock();
+		}
 	} else {
 		__dev_mc_sync(ndev, icssg_prueth_add_mcast,
 			      icssg_prueth_del_mcast);
 		if (rtnl_trylock()) {
-			vlan_for_each(ndev, icssg_update_vlan_mcast, NULL);
+			vlan_for_each(ndev, icssg_update_vlan_mcast, emac);
 			rtnl_unlock();
 		}
 	}
@@ -1196,7 +1234,7 @@ static int prueth_netdevice_port_link(struct net_device *ndev,
 		if (prueth->br_members & BIT(PRUETH_PORT_MII0) &&
 		    prueth->br_members & BIT(PRUETH_PORT_MII1)) {
 			prueth->is_switch_mode = true;
-			prueth->default_vlan = 1;
+			prueth->default_vlan = PRUETH_DFLT_VLAN_SW;
 			emac->port_vlan = prueth->default_vlan;
 			icssg_change_mode(prueth);
 		}
@@ -1249,7 +1287,7 @@ static int prueth_hsr_port_link(struct net_device *ndev)
 			      NETIF_PRUETH_HSR_OFFLOAD_FEATURES))
 				return -EOPNOTSUPP;
 			prueth->is_hsr_offload_mode = true;
-			prueth->default_vlan = 1;
+			prueth->default_vlan = PRUETH_DFLT_VLAN_HSR;
 			emac0->port_vlan = prueth->default_vlan;
 			emac1->port_vlan = prueth->default_vlan;
 			icssg_change_mode(prueth);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index 4da8b87408b5..956cb59d98b2 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -84,6 +84,8 @@
 #define ICSS_CMD_ADD_MAC 0x8
 
 /* VLAN Filtering Related MACROs */
+#define PRUETH_DFLT_VLAN_HSR	1
+#define PRUETH_DFLT_VLAN_SW	1
 #define PRUETH_DFLT_VLAN_MAC	0
 #define MAX_VLAN_ID		256
 
diff --git a/include/linux/if_hsr.h b/include/linux/if_hsr.h
index 0404f5bf4f30..d97e1d1599f0 100644
--- a/include/linux/if_hsr.h
+++ b/include/linux/if_hsr.h
@@ -13,6 +13,15 @@ enum hsr_version {
 	PRP_V1,
 };
 
+enum hsr_port_type {
+	HSR_PT_NONE = 0,	/* Must be 0, used by framereg */
+	HSR_PT_SLAVE_A,
+	HSR_PT_SLAVE_B,
+	HSR_PT_INTERLINK,
+	HSR_PT_MASTER,
+	HSR_PT_PORTS,	/* This must be the last item in the enum */
+};
+
 /* HSR Tag.
  * As defined in IEC-62439-3:2010, the HSR tag is really { ethertype = 0x88FB,
  * path, LSDU_size, sequence Nr }. But we let eth_header() create { h_dest,
@@ -32,6 +41,7 @@ struct hsr_tag {
 #if IS_ENABLED(CONFIG_HSR)
 extern bool is_hsr_master(struct net_device *dev);
 extern int hsr_get_version(struct net_device *dev, enum hsr_version *ver);
+struct net_device *hsr_get_port_ndev(struct net_device *ndev, enum hsr_port_type pt);
 #else
 static inline bool is_hsr_master(struct net_device *dev)
 {
@@ -42,6 +52,12 @@ static inline int hsr_get_version(struct net_device *dev,
 {
 	return -EINVAL;
 }
+
+static inline struct net_device *hsr_get_port_ndev(struct net_device *ndev, enum hsr_port_type pt)
+{
+	return ERR_PTR(-EINVAL);
+}
+
 #endif /* CONFIG_HSR */
 
 #endif /*_LINUX_IF_HSR_H_*/
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
index 03eadd6c51fd..1e1cbfd02778 100644
--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -663,6 +663,18 @@ bool is_hsr_master(struct net_device *dev)
 }
 EXPORT_SYMBOL(is_hsr_master);
 
+struct net_device *hsr_get_port_ndev(struct net_device *ndev, enum hsr_port_type pt)
+{
+	struct hsr_priv *hsr = netdev_priv(ndev);
+	struct hsr_port *port;
+
+	hsr_for_each_port(hsr, port)
+		if (port->type == pt)
+			return port->dev;
+	return NULL;
+}
+EXPORT_SYMBOL(hsr_get_port_ndev);
+
 /* Default multicast address for HSR Supervision frames */
 static const unsigned char def_multicast_addr[ETH_ALEN] __aligned(2) = {
 	0x01, 0x15, 0x4e, 0x00, 0x01, 0x00
diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
index fcfeb79bb040..db7d88c05b7f 100644
--- a/net/hsr/hsr_main.h
+++ b/net/hsr/hsr_main.h
@@ -121,15 +121,6 @@ struct hsrv1_ethhdr_sp {
 	struct hsr_sup_tag	hsr_sup;
 } __packed;
 
-enum hsr_port_type {
-	HSR_PT_NONE = 0,	/* Must be 0, used by framereg */
-	HSR_PT_SLAVE_A,
-	HSR_PT_SLAVE_B,
-	HSR_PT_INTERLINK,
-	HSR_PT_MASTER,
-	HSR_PT_PORTS,	/* This must be the last item in the enum */
-};
-
 /* PRP Redunancy Control Trailor (RCT).
  * As defined in IEC-62439-4:2012, the PRP RCT is really { sequence Nr,
  * Lan indentifier (LanId), LSDU_size and PRP_suffix = 0x88FB }.
-- 
2.34.1



From mark.rutland at arm.com  Mon Dec 16 02:02:34 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 16 Dec 2024 10:02:34 +0000
Subject: [GIT PULL] arm64 fixes for 6.13-rc3
In-Reply-To: <Z18MixiGByAqDYLC@lappy>
References: <Z1xx0ha7lbKkdhRC@arm.com>
 <Z18MixiGByAqDYLC@lappy>
Message-ID: <Z1_6ukG_Lc5leG1o@J2N7QTR9R3>

On Sun, Dec 15, 2024 at 12:06:19PM -0500, Sasha Levin wrote:
> On Fri, Dec 13, 2024 at 05:41:38PM +0000, Catalin Marinas wrote:
> > - arm64 stacktrace: address some fallout from the recent changes to
> >  unwinding across exception boundaries
> 
> Hi Catalin, Mark,
> 
> It seems that kselftests can hit a warning that was addressed in the
> commit above:

I assume you're referring to commit:

  32ed1205682ec42a ("arm64: stacktrace: Skip reporting LR at exception boundaries")

... ?

That was intended to fix this specific issue, as explained in the commit
message (with a very similar splat from running the ftrace kselftests).

Am I missing something? i.e. are you saying it *doesn't* fix that?

Mark.

> <12>[   74.172204] kselftest: Running tests in ftrace
> TAP version 13
> 1..1
> # timeout set to 0
> # selftests: ftrace: ftracetest-ktap
> # unlink: cannot unlink '/opt/kselftests/default-in-kernel/ftrace/logs/latest': No such file or directory
> # TAP version 13
> # 1..145
> # ok 1 Basic trace file check
> <4>[  108.427656] hrtimer: interrupt took 13044036 ns
> <4>[  161.249175] sched: DL replenish lagged too much
> <4>[  163.845977] ------------[ cut here ]------------
> <4>[  163.851787] WARNING: CPU: 1 PID: 31 at arch/arm64/kernel/stacktrace.c:141 arch_stack_walk+0x4a0/0x4b0
> <4>[  163.861012] Modules linked in: crct10dif_ce sm3_ce sm3 sha3_ce sha512_ce sha512_arm64 fuse drm backlight ip_tables x_tables
> <4>[  163.890268] CPU: 1 UID: 0 PID: 31 Comm: kworker/1:1 Not tainted 6.13.0-rc2 #1
> <4>[  163.897386] Hardware name: linux,dummy-virt (DT)
> <4>[  163.904217] Workqueue:  0x0 (mm_percpu_wq)
> <4>[  163.915526] pstate: 624020c9 (nZCv daIF +PAN -UAO +TCO -DIT -SSBS BTYPE=--)
> <4>[  163.924218] pc : arch_stack_walk+0x4a0/0x4b0
> <4>[  163.930593] lr : arch_stack_walk+0x2bc/0x4b0
> <4>[  163.937101] sp : ffff80008000b920
> <4>[  163.942456] x29: ffff80008000b9d0 x28: fff00000ff6d9400 x27: fff00000ff6d9928
> <4>[  163.954275] x26: 0000000000000001 x25: 00000000000000c0 x24: ffffae003d389d40
> <4>[  163.967208] x23: 09cfae003ae216b4 x22: ffffae003ae2e4b0 x21: ffffae003ae35c70
> <4>[  163.978823] x20: ffff80008000ba10 x19: ffffae003ae216f0 x18: 0000000000000014
> <4>[  163.989751] x17: 0000000000000000 x16: ffff800080008000 x15: 00000000b5b23a12
> <4>[  164.000780] x14: 000000005865dcaf x13: 00000000b77eca6d x12: 0000959eae5a34e8
> <4>[  164.011592] x11: ffffae003d44a670 x10: ffff80008000b920 x9 : ffffae003ae2e4b0
> <4>[  164.022498] x8 : ffff800080043e00 x7 : fff00000c682c000 x6 : 00000000ffffffff
> <4>[  164.033396] x5 : fff00000c682c000 x4 : 0000000000000000 x3 : ffff80008000bda0
> <4>[  164.045100] x2 : ffffae003ae2e4b0 x1 : ffffae003ae2e4b0 x0 : ffffae003ae2e4b0
> <4>[  164.057084] Call trace:
> <4>[  164.061489]  arch_stack_walk+0x4a0/0x4b0 (P)
> <4>[  164.067225]  arch_stack_walk+0x2bc/0x4b0 (L)
> <4>[  164.073009]  profile_pc+0x44/0x80
> <4>[  164.078489]  profile_tick+0x50/0x80 (F)
> <4>[  164.085151]  tick_nohz_handler+0xcc/0x160 (F)
> <4>[  164.091427]  __hrtimer_run_queues+0x2c4/0x358 (F)
> <4>[  164.098138]  hrtimer_interrupt+0xf4/0x268 (F)
> <4>[  164.105401]  arch_timer_handler_phys+0x34/0x58 (F)
> <4>[  164.114958]  handle_percpu_devid_irq+0x8c/0x218 (F)
> <4>[  164.120914]  generic_handle_domain_irq+0x34/0x58 (F)
> <4>[  164.127570]  gic_handle_irq+0x54/0x128 (F)
> <4>[  164.135008]  do_interrupt_handler+0x58/0x98 (F)
> <4>[  164.140769]  el1_interrupt+0x34/0x68 (F)
> <4>[  164.146665]  el1h_64_irq_handler+0x18/0x28
> <4>[  164.151813]  el1h_64_irq+0x6c/0x70
> <4>[  164.160007]  _raw_spin_unlock_irq+0x28/0x58 (PF)
> <4>[  164.176292] ------------[ cut here ]------------
> <4>[  164.187816] WARNING: CPU: 1 PID: 31 at arch/arm64/kernel/stacktrace.c:141 dump_backtrace+0x620/0x660
> <4>[  164.209007] Modules linked in: crct10dif_ce sm3_ce sm3 sha3_ce sha512_ce sha512_arm64 fuse drm backlight ip_tables x_tables
> <4>[  164.252638] CPU: 1 UID: 0 PID: 31 Comm: kworker/1:1 Not tainted 6.13.0-rc2 #1
> <4>[  164.260491] Hardware name: linux,dummy-virt (DT)
> <4>[  164.266531] Workqueue:  0x0 (mm_percpu_wq)
> <4>[  164.275972] pstate: 624023c9 (nZCv DAIF +PAN -UAO +TCO -DIT -SSBS BTYPE=--)
> <4>[  164.282685] pc : dump_backtrace+0x620/0x660
> <4>[  164.288093] lr : dump_backtrace+0x410/0x660
> <4>[  164.293392] sp : ffff80008000b510
> <4>[  164.297983] x29: ffff80008000b5c0 x28: fff00000c08c91c0 x27: fff00000ff6d9928
> <4>[  164.309075] x26: ffff80008000bda0 x25: ffffae003cd0c000 x24: ffffae003cedfaa0
> <4>[  164.320534] x23: ffffae003cce90b8 x22: ffffae003ae35c70 x21: ffffae003ccd80a8
> <4>[  164.331352] x20: ffffae003cd1fd38 x19: fff00000c08c91c0 x18: 0000000000000006
> <4>[  164.343050] x17: 0000000000000000 x16: ffff800080008000 x15: ffff80008000af40
> <4>[  164.354100] x14: ffff80010000b0fa x13: ffff80008000b102 x12: ffffae003d410098
> <4>[  164.366177] x11: ffffae003d44a670 x10: ffff80008000b350 x9 : ffffae003ae2e4b0
> <4>[  164.378146] x8 : ffff800080043e00 x7 : fff00000c682c000 x6 : 00000000ffffffff
> <4>[  164.389041] x5 : fff00000c682c000 x4 : 0000000000000000 x3 : ffff80008000bda0
> <4>[  164.400262] x2 : ffffae003ae2e4b0 x1 : ffffae003ae2e4b0 x0 : ffffae003ae2e4b0
> <4>[  164.411526] Call trace:
> <4>[  164.415800]  dump_backtrace+0x620/0x660 (P)
> <4>[  164.421415]  dump_backtrace+0x410/0x660 (L)
> <4>[  164.427393]  show_regs+0x34/0x50 (F)
> <4>[  164.434342]  __warn+0x98/0x198 (F)
> <4>[  164.439610]  report_bug+0x1dc/0x200 (F)
> <4>[  164.444981]  bug_handler+0x2c/0x90
> <4>[  164.450151]  call_break_hook+0x6c/0x88 (F)
> <4>[  164.455802]  brk_handler+0x24/0x70 (F)
> <4>[  164.460935]  do_debug_exception+0x74/0x118 (F)
> <4>[  164.466742]  el1_dbg+0x70/0x90 (F)
> <4>[  164.471595]  el1h_64_sync_handler+0xd4/0x120
> <4>[  164.477225]  el1h_64_sync+0x6c/0x70
> <4>[  164.482730]  arch_stack_walk+0x4a0/0x4b0 (P)
> <4>[  164.488313]  arch_stack_walk+0x2bc/0x4b0 (L)
> <4>[  164.494329]  profile_pc+0x44/0x80
> <4>[  164.499430]  profile_tick+0x50/0x80 (F)
> <4>[  164.504776]  tick_nohz_handler+0xcc/0x160 (F)
> <4>[  164.511508]  __hrtimer_run_queues+0x2c4/0x358 (F)
> <4>[  164.519213]  hrtimer_interrupt+0xf4/0x268 (F)
> <4>[  164.525536]  arch_timer_handler_phys+0x34/0x58 (F)
> <4>[  164.531384]  handle_percpu_devid_irq+0x8c/0x218 (F)
> <4>[  164.537153]  generic_handle_domain_irq+0x34/0x58 (F)
> <4>[  164.543448]  gic_handle_irq+0x54/0x128 (F)
> <4>[  164.548744]  do_interrupt_handler+0x58/0x98 (F)
> <4>[  164.555359]  el1_interrupt+0x34/0x68 (F)
> <4>[  164.561123]  el1h_64_irq_handler+0x18/0x28
> <4>[  164.567261]  el1h_64_irq+0x6c/0x70
> <4>[  164.573197]  _raw_spin_unlock_irq+0x28/0x58 (PF)
> <4>[  164.580018] ---[ end trace 0000000000000000 ]---
> <4>[  164.585812] ---[ end trace 0000000000000000 ]---
> 
> -- 
> Thanks,
> Sasha
> 


From dmitry.baryshkov at linaro.org  Mon Dec 16 02:04:56 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 12:04:56 +0200
Subject: [PATCH v2 03/11] drm/rockchip: analogix_dp: Add support for
 RK3588
In-Reply-To: <4395748.ejJDZkT8p0@diego>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-4-damon.ding@rock-chips.com>
 <gwogudb5vae7wu452zwuqmdlyaibenoso4f5pjmu3uttckhy2w@shndol4mz5n4>
 <4395748.ejJDZkT8p0@diego>
Message-ID: <25bh2uy6wg3kcoqmnzt5dwfamc32bjyjlivkqq4cvne6kryj3z@svlz45bbaoy7>

On Mon, Dec 16, 2024 at 10:11:54AM +0100, Heiko St?bner wrote:
> Am Montag, 16. Dezember 2024, 09:57:41 CET schrieb Dmitry Baryshkov:
> > On Mon, Dec 16, 2024 at 11:12:17AM +0800, Damon Ding wrote:
> > > RK3588 integrates the analogix eDP 1.3 TX controller IP and the HDMI/eDP
> > > TX Combo PHY based on a Samsung IP block, and there are also two
> > > independent eDP display interface on RK3588 Soc.
> > > 
> > > Add just the basic support for now, i.e. RGB output up to 4K at 60Hz, without
> > > the tests of audio, PSR and other eDP 1.3 specific features.
> > > 
> > > Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> > > 
> > > ---
> > > 
> > > Changes in v2:
> > > - Add support for the other eDP output edp1
> > > ---
> > >  .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 82 ++++++++++++++++---
> > >  include/drm/bridge/analogix_dp.h              |  3 +-
> > >  2 files changed, 74 insertions(+), 11 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> > > index 871606a31ef1..4c9a55776ada 100644
> > > --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> > > +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> > > @@ -51,10 +51,12 @@ struct rockchip_grf_reg_field {
> > >  /**
> > >   * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
> > >   * @lcdc_sel: grf register field of lcdc_sel
> > > + * @edp_mode: grf register field of edp_mode
> > >   * @chip_type: specific chip type
> > >   */
> > >  struct rockchip_dp_chip_data {
> > >  	const struct rockchip_grf_reg_field lcdc_sel;
> > > +	const struct rockchip_grf_reg_field edp_mode;
> > >  	u32	chip_type;
> > >  };
> > >  
> > > @@ -134,12 +136,21 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
> > >  		return ret;
> > >  	}
> > >  
> > > +	ret = rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 1);
> > > +	if (ret != 0)
> > > +		DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);
> > 
> > Is it to be called for non-eDP hosts too? Or for older hosts?
> 
> The implementation of rockchip_grf_field_write (in patch1) seems to
> take care of checking if that field actually exists and doing nothing if
> not.
> 
> I think eDP/DP is more a naming thing, the Analogix controller is called
> an eDP controller in all documentation things.
> 
> Even back on rk3288, the Analogix-DP, still is called an eDP controller in
> documentation, with the only difference being that it does not contain
> another additional "dedicated" DP controller

At the very least this should be mentioned in the commit message.

> > > +	i = 0;
> > > +	while (is_rockchip(dp_data[i].chip_type))
> > > +		i++;
> > > +
> > > +	if (id >= i) {
> > > +		DRM_DEV_ERROR(dev, "invalid edp id: %d\n", id);
> > > +		return -ENODEV;
> > > +	}
> > 
> > Is it applicable to non-eDP case?
> 
> same as above, it's always called eDP in all pieces of documentation,
> (Compliant with DP 1.2 and eDP 1.3)

Ack

> 
> Heiko
> 
> > > +
> > >  	dp->dev = dev;
> > >  	dp->adp = ERR_PTR(-ENODEV);
> > > -	dp->data = dp_data;
> > > +	dp->data = &dp_data[id];
> > >  	dp->plat_data.panel = panel;
> > >  	dp->plat_data.dev_type = dp->data->chip_type;
> > >  	dp->plat_data.power_on = rockchip_dp_poweron;
> > > @@ -464,19 +507,38 @@ static int rockchip_dp_resume(struct device *dev)
> > >  static DEFINE_RUNTIME_DEV_PM_OPS(rockchip_dp_pm_ops, rockchip_dp_suspend,
> > >  		rockchip_dp_resume, NULL);
> > >  
> > > -static const struct rockchip_dp_chip_data rk3399_edp = {
> > > -	.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
> > > -	.chip_type = RK3399_EDP,
> > > +static const struct rockchip_dp_chip_data rk3399_edp[] = {
> > > +	{
> > > +		.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
> > > +		.chip_type = RK3399_EDP,
> > > +	},
> > > +	{ /* sentinel */ }
> > > +};
> > > +
> > > +static const struct rockchip_dp_chip_data rk3288_dp[] = {
> > > +	{
> > > +		.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
> > > +		.chip_type = RK3288_DP,
> > > +	},
> > > +	{ /* sentinel */ }
> > >  };
> > >  
> > > -static const struct rockchip_dp_chip_data rk3288_dp = {
> > > -	.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
> > > -	.chip_type = RK3288_DP,
> > > +static const struct rockchip_dp_chip_data rk3588_edp[] = {
> > > +	{
> > > +		.edp_mode = GRF_REG_FIELD(0x0000, 0, 0),
> > > +		.chip_type = RK3588_EDP,
> > > +	},
> > > +	{
> > > +		.edp_mode = GRF_REG_FIELD(0x0004, 0, 0),
> > > +		.chip_type = RK3588_EDP,
> > > +	},
> > > +	{ /* sentinel */ }
> > >  };
> > >  
> > >  static const struct of_device_id rockchip_dp_dt_ids[] = {
> > >  	{.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp },
> > >  	{.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp },
> > > +	{.compatible = "rockchip,rk3588-edp", .data = &rk3588_edp },
> > >  	{}
> > >  };
> > >  MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
> > > diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
> > > index 6002c5666031..54086cb2d97d 100644
> > > --- a/include/drm/bridge/analogix_dp.h
> > > +++ b/include/drm/bridge/analogix_dp.h
> > > @@ -15,11 +15,12 @@ enum analogix_dp_devtype {
> > >  	EXYNOS_DP,
> > >  	RK3288_DP,
> > >  	RK3399_EDP,
> > > +	RK3588_EDP,
> > >  };
> > >  
> > >  static inline bool is_rockchip(enum analogix_dp_devtype type)
> > >  {
> > > -	return type == RK3288_DP || type == RK3399_EDP;
> > > +	return type == RK3288_DP || type == RK3399_EDP || type == RK3588_EDP;
> > >  }
> > >  
> > >  struct analogix_dp_plat_data {
> > 
> > 
> 
> 
> 
> 

-- 
With best wishes
Dmitry


From m.felsch at pengutronix.de  Mon Dec 16 02:05:23 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Mon, 16 Dec 2024 11:05:23 +0100
Subject: [PATCH v3 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241212-imx91tmu-v3-2-85e756b29437@nxp.com>
References: <20241212-imx91tmu-v3-0-85e756b29437@nxp.com>
 <20241212-imx91tmu-v3-2-85e756b29437@nxp.com>
Message-ID: <20241216100523.p5ay544cvhx3lyvu@pengutronix.de>

Hi,

On 24-12-12, Frank Li wrote:
> From: Pengfei Li <pengfei.li_1 at nxp.com>
> 
> Introduce support for the i.MX91 thermal monitoring unit, which features a
> single sensor for the CPU. The register layout differs from other chips,
> necessitating the creation of a dedicated file for this.
> 
> Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> change from v2 to v3
> - add IMX91_TMU_ prefix for register define
> - remove unused register define
> - fix missed pm_runtime_put() at error path in imx91_tmu_get_temp()
> - use dev variable in probe function
> - use pm_runtime_set_active() in probe
> - move START to imx91_tmu_get_temp()
> - use DEFINE_RUNTIME_DEV_PM_OPS()
> - keep set reset value because there are not sw "reset" bit in controller,
> uboot may change and enable tmu.
> 
> change from v1 to v2
> - use low case for hexvalue
> - combine struct imx91_tmu and tmu_sensor
> - simplify imx91_tmu_start() and imx91_tmu_enable()
> - use s16 for imx91_tmu_get_temp(), which may negative value
> - use reverse christmas tree style
> - use run time pm
> - use oneshot to sample temp
> - register thermal zone after hardware init
> ---
>  drivers/thermal/Kconfig         |  10 ++
>  drivers/thermal/Makefile        |   1 +
>  drivers/thermal/imx91_thermal.c | 263 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 274 insertions(+)
> 
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index d3f9686e26e71..da403ed86aeb1 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -296,6 +296,16 @@ config IMX8MM_THERMAL
>  	  cpufreq is used as the cooling device to throttle CPUs when the passive
>  	  trip is crossed.
>  
> +config IMX91_THERMAL
> +	tristate "Temperature sensor driver for NXP i.MX91 SoC"
> +	depends on ARCH_MXC || COMPILE_TEST
> +	depends on OF
> +	help
> +	  Support for Temperature sensor found on NXP i.MX91 SoC.
> +	  It supports one critical trip point and one passive trip point. The
> +	  cpufreq is used as the cooling device to throttle CPUs when the passive
> +	  trip is crossed.
> +
>  config K3_THERMAL
>  	tristate "Texas Instruments K3 thermal support"
>  	depends on ARCH_K3 || COMPILE_TEST
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index 9abf43a74f2bb..08da241e6a598 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
>  obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
>  obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
>  obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
> +obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
>  obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
>  obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
>  obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
> diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
> new file mode 100644
> index 0000000000000..62b579365fd03
> --- /dev/null
> +++ b/drivers/thermal/imx91_thermal.c
> @@ -0,0 +1,263 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2024 NXP.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/iopoll.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/thermal.h>
> +
> +#define IMX91_TMU_STAT0				0x10
> +#define IMX91_TMU_STAT0_DRDY0_IF_MASK		BIT(16)
> +
> +#define IMX91_TMU_DATA0				0x20
> +
> +#define IMX91_TMU_CTRL1_SET			0x204
> +#define IMX91_TMU_CTRL1_CLR			0x208
> +#define IMX91_TMU_CTRL1_EN			BIT(31)
> +#define IMX91_TMU_CTRL1_START			BIT(30)
> +#define IMX91_TMU_CTRL1_STOP			BIT(29)
> +#define IMX91_TMU_CTRL1_RES_MASK		GENMASK(19, 18)
> +#define IMX91_TMU_CTRL1_MEAS_MODE_MASK		GENMASK(25, 24)
> +#define   IMX91_TMU_CTRL1_MEAS_MODE_SINGLE	0
> +#define   IMX91_TMU_CTRL1_MEAS_MODE_CONTINUES	1
> +#define   IMX91_TMU_CTRL1_MEAS_MODE_PERIODIC	2
> +
> +#define IMX91_TMU_REF_DIV			0x280
> +#define IMX91_TMU_DIV_EN			BIT(31)
> +#define IMX91_TMU_DIV_MASK			GENMASK(23, 16)
> +#define IMX91_TMU_DIV_MAX			255
> +
> +#define IMX91_TMU_PUD_ST_CTRL			0x2b0
> +#define IMX91_TMU_PUDL_MASK			GENMASK(23, 16)
> +
> +#define IMX91_TMU_TRIM1				0x2e0
> +#define IMX91_TMU_TRIM2				0x2f0
> +
> +#define IMX91_TMU_TEMP_LOW_LIMIT		-40000
> +#define IMX91_TMU_TEMP_HIGH_LIMIT		125000
> +
> +#define IMX91_TMU_DEFAULT_TRIM1_CONFIG		0xb561bc2d
> +#define IMX91_TMU_DEFAULT_TRIM2_CONFIG		0x65d4
> +
> +struct imx91_tmu {
> +	void __iomem *base;
> +	struct clk *clk;
> +	struct device *dev;
> +	struct thermal_zone_device *tzd;
> +};
> +
> +static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
> +{
> +	u32 val = start ? IMX91_TMU_CTRL1_START : IMX91_TMU_CTRL1_STOP;
> +
> +	writel_relaxed(val, tmu->base + IMX91_TMU_CTRL1_SET);
> +}
> +
> +static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
> +{
> +	u32 reg = enable ? IMX91_TMU_CTRL1_SET : IMX91_TMU_CTRL1_CLR;
> +
> +	writel_relaxed(IMX91_TMU_CTRL1_EN, tmu->base + reg);
> +}
> +
> +static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
> +{
> +	struct imx91_tmu *tmu = thermal_zone_device_priv(tz);
> +	s16 data;
> +	int ret;
> +	u32 val;
> +
> +	ret = pm_runtime_resume_and_get(tmu->dev);
> +	if (ret < 0)
> +		return ret;
> +
> +	imx91_tmu_start(tmu, true);
> +
> +	ret = readl_relaxed_poll_timeout(tmu->base + IMX91_TMU_STAT0, val,
> +					 val & IMX91_TMU_STAT0_DRDY0_IF_MASK, 1000, 40000);
> +	if (ret) {
> +		ret = -EAGAIN;
> +		goto out;
> +	}
> +
> +	/* DATA0 is 16bit signed number */
> +	data = readw_relaxed(tmu->base + IMX91_TMU_DATA0);
> +	*temp = data * 1000 / 64;
> +	if (*temp < IMX91_TMU_TEMP_LOW_LIMIT || *temp > IMX91_TMU_TEMP_HIGH_LIMIT)
> +		ret = -EAGAIN;
> +
> +out:
> +	pm_runtime_put(tmu->dev);
> +
> +	return ret;
> +}
> +
> +static struct thermal_zone_device_ops tmu_tz_ops = {
> +	.get_temp = imx91_tmu_get_temp,
> +};
> +
> +static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
> +{
> +	struct device *dev = tmu->dev;
> +	u32 trim1, trim2;
> +	int ret;
> +
> +	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
> +	if (ret)
> +		return ret;
> +
> +	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
> +	if (ret)
> +		return ret;
> +
> +	if (trim1 == 0 || trim2 == 0)
> +		return -EINVAL;
> +
> +	writel_relaxed(trim1, tmu->base + IMX91_TMU_TRIM1);
> +	writel_relaxed(trim2, tmu->base + IMX91_TMU_TRIM2);
> +
> +	return 0;
> +}
> +
> +static int imx91_tmu_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct imx91_tmu *tmu;
> +	unsigned long rate;
> +	u32 div;
> +	int ret;
> +
> +	tmu = devm_kzalloc(dev, sizeof(struct imx91_tmu), GFP_KERNEL);
> +	if (!tmu)
> +		return -ENOMEM;
> +
> +	tmu->dev = dev;
> +
> +	tmu->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(tmu->base))
> +		return dev_err_probe(dev, PTR_ERR(tmu->base), "failed to get io resource");
> +
> +	tmu->clk = devm_clk_get_enabled(dev, NULL);
> +	if (IS_ERR(tmu->clk))
> +		return dev_err_probe(dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
> +
> +	platform_set_drvdata(pdev, tmu);
> +
> +	/* disable the monitor during initialization */
> +	imx91_tmu_enable(tmu, false);
> +	imx91_tmu_start(tmu, false);
> +
> +	ret = imx91_init_from_nvmem_cells(tmu);
> +	if (ret) {
> +		writel_relaxed(IMX91_TMU_DEFAULT_TRIM1_CONFIG, tmu->base + IMX91_TMU_TRIM1);
> +		writel_relaxed(IMX91_TMU_DEFAULT_TRIM2_CONFIG, tmu->base + IMX91_TMU_TRIM2);
> +	}
> +
> +	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
> +	rate = clk_get_rate(tmu->clk);
> +	div = (rate / 4000000) - 1;
> +	if (div > IMX91_TMU_DIV_MAX)
> +		return dev_err_probe(dev, -EINVAL, "clock divider exceed hardware limiation");
> +
> +	/* Set divider value and enable divider */
> +	writel_relaxed(IMX91_TMU_DIV_EN | FIELD_PREP(IMX91_TMU_DIV_MASK, div),
> +		       tmu->base + IMX91_TMU_REF_DIV);
> +
> +	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
> +	writel_relaxed(FIELD_PREP(IMX91_TMU_PUDL_MASK, 100U), tmu->base + IMX91_TMU_PUD_ST_CTRL);
> +
> +	/*
> +	 * Set resolution mode
> +	 * 00b - Conversion time = 0.59325 ms
> +	 * 01b - Conversion time = 1.10525 ms
> +	 * 10b - Conversion time = 2.12925 ms
> +	 * 11b - Conversion time = 4.17725 ms
> +	 */
> +	writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_RES_MASK, 0x3), tmu->base + IMX91_TMU_CTRL1_CLR);
> +	writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_RES_MASK, 0x1), tmu->base + IMX91_TMU_CTRL1_SET);
> +
> +	writel_relaxed(IMX91_TMU_CTRL1_MEAS_MODE_MASK, tmu->base + IMX91_TMU_CTRL1_CLR);
> +	writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_MEAS_MODE_MASK, IMX91_TMU_CTRL1_MEAS_MODE_SINGLE),
> +		       tmu->base + IMX91_TMU_CTRL1_SET);
> +
> +	imx91_tmu_enable(tmu, true);

Nit: I don't think that this is necessary, albeit it's not wrong.

> +	pm_runtime_set_active(dev);
> +	devm_pm_runtime_enable(dev);
> +
> +	tmu->tzd = devm_thermal_of_zone_register(dev, 0, tmu, &tmu_tz_ops);
> +	if (IS_ERR(tmu->tzd))
> +		return dev_err_probe(dev, PTR_ERR(tmu->tzd),
> +				     "failed to register thermal zone sensor\n");

This return will leave the pm_runtime in the wrong state now. I'm Not
sure if the thermal_of_zone_register() requires the device to be
operational. If not, we can move

> +	pm_runtime_put(dev);

above the devm_thermal_of_zone_register() call.

> +
> +	return 0;
> +}
> +
> +static void imx91_tmu_remove(struct platform_device *pdev)
> +{
> +	struct imx91_tmu *tmu = platform_get_drvdata(pdev);
> +
> +	/* disable tmu */
> +	imx91_tmu_start(tmu, false);

Nit: Still not needed to disable the start, as the start bit is
self-clearing, since we're running in one-shot mode.

> +	imx91_tmu_enable(tmu, false);
> +}

If we put the imx91_tmu_enable() into a devm_add_action() hook, we can
drop the .remove callback completely.

With the above addressed, feel free to add my:

Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>

Regards,
  Marco

> +static int imx91_tmu_runtime_suspend(struct device *dev)
> +{
> +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> +
> +	/* disable tmu */
> +	imx91_tmu_enable(tmu, false);
> +
> +	clk_disable_unprepare(tmu->clk);
> +
> +	return 0;
> +}
> +
> +static int imx91_tmu_runtime_resume(struct device *dev)
> +{
> +	struct imx91_tmu *tmu = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = clk_prepare_enable(tmu->clk);
> +	if (ret)
> +		return ret;
> +
> +	imx91_tmu_enable(tmu, true);
> +
> +	return 0;
> +}
> +
> +static DEFINE_RUNTIME_DEV_PM_OPS(imx91_tmu_pm_ops, imx91_tmu_runtime_suspend,
> +				 imx91_tmu_runtime_resume, NULL);
> +
> +static const struct of_device_id imx91_tmu_table[] = {
> +	{ .compatible = "fsl,imx91-tmu", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, imx91_tmu_table);
> +
> +static struct platform_driver imx91_tmu = {
> +	.driver = {
> +		.name	= "imx91_thermal",
> +		.pm	= pm_ptr(&imx91_tmu_pm_ops),
> +		.of_match_table = imx91_tmu_table,
> +	},
> +	.probe = imx91_tmu_probe,
> +	.remove = imx91_tmu_remove,
> +};
> +module_platform_driver(imx91_tmu);
> +
> +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> +MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
> +MODULE_LICENSE("GPL");
> 
> -- 
> 2.34.1
> 
> 


From tomi.valkeinen at ideasonboard.com  Mon Dec 16 02:05:43 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Mon, 16 Dec 2024 12:05:43 +0200
Subject: [PATCHv3] drm: zynqmp_dp: Fix integer overflow in
 zynqmp_dp_rate_get()
In-Reply-To: <20241215125355.938953-1-karprzy7@gmail.com>
References: <20241215125355.938953-1-karprzy7@gmail.com>
Message-ID: <062e6b9d-44ca-49e8-8be0-f6a853938c53@ideasonboard.com>

Hi,

On 15/12/2024 14:53, Karol Przybylski wrote:
> This patch fixes a potential integer overflow in the zynqmp_dp_rate_get()
> 
> The issue comes up when the expression
> drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000 is evaluated using 32-bit
> Now the constant is a compatible 64-bit type.
> 
> Resolves coverity issues: CID 1636340 and CID 1635811
> 
> Cc: stable at vger.kernel.org
> Fixes: 28edaacb821c6 ("drm: zynqmp_dp: Add debugfs interface for compliance testing")
> Signed-off-by: Karol Przybylski <karprzy7 at gmail.com>
> ---
> Changes from previous versions:
> Added Fixes tag
> Added Cc for stable kernel version
> Fixed formatting
> 
>   drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index 25c5dc61ee88..56a261a40ea3 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -2190,7 +2190,7 @@ static int zynqmp_dp_rate_get(void *data, u64 *val)
>   	struct zynqmp_dp *dp = data;
>   
>   	mutex_lock(&dp->lock);
> -	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000;
> +	*val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000ULL;
>   	mutex_unlock(&dp->lock);
>   	return 0;
>   }

Thanks, pushed to drm-misc-next.

  Tomi



From christian.bruel at foss.st.com  Mon Dec 16 02:02:07 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 16 Dec 2024 11:02:07 +0100
Subject: [PATCH v2 4/5] PCI: stm32: Add PCIe endpoint support for
 STM32MP25
In-Reply-To: <20241203152230.5mdrt27u5u5ecwcz@thinkpad>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-5-christian.bruel@foss.st.com>
 <20241203152230.5mdrt27u5u5ecwcz@thinkpad>
Message-ID: <4e257489-4d90-4e47-a4d9-a2444627c356@foss.st.com>

Hi Manivanna,

On 12/3/24 16:22, Manivannan Sadhasivam wrote:
> On Tue, Nov 26, 2024 at 04:51:18PM +0100, Christian Bruel wrote:
> 
> [...]
> 
>> +static int stm32_pcie_start_link(struct dw_pcie *pci)
>> +{
>> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
>> +	int ret;
>> +
>> +	if (stm32_pcie->link_status == STM32_PCIE_EP_LINK_ENABLED) {
>> +		dev_dbg(pci->dev, "Link is already enabled\n");
>> +		return 0;
>> +	}
>> +
>> +	ret = stm32_pcie_enable_link(pci);
>> +	if (ret) {
>> +		dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret);
>> +		return ret;
>> +	}
> 
> How the REFCLK is supplied to the endpoint? From host or generated locally?

 From Host only, we don't support the separated clock model.

> 
>> +
>> +	stm32_pcie->link_status = STM32_PCIE_EP_LINK_ENABLED;
>> +
>> +	enable_irq(stm32_pcie->perst_irq);
>> +
>> +	return 0;
>> +}
>> +
>> +static void stm32_pcie_stop_link(struct dw_pcie *pci)
>> +{
>> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
>> +
>> +	if (stm32_pcie->link_status == STM32_PCIE_EP_LINK_DISABLED) {
>> +		dev_dbg(pci->dev, "Link is already disabled\n");
>> +		return;
>> +	}
>> +
>> +	disable_irq(stm32_pcie->perst_irq);
>> +
>> +	stm32_pcie_disable_link(pci);
>> +
>> +	stm32_pcie->link_status = STM32_PCIE_EP_LINK_DISABLED;
>> +}
>> +
>> +static int stm32_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>> +				unsigned int type, u16 interrupt_num)
>> +{
>> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>> +
>> +	switch (type) {
>> +	case PCI_IRQ_INTX:
>> +		return dw_pcie_ep_raise_intx_irq(ep, func_no);
>> +	case PCI_IRQ_MSI:
>> +		return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
>> +	default:
>> +		dev_err(pci->dev, "UNKNOWN IRQ type\n");
>> +		return -EINVAL;
>> +	}
>> +}
>> +
>> +static const struct pci_epc_features stm32_pcie_epc_features = {
>> +	.msi_capable = true,
>> +	.align = 1 << 16,
> 
> Use SZ_64K
> 

OK

>> +};
>> +
> 
> [...]
> 
>> +static int stm32_add_pcie_ep(struct stm32_pcie *stm32_pcie,
>> +			     struct platform_device *pdev)
>> +{
>> +	struct dw_pcie *pci = stm32_pcie->pci;
>> +	struct dw_pcie_ep *ep = &pci->ep;
>> +	struct device *dev = &pdev->dev;
>> +	int ret;
>> +
>> +	ret = regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
>> +				 STM32MP25_PCIECR_TYPE_MASK,
>> +				 STM32MP25_PCIECR_EP);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = pm_runtime_resume_and_get(dev);
>> +	if (ret < 0) {
>> +		dev_err(dev, "pm runtime resume failed: %d\n", ret);
>> +		return ret;
>> +	}
> 
> You might want to do runtime resume before accessing regmap.

OK

>> +
>> +	reset_control_assert(stm32_pcie->rst);
>> +	reset_control_deassert(stm32_pcie->rst);
>> +
>> +	ep->ops = &stm32_pcie_ep_ops;
>> +
>> +	ret = dw_pcie_ep_init(ep);
>> +	if (ret) {
>> +		dev_err(dev, "failed to initialize ep: %d\n", ret);
>> +		goto err_init;
>> +	}
>> +
>> +	ret = stm32_pcie_enable_resources(stm32_pcie);
>> +	if (ret) {
>> +		dev_err(dev, "failed to enable resources: %d\n", ret);
>> +		goto err_clk;
>> +	}
>> +
>> +	ret = dw_pcie_ep_init_registers(ep);
>> +	if (ret) {
>> +		dev_err(dev, "Failed to initialize DWC endpoint registers\n");
>> +		goto err_init_regs;
>> +	}
>> +
>> +	pci_epc_init_notify(ep->epc);
>> +
>> +	return 0;
>> +
>> +err_init_regs:
>> +	stm32_pcie_disable_resources(stm32_pcie);
>> +
>> +err_clk:
>> +	dw_pcie_ep_deinit(ep);
>> +
>> +err_init:
>> +	pm_runtime_put_sync(dev);
>> +	return ret;
>> +}
>> +
>> +static int stm32_pcie_probe(struct platform_device *pdev)
>> +{
>> +	struct stm32_pcie *stm32_pcie;
>> +	struct dw_pcie *dw;
>> +	struct device *dev = &pdev->dev;
>> +	int ret;
>> +
>> +	stm32_pcie = devm_kzalloc(dev, sizeof(*stm32_pcie), GFP_KERNEL);
>> +	if (!stm32_pcie)
>> +		return -ENOMEM;
>> +
>> +	dw = devm_kzalloc(dev, sizeof(*dw), GFP_KERNEL);
>> +	if (!dw)
>> +		return -ENOMEM;
> 
> Why can't you allocate it statically inside 'struct stm32_pcie'?

Will do

> 
>> +
>> +	stm32_pcie->pci = dw;
>> +
>> +	dw->dev = dev;
>> +	dw->ops = &dw_pcie_ops;
>> +
>> +	stm32_pcie->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
>> +	if (IS_ERR(stm32_pcie->regmap))
>> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->regmap),
>> +				     "No syscfg specified\n");
>> +
>> +	stm32_pcie->phy = devm_phy_get(dev, "pcie-phy");
>> +	if (IS_ERR(stm32_pcie->phy))
>> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->phy),
>> +				     "failed to get pcie-phy\n");
>> +
>> +	stm32_pcie->clk = devm_clk_get(dev, NULL);
>> +	if (IS_ERR(stm32_pcie->clk))
>> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->clk),
>> +				     "Failed to get PCIe clock source\n");
>> +
>> +	stm32_pcie->rst = devm_reset_control_get_exclusive(dev, NULL);
>> +	if (IS_ERR(stm32_pcie->rst))
>> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->rst),
>> +				     "Failed to get PCIe reset\n");
>> +
>> +	stm32_pcie->perst_gpio = devm_gpiod_get(dev, "reset", GPIOD_IN);
>> +	if (IS_ERR(stm32_pcie->perst_gpio))
>> +		return dev_err_probe(dev, PTR_ERR(stm32_pcie->perst_gpio),
>> +				     "Failed to get reset GPIO\n");
>> +
>> +	ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE);
> 
> Hmm, so PHY mode is common for both endpoint and host?

Yes it is. We need to init the phy here because it is a clock source for 
the PCIe core clk

Thanks

Christian

> 
> - Mani
> 


From damon.ding at rock-chips.com  Mon Dec 16 02:06:27 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 18:06:27 +0800
Subject: [PATCH v2 04/11] phy: phy-rockchip-samsung-hdptx: Add support for
 eDP mode
In-Reply-To: <3amy575wrx65kwf2kh5t2vx2f6vugq2bq3t6orpqlmbvnmq7oo@4mvt2lwgg3fh>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-5-damon.ding@rock-chips.com>
 <3amy575wrx65kwf2kh5t2vx2f6vugq2bq3t6orpqlmbvnmq7oo@4mvt2lwgg3fh>
Message-ID: <dc520394-1777-4810-8f4f-2bc1e258fd1e@rock-chips.com>

Hi Dmitry,

On 2024/12/16 17:00, Dmitry Baryshkov wrote:
> On Mon, Dec 16, 2024 at 11:12:18AM +0800, Damon Ding wrote:
>> Add basic support for RBR/HBR/HBR2 link rates, and the voltage swing and
>> pre-emphasis configurations of each link rate have been verified according
>> to the eDP 1.3 requirements.
>>
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>>
>> ---
>>
>> Changes in v2:
>> - Add the module author
>> ---
>>   .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 937 +++++++++++++++++-
>>   1 file changed, 894 insertions(+), 43 deletions(-)
>>
>> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> index 9f084697dd05..8dd0de267d10 100644
>> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> @@ -25,6 +25,7 @@
>>   #define HDPTX_I_PLL_EN			BIT(7)
>>   #define HDPTX_I_BIAS_EN			BIT(6)
>>   #define HDPTX_I_BGR_EN			BIT(5)
>> +#define HDPTX_MODE_SEL			BIT(0)
>>   #define GRF_HDPTX_STATUS		0x80
>>   #define HDPTX_O_PLL_LOCK_DONE		BIT(3)
>>   #define HDPTX_O_PHY_CLK_RDY		BIT(2)
>> @@ -44,6 +45,7 @@
>>   #define LANE_REG(n)			HDTPX_REG(n, 0300, 062d)
>>   
>>   /* CMN_REG(0008) */
>> +#define OVRD_LCPLL_EN_MASK		BIT(7)
>>   #define LCPLL_EN_MASK			BIT(6)
>>   #define LCPLL_LCVCO_MODE_EN_MASK	BIT(4)
>>   /* CMN_REG(001e) */
>> @@ -61,49 +63,110 @@
>>   /* CMN_REG(002f) */
>>   #define LCPLL_SDC_DENOMINATOR_MASK	GENMASK(7, 2)
>>   #define LCPLL_SDC_NDIV_RSTN		BIT(0)
>> +/* CMN_REG(003c) */
>> +#define ANA_LCPLL_RESERVED7_MASK	BIT(7)
>>   /* CMN_REG(003d) */
>> +#define OVRD_ROPLL_EN_MASK		BIT(7)
>> +#define ROPLL_EN_MASK			BIT(6)
>>   #define ROPLL_LCVCO_EN			BIT(4)
>> +/* CMN_REG(0046) */
>> +#define ROPLL_ANA_CPP_CTRL_COARSE_MASK	GENMASK(7, 4)
>> +#define ROPLL_ANA_CPP_CTRL_FINE_MASK	GENMASK(3, 0)
>> +/* CMN_REG(0047) */
>> +#define ROPLL_ANA_LPF_C_SEL_COARSE_MASK	GENMASK(5, 3)
>> +#define ROPLL_ANA_LPF_C_SEL_FINE_MASK	GENMASK(2, 0)
>>   /* CMN_REG(004e) */
>>   #define ROPLL_PI_EN			BIT(5)
>> +/* CMN_REG(0051) */
>> +#define ROPLL_PMS_MDIV_MASK		GENMASK(7, 0)
>> +/* CMN_REG(0055) */
>> +#define ROPLL_PMS_MDIV_AFC_MASK		GENMASK(7, 0)
>> +/* CMN_REG(0059) */
>> +#define ANA_ROPLL_PMS_PDIV_MASK		GENMASK(7, 4)
>> +#define ANA_ROPLL_PMS_REFDIV_MASK	GENMASK(3, 0)
>> +/* CMN_REG(005a) */
>> +#define ROPLL_PMS_SDIV_RBR_MASK		GENMASK(7, 4)
>> +#define ROPLL_PMS_SDIV_HBR_MASK		GENMASK(3, 0)
>> +/* CMN_REG(005b) */
>> +#define ROPLL_PMS_SDIV_HBR2_MASK	GENMASK(7, 4)
>>   /* 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)
> 
> You have mixed the redefinition of existing bitfields with addition of
> new ones. Please split them into separate patches: one for each of
> corrections (be sure to specify Fixes tag as required), one for generic
> renaming and one for the new platform and new registers / new bitfields)

Yes, it is better split this patch into two. I'll do it in the next version.

> 
>> +#define OVRD_ROPLL_SDM_RSTN_MASK	BIT(5)
>> +#define ROPLL_SDM_RSTN_MASK		BIT(4)
>> +#define ROPLL_SDC_FRAC_EN_RBR_MASK	BIT(3)
>> +#define ROPLL_SDC_FRAC_EN_HBR_MASK	BIT(2)
>> +#define ROPLL_SDC_FRAC_EN_HBR2_MASK	BIT(1)
>> +/* CMN_REG(005f) */
>> +#define OVRD_ROPLL_SDC_RSTN_MASK	BIT(5)
>> +#define ROPLL_SDC_RSTN_MASK		BIT(4)
>> +/* CMN_REG(0060)  */
>> +#define ROPLL_SDM_DENOMINATOR_MASK	GENMASK(7, 0)
>>   /* CMN_REG(0064) */
>>   #define ROPLL_SDM_NUM_SIGN_RBR_MASK	BIT(3)
>> +#define ROPLL_SDM_NUM_SIGN_HBR_MASK	BIT(2)
>> +#define ROPLL_SDM_NUM_SIGN_HBR2_MASK	BIT(1)
>> +/* CMN_REG(0065) */
>> +#define ROPLL_SDM_NUM_MASK		GENMASK(7, 0)
>>   /* CMN_REG(0069) */
>>   #define ROPLL_SDC_N_RBR_MASK		GENMASK(2, 0)
>> +/* CMN_REG(006a) */
>> +#define ROPLL_SDC_N_HBR_MASK		GENMASK(5, 3)
>> +#define ROPLL_SDC_N_HBR2_MASK		GENMASK(2, 0)
>> +/* CMN_REG(006b) */
>> +#define ROPLL_SDC_N_HBR3_MASK		GENMASK(3, 1)
>> +/* CMN_REG(006c) */
>> +#define ROPLL_SDC_NUM_MASK		GENMASK(5, 0)
>> +/* cmn_reg0070 */
>> +#define ROPLL_SDC_DENO_MASK		GENMASK(5, 0)
>>   /* CMN_REG(0074) */
>> -#define ROPLL_SDC_NDIV_RSTN		BIT(2)
>> -#define ROPLL_SSC_EN			BIT(0)
>> +#define OVRD_ROPLL_SDC_NDIV_RSTN_MASK	BIT(3)
>> +#define ROPLL_SDC_NDIV_RSTN_MASK	BIT(2)
>> +#define OVRD_ROPLL_SSC_EN_MASK		BIT(1)
>> +#define ROPLL_SSC_EN_MASK		BIT(0)
>> +/* CMN_REG(0075) */
>> +#define ANA_ROPLL_SSC_FM_DEVIATION_MASK	GENMASK(5, 0)
>> +/* CMN_REG(0076) */
>> +#define ANA_ROPLL_SSC_FM_FREQ_MASK	GENMASK(6, 2)
>> +/* CMN_REG(0077) */
>> +#define ANA_ROPLL_SSC_CLK_DIV_SEL_MASK	GENMASK(6, 3)
>>   /* CMN_REG(0081) */
>> -#define OVRD_PLL_CD_CLK_EN		BIT(8)
>> -#define PLL_CD_HSCLK_EAST_EN		BIT(0)
>> +#define ANA_PLL_CD_TX_SER_RATE_SEL_MASK	BIT(3)
>> +#define ANA_PLL_CD_HSCLK_WEST_EN_MASK	BIT(1)
>> +#define ANA_PLL_CD_HSCLK_EAST_EN_MASK	BIT(0)
>> +/* CMN_REG(0082) */
>> +#define ANA_PLL_CD_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
>> +/* CMN_REG(0083) */
>> +#define ANA_PLL_CD_VREG_ICTRL_MASK	GENMASK(6, 5)
>> +/* CMN_REG(0084) */
>> +#define PLL_LCRO_CLK_SEL_MASK		BIT(5)
>> +/* CMN_REG(0085) */
>> +#define ANA_PLL_SYNC_LOSS_DET_MODE_MASK	GENMASK(1, 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)
>> +#define ANA_PLL_FRL_MODE_EN_MASK	BIT(3)
>> +#define ANA_PLL_TX_HS_CLK_EN_MASK	BIT(2)
>>   /* CMN_REG(0089) */
>>   #define LCPLL_ALONE_MODE		BIT(1)
>> +/* CMN_REG(0095) */
>> +#define DP_TX_LINK_BW_MASK		GENMASK(1, 0)
>>   /* CMN_REG(0097) */
>> -#define DIG_CLK_SEL			BIT(1)
>> -#define ROPLL_REF			BIT(1)
>> -#define LCPLL_REF			0
>> +#define DIG_CLK_SEL_MASK		BIT(1)
>> +#define LCPLL_REF			BIT(1)
>> +#define ROPLL_REF			0
>>   /* CMN_REG(0099) */
>> +#define SSC_EN_MASK			GENMASK(7, 6)
>>   #define CMN_ROPLL_ALONE_MODE		BIT(2)
>>   #define ROPLL_ALONE_MODE		BIT(2)
>>   /* CMN_REG(009a) */
>> -#define HS_SPEED_SEL			BIT(0)
>> +#define HS_SPEED_SEL_MASK		BIT(0)
>>   #define DIV_10_CLOCK			BIT(0)
>>   /* CMN_REG(009b) */
>> -#define IS_SPEED_SEL			BIT(4)
>> +#define LS_SPEED_SEL_MASK		BIT(4)
>>   #define LINK_SYMBOL_CLOCK		BIT(4)
>>   #define LINK_SYMBOL_CLOCK1_2		0
>>   
>> @@ -118,6 +181,8 @@
>>   /* SB_REG(0104) */
>>   #define OVRD_SB_EN_MASK			BIT(5)
>>   #define SB_EN_MASK			BIT(4)
>> +#define OVRD_SB_AUX_EN_MASK		BIT(1)
>> +#define SB_AUX_EN_MASK			BIT(0)
>>   /* SB_REG(0105) */
>>   #define OVRD_SB_EARC_CMDC_EN_MASK	BIT(6)
>>   #define SB_EARC_CMDC_EN_MASK		BIT(5)
>> @@ -126,6 +191,8 @@
>>   #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(010d) */
>> +#define ANA_SB_DMRX_LPBK_DATA_MASK	BIT(4)
>>   /* SB_REG(010f) */
>>   #define OVRD_SB_VREG_EN_MASK		BIT(7)
>>   #define SB_VREG_EN_MASK			BIT(6)
>> @@ -133,6 +200,7 @@
>>   #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_OUT_SEL_MASK	BIT(1)
>>   #define ANA_SB_VREG_REF_SEL_MASK	BIT(0)
>>   /* SB_REG(0113) */
>>   #define SB_RX_RCAL_OPT_CODE_MASK	GENMASK(5, 4)
>> @@ -147,13 +215,24 @@
>>   #define AFC_RSTN_DELAY_TIME_MASK	GENMASK(6, 4)
>>   /* SB_REG(0117) */
>>   #define FAST_PULSE_TIME_MASK		GENMASK(3, 0)
>> +/* SB_REG(0118) */
>> +#define SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK	GENMASK(7, 0)
>> +/* SB_REG(011a) */
>> +#define SB_TG_CNT_RUN_NO_7_0_MASK	GENMASK(7, 0)
>>   /* SB_REG(011b) */
>>   #define SB_EARC_SIG_DET_BYPASS_MASK	BIT(4)
>>   #define SB_AFC_TOL_MASK			GENMASK(3, 0)
>> +/* SB_REG(011c) */
>> +#define SB_AFC_STB_NUM_MASK		GENMASK(3, 0)
>> +/* SB_REG(011d) */
>> +#define SB_TG_OSC_CNT_MIN_MASK		GENMASK(7, 0)
>> +/* SB_REG(011e) */
>> +#define SB_TG_OSC_CNT_MAX_MASK		GENMASK(7, 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_AUX_EN_IN_MASK		BIT(7)
>>   #define SB_EARC_EN_MASK			BIT(1)
>>   #define SB_EARC_AFC_EN_MASK		BIT(2)
>>   /* SB_REG(0123) */
>> @@ -165,35 +244,65 @@
>>   #define HDMI_MODE			BIT(2)
>>   #define HDMI_TMDS_FRL_SEL		BIT(1)
>>   /* LNTOP_REG(0206) */
>> -#define DATA_BUS_SEL			BIT(0)
>> +#define DATA_BUS_WIDTH_MASK		GENMASK(2, 1)
>> +#define DATA_BUS_WIDTH_SEL_MASK		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)
>> +/* LANE_REG(0301) */
>> +#define OVRD_LN_TX_DRV_EI_EN_MASK	BIT(7)
>> +#define LN_TX_DRV_EI_EN_MASK		BIT(6)
>> +/* LANE_REG(0303) */
>> +#define OVRD_LN_TX_DRV_LVL_CTRL_MASK	BIT(5)
>> +#define LN_TX_DRV_LVL_CTRL_MASK		GENMASK(4, 0)
>> +/* LANE_REG(0304)  */
>> +#define OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK	BIT(4)
>> +#define LN_TX_DRV_POST_LVL_CTRL_MASK	GENMASK(3, 0)
>> +/* LANE_REG(0305) */
>> +#define OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK	BIT(6)
>> +#define LN_TX_DRV_PRE_LVL_CTRL_MASK	GENMASK(5, 2)
>> +/* LANE_REG(0306) */
>> +#define LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK	GENMASK(7, 5)
>> +#define LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK	GENMASK(4, 2)
>> +#define LN_ANA_TX_DRV_ACCDRV_EN_MASK	BIT(0)
>> +/* LANE_REG(0307) */
>> +#define LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK	BIT(6)
>> +#define LN_ANA_TX_DRV_ACCDRV_CTRL_MASK	GENMASK(5, 3)
>> +/* LANE_REG(030a) */
>> +#define LN_ANA_TX_JEQ_EN_MASK		BIT(4)
>> +#define LN_TX_JEQ_EVEN_CTRL_RBR_MASK	GENMASK(3, 0)
>> +/* LANE_REG(030b) */
>> +#define LN_TX_JEQ_EVEN_CTRL_HBR_MASK	GENMASK(7, 4)
>> +#define LN_TX_JEQ_EVEN_CTRL_HBR2_MASK	GENMASK(3, 0)
>> +/* LANE_REG(030c) */
>> +#define LN_TX_JEQ_ODD_CTRL_RBR_MASK	GENMASK(3, 0)
>> +/* LANE_REG(030d) */
>> +#define LN_TX_JEQ_ODD_CTRL_HBR_MASK	GENMASK(7, 4)
>> +#define LN_TX_JEQ_ODD_CTRL_HBR2_MASK	GENMASK(3, 0)
>> +/* LANE_REG(0310) */
>> +#define LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK	GENMASK(1, 0)
>> +/* LANE_REG(0311) */
>> +#define LN_TX_SER_40BIT_EN_RBR_MASK	BIT(3)
>> +#define LN_TX_SER_40BIT_EN_HBR_MASK	BIT(2)
>> +#define LN_TX_SER_40BIT_EN_HBR2_MASK	BIT(1)
>> +/* LANE_REG(0316) */
>> +#define LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
>> +/* LANE_REG(031B) */
>> +#define LN_ANA_TX_RESERVED_MASK		GENMASK(7, 0)
>> +/* LANE_REG(031e) */
>> +#define LN_POLARITY_INV_MASK		BIT(2)
>> +#define LN_LANE_MODE_MASK		BIT(1)
>>   
>>   #define HDMI20_MAX_RATE			600000000
>>   
>> +enum dp_link_rate {
>> +	DP_BW_RBR,
>> +	DP_BW_HBR,
>> +	DP_BW_HBR2,
>> +};
>> +
>>   struct lcpll_config {
>>   	u32 bit_rate;
>>   	u8 lcvco_mode_en;
>> @@ -255,6 +364,19 @@ struct ropll_config {
>>   	u8 cd_tx_ser_rate_sel;
>>   };
>>   
>> +struct tx_drv_ctrl {
>> +	u8 tx_drv_lvl_ctrl;
>> +	u8 tx_drv_post_lvl_ctrl;
>> +	u8 ana_tx_drv_idrv_idn_ctrl;
>> +	u8 ana_tx_drv_idrv_iup_ctrl;
>> +	u8 ana_tx_drv_accdrv_en;
>> +	u8 ana_tx_drv_accdrv_ctrl;
>> +	u8 tx_drv_pre_lvl_ctrl;
>> +	u8 ana_tx_jeq_en;
>> +	u8 tx_jeq_even_ctrl;
>> +	u8 tx_jeq_odd_ctrl;
>> +};
>> +
>>   enum rk_hdptx_reset {
>>   	RST_PHY = 0,
>>   	RST_APB,
>> @@ -560,6 +682,90 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
>>   	REG_SEQ0(LANE_REG(0606), 0x1c),
>>   };
>>   
>> +static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = {
>> +	/* voltage swing 0, pre-emphasis 0->3 */
>> +	{
>> +		{ 0x2, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +		{ 0x4, 0x3, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0x7, 0x6, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
>> +	},
>> +
>> +	/* voltage swing 1, pre-emphasis 0->2 */
>> +	{
>> +		{ 0x4, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +		{ 0x9, 0x5, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0xc, 0x8, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
>> +	},
>> +
>> +	/* voltage swing 2, pre-emphasis 0->1 */
>> +	{
>> +		{ 0x8, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +		{ 0xc, 0x5, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
>> +	},
>> +
>> +	/* voltage swing 3, pre-emphasis 0 */
>> +	{
>> +		{ 0xb, 0x0, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +	}
>> +};
>> +
>> +static struct tx_drv_ctrl tx_drv_ctrl_hbr[4][4] = {
>> +	/* voltage swing 0, pre-emphasis 0->3 */
>> +	{
>> +		{ 0x2, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +		{ 0x5, 0x4, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0x9, 0x8, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
>> +	},
>> +
>> +	/* voltage swing 1, pre-emphasis 0->2 */
>> +	{
>> +		{ 0x6, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +		{ 0xa, 0x6, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0xc, 0x8, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
>> +	},
>> +
>> +	/* voltage swing 2, pre-emphasis 0->1 */
>> +	{
>> +		{ 0x9, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +		{ 0xd, 0x6, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
>> +	},
>> +
>> +	/* voltage swing 3, pre-emphasis 0 */
>> +	{
>> +		{ 0xc, 0x1, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +	}
>> +};
>> +
>> +static struct tx_drv_ctrl tx_drv_ctrl_hbr2[4][4] = {
>> +	/* voltage swing 0, pre-emphasis 0->3 */
>> +	{
>> +		{ 0x2, 0x1, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0x5, 0x4, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0x9, 0x8, 0x4, 0x6, 0x1, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
>> +	},
>> +
>> +	/* voltage swing 1, pre-emphasis 0->2 */
>> +	{
>> +		{ 0x6, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +		{ 0xb, 0x7, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
>> +		{ 0xd, 0x9, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
>> +	},
>> +
>> +	/* voltage swing 2, pre-emphasis 0->1 */
>> +	{
>> +		{ 0x8, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +		{ 0xc, 0x6, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
>> +	},
>> +
>> +	/* voltage swing 3, pre-emphasis 0 */
>> +	{
>> +		{ 0xb, 0x0, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
>> +	}
>> +};
>> +
>>   static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
>>   {
>>   	switch (reg) {
>> @@ -911,11 +1117,297 @@ static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)
>>   	return ret;
>>   }
>>   
>> +static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx)
>> +{
>> +	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
>> +	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
>> +	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
>> +
>> +	reset_control_assert(hdptx->rsts[RST_APB].rstc);
>> +	udelay(10);
>> +	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
>> +
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0301),
>> +			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
>> +			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
>> +			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0401),
>> +			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
>> +			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
>> +			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0501),
>> +			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
>> +			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
>> +			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0601),
>> +			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
>> +			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
>> +			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
>> +
>> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
>> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +		     HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x0));
>> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +		     HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x0));
>> +}
>> +
>> +static void rk_hdptx_dp_pll_init(struct rk_hdptx_phy *hdptx)
>> +{
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(003c), ANA_LCPLL_RESERVED7_MASK,
>> +			   FIELD_PREP(ANA_LCPLL_RESERVED7_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0046),
>> +			   ROPLL_ANA_CPP_CTRL_COARSE_MASK | ROPLL_ANA_CPP_CTRL_FINE_MASK,
>> +			   FIELD_PREP(ROPLL_ANA_CPP_CTRL_COARSE_MASK, 0xe) |
>> +			   FIELD_PREP(ROPLL_ANA_CPP_CTRL_FINE_MASK, 0xe));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0047),
>> +			   ROPLL_ANA_LPF_C_SEL_COARSE_MASK |
>> +			   ROPLL_ANA_LPF_C_SEL_FINE_MASK,
>> +			   FIELD_PREP(ROPLL_ANA_LPF_C_SEL_COARSE_MASK, 0x4) |
>> +			   FIELD_PREP(ROPLL_ANA_LPF_C_SEL_FINE_MASK, 0x4));
>> +
>> +	regmap_write(hdptx->regmap, CMN_REG(0051), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x87));
>> +	regmap_write(hdptx->regmap, CMN_REG(0052), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x71));
>> +	regmap_write(hdptx->regmap, CMN_REG(0053), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x71));
>> +
>> +	regmap_write(hdptx->regmap, CMN_REG(0055),
>> +		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x87));
>> +	regmap_write(hdptx->regmap, CMN_REG(0056),
>> +		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x71));
>> +	regmap_write(hdptx->regmap, CMN_REG(0057),
>> +		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x71));
>> +
>> +	regmap_write(hdptx->regmap, CMN_REG(0059),
>> +		     FIELD_PREP(ANA_ROPLL_PMS_PDIV_MASK, 0x1) |
>> +		     FIELD_PREP(ANA_ROPLL_PMS_REFDIV_MASK, 0x1));
>> +	regmap_write(hdptx->regmap, CMN_REG(005a),
>> +		     FIELD_PREP(ROPLL_PMS_SDIV_RBR_MASK, 0x3) |
>> +		     FIELD_PREP(ROPLL_PMS_SDIV_HBR_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(005b), ROPLL_PMS_SDIV_HBR2_MASK,
>> +			   FIELD_PREP(ROPLL_PMS_SDIV_HBR2_MASK, 0x0));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,
>> +			   FIELD_PREP(ROPLL_SDM_EN_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e),
>> +			   OVRD_ROPLL_SDM_RSTN_MASK | ROPLL_SDM_RSTN_MASK,
>> +			   FIELD_PREP(OVRD_ROPLL_SDM_RSTN_MASK, 0x1) |
>> +			   FIELD_PREP(ROPLL_SDM_RSTN_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_RBR_MASK,
>> +			   FIELD_PREP(ROPLL_SDC_FRAC_EN_RBR_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_HBR_MASK,
>> +			   FIELD_PREP(ROPLL_SDC_FRAC_EN_HBR_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_HBR2_MASK,
>> +			   FIELD_PREP(ROPLL_SDC_FRAC_EN_HBR2_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(005f),
>> +			   OVRD_ROPLL_SDC_RSTN_MASK | ROPLL_SDC_RSTN_MASK,
>> +			   FIELD_PREP(OVRD_ROPLL_SDC_RSTN_MASK, 0x1) |
>> +			   FIELD_PREP(ROPLL_SDC_RSTN_MASK, 0x1));
>> +	regmap_write(hdptx->regmap, CMN_REG(0060),
>> +		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x21));
>> +	regmap_write(hdptx->regmap, CMN_REG(0061),
>> +		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x27));
>> +	regmap_write(hdptx->regmap, CMN_REG(0062),
>> +		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x27));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0064),
>> +			   ROPLL_SDM_NUM_SIGN_RBR_MASK |
>> +			   ROPLL_SDM_NUM_SIGN_HBR_MASK |
>> +			   ROPLL_SDM_NUM_SIGN_HBR2_MASK,
>> +			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, 0x0) |
>> +			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_HBR_MASK, 0x1) |
>> +			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_HBR2_MASK, 0x1));
>> +	regmap_write(hdptx->regmap, CMN_REG(0065),
>> +		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0x0));
>> +	regmap_write(hdptx->regmap, CMN_REG(0066),
>> +		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0xd));
>> +	regmap_write(hdptx->regmap, CMN_REG(0067),
>> +		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0xd));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
>> +			   FIELD_PREP(ROPLL_SDC_N_RBR_MASK, 0x2));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(006a),
>> +			   ROPLL_SDC_N_HBR_MASK | ROPLL_SDC_N_HBR2_MASK,
>> +			   FIELD_PREP(ROPLL_SDC_N_HBR_MASK, 0x1) |
>> +			   FIELD_PREP(ROPLL_SDC_N_HBR2_MASK, 0x1));
>> +
>> +	regmap_write(hdptx->regmap, CMN_REG(006c),
>> +		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x3));
>> +	regmap_write(hdptx->regmap, CMN_REG(006d),
>> +		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x7));
>> +	regmap_write(hdptx->regmap, CMN_REG(006e),
>> +		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x7));
>> +
>> +	regmap_write(hdptx->regmap, CMN_REG(0070),
>> +		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x8));
>> +	regmap_write(hdptx->regmap, CMN_REG(0071),
>> +		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x18));
>> +	regmap_write(hdptx->regmap, CMN_REG(0072),
>> +		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x18));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0074),
>> +			   OVRD_ROPLL_SDC_NDIV_RSTN_MASK | ROPLL_SDC_NDIV_RSTN_MASK,
>> +			   FIELD_PREP(OVRD_ROPLL_SDC_NDIV_RSTN_MASK, 0x1) |
>> +			   FIELD_PREP(ROPLL_SDC_NDIV_RSTN_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0077), ANA_ROPLL_SSC_CLK_DIV_SEL_MASK,
>> +			   FIELD_PREP(ANA_ROPLL_SSC_CLK_DIV_SEL_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0081), ANA_PLL_CD_TX_SER_RATE_SEL_MASK,
>> +			   FIELD_PREP(ANA_PLL_CD_TX_SER_RATE_SEL_MASK, 0x0));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0081),
>> +			   ANA_PLL_CD_HSCLK_EAST_EN_MASK | ANA_PLL_CD_HSCLK_WEST_EN_MASK,
>> +			   FIELD_PREP(ANA_PLL_CD_HSCLK_EAST_EN_MASK, 0x1) |
>> +			   FIELD_PREP(ANA_PLL_CD_HSCLK_WEST_EN_MASK, 0x0));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0082), ANA_PLL_CD_VREG_GAIN_CTRL_MASK,
>> +			   FIELD_PREP(ANA_PLL_CD_VREG_GAIN_CTRL_MASK, 0x4));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0083), ANA_PLL_CD_VREG_ICTRL_MASK,
>> +			   FIELD_PREP(ANA_PLL_CD_VREG_ICTRL_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0084), PLL_LCRO_CLK_SEL_MASK,
>> +			   FIELD_PREP(PLL_LCRO_CLK_SEL_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0085), ANA_PLL_SYNC_LOSS_DET_MODE_MASK,
>> +			   FIELD_PREP(ANA_PLL_SYNC_LOSS_DET_MODE_MASK, 0x3));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0087), ANA_PLL_TX_HS_CLK_EN_MASK,
>> +			   FIELD_PREP(ANA_PLL_TX_HS_CLK_EN_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0097), DIG_CLK_SEL_MASK,
>> +			   FIELD_PREP(DIG_CLK_SEL_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0099), CMN_ROPLL_ALONE_MODE,
>> +			   FIELD_PREP(CMN_ROPLL_ALONE_MODE, 0x1));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(009a), HS_SPEED_SEL_MASK,
>> +			   FIELD_PREP(HS_SPEED_SEL_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(009b), LS_SPEED_SEL_MASK,
>> +			   FIELD_PREP(LS_SPEED_SEL_MASK, 0x1));
>> +}
>> +
>> +static int rk_hdptx_dp_aux_init(struct rk_hdptx_phy *hdptx)
>> +{
>> +	u32 status;
>> +	int ret;
>> +
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0102), ANA_SB_RXTERM_OFFSP_MASK,
>> +			   FIELD_PREP(ANA_SB_RXTERM_OFFSP_MASK, 0x3));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0103), ANA_SB_RXTERM_OFFSN_MASK,
>> +			   FIELD_PREP(ANA_SB_RXTERM_OFFSN_MASK, 0x3));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_AUX_EN_MASK,
>> +			   FIELD_PREP(SB_AUX_EN_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0105), ANA_SB_TX_HLVL_PROG_MASK,
>> +			   FIELD_PREP(ANA_SB_TX_HLVL_PROG_MASK, 0x7));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0106), ANA_SB_TX_LLVL_PROG_MASK,
>> +			   FIELD_PREP(ANA_SB_TX_LLVL_PROG_MASK, 0x7));
>> +
>> +	regmap_update_bits(hdptx->regmap, SB_REG(010d), ANA_SB_DMRX_LPBK_DATA_MASK,
>> +			   FIELD_PREP(ANA_SB_DMRX_LPBK_DATA_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, SB_REG(010f), ANA_SB_VREG_GAIN_CTRL_MASK,
>> +			   FIELD_PREP(ANA_SB_VREG_GAIN_CTRL_MASK, 0x0));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0110),
>> +			   ANA_SB_VREG_OUT_SEL_MASK | ANA_SB_VREG_REF_SEL_MASK,
>> +			   FIELD_PREP(ANA_SB_VREG_OUT_SEL_MASK, 0x1) |
>> +			   FIELD_PREP(ANA_SB_VREG_REF_SEL_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0113),
>> +			   SB_RX_RCAL_OPT_CODE_MASK | SB_RX_RTERM_CTRL_MASK,
>> +			   FIELD_PREP(SB_RX_RCAL_OPT_CODE_MASK, 0x1) |
>> +			   FIELD_PREP(SB_RX_RTERM_CTRL_MASK, 0x3));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0114),
>> +			   SB_TG_SB_EN_DELAY_TIME_MASK | SB_TG_RXTERM_EN_DELAY_TIME_MASK,
>> +			   FIELD_PREP(SB_TG_SB_EN_DELAY_TIME_MASK, 0x2) |
>> +			   FIELD_PREP(SB_TG_RXTERM_EN_DELAY_TIME_MASK, 0x2));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0115),
>> +			   SB_READY_DELAY_TIME_MASK | SB_TG_OSC_EN_DELAY_TIME_MASK,
>> +			   FIELD_PREP(SB_READY_DELAY_TIME_MASK, 0x2) |
>> +			   FIELD_PREP(SB_TG_OSC_EN_DELAY_TIME_MASK, 0x2));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0116),
>> +			   AFC_RSTN_DELAY_TIME_MASK,
>> +			   FIELD_PREP(AFC_RSTN_DELAY_TIME_MASK, 0x2));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0117),
>> +			   FAST_PULSE_TIME_MASK,
>> +			   FIELD_PREP(FAST_PULSE_TIME_MASK, 0x4));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0118),
>> +			   SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK,
>> +			   FIELD_PREP(SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK, 0xa));
>> +
>> +	regmap_update_bits(hdptx->regmap, SB_REG(011a), SB_TG_CNT_RUN_NO_7_0_MASK,
>> +			   FIELD_PREP(SB_TG_CNT_RUN_NO_7_0_MASK, 0x3));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(011b),
>> +			   SB_EARC_SIG_DET_BYPASS_MASK | SB_AFC_TOL_MASK,
>> +			   FIELD_PREP(SB_EARC_SIG_DET_BYPASS_MASK, 0x1) |
>> +			   FIELD_PREP(SB_AFC_TOL_MASK, 0x3));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(011c), SB_AFC_STB_NUM_MASK,
>> +			   FIELD_PREP(SB_AFC_STB_NUM_MASK, 0x4));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(011d), SB_TG_OSC_CNT_MIN_MASK,
>> +			   FIELD_PREP(SB_TG_OSC_CNT_MIN_MASK, 0x67));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(011e), SB_TG_OSC_CNT_MAX_MASK,
>> +			   FIELD_PREP(SB_TG_OSC_CNT_MAX_MASK, 0x6a));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(011f), SB_PWM_AFC_CTRL_MASK,
>> +			   FIELD_PREP(SB_PWM_AFC_CTRL_MASK, 0x5));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(011f), SB_RCAL_RSTN_MASK,
>> +			   FIELD_PREP(SB_RCAL_RSTN_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0120), SB_AUX_EN_IN_MASK,
>> +			   FIELD_PREP(SB_AUX_EN_IN_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0102), OVRD_SB_RXTERM_EN_MASK,
>> +			   FIELD_PREP(OVRD_SB_RXTERM_EN_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK,
>> +			   FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_EN_MASK,
>> +			   FIELD_PREP(OVRD_SB_EN_MASK, 0x1));
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_AUX_EN_MASK,
>> +			   FIELD_PREP(OVRD_SB_AUX_EN_MASK, 0x1));
>> +
>> +	regmap_update_bits(hdptx->regmap, SB_REG(010f), OVRD_SB_VREG_EN_MASK,
>> +			   FIELD_PREP(OVRD_SB_VREG_EN_MASK, 0x1));
>> +
>> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +		     HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x1));
>> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +		     HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x1));
>> +	usleep_range(20, 25);
>> +
>> +	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
>> +	usleep_range(20, 25);
>> +	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
>> +	usleep_range(20, 25);
>> +
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK,
>> +			   FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 0x1));
>> +	usleep_range(100, 110);
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_EN_MASK,
>> +			   FIELD_PREP(SB_EN_MASK, 0x1));
>> +	usleep_range(100, 110);
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0102), SB_RXTERM_EN_MASK,
>> +			   FIELD_PREP(SB_RXTERM_EN_MASK, 0x1));
>> +	usleep_range(20, 25);
>> +	regmap_update_bits(hdptx->regmap, SB_REG(010f), SB_VREG_EN_MASK,
>> +			   FIELD_PREP(SB_VREG_EN_MASK, 0x1));
>> +	usleep_range(20, 25);
>> +	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_AUX_EN_MASK,
>> +			   FIELD_PREP(SB_AUX_EN_MASK, 0x1));
>> +	usleep_range(100, 110);
>> +
>> +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
>> +				       status, FIELD_GET(HDPTX_O_SB_RDY, status),
>> +				       50, 1000);
>> +	if (ret) {
>> +		dev_err(hdptx->dev, "Failed to get phy sb ready: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>   static int rk_hdptx_phy_power_on(struct phy *phy)
>>   {
>>   	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
>>   	int bus_width = phy_get_bus_width(hdptx->phy);
>> -	int ret;
>> +	enum phy_mode mode = phy_get_mode(phy);
>> +	int ret, lane;
>>   
>>   	/*
>>   	 * FIXME: Temporary workaround to pass pixel_clk_rate
>> @@ -927,13 +1419,43 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
>>   	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
>>   		__func__, bus_width, rate);
>>   
>> -	ret = rk_hdptx_phy_consumer_get(hdptx, rate);
>> -	if (ret)
>> -		return ret;
>> +	if (mode == PHY_MODE_DP) {
>> +		rk_hdptx_dp_reset(hdptx);
>>   
>> -	ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
>> -	if (ret)
>> -		rk_hdptx_phy_consumer_put(hdptx, true);
>> +		for (lane = 0; lane < 4; lane++) {
>> +			regmap_update_bits(hdptx->regmap, LANE_REG(031e) + 0x400 * lane,
>> +					   LN_POLARITY_INV_MASK | LN_LANE_MODE_MASK,
>> +					   FIELD_PREP(LN_POLARITY_INV_MASK, 0) |
>> +					   FIELD_PREP(LN_LANE_MODE_MASK, 1));
>> +		}
>> +
>> +		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x1));
>> +
>> +		regmap_update_bits(hdptx->regmap, LNTOP_REG(0200), PROTOCOL_SEL,
>> +				   FIELD_PREP(PROTOCOL_SEL, 0x0));
>> +		regmap_update_bits(hdptx->regmap, LNTOP_REG(0206), DATA_BUS_WIDTH_MASK,
>> +				   FIELD_PREP(DATA_BUS_WIDTH_MASK, 0x1));
>> +		regmap_update_bits(hdptx->regmap, LNTOP_REG(0206), DATA_BUS_WIDTH_SEL_MASK,
>> +				   FIELD_PREP(DATA_BUS_WIDTH_SEL_MASK, 0x0));
>> +
>> +		rk_hdptx_dp_pll_init(hdptx);
>> +
>> +		ret = rk_hdptx_dp_aux_init(hdptx);
>> +		if (ret)
>> +			pm_runtime_put(hdptx->dev);
>> +	} else {
>> +		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
>> +
>> +		ret = rk_hdptx_phy_consumer_get(hdptx, rate);
>> +		if (ret)
>> +			return ret;
>> +
>> +		ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
>> +		if (ret)
>> +			rk_hdptx_phy_consumer_put(hdptx, true);
>> +	}
>>   
>>   	return ret;
>>   }
>> @@ -945,9 +1467,337 @@ static int rk_hdptx_phy_power_off(struct phy *phy)
>>   	return rk_hdptx_phy_consumer_put(hdptx, false);
>>   }
>>   
>> +static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode,
>> +				 int submode)
>> +{
>> +	return 0;
>> +}
>> +
>> +static int rk_hdptx_phy_verify_config(struct rk_hdptx_phy *hdptx,
>> +				      struct phy_configure_opts_dp *dp)
>> +{
>> +	int i;
>> +
>> +	if (dp->set_rate) {
>> +		switch (dp->link_rate) {
>> +		case 1620:
>> +		case 2700:
>> +		case 5400:
>> +			break;
>> +		default:
>> +			return -EINVAL;
>> +		}
>> +	}
>> +
>> +	if (dp->set_lanes) {
>> +		switch (dp->lanes) {
>> +		case 0:
>> +		case 1:
>> +		case 2:
>> +		case 4:
>> +			break;
>> +		default:
>> +			return -EINVAL;
>> +		}
>> +	}
>> +
>> +	if (dp->set_voltages) {
>> +		for (i = 0; i < dp->lanes; i++) {
>> +			if (dp->voltage[i] > 3 || dp->pre[i] > 3)
>> +				return -EINVAL;
>> +
>> +			if (dp->voltage[i] + dp->pre[i] > 3)
>> +				return -EINVAL;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int rk_hdptx_phy_set_rate(struct rk_hdptx_phy *hdptx,
>> +				 struct phy_configure_opts_dp *dp)
>> +{
>> +	u32 bw, status;
>> +	int ret;
>> +
>> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
>> +
>> +	switch (dp->link_rate) {
>> +	case 1620:
>> +		bw = DP_BW_RBR;
>> +		break;
>> +	case 2700:
>> +		bw = DP_BW_HBR;
>> +		break;
>> +	case 5400:
>> +		bw = DP_BW_HBR2;
>> +		break;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0008), OVRD_LCPLL_EN_MASK | LCPLL_EN_MASK,
>> +			   FIELD_PREP(OVRD_LCPLL_EN_MASK, 0x1) |
>> +			   FIELD_PREP(LCPLL_EN_MASK, 0x0));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(003d), OVRD_ROPLL_EN_MASK | ROPLL_EN_MASK,
>> +			   FIELD_PREP(OVRD_ROPLL_EN_MASK, 0x1) |
>> +			   FIELD_PREP(ROPLL_EN_MASK, 0x1));
>> +
>> +	if (dp->ssc) {
>> +		regmap_update_bits(hdptx->regmap, CMN_REG(0074),
>> +				   OVRD_ROPLL_SSC_EN_MASK | ROPLL_SSC_EN_MASK,
>> +				   FIELD_PREP(OVRD_ROPLL_SSC_EN_MASK, 0x1) |
>> +				   FIELD_PREP(ROPLL_SSC_EN_MASK, 0x1));
>> +		regmap_write(hdptx->regmap, CMN_REG(0075),
>> +			     FIELD_PREP(ANA_ROPLL_SSC_FM_DEVIATION_MASK, 0xc));
>> +		regmap_update_bits(hdptx->regmap, CMN_REG(0076),
>> +				   ANA_ROPLL_SSC_FM_FREQ_MASK,
>> +				   FIELD_PREP(ANA_ROPLL_SSC_FM_FREQ_MASK, 0x1f));
>> +
>> +		regmap_update_bits(hdptx->regmap, CMN_REG(0099), SSC_EN_MASK,
>> +				   FIELD_PREP(SSC_EN_MASK, 0x2));
>> +	} else {
>> +		regmap_update_bits(hdptx->regmap, CMN_REG(0074),
>> +				   OVRD_ROPLL_SSC_EN_MASK | ROPLL_SSC_EN_MASK,
>> +				   FIELD_PREP(OVRD_ROPLL_SSC_EN_MASK, 0x1) |
>> +				   FIELD_PREP(ROPLL_SSC_EN_MASK, 0x0));
>> +		regmap_write(hdptx->regmap, CMN_REG(0075),
>> +			     FIELD_PREP(ANA_ROPLL_SSC_FM_DEVIATION_MASK, 0x20));
>> +		regmap_update_bits(hdptx->regmap, CMN_REG(0076),
>> +				   ANA_ROPLL_SSC_FM_FREQ_MASK,
>> +				   FIELD_PREP(ANA_ROPLL_SSC_FM_FREQ_MASK, 0xc));
>> +
>> +		regmap_update_bits(hdptx->regmap, CMN_REG(0099), SSC_EN_MASK,
>> +				   FIELD_PREP(SSC_EN_MASK, 0x0));
>> +	}
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0095), DP_TX_LINK_BW_MASK,
>> +			   FIELD_PREP(DP_TX_LINK_BW_MASK, bw));
>> +
>> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x1));
>> +
>> +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
>> +				       status, FIELD_GET(HDPTX_O_PLL_LOCK_DONE, status),
>> +				       50, 1000);
>> +	if (ret) {
>> +		dev_err(hdptx->dev, "Failed to get phy pll lock: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void rk_hdptx_phy_lane_disable(struct rk_hdptx_phy *hdptx)
>> +{
>> +	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
>> +
>> +	regmap_update_bits(hdptx->regmap, LNTOP_REG(0207), LANE_EN,
>> +			   FIELD_PREP(LANE_EN, 0x0));
>> +
>> +	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> +		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(0008), OVRD_LCPLL_EN_MASK | LCPLL_EN_MASK,
>> +			   FIELD_PREP(OVRD_LCPLL_EN_MASK, 0x1) |
>> +			   FIELD_PREP(LCPLL_EN_MASK, 0x0));
>> +
>> +	regmap_update_bits(hdptx->regmap, CMN_REG(003d), OVRD_ROPLL_EN_MASK | ROPLL_EN_MASK,
>> +			   FIELD_PREP(OVRD_ROPLL_EN_MASK, 0x1) |
>> +			   FIELD_PREP(ROPLL_EN_MASK, 0x0));
>> +}
>> +
>> +static int rk_hdptx_phy_set_lanes(struct rk_hdptx_phy *hdptx,
>> +				  struct phy_configure_opts_dp *dp)
>> +{
>> +	if (!dp->lanes) {
>> +		rk_hdptx_phy_lane_disable(hdptx);
>> +		return 0;
>> +	}
>> +
>> +	regmap_update_bits(hdptx->regmap, LNTOP_REG(0207), LANE_EN,
>> +			   FIELD_PREP(LANE_EN, GENMASK(dp->lanes - 1, 0)));
>> +
>> +	return 0;
>> +}
>> +
>> +static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
>> +				     struct phy_configure_opts_dp *dp,
>> +				     u8 lane)
>> +{
>> +	const struct tx_drv_ctrl *ctrl;
>> +	u32 offset = lane * 0x400;
>> +
>> +	switch (dp->link_rate) {
>> +	case 1620:
>> +		ctrl = &tx_drv_ctrl_rbr[dp->voltage[lane]][dp->pre[lane]];
>> +		regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
>> +				   LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
>> +				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
>> +				   ctrl->tx_jeq_even_ctrl));
>> +		regmap_update_bits(hdptx->regmap, LANE_REG(030c) + offset,
>> +				   LN_TX_JEQ_ODD_CTRL_RBR_MASK,
>> +				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_RBR_MASK,
>> +				   ctrl->tx_jeq_odd_ctrl));
>> +		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
>> +				   LN_TX_SER_40BIT_EN_RBR_MASK,
>> +				   FIELD_PREP(LN_TX_SER_40BIT_EN_RBR_MASK, 0x1));
>> +		break;
>> +	case 2700:
>> +		ctrl = &tx_drv_ctrl_hbr[dp->voltage[lane]][dp->pre[lane]];
>> +		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
>> +				   LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
>> +				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
>> +				   ctrl->tx_jeq_even_ctrl));
>> +		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
>> +				   LN_TX_JEQ_ODD_CTRL_HBR_MASK,
>> +				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR_MASK,
>> +				   ctrl->tx_jeq_odd_ctrl));
>> +		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
>> +				   LN_TX_SER_40BIT_EN_HBR_MASK,
>> +				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR_MASK, 0x1));
>> +		break;
>> +	case 5400:
>> +	default:
>> +		ctrl = &tx_drv_ctrl_hbr2[dp->voltage[lane]][dp->pre[lane]];
>> +		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
>> +				   LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
>> +				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
>> +				   ctrl->tx_jeq_even_ctrl));
>> +		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
>> +				   LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
>> +				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
>> +				   ctrl->tx_jeq_odd_ctrl));
>> +		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
>> +				   LN_TX_SER_40BIT_EN_HBR2_MASK,
>> +				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1));
>> +		break;
>> +	}
>> +
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0303) + offset,
>> +			   OVRD_LN_TX_DRV_LVL_CTRL_MASK | LN_TX_DRV_LVL_CTRL_MASK,
>> +			   FIELD_PREP(OVRD_LN_TX_DRV_LVL_CTRL_MASK, 0x1) |
>> +			   FIELD_PREP(LN_TX_DRV_LVL_CTRL_MASK,
>> +				      ctrl->tx_drv_lvl_ctrl));
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0304) + offset,
>> +			   OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK |
>> +			   LN_TX_DRV_POST_LVL_CTRL_MASK,
>> +			   FIELD_PREP(OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK, 0x1) |
>> +			   FIELD_PREP(LN_TX_DRV_POST_LVL_CTRL_MASK,
>> +				      ctrl->tx_drv_post_lvl_ctrl));
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0305) + offset,
>> +			   OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK |
>> +			   LN_TX_DRV_PRE_LVL_CTRL_MASK,
>> +			   FIELD_PREP(OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK, 0x1) |
>> +			   FIELD_PREP(LN_TX_DRV_PRE_LVL_CTRL_MASK,
>> +				      ctrl->tx_drv_pre_lvl_ctrl));
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0306) + offset,
>> +			   LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK |
>> +			   LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK |
>> +			   LN_ANA_TX_DRV_ACCDRV_EN_MASK,
>> +			   FIELD_PREP(LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK,
>> +				      ctrl->ana_tx_drv_idrv_idn_ctrl) |
>> +			   FIELD_PREP(LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK,
>> +				      ctrl->ana_tx_drv_idrv_iup_ctrl) |
>> +			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_EN_MASK,
>> +				      ctrl->ana_tx_drv_accdrv_en));
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0307) + offset,
>> +			   LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK |
>> +			   LN_ANA_TX_DRV_ACCDRV_CTRL_MASK,
>> +			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK, 0x1) |
>> +			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_CTRL_MASK,
>> +				      ctrl->ana_tx_drv_accdrv_ctrl));
>> +
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
>> +			   LN_ANA_TX_JEQ_EN_MASK,
>> +			   FIELD_PREP(LN_ANA_TX_JEQ_EN_MASK, ctrl->ana_tx_jeq_en));
>> +
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0310) + offset,
>> +			   LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK,
>> +			   FIELD_PREP(LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK, 0x3));
>> +
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(0316) + offset,
>> +			   LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK,
>> +			   FIELD_PREP(LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK, 0x2));
>> +
>> +	regmap_update_bits(hdptx->regmap, LANE_REG(031b) + offset,
>> +			   LN_ANA_TX_RESERVED_MASK,
>> +			   FIELD_PREP(LN_ANA_TX_RESERVED_MASK, 0x1));
>> +}
>> +
>> +static int rk_hdptx_phy_set_voltages(struct rk_hdptx_phy *hdptx,
>> +				     struct phy_configure_opts_dp *dp)
>> +{
>> +	u8 lane;
>> +	u32 status;
>> +	int ret;
>> +
>> +	for (lane = 0; lane < dp->lanes; lane++)
>> +		rk_hdptx_phy_set_voltage(hdptx, dp, lane);
>> +
>> +	reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
>> +
>> +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
>> +				       status, FIELD_GET(HDPTX_O_PHY_RDY, status),
>> +				       50, 5000);
>> +	if (ret) {
>> +		dev_err(hdptx->dev, "Failed to get phy ready: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opts)
>> +{
>> +	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
>> +	enum phy_mode mode = phy_get_mode(phy);
>> +	int ret;
>> +
>> +	if (mode != PHY_MODE_DP)
>> +		return -EINVAL;
>> +
>> +	ret = rk_hdptx_phy_verify_config(hdptx, &opts->dp);
>> +	if (ret) {
>> +		dev_err(hdptx->dev, "invalid params for phy configure\n");
>> +		return ret;
>> +	}
>> +
>> +	if (opts->dp.set_rate) {
>> +		ret = rk_hdptx_phy_set_rate(hdptx, &opts->dp);
>> +		if (ret) {
>> +			dev_err(hdptx->dev, "failed to set rate: %d\n", ret);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	if (opts->dp.set_lanes) {
>> +		ret = rk_hdptx_phy_set_lanes(hdptx, &opts->dp);
>> +		if (ret) {
>> +			dev_err(hdptx->dev, "failed to set lanes: %d\n", ret);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	if (opts->dp.set_voltages) {
>> +		ret = rk_hdptx_phy_set_voltages(hdptx, &opts->dp);
>> +		if (ret) {
>> +			dev_err(hdptx->dev, "failed to set voltages: %d\n",
>> +				ret);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>   static const struct phy_ops rk_hdptx_phy_ops = {
>>   	.power_on  = rk_hdptx_phy_power_on,
>>   	.power_off = rk_hdptx_phy_power_off,
>> +	.set_mode  = rk_hdptx_phy_set_mode,
>> +	.configure = rk_hdptx_phy_configure,
>>   	.owner	   = THIS_MODULE,
>>   };
>>   
>> @@ -1164,5 +2014,6 @@ 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_AUTHOR("Damon Ding <damon.ding at rock-chips.com>");
>>   MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");
>>   MODULE_LICENSE("GPL");
>> -- 
>> 2.34.1
>>
> 

Best regards,
Damon


From damon.ding at rock-chips.com  Mon Dec 16 02:09:34 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 18:09:34 +0800
Subject: [PATCH v2 03/11] drm/rockchip: analogix_dp: Add support for
 RK3588
In-Reply-To: <4395748.ejJDZkT8p0@diego>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-4-damon.ding@rock-chips.com>
 <gwogudb5vae7wu452zwuqmdlyaibenoso4f5pjmu3uttckhy2w@shndol4mz5n4>
 <4395748.ejJDZkT8p0@diego>
Message-ID: <60c85962-f0fc-41c4-a1ec-30d5ddf3196b@rock-chips.com>

Hi,

On 2024/12/16 17:11, Heiko St?bner wrote:
> Am Montag, 16. Dezember 2024, 09:57:41 CET schrieb Dmitry Baryshkov:
>> On Mon, Dec 16, 2024 at 11:12:17AM +0800, Damon Ding wrote:
>>> RK3588 integrates the analogix eDP 1.3 TX controller IP and the HDMI/eDP
>>> TX Combo PHY based on a Samsung IP block, and there are also two
>>> independent eDP display interface on RK3588 Soc.
>>>
>>> Add just the basic support for now, i.e. RGB output up to 4K at 60Hz, without
>>> the tests of audio, PSR and other eDP 1.3 specific features.
>>>
>>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>>>
>>> ---
>>>
>>> Changes in v2:
>>> - Add support for the other eDP output edp1
>>> ---
>>>   .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 82 ++++++++++++++++---
>>>   include/drm/bridge/analogix_dp.h              |  3 +-
>>>   2 files changed, 74 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>>> index 871606a31ef1..4c9a55776ada 100644
>>> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>>> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>>> @@ -51,10 +51,12 @@ struct rockchip_grf_reg_field {
>>>   /**
>>>    * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
>>>    * @lcdc_sel: grf register field of lcdc_sel
>>> + * @edp_mode: grf register field of edp_mode
>>>    * @chip_type: specific chip type
>>>    */
>>>   struct rockchip_dp_chip_data {
>>>   	const struct rockchip_grf_reg_field lcdc_sel;
>>> +	const struct rockchip_grf_reg_field edp_mode;
>>>   	u32	chip_type;
>>>   };
>>>   
>>> @@ -134,12 +136,21 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
>>>   		return ret;
>>>   	}
>>>   
>>> +	ret = rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 1);
>>> +	if (ret != 0)
>>> +		DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);
>>
>> Is it to be called for non-eDP hosts too? Or for older hosts?
> 
> The implementation of rockchip_grf_field_write (in patch1) seems to
> take care of checking if that field actually exists and doing nothing if
> not.
> 
> I think eDP/DP is more a naming thing, the Analogix controller is called
> an eDP controller in all documentation things.
> 
> Even back on rk3288, the Analogix-DP, still is called an eDP controller in
> documentation, with the only difference being that it does not contain
> another additional "dedicated" DP controller
> 
>>> @@ -396,6 +425,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
>>>   	const struct rockchip_dp_chip_data *dp_data;
>>>   	struct drm_panel *panel = NULL;
>>>   	struct rockchip_dp_device *dp;
>>> +	int id, i;
>>>   	int ret;
>>>   
>>>   	dp_data = of_device_get_match_data(dev);
>>> @@ -410,9 +440,22 @@ static int rockchip_dp_probe(struct platform_device *pdev)
>>>   	if (!dp)
>>>   		return -ENOMEM;
>>>   
>>> +	id = of_alias_get_id(dev->of_node, "edp");
>>> +	if (id < 0)
>>> +		id = 0;
>>
>> Alias is not documented.
> 
> additionally, aliases should never be used to determine actual device
> functionionality - e.g. the hw-device-number
> 
>> Please check how other platforms handle device -> ID conversion and
>> consider following it (yes, the best option currently known is to
>> hardcode bus addresses into the driver data).
> 
> see for example the dw-dsi + dw-dsi2 for existing implementations.
> 

Indeed, I will fix it in the next version.

> 
> 
>>> +	i = 0;
>>> +	while (is_rockchip(dp_data[i].chip_type))
>>> +		i++;
>>> +
>>> +	if (id >= i) {
>>> +		DRM_DEV_ERROR(dev, "invalid edp id: %d\n", id);
>>> +		return -ENODEV;
>>> +	}
>>
>> Is it applicable to non-eDP case?
> 
> same as above, it's always called eDP in all pieces of documentation,
> (Compliant with DP 1.2 and eDP 1.3)
> 
> Heiko
> 
>>> +
>>>   	dp->dev = dev;
>>>   	dp->adp = ERR_PTR(-ENODEV);
>>> -	dp->data = dp_data;
>>> +	dp->data = &dp_data[id];
>>>   	dp->plat_data.panel = panel;
>>>   	dp->plat_data.dev_type = dp->data->chip_type;
>>>   	dp->plat_data.power_on = rockchip_dp_poweron;
>>> @@ -464,19 +507,38 @@ static int rockchip_dp_resume(struct device *dev)
>>>   static DEFINE_RUNTIME_DEV_PM_OPS(rockchip_dp_pm_ops, rockchip_dp_suspend,
>>>   		rockchip_dp_resume, NULL);
>>>   
>>> -static const struct rockchip_dp_chip_data rk3399_edp = {
>>> -	.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
>>> -	.chip_type = RK3399_EDP,
>>> +static const struct rockchip_dp_chip_data rk3399_edp[] = {
>>> +	{
>>> +		.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
>>> +		.chip_type = RK3399_EDP,
>>> +	},
>>> +	{ /* sentinel */ }
>>> +};
>>> +
>>> +static const struct rockchip_dp_chip_data rk3288_dp[] = {
>>> +	{
>>> +		.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
>>> +		.chip_type = RK3288_DP,
>>> +	},
>>> +	{ /* sentinel */ }
>>>   };
>>>   
>>> -static const struct rockchip_dp_chip_data rk3288_dp = {
>>> -	.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
>>> -	.chip_type = RK3288_DP,
>>> +static const struct rockchip_dp_chip_data rk3588_edp[] = {
>>> +	{
>>> +		.edp_mode = GRF_REG_FIELD(0x0000, 0, 0),
>>> +		.chip_type = RK3588_EDP,
>>> +	},
>>> +	{
>>> +		.edp_mode = GRF_REG_FIELD(0x0004, 0, 0),
>>> +		.chip_type = RK3588_EDP,
>>> +	},
>>> +	{ /* sentinel */ }
>>>   };
>>>   
>>>   static const struct of_device_id rockchip_dp_dt_ids[] = {
>>>   	{.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp },
>>>   	{.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp },
>>> +	{.compatible = "rockchip,rk3588-edp", .data = &rk3588_edp },
>>>   	{}
>>>   };
>>>   MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
>>> diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
>>> index 6002c5666031..54086cb2d97d 100644
>>> --- a/include/drm/bridge/analogix_dp.h
>>> +++ b/include/drm/bridge/analogix_dp.h
>>> @@ -15,11 +15,12 @@ enum analogix_dp_devtype {
>>>   	EXYNOS_DP,
>>>   	RK3288_DP,
>>>   	RK3399_EDP,
>>> +	RK3588_EDP,
>>>   };
>>>   
>>>   static inline bool is_rockchip(enum analogix_dp_devtype type)
>>>   {
>>> -	return type == RK3288_DP || type == RK3399_EDP;
>>> +	return type == RK3288_DP || type == RK3399_EDP || type == RK3588_EDP;
>>>   }
>>>   
>>>   struct analogix_dp_plat_data {
>>
>>
> 
> 
> 
> 
> 
> 

Best regards,
Damon


From krzk at kernel.org  Mon Dec 16 02:14:08 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 11:14:08 +0100
Subject: [PATCH] dt-bindings: mfd: atmel,at91sam9260: Convert to json
 schema
In-Reply-To: <20241211-matrix-v1-1-5ef0104a3af4@microchip.com>
References: <20241211-matrix-v1-1-5ef0104a3af4@microchip.com>
Message-ID: <dxgqkdo6ulmqfa5vyerwta3vubuy32gzzu2cxfwwtespydfc4b@5wjrno3lgjsp>

On Wed, Dec 11, 2024 at 04:59:22PM +0530, Charan Pedumuru wrote:
> Convert old text based binding to json schema.
> Changes during conversion:
> Add a fallback for all compatibles as the IP core is compatible
> with `syscon`.

I don't understand. The syscon was already there. You added different
fallback, so provide explanation why do you think they are compatible.

> 
> Signed-off-by: Charan Pedumuru <charan.pedumuru at microchip.com>
> ---
>  .../bindings/mfd/atmel,at91sam9260-matrix.yaml     | 54 ++++++++++++++++++++++
>  .../devicetree/bindings/mfd/atmel-matrix.txt       | 26 -----------
>  2 files changed, 54 insertions(+), 26 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml
> new file mode 100644
> index 000000000000..0e827882823f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml
> @@ -0,0 +1,54 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/atmel,at91sam9260-matrix.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Microchip AT91 Bus Matrix
> +
> +maintainers:
> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
> +
> +description:
> +  The Bus Matrix (MATRIX) implements a multi-layer AHB, based on the
> +  AHB-Lite protocol, that enables parallel access paths between multiple
> +  masters and slaves in a system, thus increasing the overall bandwidth.
> +
> +properties:
> +  compatible:
> +    anyOf:

oneOf
See other bindings for preferred syntax. There is never anyOf.

> +      - items:
> +          - enum:
> +              - atmel,at91sam9260-matrix
> +              - atmel,at91sam9261-matrix
> +              - atmel,at91sam9263-matrix
> +              - atmel,at91sam9rl-matrix
> +              - atmel,at91sam9g45-matrix
> +              - atmel,at91sam9n12-matrix
> +              - atmel,at91sam9x5-matrix
> +              - atmel,sama5d3-matrix
> +          - const: syscon
> +      - items:
> +          - const: microchip,sam9x60-matrix
> +          - const: atmel,at91sam9x5-matrix
> +          - const: syscon
> +      - items:
> +          - const: microchip,sam9x7-matrix

So that's just enum with previous group.


> +          - const: atmel,at91sam9x5-matrix
> +          - const: syscon
> +
> +  reg:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    matrix at ffffec00 {

syscon@
or system-controller@


Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec 16 02:15:21 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 11:15:21 +0100
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <20241212093555.1376568-2-ping.bai@nxp.com>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
Message-ID: <z6udhrqfmbelspe3eiz2q6twqvn4nkgxnfsdyxdv7ow6llxiz6@qhbaobn63icb>

On Thu, Dec 12, 2024 at 05:35:55PM +0800, Jacky Bai wrote:
> The i.MX 943 applications processors integrate up to four
> Arm Cortex A55 cores and supports functional safety with
> built-in 2x Arm Cortex M33 and M7 cores which can be
> configured asa safety island. Optimizing performance and
> power efficiency for Industrial, IoT and automotive devices,
> i.MX 943 processors are built with NXP?s innovative Energy
> Flex architecture.
> 
> This patch adds the minimal dtsi support for i.MX943 with
> peripherals like uart, edma, i2c, spi, mu, sai etc.
> 
> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx943-clock.h  |  196 +++
>  .../arm64/boot/dts/freescale/imx943-pinfunc.h | 1542 +++++++++++++++++
>  arch/arm64/boot/dts/freescale/imx943-power.h  |   41 +
>  arch/arm64/boot/dts/freescale/imx943.dtsi     | 1284 ++++++++++++++
>  4 files changed, 3063 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx943-clock.h
>  create mode 100644 arch/arm64/boot/dts/freescale/imx943-pinfunc.h
>  create mode 100644 arch/arm64/boot/dts/freescale/imx943-power.h
>  create mode 100644 arch/arm64/boot/dts/freescale/imx943.dtsi
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx943-clock.h b/arch/arm64/boot/dts/freescale/imx943-clock.h
> new file mode 100644
> index 000000000000..64b9d5d4051e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx943-clock.h
> @@ -0,0 +1,196 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#ifndef __CLOCK_IMX943_H
> +#define __CLOCK_IMX943_H
> +
> +#define IMX943_CLK_EXT				0
> +#define IMX943_CLK_OSC32K			1
> +#define IMX943_CLK_OSC24M			2


Why exactly are you adding clock indices to header files? Nothing in
commit msg explains that.

Best regards,
Krzysztof



From danishanwar at ti.com  Mon Dec 16 02:00:40 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 16 Dec 2024 15:30:40 +0530
Subject: [PATCH net-next 0/4] Add Multicast Filtering support for VLAN interface
Message-ID: <20241216100044.577489-1-danishanwar@ti.com>

This series adds Multicast filtering support for VLAN interfaces in dual
EMAC and HSR offload mode for ICSSG driver.

Patch 1/4 - Selects symbol HSR for TI_ICSSG_PRUETH. Changes NET_SWITCHDEV
from 'depends on' to 'select' as keeping it as 'depends on' results in
below error

  *** Default configuration is based on 'defconfig'
  error: recursive dependency detected!
    symbol NET_DSA depends on HSR
    symbol HSR is selected by TI_ICSSG_PRUETH
    symbol TI_ICSSG_PRUETH depends on NET_SWITCHDEV
    symbol NET_SWITCHDEV is selected by NET_DSA
  For a resolution refer to Documentation/kbuild/kconfig-language.rst
  subsection "Kconfig recursive dependency limitations"

Patch 2/4 - Adds support for VLAN in dual EMAC mode
Patch 3/4 - Adds MC filtering support for VLAN in dual EMAC mode
Patch 4/4 - Adds MC filtering support for VLAN in HSR mode

MD Danish Anwar (4):
  net: ti: Kconfig: Select HSR for ICSSG Driver
  net: ti: icssg-prueth: Add VLAN support in EMAC mode
  net: ti: icssg-prueth: Add Multicast Filtering support for VLAN in MAC
    mode
  net: ti: icssg-prueth: Add Support for Multicast filtering with VLAN
    in HSR mode

 drivers/net/ethernet/ti/Kconfig              |   3 +-
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 170 ++++++++++++++-----
 drivers/net/ethernet/ti/icssg/icssg_prueth.h |   8 +
 include/linux/if_hsr.h                       |  16 ++
 include/linux/netdevice.h                    |   3 +
 net/core/dev_addr_lists.c                    |   7 +-
 net/hsr/hsr_device.c                         |  12 ++
 net/hsr/hsr_main.h                           |   9 -
 8 files changed, 168 insertions(+), 60 deletions(-)


base-commit: 92c932b9946c1e082406aa0515916adb3e662e24
-- 
2.34.1



From damon.ding at rock-chips.com  Mon Dec 16 02:15:38 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 16 Dec 2024 18:15:38 +0800
Subject: [PATCH v2 10/11] arm64: dts: rockchip: Enable eDP0 display on
 RK3588S EVB1 board
In-Reply-To: <ay2im4itrj3k4p2ksobgsk77b7m4laaxctkfcpffqxj5ttxenm@mzdizmf3mlcb>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-11-damon.ding@rock-chips.com>
 <ay2im4itrj3k4p2ksobgsk77b7m4laaxctkfcpffqxj5ttxenm@mzdizmf3mlcb>
Message-ID: <d0f89644-77b9-4bcd-9fab-42a10185c72f@rock-chips.com>

Hi Dmitry,

On 2024/12/16 17:06, Dmitry Baryshkov wrote:
> On Mon, Dec 16, 2024 at 11:12:24AM +0800, Damon Ding wrote:
>> Add the necessary DT changes to enable eDP0 on RK3588S EVB1 board:
>> - Add edp-panel node
>> - Set pinctrl of pwm12 for backlight
>> - Enable edp0/hdptxphy0/vp2
>>
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>>
>> ---
>>
>> Changes in v2:
>> - Remove brightness-levels and default-brightness-level properties in
>>    backlight node.
>> - Add the detail DT changes to commit message.
>> ---
>>   .../boot/dts/rockchip/rk3588s-evb1-v10.dts    | 50 +++++++++++++++++++
>>   1 file changed, 50 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
>> index bc4077575beb..5c1ea25b6524 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
>> @@ -9,6 +9,7 @@
>>   #include <dt-bindings/gpio/gpio.h>
>>   #include <dt-bindings/input/input.h>
>>   #include <dt-bindings/pinctrl/rockchip.h>
>> +#include <dt-bindings/soc/rockchip,vop2.h>
>>   #include <dt-bindings/usb/pd.h>
>>   #include "rk3588s.dtsi"
>>   
>> @@ -120,6 +121,18 @@ backlight: backlight {
>>   		pwms = <&pwm12 0 25000 0>;
>>   	};
>>   
>> +	edp_panel: edp-panel {
>> +		compatible = "lg,lp079qx1-sp0v";
> 
> Please use aux-bus and a generic "edp-panel" entry for newer platforms
> instead of declaring the panel on the platform bus. Placing eDP panels
> on the platform bus has been deprecated for quite a while.

I will apply the aux-bus in the next version. :-)

> 
>> +		backlight = <&backlight>;
>> +		power-supply = <&vcc3v3_lcd_edp>;
>> +
>> +		port {
>> +			panel_in_edp: endpoint {
>> +				remote-endpoint = <&edp_out_panel>;
>> +			};
>> +		};
>> +	};
>> +
>>   	combophy_avdd0v85: regulator-combophy-avdd0v85 {
>>   		compatible = "regulator-fixed";
>>   		regulator-name = "combophy_avdd0v85";
> 
Best regards,
Damon


From krzk at kernel.org  Mon Dec 16 02:17:46 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 11:17:46 +0100
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <20241212093555.1376568-2-ping.bai@nxp.com>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
Message-ID: <bx3r4cs3oklfduvkg65vke3clb3fc6sseske2ellq27ifpmsnm@msz6iqvjwufn>

On Thu, Dec 12, 2024 at 05:35:55PM +0800, Jacky Bai wrote:
> The i.MX 943 applications processors integrate up to four
> Arm Cortex A55 cores and supports functional safety with
> built-in 2x Arm Cortex M33 and M7 cores which can be
> configured asa safety island. Optimizing performance and
> power efficiency for Industrial, IoT and automotive devices,
> i.MX 943 processors are built with NXP?s innovative Energy
> Flex architecture.
> 
> This patch adds the minimal dtsi support for i.MX943 with
> peripherals like uart, edma, i2c, spi, mu, sai etc.
> 
> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx943-clock.h  |  196 +++
>  .../arm64/boot/dts/freescale/imx943-pinfunc.h | 1542 +++++++++++++++++
>  arch/arm64/boot/dts/freescale/imx943-power.h  |   41 +
>  arch/arm64/boot/dts/freescale/imx943.dtsi     | 1284 ++++++++++++++

No, this is untested, uncompilable.

We do not add dead code to the kernel. You need users.

>  4 files changed, 3063 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx943-clock.h
>  create mode 100644 arch/arm64/boot/dts/freescale/imx943-pinfunc.h
>  create mode 100644 arch/arm64/boot/dts/freescale/imx943-power.h
>  create mode 100644 arch/arm64/boot/dts/freescale/imx943.dtsi
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx943-clock.h b/arch/arm64/boot/dts/freescale/imx943-clock.h
> new file mode 100644
> index 000000000000..64b9d5d4051e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx943-clock.h
> @@ -0,0 +1,196 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#ifndef __CLOCK_IMX943_H
> +#define __CLOCK_IMX943_H
> +
> +#define IMX943_CLK_EXT				0
> +#define IMX943_CLK_OSC32K			1
> +#define IMX943_CLK_OSC24M			2
> +#define IMX943_CLK_FRO				3
> +#define IMX943_CLK_SYSPLL1_VCO			4
> +#define IMX943_CLK_SYSPLL1_PFD0_UNGATED		5
> +#define IMX943_CLK_SYSPLL1_PFD0			6
> +#define IMX943_CLK_SYSPLL1_PFD0_DIV2		7
> +#define IMX943_CLK_SYSPLL1_PFD1_UNGATED		8
> +#define IMX943_CLK_SYSPLL1_PFD1			9
> +#define IMX943_CLK_SYSPLL1_PFD1_DIV2		10
> +#define IMX943_CLK_SYSPLL1_PFD2_UNGATED		11
> +#define IMX943_CLK_SYSPLL1_PFD2			12
> +#define IMX943_CLK_SYSPLL1_PFD2_DIV2		13
> +#define IMX943_CLK_AUDIOPLL1_VCO		14
> +#define IMX943_CLK_AUDIOPLL1			15
> +#define IMX943_CLK_AUDIOPLL2_VCO		16
> +#define IMX943_CLK_AUDIOPLL2			17
> +#define IMX943_CLK_RESERVED18			18
> +#define IMX943_CLK_RESERVED19			19
> +#define IMX943_CLK_RESERVED20			20
> +#define IMX943_CLK_RESERVED21			21
> +#define IMX943_CLK_RESERVED22			22
> +#define IMX943_CLK_RESERVED23			23
> +#define IMX943_CLK_ENCPLL_VCO			24
> +#define IMX943_CLK_ENCPLL_PFD0_UGATED		25
> +#define IMX943_CLK_ENCPLL_PFD0			26
> +#define IMX943_CLK_ENCPLL_PFD1_UGATED		27
> +#define IMX943_CLK_ENCPLL_PFD1			28
> +#define IMX943_CLK_ARMPLL_VCO			29
> +#define IMX943_CLK_ARMPLL_PFD0_UNGATED		30
> +#define IMX943_CLK_ARMPLL_PFD0			31
> +#define IMX943_CLK_ARMPLL_PFD1_UNGATED		32
> +#define IMX943_CLK_ARMPLL_PFD1			33
> +#define IMX943_CLK_ARMPLL_PFD2_UNGATED		34
> +#define IMX943_CLK_ARMPLL_PFD2			35
> +#define IMX943_CLK_ARMPLL_PFD3_UNGATED		36
> +#define IMX943_CLK_ARMPLL_PFD3			37
> +#define IMX943_CLK_DRAMPLL_VCO			38
> +#define IMX943_CLK_DRAMPLL			39
> +#define IMX943_CLK_HSIOPLL_VCO			40
> +#define IMX943_CLK_HSIOPLL			41
> +#define IMX943_CLK_LDBPLL_VCO			42
> +#define IMX943_CLK_LDBPLL			43
> +#define IMX943_CLK_EXT1				44
> +#define IMX943_CLK_EXT2				45
> +
> +#define IMX943_CLK_NUM_SRC			46

Drop and all other clock numbers like that.

...

> +#include <dt-bindings/dma/fsl-edma.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +#include "imx943-clock.h"
> +#include "imx943-pinfunc.h"
> +#include "imx943-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>;
> +			};
> +		};
> +
> +		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_perf IMX943_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 {

labels are always lowercase.

> +			device_type = "cpu";
> +			compatible = "arm,cortex-a55";
> +			reg = <0x100>;
> +			enable-method = "psci";
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&cpu_pd_wait>;
> +			power-domains = <&scmi_perf IMX943_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_perf IMX943_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>;
> +			cpu-idle-states = <&cpu_pd_wait>;
> +			power-domains = <&scmi_perf IMX943_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>;
> +		};
> +
> +		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>;
> +		};
> +
> +		l3_cache: l3-cache {
> +			compatible = "cache";
> +			cache-size = <1048576>;
> +			cache-line-size = <64>;
> +			cache-sets = <1024>;
> +			cache-level = <3>;
> +			cache-unified;
> +		};
> +	};
> +
> +	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";
> +	};
> +
> +	osc_24m: clock-24m {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <24000000>;
> +		clock-output-names = "osc_24m";
> +	};
> +
> +	sai1_mclk: clock-sai1-mclk1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <0>;
> +		clock-output-names = "sai1_mclk";
> +	};
> +
> +	sai2_mclk: clock-sai2-mclk1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <0>;
> +		clock-output-names = "sai2_mclk";
> +	};
> +
> +	sai3_mclk: clock-sai3-mclk1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <0>;
> +		clock-output-names = "sai3_mclk";
> +	};
> +
> +	sai4_mclk: clock-sai4-mclk1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <0>;
> +		clock-output-names = "sai4_mclk";
> +	};
> +
> +	firmware {
> +		scmi {
> +			compatible = "arm,scmi";
> +			mboxes = <&mu2 5 0>, <&mu2 3 0>, <&mu2 3 1>, <&mu2 5 1>;
> +			shmem = <&scmi_buf0>, <&scmi_buf1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			arm,max-rx-timeout-ms = <5000>;
> +
> +			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_iomuxc: protocol at 19 {
> +				reg = <0x19>;
> +			};
> +
> +			scmi_bbm: protocol at 81 {
> +				reg = <0x81>;
> +			};
> +		};
> +	};
> +
> +	pmu {
> +		compatible = "arm,cortex-a55-pmu";
> +		interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	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";
> +			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>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x42000000 0x0 0x42000000 0x8000000>;
> +
> +			edma2: dma-controller at 42000000 {
> +				compatible = "fsl,imx95-edma5";

imx943 or imx95?

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec 16 02:19:12 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 16 Dec 2024 11:19:12 +0100
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <20241212093555.1376568-2-ping.bai@nxp.com>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
Message-ID: <3c9fe85a-5f86-4df6-92fb-e4ceb033f161@kernel.org>

On 12/12/2024 10:35, Jacky Bai wrote:
> The i.MX 943 applications processors integrate up to four
> Arm Cortex A55 cores and supports functional safety with
> built-in 2x Arm Cortex M33 and M7 cores which can be
> configured asa safety island. Optimizing performance and
> power efficiency for Industrial, IoT and automotive devices,
> i.MX 943 processors are built with NXP?s innovative Energy
> Flex architecture.

Few more comments:

Drop all marketing junk talk.

> 
> This patch adds the minimal dtsi support for i.MX943 with

Please do not use "This commit/patch/change", but imperative mood. See
longer explanation here:
https://elixir.bootlin.com/linux/v5.17.1/source/Documentation/process/submitting-patches.rst#L95

> peripherals like uart, edma, i2c, spi, mu, sai etc.

Explain how can we test it, why this differs from imx95 but uses imx95,
why this is needed in the first place without users.

> 
> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx943-clock.h  |  196 +++
>  .../arm64/boot/dts/freescale/imx943-pinfunc.h | 1542 +++++++++++++++++
>  arch/arm64/boot/dts/freescale/imx943-power.h  |   41 +
>  arch/arm64/boot/dts/freescale/imx943.dtsi     | 1284 ++++++++++++++
>  4 files changed, 3063 insertions(+)


Best regards,
Krzysztof


From danishanwar at ti.com  Mon Dec 16 02:23:13 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 16 Dec 2024 15:53:13 +0530
Subject: [PATCH v3 0/2] Add Clocks for ICSSG
In-Reply-To: <20241113110955.3876045-1-danishanwar@ti.com>
References: <20241113110955.3876045-1-danishanwar@ti.com>
Message-ID: <7c48ccdc-41b3-4205-854d-9b7a60f70da2@ti.com>

Hi Vignesh / Nishant

On 13/11/24 4:39 pm, MD Danish Anwar wrote:
> This series adds clocks for ICSSG for AM64x.
> 
> PATCH 1/2 Adds the dt binding necessary to add clocks to the device tree.
> It adds the `clocks` in the dt binding of ICSSG node. Each ICSSG instance
> has 7 clocks available to them as per AM64x TRM [1] Section 6.4.3 Table 
> 6-398. They are not added in the dt bindings yet. This patch adds all
> available clocks to ICSSG bindings. 
> 
> PATCH 2/2 Adds the required clock to the ICSSG nodes. It also changes the
> clock used from clock 20 (ICSSG_ICLK) to clock 0 (ICSSG_CORE). This patch
> adds the clock-names, assigned-clocks and assigned-clock-parents to icssg
> nodes.
> 
> More details on clocks can be found at [2]
> There is no additional driver changes needed for this binding change.
> 
> Changes from v2 to v3:
> *) Modified commit message of PATCH 1/2 to state why clocks are being added
> to the binding.
> *) Added all available clocks to ICSSG bindings. Earlier only two clocks
> were added.
> *) Added all available clocks to AM64x DTS. Earlier only two clocks were
> added.
> 
> Changes from v1 to v2:
> *) Dropped assigned-clocks and assigned-clock-parents from DT binding as
> suggested by Krzysztof Kozlowski
> 
> [1] https://www.ti.com/lit/pdf/spruim2
> [2] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/clocks.html#clocks-for-pru-icssg0-device
> v1 https://lore.kernel.org/all/20241107104557.1442800-1-danishanwar at ti.com/
> v2 https://lore.kernel.org/all/20241108142946.2286098-1-danishanwar at ti.com/
> 
> MD Danish Anwar (2):
>   dt-bindings: soc: ti: pruss: Add clocks for ICSSG
>   arm64: dts: ti: k3-am64-main: Switch ICSSG clock to core clock
> 
>  .../devicetree/bindings/soc/ti/ti,pruss.yaml  | 10 +++++++++
>  arch/arm64/boot/dts/ti/k3-am64-main.dtsi      | 22 +++++++++++++++++--
>  2 files changed, 30 insertions(+), 2 deletions(-)
> 
> 
> base-commit: bd05b9a700c10473c2f52bf12c5c5938c30e80b0

This series still applies cleanly on latest linux-next (next-20241216)
and doesn't need a re-base.

Can you please pick this.


-- 
Thanks and Regards,
Danish


From gchen.guomin at gmail.com  Mon Dec 16 02:37:01 2024
From: gchen.guomin at gmail.com (gchen chen)
Date: Mon, 16 Dec 2024 18:37:01 +0800
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless scmi_bus_id.
In-Reply-To: <Z1_2rxJ7TOEIOMp7@pluto>
References: <20241216073745.2973317-1-guomin_chen@sina.com>
 <Z1_p0nU93PHJ4Sg_@pluto> <Z1_2rxJ7TOEIOMp7@pluto>
Message-ID: <CAEEwsfRhe4-YAwe027huSXwFfkV-O-8w1GDNf=URa9efRsXiKA@mail.gmail.com>

Cristian Marussi <cristian.marussi at arm.com> ?2024?12?16??? 17:45???
>
> On Mon, Dec 16, 2024 at 08:50:26AM +0000, Cristian Marussi wrote:
> > On Mon, Dec 16, 2024 at 03:37:45PM +0800, guomin_chen at sina.com wrote:
> > > From: guomin chen <guomin_chen at sina.com>
> > >
> > > Currently, scmi_bus_id is only used to set scmi_dev.id,
> > > which in turn sets the SCMI device name. After removing
> > > scmi_bus_id, it is clearer and more meaningful to directly
> > > use the unique tuple [Parent name,device name, protocol] to
> > > set the SCMI device name.
> > >
> >
> > Hi Guomin,
> >
> > this same pTCH was NACKed(Rejected) a few days ago:
> >
> > https://lore.kernel.org/arm-scmi/20241211134505.2218386-1-guomin_chen at sina.com/T/#u
> >
> > ...and you agreed that is not a simplification we can do (not to break
> > multuple instances...)...
> >
> > ..so why you are posting V2 now ?
>
> Wait...you changed slightly this indeed....you are using dev_parent...my
> bad...but please when you post new version of a patch add a summary of
> changes between versions...
>
> >
> > Thanks,
> > Cristian
> >
> > > Signed-off-by: guomin chen <guomin_chen at sina.com>
> > > ---
> > >  drivers/firmware/arm_scmi/bus.c    | 17 +++--------------
> > >  drivers/firmware/arm_scmi/driver.c |  4 ++--
> > >  2 files changed, 5 insertions(+), 16 deletions(-)
> > >
> > > diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
> > > index 157172a5f2b5..800e8ec9357c 100644
> > > --- a/drivers/firmware/arm_scmi/bus.c
> > > +++ b/drivers/firmware/arm_scmi/bus.c
> > > @@ -20,7 +20,6 @@
> > >  BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
> > >  EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
> > >
> > > -static DEFINE_IDA(scmi_bus_id);
> > >
> > >  static DEFINE_IDR(scmi_requested_devices);
> > >  /* Protect access to scmi_requested_devices */
> > > @@ -341,7 +340,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
> > >     if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
> > >             atomic_set(&scmi_syspower_registered, 0);
> > >
> > > -   ida_free(&scmi_bus_id, scmi_dev->id);
> > >     device_unregister(&scmi_dev->dev);
> > >  }
> > >
> > > @@ -349,7 +347,7 @@ static struct scmi_device *
> > >  __scmi_device_create(struct device_node *np, struct device *parent,
> > >                  int protocol, const char *name)
> > >  {
> > > -   int id, retval;
> > > +   int retval;
> > >     struct scmi_device *scmi_dev;
> > >
> > >     /*
> > > @@ -387,20 +385,13 @@ __scmi_device_create(struct device_node *np, struct device *parent,
> > >             return NULL;
> > >     }
> > >
> > > -   id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
> > > -   if (id < 0) {
> > > -           kfree_const(scmi_dev->name);
> > > -           kfree(scmi_dev);
> > > -           return NULL;
> > > -   }
> > > -
> > > -   scmi_dev->id = id;
> > >     scmi_dev->protocol_id = protocol;
> > >     scmi_dev->dev.parent = parent;
> > >     device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
> > >     scmi_dev->dev.bus = &scmi_bus_type;
> > >     scmi_dev->dev.release = scmi_device_release;
> > > -   dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
> > > +   dev_set_name(&scmi_dev->dev, "scmi_dev.%s.%s.%d", dev_name(parent),
> > > +                   scmi_dev->name, protocol);
> > >
>
> So now you are using the parent top node SCMI device to create a unique
> device...and it probably endup in a name like:
>
>         scmi-dev.arm-scmi.0.auto.genpd.13
>
>         scmi-dev.arm-scmi.1.auto.genpd.13
>
> ...that certainly is more readable but is bulky and anyway giving unique
> IDs to devices is pretty common and you lookup which device is which by
> simply looking at the drivers/ link....not suure what's the benefit of
> all of this...just to avoid an IDA table ?
>
> > >     retval = device_register(&scmi_dev->dev);
> > >     if (retval)
> > > @@ -413,7 +404,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
> > >     return scmi_dev;
> > >  put_dev:
> > >     put_device(&scmi_dev->dev);
> > > -   ida_free(&scmi_bus_id, id);
> > >     return NULL;
> > >  }
> > >
> > > @@ -526,7 +516,6 @@ static void __exit scmi_bus_exit(void)
> > >      */
> > >     scmi_devices_unregister();
> > >     bus_unregister(&scmi_bus_type);
> > > -   ida_destroy(&scmi_bus_id);
> > >  }
> > >  module_exit(scmi_bus_exit);
> > >
> > > diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> > > index 1b5fb2c4ce86..bbf1f05f2be3 100644
> > > --- a/drivers/firmware/arm_scmi/driver.c
> > > +++ b/drivers/firmware/arm_scmi/driver.c
> > > @@ -2641,8 +2641,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
> > >     cinfo->max_msg_size = info->desc->max_msg_size;
> > >
> > >     /* Create a unique name for this transport device */
> > > -   snprintf(name, 32, "__scmi_transport_device_%s_%02X",
> > > -            idx ? "rx" : "tx", prot_id);
> > > +   snprintf(name, 32, "__scmi_transport_device_%s",
> > > +            idx ? "rx" : "tx");
>
> I agree on what Dan said AND also this results in having the same name for different
> devices across 2 instances if you have a per-protocol channel because you havent anymore
> the protocol_id bit.
hi  Cristian?and dan
    Because I used a 3-tuple [parent name, name, protocol] when
creating the SCMI device name, I removed the prot_id from the
parameter ?name? when creating transport devices. This way, it avoids
the repetition of protocol ID in the SCMI device name.

> All in all, I would drop this patch and keep naming as it is because I dont see a real benefit
> here....up to Sudeep decide.
     Yes, it does not have real benefits, but from the perspective of
the device name, this change will be clearer and more meaningful. And
the code is more concise.

Thanks
guomin.chen
>
> Thanks,
> Cristian


From sudeep.holla at arm.com  Mon Dec 16 02:45:32 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 16 Dec 2024 10:45:32 +0000
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless
 scmi_bus_id.
In-Reply-To: <CAEEwsfRhe4-YAwe027huSXwFfkV-O-8w1GDNf=URa9efRsXiKA@mail.gmail.com>
References: <20241216073745.2973317-1-guomin_chen@sina.com>
 <Z1_p0nU93PHJ4Sg_@pluto>
 <Z1_2rxJ7TOEIOMp7@pluto>
 <CAEEwsfRhe4-YAwe027huSXwFfkV-O-8w1GDNf=URa9efRsXiKA@mail.gmail.com>
Message-ID: <Z2AEzHc5f6TjxErs@bogus>

On Mon, Dec 16, 2024 at 06:37:01PM +0800, gchen chen wrote:
> Cristian Marussi <cristian.marussi at arm.com> ?2024?12?16??? 17:45???
> >
> > On Mon, Dec 16, 2024 at 08:50:26AM +0000, Cristian Marussi wrote:
> > > On Mon, Dec 16, 2024 at 03:37:45PM +0800, guomin_chen at sina.com wrote:
> > > > From: guomin chen <guomin_chen at sina.com>
> > > >
> > > > Currently, scmi_bus_id is only used to set scmi_dev.id,
> > > > which in turn sets the SCMI device name. After removing
> > > > scmi_bus_id, it is clearer and more meaningful to directly
> > > > use the unique tuple [Parent name,device name, protocol] to
> > > > set the SCMI device name.
> > > >
> > >
> > > Hi Guomin,
> > >
> > > this same pTCH was NACKed(Rejected) a few days ago:
> > >
> > > https://lore.kernel.org/arm-scmi/20241211134505.2218386-1-guomin_chen at sina.com/T/#u
> > >
> > > ...and you agreed that is not a simplification we can do (not to break
> > > multuple instances...)...
> > >
> > > ..so why you are posting V2 now ?
> >
> > Wait...you changed slightly this indeed....you are using dev_parent...my
> > bad...but please when you post new version of a patch add a summary of
> > changes between versions...
> >
> > >
> > > Thanks,
> > > Cristian
> > >
> > > > Signed-off-by: guomin chen <guomin_chen at sina.com>
> > > > ---
> > > >  drivers/firmware/arm_scmi/bus.c    | 17 +++--------------
> > > >  drivers/firmware/arm_scmi/driver.c |  4 ++--
> > > >  2 files changed, 5 insertions(+), 16 deletions(-)
> > > >
> > > > diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
> > > > index 157172a5f2b5..800e8ec9357c 100644
> > > > --- a/drivers/firmware/arm_scmi/bus.c
> > > > +++ b/drivers/firmware/arm_scmi/bus.c
> > > > @@ -20,7 +20,6 @@
> > > >  BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
> > > >  EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
> > > >
> > > > -static DEFINE_IDA(scmi_bus_id);
> > > >
> > > >  static DEFINE_IDR(scmi_requested_devices);
> > > >  /* Protect access to scmi_requested_devices */
> > > > @@ -341,7 +340,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
> > > >     if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
> > > >             atomic_set(&scmi_syspower_registered, 0);
> > > >
> > > > -   ida_free(&scmi_bus_id, scmi_dev->id);
> > > >     device_unregister(&scmi_dev->dev);
> > > >  }
> > > >
> > > > @@ -349,7 +347,7 @@ static struct scmi_device *
> > > >  __scmi_device_create(struct device_node *np, struct device *parent,
> > > >                  int protocol, const char *name)
> > > >  {
> > > > -   int id, retval;
> > > > +   int retval;
> > > >     struct scmi_device *scmi_dev;
> > > >
> > > >     /*
> > > > @@ -387,20 +385,13 @@ __scmi_device_create(struct device_node *np, struct device *parent,
> > > >             return NULL;
> > > >     }
> > > >
> > > > -   id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
> > > > -   if (id < 0) {
> > > > -           kfree_const(scmi_dev->name);
> > > > -           kfree(scmi_dev);
> > > > -           return NULL;
> > > > -   }
> > > > -
> > > > -   scmi_dev->id = id;
> > > >     scmi_dev->protocol_id = protocol;
> > > >     scmi_dev->dev.parent = parent;
> > > >     device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
> > > >     scmi_dev->dev.bus = &scmi_bus_type;
> > > >     scmi_dev->dev.release = scmi_device_release;
> > > > -   dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
> > > > +   dev_set_name(&scmi_dev->dev, "scmi_dev.%s.%s.%d", dev_name(parent),
> > > > +                   scmi_dev->name, protocol);
> > > >
> >
> > So now you are using the parent top node SCMI device to create a unique
> > device...and it probably endup in a name like:
> >
> >         scmi-dev.arm-scmi.0.auto.genpd.13
> >
> >         scmi-dev.arm-scmi.1.auto.genpd.13
> >
> > ...that certainly is more readable but is bulky and anyway giving unique
> > IDs to devices is pretty common and you lookup which device is which by
> > simply looking at the drivers/ link....not suure what's the benefit of
> > all of this...just to avoid an IDA table ?
> >
> > > >     retval = device_register(&scmi_dev->dev);
> > > >     if (retval)
> > > > @@ -413,7 +404,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
> > > >     return scmi_dev;
> > > >  put_dev:
> > > >     put_device(&scmi_dev->dev);
> > > > -   ida_free(&scmi_bus_id, id);
> > > >     return NULL;
> > > >  }
> > > >
> > > > @@ -526,7 +516,6 @@ static void __exit scmi_bus_exit(void)
> > > >      */
> > > >     scmi_devices_unregister();
> > > >     bus_unregister(&scmi_bus_type);
> > > > -   ida_destroy(&scmi_bus_id);
> > > >  }
> > > >  module_exit(scmi_bus_exit);
> > > >
> > > > diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> > > > index 1b5fb2c4ce86..bbf1f05f2be3 100644
> > > > --- a/drivers/firmware/arm_scmi/driver.c
> > > > +++ b/drivers/firmware/arm_scmi/driver.c
> > > > @@ -2641,8 +2641,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
> > > >     cinfo->max_msg_size = info->desc->max_msg_size;
> > > >
> > > >     /* Create a unique name for this transport device */
> > > > -   snprintf(name, 32, "__scmi_transport_device_%s_%02X",
> > > > -            idx ? "rx" : "tx", prot_id);
> > > > +   snprintf(name, 32, "__scmi_transport_device_%s",
> > > > +            idx ? "rx" : "tx");
> >
> > I agree on what Dan said AND also this results in having the same name for different
> > devices across 2 instances if you have a per-protocol channel because you havent anymore
> > the protocol_id bit.
> hi  Cristian?and dan
>     Because I used a 3-tuple [parent name, name, protocol] when
> creating the SCMI device name, I removed the prot_id from the
> parameter ?name? when creating transport devices. This way, it avoids
> the repetition of protocol ID in the SCMI device name.
> 
> > All in all, I would drop this patch and keep naming as it is because I dont see a real benefit
> > here....up to Sudeep decide.
>      Yes, it does not have real benefits, but from the perspective of
> the device name, this change will be clearer and more meaningful. And
> the code is more concise.
>

I would like to understand the motivation behind this change. What is the
goal ? Do you prefer to fetch the name and protocol id from the device
name itself ? Is that your requirement.

>From the commit log, I get a sense that you looked at the code and thought
of possible improvement but when we mentioned the limitation you just
improvised by adding parent name. Do you expect any userspace to parse
the name as that will end up being ABI and we can't break it. I need
real motive to be explained here in detail.

--
Regards,
Sudeep


From tabba at google.com  Mon Dec 16 02:50:43 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:43 +0000
Subject: [PATCH v5 03/17] KVM: arm64: Move checking protected vcpu features to
 a separate function
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-4-tabba@google.com>

At the moment, checks for supported vcpu features for protected
VMs are build-time bugs. In the following patch, they will become
runtime checks based on the vcpu's features registers. Therefore,
consolidate them into one function that would return an error if
it encounters an unsupported feature.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 45 ++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 1744574e79b2..fb733b36c6c1 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -178,20 +178,11 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 }
 
 /*
- * Initialize trap register values in protected mode.
+ * Check that cpu features that are neither trapped nor supported are not
+ * enabled for protected VMs.
  */
-static void pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
+static int pkvm_check_pvm_cpu_features(struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
-
-	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
-	vcpu->arch.mdcr_el2 = 0;
-
-	pkvm_vcpu_reset_hcr(vcpu);
-
-	if ((!pkvm_hyp_vcpu_is_protected(hyp_vcpu)))
-		return;
-
 	/*
 	 * PAuth is allowed if supported by the system and the vcpu.
 	 * Properly checking for PAuth requires checking various fields in
@@ -218,9 +209,34 @@ static void pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
 	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
 				PVM_ID_AA64PFR0_ALLOW));
 
+	return 0;
+}
+
+/*
+ * Initialize trap register values in protected mode.
+ */
+static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
+{
+	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
+	int ret;
+
+	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
+	vcpu->arch.mdcr_el2 = 0;
+
+	pkvm_vcpu_reset_hcr(vcpu);
+
+	if ((!pkvm_hyp_vcpu_is_protected(hyp_vcpu)))
+		return 0;
+
+	ret = pkvm_check_pvm_cpu_features(vcpu);
+	if (ret)
+		return ret;
+
 	pvm_init_traps_hcr(vcpu);
 	pvm_init_traps_cptr(vcpu);
 	pvm_init_traps_mdcr(vcpu);
+
+	return 0;
 }
 
 /*
@@ -417,9 +433,12 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
 	hyp_vcpu->vcpu.arch.cflags = READ_ONCE(host_vcpu->arch.cflags);
 	hyp_vcpu->vcpu.arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
 
+	ret = pkvm_vcpu_init_traps(hyp_vcpu);
+	if (ret)
+		goto done;
+
 	pkvm_vcpu_init_sve(hyp_vcpu, host_vcpu);
 	pkvm_vcpu_init_ptrauth(hyp_vcpu);
-	pkvm_vcpu_init_traps(hyp_vcpu);
 done:
 	if (ret)
 		unpin_host_vcpu(host_vcpu);
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:44 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:44 +0000
Subject: [PATCH v5 04/17] KVM: arm64: Remove KVM_ARM_VCPU_POWER_OFF from
 protected VMs allowed features in pKVM
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-5-tabba@google.com>

The hypervisor is responsible for the power state of protected
VMs in pKVM. Therefore, remove KVM_ARM_VCPU_POWER_OFF from the
list of allowed features for protected VMs.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index fb733b36c6c1..d3f67189497d 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -331,10 +331,8 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 
 	/*
 	 * For protected VMs, always allow:
-	 * - CPU starting in poweroff state
 	 * - PSCI v0.2
 	 */
-	set_bit(KVM_ARM_VCPU_POWER_OFF, allowed_features);
 	set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
 
 	/*
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:45 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:45 +0000
Subject: [PATCH v5 05/17] KVM: arm64: Use KVM extension checks for allowed
 protected VM capabilities
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-6-tabba@google.com>

Use KVM extension checks as the source for determining which
capabilities are allowed for protected VMs. KVM extension checks
is the natural place for this, since it is also the interface
exposed to users.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_pkvm.h | 25 +++++++++++++++++++++++++
 arch/arm64/kvm/arm.c              | 29 ++---------------------------
 arch/arm64/kvm/hyp/nvhe/pkvm.c    | 24 ++++++------------------
 3 files changed, 33 insertions(+), 45 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index cd56acd9a842..400f7cef1e81 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -20,6 +20,31 @@ int pkvm_init_host_vm(struct kvm *kvm);
 int pkvm_create_hyp_vm(struct kvm *kvm);
 void pkvm_destroy_hyp_vm(struct kvm *kvm);
 
+/*
+ * This functions as an allow-list of protected VM capabilities.
+ * Features not explicitly allowed by this function are denied.
+ */
+static inline bool kvm_pvm_ext_allowed(long ext)
+{
+	switch (ext) {
+	case KVM_CAP_IRQCHIP:
+	case KVM_CAP_ARM_PSCI:
+	case KVM_CAP_ARM_PSCI_0_2:
+	case KVM_CAP_NR_VCPUS:
+	case KVM_CAP_MAX_VCPUS:
+	case KVM_CAP_MAX_VCPU_ID:
+	case KVM_CAP_MSI_DEVID:
+	case KVM_CAP_ARM_VM_IPA_SIZE:
+	case KVM_CAP_ARM_PMU_V3:
+	case KVM_CAP_ARM_SVE:
+	case KVM_CAP_ARM_PTRAUTH_ADDRESS:
+	case KVM_CAP_ARM_PTRAUTH_GENERIC:
+		return true;
+	default:
+		return false;
+	}
+}
+
 extern struct memblock_region kvm_nvhe_sym(hyp_memory)[];
 extern unsigned int kvm_nvhe_sym(hyp_memblock_nr);
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..b295218cdc24 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -80,31 +80,6 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
 	return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
 }
 
-/*
- * This functions as an allow-list of protected VM capabilities.
- * Features not explicitly allowed by this function are denied.
- */
-static bool pkvm_ext_allowed(struct kvm *kvm, long ext)
-{
-	switch (ext) {
-	case KVM_CAP_IRQCHIP:
-	case KVM_CAP_ARM_PSCI:
-	case KVM_CAP_ARM_PSCI_0_2:
-	case KVM_CAP_NR_VCPUS:
-	case KVM_CAP_MAX_VCPUS:
-	case KVM_CAP_MAX_VCPU_ID:
-	case KVM_CAP_MSI_DEVID:
-	case KVM_CAP_ARM_VM_IPA_SIZE:
-	case KVM_CAP_ARM_PMU_V3:
-	case KVM_CAP_ARM_SVE:
-	case KVM_CAP_ARM_PTRAUTH_ADDRESS:
-	case KVM_CAP_ARM_PTRAUTH_GENERIC:
-		return true;
-	default:
-		return false;
-	}
-}
-
 int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 			    struct kvm_enable_cap *cap)
 {
@@ -113,7 +88,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 	if (cap->flags)
 		return -EINVAL;
 
-	if (kvm_vm_is_protected(kvm) && !pkvm_ext_allowed(kvm, cap->cap))
+	if (kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(cap->cap))
 		return -EINVAL;
 
 	switch (cap->cap) {
@@ -311,7 +286,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 {
 	int r;
 
-	if (kvm && kvm_vm_is_protected(kvm) && !pkvm_ext_allowed(kvm, ext))
+	if (kvm && kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(ext))
 		return 0;
 
 	switch (ext) {
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index d3f67189497d..59ff6aac514c 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -329,32 +329,20 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 
 	bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
 
-	/*
-	 * For protected VMs, always allow:
-	 * - PSCI v0.2
-	 */
 	set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
 
-	/*
-	 * Check if remaining features are allowed:
-	 * - Performance Monitoring
-	 * - Scalable Vectors
-	 * - Pointer Authentication
-	 */
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), PVM_ID_AA64DFR0_ALLOW))
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PMU_V3))
 		set_bit(KVM_ARM_VCPU_PMU_V3, allowed_features);
 
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), PVM_ID_AA64PFR0_ALLOW))
-		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
-
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_ALLOW) &&
-	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_ALLOW))
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_ADDRESS))
 		set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
 
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI), PVM_ID_AA64ISAR1_ALLOW) &&
-	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA), PVM_ID_AA64ISAR1_ALLOW))
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_GENERIC))
 		set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
 
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE))
+		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
+
 	bitmap_and(kvm->arch.vcpu_features, host_kvm->arch.vcpu_features,
 		   allowed_features, KVM_VCPU_MAX_FEATURES);
 }
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:46 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:46 +0000
Subject: [PATCH v5 06/17] KVM: arm64: Initialize feature id registers for
 protected VMs
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-7-tabba@google.com>

The hypervisor maintains the state of protected VMs. Initialize
the values for feature ID registers for protected VMs, to be used
when setting traps and when advertising features to protected
VMs.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h |  1 +
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  2 +
 arch/arm64/kvm/hyp/nvhe/pkvm.c                | 10 +++--
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            | 44 +++++++++++++++++--
 4 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
index d1e59b88ff66..69e26d1a0ebe 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
@@ -201,6 +201,7 @@
 u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
 bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
 bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
+void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu);
 int kvm_check_pvm_sysreg_table(void);
 
 #endif /* __ARM64_KVM_FIXED_CONFIG_H__ */
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 24a9a8330d19..698bc20ab80b 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -47,6 +47,8 @@ struct pkvm_hyp_vm {
 	struct pkvm_hyp_vcpu *vcpus[];
 };
 
+extern hyp_spinlock_t vm_table_lock;
+
 static inline struct pkvm_hyp_vm *
 pkvm_hyp_vcpu_to_hyp_vm(struct pkvm_hyp_vcpu *hyp_vcpu)
 {
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 59ff6aac514c..3014f3295d81 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -257,10 +257,10 @@ static pkvm_handle_t idx_to_vm_handle(unsigned int idx)
 
 /*
  * Spinlock for protecting state related to the VM table. Protects writes
- * to 'vm_table' and 'nr_table_entries' as well as reads and writes to
- * 'last_hyp_vcpu_lookup'.
+ * to 'vm_table', 'nr_table_entries', and other per-vm state on initialization.
+ * Also protects reads and writes to 'last_hyp_vcpu_lookup'.
  */
-static DEFINE_HYP_SPINLOCK(vm_table_lock);
+DEFINE_HYP_SPINLOCK(vm_table_lock);
 
 /*
  * The table of VM entries for protected VMs in hyp.
@@ -381,6 +381,7 @@ static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
 	hyp_vm->kvm.created_vcpus = nr_vcpus;
 	hyp_vm->kvm.arch.mmu.vtcr = host_mmu.arch.mmu.vtcr;
 	hyp_vm->kvm.arch.pkvm.enabled = READ_ONCE(host_kvm->arch.pkvm.enabled);
+	hyp_vm->kvm.arch.flags = 0;
 	pkvm_init_features_from_host(hyp_vm, host_kvm);
 }
 
@@ -419,6 +420,9 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
 	hyp_vcpu->vcpu.arch.cflags = READ_ONCE(host_vcpu->arch.cflags);
 	hyp_vcpu->vcpu.arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
 
+	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		kvm_init_pvm_id_regs(&hyp_vcpu->vcpu);
+
 	ret = pkvm_vcpu_init_traps(hyp_vcpu);
 	if (ret)
 		goto done;
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 59fb2f056177..453a130b7a5d 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -204,8 +204,7 @@ static u64 get_pvm_id_aa64mmfr2(const struct kvm_vcpu *vcpu)
 	return id_aa64mmfr2_el1_sys_val & PVM_ID_AA64MMFR2_ALLOW;
 }
 
-/* Read a sanitized cpufeature ID register by its encoding */
-u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
+static u64 pvm_calc_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 {
 	switch (id) {
 	case SYS_ID_AA64PFR0_EL1:
@@ -240,10 +239,25 @@ u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 	}
 }
 
+/* Read a sanitized cpufeature ID register by its encoding */
+u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
+{
+	return pvm_calc_id_reg(vcpu, id);
+}
+
 static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 		       struct sys_reg_desc const *r)
 {
-	return pvm_read_id_reg(vcpu, reg_to_encoding(r));
+	struct kvm *kvm = vcpu->kvm;
+	u32 reg = reg_to_encoding(r);
+
+	if (WARN_ON_ONCE(!test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags)))
+		return 0;
+
+	if (reg >= sys_reg(3, 0, 0, 1, 0) && reg <= sys_reg(3, 0, 0, 7, 7))
+		return kvm->arch.id_regs[IDREG_IDX(reg)];
+
+	return 0;
 }
 
 /* Handler to RAZ/WI sysregs */
@@ -448,6 +462,30 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = {
 	/* Performance Monitoring Registers are restricted. */
 };
 
+/*
+ * Initializes feature registers for protected vms.
+ */
+void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+	struct kvm_arch *ka = &kvm->arch;
+	u32 r;
+
+	hyp_assert_lock_held(&vm_table_lock);
+
+	if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags))
+		return;
+
+	/*
+	 * Initialize only AArch64 id registers since AArch32 isn't supported
+	 * for protected VMs.
+	 */
+	for (r = sys_reg(3, 0, 0, 4, 0); r <= sys_reg(3, 0, 0, 7, 7); r += sys_reg(0, 0, 0, 0, 1))
+		ka->id_regs[IDREG_IDX(r)] = pvm_calc_id_reg(vcpu, r);
+
+	set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
+}
+
 /*
  * Checks that the sysreg table is unique and in-order.
  *
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:47 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:47 +0000
Subject: [PATCH v5 07/17] KVM: arm64: Fix RAS trapping in pKVM for protected VMs
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-8-tabba@google.com>

Trap RAS in pKVM if not supported at all for protected VMs. The
RAS version doesn't matter in this case.

Fixes: 2a0c343386ae ("KVM: arm64: Initialize trap registers for protected VMs")
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 3014f3295d81..25bbd4c99d30 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -70,9 +70,8 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 	 */
 	val |= HCR_TACR | HCR_TIDCP | HCR_TID3 | HCR_TID1;
 
-	/* Trap RAS unless all current versions are supported */
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0) <
-	    ID_AA64PFR0_EL1_RAS_V1P1) {
+	/* Trap RAS */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0)) {
 		val |= HCR_TERR | HCR_TEA;
 		val &= ~(HCR_FIEN);
 	}
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:48 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:48 +0000
Subject: [PATCH v5 08/17] KVM: arm64: Set protected VM traps based on its view
 of feature registers
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-9-tabba@google.com>

Now that the VM's feature id registers are initialized with the
values of the supported features, use those values to determine
which traps to set using kvm_has_feature().

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c     | 84 +++++++++++-------------------
 arch/arm64/kvm/hyp/nvhe/sys_regs.c |  7 ---
 2 files changed, 30 insertions(+), 61 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 25bbd4c99d30..2aa349fc42b8 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -52,9 +52,7 @@ static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 
 static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 {
-	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
-	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
-	const u64 id_aa64mmfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
+	struct kvm *kvm = vcpu->kvm;
 	u64 val = vcpu->arch.hcr_el2;
 
 	/* No support for AArch32. */
@@ -70,24 +68,20 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 	 */
 	val |= HCR_TACR | HCR_TIDCP | HCR_TID3 | HCR_TID1;
 
-	/* Trap RAS */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0)) {
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
 		val |= HCR_TERR | HCR_TEA;
 		val &= ~(HCR_FIEN);
 	}
 
-	/* Trap AMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
 		val &= ~(HCR_AMVOFFEN);
 
-	/* Memory Tagging: Trap and Treat as Untagged if not supported. */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE), id_aa64pfr1)) {
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, MTE, IMP)) {
 		val |= HCR_TID5;
 		val &= ~(HCR_DCT | HCR_ATA);
 	}
 
-	/* Trap LOR */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_LO), id_aa64mmfr1))
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
 		val |= HCR_TLOR;
 
 	vcpu->arch.hcr_el2 = val;
@@ -95,9 +89,7 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 
 static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 {
-	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
-	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
-	const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
+	struct kvm *kvm = vcpu->kvm;
 	u64 val = vcpu->arch.cptr_el2;
 
 	if (!has_hvhe()) {
@@ -105,12 +97,11 @@ static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 		val &= ~(CPTR_NVHE_EL2_RES0);
 	}
 
-	/* Trap AMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
 		val |= CPTR_EL2_TAM;
 
-	/* Trap SVE */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), id_aa64pfr0)) {
+	/* SVE can be disabled by userspace even if supported. */
+	if (!vcpu_has_sve(vcpu)) {
 		if (has_hvhe())
 			val &= ~(CPACR_ELx_ZEN);
 		else
@@ -118,14 +109,13 @@ static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 	}
 
 	/* No SME support in KVM. */
-	BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME), id_aa64pfr1));
+	BUG_ON(kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP));
 	if (has_hvhe())
 		val &= ~(CPACR_ELx_SMEN);
 	else
 		val |= CPTR_EL2_TSM;
 
-	/* Trap Trace */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), id_aa64dfr0)) {
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP)) {
 		if (has_hvhe())
 			val |= CPACR_EL1_TTA;
 		else
@@ -137,40 +127,33 @@ static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 
 static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 {
-	const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
-	const u64 id_aa64mmfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR0_EL1);
+	struct kvm *kvm = vcpu->kvm;
 	u64 val = vcpu->arch.mdcr_el2;
 
-	/* Trap/constrain PMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), id_aa64dfr0)) {
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP)) {
 		val |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
 		val &= ~(MDCR_EL2_HPME | MDCR_EL2_MTPME | MDCR_EL2_HPMN_MASK);
 	}
 
-	/* Trap Debug */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DebugVer), id_aa64dfr0))
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DebugVer, IMP))
 		val |= MDCR_EL2_TDRA | MDCR_EL2_TDA;
 
-	/* Trap OS Double Lock */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DoubleLock), id_aa64dfr0))
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
 		val |= MDCR_EL2_TDOSA;
 
-	/* Trap SPE */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMSVer), id_aa64dfr0)) {
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, IMP)) {
 		val |= MDCR_EL2_TPMS;
 		val &= ~(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT);
 	}
 
-	/* Trap Trace Filter */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), id_aa64dfr0))
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
 		val |= MDCR_EL2_TTRF;
 
-	/* Trap External Trace */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), id_aa64dfr0))
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, ExtTrcBuff, IMP))
 		val |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
 
 	/* Trap Debug Communications Channel registers */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_FGT), id_aa64mmfr0))
+	if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, FGT, IMP))
 		val |= MDCR_EL2_TDCC;
 
 	vcpu->arch.mdcr_el2 = val;
@@ -182,31 +165,24 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
  */
 static int pkvm_check_pvm_cpu_features(struct kvm_vcpu *vcpu)
 {
-	/*
-	 * PAuth is allowed if supported by the system and the vcpu.
-	 * Properly checking for PAuth requires checking various fields in
-	 * ID_AA64ISAR1_EL1 and ID_AA64ISAR2_EL1. The way that fixed config
-	 * is controlled now in pKVM does not easily allow that. This will
-	 * change later to follow the changes upstream wrt fixed configuration
-	 * and nested virt.
-	 */
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI),
-				PVM_ID_AA64ISAR1_ALLOW));
+	struct kvm *kvm = vcpu->kvm;
 
 	/* Protected KVM does not support AArch32 guests. */
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
-		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
+	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL0, AARCH32) ||
+	    kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL1, AARCH32))
+		return -EINVAL;
 
 	/*
 	 * Linux guests assume support for floating-point and Advanced SIMD. Do
 	 * not change the trapping behavior for these from the KVM default.
 	 */
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP),
-				PVM_ID_AA64PFR0_ALLOW));
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
-				PVM_ID_AA64PFR0_ALLOW));
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, FP, IMP) ||
+	    !kvm_has_feat(kvm, ID_AA64PFR0_EL1, AdvSIMD, IMP))
+		return -EINVAL;
+
+	/* No SME support in KVM right now. Check to catch if it changes. */
+	if (kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
+		return -EINVAL;
 
 	return 0;
 }
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 453a130b7a5d..f2edd024786f 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -285,13 +285,6 @@ static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
 		return false;
 	}
 
-	/*
-	 * No support for AArch32 guests, therefore, pKVM has no sanitized copy
-	 * of AArch32 feature id registers.
-	 */
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		     PVM_ID_AA64PFR0_ALLOW) > ID_AA64PFR0_EL1_EL1_IMP);
-
 	return pvm_access_raz_wi(vcpu, p, r);
 }
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:49 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:49 +0000
Subject: [PATCH v5 09/17] KVM: arm64: Rework specifying restricted features
 for protected VMs
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-10-tabba@google.com>

The existing code didn't properly distinguish between signed and
unsigned features, and was difficult to read and to maintain.
Rework it using the same method used in other parts of KVM when
handling vcpu features.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_host.h             |   1 +
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h |   1 -
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            | 357 +++++++++---------
 3 files changed, 189 insertions(+), 170 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f333b189fb43..230b0638f0c2 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1422,6 +1422,7 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
 	return test_bit(feature, ka->vcpu_features);
 }
 
+#define kvm_vcpu_has_feature(k, f)	__vcpu_has_feature(&(k)->arch, (f))
 #define vcpu_has_feature(v, f)	__vcpu_has_feature(&(v)->kvm->arch, (f))
 
 #define kvm_vcpu_initialized(v) vcpu_get_flag(vcpu, VCPU_INITIALIZED)
diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
index 69e26d1a0ebe..37a6d2434e47 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
@@ -198,7 +198,6 @@
 	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
 	)
 
-u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
 bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
 bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
 void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index f2edd024786f..289f370d386a 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -28,221 +28,240 @@ u64 id_aa64mmfr1_el1_sys_val;
 u64 id_aa64mmfr2_el1_sys_val;
 u64 id_aa64smfr0_el1_sys_val;
 
-/*
- * Inject an unknown/undefined exception to an AArch64 guest while most of its
- * sysregs are live.
- */
-static void inject_undef64(struct kvm_vcpu *vcpu)
-{
-	u64 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
-
-	*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
-	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
-
-	kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
-
-	__kvm_adjust_pc(vcpu);
-
-	write_sysreg_el1(esr, SYS_ESR);
-	write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
-	write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
-	write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
-}
-
-/*
- * Returns the restricted features values of the feature register based on the
- * limitations in restrict_fields.
- * A feature id field value of 0b0000 does not impose any restrictions.
- * Note: Use only for unsigned feature field values.
- */
-static u64 get_restricted_features_unsigned(u64 sys_reg_val,
-					    u64 restrict_fields)
-{
-	u64 value = 0UL;
-	u64 mask = GENMASK_ULL(ARM64_FEATURE_FIELD_BITS - 1, 0);
+struct pvm_ftr_bits {
+	bool		sign;
+	u8		shift;
+	u8		width;
+	u8		max_val;
+	bool (*vm_supported)(const struct kvm *kvm);
+};
 
-	/*
-	 * According to the Arm Architecture Reference Manual, feature fields
-	 * use increasing values to indicate increases in functionality.
-	 * Iterate over the restricted feature fields and calculate the minimum
-	 * unsigned value between the one supported by the system, and what the
-	 * value is being restricted to.
-	 */
-	while (sys_reg_val && restrict_fields) {
-		value |= min(sys_reg_val & mask, restrict_fields & mask);
-		sys_reg_val &= ~mask;
-		restrict_fields &= ~mask;
-		mask <<= ARM64_FEATURE_FIELD_BITS;
+#define __MAX_FEAT_FUNC(id, fld, max, func, sgn)				\
+	{									\
+		.sign = sgn,							\
+		.shift = id##_##fld##_SHIFT,					\
+		.width = id##_##fld##_WIDTH,					\
+		.max_val = id##_##fld##_##max,					\
+		.vm_supported = func,						\
 	}
 
-	return value;
-}
-
-/*
- * Functions that return the value of feature id registers for protected VMs
- * based on allowed features, system features, and KVM support.
- */
-
-static u64 get_pvm_id_aa64pfr0(const struct kvm_vcpu *vcpu)
-{
-	u64 set_mask = 0;
-	u64 allow_mask = PVM_ID_AA64PFR0_ALLOW;
-
-	set_mask |= get_restricted_features_unsigned(id_aa64pfr0_el1_sys_val,
-		PVM_ID_AA64PFR0_ALLOW);
+#define MAX_FEAT_FUNC(id, fld, max, func)					\
+	__MAX_FEAT_FUNC(id, fld, max, func, id##_##fld##_SIGNED)
 
-	return (id_aa64pfr0_el1_sys_val & allow_mask) | set_mask;
-}
-
-static u64 get_pvm_id_aa64pfr1(const struct kvm_vcpu *vcpu)
-{
-	const struct kvm *kvm = (const struct kvm *)kern_hyp_va(vcpu->kvm);
-	u64 allow_mask = PVM_ID_AA64PFR1_ALLOW;
+#define MAX_FEAT(id, fld, max)							\
+	MAX_FEAT_FUNC(id, fld, max, NULL)
 
-	if (!kvm_has_mte(kvm))
-		allow_mask &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
+#define MAX_FEAT_ENUM(id, fld, max)						\
+	__MAX_FEAT_FUNC(id, fld, max, NULL, false)
 
-	return id_aa64pfr1_el1_sys_val & allow_mask;
-}
+#define FEAT_END {	.width = 0,	}
 
-static u64 get_pvm_id_aa64zfr0(const struct kvm_vcpu *vcpu)
+static bool vm_has_ptrauth(const struct kvm *kvm)
 {
-	/*
-	 * No support for Scalable Vectors, therefore, hyp has no sanitized
-	 * copy of the feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64ZFR0_ALLOW != 0ULL);
-	return 0;
-}
-
-static u64 get_pvm_id_aa64dfr0(const struct kvm_vcpu *vcpu)
-{
-	/*
-	 * No support for debug, including breakpoints, and watchpoints,
-	 * therefore, pKVM has no sanitized copy of the feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64DFR0_ALLOW != 0ULL);
-	return 0;
-}
-
-static u64 get_pvm_id_aa64dfr1(const struct kvm_vcpu *vcpu)
-{
-	/*
-	 * No support for debug, therefore, hyp has no sanitized copy of the
-	 * feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64DFR1_ALLOW != 0ULL);
-	return 0;
-}
+	if (!IS_ENABLED(CONFIG_ARM64_PTR_AUTH))
+		return false;
 
-static u64 get_pvm_id_aa64afr0(const struct kvm_vcpu *vcpu)
-{
-	/*
-	 * No support for implementation defined features, therefore, hyp has no
-	 * sanitized copy of the feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64AFR0_ALLOW != 0ULL);
-	return 0;
+	return (cpus_have_final_cap(ARM64_HAS_ADDRESS_AUTH) ||
+		cpus_have_final_cap(ARM64_HAS_GENERIC_AUTH)) &&
+		kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_PTRAUTH_GENERIC);
 }
 
-static u64 get_pvm_id_aa64afr1(const struct kvm_vcpu *vcpu)
+static bool vm_has_sve(const struct kvm *kvm)
 {
-	/*
-	 * No support for implementation defined features, therefore, hyp has no
-	 * sanitized copy of the feature id register.
-	 */
-	BUILD_BUG_ON(PVM_ID_AA64AFR1_ALLOW != 0ULL);
-	return 0;
+	return system_supports_sve() && kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_SVE);
 }
 
-static u64 get_pvm_id_aa64isar0(const struct kvm_vcpu *vcpu)
-{
-	return id_aa64isar0_el1_sys_val & PVM_ID_AA64ISAR0_ALLOW;
-}
+/*
+ * Definitions for features to be allowed or restricted for protected guests.
+ *
+ * Each field in the masks represents the highest supported value for the
+ * feature. If a feature field is not present, it is not supported. Moreover,
+ * these are used to generate the guest's view of the feature registers.
+ *
+ * The approach for protected VMs is to at least support features that are:
+ * - Needed by common Linux distributions (e.g., floating point)
+ * - Trivial to support, e.g., supporting the feature does not introduce or
+ * require tracking of additional state in KVM
+ * - Cannot be trapped or prevent the guest from using anyway
+ */
 
-static u64 get_pvm_id_aa64isar1(const struct kvm_vcpu *vcpu)
-{
-	u64 allow_mask = PVM_ID_AA64ISAR1_ALLOW;
+static const struct pvm_ftr_bits pvmid_aa64pfr0[] = {
+	MAX_FEAT(ID_AA64PFR0_EL1, EL0, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, EL1, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, EL2, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, EL3, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, FP, FP16),
+	MAX_FEAT(ID_AA64PFR0_EL1, AdvSIMD, FP16),
+	MAX_FEAT(ID_AA64PFR0_EL1, GIC, IMP),
+	MAX_FEAT_FUNC(ID_AA64PFR0_EL1, SVE, IMP, vm_has_sve),
+	MAX_FEAT(ID_AA64PFR0_EL1, RAS, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, DIT, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, CSV2, IMP),
+	MAX_FEAT(ID_AA64PFR0_EL1, CSV3, IMP),
+	FEAT_END
+};
 
-	if (!vcpu_has_ptrauth(vcpu))
-		allow_mask &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA) |
-				ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API) |
-				ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA) |
-				ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI));
+static const struct pvm_ftr_bits pvmid_aa64pfr1[] = {
+	MAX_FEAT(ID_AA64PFR1_EL1, BT, IMP),
+	MAX_FEAT(ID_AA64PFR1_EL1, SSBS, SSBS2),
+	MAX_FEAT_ENUM(ID_AA64PFR1_EL1, MTE_frac, NI),
+	FEAT_END
+};
 
-	return id_aa64isar1_el1_sys_val & allow_mask;
-}
+static const struct pvm_ftr_bits pvmid_aa64mmfr0[] = {
+	MAX_FEAT_ENUM(ID_AA64MMFR0_EL1, PARANGE, 40),
+	MAX_FEAT_ENUM(ID_AA64MMFR0_EL1, ASIDBITS, 16),
+	MAX_FEAT(ID_AA64MMFR0_EL1, BIGEND, IMP),
+	MAX_FEAT(ID_AA64MMFR0_EL1, SNSMEM, IMP),
+	MAX_FEAT(ID_AA64MMFR0_EL1, BIGENDEL0, IMP),
+	MAX_FEAT(ID_AA64MMFR0_EL1, EXS, IMP),
+	FEAT_END
+};
 
-static u64 get_pvm_id_aa64isar2(const struct kvm_vcpu *vcpu)
-{
-	u64 allow_mask = PVM_ID_AA64ISAR2_ALLOW;
+static const struct pvm_ftr_bits pvmid_aa64mmfr1[] = {
+	MAX_FEAT(ID_AA64MMFR1_EL1, HAFDBS, DBM),
+	MAX_FEAT_ENUM(ID_AA64MMFR1_EL1, VMIDBits, 16),
+	MAX_FEAT(ID_AA64MMFR1_EL1, HPDS, HPDS2),
+	MAX_FEAT(ID_AA64MMFR1_EL1, PAN, PAN3),
+	MAX_FEAT(ID_AA64MMFR1_EL1, SpecSEI, IMP),
+	MAX_FEAT(ID_AA64MMFR1_EL1, ETS, IMP),
+	MAX_FEAT(ID_AA64MMFR1_EL1, CMOW, IMP),
+	FEAT_END
+};
 
-	if (!vcpu_has_ptrauth(vcpu))
-		allow_mask &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3) |
-				ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3));
+static const struct pvm_ftr_bits pvmid_aa64mmfr2[] = {
+	MAX_FEAT(ID_AA64MMFR2_EL1, CnP, IMP),
+	MAX_FEAT(ID_AA64MMFR2_EL1, UAO, IMP),
+	MAX_FEAT(ID_AA64MMFR2_EL1, IESB, IMP),
+	MAX_FEAT(ID_AA64MMFR2_EL1, AT, IMP),
+	MAX_FEAT_ENUM(ID_AA64MMFR2_EL1, IDS, 0x18),
+	MAX_FEAT(ID_AA64MMFR2_EL1, TTL, IMP),
+	MAX_FEAT(ID_AA64MMFR2_EL1, BBM, 2),
+	MAX_FEAT(ID_AA64MMFR2_EL1, E0PD, IMP),
+	FEAT_END
+};
 
-	return id_aa64isar2_el1_sys_val & allow_mask;
-}
+static const struct pvm_ftr_bits pvmid_aa64isar1[] = {
+	MAX_FEAT(ID_AA64ISAR1_EL1, DPB, DPB2),
+	MAX_FEAT_FUNC(ID_AA64ISAR1_EL1, APA, PAuth, vm_has_ptrauth),
+	MAX_FEAT_FUNC(ID_AA64ISAR1_EL1, API, PAuth, vm_has_ptrauth),
+	MAX_FEAT(ID_AA64ISAR1_EL1, JSCVT, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, FCMA, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, LRCPC, LRCPC3),
+	MAX_FEAT(ID_AA64ISAR1_EL1, GPA, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, GPI, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, FRINTTS, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, SB, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, SPECRES, COSP_RCTX),
+	MAX_FEAT(ID_AA64ISAR1_EL1, BF16, EBF16),
+	MAX_FEAT(ID_AA64ISAR1_EL1, DGH, IMP),
+	MAX_FEAT(ID_AA64ISAR1_EL1, I8MM, IMP),
+	FEAT_END
+};
 
-static u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu)
-{
-	u64 set_mask;
+static const struct pvm_ftr_bits pvmid_aa64isar2[] = {
+	MAX_FEAT_FUNC(ID_AA64ISAR2_EL1, GPA3, IMP, vm_has_ptrauth),
+	MAX_FEAT_FUNC(ID_AA64ISAR2_EL1, APA3, PAuth, vm_has_ptrauth),
+	MAX_FEAT(ID_AA64ISAR2_EL1, ATS1A, IMP),
+	FEAT_END
+};
 
-	set_mask = get_restricted_features_unsigned(id_aa64mmfr0_el1_sys_val,
-		PVM_ID_AA64MMFR0_ALLOW);
+/*
+ * None of the features in ID_AA64DFR0_EL1 nor ID_AA64MMFR4_EL1 are supported.
+ * However, both have Not-Implemented values that are non-zero. Define them
+ * so they can be used when getting the value of these registers.
+ */
+#define ID_AA64DFR0_EL1_NONZERO_NI					\
+(									\
+	SYS_FIELD_PREP_ENUM(ID_AA64DFR0_EL1, DoubleLock, NI)	|	\
+	SYS_FIELD_PREP_ENUM(ID_AA64DFR0_EL1, MTPMU, NI)			\
+)
 
-	return (id_aa64mmfr0_el1_sys_val & PVM_ID_AA64MMFR0_ALLOW) | set_mask;
-}
+#define ID_AA64MMFR4_EL1_NONZERO_NI					\
+	SYS_FIELD_PREP_ENUM(ID_AA64MMFR4_EL1, E2H0, NI)
 
-static u64 get_pvm_id_aa64mmfr1(const struct kvm_vcpu *vcpu)
+/*
+ * Returns the value of the feature registers based on the system register
+ * value, the vcpu support for the revelant features, and the additional
+ * restrictions for protected VMs.
+ */
+static u64 get_restricted_features(const struct kvm_vcpu *vcpu,
+				   u64 sys_reg_val,
+				   const struct pvm_ftr_bits restrictions[])
 {
-	return id_aa64mmfr1_el1_sys_val & PVM_ID_AA64MMFR1_ALLOW;
-}
+	u64 val = 0UL;
+	int i;
+
+	for (i = 0; restrictions[i].width != 0; i++) {
+		bool (*vm_supported)(const struct kvm *) = restrictions[i].vm_supported;
+		bool sign = restrictions[i].sign;
+		int shift = restrictions[i].shift;
+		int width = restrictions[i].width;
+		u64 min_signed = (1UL << width) - 1UL;
+		u64 sign_bit = 1UL << (width - 1);
+		u64 mask = GENMASK_ULL(width + shift - 1, shift);
+		u64 sys_val = (sys_reg_val & mask) >> shift;
+		u64 pvm_max = restrictions[i].max_val;
+
+		if (vm_supported && !vm_supported(vcpu->kvm))
+			val |= (sign ? min_signed : 0) << shift;
+		else if (sign && (sys_val >= sign_bit || pvm_max >= sign_bit))
+			val |= max(sys_val, pvm_max) << shift;
+		else
+			val |= min(sys_val, pvm_max) << shift;
+	}
 
-static u64 get_pvm_id_aa64mmfr2(const struct kvm_vcpu *vcpu)
-{
-	return id_aa64mmfr2_el1_sys_val & PVM_ID_AA64MMFR2_ALLOW;
+	return val;
 }
 
 static u64 pvm_calc_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 {
 	switch (id) {
 	case SYS_ID_AA64PFR0_EL1:
-		return get_pvm_id_aa64pfr0(vcpu);
+		return get_restricted_features(vcpu, id_aa64pfr0_el1_sys_val, pvmid_aa64pfr0);
 	case SYS_ID_AA64PFR1_EL1:
-		return get_pvm_id_aa64pfr1(vcpu);
-	case SYS_ID_AA64ZFR0_EL1:
-		return get_pvm_id_aa64zfr0(vcpu);
-	case SYS_ID_AA64DFR0_EL1:
-		return get_pvm_id_aa64dfr0(vcpu);
-	case SYS_ID_AA64DFR1_EL1:
-		return get_pvm_id_aa64dfr1(vcpu);
-	case SYS_ID_AA64AFR0_EL1:
-		return get_pvm_id_aa64afr0(vcpu);
-	case SYS_ID_AA64AFR1_EL1:
-		return get_pvm_id_aa64afr1(vcpu);
+		return get_restricted_features(vcpu, id_aa64pfr1_el1_sys_val, pvmid_aa64pfr1);
 	case SYS_ID_AA64ISAR0_EL1:
-		return get_pvm_id_aa64isar0(vcpu);
+		return id_aa64isar0_el1_sys_val;
 	case SYS_ID_AA64ISAR1_EL1:
-		return get_pvm_id_aa64isar1(vcpu);
+		return get_restricted_features(vcpu, id_aa64isar1_el1_sys_val, pvmid_aa64isar1);
 	case SYS_ID_AA64ISAR2_EL1:
-		return get_pvm_id_aa64isar2(vcpu);
+		return get_restricted_features(vcpu, id_aa64isar2_el1_sys_val, pvmid_aa64isar2);
 	case SYS_ID_AA64MMFR0_EL1:
-		return get_pvm_id_aa64mmfr0(vcpu);
+		return get_restricted_features(vcpu, id_aa64mmfr0_el1_sys_val, pvmid_aa64mmfr0);
 	case SYS_ID_AA64MMFR1_EL1:
-		return get_pvm_id_aa64mmfr1(vcpu);
+		return get_restricted_features(vcpu, id_aa64mmfr1_el1_sys_val, pvmid_aa64mmfr1);
 	case SYS_ID_AA64MMFR2_EL1:
-		return get_pvm_id_aa64mmfr2(vcpu);
+		return get_restricted_features(vcpu, id_aa64mmfr2_el1_sys_val, pvmid_aa64mmfr2);
+	case SYS_ID_AA64DFR0_EL1:
+		return ID_AA64DFR0_EL1_NONZERO_NI;
+	case SYS_ID_AA64MMFR4_EL1:
+		return ID_AA64MMFR4_EL1_NONZERO_NI;
 	default:
 		/* Unhandled ID register, RAZ */
 		return 0;
 	}
 }
 
-/* Read a sanitized cpufeature ID register by its encoding */
-u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
+/*
+ * Inject an unknown/undefined exception to an AArch64 guest while most of its
+ * sysregs are live.
+ */
+static void inject_undef64(struct kvm_vcpu *vcpu)
 {
-	return pvm_calc_id_reg(vcpu, id);
+	u64 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
+
+	*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
+	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
+
+	kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
+
+	__kvm_adjust_pc(vcpu);
+
+	write_sysreg_el1(esr, SYS_ESR);
+	write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
+	write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
+	write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
 }
 
 static u64 read_id_reg(const struct kvm_vcpu *vcpu,
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:50 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:50 +0000
Subject: [PATCH v5 10/17] KVM: arm64: Remove fixed_config.h header
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-11-tabba@google.com>

The few remaining items needed in fixed_config.h are better
suited for pkvm.h. Move them there and delete it.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h | 206 ------------------
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |   5 +
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |   1 -
 arch/arm64/kvm/hyp/nvhe/setup.c               |   1 -
 arch/arm64/kvm/hyp/nvhe/switch.c              |   1 -
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            |   2 +-
 6 files changed, 6 insertions(+), 210 deletions(-)
 delete mode 100644 arch/arm64/kvm/hyp/include/nvhe/fixed_config.h

diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
deleted file mode 100644
index 37a6d2434e47..000000000000
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2021 Google LLC
- * Author: Fuad Tabba <tabba at google.com>
- */
-
-#ifndef __ARM64_KVM_FIXED_CONFIG_H__
-#define __ARM64_KVM_FIXED_CONFIG_H__
-
-#include <asm/sysreg.h>
-
-/*
- * This file contains definitions for features to be allowed or restricted for
- * guest virtual machines, depending on the mode KVM is running in and on the
- * type of guest that is running.
- *
- * Each field in the masks represents the highest supported *unsigned* value for
- * the feature, if supported by the system.
- *
- * If a feature field is not present in either, than it is not supported.
- *
- * The approach taken for protected VMs is to allow features that are:
- * - Needed by common Linux distributions (e.g., floating point)
- * - Trivial to support, e.g., supporting the feature does not introduce or
- * require tracking of additional state in KVM
- * - Cannot be trapped or prevent the guest from using anyway
- */
-
-/*
- * Allow for protected VMs:
- * - Floating-point and Advanced SIMD
- * - Data Independent Timing
- * - Spectre/Meltdown Mitigation
- *
- * Restrict to the following *unsigned* features for protected VMs:
- * - AArch64 guests only (no support for AArch32 guests):
- *	AArch32 adds complexity in trap handling, emulation, condition codes,
- *	etc...
- * - RAS (v1)
- *	Supported by KVM
- */
-#define PVM_ID_AA64PFR0_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL0, IMP) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL1, IMP) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL2, IMP) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL3, IMP) | \
-	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, RAS, IMP) \
-	)
-
-/*
- * Allow for protected VMs:
- * - Branch Target Identification
- * - Speculative Store Bypassing
- */
-#define PVM_ID_AA64PFR1_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_BT) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SSBS) \
-	)
-
-#define PVM_ID_AA64PFR2_ALLOW 0ULL
-
-/*
- * Allow for protected VMs:
- * - Mixed-endian
- * - Distinction between Secure and Non-secure Memory
- * - Mixed-endian at EL0 only
- * - Non-context synchronizing exception entry and exit
- *
- * Restrict to the following *unsigned* features for protected VMs:
- * - 40-bit IPA
- * - 16-bit ASID
- */
-#define PVM_ID_AA64MMFR0_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGEND) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_SNSMEM) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGENDEL0) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_PARANGE), ID_AA64MMFR0_EL1_PARANGE_40) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_ASIDBITS), ID_AA64MMFR0_EL1_ASIDBITS_16) \
-	)
-
-/*
- * Allow for protected VMs:
- * - Hardware translation table updates to Access flag and Dirty state
- * - Number of VMID bits from CPU
- * - Hierarchical Permission Disables
- * - Privileged Access Never
- * - SError interrupt exceptions from speculative reads
- * - Enhanced Translation Synchronization
- * - Control for cache maintenance permission
- */
-#define PVM_ID_AA64MMFR1_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_HAFDBS) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_VMIDBits) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_HPDS) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_PAN) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_SpecSEI) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_ETS) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_CMOW) \
-	)
-
-/*
- * Allow for protected VMs:
- * - Common not Private translations
- * - User Access Override
- * - IESB bit in the SCTLR_ELx registers
- * - Unaligned single-copy atomicity and atomic functions
- * - ESR_ELx.EC value on an exception by read access to feature ID space
- * - TTL field in address operations.
- * - Break-before-make sequences when changing translation block size
- * - E0PDx mechanism
- */
-#define PVM_ID_AA64MMFR2_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_CnP) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_UAO) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_IESB) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_AT) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_IDS) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_TTL) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_BBM) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR2_EL1_E0PD) \
-	)
-
-#define PVM_ID_AA64MMFR3_ALLOW (0ULL)
-
-/*
- * No support for Scalable Vectors for protected VMs:
- *	Requires additional support from KVM, e.g., context-switching and
- *	trapping at EL2
- */
-#define PVM_ID_AA64ZFR0_ALLOW (0ULL)
-
-/*
- * No support for debug, including breakpoints, and watchpoints for protected
- * VMs:
- *	The Arm architecture mandates support for at least the Armv8 debug
- *	architecture, which would include at least 2 hardware breakpoints and
- *	watchpoints. Providing that support to protected guests adds
- *	considerable state and complexity. Therefore, the reserved value of 0 is
- *	used for debug-related fields.
- */
-#define PVM_ID_AA64DFR0_ALLOW (0ULL)
-#define PVM_ID_AA64DFR1_ALLOW (0ULL)
-
-/*
- * No support for implementation defined features.
- */
-#define PVM_ID_AA64AFR0_ALLOW (0ULL)
-#define PVM_ID_AA64AFR1_ALLOW (0ULL)
-
-/*
- * No restrictions on instructions implemented in AArch64.
- */
-#define PVM_ID_AA64ISAR0_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_AES) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SHA1) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SHA2) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_CRC32) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_ATOMIC) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_RDM) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SHA3) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SM3) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_SM4) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_DP) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_FHM) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_TS) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_TLB) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR0_EL1_RNDR) \
-	)
-
-/* Restrict pointer authentication to the basic version. */
-#define PVM_ID_AA64ISAR1_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DPB) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_JSCVT) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_FCMA) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_LRCPC) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_FRINTTS) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_SB) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_SPECRES) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_BF16) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DGH) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_I8MM) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), ID_AA64ISAR1_EL1_APA_PAuth) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), ID_AA64ISAR1_EL1_API_PAuth) \
-	)
-
-#define PVM_ID_AA64ISAR2_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_ATS1A)| \
-	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_MOPS) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
-	)
-
-bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
-bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
-void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu);
-int kvm_check_pvm_sysreg_table(void);
-
-#endif /* __ARM64_KVM_FIXED_CONFIG_H__ */
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 698bc20ab80b..3888aabd78f3 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -72,4 +72,9 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 					 unsigned int vcpu_idx);
 void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
 
+bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
+bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
+void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu);
+int kvm_check_pvm_sysreg_table(void);
+
 #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 2aa349fc42b8..add0502f888f 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -9,7 +9,6 @@
 
 #include <asm/kvm_emulate.h>
 
-#include <nvhe/fixed_config.h>
 #include <nvhe/mem_protect.h>
 #include <nvhe/memory.h>
 #include <nvhe/pkvm.h>
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index cbdd18cd3f98..31bd729ea45c 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -12,7 +12,6 @@
 
 #include <nvhe/early_alloc.h>
 #include <nvhe/ffa.h>
-#include <nvhe/fixed_config.h>
 #include <nvhe/gfp.h>
 #include <nvhe/memory.h>
 #include <nvhe/mem_protect.h>
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index cc69106734ca..7786a83d0fa8 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -26,7 +26,6 @@
 #include <asm/debug-monitors.h>
 #include <asm/processor.h>
 
-#include <nvhe/fixed_config.h>
 #include <nvhe/mem_protect.h>
 
 /* Non-VHE specific context */
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 289f370d386a..1ddd9ed3cbb3 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -11,7 +11,7 @@
 
 #include <hyp/adjust_pc.h>
 
-#include <nvhe/fixed_config.h>
+#include <nvhe/pkvm.h>
 
 #include "../../sys_regs.h"
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:51 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:51 +0000
Subject: [PATCH v5 11/17] KVM: arm64: Remove redundant setting of HCR_EL2 trap bit
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-12-tabba@google.com>

In hVHE mode, HCR_E2H should be set for both protected and
non-protected VMs. Since commit b56680de9c64 ("KVM: arm64:
Initialize trap register values in hyp in pKVM"), this has been
fixed, and the setting of the flag here is redundant.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index add0502f888f..21864d101230 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -57,9 +57,6 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 	/* No support for AArch32. */
 	val |= HCR_RW;
 
-	if (has_hvhe())
-		val |= HCR_E2H;
-
 	/*
 	 * Always trap:
 	 * - Feature id registers: to control features exposed to guests
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:52 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:52 +0000
Subject: [PATCH v5 12/17] KVM: arm64: Calculate cptr_el2 traps on activating traps
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-13-tabba@google.com>

Similar to VHE, calculate the value of cptr_el2 from scratch on
activate traps. This removes the need to store cptr_el2 in every
vcpu structure. Moreover, some traps, such as whether the guest
owns the fp registers, need to be set on every vcpu run.

Reported-by: James Clark <james.clark at linaro.org>
Fixes: 5294afdbf45a ("KVM: arm64: Exclude FP ownership from kvm_vcpu_arch")
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  1 -
 arch/arm64/kvm/arm.c              |  1 -
 arch/arm64/kvm/hyp/nvhe/pkvm.c    | 42 -------------------------
 arch/arm64/kvm/hyp/nvhe/switch.c  | 51 +++++++++++++++++++------------
 4 files changed, 32 insertions(+), 63 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 230b0638f0c2..69cb88c9ce3e 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -708,7 +708,6 @@ struct kvm_vcpu_arch {
 	u64 hcr_el2;
 	u64 hcrx_el2;
 	u64 mdcr_el2;
-	u64 cptr_el2;
 
 	/* Exception Information */
 	struct kvm_vcpu_fault_info fault;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index b295218cdc24..8a3d02cf0a7a 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1546,7 +1546,6 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
 	}
 
 	vcpu_reset_hcr(vcpu);
-	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
 
 	/*
 	 * Handle the "start in power-off" case.
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 21864d101230..956385ee4aa2 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -83,44 +83,6 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 	vcpu->arch.hcr_el2 = val;
 }
 
-static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
-{
-	struct kvm *kvm = vcpu->kvm;
-	u64 val = vcpu->arch.cptr_el2;
-
-	if (!has_hvhe()) {
-		val |= CPTR_NVHE_EL2_RES1;
-		val &= ~(CPTR_NVHE_EL2_RES0);
-	}
-
-	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
-		val |= CPTR_EL2_TAM;
-
-	/* SVE can be disabled by userspace even if supported. */
-	if (!vcpu_has_sve(vcpu)) {
-		if (has_hvhe())
-			val &= ~(CPACR_ELx_ZEN);
-		else
-			val |= CPTR_EL2_TZ;
-	}
-
-	/* No SME support in KVM. */
-	BUG_ON(kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP));
-	if (has_hvhe())
-		val &= ~(CPACR_ELx_SMEN);
-	else
-		val |= CPTR_EL2_TSM;
-
-	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP)) {
-		if (has_hvhe())
-			val |= CPACR_EL1_TTA;
-		else
-			val |= CPTR_EL2_TTA;
-	}
-
-	vcpu->arch.cptr_el2 = val;
-}
-
 static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 {
 	struct kvm *kvm = vcpu->kvm;
@@ -191,7 +153,6 @@ static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
 	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
 	int ret;
 
-	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
 	vcpu->arch.mdcr_el2 = 0;
 
 	pkvm_vcpu_reset_hcr(vcpu);
@@ -204,7 +165,6 @@ static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
 		return ret;
 
 	pvm_init_traps_hcr(vcpu);
-	pvm_init_traps_cptr(vcpu);
 	pvm_init_traps_mdcr(vcpu);
 
 	return 0;
@@ -644,8 +604,6 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
 		return ret;
 	}
 
-	hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu);
-
 	return 0;
 }
 
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 7786a83d0fa8..0ebf84a9f9e2 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -35,33 +35,46 @@ DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
 
 extern void kvm_nvhe_prepare_backtrace(unsigned long fp, unsigned long pc);
 
-static void __activate_traps(struct kvm_vcpu *vcpu)
+static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
 {
-	u64 val;
+	u64 val = CPTR_EL2_TAM;	/* Same bit irrespective of E2H */
 
-	___activate_traps(vcpu, vcpu->arch.hcr_el2);
-	__activate_traps_common(vcpu);
+	if (has_hvhe()) {
+		val |= CPACR_ELx_TTA;
 
-	val = vcpu->arch.cptr_el2;
-	val |= CPTR_EL2_TAM;	/* Same bit irrespective of E2H */
-	val |= has_hvhe() ? CPACR_EL1_TTA : CPTR_EL2_TTA;
-	if (cpus_have_final_cap(ARM64_SME)) {
-		if (has_hvhe())
-			val &= ~CPACR_ELx_SMEN;
-		else
-			val |= CPTR_EL2_TSM;
-	}
+		if (guest_owns_fp_regs()) {
+			val |= CPACR_ELx_FPEN;
+			if (vcpu_has_sve(vcpu))
+				val |= CPACR_ELx_ZEN;
+		}
+	} else {
+		val |= CPTR_EL2_TTA | CPTR_NVHE_EL2_RES1;
 
-	if (!guest_owns_fp_regs()) {
-		if (has_hvhe())
-			val &= ~(CPACR_ELx_FPEN | CPACR_ELx_ZEN);
-		else
-			val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
+		/*
+		 * Always trap SME since it's not supported in KVM.
+		 * TSM is RES1 if SME isn't implemented.
+		 */
+		val |= CPTR_EL2_TSM;
 
-		__activate_traps_fpsimd32(vcpu);
+		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
+			val |= CPTR_EL2_TZ;
+
+		if (!guest_owns_fp_regs())
+			val |= CPTR_EL2_TFP;
 	}
 
+	if (!guest_owns_fp_regs())
+		__activate_traps_fpsimd32(vcpu);
+
 	kvm_write_cptr_el2(val);
+}
+
+static void __activate_traps(struct kvm_vcpu *vcpu)
+{
+	___activate_traps(vcpu, vcpu->arch.hcr_el2);
+	__activate_traps_common(vcpu);
+	__activate_cptr_traps(vcpu);
+
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
 
 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:53 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:53 +0000
Subject: [PATCH v5 13/17] KVM: arm64: Refactor kvm_reset_cptr_el2()
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-14-tabba@google.com>

Fold kvm_get_reset_cptr_el2() into kvm_reset_cptr_el2(), since it
is its only caller. Add a comment to clarify that this function
is meant for the host value of cptr_el2.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_emulate.h | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index cf811009a33c..7b3dc52248ce 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -619,7 +619,8 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
 		write_sysreg(val, cptr_el2);
 }
 
-static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
+/* Resets the value of cptr_el2 when returning to the host. */
+static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
 {
 	u64 val;
 
@@ -643,13 +644,6 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
 			val &= ~CPTR_EL2_TSM;
 	}
 
-	return val;
-}
-
-static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
-{
-	u64 val = kvm_get_reset_cptr_el2(vcpu);
-
 	kvm_write_cptr_el2(val);
 }
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:54 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:54 +0000
Subject: [PATCH v5 14/17] KVM: arm64: Fix the value of the CPTR_EL2 RES1
 bitmask for nVHE
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-15-tabba@google.com>

Since the introduction of SME, bit 12 in CPTR_EL2 (nVHE) is TSM
for trapping SME, instead of RES1, as per ARM ARM DDI 0487K.a,
section D23.2.34.

Fix the value of CPTR_NVHE_EL2_RES1 to reflect that, and adjust
the code that relies on it accordingly.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_arm.h     | 2 +-
 arch/arm64/include/asm/kvm_emulate.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3e0f0de1d2da..24e4ac7c50f2 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -300,7 +300,7 @@
 #define CPTR_EL2_TSM	(1 << 12)
 #define CPTR_EL2_TFP	(1 << CPTR_EL2_TFP_SHIFT)
 #define CPTR_EL2_TZ	(1 << 8)
-#define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
+#define CPTR_NVHE_EL2_RES1	(BIT(13) | BIT(9) | GENMASK(7, 0))
 #define CPTR_NVHE_EL2_RES0	(GENMASK(63, 32) |	\
 				 GENMASK(29, 21) |	\
 				 GENMASK(19, 14) |	\
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 7b3dc52248ce..6602a4c091ac 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -640,8 +640,8 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
 
 		if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
 			val |= CPTR_EL2_TZ;
-		if (cpus_have_final_cap(ARM64_SME))
-			val &= ~CPTR_EL2_TSM;
+		if (!cpus_have_final_cap(ARM64_SME))
+			val |= CPTR_EL2_TSM;
 	}
 
 	kvm_write_cptr_el2(val);
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:55 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:55 +0000
Subject: [PATCH v5 15/17] KVM: arm64: Remove PtrAuth guest vcpu flag
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-16-tabba@google.com>

The vcpu flag GUEST_HAS_PTRAUTH is always associated with the
vcpu PtrAuth features, which are defined per vm rather than per
vcpu.

Remove the flag, and replace it with checks for the features
instead.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_emulate.h |  5 -----
 arch/arm64/include/asm/kvm_host.h    |  7 +++----
 arch/arm64/kvm/hyp/nvhe/pkvm.c       | 13 -------------
 arch/arm64/kvm/reset.c               |  4 ----
 4 files changed, 3 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 6602a4c091ac..406e99a452bf 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -691,9 +691,4 @@ static inline bool guest_hyp_sve_traps_enabled(const struct kvm_vcpu *vcpu)
 {
 	return __guest_hyp_cptr_xen_trap_enabled(vcpu, ZEN);
 }
-
-static inline void kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
-{
-	vcpu_set_flag(vcpu, GUEST_HAS_PTRAUTH);
-}
 #endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 69cb88c9ce3e..e6be8fe6627a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -866,10 +866,8 @@ struct kvm_vcpu_arch {
 #define GUEST_HAS_SVE		__vcpu_single_flag(cflags, BIT(0))
 /* SVE config completed */
 #define VCPU_SVE_FINALIZED	__vcpu_single_flag(cflags, BIT(1))
-/* PTRAUTH exposed to guest */
-#define GUEST_HAS_PTRAUTH	__vcpu_single_flag(cflags, BIT(2))
 /* KVM_ARM_VCPU_INIT completed */
-#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(3))
+#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(2))
 
 /* Exception pending */
 #define PENDING_EXCEPTION	__vcpu_single_flag(iflags, BIT(0))
@@ -965,7 +963,8 @@ struct kvm_vcpu_arch {
 #define vcpu_has_ptrauth(vcpu)						\
 	((cpus_have_final_cap(ARM64_HAS_ADDRESS_AUTH) ||		\
 	  cpus_have_final_cap(ARM64_HAS_GENERIC_AUTH)) &&		\
-	  vcpu_get_flag(vcpu, GUEST_HAS_PTRAUTH))
+	 (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_ADDRESS) ||       \
+	  vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_GENERIC)))
 #else
 #define vcpu_has_ptrauth(vcpu)		false
 #endif
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 956385ee4aa2..b399d69b4b67 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -278,18 +278,6 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 		   allowed_features, KVM_VCPU_MAX_FEATURES);
 }
 
-static void pkvm_vcpu_init_ptrauth(struct pkvm_hyp_vcpu *hyp_vcpu)
-{
-	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
-
-	if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_ADDRESS) ||
-	    vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_GENERIC)) {
-		kvm_vcpu_enable_ptrauth(vcpu);
-	} else {
-		vcpu_clear_flag(&hyp_vcpu->vcpu, GUEST_HAS_PTRAUTH);
-	}
-}
-
 static void unpin_host_vcpu(struct kvm_vcpu *host_vcpu)
 {
 	if (host_vcpu)
@@ -359,7 +347,6 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
 		goto done;
 
 	pkvm_vcpu_init_sve(hyp_vcpu, host_vcpu);
-	pkvm_vcpu_init_ptrauth(hyp_vcpu);
 done:
 	if (ret)
 		unpin_host_vcpu(host_vcpu);
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 470524b31951..1cfab6a5d8a5 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -211,10 +211,6 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 		kvm_vcpu_reset_sve(vcpu);
 	}
 
-	if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_ADDRESS) ||
-	    vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_GENERIC))
-		kvm_vcpu_enable_ptrauth(vcpu);
-
 	if (vcpu_el1_is_32bit(vcpu))
 		pstate = VCPU_RESET_PSTATE_SVC;
 	else if (vcpu_has_nv(vcpu))
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:56 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:56 +0000
Subject: [PATCH v5 16/17] KVM: arm64: Convert the SVE guest vcpu flag to a vm flag
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-17-tabba@google.com>

The vcpu flag GUEST_HAS_SVE is per-vcpu, but it is based on what
is now a per-vm feature. Make the flag per-vm.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_emulate.h | 12 +++++++++---
 arch/arm64/include/asm/kvm_host.h    | 18 ++++++++++++------
 arch/arm64/kvm/hyp/nvhe/pkvm.c       | 11 +++++++----
 arch/arm64/kvm/reset.c               |  2 +-
 4 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 406e99a452bf..2d91fb88298a 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -620,7 +620,7 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
 }
 
 /* Resets the value of cptr_el2 when returning to the host. */
-static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
+static __always_inline void __kvm_reset_cptr_el2(struct kvm *kvm)
 {
 	u64 val;
 
@@ -631,14 +631,14 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
 	} else if (has_hvhe()) {
 		val = CPACR_ELx_FPEN;
 
-		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
+		if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
 			val |= CPACR_ELx_ZEN;
 		if (cpus_have_final_cap(ARM64_SME))
 			val |= CPACR_ELx_SMEN;
 	} else {
 		val = CPTR_NVHE_EL2_RES1;
 
-		if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
+		if (kvm_has_sve(kvm) && guest_owns_fp_regs())
 			val |= CPTR_EL2_TZ;
 		if (!cpus_have_final_cap(ARM64_SME))
 			val |= CPTR_EL2_TSM;
@@ -647,6 +647,12 @@ static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
 	kvm_write_cptr_el2(val);
 }
 
+#ifdef __KVM_NVHE_HYPERVISOR__
+#define kvm_reset_cptr_el2(v)	__kvm_reset_cptr_el2(kern_hyp_va((v)->kvm))
+#else
+#define kvm_reset_cptr_el2(v)	__kvm_reset_cptr_el2((v)->kvm)
+#endif
+
 /*
  * Returns a 'sanitised' view of CPTR_EL2, translating from nVHE to the VHE
  * format if E2H isn't set.
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e6be8fe6627a..c834b6768247 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -331,6 +331,8 @@ struct kvm_arch {
 #define KVM_ARCH_FLAG_ID_REGS_INITIALIZED		7
 	/* Fine-Grained UNDEF initialised */
 #define KVM_ARCH_FLAG_FGU_INITIALIZED			8
+	/* SVE exposed to guest */
+#define KVM_ARCH_FLAG_GUEST_HAS_SVE			9
 	unsigned long flags;
 
 	/* VM-wide vCPU feature set */
@@ -862,12 +864,10 @@ struct kvm_vcpu_arch {
 #define vcpu_set_flag(v, ...)	__vcpu_set_flag((v), __VA_ARGS__)
 #define vcpu_clear_flag(v, ...)	__vcpu_clear_flag((v), __VA_ARGS__)
 
-/* SVE exposed to guest */
-#define GUEST_HAS_SVE		__vcpu_single_flag(cflags, BIT(0))
+/* KVM_ARM_VCPU_INIT completed */
+#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(0))
 /* SVE config completed */
 #define VCPU_SVE_FINALIZED	__vcpu_single_flag(cflags, BIT(1))
-/* KVM_ARM_VCPU_INIT completed */
-#define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(2))
 
 /* Exception pending */
 #define PENDING_EXCEPTION	__vcpu_single_flag(iflags, BIT(0))
@@ -956,8 +956,14 @@ struct kvm_vcpu_arch {
 				 KVM_GUESTDBG_USE_HW | \
 				 KVM_GUESTDBG_SINGLESTEP)
 
-#define vcpu_has_sve(vcpu) (system_supports_sve() &&			\
-			    vcpu_get_flag(vcpu, GUEST_HAS_SVE))
+#define kvm_has_sve(kvm)	(system_supports_sve() &&		\
+				 test_bit(KVM_ARCH_FLAG_GUEST_HAS_SVE, &(kvm)->arch.flags))
+
+#ifdef __KVM_NVHE_HYPERVISOR__
+#define vcpu_has_sve(vcpu)	kvm_has_sve(kern_hyp_va((vcpu)->kvm))
+#else
+#define vcpu_has_sve(vcpu)	kvm_has_sve((vcpu)->kvm)
+#endif
 
 #ifdef CONFIG_ARM64_PTR_AUTH
 #define vcpu_has_ptrauth(vcpu)						\
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index b399d69b4b67..446a9114b0d3 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -248,10 +248,13 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
 {
 	struct kvm *kvm = &hyp_vm->kvm;
+	unsigned long host_arch_flags = READ_ONCE(host_kvm->arch.flags);
 	DECLARE_BITMAP(allowed_features, KVM_VCPU_MAX_FEATURES);
 
 	/* No restrictions for non-protected VMs. */
 	if (!kvm_vm_is_protected(kvm)) {
+		hyp_vm->kvm.arch.flags = host_arch_flags;
+
 		bitmap_copy(kvm->arch.vcpu_features,
 			    host_kvm->arch.vcpu_features,
 			    KVM_VCPU_MAX_FEATURES);
@@ -271,8 +274,10 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_GENERIC))
 		set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
 
-	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE))
+	if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE)) {
 		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
+		kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_GUEST_HAS_SVE);
+	}
 
 	bitmap_and(kvm->arch.vcpu_features, host_kvm->arch.vcpu_features,
 		   allowed_features, KVM_VCPU_MAX_FEATURES);
@@ -308,10 +313,8 @@ static void pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *
 {
 	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
 
-	if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) {
-		vcpu_clear_flag(vcpu, GUEST_HAS_SVE);
+	if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE))
 		vcpu_clear_flag(vcpu, VCPU_SVE_FINALIZED);
-	}
 }
 
 static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 1cfab6a5d8a5..803e11b0dc8f 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -85,7 +85,7 @@ static void kvm_vcpu_enable_sve(struct kvm_vcpu *vcpu)
 	 * KVM_REG_ARM64_SVE_VLS.  Allocation is deferred until
 	 * kvm_arm_vcpu_finalize(), which freezes the configuration.
 	 */
-	vcpu_set_flag(vcpu, GUEST_HAS_SVE);
+	set_bit(KVM_ARCH_FLAG_GUEST_HAS_SVE, &vcpu->kvm->arch.flags);
 }
 
 /*
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:57 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:57 +0000
Subject: [PATCH v5 17/17] KVM: arm64: Use kvm_vcpu_has_feature() directly for
 struct kvm
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-18-tabba@google.com>

Now that we have introduced kvm_vcpu_has_feature(), use it in the
remaining code that checks for features in struct kvm, instead of
using the __vcpu_has_feature() helper.

No functional change intended.

Suggested-by: Quentin Perret <qperret at google.com>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/nested.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index aeaa6017ffd8..92e746040de4 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1021,8 +1021,8 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		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)))
+	if (!(kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
+	      kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_PTRAUTH_GENERIC)))
 		res0 |= (HCR_API | HCR_APK);
 	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TME, IMP))
 		res0 |= BIT(39);
@@ -1078,8 +1078,8 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 
 	/* 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)))
+	if (!(kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
+	      kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_PTRAUTH_GENERIC)))
 		res0 |= (HFGxTR_EL2_APDAKey | HFGxTR_EL2_APDBKey |
 			 HFGxTR_EL2_APGAKey | HFGxTR_EL2_APIAKey |
 			 HFGxTR_EL2_APIBKey);
-- 
2.47.1.613.gc27f4b7a9f-goog



From mark.rutland at arm.com  Mon Dec 16 02:58:29 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 16 Dec 2024 10:58:29 +0000
Subject: [PATCH V3 7/7] arm64/hw_breakpoint: Enable FEAT_Debugv8p9
In-Reply-To: <20241216040831.2448257-8-anshuman.khandual@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
 <20241216040831.2448257-8-anshuman.khandual@arm.com>
Message-ID: <Z2AH1SN5CipWkkE4@J2N7QTR9R3>

On Mon, Dec 16, 2024 at 09:38:31AM +0530, Anshuman Khandual wrote:
> Currently there can be maximum 16 breakpoints, and 16 watchpoints available
> on a given platform - as detected from ID_AA64DFR0_EL1.[BRPs|WRPs] register
> fields. But these breakpoint, and watchpoints can be extended further up to
> 64 via a new arch feature FEAT_Debugv8p9.
> 
> This first enables banked access for the breakpoint and watchpoint register
> set via MDSELR_EL1, extended exceptions via MDSCR_EL1.EMBWE and determining
> available breakpoints and watchpoints in the platform from ID_AA64DFR1_EL1,
> when FEAT_Debugv8p9 is enabled.

[...]

> +static u64 read_wb_reg(int reg, int n)
> +{
> +	unsigned long flags;
> +	u64 val;
> +
> +	if (!is_debug_v8p9_enabled())
> +		return __read_wb_reg(reg, n);
> +
> +	/*
> +	 * Bank selection in MDSELR_EL1, followed by an indexed read from
> +	 * breakpoint (or watchpoint) registers cannot be interrupted, as
> +	 * that might cause misread from the wrong targets instead. Hence
> +	 * this requires mutual exclusion.
> +	 */
> +	local_irq_save(flags);
> +	write_sysreg_s(SYS_FIELD_PREP(MDSELR_EL1, BANK, n / MAX_PER_BANK), SYS_MDSELR_EL1);
> +	isb();
> +	val = __read_wb_reg(reg, n % MAX_PER_BANK);
> +	local_irq_restore(flags);
> +	return val;
> +}
>  NOKPROBE_SYMBOL(read_wb_reg);

I don't believe that disabling interrupts here is sufficient. On the
last version I asked about the case of racing with a watchpoint handler:

| For example, what prevents watchpoint_handler() from firing in the
| middle of arch_install_hw_breakpoint() or
| arch_uninstall_hw_breakpoint()?

... and disabling interrupts cannot prevent that, because
local_irq_{save,restore}() do not affect the behaviour of watchpoints or
breakpoints.

Please can you try to answer the questions I asked last time, i.e.

| What prevents a race with an exception handler? e.g. 
| 
| * Does the structure of the code prevent that somehow?
| 
| * What context(s) does this code execute in?
|   - Are debug exceptions always masked?
|   - Do we disable breakpoints/watchpoints around (some) manipulation of
|     the relevant registers?

... and the question form the earlier comment, i.e.

| Is the existing code correct?

I suspect that the existing code might not have the necessary mutual
exclusion in all cases, but it's difficult to trigger an issue by
accident. Is there any way a handler could race with some other
manipulation of watchpoints/breakpoints such that some data structure
gets corrupted, or such that the kernel deadlocks?

Mark.


From angelogioacchino.delregno at collabora.com  Mon Dec 16 03:04:06 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 16 Dec 2024 12:04:06 +0100
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <803bc2bd802506635dfa9ea9b26a6ca40a7f4912.camel@mediatek.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
 <803bc2bd802506635dfa9ea9b26a6ca40a7f4912.camel@mediatek.com>
Message-ID: <e5788187-e894-4aab-a41e-a3d7a64762c6@collabora.com>

Il 16/12/24 09:57, CK Hu (???) ha scritto:
> Hi, Angelo:
> 
> On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>
>>
>> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
>> found in MediaTek's MT8195, MT8188 SoC and their variants, and
>> including support for display modes up to 4k60 and for HDMI
>> Audio, as per the HDMI 2.0 spec.
>>
>> HDCP and CEC functionalities are also supported by this hardware,
>> but are not included in this commit and that also poses a slight
>> difference between the V2 and V1 controllers in how they handle
>> Hotplug Detection (HPD).
>>
>> While the v1 controller was using the CEC controller to check
>> HDMI cable connection and disconnection, in this driver the v2
>> one does not.
>>
>> This is due to the fact that on parts with v2 designs, like the
>> MT8195 SoC, there is one CEC controller shared between the HDMI
>> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
>> adding support to use the CEC HW to wake up the HDMI controllers
>> it is necessary to have support for one TX, one RX *and* for both
>> at the same time.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
> 
> [snip]
> 
>> +static int mtk_hdmi_v2_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)
>> +{
> 
> I would like v1 and v2 has the same behavior.
> Why v2 has atomic check but v1 has no?
> If this is better to have, add atomic check to v1, and this function would be common function.
> 

That's because v2 uses the new helpers, while v1 does not.
The v1 must be converted to the new helpers in order to use atomic_check() like v2.

Cheers,
Angelo

> Regards,
> CK
> 
>> +       return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
>> +                                                     conn_state->state);
>> +}
>> +
> 
> 





From tabba at google.com  Mon Dec 16 02:50:40 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:40 +0000
Subject: [PATCH v5 00/17] KVM: arm64: Rework guest VM fixed feature handling
 and trapping in pKVM
Message-ID: <20241216105057.579031-1-tabba@google.com>

Changes from v4:
- (Oliver) Add assertion in kvm_init_pvm_id_regs() that vm_table
  lock is held.
- (Quentin) Carve out patches that fix RAS and that remove the
  feature KVM_ARM_VCPU_POWER_OFF from original patches, for clarity.
- (Quentin) Add a patch that refactors existing code to use
  kvm_vcpu_has_feature() instead of __vcpu_has_feature().
- (Quentin) Fixes to commit messages.

Other than added assertion, no functional changes between v4 and v5.

This patch series redoes how fixed features for protected guests
are specified in pKVM, as well as how trapping is handled based
on the features available for the VM. It also fixes a couple of
existing bugs in the process. Please refer to v4 for context [1].

This series is based on kvmarm/next (60ad25e14ab5), since it
requires the patches from the series that fixes initialization of
trap register values in pKVM [2].

Cheers,
/fuad

[1] https://lore.kernel.org/all/20241202154742.3611749-1-tabba at google.com/
[2] https://lore.kernel.org/all/20241018074833.2563674-1-tabba at google.com/

Fuad Tabba (17):
  KVM: arm64: Consolidate allowed and restricted VM feature checks
  KVM: arm64: Group setting traps for protected VMs by control register
  KVM: arm64: Move checking protected vcpu features to a separate
    function
  KVM: arm64: Remove KVM_ARM_VCPU_POWER_OFF from protected VMs allowed
    features in pKVM
  KVM: arm64: Use KVM extension checks for allowed protected VM
    capabilities
  KVM: arm64: Initialize feature id registers for protected VMs
  KVM: arm64: Fix RAS trapping in pKVM for protected VMs
  KVM: arm64: Set protected VM traps based on its view of feature
    registers
  KVM: arm64: Rework specifying restricted features for protected VMs
  KVM: arm64: Remove fixed_config.h header
  KVM: arm64: Remove redundant setting of HCR_EL2 trap bit
  KVM: arm64: Calculate cptr_el2 traps on activating traps
  KVM: arm64: Refactor kvm_reset_cptr_el2()
  KVM: arm64: Fix the value of the CPTR_EL2 RES1 bitmask for nVHE
  KVM: arm64: Remove PtrAuth guest vcpu flag
  KVM: arm64: Convert the SVE guest vcpu flag to a vm flag
  KVM: arm64: Use kvm_vcpu_has_feature() directly for struct kvm

 arch/arm64/include/asm/kvm_arm.h              |   2 +-
 arch/arm64/include/asm/kvm_emulate.h          |  29 +-
 arch/arm64/include/asm/kvm_host.h             |  25 +-
 arch/arm64/include/asm/kvm_pkvm.h             |  25 ++
 arch/arm64/kvm/arm.c                          |  30 +-
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h | 223 ----------
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |   7 +
 arch/arm64/kvm/hyp/nvhe/pkvm.c                | 341 ++++++---------
 arch/arm64/kvm/hyp/nvhe/setup.c               |   1 -
 arch/arm64/kvm/hyp/nvhe/switch.c              |  52 ++-
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            | 404 ++++++++++--------
 arch/arm64/kvm/nested.c                       |   8 +-
 arch/arm64/kvm/reset.c                        |   6 +-
 13 files changed, 446 insertions(+), 707 deletions(-)
 delete mode 100644 arch/arm64/kvm/hyp/include/nvhe/fixed_config.h


base-commit: 60ad25e14ab5a4e56c8bf7f7d6846eacb9cd53df
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:41 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:41 +0000
Subject: [PATCH v5 01/17] KVM: arm64: Consolidate allowed and restricted VM
 feature checks
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-2-tabba@google.com>

The definitions for features allowed and allowed with
restrictions for protected guests, which are based on feature
registers, were defined and checked for separately, even though
they are handled in the same way. This could result in missing
checks for certain features, e.g., pointer authentication,
causing traps for allowed features.

Consolidate the definitions into one. Use that new definition to
construct the guest view of the feature registers for
consistency.

Signed-off-by: Fuad Tabba <tabba at google.com>

---

Note: This patch ends up being a no-op, since none of the changes
in it survive the series. It's included because it makes the rest
of the series flow more smoothly.
---
 .../arm64/kvm/hyp/include/nvhe/fixed_config.h | 55 +++++++------------
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  8 +--
 arch/arm64/kvm/hyp/nvhe/sys_regs.c            |  6 +-
 3 files changed, 26 insertions(+), 43 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
index f957890c7e38..d1e59b88ff66 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
@@ -14,11 +14,8 @@
  * guest virtual machines, depending on the mode KVM is running in and on the
  * type of guest that is running.
  *
- * The ALLOW masks represent a bitmask of feature fields that are allowed
- * without any restrictions as long as they are supported by the system.
- *
- * The RESTRICT_UNSIGNED masks, if present, represent unsigned fields for
- * features that are restricted to support at most the specified feature.
+ * Each field in the masks represents the highest supported *unsigned* value for
+ * the feature, if supported by the system.
  *
  * If a feature field is not present in either, than it is not supported.
  *
@@ -34,16 +31,7 @@
  * - Floating-point and Advanced SIMD
  * - Data Independent Timing
  * - Spectre/Meltdown Mitigation
- */
-#define PVM_ID_AA64PFR0_ALLOW (\
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
-	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) \
-	)
-
-/*
+ *
  * Restrict to the following *unsigned* features for protected VMs:
  * - AArch64 guests only (no support for AArch32 guests):
  *	AArch32 adds complexity in trap handling, emulation, condition codes,
@@ -51,7 +39,12 @@
  * - RAS (v1)
  *	Supported by KVM
  */
-#define PVM_ID_AA64PFR0_RESTRICT_UNSIGNED (\
+#define PVM_ID_AA64PFR0_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_DIT) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3) | \
 	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL0, IMP) | \
 	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL1, IMP) | \
 	SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL2, IMP) | \
@@ -77,20 +70,16 @@
  * - Distinction between Secure and Non-secure Memory
  * - Mixed-endian at EL0 only
  * - Non-context synchronizing exception entry and exit
+ *
+ * Restrict to the following *unsigned* features for protected VMs:
+ * - 40-bit IPA
+ * - 16-bit ASID
  */
 #define PVM_ID_AA64MMFR0_ALLOW (\
 	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGEND) | \
 	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_SNSMEM) | \
 	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_BIGENDEL0) | \
-	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) \
-	)
-
-/*
- * Restrict to the following *unsigned* features for protected VMs:
- * - 40-bit IPA
- * - 16-bit ASID
- */
-#define PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED (\
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_EXS) | \
 	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_PARANGE), ID_AA64MMFR0_EL1_PARANGE_40) | \
 	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_ASIDBITS), ID_AA64MMFR0_EL1_ASIDBITS_16) \
 	)
@@ -185,15 +174,6 @@
 	)
 
 /* Restrict pointer authentication to the basic version. */
-#define PVM_ID_AA64ISAR1_RESTRICT_UNSIGNED (\
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), ID_AA64ISAR1_EL1_APA_PAuth) | \
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), ID_AA64ISAR1_EL1_API_PAuth) \
-	)
-
-#define PVM_ID_AA64ISAR2_RESTRICT_UNSIGNED (\
-	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
-	)
-
 #define PVM_ID_AA64ISAR1_ALLOW (\
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DPB) | \
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_JSCVT) | \
@@ -206,13 +186,16 @@
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_SPECRES) | \
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_BF16) | \
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_DGH) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_I8MM) \
+	ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_I8MM) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), ID_AA64ISAR1_EL1_APA_PAuth) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), ID_AA64ISAR1_EL1_API_PAuth) \
 	)
 
 #define PVM_ID_AA64ISAR2_ALLOW (\
 	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_ATS1A)| \
 	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3) | \
-	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_MOPS) \
+	ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_MOPS) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3), ID_AA64ISAR2_EL1_APA3_PAuth) \
 	)
 
 u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 01616c39a810..76a70fee7647 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -36,9 +36,9 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
 
 	/* Protected KVM does not support AArch32 guests. */
 	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
-		PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL0_IMP);
+		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
 	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL1_IMP);
+		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
 
 	/*
 	 * Linux guests assume support for floating-point and Advanced SIMD. Do
@@ -362,8 +362,8 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
 	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), PVM_ID_AA64PFR0_ALLOW))
 		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
 
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_RESTRICT_UNSIGNED) &&
-	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_RESTRICT_UNSIGNED))
+	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API), PVM_ID_AA64ISAR1_ALLOW) &&
+	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA), PVM_ID_AA64ISAR1_ALLOW))
 		set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
 
 	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI), PVM_ID_AA64ISAR1_ALLOW) &&
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 2860548d4250..59fb2f056177 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -89,7 +89,7 @@ static u64 get_pvm_id_aa64pfr0(const struct kvm_vcpu *vcpu)
 	u64 allow_mask = PVM_ID_AA64PFR0_ALLOW;
 
 	set_mask |= get_restricted_features_unsigned(id_aa64pfr0_el1_sys_val,
-		PVM_ID_AA64PFR0_RESTRICT_UNSIGNED);
+		PVM_ID_AA64PFR0_ALLOW);
 
 	return (id_aa64pfr0_el1_sys_val & allow_mask) | set_mask;
 }
@@ -189,7 +189,7 @@ static u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu)
 	u64 set_mask;
 
 	set_mask = get_restricted_features_unsigned(id_aa64mmfr0_el1_sys_val,
-		PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED);
+		PVM_ID_AA64MMFR0_ALLOW);
 
 	return (id_aa64mmfr0_el1_sys_val & PVM_ID_AA64MMFR0_ALLOW) | set_mask;
 }
@@ -276,7 +276,7 @@ static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
 	 * of AArch32 feature id registers.
 	 */
 	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		     PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) > ID_AA64PFR0_EL1_EL1_IMP);
+		     PVM_ID_AA64PFR0_ALLOW) > ID_AA64PFR0_EL1_EL1_IMP);
 
 	return pvm_access_raz_wi(vcpu, p, r);
 }
-- 
2.47.1.613.gc27f4b7a9f-goog



From tabba at google.com  Mon Dec 16 02:50:42 2024
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Dec 2024 10:50:42 +0000
Subject: [PATCH v5 02/17] KVM: arm64: Group setting traps for protected VMs by
 control register
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <20241216105057.579031-3-tabba@google.com>

Group setting protected VM traps by control register rather than
feature id register, since some trap values (e.g., PAuth), depend
on more than one feature id register.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 317 +++++++++++++++------------------
 1 file changed, 144 insertions(+), 173 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 76a70fee7647..1744574e79b2 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -23,233 +23,204 @@ unsigned int kvm_arm_vmid_bits;
 
 unsigned int kvm_host_sve_max_vl;
 
-/*
- * Set trap register values based on features in ID_AA64PFR0.
- */
-static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
+static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 {
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
-	u64 hcr_set = HCR_RW;
-	u64 hcr_clear = 0;
-	u64 cptr_set = 0;
-	u64 cptr_clear = 0;
-
-	/* Protected KVM does not support AArch32 guests. */
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
-		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
-	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
-		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
-
-	/*
-	 * Linux guests assume support for floating-point and Advanced SIMD. Do
-	 * not change the trapping behavior for these from the KVM default.
-	 */
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP),
-				PVM_ID_AA64PFR0_ALLOW));
-	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
-				PVM_ID_AA64PFR0_ALLOW));
+	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
 
 	if (has_hvhe())
-		hcr_set |= HCR_E2H;
+		vcpu->arch.hcr_el2 |= HCR_E2H;
 
-	/* Trap RAS unless all current versions are supported */
-	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), feature_ids) <
-	    ID_AA64PFR0_EL1_RAS_V1P1) {
-		hcr_set |= HCR_TERR | HCR_TEA;
-		hcr_clear |= HCR_FIEN;
+	if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
+		/* route synchronous external abort exceptions to EL2 */
+		vcpu->arch.hcr_el2 |= HCR_TEA;
+		/* trap error record accesses */
+		vcpu->arch.hcr_el2 |= HCR_TERR;
 	}
 
-	/* Trap AMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), feature_ids)) {
-		hcr_clear |= HCR_AMVOFFEN;
-		cptr_set |= CPTR_EL2_TAM;
-	}
+	if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
+		vcpu->arch.hcr_el2 |= HCR_FWB;
 
-	/* Trap SVE */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), feature_ids)) {
-		if (has_hvhe())
-			cptr_clear |= CPACR_ELx_ZEN;
-		else
-			cptr_set |= CPTR_EL2_TZ;
-	}
+	if (cpus_have_final_cap(ARM64_HAS_EVT) &&
+	    !cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE))
+		vcpu->arch.hcr_el2 |= HCR_TID4;
+	else
+		vcpu->arch.hcr_el2 |= HCR_TID2;
 
-	vcpu->arch.hcr_el2 |= hcr_set;
-	vcpu->arch.hcr_el2 &= ~hcr_clear;
-	vcpu->arch.cptr_el2 |= cptr_set;
-	vcpu->arch.cptr_el2 &= ~cptr_clear;
+	if (vcpu_has_ptrauth(vcpu))
+		vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
 }
 
-/*
- * Set trap register values based on features in ID_AA64PFR1.
- */
-static void pvm_init_traps_aa64pfr1(struct kvm_vcpu *vcpu)
+static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
 {
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
-	u64 hcr_set = 0;
-	u64 hcr_clear = 0;
+	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
+	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
+	const u64 id_aa64mmfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
+	u64 val = vcpu->arch.hcr_el2;
+
+	/* No support for AArch32. */
+	val |= HCR_RW;
+
+	if (has_hvhe())
+		val |= HCR_E2H;
+
+	/*
+	 * Always trap:
+	 * - Feature id registers: to control features exposed to guests
+	 * - Implementation-defined features
+	 */
+	val |= HCR_TACR | HCR_TIDCP | HCR_TID3 | HCR_TID1;
+
+	/* Trap RAS unless all current versions are supported */
+	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), id_aa64pfr0) <
+	    ID_AA64PFR0_EL1_RAS_V1P1) {
+		val |= HCR_TERR | HCR_TEA;
+		val &= ~(HCR_FIEN);
+	}
+
+	/* Trap AMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
+		val &= ~(HCR_AMVOFFEN);
 
 	/* Memory Tagging: Trap and Treat as Untagged if not supported. */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE), feature_ids)) {
-		hcr_set |= HCR_TID5;
-		hcr_clear |= HCR_DCT | HCR_ATA;
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE), id_aa64pfr1)) {
+		val |= HCR_TID5;
+		val &= ~(HCR_DCT | HCR_ATA);
 	}
 
-	vcpu->arch.hcr_el2 |= hcr_set;
-	vcpu->arch.hcr_el2 &= ~hcr_clear;
+	/* Trap LOR */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_LO), id_aa64mmfr1))
+		val |= HCR_TLOR;
+
+	vcpu->arch.hcr_el2 = val;
 }
 
-/*
- * Set trap register values based on features in ID_AA64DFR0.
- */
-static void pvm_init_traps_aa64dfr0(struct kvm_vcpu *vcpu)
+static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
 {
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
-	u64 mdcr_set = 0;
-	u64 mdcr_clear = 0;
-	u64 cptr_set = 0;
+	const u64 id_aa64pfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
+	const u64 id_aa64pfr1 = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR1_EL1);
+	const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
+	u64 val = vcpu->arch.cptr_el2;
 
-	/* Trap/constrain PMU */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), feature_ids)) {
-		mdcr_set |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
-		mdcr_clear |= MDCR_EL2_HPME | MDCR_EL2_MTPME |
-			      MDCR_EL2_HPMN_MASK;
+	if (!has_hvhe()) {
+		val |= CPTR_NVHE_EL2_RES1;
+		val &= ~(CPTR_NVHE_EL2_RES0);
 	}
 
-	/* Trap Debug */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DebugVer), feature_ids))
-		mdcr_set |= MDCR_EL2_TDRA | MDCR_EL2_TDA | MDCR_EL2_TDE;
-
-	/* Trap OS Double Lock */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DoubleLock), feature_ids))
-		mdcr_set |= MDCR_EL2_TDOSA;
+	/* Trap AMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), id_aa64pfr0))
+		val |= CPTR_EL2_TAM;
 
-	/* Trap SPE */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMSVer), feature_ids)) {
-		mdcr_set |= MDCR_EL2_TPMS;
-		mdcr_clear |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT;
+	/* Trap SVE */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), id_aa64pfr0)) {
+		if (has_hvhe())
+			val &= ~(CPACR_ELx_ZEN);
+		else
+			val |= CPTR_EL2_TZ;
 	}
 
-	/* Trap Trace Filter */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), feature_ids))
-		mdcr_set |= MDCR_EL2_TTRF;
+	/* No SME support in KVM. */
+	BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME), id_aa64pfr1));
+	if (has_hvhe())
+		val &= ~(CPACR_ELx_SMEN);
+	else
+		val |= CPTR_EL2_TSM;
 
 	/* Trap Trace */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), feature_ids)) {
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), id_aa64dfr0)) {
 		if (has_hvhe())
-			cptr_set |= CPACR_EL1_TTA;
+			val |= CPACR_EL1_TTA;
 		else
-			cptr_set |= CPTR_EL2_TTA;
+			val |= CPTR_EL2_TTA;
 	}
 
-	/* Trap External Trace */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), feature_ids))
-		mdcr_clear |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
-
-	vcpu->arch.mdcr_el2 |= mdcr_set;
-	vcpu->arch.mdcr_el2 &= ~mdcr_clear;
-	vcpu->arch.cptr_el2 |= cptr_set;
-}
-
-/*
- * Set trap register values based on features in ID_AA64MMFR0.
- */
-static void pvm_init_traps_aa64mmfr0(struct kvm_vcpu *vcpu)
-{
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR0_EL1);
-	u64 mdcr_set = 0;
-
-	/* Trap Debug Communications Channel registers */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_FGT), feature_ids))
-		mdcr_set |= MDCR_EL2_TDCC;
-
-	vcpu->arch.mdcr_el2 |= mdcr_set;
+	vcpu->arch.cptr_el2 = val;
 }
 
-/*
- * Set trap register values based on features in ID_AA64MMFR1.
- */
-static void pvm_init_traps_aa64mmfr1(struct kvm_vcpu *vcpu)
-{
-	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
-	u64 hcr_set = 0;
-
-	/* Trap LOR */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR1_EL1_LO), feature_ids))
-		hcr_set |= HCR_TLOR;
-
-	vcpu->arch.hcr_el2 |= hcr_set;
-}
-
-/*
- * Set baseline trap register values.
- */
-static void pvm_init_trap_regs(struct kvm_vcpu *vcpu)
+static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
 {
-	const u64 hcr_trap_feat_regs = HCR_TID3;
-	const u64 hcr_trap_impdef = HCR_TACR | HCR_TIDCP | HCR_TID1;
-
-	/*
-	 * Always trap:
-	 * - Feature id registers: to control features exposed to guests
-	 * - Implementation-defined features
-	 */
-	vcpu->arch.hcr_el2 |= hcr_trap_feat_regs | hcr_trap_impdef;
+	const u64 id_aa64dfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
+	const u64 id_aa64mmfr0 = pvm_read_id_reg(vcpu, SYS_ID_AA64MMFR0_EL1);
+	u64 val = vcpu->arch.mdcr_el2;
 
-	/* Clear res0 and set res1 bits to trap potential new features. */
-	vcpu->arch.hcr_el2 &= ~(HCR_RES0);
-	vcpu->arch.mdcr_el2 &= ~(MDCR_EL2_RES0);
-	if (!has_hvhe()) {
-		vcpu->arch.cptr_el2 |= CPTR_NVHE_EL2_RES1;
-		vcpu->arch.cptr_el2 &= ~(CPTR_NVHE_EL2_RES0);
+	/* Trap/constrain PMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), id_aa64dfr0)) {
+		val |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
+		val &= ~(MDCR_EL2_HPME | MDCR_EL2_MTPME | MDCR_EL2_HPMN_MASK);
 	}
-}
 
-static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
-{
-	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
+	/* Trap Debug */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DebugVer), id_aa64dfr0))
+		val |= MDCR_EL2_TDRA | MDCR_EL2_TDA;
 
-	if (has_hvhe())
-		vcpu->arch.hcr_el2 |= HCR_E2H;
+	/* Trap OS Double Lock */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_DoubleLock), id_aa64dfr0))
+		val |= MDCR_EL2_TDOSA;
 
-	if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
-		/* route synchronous external abort exceptions to EL2 */
-		vcpu->arch.hcr_el2 |= HCR_TEA;
-		/* trap error record accesses */
-		vcpu->arch.hcr_el2 |= HCR_TERR;
+	/* Trap SPE */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMSVer), id_aa64dfr0)) {
+		val |= MDCR_EL2_TPMS;
+		val &= ~(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT);
 	}
 
-	if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
-		vcpu->arch.hcr_el2 |= HCR_FWB;
+	/* Trap Trace Filter */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), id_aa64dfr0))
+		val |= MDCR_EL2_TTRF;
 
-	if (cpus_have_final_cap(ARM64_HAS_EVT) &&
-	    !cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE))
-		vcpu->arch.hcr_el2 |= HCR_TID4;
-	else
-		vcpu->arch.hcr_el2 |= HCR_TID2;
+	/* Trap External Trace */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), id_aa64dfr0))
+		val |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
 
-	if (vcpu_has_ptrauth(vcpu))
-		vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
+	/* Trap Debug Communications Channel registers */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_FGT), id_aa64mmfr0))
+		val |= MDCR_EL2_TDCC;
+
+	vcpu->arch.mdcr_el2 = val;
 }
 
 /*
  * Initialize trap register values in protected mode.
  */
-static void pkvm_vcpu_init_traps(struct kvm_vcpu *vcpu)
+static void pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
 {
+	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
+
 	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
 	vcpu->arch.mdcr_el2 = 0;
 
 	pkvm_vcpu_reset_hcr(vcpu);
 
-	if ((!vcpu_is_protected(vcpu)))
+	if ((!pkvm_hyp_vcpu_is_protected(hyp_vcpu)))
 		return;
 
-	pvm_init_trap_regs(vcpu);
-	pvm_init_traps_aa64pfr0(vcpu);
-	pvm_init_traps_aa64pfr1(vcpu);
-	pvm_init_traps_aa64dfr0(vcpu);
-	pvm_init_traps_aa64mmfr0(vcpu);
-	pvm_init_traps_aa64mmfr1(vcpu);
+	/*
+	 * PAuth is allowed if supported by the system and the vcpu.
+	 * Properly checking for PAuth requires checking various fields in
+	 * ID_AA64ISAR1_EL1 and ID_AA64ISAR2_EL1. The way that fixed config
+	 * is controlled now in pKVM does not easily allow that. This will
+	 * change later to follow the changes upstream wrt fixed configuration
+	 * and nested virt.
+	 */
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI),
+				PVM_ID_AA64ISAR1_ALLOW));
+
+	/* Protected KVM does not support AArch32 guests. */
+	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
+		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL0_IMP);
+	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
+		PVM_ID_AA64PFR0_ALLOW) != ID_AA64PFR0_EL1_EL1_IMP);
+
+	/*
+	 * Linux guests assume support for floating-point and Advanced SIMD. Do
+	 * not change the trapping behavior for these from the KVM default.
+	 */
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_FP),
+				PVM_ID_AA64PFR0_ALLOW));
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
+				PVM_ID_AA64PFR0_ALLOW));
+
+	pvm_init_traps_hcr(vcpu);
+	pvm_init_traps_cptr(vcpu);
+	pvm_init_traps_mdcr(vcpu);
 }
 
 /*
@@ -448,7 +419,7 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
 
 	pkvm_vcpu_init_sve(hyp_vcpu, host_vcpu);
 	pkvm_vcpu_init_ptrauth(hyp_vcpu);
-	pkvm_vcpu_init_traps(&hyp_vcpu->vcpu);
+	pkvm_vcpu_init_traps(hyp_vcpu);
 done:
 	if (ret)
 		unpin_host_vcpu(host_vcpu);
-- 
2.47.1.613.gc27f4b7a9f-goog



From angelogioacchino.delregno at collabora.com  Mon Dec 16 03:11:29 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 16 Dec 2024 12:11:29 +0100
Subject: [PATCH] drm/mediatek: only touch DISP_REG_OVL_PITCH_MSB if AFBC
 is supported
In-Reply-To: <8c001c8e70d93d64d3ee6bf7dc5078d2783d4e32.1734300345.git.daniel@makrotopia.org>
References: <8c001c8e70d93d64d3ee6bf7dc5078d2783d4e32.1734300345.git.daniel@makrotopia.org>
Message-ID: <adb6356b-19ea-4350-a691-3487d42c9fe2@collabora.com>

Il 15/12/24 23:09, Daniel Golle ha scritto:
> Touching DISP_REG_OVL_PITCH_MSB leads to video overlay on MT2701, MT7623N
> and probably other older SoCs being broken.
> 
> Only touching it on hardware which actually supports AFBC like it was
> before commit c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek
> DRM driver") fixes it.
> 
> Fixes: c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek DRM driver")
> Cc: stable at vger.kernel.org
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---
>   drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index f731d4fbe8b6..321b40a387cd 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -545,7 +545,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
>   				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
>   		mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
>   				      DISP_REG_OVL_HDR_PITCH(ovl, idx));
> -	} else {
> +	} else if (ovl->data->supports_afbc) {
>   		mtk_ddp_write_relaxed(cmdq_pkt,
>   				      overlay_pitch.split_pitch.msb,
>   				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));

At this point you should just move the block over a new function....

if (ovl->data->supports_afbc)
	mtk_ovl_afbc_layer_config(ovl, cmdq_pkt, idx, is_afbc);

static void mtk_ovl_afbc_layer_config( .... )
{
	if (is_afbc) {
		.....
	} else {
		.....
	}
}

Cheers,
Angelo


From dmitry.baryshkov at linaro.org  Mon Dec 16 03:24:29 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 13:24:29 +0200
Subject: [PATCH v2 00/10] drm/connector: add eld_mutex to protect
 connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <xchjpeykkqwlpniaspbzitaozuoltoq7aturtu7jq6z4lcxh77@y7t5ge2sa4er>

On Fri, Dec 06, 2024 at 11:43:03AM +0200, Dmitry Baryshkov wrote:
> The connector->eld is accessed by the .get_eld() callback. This access
> can collide with the drm_edid_to_eld() updating the data at the same
> time. Add drm_connector.eld_mutex to protect the data from concurrenct
> access.
> 
> The individual drivers were just compile tested. I propose to merge the
> drm_connector and bridge drivers through drm-misc, allowing other
> maintainers either to ack merging through drm-misc or merging the
> drm-misc into their tree and then picking up correcponding patch.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
> Changes in v2:
> - Also take the mutex in clear_eld() (Jani)
> - Rebased on top of linux-next + drm-misc-next to solve build error
> - Link to v1: https://lore.kernel.org/r/20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03 at linaro.org
> 
> ---
> Dmitry Baryshkov (10):
>       drm/connector: add mutex to protect ELD from concurrent access
>       drm/bridge: anx7625: use eld_mutex to protect access to connector->eld
>       drm/bridge: ite-it66121: use eld_mutex to protect access to connector->eld
>       drm/amd/display: use eld_mutex to protect access to connector->eld
>       drm/exynos: hdmi: use eld_mutex to protect access to connector->eld
>       drm/i915/audio: use eld_mutex to protect access to connector->eld
>       drm/msm/dp: use eld_mutex to protect access to connector->eld
>       drm/radeon: use eld_mutex to protect access to connector->eld
>       drm/sti: hdmi: use eld_mutex to protect access to connector->eld
>       drm/vc4: hdmi: use eld_mutex to protect access to connector->eld

Granted the lack of reviews from AMD maintainers and granted that the
rest of the series was reviewed and acked, is it suitable to leave those
two patches out and merge the rest through drm-misc-next?

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Mon Dec 16 03:26:29 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 13:26:29 +0200
Subject: [PATCH v6 09/10] drm/vc4: hdmi: stop rereading EDID in
 get_modes()
In-Reply-To: <73xdxb575n4ncmadffkwqzczoewbadq3forpvqt4vp7zfln2nq@o2wmbbbepwgg>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-9-50dc145a9c06@linaro.org>
 <20241206-caped-proficient-rattlesnake-c882f3@houat>
 <73xdxb575n4ncmadffkwqzczoewbadq3forpvqt4vp7zfln2nq@o2wmbbbepwgg>
Message-ID: <smaa7geowgyuvqvn6sph63ls5ublpt46zqdvt4yvqcg64scz3q@te52ty7x2soz>

On Sun, Dec 08, 2024 at 01:06:46PM +0200, Dmitry Baryshkov wrote:
> On Fri, Dec 06, 2024 at 03:34:52PM +0100, Maxime Ripard wrote:
> > Hi,
> > 
> > On Fri, Dec 06, 2024 at 12:16:03PM +0200, Dmitry Baryshkov wrote:
> > > The vc4_hdmi_connector_detect_ctx() via vc4_hdmi_handle_hotplug()
> > > already reads EDID and propagates it to the drm_connector. Stop
> > > rereading EDID as a part of the .get_modes() callback and just update
> > > the list of modes. This matches the behaviour of the i915 driver.
> > > 
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > ---
> > >  drivers/gpu/drm/vc4/vc4_hdmi.c | 21 ---------------------
> > >  1 file changed, 21 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > index e5ab42f72f618b90f956482db6c9c8074c1e3bf1..3364ef90968dad3074800f02926300ffceb75c69 100644
> > > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > @@ -470,31 +470,10 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
> > >  
> > >  static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
> > >  {
> > > -	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
> > >  	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
> > > -	const struct drm_edid *drm_edid;
> > >  	int ret = 0;
> > >  
> > > -	/*
> > > -	 * NOTE: This function should really take vc4_hdmi->mutex, but doing so
> > > -	 * results in reentrancy issues since cec_s_phys_addr() might call
> > > -	 * .adap_enable, which leads to that funtion being called with our mutex
> > > -	 * held.
> > > -	 *
> > > -	 * Concurrency isn't an issue at the moment since we don't share
> > > -	 * any state with any of the other frameworks so we can ignore
> > > -	 * the lock for now.
> > > -	 */
> > > -
> > > -	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
> > > -	drm_edid_connector_update(connector, drm_edid);
> > > -	cec_s_phys_addr(vc4_hdmi->cec_adap,
> > > -			connector->display_info.source_physical_address, false);
> > > -	if (!drm_edid)
> > > -		return 0;
> > > -
> > >  	ret = drm_edid_connector_add_modes(connector);
> > > -	drm_edid_free(drm_edid);
> > 
> > I don't think that works though, for mostly two reasons:
> > 
> >  1) We're not sure we'll even have an hotplug interrupt if the system
> >     boots with the connector plugged in for example.
> > 
> >  2) afaik, the get_modes ioctl directly calls get_modes too.
> 
> I think both paths use .fill_modes, not get_modes. And fill_modes
> explicitly calls .detect / .detect_ctx. It would be nice if somebody can
> verify the change on the acual hw. But as I wrote, i915 driver does
> exactly the same: the EDID is read / updated in .detect_ctx(), while
> .get_modes() only performs drm_edid_connector_add_modes().
> Okay, there is one significant difference which we should probably patch
> out: the .force() is also implemented to update EDID in the forced case.
> I should probably do the same for the drivers being handled in this
> patchset.

Maxime, will .force() cover your concerns? I probably fail to see a path
when .get_mode() is called without calling .detect() / .force() first.

-- 
With best wishes
Dmitry


From yeoreum.yun at arm.com  Mon Dec 16 03:50:00 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:50:00 +0000
Subject: [PATCH v3 3/9] coresight: change coresight_trace_id_map's lock type to  raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <20241216115006.415861-4-yeoreum.yun@arm.com>

coresight_trace_id_map->lock can be acquired while coresight devices'
drvdata_lock.

But the drvdata_lock can be raw_spinlock_t (i.e) coresight-etm4x.

To address this, change type of coresight_trace_id_map->lock to
raw_spinlock_t

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-core.c  |  2 +-
 .../hwtracing/coresight/coresight-trace-id.c  | 22 +++++++++----------
 include/linux/coresight.h                     |  2 +-
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index ea38ecf26fcb..cc2d87b2f248 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1164,7 +1164,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
 
 	if (csdev->type == CORESIGHT_DEV_TYPE_SINK ||
 	    csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) {
-		spin_lock_init(&csdev->perf_sink_id_map.lock);
+		raw_spin_lock_init(&csdev->perf_sink_id_map.lock);
 		csdev->perf_sink_id_map.cpu_map = alloc_percpu(atomic_t);
 		if (!csdev->perf_sink_id_map.cpu_map) {
 			kfree(csdev);
diff --git a/drivers/hwtracing/coresight/coresight-trace-id.c b/drivers/hwtracing/coresight/coresight-trace-id.c
index d98e12cb30ec..a6531869e9ec 100644
--- a/drivers/hwtracing/coresight/coresight-trace-id.c
+++ b/drivers/hwtracing/coresight/coresight-trace-id.c
@@ -16,7 +16,7 @@
 static DEFINE_PER_CPU(atomic_t, id_map_default_cpu_ids) = ATOMIC_INIT(0);
 static struct coresight_trace_id_map id_map_default = {
 	.cpu_map = &id_map_default_cpu_ids,
-	.lock = __SPIN_LOCK_UNLOCKED(id_map_default.lock)
+	.lock = __RAW_SPIN_LOCK_UNLOCKED(id_map_default.lock)
 };
 
 /* #define TRACE_ID_DEBUG 1 */
@@ -121,11 +121,11 @@ static void coresight_trace_id_release_all(struct coresight_trace_id_map *id_map
 	unsigned long flags;
 	int cpu;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 	bitmap_zero(id_map->used_ids, CORESIGHT_TRACE_IDS_MAX);
 	for_each_possible_cpu(cpu)
 		atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), 0);
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 	DUMP_ID_MAP(id_map);
 }
 
@@ -134,7 +134,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map
 	unsigned long flags;
 	int id;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 
 	/* check for existing allocation for this CPU */
 	id = _coresight_trace_id_read_cpu_id(cpu, id_map);
@@ -161,7 +161,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map
 	atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), id);
 
 get_cpu_id_out_unlock:
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 
 	DUMP_ID_CPU(cpu, id);
 	DUMP_ID_MAP(id_map);
@@ -178,12 +178,12 @@ static void _coresight_trace_id_put_cpu_id(int cpu, struct coresight_trace_id_ma
 	if (!id)
 		return;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 
 	coresight_trace_id_free(id, id_map);
 	atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), 0);
 
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 	DUMP_ID_CPU(cpu, id);
 	DUMP_ID_MAP(id_map);
 }
@@ -193,10 +193,10 @@ static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *i
 	unsigned long flags;
 	int id;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 	/* prefer odd IDs for system components to avoid legacy CPU IDS */
 	id = coresight_trace_id_alloc_new_id(id_map, 0, true);
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 
 	DUMP_ID(id);
 	DUMP_ID_MAP(id_map);
@@ -207,9 +207,9 @@ static void coresight_trace_id_map_put_system_id(struct coresight_trace_id_map *
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 	coresight_trace_id_free(id, id_map);
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 
 	DUMP_ID(id);
 	DUMP_ID_MAP(id_map);
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 924b58c343b3..6446ca1f09d8 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -233,7 +233,7 @@ struct coresight_trace_id_map {
 	DECLARE_BITMAP(used_ids, CORESIGHT_TRACE_IDS_MAX);
 	atomic_t __percpu *cpu_map;
 	atomic_t perf_cs_etm_session_active;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 };
 
 /**
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Mon Dec 16 03:50:01 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:50:01 +0000
Subject: [PATCH v3 4/9] coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <20241216115006.415861-5-yeoreum.yun@arm.com>

In coresight-cti drivers, cti_drvdata->spinlock can be held during __schedule()
by perf_event_task_sched_out()/in().

Since cti_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type cti_drvdata->spinlock in coresight-cti drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-cti-core.c  | 44 +++++------
 .../hwtracing/coresight/coresight-cti-sysfs.c | 76 +++++++++----------
 drivers/hwtracing/coresight/coresight-cti.h   |  2 +-
 3 files changed, 61 insertions(+), 61 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
index d2b5a5718c29..80f6265e3740 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -93,7 +93,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
 	unsigned long flags;
 	int rc = 0;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* no need to do anything if enabled or unpowered*/
 	if (config->hw_enabled || !config->hw_powered)
@@ -108,7 +108,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
 
 	config->hw_enabled = true;
 	drvdata->config.enable_req_count++;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return rc;
 
 cti_state_unchanged:
@@ -116,7 +116,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
 
 	/* cannot enable due to error */
 cti_err_not_enabled:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return rc;
 }
 
@@ -125,7 +125,7 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata)
 {
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->hw_powered = true;
 
 	/* no need to do anything if no enable request */
@@ -138,12 +138,12 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata)
 
 	cti_write_all_hw_regs(drvdata);
 	config->hw_enabled = true;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return;
 
 	/* did not re-enable due to no claim / no request */
 cti_hp_not_enabled:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 }
 
 /* disable hardware */
@@ -153,7 +153,7 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
 	struct coresight_device *csdev = drvdata->csdev;
 	int ret = 0;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* don't allow negative refcounts, return an error */
 	if (!drvdata->config.enable_req_count) {
@@ -177,12 +177,12 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
 
 	coresight_disclaim_device_unlocked(csdev);
 	CS_LOCK(drvdata->base);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return ret;
 
 	/* not disabled this call */
 cti_not_disabled:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return ret;
 }
 
@@ -198,11 +198,11 @@ void cti_write_intack(struct device *dev, u32 ackval)
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* write if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIINTACK, ackval);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 }
 
 /*
@@ -369,7 +369,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 	reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) :
 		      CTIOUTEN(trigger_idx));
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* read - modify write - the trigger / channel enable value */
 	reg_value = direction == CTI_TRIG_IN ? config->ctiinen[trigger_idx] :
@@ -388,7 +388,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, reg_offset, reg_value);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return 0;
 }
 
@@ -406,7 +406,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
 
 	chan_bitmask = BIT(channel_idx);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	reg_value = config->ctigate;
 	switch (op) {
 	case CTI_GATE_CHAN_ENABLE:
@@ -426,7 +426,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
 		if (cti_active(config))
 			cti_write_single_reg(drvdata, CTIGATE, reg_value);
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return err;
 }
 
@@ -445,7 +445,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
 
 	chan_bitmask = BIT(channel_idx);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	reg_value = config->ctiappset;
 	switch (op) {
 	case CTI_CHAN_SET:
@@ -473,7 +473,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
 
 	if ((err == 0) && cti_active(config))
 		cti_write_single_reg(drvdata, reg_offset, reg_value);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return err;
 }
@@ -676,7 +676,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
 	if (WARN_ON_ONCE(drvdata->ctidev.cpu != cpu))
 		return NOTIFY_BAD;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	switch (cmd) {
 	case CPU_PM_ENTER:
@@ -716,7 +716,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
 	}
 
 cti_notify_exit:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return notify_res;
 }
 
@@ -743,11 +743,11 @@ static int cti_dying_cpu(unsigned int cpu)
 	if (!drvdata)
 		return 0;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.hw_powered = false;
 	if (drvdata->config.hw_enabled)
 		coresight_disclaim_device(drvdata->csdev);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return 0;
 }
 
@@ -888,7 +888,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 	drvdata->ctidev.ctm_id = 0;
 	INIT_LIST_HEAD(&drvdata->ctidev.trig_cons);
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	/* initialise CTI driver config values */
 	cti_set_default_config(dev, drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
index d25dd2737b49..572b80ee96fb 100644
--- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
@@ -84,11 +84,11 @@ static ssize_t enable_show(struct device *dev,
 	bool enabled, powered;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	enable_req = drvdata->config.enable_req_count;
 	powered = drvdata->config.hw_powered;
 	enabled = drvdata->config.hw_enabled;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	if (powered)
 		return sprintf(buf, "%d\n", enabled);
@@ -134,9 +134,9 @@ static ssize_t powered_show(struct device *dev,
 	bool powered;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	powered = drvdata->config.hw_powered;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return sprintf(buf, "%d\n", powered);
 }
@@ -181,10 +181,10 @@ static ssize_t coresight_cti_reg_show(struct device *dev,
 	u32 val = 0;
 
 	pm_runtime_get_sync(dev->parent);
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (drvdata->config.hw_powered)
 		val = readl_relaxed(drvdata->base + cti_attr->off);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	pm_runtime_put_sync(dev->parent);
 	return sysfs_emit(buf, "0x%x\n", val);
 }
@@ -202,10 +202,10 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev,
 		return -EINVAL;
 
 	pm_runtime_get_sync(dev->parent);
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (drvdata->config.hw_powered)
 		cti_write_single_reg(drvdata, cti_attr->off, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	pm_runtime_put_sync(dev->parent);
 	return size;
 }
@@ -264,7 +264,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf,
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if ((reg_offset >= 0) && cti_active(config)) {
 		CS_UNLOCK(drvdata->base);
 		val = readl_relaxed(drvdata->base + reg_offset);
@@ -274,7 +274,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf,
 	} else if (pcached_val) {
 		val = *pcached_val;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%#x\n", val);
 }
 
@@ -293,7 +293,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* local store */
 	if (pcached_val)
 		*pcached_val = (u32)val;
@@ -301,7 +301,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf,
 	/* write through if offset and enabled */
 	if ((reg_offset >= 0) && cti_active(config))
 		cti_write_single_reg(drvdata, reg_offset, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 
@@ -349,9 +349,9 @@ static ssize_t inout_sel_store(struct device *dev,
 	if (val > (CTIINOUTEN_MAX - 1))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.ctiinout_sel = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(inout_sel);
@@ -364,10 +364,10 @@ static ssize_t inen_show(struct device *dev,
 	int index;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = drvdata->config.ctiinout_sel;
 	val = drvdata->config.ctiinen[index];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%#lx\n", val);
 }
 
@@ -383,14 +383,14 @@ static ssize_t inen_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = config->ctiinout_sel;
 	config->ctiinen[index] = val;
 
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIINEN(index), val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(inen);
@@ -403,10 +403,10 @@ static ssize_t outen_show(struct device *dev,
 	int index;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = drvdata->config.ctiinout_sel;
 	val = drvdata->config.ctiouten[index];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%#lx\n", val);
 }
 
@@ -422,14 +422,14 @@ static ssize_t outen_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = config->ctiinout_sel;
 	config->ctiouten[index] = val;
 
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIOUTEN(index), val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(outen);
@@ -463,7 +463,7 @@ static ssize_t appclear_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* a 1'b1 in appclr clears down the same bit in appset*/
 	config->ctiappset &= ~val;
@@ -471,7 +471,7 @@ static ssize_t appclear_store(struct device *dev,
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(appclear);
@@ -487,12 +487,12 @@ static ssize_t apppulse_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIAPPPULSE, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(apppulse);
@@ -681,9 +681,9 @@ static ssize_t trig_filter_enable_show(struct device *dev,
 	u32 val;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = drvdata->config.trig_filter_enable;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%d\n", val);
 }
 
@@ -697,9 +697,9 @@ static ssize_t trig_filter_enable_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.trig_filter_enable = !!val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(trig_filter_enable);
@@ -728,7 +728,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev,
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* clear the CTI trigger / channel programming registers */
 	for (i = 0; i < config->nr_trig_max; i++) {
@@ -747,7 +747,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev,
 	if (cti_active(config))
 		cti_write_all_hw_regs(drvdata);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(chan_xtrigs_reset);
@@ -768,9 +768,9 @@ static ssize_t chan_xtrigs_sel_store(struct device *dev,
 	if (val > (drvdata->config.nr_ctm_channels - 1))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.xtrig_rchan_sel = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 
@@ -781,9 +781,9 @@ static ssize_t chan_xtrigs_sel_show(struct device *dev,
 	unsigned long val;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = drvdata->config.xtrig_rchan_sel;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return sprintf(buf, "%ld\n", val);
 }
@@ -838,12 +838,12 @@ static ssize_t print_chan_list(struct device *dev,
 	unsigned long inuse_bits = 0, chan_mask;
 
 	/* scan regs to get bitmap of channels in use. */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	for (i = 0; i < config->nr_trig_max; i++) {
 		inuse_bits |= config->ctiinen[i];
 		inuse_bits |= config->ctiouten[i];
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	/* inverse bits if printing free channels */
 	if (!inuse)
diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h
index cb9ee616d01f..16e310e7e9d4 100644
--- a/drivers/hwtracing/coresight/coresight-cti.h
+++ b/drivers/hwtracing/coresight/coresight-cti.h
@@ -175,7 +175,7 @@ struct cti_drvdata {
 	void __iomem *base;
 	struct coresight_device	*csdev;
 	struct cti_device ctidev;
-	spinlock_t spinlock;
+	raw_spinlock_t spinlock;
 	struct cti_config config;
 	struct list_head node;
 	void (*csdev_release)(struct device *dev);
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Mon Dec 16 03:50:02 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:50:02 +0000
Subject: [PATCH v3 5/9] coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <20241216115006.415861-6-yeoreum.yun@arm.com>

In coresight-etb10 drivers, etb_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since etb_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type etb_drvdata->spinlock in coresight-etb10 drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-etb10.c | 26 +++++++++----------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index aea9ac9c4bd0..7948597d483d 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -84,7 +84,7 @@ struct etb_drvdata {
 	struct clk		*atclk;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 	local_t			reading;
 	pid_t			pid;
 	u8			*buf;
@@ -145,7 +145,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
 	unsigned long flags;
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't messup with perf sessions. */
 	if (coresight_get_mode(csdev) == CS_MODE_PERF) {
@@ -163,7 +163,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
 
 	csdev->refcnt++;
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return ret;
 }
 
@@ -176,7 +176,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
 	struct perf_output_handle *handle = data;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* No need to continue if the component is already in used by sysFS. */
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
@@ -219,7 +219,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
 	}
 
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return ret;
 }
 
@@ -352,11 +352,11 @@ static int etb_disable(struct coresight_device *csdev)
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	unsigned long flags;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	csdev->refcnt--;
 	if (csdev->refcnt) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -366,7 +366,7 @@ static int etb_disable(struct coresight_device *csdev)
 	/* Dissociate from monitored process. */
 	drvdata->pid = -1;
 	coresight_set_mode(csdev, CS_MODE_DISABLED);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&csdev->dev, "ETB disabled\n");
 	return 0;
@@ -443,7 +443,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
 
 	capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't do anything if another tracer is using this sink */
 	if (csdev->refcnt != 1)
@@ -566,7 +566,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
 	__etb_enable_hw(drvdata);
 	CS_LOCK(drvdata->base);
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return to_read;
 }
@@ -587,13 +587,13 @@ static void etb_dump(struct etb_drvdata *drvdata)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
 		__etb_disable_hw(drvdata);
 		etb_dump_hw(drvdata);
 		__etb_enable_hw(drvdata);
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&drvdata->csdev->dev, "ETB dumped\n");
 }
@@ -746,7 +746,7 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
 	drvdata->base = base;
 	desc.access = CSDEV_ACCESS_IOMEM(base);
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	drvdata->buffer_depth = etb_get_buffer_depth(drvdata);
 
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Mon Dec 16 03:50:03 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:50:03 +0000
Subject: [PATCH v3 6/9] coresight-funnel: change funnel_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <20241216115006.415861-7-yeoreum.yun@arm.com>

In coresight-funnel drivers, cti_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since funnel_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type funnel_drvdata->spinlock in
coresight-funnel drivers, which can be called by
perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-funnel.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 33efe1acbef7..a566c8854327 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -47,7 +47,7 @@ struct funnel_drvdata {
 	struct clk		*pclk;
 	struct coresight_device	*csdev;
 	unsigned long		priority;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 };
 
 static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port)
@@ -85,7 +85,7 @@ static int funnel_enable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool first_enable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_read(&in->dest_refcnt) == 0) {
 		if (drvdata->base)
 			rc = dynamic_funnel_enable_hw(drvdata, in->dest_port);
@@ -94,7 +94,7 @@ static int funnel_enable(struct coresight_device *csdev,
 	}
 	if (!rc)
 		atomic_inc(&in->dest_refcnt);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (first_enable)
 		dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n",
@@ -129,13 +129,13 @@ static void funnel_disable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool last_disable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_dec_return(&in->dest_refcnt) == 0) {
 		if (drvdata->base)
 			dynamic_funnel_disable_hw(drvdata, in->dest_port);
 		last_disable = true;
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (last_disable)
 		dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n",
@@ -266,7 +266,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
 	}
 	dev->platform_data = pdata;
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	desc.type = CORESIGHT_DEV_TYPE_LINK;
 	desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG;
 	desc.ops = &funnel_cs_ops;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Mon Dec 16 03:50:04 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:50:04 +0000
Subject: [PATCH v3 7/9] coresight-replicator: change replicator_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <20241216115006.415861-8-yeoreum.yun@arm.com>

In coresight-replicator drivers, replicator_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since replicator_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type replicator_drvdata->spinlock in
coresight-replicator drivers, which can be called
by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-replicator.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 0fba87de6d1a..7d36fe2176cc 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -41,7 +41,7 @@ struct replicator_drvdata {
 	struct clk		*atclk;
 	struct clk		*pclk;
 	struct coresight_device	*csdev;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 	bool			check_idfilter_val;
 };
 
@@ -125,7 +125,7 @@ static int replicator_enable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool first_enable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_read(&out->src_refcnt) == 0) {
 		if (drvdata->base)
 			rc = dynamic_replicator_enable(drvdata, in->dest_port,
@@ -135,7 +135,7 @@ static int replicator_enable(struct coresight_device *csdev,
 	}
 	if (!rc)
 		atomic_inc(&out->src_refcnt);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (first_enable)
 		dev_dbg(&csdev->dev, "REPLICATOR enabled\n");
@@ -179,14 +179,14 @@ static void replicator_disable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool last_disable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_dec_return(&out->src_refcnt) == 0) {
 		if (drvdata->base)
 			dynamic_replicator_disable(drvdata, in->dest_port,
 						   out->src_port);
 		last_disable = true;
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (last_disable)
 		dev_dbg(&csdev->dev, "REPLICATOR disabled\n");
@@ -277,7 +277,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
 	}
 	dev->platform_data = pdata;
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	desc.type = CORESIGHT_DEV_TYPE_LINK;
 	desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT;
 	desc.ops = &replicator_cs_ops;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Mon Dec 16 03:50:05 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:50:05 +0000
Subject: [PATCH v3 8/9] coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <20241216115006.415861-9-yeoreum.yun@arm.com>

In coresight-tmc drivers, tmc_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since tmc_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type tmc_drvdata->spinlock in coresight-tmc drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-tmc-core.c  |  6 +--
 .../hwtracing/coresight/coresight-tmc-etf.c   | 48 +++++++++----------
 .../hwtracing/coresight/coresight-tmc-etr.c   | 40 ++++++++--------
 drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
 4 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index e9876252a789..4e9925300931 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -492,7 +492,7 @@ static int __tmc_probe(struct device *dev, struct resource *res)
 	drvdata->base = base;
 	desc.access = CSDEV_ACCESS_IOMEM(base);
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
 	drvdata->config_type = BMVAL(devid, 6, 7);
@@ -596,7 +596,7 @@ static void tmc_shutdown(struct amba_device *adev)
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = amba_get_drvdata(adev);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_DISABLED)
 		goto out;
@@ -610,7 +610,7 @@ static void tmc_shutdown(struct amba_device *adev)
 	 * the system is going down after this.
 	 */
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 }
 
 static void __tmc_remove(struct device *dev)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index d4f641cd9de6..fca8e9ffb3cf 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -182,9 +182,9 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 	 * If we don't have a buffer release the lock and allocate memory.
 	 * Otherwise keep the lock and move along.
 	 */
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (!drvdata->buf) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 		/* Allocating the memory here while outside of the spinlock */
 		buf = kzalloc(drvdata->size, GFP_KERNEL);
@@ -192,7 +192,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 			return -ENOMEM;
 
 		/* Let's try again */
-		spin_lock_irqsave(&drvdata->spinlock, flags);
+		raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	}
 
 	if (drvdata->reading) {
@@ -235,7 +235,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 		used = false;
 	}
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/* Free memory outside the spinlock if need be */
 	if (!used)
@@ -253,7 +253,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
 	struct perf_output_handle *handle = data;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	do {
 		ret = -EINVAL;
 		if (drvdata->reading)
@@ -296,7 +296,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
 			csdev->refcnt++;
 		}
 	} while (0);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -331,16 +331,16 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
 	csdev->refcnt--;
 	if (csdev->refcnt) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -351,7 +351,7 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
 	drvdata->pid = -1;
 	coresight_set_mode(csdev, CS_MODE_DISABLED);
 
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n");
 	return 0;
@@ -366,9 +366,9 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	bool first_enable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -381,7 +381,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
 	}
 	if (!ret)
 		csdev->refcnt++;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (first_enable)
 		dev_dbg(&csdev->dev, "TMC-ETF enabled\n");
@@ -396,9 +396,9 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	bool last_disable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return;
 	}
 
@@ -408,7 +408,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
 		coresight_set_mode(csdev, CS_MODE_DISABLED);
 		last_disable = true;
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (last_disable)
 		dev_dbg(&csdev->dev, "TMC-ETF disabled\n");
@@ -488,7 +488,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
 	if (WARN_ON_ONCE(coresight_get_mode(csdev) != CS_MODE_PERF))
 		return 0;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't do anything if another tracer is using this sink */
 	if (csdev->refcnt != 1)
@@ -585,7 +585,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
 	 */
 	CS_LOCK(drvdata->base);
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return to_read;
 }
@@ -623,7 +623,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
 			 drvdata->config_type != TMC_CONFIG_TYPE_ETF))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (drvdata->reading) {
 		ret = -EBUSY;
@@ -655,7 +655,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
 
 	drvdata->reading = true;
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -672,14 +672,14 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
 			 drvdata->config_type != TMC_CONFIG_TYPE_ETF))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Re-enable the TMC if need be */
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
 		/* There is no point in reading a TMC in HW FIFO mode */
 		mode = readl_relaxed(drvdata->base + TMC_MODE);
 		if (mode != TMC_MODE_CIRCULAR_BUFFER) {
-			spin_unlock_irqrestore(&drvdata->spinlock, flags);
+			raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 			return -EINVAL;
 		}
 		/*
@@ -693,7 +693,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
 		memset(drvdata->buf, 0, drvdata->size);
 		rc = __tmc_etb_enable_hw(drvdata);
 		if (rc) {
-			spin_unlock_irqrestore(&drvdata->spinlock, flags);
+			raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 			return rc;
 		}
 	} else {
@@ -706,7 +706,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
 	}
 
 	drvdata->reading = false;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/*
 	 * Free allocated memory outside of the spinlock.  There is no need
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..a0a90ce7333e 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1176,10 +1176,10 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 	 * buffer, provided the size matches. Any allocation has to be done
 	 * with the lock released.
 	 */
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	sysfs_buf = READ_ONCE(drvdata->sysfs_buf);
 	if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 		/* Allocate memory with the locks released */
 		free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata);
@@ -1187,7 +1187,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 			return new_buf;
 
 		/* Let's try again */
-		spin_lock_irqsave(&drvdata->spinlock, flags);
+		raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	}
 
 	if (drvdata->reading || coresight_get_mode(csdev) == CS_MODE_PERF) {
@@ -1206,7 +1206,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 	}
 
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/* Free memory outside the spinlock if need be */
 	if (free_buf)
@@ -1224,7 +1224,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 	if (IS_ERR(sysfs_buf))
 		return PTR_ERR(sysfs_buf);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/*
 	 * In sysFS mode we can have multiple writers per sink.  Since this
@@ -1243,7 +1243,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 	}
 
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (!ret)
 		dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
@@ -1562,17 +1562,17 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
 	struct etr_perf_buffer *etr_perf = config;
 	struct etr_buf *etr_buf = etr_perf->etr_buf;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't do anything if another tracer is using this sink */
 	if (csdev->refcnt != 1) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		goto out;
 	}
 
 	if (WARN_ON(drvdata->perf_buf != etr_buf)) {
 		lost = true;
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		goto out;
 	}
 
@@ -1582,7 +1582,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
 	tmc_sync_etr_buf(drvdata);
 
 	CS_LOCK(drvdata->base);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	lost = etr_buf->full;
 	offset = etr_buf->offset;
@@ -1651,7 +1651,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 	struct perf_output_handle *handle = data;
 	struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	 /* Don't use this sink if it is already claimed by sysFS */
 	if (coresight_get_mode(csdev) == CS_MODE_SYSFS) {
 		rc = -EBUSY;
@@ -1691,7 +1691,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 	}
 
 unlock_out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return rc;
 }
 
@@ -1713,16 +1713,16 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
 	csdev->refcnt--;
 	if (csdev->refcnt) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -1735,7 +1735,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
 	/* Reset perf specific data */
 	drvdata->perf_buf = NULL;
 
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&csdev->dev, "TMC-ETR disabled\n");
 	return 0;
@@ -1762,7 +1762,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
 		ret = -EBUSY;
 		goto out;
@@ -1784,7 +1784,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
 
 	drvdata->reading = true;
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -1798,7 +1798,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* RE-enable the TMC if need be */
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
@@ -1818,7 +1818,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
 	}
 
 	drvdata->reading = false;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/* Free allocated memory out side of the spinlock */
 	if (sysfs_buf)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 2671926be62a..60b395025bc4 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -195,7 +195,7 @@ struct tmc_drvdata {
 	void __iomem		*base;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
 	union {
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Mon Dec 16 03:49:57 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:49:57 +0000
Subject: [PATCH v3 0/9] coresight: change some driver' spinlock type to raw_spinlock_t
Message-ID: <20241216115006.415861-1-yeoreum.yun@arm.com>

In some coresight drivers, drvdata->spinlock can be held during __schedule()
by perf_event_task_sched_out()/in().

Since drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this,change type drvdata->spinlock in some coresight drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>

v2 to v3:
    - Fix build error

v1 to v2:
    - seperate patchsets to change locktype and apply gurad API.

Yeoreum Yun (9):
  coresight: change coresight_device lock type to  raw_spinlock_t
  coresight-etm4x: change etmv4_drvdata spinlock type to  raw_spinlock_t
  coresight: change coresight_trace_id_map's lock type to
    raw_spinlock_t
  coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
  coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
  coresight-funnel: change funnel_drvdata spinlock's type to
    raw_spinlock_t
  coresight-replicator: change replicator_drvdata spinlock's type to
    raw_spinlock_t
  coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
  coresight/ultrasoc: change cti_drvdata spinlock's type to
    raw_spinlock_t

 .../hwtracing/coresight/coresight-config.c    |   8 +-
 .../hwtracing/coresight/coresight-config.h    |   2 +-
 drivers/hwtracing/coresight/coresight-core.c  |   2 +-
 .../hwtracing/coresight/coresight-cti-core.c  |  44 +--
 .../hwtracing/coresight/coresight-cti-sysfs.c |  76 +++---
 drivers/hwtracing/coresight/coresight-cti.h   |   2 +-
 drivers/hwtracing/coresight/coresight-etb10.c |  26 +-
 .../coresight/coresight-etm4x-core.c          |  18 +-
 .../coresight/coresight-etm4x-sysfs.c         | 250 +++++++++---------
 drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
 .../hwtracing/coresight/coresight-funnel.c    |  12 +-
 .../coresight/coresight-replicator.c          |  12 +-
 .../hwtracing/coresight/coresight-syscfg.c    |  26 +-
 .../hwtracing/coresight/coresight-tmc-core.c  |   6 +-
 .../hwtracing/coresight/coresight-tmc-etf.c   |  48 ++--
 .../hwtracing/coresight/coresight-tmc-etr.c   |  40 +--
 drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
 .../hwtracing/coresight/coresight-trace-id.c  |  22 +-
 drivers/hwtracing/coresight/ultrasoc-smb.c    |  12 +-
 drivers/hwtracing/coresight/ultrasoc-smb.h    |   2 +-
 include/linux/coresight.h                     |   4 +-
 21 files changed, 308 insertions(+), 308 deletions(-)

--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Mon Dec 16 03:49:58 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:49:58 +0000
Subject: [PATCH v3 1/9] coresight: change coresight_device lock type to  raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <20241216115006.415861-2-yeoreum.yun@arm.com>

coresight_device->cscfg_csdev_lock can be held during __schedule()
by perf_event_task_sched_out()/in().

Since coresight->cscfg_csdev_lock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type of coresight_device->cscfg_csdev_lock
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-syscfg.c    | 26 +++++++++----------
 include/linux/coresight.h                     |  2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 11138a9762b0..a70c1454b410 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -89,9 +89,9 @@ static int cscfg_add_csdev_cfg(struct coresight_device *csdev,
 	}
 	/* if matched features, add config to device.*/
 	if (config_csdev) {
-		spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+		raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 		list_add(&config_csdev->node, &csdev->config_csdev_list);
-		spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+		raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 	}
 
 	return 0;
@@ -194,9 +194,9 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev,
 
 	/* add to internal csdev feature list & initialise using reset call */
 	cscfg_reset_feat(feat_csdev);
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	list_add(&feat_csdev->node, &csdev->feature_csdev_list);
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	return 0;
 }
@@ -765,7 +765,7 @@ static int cscfg_list_add_csdev(struct coresight_device *csdev,
 
 	INIT_LIST_HEAD(&csdev->feature_csdev_list);
 	INIT_LIST_HEAD(&csdev->config_csdev_list);
-	spin_lock_init(&csdev->cscfg_csdev_lock);
+	raw_spin_lock_init(&csdev->cscfg_csdev_lock);
 
 	return 0;
 }
@@ -855,7 +855,7 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
 	struct cscfg_feature_csdev *feat_csdev;
 	unsigned long flags;
 
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	if (list_empty(&csdev->feature_csdev_list))
 		goto unlock_exit;
 
@@ -863,7 +863,7 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
 		cscfg_reset_feat(feat_csdev);
 
 unlock_exit:
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 }
 EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
 
@@ -1059,7 +1059,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 	 * Look for matching configuration - set the active configuration
 	 * context if found.
 	 */
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
 		config_desc = config_csdev_item->config_desc;
 		if ((atomic_read(&config_desc->active_cnt)) &&
@@ -1069,7 +1069,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 			break;
 		}
 	}
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	/*
 	 * If found, attempt to enable
@@ -1090,12 +1090,12 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 			 *
 			 * Set enabled if OK, err if not.
 			 */
-			spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+			raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 			if (csdev->active_cscfg_ctxt)
 				config_csdev_active->enabled = true;
 			else
 				err = -EBUSY;
-			spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+			raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 		}
 	}
 	return err;
@@ -1124,7 +1124,7 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
 	 * If it was not enabled, we have no work to do, otherwise mark as disabled.
 	 * Clear the active config pointer.
 	 */
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	config_csdev = (struct cscfg_config_csdev *)csdev->active_cscfg_ctxt;
 	if (config_csdev) {
 		if (!config_csdev->enabled)
@@ -1133,7 +1133,7 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
 			config_csdev->enabled = false;
 	}
 	csdev->active_cscfg_ctxt = NULL;
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	/* true if there was an enabled active config */
 	if (config_csdev)
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index c13342594278..924b58c343b3 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -296,7 +296,7 @@ struct coresight_device {
 	/* system configuration and feature lists */
 	struct list_head feature_csdev_list;
 	struct list_head config_csdev_list;
-	spinlock_t cscfg_csdev_lock;
+	raw_spinlock_t cscfg_csdev_lock;
 	void *active_cscfg_ctxt;
 };
 
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Mon Dec 16 03:49:59 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:49:59 +0000
Subject: [PATCH v3 2/9] coresight-etm4x: change etmv4_drvdata spinlock type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <20241216115006.415861-3-yeoreum.yun@arm.com>

In coresight-etm4x drivers, etmv4_drvdata->spinlock can be held during
__schedule() by perf_event_task_sched_out()/in().

Since etmv4_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type etmv4_drvdata->spinlock
in coresight-etm4x drivers, which can be called
by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-config.c    |   8 +-
 .../hwtracing/coresight/coresight-config.h    |   2 +-
 .../coresight/coresight-etm4x-core.c          |  18 +-
 .../coresight/coresight-etm4x-sysfs.c         | 250 +++++++++---------
 drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
 5 files changed, 140 insertions(+), 140 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c
index 4723bf7402a2..4f72ae71b696 100644
--- a/drivers/hwtracing/coresight/coresight-config.c
+++ b/drivers/hwtracing/coresight/coresight-config.c
@@ -76,10 +76,10 @@ static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat_csdev)
 	unsigned long flags;
 	int i;
 
-	spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
+	raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
 	for (i = 0; i < feat_csdev->nr_regs; i++)
 		cscfg_set_reg(&feat_csdev->regs_csdev[i]);
-	spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+	raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
 	dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
 		feat_csdev->feat_desc->name, "set on enable");
 	return 0;
@@ -91,10 +91,10 @@ static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat_csdev)
 	unsigned long flags;
 	int i;
 
-	spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
+	raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
 	for (i = 0; i < feat_csdev->nr_regs; i++)
 		cscfg_save_reg(&feat_csdev->regs_csdev[i]);
-	spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+	raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
 	dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
 		feat_csdev->feat_desc->name, "save on disable");
 }
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 6ba013975741..b9ebc9fcfb7f 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -206,7 +206,7 @@ struct cscfg_feature_csdev {
 	const struct cscfg_feature_desc *feat_desc;
 	struct coresight_device *csdev;
 	struct list_head node;
-	spinlock_t *drv_spinlock;
+	raw_spinlock_t *drv_spinlock;
 	int nr_params;
 	struct cscfg_parameter_csdev *params_csdev;
 	int nr_regs;
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index dd8c74f893db..86893115df17 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -807,7 +807,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 			return ret;
 	}
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* sysfs needs to read and allocate a trace ID */
 	ret = etm4_read_alloc_trace_id(drvdata);
@@ -830,7 +830,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 		etm4_release_trace_id(drvdata);
 
 unlock_sysfs_enable:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	if (!ret)
 		dev_dbg(&csdev->dev, "ETM tracing enabled\n");
@@ -977,7 +977,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	 * DYING hotplug callback is serviced by the ETM driver.
 	 */
 	cpus_read_lock();
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/*
 	 * Executing etm4_disable_hw on the cpu whose ETM is being disabled
@@ -985,7 +985,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	 */
 	smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	cpus_read_unlock();
 
 	/*
@@ -1663,13 +1663,13 @@ static int etm4_starting_cpu(unsigned int cpu)
 	if (!etmdrvdata[cpu])
 		return 0;
 
-	spin_lock(&etmdrvdata[cpu]->spinlock);
+	raw_spin_lock(&etmdrvdata[cpu]->spinlock);
 	if (!etmdrvdata[cpu]->os_unlock)
 		etm4_os_unlock(etmdrvdata[cpu]);
 
 	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
 		etm4_enable_hw(etmdrvdata[cpu]);
-	spin_unlock(&etmdrvdata[cpu]->spinlock);
+	raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
 	return 0;
 }
 
@@ -1678,10 +1678,10 @@ static int etm4_dying_cpu(unsigned int cpu)
 	if (!etmdrvdata[cpu])
 		return 0;
 
-	spin_lock(&etmdrvdata[cpu]->spinlock);
+	raw_spin_lock(&etmdrvdata[cpu]->spinlock);
 	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
 		etm4_disable_hw(etmdrvdata[cpu]);
-	spin_unlock(&etmdrvdata[cpu]->spinlock);
+	raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
 	return 0;
 }
 
@@ -2125,7 +2125,7 @@ static int etm4_probe(struct device *dev)
 			return -ENOMEM;
 	}
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	drvdata->cpu = coresight_get_cpu(dev);
 	if (drvdata->cpu < 0)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a9f19629f3f8..11e865b8e824 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -174,7 +174,7 @@ static ssize_t reset_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (val)
 		config->mode = 0x0;
 
@@ -266,7 +266,7 @@ static ssize_t reset_store(struct device *dev,
 	config->vmid_mask0 = 0x0;
 	config->vmid_mask1 = 0x0;
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	/* for sysfs - only release trace id when resetting */
 	etm4_release_trace_id(drvdata);
@@ -300,7 +300,7 @@ static ssize_t mode_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->mode = val & ETMv4_MODE_ALL;
 
 	if (drvdata->instrp0 == true) {
@@ -437,7 +437,7 @@ static ssize_t mode_store(struct device *dev,
 	if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
 		etm4_config_trace_mode(config);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -466,14 +466,14 @@ static ssize_t pe_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (val > drvdata->nr_pe) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EINVAL;
 	}
 
 	config->pe_sel = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(pe);
@@ -501,7 +501,7 @@ static ssize_t event_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	switch (drvdata->nr_event) {
 	case 0x0:
 		/* EVENT0, bits[7:0] */
@@ -522,7 +522,7 @@ static ssize_t event_store(struct device *dev,
 	default:
 		break;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(event);
@@ -550,7 +550,7 @@ static ssize_t event_instren_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* start by clearing all instruction event enable bits */
 	config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;
 	switch (drvdata->nr_event) {
@@ -578,7 +578,7 @@ static ssize_t event_instren_store(struct device *dev,
 	default:
 		break;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(event_instren);
@@ -739,11 +739,11 @@ static ssize_t event_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val &= TRCVICTLR_EVENT_MASK >> __bf_shf(TRCVICTLR_EVENT_MASK);
 	config->vinst_ctrl &= ~TRCVICTLR_EVENT_MASK;
 	config->vinst_ctrl |= FIELD_PREP(TRCVICTLR_EVENT_MASK, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(event_vinst);
@@ -771,13 +771,13 @@ static ssize_t s_exlevel_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* clear all EXLEVEL_S bits  */
 	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;
 	/* enable instruction tracing for corresponding exception level */
 	val &= drvdata->s_ex_level;
 	config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_S_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(s_exlevel_vinst);
@@ -806,13 +806,13 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* clear EXLEVEL_NS bits  */
 	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;
 	/* enable instruction tracing for corresponding exception level */
 	val &= drvdata->ns_ex_level;
 	config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_NS_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ns_exlevel_vinst);
@@ -846,9 +846,9 @@ static ssize_t addr_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->addr_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_idx);
@@ -862,7 +862,7 @@ static ssize_t addr_instdatatype_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	val = FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]);
 	len = scnprintf(buf, PAGE_SIZE, "%s\n",
@@ -870,7 +870,7 @@ static ssize_t addr_instdatatype_show(struct device *dev,
 			(val == TRCACATRn_TYPE_DATA_LOAD_ADDR ? "data_load" :
 			(val == TRCACATRn_TYPE_DATA_STORE_ADDR ? "data_store" :
 			"data_load_store")));
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return len;
 }
 
@@ -888,13 +888,13 @@ static ssize_t addr_instdatatype_store(struct device *dev,
 	if (sscanf(buf, "%s", str) != 1)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!strcmp(str, "instr"))
 		/* TYPE, bits[1:0] */
 		config->addr_acc[idx] &= ~TRCACATRn_TYPE_MASK;
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_instdatatype);
@@ -909,14 +909,14 @@ static ssize_t addr_single_show(struct device *dev,
 	struct etmv4_config *config = &drvdata->config;
 
 	idx = config->addr_idx;
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 	val = (unsigned long)config->addr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -932,17 +932,17 @@ static ssize_t addr_single_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	config->addr_val[idx] = (u64)val;
 	config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_single);
@@ -956,23 +956,23 @@ static ssize_t addr_range_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 	if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
 	      (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	val1 = (unsigned long)config->addr_val[idx];
 	val2 = (unsigned long)config->addr_val[idx + 1];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
 }
 
@@ -995,10 +995,10 @@ static ssize_t addr_range_store(struct device *dev,
 	if (val1 > val2)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
@@ -1006,7 +1006,7 @@ static ssize_t addr_range_store(struct device *dev,
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
 	      (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
@@ -1023,7 +1023,7 @@ static ssize_t addr_range_store(struct device *dev,
 		exclude = config->mode & ETM_MODE_EXCLUDE;
 	etm4_set_mode_exclude(drvdata, exclude ? true : false);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_range);
@@ -1037,17 +1037,17 @@ static ssize_t addr_start_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	val = (unsigned long)config->addr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1063,22 +1063,22 @@ static ssize_t addr_start_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!drvdata->nr_addr_cmp) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EINVAL;
 	}
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	config->addr_val[idx] = (u64)val;
 	config->addr_type[idx] = ETM_ADDR_TYPE_START;
 	config->vissctlr |= BIT(idx);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_start);
@@ -1092,17 +1092,17 @@ static ssize_t addr_stop_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	val = (unsigned long)config->addr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1118,22 +1118,22 @@ static ssize_t addr_stop_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!drvdata->nr_addr_cmp) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EINVAL;
 	}
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	       config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	config->addr_val[idx] = (u64)val;
 	config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
 	config->vissctlr |= BIT(idx + 16);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_stop);
@@ -1147,14 +1147,14 @@ static ssize_t addr_ctxtype_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* CONTEXTTYPE, bits[3:2] */
 	val = FIELD_GET(TRCACATRn_CONTEXTTYPE_MASK, config->addr_acc[idx]);
 	len = scnprintf(buf, PAGE_SIZE, "%s\n", val == ETM_CTX_NONE ? "none" :
 			(val == ETM_CTX_CTXID ? "ctxid" :
 			(val == ETM_CTX_VMID ? "vmid" : "all")));
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return len;
 }
 
@@ -1172,7 +1172,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
 	if (sscanf(buf, "%s", str) != 1)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!strcmp(str, "none"))
 		/* start by clearing context type bits */
@@ -1199,7 +1199,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
 		if (drvdata->numvmidc)
 			config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_ctxtype);
@@ -1213,11 +1213,11 @@ static ssize_t addr_context_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* context ID comparator bits[6:4] */
 	val = FIELD_GET(TRCACATRn_CONTEXT_MASK, config->addr_acc[idx]);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1238,12 +1238,12 @@ static ssize_t addr_context_store(struct device *dev,
 		     drvdata->numcidc : drvdata->numvmidc))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* clear context ID comparator bits[6:4] */
 	config->addr_acc[idx] &= ~TRCACATRn_CONTEXT_MASK;
 	config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_CONTEXT_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_context);
@@ -1257,10 +1257,10 @@ static ssize_t addr_exlevel_s_ns_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	val = FIELD_GET(TRCACATRn_EXLEVEL_MASK, config->addr_acc[idx]);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1279,12 +1279,12 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
 	if (val & ~(TRCACATRn_EXLEVEL_MASK >> __bf_shf(TRCACATRn_EXLEVEL_MASK)))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8], bit[15] is res0 */
 	config->addr_acc[idx] &= ~TRCACATRn_EXLEVEL_MASK;
 	config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_EXLEVEL_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_exlevel_s_ns);
@@ -1307,7 +1307,7 @@ static ssize_t addr_cmp_view_show(struct device *dev,
 	int size = 0;
 	bool exclude = false;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	addr_v = config->addr_val[idx];
 	addr_ctrl = config->addr_acc[idx];
@@ -1322,7 +1322,7 @@ static ssize_t addr_cmp_view_show(struct device *dev,
 		}
 		exclude = config->viiectlr & BIT(idx / 2 + 16);
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	if (addr_type) {
 		size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] %s %#lx", idx,
 				 addr_type_names[addr_type], addr_v);
@@ -1366,9 +1366,9 @@ static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
 	if (!drvdata->nr_pe_cmp)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->vipcssctlr = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vinst_pe_cmp_start_stop);
@@ -1402,9 +1402,9 @@ static ssize_t seq_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->seq_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(seq_idx);
@@ -1448,10 +1448,10 @@ static ssize_t seq_event_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->seq_idx;
 	val = config->seq_ctrl[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1467,11 +1467,11 @@ static ssize_t seq_event_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->seq_idx;
 	/* Seq control has two masks B[15:8] F[7:0] */
 	config->seq_ctrl[idx] = val & 0xFFFF;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(seq_event);
@@ -1535,9 +1535,9 @@ static ssize_t cntr_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->cntr_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntr_idx);
@@ -1551,10 +1551,10 @@ static ssize_t cntrldvr_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	val = config->cntrldvr[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1572,10 +1572,10 @@ static ssize_t cntrldvr_store(struct device *dev,
 	if (val > ETM_CNTR_MAX_VAL)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntrldvr[idx] = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntrldvr);
@@ -1589,10 +1589,10 @@ static ssize_t cntr_val_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	val = config->cntr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1610,10 +1610,10 @@ static ssize_t cntr_val_store(struct device *dev,
 	if (val > ETM_CNTR_MAX_VAL)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntr_val[idx] = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntr_val);
@@ -1627,10 +1627,10 @@ static ssize_t cntr_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	val = config->cntr_ctrl[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1646,10 +1646,10 @@ static ssize_t cntr_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntr_ctrl[idx] = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntr_ctrl);
@@ -1687,9 +1687,9 @@ static ssize_t res_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->res_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(res_idx);
@@ -1703,10 +1703,10 @@ static ssize_t res_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->res_idx;
 	val = config->res_ctrl[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1722,7 +1722,7 @@ static ssize_t res_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->res_idx;
 	/* For odd idx pair inversal bit is RES0 */
 	if (idx % 2 != 0)
@@ -1732,7 +1732,7 @@ static ssize_t res_ctrl_store(struct device *dev,
 				       TRCRSCTLRn_INV |
 				       TRCRSCTLRn_GROUP_MASK |
 				       TRCRSCTLRn_SELECT_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(res_ctrl);
@@ -1761,9 +1761,9 @@ static ssize_t sshot_idx_store(struct device *dev,
 	if (val >= drvdata->nr_ss_cmp)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->ss_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(sshot_idx);
@@ -1776,9 +1776,9 @@ static ssize_t sshot_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = config->ss_ctrl[config->ss_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1794,12 +1794,12 @@ static ssize_t sshot_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ss_idx;
 	config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
 	/* must clear bit 31 in related status register on programming */
 	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(sshot_ctrl);
@@ -1811,9 +1811,9 @@ static ssize_t sshot_status_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = config->ss_status[config->ss_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 static DEVICE_ATTR_RO(sshot_status);
@@ -1826,9 +1826,9 @@ static ssize_t sshot_pe_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = config->ss_pe_cmp[config->ss_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1844,12 +1844,12 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ss_idx;
 	config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
 	/* must clear bit 31 in related status register on programming */
 	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(sshot_pe_ctrl);
@@ -1883,9 +1883,9 @@ static ssize_t ctxid_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->ctxid_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_idx);
@@ -1906,10 +1906,10 @@ static ssize_t ctxid_pid_show(struct device *dev,
 	if (task_active_pid_ns(current) != &init_pid_ns)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ctxid_idx;
 	val = (unsigned long)config->ctxid_pid[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1944,10 +1944,10 @@ static ssize_t ctxid_pid_store(struct device *dev,
 	if (kstrtoul(buf, 16, &pid))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ctxid_idx;
 	config->ctxid_pid[idx] = (u64)pid;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_pid);
@@ -1967,10 +1967,10 @@ static ssize_t ctxid_masks_show(struct device *dev,
 	if (task_active_pid_ns(current) != &init_pid_ns)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val1 = config->ctxid_mask0;
 	val2 = config->ctxid_mask1;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
 }
 
@@ -2003,7 +2003,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
 	if ((drvdata->numcidc > 4) && (nr_inputs != 2))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/*
 	 * each byte[0..3] controls mask value applied to ctxid
 	 * comparator[0..3]
@@ -2075,7 +2075,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
 			mask >>= 0x8;
 	}
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_masks);
@@ -2109,9 +2109,9 @@ static ssize_t vmid_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->vmid_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vmid_idx);
@@ -2131,9 +2131,9 @@ static ssize_t vmid_val_show(struct device *dev,
 	if (!task_is_in_init_pid_ns(current))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = (unsigned long)config->vmid_val[config->vmid_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -2161,9 +2161,9 @@ static ssize_t vmid_val_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->vmid_val[config->vmid_idx] = (u64)val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vmid_val);
@@ -2182,10 +2182,10 @@ static ssize_t vmid_masks_show(struct device *dev,
 	if (!task_is_in_init_pid_ns(current))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val1 = config->vmid_mask0;
 	val2 = config->vmid_mask1;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
 }
 
@@ -2217,7 +2217,7 @@ static ssize_t vmid_masks_store(struct device *dev,
 	if ((drvdata->numvmidc > 4) && (nr_inputs != 2))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/*
 	 * each byte[0..3] controls mask value applied to vmid
@@ -2290,7 +2290,7 @@ static ssize_t vmid_masks_store(struct device *dev,
 		else
 			mask >>= 0x8;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vmid_masks);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 9e9165f62e81..366f8f23a3e5 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -989,7 +989,7 @@ struct etmv4_drvdata {
 	struct clk			*pclk;
 	void __iomem			*base;
 	struct coresight_device		*csdev;
-	spinlock_t			spinlock;
+	raw_spinlock_t			spinlock;
 	int				cpu;
 	u8				arch;
 	u8				nr_pe;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Mon Dec 16 03:50:06 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Mon, 16 Dec 2024 11:50:06 +0000
Subject: [PATCH v3 9/9] coresight/ultrasoc: change cti_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <20241216115006.415861-10-yeoreum.yun@arm.com>

In ultrasoc-smb drivers, smb_drv_data->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since smb__drv_data->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type smb_drv_data->spinlock in ultrasoc-smb drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/ultrasoc-smb.c | 12 ++++++------
 drivers/hwtracing/coresight/ultrasoc-smb.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index dc3c9504dd7c..26cfc939e5bd 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -98,7 +98,7 @@ static int smb_open(struct inode *inode, struct file *file)
 	struct smb_drv_data *drvdata = container_of(file->private_data,
 					struct smb_drv_data, miscdev);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	if (drvdata->reading)
 		return -EBUSY;
@@ -152,7 +152,7 @@ static int smb_release(struct inode *inode, struct file *file)
 	struct smb_drv_data *drvdata = container_of(file->private_data,
 					struct smb_drv_data, miscdev);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 	drvdata->reading = false;
 
 	return 0;
@@ -245,7 +245,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 	int ret = 0;
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	/* Do nothing, the trace data is reading by other interface now */
 	if (drvdata->reading)
@@ -280,7 +280,7 @@ static int smb_disable(struct coresight_device *csdev)
 {
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	if (drvdata->reading)
 		return -EBUSY;
@@ -378,7 +378,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev,
 	if (!buf)
 		return 0;
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	/* Don't do anything if another tracer is using this sink. */
 	if (csdev->refcnt != 1)
@@ -563,7 +563,7 @@ static int smb_probe(struct platform_device *pdev)
 
 	smb_reset_buffer(drvdata);
 	platform_set_drvdata(pdev, drvdata);
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	drvdata->pid = -1;
 
 	ret = smb_register_sink(pdev, drvdata);
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing/coresight/ultrasoc-smb.h
index a91d39cfccb8..c4c111275627 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.h
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.h
@@ -115,7 +115,7 @@ struct smb_drv_data {
 	struct coresight_device	*csdev;
 	struct smb_data_buffer sdb;
 	struct miscdevice miscdev;
-	spinlock_t spinlock;
+	raw_spinlock_t spinlock;
 	bool reading;
 	pid_t pid;
 };
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From daniel.machon at microchip.com  Mon Dec 16 04:10:40 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Mon, 16 Dec 2024 12:10:40 +0000
Subject: [PATCH net-next v4 6/9] net: sparx5: verify RGMII speeds
In-Reply-To: <Z1yPq6OEziTNjWHK@shell.armlinux.org.uk>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
 <20241213-sparx5-lan969x-switch-driver-4-v4-6-d1a72c9c4714@microchip.com>
 <Z1yPq6OEziTNjWHK@shell.armlinux.org.uk>
Message-ID: <20241216121040.2dpxb7mv6h3u3r42@DEN-DL-M70577>

> On Fri, Dec 13, 2024 at 02:41:05PM +0100, Daniel Machon wrote:
> > When doing a port config, we verify the port speed against the PHY mode
> > and supported speeds of that PHY mode. Add checks for the four RGMII phy
> > modes: RGMII, RGMII_ID, RGMII_TXID and RGMII_RXID.
> >
> > Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
> > Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
> > Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
> 
> You do realise that phylink knows what speeds each interface supports
> (see phylink_get_capabilities()) and restricts the media advertisement
> to ensure that ethtool link modes that can't be supported by the MAC
> capabilities and set of interfaces that would be used are not
> advertised.
> 
> This should mean none of your verification ever triggers. If it does,
> then I'd like to know about it.

Yes, I agree. Having an extra look at phylink, these checks should not trigger
at all.

As it is, the default switch case is to throw an error, so without this
addition, the sparx5_port_verify_speed() function will fail when the PHY mode
is any of RGMII{_ID,_TXID,_RXID}. This patch just follows the established
pattern of adding the new PHY mode and checking the speed. TBH, I think that
all the checks in this function can be removed entirely, but that is something
I would like to verify and follow up on in a separate series, if that is OK? 

Thanks.

/Daniel



From broonie at kernel.org  Mon Dec 16 04:17:54 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 12:17:54 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <87a5cysfci.wl-maz@kernel.org>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
 <87a5cysfci.wl-maz@kernel.org>
Message-ID: <709a0e75-0d0c-4bff-b9fd-3bbb55c97bd5@sirena.org.uk>

On Sat, Dec 14, 2024 at 10:56:13AM +0000, Marc Zyngier wrote:

> I don't understand the need to single out SMIDR_EL1. It seems to only
> make things even more fragile than they already are by adding more
> synchronisation phases.

> Why isn't the following a good enough fix? It makes it plain that
> boot_cpu_data is only a copy of CPU0's initial boot state.

That would work but it's not clear to me that that is what the intent is
here.  The current ordering seemed like a strange enough decision to be
deliberate, though I couldn't identify the reasoning.
-------------- 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/20241216/684e9a22/attachment.sig>

From laurentiumihalcea111 at gmail.com  Mon Dec 16 04:23:50 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Mon, 16 Dec 2024 14:23:50 +0200
Subject: [PATCH v2 4/5] ASoC: SOF: imx: add driver for imx95
In-Reply-To: <Z1r9hWH1ioR5vI5H@lizhi-Precision-Tower-5810>
References: <20241113195240.3699-1-laurentiumihalcea111@gmail.com>
 <20241113195240.3699-5-laurentiumihalcea111@gmail.com>
 <ZzUJQCeWclsrr/lr@lizhi-Precision-Tower-5810>
 <c47710a5-7e53-48b1-bd6b-c0123865aee5@gmail.com>
 <Z1r9hWH1ioR5vI5H@lizhi-Precision-Tower-5810>
Message-ID: <c3c9389f-5116-4a5f-99f6-1b37c1e8c457@gmail.com>



On 12/12/2024 5:13 PM, Frank Li wrote:
> On Thu, Dec 12, 2024 at 01:11:29PM +0200, Laurentiu Mihalcea wrote:
>>
>> On 11/13/2024 10:17 PM, Frank Li wrote:
>>> On Wed, Nov 13, 2024 at 02:52:39PM -0500, Laurentiu Mihalcea wrote:
>>>> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>>>>
>>>> Add SOF driver for imx95.
>>>>
>>>> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>>>> ---
>>>>  sound/soc/sof/imx/Kconfig  |   8 +
>>>>  sound/soc/sof/imx/Makefile |   2 +
>>>>  sound/soc/sof/imx/imx95.c  | 401 +++++++++++++++++++++++++++++++++++++
>>> why not reused exist one? look likes simular.
>>>
>>> Frank
>> the SOF drivers do indeed have some similarities, but each of them has their own quirks which IMO makes it a bit harder to add the 95 support. We need to figure out the common parts and then move them to imx-common, but I believe this can be solved incrementally.
> You should create common part firstly, then implement equal function with
> existed part. Finially add imx95 part.
>
> Frank

Yes, I'm aware of how this _should_ be done, but, like I mentioned, the change is not trivial and will
require tweaking the other drivers as well. As such, I'd like to get the 95 support in as-is firstly.

Are there any other thoughts on this?

>
>>>>  3 files changed, 411 insertions(+)
>>>>  create mode 100644 sound/soc/sof/imx/imx95.c
>>>>
>>>> diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig
>>>> index 4751b04d5e6f..51a70a193533 100644
>>>> --- a/sound/soc/sof/imx/Kconfig
>>>> +++ b/sound/soc/sof/imx/Kconfig
>>>> @@ -50,4 +50,12 @@ config SND_SOC_SOF_IMX8ULP
>>>>  	  Say Y if you have such a device.
>>>>  	  If unsure select "N".
>>>>
>>>> +config SND_SOC_SOF_IMX95
>>>> +	tristate "SOF support for i.MX95"
>>>> +	depends on IMX_DSP
>>>> +	help
>>>> +	  This adds support for Sound Open Firmware for NXP i.MX95 platforms.
>>>> +	  Say Y if you have such a device.
>>>> +	  If unsure select "N".
>>>> +
>>>>  endif ## SND_SOC_SOF_IMX_TOPLEVEL
>>>> diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile
>>>> index be0bf0736dfa..715ac3798668 100644
>>>> --- a/sound/soc/sof/imx/Makefile
>>>> +++ b/sound/soc/sof/imx/Makefile
>>>> @@ -2,10 +2,12 @@
>>>>  snd-sof-imx8-y := imx8.o
>>>>  snd-sof-imx8m-y := imx8m.o
>>>>  snd-sof-imx8ulp-y := imx8ulp.o
>>>> +snd-sof-imx95-y := imx95.o
>>>>
>>>>  snd-sof-imx-common-y := imx-common.o
>>>>
>>>>  obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o
>>>>  obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o
>>>>  obj-$(CONFIG_SND_SOC_SOF_IMX8ULP) += snd-sof-imx8ulp.o
>>>> +obj-$(CONFIG_SND_SOC_SOF_IMX95) += snd-sof-imx95.o
>>>>  obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o
>>>> diff --git a/sound/soc/sof/imx/imx95.c b/sound/soc/sof/imx/imx95.c
>>>> new file mode 100644
>>>> index 000000000000..5a0e44f5bd48
>>>> --- /dev/null
>>>> +++ b/sound/soc/sof/imx/imx95.c
>>>> @@ -0,0 +1,401 @@
>>>> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
>>>> +/*
>>>> + * Copyright 2024 NXP
>>>> + */
>>>> +
>>>> +#include <linux/arm-smccc.h>
>>>> +#include <linux/clk.h>
>>>> +#include <linux/firmware/imx/dsp.h>
>>>> +#include <linux/module.h>
>>>> +#include <linux/of_platform.h>
>>>> +#include <linux/of_reserved_mem.h>
>>>> +#include <sound/sof.h>
>>>> +
>>>> +#include "../sof-of-dev.h"
>>>> +#include "../ops.h"
>>>> +
>>>> +#define IMX_SIP_SRC 0xC2000005
>>>> +#define IMX_SIP_SRC_M_RESET_ADDR_SET 0x03
>>>> +
>>>> +#define IMX95_CPU_VEC_FLAGS_BOOT BIT(29)
>>>> +
>>>> +#define IMX_SIP_LMM 0xC200000F
>>>> +#define IMX_SIP_LMM_BOOT 0x0
>>>> +#define IMX_SIP_LMM_SHUTDOWN 0x1
>>>> +
>>>> +#define IMX95_M7_LM_ID 0x1
>>>> +
>>>> +#define MBOX_DSPBOX_OFFSET 0x1000
>>>> +#define MBOX_WINDOW_OFFSET 0x6000000
>>>> +
>>>> +struct imx95_priv {
>>>> +	struct platform_device *ipc_dev;
>>>> +	struct imx_dsp_ipc *ipc_handle;
>>>> +	resource_size_t bootaddr;
>>>> +};
>>>> +
>>>> +static void imx95_ipc_handle_reply(struct imx_dsp_ipc *ipc)
>>>> +{
>>>> +	unsigned long flags;
>>>> +	struct snd_sof_dev *sdev = imx_dsp_get_data(ipc);
>>>> +
>>>> +	spin_lock_irqsave(&sdev->ipc_lock, flags);
>>>> +	snd_sof_ipc_process_reply(sdev, 0);
>>>> +	spin_unlock_irqrestore(&sdev->ipc_lock, flags);
>>>> +}
>>>> +
>>>> +static void imx95_ipc_handle_request(struct imx_dsp_ipc *ipc)
>>>> +{
>>>> +	snd_sof_ipc_msgs_rx(imx_dsp_get_data(ipc));
>>>> +}
>>>> +
>>>> +static struct imx_dsp_ops ipc_ops = {
>>>> +	.handle_reply = imx95_ipc_handle_reply,
>>>> +	.handle_request = imx95_ipc_handle_request,
>>>> +};
>>>> +
>>>> +static int imx95_disable_enable_core(bool enable)
>>>> +{
>>>> +	struct arm_smccc_res res;
>>>> +
>>>> +	if (enable)
>>>> +		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_BOOT, IMX95_M7_LM_ID,
>>>> +			      0, 0, 0, 0, 0, &res);
>>>> +	else
>>>> +		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_SHUTDOWN, IMX95_M7_LM_ID,
>>>> +			      0, 0, 0, 0, 0, &res);
>>>> +
>>>> +	return res.a0;
>>>> +}
>>>> +
>>>> +static int imx95_run(struct snd_sof_dev *sdev)
>>>> +{
>>>> +	return imx95_disable_enable_core(true);
>>>> +}
>>>> +
>>>> +static int imx95_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
>>>> +{
>>>> +	struct imx95_priv *priv = sdev->pdata->hw_pdata;
>>>> +
>>>> +	sof_mailbox_write(sdev, sdev->host_box.offset,
>>>> +			  msg->msg_data, msg->msg_size);
>>>> +
>>>> +	imx_dsp_ring_doorbell(priv->ipc_handle, 0);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int imx95_get_mailbox_offset(struct snd_sof_dev *sdev)
>>>> +{
>>>> +	return MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
>>>> +}
>>>> +
>>>> +static int imx95_get_bar_index(struct snd_sof_dev *sdev, u32 type)
>>>> +{
>>>> +	switch (type) {
>>>> +	case SOF_FW_BLK_TYPE_SRAM:
>>>> +		return type;
>>>> +	default:
>>>> +		return -EINVAL;
>>>> +	}
>>>> +}
>>>> +
>>>> +static int imx95_get_window_offset(struct snd_sof_dev *sdev, u32 id)
>>>> +{
>>>> +	return MBOX_WINDOW_OFFSET;
>>>> +}
>>>> +
>>>> +static int imx95_set_power_state(struct snd_sof_dev *sdev,
>>>> +				 const struct sof_dsp_power_state *target_state)
>>>> +{
>>>> +	sdev->dsp_power_state = *target_state;
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int imx95_suspend_resume(struct snd_sof_dev *sdev, bool suspend)
>>>> +{
>>>> +	struct imx95_priv *priv;
>>>> +	int ret, i;
>>>> +
>>>> +	priv = sdev->pdata->hw_pdata;
>>>> +
>>>> +	if (suspend) {
>>>> +		ret = imx95_disable_enable_core(false);
>>>> +		if (ret) {
>>>> +			dev_err(sdev->dev, "failed to stop core\n");
>>>> +			return ret;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
>>>> +		if (suspend)
>>>> +			imx_dsp_free_channel(priv->ipc_handle, i);
>>>> +		else
>>>> +			imx_dsp_request_channel(priv->ipc_handle, i);
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int imx95_runtime_resume(struct snd_sof_dev *sdev)
>>>> +{
>>>> +	int ret;
>>>> +	const struct sof_dsp_power_state target_state = {
>>>> +		.state = SOF_DSP_PM_D0,
>>>> +	};
>>>> +
>>>> +	ret = imx95_suspend_resume(sdev, false);
>>>> +	if (ret < 0) {
>>>> +		dev_err(sdev->dev, "failed to runtime resume: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
>>>> +}
>>>> +
>>>> +static int imx95_resume(struct snd_sof_dev *sdev)
>>>> +{
>>>> +	int ret;
>>>> +	const struct sof_dsp_power_state target_state = {
>>>> +		.state = SOF_DSP_PM_D0,
>>>> +	};
>>>> +
>>>> +	ret = imx95_suspend_resume(sdev, false);
>>>> +	if (ret < 0) {
>>>> +		dev_err(sdev->dev, "failed to resume: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	if (pm_runtime_suspended(sdev->dev)) {
>>>> +		pm_runtime_disable(sdev->dev);
>>>> +		pm_runtime_set_active(sdev->dev);
>>>> +		pm_runtime_mark_last_busy(sdev->dev);
>>>> +		pm_runtime_enable(sdev->dev);
>>>> +		pm_runtime_idle(sdev->dev);
>>>> +	}
>>>> +
>>>> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
>>>> +}
>>>> +
>>>> +static int imx95_runtime_suspend(struct snd_sof_dev *sdev)
>>>> +{
>>>> +	int ret;
>>>> +	const struct sof_dsp_power_state target_state = {
>>>> +		.state = SOF_DSP_PM_D3,
>>>> +	};
>>>> +
>>>> +	ret = imx95_suspend_resume(sdev, true);
>>>> +	if (ret < 0) {
>>>> +		dev_err(sdev->dev, "failed to runtime suspend: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
>>>> +}
>>>> +
>>>> +static int imx95_suspend(struct snd_sof_dev *sdev, unsigned int target_state)
>>>> +{
>>>> +	int ret;
>>>> +	const struct sof_dsp_power_state target_power_state = {
>>>> +		.state = target_state,
>>>> +	};
>>>> +
>>>> +	if (!pm_runtime_suspended(sdev->dev)) {
>>>> +		ret = imx95_suspend_resume(sdev, true);
>>>> +		if (ret < 0) {
>>>> +			dev_err(sdev->dev, "failed to suspend: %d\n", ret);
>>>> +			return ret;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	return snd_sof_dsp_set_power_state(sdev, &target_power_state);
>>>> +}
>>>> +
>>>> +static struct snd_soc_dai_driver imx95_dai[] = {
>>>> +	{
>>>> +		.name = "sai3",
>>>> +		.playback = {
>>>> +			.channels_min = 1,
>>>> +			.channels_max = 32,
>>>> +		},
>>>> +		.capture = {
>>>> +			.channels_min = 1,
>>>> +			.channels_max = 32,
>>>> +		},
>>>> +	},
>>>> +};
>>>> +
>>>> +static int imx95_probe(struct snd_sof_dev *sdev)
>>>> +{
>>>> +	struct platform_device *pdev;
>>>> +	struct imx95_priv *priv;
>>>> +	struct resource *res;
>>>> +	struct arm_smccc_res smc_ret;
>>>> +	int ret;
>>>> +
>>>> +	pdev = container_of(sdev->dev, struct platform_device, dev);
>>>> +
>>>> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>>>> +	if (!priv)
>>>> +		return dev_err_probe(&pdev->dev, -ENOMEM, "failed to alloc priv\n");
>>>> +
>>>> +	sdev->pdata->hw_pdata = priv;
>>>> +
>>>> +	/* map SRAM */
>>>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>>> +	if (!res)
>>>> +		return dev_err_probe(&pdev->dev, -ENODEV,
>>>> +				     "failed to fetch SRAM region\n");
>>>> +
>>>> +	sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap(&pdev->dev, res->start,
>>>> +						       resource_size(res));
>>>> +	if (IS_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]))
>>>> +		return dev_err_probe(&pdev->dev,
>>>> +				     PTR_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]),
>>>> +				     "failed to map SRAM region\n");
>>>> +
>>>> +	sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
>>>> +	sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
>>>> +	sdev->dsp_box.offset = MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
>>>> +	priv->bootaddr = res->start;
>>>> +
>>>> +	ret = of_reserved_mem_device_init(sdev->dev);
>>>> +	if (ret)
>>>> +		return dev_err_probe(&pdev->dev, ret,
>>>> +				     "failed to bind DMA region\n");
>>>> +
>>>> +	priv->ipc_dev = platform_device_register_data(&pdev->dev, "imx-dsp",
>>>> +						      PLATFORM_DEVID_NONE,
>>>> +						      pdev, sizeof(*pdev));
>>>> +	if (IS_ERR(priv->ipc_dev))
>>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->ipc_dev),
>>>> +				     "failed to create IPC device\n");
>>>> +
>>>> +	priv->ipc_handle = dev_get_drvdata(&priv->ipc_dev->dev);
>>>> +	if (!priv->ipc_handle) {
>>>> +		ret = -EPROBE_DEFER;
>>>> +		dev_err(&pdev->dev, "failed to fetch ipc handle\n");
>>>> +		goto err_unregister_ipc_dev;
>>>> +	}
>>>> +
>>>> +	priv->ipc_handle->ops = &ipc_ops;
>>>> +	imx_dsp_set_data(priv->ipc_handle, sdev);
>>>> +
>>>> +	/* set core boot reset address */
>>>> +	arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M_RESET_ADDR_SET, priv->bootaddr,
>>>> +		      IMX95_CPU_VEC_FLAGS_BOOT, 0, 0, 0, 0, &smc_ret);
>>>> +	if ((int)smc_ret.a0 < 0) {
>>>> +		ret = smc_ret.a0;
>>>> +		dev_err(&pdev->dev, "failed to set boot address: %d", ret);
>>>> +		goto err_unregister_ipc_dev;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +
>>>> +err_unregister_ipc_dev:
>>>> +	platform_device_unregister(priv->ipc_dev);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +static void imx95_remove(struct snd_sof_dev *sdev)
>>>> +{
>>>> +	struct imx95_priv *priv;
>>>> +
>>>> +	priv = sdev->pdata->hw_pdata;
>>>> +
>>>> +	if (imx95_disable_enable_core(false))
>>>> +		dev_err(sdev->dev, "failed to stop core\n");
>>>> +
>>>> +	platform_device_unregister(priv->ipc_dev);
>>>> +}
>>>> +
>>>> +static const struct snd_sof_dsp_ops sof_imx95_ops = {
>>>> +	.probe = imx95_probe,
>>>> +	.remove = imx95_remove,
>>>> +
>>>> +	/* mandatory "DSP" ops */
>>>> +	.run = imx95_run,
>>>> +	.block_read = sof_block_read,
>>>> +	.block_write = sof_block_write,
>>>> +	.send_msg = imx95_send_msg,
>>>> +	.load_firmware = snd_sof_load_firmware_memcpy,
>>>> +	.ipc_msg_data = sof_ipc_msg_data,
>>>> +
>>>> +	.mailbox_read = sof_mailbox_read,
>>>> +	.mailbox_write = sof_mailbox_write,
>>>> +
>>>> +	.get_mailbox_offset = imx95_get_mailbox_offset,
>>>> +	.get_bar_index = imx95_get_bar_index,
>>>> +	.get_window_offset = imx95_get_window_offset,
>>>> +
>>>> +	.pcm_open = sof_stream_pcm_open,
>>>> +	.pcm_close = sof_stream_pcm_close,
>>>> +	.set_stream_data_offset = sof_set_stream_data_offset,
>>>> +
>>>> +	.runtime_suspend = imx95_runtime_suspend,
>>>> +	.runtime_resume = imx95_runtime_resume,
>>>> +
>>>> +	.resume = imx95_resume,
>>>> +	.suspend = imx95_suspend,
>>>> +
>>>> +	.set_power_state = imx95_set_power_state,
>>>> +
>>>> +	.drv = imx95_dai,
>>>> +	.num_drv = ARRAY_SIZE(imx95_dai),
>>>> +
>>>> +	.hw_info = SNDRV_PCM_INFO_MMAP |
>>>> +		   SNDRV_PCM_INFO_MMAP_VALID |
>>>> +		   SNDRV_PCM_INFO_INTERLEAVED |
>>>> +		   SNDRV_PCM_INFO_PAUSE |
>>>> +		   SNDRV_PCM_INFO_BATCH |
>>>> +		   SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
>>>> +};
>>>> +
>>>> +static struct snd_sof_of_mach sof_imx95_machs[] = {
>>>> +	{
>>>> +		.compatible = "fsl,imx95-19x19-evk",
>>>> +		.sof_tplg_filename = "sof-imx95-wm8962.tplg",
>>>> +		.drv_name = "asoc-audio-graph-card2",
>>>> +	},
>>>> +	{
>>>> +	},
>>>> +};
>>>> +
>>>> +static struct sof_dev_desc sof_of_imx95_desc = {
>>>> +	.of_machines = sof_imx95_machs,
>>>> +	.ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
>>>> +	.ipc_default = SOF_IPC_TYPE_3,
>>>> +	.default_fw_path = {
>>>> +		[SOF_IPC_TYPE_3] = "imx/sof",
>>>> +	},
>>>> +	.default_tplg_path = {
>>>> +		[SOF_IPC_TYPE_3] = "imx/sof-tplg",
>>>> +	},
>>>> +	.default_fw_filename = {
>>>> +		[SOF_IPC_TYPE_3] = "sof-imx95.ri",
>>>> +	},
>>>> +	.ops = &sof_imx95_ops,
>>>> +};
>>>> +
>>>> +static const struct of_device_id sof_of_imx95_ids[] = {
>>>> +	{ .compatible = "fsl,imx95-cm7-sof", .data = &sof_of_imx95_desc },
>>>> +	{ },
>>>> +};
>>>> +MODULE_DEVICE_TABLE(of, sof_of_imx95_ids);
>>>> +
>>>> +static struct platform_driver snd_sof_of_imx95_driver = {
>>>> +	.probe = sof_of_probe,
>>>> +	.remove = sof_of_remove,
>>>> +	.driver = {
>>>> +		.name = "sof-audio-of-imx95",
>>>> +		.pm = &sof_of_pm,
>>>> +		.of_match_table = sof_of_imx95_ids,
>>>> +	},
>>>> +};
>>>> +module_platform_driver(snd_sof_of_imx95_driver);
>>>> +
>>>> +MODULE_LICENSE("Dual BSD/GPL");
>>>> +MODULE_DESCRIPTION("SOF support for i.MX95 platforms");
>>>> +MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>");
>>>> --
>>>> 2.34.1
>>>>



From mark.rutland at arm.com  Mon Dec 16 04:38:17 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 16 Dec 2024 12:38:17 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <87a5cysfci.wl-maz@kernel.org>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
 <87a5cysfci.wl-maz@kernel.org>
Message-ID: <Z2AfOZ82QG_ukWry@J2N7QTR9R3>

On Sat, Dec 14, 2024 at 10:56:13AM +0000, Marc Zyngier wrote:
> [+ Mark]
> On Sat, 14 Dec 2024 00:52:08 +0000,
> Mark Brown <broonie at kernel.org> wrote:
> > 
> > In commit 892f7237b3ff ("arm64: Delay initialisation of
> > cpuinfo_arm64::reg_{zcr,smcr}") we moved access to ZCR, SMCR and SMIDR
> > later in the boot process in order to ensure that we don't attempt to
> > interact with them if SVE or SME is disabled on the command line.
> > Unfortunately when initialising the boot CPU in init_cpu_features() we work
> > on a copy of the struct cpuinfo_arm64 for the boot CPU used only during
> > boot, not the percpu copy used by the sysfs code.
> > 
> > Fix this by moving the handling for SMIDR_EL1 for the boot CPU to
> > cpuinfo_store_boot_cpu() so it can operate on the percpu copy of the data.
> > This reduces the potential for error that could come from having both the
> > percpu and boot CPU copies in init_cpu_features().
> > 
> > This issue wasn't apparent when testing on emulated platforms that do not
> > report values in this ID register.
> > 
> > Fixes: 892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")
> > Signed-off-by: Mark Brown <broonie at kernel.org>
> > Cc: stable at vger.kernel.org
> > ---
> >  arch/arm64/kernel/cpufeature.c |  6 ------
> >  arch/arm64/kernel/cpuinfo.c    | 11 +++++++++++
> >  2 files changed, 11 insertions(+), 6 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > index 6ce71f444ed84f9056196bb21bbfac61c9687e30..b88102fd2c20f77e25af6df513fda09a484e882e 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -1167,12 +1167,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
> >  	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
> >  		unsigned long cpacr = cpacr_save_enable_kernel_sme();
> >  
> > -		/*
> > -		 * We mask out SMPS since even if the hardware
> > -		 * supports priorities the kernel does not at present
> > -		 * and we block access to them.
> > -		 */
> > -		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
> >  		vec_init_vq_map(ARM64_VEC_SME);
> >  
> >  		cpacr_restore(cpacr);
> > diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> > index d79e88fccdfce427507e7a34c5959ce6309cbd12..b7d403da71e5a01ed3943eb37e7a00af238771a2 100644
> > --- a/arch/arm64/kernel/cpuinfo.c
> > +++ b/arch/arm64/kernel/cpuinfo.c
> > @@ -499,4 +499,15 @@ void __init cpuinfo_store_boot_cpu(void)
> >  
> >  	boot_cpu_data = *info;
> >  	init_cpu_features(&boot_cpu_data);
> > +
> > +	/* SMIDR_EL1 needs to be stored in the percpu data for sysfs */
> > +	if (IS_ENABLED(CONFIG_ARM64_SME) &&
> > +	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
> > +		/*
> > +		 * We mask out SMPS since even if the hardware
> > +		 * supports priorities the kernel does not at present
> > +		 * and we block access to them.
> > +		 */
> > +		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
> > +	}
> >  }
> 
> I don't understand the need to single out SMIDR_EL1. It seems to only
> make things even more fragile than they already are by adding more
> synchronisation phases.
> 
> Why isn't the following a good enough fix? It makes it plain that
> boot_cpu_data is only a copy of CPU0's initial boot state.
> 
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index d79e88fccdfce..0cbb42fd48850 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -497,6 +497,6 @@ void __init cpuinfo_store_boot_cpu(void)
>  	struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0);
>  	__cpuinfo_store_cpu(info);
>  
> +	init_cpu_features(info);
>  	boot_cpu_data = *info;
> -	init_cpu_features(&boot_cpu_data);
>  }

I think that change in isolation is fine, but I don't think that's the
right fix.

I think that what we did in commit:

   892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")

... introduces an anti-pattern that'd be nice to avoid. That broke the
existing split of __cpuinfo_store_cpu() and init_cpu_features(), where
the former read the ID regs, and the latter set up the features
*without* altering the copy of the ID regs that was read. i.e.
init_cpu_features() shouldn't write to its info argument at all.

I understand that we have to do something as a bodge for broken FW which
traps SME, but I'd much rather we did that within __cpuinfo_store_cpu().

Can we add something to check whether SME was disabled on the command
line, and use that in __cpuinfo_store_cpu(), effectively reverting
892f7237b3ff?

Mark.


From mark.rutland at arm.com  Mon Dec 16 04:44:14 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 16 Dec 2024 12:44:14 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <709a0e75-0d0c-4bff-b9fd-3bbb55c97bd5@sirena.org.uk>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
 <87a5cysfci.wl-maz@kernel.org>
 <709a0e75-0d0c-4bff-b9fd-3bbb55c97bd5@sirena.org.uk>
Message-ID: <Z2Agntn52mY5bSTp@J2N7QTR9R3>

On Mon, Dec 16, 2024 at 12:17:54PM +0000, Mark Brown wrote:
> On Sat, Dec 14, 2024 at 10:56:13AM +0000, Marc Zyngier wrote:
> 
> > I don't understand the need to single out SMIDR_EL1. It seems to only
> > make things even more fragile than they already are by adding more
> > synchronisation phases.
> 
> > Why isn't the following a good enough fix? It makes it plain that
> > boot_cpu_data is only a copy of CPU0's initial boot state.
> 
> That would work but it's not clear to me that that is what the intent is
> here.  The current ordering seemed like a strange enough decision to be
> deliberate, though I couldn't identify the reasoning.

The original intent was that __cpuinfo_store_cpu() read *all* of a CPU's
implemented ID regs, and init_cpu_features() initialised the expected
system features based on the boot CPU's ID regs.

The expectation was that init_cpu_features() would only consume the
register values, and would not alter the cpuinfo_arm64 values, so the
order of:

	boot_cpu_data = *info;
	init_cpu_features(&boot_cpu_data);

... didn't matter either way, and using '&boot_cpu_data' was intended to
make it clear that the features were based on the boot CPU's info, even
if you just grepped for that and didn't see the surrounding context.

I think the real fix here is to move the reading back into
__cpuinfo_store_cpu(), but to have an explicit check that SME has been
disabled on the commandline, with a comment explaining that this is a
bodge for broken FW which traps the SME ID regs.

Mark.


From andre.draszik at linaro.org  Mon Dec 16 05:06:28 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Mon, 16 Dec 2024 13:06:28 +0000
Subject: [PATCH 3/4] arm64: dts: exynos: gs101-oriole: move common Pixel6 &
 6Pro parts into a .dtsi
In-Reply-To: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
Message-ID: <20241216-gs101-simplefb-v1-3-8ccad1830281@linaro.org>

In order to support Pixel 6 (Oriole) and Pixel 6 Pro (Raven) properly,
we have to be able to distinguish them properly as we add support for
more features.

For example, Raven has a larger display. There are other differences,
like battery design capacity, etc.

Move all the parts that are common for now into a gs101-raviole.dtsi,
and just leave the display related things in gs101-oriole.dts.

Raviole was chosen as the name because Google uses that when referring
to the combination of Oriole & Raven, keeping the familiar terminology.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
Note: MAINTAINERS doesn't need updating, it covers this whole directory
---
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 290 +-------------------
 .../boot/dts/exynos/google/gs101-raviole.dtsi      | 297 +++++++++++++++++++++
 2 files changed, 305 insertions(+), 282 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
index 4e1625e3fbb4..2bc9371cd42e 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
@@ -8,294 +8,20 @@
 
 /dts-v1/;
 
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/usb/pd.h>
-#include "gs101-pinctrl.h"
-#include "gs101.dtsi"
+#include "gs101-raviole.dtsi"
 
 / {
 	model = "Oriole";
 	compatible = "google,gs101-oriole", "google,gs101";
-
-	aliases {
-		serial0 = &serial_0;
-	};
-
-	chosen {
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges;
-
-		/* Bootloader expects bootargs specified otherwise it crashes */
-		bootargs = "";
-		stdout-path = &serial_0;
-
-		/* Use display framebuffer as setup by bootloader */
-		framebuffer0: framebuffer at fac00000 {
-			compatible = "simple-framebuffer";
-			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
-			width = <1080>;
-			height = <2400>;
-			stride = <(1080 * 4)>;
-			format = "a8r8g8b8";
-		};
-	};
-
-	gpio-keys {
-		compatible = "gpio-keys";
-		pinctrl-0 = <&key_voldown>, <&key_volup>, <&key_power>;
-		pinctrl-names = "default";
-
-		button-vol-down {
-			label = "KEY_VOLUMEDOWN";
-			linux,code = <KEY_VOLUMEDOWN>;
-			gpios = <&gpa7 3 GPIO_ACTIVE_LOW>;
-			wakeup-source;
-		};
-
-		button-vol-up {
-			label = "KEY_VOLUMEUP";
-			linux,code = <KEY_VOLUMEUP>;
-			gpios = <&gpa8 1 GPIO_ACTIVE_LOW>;
-			wakeup-source;
-		};
-
-		button-power {
-			label = "KEY_POWER";
-			linux,code = <KEY_POWER>;
-			gpios = <&gpa10 1 GPIO_ACTIVE_LOW>;
-			wakeup-source;
-		};
-	};
-
-	/* TODO: Remove this once PMIC is implemented  */
-	reg_placeholder: regulator-0 {
-		compatible = "regulator-fixed";
-		regulator-name = "placeholder_reg";
-	};
-
-	/* TODO: Remove this once S2MPG11 slave PMIC is implemented  */
-	ufs_0_fixed_vcc_reg: regulator-1 {
-		compatible = "regulator-fixed";
-		regulator-name = "ufs-vcc";
-		gpio = <&gpp0 1 GPIO_ACTIVE_HIGH>;
-		regulator-boot-on;
-		enable-active-high;
-	};
-
-	reserved-memory {
-		cont_splash_mem: splash at fac00000 {
-			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
-			no-map;
-		};
-	};
-};
-
-&ext_24_5m {
-	clock-frequency = <24576000>;
-};
-
-&ext_200m {
-	clock-frequency = <200000000>;
-};
-
-&hsi2c_8 {
-	status = "okay";
-
-	eeprom: eeprom at 50 {
-		compatible = "atmel,24c08";
-		reg = <0x50>;
-	};
-};
-
-&hsi2c_12 {
-	status = "okay";
-	/* TODO: add the devices once drivers exist */
-
-	usb-typec at 25 {
-		compatible = "maxim,max77759-tcpci", "maxim,max33359";
-		reg = <0x25>;
-		interrupts-extended = <&gpa8 2 IRQ_TYPE_LEVEL_LOW>;
-		pinctrl-0 = <&typec_int>;
-		pinctrl-names = "default";
-
-		connector {
-			compatible = "usb-c-connector";
-			label = "USB-C";
-			data-role = "dual";
-			power-role = "dual";
-			self-powered;
-			try-power-role = "sink";
-			op-sink-microwatt = <2600000>;
-			slow-charger-loop;
-			/*
-			 * max77759 operating in reverse boost mode (0xA) can
-			 * source up to 1.5A while extboost can only do ~1A.
-			 * Since extboost is the primary path, advertise 900mA.
-			 */
-			source-pdos = <PDO_FIXED(5000, 900,
-						 (PDO_FIXED_SUSPEND
-						  | PDO_FIXED_USB_COMM
-						  | PDO_FIXED_DATA_SWAP
-						  | PDO_FIXED_DUAL_ROLE))>;
-			sink-pdos = <PDO_FIXED(5000, 3000,
-					       (PDO_FIXED_DATA_SWAP
-						| PDO_FIXED_USB_COMM
-						| PDO_FIXED_HIGHER_CAP
-						| PDO_FIXED_DUAL_ROLE))
-				     PDO_FIXED(9000, 2200, 0)
-				     PDO_PPS_APDO(5000, 11000, 3000)>;
-			sink-vdos = <VDO_IDH(1, 1, IDH_PTYPE_PERIPH, 0,
-					     IDH_PTYPE_DFP_HOST, 2, 0x18d1)
-				     VDO_CERT(0x0)
-				     VDO_PRODUCT(0x4ee1, 0x0)
-				     VDO_UFP(UFP_VDO_VER1_2,
-					     (DEV_USB2_CAPABLE
-					      | DEV_USB3_CAPABLE),
-					     UFP_RECEPTACLE, 0,
-					     AMA_VCONN_NOT_REQ, 0,
-					     UFP_ALTMODE_NOT_SUPP,
-					     UFP_USB32_GEN1)
-				     /* padding */ 0
-				     VDO_DFP(DFP_VDO_VER1_1,
-					     (HOST_USB2_CAPABLE
-					      | HOST_USB3_CAPABLE),
-					     DFP_RECEPTACLE, 0)>;
-			sink-vdos-v1 = <VDO_IDH(1, 1, IDH_PTYPE_PERIPH, 0,
-						0, 0, 0x18d1)
-					VDO_CERT(0x0)
-					VDO_PRODUCT(0x4ee1, 0x0)>;
-			/*
-			 * Until bootloader is updated to set those two when
-			 * console is enabled, we disable PD here.
-			 */
-			pd-disable;
-			typec-power-opmode = "default";
-
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				port at 0 {
-					reg = <0>;
-
-					usbc0_orien_sw: endpoint {
-						remote-endpoint = <&usbdrd31_phy_orien_switch>;
-					};
-				};
-
-				port at 1 {
-					reg = <1>;
-
-					usbc0_role_sw: endpoint {
-						remote-endpoint = <&usbdrd31_dwc3_role_switch>;
-					};
-				};
-			};
-		};
-	};
-};
-
-&pinctrl_far_alive {
-	key_voldown: key-voldown-pins {
-		samsung,pins = "gpa7-3";
-		samsung,pin-function = <GS101_PIN_FUNC_EINT>;
-		samsung,pin-pud = <GS101_PIN_PULL_NONE>;
-		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
-	};
-
-	key_volup: key-volup-pins {
-		samsung,pins = "gpa8-1";
-		samsung,pin-function = <GS101_PIN_FUNC_EINT>;
-		samsung,pin-pud = <GS101_PIN_PULL_NONE>;
-		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
-	};
-
-	typec_int: typec-int-pins {
-		samsung,pins = "gpa8-2";
-		samsung,pin-function = <GS101_PIN_FUNC_EINT>;
-		samsung,pin-pud = <GS101_PIN_PULL_UP>;
-		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
-	};
-};
-
-&pinctrl_gpio_alive {
-	key_power: key-power-pins {
-		samsung,pins = "gpa10-1";
-		samsung,pin-function = <GS101_PIN_FUNC_EINT>;
-		samsung,pin-pud = <GS101_PIN_PULL_NONE>;
-		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
-	};
-};
-
-&serial_0 {
-	status = "okay";
-};
-
-&ufs_0 {
-	status = "okay";
-	vcc-supply = <&ufs_0_fixed_vcc_reg>;
-};
-
-&ufs_0_phy {
-	status = "okay";
-};
-
-&usbdrd31 {
-	vdd10-supply = <&reg_placeholder>;
-	vdd33-supply = <&reg_placeholder>;
-	status = "okay";
-};
-
-&usbdrd31_dwc3 {
-	dr_mode = "otg";
-	usb-role-switch;
-	role-switch-default-mode = "peripheral";
-	maximum-speed = "super-speed-plus";
-	status = "okay";
-
-	port {
-		usbdrd31_dwc3_role_switch: endpoint {
-			remote-endpoint = <&usbc0_role_sw>;
-		};
-	};
-};
-
-&usbdrd31_phy {
-	orientation-switch;
-	/* TODO: Update these once PMIC is implemented */
-	pll-supply = <&reg_placeholder>;
-	dvdd-usb20-supply = <&reg_placeholder>;
-	vddh-usb20-supply = <&reg_placeholder>;
-	vdd33-usb20-supply = <&reg_placeholder>;
-	vdda-usbdp-supply = <&reg_placeholder>;
-	vddh-usbdp-supply = <&reg_placeholder>;
-	status = "okay";
-
-	port {
-		usbdrd31_phy_orien_switch: endpoint {
-			remote-endpoint = <&usbc0_orien_sw>;
-		};
-	};
-};
-
-&usi_uart {
-	samsung,clkreq-on; /* needed for UART mode */
-	status = "okay";
-};
-
-&usi8 {
-	samsung,mode = <USI_V2_I2C>;
-	status = "okay";
 };
 
-&usi12 {
-	samsung,mode = <USI_V2_I2C>;
-	status = "okay";
+&framebuffer0 {
+	reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
+	width = <1080>;
+	height = <2400>;
+	stride = <(1080 * 4)>;
 };
 
-&watchdog_cl0 {
-	timeout-sec = <30>;
-	status = "okay";
+&cont_splash_mem {
+	reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
 };
diff --git a/arch/arm64/boot/dts/exynos/google/gs101-raviole.dtsi b/arch/arm64/boot/dts/exynos/google/gs101-raviole.dtsi
new file mode 100644
index 000000000000..90b08c1addbb
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/google/gs101-raviole.dtsi
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Raviole Device Tree
+ *
+ * Copyright 2021-2023 Google LLC
+ * Copyright 2023 Linaro Ltd - <peter.griffin at linaro.org>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/usb/pd.h>
+#include "gs101-pinctrl.h"
+#include "gs101.dtsi"
+
+/ {
+	aliases {
+		serial0 = &serial_0;
+	};
+
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		/* Bootloader expects bootargs specified otherwise it crashes */
+		bootargs = "";
+		stdout-path = &serial_0;
+
+		/* Use display framebuffer as setup by bootloader */
+		framebuffer0: framebuffer at fac00000 {
+			compatible = "simple-framebuffer";
+			/* size to be updated by actual board */
+			reg = <0x0 0xfac00000 0x100>;
+			format = "a8r8g8b8";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-0 = <&key_voldown>, <&key_volup>, <&key_power>;
+		pinctrl-names = "default";
+
+		button-vol-down {
+			label = "KEY_VOLUMEDOWN";
+			linux,code = <KEY_VOLUMEDOWN>;
+			gpios = <&gpa7 3 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+
+		button-vol-up {
+			label = "KEY_VOLUMEUP";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&gpa8 1 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+
+		button-power {
+			label = "KEY_POWER";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpa10 1 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+	};
+
+	/* TODO: Remove this once PMIC is implemented  */
+	reg_placeholder: regulator-0 {
+		compatible = "regulator-fixed";
+		regulator-name = "placeholder_reg";
+	};
+
+	/* TODO: Remove this once S2MPG11 slave PMIC is implemented  */
+	ufs_0_fixed_vcc_reg: regulator-1 {
+		compatible = "regulator-fixed";
+		regulator-name = "ufs-vcc";
+		gpio = <&gpp0 1 GPIO_ACTIVE_HIGH>;
+		regulator-boot-on;
+		enable-active-high;
+	};
+
+	reserved-memory {
+		cont_splash_mem: splash at fac00000 {
+			/* size to be updated by actual board */
+			reg = <0x0 0xfac00000 0x100>;
+			no-map;
+		};
+	};
+};
+
+&ext_24_5m {
+	clock-frequency = <24576000>;
+};
+
+&ext_200m {
+	clock-frequency = <200000000>;
+};
+
+&hsi2c_8 {
+	status = "okay";
+
+	eeprom: eeprom at 50 {
+		compatible = "atmel,24c08";
+		reg = <0x50>;
+	};
+};
+
+&hsi2c_12 {
+	status = "okay";
+	/* TODO: add the devices once drivers exist */
+
+	usb-typec at 25 {
+		compatible = "maxim,max77759-tcpci", "maxim,max33359";
+		reg = <0x25>;
+		interrupts-extended = <&gpa8 2 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-0 = <&typec_int>;
+		pinctrl-names = "default";
+
+		connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "dual";
+			self-powered;
+			try-power-role = "sink";
+			op-sink-microwatt = <2600000>;
+			slow-charger-loop;
+			/*
+			 * max77759 operating in reverse boost mode (0xA) can
+			 * source up to 1.5A while extboost can only do ~1A.
+			 * Since extboost is the primary path, advertise 900mA.
+			 */
+			source-pdos = <PDO_FIXED(5000, 900,
+						 (PDO_FIXED_SUSPEND
+						  | PDO_FIXED_USB_COMM
+						  | PDO_FIXED_DATA_SWAP
+						  | PDO_FIXED_DUAL_ROLE))>;
+			sink-pdos = <PDO_FIXED(5000, 3000,
+					       (PDO_FIXED_DATA_SWAP
+						| PDO_FIXED_USB_COMM
+						| PDO_FIXED_HIGHER_CAP
+						| PDO_FIXED_DUAL_ROLE))
+				     PDO_FIXED(9000, 2200, 0)
+				     PDO_PPS_APDO(5000, 11000, 3000)>;
+			sink-vdos = <VDO_IDH(1, 1, IDH_PTYPE_PERIPH, 0,
+					     IDH_PTYPE_DFP_HOST, 2, 0x18d1)
+				     VDO_CERT(0x0)
+				     VDO_PRODUCT(0x4ee1, 0x0)
+				     VDO_UFP(UFP_VDO_VER1_2,
+					     (DEV_USB2_CAPABLE
+					      | DEV_USB3_CAPABLE),
+					     UFP_RECEPTACLE, 0,
+					     AMA_VCONN_NOT_REQ, 0,
+					     UFP_ALTMODE_NOT_SUPP,
+					     UFP_USB32_GEN1)
+				     /* padding */ 0
+				     VDO_DFP(DFP_VDO_VER1_1,
+					     (HOST_USB2_CAPABLE
+					      | HOST_USB3_CAPABLE),
+					     DFP_RECEPTACLE, 0)>;
+			sink-vdos-v1 = <VDO_IDH(1, 1, IDH_PTYPE_PERIPH, 0,
+						0, 0, 0x18d1)
+					VDO_CERT(0x0)
+					VDO_PRODUCT(0x4ee1, 0x0)>;
+			/*
+			 * Until bootloader is updated to set those two when
+			 * console is enabled, we disable PD here.
+			 */
+			pd-disable;
+			typec-power-opmode = "default";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_orien_sw: endpoint {
+						remote-endpoint = <&usbdrd31_phy_orien_switch>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_role_sw: endpoint {
+						remote-endpoint = <&usbdrd31_dwc3_role_switch>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&pinctrl_far_alive {
+	key_voldown: key-voldown-pins {
+		samsung,pins = "gpa7-3";
+		samsung,pin-function = <GS101_PIN_FUNC_EINT>;
+		samsung,pin-pud = <GS101_PIN_PULL_NONE>;
+		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
+	};
+
+	key_volup: key-volup-pins {
+		samsung,pins = "gpa8-1";
+		samsung,pin-function = <GS101_PIN_FUNC_EINT>;
+		samsung,pin-pud = <GS101_PIN_PULL_NONE>;
+		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
+	};
+
+	typec_int: typec-int-pins {
+		samsung,pins = "gpa8-2";
+		samsung,pin-function = <GS101_PIN_FUNC_EINT>;
+		samsung,pin-pud = <GS101_PIN_PULL_UP>;
+		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
+	};
+};
+
+&pinctrl_gpio_alive {
+	key_power: key-power-pins {
+		samsung,pins = "gpa10-1";
+		samsung,pin-function = <GS101_PIN_FUNC_EINT>;
+		samsung,pin-pud = <GS101_PIN_PULL_NONE>;
+		samsung,pin-drv = <GS101_PIN_DRV_2_5_MA>;
+	};
+};
+
+&serial_0 {
+	status = "okay";
+};
+
+&ufs_0 {
+	status = "okay";
+	vcc-supply = <&ufs_0_fixed_vcc_reg>;
+};
+
+&ufs_0_phy {
+	status = "okay";
+};
+
+&usbdrd31 {
+	vdd10-supply = <&reg_placeholder>;
+	vdd33-supply = <&reg_placeholder>;
+	status = "okay";
+};
+
+&usbdrd31_dwc3 {
+	dr_mode = "otg";
+	usb-role-switch;
+	role-switch-default-mode = "peripheral";
+	maximum-speed = "super-speed-plus";
+	status = "okay";
+
+	port {
+		usbdrd31_dwc3_role_switch: endpoint {
+			remote-endpoint = <&usbc0_role_sw>;
+		};
+	};
+};
+
+&usbdrd31_phy {
+	orientation-switch;
+	/* TODO: Update these once PMIC is implemented */
+	pll-supply = <&reg_placeholder>;
+	dvdd-usb20-supply = <&reg_placeholder>;
+	vddh-usb20-supply = <&reg_placeholder>;
+	vdd33-usb20-supply = <&reg_placeholder>;
+	vdda-usbdp-supply = <&reg_placeholder>;
+	vddh-usbdp-supply = <&reg_placeholder>;
+	status = "okay";
+
+	port {
+		usbdrd31_phy_orien_switch: endpoint {
+			remote-endpoint = <&usbc0_orien_sw>;
+		};
+	};
+};
+
+&usi_uart {
+	samsung,clkreq-on; /* needed for UART mode */
+	status = "okay";
+};
+
+&usi8 {
+	samsung,mode = <USI_V2_I2C>;
+	status = "okay";
+};
+
+&usi12 {
+	samsung,mode = <USI_V2_I2C>;
+	status = "okay";
+};
+
+&watchdog_cl0 {
+	timeout-sec = <30>;
+	status = "okay";
+};

-- 
2.47.1.613.gc27f4b7a9f-goog



From daniel at fooishbar.org  Mon Dec 16 05:06:07 2024
From: daniel at fooishbar.org (Daniel Stone)
Date: Mon, 16 Dec 2024 13:06:07 +0000
Subject: [PATCH v6 08/16] drm/rockchip: vop2: Support 32x8 superblock afbc
In-Reply-To: <20241214081719.3330518-9-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com> <20241214081719.3330518-9-andyshrk@163.com>
Message-ID: <CAPj87rOjqZdyht2y8MK7gVyk_eqEzk1Sy0DcxFtQRuhrHQ_oxA@mail.gmail.com>

Hi Andy,

On Sat, 14 Dec 2024 at 08:18, Andy Yan <andyshrk at 163.com> wrote:
> This is the only afbc format supported by the upcoming
> VOP for rk3576.
>
> Add support for it.

Out of interest, how was this tested? There is no 32x8 modifier in the
format list in format_modifiers_afbc[], so it seems like it shouldn't
be possible to get a 32x8 buffer on a plane at all.

You can use the drm_info utility from
https://gitlab.freedesktop.org/emersion/drm_info to validate that the
list of supported formats/modifiers for each plane matches your
expectation.

Cheers,
Daniel


From andre.draszik at linaro.org  Mon Dec 16 05:06:26 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Mon, 16 Dec 2024 13:06:26 +0000
Subject: [PATCH 1/4] dt-bindings: arm: google: add gs101-raven
In-Reply-To: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
Message-ID: <20241216-gs101-simplefb-v1-1-8ccad1830281@linaro.org>

Raven is Google's code name for Pixel 6 Pro. Since there are
differences compared to Pixel 6 (Oriole), we need to add a separate
compatible for it.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
 Documentation/devicetree/bindings/arm/google.yaml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/google.yaml b/Documentation/devicetree/bindings/arm/google.yaml
index e20b5c9b16bc..99961e5282e5 100644
--- a/Documentation/devicetree/bindings/arm/google.yaml
+++ b/Documentation/devicetree/bindings/arm/google.yaml
@@ -34,10 +34,11 @@ properties:
     const: '/'
   compatible:
     oneOf:
-      - description: Google Pixel 6 / Oriole
+      - description: Google Pixel 6 or 6 Pro (Oriole or Raven)
         items:
           - enum:
               - google,gs101-oriole
+              - google,gs101-raven
           - const: google,gs101
 
   # Bootloader requires empty ect node to be present

-- 
2.47.1.613.gc27f4b7a9f-goog



From andre.draszik at linaro.org  Mon Dec 16 05:06:25 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Mon, 16 Dec 2024 13:06:25 +0000
Subject: [PATCH 0/4] Google Pixel 6 (simple) framebuffer support
Message-ID: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>

Hi,

This series enables simple framebuffer support on Google Pixel 6 and
Pixel 6 Pro.

Even if simple-framebuffer is deprecated and DRM should be used
instead, having it available in DT is beneficial for several reasons at
this point in time (the phone uses an OLED display):
* energy consumption goes down significantly, as it changes from white
  (as left by bootloader) to black (linux console), and we generally
  don't run out of battery anymore when plugged into a USB port
* less of a burn-in effect I assume
* phone stays cooler due to reduced energy consumption by display

Since Pixel 6 and Pixel 6 Pro use a different resolution display, this
is the time to separate them into their respective DTs, and provide one
for each of them. There are other differences between the two, like
battery design capacity, but they don't matter at this stage due to
incomplete upstream support.

* dependency note *

Due to the renaming of the gs101-oriole.dts, this series will conflict
with any pending patches touching the same file. I have therefore based
this series on top of my USB series from
https://lore.kernel.org/r/20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01 at linaro.org

Please let me know if I should do something different.

* dependency note end *

For those who want to try this out:
The stock bootloader disables the decon hardware trigger before jumping
to Linux, preventing framebuffer updates from reaching the display. We
have added a work-around in our Yocto BSP layer for the time being
(until a proper display exists upstream). An alternative might be to
port and use uniLoader from https://github.com/ivoszbg/uniLoader, as
seems to be done for some other Exynos platforms.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
Andr? Draszik (4):
      dt-bindings: arm: google: add gs101-raven
      arm64: dts: exynos: gs101-oriole: configure simple-framebuffer
      arm64: dts: exynos: gs101-oriole: move common Pixel6 & 6Pro parts into a .dtsi
      arm64: dts: exynos: gs101-raven: add new board file

 Documentation/devicetree/bindings/arm/google.yaml  |   3 +-
 arch/arm64/boot/dts/exynos/google/Makefile         |   1 +
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 269 +------------------
 arch/arm64/boot/dts/exynos/google/gs101-raven.dts  |  27 ++
 .../boot/dts/exynos/google/gs101-raviole.dtsi      | 297 +++++++++++++++++++++
 5 files changed, 335 insertions(+), 262 deletions(-)
---
base-commit: d454191ca68125bee218d1d67d6716d7e753dc7b
change-id: 20241216-gs101-simplefb-8aae80278ed7

Best regards,
-- 
Andr? Draszik <andre.draszik at linaro.org>



From andre.draszik at linaro.org  Mon Dec 16 05:06:27 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Mon, 16 Dec 2024 13:06:27 +0000
Subject: [PATCH 2/4] arm64: dts: exynos: gs101-oriole: configure
 simple-framebuffer
In-Reply-To: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
Message-ID: <20241216-gs101-simplefb-v1-2-8ccad1830281@linaro.org>

The bootloader configures the display hardware for a framebuffer at the
given address, let's add a simple-framebuffer node here until we get a
proper DRM driver.

This has several benefits since it's an OLED display:
* energy consumption goes down significantly, as it changes from white
  (as left by bootloader) to black (linux console), and we generally
  don't run out of battery anymore when plugged into a USB port
* less of a burn-in effect I assume
* phone stays cooler due to reduced energy consumption by display

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
index e58881c61d53..4e1625e3fbb4 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
@@ -23,9 +23,23 @@ aliases {
 	};
 
 	chosen {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
 		/* Bootloader expects bootargs specified otherwise it crashes */
 		bootargs = "";
 		stdout-path = &serial_0;
+
+		/* Use display framebuffer as setup by bootloader */
+		framebuffer0: framebuffer at fac00000 {
+			compatible = "simple-framebuffer";
+			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
+			width = <1080>;
+			height = <2400>;
+			stride = <(1080 * 4)>;
+			format = "a8r8g8b8";
+		};
 	};
 
 	gpio-keys {
@@ -69,6 +83,13 @@ ufs_0_fixed_vcc_reg: regulator-1 {
 		regulator-boot-on;
 		enable-active-high;
 	};
+
+	reserved-memory {
+		cont_splash_mem: splash at fac00000 {
+			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
+			no-map;
+		};
+	};
 };
 
 &ext_24_5m {

-- 
2.47.1.613.gc27f4b7a9f-goog



From andre.draszik at linaro.org  Mon Dec 16 05:06:29 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Mon, 16 Dec 2024 13:06:29 +0000
Subject: [PATCH 4/4] arm64: dts: exynos: gs101-raven: add new board file
In-Reply-To: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
Message-ID: <20241216-gs101-simplefb-v1-4-8ccad1830281@linaro.org>

Raven is Google's code name for Pixel 6 Pro. Similar to Pixel 6
(Oriole), this is also based around its Tensor gs101 SoC.

For now, the relevant difference here is the display resolution:
1440 x 3120 instead of 1080 x 2400.

Create a new board file to reflect this difference.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
Note: MAINTAINERS doesn't need updating, it covers this whole directory
---
 arch/arm64/boot/dts/exynos/google/Makefile        |  1 +
 arch/arm64/boot/dts/exynos/google/gs101-raven.dts | 27 +++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/Makefile b/arch/arm64/boot/dts/exynos/google/Makefile
index 0a6d5e1fe4ee..7385f82b03c9 100644
--- a/arch/arm64/boot/dts/exynos/google/Makefile
+++ b/arch/arm64/boot/dts/exynos/google/Makefile
@@ -2,3 +2,4 @@
 
 dtb-$(CONFIG_ARCH_EXYNOS) += \
 	gs101-oriole.dtb \
+	gs101-raven.dtb
diff --git a/arch/arm64/boot/dts/exynos/google/gs101-raven.dts b/arch/arm64/boot/dts/exynos/google/gs101-raven.dts
new file mode 100644
index 000000000000..75fd34797fa9
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/google/gs101-raven.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Raven Device Tree
+ *
+ * Copyright 2021-2023 Google LLC
+ * Copyright 2023-2024 Linaro Ltd
+ */
+
+/dts-v1/;
+
+#include "gs101-raviole.dtsi"
+
+/ {
+	model = "Raven";
+	compatible = "google,gs101-raven", "google,gs101";
+};
+
+&framebuffer0 {
+	reg = <0x0 0xfac00000 (1440 * 3120 * 4)>;
+	width = <1440>;
+	height = <3120>;
+	stride = <(1440 * 4)>;
+};
+
+&cont_splash_mem {
+	reg = <0x0 0xfac00000 (1440 * 3120 * 4)>;
+};

-- 
2.47.1.613.gc27f4b7a9f-goog



From broonie at kernel.org  Mon Dec 16 05:23:55 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 13:23:55 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <Z2Agntn52mY5bSTp@J2N7QTR9R3>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
 <87a5cysfci.wl-maz@kernel.org>
 <709a0e75-0d0c-4bff-b9fd-3bbb55c97bd5@sirena.org.uk>
 <Z2Agntn52mY5bSTp@J2N7QTR9R3>
Message-ID: <855dbb91-db37-4178-bd0b-511994d3aef7@sirena.org.uk>

On Mon, Dec 16, 2024 at 12:44:14PM +0000, Mark Rutland wrote:

> ... didn't matter either way, and using '&boot_cpu_data' was intended to
> make it clear that the features were based on the boot CPU's info, even
> if you just grepped for that and didn't see the surrounding context.

Right, that was my best guess as to what was supposed to be going on
but it wasn't super clear.  The code could use some more comments.

> I think the real fix here is to move the reading back into
> __cpuinfo_store_cpu(), but to have an explicit check that SME has been
> disabled on the commandline, with a comment explaining that this is a
> bodge for broken FW which traps the SME ID regs.

That should be doable.

There's a few other similar ID registers (eg, we already read GMID_EL1
and MPAMIDR_EL1) make me a bit nervous that we might need to generalise
it a bit, but we can deal with that if it comes up.  Even for SME the
disable was added speculatively, the factors that made this come up for
SVE are less likely to be an issue with 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/20241216/8184d0cc/attachment.sig>

From jbrunet at baylibre.com  Mon Dec 16 05:25:28 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 16 Dec 2024 14:25:28 +0100
Subject: [PATCH 0/2] reset: amlogic: rework auxiliary reset support
In-Reply-To: <20241209-meson-rst-aux-rework-v1-0-d2afb69cc72e@baylibre.com>
	(Jerome Brunet's message of "Mon, 09 Dec 2024 17:04:33 +0100")
References: <20241209-meson-rst-aux-rework-v1-0-d2afb69cc72e@baylibre.com>
Message-ID: <1jmsgv220n.fsf@starbuckisacylon.baylibre.com>

On Mon 09 Dec 2024 at 17:04, Jerome Brunet <jbrunet at baylibre.com> wrote:

> The current implementation of auxiliary reset controller, with the
> registration helper in the same module as the driver code, does not
> allow to properly decouple the registered auxiliary driver from
> the registering one.
>
> This patchset removes the registration helper from the auxiliary reset
> driver and changes how regmap is passed, to simplify the interface a bit.
>
> This patcheset depends on:
> commit 5ae1a43486fb ("clk: amlogic: axg-audio: revert reset implementation")
>
> The above removes the only user of the auxiliary reset controller, restoring
> old implementation as a temporary solution, while it is reworked.
>
> The commit has been applied to clock fixes [1] branch and will eventually
> make its way to an rc release.
>
> [1]: https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/commit/?h=clk-fixes&id=5ae1a43486fb3febd5ce78da13eb354f16d049e0

Hi Philipp,

FYI, the dependency above has made it to v6.13-rc3

Cheers

>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
> Jerome Brunet (2):
>       reset: amlogic: aux: get regmap through parent device
>       reset: amlogic: aux: drop aux registration helper
>
>  drivers/reset/amlogic/reset-meson-aux.c | 85 +++------------------------------
>  include/soc/amlogic/reset-meson-aux.h   | 23 ---------
>  2 files changed, 6 insertions(+), 102 deletions(-)
> ---
> base-commit: 3d99f9231bedcf9acfb965a97645a8ecfa93a40d
> change-id: 20241209-meson-rst-aux-rework-e26c716c6762
> prerequisite-change-id: 20241127-clk-audio-fix-rst-missing-0b80628d934b:v2
> prerequisite-patch-id: 8bf55ab8ba9db1abea5df2554864a2f4f9c72e77
>
> Best regards,

-- 
Jerome


From jinjian.song at fibocom.com  Mon Dec 16 05:53:22 2024
From: jinjian.song at fibocom.com (Jinjian Song)
Date: Mon, 16 Dec 2024 21:53:22 +0800
Subject: [net v2] net: wwan: t7xx: Fix FSM command timeout issue
In-Reply-To: <da90f64c-260a-4329-87bf-1f9ff20a5951@gmail.com>
References: <20241213064720.122615-1-jinjian.song@fibocom.com>
Message-ID: <20241216135322.4533-1-jinjian.song@fibocom.com>

From: Sergey Ryazanov <ryazanov.s.a at gmail.com>

>> Fixes: d785ed945de6 ("net: wwan: t7xx: PCIe reset rescan")
>
>The completion waiting was introduced in a different commit. I believe, 
>the fix tag should be 13e920d93e37 ("net: wwan: t7xx: Add core components")
>

Got it.

[...]
>>   	if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
>>   		*cmd->ret = result;
>
>The memory for the result storage is allocated on the stack as well. And 
>writing it unconditionally can cause unexpected consequences.
>

Got it.

[...]
>>   		wait_ret = wait_for_completion_timeout(&done,
>>   						       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
>> -		if (!wait_ret)
>> +		if (!wait_ret) {
>> +			cmd->done = NULL;
>
>We cannot access the command memory here, since fsm_finish_command() 
>could release it already.
>

Got it.

[...]
>Here we have an ownership transfer problem and a driver author has tried 
>to solve it, but as noticed, we are still experiencing issues in case of 
>timeout.
>
>The command completion routine should not release the command memory 
>unconditionally. Looks like the references counting approach should help 
>us here. E.g.
>1. grab a reference before we put a command into the queue
>1.1. grab an extra reference if we are going to wait the completion
>2. release the reference as soon as we are done with the command execution
>3. in case of completion waiting release the reference as soon as we are 
>done with waiting due to completion or timeout
>
>Could you try the following patch? Please note, besides the reference 
>counter introduction it also moves completion and result storage inside 
>the command structure as advised by the completion documentation.
>

Yes, please let me try the following patch.
[...]

Thanks.

Jinjian,
Best Regards.


From christian.bruel at foss.st.com  Mon Dec 16 06:00:58 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Mon, 16 Dec 2024 15:00:58 +0100
Subject: [PATCH v2 4/5] PCI: stm32: Add PCIe endpoint support for
 STM32MP25
In-Reply-To: <20241205172738.GA3054352@bhelgaas>
References: <20241205172738.GA3054352@bhelgaas>
Message-ID: <ef02ddbf-0838-4616-a3c5-ef7ab55de3c9@foss.st.com>



On 12/5/24 18:27, Bjorn Helgaas wrote:
> On Tue, Nov 26, 2024 at 04:51:18PM +0100, Christian Bruel wrote:
>> Add driver to configure the STM32MP25 SoC PCIe Gen2 controller based on the
>> DesignWare PCIe core in endpoint mode.
> 
>> +config PCIE_STM32_EP
>> +	tristate "STMicroelectronics STM32MP25 PCIe Controller (endpoint mode)"
>> +	depends on ARCH_STM32 || COMPILE_TEST
>> +	depends on PCI_ENDPOINT
>> +	select PCIE_DW_EP
>> +	help
>> +	  Enables endpoint support for DesignWare core based PCIe controller in found
>> +	  in STM32MP25 SoC.
> 
> s/in found in/in/ (or "found in" if you prefer)
> 
> Wrap so help text fits in 80 columns when for "make menuconfig".
> 
>> +static void stm32_pcie_ep_init(struct dw_pcie_ep *ep)
>> +{
>> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
>> +	enum pci_barno bar;
>> +
>> +	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
>> +		dw_pcie_ep_reset_bar(pci, bar);
>> +
>> +	/* Defer Completion Requests until link started */
> 
> I asked about this before [1] but didn't finish the conversation.  My
> main point is that I think "Completion Request" is a misnomer.
> There's a "Configuration Request" and a "Completion," but no such
> thing as a "Completion Request."
> 
> Based on your previous response, I think this should say something
> like "respond to config requests with Request Retry Status (RRS) until
> we're prepared to handle them."

OK thanks for the phrasing. This is inline with the DWC doc:
"... controller completes incoming configuration requests with a
configuration request retry status."
The only thing is that the PCIe specs talks about CRS, not RRS.

so slightly change to
"respond to config requests with Configuration Request Retry Status 
(CRS) until we're prepared to handle them."


> 
>> +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
>> +			   STM32MP25_PCIECR_REQ_RETRY_EN,
>> +			   STM32MP25_PCIECR_REQ_RETRY_EN);
>> +}
>> +
>> +static int stm32_pcie_enable_link(struct dw_pcie *pci)
>> +{
>> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
>> +	int ret;
>> +
>> +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
>> +			   STM32MP25_PCIECR_LTSSM_EN,
>> +			   STM32MP25_PCIECR_LTSSM_EN);
>> +
>> +	ret = dw_pcie_wait_for_link(pci);
>> +	if (ret)
>> +		return ret;
>> +
>> +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
>> +			   STM32MP25_PCIECR_REQ_RETRY_EN,
>> +			   0);
> 
> And I assume this means the endpoint will accept config requests and
> handle them normally instead of responding with RRS.
> 
> Strictly speaking this is a different condition than "the link is up"
> because the link must be up in order to even receive a config request.
> The purpose of RRS is for devices that need more initialization time
> after the link is up before they can respond to config requests.
> 
> The fact that the hardware provides this bit makes me think the
> designer anticipated that the link might come up before the rest of
> the device is fully initialized.

Agree, this there are 2 conditions in this function: link is up + 
accepting config requests. I'll split or rename

Thanks
Christian
> 
> Bjorn
> 
> [1] https://lore.kernel.org/r/20241112203846.GA1856246 at bhelgaas
> 


From andrea.porta at suse.com  Mon Dec 16 06:08:40 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon, 16 Dec 2024 15:08:40 +0100
Subject: [PATCH v5 08/10] misc: rp1: RaspberryPi RP1 misc driver
In-Reply-To: <20241210224837.GA702616-robh@kernel.org>
References: <cover.1733136811.git.andrea.porta@suse.com>
 <28fe72eec1c08781770cee65032bb10a6d5994a9.1733136811.git.andrea.porta@suse.com>
 <20241210224837.GA702616-robh@kernel.org>
Message-ID: <Z2A0aAPotT0NvoCl@apocalypse>

Hi Rob,

On 16:48 Tue 10 Dec     , Rob Herring wrote:
> On Mon, Dec 02, 2024 at 12:19:32PM +0100, Andrea della Porta wrote:
> > The RaspberryPi RP1 is a PCI multi function device containing
> > peripherals ranging from Ethernet to USB controller, I2C, SPI
> > and others.
> > 
> > Implement a bare minimum driver to operate the RP1, leveraging
> > actual OF based driver implementations for the on-board peripherals
> > by loading a devicetree overlay during driver probe.
> > 
> > The peripherals are accessed by mapping MMIO registers starting
> > from PCI BAR1 region.
> > 
> > With the overlay approach we can achieve more generic and agnostic
> > approach to managing this chipset, being that it is a PCI endpoint
> > and could possibly be reused in other hw implementations. The
> > presented approach is also used by Bootlin's Microchip LAN966x
> > patchset (see link) as well, for a similar chipset.
> > 
> > Since the gpio line names should be provided by the user, there
> > is an interface through configfs that allows the userspace to
> > load a DT overlay that will provide gpio-line-names property.
> > The interface can be invoked like this:
> > 
> > cat rpi-rp1-gpios-5-b.dtbo > /sys/kernel/config/rp1-cfg/gpio_set_names
> 
> Where's the configfs support? This looks like a stale comment.

Yes, you are right. Thanks for pointing that out, I've dropped that
paragraph, since there is no gpio name support in this specific patchset
anymore.

> 
> If this is the general purpose configfs interface for overlays, that's 
> likely never going upstream. If you want this support, then you should 
> load your overlay with the firmware loader instead of building it into 
> the kernel. You can of course add that later.

I think the best thing would be to leave the actual base overlay compiled
inside the driver as it is now, and to prepare a secondary overlay for the
gpio names to be loaded as a binary blob through request_firmware(). Does
it make sense? Of course, the gpio name overlay support would be a future
patchset of its own.

> 
> > and is designed to be similar to what users are already used to
> > from distro with downstream kernel.
> > 
> > For reasons why this driver is contained in drivers/misc, please
> > check the links.
> > 
> > This driver is heavily based on downstream code from RaspberryPi
> > Foundation, and the original author is Phil Elwell.
> > 
> > Link: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
> > Link: https://lore.kernel.org/all/20240612140208.GC1504919 at google.com/
> > Link: https://lore.kernel.org/all/83f7fa09-d0e6-4f36-a27d-cee08979be2a at app.fastmail.com/
> > Link: https://lore.kernel.org/all/2024081356-mutable-everyday-6f9d at gregkh/
> > Link: https://lore.kernel.org/all/20240808154658.247873-1-herve.codina at bootlin.com/
> > 
> > Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
> > ---
> >  MAINTAINERS                   |   1 +
> >  drivers/misc/Kconfig          |   1 +
> >  drivers/misc/Makefile         |   1 +
> >  drivers/misc/rp1/Kconfig      |  21 ++
> >  drivers/misc/rp1/Makefile     |   3 +
> >  drivers/misc/rp1/rp1-pci.dtso |   8 +
> >  drivers/misc/rp1/rp1_pci.c    | 366 ++++++++++++++++++++++++++++++++++
> >  drivers/misc/rp1/rp1_pci.h    |  14 ++
> >  drivers/pci/quirks.c          |   1 +
> >  include/linux/pci_ids.h       |   3 +
> >  10 files changed, 419 insertions(+)
> >  create mode 100644 drivers/misc/rp1/Kconfig
> >  create mode 100644 drivers/misc/rp1/Makefile
> >  create mode 100644 drivers/misc/rp1/rp1-pci.dtso
> >  create mode 100644 drivers/misc/rp1/rp1_pci.c
> >  create mode 100644 drivers/misc/rp1/rp1_pci.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fbdd8594aa7e..d67ba6d10aa8 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -19583,6 +19583,7 @@ F:	Documentation/devicetree/bindings/misc/pci1de4,1.yaml
> >  F:	Documentation/devicetree/bindings/pci/pci-ep-bus.yaml
> >  F:	Documentation/devicetree/bindings/pinctrl/raspberrypi,rp1-gpio.yaml
> >  F:	drivers/clk/clk-rp1.c
> > +F:	drivers/misc/rp1/
> >  F:	drivers/pinctrl/pinctrl-rp1.c
> >  F:	include/dt-bindings/clock/rp1.h
> >  F:	include/dt-bindings/misc/rp1.h
> > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> > index 09cbe3f0ab1e..ffa4d8315c35 100644
> > --- a/drivers/misc/Kconfig
> > +++ b/drivers/misc/Kconfig
> > @@ -651,4 +651,5 @@ source "drivers/misc/uacce/Kconfig"
> >  source "drivers/misc/pvpanic/Kconfig"
> >  source "drivers/misc/mchp_pci1xxxx/Kconfig"
> >  source "drivers/misc/keba/Kconfig"
> > +source "drivers/misc/rp1/Kconfig"
> >  endmenu
> > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> > index 40bf953185c7..3b6b07a23aac 100644
> > --- a/drivers/misc/Makefile
> > +++ b/drivers/misc/Makefile
> > @@ -74,3 +74,4 @@ lan966x-pci-objs		:= lan966x_pci.o
> >  lan966x-pci-objs		+= lan966x_pci.dtbo.o
> >  obj-$(CONFIG_MCHP_LAN966X_PCI)	+= lan966x-pci.o
> >  obj-y				+= keba/
> > +obj-$(CONFIG_MISC_RP1)		+= rp1/
> > diff --git a/drivers/misc/rp1/Kconfig b/drivers/misc/rp1/Kconfig
> > new file mode 100644
> > index 000000000000..15c443e13389
> > --- /dev/null
> > +++ b/drivers/misc/rp1/Kconfig
> > @@ -0,0 +1,21 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +#
> > +# RaspberryPi RP1 misc device
> > +#
> > +
> > +config MISC_RP1
> > +	tristate "RaspberryPi RP1 PCIe support"
> > +	depends on OF_IRQ && PCI_MSI && PCI_QUIRKS
> > +	select OF_OVERLAY
> > +	select PCI_DYNAMIC_OF_NODES
> > +	help
> > +	  Support the RP1 peripheral chip found on Raspberry Pi 5 board.
> > +
> > +	  This device supports several sub-devices including e.g. Ethernet
> > +	  controller, USB controller, I2C, SPI and UART.
> > +
> > +	  The driver is responsible for enabling the DT node once the PCIe
> > +	  endpoint has been configured, and handling interrupts.
> > +
> > +	  This driver uses an overlay to load other drivers to support for
> > +	  RP1 internal sub-devices.
> > diff --git a/drivers/misc/rp1/Makefile b/drivers/misc/rp1/Makefile
> > new file mode 100644
> > index 000000000000..508b4cb05627
> > --- /dev/null
> > +++ b/drivers/misc/rp1/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +obj-$(CONFIG_MISC_RP1)		+= rp1-pci.o
> > +rp1-pci-objs			:= rp1_pci.o rp1-pci.dtbo.o
> > diff --git a/drivers/misc/rp1/rp1-pci.dtso b/drivers/misc/rp1/rp1-pci.dtso
> > new file mode 100644
> > index 000000000000..0bf2f4bb18e6
> > --- /dev/null
> > +++ b/drivers/misc/rp1/rp1-pci.dtso
> > @@ -0,0 +1,8 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +
> > +/* the dts overlay is included from the dts directory so
> > + * it can be possible to check it with CHECK_DTBS while
> > + * also compile it from the driver source directory.
> 
> I haven't tried, but I think if you set CHECK_DTBS=y, then this file 
> will get checked. Applying it to the base DT will not though.

I think we're saying the same thing here, which is that the dtso can be
checked by passing CHECK_DTB=y but it has to be located somewhere under
arch/*/boot/dts. Or maybe I'm misunderstandig what you mean here?

> 
> > + */
> > +
> > +#include "arm64/broadcom/rp1.dtso"
> > diff --git a/drivers/misc/rp1/rp1_pci.c b/drivers/misc/rp1/rp1_pci.c
> > new file mode 100644
> > index 000000000000..0dd345341c6f
> > --- /dev/null
> > +++ b/drivers/misc/rp1/rp1_pci.c
> > @@ -0,0 +1,366 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2018-24 Raspberry Pi Ltd.
> > + * All rights reserved.
> > + */
> > +
> > +#include <linux/err.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irq.h>
> > +#include <linux/irqchip/chained_irq.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/module.h>
> > +#include <linux/msi.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/pci.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "rp1_pci.h"
> > +
> > +#define RP1_DRIVER_NAME		"rp1"
> > +
> > +#define RP1_HW_IRQ_MASK		GENMASK(5, 0)
> > +
> > +#define REG_SET			0x800
> > +#define REG_CLR			0xc00
> > +
> > +/* MSI-X CFG registers start at 0x8 */
> > +#define MSIX_CFG(x) (0x8 + (4 * (x)))
> > +
> > +#define MSIX_CFG_IACK_EN        BIT(3)
> > +#define MSIX_CFG_IACK           BIT(2)
> > +#define MSIX_CFG_ENABLE         BIT(0)
> > +
> > +/* Address map */
> > +#define RP1_PCIE_APBS_BASE	0x108000
> > +
> > +/* Interrupts */
> > +#define RP1_INT_IO_BANK0	0
> > +#define RP1_INT_IO_BANK1	1
> > +#define RP1_INT_IO_BANK2	2
> > +#define RP1_INT_AUDIO_IN	3
> > +#define RP1_INT_AUDIO_OUT	4
> > +#define RP1_INT_PWM0		5
> > +#define RP1_INT_ETH		6
> > +#define RP1_INT_I2C0		7
> > +#define RP1_INT_I2C1		8
> > +#define RP1_INT_I2C2		9
> > +#define RP1_INT_I2C3		10
> > +#define RP1_INT_I2C4		11
> > +#define RP1_INT_I2C5		12
> > +#define RP1_INT_I2C6		13
> > +#define RP1_INT_I2S0		14
> > +#define RP1_INT_I2S1		15
> > +#define RP1_INT_I2S2		16
> > +#define RP1_INT_SDIO0		17
> > +#define RP1_INT_SDIO1		18
> > +#define RP1_INT_SPI0		19
> > +#define RP1_INT_SPI1		20
> > +#define RP1_INT_SPI2		21
> > +#define RP1_INT_SPI3		22
> > +#define RP1_INT_SPI4		23
> > +#define RP1_INT_SPI5		24
> > +#define RP1_INT_UART0		25
> > +#define RP1_INT_TIMER_0		26
> > +#define RP1_INT_TIMER_1		27
> > +#define RP1_INT_TIMER_2		28
> > +#define RP1_INT_TIMER_3		29
> > +#define RP1_INT_USBHOST0	30
> > +#define RP1_INT_USBHOST0_0	31
> > +#define RP1_INT_USBHOST0_1	32
> > +#define RP1_INT_USBHOST0_2	33
> > +#define RP1_INT_USBHOST0_3	34
> > +#define RP1_INT_USBHOST1	35
> > +#define RP1_INT_USBHOST1_0	36
> > +#define RP1_INT_USBHOST1_1	37
> > +#define RP1_INT_USBHOST1_2	38
> > +#define RP1_INT_USBHOST1_3	39
> > +#define RP1_INT_DMA		40
> > +#define RP1_INT_PWM1		41
> > +#define RP1_INT_UART1		42
> > +#define RP1_INT_UART2		43
> > +#define RP1_INT_UART3		44
> > +#define RP1_INT_UART4		45
> > +#define RP1_INT_UART5		46
> > +#define RP1_INT_MIPI0		47
> > +#define RP1_INT_MIPI1		48
> > +#define RP1_INT_VIDEO_OUT	49
> > +#define RP1_INT_PIO_0		50
> > +#define RP1_INT_PIO_1		51
> > +#define RP1_INT_ADC_FIFO	52
> > +#define RP1_INT_PCIE_OUT	53
> > +#define RP1_INT_SPI6		54
> > +#define RP1_INT_SPI7		55
> > +#define RP1_INT_SPI8		56
> > +#define RP1_INT_SYSCFG		58
> > +#define RP1_INT_CLOCKS_DEFAULT	59
> > +#define RP1_INT_VBUSCTRL	60
> > +#define RP1_INT_PROC_MISC	57
> 
> Why all these defines which will never be used because they come from 
> DT?
>

Right, those defines where originally designed to be included from dts, but
previous discussion deemed interrupt numbers to be hardcoded instead of being
specified as mnemonics. In the driver source code I just use RP1_INT_END as the
number of interrupts but I thought that the specific interrupt numbers should
be documented in some way or another. Since no one is currently referencing
those defines, would it be better to just turn those in a multiline comment
just to describe them in a more compact form?

Many thanks,
Andrea

> Rob


From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:02 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:02 +0100
Subject: [PATCH 06/17] arm64: vdso: Switch to generic storage
 implementation
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-6-f7aed1bdb3b2@linutronix.de>

The generic storage implementation provides the same features as the
custom one. However it can be shared between architectures, making
maintenance easier.

This switch also moves the random state data out of the time data page.
The currently used hardcoded __VDSO_RND_DATA_OFFSET does not take into
account changes to the time data page layout.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/arm64/Kconfig                                |  1 +
 arch/arm64/include/asm/vdso.h                     |  2 +-
 arch/arm64/include/asm/vdso/compat_gettimeofday.h | 32 ++++----
 arch/arm64/include/asm/vdso/getrandom.h           | 12 ---
 arch/arm64/include/asm/vdso/gettimeofday.h        | 16 +---
 arch/arm64/include/asm/vdso/vsyscall.h            | 25 +------
 arch/arm64/kernel/vdso.c                          | 90 ++---------------------
 arch/arm64/kernel/vdso/vdso.lds.S                 |  7 +-
 arch/arm64/kernel/vdso32/vdso.lds.S               |  7 +-
 9 files changed, 31 insertions(+), 161 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5e8892c0112704f9ca74c4fc55b27..1a4a78ec593328d6e6bceacc1abb0821eab988ca 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -159,6 +159,7 @@ config ARM64
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_GETTIMEOFDAY
+	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select HARDIRQS_SW_RESEND
 	select HAS_IOPORT
diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
index 3e3c3fdb184274abd20647335b19e81e709506db..61679070f595cd25fb2f516b5b077599a9570689 100644
--- a/arch/arm64/include/asm/vdso.h
+++ b/arch/arm64/include/asm/vdso.h
@@ -5,7 +5,7 @@
 #ifndef __ASM_VDSO_H
 #define __ASM_VDSO_H
 
-#define __VVAR_PAGES    2
+#define __VDSO_PAGES    4
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/include/asm/vdso/compat_gettimeofday.h b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
index 778c1202bbbf9f5db6bfced62a833d50e1675b08..a386bba3efa794e6f3f0018c85531dd7e708ff86 100644
--- a/arch/arm64/include/asm/vdso/compat_gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
@@ -104,7 +104,7 @@ int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
 }
 
 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
-						 const struct vdso_data *vd)
+						 const struct vdso_time_data *vd)
 {
 	u64 res;
 
@@ -131,43 +131,45 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
 	return res;
 }
 
-static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
+static __always_inline const struct vdso_time_data *__aarch64_get_vdso_u_time_data(void)
 {
-	const struct vdso_data *ret;
+	const struct vdso_time_data *ret;
 
 	/*
-	 * This simply puts &_vdso_data into ret. The reason why we don't use
-	 * `ret = _vdso_data` is that the compiler tends to optimise this in a
-	 * very suboptimal way: instead of keeping &_vdso_data in a register,
-	 * it goes through a relocation almost every time _vdso_data must be
+	 * This simply puts &_vdso_time_data into ret. The reason why we don't use
+	 * `ret = _vdso_time_data` is that the compiler tends to optimise this in a
+	 * very suboptimal way: instead of keeping &_vdso_time_data in a register,
+	 * it goes through a relocation almost every time _vdso_time_data must be
 	 * accessed (even in subfunctions). This is both time and space
 	 * consuming: each relocation uses a word in the code section, and it
 	 * has to be loaded at runtime.
 	 *
 	 * This trick hides the assignment from the compiler. Since it cannot
 	 * track where the pointer comes from, it will only use one relocation
-	 * where __arch_get_vdso_data() is called, and then keep the result in
-	 * a register.
+	 * where __aarch64_get_vdso_u_time_data() is called, and then keep the
+	 * result in a register.
 	 */
-	asm volatile("mov %0, %1" : "=r"(ret) : "r"(_vdso_data));
+	asm volatile("mov %0, %1" : "=r"(ret) : "r"(vdso_u_time_data));
 
 	return ret;
 }
+#define __arch_get_vdso_u_time_data __aarch64_get_vdso_u_time_data
 
 #ifdef CONFIG_TIME_NS
 static __always_inline
-const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
+const struct vdso_time_data *__aarch64_get_vdso_u_timens_data(void)
 {
-	const struct vdso_data *ret;
+	const struct vdso_time_data *ret;
 
-	/* See __arch_get_vdso_data(). */
-	asm volatile("mov %0, %1" : "=r"(ret) : "r"(_timens_data));
+	/* See __aarch64_get_vdso_u_time_data(). */
+	asm volatile("mov %0, %1" : "=r"(ret) : "r"(vdso_u_timens_data));
 
 	return ret;
 }
+#define __arch_get_vdso_u_timens_data __aarch64_get_vdso_u_timens_data
 #endif
 
-static inline bool vdso_clocksource_ok(const struct vdso_data *vd)
+static inline bool vdso_clocksource_ok(const struct vdso_time_data *vd)
 {
 	return vd->clock_mode == VDSO_CLOCKMODE_ARCHTIMER;
 }
diff --git a/arch/arm64/include/asm/vdso/getrandom.h b/arch/arm64/include/asm/vdso/getrandom.h
index 342f807e204442c95cb9e9a849da38effbe50334..a2197da1951b021baff4eb08b3f1c314df2f5f23 100644
--- a/arch/arm64/include/asm/vdso/getrandom.h
+++ b/arch/arm64/include/asm/vdso/getrandom.h
@@ -33,18 +33,6 @@ static __always_inline ssize_t getrandom_syscall(void *_buffer, size_t _len, uns
 	return ret;
 }
 
-static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void)
-{
-	/*
-	 * The RNG data is in the real VVAR data page, but if a task belongs to a time namespace
-	 * then VVAR_DATA_PAGE_OFFSET points to the namespace-specific VVAR page and VVAR_TIMENS_
-	 * PAGE_OFFSET points to the real VVAR page.
-	 */
-	if (IS_ENABLED(CONFIG_TIME_NS) && _vdso_data->clock_mode == VDSO_CLOCKMODE_TIMENS)
-		return (void *)&_vdso_rng_data + VVAR_TIMENS_PAGE_OFFSET * (1UL << CONFIG_PAGE_SHIFT);
-	return &_vdso_rng_data;
-}
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_VDSO_GETRANDOM_H */
diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
index 764d13e2916c559bc8fd7efa032b6f468ac0d4a2..92a2b59a9f3df4d20feb483e6d8ebd1d813b7932 100644
--- a/arch/arm64/include/asm/vdso/gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/gettimeofday.h
@@ -67,7 +67,7 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
 }
 
 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
-						 const struct vdso_data *vd)
+						 const struct vdso_time_data *vd)
 {
 	u64 res;
 
@@ -99,20 +99,6 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
 	return res;
 }
 
-static __always_inline
-const struct vdso_data *__arch_get_vdso_data(void)
-{
-	return _vdso_data;
-}
-
-#ifdef CONFIG_TIME_NS
-static __always_inline
-const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
-{
-	return _timens_data;
-}
-#endif
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
index eea51946d45a2f8c7eebfff971d74878be53a798..3f65cbd00635aab50a4e0c6058d38b39fd6d43a9 100644
--- a/arch/arm64/include/asm/vdso/vsyscall.h
+++ b/arch/arm64/include/asm/vdso/vsyscall.h
@@ -2,41 +2,18 @@
 #ifndef __ASM_VDSO_VSYSCALL_H
 #define __ASM_VDSO_VSYSCALL_H
 
-#define __VDSO_RND_DATA_OFFSET  480
-
 #ifndef __ASSEMBLY__
 
 #include <vdso/datapage.h>
 
-enum vvar_pages {
-	VVAR_DATA_PAGE_OFFSET,
-	VVAR_TIMENS_PAGE_OFFSET,
-	VVAR_NR_PAGES,
-};
-
 #define VDSO_PRECISION_MASK	~(0xFF00ULL<<48)
 
-extern struct vdso_data *vdso_data;
 
 /*
  * Update the vDSO data page to keep in sync with kernel timekeeping.
  */
 static __always_inline
-struct vdso_data *__arm64_get_k_vdso_data(void)
-{
-	return vdso_data;
-}
-#define __arch_get_k_vdso_data __arm64_get_k_vdso_data
-
-static __always_inline
-struct vdso_rng_data *__arm64_get_k_vdso_rnd_data(void)
-{
-	return (void *)vdso_data + __VDSO_RND_DATA_OFFSET;
-}
-#define __arch_get_k_vdso_rng_data __arm64_get_k_vdso_rnd_data
-
-static __always_inline
-void __arm64_update_vsyscall(struct vdso_data *vdata)
+void __arm64_update_vsyscall(struct vdso_time_data *vdata)
 {
 	vdata[CS_HRES_COARSE].mask	= VDSO_PRECISION_MASK;
 	vdata[CS_RAW].mask		= VDSO_PRECISION_MASK;
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index e8ed8e5b713b525abac828b1a17ab9e6d974a3e9..887ac0b05961eb83afe649a0afcaf7deda4b186b 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -18,7 +18,7 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
-#include <linux/time_namespace.h>
+#include <linux/vdso_datastore.h>
 #include <linux/vmalloc.h>
 #include <vdso/datapage.h>
 #include <vdso/helpers.h>
@@ -57,12 +57,6 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = {
 #endif /* CONFIG_COMPAT_VDSO */
 };
 
-/*
- * The vDSO data page.
- */
-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,
 		struct vm_area_struct *new_vma)
 {
@@ -104,78 +98,6 @@ static int __init __vdso_init(enum vdso_abi abi)
 	return 0;
 }
 
-#ifdef CONFIG_TIME_NS
-struct vdso_data *arch_get_vdso_data(void *vvar_page)
-{
-	return (struct vdso_data *)(vvar_page);
-}
-
-static const struct vm_special_mapping vvar_map;
-
-/*
- * The vvar mapping contains data for a specific time namespace, so when a task
- * changes namespace we must unmap its vvar data for the old namespace.
- * Subsequent faults will map in data for the new namespace.
- *
- * For more details see timens_setup_vdso_data().
- */
-int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
-{
-	struct mm_struct *mm = task->mm;
-	struct vm_area_struct *vma;
-	VMA_ITERATOR(vmi, mm, 0);
-
-	mmap_read_lock(mm);
-
-	for_each_vma(vmi, vma) {
-		if (vma_is_special_mapping(vma, &vvar_map))
-			zap_vma_pages(vma);
-	}
-
-	mmap_read_unlock(mm);
-	return 0;
-}
-#endif
-
-static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
-			     struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	struct page *timens_page = find_timens_vvar_page(vma);
-	unsigned long pfn;
-
-	switch (vmf->pgoff) {
-	case VVAR_DATA_PAGE_OFFSET:
-		if (timens_page)
-			pfn = page_to_pfn(timens_page);
-		else
-			pfn = sym_to_pfn(vdso_data);
-		break;
-#ifdef CONFIG_TIME_NS
-	case VVAR_TIMENS_PAGE_OFFSET:
-		/*
-		 * If a task belongs to a time namespace then a namespace
-		 * specific VVAR is mapped with the VVAR_DATA_PAGE_OFFSET and
-		 * the real VVAR page is mapped with the VVAR_TIMENS_PAGE_OFFSET
-		 * offset.
-		 * See also the comment near timens_setup_vdso_data().
-		 */
-		if (!timens_page)
-			return VM_FAULT_SIGBUS;
-		pfn = sym_to_pfn(vdso_data);
-		break;
-#endif /* CONFIG_TIME_NS */
-	default:
-		return VM_FAULT_SIGBUS;
-	}
-
-	return vmf_insert_pfn(vma, vmf->address, pfn);
-}
-
-static const struct vm_special_mapping vvar_map = {
-	.name   = "[vvar]",
-	.fault = vvar_fault,
-};
-
 static int __setup_additional_pages(enum vdso_abi abi,
 				    struct mm_struct *mm,
 				    struct linux_binprm *bprm,
@@ -185,11 +107,11 @@ static int __setup_additional_pages(enum vdso_abi abi,
 	unsigned long gp_flags = 0;
 	void *ret;
 
-	BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
+	BUILD_BUG_ON(VDSO_NR_PAGES != __VDSO_PAGES);
 
 	vdso_text_len = vdso_info[abi].vdso_pages << PAGE_SHIFT;
 	/* Be sure to map the data page */
-	vdso_mapping_len = vdso_text_len + VVAR_NR_PAGES * PAGE_SIZE;
+	vdso_mapping_len = vdso_text_len + VDSO_NR_PAGES * PAGE_SIZE;
 
 	vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
 	if (IS_ERR_VALUE(vdso_base)) {
@@ -197,16 +119,14 @@ static int __setup_additional_pages(enum vdso_abi abi,
 		goto up_fail;
 	}
 
-	ret = _install_special_mapping(mm, vdso_base, VVAR_NR_PAGES * PAGE_SIZE,
-				       VM_READ|VM_MAYREAD|VM_PFNMAP,
-				       &vvar_map);
+	ret = vdso_install_vvar_mapping(mm, vdso_base);
 	if (IS_ERR(ret))
 		goto up_fail;
 
 	if (system_supports_bti_kernel())
 		gp_flags = VM_ARM64_BTI;
 
-	vdso_base += VVAR_NR_PAGES * PAGE_SIZE;
+	vdso_base += VDSO_NR_PAGES * PAGE_SIZE;
 	mm->context.vdso = (void *)vdso_base;
 	ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
 				       VM_READ|VM_EXEC|gp_flags|
diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
index 4ec32e86a8da22d5e2315e55ae2e86ec8e7f5f9a..2e20d0593f182bfefcf39aebb1400f32af0866dc 100644
--- a/arch/arm64/kernel/vdso/vdso.lds.S
+++ b/arch/arm64/kernel/vdso/vdso.lds.S
@@ -20,11 +20,8 @@ OUTPUT_ARCH(aarch64)
 
 SECTIONS
 {
-	PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
-	PROVIDE(_vdso_rng_data = _vdso_data + __VDSO_RND_DATA_OFFSET);
-#ifdef CONFIG_TIME_NS
-	PROVIDE(_timens_data = _vdso_data + PAGE_SIZE);
-#endif
+	VDSO_VVAR_SYMS
+
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text
diff --git a/arch/arm64/kernel/vdso32/vdso.lds.S b/arch/arm64/kernel/vdso32/vdso.lds.S
index 732702a187e9e8b62972ee0aad75c23568e5e779..e02b27487ce80497663dd042357558fea201fcce 100644
--- a/arch/arm64/kernel/vdso32/vdso.lds.S
+++ b/arch/arm64/kernel/vdso32/vdso.lds.S
@@ -12,16 +12,15 @@
 #include <asm/page.h>
 #include <asm/vdso.h>
 #include <asm-generic/vmlinux.lds.h>
+#include <vdso/datapage.h>
 
 OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
 OUTPUT_ARCH(arm)
 
 SECTIONS
 {
-	PROVIDE_HIDDEN(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
-#ifdef CONFIG_TIME_NS
-	PROVIDE_HIDDEN(_timens_data = _vdso_data + PAGE_SIZE);
-#endif
+	VDSO_VVAR_SYMS
+
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:01 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:01 +0100
Subject: [PATCH 05/17] vdso: Add generic architecture-specific data storage
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-5-f7aed1bdb3b2@linutronix.de>

Some architectures need to architecture-specific data to the vDSO.
Enable the generic vDSO storage mechanism to both store and map this
data. Some architectures require more than a single page, like
LoongArch, so prepare for that usecase, too.

Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/Kconfig                |  4 ++++
 include/vdso/datapage.h     | 32 ++++++++++++++++++++++++++++++++
 lib/vdso_kernel/datastore.c | 14 ++++++++++++++
 3 files changed, 50 insertions(+)

diff --git a/arch/Kconfig b/arch/Kconfig
index 6682b2a53e342cbacc05b70ef99cb1c47efe55e8..48f37e6c00674f433a0d6e6e05ce72c27cf000b7 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1576,6 +1576,10 @@ config HAVE_SPARSE_SYSCALL_NR
 	  entries at 4000, 5000 and 6000 locations. This option turns on syscall
 	  related optimizations for a given architecture.
 
+config ARCH_HAS_VDSO_ARCH_DATA
+	depends on GENERIC_VDSO_DATA_STORE
+	bool
+
 config ARCH_HAS_VDSO_TIME_DATA
 	bool
 
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 5ce322422fcb7ba77aeafddbf132fd3e5dbc5a0c..b3227f1cf62895aa60ce0ca96afa42259f4771f9 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -9,11 +9,13 @@
 #include <uapi/linux/types.h>
 #include <uapi/asm-generic/errno-base.h>
 
+#include <vdso/align.h>
 #include <vdso/bits.h>
 #include <vdso/clocksource.h>
 #include <vdso/ktime.h>
 #include <vdso/limits.h>
 #include <vdso/math64.h>
+#include <vdso/page.h>
 #include <vdso/processor.h>
 #include <vdso/time.h>
 #include <vdso/time32.h>
@@ -25,6 +27,15 @@
 struct arch_vdso_time_data {};
 #endif
 
+#if defined(CONFIG_ARCH_HAS_VDSO_ARCH_DATA)
+#include <asm/vdso/arch_data.h>
+#elif defined(CONFIG_GENERIC_VDSO_DATA_STORE)
+struct vdso_arch_data {
+	/* Needed for the generic code, never actually used at runtime */
+	char __unused;
+};
+#endif
+
 #define VDSO_BASES	(CLOCK_TAI + 1)
 #define VDSO_HRES	(BIT(CLOCK_REALTIME)		| \
 			 BIT(CLOCK_MONOTONIC)		| \
@@ -146,9 +157,11 @@ extern struct vdso_rng_data _vdso_rng_data __attribute__((visibility("hidden")))
 extern const struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
 extern const struct vdso_time_data vdso_u_timens_data[CS_BASES] __attribute__((visibility("hidden")));
 extern const struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden")));
+extern const struct vdso_arch_data vdso_u_arch_data __attribute__((visibility("hidden")));
 
 extern struct vdso_time_data *vdso_k_time_data;
 extern struct vdso_rng_data *vdso_k_rng_data;
+extern struct vdso_arch_data *vdso_k_arch_data;
 #endif
 
 /**
@@ -161,10 +174,15 @@ union vdso_data_store {
 
 #ifdef CONFIG_GENERIC_VDSO_DATA_STORE
 
+#define VDSO_ARCH_DATA_SIZE ALIGN(sizeof(struct vdso_arch_data), PAGE_SIZE)
+#define VDSO_ARCH_DATA_PAGES (VDSO_ARCH_DATA_SIZE >> PAGE_SHIFT)
+
 enum vdso_pages {
 	VDSO_TIME_PAGE_OFFSET,
 	VDSO_TIMENS_PAGE_OFFSET,
 	VDSO_RNG_PAGE_OFFSET,
+	VDSO_ARCH_PAGES_START,
+	VDSO_ARCH_PAGES_END = VDSO_ARCH_PAGES_START + VDSO_ARCH_DATA_PAGES - 1,
 	VDSO_NR_PAGES
 };
 
@@ -204,6 +222,13 @@ static __always_inline struct vdso_rng_data *__arch_get_vdso_k_rng_data(void)
 
 #endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
 
+#ifdef CONFIG_ARCH_HAS_VDSO_ARCH_DATA
+static __always_inline const struct vdso_arch_data *__arch_get_vdso_u_arch_data(void)
+{
+	return &vdso_u_arch_data;
+}
+#endif /* CONFIG_ARCH_HAS_VDSO_ARCH_DATA */
+
 /*
  * The generic vDSO implementation requires that gettimeofday.h
  * provides:
@@ -234,11 +259,18 @@ static __always_inline struct vdso_rng_data *__arch_get_vdso_k_rng_data(void)
 #define __vdso_u_rng_data
 #endif
 
+#ifdef CONFIG_ARCH_HAS_VDSO_ARCH_DATA
+#define __vdso_u_arch_data	PROVIDE(vdso_u_arch_data = vdso_u_data + 3 * PAGE_SIZE);
+#else
+#define __vdso_u_arch_data
+#endif
+
 #define VDSO_VVAR_SYMS						\
 	PROVIDE(vdso_u_data = . - __VDSO_PAGES * PAGE_SIZE);	\
 	PROVIDE(vdso_u_time_data = vdso_u_data);		\
 	__vdso_u_timens_data					\
 	__vdso_u_rng_data					\
+	__vdso_u_arch_data					\
 
 
 #endif /* !__ASSEMBLY__ */
diff --git a/lib/vdso_kernel/datastore.c b/lib/vdso_kernel/datastore.c
index 0d4f5317b508a54b4f3295f0335d1eefce74d78c..668cac8c4f80ac71d3f6de71e98e963bc65a1c15 100644
--- a/lib/vdso_kernel/datastore.c
+++ b/lib/vdso_kernel/datastore.c
@@ -24,6 +24,14 @@ struct vdso_rng_data *vdso_k_rng_data = &vdso_rng_data_store.data;
 static_assert(sizeof(vdso_rng_data_store) == PAGE_SIZE);
 #endif /* CONFIG_VDSO_GETRANDOM */
 
+#ifdef CONFIG_ARCH_HAS_VDSO_ARCH_DATA
+static union {
+	struct vdso_arch_data	data;
+	u8			page[VDSO_ARCH_DATA_SIZE];
+} vdso_arch_data_store __page_aligned_data;
+struct vdso_arch_data *vdso_k_arch_data = &vdso_arch_data_store.data;
+#endif
+
 static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 			     struct vm_area_struct *vma, struct vm_fault *vmf)
 {
@@ -63,6 +71,12 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 			return VM_FAULT_SIGBUS;
 		pfn = __phys_to_pfn(__pa_symbol(vdso_k_rng_data));
 		break;
+	case VDSO_ARCH_PAGES_START ... VDSO_ARCH_PAGES_END:
+		if (!IS_ENABLED(CONFIG_ARCH_HAS_VDSO_ARCH_DATA))
+			return VM_FAULT_SIGBUS;
+		pfn = __phys_to_pfn(__pa_symbol(vdso_k_arch_data)) +
+			vmf->pgoff - VDSO_ARCH_PAGES_START;
+		break;
 	default:
 		return VM_FAULT_SIGBUS;
 	}

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:03 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:03 +0100
Subject: [PATCH 07/17] riscv: vdso: Switch to generic storage
 implementation
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-7-f7aed1bdb3b2@linutronix.de>

The generic storage implementation provides the same features as the
custom one. However it can be shared between architectures, making
maintenance easier.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/riscv/Kconfig                                 |  3 +-
 arch/riscv/include/asm/vdso.h                      |  2 +-
 .../include/asm/vdso/{time_data.h => arch_data.h}  |  8 +-
 arch/riscv/include/asm/vdso/gettimeofday.h         | 14 +---
 arch/riscv/include/asm/vdso/vsyscall.h             |  9 ---
 arch/riscv/kernel/sys_hwprobe.c                    |  3 +-
 arch/riscv/kernel/vdso.c                           | 90 +---------------------
 arch/riscv/kernel/vdso/hwprobe.c                   |  6 +-
 arch/riscv/kernel/vdso/vdso.lds.S                  |  7 +-
 9 files changed, 18 insertions(+), 124 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index d4a7ca0388c071b536df59c0eb11d55f9080c7cd..a42d74aa53fe7c18e76820499d0ae43cd3b0c0bd 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -52,7 +52,7 @@ config RISCV
 	select ARCH_HAS_SYSCALL_WRAPPER
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAS_UBSAN
-	select ARCH_HAS_VDSO_TIME_DATA
+	select ARCH_HAS_VDSO_ARCH_DATA if HAVE_GENERIC_VDSO
 	select ARCH_KEEP_MEMBLOCK if ACPI
 	select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE	if 64BIT && MMU
 	select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
@@ -115,6 +115,7 @@ config RISCV
 	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL if MMU && 64BIT
+	select GENERIC_VDSO_DATA_STORE if HAVE_GENERIC_VDSO
 	select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO
 	select HARDIRQS_SW_RESEND
 	select HAS_IOPORT if MMU
diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index f891478829a52c41e06240f67611694cc28197d9..c130d8100232cbe50e52e35eb418e354bd114cb7 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -14,7 +14,7 @@
  */
 #ifdef CONFIG_MMU
 
-#define __VVAR_PAGES    2
+#define __VDSO_PAGES    4
 
 #ifndef __ASSEMBLY__
 #include <generated/vdso-offsets.h>
diff --git a/arch/riscv/include/asm/vdso/time_data.h b/arch/riscv/include/asm/vdso/arch_data.h
similarity index 71%
rename from arch/riscv/include/asm/vdso/time_data.h
rename to arch/riscv/include/asm/vdso/arch_data.h
index dfa65228999bed41dfd6c5e36cb678e1e055eec8..da57a3786f7a53c866fc00948826b4a2d839940f 100644
--- a/arch/riscv/include/asm/vdso/time_data.h
+++ b/arch/riscv/include/asm/vdso/arch_data.h
@@ -1,12 +1,12 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __RISCV_ASM_VDSO_TIME_DATA_H
-#define __RISCV_ASM_VDSO_TIME_DATA_H
+#ifndef __RISCV_ASM_VDSO_ARCH_DATA_H
+#define __RISCV_ASM_VDSO_ARCH_DATA_H
 
 #include <linux/types.h>
 #include <vdso/datapage.h>
 #include <asm/hwprobe.h>
 
-struct arch_vdso_time_data {
+struct vdso_arch_data {
 	/* Stash static answers to the hwprobe queries when all CPUs are selected. */
 	__u64 all_cpu_hwprobe_values[RISCV_HWPROBE_MAX_KEY + 1];
 
@@ -14,4 +14,4 @@ struct arch_vdso_time_data {
 	__u8 homogeneous_cpus;
 };
 
-#endif /* __RISCV_ASM_VDSO_TIME_DATA_H */
+#endif /* __RISCV_ASM_VDSO_ARCH_DATA_H */
diff --git a/arch/riscv/include/asm/vdso/gettimeofday.h b/arch/riscv/include/asm/vdso/gettimeofday.h
index ba3283cf7accaa93a38512d2c17eda0eefde0612..29164f84f93cec6e28251e6a0adfbc341ac88241 100644
--- a/arch/riscv/include/asm/vdso/gettimeofday.h
+++ b/arch/riscv/include/asm/vdso/gettimeofday.h
@@ -69,7 +69,7 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
 #endif /* CONFIG_GENERIC_TIME_VSYSCALL */
 
 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
-						 const struct vdso_data *vd)
+						 const struct vdso_time_data *vd)
 {
 	/*
 	 * The purpose of csr_read(CSR_TIME) is to trap the system into
@@ -79,18 +79,6 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
 	return csr_read(CSR_TIME);
 }
 
-static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
-{
-	return _vdso_data;
-}
-
-#ifdef CONFIG_TIME_NS
-static __always_inline
-const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
-{
-	return _timens_data;
-}
-#endif
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/riscv/include/asm/vdso/vsyscall.h b/arch/riscv/include/asm/vdso/vsyscall.h
index e8a9c4b53c0c9f4744196eed800b21f3918d1040..1140b54b4bc8278d7a322036cd9f84f71258f246 100644
--- a/arch/riscv/include/asm/vdso/vsyscall.h
+++ b/arch/riscv/include/asm/vdso/vsyscall.h
@@ -6,15 +6,6 @@
 
 #include <vdso/datapage.h>
 
-extern struct vdso_data *vdso_data;
-
-static __always_inline struct vdso_data *__riscv_get_k_vdso_data(void)
-{
-	return vdso_data;
-}
-
-#define __arch_get_k_vdso_data __riscv_get_k_vdso_data
-
 /* The asm-generic header needs to be included after the definitions above */
 #include <asm-generic/vdso/vsyscall.h>
 
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index cb93adfffc486e710409fd3b8a8ab22525ac4093..37e155dd3ab26da7b6a03e0b11b467e5aac51091 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -445,8 +445,7 @@ static int do_riscv_hwprobe(struct riscv_hwprobe __user *pairs,
 
 static int __init init_hwprobe_vdso_data(void)
 {
-	struct vdso_data *vd = __arch_get_k_vdso_data();
-	struct arch_vdso_time_data *avd = &vd->arch_data;
+	struct vdso_arch_data *avd = vdso_k_arch_data;
 	u64 id_bitsmash = 0;
 	struct riscv_hwprobe pair;
 	int key;
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index 3ca3ae4277e187e790a8bf513a9e80d8b6290bb2..cc2895d1fbc2fe752b3edc94f4e28a6a8fca7a3b 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -13,20 +13,11 @@
 #include <linux/err.h>
 #include <asm/page.h>
 #include <asm/vdso.h>
-#include <linux/time_namespace.h>
+#include <linux/vdso_datastore.h>
 #include <vdso/datapage.h>
 #include <vdso/vsyscall.h>
 
-enum vvar_pages {
-	VVAR_DATA_PAGE_OFFSET,
-	VVAR_TIMENS_PAGE_OFFSET,
-	VVAR_NR_PAGES,
-};
-
-#define VVAR_SIZE  (VVAR_NR_PAGES << PAGE_SHIFT)
-
-static union vdso_data_store vdso_data_store __page_aligned_data;
-struct vdso_data *vdso_data = vdso_data_store.data;
+#define VVAR_SIZE  (VDSO_NR_PAGES << PAGE_SHIFT)
 
 struct __vdso_info {
 	const char *name;
@@ -79,78 +70,6 @@ static void __init __vdso_init(struct __vdso_info *vdso_info)
 	vdso_info->cm->pages = vdso_pagelist;
 }
 
-#ifdef CONFIG_TIME_NS
-struct vdso_data *arch_get_vdso_data(void *vvar_page)
-{
-	return (struct vdso_data *)(vvar_page);
-}
-
-static const struct vm_special_mapping rv_vvar_map;
-
-/*
- * The vvar mapping contains data for a specific time namespace, so when a task
- * changes namespace we must unmap its vvar data for the old namespace.
- * Subsequent faults will map in data for the new namespace.
- *
- * For more details see timens_setup_vdso_data().
- */
-int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
-{
-	struct mm_struct *mm = task->mm;
-	struct vm_area_struct *vma;
-	VMA_ITERATOR(vmi, mm, 0);
-
-	mmap_read_lock(mm);
-
-	for_each_vma(vmi, vma) {
-		if (vma_is_special_mapping(vma, &rv_vvar_map))
-			zap_vma_pages(vma);
-	}
-
-	mmap_read_unlock(mm);
-	return 0;
-}
-#endif
-
-static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
-			     struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	struct page *timens_page = find_timens_vvar_page(vma);
-	unsigned long pfn;
-
-	switch (vmf->pgoff) {
-	case VVAR_DATA_PAGE_OFFSET:
-		if (timens_page)
-			pfn = page_to_pfn(timens_page);
-		else
-			pfn = sym_to_pfn(vdso_data);
-		break;
-#ifdef CONFIG_TIME_NS
-	case VVAR_TIMENS_PAGE_OFFSET:
-		/*
-		 * If a task belongs to a time namespace then a namespace
-		 * specific VVAR is mapped with the VVAR_DATA_PAGE_OFFSET and
-		 * the real VVAR page is mapped with the VVAR_TIMENS_PAGE_OFFSET
-		 * offset.
-		 * See also the comment near timens_setup_vdso_data().
-		 */
-		if (!timens_page)
-			return VM_FAULT_SIGBUS;
-		pfn = sym_to_pfn(vdso_data);
-		break;
-#endif /* CONFIG_TIME_NS */
-	default:
-		return VM_FAULT_SIGBUS;
-	}
-
-	return vmf_insert_pfn(vma, vmf->address, pfn);
-}
-
-static const struct vm_special_mapping rv_vvar_map = {
-	.name   = "[vvar]",
-	.fault = vvar_fault,
-};
-
 static struct vm_special_mapping rv_vdso_map __ro_after_init = {
 	.name   = "[vdso]",
 	.mremap = vdso_mremap,
@@ -196,7 +115,7 @@ static int __setup_additional_pages(struct mm_struct *mm,
 	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
 	void *ret;
 
-	BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
+	BUILD_BUG_ON(VDSO_NR_PAGES != __VDSO_PAGES);
 
 	vdso_text_len = vdso_info->vdso_pages << PAGE_SHIFT;
 	/* Be sure to map the data page */
@@ -208,8 +127,7 @@ static int __setup_additional_pages(struct mm_struct *mm,
 		goto up_fail;
 	}
 
-	ret = _install_special_mapping(mm, vdso_base, VVAR_SIZE,
-		(VM_READ | VM_MAYREAD | VM_PFNMAP), &rv_vvar_map);
+	ret = vdso_install_vvar_mapping(mm, vdso_base);
 	if (IS_ERR(ret))
 		goto up_fail;
 
diff --git a/arch/riscv/kernel/vdso/hwprobe.c b/arch/riscv/kernel/vdso/hwprobe.c
index a158c029344f60c022e7565757ff44df7e3d89e5..b699b1f65f254ad5b787e168d48a9b0e76d1f37b 100644
--- a/arch/riscv/kernel/vdso/hwprobe.c
+++ b/arch/riscv/kernel/vdso/hwprobe.c
@@ -16,8 +16,7 @@ static int riscv_vdso_get_values(struct riscv_hwprobe *pairs, size_t pair_count,
 				 size_t cpusetsize, unsigned long *cpus,
 				 unsigned int flags)
 {
-	const struct vdso_data *vd = __arch_get_vdso_data();
-	const struct arch_vdso_time_data *avd = &vd->arch_data;
+	const struct vdso_arch_data *avd = __arch_get_vdso_u_arch_data();
 	bool all_cpus = !cpusetsize && !cpus;
 	struct riscv_hwprobe *p = pairs;
 	struct riscv_hwprobe *end = pairs + pair_count;
@@ -51,8 +50,7 @@ static int riscv_vdso_get_cpus(struct riscv_hwprobe *pairs, size_t pair_count,
 			       size_t cpusetsize, unsigned long *cpus,
 			       unsigned int flags)
 {
-	const struct vdso_data *vd = __arch_get_vdso_data();
-	const struct arch_vdso_time_data *avd = &vd->arch_data;
+	const struct vdso_arch_data *avd = __arch_get_vdso_u_arch_data();
 	struct riscv_hwprobe *p = pairs;
 	struct riscv_hwprobe *end = pairs + pair_count;
 	unsigned char *c = (unsigned char *)cpus;
diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S
index cbe2a179331d2511a8b4a26c06383e46131661b1..8e86965a8aae4d7c5a36d0f26026cd1c8680b339 100644
--- a/arch/riscv/kernel/vdso/vdso.lds.S
+++ b/arch/riscv/kernel/vdso/vdso.lds.S
@@ -4,15 +4,14 @@
  */
 #include <asm/page.h>
 #include <asm/vdso.h>
+#include <vdso/datapage.h>
 
 OUTPUT_ARCH(riscv)
 
 SECTIONS
 {
-	PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
-#ifdef CONFIG_TIME_NS
-	PROVIDE(_timens_data = _vdso_data + PAGE_SIZE);
-#endif
+	VDSO_VVAR_SYMS
+
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:04 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:04 +0100
Subject: [PATCH 08/17] LoongArch: vDSO: Switch to generic storage
 implementation
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-8-f7aed1bdb3b2@linutronix.de>

The generic storage implementation provides the same features as the
custom one. However it can be shared between architectures, making
maintenance easier.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/loongarch/Kconfig                         |  2 +
 arch/loongarch/include/asm/vdso.h              |  1 -
 arch/loongarch/include/asm/vdso/arch_data.h    | 25 +++++++
 arch/loongarch/include/asm/vdso/getrandom.h    |  5 --
 arch/loongarch/include/asm/vdso/gettimeofday.h | 14 +---
 arch/loongarch/include/asm/vdso/vdso.h         | 38 +----------
 arch/loongarch/include/asm/vdso/vsyscall.h     | 17 -----
 arch/loongarch/kernel/asm-offsets.c            |  2 +-
 arch/loongarch/kernel/vdso.c                   | 92 +-------------------------
 arch/loongarch/vdso/vdso.lds.S                 |  8 +--
 arch/loongarch/vdso/vgetcpu.c                  |  7 +-
 11 files changed, 38 insertions(+), 173 deletions(-)

diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index dae3a9104ca6584133d9b6a3059ee666c216d31b..6ec7ef705199fdd4039afd23ec9050a28aa894eb 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -29,6 +29,7 @@ config LOONGARCH
 	select ARCH_HAS_SET_MEMORY
 	select ARCH_HAS_SET_DIRECT_MAP
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+	select ARCH_HAS_VDSO_ARCH_DATA
 	select ARCH_INLINE_READ_LOCK if !PREEMPTION
 	select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION
 	select ARCH_INLINE_READ_LOCK_IRQ if !PREEMPTION
@@ -104,6 +105,7 @@ config LOONGARCH
 	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
+	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select GPIOLIB
 	select HAS_IOPORT
diff --git a/arch/loongarch/include/asm/vdso.h b/arch/loongarch/include/asm/vdso.h
index d3ba35eb23e77082ea8ed564fe7378ad80df81b2..f72ec79e2dde52f8888750a53c4af85d6ab77b45 100644
--- a/arch/loongarch/include/asm/vdso.h
+++ b/arch/loongarch/include/asm/vdso.h
@@ -31,7 +31,6 @@ struct loongarch_vdso_info {
 	unsigned long size;
 	unsigned long offset_sigreturn;
 	struct vm_special_mapping code_mapping;
-	struct vm_special_mapping data_mapping;
 };
 
 extern struct loongarch_vdso_info vdso_info;
diff --git a/arch/loongarch/include/asm/vdso/arch_data.h b/arch/loongarch/include/asm/vdso/arch_data.h
new file mode 100644
index 0000000000000000000000000000000000000000..322d0a5f1c844f02de9b074d6021e8e15116f8a2
--- /dev/null
+++ b/arch/loongarch/include/asm/vdso/arch_data.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Author: Huacai Chen <chenhuacai at loongson.cn>
+ * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _VDSO_ARCH_DATA_H
+#define _VDSO_ARCH_DATA_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/asm.h>
+#include <asm/vdso.h>
+
+struct vdso_pcpu_data {
+	u32 node;
+} ____cacheline_aligned_in_smp;
+
+struct vdso_arch_data {
+	struct vdso_pcpu_data pdata[NR_CPUS];
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/loongarch/include/asm/vdso/getrandom.h b/arch/loongarch/include/asm/vdso/getrandom.h
index e80f3c4ac7481ba7f9f5d9210fefa78c3293243b..48c43f55b039b42168698614d0479b7a872d20f3 100644
--- a/arch/loongarch/include/asm/vdso/getrandom.h
+++ b/arch/loongarch/include/asm/vdso/getrandom.h
@@ -28,11 +28,6 @@ static __always_inline ssize_t getrandom_syscall(void *_buffer, size_t _len, uns
 	return ret;
 }
 
-static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void)
-{
-	return &_loongarch_data.rng_data;
-}
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_VDSO_GETRANDOM_H */
diff --git a/arch/loongarch/include/asm/vdso/gettimeofday.h b/arch/loongarch/include/asm/vdso/gettimeofday.h
index 7eb3f041af764d141b005f821593a358096874ba..88cfcf13311630ed5f1a734d23a2bc3f65d79a88 100644
--- a/arch/loongarch/include/asm/vdso/gettimeofday.h
+++ b/arch/loongarch/include/asm/vdso/gettimeofday.h
@@ -72,7 +72,7 @@ static __always_inline int clock_getres_fallback(
 }
 
 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
-						 const struct vdso_data *vd)
+						 const struct vdso_time_data *vd)
 {
 	uint64_t count;
 
@@ -89,18 +89,6 @@ static inline bool loongarch_vdso_hres_capable(void)
 }
 #define __arch_vdso_hres_capable loongarch_vdso_hres_capable
 
-static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
-{
-	return _vdso_data;
-}
-
-#ifdef CONFIG_TIME_NS
-static __always_inline
-const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
-{
-	return _timens_data;
-}
-#endif
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/loongarch/include/asm/vdso/vdso.h b/arch/loongarch/include/asm/vdso/vdso.h
index 1c183a9b2115a29a997ec8db0e788d87fb191dce..50c65fb29dafb464f36615f49db8954ee0a775e3 100644
--- a/arch/loongarch/include/asm/vdso/vdso.h
+++ b/arch/loongarch/include/asm/vdso/vdso.h
@@ -12,43 +12,9 @@
 #include <asm/asm.h>
 #include <asm/page.h>
 #include <asm/vdso.h>
+#include <vdso/datapage.h>
 
-struct vdso_pcpu_data {
-	u32 node;
-} ____cacheline_aligned_in_smp;
-
-struct loongarch_vdso_data {
-	struct vdso_pcpu_data pdata[NR_CPUS];
-	struct vdso_rng_data rng_data;
-};
-
-/*
- * The layout of vvar:
- *
- *                      high
- * +---------------------+--------------------------+
- * | loongarch vdso data | LOONGARCH_VDSO_DATA_SIZE |
- * +---------------------+--------------------------+
- * |  time-ns vdso data  |        PAGE_SIZE         |
- * +---------------------+--------------------------+
- * |  generic vdso data  |        PAGE_SIZE         |
- * +---------------------+--------------------------+
- *                      low
- */
-#define LOONGARCH_VDSO_DATA_SIZE PAGE_ALIGN(sizeof(struct loongarch_vdso_data))
-#define LOONGARCH_VDSO_DATA_PAGES (LOONGARCH_VDSO_DATA_SIZE >> PAGE_SHIFT)
-
-enum vvar_pages {
-	VVAR_GENERIC_PAGE_OFFSET,
-	VVAR_TIMENS_PAGE_OFFSET,
-	VVAR_LOONGARCH_PAGES_START,
-	VVAR_LOONGARCH_PAGES_END = VVAR_LOONGARCH_PAGES_START + LOONGARCH_VDSO_DATA_PAGES - 1,
-	VVAR_NR_PAGES,
-};
-
-#define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT)
-
-extern struct loongarch_vdso_data _loongarch_data __attribute__((visibility("hidden")));
+#define VVAR_SIZE (VDSO_NR_PAGES << PAGE_SHIFT)
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/loongarch/include/asm/vdso/vsyscall.h b/arch/loongarch/include/asm/vdso/vsyscall.h
index 8987e951d0a93c34ca75de676fb9c191ff4ef3c2..1140b54b4bc8278d7a322036cd9f84f71258f246 100644
--- a/arch/loongarch/include/asm/vdso/vsyscall.h
+++ b/arch/loongarch/include/asm/vdso/vsyscall.h
@@ -6,23 +6,6 @@
 
 #include <vdso/datapage.h>
 
-extern struct vdso_data *vdso_data;
-extern struct vdso_rng_data *vdso_rng_data;
-
-static __always_inline
-struct vdso_data *__loongarch_get_k_vdso_data(void)
-{
-	return vdso_data;
-}
-#define __arch_get_k_vdso_data __loongarch_get_k_vdso_data
-
-static __always_inline
-struct vdso_rng_data *__loongarch_get_k_vdso_rng_data(void)
-{
-	return vdso_rng_data;
-}
-#define __arch_get_k_vdso_rng_data __loongarch_get_k_vdso_rng_data
-
 /* The asm-generic header needs to be included after the definitions above */
 #include <asm-generic/vdso/vsyscall.h>
 
diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c
index 049c5c3e370cbb00fdaf6730f7777847c7325fb4..7dcf4980dbead0249ef4daeab431c7d482abfeb5 100644
--- a/arch/loongarch/kernel/asm-offsets.c
+++ b/arch/loongarch/kernel/asm-offsets.c
@@ -327,6 +327,6 @@ static void __used output_vdso_defines(void)
 {
 	COMMENT("LoongArch vDSO offsets.");
 
-	DEFINE(__VVAR_PAGES, VVAR_NR_PAGES);
+	DEFINE(__VDSO_PAGES, VDSO_NR_PAGES);
 	BLANK();
 }
diff --git a/arch/loongarch/kernel/vdso.c b/arch/loongarch/kernel/vdso.c
index 05e5fbac102a902016e633db75d9aff7ed550c50..10cf1608c7b32f8e03bc2c942b51413cf8b9c505 100644
--- a/arch/loongarch/kernel/vdso.c
+++ b/arch/loongarch/kernel/vdso.c
@@ -14,7 +14,7 @@
 #include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/time_namespace.h>
+#include <linux/vdso_datastore.h>
 
 #include <asm/page.h>
 #include <asm/vdso.h>
@@ -25,18 +25,6 @@
 
 extern char vdso_start[], vdso_end[];
 
-/* Kernel-provided data used by the VDSO. */
-static union vdso_data_store generic_vdso_data __page_aligned_data;
-
-static union {
-	u8 page[LOONGARCH_VDSO_DATA_SIZE];
-	struct loongarch_vdso_data vdata;
-} loongarch_vdso_data __page_aligned_data;
-
-struct vdso_data *vdso_data = generic_vdso_data.data;
-struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata;
-struct vdso_rng_data *vdso_rng_data = &loongarch_vdso_data.vdata.rng_data;
-
 static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma)
 {
 	current->mm->context.vdso = (void *)(new_vma->vm_start);
@@ -44,53 +32,12 @@ static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struc
 	return 0;
 }
 
-static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
-			     struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	unsigned long pfn;
-	struct page *timens_page = find_timens_vvar_page(vma);
-
-	switch (vmf->pgoff) {
-	case VVAR_GENERIC_PAGE_OFFSET:
-		if (!timens_page)
-			pfn = sym_to_pfn(vdso_data);
-		else
-			pfn = page_to_pfn(timens_page);
-		break;
-#ifdef CONFIG_TIME_NS
-	case VVAR_TIMENS_PAGE_OFFSET:
-		/*
-		 * If a task belongs to a time namespace then a namespace specific
-		 * VVAR is mapped with the VVAR_GENERIC_PAGE_OFFSET and the real
-		 * VVAR page is mapped with the VVAR_TIMENS_PAGE_OFFSET offset.
-		 * See also the comment near timens_setup_vdso_data().
-		 */
-		if (!timens_page)
-			return VM_FAULT_SIGBUS;
-		else
-			pfn = sym_to_pfn(vdso_data);
-		break;
-#endif /* CONFIG_TIME_NS */
-	case VVAR_LOONGARCH_PAGES_START ... VVAR_LOONGARCH_PAGES_END:
-		pfn = sym_to_pfn(&loongarch_vdso_data) + vmf->pgoff - VVAR_LOONGARCH_PAGES_START;
-		break;
-	default:
-		return VM_FAULT_SIGBUS;
-	}
-
-	return vmf_insert_pfn(vma, vmf->address, pfn);
-}
-
 struct loongarch_vdso_info vdso_info = {
 	.vdso = vdso_start,
 	.code_mapping = {
 		.name = "[vdso]",
 		.mremap = vdso_mremap,
 	},
-	.data_mapping = {
-		.name = "[vvar]",
-		.fault = vvar_fault,
-	},
 	.offset_sigreturn = vdso_offset_sigreturn,
 };
 
@@ -101,7 +48,7 @@ static int __init init_vdso(void)
 	BUG_ON(!PAGE_ALIGNED(vdso_info.vdso));
 
 	for_each_possible_cpu(cpu)
-		vdso_pdata[cpu].node = cpu_to_node(cpu);
+		vdso_k_arch_data->pdata[cpu].node = cpu_to_node(cpu);
 
 	vdso_info.size = PAGE_ALIGN(vdso_end - vdso_start);
 	vdso_info.code_mapping.pages =
@@ -115,37 +62,6 @@ static int __init init_vdso(void)
 }
 subsys_initcall(init_vdso);
 
-#ifdef CONFIG_TIME_NS
-struct vdso_data *arch_get_vdso_data(void *vvar_page)
-{
-	return (struct vdso_data *)(vvar_page);
-}
-
-/*
- * The vvar mapping contains data for a specific time namespace, so when a
- * task changes namespace we must unmap its vvar data for the old namespace.
- * Subsequent faults will map in data for the new namespace.
- *
- * For more details see timens_setup_vdso_data().
- */
-int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
-{
-	struct mm_struct *mm = task->mm;
-	struct vm_area_struct *vma;
-
-	VMA_ITERATOR(vmi, mm, 0);
-
-	mmap_read_lock(mm);
-	for_each_vma(vmi, vma) {
-		if (vma_is_special_mapping(vma, &vdso_info.data_mapping))
-			zap_vma_pages(vma);
-	}
-	mmap_read_unlock(mm);
-
-	return 0;
-}
-#endif
-
 static unsigned long vdso_base(void)
 {
 	unsigned long base = STACK_TOP;
@@ -181,9 +97,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 		goto out;
 	}
 
-	vma = _install_special_mapping(mm, data_addr, VVAR_SIZE,
-				       VM_READ | VM_MAYREAD | VM_PFNMAP,
-				       &info->data_mapping);
+	vma = vdso_install_vvar_mapping(mm, data_addr);
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
 		goto out;
diff --git a/arch/loongarch/vdso/vdso.lds.S b/arch/loongarch/vdso/vdso.lds.S
index 160cfaef2de45b1243502c7356f8a913658548fe..8ff98649994750e74b30a91270d9d9ea2ba751e8 100644
--- a/arch/loongarch/vdso/vdso.lds.S
+++ b/arch/loongarch/vdso/vdso.lds.S
@@ -5,6 +5,7 @@
  */
 #include <asm/page.h>
 #include <generated/asm-offsets.h>
+#include <vdso/datapage.h>
 
 OUTPUT_FORMAT("elf64-loongarch", "elf64-loongarch", "elf64-loongarch")
 
@@ -12,11 +13,8 @@ OUTPUT_ARCH(loongarch)
 
 SECTIONS
 {
-	PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
-#ifdef CONFIG_TIME_NS
-	PROVIDE(_timens_data = _vdso_data + PAGE_SIZE);
-#endif
-	PROVIDE(_loongarch_data = _vdso_data + 2 * PAGE_SIZE);
+	VDSO_VVAR_SYMS
+
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text
diff --git a/arch/loongarch/vdso/vgetcpu.c b/arch/loongarch/vdso/vgetcpu.c
index 0db51258b2a7ca7e44d2eb68ea514face48393f7..3798eebdf798dfa6574a8e51d6f58c206725c312 100644
--- a/arch/loongarch/vdso/vgetcpu.c
+++ b/arch/loongarch/vdso/vgetcpu.c
@@ -19,11 +19,6 @@ static __always_inline int read_cpu_id(void)
 	return cpu_id;
 }
 
-static __always_inline const struct vdso_pcpu_data *get_pcpu_data(void)
-{
-	return _loongarch_data.pdata;
-}
-
 extern
 int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused);
 int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused)
@@ -37,7 +32,7 @@ int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *un
 		*cpu = cpu_id;
 
 	if (node) {
-		data = get_pcpu_data();
+		data = __arch_get_vdso_u_arch_data()->pdata;
 		*node = data[cpu_id].node;
 	}
 

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:05 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:05 +0100
Subject: [PATCH 09/17] arm: vdso: Switch to generic storage implementation
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-9-f7aed1bdb3b2@linutronix.de>

The generic storage implementation provides the same features as the
custom one. However it can be shared between architectures, making
maintenance easier.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/arm/include/asm/vdso.h              |  2 ++
 arch/arm/include/asm/vdso/gettimeofday.h |  7 +------
 arch/arm/include/asm/vdso/vsyscall.h     | 12 ++---------
 arch/arm/kernel/asm-offsets.c            |  4 ----
 arch/arm/kernel/vdso.c                   | 34 +++++++-------------------------
 arch/arm/mm/Kconfig                      |  1 +
 arch/arm/vdso/vdso.lds.S                 |  4 ++--
 7 files changed, 15 insertions(+), 49 deletions(-)

diff --git a/arch/arm/include/asm/vdso.h b/arch/arm/include/asm/vdso.h
index 5b85889f82eeb422400c039e8b5e8a2a6d4553b3..88364a6727ffce224edd35dd62db1693ae5fcb1c 100644
--- a/arch/arm/include/asm/vdso.h
+++ b/arch/arm/include/asm/vdso.h
@@ -4,6 +4,8 @@
 
 #ifdef __KERNEL__
 
+#define __VDSO_PAGES	4
+
 #ifndef __ASSEMBLY__
 
 struct mm_struct;
diff --git a/arch/arm/include/asm/vdso/gettimeofday.h b/arch/arm/include/asm/vdso/gettimeofday.h
index 592d3d015ca7298b3bc35871387dbb3e7f819827..1e9f81639c88cc23cae7cf267bf4674c6d6acec0 100644
--- a/arch/arm/include/asm/vdso/gettimeofday.h
+++ b/arch/arm/include/asm/vdso/gettimeofday.h
@@ -112,7 +112,7 @@ static inline bool arm_vdso_hres_capable(void)
 #define __arch_vdso_hres_capable arm_vdso_hres_capable
 
 static __always_inline u64 __arch_get_hw_counter(int clock_mode,
-						 const struct vdso_data *vd)
+						 const struct vdso_time_data *vd)
 {
 #ifdef CONFIG_ARM_ARCH_TIMER
 	u64 cycle_now;
@@ -135,11 +135,6 @@ static __always_inline u64 __arch_get_hw_counter(int clock_mode,
 #endif
 }
 
-static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
-{
-	return _vdso_data;
-}
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/arm/include/asm/vdso/vsyscall.h b/arch/arm/include/asm/vdso/vsyscall.h
index 705414710dcdbfa9a97c344806bd079c08368801..6fe8f7113e9e533a8b7582f71611372c8db3b11f 100644
--- a/arch/arm/include/asm/vdso/vsyscall.h
+++ b/arch/arm/include/asm/vdso/vsyscall.h
@@ -7,22 +7,14 @@
 #include <vdso/datapage.h>
 #include <asm/cacheflush.h>
 
-extern struct vdso_data *vdso_data;
 extern bool cntvct_ok;
 
 static __always_inline
-struct vdso_data *__arm_get_k_vdso_data(void)
-{
-	return vdso_data;
-}
-#define __arch_get_k_vdso_data __arm_get_k_vdso_data
-
-static __always_inline
-void __arm_sync_vdso_data(struct vdso_data *vdata)
+void __arm_sync_vdso_time_data(struct vdso_time_data *vdata)
 {
 	flush_dcache_page(virt_to_page(vdata));
 }
-#define __arch_sync_vdso_data __arm_sync_vdso_data
+#define __arch_sync_vdso_data __arm_sync_vdso_time_data
 
 /* The asm-generic header needs to be included after the definitions above */
 #include <asm-generic/vdso/vsyscall.h>
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 4853875740d0fe61c6bbc32ddd9a16fa8d1fb530..123f4a8ef44660a39c4eff2a6e5fd86cb48fb572 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -153,10 +153,6 @@ int main(void)
   DEFINE(CACHE_WRITEBACK_ORDER, __CACHE_WRITEBACK_ORDER);
   DEFINE(CACHE_WRITEBACK_GRANULE, __CACHE_WRITEBACK_GRANULE);
   BLANK();
-#ifdef CONFIG_VDSO
-  DEFINE(VDSO_DATA_SIZE,	sizeof(union vdso_data_store));
-#endif
-  BLANK();
 #ifdef CONFIG_ARM_MPU
   DEFINE(MPU_RNG_INFO_RNGS,	offsetof(struct mpu_rgn_info, rgns));
   DEFINE(MPU_RNG_INFO_USED,	offsetof(struct mpu_rgn_info, used));
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index 29dd2f3c62fec64c7f290468421bfad1e739c667..325448ffbba0c29895ea5d97e60d6f51e552cb2e 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/cache.h>
+#include <linux/vdso_datastore.h>
 #include <linux/elf.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
@@ -33,15 +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;
 
-static union vdso_data_store vdso_data_store __page_aligned_data;
-struct vdso_data *vdso_data = vdso_data_store.data;
-
-static struct page *vdso_data_page __ro_after_init;
-static const struct vm_special_mapping vdso_data_mapping = {
-	.name = "[vvar]",
-	.pages = &vdso_data_page,
-};
-
 static int vdso_mremap(const struct vm_special_mapping *sm,
 		struct vm_area_struct *new_vma)
 {
@@ -192,9 +184,6 @@ static int __init vdso_init(void)
 	if (vdso_text_pagelist == NULL)
 		return -ENOMEM;
 
-	/* Grab the VDSO data page. */
-	vdso_data_page = virt_to_page(vdso_data);
-
 	/* Grab the VDSO text pages. */
 	for (i = 0; i < text_pages; i++) {
 		struct page *page;
@@ -205,7 +194,7 @@ static int __init vdso_init(void)
 
 	vdso_text_mapping.pages = vdso_text_pagelist;
 
-	vdso_total_pages = 1; /* for the data/vvar page */
+	vdso_total_pages = VDSO_NR_PAGES; /* for the data/vvar pages */
 	vdso_total_pages += text_pages;
 
 	cntvct_ok = cntvct_functional();
@@ -216,16 +205,7 @@ static int __init vdso_init(void)
 }
 arch_initcall(vdso_init);
 
-static int install_vvar(struct mm_struct *mm, unsigned long addr)
-{
-	struct vm_area_struct *vma;
-
-	vma = _install_special_mapping(mm, addr, PAGE_SIZE,
-				       VM_READ | VM_MAYREAD,
-				       &vdso_data_mapping);
-
-	return PTR_ERR_OR_ZERO(vma);
-}
+static_assert(__VDSO_PAGES == VDSO_NR_PAGES);
 
 /* assumes mmap_lock is write-locked */
 void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
@@ -238,12 +218,12 @@ void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
 	if (vdso_text_pagelist == NULL)
 		return;
 
-	if (install_vvar(mm, addr))
+	if (IS_ERR(vdso_install_vvar_mapping(mm, addr)))
 		return;
 
-	/* Account for vvar page. */
-	addr += PAGE_SIZE;
-	len = (vdso_total_pages - 1) << PAGE_SHIFT;
+	/* Account for vvar pages. */
+	addr += VDSO_NR_PAGES * PAGE_SIZE;
+	len = (vdso_total_pages - VDSO_NR_PAGES) << PAGE_SHIFT;
 
 	vma = _install_special_mapping(mm, addr, len,
 		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 2b6f50dd547840adecbe08e684ed8f1a032cd7c2..5c1023a6d78c1b4db67b2d62b71af5a79b7e701f 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -928,6 +928,7 @@ config VDSO
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_VDSO_32
 	select GENERIC_GETTIMEOFDAY
+	select GENERIC_VDSO_DATA_STORE
 	help
 	  Place in the process address space an ELF shared object
 	  providing fast implementations of gettimeofday and
diff --git a/arch/arm/vdso/vdso.lds.S b/arch/arm/vdso/vdso.lds.S
index 9bfa0f52923c851b6b9e96d4dbb51eb3d5d0960a..7c08371f440027f9a52e9fffae530d7db05b7c43 100644
--- a/arch/arm/vdso/vdso.lds.S
+++ b/arch/arm/vdso/vdso.lds.S
@@ -11,16 +11,16 @@
  */
 
 #include <linux/const.h>
-#include <asm/asm-offsets.h>
 #include <asm/page.h>
 #include <asm/vdso.h>
+#include <vdso/datapage.h>
 
 OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
 OUTPUT_ARCH(arm)
 
 SECTIONS
 {
-	PROVIDE(_vdso_data = . - VDSO_DATA_SIZE);
+	VDSO_VVAR_SYMS
 
 	. = SIZEOF_HEADERS;
 

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:06 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:06 +0100
Subject: [PATCH 10/17] s390/vdso: Switch to generic storage implementation
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-10-f7aed1bdb3b2@linutronix.de>

The generic storage implementation provides the same features as the
custom one. However it can be shared between architectures, making
maintenance easier.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/s390/Kconfig                         |  1 +
 arch/s390/include/asm/vdso.h              |  4 +-
 arch/s390/include/asm/vdso/getrandom.h    | 12 ----
 arch/s390/include/asm/vdso/gettimeofday.h | 15 +----
 arch/s390/include/asm/vdso/vsyscall.h     | 20 -------
 arch/s390/kernel/time.c                   |  6 +-
 arch/s390/kernel/vdso.c                   | 97 ++-----------------------------
 arch/s390/kernel/vdso32/vdso32.lds.S      |  7 +--
 arch/s390/kernel/vdso64/vdso64.lds.S      |  8 +--
 9 files changed, 17 insertions(+), 153 deletions(-)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 0077969170e8b4ca4c99e87ec75f6ea94f3e8e00..6472eb4c210f378eaa61ddff04a6abc2f4aa2940 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -158,6 +158,7 @@ config S390
 	select GENERIC_PTDUMP
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
+	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select GENERIC_IOREMAP if PCI
 	select HAVE_ALIGNED_STRUCT_PAGE
diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h
index 92c73e4d97a93a90cb640d44fca9856f93e0be14..420a073fdde5db92cfe84bb1f17a549f333f94e0 100644
--- a/arch/s390/include/asm/vdso.h
+++ b/arch/s390/include/asm/vdso.h
@@ -6,13 +6,11 @@
 
 #ifndef __ASSEMBLY__
 
-extern struct vdso_data *vdso_data;
-
 int vdso_getcpu_init(void);
 
 #endif /* __ASSEMBLY__ */
 
-#define __VVAR_PAGES	2
+#define __VDSO_PAGES	4
 
 #define VDSO_VERSION_STRING	LINUX_2.6.29
 
diff --git a/arch/s390/include/asm/vdso/getrandom.h b/arch/s390/include/asm/vdso/getrandom.h
index 36355af7160bee4f04f5177cfa21283699bee006..f8713ce39bb2f2081c3bb5a42eddccc3cddc40c8 100644
--- a/arch/s390/include/asm/vdso/getrandom.h
+++ b/arch/s390/include/asm/vdso/getrandom.h
@@ -23,18 +23,6 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig
 	return syscall3(__NR_getrandom, (long)buffer, (long)len, (long)flags);
 }
 
-static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void)
-{
-	/*
-	 * The RNG data is in the real VVAR data page, but if a task belongs to a time namespace
-	 * then VVAR_DATA_PAGE_OFFSET points to the namespace-specific VVAR page and VVAR_TIMENS_
-	 * PAGE_OFFSET points to the real VVAR page.
-	 */
-	if (IS_ENABLED(CONFIG_TIME_NS) && _vdso_data->clock_mode == VDSO_CLOCKMODE_TIMENS)
-		return (void *)&_vdso_rng_data + VVAR_TIMENS_PAGE_OFFSET * PAGE_SIZE;
-	return &_vdso_rng_data;
-}
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_VDSO_GETRANDOM_H */
diff --git a/arch/s390/include/asm/vdso/gettimeofday.h b/arch/s390/include/asm/vdso/gettimeofday.h
index 7937765ccfa5b222931591cc5388827e5f75d1b5..fb4564308e9d77a40f8d5059503519e9f5961f14 100644
--- a/arch/s390/include/asm/vdso/gettimeofday.h
+++ b/arch/s390/include/asm/vdso/gettimeofday.h
@@ -14,12 +14,7 @@
 #include <linux/compiler.h>
 
 
-static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
-{
-	return _vdso_data;
-}
-
-static inline u64 __arch_get_hw_counter(s32 clock_mode, const struct vdso_data *vd)
+static inline u64 __arch_get_hw_counter(s32 clock_mode, const struct vdso_time_data *vd)
 {
 	u64 adj, now;
 
@@ -49,12 +44,4 @@ long clock_getres_fallback(clockid_t clkid, struct __kernel_timespec *ts)
 	return syscall2(__NR_clock_getres, (long)clkid, (long)ts);
 }
 
-#ifdef CONFIG_TIME_NS
-static __always_inline
-const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
-{
-	return _timens_data;
-}
-#endif
-
 #endif
diff --git a/arch/s390/include/asm/vdso/vsyscall.h b/arch/s390/include/asm/vdso/vsyscall.h
index 3eb576ecd3bd998daf9372a52befa8b76d52f2bf..d346ebe513015e767405452cd69495ae497c91ee 100644
--- a/arch/s390/include/asm/vdso/vsyscall.h
+++ b/arch/s390/include/asm/vdso/vsyscall.h
@@ -2,32 +2,12 @@
 #ifndef __ASM_VDSO_VSYSCALL_H
 #define __ASM_VDSO_VSYSCALL_H
 
-#define __VDSO_RND_DATA_OFFSET	768
-
 #ifndef __ASSEMBLY__
 
 #include <linux/hrtimer.h>
 #include <vdso/datapage.h>
 #include <asm/vdso.h>
 
-enum vvar_pages {
-	VVAR_DATA_PAGE_OFFSET,
-	VVAR_TIMENS_PAGE_OFFSET,
-	VVAR_NR_PAGES
-};
-
-static __always_inline struct vdso_data *__s390_get_k_vdso_data(void)
-{
-	return vdso_data;
-}
-#define __arch_get_k_vdso_data __s390_get_k_vdso_data
-
-static __always_inline struct vdso_rng_data *__s390_get_k_vdso_rnd_data(void)
-{
-	return (void *)vdso_data + __VDSO_RND_DATA_OFFSET;
-}
-#define __arch_get_k_vdso_rng_data __s390_get_k_vdso_rnd_data
-
 /* The asm-generic header needs to be included after the definitions above */
 #include <asm-generic/vdso/vsyscall.h>
 
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 34a65c141ea076ba97b3238f1f36f077b15961df..a227621652ad682532cb2cc763f6cfe4368fe3d3 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -84,7 +84,7 @@ void __init time_early_init(void)
 	/* Initialize TOD steering parameters */
 	tod_steering_end = tod_clock_base.tod;
 	for (cs = 0; cs < CS_BASES; cs++)
-		vdso_data[cs].arch_data.tod_steering_end = tod_steering_end;
+		vdso_k_time_data[cs].arch_data.tod_steering_end = tod_steering_end;
 
 	if (!test_facility(28))
 		return;
@@ -390,8 +390,8 @@ static void clock_sync_global(long delta)
 		      tod_steering_delta);
 	tod_steering_end = now + (abs(tod_steering_delta) << 15);
 	for (cs = 0; cs < CS_BASES; cs++) {
-		vdso_data[cs].arch_data.tod_steering_end = tod_steering_end;
-		vdso_data[cs].arch_data.tod_steering_delta = tod_steering_delta;
+		vdso_k_time_data[cs].arch_data.tod_steering_end = tod_steering_end;
+		vdso_k_time_data[cs].arch_data.tod_steering_delta = tod_steering_delta;
 	}
 
 	/* Update LPAR offset. */
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 598b512cde012b1857c748042ceeea65b54cb92f..70c8f9ad13cde96f0f307213bacb671b818f628b 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -16,8 +16,8 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
-#include <linux/time_namespace.h>
 #include <linux/random.h>
+#include <linux/vdso_datastore.h>
 #include <vdso/datapage.h>
 #include <asm/vdso/vsyscall.h>
 #include <asm/alternative.h>
@@ -26,85 +26,6 @@
 extern char vdso64_start[], vdso64_end[];
 extern char vdso32_start[], vdso32_end[];
 
-static struct vm_special_mapping vvar_mapping;
-
-static union vdso_data_store vdso_data_store __page_aligned_data;
-
-struct vdso_data *vdso_data = vdso_data_store.data;
-
-#ifdef CONFIG_TIME_NS
-struct vdso_data *arch_get_vdso_data(void *vvar_page)
-{
-	return (struct vdso_data *)(vvar_page);
-}
-
-/*
- * The VVAR page layout depends on whether a task belongs to the root or
- * non-root time namespace. Whenever a task changes its namespace, the VVAR
- * page tables are cleared and then they will be re-faulted with a
- * corresponding layout.
- * See also the comment near timens_setup_vdso_data() for details.
- */
-int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
-{
-	struct mm_struct *mm = task->mm;
-	VMA_ITERATOR(vmi, mm, 0);
-	struct vm_area_struct *vma;
-
-	mmap_read_lock(mm);
-	for_each_vma(vmi, vma) {
-		if (!vma_is_special_mapping(vma, &vvar_mapping))
-			continue;
-		zap_vma_pages(vma);
-		break;
-	}
-	mmap_read_unlock(mm);
-	return 0;
-}
-#endif
-
-static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
-			     struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	struct page *timens_page = find_timens_vvar_page(vma);
-	unsigned long addr, pfn;
-	vm_fault_t err;
-
-	switch (vmf->pgoff) {
-	case VVAR_DATA_PAGE_OFFSET:
-		pfn = virt_to_pfn(vdso_data);
-		if (timens_page) {
-			/*
-			 * Fault in VVAR page too, since it will be accessed
-			 * to get clock data anyway.
-			 */
-			addr = vmf->address + VVAR_TIMENS_PAGE_OFFSET * PAGE_SIZE;
-			err = vmf_insert_pfn(vma, addr, pfn);
-			if (unlikely(err & VM_FAULT_ERROR))
-				return err;
-			pfn = page_to_pfn(timens_page);
-		}
-		break;
-#ifdef CONFIG_TIME_NS
-	case VVAR_TIMENS_PAGE_OFFSET:
-		/*
-		 * If a task belongs to a time namespace then a namespace
-		 * specific VVAR is mapped with the VVAR_DATA_PAGE_OFFSET and
-		 * the real VVAR page is mapped with the VVAR_TIMENS_PAGE_OFFSET
-		 * offset.
-		 * See also the comment near timens_setup_vdso_data().
-		 */
-		if (!timens_page)
-			return VM_FAULT_SIGBUS;
-		pfn = virt_to_pfn(vdso_data);
-		break;
-#endif /* CONFIG_TIME_NS */
-	default:
-		return VM_FAULT_SIGBUS;
-	}
-	return vmf_insert_pfn(vma, vmf->address, pfn);
-}
-
 static int vdso_mremap(const struct vm_special_mapping *sm,
 		       struct vm_area_struct *vma)
 {
@@ -112,11 +33,6 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
 	return 0;
 }
 
-static struct vm_special_mapping vvar_mapping = {
-	.name = "[vvar]",
-	.fault = vvar_fault,
-};
-
 static struct vm_special_mapping vdso64_mapping = {
 	.name = "[vdso]",
 	.mremap = vdso_mremap,
@@ -142,7 +58,7 @@ static int map_vdso(unsigned long addr, unsigned long vdso_mapping_len)
 	struct vm_area_struct *vma;
 	int rc;
 
-	BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
+	BUILD_BUG_ON(VDSO_NR_PAGES != __VDSO_PAGES);
 	if (mmap_write_lock_killable(mm))
 		return -EINTR;
 
@@ -157,14 +73,11 @@ static int map_vdso(unsigned long addr, unsigned long vdso_mapping_len)
 	rc = vvar_start;
 	if (IS_ERR_VALUE(vvar_start))
 		goto out;
-	vma = _install_special_mapping(mm, vvar_start, VVAR_NR_PAGES*PAGE_SIZE,
-				       VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP|
-				       VM_PFNMAP,
-				       &vvar_mapping);
+	vma = vdso_install_vvar_mapping(mm, vvar_start);
 	rc = PTR_ERR(vma);
 	if (IS_ERR(vma))
 		goto out;
-	vdso_text_start = vvar_start + VVAR_NR_PAGES * PAGE_SIZE;
+	vdso_text_start = vvar_start + VDSO_NR_PAGES * PAGE_SIZE;
 	/* VM_MAYWRITE for COW so gdb can set breakpoints */
 	vma = _install_special_mapping(mm, vdso_text_start, vdso_text_len,
 				       VM_READ|VM_EXEC|
@@ -220,7 +133,7 @@ unsigned long vdso_text_size(void)
 
 unsigned long vdso_size(void)
 {
-	return vdso_text_size() + VVAR_NR_PAGES * PAGE_SIZE;
+	return vdso_text_size() + VDSO_NR_PAGES * PAGE_SIZE;
 }
 
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
diff --git a/arch/s390/kernel/vdso32/vdso32.lds.S b/arch/s390/kernel/vdso32/vdso32.lds.S
index c916c4f73f766ebcc9328b189e46015e67393b0d..9630d58c20806b51f3a2f3b59a53409ad6d3508f 100644
--- a/arch/s390/kernel/vdso32/vdso32.lds.S
+++ b/arch/s390/kernel/vdso32/vdso32.lds.S
@@ -6,16 +6,15 @@
 
 #include <asm/page.h>
 #include <asm/vdso.h>
+#include <vdso/datapage.h>
 
 OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
 OUTPUT_ARCH(s390:31-bit)
 
 SECTIONS
 {
-	PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
-#ifdef CONFIG_TIME_NS
-	PROVIDE(_timens_data = _vdso_data + PAGE_SIZE);
-#endif
+	VDSO_VVAR_SYMS
+
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text
diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso64/vdso64.lds.S
index ec42b7d9cb53094b783c6b0492962af7e5027831..e4f6551ae898881baff6d37701a9d8d9188a52cc 100644
--- a/arch/s390/kernel/vdso64/vdso64.lds.S
+++ b/arch/s390/kernel/vdso64/vdso64.lds.S
@@ -7,17 +7,15 @@
 #include <asm/vdso/vsyscall.h>
 #include <asm/page.h>
 #include <asm/vdso.h>
+#include <vdso/datapage.h>
 
 OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
 OUTPUT_ARCH(s390:64-bit)
 
 SECTIONS
 {
-	PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
-	PROVIDE(_vdso_rng_data = _vdso_data + __VDSO_RND_DATA_OFFSET);
-#ifdef CONFIG_TIME_NS
-	PROVIDE(_timens_data = _vdso_data + PAGE_SIZE);
-#endif
+	VDSO_VVAR_SYMS
+
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:07 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:07 +0100
Subject: [PATCH 11/17] MIPS: vdso: Switch to generic storage implementation
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-11-f7aed1bdb3b2@linutronix.de>

The generic storage implementation provides the same features as the
custom one. However it can be shared between architectures, making
maintenance easier.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/mips/Kconfig                         |  1 +
 arch/mips/include/asm/vdso/gettimeofday.h |  9 +++---
 arch/mips/include/asm/vdso/vdso.h         | 19 ++++++-------
 arch/mips/include/asm/vdso/vsyscall.h     | 14 ++-------
 arch/mips/kernel/vdso.c                   | 47 ++++++++++++-------------------
 arch/mips/vdso/vdso.lds.S                 |  5 +++-
 6 files changed, 38 insertions(+), 57 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 467b10f4361aeb7aad0121f334eaa5d23351010c..94fae59589ae80d590ac250b52ba30e9dd6eda32 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -49,6 +49,7 @@ config MIPS
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_TIME_VSYSCALL
+	select GENERIC_VDSO_DATA_STORE
 	select GUP_GET_PXX_LOW_HIGH if CPU_MIPS32 && PHYS_ADDR_T_64BIT
 	select HAS_IOPORT if !NO_IOPORT_MAP || ISA
 	select HAVE_ARCH_COMPILER_H
diff --git a/arch/mips/include/asm/vdso/gettimeofday.h b/arch/mips/include/asm/vdso/gettimeofday.h
index 44a45f3fa4b01026e39efb7f8f51051ec464340c..18220bc823f7fac5b70cfbc4c876c91e752fafaa 100644
--- a/arch/mips/include/asm/vdso/gettimeofday.h
+++ b/arch/mips/include/asm/vdso/gettimeofday.h
@@ -167,7 +167,7 @@ static __always_inline u64 read_r4k_count(void)
 
 #ifdef CONFIG_CLKSRC_MIPS_GIC
 
-static __always_inline u64 read_gic_count(const struct vdso_data *data)
+static __always_inline u64 read_gic_count(const struct vdso_time_data *data)
 {
 	void __iomem *gic = get_gic(data);
 	u32 hi, hi2, lo;
@@ -184,7 +184,7 @@ static __always_inline u64 read_gic_count(const struct vdso_data *data)
 #endif
 
 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
-						 const struct vdso_data *vd)
+						 const struct vdso_time_data *vd)
 {
 #ifdef CONFIG_CSRC_R4K
 	if (clock_mode == VDSO_CLOCKMODE_R4K)
@@ -209,10 +209,11 @@ static inline bool mips_vdso_hres_capable(void)
 }
 #define __arch_vdso_hres_capable mips_vdso_hres_capable
 
-static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
+static __always_inline const struct vdso_time_data *__mips_get_vdso_u_time_data(void)
 {
-	return get_vdso_data();
+	return get_vdso_time_data();
 }
+#define __arch_get_vdso_u_time_data __mips_get_vdso_u_time_data
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/mips/include/asm/vdso/vdso.h b/arch/mips/include/asm/vdso/vdso.h
index 6cd88191fefa9ce6d8323dd70d45aa9a198ac9d0..acd0efcd3d93ef7e71107302a40d24b4b51aae99 100644
--- a/arch/mips/include/asm/vdso/vdso.h
+++ b/arch/mips/include/asm/vdso/vdso.h
@@ -5,16 +5,18 @@
  */
 
 #include <asm/sgidefs.h>
+#include <vdso/page.h>
+
+#define __VDSO_PAGES 4
 
 #ifndef __ASSEMBLY__
 
 #include <asm/asm.h>
-#include <asm/page.h>
 #include <asm/vdso.h>
 
-static inline unsigned long get_vdso_base(void)
+static inline const struct vdso_time_data *get_vdso_time_data(void)
 {
-	unsigned long addr;
+	const struct vdso_time_data *addr;
 
 	/*
 	 * We can't use cpu_has_mips_r6 since it needs the cpu_data[]
@@ -27,7 +29,7 @@ static inline unsigned long get_vdso_base(void)
 	 * We can't use addiupc because there is no label-label
 	 * support for the addiupc reloc
 	 */
-	__asm__("lapc	%0, _start			\n"
+	__asm__("lapc	%0, vdso_u_time_data		\n"
 		: "=r" (addr) : :);
 #else
 	/*
@@ -46,7 +48,7 @@ static inline unsigned long get_vdso_base(void)
 	"	.set noreorder				\n"
 	"	bal	1f				\n"
 	"	 nop					\n"
-	"	.word	_start - .			\n"
+	"	.word	vdso_u_time_data - .		\n"
 	"1:	lw	%0, 0($31)			\n"
 	"	" STR(PTR_ADDU) " %0, $31, %0		\n"
 	"	.set pop				\n"
@@ -58,14 +60,9 @@ static inline unsigned long get_vdso_base(void)
 	return addr;
 }
 
-static inline const struct vdso_data *get_vdso_data(void)
-{
-	return (const struct vdso_data *)(get_vdso_base() - PAGE_SIZE);
-}
-
 #ifdef CONFIG_CLKSRC_MIPS_GIC
 
-static inline void __iomem *get_gic(const struct vdso_data *data)
+static inline void __iomem *get_gic(const struct vdso_time_data *data)
 {
 	return (void __iomem *)((unsigned long)data & PAGE_MASK) - PAGE_SIZE;
 }
diff --git a/arch/mips/include/asm/vdso/vsyscall.h b/arch/mips/include/asm/vdso/vsyscall.h
index a4582870aaea49ac288d62ec4fa1338a98621918..2b1debb62dee07bb49ab64f755ff9120d512458a 100644
--- a/arch/mips/include/asm/vdso/vsyscall.h
+++ b/arch/mips/include/asm/vdso/vsyscall.h
@@ -2,22 +2,12 @@
 #ifndef __ASM_VDSO_VSYSCALL_H
 #define __ASM_VDSO_VSYSCALL_H
 
+#include <asm/page.h>
+
 #ifndef __ASSEMBLY__
 
 #include <vdso/datapage.h>
 
-extern struct vdso_data *vdso_data;
-
-/*
- * Update the vDSO data page to keep in sync with kernel timekeeping.
- */
-static __always_inline
-struct vdso_data *__mips_get_k_vdso_data(void)
-{
-	return vdso_data;
-}
-#define __arch_get_k_vdso_data __mips_get_k_vdso_data
-
 /* The asm-generic header needs to be included after the definitions above */
 #include <asm-generic/vdso/vsyscall.h>
 
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 4c8e3c0aa210476d7b8cb349b99e9a5a453aa7ce..470bf52970c9fc17b275e4e051378f8f08ebf986 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -14,6 +14,7 @@
 #include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/vdso_datastore.h>
 
 #include <asm/abi.h>
 #include <asm/mips-cps.h>
@@ -22,20 +23,7 @@
 #include <vdso/helpers.h>
 #include <vdso/vsyscall.h>
 
-/* Kernel-provided data used by the VDSO. */
-static union vdso_data_store mips_vdso_data __page_aligned_data;
-struct vdso_data *vdso_data = mips_vdso_data.data;
-
-/*
- * Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as
- * what we map and where within the area they are mapped is determined at
- * runtime.
- */
-static struct page *no_pages[] = { NULL };
-static struct vm_special_mapping vdso_vvar_mapping = {
-	.name = "[vvar]",
-	.pages = no_pages,
-};
+static_assert(VDSO_NR_PAGES == __VDSO_PAGES);
 
 static void __init init_vdso_image(struct mips_vdso_image *image)
 {
@@ -89,7 +77,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mips_vdso_image *image = current->thread.abi->vdso;
 	struct mm_struct *mm = current->mm;
-	unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr, gic_pfn, gic_base;
+	unsigned long gic_size, size, base, data_addr, vdso_addr, gic_pfn, gic_base;
 	struct vm_area_struct *vma;
 	int ret;
 
@@ -117,8 +105,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	 * the counter registers at the start.
 	 */
 	gic_size = mips_gic_present() ? PAGE_SIZE : 0;
-	vvar_size = gic_size + PAGE_SIZE;
-	size = vvar_size + image->size;
+	size = gic_size + VDSO_NR_PAGES * PAGE_SIZE + image->size;
 
 	/*
 	 * Find a region that's large enough for us to perform the
@@ -141,15 +128,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	 */
 	if (cpu_has_dc_aliases) {
 		base = __ALIGN_MASK(base, shm_align_mask);
-		base += ((unsigned long)vdso_data - gic_size) & shm_align_mask;
+		base += ((unsigned long)vdso_k_time_data - gic_size) & shm_align_mask;
 	}
 
 	data_addr = base + gic_size;
-	vdso_addr = data_addr + PAGE_SIZE;
+	vdso_addr = data_addr + VDSO_NR_PAGES * PAGE_SIZE;
 
-	vma = _install_special_mapping(mm, base, vvar_size,
-				       VM_READ | VM_MAYREAD,
-				       &vdso_vvar_mapping);
+	vma = vdso_install_vvar_mapping(mm, data_addr);
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
 		goto out;
@@ -159,6 +144,17 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	if (gic_size) {
 		gic_base = (unsigned long)mips_gic_base + MIPS_GIC_USER_OFS;
 		gic_pfn = PFN_DOWN(__pa(gic_base));
+		static const struct vm_special_mapping gic_mapping = {
+			.name	= "[gic]",
+			.pages	= (struct page **) { NULL },
+		};
+
+		vma = _install_special_mapping(mm, base, gic_size, VM_READ | VM_MAYREAD,
+					       &gic_mapping);
+		if (IS_ERR(vma)) {
+			ret = PTR_ERR(vma);
+			goto out;
+		}
 
 		ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size,
 					 pgprot_noncached(vma->vm_page_prot));
@@ -166,13 +162,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 			goto out;
 	}
 
-	/* Map data page. */
-	ret = remap_pfn_range(vma, data_addr,
-			      virt_to_phys(vdso_data) >> PAGE_SHIFT,
-			      PAGE_SIZE, vma->vm_page_prot);
-	if (ret)
-		goto out;
-
 	/* Map VDSO image. */
 	vma = _install_special_mapping(mm, vdso_addr, image->size,
 				       VM_READ | VM_EXEC |
diff --git a/arch/mips/vdso/vdso.lds.S b/arch/mips/vdso/vdso.lds.S
index 836465e3bcb8a15cb3f0f96d852d2b252c9d5e2a..c8bbe56d89cb095da21ac1f56d9999914defc305 100644
--- a/arch/mips/vdso/vdso.lds.S
+++ b/arch/mips/vdso/vdso.lds.S
@@ -5,6 +5,8 @@
  */
 
 #include <asm/sgidefs.h>
+#include <asm/vdso/vdso.h>
+#include <vdso/datapage.h>
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips", "elf64-tradlittlemips")
@@ -18,7 +20,8 @@ OUTPUT_ARCH(mips)
 
 SECTIONS
 {
-	PROVIDE(_start = .);
+	VDSO_VVAR_SYMS
+
 	. = SIZEOF_HEADERS;
 
 	/*

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:08 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:08 +0100
Subject: [PATCH 12/17] powerpc/vdso: Switch to generic storage
 implementation
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-12-f7aed1bdb3b2@linutronix.de>

The generic storage implementation provides the same features as the
custom one. However it can be shared between architectures, making
maintenance easier.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/powerpc/Kconfig                         |   2 +
 arch/powerpc/include/asm/vdso.h              |   1 +
 arch/powerpc/include/asm/vdso/arch_data.h    |  37 +++++++++
 arch/powerpc/include/asm/vdso/getrandom.h    |  11 +--
 arch/powerpc/include/asm/vdso/gettimeofday.h |  36 +++++----
 arch/powerpc/include/asm/vdso/vsyscall.h     |  13 ---
 arch/powerpc/include/asm/vdso_datapage.h     |  44 +---------
 arch/powerpc/kernel/asm-offsets.c            |   1 -
 arch/powerpc/kernel/time.c                   |   2 +-
 arch/powerpc/kernel/vdso.c                   | 115 +++------------------------
 arch/powerpc/kernel/vdso/cacheflush.S        |   2 +-
 arch/powerpc/kernel/vdso/datapage.S          |   4 +-
 arch/powerpc/kernel/vdso/gettimeofday.S      |   4 +-
 arch/powerpc/kernel/vdso/vdso32.lds.S        |   4 +-
 arch/powerpc/kernel/vdso/vdso64.lds.S        |   4 +-
 arch/powerpc/kernel/vdso/vgettimeofday.c     |  14 ++--
 16 files changed, 101 insertions(+), 193 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a0ce777f97063bf858942c60654d8411bcf2a3dc..600fa3b917ee902d016f2a04376950a9dc49074f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -156,6 +156,7 @@ config PPC
 	select ARCH_HAS_TICK_BROADCAST		if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAS_UACCESS_FLUSHCACHE
 	select ARCH_HAS_UBSAN
+	select ARCH_HAS_VDSO_ARCH_DATA
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_HAVE_EXTRA_ELF_NOTES        if SPU_BASE
 	select ARCH_KEEP_MEMBLOCK
@@ -206,6 +207,7 @@ config PPC
 	select GENERIC_PTDUMP
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
+	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select HAS_IOPORT			if PCI
 	select HAVE_ARCH_AUDITSYSCALL
diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h
index 8d972bc98b55fe916f23488ca9e2a5918046b9aa..1ca23fbfe087ae90b90c4286335f86d9f8121078 100644
--- a/arch/powerpc/include/asm/vdso.h
+++ b/arch/powerpc/include/asm/vdso.h
@@ -3,6 +3,7 @@
 #define _ASM_POWERPC_VDSO_H
 
 #define VDSO_VERSION_STRING	LINUX_2.6.15
+#define __VDSO_PAGES		4
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/powerpc/include/asm/vdso/arch_data.h b/arch/powerpc/include/asm/vdso/arch_data.h
new file mode 100644
index 0000000000000000000000000000000000000000..c240a6b875181ac4159f2e80b11f9bf214e22808
--- /dev/null
+++ b/arch/powerpc/include/asm/vdso/arch_data.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2002 Peter Bergner <bergner at vnet.ibm.com>, IBM
+ * Copyright (C) 2005 Benjamin Herrenschmidy <benh at kernel.crashing.org>,
+ * 		      IBM Corp.
+ */
+#ifndef _ASM_POWERPC_VDSO_ARCH_DATA_H
+#define _ASM_POWERPC_VDSO_ARCH_DATA_H
+
+#include <linux/unistd.h>
+#include <linux/types.h>
+
+#define SYSCALL_MAP_SIZE      ((NR_syscalls + 31) / 32)
+
+#ifdef CONFIG_PPC64
+
+struct vdso_arch_data {
+	__u64 tb_ticks_per_sec;			/* Timebase tics / sec */
+	__u32 dcache_block_size;		/* L1 d-cache block size     */
+	__u32 icache_block_size;		/* L1 i-cache block size     */
+	__u32 dcache_log_block_size;		/* L1 d-cache log block size */
+	__u32 icache_log_block_size;		/* L1 i-cache log block size */
+	__u32 syscall_map[SYSCALL_MAP_SIZE];	/* Map of syscalls  */
+	__u32 compat_syscall_map[SYSCALL_MAP_SIZE];	/* Map of compat syscalls */
+};
+
+#else /* CONFIG_PPC64 */
+
+struct vdso_arch_data {
+	__u64 tb_ticks_per_sec;		/* Timebase tics / sec */
+	__u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */
+	__u32 compat_syscall_map[0];	/* No compat syscalls on PPC32 */
+};
+
+#endif /* CONFIG_PPC64 */
+
+#endif /* _ASM_POWERPC_VDSO_ARCH_DATA_H */
diff --git a/arch/powerpc/include/asm/vdso/getrandom.h b/arch/powerpc/include/asm/vdso/getrandom.h
index 80ce0709725eb89c1f3b69e0733038b458fbf24f..c82eb0d8237681a7396abfe7d161292636b8cce4 100644
--- a/arch/powerpc/include/asm/vdso/getrandom.h
+++ b/arch/powerpc/include/asm/vdso/getrandom.h
@@ -43,20 +43,21 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig
 			    (unsigned long)len, (unsigned long)flags);
 }
 
-static __always_inline struct vdso_rng_data *__arch_get_vdso_rng_data(void)
+static __always_inline const struct vdso_rng_data *__ppc_get_vdso_u_rng_data(void)
 {
-	struct vdso_arch_data *data;
+	struct vdso_rng_data *data;
 
 	asm (
 		"	bcl	20, 31, .+4 ;"
 		"0:	mflr	%0 ;"
-		"	addis	%0, %0, (_vdso_datapage - 0b)@ha ;"
-		"	addi	%0, %0, (_vdso_datapage - 0b)@l  ;"
+		"	addis	%0, %0, (vdso_u_rng_data - 0b)@ha ;"
+		"	addi	%0, %0, (vdso_u_rng_data - 0b)@l  ;"
 		: "=r" (data) : : "lr"
 	);
 
-	return &data->rng_data;
+	return data;
 }
+#define __arch_get_vdso_u_rng_data __ppc_get_vdso_u_rng_data
 
 ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
 			     size_t opaque_len);
diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h
index c6390890a60c2fdcb608bf321b2945c3fb372f54..bddd9cde97db197d0d3daba6c2289cb29e6b5a75 100644
--- a/arch/powerpc/include/asm/vdso/gettimeofday.h
+++ b/arch/powerpc/include/asm/vdso/gettimeofday.h
@@ -94,22 +94,29 @@ int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
 #endif
 
 static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
-						 const struct vdso_data *vd)
+						 const struct vdso_time_data *vd)
 {
 	return get_tb();
 }
 
-const struct vdso_data *__arch_get_vdso_data(void);
-
 #ifdef CONFIG_TIME_NS
-static __always_inline
-const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
+static __always_inline const struct vdso_time_data *__ppc_get_vdso_u_timens_data(void)
 {
-	return (void *)vd + (1U << CONFIG_PAGE_SHIFT);
+	struct vdso_time_data *time_data;
+
+	asm(
+		"	bcl	20, 31, .+4\n"
+		"0:	mflr	%0\n"
+		"	addis	%0, %0, (vdso_u_timens_data - 0b)@ha\n"
+		"	addi	%0, %0, (vdso_u_timens_data - 0b)@l\n"
+	: "=r" (time_data) :: "lr");
+
+	return time_data;
 }
+#define __arch_get_vdso_u_timens_data __ppc_get_vdso_u_timens_data
 #endif
 
-static inline bool vdso_clocksource_ok(const struct vdso_data *vd)
+static inline bool vdso_clocksource_ok(const struct vdso_time_data *vd)
 {
 	return true;
 }
@@ -135,21 +142,22 @@ static __always_inline u64 vdso_shift_ns(u64 ns, unsigned long shift)
 
 #ifdef __powerpc64__
 int __c_kernel_clock_gettime(clockid_t clock, struct __kernel_timespec *ts,
-			     const struct vdso_data *vd);
+			     const struct vdso_time_data *vd);
 int __c_kernel_clock_getres(clockid_t clock_id, struct __kernel_timespec *res,
-			    const struct vdso_data *vd);
+			    const struct vdso_time_data *vd);
 #else
 int __c_kernel_clock_gettime(clockid_t clock, struct old_timespec32 *ts,
-			     const struct vdso_data *vd);
+			     const struct vdso_time_data *vd);
 int __c_kernel_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts,
-			       const struct vdso_data *vd);
+			       const struct vdso_time_data *vd);
 int __c_kernel_clock_getres(clockid_t clock_id, struct old_timespec32 *res,
-			    const struct vdso_data *vd);
+			    const struct vdso_time_data *vd);
 #endif
 int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz,
-			    const struct vdso_data *vd);
+			    const struct vdso_time_data *vd);
 __kernel_old_time_t __c_kernel_time(__kernel_old_time_t *time,
-				    const struct vdso_data *vd);
+				    const struct vdso_time_data *vd);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/powerpc/include/asm/vdso/vsyscall.h b/arch/powerpc/include/asm/vdso/vsyscall.h
index 48560a11955956b8fbb59360334a81972723bd57..c2c9ae1b22e71a3f87e5a1a351699c7ab42b2f95 100644
--- a/arch/powerpc/include/asm/vdso/vsyscall.h
+++ b/arch/powerpc/include/asm/vdso/vsyscall.h
@@ -6,19 +6,6 @@
 
 #include <asm/vdso_datapage.h>
 
-static __always_inline
-struct vdso_data *__arch_get_k_vdso_data(void)
-{
-	return vdso_data->data;
-}
-#define __arch_get_k_vdso_data __arch_get_k_vdso_data
-
-static __always_inline
-struct vdso_rng_data *__arch_get_k_vdso_rng_data(void)
-{
-	return &vdso_data->rng_data;
-}
-
 /* The asm-generic header needs to be included after the definitions above */
 #include <asm-generic/vdso/vsyscall.h>
 
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index a202f5b63479533a7f45a74df015feb59f3d7c87..95d45a50355d269454dd3e175a5b3844181536b5 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -11,56 +11,18 @@
 
 #ifndef __ASSEMBLY__
 
-#include <linux/unistd.h>
-#include <linux/time.h>
 #include <vdso/datapage.h>
 
-#define SYSCALL_MAP_SIZE      ((NR_syscalls + 31) / 32)
-
-#ifdef CONFIG_PPC64
-
-struct vdso_arch_data {
-	__u64 tb_ticks_per_sec;			/* Timebase tics / sec */
-	__u32 dcache_block_size;		/* L1 d-cache block size     */
-	__u32 icache_block_size;		/* L1 i-cache block size     */
-	__u32 dcache_log_block_size;		/* L1 d-cache log block size */
-	__u32 icache_log_block_size;		/* L1 i-cache log block size */
-	__u32 syscall_map[SYSCALL_MAP_SIZE];	/* Map of syscalls  */
-	__u32 compat_syscall_map[SYSCALL_MAP_SIZE];	/* Map of compat syscalls */
-
-	struct vdso_rng_data rng_data;
-
-	struct vdso_data data[CS_BASES] __aligned(1 << CONFIG_PAGE_SHIFT);
-};
-
-#else /* CONFIG_PPC64 */
-
-struct vdso_arch_data {
-	__u64 tb_ticks_per_sec;		/* Timebase tics / sec */
-	__u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */
-	__u32 compat_syscall_map[0];	/* No compat syscalls on PPC32 */
-	struct vdso_rng_data rng_data;
-
-	struct vdso_data data[CS_BASES] __aligned(1 << CONFIG_PAGE_SHIFT);
-};
-
-#endif /* CONFIG_PPC64 */
-
-extern struct vdso_arch_data *vdso_data;
-
 #else /* __ASSEMBLY__ */
 
-.macro get_datapage ptr offset=0
+.macro get_datapage ptr symbol
 	bcl	20, 31, .+4
 999:
 	mflr	\ptr
-	addis	\ptr, \ptr, (_vdso_datapage - 999b + \offset)@ha
-	addi	\ptr, \ptr, (_vdso_datapage - 999b + \offset)@l
+	addis	\ptr, \ptr, (\symbol - 999b)@ha
+	addi	\ptr, \ptr, (\symbol - 999b)@l
 .endm
 
-#include <asm/asm-offsets.h>
-#include <asm/page.h>
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 7a390bd4f4af3c7408b3e3c5ef6d43b95b3b6463..b3048f6d3822c0c457f4aa2ccb5dc870495ba79b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -334,7 +334,6 @@ int main(void)
 #endif /* ! CONFIG_PPC64 */
 
 	/* datapage offsets for use by vdso */
-	OFFSET(VDSO_DATA_OFFSET, vdso_arch_data, data);
 	OFFSET(CFG_TB_TICKS_PER_SEC, vdso_arch_data, tb_ticks_per_sec);
 #ifdef CONFIG_PPC64
 	OFFSET(CFG_ICACHE_BLOCKSZ, vdso_arch_data, icache_block_size);
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 0727332ad86fbcfcf8ca18b344ba04381e827c79..15784c5c95c77f1eccfa948a36ba69386a2c175b 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -950,7 +950,7 @@ void __init time_init(void)
 		sys_tz.tz_dsttime = 0;
 	}
 
-	vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
+	vdso_k_arch_data->tb_ticks_per_sec = tb_ticks_per_sec;
 #ifdef CONFIG_PPC64_PROC_SYSTEMCFG
 	systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
 #endif
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 43379365ce1b37cfba662ea58feca5e73dd5f700..219d67bcf747e79f48d09a50f5cb9624bcc0f7b1 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -17,7 +17,7 @@
 #include <linux/elf.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
-#include <linux/time_namespace.h>
+#include <linux/vdso_datastore.h>
 #include <vdso/datapage.h>
 
 #include <asm/syscall.h>
@@ -32,6 +32,8 @@
 #include <asm/vdso_datapage.h>
 #include <asm/setup.h>
 
+static_assert(__VDSO_PAGES == VDSO_NR_PAGES);
+
 /* The alignment of the vDSO */
 #define VDSO_ALIGNMENT	(1 << 16)
 
@@ -40,24 +42,6 @@ extern char vdso64_start, vdso64_end;
 
 long sys_ni_syscall(void);
 
-/*
- * The vdso data page (aka. systemcfg for old ppc64 fans) is here.
- * Once the early boot kernel code no longer needs to muck around
- * with it, it will become dynamically allocated
- */
-static union {
-	struct vdso_arch_data	data;
-	u8			page[2 * PAGE_SIZE];
-} vdso_data_store __page_aligned_data;
-struct vdso_arch_data *vdso_data = &vdso_data_store.data;
-
-enum vvar_pages {
-	VVAR_BASE_PAGE_OFFSET,
-	VVAR_TIME_PAGE_OFFSET,
-	VVAR_TIMENS_PAGE_OFFSET,
-	VVAR_NR_PAGES,
-};
-
 static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma,
 		       unsigned long text_size)
 {
@@ -96,14 +80,6 @@ static void vdso_close(const struct vm_special_mapping *sm, struct vm_area_struc
 	mm->context.vdso = NULL;
 }
 
-static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
-			     struct vm_area_struct *vma, struct vm_fault *vmf);
-
-static struct vm_special_mapping vvar_spec __ro_after_init = {
-	.name = "[vvar]",
-	.fault = vvar_fault,
-};
-
 static struct vm_special_mapping vdso32_spec __ro_after_init = {
 	.name = "[vdso]",
 	.mremap = vdso32_mremap,
@@ -116,73 +92,6 @@ static struct vm_special_mapping vdso64_spec __ro_after_init = {
 	.close = vdso_close,
 };
 
-#ifdef CONFIG_TIME_NS
-struct vdso_data *arch_get_vdso_data(void *vvar_page)
-{
-	return vvar_page;
-}
-
-/*
- * The vvar mapping contains data for a specific time namespace, so when a task
- * changes namespace we must unmap its vvar data for the old namespace.
- * Subsequent faults will map in data for the new namespace.
- *
- * For more details see timens_setup_vdso_data().
- */
-int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
-{
-	struct mm_struct *mm = task->mm;
-	VMA_ITERATOR(vmi, mm, 0);
-	struct vm_area_struct *vma;
-
-	mmap_read_lock(mm);
-	for_each_vma(vmi, vma) {
-		if (vma_is_special_mapping(vma, &vvar_spec))
-			zap_vma_pages(vma);
-	}
-	mmap_read_unlock(mm);
-
-	return 0;
-}
-#endif
-
-static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
-			     struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	struct page *timens_page = find_timens_vvar_page(vma);
-	unsigned long pfn;
-
-	switch (vmf->pgoff) {
-	case VVAR_BASE_PAGE_OFFSET:
-		pfn = virt_to_pfn(vdso_data);
-		break;
-	case VVAR_TIME_PAGE_OFFSET:
-		if (timens_page)
-			pfn = page_to_pfn(timens_page);
-		else
-			pfn = virt_to_pfn(vdso_data->data);
-		break;
-#ifdef CONFIG_TIME_NS
-	case VVAR_TIMENS_PAGE_OFFSET:
-		/*
-		 * If a task belongs to a time namespace then a namespace
-		 * specific VVAR is mapped with the VVAR_DATA_PAGE_OFFSET and
-		 * the real VVAR page is mapped with the VVAR_TIMENS_PAGE_OFFSET
-		 * offset.
-		 * See also the comment near timens_setup_vdso_data().
-		 */
-		if (!timens_page)
-			return VM_FAULT_SIGBUS;
-		pfn = virt_to_pfn(vdso_data->data);
-		break;
-#endif /* CONFIG_TIME_NS */
-	default:
-		return VM_FAULT_SIGBUS;
-	}
-
-	return vmf_insert_pfn(vma, vmf->address, pfn);
-}
-
 /*
  * This is called from binfmt_elf, we create the special vma for the
  * vDSO and insert it into the mm struct tree
@@ -191,7 +100,7 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int
 {
 	unsigned long vdso_size, vdso_base, mappings_size;
 	struct vm_special_mapping *vdso_spec;
-	unsigned long vvar_size = VVAR_NR_PAGES * PAGE_SIZE;
+	unsigned long vvar_size = VDSO_NR_PAGES * PAGE_SIZE;
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
 
@@ -217,9 +126,7 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int
 	/* Add required alignment. */
 	vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT);
 
-	vma = _install_special_mapping(mm, vdso_base, vvar_size,
-				       VM_READ | VM_MAYREAD | VM_IO |
-				       VM_DONTDUMP | VM_PFNMAP, &vvar_spec);
+	vma = vdso_install_vvar_mapping(mm, vdso_base);
 	if (IS_ERR(vma))
 		return PTR_ERR(vma);
 
@@ -299,10 +206,10 @@ static void __init vdso_setup_syscall_map(void)
 
 	for (i = 0; i < NR_syscalls; i++) {
 		if (sys_call_table[i] != (void *)&sys_ni_syscall)
-			vdso_data->syscall_map[i >> 5] |= 0x80000000UL >> (i & 0x1f);
+			vdso_k_arch_data->syscall_map[i >> 5] |= 0x80000000UL >> (i & 0x1f);
 		if (IS_ENABLED(CONFIG_COMPAT) &&
 		    compat_sys_call_table[i] != (void *)&sys_ni_syscall)
-			vdso_data->compat_syscall_map[i >> 5] |= 0x80000000UL >> (i & 0x1f);
+			vdso_k_arch_data->compat_syscall_map[i >> 5] |= 0x80000000UL >> (i & 0x1f);
 	}
 }
 
@@ -352,10 +259,10 @@ static struct page ** __init vdso_setup_pages(void *start, void *end)
 static int __init vdso_init(void)
 {
 #ifdef CONFIG_PPC64
-	vdso_data->dcache_block_size = ppc64_caches.l1d.block_size;
-	vdso_data->icache_block_size = ppc64_caches.l1i.block_size;
-	vdso_data->dcache_log_block_size = ppc64_caches.l1d.log_block_size;
-	vdso_data->icache_log_block_size = ppc64_caches.l1i.log_block_size;
+	vdso_k_arch_data->dcache_block_size = ppc64_caches.l1d.block_size;
+	vdso_k_arch_data->icache_block_size = ppc64_caches.l1i.block_size;
+	vdso_k_arch_data->dcache_log_block_size = ppc64_caches.l1d.log_block_size;
+	vdso_k_arch_data->icache_log_block_size = ppc64_caches.l1i.log_block_size;
 #endif /* CONFIG_PPC64 */
 
 	vdso_setup_syscall_map();
diff --git a/arch/powerpc/kernel/vdso/cacheflush.S b/arch/powerpc/kernel/vdso/cacheflush.S
index 0085ae464dac9c32381625a6969a4e422ad34eb7..488d3ade11e64996b30f42777251df8499eda92c 100644
--- a/arch/powerpc/kernel/vdso/cacheflush.S
+++ b/arch/powerpc/kernel/vdso/cacheflush.S
@@ -30,7 +30,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 #ifdef CONFIG_PPC64
 	mflr	r12
   .cfi_register lr,r12
-	get_datapage	r10
+	get_datapage	r10 vdso_u_arch_data
 	mtlr	r12
   .cfi_restore	lr
 #endif
diff --git a/arch/powerpc/kernel/vdso/datapage.S b/arch/powerpc/kernel/vdso/datapage.S
index db8e167f01667eb95b3dc74f6771e610411bba90..d23b2e8e2a34ca9b142231eb3a492716a49b2248 100644
--- a/arch/powerpc/kernel/vdso/datapage.S
+++ b/arch/powerpc/kernel/vdso/datapage.S
@@ -28,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
 	mflr	r12
   .cfi_register lr,r12
 	mr.	r4,r3
-	get_datapage	r3
+	get_datapage	r3 vdso_u_arch_data
 	mtlr	r12
 #ifdef __powerpc64__
 	addi	r3,r3,CFG_SYSCALL_MAP64
@@ -52,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
   .cfi_startproc
 	mflr	r12
   .cfi_register lr,r12
-	get_datapage	r3
+	get_datapage	r3 vdso_u_arch_data
 #ifndef __powerpc64__
 	lwz	r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
 #endif
diff --git a/arch/powerpc/kernel/vdso/gettimeofday.S b/arch/powerpc/kernel/vdso/gettimeofday.S
index 5333848322ca6105018d501952e3bf42475f49df..79c967212444732da50805fd086c6f2a3c75b0cc 100644
--- a/arch/powerpc/kernel/vdso/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso/gettimeofday.S
@@ -33,9 +33,9 @@
   .cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
 #endif
 	.ifeq	\call_time
-		get_datapage	r5 VDSO_DATA_OFFSET
+		get_datapage	r5 vdso_u_time_data
 	.else
-		get_datapage	r4 VDSO_DATA_OFFSET
+		get_datapage	r4 vdso_u_time_data
 	.endif
 	bl		CFUNC(DOTSYM(\funct))
 	PPC_LL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
diff --git a/arch/powerpc/kernel/vdso/vdso32.lds.S b/arch/powerpc/kernel/vdso/vdso32.lds.S
index 1a1b0b6d681a9977e4ef8042e52d8d33da61887e..72a1012b8a205c6357cecb4b53d2d8e1ff59b051 100644
--- a/arch/powerpc/kernel/vdso/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso/vdso32.lds.S
@@ -6,6 +6,7 @@
 #include <asm/vdso.h>
 #include <asm/page.h>
 #include <asm-generic/vmlinux.lds.h>
+#include <vdso/datapage.h>
 
 #ifdef __LITTLE_ENDIAN__
 OUTPUT_FORMAT("elf32-powerpcle", "elf32-powerpcle", "elf32-powerpcle")
@@ -16,7 +17,8 @@ OUTPUT_ARCH(powerpc:common)
 
 SECTIONS
 {
-	PROVIDE(_vdso_datapage = . - 3 * PAGE_SIZE);
+	VDSO_VVAR_SYMS
+
 	. = SIZEOF_HEADERS;
 
 	.hash          	: { *(.hash) }			:text
diff --git a/arch/powerpc/kernel/vdso/vdso64.lds.S b/arch/powerpc/kernel/vdso/vdso64.lds.S
index e21b5506cad62b16e677be74fda7921ec917141a..32102a05eaa7e015e0f89e4a94a3c5e31da7d460 100644
--- a/arch/powerpc/kernel/vdso/vdso64.lds.S
+++ b/arch/powerpc/kernel/vdso/vdso64.lds.S
@@ -6,6 +6,7 @@
 #include <asm/vdso.h>
 #include <asm/page.h>
 #include <asm-generic/vmlinux.lds.h>
+#include <vdso/datapage.h>
 
 #ifdef __LITTLE_ENDIAN__
 OUTPUT_FORMAT("elf64-powerpcle", "elf64-powerpcle", "elf64-powerpcle")
@@ -16,7 +17,8 @@ OUTPUT_ARCH(powerpc:common64)
 
 SECTIONS
 {
-	PROVIDE(_vdso_datapage = . - 3 * PAGE_SIZE);
+	VDSO_VVAR_SYMS
+
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text
diff --git a/arch/powerpc/kernel/vdso/vgettimeofday.c b/arch/powerpc/kernel/vdso/vgettimeofday.c
index 55a287c9a7366aa59ab4af1e760a8995f588a4d5..6f5167d81af5f3e6e755dbda4307769e45a28421 100644
--- a/arch/powerpc/kernel/vdso/vgettimeofday.c
+++ b/arch/powerpc/kernel/vdso/vgettimeofday.c
@@ -7,43 +7,43 @@
 
 #ifdef __powerpc64__
 int __c_kernel_clock_gettime(clockid_t clock, struct __kernel_timespec *ts,
-			     const struct vdso_data *vd)
+			     const struct vdso_time_data *vd)
 {
 	return __cvdso_clock_gettime_data(vd, clock, ts);
 }
 
 int __c_kernel_clock_getres(clockid_t clock_id, struct __kernel_timespec *res,
-			    const struct vdso_data *vd)
+			    const struct vdso_time_data *vd)
 {
 	return __cvdso_clock_getres_data(vd, clock_id, res);
 }
 #else
 int __c_kernel_clock_gettime(clockid_t clock, struct old_timespec32 *ts,
-			     const struct vdso_data *vd)
+			     const struct vdso_time_data *vd)
 {
 	return __cvdso_clock_gettime32_data(vd, clock, ts);
 }
 
 int __c_kernel_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts,
-			       const struct vdso_data *vd)
+			       const struct vdso_time_data *vd)
 {
 	return __cvdso_clock_gettime_data(vd, clock, ts);
 }
 
 int __c_kernel_clock_getres(clockid_t clock_id, struct old_timespec32 *res,
-			    const struct vdso_data *vd)
+			    const struct vdso_time_data *vd)
 {
 	return __cvdso_clock_getres_time32_data(vd, clock_id, res);
 }
 #endif
 
 int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz,
-			    const struct vdso_data *vd)
+			    const struct vdso_time_data *vd)
 {
 	return __cvdso_gettimeofday_data(vd, tv, tz);
 }
 
-__kernel_old_time_t __c_kernel_time(__kernel_old_time_t *time, const struct vdso_data *vd)
+__kernel_old_time_t __c_kernel_time(__kernel_old_time_t *time, const struct vdso_time_data *vd)
 {
 	return __cvdso_time_data(vd, time);
 }

-- 
2.47.1



From angelogioacchino.delregno at collabora.com  Mon Dec 16 06:10:23 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 16 Dec 2024 15:10:23 +0100
Subject: [PATCH 5/5] clk: mediatek: mt2701-img: add missing dummy clk
In-Reply-To: <d677486a5c563fe5c47aa995841adc2aaa183b8a.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
 <d677486a5c563fe5c47aa995841adc2aaa183b8a.1734300668.git.daniel@makrotopia.org>
Message-ID: <016f8f1a-e408-43d7-9a76-1a025ba159e8@collabora.com>

Il 15/12/24 23:14, Daniel Golle ha scritto:
> Add dummy clk for index 0 which was missed during the conversion to
> mtk_clk_simple_probe().
> 
> Fixes: 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver")
> Cc: stable at vger.kernel.org
> 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  Mon Dec 16 06:10:26 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 16 Dec 2024 15:10:26 +0100
Subject: [PATCH 1/5] clk: mediatek: mt2701-vdec: fix conversion to
 mtk_clk_simple_probe
In-Reply-To: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
Message-ID: <33c632c4-a14b-4901-b758-43763dfb271f@collabora.com>

Il 15/12/24 23:13, Daniel Golle ha scritto:
> Commit 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to
> simplify driver") broke DT bindings as the highest index was reduced by
> 1 because the id count starts from 1 and not from 0.
> 
> Fix this, like for other drivers which had the same issue, by adding a
> dummy clk at index 0.
> 
> Fixes: 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver")
> Cc: stable at vger.kernel.org
> 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  Mon Dec 16 06:10:27 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 16 Dec 2024 15:10:27 +0100
Subject: [PATCH 4/5] clk: mediatek: mt2701-mm: add missing dummy clk
In-Reply-To: <9de23440fcba1ffef9e77d58c9f505105e57a250.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
 <9de23440fcba1ffef9e77d58c9f505105e57a250.1734300668.git.daniel@makrotopia.org>
Message-ID: <73431558-89cf-4ef9-a0c5-fb9209eeb040@collabora.com>

Il 15/12/24 23:14, Daniel Golle ha scritto:
> Add dummy clk which was missed during the conversion to
> mtk_clk_pdev_probe() and is required for the existing DT bindings to
> keep working.
> 
> Fixes: 65c10c50c9c7 ("clk: mediatek: Migrate to mtk_clk_pdev_probe() for multimedia clocks")
> Cc: stable at vger.kernel.org
> 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  Mon Dec 16 06:10:28 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 16 Dec 2024 15:10:28 +0100
Subject: [PATCH 3/5] clk: mediatek: mt2701-bdp: add missing dummy clk
In-Reply-To: <b8526c882a50f2b158df0eccb4a165956fd8fa13.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
 <b8526c882a50f2b158df0eccb4a165956fd8fa13.1734300668.git.daniel@makrotopia.org>
Message-ID: <f816383a-0409-44c3-973d-8e0dcd786b68@collabora.com>

Il 15/12/24 23:14, Daniel Golle ha scritto:
> Add dummy clk for index 0 which was missed during the conversion to
> mtk_clk_simple_probe().
> 
> Fixes: 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver")
> Cc: stable at vger.kernel.org
> 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  Mon Dec 16 06:10:29 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 16 Dec 2024 15:10:29 +0100
Subject: [PATCH 2/5] clk: mediatek: mt2701-aud: fix conversion to
 mtk_clk_simple_probe
In-Reply-To: <a07584d803af57b9ce4b5df5e122c09bf5a56ac9.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
 <a07584d803af57b9ce4b5df5e122c09bf5a56ac9.1734300668.git.daniel@makrotopia.org>
Message-ID: <8cf8accf-51dd-47b1-9b02-07a96e897714@collabora.com>

Il 15/12/24 23:14, Daniel Golle ha scritto:
> Some of the audio subsystem clocks defined in clk-mt2701.h aren't
> actually used by the driver. This broke conversion to
> mtk_clk_simple_probe which expects that the highest possible clk id is
> defined by the ARRAY_SIZE.
> 
> Add additional dummy clocks to fill the gaps and remain compatible with
> the existing DT bindings.
> 
> Fixes: 0f69a423c458 ("clk: mediatek: Switch to mtk_clk_simple_probe() where possible")
> Cc: stable at vger.kernel.org
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From gchen.guomin at gmail.com  Mon Dec 16 06:10:40 2024
From: gchen.guomin at gmail.com (gchen chen)
Date: Mon, 16 Dec 2024 22:10:40 +0800
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless scmi_bus_id.
In-Reply-To: <Z2AEzHc5f6TjxErs@bogus>
References: <20241216073745.2973317-1-guomin_chen@sina.com>
 <Z1_p0nU93PHJ4Sg_@pluto> <Z1_2rxJ7TOEIOMp7@pluto> <CAEEwsfRhe4-YAwe027huSXwFfkV-O-8w1GDNf=URa9efRsXiKA@mail.gmail.com>
 <Z2AEzHc5f6TjxErs@bogus>
Message-ID: <CAEEwsfRKVBVR+DxhkYA5atxU7+6nsaL9X8-Yoa_DqB0YKEV1zg@mail.gmail.com>

Sudeep Holla <sudeep.holla at arm.com> ?2024?12?16??? 18:45???
>
> On Mon, Dec 16, 2024 at 06:37:01PM +0800, gchen chen wrote:
> > Cristian Marussi <cristian.marussi at arm.com> ?2024?12?16??? 17:45???
> > >
> > > On Mon, Dec 16, 2024 at 08:50:26AM +0000, Cristian Marussi wrote:
> > > > On Mon, Dec 16, 2024 at 03:37:45PM +0800, guomin_chen at sina.com wrote:
> > > > > From: guomin chen <guomin_chen at sina.com>
> > > > >
> > > > > Currently, scmi_bus_id is only used to set scmi_dev.id,
> > > > > which in turn sets the SCMI device name. After removing
> > > > > scmi_bus_id, it is clearer and more meaningful to directly
> > > > > use the unique tuple [Parent name,device name, protocol] to
> > > > > set the SCMI device name.
> > > > >
> > > >
> > > > Hi Guomin,
> > > >
> > > > this same pTCH was NACKed(Rejected) a few days ago:
> > > >
> > > > https://lore.kernel.org/arm-scmi/20241211134505.2218386-1-guomin_chen at sina.com/T/#u
> > > >
> > > > ...and you agreed that is not a simplification we can do (not to break
> > > > multuple instances...)...
> > > >
> > > > ..so why you are posting V2 now ?
> > >
> > > Wait...you changed slightly this indeed....you are using dev_parent...my
> > > bad...but please when you post new version of a patch add a summary of
> > > changes between versions...
> > >
> > > >
> > > > Thanks,
> > > > Cristian
> > > >
> > > > > Signed-off-by: guomin chen <guomin_chen at sina.com>
> > > > > ---
> > > > >  drivers/firmware/arm_scmi/bus.c    | 17 +++--------------
> > > > >  drivers/firmware/arm_scmi/driver.c |  4 ++--
> > > > >  2 files changed, 5 insertions(+), 16 deletions(-)
> > > > >
> > > > > diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
> > > > > index 157172a5f2b5..800e8ec9357c 100644
> > > > > --- a/drivers/firmware/arm_scmi/bus.c
> > > > > +++ b/drivers/firmware/arm_scmi/bus.c
> > > > > @@ -20,7 +20,6 @@
> > > > >  BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
> > > > >  EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
> > > > >
> > > > > -static DEFINE_IDA(scmi_bus_id);
> > > > >
> > > > >  static DEFINE_IDR(scmi_requested_devices);
> > > > >  /* Protect access to scmi_requested_devices */
> > > > > @@ -341,7 +340,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
> > > > >     if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
> > > > >             atomic_set(&scmi_syspower_registered, 0);
> > > > >
> > > > > -   ida_free(&scmi_bus_id, scmi_dev->id);
> > > > >     device_unregister(&scmi_dev->dev);
> > > > >  }
> > > > >
> > > > > @@ -349,7 +347,7 @@ static struct scmi_device *
> > > > >  __scmi_device_create(struct device_node *np, struct device *parent,
> > > > >                  int protocol, const char *name)
> > > > >  {
> > > > > -   int id, retval;
> > > > > +   int retval;
> > > > >     struct scmi_device *scmi_dev;
> > > > >
> > > > >     /*
> > > > > @@ -387,20 +385,13 @@ __scmi_device_create(struct device_node *np, struct device *parent,
> > > > >             return NULL;
> > > > >     }
> > > > >
> > > > > -   id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL);
> > > > > -   if (id < 0) {
> > > > > -           kfree_const(scmi_dev->name);
> > > > > -           kfree(scmi_dev);
> > > > > -           return NULL;
> > > > > -   }
> > > > > -
> > > > > -   scmi_dev->id = id;
> > > > >     scmi_dev->protocol_id = protocol;
> > > > >     scmi_dev->dev.parent = parent;
> > > > >     device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
> > > > >     scmi_dev->dev.bus = &scmi_bus_type;
> > > > >     scmi_dev->dev.release = scmi_device_release;
> > > > > -   dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
> > > > > +   dev_set_name(&scmi_dev->dev, "scmi_dev.%s.%s.%d", dev_name(parent),
> > > > > +                   scmi_dev->name, protocol);
> > > > >
> > >
> > > So now you are using the parent top node SCMI device to create a unique
> > > device...and it probably endup in a name like:
> > >
> > >         scmi-dev.arm-scmi.0.auto.genpd.13
> > >
> > >         scmi-dev.arm-scmi.1.auto.genpd.13
> > >
> > > ...that certainly is more readable but is bulky and anyway giving unique
> > > IDs to devices is pretty common and you lookup which device is which by
> > > simply looking at the drivers/ link....not suure what's the benefit of
> > > all of this...just to avoid an IDA table ?
> > >
> > > > >     retval = device_register(&scmi_dev->dev);
> > > > >     if (retval)
> > > > > @@ -413,7 +404,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
> > > > >     return scmi_dev;
> > > > >  put_dev:
> > > > >     put_device(&scmi_dev->dev);
> > > > > -   ida_free(&scmi_bus_id, id);
> > > > >     return NULL;
> > > > >  }
> > > > >
> > > > > @@ -526,7 +516,6 @@ static void __exit scmi_bus_exit(void)
> > > > >      */
> > > > >     scmi_devices_unregister();
> > > > >     bus_unregister(&scmi_bus_type);
> > > > > -   ida_destroy(&scmi_bus_id);
> > > > >  }
> > > > >  module_exit(scmi_bus_exit);
> > > > >
> > > > > diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> > > > > index 1b5fb2c4ce86..bbf1f05f2be3 100644
> > > > > --- a/drivers/firmware/arm_scmi/driver.c
> > > > > +++ b/drivers/firmware/arm_scmi/driver.c
> > > > > @@ -2641,8 +2641,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
> > > > >     cinfo->max_msg_size = info->desc->max_msg_size;
> > > > >
> > > > >     /* Create a unique name for this transport device */
> > > > > -   snprintf(name, 32, "__scmi_transport_device_%s_%02X",
> > > > > -            idx ? "rx" : "tx", prot_id);
> > > > > +   snprintf(name, 32, "__scmi_transport_device_%s",
> > > > > +            idx ? "rx" : "tx");
> > >
> > > I agree on what Dan said AND also this results in having the same name for different
> > > devices across 2 instances if you have a per-protocol channel because you havent anymore
> > > the protocol_id bit.
> > hi  Cristian?and dan
> >     Because I used a 3-tuple [parent name, name, protocol] when
> > creating the SCMI device name, I removed the prot_id from the
> > parameter ?name? when creating transport devices. This way, it avoids
> > the repetition of protocol ID in the SCMI device name.
> >
> > > All in all, I would drop this patch and keep naming as it is because I dont see a real benefit
> > > here....up to Sudeep decide.
> >      Yes, it does not have real benefits, but from the perspective of
> > the device name, this change will be clearer and more meaningful. And
> > the code is more concise.
> >
>
> I would like to understand the motivation behind this change. What is the
> goal ? Do you prefer to fetch the name and protocol id from the device
> name itself ? Is that your requirement.
>
hi Sudeep
    Okay, the reason I want to change names like 'scmi_dev.3' to
'scmi_dev.firmware:scmi.perf.19' is because when I was migrating the
SOC's kernel from v6.1 to v6.6, I found that the context for creating
SCMI devices had changed (commit d3cd7c525fd2: firmware: arm_scmi:
Refactor protocol device creation). This change meant that device
creation shifted from being directly created through
scmi_protocol_device_request during SCMI driver registration to being
created via scmi_device_request_notifier. This shift results in
changes to the order in which devices are created, causing the ID in
scmi_dev.id to drift.

Additionally, I encountered some cpufreq errors here?because both
scmi_cpufreq_drv and scmi_perf_domain_driver use the same
SCMI_PROTOCOL_PERF, this results in two SCMI devices corresponding to
the same device node. However, device_node.fwnode.dev only points to
the first registered scmi_device, causing other consumer devices to
find the wrong scmi device as the supplier. So I would find a
multitude of other consumer devices waiting for meaningless device
names like "scmi_dev.4" instead of meaningful names such as
"scmi_dev.firmware:scmi.perf.19" or
"scmi_dev.firmware:scmi.cpufreq.19".

Although I could further determine which specific driver it was by
looking at the driver links under the scmi_protocol bus directory, I
thought that if the logs directly displayed device names like
'scmi_dev.firmware:scmi.perf.19' instead of meaningless progressive
IDs, it would be more convenient and logical, and thus more
meaningful.

> From the commit log, I get a sense that you looked at the code and thought
> of possible improvement but when we mentioned the limitation you just
> improvised by adding parent name. Do you expect any userspace to parse
> the name as that will end up being ABI and we can't break it. I need
> real motive to be explained here in detail.
>
I did not use userspace tools to parse this SCMI device name; I simply
wanted the name to reflect the possible logic of the device.
I did not remove scmi_dev.id (This scmi_device structure has not
changed.?; I just no longer assign values to it using scmi_bus_id, so
it should not affect the kernel ABI (kABI).

Thanks
guomin.chen
> --
> Regards,
> Sudeep


From thomas.weissschuh at linutronix.de  Mon Dec 16 06:09:57 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:09:57 +0100
Subject: [PATCH 01/17] parisc: Remove unused symbol vdso_data
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-1-f7aed1bdb3b2@linutronix.de>

The symbol vdso_data is and has been unused.
Remove it.

Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/parisc/include/asm/vdso.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/parisc/include/asm/vdso.h b/arch/parisc/include/asm/vdso.h
index 2a2dc11b5545fc642a7ae4596dc174111433e948..5f581c1d64606b3ec8f9967efe31dd3d551adf76 100644
--- a/arch/parisc/include/asm/vdso.h
+++ b/arch/parisc/include/asm/vdso.h
@@ -12,8 +12,6 @@
 #define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name))
 #define VDSO32_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso32_offset_##name))
 
-extern struct vdso_data *vdso_data;
-
 #endif /* __ASSEMBLY __ */
 
 /* Default link addresses for the vDSOs */

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:09:56 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:09:56 +0100
Subject: [PATCH 00/17] vDSO: Introduce generic data storage
Message-ID: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>

Currently each architecture defines the setup of the vDSO data page on
its own, mostly through copy-and-paste from some other architecture.
Extend the existing generic vDSO implementation to also provide generic
data storage.
This removes duplicated code and paves the way for further changes to
the generic vDSO implementation without having to go through a lot of
per-architecture changes.

Based on v6.13-rc1 and intended to be merged through the tip tree.

This also provides the basis for some generic vDSO reworks.
The commits from this series and the upcoming reworks can be seen at:
https://git.kernel.org/pub/scm/linux/kernel/git/thomas.weissschuh/linux.git/log/?h=vdso/store

---
Thomas Wei?schuh (17):
      parisc: Remove unused symbol vdso_data
      vdso: Introduce vdso/align.h
      vdso: Add generic time data storage
      vdso: Add generic random data storage
      vdso: Add generic architecture-specific data storage
      arm64: vdso: Switch to generic storage implementation
      riscv: vdso: Switch to generic storage implementation
      LoongArch: vDSO: Switch to generic storage implementation
      arm: vdso: Switch to generic storage implementation
      s390/vdso: Switch to generic storage implementation
      MIPS: vdso: Switch to generic storage implementation
      powerpc/vdso: Switch to generic storage implementation
      x86/vdso: Switch to generic storage implementation
      x86/vdso/vdso2c: Remove page handling
      vdso: Remove remnants of architecture-specific random state storage
      vdso: Remove remnants of architecture-specific time storage
      vdso: Remove kconfig symbol GENERIC_VDSO_DATA_STORE

 MAINTAINERS                                        |   1 +
 arch/Kconfig                                       |   4 +
 arch/arm/include/asm/vdso.h                        |   2 +
 arch/arm/include/asm/vdso/gettimeofday.h           |   7 +-
 arch/arm/include/asm/vdso/vsyscall.h               |  12 +-
 arch/arm/kernel/asm-offsets.c                      |   4 -
 arch/arm/kernel/vdso.c                             |  34 ++----
 arch/arm/vdso/vdso.lds.S                           |   4 +-
 arch/arm64/include/asm/vdso.h                      |   2 +-
 arch/arm64/include/asm/vdso/compat_gettimeofday.h  |  32 +++---
 arch/arm64/include/asm/vdso/getrandom.h            |  12 --
 arch/arm64/include/asm/vdso/gettimeofday.h         |  16 +--
 arch/arm64/include/asm/vdso/vsyscall.h             |  25 +----
 arch/arm64/kernel/vdso.c                           |  90 +--------------
 arch/arm64/kernel/vdso/vdso.lds.S                  |   7 +-
 arch/arm64/kernel/vdso32/vdso.lds.S                |   7 +-
 arch/loongarch/Kconfig                             |   1 +
 arch/loongarch/include/asm/vdso.h                  |   1 -
 arch/loongarch/include/asm/vdso/arch_data.h        |  25 +++++
 arch/loongarch/include/asm/vdso/getrandom.h        |   5 -
 arch/loongarch/include/asm/vdso/gettimeofday.h     |  14 +--
 arch/loongarch/include/asm/vdso/vdso.h             |  38 +------
 arch/loongarch/include/asm/vdso/vsyscall.h         |  17 ---
 arch/loongarch/kernel/asm-offsets.c                |   2 +-
 arch/loongarch/kernel/vdso.c                       |  92 +--------------
 arch/loongarch/vdso/vdso.lds.S                     |   8 +-
 arch/loongarch/vdso/vgetcpu.c                      |   7 +-
 arch/mips/include/asm/vdso/gettimeofday.h          |   9 +-
 arch/mips/include/asm/vdso/vdso.h                  |  19 ++--
 arch/mips/include/asm/vdso/vsyscall.h              |  14 +--
 arch/mips/kernel/vdso.c                            |  47 +++-----
 arch/mips/vdso/vdso.lds.S                          |   5 +-
 arch/parisc/include/asm/vdso.h                     |   2 -
 arch/powerpc/Kconfig                               |   1 +
 arch/powerpc/include/asm/vdso.h                    |   1 +
 arch/powerpc/include/asm/vdso/arch_data.h          |  37 ++++++
 arch/powerpc/include/asm/vdso/getrandom.h          |  11 +-
 arch/powerpc/include/asm/vdso/gettimeofday.h       |  36 +++---
 arch/powerpc/include/asm/vdso/vsyscall.h           |  13 ---
 arch/powerpc/include/asm/vdso_datapage.h           |  44 +-------
 arch/powerpc/kernel/asm-offsets.c                  |   1 -
 arch/powerpc/kernel/time.c                         |   2 +-
 arch/powerpc/kernel/vdso.c                         | 115 ++-----------------
 arch/powerpc/kernel/vdso/cacheflush.S              |   2 +-
 arch/powerpc/kernel/vdso/datapage.S                |   4 +-
 arch/powerpc/kernel/vdso/gettimeofday.S            |   4 +-
 arch/powerpc/kernel/vdso/vdso32.lds.S              |   4 +-
 arch/powerpc/kernel/vdso/vdso64.lds.S              |   4 +-
 arch/powerpc/kernel/vdso/vgettimeofday.c           |  14 +--
 arch/riscv/Kconfig                                 |   2 +-
 arch/riscv/include/asm/vdso.h                      |   2 +-
 .../include/asm/vdso/{time_data.h => arch_data.h}  |   8 +-
 arch/riscv/include/asm/vdso/gettimeofday.h         |  14 +--
 arch/riscv/include/asm/vdso/vsyscall.h             |   9 --
 arch/riscv/kernel/sys_hwprobe.c                    |   3 +-
 arch/riscv/kernel/vdso.c                           |  90 +--------------
 arch/riscv/kernel/vdso/hwprobe.c                   |   6 +-
 arch/riscv/kernel/vdso/vdso.lds.S                  |   7 +-
 arch/s390/include/asm/vdso.h                       |   4 +-
 arch/s390/include/asm/vdso/getrandom.h             |  12 --
 arch/s390/include/asm/vdso/gettimeofday.h          |  15 +--
 arch/s390/include/asm/vdso/vsyscall.h              |  20 ----
 arch/s390/kernel/time.c                            |   6 +-
 arch/s390/kernel/vdso.c                            |  97 +---------------
 arch/s390/kernel/vdso32/vdso32.lds.S               |   7 +-
 arch/s390/kernel/vdso64/vdso64.lds.S               |   8 +-
 arch/x86/entry/vdso/vdso-layout.lds.S              |  10 +-
 arch/x86/entry/vdso/vdso2c.c                       |  21 ----
 arch/x86/entry/vdso/vdso2c.h                       |  20 ----
 arch/x86/entry/vdso/vma.c                          | 125 ++-------------------
 arch/x86/include/asm/vdso.h                        |   6 -
 arch/x86/include/asm/vdso/getrandom.h              |  10 --
 arch/x86/include/asm/vdso/gettimeofday.h           |  25 +----
 arch/x86/include/asm/vdso/vsyscall.h               |  22 +---
 drivers/char/random.c                              |   6 +-
 include/asm-generic/vdso/vsyscall.h                |  15 +--
 include/linux/align.h                              |  10 +-
 include/linux/time_namespace.h                     |   2 -
 include/linux/vdso_datastore.h                     |  10 ++
 include/vdso/align.h                               |  15 +++
 include/vdso/datapage.h                            | 105 ++++++++++++++---
 include/vdso/helpers.h                             |   8 +-
 kernel/time/namespace.c                            |  12 +-
 kernel/time/vsyscall.c                             |  19 ++--
 lib/Makefile                                       |   2 +
 lib/vdso/getrandom.c                               |   4 +-
 lib/vdso/gettimeofday.c                            |  62 +++++-----
 lib/vdso_kernel/Makefile                           |   3 +
 lib/vdso_kernel/datastore.c                        | 125 +++++++++++++++++++++
 89 files changed, 574 insertions(+), 1231 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20240911-vdso-store-rng-607a3dc9e050

Best regards,
-- 
Thomas Wei?schuh <thomas.weissschuh at linutronix.de>



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:00 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:00 +0100
Subject: [PATCH 04/17] vdso: Add generic random data storage
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-4-f7aed1bdb3b2@linutronix.de>

Extend the generic vDSO data storage with a page for the random state data.
The random state data is stored in a dedicated page, as the existing
storage page is only meant for time-related, time-namespace-aware data.
This simplifies to access logic to not need to handle time namespaces
anymore and also frees up more space in the time-related page.

In case further generic vDSO data store is required it can be added to
the random state page.

Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 include/vdso/datapage.h     | 24 ++++++++++++++++++++++++
 lib/vdso_kernel/datastore.c | 14 ++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 69af424413db1f265607d0f1bdbf88550548c5ba..5ce322422fcb7ba77aeafddbf132fd3e5dbc5a0c 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -145,8 +145,10 @@ extern struct vdso_rng_data _vdso_rng_data __attribute__((visibility("hidden")))
 #else
 extern const struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
 extern const struct vdso_time_data vdso_u_timens_data[CS_BASES] __attribute__((visibility("hidden")));
+extern const struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden")));
 
 extern struct vdso_time_data *vdso_k_time_data;
+extern struct vdso_rng_data *vdso_k_rng_data;
 #endif
 
 /**
@@ -162,6 +164,7 @@ union vdso_data_store {
 enum vdso_pages {
 	VDSO_TIME_PAGE_OFFSET,
 	VDSO_TIMENS_PAGE_OFFSET,
+	VDSO_RNG_PAGE_OFFSET,
 	VDSO_NR_PAGES
 };
 
@@ -185,6 +188,20 @@ static __always_inline const struct vdso_time_data *__arch_get_vdso_u_timens_dat
 #define __arch_get_timens_vdso_data(vd) __arch_get_vdso_u_timens_data()
 #endif /* CONFIG_TIME_NS */
 
+#ifdef CONFIG_VDSO_GETRANDOM
+static __always_inline const struct vdso_rng_data *__arch_get_vdso_u_rng_data(void)
+{
+	return &vdso_u_rng_data;
+}
+#define __arch_get_vdso_rng_data __arch_get_vdso_u_rng_data
+
+static __always_inline struct vdso_rng_data *__arch_get_vdso_k_rng_data(void)
+{
+	return vdso_k_rng_data;
+}
+#define __arch_get_k_vdso_rng_data __arch_get_vdso_k_rng_data
+#endif /* CONFIG_VDSO_GETRANDOM */
+
 #endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
 
 /*
@@ -211,10 +228,17 @@ static __always_inline const struct vdso_time_data *__arch_get_vdso_u_timens_dat
 #define __vdso_u_timens_data
 #endif
 
+#ifdef CONFIG_VDSO_GETRANDOM
+#define __vdso_u_rng_data	PROVIDE(vdso_u_rng_data = vdso_u_data + 2 * PAGE_SIZE);
+#else
+#define __vdso_u_rng_data
+#endif
+
 #define VDSO_VVAR_SYMS						\
 	PROVIDE(vdso_u_data = . - __VDSO_PAGES * PAGE_SIZE);	\
 	PROVIDE(vdso_u_time_data = vdso_u_data);		\
 	__vdso_u_timens_data					\
+	__vdso_u_rng_data					\
 
 
 #endif /* !__ASSEMBLY__ */
diff --git a/lib/vdso_kernel/datastore.c b/lib/vdso_kernel/datastore.c
index c9cd269b1ed1b6cdd5fdf9fe929d0b778314b962..0d4f5317b508a54b4f3295f0335d1eefce74d78c 100644
--- a/lib/vdso_kernel/datastore.c
+++ b/lib/vdso_kernel/datastore.c
@@ -15,6 +15,15 @@ static union vdso_data_store vdso_time_data_store __page_aligned_data;
 struct vdso_time_data *vdso_k_time_data = vdso_time_data_store.data;
 static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE);
 
+#ifdef CONFIG_VDSO_GETRANDOM
+static union {
+	struct vdso_rng_data	data;
+	u8			page[PAGE_SIZE];
+} vdso_rng_data_store __page_aligned_data;
+struct vdso_rng_data *vdso_k_rng_data = &vdso_rng_data_store.data;
+static_assert(sizeof(vdso_rng_data_store) == PAGE_SIZE);
+#endif /* CONFIG_VDSO_GETRANDOM */
+
 static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 			     struct vm_area_struct *vma, struct vm_fault *vmf)
 {
@@ -49,6 +58,11 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 			return VM_FAULT_SIGBUS;
 		pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data));
 		break;
+	case VDSO_RNG_PAGE_OFFSET:
+		if (!IS_ENABLED(CONFIG_VDSO_GETRANDOM))
+			return VM_FAULT_SIGBUS;
+		pfn = __phys_to_pfn(__pa_symbol(vdso_k_rng_data));
+		break;
 	default:
 		return VM_FAULT_SIGBUS;
 	}

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:09:58 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:09:58 +0100
Subject: [PATCH 02/17] vdso: Introduce vdso/align.h
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-2-f7aed1bdb3b2@linutronix.de>

The vDSO implementation can only include headers from the vdso/
namespace. To enable the usage of the ALIGN() macro from the vDSO, move
linux/align.h to vdso/align.h wholly.
As the only dependency linux/const.h is only a wrapper around
vdso/const.h anyways adapt that dependency.

Also provide a compatibility wrapper linux/align.h.

Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 include/linux/align.h | 10 +---------
 include/vdso/align.h  | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/include/linux/align.h b/include/linux/align.h
index 2b4acec7b95a27b6768d48f46519abc584c94d5d..55debf105a5d610c592e5c53a4153018ea1ae2c6 100644
--- a/include/linux/align.h
+++ b/include/linux/align.h
@@ -2,14 +2,6 @@
 #ifndef _LINUX_ALIGN_H
 #define _LINUX_ALIGN_H
 
-#include <linux/const.h>
-
-/* @a is a power of 2 value */
-#define ALIGN(x, a)		__ALIGN_KERNEL((x), (a))
-#define ALIGN_DOWN(x, a)	__ALIGN_KERNEL((x) - ((a) - 1), (a))
-#define __ALIGN_MASK(x, mask)	__ALIGN_KERNEL_MASK((x), (mask))
-#define PTR_ALIGN(p, a)		((typeof(p))ALIGN((unsigned long)(p), (a)))
-#define PTR_ALIGN_DOWN(p, a)	((typeof(p))ALIGN_DOWN((unsigned long)(p), (a)))
-#define IS_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)
+#include <vdso/align.h>
 
 #endif	/* _LINUX_ALIGN_H */
diff --git a/include/vdso/align.h b/include/vdso/align.h
new file mode 100644
index 0000000000000000000000000000000000000000..02dd8626b5c5aa59d2ee0b15799b6e9adb343f65
--- /dev/null
+++ b/include/vdso/align.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_ALIGN_H
+#define __VDSO_ALIGN_H
+
+#include <vdso/const.h>
+
+/* @a is a power of 2 value */
+#define ALIGN(x, a)		__ALIGN_KERNEL((x), (a))
+#define ALIGN_DOWN(x, a)	__ALIGN_KERNEL((x) - ((a) - 1), (a))
+#define __ALIGN_MASK(x, mask)	__ALIGN_KERNEL_MASK((x), (mask))
+#define PTR_ALIGN(p, a)		((typeof(p))ALIGN((unsigned long)(p), (a)))
+#define PTR_ALIGN_DOWN(p, a)	((typeof(p))ALIGN_DOWN((unsigned long)(p), (a)))
+#define IS_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)
+
+#endif	/* __VDSO_ALIGN_H */

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:09:59 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:09:59 +0100
Subject: [PATCH 03/17] vdso: Add generic time data storage
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-3-f7aed1bdb3b2@linutronix.de>

Historically each architecture defined their own way to store the vDSO
data page. Add a generic mechanism to provide storage for that page.

Furthermore this generic storage will be extended to also provide
uniform storage for *non*-time-related data, like the random state or
architecture-specific data. These will have their own pages and data
structures, so rename 'vdso_data' into 'vdso_time_data' to make that
split clear from the name.

Also introduce a new consistent naming scheme for the symbols related to
the vDSO, which makes it clear if the symbol is accessible from
userspace or kernel space and the type of data behind the symbol.

The generic fault handler contains an optimization to prefault the vvar
page when the timens page is accessed. This was lifted from s390 and x86.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 MAINTAINERS                    |  1 +
 include/linux/time_namespace.h |  1 +
 include/linux/vdso_datastore.h | 10 +++++
 include/vdso/datapage.h        | 69 +++++++++++++++++++++++++----
 lib/Kconfig                    |  1 +
 lib/Makefile                   |  2 +
 lib/vdso_kernel/Kconfig        |  7 +++
 lib/vdso_kernel/Makefile       |  3 ++
 lib/vdso_kernel/datastore.c    | 99 ++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 185 insertions(+), 8 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b13d8bbe6bf133ba7b36aa24c2b5e0..9d947e1e90ff3c6060e56f3b7eaa28cd60d6191c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9677,6 +9677,7 @@ F:	include/asm-generic/vdso/vsyscall.h
 F:	include/vdso/
 F:	kernel/time/vsyscall.c
 F:	lib/vdso/
+F:	lib/vdso_kernel/
 
 GENWQE (IBM Generic Workqueue Card)
 M:	Frank Haverkamp <haver at linux.ibm.com>
diff --git a/include/linux/time_namespace.h b/include/linux/time_namespace.h
index 876e31b4461d0ee01fe2bd3d136acdea2611789f..4b81db223f5450218dfaf553b24195be9ba97c08 100644
--- a/include/linux/time_namespace.h
+++ b/include/linux/time_namespace.h
@@ -8,6 +8,7 @@
 #include <linux/ns_common.h>
 #include <linux/err.h>
 #include <linux/time64.h>
+#include <vdso/datapage.h>
 
 struct user_namespace;
 extern struct user_namespace init_user_ns;
diff --git a/include/linux/vdso_datastore.h b/include/linux/vdso_datastore.h
new file mode 100644
index 0000000000000000000000000000000000000000..a91fa24b06e09321fdff8c2c7bdfbc1b206db574
--- /dev/null
+++ b/include/linux/vdso_datastore.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_VDSO_DATASTORE_H
+#define _LINUX_VDSO_DATASTORE_H
+
+#include <linux/mm_types.h>
+
+extern const struct vm_special_mapping vdso_vvar_mapping;
+struct vm_area_struct *vdso_install_vvar_mapping(struct mm_struct *mm, unsigned long addr);
+
+#endif /* _LINUX_VDSO_DATASTORE_H */
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index d967baa0cd0c65784e38dc4fcd7b9e8273923947..69af424413db1f265607d0f1bdbf88550548c5ba 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -45,11 +45,11 @@ struct arch_vdso_time_data {};
  *
  * There is one vdso_timestamp object in vvar for each vDSO-accelerated
  * clock_id. For high-resolution clocks, this encodes the time
- * corresponding to vdso_data.cycle_last. For coarse clocks this encodes
+ * corresponding to vdso_time_data.cycle_last. For coarse clocks this encodes
  * the actual time.
  *
  * To be noticed that for highres clocks nsec is left-shifted by
- * vdso_data.cs[x].shift.
+ * vdso_time_data[x].shift.
  */
 struct vdso_timestamp {
 	u64	sec;
@@ -57,7 +57,7 @@ struct vdso_timestamp {
 };
 
 /**
- * struct vdso_data - vdso datapage representation
+ * struct vdso_time_data - vdso datapage representation
  * @seq:		timebase sequence counter
  * @clock_mode:		clock mode
  * @cycle_last:		timebase at clocksource init
@@ -74,7 +74,7 @@ struct vdso_timestamp {
  * @arch_data:		architecture specific data (optional, defaults
  *			to an empty struct)
  *
- * vdso_data will be accessed by 64 bit and compat code at the same time
+ * vdso_time_data will be accessed by 64 bit and compat code at the same time
  * so we should be careful before modifying this structure.
  *
  * The ordering of the struct members is optimized to have fast access to the
@@ -92,7 +92,7 @@ struct vdso_timestamp {
  * For clocks which are not affected by time namespace adjustment the
  * offset must be zero.
  */
-struct vdso_data {
+struct vdso_time_data {
 	u32			seq;
 
 	s32			clock_mode;
@@ -117,6 +117,8 @@ struct vdso_data {
 	struct arch_vdso_time_data arch_data;
 };
 
+#define vdso_data vdso_time_data
+
 /**
  * struct vdso_rng_data - vdso RNG state information
  * @generation:	counter representing the number of RNG reseeds
@@ -136,18 +138,55 @@ struct vdso_rng_data {
  * With the hidden visibility, the compiler simply generates a PC-relative
  * relocation, and this is what we need.
  */
-extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
-extern struct vdso_data _timens_data[CS_BASES] __attribute__((visibility("hidden")));
+#ifndef CONFIG_GENERIC_VDSO_DATA_STORE
+extern struct vdso_time_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
+extern struct vdso_time_data _timens_data[CS_BASES] __attribute__((visibility("hidden")));
 extern struct vdso_rng_data _vdso_rng_data __attribute__((visibility("hidden")));
+#else
+extern const struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
+extern const struct vdso_time_data vdso_u_timens_data[CS_BASES] __attribute__((visibility("hidden")));
+
+extern struct vdso_time_data *vdso_k_time_data;
+#endif
 
 /**
  * union vdso_data_store - Generic vDSO data page
  */
 union vdso_data_store {
-	struct vdso_data	data[CS_BASES];
+	struct vdso_time_data	data[CS_BASES];
 	u8			page[1U << CONFIG_PAGE_SHIFT];
 };
 
+#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
+
+enum vdso_pages {
+	VDSO_TIME_PAGE_OFFSET,
+	VDSO_TIMENS_PAGE_OFFSET,
+	VDSO_NR_PAGES
+};
+
+static __always_inline struct vdso_time_data *__arch_get_vdso_k_time_data(void)
+{
+	return vdso_k_time_data;
+}
+#define __arch_get_k_vdso_data __arch_get_vdso_k_time_data
+
+static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
+{
+	return vdso_u_time_data;
+}
+#define __arch_get_vdso_data __arch_get_vdso_u_time_data
+
+#ifdef CONFIG_TIME_NS
+static __always_inline const struct vdso_time_data *__arch_get_vdso_u_timens_data(void)
+{
+	return vdso_u_timens_data;
+}
+#define __arch_get_timens_vdso_data(vd) __arch_get_vdso_u_timens_data()
+#endif /* CONFIG_TIME_NS */
+
+#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
+
 /*
  * The generic vDSO implementation requires that gettimeofday.h
  * provides:
@@ -164,6 +203,20 @@ union vdso_data_store {
 #include <asm/vdso/gettimeofday.h>
 #endif /* ENABLE_COMPAT_VDSO */
 
+#else /* !__ASSEMBLY__ */
+
+#ifdef CONFIG_TIME_NS
+#define __vdso_u_timens_data	PROVIDE(vdso_u_timens_data = vdso_u_data + PAGE_SIZE);
+#else
+#define __vdso_u_timens_data
+#endif
+
+#define VDSO_VVAR_SYMS						\
+	PROVIDE(vdso_u_data = . - __VDSO_PAGES * PAGE_SIZE);	\
+	PROVIDE(vdso_u_time_data = vdso_u_data);		\
+	__vdso_u_timens_data					\
+
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __VDSO_DATAPAGE_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 5a318f753b2f44cb0a7905cc0092e81c133bc112..7d59b2c10ce5ffab03378ead254d9f9017a4482f 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -659,6 +659,7 @@ config UCS2_STRING
 # generic vdso
 #
 source "lib/vdso/Kconfig"
+source "lib/vdso_kernel/Kconfig"
 
 source "lib/fonts/Kconfig"
 
diff --git a/lib/Makefile b/lib/Makefile
index a8155c972f02856fcc61ee949ddda436cfe211ff..aeedeea86b26cee50d7ced18f9b77b3c51201930 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -401,3 +401,5 @@ obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
 obj-$(CONFIG_FIRMWARE_TABLE) += fw_table.o
 
 subdir-$(CONFIG_FORTIFY_SOURCE) += test_fortify
+
+obj-y += vdso_kernel/
diff --git a/lib/vdso_kernel/Kconfig b/lib/vdso_kernel/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..0c7ade9b3ece67c0c0ca892544b9e29e53c860c4
--- /dev/null
+++ b/lib/vdso_kernel/Kconfig
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config GENERIC_VDSO_DATA_STORE
+	bool
+	depends on HAVE_GENERIC_VDSO
+	help
+	  Selected by architectures that use the generic vDSO data store.
diff --git a/lib/vdso_kernel/Makefile b/lib/vdso_kernel/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..4826e49f9edbdb48506b50957584ed89bde5f37f
--- /dev/null
+++ b/lib/vdso_kernel/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_GENERIC_VDSO_DATA_STORE) += datastore.o
diff --git a/lib/vdso_kernel/datastore.c b/lib/vdso_kernel/datastore.c
new file mode 100644
index 0000000000000000000000000000000000000000..c9cd269b1ed1b6cdd5fdf9fe929d0b778314b962
--- /dev/null
+++ b/lib/vdso_kernel/datastore.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/linkage.h>
+#include <linux/mmap_lock.h>
+#include <linux/mm.h>
+#include <linux/time_namespace.h>
+#include <linux/types.h>
+#include <linux/vdso_datastore.h>
+#include <vdso/datapage.h>
+
+/*
+ * The vDSO data page.
+ */
+static union vdso_data_store vdso_time_data_store __page_aligned_data;
+struct vdso_time_data *vdso_k_time_data = vdso_time_data_store.data;
+static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE);
+
+static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
+			     struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct page *timens_page = find_timens_vvar_page(vma);
+	unsigned long addr, pfn;
+	vm_fault_t err;
+
+	switch (vmf->pgoff) {
+	case VDSO_TIME_PAGE_OFFSET:
+		pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data));
+		if (timens_page) {
+			/*
+			 * Fault in VVAR page too, since it will be accessed
+			 * to get clock data anyway.
+			 */
+			addr = vmf->address + VDSO_TIMENS_PAGE_OFFSET * PAGE_SIZE;
+			err = vmf_insert_pfn(vma, addr, pfn);
+			if (unlikely(err & VM_FAULT_ERROR))
+				return err;
+			pfn = page_to_pfn(timens_page);
+		}
+		break;
+	case VDSO_TIMENS_PAGE_OFFSET:
+		/*
+		 * If a task belongs to a time namespace then a namespace
+		 * specific VVAR is mapped with the VVAR_DATA_PAGE_OFFSET and
+		 * the real VVAR page is mapped with the VVAR_TIMENS_PAGE_OFFSET
+		 * offset.
+		 * See also the comment near timens_setup_vdso_data().
+		 */
+		if (!IS_ENABLED(CONFIG_TIME_NS) || !timens_page)
+			return VM_FAULT_SIGBUS;
+		pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data));
+		break;
+	default:
+		return VM_FAULT_SIGBUS;
+	}
+
+	return vmf_insert_pfn(vma, vmf->address, pfn);
+}
+
+const struct vm_special_mapping vdso_vvar_mapping = {
+	.name	= "[vvar]",
+	.fault	= vvar_fault,
+};
+
+struct vm_area_struct *vdso_install_vvar_mapping(struct mm_struct *mm, unsigned long addr)
+{
+	return _install_special_mapping(mm, addr, VDSO_NR_PAGES * PAGE_SIZE,
+					VM_READ | VM_MAYREAD | VM_IO | VM_DONTDUMP | VM_PFNMAP,
+					&vdso_vvar_mapping);
+}
+
+#ifdef CONFIG_TIME_NS
+/*
+ * The vvar page layout depends on whether a task belongs to the root or
+ * non-root time namespace. Whenever a task changes its namespace, the VVAR
+ * page tables are cleared and then they will be re-faulted with a
+ * corresponding layout.
+ * See also the comment near timens_setup_vdso_data() for details.
+ */
+int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
+{
+	struct mm_struct *mm = task->mm;
+	struct vm_area_struct *vma;
+	VMA_ITERATOR(vmi, mm, 0);
+
+	mmap_read_lock(mm);
+	for_each_vma(vmi, vma) {
+		if (vma_is_special_mapping(vma, &vdso_vvar_mapping))
+			zap_vma_pages(vma);
+	}
+	mmap_read_unlock(mm);
+
+	return 0;
+}
+#endif
+
+struct vdso_time_data *arch_get_vdso_data(void *vvar_page)
+{
+	return (struct vdso_time_data *)vvar_page;
+}

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:09 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:09 +0100
Subject: [PATCH 13/17] x86/vdso: Switch to generic storage implementation
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-13-f7aed1bdb3b2@linutronix.de>

The generic storage implementation provides the same features as the
custom one. However it can be shared between architectures, making
maintenance easier.

This switch also moves the random state data out of the time data page.
The currently used hardcoded __VDSO_RND_DATA_OFFSET does not take into
account changes to the time data page layout.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/x86/Kconfig                         |   1 +
 arch/x86/entry/vdso/vdso-layout.lds.S    |  14 ++--
 arch/x86/entry/vdso/vma.c                | 125 ++-----------------------------
 arch/x86/include/asm/vdso/getrandom.h    |  10 ---
 arch/x86/include/asm/vdso/gettimeofday.h |  25 +------
 arch/x86/include/asm/vdso/vsyscall.h     |  22 +-----
 6 files changed, 19 insertions(+), 178 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9d7bd0ae48c4260f4abb6dbedc696e3915c230ea..e3d7f17dc414ca93d6e746dbc7f02afd2bc043a8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -177,6 +177,7 @@ config X86
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_GETTIMEOFDAY
+	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select GENERIC_VDSO_OVERFLOW_PROTECT
 	select GUP_GET_PXX_LOW_HIGH		if X86_PAE
diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S
index 872947c1004c35c006f7508eac7dff251c286aeb..6a628ead49beb3480dc750786c31dc125dfd017a 100644
--- a/arch/x86/entry/vdso/vdso-layout.lds.S
+++ b/arch/x86/entry/vdso/vdso-layout.lds.S
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #include <asm/vdso.h>
 #include <asm/vdso/vsyscall.h>
+#include <vdso/datapage.h>
 
 /*
  * Linker script for vDSO.  This is an ELF shared object prelinked to
@@ -17,17 +18,16 @@ SECTIONS
 	 * segment.
 	 */
 
-	vvar_start = . - __VVAR_PAGES * PAGE_SIZE;
-	vvar_page  = vvar_start;
+	VDSO_VVAR_SYMS
 
-	vdso_rng_data = vvar_page + __VDSO_RND_DATA_OFFSET;
-
-	timens_page  = vvar_start + PAGE_SIZE;
-
-	vclock_pages = vvar_start + VDSO_NR_VCLOCK_PAGES * PAGE_SIZE;
+	vclock_pages = vdso_u_data + VDSO_NR_VCLOCK_PAGES * PAGE_SIZE;
 	pvclock_page = vclock_pages + VDSO_PAGE_PVCLOCK_OFFSET * PAGE_SIZE;
 	hvclock_page = vclock_pages + VDSO_PAGE_HVCLOCK_OFFSET * PAGE_SIZE;
 
+	/* For compatibility with vdso2c */
+	vvar_page = vdso_u_data;
+	vvar_start = vdso_u_data;
+
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 39e6efc1a9cab760b8a65e4b02c624e8c75244b5..b9872df56402f5d00a3134481df8f98b35ddbacb 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -14,7 +14,7 @@
 #include <linux/elf.h>
 #include <linux/cpu.h>
 #include <linux/ptrace.h>
-#include <linux/time_namespace.h>
+#include <linux/vdso_datastore.h>
 
 #include <asm/pvclock.h>
 #include <asm/vgtod.h>
@@ -27,13 +27,7 @@
 #include <asm/vdso/vsyscall.h>
 #include <clocksource/hyperv_timer.h>
 
-struct vdso_data *arch_get_vdso_data(void *vvar_page)
-{
-	return (struct vdso_data *)vvar_page;
-}
-
-static union vdso_data_store vdso_data_store __page_aligned_data;
-struct vdso_data *vdso_data = vdso_data_store.data;
+static_assert(VDSO_NR_PAGES + VDSO_NR_VCLOCK_PAGES == __VDSO_PAGES);
 
 unsigned int vclocks_used __read_mostly;
 
@@ -54,7 +48,6 @@ int __init init_vdso_image(const struct vdso_image *image)
 	return 0;
 }
 
-static const struct vm_special_mapping vvar_mapping;
 struct linux_binprm;
 
 static vm_fault_t vdso_fault(const struct vm_special_mapping *sm,
@@ -98,99 +91,6 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
 	return 0;
 }
 
-#ifdef CONFIG_TIME_NS
-/*
- * The vvar page layout depends on whether a task belongs to the root or
- * non-root time namespace. Whenever a task changes its namespace, the VVAR
- * page tables are cleared and then they will re-faulted with a
- * corresponding layout.
- * See also the comment near timens_setup_vdso_data() for details.
- */
-int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
-{
-	struct mm_struct *mm = task->mm;
-	struct vm_area_struct *vma;
-	VMA_ITERATOR(vmi, mm, 0);
-
-	mmap_read_lock(mm);
-	for_each_vma(vmi, vma) {
-		if (vma_is_special_mapping(vma, &vvar_mapping))
-			zap_vma_pages(vma);
-	}
-	mmap_read_unlock(mm);
-
-	return 0;
-}
-#endif
-
-static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
-		      struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	const struct vdso_image *image = vma->vm_mm->context.vdso_image;
-	unsigned long pfn;
-	long sym_offset;
-
-	if (!image)
-		return VM_FAULT_SIGBUS;
-
-	sym_offset = (long)(vmf->pgoff << PAGE_SHIFT) +
-		image->sym_vvar_start;
-
-	/*
-	 * Sanity check: a symbol offset of zero means that the page
-	 * does not exist for this vdso image, not that the page is at
-	 * offset zero relative to the text mapping.  This should be
-	 * impossible here, because sym_offset should only be zero for
-	 * the page past the end of the vvar mapping.
-	 */
-	if (sym_offset == 0)
-		return VM_FAULT_SIGBUS;
-
-	if (sym_offset == image->sym_vvar_page) {
-		struct page *timens_page = find_timens_vvar_page(vma);
-
-		pfn = __pa_symbol(vdso_data) >> PAGE_SHIFT;
-
-		/*
-		 * If a task belongs to a time namespace then a namespace
-		 * specific VVAR is mapped with the sym_vvar_page offset and
-		 * the real VVAR page is mapped with the sym_timens_page
-		 * offset.
-		 * See also the comment near timens_setup_vdso_data().
-		 */
-		if (timens_page) {
-			unsigned long addr;
-			vm_fault_t err;
-
-			/*
-			 * Optimization: inside time namespace pre-fault
-			 * VVAR page too. As on timens page there are only
-			 * offsets for clocks on VVAR, it'll be faulted
-			 * shortly by VDSO code.
-			 */
-			addr = vmf->address + (image->sym_timens_page - sym_offset);
-			err = vmf_insert_pfn(vma, addr, pfn);
-			if (unlikely(err & VM_FAULT_ERROR))
-				return err;
-
-			pfn = page_to_pfn(timens_page);
-		}
-
-		return vmf_insert_pfn(vma, vmf->address, pfn);
-
-	} else if (sym_offset == image->sym_timens_page) {
-		struct page *timens_page = find_timens_vvar_page(vma);
-
-		if (!timens_page)
-			return VM_FAULT_SIGBUS;
-
-		pfn = __pa_symbol(vdso_data) >> PAGE_SHIFT;
-		return vmf_insert_pfn(vma, vmf->address, pfn);
-	}
-
-	return VM_FAULT_SIGBUS;
-}
-
 static vm_fault_t vvar_vclock_fault(const struct vm_special_mapping *sm,
 				    struct vm_area_struct *vma, struct vm_fault *vmf)
 {
@@ -212,7 +112,6 @@ static vm_fault_t vvar_vclock_fault(const struct vm_special_mapping *sm,
 	case VDSO_PAGE_HVCLOCK_OFFSET:
 	{
 		unsigned long pfn = hv_get_tsc_pfn();
-
 		if (pfn && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK))
 			return vmf_insert_pfn(vma, vmf->address, pfn);
 		break;
@@ -228,10 +127,6 @@ static const struct vm_special_mapping vdso_mapping = {
 	.fault = vdso_fault,
 	.mremap = vdso_mremap,
 };
-static const struct vm_special_mapping vvar_mapping = {
-	.name = "[vvar]",
-	.fault = vvar_fault,
-};
 static const struct vm_special_mapping vvar_vclock_mapping = {
 	.name = "[vvar_vclock]",
 	.fault = vvar_vclock_fault,
@@ -253,13 +148,13 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr)
 		return -EINTR;
 
 	addr = get_unmapped_area(NULL, addr,
-				 image->size - image->sym_vvar_start, 0, 0);
+				 image->size + __VDSO_PAGES * PAGE_SIZE, 0, 0);
 	if (IS_ERR_VALUE(addr)) {
 		ret = addr;
 		goto up_fail;
 	}
 
-	text_start = addr - image->sym_vvar_start;
+	text_start = addr + __VDSO_PAGES * PAGE_SIZE;
 
 	/*
 	 * MAYWRITE to allow gdb to COW and set breakpoints
@@ -276,13 +171,7 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr)
 		goto up_fail;
 	}
 
-	vma = _install_special_mapping(mm,
-				       addr,
-				       (__VVAR_PAGES - VDSO_NR_VCLOCK_PAGES) * PAGE_SIZE,
-				       VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP|
-				       VM_PFNMAP,
-				       &vvar_mapping);
-
+	vma = vdso_install_vvar_mapping(mm, addr);
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
 		do_munmap(mm, text_start, image->size, NULL);
@@ -290,7 +179,7 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr)
 	}
 
 	vma = _install_special_mapping(mm,
-				       addr + (__VVAR_PAGES - VDSO_NR_VCLOCK_PAGES) * PAGE_SIZE,
+				       vma->vm_end,
 				       VDSO_NR_VCLOCK_PAGES * PAGE_SIZE,
 				       VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP|
 				       VM_PFNMAP,
@@ -327,7 +216,7 @@ int map_vdso_once(const struct vdso_image *image, unsigned long addr)
 	 */
 	for_each_vma(vmi, vma) {
 		if (vma_is_special_mapping(vma, &vdso_mapping) ||
-				vma_is_special_mapping(vma, &vvar_mapping) ||
+				vma_is_special_mapping(vma, &vdso_vvar_mapping) ||
 				vma_is_special_mapping(vma, &vvar_vclock_mapping)) {
 			mmap_write_unlock(mm);
 			return -EEXIST;
diff --git a/arch/x86/include/asm/vdso/getrandom.h b/arch/x86/include/asm/vdso/getrandom.h
index 2bf9c0e970c3e7d2a2ddfcb1d007cb73da200494..af85539f6557b8e22f7c8fb142c5c83330219af1 100644
--- a/arch/x86/include/asm/vdso/getrandom.h
+++ b/arch/x86/include/asm/vdso/getrandom.h
@@ -27,16 +27,6 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig
 	return ret;
 }
 
-extern struct vdso_rng_data vdso_rng_data
-	__attribute__((visibility("hidden")));
-
-static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void)
-{
-	if (IS_ENABLED(CONFIG_TIME_NS) && __arch_get_vdso_data()->clock_mode == VDSO_CLOCKMODE_TIMENS)
-		return (void *)&vdso_rng_data + ((void *)&timens_page - (void *)__arch_get_vdso_data());
-	return &vdso_rng_data;
-}
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_VDSO_GETRANDOM_H */
diff --git a/arch/x86/include/asm/vdso/gettimeofday.h b/arch/x86/include/asm/vdso/gettimeofday.h
index 375a34b0f365792ec108381d7c7229f8351448f7..edec796832e08b73d6d58bda6408957048f4e80e 100644
--- a/arch/x86/include/asm/vdso/gettimeofday.h
+++ b/arch/x86/include/asm/vdso/gettimeofday.h
@@ -19,12 +19,6 @@
 #include <asm/pvclock.h>
 #include <clocksource/hyperv_timer.h>
 
-extern struct vdso_data vvar_page
-	__attribute__((visibility("hidden")));
-
-extern struct vdso_data timens_page
-	__attribute__((visibility("hidden")));
-
 #define VDSO_HAS_TIME 1
 
 #define VDSO_HAS_CLOCK_GETRES 1
@@ -59,14 +53,6 @@ extern struct ms_hyperv_tsc_page hvclock_page
 	__attribute__((visibility("hidden")));
 #endif
 
-#ifdef CONFIG_TIME_NS
-static __always_inline
-const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
-{
-	return &timens_page;
-}
-#endif
-
 #ifndef BUILD_VDSO32
 
 static __always_inline
@@ -250,7 +236,7 @@ static u64 vread_hvclock(void)
 #endif
 
 static inline u64 __arch_get_hw_counter(s32 clock_mode,
-					const struct vdso_data *vd)
+					const struct vdso_time_data *vd)
 {
 	if (likely(clock_mode == VDSO_CLOCKMODE_TSC))
 		return (u64)rdtsc_ordered() & S64_MAX;
@@ -275,12 +261,7 @@ static inline u64 __arch_get_hw_counter(s32 clock_mode,
 	return U64_MAX;
 }
 
-static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
-{
-	return &vvar_page;
-}
-
-static inline bool arch_vdso_clocksource_ok(const struct vdso_data *vd)
+static inline bool arch_vdso_clocksource_ok(const struct vdso_time_data *vd)
 {
 	return true;
 }
@@ -319,7 +300,7 @@ static inline bool arch_vdso_cycles_ok(u64 cycles)
  * declares everything with the MSB/Sign-bit set as invalid. Therefore the
  * effective mask is S64_MAX.
  */
-static __always_inline u64 vdso_calc_ns(const struct vdso_data *vd, u64 cycles, u64 base)
+static __always_inline u64 vdso_calc_ns(const struct vdso_time_data *vd, u64 cycles, u64 base)
 {
 	u64 delta = cycles - vd->cycle_last;
 
diff --git a/arch/x86/include/asm/vdso/vsyscall.h b/arch/x86/include/asm/vdso/vsyscall.h
index 37b4a70559a8228601203fe7b99b9ddfc3d94f1b..1cf31e4db2c4b58de3a81d3bbe109e18b95acc6f 100644
--- a/arch/x86/include/asm/vdso/vsyscall.h
+++ b/arch/x86/include/asm/vdso/vsyscall.h
@@ -2,8 +2,7 @@
 #ifndef __ASM_VDSO_VSYSCALL_H
 #define __ASM_VDSO_VSYSCALL_H
 
-#define __VDSO_RND_DATA_OFFSET  640
-#define __VVAR_PAGES	4
+#define __VDSO_PAGES	6
 
 #define VDSO_NR_VCLOCK_PAGES	2
 #define VDSO_PAGE_PVCLOCK_OFFSET	0
@@ -14,25 +13,6 @@
 #include <vdso/datapage.h>
 #include <asm/vgtod.h>
 
-extern struct vdso_data *vdso_data;
-
-/*
- * Update the vDSO data page to keep in sync with kernel timekeeping.
- */
-static __always_inline
-struct vdso_data *__x86_get_k_vdso_data(void)
-{
-	return vdso_data;
-}
-#define __arch_get_k_vdso_data __x86_get_k_vdso_data
-
-static __always_inline
-struct vdso_rng_data *__x86_get_k_vdso_rng_data(void)
-{
-	return (void *)vdso_data + __VDSO_RND_DATA_OFFSET;
-}
-#define __arch_get_k_vdso_rng_data __x86_get_k_vdso_rng_data
-
 /* The asm-generic header needs to be included after the definitions above */
 #include <asm-generic/vdso/vsyscall.h>
 

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:10 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:10 +0100
Subject: [PATCH 14/17] x86/vdso/vdso2c: Remove page handling
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-14-f7aed1bdb3b2@linutronix.de>

The values are not used anymore.
Also the sanity checks performed by vdso2c can never trigger as they
only validate invariants already enforced by the linker script.

Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/x86/entry/vdso/vdso-layout.lds.S |  4 ----
 arch/x86/entry/vdso/vdso2c.c          | 21 ---------------------
 arch/x86/entry/vdso/vdso2c.h          | 20 --------------------
 arch/x86/include/asm/vdso.h           |  6 ------
 4 files changed, 51 deletions(-)

diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S
index 6a628ead49beb3480dc750786c31dc125dfd017a..f93944ec29e5318aea29e4ad83c3e7f76889e489 100644
--- a/arch/x86/entry/vdso/vdso-layout.lds.S
+++ b/arch/x86/entry/vdso/vdso-layout.lds.S
@@ -24,10 +24,6 @@ SECTIONS
 	pvclock_page = vclock_pages + VDSO_PAGE_PVCLOCK_OFFSET * PAGE_SIZE;
 	hvclock_page = vclock_pages + VDSO_PAGE_HVCLOCK_OFFSET * PAGE_SIZE;
 
-	/* For compatibility with vdso2c */
-	vvar_page = vdso_u_data;
-	vvar_start = vdso_u_data;
-
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text
diff --git a/arch/x86/entry/vdso/vdso2c.c b/arch/x86/entry/vdso/vdso2c.c
index 90d15f2a72055e37f2ef4292096dd780a051bc84..f84e8f8fa5fe6d1bc680895dfef28fe9251a7fe3 100644
--- a/arch/x86/entry/vdso/vdso2c.c
+++ b/arch/x86/entry/vdso/vdso2c.c
@@ -69,33 +69,12 @@
 
 const char *outfilename;
 
-/* Symbols that we need in vdso2c. */
-enum {
-	sym_vvar_start,
-	sym_vvar_page,
-	sym_pvclock_page,
-	sym_hvclock_page,
-	sym_timens_page,
-};
-
-const int special_pages[] = {
-	sym_vvar_page,
-	sym_pvclock_page,
-	sym_hvclock_page,
-	sym_timens_page,
-};
-
 struct vdso_sym {
 	const char *name;
 	bool export;
 };
 
 struct vdso_sym required_syms[] = {
-	[sym_vvar_start] = {"vvar_start", true},
-	[sym_vvar_page] = {"vvar_page", true},
-	[sym_pvclock_page] = {"pvclock_page", true},
-	[sym_hvclock_page] = {"hvclock_page", true},
-	[sym_timens_page] = {"timens_page", true},
 	{"VDSO32_NOTE_MASK", true},
 	{"__kernel_vsyscall", true},
 	{"__kernel_sigreturn", true},
diff --git a/arch/x86/entry/vdso/vdso2c.h b/arch/x86/entry/vdso/vdso2c.h
index 67b3e37576a64a29ecbdc6fd75e410fc52a82e58..78ed1c1f28b92b97973f57d3f65b9c4d4694f462 100644
--- a/arch/x86/entry/vdso/vdso2c.h
+++ b/arch/x86/entry/vdso/vdso2c.h
@@ -150,26 +150,6 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
 		}
 	}
 
-	/* Validate mapping addresses. */
-	for (i = 0; i < sizeof(special_pages) / sizeof(special_pages[0]); i++) {
-		INT_BITS symval = syms[special_pages[i]];
-
-		if (!symval)
-			continue;  /* The mapping isn't used; ignore it. */
-
-		if (symval % 4096)
-			fail("%s must be a multiple of 4096\n",
-			     required_syms[i].name);
-		if (symval + 4096 < syms[sym_vvar_start])
-			fail("%s underruns vvar_start\n",
-			     required_syms[i].name);
-		if (symval + 4096 > 0)
-			fail("%s is on the wrong side of the vdso text\n",
-			     required_syms[i].name);
-	}
-	if (syms[sym_vvar_start] % 4096)
-		fail("vvar_begin must be a multiple of 4096\n");
-
 	if (!image_name) {
 		fwrite(stripped_addr, stripped_len, 1, outfile);
 		return;
diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h
index d7f6592b74a94f6fecba59ce8f23eb3990843db4..80be0da733df43de7520bef69ad120ce05d37994 100644
--- a/arch/x86/include/asm/vdso.h
+++ b/arch/x86/include/asm/vdso.h
@@ -18,12 +18,6 @@ struct vdso_image {
 	unsigned long extable_base, extable_len;
 	const void *extable;
 
-	long sym_vvar_start;  /* Negative offset to the vvar area */
-
-	long sym_vvar_page;
-	long sym_pvclock_page;
-	long sym_hvclock_page;
-	long sym_timens_page;
 	long sym_VDSO32_NOTE_MASK;
 	long sym___kernel_sigreturn;
 	long sym___kernel_rt_sigreturn;

-- 
2.47.1



From robh at kernel.org  Mon Dec 16 06:27:14 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 16 Dec 2024 08:27:14 -0600
Subject: [PATCH 2/4] dt-bindings: mfd: syscon: allow two reg regions for gs101-pmu
In-Reply-To: <20241216141846.GA71151-robh@kernel.org>
References: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
 <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-2-c72978f63713@linaro.org>
 <20241216141846.GA71151-robh@kernel.org>
Message-ID: <CAL_JsqKNZGwgd17q4Em9-fdVLgTsjLYnVHEXjDcH+i60b1ssdA@mail.gmail.com>

On Mon, Dec 16, 2024 at 8:19?AM Rob Herring <robh at kernel.org> wrote:
>
> On Fri, Dec 13, 2024 at 04:44:39PM +0000, Peter Griffin wrote:
> > To avoid dtschema warnings allow google,gs101-pmu to have
> > two reg regions.
>
> It's not a "simple" syscon if you have 2 regions, so put it in its own
> schema doc.

NM, I see it already does. If you keep 'syscon', then 'maxItems: 1'
will probably need to move to syscon.yaml.

Rob


From maz at kernel.org  Mon Dec 16 06:31:43 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 16 Dec 2024 14:31:43 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to __cpuinfo_store_cpu()
In-Reply-To: <Z2AfOZ82QG_ukWry@J2N7QTR9R3>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>	<87a5cysfci.wl-maz@kernel.org>	<Z2AfOZ82QG_ukWry@J2N7QTR9R3>
Message-ID: <865xnjsnqo.wl-maz@kernel.org>

On Mon, 16 Dec 2024 12:38:17 +0000,
Mark Rutland <mark.rutland at arm.com> wrote:
> 
> On Sat, Dec 14, 2024 at 10:56:13AM +0000, Marc Zyngier wrote:
>
> > Why isn't the following a good enough fix? It makes it plain that
> > boot_cpu_data is only a copy of CPU0's initial boot state.
> > 
> > diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> > index d79e88fccdfce..0cbb42fd48850 100644
> > --- a/arch/arm64/kernel/cpuinfo.c
> > +++ b/arch/arm64/kernel/cpuinfo.c
> > @@ -497,6 +497,6 @@ void __init cpuinfo_store_boot_cpu(void)
> >  	struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0);
> >  	__cpuinfo_store_cpu(info);
> >  
> > +	init_cpu_features(info);
> >  	boot_cpu_data = *info;
> > -	init_cpu_features(&boot_cpu_data);
> >  }
> 
> I think that change in isolation is fine, but I don't think that's the
> right fix.
> 
> I think that what we did in commit:
> 
>    892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")
> 
> ... introduces an anti-pattern that'd be nice to avoid. That broke the
> existing split of __cpuinfo_store_cpu() and init_cpu_features(), where
> the former read the ID regs, and the latter set up the features
> *without* altering the copy of the ID regs that was read. i.e.
> init_cpu_features() shouldn't write to its info argument at all.
> 
> I understand that we have to do something as a bodge for broken FW which
> traps SME, but I'd much rather we did that within __cpuinfo_store_cpu().

Honestly, I'd rather revert that patch, together with b3000e2133d8
("arm64: Add the arm64.nosme command line option"). I'm getting tired
of the FW nonsense, and we are only allowing vendors to ship untested
crap.

Furthermore, given the state of SME in the kernel, I don't think this
is makes any difference. So maybe this is the right time to reset
everything to a sane state.

> Can we add something to check whether SME was disabled on the command
> line, and use that in __cpuinfo_store_cpu(), effectively reverting
> 892f7237b3ff?

Maybe, but that'd be before any sanitisation of the overrides, so it
would have to severely limit its scope. Something like this, which I
haven't tested:

diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index d79e88fccdfce..9e9295e045009 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -492,10 +492,22 @@ void cpuinfo_store_cpu(void)
 	update_cpu_features(smp_processor_id(), info, &boot_cpu_data);
 }
 
+static void cpuinfo_apply_overrides(struct cpuinfo_arm64 *info)
+{
+	if (FIELD_GET(ID_AA64PFR0_EL1_SVE, id_aa64pfr0_override.mask) &&
+	    !FIELD_GET(ID_AA64PFR0_EL1_SVE, id_aa64pfr0_override.val))
+		info->reg_id_aa64pfr0 &= ~ID_AA64PFR0_EL1_SVE;
+
+	if (FIELD_GET(ID_AA64PFR1_EL1_SME, id_aa64pfr1_override.mask) &&
+	    !FIELD_GET(ID_AA64PFR1_EL1_SME, id_aa64pfr1_override.val))
+		info->reg_id_aa64pfr1 &= ~ID_AA64PFR1_EL1_SME;
+}
+
 void __init cpuinfo_store_boot_cpu(void)
 {
 	struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0);
 	__cpuinfo_store_cpu(info);
+	cpuinfo_apply_overrides(info);
 
 	boot_cpu_data = *info;
 	init_cpu_features(&boot_cpu_data);

But this will have ripple effects on the rest of the override code
(the kernel messages are likely to be wrong).

	M.

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


From mark.rutland at arm.com  Mon Dec 16 06:31:47 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 16 Dec 2024 14:31:47 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <855dbb91-db37-4178-bd0b-511994d3aef7@sirena.org.uk>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
 <87a5cysfci.wl-maz@kernel.org>
 <709a0e75-0d0c-4bff-b9fd-3bbb55c97bd5@sirena.org.uk>
 <Z2Agntn52mY5bSTp@J2N7QTR9R3>
 <855dbb91-db37-4178-bd0b-511994d3aef7@sirena.org.uk>
Message-ID: <Z2A502_EpqvLYN8g@J2N7QTR9R3.cambridge.arm.com>

On Mon, Dec 16, 2024 at 01:23:55PM +0000, Mark Brown wrote:
> On Mon, Dec 16, 2024 at 12:44:14PM +0000, Mark Rutland wrote:
> 
> > ... didn't matter either way, and using '&boot_cpu_data' was intended to
> > make it clear that the features were based on the boot CPU's info, even
> > if you just grepped for that and didn't see the surrounding context.
> 
> Right, that was my best guess as to what was supposed to be going on
> but it wasn't super clear.  The code could use some more comments.
> 
> > I think the real fix here is to move the reading back into
> > __cpuinfo_store_cpu(), but to have an explicit check that SME has been
> > disabled on the commandline, with a comment explaining that this is a
> > bodge for broken FW which traps the SME ID regs.
> 
> That should be doable.
> 
> There's a few other similar ID registers (eg, we already read GMID_EL1
> and MPAMIDR_EL1) make me a bit nervous that we might need to generalise
> it a bit, but we can deal with that if it comes up.  Even for SME the
> disable was added speculatively, the factors that made this come up for
> SVE are less likely to be an issue with SME.

FWIW, I had a quick go (with only the SME case), and I think the shape
that we want is roughly as below, which I think is easy to generalise to
those other cases.

MarcZ, thoughts?

Mark.

---->8----
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 8b4e5a3cd24c8..f16eb99c10723 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -91,6 +91,16 @@ struct arm64_ftr_override {
 	u64		mask;
 };
 
+static inline u64
+arm64_ftr_override_apply(const struct arm64_ftr_override *override,
+			 u64 val)
+{
+	val &= ~override->mask;
+	val |= override->val & override->mask;
+
+	return val;
+}
+
 /*
  * @arm64_ftr_reg - Feature register
  * @strict_mask		Bits which should match across all CPUs for sanity.
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed84..faad7d3e4cf5f 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1167,12 +1167,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
 		unsigned long cpacr = cpacr_save_enable_kernel_sme();
 
-		/*
-		 * We mask out SMPS since even if the hardware
-		 * supports priorities the kernel does not at present
-		 * and we block access to them.
-		 */
-		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
 		vec_init_vq_map(ARM64_VEC_SME);
 
 		cpacr_restore(cpacr);
@@ -1550,10 +1544,8 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
 	}
 
 	regp  = get_arm64_ftr_reg(sys_id);
-	if (regp) {
-		val &= ~regp->override->mask;
-		val |= (regp->override->val & regp->override->mask);
-	}
+	if (regp)
+		val = arm64_ftr_override_apply(regp->override, val);
 
 	return val;
 }
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index d79e88fccdfce..1460e3541132f 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -439,6 +439,24 @@ static void __cpuinfo_store_cpu_32bit(struct cpuinfo_32bit *info)
 	info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
 }
 
+static void __cpuinfo_store_cpu_sme(struct cpuinfo_arm64 *info)
+{
+	/*
+	 * TODO: explain that this bodge is to avoid trapping.
+	 */
+	u64 pfr1 = info->reg_id_aa64pfr1;
+	pfr1 = arm64_ftr_override_apply(&id_aa64pfr1_override, pfr1);
+	if (!id_aa64pfr1_sme(pfr1))
+		return;
+
+	/*
+	 * We mask out SMPS since even if the hardware
+	 * supports priorities the kernel does not at present
+	 * and we block access to them.
+	 */
+	info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
+}
+
 static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 {
 	info->reg_cntfrq = arch_timer_get_cntfrq();
@@ -482,6 +500,8 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
 		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
 
+	__cpuinfo_store_cpu_sme(info);
+
 	cpuinfo_detect_icache_policy(info);
 }
 




From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:12 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:12 +0100
Subject: [PATCH 16/17] vdso: Remove remnants of architecture-specific time
 storage
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-16-f7aed1bdb3b2@linutronix.de>

All users of the random vDSO are using the generic storage
implementation. Remove the now unnecessary compatibility accessor
functions and symbols.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/arm/include/asm/vdso/vsyscall.h |  2 +-
 include/asm-generic/vdso/vsyscall.h  | 15 +++------
 include/linux/time_namespace.h       |  3 --
 include/vdso/datapage.h              | 24 +-------------
 include/vdso/helpers.h               |  8 ++---
 kernel/time/namespace.c              | 12 +++----
 kernel/time/vsyscall.c               | 19 ++++++-----
 lib/vdso/gettimeofday.c              | 62 ++++++++++++++++++------------------
 lib/vdso_kernel/datastore.c          | 10 +++---
 9 files changed, 60 insertions(+), 95 deletions(-)

diff --git a/arch/arm/include/asm/vdso/vsyscall.h b/arch/arm/include/asm/vdso/vsyscall.h
index 6fe8f7113e9e533a8b7582f71611372c8db3b11f..828348083a6041f310a869e07be755b7baa4bdd0 100644
--- a/arch/arm/include/asm/vdso/vsyscall.h
+++ b/arch/arm/include/asm/vdso/vsyscall.h
@@ -14,7 +14,7 @@ void __arm_sync_vdso_time_data(struct vdso_time_data *vdata)
 {
 	flush_dcache_page(virt_to_page(vdata));
 }
-#define __arch_sync_vdso_data __arm_sync_vdso_time_data
+#define __arch_sync_vdso_time_data __arm_sync_vdso_time_data
 
 /* The asm-generic header needs to be included after the definitions above */
 #include <asm-generic/vdso/vsyscall.h>
diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h
index 01dafd604188fb0512d21c4ce4b027f7da54f5a0..cb012850a9993bd0df3d118c5412540968adb36a 100644
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -4,24 +4,17 @@
 
 #ifndef __ASSEMBLY__
 
-#ifndef __arch_get_k_vdso_data
-static __always_inline struct vdso_data *__arch_get_k_vdso_data(void)
-{
-	return NULL;
-}
-#endif /* __arch_get_k_vdso_data */
-
 #ifndef __arch_update_vsyscall
-static __always_inline void __arch_update_vsyscall(struct vdso_data *vdata)
+static __always_inline void __arch_update_vsyscall(struct vdso_time_data *vdata)
 {
 }
 #endif /* __arch_update_vsyscall */
 
-#ifndef __arch_sync_vdso_data
-static __always_inline void __arch_sync_vdso_data(struct vdso_data *vdata)
+#ifndef __arch_sync_vdso_time_data
+static __always_inline void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
 {
 }
-#endif /* __arch_sync_vdso_data */
+#endif /* __arch_sync_vdso_time_data */
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/include/linux/time_namespace.h b/include/linux/time_namespace.h
index 4b81db223f5450218dfaf553b24195be9ba97c08..0b8b32bf0655109d368c5dacc23ca5efcbb5aa80 100644
--- a/include/linux/time_namespace.h
+++ b/include/linux/time_namespace.h
@@ -8,7 +8,6 @@
 #include <linux/ns_common.h>
 #include <linux/err.h>
 #include <linux/time64.h>
-#include <vdso/datapage.h>
 
 struct user_namespace;
 extern struct user_namespace init_user_ns;
@@ -166,6 +165,4 @@ static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
 }
 #endif
 
-struct vdso_data *arch_get_vdso_data(void *vvar_page);
-
 #endif /* _LINUX_TIMENS_H */
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 0fc240c08e0f7cf596135eed18dd6f06011917d5..fe2368d9ae6a759101de80b1746f5cc221d7d142 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -128,8 +128,6 @@ struct vdso_time_data {
 	struct arch_vdso_time_data arch_data;
 };
 
-#define vdso_data vdso_time_data
-
 /**
  * struct vdso_rng_data - vdso RNG state information
  * @generation:	counter representing the number of RNG reseeds
@@ -149,10 +147,7 @@ struct vdso_rng_data {
  * With the hidden visibility, the compiler simply generates a PC-relative
  * relocation, and this is what we need.
  */
-#ifndef CONFIG_GENERIC_VDSO_DATA_STORE
-extern struct vdso_time_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
-extern struct vdso_time_data _timens_data[CS_BASES] __attribute__((visibility("hidden")));
-#else
+#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
 extern const struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
 extern const struct vdso_time_data vdso_u_timens_data[CS_BASES] __attribute__((visibility("hidden")));
 extern const struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden")));
@@ -163,14 +158,6 @@ extern struct vdso_rng_data *vdso_k_rng_data;
 extern struct vdso_arch_data *vdso_k_arch_data;
 #endif
 
-/**
- * union vdso_data_store - Generic vDSO data page
- */
-union vdso_data_store {
-	struct vdso_time_data	data[CS_BASES];
-	u8			page[1U << CONFIG_PAGE_SHIFT];
-};
-
 #ifdef CONFIG_GENERIC_VDSO_DATA_STORE
 
 #define VDSO_ARCH_DATA_SIZE ALIGN(sizeof(struct vdso_arch_data), PAGE_SIZE)
@@ -185,24 +172,16 @@ enum vdso_pages {
 	VDSO_NR_PAGES
 };
 
-static __always_inline struct vdso_time_data *__arch_get_vdso_k_time_data(void)
-{
-	return vdso_k_time_data;
-}
-#define __arch_get_k_vdso_data __arch_get_vdso_k_time_data
-
 static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
 {
 	return vdso_u_time_data;
 }
-#define __arch_get_vdso_data __arch_get_vdso_u_time_data
 
 #ifdef CONFIG_TIME_NS
 static __always_inline const struct vdso_time_data *__arch_get_vdso_u_timens_data(void)
 {
 	return vdso_u_timens_data;
 }
-#define __arch_get_timens_vdso_data(vd) __arch_get_vdso_u_timens_data()
 #endif /* CONFIG_TIME_NS */
 
 #ifdef CONFIG_VDSO_GETRANDOM
@@ -224,7 +203,6 @@ static __always_inline const struct vdso_arch_data *__arch_get_vdso_u_arch_data(
 /*
  * The generic vDSO implementation requires that gettimeofday.h
  * provides:
- * - __arch_get_vdso_data(): to get the vdso datapage.
  * - __arch_get_hw_counter(): to get the hw counter based on the
  *   clock_mode.
  * - gettimeofday_fallback(): fallback for gettimeofday.
diff --git a/include/vdso/helpers.h b/include/vdso/helpers.h
index 3ddb03bb05cbeefc110adf0e672c2cd68848a0ae..41c3087070c7ab21d7adec04e6cd30c4b32ea221 100644
--- a/include/vdso/helpers.h
+++ b/include/vdso/helpers.h
@@ -7,7 +7,7 @@
 #include <asm/barrier.h>
 #include <vdso/datapage.h>
 
-static __always_inline u32 vdso_read_begin(const struct vdso_data *vd)
+static __always_inline u32 vdso_read_begin(const struct vdso_time_data *vd)
 {
 	u32 seq;
 
@@ -18,7 +18,7 @@ static __always_inline u32 vdso_read_begin(const struct vdso_data *vd)
 	return seq;
 }
 
-static __always_inline u32 vdso_read_retry(const struct vdso_data *vd,
+static __always_inline u32 vdso_read_retry(const struct vdso_time_data *vd,
 					   u32 start)
 {
 	u32 seq;
@@ -28,7 +28,7 @@ static __always_inline u32 vdso_read_retry(const struct vdso_data *vd,
 	return seq != start;
 }
 
-static __always_inline void vdso_write_begin(struct vdso_data *vd)
+static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
 {
 	/*
 	 * WRITE_ONCE() is required otherwise the compiler can validly tear
@@ -40,7 +40,7 @@ static __always_inline void vdso_write_begin(struct vdso_data *vd)
 	smp_wmb();
 }
 
-static __always_inline void vdso_write_end(struct vdso_data *vd)
+static __always_inline void vdso_write_end(struct vdso_time_data *vd)
 {
 	smp_wmb();
 	/*
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index 0775b9ec952af9639480db9480d06d12293d1ceb..12f55aa539adbc11cce4055f519dbeca8a73320c 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -165,18 +165,18 @@ static struct timens_offset offset_from_ts(struct timespec64 off)
  *     HVCLOCK
  *     VVAR
  *
- * The check for vdso_data->clock_mode is in the unlikely path of
+ * The check for vdso_time_data->clock_mode is in the unlikely path of
  * the seq begin magic. So for the non-timens case most of the time
  * 'seq' is even, so the branch is not taken.
  *
  * If 'seq' is odd, i.e. a concurrent update is in progress, the extra check
- * for vdso_data->clock_mode is a non-issue. The task is spin waiting for the
+ * for vdso_time_data->clock_mode is a non-issue. The task is spin waiting for the
  * update to finish and for 'seq' to become even anyway.
  *
- * Timens page has vdso_data->clock_mode set to VDSO_CLOCKMODE_TIMENS which
+ * Timens page has vdso_time_data->clock_mode set to VDSO_CLOCKMODE_TIMENS which
  * enforces the time namespace handling path.
  */
-static void timens_setup_vdso_data(struct vdso_data *vdata,
+static void timens_setup_vdso_data(struct vdso_time_data *vdata,
 				   struct time_namespace *ns)
 {
 	struct timens_offset *offset = vdata->offset;
@@ -219,7 +219,7 @@ static DEFINE_MUTEX(offset_lock);
 static void timens_set_vvar_page(struct task_struct *task,
 				struct time_namespace *ns)
 {
-	struct vdso_data *vdata;
+	struct vdso_time_data *vdata;
 	unsigned int i;
 
 	if (ns == &init_time_ns)
@@ -235,7 +235,7 @@ static void timens_set_vvar_page(struct task_struct *task,
 		goto out;
 
 	ns->frozen_offsets = true;
-	vdata = arch_get_vdso_data(page_address(ns->vvar_page));
+	vdata = page_address(ns->vvar_page);
 
 	for (i = 0; i < CS_BASES; i++)
 		timens_setup_vdso_data(&vdata[i], ns);
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index 05d3831431658227c080a89202f45e7a0af88895..418192296ef7dd3c1772d50f129e7838883cf00c 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -15,8 +15,7 @@
 
 #include "timekeeping_internal.h"
 
-static inline void update_vdso_data(struct vdso_data *vdata,
-				    struct timekeeper *tk)
+static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct timekeeper *tk)
 {
 	struct vdso_timestamp *vdso_ts;
 	u64 nsec, sec;
@@ -77,7 +76,7 @@ static inline void update_vdso_data(struct vdso_data *vdata,
 
 void update_vsyscall(struct timekeeper *tk)
 {
-	struct vdso_data *vdata = __arch_get_k_vdso_data();
+	struct vdso_time_data *vdata = vdso_k_time_data;
 	struct vdso_timestamp *vdso_ts;
 	s32 clock_mode;
 	u64 nsec;
@@ -117,23 +116,23 @@ void update_vsyscall(struct timekeeper *tk)
 	 * update of the high resolution parts.
 	 */
 	if (clock_mode != VDSO_CLOCKMODE_NONE)
-		update_vdso_data(vdata, tk);
+		update_vdso_time_data(vdata, tk);
 
 	__arch_update_vsyscall(vdata);
 
 	vdso_write_end(vdata);
 
-	__arch_sync_vdso_data(vdata);
+	__arch_sync_vdso_time_data(vdata);
 }
 
 void update_vsyscall_tz(void)
 {
-	struct vdso_data *vdata = __arch_get_k_vdso_data();
+	struct vdso_time_data *vdata = vdso_k_time_data;
 
 	vdata[CS_HRES_COARSE].tz_minuteswest = sys_tz.tz_minuteswest;
 	vdata[CS_HRES_COARSE].tz_dsttime = sys_tz.tz_dsttime;
 
-	__arch_sync_vdso_data(vdata);
+	__arch_sync_vdso_time_data(vdata);
 }
 
 /**
@@ -150,7 +149,7 @@ void update_vsyscall_tz(void)
  */
 unsigned long vdso_update_begin(void)
 {
-	struct vdso_data *vdata = __arch_get_k_vdso_data();
+	struct vdso_time_data *vdata = vdso_k_time_data;
 	unsigned long flags = timekeeper_lock_irqsave();
 
 	vdso_write_begin(vdata);
@@ -167,9 +166,9 @@ unsigned long vdso_update_begin(void)
  */
 void vdso_update_end(unsigned long flags)
 {
-	struct vdso_data *vdata = __arch_get_k_vdso_data();
+	struct vdso_time_data *vdata = vdso_k_time_data;
 
 	vdso_write_end(vdata);
-	__arch_sync_vdso_data(vdata);
+	__arch_sync_vdso_time_data(vdata);
 	timekeeper_unlock_irqrestore(flags);
 }
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index c01eaafd8041916878f3f407f7f4fc3e0a0611ca..c23ced571a9cc1df6966e0519c4458281cd5d448 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -14,12 +14,12 @@
 #endif
 
 #ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
-static __always_inline bool vdso_delta_ok(const struct vdso_data *vd, u64 delta)
+static __always_inline bool vdso_delta_ok(const struct vdso_time_data *vd, u64 delta)
 {
 	return delta < vd->max_cycles;
 }
 #else
-static __always_inline bool vdso_delta_ok(const struct vdso_data *vd, u64 delta)
+static __always_inline bool vdso_delta_ok(const struct vdso_time_data *vd, u64 delta)
 {
 	return true;
 }
@@ -36,7 +36,7 @@ static __always_inline u64 vdso_shift_ns(u64 ns, u32 shift)
  * Default implementation which works for all sane clocksources. That
  * obviously excludes x86/TSC.
  */
-static __always_inline u64 vdso_calc_ns(const struct vdso_data *vd, u64 cycles, u64 base)
+static __always_inline u64 vdso_calc_ns(const struct vdso_time_data *vd, u64 cycles, u64 base)
 {
 	u64 delta = (cycles - vd->cycle_last) & VDSO_DELTA_MASK(vd);
 
@@ -55,7 +55,7 @@ static inline bool __arch_vdso_hres_capable(void)
 #endif
 
 #ifndef vdso_clocksource_ok
-static inline bool vdso_clocksource_ok(const struct vdso_data *vd)
+static inline bool vdso_clocksource_ok(const struct vdso_time_data *vd)
 {
 	return vd->clock_mode != VDSO_CLOCKMODE_NONE;
 }
@@ -69,18 +69,18 @@ static inline bool vdso_cycles_ok(u64 cycles)
 #endif
 
 #ifdef CONFIG_TIME_NS
-static __always_inline int do_hres_timens(const struct vdso_data *vdns, clockid_t clk,
+static __always_inline int do_hres_timens(const struct vdso_time_data *vdns, clockid_t clk,
 					  struct __kernel_timespec *ts)
 {
 	const struct timens_offset *offs = &vdns->offset[clk];
 	const struct vdso_timestamp *vdso_ts;
-	const struct vdso_data *vd;
+	const struct vdso_time_data *vd;
 	u64 cycles, ns;
 	u32 seq;
 	s64 sec;
 
 	vd = vdns - (clk == CLOCK_MONOTONIC_RAW ? CS_RAW : CS_HRES_COARSE);
-	vd = __arch_get_timens_vdso_data(vd);
+	vd = __arch_get_vdso_u_timens_data();
 	if (clk != CLOCK_MONOTONIC_RAW)
 		vd = &vd[CS_HRES_COARSE];
 	else
@@ -115,19 +115,19 @@ static __always_inline int do_hres_timens(const struct vdso_data *vdns, clockid_
 }
 #else
 static __always_inline
-const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
+const struct vdso_time_data *__arch_get_vdso_u_timens_data(void)
 {
 	return NULL;
 }
 
-static __always_inline int do_hres_timens(const struct vdso_data *vdns, clockid_t clk,
+static __always_inline int do_hres_timens(const struct vdso_time_data *vdns, clockid_t clk,
 					  struct __kernel_timespec *ts)
 {
 	return -EINVAL;
 }
 #endif
 
-static __always_inline int do_hres(const struct vdso_data *vd, clockid_t clk,
+static __always_inline int do_hres(const struct vdso_time_data *vd, clockid_t clk,
 				   struct __kernel_timespec *ts)
 {
 	const struct vdso_timestamp *vdso_ts = &vd->basetime[clk];
@@ -179,10 +179,10 @@ static __always_inline int do_hres(const struct vdso_data *vd, clockid_t clk,
 }
 
 #ifdef CONFIG_TIME_NS
-static __always_inline int do_coarse_timens(const struct vdso_data *vdns, clockid_t clk,
+static __always_inline int do_coarse_timens(const struct vdso_time_data *vdns, clockid_t clk,
 					    struct __kernel_timespec *ts)
 {
-	const struct vdso_data *vd = __arch_get_timens_vdso_data(vdns);
+	const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data();
 	const struct vdso_timestamp *vdso_ts = &vd->basetime[clk];
 	const struct timens_offset *offs = &vdns->offset[clk];
 	u64 nsec;
@@ -208,14 +208,14 @@ static __always_inline int do_coarse_timens(const struct vdso_data *vdns, clocki
 	return 0;
 }
 #else
-static __always_inline int do_coarse_timens(const struct vdso_data *vdns, clockid_t clk,
+static __always_inline int do_coarse_timens(const struct vdso_time_data *vdns, clockid_t clk,
 					    struct __kernel_timespec *ts)
 {
 	return -1;
 }
 #endif
 
-static __always_inline int do_coarse(const struct vdso_data *vd, clockid_t clk,
+static __always_inline int do_coarse(const struct vdso_time_data *vd, clockid_t clk,
 				     struct __kernel_timespec *ts)
 {
 	const struct vdso_timestamp *vdso_ts = &vd->basetime[clk];
@@ -242,7 +242,7 @@ static __always_inline int do_coarse(const struct vdso_data *vd, clockid_t clk,
 }
 
 static __always_inline int
-__cvdso_clock_gettime_common(const struct vdso_data *vd, clockid_t clock,
+__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
 			     struct __kernel_timespec *ts)
 {
 	u32 msk;
@@ -269,7 +269,7 @@ __cvdso_clock_gettime_common(const struct vdso_data *vd, clockid_t clock,
 }
 
 static __maybe_unused int
-__cvdso_clock_gettime_data(const struct vdso_data *vd, clockid_t clock,
+__cvdso_clock_gettime_data(const struct vdso_time_data *vd, clockid_t clock,
 			   struct __kernel_timespec *ts)
 {
 	int ret = __cvdso_clock_gettime_common(vd, clock, ts);
@@ -282,12 +282,12 @@ __cvdso_clock_gettime_data(const struct vdso_data *vd, clockid_t clock,
 static __maybe_unused int
 __cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
 {
-	return __cvdso_clock_gettime_data(__arch_get_vdso_data(), clock, ts);
+	return __cvdso_clock_gettime_data(__arch_get_vdso_u_time_data(), clock, ts);
 }
 
 #ifdef BUILD_VDSO32
 static __maybe_unused int
-__cvdso_clock_gettime32_data(const struct vdso_data *vd, clockid_t clock,
+__cvdso_clock_gettime32_data(const struct vdso_time_data *vd, clockid_t clock,
 			     struct old_timespec32 *res)
 {
 	struct __kernel_timespec ts;
@@ -308,12 +308,12 @@ __cvdso_clock_gettime32_data(const struct vdso_data *vd, clockid_t clock,
 static __maybe_unused int
 __cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res)
 {
-	return __cvdso_clock_gettime32_data(__arch_get_vdso_data(), clock, res);
+	return __cvdso_clock_gettime32_data(__arch_get_vdso_u_time_data(), clock, res);
 }
 #endif /* BUILD_VDSO32 */
 
 static __maybe_unused int
-__cvdso_gettimeofday_data(const struct vdso_data *vd,
+__cvdso_gettimeofday_data(const struct vdso_time_data *vd,
 			  struct __kernel_old_timeval *tv, struct timezone *tz)
 {
 
@@ -330,7 +330,7 @@ __cvdso_gettimeofday_data(const struct vdso_data *vd,
 	if (unlikely(tz != NULL)) {
 		if (IS_ENABLED(CONFIG_TIME_NS) &&
 		    vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
-			vd = __arch_get_timens_vdso_data(vd);
+			vd = __arch_get_vdso_u_timens_data();
 
 		tz->tz_minuteswest = vd[CS_HRES_COARSE].tz_minuteswest;
 		tz->tz_dsttime = vd[CS_HRES_COARSE].tz_dsttime;
@@ -342,18 +342,18 @@ __cvdso_gettimeofday_data(const struct vdso_data *vd,
 static __maybe_unused int
 __cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
 {
-	return __cvdso_gettimeofday_data(__arch_get_vdso_data(), tv, tz);
+	return __cvdso_gettimeofday_data(__arch_get_vdso_u_time_data(), tv, tz);
 }
 
 #ifdef VDSO_HAS_TIME
 static __maybe_unused __kernel_old_time_t
-__cvdso_time_data(const struct vdso_data *vd, __kernel_old_time_t *time)
+__cvdso_time_data(const struct vdso_time_data *vd, __kernel_old_time_t *time)
 {
 	__kernel_old_time_t t;
 
 	if (IS_ENABLED(CONFIG_TIME_NS) &&
 	    vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
-		vd = __arch_get_timens_vdso_data(vd);
+		vd = __arch_get_vdso_u_timens_data();
 
 	t = READ_ONCE(vd[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
 
@@ -365,13 +365,13 @@ __cvdso_time_data(const struct vdso_data *vd, __kernel_old_time_t *time)
 
 static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time)
 {
-	return __cvdso_time_data(__arch_get_vdso_data(), time);
+	return __cvdso_time_data(__arch_get_vdso_u_time_data(), time);
 }
 #endif /* VDSO_HAS_TIME */
 
 #ifdef VDSO_HAS_CLOCK_GETRES
 static __maybe_unused
-int __cvdso_clock_getres_common(const struct vdso_data *vd, clockid_t clock,
+int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
 				struct __kernel_timespec *res)
 {
 	u32 msk;
@@ -383,7 +383,7 @@ int __cvdso_clock_getres_common(const struct vdso_data *vd, clockid_t clock,
 
 	if (IS_ENABLED(CONFIG_TIME_NS) &&
 	    vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
-		vd = __arch_get_timens_vdso_data(vd);
+		vd = __arch_get_vdso_u_timens_data();
 
 	/*
 	 * Convert the clockid to a bitmask and use it to check which
@@ -412,7 +412,7 @@ int __cvdso_clock_getres_common(const struct vdso_data *vd, clockid_t clock,
 }
 
 static __maybe_unused
-int __cvdso_clock_getres_data(const struct vdso_data *vd, clockid_t clock,
+int __cvdso_clock_getres_data(const struct vdso_time_data *vd, clockid_t clock,
 			      struct __kernel_timespec *res)
 {
 	int ret = __cvdso_clock_getres_common(vd, clock, res);
@@ -425,12 +425,12 @@ int __cvdso_clock_getres_data(const struct vdso_data *vd, clockid_t clock,
 static __maybe_unused
 int __cvdso_clock_getres(clockid_t clock, struct __kernel_timespec *res)
 {
-	return __cvdso_clock_getres_data(__arch_get_vdso_data(), clock, res);
+	return __cvdso_clock_getres_data(__arch_get_vdso_u_time_data(), clock, res);
 }
 
 #ifdef BUILD_VDSO32
 static __maybe_unused int
-__cvdso_clock_getres_time32_data(const struct vdso_data *vd, clockid_t clock,
+__cvdso_clock_getres_time32_data(const struct vdso_time_data *vd, clockid_t clock,
 				 struct old_timespec32 *res)
 {
 	struct __kernel_timespec ts;
@@ -451,7 +451,7 @@ __cvdso_clock_getres_time32_data(const struct vdso_data *vd, clockid_t clock,
 static __maybe_unused int
 __cvdso_clock_getres_time32(clockid_t clock, struct old_timespec32 *res)
 {
-	return __cvdso_clock_getres_time32_data(__arch_get_vdso_data(),
+	return __cvdso_clock_getres_time32_data(__arch_get_vdso_u_time_data(),
 						clock, res);
 }
 #endif /* BUILD_VDSO32 */
diff --git a/lib/vdso_kernel/datastore.c b/lib/vdso_kernel/datastore.c
index 668cac8c4f80ac71d3f6de71e98e963bc65a1c15..17fbe4fe809fac8e41dcff4aba460187b9b46dac 100644
--- a/lib/vdso_kernel/datastore.c
+++ b/lib/vdso_kernel/datastore.c
@@ -11,7 +11,10 @@
 /*
  * The vDSO data page.
  */
-static union vdso_data_store vdso_time_data_store __page_aligned_data;
+static union {
+	struct vdso_time_data	data[CS_BASES];
+	u8			page[PAGE_SIZE];
+} vdso_time_data_store __page_aligned_data;
 struct vdso_time_data *vdso_k_time_data = vdso_time_data_store.data;
 static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE);
 
@@ -120,8 +123,3 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
 	return 0;
 }
 #endif
-
-struct vdso_time_data *arch_get_vdso_data(void *vvar_page)
-{
-	return (struct vdso_time_data *)vvar_page;
-}

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:11 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:11 +0100
Subject: [PATCH 15/17] vdso: Remove remnants of architecture-specific
 random state storage
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-15-f7aed1bdb3b2@linutronix.de>

All users of the random vDSO are using the generic storage
implementation. Remove the now unnecessary compatibility accessor
functions and symbols.

Co-developed-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Nam Cao <namcao at linutronix.de>
Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 drivers/char/random.c   | 6 +++---
 include/vdso/datapage.h | 8 --------
 lib/vdso/getrandom.c    | 4 ++--
 3 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 23ee76bbb4aa728274bf9980a60b863216d88797..84efda7bede348401db2ed1c443e5ab2bc5dbd2b 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -278,7 +278,7 @@ static void crng_reseed(struct work_struct *work)
 	WRITE_ONCE(base_crng.generation, next_gen);
 #ifdef CONFIG_VDSO_GETRANDOM
 	/* base_crng.generation's invalid value is ULONG_MAX, while
-	 * _vdso_rng_data.generation's invalid value is 0, so add one to the
+	 * vdso_k_rng_data->generation's invalid value is 0, so add one to the
 	 * former to arrive at the latter. Use smp_store_release so that this
 	 * is ordered with the write above to base_crng.generation. Pairs with
 	 * the smp_rmb() before the syscall in the vDSO code.
@@ -290,7 +290,7 @@ static void crng_reseed(struct work_struct *work)
 	 * because the vDSO side only checks whether the value changed, without
 	 * actually using or interpreting the value.
 	 */
-	smp_store_release((unsigned long *)&__arch_get_k_vdso_rng_data()->generation, next_gen + 1);
+	smp_store_release((unsigned long *)&vdso_k_rng_data->generation, next_gen + 1);
 #endif
 	if (!static_branch_likely(&crng_is_ready))
 		crng_init = CRNG_READY;
@@ -743,7 +743,7 @@ static void __cold _credit_init_bits(size_t bits)
 			queue_work(system_unbound_wq, &set_ready);
 		atomic_notifier_call_chain(&random_ready_notifier, 0, NULL);
 #ifdef CONFIG_VDSO_GETRANDOM
-		WRITE_ONCE(__arch_get_k_vdso_rng_data()->is_ready, true);
+		WRITE_ONCE(vdso_k_rng_data->is_ready, true);
 #endif
 		wake_up_interruptible(&crng_init_wait);
 		kill_fasync(&fasync, SIGIO, POLL_IN);
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index b3227f1cf62895aa60ce0ca96afa42259f4771f9..0fc240c08e0f7cf596135eed18dd6f06011917d5 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -152,7 +152,6 @@ struct vdso_rng_data {
 #ifndef CONFIG_GENERIC_VDSO_DATA_STORE
 extern struct vdso_time_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
 extern struct vdso_time_data _timens_data[CS_BASES] __attribute__((visibility("hidden")));
-extern struct vdso_rng_data _vdso_rng_data __attribute__((visibility("hidden")));
 #else
 extern const struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
 extern const struct vdso_time_data vdso_u_timens_data[CS_BASES] __attribute__((visibility("hidden")));
@@ -211,13 +210,6 @@ static __always_inline const struct vdso_rng_data *__arch_get_vdso_u_rng_data(vo
 {
 	return &vdso_u_rng_data;
 }
-#define __arch_get_vdso_rng_data __arch_get_vdso_u_rng_data
-
-static __always_inline struct vdso_rng_data *__arch_get_vdso_k_rng_data(void)
-{
-	return vdso_k_rng_data;
-}
-#define __arch_get_k_vdso_rng_data __arch_get_vdso_k_rng_data
 #endif /* CONFIG_VDSO_GETRANDOM */
 
 #endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c
index 938ca539aaa64bc46280ef6dd17aa661126699eb..2ed019a76abca099de33326ef45101cf50f2f778 100644
--- a/lib/vdso/getrandom.c
+++ b/lib/vdso/getrandom.c
@@ -152,7 +152,7 @@ __cvdso_getrandom_data(const struct vdso_rng_data *rng_info, void *buffer, size_
 
 		/*
 		 * Prevent the syscall from being reordered wrt current_generation. Pairs with the
-		 * smp_store_release(&_vdso_rng_data.generation) in random.c.
+		 * smp_store_release(&vdso_k_rng_data.generation) in random.c.
 		 */
 		smp_rmb();
 
@@ -256,5 +256,5 @@ __cvdso_getrandom_data(const struct vdso_rng_data *rng_info, void *buffer, size_
 static __always_inline ssize_t
 __cvdso_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state, size_t opaque_len)
 {
-	return __cvdso_getrandom_data(__arch_get_vdso_rng_data(), buffer, len, flags, opaque_state, opaque_len);
+	return __cvdso_getrandom_data(__arch_get_vdso_u_rng_data(), buffer, len, flags, opaque_state, opaque_len);
 }

-- 
2.47.1



From thomas.weissschuh at linutronix.de  Mon Dec 16 06:10:13 2024
From: thomas.weissschuh at linutronix.de (=?utf-8?q?Thomas_Wei=C3=9Fschuh?=)
Date: Mon, 16 Dec 2024 15:10:13 +0100
Subject: [PATCH 17/17] vdso: Remove kconfig symbol GENERIC_VDSO_DATA_STORE
In-Reply-To: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241216-vdso-store-rng-v1-17-f7aed1bdb3b2@linutronix.de>

All users of HAVE_GENERIC_VDSO have been switched over to the generic
storage logic. The dedicated kconfig symbol can be removed and replaced
by HAVE_GENERIC_VDSO.

Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
---
 arch/Kconfig             | 2 +-
 arch/arm/mm/Kconfig      | 1 -
 arch/arm64/Kconfig       | 1 -
 arch/loongarch/Kconfig   | 1 -
 arch/mips/Kconfig        | 1 -
 arch/powerpc/Kconfig     | 1 -
 arch/riscv/Kconfig       | 1 -
 arch/s390/Kconfig        | 1 -
 arch/x86/Kconfig         | 1 -
 include/vdso/datapage.h  | 8 +-------
 lib/Kconfig              | 1 -
 lib/vdso_kernel/Kconfig  | 7 -------
 lib/vdso_kernel/Makefile | 2 +-
 13 files changed, 3 insertions(+), 25 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 48f37e6c00674f433a0d6e6e05ce72c27cf000b7..63e20e5e779d5c6d786b90ccb139e16a23445fcb 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1577,7 +1577,7 @@ config HAVE_SPARSE_SYSCALL_NR
 	  related optimizations for a given architecture.
 
 config ARCH_HAS_VDSO_ARCH_DATA
-	depends on GENERIC_VDSO_DATA_STORE
+	depends on HAVE_GENERIC_VDSO
 	bool
 
 config ARCH_HAS_VDSO_TIME_DATA
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 5c1023a6d78c1b4db67b2d62b71af5a79b7e701f..2b6f50dd547840adecbe08e684ed8f1a032cd7c2 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -928,7 +928,6 @@ config VDSO
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_VDSO_32
 	select GENERIC_GETTIMEOFDAY
-	select GENERIC_VDSO_DATA_STORE
 	help
 	  Place in the process address space an ELF shared object
 	  providing fast implementations of gettimeofday and
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1a4a78ec593328d6e6bceacc1abb0821eab988ca..100570a048c5e8892c0112704f9ca74c4fc55b27 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -159,7 +159,6 @@ config ARM64
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_GETTIMEOFDAY
-	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select HARDIRQS_SW_RESEND
 	select HAS_IOPORT
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 6ec7ef705199fdd4039afd23ec9050a28aa894eb..4dffb5ccd46397eedd27870183a105688ab23c5e 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -105,7 +105,6 @@ config LOONGARCH
 	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
-	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select GPIOLIB
 	select HAS_IOPORT
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 94fae59589ae80d590ac250b52ba30e9dd6eda32..467b10f4361aeb7aad0121f334eaa5d23351010c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -49,7 +49,6 @@ config MIPS
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_TIME_VSYSCALL
-	select GENERIC_VDSO_DATA_STORE
 	select GUP_GET_PXX_LOW_HIGH if CPU_MIPS32 && PHYS_ADDR_T_64BIT
 	select HAS_IOPORT if !NO_IOPORT_MAP || ISA
 	select HAVE_ARCH_COMPILER_H
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 600fa3b917ee902d016f2a04376950a9dc49074f..744c09813c43736089e69d06541a7a7d48a4d6da 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -207,7 +207,6 @@ config PPC
 	select GENERIC_PTDUMP
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
-	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select HAS_IOPORT			if PCI
 	select HAVE_ARCH_AUDITSYSCALL
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index a42d74aa53fe7c18e76820499d0ae43cd3b0c0bd..25023e4bc41b2aa02242ed1fe31caa3031a3edd5 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -115,7 +115,6 @@ config RISCV
 	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL if MMU && 64BIT
-	select GENERIC_VDSO_DATA_STORE if HAVE_GENERIC_VDSO
 	select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO
 	select HARDIRQS_SW_RESEND
 	select HAS_IOPORT if MMU
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 6472eb4c210f378eaa61ddff04a6abc2f4aa2940..0077969170e8b4ca4c99e87ec75f6ea94f3e8e00 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -158,7 +158,6 @@ config S390
 	select GENERIC_PTDUMP
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
-	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select GENERIC_IOREMAP if PCI
 	select HAVE_ALIGNED_STRUCT_PAGE
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e3d7f17dc414ca93d6e746dbc7f02afd2bc043a8..9d7bd0ae48c4260f4abb6dbedc696e3915c230ea 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -177,7 +177,6 @@ config X86
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_GETTIMEOFDAY
-	select GENERIC_VDSO_DATA_STORE
 	select GENERIC_VDSO_TIME_NS
 	select GENERIC_VDSO_OVERFLOW_PROTECT
 	select GUP_GET_PXX_LOW_HIGH		if X86_PAE
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index fe2368d9ae6a759101de80b1746f5cc221d7d142..49b23b35df5fc0699ac7f34693b7de1201aa4486 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -29,7 +29,7 @@ struct arch_vdso_time_data {};
 
 #if defined(CONFIG_ARCH_HAS_VDSO_ARCH_DATA)
 #include <asm/vdso/arch_data.h>
-#elif defined(CONFIG_GENERIC_VDSO_DATA_STORE)
+#else
 struct vdso_arch_data {
 	/* Needed for the generic code, never actually used at runtime */
 	char __unused;
@@ -147,7 +147,6 @@ struct vdso_rng_data {
  * With the hidden visibility, the compiler simply generates a PC-relative
  * relocation, and this is what we need.
  */
-#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
 extern const struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
 extern const struct vdso_time_data vdso_u_timens_data[CS_BASES] __attribute__((visibility("hidden")));
 extern const struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden")));
@@ -156,9 +155,6 @@ extern const struct vdso_arch_data vdso_u_arch_data __attribute__((visibility("h
 extern struct vdso_time_data *vdso_k_time_data;
 extern struct vdso_rng_data *vdso_k_rng_data;
 extern struct vdso_arch_data *vdso_k_arch_data;
-#endif
-
-#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
 
 #define VDSO_ARCH_DATA_SIZE ALIGN(sizeof(struct vdso_arch_data), PAGE_SIZE)
 #define VDSO_ARCH_DATA_PAGES (VDSO_ARCH_DATA_SIZE >> PAGE_SHIFT)
@@ -191,8 +187,6 @@ static __always_inline const struct vdso_rng_data *__arch_get_vdso_u_rng_data(vo
 }
 #endif /* CONFIG_VDSO_GETRANDOM */
 
-#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
-
 #ifdef CONFIG_ARCH_HAS_VDSO_ARCH_DATA
 static __always_inline const struct vdso_arch_data *__arch_get_vdso_u_arch_data(void)
 {
diff --git a/lib/Kconfig b/lib/Kconfig
index 7d59b2c10ce5ffab03378ead254d9f9017a4482f..5a318f753b2f44cb0a7905cc0092e81c133bc112 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -659,7 +659,6 @@ config UCS2_STRING
 # generic vdso
 #
 source "lib/vdso/Kconfig"
-source "lib/vdso_kernel/Kconfig"
 
 source "lib/fonts/Kconfig"
 
diff --git a/lib/vdso_kernel/Kconfig b/lib/vdso_kernel/Kconfig
deleted file mode 100644
index 0c7ade9b3ece67c0c0ca892544b9e29e53c860c4..0000000000000000000000000000000000000000
--- a/lib/vdso_kernel/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-config GENERIC_VDSO_DATA_STORE
-	bool
-	depends on HAVE_GENERIC_VDSO
-	help
-	  Selected by architectures that use the generic vDSO data store.
diff --git a/lib/vdso_kernel/Makefile b/lib/vdso_kernel/Makefile
index 4826e49f9edbdb48506b50957584ed89bde5f37f..aadc987caa434ef99c1420c62bb71fde04a07603 100644
--- a/lib/vdso_kernel/Makefile
+++ b/lib/vdso_kernel/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-$(CONFIG_GENERIC_VDSO_DATA_STORE) += datastore.o
+obj-$(CONFIG_HAVE_GENERIC_VDSO) += datastore.o

-- 
2.47.1



From robh at kernel.org  Mon Dec 16 06:18:46 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 16 Dec 2024 08:18:46 -0600
Subject: [PATCH 2/4] dt-bindings: mfd: syscon: allow two reg regions for
 gs101-pmu
In-Reply-To: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-2-c72978f63713@linaro.org>
References: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
 <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-2-c72978f63713@linaro.org>
Message-ID: <20241216141846.GA71151-robh@kernel.org>

On Fri, Dec 13, 2024 at 04:44:39PM +0000, Peter Griffin wrote:
> To avoid dtschema warnings allow google,gs101-pmu to have
> two reg regions.

It's not a "simple" syscon if you have 2 regions, so put it in its own 
schema doc.

> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
> I don't really like this patch, but also didn't want to submit the series
> with a dtschema warning ;-)
> 
> Possibly a better solution is when Robs patch
> `mfd: syscon: Allow syscon nodes without a "syscon" compatible` [1]
> 
> gets updated with a v2, we could remove syscon compatible from
> gs101.dtsi (an ABI issue). If I understood his patch correctly,
> it would mean this yaml update would then no longer be required.

Whether you can tolerate an ABI issue is up to you.

Rob


From maz at kernel.org  Mon Dec 16 06:44:07 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 16 Dec 2024 14:44:07 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to __cpuinfo_store_cpu()
In-Reply-To: <Z2A502_EpqvLYN8g@J2N7QTR9R3.cambridge.arm.com>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
	<87a5cysfci.wl-maz@kernel.org>
	<709a0e75-0d0c-4bff-b9fd-3bbb55c97bd5@sirena.org.uk>
	<Z2Agntn52mY5bSTp@J2N7QTR9R3>
	<855dbb91-db37-4178-bd0b-511994d3aef7@sirena.org.uk>
	<Z2A502_EpqvLYN8g@J2N7QTR9R3.cambridge.arm.com>
Message-ID: <864j33sn60.wl-maz@kernel.org>

On Mon, 16 Dec 2024 14:31:47 +0000,
Mark Rutland <mark.rutland at arm.com> wrote:
> 
> On Mon, Dec 16, 2024 at 01:23:55PM +0000, Mark Brown wrote:
> > On Mon, Dec 16, 2024 at 12:44:14PM +0000, Mark Rutland wrote:
> > 
> > > ... didn't matter either way, and using '&boot_cpu_data' was intended to
> > > make it clear that the features were based on the boot CPU's info, even
> > > if you just grepped for that and didn't see the surrounding context.
> > 
> > Right, that was my best guess as to what was supposed to be going on
> > but it wasn't super clear.  The code could use some more comments.
> > 
> > > I think the real fix here is to move the reading back into
> > > __cpuinfo_store_cpu(), but to have an explicit check that SME has been
> > > disabled on the commandline, with a comment explaining that this is a
> > > bodge for broken FW which traps the SME ID regs.
> > 
> > That should be doable.
> > 
> > There's a few other similar ID registers (eg, we already read GMID_EL1
> > and MPAMIDR_EL1) make me a bit nervous that we might need to generalise
> > it a bit, but we can deal with that if it comes up.  Even for SME the
> > disable was added speculatively, the factors that made this come up for
> > SVE are less likely to be an issue with SME.
> 
> FWIW, I had a quick go (with only the SME case), and I think the shape
> that we want is roughly as below, which I think is easy to generalise to
> those other cases.
> 
> MarcZ, thoughts?
> 
> Mark.
> 
> ---->8----
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 8b4e5a3cd24c8..f16eb99c10723 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -91,6 +91,16 @@ struct arm64_ftr_override {
>  	u64		mask;
>  };
>  
> +static inline u64
> +arm64_ftr_override_apply(const struct arm64_ftr_override *override,
> +			 u64 val)
> +{
> +	val &= ~override->mask;
> +	val |= override->val & override->mask;
> +
> +	return val;
> +}
> +
>  /*
>   * @arm64_ftr_reg - Feature register
>   * @strict_mask		Bits which should match across all CPUs for sanity.
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 6ce71f444ed84..faad7d3e4cf5f 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1167,12 +1167,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
>  	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
>  		unsigned long cpacr = cpacr_save_enable_kernel_sme();
>  
> -		/*
> -		 * We mask out SMPS since even if the hardware
> -		 * supports priorities the kernel does not at present
> -		 * and we block access to them.
> -		 */
> -		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
>  		vec_init_vq_map(ARM64_VEC_SME);
>  
>  		cpacr_restore(cpacr);
> @@ -1550,10 +1544,8 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
>  	}
>  
>  	regp  = get_arm64_ftr_reg(sys_id);
> -	if (regp) {
> -		val &= ~regp->override->mask;
> -		val |= (regp->override->val & regp->override->mask);
> -	}
> +	if (regp)
> +		val = arm64_ftr_override_apply(regp->override, val);
>  
>  	return val;
>  }
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index d79e88fccdfce..1460e3541132f 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -439,6 +439,24 @@ static void __cpuinfo_store_cpu_32bit(struct cpuinfo_32bit *info)
>  	info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
>  }
>  
> +static void __cpuinfo_store_cpu_sme(struct cpuinfo_arm64 *info)
> +{
> +	/*
> +	 * TODO: explain that this bodge is to avoid trapping.
> +	 */
> +	u64 pfr1 = info->reg_id_aa64pfr1;
> +	pfr1 = arm64_ftr_override_apply(&id_aa64pfr1_override, pfr1);
> +	if (!id_aa64pfr1_sme(pfr1))
> +		return;

I don't think blindly applying the override at this stage is a good
thing. Specially not the whole register, and definitely not
non-disabling values.

It needs to be done on a per feature basis, and only to disable
things.

See the hack I posted for the things I think need checking.

	M.

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


From laurentiumihalcea111 at gmail.com  Mon Dec 16 06:50:38 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Mon, 16 Dec 2024 09:50:38 -0500
Subject: [PATCH v3 4/5] ASoC: SOF: imx: add driver for imx95
In-Reply-To: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
Message-ID: <20241216145039.3074-5-laurentiumihalcea111@gmail.com>

From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>

Add SOF driver for imx95.

Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
---
 sound/soc/sof/imx/Kconfig  |   8 +
 sound/soc/sof/imx/Makefile |   2 +
 sound/soc/sof/imx/imx95.c  | 401 +++++++++++++++++++++++++++++++++++++
 3 files changed, 411 insertions(+)
 create mode 100644 sound/soc/sof/imx/imx95.c

diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig
index 4751b04d5e6f..51a70a193533 100644
--- a/sound/soc/sof/imx/Kconfig
+++ b/sound/soc/sof/imx/Kconfig
@@ -50,4 +50,12 @@ config SND_SOC_SOF_IMX8ULP
 	  Say Y if you have such a device.
 	  If unsure select "N".
 
+config SND_SOC_SOF_IMX95
+	tristate "SOF support for i.MX95"
+	depends on IMX_DSP
+	help
+	  This adds support for Sound Open Firmware for NXP i.MX95 platforms.
+	  Say Y if you have such a device.
+	  If unsure select "N".
+
 endif ## SND_SOC_SOF_IMX_TOPLEVEL
diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile
index be0bf0736dfa..715ac3798668 100644
--- a/sound/soc/sof/imx/Makefile
+++ b/sound/soc/sof/imx/Makefile
@@ -2,10 +2,12 @@
 snd-sof-imx8-y := imx8.o
 snd-sof-imx8m-y := imx8m.o
 snd-sof-imx8ulp-y := imx8ulp.o
+snd-sof-imx95-y := imx95.o
 
 snd-sof-imx-common-y := imx-common.o
 
 obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o
 obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o
 obj-$(CONFIG_SND_SOC_SOF_IMX8ULP) += snd-sof-imx8ulp.o
+obj-$(CONFIG_SND_SOC_SOF_IMX95) += snd-sof-imx95.o
 obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o
diff --git a/sound/soc/sof/imx/imx95.c b/sound/soc/sof/imx/imx95.c
new file mode 100644
index 000000000000..5a0e44f5bd48
--- /dev/null
+++ b/sound/soc/sof/imx/imx95.c
@@ -0,0 +1,401 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/firmware/imx/dsp.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
+#include <sound/sof.h>
+
+#include "../sof-of-dev.h"
+#include "../ops.h"
+
+#define IMX_SIP_SRC 0xC2000005
+#define IMX_SIP_SRC_M_RESET_ADDR_SET 0x03
+
+#define IMX95_CPU_VEC_FLAGS_BOOT BIT(29)
+
+#define IMX_SIP_LMM 0xC200000F
+#define IMX_SIP_LMM_BOOT 0x0
+#define IMX_SIP_LMM_SHUTDOWN 0x1
+
+#define IMX95_M7_LM_ID 0x1
+
+#define MBOX_DSPBOX_OFFSET 0x1000
+#define MBOX_WINDOW_OFFSET 0x6000000
+
+struct imx95_priv {
+	struct platform_device *ipc_dev;
+	struct imx_dsp_ipc *ipc_handle;
+	resource_size_t bootaddr;
+};
+
+static void imx95_ipc_handle_reply(struct imx_dsp_ipc *ipc)
+{
+	unsigned long flags;
+	struct snd_sof_dev *sdev = imx_dsp_get_data(ipc);
+
+	spin_lock_irqsave(&sdev->ipc_lock, flags);
+	snd_sof_ipc_process_reply(sdev, 0);
+	spin_unlock_irqrestore(&sdev->ipc_lock, flags);
+}
+
+static void imx95_ipc_handle_request(struct imx_dsp_ipc *ipc)
+{
+	snd_sof_ipc_msgs_rx(imx_dsp_get_data(ipc));
+}
+
+static struct imx_dsp_ops ipc_ops = {
+	.handle_reply = imx95_ipc_handle_reply,
+	.handle_request = imx95_ipc_handle_request,
+};
+
+static int imx95_disable_enable_core(bool enable)
+{
+	struct arm_smccc_res res;
+
+	if (enable)
+		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_BOOT, IMX95_M7_LM_ID,
+			      0, 0, 0, 0, 0, &res);
+	else
+		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_SHUTDOWN, IMX95_M7_LM_ID,
+			      0, 0, 0, 0, 0, &res);
+
+	return res.a0;
+}
+
+static int imx95_run(struct snd_sof_dev *sdev)
+{
+	return imx95_disable_enable_core(true);
+}
+
+static int imx95_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
+{
+	struct imx95_priv *priv = sdev->pdata->hw_pdata;
+
+	sof_mailbox_write(sdev, sdev->host_box.offset,
+			  msg->msg_data, msg->msg_size);
+
+	imx_dsp_ring_doorbell(priv->ipc_handle, 0);
+
+	return 0;
+}
+
+static int imx95_get_mailbox_offset(struct snd_sof_dev *sdev)
+{
+	return MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
+}
+
+static int imx95_get_bar_index(struct snd_sof_dev *sdev, u32 type)
+{
+	switch (type) {
+	case SOF_FW_BLK_TYPE_SRAM:
+		return type;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int imx95_get_window_offset(struct snd_sof_dev *sdev, u32 id)
+{
+	return MBOX_WINDOW_OFFSET;
+}
+
+static int imx95_set_power_state(struct snd_sof_dev *sdev,
+				 const struct sof_dsp_power_state *target_state)
+{
+	sdev->dsp_power_state = *target_state;
+
+	return 0;
+}
+
+static int imx95_suspend_resume(struct snd_sof_dev *sdev, bool suspend)
+{
+	struct imx95_priv *priv;
+	int ret, i;
+
+	priv = sdev->pdata->hw_pdata;
+
+	if (suspend) {
+		ret = imx95_disable_enable_core(false);
+		if (ret) {
+			dev_err(sdev->dev, "failed to stop core\n");
+			return ret;
+		}
+	}
+
+	for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
+		if (suspend)
+			imx_dsp_free_channel(priv->ipc_handle, i);
+		else
+			imx_dsp_request_channel(priv->ipc_handle, i);
+	}
+
+	return 0;
+}
+
+static int imx95_runtime_resume(struct snd_sof_dev *sdev)
+{
+	int ret;
+	const struct sof_dsp_power_state target_state = {
+		.state = SOF_DSP_PM_D0,
+	};
+
+	ret = imx95_suspend_resume(sdev, false);
+	if (ret < 0) {
+		dev_err(sdev->dev, "failed to runtime resume: %d\n", ret);
+		return ret;
+	}
+
+	return snd_sof_dsp_set_power_state(sdev, &target_state);
+}
+
+static int imx95_resume(struct snd_sof_dev *sdev)
+{
+	int ret;
+	const struct sof_dsp_power_state target_state = {
+		.state = SOF_DSP_PM_D0,
+	};
+
+	ret = imx95_suspend_resume(sdev, false);
+	if (ret < 0) {
+		dev_err(sdev->dev, "failed to resume: %d\n", ret);
+		return ret;
+	}
+
+	if (pm_runtime_suspended(sdev->dev)) {
+		pm_runtime_disable(sdev->dev);
+		pm_runtime_set_active(sdev->dev);
+		pm_runtime_mark_last_busy(sdev->dev);
+		pm_runtime_enable(sdev->dev);
+		pm_runtime_idle(sdev->dev);
+	}
+
+	return snd_sof_dsp_set_power_state(sdev, &target_state);
+}
+
+static int imx95_runtime_suspend(struct snd_sof_dev *sdev)
+{
+	int ret;
+	const struct sof_dsp_power_state target_state = {
+		.state = SOF_DSP_PM_D3,
+	};
+
+	ret = imx95_suspend_resume(sdev, true);
+	if (ret < 0) {
+		dev_err(sdev->dev, "failed to runtime suspend: %d\n", ret);
+		return ret;
+	}
+
+	return snd_sof_dsp_set_power_state(sdev, &target_state);
+}
+
+static int imx95_suspend(struct snd_sof_dev *sdev, unsigned int target_state)
+{
+	int ret;
+	const struct sof_dsp_power_state target_power_state = {
+		.state = target_state,
+	};
+
+	if (!pm_runtime_suspended(sdev->dev)) {
+		ret = imx95_suspend_resume(sdev, true);
+		if (ret < 0) {
+			dev_err(sdev->dev, "failed to suspend: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return snd_sof_dsp_set_power_state(sdev, &target_power_state);
+}
+
+static struct snd_soc_dai_driver imx95_dai[] = {
+	{
+		.name = "sai3",
+		.playback = {
+			.channels_min = 1,
+			.channels_max = 32,
+		},
+		.capture = {
+			.channels_min = 1,
+			.channels_max = 32,
+		},
+	},
+};
+
+static int imx95_probe(struct snd_sof_dev *sdev)
+{
+	struct platform_device *pdev;
+	struct imx95_priv *priv;
+	struct resource *res;
+	struct arm_smccc_res smc_ret;
+	int ret;
+
+	pdev = container_of(sdev->dev, struct platform_device, dev);
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return dev_err_probe(&pdev->dev, -ENOMEM, "failed to alloc priv\n");
+
+	sdev->pdata->hw_pdata = priv;
+
+	/* map SRAM */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return dev_err_probe(&pdev->dev, -ENODEV,
+				     "failed to fetch SRAM region\n");
+
+	sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap(&pdev->dev, res->start,
+						       resource_size(res));
+	if (IS_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]))
+		return dev_err_probe(&pdev->dev,
+				     PTR_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]),
+				     "failed to map SRAM region\n");
+
+	sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
+	sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
+	sdev->dsp_box.offset = MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
+	priv->bootaddr = res->start;
+
+	ret = of_reserved_mem_device_init(sdev->dev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to bind DMA region\n");
+
+	priv->ipc_dev = platform_device_register_data(&pdev->dev, "imx-dsp",
+						      PLATFORM_DEVID_NONE,
+						      pdev, sizeof(*pdev));
+	if (IS_ERR(priv->ipc_dev))
+		return dev_err_probe(&pdev->dev, PTR_ERR(priv->ipc_dev),
+				     "failed to create IPC device\n");
+
+	priv->ipc_handle = dev_get_drvdata(&priv->ipc_dev->dev);
+	if (!priv->ipc_handle) {
+		ret = -EPROBE_DEFER;
+		dev_err(&pdev->dev, "failed to fetch ipc handle\n");
+		goto err_unregister_ipc_dev;
+	}
+
+	priv->ipc_handle->ops = &ipc_ops;
+	imx_dsp_set_data(priv->ipc_handle, sdev);
+
+	/* set core boot reset address */
+	arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M_RESET_ADDR_SET, priv->bootaddr,
+		      IMX95_CPU_VEC_FLAGS_BOOT, 0, 0, 0, 0, &smc_ret);
+	if ((int)smc_ret.a0 < 0) {
+		ret = smc_ret.a0;
+		dev_err(&pdev->dev, "failed to set boot address: %d", ret);
+		goto err_unregister_ipc_dev;
+	}
+
+	return 0;
+
+err_unregister_ipc_dev:
+	platform_device_unregister(priv->ipc_dev);
+
+	return ret;
+}
+
+static void imx95_remove(struct snd_sof_dev *sdev)
+{
+	struct imx95_priv *priv;
+
+	priv = sdev->pdata->hw_pdata;
+
+	if (imx95_disable_enable_core(false))
+		dev_err(sdev->dev, "failed to stop core\n");
+
+	platform_device_unregister(priv->ipc_dev);
+}
+
+static const struct snd_sof_dsp_ops sof_imx95_ops = {
+	.probe = imx95_probe,
+	.remove = imx95_remove,
+
+	/* mandatory "DSP" ops */
+	.run = imx95_run,
+	.block_read = sof_block_read,
+	.block_write = sof_block_write,
+	.send_msg = imx95_send_msg,
+	.load_firmware = snd_sof_load_firmware_memcpy,
+	.ipc_msg_data = sof_ipc_msg_data,
+
+	.mailbox_read = sof_mailbox_read,
+	.mailbox_write = sof_mailbox_write,
+
+	.get_mailbox_offset = imx95_get_mailbox_offset,
+	.get_bar_index = imx95_get_bar_index,
+	.get_window_offset = imx95_get_window_offset,
+
+	.pcm_open = sof_stream_pcm_open,
+	.pcm_close = sof_stream_pcm_close,
+	.set_stream_data_offset = sof_set_stream_data_offset,
+
+	.runtime_suspend = imx95_runtime_suspend,
+	.runtime_resume = imx95_runtime_resume,
+
+	.resume = imx95_resume,
+	.suspend = imx95_suspend,
+
+	.set_power_state = imx95_set_power_state,
+
+	.drv = imx95_dai,
+	.num_drv = ARRAY_SIZE(imx95_dai),
+
+	.hw_info = SNDRV_PCM_INFO_MMAP |
+		   SNDRV_PCM_INFO_MMAP_VALID |
+		   SNDRV_PCM_INFO_INTERLEAVED |
+		   SNDRV_PCM_INFO_PAUSE |
+		   SNDRV_PCM_INFO_BATCH |
+		   SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
+};
+
+static struct snd_sof_of_mach sof_imx95_machs[] = {
+	{
+		.compatible = "fsl,imx95-19x19-evk",
+		.sof_tplg_filename = "sof-imx95-wm8962.tplg",
+		.drv_name = "asoc-audio-graph-card2",
+	},
+	{
+	},
+};
+
+static struct sof_dev_desc sof_of_imx95_desc = {
+	.of_machines = sof_imx95_machs,
+	.ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+	.ipc_default = SOF_IPC_TYPE_3,
+	.default_fw_path = {
+		[SOF_IPC_TYPE_3] = "imx/sof",
+	},
+	.default_tplg_path = {
+		[SOF_IPC_TYPE_3] = "imx/sof-tplg",
+	},
+	.default_fw_filename = {
+		[SOF_IPC_TYPE_3] = "sof-imx95.ri",
+	},
+	.ops = &sof_imx95_ops,
+};
+
+static const struct of_device_id sof_of_imx95_ids[] = {
+	{ .compatible = "fsl,imx95-cm7-sof", .data = &sof_of_imx95_desc },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, sof_of_imx95_ids);
+
+static struct platform_driver snd_sof_of_imx95_driver = {
+	.probe = sof_of_probe,
+	.remove = sof_of_remove,
+	.driver = {
+		.name = "sof-audio-of-imx95",
+		.pm = &sof_of_pm,
+		.of_match_table = sof_of_imx95_ids,
+	},
+};
+module_platform_driver(snd_sof_of_imx95_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("SOF support for i.MX95 platforms");
+MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>");
-- 
2.34.1



From laurentiumihalcea111 at gmail.com  Mon Dec 16 06:50:39 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Mon, 16 Dec 2024 09:50:39 -0500
Subject: [PATCH v3 5/5] arm64: dts: imx: add imx95 dts for sof
In-Reply-To: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
Message-ID: <20241216145039.3074-6-laurentiumihalcea111@gmail.com>

From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>

Add imx95 DTS for SOF usage.

Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |  1 +
 .../dts/freescale/imx95-19x19-evk-sof.dts     | 75 +++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 839432153cc7..27f64e333e4b 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -282,6 +282,7 @@ 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
+dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk-sof.dtb
 
 imx8mm-kontron-dl-dtbs			:= imx8mm-kontron-bl.dtb imx8mm-kontron-dl.dtbo
 
diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts
new file mode 100644
index 000000000000..8eef83d7bdd7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+/dts-v1/;
+
+#include "imx95-19x19-evk.dts"
+
+/ {
+	sof_cpu: cm7-cpu at 80000000 {
+		compatible = "fsl,imx95-cm7-sof";
+		reg = <0x0 0x80000000 0x0 0x6100000>;
+		memory-region = <&adma_res>;
+		mboxes = <&mu7 2 0>, <&mu7 2 1>, <&mu7 3 0>, <&mu7 3 1>;
+		mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";
+		cpu: port {
+			cpu_ep: endpoint { remote-endpoint = <&codec_ep>; };
+		};
+	};
+
+	reserved-memory {
+		adma_res: memory at 86100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x0 0x86100000 0x0 0x100000>;
+			no-map;
+		};
+	};
+
+	sof-sound-wm8962 {
+		compatible = "audio-graph-card2";
+		links = <&cpu>;
+		label = "wm8962-audio";
+		hp-det-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_hp>;
+		widgets =
+			"Headphone", "Headphones",
+			"Microphone", "Headset Mic";
+		routing =
+			"Headphones", "HPOUTL",
+			"Headphones", "HPOUTR",
+			"Headset Mic", "MICBIAS",
+			"IN3R", "Headset Mic",
+			"IN1R", "Headset Mic";
+	};
+
+	sound-wm8962 {
+		status = "disabled";
+	};
+
+};
+
+&edma2 {
+	dma-channel-mask = <0xc0000000>, <0x0>;
+};
+
+&sai3 {
+	status = "disabled";
+};
+
+&wm8962 {
+	assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>,
+			  <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>,
+			  <&scmi_clk IMX95_CLK_AUDIOPLL1>,
+			  <&scmi_clk IMX95_CLK_AUDIOPLL2>,
+			  <&scmi_clk IMX95_CLK_SAI3>;
+	assigned-clock-parents = <0>, <0>, <0>, <0>, <&scmi_clk IMX95_CLK_AUDIOPLL1>;
+	assigned-clock-rates = <3932160000>, <3612672000>,
+			       <393216000>, <361267200>,
+			       <12288000>;
+	port {
+		codec_ep: endpoint { remote-endpoint = <&cpu_ep>; };
+	};
+};
-- 
2.34.1



From harry.wentland at amd.com  Mon Dec 16 06:53:45 2024
From: harry.wentland at amd.com (Harry Wentland)
Date: Mon, 16 Dec 2024 09:53:45 -0500
Subject: [PATCH v2 04/10] drm/amd/display: use eld_mutex to protect access
 to connector->eld
In-Reply-To: <pgi7p3aemxm3db2k27vi5euh6q6ppayrw6y7tcfeq4g5z23hzr@xousag2qhobp>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
 <20241206-drm-connector-eld-mutex-v2-4-c9bce1ee8bea@linaro.org>
 <pgi7p3aemxm3db2k27vi5euh6q6ppayrw6y7tcfeq4g5z23hzr@xousag2qhobp>
Message-ID: <fc8e80dd-bcea-4515-b446-158649719569@amd.com>



On 2024-12-10 16:20, Dmitry Baryshkov wrote:
> On Fri, Dec 06, 2024 at 11:43:07AM +0200, Dmitry Baryshkov wrote:
>> Reading access to connector->eld can happen at the same time the
>> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
>> order to protect connector->eld from concurrent access.
>>
>> Reviewed-by: Maxime Ripard <mripard at kernel.org>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>> ---
>>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
>>  1 file changed, 2 insertions(+)
> 
> Harry, Leo, Rodrigo, Alex, Christian, Xinhui, any response to this one
> and to the radeon patches? I'd like to be able to pick the series for
> drm-misc and these two are not reviewed by you.
> 
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index 19a58630e774029767bf2a27eb4ddf17e3c21129..04c68c320252b5ce9647f0606fb86fe57f347639 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -1037,8 +1037,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port,
>>  			continue;
>>  
>>  		*enabled = true;
>> +		mutex_lock(&connector->eld_mutex);
>>  		ret = drm_eld_size(connector->eld);
>>  		memcpy(buf, connector->eld, min(max_bytes, ret));
>> +		mutex_unlock(&connector->eld_mutex);

All of this is wrapped by the adev->dm.audio_lock mutex. It might
be safer to modify the audio_lock mutex so it only guards the
aconnector->audio_inst access.

But I don't see any way these mutexes would otherwise interact,
so this change should be good as-is.

Reviewed-by: Harry Wentland <harry.wentland at amd.com>

Harry

>>  
>>  		break;
>>  	}
>>
>> -- 
>> 2.39.5
>>
> 



From ben.wolsieffer at hefring.com  Mon Dec 16 06:53:23 2024
From: ben.wolsieffer at hefring.com (Ben Wolsieffer)
Date: Mon, 16 Dec 2024 09:53:23 -0500
Subject: [PATCH] serial: stm32: use port lock wrappers for break control
Message-ID: <20241216145323.111612-1-ben.wolsieffer@hefring.com>

Commit 30e945861f3b ("serial: stm32: add support for break control")
added another usage of the port lock, but was merged on the same day as
c5d06662551c ("serial: stm32: Use port lock wrappers"), therefore the
latter did not update this usage to use the port lock wrappers.

Fixes: c5d06662551c ("serial: stm32: Use port lock wrappers")
Signed-off-by: Ben Wolsieffer <ben.wolsieffer at hefring.com>
---
 drivers/tty/serial/stm32-usart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 7dc254546075..1ec5d8c3aef8 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -1051,14 +1051,14 @@ static void stm32_usart_break_ctl(struct uart_port *port, int break_state)
 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
 	unsigned long flags;
 
-	spin_lock_irqsave(&port->lock, flags);
+	uart_port_lock_irqsave(port, &flags);
 
 	if (break_state)
 		stm32_usart_set_bits(port, ofs->rqr, USART_RQR_SBKRQ);
 	else
 		stm32_usart_clr_bits(port, ofs->rqr, USART_RQR_SBKRQ);
 
-	spin_unlock_irqrestore(&port->lock, flags);
+	uart_port_unlock_irqrestore(port, flags);
 }
 
 static int stm32_usart_startup(struct uart_port *port)
-- 
2.46.1



From laurentiumihalcea111 at gmail.com  Mon Dec 16 06:50:34 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Mon, 16 Dec 2024 09:50:34 -0500
Subject: [PATCH v3 0/5] add sof support on imx95
Message-ID: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>

From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>

Add sof support on imx95. This series also includes some changes to
the audio-graph-card2 binding required for the support.

---
Changes in v3:
- Ordered DT nodes alphabetically
- Removed 'cpu' and 'cpu_ep' labels from binding example
- Some small changes to the binding commit messages/titles.
- Link to v2: https://lore.kernel.org/lkml/20241113195240.3699-1-laurentiumihalcea111 at gmail.com/

Changes in v2:
- Added new binding for 95's CM7 core with SOF. fsl,dsp.yaml is no longer used.
- "hp-det-gpios" and "widgets" properties now reference the definitions from audio-graph.yaml
- Removed extra empty spaces from DTS as suggested by Frank
- Ordered 'edma2', 'sai3', 'wm8962' DT nodes alphabetically. The order of the nodes
placed inside / is kept the same for readability
- Ordered driver header files includes alphabetically as suggested by Frank
- Removed "reg-names" and changed the maximum size of the "reg" property to 1 to align
with the other NXP CPUs sharing the same programming model (i.e: audio processing with SOF).
The region described in the DTS is the SRAM and the mailbox region is now hardcoded in the
driver as an offset to the start of the SRAM region.
- Added new binding with properties required by all NXP CPUs sharing the same programming
model (i.e: audio processing with SOF).
- Various driver adjustments made to accomodate the DT changes + some bug fixing related
to the mboxes not being requested/free'd on resume/suspend.
- Fixed value passed to "dma-channel-mask". A set bit means the channel is masked, not the
other way around.
- Link to v1: https://lore.kernel.org/lkml/20241023162114.3354-1-laurentiumihalcea111 at gmail.com/
---

Laurentiu Mihalcea (5):
  ASoC: dt-bindings: add common binding for NXP audio processors
  ASoC: dt-bindings: support imx95's CM7 core
  ASoC: dt-bindings: audio-graph-card2: add widgets and hp-det-gpios
    support
  ASoC: SOF: imx: add driver for imx95
  arm64: dts: imx: add imx95 dts for sof

 .../bindings/sound/audio-graph-card2.yaml     |   4 +
 .../bindings/sound/fsl,imx95-cm7-sof.yaml     |  44 ++
 .../bindings/sound/fsl,sof-cpu.yaml           |  35 ++
 arch/arm64/boot/dts/freescale/Makefile        |   1 +
 .../dts/freescale/imx95-19x19-evk-sof.dts     |  75 ++++
 sound/soc/sof/imx/Kconfig                     |   8 +
 sound/soc/sof/imx/Makefile                    |   2 +
 sound/soc/sof/imx/imx95.c                     | 401 ++++++++++++++++++
 8 files changed, 570 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml
 create mode 100644 arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts
 create mode 100644 sound/soc/sof/imx/imx95.c

-- 
2.34.1



From laurentiumihalcea111 at gmail.com  Mon Dec 16 06:50:35 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Mon, 16 Dec 2024 09:50:35 -0500
Subject: [PATCH v3 1/5] ASoC: dt-bindings: add common binding for NXP audio processors
In-Reply-To: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
Message-ID: <20241216145039.3074-2-laurentiumihalcea111@gmail.com>

From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>

Add common binding for NXP audio processors with Sound Open Firmware
(SOF) support.

Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
---
 .../bindings/sound/fsl,sof-cpu.yaml           | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml b/Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml
new file mode 100644
index 000000000000..1958afceba75
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,sof-cpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP audio processor common properties
+
+maintainers:
+  - Daniel Baluta <daniel.baluta at nxp.com>
+
+properties:
+  reg:
+    maxItems: 1
+
+  mboxes:
+    maxItems: 4
+
+  mbox-names:
+    items:
+      - const: txdb0
+      - const: txdb1
+      - const: rxdb0
+      - const: rxdb1
+
+  memory-region:
+    maxItems: 1
+
+required:
+  - reg
+  - mboxes
+  - mbox-names
+  - memory-region
+
+additionalProperties: true
-- 
2.34.1



From laurentiumihalcea111 at gmail.com  Mon Dec 16 06:50:36 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Mon, 16 Dec 2024 09:50:36 -0500
Subject: [PATCH v3 2/5] ASoC: dt-bindings: support imx95's CM7 core
In-Reply-To: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
Message-ID: <20241216145039.3074-3-laurentiumihalcea111@gmail.com>

From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>

Add binding for imx95's CM7 core, used for audio processing.

Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
---
 .../bindings/sound/fsl,imx95-cm7-sof.yaml     | 44 +++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml b/Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml
new file mode 100644
index 000000000000..cc1eb358f288
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,imx95-cm7-sof.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP imx95 CM7 core
+
+maintainers:
+  - Daniel Baluta <daniel.baluta at nxp.com>
+
+description: NXP imx95 CM7 core used for audio processing
+
+allOf:
+  - $ref: fsl,sof-cpu.yaml#
+
+properties:
+  compatible:
+    const: fsl,imx95-cm7-sof
+
+  port:
+    description: SAI3 port
+    $ref: audio-graph-port.yaml#
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - port
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    cm7-cpu at 80000000 {
+        compatible = "fsl,imx95-cm7-sof";
+        reg = <0x80000000 0x6100000>;
+        mboxes = <&mu7 2 0>, <&mu7 2 1>, <&mu7 3 0>, <&mu7 3 1>;
+        mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";
+        memory-region = <&adma_res>;
+        port {
+          /* SAI3-WM8962 link */
+          endpoint { remote-endpoint = <&wm8962_ep>; };
+        };
+    };
-- 
2.34.1



From laurentiumihalcea111 at gmail.com  Mon Dec 16 06:50:37 2024
From: laurentiumihalcea111 at gmail.com (Laurentiu Mihalcea)
Date: Mon, 16 Dec 2024 09:50:37 -0500
Subject: [PATCH v3 3/5] ASoC: dt-bindings: audio-graph-card2: add widgets and hp-det-gpios support
In-Reply-To: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
Message-ID: <20241216145039.3074-4-laurentiumihalcea111@gmail.com>

From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>

Introduce the 'widgets' property, allowing the creation of widgets from
4 template widgets: Microphone, Line, Headphone, and Speaker. Also
introduce the 'hp-det-gpios' property, which allows using headphone
detection using the specified GPIO.

Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
---
 .../devicetree/bindings/sound/audio-graph-card2.yaml          | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml
index f943f90d8b15..94588353f852 100644
--- a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml
+++ b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml
@@ -37,6 +37,10 @@ properties:
   codec2codec:
     type: object
     description: Codec to Codec node
+  hp-det-gpios:
+    $ref: audio-graph.yaml#/properties/hp-det-gpios
+  widgets:
+    $ref: audio-graph.yaml#/properties/widgets
 
 required:
   - compatible
-- 
2.34.1



From sashal at kernel.org  Mon Dec 16 06:59:12 2024
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 16 Dec 2024 09:59:12 -0500
Subject: [GIT PULL] arm64 fixes for 6.13-rc3
In-Reply-To: <Z1_6ukG_Lc5leG1o@J2N7QTR9R3>
References: <Z1xx0ha7lbKkdhRC@arm.com>
 <Z18MixiGByAqDYLC@lappy>
 <Z1_6ukG_Lc5leG1o@J2N7QTR9R3>
Message-ID: <Z2BAQEuXJg01qWDp@lappy>

On Mon, Dec 16, 2024 at 10:02:34AM +0000, Mark Rutland wrote:
>On Sun, Dec 15, 2024 at 12:06:19PM -0500, Sasha Levin wrote:
>> On Fri, Dec 13, 2024 at 05:41:38PM +0000, Catalin Marinas wrote:
>> > - arm64 stacktrace: address some fallout from the recent changes to
>> >  unwinding across exception boundaries
>>
>> Hi Catalin, Mark,
>>
>> It seems that kselftests can hit a warning that was addressed in the
>> commit above:
>
>I assume you're referring to commit:
>
>  32ed1205682ec42a ("arm64: stacktrace: Skip reporting LR at exception boundaries")
>
>... ?

I was actually thinking 65ac33bed8b9 ("arm64: stacktrace: Don't WARN
when unwinding other tasks"), sorry for the confusion

>That was intended to fix this specific issue, as explained in the commit
>message (with a very similar splat from running the ftrace kselftests).
>
>Am I missing something? i.e. are you saying it *doesn't* fix that?

Right - LKFT is able to trigger the warning I copied on Linus's tree.

-- 
Thanks,
Sasha


From dan.carpenter at linaro.org  Mon Dec 16 07:03:36 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Mon, 16 Dec 2024 18:03:36 +0300
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless
 scmi_bus_id.
In-Reply-To: <CAEEwsfRhe4-YAwe027huSXwFfkV-O-8w1GDNf=URa9efRsXiKA@mail.gmail.com>
References: <20241216073745.2973317-1-guomin_chen@sina.com>
 <Z1_p0nU93PHJ4Sg_@pluto>
 <Z1_2rxJ7TOEIOMp7@pluto>
 <CAEEwsfRhe4-YAwe027huSXwFfkV-O-8w1GDNf=URa9efRsXiKA@mail.gmail.com>
Message-ID: <c3803026-8286-431a-9042-62cf46ede408@stanley.mountain>

On Mon, Dec 16, 2024 at 06:37:01PM +0800, gchen chen wrote:
> > > > diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> > > > index 1b5fb2c4ce86..bbf1f05f2be3 100644
> > > > --- a/drivers/firmware/arm_scmi/driver.c
> > > > +++ b/drivers/firmware/arm_scmi/driver.c
> > > > @@ -2641,8 +2641,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
> > > >     cinfo->max_msg_size = info->desc->max_msg_size;
> > > >
> > > >     /* Create a unique name for this transport device */
> > > > -   snprintf(name, 32, "__scmi_transport_device_%s_%02X",
> > > > -            idx ? "rx" : "tx", prot_id);
> > > > +   snprintf(name, 32, "__scmi_transport_device_%s",
> > > > +            idx ? "rx" : "tx");
> >
> > I agree on what Dan said AND also this results in having the same name for different
> > devices across 2 instances if you have a per-protocol channel because you havent anymore
> > the protocol_id bit.
> hi  Cristian?and dan
>     Because I used a 3-tuple [parent name, name, protocol] when
> creating the SCMI device name, I removed the prot_id from the
> parameter ?name? when creating transport devices. This way, it avoids
> the repetition of protocol ID in the SCMI device name.
> 

I haven't actually tested this code, I'm just going by reviewing.

scmi_channels_setup() calls scmi_txrx_setup() in a loop with a different
port_id each time.  The info->dev is the same on each iteration.  Since
the name is the same except for the rx/tx then __scmi_device_create() will
find the existing device on the first line and return success instead of
allocating a new device:

	scmi_dev = scmi_child_dev_find(parent, protocol, name);
	if (scmi_dev)
		return scmi_dev;

regards,
dan carpenter


From broonie at kernel.org  Mon Dec 16 07:05:44 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 15:05:44 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <865xnjsnqo.wl-maz@kernel.org>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
 <87a5cysfci.wl-maz@kernel.org>
 <Z2AfOZ82QG_ukWry@J2N7QTR9R3>
 <865xnjsnqo.wl-maz@kernel.org>
Message-ID: <c0501e6c-7657-4885-abfa-1c0753c0e063@sirena.org.uk>

On Mon, Dec 16, 2024 at 02:31:43PM +0000, Marc Zyngier wrote:
> Mark Rutland <mark.rutland at arm.com> wrote:

> > I understand that we have to do something as a bodge for broken FW which
> > traps SME, but I'd much rather we did that within __cpuinfo_store_cpu().

> Honestly, I'd rather revert that patch, together with b3000e2133d8
> ("arm64: Add the arm64.nosme command line option"). I'm getting tired
> of the FW nonsense, and we are only allowing vendors to ship untested
> crap.

I'd certainly be happy to remove the override for SME, the circumstances
that lead to the need to override SVE are much less likely to occur with
SME.  We can add it again later if there's a need for it.

> Furthermore, given the state of SME in the kernel, I don't think this
> is makes any difference. So maybe this is the right time to reset
> everything to a sane state.

I'm not aware of any issues that don't have fixes on the list (the fixes
have all been on the list for about a month, apart from this one).
-------------- 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/20241216/72f698d9/attachment.sig>

From gregkh at linuxfoundation.org  Mon Dec 16 07:07:43 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 16 Dec 2024 16:07:43 +0100
Subject: [PATCH] serial: stm32: use port lock wrappers for break control
In-Reply-To: <20241216145323.111612-1-ben.wolsieffer@hefring.com>
References: <20241216145323.111612-1-ben.wolsieffer@hefring.com>
Message-ID: <2024121632-railing-battle-07c7@gregkh>

On Mon, Dec 16, 2024 at 09:53:23AM -0500, Ben Wolsieffer wrote:
> Commit 30e945861f3b ("serial: stm32: add support for break control")
> added another usage of the port lock, but was merged on the same day as
> c5d06662551c ("serial: stm32: Use port lock wrappers"), therefore the
> latter did not update this usage to use the port lock wrappers.
> 
> Fixes: c5d06662551c ("serial: stm32: Use port lock wrappers")
> Signed-off-by: Ben Wolsieffer <ben.wolsieffer at hefring.com>
> ---
>  drivers/tty/serial/stm32-usart.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 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:

- You have marked a patch with a "Fixes:" tag for a commit that is in an
  older released kernel, yet you do not have a cc: stable line in the
  signed-off-by area at all, which means that the patch will not be
  applied to any older kernel releases.  To properly fix this, please
  follow the documented rules in the
  Documentation/process/stable-kernel-rules.rst file for how to resolve
  this.

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 mark.rutland at arm.com  Mon Dec 16 07:07:15 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 16 Dec 2024 15:07:15 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <865xnjsnqo.wl-maz@kernel.org>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
 <87a5cysfci.wl-maz@kernel.org>
 <Z2AfOZ82QG_ukWry@J2N7QTR9R3>
 <865xnjsnqo.wl-maz@kernel.org>
Message-ID: <Z2BCI61c9QWG7mMB@J2N7QTR9R3.cambridge.arm.com>

On Mon, Dec 16, 2024 at 02:31:43PM +0000, Marc Zyngier wrote:
> On Mon, 16 Dec 2024 12:38:17 +0000,
> Mark Rutland <mark.rutland at arm.com> wrote:
> > I think that what we did in commit:
> > 
> >    892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")
> > 
> > ... introduces an anti-pattern that'd be nice to avoid. That broke the
> > existing split of __cpuinfo_store_cpu() and init_cpu_features(), where
> > the former read the ID regs, and the latter set up the features
> > *without* altering the copy of the ID regs that was read. i.e.
> > init_cpu_features() shouldn't write to its info argument at all.
> > 
> > I understand that we have to do something as a bodge for broken FW which
> > traps SME, but I'd much rather we did that within __cpuinfo_store_cpu().
> 
> Honestly, I'd rather revert that patch, together with b3000e2133d8
> ("arm64: Add the arm64.nosme command line option"). I'm getting tired
> of the FW nonsense, and we are only allowing vendors to ship untested
> crap.
> 
> Furthermore, given the state of SME in the kernel, I don't think this
> is makes any difference. So maybe this is the right time to reset
> everything to a sane state.

Looking again, a revert does look to be the best option.

We removed reg_zcr and reg_smcr in v6.7 in commits:

  abef0695f9665c3d ("arm64/sve: Remove ZCR pseudo register from cpufeature code")
  391208485c3ad50f ("arm64/sve: Remove SMCR pseudo register from cpufeature code")

As of those commits, ZCR and SCMR no longer matter to
__cpuinfo_store_cpu(), and only SMIDR_EL1 remains...

Per ARM DDI 0487 L.a, accesses to SMIDR_EL1 never trap to EL3, so we can
read that safely as long as ID_AA64PFR1_EL1.SME indicates that SME is
implemented.

Which is to say that if we revert the remaining portion of 892f7237b3ff
and restore the read of SMIDR, that should be good as far back as v6.7,
which sounds good to me.

Mark.

> > Can we add something to check whether SME was disabled on the command
> > line, and use that in __cpuinfo_store_cpu(), effectively reverting
> > 892f7237b3ff?
> 
> Maybe, but that'd be before any sanitisation of the overrides, so it
> would have to severely limit its scope. Something like this, which I
> haven't tested:
> 
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index d79e88fccdfce..9e9295e045009 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -492,10 +492,22 @@ void cpuinfo_store_cpu(void)
>  	update_cpu_features(smp_processor_id(), info, &boot_cpu_data);
>  }
>  
> +static void cpuinfo_apply_overrides(struct cpuinfo_arm64 *info)
> +{
> +	if (FIELD_GET(ID_AA64PFR0_EL1_SVE, id_aa64pfr0_override.mask) &&
> +	    !FIELD_GET(ID_AA64PFR0_EL1_SVE, id_aa64pfr0_override.val))
> +		info->reg_id_aa64pfr0 &= ~ID_AA64PFR0_EL1_SVE;
> +
> +	if (FIELD_GET(ID_AA64PFR1_EL1_SME, id_aa64pfr1_override.mask) &&
> +	    !FIELD_GET(ID_AA64PFR1_EL1_SME, id_aa64pfr1_override.val))
> +		info->reg_id_aa64pfr1 &= ~ID_AA64PFR1_EL1_SME;
> +}
> +
>  void __init cpuinfo_store_boot_cpu(void)
>  {
>  	struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0);
>  	__cpuinfo_store_cpu(info);
> +	cpuinfo_apply_overrides(info);
>  
>  	boot_cpu_data = *info;
>  	init_cpu_features(&boot_cpu_data);
> 
> But this will have ripple effects on the rest of the override code
> (the kernel messages are likely to be wrong).
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.


From broonie at kernel.org  Mon Dec 16 07:08:55 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 15:08:55 +0000
Subject: [PATCH V2 03/46] arm64/sysreg: Update register fields for
 ID_AA64PFR0_EL1
In-Reply-To: <20241210055311.780688-4-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-4-anshuman.khandual@arm.com>
Message-ID: <b5d96df1-3c02-40a7-833b-6a42183ec972@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:28AM +0530, Anshuman Khandual wrote:
> This updates ID_AA64PFR0_EL1.RAS and ID_AA64PFR0_EL1.RME register fields as
> per the definitions based on DDI0601 2024-09.

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/20241216/32163051/attachment.sig>

From dmitry.baryshkov at linaro.org  Mon Dec 16 07:12:09 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 17:12:09 +0200
Subject: [PATCH v2 04/10] drm/amd/display: use eld_mutex to protect access
 to connector->eld
In-Reply-To: <fc8e80dd-bcea-4515-b446-158649719569@amd.com>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
 <20241206-drm-connector-eld-mutex-v2-4-c9bce1ee8bea@linaro.org>
 <pgi7p3aemxm3db2k27vi5euh6q6ppayrw6y7tcfeq4g5z23hzr@xousag2qhobp> <fc8e80dd-bcea-4515-b446-158649719569@amd.com>
Message-ID: <CAA8EJpoR8HYq9ATDfmR5ksSnttBzj=DY+BKp5=OuVNF1WDJ-fg@mail.gmail.com>

On Mon, 16 Dec 2024 at 16:53, Harry Wentland <harry.wentland at amd.com> wrote:
>
>
>
> On 2024-12-10 16:20, Dmitry Baryshkov wrote:
> > On Fri, Dec 06, 2024 at 11:43:07AM +0200, Dmitry Baryshkov wrote:
> >> Reading access to connector->eld can happen at the same time the
> >> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
> >> order to protect connector->eld from concurrent access.
> >>
> >> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> >> ---
> >>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
> >>  1 file changed, 2 insertions(+)
> >
> > Harry, Leo, Rodrigo, Alex, Christian, Xinhui, any response to this one
> > and to the radeon patches? I'd like to be able to pick the series for
> > drm-misc and these two are not reviewed by you.
> >
> >>
> >> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> index 19a58630e774029767bf2a27eb4ddf17e3c21129..04c68c320252b5ce9647f0606fb86fe57f347639 100644
> >> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> @@ -1037,8 +1037,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port,
> >>                      continue;
> >>
> >>              *enabled = true;
> >> +            mutex_lock(&connector->eld_mutex);
> >>              ret = drm_eld_size(connector->eld);
> >>              memcpy(buf, connector->eld, min(max_bytes, ret));
> >> +            mutex_unlock(&connector->eld_mutex);
>
> All of this is wrapped by the adev->dm.audio_lock mutex. It might
> be safer to modify the audio_lock mutex so it only guards the
> aconnector->audio_inst access.
>
> But I don't see any way these mutexes would otherwise interact,
> so this change should be good as-is.
>
> Reviewed-by: Harry Wentland <harry.wentland at amd.com>

Would you ack it to merge it through drm-misc? Or would you prefer to
pick up those two patches after merging drm-misc-next once the rest of
the series lands?

>
> Harry
>
> >>
> >>              break;
> >>      }
> >>
> >> --
> >> 2.39.5
> >>
> >
>


-- 
With best wishes
Dmitry


From mark.rutland at arm.com  Mon Dec 16 07:11:46 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 16 Dec 2024 15:11:46 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <864j33sn60.wl-maz@kernel.org>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
 <87a5cysfci.wl-maz@kernel.org>
 <709a0e75-0d0c-4bff-b9fd-3bbb55c97bd5@sirena.org.uk>
 <Z2Agntn52mY5bSTp@J2N7QTR9R3>
 <855dbb91-db37-4178-bd0b-511994d3aef7@sirena.org.uk>
 <Z2A502_EpqvLYN8g@J2N7QTR9R3.cambridge.arm.com>
 <864j33sn60.wl-maz@kernel.org>
Message-ID: <Z2BDMpPYRFfio8lr@J2N7QTR9R3.cambridge.arm.com>

On Mon, Dec 16, 2024 at 02:44:07PM +0000, Marc Zyngier wrote:
> On Mon, 16 Dec 2024 14:31:47 +0000,
> Mark Rutland <mark.rutland at arm.com> wrote:
> > 
> > On Mon, Dec 16, 2024 at 01:23:55PM +0000, Mark Brown wrote:
> > > On Mon, Dec 16, 2024 at 12:44:14PM +0000, Mark Rutland wrote:
> > > 
> > > > ... didn't matter either way, and using '&boot_cpu_data' was intended to
> > > > make it clear that the features were based on the boot CPU's info, even
> > > > if you just grepped for that and didn't see the surrounding context.
> > > 
> > > Right, that was my best guess as to what was supposed to be going on
> > > but it wasn't super clear.  The code could use some more comments.
> > > 
> > > > I think the real fix here is to move the reading back into
> > > > __cpuinfo_store_cpu(), but to have an explicit check that SME has been
> > > > disabled on the commandline, with a comment explaining that this is a
> > > > bodge for broken FW which traps the SME ID regs.
> > > 
> > > That should be doable.
> > > 
> > > There's a few other similar ID registers (eg, we already read GMID_EL1
> > > and MPAMIDR_EL1) make me a bit nervous that we might need to generalise
> > > it a bit, but we can deal with that if it comes up.  Even for SME the
> > > disable was added speculatively, the factors that made this come up for
> > > SVE are less likely to be an issue with SME.
> > 
> > FWIW, I had a quick go (with only the SME case), and I think the shape
> > that we want is roughly as below, which I think is easy to generalise to
> > those other cases.
> > 
> > MarcZ, thoughts?
> > 
> > Mark.

[... dodgy patch was here ...]

> I don't think blindly applying the override at this stage is a good
> thing. Specially not the whole register, and definitely not
> non-disabling values.
> 
> It needs to be done on a per feature basis, and only to disable
> things.
> 
> See the hack I posted for the things I think need checking.

Understood; sorry for the noise -- we raced when replying and I only
spotted your reply after sending this. I think I'm more in favour of the
revert option now; I've repled with more details at:

  https://lore.kernel.org/linux-arm-kernel/Z2BCI61c9QWG7mMB at J2N7QTR9R3.cambridge.arm.com/T/#m8d6ace8d6201591ca72d51cf14c4a605e7d98a88

Mark.


From broonie at kernel.org  Mon Dec 16 07:12:36 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 15:12:36 +0000
Subject: [PATCH V2 04/46] arm64/sysreg: Update register fields for
 TRBIDR_EL1
In-Reply-To: <20241210055311.780688-5-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-5-anshuman.khandual@arm.com>
Message-ID: <1c1c9117-e2b2-49e7-9bdb-7ac6a184d7fd@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:29AM +0530, Anshuman Khandual wrote:
> This adds register fields for TRBIDR_EL1 as per the definitions based
> on DDI0601 2024-09.

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/20241216/9889f3a3/attachment.sig>

From broonie at kernel.org  Mon Dec 16 07:17:11 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 15:17:11 +0000
Subject: [PATCH V2 07/46] arm64/sysreg: Add register fields for
 HFGITR2_EL2
In-Reply-To: <20241210055311.780688-8-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-8-anshuman.khandual@arm.com>
Message-ID: <a953ea06-af70-4fe4-a4c4-0a4e87aa88cd@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:32AM +0530, Anshuman Khandual wrote:
> This adds register fields for HFGITR2_EL2 as per the definitions based
> on DDI0601 2024-09.

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/20241216/7c9606d3/attachment.sig>

From eichest at gmail.com  Mon Dec 16 07:16:40 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Mon, 16 Dec 2024 16:16:40 +0100
Subject: [PATCH v1] i2c: imx: fix missing stop condition in single-master mode
Message-ID: <20241216151829.74056-1-eichest@gmail.com>

From: Stefan Eichenberger <stefan.eichenberger at toradex.com>

A regression was introduced with the implementation of single-master
mode, preventing proper stop conditions from being generated. Devices
that require a valid stop condition, such as EEPROMs, fail to function
correctly as a result.

The issue only affects devices with the single-master property enabled.

This commit resolves the issue by re-enabling I2C bus busy bit (IBB)
polling for single-master mode when generating a stop condition. The fix
further ensures that the i2c_imx->stopped flag is cleared at the start
of each transfer, allowing the stop condition to be correctly generated
in i2c_imx_stop().

According to the reference manual (IMX8MMRM, Rev. 2, 09/2019, page
5270), polling the IBB bit to determine if the bus is free is only
necessary in multi-master mode. Consequently, the IBB bit is not polled
for the start condition in single-master mode.

Fixes: 6692694aca86 ("i2c: imx: do not poll for bus busy in single master mode")
Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>
---
 drivers/i2c/busses/i2c-imx.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index f751d231ded8..cbf66a69e20b 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -534,20 +534,18 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a
 {
 	unsigned long orig_jiffies = jiffies;
 	unsigned int temp;
-
-	if (!i2c_imx->multi_master)
-		return 0;
+	bool multi_master = i2c_imx->multi_master;
 
 	while (1) {
 		temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
 
 		/* check for arbitration lost */
-		if (temp & I2SR_IAL) {
+		if (multi_master && (temp & I2SR_IAL)) {
 			i2c_imx_clear_irq(i2c_imx, I2SR_IAL);
 			return -EAGAIN;
 		}
 
-		if (for_busy && (temp & I2SR_IBB)) {
+		if (for_busy && (!multi_master || (temp & I2SR_IBB))) {
 			i2c_imx->stopped = 0;
 			break;
 		}
-- 
2.45.2



From broonie at kernel.org  Mon Dec 16 07:20:20 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 15:20:20 +0000
Subject: [PATCH V2 08/46] arm64/sysreg: Add register fields for
 HFGRTR2_EL2
In-Reply-To: <20241210055311.780688-9-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-9-anshuman.khandual@arm.com>
Message-ID: <4830a422-9acc-4d2e-86e7-7e75af340dea@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:33AM +0530, Anshuman Khandual wrote:
> This adds register fields for HFGRTR2_EL2 as per the definitions based
> on DDI0601 2024-09.

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/20241216/92461646/attachment.sig>

From broonie at kernel.org  Mon Dec 16 07:21:35 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 15:21:35 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <Z2BCI61c9QWG7mMB@J2N7QTR9R3.cambridge.arm.com>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
 <87a5cysfci.wl-maz@kernel.org>
 <Z2AfOZ82QG_ukWry@J2N7QTR9R3>
 <865xnjsnqo.wl-maz@kernel.org>
 <Z2BCI61c9QWG7mMB@J2N7QTR9R3.cambridge.arm.com>
Message-ID: <4f72a6ec-63e8-4947-9455-fd354d03cadc@sirena.org.uk>

On Mon, Dec 16, 2024 at 03:07:15PM +0000, Mark Rutland wrote:

> Looking again, a revert does look to be the best option.

Since we all seem to agree I'll send a patch doing 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/20241216/b70be541/attachment.sig>

From mripard at kernel.org  Mon Dec 16 07:24:26 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 16 Dec 2024 16:24:26 +0100
Subject: [PATCH v2 00/10] drm/connector: add eld_mutex to protect
 connector->eld
In-Reply-To: <xchjpeykkqwlpniaspbzitaozuoltoq7aturtu7jq6z4lcxh77@y7t5ge2sa4er>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
 <xchjpeykkqwlpniaspbzitaozuoltoq7aturtu7jq6z4lcxh77@y7t5ge2sa4er>
Message-ID: <20241216-observant-spiritual-wolf-564ee3@houat>

On Mon, Dec 16, 2024 at 01:24:29PM +0200, Dmitry Baryshkov wrote:
> On Fri, Dec 06, 2024 at 11:43:03AM +0200, Dmitry Baryshkov wrote:
> > The connector->eld is accessed by the .get_eld() callback. This access
> > can collide with the drm_edid_to_eld() updating the data at the same
> > time. Add drm_connector.eld_mutex to protect the data from concurrenct
> > access.
> > 
> > The individual drivers were just compile tested. I propose to merge the
> > drm_connector and bridge drivers through drm-misc, allowing other
> > maintainers either to ack merging through drm-misc or merging the
> > drm-misc into their tree and then picking up correcponding patch.
> > 
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> > Changes in v2:
> > - Also take the mutex in clear_eld() (Jani)
> > - Rebased on top of linux-next + drm-misc-next to solve build error
> > - Link to v1: https://lore.kernel.org/r/20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03 at linaro.org
> > 
> > ---
> > Dmitry Baryshkov (10):
> >       drm/connector: add mutex to protect ELD from concurrent access
> >       drm/bridge: anx7625: use eld_mutex to protect access to connector->eld
> >       drm/bridge: ite-it66121: use eld_mutex to protect access to connector->eld
> >       drm/amd/display: use eld_mutex to protect access to connector->eld
> >       drm/exynos: hdmi: use eld_mutex to protect access to connector->eld
> >       drm/i915/audio: use eld_mutex to protect access to connector->eld
> >       drm/msm/dp: use eld_mutex to protect access to connector->eld
> >       drm/radeon: use eld_mutex to protect access to connector->eld
> >       drm/sti: hdmi: use eld_mutex to protect access to connector->eld
> >       drm/vc4: hdmi: use eld_mutex to protect access to connector->eld
> 
> Granted the lack of reviews from AMD maintainers and granted that the
> rest of the series was reviewed and acked, is it suitable to leave those
> two patches out and merge the rest through drm-misc-next?

Sounds reasonable to me

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

From maz at kernel.org  Mon Dec 16 07:28:25 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 16 Dec 2024 15:28:25 +0000
Subject: [PATCH] arm64/sme: Move storage of reg_smidr to __cpuinfo_store_cpu()
In-Reply-To: <Z2BCI61c9QWG7mMB@J2N7QTR9R3.cambridge.arm.com>
References: <20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd@kernel.org>
	<87a5cysfci.wl-maz@kernel.org>
	<Z2AfOZ82QG_ukWry@J2N7QTR9R3>
	<865xnjsnqo.wl-maz@kernel.org>
	<Z2BCI61c9QWG7mMB@J2N7QTR9R3.cambridge.arm.com>
Message-ID: <8634insl46.wl-maz@kernel.org>

On Mon, 16 Dec 2024 15:07:15 +0000,
Mark Rutland <mark.rutland at arm.com> wrote:
> 
> On Mon, Dec 16, 2024 at 02:31:43PM +0000, Marc Zyngier wrote:
> > On Mon, 16 Dec 2024 12:38:17 +0000,
> > Mark Rutland <mark.rutland at arm.com> wrote:
> > > I think that what we did in commit:
> > > 
> > >    892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")
> > > 
> > > ... introduces an anti-pattern that'd be nice to avoid. That broke the
> > > existing split of __cpuinfo_store_cpu() and init_cpu_features(), where
> > > the former read the ID regs, and the latter set up the features
> > > *without* altering the copy of the ID regs that was read. i.e.
> > > init_cpu_features() shouldn't write to its info argument at all.
> > > 
> > > I understand that we have to do something as a bodge for broken FW which
> > > traps SME, but I'd much rather we did that within __cpuinfo_store_cpu().
> > 
> > Honestly, I'd rather revert that patch, together with b3000e2133d8
> > ("arm64: Add the arm64.nosme command line option"). I'm getting tired
> > of the FW nonsense, and we are only allowing vendors to ship untested
> > crap.
> > 
> > Furthermore, given the state of SME in the kernel, I don't think this
> > is makes any difference. So maybe this is the right time to reset
> > everything to a sane state.
> 
> Looking again, a revert does look to be the best option.
> 
> We removed reg_zcr and reg_smcr in v6.7 in commits:
> 
>   abef0695f9665c3d ("arm64/sve: Remove ZCR pseudo register from cpufeature code")
>   391208485c3ad50f ("arm64/sve: Remove SMCR pseudo register from cpufeature code")
> 
> As of those commits, ZCR and SCMR no longer matter to
> __cpuinfo_store_cpu(), and only SMIDR_EL1 remains...
> 
> Per ARM DDI 0487 L.a, accesses to SMIDR_EL1 never trap to EL3, so we can
> read that safely as long as ID_AA64PFR1_EL1.SME indicates that SME is
> implemented.
> 
> Which is to say that if we revert the remaining portion of 892f7237b3ff
> and restore the read of SMIDR, that should be good as far back as v6.7,
> which sounds good to me.

Sounds reasonable indeed. I guess *someone* will want it for the
previous kernel versions, but they can have fun with the backport on
their own.

	M.

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


From john.ogness at linutronix.de  Mon Dec 16 07:29:26 2024
From: john.ogness at linutronix.de (John Ogness)
Date: Mon, 16 Dec 2024 16:35:26 +0106
Subject: [PATCH] serial: stm32: use port lock wrappers for break control
In-Reply-To: <20241216145323.111612-1-ben.wolsieffer@hefring.com>
References: <20241216145323.111612-1-ben.wolsieffer@hefring.com>
Message-ID: <84cyhrk5nt.fsf@jogness.linutronix.de>

On 2024-12-16, Ben Wolsieffer <ben.wolsieffer at hefring.com> wrote:
> Commit 30e945861f3b ("serial: stm32: add support for break control")
> added another usage of the port lock, but was merged on the same day as
> c5d06662551c ("serial: stm32: Use port lock wrappers"), therefore the
> latter did not update this usage to use the port lock wrappers.
>
> Fixes: c5d06662551c ("serial: stm32: Use port lock wrappers")
> Signed-off-by: Ben Wolsieffer <ben.wolsieffer at hefring.com>

Thanks for catching this!

Reviewed-by: John Ogness <john.ogness at linutronix.de>


From alexdeucher at gmail.com  Mon Dec 16 07:31:55 2024
From: alexdeucher at gmail.com (Alex Deucher)
Date: Mon, 16 Dec 2024 10:31:55 -0500
Subject: [PATCH v2 04/10] drm/amd/display: use eld_mutex to protect access
 to connector->eld
In-Reply-To: <CAA8EJpoR8HYq9ATDfmR5ksSnttBzj=DY+BKp5=OuVNF1WDJ-fg@mail.gmail.com>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
 <20241206-drm-connector-eld-mutex-v2-4-c9bce1ee8bea@linaro.org>
 <pgi7p3aemxm3db2k27vi5euh6q6ppayrw6y7tcfeq4g5z23hzr@xousag2qhobp>
 <fc8e80dd-bcea-4515-b446-158649719569@amd.com> <CAA8EJpoR8HYq9ATDfmR5ksSnttBzj=DY+BKp5=OuVNF1WDJ-fg@mail.gmail.com>
Message-ID: <CADnq5_M8jC2w=XWB4BG+id60zfGFMMkSegmeg-y=VpSHC+FvFQ@mail.gmail.com>

On Mon, Dec 16, 2024 at 10:12?AM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Mon, 16 Dec 2024 at 16:53, Harry Wentland <harry.wentland at amd.com> wrote:
> >
> >
> >
> > On 2024-12-10 16:20, Dmitry Baryshkov wrote:
> > > On Fri, Dec 06, 2024 at 11:43:07AM +0200, Dmitry Baryshkov wrote:
> > >> Reading access to connector->eld can happen at the same time the
> > >> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
> > >> order to protect connector->eld from concurrent access.
> > >>
> > >> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> > >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > >> ---
> > >>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
> > >>  1 file changed, 2 insertions(+)
> > >
> > > Harry, Leo, Rodrigo, Alex, Christian, Xinhui, any response to this one
> > > and to the radeon patches? I'd like to be able to pick the series for
> > > drm-misc and these two are not reviewed by you.
> > >
> > >>
> > >> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > >> index 19a58630e774029767bf2a27eb4ddf17e3c21129..04c68c320252b5ce9647f0606fb86fe57f347639 100644
> > >> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > >> @@ -1037,8 +1037,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port,
> > >>                      continue;
> > >>
> > >>              *enabled = true;
> > >> +            mutex_lock(&connector->eld_mutex);
> > >>              ret = drm_eld_size(connector->eld);
> > >>              memcpy(buf, connector->eld, min(max_bytes, ret));
> > >> +            mutex_unlock(&connector->eld_mutex);
> >
> > All of this is wrapped by the adev->dm.audio_lock mutex. It might
> > be safer to modify the audio_lock mutex so it only guards the
> > aconnector->audio_inst access.
> >
> > But I don't see any way these mutexes would otherwise interact,
> > so this change should be good as-is.
> >
> > Reviewed-by: Harry Wentland <harry.wentland at amd.com>
>
> Would you ack it to merge it through drm-misc? Or would you prefer to
> pick up those two patches after merging drm-misc-next once the rest of
> the series lands?

Merging through drm-misc is fine with me.

Thanks,

Alex

>
> >
> > Harry
> >
> > >>
> > >>              break;
> > >>      }
> > >>
> > >> --
> > >> 2.39.5
> > >>
> > >
> >
>
>
> --
> With best wishes
> Dmitry


From dmitry.baryshkov at linaro.org  Mon Dec 16 07:39:22 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 17:39:22 +0200
Subject: [PATCH v2 04/10] drm/amd/display: use eld_mutex to protect access
 to connector->eld
In-Reply-To: <CADnq5_M8jC2w=XWB4BG+id60zfGFMMkSegmeg-y=VpSHC+FvFQ@mail.gmail.com>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
 <20241206-drm-connector-eld-mutex-v2-4-c9bce1ee8bea@linaro.org>
 <pgi7p3aemxm3db2k27vi5euh6q6ppayrw6y7tcfeq4g5z23hzr@xousag2qhobp>
 <fc8e80dd-bcea-4515-b446-158649719569@amd.com> <CAA8EJpoR8HYq9ATDfmR5ksSnttBzj=DY+BKp5=OuVNF1WDJ-fg@mail.gmail.com>
 <CADnq5_M8jC2w=XWB4BG+id60zfGFMMkSegmeg-y=VpSHC+FvFQ@mail.gmail.com>
Message-ID: <CAA8EJpqYs92T9x3omDa5XR21GC04Kcc75eVRr6w3pt0W7qPX-w@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:32, Alex Deucher <alexdeucher at gmail.com> wrote:
>
> On Mon, Dec 16, 2024 at 10:12?AM Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
> >
> > On Mon, 16 Dec 2024 at 16:53, Harry Wentland <harry.wentland at amd.com> wrote:
> > >
> > >
> > >
> > > On 2024-12-10 16:20, Dmitry Baryshkov wrote:
> > > > On Fri, Dec 06, 2024 at 11:43:07AM +0200, Dmitry Baryshkov wrote:
> > > >> Reading access to connector->eld can happen at the same time the
> > > >> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
> > > >> order to protect connector->eld from concurrent access.
> > > >>
> > > >> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> > > >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > >> ---
> > > >>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
> > > >>  1 file changed, 2 insertions(+)
> > > >
> > > > Harry, Leo, Rodrigo, Alex, Christian, Xinhui, any response to this one
> > > > and to the radeon patches? I'd like to be able to pick the series for
> > > > drm-misc and these two are not reviewed by you.
> > > >
> > > >>
> > > >> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > >> index 19a58630e774029767bf2a27eb4ddf17e3c21129..04c68c320252b5ce9647f0606fb86fe57f347639 100644
> > > >> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > >> @@ -1037,8 +1037,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port,
> > > >>                      continue;
> > > >>
> > > >>              *enabled = true;
> > > >> +            mutex_lock(&connector->eld_mutex);
> > > >>              ret = drm_eld_size(connector->eld);
> > > >>              memcpy(buf, connector->eld, min(max_bytes, ret));
> > > >> +            mutex_unlock(&connector->eld_mutex);
> > >
> > > All of this is wrapped by the adev->dm.audio_lock mutex. It might
> > > be safer to modify the audio_lock mutex so it only guards the
> > > aconnector->audio_inst access.
> > >
> > > But I don't see any way these mutexes would otherwise interact,
> > > so this change should be good as-is.
> > >
> > > Reviewed-by: Harry Wentland <harry.wentland at amd.com>
> >
> > Would you ack it to merge it through drm-misc? Or would you prefer to
> > pick up those two patches after merging drm-misc-next once the rest of
> > the series lands?
>
> Merging through drm-misc is fine with me.

Thanks!

>
> Thanks,
>
> Alex
>
> >
> > >
> > > Harry
> > >
> > > >>
> > > >>              break;
> > > >>      }
> > > >>
> > > >> --
> > > >> 2.39.5
> > > >>
> > > >
> > >
> >
> >
> > --
> > With best wishes
> > Dmitry



-- 
With best wishes
Dmitry


From fabrice.gasnier at foss.st.com  Mon Dec 16 07:39:06 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Mon, 16 Dec 2024 16:39:06 +0100
Subject: [PATCH 3/5] ARM: dts: stm32: add counter subnodes on stm32mp135f-dk
In-Reply-To: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
References: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241216153908.3069548-4-fabrice.gasnier@foss.st.com>

Enable the counter nodes without dedicated pins. With such configuration,
the counter interface can be used on internal clock to generate events.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp135f-dk.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index 1af335a39993..c6a5bfe89a38 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -396,6 +396,9 @@ &timers3 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		/* PWM output on pin 7 of the expansion connector (CN8.7) using TIM3_CH4 func */
 		pinctrl-0 = <&pwm3_pins_a>;
@@ -412,6 +415,9 @@ &timers4 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		/* PWM output on pin 31 of the expansion connector (CN8.31) using TIM4_CH2 func */
 		pinctrl-0 = <&pwm4_pins_a>;
@@ -428,6 +434,9 @@ &timers8 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		/* PWM output on pin 32 of the expansion connector (CN8.32) using TIM8_CH3 func */
 		pinctrl-0 = <&pwm8_pins_a>;
@@ -442,6 +451,9 @@ timer at 7 {
 
 &timers14 {
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		/* PWM output on pin 33 of the expansion connector (CN8.33) using TIM14_CH1 func */
 		pinctrl-0 = <&pwm14_pins_a>;
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Mon Dec 16 07:39:03 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Mon, 16 Dec 2024 16:39:03 +0100
Subject: [PATCH 0/5] ARM: dts: stm32: add counter nodes on stm32mp13 and stm32mp15
Message-ID: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>

Counter driver originally had support limited to quadrature interface
and simple counter. It has been improved[1], so populate and enable
stm32 timer counter nodes on stm32mp13 and stm32mp15.

[1] https://lore.kernel.org/linux-arm-kernel/20240307133306.383045-1-fabrice.gasnier at foss.st.com/

Fabrice Gasnier (5):
  ARM: dts: stm32: populate all timer counter nodes on stm32mp13
  ARM: dts: stm32: populate all timer counter nodes on stm32mp15
  ARM: dts: stm32: add counter subnodes on stm32mp135f-dk
  ARM: dts: stm32: add counter subnodes on stm32mp157c-ev1
  ARM: dts: stm32: add counter subnodes on stm32mp157 dk boards

 arch/arm/boot/dts/st/stm32mp131.dtsi      | 40 ++++++++++++++++++++++
 arch/arm/boot/dts/st/stm32mp135f-dk.dts   | 12 +++++++
 arch/arm/boot/dts/st/stm32mp151.dtsi      | 41 +++++++++++++++++++++++
 arch/arm/boot/dts/st/stm32mp157c-ev1.dts  |  9 +++++
 arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi | 18 ++++++++++
 5 files changed, 120 insertions(+)

-- 
2.25.1



From fabrice.gasnier at foss.st.com  Mon Dec 16 07:39:05 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Mon, 16 Dec 2024 16:39:05 +0100
Subject: [PATCH 2/5] ARM: dts: stm32: populate all timer counter nodes on stm32mp15
In-Reply-To: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
References: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241216153908.3069548-3-fabrice.gasnier@foss.st.com>

Counter driver originally had support limited to quadrature interface
and simple counter. It has been improved[1], so add the remaining
stm32 timer counter nodes.

[1] https://lore.kernel.org/linux-arm-kernel/20240307133306.383045-1-fabrice.gasnier at foss.st.com/

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp151.dtsi | 41 ++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp151.dtsi b/arch/arm/boot/dts/st/stm32mp151.dtsi
index 4f878ec102c1..13e172371eac 100644
--- a/arch/arm/boot/dts/st/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp151.dtsi
@@ -576,6 +576,11 @@ timers6: timer at 40004000 {
 				access-controllers = <&etzpc 20>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				timer at 5 {
 					compatible = "st,stm32h7-timer-trigger";
 					reg = <5>;
@@ -597,6 +602,11 @@ timers7: timer at 40005000 {
 				access-controllers = <&etzpc 21>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				timer at 6 {
 					compatible = "st,stm32h7-timer-trigger";
 					reg = <6>;
@@ -616,6 +626,11 @@ timers12: timer at 40006000 {
 				access-controllers = <&etzpc 22>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
@@ -641,6 +656,11 @@ timers13: timer at 40007000 {
 				access-controllers = <&etzpc 23>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
@@ -666,6 +686,11 @@ timers14: timer at 40008000 {
 				access-controllers = <&etzpc 24>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
@@ -1114,6 +1139,11 @@ timers15: timer at 44006000 {
 				access-controllers = <&etzpc 54>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
@@ -1142,11 +1172,17 @@ timers16: timer at 44007000 {
 				access-controllers = <&etzpc 55>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
 					status = "disabled";
 				};
+
 				timer at 15 {
 					compatible = "st,stm32h7-timer-trigger";
 					reg = <15>;
@@ -1169,6 +1205,11 @@ timers17: timer at 44008000 {
 				access-controllers = <&etzpc 56>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Mon Dec 16 07:39:04 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Mon, 16 Dec 2024 16:39:04 +0100
Subject: [PATCH 1/5] ARM: dts: stm32: populate all timer counter nodes on stm32mp13
In-Reply-To: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
References: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241216153908.3069548-2-fabrice.gasnier@foss.st.com>

Counter driver originally had support limited to quadrature interface
and simple counter. It has been improved[1], so add the remaining
stm32 timer counter nodes.

[1] https://lore.kernel.org/linux-arm-kernel/20240307133306.383045-1-fabrice.gasnier at foss.st.com/

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp131.dtsi | 40 ++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp131.dtsi b/arch/arm/boot/dts/st/stm32mp131.dtsi
index e1a764d269d2..0019d12c3d3d 100644
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -261,6 +261,11 @@ timers6: timer at 40004000 {
 			dma-names = "up";
 			status = "disabled";
 
+			counter {
+				compatible = "st,stm32-timer-counter";
+				status = "disabled";
+			};
+
 			timer at 5 {
 				compatible = "st,stm32h7-timer-trigger";
 				reg = <5>;
@@ -281,6 +286,11 @@ timers7: timer at 40005000 {
 			dma-names = "up";
 			status = "disabled";
 
+			counter {
+				compatible = "st,stm32-timer-counter";
+				status = "disabled";
+			};
+
 			timer at 6 {
 				compatible = "st,stm32h7-timer-trigger";
 				reg = <6>;
@@ -1196,6 +1206,11 @@ timers12: timer at 4c007000 {
 				access-controllers = <&etzpc 23>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
@@ -1221,6 +1236,11 @@ timers13: timer at 4c008000 {
 				access-controllers = <&etzpc 24>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
@@ -1246,6 +1266,11 @@ timers14: timer at 4c009000 {
 				access-controllers = <&etzpc 25>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
@@ -1276,6 +1301,11 @@ timers15: timer at 4c00a000 {
 				access-controllers = <&etzpc 26>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
@@ -1304,6 +1334,11 @@ timers16: timer at 4c00b000 {
 				access-controllers = <&etzpc 27>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
@@ -1332,6 +1367,11 @@ timers17: timer at 4c00c000 {
 				access-controllers = <&etzpc 28>;
 				status = "disabled";
 
+				counter {
+					compatible = "st,stm32-timer-counter";
+					status = "disabled";
+				};
+
 				pwm {
 					compatible = "st,stm32-pwm";
 					#pwm-cells = <3>;
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Mon Dec 16 07:39:07 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Mon, 16 Dec 2024 16:39:07 +0100
Subject: [PATCH 4/5] ARM: dts: stm32: add counter subnodes on stm32mp157c-ev1
In-Reply-To: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
References: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241216153908.3069548-5-fabrice.gasnier@foss.st.com>

Enable the counter nodes without dedicated pins. With such configuration,
the counter interface can be used on internal clock to generate events.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp157c-ev1.dts | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp157c-ev1.dts b/arch/arm/boot/dts/st/stm32mp157c-ev1.dts
index 9eb9a1bf4f2c..8f99c30f1af1 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-ev1.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-ev1.dts
@@ -306,6 +306,9 @@ &timers2 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		pinctrl-0 = <&pwm2_pins_a>;
 		pinctrl-1 = <&pwm2_sleep_pins_a>;
@@ -321,6 +324,9 @@ &timers8 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		pinctrl-0 = <&pwm8_pins_a>;
 		pinctrl-1 = <&pwm8_sleep_pins_a>;
@@ -336,6 +342,9 @@ &timers12 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		pinctrl-0 = <&pwm12_pins_a>;
 		pinctrl-1 = <&pwm12_sleep_pins_a>;
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Mon Dec 16 07:39:08 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Mon, 16 Dec 2024 16:39:08 +0100
Subject: [PATCH 5/5] ARM: dts: stm32: add counter subnodes on stm32mp157 dk boards
In-Reply-To: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
References: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241216153908.3069548-6-fabrice.gasnier@foss.st.com>

Enable the counter nodes without dedicated pins. With such configuration,
the counter interface can be used on internal clock to generate events.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi
index f7634c51efb2..a5511b1f0ce3 100644
--- a/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi
@@ -570,6 +570,9 @@ &timers1 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		pinctrl-0 = <&pwm1_pins_a>;
 		pinctrl-1 = <&pwm1_sleep_pins_a>;
@@ -585,6 +588,9 @@ &timers3 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		pinctrl-0 = <&pwm3_pins_a>;
 		pinctrl-1 = <&pwm3_sleep_pins_a>;
@@ -600,6 +606,9 @@ &timers4 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		pinctrl-0 = <&pwm4_pins_a &pwm4_pins_b>;
 		pinctrl-1 = <&pwm4_sleep_pins_a &pwm4_sleep_pins_b>;
@@ -615,6 +624,9 @@ &timers5 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		pinctrl-0 = <&pwm5_pins_a>;
 		pinctrl-1 = <&pwm5_sleep_pins_a>;
@@ -630,6 +642,9 @@ &timers6 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	timer at 5 {
 		status = "okay";
 	};
@@ -639,6 +654,9 @@ &timers12 {
 	/delete-property/dmas;
 	/delete-property/dma-names;
 	status = "disabled";
+	counter {
+		status = "okay";
+	};
 	pwm {
 		pinctrl-0 = <&pwm12_pins_a>;
 		pinctrl-1 = <&pwm12_sleep_pins_a>;
-- 
2.25.1



From sudeep.holla at arm.com  Mon Dec 16 08:08:27 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 16 Dec 2024 16:08:27 +0000
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless
 scmi_bus_id.
In-Reply-To: <CAEEwsfRKVBVR+DxhkYA5atxU7+6nsaL9X8-Yoa_DqB0YKEV1zg@mail.gmail.com>
References: <20241216073745.2973317-1-guomin_chen@sina.com>
 <Z1_p0nU93PHJ4Sg_@pluto>
 <Z1_2rxJ7TOEIOMp7@pluto>
 <CAEEwsfRhe4-YAwe027huSXwFfkV-O-8w1GDNf=URa9efRsXiKA@mail.gmail.com>
 <Z2AEzHc5f6TjxErs@bogus>
 <CAEEwsfRKVBVR+DxhkYA5atxU7+6nsaL9X8-Yoa_DqB0YKEV1zg@mail.gmail.com>
Message-ID: <Z2BQe3-zl2IN_Cjj@bogus>

On Mon, Dec 16, 2024 at 10:10:40PM +0800, gchen chen wrote:
> Sudeep Holla <sudeep.holla at arm.com> ?2024?12?16??? 18:45???

[...]

> >
> > I would like to understand the motivation behind this change. What is the
> > goal ? Do you prefer to fetch the name and protocol id from the device
> > name itself ? Is that your requirement.
> >
> hi Sudeep
>     Okay, the reason I want to change names like 'scmi_dev.3' to
> 'scmi_dev.firmware:scmi.perf.19' is because when I was migrating the
> SOC's kernel from v6.1 to v6.6, I found that the context for creating
> SCMI devices had changed (commit d3cd7c525fd2: firmware: arm_scmi:
> Refactor protocol device creation).

Correct. That's the beauty of Linux we can adjust the internals to enhance
the features without breaking the user-space.

> This change meant that device creation shifted from being directly
> created through scmi_protocol_device_request during SCMI driver
> registration to being created via scmi_device_request_notifier.
> This shift results in changes to the order in which devices are created,
> causing the ID in scmi_dev.id to drift.
>

What issue does this drift cause exactly ? I mean the order in which
the devices are created should not impact on anything if the dependency
on the order was not created. What was that dependency ?

> Additionally, I encountered some cpufreq errors here?because both
> scmi_cpufreq_drv and scmi_perf_domain_driver use the same
> SCMI_PROTOCOL_PERF, this results in two SCMI devices corresponding to
> the same device node. However, device_node.fwnode.dev only points to
> the first registered scmi_device, causing other consumer devices to
> find the wrong scmi device as the supplier. So I would find a
> multitude of other consumer devices waiting for meaningless device
> names like "scmi_dev.4" instead of meaningful names such as
> "scmi_dev.firmware:scmi.perf.19" or
> "scmi_dev.firmware:scmi.cpufreq.19".
>

Yes this was reported. I think most of the std protocol may not use that
node and need not be assigned. But I think vendor extensions are adding
info to the DT that may need this.

> Although I could further determine which specific driver it was by
> looking at the driver links under the scmi_protocol bus directory, I
> thought that if the logs directly displayed device names like
> 'scmi_dev.firmware:scmi.perf.19' instead of meaningless progressive
> IDs, it would be more convenient and logical, and thus more
> meaningful.
>

If the issue you encountered render your platform into boot issues ?
If so I would like to know what exactly happened. If not, I can think of
alternate solution if possible.

> > From the commit log, I get a sense that you looked at the code and thought
> > of possible improvement but when we mentioned the limitation you just
> > improvised by adding parent name. Do you expect any userspace to parse
> > the name as that will end up being ABI and we can't break it. I need
> > real motive to be explained here in detail.
> >
> I did not use userspace tools to parse this SCMI device name; I simply
> wanted the name to reflect the possible logic of the device.
> I did not remove scmi_dev.id (This scmi_device structure has not
> changed.?; I just no longer assign values to it using scmi_bus_id, so
> it should not affect the kernel ABI (kABI).

I understand the change, just not the possible impact w.r.t user-space.

-- 
Regards,
Sudeep


From dmitry.baryshkov at linaro.org  Mon Dec 16 08:08:41 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 18:08:41 +0200
Subject: [PATCH v2 00/10] drm/connector: add eld_mutex to protect connector->eld
In-Reply-To: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
Message-ID: <173436531753.3257291.12458012077695445848.b4-ty@linaro.org>

On Fri, 06 Dec 2024 11:43:03 +0200, Dmitry Baryshkov wrote:
> The connector->eld is accessed by the .get_eld() callback. This access
> can collide with the drm_edid_to_eld() updating the data at the same
> time. Add drm_connector.eld_mutex to protect the data from concurrenct
> access.
> 
> The individual drivers were just compile tested. I propose to merge the
> drm_connector and bridge drivers through drm-misc, allowing other
> maintainers either to ack merging through drm-misc or merging the
> drm-misc into their tree and then picking up correcponding patch.
> 
> [...]

Applied to drm-misc-next, thanks!

[01/10] drm/connector: add mutex to protect ELD from concurrent access
        commit: df7c8e3dde37a9d81c0613285b43600f3cc70f34
[02/10] drm/bridge: anx7625: use eld_mutex to protect access to connector->eld
        commit: e72bf423a60afd744d13e40ab2194044a3af5217
[03/10] drm/bridge: ite-it66121: use eld_mutex to protect access to connector->eld
        commit: 39ead6e02ea7d19b421e9d42299d4293fed3064e
[04/10] drm/amd/display: use eld_mutex to protect access to connector->eld
        commit: 819bee01eea06282d7bda17d46caf29cae4f6d84
[05/10] drm/exynos: hdmi: use eld_mutex to protect access to connector->eld
        commit: 5e8436d334ed7f6785416447c50b42077c6503e0
[06/10] drm/i915/audio: use eld_mutex to protect access to connector->eld
        commit: 5db44dd1528625c73a31542df2a68972327c9897
[07/10] drm/msm/dp: use eld_mutex to protect access to connector->eld
        commit: 9aad030dc64f6994dc5de7bb81ceca55dbc555c3
[08/10] drm/radeon: use eld_mutex to protect access to connector->eld
        commit: b54c14f82428c8a602392d4cae1958a71a578132
[09/10] drm/sti: hdmi: use eld_mutex to protect access to connector->eld
        commit: e99c0b517bcd53cf61f998a3c4291333401cb391
[10/10] drm/vc4: hdmi: use eld_mutex to protect access to connector->eld
        commit: 81a9a93b169a273ccc4a9a1ee56f17e9981d3f98

Best regards,
-- 
With best wishes
Dmitry



From manivannan.sadhasivam at linaro.org  Mon Dec 16 08:17:00 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Mon, 16 Dec 2024 21:47:00 +0530
Subject: [PATCH v2 4/5] PCI: stm32: Add PCIe endpoint support for
 STM32MP25
In-Reply-To: <4e257489-4d90-4e47-a4d9-a2444627c356@foss.st.com>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-5-christian.bruel@foss.st.com>
 <20241203152230.5mdrt27u5u5ecwcz@thinkpad>
 <4e257489-4d90-4e47-a4d9-a2444627c356@foss.st.com>
Message-ID: <20241216161700.dtldi7fari6kafrr@thinkpad>

On Mon, Dec 16, 2024 at 11:02:07AM +0100, Christian Bruel wrote:
> Hi Manivanna,
> 
> On 12/3/24 16:22, Manivannan Sadhasivam wrote:
> > On Tue, Nov 26, 2024 at 04:51:18PM +0100, Christian Bruel wrote:
> > 
> > [...]
> > 
> > > +static int stm32_pcie_start_link(struct dw_pcie *pci)
> > > +{
> > > +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
> > > +	int ret;
> > > +
> > > +	if (stm32_pcie->link_status == STM32_PCIE_EP_LINK_ENABLED) {
> > > +		dev_dbg(pci->dev, "Link is already enabled\n");
> > > +		return 0;
> > > +	}
> > > +
> > > +	ret = stm32_pcie_enable_link(pci);
> > > +	if (ret) {
> > > +		dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret);
> > > +		return ret;
> > > +	}
> > 
> > How the REFCLK is supplied to the endpoint? From host or generated locally?
> 
> From Host only, we don't support the separated clock model.
> 

OK. So even without refclk you are still able to access the controller
registers? So the controller CSRs should be accessible by separate local clock I
believe.

Anyhow, please add this limitation (refclk dependency from host) in commit
message.

[...]

> > > +	ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE);
> > 
> > Hmm, so PHY mode is common for both endpoint and host?
> 
> Yes it is. We need to init the phy here because it is a clock source for the
> PCIe core clk
> 

Clock source? Is it coming directly to PCIe or through RCC? There is no direct
clock representation from PHY to PCIe in DT binding.

- Mani

-- 
????????? ????????


From arnd at arndb.de  Mon Dec 16 08:21:06 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 16 Dec 2024 17:21:06 +0100
Subject: [GIT PULL] soc: fixes for 6.13
Message-ID: <cccdf954-3374-414c-81fb-658df16325fc@app.fastmail.com>

The following changes since commit fac04efc5c793dccbd07e2d59af9f90b7fc0dca4:

  Linux 6.13-rc2 (2024-12-08 14:03:39 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-6.13

for you to fetch changes up to f578281000c50cae991c40e1f68b2fc0b1b9e60e:

  Merge tag 'ffa-fix-6.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes (2024-12-13 14:26:32 +0100)

----------------------------------------------------------------
soc: fixes for 6.13

There are three small fixes for the soc tree:

 - A devicetee fix for the Arm Juno reference machine, so allow more
   interesting PCI configurations

 - A build fix for SCMI firmware on the NXP i.MX platform

 - A fix for a race condition in Arm FF-A firmware

----------------------------------------------------------------
Aneesh Kumar K.V (Arm) (1):
      arm64: dts: fvp: Update PCIe bus-range property

Arnd Bergmann (4):
      firmware: arm_scmi: Fix i.MX build dependency
      Merge tag 'juno-fix-6.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes
      Merge tag 'scmi-fix-6.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes
      Merge tag 'ffa-fix-6.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes

Levi Yun (1):
      firmware: arm_ffa: Fix the race around setting ffa_dev->properties

 arch/arm64/boot/dts/arm/fvp-base-revc.dts     |  2 +-
 drivers/firmware/arm_ffa/bus.c                | 15 +++++++++++----
 drivers/firmware/arm_ffa/driver.c             |  7 +------
 drivers/firmware/arm_scmi/vendors/imx/Kconfig |  1 +
 drivers/firmware/imx/Kconfig                  |  1 -
 include/linux/arm_ffa.h                       | 13 ++++++++-----
 sound/soc/fsl/Kconfig                         |  2 +-
 7 files changed, 23 insertions(+), 18 deletions(-)


From robh at kernel.org  Mon Dec 16 08:29:15 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 16 Dec 2024 10:29:15 -0600
Subject: [PATCH v1 0/8] DTS updates for system1 BMC
In-Reply-To: <20241213145037.3784931-1-ninad@linux.ibm.com>
References: <20241213145037.3784931-1-ninad@linux.ibm.com>
Message-ID: <173436597537.264948.12611164276777551472.robh@kernel.org>


On Fri, 13 Dec 2024 08:50:26 -0600, Ninad Palsule wrote:
> Hello
> 
> Please review the patch set. It has various device tree changes for
> system1 BMC after hardware testing.
> 
> NINAD PALSULE (7):
>   ARM: dts: aspeed: system1: Add IPMB device
>   ARM: dts: aspeed: system1: Add GPIO line name
>   ARM: dts: aspeed: system1: Add RGMII support
>   ARM: dts: aspeed: system1: Reduce sgpio speed
>   ARM: dts: aspeed: system1: Update LED gpio name
>   ARM: dts: aspeed: system1: Remove VRs max8952
>   ARM: dts: aspeed: system1: Mark GPIO line high/low
> 
> Ninad Palsule (1):
>   ARM: dts: aspeed: system1: Disable gpio pull down
> 
>  .../dts/aspeed/aspeed-bmc-ibm-system1.dts     | 178 ++++++++++++------
>  1 file changed, 119 insertions(+), 59 deletions(-)
> 
> --
> 2.43.0
> 
> 
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y aspeed/aspeed-bmc-ibm-system1.dtb' for 20241213145037.3784931-1-ninad at linux.ibm.com:

arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dtb: ethernet at 1e660000: phy-mode:0: 'rgmii-rxid' is not one of ['rgmii', 'rmii']
	from schema $id: http://devicetree.org/schemas/net/faraday,ftgmac100.yaml#
arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dtb: gpio at 1e780000: 'fan_controller_reset', 'isolate_errs_cpu1', 'rtc_reset', 'srtc_reset' do not match any of the regexes: 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/gpio/aspeed,ast2400-gpio.yaml#
arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dtb: rtc_reset: $nodename:0: 'rtc_reset' does not match '^(hog-[0-9]+|.+-hog(-[0-9]+)?)$'
	from schema $id: http://devicetree.org/schemas/gpio/gpio-hog.yaml#
arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dtb: srtc_reset: $nodename:0: 'srtc_reset' does not match '^(hog-[0-9]+|.+-hog(-[0-9]+)?)$'
	from schema $id: http://devicetree.org/schemas/gpio/gpio-hog.yaml#
arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dtb: fan_controller_reset: $nodename:0: 'fan_controller_reset' does not match '^(hog-[0-9]+|.+-hog(-[0-9]+)?)$'
	from schema $id: http://devicetree.org/schemas/gpio/gpio-hog.yaml#
arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dtb: isolate_errs_cpu1: $nodename:0: 'isolate_errs_cpu1' does not match '^(hog-[0-9]+|.+-hog(-[0-9]+)?)$'
	from schema $id: http://devicetree.org/schemas/gpio/gpio-hog.yaml#
arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dtb: /ahb/apb at 1e780000/bus at 1e78a000/i2c at 280/bmc_slave at 10: failed to match any schema with compatible: ['ipmb-dev']







From robh at kernel.org  Mon Dec 16 08:29:19 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 16 Dec 2024 10:29:19 -0600
Subject: [PATCH v3 0/3] arm64: dts: rockchip: Add Firefly ITX-3588J
 Board
In-Reply-To: <20241215032507.4739-1-shimrrashai@gmail.com>
References: <20241215032507.4739-1-shimrrashai@gmail.com>
Message-ID: <173436598341.265396.5585546641509709958.robh@kernel.org>


On Sat, 14 Dec 2024 21:24:52 -0600, Shimrra Shai wrote:
> This is the 3rd draft of the device tree proposal for the Firefly ITX-3588J
> board. The same functionality issues as before are still outstanding;
> however I have cleaned up the style and structure as per the comments by
> Heiko St?bner on version 2. Of particular note is the splitting of the
> device tree source into two files because this platform actually consists
> of two boards: the ITX-3588J baseboard and a single Core-3588J compute
> module stuck in a slot on it.
> 
>  - Shimrra Shai.
> 
> Shimrra Shai (3):
>   arm64: dts: rockchip: add DTs for Firefly ITX-3588J and its Core-3588J
>     SoM
>   dt-bindings: pinctrl: add header for PCA9555 GPIO extender bindings on
>     some Rockchip-based devices
>   dt-bindings: arm: rockchip: Add Firefly ITX-3588J board
> 
>  .../devicetree/bindings/arm/rockchip.yaml     |   7 +
>  arch/arm64/boot/dts/rockchip/Makefile         |   1 +
>  .../rockchip/rk3588-firefly-core-3588j.dtsi   | 453 +++++++++++
>  .../dts/rockchip/rk3588-firefly-itx-3588j.dts | 712 ++++++++++++++++++
>  .../dt-bindings/pinctrl/rockchip-pca9555.h    |  31 +
>  5 files changed, 1204 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
>  create mode 100644 include/dt-bindings/pinctrl/rockchip-pca9555.h
> 
> --
> 2.45.2
> 
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y rockchip/rk3588-firefly-itx-3588j.dtb' for 20241215032507.4739-1-shimrrashai at gmail.com:

arch/arm64/boot/dts/rockchip/rk3588-base.dtsi:355.39-358.4: Warning (clocks_property): /display-subsystem: Missing property '#clock-cells' in node /phy at fed60000 or bad phandle (referred from clocks[0])
  also defined at arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts:292.20-295.3
arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dtb: display-subsystem: 'clock-names', 'clocks' do not match any of the regexes: 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip-drm.yaml#
arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dtb: pmic at 0: Unevaluated properties are not allowed ('rk806_dvs1_pwrdn' was unexpected)
	from schema $id: http://devicetree.org/schemas/mfd/rockchip,rk806.yaml#
arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dtb: pcie at fe170000: Unevaluated properties are not allowed ('rockchip,skip-scan-in-resume' was unexpected)
	from schema $id: http://devicetree.org/schemas/pci/rockchip-dw-pcie.yaml#







From robh at kernel.org  Mon Dec 16 08:29:22 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 16 Dec 2024 10:29:22 -0600
Subject: [PATCH v2 00/11] Add eDP support for RK3588
In-Reply-To: <20241216031225.3746-1-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
Message-ID: <173436598997.265439.13057492933592323468.robh@kernel.org>


On Mon, 16 Dec 2024 11:12:14 +0800, Damon Ding wrote:
> These patchs have been tested with a 1536x2048p60 eDP panel on
> RK3588S EVB1 board, and HDMI 1080P/4K display also has been verified
> on RK3588 EVB1 board.
> 
> Patch 1~3 are the RK3588 eDP support of Rockchip analogix_dp driver.
> Patch 4   is the eDP mode support of samsung hdptx phy driver.
> Patch 5~6 are the Rk3588 eDP support of Aanalogix DP driver. Add phy
>           interfaces is to configure the HDMI/eDP TX Combo PHY.
> Patch 7~8 are the renaming of hdptxphy node. It is not only used by
>           HDMI display but also for the eDP display.
> Patch 9   is the addition of RK3588 eDP0 node.
> Patch 10  is to enable the eDP0 display on RK3588S EVB1 board.
> Patch 11  is to add the eDP1 related nodes for RK3588 SoC.
> 
> Damon Ding (11):
>   drm/rockchip: analogix_dp: Use formalized struct definition for grf
>     field
>   dt-bindings: display: rockchip: analogix-dp: Add support for RK3588
>   drm/rockchip: analogix_dp: Add support for RK3588
>   phy: phy-rockchip-samsung-hdptx: Add support for eDP mode
>   drm/bridge: analogix_dp: add support for RK3588
>   drm/bridge: analogix_dp: Add support for phy configuration.
>   dt-bindings: display: rockchip: Fix label name of hdptxphy for RK3588
>     HDMI TX Controller
>   arm64: dts: rockchip: Fix label name of hdptxphy for RK3588
>   arm64: dts: rockchip: Add eDP0 node for RK3588
>   arm64: dts: rockchip: Enable eDP0 display on RK3588S EVB1 board
>   arm64: dts: rockchip: Add nodes related to eDP1 for RK3588
> 
>  .../rockchip/rockchip,analogix-dp.yaml        |   1 +
>  .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml  |   2 +-
>  arch/arm64/boot/dts/rockchip/rk3588-base.dtsi |  33 +-
>  .../dts/rockchip/rk3588-coolpi-cm5-evb.dts    |   2 +-
>  .../rockchip/rk3588-coolpi-cm5-genbook.dts    |   2 +-
>  .../boot/dts/rockchip/rk3588-evb1-v10.dts     |   2 +-
>  .../arm64/boot/dts/rockchip/rk3588-extra.dtsi |  55 +
>  .../rk3588-friendlyelec-cm3588-nas.dts        |   2 +-
>  .../arm64/boot/dts/rockchip/rk3588-jaguar.dts |   2 +-
>  .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi   |   2 +-
>  .../dts/rockchip/rk3588-orangepi-5-plus.dts   |   2 +-
>  .../boot/dts/rockchip/rk3588-rock-5b.dts      |   2 +-
>  .../boot/dts/rockchip/rk3588-tiger-haikou.dts |   2 +-
>  .../boot/dts/rockchip/rk3588s-coolpi-4b.dts   |   2 +-
>  .../boot/dts/rockchip/rk3588s-evb1-v10.dts    |  50 +
>  .../dts/rockchip/rk3588s-indiedroid-nova.dts  |   2 +-
>  .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi  |   2 +-
>  .../boot/dts/rockchip/rk3588s-odroid-m2.dts   |   2 +-
>  .../boot/dts/rockchip/rk3588s-orangepi-5.dtsi |   2 +-
>  .../boot/dts/rockchip/rk3588s-rock-5a.dts     |   2 +-
>  .../boot/dts/rockchip/rk3588s-rock-5c.dts     |   2 +-
>  .../drm/bridge/analogix/analogix_dp_core.c    |   5 +
>  .../gpu/drm/bridge/analogix/analogix_dp_reg.c |  56 ++
>  .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 149 ++-
>  .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 937 +++++++++++++++++-
>  include/drm/bridge/analogix_dp.h              |   3 +-
>  26 files changed, 1223 insertions(+), 100 deletions(-)
> 
> --
> 2.34.1
> 
> 
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y rockchip/rk3588-coolpi-cm5-evb.dtb rockchip/rk3588-coolpi-cm5-genbook.dtb rockchip/rk3588-evb1-v10.dtb rockchip/rk3588-friendlyelec-cm3588-nas.dtb rockchip/rk3588-jaguar.dtb rockchip/rk3588-orangepi-5-plus.dtb rockchip/rk3588-rock-5b.dtb rockchip/rk3588-tiger-haikou.dtb rockchip/rk3588s-coolpi-4b.dtb rockchip/rk3588s-evb1-v10.dtb rockchip/rk3588s-indiedroid-nova.dtb rockchip/rk3588s-odroid-m2.dtb rockchip/rk3588s-rock-5a.dtb rockchip/rk3588s-rock-5c.dtb' for 20241216031225.3746-1-damon.ding at rock-chips.com:

arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dtb: edp at fdec0000: resets: [[28, 469], [28, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dtb: edp at fdec0000: Unevaluated properties are not allowed ('#sound-dai-cells', 'reset-names', 'resets' were unexpected)
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fded0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fded0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fded0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fded0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fded0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fded0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fded0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fded0000: clock-names:2: 'grf' was expected
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#







From robh at kernel.org  Mon Dec 16 08:30:55 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 16 Dec 2024 10:30:55 -0600
Subject: [PATCH RESEND 1/2] dt-bindings: timer: fsl,imxgpt: Fix the
 fsl,imx7d-gpt fallback
In-Reply-To: <20241202132147.587799-1-festevam@gmail.com>
References: <20241202132147.587799-1-festevam@gmail.com>
Message-ID: <173436661185.273479.1114801374109487075.robh@kernel.org>


On Mon, 02 Dec 2024 10:21:46 -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> imx7s.dtsi correctly describes the GPT node as:
> 
> compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt";
> 
> Document the fallback compatible to be "fsl,imx6dl-gpt" in the bindings.
> 
> This fixes the following dt-schema warnings:
> 
> timer at 302f0000: compatible: 'oneOf' conditional failed, one must be fixed:
> 	['fsl,imx7d-gpt', 'fsl,imx6dl-gpt'] is too long
> 	'fsl,imx1-gpt' was expected
> 	'fsl,imx21-gpt' was expected
> 	'fsl,imx27-gpt' was expected
> 	'fsl,imx31-gpt' was expected
> 	'fsl,imx7d-gpt' is not one of ['fsl,imx25-gpt', 'fsl,imx50-gpt', 'fsl,imx51-gpt', 'fsl,imx53-gpt', 'fsl,imx6q-gpt']
> 	'fsl,imx6dl-gpt' was expected
> 	'fsl,imx7d-gpt' is not one of ['fsl,imx6sl-gpt', 'fsl,imx6sx-gpt', 'fsl,imx8mp-gpt', 'fsl,imxrt1050-gpt', 'fsl,imxrt1170-gpt']
> 	'fsl,imx6sx-gpt' was expected
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>
> Reviewed-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> ---
>  Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Applied, thanks!



From robh at kernel.org  Mon Dec 16 08:31:09 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 16 Dec 2024 10:31:09 -0600
Subject: [PATCH RESEND 2/2] dt-bindings: timer: fsl,imxgpt: Document
 fsl,imx35-gpt
In-Reply-To: <20241202132147.587799-2-festevam@gmail.com>
References: <20241202132147.587799-1-festevam@gmail.com>
 <20241202132147.587799-2-festevam@gmail.com>
Message-ID: <173436664990.274185.16737357220255320262.robh@kernel.org>


On Mon, 02 Dec 2024 10:21:47 -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> The i.MX35 General Purpose Timer is compatible with i.MX31.
> 
> Document the fsl,imx35-gpt compatible.
> 
> This fixes the following dt-schema warning:
> 
> timer at 53f90000: compatible: 'oneOf' conditional failed, one must be fixed:
> 	['fsl,imx35-gpt', 'fsl,imx31-gpt'] is too long
> 	'fsl,imx1-gpt' was expected
> 	'fsl,imx21-gpt' was expected
> 	'fsl,imx27-gpt' was expected
> 	'fsl,imx31-gpt' was expected
> 	'fsl,imx35-gpt' is not one of ['fsl,imx25-gpt', 'fsl,imx50-gpt', 'fsl,imx51-gpt', 'fsl,imx53-gpt', 'fsl,imx6q-gpt']
> 	'fsl,imx6dl-gpt' was expected
> 	'fsl,imx35-gpt' is not one of ['fsl,imx6sl-gpt', 'fsl,imx6sx-gpt', 'fsl,imx8mp-gpt', 'fsl,imxrt1050-gpt', 'fsl,imxrt1170-gpt']
> 	'fsl,imx35-gpt' is not one of ['fsl,imx6ul-gpt', 'fsl,imx7d-gpt']
> 	'fsl,imx6sx-gpt' was expected
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>
> Reviewed-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> ---
>  Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Applied, thanks!



From Frank.li at nxp.com  Mon Dec 16 08:35:02 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 16 Dec 2024 11:35:02 -0500
Subject: [PATCH v1] i2c: imx: fix missing stop condition in single-master
 mode
In-Reply-To: <20241216151829.74056-1-eichest@gmail.com>
References: <20241216151829.74056-1-eichest@gmail.com>
Message-ID: <Z2BWtjPT1sTUCZ82@lizhi-Precision-Tower-5810>

On Mon, Dec 16, 2024 at 04:16:40PM +0100, Stefan Eichenberger wrote:
> From: Stefan Eichenberger <stefan.eichenberger at toradex.com>
>
> A regression was introduced with the implementation of single-master
> mode, preventing proper stop conditions from being generated. Devices
> that require a valid stop condition, such as EEPROMs, fail to function
> correctly as a result.
>
> The issue only affects devices with the single-master property enabled.
>
> This commit resolves the issue by re-enabling I2C bus busy bit (IBB)
> polling for single-master mode when generating a stop condition. The fix
> further ensures that the i2c_imx->stopped flag is cleared at the start
> of each transfer, allowing the stop condition to be correctly generated
> in i2c_imx_stop().
>
> According to the reference manual (IMX8MMRM, Rev. 2, 09/2019, page
> 5270), polling the IBB bit to determine if the bus is free is only
> necessary in multi-master mode. Consequently, the IBB bit is not polled
> for the start condition in single-master mode.
>
> Fixes: 6692694aca86 ("i2c: imx: do not poll for bus busy in single master mode")
> Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>
> ---
>  drivers/i2c/busses/i2c-imx.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index f751d231ded8..cbf66a69e20b 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -534,20 +534,18 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a
>  {
>  	unsigned long orig_jiffies = jiffies;
>  	unsigned int temp;
> -
> -	if (!i2c_imx->multi_master)
> -		return 0;
> +	bool multi_master = i2c_imx->multi_master;

Move "bool multi_master = i2c_imx->multi_master;" before
"unsigned long orig_jiffies = jiffies;" to keep reverse christmas tree
order.

Reviewed-by: Frank Li <Frank.Li at nxp.com>

>
>  	while (1) {
>  		temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
>
>  		/* check for arbitration lost */
> -		if (temp & I2SR_IAL) {
> +		if (multi_master && (temp & I2SR_IAL)) {
>  			i2c_imx_clear_irq(i2c_imx, I2SR_IAL);
>  			return -EAGAIN;
>  		}
>
> -		if (for_busy && (temp & I2SR_IBB)) {
> +		if (for_busy && (!multi_master || (temp & I2SR_IBB))) {
>  			i2c_imx->stopped = 0;
>  			break;
>  		}
> --
> 2.45.2
>


From Frank.li at nxp.com  Mon Dec 16 08:39:50 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 16 Dec 2024 11:39:50 -0500
Subject: [PATCH v3 2/5] ASoC: dt-bindings: support imx95's CM7 core
In-Reply-To: <20241216145039.3074-3-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
 <20241216145039.3074-3-laurentiumihalcea111@gmail.com>
Message-ID: <Z2BX1nfd3Y2FYQXf@lizhi-Precision-Tower-5810>

On Mon, Dec 16, 2024 at 09:50:36AM -0500, Laurentiu Mihalcea wrote:
> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>
> Add binding for imx95's CM7 core, used for audio processing.
>
> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> ---
>  .../bindings/sound/fsl,imx95-cm7-sof.yaml     | 44 +++++++++++++++++++
>  1 file changed, 44 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml
>
> diff --git a/Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml b/Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml
> new file mode 100644
> index 000000000000..cc1eb358f288
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml
> @@ -0,0 +1,44 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/fsl,imx95-cm7-sof.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP imx95 CM7 core
> +
> +maintainers:
> +  - Daniel Baluta <daniel.baluta at nxp.com>
> +
> +description: NXP imx95 CM7 core used for audio processing
> +
> +allOf:
> +  - $ref: fsl,sof-cpu.yaml#
> +

Generally, allOf should be move just before unevaluatedProperties in
case need if-else-then in future.

Frank

> +properties:
> +  compatible:
> +    const: fsl,imx95-cm7-sof
> +
> +  port:
> +    description: SAI3 port
> +    $ref: audio-graph-port.yaml#
> +    unevaluatedProperties: false
> +
> +required:
> +  - compatible
> +  - port
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    cm7-cpu at 80000000 {
> +        compatible = "fsl,imx95-cm7-sof";
> +        reg = <0x80000000 0x6100000>;
> +        mboxes = <&mu7 2 0>, <&mu7 2 1>, <&mu7 3 0>, <&mu7 3 1>;
> +        mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";
> +        memory-region = <&adma_res>;
> +        port {
> +          /* SAI3-WM8962 link */
> +          endpoint { remote-endpoint = <&wm8962_ep>; };
> +        };
> +    };
> --
> 2.34.1
>


From Frank.li at nxp.com  Mon Dec 16 08:42:27 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 16 Dec 2024 11:42:27 -0500
Subject: [PATCH v3 1/5] ASoC: dt-bindings: add common binding for NXP
 audio processors
In-Reply-To: <20241216145039.3074-2-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
 <20241216145039.3074-2-laurentiumihalcea111@gmail.com>
Message-ID: <Z2BYcw6x3zyeBwvE@lizhi-Precision-Tower-5810>

On Mon, Dec 16, 2024 at 09:50:35AM -0500, Laurentiu Mihalcea wrote:
> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>
> Add common binding for NXP audio processors with Sound Open Firmware
> (SOF) support.
>
> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> ---
>  .../bindings/sound/fsl,sof-cpu.yaml           | 35 +++++++++++++++++++
>  1 file changed, 35 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml

You create common file, could you please change existed binding yaml to
use it also?

Frank

>
> diff --git a/Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml b/Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml
> new file mode 100644
> index 000000000000..1958afceba75
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml
> @@ -0,0 +1,35 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/fsl,sof-cpu.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP audio processor common properties
> +
> +maintainers:
> +  - Daniel Baluta <daniel.baluta at nxp.com>
> +
> +properties:
> +  reg:
> +    maxItems: 1
> +
> +  mboxes:
> +    maxItems: 4
> +
> +  mbox-names:
> +    items:
> +      - const: txdb0
> +      - const: txdb1
> +      - const: rxdb0
> +      - const: rxdb1
> +
> +  memory-region:
> +    maxItems: 1
> +
> +required:
> +  - reg
> +  - mboxes
> +  - mbox-names
> +  - memory-region
> +
> +additionalProperties: true
> --
> 2.34.1
>


From suzuki.poulose at arm.com  Mon Dec 16 08:45:21 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 16 Dec 2024 16:45:21 +0000
Subject: [PATCH v6 03/43] arm64: RME: Handle Granule Protection Faults
 (GPFs)
In-Reply-To: <20241212155610.76522-4-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
 <20241212155610.76522-4-steven.price@arm.com>
Message-ID: <6036b1a0-608b-4fff-a2f3-63eff2d52338@arm.com>

On 12/12/2024 15:55, Steven Price wrote:
> If the host attempts to access granules that have been delegated for use
> in a realm these accesses will be caught and will trigger a Granule
> Protection Fault (GPF).
> 
> A fault during a page walk signals a bug in the kernel and is handled by
> oopsing the kernel. A non-page walk fault could be caused by user space
> having access to a page which has been delegated to the kernel and will
> trigger a SIGBUS to allow debugging why user space is trying to access a
> delegated page.
> 
> Signed-off-by: Steven Price <steven.price at arm.com>

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




From Frank.li at nxp.com  Mon Dec 16 08:48:57 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 16 Dec 2024 11:48:57 -0500
Subject: [PATCH v3 4/5] ASoC: SOF: imx: add driver for imx95
In-Reply-To: <20241216145039.3074-5-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
 <20241216145039.3074-5-laurentiumihalcea111@gmail.com>
Message-ID: <Z2BZ+WUY6ecIwhEt@lizhi-Precision-Tower-5810>

On Mon, Dec 16, 2024 at 09:50:38AM -0500, Laurentiu Mihalcea wrote:
> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>
> Add SOF driver for imx95.
>
> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> ---
>  sound/soc/sof/imx/Kconfig  |   8 +
>  sound/soc/sof/imx/Makefile |   2 +
>  sound/soc/sof/imx/imx95.c  | 401 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 411 insertions(+)
>  create mode 100644 sound/soc/sof/imx/imx95.c
>
> diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig
> index 4751b04d5e6f..51a70a193533 100644
> --- a/sound/soc/sof/imx/Kconfig
> +++ b/sound/soc/sof/imx/Kconfig
> @@ -50,4 +50,12 @@ config SND_SOC_SOF_IMX8ULP
>  	  Say Y if you have such a device.
>  	  If unsure select "N".
>
> +config SND_SOC_SOF_IMX95
> +	tristate "SOF support for i.MX95"
> +	depends on IMX_DSP
> +	help
> +	  This adds support for Sound Open Firmware for NXP i.MX95 platforms.
> +	  Say Y if you have such a device.
> +	  If unsure select "N".
> +
>  endif ## SND_SOC_SOF_IMX_TOPLEVEL
> diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile
> index be0bf0736dfa..715ac3798668 100644
> --- a/sound/soc/sof/imx/Makefile
> +++ b/sound/soc/sof/imx/Makefile
> @@ -2,10 +2,12 @@
>  snd-sof-imx8-y := imx8.o
>  snd-sof-imx8m-y := imx8m.o
>  snd-sof-imx8ulp-y := imx8ulp.o
> +snd-sof-imx95-y := imx95.o
>
>  snd-sof-imx-common-y := imx-common.o
>
>  obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o
>  obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o
>  obj-$(CONFIG_SND_SOC_SOF_IMX8ULP) += snd-sof-imx8ulp.o
> +obj-$(CONFIG_SND_SOC_SOF_IMX95) += snd-sof-imx95.o
>  obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o
> diff --git a/sound/soc/sof/imx/imx95.c b/sound/soc/sof/imx/imx95.c
> new file mode 100644
> index 000000000000..5a0e44f5bd48
> --- /dev/null
> +++ b/sound/soc/sof/imx/imx95.c
> @@ -0,0 +1,401 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/clk.h>
> +#include <linux/firmware/imx/dsp.h>
> +#include <linux/module.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_reserved_mem.h>
> +#include <sound/sof.h>
> +
> +#include "../sof-of-dev.h"
> +#include "../ops.h"
> +
> +#define IMX_SIP_SRC 0xC2000005
> +#define IMX_SIP_SRC_M_RESET_ADDR_SET 0x03
> +
> +#define IMX95_CPU_VEC_FLAGS_BOOT BIT(29)
> +
> +#define IMX_SIP_LMM 0xC200000F
> +#define IMX_SIP_LMM_BOOT 0x0
> +#define IMX_SIP_LMM_SHUTDOWN 0x1
> +
> +#define IMX95_M7_LM_ID 0x1
> +
> +#define MBOX_DSPBOX_OFFSET 0x1000
> +#define MBOX_WINDOW_OFFSET 0x6000000
> +
> +struct imx95_priv {
> +	struct platform_device *ipc_dev;
> +	struct imx_dsp_ipc *ipc_handle;
> +	resource_size_t bootaddr;
> +};
> +
> +static void imx95_ipc_handle_reply(struct imx_dsp_ipc *ipc)
> +{
> +	unsigned long flags;
> +	struct snd_sof_dev *sdev = imx_dsp_get_data(ipc);
> +
> +	spin_lock_irqsave(&sdev->ipc_lock, flags);
> +	snd_sof_ipc_process_reply(sdev, 0);
> +	spin_unlock_irqrestore(&sdev->ipc_lock, flags);
> +}
> +
> +static void imx95_ipc_handle_request(struct imx_dsp_ipc *ipc)
> +{
> +	snd_sof_ipc_msgs_rx(imx_dsp_get_data(ipc));
> +}
> +
> +static struct imx_dsp_ops ipc_ops = {
> +	.handle_reply = imx95_ipc_handle_reply,
> +	.handle_request = imx95_ipc_handle_request,
> +};
> +
> +static int imx95_disable_enable_core(bool enable)
> +{
> +	struct arm_smccc_res res;
> +
> +	if (enable)
> +		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_BOOT, IMX95_M7_LM_ID,
> +			      0, 0, 0, 0, 0, &res);
> +	else
> +		arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_SHUTDOWN, IMX95_M7_LM_ID,
> +			      0, 0, 0, 0, 0, &res);
> +
> +	return res.a0;
> +}
> +
> +static int imx95_run(struct snd_sof_dev *sdev)
> +{
> +	return imx95_disable_enable_core(true);
> +}
> +
> +static int imx95_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
> +{
> +	struct imx95_priv *priv = sdev->pdata->hw_pdata;
> +
> +	sof_mailbox_write(sdev, sdev->host_box.offset,
> +			  msg->msg_data, msg->msg_size);
> +
> +	imx_dsp_ring_doorbell(priv->ipc_handle, 0);
> +
> +	return 0;
> +}
> +
> +static int imx95_get_mailbox_offset(struct snd_sof_dev *sdev)
> +{
> +	return MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
> +}
> +
> +static int imx95_get_bar_index(struct snd_sof_dev *sdev, u32 type)
> +{
> +	switch (type) {
> +	case SOF_FW_BLK_TYPE_SRAM:
> +		return type;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int imx95_get_window_offset(struct snd_sof_dev *sdev, u32 id)
> +{
> +	return MBOX_WINDOW_OFFSET;
> +}
> +
> +static int imx95_set_power_state(struct snd_sof_dev *sdev,
> +				 const struct sof_dsp_power_state *target_state)
> +{
> +	sdev->dsp_power_state = *target_state;
> +
> +	return 0;
> +}
> +
> +static int imx95_suspend_resume(struct snd_sof_dev *sdev, bool suspend)
> +{
> +	struct imx95_priv *priv;
> +	int ret, i;
> +
> +	priv = sdev->pdata->hw_pdata;
> +
> +	if (suspend) {
> +		ret = imx95_disable_enable_core(false);
> +		if (ret) {
> +			dev_err(sdev->dev, "failed to stop core\n");
> +			return ret;
> +		}
> +	}
> +
> +	for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
> +		if (suspend)
> +			imx_dsp_free_channel(priv->ipc_handle, i);
> +		else
> +			imx_dsp_request_channel(priv->ipc_handle, i);
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx95_runtime_resume(struct snd_sof_dev *sdev)
> +{
> +	int ret;
> +	const struct sof_dsp_power_state target_state = {
> +		.state = SOF_DSP_PM_D0,
> +	};
> +
> +	ret = imx95_suspend_resume(sdev, false);
> +	if (ret < 0) {
> +		dev_err(sdev->dev, "failed to runtime resume: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
> +}
> +
> +static int imx95_resume(struct snd_sof_dev *sdev)
> +{
> +	int ret;
> +	const struct sof_dsp_power_state target_state = {
> +		.state = SOF_DSP_PM_D0,
> +	};
> +
> +	ret = imx95_suspend_resume(sdev, false);
> +	if (ret < 0) {
> +		dev_err(sdev->dev, "failed to resume: %d\n", ret);
> +		return ret;
> +	}
> +
> +	if (pm_runtime_suspended(sdev->dev)) {
> +		pm_runtime_disable(sdev->dev);
> +		pm_runtime_set_active(sdev->dev);
> +		pm_runtime_mark_last_busy(sdev->dev);
> +		pm_runtime_enable(sdev->dev);
> +		pm_runtime_idle(sdev->dev);
> +	}
> +
> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
> +}
> +
> +static int imx95_runtime_suspend(struct snd_sof_dev *sdev)
> +{
> +	int ret;
> +	const struct sof_dsp_power_state target_state = {
> +		.state = SOF_DSP_PM_D3,
> +	};
> +
> +	ret = imx95_suspend_resume(sdev, true);
> +	if (ret < 0) {
> +		dev_err(sdev->dev, "failed to runtime suspend: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return snd_sof_dsp_set_power_state(sdev, &target_state);
> +}
> +
> +static int imx95_suspend(struct snd_sof_dev *sdev, unsigned int target_state)
> +{
> +	int ret;
> +	const struct sof_dsp_power_state target_power_state = {
> +		.state = target_state,
> +	};
> +
> +	if (!pm_runtime_suspended(sdev->dev)) {
> +		ret = imx95_suspend_resume(sdev, true);
> +		if (ret < 0) {
> +			dev_err(sdev->dev, "failed to suspend: %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	return snd_sof_dsp_set_power_state(sdev, &target_power_state);
> +}
> +
> +static struct snd_soc_dai_driver imx95_dai[] = {
> +	{
> +		.name = "sai3",
> +		.playback = {
> +			.channels_min = 1,
> +			.channels_max = 32,
> +		},
> +		.capture = {
> +			.channels_min = 1,
> +			.channels_max = 32,
> +		},
> +	},
> +};
> +
> +static int imx95_probe(struct snd_sof_dev *sdev)
> +{
> +	struct platform_device *pdev;
> +	struct imx95_priv *priv;
> +	struct resource *res;
> +	struct arm_smccc_res smc_ret;
> +	int ret;
> +
> +	pdev = container_of(sdev->dev, struct platform_device, dev);
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return dev_err_probe(&pdev->dev, -ENOMEM, "failed to alloc priv\n");
> +
> +	sdev->pdata->hw_pdata = priv;
> +
> +	/* map SRAM */
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return dev_err_probe(&pdev->dev, -ENODEV,
> +				     "failed to fetch SRAM region\n");
> +
> +	sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap(&pdev->dev, res->start,
> +						       resource_size(res));
> +	if (IS_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]))
> +		return dev_err_probe(&pdev->dev,
> +				     PTR_ERR(sdev->bar[SOF_FW_BLK_TYPE_SRAM]),
> +				     "failed to map SRAM region\n");
> +
> +	sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
> +	sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
> +	sdev->dsp_box.offset = MBOX_DSPBOX_OFFSET + MBOX_WINDOW_OFFSET;
> +	priv->bootaddr = res->start;
> +
> +	ret = of_reserved_mem_device_init(sdev->dev);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret,
> +				     "failed to bind DMA region\n");
> +
> +	priv->ipc_dev = platform_device_register_data(&pdev->dev, "imx-dsp",
> +						      PLATFORM_DEVID_NONE,
> +						      pdev, sizeof(*pdev));
> +	if (IS_ERR(priv->ipc_dev))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->ipc_dev),
> +				     "failed to create IPC device\n");
> +
> +	priv->ipc_handle = dev_get_drvdata(&priv->ipc_dev->dev);
> +	if (!priv->ipc_handle) {
> +		ret = -EPROBE_DEFER;
> +		dev_err(&pdev->dev, "failed to fetch ipc handle\n");
> +		goto err_unregister_ipc_dev;
> +	}
> +
> +	priv->ipc_handle->ops = &ipc_ops;
> +	imx_dsp_set_data(priv->ipc_handle, sdev);
> +
> +	/* set core boot reset address */
> +	arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M_RESET_ADDR_SET, priv->bootaddr,
> +		      IMX95_CPU_VEC_FLAGS_BOOT, 0, 0, 0, 0, &smc_ret);
> +	if ((int)smc_ret.a0 < 0) {
> +		ret = smc_ret.a0;
> +		dev_err(&pdev->dev, "failed to set boot address: %d", ret);
> +		goto err_unregister_ipc_dev;
> +	}
> +
> +	return 0;
> +
> +err_unregister_ipc_dev:
> +	platform_device_unregister(priv->ipc_dev);

If use devm_add_action(), this and imx95_remove() can be removed.

Frank

> +
> +	return ret;
> +}
> +
> +static void imx95_remove(struct snd_sof_dev *sdev)
> +{
> +	struct imx95_priv *priv;
> +
> +	priv = sdev->pdata->hw_pdata;
> +
> +	if (imx95_disable_enable_core(false))
> +		dev_err(sdev->dev, "failed to stop core\n");
> +
> +	platform_device_unregister(priv->ipc_dev);
> +}
> +
> +static const struct snd_sof_dsp_ops sof_imx95_ops = {
> +	.probe = imx95_probe,
> +	.remove = imx95_remove,
> +
> +	/* mandatory "DSP" ops */
> +	.run = imx95_run,
> +	.block_read = sof_block_read,
> +	.block_write = sof_block_write,
> +	.send_msg = imx95_send_msg,
> +	.load_firmware = snd_sof_load_firmware_memcpy,
> +	.ipc_msg_data = sof_ipc_msg_data,
> +
> +	.mailbox_read = sof_mailbox_read,
> +	.mailbox_write = sof_mailbox_write,
> +
> +	.get_mailbox_offset = imx95_get_mailbox_offset,
> +	.get_bar_index = imx95_get_bar_index,
> +	.get_window_offset = imx95_get_window_offset,
> +
> +	.pcm_open = sof_stream_pcm_open,
> +	.pcm_close = sof_stream_pcm_close,
> +	.set_stream_data_offset = sof_set_stream_data_offset,
> +
> +	.runtime_suspend = imx95_runtime_suspend,
> +	.runtime_resume = imx95_runtime_resume,
> +
> +	.resume = imx95_resume,
> +	.suspend = imx95_suspend,
> +
> +	.set_power_state = imx95_set_power_state,
> +
> +	.drv = imx95_dai,
> +	.num_drv = ARRAY_SIZE(imx95_dai),
> +
> +	.hw_info = SNDRV_PCM_INFO_MMAP |
> +		   SNDRV_PCM_INFO_MMAP_VALID |
> +		   SNDRV_PCM_INFO_INTERLEAVED |
> +		   SNDRV_PCM_INFO_PAUSE |
> +		   SNDRV_PCM_INFO_BATCH |
> +		   SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
> +};
> +
> +static struct snd_sof_of_mach sof_imx95_machs[] = {
> +	{
> +		.compatible = "fsl,imx95-19x19-evk",
> +		.sof_tplg_filename = "sof-imx95-wm8962.tplg",
> +		.drv_name = "asoc-audio-graph-card2",
> +	},
> +	{
> +	},
> +};
> +
> +static struct sof_dev_desc sof_of_imx95_desc = {
> +	.of_machines = sof_imx95_machs,
> +	.ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
> +	.ipc_default = SOF_IPC_TYPE_3,
> +	.default_fw_path = {
> +		[SOF_IPC_TYPE_3] = "imx/sof",
> +	},
> +	.default_tplg_path = {
> +		[SOF_IPC_TYPE_3] = "imx/sof-tplg",
> +	},
> +	.default_fw_filename = {
> +		[SOF_IPC_TYPE_3] = "sof-imx95.ri",
> +	},
> +	.ops = &sof_imx95_ops,
> +};
> +
> +static const struct of_device_id sof_of_imx95_ids[] = {
> +	{ .compatible = "fsl,imx95-cm7-sof", .data = &sof_of_imx95_desc },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, sof_of_imx95_ids);
> +
> +static struct platform_driver snd_sof_of_imx95_driver = {
> +	.probe = sof_of_probe,
> +	.remove = sof_of_remove,
> +	.driver = {
> +		.name = "sof-audio-of-imx95",
> +		.pm = &sof_of_pm,
> +		.of_match_table = sof_of_imx95_ids,
> +	},
> +};
> +module_platform_driver(snd_sof_of_imx95_driver);
> +
> +MODULE_LICENSE("Dual BSD/GPL");
> +MODULE_DESCRIPTION("SOF support for i.MX95 platforms");
> +MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>");
> --
> 2.34.1
>


From mathieu.poirier at linaro.org  Mon Dec 16 08:51:13 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 16 Dec 2024 09:51:13 -0700
Subject: [PATCH v2] remoteproc: mtk_scp: Only populate devices for SCP
 cores
In-Reply-To: <20241211072009.120511-1-wenst@chromium.org>
References: <20241211072009.120511-1-wenst@chromium.org>
Message-ID: <Z2Baga9gSFLlmXll@p14s>

On Wed, Dec 11, 2024 at 03:20:07PM +0800, Chen-Yu Tsai wrote:
> When multi-core SCP support was added, the driver was made to populate
> platform devices for all the sub-nodes. This ended up adding platform
> devices for the rpmsg sub-nodes as well, which never actually get used,
> since rpmsg devices are registered through the rpmsg interface.
> 
> Limit of_platform_populate() to just populating the SCP cores with a
> compatible string match list.
> 
> Fixes: 1fdbf0cdde98 ("remoteproc: mediatek: Probe SCP cluster on multi-core SCP")
> Cc: Tinghan Shen <tinghan.shen at mediatek.com>
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
> Changes since v1:
> - Fix commit subject: populate devices *for* SCP cores
> ---
>  drivers/remoteproc/mtk_scp.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>

I have applied this patch.

Thanks,
Mathieu

> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> index 0f4a7065d0bd..8206a1766481 100644
> --- a/drivers/remoteproc/mtk_scp.c
> +++ b/drivers/remoteproc/mtk_scp.c
> @@ -1326,6 +1326,11 @@ static int scp_cluster_init(struct platform_device *pdev, struct mtk_scp_of_clus
>  	return ret;
>  }
>  
> +static const struct of_device_id scp_core_match[] = {
> +	{ .compatible = "mediatek,scp-core" },
> +	{}
> +};
> +
>  static int scp_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -1357,13 +1362,15 @@ static int scp_probe(struct platform_device *pdev)
>  	INIT_LIST_HEAD(&scp_cluster->mtk_scp_list);
>  	mutex_init(&scp_cluster->cluster_lock);
>  
> -	ret = devm_of_platform_populate(dev);
> +	ret = of_platform_populate(dev_of_node(dev), scp_core_match, NULL, dev);
>  	if (ret)
>  		return dev_err_probe(dev, ret, "Failed to populate platform devices\n");
>  
>  	ret = scp_cluster_init(pdev, scp_cluster);
> -	if (ret)
> +	if (ret) {
> +		of_platform_depopulate(dev);
>  		return ret;
> +	}
>  
>  	return 0;
>  }
> @@ -1379,6 +1386,7 @@ static void scp_remove(struct platform_device *pdev)
>  		rproc_del(scp->rproc);
>  		scp_free(scp);
>  	}
> +	of_platform_depopulate(&pdev->dev);
>  	mutex_destroy(&scp_cluster->cluster_lock);
>  }
>  
> -- 
> 2.47.0.338.g60cca15819-goog
> 


From mripard at kernel.org  Mon Dec 16 09:04:41 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 16 Dec 2024 18:04:41 +0100
Subject: [PATCH v6 03/10] drm/connector: implement generic HDMI codec
 helpers
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-3-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-3-50dc145a9c06@linaro.org>
Message-ID: <20241216-heretic-mackerel-of-wholeness-fcfed7@houat>

Hi,

On Fri, Dec 06, 2024 at 12:15:57PM +0200, Dmitry Baryshkov wrote:
> Several DRM drivers implement HDMI codec support (despite its name it
> applies to both HDMI and DisplayPort drivers). Implement generic
> framework to be used by these drivers. This removes a requirement to
> implement get_eld() callback and provides default implementation for
> codec's plug handling.
> 
> The framework is integrated with the DRM HDMI Connector framework, but
> can be used by DisplayPort drivers.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/Makefile                   |   1 +
>  drivers/gpu/drm/drm_connector.c            |   5 +
>  drivers/gpu/drm/drm_connector_hdmi_codec.c | 185 +++++++++++++++++++++++++++++
>  include/drm/drm_connector.h                |  80 +++++++++++++
>  4 files changed, 271 insertions(+)
> 
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 1677c1f335fbb0c6114bdb4cc0b12eb407d84564..afdd9268ca23ac7602e73bbe45f3f9cd090a3afd 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -42,6 +42,7 @@ drm-y := \
>  	drm_cache.o \
>  	drm_color_mgmt.o \
>  	drm_connector.o \
> +	drm_connector_hdmi_codec.o \
>  	drm_crtc.o \
>  	drm_displayid.o \
>  	drm_drv.o \
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index bbdaaf7022b62d84594a29f1b60144920903a99a..4abfbded962bf45b793a2bd5b1b5c4d9f478a1f7 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -33,6 +33,7 @@
>  #include <drm/drm_sysfs.h>
>  #include <drm/drm_utils.h>
>  
> +#include <linux/platform_device.h>
>  #include <linux/property.h>
>  #include <linux/uaccess.h>
>  
> @@ -280,6 +281,7 @@ static int __drm_connector_init(struct drm_device *dev,
>  	mutex_init(&connector->eld_mutex);
>  	mutex_init(&connector->edid_override_mutex);
>  	mutex_init(&connector->hdmi.infoframes.lock);
> +	mutex_init(&connector->hdmi_codec.lock);
>  	connector->edid_blob_ptr = NULL;
>  	connector->epoch_counter = 0;
>  	connector->tile_blob_ptr = NULL;
> @@ -632,6 +634,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
>  		    DRM_CONNECTOR_REGISTERED))
>  		drm_connector_unregister(connector);
>  
> +	platform_device_unregister(connector->hdmi_codec.codec_pdev);
> +
>  	if (connector->privacy_screen) {
>  		drm_privacy_screen_put(connector->privacy_screen);
>  		connector->privacy_screen = NULL;
> @@ -670,6 +674,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
>  		connector->funcs->atomic_destroy_state(connector,
>  						       connector->state);
>  
> +	mutex_destroy(&connector->hdmi_codec.lock);
>  	mutex_destroy(&connector->hdmi.infoframes.lock);
>  	mutex_destroy(&connector->mutex);
>  
> diff --git a/drivers/gpu/drm/drm_connector_hdmi_codec.c b/drivers/gpu/drm/drm_connector_hdmi_codec.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..1934fb53b4d128434559970c9fea548bbc4bedda
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_connector_hdmi_codec.c
> @@ -0,0 +1,185 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright (c) 2024 Linaro Ltd
> + */
> +
> +#include <linux/mutex.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +
> +#include <drm/drm_connector.h>
> +#include <drm/drm_device.h>
> +
> +#include <sound/hdmi-codec.h>
> +
> +static int drm_connector_hdmi_codec_audio_startup(struct device *dev, void *data)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi.funcs->codec_funcs;
> +
> +	if (funcs->audio_startup)
> +		return funcs->audio_startup(connector);
> +
> +	return 0;
> +}
> +
> +static int drm_connector_hdmi_codec_prepare(struct device *dev, void *data,
> +					    struct hdmi_codec_daifmt *fmt,
> +					    struct hdmi_codec_params *hparms)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi.funcs->codec_funcs;
> +
> +	return funcs->prepare(connector, fmt, hparms);
> +}
> +
> +static void drm_connector_hdmi_codec_audio_shutdown(struct device *dev, void *data)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi.funcs->codec_funcs;
> +
> +	return funcs->audio_shutdown(connector);
> +}
> +
> +static int drm_connector_hdmi_codec_mute_stream(struct device *dev, void *data,
> +						bool enable, int direction)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi.funcs->codec_funcs;
> +
> +	if (funcs->mute_stream)
> +		return funcs->mute_stream(connector, enable, direction);
> +
> +	return -ENOTSUPP;
> +}
> +
> +static int drm_connector_hdmi_codec_get_dai_id(struct snd_soc_component *comment,
> +		  struct device_node *endpoint,
> +		  void *data)
> +{
> +	struct drm_connector *connector = data;
> +	struct of_endpoint of_ep;
> +	int ret;
> +
> +	if (connector->hdmi_codec.dai_port < 0)
> +		return -ENOTSUPP;
> +
> +	ret = of_graph_parse_endpoint(endpoint, &of_ep);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (of_ep.port == connector->hdmi_codec.dai_port)
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +
> +static int drm_connector_hdmi_codec_get_eld(struct device *dev, void *data,
> +					    uint8_t *buf, size_t len)
> +{
> +	struct drm_connector *connector = data;
> +
> +	mutex_lock(&connector->eld_mutex);
> +	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
> +	mutex_unlock(&connector->eld_mutex);
> +
> +	return 0;
> +}
> +
> +static int drm_connector_hdmi_codec_hook_plugged_cb(struct device *dev,
> +						    void *data,
> +						    hdmi_codec_plugged_cb fn,
> +						    struct device *codec_dev)
> +{
> +	struct drm_connector *connector = data;
> +
> +	mutex_lock(&connector->hdmi_codec.lock);
> +
> +	connector->hdmi_codec.plugged_cb = fn;
> +	connector->hdmi_codec.plugged_cb_dev = codec_dev;
> +
> +	fn(codec_dev, connector->hdmi_codec.last_state);
> +
> +	mutex_unlock(&connector->hdmi_codec.lock);
> +
> +	return 0;
> +}
> +
> +void drm_connector_hdmi_codec_plugged_notify(struct drm_connector *connector,
> +					     bool plugged)
> +{
> +	mutex_lock(&connector->hdmi_codec.lock);
> +
> +	connector->hdmi_codec.last_state = plugged;
> +
> +	if (connector->hdmi_codec.plugged_cb &&
> +	    connector->hdmi_codec.plugged_cb_dev)
> +		connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev,
> +						 connector->hdmi_codec.last_state);
> +
> +	mutex_unlock(&connector->hdmi_codec.lock);
> +}
> +EXPORT_SYMBOL(drm_connector_hdmi_codec_plugged_notify);
> +
> +static const struct hdmi_codec_ops drm_connector_hdmi_codec_ops = {
> +	.audio_startup = drm_connector_hdmi_codec_audio_startup,
> +	.prepare = drm_connector_hdmi_codec_prepare,
> +	.audio_shutdown = drm_connector_hdmi_codec_audio_shutdown,
> +	.mute_stream = drm_connector_hdmi_codec_mute_stream,
> +	.get_eld = drm_connector_hdmi_codec_get_eld,
> +	.get_dai_id = drm_connector_hdmi_codec_get_dai_id,
> +	.hook_plugged_cb = drm_connector_hdmi_codec_hook_plugged_cb,
> +};
> +
> +/**
> + * drm_connector_hdmi_codec_init - Initialize HDMI Codec device for the DRM connector

I think it'd be better to call it drm_connector_hdmi_audio_init over
drm_connector_hdmi_codec_init (feature over implementation).

> + * @connector: A pointer to the connector to allocate codec for
> + * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
> + * @max_i2s_playback_channels: maximum number of playback I2S channels
> + * @spdif_playback: set if HDMI codec has S/PDIF playback port
> + * @dai_port: sound DAI port, -1 if it is not enabled
> + *
> + * Create a HDMI codec device to be used with the specified connector.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int drm_connector_hdmi_codec_init(struct drm_connector *connector,
> +				  struct device *hdmi_codec_dev,
> +				  unsigned int max_i2s_playback_channels,
> +				  bool spdif_playback,
> +				  int dai_port)
> +{
> +	struct hdmi_codec_pdata codec_pdata = {
> +		.ops = &drm_connector_hdmi_codec_ops,
> +		.max_i2s_channels = max_i2s_playback_channels,
> +		.i2s = !!max_i2s_playback_channels,
> +		.spdif = spdif_playback,
> +		.no_i2s_capture = true,
> +		.no_spdif_capture = true,
> +		.data = connector,
> +	};
> +	struct platform_device *pdev;
> +
> +	connector->hdmi_codec.dai_port = dai_port;
> +
> +	if (!connector->hdmi.funcs->codec_funcs->prepare ||
> +	    !connector->hdmi.funcs->codec_funcs->audio_shutdown)
> +		return -EINVAL;
> +
> +	pdev = platform_device_register_data(hdmi_codec_dev,
> +					     HDMI_CODEC_DRV_NAME,
> +					     PLATFORM_DEVID_AUTO,
> +					     &codec_pdata, sizeof(codec_pdata));
> +	if (IS_ERR(pdev))
> +		return PTR_ERR(pdev);
> +
> +	connector->hdmi_codec.codec_pdev = pdev;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_connector_hdmi_codec_init);
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 1e2b25e204cb523d61d30f5409faa059bf2b86eb..1d113c0ceec7ce8196a412d7c00a1737175c6fbe 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -46,6 +46,8 @@ struct drm_property_blob;
>  struct drm_printer;
>  struct drm_privacy_screen;
>  struct edid;
> +struct hdmi_codec_daifmt;
> +struct hdmi_codec_params;
>  struct i2c_adapter;
>  
>  enum drm_connector_force {
> @@ -1141,6 +1143,52 @@ struct drm_connector_state {
>  	struct drm_connector_hdmi_state hdmi;
>  };
>  
> +struct drm_connector_hdmi_codec_funcs {
> +	/**
> +	 * @audio_startup:
> +	 *
> +	 * Called when ASoC starts an audio stream setup. The
> +	 * @hdmi_audio_startup is optional.
> +	 *
> +	 * Returns:
> +	 * 0 on success, a negative error code otherwise
> +	 */
> +	int (*audio_startup)(struct drm_connector *connector);
> +
> +	/**
> +	 * @prepare:
> +	 * Configures HDMI-encoder for audio stream. Can be called
> +	 * multiple times for each setup. Mandatory.
> +	 *
> +	 * Returns:
> +	 * 0 on success, a negative error code otherwise
> +	 */
> +	int (*prepare)(struct drm_connector *connector,
> +		       struct hdmi_codec_daifmt *fmt,
> +		       struct hdmi_codec_params *hparms);

Missing newline

> +	/**
> +	 * @audio_shutdown:
> +	 *
> +	 * Shut down the audio stream. Mandatory.
> +	 *
> +	 * Returns:
> +	 * 0 on success, a negative error code otherwise
> +	 */
> +	void (*audio_shutdown)(struct drm_connector *connector);

And thus we can probably just call that one shutdown?

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

From Frank.li at nxp.com  Mon Dec 16 09:05:18 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 16 Dec 2024 12:05:18 -0500
Subject: [PATCH v3 5/5] arm64: dts: imx: add imx95 dts for sof
In-Reply-To: <20241216145039.3074-6-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
 <20241216145039.3074-6-laurentiumihalcea111@gmail.com>
Message-ID: <Z2Bdzr4/hs4b+s83@lizhi-Precision-Tower-5810>

On Mon, Dec 16, 2024 at 09:50:39AM -0500, Laurentiu Mihalcea wrote:
> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
>
> Add imx95 DTS for SOF usage.
>
> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/Makefile        |  1 +
>  .../dts/freescale/imx95-19x19-evk-sof.dts     | 75 +++++++++++++++++++
>  2 files changed, 76 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts
>
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index 839432153cc7..27f64e333e4b 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -282,6 +282,7 @@ 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
> +dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk-sof.dtb
>
>  imx8mm-kontron-dl-dtbs			:= imx8mm-kontron-bl.dtb imx8mm-kontron-dl.dtbo
>
> diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts
> new file mode 100644
> index 000000000000..8eef83d7bdd7
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk-sof.dts
> @@ -0,0 +1,75 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +/dts-v1/;
> +
> +#include "imx95-19x19-evk.dts"
> +
> +/ {
> +	sof_cpu: cm7-cpu at 80000000 {
> +		compatible = "fsl,imx95-cm7-sof";
> +		reg = <0x0 0x80000000 0x0 0x6100000>;
> +		memory-region = <&adma_res>;
> +		mboxes = <&mu7 2 0>, <&mu7 2 1>, <&mu7 3 0>, <&mu7 3 1>;
> +		mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";

need empty line here.

> +		cpu: port {
> +			cpu_ep: endpoint { remote-endpoint = <&codec_ep>; };
> +		};
> +	};
> +
> +	reserved-memory {
> +		adma_res: memory at 86100000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0x0 0x86100000 0x0 0x100000>;
> +			no-map;
> +		};
> +	};
> +
> +	sof-sound-wm8962 {
> +		compatible = "audio-graph-card2";
> +		links = <&cpu>;
> +		label = "wm8962-audio";
> +		hp-det-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_hp>;
> +		widgets =
> +			"Headphone", "Headphones",
> +			"Microphone", "Headset Mic";
> +		routing =
> +			"Headphones", "HPOUTL",
> +			"Headphones", "HPOUTR",
> +			"Headset Mic", "MICBIAS",
> +			"IN3R", "Headset Mic",
> +			"IN1R", "Headset Mic";
> +	};
> +
> +	sound-wm8962 {
> +		status = "disabled";
> +	};
> +
> +};
> +
> +&edma2 {
> +	dma-channel-mask = <0xc0000000>, <0x0>;
> +};

why need change dma mask here?

> +
> +&sai3 {
> +	status = "disabled";
> +};
> +
> +&wm8962 {
> +	assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>,
> +			  <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>,
> +			  <&scmi_clk IMX95_CLK_AUDIOPLL1>,
> +			  <&scmi_clk IMX95_CLK_AUDIOPLL2>,
> +			  <&scmi_clk IMX95_CLK_SAI3>;
> +	assigned-clock-parents = <0>, <0>, <0>, <0>, <&scmi_clk IMX95_CLK_AUDIOPLL1>;
> +	assigned-clock-rates = <3932160000>, <3612672000>,
> +			       <393216000>, <361267200>,
> +			       <12288000>;

empty line here

> +	port {
> +		codec_ep: endpoint { remote-endpoint = <&cpu_ep>; };
> +	};
> +};
> --
> 2.34.1
>


From karansanghvi98 at gmail.com  Mon Dec 16 09:07:00 2024
From: karansanghvi98 at gmail.com (Karan Sanghavi)
Date: Mon, 16 Dec 2024 17:07:00 +0000
Subject: [PATCH v5] dt-bindings: power: Convert raspberrypi,bcm2835-power
 to Dt schema
Message-ID: <20241216-raspberrypi-bcm2835-power-v5-1-222fc244132b@gmail.com>

Convert the raspberrypi,bcm2835-power binding to Dt schema

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Karan Sanghavi <karansanghvi98 at gmail.com>
---
Changes in v5:
- Added maintainers for the power domain
- Link to v4: https://lore.kernel.org/r/20241028-raspberrypi-bcm2835-power-v4-1-acf44abd45ff at gmail.com

Changes in v4:
- Corrected misindentations and random differences.
- Link to v3: https://lore.kernel.org/r/20241026-raspberrypi-bcm2835-power-v3-1-6621e075d33f at gmail.com

Changes in v3:
- Applied changes as per the feedback received for title and description
- Removed power label and renamed node to power-controller	
- Moved the file from bindings/soc/bcm to bindings/power
- Link to v2: https://lore.kernel.org/r/20241022-raspberrypi-bcm2835-power-v2-1-1a4a8a8a5737 at gmail.com

Changes in v2:
- Added original file maintainers
- Removed unnecessary headers from example and formating from description 
- Link to v1: https://lore.kernel.org/r/20241019-raspberrypi-bcm2835-power-v1-1-75e924dc3745 at gmail.com
---
 .../bindings/power/raspberrypi,bcm2835-power.yaml  | 42 +++++++++++++++++++
 .../bindings/soc/bcm/raspberrypi,bcm2835-power.txt | 47 ----------------------
 2 files changed, 42 insertions(+), 47 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/raspberrypi,bcm2835-power.yaml b/Documentation/devicetree/bindings/power/raspberrypi,bcm2835-power.yaml
new file mode 100644
index 000000000000..259e1d9b3fab
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/raspberrypi,bcm2835-power.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/raspberrypi,bcm2835-power.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM2835 power domain
+
+maintainers:
+  - Alexander Aring <alex.aring at gmail.com>
+  - Eric Anholt <eric at anholt.net>
+
+description:
+  The Raspberry Pi power domain manages power for various subsystems
+  in the Raspberry Pi BCM2835 SoC.
+
+properties:
+  compatible:
+    enum:
+      - raspberrypi,bcm2835-power
+
+  firmware:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: Reference to the RPi firmware device node
+
+  "#power-domain-cells":
+    const: 1
+
+required:
+  - compatible
+  - firmware
+  - "#power-domain-cells"
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    power-controller {
+      compatible = "raspberrypi,bcm2835-power";
+      firmware = <&firmware>;
+      #power-domain-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt b/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt
deleted file mode 100644
index 30942cf7992b..000000000000
--- a/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-Raspberry Pi power domain driver
-
-Required properties:
-
-- compatible:		Should be "raspberrypi,bcm2835-power".
-- firmware:		Reference to the RPi firmware device node.
-- #power-domain-cells:	Should be <1>, we providing multiple power domains.
-
-The valid defines for power domain are:
-
- RPI_POWER_DOMAIN_I2C0
- RPI_POWER_DOMAIN_I2C1
- RPI_POWER_DOMAIN_I2C2
- RPI_POWER_DOMAIN_VIDEO_SCALER
- RPI_POWER_DOMAIN_VPU1
- RPI_POWER_DOMAIN_HDMI
- RPI_POWER_DOMAIN_USB
- RPI_POWER_DOMAIN_VEC
- RPI_POWER_DOMAIN_JPEG
- RPI_POWER_DOMAIN_H264
- RPI_POWER_DOMAIN_V3D
- RPI_POWER_DOMAIN_ISP
- RPI_POWER_DOMAIN_UNICAM0
- RPI_POWER_DOMAIN_UNICAM1
- RPI_POWER_DOMAIN_CCP2RX
- RPI_POWER_DOMAIN_CSI2
- RPI_POWER_DOMAIN_CPI
- RPI_POWER_DOMAIN_DSI0
- RPI_POWER_DOMAIN_DSI1
- RPI_POWER_DOMAIN_TRANSPOSER
- RPI_POWER_DOMAIN_CCP2TX
- RPI_POWER_DOMAIN_CDP
- RPI_POWER_DOMAIN_ARM
-
-Example:
-
-power: power {
-	compatible = "raspberrypi,bcm2835-power";
-	firmware = <&firmware>;
-	#power-domain-cells = <1>;
-};
-
-Example for using power domain:
-
-&usb {
-       power-domains = <&power RPI_POWER_DOMAIN_USB>;
-};

---
base-commit: 8e929cb546ee42c9a61d24fae60605e9e3192354
change-id: 20241019-raspberrypi-bcm2835-power-5a4231be8959

Best regards,
-- 
Karan Sanghavi <karansanghvi98 at gmail.com>



From robdclark at gmail.com  Mon Dec 16 09:10:17 2024
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 16 Dec 2024 09:10:17 -0800
Subject: [PATCH] iommu/arm-smmu-qcom: Only enable stall on smmu-v2
Message-ID: <20241216171017.4881-1-robdclark@gmail.com>

From: Rob Clark <robdclark at chromium.org>

On mmu-500, stall-on-fault seems to stall all context banks, causing the
GMU to misbehave.  So limit this feature to smmu-v2 for now.

This fixes an issue with an older mesa bug taking outo the system
because of GMU going off into the year.

Signed-off-by: Rob Clark <robdclark at chromium.org>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index c4c52f7bd09a..1c881e88fc4d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -331,8 +331,10 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
 	priv->get_ttbr1_cfg = qcom_adreno_smmu_get_ttbr1_cfg;
 	priv->set_ttbr0_cfg = qcom_adreno_smmu_set_ttbr0_cfg;
 	priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
-	priv->set_stall = qcom_adreno_smmu_set_stall;
-	priv->resume_translation = qcom_adreno_smmu_resume_translation;
+	if (of_device_is_compatible(np, "qcom,smmu-v2")) {
+		priv->set_stall = qcom_adreno_smmu_set_stall;
+		priv->resume_translation = qcom_adreno_smmu_resume_translation;
+	}
 	priv->set_prr_bit = NULL;
 	priv->set_prr_addr = NULL;
 
-- 
2.47.1



From mripard at kernel.org  Mon Dec 16 09:14:43 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 16 Dec 2024 18:14:43 +0100
Subject: [PATCH v6 04/10] drm/bridge: connector: add support for HDMI
 codec framework
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-4-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-4-50dc145a9c06@linaro.org>
Message-ID: <20241216-benign-amiable-grebe-e0b3e1@houat>

On Fri, Dec 06, 2024 at 12:15:58PM +0200, Dmitry Baryshkov wrote:
> Add necessary glue code to be able to use new HDMI codec framework from
> the DRM bridge drivers. The drm_bridge implements a limited set of the
> hdmi_codec_ops interface, with the functions accepting both
> drm_connector and drm_bridge instead of just a generic void pointer.
> 
> This framework is integrated with the DRM HDMI Connector framework, but
> can also be used for DisplayPort connectors.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/display/drm_bridge_connector.c | 100 ++++++++++++++++++++++++-
>  include/drm/drm_bridge.h                       |  38 ++++++++++
>  2 files changed, 134 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
> index 512ced87ea18c74e182a558a686ddd83de891814..4fa1bb73d430d02d5b79a1a184c203ec9e9c66e7 100644
> --- a/drivers/gpu/drm/display/drm_bridge_connector.c
> +++ b/drivers/gpu/drm/display/drm_bridge_connector.c
> @@ -21,6 +21,8 @@
>  #include <drm/display/drm_hdmi_helper.h>
>  #include <drm/display/drm_hdmi_state_helper.h>
>  
> +#include <sound/hdmi-codec.h>
> +
>  /**
>   * DOC: overview
>   *
> @@ -368,10 +370,80 @@ static int drm_bridge_connector_write_infoframe(struct drm_connector *connector,
>  	return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len);
>  }
>  
> +static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
> +{
> +	struct drm_bridge_connector *bridge_connector =
> +		to_drm_bridge_connector(connector);
> +	struct drm_bridge *bridge;
> +
> +	bridge = bridge_connector->bridge_hdmi;
> +	if (!bridge)
> +		return -EINVAL;
> +
> +	if (bridge->funcs->hdmi_codec_audio_startup)
> +		return bridge->funcs->hdmi_codec_audio_startup(connector, bridge);
> +	else
> +		return 0;
> +}

Nit: it looks like you return in other cases, and there's no need for
that else.

I'd remove the else.

Looks good otherwise, once fixed
Reviewed-by: Maxime Ripard <mripard at kernel.org>

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

From mripard at kernel.org  Mon Dec 16 09:15:26 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 16 Dec 2024 17:15:26 +0000
Subject: [PATCH v6 05/10] drm/bridge: lt9611: switch to using the DRM
 HDMI codec framework
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-5-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-5-50dc145a9c06@linaro.org>
Message-ID: <05419690edbfe859f02d8675c57d3f8f@kernel.org>

On Fri, 6 Dec 2024 12:15:59 +0200, Dmitry Baryshkov wrote:
> Make the Lontium LT9611 DSI-to-HDMI bridge driver use the DRM HDMI Codec
> framework. This enables programming of Audio InfoFrames using the HDMI
> Connector interface and also enables support for the missing features,
> including the ELD retrieval and better hotplug support.
> 
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From mripard at kernel.org  Mon Dec 16 09:20:04 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 16 Dec 2024 18:20:04 +0100
Subject: [PATCH v6 06/10] drm/display/hdmi: implement hotplug functions
In-Reply-To: <20241206-drm-bridge-hdmi-connector-v6-6-50dc145a9c06@linaro.org>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-6-50dc145a9c06@linaro.org>
Message-ID: <20241216-courageous-mysterious-pelican-5a8d2e@houat>

On Fri, Dec 06, 2024 at 12:16:00PM +0200, Dmitry Baryshkov wrote:
> The HDMI Connectors need to perform a variety of tasks when the HDMI
> connector state changes. Such tasks include setting or invalidating CEC
> address, notifying HDMI codec driver, updating scrambler data, etc.
> 
> Implementing such tasks in a driver-specific callbacks is error prone.
> Start implementing the generic helper function (currently handling only
> the HDMI Codec framework) to be used by drivers utilizing HDMI Connector
> framework.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/display/drm_hdmi_state_helper.c | 61 +++++++++++++++++++++++++
>  include/drm/display/drm_hdmi_state_helper.h     |  8 ++++
>  2 files changed, 69 insertions(+)
> 
> diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> index 80bf2829ba89b5f84fed4fa9eb1d6302e10a4f9e..4cdeb63688b9e48acd8e8ae87a45b6253f7dd12b 100644
> --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> @@ -769,3 +769,64 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con
>  	return ret;
>  }
>  EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe);
> +
> +/**
> + * drm_atomic_helper_connector_hdmi_hotplug_edid - Handle the hotplug event for the HDMI connector passing custom EDID
> + * @connector: A pointer to the HDMI connector
> + * @status: Connection status
> + * @drm_edid: EDID to process
> + *
> + * This function should be called as a part of the .detect() / .detect_ctx()
> + * and .force() callbacks, updating the HDMI-specific connector's data. Most
> + * drivers should be able to use @drm_atomic_helper_connector_hdmi_hotplug()
> + * instead.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int
> +drm_atomic_helper_connector_hdmi_hotplug_edid(struct drm_connector *connector,
> +					      enum drm_connector_status status,
> +					      const struct drm_edid *drm_edid)
> +{
> +	if (status == connector_status_disconnected) {
> +		// TODO: also handle CEC and scramber, HDMI sink disconnected.
> +		drm_connector_hdmi_codec_plugged_notify(connector, false);
> +	}
> +
> +	drm_edid_connector_update(connector, drm_edid);
> +
> +	if (status == connector_status_connected) {
> +		// TODO: also handle CEC and scramber, HDMI sink is now connected.
> +		drm_connector_hdmi_codec_plugged_notify(connector, true);
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_hotplug_edid);

I think we discussed it in a previous version's thread after you sent
that one, but I'd rather have that helper call an edid retrieval
function than passing it edids.

Also, EDIDs are mandatory for HDMI, so I'd call the function
drm_atomic_helper_connector_hdmi_hotplug.

> +/**
> + * drm_atomic_helper_connector_hdmi_hotplug - Handle the hotplug event for the HDMI connector
> + * @connector: A pointer to the HDMI connector
> + * @status: Connection status
> + *
> + * This function should be called as a part of the .detect() / .detect_ctx()
> + * and .force() callbacks, updating the HDMI-specific connector's data.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int
> +drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
> +					 enum drm_connector_status status)
> +{
> +	const struct drm_edid *drm_edid;
> +	int ret;
> +
> +	drm_edid = drm_edid_read(connector);
> +	ret = drm_atomic_helper_connector_hdmi_hotplug_edid(connector, status, drm_edid);
> +	drm_edid_free(drm_edid);

Oh. Why do we need the two variants? Or is it to deal with drivers that
don't set connector->ddc?

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

From lkp at intel.com  Mon Dec 16 09:30:03 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Dec 2024 01:30:03 +0800
Subject: [PATCH] arm64: dts: mt8186: Add mt8186-skitty
In-Reply-To: <20241216-skitty_kernel-v1-1-bc75dcdfeb57@pegatron.corp-partner.google.com>
References: <20241216-skitty_kernel-v1-1-bc75dcdfeb57@pegatron.corp-partner.google.com>
Message-ID: <202412170154.QsBtjHdl-lkp@intel.com>

Hi Geoffrey,

kernel test robot noticed the following build errors:

[auto build test ERROR on 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8]

url:    https://github.com/intel-lab-lkp/linux/commits/Geoffrey-Chien/arm64-dts-mt8186-Add-mt8186-skitty/20241216-153651
base:   78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
patch link:    https://lore.kernel.org/r/20241216-skitty_kernel-v1-1-bc75dcdfeb57%40pegatron.corp-partner.google.com
patch subject: [PATCH] arm64: dts: mt8186: Add mt8186-skitty
config: arm64-randconfig-003-20241216 (https://download.01.org/0day-ci/archive/20241217/202412170154.QsBtjHdl-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241217/202412170154.QsBtjHdl-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/202412170154.QsBtjHdl-lkp at intel.com/

All errors (new ones prefixed by >>):

>> Error: arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty.dtsi:42.1-8 Label or path target not found
   FATAL ERROR: Syntax error parsing input tree

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


From mark.rutland at arm.com  Mon Dec 16 09:36:22 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 16 Dec 2024 17:36:22 +0000
Subject: [GIT PULL] arm64 fixes for 6.13-rc3
In-Reply-To: <Z2BAQEuXJg01qWDp@lappy>
References: <Z1xx0ha7lbKkdhRC@arm.com>
 <Z18MixiGByAqDYLC@lappy>
 <Z1_6ukG_Lc5leG1o@J2N7QTR9R3>
 <Z2BAQEuXJg01qWDp@lappy>
Message-ID: <Z2BlFtmP4QP3XyLe@J2N7QTR9R3.cambridge.arm.com>

On Mon, Dec 16, 2024 at 09:59:12AM -0500, Sasha Levin wrote:
> On Mon, Dec 16, 2024 at 10:02:34AM +0000, Mark Rutland wrote:
> > On Sun, Dec 15, 2024 at 12:06:19PM -0500, Sasha Levin wrote:
> > > On Fri, Dec 13, 2024 at 05:41:38PM +0000, Catalin Marinas wrote:
> > > > - arm64 stacktrace: address some fallout from the recent changes to
> > > >  unwinding across exception boundaries
> > > 
> > > Hi Catalin, Mark,
> > > 
> > > It seems that kselftests can hit a warning that was addressed in the
> > > commit above:
> > 
> > I assume you're referring to commit:
> > 
> >  32ed1205682ec42a ("arm64: stacktrace: Skip reporting LR at exception boundaries")
> > 
> > ... ?
> 
> I was actually thinking 65ac33bed8b9 ("arm64: stacktrace: Don't WARN
> when unwinding other tasks"), sorry for the confusion

That commit should have no impact the case you report, which is seen
when unwinding the current task, not another task.

The commit immediately before that (32ed1205682ec42a) *should* fix the
issue triggered by the ftrace kselftests.

> > That was intended to fix this specific issue, as explained in the commit
> > message (with a very similar splat from running the ftrace kselftests).
> > 
> > Am I missing something? i.e. are you saying it *doesn't* fix that?
> 
> Right - LKFT is able to trigger the warning I copied on Linus's tree.

Is that "Right" as in "Right, that commit fixes it", or "Right, that
commit does not fix it"?

The warning you reported says:

	Not tainted 6.13.0-rc2 #1

... which is *before* either of the two fixes above, since the arm64
for-next/fixes branch is based on v6.13-rc2.

Are you seeing the warning with those applied? e.g. do you see this in
v6.13-rc3? I cannot reproduce the issue on v6.13-rc3 so far.

Mark.


From robh at kernel.org  Mon Dec 16 09:39:54 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 16 Dec 2024 11:39:54 -0600
Subject: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon" compatible
In-Reply-To: <20241215203344.46158-1-john.madieu.xa@bp.renesas.com>
References: <20241211-syscon-fixes-v1-3-b5ac8c219e96@kernel.org> <20241215203344.46158-1-john.madieu.xa@bp.renesas.com>
Message-ID: <CAL_Jsq+DEWibue5DVB=gSNB7cvaE85rV5XPf8HPqQDz0DgjCXw@mail.gmail.com>

On Sun, Dec 15, 2024 at 2:34?PM John Madieu
<john.madieu.xa at bp.renesas.com> wrote:
>
> Hi Rob,
>
> On Wed, 11 Dec 2024 14:57:14 -0600 Rob Herring wrote:
> > diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> > index bfb1f69fcff1..e6df2825c14d 100644
> > --- a/drivers/mfd/syscon.c
> > +++ b/drivers/mfd/syscon.c
> > @@ -171,8 +171,10 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
> >                       break;
> >               }
> >
> > -     if (!syscon)
> > +     if (!syscon && of_device_is_compatible(np, "syscon"))
> >               syscon = of_syscon_register(np, check_res);
> > +     else
> > +             syscon = ERR_PTR(-EINVAL);
>
> The current modification will make device_node_get_regmap() return -EINVAL even
> for syscons that were already found in the syscon_list, which I believe is not
> the intended behavior.

Yes, it is. Doesn't Will's fix work for you?

>
> I suggest modifying it this way to maintain lookup functionality for registered
> syscons while implementing your intended changes:
>
> static struct regmap *device_node_get_regmap(struct device_node *np,
>                                              bool check_res)
> {
>         struct syscon *entry, *syscon = NULL;
>         struct regmap *regmap;
>
>         mutex_lock(&syscon_list_lock);
>
>         list_for_each_entry(entry, &syscon_list, list)
>                 if (entry->np == np) {
>                         syscon = entry;
>                         break;
>                 }
>
>         if (syscon) {
>                 regmap = syscon->regmap;
>                 mut ix_unlock(&syscon_list_lock);
>                 return regmap;
>         }
>
>         if (of_device_is_compatible(np, "syscon")) {
>                 syscon = of_syscon_register(np, check_res);
>                 mutex_unlock(&syscon_list_lock);
>                 if (IS_ERR(syscon))
>                         return ERR_CAST(syscon);
>                 return syscon->regmap;
>         }
>
>         mutex_unlock(&syscon_list_lock);

3 unlock calls is a sign the code structure could be improved. A goto
or a guard() for example. However, I think this is the same logic as
what Will suggested.

Rob


From lorenzo at kernel.org  Mon Dec 16 09:47:33 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Mon, 16 Dec 2024 18:47:33 +0100
Subject: [PATCH net-next v2] net: airoha: Fix error path in airoha_probe()
Message-ID: <20241216-airoha_probe-error-path-fix-v2-1-6b10e04e9a5c@kernel.org>

Do not run napi_disable() if airoha_hw_init() fails since Tx/Rx napi
has not been started yet. In order to fix the issue, introduce
airoha_qdma_stop_napi routine and remove napi_disable in
airoha_hw_cleanup().

Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
Reviewed-by: Michal Swiatkowski <michal.swiatkowski at linux.intel.com>
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
Changes in v2:
- rename airoha_qdma_disable_napi() in airoha_qdma_stop_napi()
- Link to v1: https://lore.kernel.org/r/20241215-airoha_probe-error-path-fix-v1-1-dd299122d343 at kernel.org
---
 drivers/net/ethernet/mediatek/airoha_eth.c | 33 ++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
index 6c683a12d5aa52dd9d966df123509075a989c0b3..d8bfc21a5b194478e18201ee3beca7494c223e24 100644
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -2138,17 +2138,14 @@ static void airoha_hw_cleanup(struct airoha_qdma *qdma)
 		if (!qdma->q_rx[i].ndesc)
 			continue;
 
-		napi_disable(&qdma->q_rx[i].napi);
 		netif_napi_del(&qdma->q_rx[i].napi);
 		airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
 		if (qdma->q_rx[i].page_pool)
 			page_pool_destroy(qdma->q_rx[i].page_pool);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
-		napi_disable(&qdma->q_tx_irq[i].napi);
+	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
 		netif_napi_del(&qdma->q_tx_irq[i].napi);
-	}
 
 	for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
 		if (!qdma->q_tx[i].ndesc)
@@ -2173,6 +2170,21 @@ static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
 	}
 }
 
+static void airoha_qdma_stop_napi(struct airoha_qdma *qdma)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
+		napi_disable(&qdma->q_tx_irq[i].napi);
+
+	for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+		if (!qdma->q_rx[i].ndesc)
+			continue;
+
+		napi_disable(&qdma->q_rx[i].napi);
+	}
+}
+
 static void airoha_update_hw_stats(struct airoha_gdm_port *port)
 {
 	struct airoha_eth *eth = port->qdma->eth;
@@ -2738,7 +2750,7 @@ static int airoha_probe(struct platform_device *pdev)
 
 	err = airoha_hw_init(pdev, eth);
 	if (err)
-		goto error;
+		goto error_hw_cleanup;
 
 	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
 		airoha_qdma_start_napi(&eth->qdma[i]);
@@ -2753,13 +2765,16 @@ static int airoha_probe(struct platform_device *pdev)
 		err = airoha_alloc_gdm_port(eth, np);
 		if (err) {
 			of_node_put(np);
-			goto error;
+			goto error_napi_stop;
 		}
 	}
 
 	return 0;
 
-error:
+error_napi_stop:
+	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+		airoha_qdma_stop_napi(&eth->qdma[i]);
+error_hw_cleanup:
 	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
 		airoha_hw_cleanup(&eth->qdma[i]);
 
@@ -2780,8 +2795,10 @@ static void airoha_remove(struct platform_device *pdev)
 	struct airoha_eth *eth = platform_get_drvdata(pdev);
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+	for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
+		airoha_qdma_stop_napi(&eth->qdma[i]);
 		airoha_hw_cleanup(&eth->qdma[i]);
+	}
 
 	for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
 		struct airoha_gdm_port *port = eth->ports[i];

---
base-commit: bc6a5efe3dcd9ada8d76eeb69039a11a86add39b
change-id: 20241215-airoha_probe-error-path-fix-5bc6bed0e20e

Best regards,
-- 
Lorenzo Bianconi <lorenzo at kernel.org>



From dmitry.baryshkov at linaro.org  Mon Dec 16 09:49:47 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 19:49:47 +0200
Subject: [PATCH v6 04/10] drm/bridge: connector: add support for HDMI
 codec framework
In-Reply-To: <20241216-benign-amiable-grebe-e0b3e1@houat>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-4-50dc145a9c06@linaro.org>
 <20241216-benign-amiable-grebe-e0b3e1@houat>
Message-ID: <3su4cgtkkysztdvog24tkltvcflfbhdb24c2acelmbtt3dbm3n@dxtsuiqnxawz>

On Mon, Dec 16, 2024 at 06:14:43PM +0100, Maxime Ripard wrote:
> On Fri, Dec 06, 2024 at 12:15:58PM +0200, Dmitry Baryshkov wrote:
> > Add necessary glue code to be able to use new HDMI codec framework from
> > the DRM bridge drivers. The drm_bridge implements a limited set of the
> > hdmi_codec_ops interface, with the functions accepting both
> > drm_connector and drm_bridge instead of just a generic void pointer.
> > 
> > This framework is integrated with the DRM HDMI Connector framework, but
> > can also be used for DisplayPort connectors.
> > 
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >  drivers/gpu/drm/display/drm_bridge_connector.c | 100 ++++++++++++++++++++++++-
> >  include/drm/drm_bridge.h                       |  38 ++++++++++
> >  2 files changed, 134 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
> > index 512ced87ea18c74e182a558a686ddd83de891814..4fa1bb73d430d02d5b79a1a184c203ec9e9c66e7 100644
> > --- a/drivers/gpu/drm/display/drm_bridge_connector.c
> > +++ b/drivers/gpu/drm/display/drm_bridge_connector.c
> > @@ -21,6 +21,8 @@
> >  #include <drm/display/drm_hdmi_helper.h>
> >  #include <drm/display/drm_hdmi_state_helper.h>
> >  
> > +#include <sound/hdmi-codec.h>
> > +
> >  /**
> >   * DOC: overview
> >   *
> > @@ -368,10 +370,80 @@ static int drm_bridge_connector_write_infoframe(struct drm_connector *connector,
> >  	return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len);
> >  }
> >  
> > +static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
> > +{
> > +	struct drm_bridge_connector *bridge_connector =
> > +		to_drm_bridge_connector(connector);
> > +	struct drm_bridge *bridge;
> > +
> > +	bridge = bridge_connector->bridge_hdmi;
> > +	if (!bridge)
> > +		return -EINVAL;
> > +
> > +	if (bridge->funcs->hdmi_codec_audio_startup)
> > +		return bridge->funcs->hdmi_codec_audio_startup(connector, bridge);
> > +	else
> > +		return 0;
> > +}
> 
> Nit: it looks like you return in other cases, and there's no need for
> that else.
> 
> I'd remove the else.

Ack

> 
> Looks good otherwise, once fixed
> Reviewed-by: Maxime Ripard <mripard at kernel.org>
> 
> Maxime



-- 
With best wishes
Dmitry


From ninad at linux.ibm.com  Mon Dec 16 09:50:38 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 11:50:38 -0600
Subject: [PATCH v2 0/4] Add support for Intel CRPS PSU
Message-ID: <20241216175044.4144442-1-ninad@linux.ibm.com>

Hello,

Please review the patchset for Intel CRPS185 driver.
V2:
---
  - Incorporated review comments by Guenter Roeck
  - Incorporated review comments by Krzysztof Kozlowski

Ninad Palsule (4):
  hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
  hwmon: (pmbus/crps) Add Intel CRPS185 power supply
  dt-bindings: hwmon: intel,crps185: Add to trivial
  ARM: dts: aspeed: system1: Use crps PSU driver

 .../devicetree/bindings/trivial-devices.yaml  |  2 +
 Documentation/hwmon/crps.rst                  | 97 +++++++++++++++++++
 Documentation/hwmon/index.rst                 |  1 +
 MAINTAINERS                                   |  7 ++
 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     |  8 +-
 drivers/hwmon/pmbus/Kconfig                   |  9 ++
 drivers/hwmon/pmbus/Makefile                  |  1 +
 drivers/hwmon/pmbus/crps.c                    | 79 +++++++++++++++
 drivers/hwmon/pmbus/pmbus_core.c              | 13 ++-
 9 files changed, 211 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/hwmon/crps.rst
 create mode 100644 drivers/hwmon/pmbus/crps.c

-- 
2.43.0



From ninad at linux.ibm.com  Mon Dec 16 09:50:42 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 11:50:42 -0600
Subject: [PATCH v2 4/4] ARM: dts: aspeed: system1: Use crps PSU driver
In-Reply-To: <20241216175044.4144442-1-ninad@linux.ibm.com>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
Message-ID: <20241216175044.4144442-5-ninad@linux.ibm.com>

The system1 uses Intel common redundant (crps185) power supplies so move
to correct new crps driver.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index 8f77bc9e860c..360b9ce3c850 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -681,22 +681,22 @@ &i2c2 {
 	status = "okay";
 
 	power-supply at 58 {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x58>;
 	};
 
 	power-supply at 59 {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x59>;
 	};
 
 	power-supply at 5a {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x5a>;
 	};
 
 	power-supply at 5b {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x5b>;
 	};
 };
-- 
2.43.0



From ninad at linux.ibm.com  Mon Dec 16 09:50:39 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 11:50:39 -0600
Subject: [PATCH v2 1/4] hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
In-Reply-To: <20241216175044.4144442-1-ninad@linux.ibm.com>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
Message-ID: <20241216175044.4144442-2-ninad@linux.ibm.com>

Add debugfs file for the PMBUS_REVISION command. This command provides
information about PMBus protocol revision number.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 drivers/hwmon/pmbus/pmbus_core.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index a7000314e5ad..787683e83db6 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -3534,11 +3534,11 @@ static int pmbus_init_debugfs(struct i2c_client *client,
 
 	/*
 	 * Allocate the max possible entries we need.
-	 * 6 entries device-specific
+	 * 7 entries device-specific
 	 * 10 entries page-specific
 	 */
 	entries = devm_kcalloc(data->dev,
-			       6 + data->info->pages * 10, sizeof(*entries),
+			       7 + data->info->pages * 10, sizeof(*entries),
 			       GFP_KERNEL);
 	if (!entries)
 		return -ENOMEM;
@@ -3551,6 +3551,15 @@ static int pmbus_init_debugfs(struct i2c_client *client,
 	 * assume that values of the following registers are the same for all
 	 * pages and report values only for page 0.
 	 */
+	if (pmbus_check_byte_register(client, 0, PMBUS_REVISION)) {
+		entries[idx].client = client;
+		entries[idx].page = 0;
+		entries[idx].reg = PMBUS_REVISION;
+		debugfs_create_file("revision", 0444, data->debugfs,
+				    &entries[idx++],
+				    &pmbus_debugfs_ops);
+	}
+
 	if (pmbus_check_block_register(client, 0, PMBUS_MFR_ID)) {
 		entries[idx].client = client;
 		entries[idx].page = 0;
-- 
2.43.0



From suzuki.poulose at arm.com  Mon Dec 16 09:51:03 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 16 Dec 2024 17:51:03 +0000
Subject: [PATCH v6 04/43] arm64: RME: Add SMC definitions for calling the
 RMM
In-Reply-To: <20241212155610.76522-5-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
 <20241212155610.76522-5-steven.price@arm.com>
Message-ID: <e88930d3-f933-41a3-a698-3a34633e5019@arm.com>

On 12/12/2024 15:55, Steven Price wrote:
> The RMM (Realm Management Monitor) provides functionality that can be
> accessed by SMC calls from the host.
> 
> The SMC definitions are based on DEN0137[1] version 1.0-rel0
> 
> [1] https://developer.arm.com/documentation/den0137/1-0rel0/
> 
> Signed-off-by: Steven Price <steven.price at arm.com>
> ---
> Changes since v5:
>   * Sorted the SMC #defines by value.
>   * Renamed SMI_RxI_CALL to SMI_RMI_CALL since the macro is only used for
>     RMI calls.
>   * Renamed REC_GIC_NUM_LRS to REC_MAX_GIC_NUM_LRS since the actual
>     number of available list registers could be lower.
>   * Provided a define for the reserved fields of FeatureRegister0.
>   * Fix inconsistent names for padding fields.
> Changes since v4:
>   * Update to point to final released RMM spec.
>   * Minor rearrangements.
> Changes since v3:
>   * Update to match RMM spec v1.0-rel0-rc1.
> Changes since v2:
>   * Fix specification link.
>   * Rename rec_entry->rec_enter to match spec.
>   * Fix size of pmu_ovf_status to match spec.
> ---
>   arch/arm64/include/asm/rmi_smc.h | 259 +++++++++++++++++++++++++++++++
>   1 file changed, 259 insertions(+)
>   create mode 100644 arch/arm64/include/asm/rmi_smc.h
> 
> diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_smc.h
> new file mode 100644
> index 000000000000..eec659e284cd
> --- /dev/null
> +++ b/arch/arm64/include/asm/rmi_smc.h
> @@ -0,0 +1,259 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2023-2024 ARM Ltd.
> + *
> + * The values and structures in this file are from the Realm Management Monitor
> + * specification (DEN0137) version 1.0-rel0:
> + * https://developer.arm.com/documentation/den0137/1-0rel0/
> + */
> +
> +#ifndef __ASM_RME_SMC_H
> +#define __ASM_RME_SMC_H
> +
> +#include <linux/arm-smccc.h>
> +
> +#define SMC_RMI_CALL(func)				\
> +	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,		\
> +			   ARM_SMCCC_SMC_64,		\
> +			   ARM_SMCCC_OWNER_STANDARD,	\
> +			   (func))
> +
> +#define SMC_RMI_VERSION			SMC_RMI_CALL(0x0150)
> +#define SMC_RMI_GRANULE_DELEGATE	SMC_RMI_CALL(0x0151)
> +#define SMC_RMI_GRANULE_UNDELEGATE	SMC_RMI_CALL(0x0152)
> +#define SMC_RMI_DATA_CREATE		SMC_RMI_CALL(0x0153)
> +#define SMC_RMI_DATA_CREATE_UNKNOWN	SMC_RMI_CALL(0x0154)
> +#define SMC_RMI_DATA_DESTROY		SMC_RMI_CALL(0x0155)
> +
> +#define SMC_RMI_REALM_ACTIVATE		SMC_RMI_CALL(0x0157)
> +#define SMC_RMI_REALM_CREATE		SMC_RMI_CALL(0x0158)
> +#define SMC_RMI_REALM_DESTROY		SMC_RMI_CALL(0x0159)
> +#define SMC_RMI_REC_CREATE		SMC_RMI_CALL(0x015a)
> +#define SMC_RMI_REC_DESTROY		SMC_RMI_CALL(0x015b)
> +#define SMC_RMI_REC_ENTER		SMC_RMI_CALL(0x015c)
> +#define SMC_RMI_RTT_CREATE		SMC_RMI_CALL(0x015d)
> +#define SMC_RMI_RTT_DESTROY		SMC_RMI_CALL(0x015e)
> +#define SMC_RMI_RTT_MAP_UNPROTECTED	SMC_RMI_CALL(0x015f)
> +
> +#define SMC_RMI_RTT_READ_ENTRY		SMC_RMI_CALL(0x0161)
> +#define SMC_RMI_RTT_UNMAP_UNPROTECTED	SMC_RMI_CALL(0x0162)
> +
> +#define SMC_RMI_PSCI_COMPLETE		SMC_RMI_CALL(0x0164)
> +#define SMC_RMI_FEATURES		SMC_RMI_CALL(0x0165)
> +#define SMC_RMI_RTT_FOLD		SMC_RMI_CALL(0x0166)
> +#define SMC_RMI_REC_AUX_COUNT		SMC_RMI_CALL(0x0167)
> +#define SMC_RMI_RTT_INIT_RIPAS		SMC_RMI_CALL(0x0168)
> +#define SMC_RMI_RTT_SET_RIPAS		SMC_RMI_CALL(0x0169)
> +
> +#define RMI_ABI_MAJOR_VERSION	1
> +#define RMI_ABI_MINOR_VERSION	0
> +
> +#define RMI_ABI_VERSION_GET_MAJOR(version) ((version) >> 16)
> +#define RMI_ABI_VERSION_GET_MINOR(version) ((version) & 0xFFFF)
> +#define RMI_ABI_VERSION(major, minor)      (((major) << 16) | (minor))
> +
> +#define RMI_UNASSIGNED			0
> +#define RMI_ASSIGNED			1
> +#define RMI_TABLE			2
> +
> +#define RMI_RETURN_STATUS(ret)		((ret) & 0xFF)
> +#define RMI_RETURN_INDEX(ret)		(((ret) >> 8) & 0xFF)
> +
> +#define RMI_SUCCESS		0
> +#define RMI_ERROR_INPUT		1
> +#define RMI_ERROR_REALM		2
> +#define RMI_ERROR_REC		3
> +#define RMI_ERROR_RTT		4
> +
> +enum rmi_ripas {
> +	RMI_EMPTY = 0,
> +	RMI_RAM = 1,
> +	RMI_DESTROYED = 2,
> +};
> +
> +#define RMI_NO_MEASURE_CONTENT	0
> +#define RMI_MEASURE_CONTENT	1
> +
> +#define RMI_FEATURE_REGISTER_0_S2SZ		GENMASK(7, 0)
> +#define RMI_FEATURE_REGISTER_0_LPA2		BIT(8)
> +#define RMI_FEATURE_REGISTER_0_SVE_EN		BIT(9)
> +#define RMI_FEATURE_REGISTER_0_SVE_VL		GENMASK(13, 10)
> +#define RMI_FEATURE_REGISTER_0_NUM_BPS		GENMASK(19, 14)
> +#define RMI_FEATURE_REGISTER_0_NUM_WPS		GENMASK(25, 20)
> +#define RMI_FEATURE_REGISTER_0_PMU_EN		BIT(26)
> +#define RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS	GENMASK(31, 27)
> +#define RMI_FEATURE_REGISTER_0_HASH_SHA_256	BIT(32)
> +#define RMI_FEATURE_REGISTER_0_HASH_SHA_512	BIT(33)
> +#define RMI_FEATURE_REGISTER_0_GICV3_NUM_LRS	GENMASK(37, 34)
> +#define RMI_FEATURE_REGISTER_0_MAX_RECS_ORDER	GENMASK(41, 38)
> +#define RMI_FEATURE_REGISTER_0_Reserved		GENMASK(63, 42)
> +
> +#define RMI_REALM_PARAM_FLAG_LPA2		BIT(0)
> +#define RMI_REALM_PARAM_FLAG_SVE		BIT(1)
> +#define RMI_REALM_PARAM_FLAG_PMU		BIT(2)
> +
> +/*
> + * Note many of these fields are smaller than u64 but all fields have u64
> + * alignment, so use u64 to ensure correct alignment.
> + */
> +struct realm_params {
> +	union { /* 0x0 */
> +		struct {
> +			u64 flags;
> +			u64 s2sz;
> +			u64 sve_vl;
> +			u64 num_bps;
> +			u64 num_wps;
> +			u64 pmu_num_ctrs;
> +			u64 hash_algo;
> +		};
> +		u8 padding0[0x400];
> +	};
> +	union { /* 0x400 */
> +		u8 rpv[64];
> +		u8 padding1[0x400];
> +	};
> +	union { /* 0x800 */
> +		struct {
> +			u64 vmid;
> +			u64 rtt_base;
> +			s64 rtt_level_start;
> +			u64 rtt_num_start;
> +		};
> +		u8 padding2[0x800];
> +	};
> +};
> +
> +/*
> + * The number of GPRs (starting from X0) that are
> + * configured by the host when a REC is created.
> + */
> +#define REC_CREATE_NR_GPRS		8
> +
> +#define REC_PARAMS_FLAG_RUNNABLE	BIT_ULL(0)
> +
> +#define REC_PARAMS_AUX_GRANULES		16
> +
> +struct rec_params {
> +	union { /* 0x0 */
> +		u64 flags;
> +		u8 padding0[0x100];
> +	};
> +	union { /* 0x100 */
> +		u64 mpidr;
> +		u8 padding1[0x100];
> +	};
> +	union { /* 0x200 */
> +		u64 pc;
> +		u8 padding2[0x100];
> +	};
> +	union { /* 0x300 */
> +		u64 gprs[REC_CREATE_NR_GPRS];
> +		u8 padding3[0x500];
> +	};
> +	union { /* 0x800 */
> +		struct {
> +			u64 num_rec_aux;
> +			u64 aux[REC_PARAMS_AUX_GRANULES];
> +		};
> +		u8 padding4[0x800];
> +	};
> +};
> +
> +#define REC_ENTER_EMULATED_MMIO		BIT(0)
> +#define REC_ENTER_INJECT_SEA		BIT(1)
> +#define REC_ENTER_TRAP_WFI		BIT(2)
> +#define REC_ENTER_TRAP_WFE		BIT(3)
> +#define REC_ENTER_RIPAS_RESPONSE	BIT(4)
> +

Minor nit: Everywhere else, the flags bit definitions indicate

OBJECT_FLAG_xyz

inline with that should this be :

REC_ENTER_FLAG_xyz ?


Rest looks fine to me

Suzuki



From ninad at linux.ibm.com  Mon Dec 16 09:50:41 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 11:50:41 -0600
Subject: [PATCH v2 3/4] dt-bindings: hwmon: intel,crps185: Add to trivial
In-Reply-To: <20241216175044.4144442-1-ninad@linux.ibm.com>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
Message-ID: <20241216175044.4144442-4-ninad@linux.ibm.com>

Add INTEL Common Redundant Power Supply Versions crps185 bindings as
trivial. It is trivial because only compatibility string is required in
the device tree to load this driver.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index 73a49d50c4ef..7d07b08b1459 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -151,6 +151,8 @@ properties:
           - injoinic,ip5306
             # Inspur Power System power supply unit version 1
           - inspur,ipsps1
+            # Intel common redudant power supply crps185
+          - intel,crps185
             # Intersil ISL29028 Ambient Light and Proximity Sensor
           - isil,isl29028
             # Intersil ISL29030 Ambient Light and Proximity Sensor
-- 
2.43.0



From dmitry.baryshkov at linaro.org  Mon Dec 16 09:47:32 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 19:47:32 +0200
Subject: [PATCH v6 03/10] drm/connector: implement generic HDMI codec
 helpers
In-Reply-To: <20241216-heretic-mackerel-of-wholeness-fcfed7@houat>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-3-50dc145a9c06@linaro.org>
 <20241216-heretic-mackerel-of-wholeness-fcfed7@houat>
Message-ID: <exocd3b65cy6cy5w47cwx3ykn54ncf34hwyj7ffihs5jjzean5@y677uywnlah2>

On Mon, Dec 16, 2024 at 06:04:41PM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Fri, Dec 06, 2024 at 12:15:57PM +0200, Dmitry Baryshkov wrote:
> > Several DRM drivers implement HDMI codec support (despite its name it
> > applies to both HDMI and DisplayPort drivers). Implement generic
> > framework to be used by these drivers. This removes a requirement to
> > implement get_eld() callback and provides default implementation for
> > codec's plug handling.
> > 
> > The framework is integrated with the DRM HDMI Connector framework, but
> > can be used by DisplayPort drivers.
> > 
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >  drivers/gpu/drm/Makefile                   |   1 +
> >  drivers/gpu/drm/drm_connector.c            |   5 +
> >  drivers/gpu/drm/drm_connector_hdmi_codec.c | 185 +++++++++++++++++++++++++++++
> >  include/drm/drm_connector.h                |  80 +++++++++++++
> >  4 files changed, 271 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> > index 1677c1f335fbb0c6114bdb4cc0b12eb407d84564..afdd9268ca23ac7602e73bbe45f3f9cd090a3afd 100644
> > --- a/drivers/gpu/drm/Makefile
> > +++ b/drivers/gpu/drm/Makefile
> > @@ -42,6 +42,7 @@ drm-y := \
> >  	drm_cache.o \
> >  	drm_color_mgmt.o \
> >  	drm_connector.o \
> > +	drm_connector_hdmi_codec.o \
> >  	drm_crtc.o \
> >  	drm_displayid.o \
> >  	drm_drv.o \
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index bbdaaf7022b62d84594a29f1b60144920903a99a..4abfbded962bf45b793a2bd5b1b5c4d9f478a1f7 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -33,6 +33,7 @@
> >  #include <drm/drm_sysfs.h>
> >  #include <drm/drm_utils.h>
> >  
> > +#include <linux/platform_device.h>
> >  #include <linux/property.h>
> >  #include <linux/uaccess.h>
> >  
> > @@ -280,6 +281,7 @@ static int __drm_connector_init(struct drm_device *dev,
> >  	mutex_init(&connector->eld_mutex);
> >  	mutex_init(&connector->edid_override_mutex);
> >  	mutex_init(&connector->hdmi.infoframes.lock);
> > +	mutex_init(&connector->hdmi_codec.lock);
> >  	connector->edid_blob_ptr = NULL;
> >  	connector->epoch_counter = 0;
> >  	connector->tile_blob_ptr = NULL;
> > @@ -632,6 +634,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
> >  		    DRM_CONNECTOR_REGISTERED))
> >  		drm_connector_unregister(connector);
> >  
> > +	platform_device_unregister(connector->hdmi_codec.codec_pdev);
> > +
> >  	if (connector->privacy_screen) {
> >  		drm_privacy_screen_put(connector->privacy_screen);
> >  		connector->privacy_screen = NULL;
> > @@ -670,6 +674,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
> >  		connector->funcs->atomic_destroy_state(connector,
> >  						       connector->state);
> >  
> > +	mutex_destroy(&connector->hdmi_codec.lock);
> >  	mutex_destroy(&connector->hdmi.infoframes.lock);
> >  	mutex_destroy(&connector->mutex);
> >  
> > diff --git a/drivers/gpu/drm/drm_connector_hdmi_codec.c b/drivers/gpu/drm/drm_connector_hdmi_codec.c
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..1934fb53b4d128434559970c9fea548bbc4bedda
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_connector_hdmi_codec.c
> > @@ -0,0 +1,185 @@
> > +// SPDX-License-Identifier: MIT
> > +/*
> > + * Copyright (c) 2024 Linaro Ltd
> > + */
> > +
> > +#include <linux/mutex.h>
> > +#include <linux/of_graph.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include <drm/drm_connector.h>
> > +#include <drm/drm_device.h>
> > +
> > +#include <sound/hdmi-codec.h>
> > +
> > +static int drm_connector_hdmi_codec_audio_startup(struct device *dev, void *data)
> > +{
> > +	struct drm_connector *connector = data;
> > +	const struct drm_connector_hdmi_codec_funcs *funcs =
> > +		connector->hdmi.funcs->codec_funcs;
> > +
> > +	if (funcs->audio_startup)
> > +		return funcs->audio_startup(connector);
> > +
> > +	return 0;
> > +}
> > +
> > +static int drm_connector_hdmi_codec_prepare(struct device *dev, void *data,
> > +					    struct hdmi_codec_daifmt *fmt,
> > +					    struct hdmi_codec_params *hparms)
> > +{
> > +	struct drm_connector *connector = data;
> > +	const struct drm_connector_hdmi_codec_funcs *funcs =
> > +		connector->hdmi.funcs->codec_funcs;
> > +
> > +	return funcs->prepare(connector, fmt, hparms);
> > +}
> > +
> > +static void drm_connector_hdmi_codec_audio_shutdown(struct device *dev, void *data)
> > +{
> > +	struct drm_connector *connector = data;
> > +	const struct drm_connector_hdmi_codec_funcs *funcs =
> > +		connector->hdmi.funcs->codec_funcs;
> > +
> > +	return funcs->audio_shutdown(connector);
> > +}
> > +
> > +static int drm_connector_hdmi_codec_mute_stream(struct device *dev, void *data,
> > +						bool enable, int direction)
> > +{
> > +	struct drm_connector *connector = data;
> > +	const struct drm_connector_hdmi_codec_funcs *funcs =
> > +		connector->hdmi.funcs->codec_funcs;
> > +
> > +	if (funcs->mute_stream)
> > +		return funcs->mute_stream(connector, enable, direction);
> > +
> > +	return -ENOTSUPP;
> > +}
> > +
> > +static int drm_connector_hdmi_codec_get_dai_id(struct snd_soc_component *comment,
> > +		  struct device_node *endpoint,
> > +		  void *data)
> > +{
> > +	struct drm_connector *connector = data;
> > +	struct of_endpoint of_ep;
> > +	int ret;
> > +
> > +	if (connector->hdmi_codec.dai_port < 0)
> > +		return -ENOTSUPP;
> > +
> > +	ret = of_graph_parse_endpoint(endpoint, &of_ep);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	if (of_ep.port == connector->hdmi_codec.dai_port)
> > +		return 0;
> > +
> > +	return -EINVAL;
> > +}
> > +
> > +static int drm_connector_hdmi_codec_get_eld(struct device *dev, void *data,
> > +					    uint8_t *buf, size_t len)
> > +{
> > +	struct drm_connector *connector = data;
> > +
> > +	mutex_lock(&connector->eld_mutex);
> > +	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
> > +	mutex_unlock(&connector->eld_mutex);
> > +
> > +	return 0;
> > +}
> > +
> > +static int drm_connector_hdmi_codec_hook_plugged_cb(struct device *dev,
> > +						    void *data,
> > +						    hdmi_codec_plugged_cb fn,
> > +						    struct device *codec_dev)
> > +{
> > +	struct drm_connector *connector = data;
> > +
> > +	mutex_lock(&connector->hdmi_codec.lock);
> > +
> > +	connector->hdmi_codec.plugged_cb = fn;
> > +	connector->hdmi_codec.plugged_cb_dev = codec_dev;
> > +
> > +	fn(codec_dev, connector->hdmi_codec.last_state);
> > +
> > +	mutex_unlock(&connector->hdmi_codec.lock);
> > +
> > +	return 0;
> > +}
> > +
> > +void drm_connector_hdmi_codec_plugged_notify(struct drm_connector *connector,
> > +					     bool plugged)
> > +{
> > +	mutex_lock(&connector->hdmi_codec.lock);
> > +
> > +	connector->hdmi_codec.last_state = plugged;
> > +
> > +	if (connector->hdmi_codec.plugged_cb &&
> > +	    connector->hdmi_codec.plugged_cb_dev)
> > +		connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev,
> > +						 connector->hdmi_codec.last_state);
> > +
> > +	mutex_unlock(&connector->hdmi_codec.lock);
> > +}
> > +EXPORT_SYMBOL(drm_connector_hdmi_codec_plugged_notify);
> > +
> > +static const struct hdmi_codec_ops drm_connector_hdmi_codec_ops = {
> > +	.audio_startup = drm_connector_hdmi_codec_audio_startup,
> > +	.prepare = drm_connector_hdmi_codec_prepare,
> > +	.audio_shutdown = drm_connector_hdmi_codec_audio_shutdown,
> > +	.mute_stream = drm_connector_hdmi_codec_mute_stream,
> > +	.get_eld = drm_connector_hdmi_codec_get_eld,
> > +	.get_dai_id = drm_connector_hdmi_codec_get_dai_id,
> > +	.hook_plugged_cb = drm_connector_hdmi_codec_hook_plugged_cb,
> > +};
> > +
> > +/**
> > + * drm_connector_hdmi_codec_init - Initialize HDMI Codec device for the DRM connector
> 
> I think it'd be better to call it drm_connector_hdmi_audio_init over
> drm_connector_hdmi_codec_init (feature over implementation).
> 
> > + * @connector: A pointer to the connector to allocate codec for
> > + * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
> > + * @max_i2s_playback_channels: maximum number of playback I2S channels
> > + * @spdif_playback: set if HDMI codec has S/PDIF playback port
> > + * @dai_port: sound DAI port, -1 if it is not enabled
> > + *
> > + * Create a HDMI codec device to be used with the specified connector.
> > + *
> > + * Returns:
> > + * Zero on success, error code on failure.
> > + */
> > +int drm_connector_hdmi_codec_init(struct drm_connector *connector,
> > +				  struct device *hdmi_codec_dev,
> > +				  unsigned int max_i2s_playback_channels,
> > +				  bool spdif_playback,
> > +				  int dai_port)
> > +{
> > +	struct hdmi_codec_pdata codec_pdata = {
> > +		.ops = &drm_connector_hdmi_codec_ops,
> > +		.max_i2s_channels = max_i2s_playback_channels,
> > +		.i2s = !!max_i2s_playback_channels,
> > +		.spdif = spdif_playback,
> > +		.no_i2s_capture = true,
> > +		.no_spdif_capture = true,
> > +		.data = connector,
> > +	};
> > +	struct platform_device *pdev;
> > +
> > +	connector->hdmi_codec.dai_port = dai_port;
> > +
> > +	if (!connector->hdmi.funcs->codec_funcs->prepare ||
> > +	    !connector->hdmi.funcs->codec_funcs->audio_shutdown)
> > +		return -EINVAL;
> > +
> > +	pdev = platform_device_register_data(hdmi_codec_dev,
> > +					     HDMI_CODEC_DRV_NAME,
> > +					     PLATFORM_DEVID_AUTO,
> > +					     &codec_pdata, sizeof(codec_pdata));
> > +	if (IS_ERR(pdev))
> > +		return PTR_ERR(pdev);
> > +
> > +	connector->hdmi_codec.codec_pdev = pdev;
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(drm_connector_hdmi_codec_init);
> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > index 1e2b25e204cb523d61d30f5409faa059bf2b86eb..1d113c0ceec7ce8196a412d7c00a1737175c6fbe 100644
> > --- a/include/drm/drm_connector.h
> > +++ b/include/drm/drm_connector.h
> > @@ -46,6 +46,8 @@ struct drm_property_blob;
> >  struct drm_printer;
> >  struct drm_privacy_screen;
> >  struct edid;
> > +struct hdmi_codec_daifmt;
> > +struct hdmi_codec_params;
> >  struct i2c_adapter;
> >  
> >  enum drm_connector_force {
> > @@ -1141,6 +1143,52 @@ struct drm_connector_state {
> >  	struct drm_connector_hdmi_state hdmi;
> >  };
> >  
> > +struct drm_connector_hdmi_codec_funcs {
> > +	/**
> > +	 * @audio_startup:
> > +	 *
> > +	 * Called when ASoC starts an audio stream setup. The
> > +	 * @hdmi_audio_startup is optional.
> > +	 *
> > +	 * Returns:
> > +	 * 0 on success, a negative error code otherwise
> > +	 */
> > +	int (*audio_startup)(struct drm_connector *connector);
> > +
> > +	/**
> > +	 * @prepare:
> > +	 * Configures HDMI-encoder for audio stream. Can be called
> > +	 * multiple times for each setup. Mandatory.
> > +	 *
> > +	 * Returns:
> > +	 * 0 on success, a negative error code otherwise
> > +	 */
> > +	int (*prepare)(struct drm_connector *connector,
> > +		       struct hdmi_codec_daifmt *fmt,
> > +		       struct hdmi_codec_params *hparms);
> 
> Missing newline
> 
> > +	/**
> > +	 * @audio_shutdown:
> > +	 *
> > +	 * Shut down the audio stream. Mandatory.
> > +	 *
> > +	 * Returns:
> > +	 * 0 on success, a negative error code otherwise
> > +	 */
> > +	void (*audio_shutdown)(struct drm_connector *connector);
> 
> And thus we can probably just call that one shutdown?

It should be called automatically by the sound system. I'd rather not
call items directly that we are not supposed to call.

-- 
With best wishes
Dmitry


From tanmay.shah at amd.com  Mon Dec 16 09:47:33 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 16 Dec 2024 11:47:33 -0600
Subject: [PATCH v2] mailbox: zynqmp: Remove invalid __percpu annotation in
 zynqmp_ipi_probe()
In-Reply-To: <25eb1e35-83b0-46f4-9a9c-138c89665e05@amd.com>
References: <20241214091327.4716-1-ubizjak@gmail.com>
 <25eb1e35-83b0-46f4-9a9c-138c89665e05@amd.com>
Message-ID: <65a1d19e-e793-4371-a33d-e2374908d7f8@amd.com>

Reviewed-by: Tanmay Shah <tanmay.shah at amd.com>

On 12/16/24 1:16 AM, Michal Simek wrote:
> 
> 
> On 12/14/24 10:12, Uros Bizjak wrote:
>> struct zynqmp_ipi_pdata __percpu *pdata is not a per-cpu variable,
>> so it should not be annotated with __percpu annotation.
>>
>> Remove invalid __percpu annotation to fix several
>>
>> zynqmp-ipi-mailbox.c:920:15: warning: incorrect type in assignment 
>> (different address spaces)
>> zynqmp-ipi-mailbox.c:920:15:??? expected struct zynqmp_ipi_pdata 
>> [noderef] __percpu *pdata
>> zynqmp-ipi-mailbox.c:920:15:??? got void *
>> zynqmp-ipi-mailbox.c:927:56: warning: incorrect type in argument 3 
>> (different address spaces)
>> zynqmp-ipi-mailbox.c:927:56:??? expected unsigned int [usertype] 
>> *out_value
>> zynqmp-ipi-mailbox.c:927:56:??? got unsigned int [noderef] __percpu *
>> ...
>>
>> and several
>>
>> drivers/mailbox/zynqmp-ipi-mailbox.c:924:9: warning: dereference of 
>> noderef expression
>> ...
>>
>> sparse warnings.
>>
>> There were no changes in the resulting object file.
>>
>> Cc: stable at vger.kernel.org
>> Fixes: 6ffb1635341b ("mailbox: zynqmp: handle SGI for shared IPI")
>> Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
>> Cc: Jassi Brar <jassisinghbrar at gmail.com>
>> Cc: Michal Simek <michal.simek at amd.com>
>> Cc: Tanmay Shah <tanmay.shah at amd.com>
>> ---
>> v2: - Fix typo in commit message
>> ???? - Add Fixes and Cc: stable.
>> ---
>> ? drivers/mailbox/zynqmp-ipi-mailbox.c | 2 +-
>> ? 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/ 
>> zynqmp-ipi-mailbox.c
>> index aa5249da59b2..0c143beaafda 100644
>> --- a/drivers/mailbox/zynqmp-ipi-mailbox.c
>> +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
>> @@ -905,7 +905,7 @@ static int zynqmp_ipi_probe(struct platform_device 
>> *pdev)
>> ? {
>> ????? struct device *dev = &pdev->dev;
>> ????? struct device_node *nc, *np = pdev->dev.of_node;
>> -??? struct zynqmp_ipi_pdata __percpu *pdata;
>> +??? struct zynqmp_ipi_pdata *pdata;
>> ????? struct of_phandle_args out_irq;
>> ????? struct zynqmp_ipi_mbox *mbox;
>> ????? int num_mboxes, ret = -EINVAL;
> 
> Tanmay: Please take a look
> 
> I think this patch is correct. Pdata structure is allocated only once 
> not for every CPU and marking here is not correct. Information from 
> zynqmp_ipi_pdata are likely fixed and the same for every CPU. Only IRQ 
> handling is done per cpu basis but that's it.
> 
> Reviewed-by: Michal Simek <michal.simek at amd.com>
> 
> Thanks,
> Michal
> 



From ninad at linux.ibm.com  Mon Dec 16 09:50:40 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 11:50:40 -0600
Subject: [PATCH v2 2/4] hwmon: (pmbus/crps) Add Intel CRPS185 power supply
In-Reply-To: <20241216175044.4144442-1-ninad@linux.ibm.com>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
Message-ID: <20241216175044.4144442-3-ninad@linux.ibm.com>

Add the driver to monitor Intel common redundant power supply (crps185)
with hwmon over pmbus.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 Documentation/hwmon/crps.rst  | 97 +++++++++++++++++++++++++++++++++++
 Documentation/hwmon/index.rst |  1 +
 MAINTAINERS                   |  7 +++
 drivers/hwmon/pmbus/Kconfig   |  9 ++++
 drivers/hwmon/pmbus/Makefile  |  1 +
 drivers/hwmon/pmbus/crps.c    | 79 ++++++++++++++++++++++++++++
 6 files changed, 194 insertions(+)
 create mode 100644 Documentation/hwmon/crps.rst
 create mode 100644 drivers/hwmon/pmbus/crps.c

diff --git a/Documentation/hwmon/crps.rst b/Documentation/hwmon/crps.rst
new file mode 100644
index 000000000000..74570ed1e978
--- /dev/null
+++ b/Documentation/hwmon/crps.rst
@@ -0,0 +1,97 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver crps
+==================
+
+Supported chips:
+
+  * Intel CRPS185
+
+    Prefix: 'crps185'
+
+    Addresses scanned: -
+
+    Datasheet: Publicly not available.
+
+Authors:
+    Ninad Palsule <ninad at linux.ibm.com>
+
+
+Description
+-----------
+
+This driver implements support for Intel Common Redundant Power supply with
+PMBus support.
+
+The driver is a client driver to the core PMBus driver.
+Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers.
+
+
+Usage Notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices.rst for
+details.
+
+
+Sysfs entries
+-------------
+
+======================= ======================================================
+curr1_label		"iin"
+curr1_input		Measured input current
+curr1_max		Maximum input current
+curr1_max_alarm         Input maximum current high alarm
+curr1_crit              Critial high input current
+curr1_crit_alarm        Input critical current high alarm
+curr1_rated_max		Maximum rated input current
+
+curr2_label		"iout1"
+curr2_input		Measured output current
+curr2_max		Maximum output current
+curr2_max_alarm         Output maximum current high alarm
+curr2_crit	        Critial high output current
+curr2_crit_alarm        Output critical current high alarm
+curr2_rated_max		Maximum rated output current
+
+in1_label		"vin"
+in1_input		Measured input voltage
+in1_crit                Critical input over voltage
+in1_crit_alarm          Critical input over voltage alarm
+in1_max                 Maximum input over voltage
+in1_max_alarm           Maximum input over voltage alarm
+in1_rated_min		Minimum rated input voltage
+in1_rated_max		Maximum rated input voltage
+
+in2_label		"vout1"
+in2_input		Measured input voltage
+in2_crit                Critical input over voltage
+in2_crit_alarm          Critical input over voltage alarm
+in2_lcrit               Critical input under voltage fault
+in2_lcrit_alarm         Critical input under voltage fault alarm
+in2_max                 Maximum input over voltage
+in2_max_alarm           Maximum input over voltage alarm
+in2_min                 Minimum input under voltage warning
+in2_min_alarm           Minimum input under voltage warning alarm
+in2_rated_min		Minimum rated input voltage
+in2_rated_max		Maximum rated input voltage
+
+power1_label		"pin"
+power1_input		Measured input power
+power1_alarm		Input power high alarm
+power1_max  		Maximum input power
+power1_rated_max        Maximum rated input power
+
+temp[1-2]_input		Measured temperature
+temp[1-2]_crit 		Critical temperature
+temp[1-2]_crit_alarm    Critical temperature alarm
+temp[1-2]_max  		Maximum temperature
+temp[1-2]_max_alarm     Maximum temperature alarm
+temp[1-2]_rated_max     Maximum rated temperature
+
+fan1_alarm		Fan 1 warning.
+fan1_fault		Fan 1 fault.
+fan1_input		Fan 1 speed in RPM.
+fan1_target             Fan 1 target.
+======================= ======================================================
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 1a3cb0a59f72..b1ea445479b0 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -58,6 +58,7 @@ Hardware Monitoring Kernel Drivers
    corsair-cpro
    corsair-psu
    cros_ec_hwmon
+   crps
    da9052
    da9055
    dell-smm-hwmon
diff --git a/MAINTAINERS b/MAINTAINERS
index 637ddd44245f..e99f26f75733 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6100,6 +6100,13 @@ L:	linux-input at vger.kernel.org
 S:	Maintained
 F:	drivers/hid/hid-creative-sb0540.c
 
+INTEL CRPS COMMON REDUNDANT PSU DRIVER
+M:	Ninad Palsule <ninad at linux.ibm.com>
+L:	linux-hwmon at vger.kernel.org
+S:	Maintained
+F:	Documentation/hwmon/crps.rst
+F:	drivers/hwmon/pmbus/crps.c
+
 CRYPTO API
 M:	Herbert Xu <herbert at gondor.apana.org.au>
 M:	"David S. Miller" <davem at davemloft.net>
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 22418a05ced0..43b6df04e0f9 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -85,6 +85,15 @@ config SENSORS_BPA_RS600
 	  This driver can also be built as a module. If so, the module will
 	  be called bpa-rs600.
 
+config SENSORS_CRPS
+	tristate "Intel Common Redundant Power Supply"
+	help
+	  If you say yes here you get hardware monitoring support for the Intel
+	  Common Redundant Power Supply.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called crps.
+
 config SENSORS_DELTA_AHE50DC_FAN
 	tristate "Delta AHE-50DC fan control module"
 	help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 3d3183f8d2a7..c7eb7739b7f8 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -62,3 +62,4 @@ obj-$(CONFIG_SENSORS_XDPE122)	+= xdpe12284.o
 obj-$(CONFIG_SENSORS_XDPE152)	+= xdpe152c4.o
 obj-$(CONFIG_SENSORS_ZL6100)	+= zl6100.o
 obj-$(CONFIG_SENSORS_PIM4328)	+= pim4328.o
+obj-$(CONFIG_SENSORS_CRPS)	+= crps.o
diff --git a/drivers/hwmon/pmbus/crps.c b/drivers/hwmon/pmbus/crps.c
new file mode 100644
index 000000000000..09425c404fc8
--- /dev/null
+++ b/drivers/hwmon/pmbus/crps.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2024 IBM Corp.
+ */
+
+#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/pmbus.h>
+
+#include "pmbus.h"
+
+static const struct i2c_device_id crps_id[] = {
+	{ "intel_crps185" },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, crps_id);
+
+static struct pmbus_driver_info crps_info = {
+	.pages = 1,
+	/* PSU uses default linear data format. */
+	.func[0] = PMBUS_HAVE_PIN | PMBUS_HAVE_IOUT |
+		PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_IIN |
+		PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
+		PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+		PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
+		PMBUS_HAVE_STATUS_TEMP |
+		PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
+};
+
+static int crps_probe(struct i2c_client *client)
+{
+	int rc;
+	struct device *dev = &client->dev;
+	char buf[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
+
+	rc = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
+	if (rc < 0) {
+		dev_err_probe(dev, rc, "Failed to read PMBUS_MFR_MODEL\n");
+		return rc;
+	}
+
+	if (strncmp(buf, "03NK260", 7) == 7) {
+		buf[rc] = '\0';
+		dev_err_probe(dev, -ENODEV, "Model '%s' not supported\n", buf);
+		return -ENODEV;
+	}
+
+	rc = pmbus_do_probe(client, &crps_info);
+	if (rc) {
+		dev_err_probe(dev, rc, "Failed to probe %d\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id crps_of_match[] = {
+	{
+		.compatible = "intel,crps185",
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, crps_of_match);
+
+static struct i2c_driver crps_driver = {
+	.driver = {
+		.name = "crps",
+		.of_match_table = crps_of_match,
+	},
+	.probe = crps_probe,
+	.id_table = crps_id,
+};
+
+module_i2c_driver(crps_driver);
+
+MODULE_AUTHOR("Ninad Palsule");
+MODULE_DESCRIPTION("PMBus driver for Intel Common Redundant power supplies");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("PMBUS");
-- 
2.43.0



From qperret at google.com  Mon Dec 16 09:57:47 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:47 +0000
Subject: [PATCH v3 02/18] KVM: arm64: Move enum pkvm_page_state to memory.h
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-3-qperret@google.com>

In order to prepare the way for storing page-tracking information in
pKVM's vmemmap, move the enum pkvm_page_state definition to
nvhe/memory.h.

No functional changes intended.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 34 +------------------
 arch/arm64/kvm/hyp/include/nvhe/memory.h      | 33 ++++++++++++++++++
 2 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 8c30362af2b9..25038ac705d8 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -11,42 +11,10 @@
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_pgtable.h>
 #include <asm/virt.h>
+#include <nvhe/memory.h>
 #include <nvhe/pkvm.h>
 #include <nvhe/spinlock.h>
 
-/*
- * SW bits 0-1 are reserved to track the memory ownership state of each page:
- *   00: The page is owned exclusively by the page-table owner.
- *   01: The page is owned by the page-table owner, but is shared
- *       with another entity.
- *   10: The page is shared with, but not owned by the page-table owner.
- *   11: Reserved for future use (lending).
- */
-enum pkvm_page_state {
-	PKVM_PAGE_OWNED			= 0ULL,
-	PKVM_PAGE_SHARED_OWNED		= BIT(0),
-	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
-	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
-
-	/* Meta-states which aren't encoded directly in the PTE's SW bits */
-	PKVM_NOPAGE			= BIT(2),
-};
-#define PKVM_PAGE_META_STATES_MASK	(~(BIT(0) | BIT(1)))
-
-#define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
-static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
-						 enum pkvm_page_state state)
-{
-	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
-	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
-	return prot;
-}
-
-static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
-{
-	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
-}
-
 struct host_mmu {
 	struct kvm_arch arch;
 	struct kvm_pgtable pgt;
diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index ab205c4d6774..c84b24234ac7 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -7,6 +7,39 @@
 
 #include <linux/types.h>
 
+/*
+ * SW bits 0-1 are reserved to track the memory ownership state of each page:
+ *   00: The page is owned exclusively by the page-table owner.
+ *   01: The page is owned by the page-table owner, but is shared
+ *       with another entity.
+ *   10: The page is shared with, but not owned by the page-table owner.
+ *   11: Reserved for future use (lending).
+ */
+enum pkvm_page_state {
+	PKVM_PAGE_OWNED			= 0ULL,
+	PKVM_PAGE_SHARED_OWNED		= BIT(0),
+	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
+	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
+
+	/* Meta-states which aren't encoded directly in the PTE's SW bits */
+	PKVM_NOPAGE			= BIT(2),
+};
+#define PKVM_PAGE_META_STATES_MASK	(~(BIT(0) | BIT(1)))
+
+#define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
+static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
+						 enum pkvm_page_state state)
+{
+	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
+	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
+	return prot;
+}
+
+static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
+{
+	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
+}
+
 struct hyp_page {
 	unsigned short refcount;
 	unsigned short order;
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:48 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:48 +0000
Subject: [PATCH v3 03/18] KVM: arm64: Make hyp_page::order a u8
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-4-qperret@google.com>

We don't need 16 bits to store the hyp page order, and we'll need some
bits to store page ownership data soon, so let's reduce the order
member.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/gfp.h    |  6 +++---
 arch/arm64/kvm/hyp/include/nvhe/memory.h |  5 +++--
 arch/arm64/kvm/hyp/nvhe/page_alloc.c     | 14 +++++++-------
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
index 97c527ef53c2..f1725bad6331 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
@@ -7,7 +7,7 @@
 #include <nvhe/memory.h>
 #include <nvhe/spinlock.h>
 
-#define HYP_NO_ORDER	USHRT_MAX
+#define HYP_NO_ORDER	0xff
 
 struct hyp_pool {
 	/*
@@ -19,11 +19,11 @@ struct hyp_pool {
 	struct list_head free_area[NR_PAGE_ORDERS];
 	phys_addr_t range_start;
 	phys_addr_t range_end;
-	unsigned short max_order;
+	u8 max_order;
 };
 
 /* Allocation */
-void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order);
+void *hyp_alloc_pages(struct hyp_pool *pool, u8 order);
 void hyp_split_page(struct hyp_page *page);
 void hyp_get_page(struct hyp_pool *pool, void *addr);
 void hyp_put_page(struct hyp_pool *pool, void *addr);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index c84b24234ac7..45b8d1840aa4 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -41,8 +41,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
 }
 
 struct hyp_page {
-	unsigned short refcount;
-	unsigned short order;
+	u16 refcount;
+	u8 order;
+	u8 reserved;
 };
 
 extern u64 __hyp_vmemmap;
diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
index e691290d3765..a1eb27a1a747 100644
--- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
+++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
@@ -32,7 +32,7 @@ u64 __hyp_vmemmap;
  */
 static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool,
 					     struct hyp_page *p,
-					     unsigned short order)
+					     u8 order)
 {
 	phys_addr_t addr = hyp_page_to_phys(p);
 
@@ -51,7 +51,7 @@ static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool,
 /* Find a buddy page currently available for allocation */
 static struct hyp_page *__find_buddy_avail(struct hyp_pool *pool,
 					   struct hyp_page *p,
-					   unsigned short order)
+					   u8 order)
 {
 	struct hyp_page *buddy = __find_buddy_nocheck(pool, p, order);
 
@@ -94,7 +94,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
 			      struct hyp_page *p)
 {
 	phys_addr_t phys = hyp_page_to_phys(p);
-	unsigned short order = p->order;
+	u8 order = p->order;
 	struct hyp_page *buddy;
 
 	memset(hyp_page_to_virt(p), 0, PAGE_SIZE << p->order);
@@ -129,7 +129,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
 
 static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool,
 					   struct hyp_page *p,
-					   unsigned short order)
+					   u8 order)
 {
 	struct hyp_page *buddy;
 
@@ -183,7 +183,7 @@ void hyp_get_page(struct hyp_pool *pool, void *addr)
 
 void hyp_split_page(struct hyp_page *p)
 {
-	unsigned short order = p->order;
+	u8 order = p->order;
 	unsigned int i;
 
 	p->order = 0;
@@ -195,10 +195,10 @@ void hyp_split_page(struct hyp_page *p)
 	}
 }
 
-void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order)
+void *hyp_alloc_pages(struct hyp_pool *pool, u8 order)
 {
-	unsigned short i = order;
 	struct hyp_page *p;
+	u8 i = order;
 
 	hyp_spin_lock(&pool->lock);
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:49 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:49 +0000
Subject: [PATCH v3 04/18] KVM: arm64: Move host page ownership tracking to the
 hyp vmemmap
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-5-qperret@google.com>

We currently store part of the page-tracking state in PTE software bits
for the host, guests and the hypervisor. This is sub-optimal when e.g.
sharing pages as this forces to break block mappings purely to support
this software tracking. This causes an unnecessarily fragmented stage-2
page-table for the host in particular when it shares pages with Secure,
which can lead to measurable regressions. Moreover, having this state
stored in the page-table forces us to do multiple costly walks on the
page transition path, hence causing overhead.

In order to work around these problems, move the host-side page-tracking
logic from SW bits in its stage-2 PTEs to the hypervisor's vmemmap.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/memory.h |   6 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 100 ++++++++++++++++-------
 arch/arm64/kvm/hyp/nvhe/setup.c          |   7 +-
 3 files changed, 77 insertions(+), 36 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index 45b8d1840aa4..8bd9a539f260 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -8,7 +8,7 @@
 #include <linux/types.h>
 
 /*
- * SW bits 0-1 are reserved to track the memory ownership state of each page:
+ * Bits 0-1 are reserved to track the memory ownership state of each page:
  *   00: The page is owned exclusively by the page-table owner.
  *   01: The page is owned by the page-table owner, but is shared
  *       with another entity.
@@ -43,7 +43,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
 struct hyp_page {
 	u16 refcount;
 	u8 order;
-	u8 reserved;
+
+	/* Host (non-meta) state. Guarded by the host stage-2 lock. */
+	enum pkvm_page_state host_state : 8;
 };
 
 extern u64 __hyp_vmemmap;
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index caba3e4bd09e..12bb5445fe47 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -201,8 +201,8 @@ static void *guest_s2_zalloc_page(void *mc)
 
 	memset(addr, 0, PAGE_SIZE);
 	p = hyp_virt_to_page(addr);
-	memset(p, 0, sizeof(*p));
 	p->refcount = 1;
+	p->order = 0;
 
 	return addr;
 }
@@ -268,6 +268,7 @@ int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd)
 
 void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
 {
+	struct hyp_page *page;
 	void *addr;
 
 	/* Dump all pgtable pages in the hyp_pool */
@@ -279,7 +280,9 @@ void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
 	/* Drain the hyp_pool into the memcache */
 	addr = hyp_alloc_pages(&vm->pool, 0);
 	while (addr) {
-		memset(hyp_virt_to_page(addr), 0, sizeof(struct hyp_page));
+		page = hyp_virt_to_page(addr);
+		page->refcount = 0;
+		page->order = 0;
 		push_hyp_memcache(mc, addr, hyp_virt_to_phys);
 		WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1));
 		addr = hyp_alloc_pages(&vm->pool, 0);
@@ -382,19 +385,28 @@ bool addr_is_memory(phys_addr_t phys)
 	return !!find_mem_range(phys, &range);
 }
 
-static bool addr_is_allowed_memory(phys_addr_t phys)
+static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
+{
+	return range->start <= addr && addr < range->end;
+}
+
+static int check_range_allowed_memory(u64 start, u64 end)
 {
 	struct memblock_region *reg;
 	struct kvm_mem_range range;
 
-	reg = find_mem_range(phys, &range);
+	/*
+	 * Callers can't check the state of a range that overlaps memory and
+	 * MMIO regions, so ensure [start, end[ is in the same kvm_mem_range.
+	 */
+	reg = find_mem_range(start, &range);
+	if (!is_in_mem_range(end - 1, &range))
+		return -EINVAL;
 
-	return reg && !(reg->flags & MEMBLOCK_NOMAP);
-}
+	if (!reg || reg->flags & MEMBLOCK_NOMAP)
+		return -EPERM;
 
-static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
-{
-	return range->start <= addr && addr < range->end;
+	return 0;
 }
 
 static bool range_is_memory(u64 start, u64 end)
@@ -454,8 +466,10 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
 	if (kvm_pte_valid(pte))
 		return -EAGAIN;
 
-	if (pte)
+	if (pte) {
+		WARN_ON(addr_is_memory(addr) && hyp_phys_to_page(addr)->host_state != PKVM_NOPAGE);
 		return -EPERM;
+	}
 
 	do {
 		u64 granule = kvm_granule_size(level);
@@ -477,10 +491,33 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
 	return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
 }
 
+static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm_page_state state)
+{
+	phys_addr_t end = addr + size;
+
+	for (; addr < end; addr += PAGE_SIZE)
+		hyp_phys_to_page(addr)->host_state = state;
+}
+
 int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
 {
-	return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
-			       addr, size, &host_s2_pool, owner_id);
+	int ret;
+
+	if (!addr_is_memory(addr))
+		return -EPERM;
+
+	ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
+			      addr, size, &host_s2_pool, owner_id);
+	if (ret)
+		return ret;
+
+	/* Don't forget to update the vmemmap tracking for the host */
+	if (owner_id == PKVM_ID_HOST)
+		__host_update_page_state(addr, size, PKVM_PAGE_OWNED);
+	else
+		__host_update_page_state(addr, size, PKVM_NOPAGE);
+
+	return 0;
 }
 
 static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
@@ -604,35 +641,38 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size,
 	return kvm_pgtable_walk(pgt, addr, size, &walker);
 }
 
-static enum pkvm_page_state host_get_page_state(kvm_pte_t pte, u64 addr)
-{
-	if (!addr_is_allowed_memory(addr))
-		return PKVM_NOPAGE;
-
-	if (!kvm_pte_valid(pte) && pte)
-		return PKVM_NOPAGE;
-
-	return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
-}
-
 static int __host_check_page_state_range(u64 addr, u64 size,
 					 enum pkvm_page_state state)
 {
-	struct check_walk_data d = {
-		.desired	= state,
-		.get_page_state	= host_get_page_state,
-	};
+	u64 end = addr + size;
+	int ret;
+
+	ret = check_range_allowed_memory(addr, end);
+	if (ret)
+		return ret;
 
 	hyp_assert_lock_held(&host_mmu.lock);
-	return check_page_state_range(&host_mmu.pgt, addr, size, &d);
+	for (; addr < end; addr += PAGE_SIZE) {
+		if (hyp_phys_to_page(addr)->host_state != state)
+			return -EPERM;
+	}
+
+	return 0;
 }
 
 static int __host_set_page_state_range(u64 addr, u64 size,
 				       enum pkvm_page_state state)
 {
-	enum kvm_pgtable_prot prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, state);
+	if (hyp_phys_to_page(addr)->host_state == PKVM_NOPAGE) {
+		int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT);
 
-	return host_stage2_idmap_locked(addr, size, prot);
+		if (ret)
+			return ret;
+	}
+
+	__host_update_page_state(addr, size, state);
+
+	return 0;
 }
 
 static int host_request_owned_transition(u64 *completer_addr,
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index cbdd18cd3f98..7e04d1c2a03d 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -180,7 +180,6 @@ static void hpool_put_page(void *addr)
 static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
 				     enum kvm_pgtable_walk_flags visit)
 {
-	enum kvm_pgtable_prot prot;
 	enum pkvm_page_state state;
 	phys_addr_t phys;
 
@@ -203,16 +202,16 @@ static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
 	case PKVM_PAGE_OWNED:
 		return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP);
 	case PKVM_PAGE_SHARED_OWNED:
-		prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED);
+		hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_BORROWED;
 		break;
 	case PKVM_PAGE_SHARED_BORROWED:
-		prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
+		hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_OWNED;
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	return host_stage2_idmap_locked(phys, PAGE_SIZE, prot);
+	return 0;
 }
 
 static int fix_hyp_pgtable_refcnt_walker(const struct kvm_pgtable_visit_ctx *ctx,
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:50 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:50 +0000
Subject: [PATCH v3 05/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_mkyoung
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-6-qperret@google.com>

kvm_pgtable_stage2_mkyoung currently assumes that it is being called
from a 'shared' walker, which will not be true once called from pKVM.
To allow for the re-use of that function, make the walk flags one of
its parameters.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 4 +++-
 arch/arm64/kvm/hyp/pgtable.c         | 7 +++----
 arch/arm64/kvm/mmu.c                 | 3 ++-
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index aab04097b505..38b7ec1c8614 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -669,13 +669,15 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
  * kvm_pgtable_stage2_mkyoung() - Set the access flag in a page-table entry.
  * @pgt:	Page-table structure initialised by kvm_pgtable_stage2_init*().
  * @addr:	Intermediate physical address to identify the page-table entry.
+ * @flags:	Flags to control the page-table walk (ex. a shared walk)
  *
  * The offset of @addr within a page is ignored.
  *
  * If there is a valid, leaf page-table entry used to translate @addr, then
  * set the access flag in that entry.
  */
-void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr);
+void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
+				enum kvm_pgtable_walk_flags flags);
 
 /**
  * kvm_pgtable_stage2_test_clear_young() - Test and optionally clear the access
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 40bd55966540..0470aedb4bf4 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -1245,14 +1245,13 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
 					NULL, NULL, 0);
 }
 
-void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr)
+void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
+				enum kvm_pgtable_walk_flags flags)
 {
 	int ret;
 
 	ret = stage2_update_leaf_attrs(pgt, addr, 1, KVM_PTE_LEAF_ATTR_LO_S2_AF, 0,
-				       NULL, NULL,
-				       KVM_PGTABLE_WALK_HANDLE_FAULT |
-				       KVM_PGTABLE_WALK_SHARED);
+				       NULL, NULL, flags);
 	if (!ret)
 		dsb(ishst);
 }
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index c9d46ad57e52..a2339b76c826 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1718,13 +1718,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 /* Resolve the access fault by making the page young again. */
 static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 {
+	enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED;
 	struct kvm_s2_mmu *mmu;
 
 	trace_kvm_access_fault(fault_ipa);
 
 	read_lock(&vcpu->kvm->mmu_lock);
 	mmu = vcpu->arch.hw_mmu;
-	kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa);
+	kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa, flags);
 	read_unlock(&vcpu->kvm->mmu_lock);
 }
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:51 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:51 +0000
Subject: [PATCH v3 06/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_relax_perms
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-7-qperret@google.com>

kvm_pgtable_stage2_relax_perms currently assumes that it is being called
from a 'shared' walker, which will not be true once called from pKVM. To
allow for the re-use of that function, make the walk flags one of its
parameters.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 4 +++-
 arch/arm64/kvm/hyp/pgtable.c         | 6 ++----
 arch/arm64/kvm/mmu.c                 | 7 +++----
 3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 38b7ec1c8614..c2f4149283ef 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -707,6 +707,7 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
  * @pgt:	Page-table structure initialised by kvm_pgtable_stage2_init*().
  * @addr:	Intermediate physical address to identify the page-table entry.
  * @prot:	Additional permissions to grant for the mapping.
+ * @flags:	Flags to control the page-table walk (ex. a shared walk)
  *
  * The offset of @addr within a page is ignored.
  *
@@ -719,7 +720,8 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
  * Return: 0 on success, negative error code on failure.
  */
 int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
-				   enum kvm_pgtable_prot prot);
+				   enum kvm_pgtable_prot prot,
+				   enum kvm_pgtable_walk_flags flags);
 
 /**
  * kvm_pgtable_stage2_flush_range() - Clean and invalidate data cache to Point
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 0470aedb4bf4..b7a3b5363235 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -1307,7 +1307,7 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
 }
 
 int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
-				   enum kvm_pgtable_prot prot)
+				   enum kvm_pgtable_prot prot, enum kvm_pgtable_walk_flags flags)
 {
 	int ret;
 	s8 level;
@@ -1325,9 +1325,7 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
 	if (prot & KVM_PGTABLE_PROT_X)
 		clr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
 
-	ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level,
-				       KVM_PGTABLE_WALK_HANDLE_FAULT |
-				       KVM_PGTABLE_WALK_SHARED);
+	ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level, flags);
 	if (!ret || ret == -EAGAIN)
 		kvm_call_hyp(__kvm_tlb_flush_vmid_ipa_nsh, pgt->mmu, addr, level);
 	return ret;
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index a2339b76c826..641e4fec1659 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1452,6 +1452,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
 	struct kvm_pgtable *pgt;
 	struct page *page;
+	enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED;
 
 	if (fault_is_perm)
 		fault_granule = kvm_vcpu_trap_get_perm_fault_granule(vcpu);
@@ -1695,13 +1696,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		 * PTE, which will be preserved.
 		 */
 		prot &= ~KVM_NV_GUEST_MAP_SZ;
-		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot);
+		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot, flags);
 	} else {
 		ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
 					     __pfn_to_phys(pfn), prot,
-					     memcache,
-					     KVM_PGTABLE_WALK_HANDLE_FAULT |
-					     KVM_PGTABLE_WALK_SHARED);
+					     memcache, flags);
 	}
 
 out_unlock:
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:52 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:52 +0000
Subject: [PATCH v3 07/18] KVM: arm64: Make kvm_pgtable_stage2_init() a static
 inline function
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-8-qperret@google.com>

Turn kvm_pgtable_stage2_init() into a static inline function instead of
a macro. This will allow the usage of typeof() on it later on.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index c2f4149283ef..04418b5e3004 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -526,8 +526,11 @@ int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
 			      enum kvm_pgtable_stage2_flags flags,
 			      kvm_pgtable_force_pte_cb_t force_pte_cb);
 
-#define kvm_pgtable_stage2_init(pgt, mmu, mm_ops) \
-	__kvm_pgtable_stage2_init(pgt, mmu, mm_ops, 0, NULL)
+static inline int kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
+					  struct kvm_pgtable_mm_ops *mm_ops)
+{
+	return __kvm_pgtable_stage2_init(pgt, mmu, mm_ops, 0, NULL);
+}
 
 /**
  * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:53 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:53 +0000
Subject: [PATCH v3 08/18] KVM: arm64: Add {get,put}_pkvm_hyp_vm() helpers
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-9-qperret@google.com>

In preparation for accessing pkvm_hyp_vm structures at EL2 in a context
where we can't always expect a vCPU to be loaded (e.g. MMU notifiers),
introduce get/put helpers to get temporary references to hyp VMs from
any context.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  3 +++
 arch/arm64/kvm/hyp/nvhe/pkvm.c         | 20 ++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 24a9a8330d19..f361d8b91930 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -70,4 +70,7 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 					 unsigned int vcpu_idx);
 void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
 
+struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
+void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
+
 #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 071993c16de8..d46a02e24e4a 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -327,6 +327,26 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 	hyp_spin_unlock(&vm_table_lock);
 }
 
+struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
+{
+	struct pkvm_hyp_vm *hyp_vm;
+
+	hyp_spin_lock(&vm_table_lock);
+	hyp_vm = get_vm_by_handle(handle);
+	if (hyp_vm)
+		hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
+	hyp_spin_unlock(&vm_table_lock);
+
+	return hyp_vm;
+}
+
+void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm)
+{
+	hyp_spin_lock(&vm_table_lock);
+	hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
+	hyp_spin_unlock(&vm_table_lock);
+}
+
 static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
 {
 	struct kvm *kvm = &hyp_vm->kvm;
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:54 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:54 +0000
Subject: [PATCH v3 09/18] KVM: arm64: Introduce __pkvm_vcpu_{load,put}()
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-10-qperret@google.com>

From: Marc Zyngier <maz at kernel.org>

Rather than look-up the hyp vCPU on every run hypercall at EL2,
introduce a per-CPU 'loaded_hyp_vcpu' tracking variable which is updated
by a pair of load/put hypercalls called directly from
kvm_arch_vcpu_{load,put}() when pKVM is enabled.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h       |  2 ++
 arch/arm64/kvm/arm.c                   | 14 ++++++++
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  7 ++++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c     | 47 ++++++++++++++++++++------
 arch/arm64/kvm/hyp/nvhe/pkvm.c         | 29 ++++++++++++++++
 arch/arm64/kvm/vgic/vgic-v3.c          |  6 ++--
 6 files changed, 93 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index ca2590344313..89c0fac69551 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -79,6 +79,8 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
 	__KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu,
 	__KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
+	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
+	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
 };
 
 #define DECLARE_KVM_VHE_SYM(sym)	extern char sym[]
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..55cc62b2f469 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -619,12 +619,26 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 	kvm_arch_vcpu_load_debug_state_flags(vcpu);
 
+	if (is_protected_kvm_enabled()) {
+		kvm_call_hyp_nvhe(__pkvm_vcpu_load,
+				  vcpu->kvm->arch.pkvm.handle,
+				  vcpu->vcpu_idx, vcpu->arch.hcr_el2);
+		kvm_call_hyp(__vgic_v3_restore_vmcr_aprs,
+			     &vcpu->arch.vgic_cpu.vgic_v3);
+	}
+
 	if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus))
 		vcpu_set_on_unsupported_cpu(vcpu);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+	if (is_protected_kvm_enabled()) {
+		kvm_call_hyp(__vgic_v3_save_vmcr_aprs,
+			     &vcpu->arch.vgic_cpu.vgic_v3);
+		kvm_call_hyp_nvhe(__pkvm_vcpu_put);
+	}
+
 	kvm_arch_vcpu_put_debug_state_flags(vcpu);
 	kvm_arch_vcpu_put_fp(vcpu);
 	if (has_vhe())
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index f361d8b91930..be52c5b15e21 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -20,6 +20,12 @@ struct pkvm_hyp_vcpu {
 
 	/* Backpointer to the host's (untrusted) vCPU instance. */
 	struct kvm_vcpu *host_vcpu;
+
+	/*
+	 * If this hyp vCPU is loaded, then this is a backpointer to the
+	 * per-cpu pointer tracking us. Otherwise, NULL if not loaded.
+	 */
+	struct pkvm_hyp_vcpu **loaded_hyp_vcpu;
 };
 
 /*
@@ -69,6 +75,7 @@ int __pkvm_teardown_vm(pkvm_handle_t handle);
 struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 					 unsigned int vcpu_idx);
 void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
+struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void);
 
 struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
 void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 6aa0b13d86e5..95d78db315b3 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -141,16 +141,46 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 		host_cpu_if->vgic_lr[i] = hyp_cpu_if->vgic_lr[i];
 }
 
+static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(unsigned int, vcpu_idx, host_ctxt, 2);
+	DECLARE_REG(u64, hcr_el2, host_ctxt, 3);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+
+	if (!is_protected_kvm_enabled())
+		return;
+
+	hyp_vcpu = pkvm_load_hyp_vcpu(handle, vcpu_idx);
+	if (!hyp_vcpu)
+		return;
+
+	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
+		/* Propagate WFx trapping flags */
+		hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWE | HCR_TWI);
+		hyp_vcpu->vcpu.arch.hcr_el2 |= hcr_el2 & (HCR_TWE | HCR_TWI);
+	}
+}
+
+static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt)
+{
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+
+	if (!is_protected_kvm_enabled())
+		return;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (hyp_vcpu)
+		pkvm_put_hyp_vcpu(hyp_vcpu);
+}
+
 static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, host_vcpu, host_ctxt, 1);
 	int ret;
 
-	host_vcpu = kern_hyp_va(host_vcpu);
-
 	if (unlikely(is_protected_kvm_enabled())) {
-		struct pkvm_hyp_vcpu *hyp_vcpu;
-		struct kvm *host_kvm;
+		struct pkvm_hyp_vcpu *hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
 
 		/*
 		 * KVM (and pKVM) doesn't support SME guests for now, and
@@ -163,9 +193,6 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 			goto out;
 		}
 
-		host_kvm = kern_hyp_va(host_vcpu->kvm);
-		hyp_vcpu = pkvm_load_hyp_vcpu(host_kvm->arch.pkvm.handle,
-					      host_vcpu->vcpu_idx);
 		if (!hyp_vcpu) {
 			ret = -EINVAL;
 			goto out;
@@ -176,12 +203,10 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 		ret = __kvm_vcpu_run(&hyp_vcpu->vcpu);
 
 		sync_hyp_vcpu(hyp_vcpu);
-		pkvm_put_hyp_vcpu(hyp_vcpu);
 	} else {
 		/* The host is fully trusted, run its vCPU directly. */
-		ret = __kvm_vcpu_run(host_vcpu);
+		ret = __kvm_vcpu_run(kern_hyp_va(host_vcpu));
 	}
-
 out:
 	cpu_reg(host_ctxt, 1) =  ret;
 }
@@ -409,6 +434,8 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_init_vm),
 	HANDLE_FUNC(__pkvm_init_vcpu),
 	HANDLE_FUNC(__pkvm_teardown_vm),
+	HANDLE_FUNC(__pkvm_vcpu_load),
+	HANDLE_FUNC(__pkvm_vcpu_put),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index d46a02e24e4a..496d186efb03 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -23,6 +23,12 @@ unsigned int kvm_arm_vmid_bits;
 
 unsigned int kvm_host_sve_max_vl;
 
+/*
+ * The currently loaded hyp vCPU for each physical CPU. Used only when
+ * protected KVM is enabled, but for both protected and non-protected VMs.
+ */
+static DEFINE_PER_CPU(struct pkvm_hyp_vcpu *, loaded_hyp_vcpu);
+
 /*
  * Set trap register values based on features in ID_AA64PFR0.
  */
@@ -306,15 +312,30 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 	struct pkvm_hyp_vcpu *hyp_vcpu = NULL;
 	struct pkvm_hyp_vm *hyp_vm;
 
+	/* Cannot load a new vcpu without putting the old one first. */
+	if (__this_cpu_read(loaded_hyp_vcpu))
+		return NULL;
+
 	hyp_spin_lock(&vm_table_lock);
 	hyp_vm = get_vm_by_handle(handle);
 	if (!hyp_vm || hyp_vm->nr_vcpus <= vcpu_idx)
 		goto unlock;
 
 	hyp_vcpu = hyp_vm->vcpus[vcpu_idx];
+
+	/* Ensure vcpu isn't loaded on more than one cpu simultaneously. */
+	if (unlikely(hyp_vcpu->loaded_hyp_vcpu)) {
+		hyp_vcpu = NULL;
+		goto unlock;
+	}
+
+	hyp_vcpu->loaded_hyp_vcpu = this_cpu_ptr(&loaded_hyp_vcpu);
 	hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
 unlock:
 	hyp_spin_unlock(&vm_table_lock);
+
+	if (hyp_vcpu)
+		__this_cpu_write(loaded_hyp_vcpu, hyp_vcpu);
 	return hyp_vcpu;
 }
 
@@ -323,10 +344,18 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 	struct pkvm_hyp_vm *hyp_vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu);
 
 	hyp_spin_lock(&vm_table_lock);
+	hyp_vcpu->loaded_hyp_vcpu = NULL;
+	__this_cpu_write(loaded_hyp_vcpu, NULL);
 	hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
 	hyp_spin_unlock(&vm_table_lock);
 }
 
+struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void)
+{
+	return __this_cpu_read(loaded_hyp_vcpu);
+
+}
+
 struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
 {
 	struct pkvm_hyp_vm *hyp_vm;
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index f267bc2486a1..c2ef41fff079 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -734,7 +734,8 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
-	kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
+	if (likely(!is_protected_kvm_enabled()))
+		kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
 
 	if (has_vhe())
 		__vgic_v3_activate_traps(cpu_if);
@@ -746,7 +747,8 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
-	kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
+	if (likely(!is_protected_kvm_enabled()))
+		kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
 	WARN_ON(vgic_v4_put(vcpu));
 
 	if (has_vhe())
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:55 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:55 +0000
Subject: [PATCH v3 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-11-qperret@google.com>

In preparation for handling guest stage-2 mappings at EL2, introduce a
new pKVM hypercall allowing to share pages with non-protected guests.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/include/asm/kvm_host.h             |  3 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/include/nvhe/memory.h      |  2 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 34 +++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 72 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  7 ++
 7 files changed, 120 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 89c0fac69551..449337f5b2a3 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -65,6 +65,7 @@ enum __kvm_host_smccc_func {
 	/* Hypercalls available after pKVM finalisation */
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e18e9244d17a..1246f1d01dbf 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -771,6 +771,9 @@ struct kvm_vcpu_arch {
 	/* Cache some mmu pages needed inside spinlock regions */
 	struct kvm_mmu_memory_cache mmu_page_cache;
 
+	/* Pages to top-up the pKVM/EL2 guest pool */
+	struct kvm_hyp_memcache pkvm_memcache;
+
 	/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
 	u64 vsesr_el2;
 
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 25038ac705d8..a7976e50f556 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -39,6 +39,7 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages);
 int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
+int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index 8bd9a539f260..cc431820c6ce 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -46,6 +46,8 @@ struct hyp_page {
 
 	/* Host (non-meta) state. Guarded by the host stage-2 lock. */
 	enum pkvm_page_state host_state : 8;
+
+	u32 host_share_guest_count;
 };
 
 extern u64 __hyp_vmemmap;
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 95d78db315b3..d659462fbf5d 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -211,6 +211,39 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+static int pkvm_refill_memcache(struct pkvm_hyp_vcpu *hyp_vcpu)
+{
+	struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
+
+	return refill_memcache(&hyp_vcpu->vcpu.arch.pkvm_memcache,
+			       host_vcpu->arch.pkvm_memcache.nr_pages,
+			       &host_vcpu->arch.pkvm_memcache);
+}
+
+static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, pfn, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 3);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		goto out;
+
+	ret = pkvm_refill_memcache(hyp_vcpu);
+	if (ret)
+		goto out;
+
+	ret = __pkvm_host_share_guest(pfn, gfn, hyp_vcpu, prot);
+out:
+	cpu_reg(host_ctxt, 1) =  ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -420,6 +453,7 @@ static const hcall_t host_hcall[] = {
 
 	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
+	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 12bb5445fe47..fb9592e721cf 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -867,6 +867,27 @@ static int hyp_complete_donation(u64 addr,
 	return pkvm_create_mappings_locked(start, end, prot);
 }
 
+static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr)
+{
+	if (!kvm_pte_valid(pte))
+		return PKVM_NOPAGE;
+
+	return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
+}
+
+static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
+					  u64 size, enum pkvm_page_state state)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	struct check_walk_data d = {
+		.desired	= state,
+		.get_page_state	= guest_get_page_state,
+	};
+
+	hyp_assert_lock_held(&vm->lock);
+	return check_page_state_range(&vm->pgt, addr, size, &d);
+}
+
 static int check_share(struct pkvm_mem_share *share)
 {
 	const struct pkvm_mem_transition *tx = &share->tx;
@@ -1349,3 +1370,54 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
 
 	return ret;
 }
+
+int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
+			    enum kvm_pgtable_prot prot)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	u64 phys = hyp_pfn_to_phys(pfn);
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	struct hyp_page *page;
+	int ret;
+
+	if (prot & ~KVM_PGTABLE_PROT_RWX)
+		return -EINVAL;
+
+	ret = check_range_allowed_memory(phys, phys + PAGE_SIZE);
+	if (ret)
+		return ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __guest_check_page_state_range(vcpu, ipa, PAGE_SIZE, PKVM_NOPAGE);
+	if (ret)
+		goto unlock;
+
+	page = hyp_phys_to_page(phys);
+	switch (page->host_state) {
+	case PKVM_PAGE_OWNED:
+		WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_OWNED));
+		break;
+	case PKVM_PAGE_SHARED_OWNED:
+		if (page->host_share_guest_count)
+			break;
+		/* Only host to np-guest multi-sharing is tolerated */
+		WARN_ON(1);
+		fallthrough;
+	default:
+		ret = -EPERM;
+		goto unlock;
+	}
+
+	WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys,
+				       pkvm_mkstate(prot, PKVM_PAGE_SHARED_BORROWED),
+				       &vcpu->vcpu.arch.pkvm_memcache, 0));
+	page->host_share_guest_count++;
+
+unlock:
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 496d186efb03..f2e363fe6b84 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -795,6 +795,13 @@ int __pkvm_teardown_vm(pkvm_handle_t handle)
 	/* Push the metadata pages to the teardown memcache */
 	for (idx = 0; idx < hyp_vm->nr_vcpus; ++idx) {
 		struct pkvm_hyp_vcpu *hyp_vcpu = hyp_vm->vcpus[idx];
+		struct kvm_hyp_memcache *vcpu_mc = &hyp_vcpu->vcpu.arch.pkvm_memcache;
+
+		while (vcpu_mc->nr_pages) {
+			void *addr = pop_hyp_memcache(vcpu_mc, hyp_phys_to_virt);
+			push_hyp_memcache(mc, addr, hyp_virt_to_phys);
+			unmap_donated_memory_noclear(addr, PAGE_SIZE);
+		}
 
 		teardown_donated_memory(mc, hyp_vcpu, sizeof(*hyp_vcpu));
 	}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:56 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:56 +0000
Subject: [PATCH v3 11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-12-qperret@google.com>

In preparation for letting the host unmap pages from non-protected
guests, introduce a new hypercall implementing the host-unshare-guest
transition.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  6 ++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 21 ++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 67 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/pkvm.c                | 12 ++++
 6 files changed, 108 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 449337f5b2a3..0b6c4d325134 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -66,6 +66,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index a7976e50f556..e528a42ed60e 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -40,6 +40,7 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
+int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index be52c5b15e21..0cc2a429f1fb 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -64,6 +64,11 @@ static inline bool pkvm_hyp_vcpu_is_protected(struct pkvm_hyp_vcpu *hyp_vcpu)
 	return vcpu_is_protected(&hyp_vcpu->vcpu);
 }
 
+static inline bool pkvm_hyp_vm_is_protected(struct pkvm_hyp_vm *hyp_vm)
+{
+	return kvm_vm_is_protected(&hyp_vm->kvm);
+}
+
 void pkvm_hyp_vm_table_init(void *tbl);
 
 int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
@@ -78,6 +83,7 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
 struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void);
 
 struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
+struct pkvm_hyp_vm *get_np_pkvm_hyp_vm(pkvm_handle_t handle);
 void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
 
 #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index d659462fbf5d..3c3a27c985a2 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -244,6 +244,26 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	struct pkvm_hyp_vm *hyp_vm;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vm = get_np_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		goto out;
+
+	ret = __pkvm_host_unshare_guest(gfn, hyp_vm);
+	put_pkvm_hyp_vm(hyp_vm);
+out:
+	cpu_reg(host_ctxt, 1) =  ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -454,6 +474,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
 	HANDLE_FUNC(__pkvm_host_share_guest),
+	HANDLE_FUNC(__pkvm_host_unshare_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index fb9592e721cf..30243b7922f1 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1421,3 +1421,70 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
 
 	return ret;
 }
+
+static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)
+{
+	enum pkvm_page_state state;
+	struct hyp_page *page;
+	kvm_pte_t pte;
+	u64 phys;
+	s8 level;
+	int ret;
+
+	ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
+	if (ret)
+		return ret;
+	if (level != KVM_PGTABLE_LAST_LEVEL)
+		return -E2BIG;
+	if (!kvm_pte_valid(pte))
+		return -ENOENT;
+
+	state = guest_get_page_state(pte, ipa);
+	if (state != PKVM_PAGE_SHARED_BORROWED)
+		return -EPERM;
+
+	phys = kvm_pte_to_phys(pte);
+	ret = check_range_allowed_memory(phys, phys + PAGE_SIZE);
+	if (WARN_ON(ret))
+		return ret;
+
+	page = hyp_phys_to_page(phys);
+	if (page->host_state != PKVM_PAGE_SHARED_OWNED)
+		return -EPERM;
+	if (WARN_ON(!page->host_share_guest_count))
+		return -EINVAL;
+
+	*__phys = phys;
+
+	return 0;
+}
+
+int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *vm)
+{
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	struct hyp_page *page;
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (ret)
+		goto unlock;
+
+	ret = kvm_pgtable_stage2_unmap(&vm->pgt, ipa, PAGE_SIZE);
+	if (ret)
+		goto unlock;
+
+	page = hyp_phys_to_page(phys);
+	page->host_share_guest_count--;
+	if (!page->host_share_guest_count)
+		WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_OWNED));
+
+unlock:
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index f2e363fe6b84..1b0982fa5ba8 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -376,6 +376,18 @@ void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm)
 	hyp_spin_unlock(&vm_table_lock);
 }
 
+struct pkvm_hyp_vm *get_np_pkvm_hyp_vm(pkvm_handle_t handle)
+{
+	struct pkvm_hyp_vm *hyp_vm = get_pkvm_hyp_vm(handle);
+
+	if (hyp_vm && pkvm_hyp_vm_is_protected(hyp_vm)) {
+		put_pkvm_hyp_vm(hyp_vm);
+		hyp_vm = NULL;
+	}
+
+	return hyp_vm;
+}
+
 static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
 {
 	struct kvm *kvm = &hyp_vm->kvm;
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:57 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:57 +0000
Subject: [PATCH v3 12/18] KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-13-qperret@google.com>

Introduce a new hypercall allowing the host to relax the stage-2
permissions of mappings in a non-protected guest page-table. It will be
used later once we start allowing RO memslots and dirty logging.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 20 ++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 23 +++++++++++++++++++
 4 files changed, 45 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 0b6c4d325134..66ee8542dcc9 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -67,6 +67,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index e528a42ed60e..a308dcd3b5b8 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -41,6 +41,7 @@ int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
+int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 3c3a27c985a2..287e4ee93ef2 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -264,6 +264,25 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, gfn, host_ctxt, 1);
+	DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 2);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		goto out;
+
+	ret = __pkvm_host_relax_perms_guest(gfn, hyp_vcpu, prot);
+out:
+	cpu_reg(host_ctxt, 1) = ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -475,6 +494,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
 	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
+	HANDLE_FUNC(__pkvm_host_relax_perms_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 30243b7922f1..aa8e0408aebb 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1488,3 +1488,26 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *vm)
 
 	return ret;
 }
+
+int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	if (prot & ~KVM_PGTABLE_PROT_RWX)
+		return -EINVAL;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (!ret)
+		ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:58 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:58 +0000
Subject: [PATCH v3 13/18] KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-14-qperret@google.com>

Introduce a new hypercall to remove the write permission from a
non-protected guest stage-2 mapping. This will be used for e.g. enabling
dirty logging.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 21 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 +++++++++++++++++
 4 files changed, 42 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 66ee8542dcc9..8663a588cf34 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -68,6 +68,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index a308dcd3b5b8..fc9fdd5b0a52 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -42,6 +42,7 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
+int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 287e4ee93ef2..98d317735107 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -283,6 +283,26 @@ static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *host_ct
 	cpu_reg(host_ctxt, 1) = ret;
 }
 
+static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	struct pkvm_hyp_vm *hyp_vm;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vm = get_np_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		goto out;
+
+	ret = __pkvm_host_wrprotect_guest(gfn, hyp_vm);
+	put_pkvm_hyp_vm(hyp_vm);
+out:
+	cpu_reg(host_ctxt, 1) = ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -495,6 +515,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
 	HANDLE_FUNC(__pkvm_host_relax_perms_guest),
+	HANDLE_FUNC(__pkvm_host_wrprotect_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index aa8e0408aebb..94e4251b5077 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1511,3 +1511,22 @@ int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_
 
 	return ret;
 }
+
+int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
+{
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (!ret)
+		ret = kvm_pgtable_stage2_wrprotect(&vm->pgt, ipa, PAGE_SIZE);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:59 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:59 +0000
Subject: [PATCH v3 14/18] KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-15-qperret@google.com>

Plumb the kvm_stage2_test_clear_young() callback into pKVM for
non-protected guest. It will be later be called from MMU notifiers.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 22 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 ++++++++++++++++
 4 files changed, 43 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 8663a588cf34..4f97155d6323 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -69,6 +69,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index fc9fdd5b0a52..b3aaad150b3e 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -43,6 +43,7 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum k
 int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
+int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 98d317735107..616e172a9c48 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -303,6 +303,27 @@ static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt
 	cpu_reg(host_ctxt, 1) = ret;
 }
 
+static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	DECLARE_REG(bool, mkold, host_ctxt, 3);
+	struct pkvm_hyp_vm *hyp_vm;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vm = get_np_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		goto out;
+
+	ret = __pkvm_host_test_clear_young_guest(gfn, mkold, hyp_vm);
+	put_pkvm_hyp_vm(hyp_vm);
+out:
+	cpu_reg(host_ctxt, 1) = ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -516,6 +537,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
 	HANDLE_FUNC(__pkvm_host_relax_perms_guest),
 	HANDLE_FUNC(__pkvm_host_wrprotect_guest),
+	HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 94e4251b5077..0e42c3baaf4b 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1530,3 +1530,22 @@ int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
 
 	return ret;
 }
+
+int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm)
+{
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (!ret)
+		ret = kvm_pgtable_stage2_test_clear_young(&vm->pgt, ipa, PAGE_SIZE, mkold);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:58:00 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:58:00 +0000
Subject: [PATCH v3 15/18] KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-16-qperret@google.com>

Plumb the kvm_pgtable_stage2_mkyoung() callback into pKVM for
non-protected guests. It will be called later from the fault handling
path.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 19 ++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 20 +++++++++++++++++++
 4 files changed, 41 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 4f97155d6323..a3b07db2776c 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -70,6 +70,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_mkyoung_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index b3aaad150b3e..65c34753d86c 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -44,6 +44,7 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
+int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 616e172a9c48..32c4627b5b5b 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -324,6 +324,24 @@ static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *ho
 	cpu_reg(host_ctxt, 1) = ret;
 }
 
+static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, gfn, host_ctxt, 1);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		goto out;
+
+	ret = __pkvm_host_mkyoung_guest(gfn, hyp_vcpu);
+out:
+	cpu_reg(host_ctxt, 1) =  ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -538,6 +556,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_relax_perms_guest),
 	HANDLE_FUNC(__pkvm_host_wrprotect_guest),
 	HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
+	HANDLE_FUNC(__pkvm_host_mkyoung_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 0e42c3baaf4b..eae03509d371 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1549,3 +1549,23 @@ int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *
 
 	return ret;
 }
+
+int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (!ret)
+		kvm_pgtable_stage2_mkyoung(&vm->pgt, ipa, 0);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:58:01 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:58:01 +0000
Subject: [PATCH v3 16/18] KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-17-qperret@google.com>

Introduce a new hypercall to flush the TLBs of non-protected guests. The
host kernel will be responsible for issuing this hypercall after changing
stage-2 permissions using the __pkvm_host_relax_guest_perms() or
__pkvm_host_wrprotect_guest() paths. This is left under the host's
responsibility for performance reasons.

Note however that the TLB maintenance for all *unmap* operations still
remains entirely under the hypervisor's responsibility for security
reasons -- an unmapped page may be donated to another entity, so a stale
TLB entry could be used to leak private data.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h   |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index a3b07db2776c..002088c6e297 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -87,6 +87,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
 	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
 	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
+	__KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
 };
 
 #define DECLARE_KVM_VHE_SYM(sym)	extern char sym[]
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 32c4627b5b5b..130f5f23bcb5 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -389,6 +389,22 @@ static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
 	__kvm_tlb_flush_vmid(kern_hyp_va(mmu));
 }
 
+static void handle___pkvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	struct pkvm_hyp_vm *hyp_vm;
+
+	if (!is_protected_kvm_enabled())
+		return;
+
+	hyp_vm = get_np_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		return;
+
+	__kvm_tlb_flush_vmid(&hyp_vm->kvm.arch.mmu);
+	put_pkvm_hyp_vm(hyp_vm);
+}
+
 static void handle___kvm_flush_cpu_context(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1);
@@ -573,6 +589,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_teardown_vm),
 	HANDLE_FUNC(__pkvm_vcpu_load),
 	HANDLE_FUNC(__pkvm_vcpu_put),
+	HANDLE_FUNC(__pkvm_tlb_flush_vmid),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:58:02 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:58:02 +0000
Subject: [PATCH v3 17/18] KVM: arm64: Introduce the EL1 pKVM MMU
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-18-qperret@google.com>

Introduce a set of helper functions allowing to manipulate the pKVM
guest stage-2 page-tables from EL1 using pKVM's HVC interface.

Each helper has an exact one-to-one correspondance with the traditional
kvm_pgtable_stage2_*() functions from pgtable.c, with a strictly
matching prototype. This will ease plumbing later on in mmu.c.

These callbacks track the gfn->pfn mappings in a simple rb_tree indexed
by IPA in lieu of a page-table. This rb-tree is kept in sync with pKVM's
state and is protected by a new rwlock -- the existing mmu_lock
protection does not suffice in the map() path where the tree must be
modified while user_mem_abort() only acquires a read_lock.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_host.h    |   1 +
 arch/arm64/include/asm/kvm_pgtable.h |  23 ++--
 arch/arm64/include/asm/kvm_pkvm.h    |  23 ++++
 arch/arm64/kvm/pkvm.c                | 198 +++++++++++++++++++++++++++
 4 files changed, 236 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 1246f1d01dbf..f23f4ea9ec8b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -85,6 +85,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
 struct kvm_hyp_memcache {
 	phys_addr_t head;
 	unsigned long nr_pages;
+	struct pkvm_mapping *mapping; /* only used from EL1 */
 };
 
 static inline void push_hyp_memcache(struct kvm_hyp_memcache *mc,
diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 04418b5e3004..6b9d274052c7 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -412,15 +412,20 @@ static inline bool kvm_pgtable_walk_lock_held(void)
  *			be used instead of block mappings.
  */
 struct kvm_pgtable {
-	u32					ia_bits;
-	s8					start_level;
-	kvm_pteref_t				pgd;
-	struct kvm_pgtable_mm_ops		*mm_ops;
-
-	/* Stage-2 only */
-	struct kvm_s2_mmu			*mmu;
-	enum kvm_pgtable_stage2_flags		flags;
-	kvm_pgtable_force_pte_cb_t		force_pte_cb;
+	union {
+		struct rb_root					pkvm_mappings;
+		struct {
+			u32					ia_bits;
+			s8					start_level;
+			kvm_pteref_t				pgd;
+			struct kvm_pgtable_mm_ops		*mm_ops;
+
+			/* Stage-2 only */
+			enum kvm_pgtable_stage2_flags		flags;
+			kvm_pgtable_force_pte_cb_t		force_pte_cb;
+		};
+	};
+	struct kvm_s2_mmu					*mmu;
 };
 
 /**
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index cd56acd9a842..76a8b70176a6 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -137,4 +137,27 @@ static inline size_t pkvm_host_sve_state_size(void)
 			SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_sve_max_vl)));
 }
 
+struct pkvm_mapping {
+	struct rb_node node;
+	u64 gfn;
+	u64 pfn;
+};
+
+int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops);
+void pkvm_pgtable_destroy(struct kvm_pgtable *pgt);
+int pkvm_pgtable_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
+			   u64 phys, enum kvm_pgtable_prot prot,
+			   void *mc, enum kvm_pgtable_walk_flags flags);
+int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
+int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
+int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
+bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold);
+int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
+			     enum kvm_pgtable_walk_flags flags);
+void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags);
+int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc);
+void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level);
+kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
+					enum kvm_pgtable_prot prot, void *mc, bool force_pte);
+
 #endif	/* __ARM64_KVM_PKVM_H__ */
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index 85117ea8f351..9de9159afa5a 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/kmemleak.h>
 #include <linux/kvm_host.h>
+#include <asm/kvm_mmu.h>
 #include <linux/memblock.h>
 #include <linux/mutex.h>
 #include <linux/sort.h>
@@ -268,3 +269,200 @@ static int __init finalize_pkvm(void)
 	return ret;
 }
 device_initcall_sync(finalize_pkvm);
+
+static int cmp_mappings(struct rb_node *node, const struct rb_node *parent)
+{
+	struct pkvm_mapping *a = rb_entry(node, struct pkvm_mapping, node);
+	struct pkvm_mapping *b = rb_entry(parent, struct pkvm_mapping, node);
+
+	if (a->gfn < b->gfn)
+		return -1;
+	if (a->gfn > b->gfn)
+		return 1;
+	return 0;
+}
+
+static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
+{
+	struct rb_node *node = root->rb_node, *prev = NULL;
+	struct pkvm_mapping *mapping;
+
+	while (node) {
+		mapping = rb_entry(node, struct pkvm_mapping, node);
+		if (mapping->gfn == gfn)
+			return node;
+		prev = node;
+		node = (gfn < mapping->gfn) ? node->rb_left : node->rb_right;
+	}
+
+	return prev;
+}
+
+/*
+ * __tmp is updated to rb_next(__tmp) *before* entering the body of the loop to allow freeing
+ * of __map inline.
+ */
+#define for_each_mapping_in_range_safe(__pgt, __start, __end, __map)					\
+	for (struct rb_node *__tmp = find_first_mapping_node(&(__pgt)->pkvm_mappings,			\
+							     ((__start) >> PAGE_SHIFT));		\
+	     __tmp && ({										\
+				__map = rb_entry(__tmp, struct pkvm_mapping, node);			\
+				__tmp = rb_next(__tmp);							\
+				true;									\
+		       });										\
+	    )												\
+		if (__map->gfn < ((__start) >> PAGE_SHIFT))						\
+			continue;									\
+		else if (__map->gfn >= ((__end) >> PAGE_SHIFT))						\
+			break;										\
+		else
+
+int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops)
+{
+	pgt->pkvm_mappings	= RB_ROOT;
+	pgt->mmu		= mmu;
+
+	return 0;
+}
+
+void pkvm_pgtable_destroy(struct kvm_pgtable *pgt)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	pkvm_handle_t handle = kvm->arch.pkvm.handle;
+	struct pkvm_mapping *mapping;
+	struct rb_node *node;
+
+	if (!handle)
+		return;
+
+	node = rb_first(&pgt->pkvm_mappings);
+	while (node) {
+		mapping = rb_entry(node, struct pkvm_mapping, node);
+		kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
+		node = rb_next(node);
+		rb_erase(&mapping->node, &pgt->pkvm_mappings);
+		kfree(mapping);
+	}
+}
+
+int pkvm_pgtable_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
+			   u64 phys, enum kvm_pgtable_prot prot,
+			   void *mc, enum kvm_pgtable_walk_flags flags)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	struct pkvm_mapping *mapping = NULL;
+	struct kvm_hyp_memcache *cache = mc;
+	u64 gfn = addr >> PAGE_SHIFT;
+	u64 pfn = phys >> PAGE_SHIFT;
+	int ret;
+
+	if (size != PAGE_SIZE)
+		return -EINVAL;
+
+	lockdep_assert_held_write(&kvm->mmu_lock);
+	ret = kvm_call_hyp_nvhe(__pkvm_host_share_guest, pfn, gfn, prot);
+	if (ret) {
+		/* Is the gfn already mapped due to a racing vCPU? */
+		if (ret == -EPERM)
+			return -EAGAIN;
+	}
+
+	swap(mapping, cache->mapping);
+	mapping->gfn = gfn;
+	mapping->pfn = pfn;
+	WARN_ON(rb_find_add(&mapping->node, &pgt->pkvm_mappings, cmp_mappings));
+
+	return ret;
+}
+
+int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	pkvm_handle_t handle = kvm->arch.pkvm.handle;
+	struct pkvm_mapping *mapping;
+	int ret = 0;
+
+	lockdep_assert_held_write(&kvm->mmu_lock);
+	for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
+		if (WARN_ON(ret))
+			break;
+		rb_erase(&mapping->node, &pgt->pkvm_mappings);
+		kfree(mapping);
+	}
+
+	return ret;
+}
+
+int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	pkvm_handle_t handle = kvm->arch.pkvm.handle;
+	struct pkvm_mapping *mapping;
+	int ret = 0;
+
+	lockdep_assert_held(&kvm->mmu_lock);
+	for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn);
+		if (WARN_ON(ret))
+			break;
+	}
+
+	return ret;
+}
+
+int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	struct pkvm_mapping *mapping;
+
+	lockdep_assert_held(&kvm->mmu_lock);
+	for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping)
+		__clean_dcache_guest_page(pfn_to_kaddr(mapping->pfn), PAGE_SIZE);
+
+	return 0;
+}
+
+bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	pkvm_handle_t handle = kvm->arch.pkvm.handle;
+	struct pkvm_mapping *mapping;
+	bool young = false;
+
+	lockdep_assert_held(&kvm->mmu_lock);
+	for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping)
+		young |= kvm_call_hyp_nvhe(__pkvm_host_test_clear_young_guest, handle, mapping->gfn,
+					   mkold);
+
+	return young;
+}
+
+int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
+			     enum kvm_pgtable_walk_flags flags)
+{
+	return kvm_call_hyp_nvhe(__pkvm_host_relax_perms_guest, addr >> PAGE_SHIFT, prot);
+}
+
+void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags)
+{
+	WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_mkyoung_guest, addr >> PAGE_SHIFT));
+}
+
+void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
+{
+	WARN_ON_ONCE(1);
+}
+
+kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
+					enum kvm_pgtable_prot prot, void *mc, bool force_pte)
+{
+	WARN_ON_ONCE(1);
+	return NULL;
+}
+
+int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc)
+{
+	WARN_ON_ONCE(1);
+	return -EINVAL;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:58:03 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:58:03 +0000
Subject: [PATCH v3 18/18] KVM: arm64: Plumb the pKVM MMU in KVM
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-19-qperret@google.com>

Introduce the KVM_PGT_S2() helper macro to allow switching from the
traditional pgtable code to the pKVM version easily in mmu.c. The cost
of this 'indirection' is expected to be very minimal due to
is_protected_kvm_enabled() being backed by a static key.

With this, everything is in place to allow the delegation of
non-protected guest stage-2 page-tables to pKVM, so let's stop using the
host's kvm_s2_mmu from EL2 and enjoy the ride.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_mmu.h   |  16 +++++
 arch/arm64/kvm/arm.c               |   9 ++-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c |   2 -
 arch/arm64/kvm/mmu.c               | 107 +++++++++++++++++++++--------
 4 files changed, 101 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 66d93e320ec8..d116ab4230e8 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -353,6 +353,22 @@ static inline bool kvm_is_nested_s2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
 	return &kvm->arch.mmu != mmu;
 }
 
+static inline void kvm_fault_lock(struct kvm *kvm)
+{
+	if (is_protected_kvm_enabled())
+		write_lock(&kvm->mmu_lock);
+	else
+		read_lock(&kvm->mmu_lock);
+}
+
+static inline void kvm_fault_unlock(struct kvm *kvm)
+{
+	if (is_protected_kvm_enabled())
+		write_unlock(&kvm->mmu_lock);
+	else
+		read_unlock(&kvm->mmu_lock);
+}
+
 #ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
 void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
 #else
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 55cc62b2f469..9bcbc7b8ed38 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -502,7 +502,10 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 
 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
-	kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+	if (!is_protected_kvm_enabled())
+		kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+	else
+		free_hyp_memcache(&vcpu->arch.pkvm_memcache);
 	kvm_timer_vcpu_terminate(vcpu);
 	kvm_pmu_vcpu_destroy(vcpu);
 	kvm_vgic_vcpu_destroy(vcpu);
@@ -574,6 +577,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	struct kvm_s2_mmu *mmu;
 	int *last_ran;
 
+	if (is_protected_kvm_enabled())
+		goto nommu;
+
 	if (vcpu_has_nv(vcpu))
 		kvm_vcpu_load_hw_mmu(vcpu);
 
@@ -594,6 +600,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		*last_ran = vcpu->vcpu_idx;
 	}
 
+nommu:
 	vcpu->cpu = cpu;
 
 	kvm_vgic_load(vcpu);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 130f5f23bcb5..258d572eed62 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -103,8 +103,6 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 	/* Limit guest vector length to the maximum supported by the host.  */
 	hyp_vcpu->vcpu.arch.sve_max_vl	= min(host_vcpu->arch.sve_max_vl, kvm_host_sve_max_vl);
 
-	hyp_vcpu->vcpu.arch.hw_mmu	= host_vcpu->arch.hw_mmu;
-
 	hyp_vcpu->vcpu.arch.mdcr_el2	= host_vcpu->arch.mdcr_el2;
 	hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE);
 	hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2) &
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 641e4fec1659..7c2995cb4577 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -15,6 +15,7 @@
 #include <asm/kvm_arm.h>
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_pgtable.h>
+#include <asm/kvm_pkvm.h>
 #include <asm/kvm_ras.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
@@ -31,6 +32,14 @@ static phys_addr_t __ro_after_init hyp_idmap_vector;
 
 static unsigned long __ro_after_init io_map_base;
 
+#define KVM_PGT_S2(fn, ...)								\
+	({										\
+		typeof(kvm_pgtable_stage2_ ## fn) *__fn = kvm_pgtable_stage2_ ## fn;	\
+		if (is_protected_kvm_enabled())						\
+			__fn = pkvm_pgtable_ ## fn;					\
+		__fn(__VA_ARGS__);							\
+	})
+
 static phys_addr_t __stage2_range_addr_end(phys_addr_t addr, phys_addr_t end,
 					   phys_addr_t size)
 {
@@ -147,7 +156,7 @@ static int kvm_mmu_split_huge_pages(struct kvm *kvm, phys_addr_t addr,
 			return -EINVAL;
 
 		next = __stage2_range_addr_end(addr, end, chunk_size);
-		ret = kvm_pgtable_stage2_split(pgt, addr, next - addr, cache);
+		ret = KVM_PGT_S2(split, pgt, addr, next - addr, cache);
 		if (ret)
 			break;
 	} while (addr = next, addr != end);
@@ -168,15 +177,23 @@ static bool memslot_is_logging(struct kvm_memory_slot *memslot)
  */
 int kvm_arch_flush_remote_tlbs(struct kvm *kvm)
 {
-	kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
+	if (is_protected_kvm_enabled())
+		kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
+	else
+		kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
 	return 0;
 }
 
 int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm,
 				      gfn_t gfn, u64 nr_pages)
 {
-	kvm_tlb_flush_vmid_range(&kvm->arch.mmu,
-				gfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT);
+	u64 size = nr_pages << PAGE_SHIFT;
+	u64 addr = gfn << PAGE_SHIFT;
+
+	if (is_protected_kvm_enabled())
+		kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
+	else
+		kvm_tlb_flush_vmid_range(&kvm->arch.mmu, addr, size);
 	return 0;
 }
 
@@ -225,7 +242,7 @@ static void stage2_free_unlinked_table_rcu_cb(struct rcu_head *head)
 	void *pgtable = page_to_virt(page);
 	s8 level = page_private(page);
 
-	kvm_pgtable_stage2_free_unlinked(&kvm_s2_mm_ops, pgtable, level);
+	KVM_PGT_S2(free_unlinked, &kvm_s2_mm_ops, pgtable, level);
 }
 
 static void stage2_free_unlinked_table(void *addr, s8 level)
@@ -280,6 +297,11 @@ static void invalidate_icache_guest_page(void *va, size_t size)
 	__invalidate_icache_guest_page(va, size);
 }
 
+static int kvm_s2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	return KVM_PGT_S2(unmap, pgt, addr, size);
+}
+
 /*
  * Unmapping vs dcache management:
  *
@@ -324,8 +346,7 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
 
 	lockdep_assert_held_write(&kvm->mmu_lock);
 	WARN_ON(size & ~PAGE_MASK);
-	WARN_ON(stage2_apply_range(mmu, start, end, kvm_pgtable_stage2_unmap,
-				   may_block));
+	WARN_ON(stage2_apply_range(mmu, start, end, kvm_s2_unmap, may_block));
 }
 
 void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
@@ -334,9 +355,14 @@ void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
 	__unmap_stage2_range(mmu, start, size, may_block);
 }
 
+static int kvm_s2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	return KVM_PGT_S2(flush, pgt, addr, size);
+}
+
 void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
 {
-	stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_flush);
+	stage2_apply_range_resched(mmu, addr, end, kvm_s2_flush);
 }
 
 static void stage2_flush_memslot(struct kvm *kvm,
@@ -942,10 +968,14 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 		return -ENOMEM;
 
 	mmu->arch = &kvm->arch;
-	err = kvm_pgtable_stage2_init(pgt, mmu, &kvm_s2_mm_ops);
+	err = KVM_PGT_S2(init, pgt, mmu, &kvm_s2_mm_ops);
 	if (err)
 		goto out_free_pgtable;
 
+	mmu->pgt = pgt;
+	if (is_protected_kvm_enabled())
+		return 0;
+
 	mmu->last_vcpu_ran = alloc_percpu(typeof(*mmu->last_vcpu_ran));
 	if (!mmu->last_vcpu_ran) {
 		err = -ENOMEM;
@@ -959,7 +989,6 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 	mmu->split_page_chunk_size = KVM_ARM_EAGER_SPLIT_CHUNK_SIZE_DEFAULT;
 	mmu->split_page_cache.gfp_zero = __GFP_ZERO;
 
-	mmu->pgt = pgt;
 	mmu->pgd_phys = __pa(pgt->pgd);
 
 	if (kvm_is_nested_s2_mmu(kvm, mmu))
@@ -968,7 +997,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 	return 0;
 
 out_destroy_pgtable:
-	kvm_pgtable_stage2_destroy(pgt);
+	KVM_PGT_S2(destroy, pgt);
 out_free_pgtable:
 	kfree(pgt);
 	return err;
@@ -1065,7 +1094,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
 	write_unlock(&kvm->mmu_lock);
 
 	if (pgt) {
-		kvm_pgtable_stage2_destroy(pgt);
+		KVM_PGT_S2(destroy, pgt);
 		kfree(pgt);
 	}
 }
@@ -1082,9 +1111,11 @@ static void *hyp_mc_alloc_fn(void *unused)
 
 void free_hyp_memcache(struct kvm_hyp_memcache *mc)
 {
-	if (is_protected_kvm_enabled())
-		__free_hyp_memcache(mc, hyp_mc_free_fn,
-				    kvm_host_va, NULL);
+	if (!is_protected_kvm_enabled())
+		return;
+
+	kfree(mc->mapping);
+	__free_hyp_memcache(mc, hyp_mc_free_fn, kvm_host_va, NULL);
 }
 
 int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages)
@@ -1092,6 +1123,12 @@ int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages)
 	if (!is_protected_kvm_enabled())
 		return 0;
 
+	if (!mc->mapping) {
+		mc->mapping = kzalloc(sizeof(struct pkvm_mapping), GFP_KERNEL_ACCOUNT);
+		if (!mc->mapping)
+			return -ENOMEM;
+	}
+
 	return __topup_hyp_memcache(mc, min_pages, hyp_mc_alloc_fn,
 				    kvm_host_pa, NULL);
 }
@@ -1130,8 +1167,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 			break;
 
 		write_lock(&kvm->mmu_lock);
-		ret = kvm_pgtable_stage2_map(pgt, addr, PAGE_SIZE, pa, prot,
-					     &cache, 0);
+		ret = KVM_PGT_S2(map, pgt, addr, PAGE_SIZE, pa, prot, &cache, 0);
 		write_unlock(&kvm->mmu_lock);
 		if (ret)
 			break;
@@ -1143,6 +1179,10 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 	return ret;
 }
 
+static int kvm_s2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	return KVM_PGT_S2(wrprotect, pgt, addr, size);
+}
 /**
  * kvm_stage2_wp_range() - write protect stage2 memory region range
  * @mmu:        The KVM stage-2 MMU pointer
@@ -1151,7 +1191,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
  */
 void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
 {
-	stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_wrprotect);
+	stage2_apply_range_resched(mmu, addr, end, kvm_s2_wrprotect);
 }
 
 /**
@@ -1442,9 +1482,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	unsigned long mmu_seq;
 	phys_addr_t ipa = fault_ipa;
 	struct kvm *kvm = vcpu->kvm;
-	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
 	struct vm_area_struct *vma;
 	short vma_shift;
+	void *memcache;
 	gfn_t gfn;
 	kvm_pfn_t pfn;
 	bool logging_active = memslot_is_logging(memslot);
@@ -1472,8 +1512,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * and a write fault needs to collapse a block entry into a table.
 	 */
 	if (!fault_is_perm || (logging_active && write_fault)) {
-		ret = kvm_mmu_topup_memory_cache(memcache,
-						 kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu));
+		int min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu);
+
+		if (!is_protected_kvm_enabled()) {
+			memcache = &vcpu->arch.mmu_page_cache;
+			ret = kvm_mmu_topup_memory_cache(memcache, min_pages);
+		} else {
+			memcache = &vcpu->arch.pkvm_memcache;
+			ret = topup_hyp_memcache(memcache, min_pages);
+		}
 		if (ret)
 			return ret;
 	}
@@ -1494,7 +1541,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * logging_active is guaranteed to never be true for VM_PFNMAP
 	 * memslots.
 	 */
-	if (logging_active) {
+	if (logging_active || is_protected_kvm_enabled()) {
 		force_pte = true;
 		vma_shift = PAGE_SHIFT;
 	} else {
@@ -1634,7 +1681,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		prot |= kvm_encode_nested_level(nested);
 	}
 
-	read_lock(&kvm->mmu_lock);
+	kvm_fault_lock(kvm);
 	pgt = vcpu->arch.hw_mmu->pgt;
 	if (mmu_invalidate_retry(kvm, mmu_seq)) {
 		ret = -EAGAIN;
@@ -1696,16 +1743,16 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		 * PTE, which will be preserved.
 		 */
 		prot &= ~KVM_NV_GUEST_MAP_SZ;
-		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot, flags);
+		ret = KVM_PGT_S2(relax_perms, pgt, fault_ipa, prot, flags);
 	} else {
-		ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
+		ret = KVM_PGT_S2(map, pgt, fault_ipa, vma_pagesize,
 					     __pfn_to_phys(pfn), prot,
 					     memcache, flags);
 	}
 
 out_unlock:
 	kvm_release_faultin_page(kvm, page, !!ret, writable);
-	read_unlock(&kvm->mmu_lock);
+	kvm_fault_unlock(kvm);
 
 	/* Mark the page dirty only if the fault is handled successfully */
 	if (writable && !ret)
@@ -1724,7 +1771,7 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 
 	read_lock(&vcpu->kvm->mmu_lock);
 	mmu = vcpu->arch.hw_mmu;
-	kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa, flags);
+	KVM_PGT_S2(mkyoung, mmu->pgt, fault_ipa, flags);
 	read_unlock(&vcpu->kvm->mmu_lock);
 }
 
@@ -1764,7 +1811,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		}
 
 		/* Falls between the IPA range and the PARange? */
-		if (fault_ipa >= BIT_ULL(vcpu->arch.hw_mmu->pgt->ia_bits)) {
+		if (fault_ipa >= BIT_ULL(VTCR_EL2_IPA(vcpu->arch.hw_mmu->vtcr))) {
 			fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
 
 			if (is_iabt)
@@ -1930,7 +1977,7 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
-	return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
+	return KVM_PGT_S2(test_clear_young, kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, true);
 	/*
@@ -1946,7 +1993,7 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
-	return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
+	return KVM_PGT_S2(test_clear_young, kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, false);
 }
-- 
2.47.1.613.gc27f4b7a9f-goog



From ninad at linux.ibm.com  Mon Dec 16 09:53:27 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 11:53:27 -0600
Subject: [PATCH v1 1/4] hwmon: pmbus-core: Add label for fan and temp
In-Reply-To: <2713e85d-f88a-49d6-8221-151e8631758c@roeck-us.net>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
 <20241212214927.3586509-2-ninad@linux.ibm.com>
 <f9d881b7-7301-476e-b281-0380dfcf0e10@roeck-us.net>
 <c7717f89-65cc-4668-a3e0-ee042cdcd426@linux.ibm.com>
 <2713e85d-f88a-49d6-8221-151e8631758c@roeck-us.net>
Message-ID: <b5f5635a-a807-42ea-a81f-22b80fe4eda0@linux.ibm.com>

Hi Guenter,


On 12/13/24 11:08, Guenter Roeck wrote:
> On 12/13/24 08:12, Ninad Palsule wrote:
>> Hello Guenter,
>>
>> On 12/12/24 16:06, Guenter Roeck wrote:
>>> On 12/12/24 13:49, Ninad Palsule wrote:
>>>> Adding label files for fan and temperature sensors in the power 
>>>> supply.
>>>> The openbmc application dbus-sensor(psusensor) requires those files to
>>>> consfigure those sensors.
>>>> Note that prefix for temp label is temp[A..C] used instead of 
>>>> temp[1..3]
>>>> as dbus-sensor(psusensor) application calculate index based on last
>>>> digit in the name so we do not want to make index double digit after
>>>> appending page index.
>>>>
>>>> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
>>>
>>> We are not going to fix userspace problems in the kernel.
>>>
>>> Guenter
>>>
>>
>> Thanks for the quick review.
>>
>> Sorry I am not clear on this. I feel that it is better to support 
>> labels for temperature
>>
>> sensors and fans like other. Are you saying we should not support 
>> these labels or
>>
>> I need update in the patch to support them better?
>>
>
> There should be no such labels. Labels are supposed to have specific 
> meanings,
> such as "this is the CPU temperature sensor", not vague meanings such 
> as "tempA".
>
> Guenter

Thanks for the quick response. I will remove these changes for now and 
will talk to you later about

better option.

Thanks & Regards,

Ninad Palsule



From dmitry.baryshkov at linaro.org  Mon Dec 16 09:55:57 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 16 Dec 2024 19:55:57 +0200
Subject: [PATCH v6 06/10] drm/display/hdmi: implement hotplug functions
In-Reply-To: <20241216-courageous-mysterious-pelican-5a8d2e@houat>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-6-50dc145a9c06@linaro.org>
 <20241216-courageous-mysterious-pelican-5a8d2e@houat>
Message-ID: <bapkgt2e33bhdmun4efcuaedshyyv7qvjgugu5y53ordw3gigl@n7zbfoga7qo7>

On Mon, Dec 16, 2024 at 06:20:04PM +0100, Maxime Ripard wrote:
> On Fri, Dec 06, 2024 at 12:16:00PM +0200, Dmitry Baryshkov wrote:
> > The HDMI Connectors need to perform a variety of tasks when the HDMI
> > connector state changes. Such tasks include setting or invalidating CEC
> > address, notifying HDMI codec driver, updating scrambler data, etc.
> > 
> > Implementing such tasks in a driver-specific callbacks is error prone.
> > Start implementing the generic helper function (currently handling only
> > the HDMI Codec framework) to be used by drivers utilizing HDMI Connector
> > framework.
> > 
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >  drivers/gpu/drm/display/drm_hdmi_state_helper.c | 61 +++++++++++++++++++++++++
> >  include/drm/display/drm_hdmi_state_helper.h     |  8 ++++
> >  2 files changed, 69 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > index 80bf2829ba89b5f84fed4fa9eb1d6302e10a4f9e..4cdeb63688b9e48acd8e8ae87a45b6253f7dd12b 100644
> > --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > @@ -769,3 +769,64 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con
> >  	return ret;
> >  }
> >  EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe);
> > +
> > +/**
> > + * drm_atomic_helper_connector_hdmi_hotplug_edid - Handle the hotplug event for the HDMI connector passing custom EDID
> > + * @connector: A pointer to the HDMI connector
> > + * @status: Connection status
> > + * @drm_edid: EDID to process
> > + *
> > + * This function should be called as a part of the .detect() / .detect_ctx()
> > + * and .force() callbacks, updating the HDMI-specific connector's data. Most
> > + * drivers should be able to use @drm_atomic_helper_connector_hdmi_hotplug()
> > + * instead.
> > + *
> > + * Returns:
> > + * Zero on success, error code on failure.
> > + */
> > +int
> > +drm_atomic_helper_connector_hdmi_hotplug_edid(struct drm_connector *connector,
> > +					      enum drm_connector_status status,
> > +					      const struct drm_edid *drm_edid)
> > +{
> > +	if (status == connector_status_disconnected) {
> > +		// TODO: also handle CEC and scramber, HDMI sink disconnected.
> > +		drm_connector_hdmi_codec_plugged_notify(connector, false);
> > +	}
> > +
> > +	drm_edid_connector_update(connector, drm_edid);
> > +
> > +	if (status == connector_status_connected) {
> > +		// TODO: also handle CEC and scramber, HDMI sink is now connected.
> > +		drm_connector_hdmi_codec_plugged_notify(connector, true);
> > +	}
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_hotplug_edid);
> 
> I think we discussed it in a previous version's thread after you sent
> that one, but I'd rather have that helper call an edid retrieval
> function than passing it edids.

Ack, I forgot to add the hook. I'll do that for the next version. I'll
add the .read_edid callback to the HDMI functions.

> 
> Also, EDIDs are mandatory for HDMI, so I'd call the function
> drm_atomic_helper_connector_hdmi_hotplug.

See below.

> 
> > +/**
> > + * drm_atomic_helper_connector_hdmi_hotplug - Handle the hotplug event for the HDMI connector
> > + * @connector: A pointer to the HDMI connector
> > + * @status: Connection status
> > + *
> > + * This function should be called as a part of the .detect() / .detect_ctx()
> > + * and .force() callbacks, updating the HDMI-specific connector's data.
> > + *
> > + * Returns:
> > + * Zero on success, error code on failure.
> > + */
> > +int
> > +drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
> > +					 enum drm_connector_status status)
> > +{
> > +	const struct drm_edid *drm_edid;
> > +	int ret;
> > +
> > +	drm_edid = drm_edid_read(connector);
> > +	ret = drm_atomic_helper_connector_hdmi_hotplug_edid(connector, status, drm_edid);
> > +	drm_edid_free(drm_edid);
> 
> Oh. Why do we need the two variants? Or is it to deal with drivers that
> don't set connector->ddc?

Yes. There are enough HDMI bridge drivers that would provide the
callback instead of the DDC bus. Adding callback should solve that.

-- 
With best wishes
Dmitry


From broonie at kernel.org  Mon Dec 16 09:56:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 17:56:57 +0000
Subject: [PATCH v3 4/5] ASoC: SOF: imx: add driver for imx95
In-Reply-To: <Z2BZ+WUY6ecIwhEt@lizhi-Precision-Tower-5810>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
 <20241216145039.3074-5-laurentiumihalcea111@gmail.com>
 <Z2BZ+WUY6ecIwhEt@lizhi-Precision-Tower-5810>
Message-ID: <03b0bcda-c351-4d76-accc-3d3e0ed9c335@sirena.org.uk>

On Mon, Dec 16, 2024 at 11:48:57AM -0500, Frank Li wrote:
> On Mon, Dec 16, 2024 at 09:50:38AM -0500, Laurentiu Mihalcea wrote:
> > From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> >
> > Add SOF driver for imx95.
> >
> > Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> > ---
> >  sound/soc/sof/imx/Kconfig  |   8 +
> >  sound/soc/sof/imx/Makefile |   2 +
> >  sound/soc/sof/imx/imx95.c  | 401 +++++++++++++++++++++++++++++++++++++
> >  3 files changed, 411 insertions(+)

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/20241216/76c6ed7a/attachment.sig>

From qperret at google.com  Mon Dec 16 09:57:45 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:45 +0000
Subject: [PATCH v3 00/18] KVM: arm64: Non-protected guest stage-2 support for pKVM
Message-ID: <20241216175803.2716565-1-qperret@google.com>

Hi all,

This is the v3 of the series adding support for non-protected guests
stage-2 to pKVM. Please refer to v1 for all the context:

  https://lore.kernel.org/kvmarm/20241104133204.85208-1-qperret at google.com/

The series is organized as follows:

 - Patches 01 to 04 move the host ownership state tracking from the
   host's stage-2 page-table to the hypervisor's vmemmap. This avoids
   fragmenting the host stage-2 for shared pages, which is only needed
   to store an annotation in the SW bits of the corresponding PTE. All
   pages mapped into non-protected guests are shared from pKVM's PoV,
   so the cost of stage-2 fragmentation will increase massively as we
   start tracking that at EL2. Note that these patches also help with
   the existing sharing for e.g. FF-A, so they could possibly be merged
   separately from the rest of the series.

 - Patches 05 to 07 implement a minor refactoring of the pgtable code to
   ease the integration of the pKVM MMU later on.

 - Patches 08 to 16 introduce all the infrastructure needed on the pKVM
   side for handling guest stage-2 page-tables at EL2.

 - Patches 17 and 18 plumb the newly introduced pKVM support into
   KVM/arm64.

Patches based on 6.13-rc3, tested on Pixel 6 and Qemu.

Changes in v3:
 - Rebased on 6.13-rc3
 - Applied Marc's rework of the for_each_mapping_in_range() macro mess
 - Removed mappings_lock in favor the mmu_lock
 - Dropped BUG_ON() from pkvm_mkstate()
 - Renamed range_is_allowed_memory() and clarified the comment inside it
 - Explicitly bail out when using host_stage2_set_owner_locked() on
   non-memory regions
 - Check PKVM_NOPAGE state as an equality rather than a bitwise
   operator
 - Reworked __pkvm_host_share_guest() to return -EPERM in case of
   illegal multi-sharing
 - Added get_np_pkvm_hyp_vm() to simplify HVC error handling in
   hyp-main.c
 - Cosmetic changes and improved coding consitency thoughout the series

Changes in v2:
 - Rebased on 6.13-rc1 (small conflicts with 2362506f7cff ("KVM: arm64:
   Don't mark "struct page" accessed when making SPTE young") in
   particular)
 - Fixed kerneldoc breakage for __unmap_stage2_range()
 - Fixed pkvm_pgtable_test_clear_young() to use correct HVC
 - Folded guest_get_valid_pte() into __check_host_unshare_guest() for
   clarity

Thanks,
Quentin

Marc Zyngier (1):
  KVM: arm64: Introduce __pkvm_vcpu_{load,put}()

Quentin Perret (17):
  KVM: arm64: Change the layout of enum pkvm_page_state
  KVM: arm64: Move enum pkvm_page_state to memory.h
  KVM: arm64: Make hyp_page::order a u8
  KVM: arm64: Move host page ownership tracking to the hyp vmemmap
  KVM: arm64: Pass walk flags to kvm_pgtable_stage2_mkyoung
  KVM: arm64: Pass walk flags to kvm_pgtable_stage2_relax_perms
  KVM: arm64: Make kvm_pgtable_stage2_init() a static inline function
  KVM: arm64: Add {get,put}_pkvm_hyp_vm() helpers
  KVM: arm64: Introduce __pkvm_host_share_guest()
  KVM: arm64: Introduce __pkvm_host_unshare_guest()
  KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
  KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
  KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
  KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
  KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
  KVM: arm64: Introduce the EL1 pKVM MMU
  KVM: arm64: Plumb the pKVM MMU in KVM

 arch/arm64/include/asm/kvm_asm.h              |   9 +
 arch/arm64/include/asm/kvm_host.h             |   4 +
 arch/arm64/include/asm/kvm_mmu.h              |  16 +
 arch/arm64/include/asm/kvm_pgtable.h          |  38 ++-
 arch/arm64/include/asm/kvm_pkvm.h             |  23 ++
 arch/arm64/kvm/arm.c                          |  23 +-
 arch/arm64/kvm/hyp/include/nvhe/gfp.h         |   6 +-
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  38 +--
 arch/arm64/kvm/hyp/include/nvhe/memory.h      |  42 ++-
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  16 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 201 ++++++++++-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 320 ++++++++++++++++--
 arch/arm64/kvm/hyp/nvhe/page_alloc.c          |  14 +-
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  68 ++++
 arch/arm64/kvm/hyp/nvhe/setup.c               |   7 +-
 arch/arm64/kvm/hyp/pgtable.c                  |  13 +-
 arch/arm64/kvm/mmu.c                          | 113 +++++--
 arch/arm64/kvm/pkvm.c                         | 198 +++++++++++
 arch/arm64/kvm/vgic/vgic-v3.c                 |   6 +-
 19 files changed, 1010 insertions(+), 145 deletions(-)

-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Mon Dec 16 09:57:46 2024
From: qperret at google.com (Quentin Perret)
Date: Mon, 16 Dec 2024 17:57:46 +0000
Subject: [PATCH v3 01/18] KVM: arm64: Change the layout of enum pkvm_page_state
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <20241216175803.2716565-2-qperret@google.com>

The 'concrete' (a.k.a non-meta) page states are currently encoded using
software bits in PTEs. For performance reasons, the abstract
pkvm_page_state enum uses the same bits to encode these states as that
makes conversions from and to PTEs easy.

In order to prepare the ground for moving the 'concrete' state storage
to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this
purpose.

No functional changes intended.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 0972faccc2af..8c30362af2b9 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -24,25 +24,27 @@
  */
 enum pkvm_page_state {
 	PKVM_PAGE_OWNED			= 0ULL,
-	PKVM_PAGE_SHARED_OWNED		= KVM_PGTABLE_PROT_SW0,
-	PKVM_PAGE_SHARED_BORROWED	= KVM_PGTABLE_PROT_SW1,
-	__PKVM_PAGE_RESERVED		= KVM_PGTABLE_PROT_SW0 |
-					  KVM_PGTABLE_PROT_SW1,
+	PKVM_PAGE_SHARED_OWNED		= BIT(0),
+	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
+	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
 
 	/* Meta-states which aren't encoded directly in the PTE's SW bits */
-	PKVM_NOPAGE,
+	PKVM_NOPAGE			= BIT(2),
 };
+#define PKVM_PAGE_META_STATES_MASK	(~(BIT(0) | BIT(1)))
 
 #define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
 static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
 						 enum pkvm_page_state state)
 {
-	return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
+	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
+	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
+	return prot;
 }
 
 static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
 {
-	return prot & PKVM_PAGE_STATE_PROT_MASK;
+	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
 }
 
 struct host_mmu {
-- 
2.47.1.613.gc27f4b7a9f-goog



From ninad at linux.ibm.com  Mon Dec 16 10:01:00 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 12:01:00 -0600
Subject: [PATCH v1 2/4] hwmon: (pmbus/crps) Add Intel CRPS185 power supply
In-Reply-To: <5b095371-f835-4c23-aa43-deefa33123bb@roeck-us.net>
References: <20241212214927.3586509-1-ninad@linux.ibm.com>
 <20241212214927.3586509-3-ninad@linux.ibm.com>
 <5b095371-f835-4c23-aa43-deefa33123bb@roeck-us.net>
Message-ID: <2288d2ab-51c0-4e88-86e1-7a113ac67a16@linux.ibm.com>

Hi Guenter,

Thanks for the review!

On 12/12/24 19:29, Guenter Roeck wrote:
> On 12/12/24 13:49, Ninad Palsule wrote:
>> Add the driver to monitor Intel common redundant power supply (crps185)
>> with hwmon over pmbus.
>>
>> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
>> ---
>> ? Documentation/hwmon/crps.rst |? 95 +++++++++++
>
> Documentation/hwmon/index.rst needs to be updated.
Added the entry. Sorry for that.
>
>> ? MAINTAINERS????????????????? |?? 7 +
>> ? drivers/hwmon/pmbus/Kconfig? |?? 9 ++
>> ? drivers/hwmon/pmbus/Makefile |?? 1 +
>> ? drivers/hwmon/pmbus/crps.c?? | 299 +++++++++++++++++++++++++++++++++++
>> ? 5 files changed, 411 insertions(+)
>> ? create mode 100644 Documentation/hwmon/crps.rst
>> ? create mode 100644 drivers/hwmon/pmbus/crps.c
>>
>> diff --git a/Documentation/hwmon/crps.rst b/Documentation/hwmon/crps.rst
>> new file mode 100644
>> index 000000000000..81d5dfd68a46
>> --- /dev/null
>> +++ b/Documentation/hwmon/crps.rst
>> @@ -0,0 +1,95 @@
>> +.. SPDX-License-Identifier: GPL-2.0-or-later
>> +
>> +Kernel driver crps
>> +========================
>
> I am quite sure that this triggers a documentation warning.
Fixed it.
>
>> +
>> +Supported chips:
>> +
>> +? * Intel CRPS185
>> +
>> +??? Prefix: 'crps185'
>> +
>> +??? Addresses scanned: -
>> +
>> +Authors:
>> +??? Ninad Palsule <ninad at linux.ibm.com>
>> +
>> +
>
> Is the documentation available somewhere ?
> If yes, please add a reference. If not, add a comment explaining that
> it is not available to the public.
There is no public spec, added the comment
>
>> +Description
>> +-----------
>> +
>> +This driver implements support for Common Redundant Power supply 
>> with PMBus
>
> For _Intel_ ...
Updated.
>
>> +support.
>> +
>> +The driver is a client driver to the core PMBus driver.
>> +Please see Documentation/hwmon/pmbus.rst for details on PMBus client 
>> drivers.
>> +
>> +
>> +Usage Notes
>> +-----------
>> +
>> +This driver does not auto-detect devices. You will have to 
>> instantiate the
>> +devices explicitly. Please see 
>> Documentation/i2c/instantiating-devices.rst for
>> +details.
>> +
>> +
>> +Sysfs entries
>> +-------------
>> +
>> +======================= 
>> ======================================================
>> +curr1_label??????? "iin"
>> +curr1_input??????? Measured input current
>> +curr1_max??????? Maximum input current
>> +curr1_max_alarm???????? Input maximum current high alarm
>> +curr1_crit????????????? Critial high input current
>> +curr1_crit_alarm??????? Input critical current high alarm
>> +curr1_rated_max??????? Maximum rated input current
>> +
>> +curr2_label??????? "iout1"
>> +curr2_input??????? Measured output current
>> +curr2_max??????? Maximum output current
>> +curr2_max_alarm???????? Output maximum current high alarm
>> +curr2_crit??????????? Critial high output current
>> +curr2_crit_alarm??????? Output critical current high alarm
>> +curr2_rated_max??????? Maximum rated output current
>> +
>> +in1_label??????? "vin"
>> +in1_input??????? Measured input voltage
>> +in1_crit??????????????? Critical input over voltage
>> +in1_crit_alarm????????? Critical input over voltage alarm
>> +in1_max???????????????? Maximum input over voltage
>> +in1_max_alarm?????????? Maximum input over voltage alarm
>> +in1_rated_min??????? Minimum rated input voltage
>> +in1_rated_max??????? Maximum rated input voltage
>> +
>> +in2_label??????? "vout1"
>> +in2_input??????? Measured input voltage
>> +in2_crit??????????????? Critical input over voltage
>> +in2_crit_alarm????????? Critical input over voltage alarm
>> +in2_lcrit?????????????? Critical input under voltage fault
>> +in2_lcrit_alarm???????? Critical input under voltage fault alarm
>> +in2_max???????????????? Maximum input over voltage
>> +in2_max_alarm?????????? Maximum input over voltage alarm
>> +in2_min???????????????? Minimum input under voltage warning
>> +in2_min_alarm?????????? Minimum input under voltage warning alarm
>> +in2_rated_min??????? Minimum rated input voltage
>> +in2_rated_max??????? Maximum rated input voltage
>> +
>> +power1_label??????? "pin"
>> +power1_input??????? Measured input power
>> +power1_alarm??????? Input power high alarm
>> +power1_max????????? Maximum input power
>> +power1_rated_max??????? Maximum rated input power
>> +
>> +temp[1-2]_input??????? Measured temperature
>> +temp[1-2]_crit???????? Critical temperature
>> +temp[1-2]_crit_alarm??? Critical temperature alarm
>> +temp[1-2]_max????????? Maximum temperature
>> +temp[1-2]_max_alarm???? Maximum temperature alarm
>> +temp[1-2]_rated_max???? Maximum rated temperature
>> +
>> +fan1_alarm??????? Fan 1 warning.
>> +fan1_fault??????? Fan 1 fault.
>> +fan1_input??????? Fan 1 speed in RPM.
>> +fan1_target???????????? Fan 1 target.
>> +======================= 
>> ======================================================
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 637ddd44245f..6b31d545f0f1 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -6100,6 +6100,13 @@ L:??? linux-input at vger.kernel.org
>> ? S:??? Maintained
>> ? F:??? drivers/hid/hid-creative-sb0540.c
>> ? +CRPS COMMON REDUNDANT PSU DRIVER
>
> This is _INTEL_ CRPS.
Updated.
>
>> +M:??? Ninad Palsule <ninad at linux.ibm.com>
>> +L:??? linux-hwmon at vger.kernel.org
>> +S:??? Maintained
>> +F:??? Documentation/hwmon/crps.rst
>> +F:??? drivers/hwmon/pmbus/crps.c
>> +
>> ? CRYPTO API
>> ? M:??? Herbert Xu <herbert at gondor.apana.org.au>
>> ? M:??? "David S. Miller" <davem at davemloft.net>
>> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
>> index 22418a05ced0..56c4eb4b846e 100644
>> --- a/drivers/hwmon/pmbus/Kconfig
>> +++ b/drivers/hwmon/pmbus/Kconfig
>> @@ -85,6 +85,15 @@ config SENSORS_BPA_RS600
>> ??????? This driver can also be built as a module. If so, the module 
>> will
>> ??????? be called bpa-rs600.
>> ? +config SENSORS_CRPS
>> +??? tristate "Common Redundant Power Supply"
>
> Again, this is an Intel product.
Fixed.
>
>> +??? help
>> +????? If you say yes here you get hardware monitoring support for 
>> the Common
>> +????? Redundant Power Supply.
>> +
>> +????? This driver can also be built as a module. If so, the module will
>> +????? be called crps.
>> +
>> ? config SENSORS_DELTA_AHE50DC_FAN
>> ????? tristate "Delta AHE-50DC fan control module"
>> ????? help
>> diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
>> index 3d3183f8d2a7..c7eb7739b7f8 100644
>> --- a/drivers/hwmon/pmbus/Makefile
>> +++ b/drivers/hwmon/pmbus/Makefile
>> @@ -62,3 +62,4 @@ obj-$(CONFIG_SENSORS_XDPE122)??? += xdpe12284.o
>> ? obj-$(CONFIG_SENSORS_XDPE152)??? += xdpe152c4.o
>> ? obj-$(CONFIG_SENSORS_ZL6100)??? += zl6100.o
>> ? obj-$(CONFIG_SENSORS_PIM4328)??? += pim4328.o
>> +obj-$(CONFIG_SENSORS_CRPS)??? += crps.o
>> diff --git a/drivers/hwmon/pmbus/crps.c b/drivers/hwmon/pmbus/crps.c
>> new file mode 100644
>> index 000000000000..44d309f81803
>> --- /dev/null
>> +++ b/drivers/hwmon/pmbus/crps.c
>> @@ -0,0 +1,299 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright 2024 IBM Corp.
>> + */
>> +
>> +#include <linux/debugfs.h>
>> +#include <linux/i2c.h>
>> +#include <linux/of.h>
>> +#include <linux/pmbus.h>
>> +
>> +#include "pmbus.h"
>> +
>> +/* Intel crps185 specific commands. */
>> +#define CRPS185_MFR_IOUT_MAX??????? 0xA6
>> +#define CRPS185_MFR_POUT_MAX??????? 0xA7
>> +
>
> I fail to see the point in those defines, even more so since
> PMBUS_MFR_POUT_MAX and PMBUS_MFR_IOUT_MAX are used below.
Removed these defines.
>
>> +enum {
>> +??? CRPS_DEBUGFS_PMBUS_REVISION = 0,
>> +??? CRPS_DEBUGFS_MAX_POWER_OUT,
>> +??? CRPS_DEBUGFS_MAX_CURRENT_OUT,
>> +??? CRPS_DEBUGFS_NUM_ENTRIES
>> +};
>> +
>> +enum models { crps185 = 1, crps_unknown };
>
> Pointless enum. The driver only supports a single power supply.
Removed the enum.
>
>> +
>> +struct crps {
>> +??? enum models version;
>> +??? struct i2c_client *client;
>> +
>> +??? int debugfs_entries[CRPS_DEBUGFS_NUM_ENTRIES];
>> +};
>> +
>> +#define to_psu(x, y) container_of((x), struct crps, 
>> debugfs_entries[(y)])
>> +
>> +static struct pmbus_platform_data crps_pdata = {
>> +??? .flags = PMBUS_SKIP_STATUS_CHECK,
>> +};
>
> Did you confirm that it is needed ? If so, explain why it is needed.
I removed it and still driver is working. I added it because spec did 
not mention about PMBUS_STATUS_CML
>
>> +
>> +static const struct i2c_device_id crps_id[] = {
>> +??? { "intel_crps185", crps185 },
>> +??? {}
>> +};
>> +MODULE_DEVICE_TABLE(i2c, crps_id);
>> +
>> +/*
>> + * Convert linear format word to machine format. 11 LSB side bits 
>> are two's
>> + * complement integer mantissa and 5 MSB side bits are two's complement
>> + * exponent
>> + */
>> +static int crps_convert_linear(int rc)
>> +{
>> +??? s16 exponent;
>> +??? s32 mantissa;
>> +??? s64 val;
>> +
>> +??? exponent = ((s16)rc) >> 11;
>> +??? mantissa = ((s16)((rc & 0x7ff) << 5)) >> 5;
>> +
>> +??? val = mantissa;
>> +??? if (exponent >= 0)
>> +??????? val <<= exponent;
>> +??? else
>> +??????? val >>= -exponent;
>> +
>> +??? return (int)val;
>> +}
>> +
>> +static ssize_t crps_debugfs_read(struct file *file, char __user *buf,
>> +???????????????? size_t count, loff_t *ppos)
>> +{
>> +??? int rc;
>> +??? int *idxp = file->private_data;
>> +??? int idx = *idxp;
>> +??? struct crps *psu = to_psu(idxp, idx);
>> +??? char data[2 * I2C_SMBUS_BLOCK_MAX] = { 0 };
>> +
>> +??? rc = pmbus_lock_interruptible(psu->client);
>> +??? if (rc)
>> +??????? return rc;
>> +
>> +??? rc = pmbus_set_page(psu->client, 0, 0xff);
>> +??? if (rc)
>> +??????? goto unlock;
>> +
>> +??? switch (idx) {
>> +??? case CRPS_DEBUGFS_PMBUS_REVISION:
>> +??????? rc = i2c_smbus_read_byte_data(psu->client, PMBUS_REVISION);
>> +??????? if (rc >= 0) {
>> +??????????? if (psu->version == crps185) {
>> +??????????????? if (rc == 0)
>> +??????????????????? rc = sprintf(data, "%s", "1.0");
>> +??????????????? else if (rc == 0x11)
>> +??????????????????? rc = sprintf(data, "%s", "1.1");
>> +??????????????? else if (rc == 0x22)
>> +??????????????????? rc = sprintf(data, "%s", "1.2");
>> +??????????????? else
>> +??????????????????? rc = snprintf(data, 3, "0x%02x", rc);
>> +??????????? } else {
>> +??????????????? rc = snprintf(data, 3, "%02x", rc);
>> +??????????? }
>> +??????? }
>
> This attribute should be added into the PMBus core.

Moved the attribute in the core.


>
>> +??????? break;
>> +??? case CRPS_DEBUGFS_MAX_POWER_OUT:
>> +??????? rc = i2c_smbus_read_word_data(psu->client, PMBUS_MFR_POUT_MAX);
>> +??????? if (rc >= 0) {
>> +??????????? rc = crps_convert_linear(rc);
>> +??????????? rc = snprintf(data, I2C_SMBUS_BLOCK_MAX, "%d", rc);
>> +??????? }
>> +??????? break;
>> +??? case CRPS_DEBUGFS_MAX_CURRENT_OUT:
>> +??????? rc = i2c_smbus_read_word_data(psu->client, PMBUS_MFR_IOUT_MAX);
>> +??????? if (rc >= 0) {
>> +??????????? rc = crps_convert_linear(rc);
>> +??????????? rc = snprintf(data, I2C_SMBUS_BLOCK_MAX, "%d", rc);
>> +??????? }
>> +??????? break;
>
> What is the point of those two attributes ? There are already
> standard sysfs attributes reporting those values.
Removed debugfs
>
>> +??? default:
>> +??????? rc = -EINVAL;
>> +??????? break;
>> +??? }
>> +
>> +unlock:
>> +??? pmbus_unlock(psu->client);
>> +??? if (rc < 0)
>> +??????? return rc;
>> +
>> +??? data[rc] = '\n';
>> +??? rc += 2;
>> +
>> +??? return simple_read_from_buffer(buf, count, ppos, data, rc);
>> +}
>> +
>> +static const struct file_operations crps_debugfs_fops = {
>> +??? .llseek = noop_llseek,
>> +??? .read = crps_debugfs_read,
>> +??? .open = simple_open,
>> +};
>> +
>> +static int crps_read_word_data(struct i2c_client *client, int page,
>> +??????????????? int phase, int reg)
>> +{
>> +??? int rc;
>> +
>> +??? switch (reg) {
>> +??? case PMBUS_STATUS_WORD:
>> +??????? rc = pmbus_read_word_data(client, page, phase, reg);
>> +??????? if (rc < 0)
>> +??????????? return rc;
>> +??????? break;
>
> Why is this needed ?
You are right, removed it.
>
>> +??? case PMBUS_OT_WARN_LIMIT:
>> +??????? rc = pmbus_read_word_data(client, page, phase,
>> +????????????????????? PMBUS_MFR_MAX_TEMP_1);
>> +??????? if (rc < 0)
>> +??????????? return rc;
>> +??????? break;
>> +??? case PMBUS_IOUT_OC_WARN_LIMIT:
>> +??????? rc = pmbus_read_word_data(client, page, phase,
>> +????????????????????? CRPS185_MFR_IOUT_MAX);
>> +??????? if (rc < 0)
>> +??????????? return rc;
>> +??????? break;
>> +??? case PMBUS_POUT_OP_WARN_LIMIT:
>> +??????? rc = pmbus_read_word_data(client, page, phase,
>> +????????????????????? CRPS185_MFR_POUT_MAX);
>> +??????? if (rc < 0)
>> +??????????? return rc;
>> +??????? break;
>
> The above three values are more than odd. They duplicate the respective
> standard rated_max attributes as warning limits. Why ?
I realized that some of these registers exist. So removed it.
>
> On top of that, on writes, the actual warning limits are overwritten.
> That makes even less sense.
I have removed read function so now we don't need write too.
>
>> +??? default:
>> +??????? rc = -ENODATA;
>> +??????? break;
>> +??? }
>> +
>> +??? return rc;
>> +}
>> +
>> +static struct pmbus_driver_info crps_info[] = {
>> +??? [crps185] = {
>> +??????? .pages = 1,
>> +??????? /* PSU uses default linear data format. */
>> +??????? .func[0] = PMBUS_HAVE_PIN | PMBUS_HAVE_IOUT |
>> +??????????? PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_IIN |
>> +??????????? PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
>> +??????????? PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
>> +??????????? PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
>> +??????????? PMBUS_HAVE_STATUS_TEMP |
>> +??????????? PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
>> +??????? .read_word_data = crps_read_word_data,
>> +??? },
>> +};
>> +
>> +#define to_psu(x, y) container_of((x), struct crps, 
>> debugfs_entries[(y)])
>> +
>> +static void crps_init_debugfs(struct crps *psu)
>> +{
>> +??? struct i2c_client *client = psu->client;
>> +??? struct dentry *debugfs;
>> +??? int i;
>> +
>> +??? /* Don't fail the probe if we can't create debugfs */
>> +??? debugfs = pmbus_get_debugfs_dir(client);
>> +??? if (!debugfs)
>> +??????? return;
>> +
>> +??? for (i = 0; i < CRPS_DEBUGFS_NUM_ENTRIES; ++i)
>> +??????? psu->debugfs_entries[i] = i;
>> +
>> +??? debugfs_create_file("pmbus_revision", 0444, debugfs,
>> + &psu->debugfs_entries[CRPS_DEBUGFS_PMBUS_REVISION],
>> +??????????????? &crps_debugfs_fops);
>> +??? debugfs_create_file("max_power_out", 0444, debugfs,
>> + &psu->debugfs_entries[CRPS_DEBUGFS_MAX_POWER_OUT],
>> +??????????????? &crps_debugfs_fops);
>> +??? debugfs_create_file("max_current_out", 0444, debugfs,
>> + &psu->debugfs_entries[CRPS_DEBUGFS_MAX_CURRENT_OUT],
>> +??????????????? &crps_debugfs_fops);
>> +}
>> +
>> +static int crps_probe(struct i2c_client *client)
>> +{
>> +??? int rc;
>> +??? struct device *dev = &client->dev;
>> +??? enum models vs = crps_unknown;
>> +??? struct crps *psu;
>> +??? const void *md = of_device_get_match_data(&client->dev);
>> +??? const struct i2c_device_id *id = NULL;
>> +??? char buf[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
>> +
>> +??? if (md) {
>> +??????? vs = (uintptr_t)md;
>> +??? } else {
>> +??????? id = i2c_match_id(crps_id, client);
>> +??????? if (id)
>> +??????????? vs = (enum models)id->driver_data;
>> +??? }
>> +
> Consider using i2c_get_match_data().
Removed this code.
>
>> +??? if (!vs || vs >= crps_unknown) {
>> +??????? dev_err(dev, "Version %d not supported\n", vs);
>> +??????? return -EINVAL;
>> +??? }
>
> This is very much pointless. The driver would not be instantiated 
> withut match.
Yes, removed it.
>
>> +
>> +??? rc = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
>> +??? if (rc < 0) {
>> +??????? dev_err(dev, "Failed to read PMBUS_MFR_MODEL\n");
>> +??????? return rc;
>
> dev_err_probe().
Changed to use this function.
>
>> +??? }
>> +??? if (strncmp(buf, "03NK260", 7)) {
>
> This should also check and ensure that rc == 7.
Good idea, Added this check.
>
>> +??????? buf[rc] = '\0';
>> +??????? dev_err(dev, "Model '%s' not supported\n", buf);
>
> dev_err_probe()
Changed the function
>
>> +??????? return -ENODEV;
>> +??? }
>> +
>> +??? client->dev.platform_data = &crps_pdata;
>> +??? rc = pmbus_do_probe(client, &crps_info[vs]);
>> +??? if (rc) {
>> +??????? dev_err(dev, "Failed to probe %d\n", rc);
>> +??????? return rc;
>
> dev_err_probe().
Changed this function.
>
>> +??? }
>> +
>> +??? /*
>> +???? * Don't fail the probe if there isn't enough memory for debugfs.
>> +???? */
>> +??? psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
>> +??? if (!psu) {
>> +??????? dev_warn(dev, "Failed to allocate memory. debugfs are not 
>> supported.\n");
>> +??????? return 0;
>> +??? }
>> +
>> +??? psu->version = vs;
>> +??? psu->client = client;
>> +
>
> Drop all this. Add the PMBus version as standard debugfs attribute to 
> the PMBus core
> if needed/wanted. The rest is already provided as standard sysfs 
> attributes, and
> reporting the same value in debugfs files adds no value.
Yes, Removed debugfs.
>
>> +??? crps_init_debugfs(psu);
>> +
>> +??? return 0;
>> +}
>> +
>> +static const struct of_device_id crps_of_match[] = {
>> +??? {
>> +??????? .compatible = "intel,crps185",
>> +??????? .data = (void *)crps185
>> +??? },
>> +??? {}
>> +};
>> +MODULE_DEVICE_TABLE(of, crps_of_match);
>> +
>> +static struct i2c_driver crps_driver = {
>> +??? .driver = {
>> +??????? .name = "crps",
>> +??????? .of_match_table = crps_of_match,
>> +??? },
>> +??? .probe = crps_probe,
>> +??? .id_table = crps_id,
>> +};
>> +
>> +module_i2c_driver(crps_driver);
>> +
>> +MODULE_AUTHOR("Ninad Palsule");
>> +MODULE_DESCRIPTION("PMBus driver for Common Redundant power supplies");
>
> Again, this is for _Intel_ power supplies.

Yes, Added Intel


Thanks and Regards,

Ninad Palsule

>
>> +MODULE_LICENSE("GPL");
>> +MODULE_IMPORT_NS("PMBUS");
>


From linux at roeck-us.net  Mon Dec 16 10:26:06 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 16 Dec 2024 10:26:06 -0800
Subject: [PATCH v2 2/4] hwmon: (pmbus/crps) Add Intel CRPS185 power supply
In-Reply-To: <20241216175044.4144442-3-ninad@linux.ibm.com>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
 <20241216175044.4144442-3-ninad@linux.ibm.com>
Message-ID: <68f5d2e1-10e8-4441-9338-e2a385a9c2b1@roeck-us.net>

On 12/16/24 09:50, Ninad Palsule wrote:
> Add the driver to monitor Intel common redundant power supply (crps185)
> with hwmon over pmbus.
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
> ---
>   Documentation/hwmon/crps.rst  | 97 +++++++++++++++++++++++++++++++++++
>   Documentation/hwmon/index.rst |  1 +
>   MAINTAINERS                   |  7 +++
>   drivers/hwmon/pmbus/Kconfig   |  9 ++++
>   drivers/hwmon/pmbus/Makefile  |  1 +
>   drivers/hwmon/pmbus/crps.c    | 79 ++++++++++++++++++++++++++++
>   6 files changed, 194 insertions(+)
>   create mode 100644 Documentation/hwmon/crps.rst
>   create mode 100644 drivers/hwmon/pmbus/crps.c
> 
> diff --git a/Documentation/hwmon/crps.rst b/Documentation/hwmon/crps.rst
> new file mode 100644
> index 000000000000..74570ed1e978
> --- /dev/null
> +++ b/Documentation/hwmon/crps.rst
> @@ -0,0 +1,97 @@
> +.. SPDX-License-Identifier: GPL-2.0-or-later
> +
> +Kernel driver crps
> +==================
> +
> +Supported chips:
> +
> +  * Intel CRPS185
> +
> +    Prefix: 'crps185'
> +
> +    Addresses scanned: -
> +
> +    Datasheet: Publicly not available.

Maybe "Only available under NDA". Or at least that is what I found.

> +
> +Authors:
> +    Ninad Palsule <ninad at linux.ibm.com>
> +
> +
> +Description
> +-----------
> +
> +This driver implements support for Intel Common Redundant Power supply with
> +PMBus support.
> +
> +The driver is a client driver to the core PMBus driver.
> +Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers.
> +
> +
> +Usage Notes
> +-----------
> +
> +This driver does not auto-detect devices. You will have to instantiate the
> +devices explicitly. Please see Documentation/i2c/instantiating-devices.rst for
> +details.
> +
> +
> +Sysfs entries
> +-------------
> +
> +======================= ======================================================
> +curr1_label		"iin"
> +curr1_input		Measured input current
> +curr1_max		Maximum input current
> +curr1_max_alarm         Input maximum current high alarm
> +curr1_crit              Critial high input current
> +curr1_crit_alarm        Input critical current high alarm
> +curr1_rated_max		Maximum rated input current
> +
> +curr2_label		"iout1"
> +curr2_input		Measured output current
> +curr2_max		Maximum output current
> +curr2_max_alarm         Output maximum current high alarm
> +curr2_crit	        Critial high output current
> +curr2_crit_alarm        Output critical current high alarm
> +curr2_rated_max		Maximum rated output current
> +
> +in1_label		"vin"
> +in1_input		Measured input voltage
> +in1_crit                Critical input over voltage
> +in1_crit_alarm          Critical input over voltage alarm
> +in1_max                 Maximum input over voltage
> +in1_max_alarm           Maximum input over voltage alarm
> +in1_rated_min		Minimum rated input voltage
> +in1_rated_max		Maximum rated input voltage
> +
> +in2_label		"vout1"
> +in2_input		Measured input voltage
> +in2_crit                Critical input over voltage
> +in2_crit_alarm          Critical input over voltage alarm
> +in2_lcrit               Critical input under voltage fault
> +in2_lcrit_alarm         Critical input under voltage fault alarm
> +in2_max                 Maximum input over voltage
> +in2_max_alarm           Maximum input over voltage alarm
> +in2_min                 Minimum input under voltage warning
> +in2_min_alarm           Minimum input under voltage warning alarm
> +in2_rated_min		Minimum rated input voltage
> +in2_rated_max		Maximum rated input voltage
> +
> +power1_label		"pin"
> +power1_input		Measured input power
> +power1_alarm		Input power high alarm
> +power1_max  		Maximum input power
> +power1_rated_max        Maximum rated input power
> +
> +temp[1-2]_input		Measured temperature
> +temp[1-2]_crit 		Critical temperature
> +temp[1-2]_crit_alarm    Critical temperature alarm
> +temp[1-2]_max  		Maximum temperature
> +temp[1-2]_max_alarm     Maximum temperature alarm
> +temp[1-2]_rated_max     Maximum rated temperature
> +
> +fan1_alarm		Fan 1 warning.
> +fan1_fault		Fan 1 fault.
> +fan1_input		Fan 1 speed in RPM.
> +fan1_target             Fan 1 target.
> +======================= ======================================================

Does this pass "make htmldocs" ?


> diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
> index 1a3cb0a59f72..b1ea445479b0 100644
> --- a/Documentation/hwmon/index.rst
> +++ b/Documentation/hwmon/index.rst
> @@ -58,6 +58,7 @@ Hardware Monitoring Kernel Drivers
>      corsair-cpro
>      corsair-psu
>      cros_ec_hwmon
> +   crps
>      da9052
>      da9055
>      dell-smm-hwmon
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 637ddd44245f..e99f26f75733 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6100,6 +6100,13 @@ L:	linux-input at vger.kernel.org
>   S:	Maintained
>   F:	drivers/hid/hid-creative-sb0540.c
>   
> +INTEL CRPS COMMON REDUNDANT PSU DRIVER
> +M:	Ninad Palsule <ninad at linux.ibm.com>
> +L:	linux-hwmon at vger.kernel.org
> +S:	Maintained
> +F:	Documentation/hwmon/crps.rst
> +F:	drivers/hwmon/pmbus/crps.c
> +
>   CRYPTO API
>   M:	Herbert Xu <herbert at gondor.apana.org.au>
>   M:	"David S. Miller" <davem at davemloft.net>
> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
> index 22418a05ced0..43b6df04e0f9 100644
> --- a/drivers/hwmon/pmbus/Kconfig
> +++ b/drivers/hwmon/pmbus/Kconfig
> @@ -85,6 +85,15 @@ config SENSORS_BPA_RS600
>   	  This driver can also be built as a module. If so, the module will
>   	  be called bpa-rs600.
>   
> +config SENSORS_CRPS
> +	tristate "Intel Common Redundant Power Supply"
> +	help
> +	  If you say yes here you get hardware monitoring support for the Intel
> +	  Common Redundant Power Supply.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called crps.
> +
>   config SENSORS_DELTA_AHE50DC_FAN
>   	tristate "Delta AHE-50DC fan control module"
>   	help
> diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
> index 3d3183f8d2a7..c7eb7739b7f8 100644
> --- a/drivers/hwmon/pmbus/Makefile
> +++ b/drivers/hwmon/pmbus/Makefile
> @@ -62,3 +62,4 @@ obj-$(CONFIG_SENSORS_XDPE122)	+= xdpe12284.o
>   obj-$(CONFIG_SENSORS_XDPE152)	+= xdpe152c4.o
>   obj-$(CONFIG_SENSORS_ZL6100)	+= zl6100.o
>   obj-$(CONFIG_SENSORS_PIM4328)	+= pim4328.o
> +obj-$(CONFIG_SENSORS_CRPS)	+= crps.o
> diff --git a/drivers/hwmon/pmbus/crps.c b/drivers/hwmon/pmbus/crps.c
> new file mode 100644
> index 000000000000..09425c404fc8
> --- /dev/null
> +++ b/drivers/hwmon/pmbus/crps.c
> @@ -0,0 +1,79 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright 2024 IBM Corp.
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/of.h>
> +#include <linux/pmbus.h>
> +
> +#include "pmbus.h"
> +
> +static const struct i2c_device_id crps_id[] = {
> +	{ "intel_crps185" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(i2c, crps_id);
> +
> +static struct pmbus_driver_info crps_info = {
> +	.pages = 1,
> +	/* PSU uses default linear data format. */
> +	.func[0] = PMBUS_HAVE_PIN | PMBUS_HAVE_IOUT |
> +		PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_IIN |
> +		PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
> +		PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
> +		PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
> +		PMBUS_HAVE_STATUS_TEMP |
> +		PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
> +};
> +
> +static int crps_probe(struct i2c_client *client)
> +{
> +	int rc;
> +	struct device *dev = &client->dev;
> +	char buf[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
> +
> +	rc = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
> +	if (rc < 0) {
> +		dev_err_probe(dev, rc, "Failed to read PMBUS_MFR_MODEL\n");
> +		return rc;

		return dev_err_probe(...);

> +	}
> +
> +	if (strncmp(buf, "03NK260", 7) == 7) {

strncmp() never returns 7. You probably want something like

	if (rc != 7 || strncmp(buf, "03NK260", 7)) {

> +		buf[rc] = '\0';
> +		dev_err_probe(dev, -ENODEV, "Model '%s' not supported\n", buf);

		return dev_err_probe(...);

> +		return -ENODEV;
> +	}
> +
> +	rc = pmbus_do_probe(client, &crps_info);
> +	if (rc) {
> +		dev_err_probe(dev, rc, "Failed to probe %d\n", rc);

dev_err_probe() already handles the error, and a message such as
"failed to probe -22" isn't very useful anyway. Also,
		return dev_err_probe(...);

> +		return rc;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id crps_of_match[] = {
> +	{
> +		.compatible = "intel,crps185",
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, crps_of_match);
> +
> +static struct i2c_driver crps_driver = {
> +	.driver = {
> +		.name = "crps",
> +		.of_match_table = crps_of_match,
> +	},
> +	.probe = crps_probe,
> +	.id_table = crps_id,
> +};
> +
> +module_i2c_driver(crps_driver);
> +
> +MODULE_AUTHOR("Ninad Palsule");
> +MODULE_DESCRIPTION("PMBus driver for Intel Common Redundant power supplies");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS("PMBUS");



From francesco at dolcini.it  Mon Dec 16 10:42:31 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Mon, 16 Dec 2024 19:42:31 +0100
Subject: [PATCH v1] i2c: imx: fix missing stop condition in single-master
 mode
In-Reply-To: <20241216151829.74056-1-eichest@gmail.com>
References: <20241216151829.74056-1-eichest@gmail.com>
Message-ID: <20241216184231.GA53492@francesco-nb>

On Mon, Dec 16, 2024 at 04:16:40PM +0100, Stefan Eichenberger wrote:
> From: Stefan Eichenberger <stefan.eichenberger at toradex.com>
> 
> A regression was introduced with the implementation of single-master
> mode, preventing proper stop conditions from being generated. Devices
> that require a valid stop condition, such as EEPROMs, fail to function
> correctly as a result.
> 
> The issue only affects devices with the single-master property enabled.
> 
> This commit resolves the issue by re-enabling I2C bus busy bit (IBB)
> polling for single-master mode when generating a stop condition. The fix
> further ensures that the i2c_imx->stopped flag is cleared at the start
> of each transfer, allowing the stop condition to be correctly generated
> in i2c_imx_stop().
> 
> According to the reference manual (IMX8MMRM, Rev. 2, 09/2019, page
> 5270), polling the IBB bit to determine if the bus is free is only
> necessary in multi-master mode. Consequently, the IBB bit is not polled
> for the start condition in single-master mode.
> 
> Fixes: 6692694aca86 ("i2c: imx: do not poll for bus busy in single master mode")
> Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>

Reviewed-by: Francesco Dolcini <francesco.dolcini at toradex.com>



From linux at roeck-us.net  Mon Dec 16 10:44:51 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 16 Dec 2024 10:44:51 -0800
Subject: [PATCH v2 1/4] hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
In-Reply-To: <20241216175044.4144442-2-ninad@linux.ibm.com>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
 <20241216175044.4144442-2-ninad@linux.ibm.com>
Message-ID: <6604eea3-de0f-4d2e-bc12-7f75012b949e@roeck-us.net>

On Mon, Dec 16, 2024 at 11:50:39AM -0600, Ninad Palsule wrote:
> Add debugfs file for the PMBUS_REVISION command. This command provides
> information about PMBus protocol revision number.
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>

Applied.

Thanks,
Guenter


From linux at roeck-us.net  Mon Dec 16 10:47:34 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 16 Dec 2024 10:47:34 -0800
Subject: [PATCH v2 3/4] dt-bindings: hwmon: intel,crps185: Add to trivial
In-Reply-To: <20241216175044.4144442-4-ninad@linux.ibm.com>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
 <20241216175044.4144442-4-ninad@linux.ibm.com>
Message-ID: <a010366e-b911-43bd-8445-e893e11fa51a@roeck-us.net>

On 12/16/24 09:50, Ninad Palsule wrote:
> Add INTEL Common Redundant Power Supply Versions crps185 bindings as
> trivial. It is trivial because only compatibility string is required in
> the device tree to load this driver.
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>

Krzysztof had Acked this patch. I don't immediately see why you dropped it.
Am I missing something ?

Guenter

> ---
>   Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
> index 73a49d50c4ef..7d07b08b1459 100644
> --- a/Documentation/devicetree/bindings/trivial-devices.yaml
> +++ b/Documentation/devicetree/bindings/trivial-devices.yaml
> @@ -151,6 +151,8 @@ properties:
>             - injoinic,ip5306
>               # Inspur Power System power supply unit version 1
>             - inspur,ipsps1
> +            # Intel common redudant power supply crps185
> +          - intel,crps185
>               # Intersil ISL29028 Ambient Light and Proximity Sensor
>             - isil,isl29028
>               # Intersil ISL29030 Ambient Light and Proximity Sensor



From linux at roeck-us.net  Mon Dec 16 10:48:14 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 16 Dec 2024 10:48:14 -0800
Subject: [PATCH v2 0/4] Add support for Intel CRPS PSU
In-Reply-To: <20241216175044.4144442-1-ninad@linux.ibm.com>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
Message-ID: <c64bb634-46d4-486a-8743-699775326058@roeck-us.net>

On 12/16/24 09:50, Ninad Palsule wrote:
> Hello,
> 
> Please review the patchset for Intel CRPS185 driver.
> V2:
> ---
>    - Incorporated review comments by Guenter Roeck
>    - Incorporated review comments by Krzysztof Kozlowski
> 

That is not a useful change log. Please describe what you changed, not who
asked for it.

Guenter

> Ninad Palsule (4):
>    hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
>    hwmon: (pmbus/crps) Add Intel CRPS185 power supply
>    dt-bindings: hwmon: intel,crps185: Add to trivial
>    ARM: dts: aspeed: system1: Use crps PSU driver
> 
>   .../devicetree/bindings/trivial-devices.yaml  |  2 +
>   Documentation/hwmon/crps.rst                  | 97 +++++++++++++++++++
>   Documentation/hwmon/index.rst                 |  1 +
>   MAINTAINERS                                   |  7 ++
>   .../dts/aspeed/aspeed-bmc-ibm-system1.dts     |  8 +-
>   drivers/hwmon/pmbus/Kconfig                   |  9 ++
>   drivers/hwmon/pmbus/Makefile                  |  1 +
>   drivers/hwmon/pmbus/crps.c                    | 79 +++++++++++++++
>   drivers/hwmon/pmbus/pmbus_core.c              | 13 ++-
>   9 files changed, 211 insertions(+), 6 deletions(-)
>   create mode 100644 Documentation/hwmon/crps.rst
>   create mode 100644 drivers/hwmon/pmbus/crps.c
> 



From neil.armstrong at linaro.org  Mon Dec 16 10:53:50 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 16 Dec 2024 19:53:50 +0100
Subject: [PATCH] clk: amlogic: g12b: fix cluster A parent data
In-Reply-To: <20241213-amlogic-clk-g12a-cpua-parent-fix-v1-1-d8c0f41865fe@baylibre.com>
References: <20241213-amlogic-clk-g12a-cpua-parent-fix-v1-1-d8c0f41865fe@baylibre.com>
Message-ID: <5c8691c4-4a57-40a9-9da6-00accf3d1a4f@linaro.org>

On 13/12/2024 15:30, Jerome Brunet wrote:
> Several clocks used by both g12a and g12b use the g12a cpu A clock hw
> pointer as clock parent. This is incorrect on g12b since the parents of
> cluster A cpu clock are different. Also the hw clock provided as parent to
> these children is not even registered clock on g12b.
> 
> Fix the problem by reverting to the global namespace and let CCF pick
> the appropriate, as it is already done for other clocks, such as
> cpu_clk_trace_div.
> 
> Fixes: 25e682a02d91 ("clk: meson: g12a: migrate to the new parent description method")
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
>   drivers/clk/meson/g12a.c | 36 ++++++++++++++++++++++++------------
>   1 file changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
> index 20be7b037c07535bd2115f6e70404a95a7832756..4e6584377e43fa7c9956017ddfcd3f295fafd686 100644
> --- a/drivers/clk/meson/g12a.c
> +++ b/drivers/clk/meson/g12a.c
> @@ -1137,8 +1137,18 @@ static struct clk_regmap g12a_cpu_clk_div16_en = {
>   	.hw.init = &(struct clk_init_data) {
>   		.name = "cpu_clk_div16_en",
>   		.ops = &clk_regmap_gate_ro_ops,
> -		.parent_hws = (const struct clk_hw *[]) {
> -			&g12a_cpu_clk.hw
> +		.parent_data = &(const struct clk_parent_data) {
> +			/*
> +			 * Note:
> +			 * G12A and G12B have different cpu clocks (with
> +			 * different struct clk_hw). We fallback to the global
> +			 * naming string mechanism so this clock picks
> +			 * up the appropriate one. Same goes for the other
> +			 * clock using cpu cluster A clock output and present
> +			 * on both G12 variant.
> +			 */
> +			.name = "cpu_clk",
> +			.index = -1,
>   		},
>   		.num_parents = 1,
>   		/*
> @@ -1203,7 +1213,10 @@ static struct clk_regmap g12a_cpu_clk_apb_div = {
>   	.hw.init = &(struct clk_init_data){
>   		.name = "cpu_clk_apb_div",
>   		.ops = &clk_regmap_divider_ro_ops,
> -		.parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
> +		.parent_data = &(const struct clk_parent_data) {
> +			.name = "cpu_clk",
> +			.index = -1,
> +		},
>   		.num_parents = 1,
>   	},
>   };
> @@ -1237,7 +1250,10 @@ static struct clk_regmap g12a_cpu_clk_atb_div = {
>   	.hw.init = &(struct clk_init_data){
>   		.name = "cpu_clk_atb_div",
>   		.ops = &clk_regmap_divider_ro_ops,
> -		.parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
> +		.parent_data = &(const struct clk_parent_data) {
> +			.name = "cpu_clk",
> +			.index = -1,
> +		},
>   		.num_parents = 1,
>   	},
>   };
> @@ -1271,7 +1287,10 @@ static struct clk_regmap g12a_cpu_clk_axi_div = {
>   	.hw.init = &(struct clk_init_data){
>   		.name = "cpu_clk_axi_div",
>   		.ops = &clk_regmap_divider_ro_ops,
> -		.parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
> +		.parent_data = &(const struct clk_parent_data) {
> +			.name = "cpu_clk",
> +			.index = -1,
> +		},
>   		.num_parents = 1,
>   	},
>   };
> @@ -1306,13 +1325,6 @@ static struct clk_regmap g12a_cpu_clk_trace_div = {
>   		.name = "cpu_clk_trace_div",
>   		.ops = &clk_regmap_divider_ro_ops,
>   		.parent_data = &(const struct clk_parent_data) {
> -			/*
> -			 * Note:
> -			 * G12A and G12B have different cpu_clks (with
> -			 * different struct clk_hw). We fallback to the global
> -			 * naming string mechanism so cpu_clk_trace_div picks
> -			 * up the appropriate one.
> -			 */
>   			.name = "cpu_clk",
>   			.index = -1,
>   		},
> 
> ---
> base-commit: 799ce46951dcc75682223cdab12fdc905f2fe735
> change-id: 20241213-amlogic-clk-g12a-cpua-parent-fix-64362495fc9b
> 
> Best regards,

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From willmcvicker at google.com  Mon Dec 16 10:54:15 2024
From: willmcvicker at google.com (William McVicker)
Date: Mon, 16 Dec 2024 10:54:15 -0800
Subject: [PATCH v2 3/4] arm64: dts: exynos: gs101: add ACPM protocol node
In-Reply-To: <20241212-b4-acpm-v4-upstream-dts-v2-3-91b7a6f6d0b0@linaro.org>
References: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
 <20241212-b4-acpm-v4-upstream-dts-v2-3-91b7a6f6d0b0@linaro.org>
Message-ID: <Z2B3V78k2ibIdLYh@google.com>

Hi Tudor,

On 12/12/2024, Tudor Ambarus wrote:
> Add the ACPM protocol node. ACPM protocol provides interface for all
> the client drivers making use of the features offered by the
> Active Power Management (APM) module.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> index 04561e15b96c..8c3f07371912 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> @@ -277,6 +277,28 @@ apm_sram: sram at 2039000 {
>  		ranges = <0x0 0x0 0x2039000 0x40000>;
>  	};
>  
> +	firmware {
> +		acpm_ipc: power-management {
> +			compatible = "google,gs101-acpm-ipc";
> +			mboxes = <&ap2apm_mailbox 0 0
> +				  &ap2apm_mailbox 0 1
> +				  &ap2apm_mailbox 0 2
> +				  &ap2apm_mailbox 0 3
> +				  &ap2apm_mailbox 0 4
> +				  &ap2apm_mailbox 0 5
> +				  &ap2apm_mailbox 0 6
> +				  &ap2apm_mailbox 0 7
> +				  &ap2apm_mailbox 0 8
> +				  &ap2apm_mailbox 0 9
> +				  &ap2apm_mailbox 0 10
> +				  &ap2apm_mailbox 0 11
> +				  &ap2apm_mailbox 0 12
> +				  &ap2apm_mailbox 0 13
> +				  &ap2apm_mailbox 0 14>;
> +			shmem = <&apm_sram>;
> +		};
> +	};

You mentioned in the previous patch that "GS101 has 14 mailbox controllers",
but here you have 15 mailboxes. I looked at the downstream driver and see the
number of mailboxes is defined by the ACPM framework (firmware) which is read
from SRAM initdata. Dumping that, I see there are 15 ACPM channels. Have you
looked into into extracting the data from the initdata SRAM address?

Thanks,
Will


From Frank.Li at nxp.com  Mon Dec 16 11:25:14 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 16 Dec 2024 14:25:14 -0500
Subject: [PATCH v4 1/2] dt-bindings: thermal: fsl,imx91-tmu: add bindings
 for NXP i.MX91 thermal module
In-Reply-To: <20241216-imx91tmu-v4-0-75caef7481b8@nxp.com>
References: <20241216-imx91tmu-v4-0-75caef7481b8@nxp.com>
Message-ID: <20241216-imx91tmu-v4-1-75caef7481b8@nxp.com>

From: Pengfei Li <pengfei.li_1 at nxp.com>

Add bindings documentation for i.MX91 thermal modules.

Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v2 to v3
- add ref thermal-sensor
- restrict #thermal-sensor-cells to 0 only
- Change to unevaluatedProperties
---
 .../devicetree/bindings/thermal/fsl,imx91-tmu.yaml | 67 ++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml b/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml
new file mode 100644
index 0000000000000..8411f3233bf44
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/fsl,imx91-tmu.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/fsl,imx91-tmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX91 Thermal
+
+maintainers:
+  - Pengfei Li <pengfei.li_1 at nxp.com>
+
+description:
+  i.MX91 features a new temperature sensor. It includes programmable
+  temperature threshold comparators for both normal and privileged
+  accesses and allows a programmable measurement frequency for the
+  Periodic One-Shot Measurement mode. Additionally, it provides
+  status registers for indicating the end of measurement and threshold
+  violation events.
+
+properties:
+  compatible:
+    items:
+      - const: fsl,imx91-tmu
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  nvmem-cells:
+    items:
+      - description: Phandle to the trim control 1 provided by ocotp
+      - description: Phandle to the trim control 2 provided by ocotp
+
+  nvmem-cell-names:
+    items:
+      - const: trim1
+      - const: trim2
+
+  "#thermal-sensor-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+allOf:
+  - $ref: thermal-sensor.yaml
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx93-clock.h>
+
+    thermal-sensor at 44482000 {
+        compatible = "fsl,imx91-tmu";
+        reg = <0x44482000 0x1000>;
+        #thermal-sensor-cells = <0>;
+        clocks = <&clk IMX93_CLK_TMC_GATE>;
+        nvmem-cells = <&tmu_trim1>, <&tmu_trim2>;
+        nvmem-cell-names = "trim1", "trim2";
+    };
+
+...

-- 
2.34.1



From Frank.Li at nxp.com  Mon Dec 16 11:25:13 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 16 Dec 2024 14:25:13 -0500
Subject: [PATCH v4 0/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
Message-ID: <20241216-imx91tmu-v4-0-75caef7481b8@nxp.com>

- Add binding doc
- Add imx91 thermal driver
- dts part wait for https://lore.kernel.org/imx/Z04W5chGq5TitB9f at lizhi-Precision-Tower-5810/
merged, so not in this serial.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Changes in v4:
- Add Kryz's review tag for binding
- Add Marco's review tag for driver
- Use devm_add_action()
- Move pm_runtim_put before thermal_of_zone_register()
- Link to v3: https://lore.kernel.org/r/20241212-imx91tmu-v3-0-85e756b29437 at nxp.com

Changes in v3:
- add ref thermal-sensor
- restrict #thermal-sensor-cells to 0 only
- Change to unevaluatedProperties

- add IMX91_TMU_ prefix for register define
- remove unused register define
- fix missed pm_runtime_put() at error path in imx91_tmu_get_temp()
- use dev variable in probe function
- use pm_runtime_set_active() in probe
- move START to imx91_tmu_get_temp()
- use DEFINE_RUNTIME_DEV_PM_OPS()
- keep set reset value because there are not sw "reset" bit in controller,
  uboot may change and enable tmu.

- Link to v2: https://lore.kernel.org/r/20241210-imx91tmu-v2-0-5032aad4d88e at nxp.com

Changes in v2:
- use low case for hexvalue
- combine struct imx91_tmu and tmu_sensor
- simplify imx91_tmu_start() and imx91_tmu_enable()
- use s16 for imx91_tmu_get_temp(), which may negative value
- use reverse christmas tree style
- use run time pm
- use oneshot to sample temp
- register thermal zone after hardware init
- Link to v1: https://lore.kernel.org/r/20241209-imx91tmu-v1-0-7859c5387f31 at nxp.com

---
Pengfei Li (2):
      dt-bindings: thermal: fsl,imx91-tmu: add bindings for NXP i.MX91 thermal module
      thermal: imx91: Add support for i.MX91 thermal monitoring unit

 .../devicetree/bindings/thermal/fsl,imx91-tmu.yaml |  67 ++++++
 drivers/thermal/Kconfig                            |  10 +
 drivers/thermal/Makefile                           |   1 +
 drivers/thermal/imx91_thermal.c                    | 263 +++++++++++++++++++++
 4 files changed, 341 insertions(+)
---
base-commit: d07c576946b2bc440d6d2073998023e8a0bd7568
change-id: 20241209-imx91tmu-af2a7c042d8d

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Mon Dec 16 11:25:15 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 16 Dec 2024 14:25:15 -0500
Subject: [PATCH v4 2/2] thermal: imx91: Add support for i.MX91 thermal
 monitoring unit
In-Reply-To: <20241216-imx91tmu-v4-0-75caef7481b8@nxp.com>
References: <20241216-imx91tmu-v4-0-75caef7481b8@nxp.com>
Message-ID: <20241216-imx91tmu-v4-2-75caef7481b8@nxp.com>

From: Pengfei Li <pengfei.li_1 at nxp.com>

Introduce support for the i.MX91 thermal monitoring unit, which features a
single sensor for the CPU. The register layout differs from other chips,
necessitating the creation of a dedicated file for this.

Signed-off-by: Pengfei Li <pengfei.li_1 at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v3 to v4
- Add Macro's review tag
- Use devm_add_action()
- Move pm_runtim_put before thermal_of_zone_register()

change from v2 to v3
- add IMX91_TMU_ prefix for register define
- remove unused register define
- fix missed pm_runtime_put() at error path in imx91_tmu_get_temp()
- use dev variable in probe function
- use pm_runtime_set_active() in probe
- move START to imx91_tmu_get_temp()
- use DEFINE_RUNTIME_DEV_PM_OPS()
- keep set reset value because there are not sw "reset" bit in controller,
uboot may change and enable tmu.

change from v1 to v2
- use low case for hexvalue
- combine struct imx91_tmu and tmu_sensor
- simplify imx91_tmu_start() and imx91_tmu_enable()
- use s16 for imx91_tmu_get_temp(), which may negative value
- use reverse christmas tree style
- use run time pm
- use oneshot to sample temp
- register thermal zone after hardware init
---
 drivers/thermal/Kconfig         |  10 ++
 drivers/thermal/Makefile        |   1 +
 drivers/thermal/imx91_thermal.c | 263 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 274 insertions(+)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index d3f9686e26e71..da403ed86aeb1 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -296,6 +296,16 @@ config IMX8MM_THERMAL
 	  cpufreq is used as the cooling device to throttle CPUs when the passive
 	  trip is crossed.
 
+config IMX91_THERMAL
+	tristate "Temperature sensor driver for NXP i.MX91 SoC"
+	depends on ARCH_MXC || COMPILE_TEST
+	depends on OF
+	help
+	  Support for Temperature sensor found on NXP i.MX91 SoC.
+	  It supports one critical trip point and one passive trip point. The
+	  cpufreq is used as the cooling device to throttle CPUs when the passive
+	  trip is crossed.
+
 config K3_THERMAL
 	tristate "Texas Instruments K3 thermal support"
 	depends on ARCH_K3 || COMPILE_TEST
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 9abf43a74f2bb..08da241e6a598 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_ARMADA_THERMAL)	+= armada_thermal.o
 obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
 obj-$(CONFIG_IMX_SC_THERMAL)	+= imx_sc_thermal.o
 obj-$(CONFIG_IMX8MM_THERMAL)	+= imx8mm_thermal.o
+obj-$(CONFIG_IMX91_THERMAL)	+= imx91_thermal.o
 obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
 obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
 obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
diff --git a/drivers/thermal/imx91_thermal.c b/drivers/thermal/imx91_thermal.c
new file mode 100644
index 0000000000000..ef5e8e181dd0f
--- /dev/null
+++ b/drivers/thermal/imx91_thermal.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2024 NXP.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/thermal.h>
+
+#define IMX91_TMU_STAT0				0x10
+#define IMX91_TMU_STAT0_DRDY0_IF_MASK		BIT(16)
+
+#define IMX91_TMU_DATA0				0x20
+
+#define IMX91_TMU_CTRL1_SET			0x204
+#define IMX91_TMU_CTRL1_CLR			0x208
+#define IMX91_TMU_CTRL1_EN			BIT(31)
+#define IMX91_TMU_CTRL1_START			BIT(30)
+#define IMX91_TMU_CTRL1_STOP			BIT(29)
+#define IMX91_TMU_CTRL1_RES_MASK		GENMASK(19, 18)
+#define IMX91_TMU_CTRL1_MEAS_MODE_MASK		GENMASK(25, 24)
+#define   IMX91_TMU_CTRL1_MEAS_MODE_SINGLE	0
+#define   IMX91_TMU_CTRL1_MEAS_MODE_CONTINUES	1
+#define   IMX91_TMU_CTRL1_MEAS_MODE_PERIODIC	2
+
+#define IMX91_TMU_REF_DIV			0x280
+#define IMX91_TMU_DIV_EN			BIT(31)
+#define IMX91_TMU_DIV_MASK			GENMASK(23, 16)
+#define IMX91_TMU_DIV_MAX			255
+
+#define IMX91_TMU_PUD_ST_CTRL			0x2b0
+#define IMX91_TMU_PUDL_MASK			GENMASK(23, 16)
+
+#define IMX91_TMU_TRIM1				0x2e0
+#define IMX91_TMU_TRIM2				0x2f0
+
+#define IMX91_TMU_TEMP_LOW_LIMIT		-40000
+#define IMX91_TMU_TEMP_HIGH_LIMIT		125000
+
+#define IMX91_TMU_DEFAULT_TRIM1_CONFIG		0xb561bc2d
+#define IMX91_TMU_DEFAULT_TRIM2_CONFIG		0x65d4
+
+struct imx91_tmu {
+	void __iomem *base;
+	struct clk *clk;
+	struct device *dev;
+	struct thermal_zone_device *tzd;
+};
+
+static void imx91_tmu_start(struct imx91_tmu *tmu, bool start)
+{
+	u32 val = start ? IMX91_TMU_CTRL1_START : IMX91_TMU_CTRL1_STOP;
+
+	writel_relaxed(val, tmu->base + IMX91_TMU_CTRL1_SET);
+}
+
+static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable)
+{
+	u32 reg = enable ? IMX91_TMU_CTRL1_SET : IMX91_TMU_CTRL1_CLR;
+
+	writel_relaxed(IMX91_TMU_CTRL1_EN, tmu->base + reg);
+}
+
+static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+	struct imx91_tmu *tmu = thermal_zone_device_priv(tz);
+	s16 data;
+	int ret;
+	u32 val;
+
+	ret = pm_runtime_resume_and_get(tmu->dev);
+	if (ret < 0)
+		return ret;
+
+	imx91_tmu_start(tmu, true);
+
+	ret = readl_relaxed_poll_timeout(tmu->base + IMX91_TMU_STAT0, val,
+					 val & IMX91_TMU_STAT0_DRDY0_IF_MASK, 1000, 40000);
+	if (ret) {
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	/* DATA0 is 16bit signed number */
+	data = readw_relaxed(tmu->base + IMX91_TMU_DATA0);
+	*temp = data * 1000 / 64;
+	if (*temp < IMX91_TMU_TEMP_LOW_LIMIT || *temp > IMX91_TMU_TEMP_HIGH_LIMIT)
+		ret = -EAGAIN;
+
+out:
+	pm_runtime_put(tmu->dev);
+
+	return ret;
+}
+
+static struct thermal_zone_device_ops tmu_tz_ops = {
+	.get_temp = imx91_tmu_get_temp,
+};
+
+static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu)
+{
+	struct device *dev = tmu->dev;
+	u32 trim1, trim2;
+	int ret;
+
+	ret = nvmem_cell_read_u32(dev, "trim1", &trim1);
+	if (ret)
+		return ret;
+
+	ret = nvmem_cell_read_u32(dev, "trim2", &trim2);
+	if (ret)
+		return ret;
+
+	if (trim1 == 0 || trim2 == 0)
+		return -EINVAL;
+
+	writel_relaxed(trim1, tmu->base + IMX91_TMU_TRIM1);
+	writel_relaxed(trim2, tmu->base + IMX91_TMU_TRIM2);
+
+	return 0;
+}
+
+static void imx91_tmu_action_remove(void *data)
+{
+	struct imx91_tmu *tmu = data;
+
+	/* disable tmu */
+	imx91_tmu_enable(tmu, false);
+}
+
+static int imx91_tmu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct imx91_tmu *tmu;
+	unsigned long rate;
+	u32 div;
+	int ret;
+
+	tmu = devm_kzalloc(dev, sizeof(struct imx91_tmu), GFP_KERNEL);
+	if (!tmu)
+		return -ENOMEM;
+
+	tmu->dev = dev;
+
+	tmu->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(tmu->base))
+		return dev_err_probe(dev, PTR_ERR(tmu->base), "failed to get io resource");
+
+	tmu->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(tmu->clk))
+		return dev_err_probe(dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n");
+
+	platform_set_drvdata(pdev, tmu);
+
+	/* disable the monitor during initialization */
+	imx91_tmu_enable(tmu, false);
+	imx91_tmu_start(tmu, false);
+
+	ret = imx91_init_from_nvmem_cells(tmu);
+	if (ret) {
+		writel_relaxed(IMX91_TMU_DEFAULT_TRIM1_CONFIG, tmu->base + IMX91_TMU_TRIM1);
+		writel_relaxed(IMX91_TMU_DEFAULT_TRIM2_CONFIG, tmu->base + IMX91_TMU_TRIM2);
+	}
+
+	/* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */
+	rate = clk_get_rate(tmu->clk);
+	div = (rate / 4000000) - 1;
+	if (div > IMX91_TMU_DIV_MAX)
+		return dev_err_probe(dev, -EINVAL, "clock divider exceed hardware limitation");
+
+	/* Set divider value and enable divider */
+	writel_relaxed(IMX91_TMU_DIV_EN | FIELD_PREP(IMX91_TMU_DIV_MASK, div),
+		       tmu->base + IMX91_TMU_REF_DIV);
+
+	/* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */
+	writel_relaxed(FIELD_PREP(IMX91_TMU_PUDL_MASK, 100U), tmu->base + IMX91_TMU_PUD_ST_CTRL);
+
+	/*
+	 * Set resolution mode
+	 * 00b - Conversion time = 0.59325 ms
+	 * 01b - Conversion time = 1.10525 ms
+	 * 10b - Conversion time = 2.12925 ms
+	 * 11b - Conversion time = 4.17725 ms
+	 */
+	writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_RES_MASK, 0x3), tmu->base + IMX91_TMU_CTRL1_CLR);
+	writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_RES_MASK, 0x1), tmu->base + IMX91_TMU_CTRL1_SET);
+
+	writel_relaxed(IMX91_TMU_CTRL1_MEAS_MODE_MASK, tmu->base + IMX91_TMU_CTRL1_CLR);
+	writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_MEAS_MODE_MASK, IMX91_TMU_CTRL1_MEAS_MODE_SINGLE),
+		       tmu->base + IMX91_TMU_CTRL1_SET);
+
+	pm_runtime_set_active(dev);
+	devm_pm_runtime_enable(dev);
+	pm_runtime_put(dev);
+
+	tmu->tzd = devm_thermal_of_zone_register(dev, 0, tmu, &tmu_tz_ops);
+	if (IS_ERR(tmu->tzd))
+		return dev_err_probe(dev, PTR_ERR(tmu->tzd),
+				     "failed to register thermal zone sensor\n");
+
+	ret = devm_add_action(dev, imx91_tmu_action_remove, tmu);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failure to add action imx91_tmu_action_remove()\n");
+
+	return 0;
+}
+
+static int imx91_tmu_runtime_suspend(struct device *dev)
+{
+	struct imx91_tmu *tmu = dev_get_drvdata(dev);
+
+	/* disable tmu */
+	imx91_tmu_enable(tmu, false);
+
+	clk_disable_unprepare(tmu->clk);
+
+	return 0;
+}
+
+static int imx91_tmu_runtime_resume(struct device *dev)
+{
+	struct imx91_tmu *tmu = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(tmu->clk);
+	if (ret)
+		return ret;
+
+	imx91_tmu_enable(tmu, true);
+
+	return 0;
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(imx91_tmu_pm_ops, imx91_tmu_runtime_suspend,
+				 imx91_tmu_runtime_resume, NULL);
+
+static const struct of_device_id imx91_tmu_table[] = {
+	{ .compatible = "fsl,imx91-tmu", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, imx91_tmu_table);
+
+static struct platform_driver imx91_tmu = {
+	.driver = {
+		.name	= "imx91_thermal",
+		.pm	= pm_ptr(&imx91_tmu_pm_ops),
+		.of_match_table = imx91_tmu_table,
+	},
+	.probe = imx91_tmu_probe,
+};
+module_platform_driver(imx91_tmu);
+
+MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
+MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From broonie at kernel.org  Mon Dec 16 11:28:24 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 19:28:24 +0000
Subject: [PATCH] KVM: arm64: Fix set_id_regs selftest for ASIDBITS becoming
 unwritable
Message-ID: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>

In commit 03c7527e97f7 ("KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits
to be overridden") we made that bitfield in the ID registers unwritable
however the change neglected to make the corresponding update to set_id_regs
resulting in it failing:

# ok 56 ID_AA64MMFR0_EL1_BIGEND
# ==== Test Assertion Failure ====
#   aarch64/set_id_regs.c:434: masks[idx] & ftr_bits[j].mask == ftr_bits[j].mask
#   pid=5566 tid=5566 errno=22 - Invalid argument
#      1	0x00000000004034a7: test_vm_ftr_id_regs at set_id_regs.c:434
#      2	0x0000000000401b53: main at set_id_regs.c:684
#      3	0x0000ffff8e6b7543: ?? ??:0
#      4	0x0000ffff8e6b7617: ?? ??:0
#      5	0x0000000000401e6f: _start at ??:?
#   0 != 0xf0 (masks[idx] & ftr_bits[j].mask != ftr_bits[j].mask)
not ok 8 selftests: kvm: set_id_regs # exit=254

Remove ID_AA64MMFR1_EL1.ASIDBITS from the set of bitfields we test for
writeability.

Fixes: 03c7527e97f7 ("KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden")
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/kvm/aarch64/set_id_regs.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/aarch64/set_id_regs.c b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
index a79b7f18452d2ec336ae623b8aa5c9cf329b6b4e..3a97c160b5fec990aaf8dfaf100a907b913f057c 100644
--- a/tools/testing/selftests/kvm/aarch64/set_id_regs.c
+++ b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
@@ -152,7 +152,6 @@ static const struct reg_ftr_bits ftr_id_aa64mmfr0_el1[] = {
 	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, BIGENDEL0, 0),
 	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, SNSMEM, 0),
 	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, BIGEND, 0),
-	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, ASIDBITS, 0),
 	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, PARANGE, 0),
 	REG_FTR_END,
 };

---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241216-kvm-arm64-fix-set-id-asidbits-9bede25b7ad3

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From harry.wentland at amd.com  Mon Dec 16 11:38:54 2024
From: harry.wentland at amd.com (Harry Wentland)
Date: Mon, 16 Dec 2024 14:38:54 -0500
Subject: [PATCH v2 04/10] drm/amd/display: use eld_mutex to protect access
 to connector->eld
In-Reply-To: <CADnq5_M8jC2w=XWB4BG+id60zfGFMMkSegmeg-y=VpSHC+FvFQ@mail.gmail.com>
References: <20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea@linaro.org>
 <20241206-drm-connector-eld-mutex-v2-4-c9bce1ee8bea@linaro.org>
 <pgi7p3aemxm3db2k27vi5euh6q6ppayrw6y7tcfeq4g5z23hzr@xousag2qhobp>
 <fc8e80dd-bcea-4515-b446-158649719569@amd.com>
 <CAA8EJpoR8HYq9ATDfmR5ksSnttBzj=DY+BKp5=OuVNF1WDJ-fg@mail.gmail.com>
 <CADnq5_M8jC2w=XWB4BG+id60zfGFMMkSegmeg-y=VpSHC+FvFQ@mail.gmail.com>
Message-ID: <ab347745-80cc-4a5c-ab92-de6bc6bce3cc@amd.com>



On 2024-12-16 10:31, Alex Deucher wrote:
> On Mon, Dec 16, 2024 at 10:12?AM Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
>>
>> On Mon, 16 Dec 2024 at 16:53, Harry Wentland <harry.wentland at amd.com> wrote:
>>>
>>>
>>>
>>> On 2024-12-10 16:20, Dmitry Baryshkov wrote:
>>>> On Fri, Dec 06, 2024 at 11:43:07AM +0200, Dmitry Baryshkov wrote:
>>>>> Reading access to connector->eld can happen at the same time the
>>>>> drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
>>>>> order to protect connector->eld from concurrent access.
>>>>>
>>>>> Reviewed-by: Maxime Ripard <mripard at kernel.org>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>>>> ---
>>>>>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
>>>>>  1 file changed, 2 insertions(+)
>>>>
>>>> Harry, Leo, Rodrigo, Alex, Christian, Xinhui, any response to this one
>>>> and to the radeon patches? I'd like to be able to pick the series for
>>>> drm-misc and these two are not reviewed by you.
>>>>
>>>>>
>>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>>> index 19a58630e774029767bf2a27eb4ddf17e3c21129..04c68c320252b5ce9647f0606fb86fe57f347639 100644
>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>>> @@ -1037,8 +1037,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port,
>>>>>                      continue;
>>>>>
>>>>>              *enabled = true;
>>>>> +            mutex_lock(&connector->eld_mutex);
>>>>>              ret = drm_eld_size(connector->eld);
>>>>>              memcpy(buf, connector->eld, min(max_bytes, ret));
>>>>> +            mutex_unlock(&connector->eld_mutex);
>>>
>>> All of this is wrapped by the adev->dm.audio_lock mutex. It might
>>> be safer to modify the audio_lock mutex so it only guards the
>>> aconnector->audio_inst access.
>>>
>>> But I don't see any way these mutexes would otherwise interact,
>>> so this change should be good as-is.
>>>
>>> Reviewed-by: Harry Wentland <harry.wentland at amd.com>
>>
>> Would you ack it to merge it through drm-misc? Or would you prefer to
>> pick up those two patches after merging drm-misc-next once the rest of
>> the series lands?
> 
> Merging through drm-misc is fine with me.
> 

Same.

Harry

> Thanks,
> 
> Alex
> 
>>
>>>
>>> Harry
>>>
>>>>>
>>>>>              break;
>>>>>      }
>>>>>
>>>>> --
>>>>> 2.39.5
>>>>>
>>>>
>>>
>>
>>
>> --
>> With best wishes
>> Dmitry



From nfraprado at collabora.com  Mon Dec 16 11:51:25 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 16 Dec 2024 16:51:25 -0300
Subject: [PATCH 1/2] arm64: defconfig: Enable sound for MT8188
In-Reply-To: <20241216-genio700-configs-eth-sound-v1-0-04a719035d6e@collabora.com>
References: <20241216-genio700-configs-eth-sound-v1-0-04a719035d6e@collabora.com>
Message-ID: <20241216-genio700-configs-eth-sound-v1-1-04a719035d6e@collabora.com>

Enable platform and machine sound drivers for the MT8188 SoC with the
MT6359 PMIC codec, as well as the MT8186 SOF driver which is also
compatible with MT8188, in order to get working sound on MT8188 SoCs.

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 dfa5c8d5b65863741be7d7d3c6f6f05567d336da..95af0377ddc673be7003d7517e3990012a817cbe 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -970,6 +970,8 @@ CONFIG_SND_SOC_IMX_AUDMIX=m
 CONFIG_SND_SOC_MT8183=m
 CONFIG_SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A=m
 CONFIG_SND_SOC_MT8183_DA7219_MAX98357A=m
+CONFIG_SND_SOC_MT8188=m
+CONFIG_SND_SOC_MT8188_MT6359=m
 CONFIG_SND_SOC_MT8192=m
 CONFIG_SND_SOC_MT8192_MT6359_RT1015_RT5682=m
 CONFIG_SND_SOC_MT8195=m
@@ -998,6 +1000,7 @@ CONFIG_SND_SOC_RZ=m
 CONFIG_SND_SOC_SOF_TOPLEVEL=y
 CONFIG_SND_SOC_SOF_OF=y
 CONFIG_SND_SOC_SOF_MTK_TOPLEVEL=y
+CONFIG_SND_SOC_SOF_MT8186=m
 CONFIG_SND_SOC_SOF_MT8195=m
 CONFIG_SND_SUN8I_CODEC=m
 CONFIG_SND_SUN8I_CODEC_ANALOG=m

-- 
2.47.1



From conor at kernel.org  Mon Dec 16 11:50:53 2024
From: conor at kernel.org (Conor Dooley)
Date: Mon, 16 Dec 2024 19:50:53 +0000
Subject: [PATCH v2 03/11] dt-bindings: regulator: pca9450: Document
 nxp,sd-vsel-fixed-low property for LDO5
In-Reply-To: <9276fad1-0e3c-4935-a62a-1580af2e0a4b@kontron.de>
References: <20241127164337.613915-1-frieder@fris.de>
 <20241127164337.613915-4-frieder@fris.de>
 <20241128-endanger-envy-d1b19f650b38@spud>
 <9276fad1-0e3c-4935-a62a-1580af2e0a4b@kontron.de>
Message-ID: <20241216-reburial-turmoil-4825bbee6aa8@spud>

On Tue, Dec 10, 2024 at 04:36:41PM +0100, Frieder Schrempf wrote:
> On 28.11.24 6:33 PM, Conor Dooley wrote:
> > On Wed, Nov 27, 2024 at 05:42:19PM +0100, Frieder Schrempf wrote:
> >> From: Frieder Schrempf <frieder.schrempf at kontron.de>
> >>
> >> This new property can be used for boards which have the SD_VSEL tied
> >> to a fixed low level. The voltage of LDO5 is therefore only controlled
> >> by writing to the LDO5CTRL_L register.
> >>
> >> Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> >> ---
> >> Changes for v2:
> >> * new patch
> >> ---
> >>  .../bindings/regulator/nxp,pca9450-regulator.yaml           | 6 ++++++
> >>  1 file changed, 6 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
> >> index 5d0d684186c96..0e19c54aa5f8a 100644
> >> --- a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
> >> +++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
> >> @@ -49,6 +49,12 @@ properties:
> >>            Properties for single LDO5 regulator.
> >>  
> >>          properties:
> >> +          nxp,sd-vsel-fixed-low:
> >> +            type: boolean
> >> +            description:
> >> +              Let the driver know that SD_VSEL is hardwired to low level and
> >> +              there is no GPIO to get the actual value from.
> > 
> > Does this mean that if you don't provide the property or a GPIO it is tied
> > high or High-Z? If so, please mention it here. More likely, given the
> > context of this patch, no gpio and no tied low property means the driver
> > should handle things as they used to be - but you should call that out
> > in your commit message to be clear.
> 
> Providing neither 'sd-vsel-gpios', nor 'nxp,sd-vsel-fixed-low' means the
> driver has to assume that SD_VSEL is tied high and it has to use the
> LDO5CTRL_H for voltage control.
> 
> I will make this more clear in the commit message.
> 
> This is the original/current behavior of the driver, though it doesn't
> match the actual hardware as all known boards actually have the SD_VSEL
> connected to the USDHC_VSELECT (which changes state whenever the USDHC
> controller wants to switch IO voltage).

That's fine, as long as it is a match for the old behaviour. Sorry for
the delay responding, I was unexpectedly AFK last week.

> 
> Getting rid of this mismatch is one of the main motivations for this series.
> 
> > 
> >> +
> >>            sd-vsel-gpios:
> >>              description:
> >>                GPIO that can be used to read the current status of the SD_VSEL
> >> -- 
> >> 2.46.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/20241216/b3e907d3/attachment.sig>

From nfraprado at collabora.com  Mon Dec 16 11:51:24 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 16 Dec 2024 16:51:24 -0300
Subject: [PATCH 0/2] arm64: defconfig: Configs for MT8188
Message-ID: <20241216-genio700-configs-eth-sound-v1-0-04a719035d6e@collabora.com>

This series contains a couple configs needed for MT8188 platforms to get
working ethernet and sound.

Tested on the Genio 700 EVK.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
N?colas F. R. A. Prado (2):
      arm64: defconfig: Enable sound for MT8188
      arm64: defconfig: Enable MediaTek DWMAC

 arch/arm64/configs/defconfig | 4 ++++
 1 file changed, 4 insertions(+)
---
base-commit: e25c8d66f6786300b680866c0e0139981273feba
change-id: 20241216-genio700-configs-eth-sound-8876c4356602

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From nfraprado at collabora.com  Mon Dec 16 11:51:26 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 16 Dec 2024 16:51:26 -0300
Subject: [PATCH 2/2] arm64: defconfig: Enable MediaTek DWMAC
In-Reply-To: <20241216-genio700-configs-eth-sound-v1-0-04a719035d6e@collabora.com>
References: <20241216-genio700-configs-eth-sound-v1-0-04a719035d6e@collabora.com>
Message-ID: <20241216-genio700-configs-eth-sound-v1-2-04a719035d6e@collabora.com>

Enable the config for the DWMAC MediaTek glue layer to allow usage of
the Ethernet controller present on MT8195 and MT8188 SoCs.

Signed-off-by: N?colas F. R. A. Prado <nfraprado 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 95af0377ddc673be7003d7517e3990012a817cbe..188a0f3faedc62d92d0d59a397570e4c88c3f803 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -375,6 +375,7 @@ CONFIG_SMSC911X=y
 CONFIG_SNI_AVE=y
 CONFIG_SNI_NETSEC=y
 CONFIG_STMMAC_ETH=m
+CONFIG_DWMAC_MEDIATEK=m
 CONFIG_DWMAC_TEGRA=m
 CONFIG_TI_K3_AM65_CPSW_NUSS=y
 CONFIG_TI_ICSSG_PRUETH=m

-- 
2.47.1



From conor at kernel.org  Mon Dec 16 11:59:20 2024
From: conor at kernel.org (Conor Dooley)
Date: Mon, 16 Dec 2024 19:59:20 +0000
Subject: [PATCH v2 01/11] Revert "regulator: pca9450: Add sd-vsel GPIO"
In-Reply-To: <b5456480-a68f-4e71-831b-f145453e2646@kontron.de>
References: <20241127164337.613915-1-frieder@fris.de>
 <20241127164337.613915-2-frieder@fris.de>
 <20241128-candle-guzzler-b7ea4e5ce643@spud>
 <b5456480-a68f-4e71-831b-f145453e2646@kontron.de>
Message-ID: <20241216-unchain-respect-1c344203a140@spud>

On Tue, Dec 10, 2024 at 04:59:06PM +0100, Frieder Schrempf wrote:
> On 28.11.24 6:37 PM, Conor Dooley wrote:
> > On Wed, Nov 27, 2024 at 05:42:17PM +0100, Frieder Schrempf wrote:
> >> From: Frieder Schrempf <frieder.schrempf at kontron.de>
> >>
> >> This reverts commit 27866e3e8a7e93494f8374f48061aa73ee46ceb2.
> >>
> >> It turned out that this feature was implemented based on
> >> the wrong assumption that the SD_VSEL signal needs to be
> >> controlled as GPIO in any case.
> >>
> >> In fact the straight-forward approach is to mux the signal
> >> as USDHC_VSELECT and let the USDHC controller do the job.
> >>
> >> Most users never even used this property and the few who
> >> did have been or are getting migrated to the alternative
> >> approach.
> >>
> >> Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> >> ---
> >> Changes for v2:
> >> * split revert into separate patch
> >> ---
> >>  .../devicetree/bindings/regulator/nxp,pca9450-regulator.yaml | 5 -----
> >>  1 file changed, 5 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
> >> index f8057bba747a5..79fc0baf5fa2f 100644
> >> --- a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
> >> +++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
> >> @@ -77,11 +77,6 @@ properties:
> >>  
> >>      additionalProperties: false
> >>  
> >> -  sd-vsel-gpios:
> >> -    description: GPIO that is used to switch LDO5 between being configured by
> >> -      LDO5CTRL_L or LDO5CTRL_H register. Use this if the SD_VSEL signal is
> >> -      connected to a host GPIO.
> > 
> > Your driver side of this, that I wasn't sent and cba downloading an
> > mbox of is not backwards compatible. The code has been there for a few
> > years, are you sure that there are no out of tree users or other OSes
> > that use the property?
> 
> Yes, this is not backwards compatible. I introduced the original meaning
> for the sd-vsel-gpios property based on some misunderstanding of how the
> hardware actually works. Therefore I'm quite sure that except for the
> cases where someone copied my erroneous implementation into their
> devicetree, nobody has really any reason to actually use this.
> 
> In-tree all users have been removed (one fix still included in this
> series). Of course we can't be fully sure that there isn't someone out
> there having non-standard hardware (SD_VSEL not connected to
> USDHC_VSELECT but to GPIO only) and using the old sd-vsel-gpios, but the
> probability is very, very low.
> 
> IMHO taking the small risk here is better than keeping the misleading
> implementation which will likely cause confusion and failures in the
> future. But of course that's not up to me to decide.

Given that the !property case retains the behaviour from before, only
those with the property are affected - which means if it does end up
being problematic then it can be rectified at that point in time.

> > tbh, I think all 3 of your dt-binding patches should be squashed rather
> > than drip-feeding the conversion. It makes more sense as a single
> > change, rather than splitting the rationales across 3 patches.
> 
> Ok, if you like this better in one change I can squash these for the
> next version.

Sounds good, sorry again for the delay getting back to you.
-------------- 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/20241216/f46a0716/attachment.sig>

From quic_akhilpo at quicinc.com  Mon Dec 16 12:28:30 2024
From: quic_akhilpo at quicinc.com (Akhil P Oommen)
Date: Tue, 17 Dec 2024 01:58:30 +0530
Subject: [PATCH] iommu/arm-smmu-qcom: Only enable stall on smmu-v2
In-Reply-To: <20241216171017.4881-1-robdclark@gmail.com>
References: <20241216171017.4881-1-robdclark@gmail.com>
Message-ID: <a15a7594-8793-478b-a86e-81a06812e4ff@quicinc.com>

On 12/16/2024 10:40 PM, Rob Clark wrote:
> From: Rob Clark <robdclark at chromium.org>
> 
> On mmu-500, stall-on-fault seems to stall all context banks, causing the
> GMU to misbehave.  So limit this feature to smmu-v2 for now.
> 
> This fixes an issue with an older mesa bug taking outo the system
> because of GMU going off into the year.
> 
> Signed-off-by: Rob Clark <robdclark at chromium.org>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index c4c52f7bd09a..1c881e88fc4d 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -331,8 +331,10 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>  	priv->get_ttbr1_cfg = qcom_adreno_smmu_get_ttbr1_cfg;
>  	priv->set_ttbr0_cfg = qcom_adreno_smmu_set_ttbr0_cfg;
>  	priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
> -	priv->set_stall = qcom_adreno_smmu_set_stall;
> -	priv->resume_translation = qcom_adreno_smmu_resume_translation;
> +	if (of_device_is_compatible(np, "qcom,smmu-v2")) {
> +		priv->set_stall = qcom_adreno_smmu_set_stall;
> +		priv->resume_translation = qcom_adreno_smmu_resume_translation;
> +	}

Shall we disable this from the driver instead? A debugfs knob to trigger
coredump after a pagefault is very convenient.

-Akhil

>  	priv->set_prr_bit = NULL;
>  	priv->set_prr_addr = NULL;
>  



From broonie at kernel.org  Mon Dec 16 12:52:06 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 20:52:06 +0000
Subject: [PATCH V2 09/46] arm64/sysreg: Add register fields for
 HFGWTR2_EL2
In-Reply-To: <20241210055311.780688-10-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-10-anshuman.khandual@arm.com>
Message-ID: <1c1ac530-35cd-4fe4-93f1-1a6876c796c7@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:34AM +0530, Anshuman Khandual wrote:
> This adds register fields for HFGWTR2_EL2 as per the definitions based
> on DDI0601 2024-09.

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/20241216/7b300222/attachment.sig>

From robdclark at gmail.com  Mon Dec 16 12:54:43 2024
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 16 Dec 2024 12:54:43 -0800
Subject: [PATCH] iommu/arm-smmu-qcom: Only enable stall on smmu-v2
In-Reply-To: <a15a7594-8793-478b-a86e-81a06812e4ff@quicinc.com>
References: <20241216171017.4881-1-robdclark@gmail.com> <a15a7594-8793-478b-a86e-81a06812e4ff@quicinc.com>
Message-ID: <CAF6AEGsFeibyH5_a7m=9PMKReD4Xb+c=dEGsbCN0_UHiJK1vbA@mail.gmail.com>

On Mon, Dec 16, 2024 at 12:28?PM Akhil P Oommen
<quic_akhilpo at quicinc.com> wrote:
>
> On 12/16/2024 10:40 PM, Rob Clark wrote:
> > From: Rob Clark <robdclark at chromium.org>
> >
> > On mmu-500, stall-on-fault seems to stall all context banks, causing the
> > GMU to misbehave.  So limit this feature to smmu-v2 for now.
> >
> > This fixes an issue with an older mesa bug taking outo the system
> > because of GMU going off into the year.
> >
> > Signed-off-by: Rob Clark <robdclark at chromium.org>
> > ---
> >  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 6 ++++--
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > index c4c52f7bd09a..1c881e88fc4d 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > @@ -331,8 +331,10 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> >       priv->get_ttbr1_cfg = qcom_adreno_smmu_get_ttbr1_cfg;
> >       priv->set_ttbr0_cfg = qcom_adreno_smmu_set_ttbr0_cfg;
> >       priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
> > -     priv->set_stall = qcom_adreno_smmu_set_stall;
> > -     priv->resume_translation = qcom_adreno_smmu_resume_translation;
> > +     if (of_device_is_compatible(np, "qcom,smmu-v2")) {
> > +             priv->set_stall = qcom_adreno_smmu_set_stall;
> > +             priv->resume_translation = qcom_adreno_smmu_resume_translation;
> > +     }
>
> Shall we disable this from the driver instead? A debugfs knob to trigger
> coredump after a pagefault is very convenient.

It would require the driver to find the compatible for the smmu, so it
could differentiate btwn smmu-v2 and mmu-500, which seemed like it
might be a bit uglier.

Ideally/hopefully we could figure out how to make GMU a bit more
resilient in the face of stalled translations, because it is useful to
get accurate devcore dumps on smmu faults.  At that point we could
revert this change.

BR,
-R

>
> -Akhil
>
> >       priv->set_prr_bit = NULL;
> >       priv->set_prr_addr = NULL;
> >
>


From broonie at kernel.org  Mon Dec 16 12:57:34 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 20:57:34 +0000
Subject: [PATCH V2 10/46] arm64/sysreg: Add register fields for MDSELR_EL1
In-Reply-To: <20241210055311.780688-11-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-11-anshuman.khandual@arm.com>
Message-ID: <9004e368-6e0d-4313-8ae7-62e3200697f7@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:35AM +0530, Anshuman Khandual wrote:
> This adds register fields for MDSELR_EL1 as per the definitions based
> on DDI0601 2024-09.

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/20241216/53100cb5/attachment.sig>

From ivo.ivanov.ivanov1 at gmail.com  Mon Dec 16 12:59:22 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Mon, 16 Dec 2024 22:59:22 +0200
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
Message-ID: <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>

On 12/16/24 10:44, Krzysztof Kozlowski wrote:
> On 14/12/2024 23:04, Ivaylo Ivanov wrote:
>> Add samsung,exynos8895-hsi2c dedicated compatible for representing
>> I2C of Exynos8895 SoC. Since there are I2C buses that aren't implemented
>> as a part of USIv1 blocks, they only require a single clock.
>>
>> Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
>> ---
>>  .../devicetree/bindings/i2c/i2c-exynos5.yaml  | 26 ++++++++++++++++---
>>  1 file changed, 23 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
>> index cc8bba553..b029be88e 100644
>> --- a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
>> +++ b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
>> @@ -25,6 +25,7 @@ properties:
>>            - samsung,exynos5250-hsi2c    # Exynos5250 and Exynos5420
>>            - samsung,exynos5260-hsi2c    # Exynos5260
>>            - samsung,exynos7-hsi2c       # Exynos7
>> +          - samsung,exynos8895-hsi2c
>>            - samsung,exynosautov9-hsi2c
>>        - items:
>>            - enum:
>> @@ -94,9 +95,28 @@ allOf:
>>          - clock-names
>>  
>>      else:
>> -      properties:
>> -        clocks:
>> -          maxItems: 1
>> +      if:
>> +        properties:
>> +          compatible:
>> +            contains:
>> +              enum:
>> +                - samsung,exynos8895-hsi2c
>> +
>> +      then:
>> +        properties:
>> +          clocks:
> Missing minItems
>
>> +            maxItems: 2
>> +
>> +          clock-names:
> Ditto
>
>> +            maxItems: 2
>> +
>> +        required:
>> +          - clock-names
> I don't understand why do you need second, same branch in if, basically

Because, as I stated in the commit message, we have HSI2C controllers
both implemented in USIv1 blocks and outside. These that are a part of
USIv1 need 2 clocks, and those that aren't have only one. So it's not
a duplicate for the previous - autov9 sets a minitems of 2 and the
others have a maxitems of 1.

Best regards,
Ivo

> duplicating previous. But regardless of that, no nesting of ifs. Define
> clocks for all variants explicitly.
>
> Best regards,
> Krzysztof



From broonie at kernel.org  Mon Dec 16 13:03:24 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 21:03:24 +0000
Subject: [PATCH V2 11/46] arm64/sysreg: Add register fields for PMSIDR_EL1
In-Reply-To: <20241210055311.780688-12-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-12-anshuman.khandual@arm.com>
Message-ID: <ae09e8bd-271a-4942-ab59-f257a67b991b@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:36AM +0530, Anshuman Khandual wrote:
> This adds register fields for PMSIDR_EL1 as per the definitions based
> on DDI0601 2024-09.

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/20241216/2f7063d7/attachment.sig>

From pr-tracker-bot at kernel.org  Mon Dec 16 13:22:39 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Mon, 16 Dec 2024 21:22:39 +0000
Subject: [GIT PULL] soc: fixes for 6.13
In-Reply-To: <cccdf954-3374-414c-81fb-658df16325fc@app.fastmail.com>
References: <cccdf954-3374-414c-81fb-658df16325fc@app.fastmail.com>
Message-ID: <173438415948.354515.11626612676903026198.pr-tracker-bot@kernel.org>

The pull request you sent on Mon, 16 Dec 2024 17:21:06 +0100:

> https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-6.13

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/f44d154d6e3d633d4c49a5d6aed8a0e4684ae25e

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From dianders at chromium.org  Mon Dec 16 13:29:10 2024
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 16 Dec 2024 13:29:10 -0800
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <CAODwPW_c+Ycu_zhiDOKN-fH2FEWf2pxr+FcugpqEjLX-nVjQrg@mail.gmail.com>
References: <20241214005248.198803-1-dianders@chromium.org>
 <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid> <CAODwPW_c+Ycu_zhiDOKN-fH2FEWf2pxr+FcugpqEjLX-nVjQrg@mail.gmail.com>
Message-ID: <CAD=FV=UHBA7zXZEw3K6TRpZEN-ApOkmymhRCOkz7h+yrAkR_Dw@mail.gmail.com>

Hi,

On Fri, Dec 13, 2024 at 6:25?PM Julius Werner <jwerner at chromium.org> wrote:
>
> I feel like this patch is maybe taking a bit of a wrong angle at
> achieving what you're trying to do. The code seems to be structured in
> a way that it has separate functions to test for each of the possible
> mitigation options one at a time, and pushing the default case into
> spectre_bhb_loop_affected() feels like a bit of a layering violation.
> I think it would work the way you wrote it, but it depends heavily on
> the order functions are called in is_spectre_bhb_affected(), which
> seems counter-intuitive with the way the functions seem to be designed
> as independent checks.
>
> What do you think about an approach like this instead:
>
> - Refactor max_bhb_k in spectre_bhb_loop_affected() to be a global
> instead, which starts out as zero, is updated by
> spectre_bhb_loop_affected(), and is directly read by
> spectre_bhb_patch_loop_iter() (could probably remove the `scope`
> argument from spectre_bhb_loop_affected() then).

Refactoring "max_bhb_k" would be a general cleanup and not related to
anything else here, right?

...but the function is_spectre_bhb_affected() is called from
"cpu_errata.c" and has a scope. Can we guarantee that it's always
"SCOPE_LOCAL_CPU"? I tried reading through the code and it's
_probably_ SCOPE_LOCAL_CPU most of the time, but it doesn't seem worth
it to add an assumption here for a small cleanup.

I'm not going to do this, though I will move "max_bhb_k" to be a
global for the suggestion below.


> - Add a function is_spectre_bhb_safe() that just checks if the MIDR is
> in the new list you're adding
>
> - Add an `if (is_spectre_bhb_safe()) return false;` to the top of
> is_spectre_bhb_affected

That seems reasonable to do and lets me get rid of the "safe" checks
from is_spectre_bhb_fw_affected() and spectre_bhb_loop_affected(), so
it sounds good.


> - Change the `return false` into `return true` at the end of
> is_spectre_bhb_affected (in fact, you can probably take out some of
> the other calls that result in returning true as well then)

I'm not sure you can take out the other calls. Specifically, both
spectre_bhb_loop_affected() and is_spectre_bhb_fw_affected() _need_ to
be called for each CPU so that they update static globals, right?
Maybe we could get rid of the call to supports_clearbhb(), but that
_would_ change things in ways that are not obvious. Specifically I
could believe that someone could have backported "clear BHB" to their
core but their core is otherwise listed as "loop affected". That would
affect "max_bhb_k". Maybe (?) it doesn't matter in this case, but I'd
rather not mess with it unless someone really wants me to and is sure
it's safe.


> - In spectre_bhb_enable_mitigations(), at the end of the long if-else
> chain, put a last else block that prints your WARN_ONCE(), sets the
> max_bhb_k global to 32, and then does the same stuff that the `if
> (spectre_bhb_loop_affected())` block would have installed (maybe
> factoring that out into a helper function called from both cases).

...or just reorder it so that the spectre_bhb_loop_affected() code is
last and it can be the "else". Then I can WARN_ONCE() if
spectre_bhb_loop_affected(). ...or I could just do the WARN_ONCE()
when I get to the end of is_spectre_bhb_affected() and set "max_bhb_k"
to 32 there. I'd actually rather do that so that "max_bhb_k" is
consistently set after is_spectre_bhb_affected() is called on all
cores regardless of whether or not some cores are unknown.


From shimrrashai at gmail.com  Mon Dec 16 13:41:50 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Mon, 16 Dec 2024 15:41:50 -0600
Subject: [PATCH v4 0/2] arm64: dts: rockchip: Add Firefly ITX-3588J Board
Message-ID: <20241216214152.58387-1-shimrrashai@gmail.com>

Draft 4 for the device trees for this board. I hope this one finally
addresses all outstanding style and organization issues. Note that the
technical functionality limitations from the preceding versions remain.

Changes since draft 3:
 * Removed the rockchip-pca9555.h header and used the pin numbers directly
   in the .dts.
 * Removed the display-subsystem node in the .dts. No other board seems to
   have one like the one that was there and it was causing warnings.
 * Removed extraneous property "rk806_dvs1_pwrdn" on the PMIC subnode on
   SPI2.
 * Removed an extraneous property "rockchip,skip-scan-in-resume" on the
   PCIe node pcie2x1l0.

Shimrra

---
Shimrra Shai (2):
  dt-bindings: arm: rockchip: Add Firefly ITX-3588J board
  arm64: dts: rockchip: add DTs for Firefly ITX-3588J and its Core-3588J
    SoM

 .../devicetree/bindings/arm/rockchip.yaml     |   7 +
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../rockchip/rk3588-firefly-core-3588j.dtsi   | 447 +++++++++++
 .../dts/rockchip/rk3588-firefly-itx-3588j.dts | 705 ++++++++++++++++++
 4 files changed, 1160 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts

-- 
2.45.2



From shimrrashai at gmail.com  Mon Dec 16 13:41:51 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Mon, 16 Dec 2024 15:41:51 -0600
Subject: [PATCH v4 1/2] dt-bindings: arm: rockchip: Add Firefly ITX-3588J board
In-Reply-To: <20241216214152.58387-1-shimrrashai@gmail.com>
References: <20241216214152.58387-1-shimrrashai@gmail.com>
Message-ID: <20241216214152.58387-2-shimrrashai@gmail.com>

Document board compatible bindings.

Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 753199a12..fc7ee86e2 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -167,6 +167,13 @@ properties:
           - const: engicam,px30-core
           - const: rockchip,px30
 
+      - description: Firefly Core-3588J-based boards
+        items:
+          - enum:
+              - firefly,itx-3588j
+          - const: firefly,core-3588j
+          - const: rockchip,rk3588
+
       - description: Firefly Core-PX30-JD4 on MB-JD4-PX30 baseboard
         items:
           - const: firefly,px30-jd4-core-mb
-- 
2.45.2



From shimrrashai at gmail.com  Mon Dec 16 13:41:52 2024
From: shimrrashai at gmail.com (Shimrra Shai)
Date: Mon, 16 Dec 2024 15:41:52 -0600
Subject: [PATCH v4 2/2] arm64: dts: rockchip: add DTs for Firefly ITX-3588J and its Core-3588J SoM
In-Reply-To: <20241216214152.58387-1-shimrrashai@gmail.com>
References: <20241216214152.58387-1-shimrrashai@gmail.com>
Message-ID: <20241216214152.58387-3-shimrrashai@gmail.com>

Add the device tree and Makefile update.

Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../rockchip/rk3588-firefly-core-3588j.dtsi   | 447 +++++++++++
 .../dts/rockchip/rk3588-firefly-itx-3588j.dts | 705 ++++++++++++++++++
 3 files changed, 1153 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 86cc418a2..3f2eebd1f 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -137,6 +137,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-wifi.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-firefly-itx-3588j.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-friendlyelec-cm3588-nas.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
new file mode 100644
index 000000000..fb53bf475
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-firefly-core-3588j.dtsi
@@ -0,0 +1,447 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+#include "rk3588.dtsi"
+
+/ {
+	compatible = "firefly,core-3588j", "rockchip,rk3588";
+
+	aliases {
+		mmc0 = &sdhci;
+	};
+};
+
+&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-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-name = "vdd_cpu_big0_s0";
+		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;
+		};
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1m2_xfer>;
+	status = "okay";
+
+	vdd_npu_s0: vdd_npu_mem_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <950000>;
+		regulator-name = "vdd_npu_s0";
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&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-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;
+				};
+			};
+
+			avcc_3v3_s0: pldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "avcc_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>;
+				};
+			};
+
+			avdd_ddr_pll_s0: nldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "avdd_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;
+				};
+			};
+
+			avdd_0v85_s0: nldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "avdd_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;
+				};
+			};
+		};
+	};
+};
+
+/* rk3588 preferred debug out */
+&uart2 {
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts b/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
new file mode 100644
index 000000000..c29814984
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dts
@@ -0,0 +1,705 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "dt-bindings/usb/pd.h"
+
+#include "rk3588-firefly-core-3588j.dtsi"
+
+/ {
+	model = "Firefly ITX-3588J";
+	compatible = "firefly,itx-3588j", "firefly,core-3588j", "rockchip,rk3588";
+
+	aliases {
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
+		mmc0 = &sdhci;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	/*
+	 * there are also a "Reset" and "Mask ROM" button, but the needed
+	 * settings are unknown at this time
+	 */
+	adc-keys-0 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-recovery {
+			label = "Recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <2000>;
+		};
+	};
+
+	analog-sound {
+		compatible = "simple-audio-card";
+		pinctrl-0 = <&hp_detect>;
+		pinctrl-names = "default";
+		simple-audio-card,aux-devs = <&amp_headphones>, <&amp_speaker>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,hp-det-gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>;
+		simple-audio-card,mclk-fs = <384>;
+		simple-audio-card,name = "rockchip_es8323";
+		simple-audio-card,pin-switches = "Headphones", "Speaker";
+		simple-audio-card,routing =
+			"Speaker Amplifier INL", "LOUT2",
+			"Speaker Amplifier INR", "ROUT2",
+			"Speaker", "Speaker Amplifier OUTL",
+			"Speaker", "Speaker Amplifier OUTR",
+			"Headphones Amplifier INL", "LOUT1",
+			"Headphones Amplifier INR", "ROUT1",
+			"Headphones", "Headphones Amplifier OUTL",
+			"Headphones", "Headphones Amplifier OUTR",
+			"LINPUT1", "Microphone Jack",
+			"RINPUT1", "Microphone Jack",
+			"LINPUT2", "Onboard Microphone",
+			"RINPUT2", "Onboard Microphone";
+		simple-audio-card,widgets =
+			"Microphone", "Microphone Jack",
+			"Microphone", "Onboard Microphone",
+			"Headphone", "Headphones",
+			"Speaker", "Speaker";
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s0_8ch>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&es8323>;
+			system-clock-frequency = <12288000>;
+		};
+	};
+
+	/*
+	 * this does not seem to be a proper "amplifier" but is just
+	 * a way to control the GPIO pins to switch on or off the given
+	 * sound output device
+	 */
+	amp_headphones: headphones-audio-amplifier {
+		compatible = "simple-audio-amplifier";
+		enable-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&headphone_amplifier_en>;
+		sound-name-prefix = "Headphones Amplifier";
+	};
+
+	amp_speaker: speaker-audio-amplifier {
+		compatible = "simple-audio-amplifier";
+		enable-gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&speaker_amplifier_en>;
+		sound-name-prefix = "Speaker Amplifier";
+	};
+
+	fan: pwm-fan {
+		compatible = "pwm-fan";
+		#cooling-cells = <2>;
+		cooling-levels = <0 120 150 180 210 240 255>;
+		fan-supply = <&vcc12v_dcin>;
+		pwms = <&pwm15 0 50000 1>;
+	};
+
+	hdmi0-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi0_con_in: endpoint {
+				remote-endpoint = <&hdmi0_out_con>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		/*
+		 * There is also a Power LED control @ RK_PB3 on
+		 * GPIO1 but for some reason it doesn't seem to work right
+		 */
+
+		user_led: led-1 {
+			gpios = <&pca9555 3 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "disk-activity";
+		};
+	};
+
+	pcie30_avdd0v75: pcie30-avdd0v75 {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <750000>;
+		regulator-max-microvolt = <750000>;
+		regulator-name = "pcie30_avdd0v75";
+		vin-supply = <&avdd_0v75_s0>;
+	};
+
+	vbus5v0_typec_pwr_en: regulator-vbus5v0-typec-pwr-en {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 12 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-name = "vbus5v0_typec_pwr_en";
+	};
+
+	vcc12v_dcin: regulator-vcc12v-dcin {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-name = "vcc12v_dcin";
+	};
+
+	vcc3v3_pcie30: regulator-vcc3v3-pcie30 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pcie3_vcc3v3_en>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-name = "vcc3v3_pcie30";
+		startup-delay-us = <5000>;
+		vin-supply = <&vcc12v_dcin>;
+		status = "okay";
+	};
+
+	vcc5v0_host: regulator-vcc5v0-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 5 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-name = "vcc5v0_host";
+		vin-supply = <&vcc5v0_usb>;
+		status = "okay";
+	};
+
+	vcc5v0_host3: regulator-vcc5v0-host3 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 7 GPIO_ACTIVE_HIGH>;
+		regulator-name = "vcc5v0_host3";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_sys: regulator-vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-name = "vcc5v0_sys";
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usb: regulator-vcc5v0-usb {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-name = "vcc5v0_usb";
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		regulator-name = "vcc_1v1_nldo_s3";
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc_fan_pwr_en: regulator-vcc-fan-pwr-en {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 11 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-name = "vcc_fan_pwr_en";
+	};
+
+	vcc_hub_reset: regulator-vcc-hub-reset {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 4 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-name = "vcc_hub_reset";
+	};
+
+	vcc_hub3_reset: regulator-vcc-hub3-reset {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 6 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-name = "vcc_hub3_reset";
+	};
+
+	vcc_sata_pwr_en: regulator-vcc-sata-pwr-en {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&pca9555 10 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-name = "vcc_sata_pwr_en";
+	};
+};
+
+&avcc_1v8_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+	};
+};
+
+&combphy0_ps {
+	status = "okay";
+};
+
+&combphy1_ps {
+	status = "okay";
+};
+
+&combphy2_psu {
+	status = "okay";
+};
+
+&gmac0 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy0>;
+	phy-mode = "rgmii-rxid";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+	tx_delay = <0x45>;
+	rx_delay = <0x4a>;
+	status = "okay";
+};
+
+&gmac1 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii-rxid";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac1_miim
+		     &gmac1_tx_bus2
+		     &gmac1_rx_bus2
+		     &gmac1_rgmii_clk
+		     &gmac1_rgmii_bus>;
+	tx_delay = <0x42>;
+	rx_delay = <0x4f>;
+	status = "okay";
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu_s0>;
+	sram-supply = <&vdd_gpu_mem_s0>;
+	status = "okay";
+};
+
+&hdmi0 {
+	status = "okay";
+};
+
+&hdmi0_in {
+	hdmi0_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi0>;
+	};
+};
+
+&hdmi0_out {
+	hdmi0_out_con: endpoint {
+		remote-endpoint = <&hdmi0_con_in>;
+	};
+};
+
+&hdptxphy_hdmi0 {
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+
+	/*
+	 * in the Firefly BSP source this was confusingly called an
+	 * "ES8388" - it actually seems to be an ES8323 and the drivers
+	 * for that work best
+	 */
+	es8323: audio-codec at 11 {
+		compatible = "everest,es8323";
+		reg = <0x11>;
+		assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+		assigned-clock-rates = <12288000>;
+		clocks = <&cru I2S0_8CH_MCLKOUT>;
+		clock-names = "mclk";
+		#sound-dai-cells = <0>;
+	};
+};
+
+&i2c6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c6m0_xfer>;
+	status = "okay";
+
+	pca9555: gpio at 21 {
+		compatible = "nxp,pca9555";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	usbc0: usb-typec at 22 {
+		compatible = "fcs,fusb302";
+		reg = <0x22>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbc0_int>;
+		vbus-supply = <&vbus5v0_typec_pwr_en>;
+
+		usb_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			op-sink-microwatt = <1000000>;
+			power-role = "dual";
+			sink-pdos =
+				<PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
+			source-pdos =
+				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			try-power-role = "source";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_orien_sw: endpoint {
+						remote-endpoint = <&usbdp_phy0_orientation_switch>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_role_sw: endpoint {
+						remote-endpoint = <&dwc3_0_role_switch>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+
+					dp_altmode_mux: endpoint {
+						remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+					};
+				};
+			};
+		};
+	};
+
+	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_PB0 IRQ_TYPE_LEVEL_LOW>;
+		wakeup-source;
+	};
+};
+
+&i2s0_8ch {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s0_lrck
+		     &i2s0_mclk
+		     &i2s0_sclk
+		     &i2s0_sdi0
+		     &i2s0_sdo0>;
+	status = "okay";
+};
+
+&mdio0 {
+	rgmii_phy0: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+	};
+};
+
+&pcie2x1l0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2_0_rst>;
+	reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&pcie30phy {
+	status = "okay";
+};
+
+&pcie3x4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie3_rst>;
+	reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_pcie30>;
+	status = "okay";
+};
+
+&pinctrl {
+	dp {
+		dp1_hpd: dp1-hpd {
+			 rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	hym8563 {
+		hym8563_int: hym8563-int {
+			rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	gpio-leds {
+		sys_led_pin: sys-led-pin {
+			rockchip,pins =
+				<1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pcie2 {
+		pcie2_0_rst: pcie2-0-rst {
+			rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pcie3 {
+		pcie3_rst: pcie3-rst {
+			rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		pcie3_vcc3v3_en: pcie3-vcc3v3-en {
+			rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sound {
+		hp_detect: hp-detect {
+			rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		headphone_amplifier_en: headphone-amplifier-en {
+			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		speaker_amplifier_en: speaker-amplifier-en {
+			rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		usbc0_int: usbc0-int {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&pwm15 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm15m2_pins>;
+	status = "okay";
+};
+
+&sata0 {
+	status = "okay";
+};
+
+&sata1 {
+	status = "okay";
+};
+
+&sata2 {
+	status = "okay";
+};
+
+/* uart/232/485 */
+&uart0 {
+	pinctrl-0 = <&uart0m2_xfer>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-0 = <&uart1m1_xfer>;
+	status = "okay";
+};
+
+/* usb enable */
+&u2phy0 {
+	status = "okay";
+};
+
+&u2phy0_otg {
+	status = "okay";
+};
+
+&u2phy1 {
+	status = "okay";
+};
+
+&u2phy1_otg {
+	phy-supply = <&vcc5v0_host>;
+	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_host0_xhci {
+	usb-role-switch;
+	dr_mode = "otg";
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dwc3_0_role_switch: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&usbc0_role_sw>;
+		};
+	};
+};
+
+&usb_host1_xhci {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usb_host2_xhci {
+	status = "okay";
+};
+
+&usbdp_phy0 {
+	orientation-switch;
+	sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
+	sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usbdp_phy0_orientation_switch: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&usbc0_orien_sw>;
+		};
+
+		usbdp_phy0_dp_altmode_mux: endpoint at 1 {
+			reg = <1>;
+			remote-endpoint = <&dp_altmode_mux>;
+		};
+	};
+};
+
+&usbdp_phy1 {
+	rockchip,dp-lane-mux = <2 3>;
+	status = "okay";
+};
+
+&vcc_1v8_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+		regulator-suspend-microvolt = <1800000>;
+	};
+};
+
+/* for fan when deep sleep */
+&vdd_log_s0 {
+	regulator-state-mem {
+		regulator-on-in-suspend;
+		regulator-suspend-microvolt = <750000>;
+	};
+};
+
+/* display generator */
+&vop_mmu {
+	status = "okay";
+};
+
+&vop {
+	status = "okay";
+};
+
+&vp0 {
+	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi0_in_vp0>;
+	};
+};
-- 
2.45.2



From tanmay.shah at amd.com  Mon Dec 16 13:42:58 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 16 Dec 2024 13:42:58 -0800
Subject: [PATCH v2] mailbox: zynqmp: setup IPI for each valid child node
Message-ID: <20241216214257.3924162-1-tanmay.shah@amd.com>

As per zynqmp-ipi bindings, zynqmp IPI node can have multiple child nodes.
Current IPI setup function is set only for first child node. If IPI node
has multiple child nodes in the device-tree, then IPI setup fails for
child nodes other than first child node. In such case kernel will crash.
Fix this crash by registering IPI setup function for each available child
node.

Cc: stable at vger.kernel.org
Fixes: 41bcf30100c5 (mailbox: zynqmp: Move buffered IPI setup)
Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
Reviewed-by: Michal Simek <michal.simek at amd.com>
---

Changes in v2:
  - Add Fixes tag

 drivers/mailbox/zynqmp-ipi-mailbox.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index 521d08b9ab47..815e0492f029 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -940,10 +940,10 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
 	pdata->num_mboxes = num_mboxes;
 
 	mbox = pdata->ipi_mboxes;
-	mbox->setup_ipi_fn = ipi_fn;
-
 	for_each_available_child_of_node(np, nc) {
 		mbox->pdata = pdata;
+		mbox->setup_ipi_fn = ipi_fn;
+
 		ret = zynqmp_ipi_mbox_probe(mbox, nc);
 		if (ret) {
 			of_node_put(nc);

base-commit: 28955f4fa2823e39f1ecfb3a37a364563527afbc
-- 
2.34.1



From dianders at chromium.org  Mon Dec 16 13:53:51 2024
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 16 Dec 2024 13:53:51 -0800
Subject: [PATCH 5/6] arm64: errata: Add QCOM_KRYO_5XX_GOLD to the spectre_bhb_k24_list
In-Reply-To: <2qx75syaojhnsqt256li6sinafml4gohohvld6uw3zhejrayuj@biiep5dvko7t>
References: <20241209174430.2904353-1-dianders@chromium.org>
 <20241209094310.5.I41e227ed809ea607114027209b57d02dc0e98384@changeid>
 <l5rqbbxn6hktlcxooolkvi5n3arkht6zzhrvdjf6kis322nsup@5hsrak4cgteq>
 <CAD=FV=WQf+ig21u316WvQh0DoKsdKAmZgqPn5LB-myDXsJtXig@mail.gmail.com>
 <CAODwPW919K+XdxjUe3aPgxsv0CEWwx0P_Hxvf=VniLhk8eagkQ@mail.gmail.com> <2qx75syaojhnsqt256li6sinafml4gohohvld6uw3zhejrayuj@biiep5dvko7t>
Message-ID: <CAD=FV=WQhJcCNhSV7NJkdsuGjV2TVSvepdGisMU4reVUBURAzg@mail.gmail.com>

Hi,

On Sat, Dec 14, 2024 at 3:39?AM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Fri, Dec 13, 2024 at 05:28:55PM -0800, Julius Werner wrote:
> > > Interesting. So the Gold/Prime are actually IDing themselves as
> > > straight Cortex A77. The Silver is IDing itself the same as
> > > KRYO_4XX_SILVER. ...so in that sense there's nothing to do here for
> > > those cores.
> >
> > Should we add some comments to cputype.h to record which other
> > products are matched under the same ID?
>
> I'd say, yes.

Sure. I'll send a v3 with this tomorrow.

-Doug


From broonie at kernel.org  Mon Dec 16 14:09:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 22:09:57 +0000
Subject: [PATCH v2] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
Message-ID: <20241216-arm64-fix-boot-cpu-smidr-v2-1-a99ffba2c37f@kernel.org>

In commit 892f7237b3ff ("arm64: Delay initialisation of
cpuinfo_arm64::reg_{zcr,smcr}") we moved access to ZCR, SMCR and SMIDR
later in the boot process in order to ensure that we don't attempt to
interact with them if SVE or SME is disabled on the command line.
Unfortunately when initialising the boot CPU in init_cpu_features() we work
on a copy of the struct cpuinfo_arm64 for the boot CPU used only during
boot, not the percpu copy used by the sysfs code. The expectation of the
feature identification code was that the ID registers would be read in
__cpuinfo_store_cpu() and the values not modified by init_cpu_features().

The main reason for the original change was to avoid early accesses to
ZCR on practical systems that were seen shipping with SVE reported in ID
registers but traps enabled at EL3 and handled as fatal errors, SME was
rolled in due to the similarity with SVE. Since then we have removed the
early accesses to ZCR and SMCR in commits:

  abef0695f9665c3d ("arm64/sve: Remove ZCR pseudo register from cpufeature code")
  391208485c3ad50f ("arm64/sve: Remove SMCR pseudo register from cpufeature code")

so only the SMIDR_EL1 part of the change remains. Since SMIDR_EL1 is
only trapped via FEAT_IDST and not the SME trap it is less likely to be
affected by similar issues, and the factors that lead to issues with SVE
are less likely to apply to SME.

Since we have not yet seen practical SME systems that need to use a
command line override (and are only just beginning to see SME systems at
all) let's just remove the override and store SMIDR_EL1 along with all
the other ID register reads in __cpuinfo_store_cpu().

This issue wasn't apparent when testing on emulated platforms that do not
report values in SMIDR_EL1.

Fixes: 892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")
Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: stable at vger.kernel.org
---
Changes in v2:
- Move the ID register read back to __cpuinfo_store_cpu().
- Remove the command line option for SME ID register override.
- Link to v1: https://lore.kernel.org/r/20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd at kernel.org
---
 Documentation/admin-guide/kernel-parameters.txt |  3 ---
 arch/arm64/kernel/cpufeature.c                  | 13 -------------
 arch/arm64/kernel/cpuinfo.c                     | 10 ++++++++++
 arch/arm64/kernel/pi/idreg-override.c           | 16 ----------------
 4 files changed, 10 insertions(+), 32 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index dc663c0ca67067d041cf9a3767117eec765ccca8..d29dee978e933245e0db0f654f17eef3e414bb64 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -458,9 +458,6 @@
 	arm64.nopauth	[ARM64] Unconditionally disable Pointer Authentication
 			support
 
-	arm64.nosme	[ARM64] Unconditionally disable Scalable Matrix
-			Extension support
-
 	arm64.nosve	[ARM64] Unconditionally disable Scalable Vector
 			Extension support
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed84f9056196bb21bbfac61c9687e30..818aca922ca6066eb4bdf79e153cccb24246c61b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1167,12 +1167,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
 		unsigned long cpacr = cpacr_save_enable_kernel_sme();
 
-		/*
-		 * We mask out SMPS since even if the hardware
-		 * supports priorities the kernel does not at present
-		 * and we block access to them.
-		 */
-		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
 		vec_init_vq_map(ARM64_VEC_SME);
 
 		cpacr_restore(cpacr);
@@ -1423,13 +1417,6 @@ void update_cpu_features(int cpu,
 	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
 		unsigned long cpacr = cpacr_save_enable_kernel_sme();
 
-		/*
-		 * We mask out SMPS since even if the hardware
-		 * supports priorities the kernel does not at present
-		 * and we block access to them.
-		 */
-		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
-
 		/* Probe vector lengths */
 		if (!system_capabilities_finalized())
 			vec_update_vq_map(ARM64_VEC_SME);
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index d79e88fccdfce427507e7a34c5959ce6309cbd12..c45633b5ae233fe78607fce3d623efb28a9f341a 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -482,6 +482,16 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
 		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+		/*
+		 * We mask out SMPS since even if the hardware
+		 * supports priorities the kernel does not at present
+		 * and we block access to them.
+		 */
+		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
+	}
+
 	cpuinfo_detect_icache_policy(info);
 }
 
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index 22159251eb3a6a5efea90ebda2910ebcfff52b8f..15dca48332c9b83b55752e474854d8fc45b0989b 100644
--- a/arch/arm64/kernel/pi/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -122,21 +122,6 @@ static const struct ftr_set_desc pfr0 __prel64_initconst = {
 	},
 };
 
-static bool __init pfr1_sme_filter(u64 val)
-{
-	/*
-	 * Similarly to SVE, disabling SME also means disabling all
-	 * the features that are associated with it. Just set
-	 * id_aa64smfr0_el1 to 0 and don't look back.
-	 */
-	if (!val) {
-		id_aa64smfr0_override.val = 0;
-		id_aa64smfr0_override.mask = GENMASK(63, 0);
-	}
-
-	return true;
-}
-
 static const struct ftr_set_desc pfr1 __prel64_initconst = {
 	.name		= "id_aa64pfr1",
 	.override	= &id_aa64pfr1_override,
@@ -144,7 +129,6 @@ static const struct ftr_set_desc pfr1 __prel64_initconst = {
 		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),
 		{}
 	},
 };

---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241213-arm64-fix-boot-cpu-smidr-386b8db292b2

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Mon Dec 16 14:11:22 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Dec 2024 22:11:22 +0000
Subject: [PATCH V2 12/46] arm64/sysreg: Add register fields for
 TRBMPAM_EL1
In-Reply-To: <20241210055311.780688-13-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-13-anshuman.khandual@arm.com>
Message-ID: <01ca449e-b34d-4833-941a-4aaeb197b28c@sirena.org.uk>

On Tue, Dec 10, 2024 at 11:22:37AM +0530, Anshuman Khandual wrote:
> This adds register fields for TRBMPAM_EL1 as per the definitions based
> on DDI0601 2024-09.

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/20241216/cdf46ae3/attachment.sig>

From beata.michalska at arm.com  Mon Dec 16 14:15:13 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Mon, 16 Dec 2024 23:15:13 +0100
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <20241212065100.sjb7lrlmksbm2hdk@vireshk-i7>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
 <20241212065100.sjb7lrlmksbm2hdk@vireshk-i7>
Message-ID: <Z2CmcelSy89NULtz@arm.com>

On Thu, Dec 12, 2024 at 12:21:00PM +0530, Viresh Kumar wrote:
> On 06-12-24, 13:55, Beata Michalska wrote:
> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > index 04fc786dd2c0..70df2a24437b 100644
> > --- a/drivers/cpufreq/cpufreq.c
> > +++ b/drivers/cpufreq/cpufreq.c
> > @@ -747,9 +747,14 @@ show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
> >  show_one(scaling_min_freq, min);
> >  show_one(scaling_max_freq, max);
> >  
> > -__weak unsigned int arch_freq_get_on_cpu(int cpu)
> > +__weak int arch_freq_get_on_cpu(int cpu)
> >  {
> > -	return 0;
> > +	return -EOPNOTSUPP;
> 
> I did suggest not doing this as it may not be acceptable.
> 
> https://lore.kernel.org/all/CAKohpokFUpQyHYO017kOn-Jbt0CFZ1GuxoG3N-fenWJ_poW=4Q at mail.gmail.com/
>
My bad as I must have misinterpreted that message. Although I am not entirely
sure why this might be unacceptable as it is not such uncommon approach to use
signed int space to cover both: expected positive value as well as potential
error code case failure.
Enabling the new attribute for all is an option, tough not entirely compelling
one as exposing a feature that is known not to be supported seems bit
counterintuitive. On the other hand using cpufreq driver flags won't help much
as the support for the new attrib is platform-specific, not driver-specific.

---
BR
Beata
> -- 
> viresh


From beata.michalska at arm.com  Mon Dec 16 14:21:21 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Mon, 16 Dec 2024 23:21:21 +0100
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <3f19c5a8-9ee6-42fe-8b4c-3a66c65c8d35@nvidia.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
 <3f19c5a8-9ee6-42fe-8b4c-3a66c65c8d35@nvidia.com>
Message-ID: <Z2Cn4YQjw9-4m55c@arm.com>

On Mon, Dec 16, 2024 at 01:43:02PM +0800, Kai-Heng Feng wrote:
> Hi Beata,
> 
> On 2024/12/6 9:55 PM, Beata Michalska wrote:
> > Currently the CPUFreq core exposes two sysfs attributes that can be used
> > to query current frequency of a given CPU(s): namely cpuinfo_cur_freq
> > and scaling_cur_freq. Both provide slightly different view on the
> > subject and they do come with their own drawbacks.
> > 
> > cpuinfo_cur_freq provides higher precision though at a cost of being
> > rather expensive. Moreover, the information retrieved via this attribute
> > is somewhat short lived as frequency can change at any point of time
> > making it difficult to reason from.
> > 
> > scaling_cur_freq, on the other hand, tends to be less accurate but then
> > the actual level of precision (and source of information) varies between
> > architectures making it a bit ambiguous.
> > 
> > The new attribute, cpuinfo_avg_freq, is intended to provide more stable,
> > distinct interface, exposing an average frequency of a given CPU(s), as
> > reported by the hardware, over a time frame spanning no more than a few
> > milliseconds. As it requires appropriate hardware support, this
> > interface is optional.
> > 
> > Note that under the hood, the new attribute relies on the information
> > provided by arch_freq_get_on_cpu, which, up to this point, has been
> > feeding data for scaling_cur_freq attribute, being the source of
> > ambiguity when it comes to interpretation. This has been amended by
> > restoring the intended behavior for scaling_cur_freq, with a new
> > dedicated config option to maintain status quo for those, who may need
> > it.
> > 
> > CC: Jonathan Corbet <corbet at lwn.net>
> > CC: Thomas Gleixner <tglx at linutronix.de>
> > CC: Ingo Molnar <mingo at redhat.com>
> > CC: Borislav Petkov <bp at alien8.de>
> > CC: Dave Hansen <dave.hansen at linux.intel.com>
> > CC: H. Peter Anvin <hpa at zytor.com>
> > CC: Phil Auld <pauld at redhat.com>
> > CC: x86 at kernel.org
> > CC: linux-doc at vger.kernel.org
> > Signed-off-by: Beata Michalska <beata.michalska at arm.com>
> > ---
> >   Documentation/admin-guide/pm/cpufreq.rst | 16 ++++++++++-
> >   arch/x86/kernel/cpu/aperfmperf.c         |  2 +-
> >   arch/x86/kernel/cpu/proc.c               |  7 +++--
> >   drivers/cpufreq/Kconfig.x86              | 12 ++++++++
> >   drivers/cpufreq/cpufreq.c                | 36 +++++++++++++++++++++---
> >   include/linux/cpufreq.h                  |  2 +-
> >   6 files changed, 66 insertions(+), 9 deletions(-)
> > 
> > diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst
> > index fe1be4ad88cb..76f3835afe01 100644
> > --- a/Documentation/admin-guide/pm/cpufreq.rst
> > +++ b/Documentation/admin-guide/pm/cpufreq.rst
> > @@ -248,6 +248,19 @@ are the following:
> >   	If that frequency cannot be determined, this attribute should not
> >   	be present.
> > +``cpuinfo_avg_freq``
> > +        An average frequency (in KHz) of all CPUs belonging to a given policy,
> > +        derived from a hardware provided feedback and reported on a time frame
> > +        spanning at most few milliseconds.
> > +
> > +        This is expected to be based on the frequency the hardware actually runs
> > +        at and, as such, might require specialised hardware support (such as AMU
> > +        extension on ARM). If one cannot be determined, this attribute should
> > +        not be present.
> > +
> > +        Note, that failed attempt to retrieve current frequency for a given
> > +        CPU(s) will result in an appropriate error.
> > +
> >   ``cpuinfo_max_freq``
> >   	Maximum possible operating frequency the CPUs belonging to this policy
> >   	can run at (in kHz).
> > @@ -293,7 +306,8 @@ are the following:
> >   	Some architectures (e.g. ``x86``) may attempt to provide information
> >   	more precisely reflecting the current CPU frequency through this
> >   	attribute, but that still may not be the exact current CPU frequency as
> > -	seen by the hardware at the moment.
> > +	seen by the hardware at the moment. This behavior though, is only
> > +	available via c:macro:``CPUFREQ_ARCH_CUR_FREQ`` option.
> >   ``scaling_driver``
> >   	The scaling driver currently in use.
> > diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
> > index 0b69bfbf345d..a00059139ca4 100644
> > --- a/arch/x86/kernel/cpu/aperfmperf.c
> > +++ b/arch/x86/kernel/cpu/aperfmperf.c
> > @@ -413,7 +413,7 @@ void arch_scale_freq_tick(void)
> >    */
> >   #define MAX_SAMPLE_AGE	((unsigned long)HZ / 50)
> > -unsigned int arch_freq_get_on_cpu(int cpu)
> > +int arch_freq_get_on_cpu(int cpu)
> >   {
> >   	struct aperfmperf *s = per_cpu_ptr(&cpu_samples, cpu);
> >   	unsigned int seq, freq;
> > diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
> > index e65fae63660e..34d8fb93fb70 100644
> > --- a/arch/x86/kernel/cpu/proc.c
> > +++ b/arch/x86/kernel/cpu/proc.c
> > @@ -86,9 +86,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
> >   		seq_printf(m, "microcode\t: 0x%x\n", c->microcode);
> >   	if (cpu_has(c, X86_FEATURE_TSC)) {
> > -		unsigned int freq = arch_freq_get_on_cpu(cpu);
> > +		int freq = arch_freq_get_on_cpu(cpu);
> > -		seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 1000));
> > +		if (freq <= 0)
> > +			seq_puts(m, "cpu MHz\t\t: Unknown\n");
> > +		else
> > +			seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 1000));
> >   	}
> >   	/* Cache size */
> > diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
> > index 97c2d4f15d76..212e1b9afe21 100644
> > --- a/drivers/cpufreq/Kconfig.x86
> > +++ b/drivers/cpufreq/Kconfig.x86
> > @@ -340,3 +340,15 @@ config X86_SPEEDSTEP_RELAXED_CAP_CHECK
> >   	  option lets the probing code bypass some of those checks if the
> >   	  parameter "relaxed_check=1" is passed to the module.
> > +config CPUFREQ_ARCH_CUR_FREQ
> > +	default y
> > +	bool "Current frequency derived from HW provided feedback"
> > +	help
> > +	  This determines whether the scaling_cur_freq sysfs attribute returns
> > +	  the last requested frequency or a more precise value based on hardware
> > +	  provided feedback (as architected counters).
> > +	  Given that a more precise frequency can now be provided via the
> > +	  cpuinfo_avg_cur_freq attribute, by enabling this option,
> > +	  scaling_cur_freq maintains the provision of a counter based frequency,
> > +	  for compatibility reasons.
> > +
> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > index 04fc786dd2c0..70df2a24437b 100644
> > --- a/drivers/cpufreq/cpufreq.c
> > +++ b/drivers/cpufreq/cpufreq.c
> > @@ -747,9 +747,14 @@ show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
> >   show_one(scaling_min_freq, min);
> >   show_one(scaling_max_freq, max);
> > -__weak unsigned int arch_freq_get_on_cpu(int cpu)
> > +__weak int arch_freq_get_on_cpu(int cpu)
> >   {
> > -	return 0;
> > +	return -EOPNOTSUPP;
> > +}
> > +
> > +static inline bool cpufreq_avg_freq_supported(struct cpufreq_policy *policy)
> > +{
> > +	return arch_freq_get_on_cpu(policy->cpu) != -EOPNOTSUPP;
> >   }
> >   static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
> > @@ -757,8 +762,11 @@ static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
> >   	ssize_t ret;
> >   	unsigned int freq;
> > -	freq = arch_freq_get_on_cpu(policy->cpu);
> > -	if (freq)
> > +	freq = IS_ENABLED(CONFIG_CPUFREQ_ARCH_CUR_FREQ)
> > +		? arch_freq_get_on_cpu(policy->cpu)
> > +		: 0;
> > +
> > +	if (freq > 0)
> >   		ret = sysfs_emit(buf, "%u\n", freq);
> >   	else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
> >   		ret = sysfs_emit(buf, "%u\n", cpufreq_driver->get(policy->cpu));
> > @@ -802,6 +810,19 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
> >   	return sysfs_emit(buf, "<unknown>\n");
> >   }
> > +/*
> > + * show_cpuinfo_avg_freq - average CPU frequency as detected by hardware
> > + */
> > +static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
> > +				     char *buf)
> > +{
> > +	int avg_freq = arch_freq_get_on_cpu(policy->cpu);
> 
> We are seeing issues when reading cpuinfo_avg_freq on an ARM64 system:
> 
> $ cat /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq
> cat: /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq: Resource
> temporarily unavailable
> 
> The CPU is in idle state, so arch_freq_get_on_cpu() can't find a good
> alternative source for frequency info.
> 
> One way to resolve this is to have fallback methods in
> show_cpuinfo_avg_freq() so it will look like this:
> 
> static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
>                                      char *buf)
> {
>         int avg_freq = arch_freq_get_on_cpu(policy->cpu);
>         int ret;
> 
>         if (avg_freq > 0)
>                 ret = sysfs_emit(buf, "%u\n", avg_freq);
>         else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
>                 ret = sysfs_emit(buf, "%u\n", cpufreq_driver->get(policy->cpu));
>         else
>                 ret = sysfs_emit(buf, "%u\n", policy->cur);
>         return ret;
> }
> 
> But that also makes show_cpuinfo_avg_freq() pretty much the same as
> show_scaling_cur_freq().
> 
> So is it possible to consolidate show_cpuinfo_avg_freq() into
> show_scaling_cur_freq(), by making CONFIG_CPUFREQ_ARCH_CUR_FREQ also
> available to ARM64?
>
The whole idea of this patch was to add support for retrieving the average
frequency withouth modifying expected bahaviour of the scaling_cur_freq handler.
The proposed config option is there to keep backward compatibility and allow
userspace tools to catch up with the change - I'd expect that option to be
either set as default to No or droped at some point.

---
BR
Beata
> Kai-Heng
> 
> > +
> > +	if (avg_freq > 0)
> > +		return sysfs_emit(buf, "%u\n", avg_freq);
> > +	return avg_freq != 0 ? avg_freq : -EINVAL;
> > +}
> > +
> >   /*
> >    * show_scaling_governor - show the current policy for the specified CPU
> >    */
> > @@ -964,6 +985,7 @@ static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
> >   }
> >   cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
> > +cpufreq_freq_attr_ro(cpuinfo_avg_freq);
> >   cpufreq_freq_attr_ro(cpuinfo_min_freq);
> >   cpufreq_freq_attr_ro(cpuinfo_max_freq);
> >   cpufreq_freq_attr_ro(cpuinfo_transition_latency);
> > @@ -1091,6 +1113,12 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy)
> >   			return ret;
> >   	}
> > +	if (cpufreq_avg_freq_supported(policy)) {
> > +		ret = sysfs_create_file(&policy->kobj, &cpuinfo_avg_freq.attr);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >   	ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
> >   	if (ret)
> >   		return ret;
> > diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> > index d4d2f4d1d7cb..a7b6c0ccf9bc 100644
> > --- a/include/linux/cpufreq.h
> > +++ b/include/linux/cpufreq.h
> > @@ -1194,7 +1194,7 @@ static inline int of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_
> >   }
> >   #endif
> > -extern unsigned int arch_freq_get_on_cpu(int cpu);
> > +extern int arch_freq_get_on_cpu(int cpu);
> >   #ifndef arch_set_freq_scale
> >   static __always_inline
> 


From ja at ssi.bg  Mon Dec 16 14:18:05 2024
From: ja at ssi.bg (Julian Anastasov)
Date: Tue, 17 Dec 2024 00:18:05 +0200 (EET)
Subject: [PATCH net-next] Fix clamp() of ip_vs_conn_tab on small memory
 systems.
In-Reply-To: <24a6bfd0811b4931b6ef40098b33c9ee@AcuMS.aculab.com>
References: <24a6bfd0811b4931b6ef40098b33c9ee@AcuMS.aculab.com>
Message-ID: <5e288aa5-5374-5542-b730-f3b923ba5a36@ssi.bg>


	Hello,

On Sat, 14 Dec 2024, David Laight wrote:

> The 'max_avail' value is calculated from the system memory
> size using order_base_2().
> order_base_2(x) is defined as '(x) ? fn(x) : 0'.
> The compiler generates two copies of the code that follows
> and then expands clamp(max, min, PAGE_SHIFT - 12) (11 on 32bit).
> This triggers a compile-time assert since min is 5.

	8 ?

> 
> In reality a system would have to have less than 512MB memory
> for the bounds passed to clamp to be reversed.
> 
> Swap the order of the arguments to clamp() to avoid the warning.
> 
> Replace the clamp_val() on the line below with clamp().
> clamp_val() is just 'an accident waiting to happen' and not needed here.
> 
> Detected by compile time checks added to clamp(), specifically:
> minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
> 
> Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>
> Closes: https://lore.kernel.org/all/CA+G9fYsT34UkGFKxus63H6UVpYi5GRZkezT9MRLfAbM3f6ke0g at mail.gmail.com/
> Fixes: 4f325e26277b ("ipvs: dynamically limit the connection hash table")
> Tested-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> Signed-off-by: David Laight <david.laight at aculab.com>

	Looks good to me, thanks to everyone!

Acked-by: Julian Anastasov <ja at ssi.bg>

	Pablo, Simon, probably, this should be applied
to the 'nf' tree as it fixes a build failure...

> ---
> 
> Julian seems to be waiting for a 'v2' from me.
> Changed target tree to 'net-next'.
> I've re-written the commit message.
> Copied Andrew Morton - he might want to take the change through the 'mm' tree.
> Plausibly the 'fixes' tag should refer to the minmax.h change?
> This will need back-porting if the minmax set get back-ported.
> 
> I'm not sure whether there ought to be an attribution to Dan Carpenter <dan.carpenter at linaro.org>
> 
>  net/netfilter/ipvs/ip_vs_conn.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
> index 98d7dbe3d787..c0289f83f96d 100644
> --- a/net/netfilter/ipvs/ip_vs_conn.c
> +++ b/net/netfilter/ipvs/ip_vs_conn.c
> @@ -1495,8 +1495,8 @@ int __init ip_vs_conn_init(void)
>  	max_avail -= 2;		/* ~4 in hash row */
>  	max_avail -= 1;		/* IPVS up to 1/2 of mem */
>  	max_avail -= order_base_2(sizeof(struct ip_vs_conn));
> -	max = clamp(max, min, max_avail);
> -	ip_vs_conn_tab_bits = clamp_val(ip_vs_conn_tab_bits, min, max);
> +	max = clamp(max_avail, min, max);
> +	ip_vs_conn_tab_bits = clamp(ip_vs_conn_tab_bits, min, max);
>  	ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
>  	ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
>  
> -- 
> 2.17.1

Regards

--
Julian Anastasov <ja at ssi.bg>



From ninad at linux.ibm.com  Mon Dec 16 14:27:35 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 16:27:35 -0600
Subject: [PATCH v2 0/4] Add support for Intel CRPS PSU
In-Reply-To: <c64bb634-46d4-486a-8743-699775326058@roeck-us.net>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
 <c64bb634-46d4-486a-8743-699775326058@roeck-us.net>
Message-ID: <d75e72a8-6bd5-4929-a8bb-e1b13fd7d3b8@linux.ibm.com>

Hi Guenter,

Thanks for the review.

On 12/16/24 12:48, Guenter Roeck wrote:
> On 12/16/24 09:50, Ninad Palsule wrote:
>> Hello,
>>
>> Please review the patchset for Intel CRPS185 driver.
>> V2:
>> ---
>> ?? - Incorporated review comments by Guenter Roeck
>> ?? - Incorporated review comments by Krzysztof Kozlowski
>>
>
> That is not a useful change log. Please describe what you changed, not 
> who
> asked for it.
>
> Guenter
>
ok, I will improve it in version 3.

Regards,

Ninad

>> Ninad Palsule (4):
>> ?? hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
>> ?? hwmon: (pmbus/crps) Add Intel CRPS185 power supply
>> ?? dt-bindings: hwmon: intel,crps185: Add to trivial
>> ?? ARM: dts: aspeed: system1: Use crps PSU driver
>>
>> ? .../devicetree/bindings/trivial-devices.yaml? |? 2 +
>> ? Documentation/hwmon/crps.rst????????????????? | 97 +++++++++++++++++++
>> ? Documentation/hwmon/index.rst???????????????? |? 1 +
>> ? MAINTAINERS?????????????????????????????????? |? 7 ++
>> ? .../dts/aspeed/aspeed-bmc-ibm-system1.dts???? |? 8 +-
>> ? drivers/hwmon/pmbus/Kconfig?????????????????? |? 9 ++
>> ? drivers/hwmon/pmbus/Makefile????????????????? |? 1 +
>> ? drivers/hwmon/pmbus/crps.c??????????????????? | 79 +++++++++++++++
>> ? drivers/hwmon/pmbus/pmbus_core.c????????????? | 13 ++-
>> ? 9 files changed, 211 insertions(+), 6 deletions(-)
>> ? create mode 100644 Documentation/hwmon/crps.rst
>> ? create mode 100644 drivers/hwmon/pmbus/crps.c
>>
>
>


From ninad at linux.ibm.com  Mon Dec 16 14:28:18 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 16:28:18 -0600
Subject: [PATCH v2 3/4] dt-bindings: hwmon: intel,crps185: Add to trivial
In-Reply-To: <a010366e-b911-43bd-8445-e893e11fa51a@roeck-us.net>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
 <20241216175044.4144442-4-ninad@linux.ibm.com>
 <a010366e-b911-43bd-8445-e893e11fa51a@roeck-us.net>
Message-ID: <ff077ea7-80dd-4cdf-8c08-f2eb7104f213@linux.ibm.com>

Hi Guenter,

Thanks for the review.

On 12/16/24 12:47, Guenter Roeck wrote:
> On 12/16/24 09:50, Ninad Palsule wrote:
>> Add INTEL Common Redundant Power Supply Versions crps185 bindings as
>> trivial. It is trivial because only compatibility string is required in
>> the device tree to load this driver.
>>
>> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
>
> Krzysztof had Acked this patch. I don't immediately see why you 
> dropped it.
> Am I missing something ?
>
> Guenter
>
I think that was my mistake. Adding it in version 3.


>> ---
>> ? Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
>> ? 1 file changed, 2 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml 
>> b/Documentation/devicetree/bindings/trivial-devices.yaml
>> index 73a49d50c4ef..7d07b08b1459 100644
>> --- a/Documentation/devicetree/bindings/trivial-devices.yaml
>> +++ b/Documentation/devicetree/bindings/trivial-devices.yaml
>> @@ -151,6 +151,8 @@ properties:
>> ??????????? - injoinic,ip5306
>> ????????????? # Inspur Power System power supply unit version 1
>> ??????????? - inspur,ipsps1
>> +??????????? # Intel common redudant power supply crps185
>> +????????? - intel,crps185
>> ????????????? # Intersil ISL29028 Ambient Light and Proximity Sensor
>> ??????????? - isil,isl29028
>> ????????????? # Intersil ISL29030 Ambient Light and Proximity Sensor
>
>


From ninad at linux.ibm.com  Mon Dec 16 14:30:28 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 16:30:28 -0600
Subject: [PATCH v2 2/4] hwmon: (pmbus/crps) Add Intel CRPS185 power supply
In-Reply-To: <68f5d2e1-10e8-4441-9338-e2a385a9c2b1@roeck-us.net>
References: <20241216175044.4144442-1-ninad@linux.ibm.com>
 <20241216175044.4144442-3-ninad@linux.ibm.com>
 <68f5d2e1-10e8-4441-9338-e2a385a9c2b1@roeck-us.net>
Message-ID: <25235d06-6f2a-427a-aead-437a8a7deb0d@linux.ibm.com>

Hi Guenter,

Thanks for the review.

On 12/16/24 12:26, Guenter Roeck wrote:
> On 12/16/24 09:50, Ninad Palsule wrote:
>> Add the driver to monitor Intel common redundant power supply (crps185)
>> with hwmon over pmbus.
>>
>> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
>> ---
>> ? Documentation/hwmon/crps.rst? | 97 +++++++++++++++++++++++++++++++++++
>> ? Documentation/hwmon/index.rst |? 1 +
>> ? MAINTAINERS?????????????????? |? 7 +++
>> ? drivers/hwmon/pmbus/Kconfig?? |? 9 ++++
>> ? drivers/hwmon/pmbus/Makefile? |? 1 +
>> ? drivers/hwmon/pmbus/crps.c??? | 79 ++++++++++++++++++++++++++++
>> ? 6 files changed, 194 insertions(+)
>> ? create mode 100644 Documentation/hwmon/crps.rst
>> ? create mode 100644 drivers/hwmon/pmbus/crps.c
>>
>> diff --git a/Documentation/hwmon/crps.rst b/Documentation/hwmon/crps.rst
>> new file mode 100644
>> index 000000000000..74570ed1e978
>> --- /dev/null
>> +++ b/Documentation/hwmon/crps.rst
>> @@ -0,0 +1,97 @@
>> +.. SPDX-License-Identifier: GPL-2.0-or-later
>> +
>> +Kernel driver crps
>> +==================
>> +
>> +Supported chips:
>> +
>> +? * Intel CRPS185
>> +
>> +??? Prefix: 'crps185'
>> +
>> +??? Addresses scanned: -
>> +
>> +??? Datasheet: Publicly not available.
>
> Maybe "Only available under NDA". Or at least that is what I found.
Updated as per your suggestion.
>
>> +
>> +Authors:
>> +??? Ninad Palsule <ninad at linux.ibm.com>
>> +
>> +
>> +Description
>> +-----------
>> +
>> +This driver implements support for Intel Common Redundant Power 
>> supply with
>> +PMBus support.
>> +
>> +The driver is a client driver to the core PMBus driver.
>> +Please see Documentation/hwmon/pmbus.rst for details on PMBus client 
>> drivers.
>> +
>> +
>> +Usage Notes
>> +-----------
>> +
>> +This driver does not auto-detect devices. You will have to 
>> instantiate the
>> +devices explicitly. Please see 
>> Documentation/i2c/instantiating-devices.rst for
>> +details.
>> +
>> +
>> +Sysfs entries
>> +-------------
>> +
>> +======================= 
>> ======================================================
>> +curr1_label??????? "iin"
>> +curr1_input??????? Measured input current
>> +curr1_max??????? Maximum input current
>> +curr1_max_alarm???????? Input maximum current high alarm
>> +curr1_crit????????????? Critial high input current
>> +curr1_crit_alarm??????? Input critical current high alarm
>> +curr1_rated_max??????? Maximum rated input current
>> +
>> +curr2_label??????? "iout1"
>> +curr2_input??????? Measured output current
>> +curr2_max??????? Maximum output current
>> +curr2_max_alarm???????? Output maximum current high alarm
>> +curr2_crit??????????? Critial high output current
>> +curr2_crit_alarm??????? Output critical current high alarm
>> +curr2_rated_max??????? Maximum rated output current
>> +
>> +in1_label??????? "vin"
>> +in1_input??????? Measured input voltage
>> +in1_crit??????????????? Critical input over voltage
>> +in1_crit_alarm????????? Critical input over voltage alarm
>> +in1_max???????????????? Maximum input over voltage
>> +in1_max_alarm?????????? Maximum input over voltage alarm
>> +in1_rated_min??????? Minimum rated input voltage
>> +in1_rated_max??????? Maximum rated input voltage
>> +
>> +in2_label??????? "vout1"
>> +in2_input??????? Measured input voltage
>> +in2_crit??????????????? Critical input over voltage
>> +in2_crit_alarm????????? Critical input over voltage alarm
>> +in2_lcrit?????????????? Critical input under voltage fault
>> +in2_lcrit_alarm???????? Critical input under voltage fault alarm
>> +in2_max???????????????? Maximum input over voltage
>> +in2_max_alarm?????????? Maximum input over voltage alarm
>> +in2_min???????????????? Minimum input under voltage warning
>> +in2_min_alarm?????????? Minimum input under voltage warning alarm
>> +in2_rated_min??????? Minimum rated input voltage
>> +in2_rated_max??????? Maximum rated input voltage
>> +
>> +power1_label??????? "pin"
>> +power1_input??????? Measured input power
>> +power1_alarm??????? Input power high alarm
>> +power1_max????????? Maximum input power
>> +power1_rated_max??????? Maximum rated input power
>> +
>> +temp[1-2]_input??????? Measured temperature
>> +temp[1-2]_crit???????? Critical temperature
>> +temp[1-2]_crit_alarm??? Critical temperature alarm
>> +temp[1-2]_max????????? Maximum temperature
>> +temp[1-2]_max_alarm???? Maximum temperature alarm
>> +temp[1-2]_rated_max???? Maximum rated temperature
>> +
>> +fan1_alarm??????? Fan 1 warning.
>> +fan1_fault??????? Fan 1 fault.
>> +fan1_input??????? Fan 1 speed in RPM.
>> +fan1_target???????????? Fan 1 target.
>> +======================= 
>> ======================================================
>
> Does this pass "make htmldocs" ?

Yes, I don't get any error. I run following command on the top level 
directory.

export ARCH=arm;export CROSS_COMPILE="arm-linux-gnueabi-";make htmldocs

>
>
>> diff --git a/Documentation/hwmon/index.rst 
>> b/Documentation/hwmon/index.rst
>> index 1a3cb0a59f72..b1ea445479b0 100644
>> --- a/Documentation/hwmon/index.rst
>> +++ b/Documentation/hwmon/index.rst
>> @@ -58,6 +58,7 @@ Hardware Monitoring Kernel Drivers
>> ???? corsair-cpro
>> ???? corsair-psu
>> ???? cros_ec_hwmon
>> +?? crps
>> ???? da9052
>> ???? da9055
>> ???? dell-smm-hwmon
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 637ddd44245f..e99f26f75733 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -6100,6 +6100,13 @@ L:??? linux-input at vger.kernel.org
>> ? S:??? Maintained
>> ? F:??? drivers/hid/hid-creative-sb0540.c
>> ? +INTEL CRPS COMMON REDUNDANT PSU DRIVER
>> +M:??? Ninad Palsule <ninad at linux.ibm.com>
>> +L:??? linux-hwmon at vger.kernel.org
>> +S:??? Maintained
>> +F:??? Documentation/hwmon/crps.rst
>> +F:??? drivers/hwmon/pmbus/crps.c
>> +
>> ? CRYPTO API
>> ? M:??? Herbert Xu <herbert at gondor.apana.org.au>
>> ? M:??? "David S. Miller" <davem at davemloft.net>
>> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
>> index 22418a05ced0..43b6df04e0f9 100644
>> --- a/drivers/hwmon/pmbus/Kconfig
>> +++ b/drivers/hwmon/pmbus/Kconfig
>> @@ -85,6 +85,15 @@ config SENSORS_BPA_RS600
>> ??????? This driver can also be built as a module. If so, the module 
>> will
>> ??????? be called bpa-rs600.
>> ? +config SENSORS_CRPS
>> +??? tristate "Intel Common Redundant Power Supply"
>> +??? help
>> +????? If you say yes here you get hardware monitoring support for 
>> the Intel
>> +????? Common Redundant Power Supply.
>> +
>> +????? This driver can also be built as a module. If so, the module will
>> +????? be called crps.
>> +
>> ? config SENSORS_DELTA_AHE50DC_FAN
>> ????? tristate "Delta AHE-50DC fan control module"
>> ????? help
>> diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
>> index 3d3183f8d2a7..c7eb7739b7f8 100644
>> --- a/drivers/hwmon/pmbus/Makefile
>> +++ b/drivers/hwmon/pmbus/Makefile
>> @@ -62,3 +62,4 @@ obj-$(CONFIG_SENSORS_XDPE122)??? += xdpe12284.o
>> ? obj-$(CONFIG_SENSORS_XDPE152)??? += xdpe152c4.o
>> ? obj-$(CONFIG_SENSORS_ZL6100)??? += zl6100.o
>> ? obj-$(CONFIG_SENSORS_PIM4328)??? += pim4328.o
>> +obj-$(CONFIG_SENSORS_CRPS)??? += crps.o
>> diff --git a/drivers/hwmon/pmbus/crps.c b/drivers/hwmon/pmbus/crps.c
>> new file mode 100644
>> index 000000000000..09425c404fc8
>> --- /dev/null
>> +++ b/drivers/hwmon/pmbus/crps.c
>> @@ -0,0 +1,79 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright 2024 IBM Corp.
>> + */
>> +
>> +#include <linux/i2c.h>
>> +#include <linux/of.h>
>> +#include <linux/pmbus.h>
>> +
>> +#include "pmbus.h"
>> +
>> +static const struct i2c_device_id crps_id[] = {
>> +??? { "intel_crps185" },
>> +??? {}
>> +};
>> +MODULE_DEVICE_TABLE(i2c, crps_id);
>> +
>> +static struct pmbus_driver_info crps_info = {
>> +??? .pages = 1,
>> +??? /* PSU uses default linear data format. */
>> +??? .func[0] = PMBUS_HAVE_PIN | PMBUS_HAVE_IOUT |
>> +??????? PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_IIN |
>> +??????? PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
>> +??????? PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
>> +??????? PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
>> +??????? PMBUS_HAVE_STATUS_TEMP |
>> +??????? PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
>> +};
>> +
>> +static int crps_probe(struct i2c_client *client)
>> +{
>> +??? int rc;
>> +??? struct device *dev = &client->dev;
>> +??? char buf[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
>> +
>> +??? rc = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
>> +??? if (rc < 0) {
>> +??????? dev_err_probe(dev, rc, "Failed to read PMBUS_MFR_MODEL\n");
>> +??????? return rc;
>
> ??????? return dev_err_probe(...);
>
>> +??? }
>> +
>> +??? if (strncmp(buf, "03NK260", 7) == 7) {
>
> strncmp() never returns 7. You probably want something like
>
> ????if (rc != 7 || strncmp(buf, "03NK260", 7)) {
My bad. Fixed it.
>
>> +??????? buf[rc] = '\0';
>> +??????? dev_err_probe(dev, -ENODEV, "Model '%s' not supported\n", buf);
>
> ??????? return dev_err_probe(...);
Fixed.
>
>> +??????? return -ENODEV;
>> +??? }
>> +
>> +??? rc = pmbus_do_probe(client, &crps_info);
>> +??? if (rc) {
>> +??????? dev_err_probe(dev, rc, "Failed to probe %d\n", rc);
>
> dev_err_probe() already handles the error, and a message such as
> "failed to probe -22" isn't very useful anyway. Also,
> ??????? return dev_err_probe(...);
Fixed.


Thanks and regards,

Ninad Palsule



From seanjc at google.com  Mon Dec 16 14:33:24 2024
From: seanjc at google.com (Sean Christopherson)
Date: Mon, 16 Dec 2024 14:33:24 -0800
Subject: [PATCH v4 00/16] KVM: selftests: "tree" wide overhauls
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <Z2CqtL1R0-368hO-@google.com>

On Wed, Nov 27, 2024, Sean Christopherson wrote:
> Two separate series (mmu_stress_test[1] and $ARCH[2]), posted as one to
> avoid unpleasant conflicts, and because I hope to land both in kvm/next
> shortly after 6.12-rc1 since they impact all of KVM selftests.
> 
> mmu_stress_test
> ---------------
> Convert the max_guest_memory_test into a more generic mmu_stress_test.
> The basic gist of the "conversion" is to have the test do mprotect() on
> guest memory while vCPUs are accessing said memory, e.g. to verify KVM
> and mmu_notifiers are working as intended.
> 
> The original plan was that patch 3 would be a single patch, but things
> snowballed in order to rework vcpu_get_reg() to return a value instead
> of using an out-param.  Having to define a variable just to bump the
> program counter on arm64 annoyed me.
> 
> $ARCH
> -----
> Play nice with treewrite builds of unsupported architectures, e.g. arm
> (32-bit), as KVM selftests' Makefile doesn't do anything to ensure the
> target architecture is actually one KVM selftests supports.
> 
> The last two patches are opportunistic changes (since the above Makefile
> change will generate conflicts everywhere) to switch to using $(ARCH)
> instead of the target triple for arch specific directories, e.g. arm64
> instead of aarch64, mainly so as not to be different from the rest of
> the kernel.

Paolo,

Unless you or someone else have concerns, can you apply this to kvm/next sooner
than later?  I'd like to start applying selftests changes for 6.14 and don't want
generate conflicts, and I really don't want to have to rebase and push this series
out again.

Thanks!


From beata.michalska at arm.com  Mon Dec 16 14:32:54 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Mon, 16 Dec 2024 23:32:54 +0100
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <e3284392-4f57-4b5f-a79d-40b588e6c70e@nvidia.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
 <3f19c5a8-9ee6-42fe-8b4c-3a66c65c8d35@nvidia.com>
 <955a7947-3053-490e-a803-d55699dddd0c@nvidia.com>
 <e3284392-4f57-4b5f-a79d-40b588e6c70e@nvidia.com>
Message-ID: <Z2CqlrtNSyP1rwvv@arm.com>

On Mon, Dec 16, 2024 at 04:33:28PM +0800, Kai-Heng Feng wrote:
> Hi Sumit,
> 
> On 2024/12/16 3:11 PM, Sumit Gupta wrote:
> > 
> > 
> > On 16/12/24 11:13, Kai-Heng Feng wrote:
> > > Hi Beata,
> > > 
> > > On 2024/12/6 9:55 PM, Beata Michalska wrote:
> > > > Currently the CPUFreq core exposes two sysfs attributes that can be used
> > > > to query current frequency of a given CPU(s): namely cpuinfo_cur_freq
> > > > and scaling_cur_freq. Both provide slightly different view on the
> > > > subject and they do come with their own drawbacks.
> > > > 
> > > > cpuinfo_cur_freq provides higher precision though at a cost of being
> > > > rather expensive. Moreover, the information retrieved via this attribute
> > > > is somewhat short lived as frequency can change at any point of time
> > > > making it difficult to reason from.
> > > > 
> > > > scaling_cur_freq, on the other hand, tends to be less accurate but then
> > > > the actual level of precision (and source of information) varies between
> > > > architectures making it a bit ambiguous.
> > > > 
> > > > The new attribute, cpuinfo_avg_freq, is intended to provide more stable,
> > > > distinct interface, exposing an average frequency of a given CPU(s), as
> > > > reported by the hardware, over a time frame spanning no more than a few
> > > > milliseconds. As it requires appropriate hardware support, this
> > > > interface is optional.
> > > > 
> > > > Note that under the hood, the new attribute relies on the information
> > > > provided by arch_freq_get_on_cpu, which, up to this point, has been
> > > > feeding data for scaling_cur_freq attribute, being the source of
> > > > ambiguity when it comes to interpretation. This has been amended by
> > > > restoring the intended behavior for scaling_cur_freq, with a new
> > > > dedicated config option to maintain status quo for those, who may need
> > > > it.
> > > > 
> > > > CC: Jonathan Corbet <corbet at lwn.net>
> > > > CC: Thomas Gleixner <tglx at linutronix.de>
> > > > CC: Ingo Molnar <mingo at redhat.com>
> > > > CC: Borislav Petkov <bp at alien8.de>
> > > > CC: Dave Hansen <dave.hansen at linux.intel.com>
> > > > CC: H. Peter Anvin <hpa at zytor.com>
> > > > CC: Phil Auld <pauld at redhat.com>
> > > > CC: x86 at kernel.org
> > > > CC: linux-doc at vger.kernel.org
> > > > Signed-off-by: Beata Michalska <beata.michalska at arm.com>
> > > > ---
> > > > ? Documentation/admin-guide/pm/cpufreq.rst | 16 ++++++++++-
> > > > ? arch/x86/kernel/cpu/aperfmperf.c???????? |? 2 +-
> > > > ? arch/x86/kernel/cpu/proc.c?????????????? |? 7 +++--
> > > > ? drivers/cpufreq/Kconfig.x86????????????? | 12 ++++++++
> > > > ? drivers/cpufreq/cpufreq.c??????????????? | 36 +++++++++++++++++++++---
> > > > ? include/linux/cpufreq.h????????????????? |? 2 +-
> > > > ? 6 files changed, 66 insertions(+), 9 deletions(-)
> > > > 
> > > > diff --git a/Documentation/admin-guide/pm/cpufreq.rst
> > > > b/Documentation/admin- guide/pm/cpufreq.rst
> > > > index fe1be4ad88cb..76f3835afe01 100644
> > > > --- a/Documentation/admin-guide/pm/cpufreq.rst
> > > > +++ b/Documentation/admin-guide/pm/cpufreq.rst
> > > > @@ -248,6 +248,19 @@ are the following:
> > > > ????? If that frequency cannot be determined, this attribute should not
> > > > ????? be present.
> > > > +``cpuinfo_avg_freq``
> > > > +??????? An average frequency (in KHz) of all CPUs belonging to a given policy,
> > > > +??????? derived from a hardware provided feedback and reported on a time frame
> > > > +??????? spanning at most few milliseconds.
> > > > +
> > > > +??????? This is expected to be based on the frequency the
> > > > hardware actually runs
> > > > +??????? at and, as such, might require specialised hardware
> > > > support (such as AMU
> > > > +??????? extension on ARM). If one cannot be determined, this attribute should
> > > > +??????? not be present.
> > > > +
> > > > +??????? Note, that failed attempt to retrieve current frequency for a given
> > > > +??????? CPU(s) will result in an appropriate error.
> > > > +
> > > > ? ``cpuinfo_max_freq``
> > > > ????? Maximum possible operating frequency the CPUs belonging to this policy
> > > > ????? can run at (in kHz).
> > > > @@ -293,7 +306,8 @@ are the following:
> > > > ????? Some architectures (e.g. ``x86``) may attempt to provide information
> > > > ????? more precisely reflecting the current CPU frequency through this
> > > > ????? attribute, but that still may not be the exact current CPU frequency as
> > > > -??? seen by the hardware at the moment.
> > > > +??? seen by the hardware at the moment. This behavior though, is only
> > > > +??? available via c:macro:``CPUFREQ_ARCH_CUR_FREQ`` option.
> > > > ? ``scaling_driver``
> > > > ????? The scaling driver currently in use.
> > > > diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
> > > > index 0b69bfbf345d..a00059139ca4 100644
> > > > --- a/arch/x86/kernel/cpu/aperfmperf.c
> > > > +++ b/arch/x86/kernel/cpu/aperfmperf.c
> > > > @@ -413,7 +413,7 @@ void arch_scale_freq_tick(void)
> > > > ?? */
> > > > ? #define MAX_SAMPLE_AGE??? ((unsigned long)HZ / 50)
> > > > -unsigned int arch_freq_get_on_cpu(int cpu)
> > > > +int arch_freq_get_on_cpu(int cpu)
> > > > ? {
> > > > ????? struct aperfmperf *s = per_cpu_ptr(&cpu_samples, cpu);
> > > > ????? unsigned int seq, freq;
> > > > diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
> > > > index e65fae63660e..34d8fb93fb70 100644
> > > > --- a/arch/x86/kernel/cpu/proc.c
> > > > +++ b/arch/x86/kernel/cpu/proc.c
> > > > @@ -86,9 +86,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
> > > > ????????? seq_printf(m, "microcode\t: 0x%x\n", c->microcode);
> > > > ????? if (cpu_has(c, X86_FEATURE_TSC)) {
> > > > -??????? unsigned int freq = arch_freq_get_on_cpu(cpu);
> > > > +??????? int freq = arch_freq_get_on_cpu(cpu);
> > > > -??????? seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 1000));
> > > > +??????? if (freq <= 0)
> > > > +??????????? seq_puts(m, "cpu MHz\t\t: Unknown\n");
> > > > +??????? else
> > > > +??????????? seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq /
> > > > 1000, (freq % 1000));
> > > > ????? }
> > > > ????? /* Cache size */
> > > > diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
> > > > index 97c2d4f15d76..212e1b9afe21 100644
> > > > --- a/drivers/cpufreq/Kconfig.x86
> > > > +++ b/drivers/cpufreq/Kconfig.x86
> > > > @@ -340,3 +340,15 @@ config X86_SPEEDSTEP_RELAXED_CAP_CHECK
> > > > ??????? option lets the probing code bypass some of those checks if the
> > > > ??????? parameter "relaxed_check=1" is passed to the module.
> > > > +config CPUFREQ_ARCH_CUR_FREQ
> > > > +??? default y
> > > > +??? bool "Current frequency derived from HW provided feedback"
> > > > +??? help
> > > > +????? This determines whether the scaling_cur_freq sysfs attribute returns
> > > > +????? the last requested frequency or a more precise value based on hardware
> > > > +????? provided feedback (as architected counters).
> > > > +????? Given that a more precise frequency can now be provided via the
> > > > +????? cpuinfo_avg_cur_freq attribute, by enabling this option,
> > > > +????? scaling_cur_freq maintains the provision of a counter based frequency,
> > > > +????? for compatibility reasons.
> > > > +
> > > > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > > > index 04fc786dd2c0..70df2a24437b 100644
> > > > --- a/drivers/cpufreq/cpufreq.c
> > > > +++ b/drivers/cpufreq/cpufreq.c
> > > > @@ -747,9 +747,14 @@ show_one(cpuinfo_transition_latency,
> > > > cpuinfo.transition_latency);
> > > > ? show_one(scaling_min_freq, min);
> > > > ? show_one(scaling_max_freq, max);
> > > > -__weak unsigned int arch_freq_get_on_cpu(int cpu)
> > > > +__weak int arch_freq_get_on_cpu(int cpu)
> > > > ? {
> > > > -??? return 0;
> > > > +??? return -EOPNOTSUPP;
> > > > +}
> > > > +
> > > > +static inline bool cpufreq_avg_freq_supported(struct cpufreq_policy *policy)
> > > > +{
> > > > +??? return arch_freq_get_on_cpu(policy->cpu) != -EOPNOTSUPP;
> > > > ? }
> > > > ? static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
> > > > @@ -757,8 +762,11 @@ static ssize_t show_scaling_cur_freq(struct
> > > > cpufreq_policy *policy, char *buf)
> > > > ????? ssize_t ret;
> > > > ????? unsigned int freq;
> > > > -??? freq = arch_freq_get_on_cpu(policy->cpu);
> > > > -??? if (freq)
> > > > +??? freq = IS_ENABLED(CONFIG_CPUFREQ_ARCH_CUR_FREQ)
> > > > +??????? ? arch_freq_get_on_cpu(policy->cpu)
> > > > +??????? : 0;
> > > > +
> > > > +??? if (freq > 0)
> > > > ????????? ret = sysfs_emit(buf, "%u\n", freq);
> > > > ????? else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
> > > > ????????? ret = sysfs_emit(buf, "%u\n", cpufreq_driver->get(policy->cpu));
> > > > @@ -802,6 +810,19 @@ static ssize_t show_cpuinfo_cur_freq(struct
> > > > cpufreq_policy *policy,
> > > > ????? return sysfs_emit(buf, "<unknown>\n");
> > > > ? }
> > > > +/*
> > > > + * show_cpuinfo_avg_freq - average CPU frequency as detected by hardware
> > > > + */
> > > > +static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
> > > > +???????????????????? char *buf)
> > > > +{
> > > > +??? int avg_freq = arch_freq_get_on_cpu(policy->cpu);
> > > 
> > > We are seeing issues when reading cpuinfo_avg_freq on an ARM64 system:
> > > 
> > > $ cat /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq
> > > cat: /sys/devices/system/cpu/cpufreq/policy1/cpuinfo_avg_freq:
> > > Resource temporarily unavailable
> > > 
> > > The CPU is in idle state, so arch_freq_get_on_cpu() can't find a
> > > good alternative source for frequency info.
> > > 
> > 
> > Hi Kai Heng,
> > This has already been discussed during v7 in [1] & [2].
> 
> Thanks for the info!
@Sumit: Thank you indeed.
> 
> > In v7, we were returning zero which printed 'unknown'.
> > The discussion was about printing in more descriptive way or with an
> > appropriate error code. In v8 we are returning 'EAGAIN' instead of zero.
> > The final decision was of Maintainers.
> 
> Is there any cpufreq driver that prints "unknown" or error when CPU is in idle?
I think at this point, for cpuinfo_cur_freq, one gets either the frequency value
or 'unknown'. I'm not sure whether there are any drivers that report error upon
'get'.
> 
> I think it's more unsurprising to print the lowest CPU frequency when CPU is
> in idle state, instead of any other error code.
With that approach one cannot easily determine whether the CPU is actually
running at the lowest frequency or it's idle.
Returning an error also avoids mixing types of data provided by the handler.

---
BR
Beata
> 
> Kai-Heng
> 
> > 
> > Viresh,
> > You have any preference on this?
> > 
> > [1] https://lore.kernel.org/lkml/aa254516-968e-4665-bb5b-981c296ffc35 at nvidia.com/#t
> > [2] https://lore.kernel.org/lkml/Zyh-uVSW-0d0r8oB at arm.com/
> > 
> > Thank you,
> > Sumit Gupta
> > 
> > > One way to resolve this is to have fallback methods in
> > > show_cpuinfo_avg_freq() so it will look like this:
> > > 
> > > static ssize_t show_cpuinfo_avg_freq(struct cpufreq_policy *policy,
> > > ????????????????????????????????????? char *buf)
> > > {
> > > ???????? int avg_freq = arch_freq_get_on_cpu(policy->cpu);
> > > ???????? int ret;
> > > 
> > > ???????? if (avg_freq > 0)
> > > ???????????????? ret = sysfs_emit(buf, "%u\n", avg_freq);
> > > ???????? else if (cpufreq_driver->setpolicy && cpufreq_driver->get)
> > > ???????????????? ret = sysfs_emit(buf, "%u\n", cpufreq_driver->get(policy->cpu));
> > > ???????? else
> > > ???????????????? ret = sysfs_emit(buf, "%u\n", policy->cur);
> > > ???????? return ret;
> > > }
> > > 
> > > But that also makes show_cpuinfo_avg_freq() pretty much the same as
> > > show_scaling_cur_freq().
> > > 
> > > So is it possible to consolidate show_cpuinfo_avg_freq() into
> > > show_scaling_cur_freq(), by making CONFIG_CPUFREQ_ARCH_CUR_FREQ also
> > > available to ARM64?
> > > 
> > > Kai-Heng
> > > 
> > > > +
> > > > +??? if (avg_freq > 0)
> > > > +??????? return sysfs_emit(buf, "%u\n", avg_freq);
> > > > +??? return avg_freq != 0 ? avg_freq : -EINVAL;
> > > > +}
> > > > +
> > > > ? /*
> > > > ?? * show_scaling_governor - show the current policy for the specified CPU
> > > > ?? */
> > > > @@ -964,6 +985,7 @@ static ssize_t show_bios_limit(struct
> > > > cpufreq_policy *policy, char *buf)
> > > > ? }
> > > > ? cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
> > > > +cpufreq_freq_attr_ro(cpuinfo_avg_freq);
> > > > ? cpufreq_freq_attr_ro(cpuinfo_min_freq);
> > > > ? cpufreq_freq_attr_ro(cpuinfo_max_freq);
> > > > ? cpufreq_freq_attr_ro(cpuinfo_transition_latency);
> > > > @@ -1091,6 +1113,12 @@ static int
> > > > cpufreq_add_dev_interface(struct cpufreq_policy *policy)
> > > > ????????????? return ret;
> > > > ????? }
> > > > +??? if (cpufreq_avg_freq_supported(policy)) {
> > > > +??????? ret = sysfs_create_file(&policy->kobj, &cpuinfo_avg_freq.attr);
> > > > +??????? if (ret)
> > > > +??????????? return ret;
> > > > +??? }
> > > > +
> > > > ????? ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
> > > > ????? if (ret)
> > > > ????????? return ret;
> > > > diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> > > > index d4d2f4d1d7cb..a7b6c0ccf9bc 100644
> > > > --- a/include/linux/cpufreq.h
> > > > +++ b/include/linux/cpufreq.h
> > > > @@ -1194,7 +1194,7 @@ static inline int
> > > > of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_
> > > > ? }
> > > > ? #endif
> > > > -extern unsigned int arch_freq_get_on_cpu(int cpu);
> > > > +extern int arch_freq_get_on_cpu(int cpu);
> > > > ? #ifndef arch_set_freq_scale
> > > > ? static __always_inline
> > > 
> 


From luca.ceresoli at bootlin.com  Mon Dec 16 14:54:56 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Mon, 16 Dec 2024 23:54:56 +0100
Subject: imx8m-blk-ctrl: WARNING, no release() function
In-Reply-To: <20241212141003.GA44219@francesco-nb>
References: <20241212141003.GA44219@francesco-nb>
Message-ID: <20241216235456.3a6b07a2@booty>

Hi Francesco,

+Cc: Jindong, Benjamin, Paul (recent committers, in lack of an
imx8m-blk-ctrl.c maintainer)
+Cc: Herv? (stumbled on this issue too)

On Thu, 12 Dec 2024 15:10:03 +0100
Francesco Dolcini <francesco at dolcini.it> wrote:

> Hello,
> on v6.13-rc2 (PREEMPT_RT, if it matters), I have the following warning
> 
> [    4.615793] ------------[ cut here ]------------
> [    4.615814] Device 'mediablk-mipi-csi2-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.

Thanks for the report. It is happening also here after upgrading from
6.13-rc1 to 6.13-rc3.

This originates from drivers/pmdomain/imx/imx8m-blk-ctrl.c

I bisected and the initial commit exposing this warning is:

  commit b8f7bbd1f4ecff6d6277b8c454f62bb0a1c6dbe4
  Author: Ulf Hansson <ulf.hansson at linaro.org>
  Date:   Fri Nov 22 14:42:02 2024 +0100

    pmdomain: core: Add missing put_device()
    
    When removing a genpd we don't clean up the genpd->dev correctly. Let's add
    the missing put_device() in genpd_free_data() to fix this.
    
    Fixes: 401ea1572de9 ("PM / Domain: Add struct device to genpd")
    Cc: stable at vger.kernel.org
    Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
    Message-ID: <20241122134207.157283-2-ulf.hansson at linaro.org>

Superficially, it looks to me like a legitimate commit which exposes a
pre-existing flaw in drivers/pmdomain/imx/imx8m-blk-ctrl.c.

I have no more info at the moment.

Luca

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From robh at kernel.org  Mon Dec 16 15:15:05 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 16 Dec 2024 17:15:05 -0600
Subject: [PATCH V2 18/46] arm64/sysreg: Add register fields for PMUACR_EL1
In-Reply-To: <20241210055311.780688-19-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-19-anshuman.khandual@arm.com>
Message-ID: <20241216231505.GA601635-robh@kernel.org>

On Tue, Dec 10, 2024 at 11:22:43AM +0530, Anshuman Khandual wrote:
> This adds register fields for PMUACR_EL1 as per the definitions based
> on DDI0601 2024-09.
> 
> 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 | 37 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 214ad6da1dff..462adb8031ca 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2349,6 +2349,43 @@ Res0	63:5
>  Field	4:0	SEL
>  EndSysreg
>  
> +Sysreg	PMUACR_EL1	3	0	9	14	4

I already added this and various other PMUv3.9 registers you've added 
here in v6.12 and v6.13. So are you on an old base or the tool allows 
multiple definitions? If the latter, that should be fixed.

> +Res0	63:33
> +Field	32	FM
> +Field	31	C
> +Field	30	P30
> +Field	29	P29
> +Field	28	P28
> +Field	27	P27
> +Field	26	P26
> +Field	25	P25
> +Field	24	P24
> +Field	23	P23
> +Field	22	P22
> +Field	21	P21
> +Field	20	P20
> +Field	19	P19
> +Field	18	P18
> +Field	17	P17
> +Field	16	P16
> +Field	15	P15
> +Field	14	P14
> +Field	13	P13
> +Field	12	P12
> +Field	11	P11
> +Field	10	P10
> +Field	9	P9
> +Field	8	P8
> +Field	7	P7
> +Field	6	P6
> +Field	5	P5
> +Field	4	P4
> +Field	3	P3
> +Field	2	P2
> +Field	1	P1
> +Field	0	P0

We're never going to use Pnn defines. This is just useless bloat unless 
we're aiming to top amd gpu defines LOC.

Rob


From jane.chu at oracle.com  Mon Dec 16 15:37:24 2024
From: jane.chu at oracle.com (jane.chu at oracle.com)
Date: Mon, 16 Dec 2024 15:37:24 -0800
Subject: [PATCH v17 1/3] ACPI: APEI: send SIGBUS to current task if
 synchronous memory error not recovered
In-Reply-To: <20241202030527.20586-2-xueshuai@linux.alibaba.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
 <20241202030527.20586-2-xueshuai@linux.alibaba.com>
Message-ID: <2fb8b1e5-d606-47be-a79e-a4e37a3b8f7f@oracle.com>


On 12/1/2024 7:05 PM, Shuai Xue wrote:
> Synchronous error was detected as a result of user-space process accessing
> a 2-bit uncorrected error. The CPU will take a synchronous error exception
> such as Synchronous External Abort (SEA) on Arm64. The kernel will queue a
> memory_failure() work which poisons the related page, unmaps the page, and
> then sends a SIGBUS to the process, so that a system wide panic can be
> avoided.
>
> However, no memory_failure() work will be queued when abnormal synchronous
> errors occur. These errors can include situations such as invalid PA,
> unexpected severity, no memory failure config support, invalid GUID
> section, etc. In such case, the user-space process will trigger SEA again.
> This loop can potentially exceed the platform firmware threshold or even
> trigger a kernel hard lockup, leading to a system reboot.
>
> Fix it by performing a force kill if no memory_failure() work is queued
> for synchronous errors.
>
> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
> Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Reviewed-by: Yazen Ghannam <yazen.ghannam at amd.com>
> ---
>   drivers/acpi/apei/ghes.c | 11 +++++++++++
>   1 file changed, 11 insertions(+)
>
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index a2491905f165..106486bdfefc 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -801,6 +801,17 @@ static bool ghes_do_proc(struct ghes *ghes,
>   		}
>   	}
>   
> +	/*
> +	 * If no memory failure work is queued for abnormal synchronous
> +	 * errors, do a force kill.
> +	 */
> +	if (sync && !queued) {
> +		dev_err(ghes->dev,
> +			HW_ERR GHES_PFX "%s:%d: synchronous unrecoverable error (SIGBUS)\n",
> +			current->comm, task_pid_nr(current));
> +		force_sig(SIGBUS);
> +	}
> +
>   	return queued;
>   }
>   

Looks good.

Reviewed-by: Jane Chu <jane.chu at oracle.com>

-jane



From jane.chu at oracle.com  Mon Dec 16 15:37:58 2024
From: jane.chu at oracle.com (jane.chu at oracle.com)
Date: Mon, 16 Dec 2024 15:37:58 -0800
Subject: [PATCH v17 2/3] mm: memory-failure: move return value
 documentation to function declaration
In-Reply-To: <20241202030527.20586-3-xueshuai@linux.alibaba.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
 <20241202030527.20586-3-xueshuai@linux.alibaba.com>
Message-ID: <51d231c2-3659-461a-b6c3-d0e7f9fddfc1@oracle.com>


On 12/1/2024 7:05 PM, Shuai Xue wrote:
> Part of return value comments for memory_failure() were originally
> documented at the call site. Move those comments to the function
> declaration to improve code readability and to provide developers with
> immediate access to function usage and return information.
>
> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
> Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Reviewed-by: Yazen Ghannam <yazen.ghannam at amd.com>
> ---
>   arch/x86/kernel/cpu/mce/core.c |  7 -------
>   mm/memory-failure.c            | 10 +++++++---
>   2 files changed, 7 insertions(+), 10 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
> index 7fb5556a0b53..d1dd7f892514 100644
> --- a/arch/x86/kernel/cpu/mce/core.c
> +++ b/arch/x86/kernel/cpu/mce/core.c
> @@ -1398,13 +1398,6 @@ static void kill_me_maybe(struct callback_head *cb)
>   		return;
>   	}
>   
> -	/*
> -	 * -EHWPOISON from memory_failure() means that it already sent SIGBUS
> -	 * to the current process with the proper error info,
> -	 * -EOPNOTSUPP means hwpoison_filter() filtered the error event,
> -	 *
> -	 * In both cases, no further processing is required.
> -	 */
>   	if (ret == -EHWPOISON || ret == -EOPNOTSUPP)
>   		return;
>   
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> index a7b8ccd29b6f..14c316d7d38d 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -2211,9 +2211,13 @@ static void kill_procs_now(struct page *p, unsigned long pfn, int flags,
>    * Must run in process context (e.g. a work queue) with interrupts
>    * enabled and no spinlocks held.
>    *
> - * Return: 0 for successfully handled the memory error,
> - *         -EOPNOTSUPP for hwpoison_filter() filtered the error event,
> - *         < 0(except -EOPNOTSUPP) on failure.
> + * Return:
> + *   0             - success,
> + *   -ENXIO        - memory not managed by the kernel
> + *   -EOPNOTSUPP   - hwpoison_filter() filtered the error event,
> + *   -EHWPOISON    - the page was already poisoned, potentially
> + *                   kill process,
> + *   other negative values - failure.
>    */
>   int memory_failure(unsigned long pfn, int flags)
>   {

Looks good.

Reviewed-by: Jane Chu <jane.chu at oracle.com>

-jane



From robh at kernel.org  Mon Dec 16 15:42:51 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 16 Dec 2024 17:42:51 -0600
Subject: [PATCH V3 6/7] arm64/boot: Enable EL2 requirements for
 FEAT_Debugv8p9
In-Reply-To: <20241216040831.2448257-7-anshuman.khandual@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
 <20241216040831.2448257-7-anshuman.khandual@arm.com>
Message-ID: <20241216234251.GA629562-robh@kernel.org>

On Mon, Dec 16, 2024 at 09:38:30AM +0530, Anshuman Khandual wrote:
> Fine grained trap control for MDSELR_EL1 register needs to be configured in
> HDFGRTR2_EL2, and HDFGWTR2_EL2 registers when kernel enters at EL1, but EL2
> is also present.

Shouldn't this be "when kernel enters at EL2, and EL3 is also present"? 
Though it is really "If EL3 set FGTEn2 and the kernel is entered in 
EL2, then FGT2 must be initialized for MDSELR_EL1."

If it was me, I'd just plagarize what was written for prior FGT 
commits for this code. :)

> This adds a new helper __init_el2_fgt2() initializing this
> new FEAT_FGT2 based fine grained registers.

"This adds" is the same as saying "This patch/commit adds" which is well 
documented to avoid. Use imperative "Add a new helper...". Though it is 
clear from the diff that is what you are doing...


> MDCR_EL2.EBWE needs to be enabled for additional (beyond 16) breakpoint and
> watchpoint exceptions when kernel enters at EL1, but EL2 is also present.
> This updates __init_el2_debug() as required for FEAT_Debugv8p9.
> 
> While here, also update booting.rst with MDCR_EL3 and SCR_EL3 requirements.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Jonathan Corbet <corbet at lwn.net>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oliver.upton at linux.dev>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: kvmarm at lists.linux.dev
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
> Changes in V3:
> 
> - Dropped MDCR_EL3.TDA boot requirement from documentation (separate series)
> - Dropped MDCR_EL2_EBWE definition as MDCR_EL2 is now defined in tools sysreg
> 
> https://lore.kernel.org/all/20241211065425.1106683-1-anshuman.khandual at arm.com/
> 
>  Documentation/arch/arm64/booting.rst | 18 ++++++++++++++++++
>  arch/arm64/include/asm/el2_setup.h   | 26 ++++++++++++++++++++++++++
>  2 files changed, 44 insertions(+)
> 
> diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
> index 3278fb4bf219..054cfe1cad18 100644
> --- a/Documentation/arch/arm64/booting.rst
> +++ b/Documentation/arch/arm64/booting.rst
> @@ -288,6 +288,12 @@ Before jumping into the kernel, the following conditions must be met:
>  
>      - SCR_EL3.FGTEn (bit 27) must be initialised to 0b1.
>  
> +  For CPUs with the Fine Grained Traps (FEAT_FGT2) extension present:
> +
> +  - If EL3 is present and the kernel is entered at EL2:
> +
> +    - SCR_EL3.FGTEn2 (bit 59) must be initialised to 0b1.
> +
>    For CPUs with support for HCRX_EL2 (FEAT_HCX) present:
>  
>    - If EL3 is present and the kernel is entered at EL2:
> @@ -322,6 +328,18 @@ Before jumping into the kernel, the following conditions must be met:
>      - ZCR_EL2.LEN must be initialised to the same value for all CPUs the
>        kernel will execute on.
>  
> +  For CPUs with FEAT_Debugv8p9 extension present:
> +
> +  - If the kernel is entered at EL1 and EL2 is present:
> +
> +    - HDFGRTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1
> +    - HDFGWTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1
> +    - MDCR_EL2.EBWE (bit 43) must be initialized to 0b1
> +
> +  - If EL3 is present:
> +
> +    - MDCR_EL3.EBWE (bit 43) must be initialized to 0b1
> +
>    For CPUs with the Scalable Matrix Extension (FEAT_SME):
>  
>    - If EL3 is present:
> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index 4ef52d7245bb..2fbfe27d38b5 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -105,6 +105,13 @@
>  						// to own it.
>  
>  .Lskip_trace_\@:
> +	mrs	x1, id_aa64dfr0_el1
> +	ubfx	x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
> +	cmp	x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
> +	b.lt	.Lskip_dbg_v8p9_\@
> +
> +	orr	x2, x2, #MDCR_EL2_EBWE
> +.Lskip_dbg_v8p9_\@:
>  	msr	mdcr_el2, x2			// Configure debug traps
>  .endm
>  
> @@ -244,6 +251,24 @@
>  .Lskip_gcs_\@:
>  .endm
>  
> +.macro __init_el2_fgt2
> +	mrs	x1, id_aa64mmfr0_el1
> +	ubfx	x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
> +	cmp	x1, #ID_AA64MMFR0_EL1_FGT_FGT2

We already read this field in __init_el2_fgt, shouldn't we leverage that 
and move all this there rather than read the feature reg twice.

> +	b.lt	.Lskip_fgt2_\@
> +
> +	mrs	x1, id_aa64dfr0_el1
> +	ubfx	x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
> +	cmp	x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
> +	b.lt	.Lskip_dbg_v8p9_\@
> +
> +	mov_q   x0, HDFGWTR2_EL2_nMDSELR_EL1
> +	msr_s	SYS_HDFGWTR2_EL2, x0
> +	msr_s	SYS_HDFGRTR2_EL2, x0

If Debug v8.9 is not present, but FGT2 is, shouldn't we write 0 to these 
registers? That is what we do for FGT.


I just realized I forgot to add FGT2 setup for the PMUv3.9 features I 
already added in 6.12 and 6.13. So this really needs to land sooner 
rather than later to add that. 

Rob


From jane.chu at oracle.com  Mon Dec 16 15:53:54 2024
From: jane.chu at oracle.com (jane.chu at oracle.com)
Date: Mon, 16 Dec 2024 15:53:54 -0800
Subject: [PATCH v17 3/3] ACPI: APEI: handle synchronous exceptions in task
 work
In-Reply-To: <20241202030527.20586-4-xueshuai@linux.alibaba.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
 <20241202030527.20586-4-xueshuai@linux.alibaba.com>
Message-ID: <d7adcb58-7a1d-4f0b-a55d-40c12ca60b02@oracle.com>


On 12/1/2024 7:05 PM, Shuai Xue wrote:
> The memory uncorrected error could be signaled by asynchronous interrupt
> (specifically, SPI in arm64 platform), e.g. when an error is detected by
> a background scrubber, or signaled by synchronous exception
> (specifically, data abort exception in arm64 platform), e.g. when a CPU
> tries to access a poisoned cache line. Currently, both synchronous and
> asynchronous error use memory_failure_queue() to schedule
> memory_failure() to exectute in a kworker context.
>
> As a result, when a user-space process is accessing a poisoned data, a
> data abort is taken and the memory_failure() is executed in the kworker
> context, memory_failure():
>
>    - will send wrong si_code by SIGBUS signal in early_kill mode, and
>    - can not kill the user-space in some cases resulting a synchronous
>      error infinite loop
>
> Issue 1: send wrong si_code in early_kill mode
>
> Since commit a70297d22132 ("ACPI: APEI: set memory failure flags as
> MF_ACTION_REQUIRED on synchronous events")', the flag MF_ACTION_REQUIRED
> could be used to determine whether a synchronous exception occurs on
> ARM64 platform.  When a synchronous exception is detected, the kernel is
> expected to terminate the current process which has accessed poisoned
> page. This is done by sending a SIGBUS signal with an error code
> BUS_MCEERR_AR, indicating an action-required machine check error on
> read.
>
> However, when kill_proc() is called to terminate the processes who have
> the poisoned page mapped, it sends the incorrect SIGBUS error code
> BUS_MCEERR_AO because the context in which it operates is not the one
> where the error was triggered.
>
> To reproduce this problem:
>
>    #sysctl -w vm.memory_failure_early_kill=1
>    vm.memory_failure_early_kill = 1
>
>    # STEP2: inject an UCE error and consume it to trigger a synchronous error
>    #einj_mem_uc single
>    0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>    injecting ...
>    triggering ...
>    signal 7 code 5 addr 0xffffb0d75000
>    page not present
>    Test passed
>
> The si_code (code 5) from einj_mem_uc indicates that it is BUS_MCEERR_AO
> error and it is not the fact.
>
> After this patch:
>
>    # STEP1: enable early kill mode
>    #sysctl -w vm.memory_failure_early_kill=1
>    vm.memory_failure_early_kill = 1
>    # STEP2: inject an UCE error and consume it to trigger a synchronous error
>    #einj_mem_uc single
>    0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>    injecting ...
>    triggering ...
>    signal 7 code 4 addr 0xffffb0d75000
>    page not present
>    Test passed
>
> The si_code (code 4) from einj_mem_uc indicates that it is a BUS_MCEERR_AR
> error as we expected.
>
> Issue 2: a synchronous error infinite loop
>
> If a user-space process, e.g. devmem, accesses a poisoned page for which
> the HWPoison flag is set, kill_accessing_process() is called to send
> SIGBUS to current processs with error info. Because the memory_failure()
> is executed in the kworker context, it will just do nothing but return
> EFAULT. So, devmem will access the posioned page and trigger an
> exception again, resulting in a synchronous error infinite loop. Such
> exception loop may cause platform firmware to exceed some threshold and
> reboot when Linux could have recovered from this error.
>
> To reproduce this problem:
>
>    # STEP 1: inject an UCE error, and kernel will set HWPosion flag for related page
>    #einj_mem_uc single
>    0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>    injecting ...
>    triggering ...
>    signal 7 code 4 addr 0xffffb0d75000
>    page not present
>    Test passed
>
>    # STEP 2: access the same page and it will trigger a synchronous error infinite loop
>    devmem 0x4092d55b400
>
> To fix above two issues, queue memory_failure() as a task_work so that
> it runs in the context of the process that is actually consuming the
> poisoned data.
>
> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
> Tested-by: Ma Wupeng <mawupeng1 at huawei.com>
> Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> Reviewed-by: Xiaofei Tan <tanxiaofei at huawei.com>
> Reviewed-by: Baolin Wang <baolin.wang at linux.alibaba.com>
> Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> ---
>   drivers/acpi/apei/ghes.c | 77 +++++++++++++++++++++++-----------------
>   include/acpi/ghes.h      |  3 --
>   include/linux/mm.h       |  1 -
>   mm/memory-failure.c      | 13 -------
>   4 files changed, 44 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 106486bdfefc..70f2ee3ad1a8 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -467,28 +467,41 @@ static void ghes_clear_estatus(struct ghes *ghes,
>   }
>   
>   /*
> - * Called as task_work before returning to user-space.
> - * Ensure any queued work has been done before we return to the context that
> - * triggered the notification.
> + * struct ghes_task_work - for synchronous RAS event
> + *
> + * @twork:                callback_head for task work
> + * @pfn:                  page frame number of corrupted page
> + * @flags:                work control flags
> + *
> + * Structure to pass task work to be handled before
> + * returning to user-space via task_work_add().
>    */
> -static void ghes_kick_task_work(struct callback_head *head)
> +struct ghes_task_work {
> +	struct callback_head twork;
> +	u64 pfn;
> +	int flags;
> +};
> +
> +static void memory_failure_cb(struct callback_head *twork)
>   {
> -	struct acpi_hest_generic_status *estatus;
> -	struct ghes_estatus_node *estatus_node;
> -	u32 node_len;
> +	struct ghes_task_work *twcb = container_of(twork, struct ghes_task_work, twork);
> +	int ret;
>   
> -	estatus_node = container_of(head, struct ghes_estatus_node, task_work);
> -	if (IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
> -		memory_failure_queue_kick(estatus_node->task_work_cpu);
> +	ret = memory_failure(twcb->pfn, twcb->flags);
> +	gen_pool_free(ghes_estatus_pool, (unsigned long)twcb, sizeof(*twcb));
>   
> -	estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
> -	node_len = GHES_ESTATUS_NODE_LEN(cper_estatus_len(estatus));
> -	gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len);
> +	if (!ret || ret == -EHWPOISON || ret == -EOPNOTSUPP)
> +		return;
> +
> +	pr_err("%#llx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",
> +			twcb->pfn, current->comm, task_pid_nr(current));
> +	force_sig(SIGBUS);
>   }
>   
>   static bool ghes_do_memory_failure(u64 physical_addr, int flags)
>   {
>   	unsigned long pfn;
> +	struct ghes_task_work *twcb;
>   
>   	if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
>   		return false;
> @@ -501,6 +514,18 @@ static bool ghes_do_memory_failure(u64 physical_addr, int flags)
>   		return false;
>   	}
>   
> +	if (flags == MF_ACTION_REQUIRED && current->mm) {
> +		twcb = (void *)gen_pool_alloc(ghes_estatus_pool, sizeof(*twcb));
> +		if (!twcb)
> +			return false;
> +
> +		twcb->pfn = pfn;
> +		twcb->flags = flags;
> +		init_task_work(&twcb->twork, memory_failure_cb);
> +		task_work_add(current, &twcb->twork, TWA_RESUME);
> +		return true;
> +	}
> +
>   	memory_failure_queue(pfn, flags);
>   	return true;
>   }
> @@ -745,7 +770,7 @@ int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd)
>   }
>   EXPORT_SYMBOL_NS_GPL(cxl_cper_kfifo_get, CXL);
>   
> -static bool ghes_do_proc(struct ghes *ghes,
> +static void ghes_do_proc(struct ghes *ghes,
>   			 const struct acpi_hest_generic_status *estatus)
>   {
>   	int sev, sec_sev;
> @@ -811,8 +836,6 @@ static bool ghes_do_proc(struct ghes *ghes,
>   			current->comm, task_pid_nr(current));
>   		force_sig(SIGBUS);
>   	}
> -
> -	return queued;
>   }
>   
>   static void __ghes_print_estatus(const char *pfx,
> @@ -1114,9 +1137,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
>   	struct ghes_estatus_node *estatus_node;
>   	struct acpi_hest_generic *generic;
>   	struct acpi_hest_generic_status *estatus;
> -	bool task_work_pending;
>   	u32 len, node_len;
> -	int ret;
>   
>   	llnode = llist_del_all(&ghes_estatus_llist);
>   	/*
> @@ -1131,25 +1152,16 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
>   		estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
>   		len = cper_estatus_len(estatus);
>   		node_len = GHES_ESTATUS_NODE_LEN(len);
> -		task_work_pending = ghes_do_proc(estatus_node->ghes, estatus);
> +
> +		ghes_do_proc(estatus_node->ghes, estatus);
> +
>   		if (!ghes_estatus_cached(estatus)) {
>   			generic = estatus_node->generic;
>   			if (ghes_print_estatus(NULL, generic, estatus))
>   				ghes_estatus_cache_add(generic, estatus);
>   		}
> -
> -		if (task_work_pending && current->mm) {
> -			estatus_node->task_work.func = ghes_kick_task_work;
> -			estatus_node->task_work_cpu = smp_processor_id();
> -			ret = task_work_add(current, &estatus_node->task_work,
> -					    TWA_RESUME);
> -			if (ret)
> -				estatus_node->task_work.func = NULL;
> -		}
> -
> -		if (!estatus_node->task_work.func)
> -			gen_pool_free(ghes_estatus_pool,
> -				      (unsigned long)estatus_node, node_len);
> +		gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node,
> +			      node_len);
>   
>   		llnode = next;
>   	}
> @@ -1210,7 +1222,6 @@ static int ghes_in_nmi_queue_one_entry(struct ghes *ghes,
>   
>   	estatus_node->ghes = ghes;
>   	estatus_node->generic = ghes->generic;
> -	estatus_node->task_work.func = NULL;
>   	estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
>   
>   	if (__ghes_read_estatus(estatus, buf_paddr, fixmap_idx, len)) {
> diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
> index be1dd4c1a917..ebd21b05fe6e 100644
> --- a/include/acpi/ghes.h
> +++ b/include/acpi/ghes.h
> @@ -35,9 +35,6 @@ struct ghes_estatus_node {
>   	struct llist_node llnode;
>   	struct acpi_hest_generic *generic;
>   	struct ghes *ghes;
> -
> -	int task_work_cpu;
> -	struct callback_head task_work;
>   };
>   
>   struct ghes_estatus_cache {
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index c39c4945946c..aa4246c7c23e 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -3936,7 +3936,6 @@ enum mf_flags {
>   int mf_dax_kill_procs(struct address_space *mapping, pgoff_t index,
>   		      unsigned long count, int mf_flags);
>   extern int memory_failure(unsigned long pfn, int flags);
> -extern void memory_failure_queue_kick(int cpu);
>   extern int unpoison_memory(unsigned long pfn);
>   extern atomic_long_t num_poisoned_pages __read_mostly;
>   extern int soft_offline_page(unsigned long pfn, int flags);
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> index 14c316d7d38d..e0adb665d07b 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -2499,19 +2499,6 @@ static void memory_failure_work_func(struct work_struct *work)
>   	}
>   }
>   
> -/*
> - * Process memory_failure work queued on the specified CPU.
> - * Used to avoid return-to-userspace racing with the memory_failure workqueue.
> - */
> -void memory_failure_queue_kick(int cpu)
> -{
> -	struct memory_failure_cpu *mf_cpu;
> -
> -	mf_cpu = &per_cpu(memory_failure_cpu, cpu);
> -	cancel_work_sync(&mf_cpu->work);
> -	memory_failure_work_func(&mf_cpu->work);
> -}
> -
>   static int __init memory_failure_init(void)
>   {
>   	struct memory_failure_cpu *mf_cpu;

Looks good.

Reviewed-by: Jane Chu <jane.chu at oracle.com>

-jane




From yuji2.ishikawa at toshiba.co.jp  Mon Dec 16 15:57:49 2024
From: yuji2.ishikawa at toshiba.co.jp (yuji2.ishikawa at toshiba.co.jp)
Date: Mon, 16 Dec 2024 23:57:49 +0000
Subject: [PATCH v12 1/8] dt-bindings: media: platform: visconti: Add
 Toshiba Visconti MIPI CSI-2 Receiver
In-Reply-To: <07e0cc97-c0c4-42fd-b51d-87b0eaed4e4a@kernel.org>
References: <20241125092146.1561901-1-yuji2.ishikawa@toshiba.co.jp>
 <20241125092146.1561901-2-yuji2.ishikawa@toshiba.co.jp>
 <07e0cc97-c0c4-42fd-b51d-87b0eaed4e4a@kernel.org>
Message-ID: <TY3PR01MB9982FE7739FABB2275C79C0B923B2@TY3PR01MB9982.jpnprd01.prod.outlook.com>

Hello Krzysztof

Thank you for your review

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk at kernel.org>
> Sent: Monday, November 25, 2024 7:11 PM
> To: ishikawa yuji(?? ?? ?????????????)
> <yuji2.ishikawa at toshiba.co.jp>; Laurent Pinchart
> <laurent.pinchart at ideasonboard.com>; Mauro Carvalho Chehab
> <mchehab at kernel.org>; Rob Herring <robh at kernel.org>; Krzysztof Kozlowski
> <krzk+dt at kernel.org>; Conor Dooley <conor+dt at kernel.org>; Sakari Ailus
> <sakari.ailus at linux.intel.com>; Hans Verkuil <hverkuil-cisco at xs4all.nl>;
> iwamatsu nobuhiro(?? ?? ?????????????)
> <nobuhiro1.iwamatsu at toshiba.co.jp>
> Cc: linux-media at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org
> Subject: Re: [PATCH v12 1/8] dt-bindings: media: platform: visconti: Add
> Toshiba Visconti MIPI CSI-2 Receiver
> 
> On 25/11/2024 10:21, Yuji Ishikawa wrote:
> > Adds the Device Tree binding documentation that allows to describe the
> > MIPI CSI-2 Receiver found in Toshiba Visconti SoCs.
> >
> > Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
> > Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> 
> 
> How newly added patch can have already Rb tag? Was this review really, really
> performed internally or you just satisfy some internal managers requirements
> and fake the stats?
> 

I added this Reviewed-by tag because the patch was reviewed internally.

> > ---
> >
> > Changelog v12:
> > - Newly add bindings for CSI2RX driver
> >
> >  .../media/toshiba,visconti5-csi2rx.yaml       | 104
> ++++++++++++++++++
> >  1 file changed, 104 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/media/toshiba,visconti5-csi2rx.yaml
> >
> > diff --git
> > a/Documentation/devicetree/bindings/media/toshiba,visconti5-csi2rx.yam
> > l
> > b/Documentation/devicetree/bindings/media/toshiba,visconti5-csi2rx.yam
> > l
> > new file mode 100644
> > index 000000000000..5488072bc82a
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/toshiba,visconti5-csi2rx
> > +++ .yaml
> > @@ -0,0 +1,104 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id:
> > +http://devicetree.org/schemas/media/toshiba,visconti5-csi2rx.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Toshiba Visconti5 SoC MIPI CSI-2 receiver
> > +
> > +maintainers:
> > +  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> > +
> > +description: |-
> 
> Drop |-
> 

I'll drop "|-"

> > +  Toshiba Visconti5 SoC MIPI CSI-2 receiver device receives MIPI
> > + CSI-2 video  stream. Use with VIIF device. T.B.D
> > +
> > +properties:
> > +  compatible:
> > +    const: toshiba,visconti5-csi2rx
> 
> Why this is called "RX"? Can you have a TX? I had impression that one cannot.
> 

VIIF has only MIPI CSI2 receiver (CSI2RX). There's no TX for it.
Visconti also has VOIF (Video Output Interface) hardware which has MIPI CSI2 (not DSI) transmitter (CSI2TX).

> > +
> > +  reg:
> > +    items:
> > +      - description: Registers for CSI2 receiver control
> > +
> > +  interrupts:
> > +    items:
> > +      - description: CSI2 Receiver Interrupt
> > +
> > +  ports:
> > +    $ref: /schemas/graph.yaml#/properties/ports
> > +
> > +    properties:
> > +      port at 0:
> > +        $ref: /schemas/graph.yaml#/$defs/port-base
> > +        unevaluatedProperties: false
> > +        description:
> > +          Input port node, single endpoint describing the CSI-2
> transmitter.
> > +
> > +        properties:
> > +          endpoint:
> > +            $ref: video-interfaces.yaml#
> > +            unevaluatedProperties: false
> > +
> > +            properties:
> > +              data-lanes:
> > +                description: CSI2 receiver supports 1, 2, 3 or 4 data lanes
> > +                minItems: 1
> > +                items:
> > +                  - const: 1
> > +                  - const: 2
> > +                  - const: 3
> > +                  - const: 4
> > +            required:
> > +              - data-lanes
> > +
> > +      port at 1:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description:
> > +          Output port node, single endpoint describing the Visconti VIIF.
> > +
> > +    required:
> > +      - port at 0
> > +      - port at 1
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +
> > +    soc {
> > +        #address-cells = <2>;
> > +        #size-cells = <2>;
> > +
> > +        csi2rx at 1c008000 {
> 
> 
> csi@
> 
> 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-devicetre
> e-basics.html#generic-names-recommendation
> 

I'll fix the node names.

> 
> Best regards,
> Krzysztof


Best regards,
Yuji Ishikawa

From yuji2.ishikawa at toshiba.co.jp  Mon Dec 16 16:00:16 2024
From: yuji2.ishikawa at toshiba.co.jp (yuji2.ishikawa at toshiba.co.jp)
Date: Tue, 17 Dec 2024 00:00:16 +0000
Subject: [PATCH v12 2/8] dt-bindings: media: platform: visconti: Add
 Toshiba Visconti Video Input Interface
In-Reply-To: <04a7ebf7-2924-4894-bc53-ba77e2f64fae@kernel.org>
References: <20241125092146.1561901-1-yuji2.ishikawa@toshiba.co.jp>
 <20241125092146.1561901-3-yuji2.ishikawa@toshiba.co.jp>
 <04a7ebf7-2924-4894-bc53-ba77e2f64fae@kernel.org>
Message-ID: <TY3PR01MB99822E6161ED319B4DE855B492042@TY3PR01MB9982.jpnprd01.prod.outlook.com>

Hello Krzysztof

Thank you for your review

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk at kernel.org>
> Sent: Monday, November 25, 2024 7:08 PM
> To: ishikawa yuji(?? ?? ?????????????)
> <yuji2.ishikawa at toshiba.co.jp>; Laurent Pinchart
> <laurent.pinchart at ideasonboard.com>; Mauro Carvalho Chehab
> <mchehab at kernel.org>; Rob Herring <robh at kernel.org>; Krzysztof Kozlowski
> <krzk+dt at kernel.org>; Conor Dooley <conor+dt at kernel.org>; Sakari Ailus
> <sakari.ailus at linux.intel.com>; Hans Verkuil <hverkuil-cisco at xs4all.nl>;
> iwamatsu nobuhiro(?? ?? ?????????????)
> <nobuhiro1.iwamatsu at toshiba.co.jp>
> Cc: linux-media at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org
> Subject: Re: [PATCH v12 2/8] dt-bindings: media: platform: visconti: Add
> Toshiba Visconti Video Input Interface
> 
> On 25/11/2024 10:21, Yuji Ishikawa wrote:
> > Adds the Device Tree binding documentation that allows to describe the
> > Video Input Interface found in Toshiba Visconti SoCs.
> >
> > Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
> > Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> 
> Why this tag stayed and other was removed? What was the reason of tag
> removal?
> 

The stayed tag is due to internal review.
The removed tag is due to code's change (split of csi2rx part) after the last review.
If the code is largely changed following the instruction of another reviewer
after obtaining the tags, how should the tags be handled?

> > ---
> > Changelog v2:
> > - no change
> >
> > Changelog v3:
> > - no change
> >
> > Changelog v4:
> > - fix style problems at the v3 patch
> > - remove "index" member
> > - update example
> >
> > Changelog v5:
> > - no change
> >
> > Changelog v6:
> > - add register definition of BUS-IF and MPU
> >
> > Changelog v7:
> > - remove trailing "bindings" from commit header message
> > - remove trailing "Device Tree Bindings" from title
> > - fix text wrapping of description
> > - change compatible to visconti5-viif
> > - explicitly define allowed properties for port::endpoint
> >
> > Changelog v8:
> > - Suggestion from Krzysztof Kozlowski
> >   - rename bindings description file
> >   - use block style array instead of inline style
> >   - remove clock-lane (as it is fixed at position 0)
> >   - update sample node's name
> >   - use lowercase hex for literals
> > - Suggestion from Laurent Pinchart
> >   - update description message port::description
> >   - remove port::endpoint::bus-type as it is fixed to <4>
> >   - remove port::endpoint::clock-lanes from example
> >   - add port::endpoint::data-lanes to required parameters list
> >   - fix sequence of data-lanes: <1 2 3 4> because current driver does not
> support data reordering
> >   - update port::endpoint::data-lanes::description
> >   - remove redundant type definition for port::endpoint::data-lanes
> >
> > Changelog v9:
> > - place "required" after "properties"
> > - dictionary ordering of properties
> >
> > Changelog v10:
> > - no change
> >
> > Changelog v11:
> > - no change
> >
> > Changelog v12:
> > - remove property "clock-noncontinuous" as VIIF switches both modes
> > automatically
> > - remove property "link-frequencies" as VIIF does not use the
> > information
> 
> Driver does not use or hardware supports only one frequency?
> 

My comment was incorrect.
It should be "Driver does not use the information"

> > - remove reg[2] and interrupts[3] which are used for CSI2RX driver
> > - update example to refer csi2rx for remote-endpoint
> 
> Were these the reasons?
> 
> I am really surprised that after 11 versions this binding still is being totally
> reshaped and you need us to re-review.
>

Sorry for poor quality.
Several changes were brought about by the introduction of the CSI2RX driver.
The new driver was requested in the previous review.
The property "clock-noncontinuous" was pointed out as unnecessary (because HW supports both modes) in the previous review.
The property "link-frequencies" was dropped because It was found to be unused after re-check of the code.

> Also, start using b4 tool, so:
> 1. your cover letter will have proper links to previous versions 2. b4 diff would
> work. Look, try by yourself:
> 
> 
> 
> b4 diff '<20241125092146.1561901-3-yuji2.ishikawa at toshiba.co.jp>'
> Grabbing thread from
> lore.kernel.org/all/20241125092146.1561901-3-yuji2.ishikawa at toshiba.co.jp/t
> .mbox.gz
> Checking for older revisions
> Grabbing search results from lore.kernel.org
>   Added from v11: 7 patches
> ---
> Analyzing 144 messages in the thread
> Looking for additional code-review trailers on lore.kernel.org Analyzing 13
> code-review messages Preparing fake-am for v11: Add Toshiba Visconti Video
> Input Interface driver
>   range: e16e149ced15..4efb0d6768a6
> Preparing fake-am for v12: dt-bindings: media: platform: visconti: Add Toshiba
> Visconti MIPI CSI-2 Receiver
> ERROR: v12 series incomplete; unable to create a fake-am range
> ---
> Could not create fake-am range for upper series v12
> 
> 
> 
> How can I verify what happened here without too much effort?
> 
> 

I will use b4 tool for further submits.
Also I'll add links to previous versions in the cover letter.

I ran b4 diff with the HEAD of media_stage tree and confirmed that it produced non-error results.
I needed to fetch the tree to a certain depth to ensure everything worked smoothly.

$ git clone https://git.linuxtv.org/media_stage.git --depth 1
$ git fetch --shallow-exclude v6.4
$ git log --oneline | head -5
40384c840ea1 Linux 6.13-rc1
a14bf463e7df Merge tag 'i2c-for-6.13-rc1-part3' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
88862eeb4763 Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
f788b5ef1ca9 Merge tag 'timers_urgent_for_v6.13_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
63f4993b792e Merge tag 'irq_urgent_for_v6.13_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

$ b4 diff '<20241125092146.1561901-3-yuji2.ishikawa at toshiba.co.jp>'

> >
> >  .../media/toshiba,visconti5-viif.yaml         | 95
> +++++++++++++++++++
> >  1 file changed, 95 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/media/toshiba,visconti5-viif.yaml
> >
> > diff --git
> > a/Documentation/devicetree/bindings/media/toshiba,visconti5-viif.yaml
> > b/Documentation/devicetree/bindings/media/toshiba,visconti5-viif.yaml
> > new file mode 100644
> > index 000000000000..ef0452a47e98
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/toshiba,visconti5-viif.y
> > +++ aml
> > @@ -0,0 +1,95 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/media/toshiba,visconti5-viif.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Toshiba Visconti5 SoC Video Input Interface
> > +
> > +maintainers:
> > +  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> > +
> > +description: |-
> 
> Since you ask for re-review, then:
> 
> Drop |-
> 

I'll drop "|-"

> Best regards,
> Krzysztof

Best regards,
Yuji Ishikawa

From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:31 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:31 +0200
Subject: [PATCH v7 09/10] drm/vc4: hdmi: stop rereading EDID in get_modes()
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-9-cb9df2b6a515@linaro.org>

The vc4_hdmi_connector_detect_ctx() via vc4_hdmi_handle_hotplug()
already reads EDID and propagates it to the drm_connector. Stop
rereading EDID as a part of the .get_modes() callback and just update
the list of modes. This matches the behaviour of the i915 driver.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 2a2aca7017994779a7163935df3fc87ca312d6dd..bb5e8738845c74d975c1e0e1262ced46e4ef8fde 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -470,31 +470,10 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
 
 static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
-	const struct drm_edid *drm_edid;
 	int ret = 0;
 
-	/*
-	 * NOTE: This function should really take vc4_hdmi->mutex, but doing so
-	 * results in reentrancy issues since cec_s_phys_addr() might call
-	 * .adap_enable, which leads to that funtion being called with our mutex
-	 * held.
-	 *
-	 * Concurrency isn't an issue at the moment since we don't share
-	 * any state with any of the other frameworks so we can ignore
-	 * the lock for now.
-	 */
-
-	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
-	drm_edid_connector_update(connector, drm_edid);
-	cec_s_phys_addr(vc4_hdmi->cec_adap,
-			connector->display_info.source_physical_address, false);
-	if (!drm_edid)
-		return 0;
-
 	ret = drm_edid_connector_add_modes(connector);
-	drm_edid_free(drm_edid);
 
 	if (!vc4->hvs->vc5_hdmi_enable_hdmi_20) {
 		struct drm_device *drm = connector->dev;

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:32 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:32 +0200
Subject: [PATCH v7 10/10] drm/vc4: hdmi: use
 drm_atomic_helper_connector_hdmi_hotplug_edid()
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-10-cb9df2b6a515@linaro.org>

Use the helper function to update the connector's information. This
makes sure that HDMI-related events are handled in a generic way.
Currently it is limited to the HDMI state reporting to the sound system.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index bb5e8738845c74d975c1e0e1262ced46e4ef8fde..328a845ce0c4168b5463d344b3ad1f77a5437cff 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -383,7 +383,6 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
 				    enum drm_connector_status status)
 {
 	struct drm_connector *connector = &vc4_hdmi->connector;
-	const struct drm_edid *drm_edid;
 	int ret;
 
 	/*
@@ -405,17 +404,14 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
 		return;
 	}
 
-	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
+	drm_atomic_helper_connector_hdmi_hotplug(connector, status);
 
-	drm_edid_connector_update(connector, drm_edid);
 	cec_s_phys_addr(vc4_hdmi->cec_adap,
 			connector->display_info.source_physical_address, false);
 
-	if (!drm_edid)
+	if (status != connector_status_connected)
 		return;
 
-	drm_edid_free(drm_edid);
-
 	for (;;) {
 		ret = vc4_hdmi_reset_link(connector, ctx);
 		if (ret == -EDEADLK) {
@@ -549,6 +545,7 @@ static void vc4_hdmi_connector_reset(struct drm_connector *connector)
 }
 
 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
+	.force = drm_atomic_helper_connector_hdmi_force,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.reset = vc4_hdmi_connector_reset,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:22 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:22 +0200
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>

While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
framework, I stumbled upon an issue while handling the Audio InfoFrames.
The HDMI codec callbacks weren't receiving the drm_atomic_state, so
there was no simple way to get the drm_connector that stayed at the end
of the bridge chain. At the same point the drm_hdmi_connector functions
expected to get drm_connector instance.

While looking for a way to solve the issue, I stumbled upon several
deficiencies in existing hdmi_codec_ops implementations. Only few of the
implementations were able to handle codec's 'plugged' callback. One
third of the drivers didn't implement the get_eld() callback.

Most of the issues can be solved if drm_connector handles
hdmi-audio-codec on its own, delegating functionality to the actual
implementation, be it a driver that implements drm_connector or
drm_bridge.

Implement such high-level framework, adding proper support for Audio
InfoFrame generation to the LT9611 driver.

Several design decisions to be kept in mind:

- drm_connector_hdmi_codec is kept as simple as possible. It implements
  generic functionality (ELD, hotplug, registration).

- drm_hdmi_connector sets up HDMI codec device if the connector
  is setup correspondingly (either I2S or S/PDIF is marked as
  supported).

- drm_bridge_connector provides a way to link HDMI audio codec
  funcionality in the drm_bridge with the drm_connector_hdmi_codec
  framework.

- It might be worth reverting the no_i2s_capture / no_spdif_capture
  bits. Only TDA889x driver sets them, while it's safe to assume that
  most of HDMI / DP devices do not support ARC / capture. I think the
  drivers should opt-in capture support rather than having to opt-out of
  it.

This series depends on the ELD mutex series [1]

[1] https://lore.kernel.org/r/20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03 at linaro.org

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
Changes in v7:
- Renamed drm_connector_hdmi_codec_init() to
  drm_connector_hdmi_audio_init() (Maxime)
- Added extra empty line in struct drm_connector_hdmi_codec_funcs
  (Maxime)
- Dropped if/else from drm_bridge_connector_audio_startup() (Maxime)
- Added optional .read_edid() callback and reworked
  drm_atomic_helper_connector_hdmi_hotplug() to use that callback
  instead of having an internal function which accepts EDID (Maxime)
- Made VC4 and drm_bridge_connector use .force() in addition to
  .detect() and .detect_ctx().
- Moved HDMI codec functions out of struct drm_connector_hdmi_funcs.
  Assign them from drm_connector_hdmi_audio_init().
- Documented struct drm_connector_hdmi_codec and its fields.
- Link to v6: https://lore.kernel.org/r/20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06 at linaro.org

Changes in v6:
- Dropped extra checks on the EDID (Jani)
- Reworked drmm_connector_hdmi_init(), splitting the codec init to a
  separate optional function rather than passing arguments through
  drm_connector (Maxime)
- Reworked EDID update functions (Maxime, Jani)
- No longer refresh the EDID in vc4_hdmi_connector_get_modes(), it is
  redundant as vc4_hdmi_connector_detect_cxtx() already does that.
- Link to v5: https://lore.kernel.org/r/20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a at linaro.org

Changes in v5:
- Moved prototypes from drm_internal.h to
  drm_connector_hdmi_codec_internal.h (Jani)
- Rebased on top of ELD mutex series, resolving the long-standing FIXME
- Converted the VC4 driver (compile-tested only)
- Link to v4: https://lore.kernel.org/r/20241122-drm-bridge-hdmi-connector-v4-0-b4d69d6e3bd9 at linaro.org

Changes in v4:
- Added forward declaration of struct drm_edid (LKP)
- Fixed kerneldoc for drm_atomic_helper_connector_hdmi_update_edid().
- Link to v3: https://lore.kernel.org/r/20241109-drm-bridge-hdmi-connector-v3-0-c15afdca5884 at linaro.org

Changes in v3:
- Dropped RFC status
- Fixed drm_connector_hdmi_codec_init() kerneldoc (LKP)
- Dropped double underscore prefix from
  __drm_atomic_helper_connector_hdmi_update_edid() (Jani)
- Moved drm_edid_free() from
  drm_atomic_helper_connector_hdmi_update_edid() to the caller's side
  (Jani)
- Link to v2: https://lore.kernel.org/r/20241101-drm-bridge-hdmi-connector-v2-0-739ef9addf9e at linaro.org

Changes in v2:
- Use drm_atomic_get_old_connector_for_encoder in atomic_disable() to
  prevent it from crashing
- Reworked HDMI codec init/exit, removing drmm_ calls (Maxime)
- Drafted the helper to be called from .detect_ctx() that performs HDMI
  Connector maintenance duties (Maxime)
- Moved no_capture_mute to struct hdmi_codec_pdata
- Link to v1: https://lore.kernel.org/r/20240615-drm-bridge-hdmi-connector-v1-0-d59fc7865ab2 at linaro.org

---
Dmitry Baryshkov (10):
      ASoC: hdmi-codec: pass data to get_dai_id too
      ASoC: hdmi-codec: move no_capture_mute to struct hdmi_codec_pdata
      drm/connector: implement generic HDMI codec helpers
      drm/bridge: connector: add support for HDMI codec framework
      drm/bridge: lt9611: switch to using the DRM HDMI codec framework
      drm/display/hdmi: implement hotplug functions
      drm/bridge_connector: hook drm_atomic_helper_connector_hdmi_hotplug()
      drm/vc4: hdmi: switch to using generic HDMI Codec infrastructure
      drm/vc4: hdmi: stop rereading EDID in get_modes()
      drm/vc4: hdmi: use drm_atomic_helper_connector_hdmi_hotplug_edid()

 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c     |   3 +-
 drivers/gpu/drm/bridge/analogix/anx7625.c          |   3 +-
 drivers/gpu/drm/bridge/ite-it66121.c               |   2 +-
 drivers/gpu/drm/bridge/lontium-lt9611.c            | 169 ++++++++----------
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c         |   3 +-
 drivers/gpu/drm/bridge/sii902x.c                   |   5 +-
 .../gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c    |   3 +-
 drivers/gpu/drm/display/drm_bridge_connector.c     | 137 ++++++++++++++-
 drivers/gpu/drm/display/drm_hdmi_state_helper.c    |  56 ++++++
 drivers/gpu/drm/drm_connector.c                    |   5 +
 drivers/gpu/drm/drm_connector_hdmi_codec.c         | 189 +++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_hdmi.c               |   2 +-
 drivers/gpu/drm/i2c/tda998x_drv.c                  |   2 +-
 drivers/gpu/drm/mediatek/mtk_dp.c                  |   2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c                |   2 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c             |   2 +-
 drivers/gpu/drm/sti/sti_hdmi.c                     |   2 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c                     |  99 +++--------
 drivers/gpu/drm/vc4/vc4_hdmi.h                     |   2 -
 include/drm/display/drm_hdmi_state_helper.h        |   5 +
 include/drm/drm_bridge.h                           |  38 +++++
 include/drm/drm_connector.h                        | 141 +++++++++++++++
 include/sound/hdmi-codec.h                         |   7 +-
 sound/soc/codecs/hdmi-codec.c                      |   4 +-
 25 files changed, 678 insertions(+), 206 deletions(-)
---
base-commit: 81a9a93b169a273ccc4a9a1ee56f17e9981d3f98
change-id: 20240530-drm-bridge-hdmi-connector-9b0f6725973e

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:23 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:23 +0200
Subject: [PATCH v7 01/10] ASoC: hdmi-codec: pass data to get_dai_id too
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-1-cb9df2b6a515@linaro.org>

The upcoming DRM connector HDMI codec implementation is going to use
codec-specific data in the .get_dai_id to get drm_connector. Pass data
to the callback, as it is done with other hdmi_codec_ops callbacks.

Acked-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c      | 3 ++-
 drivers/gpu/drm/bridge/analogix/anx7625.c           | 3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611.c             | 3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c          | 3 ++-
 drivers/gpu/drm/bridge/sii902x.c                    | 3 ++-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 3 ++-
 include/sound/hdmi-codec.h                          | 3 ++-
 sound/soc/codecs/hdmi-codec.c                       | 2 +-
 8 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
index 61f4a38e7d2bf6905683cbc9e762b28ecc999d05..51fb9a574b4e28450b2598a92e2930ace5128b71 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -204,7 +204,8 @@ static void audio_shutdown(struct device *dev, void *data)
 }
 
 static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-					struct device_node *endpoint)
+					struct device_node *endpoint,
+					void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 6238eabd23282d5f7e59a05d267737f40211aaf3..d65680d1bc8f2f27927b8a9d6926b72531791614 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1952,7 +1952,8 @@ static void anx7625_audio_shutdown(struct device *dev, void *data)
 }
 
 static int anx7625_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				       struct device_node *endpoint)
+				       struct device_node *endpoint,
+				       void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 74f726efc74613460a6eb9c41f0bbad2ab06208f..698a9a01783d28edc734b6932a7768978de65ffc 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -1057,7 +1057,8 @@ static void lt9611_audio_shutdown(struct device *dev, void *data)
 }
 
 static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				      struct device_node *endpoint)
+				      struct device_node *endpoint,
+				      void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index db9a5466060b663e88d58e85f24bf2d58d74a81c..f4c3ff1fdc6923eb7a8c0d8f7f92e7649c797d77 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -522,7 +522,8 @@ static void lt9611uxc_audio_shutdown(struct device *dev, void *data)
 }
 
 static int lt9611uxc_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-					 struct device_node *endpoint)
+					 struct device_node *endpoint,
+					 void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 127da22011b3235b049c38413e56d50414cf36fb..a02d30c0ba4221d7fee0eb50892ab4d8e8436004 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -815,7 +815,8 @@ static int sii902x_audio_get_eld(struct device *dev, void *data,
 }
 
 static int sii902x_audio_get_dai_id(struct snd_soc_component *component,
-				    struct device_node *endpoint)
+				    struct device_node *endpoint,
+				    void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index f1c5a8d0fa90e2eb2ee488b6a5871b005f797ea1..2c903c9fe8052ab721445188fd2b75270a55f2b0 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -148,7 +148,8 @@ static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, uint8_t *buf,
 }
 
 static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				  struct device_node *endpoint)
+				  struct device_node *endpoint,
+				  void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index 5e1a9eafd10f5d4f831abbb6f4c0fff661909584..b3407b47b4a7878532ecf3b08eeecd443d6fdb07 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -105,7 +105,8 @@ struct hdmi_codec_ops {
 	 * Optional
 	 */
 	int (*get_dai_id)(struct snd_soc_component *comment,
-			  struct device_node *endpoint);
+			  struct device_node *endpoint,
+			  void *data);
 
 	/*
 	 * Hook callback function to handle connector plug event.
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index d9df29a26f4f213a30a2ebcdb63a593f9cf4b901..f536ca60e162dca6b50b37854ca6de2c114bc2a1 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -995,7 +995,7 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
 	int ret = -ENOTSUPP; /* see snd_soc_get_dai_id() */
 
 	if (hcp->hcd.ops->get_dai_id)
-		ret = hcp->hcd.ops->get_dai_id(component, endpoint);
+		ret = hcp->hcd.ops->get_dai_id(component, endpoint, hcp->hcd.data);
 
 	return ret;
 }

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:24 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:24 +0200
Subject: [PATCH v7 02/10] ASoC: hdmi-codec: move no_capture_mute to struct
 hdmi_codec_pdata
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-2-cb9df2b6a515@linaro.org>

The no_capture_mute flag might differ from platform to platform,
especially in the case of the wrapping implementations, like the
upcoming DRM HDMI Codec framework. Move the flag next to all other flags
in struct hdmi_codec_pdata.

Acked-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/ite-it66121.c   | 2 +-
 drivers/gpu/drm/bridge/sii902x.c       | 2 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c   | 2 +-
 drivers/gpu/drm/i2c/tda998x_drv.c      | 2 +-
 drivers/gpu/drm/mediatek/mtk_dp.c      | 2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c    | 2 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +-
 drivers/gpu/drm/sti/sti_hdmi.c         | 2 +-
 include/sound/hdmi-codec.h             | 4 +---
 sound/soc/codecs/hdmi-codec.c          | 2 +-
 10 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c
index 940083e5d2ddbfc56f14e2bdc6ddd0b9dd50b1f8..7734e389ca7692f7880aa9b8650e45aab228c7fd 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -1466,7 +1466,6 @@ static const struct hdmi_codec_ops it66121_audio_codec_ops = {
 	.audio_shutdown = it66121_audio_shutdown,
 	.mute_stream = it66121_audio_mute,
 	.get_eld = it66121_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev)
@@ -1476,6 +1475,7 @@ static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev)
 		.i2s = 1, /* Only i2s support for now */
 		.spdif = 0,
 		.max_i2s_channels = 8,
+		.no_capture_mute = 1,
 	};
 
 	dev_dbg(dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index a02d30c0ba4221d7fee0eb50892ab4d8e8436004..2a0af0f09defa2994ddece755ecf9742b418473b 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -841,7 +841,6 @@ static const struct hdmi_codec_ops sii902x_audio_codec_ops = {
 	.mute_stream = sii902x_audio_mute,
 	.get_eld = sii902x_audio_get_eld,
 	.get_dai_id = sii902x_audio_get_dai_id,
-	.no_capture_mute = 1,
 };
 
 static int sii902x_audio_codec_init(struct sii902x *sii902x,
@@ -864,6 +863,7 @@ static int sii902x_audio_codec_init(struct sii902x *sii902x,
 		.i2s = 1, /* Only i2s support for now. */
 		.spdif = 0,
 		.max_i2s_channels = 0,
+		.no_capture_mute = 1,
 	};
 	u8 lanes[4];
 	int num_lanes, i;
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 7a57d4a23e410db1d4d3a11bb9285d34c784f2d5..176fd88717597c37824fbf825ca6b893b083e0ca 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1660,7 +1660,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = hdmi_audio_shutdown,
 	.mute_stream = hdmi_audio_mute,
 	.get_eld = hdmi_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int hdmi_register_audio_device(struct hdmi_context *hdata)
@@ -1669,6 +1668,7 @@ static int hdmi_register_audio_device(struct hdmi_context *hdata)
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 6,
 		.i2s = 1,
+		.no_capture_mute = 1,
 	};
 
 	hdata->audio.pdev = platform_device_register_data(
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 57ce77c2be2458fff5b752332ae51e016582ddca..82d4a4e206a584e045a8fcd593fc12b7c1257bfe 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1165,7 +1165,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = tda998x_audio_shutdown,
 	.mute_stream = tda998x_audio_mute_stream,
 	.get_eld = tda998x_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int tda998x_audio_codec_init(struct tda998x_priv *priv,
@@ -1176,6 +1175,7 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
 		.max_i2s_channels = 2,
 		.no_i2s_capture = 1,
 		.no_spdif_capture = 1,
+		.no_capture_mute = 1,
 	};
 
 	if (priv->audio_port_enable[AUDIO_ROUTE_I2S])
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 36713c176cfcf1af2d365280700d06f4c1239e09..5c805094daf6d4678355fec43648552b34508bec 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -2615,7 +2615,6 @@ static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = {
 	.audio_shutdown = mtk_dp_audio_shutdown,
 	.get_eld = mtk_dp_audio_get_eld,
 	.hook_plugged_cb = mtk_dp_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int mtk_dp_register_audio_driver(struct device *dev)
@@ -2626,6 +2625,7 @@ static int mtk_dp_register_audio_driver(struct device *dev)
 		.max_i2s_channels = 8,
 		.i2s = 1,
 		.data = mtk_dp,
+		.no_capture_mute = 1,
 	};
 
 	mtk_dp->audio_pdev = platform_device_register_data(dev,
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 70dc1d4460adfc04b5c40263d11184aae826c658..ca82bc829cb96446d4d34eeef45848df03bd716b 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1660,7 +1660,6 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
 	.mute_stream = mtk_hdmi_audio_mute,
 	.get_eld = mtk_hdmi_audio_get_eld,
 	.hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int mtk_hdmi_register_audio_driver(struct device *dev)
@@ -1671,6 +1670,7 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
 		.max_i2s_channels = 2,
 		.i2s = 1,
 		.data = hdmi,
+		.no_capture_mute = 1,
 	};
 	struct platform_device *pdev;
 
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b76337f690ec2fdfbf4dac08a04aa4de4eff257f..b17de83b988b1f1afb2f6d12b1d155761ff9ca50 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -885,7 +885,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.mute_stream = cdn_dp_audio_mute_stream,
 	.get_eld = cdn_dp_audio_get_eld,
 	.hook_plugged_cb = cdn_dp_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
@@ -896,6 +895,7 @@ static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
 		.spdif = 1,
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 8,
+		.no_capture_mute = 1,
 	};
 
 	dp->audio_pdev = platform_device_register_data(
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index f8bbae6393ef8c0bd1deb75d1e131c1d83c1ebfe..ca2fe17de4a5d1e0199e59a97e6c7601e139ed9e 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -1237,7 +1237,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = hdmi_audio_shutdown,
 	.mute_stream = hdmi_audio_mute,
 	.get_eld = hdmi_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int sti_hdmi_register_audio_driver(struct device *dev,
@@ -1247,6 +1246,7 @@ static int sti_hdmi_register_audio_driver(struct device *dev,
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 8,
 		.i2s = 1,
+		.no_capture_mute = 1,
 	};
 
 	DRM_DEBUG_DRIVER("\n");
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index b3407b47b4a7878532ecf3b08eeecd443d6fdb07..b220072cfa1baf503efbe2d530d7e8392dc16603 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -115,9 +115,6 @@ struct hdmi_codec_ops {
 	int (*hook_plugged_cb)(struct device *dev, void *data,
 			       hdmi_codec_plugged_cb fn,
 			       struct device *codec_dev);
-
-	/* bit field */
-	unsigned int no_capture_mute:1;
 };
 
 /* HDMI codec initalization data */
@@ -129,6 +126,7 @@ struct hdmi_codec_pdata {
 	uint spdif:1;
 	uint no_spdif_playback:1;
 	uint no_spdif_capture:1;
+	uint no_capture_mute:1;
 	int max_i2s_channels;
 	void *data;
 };
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index f536ca60e162dca6b50b37854ca6de2c114bc2a1..69f98975e14ae367f482862724a358eb138ebf6a 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -714,7 +714,7 @@ static int hdmi_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
 	 */
 	if (hcp->hcd.ops->mute_stream &&
 	    (direction == SNDRV_PCM_STREAM_PLAYBACK ||
-	     !hcp->hcd.ops->no_capture_mute))
+	     !hcp->hcd.no_capture_mute))
 		return hcp->hcd.ops->mute_stream(dai->dev->parent,
 						 hcp->hcd.data,
 						 mute, direction);

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:25 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:25 +0200
Subject: [PATCH v7 03/10] drm/connector: implement generic HDMI codec
 helpers
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-3-cb9df2b6a515@linaro.org>

Several DRM drivers implement HDMI codec support (despite its name it
applies to both HDMI and DisplayPort drivers). Implement generic
framework to be used by these drivers. This removes a requirement to
implement get_eld() callback and provides default implementation for
codec's plug handling.

The framework is integrated with the DRM HDMI Connector framework, but
can be used by DisplayPort drivers.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/Makefile                   |   1 +
 drivers/gpu/drm/drm_connector.c            |   5 +
 drivers/gpu/drm/drm_connector_hdmi_codec.c | 189 +++++++++++++++++++++++++++++
 include/drm/drm_connector.h                | 125 +++++++++++++++++++
 4 files changed, 320 insertions(+)

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 19fb370fbc56772077973c864df71e4b8e0bf99b..46e6dbc355afe4015ff2327ba04211cdc011a0b7 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -42,6 +42,7 @@ drm-y := \
 	drm_cache.o \
 	drm_color_mgmt.o \
 	drm_connector.o \
+	drm_connector_hdmi_codec.o \
 	drm_crtc.o \
 	drm_displayid.o \
 	drm_drv.o \
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index bbdaaf7022b62d84594a29f1b60144920903a99a..4abfbded962bf45b793a2bd5b1b5c4d9f478a1f7 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -33,6 +33,7 @@
 #include <drm/drm_sysfs.h>
 #include <drm/drm_utils.h>
 
+#include <linux/platform_device.h>
 #include <linux/property.h>
 #include <linux/uaccess.h>
 
@@ -280,6 +281,7 @@ static int __drm_connector_init(struct drm_device *dev,
 	mutex_init(&connector->eld_mutex);
 	mutex_init(&connector->edid_override_mutex);
 	mutex_init(&connector->hdmi.infoframes.lock);
+	mutex_init(&connector->hdmi_codec.lock);
 	connector->edid_blob_ptr = NULL;
 	connector->epoch_counter = 0;
 	connector->tile_blob_ptr = NULL;
@@ -632,6 +634,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		    DRM_CONNECTOR_REGISTERED))
 		drm_connector_unregister(connector);
 
+	platform_device_unregister(connector->hdmi_codec.codec_pdev);
+
 	if (connector->privacy_screen) {
 		drm_privacy_screen_put(connector->privacy_screen);
 		connector->privacy_screen = NULL;
@@ -670,6 +674,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		connector->funcs->atomic_destroy_state(connector,
 						       connector->state);
 
+	mutex_destroy(&connector->hdmi_codec.lock);
 	mutex_destroy(&connector->hdmi.infoframes.lock);
 	mutex_destroy(&connector->mutex);
 
diff --git a/drivers/gpu/drm/drm_connector_hdmi_codec.c b/drivers/gpu/drm/drm_connector_hdmi_codec.c
new file mode 100644
index 0000000000000000000000000000000000000000..a6e2f27c3f7ff9d57cf19c055870001daff4c676
--- /dev/null
+++ b/drivers/gpu/drm/drm_connector_hdmi_codec.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2024 Linaro Ltd
+ */
+
+#include <linux/mutex.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+
+#include <drm/drm_connector.h>
+#include <drm/drm_device.h>
+
+#include <sound/hdmi-codec.h>
+
+static int drm_connector_hdmi_codec_audio_startup(struct device *dev, void *data)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_codec_funcs *funcs =
+		connector->hdmi_codec.funcs;
+
+	if (funcs->audio_startup)
+		return funcs->audio_startup(connector);
+
+	return 0;
+}
+
+static int drm_connector_hdmi_codec_prepare(struct device *dev, void *data,
+					    struct hdmi_codec_daifmt *fmt,
+					    struct hdmi_codec_params *hparms)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_codec_funcs *funcs =
+		connector->hdmi_codec.funcs;
+
+	return funcs->prepare(connector, fmt, hparms);
+}
+
+static void drm_connector_hdmi_codec_audio_shutdown(struct device *dev, void *data)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_codec_funcs *funcs =
+		connector->hdmi_codec.funcs;
+
+	return funcs->audio_shutdown(connector);
+}
+
+static int drm_connector_hdmi_codec_mute_stream(struct device *dev, void *data,
+						bool enable, int direction)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_codec_funcs *funcs =
+		connector->hdmi_codec.funcs;
+
+	if (funcs->mute_stream)
+		return funcs->mute_stream(connector, enable, direction);
+
+	return -ENOTSUPP;
+}
+
+static int drm_connector_hdmi_codec_get_dai_id(struct snd_soc_component *comment,
+		  struct device_node *endpoint,
+		  void *data)
+{
+	struct drm_connector *connector = data;
+	struct of_endpoint of_ep;
+	int ret;
+
+	if (connector->hdmi_codec.dai_port < 0)
+		return -ENOTSUPP;
+
+	ret = of_graph_parse_endpoint(endpoint, &of_ep);
+	if (ret < 0)
+		return ret;
+
+	if (of_ep.port == connector->hdmi_codec.dai_port)
+		return 0;
+
+	return -EINVAL;
+}
+
+static int drm_connector_hdmi_codec_get_eld(struct device *dev, void *data,
+					    uint8_t *buf, size_t len)
+{
+	struct drm_connector *connector = data;
+
+	mutex_lock(&connector->eld_mutex);
+	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
+	mutex_unlock(&connector->eld_mutex);
+
+	return 0;
+}
+
+static int drm_connector_hdmi_codec_hook_plugged_cb(struct device *dev,
+						    void *data,
+						    hdmi_codec_plugged_cb fn,
+						    struct device *codec_dev)
+{
+	struct drm_connector *connector = data;
+
+	mutex_lock(&connector->hdmi_codec.lock);
+
+	connector->hdmi_codec.plugged_cb = fn;
+	connector->hdmi_codec.plugged_cb_dev = codec_dev;
+
+	fn(codec_dev, connector->hdmi_codec.last_state);
+
+	mutex_unlock(&connector->hdmi_codec.lock);
+
+	return 0;
+}
+
+void drm_connector_hdmi_codec_plugged_notify(struct drm_connector *connector,
+					     bool plugged)
+{
+	mutex_lock(&connector->hdmi_codec.lock);
+
+	connector->hdmi_codec.last_state = plugged;
+
+	if (connector->hdmi_codec.plugged_cb &&
+	    connector->hdmi_codec.plugged_cb_dev)
+		connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev,
+						 connector->hdmi_codec.last_state);
+
+	mutex_unlock(&connector->hdmi_codec.lock);
+}
+EXPORT_SYMBOL(drm_connector_hdmi_codec_plugged_notify);
+
+static const struct hdmi_codec_ops drm_connector_hdmi_codec_ops = {
+	.audio_startup = drm_connector_hdmi_codec_audio_startup,
+	.prepare = drm_connector_hdmi_codec_prepare,
+	.audio_shutdown = drm_connector_hdmi_codec_audio_shutdown,
+	.mute_stream = drm_connector_hdmi_codec_mute_stream,
+	.get_eld = drm_connector_hdmi_codec_get_eld,
+	.get_dai_id = drm_connector_hdmi_codec_get_dai_id,
+	.hook_plugged_cb = drm_connector_hdmi_codec_hook_plugged_cb,
+};
+
+/**
+ * drm_connector_hdmi_audio_init - Initialize HDMI Codec device for the DRM connector
+ * @connector: A pointer to the connector to allocate codec for
+ * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
+ * @funcs: callbacks for this HDMI Codec
+ * @max_i2s_playback_channels: maximum number of playback I2S channels
+ * @spdif_playback: set if HDMI codec has S/PDIF playback port
+ * @dai_port: sound DAI port, -1 if it is not enabled
+ *
+ * Create a HDMI codec device to be used with the specified connector.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_connector_hdmi_audio_init(struct drm_connector *connector,
+				  struct device *hdmi_codec_dev,
+				  const struct drm_connector_hdmi_codec_funcs *funcs,
+				  unsigned int max_i2s_playback_channels,
+				  bool spdif_playback,
+				  int dai_port)
+{
+	struct hdmi_codec_pdata codec_pdata = {
+		.ops = &drm_connector_hdmi_codec_ops,
+		.max_i2s_channels = max_i2s_playback_channels,
+		.i2s = !!max_i2s_playback_channels,
+		.spdif = spdif_playback,
+		.no_i2s_capture = true,
+		.no_spdif_capture = true,
+		.data = connector,
+	};
+	struct platform_device *pdev;
+
+	if (!funcs ||
+	    !funcs->prepare ||
+	    !funcs->audio_shutdown)
+		return -EINVAL;
+
+	connector->hdmi_codec.funcs = funcs;
+	connector->hdmi_codec.dai_port = dai_port;
+
+	pdev = platform_device_register_data(hdmi_codec_dev,
+					     HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO,
+					     &codec_pdata, sizeof(codec_pdata));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	connector->hdmi_codec.codec_pdev = pdev;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_hdmi_audio_init);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 1e2b25e204cb523d61d30f5409faa059bf2b86eb..536d604b6fb27368c43805a2ecf57fac06b3d472 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -46,6 +46,8 @@ struct drm_property_blob;
 struct drm_printer;
 struct drm_privacy_screen;
 struct edid;
+struct hdmi_codec_daifmt;
+struct hdmi_codec_params;
 struct i2c_adapter;
 
 enum drm_connector_force {
@@ -1141,6 +1143,53 @@ struct drm_connector_state {
 	struct drm_connector_hdmi_state hdmi;
 };
 
+struct drm_connector_hdmi_codec_funcs {
+	/**
+	 * @audio_startup:
+	 *
+	 * Called when ASoC starts an audio stream setup. The
+	 * @hdmi_audio_startup is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*audio_startup)(struct drm_connector *connector);
+
+	/**
+	 * @prepare:
+	 * Configures HDMI-encoder for audio stream. Can be called
+	 * multiple times for each setup. Mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*prepare)(struct drm_connector *connector,
+		       struct hdmi_codec_daifmt *fmt,
+		       struct hdmi_codec_params *hparms);
+
+	/**
+	 * @audio_shutdown:
+	 *
+	 * Shut down the audio stream. Mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	void (*audio_shutdown)(struct drm_connector *connector);
+
+	/**
+	 * @mute_stream:
+	 *
+	 * Mute/unmute HDMI audio stream. The @mute_stream callback is
+	 * optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*mute_stream)(struct drm_connector *connector,
+			   bool enable, int direction);
+};
+
 /**
  * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
  */
@@ -1660,6 +1709,68 @@ struct drm_cmdline_mode {
 	bool tv_mode_specified;
 };
 
+/**
+ * struct drm_connector_hdmi_codec - DRM gemeric HDMI Codec-related structure
+ *
+ * HDMI drivers usually incorporate a HDMI Codec. This structure expresses the
+ * generic HDMI Codec as used by the DRM HDMI Codec framework.
+ */
+struct drm_connector_hdmi_codec {
+	/**
+	 * @funcs:
+	 *
+	 * Implementation of the HDMI codec functionality to be used by the DRM
+	 * HDMI Codec framework.
+	 */
+	const struct drm_connector_hdmi_codec_funcs *funcs;
+
+	/**
+	 * @codec_pdev:
+	 *
+	 * Platform device created to hold the HDMI Codec. It will be
+	 * automatically unregistered during drm_connector_cleanup().
+	 */
+	struct platform_device *codec_pdev;
+
+	/**
+	 * @lock:
+	 *
+	 * Mutex to protect @last_state, @plugged_cb and @plugged_cb_dev.
+	 */
+	struct mutex lock;
+
+	/**
+	 * @plugged_cb:
+	 *
+	 * Callback to be called when the HDMI sink get plugged to or unplugged
+	 * from this connector. This is assigned by the framework when
+	 * requested by the ASoC code.
+	 */
+	void (*plugged_cb)(struct device *dev, bool plugged);
+
+	/**
+	 * @plugged_cb_dev:
+	 *
+	 * The data for @plugged_cb(). It is being provided by the ASoC.
+	 */
+	struct device *plugged_cb_dev;
+
+	/**
+	 * @last_state:
+	 *
+	 * Last plugged state recored by the framework. It is used to correctly
+	 * report the state to @plugged_cb().
+	 */
+	bool last_state;
+
+	/**
+	 * @dai_port:
+	 *
+	 * The port in DT that is used for the Codec DAI.
+	 */
+	int dai_port;
+};
+
 /*
  * struct drm_connector_hdmi - DRM Connector HDMI-related structure
  */
@@ -2121,6 +2232,11 @@ struct drm_connector {
 	 * @hdmi: HDMI-related variable and properties.
 	 */
 	struct drm_connector_hdmi hdmi;
+
+	/**
+	 * @hdmi_codec: HDMI codec properties and non-DRM state.
+	 */
+	struct drm_connector_hdmi_codec hdmi_codec;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -2148,12 +2264,21 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct i2c_adapter *ddc,
 			     unsigned long supported_formats,
 			     unsigned int max_bpc);
+int drm_connector_hdmi_audio_init(struct drm_connector *connector,
+				  struct device *hdmi_codec_dev,
+				  const struct drm_connector_hdmi_codec_funcs *funcs,
+				  unsigned int max_i2s_playback_channels,
+				  bool spdif_playback,
+				  int sound_dai_port);
 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);
 int drm_connector_attach_encoder(struct drm_connector *connector,
 				      struct drm_encoder *encoder);
 
+void drm_connector_hdmi_codec_plugged_notify(struct drm_connector *connector,
+					     bool plugged);
+
 void drm_connector_cleanup(struct drm_connector *connector);
 
 static inline unsigned int drm_connector_index(const struct drm_connector *connector)

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:26 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:26 +0200
Subject: [PATCH v7 04/10] drm/bridge: connector: add support for HDMI codec
 framework
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-4-cb9df2b6a515@linaro.org>

Add necessary glue code to be able to use new HDMI codec framework from
the DRM bridge drivers. The drm_bridge implements a limited set of the
hdmi_codec_ops interface, with the functions accepting both
drm_connector and drm_bridge instead of just a generic void pointer.

This framework is integrated with the DRM HDMI Connector framework, but
can also be used for DisplayPort connectors.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 98 ++++++++++++++++++++++++--
 include/drm/drm_bridge.h                       | 38 ++++++++++
 2 files changed, 132 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 512ced87ea18c74e182a558a686ddd83de891814..be46d2e7cb5cec262ca5dd6f42f8f31b0187a0f7 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -374,6 +374,75 @@ static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
 	.write_infoframe = drm_bridge_connector_write_infoframe,
 };
 
+static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	if (!bridge->funcs->hdmi_codec_audio_startup)
+		return 0;
+
+	return bridge->funcs->hdmi_codec_audio_startup(connector, bridge);
+}
+
+static int drm_bridge_connector_prepare(struct drm_connector *connector,
+					struct hdmi_codec_daifmt *fmt,
+					struct hdmi_codec_params *hparms)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	return bridge->funcs->hdmi_codec_prepare(connector, bridge, fmt, hparms);
+}
+
+static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return;
+
+	bridge->funcs->hdmi_codec_audio_shutdown(connector, bridge);
+}
+
+static int drm_bridge_connector_mute_stream(struct drm_connector *connector,
+					    bool enable, int direction)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	if (bridge->funcs->hdmi_codec_mute_stream)
+		return bridge->funcs->hdmi_codec_mute_stream(connector, bridge,
+							     enable, direction);
+	else
+		return -ENOTSUPP;
+}
+
+static const struct drm_connector_hdmi_codec_funcs drm_bridge_connector_hdmi_codec_funcs = {
+	.audio_startup = drm_bridge_connector_audio_startup,
+	.prepare = drm_bridge_connector_prepare,
+	.audio_shutdown = drm_bridge_connector_audio_shutdown,
+	.mute_stream = drm_bridge_connector_mute_stream,
+};
+
 /* -----------------------------------------------------------------------------
  * Bridge Connector Initialisation
  */
@@ -473,7 +542,9 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
 		return ERR_PTR(-EINVAL);
 
-	if (bridge_connector->bridge_hdmi)
+	if (bridge_connector->bridge_hdmi) {
+		bridge = bridge_connector->bridge_hdmi;
+
 		ret = drmm_connector_hdmi_init(drm, connector,
 					       bridge_connector->bridge_hdmi->vendor,
 					       bridge_connector->bridge_hdmi->product,
@@ -482,12 +553,31 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 					       connector_type, ddc,
 					       supported_formats,
 					       max_bpc);
-	else
+		if (ret)
+			return ERR_PTR(ret);
+
+		if (bridge->hdmi_codec_max_i2s_playback_channels ||
+		    bridge->hdmi_codec_spdif_playback) {
+			if (!bridge->funcs->hdmi_codec_prepare ||
+			    !bridge->funcs->hdmi_codec_audio_shutdown)
+				return ERR_PTR(-EINVAL);
+
+			ret = drm_connector_hdmi_audio_init(connector,
+							    bridge->hdmi_codec_dev,
+							    &drm_bridge_connector_hdmi_codec_funcs,
+							    bridge->hdmi_codec_max_i2s_playback_channels,
+							    bridge->hdmi_codec_spdif_playback,
+							    bridge->hdmi_codec_dai_port);
+			if (ret)
+				return ERR_PTR(ret);
+		}
+	} else {
 		ret = drmm_connector_init(drm, connector,
 					  &drm_bridge_connector_funcs,
 					  connector_type, ddc);
-	if (ret)
-		return ERR_PTR(ret);
+		if (ret)
+			return ERR_PTR(ret);
+	}
 
 	drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs);
 
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index e8d735b7f6a480468c88287e2517b387ceec0f22..fd7ad7315a8bfda90f02b0704c33ba0e356899fb 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -41,6 +41,8 @@ struct drm_display_info;
 struct drm_minor;
 struct drm_panel;
 struct edid;
+struct hdmi_codec_daifmt;
+struct hdmi_codec_params;
 struct i2c_adapter;
 
 /**
@@ -676,6 +678,21 @@ struct drm_bridge_funcs {
 				    enum hdmi_infoframe_type type,
 				    const u8 *buffer, size_t len);
 
+	int (*hdmi_codec_audio_startup)(struct drm_connector *connector,
+					struct drm_bridge *bridge);
+
+	int (*hdmi_codec_prepare)(struct drm_connector *connector,
+				  struct drm_bridge *bridge,
+				  struct hdmi_codec_daifmt *fmt,
+				  struct hdmi_codec_params *hparms);
+
+	void (*hdmi_codec_audio_shutdown)(struct drm_connector *connector,
+					  struct drm_bridge *bridge);
+
+	int (*hdmi_codec_mute_stream)(struct drm_connector *connector,
+				      struct drm_bridge *bridge,
+				      bool enable, int direction);
+
 	/**
 	 * @debugfs_init:
 	 *
@@ -859,6 +876,27 @@ struct drm_bridge {
 	 * @DRM_BRIDGE_OP_HDMI is set.
 	 */
 	unsigned int max_bpc;
+
+	/**
+	 * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
+	 */
+	struct device *hdmi_codec_dev;
+
+	/**
+	 * @hdmi_codec_max_i2s_playback_channels: maximum number of playback
+	 * I2S channels for the HDMI codec
+	 */
+	int hdmi_codec_max_i2s_playback_channels;
+
+	/**
+	 * @hdmi_codec_spdif_playback: set if HDMI codec has S/PDIF playback port
+	 */
+	unsigned int hdmi_codec_spdif_playback : 1;
+
+	/**
+	 * @hdmi_codec_dai_port: sound DAI port, -1 if it is not enabled
+	 */
+	int hdmi_codec_dai_port;
 };
 
 static inline struct drm_bridge *

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:27 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:27 +0200
Subject: [PATCH v7 05/10] drm/bridge: lt9611: switch to using the DRM HDMI
 codec framework
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-5-cb9df2b6a515@linaro.org>

Make the Lontium LT9611 DSI-to-HDMI bridge driver use the DRM HDMI Codec
framework. This enables programming of Audio InfoFrames using the HDMI
Connector interface and also enables support for the missing features,
including the ELD retrieval and better hotplug support.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 170 +++++++++++++-------------------
 1 file changed, 68 insertions(+), 102 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 698a9a01783d28edc734b6932a7768978de65ffc..f0bcb8798467e86708df97dd963b9c69529f4981 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -45,7 +45,6 @@ struct lt9611 {
 	struct device_node *dsi1_node;
 	struct mipi_dsi_device *dsi0;
 	struct mipi_dsi_device *dsi1;
-	struct platform_device *audio_pdev;
 
 	bool ac_mode;
 
@@ -864,6 +863,10 @@ static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge,
 	unsigned int mask;
 
 	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mask = LT9611_INFOFRAME_AUDIO;
+		break;
+
 	case HDMI_INFOFRAME_TYPE_AVI:
 		mask = LT9611_INFOFRAME_AVI;
 		break;
@@ -897,6 +900,11 @@ static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge,
 	int i;
 
 	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mask = LT9611_INFOFRAME_AUDIO;
+		addr = 0x84b2;
+		break;
+
 	case HDMI_INFOFRAME_TYPE_AVI:
 		mask = LT9611_INFOFRAME_AVI;
 		addr = 0x8440;
@@ -940,6 +948,55 @@ lt9611_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
 	return MODE_OK;
 }
 
+static int lt9611_hdmi_codec_audio_startup(struct drm_connector *connector,
+					   struct drm_bridge *bridge)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	regmap_write(lt9611->regmap, 0x82d6, 0x8c);
+	regmap_write(lt9611->regmap, 0x82d7, 0x04);
+
+	regmap_write(lt9611->regmap, 0x8406, 0x08);
+	regmap_write(lt9611->regmap, 0x8407, 0x10);
+
+	regmap_write(lt9611->regmap, 0x8434, 0xd5);
+
+	return 0;
+}
+
+static int lt9611_hdmi_codec_prepare(struct drm_connector *connector,
+				     struct drm_bridge *bridge,
+				     struct hdmi_codec_daifmt *fmt,
+				     struct hdmi_codec_params *hparms)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	if (hparms->sample_rate == 48000)
+		regmap_write(lt9611->regmap, 0x840f, 0x2b);
+	else if (hparms->sample_rate == 96000)
+		regmap_write(lt9611->regmap, 0x840f, 0xab);
+	else
+		return -EINVAL;
+
+	regmap_write(lt9611->regmap, 0x8435, 0x00);
+	regmap_write(lt9611->regmap, 0x8436, 0x18);
+	regmap_write(lt9611->regmap, 0x8437, 0x00);
+
+	return drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
+								       &hparms->cea);
+}
+
+static void lt9611_hdmi_codec_audio_shutdown(struct drm_connector *connector,
+					     struct drm_bridge *bridge)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector);
+
+	regmap_write(lt9611->regmap, 0x8406, 0x00);
+	regmap_write(lt9611->regmap, 0x8407, 0x00);
+}
+
 static const struct drm_bridge_funcs lt9611_bridge_funcs = {
 	.attach = lt9611_bridge_attach,
 	.mode_valid = lt9611_bridge_mode_valid,
@@ -960,6 +1017,10 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = {
 	.hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid,
 	.hdmi_write_infoframe = lt9611_hdmi_write_infoframe,
 	.hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe,
+
+	.hdmi_codec_audio_startup = lt9611_hdmi_codec_audio_startup,
+	.hdmi_codec_prepare = lt9611_hdmi_codec_prepare,
+	.hdmi_codec_audio_shutdown = lt9611_hdmi_codec_audio_shutdown,
 };
 
 static int lt9611_parse_dt(struct device *dev,
@@ -1013,102 +1074,6 @@ static int lt9611_read_device_rev(struct lt9611 *lt9611)
 	return ret;
 }
 
-static int lt9611_hdmi_hw_params(struct device *dev, void *data,
-				 struct hdmi_codec_daifmt *fmt,
-				 struct hdmi_codec_params *hparms)
-{
-	struct lt9611 *lt9611 = data;
-
-	if (hparms->sample_rate == 48000)
-		regmap_write(lt9611->regmap, 0x840f, 0x2b);
-	else if (hparms->sample_rate == 96000)
-		regmap_write(lt9611->regmap, 0x840f, 0xab);
-	else
-		return -EINVAL;
-
-	regmap_write(lt9611->regmap, 0x8435, 0x00);
-	regmap_write(lt9611->regmap, 0x8436, 0x18);
-	regmap_write(lt9611->regmap, 0x8437, 0x00);
-
-	return 0;
-}
-
-static int lt9611_audio_startup(struct device *dev, void *data)
-{
-	struct lt9611 *lt9611 = data;
-
-	regmap_write(lt9611->regmap, 0x82d6, 0x8c);
-	regmap_write(lt9611->regmap, 0x82d7, 0x04);
-
-	regmap_write(lt9611->regmap, 0x8406, 0x08);
-	regmap_write(lt9611->regmap, 0x8407, 0x10);
-
-	regmap_write(lt9611->regmap, 0x8434, 0xd5);
-
-	return 0;
-}
-
-static void lt9611_audio_shutdown(struct device *dev, void *data)
-{
-	struct lt9611 *lt9611 = data;
-
-	regmap_write(lt9611->regmap, 0x8406, 0x00);
-	regmap_write(lt9611->regmap, 0x8407, 0x00);
-}
-
-static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				      struct device_node *endpoint,
-				      void *data)
-{
-	struct of_endpoint of_ep;
-	int ret;
-
-	ret = of_graph_parse_endpoint(endpoint, &of_ep);
-	if (ret < 0)
-		return ret;
-
-	/*
-	 * HDMI sound should be located as reg = <2>
-	 * Then, it is sound port 0
-	 */
-	if (of_ep.port == 2)
-		return 0;
-
-	return -EINVAL;
-}
-
-static const struct hdmi_codec_ops lt9611_codec_ops = {
-	.hw_params	= lt9611_hdmi_hw_params,
-	.audio_shutdown = lt9611_audio_shutdown,
-	.audio_startup	= lt9611_audio_startup,
-	.get_dai_id	= lt9611_hdmi_i2s_get_dai_id,
-};
-
-static struct hdmi_codec_pdata codec_data = {
-	.ops = &lt9611_codec_ops,
-	.max_i2s_channels = 8,
-	.i2s = 1,
-};
-
-static int lt9611_audio_init(struct device *dev, struct lt9611 *lt9611)
-{
-	codec_data.data = lt9611;
-	lt9611->audio_pdev =
-		platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-					      PLATFORM_DEVID_AUTO,
-					      &codec_data, sizeof(codec_data));
-
-	return PTR_ERR_OR_ZERO(lt9611->audio_pdev);
-}
-
-static void lt9611_audio_exit(struct lt9611 *lt9611)
-{
-	if (lt9611->audio_pdev) {
-		platform_device_unregister(lt9611->audio_pdev);
-		lt9611->audio_pdev = NULL;
-	}
-}
-
 static int lt9611_probe(struct i2c_client *client)
 {
 	struct lt9611 *lt9611;
@@ -1172,6 +1137,9 @@ static int lt9611_probe(struct i2c_client *client)
 
 	i2c_set_clientdata(client, lt9611);
 
+	/* Disable Audio InfoFrame, enabled by default */
+	regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, 0);
+
 	lt9611->bridge.funcs = &lt9611_bridge_funcs;
 	lt9611->bridge.of_node = client->dev.of_node;
 	lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
@@ -1180,6 +1148,9 @@ static int lt9611_probe(struct i2c_client *client)
 	lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	lt9611->bridge.vendor = "Lontium";
 	lt9611->bridge.product = "LT9611";
+	lt9611->bridge.hdmi_codec_dev = dev;
+	lt9611->bridge.hdmi_codec_max_i2s_playback_channels = 8;
+	lt9611->bridge.hdmi_codec_dai_port = 2;
 
 	drm_bridge_add(&lt9611->bridge);
 
@@ -1201,10 +1172,6 @@ static int lt9611_probe(struct i2c_client *client)
 
 	lt9611_enable_hpd_interrupts(lt9611);
 
-	ret = lt9611_audio_init(dev, lt9611);
-	if (ret)
-		goto err_remove_bridge;
-
 	return 0;
 
 err_remove_bridge:
@@ -1225,7 +1192,6 @@ static void lt9611_remove(struct i2c_client *client)
 	struct lt9611 *lt9611 = i2c_get_clientdata(client);
 
 	disable_irq(client->irq);
-	lt9611_audio_exit(lt9611);
 	drm_bridge_remove(&lt9611->bridge);
 
 	regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:28 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:28 +0200
Subject: [PATCH v7 06/10] drm/display/hdmi: implement hotplug functions
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-6-cb9df2b6a515@linaro.org>

The HDMI Connectors need to perform a variety of tasks when the HDMI
connector state changes. Such tasks include setting or invalidating CEC
address, notifying HDMI codec driver, updating scrambler data, etc.

Implementing such tasks in a driver-specific callbacks is error prone.
Start implementing the generic helper function (currently handling only
the HDMI Codec framework) to be used by drivers utilizing HDMI Connector
framework.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_hdmi_state_helper.c | 56 +++++++++++++++++++++++++
 include/drm/display/drm_hdmi_state_helper.h     |  5 +++
 include/drm/drm_connector.h                     | 16 +++++++
 3 files changed, 77 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index 80bf2829ba89b5f84fed4fa9eb1d6302e10a4f9e..e175c0eaa1cdc0b8b8b8408bdc3fdcf49067c634 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -769,3 +769,59 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con
 	return ret;
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe);
+
+static void
+drm_atomic_helper_connector_hdmi_update(struct drm_connector *connector,
+					enum drm_connector_status status)
+{
+	const struct drm_edid *drm_edid;
+
+	if (status == connector_status_disconnected) {
+		// TODO: also handle CEC and scramber, HDMI sink disconnected.
+		drm_connector_hdmi_codec_plugged_notify(connector, false);
+	}
+
+	if (connector->hdmi.funcs->read_edid)
+		drm_edid = connector->hdmi.funcs->read_edid(connector);
+	else
+		drm_edid = drm_edid_read(connector);
+
+	drm_edid_connector_update(connector, drm_edid);
+
+	drm_edid_free(drm_edid);
+
+	if (status == connector_status_connected) {
+		// TODO: also handle CEC and scramber, HDMI sink is now connected.
+		drm_connector_hdmi_codec_plugged_notify(connector, true);
+	}
+}
+
+/**
+ * drm_atomic_helper_connector_hdmi_hotplug - Handle the hotplug event for the HDMI connector
+ * @connector: A pointer to the HDMI connector
+ * @status: Connection status
+ *
+ * This function should be called as a part of the .detect() / .detect_ctx()
+ * callbacks, updating the HDMI-specific connector's data.
+ */
+void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
+					      enum drm_connector_status status)
+{
+	drm_atomic_helper_connector_hdmi_update(connector, status);
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_hotplug);
+
+/**
+ * drm_atomic_helper_connector_hdmi_force - HDMI Connector implementation of the force callback
+ * @connector: A pointer to the HDMI connector
+ *
+ * This function implements the .force() callback for the HDMI connectors. It
+ * can either be used directly as the callback or should be called from within
+ * the .force() callback implementation to maintain the HDMI-specific
+ * connector's data.
+ */
+void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector)
+{
+	drm_atomic_helper_connector_hdmi_update(connector, connector->status);
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_force);
diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h
index d6d65da6d8f9ee46de33114cce2d6fbe6098a862..9ae19f3caf727f9a0fe06e6afe5fc46db924444f 100644
--- a/include/drm/display/drm_hdmi_state_helper.h
+++ b/include/drm/display/drm_hdmi_state_helper.h
@@ -8,6 +8,8 @@ struct drm_connector;
 struct drm_connector_state;
 struct hdmi_audio_infoframe;
 
+enum drm_connector_status;
+
 void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
 					      struct drm_connector_state *new_conn_state);
 
@@ -19,6 +21,9 @@ int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector
 int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector);
 int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
 						       struct drm_atomic_state *state);
+void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
+					      enum drm_connector_status status);
+void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector);
 
 enum drm_mode_status
 drm_hdmi_connector_mode_valid(struct drm_connector *connector,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 536d604b6fb27368c43805a2ecf57fac06b3d472..23340696bf36313952da0089b9dc24dcf772a9c5 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -45,6 +45,7 @@ struct drm_property;
 struct drm_property_blob;
 struct drm_printer;
 struct drm_privacy_screen;
+struct drm_edid;
 struct edid;
 struct hdmi_codec_daifmt;
 struct hdmi_codec_params;
@@ -1247,6 +1248,21 @@ struct drm_connector_hdmi_funcs {
 	int (*write_infoframe)(struct drm_connector *connector,
 			       enum hdmi_infoframe_type type,
 			       const u8 *buffer, size_t len);
+
+	/**
+	 * @read_edid:
+	 *
+	 * This callback is used by the framework as a replacement for reading
+	 * the EDID from connector->ddc. It is still recommended to provide
+	 * connector->ddc instead of implementing this callback. Returned EDID
+	 * should be freed via the drm_edid_free().
+	 *
+	 * The @read_edid callback is optional.
+	 *
+	 * Returns:
+	 * Valid EDID on success, NULL in case of failure.
+	 */
+	const struct drm_edid *(*read_edid)(struct drm_connector *connector);
 };
 
 /**

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:29 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:29 +0200
Subject: [PATCH v7 07/10] drm/bridge_connector: hook
 drm_atomic_helper_connector_hdmi_hotplug()
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-7-cb9df2b6a515@linaro.org>

Extend drm_bridge_connector code to read the EDID and use it to update
connector status if the bridge chain implements HDMI bridge. Performing
it from the generic location minimizes individual bridge's code and
enforces standard behaviour from all corresponding drivers.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 39 ++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index be46d2e7cb5cec262ca5dd6f42f8f31b0187a0f7..4bc044e73fbd8c9fa32ea11f54f268acf024f55f 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -17,6 +17,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_hdmi_state_helper.h>
@@ -180,11 +181,15 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
 	struct drm_bridge_connector *bridge_connector =
 		to_drm_bridge_connector(connector);
 	struct drm_bridge *detect = bridge_connector->bridge_detect;
+	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
 	enum drm_connector_status status;
 
 	if (detect) {
 		status = detect->funcs->detect(detect);
 
+		if (hdmi)
+			drm_atomic_helper_connector_hdmi_hotplug(connector, status);
+
 		drm_bridge_connector_hpd_notify(connector, status);
 	} else {
 		switch (connector->connector_type) {
@@ -203,6 +208,16 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
 	return status;
 }
 
+static void drm_bridge_connector_force(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
+
+	if (hdmi)
+		drm_atomic_helper_connector_hdmi_force(connector);
+}
+
 static void drm_bridge_connector_debugfs_init(struct drm_connector *connector,
 					      struct dentry *root)
 {
@@ -231,6 +246,7 @@ static void drm_bridge_connector_reset(struct drm_connector *connector)
 static const struct drm_connector_funcs drm_bridge_connector_funcs = {
 	.reset = drm_bridge_connector_reset,
 	.detect = drm_bridge_connector_detect,
+	.force = drm_bridge_connector_force,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
@@ -276,6 +292,14 @@ static int drm_bridge_connector_get_modes(struct drm_connector *connector)
 		to_drm_bridge_connector(connector);
 	struct drm_bridge *bridge;
 
+	/*
+	 * If there is a HDMI bridge, EDID has been updated as a part of
+	 * the .detect(). Just update the modes here.
+	 */
+	bridge = bridge_connector->bridge_hdmi;
+	if (bridge)
+		return drm_edid_connector_add_modes(connector);
+
 	/*
 	 * If display exposes EDID, then we parse that in the normal way to
 	 * build table of supported modes.
@@ -368,10 +392,25 @@ static int drm_bridge_connector_write_infoframe(struct drm_connector *connector,
 	return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len);
 }
 
+static const struct drm_edid *
+drm_bridge_connector_read_edid(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_edid;
+	if (!bridge)
+		return NULL;
+
+	return drm_bridge_edid_read(bridge, connector);
+}
+
 static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
 	.tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid,
 	.clear_infoframe = drm_bridge_connector_clear_infoframe,
 	.write_infoframe = drm_bridge_connector_write_infoframe,
+	.read_edid = drm_bridge_connector_read_edid,
 };
 
 static int drm_bridge_connector_audio_startup(struct drm_connector *connector)

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Mon Dec 16 16:40:30 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 02:40:30 +0200
Subject: [PATCH v7 08/10] drm/vc4: hdmi: switch to using generic HDMI Codec
 infrastructure
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-drm-bridge-hdmi-connector-v7-8-cb9df2b6a515@linaro.org>

Drop driver-specific implementation and use the generic HDMI Codec
framework in order to implement the HDMI audio support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 69 ++++++++++--------------------------------
 drivers/gpu/drm/vc4/vc4_hdmi.h |  2 --
 2 files changed, 16 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 203293a8beca738dbfeaaf15f350026e263e646b..2a2aca7017994779a7163935df3fc87ca312d6dd 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -584,6 +584,7 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
 };
 
 static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs;
+static const struct drm_connector_hdmi_codec_funcs vc4_hdmi_codec_funcs;
 
 static int vc4_hdmi_connector_init(struct drm_device *dev,
 				   struct vc4_hdmi *vc4_hdmi)
@@ -609,6 +610,12 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	ret = drm_connector_hdmi_audio_init(connector, dev->dev,
+					    &vc4_hdmi_codec_funcs,
+					    8, false, -1);
+	if (ret)
+		return ret;
+
 	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
 
 	/*
@@ -1921,9 +1928,9 @@ static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi)
 	return true;
 }
 
-static int vc4_hdmi_audio_startup(struct device *dev, void *data)
+static int vc4_hdmi_audio_startup(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	unsigned long flags;
 	int ret = 0;
@@ -1985,9 +1992,9 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 	spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 }
 
-static void vc4_hdmi_audio_shutdown(struct device *dev, void *data)
+static void vc4_hdmi_audio_shutdown(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	unsigned long flags;
 	int idx;
@@ -2057,13 +2064,12 @@ static int sample_rate_to_mai_fmt(int samplerate)
 }
 
 /* HDMI audio codec callbacks */
-static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
+static int vc4_hdmi_audio_prepare(struct drm_connector *connector,
 				  struct hdmi_codec_daifmt *daifmt,
 				  struct hdmi_codec_params *params)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	struct drm_connector *connector = &vc4_hdmi->connector;
 	struct vc4_dev *vc4 = to_vc4_dev(drm);
 	unsigned int sample_rate = params->sample_rate;
 	unsigned int channels = params->channels;
@@ -2075,7 +2081,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
 	int ret = 0;
 	int idx;
 
-	dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
+	dev_dbg(&vc4_hdmi->pdev->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
 		sample_rate, params->sample_width, channels);
 
 	mutex_lock(&vc4_hdmi->mutex);
@@ -2214,40 +2220,12 @@ static const struct snd_dmaengine_pcm_config pcm_conf = {
 	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
 };
 
-static int vc4_hdmi_audio_get_eld(struct device *dev, void *data,
-				  uint8_t *buf, size_t len)
-{
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-
-	mutex_lock(&connector->eld_mutex);
-	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
-	mutex_unlock(&connector->eld_mutex);
-
-	return 0;
-}
-
-static const struct hdmi_codec_ops vc4_hdmi_codec_ops = {
-	.get_eld = vc4_hdmi_audio_get_eld,
+static const struct drm_connector_hdmi_codec_funcs vc4_hdmi_codec_funcs = {
 	.prepare = vc4_hdmi_audio_prepare,
 	.audio_shutdown = vc4_hdmi_audio_shutdown,
 	.audio_startup = vc4_hdmi_audio_startup,
 };
 
-static struct hdmi_codec_pdata vc4_hdmi_codec_pdata = {
-	.ops = &vc4_hdmi_codec_ops,
-	.max_i2s_channels = 8,
-	.i2s = 1,
-};
-
-static void vc4_hdmi_audio_codec_release(void *ptr)
-{
-	struct vc4_hdmi *vc4_hdmi = ptr;
-
-	platform_device_unregister(vc4_hdmi->audio.codec_pdev);
-	vc4_hdmi->audio.codec_pdev = NULL;
-}
-
 static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 {
 	const struct vc4_hdmi_register *mai_data =
@@ -2255,7 +2233,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 	struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link;
 	struct snd_soc_card *card = &vc4_hdmi->audio.card;
 	struct device *dev = &vc4_hdmi->pdev->dev;
-	struct platform_device *codec_pdev;
 	const __be32 *addr;
 	int index, len;
 	int ret;
@@ -2348,20 +2325,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 		return ret;
 	}
 
-	codec_pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-						   PLATFORM_DEVID_AUTO,
-						   &vc4_hdmi_codec_pdata,
-						   sizeof(vc4_hdmi_codec_pdata));
-	if (IS_ERR(codec_pdev)) {
-		dev_err(dev, "Couldn't register the HDMI codec: %ld\n", PTR_ERR(codec_pdev));
-		return PTR_ERR(codec_pdev);
-	}
-	vc4_hdmi->audio.codec_pdev = codec_pdev;
-
-	ret = devm_add_action_or_reset(dev, vc4_hdmi_audio_codec_release, vc4_hdmi);
-	if (ret)
-		return ret;
-
 	dai_link->cpus		= &vc4_hdmi->audio.cpu;
 	dai_link->codecs	= &vc4_hdmi->audio.codec;
 	dai_link->platforms	= &vc4_hdmi->audio.platform;
@@ -2374,7 +2337,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 	dai_link->stream_name = "MAI PCM";
 	dai_link->codecs->dai_name = "i2s-hifi";
 	dai_link->cpus->dai_name = dev_name(dev);
-	dai_link->codecs->name = dev_name(&codec_pdev->dev);
+	dai_link->codecs->name = dev_name(&vc4_hdmi->connector.hdmi_codec.codec_pdev->dev);
 	dai_link->platforms->name = dev_name(dev);
 
 	card->dai_link = dai_link;
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index b2424a21da230db99db207efa293417faccd254d..e3d989ca302b72533c374dfa3fd0d5bd7fe64a82 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -104,8 +104,6 @@ struct vc4_hdmi_audio {
 	struct snd_soc_dai_link_component codec;
 	struct snd_soc_dai_link_component platform;
 	struct snd_dmaengine_dai_dma_data dma_data;
-	struct hdmi_audio_infoframe infoframe;
-	struct platform_device *codec_pdev;
 	bool streaming;
 };
 

-- 
2.39.5



From andyshrk at 163.com  Mon Dec 16 16:41:24 2024
From: andyshrk at 163.com (Andy Yan)
Date: Tue, 17 Dec 2024 08:41:24 +0800 (CST)
Subject: [PATCH v6 08/16] drm/rockchip: vop2: Support 32x8 superblock
 afbc
In-Reply-To: <CAPj87rOjqZdyht2y8MK7gVyk_eqEzk1Sy0DcxFtQRuhrHQ_oxA@mail.gmail.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
 <20241214081719.3330518-9-andyshrk@163.com>
 <CAPj87rOjqZdyht2y8MK7gVyk_eqEzk1Sy0DcxFtQRuhrHQ_oxA@mail.gmail.com>
Message-ID: <165af58a.697.193d2100239.Coremail.andyshrk@163.com>


Hi Daniel,

At 2024-12-16 21:06:07, "Daniel Stone" <daniel at fooishbar.org> wrote:
>Hi Andy,
>
>On Sat, 14 Dec 2024 at 08:18, Andy Yan <andyshrk at 163.com> wrote:
>> This is the only afbc format supported by the upcoming
>> VOP for rk3576.
>>
>> Add support for it.
>
>Out of interest, how was this tested? There is no 32x8 modifier in the
>format list in format_modifiers_afbc[], so it seems like it shouldn't
>be possible to get a 32x8 buffer on a plane at all.

The 32x8 modifier  added in PATCH 16/16:

+/* used from rk3576, afbc 32*8 half mode */
+static const uint64_t format_modifiers_rk3576_afbc[] = {
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_SPLIT),
+

I write an ovltest[0] tool which can take linear/AFBC rgb/yuv data from a file, then
commit to drm driver, I use this tool for most basic format test.

But when tested on weston, I found that weston does not use the AFBC format for display,
don't know why.

>
>You can use the drm_info utility from
>https://gitlab.freedesktop.org/emersion/drm_info to validate that the
>list of supported formats/modifiers for each plane matches your
>expectation.

I think this is similar to what modetest dump?
38      0       0       0,0             0,0     0               0x00000001
  formats: XR30 XB30 AR30 AB30 XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV21 NV16 NV61 NV24 NV42 NV15 NV20 NV30
  props:
        8 type:
                flags: immutable enum
                enums: Overlay=0 Primary=1 Cursor=2
                value: 0
        30 IN_FORMATS:
                flags: immutable blob
                blobs:

                value:
                        01000000000000001500000018000000
                        09000000700000005852333058423330
                        41523330414233305852323441523234
                        58423234414232345247323442473234
                        52473136424731364e5631324e563231
                        4e5631364e5636314e5632344e563432
                        4e5631354e5632304e56333000000000
                        ff0f0000000000000000000000000000
                        2200000000000008ff0f000000000000
                        00000000000000006200000000000008
                        ff0f0000000000000000000000000000
                        3200000000000008ff0f000000000000
                        0000000000000000a200000000000008
                        ff0f0000000000000000000000000000
                        e200000000000008ff0f000000000000
                        0000000000000000b200000000000008
                        ff0f0000000000000000000000000000
                        f200000000000008ff0f000000000000
                        00000000000000007200000000000008
                        ffff1f00000000000000000000000000
                        0000000000000000
                in_formats blob decoded:
                         XR30:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         XB30:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         AR30:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         AB30:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         XR24:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         AR24:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         XB24:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         AB24:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         RG24:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         BG24:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         RG16:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         BG16:  ARM_BLOCK_SIZE=32x8,MODE=SPLIT(0x800000000000022) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT(0x800000000000032) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|CBR(0x8000000000000a2) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE|CBR(0x8000000000000e2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|CBR(0x8000000000000b2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE|CBR(0x8000000000000f2) ARM_BLOCK_SIZE=32x8,MODE=YTR|SPLIT|SPARSE(0x800000000000072) LINEAR(0x0)
                         NV12:  LINEAR(0x0)
                         NV21:  LINEAR(0x0)
                         NV16:  LINEAR(0x0)
                         NV61:  LINEAR(0x0)
                         NV24:  LINEAR(0x0)
                         NV42:  LINEAR(0x0)
                         NV15:  LINEAR(0x0)
                         NV20:  LINEAR(0x0)
                         NV30:  LINEAR(0x0)




[0]https://github.com/andyshrk/mesa-drm/blob/mydev/tests/ovltest/ovltest.c#L1167
>
>Cheers,
>Daniel
>
>_______________________________________________
>Linux-rockchip mailing list
>Linux-rockchip at lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-rockchip

From inochiama at gmail.com  Mon Dec 16 16:47:36 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Tue, 17 Dec 2024 08:47:36 +0800
Subject: [PATCH RFC net-next 0/3] riscv: sophgo: Add ethernet support for
 SG2044
In-Reply-To: <20241101014327.513732-1-inochiama@gmail.com>
References: <20241101014327.513732-1-inochiama@gmail.com>
Message-ID: <puld3vngm4rti74aecpeoro3tatifgasrq6sxg4huufuptmjtk@njfskna3k7ds>

On Fri, Nov 01, 2024 at 09:43:24AM +0800, Inochi Amaoto wrote:
> The ethernet controller of SG2044 is Synopsys DesignWare IP with
> custom clock. Add glue layer for it.
> 
> Since v2, these patch depends on that following patch that provides
> helper function to compute rgmii clock, and this patch are marked as RFC:
> https://lore.kernel.org/netdev/20241028-upstream_s32cc_gmac-v4-4-03618f10e3e2 at oss.nxp.com/
> 

Hi,

I have seen the dependency has been merged, is it possible to 
resend a normal version of this patch?

https://lore.kernel.org/netdev/173380743727.355055.17303486442146316315.git-patchwork-notify at kernel.org/

Regards,
Inochi


From daniel at makrotopia.org  Mon Dec 16 17:18:01 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 17 Dec 2024 01:18:01 +0000
Subject: [PATCH v2] drm/mediatek: only touch DISP_REG_OVL_PITCH_MSB if AFBC
 is supported
Message-ID: <c7fbd3c3e633c0b7dd6d1cd78ccbdded31e1ca0f.1734397800.git.daniel@makrotopia.org>

Touching DISP_REG_OVL_PITCH_MSB leads to video overlay on MT2701, MT7623N
and probably other older SoCs being broken.

Move setting up AFBC layer configuration into a separate function only
being called on hardware which actually supports AFBC which restores the
behavior as it was before commit c410fa9b07c3 ("drm/mediatek: Add AFBC
support to Mediatek DRM driver") on non-AFBC hardware.

Fixes: c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek DRM driver")
Cc: stable at vger.kernel.org
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v2: move AFBC layer config into a new function

 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 57 +++++++++++++------------
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index f731d4fbe8b6..e0e24f0a6edd 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -460,6 +460,29 @@ static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl,
 	}
 }
 
+static void mtk_ovl_afbc_layer_config(struct mtk_disp_ovl *ovl,
+				      unsigned int idx,
+				      struct mtk_plane_pending_state *pending,
+				      struct cmdq_pkt *cmdq_pkt)
+{
+	unsigned int pitch_msb = pending->pitch >> 16;
+	unsigned int hdr_pitch = pending->hdr_pitch;
+	unsigned int hdr_addr = pending->hdr_addr;
+
+	if (pending->modifier != DRM_FORMAT_MOD_LINEAR) {
+		mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
+				      DISP_REG_OVL_HDR_ADDR(ovl, idx));
+		mtk_ddp_write_relaxed(cmdq_pkt,
+				      OVL_PITCH_MSB_2ND_SUBBUF | pitch_msb,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
+		mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
+				      DISP_REG_OVL_HDR_PITCH(ovl, idx));
+	} else {
+		mtk_ddp_write_relaxed(cmdq_pkt, pitch_msb,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
+	}
+}
+
 void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 			  struct mtk_plane_state *state,
 			  struct cmdq_pkt *cmdq_pkt)
@@ -467,25 +490,13 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
 	struct mtk_plane_pending_state *pending = &state->pending;
 	unsigned int addr = pending->addr;
-	unsigned int hdr_addr = pending->hdr_addr;
-	unsigned int pitch = pending->pitch;
-	unsigned int hdr_pitch = pending->hdr_pitch;
+	unsigned int pitch_lsb = pending->pitch & GENMASK(15, 0);
 	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 {
-		struct split_pitch {
-			u16 lsb;
-			u16 msb;
-		} split_pitch;
-		u32 pitch;
-	} overlay_pitch;
-
-	overlay_pitch.pitch = pitch;
 
 	if (!pending->enable) {
 		mtk_ovl_layer_off(dev, idx, cmdq_pkt);
@@ -524,11 +535,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 	}
 
 	if (ovl->data->supports_afbc)
-		mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc);
+		mtk_ovl_set_afbc(ovl, cmdq_pkt, idx,
+				 pending->modifier != DRM_FORMAT_MOD_LINEAR);
 
 	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 | ignore_pixel_alpha,
+	mtk_ddp_write_relaxed(cmdq_pkt, 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));
@@ -537,19 +549,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 	mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
 			      DISP_REG_OVL_ADDR(ovl, idx));
 
-	if (is_afbc) {
-		mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
-				      DISP_REG_OVL_HDR_ADDR(ovl, idx));
-		mtk_ddp_write_relaxed(cmdq_pkt,
-				      OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb,
-				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
-		mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
-				      DISP_REG_OVL_HDR_PITCH(ovl, idx));
-	} else {
-		mtk_ddp_write_relaxed(cmdq_pkt,
-				      overlay_pitch.split_pitch.msb,
-				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
-	}
+	if (ovl->data->supports_afbc)
+		mtk_ovl_afbc_layer_config(ovl, idx, pending, cmdq_pkt);
 
 	mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
 	mtk_ovl_layer_on(dev, idx, cmdq_pkt);
-- 
2.47.1


From kuba at kernel.org  Mon Dec 16 17:33:33 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 16 Dec 2024 17:33:33 -0800
Subject: [PATCH net-next 2/2] net: stmmac: dwmac-socfpga: Set interface
 modes from Lynx PCS as supported
In-Reply-To: <20241216094224.199e8df7@fedora.home>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
	<20241213090526.71516-3-maxime.chevallier@bootlin.com>
	<Z1wnFXlgEU84VX8F@shell.armlinux.org.uk>
	<20241213182904.55eb2504@fedora.home>
	<Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
	<20241216094224.199e8df7@fedora.home>
Message-ID: <20241216173333.55e35f34@kernel.org>

On Mon, 16 Dec 2024 09:42:24 +0100 Maxime Chevallier wrote:
> > I've actually already created that series!  
> 
> Woaw that was fast ! I'll review and give it a test on my setup then.
> 
> Maybe one thing to clarify with the net maintainers is that this work
> you've done doesn't replace the series this thread is replying to,
> which still makes sense (we need the
> stmmac_priv->phylink_config.supported_interfaces to be correctly
> populated on socfpga).

Ah, sorry. Should have asked. 

I assumed since Lynx PCS will have the SGMII and 1000BASEX set -
Russell's patch 5 will copy them for you to
priv->phylink_config.supported_interfaces. Your patch 1 is still needed.
Did I get it wrong?


From peng.fan at nxp.com  Mon Dec 16 17:39:09 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Tue, 17 Dec 2024 01:39:09 +0000
Subject: imx8m-blk-ctrl: WARNING, no release() function
In-Reply-To: <20241212141003.GA44219@francesco-nb>
References: <20241212141003.GA44219@francesco-nb>
Message-ID: <PAXPR04MB8459AB53B142CB43782757D988042@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: imx8m-blk-ctrl: WARNING, no release() function

Please try this patch.
https://lore.kernel.org/all/20241206112731.98244-1-peng.fan at oss.nxp.com/

Thanks,
Peng.

> 
> Hello,
> on v6.13-rc2 (PREEMPT_RT, if it matters), I have the following warning
> 
> [    4.615793] ------------[ cut here ]------------
> [    4.615814] Device 'mediablk-mipi-csi2-1' does not have a release()
> function, it is broken and must be fixed. See Documentation/core-
> api/kobject.rst.
> [    4.618977] WARNING: CPU: 1 PID: 11 at /drivers/base/core.c:2569
> device_release+0x80/0x94
> [    4.638974] Modules linked in: ecdh_generic ecc etnaviv(+) rfkill
> libaes samsung_dsim gpu_sched imx_sdma(+) governor_userspace
> imx_bus dwc3_imx8mp spi_nxp_fspi lontium_lt8912b ina2xx
> snd_soc_wm8904 ti_ads1015 industrialio_triggered_buffer kfifo_buf
> lm75 snvs_pwrkey pwm_imx27 nvmem_snvs_lpgpr imx8mm_thermal
> caam flexcan error can_dev spi_imx usb_conn_gpio display_connector
> roles gpio_keys fuse ipv6 autofs4
> [    4.639073] CPU: 1 UID: 0 PID: 11 Comm: kworker/u16:0 Not tainted
> 6.13.0-rc2-0.0.0-devel-00040-ga1625b19385c #1
> [    4.639082] Hardware name: Toradex Verdin iMX8M Plus WB on
> Dahlia Board (DT)
> [    4.639087] Workqueue: events_unbound
> deferred_probe_work_func
> [    4.639099] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS
> BTYPE=--)
> [    4.639107] pc : device_release+0x80/0x94
> [    4.639116] lr : device_release+0x80/0x94
> [    4.639122] sp : ffff80008142b910
> [    4.639125] x29: ffff80008142b910 x28: 00000000fffffdfb x27:
> ffff000005c92180
> [    4.639137] x26: ffff000000018028 x25: ffff000000046dc0 x24:
> ffff800080c43710
> [    4.639147] x23: 0000000100000001 x22: 0000000000000000 x21:
> ffff800080e43750
> [    4.639158] x20: 0000000000000000 x19: ffff000007cb06d8 x18:
> 0000000000000006
> [    4.639168] x17: 0000000000000001 x16: 0000000000000000 x15:
> 0000000000000002
> [    4.639179] x14: 0000000000001400 x13: ffff0000000a9110 x12:
> 0000000000225510
> [    4.639190] x11: 0000000000000000 x10: 00000000000009c0 x9 :
> ffff80008142b790
> [    4.639200] x8 : ffff00000013bba0 x7 : 000000000000002d x6 :
> 000000000113158e
> [    4.639210] x5 : 00000001134e0800 x4 : 0000000000000002 x3 :
> ffff000003b04c50
> [    4.639221] x2 : 0000000000000000 x1 : 0000000000000000 x0 :
> ffff00000013b180
> [    4.639231] Call trace:
> [    4.639235]  device_release+0x80/0x94 (P)
> [    4.639245]  device_release+0x80/0x94 (L)
> [    4.639253]  kobject_put+0xb0/0x214
> [    4.639264]  put_device+0x14/0x24
> [    4.639272]  genpd_remove+0x114/0x248
> [    4.639281]  pm_genpd_remove+0x30/0x58
> [    4.639288]  imx8m_blk_ctrl_probe+0x36c/0x540
> [    4.639299]  platform_probe+0x68/0xdc
> [    4.639308]  really_probe+0xc0/0x39c
> [    4.639315]  __driver_probe_device+0x7c/0x14c
> [    4.639322]  driver_probe_device+0x3c/0x120
> [    4.639329]  __device_attach_driver+0xbc/0x160
> [    4.639336]  bus_for_each_drv+0x88/0xe8
> [    4.639346]  __device_attach+0xa0/0x1b4
> [    4.639353]  device_initial_probe+0x14/0x20
> [    4.639360]  bus_probe_device+0xb0/0xbc
> [    4.639366]  deferred_probe_work_func+0xa0/0xf0
> [    4.639373]  process_one_work+0x148/0x284
> [    4.639383]  worker_thread+0x2d0/0x3e4
> [    4.639391]  kthread+0x110/0x114
> [    4.639399]  ret_from_fork+0x10/0x20
> [    4.639409] ---[ end trace 0000000000000000 ]---
> 
> and more for other devices, from the same driver.
> 
> Just reporting for the moment, in case someone has some ideas or
> wants to have a look.
> 
> Francesco



From xueshuai at linux.alibaba.com  Mon Dec 16 17:40:31 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Tue, 17 Dec 2024 09:40:31 +0800
Subject: [PATCH v17 1/3] ACPI: APEI: send SIGBUS to current task if
 synchronous memory error not recovered
In-Reply-To: <2fb8b1e5-d606-47be-a79e-a4e37a3b8f7f@oracle.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
 <20241202030527.20586-2-xueshuai@linux.alibaba.com>
 <2fb8b1e5-d606-47be-a79e-a4e37a3b8f7f@oracle.com>
Message-ID: <29d80fff-f33f-4470-a345-3f8f1a46f1af@linux.alibaba.com>



? 2024/12/17 07:37, jane.chu at oracle.com ??:
> 
> On 12/1/2024 7:05 PM, Shuai Xue wrote:
>> Synchronous error was detected as a result of user-space process accessing
>> a 2-bit uncorrected error. The CPU will take a synchronous error exception
>> such as Synchronous External Abort (SEA) on Arm64. The kernel will queue a
>> memory_failure() work which poisons the related page, unmaps the page, and
>> then sends a SIGBUS to the process, so that a system wide panic can be
>> avoided.
>>
>> However, no memory_failure() work will be queued when abnormal synchronous
>> errors occur. These errors can include situations such as invalid PA,
>> unexpected severity, no memory failure config support, invalid GUID
>> section, etc. In such case, the user-space process will trigger SEA again.
>> This loop can potentially exceed the platform firmware threshold or even
>> trigger a kernel hard lockup, leading to a system reboot.
>>
>> Fix it by performing a force kill if no memory_failure() work is queued
>> for synchronous errors.
>>
>> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
>> Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
>> Reviewed-by: Yazen Ghannam <yazen.ghannam at amd.com>
>> ---
>> ? drivers/acpi/apei/ghes.c | 11 +++++++++++
>> ? 1 file changed, 11 insertions(+)
>>
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index a2491905f165..106486bdfefc 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -801,6 +801,17 @@ static bool ghes_do_proc(struct ghes *ghes,
>> ????????? }
>> ????? }
>> +??? /*
>> +???? * If no memory failure work is queued for abnormal synchronous
>> +???? * errors, do a force kill.
>> +???? */
>> +??? if (sync && !queued) {
>> +??????? dev_err(ghes->dev,
>> +??????????? HW_ERR GHES_PFX "%s:%d: synchronous unrecoverable error (SIGBUS)\n",
>> +??????????? current->comm, task_pid_nr(current));
>> +??????? force_sig(SIGBUS);
>> +??? }
>> +
>> ????? return queued;
>> ? }
> 
> Looks good.
> 
> Reviewed-by: Jane Chu <jane.chu at oracle.com>
> 
> -jane

Thanks.

Best Regards,
Shuai


From xueshuai at linux.alibaba.com  Mon Dec 16 17:41:17 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Tue, 17 Dec 2024 09:41:17 +0800
Subject: [PATCH v17 3/3] ACPI: APEI: handle synchronous exceptions in task
 work
In-Reply-To: <d7adcb58-7a1d-4f0b-a55d-40c12ca60b02@oracle.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
 <20241202030527.20586-4-xueshuai@linux.alibaba.com>
 <d7adcb58-7a1d-4f0b-a55d-40c12ca60b02@oracle.com>
Message-ID: <8a8511f3-ace1-4187-8030-55a72573c63d@linux.alibaba.com>



? 2024/12/17 07:53, jane.chu at oracle.com ??:
> 
> On 12/1/2024 7:05 PM, Shuai Xue wrote:
>> The memory uncorrected error could be signaled by asynchronous interrupt
>> (specifically, SPI in arm64 platform), e.g. when an error is detected by
>> a background scrubber, or signaled by synchronous exception
>> (specifically, data abort exception in arm64 platform), e.g. when a CPU
>> tries to access a poisoned cache line. Currently, both synchronous and
>> asynchronous error use memory_failure_queue() to schedule
>> memory_failure() to exectute in a kworker context.
>>
>> As a result, when a user-space process is accessing a poisoned data, a
>> data abort is taken and the memory_failure() is executed in the kworker
>> context, memory_failure():
>>
>> ?? - will send wrong si_code by SIGBUS signal in early_kill mode, and
>> ?? - can not kill the user-space in some cases resulting a synchronous
>> ???? error infinite loop
>>
>> Issue 1: send wrong si_code in early_kill mode
>>
>> Since commit a70297d22132 ("ACPI: APEI: set memory failure flags as
>> MF_ACTION_REQUIRED on synchronous events")', the flag MF_ACTION_REQUIRED
>> could be used to determine whether a synchronous exception occurs on
>> ARM64 platform.? When a synchronous exception is detected, the kernel is
>> expected to terminate the current process which has accessed poisoned
>> page. This is done by sending a SIGBUS signal with an error code
>> BUS_MCEERR_AR, indicating an action-required machine check error on
>> read.
>>
>> However, when kill_proc() is called to terminate the processes who have
>> the poisoned page mapped, it sends the incorrect SIGBUS error code
>> BUS_MCEERR_AO because the context in which it operates is not the one
>> where the error was triggered.
>>
>> To reproduce this problem:
>>
>> ?? #sysctl -w vm.memory_failure_early_kill=1
>> ?? vm.memory_failure_early_kill = 1
>>
>> ?? # STEP2: inject an UCE error and consume it to trigger a synchronous error
>> ?? #einj_mem_uc single
>> ?? 0: single?? vaddr = 0xffffb0d75400 paddr = 4092d55b400
>> ?? injecting ...
>> ?? triggering ...
>> ?? signal 7 code 5 addr 0xffffb0d75000
>> ?? page not present
>> ?? Test passed
>>
>> The si_code (code 5) from einj_mem_uc indicates that it is BUS_MCEERR_AO
>> error and it is not the fact.
>>
>> After this patch:
>>
>> ?? # STEP1: enable early kill mode
>> ?? #sysctl -w vm.memory_failure_early_kill=1
>> ?? vm.memory_failure_early_kill = 1
>> ?? # STEP2: inject an UCE error and consume it to trigger a synchronous error
>> ?? #einj_mem_uc single
>> ?? 0: single?? vaddr = 0xffffb0d75400 paddr = 4092d55b400
>> ?? injecting ...
>> ?? triggering ...
>> ?? signal 7 code 4 addr 0xffffb0d75000
>> ?? page not present
>> ?? Test passed
>>
>> The si_code (code 4) from einj_mem_uc indicates that it is a BUS_MCEERR_AR
>> error as we expected.
>>
>> Issue 2: a synchronous error infinite loop
>>
>> If a user-space process, e.g. devmem, accesses a poisoned page for which
>> the HWPoison flag is set, kill_accessing_process() is called to send
>> SIGBUS to current processs with error info. Because the memory_failure()
>> is executed in the kworker context, it will just do nothing but return
>> EFAULT. So, devmem will access the posioned page and trigger an
>> exception again, resulting in a synchronous error infinite loop. Such
>> exception loop may cause platform firmware to exceed some threshold and
>> reboot when Linux could have recovered from this error.
>>
>> To reproduce this problem:
>>
>> ?? # STEP 1: inject an UCE error, and kernel will set HWPosion flag for related page
>> ?? #einj_mem_uc single
>> ?? 0: single?? vaddr = 0xffffb0d75400 paddr = 4092d55b400
>> ?? injecting ...
>> ?? triggering ...
>> ?? signal 7 code 4 addr 0xffffb0d75000
>> ?? page not present
>> ?? Test passed
>>
>> ?? # STEP 2: access the same page and it will trigger a synchronous error infinite loop
>> ?? devmem 0x4092d55b400
>>
>> To fix above two issues, queue memory_failure() as a task_work so that
>> it runs in the context of the process that is actually consuming the
>> poisoned data.
>>
>> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
>> Tested-by: Ma Wupeng <mawupeng1 at huawei.com>
>> Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>> Reviewed-by: Xiaofei Tan <tanxiaofei at huawei.com>
>> Reviewed-by: Baolin Wang <baolin.wang at linux.alibaba.com>
>> Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
>> ---
>> ? drivers/acpi/apei/ghes.c | 77 +++++++++++++++++++++++-----------------
>> ? include/acpi/ghes.h????? |? 3 --
>> ? include/linux/mm.h?????? |? 1 -
>> ? mm/memory-failure.c????? | 13 -------
>> ? 4 files changed, 44 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 106486bdfefc..70f2ee3ad1a8 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -467,28 +467,41 @@ static void ghes_clear_estatus(struct ghes *ghes,
>> ? }
>> ? /*
>> - * Called as task_work before returning to user-space.
>> - * Ensure any queued work has been done before we return to the context that
>> - * triggered the notification.
>> + * struct ghes_task_work - for synchronous RAS event
>> + *
>> + * @twork:??????????????? callback_head for task work
>> + * @pfn:????????????????? page frame number of corrupted page
>> + * @flags:??????????????? work control flags
>> + *
>> + * Structure to pass task work to be handled before
>> + * returning to user-space via task_work_add().
>> ?? */
>> -static void ghes_kick_task_work(struct callback_head *head)
>> +struct ghes_task_work {
>> +??? struct callback_head twork;
>> +??? u64 pfn;
>> +??? int flags;
>> +};
>> +
>> +static void memory_failure_cb(struct callback_head *twork)
>> ? {
>> -??? struct acpi_hest_generic_status *estatus;
>> -??? struct ghes_estatus_node *estatus_node;
>> -??? u32 node_len;
>> +??? struct ghes_task_work *twcb = container_of(twork, struct ghes_task_work, twork);
>> +??? int ret;
>> -??? estatus_node = container_of(head, struct ghes_estatus_node, task_work);
>> -??? if (IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
>> -??????? memory_failure_queue_kick(estatus_node->task_work_cpu);
>> +??? ret = memory_failure(twcb->pfn, twcb->flags);
>> +??? gen_pool_free(ghes_estatus_pool, (unsigned long)twcb, sizeof(*twcb));
>> -??? estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
>> -??? node_len = GHES_ESTATUS_NODE_LEN(cper_estatus_len(estatus));
>> -??? gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len);
>> +??? if (!ret || ret == -EHWPOISON || ret == -EOPNOTSUPP)
>> +??????? return;
>> +
>> +??? pr_err("%#llx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",
>> +??????????? twcb->pfn, current->comm, task_pid_nr(current));
>> +??? force_sig(SIGBUS);
>> ? }
>> ? static bool ghes_do_memory_failure(u64 physical_addr, int flags)
>> ? {
>> ????? unsigned long pfn;
>> +??? struct ghes_task_work *twcb;
>> ????? if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
>> ????????? return false;
>> @@ -501,6 +514,18 @@ static bool ghes_do_memory_failure(u64 physical_addr, int flags)
>> ????????? return false;
>> ????? }
>> +??? if (flags == MF_ACTION_REQUIRED && current->mm) {
>> +??????? twcb = (void *)gen_pool_alloc(ghes_estatus_pool, sizeof(*twcb));
>> +??????? if (!twcb)
>> +??????????? return false;
>> +
>> +??????? twcb->pfn = pfn;
>> +??????? twcb->flags = flags;
>> +??????? init_task_work(&twcb->twork, memory_failure_cb);
>> +??????? task_work_add(current, &twcb->twork, TWA_RESUME);
>> +??????? return true;
>> +??? }
>> +
>> ????? memory_failure_queue(pfn, flags);
>> ????? return true;
>> ? }
>> @@ -745,7 +770,7 @@ int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd)
>> ? }
>> ? EXPORT_SYMBOL_NS_GPL(cxl_cper_kfifo_get, CXL);
>> -static bool ghes_do_proc(struct ghes *ghes,
>> +static void ghes_do_proc(struct ghes *ghes,
>> ?????????????? const struct acpi_hest_generic_status *estatus)
>> ? {
>> ????? int sev, sec_sev;
>> @@ -811,8 +836,6 @@ static bool ghes_do_proc(struct ghes *ghes,
>> ????????????? current->comm, task_pid_nr(current));
>> ????????? force_sig(SIGBUS);
>> ????? }
>> -
>> -??? return queued;
>> ? }
>> ? static void __ghes_print_estatus(const char *pfx,
>> @@ -1114,9 +1137,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
>> ????? struct ghes_estatus_node *estatus_node;
>> ????? struct acpi_hest_generic *generic;
>> ????? struct acpi_hest_generic_status *estatus;
>> -??? bool task_work_pending;
>> ????? u32 len, node_len;
>> -??? int ret;
>> ????? llnode = llist_del_all(&ghes_estatus_llist);
>> ????? /*
>> @@ -1131,25 +1152,16 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
>> ????????? estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
>> ????????? len = cper_estatus_len(estatus);
>> ????????? node_len = GHES_ESTATUS_NODE_LEN(len);
>> -??????? task_work_pending = ghes_do_proc(estatus_node->ghes, estatus);
>> +
>> +??????? ghes_do_proc(estatus_node->ghes, estatus);
>> +
>> ????????? if (!ghes_estatus_cached(estatus)) {
>> ????????????? generic = estatus_node->generic;
>> ????????????? if (ghes_print_estatus(NULL, generic, estatus))
>> ????????????????? ghes_estatus_cache_add(generic, estatus);
>> ????????? }
>> -
>> -??????? if (task_work_pending && current->mm) {
>> -??????????? estatus_node->task_work.func = ghes_kick_task_work;
>> -??????????? estatus_node->task_work_cpu = smp_processor_id();
>> -??????????? ret = task_work_add(current, &estatus_node->task_work,
>> -??????????????????????? TWA_RESUME);
>> -??????????? if (ret)
>> -??????????????? estatus_node->task_work.func = NULL;
>> -??????? }
>> -
>> -??????? if (!estatus_node->task_work.func)
>> -??????????? gen_pool_free(ghes_estatus_pool,
>> -????????????????????? (unsigned long)estatus_node, node_len);
>> +??????? gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node,
>> +????????????????? node_len);
>> ????????? llnode = next;
>> ????? }
>> @@ -1210,7 +1222,6 @@ static int ghes_in_nmi_queue_one_entry(struct ghes *ghes,
>> ????? estatus_node->ghes = ghes;
>> ????? estatus_node->generic = ghes->generic;
>> -??? estatus_node->task_work.func = NULL;
>> ????? estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
>> ????? if (__ghes_read_estatus(estatus, buf_paddr, fixmap_idx, len)) {
>> diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
>> index be1dd4c1a917..ebd21b05fe6e 100644
>> --- a/include/acpi/ghes.h
>> +++ b/include/acpi/ghes.h
>> @@ -35,9 +35,6 @@ struct ghes_estatus_node {
>> ????? struct llist_node llnode;
>> ????? struct acpi_hest_generic *generic;
>> ????? struct ghes *ghes;
>> -
>> -??? int task_work_cpu;
>> -??? struct callback_head task_work;
>> ? };
>> ? struct ghes_estatus_cache {
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index c39c4945946c..aa4246c7c23e 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -3936,7 +3936,6 @@ enum mf_flags {
>> ? int mf_dax_kill_procs(struct address_space *mapping, pgoff_t index,
>> ??????????????? unsigned long count, int mf_flags);
>> ? extern int memory_failure(unsigned long pfn, int flags);
>> -extern void memory_failure_queue_kick(int cpu);
>> ? extern int unpoison_memory(unsigned long pfn);
>> ? extern atomic_long_t num_poisoned_pages __read_mostly;
>> ? extern int soft_offline_page(unsigned long pfn, int flags);
>> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
>> index 14c316d7d38d..e0adb665d07b 100644
>> --- a/mm/memory-failure.c
>> +++ b/mm/memory-failure.c
>> @@ -2499,19 +2499,6 @@ static void memory_failure_work_func(struct work_struct *work)
>> ????? }
>> ? }
>> -/*
>> - * Process memory_failure work queued on the specified CPU.
>> - * Used to avoid return-to-userspace racing with the memory_failure workqueue.
>> - */
>> -void memory_failure_queue_kick(int cpu)
>> -{
>> -??? struct memory_failure_cpu *mf_cpu;
>> -
>> -??? mf_cpu = &per_cpu(memory_failure_cpu, cpu);
>> -??? cancel_work_sync(&mf_cpu->work);
>> -??? memory_failure_work_func(&mf_cpu->work);
>> -}
>> -
>> ? static int __init memory_failure_init(void)
>> ? {
>> ????? struct memory_failure_cpu *mf_cpu;
> 
> Looks good.
> 
> Reviewed-by: Jane Chu <jane.chu at oracle.com>
> 
> -jane
> 

Thanks.

Best Regards,
Shuai


From quic_zhenhuah at quicinc.com  Mon Dec 16 17:47:03 2024
From: quic_zhenhuah at quicinc.com (Zhenhua Huang)
Date: Tue, 17 Dec 2024 09:47:03 +0800
Subject: [PATCH v2 0/2] Fix subsection vmemmap_populate logic
In-Reply-To: <20241209094227.1529977-1-quic_zhenhuah@quicinc.com>
References: <20241209094227.1529977-1-quic_zhenhuah@quicinc.com>
Message-ID: <9e5104c0-99ba-4519-b6b1-3b8e8196c9a5@quicinc.com>



On 2024/12/9 17:42, Zhenhua Huang wrote:
> To perform memory hotplug operations, the memmap (aka struct page) will be
> updated. For arm64 with 4K page size, the typical granularity is 128M,
> which corresponds to a 2M memmap buffer.
> Commit c1cc1552616d ("arm64: MMU initialisation")
> optimizes this 2M buffer to be mapped with one single PMD entry. However,
> commit ba72b4c8cf60 ("mm/sparsemem: support sub-section hotplug")
> which supports 2M subsection hotplug granularity, causes other issues
> (refer to the change log of patch #1). The logic is adjusted to populate
> with huge pages only if the hotplug address/size is section-aligned.
> 

Could any expert help review please?

> Changes since v1:
>    - Modified change log to make it more clear which was based on Catalin's
>      comments.
> 
> Zhenhua Huang (2):
>    arm64: mm: vmemmap populate to page level if not section aligned
>    arm64: mm: implement vmemmap_check_pmd for arm64
> 
>   arch/arm64/mm/mmu.c | 7 +++++--
>   1 file changed, 5 insertions(+), 2 deletions(-)
> 



From ck.hu at mediatek.com  Mon Dec 16 17:55:18 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 17 Dec 2024 01:55:18 +0000
Subject: [PATCH v2 12/15] drm/mediatek: mtk_hdmi: Split driver and add
 common probe function
In-Reply-To: <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-13-angelogioacchino.delregno@collabora.com>
Message-ID: <deb042d486fcccee6fb669d0dafd3da930f4c179.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for adding a new driver for the HDMI TX v2 IP,
> split out the functions that will be common between the already
> present mtk_hdmi (v1) driver and the new one.
> 
> Since the probe flow for both drivers is 90% similar, add a common
> probe function that will be called from each driver's .probe()
> callback, avoiding lots of code duplication.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

>  static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi)
> @@ -1143,10 +886,11 @@ static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi)
>  static enum drm_connector_status
>  mtk_hdmi_update_plugged_status(struct mtk_hdmi *hdmi)
>  {
> -       bool connected;
> +       bool connected = true;
> 
>         mutex_lock(&hdmi->update_plugged_status_lock);
> -       connected = mtk_cec_hpd_high(hdmi->cec_dev);
> +       if (hdmi->cec_dev)

Only v1 would call mtk_hdmi_update_plugged_status() and v1 should has hdmi->cec_dev,
so this checking is redundant.

> +               connected = mtk_cec_hpd_high(hdmi->cec_dev);
>         if (hdmi->plugged_cb && hdmi->codec_dev)
>                 hdmi->plugged_cb(hdmi->codec_dev, connected);
>         mutex_unlock(&hdmi->update_plugged_status_lock);
> @@ -1254,18 +998,12 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge,
>                         return ret;
>         }
> 
> -       mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, hdmi->dev);
> +       if (hdmi->cec_dev)

Ditto.

Regards,
CK

> +               mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, hdmi->dev);
> 
>         return 0;
>  }
> 


From peng.fan at oss.nxp.com  Mon Dec 16 17:58:26 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 17 Dec 2024 09:58:26 +0800
Subject: [PATCH V2] soc: imx8m: Add remove function
Message-ID: <20241217015826.1374497-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Unregister the cpufreq device and soc device in remove path, otherwise
there will be warning when do removing test:
sysfs: cannot create duplicate filename '/devices/platform/imx-cpufreq-dt'
CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.13.0-rc1-next-20241204
Hardware name: NXP i.MX8MPlus EVK board (DT)

Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as platform driver")
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---

V2:
 Add err check when create the cpufreq platform device

 drivers/soc/imx/soc-imx8m.c | 41 +++++++++++++++++++++++++++++++------
 1 file changed, 35 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
index 8ac7658e3d52..97c8718c2aa1 100644
--- a/drivers/soc/imx/soc-imx8m.c
+++ b/drivers/soc/imx/soc-imx8m.c
@@ -33,6 +33,11 @@ struct imx8_soc_data {
 	int (*soc_revision)(u32 *socrev, u64 *socuid);
 };
 
+struct imx8m_soc_priv {
+	struct soc_device *soc_dev;
+	struct platform_device *cpufreq_dev;
+};
+
 #ifdef CONFIG_HAVE_ARM_SMCCC
 static u32 imx8mq_soc_revision_from_atf(void)
 {
@@ -195,10 +200,11 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
 static int imx8m_soc_probe(struct platform_device *pdev)
 {
 	struct soc_device_attribute *soc_dev_attr;
+	struct platform_device *cpufreq_dev;
 	const struct imx8_soc_data *data;
 	struct device *dev = &pdev->dev;
 	const struct of_device_id *id;
-	struct soc_device *soc_dev;
+	struct imx8m_soc_priv *priv;
 	u32 soc_rev = 0;
 	u64 soc_uid = 0;
 	int ret;
@@ -207,6 +213,10 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 	if (!soc_dev_attr)
 		return -ENOMEM;
 
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
 	soc_dev_attr->family = "Freescale i.MX";
 
 	ret = of_property_read_string(of_root, "model", &soc_dev_attr->machine);
@@ -235,21 +245,40 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 	if (!soc_dev_attr->serial_number)
 		return -ENOMEM;
 
-	soc_dev = soc_device_register(soc_dev_attr);
-	if (IS_ERR(soc_dev))
-		return PTR_ERR(soc_dev);
+	priv->soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR(priv->soc_dev))
+		return PTR_ERR(priv->soc_dev);
 
 	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
 		soc_dev_attr->revision);
 
-	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
-		platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
+	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) {
+		cpufreq_dev = platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
+		if (!IS_ERR(cpufreq_dev))
+			priv->cpufreq_dev = cpufreq_dev;
+		else
+			dev_err(dev, "Failed to create imx-cpufreq-dev device: %ld",
+				PTR_ERR(cpufreq_dev));
+	}
+
+	platform_set_drvdata(pdev, priv);
 
 	return 0;
 }
 
+static void imx8m_soc_remove(struct platform_device *pdev)
+{
+	struct imx8m_soc_priv *priv = platform_get_drvdata(pdev);
+
+	if (priv->cpufreq_dev)
+		platform_device_unregister(priv->cpufreq_dev);
+
+	soc_device_unregister(priv->soc_dev);
+}
+
 static struct platform_driver imx8m_soc_driver = {
 	.probe = imx8m_soc_probe,
+	.remove	= imx8m_soc_remove,
 	.driver = {
 		.name = "imx8m-soc",
 	},
-- 
2.37.1



From gchen.guomin at gmail.com  Mon Dec 16 18:06:46 2024
From: gchen.guomin at gmail.com (gchen chen)
Date: Tue, 17 Dec 2024 10:06:46 +0800
Subject: [PATCH v2] firmware: arm_scmi: Delete the meaningless scmi_bus_id.
In-Reply-To: <Z2BQe3-zl2IN_Cjj@bogus>
References: <20241216073745.2973317-1-guomin_chen@sina.com>
 <Z1_p0nU93PHJ4Sg_@pluto> <Z1_2rxJ7TOEIOMp7@pluto> <CAEEwsfRhe4-YAwe027huSXwFfkV-O-8w1GDNf=URa9efRsXiKA@mail.gmail.com>
 <Z2AEzHc5f6TjxErs@bogus> <CAEEwsfRKVBVR+DxhkYA5atxU7+6nsaL9X8-Yoa_DqB0YKEV1zg@mail.gmail.com>
 <Z2BQe3-zl2IN_Cjj@bogus>
Message-ID: <CAEEwsfSYMx6Kdf2TK3hMN_TyoqEBbQXkCk_zPb+6-i=omZU_Fg@mail.gmail.com>

Sudeep Holla <sudeep.holla at arm.com> ?2024?12?17??? 00:08???
>
> On Mon, Dec 16, 2024 at 10:10:40PM +0800, gchen chen wrote:
> > Sudeep Holla <sudeep.holla at arm.com> ?2024?12?16??? 18:45???
>
> [...]
>
> > >
> > > I would like to understand the motivation behind this change. What is the
> > > goal ? Do you prefer to fetch the name and protocol id from the device
> > > name itself ? Is that your requirement.
> > >
> > hi Sudeep
> >     Okay, the reason I want to change names like 'scmi_dev.3' to
> > 'scmi_dev.firmware:scmi.perf.19' is because when I was migrating the
> > SOC's kernel from v6.1 to v6.6, I found that the context for creating
> > SCMI devices had changed (commit d3cd7c525fd2: firmware: arm_scmi:
> > Refactor protocol device creation).
>
> Correct. That's the beauty of Linux we can adjust the internals to enhance
> the features without breaking the user-space.
>
> > This change meant that device creation shifted from being directly
> > created through scmi_protocol_device_request during SCMI driver
> > registration to being created via scmi_device_request_notifier.
> > This shift results in changes to the order in which devices are created,
> > causing the ID in scmi_dev.id to drift.
> >
>
> What issue does this drift cause exactly ? I mean the order in which
> the devices are created should not impact on anything if the dependency
> on the order was not created. What was that dependency ?
>
Yes, my issue is that the loading order of the scmi_cpufreq_drv and
scmi_perf_domain_driver drivers causes other consumer devices to find
the wrong SCMI device as the supplier. Since both the scmi_cpufreq_drv
and scmi_perf_domain_driver drivers use the same device node (the same
SCMI_PROTOCOL_PERF), device_node.fwnode.dev will only point to the
SCMI device that was registered first.

Thanks

> > Additionally, I encountered some cpufreq errors here?because both
> > scmi_cpufreq_drv and scmi_perf_domain_driver use the same
> > SCMI_PROTOCOL_PERF, this results in two SCMI devices corresponding to
> > the same device node. However, device_node.fwnode.dev only points to
> > the first registered scmi_device, causing other consumer devices to
> > find the wrong scmi device as the supplier. So I would find a
> > multitude of other consumer devices waiting for meaningless device
> > names like "scmi_dev.4" instead of meaningful names such as
> > "scmi_dev.firmware:scmi.perf.19" or
> > "scmi_dev.firmware:scmi.cpufreq.19".
> >
>
> Yes this was reported. I think most of the std protocol may not use that
> node and need not be assigned. But I think vendor extensions are adding
> info to the DT that may need this.
>
> > Although I could further determine which specific driver it was by
> > looking at the driver links under the scmi_protocol bus directory, I
> > thought that if the logs directly displayed device names like
> > 'scmi_dev.firmware:scmi.perf.19' instead of meaningless progressive
> > IDs, it would be more convenient and logical, and thus more
> > meaningful.
> >
>
> If the issue you encountered render your platform into boot issues ?
> If so I would like to know what exactly happened. If not, I can think of
> alternate solution if possible.
>
> > > From the commit log, I get a sense that you looked at the code and thought
> > > of possible improvement but when we mentioned the limitation you just
> > > improvised by adding parent name. Do you expect any userspace to parse
> > > the name as that will end up being ABI and we can't break it. I need
> > > real motive to be explained here in detail.
> > >
> > I did not use userspace tools to parse this SCMI device name; I simply
> > wanted the name to reflect the possible logic of the device.
> > I did not remove scmi_dev.id (This scmi_device structure has not
> > changed.?; I just no longer assign values to it using scmi_bus_id, so
> > it should not affect the kernel ABI (kABI).
>
> I understand the change, just not the possible impact w.r.t user-space.
>
> --
> Regards,
> Sudeep


From chin-ting_kuo at aspeedtech.com  Mon Dec 16 18:15:18 2024
From: chin-ting_kuo at aspeedtech.com (Chin-Ting Kuo)
Date: Tue, 17 Dec 2024 02:15:18 +0000
Subject: [PATCH v4 1/3] watchdog: aspeed: Update bootstatus handling
In-Reply-To: <1bc83ee73545f9aab6e0a931cda8f5ffe41cb445.camel@codeconstruct.com.au>
References: <20241101121201.2464091-1-chin-ting_kuo@aspeedtech.com>
	 <20241101121201.2464091-2-chin-ting_kuo@aspeedtech.com>
	 <ZyUcIIb1dtoNhX00@heinlein.vulture-banana.ts.net>
	 <a0faca9a6ec7f4acdfa2f29b4ffb94b5392aea6b.camel@codeconstruct.com.au>
	 <TYZPR06MB5203053A004676F51322DECFB25C2@TYZPR06MB5203.apcprd06.prod.outlook.com>
	 <ed77d57facaaef0be796b4c6a742dc7bf3bff479.camel@codeconstruct.com.au>
	 <TYZPR06MB52039B02B6D3053355F30489B25D2@TYZPR06MB5203.apcprd06.prod.outlook.com>
	 <9a1e64ef-81d9-48b0-b871-ce4ff792eae4@roeck-us.net>
	 <TYZPR06MB52039DB39B62E6FA5220103AB2272@TYZPR06MB5203.apcprd06.prod.outlook.com>
	 <2531f830-6a36-4bd5-ba1e-9e19f0f66496@roeck-us.net>
	 <219607ab74764f3d47659fb5ab3223b3034152e5.camel@codeconstruct.com.au>
	 <9565c496-44d8-4214-8038-931926210d0f@roeck-us.net>
 <1bc83ee73545f9aab6e0a931cda8f5ffe41cb445.camel@codeconstruct.com.au>
Message-ID: <TYZPR06MB52039AB24714A400FF266024B2042@TYZPR06MB5203.apcprd06.prod.outlook.com>

Hi Andrew,

> -----Original Message-----
> From: Andrew Jeffery <andrew at codeconstruct.com.au>
> Sent: Wednesday, November 20, 2024 12:54 PM
> Subject: Re: [PATCH v4 1/3] watchdog: aspeed: Update bootstatus handling
> 
> On Mon, 2024-11-18 at 17:27 -0800, Guenter Roeck wrote:
> > So, again, what exactly would userspace do with the information that
> > this was a watchdog triggered warm reboot ? Why would it need that
> > information ?
> 
> I'll defer to the others on To/Cc to answer that.
> 
> My only position is I don't think changing behaviour of existing drivers to
> exploit WDIOF_EXTERN1 as a graceful-reboot indicator is a good idea either.
> Obviously I don't have much skin in the game with watchdog maintenance, so
> my thoughts shouldn't have much influence beyond the Aspeed-specifics, but I
> just didn't want to see some fun new confusion or incompatibility arise as a
> result.
> 
Agree to your misgiving, in the next patches, only two categories, "Power on reset"
and "WDT reset" (Card reset), will be taken into consideration. The graceful-reboot
scenario will be postponed to the patches in the future.


Thanks,
Chin-Ting


From ninad at linux.ibm.com  Mon Dec 16 18:20:39 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 20:20:39 -0600
Subject: [PATCH v3 1/4] hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
In-Reply-To: <20241217022046.113830-1-ninad@linux.ibm.com>
References: <20241217022046.113830-1-ninad@linux.ibm.com>
Message-ID: <20241217022046.113830-2-ninad@linux.ibm.com>

Add debugfs file for the PMBUS_REVISION command. This command provides
information about PMBus protocol revision number.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 drivers/hwmon/pmbus/pmbus_core.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index a7000314e5ad..787683e83db6 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -3534,11 +3534,11 @@ static int pmbus_init_debugfs(struct i2c_client *client,
 
 	/*
 	 * Allocate the max possible entries we need.
-	 * 6 entries device-specific
+	 * 7 entries device-specific
 	 * 10 entries page-specific
 	 */
 	entries = devm_kcalloc(data->dev,
-			       6 + data->info->pages * 10, sizeof(*entries),
+			       7 + data->info->pages * 10, sizeof(*entries),
 			       GFP_KERNEL);
 	if (!entries)
 		return -ENOMEM;
@@ -3551,6 +3551,15 @@ static int pmbus_init_debugfs(struct i2c_client *client,
 	 * assume that values of the following registers are the same for all
 	 * pages and report values only for page 0.
 	 */
+	if (pmbus_check_byte_register(client, 0, PMBUS_REVISION)) {
+		entries[idx].client = client;
+		entries[idx].page = 0;
+		entries[idx].reg = PMBUS_REVISION;
+		debugfs_create_file("revision", 0444, data->debugfs,
+				    &entries[idx++],
+				    &pmbus_debugfs_ops);
+	}
+
 	if (pmbus_check_block_register(client, 0, PMBUS_MFR_ID)) {
 		entries[idx].client = client;
 		entries[idx].page = 0;
-- 
2.43.0



From ninad at linux.ibm.com  Mon Dec 16 18:20:40 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 20:20:40 -0600
Subject: [PATCH v3 2/4] hwmon: (pmbus/crps) Add Intel CRPS185 power supply
In-Reply-To: <20241217022046.113830-1-ninad@linux.ibm.com>
References: <20241217022046.113830-1-ninad@linux.ibm.com>
Message-ID: <20241217022046.113830-3-ninad@linux.ibm.com>

Add the driver to monitor Intel common redundant power supply (crps185)
with hwmon over pmbus.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 Documentation/hwmon/crps.rst  | 97 +++++++++++++++++++++++++++++++++++
 Documentation/hwmon/index.rst |  1 +
 MAINTAINERS                   |  7 +++
 drivers/hwmon/pmbus/Kconfig   |  9 ++++
 drivers/hwmon/pmbus/Makefile  |  1 +
 drivers/hwmon/pmbus/crps.c    | 74 ++++++++++++++++++++++++++
 6 files changed, 189 insertions(+)
 create mode 100644 Documentation/hwmon/crps.rst
 create mode 100644 drivers/hwmon/pmbus/crps.c

diff --git a/Documentation/hwmon/crps.rst b/Documentation/hwmon/crps.rst
new file mode 100644
index 000000000000..87380b496558
--- /dev/null
+++ b/Documentation/hwmon/crps.rst
@@ -0,0 +1,97 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver crps
+==================
+
+Supported chips:
+
+  * Intel CRPS185
+
+    Prefix: 'crps185'
+
+    Addresses scanned: -
+
+    Datasheet: Only available under NDA.
+
+Authors:
+    Ninad Palsule <ninad at linux.ibm.com>
+
+
+Description
+-----------
+
+This driver implements support for Intel Common Redundant Power supply with
+PMBus support.
+
+The driver is a client driver to the core PMBus driver.
+Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers.
+
+
+Usage Notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices.rst for
+details.
+
+
+Sysfs entries
+-------------
+
+======================= ======================================================
+curr1_label		"iin"
+curr1_input		Measured input current
+curr1_max		Maximum input current
+curr1_max_alarm		Input maximum current high alarm
+curr1_crit		Critial high input current
+curr1_crit_alarm	Input critical current high alarm
+curr1_rated_max		Maximum rated input current
+
+curr2_label		"iout1"
+curr2_input		Measured output current
+curr2_max		Maximum output current
+curr2_max_alarm		Output maximum current high alarm
+curr2_crit		Critial high output current
+curr2_crit_alarm	Output critical current high alarm
+curr2_rated_max		Maximum rated output current
+
+in1_label		"vin"
+in1_input		Measured input voltage
+in1_crit		Critical input over voltage
+in1_crit_alarm		Critical input over voltage alarm
+in1_max			Maximum input over voltage
+in1_max_alarm		Maximum input over voltage alarm
+in1_rated_min		Minimum rated input voltage
+in1_rated_max		Maximum rated input voltage
+
+in2_label		"vout1"
+in2_input		Measured input voltage
+in2_crit		Critical input over voltage
+in2_crit_alarm		Critical input over voltage alarm
+in2_lcrit		Critical input under voltage fault
+in2_lcrit_alarm		Critical input under voltage fault alarm
+in2_max			Maximum input over voltage
+in2_max_alarm		Maximum input over voltage alarm
+in2_min			Minimum input under voltage warning
+in2_min_alarm		Minimum input under voltage warning alarm
+in2_rated_min		Minimum rated input voltage
+in2_rated_max		Maximum rated input voltage
+
+power1_label		"pin"
+power1_input		Measured input power
+power1_alarm		Input power high alarm
+power1_max  		Maximum input power
+power1_rated_max	Maximum rated input power
+
+temp[1-2]_input		Measured temperature
+temp[1-2]_crit 		Critical temperature
+temp[1-2]_crit_alarm	Critical temperature alarm
+temp[1-2]_max		Maximum temperature
+temp[1-2]_max_alarm	Maximum temperature alarm
+temp[1-2]_rated_max	Maximum rated temperature
+
+fan1_alarm		Fan 1 warning.
+fan1_fault		Fan 1 fault.
+fan1_input		Fan 1 speed in RPM.
+fan1_target		Fan 1 target.
+======================= ======================================================
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 1a3cb0a59f72..b1ea445479b0 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -58,6 +58,7 @@ Hardware Monitoring Kernel Drivers
    corsair-cpro
    corsair-psu
    cros_ec_hwmon
+   crps
    da9052
    da9055
    dell-smm-hwmon
diff --git a/MAINTAINERS b/MAINTAINERS
index 7523a456fd6f..e194478ecc55 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6118,6 +6118,13 @@ L:	linux-input at vger.kernel.org
 S:	Maintained
 F:	drivers/hid/hid-creative-sb0540.c
 
+INTEL CRPS COMMON REDUNDANT PSU DRIVER
+M:	Ninad Palsule <ninad at linux.ibm.com>
+L:	linux-hwmon at vger.kernel.org
+S:	Maintained
+F:	Documentation/hwmon/crps.rst
+F:	drivers/hwmon/pmbus/crps.c
+
 CRYPTO API
 M:	Herbert Xu <herbert at gondor.apana.org.au>
 M:	"David S. Miller" <davem at davemloft.net>
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 22418a05ced0..43b6df04e0f9 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -85,6 +85,15 @@ config SENSORS_BPA_RS600
 	  This driver can also be built as a module. If so, the module will
 	  be called bpa-rs600.
 
+config SENSORS_CRPS
+	tristate "Intel Common Redundant Power Supply"
+	help
+	  If you say yes here you get hardware monitoring support for the Intel
+	  Common Redundant Power Supply.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called crps.
+
 config SENSORS_DELTA_AHE50DC_FAN
 	tristate "Delta AHE-50DC fan control module"
 	help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 3d3183f8d2a7..c7eb7739b7f8 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -62,3 +62,4 @@ obj-$(CONFIG_SENSORS_XDPE122)	+= xdpe12284.o
 obj-$(CONFIG_SENSORS_XDPE152)	+= xdpe152c4.o
 obj-$(CONFIG_SENSORS_ZL6100)	+= zl6100.o
 obj-$(CONFIG_SENSORS_PIM4328)	+= pim4328.o
+obj-$(CONFIG_SENSORS_CRPS)	+= crps.o
diff --git a/drivers/hwmon/pmbus/crps.c b/drivers/hwmon/pmbus/crps.c
new file mode 100644
index 000000000000..164b33fed312
--- /dev/null
+++ b/drivers/hwmon/pmbus/crps.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2024 IBM Corp.
+ */
+
+#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/pmbus.h>
+
+#include "pmbus.h"
+
+static const struct i2c_device_id crps_id[] = {
+	{ "intel_crps185" },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, crps_id);
+
+static struct pmbus_driver_info crps_info = {
+	.pages = 1,
+	/* PSU uses default linear data format. */
+	.func[0] = PMBUS_HAVE_PIN | PMBUS_HAVE_IOUT |
+		PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_IIN |
+		PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
+		PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+		PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
+		PMBUS_HAVE_STATUS_TEMP |
+		PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
+};
+
+static int crps_probe(struct i2c_client *client)
+{
+	int rc;
+	struct device *dev = &client->dev;
+	char buf[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
+
+	rc = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
+	if (rc < 0)
+		return dev_err_probe(dev, rc, "Failed to read PMBUS_MFR_MODEL\n");
+
+	if (rc != 7 || strncmp(buf, "03NK260", 7)) {
+		buf[rc] = '\0';
+		return dev_err_probe(dev, -ENODEV, "Model '%s' not supported\n", buf);
+	}
+
+	rc = pmbus_do_probe(client, &crps_info);
+	if (rc)
+		return dev_err_probe(dev, rc, "Failed to probe\n");
+
+	return 0;
+}
+
+static const struct of_device_id crps_of_match[] = {
+	{
+		.compatible = "intel,crps185",
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, crps_of_match);
+
+static struct i2c_driver crps_driver = {
+	.driver = {
+		.name = "crps",
+		.of_match_table = crps_of_match,
+	},
+	.probe = crps_probe,
+	.id_table = crps_id,
+};
+
+module_i2c_driver(crps_driver);
+
+MODULE_AUTHOR("Ninad Palsule");
+MODULE_DESCRIPTION("PMBus driver for Intel Common Redundant power supplies");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("PMBUS");
-- 
2.43.0



From ninad at linux.ibm.com  Mon Dec 16 18:20:41 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 20:20:41 -0600
Subject: [PATCH v3 3/4] dt-bindings: hwmon: intel,crps185: Add to trivial
In-Reply-To: <20241217022046.113830-1-ninad@linux.ibm.com>
References: <20241217022046.113830-1-ninad@linux.ibm.com>
Message-ID: <20241217022046.113830-4-ninad@linux.ibm.com>

Add INTEL Common Redundant Power Supply Versions crps185 bindings as
trivial. It is trivial because only compatibility string is required in
the device tree to load this driver.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index 34e8ac1ddc24..fadbd3c041c8 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -149,6 +149,8 @@ properties:
           - injoinic,ip5306
             # Inspur Power System power supply unit version 1
           - inspur,ipsps1
+            # Intel common redudant power supply crps185
+          - intel,crps185
             # Intersil ISL29028 Ambient Light and Proximity Sensor
           - isil,isl29028
             # Intersil ISL29030 Ambient Light and Proximity Sensor
-- 
2.43.0



From ninad at linux.ibm.com  Mon Dec 16 18:20:38 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 20:20:38 -0600
Subject: [PATCH v3 0/4] Add support for Intel CRPS PSU
Message-ID: <20241217022046.113830-1-ninad@linux.ibm.com>

Hello,

Please review the version 3 of patchset.

V3:
---
  - Improved documentation as per suggestion.
  - Fixed issues in the probe function.
  - Add ACKed string in the commit message
V2:
---
  - Fixed documentation issues.
  - Added pmbus revision debugfs file in the core
  - Remove debugfs and read word from crps185
  - Improved commit messages

Ninad Palsule (4):
  hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
  hwmon: (pmbus/crps) Add Intel CRPS185 power supply
  dt-bindings: hwmon: intel,crps185: Add to trivial
  ARM: dts: aspeed: system1: Use crps PSU driver

 .../devicetree/bindings/trivial-devices.yaml  |  2 +
 Documentation/hwmon/crps.rst                  | 97 +++++++++++++++++++
 Documentation/hwmon/index.rst                 |  1 +
 MAINTAINERS                                   |  7 ++
 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     |  8 +-
 drivers/hwmon/pmbus/Kconfig                   |  9 ++
 drivers/hwmon/pmbus/Makefile                  |  1 +
 drivers/hwmon/pmbus/crps.c                    | 74 ++++++++++++++
 drivers/hwmon/pmbus/pmbus_core.c              | 13 ++-
 9 files changed, 206 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/hwmon/crps.rst
 create mode 100644 drivers/hwmon/pmbus/crps.c

-- 
2.43.0



From ninad at linux.ibm.com  Mon Dec 16 18:20:42 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Mon, 16 Dec 2024 20:20:42 -0600
Subject: [PATCH v3 4/4] ARM: dts: aspeed: system1: Use crps PSU driver
In-Reply-To: <20241217022046.113830-1-ninad@linux.ibm.com>
References: <20241217022046.113830-1-ninad@linux.ibm.com>
Message-ID: <20241217022046.113830-5-ninad@linux.ibm.com>

The system1 uses Intel common redundant (crps185) power supplies so move
to correct new crps driver.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index 8f77bc9e860c..360b9ce3c850 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -681,22 +681,22 @@ &i2c2 {
 	status = "okay";
 
 	power-supply at 58 {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x58>;
 	};
 
 	power-supply at 59 {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x59>;
 	};
 
 	power-supply at 5a {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x5a>;
 	};
 
 	power-supply at 5b {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x5b>;
 	};
 };
-- 
2.43.0



From damon.ding at rock-chips.com  Mon Dec 16 18:32:33 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Tue, 17 Dec 2024 10:32:33 +0800
Subject: [PATCH v2 00/11] Add eDP support for RK3588
In-Reply-To: <173436598997.265439.13057492933592323468.robh@kernel.org>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <173436598997.265439.13057492933592323468.robh@kernel.org>
Message-ID: <7c1b03e1-8e0e-4a17-8cbf-ed43459f61df@rock-chips.com>

Hi Rob,

On 2024/12/17 0:29, Rob Herring (Arm) wrote:
> 
> On Mon, 16 Dec 2024 11:12:14 +0800, Damon Ding wrote:
>> These patchs have been tested with a 1536x2048p60 eDP panel on
>> RK3588S EVB1 board, and HDMI 1080P/4K display also has been verified
>> on RK3588 EVB1 board.
>>
>> Patch 1~3 are the RK3588 eDP support of Rockchip analogix_dp driver.
>> Patch 4   is the eDP mode support of samsung hdptx phy driver.
>> Patch 5~6 are the Rk3588 eDP support of Aanalogix DP driver. Add phy
>>            interfaces is to configure the HDMI/eDP TX Combo PHY.
>> Patch 7~8 are the renaming of hdptxphy node. It is not only used by
>>            HDMI display but also for the eDP display.
>> Patch 9   is the addition of RK3588 eDP0 node.
>> Patch 10  is to enable the eDP0 display on RK3588S EVB1 board.
>> Patch 11  is to add the eDP1 related nodes for RK3588 SoC.
>>
>> Damon Ding (11):
>>    drm/rockchip: analogix_dp: Use formalized struct definition for grf
>>      field
>>    dt-bindings: display: rockchip: analogix-dp: Add support for RK3588
>>    drm/rockchip: analogix_dp: Add support for RK3588
>>    phy: phy-rockchip-samsung-hdptx: Add support for eDP mode
>>    drm/bridge: analogix_dp: add support for RK3588
>>    drm/bridge: analogix_dp: Add support for phy configuration.
>>    dt-bindings: display: rockchip: Fix label name of hdptxphy for RK3588
>>      HDMI TX Controller
>>    arm64: dts: rockchip: Fix label name of hdptxphy for RK3588
>>    arm64: dts: rockchip: Add eDP0 node for RK3588
>>    arm64: dts: rockchip: Enable eDP0 display on RK3588S EVB1 board
>>    arm64: dts: rockchip: Add nodes related to eDP1 for RK3588
>>
>>   .../rockchip/rockchip,analogix-dp.yaml        |   1 +
>>   .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml  |   2 +-
>>   arch/arm64/boot/dts/rockchip/rk3588-base.dtsi |  33 +-
>>   .../dts/rockchip/rk3588-coolpi-cm5-evb.dts    |   2 +-
>>   .../rockchip/rk3588-coolpi-cm5-genbook.dts    |   2 +-
>>   .../boot/dts/rockchip/rk3588-evb1-v10.dts     |   2 +-
>>   .../arm64/boot/dts/rockchip/rk3588-extra.dtsi |  55 +
>>   .../rk3588-friendlyelec-cm3588-nas.dts        |   2 +-
>>   .../arm64/boot/dts/rockchip/rk3588-jaguar.dts |   2 +-
>>   .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi   |   2 +-
>>   .../dts/rockchip/rk3588-orangepi-5-plus.dts   |   2 +-
>>   .../boot/dts/rockchip/rk3588-rock-5b.dts      |   2 +-
>>   .../boot/dts/rockchip/rk3588-tiger-haikou.dts |   2 +-
>>   .../boot/dts/rockchip/rk3588s-coolpi-4b.dts   |   2 +-
>>   .../boot/dts/rockchip/rk3588s-evb1-v10.dts    |  50 +
>>   .../dts/rockchip/rk3588s-indiedroid-nova.dts  |   2 +-
>>   .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi  |   2 +-
>>   .../boot/dts/rockchip/rk3588s-odroid-m2.dts   |   2 +-
>>   .../boot/dts/rockchip/rk3588s-orangepi-5.dtsi |   2 +-
>>   .../boot/dts/rockchip/rk3588s-rock-5a.dts     |   2 +-
>>   .../boot/dts/rockchip/rk3588s-rock-5c.dts     |   2 +-
>>   .../drm/bridge/analogix/analogix_dp_core.c    |   5 +
>>   .../gpu/drm/bridge/analogix/analogix_dp_reg.c |  56 ++
>>   .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 149 ++-
>>   .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 937 +++++++++++++++++-
>>   include/drm/bridge/analogix_dp.h              |   3 +-
>>   26 files changed, 1223 insertions(+), 100 deletions(-)
>>
>> --
>> 2.34.1
>>
>>
>>
> 
> 
> My bot found new DTB warnings on the .dts files added or changed in this
> series.
> 
> Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
> are fixed by another series. Ultimately, it is up to the platform
> maintainer whether these warnings are acceptable or not. No need to reply
> unless the platform maintainer has comments.
> 
> If you already ran DT checks and didn't see these error(s), then
> make sure dt-schema is up to date:
> 
>    pip3 install dtschema --upgrade
> 
> 
> New warnings running 'make CHECK_DTBS=y rockchip/rk3588-coolpi-cm5-evb.dtb rockchip/rk3588-coolpi-cm5-genbook.dtb rockchip/rk3588-evb1-v10.dtb rockchip/rk3588-friendlyelec-cm3588-nas.dtb rockchip/rk3588-jaguar.dtb rockchip/rk3588-orangepi-5-plus.dtb rockchip/rk3588-rock-5b.dtb rockchip/rk3588-tiger-haikou.dtb rockchip/rk3588s-coolpi-4b.dtb rockchip/rk3588s-evb1-v10.dtb rockchip/rk3588s-indiedroid-nova.dtb rockchip/rk3588s-odroid-m2.dtb rockchip/rk3588s-rock-5a.dtb rockchip/rk3588s-rock-5c.dtb' for 20241216031225.3746-1-damon.ding at rock-chips.com:
> 
> arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dtb: edp at fdec0000: resets: [[28, 469], [28, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dtb: edp at fdec0000: Unevaluated properties are not allowed ('#sound-dai-cells', 'reset-names', 'resets' were unexpected)
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fded0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fded0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-jaguar.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fded0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fded0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fded0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fded0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dtb: edp at fdec0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dtb: edp at fdec0000: resets: [[31, 469], [31, 468]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dtb: edp at fdec0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fded0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fded0000: clock-names:2: 'grf' was expected
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fded0000: resets: [[31, 471], [31, 470]] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dtb: edp at fded0000: reset-names: ['dp', 'apb'] is too long
> 	from schema $id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> 
> 
> 
> 
> 
> 
> 
I found the same warnings when dt-schema was updated, and all of these 
will be fixed in the next version.

Best regards,
Damon




From zhangqing at rock-chips.com  Mon Dec 16 18:39:07 2024
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 17 Dec 2024 10:39:07 +0800
Subject: [PATCH 1/2] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20241217023908.1292999-1-zhangqing@rock-chips.com>
References: <20241217023908.1292999-1-zhangqing@rock-chips.com>
Message-ID: <20241217023908.1292999-2-zhangqing@rock-chips.com>

Is new controller:
Support CAN and CANFD protocol.
Support DMA.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 drivers/net/can/rockchip/Kconfig        |   10 +
 drivers/net/can/rockchip/Makefile       |    1 +
 drivers/net/can/rockchip/rk3576_canfd.c | 1349 +++++++++++++++++++++++
 3 files changed, 1360 insertions(+)
 create mode 100644 drivers/net/can/rockchip/rk3576_canfd.c

diff --git a/drivers/net/can/rockchip/Kconfig b/drivers/net/can/rockchip/Kconfig
index d203c530551f..78c2990e374e 100644
--- a/drivers/net/can/rockchip/Kconfig
+++ b/drivers/net/can/rockchip/Kconfig
@@ -8,3 +8,13 @@ config CAN_ROCKCHIP_CANFD
 	help
 	  Say Y here if you want to use CAN-FD controller found on
 	  Rockchip SoCs.
+
+config CANFD_RK3576
+	tristate "RK3576 CANFD controller"
+	depends on OF
+	depends on ARCH_ROCKCHIP || COMPILE_TEST
+	help
+	  Say Y here if you want to use CANFD controller found on RK3576 SoCs.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called rk3576_canfd.
diff --git a/drivers/net/can/rockchip/Makefile b/drivers/net/can/rockchip/Makefile
index 3760d3e1baa3..151f9e0ee6aa 100644
--- a/drivers/net/can/rockchip/Makefile
+++ b/drivers/net/can/rockchip/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_CAN_ROCKCHIP_CANFD) += rockchip_canfd.o
+obj-$(CONFIG_CANFD_RK3576) += rk3576_canfd.o
 
 rockchip_canfd-objs :=
 rockchip_canfd-objs += rockchip_canfd-core.o
diff --git a/drivers/net/can/rockchip/rk3576_canfd.c b/drivers/net/can/rockchip/rk3576_canfd.c
new file mode 100644
index 000000000000..663f6e3a68ab
--- /dev/null
+++ b/drivers/net/can/rockchip/rk3576_canfd.c
@@ -0,0 +1,1349 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ * Rk3576 CANFD driver
+ */
+
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/reset.h>
+#include <linux/pm_runtime.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+
+/* registers definition */
+enum rk3576_canfd_reg {
+	CANFD_MODE = 0x00,
+	CANFD_CMD = 0x04,
+	CANFD_STATE = 0x08,
+	CANFD_INT = 0x0c,
+	CANFD_INT_MASK = 0x10,
+	CANFD_NBTP = 0x100,
+	CANFD_DBTP = 0x104,
+	CANFD_TDCR = 0x108,
+	CANFD_BRS_CFG = 0x10c,
+	CANFD_DMA_CTRL = 0x11c,
+	CANFD_TXFIC = 0x200,
+	CANFD_TXID = 0x204,
+	CANFD_TXDAT0 = 0x208,
+	CANFD_TXDAT1 = 0x20c,
+	CANFD_TXDAT2 = 0x210,
+	CANFD_TXDAT3 = 0x214,
+	CANFD_TXDAT4 = 0x218,
+	CANFD_TXDAT5 = 0x21c,
+	CANFD_TXDAT6 = 0x220,
+	CANFD_TXDAT7 = 0x224,
+	CANFD_TXDAT8 = 0x228,
+	CANFD_TXDAT9 = 0x22c,
+	CANFD_TXDAT10 = 0x230,
+	CANFD_TXDAT11 = 0x234,
+	CANFD_TXDAT12 = 0x238,
+	CANFD_TXDAT13 = 0x23c,
+	CANFD_TXDAT14 = 0x240,
+	CANFD_TXDAT15 = 0x244,
+	CANFD_RXFIC = 0x300,
+	CANFD_RXID = 0x304,
+	CANFD_RXTS = 0x308,
+	CANFD_RXDAT0 = 0x30c,
+	CANFD_RXDAT1 = 0x310,
+	CANFD_RXDAT2 = 0x314,
+	CANFD_RXDAT3 = 0x318,
+	CANFD_RXDAT4 = 0x31c,
+	CANFD_RXDAT5 = 0x320,
+	CANFD_RXDAT6 = 0x324,
+	CANFD_RXDAT7 = 0x328,
+	CANFD_RXDAT8 = 0x32c,
+	CANFD_RXDAT9 = 0x330,
+	CANFD_RXDAT10 = 0x334,
+	CANFD_RXDAT11 = 0x338,
+	CANFD_RXDAT12 = 0x33c,
+	CANFD_RXDAT13 = 0x340,
+	CANFD_RXDAT14 = 0x344,
+	CANFD_RXDAT15 = 0x348,
+	CANFD_RXFRD = 0x400,
+	CANFD_STR_CTL = 0x600,
+	CANFD_STR_STATE = 0x604,
+	CANFD_STR_TIMEOUT = 0x608,
+	CANFD_STR_WTM = 0x60c,
+	CANFD_EXTM_START_ADDR = 0x610,
+	CANFD_EXTM_SIZE = 0x614,
+	CANFD_EXTM_WADDR = 0x618,
+	CANFD_EXTM_RADDR = 0x61c,
+	CANFD_EXTM_AHB_TXTHR = 0x620,
+	CANFD_EXTM_LEFT_CNT = 0x624,
+	CANFD_ATF0 = 0x700,
+	CANFD_ATF1 = 0x704,
+	CANFD_ATF2 = 0x708,
+	CANFD_ATF3 = 0x70c,
+	CANFD_ATF4 = 0x710,
+	CANFD_ATFM0 = 0x714,
+	CANFD_ATFM1 = 0x718,
+	CANFD_ATFM2 = 0x71c,
+	CANFD_ATFM3 = 0x720,
+	CANFD_ATFM4 = 0x724,
+	CANFD_ATF_DLC = 0x728,
+	CANFD_ATF_CTL = 0x72c,
+	CANFD_SPACE_CTRL = 0x800,
+	CANFD_AUTO_RETX_CFG = 0x808,
+	CANFD_AUTO_RETX_STATE0 = 0x80c,
+	CANFD_AUTO_RETX_STATE1 = 0x810,
+	CANFD_OLF_CFG = 0x814,
+	CANFD_RXINT_CTRL = 0x818,
+	CANFD_RXINT_TIMEOUT = 0x81c,
+	CANFD_OTHER_CFG = 0x820,
+	CANFD_WAVE_FILTER_CFG = 0x824,
+	CANFD_RBC_CFG = 0x828,
+	CANFD_TXCRC_CFG = 0x82c,
+	CANFD_BUSOFFRCY_CFG = 0x830,
+	CANFD_BUSOFF_RCY_THR = 0x834,
+	CANFD_ERROR_CODE = 0x900,
+	CANFD_ERROR_MASK = 0x904,
+	CANFD_RXERRORCNT = 0x910,
+	CANFD_TXERRORCNT = 0x914,
+	CANFD_RX_RXSRAM_RDATA = 0xc00,
+	CANFD_RTL_VERSION = 0xf0c,
+};
+
+#define DATE_LENGTH_12_BYTE	(0x9)
+#define DATE_LENGTH_16_BYTE	(0xa)
+#define DATE_LENGTH_20_BYTE	(0xb)
+#define DATE_LENGTH_24_BYTE	(0xc)
+#define DATE_LENGTH_32_BYTE	(0xd)
+#define DATE_LENGTH_48_BYTE	(0xe)
+#define DATE_LENGTH_64_BYTE	(0xf)
+
+#define CANFD_TX0_REQ		BIT(0)
+#define CANFD_TX1_REQ		BIT(1)
+#define CANFD_TX_REQ_FULL	((CANFD_TX0_REQ) | (CANFD_TX1_REQ))
+
+#define MODE_PASS_ERR		BIT(10)
+#define MODE_DIS_PEE		BIT(9)
+#define MODE_RETT		BIT(8)
+#define MODE_AUTO_BUS_ON	BIT(7)
+#define MODE_COVER		BIT(6)
+#define MODE_RXSTX		BIT(5)
+#define MODE_LBACK		BIT(4)
+#define MODE_SILENT		BIT(3)
+#define MODE_SELF_TEST		BIT(2)
+#define MODE_SLEEP		BIT(1)
+#define RESET_MODE		0
+#define WORK_MODE		BIT(0)
+
+#define RETX_TIME_LIMIT_CNT	0x12c /* 300 */
+#define RETX_TIME_LIMIT_SHIFT	3
+#define RETX_LIMIT_EN		BIT(1)
+#define AUTO_RETX_EN		BIT(0)
+
+#define ERR_WARNING_STATE	BIT(3)
+#define BUS_OFF_STATE		BIT(4)
+
+#define RX_FINISH_INT		BIT(0)
+#define TX_FINISH_INT		BIT(1)
+#define ERR_WARN_INT		BIT(2)
+#define RX_BUF_OV_INT		BIT(3)
+#define PASSIVE_ERR_INT		BIT(4)
+#define TX_LOSTARB_INT		BIT(5)
+#define BUS_ERR_INT		BIT(6)
+#define RX_STR_FULL_INT	BIT(7)
+#define RX_STR_OV_INT		BIT(8)
+#define BUS_OFF_INT		BIT(9)
+#define BUS_OFF_RECOVERY_INT	BIT(10)
+#define WAKEUP_INT		BIT(11)
+#define AUTO_RETX_FAIL_INT	BIT(12)
+#define MFI_INT	BIT(13)
+#define MFI_TIMEOUT		BIT(14)
+#define RX_STR_TIMEOUT_INT	BIT(15)
+#define BUSINT_INT		BIT(16)
+#define ISM_WTM_INT		BIT(17)
+#define ESM_WTM_INT		BIT(18)
+#define BUSOFF_RCY_INT		BIT(19)
+
+#define INT_ENABLE		BIT(0)
+
+#define ERR_PHASE		BIT(28)
+#define ARB_PHASE		0
+#define DATA_PHASE		1
+#define ERR_TYPE_MASK		GENMASK(27, 25)
+#define ERR_TYPE_SHIFT		25
+#define BIT_ERROR		0
+#define BIT_STUFF_ERROR		1
+#define FORM_ERROR		2
+#define ACK_ERROR		3
+#define CRC_ERROR		4
+#define TRANSMIT_ACK_EOF	BIT(24)
+#define TRANSMIT_CRC		BIT(23)
+#define TRANSMIT_STUFF_COUNT	BIT(22)
+#define TRANSMIT_DATA		BIT(21)
+#define TRANSMIT_SOF_DLC	BIT(20)
+#define TRANSMIT_IDLE		BIT(19)
+#define RECEIVE_ERROR		BIT(18)
+#define RECEIVE_OVERLOAD	BIT(17)
+#define RECEIVE_SPACE		BIT(16)
+#define RECEIVE_EOF		BIT(15)
+#define RECEIVE_ACK_LIM		BIT(14)
+#define RECEIVE_ACK_SLOT	BIT(13)
+#define RECEIVE_CRC_LIM		BIT(12)
+#define RECEIVE_CRC		BIT(11)
+#define RECEIVE_STUFF_COUNT	BIT(10)
+#define RECEIVE_DATA		BIT(9)
+#define RECEIVE_DLC		BIT(8)
+#define RECEIVE_BRS_ESI		BIT(7)
+#define RECEIVE_RES		BIT(6)
+#define RECEIVE_FDF		BIT(5)
+#define RECEIVE_ID2_RTR		BIT(4)
+#define RECEIVE_SOF_IDE		BIT(3)
+#define RECEIVE_BUS_IDLE	BIT(2)
+#define RECEIVE_BUS_INT		BIT(1)
+#define RECEIVE_STOP		BIT(0)
+
+/* Nominal Bit Timing & Prescaler Register (NBTP) */
+#define NBTP_MODE_3_SAMPLES	BIT(31)
+#define NBTP_NSJW_SHIFT		24
+#define NBTP_NSJW_MASK		(0x7f << NBTP_NSJW_SHIFT)
+#define NBTP_NBRP_SHIFT		16
+#define NBTP_NBRP_MASK		(0xff << NBTP_NBRP_SHIFT)
+#define NBTP_NTSEG2_SHIFT	8
+#define NBTP_NTSEG2_MASK	(0x7f << NBTP_NTSEG2_SHIFT)
+#define NBTP_NTSEG1_SHIFT	0
+#define NBTP_NTSEG1_MASK	(0xff << NBTP_NTSEG1_SHIFT)
+
+/* Data Bit Timing & Prescaler Register (DBTP) */
+#define DBTP_BRS_TSEG1_SHIFT	24
+#define DBTP_BRS_TSEG1_MASK	(0xff << DBTP_BRS_TSEG1_SHIFT)
+#define DBTP_BRS_MODE		BIT(23)
+#define DBTP_MODE_3_SAMPLES	BIT(21)
+#define DBTP_DSJW_SHIFT		17
+#define DBTP_DSJW_MASK		(0xf << DBTP_DSJW_SHIFT)
+#define DBTP_DBRP_SHIFT		9
+#define DBTP_DBRP_MASK		(0xff << DBTP_DBRP_SHIFT)
+#define DBTP_DTSEG2_SHIFT	5
+#define DBTP_DTSEG2_MASK	(0xf << DBTP_DTSEG2_SHIFT)
+#define DBTP_DTSEG1_SHIFT	0
+#define DBTP_DTSEG1_MASK	(0x1f << DBTP_DTSEG1_SHIFT)
+
+/* Transmitter Delay Compensation Register (TDCR) */
+#define TDCR_TDCO_SHIFT		1
+#define TDCR_TDCO_MASK		(0x3f << TDCR_TDCO_SHIFT)
+#define TDCR_TDC_ENABLE		BIT(0)
+
+#define RX_DMA_ENABLE		BIT(9)
+
+#define TX_FD_ENABLE		BIT(5)
+#define TX_FD_BRS_ENABLE	BIT(4)
+
+#define TX_FORMAT_SHIFT		7
+#define TX_FORMAT_MASK		(0x1 << TX_FORMAT_SHIFT)
+#define TX_RTR_SHIFT		6
+#define TX_RTR_MASK		(0x1 << TX_RTR_SHIFT)
+#define TX_FDF_SHIFT		5
+#define TX_FDF_MASK		(0x1 << TX_FDF_SHIFT)
+#define TX_BRS_SHIFT		4
+#define TX_BRS_MASK		(0x1 << TX_BRS_SHIFT)
+#define TX_DLC_SHIFT		0
+#define TX_DLC_MASK		(0xF << TX_DLC_SHIFT)
+
+#define RX_FORMAT_SHIFT		23
+#define RX_FORMAT_MASK		(0x1 << RX_FORMAT_SHIFT)
+#define RX_RTR_SHIFT		22
+#define RX_RTR_MASK		(0x1 << RX_RTR_SHIFT)
+#define RX_FDF_SHIFT		21
+#define RX_FDF_MASK		(0x1 << RX_FDF_SHIFT)
+#define RX_BRS_SHIFT		20
+#define RX_BRS_MASK		(0x1 << RX_BRS_SHIFT)
+#define RX_DLC_SHIFT		24
+#define RX_DLC_MASK		(0xF << RX_DLC_SHIFT)
+#define RX_ISM_LEN_SHIFT	8
+#define RX_ISM_LEN_MASK		(0xF << RX_ISM_LEN_SHIFT)
+
+#define BUFFER_MODE_ENABLE	BIT(0)
+#define EXT_STORAGE_MODE	BIT(1)
+#define ISM_SEL_SHIFT		2
+#define ISM_SEL_MASK		(0x3 << ISM_SEL_SHIFT)
+#define RX_STORAGE_RESET	BIT(4)
+#define ESM_SEL_SHIFT		6
+#define ESM_SEL_MASK		(0x3 << ESM_SEL_SHIFT)
+#define STORAGE_TIMEOUT_MODE	BIT(8)
+
+#define INTM_CNT_SHIFT		17
+#define INTM_CNT_MASK		(0x1ff << INTM_CNT_SHIFT)
+#define INTM_LEFT_CNT_SHIFT	8
+#define INTM_LEFT_CNT_MASK	(0x1ff << INTM_LEFT_CNT_SHIFT)
+#define EXTM_FULL		BIT(3)
+#define EXTM_EMPTY		BIT(2)
+#define INTM_FULL		BIT(1)
+#define INTM_EMPTY		BIT(0)
+
+#define EXTTM_LEFT_CNT_SHIFT	0
+#define EXTTM_LEFT_CNT_MASK	(0x3fffff << EXTTM_LEFT_CNT_SHIFT)
+
+#define ISM_WATERMASK_CAN	0x6c /* word */
+#define ISM_WATERMASK_CANFD	0x6c /* word */
+#define ESM_WATERMASK		(0x50 << 8) /* word */
+
+#define BUSOFF_RCY_MODE_EN	BIT(8)
+#define BUSOFF_RCY_TIME_CLR	BIT(9)
+#define BUSOFF_RCY_CNT_FAST	4
+#define BUSOFF_RCY_CNT_SLOW	5
+#define BUSOFF_RCY_TIME_FAST	0x3d0900 /* 40ms : cnt * (1 / can_clk) */
+#define BUSOFF_RCY_TIME_SLOW	0x1312d00 /* 200ms : cnt * (1 / can_clk) */
+
+#define ATF_MASK		BIT(31)
+#define ATF_RTR_EN		BIT(30)
+#define ATF_RTR			BIT(29)
+
+#define ATF_DLC_MODE		BIT(5)
+#define ATF_DLC_EN		BIT(4)
+#define ATF_DLC_SHIFT		0
+#define ATF_DLC_MASK		(0xf << ATF_DLC_SHIFT)
+
+#define ATF_DIS(n)		BIT(n)
+
+#define ACK_ERROR_MASK		BIT(4)
+#define FORM_ERROR_MASK		BIT(3)
+#define CRC_ERROR_MASK		BIT(2)
+#define STUFF_ERROR_MASK	BIT(1)
+#define BIT_ERROR_MASK		BIT(0)
+
+#define SRAM_MAX_DEPTH		256 /* word */
+#define EXT_MEM_SIZE		0x2000 /* 8KByte */
+
+#define CANFD_FILTER_MASK	0x1fffffff
+
+#define CANFD_FIFO_CNT_MASK	0xff
+
+#define CANBUSOFF_RCY_SLOW	200 /* ms */
+#define CANBUSOFF_RCY_FAST	30 /* ms */
+
+#define DRV_NAME		"rk3576_canfd"
+
+enum rk3576_canfd_atf_mode {
+	CANFD_ATF_MASK_MODE = 0,
+	CANFD_ATF_LIST_MODE,
+};
+
+enum rk3576_canfd_storage_mode {
+	CANFD_DATA_FLEXIBLE = 0,
+	CANFD_DATA_CAN_FIXED,
+	CANFD_DATA_CANFD_FIXED,
+};
+
+/* rk3576_canfd private data structure */
+
+struct rk3576_canfd {
+	struct can_priv can;
+	struct device *dev;
+	struct napi_struct napi;
+	struct clk_bulk_data *clks;
+	int num_clks;
+	struct reset_control *reset;
+	void __iomem *base;
+	u32 irqstatus;
+	unsigned long mode;
+	int rx_fifo_shift;
+	u32 rx_fifo_mask;
+	int rx_fifo_depth;
+	int rx_max_data;
+	bool use_dma;
+	u32 dma_size;
+	int quota;
+	struct dma_chan *rxchan;
+	u32 *rxbuf;
+	dma_addr_t rx_dma_src_addr;
+	dma_addr_t rx_dma_dst_addr;
+};
+
+static inline u32 rk3576_canfd_read(const struct rk3576_canfd *priv,
+				    enum rk3576_canfd_reg reg)
+{
+	return readl(priv->base + reg);
+}
+
+static inline void rk3576_canfd_write(const struct rk3576_canfd *priv,
+				      enum rk3576_canfd_reg reg, u32 val)
+{
+	writel(val, priv->base + reg);
+}
+
+static const struct can_bittiming_const rk3576_canfd_bittiming_const = {
+	.name = DRV_NAME,
+	.tseg1_min = 1,
+	.tseg1_max = 128,
+	.tseg2_min = 1,
+	.tseg2_max = 128,
+	.sjw_max = 128,
+	.brp_min = 1,
+	.brp_max = 256,
+	.brp_inc = 2,
+};
+
+static const struct can_bittiming_const rk3576_canfd_data_bittiming_const = {
+	.name = DRV_NAME,
+	.tseg1_min = 1,
+	.tseg1_max = 32,
+	.tseg2_min = 1,
+	.tseg2_max = 16,
+	.sjw_max = 16,
+	.brp_min = 1,
+	.brp_max = 256,
+	.brp_inc = 2,
+};
+
+static int set_reset_mode(struct net_device *ndev)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+
+	reset_control_assert(rcan->reset);
+	udelay(2);
+	reset_control_deassert(rcan->reset);
+
+	rk3576_canfd_write(rcan, CANFD_MODE, 0);
+
+	netdev_dbg(ndev, "%s MODE=0x%08x\n", __func__,
+		   rk3576_canfd_read(rcan, CANFD_MODE));
+
+	return 0;
+}
+
+static int set_normal_mode(struct net_device *ndev)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	u32 val;
+
+	val = rk3576_canfd_read(rcan, CANFD_MODE);
+	val |= WORK_MODE;
+	rk3576_canfd_write(rcan, CANFD_MODE, val);
+
+	netdev_dbg(ndev, "%s MODE=0x%08x\n", __func__,
+		   rk3576_canfd_read(rcan, CANFD_MODE));
+	return 0;
+}
+
+/* bittiming is called in reset_mode only */
+static int rk3576_canfd_set_bittiming(struct net_device *ndev)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	const struct can_bittiming *bt = &rcan->can.bittiming;
+	const struct can_bittiming *dbt = &rcan->can.data_bittiming;
+	u16 brp, sjw, tseg1, tseg2;
+	u32 reg_btp;
+
+	brp = (bt->brp >> 1) - 1;
+	sjw = bt->sjw - 1;
+	tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
+	tseg2 = bt->phase_seg2 - 1;
+	reg_btp = (brp << NBTP_NBRP_SHIFT) | (sjw << NBTP_NSJW_SHIFT) |
+		  (tseg1 << NBTP_NTSEG1_SHIFT) |
+		  (tseg2 << NBTP_NTSEG2_SHIFT);
+
+	if (rcan->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+		reg_btp |= NBTP_MODE_3_SAMPLES;
+
+	rk3576_canfd_write(rcan, CANFD_NBTP, reg_btp);
+
+	if (rcan->can.ctrlmode & CAN_CTRLMODE_FD) {
+		reg_btp = 0;
+		brp = (dbt->brp >> 1) - 1;
+		sjw = dbt->sjw - 1;
+		tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
+		tseg2 = dbt->phase_seg2 - 1;
+		if (sjw < 2)
+			sjw = 2;
+
+		if (dbt->bitrate > 2200000) {
+			u32 tdco;
+
+			/* Equation based on Bosch's ROCKCHIP_CANFD User Manual's
+			 * Transmitter Delay Compensation Section
+			 */
+			tdco = ((1 + 1 + tseg1) * (brp + 1)) - 2;
+			/* Max valid TDCO value is 63 */
+			if (tdco > 63)
+				tdco = 63;
+			rk3576_canfd_write(rcan, CANFD_TDCR,
+					   (tdco << TDCR_TDCO_SHIFT) |
+					   TDCR_TDC_ENABLE);
+		} else {
+			rk3576_canfd_write(rcan, CANFD_TDCR, 0);
+		}
+
+		reg_btp |= (brp << DBTP_DBRP_SHIFT) |
+			   (sjw << DBTP_DSJW_SHIFT) |
+			   (tseg1 << DBTP_DTSEG1_SHIFT) |
+			   (tseg2 << DBTP_DTSEG2_SHIFT) |
+			   DBTP_BRS_MODE |
+			   ((tseg1 / 2) << DBTP_BRS_TSEG1_SHIFT);
+
+		if (rcan->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+			reg_btp |= DBTP_MODE_3_SAMPLES;
+
+		rk3576_canfd_write(rcan, CANFD_DBTP, reg_btp);
+	}
+
+	netdev_dbg(ndev, "%s NBTP=0x%08x, DBTP=0x%08x, TDCR=0x%08x\n", __func__,
+		   rk3576_canfd_read(rcan, CANFD_NBTP),
+		   rk3576_canfd_read(rcan, CANFD_DBTP),
+		   rk3576_canfd_read(rcan, CANFD_TDCR));
+	return 0;
+}
+
+static int rk3576_canfd_get_berr_counter(const struct net_device *ndev,
+					 struct can_berr_counter *bec)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	int err;
+
+	err = pm_runtime_get_sync(rcan->dev);
+	if (err < 0) {
+		netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
+			   __func__, err);
+		return err;
+	}
+
+	bec->rxerr = rk3576_canfd_read(rcan, CANFD_RXERRORCNT);
+	bec->txerr = rk3576_canfd_read(rcan, CANFD_TXERRORCNT);
+
+	pm_runtime_put(rcan->dev);
+
+	netdev_dbg(ndev, "%s RX_ERR_CNT=0x%08x, TX_ERR_CNT=0x%08x\n", __func__,
+		   rk3576_canfd_read(rcan, CANFD_RXERRORCNT),
+		   rk3576_canfd_read(rcan, CANFD_TXERRORCNT));
+
+	return 0;
+}
+
+static int rk3576_canfd_atf_config(const struct net_device *ndev, int mode)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	u32 id[10] = {0};
+	u32 dlc = 0, dlc_over = 0;
+
+	switch (mode) {
+	case CANFD_ATF_MASK_MODE:
+		rk3576_canfd_write(rcan, CANFD_ATF0, id[0]);
+		rk3576_canfd_write(rcan, CANFD_ATF1, id[1]);
+		rk3576_canfd_write(rcan, CANFD_ATF2, id[2]);
+		rk3576_canfd_write(rcan, CANFD_ATF3, id[3]);
+		rk3576_canfd_write(rcan, CANFD_ATF4, id[4]);
+		rk3576_canfd_write(rcan, CANFD_ATFM0, 0x7fff);
+		rk3576_canfd_write(rcan, CANFD_ATFM1, 0x7fff);
+		rk3576_canfd_write(rcan, CANFD_ATFM2, 0x7fff);
+		rk3576_canfd_write(rcan, CANFD_ATFM3, 0x7fff);
+		rk3576_canfd_write(rcan, CANFD_ATFM4, 0x7fff);
+		break;
+	case CANFD_ATF_LIST_MODE:
+		rk3576_canfd_write(rcan, CANFD_ATF0, id[0]);
+		rk3576_canfd_write(rcan, CANFD_ATF1, id[1]);
+		rk3576_canfd_write(rcan, CANFD_ATF2, id[2]);
+		rk3576_canfd_write(rcan, CANFD_ATF3, id[3]);
+		rk3576_canfd_write(rcan, CANFD_ATF4, id[4]);
+		rk3576_canfd_write(rcan, CANFD_ATFM0, id[5] | (1 << 31));
+		rk3576_canfd_write(rcan, CANFD_ATFM1, id[6] | (1 << 31));
+		rk3576_canfd_write(rcan, CANFD_ATFM2, id[7] | (1 << 31));
+		rk3576_canfd_write(rcan, CANFD_ATFM3, id[8] | (1 << 31));
+		rk3576_canfd_write(rcan, CANFD_ATFM4, id[9] | (1 << 31));
+		break;
+	default:
+		rk3576_canfd_write(rcan, CANFD_ATF_CTL, 0xffff);
+		return -EINVAL;
+	}
+
+	if (dlc) {
+		if (dlc_over)
+			rk3576_canfd_write(rcan, CANFD_ATF_DLC, dlc | (1 << 4));
+		else
+			rk3576_canfd_write(rcan, CANFD_ATF_DLC, dlc | (1 << 4) | (1 << 5));
+	}
+	rk3576_canfd_write(rcan, CANFD_ATF_CTL, 0);
+
+	return 0;
+}
+
+static int rk3576_canfd_start(struct net_device *ndev)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	u32 val, ism = 0, water = 0;
+
+	/* we need to enter the reset mode */
+	set_reset_mode(ndev);
+
+	rk3576_canfd_write(rcan, CANFD_INT_MASK, INT_ENABLE);
+	rk3576_canfd_atf_config(ndev, CANFD_ATF_MASK_MODE);
+
+	/* set mode */
+	val = rk3576_canfd_read(rcan, CANFD_MODE);
+
+	if (rcan->rx_max_data > 4) {
+		ism = CANFD_DATA_CANFD_FIXED;
+		water = ISM_WATERMASK_CANFD;
+	} else {
+		ism = CANFD_DATA_CAN_FIXED;
+		water = ISM_WATERMASK_CAN;
+	}
+
+	/* internal sram mode */
+	rk3576_canfd_write(rcan, CANFD_STR_CTL,
+			   (ism << ISM_SEL_SHIFT) | STORAGE_TIMEOUT_MODE);
+	rk3576_canfd_write(rcan, CANFD_STR_WTM, water);
+
+	/* Loopback Mode */
+	if (rcan->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+		val |= MODE_LBACK;
+		rk3576_canfd_write(rcan, CANFD_ERROR_MASK, ACK_ERROR_MASK);
+	} else if (rcan->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+		val |= MODE_SILENT;
+		rk3576_canfd_write(rcan, CANFD_ERROR_MASK, ACK_ERROR_MASK);
+	} else {
+		rk3576_canfd_write(rcan, CANFD_ERROR_MASK, 0);
+	}
+
+	rk3576_canfd_write(rcan, CANFD_AUTO_RETX_CFG,
+			   AUTO_RETX_EN | RETX_LIMIT_EN |
+			   (RETX_TIME_LIMIT_CNT << RETX_TIME_LIMIT_SHIFT));
+
+	rk3576_canfd_write(rcan, CANFD_MODE, val);
+	if (rcan->use_dma)
+		rk3576_canfd_write(rcan, CANFD_DMA_CTRL, RX_DMA_ENABLE);
+
+	rk3576_canfd_write(rcan, CANFD_BRS_CFG, 0x7);
+
+	rk3576_canfd_write(rcan, CANFD_BUSOFFRCY_CFG, BUSOFF_RCY_MODE_EN | BUSOFF_RCY_CNT_FAST);
+	rk3576_canfd_write(rcan, CANFD_BUSOFF_RCY_THR, BUSOFF_RCY_TIME_FAST);
+
+	rk3576_canfd_set_bittiming(ndev);
+
+	set_normal_mode(ndev);
+
+	rcan->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	netdev_dbg(ndev, "%s MODE=0x%08x, INT_MASK=0x%08x\n", __func__,
+		   rk3576_canfd_read(rcan, CANFD_MODE),
+		   rk3576_canfd_read(rcan, CANFD_INT_MASK));
+
+	return 0;
+}
+
+static int rk3576_canfd_stop(struct net_device *ndev)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+
+	rcan->can.state = CAN_STATE_STOPPED;
+	/* we need to enter reset mode */
+	set_reset_mode(ndev);
+
+	/* disable all interrupts */
+	rk3576_canfd_write(rcan, CANFD_INT_MASK, 0xffffffff);
+
+	netdev_dbg(ndev, "%s MODE=0x%08x, INT_MASK=0x%08x\n", __func__,
+		   rk3576_canfd_read(rcan, CANFD_MODE),
+		   rk3576_canfd_read(rcan, CANFD_INT_MASK));
+	return 0;
+}
+
+static int rk3576_canfd_set_mode(struct net_device *ndev,
+				 enum can_mode mode)
+{
+	int err;
+
+	switch (mode) {
+	case CAN_MODE_START:
+		err = rk3576_canfd_start(ndev);
+		if (err) {
+			netdev_err(ndev, "starting CANFD controller failed!\n");
+			return err;
+		}
+		if (netif_queue_stopped(ndev))
+			netif_wake_queue(ndev);
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+/* transmit a CANFD message
+ * message layout in the sk_buff should be like this:
+ * xx xx xx xx ff ll 00 11 22 33 44 55 66 77
+ * [ can_id ] [flags] [len] [can data (up to 8 bytes]
+ */
+static netdev_tx_t rk3576_canfd_start_xmit(struct sk_buff *skb,
+					   struct net_device *ndev)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	struct canfd_frame *cf = (struct canfd_frame *)skb->data;
+	u32 id, dlc;
+	u32 cmd = CANFD_TX0_REQ;
+	int i;
+
+	if (can_dropped_invalid_skb(ndev, skb))
+		return NETDEV_TX_OK;
+
+	netif_stop_queue(ndev);
+
+	if (rk3576_canfd_read(rcan, CANFD_CMD) & CANFD_TX0_REQ)
+		cmd = CANFD_TX1_REQ;
+
+	/* Watch carefully on the bit sequence */
+	if (cf->can_id & CAN_EFF_FLAG) {
+		/* Extended CANFD ID format */
+		id = cf->can_id & CAN_EFF_MASK;
+		dlc = can_fd_len2dlc(cf->len) & TX_DLC_MASK;
+		dlc |= TX_FORMAT_MASK;
+
+		/* Extended frames remote TX request */
+		if (cf->can_id & CAN_RTR_FLAG)
+			dlc |= TX_RTR_MASK;
+	} else {
+		/* Standard CANFD ID format */
+		id = cf->can_id & CAN_SFF_MASK;
+		dlc = can_fd_len2dlc(cf->len) & TX_DLC_MASK;
+
+		/* Standard frames remote TX request */
+		if (cf->can_id & CAN_RTR_FLAG)
+			dlc |= TX_RTR_MASK;
+	}
+
+	if ((rcan->can.ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) {
+		dlc |= TX_FD_ENABLE;
+		if (cf->flags & CANFD_BRS)
+			dlc |= TX_FD_BRS_ENABLE;
+	}
+
+	rk3576_canfd_write(rcan, CANFD_TXID, id);
+	rk3576_canfd_write(rcan, CANFD_TXFIC, dlc);
+
+	for (i = 0; i < cf->len; i += 4)
+		rk3576_canfd_write(rcan, CANFD_TXDAT0 + i,
+				   *(u32 *)(cf->data + i));
+
+	can_put_echo_skb(skb, ndev, 0, 0);
+
+	rk3576_canfd_write(rcan, CANFD_CMD, cmd);
+
+	return NETDEV_TX_OK;
+}
+
+static int rk3576_canfd_rx(struct net_device *ndev, u32 addr)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct canfd_frame *cf;
+	struct sk_buff *skb;
+	u32 id_rk3576_canfd, dlc;
+	int i = 0;
+	u32 __maybe_unused ts, ret;
+	u32 data[16] = {0};
+
+	if (rcan->use_dma) {
+		dlc = readl(rcan->rxbuf + addr * rcan->rx_max_data);
+		id_rk3576_canfd = readl(rcan->rxbuf + 1 + addr * rcan->rx_max_data);
+		for (i = 0; i < (rcan->rx_max_data - 2); i++)
+			data[i] = readl(rcan->rxbuf + 2 + i + addr * rcan->rx_max_data);
+	} else {
+		dlc = rk3576_canfd_read(rcan, addr);
+		id_rk3576_canfd = rk3576_canfd_read(rcan, addr);
+		for (i = 0; i < (rcan->rx_max_data - 2); i++)
+			data[i] = rk3576_canfd_read(rcan, addr);
+	}
+
+	/* create zero'ed CANFD frame buffer */
+	if (dlc & RX_FDF_MASK)
+		skb = alloc_canfd_skb(ndev, &cf);
+	else
+		skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
+	if (!skb) {
+		stats->rx_dropped++;
+		return 1;
+	}
+
+	/* Change CANFD data length format to SocketCAN data format */
+	if (dlc & RX_FDF_MASK)
+		cf->len = can_fd_dlc2len((dlc & RX_DLC_MASK) >> RX_DLC_SHIFT);
+	else
+		cf->len = can_cc_dlc2len((dlc & RX_DLC_MASK) >> RX_DLC_SHIFT);
+
+	/* Change CANFD ID format to SocketCAN ID format */
+	if (dlc & RX_FORMAT_MASK) {
+		/* The received frame is an Extended format frame */
+		cf->can_id = id_rk3576_canfd;
+		cf->can_id |= CAN_EFF_FLAG;
+		if (dlc & RX_RTR_MASK)
+			cf->can_id |= CAN_RTR_FLAG;
+	} else {
+		/* The received frame is a standard format frame */
+		cf->can_id = id_rk3576_canfd;
+		if (dlc & RX_RTR_MASK)
+			cf->can_id |= CAN_RTR_FLAG;
+	}
+
+	if (dlc & RX_BRS_MASK)
+		cf->flags |= CANFD_BRS;
+
+	if (!(cf->can_id & CAN_RTR_FLAG)) {
+		/* Change CANFD data format to SocketCAN data format */
+		for (i = 0; i < cf->len; i += 4)
+			*(u32 *)(cf->data + i) = data[i / 4];
+	}
+
+	stats->rx_packets++;
+	stats->rx_bytes += cf->len;
+	netif_rx(skb);
+
+	return 1;
+}
+
+/* rk3576_canfd_rx_poll - Poll routine for rx packets (NAPI)
+ * @napi:	napi structure pointer
+ * @quota:	Max number of rx packets to be processed.
+ *
+ * This is the poll routine for rx part.
+ * It will process the packets maximux quota value.
+ *
+ * Return: number of packets received
+ */
+static int rk3576_canfd_rx_poll(struct napi_struct *napi, int quota)
+{
+	struct net_device *ndev = napi->dev;
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	int work_done = 0, cnt = 0;
+
+	if (rcan->use_dma) {
+		while (work_done < rcan->quota)
+			work_done += rk3576_canfd_rx(ndev, work_done);
+
+		if (work_done <= rcan->rx_fifo_depth) {
+			napi_complete_done(napi, work_done);
+			rk3576_canfd_write(rcan, CANFD_INT_MASK, INT_ENABLE);
+		}
+	} else {
+		quota = (rk3576_canfd_read(rcan, CANFD_STR_STATE) & rcan->rx_fifo_mask) >>
+			rcan->rx_fifo_shift;
+		quota = quota / rcan->rx_max_data;
+		cnt = (rk3576_canfd_read(rcan, CANFD_STR_STATE) & INTM_CNT_MASK) >> INTM_CNT_SHIFT;
+		if (quota != cnt)
+			quota = ((rk3576_canfd_read(rcan, CANFD_STR_STATE) & rcan->rx_fifo_mask) >>
+				rcan->rx_fifo_shift) / rcan->rx_max_data;
+
+		while (work_done < quota)
+			work_done += rk3576_canfd_rx(ndev, CANFD_RXFRD);
+
+		if (work_done <= rcan->rx_fifo_depth) {
+			napi_complete_done(napi, work_done);
+			rk3576_canfd_write(rcan, CANFD_INT_MASK, INT_ENABLE);
+		}
+	}
+	return work_done;
+}
+
+static void rk3576_canfd_rx_dma_callback(void *data)
+{
+	struct rk3576_canfd *rcan = data;
+
+	napi_schedule(&rcan->napi);
+}
+
+static int rk3576_canfd_rx_dma(struct rk3576_canfd *rcan)
+{
+	struct dma_async_tx_descriptor *rxdesc = NULL;
+	int quota = 0, cnt = 0;
+
+	quota = (rk3576_canfd_read(rcan, CANFD_STR_STATE) & rcan->rx_fifo_mask) >>
+		rcan->rx_fifo_shift;
+	quota = quota / rcan->rx_max_data;
+	cnt = (rk3576_canfd_read(rcan, CANFD_STR_STATE) & INTM_CNT_MASK) >> INTM_CNT_SHIFT;
+
+	if (quota != cnt)
+		quota = ((rk3576_canfd_read(rcan, CANFD_STR_STATE) & rcan->rx_fifo_mask) >>
+			rcan->rx_fifo_shift) / rcan->rx_max_data;
+
+	rcan->quota = quota;
+	if (rcan->quota == 0)
+		return 1;
+
+	rxdesc = dmaengine_prep_slave_single(rcan->rxchan, rcan->rx_dma_dst_addr,
+					     rcan->dma_size * rcan->quota, DMA_DEV_TO_MEM, 0);
+	if (!rxdesc)
+		return -EBUSY;
+
+	rxdesc->callback = rk3576_canfd_rx_dma_callback;
+	rxdesc->callback_param = rcan;
+
+	dmaengine_submit(rxdesc);
+	dma_async_issue_pending(rcan->rxchan);
+	return 1;
+}
+
+static int rk3576_canfd_err(struct net_device *ndev, u32 isr)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	unsigned int rxerr, txerr;
+	u32 sta_reg;
+
+	skb = alloc_can_err_skb(ndev, &cf);
+
+	rxerr = rk3576_canfd_read(rcan, CANFD_RXERRORCNT);
+	txerr = rk3576_canfd_read(rcan, CANFD_TXERRORCNT);
+	sta_reg = rk3576_canfd_read(rcan, CANFD_STATE);
+
+	if (skb) {
+		cf->data[6] = txerr;
+		cf->data[7] = rxerr;
+	}
+
+	if (isr & BUS_OFF_INT) {
+		rcan->can.state = CAN_STATE_BUS_OFF;
+		rcan->can.can_stats.bus_off++;
+		cf->can_id |= CAN_ERR_BUSOFF;
+	} else if (isr & PASSIVE_ERR_INT) {
+		rcan->can.can_stats.error_passive++;
+		rcan->can.state = CAN_STATE_ERROR_PASSIVE;
+		/* error passive state */
+		cf->can_id |= CAN_ERR_CRTL;
+		cf->data[1] = (txerr > rxerr) ?
+					CAN_ERR_CRTL_TX_WARNING :
+					CAN_ERR_CRTL_RX_WARNING;
+		cf->data[6] = txerr;
+		cf->data[7] = rxerr;
+	}
+	if (sta_reg & ERR_WARNING_STATE) {
+		rcan->can.can_stats.error_warning++;
+		rcan->can.state = CAN_STATE_ERROR_WARNING;
+		/* error warning state */
+		if (likely(skb)) {
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] = (txerr > rxerr) ?
+				CAN_ERR_CRTL_TX_WARNING :
+				CAN_ERR_CRTL_RX_WARNING;
+			cf->data[6] = txerr;
+			cf->data[7] = rxerr;
+		}
+	}
+
+	if (isr & BUSOFF_RCY_INT) {
+		rk3576_canfd_write(rcan, CANFD_INT_MASK, 0xffff);
+		rk3576_canfd_write(rcan, CANFD_INT, isr);
+		napi_schedule(&rcan->napi);
+		rk3576_canfd_write(rcan, CANFD_BUSOFFRCY_CFG, BUSOFF_RCY_TIME_CLR);
+		rk3576_canfd_write(rcan, CANFD_BUSOFF_RCY_THR, BUSOFF_RCY_TIME_SLOW);
+		rk3576_canfd_write(rcan, CANFD_BUSOFFRCY_CFG,
+				   BUSOFF_RCY_MODE_EN | BUSOFF_RCY_CNT_SLOW);
+		rk3576_canfd_write(rcan, CANFD_INT_MASK, INT_ENABLE);
+		netif_stop_queue(ndev);
+		can_free_echo_skb(ndev, 0, NULL);
+		netif_start_queue(ndev);
+	}
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+	netif_rx(skb);
+
+	return 0;
+}
+
+static irqreturn_t rk3576_canfd_interrupt(int irq, void *dev_id)
+{
+	struct net_device *ndev = (struct net_device *)dev_id;
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	u32 err_int = ERR_WARN_INT | RX_BUF_OV_INT | PASSIVE_ERR_INT |
+		      BUS_ERR_INT | BUS_OFF_INT | BUSOFF_RCY_INT |
+		      BUS_OFF_RECOVERY_INT | RX_STR_FULL_INT;
+	u32 isr;
+
+	isr = rk3576_canfd_read(rcan, CANFD_INT);
+	if ((isr & RX_STR_TIMEOUT_INT) || (isr & ISM_WTM_INT) || (isr & RX_STR_FULL_INT)) {
+		rk3576_canfd_write(rcan, CANFD_INT_MASK,
+				   ISM_WTM_INT | RX_STR_TIMEOUT_INT |
+				   RX_FINISH_INT);
+		if (rcan->use_dma)
+			rk3576_canfd_rx_dma(rcan);
+		else
+			napi_schedule(&rcan->napi);
+	}
+
+	if (isr & TX_FINISH_INT) {
+		rk3576_canfd_write(rcan, CANFD_CMD, 0);
+		stats->tx_bytes += can_get_echo_skb(ndev, 0, NULL);
+		stats->tx_packets++;
+		netif_wake_queue(ndev);
+	}
+
+	if (isr & err_int) {
+		/* error interrupt */
+		if (rk3576_canfd_err(ndev, isr))
+			netdev_err(ndev, "can't allocate buffer - clearing pending interrupts\n");
+	}
+
+	rk3576_canfd_write(rcan, CANFD_INT, isr);
+	return IRQ_HANDLED;
+}
+
+static int rk3576_canfd_open(struct net_device *ndev)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	int err;
+
+	/* common open */
+	err = open_candev(ndev);
+	if (err)
+		return err;
+
+	err = pm_runtime_get_sync(rcan->dev);
+	if (err < 0) {
+		netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
+			   __func__, err);
+		goto exit;
+	}
+
+	err = rk3576_canfd_start(ndev);
+	if (err) {
+		netdev_err(ndev, "could not start CANFD peripheral\n");
+		goto exit_can_start;
+	}
+
+	napi_enable(&rcan->napi);
+	netif_start_queue(ndev);
+
+	netdev_dbg(ndev, "%s\n", __func__);
+	return 0;
+
+exit_can_start:
+	pm_runtime_put(rcan->dev);
+exit:
+	close_candev(ndev);
+	return err;
+}
+
+static int rk3576_canfd_close(struct net_device *ndev)
+{
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+
+	netif_stop_queue(ndev);
+	napi_disable(&rcan->napi);
+	rk3576_canfd_stop(ndev);
+	close_candev(ndev);
+	pm_runtime_put(rcan->dev);
+
+	netdev_dbg(ndev, "%s\n", __func__);
+	return 0;
+}
+
+static const struct net_device_ops rk3576_canfd_netdev_ops = {
+	.ndo_open = rk3576_canfd_open,
+	.ndo_stop = rk3576_canfd_close,
+	.ndo_start_xmit = rk3576_canfd_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
+/**
+ * rk3576_canfd_suspend - Suspend method for the driver
+ * @dev:	Address of the device structure
+ *
+ * Put the driver into low power mode.
+ * Return: 0 on success and failure value on error
+ */
+static int __maybe_unused rk3576_canfd_suspend(struct device *dev)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
+
+	if (netif_running(ndev)) {
+		netif_stop_queue(ndev);
+		netif_device_detach(ndev);
+		rk3576_canfd_stop(ndev);
+	}
+
+	return pm_runtime_force_suspend(dev);
+}
+
+/**
+ * rk3576_canfd_resume - Resume from suspend
+ * @dev:	Address of the device structure
+ *
+ * Resume operation after suspend.
+ * Return: 0 on success and failure value on error
+ */
+static int __maybe_unused rk3576_canfd_resume(struct device *dev)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret) {
+		dev_err(dev, "pm_runtime_force_resume failed on resume\n");
+		return ret;
+	}
+
+	if (netif_running(ndev)) {
+		ret = rk3576_canfd_start(ndev);
+		if (ret) {
+			dev_err(dev, "rk3576_canfd_chip_start failed on resume\n");
+			return ret;
+		}
+
+		netif_device_attach(ndev);
+		netif_start_queue(ndev);
+	}
+
+	return 0;
+}
+
+/**
+ * rk3576_canfd_runtime_suspend - Runtime suspend method for the driver
+ * @dev:	Address of the device structure
+ *
+ * Put the driver into low power mode.
+ * Return: 0 always
+ */
+static int __maybe_unused rk3576_canfd_runtime_suspend(struct device *dev)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+
+	clk_bulk_disable_unprepare(rcan->num_clks, rcan->clks);
+
+	return 0;
+}
+
+/**
+ * rk3576_canfd_runtime_resume - Runtime resume from suspend
+ * @dev:	Address of the device structure
+ *
+ * Resume operation after suspend.
+ * Return: 0 on success and failure value on error
+ */
+static int __maybe_unused rk3576_canfd_runtime_resume(struct device *dev)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(rcan->num_clks, rcan->clks);
+	if (ret) {
+		dev_err(dev, "Cannot enable clock.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops rk3576_canfd_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(rk3576_canfd_suspend, rk3576_canfd_resume)
+	SET_RUNTIME_PM_OPS(rk3576_canfd_runtime_suspend,
+			   rk3576_canfd_runtime_resume, NULL)
+};
+
+static const struct of_device_id rk3576_canfd_of_match[] = {
+	{
+		.compatible = "rockchip,rk3576-canfd",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, rk3576_canfd_of_match);
+
+static void rk3576_canfd_dma_init(struct rk3576_canfd *rcan)
+{
+	struct dma_slave_config rxconf = {
+		.direction = DMA_DEV_TO_MEM,
+		.src_addr = rcan->rx_dma_src_addr,
+		.src_addr_width = 4,
+		.dst_addr_width = 4,
+		.src_maxburst = 16,
+	};
+
+	rcan->rxbuf = dma_alloc_coherent(rcan->dev, rcan->dma_size * rcan->rx_fifo_depth,
+					 &rcan->rx_dma_dst_addr, GFP_KERNEL);
+	if (!rcan->rxbuf) {
+		rcan->use_dma = 0;
+		return;
+	}
+	dmaengine_slave_config(rcan->rxchan, &rxconf);
+}
+
+static int rk3576_canfd_probe(struct platform_device *pdev)
+{
+	struct net_device *ndev;
+	struct rk3576_canfd *rcan;
+	struct resource *res;
+	void __iomem *addr;
+	int err, irq;
+	u32 val = 0;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "could not get a valid irq\n");
+		return -ENODEV;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(addr))
+		return -EBUSY;
+
+	ndev = alloc_candev(sizeof(struct rk3576_canfd), 1);
+	if (!ndev) {
+		dev_err(&pdev->dev, "could not allocate memory for CANFD device\n");
+		return -ENOMEM;
+	}
+	rcan = netdev_priv(ndev);
+
+	/* register interrupt handler */
+	err = devm_request_irq(&pdev->dev, irq, rk3576_canfd_interrupt,
+			       0, ndev->name, ndev);
+	if (err) {
+		dev_err(&pdev->dev, "request_irq err: %d\n", err);
+		return err;
+	}
+
+	rcan->reset = devm_reset_control_array_get_exclusive(&pdev->dev);
+	if (IS_ERR(rcan->reset)) {
+		if (PTR_ERR(rcan->reset) != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "failed to get canfd reset lines\n");
+		return PTR_ERR(rcan->reset);
+	}
+	rcan->num_clks = devm_clk_bulk_get_all(&pdev->dev, &rcan->clks);
+	if (rcan->num_clks < 1)
+		return -ENODEV;
+
+	rcan->mode = (unsigned long)of_device_get_match_data(&pdev->dev);
+
+	rcan->base = addr;
+	rcan->can.clock.freq = clk_get_rate(rcan->clks[0].clk);
+	rcan->dev = &pdev->dev;
+	rcan->can.state = CAN_STATE_STOPPED;
+
+	rcan->can.bittiming_const = &rk3576_canfd_bittiming_const;
+	rcan->can.data_bittiming_const = &rk3576_canfd_data_bittiming_const;
+	rcan->can.do_set_mode = rk3576_canfd_set_mode;
+	rcan->can.do_get_berr_counter = rk3576_canfd_get_berr_counter;
+	rcan->can.do_set_bittiming = rk3576_canfd_set_bittiming;
+	rcan->can.do_set_data_bittiming = rk3576_canfd_set_bittiming;
+	rcan->can.ctrlmode = CAN_CTRLMODE_FD;
+	/* IFI CANFD can do both Bosch FD and ISO FD */
+	rcan->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
+				       CAN_CTRLMODE_LISTENONLY |
+				       CAN_CTRLMODE_FD;
+
+	rcan->rx_fifo_shift = INTM_LEFT_CNT_SHIFT;
+	rcan->rx_fifo_mask = INTM_LEFT_CNT_MASK;
+
+	/* rx-max-data only 4 Words or 18 words are supported */
+	if (device_property_read_u32_array(&pdev->dev, "rockchip,rx-max-data", &val, 1))
+		rcan->rx_max_data = 18;
+	else
+		rcan->rx_max_data = val;
+
+	if (rcan->rx_max_data != 4 && rcan->rx_max_data != 18) {
+		rcan->rx_max_data = 18;
+		dev_warn(&pdev->dev, "rx_max_data is invalid, set to 18 words!\n");
+	}
+	rcan->rx_fifo_depth = SRAM_MAX_DEPTH / rcan->rx_max_data;
+
+	rcan->rxchan = dma_request_chan(&pdev->dev, "rx");
+	if (IS_ERR(rcan->rxchan)) {
+		dev_warn(&pdev->dev, "Failed to request rxchan\n");
+		rcan->rxchan = NULL;
+		rcan->use_dma = 0;
+	} else {
+		rcan->rx_dma_src_addr = res->start + CANFD_RXFRD;
+		rcan->dma_size = rcan->rx_max_data * 4;
+		rcan->use_dma = 1;
+	}
+	if (rcan->use_dma)
+		rk3576_canfd_dma_init(rcan);
+
+	ndev->netdev_ops = &rk3576_canfd_netdev_ops;
+	ndev->irq = irq;
+	ndev->flags |= IFF_ECHO;
+
+	platform_set_drvdata(pdev, ndev);
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	pm_runtime_enable(&pdev->dev);
+	err = pm_runtime_get_sync(&pdev->dev);
+	if (err < 0) {
+		dev_err(&pdev->dev, "%s: pm_runtime_get failed(%d)\n",
+			__func__, err);
+		goto err_pmdisable;
+	}
+	netif_napi_add(ndev, &rcan->napi, rk3576_canfd_rx_poll);
+	err = register_candev(ndev);
+	if (err) {
+		dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto err_disableclks;
+	}
+	dev_info(&pdev->dev, "CAN info: use_dma = %d, rx_max_data = %d, fifo_depth = %d\n",
+		 rcan->use_dma, rcan->rx_max_data, rcan->rx_fifo_depth);
+	return 0;
+
+err_disableclks:
+	pm_runtime_put(&pdev->dev);
+err_pmdisable:
+	if (rcan->rxbuf) {
+		dma_free_coherent(rcan->dev, rcan->dma_size * rcan->rx_fifo_depth, rcan->rxbuf,
+				  rcan->rx_dma_dst_addr);
+		rcan->rxbuf = NULL;
+	}
+	if (rcan->rxchan)
+		dma_release_channel(rcan->rxchan);
+	pm_runtime_disable(&pdev->dev);
+	free_candev(ndev);
+
+	return err;
+}
+
+static void rk3576_canfd_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct rk3576_canfd *rcan = netdev_priv(ndev);
+
+	if (rcan->rxbuf) {
+		dma_free_coherent(rcan->dev, rcan->dma_size * rcan->rx_fifo_depth, rcan->rxbuf,
+				  rcan->rx_dma_dst_addr);
+		rcan->rxbuf = NULL;
+	}
+
+	if (rcan->rxchan)
+		dma_release_channel(rcan->rxchan);
+
+	unregister_netdev(ndev);
+	pm_runtime_disable(&pdev->dev);
+	netif_napi_del(&rcan->napi);
+	free_candev(ndev);
+}
+
+static struct platform_driver rk3576_canfd_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.pm = &rk3576_canfd_dev_pm_ops,
+		.of_match_table = rk3576_canfd_of_match,
+	},
+	.probe = rk3576_canfd_probe,
+	.remove = rk3576_canfd_remove,
+};
+module_platform_driver(rk3576_canfd_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Elaine Zhang <zhangqing at rock-chips.com>");
+MODULE_DESCRIPTION("RK3576 CANFD Drivers");
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Dec 16 18:39:08 2024
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 17 Dec 2024 10:39:08 +0800
Subject: [PATCH 2/2] arm64: dts: rockchip: rk3576: add can dts nodes
In-Reply-To: <20241217023908.1292999-1-zhangqing@rock-chips.com>
References: <20241217023908.1292999-1-zhangqing@rock-chips.com>
Message-ID: <20241217023908.1292999-3-zhangqing@rock-chips.com>

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 26 ++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index 436232ffe4d1..82fdfd4720ec 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1195,6 +1195,32 @@ dmac2: dma-controller at 2abd0000 {
 			#dma-cells = <1>;
 		};
 
+		can0: can at 2ac00000 {
+			compatible = "rockchip,rk3576-canfd";
+			reg = <0x0 0x2ac00000 0x0 0x1000>;
+			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru CLK_CAN0>, <&cru HCLK_CAN0>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&cru SRST_CAN0>, <&cru SRST_H_CAN0>;
+			reset-names = "can", "can-apb";
+			dmas = <&dmac0 20>;
+			dma-names = "rx";
+			status = "disabled";
+		};
+	
+		can1: can at 2ac10000 {
+			compatible = "rockchip,rk3576-canfd";
+			reg = <0x0 0x2ac10000 0x0 0x1000>;
+			interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru CLK_CAN1>, <&cru HCLK_CAN1>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&cru SRST_CAN1>, <&cru SRST_H_CAN1>;
+			reset-names = "can", "can-apb";
+			dmas = <&dmac1 21>;
+			dma-names = "rx";
+			status = "disabled";
+		};
+
 		i2c1: i2c at 2ac40000 {
 			compatible = "rockchip,rk3576-i2c", "rockchip,rk3399-i2c";
 			reg = <0x0 0x2ac40000 0x0 0x1000>;
-- 
2.34.1



From david at ixit.cz  Mon Dec 16 18:41:50 2024
From: david at ixit.cz (David Heidelberg)
Date: Mon, 16 Dec 2024 21:41:50 -0500
Subject: [PATCH 1/2] dt-bindings: media: imx219: Rename to include vendor prefix
Message-ID: <20241217024206.1700170-1-david@ixit.cz>

imx219.yaml doesn't include the vendor prefix of sony,
so rename to add it.

Update the id entry and MAINTAINERS to match.

Signed-off-by: David Heidelberg <david at ixit.cz>
---
 .../bindings/media/i2c/{imx219.yaml => sony,imx219.yaml}        | 2 +-
 MAINTAINERS                                                     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
 rename Documentation/devicetree/bindings/media/i2c/{imx219.yaml => sony,imx219.yaml} (97%)

diff --git ./Documentation/devicetree/bindings/media/i2c/imx219.yaml ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml
similarity index 97%
rename from Documentation/devicetree/bindings/media/i2c/imx219.yaml
rename to Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml
index 07d088cf66e0..8b23e5fc6a24 100644
--- ./Documentation/devicetree/bindings/media/i2c/imx219.yaml
+++ ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/media/i2c/imx219.yaml#
+$id: http://devicetree.org/schemas/media/i2c/sony,imx219.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Sony 1/4.0-Inch 8Mpixel CMOS Digital Image Sensor
diff --git ./MAINTAINERS ./MAINTAINERS
index 453ba75fce3b..32a4d057a559 100644
--- ./MAINTAINERS
+++ ./MAINTAINERS
@@ -21796,7 +21796,7 @@ M:	Dave Stevenson <dave.stevenson at raspberrypi.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 T:	git git://linuxtv.org/media.git
-F:	Documentation/devicetree/bindings/media/i2c/imx219.yaml
+F:	Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml
 F:	drivers/media/i2c/imx219.c
 
 SONY IMX258 SENSOR DRIVER
-- 
2.45.2



From zhangqing at rock-chips.com  Mon Dec 16 18:39:06 2024
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 17 Dec 2024 10:39:06 +0800
Subject: [PATCH 0/2] rockchip: add can for RK3576 Soc
Message-ID: <20241217023908.1292999-1-zhangqing@rock-chips.com>

rk3576 can is a new controller:
Support CAN and CANFD protocol.
Support DMA

There are major differences from the previous rk3568. All errata on the
rk3568 have been fixed and redesigned.

Elaine Zhang (2):
  net: can: rockchip: add can for RK3576 Soc
  arm64: dts: rockchip: rk3576: add can dts nodes

 arch/arm64/boot/dts/rockchip/rk3576.dtsi |   26 +
 drivers/net/can/rockchip/Kconfig         |   10 +
 drivers/net/can/rockchip/Makefile        |    1 +
 drivers/net/can/rockchip/rk3576_canfd.c  | 1349 ++++++++++++++++++++++
 4 files changed, 1386 insertions(+)
 create mode 100644 drivers/net/can/rockchip/rk3576_canfd.c

-- 
2.34.1



From david at ixit.cz  Mon Dec 16 18:41:51 2024
From: david at ixit.cz (David Heidelberg)
Date: Mon, 16 Dec 2024 21:41:51 -0500
Subject: [PATCH 2/2] dt-bindings: media: imx219: Describe sensor address using the reg property
In-Reply-To: <20241217024206.1700170-1-david@ixit.cz>
References: <20241217024206.1700170-1-david@ixit.cz>
Message-ID: <20241217024206.1700170-2-david@ixit.cz>

Use the reg property instead of text in the description.
Drop useless description of reg property.

Signed-off-by: David Heidelberg <david at ixit.cz>
---
 Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml
index 8b23e5fc6a24..066eeb7af5e3 100644
--- ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml
+++ ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml
@@ -12,7 +12,7 @@ maintainers:
 description: |-
   The Sony imx219 is a 1/4.0-inch CMOS active pixel digital image sensor
   with an active array size of 3280H x 2464V. It is programmable through
-  I2C interface. The I2C address is fixed to 0x10 as per sensor data sheet.
+  I2C interface.
   Image data is sent through MIPI CSI-2, which is configured as either 2 or
   4 data lanes.
 
@@ -21,8 +21,7 @@ properties:
     const: sony,imx219
 
   reg:
-    description: I2C device address
-    maxItems: 1
+    const: 0x10
 
   clocks:
     maxItems: 1
-- 
2.45.2



From xueshuai at linux.alibaba.com  Mon Dec 16 19:05:11 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Tue, 17 Dec 2024 11:05:11 +0800
Subject: [PATCH v17 2/3] mm: memory-failure: move return value
 documentation to function declaration
In-Reply-To: <51d231c2-3659-461a-b6c3-d0e7f9fddfc1@oracle.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
 <20241202030527.20586-3-xueshuai@linux.alibaba.com>
 <51d231c2-3659-461a-b6c3-d0e7f9fddfc1@oracle.com>
Message-ID: <1e0a0f9b-7c58-4f70-b2d4-6b3c2c4143de@linux.alibaba.com>



? 2024/12/17 07:37, jane.chu at oracle.com ??:
> 
> On 12/1/2024 7:05 PM, Shuai Xue wrote:
>> Part of return value comments for memory_failure() were originally
>> documented at the call site. Move those comments to the function
>> declaration to improve code readability and to provide developers with
>> immediate access to function usage and return information.
>>
>> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
>> Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
>> Reviewed-by: Yazen Ghannam <yazen.ghannam at amd.com>
>> ---
>> ? arch/x86/kernel/cpu/mce/core.c |? 7 -------
>> ? mm/memory-failure.c??????????? | 10 +++++++---
>> ? 2 files changed, 7 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
>> index 7fb5556a0b53..d1dd7f892514 100644
>> --- a/arch/x86/kernel/cpu/mce/core.c
>> +++ b/arch/x86/kernel/cpu/mce/core.c
>> @@ -1398,13 +1398,6 @@ static void kill_me_maybe(struct callback_head *cb)
>> ????????? return;
>> ????? }
>> -??? /*
>> -???? * -EHWPOISON from memory_failure() means that it already sent SIGBUS
>> -???? * to the current process with the proper error info,
>> -???? * -EOPNOTSUPP means hwpoison_filter() filtered the error event,
>> -???? *
>> -???? * In both cases, no further processing is required.
>> -???? */
>> ????? if (ret == -EHWPOISON || ret == -EOPNOTSUPP)
>> ????????? return;
>> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
>> index a7b8ccd29b6f..14c316d7d38d 100644
>> --- a/mm/memory-failure.c
>> +++ b/mm/memory-failure.c
>> @@ -2211,9 +2211,13 @@ static void kill_procs_now(struct page *p, unsigned long pfn, int flags,
>> ?? * Must run in process context (e.g. a work queue) with interrupts
>> ?? * enabled and no spinlocks held.
>> ?? *
>> - * Return: 0 for successfully handled the memory error,
>> - *???????? -EOPNOTSUPP for hwpoison_filter() filtered the error event,
>> - *???????? < 0(except -EOPNOTSUPP) on failure.
>> + * Return:
>> + *?? 0???????????? - success,
>> + *?? -ENXIO??????? - memory not managed by the kernel
>> + *?? -EOPNOTSUPP?? - hwpoison_filter() filtered the error event,
>> + *?? -EHWPOISON??? - the page was already poisoned, potentially
>> + *?????????????????? kill process,
>> + *?? other negative values - failure.
>> ?? */
>> ? int memory_failure(unsigned long pfn, int flags)
>> ? {
> 
> Looks good.
> 
> Reviewed-by: Jane Chu <jane.chu at oracle.com>
> 
> -jane


Thanks.

Best Regards,
Shuai


From david at ixit.cz  Mon Dec 16 19:28:17 2024
From: david at ixit.cz (David Heidelberg)
Date: Mon, 16 Dec 2024 22:28:17 -0500
Subject: [PATCH] dt-bindings: media: imx283: Describe sensor address using the reg property
Message-ID: <20241217032821.1712916-1-david@ixit.cz>

Use the reg property instead of text in the description.

Signed-off-by: David Heidelberg <david at ixit.cz>
---
 .../devicetree/bindings/media/i2c/sony,imx283.yaml         | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
index e4f49f1435a5..f4ee991c89a3 100644
--- ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
+++ ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
@@ -13,16 +13,15 @@ maintainers:
 
 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.
+  array size of 5472H x 3648V. It is programmable through I2C interface.
+  Image data is sent through MIPI CSI-2.
 
 properties:
   compatible:
     const: sony,imx283
 
   reg:
-    maxItems: 1
+    const: 0x1a
 
   clocks:
     description: Clock frequency from 6 to 24 MHz.
-- 
2.45.2



From anshuman.khandual at arm.com  Mon Dec 16 19:48:07 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 17 Dec 2024 09:18:07 +0530
Subject: [PATCH] mm/ptdump: Drop GENERIC_PTDUMP
Message-ID: <20241217034807.2541349-1-anshuman.khandual@arm.com>

GENERIC_PTDUMP does not guard any code but instead just used for platform's
subscription into core ptdump defined under PTDUMP_CORE, which is selected.
Instead use PTDUMP_CORE for platform subscription and drop GENERIC_PTDUMP.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Jonathan Corbet <corbet at lwn.net>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Michael Ellerman <mpe at ellerman.id.au>
Cc: Nicholas Piggin <npiggin at gmail.com>
Cc: Paul Walmsley <paul.walmsley at sifive.com>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
Cc: Heiko Carstens <hca at linux.ibm.com>
Cc: Vasily Gorbik <gor at linux.ibm.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: kvmarm at lists.linux.dev
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-riscv at lists.infradead.org
Cc: linux-s390 at vger.kernel.org
Cc: linux-mm at kvack.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This patch applies on v6.13-rc3 and has been tested on arm64, although it
also clears build tests on impacted platforms.

 Documentation/arch/arm64/ptdump.rst       | 1 -
 arch/arm64/Kconfig                        | 2 +-
 arch/arm64/kvm/Kconfig                    | 3 +--
 arch/powerpc/Kconfig                      | 2 +-
 arch/powerpc/configs/mpc885_ads_defconfig | 1 -
 arch/riscv/Kconfig                        | 2 +-
 arch/s390/Kconfig                         | 2 +-
 arch/x86/Kconfig                          | 2 +-
 arch/x86/Kconfig.debug                    | 2 +-
 kernel/configs/debug.config               | 1 -
 mm/Kconfig.debug                          | 8 ++------
 11 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/Documentation/arch/arm64/ptdump.rst b/Documentation/arch/arm64/ptdump.rst
index 5dcfc5d7cddf..61ca040a885b 100644
--- a/Documentation/arch/arm64/ptdump.rst
+++ b/Documentation/arch/arm64/ptdump.rst
@@ -22,7 +22,6 @@ offlining of memory being accessed by the ptdump code.
 In order to dump the kernel page tables, enable the following
 configurations and mount debugfs::
 
- CONFIG_GENERIC_PTDUMP=y
  CONFIG_PTDUMP_CORE=y
  CONFIG_PTDUMP_DEBUGFS=y
 
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..b5479c8b454c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -154,7 +154,7 @@ config ARM64
 	select GENERIC_IRQ_SHOW_LEVEL
 	select GENERIC_LIB_DEVMEM_IS_ALLOWED
 	select GENERIC_PCI_IOMAP
-	select GENERIC_PTDUMP
+	select PTDUMP_CORE
 	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index ead632ad01b4..fe17d7f5b061 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -71,8 +71,7 @@ config PTDUMP_STAGE2_DEBUGFS
 	depends on KVM
 	depends on DEBUG_KERNEL
 	depends on DEBUG_FS
-	depends on GENERIC_PTDUMP
-	select PTDUMP_CORE
+	depends on PTDUMP_CORE
 	default n
 	help
 	  Say Y here if you want to show the stage-2 kernel pagetables
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a0ce777f9706..c716f8df10de 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -203,7 +203,7 @@ config PPC
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IRQ_SHOW_LEVEL
 	select GENERIC_PCI_IOMAP		if PCI
-	select GENERIC_PTDUMP
+	select PTDUMP_CORE
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_VDSO_TIME_NS
diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig
index 77306be62e9e..ea6f836407d2 100644
--- a/arch/powerpc/configs/mpc885_ads_defconfig
+++ b/arch/powerpc/configs/mpc885_ads_defconfig
@@ -78,4 +78,3 @@ CONFIG_DEBUG_VM_PGTABLE=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_BDI_SWITCH=y
 CONFIG_PPC_EARLY_DEBUG=y
-CONFIG_GENERIC_PTDUMP=y
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index d4a7ca0388c0..05f969729e72 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -111,7 +111,7 @@ config RISCV
 	select GENERIC_IRQ_SHOW_LEVEL
 	select GENERIC_LIB_DEVMEM_IS_ALLOWED
 	select GENERIC_PCI_IOMAP
-	select GENERIC_PTDUMP if MMU
+	select PTDUMP_CORE if MMU
 	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL if MMU && 64BIT
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 0077969170e8..0e19fe547d84 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -155,7 +155,7 @@ config S390
 	select GENERIC_CPU_VULNERABILITIES
 	select GENERIC_ENTRY
 	select GENERIC_GETTIMEOFDAY
-	select GENERIC_PTDUMP
+	select PTDUMP_CORE
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_VDSO_TIME_NS
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9d7bd0ae48c4..d84cb2ac93ac 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -173,7 +173,7 @@ config X86
 	select GENERIC_IRQ_RESERVATION_MODE
 	select GENERIC_IRQ_SHOW
 	select GENERIC_PENDING_IRQ		if SMP
-	select GENERIC_PTDUMP
+	select PTDUMP_CORE
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_GETTIMEOFDAY
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 74777a97e394..198d7f090b98 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -59,7 +59,7 @@ config EARLY_PRINTK_USB_XDBC
 config EFI_PGT_DUMP
 	bool "Dump the EFI pagetable"
 	depends on EFI
-	select PTDUMP_CORE
+	depends on PTDUMP_CORE
 	help
 	  Enable this if you want to dump the EFI page table before
 	  enabling virtual mode. This can be used to debug miscellaneous
diff --git a/kernel/configs/debug.config b/kernel/configs/debug.config
index 20552f163930..8aafd050b754 100644
--- a/kernel/configs/debug.config
+++ b/kernel/configs/debug.config
@@ -73,7 +73,6 @@ CONFIG_DEBUG_VM=y
 CONFIG_DEBUG_VM_PGFLAGS=y
 CONFIG_DEBUG_VM_RB=y
 CONFIG_DEBUG_VM_VMACACHE=y
-CONFIG_GENERIC_PTDUMP=y
 CONFIG_KASAN=y
 CONFIG_KASAN_GENERIC=y
 CONFIG_KASAN_INLINE=y
diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
index 41a58536531d..b206e5a11f96 100644
--- a/mm/Kconfig.debug
+++ b/mm/Kconfig.debug
@@ -187,7 +187,7 @@ config DEBUG_WX
 	bool "Warn on W+X mappings at boot"
 	depends on ARCH_HAS_DEBUG_WX
 	depends on MMU
-	select PTDUMP_CORE
+	depends on PTDUMP_CORE
 	help
 	  Generate a warning if any W+X mappings are found at boot.
 
@@ -212,9 +212,6 @@ config DEBUG_WX
 
 	  If in doubt, say "Y".
 
-config GENERIC_PTDUMP
-	bool
-
 config PTDUMP_CORE
 	bool
 
@@ -222,8 +219,7 @@ config PTDUMP_DEBUGFS
 	bool "Export kernel pagetable layout to userspace via debugfs"
 	depends on DEBUG_KERNEL
 	depends on DEBUG_FS
-	depends on GENERIC_PTDUMP
-	select PTDUMP_CORE
+	depends on PTDUMP_CORE
 	help
 	  Say Y here if you want to show the kernel pagetable layout in a
 	  debugfs file. This information is only useful for kernel developers
-- 
2.30.2



From viresh.kumar at linaro.org  Mon Dec 16 20:27:26 2024
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 17 Dec 2024 09:57:26 +0530
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <Z2CmcelSy89NULtz@arm.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
 <20241212065100.sjb7lrlmksbm2hdk@vireshk-i7>
 <Z2CmcelSy89NULtz@arm.com>
Message-ID: <20241217042726.isllh5bulpnwql7i@vireshk-i7>

On 16-12-24, 23:15, Beata Michalska wrote:
> My bad as I must have misinterpreted that message. Although I am not entirely
> sure why this might be unacceptable as it is not such uncommon approach to use
> signed int space to cover both: expected positive value as well as potential
> error code case failure.

This part is fine. The problem is with handling frequency here. Signed int can
capture up to 2 GHz of freq, where as unsigned int can capture up to 4 GHz and
so we would really like to keep it at 4 GHz..

Maybe we need to move to 64 bits for frequency at some point of time, but at
least we should try to not break it for now.

> Enabling the new attribute for all is an option, tough not entirely compelling
> one as exposing a feature that is known not to be supported seems bit
> counterintuitive. On the other hand using cpufreq driver flags won't help much
> as the support for the new attrib is platform-specific, not driver-specific.

-- 
viresh


From anshuman.khandual at arm.com  Mon Dec 16 20:33:10 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 17 Dec 2024 10:03:10 +0530
Subject: [PATCH V2 18/46] arm64/sysreg: Add register fields for PMUACR_EL1
In-Reply-To: <20241216231505.GA601635-robh@kernel.org>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-19-anshuman.khandual@arm.com>
 <20241216231505.GA601635-robh@kernel.org>
Message-ID: <0b8a055f-eab9-4b44-baac-ad25756dbbfd@arm.com>



On 12/17/24 04:45, Rob Herring wrote:
> On Tue, Dec 10, 2024 at 11:22:43AM +0530, Anshuman Khandual wrote:
>> This adds register fields for PMUACR_EL1 as per the definitions based
>> on DDI0601 2024-09.
>>
>> 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 | 37 +++++++++++++++++++++++++++++++++++++
>>  1 file changed, 37 insertions(+)
>>
>> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
>> index 214ad6da1dff..462adb8031ca 100644
>> --- a/arch/arm64/tools/sysreg
>> +++ b/arch/arm64/tools/sysreg
>> @@ -2349,6 +2349,43 @@ Res0	63:5
>>  Field	4:0	SEL
>>  EndSysreg
>>  
>> +Sysreg	PMUACR_EL1	3	0	9	14	4
> 
> I already added this and various other PMUv3.9 registers you've added 
> here in v6.12 and v6.13. So are you on an old base or the tool allows 
> multiple definitions? If the latter, that should be fixed.

This series is based on v6.13-rc1 and as you mentioned PMUACR_EL1 has
already been added into tools sysreg.

Sysreg  PMUACR_EL1      3       0       9       14      4
Res0    63:33
Field   32      F0
Field   31      C
Field   30:0    P
EndSysreg

Seems like the tool does allow multiple definitions for a single register.
The generated header (arch/arm64/include/generated/asm/sysreg-defs.h) does
include redundant blocks for the following.

#define REG_PMUACR_EL1                                  S3_0_C9_C14_4
#define SYS_PMUACR_EL1                                  sys_reg(3, 0, 9, 14, 4)
#define SYS_PMUACR_EL1_Op0                              3
#define SYS_PMUACR_EL1_Op1                              0
#define SYS_PMUACR_EL1_CRn                              9
#define SYS_PMUACR_EL1_CRm                              14
#define SYS_PMUACR_EL1_Op2                              4

#define PMUACR_EL1_C                                    GENMASK(31, 31)
#define PMUACR_EL1_C_MASK                               GENMASK(31, 31)
#define PMUACR_EL1_C_SHIFT                              31
#define PMUACR_EL1_C_WIDTH                              1

I am wondering how this did not cause any re-definition warning ?

> 
>> +Res0	63:33
>> +Field	32	FM
>> +Field	31	C
>> +Field	30	P30
>> +Field	29	P29
>> +Field	28	P28
>> +Field	27	P27
>> +Field	26	P26
>> +Field	25	P25
>> +Field	24	P24
>> +Field	23	P23
>> +Field	22	P22
>> +Field	21	P21
>> +Field	20	P20
>> +Field	19	P19
>> +Field	18	P18
>> +Field	17	P17
>> +Field	16	P16
>> +Field	15	P15
>> +Field	14	P14
>> +Field	13	P13
>> +Field	12	P12
>> +Field	11	P11
>> +Field	10	P10
>> +Field	9	P9
>> +Field	8	P8
>> +Field	7	P7
>> +Field	6	P6
>> +Field	5	P5
>> +Field	4	P4
>> +Field	3	P3
>> +Field	2	P2
>> +Field	1	P1
>> +Field	0	P0
> 
> We're never going to use Pnn defines. This is just useless bloat unless 
> we're aiming to top amd gpu defines LOC.

Okay, this patch was trying to be cautiously comprehensive. But anyways
PMUACR_EL1 has already been added and hence this is redundant now.


From charlie at rivosinc.com  Mon Dec 16 21:05:35 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 21:05:35 -0800
Subject: [PATCH v2 01/16] perf tools: Create generic syscall table support
In-Reply-To: <Z1zBzTgEYXw1DbEL@google.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
 <20241212-perf_syscalltbl-v2-1-f8ca984ffe40@rivosinc.com>
 <Z1zBzTgEYXw1DbEL@google.com>
Message-ID: <Z2EGn2V1OPqqKxKZ@ghost>

On Fri, Dec 13, 2024 at 03:22:53PM -0800, Namhyung Kim wrote:
> Hello,
> 
> On Thu, Dec 12, 2024 at 04:32:51PM -0800, Charlie Jenkins wrote:
> > Currently each architecture in perf independently generates syscall
> > headers. Adapt the work that has gone into unifying syscall header
> > implementations in the kernel to work with perf tools. Introduce this
> > framework with riscv at first. riscv previously relied on libaudit, but
> > with this change, perf tools for riscv no longer needs this external
> > dependency.
> 
> Nice work!
> 
> > 
> > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > ---
> >  tools/perf/Makefile.config                         |  11 +-
> >  tools/perf/Makefile.perf                           |   4 +
> >  tools/perf/arch/riscv/Makefile                     |  22 --
> >  tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
> >  .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
> >  tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 ---
> >  tools/perf/arch/riscv/include/syscall_table.h      |   8 +
> >  tools/perf/check-headers.sh                        |   1 +
> >  tools/perf/scripts/Makefile.syscalls               |  60 +++
> >  tools/perf/scripts/syscalltbl.sh                   |  86 +++++
> >  tools/perf/util/syscalltbl.c                       |   8 +-
> >  tools/scripts/syscall.tbl                          | 409 +++++++++++++++++++++
> >  12 files changed, 585 insertions(+), 77 deletions(-)
> > 
> > diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> > index 2916d59c88cd08b299202a48ddb42fa32aac04a6..a72f25162714f0117a88d94474da336814d4f030 100644
> > --- a/tools/perf/Makefile.config
> > +++ b/tools/perf/Makefile.config
> > @@ -35,6 +35,13 @@ ifneq ($(NO_SYSCALL_TABLE),1)
> >      NO_SYSCALL_TABLE := 0
> >    endif
> >  
> > +  # architectures that use the generic syscall table scripts
> > +  ifeq ($(SRCARCH),riscv)
> > +    NO_SYSCALL_TABLE := 0
> > +    CFLAGS += -DGENERIC_SYSCALL_TABLE
> > +    CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
> > +  endif
> > +
> >    ifneq ($(NO_SYSCALL_TABLE),1)
> >      CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
> >    endif
> > @@ -83,10 +90,6 @@ ifeq ($(ARCH),mips)
> >    LIBUNWIND_LIBS = -lunwind -lunwind-mips
> >  endif
> >  
> > -ifeq ($(ARCH),riscv)
> > -  CFLAGS += -I$(OUTPUT)arch/riscv/include/generated
> > -endif
> > -
> >  # So far there's only x86 and arm libdw unwind support merged in perf.
> >  # Disable it on all other architectures in case libdw unwind
> >  # support is detected in system. Add supported architectures
> > diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> > index d74241a151313bd09101aabb5d765a5a0a6efc84..f5278ed9f778f928436693a14e016c5c3c5171c1 100644
> > --- a/tools/perf/Makefile.perf
> > +++ b/tools/perf/Makefile.perf
> > @@ -310,6 +310,10 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
> >  FEATURE_TESTS := all
> >  endif
> >  endif
> > +# architectures that use the generic syscall table
> > +ifeq ($(SRCARCH),riscv)
> > +include $(srctree)/tools/perf/scripts/Makefile.syscalls
> > +endif
> >  include Makefile.config
> >  endif
> >  
> > diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
> > index 18ad078000e2bba595f92efc5d97a63fdb83ef45..087e099fb453a9236db34878077a51f711881ce0 100644
> > --- a/tools/perf/arch/riscv/Makefile
> > +++ b/tools/perf/arch/riscv/Makefile
> > @@ -1,25 +1,3 @@
> >  # SPDX-License-Identifier: GPL-2.0
> >  PERF_HAVE_JITDUMP := 1
> >  HAVE_KVM_STAT_SUPPORT := 1
> > -
> > -#
> > -# Syscall table generation for perf
> > -#
> > -
> > -out    := $(OUTPUT)arch/riscv/include/generated/asm
> > -header := $(out)/syscalls.c
> > -incpath := $(srctree)/tools
> > -sysdef := $(srctree)/tools/arch/riscv/include/uapi/asm/unistd.h
> > -sysprf := $(srctree)/tools/perf/arch/riscv/entry/syscalls/
> > -systbl := $(sysprf)/mksyscalltbl
> > -
> > -# Create output directory if not already present
> > -$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
> > -
> > -$(header): $(sysdef) $(systbl)
> > -	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
> > -
> > -clean::
> > -	$(call QUIET_CLEAN, riscv) $(RM) $(header)
> > -
> > -archheaders: $(header)
> > diff --git a/tools/perf/arch/riscv/entry/syscalls/Kbuild b/tools/perf/arch/riscv/entry/syscalls/Kbuild
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
> > --- /dev/null
> > +++ b/tools/perf/arch/riscv/entry/syscalls/Kbuild
> > @@ -0,0 +1,2 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +syscall-y += syscalls_64.h
> > diff --git a/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..9668fd1faf60e828ed2786c2ee84739ac1f153fc
> > --- /dev/null
> > +++ b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
> > @@ -0,0 +1,4 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +syscall_abis_32 += riscv memfd_secret
> > +syscall_abis_64 += riscv rlimit memfd_secret
> > diff --git a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl b/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
> > deleted file mode 100755
> > index c59f5e852b97712a9a879b89e6ef6999ed4b6cd7..0000000000000000000000000000000000000000
> > --- a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
> > +++ /dev/null
> > @@ -1,47 +0,0 @@
> > -#!/bin/sh
> > -# SPDX-License-Identifier: GPL-2.0
> > -#
> > -# Generate system call table for perf. Derived from
> > -# powerpc script.
> > -#
> > -# Copyright IBM Corp. 2017
> > -# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
> > -# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
> > -# Changed by: Kim Phillips <kim.phillips at arm.com>
> > -# Changed by: Bj?rn T?pel <bjorn at rivosinc.com>
> > -
> > -gcc=$1
> > -hostcc=$2
> > -incpath=$3
> > -input=$4
> > -
> > -if ! test -r $input; then
> > -	echo "Could not read input file" >&2
> > -	exit 1
> > -fi
> > -
> > -create_sc_table()
> > -{
> > -	local sc nr max_nr
> > -
> > -	while read sc nr; do
> > -		printf "%s\n" "	[$nr] = \"$sc\","
> > -		max_nr=$nr
> > -	done
> > -
> > -	echo "#define SYSCALLTBL_RISCV_MAX_ID $max_nr"
> > -}
> > -
> > -create_table()
> > -{
> > -	echo "#include \"$input\""
> > -	echo "static const char *const syscalltbl_riscv[] = {"
> > -	create_sc_table
> > -	echo "};"
> > -}
> > -
> > -$gcc -E -dM -x c -I $incpath/include/uapi $input \
> > -	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
> > -		sub("^#define __NR(3264)?_", "");
> > -		print | "sort -k2 -n"}' \
> > -	|create_table
> > diff --git a/tools/perf/arch/riscv/include/syscall_table.h b/tools/perf/arch/riscv/include/syscall_table.h
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
> > --- /dev/null
> > +++ b/tools/perf/arch/riscv/include/syscall_table.h
> > @@ -0,0 +1,8 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#include <asm/bitsperlong.h>
> > +
> > +#if __BITS_PER_LONG == 64
> > +#include <asm/syscalls_64.h>
> > +#else
> > +#include <asm/syscalls_32.h>
> > +#endif
> > diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
> > index a05c1c105c51bf1bd18a59195220894598eb7461..692f48db810ccbef229e240db29261f0c60db632 100755
> > --- a/tools/perf/check-headers.sh
> > +++ b/tools/perf/check-headers.sh
> > @@ -71,6 +71,7 @@ FILES=(
> >    "include/uapi/asm-generic/ioctls.h"
> >    "include/uapi/asm-generic/mman-common.h"
> >    "include/uapi/asm-generic/unistd.h"
> > +  "scripts/syscall.tbl"
> >  )
> >  
> >  declare -a SYNC_CHECK_FILES
> > diff --git a/tools/perf/scripts/Makefile.syscalls b/tools/perf/scripts/Makefile.syscalls
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..e2b0c4b513d5c42c8e9ac51a9ea774c34a1311b7
> > --- /dev/null
> > +++ b/tools/perf/scripts/Makefile.syscalls
> > @@ -0,0 +1,60 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +# This Makefile generates tools/perf/arch/$(SRCARCH)/include/generated/asm from
> > +# the generic syscall table if that is supported by the architecture, otherwise
> > +# from the architecture's defined syscall table.
> > +
> > +PHONY := all
> > +all:
> > +
> > +obj := $(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated/asm
> > +
> > +syscall_abis_32  += common,32
> > +syscall_abis_64  += common,64
> 
> Couldn't it be := instead of += ?

Yes good point.

> 
> 
> > +syscalltbl := $(srctree)/tools/scripts/syscall.tbl
> > +
> > +# let architectures override $(syscall_abis_%) and $(syscalltbl)
> > +-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Makefile.syscalls
> > +include $(srctree)/scripts/Kbuild.include
> > +-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Kbuild
> > +
> > +systbl := $(srctree)/tools/perf/scripts/syscalltbl.sh
> > +
> > +syscall-y   := $(addprefix $(obj)/, $(syscall-y))
> > +
> > +# Remove stale wrappers when the corresponding files are removed from generic-y
> > +old-headers := $(wildcard $(obj)/*.c)
> > +unwanted    := $(filter-out $(syscall-y),$(old-headers))
> 
> Can you elaborate?  What's the stable wrappers?
> 
> I think syscall-y and old-headers have .h files but the wildcard above
> is called for .c files?

Oh yes! I meant to change that to .h, thank you for mentioning that, I
had .c at some point during development but changed it to .h files.

- Charlie

> 
> Thanks,
> Namhyung
> 
> > +
> > +quiet_cmd_remove = REMOVE  $(unwanted)
> > +      cmd_remove = rm -f $(unwanted)
> > +
> > +quiet_cmd_systbl = SYSTBL  $@
> > +      cmd_systbl = $(CONFIG_SHELL) $(systbl) \
> > +		   $(if $(systbl-args-$*),$(systbl-args-$*),$(systbl-args)) \
> > +		   --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \
> > +		   $< $@
> > +
> > +all: $(syscall-y)
> > +	$(if $(unwanted),$(call cmd,remove))
> > +	@:
> > +
> > +$(obj)/syscalls_%.h: $(syscalltbl) $(systbl) FORCE
> > +	$(call if_changed,systbl)
> > +
> > +targets := $(syscall-y)
> > +
> > +# Create output directory. Skip it if at least one old header exists
> > +# since we know the output directory already exists.
> > +ifeq ($(old-headers),)
> > +$(shell mkdir -p $(obj))
> > +endif
> > +
> > +PHONY += FORCE
> > +
> > +FORCE:
> > +
> > +existing-targets := $(wildcard $(sort $(targets)))
> > +
> > +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
> > +
> > +.PHONY: $(PHONY)


From apopple at nvidia.com  Mon Dec 16 21:12:48 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:48 +1100
Subject: [PATCH v4 05/25] fs/dax: Create a common implementation to break DAX layouts
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <ea8d2a2dfd70fa56a32a37d595df1d561436eb50.1734407924.git-series.apopple@nvidia.com>

Prior to freeing a block file systems supporting FS DAX must check
that the associated pages are both unmapped from user-space and not
undergoing DMA or other access from eg. get_user_pages(). This is
achieved by unmapping the file range and scanning the FS DAX
page-cache to see if any pages within the mapping have an elevated
refcount.

This is done using two functions - dax_layout_busy_page_range() which
returns a page to wait for the refcount to become idle on. Rather than
open-code this introduce a common implementation to both unmap and
wait for the page to become idle.

Signed-off-by: Alistair Popple <apopple at nvidia.com>

---

Changes for v4:

 - Fixed some build breakage due to missing symbol exports reported by
   John Hubbard (thanks!).
---
 fs/dax.c            | 30 ++++++++++++++++++++++++++++++
 fs/ext4/inode.c     | 10 +---------
 fs/fuse/dax.c       | 29 +++++------------------------
 fs/xfs/xfs_inode.c  | 23 +++++------------------
 fs/xfs/xfs_inode.h  |  2 +-
 include/linux/dax.h | 21 +++++++++++++++++++++
 mm/madvise.c        |  8 ++++----
 7 files changed, 67 insertions(+), 56 deletions(-)

diff --git a/fs/dax.c b/fs/dax.c
index d010c10..5462d9d 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -845,6 +845,36 @@ int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index)
 	return ret;
 }
 
+static int wait_page_idle(struct page *page,
+			void (cb)(struct inode *),
+			struct inode *inode)
+{
+	return ___wait_var_event(page, page_ref_count(page) == 1,
+				TASK_INTERRUPTIBLE, 0, 0, cb(inode));
+}
+
+/*
+ * Unmaps the inode and waits for any DMA to complete prior to deleting the
+ * DAX mapping entries for the range.
+ */
+int dax_break_mapping(struct inode *inode, loff_t start, loff_t end,
+		void (cb)(struct inode *))
+{
+	struct page *page;
+	int error;
+
+	do {
+		page = dax_layout_busy_page_range(inode->i_mapping, start, end);
+		if (!page)
+			break;
+
+		error = wait_page_idle(page, cb, inode);
+	} while (error == 0);
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(dax_break_mapping);
+
 /*
  * Invalidate DAX entry if it is clean.
  */
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index cc1acb1..ee8e83f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3917,15 +3917,7 @@ int ext4_break_layouts(struct inode *inode)
 	if (WARN_ON_ONCE(!rwsem_is_locked(&inode->i_mapping->invalidate_lock)))
 		return -EINVAL;
 
-	do {
-		page = dax_layout_busy_page(inode->i_mapping);
-		if (!page)
-			return 0;
-
-		error = dax_wait_page_idle(page, ext4_wait_dax_page, inode);
-	} while (error == 0);
-
-	return error;
+	return dax_break_mapping_inode(inode, ext4_wait_dax_page);
 }
 
 /*
diff --git a/fs/fuse/dax.c b/fs/fuse/dax.c
index d156c55..48d0652 100644
--- a/fs/fuse/dax.c
+++ b/fs/fuse/dax.c
@@ -665,38 +665,19 @@ static void fuse_wait_dax_page(struct inode *inode)
 	filemap_invalidate_lock(inode->i_mapping);
 }
 
-/* Should be called with mapping->invalidate_lock held exclusively */
-static int __fuse_dax_break_layouts(struct inode *inode, bool *retry,
-				    loff_t start, loff_t end)
-{
-	struct page *page;
-
-	page = dax_layout_busy_page_range(inode->i_mapping, start, end);
-	if (!page)
-		return 0;
-
-	*retry = true;
-	return dax_wait_page_idle(page, fuse_wait_dax_page, inode);
-}
-
-/* dmap_end == 0 leads to unmapping of whole file */
+/* Should be called with mapping->invalidate_lock held exclusively.
+ * dmap_end == 0 leads to unmapping of whole file.
+ */
 int fuse_dax_break_layouts(struct inode *inode, u64 dmap_start,
 				  u64 dmap_end)
 {
-	bool	retry;
-	int	ret;
-
-	do {
-		retry = false;
-		ret = __fuse_dax_break_layouts(inode, &retry, dmap_start,
-					       dmap_end);
-	} while (ret == 0 && retry);
 	if (!dmap_end) {
 		dmap_start = 0;
 		dmap_end = LLONG_MAX;
 	}
 
-	return ret;
+	return dax_break_mapping(inode, dmap_start, dmap_end,
+				fuse_wait_dax_page);
 }
 
 ssize_t fuse_dax_read_iter(struct kiocb *iocb, struct iov_iter *to)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 42ea203..295730a 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2715,21 +2715,17 @@ xfs_mmaplock_two_inodes_and_break_dax_layout(
 	struct xfs_inode	*ip2)
 {
 	int			error;
-	bool			retry;
 	struct page		*page;
 
 	if (ip1->i_ino > ip2->i_ino)
 		swap(ip1, ip2);
 
 again:
-	retry = false;
 	/* Lock the first inode */
 	xfs_ilock(ip1, XFS_MMAPLOCK_EXCL);
-	error = xfs_break_dax_layouts(VFS_I(ip1), &retry);
-	if (error || retry) {
+	error = xfs_break_dax_layouts(VFS_I(ip1));
+	if (error) {
 		xfs_iunlock(ip1, XFS_MMAPLOCK_EXCL);
-		if (error == 0 && retry)
-			goto again;
 		return error;
 	}
 
@@ -2988,19 +2984,11 @@ xfs_wait_dax_page(
 
 int
 xfs_break_dax_layouts(
-	struct inode		*inode,
-	bool			*retry)
+	struct inode		*inode)
 {
-	struct page		*page;
-
 	xfs_assert_ilocked(XFS_I(inode), XFS_MMAPLOCK_EXCL);
 
-	page = dax_layout_busy_page(inode->i_mapping);
-	if (!page)
-		return 0;
-
-	*retry = true;
-	return dax_wait_page_idle(page, xfs_wait_dax_page, inode);
+	return dax_break_mapping_inode(inode, xfs_wait_dax_page);
 }
 
 int
@@ -3018,8 +3006,7 @@ xfs_break_layouts(
 		retry = false;
 		switch (reason) {
 		case BREAK_UNMAP:
-			error = xfs_break_dax_layouts(inode, &retry);
-			if (error || retry)
+			if (xfs_break_dax_layouts(inode))
 				break;
 			fallthrough;
 		case BREAK_WRITE:
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 1648dc5..c4f03f6 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -593,7 +593,7 @@ xfs_itruncate_extents(
 	return xfs_itruncate_extents_flags(tpp, ip, whichfork, new_size, 0);
 }
 
-int	xfs_break_dax_layouts(struct inode *inode, bool *retry);
+int	xfs_break_dax_layouts(struct inode *inode);
 int	xfs_break_layouts(struct inode *inode, uint *iolock,
 		enum layout_break_reason reason);
 
diff --git a/include/linux/dax.h b/include/linux/dax.h
index 9b1ce98..f6583d3 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -228,6 +228,20 @@ static inline void dax_read_unlock(int id)
 {
 }
 #endif /* CONFIG_DAX */
+
+#if !IS_ENABLED(CONFIG_FS_DAX)
+static inline int __must_check dax_break_mapping(struct inode *inode,
+			    loff_t start, loff_t end, void (cb)(struct inode *))
+{
+	return 0;
+}
+
+static inline void dax_break_mapping_uninterruptible(struct inode *inode,
+						void (cb)(struct inode *))
+{
+}
+#endif
+
 bool dax_alive(struct dax_device *dax_dev);
 void *dax_get_private(struct dax_device *dax_dev);
 long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
@@ -251,6 +265,13 @@ vm_fault_t dax_finish_sync_fault(struct vm_fault *vmf,
 int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index);
 int dax_invalidate_mapping_entry_sync(struct address_space *mapping,
 				      pgoff_t index);
+int __must_check dax_break_mapping(struct inode *inode, loff_t start,
+				loff_t end, void (cb)(struct inode *));
+static inline int __must_check dax_break_mapping_inode(struct inode *inode,
+						void (cb)(struct inode *))
+{
+	return dax_break_mapping(inode, 0, LLONG_MAX, cb);
+}
 int dax_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
 				  struct inode *dest, loff_t destoff,
 				  loff_t len, bool *is_same,
diff --git a/mm/madvise.c b/mm/madvise.c
index 49f3a75..1f4c99e 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -1063,7 +1063,7 @@ static int guard_install_pud_entry(pud_t *pud, unsigned long addr,
 	pud_t pudval = pudp_get(pud);
 
 	/* If huge return >0 so we abort the operation + zap. */
-	return pud_trans_huge(pudval) || pud_devmap(pudval);
+	return pud_trans_huge(pudval);
 }
 
 static int guard_install_pmd_entry(pmd_t *pmd, unsigned long addr,
@@ -1072,7 +1072,7 @@ static int guard_install_pmd_entry(pmd_t *pmd, unsigned long addr,
 	pmd_t pmdval = pmdp_get(pmd);
 
 	/* If huge return >0 so we abort the operation + zap. */
-	return pmd_trans_huge(pmdval) || pmd_devmap(pmdval);
+	return pmd_trans_huge(pmdval);
 }
 
 static int guard_install_pte_entry(pte_t *pte, unsigned long addr,
@@ -1183,7 +1183,7 @@ static int guard_remove_pud_entry(pud_t *pud, unsigned long addr,
 	pud_t pudval = pudp_get(pud);
 
 	/* If huge, cannot have guard pages present, so no-op - skip. */
-	if (pud_trans_huge(pudval) || pud_devmap(pudval))
+	if (pud_trans_huge(pudval))
 		walk->action = ACTION_CONTINUE;
 
 	return 0;
@@ -1195,7 +1195,7 @@ static int guard_remove_pmd_entry(pmd_t *pmd, unsigned long addr,
 	pmd_t pmdval = pmdp_get(pmd);
 
 	/* If huge, cannot have guard pages present, so no-op - skip. */
-	if (pmd_trans_huge(pmdval) || pmd_devmap(pmdval))
+	if (pmd_trans_huge(pmdval))
 		walk->action = ACTION_CONTINUE;
 
 	return 0;
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:49 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:49 +1100
Subject: [PATCH v4 06/25] fs/dax: Always remove DAX page-cache entries when breaking layouts
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <be25c9f9fbc1481162a46049b62486b9a095bf94.1734407924.git-series.apopple@nvidia.com>

Prior to any truncation operations file systems call
dax_break_mapping() to ensure pages in the range are not under going
DMA. Later DAX page-cache entries will be removed by
truncate_folio_batch_exceptionals() in the generic page-cache code.

However this makes it possible for folios to be removed from the
page-cache even though they are still DMA busy if the file-system
hasn't called dax_break_mapping(). It also means they can never be
waited on in future because FS DAX will lose track of them once the
page-cache entry has been deleted.

Instead it is better to delete the FS DAX entry when the file-system
calls dax_break_mapping() as part of it's truncate operation. This
ensures only idle pages can be removed from the FS DAX page-cache and
makes it easy to detect if a file-system hasn't called
dax_break_mapping() prior to a truncate operation.

Signed-off-by: Alistair Popple <apopple at nvidia.com>

---

Ideally I think we would move the whole wait-for-idle logic directly
into the truncate paths. However this is difficult for a few
reasons. Each filesystem needs it's own wait callback, although a new
address space operation could address that. More problematic is that
the wait-for-idle can fail as the wait is TASK_INTERRUPTIBLE, but none
of the generic truncate paths allow for failure.

So it ends up being easier to continue to let file systems call this
and check that they behave as expected.
---
 fs/dax.c            | 33 +++++++++++++++++++++++++++++++++
 fs/xfs/xfs_inode.c  |  6 ++++++
 include/linux/dax.h |  2 ++
 mm/truncate.c       | 16 +++++++++++++++-
 4 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/fs/dax.c b/fs/dax.c
index 5462d9d..cd6cca8 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -845,6 +845,36 @@ int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index)
 	return ret;
 }
 
+void dax_delete_mapping_range(struct address_space *mapping,
+				loff_t start, loff_t end)
+{
+	void *entry;
+	pgoff_t start_idx = start >> PAGE_SHIFT;
+	pgoff_t end_idx;
+	XA_STATE(xas, &mapping->i_pages, start_idx);
+
+	/* If end == LLONG_MAX, all pages from start to till end of file */
+	if (end == LLONG_MAX)
+		end_idx = ULONG_MAX;
+	else
+		end_idx = end >> PAGE_SHIFT;
+
+	xas_lock_irq(&xas);
+	xas_for_each(&xas, entry, end_idx) {
+		if (!xa_is_value(entry))
+			continue;
+		entry = wait_entry_unlocked_exclusive(&xas, entry);
+		if (!entry)
+			continue;
+		dax_disassociate_entry(entry, mapping, true);
+		xas_store(&xas, NULL);
+		mapping->nrpages -= 1UL << dax_entry_order(entry);
+		put_unlocked_entry(&xas, entry, WAKE_ALL);
+	}
+	xas_unlock_irq(&xas);
+}
+EXPORT_SYMBOL_GPL(dax_delete_mapping_range);
+
 static int wait_page_idle(struct page *page,
 			void (cb)(struct inode *),
 			struct inode *inode)
@@ -871,6 +901,9 @@ int dax_break_mapping(struct inode *inode, loff_t start, loff_t end,
 		error = wait_page_idle(page, cb, inode);
 	} while (error == 0);
 
+	if (!page)
+		dax_delete_mapping_range(inode->i_mapping, start, end);
+
 	return error;
 }
 EXPORT_SYMBOL_GPL(dax_break_mapping);
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 295730a..4410b42 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2746,6 +2746,12 @@ xfs_mmaplock_two_inodes_and_break_dax_layout(
 		goto again;
 	}
 
+	/*
+	 * Normally xfs_break_dax_layouts() would delete the mapping entries as well so
+	 * do that here.
+	 */
+	dax_delete_mapping_range(VFS_I(ip2)->i_mapping, 0, LLONG_MAX);
+
 	return 0;
 }
 
diff --git a/include/linux/dax.h b/include/linux/dax.h
index f6583d3..ef9e02c 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -263,6 +263,8 @@ vm_fault_t dax_iomap_fault(struct vm_fault *vmf, unsigned int order,
 vm_fault_t dax_finish_sync_fault(struct vm_fault *vmf,
 		unsigned int order, pfn_t pfn);
 int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index);
+void dax_delete_mapping_range(struct address_space *mapping,
+				loff_t start, loff_t end);
 int dax_invalidate_mapping_entry_sync(struct address_space *mapping,
 				      pgoff_t index);
 int __must_check dax_break_mapping(struct inode *inode, loff_t start,
diff --git a/mm/truncate.c b/mm/truncate.c
index 7c304d2..b7f51a6 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -78,8 +78,22 @@ static void truncate_folio_batch_exceptionals(struct address_space *mapping,
 
 	if (dax_mapping(mapping)) {
 		for (i = j; i < nr; i++) {
-			if (xa_is_value(fbatch->folios[i]))
+			if (xa_is_value(fbatch->folios[i])) {
+				/*
+				 * File systems should already have called
+				 * dax_break_mapping_entry() to remove all DAX
+				 * entries while holding a lock to prevent
+				 * establishing new entries. Therefore we
+				 * shouldn't find any here.
+				 */
+				WARN_ON_ONCE(1);
+
+				/*
+				 * Delete the mapping so truncate_pagecache()
+				 * doesn't loop forever.
+				 */
 				dax_delete_mapping_entry(mapping, indices[i]);
+			}
 		}
 		goto out;
 	}
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:50 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:50 +1100
Subject: [PATCH v4 07/25] fs/dax: Ensure all pages are idle prior to filesystem unmount
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <f6aea86fad2d670a35ff9d60ba8e9f3f748bbd8c.1734407924.git-series.apopple@nvidia.com>

File systems call dax_break_mapping() prior to reallocating file
system blocks to ensure the page is not undergoing any DMA or other
accesses. Generally this is needed when a file is truncated to ensure
that if a block is reallocated nothing is writing to it. However
filesystems currently don't call this when an FS DAX inode is evicted.

This can cause problems when the file system is unmounted as a page
can continue to be under going DMA or other remote access after
unmount. This means if the file system is remounted any truncate or
other operation which requires the underlying file system block to be
freed will not wait for the remote access to complete. Therefore a
busy block may be reallocated to a new file leading to corruption.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 fs/dax.c            | 26 ++++++++++++++++++++++++++
 fs/ext4/inode.c     | 32 ++++++++++++++------------------
 fs/xfs/xfs_inode.c  |  9 +++++++++
 fs/xfs/xfs_inode.h  |  1 +
 fs/xfs/xfs_super.c  | 18 ++++++++++++++++++
 include/linux/dax.h |  2 ++
 6 files changed, 70 insertions(+), 18 deletions(-)

diff --git a/fs/dax.c b/fs/dax.c
index cd6cca8..34a7690 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -883,6 +883,14 @@ static int wait_page_idle(struct page *page,
 				TASK_INTERRUPTIBLE, 0, 0, cb(inode));
 }
 
+static void wait_page_idle_uninterruptible(struct page *page,
+					void (cb)(struct inode *),
+					struct inode *inode)
+{
+	___wait_var_event(page, page_ref_count(page) == 1,
+			TASK_UNINTERRUPTIBLE, 0, 0, cb(inode));
+}
+
 /*
  * Unmaps the inode and waits for any DMA to complete prior to deleting the
  * DAX mapping entries for the range.
@@ -908,6 +916,24 @@ int dax_break_mapping(struct inode *inode, loff_t start, loff_t end,
 }
 EXPORT_SYMBOL_GPL(dax_break_mapping);
 
+void dax_break_mapping_uninterruptible(struct inode *inode,
+				void (cb)(struct inode *))
+{
+	struct page *page;
+
+	do {
+		page = dax_layout_busy_page_range(inode->i_mapping, 0,
+						LLONG_MAX);
+		if (!page)
+			break;
+
+		wait_page_idle_uninterruptible(page, cb, inode);
+	} while (true);
+
+	dax_delete_mapping_range(inode->i_mapping, 0, LLONG_MAX);
+}
+EXPORT_SYMBOL_GPL(dax_break_mapping_uninterruptible);
+
 /*
  * Invalidate DAX entry if it is clean.
  */
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ee8e83f..fa35161 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -163,6 +163,18 @@ int ext4_inode_is_fast_symlink(struct inode *inode)
 	       (inode->i_size < EXT4_N_BLOCKS * 4);
 }
 
+static void ext4_wait_dax_page(struct inode *inode)
+{
+	filemap_invalidate_unlock(inode->i_mapping);
+	schedule();
+	filemap_invalidate_lock(inode->i_mapping);
+}
+
+int ext4_break_layouts(struct inode *inode)
+{
+	return dax_break_mapping_inode(inode, ext4_wait_dax_page);
+}
+
 /*
  * Called at the last iput() if i_nlink is zero.
  */
@@ -181,6 +193,8 @@ void ext4_evict_inode(struct inode *inode)
 
 	trace_ext4_evict_inode(inode);
 
+	dax_break_mapping_uninterruptible(inode, ext4_wait_dax_page);
+
 	if (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)
 		ext4_evict_ea_inode(inode);
 	if (inode->i_nlink) {
@@ -3902,24 +3916,6 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
 	return ret;
 }
 
-static void ext4_wait_dax_page(struct inode *inode)
-{
-	filemap_invalidate_unlock(inode->i_mapping);
-	schedule();
-	filemap_invalidate_lock(inode->i_mapping);
-}
-
-int ext4_break_layouts(struct inode *inode)
-{
-	struct page *page;
-	int error;
-
-	if (WARN_ON_ONCE(!rwsem_is_locked(&inode->i_mapping->invalidate_lock)))
-		return -EINVAL;
-
-	return dax_break_mapping_inode(inode, ext4_wait_dax_page);
-}
-
 /*
  * ext4_punch_hole: punches a hole in a file by releasing the blocks
  * associated with the given offset and length
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 4410b42..c7ec5ab 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2997,6 +2997,15 @@ xfs_break_dax_layouts(
 	return dax_break_mapping_inode(inode, xfs_wait_dax_page);
 }
 
+void
+xfs_break_dax_layouts_uninterruptible(
+	struct inode		*inode)
+{
+	xfs_assert_ilocked(XFS_I(inode), XFS_MMAPLOCK_EXCL);
+
+	dax_break_mapping_uninterruptible(inode, xfs_wait_dax_page);
+}
+
 int
 xfs_break_layouts(
 	struct inode		*inode,
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index c4f03f6..613797a 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -594,6 +594,7 @@ xfs_itruncate_extents(
 }
 
 int	xfs_break_dax_layouts(struct inode *inode);
+void xfs_break_dax_layouts_uninterruptible(struct inode *inode);
 int	xfs_break_layouts(struct inode *inode, uint *iolock,
 		enum layout_break_reason reason);
 
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 8524b9d..73ec060 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -751,6 +751,23 @@ xfs_fs_drop_inode(
 	return generic_drop_inode(inode);
 }
 
+STATIC void
+xfs_fs_evict_inode(
+	struct inode		*inode)
+{
+	struct xfs_inode	*ip = XFS_I(inode);
+	uint			iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
+
+	if (IS_DAX(inode)) {
+		xfs_ilock(ip, iolock);
+		xfs_break_dax_layouts_uninterruptible(inode);
+		xfs_iunlock(ip, iolock);
+	}
+
+	truncate_inode_pages_final(&inode->i_data);
+	clear_inode(inode);
+}
+
 static void
 xfs_mount_free(
 	struct xfs_mount	*mp)
@@ -1189,6 +1206,7 @@ static const struct super_operations xfs_super_operations = {
 	.destroy_inode		= xfs_fs_destroy_inode,
 	.dirty_inode		= xfs_fs_dirty_inode,
 	.drop_inode		= xfs_fs_drop_inode,
+	.evict_inode		= xfs_fs_evict_inode,
 	.put_super		= xfs_fs_put_super,
 	.sync_fs		= xfs_fs_sync_fs,
 	.freeze_fs		= xfs_fs_freeze,
diff --git a/include/linux/dax.h b/include/linux/dax.h
index ef9e02c..7c3773f 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -274,6 +274,8 @@ static inline int __must_check dax_break_mapping_inode(struct inode *inode,
 {
 	return dax_break_mapping(inode, 0, LLONG_MAX, cb);
 }
+void dax_break_mapping_uninterruptible(struct inode *inode,
+				void (cb)(struct inode *));
 int dax_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
 				  struct inode *dest, loff_t destoff,
 				  loff_t len, bool *is_same,
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:51 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:51 +1100
Subject: [PATCH v4 08/25] fs/dax: Remove PAGE_MAPPING_DAX_SHARED mapping flag
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <0aabbc2d9fe4d136d5a7458c4fa55e4b139a0b5e.1734407924.git-series.apopple@nvidia.com>

PAGE_MAPPING_DAX_SHARED is the same as PAGE_MAPPING_ANON. This isn't
currently a problem because FS DAX pages are treated
specially. However a future change will make FS DAX pages more like
normal pages, so folio_test_anon() must not return true for a FS DAX
page.

We could explicitly test for a FS DAX page in folio_test_anon(),
etc. however the PAGE_MAPPING_DAX_SHARED flag isn't actually
needed. Instead we can use the page->mapping field to implicitly track
the first mapping of a page. If page->mapping is non-NULL it implies
the page is associated with a single mapping at page->index. If the
page is associated with a second mapping clear page->mapping and set
page->share to 1.

This is possible because a shared mapping implies the file-system
implements dax_holder_operations which makes the ->mapping and
->index, which is a union with ->share, unused.

The page is considered shared when page->mapping == NULL and
page->share > 0 or page->mapping != NULL, implying it is present in at
least one address space. This also makes it easier for a future change
to detect when a page is first mapped into an address space which
requires special handling.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 fs/dax.c                   | 45 +++++++++++++++++++++++++--------------
 include/linux/page-flags.h |  6 +-----
 2 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/fs/dax.c b/fs/dax.c
index 34a7690..6f2d1de 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -351,38 +351,41 @@ static unsigned long dax_end_pfn(void *entry)
 	for (pfn = dax_to_pfn(entry); \
 			pfn < dax_end_pfn(entry); pfn++)
 
+/*
+ * A DAX page is considered shared if it has no mapping set and ->share (which
+ * shares the ->index field) is non-zero. Note this may return false even if the
+ * page if shared between multiple files but has not yet actually been mapped
+ * into multiple address spaces.
+ */
 static inline bool dax_page_is_shared(struct page *page)
 {
-	return page->mapping == PAGE_MAPPING_DAX_SHARED;
+	return !page->mapping && page->share;
 }
 
 /*
- * Set the page->mapping with PAGE_MAPPING_DAX_SHARED flag, increase the
- * refcount.
+ * Increase the page share refcount, warning if the page is not marked as shared.
  */
 static inline void dax_page_share_get(struct page *page)
 {
-	if (page->mapping != PAGE_MAPPING_DAX_SHARED) {
-		/*
-		 * Reset the index if the page was already mapped
-		 * regularly before.
-		 */
-		if (page->mapping)
-			page->share = 1;
-		page->mapping = PAGE_MAPPING_DAX_SHARED;
-	}
+	WARN_ON_ONCE(!page->share);
+	WARN_ON_ONCE(page->mapping);
 	page->share++;
 }
 
 static inline unsigned long dax_page_share_put(struct page *page)
 {
+	WARN_ON_ONCE(!page->share);
 	return --page->share;
 }
 
 /*
- * When it is called in dax_insert_entry(), the shared flag will indicate that
- * whether this entry is shared by multiple files.  If so, set the page->mapping
- * PAGE_MAPPING_DAX_SHARED, and use page->share as refcount.
+ * When it is called in dax_insert_entry(), the shared flag will indicate
+ * whether this entry is shared by multiple files. If the page has not
+ * previously been associated with any mappings the ->mapping and ->index
+ * fields will be set. If it has already been associated with a mapping
+ * the mapping will be cleared and the share count set. It's then up the
+ * file-system to track which mappings contain which pages, ie. by implementing
+ * dax_holder_operations.
  */
 static void dax_associate_entry(void *entry, struct address_space *mapping,
 		struct vm_area_struct *vma, unsigned long address, bool shared)
@@ -397,7 +400,17 @@ static void dax_associate_entry(void *entry, struct address_space *mapping,
 	for_each_mapped_pfn(entry, pfn) {
 		struct page *page = pfn_to_page(pfn);
 
-		if (shared) {
+		if (shared && page->mapping && page->share) {
+			if (page->mapping) {
+				page->mapping = NULL;
+
+				/*
+				 * Page has already been mapped into one address
+				 * space so set the share count.
+				 */
+				page->share = 1;
+			}
+
 			dax_page_share_get(page);
 		} else {
 			WARN_ON_ONCE(page->mapping);
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 691506b..598334e 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -668,12 +668,6 @@ PAGEFLAG_FALSE(VmemmapSelfHosted, vmemmap_self_hosted)
 #define PAGE_MAPPING_KSM	(PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
 #define PAGE_MAPPING_FLAGS	(PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
 
-/*
- * Different with flags above, this flag is used only for fsdax mode.  It
- * indicates that this page->mapping is now under reflink case.
- */
-#define PAGE_MAPPING_DAX_SHARED	((void *)0x1)
-
 static __always_inline bool folio_mapping_flags(const struct folio *folio)
 {
 	return ((unsigned long)folio->mapping & PAGE_MAPPING_FLAGS) != 0;
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:52 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:52 +1100
Subject: [PATCH v4 09/25] mm/gup.c: Remove redundant check for PCI P2PDMA page
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <3f20b8d258d4eb72e1eadd5926d892bc61f0e0d4.1734407924.git-series.apopple@nvidia.com>

PCI P2PDMA pages are not mapped with pXX_devmap PTEs therefore the
check in __gup_device_huge() is redundant. Remove it

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Reviewed-by: Dan Wiliams <dan.j.williams at intel.com>
Acked-by: David Hildenbrand <david at redhat.com>
---
 mm/gup.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 2304175..9b587b5 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3016,11 +3016,6 @@ static int gup_fast_devmap_leaf(unsigned long pfn, unsigned long addr,
 			break;
 		}
 
-		if (!(flags & FOLL_PCI_P2PDMA) && is_pci_p2pdma_page(page)) {
-			gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
-			break;
-		}
-
 		folio = try_grab_folio_fast(page, 1, flags);
 		if (!folio) {
 			gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:53 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:53 +1100
Subject: [PATCH v4 10/25] mm/mm_init: Move p2pdma page refcount initialisation to p2pdma
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <aaa23e6f315a2d9b30a422c3769100cdfa42e85a.1734407924.git-series.apopple@nvidia.com>

Currently ZONE_DEVICE page reference counts are initialised by core
memory management code in __init_zone_device_page() as part of the
memremap() call which driver modules make to obtain ZONE_DEVICE
pages. This initialises page refcounts to 1 before returning them to
the driver.

This was presumably done because it drivers had a reference of sorts
on the page. It also ensured the page could always be mapped with
vm_insert_page() for example and would never get freed (ie. have a
zero refcount), freeing drivers of manipulating page reference counts.

However it complicates figuring out whether or not a page is free from
the mm perspective because it is no longer possible to just look at
the refcount. Instead the page type must be known and if GUP is used a
secondary pgmap reference is also sometimes needed.

To simplify this it is desirable to remove the page reference count
for the driver, so core mm can just use the refcount without having to
account for page type or do other types of tracking. This is possible
because drivers can always assume the page is valid as core kernel
will never offline or remove the struct page.

This means it is now up to drivers to initialise the page refcount as
required. P2PDMA uses vm_insert_page() to map the page, and that
requires a non-zero reference count when initialising the page so set
that when the page is first mapped.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Reviewed-by: Dan Williams <dan.j.williams at intel.com>

---

Changes since v2:

 - Initialise the page refcount for all pages covered by the kaddr
---
 drivers/pci/p2pdma.c | 13 +++++++++++--
 mm/memremap.c        | 17 +++++++++++++----
 mm/mm_init.c         | 22 ++++++++++++++++++----
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 0cb7e0a..04773a8 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -140,13 +140,22 @@ static int p2pmem_alloc_mmap(struct file *filp, struct kobject *kobj,
 	rcu_read_unlock();
 
 	for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
-		ret = vm_insert_page(vma, vaddr, virt_to_page(kaddr));
+		struct page *page = virt_to_page(kaddr);
+
+		/*
+		 * Initialise the refcount for the freshly allocated page. As
+		 * we have just allocated the page no one else should be
+		 * using it.
+		 */
+		VM_WARN_ON_ONCE_PAGE(!page_ref_count(page), page);
+		set_page_count(page, 1);
+		ret = vm_insert_page(vma, vaddr, page);
 		if (ret) {
 			gen_pool_free(p2pdma->pool, (uintptr_t)kaddr, len);
 			return ret;
 		}
 		percpu_ref_get(ref);
-		put_page(virt_to_page(kaddr));
+		put_page(page);
 		kaddr += PAGE_SIZE;
 		len -= PAGE_SIZE;
 	}
diff --git a/mm/memremap.c b/mm/memremap.c
index 40d4547..07bbe0e 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -488,15 +488,24 @@ void free_zone_device_folio(struct folio *folio)
 	folio->mapping = NULL;
 	folio->page.pgmap->ops->page_free(folio_page(folio, 0));
 
-	if (folio->page.pgmap->type != MEMORY_DEVICE_PRIVATE &&
-	    folio->page.pgmap->type != MEMORY_DEVICE_COHERENT)
+	switch (folio->page.pgmap->type) {
+	case MEMORY_DEVICE_PRIVATE:
+	case MEMORY_DEVICE_COHERENT:
+		put_dev_pagemap(folio->page.pgmap);
+		break;
+
+	case MEMORY_DEVICE_FS_DAX:
+	case MEMORY_DEVICE_GENERIC:
 		/*
 		 * Reset the refcount to 1 to prepare for handing out the page
 		 * again.
 		 */
 		folio_set_count(folio, 1);
-	else
-		put_dev_pagemap(folio->page.pgmap);
+		break;
+
+	case MEMORY_DEVICE_PCI_P2PDMA:
+		break;
+	}
 }
 
 void zone_device_page_init(struct page *page)
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 24b68b4..f021e63 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1017,12 +1017,26 @@ static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,
 	}
 
 	/*
-	 * ZONE_DEVICE pages are released directly to the driver page allocator
-	 * which will set the page count to 1 when allocating the page.
+	 * ZONE_DEVICE pages other than MEMORY_TYPE_GENERIC and
+	 * MEMORY_TYPE_FS_DAX pages are released directly to the driver page
+	 * allocator which will set the page count to 1 when allocating the
+	 * page.
+	 *
+	 * MEMORY_TYPE_GENERIC and MEMORY_TYPE_FS_DAX pages automatically have
+	 * their refcount reset to one whenever they are freed (ie. after
+	 * their refcount drops to 0).
 	 */
-	if (pgmap->type == MEMORY_DEVICE_PRIVATE ||
-	    pgmap->type == MEMORY_DEVICE_COHERENT)
+	switch (pgmap->type) {
+	case MEMORY_DEVICE_PRIVATE:
+	case MEMORY_DEVICE_COHERENT:
+	case MEMORY_DEVICE_PCI_P2PDMA:
 		set_page_count(page, 0);
+		break;
+
+	case MEMORY_DEVICE_FS_DAX:
+	case MEMORY_DEVICE_GENERIC:
+		break;
+	}
 }
 
 /*
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:54 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:54 +1100
Subject: [PATCH v4 11/25] mm: Allow compound zone device pages
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <ede5823e99c178bbe28470af1e5d84d09bfcc989.1734407924.git-series.apopple@nvidia.com>

Zone device pages are used to represent various type of device memory
managed by device drivers. Currently compound zone device pages are
not supported. This is because MEMORY_DEVICE_FS_DAX pages are the only
user of higher order zone device pages and have their own page
reference counting.

A future change will unify FS DAX reference counting with normal page
reference counting rules and remove the special FS DAX reference
counting. Supporting that requires compound zone device pages.

Supporting compound zone device pages requires compound_head() to
distinguish between head and tail pages whilst still preserving the
special struct page fields that are specific to zone device pages.

A tail page is distinguished by having bit zero being set in
page->compound_head, with the remaining bits pointing to the head
page. For zone device pages page->compound_head is shared with
page->pgmap.

The page->pgmap field is common to all pages within a memory section.
Therefore pgmap is the same for both head and tail pages and can be
moved into the folio and we can use the standard scheme to find
compound_head from a tail page.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Reviewed-by: Dan Williams <dan.j.williams at intel.com>

---

Changes for v4:
 - Fix build breakages reported by kernel test robot

Changes since v2:

 - Indentation fix
 - Rename page_dev_pagemap() to page_pgmap()
 - Rename folio _unused field to _unused_pgmap_compound_head
 - s/WARN_ON/VM_WARN_ON_ONCE_PAGE/

Changes since v1:

 - Move pgmap to the folio as suggested by Matthew Wilcox
---
 drivers/gpu/drm/nouveau/nouveau_dmem.c |  3 ++-
 drivers/pci/p2pdma.c                   |  6 +++---
 include/linux/memremap.h               |  6 +++---
 include/linux/migrate.h                |  4 ++--
 include/linux/mm_types.h               |  9 +++++++--
 include/linux/mmzone.h                 | 12 +++++++++++-
 lib/test_hmm.c                         |  3 ++-
 mm/hmm.c                               |  2 +-
 mm/memory.c                            |  4 +++-
 mm/memremap.c                          | 14 +++++++-------
 mm/migrate_device.c                    |  7 +++++--
 mm/mm_init.c                           |  2 +-
 12 files changed, 47 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c
index 1a07256..61d0f41 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
@@ -88,7 +88,8 @@ struct nouveau_dmem {
 
 static struct nouveau_dmem_chunk *nouveau_page_to_chunk(struct page *page)
 {
-	return container_of(page->pgmap, struct nouveau_dmem_chunk, pagemap);
+	return container_of(page_pgmap(page), struct nouveau_dmem_chunk,
+			    pagemap);
 }
 
 static struct nouveau_drm *page_to_drm(struct page *page)
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 04773a8..19214ec 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -202,7 +202,7 @@ static const struct attribute_group p2pmem_group = {
 
 static void p2pdma_page_free(struct page *page)
 {
-	struct pci_p2pdma_pagemap *pgmap = to_p2p_pgmap(page->pgmap);
+	struct pci_p2pdma_pagemap *pgmap = to_p2p_pgmap(page_pgmap(page));
 	/* safe to dereference while a reference is held to the percpu ref */
 	struct pci_p2pdma *p2pdma =
 		rcu_dereference_protected(pgmap->provider->p2pdma, 1);
@@ -1025,8 +1025,8 @@ enum pci_p2pdma_map_type
 pci_p2pdma_map_segment(struct pci_p2pdma_map_state *state, struct device *dev,
 		       struct scatterlist *sg)
 {
-	if (state->pgmap != sg_page(sg)->pgmap) {
-		state->pgmap = sg_page(sg)->pgmap;
+	if (state->pgmap != page_pgmap(sg_page(sg))) {
+		state->pgmap = page_pgmap(sg_page(sg));
 		state->map = pci_p2pdma_map_type(state->pgmap, dev);
 		state->bus_off = to_p2p_pgmap(state->pgmap)->bus_offset;
 	}
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 3f7143a..0256a42 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -161,7 +161,7 @@ static inline bool is_device_private_page(const struct page *page)
 {
 	return IS_ENABLED(CONFIG_DEVICE_PRIVATE) &&
 		is_zone_device_page(page) &&
-		page->pgmap->type == MEMORY_DEVICE_PRIVATE;
+		page_pgmap(page)->type == MEMORY_DEVICE_PRIVATE;
 }
 
 static inline bool folio_is_device_private(const struct folio *folio)
@@ -173,13 +173,13 @@ static inline bool is_pci_p2pdma_page(const struct page *page)
 {
 	return IS_ENABLED(CONFIG_PCI_P2PDMA) &&
 		is_zone_device_page(page) &&
-		page->pgmap->type == MEMORY_DEVICE_PCI_P2PDMA;
+		page_pgmap(page)->type == MEMORY_DEVICE_PCI_P2PDMA;
 }
 
 static inline bool is_device_coherent_page(const struct page *page)
 {
 	return is_zone_device_page(page) &&
-		page->pgmap->type == MEMORY_DEVICE_COHERENT;
+		page_pgmap(page)->type == MEMORY_DEVICE_COHERENT;
 }
 
 static inline bool folio_is_device_coherent(const struct folio *folio)
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 29919fa..61899ec 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -205,8 +205,8 @@ struct migrate_vma {
 	unsigned long		end;
 
 	/*
-	 * Set to the owner value also stored in page->pgmap->owner for
-	 * migrating out of device private memory. The flags also need to
+	 * Set to the owner value also stored in page_pgmap(page)->owner
+	 * for migrating out of device private memory. The flags also need to
 	 * be set to MIGRATE_VMA_SELECT_DEVICE_PRIVATE.
 	 * The caller should always set this field when using mmu notifier
 	 * callbacks to avoid device MMU invalidations for device private
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index df8f515..54b59b8 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -129,8 +129,11 @@ struct page {
 			unsigned long compound_head;	/* Bit zero is set */
 		};
 		struct {	/* ZONE_DEVICE pages */
-			/** @pgmap: Points to the hosting device page map. */
-			struct dev_pagemap *pgmap;
+			/*
+			 * The first word is used for compound_head or folio
+			 * pgmap
+			 */
+			void *_unused_pgmap_compound_head;
 			void *zone_device_data;
 			/*
 			 * ZONE_DEVICE private pages are counted as being
@@ -299,6 +302,7 @@ typedef struct {
  * @_refcount: Do not access this member directly.  Use folio_ref_count()
  *    to find how many references there are to this folio.
  * @memcg_data: Memory Control Group data.
+ * @pgmap: Metadata for ZONE_DEVICE mappings
  * @virtual: Virtual address in the kernel direct map.
  * @_last_cpupid: IDs of last CPU and last process that accessed the folio.
  * @_entire_mapcount: Do not use directly, call folio_entire_mapcount().
@@ -337,6 +341,7 @@ struct folio {
 	/* private: */
 				};
 	/* public: */
+				struct dev_pagemap *pgmap;
 			};
 			struct address_space *mapping;
 			pgoff_t index;
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index c7ad4d6..fd492c3 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -1159,6 +1159,12 @@ static inline bool is_zone_device_page(const struct page *page)
 	return page_zonenum(page) == ZONE_DEVICE;
 }
 
+static inline struct dev_pagemap *page_pgmap(const struct page *page)
+{
+	VM_WARN_ON_ONCE_PAGE(!is_zone_device_page(page), page);
+	return page_folio(page)->pgmap;
+}
+
 /*
  * Consecutive zone device pages should not be merged into the same sgl
  * or bvec segment with other types of pages or if they belong to different
@@ -1174,7 +1180,7 @@ static inline bool zone_device_pages_have_same_pgmap(const struct page *a,
 		return false;
 	if (!is_zone_device_page(a))
 		return true;
-	return a->pgmap == b->pgmap;
+	return page_pgmap(a) == page_pgmap(b);
 }
 
 extern void memmap_init_zone_device(struct zone *, unsigned long,
@@ -1189,6 +1195,10 @@ static inline bool zone_device_pages_have_same_pgmap(const struct page *a,
 {
 	return true;
 }
+static inline struct dev_pagemap *page_pgmap(const struct page *page)
+{
+	return NULL;
+}
 #endif
 
 static inline bool folio_is_zone_device(const struct folio *folio)
diff --git a/lib/test_hmm.c b/lib/test_hmm.c
index 056f2e4..ffd0c6f 100644
--- a/lib/test_hmm.c
+++ b/lib/test_hmm.c
@@ -195,7 +195,8 @@ static int dmirror_fops_release(struct inode *inode, struct file *filp)
 
 static struct dmirror_chunk *dmirror_page_to_chunk(struct page *page)
 {
-	return container_of(page->pgmap, struct dmirror_chunk, pagemap);
+	return container_of(page_pgmap(page), struct dmirror_chunk,
+			    pagemap);
 }
 
 static struct dmirror_device *dmirror_page_to_device(struct page *page)
diff --git a/mm/hmm.c b/mm/hmm.c
index 7e0229a..082f7b7 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -248,7 +248,7 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
 		 * just report the PFN.
 		 */
 		if (is_device_private_entry(entry) &&
-		    pfn_swap_entry_to_page(entry)->pgmap->owner ==
+		    page_pgmap(pfn_swap_entry_to_page(entry))->owner ==
 		    range->dev_private_owner) {
 			cpu_flags = HMM_PFN_VALID;
 			if (is_writable_device_private_entry(entry))
diff --git a/mm/memory.c b/mm/memory.c
index f09f20c..06bb29e 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4316,6 +4316,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 			vmf->page = pfn_swap_entry_to_page(entry);
 			ret = remove_device_exclusive_entry(vmf);
 		} else if (is_device_private_entry(entry)) {
+			struct dev_pagemap *pgmap;
 			if (vmf->flags & FAULT_FLAG_VMA_LOCK) {
 				/*
 				 * migrate_to_ram is not yet ready to operate
@@ -4340,7 +4341,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 			 */
 			get_page(vmf->page);
 			pte_unmap_unlock(vmf->pte, vmf->ptl);
-			ret = vmf->page->pgmap->ops->migrate_to_ram(vmf);
+			pgmap = page_pgmap(vmf->page);
+			ret = pgmap->ops->migrate_to_ram(vmf);
 			put_page(vmf->page);
 		} else if (is_hwpoison_entry(entry)) {
 			ret = VM_FAULT_HWPOISON;
diff --git a/mm/memremap.c b/mm/memremap.c
index 07bbe0e..68099af 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -458,8 +458,8 @@ EXPORT_SYMBOL_GPL(get_dev_pagemap);
 
 void free_zone_device_folio(struct folio *folio)
 {
-	if (WARN_ON_ONCE(!folio->page.pgmap->ops ||
-			!folio->page.pgmap->ops->page_free))
+	if (WARN_ON_ONCE(!folio->pgmap->ops ||
+			!folio->pgmap->ops->page_free))
 		return;
 
 	mem_cgroup_uncharge(folio);
@@ -486,12 +486,12 @@ void free_zone_device_folio(struct folio *folio)
 	 * to clear folio->mapping.
 	 */
 	folio->mapping = NULL;
-	folio->page.pgmap->ops->page_free(folio_page(folio, 0));
+	folio->pgmap->ops->page_free(folio_page(folio, 0));
 
-	switch (folio->page.pgmap->type) {
+	switch (folio->pgmap->type) {
 	case MEMORY_DEVICE_PRIVATE:
 	case MEMORY_DEVICE_COHERENT:
-		put_dev_pagemap(folio->page.pgmap);
+		put_dev_pagemap(folio->pgmap);
 		break;
 
 	case MEMORY_DEVICE_FS_DAX:
@@ -514,7 +514,7 @@ void zone_device_page_init(struct page *page)
 	 * Drivers shouldn't be allocating pages after calling
 	 * memunmap_pages().
 	 */
-	WARN_ON_ONCE(!percpu_ref_tryget_live(&page->pgmap->ref));
+	WARN_ON_ONCE(!percpu_ref_tryget_live(&page_pgmap(page)->ref));
 	set_page_count(page, 1);
 	lock_page(page);
 }
@@ -523,7 +523,7 @@ EXPORT_SYMBOL_GPL(zone_device_page_init);
 #ifdef CONFIG_FS_DAX
 bool __put_devmap_managed_folio_refs(struct folio *folio, int refs)
 {
-	if (folio->page.pgmap->type != MEMORY_DEVICE_FS_DAX)
+	if (folio->pgmap->type != MEMORY_DEVICE_FS_DAX)
 		return false;
 
 	/*
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 9cf2659..2209070 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -106,6 +106,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
 	arch_enter_lazy_mmu_mode();
 
 	for (; addr < end; addr += PAGE_SIZE, ptep++) {
+		struct dev_pagemap *pgmap;
 		unsigned long mpfn = 0, pfn;
 		struct folio *folio;
 		struct page *page;
@@ -133,9 +134,10 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
 				goto next;
 
 			page = pfn_swap_entry_to_page(entry);
+			pgmap = page_pgmap(page);
 			if (!(migrate->flags &
 				MIGRATE_VMA_SELECT_DEVICE_PRIVATE) ||
-			    page->pgmap->owner != migrate->pgmap_owner)
+			    pgmap->owner != migrate->pgmap_owner)
 				goto next;
 
 			mpfn = migrate_pfn(page_to_pfn(page)) |
@@ -151,12 +153,13 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
 				goto next;
 			}
 			page = vm_normal_page(migrate->vma, addr, pte);
+			pgmap = page_pgmap(page);
 			if (page && !is_zone_device_page(page) &&
 			    !(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM))
 				goto next;
 			else if (page && is_device_coherent_page(page) &&
 			    (!(migrate->flags & MIGRATE_VMA_SELECT_DEVICE_COHERENT) ||
-			     page->pgmap->owner != migrate->pgmap_owner))
+			     pgmap->owner != migrate->pgmap_owner))
 				goto next;
 			mpfn = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
 			mpfn |= pte_write(pte) ? MIGRATE_PFN_WRITE : 0;
diff --git a/mm/mm_init.c b/mm/mm_init.c
index f021e63..cb73402 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -998,7 +998,7 @@ static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,
 	 * and zone_device_data.  It is a bug if a ZONE_DEVICE page is
 	 * ever freed or placed on a driver-private list.
 	 */
-	page->pgmap = pgmap;
+	page_folio(page)->pgmap = pgmap;
 	page->zone_device_data = NULL;
 
 	/*
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:55 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:55 +1100
Subject: [PATCH v4 12/25] mm/memory: Enhance insert_page_into_pte_locked() to create writable mappings
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <25a23433cb70f0fe6af92042eb71e962fcbf092b.1734407924.git-series.apopple@nvidia.com>

In preparation for using insert_page() for DAX, enhance
insert_page_into_pte_locked() to handle establishing writable
mappings.  Recall that DAX returns VM_FAULT_NOPAGE after installing a
PTE which bypasses the typical set_pte_range() in finish_fault.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Suggested-by: Dan Williams <dan.j.williams at intel.com>

---

Changes since v2:

 - New patch split out from "mm/memory: Add dax_insert_pfn"
---
 mm/memory.c | 45 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 8 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 06bb29e..cd82952 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2126,19 +2126,47 @@ static int validate_page_before_insert(struct vm_area_struct *vma,
 }
 
 static int insert_page_into_pte_locked(struct vm_area_struct *vma, pte_t *pte,
-			unsigned long addr, struct page *page, pgprot_t prot)
+				unsigned long addr, struct page *page,
+				pgprot_t prot, bool mkwrite)
 {
 	struct folio *folio = page_folio(page);
+	pte_t entry = ptep_get(pte);
 	pte_t pteval;
 
-	if (!pte_none(ptep_get(pte)))
-		return -EBUSY;
+	if (!pte_none(entry)) {
+		if (!mkwrite)
+			return -EBUSY;
+
+		/*
+		 * For read faults on private mappings the PFN passed in may not
+		 * match the PFN we have mapped if the mapped PFN is a writeable
+		 * COW page.  In the mkwrite case we are creating a writable PTE
+		 * for a shared mapping and we expect the PFNs to match. If they
+		 * don't match, we are likely racing with block allocation and
+		 * mapping invalidation so just skip the update.
+		 */
+		if (pte_pfn(entry) != page_to_pfn(page)) {
+			WARN_ON_ONCE(!is_zero_pfn(pte_pfn(entry)));
+			return -EFAULT;
+		}
+		entry = maybe_mkwrite(entry, vma);
+		entry = pte_mkyoung(entry);
+		if (ptep_set_access_flags(vma, addr, pte, entry, 1))
+			update_mmu_cache(vma, addr, pte);
+		return 0;
+	}
+
 	/* Ok, finally just insert the thing.. */
 	pteval = mk_pte(page, prot);
 	if (unlikely(is_zero_folio(folio))) {
 		pteval = pte_mkspecial(pteval);
 	} else {
 		folio_get(folio);
+		entry = mk_pte(page, prot);
+		if (mkwrite) {
+			entry = pte_mkyoung(entry);
+			entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+		}
 		inc_mm_counter(vma->vm_mm, mm_counter_file(folio));
 		folio_add_file_rmap_pte(folio, page, vma);
 	}
@@ -2147,7 +2175,7 @@ static int insert_page_into_pte_locked(struct vm_area_struct *vma, pte_t *pte,
 }
 
 static int insert_page(struct vm_area_struct *vma, unsigned long addr,
-			struct page *page, pgprot_t prot)
+			struct page *page, pgprot_t prot, bool mkwrite)
 {
 	int retval;
 	pte_t *pte;
@@ -2160,7 +2188,8 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,
 	pte = get_locked_pte(vma->vm_mm, addr, &ptl);
 	if (!pte)
 		goto out;
-	retval = insert_page_into_pte_locked(vma, pte, addr, page, prot);
+	retval = insert_page_into_pte_locked(vma, pte, addr, page, prot,
+					mkwrite);
 	pte_unmap_unlock(pte, ptl);
 out:
 	return retval;
@@ -2174,7 +2203,7 @@ static int insert_page_in_batch_locked(struct vm_area_struct *vma, pte_t *pte,
 	err = validate_page_before_insert(vma, page);
 	if (err)
 		return err;
-	return insert_page_into_pte_locked(vma, pte, addr, page, prot);
+	return insert_page_into_pte_locked(vma, pte, addr, page, prot, false);
 }
 
 /* insert_pages() amortizes the cost of spinlock operations
@@ -2310,7 +2339,7 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
 		BUG_ON(vma->vm_flags & VM_PFNMAP);
 		vm_flags_set(vma, VM_MIXEDMAP);
 	}
-	return insert_page(vma, addr, page, vma->vm_page_prot);
+	return insert_page(vma, addr, page, vma->vm_page_prot, false);
 }
 EXPORT_SYMBOL(vm_insert_page);
 
@@ -2590,7 +2619,7 @@ static vm_fault_t __vm_insert_mixed(struct vm_area_struct *vma,
 		 * result in pfn_t_has_page() == false.
 		 */
 		page = pfn_to_page(pfn_t_to_pfn(pfn));
-		err = insert_page(vma, addr, page, pgprot);
+		err = insert_page(vma, addr, page, pgprot, mkwrite);
 	} else {
 		return insert_pfn(vma, addr, pfn, pgprot, mkwrite);
 	}
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:56 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:56 +1100
Subject: [PATCH v4 13/25] mm/memory: Add vmf_insert_page_mkwrite()
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <e55ea5e8aa44946b09030fc4a164d2735c305327.1734407924.git-series.apopple@nvidia.com>

Currently to map a DAX page the DAX driver calls vmf_insert_pfn. This
creates a special devmap PTE entry for the pfn but does not take a
reference on the underlying struct page for the mapping. This is
because DAX page refcounts are treated specially, as indicated by the
presence of a devmap entry.

To allow DAX page refcounts to be managed the same as normal page
refcounts introduce vmf_insert_page_mkwrite(). This will take a
reference on the underlying page much the same as vmf_insert_page,
except it also permits upgrading an existing mapping to be writable if
requested/possible.

Signed-off-by: Alistair Popple <apopple at nvidia.com>

---

Updates from v2:

 - Rename function to make not DAX specific

 - Split the insert_page_into_pte_locked() change into a separate
   patch.

Updates from v1:

 - Re-arrange code in insert_page_into_pte_locked() based on comments
   from Jan Kara.

 - Call mkdrity/mkyoung for the mkwrite case, also suggested by Jan.
---
 include/linux/mm.h |  2 ++
 mm/memory.c        | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index e790298..f267b06 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3620,6 +3620,8 @@ int vm_map_pages(struct vm_area_struct *vma, struct page **pages,
 				unsigned long num);
 int vm_map_pages_zero(struct vm_area_struct *vma, struct page **pages,
 				unsigned long num);
+vm_fault_t vmf_insert_page_mkwrite(struct vm_fault *vmf, struct page *page,
+			bool write);
 vm_fault_t vmf_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
 			unsigned long pfn);
 vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr,
diff --git a/mm/memory.c b/mm/memory.c
index cd82952..4f73454 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2632,6 +2632,42 @@ static vm_fault_t __vm_insert_mixed(struct vm_area_struct *vma,
 	return VM_FAULT_NOPAGE;
 }
 
+vm_fault_t vmf_insert_page_mkwrite(struct vm_fault *vmf, struct page *page,
+			bool write)
+{
+	struct vm_area_struct *vma = vmf->vma;
+	pgprot_t pgprot = vma->vm_page_prot;
+	unsigned long pfn = page_to_pfn(page);
+	unsigned long addr = vmf->address;
+	int err;
+
+	if (addr < vma->vm_start || addr >= vma->vm_end)
+		return VM_FAULT_SIGBUS;
+
+	track_pfn_insert(vma, &pgprot, pfn_to_pfn_t(pfn));
+
+	if (!pfn_modify_allowed(pfn, pgprot))
+		return VM_FAULT_SIGBUS;
+
+	/*
+	 * We refcount the page normally so make sure pfn_valid is true.
+	 */
+	if (!pfn_valid(pfn))
+		return VM_FAULT_SIGBUS;
+
+	if (WARN_ON(is_zero_pfn(pfn) && write))
+		return VM_FAULT_SIGBUS;
+
+	err = insert_page(vma, addr, page, pgprot, write);
+	if (err == -ENOMEM)
+		return VM_FAULT_OOM;
+	if (err < 0 && err != -EBUSY)
+		return VM_FAULT_SIGBUS;
+
+	return VM_FAULT_NOPAGE;
+}
+EXPORT_SYMBOL_GPL(vmf_insert_page_mkwrite);
+
 vm_fault_t vmf_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
 		pfn_t pfn)
 {
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:57 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:57 +1100
Subject: [PATCH v4 14/25] rmap: Add support for PUD sized mappings to rmap
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <7f739c9e9f0a25cafb76a482e31e632c8f72102e.1734407924.git-series.apopple@nvidia.com>

The rmap doesn't currently support adding a PUD mapping of a
folio. This patch adds support for entire PUD mappings of folios,
primarily to allow for more standard refcounting of device DAX
folios. Currently DAX is the only user of this and it doesn't require
support for partially mapped PUD-sized folios so we don't support for
that for now.

Signed-off-by: Alistair Popple <apopple at nvidia.com>

---

David - Thanks for your previous comments, I'm less familiar with the
rmap code so I would appreciate you taking another look. In particular
I haven't added a stat for PUD mapped folios as it seemed like
overkill for just the device DAX case but let me know if you think
otherwise.

Changes for v4:

 - New for v4, split out rmap changes as suggested by David.
---
 include/linux/rmap.h | 15 ++++++++++++-
 mm/rmap.c            | 56 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 71 insertions(+)

diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 683a040..7043914 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -192,6 +192,7 @@ typedef int __bitwise rmap_t;
 enum rmap_level {
 	RMAP_LEVEL_PTE = 0,
 	RMAP_LEVEL_PMD,
+	RMAP_LEVEL_PUD,
 };
 
 static inline void __folio_rmap_sanity_checks(const struct folio *folio,
@@ -228,6 +229,14 @@ static inline void __folio_rmap_sanity_checks(const struct folio *folio,
 		VM_WARN_ON_FOLIO(folio_nr_pages(folio) != HPAGE_PMD_NR, folio);
 		VM_WARN_ON_FOLIO(nr_pages != HPAGE_PMD_NR, folio);
 		break;
+	case RMAP_LEVEL_PUD:
+		/*
+		 * Assume that we are creating * a single "entire" mapping of the
+		 * folio.
+		 */
+		VM_WARN_ON_FOLIO(folio_nr_pages(folio) != HPAGE_PUD_NR, folio);
+		VM_WARN_ON_FOLIO(nr_pages != HPAGE_PUD_NR, folio);
+		break;
 	default:
 		VM_WARN_ON_ONCE(true);
 	}
@@ -251,12 +260,16 @@ void folio_add_file_rmap_ptes(struct folio *, struct page *, int nr_pages,
 	folio_add_file_rmap_ptes(folio, page, 1, vma)
 void folio_add_file_rmap_pmd(struct folio *, struct page *,
 		struct vm_area_struct *);
+void folio_add_file_rmap_pud(struct folio *, struct page *,
+		struct vm_area_struct *);
 void folio_remove_rmap_ptes(struct folio *, struct page *, int nr_pages,
 		struct vm_area_struct *);
 #define folio_remove_rmap_pte(folio, page, vma) \
 	folio_remove_rmap_ptes(folio, page, 1, vma)
 void folio_remove_rmap_pmd(struct folio *, struct page *,
 		struct vm_area_struct *);
+void folio_remove_rmap_pud(struct folio *, struct page *,
+		struct vm_area_struct *);
 
 void hugetlb_add_anon_rmap(struct folio *, struct vm_area_struct *,
 		unsigned long address, rmap_t flags);
@@ -341,6 +354,7 @@ static __always_inline void __folio_dup_file_rmap(struct folio *folio,
 		atomic_add(orig_nr_pages, &folio->_large_mapcount);
 		break;
 	case RMAP_LEVEL_PMD:
+	case RMAP_LEVEL_PUD:
 		atomic_inc(&folio->_entire_mapcount);
 		atomic_inc(&folio->_large_mapcount);
 		break;
@@ -437,6 +451,7 @@ static __always_inline int __folio_try_dup_anon_rmap(struct folio *folio,
 		atomic_add(orig_nr_pages, &folio->_large_mapcount);
 		break;
 	case RMAP_LEVEL_PMD:
+	case RMAP_LEVEL_PUD:
 		if (PageAnonExclusive(page)) {
 			if (unlikely(maybe_pinned))
 				return -EBUSY;
diff --git a/mm/rmap.c b/mm/rmap.c
index c6c4d4e..39d0439 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1203,6 +1203,11 @@ static __always_inline unsigned int __folio_add_rmap(struct folio *folio,
 		}
 		atomic_inc(&folio->_large_mapcount);
 		break;
+	case RMAP_LEVEL_PUD:
+		/* We only support entire mappings of PUD sized folios in rmap */
+		atomic_inc(&folio->_entire_mapcount);
+		atomic_inc(&folio->_large_mapcount);
+		break;
 	}
 	return nr;
 }
@@ -1338,6 +1343,13 @@ static __always_inline void __folio_add_anon_rmap(struct folio *folio,
 		case RMAP_LEVEL_PMD:
 			SetPageAnonExclusive(page);
 			break;
+		case RMAP_LEVEL_PUD:
+			/*
+			 * Keep the compiler happy, we don't support anonymous
+			 * PUD mappings.
+			 */
+			WARN_ON_ONCE(1);
+			break;
 		}
 	}
 	for (i = 0; i < nr_pages; i++) {
@@ -1531,6 +1543,26 @@ void folio_add_file_rmap_pmd(struct folio *folio, struct page *page,
 #endif
 }
 
+/**
+ * folio_add_file_rmap_pud - add a PUD mapping to a page range of a folio
+ * @folio:	The folio to add the mapping to
+ * @page:	The first page to add
+ * @vma:	The vm area in which the mapping is added
+ *
+ * The page range of the folio is defined by [page, page + HPAGE_PUD_NR)
+ *
+ * The caller needs to hold the page table lock.
+ */
+void folio_add_file_rmap_pud(struct folio *folio, struct page *page,
+		struct vm_area_struct *vma)
+{
+#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
+	__folio_add_file_rmap(folio, page, HPAGE_PUD_NR, vma, RMAP_LEVEL_PUD);
+#else
+	WARN_ON_ONCE(true);
+#endif
+}
+
 static __always_inline void __folio_remove_rmap(struct folio *folio,
 		struct page *page, int nr_pages, struct vm_area_struct *vma,
 		enum rmap_level level)
@@ -1578,6 +1610,10 @@ static __always_inline void __folio_remove_rmap(struct folio *folio,
 
 		partially_mapped = nr && nr < nr_pmdmapped;
 		break;
+	case RMAP_LEVEL_PUD:
+		atomic_dec(&folio->_large_mapcount);
+		atomic_dec(&folio->_entire_mapcount);
+		break;
 	}
 
 	/*
@@ -1640,6 +1676,26 @@ void folio_remove_rmap_pmd(struct folio *folio, struct page *page,
 #endif
 }
 
+/**
+ * folio_remove_rmap_pud - remove a PUD mapping from a page range of a folio
+ * @folio:	The folio to remove the mapping from
+ * @page:	The first page to remove
+ * @vma:	The vm area from which the mapping is removed
+ *
+ * The page range of the folio is defined by [page, page + HPAGE_PUD_NR)
+ *
+ * The caller needs to hold the page table lock.
+ */
+void folio_remove_rmap_pud(struct folio *folio, struct page *page,
+		struct vm_area_struct *vma)
+{
+#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
+	__folio_remove_rmap(folio, page, HPAGE_PUD_NR, vma, RMAP_LEVEL_PUD);
+#else
+	WARN_ON_ONCE(true);
+#endif
+}
+
 /*
  * @arg: enum ttu_flags will be passed to this argument
  */
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:58 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:58 +1100
Subject: [PATCH v4 15/25] huge_memory: Add vmf_insert_folio_pud()
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <03cb3c24f10818c0780a08509628893ab460e5d1.1734407924.git-series.apopple@nvidia.com>

Currently DAX folio/page reference counts are managed differently to
normal pages. To allow these to be managed the same as normal pages
introduce vmf_insert_folio_pud. This will map the entire PUD-sized folio
and take references as it would for a normally mapped page.

This is distinct from the current mechanism, vmf_insert_pfn_pud, which
simply inserts a special devmap PUD entry into the page table without
holding a reference to the page for the mapping.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 include/linux/huge_mm.h | 11 +++++-
 mm/huge_memory.c        | 96 ++++++++++++++++++++++++++++++++++++------
 2 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 93e509b..012137b 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -39,6 +39,7 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
 
 vm_fault_t vmf_insert_pfn_pmd(struct vm_fault *vmf, pfn_t pfn, bool write);
 vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write);
+vm_fault_t vmf_insert_folio_pud(struct vm_fault *vmf, struct folio *folio, bool write);
 
 enum transparent_hugepage_flag {
 	TRANSPARENT_HUGEPAGE_UNSUPPORTED,
@@ -458,6 +459,11 @@ static inline bool is_huge_zero_pmd(pmd_t pmd)
 	return pmd_present(pmd) && READ_ONCE(huge_zero_pfn) == pmd_pfn(pmd);
 }
 
+static inline bool is_huge_zero_pud(pud_t pud)
+{
+	return false;
+}
+
 struct folio *mm_get_huge_zero_folio(struct mm_struct *mm);
 void mm_put_huge_zero_folio(struct mm_struct *mm);
 
@@ -604,6 +610,11 @@ static inline bool is_huge_zero_pmd(pmd_t pmd)
 	return false;
 }
 
+static inline bool is_huge_zero_pud(pud_t pud)
+{
+	return false;
+}
+
 static inline void mm_put_huge_zero_folio(struct mm_struct *mm)
 {
 	return;
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 120cd2c..5081808 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1482,19 +1482,17 @@ static void insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
 	struct mm_struct *mm = vma->vm_mm;
 	pgprot_t prot = vma->vm_page_prot;
 	pud_t entry;
-	spinlock_t *ptl;
 
-	ptl = pud_lock(mm, pud);
 	if (!pud_none(*pud)) {
 		if (write) {
 			if (WARN_ON_ONCE(pud_pfn(*pud) != pfn_t_to_pfn(pfn)))
-				goto out_unlock;
+				return;
 			entry = pud_mkyoung(*pud);
 			entry = maybe_pud_mkwrite(pud_mkdirty(entry), vma);
 			if (pudp_set_access_flags(vma, addr, pud, entry, 1))
 				update_mmu_cache_pud(vma, addr, pud);
 		}
-		goto out_unlock;
+		return;
 	}
 
 	entry = pud_mkhuge(pfn_t_pud(pfn, prot));
@@ -1508,9 +1506,6 @@ static void insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
 	}
 	set_pud_at(mm, addr, pud, entry);
 	update_mmu_cache_pud(vma, addr, pud);
-
-out_unlock:
-	spin_unlock(ptl);
 }
 
 /**
@@ -1528,6 +1523,7 @@ vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write)
 	unsigned long addr = vmf->address & PUD_MASK;
 	struct vm_area_struct *vma = vmf->vma;
 	pgprot_t pgprot = vma->vm_page_prot;
+	spinlock_t *ptl;
 
 	/*
 	 * If we had pud_special, we could avoid all these restrictions,
@@ -1545,10 +1541,55 @@ vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write)
 
 	track_pfn_insert(vma, &pgprot, pfn);
 
+	ptl = pud_lock(vma->vm_mm, vmf->pud);
 	insert_pfn_pud(vma, addr, vmf->pud, pfn, write);
+	spin_unlock(ptl);
+
 	return VM_FAULT_NOPAGE;
 }
 EXPORT_SYMBOL_GPL(vmf_insert_pfn_pud);
+
+/**
+ * vmf_insert_folio_pud - insert a pud size folio mapped by a pud entry
+ * @vmf: Structure describing the fault
+ * @pfn: pfn of the page to insert
+ * @write: whether it's a write fault
+ *
+ * Return: vm_fault_t value.
+ */
+vm_fault_t vmf_insert_folio_pud(struct vm_fault *vmf, struct folio *folio, bool write)
+{
+	struct vm_area_struct *vma = vmf->vma;
+	unsigned long addr = vmf->address & PUD_MASK;
+	pfn_t pfn = pfn_to_pfn_t(folio_pfn(folio));
+	pud_t *pud = vmf->pud;
+	pgprot_t prot = vma->vm_page_prot;
+	struct mm_struct *mm = vma->vm_mm;
+	spinlock_t *ptl;
+	struct page *page;
+
+	if (addr < vma->vm_start || addr >= vma->vm_end)
+		return VM_FAULT_SIGBUS;
+
+	if (WARN_ON_ONCE(folio_order(folio) != PUD_ORDER))
+		return VM_FAULT_SIGBUS;
+
+	track_pfn_insert(vma, &prot, pfn);
+
+	ptl = pud_lock(mm, pud);
+	if (pud_none(*vmf->pud)) {
+		page = pfn_t_to_page(pfn);
+		folio = page_folio(page);
+		folio_get(folio);
+		folio_add_file_rmap_pud(folio, page, vma);
+		add_mm_counter(mm, mm_counter_file(folio), HPAGE_PUD_NR);
+	}
+	insert_pfn_pud(vma, addr, vmf->pud, pfn, write);
+	spin_unlock(ptl);
+
+	return VM_FAULT_NOPAGE;
+}
+EXPORT_SYMBOL_GPL(vmf_insert_folio_pud);
 #endif /* CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
 
 void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
@@ -2146,7 +2187,8 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
 			zap_deposited_table(tlb->mm, pmd);
 		spin_unlock(ptl);
 	} else if (is_huge_zero_pmd(orig_pmd)) {
-		zap_deposited_table(tlb->mm, pmd);
+		if (!vma_is_dax(vma) || arch_needs_pgtable_deposit())
+			zap_deposited_table(tlb->mm, pmd);
 		spin_unlock(ptl);
 	} else {
 		struct folio *folio = NULL;
@@ -2634,12 +2676,24 @@ int zap_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	orig_pud = pudp_huge_get_and_clear_full(vma, addr, pud, tlb->fullmm);
 	arch_check_zapped_pud(vma, orig_pud);
 	tlb_remove_pud_tlb_entry(tlb, pud, addr);
-	if (vma_is_special_huge(vma)) {
+	if (!vma_is_dax(vma) && vma_is_special_huge(vma)) {
 		spin_unlock(ptl);
 		/* No zero page support yet */
 	} else {
-		/* No support for anonymous PUD pages yet */
-		BUG();
+		struct page *page = NULL;
+		struct folio *folio;
+
+		/* No support for anonymous PUD pages or migration yet */
+		BUG_ON(vma_is_anonymous(vma) || !pud_present(orig_pud));
+
+		page = pud_page(orig_pud);
+		folio = page_folio(page);
+		folio_remove_rmap_pud(folio, page, vma);
+		VM_BUG_ON_PAGE(!PageHead(page), page);
+		add_mm_counter(tlb->mm, mm_counter_file(folio), -HPAGE_PUD_NR);
+
+		spin_unlock(ptl);
+		tlb_remove_page_size(tlb, page, HPAGE_PUD_SIZE);
 	}
 	return 1;
 }
@@ -2647,6 +2701,8 @@ int zap_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma,
 static void __split_huge_pud_locked(struct vm_area_struct *vma, pud_t *pud,
 		unsigned long haddr)
 {
+	pud_t old_pud;
+
 	VM_BUG_ON(haddr & ~HPAGE_PUD_MASK);
 	VM_BUG_ON_VMA(vma->vm_start > haddr, vma);
 	VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PUD_SIZE, vma);
@@ -2654,7 +2710,23 @@ static void __split_huge_pud_locked(struct vm_area_struct *vma, pud_t *pud,
 
 	count_vm_event(THP_SPLIT_PUD);
 
-	pudp_huge_clear_flush(vma, haddr, pud);
+	old_pud = pudp_huge_clear_flush(vma, haddr, pud);
+	if (is_huge_zero_pud(old_pud))
+		return;
+
+	if (vma_is_dax(vma)) {
+		struct page *page = pud_page(old_pud);
+		struct folio *folio = page_folio(page);
+
+		if (!folio_test_dirty(folio) && pud_dirty(old_pud))
+			folio_mark_dirty(folio);
+		if (!folio_test_referenced(folio) && pud_young(old_pud))
+			folio_set_referenced(folio);
+		folio_remove_rmap_pud(folio, page, vma);
+		folio_put(folio);
+		add_mm_counter(vma->vm_mm, mm_counter_file(folio),
+			-HPAGE_PUD_NR);
+	}
 }
 
 void __split_huge_pud(struct vm_area_struct *vma, pud_t *pud,
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:59 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:59 +1100
Subject: [PATCH v4 16/25] huge_memory: Add vmf_insert_folio_pmd()
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <b1c1e92f29094d6d5b78c6f87dc8ac81a9cbd7aa.1734407924.git-series.apopple@nvidia.com>

Currently DAX folio/page reference counts are managed differently to
normal pages. To allow these to be managed the same as normal pages
introduce vmf_insert_folio_pmd. This will map the entire PMD-sized folio
and take references as it would for a normally mapped page.

This is distinct from the current mechanism, vmf_insert_pfn_pmd, which
simply inserts a special devmap PMD entry into the page table without
holding a reference to the page for the mapping.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 include/linux/huge_mm.h |  1 +-
 mm/huge_memory.c        | 60 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 012137b..4ad9aa7 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -39,6 +39,7 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
 
 vm_fault_t vmf_insert_pfn_pmd(struct vm_fault *vmf, pfn_t pfn, bool write);
 vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write);
+vm_fault_t vmf_insert_folio_pmd(struct vm_fault *vmf, struct folio *folio, bool write);
 vm_fault_t vmf_insert_folio_pud(struct vm_fault *vmf, struct folio *folio, bool write);
 
 enum transparent_hugepage_flag {
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 5081808..55293b0 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1381,14 +1381,12 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
 {
 	struct mm_struct *mm = vma->vm_mm;
 	pmd_t entry;
-	spinlock_t *ptl;
 
-	ptl = pmd_lock(mm, pmd);
 	if (!pmd_none(*pmd)) {
 		if (write) {
 			if (pmd_pfn(*pmd) != pfn_t_to_pfn(pfn)) {
 				WARN_ON_ONCE(!is_huge_zero_pmd(*pmd));
-				goto out_unlock;
+				return;
 			}
 			entry = pmd_mkyoung(*pmd);
 			entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
@@ -1396,7 +1394,7 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
 				update_mmu_cache_pmd(vma, addr, pmd);
 		}
 
-		goto out_unlock;
+		return;
 	}
 
 	entry = pmd_mkhuge(pfn_t_pmd(pfn, prot));
@@ -1417,11 +1415,6 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
 
 	set_pmd_at(mm, addr, pmd, entry);
 	update_mmu_cache_pmd(vma, addr, pmd);
-
-out_unlock:
-	spin_unlock(ptl);
-	if (pgtable)
-		pte_free(mm, pgtable);
 }
 
 /**
@@ -1440,6 +1433,7 @@ vm_fault_t vmf_insert_pfn_pmd(struct vm_fault *vmf, pfn_t pfn, bool write)
 	struct vm_area_struct *vma = vmf->vma;
 	pgprot_t pgprot = vma->vm_page_prot;
 	pgtable_t pgtable = NULL;
+	spinlock_t *ptl;
 
 	/*
 	 * If we had pmd_special, we could avoid all these restrictions,
@@ -1462,12 +1456,58 @@ vm_fault_t vmf_insert_pfn_pmd(struct vm_fault *vmf, pfn_t pfn, bool write)
 	}
 
 	track_pfn_insert(vma, &pgprot, pfn);
-
+	ptl = pmd_lock(vma->vm_mm, vmf->pmd);
 	insert_pfn_pmd(vma, addr, vmf->pmd, pfn, pgprot, write, pgtable);
+	spin_unlock(ptl);
+	if (pgtable)
+		pte_free(vma->vm_mm, pgtable);
+
 	return VM_FAULT_NOPAGE;
 }
 EXPORT_SYMBOL_GPL(vmf_insert_pfn_pmd);
 
+vm_fault_t vmf_insert_folio_pmd(struct vm_fault *vmf, struct folio *folio, bool write)
+{
+	struct vm_area_struct *vma = vmf->vma;
+	unsigned long addr = vmf->address & PMD_MASK;
+	pfn_t pfn = pfn_to_pfn_t(folio_pfn(folio));
+	struct mm_struct *mm = vma->vm_mm;
+	spinlock_t *ptl;
+	pgtable_t pgtable = NULL;
+	struct page *page;
+
+	if (addr < vma->vm_start || addr >= vma->vm_end)
+		return VM_FAULT_SIGBUS;
+
+	if (WARN_ON_ONCE(folio_order(folio) != PMD_ORDER))
+		return VM_FAULT_SIGBUS;
+
+	if (arch_needs_pgtable_deposit()) {
+		pgtable = pte_alloc_one(vma->vm_mm);
+		if (!pgtable)
+			return VM_FAULT_OOM;
+	}
+
+	track_pfn_insert(vma, &vma->vm_page_prot, pfn);
+
+	ptl = pmd_lock(mm, vmf->pmd);
+	if (pmd_none(*vmf->pmd)) {
+		page = pfn_t_to_page(pfn);
+		folio = page_folio(page);
+		folio_get(folio);
+		folio_add_file_rmap_pmd(folio, page, vma);
+		add_mm_counter(mm, mm_counter_file(folio), HPAGE_PMD_NR);
+	}
+	insert_pfn_pmd(vma, addr, vmf->pmd, pfn, vma->vm_page_prot,
+		write, pgtable);
+	spin_unlock(ptl);
+	if (pgtable)
+		pte_free(mm, pgtable);
+
+	return VM_FAULT_NOPAGE;
+}
+EXPORT_SYMBOL_GPL(vmf_insert_folio_pmd);
+
 #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
 static pud_t maybe_pud_mkwrite(pud_t pud, struct vm_area_struct *vma)
 {
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:13:00 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:13:00 +1100
Subject: [PATCH v4 17/25] memremap: Add is_device_dax_page() and is_fsdax_page() helpers
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <58ea909bd178d97bcc73997d6499880137d5e4ed.1734407924.git-series.apopple@nvidia.com>

Add helpers to determine if a page or folio is a device dax or fs dax
page or folio.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 include/linux/memremap.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 0256a42..f2a8d13 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -187,6 +187,28 @@ static inline bool folio_is_device_coherent(const struct folio *folio)
 	return is_device_coherent_page(&folio->page);
 }
 
+static inline bool is_fsdax_page(const struct page *page)
+{
+	return is_zone_device_page(page) &&
+		page_pgmap(page)->type == MEMORY_DEVICE_FS_DAX;
+}
+
+static inline bool folio_is_fsdax(const struct folio *folio)
+{
+	return is_fsdax_page(&folio->page);
+}
+
+static inline bool is_device_dax_page(const struct page *page)
+{
+	return is_zone_device_page(page) &&
+		page_pgmap(page)->type == MEMORY_DEVICE_GENERIC;
+}
+
+static inline bool folio_is_device_dax(const struct folio *folio)
+{
+	return is_device_dax_page(&folio->page);
+}
+
 #ifdef CONFIG_ZONE_DEVICE
 void zone_device_page_init(struct page *page);
 void *memremap_pages(struct dev_pagemap *pgmap, int nid);
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:13:01 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:13:01 +1100
Subject: [PATCH v4 18/25] gup: Don't allow FOLL_LONGTERM pinning of FS DAX pages
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <f315b61169d0671301e4a793ecbb1a6c46b69bef.1734407924.git-series.apopple@nvidia.com>

Longterm pinning of FS DAX pages should already be disallowed by
various pXX_devmap checks. However a future change will cause these
checks to be invalid for FS DAX pages so make
folio_is_longterm_pinnable() return false for FS DAX pages.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Reviewed-by: John Hubbard <jhubbard at nvidia.com>
---
 include/linux/mm.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f267b06..01edca9 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2078,6 +2078,10 @@ static inline bool folio_is_longterm_pinnable(struct folio *folio)
 	if (folio_is_device_coherent(folio))
 		return false;
 
+	/* DAX must also always allow eviction. */
+	if (folio_is_fsdax(folio))
+		return false;
+
 	/* Otherwise, non-movable zone folios can be pinned. */
 	return !folio_is_zone_movable(folio);
 
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:13:02 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:13:02 +1100
Subject: [PATCH v4 19/25] proc/task_mmu: Ignore ZONE_DEVICE pages
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <f3ebda542373feb70ed3e5d83b276a2e8347609f.1734407924.git-series.apopple@nvidia.com>

The procfs mmu files such as smaps currently ignore device dax and fs
dax pages because these pages are considered special. To maintain
existing behaviour once these pages are treated as normal pages and
returned from vm_normal_page() add tests to explicitly skip them.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 fs/proc/task_mmu.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 38a5a3e..c9b227a 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -801,6 +801,8 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
 
 	if (pte_present(ptent)) {
 		page = vm_normal_page(vma, addr, ptent);
+		if (page && (is_device_dax_page(page) || is_fsdax_page(page)))
+			page = NULL;
 		young = pte_young(ptent);
 		dirty = pte_dirty(ptent);
 		present = true;
@@ -849,6 +851,8 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
 
 	if (pmd_present(*pmd)) {
 		page = vm_normal_page_pmd(vma, addr, *pmd);
+		if (page && (is_device_dax_page(page) || is_fsdax_page(page)))
+			page = NULL;
 		present = true;
 	} else if (unlikely(thp_migration_supported() && is_swap_pmd(*pmd))) {
 		swp_entry_t entry = pmd_to_swp_entry(*pmd);
@@ -1378,7 +1382,7 @@ static inline bool pte_is_pinned(struct vm_area_struct *vma, unsigned long addr,
 	if (likely(!test_bit(MMF_HAS_PINNED, &vma->vm_mm->flags)))
 		return false;
 	folio = vm_normal_folio(vma, addr, pte);
-	if (!folio)
+	if (!folio || folio_is_device_dax(folio) || folio_is_fsdax(folio))
 		return false;
 	return folio_maybe_dma_pinned(folio);
 }
@@ -1703,6 +1707,8 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm,
 			frame = pte_pfn(pte);
 		flags |= PM_PRESENT;
 		page = vm_normal_page(vma, addr, pte);
+		if (page && (is_device_dax_page(page) || is_fsdax_page(page)))
+			page = NULL;
 		if (pte_soft_dirty(pte))
 			flags |= PM_SOFT_DIRTY;
 		if (pte_uffd_wp(pte))
@@ -2089,7 +2095,9 @@ static unsigned long pagemap_page_category(struct pagemap_scan_private *p,
 
 		if (p->masks_of_interest & PAGE_IS_FILE) {
 			page = vm_normal_page(vma, addr, pte);
-			if (page && !PageAnon(page))
+			if (page && !PageAnon(page) &&
+			    !is_device_dax_page(page) &&
+			    !is_fsdax_page(page))
 				categories |= PAGE_IS_FILE;
 		}
 
@@ -2151,7 +2159,9 @@ static unsigned long pagemap_thp_category(struct pagemap_scan_private *p,
 
 		if (p->masks_of_interest & PAGE_IS_FILE) {
 			page = vm_normal_page_pmd(vma, addr, pmd);
-			if (page && !PageAnon(page))
+			if (page && !PageAnon(page) &&
+			    !is_device_dax_page(page) &&
+			    !is_fsdax_page(page))
 				categories |= PAGE_IS_FILE;
 		}
 
@@ -2914,7 +2924,7 @@ static struct page *can_gather_numa_stats_pmd(pmd_t pmd,
 		return NULL;
 
 	page = vm_normal_page_pmd(vma, addr, pmd);
-	if (!page)
+	if (!page || is_device_dax_page(page) || is_fsdax_page(page))
 		return NULL;
 
 	if (PageReserved(page))
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:13:03 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:13:03 +1100
Subject: [PATCH v4 20/25] mm/mlock: Skip ZONE_DEVICE PMDs during mlock
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <e1fe10474fc06aaf24b17fcd916efffcc8c13f78.1734407924.git-series.apopple@nvidia.com>

At present mlock skips ptes mapping ZONE_DEVICE pages. A future change
to remove pmd_devmap will allow pmd_trans_huge_lock() to return
ZONE_DEVICE folios so make sure we continue to skip those.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 mm/mlock.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/mlock.c b/mm/mlock.c
index cde076f..3cb72b5 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -368,6 +368,8 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
 		if (is_huge_zero_pmd(*pmd))
 			goto out;
 		folio = pmd_folio(*pmd);
+		if (folio_is_zone_device(folio))
+			goto out;
 		if (vma->vm_flags & VM_LOCKED)
 			mlock_folio(folio);
 		else
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:13:04 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:13:04 +1100
Subject: [PATCH v4 21/25] fs/dax: Properly refcount fs dax pages
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <cf03be2d827737240c10de615023ff913870bec6.1734407924.git-series.apopple@nvidia.com>

Currently fs dax pages are considered free when the refcount drops to
one and their refcounts are not increased when mapped via PTEs or
decreased when unmapped. This requires special logic in mm paths to
detect that these pages should not be properly refcounted, and to
detect when the refcount drops to one instead of zero.

On the other hand get_user_pages(), etc. will properly refcount fs dax
pages by taking a reference and dropping it when the page is
unpinned.

Tracking this special behaviour requires extra PTE bits
(eg. pte_devmap) and introduces rules that are potentially confusing
and specific to FS DAX pages. To fix this, and to possibly allow
removal of the special PTE bits in future, convert the fs dax page
refcounts to be zero based and instead take a reference on the page
each time it is mapped as is currently the case for normal pages.

This may also allow a future clean-up to remove the pgmap refcounting
that is currently done in mm/gup.c.

Signed-off-by: Alistair Popple <apopple at nvidia.com>

---

Changes since v2:

Based on some questions from Dan I attempted to have the FS DAX page
cache (ie. address space) hold a reference to the folio whilst it was
mapped. However I came to the strong conclusion that this was not the
right thing to do.

If the page refcount == 0 it means the page is:

1. not mapped into user-space
2. not subject to other access via DMA/GUP/etc.

Ie. From the core MM perspective the page is not in use.

The fact a page may or may not be present in one or more address space
mappings is irrelevant for core MM. It just means the page is still in
use or valid from the file system perspective, and it's a
responsiblity of the file system to remove these mappings if the pfn
mapping becomes invalid (along with first making sure the MM state,
ie. page->refcount, is idle). So we shouldn't be trying to track that
lifetime with MM refcounts.

Doing so just makes DMA-idle tracking more complex because there is
now another thing (one or more address spaces) which can hold
references on a page. And FS DAX can't even keep track of all the
address spaces which might contain a reference to the page in the
XFS/reflink case anyway.

We could do this if we made file systems invalidate all address space
mappings prior to calling dax_break_layouts(), but that isn't
currently neccessary and would lead to increased faults just so we
could do some superfluous refcounting which the file system already
does.

I have however put the page sharing checks and WARN_ON's back which
also turned out to be useful for figuring out when to re-initialising
a folio.
---
 drivers/nvdimm/pmem.c    |   4 +-
 fs/dax.c                 | 212 +++++++++++++++++++++++-----------------
 fs/fuse/virtio_fs.c      |   3 +-
 fs/xfs/xfs_inode.c       |   2 +-
 include/linux/dax.h      |   6 +-
 include/linux/mm.h       |  27 +-----
 include/linux/mm_types.h |   5 +-
 mm/gup.c                 |   9 +--
 mm/huge_memory.c         |   6 +-
 mm/internal.h            |   2 +-
 mm/memory-failure.c      |   6 +-
 mm/memory.c              |   6 +-
 mm/memremap.c            |  47 ++++-----
 mm/mm_init.c             |   9 +--
 mm/swap.c                |   2 +-
 15 files changed, 181 insertions(+), 165 deletions(-)

diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index d81faa9..785b2d2 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -513,7 +513,7 @@ static int pmem_attach_disk(struct device *dev,
 
 	pmem->disk = disk;
 	pmem->pgmap.owner = pmem;
-	pmem->pfn_flags = PFN_DEV;
+	pmem->pfn_flags = 0;
 	if (is_nd_pfn(dev)) {
 		pmem->pgmap.type = MEMORY_DEVICE_FS_DAX;
 		pmem->pgmap.ops = &fsdax_pagemap_ops;
@@ -522,7 +522,6 @@ static int pmem_attach_disk(struct device *dev,
 		pmem->data_offset = le64_to_cpu(pfn_sb->dataoff);
 		pmem->pfn_pad = resource_size(res) -
 			range_len(&pmem->pgmap.range);
-		pmem->pfn_flags |= PFN_MAP;
 		bb_range = pmem->pgmap.range;
 		bb_range.start += pmem->data_offset;
 	} else if (pmem_should_map_pages(dev)) {
@@ -532,7 +531,6 @@ static int pmem_attach_disk(struct device *dev,
 		pmem->pgmap.type = MEMORY_DEVICE_FS_DAX;
 		pmem->pgmap.ops = &fsdax_pagemap_ops;
 		addr = devm_memremap_pages(dev, &pmem->pgmap);
-		pmem->pfn_flags |= PFN_MAP;
 		bb_range = pmem->pgmap.range;
 	} else {
 		addr = devm_memremap(dev, pmem->phys_addr,
diff --git a/fs/dax.c b/fs/dax.c
index 6f2d1de..139891f 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -71,6 +71,11 @@ static unsigned long dax_to_pfn(void *entry)
 	return xa_to_value(entry) >> DAX_SHIFT;
 }
 
+static struct folio *dax_to_folio(void *entry)
+{
+	return page_folio(pfn_to_page(dax_to_pfn(entry)));
+}
+
 static void *dax_make_entry(pfn_t pfn, unsigned long flags)
 {
 	return xa_mk_value(flags | (pfn_t_to_pfn(pfn) << DAX_SHIFT));
@@ -338,44 +343,88 @@ static unsigned long dax_entry_size(void *entry)
 		return PAGE_SIZE;
 }
 
-static unsigned long dax_end_pfn(void *entry)
-{
-	return dax_to_pfn(entry) + dax_entry_size(entry) / PAGE_SIZE;
-}
-
-/*
- * Iterate through all mapped pfns represented by an entry, i.e. skip
- * 'empty' and 'zero' entries.
- */
-#define for_each_mapped_pfn(entry, pfn) \
-	for (pfn = dax_to_pfn(entry); \
-			pfn < dax_end_pfn(entry); pfn++)
-
 /*
  * A DAX page is considered shared if it has no mapping set and ->share (which
  * shares the ->index field) is non-zero. Note this may return false even if the
  * page if shared between multiple files but has not yet actually been mapped
  * into multiple address spaces.
  */
-static inline bool dax_page_is_shared(struct page *page)
+static inline bool dax_folio_is_shared(struct folio *folio)
 {
-	return !page->mapping && page->share;
+	return !folio->mapping && folio->share;
 }
 
 /*
- * Increase the page share refcount, warning if the page is not marked as shared.
+ * Increase the folio share refcount, warning if the folio is not marked as shared.
  */
-static inline void dax_page_share_get(struct page *page)
+static inline void dax_folio_share_get(void *entry)
 {
-	WARN_ON_ONCE(!page->share);
-	WARN_ON_ONCE(page->mapping);
-	page->share++;
+	struct folio *folio = dax_to_folio(entry);
+
+	WARN_ON_ONCE(!folio->share);
+	WARN_ON_ONCE(folio->mapping);
+	WARN_ON_ONCE(dax_entry_order(entry) != folio_order(folio));
+	folio->share++;
+}
+
+static inline unsigned long dax_folio_share_put(struct folio *folio)
+{
+	unsigned long ref;
+
+	if (!dax_folio_is_shared(folio))
+		ref = 0;
+	else
+		ref = --folio->share;
+
+	WARN_ON_ONCE(ref < 0);
+	if (!ref) {
+		folio->mapping = NULL;
+		if (folio_order(folio)) {
+			struct dev_pagemap *pgmap = page_pgmap(&folio->page);
+			unsigned int order = folio_order(folio);
+			unsigned int i;
+
+			for (i = 0; i < (1UL << order); i++) {
+				struct page *page = folio_page(folio, i);
+
+				ClearPageHead(page);
+				clear_compound_head(page);
+
+				/*
+				 * Reset pgmap which was over-written by
+				 * prep_compound_page().
+				 */
+				page_folio(page)->pgmap = pgmap;
+
+				/* Make sure this isn't set to TAIL_MAPPING */
+				page->mapping = NULL;
+				page->share = 0;
+				WARN_ON_ONCE(page_ref_count(page));
+			}
+		}
+	}
+
+	return ref;
 }
 
-static inline unsigned long dax_page_share_put(struct page *page)
+static void dax_device_folio_init(void *entry)
 {
-	WARN_ON_ONCE(!page->share);
-	return --page->share;
+	struct folio *folio = dax_to_folio(entry);
+	int order = dax_entry_order(entry);
+
+	/*
+	 * Folio should have been split back to order-0 pages in
+	 * dax_folio_share_put() when they were removed from their
+	 * final mapping.
+	 */
+	WARN_ON_ONCE(folio_order(folio));
+
+	if (order > 0) {
+		prep_compound_page(&folio->page, order);
+		if (order > 1)
+			INIT_LIST_HEAD(&folio->_deferred_list);
+		WARN_ON_ONCE(folio_ref_count(folio));
+	}
 }
 
 /*
@@ -388,72 +437,58 @@ static inline unsigned long dax_page_share_put(struct page *page)
  * dax_holder_operations.
  */
 static void dax_associate_entry(void *entry, struct address_space *mapping,
-		struct vm_area_struct *vma, unsigned long address, bool shared)
+				struct vm_area_struct *vma, unsigned long address, bool shared)
 {
-	unsigned long size = dax_entry_size(entry), pfn, index;
-	int i = 0;
+	unsigned long size = dax_entry_size(entry), index;
+	struct folio *folio = dax_to_folio(entry);
 
 	if (IS_ENABLED(CONFIG_FS_DAX_LIMITED))
 		return;
 
 	index = linear_page_index(vma, address & ~(size - 1));
-	for_each_mapped_pfn(entry, pfn) {
-		struct page *page = pfn_to_page(pfn);
-
-		if (shared && page->mapping && page->share) {
-			if (page->mapping) {
-				page->mapping = NULL;
+	if (shared && (folio->mapping || dax_folio_is_shared(folio))) {
+		if (folio->mapping) {
+			folio->mapping = NULL;
 
-				/*
-				 * Page has already been mapped into one address
-				 * space so set the share count.
-				 */
-				page->share = 1;
-			}
-
-			dax_page_share_get(page);
-		} else {
-			WARN_ON_ONCE(page->mapping);
-			page->mapping = mapping;
-			page->index = index + i++;
+			/*
+			 * folio has already been mapped into one address
+			 * space so set the share count.
+			 */
+			folio->share = 1;
 		}
+
+		dax_folio_share_get(entry);
+	} else {
+		WARN_ON_ONCE(folio->mapping);
+		dax_device_folio_init(entry);
+		folio = dax_to_folio(entry);
+		folio->mapping = mapping;
+		folio->index = index;
 	}
 }
 
 static void dax_disassociate_entry(void *entry, struct address_space *mapping,
-		bool trunc)
+				bool trunc)
 {
-	unsigned long pfn;
+	struct folio *folio = dax_to_folio(entry);
 
 	if (IS_ENABLED(CONFIG_FS_DAX_LIMITED))
 		return;
 
-	for_each_mapped_pfn(entry, pfn) {
-		struct page *page = pfn_to_page(pfn);
-
-		WARN_ON_ONCE(trunc && page_ref_count(page) > 1);
-		if (dax_page_is_shared(page)) {
-			/* keep the shared flag if this page is still shared */
-			if (dax_page_share_put(page) > 0)
-				continue;
-		} else
-			WARN_ON_ONCE(page->mapping && page->mapping != mapping);
-		page->mapping = NULL;
-		page->index = 0;
-	}
+	dax_folio_share_put(folio);
 }
 
 static struct page *dax_busy_page(void *entry)
 {
-	unsigned long pfn;
+	struct folio *folio = dax_to_folio(entry);
 
-	for_each_mapped_pfn(entry, pfn) {
-		struct page *page = pfn_to_page(pfn);
+	if (dax_is_zero_entry(entry) || dax_is_empty_entry(entry))
+		return NULL;
 
-		if (page_ref_count(page) > 1)
-			return page;
-	}
-	return NULL;
+	if (folio_ref_count(folio) - folio_mapcount(folio))
+		return &folio->page;
+	else
+		return NULL;
 }
 
 /**
@@ -786,7 +821,7 @@ struct page *dax_layout_busy_page(struct address_space *mapping)
 EXPORT_SYMBOL_GPL(dax_layout_busy_page);
 
 static int __dax_invalidate_entry(struct address_space *mapping,
-					  pgoff_t index, bool trunc)
+				  pgoff_t index, bool trunc)
 {
 	XA_STATE(xas, &mapping->i_pages, index);
 	int ret = 0;
@@ -892,7 +927,7 @@ static int wait_page_idle(struct page *page,
 			void (cb)(struct inode *),
 			struct inode *inode)
 {
-	return ___wait_var_event(page, page_ref_count(page) == 1,
+	return ___wait_var_event(page, page_ref_count(page) == 0,
 				TASK_INTERRUPTIBLE, 0, 0, cb(inode));
 }
 
@@ -900,7 +935,7 @@ static void wait_page_idle_uninterruptible(struct page *page,
 					void (cb)(struct inode *),
 					struct inode *inode)
 {
-	___wait_var_event(page, page_ref_count(page) == 1,
+	___wait_var_event(page, page_ref_count(page) == 0,
 			TASK_UNINTERRUPTIBLE, 0, 0, cb(inode));
 }
 
@@ -943,7 +978,8 @@ void dax_break_mapping_uninterruptible(struct inode *inode,
 		wait_page_idle_uninterruptible(page, cb, inode);
 	} while (true);
 
-	dax_delete_mapping_range(inode->i_mapping, 0, LLONG_MAX);
+	if (!page)
+		dax_delete_mapping_range(inode->i_mapping, 0, LLONG_MAX);
 }
 EXPORT_SYMBOL_GPL(dax_break_mapping_uninterruptible);
 
@@ -1029,8 +1065,10 @@ static void *dax_insert_entry(struct xa_state *xas, struct vm_fault *vmf,
 		void *old;
 
 		dax_disassociate_entry(entry, mapping, false);
-		dax_associate_entry(new_entry, mapping, vmf->vma, vmf->address,
-				shared);
+		if (!(flags & DAX_ZERO_PAGE))
+			dax_associate_entry(new_entry, mapping, vmf->vma, vmf->address,
+						shared);
+
 		/*
 		 * Only swap our new entry into the page cache if the current
 		 * entry is a zero page or an empty entry.  If a normal PTE or
@@ -1218,9 +1256,7 @@ static int dax_iomap_direct_access(const struct iomap *iomap, loff_t pos,
 		goto out;
 	if (pfn_t_to_pfn(*pfnp) & (PHYS_PFN(size)-1))
 		goto out;
-	/* For larger pages we need devmap */
-	if (length > 1 && !pfn_t_devmap(*pfnp))
-		goto out;
+
 	rc = 0;
 
 out_check_addr:
@@ -1327,7 +1363,7 @@ static vm_fault_t dax_load_hole(struct xa_state *xas, struct vm_fault *vmf,
 
 	*entry = dax_insert_entry(xas, vmf, iter, *entry, pfn, DAX_ZERO_PAGE);
 
-	ret = vmf_insert_mixed(vmf->vma, vaddr, pfn);
+	ret = vmf_insert_page_mkwrite(vmf, pfn_t_to_page(pfn), false);
 	trace_dax_load_hole(inode, vmf, ret);
 	return ret;
 }
@@ -1798,7 +1834,8 @@ static vm_fault_t dax_fault_iter(struct vm_fault *vmf,
 	loff_t pos = (loff_t)xas->xa_index << PAGE_SHIFT;
 	bool write = iter->flags & IOMAP_WRITE;
 	unsigned long entry_flags = pmd ? DAX_PMD : 0;
-	int err = 0;
+	struct folio *folio;
+	int ret, err = 0;
 	pfn_t pfn;
 	void *kaddr;
 
@@ -1830,17 +1867,18 @@ static vm_fault_t dax_fault_iter(struct vm_fault *vmf,
 			return dax_fault_return(err);
 	}
 
+	folio = dax_to_folio(*entry);
 	if (dax_fault_is_synchronous(iter, vmf->vma))
 		return dax_fault_synchronous_pfnp(pfnp, pfn);
 
-	/* insert PMD pfn */
+	folio_ref_inc(folio);
 	if (pmd)
-		return vmf_insert_pfn_pmd(vmf, pfn, write);
+		ret = vmf_insert_folio_pmd(vmf, pfn_folio(pfn_t_to_pfn(pfn)), write);
+	else
+		ret = vmf_insert_page_mkwrite(vmf, pfn_t_to_page(pfn), write);
+	folio_put(folio);
 
-	/* insert PTE pfn */
-	if (write)
-		return vmf_insert_mixed_mkwrite(vmf->vma, vmf->address, pfn);
-	return vmf_insert_mixed(vmf->vma, vmf->address, pfn);
+	return ret;
 }
 
 static vm_fault_t dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
@@ -2079,6 +2117,7 @@ dax_insert_pfn_mkwrite(struct vm_fault *vmf, pfn_t pfn, unsigned int order)
 {
 	struct address_space *mapping = vmf->vma->vm_file->f_mapping;
 	XA_STATE_ORDER(xas, &mapping->i_pages, vmf->pgoff, order);
+	struct folio *folio;
 	void *entry;
 	vm_fault_t ret;
 
@@ -2096,14 +2135,17 @@ dax_insert_pfn_mkwrite(struct vm_fault *vmf, pfn_t pfn, unsigned int order)
 	xas_set_mark(&xas, PAGECACHE_TAG_DIRTY);
 	dax_lock_entry(&xas, entry);
 	xas_unlock_irq(&xas);
+	folio = pfn_folio(pfn_t_to_pfn(pfn));
+	folio_ref_inc(folio);
 	if (order == 0)
-		ret = vmf_insert_mixed_mkwrite(vmf->vma, vmf->address, pfn);
+		ret = vmf_insert_page_mkwrite(vmf, &folio->page, true);
 #ifdef CONFIG_FS_DAX_PMD
 	else if (order == PMD_ORDER)
-		ret = vmf_insert_pfn_pmd(vmf, pfn, FAULT_FLAG_WRITE);
+		ret = vmf_insert_folio_pmd(vmf, folio, FAULT_FLAG_WRITE);
 #endif
 	else
 		ret = VM_FAULT_FALLBACK;
+	folio_put(folio);
 	dax_unlock_entry(&xas, entry);
 	trace_dax_insert_pfn_mkwrite(mapping->host, vmf, ret);
 	return ret;
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index 82afe78..2c7b24c 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -1017,8 +1017,7 @@ static long virtio_fs_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
 	if (kaddr)
 		*kaddr = fs->window_kaddr + offset;
 	if (pfn)
-		*pfn = phys_to_pfn_t(fs->window_phys_addr + offset,
-					PFN_DEV | PFN_MAP);
+		*pfn = phys_to_pfn_t(fs->window_phys_addr + offset, 0);
 	return nr_pages > max_nr_pages ? max_nr_pages : nr_pages;
 }
 
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index c7ec5ab..7bfb4eb 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2740,7 +2740,7 @@ xfs_mmaplock_two_inodes_and_break_dax_layout(
 	 * for this nested lock case.
 	 */
 	page = dax_layout_busy_page(VFS_I(ip2)->i_mapping);
-	if (page && page_ref_count(page) != 1) {
+	if (page && page_ref_count(page) != 0) {
 		xfs_iunlock(ip2, XFS_MMAPLOCK_EXCL);
 		xfs_iunlock(ip1, XFS_MMAPLOCK_EXCL);
 		goto again;
diff --git a/include/linux/dax.h b/include/linux/dax.h
index 7c3773f..dbefea1 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -211,8 +211,12 @@ static inline int dax_wait_page_idle(struct page *page,
 				void (cb)(struct inode *),
 				struct inode *inode)
 {
-	return ___wait_var_event(page, page_ref_count(page) == 1,
+	int ret;
+
+	ret = ___wait_var_event(page, !page_ref_count(page),
 				TASK_INTERRUPTIBLE, 0, 0, cb(inode));
+
+	return ret;
 }
 
 #if IS_ENABLED(CONFIG_DAX)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 01edca9..a734278 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1161,6 +1161,8 @@ int vma_is_stack_for_current(struct vm_area_struct *vma);
 struct mmu_gather;
 struct inode;
 
+extern void prep_compound_page(struct page *page, unsigned int order);
+
 /*
  * compound_order() can be called without holding a reference, which means
  * that niceties like page_folio() don't work.  These callers should be
@@ -1482,25 +1484,6 @@ vm_fault_t finish_fault(struct vm_fault *vmf);
  *   back into memory.
  */
 
-#if defined(CONFIG_ZONE_DEVICE) && defined(CONFIG_FS_DAX)
-DECLARE_STATIC_KEY_FALSE(devmap_managed_key);
-
-bool __put_devmap_managed_folio_refs(struct folio *folio, int refs);
-static inline bool put_devmap_managed_folio_refs(struct folio *folio, int refs)
-{
-	if (!static_branch_unlikely(&devmap_managed_key))
-		return false;
-	if (!folio_is_zone_device(folio))
-		return false;
-	return __put_devmap_managed_folio_refs(folio, refs);
-}
-#else /* CONFIG_ZONE_DEVICE && CONFIG_FS_DAX */
-static inline bool put_devmap_managed_folio_refs(struct folio *folio, int refs)
-{
-	return false;
-}
-#endif /* CONFIG_ZONE_DEVICE && CONFIG_FS_DAX */
-
 /* 127: arbitrary random number, small enough to assemble well */
 #define folio_ref_zero_or_close_to_overflow(folio) \
 	((unsigned int) folio_ref_count(folio) + 127u <= 127u)
@@ -1615,12 +1598,6 @@ static inline void put_page(struct page *page)
 {
 	struct folio *folio = page_folio(page);
 
-	/*
-	 * For some devmap managed pages we need to catch refcount transition
-	 * from 2 to 1:
-	 */
-	if (put_devmap_managed_folio_refs(folio, 1))
-		return;
 	folio_put(folio);
 }
 
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 54b59b8..5ad6d3d 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -344,7 +344,10 @@ struct folio {
 				struct dev_pagemap *pgmap;
 			};
 			struct address_space *mapping;
-			pgoff_t index;
+			union {
+				pgoff_t index;
+				unsigned long share;
+			};
 			union {
 				void *private;
 				swp_entry_t swap;
diff --git a/mm/gup.c b/mm/gup.c
index 9b587b5..d6575ed 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -96,8 +96,7 @@ static inline struct folio *try_get_folio(struct page *page, int refs)
 	 * belongs to this folio.
 	 */
 	if (unlikely(page_folio(page) != folio)) {
-		if (!put_devmap_managed_folio_refs(folio, refs))
-			folio_put_refs(folio, refs);
+		folio_put_refs(folio, refs);
 		goto retry;
 	}
 
@@ -116,8 +115,7 @@ static void gup_put_folio(struct folio *folio, int refs, unsigned int flags)
 			refs *= GUP_PIN_COUNTING_BIAS;
 	}
 
-	if (!put_devmap_managed_folio_refs(folio, refs))
-		folio_put_refs(folio, refs);
+	folio_put_refs(folio, refs);
 }
 
 /**
@@ -565,8 +563,7 @@ static struct folio *try_grab_folio_fast(struct page *page, int refs,
 	 */
 	if (unlikely((flags & FOLL_LONGTERM) &&
 		     !folio_is_longterm_pinnable(folio))) {
-		if (!put_devmap_managed_folio_refs(folio, refs))
-			folio_put_refs(folio, refs);
+		folio_put_refs(folio, refs);
 		return NULL;
 	}
 
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 55293b0..44672d3 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2222,7 +2222,7 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
 						tlb->fullmm);
 	arch_check_zapped_pmd(vma, orig_pmd);
 	tlb_remove_pmd_tlb_entry(tlb, pmd, addr);
-	if (vma_is_special_huge(vma)) {
+	if (!vma_is_dax(vma) && vma_is_special_huge(vma)) {
 		if (arch_needs_pgtable_deposit())
 			zap_deposited_table(tlb->mm, pmd);
 		spin_unlock(ptl);
@@ -2866,13 +2866,15 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
 		 */
 		if (arch_needs_pgtable_deposit())
 			zap_deposited_table(mm, pmd);
-		if (vma_is_special_huge(vma))
+		if (!vma_is_dax(vma) && vma_is_special_huge(vma))
 			return;
 		if (unlikely(is_pmd_migration_entry(old_pmd))) {
 			swp_entry_t entry;
 
 			entry = pmd_to_swp_entry(old_pmd);
 			folio = pfn_swap_entry_folio(entry);
+		} else if (is_huge_zero_pmd(old_pmd)) {
+			return;
 		} else {
 			page = pmd_page(old_pmd);
 			folio = page_folio(page);
diff --git a/mm/internal.h b/mm/internal.h
index 3922788..c4df0ad 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -733,8 +733,6 @@ static inline void prep_compound_tail(struct page *head, int tail_idx)
 	set_page_private(p, 0);
 }
 
-extern void prep_compound_page(struct page *page, unsigned int order);
-
 void post_alloc_hook(struct page *page, unsigned int order, gfp_t gfp_flags);
 extern bool free_pages_prepare(struct page *page, unsigned int order);
 
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index a7b8ccd..7838bf1 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -419,18 +419,18 @@ static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma,
 	pud = pud_offset(p4d, address);
 	if (!pud_present(*pud))
 		return 0;
-	if (pud_devmap(*pud))
+	if (pud_trans_huge(*pud))
 		return PUD_SHIFT;
 	pmd = pmd_offset(pud, address);
 	if (!pmd_present(*pmd))
 		return 0;
-	if (pmd_devmap(*pmd))
+	if (pmd_trans_huge(*pmd))
 		return PMD_SHIFT;
 	pte = pte_offset_map(pmd, address);
 	if (!pte)
 		return 0;
 	ptent = ptep_get(pte);
-	if (pte_present(ptent) && pte_devmap(ptent))
+	if (pte_present(ptent))
 		ret = PAGE_SHIFT;
 	pte_unmap(pte);
 	return ret;
diff --git a/mm/memory.c b/mm/memory.c
index 4f73454..fa0d7b8 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3851,13 +3851,15 @@ static vm_fault_t do_wp_page(struct vm_fault *vmf)
 	if (vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) {
 		/*
 		 * VM_MIXEDMAP !pfn_valid() case, or VM_SOFTDIRTY clear on a
-		 * VM_PFNMAP VMA.
+		 * VM_PFNMAP VMA. FS DAX also wants ops->pfn_mkwrite called.
 		 *
 		 * We should not cow pages in a shared writeable mapping.
 		 * Just mark the pages writable and/or call ops->pfn_mkwrite.
 		 */
-		if (!vmf->page)
+		if (!vmf->page || is_fsdax_page(vmf->page)) {
+			vmf->page = NULL;
 			return wp_pfn_shared(vmf);
+		}
 		return wp_page_shared(vmf, folio);
 	}
 
diff --git a/mm/memremap.c b/mm/memremap.c
index 68099af..9a8879b 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -458,8 +458,13 @@ EXPORT_SYMBOL_GPL(get_dev_pagemap);
 
 void free_zone_device_folio(struct folio *folio)
 {
-	if (WARN_ON_ONCE(!folio->pgmap->ops ||
-			!folio->pgmap->ops->page_free))
+	struct dev_pagemap *pgmap = folio->pgmap;
+
+	if (WARN_ON_ONCE(!pgmap->ops))
+		return;
+
+	if (WARN_ON_ONCE(pgmap->type != MEMORY_DEVICE_FS_DAX &&
+			 !pgmap->ops->page_free))
 		return;
 
 	mem_cgroup_uncharge(folio);
@@ -484,26 +489,36 @@ void free_zone_device_folio(struct folio *folio)
 	 * For other types of ZONE_DEVICE pages, migration is either
 	 * handled differently or not done at all, so there is no need
 	 * to clear folio->mapping.
+	 *
+	 * FS DAX pages clear the mapping when the folio->share count hits
+	 * zero which indicating the page has been removed from the file
+	 * system mapping.
 	 */
-	folio->mapping = NULL;
-	folio->pgmap->ops->page_free(folio_page(folio, 0));
+	if (pgmap->type != MEMORY_DEVICE_FS_DAX)
+		folio->mapping = NULL;
 
-	switch (folio->pgmap->type) {
+	switch (pgmap->type) {
 	case MEMORY_DEVICE_PRIVATE:
 	case MEMORY_DEVICE_COHERENT:
-		put_dev_pagemap(folio->pgmap);
+		pgmap->ops->page_free(folio_page(folio, 0));
+		put_dev_pagemap(pgmap);
 		break;
 
-	case MEMORY_DEVICE_FS_DAX:
 	case MEMORY_DEVICE_GENERIC:
 		/*
 		 * Reset the refcount to 1 to prepare for handing out the page
 		 * again.
 		 */
+		pgmap->ops->page_free(folio_page(folio, 0));
 		folio_set_count(folio, 1);
 		break;
 
+	case MEMORY_DEVICE_FS_DAX:
+		wake_up_var(&folio->page);
+		break;
+
 	case MEMORY_DEVICE_PCI_P2PDMA:
+		pgmap->ops->page_free(folio_page(folio, 0));
 		break;
 	}
 }
@@ -519,21 +534,3 @@ void zone_device_page_init(struct page *page)
 	lock_page(page);
 }
 EXPORT_SYMBOL_GPL(zone_device_page_init);
-
-#ifdef CONFIG_FS_DAX
-bool __put_devmap_managed_folio_refs(struct folio *folio, int refs)
-{
-	if (folio->pgmap->type != MEMORY_DEVICE_FS_DAX)
-		return false;
-
-	/*
-	 * fsdax page refcounts are 1-based, rather than 0-based: if
-	 * refcount is 1, then the page is free and the refcount is
-	 * stable because nobody holds a reference on the page.
-	 */
-	if (folio_ref_sub_return(folio, refs) == 1)
-		wake_up_var(&folio->_refcount);
-	return true;
-}
-EXPORT_SYMBOL(__put_devmap_managed_folio_refs);
-#endif /* CONFIG_FS_DAX */
diff --git a/mm/mm_init.c b/mm/mm_init.c
index cb73402..0c12b29 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1017,23 +1017,22 @@ static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,
 	}
 
 	/*
-	 * ZONE_DEVICE pages other than MEMORY_TYPE_GENERIC and
-	 * MEMORY_TYPE_FS_DAX pages are released directly to the driver page
-	 * allocator which will set the page count to 1 when allocating the
-	 * page.
+	 * ZONE_DEVICE pages other than MEMORY_TYPE_GENERIC are released
+	 * directly to the driver page allocator which will set the page count
+	 * to 1 when allocating the page.
 	 *
 	 * MEMORY_TYPE_GENERIC and MEMORY_TYPE_FS_DAX pages automatically have
 	 * their refcount reset to one whenever they are freed (ie. after
 	 * their refcount drops to 0).
 	 */
 	switch (pgmap->type) {
+	case MEMORY_DEVICE_FS_DAX:
 	case MEMORY_DEVICE_PRIVATE:
 	case MEMORY_DEVICE_COHERENT:
 	case MEMORY_DEVICE_PCI_P2PDMA:
 		set_page_count(page, 0);
 		break;
 
-	case MEMORY_DEVICE_FS_DAX:
 	case MEMORY_DEVICE_GENERIC:
 		break;
 	}
diff --git a/mm/swap.c b/mm/swap.c
index 062c856..a587842 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -952,8 +952,6 @@ void folios_put_refs(struct folio_batch *folios, unsigned int *refs)
 				unlock_page_lruvec_irqrestore(lruvec, flags);
 				lruvec = NULL;
 			}
-			if (put_devmap_managed_folio_refs(folio, nr_refs))
-				continue;
 			if (folio_ref_sub_and_test(folio, nr_refs))
 				free_zone_device_folio(folio);
 			continue;
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:13:05 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:13:05 +1100
Subject: [PATCH v4 22/25] device/dax: Properly refcount device dax pages when mapping
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <af81ab79fdf2e18abdee6bc0a5ab5948f388247e.1734407924.git-series.apopple@nvidia.com>

Device DAX pages are currently not reference counted when mapped,
instead relying on the devmap PTE bit to ensure mapping code will not
get/put references. This requires special handling in various page
table walkers, particularly GUP, to manage references on the
underlying pgmap to ensure the pages remain valid.

However there is no reason these pages can't be refcounted properly at
map time. Doning so eliminates the need for the devmap PTE bit,
freeing up a precious PTE bit. It also simplifies GUP as it no longer
needs to manage the special pgmap references and can instead just
treat the pages normally as defined by vm_normal_page().

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 drivers/dax/device.c | 15 +++++++++------
 mm/memremap.c        | 13 ++++++-------
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/dax/device.c b/drivers/dax/device.c
index 6d74e62..fd22dbf 100644
--- a/drivers/dax/device.c
+++ b/drivers/dax/device.c
@@ -126,11 +126,12 @@ static vm_fault_t __dev_dax_pte_fault(struct dev_dax *dev_dax,
 		return VM_FAULT_SIGBUS;
 	}
 
-	pfn = phys_to_pfn_t(phys, PFN_DEV|PFN_MAP);
+	pfn = phys_to_pfn_t(phys, 0);
 
 	dax_set_mapping(vmf, pfn, fault_size);
 
-	return vmf_insert_mixed(vmf->vma, vmf->address, pfn);
+	return vmf_insert_page_mkwrite(vmf, pfn_t_to_page(pfn),
+					vmf->flags & FAULT_FLAG_WRITE);
 }
 
 static vm_fault_t __dev_dax_pmd_fault(struct dev_dax *dev_dax,
@@ -169,11 +170,12 @@ static vm_fault_t __dev_dax_pmd_fault(struct dev_dax *dev_dax,
 		return VM_FAULT_SIGBUS;
 	}
 
-	pfn = phys_to_pfn_t(phys, PFN_DEV|PFN_MAP);
+	pfn = phys_to_pfn_t(phys, 0);
 
 	dax_set_mapping(vmf, pfn, fault_size);
 
-	return vmf_insert_pfn_pmd(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE);
+	return vmf_insert_folio_pmd(vmf, page_folio(pfn_t_to_page(pfn)),
+				vmf->flags & FAULT_FLAG_WRITE);
 }
 
 #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
@@ -214,11 +216,12 @@ static vm_fault_t __dev_dax_pud_fault(struct dev_dax *dev_dax,
 		return VM_FAULT_SIGBUS;
 	}
 
-	pfn = phys_to_pfn_t(phys, PFN_DEV|PFN_MAP);
+	pfn = phys_to_pfn_t(phys, 0);
 
 	dax_set_mapping(vmf, pfn, fault_size);
 
-	return vmf_insert_pfn_pud(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE);
+	return vmf_insert_folio_pud(vmf, page_folio(pfn_t_to_page(pfn)),
+				vmf->flags & FAULT_FLAG_WRITE);
 }
 #else
 static vm_fault_t __dev_dax_pud_fault(struct dev_dax *dev_dax,
diff --git a/mm/memremap.c b/mm/memremap.c
index 9a8879b..532a52a 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -460,11 +460,10 @@ void free_zone_device_folio(struct folio *folio)
 {
 	struct dev_pagemap *pgmap = folio->pgmap;
 
-	if (WARN_ON_ONCE(!pgmap->ops))
-		return;
-
-	if (WARN_ON_ONCE(pgmap->type != MEMORY_DEVICE_FS_DAX &&
-			 !pgmap->ops->page_free))
+	if (WARN_ON_ONCE((!pgmap->ops &&
+			  pgmap->type != MEMORY_DEVICE_GENERIC) ||
+			 (pgmap->ops && !pgmap->ops->page_free &&
+			  pgmap->type != MEMORY_DEVICE_FS_DAX)))
 		return;
 
 	mem_cgroup_uncharge(folio);
@@ -494,7 +493,8 @@ void free_zone_device_folio(struct folio *folio)
 	 * zero which indicating the page has been removed from the file
 	 * system mapping.
 	 */
-	if (pgmap->type != MEMORY_DEVICE_FS_DAX)
+	if (pgmap->type != MEMORY_DEVICE_FS_DAX &&
+	    pgmap->type != MEMORY_DEVICE_GENERIC)
 		folio->mapping = NULL;
 
 	switch (pgmap->type) {
@@ -509,7 +509,6 @@ void free_zone_device_folio(struct folio *folio)
 		 * Reset the refcount to 1 to prepare for handing out the page
 		 * again.
 		 */
-		pgmap->ops->page_free(folio_page(folio, 0));
 		folio_set_count(folio, 1);
 		break;
 
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:13:06 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:13:06 +1100
Subject: [PATCH v4 23/25] mm: Remove pXX_devmap callers
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <a3b94eccd6d41fe85b2b036a9fb2c12df4eaadec.1734407924.git-series.apopple@nvidia.com>

The devmap PTE special bit was used to detect mappings of FS DAX
pages. This tracking was required to ensure the generic mm did not
manipulate the page reference counts as FS DAX implemented it's own
reference counting scheme.

Now that FS DAX pages have their references counted the same way as
normal pages this tracking is no longer needed and can be
removed.

Almost all existing uses of pmd_devmap() are paired with a check of
pmd_trans_huge(). As pmd_trans_huge() now returns true for FS DAX pages
dropping the check in these cases doesn't change anything.

However care needs to be taken because pmd_trans_huge() also checks that
a page is not an FS DAX page. This is dealt with either by checking
!vma_is_dax() or relying on the fact that the page pointer was obtained
from a page list. This is possible because zone device pages cannot
appear in any page list due to sharing page->lru with page->pgmap.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 arch/powerpc/mm/book3s64/hash_pgtable.c  |   3 +-
 arch/powerpc/mm/book3s64/pgtable.c       |   8 +-
 arch/powerpc/mm/book3s64/radix_pgtable.c |   5 +-
 arch/powerpc/mm/pgtable.c                |   2 +-
 fs/dax.c                                 |   5 +-
 fs/userfaultfd.c                         |   2 +-
 include/linux/huge_mm.h                  |  10 +-
 include/linux/pgtable.h                  |   2 +-
 mm/gup.c                                 | 162 +------------------------
 mm/hmm.c                                 |   7 +-
 mm/huge_memory.c                         |  71 +----------
 mm/khugepaged.c                          |   2 +-
 mm/mapping_dirty_helpers.c               |   4 +-
 mm/memory.c                              |  35 +----
 mm/migrate_device.c                      |   2 +-
 mm/mprotect.c                            |   2 +-
 mm/mremap.c                              |   5 +-
 mm/page_vma_mapped.c                     |   5 +-
 mm/pagewalk.c                            |  14 +-
 mm/pgtable-generic.c                     |   7 +-
 mm/userfaultfd.c                         |   5 +-
 mm/vmscan.c                              |   5 +-
 22 files changed, 63 insertions(+), 300 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/hash_pgtable.c b/arch/powerpc/mm/book3s64/hash_pgtable.c
index 988948d..82d3117 100644
--- a/arch/powerpc/mm/book3s64/hash_pgtable.c
+++ b/arch/powerpc/mm/book3s64/hash_pgtable.c
@@ -195,7 +195,7 @@ unsigned long hash__pmd_hugepage_update(struct mm_struct *mm, unsigned long addr
 	unsigned long old;
 
 #ifdef CONFIG_DEBUG_VM
-	WARN_ON(!hash__pmd_trans_huge(*pmdp) && !pmd_devmap(*pmdp));
+	WARN_ON(!hash__pmd_trans_huge(*pmdp));
 	assert_spin_locked(pmd_lockptr(mm, pmdp));
 #endif
 
@@ -227,7 +227,6 @@ pmd_t hash__pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long addres
 
 	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
 	VM_BUG_ON(pmd_trans_huge(*pmdp));
-	VM_BUG_ON(pmd_devmap(*pmdp));
 
 	pmd = *pmdp;
 	pmd_clear(pmdp);
diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
index 3745425..de66682 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -63,7 +63,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 {
 	int changed;
 #ifdef CONFIG_DEBUG_VM
-	WARN_ON(!pmd_trans_huge(*pmdp) && !pmd_devmap(*pmdp));
+	WARN_ON(!pmd_trans_huge(*pmdp));
 	assert_spin_locked(pmd_lockptr(vma->vm_mm, pmdp));
 #endif
 	changed = !pmd_same(*(pmdp), entry);
@@ -83,7 +83,6 @@ int pudp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 {
 	int changed;
 #ifdef CONFIG_DEBUG_VM
-	WARN_ON(!pud_devmap(*pudp));
 	assert_spin_locked(pud_lockptr(vma->vm_mm, pudp));
 #endif
 	changed = !pud_same(*(pudp), entry);
@@ -206,7 +205,7 @@ pmd_t pmdp_huge_get_and_clear_full(struct vm_area_struct *vma,
 	pmd_t pmd;
 	VM_BUG_ON(addr & ~HPAGE_PMD_MASK);
 	VM_BUG_ON((pmd_present(*pmdp) && !pmd_trans_huge(*pmdp) &&
-		   !pmd_devmap(*pmdp)) || !pmd_present(*pmdp));
+		   !pmd_present(*pmdp));
 	pmd = pmdp_huge_get_and_clear(vma->vm_mm, addr, pmdp);
 	/*
 	 * if it not a fullmm flush, then we can possibly end up converting
@@ -224,8 +223,7 @@ pud_t pudp_huge_get_and_clear_full(struct vm_area_struct *vma,
 	pud_t pud;
 
 	VM_BUG_ON(addr & ~HPAGE_PMD_MASK);
-	VM_BUG_ON((pud_present(*pudp) && !pud_devmap(*pudp)) ||
-		  !pud_present(*pudp));
+	VM_BUG_ON(!pud_present(*pudp));
 	pud = pudp_huge_get_and_clear(vma->vm_mm, addr, pudp);
 	/*
 	 * if it not a fullmm flush, then we can possibly end up converting
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 311e211..f0b606d 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -1412,7 +1412,7 @@ unsigned long radix__pmd_hugepage_update(struct mm_struct *mm, unsigned long add
 	unsigned long old;
 
 #ifdef CONFIG_DEBUG_VM
-	WARN_ON(!radix__pmd_trans_huge(*pmdp) && !pmd_devmap(*pmdp));
+	WARN_ON(!radix__pmd_trans_huge(*pmdp));
 	assert_spin_locked(pmd_lockptr(mm, pmdp));
 #endif
 
@@ -1429,7 +1429,7 @@ unsigned long radix__pud_hugepage_update(struct mm_struct *mm, unsigned long add
 	unsigned long old;
 
 #ifdef CONFIG_DEBUG_VM
-	WARN_ON(!pud_devmap(*pudp));
+	WARN_ON(!pud_trans_huge(*pudp));
 	assert_spin_locked(pud_lockptr(mm, pudp));
 #endif
 
@@ -1447,7 +1447,6 @@ pmd_t radix__pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long addre
 
 	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
 	VM_BUG_ON(radix__pmd_trans_huge(*pmdp));
-	VM_BUG_ON(pmd_devmap(*pmdp));
 	/*
 	 * khugepaged calls this for normal pmd
 	 */
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 61df5ae..dfaa9fd 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -509,7 +509,7 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
 		return NULL;
 #endif
 
-	if (pmd_trans_huge(pmd) || pmd_devmap(pmd)) {
+	if (pmd_trans_huge(pmd)) {
 		if (is_thp)
 			*is_thp = true;
 		ret_pte = (pte_t *)pmdp;
diff --git a/fs/dax.c b/fs/dax.c
index 139891f..70d82cc 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -1922,7 +1922,7 @@ static vm_fault_t dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
 	 * the PTE we need to set up.  If so just return and the fault will be
 	 * retried.
 	 */
-	if (pmd_trans_huge(*vmf->pmd) || pmd_devmap(*vmf->pmd)) {
+	if (pmd_trans_huge(*vmf->pmd)) {
 		ret = VM_FAULT_NOPAGE;
 		goto unlock_entry;
 	}
@@ -2043,8 +2043,7 @@ static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
 	 * the PMD we need to set up.  If so just return and the fault will be
 	 * retried.
 	 */
-	if (!pmd_none(*vmf->pmd) && !pmd_trans_huge(*vmf->pmd) &&
-			!pmd_devmap(*vmf->pmd)) {
+	if (!pmd_none(*vmf->pmd) && !pmd_trans_huge(*vmf->pmd)) {
 		ret = 0;
 		goto unlock_entry;
 	}
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 7c0bd0b..c52b91f 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -304,7 +304,7 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
 		goto out;
 
 	ret = false;
-	if (!pmd_present(_pmd) || pmd_devmap(_pmd))
+	if (!pmd_present(_pmd) || vma_is_dax(vmf->vma))
 		goto out;
 
 	if (pmd_trans_huge(_pmd)) {
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 4ad9aa7..cf83981 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -368,8 +368,7 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
 #define split_huge_pmd(__vma, __pmd, __address)				\
 	do {								\
 		pmd_t *____pmd = (__pmd);				\
-		if (is_swap_pmd(*____pmd) || pmd_trans_huge(*____pmd)	\
-					|| pmd_devmap(*____pmd))	\
+		if (is_swap_pmd(*____pmd) || pmd_trans_huge(*____pmd))	\
 			__split_huge_pmd(__vma, __pmd, __address,	\
 						false, NULL);		\
 	}  while (0)
@@ -395,8 +394,7 @@ change_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma,
 #define split_huge_pud(__vma, __pud, __address)				\
 	do {								\
 		pud_t *____pud = (__pud);				\
-		if (pud_trans_huge(*____pud)				\
-					|| pud_devmap(*____pud))	\
+		if (pud_trans_huge(*____pud))				\
 			__split_huge_pud(__vma, __pud, __address);	\
 	}  while (0)
 
@@ -419,7 +417,7 @@ static inline int is_swap_pmd(pmd_t pmd)
 static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd,
 		struct vm_area_struct *vma)
 {
-	if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd))
+	if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd))
 		return __pmd_trans_huge_lock(pmd, vma);
 	else
 		return NULL;
@@ -427,7 +425,7 @@ static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd,
 static inline spinlock_t *pud_trans_huge_lock(pud_t *pud,
 		struct vm_area_struct *vma)
 {
-	if (pud_trans_huge(*pud) || pud_devmap(*pud))
+	if (pud_trans_huge(*pud))
 		return __pud_trans_huge_lock(pud, vma);
 	else
 		return NULL;
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 94d267d..00e4a06 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -1635,7 +1635,7 @@ static inline int pud_trans_unstable(pud_t *pud)
 	defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
 	pud_t pudval = READ_ONCE(*pud);
 
-	if (pud_none(pudval) || pud_trans_huge(pudval) || pud_devmap(pudval))
+	if (pud_none(pudval) || pud_trans_huge(pudval))
 		return 1;
 	if (unlikely(pud_bad(pudval))) {
 		pud_clear_bad(pud);
diff --git a/mm/gup.c b/mm/gup.c
index d6575ed..95be530 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -678,31 +678,9 @@ static struct page *follow_huge_pud(struct vm_area_struct *vma,
 		return NULL;
 
 	pfn += (addr & ~PUD_MASK) >> PAGE_SHIFT;
-
-	if (IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) &&
-	    pud_devmap(pud)) {
-		/*
-		 * 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);
-	}
-
 	page = pfn_to_page(pfn);
 
-	if (!pud_devmap(pud) && !pud_write(pud) &&
-	    gup_must_unshare(vma, flags, page))
+	if (!pud_write(pud) && gup_must_unshare(vma, flags, page))
 		return ERR_PTR(-EMLINK);
 
 	ret = try_grab_folio(page_folio(page), 1, flags);
@@ -861,8 +839,7 @@ static struct page *follow_page_pte(struct vm_area_struct *vma,
 	page = vm_normal_page(vma, address, pte);
 
 	/*
-	 * We only care about anon pages in can_follow_write_pte() and don't
-	 * have to worry about pte_devmap() because they are never anon.
+	 * We only care about anon pages in can_follow_write_pte().
 	 */
 	if ((flags & FOLL_WRITE) &&
 	    !can_follow_write_pte(pte, page, vma, flags)) {
@@ -870,18 +847,7 @@ static struct page *follow_page_pte(struct vm_area_struct *vma,
 		goto out;
 	}
 
-	if (!page && pte_devmap(pte) && (flags & (FOLL_GET | FOLL_PIN))) {
-		/*
-		 * Only return device mapping pages in the FOLL_GET or FOLL_PIN
-		 * case since they are only valid while holding the pgmap
-		 * reference.
-		 */
-		*pgmap = get_dev_pagemap(pte_pfn(pte), *pgmap);
-		if (*pgmap)
-			page = pte_page(pte);
-		else
-			goto no_page;
-	} else if (unlikely(!page)) {
+	if (unlikely(!page)) {
 		if (flags & FOLL_DUMP) {
 			/* Avoid special (like zero) pages in core dumps */
 			page = ERR_PTR(-EFAULT);
@@ -963,14 +929,6 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma,
 		return no_page_table(vma, flags, address);
 	if (!pmd_present(pmdval))
 		return no_page_table(vma, flags, address);
-	if (pmd_devmap(pmdval)) {
-		ptl = pmd_lock(mm, pmd);
-		page = follow_devmap_pmd(vma, address, pmd, flags, &ctx->pgmap);
-		spin_unlock(ptl);
-		if (page)
-			return page;
-		return no_page_table(vma, flags, address);
-	}
 	if (likely(!pmd_leaf(pmdval)))
 		return follow_page_pte(vma, address, pmd, flags, &ctx->pgmap);
 
@@ -2892,7 +2850,7 @@ static int gup_fast_pte_range(pmd_t pmd, pmd_t *pmdp, unsigned long addr,
 		int *nr)
 {
 	struct dev_pagemap *pgmap = NULL;
-	int nr_start = *nr, ret = 0;
+	int ret = 0;
 	pte_t *ptep, *ptem;
 
 	ptem = ptep = pte_offset_map(&pmd, addr);
@@ -2916,16 +2874,7 @@ static int gup_fast_pte_range(pmd_t pmd, pmd_t *pmdp, unsigned long addr,
 		if (!pte_access_permitted(pte, flags & FOLL_WRITE))
 			goto pte_unmap;
 
-		if (pte_devmap(pte)) {
-			if (unlikely(flags & FOLL_LONGTERM))
-				goto pte_unmap;
-
-			pgmap = get_dev_pagemap(pte_pfn(pte), pgmap);
-			if (unlikely(!pgmap)) {
-				gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
-				goto pte_unmap;
-			}
-		} else if (pte_special(pte))
+		if (pte_special(pte))
 			goto pte_unmap;
 
 		VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
@@ -2996,91 +2945,6 @@ static int gup_fast_pte_range(pmd_t pmd, pmd_t *pmdp, unsigned long addr,
 }
 #endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */
 
-#if defined(CONFIG_ARCH_HAS_PTE_DEVMAP) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
-static int gup_fast_devmap_leaf(unsigned long pfn, unsigned long addr,
-	unsigned long end, unsigned int flags, struct page **pages, int *nr)
-{
-	int nr_start = *nr;
-	struct dev_pagemap *pgmap = NULL;
-
-	do {
-		struct folio *folio;
-		struct page *page = pfn_to_page(pfn);
-
-		pgmap = get_dev_pagemap(pfn, pgmap);
-		if (unlikely(!pgmap)) {
-			gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
-			break;
-		}
-
-		folio = try_grab_folio_fast(page, 1, flags);
-		if (!folio) {
-			gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
-			break;
-		}
-		folio_set_referenced(folio);
-		pages[*nr] = page;
-		(*nr)++;
-		pfn++;
-	} while (addr += PAGE_SIZE, addr != end);
-
-	put_dev_pagemap(pgmap);
-	return addr == end;
-}
-
-static int gup_fast_devmap_pmd_leaf(pmd_t orig, pmd_t *pmdp, unsigned long addr,
-		unsigned long end, unsigned int flags, struct page **pages,
-		int *nr)
-{
-	unsigned long fault_pfn;
-	int nr_start = *nr;
-
-	fault_pfn = pmd_pfn(orig) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
-	if (!gup_fast_devmap_leaf(fault_pfn, addr, end, flags, pages, nr))
-		return 0;
-
-	if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
-		gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
-		return 0;
-	}
-	return 1;
-}
-
-static int gup_fast_devmap_pud_leaf(pud_t orig, pud_t *pudp, unsigned long addr,
-		unsigned long end, unsigned int flags, struct page **pages,
-		int *nr)
-{
-	unsigned long fault_pfn;
-	int nr_start = *nr;
-
-	fault_pfn = pud_pfn(orig) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
-	if (!gup_fast_devmap_leaf(fault_pfn, addr, end, flags, pages, nr))
-		return 0;
-
-	if (unlikely(pud_val(orig) != pud_val(*pudp))) {
-		gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
-		return 0;
-	}
-	return 1;
-}
-#else
-static int gup_fast_devmap_pmd_leaf(pmd_t orig, pmd_t *pmdp, unsigned long addr,
-		unsigned long end, unsigned int flags, struct page **pages,
-		int *nr)
-{
-	BUILD_BUG();
-	return 0;
-}
-
-static int gup_fast_devmap_pud_leaf(pud_t pud, pud_t *pudp, unsigned long addr,
-		unsigned long end, unsigned int flags, struct page **pages,
-		int *nr)
-{
-	BUILD_BUG();
-	return 0;
-}
-#endif
-
 static int gup_fast_pmd_leaf(pmd_t orig, pmd_t *pmdp, unsigned long addr,
 		unsigned long end, unsigned int flags, struct page **pages,
 		int *nr)
@@ -3095,13 +2959,6 @@ static int gup_fast_pmd_leaf(pmd_t orig, pmd_t *pmdp, unsigned long addr,
 	if (pmd_special(orig))
 		return 0;
 
-	if (pmd_devmap(orig)) {
-		if (unlikely(flags & FOLL_LONGTERM))
-			return 0;
-		return gup_fast_devmap_pmd_leaf(orig, pmdp, addr, end, flags,
-					        pages, nr);
-	}
-
 	page = pmd_page(orig);
 	refs = record_subpages(page, PMD_SIZE, addr, end, pages + *nr);
 
@@ -3142,13 +2999,6 @@ static int gup_fast_pud_leaf(pud_t orig, pud_t *pudp, unsigned long addr,
 	if (pud_special(orig))
 		return 0;
 
-	if (pud_devmap(orig)) {
-		if (unlikely(flags & FOLL_LONGTERM))
-			return 0;
-		return gup_fast_devmap_pud_leaf(orig, pudp, addr, end, flags,
-					        pages, nr);
-	}
-
 	page = pud_page(orig);
 	refs = record_subpages(page, PUD_SIZE, addr, end, pages + *nr);
 
@@ -3187,8 +3037,6 @@ static int gup_fast_pgd_leaf(pgd_t orig, pgd_t *pgdp, unsigned long addr,
 	if (!pgd_access_permitted(orig, flags & FOLL_WRITE))
 		return 0;
 
-	BUILD_BUG_ON(pgd_devmap(orig));
-
 	page = pgd_page(orig);
 	refs = record_subpages(page, PGDIR_SIZE, addr, end, pages + *nr);
 
diff --git a/mm/hmm.c b/mm/hmm.c
index 082f7b7..285578e 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -298,7 +298,6 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
 	 * fall through and treat it like a normal page.
 	 */
 	if (!vm_normal_page(walk->vma, addr, pte) &&
-	    !pte_devmap(pte) &&
 	    !is_zero_pfn(pte_pfn(pte))) {
 		if (hmm_pte_need_fault(hmm_vma_walk, pfn_req_flags, 0)) {
 			pte_unmap(ptep);
@@ -351,7 +350,7 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp,
 		return hmm_pfns_fill(start, end, range, HMM_PFN_ERROR);
 	}
 
-	if (pmd_devmap(pmd) || pmd_trans_huge(pmd)) {
+	if (pmd_trans_huge(pmd)) {
 		/*
 		 * No need to take pmd_lock here, even if some other thread
 		 * is splitting the huge pmd we will get that event through
@@ -362,7 +361,7 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp,
 		 * values.
 		 */
 		pmd = pmdp_get_lockless(pmdp);
-		if (!pmd_devmap(pmd) && !pmd_trans_huge(pmd))
+		if (!pmd_trans_huge(pmd))
 			goto again;
 
 		return hmm_vma_handle_pmd(walk, addr, end, hmm_pfns, pmd);
@@ -429,7 +428,7 @@ static int hmm_vma_walk_pud(pud_t *pudp, unsigned long start, unsigned long end,
 		return hmm_vma_walk_hole(start, end, -1, walk);
 	}
 
-	if (pud_leaf(pud) && pud_devmap(pud)) {
+	if (pud_leaf(pud) && vma_is_dax(walk->vma)) {
 		unsigned long i, npages, pfn;
 		unsigned int required_fault;
 		unsigned long *hmm_pfns;
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 44672d3..e03d71f 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1398,10 +1398,7 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
 	}
 
 	entry = pmd_mkhuge(pfn_t_pmd(pfn, prot));
-	if (pfn_t_devmap(pfn))
-		entry = pmd_mkdevmap(entry);
-	else
-		entry = pmd_mkspecial(entry);
+	entry = pmd_mkspecial(entry);
 	if (write) {
 		entry = pmd_mkyoung(pmd_mkdirty(entry));
 		entry = maybe_pmd_mkwrite(entry, vma);
@@ -1440,8 +1437,6 @@ vm_fault_t vmf_insert_pfn_pmd(struct vm_fault *vmf, pfn_t pfn, bool write)
 	 * but we need to be consistent with PTEs and architectures that
 	 * can't support a 'special' bit.
 	 */
-	BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) &&
-			!pfn_t_devmap(pfn));
 	BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) ==
 						(VM_PFNMAP|VM_MIXEDMAP));
 	BUG_ON((vma->vm_flags & VM_PFNMAP) && is_cow_mapping(vma->vm_flags));
@@ -1536,10 +1531,7 @@ static void insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
 	}
 
 	entry = pud_mkhuge(pfn_t_pud(pfn, prot));
-	if (pfn_t_devmap(pfn))
-		entry = pud_mkdevmap(entry);
-	else
-		entry = pud_mkspecial(entry);
+	entry = pud_mkspecial(entry);
 	if (write) {
 		entry = pud_mkyoung(pud_mkdirty(entry));
 		entry = maybe_pud_mkwrite(entry, vma);
@@ -1570,8 +1562,6 @@ vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write)
 	 * but we need to be consistent with PTEs and architectures that
 	 * can't support a 'special' bit.
 	 */
-	BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) &&
-			!pfn_t_devmap(pfn));
 	BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) ==
 						(VM_PFNMAP|VM_MIXEDMAP));
 	BUG_ON((vma->vm_flags & VM_PFNMAP) && is_cow_mapping(vma->vm_flags));
@@ -1645,46 +1635,6 @@ void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
 		update_mmu_cache_pmd(vma, addr, pmd);
 }
 
-struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr,
-		pmd_t *pmd, int flags, struct dev_pagemap **pgmap)
-{
-	unsigned long pfn = pmd_pfn(*pmd);
-	struct mm_struct *mm = vma->vm_mm;
-	struct page *page;
-	int ret;
-
-	assert_spin_locked(pmd_lockptr(mm, pmd));
-
-	if (flags & FOLL_WRITE && !pmd_write(*pmd))
-		return NULL;
-
-	if (pmd_present(*pmd) && pmd_devmap(*pmd))
-		/* pass */;
-	else
-		return NULL;
-
-	if (flags & FOLL_TOUCH)
-		touch_pmd(vma, addr, pmd, flags & FOLL_WRITE);
-
-	/*
-	 * device mapped pages can only be returned if the
-	 * caller will manage the page reference count.
-	 */
-	if (!(flags & (FOLL_GET | FOLL_PIN)))
-		return ERR_PTR(-EEXIST);
-
-	pfn += (addr & ~PMD_MASK) >> PAGE_SHIFT;
-	*pgmap = get_dev_pagemap(pfn, *pgmap);
-	if (!*pgmap)
-		return ERR_PTR(-EFAULT);
-	page = pfn_to_page(pfn);
-	ret = try_grab_folio(page_folio(page), 1, flags);
-	if (ret)
-		page = ERR_PTR(ret);
-
-	return page;
-}
-
 int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
 		  pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr,
 		  struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
@@ -1836,7 +1786,7 @@ int copy_huge_pud(struct mm_struct *dst_mm, struct mm_struct *src_mm,
 
 	ret = -EAGAIN;
 	pud = *src_pud;
-	if (unlikely(!pud_trans_huge(pud) && !pud_devmap(pud)))
+	if (unlikely(!pud_trans_huge(pud)))
 		goto out_unlock;
 
 	/*
@@ -2678,8 +2628,7 @@ spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma)
 {
 	spinlock_t *ptl;
 	ptl = pmd_lock(vma->vm_mm, pmd);
-	if (likely(is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) ||
-			pmd_devmap(*pmd)))
+	if (likely(is_swap_pmd(*pmd) || pmd_trans_huge(*pmd)))
 		return ptl;
 	spin_unlock(ptl);
 	return NULL;
@@ -2696,7 +2645,7 @@ spinlock_t *__pud_trans_huge_lock(pud_t *pud, struct vm_area_struct *vma)
 	spinlock_t *ptl;
 
 	ptl = pud_lock(vma->vm_mm, pud);
-	if (likely(pud_trans_huge(*pud) || pud_devmap(*pud)))
+	if (likely(pud_trans_huge(*pud)))
 		return ptl;
 	spin_unlock(ptl);
 	return NULL;
@@ -2746,7 +2695,7 @@ static void __split_huge_pud_locked(struct vm_area_struct *vma, pud_t *pud,
 	VM_BUG_ON(haddr & ~HPAGE_PUD_MASK);
 	VM_BUG_ON_VMA(vma->vm_start > haddr, vma);
 	VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PUD_SIZE, vma);
-	VM_BUG_ON(!pud_trans_huge(*pud) && !pud_devmap(*pud));
+	VM_BUG_ON(!pud_trans_huge(*pud));
 
 	count_vm_event(THP_SPLIT_PUD);
 
@@ -2780,7 +2729,7 @@ void __split_huge_pud(struct vm_area_struct *vma, pud_t *pud,
 				(address & HPAGE_PUD_MASK) + HPAGE_PUD_SIZE);
 	mmu_notifier_invalidate_range_start(&range);
 	ptl = pud_lock(vma->vm_mm, pud);
-	if (unlikely(!pud_trans_huge(*pud) && !pud_devmap(*pud)))
+	if (unlikely(!pud_trans_huge(*pud)))
 		goto out;
 	__split_huge_pud_locked(vma, pud, range.start);
 
@@ -2853,8 +2802,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
 	VM_BUG_ON(haddr & ~HPAGE_PMD_MASK);
 	VM_BUG_ON_VMA(vma->vm_start > haddr, vma);
 	VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PMD_SIZE, vma);
-	VM_BUG_ON(!is_pmd_migration_entry(*pmd) && !pmd_trans_huge(*pmd)
-				&& !pmd_devmap(*pmd));
+	VM_BUG_ON(!is_pmd_migration_entry(*pmd) && !pmd_trans_huge(*pmd));
 
 	count_vm_event(THP_SPLIT_PMD);
 
@@ -3071,8 +3019,7 @@ void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
 	 * require a folio to check the PMD against. Otherwise, there
 	 * is a risk of replacing the wrong folio.
 	 */
-	if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) ||
-	    is_pmd_migration_entry(*pmd)) {
+	if (pmd_trans_huge(*pmd) || is_pmd_migration_entry(*pmd)) {
 		if (folio && folio != pmd_folio(*pmd))
 			return;
 		__split_huge_pmd_locked(vma, pmd, address, freeze);
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 99dc995..aedef75 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -957,8 +957,6 @@ static inline int check_pmd_state(pmd_t *pmd)
 		return SCAN_PMD_NULL;
 	if (pmd_trans_huge(pmde))
 		return SCAN_PMD_MAPPED;
-	if (pmd_devmap(pmde))
-		return SCAN_PMD_NULL;
 	if (pmd_bad(pmde))
 		return SCAN_PMD_NULL;
 	return SCAN_SUCCEED;
diff --git a/mm/mapping_dirty_helpers.c b/mm/mapping_dirty_helpers.c
index 2f8829b..208b428 100644
--- a/mm/mapping_dirty_helpers.c
+++ b/mm/mapping_dirty_helpers.c
@@ -129,7 +129,7 @@ static int wp_clean_pmd_entry(pmd_t *pmd, unsigned long addr, unsigned long end,
 	pmd_t pmdval = pmdp_get_lockless(pmd);
 
 	/* Do not split a huge pmd, present or migrated */
-	if (pmd_trans_huge(pmdval) || pmd_devmap(pmdval)) {
+	if (pmd_trans_huge(pmdval)) {
 		WARN_ON(pmd_write(pmdval) || pmd_dirty(pmdval));
 		walk->action = ACTION_CONTINUE;
 	}
@@ -152,7 +152,7 @@ static int wp_clean_pud_entry(pud_t *pud, unsigned long addr, unsigned long end,
 	pud_t pudval = READ_ONCE(*pud);
 
 	/* Do not split a huge pud */
-	if (pud_trans_huge(pudval) || pud_devmap(pudval)) {
+	if (pud_trans_huge(pudval)) {
 		WARN_ON(pud_write(pudval) || pud_dirty(pudval));
 		walk->action = ACTION_CONTINUE;
 	}
diff --git a/mm/memory.c b/mm/memory.c
index fa0d7b8..506fa23 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -603,16 +603,6 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
 			return NULL;
 		if (is_zero_pfn(pfn))
 			return NULL;
-		if (pte_devmap(pte))
-		/*
-		 * NOTE: New users of ZONE_DEVICE will not set pte_devmap()
-		 * and will have refcounts incremented on their struct pages
-		 * when they are inserted into PTEs, thus they are safe to
-		 * return here. Legacy ZONE_DEVICE pages that set pte_devmap()
-		 * do not have refcounts. Example of legacy ZONE_DEVICE is
-		 * MEMORY_DEVICE_FS_DAX type in pmem or virtio_fs drivers.
-		 */
-			return NULL;
 
 		print_bad_pte(vma, addr, pte, NULL);
 		return NULL;
@@ -690,8 +680,6 @@ struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
 		}
 	}
 
-	if (pmd_devmap(pmd))
-		return NULL;
 	if (is_huge_zero_pmd(pmd))
 		return NULL;
 	if (unlikely(pfn > highest_memmap_pfn))
@@ -1245,8 +1233,7 @@ copy_pmd_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
 	src_pmd = pmd_offset(src_pud, addr);
 	do {
 		next = pmd_addr_end(addr, end);
-		if (is_swap_pmd(*src_pmd) || pmd_trans_huge(*src_pmd)
-			|| pmd_devmap(*src_pmd)) {
+		if (is_swap_pmd(*src_pmd) || pmd_trans_huge(*src_pmd)) {
 			int err;
 			VM_BUG_ON_VMA(next-addr != HPAGE_PMD_SIZE, src_vma);
 			err = copy_huge_pmd(dst_mm, src_mm, dst_pmd, src_pmd,
@@ -1282,7 +1269,7 @@ copy_pud_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
 	src_pud = pud_offset(src_p4d, addr);
 	do {
 		next = pud_addr_end(addr, end);
-		if (pud_trans_huge(*src_pud) || pud_devmap(*src_pud)) {
+		if (pud_trans_huge(*src_pud)) {
 			int err;
 
 			VM_BUG_ON_VMA(next-addr != HPAGE_PUD_SIZE, src_vma);
@@ -1797,7 +1784,7 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
 	pmd = pmd_offset(pud, addr);
 	do {
 		next = pmd_addr_end(addr, end);
-		if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) {
+		if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd)) {
 			if (next - addr != HPAGE_PMD_SIZE)
 				__split_huge_pmd(vma, pmd, addr, false, NULL);
 			else if (zap_huge_pmd(tlb, vma, pmd, addr)) {
@@ -1839,7 +1826,7 @@ static inline unsigned long zap_pud_range(struct mmu_gather *tlb,
 	pud = pud_offset(p4d, addr);
 	do {
 		next = pud_addr_end(addr, end);
-		if (pud_trans_huge(*pud) || pud_devmap(*pud)) {
+		if (pud_trans_huge(*pud)) {
 			if (next - addr != HPAGE_PUD_SIZE) {
 				mmap_assert_locked(tlb->mm);
 				split_huge_pud(vma, pud, addr);
@@ -2462,10 +2449,7 @@ static vm_fault_t insert_pfn(struct vm_area_struct *vma, unsigned long addr,
 	}
 
 	/* Ok, finally just insert the thing.. */
-	if (pfn_t_devmap(pfn))
-		entry = pte_mkdevmap(pfn_t_pte(pfn, prot));
-	else
-		entry = pte_mkspecial(pfn_t_pte(pfn, prot));
+	entry = pte_mkspecial(pfn_t_pte(pfn, prot));
 
 	if (mkwrite) {
 		entry = pte_mkyoung(entry);
@@ -2576,8 +2560,6 @@ static bool vm_mixed_ok(struct vm_area_struct *vma, pfn_t pfn, bool mkwrite)
 	/* these checks mirror the abort conditions in vm_normal_page */
 	if (vma->vm_flags & VM_MIXEDMAP)
 		return true;
-	if (pfn_t_devmap(pfn))
-		return true;
 	if (pfn_t_special(pfn))
 		return true;
 	if (is_zero_pfn(pfn_t_to_pfn(pfn)))
@@ -2609,8 +2591,7 @@ static vm_fault_t __vm_insert_mixed(struct vm_area_struct *vma,
 	 * than insert_pfn).  If a zero_pfn were inserted into a VM_MIXEDMAP
 	 * without pte special, it would there be refcounted as a normal page.
 	 */
-	if (!IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL) &&
-	    !pfn_t_devmap(pfn) && pfn_t_valid(pfn)) {
+	if (!IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL) && pfn_t_valid(pfn)) {
 		struct page *page;
 
 		/*
@@ -6042,7 +6023,7 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
 		pud_t orig_pud = *vmf.pud;
 
 		barrier();
-		if (pud_trans_huge(orig_pud) || pud_devmap(orig_pud)) {
+		if (pud_trans_huge(orig_pud)) {
 
 			/*
 			 * TODO once we support anonymous PUDs: NUMA case and
@@ -6083,7 +6064,7 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
 				pmd_migration_entry_wait(mm, vmf.pmd);
 			return 0;
 		}
-		if (pmd_trans_huge(vmf.orig_pmd) || pmd_devmap(vmf.orig_pmd)) {
+		if (pmd_trans_huge(vmf.orig_pmd)) {
 			if (pmd_protnone(vmf.orig_pmd) && vma_is_accessible(vma))
 				return do_huge_pmd_numa_page(&vmf);
 
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 2209070..a721e0d 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -599,7 +599,7 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
 	pmdp = pmd_alloc(mm, pudp, addr);
 	if (!pmdp)
 		goto abort;
-	if (pmd_trans_huge(*pmdp) || pmd_devmap(*pmdp))
+	if (pmd_trans_huge(*pmdp))
 		goto abort;
 	if (pte_alloc(mm, pmdp))
 		goto abort;
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 516b1d8..31055a8 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -384,7 +384,7 @@ static inline long change_pmd_range(struct mmu_gather *tlb,
 			goto next;
 
 		_pmd = pmdp_get_lockless(pmd);
-		if (is_swap_pmd(_pmd) || pmd_trans_huge(_pmd) || pmd_devmap(_pmd)) {
+		if (is_swap_pmd(_pmd) || pmd_trans_huge(_pmd)) {
 			if ((next - addr != HPAGE_PMD_SIZE) ||
 			    pgtable_split_needed(vma, cp_flags)) {
 				__split_huge_pmd(vma, pmd, addr, false, NULL);
diff --git a/mm/mremap.c b/mm/mremap.c
index 6047341..96fff18 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -603,7 +603,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
 		new_pud = alloc_new_pud(vma->vm_mm, vma, new_addr);
 		if (!new_pud)
 			break;
-		if (pud_trans_huge(*old_pud) || pud_devmap(*old_pud)) {
+		if (pud_trans_huge(*old_pud)) {
 			if (extent == HPAGE_PUD_SIZE) {
 				move_pgt_entry(HPAGE_PUD, vma, old_addr, new_addr,
 					       old_pud, new_pud, need_rmap_locks);
@@ -625,8 +625,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
 		if (!new_pmd)
 			break;
 again:
-		if (is_swap_pmd(*old_pmd) || pmd_trans_huge(*old_pmd) ||
-		    pmd_devmap(*old_pmd)) {
+		if (is_swap_pmd(*old_pmd) || pmd_trans_huge(*old_pmd)) {
 			if (extent == HPAGE_PMD_SIZE &&
 			    move_pgt_entry(HPAGE_PMD, vma, old_addr, new_addr,
 					   old_pmd, new_pmd, need_rmap_locks))
diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
index 81839a9..18eadc5 100644
--- a/mm/page_vma_mapped.c
+++ b/mm/page_vma_mapped.c
@@ -242,8 +242,7 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
 		 */
 		pmde = pmdp_get_lockless(pvmw->pmd);
 
-		if (pmd_trans_huge(pmde) || is_pmd_migration_entry(pmde) ||
-		    (pmd_present(pmde) && pmd_devmap(pmde))) {
+		if (pmd_trans_huge(pmde) || is_pmd_migration_entry(pmde)) {
 			pvmw->ptl = pmd_lock(mm, pvmw->pmd);
 			pmde = *pvmw->pmd;
 			if (!pmd_present(pmde)) {
@@ -258,7 +257,7 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
 					return not_found(pvmw);
 				return true;
 			}
-			if (likely(pmd_trans_huge(pmde) || pmd_devmap(pmde))) {
+			if (likely(pmd_trans_huge(pmde))) {
 				if (pvmw->flags & PVMW_MIGRATION)
 					return not_found(pvmw);
 				if (!check_pmd(pmd_pfn(pmde), pvmw))
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index e478777..a85c331 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -143,8 +143,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
 			 * We are ONLY installing, so avoid unnecessarily
 			 * splitting a present huge page.
 			 */
-			if (pmd_present(*pmd) &&
-			    (pmd_trans_huge(*pmd) || pmd_devmap(*pmd)))
+			if (pmd_present(*pmd) && pmd_trans_huge(*pmd))
 				continue;
 		}
 
@@ -210,8 +209,7 @@ static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
 			 * We are ONLY installing, so avoid unnecessarily
 			 * splitting a present huge page.
 			 */
-			if (pud_present(*pud) &&
-			    (pud_trans_huge(*pud) || pud_devmap(*pud)))
+			if (pud_present(*pud) && pud_trans_huge(*pud))
 				continue;
 		}
 
@@ -872,7 +870,7 @@ struct folio *folio_walk_start(struct folio_walk *fw,
 		 * TODO: FW_MIGRATION support for PUD migration entries
 		 * once there are relevant users.
 		 */
-		if (!pud_present(pud) || pud_devmap(pud) || pud_special(pud)) {
+		if (!pud_present(pud) || pud_special(pud)) {
 			spin_unlock(ptl);
 			goto not_found;
 		} else if (!pud_leaf(pud)) {
@@ -884,6 +882,12 @@ struct folio *folio_walk_start(struct folio_walk *fw,
 		 * support PUD mappings in VM_PFNMAP|VM_MIXEDMAP VMAs.
 		 */
 		page = pud_page(pud);
+
+		if (is_device_dax_page(page)) {
+			spin_unlock(ptl);
+			goto not_found;
+		}
+
 		goto found;
 	}
 
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index 5a882f2..567e2d0 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -139,8 +139,7 @@ pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, unsigned long address,
 {
 	pmd_t pmd;
 	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
-	VM_BUG_ON(pmd_present(*pmdp) && !pmd_trans_huge(*pmdp) &&
-			   !pmd_devmap(*pmdp));
+	VM_BUG_ON(pmd_present(*pmdp) && !pmd_trans_huge(*pmdp));
 	pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
 	flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 	return pmd;
@@ -153,7 +152,7 @@ pud_t pudp_huge_clear_flush(struct vm_area_struct *vma, unsigned long address,
 	pud_t pud;
 
 	VM_BUG_ON(address & ~HPAGE_PUD_MASK);
-	VM_BUG_ON(!pud_trans_huge(*pudp) && !pud_devmap(*pudp));
+	VM_BUG_ON(!pud_trans_huge(*pudp));
 	pud = pudp_huge_get_and_clear(vma->vm_mm, address, pudp);
 	flush_pud_tlb_range(vma, address, address + HPAGE_PUD_SIZE);
 	return pud;
@@ -293,7 +292,7 @@ pte_t *___pte_offset_map(pmd_t *pmd, unsigned long addr, pmd_t *pmdvalp)
 		*pmdvalp = pmdval;
 	if (unlikely(pmd_none(pmdval) || is_pmd_migration_entry(pmdval)))
 		goto nomap;
-	if (unlikely(pmd_trans_huge(pmdval) || pmd_devmap(pmdval)))
+	if (unlikely(pmd_trans_huge(pmdval)))
 		goto nomap;
 	if (unlikely(pmd_bad(pmdval))) {
 		pmd_clear_bad(pmd);
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 4527c38..a03c6f1 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -790,8 +790,7 @@ static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx,
 		 * (This includes the case where the PMD used to be THP and
 		 * changed back to none after __pte_alloc().)
 		 */
-		if (unlikely(!pmd_present(dst_pmdval) || pmd_trans_huge(dst_pmdval) ||
-			     pmd_devmap(dst_pmdval))) {
+		if (unlikely(!pmd_present(dst_pmdval) || pmd_trans_huge(dst_pmdval))) {
 			err = -EEXIST;
 			break;
 		}
@@ -1694,7 +1693,7 @@ ssize_t move_pages(struct userfaultfd_ctx *ctx, unsigned long dst_start,
 
 		ptl = pmd_trans_huge_lock(src_pmd, src_vma);
 		if (ptl) {
-			if (pmd_devmap(*src_pmd)) {
+			if (vma_is_dax(src_vma)) {
 				spin_unlock(ptl);
 				err = -ENOENT;
 				break;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 39886f4..b0e25d1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3366,7 +3366,7 @@ static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned
 	if (!pte_present(pte) || is_zero_pfn(pfn))
 		return -1;
 
-	if (WARN_ON_ONCE(pte_devmap(pte) || pte_special(pte)))
+	if (WARN_ON_ONCE(pte_special(pte)))
 		return -1;
 
 	if (!pte_young(pte) && !mm_has_notifiers(vma->vm_mm))
@@ -3391,9 +3391,6 @@ static unsigned long get_pmd_pfn(pmd_t pmd, struct vm_area_struct *vma, unsigned
 	if (!pmd_present(pmd) || is_huge_zero_pmd(pmd))
 		return -1;
 
-	if (WARN_ON_ONCE(pmd_devmap(pmd)))
-		return -1;
-
 	if (!pmd_young(pmd) && !mm_has_notifiers(vma->vm_mm))
 		return -1;
 
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:13:07 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:13:07 +1100
Subject: [PATCH v4 24/25] mm: Remove devmap related functions and page table bits
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <910fbc82c517aed14ce2d80074ff603b1dc0d6ef.1734407924.git-series.apopple@nvidia.com>

Now that DAX and all other reference counts to ZONE_DEVICE pages are
managed normally there is no need for the special devmap PTE/PMD/PUD
page table bits. So drop all references to these, freeing up a
software defined page table bit on architectures supporting it.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Acked-by: Will Deacon <will at kernel.org> # arm64
---
 Documentation/mm/arch_pgtable_helpers.rst     |  6 +--
 arch/arm64/Kconfig                            |  1 +-
 arch/arm64/include/asm/pgtable-prot.h         |  1 +-
 arch/arm64/include/asm/pgtable.h              | 24 +--------
 arch/powerpc/Kconfig                          |  1 +-
 arch/powerpc/include/asm/book3s/64/hash-4k.h  |  6 +--
 arch/powerpc/include/asm/book3s/64/hash-64k.h |  7 +--
 arch/powerpc/include/asm/book3s/64/pgtable.h  | 52 +------------------
 arch/powerpc/include/asm/book3s/64/radix.h    | 14 +-----
 arch/x86/Kconfig                              |  1 +-
 arch/x86/include/asm/pgtable.h                | 51 +-----------------
 arch/x86/include/asm/pgtable_types.h          |  5 +--
 include/linux/mm.h                            |  7 +--
 include/linux/pfn_t.h                         | 20 +-------
 include/linux/pgtable.h                       | 19 +------
 mm/Kconfig                                    |  4 +-
 mm/debug_vm_pgtable.c                         | 59 +--------------------
 mm/hmm.c                                      |  3 +-
 18 files changed, 11 insertions(+), 270 deletions(-)

diff --git a/Documentation/mm/arch_pgtable_helpers.rst b/Documentation/mm/arch_pgtable_helpers.rst
index af24516..c88c7fa 100644
--- a/Documentation/mm/arch_pgtable_helpers.rst
+++ b/Documentation/mm/arch_pgtable_helpers.rst
@@ -30,8 +30,6 @@ PTE Page Table Helpers
 +---------------------------+--------------------------------------------------+
 | pte_protnone              | Tests a PROT_NONE PTE                            |
 +---------------------------+--------------------------------------------------+
-| pte_devmap                | Tests a ZONE_DEVICE mapped PTE                   |
-+---------------------------+--------------------------------------------------+
 | pte_soft_dirty            | Tests a soft dirty PTE                           |
 +---------------------------+--------------------------------------------------+
 | pte_swp_soft_dirty        | Tests a soft dirty swapped PTE                   |
@@ -104,8 +102,6 @@ PMD Page Table Helpers
 +---------------------------+--------------------------------------------------+
 | pmd_protnone              | Tests a PROT_NONE PMD                            |
 +---------------------------+--------------------------------------------------+
-| pmd_devmap                | Tests a ZONE_DEVICE mapped PMD                   |
-+---------------------------+--------------------------------------------------+
 | pmd_soft_dirty            | Tests a soft dirty PMD                           |
 +---------------------------+--------------------------------------------------+
 | pmd_swp_soft_dirty        | Tests a soft dirty swapped PMD                   |
@@ -177,8 +173,6 @@ PUD Page Table Helpers
 +---------------------------+--------------------------------------------------+
 | pud_write                 | Tests a writable PUD                             |
 +---------------------------+--------------------------------------------------+
-| pud_devmap                | Tests a ZONE_DEVICE mapped PUD                   |
-+---------------------------+--------------------------------------------------+
 | pud_mkyoung               | Creates a young PUD                              |
 +---------------------------+--------------------------------------------------+
 | pud_mkold                 | Creates an old PUD                               |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 39310a4..81855d1 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -41,7 +41,6 @@ config ARM64
 	select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
 	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	select ARCH_HAS_NONLEAF_PMD_YOUNG if ARM64_HAFT
-	select ARCH_HAS_PTE_DEVMAP
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_HW_PTE_YOUNG
 	select ARCH_HAS_SETUP_DMA_OPS
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 9f9cf13..49b51df 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -17,7 +17,6 @@
 #define PTE_SWP_EXCLUSIVE	(_AT(pteval_t, 1) << 2)	 /* only for swp ptes */
 #define PTE_DIRTY		(_AT(pteval_t, 1) << 55)
 #define PTE_SPECIAL		(_AT(pteval_t, 1) << 56)
-#define PTE_DEVMAP		(_AT(pteval_t, 1) << 57)
 
 /*
  * PTE_PRESENT_INVALID=1 & PTE_VALID=0 indicates that the pte's fields should be
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index f8dac66..ea34e51 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -108,7 +108,6 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
 #define pte_user(pte)		(!!(pte_val(pte) & PTE_USER))
 #define pte_user_exec(pte)	(!(pte_val(pte) & PTE_UXN))
 #define pte_cont(pte)		(!!(pte_val(pte) & PTE_CONT))
-#define pte_devmap(pte)		(!!(pte_val(pte) & PTE_DEVMAP))
 #define pte_tagged(pte)		((pte_val(pte) & PTE_ATTRINDX_MASK) == \
 				 PTE_ATTRINDX(MT_NORMAL_TAGGED))
 
@@ -290,11 +289,6 @@ static inline pmd_t pmd_mkcont(pmd_t pmd)
 	return __pmd(pmd_val(pmd) | PMD_SECT_CONT);
 }
 
-static inline pte_t pte_mkdevmap(pte_t pte)
-{
-	return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL));
-}
-
 #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
 static inline int pte_uffd_wp(pte_t pte)
 {
@@ -587,14 +581,6 @@ static inline int pmd_trans_huge(pmd_t pmd)
 
 #define pmd_mkhuge(pmd)		(__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-#define pmd_devmap(pmd)		pte_devmap(pmd_pte(pmd))
-#endif
-static inline pmd_t pmd_mkdevmap(pmd_t pmd)
-{
-	return pte_pmd(set_pte_bit(pmd_pte(pmd), __pgprot(PTE_DEVMAP)));
-}
-
 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
 #define pmd_special(pte)	(!!((pmd_val(pte) & PTE_SPECIAL)))
 static inline pmd_t pmd_mkspecial(pmd_t pmd)
@@ -1195,16 +1181,6 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
 	return __ptep_set_access_flags(vma, address, (pte_t *)pmdp,
 							pmd_pte(entry), dirty);
 }
-
-static inline int pud_devmap(pud_t pud)
-{
-	return 0;
-}
-
-static inline int pgd_devmap(pgd_t pgd)
-{
-	return 0;
-}
 #endif
 
 #ifdef CONFIG_PAGE_TABLE_CHECK
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index da0ac66..3e85f89 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -147,7 +147,6 @@ config PPC
 	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_HAS_PMEM_API
-	select ARCH_HAS_PTE_DEVMAP		if PPC_BOOK3S_64
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_SCALED_CPUTIME		if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64
 	select ARCH_HAS_SET_MEMORY
diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
index c3efaca..b0546d3 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
@@ -160,12 +160,6 @@ extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
 extern int hash__has_transparent_hugepage(void);
 #endif
 
-static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd)
-{
-	BUG();
-	return pmd;
-}
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h
index 0bf6fd0..0fb5b7d 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-64k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
@@ -259,7 +259,7 @@ static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
  */
 static inline int hash__pmd_trans_huge(pmd_t pmd)
 {
-	return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP)) ==
+	return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE)) ==
 		  (_PAGE_PTE | H_PAGE_THP_HUGE));
 }
 
@@ -281,11 +281,6 @@ extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
 extern int hash__has_transparent_hugepage(void);
 #endif /*  CONFIG_TRANSPARENT_HUGEPAGE */
 
-static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd)
-{
-	return __pmd(pmd_val(pmd) | (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP));
-}
-
 #endif	/* __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 6d98e6f..bda0649 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -88,7 +88,6 @@
 
 #define _PAGE_SOFT_DIRTY	_RPAGE_SW3 /* software: software dirty tracking */
 #define _PAGE_SPECIAL		_RPAGE_SW2 /* software: special page */
-#define _PAGE_DEVMAP		_RPAGE_SW1 /* software: ZONE_DEVICE page */
 
 /*
  * Drivers request for cache inhibited pte mapping using _PAGE_NO_CACHE
@@ -109,7 +108,7 @@
  */
 #define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
 			 _PAGE_ACCESSED | H_PAGE_THP_HUGE | _PAGE_PTE | \
-			 _PAGE_SOFT_DIRTY | _PAGE_DEVMAP)
+			 _PAGE_SOFT_DIRTY)
 /*
  * user access blocked by key
  */
@@ -123,7 +122,7 @@
  */
 #define _PAGE_CHG_MASK	(PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
 			 _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE |	\
-			 _PAGE_SOFT_DIRTY | _PAGE_DEVMAP)
+			 _PAGE_SOFT_DIRTY)
 
 /*
  * We define 2 sets of base prot bits, one for basic pages (ie,
@@ -609,24 +608,6 @@ static inline pte_t pte_mkhuge(pte_t pte)
 	return pte;
 }
 
-static inline pte_t pte_mkdevmap(pte_t pte)
-{
-	return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_SPECIAL | _PAGE_DEVMAP));
-}
-
-/*
- * This is potentially called with a pmd as the argument, in which case it's not
- * safe to check _PAGE_DEVMAP unless we also confirm that _PAGE_PTE is set.
- * That's because the bit we use for _PAGE_DEVMAP is not reserved for software
- * use in page directory entries (ie. non-ptes).
- */
-static inline int pte_devmap(pte_t pte)
-{
-	__be64 mask = cpu_to_be64(_PAGE_DEVMAP | _PAGE_PTE);
-
-	return (pte_raw(pte) & mask) == mask;
-}
-
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
 	/* FIXME!! check whether this need to be a conditional */
@@ -1380,35 +1361,6 @@ static inline bool arch_needs_pgtable_deposit(void)
 }
 extern void serialize_against_pte_lookup(struct mm_struct *mm);
 
-
-static inline pmd_t pmd_mkdevmap(pmd_t pmd)
-{
-	if (radix_enabled())
-		return radix__pmd_mkdevmap(pmd);
-	return hash__pmd_mkdevmap(pmd);
-}
-
-static inline pud_t pud_mkdevmap(pud_t pud)
-{
-	if (radix_enabled())
-		return radix__pud_mkdevmap(pud);
-	BUG();
-	return pud;
-}
-
-static inline int pmd_devmap(pmd_t pmd)
-{
-	return pte_devmap(pmd_pte(pmd));
-}
-
-static inline int pud_devmap(pud_t pud)
-{
-	return pte_devmap(pud_pte(pud));
-}
-
-static inline int pgd_devmap(pgd_t pgd)
-{
-	return 0;
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index 8f55ff7..df23a82 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -264,7 +264,7 @@ static inline int radix__p4d_bad(p4d_t p4d)
 
 static inline int radix__pmd_trans_huge(pmd_t pmd)
 {
-	return (pmd_val(pmd) & (_PAGE_PTE | _PAGE_DEVMAP)) == _PAGE_PTE;
+	return (pmd_val(pmd) & _PAGE_PTE) == _PAGE_PTE;
 }
 
 static inline pmd_t radix__pmd_mkhuge(pmd_t pmd)
@@ -274,7 +274,7 @@ static inline pmd_t radix__pmd_mkhuge(pmd_t pmd)
 
 static inline int radix__pud_trans_huge(pud_t pud)
 {
-	return (pud_val(pud) & (_PAGE_PTE | _PAGE_DEVMAP)) == _PAGE_PTE;
+	return (pud_val(pud) & _PAGE_PTE) == _PAGE_PTE;
 }
 
 static inline pud_t radix__pud_mkhuge(pud_t pud)
@@ -315,16 +315,6 @@ static inline int radix__has_transparent_pud_hugepage(void)
 }
 #endif
 
-static inline pmd_t radix__pmd_mkdevmap(pmd_t pmd)
-{
-	return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP));
-}
-
-static inline pud_t radix__pud_mkdevmap(pud_t pud)
-{
-	return __pud(pud_val(pud) | (_PAGE_PTE | _PAGE_DEVMAP));
-}
-
 struct vmem_altmap;
 struct dev_pagemap;
 extern int __meminit radix__vmemmap_create_mapping(unsigned long start,
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 77f001c..acac373 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -97,7 +97,6 @@ config X86
 	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	select ARCH_HAS_PMEM_API		if X86_64
 	select ARCH_HAS_PREEMPT_LAZY
-	select ARCH_HAS_PTE_DEVMAP		if X86_64
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_HW_PTE_YOUNG
 	select ARCH_HAS_NONLEAF_PMD_YOUNG	if PGTABLE_LEVELS > 2
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 593f10a..77705be 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -308,16 +308,15 @@ static inline bool pmd_leaf(pmd_t pte)
 }
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-/* NOTE: when predicate huge page, consider also pmd_devmap, or use pmd_leaf */
 static inline int pmd_trans_huge(pmd_t pmd)
 {
-	return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
+	return (pmd_val(pmd) & _PAGE_PSE) == _PAGE_PSE;
 }
 
 #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
 static inline int pud_trans_huge(pud_t pud)
 {
-	return (pud_val(pud) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
+	return (pud_val(pud) & _PAGE_PSE) == _PAGE_PSE;
 }
 #endif
 
@@ -327,24 +326,6 @@ static inline int has_transparent_hugepage(void)
 	return boot_cpu_has(X86_FEATURE_PSE);
 }
 
-#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
-static inline int pmd_devmap(pmd_t pmd)
-{
-	return !!(pmd_val(pmd) & _PAGE_DEVMAP);
-}
-
-#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
-static inline int pud_devmap(pud_t pud)
-{
-	return !!(pud_val(pud) & _PAGE_DEVMAP);
-}
-#else
-static inline int pud_devmap(pud_t pud)
-{
-	return 0;
-}
-#endif
-
 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
 static inline bool pmd_special(pmd_t pmd)
 {
@@ -368,12 +349,6 @@ static inline pud_t pud_mkspecial(pud_t pud)
 	return pud_set_flags(pud, _PAGE_SPECIAL);
 }
 #endif	/* CONFIG_ARCH_SUPPORTS_PUD_PFNMAP */
-
-static inline int pgd_devmap(pgd_t pgd)
-{
-	return 0;
-}
-#endif
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
 static inline pte_t pte_set_flags(pte_t pte, pteval_t set)
@@ -534,11 +509,6 @@ static inline pte_t pte_mkspecial(pte_t pte)
 	return pte_set_flags(pte, _PAGE_SPECIAL);
 }
 
-static inline pte_t pte_mkdevmap(pte_t pte)
-{
-	return pte_set_flags(pte, _PAGE_SPECIAL|_PAGE_DEVMAP);
-}
-
 /* See comments above mksaveddirty_shift() */
 static inline pmd_t pmd_mksaveddirty(pmd_t pmd)
 {
@@ -610,11 +580,6 @@ static inline pmd_t pmd_mkwrite_shstk(pmd_t pmd)
 	return pmd_set_flags(pmd, _PAGE_DIRTY);
 }
 
-static inline pmd_t pmd_mkdevmap(pmd_t pmd)
-{
-	return pmd_set_flags(pmd, _PAGE_DEVMAP);
-}
-
 static inline pmd_t pmd_mkhuge(pmd_t pmd)
 {
 	return pmd_set_flags(pmd, _PAGE_PSE);
@@ -680,11 +645,6 @@ static inline pud_t pud_mkdirty(pud_t pud)
 	return pud_mksaveddirty(pud);
 }
 
-static inline pud_t pud_mkdevmap(pud_t pud)
-{
-	return pud_set_flags(pud, _PAGE_DEVMAP);
-}
-
 static inline pud_t pud_mkhuge(pud_t pud)
 {
 	return pud_set_flags(pud, _PAGE_PSE);
@@ -1012,13 +972,6 @@ static inline int pte_present(pte_t a)
 	return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE);
 }
 
-#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
-static inline int pte_devmap(pte_t a)
-{
-	return (pte_flags(a) & _PAGE_DEVMAP) == _PAGE_DEVMAP;
-}
-#endif
-
 #define pte_accessible pte_accessible
 static inline bool pte_accessible(struct mm_struct *mm, pte_t a)
 {
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 4b80453..e4c7b51 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -33,7 +33,6 @@
 #define _PAGE_BIT_CPA_TEST	_PAGE_BIT_SOFTW1
 #define _PAGE_BIT_UFFD_WP	_PAGE_BIT_SOFTW2 /* userfaultfd wrprotected */
 #define _PAGE_BIT_SOFT_DIRTY	_PAGE_BIT_SOFTW3 /* software dirty tracking */
-#define _PAGE_BIT_DEVMAP	_PAGE_BIT_SOFTW4
 
 #ifdef CONFIG_X86_64
 #define _PAGE_BIT_SAVED_DIRTY	_PAGE_BIT_SOFTW5 /* Saved Dirty bit (leaf) */
@@ -119,11 +118,9 @@
 
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
 #define _PAGE_NX	(_AT(pteval_t, 1) << _PAGE_BIT_NX)
-#define _PAGE_DEVMAP	(_AT(u64, 1) << _PAGE_BIT_DEVMAP)
 #define _PAGE_SOFTW4	(_AT(pteval_t, 1) << _PAGE_BIT_SOFTW4)
 #else
 #define _PAGE_NX	(_AT(pteval_t, 0))
-#define _PAGE_DEVMAP	(_AT(pteval_t, 0))
 #define _PAGE_SOFTW4	(_AT(pteval_t, 0))
 #endif
 
@@ -152,7 +149,7 @@
 #define _COMMON_PAGE_CHG_MASK	(PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT |	\
 				 _PAGE_SPECIAL | _PAGE_ACCESSED |	\
 				 _PAGE_DIRTY_BITS | _PAGE_SOFT_DIRTY |	\
-				 _PAGE_DEVMAP | _PAGE_CC | _PAGE_UFFD_WP)
+				 _PAGE_CC | _PAGE_UFFD_WP)
 #define _PAGE_CHG_MASK	(_COMMON_PAGE_CHG_MASK | _PAGE_PAT)
 #define _HPAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PSE | _PAGE_PAT_LARGE)
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index a734278..23c4e9b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2769,13 +2769,6 @@ static inline pud_t pud_mkspecial(pud_t pud)
 }
 #endif	/* CONFIG_ARCH_SUPPORTS_PUD_PFNMAP */
 
-#ifndef CONFIG_ARCH_HAS_PTE_DEVMAP
-static inline int pte_devmap(pte_t pte)
-{
-	return 0;
-}
-#endif
-
 extern pte_t *__get_locked_pte(struct mm_struct *mm, unsigned long addr,
 			       spinlock_t **ptl);
 static inline pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr,
diff --git a/include/linux/pfn_t.h b/include/linux/pfn_t.h
index 2d91482..0100ad8 100644
--- a/include/linux/pfn_t.h
+++ b/include/linux/pfn_t.h
@@ -97,26 +97,6 @@ static inline pud_t pfn_t_pud(pfn_t pfn, pgprot_t pgprot)
 #endif
 #endif
 
-#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
-static inline bool pfn_t_devmap(pfn_t pfn)
-{
-	const u64 flags = PFN_DEV|PFN_MAP;
-
-	return (pfn.val & flags) == flags;
-}
-#else
-static inline bool pfn_t_devmap(pfn_t pfn)
-{
-	return false;
-}
-pte_t pte_mkdevmap(pte_t pte);
-pmd_t pmd_mkdevmap(pmd_t pmd);
-#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \
-	defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
-pud_t pud_mkdevmap(pud_t pud);
-#endif
-#endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
-
 #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL
 static inline bool pfn_t_special(pfn_t pfn)
 {
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 00e4a06..1c377de 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -1606,21 +1606,6 @@ static inline int pud_write(pud_t pud)
 }
 #endif /* pud_write */
 
-#if !defined(CONFIG_ARCH_HAS_PTE_DEVMAP) || !defined(CONFIG_TRANSPARENT_HUGEPAGE)
-static inline int pmd_devmap(pmd_t pmd)
-{
-	return 0;
-}
-static inline int pud_devmap(pud_t pud)
-{
-	return 0;
-}
-static inline int pgd_devmap(pgd_t pgd)
-{
-	return 0;
-}
-#endif
-
 #if !defined(CONFIG_TRANSPARENT_HUGEPAGE) || \
 	!defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
 static inline int pud_trans_huge(pud_t pud)
@@ -1875,8 +1860,8 @@ typedef unsigned int pgtbl_mod_mask;
  * - It should contain a huge PFN, which points to a huge page larger than
  *   PAGE_SIZE of the platform.  The PFN format isn't important here.
  *
- * - It should cover all kinds of huge mappings (e.g., pXd_trans_huge(),
- *   pXd_devmap(), or hugetlb mappings).
+ * - It should cover all kinds of huge mappings (i.e. pXd_trans_huge()
+ *   or hugetlb mappings).
  */
 #ifndef pgd_leaf
 #define pgd_leaf(x)	false
diff --git a/mm/Kconfig b/mm/Kconfig
index 7949ab1..e1d0981 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1044,9 +1044,6 @@ config ARCH_HAS_CURRENT_STACK_POINTER
 	  register alias named "current_stack_pointer", this config can be
 	  selected.
 
-config ARCH_HAS_PTE_DEVMAP
-	bool
-
 config ARCH_HAS_ZONE_DMA_SET
 	bool
 
@@ -1064,7 +1061,6 @@ config ZONE_DEVICE
 	depends on MEMORY_HOTPLUG
 	depends on MEMORY_HOTREMOVE
 	depends on SPARSEMEM_VMEMMAP
-	depends on ARCH_HAS_PTE_DEVMAP
 	select XARRAY_MULTI
 
 	help
diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
index bc748f7..cf5ff92 100644
--- a/mm/debug_vm_pgtable.c
+++ b/mm/debug_vm_pgtable.c
@@ -348,12 +348,6 @@ static void __init pud_advanced_tests(struct pgtable_debug_args *args)
 	vaddr &= HPAGE_PUD_MASK;
 
 	pud = pfn_pud(args->pud_pfn, args->page_prot);
-	/*
-	 * Some architectures have debug checks to make sure
-	 * huge pud mapping are only found with devmap entries
-	 * For now test with only devmap entries.
-	 */
-	pud = pud_mkdevmap(pud);
 	set_pud_at(args->mm, vaddr, args->pudp, pud);
 	flush_dcache_page(page);
 	pudp_set_wrprotect(args->mm, vaddr, args->pudp);
@@ -366,7 +360,6 @@ static void __init pud_advanced_tests(struct pgtable_debug_args *args)
 	WARN_ON(!pud_none(pud));
 #endif /* __PAGETABLE_PMD_FOLDED */
 	pud = pfn_pud(args->pud_pfn, args->page_prot);
-	pud = pud_mkdevmap(pud);
 	pud = pud_wrprotect(pud);
 	pud = pud_mkclean(pud);
 	set_pud_at(args->mm, vaddr, args->pudp, pud);
@@ -384,7 +377,6 @@ static void __init pud_advanced_tests(struct pgtable_debug_args *args)
 #endif /* __PAGETABLE_PMD_FOLDED */
 
 	pud = pfn_pud(args->pud_pfn, args->page_prot);
-	pud = pud_mkdevmap(pud);
 	pud = pud_mkyoung(pud);
 	set_pud_at(args->mm, vaddr, args->pudp, pud);
 	flush_dcache_page(page);
@@ -693,53 +685,6 @@ static void __init pmd_protnone_tests(struct pgtable_debug_args *args)
 static void __init pmd_protnone_tests(struct pgtable_debug_args *args) { }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
-#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
-static void __init pte_devmap_tests(struct pgtable_debug_args *args)
-{
-	pte_t pte = pfn_pte(args->fixed_pte_pfn, args->page_prot);
-
-	pr_debug("Validating PTE devmap\n");
-	WARN_ON(!pte_devmap(pte_mkdevmap(pte)));
-}
-
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-static void __init pmd_devmap_tests(struct pgtable_debug_args *args)
-{
-	pmd_t pmd;
-
-	if (!has_transparent_hugepage())
-		return;
-
-	pr_debug("Validating PMD devmap\n");
-	pmd = pfn_pmd(args->fixed_pmd_pfn, args->page_prot);
-	WARN_ON(!pmd_devmap(pmd_mkdevmap(pmd)));
-}
-
-#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
-static void __init pud_devmap_tests(struct pgtable_debug_args *args)
-{
-	pud_t pud;
-
-	if (!has_transparent_pud_hugepage())
-		return;
-
-	pr_debug("Validating PUD devmap\n");
-	pud = pfn_pud(args->fixed_pud_pfn, args->page_prot);
-	WARN_ON(!pud_devmap(pud_mkdevmap(pud)));
-}
-#else  /* !CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
-static void __init pud_devmap_tests(struct pgtable_debug_args *args) { }
-#endif /* CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
-#else  /* CONFIG_TRANSPARENT_HUGEPAGE */
-static void __init pmd_devmap_tests(struct pgtable_debug_args *args) { }
-static void __init pud_devmap_tests(struct pgtable_debug_args *args) { }
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-#else
-static void __init pte_devmap_tests(struct pgtable_debug_args *args) { }
-static void __init pmd_devmap_tests(struct pgtable_debug_args *args) { }
-static void __init pud_devmap_tests(struct pgtable_debug_args *args) { }
-#endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
-
 static void __init pte_soft_dirty_tests(struct pgtable_debug_args *args)
 {
 	pte_t pte = pfn_pte(args->fixed_pte_pfn, args->page_prot);
@@ -1341,10 +1286,6 @@ static int __init debug_vm_pgtable(void)
 	pte_protnone_tests(&args);
 	pmd_protnone_tests(&args);
 
-	pte_devmap_tests(&args);
-	pmd_devmap_tests(&args);
-	pud_devmap_tests(&args);
-
 	pte_soft_dirty_tests(&args);
 	pmd_soft_dirty_tests(&args);
 	pte_swap_soft_dirty_tests(&args);
diff --git a/mm/hmm.c b/mm/hmm.c
index 285578e..2a12879 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -395,8 +395,7 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp,
 	return 0;
 }
 
-#if defined(CONFIG_ARCH_HAS_PTE_DEVMAP) && \
-    defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
+#if defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
 static inline unsigned long pud_to_hmm_pfn_flags(struct hmm_range *range,
 						 pud_t pud)
 {
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:13:08 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:13:08 +1100
Subject: [PATCH v4 25/25] Revert "riscv: mm: Add support for ZONE_DEVICE"
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <f6340f6527b6eca57ba423e3159818eb63d3a165.1734407924.git-series.apopple@nvidia.com>

DEVMAP PTEs are no longer required to support ZONE_DEVICE so remove
them.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Suggested-by: Chunyan Zhang <zhang.lyra at gmail.com>
Reviewed-by: Bj?rn T?pel <bjorn at rivosinc.com>
---
 arch/riscv/Kconfig                    |  1 -
 arch/riscv/include/asm/pgtable-64.h   | 20 --------------------
 arch/riscv/include/asm/pgtable-bits.h |  1 -
 arch/riscv/include/asm/pgtable.h      | 17 -----------------
 4 files changed, 39 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 7d57186..c285250 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -43,7 +43,6 @@ config RISCV
 	select ARCH_HAS_PMEM_API
 	select ARCH_HAS_PREEMPT_LAZY
 	select ARCH_HAS_PREPARE_SYNC_CORE_CMD
-	select ARCH_HAS_PTE_DEVMAP if 64BIT && MMU
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_SET_DIRECT_MAP if MMU
 	select ARCH_HAS_SET_MEMORY if MMU
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 0897dd9..8c36a88 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -398,24 +398,4 @@ static inline struct page *pgd_page(pgd_t pgd)
 #define p4d_offset p4d_offset
 p4d_t *p4d_offset(pgd_t *pgd, unsigned long address);
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-static inline int pte_devmap(pte_t pte);
-static inline pte_t pmd_pte(pmd_t pmd);
-
-static inline int pmd_devmap(pmd_t pmd)
-{
-	return pte_devmap(pmd_pte(pmd));
-}
-
-static inline int pud_devmap(pud_t pud)
-{
-	return 0;
-}
-
-static inline int pgd_devmap(pgd_t pgd)
-{
-	return 0;
-}
-#endif
-
 #endif /* _ASM_RISCV_PGTABLE_64_H */
diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
index a8f5205..179bd4a 100644
--- a/arch/riscv/include/asm/pgtable-bits.h
+++ b/arch/riscv/include/asm/pgtable-bits.h
@@ -19,7 +19,6 @@
 #define _PAGE_SOFT      (3 << 8)    /* Reserved for software */
 
 #define _PAGE_SPECIAL   (1 << 8)    /* RSW: 0x1 */
-#define _PAGE_DEVMAP    (1 << 9)    /* RSW, devmap */
 #define _PAGE_TABLE     _PAGE_PRESENT
 
 /*
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index d4e99ee..9fa9d13 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -399,13 +399,6 @@ static inline int pte_special(pte_t pte)
 	return pte_val(pte) & _PAGE_SPECIAL;
 }
 
-#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
-static inline int pte_devmap(pte_t pte)
-{
-	return pte_val(pte) & _PAGE_DEVMAP;
-}
-#endif
-
 /* static inline pte_t pte_rdprotect(pte_t pte) */
 
 static inline pte_t pte_wrprotect(pte_t pte)
@@ -447,11 +440,6 @@ static inline pte_t pte_mkspecial(pte_t pte)
 	return __pte(pte_val(pte) | _PAGE_SPECIAL);
 }
 
-static inline pte_t pte_mkdevmap(pte_t pte)
-{
-	return __pte(pte_val(pte) | _PAGE_DEVMAP);
-}
-
 static inline pte_t pte_mkhuge(pte_t pte)
 {
 	return pte;
@@ -763,11 +751,6 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd)
 	return pte_pmd(pte_mkdirty(pmd_pte(pmd)));
 }
 
-static inline pmd_t pmd_mkdevmap(pmd_t pmd)
-{
-	return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
-}
-
 static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
 				pmd_t *pmdp, pmd_t pmd)
 {
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:20:21 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:20:21 +1100
Subject: [PATCH v3 00/25] fs/dax: Fix ZONE_DEVICE page reference counts
In-Reply-To: <20241215222655.ef0b15148120a2e2b06b2234@linux-foundation.org>
References: <cover.e1ebdd6cab9bde0d232c1810deacf0bae25e6707.1732239628.git-series.apopple@nvidia.com>
 <675ce1e5a3d68_fad0294d0@dwillia2-xfh.jf.intel.com.notmuch>
 <45555f72-e82a-4196-94af-22d05d6ac947@redhat.com>
 <wysuus23bqmjtwkfu3zutqtmkse3ki3erf45x32yezlrl24qto@xlqt7qducyld>
 <20241215222655.ef0b15148120a2e2b06b2234@linux-foundation.org>
Message-ID: <jn3j4pdzfnlai4oqr4g7ldl6cq6awiyugg5gbny3l3g5y67abe@rm6zpap7y2gh>

On Sun, Dec 15, 2024 at 10:26:55PM -0800, Andrew Morton wrote:
> On Mon, 16 Dec 2024 11:55:30 +1100 Alistair Popple <apopple at nvidia.com> wrote:
> 
> > The remainder are more -mm focussed. However they do depend on the fs/dax
> > cleanups in the first half so the trick would be making sure Andrew only takes
> > them if the nvdimm.git changes have made it into -next. I'm happy with either
> > approach, so let me know if I should split the series or not.
> 
> My inclination is to put it all into the nvdimm tree, with appropriate
> MM developer acks.
> 
> But I'm having difficulty determining how practical that is because the
> v3 series is almost a month old so my test merging was quite ugly.
> 
> Perhaps you could prepare a new-doesn't-need-to-be-final version for
> people to look at and to aid with this head-scratching?

I have just sent a new-maybe-almost-final v4 rebased on top of next-20241216 to
help with the head-scratching. I haven't yet done extensive build tests or a full
xfs-test run on it yet because it sounded better to get it out sooner. So no doubt
the kernel build bot will find some fat finger of mine somewhere :-)

That said the rebase wasn't awful so let me know if it should be rebased on a
different tree.

 - Alistair


From krzk at kernel.org  Mon Dec 16 21:24:49 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 06:24:49 +0100
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
 <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
Message-ID: <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>

On 16/12/2024 21:59, Ivaylo Ivanov wrote:
> On 12/16/24 10:44, Krzysztof Kozlowski wrote:
>> On 14/12/2024 23:04, Ivaylo Ivanov wrote:
>>> Add samsung,exynos8895-hsi2c dedicated compatible for representing
>>> I2C of Exynos8895 SoC. Since there are I2C buses that aren't implemented
>>> as a part of USIv1 blocks, they only require a single clock.
>>>
>>> Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
>>> ---
>>>  .../devicetree/bindings/i2c/i2c-exynos5.yaml  | 26 ++++++++++++++++---
>>>  1 file changed, 23 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
>>> index cc8bba553..b029be88e 100644
>>> --- a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
>>> +++ b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
>>> @@ -25,6 +25,7 @@ properties:
>>>            - samsung,exynos5250-hsi2c    # Exynos5250 and Exynos5420
>>>            - samsung,exynos5260-hsi2c    # Exynos5260
>>>            - samsung,exynos7-hsi2c       # Exynos7
>>> +          - samsung,exynos8895-hsi2c
>>>            - samsung,exynosautov9-hsi2c
>>>        - items:
>>>            - enum:
>>> @@ -94,9 +95,28 @@ allOf:
>>>          - clock-names
>>>  
>>>      else:
>>> -      properties:
>>> -        clocks:
>>> -          maxItems: 1
>>> +      if:
>>> +        properties:
>>> +          compatible:
>>> +            contains:
>>> +              enum:
>>> +                - samsung,exynos8895-hsi2c
>>> +
>>> +      then:
>>> +        properties:
>>> +          clocks:
>> Missing minItems
>>
>>> +            maxItems: 2
>>> +
>>> +          clock-names:
>> Ditto
>>
>>> +            maxItems: 2
>>> +
>>> +        required:
>>> +          - clock-names
>> I don't understand why do you need second, same branch in if, basically
> 
> Because, as I stated in the commit message, we have HSI2C controllers
> both implemented in USIv1 blocks and outside. These that are a part of

On Exynos8895? Where? With the same compatible?

> USIv1 need 2 clocks, and those that aren't have only one. So it's not
> a duplicate for the previous - autov9 sets a minitems of 2 and the
> others have a maxitems of 1.

We talk here about branch that says 2 items. You duplicate that one.

Best regards,
Krzysztof


From charlie at rivosinc.com  Mon Dec 16 21:30:39 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 21:30:39 -0800
Subject: [PATCH v2 02/16] perf tools: arc: Support generic syscall headers
In-Reply-To: <Z1zIlKq19lAXMoGs@google.com>
References: <20241212-perf_syscalltbl-v2-0-f8ca984ffe40@rivosinc.com>
 <20241212-perf_syscalltbl-v2-2-f8ca984ffe40@rivosinc.com>
 <Z1zIlKq19lAXMoGs@google.com>
Message-ID: <Z2EMf8_oShdXHyL1@ghost>

On Fri, Dec 13, 2024 at 03:51:48PM -0800, Namhyung Kim wrote:
> On Thu, Dec 12, 2024 at 04:32:52PM -0800, Charlie Jenkins wrote:
> > Arc uses the generic syscall table, use that in perf instead of
> > requiring libaudit.
> > 
> > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > ---
> >  tools/perf/Makefile.config                           | 2 +-
> >  tools/perf/Makefile.perf                             | 2 +-
> >  tools/perf/arch/arc/entry/syscalls/Kbuild            | 2 ++
> >  tools/perf/arch/arc/entry/syscalls/Makefile.syscalls | 3 +++
> >  tools/perf/arch/arc/include/syscall_table.h          | 2 ++
> >  5 files changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> > index a72f25162714f0117a88d94474da336814d4f030..3959a9c9972999f6d1bb85e8c1d7dc5dce92fd09 100644
> > --- a/tools/perf/Makefile.config
> > +++ b/tools/perf/Makefile.config
> > @@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
> >    endif
> >  
> >    # architectures that use the generic syscall table scripts
> > -  ifeq ($(SRCARCH),riscv)
> > +  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
> 
> This might work as well.
> 
>   ifneq ($(filter $(SRCARCH), riscv arc),)
> 
> And maybe you can add a variable for supported archs.

Yeah I can do that. All of this is just temporary though. The final
patch removes all of this, since this series implements this for every
architecture.

- Charlie

> 
> Thanks,
> Namhyung
> 
> 
> >      NO_SYSCALL_TABLE := 0
> >      CFLAGS += -DGENERIC_SYSCALL_TABLE
> >      CFLAGS += -I$(OUTPUT)/tools/perf/arch/$(SRCARCH)/include/generated
> > diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> > index f5278ed9f778f928436693a14e016c5c3c5171c1..3b463b42b0e3982e74056e672b2ee6adad5a3f0e 100644
> > --- a/tools/perf/Makefile.perf
> > +++ b/tools/perf/Makefile.perf
> > @@ -311,7 +311,7 @@ FEATURE_TESTS := all
> >  endif
> >  endif
> >  # architectures that use the generic syscall table
> > -ifeq ($(SRCARCH),riscv)
> > +ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
> >  include $(srctree)/tools/perf/scripts/Makefile.syscalls
> >  endif
> >  include Makefile.config
> > diff --git a/tools/perf/arch/arc/entry/syscalls/Kbuild b/tools/perf/arch/arc/entry/syscalls/Kbuild
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
> > --- /dev/null
> > +++ b/tools/perf/arch/arc/entry/syscalls/Kbuild
> > @@ -0,0 +1,2 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +syscall-y += syscalls_32.h
> > diff --git a/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..391d30ab7a831b72d2ed3f2e7966fdbf558a9ed7
> > --- /dev/null
> > +++ b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +syscall_abis_32 += arc time32 renameat stat64 rlimit
> > diff --git a/tools/perf/arch/arc/include/syscall_table.h b/tools/perf/arch/arc/include/syscall_table.h
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
> > --- /dev/null
> > +++ b/tools/perf/arch/arc/include/syscall_table.h
> > @@ -0,0 +1,2 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#include <asm/syscalls_32.h>
> > 
> > -- 
> > 2.34.1
> > 


From krzk at kernel.org  Mon Dec 16 21:31:23 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 06:31:23 +0100
Subject: [PATCH] dt-bindings: mfd: atmel,at91sam9260: Convert to json
 schema
In-Reply-To: <92579055-5a46-4f20-b579-123188554a03@microchip.com>
References: <20241211-matrix-v1-1-5ef0104a3af4@microchip.com>
 <dxgqkdo6ulmqfa5vyerwta3vubuy32gzzu2cxfwwtespydfc4b@5wjrno3lgjsp>
 <92579055-5a46-4f20-b579-123188554a03@microchip.com>
Message-ID: <4e4e8a02-5fc1-4b90-ad9d-9f9ec5c8bc61@kernel.org>

On 17/12/2024 06:00, Charan.Pedumuru at microchip.com wrote:
>>
>>> +      - items:
>>> +          - enum:
>>> +              - atmel,at91sam9260-matrix
>>> +              - atmel,at91sam9261-matrix
>>> +              - atmel,at91sam9263-matrix
>>> +              - atmel,at91sam9rl-matrix
>>> +              - atmel,at91sam9g45-matrix
>>> +              - atmel,at91sam9n12-matrix
>>> +              - atmel,at91sam9x5-matrix
>>> +              - atmel,sama5d3-matrix
>>> +          - const: syscon
>>> +      - items:
>>> +          - const: microchip,sam9x60-matrix
>>> +          - const: atmel,at91sam9x5-matrix
>>> +          - const: syscon
>>> +      - items:
>>> +          - const: microchip,sam9x7-matrix
>> So that's just enum with previous group.
> 
> Yes, as both boards have 2 compatibles one after another, I defined them 
> as two different groups to resolve dt_check warnings.

My comment stands. I understand your "Yes" means you will fix it.


Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec 16 21:43:22 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 06:43:22 +0100
Subject: [PATCH v12 2/8] dt-bindings: media: platform: visconti: Add
 Toshiba Visconti Video Input Interface
In-Reply-To: <TY3PR01MB99822E6161ED319B4DE855B492042@TY3PR01MB9982.jpnprd01.prod.outlook.com>
References: <20241125092146.1561901-1-yuji2.ishikawa@toshiba.co.jp>
 <20241125092146.1561901-3-yuji2.ishikawa@toshiba.co.jp>
 <04a7ebf7-2924-4894-bc53-ba77e2f64fae@kernel.org>
 <TY3PR01MB99822E6161ED319B4DE855B492042@TY3PR01MB9982.jpnprd01.prod.outlook.com>
Message-ID: <d5294015-4790-490e-8136-615039a5c733@kernel.org>

On 17/12/2024 01:00, yuji2.ishikawa at toshiba.co.jp wrote:
> Hello Krzysztof
> 
> Thank you for your review
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski <krzk at kernel.org>
>> Sent: Monday, November 25, 2024 7:08 PM
>> To: ishikawa yuji(?? ?? ?????????????)
>> <yuji2.ishikawa at toshiba.co.jp>; Laurent Pinchart
>> <laurent.pinchart at ideasonboard.com>; Mauro Carvalho Chehab
>> <mchehab at kernel.org>; Rob Herring <robh at kernel.org>; Krzysztof Kozlowski
>> <krzk+dt at kernel.org>; Conor Dooley <conor+dt at kernel.org>; Sakari Ailus
>> <sakari.ailus at linux.intel.com>; Hans Verkuil <hverkuil-cisco at xs4all.nl>;
>> iwamatsu nobuhiro(?? ?? ?????????????)
>> <nobuhiro1.iwamatsu at toshiba.co.jp>
>> Cc: linux-media at vger.kernel.org; linux-kernel at vger.kernel.org;
>> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org
>> Subject: Re: [PATCH v12 2/8] dt-bindings: media: platform: visconti: Add
>> Toshiba Visconti Video Input Interface
>>
>> On 25/11/2024 10:21, Yuji Ishikawa wrote:
>>> Adds the Device Tree binding documentation that allows to describe the
>>> Video Input Interface found in Toshiba Visconti SoCs.
>>>
>>> Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
>>> Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
>>
>> Why this tag stayed and other was removed? What was the reason of tag
>> removal?
>>
> 
> The stayed tag is due to internal review.

Did the internal review really happened? How is it that immediately new
version has internal review without any traces?

I have doubts this review happened in the context of reviewer's
statement of oversight.


> The removed tag is due to code's change (split of csi2rx part) after the last review.
> If the code is largely changed following the instruction of another reviewer
> after obtaining the tags, how should the tags be handled?

Drop all reviews and perform reviews on the list.

Such internal review appearing afterwards is rather a proof it you are
adding just the tags to satisfy your process. I have no way to even
verify whether that person performed any reasonable review or maybe just
acked your patch. I cannot even verify that that person understands the
reviewer's statement of oversight.


...

>>>
>>> Changelog v11:
>>> - no change
>>>
>>> Changelog v12:
>>> - remove property "clock-noncontinuous" as VIIF switches both modes
>>> automatically
>>> - remove property "link-frequencies" as VIIF does not use the
>>> information
>>
>> Driver does not use or hardware supports only one frequency?
>>
> 
> My comment was incorrect.
> It should be "Driver does not use the information"

Then this is not that helping. Maybe hardware supports only one frequency?


Best regards,
Krzysztof


From apopple at nvidia.com  Mon Dec 16 21:12:43 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:43 +1100
Subject: [PATCH v4 00/25] fs/dax: Fix ZONE_DEVICE page reference counts
Message-ID: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>

Main updates since v3:
 - Rebased onto next-20241216

 - Fixed a bunch of build breakages reported by John Hubbard and the
   kernel test robot due to various combinations of CONFIG options.

 - Split the rmap changes into a separate patch as suggested by David H.

 - Reworded the description for the P2PDMA change.

Main updates since v2:

 - Rename the DAX specific dax_insert_XXX functions to vmf_insert_XXX
   and have them pass the vmf struct.

 - Seperate out the device DAX changes.

 - Restore the page share mapping counting and associated warnings.

 - Rework truncate to require file-systems to have previously called
   dax_break_layout() to remove the address space mapping for a
   page. This found several bugs which are fixed by the first half of
   the series. The motivation for this was initially to allow the FS
   DAX page-cache mappings to hold a reference on the page.

   However that turned out to be a dead-end (see the comments on patch
   21), but it found several bugs and I think overall it is an
   improvement so I have left it here.

Device and FS DAX pages have always maintained their own page
reference counts without following the normal rules for page reference
counting. In particular pages are considered free when the refcount
hits one rather than zero and refcounts are not added when mapping the
page.

Tracking this requires special PTE bits (PTE_DEVMAP) and a secondary
mechanism for allowing GUP to hold references on the page (see
get_dev_pagemap). However there doesn't seem to be any reason why FS
DAX pages need their own reference counting scheme.

By treating the refcounts on these pages the same way as normal pages
we can remove a lot of special checks. In particular pXd_trans_huge()
becomes the same as pXd_leaf(), although I haven't made that change
here. It also frees up a valuable SW define PTE bit on architectures
that have devmap PTE bits defined.

It also almost certainly allows further clean-up of the devmap managed
functions, but I have left that as a future improvment. It also
enables support for compound ZONE_DEVICE pages which is one of my
primary motivators for doing this work.

Signed-off-by: Alistair Popple <apopple at nvidia.com>

---

Cc: lina at asahilina.net
Cc: zhang.lyra at gmail.com
Cc: gerald.schaefer at linux.ibm.com
Cc: dan.j.williams at intel.com
Cc: vishal.l.verma at intel.com
Cc: dave.jiang at intel.com
Cc: logang at deltatee.com
Cc: bhelgaas at google.com
Cc: jack at suse.cz
Cc: jgg at ziepe.ca
Cc: catalin.marinas at arm.com
Cc: will at kernel.org
Cc: mpe at ellerman.id.au
Cc: npiggin at gmail.com
Cc: dave.hansen at linux.intel.com
Cc: ira.weiny at intel.com
Cc: willy at infradead.org
Cc: djwong at kernel.org
Cc: tytso at mit.edu
Cc: linmiaohe at huawei.com
Cc: david at redhat.com
Cc: peterx at redhat.com
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: nvdimm at lists.linux.dev
Cc: linux-cxl at vger.kernel.org
Cc: linux-fsdevel at vger.kernel.org
Cc: linux-mm at kvack.org
Cc: linux-ext4 at vger.kernel.org
Cc: linux-xfs at vger.kernel.org
Cc: jhubbard at nvidia.com
Cc: hch at lst.de
Cc: david at fromorbit.com

Alistair Popple (25):
  fuse: Fix dax truncate/punch_hole fault path
  fs/dax: Return unmapped busy pages from dax_layout_busy_page_range()
  fs/dax: Don't skip locked entries when scanning entries
  fs/dax: Refactor wait for dax idle page
  fs/dax: Create a common implementation to break DAX layouts
  fs/dax: Always remove DAX page-cache entries when breaking layouts
  fs/dax: Ensure all pages are idle prior to filesystem unmount
  fs/dax: Remove PAGE_MAPPING_DAX_SHARED mapping flag
  mm/gup.c: Remove redundant check for PCI P2PDMA page
  mm/mm_init: Move p2pdma page refcount initialisation to p2pdma
  mm: Allow compound zone device pages
  mm/memory: Enhance insert_page_into_pte_locked() to create writable mappings
  mm/memory: Add vmf_insert_page_mkwrite()
  rmap: Add support for PUD sized mappings to rmap
  huge_memory: Add vmf_insert_folio_pud()
  huge_memory: Add vmf_insert_folio_pmd()
  memremap: Add is_device_dax_page() and is_fsdax_page() helpers
  gup: Don't allow FOLL_LONGTERM pinning of FS DAX pages
  proc/task_mmu: Ignore ZONE_DEVICE pages
  mm/mlock: Skip ZONE_DEVICE PMDs during mlock
  fs/dax: Properly refcount fs dax pages
  device/dax: Properly refcount device dax pages when mapping
  mm: Remove pXX_devmap callers
  mm: Remove devmap related functions and page table bits
  Revert "riscv: mm: Add support for ZONE_DEVICE"

 Documentation/mm/arch_pgtable_helpers.rst     |   6 +-
 arch/arm64/Kconfig                            |   1 +-
 arch/arm64/include/asm/pgtable-prot.h         |   1 +-
 arch/arm64/include/asm/pgtable.h              |  24 +-
 arch/powerpc/Kconfig                          |   1 +-
 arch/powerpc/include/asm/book3s/64/hash-4k.h  |   6 +-
 arch/powerpc/include/asm/book3s/64/hash-64k.h |   7 +-
 arch/powerpc/include/asm/book3s/64/pgtable.h  |  52 +---
 arch/powerpc/include/asm/book3s/64/radix.h    |  14 +-
 arch/powerpc/mm/book3s64/hash_pgtable.c       |   3 +-
 arch/powerpc/mm/book3s64/pgtable.c            |   8 +-
 arch/powerpc/mm/book3s64/radix_pgtable.c      |   5 +-
 arch/powerpc/mm/pgtable.c                     |   2 +-
 arch/riscv/Kconfig                            |   1 +-
 arch/riscv/include/asm/pgtable-64.h           |  20 +-
 arch/riscv/include/asm/pgtable-bits.h         |   1 +-
 arch/riscv/include/asm/pgtable.h              |  17 +-
 arch/x86/Kconfig                              |   1 +-
 arch/x86/include/asm/pgtable.h                |  51 +---
 arch/x86/include/asm/pgtable_types.h          |   5 +-
 drivers/dax/device.c                          |  15 +-
 drivers/gpu/drm/nouveau/nouveau_dmem.c        |   3 +-
 drivers/nvdimm/pmem.c                         |   4 +-
 drivers/pci/p2pdma.c                          |  19 +-
 fs/dax.c                                      | 357 ++++++++++++++-----
 fs/ext4/inode.c                               |  43 +--
 fs/fuse/dax.c                                 |  35 +--
 fs/fuse/virtio_fs.c                           |   3 +-
 fs/proc/task_mmu.c                            |  18 +-
 fs/userfaultfd.c                              |   2 +-
 fs/xfs/xfs_inode.c                            |  40 +-
 fs/xfs/xfs_inode.h                            |   3 +-
 fs/xfs/xfs_super.c                            |  18 +-
 include/linux/dax.h                           |  37 ++-
 include/linux/huge_mm.h                       |  22 +-
 include/linux/memremap.h                      |  28 +-
 include/linux/migrate.h                       |   4 +-
 include/linux/mm.h                            |  40 +--
 include/linux/mm_types.h                      |  14 +-
 include/linux/mmzone.h                        |  12 +-
 include/linux/page-flags.h                    |   6 +-
 include/linux/pfn_t.h                         |  20 +-
 include/linux/pgtable.h                       |  21 +-
 include/linux/rmap.h                          |  15 +-
 lib/test_hmm.c                                |   3 +-
 mm/Kconfig                                    |   4 +-
 mm/debug_vm_pgtable.c                         |  59 +---
 mm/gup.c                                      | 176 +---------
 mm/hmm.c                                      |  12 +-
 mm/huge_memory.c                              | 233 +++++++-----
 mm/internal.h                                 |   2 +-
 mm/khugepaged.c                               |   2 +-
 mm/madvise.c                                  |   8 +-
 mm/mapping_dirty_helpers.c                    |   4 +-
 mm/memory-failure.c                           |   6 +-
 mm/memory.c                                   | 126 ++++---
 mm/memremap.c                                 |  59 +--
 mm/migrate_device.c                           |   9 +-
 mm/mlock.c                                    |   2 +-
 mm/mm_init.c                                  |  23 +-
 mm/mprotect.c                                 |   2 +-
 mm/mremap.c                                   |   5 +-
 mm/page_vma_mapped.c                          |   5 +-
 mm/pagewalk.c                                 |  14 +-
 mm/pgtable-generic.c                          |   7 +-
 mm/rmap.c                                     |  56 +++-
 mm/swap.c                                     |   2 +-
 mm/truncate.c                                 |  16 +-
 mm/userfaultfd.c                              |   5 +-
 mm/vmscan.c                                   |   5 +-
 70 files changed, 922 insertions(+), 928 deletions(-)

base-commit: e25c8d66f6786300b680866c0e0139981273feba
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:44 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:44 +1100
Subject: [PATCH v4 01/25] fuse: Fix dax truncate/punch_hole fault path
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <f20cc2603bd33ee05ec4bc4cc7327cec61119796.1734407924.git-series.apopple@nvidia.com>

FS DAX requires file systems to call into the DAX layout prior to
unlinking inodes to ensure there is no ongoing DMA or other remote
access to the direct mapped page. The fuse file system implements
fuse_dax_break_layouts() to do this which includes a comment
indicating that passing dmap_end == 0 leads to unmapping of the whole
file.

However this is not true - passing dmap_end == 0 will not unmap
anything before dmap_start, and further more
dax_layout_busy_page_range() will not scan any of the range to see if
there maybe ongoing DMA access to the range. Fix this by checking for
dmap_end == 0 in fuse_dax_break_layouts() and pass the entire file
range to dax_layout_busy_page_range().

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Fixes: 6ae330cad6ef ("virtiofs: serialize truncate/punch_hole and dax fault path")
Cc: Vivek Goyal <vgoyal at redhat.com>

---

I am not at all familiar with the fuse file system driver so I have no
idea if the comment is relevant or not and whether the documented
behaviour for dmap_end == 0 is ever relied upon. However this seemed
like the safest fix unless someone more familiar with fuse can confirm
that dmap_end == 0 is never used.
---
 fs/fuse/dax.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/fuse/dax.c b/fs/fuse/dax.c
index 9abbc2f..c5d1fea 100644
--- a/fs/fuse/dax.c
+++ b/fs/fuse/dax.c
@@ -693,6 +693,10 @@ int fuse_dax_break_layouts(struct inode *inode, u64 dmap_start,
 		ret = __fuse_dax_break_layouts(inode, &retry, dmap_start,
 					       dmap_end);
 	} while (ret == 0 && retry);
+	if (!dmap_end) {
+		dmap_start = 0;
+		dmap_end = LLONG_MAX;
+	}
 
 	return ret;
 }
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:45 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:45 +1100
Subject: [PATCH v4 02/25] fs/dax: Return unmapped busy pages from dax_layout_busy_page_range()
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <db02794f12a4cc8c659a1123bdc90fcb4dcb1104.1734407924.git-series.apopple@nvidia.com>

dax_layout_busy_page_range() is used by file systems to scan the DAX
page-cache to unmap mapping pages from user-space and to determine if
any pages in the given range are busy, either due to ongoing DMA or
other get_user_pages() usage.

Currently it checks to see the file mapping is mapped into user-space
with mapping_mapped() and returns early if not, skipping the check for
DMA busy pages. This is wrong as pages may still be undergoing DMA
access even if they have subsequently been unmapped from
user-space. Fix this by dropping the check for mapping_mapped().

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Suggested-by: Dan Williams <dan.j.williams at intel.com>
---
 fs/dax.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/dax.c b/fs/dax.c
index 21b4740..5133568 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -690,7 +690,7 @@ struct page *dax_layout_busy_page_range(struct address_space *mapping,
 	if (IS_ENABLED(CONFIG_FS_DAX_LIMITED))
 		return NULL;
 
-	if (!dax_mapping(mapping) || !mapping_mapped(mapping))
+	if (!dax_mapping(mapping))
 		return NULL;
 
 	/* If end == LLONG_MAX, all pages from start to till end of file */
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:46 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:46 +1100
Subject: [PATCH v4 03/25] fs/dax: Don't skip locked entries when scanning entries
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <6d25aaaadc853ffb759d538392ff48ed108e3d50.1734407924.git-series.apopple@nvidia.com>

Several functions internal to FS DAX use the following pattern when
trying to obtain an unlocked entry:

    xas_for_each(&xas, entry, end_idx) {
	if (dax_is_locked(entry))
	    entry = get_unlocked_entry(&xas, 0);

This is problematic because get_unlocked_entry() will get the next
present entry in the range, and the next entry may not be
locked. Therefore any processing of the original locked entry will be
skipped. This can cause dax_layout_busy_page_range() to miss DMA-busy
pages in the range, leading file systems to free blocks whilst DMA
operations are ongoing which can lead to file system corruption.

Instead callers from within a xas_for_each() loop should be waiting
for the current entry to be unlocked without advancing the XArray
state so a new function is introduced to wait.

Also while we are here rename get_unlocked_entry() to
get_next_unlocked_entry() to make it clear that it may advance the
iterator state.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
---
 fs/dax.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/fs/dax.c b/fs/dax.c
index 5133568..d010c10 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -206,7 +206,7 @@ static void dax_wake_entry(struct xa_state *xas, void *entry,
  *
  * Must be called with the i_pages lock held.
  */
-static void *get_unlocked_entry(struct xa_state *xas, unsigned int order)
+static void *get_next_unlocked_entry(struct xa_state *xas, unsigned int order)
 {
 	void *entry;
 	struct wait_exceptional_entry_queue ewait;
@@ -236,6 +236,37 @@ static void *get_unlocked_entry(struct xa_state *xas, unsigned int order)
 }
 
 /*
+ * Wait for the given entry to become unlocked. Caller must hold the i_pages
+ * lock and call either put_unlocked_entry() if it did not lock the entry or
+ * dax_unlock_entry() if it did. Returns an unlocked entry if still present.
+ */
+static void *wait_entry_unlocked_exclusive(struct xa_state *xas, void *entry)
+{
+	struct wait_exceptional_entry_queue ewait;
+	wait_queue_head_t *wq;
+
+	init_wait(&ewait.wait);
+	ewait.wait.func = wake_exceptional_entry_func;
+
+	while (unlikely(dax_is_locked(entry))) {
+		wq = dax_entry_waitqueue(xas, entry, &ewait.key);
+		prepare_to_wait_exclusive(wq, &ewait.wait,
+					TASK_UNINTERRUPTIBLE);
+		xas_pause(xas);
+		xas_unlock_irq(xas);
+		schedule();
+		finish_wait(wq, &ewait.wait);
+		xas_lock_irq(xas);
+		entry = xas_load(xas);
+	}
+
+	if (xa_is_internal(entry))
+		return NULL;
+
+	return entry;
+}
+
+/*
  * The only thing keeping the address space around is the i_pages lock
  * (it's cycled in clear_inode() after removing the entries from i_pages)
  * After we call xas_unlock_irq(), we cannot touch xas->xa.
@@ -250,7 +281,7 @@ static void wait_entry_unlocked(struct xa_state *xas, void *entry)
 
 	wq = dax_entry_waitqueue(xas, entry, &ewait.key);
 	/*
-	 * Unlike get_unlocked_entry() there is no guarantee that this
+	 * Unlike get_next_unlocked_entry() there is no guarantee that this
 	 * path ever successfully retrieves an unlocked entry before an
 	 * inode dies. Perform a non-exclusive wait in case this path
 	 * never successfully performs its own wake up.
@@ -580,7 +611,7 @@ static void *grab_mapping_entry(struct xa_state *xas,
 retry:
 	pmd_downgrade = false;
 	xas_lock_irq(xas);
-	entry = get_unlocked_entry(xas, order);
+	entry = get_next_unlocked_entry(xas, order);
 
 	if (entry) {
 		if (dax_is_conflict(entry))
@@ -716,8 +747,7 @@ struct page *dax_layout_busy_page_range(struct address_space *mapping,
 	xas_for_each(&xas, entry, end_idx) {
 		if (WARN_ON_ONCE(!xa_is_value(entry)))
 			continue;
-		if (unlikely(dax_is_locked(entry)))
-			entry = get_unlocked_entry(&xas, 0);
+		entry = wait_entry_unlocked_exclusive(&xas, entry);
 		if (entry)
 			page = dax_busy_page(entry);
 		put_unlocked_entry(&xas, entry, WAKE_NEXT);
@@ -750,7 +780,7 @@ static int __dax_invalidate_entry(struct address_space *mapping,
 	void *entry;
 
 	xas_lock_irq(&xas);
-	entry = get_unlocked_entry(&xas, 0);
+	entry = get_next_unlocked_entry(&xas, 0);
 	if (!entry || WARN_ON_ONCE(!xa_is_value(entry)))
 		goto out;
 	if (!trunc &&
@@ -776,7 +806,9 @@ static int __dax_clear_dirty_range(struct address_space *mapping,
 
 	xas_lock_irq(&xas);
 	xas_for_each(&xas, entry, end) {
-		entry = get_unlocked_entry(&xas, 0);
+		entry = wait_entry_unlocked_exclusive(&xas, entry);
+		if (!entry)
+			continue;
 		xas_clear_mark(&xas, PAGECACHE_TAG_DIRTY);
 		xas_clear_mark(&xas, PAGECACHE_TAG_TOWRITE);
 		put_unlocked_entry(&xas, entry, WAKE_NEXT);
@@ -940,7 +972,7 @@ static int dax_writeback_one(struct xa_state *xas, struct dax_device *dax_dev,
 	if (unlikely(dax_is_locked(entry))) {
 		void *old_entry = entry;
 
-		entry = get_unlocked_entry(xas, 0);
+		entry = get_next_unlocked_entry(xas, 0);
 
 		/* Entry got punched out / reallocated? */
 		if (!entry || WARN_ON_ONCE(!xa_is_value(entry)))
@@ -1949,7 +1981,7 @@ dax_insert_pfn_mkwrite(struct vm_fault *vmf, pfn_t pfn, unsigned int order)
 	vm_fault_t ret;
 
 	xas_lock_irq(&xas);
-	entry = get_unlocked_entry(&xas, order);
+	entry = get_next_unlocked_entry(&xas, order);
 	/* Did we race with someone splitting entry or so? */
 	if (!entry || dax_is_conflict(entry) ||
 	    (order == 0 && !dax_is_pte_entry(entry))) {
-- 
git-series 0.9.1


From apopple at nvidia.com  Mon Dec 16 21:12:47 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Tue, 17 Dec 2024 16:12:47 +1100
Subject: [PATCH v4 04/25] fs/dax: Refactor wait for dax idle page
In-Reply-To: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
Message-ID: <62a85767a21fb76b548801a002a85c7831e8e25c.1734407924.git-series.apopple@nvidia.com>

A FS DAX page is considered idle when its refcount drops to one. This
is currently open-coded in all file systems supporting FS DAX. Move
the idle detection to a common function to make future changes easier.

Signed-off-by: Alistair Popple <apopple at nvidia.com>
Reviewed-by: Jan Kara <jack at suse.cz>
Reviewed-by: Christoph Hellwig <hch at lst.de>
Reviewed-by: Dan Williams <dan.j.williams at intel.com>
Acked-by: Theodore Ts'o <tytso at mit.edu>
---
 fs/ext4/inode.c     | 5 +----
 fs/fuse/dax.c       | 4 +---
 fs/xfs/xfs_inode.c  | 4 +---
 include/linux/dax.h | 8 ++++++++
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 7c54ae5..cc1acb1 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3922,10 +3922,7 @@ int ext4_break_layouts(struct inode *inode)
 		if (!page)
 			return 0;
 
-		error = ___wait_var_event(&page->_refcount,
-				atomic_read(&page->_refcount) == 1,
-				TASK_INTERRUPTIBLE, 0, 0,
-				ext4_wait_dax_page(inode));
+		error = dax_wait_page_idle(page, ext4_wait_dax_page, inode);
 	} while (error == 0);
 
 	return error;
diff --git a/fs/fuse/dax.c b/fs/fuse/dax.c
index c5d1fea..d156c55 100644
--- a/fs/fuse/dax.c
+++ b/fs/fuse/dax.c
@@ -676,9 +676,7 @@ static int __fuse_dax_break_layouts(struct inode *inode, bool *retry,
 		return 0;
 
 	*retry = true;
-	return ___wait_var_event(&page->_refcount,
-			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
-			0, 0, fuse_wait_dax_page(inode));
+	return dax_wait_page_idle(page, fuse_wait_dax_page, inode);
 }
 
 /* dmap_end == 0 leads to unmapping of whole file */
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index c8ad260..42ea203 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -3000,9 +3000,7 @@ xfs_break_dax_layouts(
 		return 0;
 
 	*retry = true;
-	return ___wait_var_event(&page->_refcount,
-			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
-			0, 0, xfs_wait_dax_page(inode));
+	return dax_wait_page_idle(page, xfs_wait_dax_page, inode);
 }
 
 int
diff --git a/include/linux/dax.h b/include/linux/dax.h
index df41a00..9b1ce98 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -207,6 +207,14 @@ int dax_zero_range(struct inode *inode, loff_t pos, loff_t len, bool *did_zero,
 int dax_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,
 		const struct iomap_ops *ops);
 
+static inline int dax_wait_page_idle(struct page *page,
+				void (cb)(struct inode *),
+				struct inode *inode)
+{
+	return ___wait_var_event(page, page_ref_count(page) == 1,
+				TASK_INTERRUPTIBLE, 0, 0, cb(inode));
+}
+
 #if IS_ENABLED(CONFIG_DAX)
 int dax_read_lock(void);
 void dax_read_unlock(int id);
-- 
git-series 0.9.1


From krzk at kernel.org  Mon Dec 16 21:44:58 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 06:44:58 +0100
Subject: [PATCH v12 1/8] dt-bindings: media: platform: visconti: Add
 Toshiba Visconti MIPI CSI-2 Receiver
In-Reply-To: <TY3PR01MB9982FE7739FABB2275C79C0B923B2@TY3PR01MB9982.jpnprd01.prod.outlook.com>
References: <20241125092146.1561901-1-yuji2.ishikawa@toshiba.co.jp>
 <20241125092146.1561901-2-yuji2.ishikawa@toshiba.co.jp>
 <07e0cc97-c0c4-42fd-b51d-87b0eaed4e4a@kernel.org>
 <TY3PR01MB9982FE7739FABB2275C79C0B923B2@TY3PR01MB9982.jpnprd01.prod.outlook.com>
Message-ID: <cb6be804-1649-4d17-839c-fe58a39baa1d@kernel.org>

On 17/12/2024 00:57, yuji2.ishikawa at toshiba.co.jp wrote:
>> On 25/11/2024 10:21, Yuji Ishikawa wrote:
>>> Adds the Device Tree binding documentation that allows to describe the
>>> MIPI CSI-2 Receiver found in Toshiba Visconti SoCs.
>>>
>>> Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
>>> Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
>>
>>
>> How newly added patch can have already Rb tag? Was this review really, really
>> performed internally or you just satisfy some internal managers requirements
>> and fake the stats?
>>
> 
> I added this Reviewed-by tag because the patch was reviewed internally.


What issues were identified by internal review, especially in the
context of bindings?

> 
>>> ---
>>>
>>> Changelog v12:
>>> - Newly add bindings for CSI2RX driver
>>>
>>>  .../media/toshiba,visconti5-csi2rx.yaml       | 104
>> ++++++++++++++++++
>>>  1 file changed, 104 insertions(+)
>>>  create mode 100644
>>> Documentation/devicetree/bindings/media/toshiba,visconti5-csi2rx.yaml
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/media/toshiba,visconti5-csi2rx.yam
>>> l
>>> b/Documentation/devicetree/bindings/media/toshiba,visconti5-csi2rx.yam
>>> l
>>> new file mode 100644
>>> index 000000000000..5488072bc82a
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/media/toshiba,visconti5-csi2rx
>>> +++ .yaml
>>> @@ -0,0 +1,104 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
>>> +---
>>> +$id:
>>> +http://devicetree.org/schemas/media/toshiba,visconti5-csi2rx.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Toshiba Visconti5 SoC MIPI CSI-2 receiver
>>> +
>>> +maintainers:
>>> +  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
>>> +
>>> +description: |-
>>
>> Drop |-
>>
> 
> I'll drop "|-"
> 
>>> +  Toshiba Visconti5 SoC MIPI CSI-2 receiver device receives MIPI
>>> + CSI-2 video  stream. Use with VIIF device. T.B.D
>>> +
>>> +properties:
>>> +  compatible:
>>> +    const: toshiba,visconti5-csi2rx
>>
>> Why this is called "RX"? Can you have a TX? I had impression that one cannot.
>>
> 
> VIIF has only MIPI CSI2 receiver (CSI2RX). There's no TX for it.

So this device cannot be anything else? Then drop rx.

> Visconti also has VOIF (Video Output Interface) hardware which has MIPI CSI2 (not DSI) transmitter (CSI2TX).

Or this can be something else? Confusing.



Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec 16 21:49:45 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 06:49:45 +0100
Subject: [PATCH v3 3/4] dt-bindings: hwmon: intel,crps185: Add to trivial
In-Reply-To: <20241217022046.113830-4-ninad@linux.ibm.com>
References: <20241217022046.113830-1-ninad@linux.ibm.com>
 <20241217022046.113830-4-ninad@linux.ibm.com>
Message-ID: <21008f97-d0bd-45bf-8e10-9ec2539ed858@kernel.org>

On 17/12/2024 03:20, Ninad Palsule wrote:
> Add INTEL Common Redundant Power Supply Versions crps185 bindings as
> trivial. It is trivial because only compatibility string is required in
> the device tree to load this driver.

That's incorrect reason. You should describe the hardware, e.g. the
hardware does not have any resources, like clocks or supplies.



Best regards,
Krzysztof


From krzk at kernel.org  Mon Dec 16 22:01:49 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 07:01:49 +0100
Subject: [PATCH v4 1/2] dt-bindings: arm: rockchip: Add Firefly ITX-3588J
 board
In-Reply-To: <20241216214152.58387-2-shimrrashai@gmail.com>
References: <20241216214152.58387-1-shimrrashai@gmail.com>
 <20241216214152.58387-2-shimrrashai@gmail.com>
Message-ID: <lkj2atlhann2t4b2oiztnlurr6zecmzllxstaf7vdnj2zy5x5d@pbzfqr6lsnhu>

On Mon, Dec 16, 2024 at 03:41:51PM -0600, Shimrra Shai wrote:
> Document board compatible bindings.
> 
> Signed-off-by: Shimrra Shai <shimrrashai at gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>  1 file changed, 7 insertions(+)
> 

<form letter>
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.
</form letter>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Mon Dec 16 22:12:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 07:12:26 +0100
Subject: [PATCH] dt-bindings: interrupt-controller: arm,gic: Correct VGIC interrupt description
Message-ID: <20241217061226.14139-1-krzysztof.kozlowski@linaro.org>

The description of VGIC interrupt referenced obsolete "see below" after
converting TXT to DT Schema in commit 66ed144f147a ("dt-bindings:
interrupt-controller: Convert ARM GIC to json-schema"), because there is
no dedicated "VGIC" chapter anymore below.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../devicetree/bindings/interrupt-controller/arm,gic.yaml     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
index a2846e493497..7173c4b5a228 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
@@ -110,8 +110,8 @@ properties:
 
   interrupts:
     description: Interrupt source of the parent interrupt controller on
-      secondary GICs, or VGIC maintenance interrupt on primary GIC (see
-      below).
+      secondary GICs, or VGIC maintenance interrupt on primary GIC (see "GICv2
+      with virtualization extensions" paragraph in the "reg" property).
     maxItems: 1
 
   cpu-offset:
-- 
2.43.0



From krzk at kernel.org  Mon Dec 16 22:13:57 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 07:13:57 +0100
Subject: [PATCH 1/2] dt-bindings: media: imx219: Rename to include vendor
 prefix
In-Reply-To: <20241217024206.1700170-1-david@ixit.cz>
References: <20241217024206.1700170-1-david@ixit.cz>
Message-ID: <0216b38b-70f7-4832-bda4-ed268b767b80@kernel.org>

On 17/12/2024 03:41, David Heidelberg wrote:
> imx219.yaml doesn't include the vendor prefix of sony,
> so rename to add it.
> 
> Update the id entry and MAINTAINERS to match.
> 
> Signed-off-by: David Heidelberg <david at ixit.cz>
> ---
>  .../bindings/media/i2c/{imx219.yaml => sony,imx219.yaml}        | 2 +-
>  MAINTAINERS                                                     | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>  rename Documentation/devicetree/bindings/media/i2c/{imx219.yaml => sony,imx219.yaml} (97%)

If you are doing changes like this, fix entire subsystem so all bindings
there. Not one file.

Best regards,
Krzysztof


From quic_jinlmao at quicinc.com  Mon Dec 16 22:33:24 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Tue, 17 Dec 2024 14:33:24 +0800
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
Message-ID: <20241217063324.33781-3-quic_jinlmao@quicinc.com>

For some coresight components like CTI and TPDM, there could be
numerous of them. From the node name, we can only get the type and
register address of the component. We can't identify the HW or the
system the component belongs to. Add label sysfs node support for
showing the intuitive name of the device.

Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
 .../sysfs-bus-coresight-devices-funnel        |  6 ++++
 .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
 drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++++++++++++++++++
 4 files changed, 50 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
index bf2869c413e7..909670e0451a 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
@@ -239,3 +239,9 @@ Date:		March 2020
 KernelVersion	5.7
 Contact:	Mike Leach or Mathieu Poirier
 Description:	(Write) Clear all channel / trigger programming.
+
+What:           /sys/bus/coresight/devices/<cti-name>/label
+Date:           Dec 2024
+KernelVersion   6.14
+Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
+Description:    (Read) Show hardware context information of device.
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
index d75acda5e1b3..944aad879aeb 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
@@ -10,3 +10,9 @@ Date:		November 2014
 KernelVersion:	3.19
 Contact:	Mathieu Poirier <mathieu.poirier at linaro.org>
 Description:	(RW) Defines input port priority order.
+
+What:           /sys/bus/coresight/devices/<memory_map>.funnel/label
+Date:           Dec 2024
+KernelVersion   6.14
+Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
+Description:    (Read) Show hardware context information of device.
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index bf710ea6e0ef..309802246398 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -257,3 +257,9 @@ 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 CMB subunit
 		TPDM.
+
+What:           /sys/bus/coresight/devices/<tpdm-name>/label
+Date:           Dec 2024
+KernelVersion   6.14
+Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
+Description:    (Read) Show hardware context information of device.
diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
index a01c9e54e2ed..4af40cd7d75a 100644
--- a/drivers/hwtracing/coresight/coresight-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-sysfs.c
@@ -7,6 +7,7 @@
 #include <linux/device.h>
 #include <linux/idr.h>
 #include <linux/kernel.h>
+#include <linux/property.h>
 
 #include "coresight-priv.h"
 #include "coresight-trace-id.h"
@@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(enable_source);
 
+static ssize_t label_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+
+	const char *str;
+	int ret = 0;
+
+	ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
+	if (ret == 0)
+		return scnprintf(buf, PAGE_SIZE, "%s\n", str);
+	else
+		return ret;
+}
+static DEVICE_ATTR_RO(label);
+
 static struct attribute *coresight_sink_attrs[] = {
 	&dev_attr_enable_sink.attr,
+	&dev_attr_label.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(coresight_sink);
 
 static struct attribute *coresight_source_attrs[] = {
 	&dev_attr_enable_source.attr,
+	&dev_attr_label.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(coresight_source);
 
+static struct attribute *coresight_link_attrs[] = {
+	&dev_attr_label.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(coresight_link);
+
+static struct attribute *coresight_helper_attrs[] = {
+	&dev_attr_label.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(coresight_helper);
+
 const struct device_type coresight_dev_type[] = {
 	[CORESIGHT_DEV_TYPE_SINK] = {
 		.name = "sink",
@@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
 	},
 	[CORESIGHT_DEV_TYPE_LINK] = {
 		.name = "link",
+		.groups = coresight_link_groups,
 	},
 	[CORESIGHT_DEV_TYPE_LINKSINK] = {
 		.name = "linksink",
@@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
 	},
 	[CORESIGHT_DEV_TYPE_HELPER] = {
 		.name = "helper",
+		.groups = coresight_helper_groups,
 	}
 };
 /* Ensure the enum matches the names and groups */
-- 
2.17.1



From quic_jinlmao at quicinc.com  Mon Dec 16 22:33:22 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Tue, 17 Dec 2024 14:33:22 +0800
Subject: [PATCH v6 0/2] coresight: Add label sysfs node support
Message-ID: <20241217063324.33781-1-quic_jinlmao@quicinc.com>

With current design, the name of the non-cpu bounded coresight
component is the device type with the number. And with 'ls' command
we can get the register address of the component. But from these
information, we can't know what the HW or system the component belongs
to. Add label in DT and show the hw information by reading label sysfs
node.

cti_sys0 -> ../../../devices/platform/soc at 0/138f0000.cti/cti_sys0
cti_sys1 -> ../../../devices/platform/soc at 0/13900000.cti/cti_sys1
tpdm0 -> ../../../devices/platform/soc at 0/10b0d000.tpdm/tpdm0
tpdm1 -> ../../../devices/platform/soc at 0/10c28000.tpdm/tpdm1
tpdm2 -> ../../../devices/platform/soc at 0/10c29000.tpdm/tpdm2

/sys/bus/coresight/devices # cat cti*/label
cti_dlct_0
cti_dlct_1
cti_apss_0
cti_apss_1
cti_apss_2

Change since V5:
1. Update the kernel version of ABI files.
2. Add link of different patch versions.
V5 link: https://patchwork.kernel.org/project/linux-arm-msm/cover/20241210122253.31926-1-quic_jinlmao at quicinc.com/

Change since V4:
1. Add label in DT and add label sysfs node for each coresight device. 
V4 link: https://patchwork.kernel.org/project/linux-arm-msm/cover/20240703122340.26864-1-quic_jinlmao at quicinc.com/

Change since V3:
1. Change device-name to arm,cs-dev-name.
2. Add arm,cs-dev-name to only CTI and sources' dt-binding.
V3 link: https://patchwork.kernel.org/project/linux-arm-msm/cover/20240131082628.6288-1-quic_jinlmao at quicinc.com/

Change since V2:
1. Fix the error in coresight core.
drivers/hwtracing/coresight/coresight-core.c:1775:7: error: assigning to 'char *' from 'const char *' discards qualifiers

2. Fix the warning when run dtbinding check.
Documentation/devicetree/bindings/arm/arm,coresight-cpu-debug.yaml: device-name: missing type definition
V2 link: https://patchwork.kernel.org/project/linux-arm-msm/cover/20240115164252.26510-1-quic_jinlmao at quicinc.com/

Change since V1:
1. Change coresight-name to device name.
2. Add the device-name in coresight dt bindings.
V1 link: https://patchwork.kernel.org/project/linux-arm-kernel/patch/20230208110716.18321-1-quic_jinlmao at quicinc.com/#25231737


Mao Jinlong (2):
  dt-bindings: arm: Add label in the coresight components
  coresight: Add label sysfs node support

 .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
 .../sysfs-bus-coresight-devices-funnel        |  6 ++++
 .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
 .../bindings/arm/arm,coresight-cti.yaml       |  6 ++++
 .../arm/arm,coresight-dummy-sink.yaml         |  6 ++++
 .../arm/arm,coresight-dummy-source.yaml       |  6 ++++
 .../arm/arm,coresight-dynamic-funnel.yaml     |  6 ++++
 .../arm/arm,coresight-dynamic-replicator.yaml |  6 ++++
 .../arm/arm,coresight-static-funnel.yaml      |  6 ++++
 .../arm/arm,coresight-static-replicator.yaml  |  6 ++++
 .../bindings/arm/arm,coresight-tmc.yaml       |  6 ++++
 .../bindings/arm/qcom,coresight-tpda.yaml     |  6 ++++
 .../bindings/arm/qcom,coresight-tpdm.yaml     |  6 ++++
 drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++++++++++++++++++
 14 files changed, 110 insertions(+)

-- 
2.17.1



From quic_jinlmao at quicinc.com  Mon Dec 16 22:33:23 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Tue, 17 Dec 2024 14:33:23 +0800
Subject: [PATCH v6 1/2] dt-bindings: arm: Add label in the coresight components
In-Reply-To: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
Message-ID: <20241217063324.33781-2-quic_jinlmao@quicinc.com>

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 label to show hardware context information of each coresight
device. There will be a sysfs node label in each device folder.

cat /sys/bus/coresight/devices/cti_sys0/label

Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../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 ++++++
 .../bindings/arm/arm,coresight-static-funnel.yaml           | 6 ++++++
 .../bindings/arm/arm,coresight-static-replicator.yaml       | 6 ++++++
 .../devicetree/bindings/arm/arm,coresight-tmc.yaml          | 6 ++++++
 .../devicetree/bindings/arm/qcom,coresight-tpda.yaml        | 6 ++++++
 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml        | 6 ++++++
 10 files changed, 60 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml
index 2d5545a2b49c..5ca6d3d313a3 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml
@@ -98,6 +98,12 @@ properties:
   power-domains:
     maxItems: 1
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   arm,cti-ctm-id:
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml
index 08b89b62c505..bc82cd1f3595 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml
@@ -39,6 +39,12 @@ properties:
     enum:
       - arm,coresight-dummy-sink
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   in-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml
index 04a8c37b4aff..245929c36357 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml
@@ -38,6 +38,12 @@ properties:
     enum:
       - arm,coresight-dummy-source
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   out-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml
index 44a1041cb0fc..30776610d4b4 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml
@@ -57,6 +57,12 @@ properties:
   power-domains:
     maxItems: 1
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   in-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml
index 03792e9bd97a..178a3861ee29 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml
@@ -54,6 +54,12 @@ properties:
       - const: apb_pclk
       - const: atclk
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   power-domains:
     maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml
index cc8c3baa79b4..39b291909cc4 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml
@@ -30,6 +30,12 @@ properties:
   power-domains:
     maxItems: 1
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   in-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
index 1892a091ac35..ba10897043cf 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
@@ -39,6 +39,12 @@ properties:
         description: Input connection from CoreSight Trace bus
         $ref: /schemas/graph.yaml#/properties/port
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   out-ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
index cb8dceaca70e..8d952150d7b9 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
@@ -55,6 +55,12 @@ properties:
       - const: apb_pclk
       - const: atclk
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   iommus:
     maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml
index 76163abed655..986b9b4f360d 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml
@@ -65,6 +65,12 @@ properties:
     items:
       - const: apb_pclk
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   in-ports:
     description: |
       Input connections from TPDM to TPDA
diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index 8eec07d9d454..59e533720bdd 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -77,6 +77,12 @@ properties:
     minimum: 0
     maximum: 32
 
+  label:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      Define the label which can describe what kind of HW or system the
+      coresight device belongs to.
+
   clocks:
     maxItems: 1
 
-- 
2.17.1



From fj5100bi at fujitsu.com  Mon Dec 16 22:35:14 2024
From: fj5100bi at fujitsu.com (Yoshihiro Furudera (Fujitsu))
Date: Tue, 17 Dec 2024 06:35:14 +0000
Subject: [PATCH v2] perf vendor events arm64: Add FUJITSU-MONAKA pmu event
In-Reply-To: <OS3PR01MB690303F6D0FAF71ADDE7AA4BD43D2@OS3PR01MB6903.jpnprd01.prod.outlook.com>
References: <20241111064843.3003093-1-fj5100bi@fujitsu.com>
 <ee89c235-a126-4874-994d-b2489eb1c00f@linaro.org>
 <OS3PR01MB690303F6D0FAF71ADDE7AA4BD43D2@OS3PR01MB6903.jpnprd01.prod.outlook.com>
Message-ID: <OS3PR01MB6903A0317D8BB90A9B4DD7E8D4042@OS3PR01MB6903.jpnprd01.prod.outlook.com>

Hi, James

> > Also in the common files, we're using the description strings from the
> > Arm ARM. I noticed that the ones from your spec are slightly different.
> > This is ok for now, but if we add any new Arm cores that use the same
> > events this description may get overwritten. For example
> > ASE_SVE_INST_SPEC in the Arm ARM is currently "Operation speculatively
> executed, Advanced SIMD or SVE".
> >
> > If you have any actual relevant details that are different from the
> > common string, you should put them in .../arch/arm64/fujitsu/monaka.
> > But if you are ok with the potential overwrite (which looks like it
> > should be ok) then you can leave them as is.
> 
> I think it's okay to overwrite it, but I'll check the specs.

Regarding this matter, the descriptions of the events added to the common files
(common-and-microarch.json, recommended.json) will be modified to match Arm ARM.
Then, we will write current descriptions as "BriefDescription" in .../arch/arm64/fujitsu/monaka.
We will post this as a v3 patch later.

> 
> >
> > [...]
> >
> > > diff --git
> > > a/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
> > > b/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
> > > new file mode 100644
> > > index 000000000000..80bf17fb8f4c
> > > --- /dev/null
> > > +++ b/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
> > > @@ -0,0 +1,8 @@
> > > +[
> > > +    {
> > > +        "ArchStdEvent": "CPU_CYCLES"
> > > +    },
> >
> > Other cores put CPU_CYCLES in bus.json. For user friendlyness I would
> > put the common ones into the same existing groups. The same issue
> > applies for some other common events.
> >
> 
> I will update as suggested.

MONAKA's event grouping is based on the grouping of "neoverse n1/n2".
We found that the groups in "neoverse n1/n2" may differ from those in other cores.
For example, "CPU_CYCLES" is classified in general.json in "neoverse n1/n2",
but in bus.json in many other cores.

As a result, it is not possible to completely match the event groups of other cores.
We will be checking the current grouping of events and modifying them as much as possible
to match the other core, and will post this later as a v3 patch.

Best Regards,
Yoshihiro Furudera

From quic_wasimn at quicinc.com  Mon Dec 16 22:48:50 2024
From: quic_wasimn at quicinc.com (Wasim Nazir)
Date: Tue, 17 Dec 2024 12:18:50 +0530
Subject: [PATCH v4 1/7] dt-bindings: arm: qcom,ids: add SoC ID for QCS9075
In-Reply-To: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
Message-ID: <20241217064856.2772305-2-quic_wasimn@quicinc.com>

Add the unique ID for Qualcomm QCS9075 SoC.
This value is used to differentiate the SoC across qcom targets.

Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Wasim Nazir <quic_wasimn at quicinc.com>
---
 include/dt-bindings/arm/qcom,ids.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h
index e850dc3a1ad3..1b3e0176dcb7 100644
--- a/include/dt-bindings/arm/qcom,ids.h
+++ b/include/dt-bindings/arm/qcom,ids.h
@@ -284,6 +284,7 @@
 #define QCOM_ID_QCS9100			667
 #define QCOM_ID_QCS8300			674
 #define QCOM_ID_QCS8275			675
+#define QCOM_ID_QCS9075			676
 #define QCOM_ID_QCS615			680

 /*
--
2.47.0



From quic_wasimn at quicinc.com  Mon Dec 16 22:48:52 2024
From: quic_wasimn at quicinc.com (Wasim Nazir)
Date: Tue, 17 Dec 2024 12:18:52 +0530
Subject: [PATCH v4 3/7] dt-bindings: arm: qcom: Document rb8/ride/ride-r3 on QCS9075
In-Reply-To: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
Message-ID: <20241217064856.2772305-4-quic_wasimn@quicinc.com>

qcs9075 rb8, ride & ride-r3 boards are based on QCS9075 SoC.

QCS9075 is compatible IoT-industrial grade variant of SA8775p SoC.
Unlike QCS9100, it doesn't have safety monitoring feature of
Safety-Island(SAIL) subsystem, which affects thermal management.

Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Wasim Nazir <quic_wasimn at quicinc.com>
---
 Documentation/devicetree/bindings/arm/qcom.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index d394dffe3fba..8cee92a804c4 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -57,6 +57,7 @@ description: |
         qcs8550
         qcm2290
         qcm6490
+        qcs9075
         qcs9100
         qdu1000
         qrb2210
@@ -950,6 +951,14 @@ properties:
               - qcom,sa8775p-ride-r3
           - const: qcom,sa8775p

+      - items:
+          - enum:
+              - qcom,qcs9075-rb8
+              - qcom,qcs9075-ride
+              - qcom,qcs9075-ride-r3
+          - const: qcom,qcs9075
+          - const: qcom,sa8775p
+
       - items:
           - enum:
               - qcom,qcs9100-ride
--
2.47.0



From quic_wasimn at quicinc.com  Mon Dec 16 22:48:55 2024
From: quic_wasimn at quicinc.com (Wasim Nazir)
Date: Tue, 17 Dec 2024 12:18:55 +0530
Subject: [PATCH v4 6/7] arm64: defconfig: enable cpu idle injection and cpu idle cooling device
In-Reply-To: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
Message-ID: <20241217064856.2772305-7-quic_wasimn@quicinc.com>

From: Manaf Meethalavalappu Pallikunhi <quic_manafm at quicinc.com>

Enable cpu idle injection framework and thermal cpu idle cooling device
to throttle the cpu by injecting idle cycle during high thermal condition.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <quic_manafm at quicinc.com>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 76bd7424985a..32911e57e761 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -693,6 +693,7 @@ CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
+CONFIG_CPU_IDLE_THERMAL=y
 CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
 CONFIG_IMX_SC_THERMAL=m
@@ -1595,6 +1596,8 @@ CONFIG_HISI_PMU=y
 CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
 CONFIG_NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
 CONFIG_MESON_DDR_PMU=m
+CONFIG_POWERCAP=y
+CONFIG_IDLE_INJECT=y
 CONFIG_NVMEM_LAYOUT_SL28_VPD=m
 CONFIG_NVMEM_IMX_OCOTP=y
 CONFIG_NVMEM_IMX_OCOTP_ELE=m
--
2.47.0



From quic_wasimn at quicinc.com  Mon Dec 16 22:48:49 2024
From: quic_wasimn at quicinc.com (Wasim Nazir)
Date: Tue, 17 Dec 2024 12:18:49 +0530
Subject: [PATCH v4 0/7] arm64: qcom: Add support for QCS9075 boards
Message-ID: <20241217064856.2772305-1-quic_wasimn@quicinc.com>

This series:

Add support for Qualcomm's rb8, ride/ride-r3 boards using QCS9075 SoC.

QCS9075 is compatible IoT-industrial grade variant of SA8775p SoC.
Unlike QCS9100, it doesn't have safety monitoring feature of
Safety-Island(SAIL) subsystem, which affects thermal management.

In QCS9100 SoC, the safety subsystem monitors all thermal sensors and
does corrective action for each subsystem based on sensor violation
to comply safety standards. But as QCS9075 is non-safe SoC it requires
conventional thermal mitigation for thermal management.

Difference between Ride & ride-r3 boards is ethernet phy,
ride uses 1G ethernet phy while ride-r3 uses 2.5G ethernet phy.

This series depends on [1] for thermal functionality to work.

[1]: https://lore.kernel.org/all/20241112-sa8775p_cpuidle-v1-1-66ff3ba72464 at quicinc.com/

---
Changelog:

v4:
  - Replace dts to dtsi in Ride/Ride-r3 platform files
  - Add thermal patch to differentiate between 9100 vs 9075
  - Add proper abbreviation and update commit for 9100 vs 9075
  - v3: https://lore.kernel.org/all/20241119174954.1219002-1-quic_wasimn at quicinc.com/

v3:
  - Fix RB8 board compatible string
  - v2: https://lore.kernel.org/all/20241115225152.3264396-1-quic_wasimn at quicinc.com/

v2:
  - Remove unused dp nodes & update commit for ride vs ride-r3.
  - v1: https://lore.kernel.org/all/20241110145339.3635437-1-quic_wasimn at quicinc.com/

Manaf Meethalavalappu Pallikunhi (2):
  arm64: defconfig: enable cpu idle injection and cpu idle cooling
    device
  arm64: dts: qcom: Enable cpu cooling devices for QCS9075 platforms

Wasim Nazir (5):
  dt-bindings: arm: qcom,ids: add SoC ID for QCS9075
  soc: qcom: socinfo: add QCS9075 SoC ID
  dt-bindings: arm: qcom: Document rb8/ride/ride-r3 on QCS9075
  arm64: dts: qcom: Add support for QCS9075 RB8
  arm64: dts: qcom: Add support for QCS9075 Ride & Ride-r3

 .../devicetree/bindings/arm/qcom.yaml         |   9 +
 arch/arm64/boot/dts/qcom/Makefile             |   3 +
 arch/arm64/boot/dts/qcom/qcs9075-rb8.dts      | 282 +++++++++++++++++
 arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts  |  47 +++
 arch/arm64/boot/dts/qcom/qcs9075-ride.dts     |  47 +++
 arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi | 287 ++++++++++++++++++
 arch/arm64/configs/defconfig                  |   3 +
 drivers/soc/qcom/socinfo.c                    |   1 +
 include/dt-bindings/arm/qcom,ids.h            |   1 +
 9 files changed, 680 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-rb8.dts
 create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
 create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-ride.dts
 create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi


base-commit: 4176cf5c5651c33769de83bb61b0287f4ec7719f
--
2.47.0



From quic_wasimn at quicinc.com  Mon Dec 16 22:48:53 2024
From: quic_wasimn at quicinc.com (Wasim Nazir)
Date: Tue, 17 Dec 2024 12:18:53 +0530
Subject: [PATCH v4 4/7] arm64: dts: qcom: Add support for QCS9075 RB8
In-Reply-To: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
Message-ID: <20241217064856.2772305-5-quic_wasimn@quicinc.com>

Add initial device tree support for the RB8 board
based on Qualcomm's QCS9075 SoC.

Basic changes are supported for boot to shell.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Signed-off-by: Wasim Nazir <quic_wasimn at quicinc.com>
---
 arch/arm64/boot/dts/qcom/Makefile        |   1 +
 arch/arm64/boot/dts/qcom/qcs9075-rb8.dts | 281 +++++++++++++++++++++++
 2 files changed, 282 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-rb8.dts

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 4686f2a8ddd8..78613a1bd34a 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -117,6 +117,7 @@ dtb-$(CONFIG_ARCH_QCOM)	+= qcs615-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-rb8.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride-r3.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qdu1000-idp.dtb
diff --git a/arch/arm64/boot/dts/qcom/qcs9075-rb8.dts b/arch/arm64/boot/dts/qcom/qcs9075-rb8.dts
new file mode 100644
index 000000000000..ecaa383b6508
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs9075-rb8.dts
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "sa8775p.dtsi"
+#include "sa8775p-pmics.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Robotics RB8";
+	compatible = "qcom,qcs9075-rb8", "qcom,qcs9075", "qcom,sa8775p";
+
+	aliases {
+		serial0 = &uart10;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vreg_s4a: smps4 {
+			regulator-name = "vreg_s4a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1816000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5a: smps5 {
+			regulator-name = "vreg_s5a";
+			regulator-min-microvolt = <1850000>;
+			regulator-max-microvolt = <1996000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9a: smps9 {
+			regulator-name = "vreg_s9a";
+			regulator-min-microvolt = <535000>;
+			regulator-max-microvolt = <1120000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4a: ldo4 {
+			regulator-name = "vreg_l4a";
+			regulator-min-microvolt = <788000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5a: ldo5 {
+			regulator-name = "vreg_l5a";
+			regulator-min-microvolt = <870000>;
+			regulator-max-microvolt = <950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6a: ldo6 {
+			regulator-name = "vreg_l6a";
+			regulator-min-microvolt = <870000>;
+			regulator-max-microvolt = <970000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a: ldo7 {
+			regulator-name = "vreg_l7a";
+			regulator-min-microvolt = <720000>;
+			regulator-max-microvolt = <950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a: ldo8 {
+			regulator-name = "vreg_l8a";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a: ldo9 {
+			regulator-name = "vreg_l9a";
+			regulator-min-microvolt = <2970000>;
+			regulator-max-microvolt = <3544000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vreg_l1c: ldo1 {
+			regulator-name = "vreg_l1c";
+			regulator-min-microvolt = <1140000>;
+			regulator-max-microvolt = <1260000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c: ldo2 {
+			regulator-name = "vreg_l2c";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3c: ldo3 {
+			regulator-name = "vreg_l3c";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c: ldo4 {
+			regulator-name = "vreg_l4c";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			/*
+			 * FIXME: This should have regulator-allow-set-load but
+			 * we're getting an over-current fault from the PMIC
+			 * when switching to LPM.
+			 */
+		};
+
+		vreg_l5c: ldo5 {
+			regulator-name = "vreg_l5c";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6c: ldo6 {
+			regulator-name = "vreg_l6c";
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <1980000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c: ldo7 {
+			regulator-name = "vreg_l7c";
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c: ldo8 {
+			regulator-name = "vreg_l8c";
+			regulator-min-microvolt = <2400000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c: ldo9 {
+			regulator-name = "vreg_l9c";
+			regulator-min-microvolt = <1650000>;
+			regulator-max-microvolt = <2700000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-2 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "e";
+
+		vreg_s4e: smps4 {
+			regulator-name = "vreg_s4e";
+			regulator-min-microvolt = <970000>;
+			regulator-max-microvolt = <1520000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s7e: smps7 {
+			regulator-name = "vreg_s7e";
+			regulator-min-microvolt = <1010000>;
+			regulator-max-microvolt = <1170000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9e: smps9 {
+			regulator-name = "vreg_s9e";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <570000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6e: ldo6 {
+			regulator-name = "vreg_l6e";
+			regulator-min-microvolt = <1280000>;
+			regulator-max-microvolt = <1450000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8e: ldo8 {
+			regulator-name = "vreg_l8e";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&sleep_clk {
+	clock-frequency = <32768>;
+};
+
+&tlmm {
+	qup_uart10_default: qup-uart10-state {
+		pins = "gpio46", "gpio47";
+		function = "qup1_se3";
+	};
+};
+
+&uart10 {
+	compatible = "qcom,geni-debug-uart";
+	pinctrl-0 = <&qup_uart10_default>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&xo_board_clk {
+	clock-frequency = <38400000>;
+};
--
2.47.0



From quic_wasimn at quicinc.com  Mon Dec 16 22:48:51 2024
From: quic_wasimn at quicinc.com (Wasim Nazir)
Date: Tue, 17 Dec 2024 12:18:51 +0530
Subject: [PATCH v4 2/7] soc: qcom: socinfo: add QCS9075 SoC ID
In-Reply-To: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
Message-ID: <20241217064856.2772305-3-quic_wasimn@quicinc.com>

Update soc_id table for the Qualcomm QCS9075 SoC
to represent qcs9075 machine.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Wasim Nazir <quic_wasimn at quicinc.com>
---
 drivers/soc/qcom/socinfo.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 62fadfe44a09..174210f3467b 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -451,6 +451,7 @@ static const struct soc_id soc_id[] = {
 	{ qcom_board_id(QCS9100) },
 	{ qcom_board_id(QCS8300) },
 	{ qcom_board_id(QCS8275) },
+	{ qcom_board_id(QCS9075) },
 	{ qcom_board_id(QCS615) },
 };

--
2.47.0



From quic_wasimn at quicinc.com  Mon Dec 16 22:48:54 2024
From: quic_wasimn at quicinc.com (Wasim Nazir)
Date: Tue, 17 Dec 2024 12:18:54 +0530
Subject: [PATCH v4 5/7] arm64: dts: qcom: Add support for QCS9075 Ride & Ride-r3
In-Reply-To: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
Message-ID: <20241217064856.2772305-6-quic_wasimn@quicinc.com>

Add device tree support for QCS9075 Ride & Ride-r3 boards.

QCS9075 lacks the safety monitoring features of Safety-Island (SAIL)
subsystem which is available in QCS9100, and it affects thermal
management.

Also, between ride and ride-r3 ethernet phy is different.
Ride uses 1G ethernet phy while ride-r3 uses 2.5G ethernet phy.

Signed-off-by: Wasim Nazir <quic_wasimn at quicinc.com>
---
 arch/arm64/boot/dts/qcom/Makefile            |  2 +
 arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts | 46 ++++++++++++++++++++
 arch/arm64/boot/dts/qcom/qcs9075-ride.dts    | 46 ++++++++++++++++++++
 3 files changed, 94 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
 create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-ride.dts

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 78613a1bd34a..41cb2bbd3472 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -118,6 +118,8 @@ dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-rb8.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-ride-r3.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride-r3.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qdu1000-idp.dtb
diff --git a/arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts b/arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
new file mode 100644
index 000000000000..d9a8956d3a76
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "sa8775p-ride.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS9075 Ride Rev3";
+	compatible = "qcom,qcs9075-ride-r3", "qcom,qcs9075", "qcom,sa8775p";
+};
+
+&ethernet0 {
+	phy-mode = "2500base-x";
+};
+
+&ethernet1 {
+	phy-mode = "2500base-x";
+};
+
+&mdio {
+	compatible = "snps,dwmac-mdio";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	sgmii_phy0: phy at 8 {
+		compatible = "ethernet-phy-id31c3.1c33";
+		reg = <0x8>;
+		device_type = "ethernet-phy";
+		interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <11000>;
+		reset-deassert-us = <70000>;
+	};
+
+	sgmii_phy1: phy at 0 {
+		compatible = "ethernet-phy-id31c3.1c33";
+		reg = <0x0>;
+		device_type = "ethernet-phy";
+		interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <11000>;
+		reset-deassert-us = <70000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs9075-ride.dts b/arch/arm64/boot/dts/qcom/qcs9075-ride.dts
new file mode 100644
index 000000000000..3b524359a72d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs9075-ride.dts
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "sa8775p-ride.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS9075 Ride";
+	compatible = "qcom,qcs9075-ride", "qcom,qcs9075", "qcom,sa8775p";
+};
+
+&ethernet0 {
+	phy-mode = "sgmii";
+};
+
+&ethernet1 {
+	phy-mode = "sgmii";
+};
+
+&mdio {
+	compatible = "snps,dwmac-mdio";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	sgmii_phy0: phy at 8 {
+		compatible = "ethernet-phy-id0141.0dd4";
+		reg = <0x8>;
+		device_type = "ethernet-phy";
+		interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <11000>;
+		reset-deassert-us = <70000>;
+	};
+
+	sgmii_phy1: phy at a {
+		compatible = "ethernet-phy-id0141.0dd4";
+		reg = <0xa>;
+		device_type = "ethernet-phy";
+		interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <11000>;
+		reset-deassert-us = <70000>;
+	};
+};
--
2.47.0



From quic_wasimn at quicinc.com  Mon Dec 16 22:48:56 2024
From: quic_wasimn at quicinc.com (Wasim Nazir)
Date: Tue, 17 Dec 2024 12:18:56 +0530
Subject: [PATCH v4 7/7] arm64: dts: qcom: Enable cpu cooling devices for QCS9075 platforms
In-Reply-To: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
Message-ID: <20241217064856.2772305-8-quic_wasimn@quicinc.com>

From: Manaf Meethalavalappu Pallikunhi <quic_manafm at quicinc.com>

In QCS9100 SoC, the safety subsystem monitors all thermal sensors and
does corrective action for each subsystem based on sensor violation
to comply safety standards. But as QCS9075 is non-safe SoC it
requires conventional thermal mitigation to control thermal for
different subsystems.

The cpu frequency throttling for different cpu tsens is enabled in
hardware as first defense for cpu thermal control. But QCS9075 SoC
has higher ambient specification. During high ambient condition, even
lowest frequency with multi cores can slowly build heat over the time
and it can lead to thermal run-away situations. This patch restrict
cpu cores during this scenario helps further thermal control and
avoids thermal critical violation.

Add cpu idle injection cooling bindings for cpu tsens thermal zones
as a mitigation for cpu subsystem prior to thermal shutdown.

Add cpu frequency cooling devices that will be used by userspace
thermal governor to mitigate skin thermal management.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <quic_manafm at quicinc.com>
---
 arch/arm64/boot/dts/qcom/qcs9075-rb8.dts      |   1 +
 arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts  |   1 +
 arch/arm64/boot/dts/qcom/qcs9075-ride.dts     |   1 +
 arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi | 287 ++++++++++++++++++
 4 files changed, 290 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi

diff --git a/arch/arm64/boot/dts/qcom/qcs9075-rb8.dts b/arch/arm64/boot/dts/qcom/qcs9075-rb8.dts
index ecaa383b6508..3ab6deeaacf1 100644
--- a/arch/arm64/boot/dts/qcom/qcs9075-rb8.dts
+++ b/arch/arm64/boot/dts/qcom/qcs9075-rb8.dts
@@ -9,6 +9,7 @@

 #include "sa8775p.dtsi"
 #include "sa8775p-pmics.dtsi"
+#include "qcs9075-thermal.dtsi"

 / {
 	model = "Qualcomm Technologies, Inc. Robotics RB8";
diff --git a/arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts b/arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
index d9a8956d3a76..5f2d9f416617 100644
--- a/arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
+++ b/arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
@@ -5,6 +5,7 @@
 /dts-v1/;

 #include "sa8775p-ride.dtsi"
+#include "qcs9075-thermal.dtsi"

 / {
 	model = "Qualcomm Technologies, Inc. QCS9075 Ride Rev3";
diff --git a/arch/arm64/boot/dts/qcom/qcs9075-ride.dts b/arch/arm64/boot/dts/qcom/qcs9075-ride.dts
index 3b524359a72d..10ce48e7ba2f 100644
--- a/arch/arm64/boot/dts/qcom/qcs9075-ride.dts
+++ b/arch/arm64/boot/dts/qcom/qcs9075-ride.dts
@@ -5,6 +5,7 @@
 /dts-v1/;

 #include "sa8775p-ride.dtsi"
+#include "qcs9075-thermal.dtsi"

 / {
 	model = "Qualcomm Technologies, Inc. QCS9075 Ride";
diff --git a/arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi b/arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi
new file mode 100644
index 000000000000..40544c8582c4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/thermal/thermal.h>
+
+&cpu0 {
+	#cooling-cells = <2>;
+};
+
+&cpu1 {
+	#cooling-cells = <2>;
+	cpu1_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&cpu2 {
+	#cooling-cells = <2>;
+	cpu2_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&cpu3 {
+	#cooling-cells = <2>;
+	cpu3_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&cpu4 {
+	#cooling-cells = <2>;
+	cpu4_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&cpu5 {
+	#cooling-cells = <2>;
+	cpu5_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&cpu6 {
+	#cooling-cells = <2>;
+	cpu6_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&cpu7 {
+	#cooling-cells = <2>;
+	cpu7_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+/ {
+	thermal-zones {
+		cpu-0-1-0-thermal {
+			trips {
+				cpu_0_1_0_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_0_1_0_passive>;
+					cooling-device = <&cpu1_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-0-2-0-thermal {
+			trips {
+				cpu_0_2_0_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_0_2_0_passive>;
+					cooling-device = <&cpu2_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-0-3-0-thermal {
+			trips {
+				cpu_0_3_0_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_0_3_0_passive>;
+					cooling-device = <&cpu3_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-0-1-1-thermal {
+			trips {
+				cpu_0_1_1_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_0_1_1_passive>;
+					cooling-device = <&cpu1_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-0-2-1-thermal {
+			trips {
+				cpu_0_2_1_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_0_2_1_passive>;
+					cooling-device = <&cpu2_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-0-3-1-thermal {
+			trips {
+				cpu_0_3_1_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_0_3_1_passive>;
+					cooling-device = <&cpu3_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-1-0-0-thermal {
+			trips {
+				cpu_1_0_0_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_1_0_0_passive>;
+					cooling-device = <&cpu4_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-1-1-0-thermal {
+			trips {
+				cpu_1_1_0_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_1_1_0_passive>;
+					cooling-device = <&cpu5_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-1-2-0-thermal {
+			trips {
+				cpu_1_2_0_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_1_2_0_passive>;
+					cooling-device = <&cpu6_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-1-3-0-thermal {
+			trips {
+				cpu_1_3_0_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_1_3_0_passive>;
+					cooling-device = <&cpu7_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-1-0-1-thermal {
+			trips {
+				cpu_1_0_1_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_1_0_1_passive>;
+					cooling-device = <&cpu4_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-1-1-1-thermal {
+			trips {
+				cpu_1_1_1_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_1_1_1_passive>;
+					cooling-device = <&cpu5_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-1-2-1-thermal {
+			trips {
+				cpu_1_2_1_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_1_2_1_passive>;
+					cooling-device = <&cpu6_idle 100 100>;
+				};
+			};
+		};
+
+		cpu-1-3-1-thermal {
+			trips {
+				cpu_1_3_1_passive: trip-point1 {
+					temperature = <116000>;
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_1_3_1_passive>;
+					cooling-device = <&cpu7_idle 100 100>;
+				};
+			};
+		};
+	};
+};
--
2.47.0



From Sandor.yu at nxp.com  Mon Dec 16 22:51:51 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:51 +0800
Subject: [PATCH v20 9/9] arm64: dts: imx8mq: tqma8mq-mba8mx: Enable HDMI support
In-Reply-To: <cover.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <e72920a199e245d0e1f71f3a62af6c603e4b1f39.1734340233.git.Sandor.yu@nxp.com>

From: Alexander Stein <alexander.stein at ew.tq-group.com>

Add HDMI connector and connect it to MHDP output. Enable peripherals
for HDMI output.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
v19->v20:
 *No change

v18->v19:
- Move property data-lanes to endpoint of port at 1

v17->v18:
- replace lane-mapping with data-lanes

 .../dts/freescale/imx8mq-tqma8mq-mba8mx.dts   | 26 +++++++++++++++++++
 arch/arm64/boot/dts/freescale/mba8mx.dtsi     | 11 ++++++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
index 0165f3a259853..5ba06a411c6a1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
@@ -53,6 +53,10 @@ &btn2 {
 	gpios = <&gpio3 17 GPIO_ACTIVE_LOW>;
 };
 
+&dcss {
+	status = "okay";
+};
+
 &gpio_leds {
 	led3 {
 		label = "led3";
@@ -60,6 +64,14 @@ led3 {
 	};
 };
 
+&hdmi_connector {
+	port {
+		hdmi_connector_in: endpoint {
+			remote-endpoint = <&mhdp_out>;
+		};
+	};
+};
+
 &i2c1 {
 	expander2: gpio at 25 {
 		compatible = "nxp,pca9555";
@@ -91,6 +103,20 @@ &led2 {
 	gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
 };
 
+&mhdp {
+	status = "okay";
+	ports {
+		port at 1 {
+			reg = <1>;
+
+			mhdp_out: endpoint {
+				remote-endpoint = <&hdmi_connector_in>;
+				data-lanes = <0 1 2 3>;
+			};
+		};
+	};
+};
+
 /* PCIe slot on X36 */
 &pcie0 {
 	reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
index 58e3865c28895..d04b75a76dfe6 100644
--- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
@@ -89,6 +89,17 @@ gpio_delays: gpio-delays {
 		gpio-line-names = "LVDS_BRIDGE_EN_1V8";
 	};
 
+	hdmi_connector: connector {
+		compatible = "hdmi-connector";
+		label = "X11";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+			};
+		};
+	};
+
 	panel: panel-lvds {
 		/*
 		 * Display is not fixed, so compatible has to be added from
-- 
2.34.1



From krzk at kernel.org  Mon Dec 16 22:56:26 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 07:56:26 +0100
Subject: [PATCH v3 2/5] ASoC: dt-bindings: support imx95's CM7 core
In-Reply-To: <20241216145039.3074-3-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
 <20241216145039.3074-3-laurentiumihalcea111@gmail.com>
Message-ID: <jwhjz7a7spikaj3sgrpqqt5deygeedspz4iar7h6tofadk44nr@ytl7dnnbcrom>

On Mon, Dec 16, 2024 at 09:50:36AM -0500, Laurentiu Mihalcea wrote:
> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> 
> Add binding for imx95's CM7 core, used for audio processing.

Adding common binding and using it should be the same patch, for such
relatively small bindings.

> 
> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> ---
>  .../bindings/sound/fsl,imx95-cm7-sof.yaml     | 44 +++++++++++++++++++
>  1 file changed, 44 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml

...

> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    cm7-cpu at 80000000 {
> +        compatible = "fsl,imx95-cm7-sof";
> +        reg = <0x80000000 0x6100000>;
> +        mboxes = <&mu7 2 0>, <&mu7 2 1>, <&mu7 3 0>, <&mu7 3 1>;
> +        mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";
> +        memory-region = <&adma_res>;
> +        port {
> +          /* SAI3-WM8962 link */

Keep consistent indentation.

> +          endpoint { remote-endpoint = <&wm8962_ep>; };

This should not be one line, but three lines.

> +        };
> +    };
> -- 
> 2.34.1
> 


From kieran.bingham at ideasonboard.com  Mon Dec 16 22:53:18 2024
From: kieran.bingham at ideasonboard.com (Kieran Bingham)
Date: Tue, 17 Dec 2024 06:53:18 +0000
Subject: [PATCH] dt-bindings: media: imx283: Describe sensor address using the reg property
In-Reply-To: <20241217032821.1712916-1-david@ixit.cz>
References: <20241217032821.1712916-1-david@ixit.cz>
Message-ID: <173441839809.2983864.13556053856142193864@ping.linuxembedded.co.uk>

Quoting David Heidelberg (2024-12-17 03:28:17)
> Use the reg property instead of text in the description.
> 
> Signed-off-by: David Heidelberg <david at ixit.cz>

Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>

> ---
>  .../devicetree/bindings/media/i2c/sony,imx283.yaml         | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
> index e4f49f1435a5..f4ee991c89a3 100644
> --- ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
> +++ ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
> @@ -13,16 +13,15 @@ maintainers:
>  
>  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.
> +  array size of 5472H x 3648V. It is programmable through I2C interface.
> +  Image data is sent through MIPI CSI-2.
>  
>  properties:
>    compatible:
>      const: sony,imx283
>  
>    reg:
> -    maxItems: 1
> +    const: 0x1a
>  
>    clocks:
>      description: Clock frequency from 6 to 24 MHz.
> -- 
> 2.45.2
>


From krzk at kernel.org  Mon Dec 16 23:07:38 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 08:07:38 +0100
Subject: [PATCH v3 3/5] ASoC: dt-bindings: audio-graph-card2: add widgets
 and hp-det-gpios support
In-Reply-To: <20241216145039.3074-4-laurentiumihalcea111@gmail.com>
References: <20241216145039.3074-1-laurentiumihalcea111@gmail.com>
 <20241216145039.3074-4-laurentiumihalcea111@gmail.com>
Message-ID: <nxcoukgiwtcsowi2uxytxa32mdp5dhl4tvnetpd2spti7oiiu3@mpqbv43ivznc>

On Mon, Dec 16, 2024 at 09:50:37AM -0500, Laurentiu Mihalcea wrote:
> From: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> 
> Introduce the 'widgets' property, allowing the creation of widgets from
> 4 template widgets: Microphone, Line, Headphone, and Speaker. Also
> introduce the 'hp-det-gpios' property, which allows using headphone
> detection using the specified GPIO.
> 
> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea at nxp.com>
> ---
>  .../devicetree/bindings/sound/audio-graph-card2.yaml          | 4 ++++

I have impression you are duplicating audio graph properties instead of
referencing proper schema, but considering that the bindings
audio-graph-card and audio-graph-card2 differ only by number "2" without
any description, not sure what is correct here.

Best regards,
Krzysztof



From Sandor.yu at nxp.com  Mon Dec 16 22:51:42 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:42 +0800
Subject: [PATCH v20 0/8] Initial support Cadence MHDP8501(HDMI/DP) for i.MX8MQ
Message-ID: <cover.1734340233.git.Sandor.yu@nxp.com>

The patch set initial support Cadence MHDP8501(HDMI/DP) DRM bridge
driver and Cadence HDP-TX PHY(HDMI/DP) driver for Freescale i.MX8MQ.

The patch set compose of DRM bridge drivers and PHY driver.

Both of them need by patch #1 and #3 to pass build.

DRM bridges driver patches:
  #1: soc: cadence: Create helper functions for Cadence MHDP
  #2: drm: bridge: cadence: Update mhdp8546 mailbox access functions
  #3: phy: Add HDMI configuration options
  #4: dt-bindings: display: bridge: Add Cadence MHDP8501
  #5: drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver

PHY driver patches:
  #1: soc: cadence: Create helper functions for Cadence MHDP
  #3: phy: Add HDMI configuration options
  #6: dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
  #7: phy: freescale: Add DisplayPort/HDMI Combo-PHY driver for i.MX8MQ

i.MX8M/TQMa8Mx DT patches:
  #8: Add DT nodes for DCSS/HDMI pipeline
  #9: Enable HDMI for TQMa8Mx/MBa8Mx

v19->v20:
Patch #1: soc: cadence: Create helper functions for Cadence MHDP
Patch #2: drm: bridge: cadence: Update mhdp8546 mailbox access functions
- The two patches are split from Patch #1 in v19.
  The MHDP helper functions have been moved in a new "cadence" directory
  under the SOC directory in patch #1, in order to promote code reuse
  among MHDP8546, MHDP8501, and the i.MX8MQ HDMI/DP PHY drivers,

Patch #3: phy: Add HDMI configuration options
- Add a-b tag

Patch #4: dt-bindings: display: bridge: Add Cadence MHDP8501
- remove data type link of data-lanes

Patch #5: drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
- Dump mhdp FW version by debugfs
- Combine HDMI and DP cable detect functions into one function
- Combine HDMI and DP cable bridge_mode_valid() functions into one function
- Rename cdns_hdmi_reset_link() to cdns_hdmi_handle_hotplug()
- Add comments for EDID in cdns_hdmi_handle_hotplug() and cdns_dp_check_link_state()
- Add atomic_get_input_bus_fmts() and bridge_atomic_check() for DP driver
- Remove bpc and color_fmt init in atomic_enable() function.
- More detail comments for DDC adapter only support SCDC_I2C_SLAVE_ADDRESS
  read and write in HDMI driver.

Patch #7: phy: freescale: Add DisplayPort/HDMI Combo-PHY driver for i.MX8MQ
- implify DP configuration handling by directly copying
  the configuration options to the driver's internal structure.
- return the error code directly instead of logging an error message in `hdptx_clk_enable`
- Remove redundant ref_clk_rate check


v18->v19:
Patch #1
- use guard(mutex)
- Add kerneldocs for all new APIs.
- Detail comments for mailbox access specific case.
- remove cdns_mhdp_dp_reg_write() because it is not needed by driver now.

Patch #3
- move property data-lanes to endpoint of port at 1

Patch #4
- get endpoint for data-lanes as it had move to endpoint of port at 1
- update clock management as devm_clk_get_enabled() introduced.
- Fix clear_infoframe() function is not work issue.
- Manage PHY power state via phy_power_on() and phy_power_off().

Patch #6
- Simplify the PLL table by removing unused and constant data
- Remove PHY power management, controller driver will handle them.
- Remove enum dp_link_rate
- introduce read_pll_timeout.
- update clock management as devm_clk_get_enabled() introduced.
- remove cdns_hdptx_phy_init() and cdns_hdptx_phy_remove().

Patch #8:
- move property data-lanes to endpoint of port at 1

v17->v18:
Patch #1
- Create three ordinary mailbox access APIs
    cdns_mhdp_mailbox_send
    cdns_mhdp_mailbox_send_recv
    cdns_mhdp_mailbox_send_recv_multi
- Create three secure mailbox access APIs
    cdns_mhdp_secure_mailbox_send
    cdns_mhdp_secure_mailbox_send_recv
    cdns_mhdp_secure_mailbox_send_recv_multi
- MHDP8546 DP and HDCP commands that need access mailbox are rewrited
  with above 6 API functions.

Patch #3
- remove lane-mapping and replace it with data-lanes
- remove r-b tag as property changed.

Patch #4
- MHDP8501 HDMI and DP commands that need access mailbox are rewrited
  with new API functions created in patch #1.
- replace lane-mapping with data-lanes, use the value from data-lanes
  to reorder HDMI and DP lane mapping.
- create I2C adapter for HDMI SCDC, remove cdns_hdmi_scdc_write() function.
- Rewrite cdns_hdmi_sink_config() function, use HDMI SCDC helper function
  drm_scdc_set_high_tmds_clock_ratio() and drm_scdc_set_scrambling()
  to config HDMI sink TMDS.
- Remove struct video_info from HDMI driver.
- Remove tmds_char_rate_valid() be called in bridge_mode_valid(),
  community had patch in reviewing to implement the function.
- Remove warning message print when get unknown HPD cable status.
- Add more detail comments for HDP plugin and plugout interrupt.
- use dev_dbg to repleace DRM_INFO when cable HPD status changed.
- Remove t-b tag as above code change.

Patch #6
- fix build error as code rebase to latest kernel version.

Patch #8:
- replace lane-mapping with data-lanes


v16->v17:
Patch #1:
- Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
Patch #2:
- remove hdmi.h
- add 2024 year to copyright
- Add r-b tag.
Patch #3:
- Add lane-mapping property.
Patch #4:
- Reset the HDMI/DP link when an HPD (Hot Plug Detect) event is detected
- Move the HDMI protocol settings from hdmi_ctrl_init() to a new function
  cdns_hdmi_set_hdmi_mode_type(), to align with the introduced link reset functionality.
- Implement logic to check the type of HDMI sink.
  If the sink is not a hdmi display, set the default mode to DVI.
- Implement hdmi_reset_infoframe function
- Reorder certain bit definitions in the header file to follow a descending order.
- Add "lane-mapping" property for both HDMI and DP, remove platform data from driver.
  lane-mapping should be setting in dts according different board layout.
- Remove variable mode in struct cdns_mhdp8501_device, video mode could get from struct drm_crtc_state
- Remove variable char_rate in  struct cdns_mhdp8501_device, it could get from struct struct drm_connector_state.hdmi
- Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
- Remove mutext protect for phy_api access functions.
Patch #6:
- Remove mbox_mutex

v15->v16:
Patch #2:
- Remove pixel_clk_rate, bpc and color_space fields from struct
  phy_configure_opts_hdmi, they were replaced by
  unsigned long long tmds_char_rate.
- Remove r-b and a-c tags because this patch have important change.
Patch #4:
- Add DRM_BRIDGE_OP_HDMI flags for HDMI driver,
- Introduce the hdmi info frame helper functions,
  added hdmi_clear_infoframe(), hdmi_write_infoframe() and
  hdmi_tmds_char_rate_valid() according Dmitry's patch
  'make use of the HDMI connector infrastructure' patchset ([2]).
- mode_fixup() is replaced by atomic_check().
- Fix video mode 4Kp30 did not work on some displays that support
  LTE_340Mcsc_scramble.
- updated for tmds_char_rate added in patch #2. 
Patch #6:
- updated for tmds_char_rate added in patch #2. 

v14->v15:
Patch #6 + #7:
-  Merged PHY driver into a single combo PHY driver
Patch #7 + #8:
- Add DT patches for a running HDMI setup

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/

Alexander Stein (2):
  arm64: dts: imx8mq: Add DCSS + HDMI/DP display pipeline
  arm64: dts: imx8mq: tqma8mq-mba8mx: Enable HDMI support

Sandor Yu (7):
  soc: cadence: Create helper functions for Cadence MHDP
  drm: bridge: cadence: Update mhdp8546 mailbox access functions
  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/HDMI Combo-PHY driver for i.MX8MQ

 .../display/bridge/cdns,mhdp8501.yaml         |  121 ++
 .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  |   51 +
 .../dts/freescale/imx8mq-tqma8mq-mba8mx.dts   |   26 +
 arch/arm64/boot/dts/freescale/imx8mq.dtsi     |   68 +
 arch/arm64/boot/dts/freescale/mba8mx.dtsi     |   11 +
 drivers/gpu/drm/bridge/cadence/Kconfig        |   17 +
 drivers/gpu/drm/bridge/cadence/Makefile       |    2 +
 .../drm/bridge/cadence/cdns-mhdp8501-core.c   |  379 +++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.h   |  380 +++++
 .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c |  694 ++++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   |  745 ++++++++++
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   |  487 ++-----
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |   47 +-
 .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   |  212 +--
 .../drm/bridge/cadence/cdns-mhdp8546-hdcp.h   |   18 +-
 drivers/phy/freescale/Kconfig                 |   10 +
 drivers/phy/freescale/Makefile                |    1 +
 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c  | 1231 +++++++++++++++++
 drivers/soc/Kconfig                           |    1 +
 drivers/soc/Makefile                          |    1 +
 drivers/soc/cadence/Kconfig                   |    9 +
 drivers/soc/cadence/Makefile                  |    3 +
 drivers/soc/cadence/cdns-mhdp-helper.c        |  565 ++++++++
 include/linux/phy/phy-hdmi.h                  |   19 +
 include/linux/phy/phy.h                       |    7 +-
 include/soc/cadence/cdns-mhdp-helper.h        |  129 ++
 26 files changed, 4572 insertions(+), 662 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-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-hdptx.c
 create mode 100644 drivers/soc/cadence/Kconfig
 create mode 100644 drivers/soc/cadence/Makefile
 create mode 100644 drivers/soc/cadence/cdns-mhdp-helper.c
 create mode 100644 include/linux/phy/phy-hdmi.h
 create mode 100644 include/soc/cadence/cdns-mhdp-helper.h

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:45 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:45 -0800
Subject: [PATCH v3 00/16] perf tools: Use generic syscall scripts for all
 archs
Message-ID: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>

Standardize the generation of syscall headers around syscall tables.
Previously each architecture independently selected how syscall headers
would be generated, or would not define a way and fallback onto
libaudit. Convert all architectures to use a standard syscall header
generation script and allow each architecture to override the syscall
table to use if they do not use the generic table.

As a result of these changes, no architecture will require libaudit, and
so the fallback case of using libaudit is removed by this series.

Testing:

I have tested that the syscall mappings of id to name generation works
as expected for every architecture, but I have only validated that perf
trace compiles and runs as expected on riscv, arm64, and x86_64.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
Changes in v3:
- Fix compiliation when OUTPUT is empty
- Correct unused headers to be .h instead of .c  (Namhyung)
- Make variable definition of supported archs (Namhyung)
- Convert += into := for syscalls headers (Namhyung)
- Link to v2: https://lore.kernel.org/r/20241212-perf_syscalltbl-v2-0-f8ca984ffe40 at rivosinc.com

Changes in v2:
- Rebase onto 6.13-rc2
- Fix output path so it generates to /tools/perf/arch properly
- Link to v1: https://lore.kernel.org/r/20241104-perf_syscalltbl-v1-0-9adae5c761ef at rivosinc.com

---
Charlie Jenkins (16):
      perf tools: Create generic syscall table support
      perf tools: arc: Support generic syscall headers
      perf tools: csky: Support generic syscall headers
      perf tools: arm: Support syscall headers
      perf tools: sh: Support syscall headers
      perf tools: sparc: Support syscall headers
      perf tools: xtensa: Support syscall header
      perf tools: x86: Use generic syscall scripts
      perf tools: alpha: Support syscall header
      perf tools: parisc: Support syscall header
      perf tools: arm64: Use syscall table
      perf tools: loongarch: Use syscall table
      perf tools: mips: Use generic syscall scripts
      perf tools: powerpc: Use generic syscall table scripts
      perf tools: s390: Use generic syscall table scripts
      perf tools: Remove dependency on libaudit

 Documentation/admin-guide/workload-tracing.rst     |   2 +-
 tools/build/feature/Makefile                       |   4 -
 tools/build/feature/test-libaudit.c                |  11 -
 tools/perf/Documentation/perf-check.txt            |   1 -
 tools/perf/Makefile.config                         |  39 +-
 tools/perf/Makefile.perf                           |  12 +-
 tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
 .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 ++++++++++++++++++++
 tools/perf/arch/alpha/include/syscall_table.h      |   2 +
 tools/perf/arch/arc/entry/syscalls/Kbuild          |   2 +
 .../perf/arch/arc/entry/syscalls/Makefile.syscalls |   3 +
 tools/perf/arch/arc/include/syscall_table.h        |   2 +
 tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
 .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
 tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 483 +++++++++++++++++++
 tools/perf/arch/arm/include/syscall_table.h        |   2 +
 tools/perf/arch/arm64/Makefile                     |  22 -
 tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
 .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
 .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++
 .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
 tools/perf/arch/arm64/include/syscall_table.h      |   8 +
 tools/perf/arch/csky/entry/syscalls/Kbuild         |   2 +
 .../arch/csky/entry/syscalls/Makefile.syscalls     |   3 +
 tools/perf/arch/csky/include/syscall_table.h       |   2 +
 tools/perf/arch/loongarch/Makefile                 |  22 -
 tools/perf/arch/loongarch/entry/syscalls/Kbuild    |   2 +
 .../loongarch/entry/syscalls/Makefile.syscalls     |   3 +
 .../arch/loongarch/entry/syscalls/mksyscalltbl     |  45 --
 tools/perf/arch/loongarch/include/syscall_table.h  |   2 +
 tools/perf/arch/mips/entry/syscalls/Kbuild         |   2 +
 .../arch/mips/entry/syscalls/Makefile.syscalls     |   5 +
 tools/perf/arch/mips/entry/syscalls/mksyscalltbl   |  32 --
 tools/perf/arch/mips/include/syscall_table.h       |   2 +
 tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
 .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
 tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++
 tools/perf/arch/parisc/include/syscall_table.h     |   8 +
 tools/perf/arch/powerpc/Makefile                   |  25 -
 tools/perf/arch/powerpc/entry/syscalls/Kbuild      |   3 +
 .../arch/powerpc/entry/syscalls/Makefile.syscalls  |   6 +
 .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  |  39 --
 tools/perf/arch/powerpc/include/syscall_table.h    |   8 +
 tools/perf/arch/riscv/Makefile                     |  22 -
 tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
 .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
 tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 --
 tools/perf/arch/riscv/include/syscall_table.h      |   8 +
 tools/perf/arch/s390/Makefile                      |  21 -
 tools/perf/arch/s390/entry/syscalls/Kbuild         |   2 +
 .../arch/s390/entry/syscalls/Makefile.syscalls     |   5 +
 tools/perf/arch/s390/entry/syscalls/mksyscalltbl   |  32 --
 tools/perf/arch/s390/include/syscall_table.h       |   2 +
 tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
 .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
 tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 472 +++++++++++++++++++
 tools/perf/arch/sh/include/syscall_table.h         |   2 +
 tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
 .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 514 +++++++++++++++++++++
 tools/perf/arch/sparc/include/syscall_table.h      |   8 +
 tools/perf/arch/x86/Build                          |   1 -
 tools/perf/arch/x86/Makefile                       |  25 -
 tools/perf/arch/x86/entry/syscalls/Kbuild          |   3 +
 .../perf/arch/x86/entry/syscalls/Makefile.syscalls |   6 +
 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   |  42 --
 tools/perf/arch/x86/include/syscall_table.h        |   8 +
 tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
 .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 439 ++++++++++++++++++
 tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
 tools/perf/builtin-check.c                         |   1 -
 tools/perf/builtin-help.c                          |   2 -
 tools/perf/builtin-trace.c                         |  30 --
 tools/perf/check-headers.sh                        |   9 +
 tools/perf/perf.c                                  |   6 +-
 tools/perf/scripts/Makefile.syscalls               |  61 +++
 tools/perf/scripts/syscalltbl.sh                   |  86 ++++
 tools/perf/tests/make                              |   7 +-
 tools/perf/util/env.c                              |   4 +-
 tools/perf/util/generate-cmdlist.sh                |   4 +-
 tools/perf/util/syscalltbl.c                       |  90 +---
 tools/scripts/syscall.tbl                          | 409 ++++++++++++++++
 85 files changed, 4102 insertions(+), 619 deletions(-)
---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20240913-perf_syscalltbl-6f98defcc6f5
-- 
- Charlie



From charlie at rivosinc.com  Mon Dec 16 22:32:46 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:46 -0800
Subject: [PATCH v3 01/16] perf tools: Create generic syscall table support
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-1-239f032481d5@rivosinc.com>

Currently each architecture in perf independently generates syscall
headers. Adapt the work that has gone into unifying syscall header
implementations in the kernel to work with perf tools. Introduce this
framework with riscv at first. riscv previously relied on libaudit, but
with this change, perf tools for riscv no longer needs this external
dependency.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  11 +-
 tools/perf/Makefile.perf                           |   4 +
 tools/perf/arch/riscv/Makefile                     |  22 --
 tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
 .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
 tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 ---
 tools/perf/arch/riscv/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   1 +
 tools/perf/scripts/Makefile.syscalls               |  61 +++
 tools/perf/scripts/syscalltbl.sh                   |  86 +++++
 tools/perf/util/syscalltbl.c                       |   8 +-
 tools/scripts/syscall.tbl                          | 409 +++++++++++++++++++++
 12 files changed, 586 insertions(+), 77 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 2916d59c88cd08b299202a48ddb42fa32aac04a6..6e4d0ef58ccb40da793f3ab8cca77d620d258bb4 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -35,6 +35,13 @@ ifneq ($(NO_SYSCALL_TABLE),1)
     NO_SYSCALL_TABLE := 0
   endif
 
+  # architectures that use the generic syscall table scripts
+  ifeq ($(SRCARCH),riscv)
+    NO_SYSCALL_TABLE := 0
+    CFLAGS += -DGENERIC_SYSCALL_TABLE
+    CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
+  endif
+
   ifneq ($(NO_SYSCALL_TABLE),1)
     CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
   endif
@@ -83,10 +90,6 @@ ifeq ($(ARCH),mips)
   LIBUNWIND_LIBS = -lunwind -lunwind-mips
 endif
 
-ifeq ($(ARCH),riscv)
-  CFLAGS += -I$(OUTPUT)arch/riscv/include/generated
-endif
-
 # So far there's only x86 and arm libdw unwind support merged in perf.
 # Disable it on all other architectures in case libdw unwind
 # support is detected in system. Add supported architectures
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index d74241a151313bd09101aabb5d765a5a0a6efc84..f5278ed9f778f928436693a14e016c5c3c5171c1 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -310,6 +310,10 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
 FEATURE_TESTS := all
 endif
 endif
+# architectures that use the generic syscall table
+ifeq ($(SRCARCH),riscv)
+include $(srctree)/tools/perf/scripts/Makefile.syscalls
+endif
 include Makefile.config
 endif
 
diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
index 18ad078000e2bba595f92efc5d97a63fdb83ef45..087e099fb453a9236db34878077a51f711881ce0 100644
--- a/tools/perf/arch/riscv/Makefile
+++ b/tools/perf/arch/riscv/Makefile
@@ -1,25 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/riscv/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/riscv/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/riscv/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, riscv) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/riscv/entry/syscalls/Kbuild b/tools/perf/arch/riscv/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/riscv/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..9668fd1faf60e828ed2786c2ee84739ac1f153fc
--- /dev/null
+++ b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += riscv memfd_secret
+syscall_abis_64 += riscv rlimit memfd_secret
diff --git a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl b/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
deleted file mode 100755
index c59f5e852b97712a9a879b89e6ef6999ed4b6cd7..0000000000000000000000000000000000000000
--- a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-# Changed by: Kim Phillips <kim.phillips at arm.com>
-# Changed by: Bj?rn T?pel <bjorn at rivosinc.com>
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_RISCV_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_riscv[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/riscv/include/syscall_table.h b/tools/perf/arch/riscv/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/riscv/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index a05c1c105c51bf1bd18a59195220894598eb7461..692f48db810ccbef229e240db29261f0c60db632 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -71,6 +71,7 @@ FILES=(
   "include/uapi/asm-generic/ioctls.h"
   "include/uapi/asm-generic/mman-common.h"
   "include/uapi/asm-generic/unistd.h"
+  "scripts/syscall.tbl"
 )
 
 declare -a SYNC_CHECK_FILES
diff --git a/tools/perf/scripts/Makefile.syscalls b/tools/perf/scripts/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..0bf27d679b5bb2da6c0eefbc44e10bc44b51da0f
--- /dev/null
+++ b/tools/perf/scripts/Makefile.syscalls
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: GPL-2.0
+# This Makefile generates headers in
+# tools/perf/arch/$(SRCARCH)/include/generated/asm from the architecture's
+# syscall table. This will either be from the generic syscall table, or from a
+# table that is specific to that architecture.
+
+PHONY := all
+all:
+
+obj := $(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated/asm
+
+syscall_abis_32  := common,32
+syscall_abis_64  := common,64
+syscalltbl := $(srctree)/tools/scripts/syscall.tbl
+
+# let architectures override $(syscall_abis_%) and $(syscalltbl)
+-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Makefile.syscalls
+include $(srctree)/scripts/Kbuild.include
+-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Kbuild
+
+systbl := $(srctree)/tools/perf/scripts/syscalltbl.sh
+
+syscall-y   := $(addprefix $(obj)/, $(syscall-y))
+
+# Remove stale wrappers when the corresponding files are removed from generic-y
+old-headers := $(wildcard $(obj)/*.h)
+unwanted    := $(filter-out $(syscall-y),$(old-headers))
+
+quiet_cmd_remove = REMOVE  $(unwanted)
+      cmd_remove = rm -f $(unwanted)
+
+quiet_cmd_systbl = SYSTBL  $@
+      cmd_systbl = $(CONFIG_SHELL) $(systbl) \
+		   $(if $(systbl-args-$*),$(systbl-args-$*),$(systbl-args)) \
+		   --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \
+		   $< $@
+
+all: $(syscall-y)
+	$(if $(unwanted),$(call cmd,remove))
+	@:
+
+$(obj)/syscalls_%.h: $(syscalltbl) $(systbl) FORCE
+	$(call if_changed,systbl)
+
+targets := $(syscall-y)
+
+# Create output directory. Skip it if at least one old header exists
+# since we know the output directory already exists.
+ifeq ($(old-headers),)
+$(shell mkdir -p $(obj))
+endif
+
+PHONY += FORCE
+
+FORCE:
+
+existing-targets := $(wildcard $(sort $(targets)))
+
+-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
+
+.PHONY: $(PHONY)
diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1ce0d5aa8b506427a66be50f0f441cf6e9705b33
--- /dev/null
+++ b/tools/perf/scripts/syscalltbl.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generate a syscall table header.
+#
+# Each line of the syscall table should have the following format:
+#
+# NR ABI NAME [NATIVE] [COMPAT]
+#
+# NR       syscall number
+# ABI      ABI name
+# NAME     syscall name
+# NATIVE   native entry point (optional)
+# COMPAT   compat entry point (optional)
+
+set -e
+
+usage() {
+	echo >&2 "usage: $0 [--abis ABIS] INFILE OUTFILE" >&2
+	echo >&2
+	echo >&2 "  INFILE    input syscall table"
+	echo >&2 "  OUTFILE   output header file"
+	echo >&2
+	echo >&2 "options:"
+	echo >&2 "  --abis ABIS        ABI(s) to handle (By default, all lines are handled)"
+	exit 1
+}
+
+# default unless specified by options
+abis=
+
+while [ $# -gt 0 ]
+do
+	case $1 in
+	--abis)
+		abis=$(echo "($2)" | tr ',' '|')
+		shift 2;;
+	-*)
+		echo "$1: unknown option" >&2
+		usage;;
+	*)
+		break;;
+	esac
+done
+
+if [ $# -ne 2 ]; then
+	usage
+fi
+
+infile="$1"
+outfile="$2"
+
+nxt=0
+
+syscall_macro() {
+    nr="$1"
+    name="$2"
+
+    echo "	[$nr] = \"$name\","
+}
+
+emit() {
+    nr="$1"
+    entry="$2"
+
+    syscall_macro "$nr" "$entry"
+}
+
+echo "static const char *const syscalltbl[] = {" > $outfile
+
+sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
+grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table
+
+max_nr=0
+# the params are: nr abi name entry compat
+# use _ for intentionally unused variables according to SC2034
+while read nr _ name _ _; do
+    emit "$nr" "$name" >> $outfile
+    max_nr=$nr
+done < $sorted_table
+
+rm -f $sorted_table
+
+echo "};" >> $outfile
+
+echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 69d8dcf5cf28c4e8a0e403153c92bd6436e2a0b2..ccf234a54366f9921c3b9a02ffb0a365d17244bc 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -46,10 +46,10 @@ static const char *const *syscalltbl_native = syscalltbl_mips_n64;
 #include <asm/syscalls.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_loongarch;
-#elif defined(__riscv)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_RISCV_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_riscv;
+#elif defined(GENERIC_SYSCALL_TABLE)
+#include <syscall_table.h>
+const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
+static const char *const *syscalltbl_native = syscalltbl;
 #else
 const int syscalltbl_native_max_id = 0;
 static const char *const syscalltbl_native[] = {
diff --git a/tools/scripts/syscall.tbl b/tools/scripts/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..ebbdb3c42e9f74613b003014c0baf44c842bb756
--- /dev/null
+++ b/tools/scripts/syscall.tbl
@@ -0,0 +1,409 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# This file contains the system call numbers for all of the
+# more recently added architectures.
+#
+# As a basic principle, no duplication of functionality
+# should be added, e.g. we don't use lseek when llseek
+# is present. New architectures should use this file
+# and implement the less feature-full calls in user space.
+#
+0	common	io_setup			sys_io_setup			compat_sys_io_setup
+1	common	io_destroy			sys_io_destroy
+2	common	io_submit			sys_io_submit			compat_sys_io_submit
+3	common	io_cancel			sys_io_cancel
+4	time32	io_getevents			sys_io_getevents_time32
+4	64	io_getevents			sys_io_getevents
+5	common	setxattr			sys_setxattr
+6	common	lsetxattr			sys_lsetxattr
+7	common	fsetxattr			sys_fsetxattr
+8	common	getxattr			sys_getxattr
+9	common	lgetxattr			sys_lgetxattr
+10	common	fgetxattr			sys_fgetxattr
+11	common	listxattr			sys_listxattr
+12	common	llistxattr			sys_llistxattr
+13	common	flistxattr			sys_flistxattr
+14	common	removexattr			sys_removexattr
+15	common	lremovexattr			sys_lremovexattr
+16	common	fremovexattr			sys_fremovexattr
+17	common	getcwd				sys_getcwd
+18	common	lookup_dcookie			sys_ni_syscall
+19	common	eventfd2			sys_eventfd2
+20	common	epoll_create1			sys_epoll_create1
+21	common	epoll_ctl			sys_epoll_ctl
+22	common	epoll_pwait			sys_epoll_pwait			compat_sys_epoll_pwait
+23	common	dup				sys_dup
+24	common	dup3				sys_dup3
+25	32	fcntl64				sys_fcntl64			compat_sys_fcntl64
+25	64	fcntl				sys_fcntl
+26	common	inotify_init1			sys_inotify_init1
+27	common	inotify_add_watch		sys_inotify_add_watch
+28	common	inotify_rm_watch		sys_inotify_rm_watch
+29	common	ioctl				sys_ioctl			compat_sys_ioctl
+30	common	ioprio_set			sys_ioprio_set
+31	common	ioprio_get			sys_ioprio_get
+32	common	flock				sys_flock
+33	common	mknodat				sys_mknodat
+34	common	mkdirat				sys_mkdirat
+35	common	unlinkat			sys_unlinkat
+36	common	symlinkat			sys_symlinkat
+37	common	linkat				sys_linkat
+# renameat is superseded with flags by renameat2
+38	renameat renameat			sys_renameat
+39	common	umount2				sys_umount
+40	common	mount				sys_mount
+41	common	pivot_root			sys_pivot_root
+42	common	nfsservctl			sys_ni_syscall
+43	32	statfs64			sys_statfs64			compat_sys_statfs64
+43	64	statfs				sys_statfs
+44	32	fstatfs64			sys_fstatfs64			compat_sys_fstatfs64
+44	64	fstatfs				sys_fstatfs
+45	32	truncate64			sys_truncate64			compat_sys_truncate64
+45	64	truncate			sys_truncate
+46	32	ftruncate64			sys_ftruncate64			compat_sys_ftruncate64
+46	64	ftruncate			sys_ftruncate
+47	common	fallocate			sys_fallocate			compat_sys_fallocate
+48	common	faccessat			sys_faccessat
+49	common	chdir				sys_chdir
+50	common	fchdir				sys_fchdir
+51	common	chroot				sys_chroot
+52	common	fchmod				sys_fchmod
+53	common	fchmodat			sys_fchmodat
+54	common	fchownat			sys_fchownat
+55	common	fchown				sys_fchown
+56	common	openat				sys_openat
+57	common	close				sys_close
+58	common	vhangup				sys_vhangup
+59	common	pipe2				sys_pipe2
+60	common	quotactl			sys_quotactl
+61	common	getdents64			sys_getdents64
+62	32	llseek				sys_llseek
+62	64	lseek				sys_lseek
+63	common	read				sys_read
+64	common	write				sys_write
+65	common	readv				sys_readv			sys_readv
+66	common	writev				sys_writev			sys_writev
+67	common	pread64				sys_pread64			compat_sys_pread64
+68	common	pwrite64			sys_pwrite64			compat_sys_pwrite64
+69	common	preadv				sys_preadv			compat_sys_preadv
+70	common	pwritev				sys_pwritev			compat_sys_pwritev
+71	32	sendfile64			sys_sendfile64
+71	64	sendfile			sys_sendfile64
+72	time32	pselect6			sys_pselect6_time32		compat_sys_pselect6_time32
+72	64	pselect6			sys_pselect6
+73	time32	ppoll				sys_ppoll_time32		compat_sys_ppoll_time32
+73	64	ppoll				sys_ppoll
+74	common	signalfd4			sys_signalfd4			compat_sys_signalfd4
+75	common	vmsplice			sys_vmsplice
+76	common	splice				sys_splice
+77	common	tee				sys_tee
+78	common	readlinkat			sys_readlinkat
+79	stat64	fstatat64			sys_fstatat64
+79	64	newfstatat			sys_newfstatat
+80	stat64	fstat64				sys_fstat64
+80	64	fstat				sys_newfstat
+81	common	sync				sys_sync
+82	common	fsync				sys_fsync
+83	common	fdatasync			sys_fdatasync
+84	common	sync_file_range			sys_sync_file_range		compat_sys_sync_file_range
+85	common	timerfd_create			sys_timerfd_create
+86	time32	timerfd_settime			sys_timerfd_settime32
+86	64	timerfd_settime			sys_timerfd_settime
+87	time32	timerfd_gettime			sys_timerfd_gettime32
+87	64	timerfd_gettime			sys_timerfd_gettime
+88	time32	utimensat			sys_utimensat_time32
+88	64	utimensat			sys_utimensat
+89	common	acct				sys_acct
+90	common	capget				sys_capget
+91	common	capset				sys_capset
+92	common	personality			sys_personality
+93	common	exit				sys_exit
+94	common	exit_group			sys_exit_group
+95	common	waitid				sys_waitid			compat_sys_waitid
+96	common	set_tid_address			sys_set_tid_address
+97	common	unshare				sys_unshare
+98	time32	futex				sys_futex_time32
+98	64	futex				sys_futex
+99	common	set_robust_list			sys_set_robust_list		compat_sys_set_robust_list
+100	common	get_robust_list			sys_get_robust_list		compat_sys_get_robust_list
+101	time32	nanosleep			sys_nanosleep_time32
+101	64	nanosleep			sys_nanosleep
+102	common	getitimer			sys_getitimer			compat_sys_getitimer
+103	common	setitimer			sys_setitimer			compat_sys_setitimer
+104	common	kexec_load			sys_kexec_load			compat_sys_kexec_load
+105	common	init_module			sys_init_module
+106	common	delete_module			sys_delete_module
+107	common	timer_create			sys_timer_create		compat_sys_timer_create
+108	time32	timer_gettime			sys_timer_gettime32
+108	64	timer_gettime			sys_timer_gettime
+109	common	timer_getoverrun		sys_timer_getoverrun
+110	time32	timer_settime			sys_timer_settime32
+110	64	timer_settime			sys_timer_settime
+111	common	timer_delete			sys_timer_delete
+112	time32	clock_settime			sys_clock_settime32
+112	64	clock_settime			sys_clock_settime
+113	time32	clock_gettime			sys_clock_gettime32
+113	64	clock_gettime			sys_clock_gettime
+114	time32	clock_getres			sys_clock_getres_time32
+114	64	clock_getres			sys_clock_getres
+115	time32	clock_nanosleep			sys_clock_nanosleep_time32
+115	64	clock_nanosleep			sys_clock_nanosleep
+116	common	syslog				sys_syslog
+117	common	ptrace				sys_ptrace			compat_sys_ptrace
+118	common	sched_setparam			sys_sched_setparam
+119	common	sched_setscheduler		sys_sched_setscheduler
+120	common	sched_getscheduler		sys_sched_getscheduler
+121	common	sched_getparam			sys_sched_getparam
+122	common	sched_setaffinity		sys_sched_setaffinity		compat_sys_sched_setaffinity
+123	common	sched_getaffinity		sys_sched_getaffinity		compat_sys_sched_getaffinity
+124	common	sched_yield			sys_sched_yield
+125	common	sched_get_priority_max		sys_sched_get_priority_max
+126	common	sched_get_priority_min		sys_sched_get_priority_min
+127	time32	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+127	64	sched_rr_get_interval		sys_sched_rr_get_interval
+128	common	restart_syscall			sys_restart_syscall
+129	common	kill				sys_kill
+130	common	tkill				sys_tkill
+131	common	tgkill				sys_tgkill
+132	common	sigaltstack			sys_sigaltstack			compat_sys_sigaltstack
+133	common	rt_sigsuspend			sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+134	common	rt_sigaction			sys_rt_sigaction		compat_sys_rt_sigaction
+135	common	rt_sigprocmask			sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+136	common	rt_sigpending			sys_rt_sigpending		compat_sys_rt_sigpending
+137	time32	rt_sigtimedwait			sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+137	64	rt_sigtimedwait			sys_rt_sigtimedwait
+138	common	rt_sigqueueinfo			sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+139	common	rt_sigreturn			sys_rt_sigreturn		compat_sys_rt_sigreturn
+140	common	setpriority			sys_setpriority
+141	common	getpriority			sys_getpriority
+142	common	reboot				sys_reboot
+143	common	setregid			sys_setregid
+144	common	setgid				sys_setgid
+145	common	setreuid			sys_setreuid
+146	common	setuid				sys_setuid
+147	common	setresuid			sys_setresuid
+148	common	getresuid			sys_getresuid
+149	common	setresgid			sys_setresgid
+150	common	getresgid			sys_getresgid
+151	common	setfsuid			sys_setfsuid
+152	common	setfsgid			sys_setfsgid
+153	common	times				sys_times			compat_sys_times
+154	common	setpgid				sys_setpgid
+155	common	getpgid				sys_getpgid
+156	common	getsid				sys_getsid
+157	common	setsid				sys_setsid
+158	common	getgroups			sys_getgroups
+159	common	setgroups			sys_setgroups
+160	common	uname				sys_newuname
+161	common	sethostname			sys_sethostname
+162	common	setdomainname			sys_setdomainname
+# getrlimit and setrlimit are superseded with prlimit64
+163	rlimit	getrlimit			sys_getrlimit			compat_sys_getrlimit
+164	rlimit	setrlimit			sys_setrlimit			compat_sys_setrlimit
+165	common	getrusage			sys_getrusage			compat_sys_getrusage
+166	common	umask				sys_umask
+167	common	prctl				sys_prctl
+168	common	getcpu				sys_getcpu
+169	time32	gettimeofday			sys_gettimeofday		compat_sys_gettimeofday
+169	64	gettimeofday			sys_gettimeofday
+170	time32	settimeofday			sys_settimeofday		compat_sys_settimeofday
+170	64	settimeofday			sys_settimeofday
+171	time32	adjtimex			sys_adjtimex_time32
+171	64	adjtimex			sys_adjtimex
+172	common	getpid				sys_getpid
+173	common	getppid				sys_getppid
+174	common	getuid				sys_getuid
+175	common	geteuid				sys_geteuid
+176	common	getgid				sys_getgid
+177	common	getegid				sys_getegid
+178	common	gettid				sys_gettid
+179	common	sysinfo				sys_sysinfo			compat_sys_sysinfo
+180	common	mq_open				sys_mq_open			compat_sys_mq_open
+181	common	mq_unlink			sys_mq_unlink
+182	time32	mq_timedsend			sys_mq_timedsend_time32
+182	64	mq_timedsend			sys_mq_timedsend
+183	time32	mq_timedreceive			sys_mq_timedreceive_time32
+183	64	mq_timedreceive			sys_mq_timedreceive
+184	common	mq_notify			sys_mq_notify			compat_sys_mq_notify
+185	common	mq_getsetattr			sys_mq_getsetattr		compat_sys_mq_getsetattr
+186	common	msgget				sys_msgget
+187	common	msgctl				sys_msgctl			compat_sys_msgctl
+188	common	msgrcv				sys_msgrcv			compat_sys_msgrcv
+189	common	msgsnd				sys_msgsnd			compat_sys_msgsnd
+190	common	semget				sys_semget
+191	common	semctl				sys_semctl			compat_sys_semctl
+192	time32	semtimedop			sys_semtimedop_time32
+192	64	semtimedop			sys_semtimedop
+193	common	semop				sys_semop
+194	common	shmget				sys_shmget
+195	common	shmctl				sys_shmctl			compat_sys_shmctl
+196	common	shmat				sys_shmat			compat_sys_shmat
+197	common	shmdt				sys_shmdt
+198	common	socket				sys_socket
+199	common	socketpair			sys_socketpair
+200	common	bind				sys_bind
+201	common	listen				sys_listen
+202	common	accept				sys_accept
+203	common	connect				sys_connect
+204	common	getsockname			sys_getsockname
+205	common	getpeername			sys_getpeername
+206	common	sendto				sys_sendto
+207	common	recvfrom			sys_recvfrom			compat_sys_recvfrom
+208	common	setsockopt			sys_setsockopt			sys_setsockopt
+209	common	getsockopt			sys_getsockopt			sys_getsockopt
+210	common	shutdown			sys_shutdown
+211	common	sendmsg				sys_sendmsg			compat_sys_sendmsg
+212	common	recvmsg				sys_recvmsg			compat_sys_recvmsg
+213	common	readahead			sys_readahead			compat_sys_readahead
+214	common	brk				sys_brk
+215	common	munmap				sys_munmap
+216	common	mremap				sys_mremap
+217	common	add_key				sys_add_key
+218	common	request_key			sys_request_key
+219	common	keyctl				sys_keyctl			compat_sys_keyctl
+220	common	clone				sys_clone
+221	common	execve				sys_execve			compat_sys_execve
+222	32	mmap2				sys_mmap2
+222	64	mmap				sys_mmap
+223	32	fadvise64_64			sys_fadvise64_64		compat_sys_fadvise64_64
+223	64	fadvise64			sys_fadvise64_64
+224	common	swapon				sys_swapon
+225	common	swapoff				sys_swapoff
+226	common	mprotect			sys_mprotect
+227	common	msync				sys_msync
+228	common	mlock				sys_mlock
+229	common	munlock				sys_munlock
+230	common	mlockall			sys_mlockall
+231	common	munlockall			sys_munlockall
+232	common	mincore				sys_mincore
+233	common	madvise				sys_madvise
+234	common	remap_file_pages		sys_remap_file_pages
+235	common	mbind				sys_mbind
+236	common	get_mempolicy			sys_get_mempolicy
+237	common	set_mempolicy			sys_set_mempolicy
+238	common	migrate_pages			sys_migrate_pages
+239	common	move_pages			sys_move_pages
+240	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+241	common	perf_event_open			sys_perf_event_open
+242	common	accept4				sys_accept4
+243	time32	recvmmsg			sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+243	64	recvmmsg			sys_recvmmsg
+# Architectures may provide up to 16 syscalls of their own between 244 and 259
+244	arc	cacheflush			sys_cacheflush
+245	arc	arc_settls			sys_arc_settls
+246	arc	arc_gettls			sys_arc_gettls
+247	arc	sysfs				sys_sysfs
+248	arc	arc_usr_cmpxchg			sys_arc_usr_cmpxchg
+
+244	csky	set_thread_area			sys_set_thread_area
+245	csky	cacheflush			sys_cacheflush
+
+244	nios2	cacheflush			sys_cacheflush
+
+244	or1k	or1k_atomic			sys_or1k_atomic
+
+258	riscv	riscv_hwprobe			sys_riscv_hwprobe
+259	riscv	riscv_flush_icache		sys_riscv_flush_icache
+
+260	time32	wait4				sys_wait4			compat_sys_wait4
+260	64	wait4				sys_wait4
+261	common	prlimit64			sys_prlimit64
+262	common	fanotify_init			sys_fanotify_init
+263	common	fanotify_mark			sys_fanotify_mark
+264	common	name_to_handle_at		sys_name_to_handle_at
+265	common	open_by_handle_at		sys_open_by_handle_at
+266	time32	clock_adjtime			sys_clock_adjtime32
+266	64	clock_adjtime			sys_clock_adjtime
+267	common	syncfs				sys_syncfs
+268	common	setns				sys_setns
+269	common	sendmmsg			sys_sendmmsg			compat_sys_sendmmsg
+270	common	process_vm_readv		sys_process_vm_readv
+271	common	process_vm_writev		sys_process_vm_writev
+272	common	kcmp				sys_kcmp
+273	common	finit_module			sys_finit_module
+274	common	sched_setattr			sys_sched_setattr
+275	common	sched_getattr			sys_sched_getattr
+276	common	renameat2			sys_renameat2
+277	common	seccomp				sys_seccomp
+278	common	getrandom			sys_getrandom
+279	common	memfd_create			sys_memfd_create
+280	common	bpf				sys_bpf
+281	common	execveat			sys_execveat			compat_sys_execveat
+282	common	userfaultfd			sys_userfaultfd
+283	common	membarrier			sys_membarrier
+284	common	mlock2				sys_mlock2
+285	common	copy_file_range			sys_copy_file_range
+286	common	preadv2				sys_preadv2			compat_sys_preadv2
+287	common	pwritev2			sys_pwritev2			compat_sys_pwritev2
+288	common	pkey_mprotect			sys_pkey_mprotect
+289	common	pkey_alloc			sys_pkey_alloc
+290	common	pkey_free			sys_pkey_free
+291	common	statx				sys_statx
+292	time32	io_pgetevents			sys_io_pgetevents_time32	compat_sys_io_pgetevents
+292	64	io_pgetevents			sys_io_pgetevents
+293	common	rseq				sys_rseq
+294	common	kexec_file_load			sys_kexec_file_load
+# 295 through 402 are unassigned to sync up with generic numbers don't use
+403	32	clock_gettime64			sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+447	memfd_secret	memfd_secret		sys_memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:47 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:47 -0800
Subject: [PATCH v3 02/16] perf tools: arc: Support generic syscall headers
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-2-239f032481d5@rivosinc.com>

Arc uses the generic syscall table, use that in perf instead of
requiring libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                           | 2 +-
 tools/perf/Makefile.perf                             | 3 ++-
 tools/perf/arch/arc/entry/syscalls/Kbuild            | 2 ++
 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls | 3 +++
 tools/perf/arch/arc/include/syscall_table.h          | 2 ++
 5 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 6e4d0ef58ccb40da793f3ab8cca77d620d258bb4..d3c12c6ba6764e9a8b12acee603a0509154f2c74 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),riscv)
+  ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f5278ed9f778f928436693a14e016c5c3c5171c1..f717e4628d9e4632f53fed16524a659a3e4feea5 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,8 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),riscv)
+generic_syscall_table_archs := riscv arc
+ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/arc/entry/syscalls/Kbuild b/tools/perf/arch/arc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/arc/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..391d30ab7a831b72d2ed3f2e7966fdbf558a9ed7
--- /dev/null
+++ b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += arc time32 renameat stat64 rlimit
diff --git a/tools/perf/arch/arc/include/syscall_table.h b/tools/perf/arch/arc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/arc/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:48 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:48 -0800
Subject: [PATCH v3 03/16] perf tools: csky: Support generic syscall headers
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-3-239f032481d5@rivosinc.com>

csky uses the generic syscall table, use that in perf instead of
requiring libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                              | 2 +-
 tools/perf/arch/csky/entry/syscalls/Kbuild            | 2 ++
 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls | 3 +++
 tools/perf/arch/csky/include/syscall_table.h          | 2 ++
 4 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f717e4628d9e4632f53fed16524a659a3e4feea5..b20daf3769771a7c23cc0f7dd46f562510bc3199 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc
+generic_syscall_table_archs := riscv arc csky
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/csky/entry/syscalls/Kbuild b/tools/perf/arch/csky/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/csky/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls b/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..ea2dd10d0571df464574a9c0232ada0ac1f79a3f
--- /dev/null
+++ b/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += csky time32 stat64 rlimit
diff --git a/tools/perf/arch/csky/include/syscall_table.h b/tools/perf/arch/csky/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/csky/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:49 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:49 -0800
Subject: [PATCH v3 04/16] perf tools: arm: Support syscall headers
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-4-239f032481d5@rivosinc.com>

arm uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
 .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
 tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 483 +++++++++++++++++++++
 tools/perf/arch/arm/include/syscall_table.h        |   2 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 493 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index b20daf3769771a7c23cc0f7dd46f562510bc3199..fa69b056bab31568baba78a9903312bd37b98067 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky
+generic_syscall_table_archs := riscv arc csky arm
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/arm/entry/syscalls/Kbuild b/tools/perf/arch/arm/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9d777540f08987908a6532c5ece66553dffc52df
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/Kbuild
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += oabi
+syscalltbl = $(srctree)/tools/perf/arch/arm/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arm/entry/syscalls/syscall.tbl b/tools/perf/arch/arm/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..49eeb2ad8dbd8e074c6240417693f23fb328afa8
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/syscall.tbl
@@ -0,0 +1,483 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# Linux system call numbers and entry vectors
+#
+# The format is:
+# <num>	<abi>	<name>			[<entry point>			[<oabi compat entry point>]]
+#
+# Where abi is:
+#  common - for system calls shared between oabi and eabi (may have compat)
+#  oabi   - for oabi-only system calls (may have compat)
+#  eabi   - for eabi-only system calls
+#
+# For each syscall number, "common" is mutually exclusive with oabi and eabi
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open
+6	common	close			sys_close
+# 7 was sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve
+12	common	chdir			sys_chdir
+13	oabi	time			sys_time32
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19	common	lseek			sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+22	oabi	umount			sys_oldumount
+23	common	setuid			sys_setuid16
+24	common	getuid			sys_getuid16
+25	oabi	stime			sys_stime32
+26	common	ptrace			sys_ptrace
+27	oabi	alarm			sys_alarm
+# 28 was sys_fstat
+29	common	pause			sys_pause
+30	oabi	utime			sys_utime32
+# 31 was sys_stty
+# 32 was sys_gtty
+33	common	access			sys_access
+34	common	nice			sys_nice
+# 35 was sys_ftime
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times
+# 44 was sys_prof
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid16
+47	common	getgid			sys_getgid16
+# 48 was sys_signal
+49	common	geteuid			sys_geteuid16
+50	common	getegid			sys_getegid16
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+# 53 was sys_lock
+54	common	ioctl			sys_ioctl
+55	common	fcntl			sys_fcntl
+# 56 was sys_mpx
+57	common	setpgid			sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	sigaction		sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70	common	setreuid		sys_setreuid16
+71	common	setregid		sys_setregid16
+72	common	sigsuspend		sys_sigsuspend
+73	common	sigpending		sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit
+# Back compat 2GB limited rlimit
+76	oabi	getrlimit		sys_old_getrlimit
+77	common	getrusage		sys_getrusage
+78	common	gettimeofday		sys_gettimeofday
+79	common	settimeofday		sys_settimeofday
+80	common	getgroups		sys_getgroups16
+81	common	setgroups		sys_setgroups16
+82	oabi	select			sys_old_select
+83	common	symlink			sys_symlink
+# 84 was sys_lstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_uselib
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+89	oabi	readdir			sys_old_readdir
+90	oabi	mmap			sys_old_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate
+93	common	ftruncate		sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown16
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+# 98 was sys_profil
+99	common	statfs			sys_statfs
+100	common	fstatfs			sys_fstatfs
+# 101 was sys_ioperm
+102	oabi	socketcall		sys_socketcall		sys_oabi_socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer
+105	common	getitimer		sys_getitimer
+106	common	stat			sys_newstat
+107	common	lstat			sys_newlstat
+108	common	fstat			sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111	common	vhangup			sys_vhangup
+# 112 was sys_idle
+# syscall to call a syscall!
+113	oabi	syscall			sys_syscall
+114	common	wait4			sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo
+117	oabi	ipc			sys_ipc			sys_oabi_ipc
+118	common	fsync			sys_fsync
+119	common	sigreturn		sys_sigreturn_wrapper
+120	common	clone			sys_clone
+121	common	setdomainname		sys_setdomainname
+122	common	uname			sys_newuname
+# 123 was sys_modify_ldt
+124	common	adjtimex		sys_adjtimex_time32
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask
+# 127 was sys_create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was sys_get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	common	personality		sys_personality
+# 137 was sys_afs_syscall
+138	common	setfsuid		sys_setfsuid16
+139	common	setfsgid		sys_setfsgid16
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents
+142	common	_newselect		sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	common	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+162	common	nanosleep		sys_nanosleep_time32
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid16
+165	common	getresuid		sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168	common	poll			sys_poll
+169	common	nfsservctl
+170	common	setresgid		sys_setresgid16
+171	common	getresgid		sys_getresgid16
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper
+174	common	rt_sigaction		sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending
+177	common	rt_sigtimedwait		sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend
+180	common	pread64			sys_pread64		sys_oabi_pread64
+181	common	pwrite64		sys_pwrite64		sys_oabi_pwrite64
+182	common	chown			sys_chown16
+183	common	getcwd			sys_getcwd
+184	common	capget			sys_capget
+185	common	capset			sys_capset
+186	common	sigaltstack		sys_sigaltstack
+187	common	sendfile		sys_sendfile
+# 188 reserved
+# 189 reserved
+190	common	vfork			sys_vfork
+# SuS compliant getrlimit
+191	common	ugetrlimit		sys_getrlimit
+192	common	mmap2			sys_mmap2
+193	common	truncate64		sys_truncate64		sys_oabi_truncate64
+194	common	ftruncate64		sys_ftruncate64		sys_oabi_ftruncate64
+195	common	stat64			sys_stat64		sys_oabi_stat64
+196	common	lstat64			sys_lstat64		sys_oabi_lstat64
+197	common	fstat64			sys_fstat64		sys_oabi_fstat64
+198	common	lchown32		sys_lchown
+199	common	getuid32		sys_getuid
+200	common	getgid32		sys_getgid
+201	common	geteuid32		sys_geteuid
+202	common	getegid32		sys_getegid
+203	common	setreuid32		sys_setreuid
+204	common	setregid32		sys_setregid
+205	common	getgroups32		sys_getgroups
+206	common	setgroups32		sys_setgroups
+207	common	fchown32		sys_fchown
+208	common	setresuid32		sys_setresuid
+209	common	getresuid32		sys_getresuid
+210	common	setresgid32		sys_setresgid
+211	common	getresgid32		sys_getresgid
+212	common	chown32			sys_chown
+213	common	setuid32		sys_setuid
+214	common	setgid32		sys_setgid
+215	common	setfsuid32		sys_setfsuid
+216	common	setfsgid32		sys_setfsgid
+217	common	getdents64		sys_getdents64
+218	common	pivot_root		sys_pivot_root
+219	common	mincore			sys_mincore
+220	common	madvise			sys_madvise
+221	common	fcntl64			sys_fcntl64		sys_oabi_fcntl64
+# 222 for tux
+# 223 is unused
+224	common	gettid			sys_gettid
+225	common	readahead		sys_readahead		sys_oabi_readahead
+226	common	setxattr		sys_setxattr
+227	common	lsetxattr		sys_lsetxattr
+228	common	fsetxattr		sys_fsetxattr
+229	common	getxattr		sys_getxattr
+230	common	lgetxattr		sys_lgetxattr
+231	common	fgetxattr		sys_fgetxattr
+232	common	listxattr		sys_listxattr
+233	common	llistxattr		sys_llistxattr
+234	common	flistxattr		sys_flistxattr
+235	common	removexattr		sys_removexattr
+236	common	lremovexattr		sys_lremovexattr
+237	common	fremovexattr		sys_fremovexattr
+238	common	tkill			sys_tkill
+239	common	sendfile64		sys_sendfile64
+240	common	futex			sys_futex_time32
+241	common	sched_setaffinity	sys_sched_setaffinity
+242	common	sched_getaffinity	sys_sched_getaffinity
+243	common	io_setup		sys_io_setup
+244	common	io_destroy		sys_io_destroy
+245	common	io_getevents		sys_io_getevents_time32
+246	common	io_submit		sys_io_submit
+247	common	io_cancel		sys_io_cancel
+248	common	exit_group		sys_exit_group
+249	common	lookup_dcookie		sys_ni_syscall
+250	common	epoll_create		sys_epoll_create
+251	common	epoll_ctl		sys_epoll_ctl		sys_oabi_epoll_ctl
+252	common	epoll_wait		sys_epoll_wait
+253	common	remap_file_pages	sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256	common	set_tid_address		sys_set_tid_address
+257	common	timer_create		sys_timer_create
+258	common	timer_settime		sys_timer_settime32
+259	common	timer_gettime		sys_timer_gettime32
+260	common	timer_getoverrun	sys_timer_getoverrun
+261	common	timer_delete		sys_timer_delete
+262	common	clock_settime		sys_clock_settime32
+263	common	clock_gettime		sys_clock_gettime32
+264	common	clock_getres		sys_clock_getres_time32
+265	common	clock_nanosleep		sys_clock_nanosleep_time32
+266	common	statfs64		sys_statfs64_wrapper
+267	common	fstatfs64		sys_fstatfs64_wrapper
+268	common	tgkill			sys_tgkill
+269	common	utimes			sys_utimes_time32
+270	common	arm_fadvise64_64	sys_arm_fadvise64_64
+271	common	pciconfig_iobase	sys_pciconfig_iobase
+272	common	pciconfig_read		sys_pciconfig_read
+273	common	pciconfig_write		sys_pciconfig_write
+274	common	mq_open			sys_mq_open
+275	common	mq_unlink		sys_mq_unlink
+276	common	mq_timedsend		sys_mq_timedsend_time32
+277	common	mq_timedreceive		sys_mq_timedreceive_time32
+278	common	mq_notify		sys_mq_notify
+279	common	mq_getsetattr		sys_mq_getsetattr
+280	common	waitid			sys_waitid
+281	common	socket			sys_socket
+282	common	bind			sys_bind		sys_oabi_bind
+283	common	connect			sys_connect		sys_oabi_connect
+284	common	listen			sys_listen
+285	common	accept			sys_accept
+286	common	getsockname		sys_getsockname
+287	common	getpeername		sys_getpeername
+288	common	socketpair		sys_socketpair
+289	common	send			sys_send
+290	common	sendto			sys_sendto		sys_oabi_sendto
+291	common	recv			sys_recv
+292	common	recvfrom		sys_recvfrom
+293	common	shutdown		sys_shutdown
+294	common	setsockopt		sys_setsockopt
+295	common	getsockopt		sys_getsockopt
+296	common	sendmsg			sys_sendmsg		sys_oabi_sendmsg
+297	common	recvmsg			sys_recvmsg
+298	common	semop			sys_semop		sys_oabi_semop
+299	common	semget			sys_semget
+300	common	semctl			sys_old_semctl
+301	common	msgsnd			sys_msgsnd
+302	common	msgrcv			sys_msgrcv
+303	common	msgget			sys_msgget
+304	common	msgctl			sys_old_msgctl
+305	common	shmat			sys_shmat
+306	common	shmdt			sys_shmdt
+307	common	shmget			sys_shmget
+308	common	shmctl			sys_old_shmctl
+309	common	add_key			sys_add_key
+310	common	request_key		sys_request_key
+311	common	keyctl			sys_keyctl
+312	common	semtimedop		sys_semtimedop_time32	sys_oabi_semtimedop
+313	common	vserver
+314	common	ioprio_set		sys_ioprio_set
+315	common	ioprio_get		sys_ioprio_get
+316	common	inotify_init		sys_inotify_init
+317	common	inotify_add_watch	sys_inotify_add_watch
+318	common	inotify_rm_watch	sys_inotify_rm_watch
+319	common	mbind			sys_mbind
+320	common	get_mempolicy		sys_get_mempolicy
+321	common	set_mempolicy		sys_set_mempolicy
+322	common	openat			sys_openat
+323	common	mkdirat			sys_mkdirat
+324	common	mknodat			sys_mknodat
+325	common	fchownat		sys_fchownat
+326	common	futimesat		sys_futimesat_time32
+327	common	fstatat64		sys_fstatat64		sys_oabi_fstatat64
+328	common	unlinkat		sys_unlinkat
+329	common	renameat		sys_renameat
+330	common	linkat			sys_linkat
+331	common	symlinkat		sys_symlinkat
+332	common	readlinkat		sys_readlinkat
+333	common	fchmodat		sys_fchmodat
+334	common	faccessat		sys_faccessat
+335	common	pselect6		sys_pselect6_time32
+336	common	ppoll			sys_ppoll_time32
+337	common	unshare			sys_unshare
+338	common	set_robust_list		sys_set_robust_list
+339	common	get_robust_list		sys_get_robust_list
+340	common	splice			sys_splice
+341	common	arm_sync_file_range	sys_sync_file_range2
+342	common	tee			sys_tee
+343	common	vmsplice		sys_vmsplice
+344	common	move_pages		sys_move_pages
+345	common	getcpu			sys_getcpu
+346	common	epoll_pwait		sys_epoll_pwait
+347	common	kexec_load		sys_kexec_load
+348	common	utimensat		sys_utimensat_time32
+349	common	signalfd		sys_signalfd
+350	common	timerfd_create		sys_timerfd_create
+351	common	eventfd			sys_eventfd
+352	common	fallocate		sys_fallocate
+353	common	timerfd_settime		sys_timerfd_settime32
+354	common	timerfd_gettime		sys_timerfd_gettime32
+355	common	signalfd4		sys_signalfd4
+356	common	eventfd2		sys_eventfd2
+357	common	epoll_create1		sys_epoll_create1
+358	common	dup3			sys_dup3
+359	common	pipe2			sys_pipe2
+360	common	inotify_init1		sys_inotify_init1
+361	common	preadv			sys_preadv
+362	common	pwritev			sys_pwritev
+363	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo
+364	common	perf_event_open		sys_perf_event_open
+365	common	recvmmsg		sys_recvmmsg_time32
+366	common	accept4			sys_accept4
+367	common	fanotify_init		sys_fanotify_init
+368	common	fanotify_mark		sys_fanotify_mark
+369	common	prlimit64		sys_prlimit64
+370	common	name_to_handle_at	sys_name_to_handle_at
+371	common	open_by_handle_at	sys_open_by_handle_at
+372	common	clock_adjtime		sys_clock_adjtime32
+373	common	syncfs			sys_syncfs
+374	common	sendmmsg		sys_sendmmsg
+375	common	setns			sys_setns
+376	common	process_vm_readv	sys_process_vm_readv
+377	common	process_vm_writev	sys_process_vm_writev
+378	common	kcmp			sys_kcmp
+379	common	finit_module		sys_finit_module
+380	common	sched_setattr		sys_sched_setattr
+381	common	sched_getattr		sys_sched_getattr
+382	common	renameat2		sys_renameat2
+383	common	seccomp			sys_seccomp
+384	common	getrandom		sys_getrandom
+385	common	memfd_create		sys_memfd_create
+386	common	bpf			sys_bpf
+387	common	execveat		sys_execveat
+388	common	userfaultfd		sys_userfaultfd
+389	common	membarrier		sys_membarrier
+390	common	mlock2			sys_mlock2
+391	common	copy_file_range		sys_copy_file_range
+392	common	preadv2			sys_preadv2
+393	common	pwritev2		sys_pwritev2
+394	common	pkey_mprotect		sys_pkey_mprotect
+395	common	pkey_alloc		sys_pkey_alloc
+396	common	pkey_free		sys_pkey_free
+397	common	statx			sys_statx
+398	common	rseq			sys_rseq
+399	common	io_pgetevents		sys_io_pgetevents_time32
+400	common	migrate_pages		sys_migrate_pages
+401	common	kexec_file_load		sys_kexec_file_load
+# 402 is unused
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/arm/include/syscall_table.h b/tools/perf/arch/arm/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/arm/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 692f48db810ccbef229e240db29261f0c60db632..542f3bee1501c751a831df460c4e585ab756c8fc 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -202,6 +202,7 @@ check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscall
 check_2 tools/perf/arch/powerpc/entry/syscalls/syscall.tbl arch/powerpc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
+check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:50 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:50 -0800
Subject: [PATCH v3 05/16] perf tools: sh: Support syscall headers
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-5-239f032481d5@rivosinc.com>

sh uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
 .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
 tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 472 +++++++++++++++++++++
 tools/perf/arch/sh/include/syscall_table.h         |   2 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 482 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index fa69b056bab31568baba78a9903312bd37b98067..9eb909edbc4a51937c6dc777ada23b82906d19ac 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm
+generic_syscall_table_archs := riscv arc csky arm sh
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/sh/entry/syscalls/Kbuild b/tools/perf/arch/sh/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..25080390e4ed49ae56f314ad712007e674a9168e
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 +=
+syscalltbl = $(srctree)/tools/perf/arch/sh/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sh/entry/syscalls/syscall.tbl b/tools/perf/arch/sh/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..c8cad33bf250ea110de37bd1407f5a43ec5e38f2
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/syscall.tbl
@@ -0,0 +1,472 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for sh
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	restart_syscall			sys_restart_syscall
+1	common	exit				sys_exit
+2	common	fork				sys_fork
+3	common	read				sys_read
+4	common	write				sys_write
+5	common	open				sys_open
+6	common	close				sys_close
+7	common	waitpid				sys_waitpid
+8	common	creat				sys_creat
+9	common	link				sys_link
+10	common	unlink				sys_unlink
+11	common	execve				sys_execve
+12	common	chdir				sys_chdir
+13	common	time				sys_time32
+14	common	mknod				sys_mknod
+15	common	chmod				sys_chmod
+16	common	lchown				sys_lchown16
+# 17 was break
+18	common	oldstat				sys_stat
+19	common	lseek				sys_lseek
+20	common	getpid				sys_getpid
+21	common	mount				sys_mount
+22	common	umount				sys_oldumount
+23	common	setuid				sys_setuid16
+24	common	getuid				sys_getuid16
+25	common	stime				sys_stime32
+26	common	ptrace				sys_ptrace
+27	common	alarm				sys_alarm
+28	common	oldfstat			sys_fstat
+29	common	pause				sys_pause
+30	common	utime				sys_utime32
+# 31 was stty
+# 32 was gtty
+33	common	access				sys_access
+34	common	nice				sys_nice
+# 35 was ftime
+36	common	sync				sys_sync
+37	common	kill				sys_kill
+38	common	rename				sys_rename
+39	common	mkdir				sys_mkdir
+40	common	rmdir				sys_rmdir
+41	common	dup				sys_dup
+42	common	pipe				sys_sh_pipe
+43	common	times				sys_times
+# 44 was prof
+45	common	brk				sys_brk
+46	common	setgid				sys_setgid16
+47	common	getgid				sys_getgid16
+48	common	signal				sys_signal
+49	common	geteuid				sys_geteuid16
+50	common	getegid				sys_getegid16
+51	common	acct				sys_acct
+52	common	umount2				sys_umount
+# 53 was lock
+54	common	ioctl				sys_ioctl
+55	common	fcntl				sys_fcntl
+# 56 was mpx
+57	common	setpgid				sys_setpgid
+# 58 was ulimit
+# 59 was olduname
+60	common	umask				sys_umask
+61	common	chroot				sys_chroot
+62	common	ustat				sys_ustat
+63	common	dup2				sys_dup2
+64	common	getppid				sys_getppid
+65	common	getpgrp				sys_getpgrp
+66	common	setsid				sys_setsid
+67	common	sigaction			sys_sigaction
+68	common	sgetmask			sys_sgetmask
+69	common	ssetmask			sys_ssetmask
+70	common	setreuid			sys_setreuid16
+71	common	setregid			sys_setregid16
+72	common	sigsuspend			sys_sigsuspend
+73	common	sigpending			sys_sigpending
+74	common	sethostname			sys_sethostname
+75	common	setrlimit			sys_setrlimit
+76	common	getrlimit			sys_old_getrlimit
+77	common	getrusage			sys_getrusage
+78	common	gettimeofday			sys_gettimeofday
+79	common	settimeofday			sys_settimeofday
+80	common	getgroups			sys_getgroups16
+81	common	setgroups			sys_setgroups16
+# 82 was select
+83	common	symlink				sys_symlink
+84	common	oldlstat			sys_lstat
+85	common	readlink			sys_readlink
+86	common	uselib				sys_uselib
+87	common	swapon				sys_swapon
+88	common	reboot				sys_reboot
+89	common	readdir				sys_old_readdir
+90	common	mmap				old_mmap
+91	common	munmap				sys_munmap
+92	common	truncate			sys_truncate
+93	common	ftruncate			sys_ftruncate
+94	common	fchmod				sys_fchmod
+95	common	fchown				sys_fchown16
+96	common	getpriority			sys_getpriority
+97	common	setpriority			sys_setpriority
+# 98 was profil
+99	common	statfs				sys_statfs
+100	common	fstatfs				sys_fstatfs
+# 101 was ioperm
+102	common	socketcall			sys_socketcall
+103	common	syslog				sys_syslog
+104	common	setitimer			sys_setitimer
+105	common	getitimer			sys_getitimer
+106	common	stat				sys_newstat
+107	common	lstat				sys_newlstat
+108	common	fstat				sys_newfstat
+109	common	olduname			sys_uname
+# 110 was iopl
+111	common	vhangup				sys_vhangup
+# 112 was idle
+# 113 was vm86old
+114	common	wait4				sys_wait4
+115	common	swapoff				sys_swapoff
+116	common	sysinfo				sys_sysinfo
+117	common	ipc				sys_ipc
+118	common	fsync				sys_fsync
+119	common	sigreturn			sys_sigreturn
+120	common	clone				sys_clone
+121	common	setdomainname			sys_setdomainname
+122	common	uname				sys_newuname
+123	common	cacheflush			sys_cacheflush
+124	common	adjtimex			sys_adjtimex_time32
+125	common	mprotect			sys_mprotect
+126	common	sigprocmask			sys_sigprocmask
+# 127 was create_module
+128	common	init_module			sys_init_module
+129	common	delete_module			sys_delete_module
+# 130 was get_kernel_syms
+131	common	quotactl			sys_quotactl
+132	common	getpgid				sys_getpgid
+133	common	fchdir				sys_fchdir
+134	common	bdflush				sys_ni_syscall
+135	common	sysfs				sys_sysfs
+136	common	personality			sys_personality
+# 137 was afs_syscall
+138	common	setfsuid			sys_setfsuid16
+139	common	setfsgid			sys_setfsgid16
+140	common	_llseek				sys_llseek
+141	common	getdents			sys_getdents
+142	common	_newselect			sys_select
+143	common	flock				sys_flock
+144	common	msync				sys_msync
+145	common	readv				sys_readv
+146	common	writev				sys_writev
+147	common	getsid				sys_getsid
+148	common	fdatasync			sys_fdatasync
+149	common	_sysctl				sys_ni_syscall
+150	common	mlock				sys_mlock
+151	common	munlock				sys_munlock
+152	common	mlockall			sys_mlockall
+153	common	munlockall			sys_munlockall
+154	common	sched_setparam			sys_sched_setparam
+155	common	sched_getparam			sys_sched_getparam
+156	common	sched_setscheduler		sys_sched_setscheduler
+157	common	sched_getscheduler		sys_sched_getscheduler
+158	common	sched_yield			sys_sched_yield
+159	common	sched_get_priority_max		sys_sched_get_priority_max
+160	common	sched_get_priority_min		sys_sched_get_priority_min
+161	common	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+162	common	nanosleep			sys_nanosleep_time32
+163	common	mremap				sys_mremap
+164	common	setresuid			sys_setresuid16
+165	common	getresuid			sys_getresuid16
+# 166 was vm86
+# 167 was query_module
+168	common	poll				sys_poll
+169	common	nfsservctl			sys_ni_syscall
+170	common	setresgid			sys_setresgid16
+171	common	getresgid			sys_getresgid16
+172	common	prctl				sys_prctl
+173	common	rt_sigreturn			sys_rt_sigreturn
+174	common	rt_sigaction			sys_rt_sigaction
+175	common	rt_sigprocmask			sys_rt_sigprocmask
+176	common	rt_sigpending			sys_rt_sigpending
+177	common	rt_sigtimedwait			sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+179	common	rt_sigsuspend			sys_rt_sigsuspend
+180	common	pread64				sys_pread_wrapper
+181	common	pwrite64			sys_pwrite_wrapper
+182	common	chown				sys_chown16
+183	common	getcwd				sys_getcwd
+184	common	capget				sys_capget
+185	common	capset				sys_capset
+186	common	sigaltstack			sys_sigaltstack
+187	common	sendfile			sys_sendfile
+# 188 is reserved for getpmsg
+# 189 is reserved for putpmsg
+190	common	vfork				sys_vfork
+191	common	ugetrlimit			sys_getrlimit
+192	common	mmap2				sys_mmap2
+193	common	truncate64			sys_truncate64
+194	common	ftruncate64			sys_ftruncate64
+195	common	stat64				sys_stat64
+196	common	lstat64				sys_lstat64
+197	common	fstat64				sys_fstat64
+198	common	lchown32			sys_lchown
+199	common	getuid32			sys_getuid
+200	common	getgid32			sys_getgid
+201	common	geteuid32			sys_geteuid
+202	common	getegid32			sys_getegid
+203	common	setreuid32			sys_setreuid
+204	common	setregid32			sys_setregid
+205	common	getgroups32			sys_getgroups
+206	common	setgroups32			sys_setgroups
+207	common	fchown32			sys_fchown
+208	common	setresuid32			sys_setresuid
+209	common	getresuid32			sys_getresuid
+210	common	setresgid32			sys_setresgid
+211	common	getresgid32			sys_getresgid
+212	common	chown32				sys_chown
+213	common	setuid32			sys_setuid
+214	common	setgid32			sys_setgid
+215	common	setfsuid32			sys_setfsuid
+216	common	setfsgid32			sys_setfsgid
+217	common	pivot_root			sys_pivot_root
+218	common	mincore				sys_mincore
+219	common	madvise				sys_madvise
+220	common	getdents64			sys_getdents64
+221	common	fcntl64				sys_fcntl64
+# 222 is reserved for tux
+# 223 is unused
+224	common	gettid				sys_gettid
+225	common	readahead			sys_readahead
+226	common	setxattr			sys_setxattr
+227	common	lsetxattr			sys_lsetxattr
+228	common	fsetxattr			sys_fsetxattr
+229	common	getxattr			sys_getxattr
+230	common	lgetxattr			sys_lgetxattr
+231	common	fgetxattr			sys_fgetxattr
+232	common	listxattr			sys_listxattr
+233	common	llistxattr			sys_llistxattr
+234	common	flistxattr			sys_flistxattr
+235	common	removexattr			sys_removexattr
+236	common	lremovexattr			sys_lremovexattr
+237	common	fremovexattr			sys_fremovexattr
+238	common	tkill				sys_tkill
+239	common	sendfile64			sys_sendfile64
+240	common	futex				sys_futex_time32
+241	common	sched_setaffinity		sys_sched_setaffinity
+242	common	sched_getaffinity		sys_sched_getaffinity
+# 243 is reserved for set_thread_area
+# 244 is reserved for get_thread_area
+245	common	io_setup			sys_io_setup
+246	common	io_destroy			sys_io_destroy
+247	common	io_getevents			sys_io_getevents_time32
+248	common	io_submit			sys_io_submit
+249	common	io_cancel			sys_io_cancel
+250	common	fadvise64			sys_fadvise64
+# 251 is unused
+252	common	exit_group			sys_exit_group
+253	common	lookup_dcookie			sys_ni_syscall
+254	common	epoll_create			sys_epoll_create
+255	common	epoll_ctl			sys_epoll_ctl
+256	common	epoll_wait			sys_epoll_wait
+257	common	remap_file_pages		sys_remap_file_pages
+258	common	set_tid_address			sys_set_tid_address
+259	common	timer_create			sys_timer_create
+260	common	timer_settime			sys_timer_settime32
+261	common	timer_gettime			sys_timer_gettime32
+262	common	timer_getoverrun		sys_timer_getoverrun
+263	common	timer_delete			sys_timer_delete
+264	common	clock_settime			sys_clock_settime32
+265	common	clock_gettime			sys_clock_gettime32
+266	common	clock_getres			sys_clock_getres_time32
+267	common	clock_nanosleep			sys_clock_nanosleep_time32
+268	common	statfs64			sys_statfs64
+269	common	fstatfs64			sys_fstatfs64
+270	common	tgkill				sys_tgkill
+271	common	utimes				sys_utimes_time32
+272	common	fadvise64_64			sys_fadvise64_64_wrapper
+# 273 is reserved for vserver
+274	common	mbind				sys_mbind
+275	common	get_mempolicy			sys_get_mempolicy
+276	common	set_mempolicy			sys_set_mempolicy
+277	common	mq_open				sys_mq_open
+278	common	mq_unlink			sys_mq_unlink
+279	common	mq_timedsend			sys_mq_timedsend_time32
+280	common	mq_timedreceive			sys_mq_timedreceive_time32
+281	common	mq_notify			sys_mq_notify
+282	common	mq_getsetattr			sys_mq_getsetattr
+283	common	kexec_load			sys_kexec_load
+284	common	waitid				sys_waitid
+285	common	add_key				sys_add_key
+286	common	request_key			sys_request_key
+287	common	keyctl				sys_keyctl
+288	common	ioprio_set			sys_ioprio_set
+289	common	ioprio_get			sys_ioprio_get
+290	common	inotify_init			sys_inotify_init
+291	common	inotify_add_watch		sys_inotify_add_watch
+292	common	inotify_rm_watch		sys_inotify_rm_watch
+# 293 is unused
+294	common	migrate_pages			sys_migrate_pages
+295	common	openat				sys_openat
+296	common	mkdirat				sys_mkdirat
+297	common	mknodat				sys_mknodat
+298	common	fchownat			sys_fchownat
+299	common	futimesat			sys_futimesat_time32
+300	common	fstatat64			sys_fstatat64
+301	common	unlinkat			sys_unlinkat
+302	common	renameat			sys_renameat
+303	common	linkat				sys_linkat
+304	common	symlinkat			sys_symlinkat
+305	common	readlinkat			sys_readlinkat
+306	common	fchmodat			sys_fchmodat
+307	common	faccessat			sys_faccessat
+308	common	pselect6			sys_pselect6_time32
+309	common	ppoll				sys_ppoll_time32
+310	common	unshare				sys_unshare
+311	common	set_robust_list			sys_set_robust_list
+312	common	get_robust_list			sys_get_robust_list
+313	common	splice				sys_splice
+314	common	sync_file_range			sys_sh_sync_file_range6
+315	common	tee				sys_tee
+316	common	vmsplice			sys_vmsplice
+317	common	move_pages			sys_move_pages
+318	common	getcpu				sys_getcpu
+319	common	epoll_pwait			sys_epoll_pwait
+320	common	utimensat			sys_utimensat_time32
+321	common	signalfd			sys_signalfd
+322	common	timerfd_create			sys_timerfd_create
+323	common	eventfd				sys_eventfd
+324	common	fallocate			sys_fallocate
+325	common	timerfd_settime			sys_timerfd_settime32
+326	common	timerfd_gettime			sys_timerfd_gettime32
+327	common	signalfd4			sys_signalfd4
+328	common	eventfd2			sys_eventfd2
+329	common	epoll_create1			sys_epoll_create1
+330	common	dup3				sys_dup3
+331	common	pipe2				sys_pipe2
+332	common	inotify_init1			sys_inotify_init1
+333	common	preadv				sys_preadv
+334	common	pwritev				sys_pwritev
+335	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+336	common	perf_event_open			sys_perf_event_open
+337	common	fanotify_init			sys_fanotify_init
+338	common	fanotify_mark			sys_fanotify_mark
+339	common	prlimit64			sys_prlimit64
+340	common	socket				sys_socket
+341	common	bind				sys_bind
+342	common	connect				sys_connect
+343	common	listen				sys_listen
+344	common	accept				sys_accept
+345	common	getsockname			sys_getsockname
+346	common	getpeername			sys_getpeername
+347	common	socketpair			sys_socketpair
+348	common	send				sys_send
+349	common	sendto				sys_sendto
+350	common	recv				sys_recv
+351	common	recvfrom			sys_recvfrom
+352	common	shutdown			sys_shutdown
+353	common	setsockopt			sys_setsockopt
+354	common	getsockopt			sys_getsockopt
+355	common	sendmsg				sys_sendmsg
+356	common	recvmsg				sys_recvmsg
+357	common	recvmmsg			sys_recvmmsg_time32
+358	common	accept4				sys_accept4
+359	common	name_to_handle_at		sys_name_to_handle_at
+360	common	open_by_handle_at		sys_open_by_handle_at
+361	common	clock_adjtime			sys_clock_adjtime32
+362	common	syncfs				sys_syncfs
+363	common	sendmmsg			sys_sendmmsg
+364	common	setns				sys_setns
+365	common	process_vm_readv		sys_process_vm_readv
+366	common	process_vm_writev		sys_process_vm_writev
+367	common	kcmp				sys_kcmp
+368	common	finit_module			sys_finit_module
+369	common	sched_getattr			sys_sched_getattr
+370	common	sched_setattr			sys_sched_setattr
+371	common	renameat2			sys_renameat2
+372	common	seccomp				sys_seccomp
+373	common	getrandom			sys_getrandom
+374	common	memfd_create			sys_memfd_create
+375	common	bpf				sys_bpf
+376	common	execveat			sys_execveat
+377	common	userfaultfd			sys_userfaultfd
+378	common	membarrier			sys_membarrier
+379	common	mlock2				sys_mlock2
+380	common	copy_file_range			sys_copy_file_range
+381	common	preadv2				sys_preadv2
+382	common	pwritev2			sys_pwritev2
+383	common	statx				sys_statx
+384	common	pkey_mprotect			sys_pkey_mprotect
+385	common	pkey_alloc			sys_pkey_alloc
+386	common	pkey_free			sys_pkey_free
+387	common	rseq				sys_rseq
+388	common	sync_file_range2		sys_sync_file_range2
+# room for arch specific syscalls
+393	common	semget				sys_semget
+394	common	semctl				sys_semctl
+395	common	shmget				sys_shmget
+396	common	shmctl				sys_shmctl
+397	common	shmat				sys_shmat
+398	common	shmdt				sys_shmdt
+399	common	msgget				sys_msgget
+400	common	msgsnd				sys_msgsnd
+401	common	msgrcv				sys_msgrcv
+402	common	msgctl				sys_msgctl
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+# 435 reserved for clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/sh/include/syscall_table.h b/tools/perf/arch/sh/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/sh/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 542f3bee1501c751a831df460c4e585ab756c8fc..2f1b42bf337b3d601f0f2e792bd79413f46e583a 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -203,6 +203,7 @@ check_2 tools/perf/arch/powerpc/entry/syscalls/syscall.tbl arch/powerpc/kernel/s
 check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
+check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:51 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:51 -0800
Subject: [PATCH v3 06/16] perf tools: sparc: Support syscall headers
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-6-239f032481d5@rivosinc.com>

sparc uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
 .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 514 +++++++++++++++++++++
 tools/perf/arch/sparc/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 532 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 9eb909edbc4a51937c6dc777ada23b82906d19ac..2772c05c661bb1a8084255d19a1a75941a8ac8b8 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh
+generic_syscall_table_archs := riscv arc csky arm sh sparc
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/sparc/entry/syscalls/Kbuild b/tools/perf/arch/sparc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..212c1800b64477c615b8963176d873db5ccabe0c
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscall_abis_64  +=
+syscalltbl = $(srctree)/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sparc/entry/syscalls/syscall.tbl b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..727f99d333b304b3db0711953a3d91ece18a28eb
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
@@ -0,0 +1,514 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for sparc
+#
+# The format is:
+# <number> <abi> <name> <entry point> <compat entry point>
+#
+# The <abi> can be common, 64, or 32 for this file.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	32	exit			sys_exit			sparc_exit
+1	64	exit			sparc_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open			compat_sys_open
+6	common	close			sys_close
+7	common	wait4			sys_wait4			compat_sys_wait4
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	32	execv			sunos_execv
+11	64	execv			sys_nis_syscall
+12	common	chdir			sys_chdir
+13	32    	chown			sys_chown16
+13	64	chown			sys_chown
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	32	lchown			sys_lchown16
+16	64	lchown			sys_lchown
+17	common	brk			sys_brk
+18	common	perfctr			sys_nis_syscall
+19	common	lseek			sys_lseek			compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	capget			sys_capget
+22	common	capset			sys_capset
+23	32    	setuid			sys_setuid16
+23	64    	setuid			sys_setuid
+24	32	getuid			sys_getuid16
+24	64   	getuid			sys_getuid
+25	common	vmsplice		sys_vmsplice
+26	common	ptrace			sys_ptrace			compat_sys_ptrace
+27	common	alarm			sys_alarm
+28	common	sigaltstack		sys_sigaltstack			compat_sys_sigaltstack
+29	32    	pause			sys_pause
+29	64    	pause			sys_nis_syscall
+30	32	utime			sys_utime32
+30	64	utime			sys_utime
+31	32    	lchown32		sys_lchown
+32	32    	fchown32		sys_fchown
+33	common	access			sys_access
+34	common	nice			sys_nice
+35	32    	chown32			sys_chown
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	stat			sys_newstat			compat_sys_newstat
+39	32	sendfile		sys_sendfile			compat_sys_sendfile
+39	64	sendfile		sys_sendfile64
+40	common	lstat			sys_newlstat			compat_sys_newlstat
+41	common	dup			sys_dup
+42	common	pipe			sys_sparc_pipe
+43	common	times			sys_times			compat_sys_times
+44	32    	getuid32		sys_getuid
+45	common	umount2			sys_umount
+46	32	setgid			sys_setgid16
+46	64	setgid			sys_setgid
+47	32	getgid			sys_getgid16
+47	64	getgid			sys_getgid
+48	common	signal			sys_signal
+49	32	geteuid			sys_geteuid16
+49	64	geteuid			sys_geteuid
+50	32	getegid			sys_getegid16
+50	64	getegid			sys_getegid
+51	common	acct			sys_acct
+52	64	memory_ordering		sys_memory_ordering
+53	32	getgid32		sys_getgid
+54	common	ioctl			sys_ioctl			compat_sys_ioctl
+55	common	reboot			sys_reboot
+56	32    	mmap2			sys_mmap2			sys32_mmap2
+57	common	symlink			sys_symlink
+58	common	readlink		sys_readlink
+59	32	execve			sys_execve			sys32_execve
+59	64	execve			sys64_execve
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	fstat			sys_newfstat			compat_sys_newfstat
+63	common	fstat64			sys_fstat64			compat_sys_fstat64
+64	common	getpagesize		sys_getpagesize
+65	common	msync			sys_msync
+66	common	vfork			sys_vfork
+67	common	pread64			sys_pread64			compat_sys_pread64
+68	common	pwrite64		sys_pwrite64			compat_sys_pwrite64
+69	32    	geteuid32		sys_geteuid
+70	32	getegid32		sys_getegid
+71	common	mmap			sys_mmap
+72	32	setreuid32		sys_setreuid
+73	32	munmap			sys_munmap
+73	64	munmap			sys_64_munmap
+74	common	mprotect		sys_mprotect
+75	common	madvise			sys_madvise
+76	common	vhangup			sys_vhangup
+77	32	truncate64		sys_truncate64			compat_sys_truncate64
+78	common	mincore			sys_mincore
+79	32	getgroups		sys_getgroups16
+79	64	getgroups		sys_getgroups
+80	32	setgroups		sys_setgroups16
+80	64	setgroups		sys_setgroups
+81	common	getpgrp			sys_getpgrp
+82	32	setgroups32		sys_setgroups
+83	common	setitimer		sys_setitimer			compat_sys_setitimer
+84	32	ftruncate64		sys_ftruncate64			compat_sys_ftruncate64
+85	common	swapon			sys_swapon
+86	common	getitimer		sys_getitimer			compat_sys_getitimer
+87	32	setuid32		sys_setuid
+88	common	sethostname		sys_sethostname
+89	32	setgid32		sys_setgid
+90	common	dup2			sys_dup2
+91	32	setfsuid32		sys_setfsuid
+92	common	fcntl			sys_fcntl			compat_sys_fcntl
+93	common	select			sys_select			compat_sys_select
+94	32	setfsgid32		sys_setfsgid
+95	common	fsync			sys_fsync
+96	common	setpriority		sys_setpriority
+97	common	socket			sys_socket
+98	common	connect			sys_connect
+99	common	accept			sys_accept
+100	common	getpriority		sys_getpriority
+101	common	rt_sigreturn		sys_rt_sigreturn		sys32_rt_sigreturn
+102	common	rt_sigaction		sys_rt_sigaction		compat_sys_rt_sigaction
+103	common	rt_sigprocmask		sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+104	common	rt_sigpending		sys_rt_sigpending		compat_sys_rt_sigpending
+105	32	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+105	64	rt_sigtimedwait		sys_rt_sigtimedwait
+106	common	rt_sigqueueinfo		sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+107	common	rt_sigsuspend		sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+108	32	setresuid32		sys_setresuid
+108	64	setresuid		sys_setresuid
+109	32	getresuid32		sys_getresuid
+109	64	getresuid		sys_getresuid
+110	32	setresgid32		sys_setresgid
+110	64	setresgid		sys_setresgid
+111	32	getresgid32		sys_getresgid
+111	64	getresgid		sys_getresgid
+112	32	setregid32		sys_setregid
+113	common	recvmsg			sys_recvmsg			compat_sys_recvmsg
+114	common	sendmsg			sys_sendmsg			compat_sys_sendmsg
+115	32	getgroups32		sys_getgroups
+116	common	gettimeofday		sys_gettimeofday		compat_sys_gettimeofday
+117	common	getrusage		sys_getrusage			compat_sys_getrusage
+118	common	getsockopt		sys_getsockopt			sys_getsockopt
+119	common	getcwd			sys_getcwd
+120	common	readv			sys_readv
+121	common	writev			sys_writev
+122	common	settimeofday		sys_settimeofday		compat_sys_settimeofday
+123	32	fchown			sys_fchown16
+123	64	fchown			sys_fchown
+124	common	fchmod			sys_fchmod
+125	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
+126	32	setreuid		sys_setreuid16
+126	64	setreuid		sys_setreuid
+127	32	setregid		sys_setregid16
+127	64	setregid		sys_setregid
+128	common	rename			sys_rename
+129	common	truncate		sys_truncate			compat_sys_truncate
+130	common	ftruncate		sys_ftruncate			compat_sys_ftruncate
+131	common	flock			sys_flock
+132	common	lstat64			sys_lstat64			compat_sys_lstat64
+133	common	sendto			sys_sendto
+134	common	shutdown		sys_shutdown
+135	common	socketpair		sys_socketpair
+136	common	mkdir			sys_mkdir
+137	common	rmdir			sys_rmdir
+138	32	utimes			sys_utimes_time32
+138	64	utimes			sys_utimes
+139	common	stat64			sys_stat64			compat_sys_stat64
+140	common	sendfile64		sys_sendfile64
+141	common	getpeername		sys_getpeername
+142	32	futex			sys_futex_time32
+142	64	futex			sys_futex
+143	common	gettid			sys_gettid
+144	common	getrlimit		sys_getrlimit			compat_sys_getrlimit
+145	common	setrlimit		sys_setrlimit			compat_sys_setrlimit
+146	common	pivot_root		sys_pivot_root
+147	common	prctl			sys_prctl
+148	common	pciconfig_read		sys_pciconfig_read
+149	common	pciconfig_write		sys_pciconfig_write
+150	common	getsockname		sys_getsockname
+151	common	inotify_init		sys_inotify_init
+152	common	inotify_add_watch	sys_inotify_add_watch
+153	common	poll			sys_poll
+154	common	getdents64		sys_getdents64
+155	32	fcntl64			sys_fcntl64			compat_sys_fcntl64
+156	common	inotify_rm_watch	sys_inotify_rm_watch
+157	common	statfs			sys_statfs			compat_sys_statfs
+158	common	fstatfs			sys_fstatfs			compat_sys_fstatfs
+159	common	umount			sys_oldumount
+160	common	sched_set_affinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+161	common	sched_get_affinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+162	common	getdomainname		sys_getdomainname
+163	common	setdomainname		sys_setdomainname
+164	64	utrap_install		sys_utrap_install
+165	common	quotactl		sys_quotactl
+166	common	set_tid_address		sys_set_tid_address
+167	common	mount			sys_mount
+168	common	ustat			sys_ustat			compat_sys_ustat
+169	common	setxattr		sys_setxattr
+170	common	lsetxattr		sys_lsetxattr
+171	common	fsetxattr		sys_fsetxattr
+172	common	getxattr		sys_getxattr
+173	common	lgetxattr		sys_lgetxattr
+174	common	getdents		sys_getdents			compat_sys_getdents
+175	common	setsid			sys_setsid
+176	common	fchdir			sys_fchdir
+177	common	fgetxattr		sys_fgetxattr
+178	common	listxattr		sys_listxattr
+179	common	llistxattr		sys_llistxattr
+180	common	flistxattr		sys_flistxattr
+181	common	removexattr		sys_removexattr
+182	common	lremovexattr		sys_lremovexattr
+183	32	sigpending		sys_sigpending			compat_sys_sigpending
+183	64	sigpending		sys_nis_syscall
+184	common	query_module		sys_ni_syscall
+185	common	setpgid			sys_setpgid
+186	common	fremovexattr		sys_fremovexattr
+187	common	tkill			sys_tkill
+188	32	exit_group		sys_exit_group			sparc_exit_group
+188	64	exit_group		sparc_exit_group
+189	common	uname			sys_newuname
+190	common	init_module		sys_init_module
+191	32	personality		sys_personality			sys_sparc64_personality
+191	64	personality		sys_sparc64_personality
+192	32	remap_file_pages	sys_sparc_remap_file_pages	sys_remap_file_pages
+192	64	remap_file_pages	sys_remap_file_pages
+193	common	epoll_create		sys_epoll_create
+194	common	epoll_ctl		sys_epoll_ctl
+195	common	epoll_wait		sys_epoll_wait
+196	common	ioprio_set		sys_ioprio_set
+197	common	getppid			sys_getppid
+198	32	sigaction		sys_sparc_sigaction		compat_sys_sparc_sigaction
+198	64	sigaction		sys_nis_syscall
+199	common	sgetmask		sys_sgetmask
+200	common	ssetmask		sys_ssetmask
+201	32	sigsuspend		sys_sigsuspend
+201	64	sigsuspend		sys_nis_syscall
+202	common	oldlstat		sys_newlstat			compat_sys_newlstat
+203	common	uselib			sys_uselib
+204	32	readdir			sys_old_readdir			compat_sys_old_readdir
+204	64	readdir			sys_nis_syscall
+205	common	readahead		sys_readahead			compat_sys_readahead
+206	common	socketcall		sys_socketcall			compat_sys_socketcall
+207	common	syslog			sys_syslog
+208	common	lookup_dcookie		sys_ni_syscall
+209	common	fadvise64		sys_fadvise64			compat_sys_fadvise64
+210	common	fadvise64_64		sys_fadvise64_64		compat_sys_fadvise64_64
+211	common	tgkill			sys_tgkill
+212	common	waitpid			sys_waitpid
+213	common	swapoff			sys_swapoff
+214	common	sysinfo			sys_sysinfo			compat_sys_sysinfo
+215	32	ipc			sys_ipc				compat_sys_ipc
+215	64	ipc			sys_sparc_ipc
+216	32	sigreturn		sys_sigreturn			sys32_sigreturn
+216	64	sigreturn		sys_nis_syscall
+217	common	clone			sys_clone
+218	common	ioprio_get		sys_ioprio_get
+219	32	adjtimex		sys_adjtimex_time32
+219	64	adjtimex		sys_sparc_adjtimex
+220	32	sigprocmask		sys_sigprocmask			compat_sys_sigprocmask
+220	64	sigprocmask		sys_nis_syscall
+221	common	create_module		sys_ni_syscall
+222	common	delete_module		sys_delete_module
+223	common	get_kernel_syms		sys_ni_syscall
+224	common	getpgid			sys_getpgid
+225	common	bdflush			sys_ni_syscall
+226	common	sysfs			sys_sysfs
+227	common	afs_syscall		sys_nis_syscall
+228	common	setfsuid		sys_setfsuid16
+229	common	setfsgid		sys_setfsgid16
+230	common	_newselect		sys_select			compat_sys_select
+231	32	time			sys_time32
+232	common	splice			sys_splice
+233	32	stime			sys_stime32
+233	64	stime			sys_stime
+234	common	statfs64		sys_statfs64			compat_sys_statfs64
+235	common	fstatfs64		sys_fstatfs64			compat_sys_fstatfs64
+236	common	_llseek			sys_llseek
+237	common	mlock			sys_mlock
+238	common	munlock			sys_munlock
+239	common	mlockall		sys_mlockall
+240	common	munlockall		sys_munlockall
+241	common	sched_setparam		sys_sched_setparam
+242	common	sched_getparam		sys_sched_getparam
+243	common	sched_setscheduler	sys_sched_setscheduler
+244	common	sched_getscheduler	sys_sched_getscheduler
+245	common	sched_yield		sys_sched_yield
+246	common	sched_get_priority_max	sys_sched_get_priority_max
+247	common	sched_get_priority_min	sys_sched_get_priority_min
+248	32	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+248	64	sched_rr_get_interval	sys_sched_rr_get_interval
+249	32	nanosleep		sys_nanosleep_time32
+249	64	nanosleep		sys_nanosleep
+250	32	mremap			sys_mremap
+250	64	mremap			sys_64_mremap
+251	common	_sysctl			sys_ni_syscall
+252	common	getsid			sys_getsid
+253	common	fdatasync		sys_fdatasync
+254	32	nfsservctl		sys_ni_syscall			sys_nis_syscall
+254	64	nfsservctl		sys_nis_syscall
+255	common	sync_file_range		sys_sync_file_range		compat_sys_sync_file_range
+256	32	clock_settime		sys_clock_settime32
+256	64	clock_settime		sys_clock_settime
+257	32	clock_gettime		sys_clock_gettime32
+257	64	clock_gettime		sys_clock_gettime
+258	32	clock_getres		sys_clock_getres_time32
+258	64	clock_getres		sys_clock_getres
+259	32	clock_nanosleep		sys_clock_nanosleep_time32
+259	64	clock_nanosleep		sys_clock_nanosleep
+260	common	sched_getaffinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+261	common	sched_setaffinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+262	32	timer_settime		sys_timer_settime32
+262	64	timer_settime		sys_timer_settime
+263	32	timer_gettime		sys_timer_gettime32
+263	64	timer_gettime		sys_timer_gettime
+264	common	timer_getoverrun	sys_timer_getoverrun
+265	common	timer_delete		sys_timer_delete
+266	common	timer_create		sys_timer_create		compat_sys_timer_create
+# 267 was vserver
+267	common	vserver			sys_nis_syscall
+268	common	io_setup		sys_io_setup			compat_sys_io_setup
+269	common	io_destroy		sys_io_destroy
+270	common	io_submit		sys_io_submit			compat_sys_io_submit
+271	common	io_cancel		sys_io_cancel
+272	32	io_getevents		sys_io_getevents_time32
+272	64	io_getevents		sys_io_getevents
+273	common	mq_open			sys_mq_open			compat_sys_mq_open
+274	common	mq_unlink		sys_mq_unlink
+275	32	mq_timedsend		sys_mq_timedsend_time32
+275	64	mq_timedsend		sys_mq_timedsend
+276	32	mq_timedreceive		sys_mq_timedreceive_time32
+276	64	mq_timedreceive		sys_mq_timedreceive
+277	common	mq_notify		sys_mq_notify			compat_sys_mq_notify
+278	common	mq_getsetattr		sys_mq_getsetattr		compat_sys_mq_getsetattr
+279	common	waitid			sys_waitid			compat_sys_waitid
+280	common	tee			sys_tee
+281	common	add_key			sys_add_key
+282	common	request_key		sys_request_key
+283	common	keyctl			sys_keyctl			compat_sys_keyctl
+284	common	openat			sys_openat			compat_sys_openat
+285	common	mkdirat			sys_mkdirat
+286	common	mknodat			sys_mknodat
+287	common	fchownat		sys_fchownat
+288	32	futimesat		sys_futimesat_time32
+288	64	futimesat		sys_futimesat
+289	common	fstatat64		sys_fstatat64			compat_sys_fstatat64
+290	common	unlinkat		sys_unlinkat
+291	common	renameat		sys_renameat
+292	common	linkat			sys_linkat
+293	common	symlinkat		sys_symlinkat
+294	common	readlinkat		sys_readlinkat
+295	common	fchmodat		sys_fchmodat
+296	common	faccessat		sys_faccessat
+297	32	pselect6		sys_pselect6_time32		compat_sys_pselect6_time32
+297	64	pselect6		sys_pselect6
+298	32	ppoll			sys_ppoll_time32		compat_sys_ppoll_time32
+298	64	ppoll			sys_ppoll
+299	common	unshare			sys_unshare
+300	common	set_robust_list		sys_set_robust_list		compat_sys_set_robust_list
+301	common	get_robust_list		sys_get_robust_list		compat_sys_get_robust_list
+302	common	migrate_pages		sys_migrate_pages
+303	common	mbind			sys_mbind
+304	common	get_mempolicy		sys_get_mempolicy
+305	common	set_mempolicy		sys_set_mempolicy
+306	common	kexec_load		sys_kexec_load			compat_sys_kexec_load
+307	common	move_pages		sys_move_pages
+308	common	getcpu			sys_getcpu
+309	common	epoll_pwait		sys_epoll_pwait			compat_sys_epoll_pwait
+310	32	utimensat		sys_utimensat_time32
+310	64	utimensat		sys_utimensat
+311	common	signalfd		sys_signalfd			compat_sys_signalfd
+312	common	timerfd_create		sys_timerfd_create
+313	common	eventfd			sys_eventfd
+314	common	fallocate		sys_fallocate			compat_sys_fallocate
+315	32	timerfd_settime		sys_timerfd_settime32
+315	64	timerfd_settime		sys_timerfd_settime
+316	32	timerfd_gettime		sys_timerfd_gettime32
+316	64	timerfd_gettime		sys_timerfd_gettime
+317	common	signalfd4		sys_signalfd4			compat_sys_signalfd4
+318	common	eventfd2		sys_eventfd2
+319	common	epoll_create1		sys_epoll_create1
+320	common	dup3			sys_dup3
+321	common	pipe2			sys_pipe2
+322	common	inotify_init1		sys_inotify_init1
+323	common	accept4			sys_accept4
+324	common	preadv			sys_preadv			compat_sys_preadv
+325	common	pwritev			sys_pwritev			compat_sys_pwritev
+326	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+327	common	perf_event_open		sys_perf_event_open
+328	32	recvmmsg		sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+328	64	recvmmsg		sys_recvmmsg
+329	common	fanotify_init		sys_fanotify_init
+330	common	fanotify_mark		sys_fanotify_mark		compat_sys_fanotify_mark
+331	common	prlimit64		sys_prlimit64
+332	common	name_to_handle_at	sys_name_to_handle_at
+333	common	open_by_handle_at	sys_open_by_handle_at		compat_sys_open_by_handle_at
+334	32	clock_adjtime		sys_clock_adjtime32
+334	64	clock_adjtime		sys_sparc_clock_adjtime
+335	common	syncfs			sys_syncfs
+336	common	sendmmsg		sys_sendmmsg			compat_sys_sendmmsg
+337	common	setns			sys_setns
+338	common	process_vm_readv	sys_process_vm_readv
+339	common	process_vm_writev	sys_process_vm_writev
+340	32	kern_features		sys_ni_syscall			sys_kern_features
+340	64	kern_features		sys_kern_features
+341	common	kcmp			sys_kcmp
+342	common	finit_module		sys_finit_module
+343	common	sched_setattr		sys_sched_setattr
+344	common	sched_getattr		sys_sched_getattr
+345	common	renameat2		sys_renameat2
+346	common	seccomp			sys_seccomp
+347	common	getrandom		sys_getrandom
+348	common	memfd_create		sys_memfd_create
+349	common	bpf			sys_bpf
+350	32	execveat		sys_execveat			sys32_execveat
+350	64	execveat		sys64_execveat
+351	common	membarrier		sys_membarrier
+352	common	userfaultfd		sys_userfaultfd
+353	common	bind			sys_bind
+354	common	listen			sys_listen
+355	common	setsockopt		sys_setsockopt			sys_setsockopt
+356	common	mlock2			sys_mlock2
+357	common	copy_file_range		sys_copy_file_range
+358	common	preadv2			sys_preadv2			compat_sys_preadv2
+359	common	pwritev2		sys_pwritev2			compat_sys_pwritev2
+360	common	statx			sys_statx
+361	32	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+361	64	io_pgetevents		sys_io_pgetevents
+362	common	pkey_mprotect		sys_pkey_mprotect
+363	common	pkey_alloc		sys_pkey_alloc
+364	common	pkey_free		sys_pkey_free
+365	common	rseq			sys_rseq
+# room for arch specific syscalls
+392	64	semtimedop			sys_semtimedop
+393	common	semget			sys_semget
+394	common	semctl			sys_semctl			compat_sys_semctl
+395	common	shmget			sys_shmget
+396	common	shmctl			sys_shmctl			compat_sys_shmctl
+397	common	shmat			sys_shmat			compat_sys_shmat
+398	common	shmdt			sys_shmdt
+399	common	msgget			sys_msgget
+400	common	msgsnd			sys_msgsnd			compat_sys_msgsnd
+401	common	msgrcv			sys_msgrcv			compat_sys_msgrcv
+402	common	msgctl			sys_msgctl			compat_sys_msgctl
+403	32	clock_gettime64			sys_clock_gettime		sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime		sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime		sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime		sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime		sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat			sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop			sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+# 435 reserved for clone3
+436	common	close_range			sys_close_range
+437	common	openat2			sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal 				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/sparc/include/syscall_table.h b/tools/perf/arch/sparc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/sparc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 2f1b42bf337b3d601f0f2e792bd79413f46e583a..99a278a3f1b5bf44132c817ed1f2623a232d3dc5 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -204,6 +204,7 @@ check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscall
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:52 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:52 -0800
Subject: [PATCH v3 07/16] perf tools: xtensa: Support syscall header
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-7-239f032481d5@rivosinc.com>

xtensa uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
 .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 439 +++++++++++++++++++++
 tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 449 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 2772c05c661bb1a8084255d19a1a75941a8ac8b8..47fe3c41fa13a388803ba804a7c3a4aac81d20ae 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Kbuild b/tools/perf/arch/xtensa/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls b/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..d4aa2358460c13945a8299b6513c93d35a5c5ea4
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscalltbl = $(srctree)/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..37effc1b134eea061f2c350c1d68b4436b65a4dd
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
@@ -0,0 +1,439 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for xtensa
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	spill				sys_ni_syscall
+1	common	xtensa				sys_ni_syscall
+2	common	available4			sys_ni_syscall
+3	common	available5			sys_ni_syscall
+4	common	available6			sys_ni_syscall
+5	common	available7			sys_ni_syscall
+6	common	available8			sys_ni_syscall
+7	common	available9			sys_ni_syscall
+# File Operations
+8	common	open				sys_open
+9	common	close				sys_close
+10	common	dup				sys_dup
+11	common	dup2				sys_dup2
+12	common	read				sys_read
+13	common	write				sys_write
+14	common	select				sys_select
+15	common	lseek				sys_lseek
+16	common	poll				sys_poll
+17	common	_llseek				sys_llseek
+18	common	epoll_wait			sys_epoll_wait
+19	common	epoll_ctl			sys_epoll_ctl
+20	common	epoll_create			sys_epoll_create
+21	common	creat				sys_creat
+22	common	truncate			sys_truncate
+23	common	ftruncate			sys_ftruncate
+24	common	readv				sys_readv
+25	common	writev				sys_writev
+26	common	fsync				sys_fsync
+27	common	fdatasync			sys_fdatasync
+28	common	truncate64			sys_truncate64
+29	common	ftruncate64			sys_ftruncate64
+30	common	pread64				sys_pread64
+31	common	pwrite64			sys_pwrite64
+32	common	link				sys_link
+33	common	rename				sys_rename
+34	common	symlink				sys_symlink
+35	common	readlink			sys_readlink
+36	common	mknod				sys_mknod
+37	common	pipe				sys_pipe
+38	common	unlink				sys_unlink
+39	common	rmdir				sys_rmdir
+40	common	mkdir				sys_mkdir
+41	common	chdir				sys_chdir
+42	common	fchdir				sys_fchdir
+43	common	getcwd				sys_getcwd
+44	common	chmod				sys_chmod
+45	common	chown				sys_chown
+46	common	stat				sys_newstat
+47	common	stat64				sys_stat64
+48	common	lchown				sys_lchown
+49	common	lstat				sys_newlstat
+50	common	lstat64				sys_lstat64
+51	common	available51			sys_ni_syscall
+52	common	fchmod				sys_fchmod
+53	common	fchown				sys_fchown
+54	common	fstat				sys_newfstat
+55	common	fstat64				sys_fstat64
+56	common	flock				sys_flock
+57	common	access				sys_access
+58	common	umask				sys_umask
+59	common	getdents			sys_getdents
+60	common	getdents64			sys_getdents64
+61	common	fcntl64				sys_fcntl64
+62	common	fallocate			sys_fallocate
+63	common	fadvise64_64			xtensa_fadvise64_64
+64	common	utime				sys_utime32
+65	common	utimes				sys_utimes_time32
+66	common	ioctl				sys_ioctl
+67	common	fcntl				sys_fcntl
+68	common	setxattr			sys_setxattr
+69	common	getxattr			sys_getxattr
+70	common	listxattr			sys_listxattr
+71	common	removexattr			sys_removexattr
+72	common	lsetxattr			sys_lsetxattr
+73	common	lgetxattr			sys_lgetxattr
+74	common	llistxattr			sys_llistxattr
+75	common	lremovexattr			sys_lremovexattr
+76	common	fsetxattr			sys_fsetxattr
+77	common	fgetxattr			sys_fgetxattr
+78	common	flistxattr			sys_flistxattr
+79	common	fremovexattr			sys_fremovexattr
+# File Map / Shared Memory Operations
+80	common	mmap2				sys_mmap_pgoff
+81	common	munmap				sys_munmap
+82	common	mprotect			sys_mprotect
+83	common	brk				sys_brk
+84	common	mlock				sys_mlock
+85	common	munlock				sys_munlock
+86	common	mlockall			sys_mlockall
+87	common	munlockall			sys_munlockall
+88	common	mremap				sys_mremap
+89	common	msync				sys_msync
+90	common	mincore				sys_mincore
+91	common	madvise				sys_madvise
+92	common	shmget				sys_shmget
+93	common	shmat				xtensa_shmat
+94	common	shmctl				sys_old_shmctl
+95	common	shmdt				sys_shmdt
+# Socket Operations
+96	common	socket				sys_socket
+97	common	setsockopt			sys_setsockopt
+98	common	getsockopt			sys_getsockopt
+99	common	shutdown			sys_shutdown
+100	common	bind				sys_bind
+101	common	connect				sys_connect
+102	common	listen				sys_listen
+103	common	accept				sys_accept
+104	common	getsockname			sys_getsockname
+105	common	getpeername			sys_getpeername
+106	common	sendmsg				sys_sendmsg
+107	common	recvmsg				sys_recvmsg
+108	common	send				sys_send
+109	common	recv				sys_recv
+110	common	sendto				sys_sendto
+111	common	recvfrom			sys_recvfrom
+112	common	socketpair			sys_socketpair
+113	common	sendfile			sys_sendfile
+114	common	sendfile64			sys_sendfile64
+115	common	sendmmsg			sys_sendmmsg
+# Process Operations
+116	common	clone				sys_clone
+117	common	execve				sys_execve
+118	common	exit				sys_exit
+119	common	exit_group			sys_exit_group
+120	common	getpid				sys_getpid
+121	common	wait4				sys_wait4
+122	common	waitid				sys_waitid
+123	common	kill				sys_kill
+124	common	tkill				sys_tkill
+125	common	tgkill				sys_tgkill
+126	common	set_tid_address			sys_set_tid_address
+127	common	gettid				sys_gettid
+128	common	setsid				sys_setsid
+129	common	getsid				sys_getsid
+130	common	prctl				sys_prctl
+131	common	personality			sys_personality
+132	common	getpriority			sys_getpriority
+133	common	setpriority			sys_setpriority
+134	common	setitimer			sys_setitimer
+135	common	getitimer			sys_getitimer
+136	common	setuid				sys_setuid
+137	common	getuid				sys_getuid
+138	common	setgid				sys_setgid
+139	common	getgid				sys_getgid
+140	common	geteuid				sys_geteuid
+141	common	getegid				sys_getegid
+142	common	setreuid			sys_setreuid
+143	common	setregid			sys_setregid
+144	common	setresuid			sys_setresuid
+145	common	getresuid			sys_getresuid
+146	common	setresgid			sys_setresgid
+147	common	getresgid			sys_getresgid
+148	common	setpgid				sys_setpgid
+149	common	getpgid				sys_getpgid
+150	common	getppid				sys_getppid
+151	common	getpgrp				sys_getpgrp
+# 152 was set_thread_area
+152	common	reserved152			sys_ni_syscall
+# 153 was get_thread_area
+153	common	reserved153			sys_ni_syscall
+154	common	times				sys_times
+155	common	acct				sys_acct
+156	common	sched_setaffinity		sys_sched_setaffinity
+157	common	sched_getaffinity		sys_sched_getaffinity
+158	common	capget				sys_capget
+159	common	capset				sys_capset
+160	common	ptrace				sys_ptrace
+161	common	semtimedop			sys_semtimedop_time32
+162	common	semget				sys_semget
+163	common	semop				sys_semop
+164	common	semctl				sys_old_semctl
+165	common	available165			sys_ni_syscall
+166	common	msgget				sys_msgget
+167	common	msgsnd				sys_msgsnd
+168	common	msgrcv				sys_msgrcv
+169	common	msgctl				sys_old_msgctl
+170	common	available170			sys_ni_syscall
+# File System
+171	common	umount2				sys_umount
+172	common	mount				sys_mount
+173	common	swapon				sys_swapon
+174	common	chroot				sys_chroot
+175	common	pivot_root			sys_pivot_root
+176	common	umount				sys_oldumount
+177	common	swapoff				sys_swapoff
+178	common	sync				sys_sync
+179	common	syncfs				sys_syncfs
+180	common	setfsuid			sys_setfsuid
+181	common	setfsgid			sys_setfsgid
+182	common	sysfs				sys_sysfs
+183	common	ustat				sys_ustat
+184	common	statfs				sys_statfs
+185	common	fstatfs				sys_fstatfs
+186	common	statfs64			sys_statfs64
+187	common	fstatfs64			sys_fstatfs64
+# System
+188	common	setrlimit			sys_setrlimit
+189	common	getrlimit			sys_getrlimit
+190	common	getrusage			sys_getrusage
+191	common	futex				sys_futex_time32
+192	common	gettimeofday			sys_gettimeofday
+193	common	settimeofday			sys_settimeofday
+194	common	adjtimex			sys_adjtimex_time32
+195	common	nanosleep			sys_nanosleep_time32
+196	common	getgroups			sys_getgroups
+197	common	setgroups			sys_setgroups
+198	common	sethostname			sys_sethostname
+199	common	setdomainname			sys_setdomainname
+200	common	syslog				sys_syslog
+201	common	vhangup				sys_vhangup
+202	common	uselib				sys_uselib
+203	common	reboot				sys_reboot
+204	common	quotactl			sys_quotactl
+# 205 was old nfsservctl
+205	common	nfsservctl			sys_ni_syscall
+206	common	_sysctl				sys_ni_syscall
+207	common	bdflush				sys_ni_syscall
+208	common	uname				sys_newuname
+209	common	sysinfo				sys_sysinfo
+210	common	init_module			sys_init_module
+211	common	delete_module			sys_delete_module
+212	common	sched_setparam			sys_sched_setparam
+213	common	sched_getparam			sys_sched_getparam
+214	common	sched_setscheduler		sys_sched_setscheduler
+215	common	sched_getscheduler		sys_sched_getscheduler
+216	common	sched_get_priority_max		sys_sched_get_priority_max
+217	common	sched_get_priority_min		sys_sched_get_priority_min
+218	common	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+219	common	sched_yield			sys_sched_yield
+222	common	available222			sys_ni_syscall
+# Signal Handling
+223	common	restart_syscall			sys_restart_syscall
+224	common	sigaltstack			sys_sigaltstack
+225	common	rt_sigreturn			xtensa_rt_sigreturn
+226	common	rt_sigaction			sys_rt_sigaction
+227	common	rt_sigprocmask			sys_rt_sigprocmask
+228	common	rt_sigpending			sys_rt_sigpending
+229	common	rt_sigtimedwait			sys_rt_sigtimedwait_time32
+230	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+231	common	rt_sigsuspend			sys_rt_sigsuspend
+# Message
+232	common	mq_open				sys_mq_open
+233	common	mq_unlink			sys_mq_unlink
+234	common	mq_timedsend			sys_mq_timedsend_time32
+235	common	mq_timedreceive			sys_mq_timedreceive_time32
+236	common	mq_notify			sys_mq_notify
+237	common	mq_getsetattr			sys_mq_getsetattr
+238	common	available238			sys_ni_syscall
+239	common	io_setup			sys_io_setup
+# IO
+240	common	io_destroy			sys_io_destroy
+241	common	io_submit			sys_io_submit
+242	common	io_getevents			sys_io_getevents_time32
+243	common	io_cancel			sys_io_cancel
+244	common	clock_settime			sys_clock_settime32
+245	common	clock_gettime			sys_clock_gettime32
+246	common	clock_getres			sys_clock_getres_time32
+247	common	clock_nanosleep			sys_clock_nanosleep_time32
+# Timer
+248	common	timer_create			sys_timer_create
+249	common	timer_delete			sys_timer_delete
+250	common	timer_settime			sys_timer_settime32
+251	common	timer_gettime			sys_timer_gettime32
+252	common	timer_getoverrun		sys_timer_getoverrun
+# System
+253	common	reserved253			sys_ni_syscall
+254	common	lookup_dcookie			sys_ni_syscall
+255	common	available255			sys_ni_syscall
+256	common	add_key				sys_add_key
+257	common	request_key			sys_request_key
+258	common	keyctl				sys_keyctl
+259	common	available259			sys_ni_syscall
+260	common	readahead			sys_readahead
+261	common	remap_file_pages		sys_remap_file_pages
+262	common	migrate_pages			sys_migrate_pages
+263	common	mbind				sys_mbind
+264	common	get_mempolicy			sys_get_mempolicy
+265	common	set_mempolicy			sys_set_mempolicy
+266	common	unshare				sys_unshare
+267	common	move_pages			sys_move_pages
+268	common	splice				sys_splice
+269	common	tee				sys_tee
+270	common	vmsplice			sys_vmsplice
+271	common	available271			sys_ni_syscall
+272	common	pselect6			sys_pselect6_time32
+273	common	ppoll				sys_ppoll_time32
+274	common	epoll_pwait			sys_epoll_pwait
+275	common	epoll_create1			sys_epoll_create1
+276	common	inotify_init			sys_inotify_init
+277	common	inotify_add_watch		sys_inotify_add_watch
+278	common	inotify_rm_watch		sys_inotify_rm_watch
+279	common	inotify_init1			sys_inotify_init1
+280	common	getcpu				sys_getcpu
+281	common	kexec_load			sys_ni_syscall
+282	common	ioprio_set			sys_ioprio_set
+283	common	ioprio_get			sys_ioprio_get
+284	common	set_robust_list			sys_set_robust_list
+285	common	get_robust_list			sys_get_robust_list
+286	common	available286			sys_ni_syscall
+287	common	available287			sys_ni_syscall
+# Relative File Operations
+288	common	openat				sys_openat
+289	common	mkdirat				sys_mkdirat
+290	common	mknodat				sys_mknodat
+291	common	unlinkat			sys_unlinkat
+292	common	renameat			sys_renameat
+293	common	linkat				sys_linkat
+294	common	symlinkat			sys_symlinkat
+295	common	readlinkat			sys_readlinkat
+296	common	utimensat			sys_utimensat_time32
+297	common	fchownat			sys_fchownat
+298	common	futimesat			sys_futimesat_time32
+299	common	fstatat64			sys_fstatat64
+300	common	fchmodat			sys_fchmodat
+301	common	faccessat			sys_faccessat
+302	common	available302			sys_ni_syscall
+303	common	available303			sys_ni_syscall
+304	common	signalfd			sys_signalfd
+# 305 was timerfd
+306	common	eventfd				sys_eventfd
+307	common	recvmmsg			sys_recvmmsg_time32
+308	common	setns				sys_setns
+309	common	signalfd4			sys_signalfd4
+310	common	dup3				sys_dup3
+311	common	pipe2				sys_pipe2
+312	common	timerfd_create			sys_timerfd_create
+313	common	timerfd_settime			sys_timerfd_settime32
+314	common	timerfd_gettime			sys_timerfd_gettime32
+315	common	available315			sys_ni_syscall
+316	common	eventfd2			sys_eventfd2
+317	common	preadv				sys_preadv
+318	common	pwritev				sys_pwritev
+319	common	available319			sys_ni_syscall
+320	common	fanotify_init			sys_fanotify_init
+321	common	fanotify_mark			sys_fanotify_mark
+322	common	process_vm_readv		sys_process_vm_readv
+323	common	process_vm_writev		sys_process_vm_writev
+324	common	name_to_handle_at		sys_name_to_handle_at
+325	common	open_by_handle_at		sys_open_by_handle_at
+326	common	sync_file_range2		sys_sync_file_range2
+327	common	perf_event_open			sys_perf_event_open
+328	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+329	common	clock_adjtime			sys_clock_adjtime32
+330	common	prlimit64			sys_prlimit64
+331	common	kcmp				sys_kcmp
+332	common	finit_module			sys_finit_module
+333	common	accept4				sys_accept4
+334	common	sched_setattr			sys_sched_setattr
+335	common	sched_getattr			sys_sched_getattr
+336	common	renameat2			sys_renameat2
+337	common	seccomp				sys_seccomp
+338	common	getrandom			sys_getrandom
+339	common	memfd_create			sys_memfd_create
+340	common	bpf				sys_bpf
+341	common	execveat			sys_execveat
+342	common	userfaultfd			sys_userfaultfd
+343	common	membarrier			sys_membarrier
+344	common	mlock2				sys_mlock2
+345	common	copy_file_range			sys_copy_file_range
+346	common	preadv2				sys_preadv2
+347	common	pwritev2			sys_pwritev2
+348	common	pkey_mprotect			sys_pkey_mprotect
+349	common	pkey_alloc			sys_pkey_alloc
+350	common	pkey_free			sys_pkey_free
+351	common	statx				sys_statx
+352	common	rseq				sys_rseq
+# 353 through 402 are unassigned to sync up with generic numbers
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal 				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/xtensa/include/syscall_table.h b/tools/perf/arch/xtensa/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/xtensa/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 99a278a3f1b5bf44132c817ed1f2623a232d3dc5..e9e352579e6d33085a1d863441432c81d2353f49 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -205,6 +205,7 @@ check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/sys
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:53 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:53 -0800
Subject: [PATCH v3 08/16] perf tools: x86: Use generic syscall scripts
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-8-239f032481d5@rivosinc.com>

Use the generic scripts to generate headers from the syscall table for
both 32- and 64-bit x86.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  3 +-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/x86/Build                          |  1 -
 tools/perf/arch/x86/Makefile                       | 25 -------------
 tools/perf/arch/x86/entry/syscalls/Kbuild          |  3 ++
 .../perf/arch/x86/entry/syscalls/Makefile.syscalls |  6 ++++
 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   | 42 ----------------------
 tools/perf/arch/x86/include/syscall_table.h        |  8 +++++
 tools/perf/util/syscalltbl.c                       | 10 +-----
 9 files changed, 20 insertions(+), 80 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index d3c12c6ba6764e9a8b12acee603a0509154f2c74..218c407c953f8526ea995cc5126a94654ebbae11 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 powerpc arm64 s390 mips loongarch riscv))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips loongarch))
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -56,7 +56,6 @@ endif
 # Additional ARCH settings for x86
 ifeq ($(SRCARCH),x86)
   $(call detected,CONFIG_X86)
-  CFLAGS += -I$(OUTPUT)arch/x86/include/generated
   ifeq (${IS_64_BIT}, 1)
     CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT
     ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 47fe3c41fa13a388803ba804a7c3a4aac81d20ae..698967f50ceb5cfc29dc5c2947c995980120e64e 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/x86/Build b/tools/perf/arch/x86/Build
index 87d0574913431b7c4505caf78f41d48b180a2fbc..02a1ca780a2071d322f75fb2885c3a36bc278e8d 100644
--- a/tools/perf/arch/x86/Build
+++ b/tools/perf/arch/x86/Build
@@ -2,7 +2,6 @@ perf-util-y += util/
 perf-test-y += tests/
 
 ifdef SHELLCHECK
-  SHELL_TESTS := entry/syscalls/syscalltbl.sh
   TEST_LOGS := $(SHELL_TESTS:%=%.shellcheck_log)
 else
   SHELL_TESTS :=
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index a6b6e0a9308a8e401c65eb802e5815a41fbdefe9..a295a80ea078199547e816d18531820bfdba7961 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -1,28 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
-
-###
-# Syscall table generation
-#
-
-generated := $(OUTPUT)arch/x86/include/generated
-out       := $(generated)/asm
-header    := $(out)/syscalls_64.c
-header_32 := $(out)/syscalls_32.c
-sys       := $(srctree)/tools/perf/arch/x86/entry/syscalls
-systbl    := $(sys)/syscalltbl.sh
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sys)/syscall_64.tbl $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
-
-$(header_32): $(sys)/syscall_32.tbl $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_32.tbl 'x86' > $@
-
-clean::
-	$(call QUIET_CLEAN, x86) $(RM) -r $(header) $(generated)
-
-archheaders: $(header) $(header_32)
diff --git a/tools/perf/arch/x86/entry/syscalls/Kbuild b/tools/perf/arch/x86/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls b/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..db3d5d6d4e5699d338afc55f6415612ef924d985
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += i386
+syscall_abis_64 +=
+
+syscalltbl = $(srctree)/tools/perf/arch/x86/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh b/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
deleted file mode 100755
index 2b71f99933a549607b0c18aa2b8be16b860f603c..0000000000000000000000000000000000000000
--- a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-in="$1"
-arch="$2"
-
-syscall_macro() {
-    nr="$1"
-    name="$2"
-
-    echo "	[$nr] = \"$name\","
-}
-
-emit() {
-    nr="$1"
-    entry="$2"
-
-    syscall_macro "$nr" "$entry"
-}
-
-echo "static const char *const syscalltbl_${arch}[] = {"
-
-sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
-grep '^[0-9]' "$in" | sort -n > $sorted_table
-
-max_nr=0
-# the params are: nr abi name entry compat
-# use _ for intentionally unused variables according to SC2034
-while read nr _ name _ _; do
-    if [ $nr -ge 512 ] ; then # discard compat sycalls
-        break
-    fi
-
-    emit "$nr" "$name"
-    max_nr=$nr
-done < $sorted_table
-
-rm -f $sorted_table
-
-echo "};"
-
-echo "#define SYSCALLTBL_${arch}_MAX_ID ${max_nr}"
diff --git a/tools/perf/arch/x86/include/syscall_table.h b/tools/perf/arch/x86/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/x86/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index ccf234a54366f9921c3b9a02ffb0a365d17244bc..02f23483bfff83809c4e649a2d054dba6975d12c 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -14,15 +14,7 @@
 #include <string.h>
 #include "string2.h"
 
-#if defined(__x86_64__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_x86_64;
-#elif defined(__i386__)
-#include <asm/syscalls_32.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_x86_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_x86;
-#elif defined(__s390x__)
+#if defined(__s390x__)
 #include <asm/syscalls_64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_s390_64;

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:54 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:54 -0800
Subject: [PATCH v3 09/16] perf tools: alpha: Support syscall header
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-9-239f032481d5@rivosinc.com>

alpha uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
 .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 +++++++++++++++++++++
 tools/perf/arch/alpha/include/syscall_table.h      |   2 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 515 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 698967f50ceb5cfc29dc5c2947c995980120e64e..7528e6acaf3b1cf76198dafe094800fc00fd56eb 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/alpha/entry/syscalls/Kbuild b/tools/perf/arch/alpha/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls b/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..690168aac34db9f1b96346210993675defcfc300
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64  +=
+
+syscalltbl = $(srctree)/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/alpha/entry/syscalls/syscall.tbl b/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..74720667fe091768800a22fd4ce68b5324abff09
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
@@ -0,0 +1,504 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for alpha
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	osf_syscall			alpha_syscall_zero
+1	common	exit				sys_exit
+2	common	fork				alpha_fork
+3	common	read				sys_read
+4	common	write				sys_write
+5	common	osf_old_open			sys_ni_syscall
+6	common	close				sys_close
+7	common	osf_wait4			sys_osf_wait4
+8	common	osf_old_creat			sys_ni_syscall
+9	common	link				sys_link
+10	common	unlink				sys_unlink
+11	common	osf_execve			sys_ni_syscall
+12	common	chdir				sys_chdir
+13	common	fchdir				sys_fchdir
+14	common	mknod				sys_mknod
+15	common	chmod				sys_chmod
+16	common	chown				sys_chown
+17	common	brk				sys_osf_brk
+18	common	osf_getfsstat			sys_ni_syscall
+19	common	lseek				sys_lseek
+20	common	getxpid				sys_getxpid
+21	common	osf_mount			sys_osf_mount
+22	common	umount2				sys_umount
+23	common	setuid				sys_setuid
+24	common	getxuid				sys_getxuid
+25	common	exec_with_loader		sys_ni_syscall
+26	common	ptrace				sys_ptrace
+27	common	osf_nrecvmsg			sys_ni_syscall
+28	common	osf_nsendmsg			sys_ni_syscall
+29	common	osf_nrecvfrom			sys_ni_syscall
+30	common	osf_naccept			sys_ni_syscall
+31	common	osf_ngetpeername		sys_ni_syscall
+32	common	osf_ngetsockname		sys_ni_syscall
+33	common	access				sys_access
+34	common	osf_chflags			sys_ni_syscall
+35	common	osf_fchflags			sys_ni_syscall
+36	common	sync				sys_sync
+37	common	kill				sys_kill
+38	common	osf_old_stat			sys_ni_syscall
+39	common	setpgid				sys_setpgid
+40	common	osf_old_lstat			sys_ni_syscall
+41	common	dup				sys_dup
+42	common	pipe				sys_alpha_pipe
+43	common	osf_set_program_attributes	sys_osf_set_program_attributes
+44	common	osf_profil			sys_ni_syscall
+45	common	open				sys_open
+46	common	osf_old_sigaction		sys_ni_syscall
+47	common	getxgid				sys_getxgid
+48	common	osf_sigprocmask			sys_osf_sigprocmask
+49	common	osf_getlogin			sys_ni_syscall
+50	common	osf_setlogin			sys_ni_syscall
+51	common	acct				sys_acct
+52	common	sigpending			sys_sigpending
+54	common	ioctl				sys_ioctl
+55	common	osf_reboot			sys_ni_syscall
+56	common	osf_revoke			sys_ni_syscall
+57	common	symlink				sys_symlink
+58	common	readlink			sys_readlink
+59	common	execve				sys_execve
+60	common	umask				sys_umask
+61	common	chroot				sys_chroot
+62	common	osf_old_fstat			sys_ni_syscall
+63	common	getpgrp				sys_getpgrp
+64	common	getpagesize			sys_getpagesize
+65	common	osf_mremap			sys_ni_syscall
+66	common	vfork				alpha_vfork
+67	common	stat				sys_newstat
+68	common	lstat				sys_newlstat
+69	common	osf_sbrk			sys_ni_syscall
+70	common	osf_sstk			sys_ni_syscall
+71	common	mmap				sys_osf_mmap
+72	common	osf_old_vadvise			sys_ni_syscall
+73	common	munmap				sys_munmap
+74	common	mprotect			sys_mprotect
+75	common	madvise				sys_madvise
+76	common	vhangup				sys_vhangup
+77	common	osf_kmodcall			sys_ni_syscall
+78	common	osf_mincore			sys_ni_syscall
+79	common	getgroups			sys_getgroups
+80	common	setgroups			sys_setgroups
+81	common	osf_old_getpgrp			sys_ni_syscall
+82	common	setpgrp				sys_setpgid
+83	common	osf_setitimer			compat_sys_setitimer
+84	common	osf_old_wait			sys_ni_syscall
+85	common	osf_table			sys_ni_syscall
+86	common	osf_getitimer			compat_sys_getitimer
+87	common	gethostname			sys_gethostname
+88	common	sethostname			sys_sethostname
+89	common	getdtablesize			sys_getdtablesize
+90	common	dup2				sys_dup2
+91	common	fstat				sys_newfstat
+92	common	fcntl				sys_fcntl
+93	common	osf_select			sys_osf_select
+94	common	poll				sys_poll
+95	common	fsync				sys_fsync
+96	common	setpriority			sys_setpriority
+97	common	socket				sys_socket
+98	common	connect				sys_connect
+99	common	accept				sys_accept
+100	common	getpriority			sys_osf_getpriority
+101	common	send				sys_send
+102	common	recv				sys_recv
+103	common	sigreturn			sys_sigreturn
+104	common	bind				sys_bind
+105	common	setsockopt			sys_setsockopt
+106	common	listen				sys_listen
+107	common	osf_plock			sys_ni_syscall
+108	common	osf_old_sigvec			sys_ni_syscall
+109	common	osf_old_sigblock		sys_ni_syscall
+110	common	osf_old_sigsetmask		sys_ni_syscall
+111	common	sigsuspend			sys_sigsuspend
+112	common	osf_sigstack			sys_osf_sigstack
+113	common	recvmsg				sys_recvmsg
+114	common	sendmsg				sys_sendmsg
+115	common	osf_old_vtrace			sys_ni_syscall
+116	common	osf_gettimeofday		sys_osf_gettimeofday
+117	common	osf_getrusage			sys_osf_getrusage
+118	common	getsockopt			sys_getsockopt
+120	common	readv				sys_readv
+121	common	writev				sys_writev
+122	common	osf_settimeofday		sys_osf_settimeofday
+123	common	fchown				sys_fchown
+124	common	fchmod				sys_fchmod
+125	common	recvfrom			sys_recvfrom
+126	common	setreuid			sys_setreuid
+127	common	setregid			sys_setregid
+128	common	rename				sys_rename
+129	common	truncate			sys_truncate
+130	common	ftruncate			sys_ftruncate
+131	common	flock				sys_flock
+132	common	setgid				sys_setgid
+133	common	sendto				sys_sendto
+134	common	shutdown			sys_shutdown
+135	common	socketpair			sys_socketpair
+136	common	mkdir				sys_mkdir
+137	common	rmdir				sys_rmdir
+138	common	osf_utimes			sys_osf_utimes
+139	common	osf_old_sigreturn		sys_ni_syscall
+140	common	osf_adjtime			sys_ni_syscall
+141	common	getpeername			sys_getpeername
+142	common	osf_gethostid			sys_ni_syscall
+143	common	osf_sethostid			sys_ni_syscall
+144	common	getrlimit			sys_getrlimit
+145	common	setrlimit			sys_setrlimit
+146	common	osf_old_killpg			sys_ni_syscall
+147	common	setsid				sys_setsid
+148	common	quotactl			sys_quotactl
+149	common	osf_oldquota			sys_ni_syscall
+150	common	getsockname			sys_getsockname
+153	common	osf_pid_block			sys_ni_syscall
+154	common	osf_pid_unblock			sys_ni_syscall
+156	common	sigaction			sys_osf_sigaction
+157	common	osf_sigwaitprim			sys_ni_syscall
+158	common	osf_nfssvc			sys_ni_syscall
+159	common	osf_getdirentries		sys_osf_getdirentries
+160	common	osf_statfs			sys_osf_statfs
+161	common	osf_fstatfs			sys_osf_fstatfs
+163	common	osf_asynch_daemon		sys_ni_syscall
+164	common	osf_getfh			sys_ni_syscall
+165	common	osf_getdomainname		sys_osf_getdomainname
+166	common	setdomainname			sys_setdomainname
+169	common	osf_exportfs			sys_ni_syscall
+181	common	osf_alt_plock			sys_ni_syscall
+184	common	osf_getmnt			sys_ni_syscall
+187	common	osf_alt_sigpending		sys_ni_syscall
+188	common	osf_alt_setsid			sys_ni_syscall
+199	common	osf_swapon			sys_swapon
+200	common	msgctl				sys_old_msgctl
+201	common	msgget				sys_msgget
+202	common	msgrcv				sys_msgrcv
+203	common	msgsnd				sys_msgsnd
+204	common	semctl				sys_old_semctl
+205	common	semget				sys_semget
+206	common	semop				sys_semop
+207	common	osf_utsname			sys_osf_utsname
+208	common	lchown				sys_lchown
+209	common	shmat				sys_shmat
+210	common	shmctl				sys_old_shmctl
+211	common	shmdt				sys_shmdt
+212	common	shmget				sys_shmget
+213	common	osf_mvalid			sys_ni_syscall
+214	common	osf_getaddressconf		sys_ni_syscall
+215	common	osf_msleep			sys_ni_syscall
+216	common	osf_mwakeup			sys_ni_syscall
+217	common	msync				sys_msync
+218	common	osf_signal			sys_ni_syscall
+219	common	osf_utc_gettime			sys_ni_syscall
+220	common	osf_utc_adjtime			sys_ni_syscall
+222	common	osf_security			sys_ni_syscall
+223	common	osf_kloadcall			sys_ni_syscall
+224	common	osf_stat			sys_osf_stat
+225	common	osf_lstat			sys_osf_lstat
+226	common	osf_fstat			sys_osf_fstat
+227	common	osf_statfs64			sys_osf_statfs64
+228	common	osf_fstatfs64			sys_osf_fstatfs64
+233	common	getpgid				sys_getpgid
+234	common	getsid				sys_getsid
+235	common	sigaltstack			sys_sigaltstack
+236	common	osf_waitid			sys_ni_syscall
+237	common	osf_priocntlset			sys_ni_syscall
+238	common	osf_sigsendset			sys_ni_syscall
+239	common	osf_set_speculative		sys_ni_syscall
+240	common	osf_msfs_syscall		sys_ni_syscall
+241	common	osf_sysinfo			sys_osf_sysinfo
+242	common	osf_uadmin			sys_ni_syscall
+243	common	osf_fuser			sys_ni_syscall
+244	common	osf_proplist_syscall		sys_osf_proplist_syscall
+245	common	osf_ntp_adjtime			sys_ni_syscall
+246	common	osf_ntp_gettime			sys_ni_syscall
+247	common	osf_pathconf			sys_ni_syscall
+248	common	osf_fpathconf			sys_ni_syscall
+250	common	osf_uswitch			sys_ni_syscall
+251	common	osf_usleep_thread		sys_osf_usleep_thread
+252	common	osf_audcntl			sys_ni_syscall
+253	common	osf_audgen			sys_ni_syscall
+254	common	sysfs				sys_sysfs
+255	common	osf_subsys_info			sys_ni_syscall
+256	common	osf_getsysinfo			sys_osf_getsysinfo
+257	common	osf_setsysinfo			sys_osf_setsysinfo
+258	common	osf_afs_syscall			sys_ni_syscall
+259	common	osf_swapctl			sys_ni_syscall
+260	common	osf_memcntl			sys_ni_syscall
+261	common	osf_fdatasync			sys_ni_syscall
+300	common	bdflush				sys_ni_syscall
+301	common	sethae				sys_sethae
+302	common	mount				sys_mount
+303	common	old_adjtimex			sys_old_adjtimex
+304	common	swapoff				sys_swapoff
+305	common	getdents			sys_getdents
+306	common	create_module			sys_ni_syscall
+307	common	init_module			sys_init_module
+308	common	delete_module			sys_delete_module
+309	common	get_kernel_syms			sys_ni_syscall
+310	common	syslog				sys_syslog
+311	common	reboot				sys_reboot
+312	common	clone				alpha_clone
+313	common	uselib				sys_uselib
+314	common	mlock				sys_mlock
+315	common	munlock				sys_munlock
+316	common	mlockall			sys_mlockall
+317	common	munlockall			sys_munlockall
+318	common	sysinfo				sys_sysinfo
+319	common	_sysctl				sys_ni_syscall
+# 320 was sys_idle
+321	common	oldumount			sys_oldumount
+322	common	swapon				sys_swapon
+323	common	times				sys_times
+324	common	personality			sys_personality
+325	common	setfsuid			sys_setfsuid
+326	common	setfsgid			sys_setfsgid
+327	common	ustat				sys_ustat
+328	common	statfs				sys_statfs
+329	common	fstatfs				sys_fstatfs
+330	common	sched_setparam			sys_sched_setparam
+331	common	sched_getparam			sys_sched_getparam
+332	common	sched_setscheduler		sys_sched_setscheduler
+333	common	sched_getscheduler		sys_sched_getscheduler
+334	common	sched_yield			sys_sched_yield
+335	common	sched_get_priority_max		sys_sched_get_priority_max
+336	common	sched_get_priority_min		sys_sched_get_priority_min
+337	common	sched_rr_get_interval		sys_sched_rr_get_interval
+338	common	afs_syscall			sys_ni_syscall
+339	common	uname				sys_newuname
+340	common	nanosleep			sys_nanosleep
+341	common	mremap				sys_mremap
+342	common	nfsservctl			sys_ni_syscall
+343	common	setresuid			sys_setresuid
+344	common	getresuid			sys_getresuid
+345	common	pciconfig_read			sys_pciconfig_read
+346	common	pciconfig_write			sys_pciconfig_write
+347	common	query_module			sys_ni_syscall
+348	common	prctl				sys_prctl
+349	common	pread64				sys_pread64
+350	common	pwrite64			sys_pwrite64
+351	common	rt_sigreturn			sys_rt_sigreturn
+352	common	rt_sigaction			sys_rt_sigaction
+353	common	rt_sigprocmask			sys_rt_sigprocmask
+354	common	rt_sigpending			sys_rt_sigpending
+355	common	rt_sigtimedwait			sys_rt_sigtimedwait
+356	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+357	common	rt_sigsuspend			sys_rt_sigsuspend
+358	common	select				sys_select
+359	common	gettimeofday			sys_gettimeofday
+360	common	settimeofday			sys_settimeofday
+361	common	getitimer			sys_getitimer
+362	common	setitimer			sys_setitimer
+363	common	utimes				sys_utimes
+364	common	getrusage			sys_getrusage
+365	common	wait4				sys_wait4
+366	common	adjtimex			sys_adjtimex
+367	common	getcwd				sys_getcwd
+368	common	capget				sys_capget
+369	common	capset				sys_capset
+370	common	sendfile			sys_sendfile64
+371	common	setresgid			sys_setresgid
+372	common	getresgid			sys_getresgid
+373	common	dipc				sys_ni_syscall
+374	common	pivot_root			sys_pivot_root
+375	common	mincore				sys_mincore
+376	common	pciconfig_iobase		sys_pciconfig_iobase
+377	common	getdents64			sys_getdents64
+378	common	gettid				sys_gettid
+379	common	readahead			sys_readahead
+# 380 is unused
+381	common	tkill				sys_tkill
+382	common	setxattr			sys_setxattr
+383	common	lsetxattr			sys_lsetxattr
+384	common	fsetxattr			sys_fsetxattr
+385	common	getxattr			sys_getxattr
+386	common	lgetxattr			sys_lgetxattr
+387	common	fgetxattr			sys_fgetxattr
+388	common	listxattr			sys_listxattr
+389	common	llistxattr			sys_llistxattr
+390	common	flistxattr			sys_flistxattr
+391	common	removexattr			sys_removexattr
+392	common	lremovexattr			sys_lremovexattr
+393	common	fremovexattr			sys_fremovexattr
+394	common	futex				sys_futex
+395	common	sched_setaffinity		sys_sched_setaffinity
+396	common	sched_getaffinity		sys_sched_getaffinity
+397	common	tuxcall				sys_ni_syscall
+398	common	io_setup			sys_io_setup
+399	common	io_destroy			sys_io_destroy
+400	common	io_getevents			sys_io_getevents
+401	common	io_submit			sys_io_submit
+402	common	io_cancel			sys_io_cancel
+405	common	exit_group			sys_exit_group
+406	common	lookup_dcookie			sys_ni_syscall
+407	common	epoll_create			sys_epoll_create
+408	common	epoll_ctl			sys_epoll_ctl
+409	common	epoll_wait			sys_epoll_wait
+410	common	remap_file_pages		sys_remap_file_pages
+411	common	set_tid_address			sys_set_tid_address
+412	common	restart_syscall			sys_restart_syscall
+413	common	fadvise64			sys_fadvise64
+414	common	timer_create			sys_timer_create
+415	common	timer_settime			sys_timer_settime
+416	common	timer_gettime			sys_timer_gettime
+417	common	timer_getoverrun		sys_timer_getoverrun
+418	common	timer_delete			sys_timer_delete
+419	common	clock_settime			sys_clock_settime
+420	common	clock_gettime			sys_clock_gettime
+421	common	clock_getres			sys_clock_getres
+422	common	clock_nanosleep			sys_clock_nanosleep
+423	common	semtimedop			sys_semtimedop
+424	common	tgkill				sys_tgkill
+425	common	stat64				sys_stat64
+426	common	lstat64				sys_lstat64
+427	common	fstat64				sys_fstat64
+428	common	vserver				sys_ni_syscall
+429	common	mbind				sys_ni_syscall
+430	common	get_mempolicy			sys_ni_syscall
+431	common	set_mempolicy			sys_ni_syscall
+432	common	mq_open				sys_mq_open
+433	common	mq_unlink			sys_mq_unlink
+434	common	mq_timedsend			sys_mq_timedsend
+435	common	mq_timedreceive			sys_mq_timedreceive
+436	common	mq_notify			sys_mq_notify
+437	common	mq_getsetattr			sys_mq_getsetattr
+438	common	waitid				sys_waitid
+439	common	add_key				sys_add_key
+440	common	request_key			sys_request_key
+441	common	keyctl				sys_keyctl
+442	common	ioprio_set			sys_ioprio_set
+443	common	ioprio_get			sys_ioprio_get
+444	common	inotify_init			sys_inotify_init
+445	common	inotify_add_watch		sys_inotify_add_watch
+446	common	inotify_rm_watch		sys_inotify_rm_watch
+447	common	fdatasync			sys_fdatasync
+448	common	kexec_load			sys_kexec_load
+449	common	migrate_pages			sys_migrate_pages
+450	common	openat				sys_openat
+451	common	mkdirat				sys_mkdirat
+452	common	mknodat				sys_mknodat
+453	common	fchownat			sys_fchownat
+454	common	futimesat			sys_futimesat
+455	common	fstatat64			sys_fstatat64
+456	common	unlinkat			sys_unlinkat
+457	common	renameat			sys_renameat
+458	common	linkat				sys_linkat
+459	common	symlinkat			sys_symlinkat
+460	common	readlinkat			sys_readlinkat
+461	common	fchmodat			sys_fchmodat
+462	common	faccessat			sys_faccessat
+463	common	pselect6			sys_pselect6
+464	common	ppoll				sys_ppoll
+465	common	unshare				sys_unshare
+466	common	set_robust_list			sys_set_robust_list
+467	common	get_robust_list			sys_get_robust_list
+468	common	splice				sys_splice
+469	common	sync_file_range			sys_sync_file_range
+470	common	tee				sys_tee
+471	common	vmsplice			sys_vmsplice
+472	common	move_pages			sys_move_pages
+473	common	getcpu				sys_getcpu
+474	common	epoll_pwait			sys_epoll_pwait
+475	common	utimensat			sys_utimensat
+476	common	signalfd			sys_signalfd
+477	common	timerfd				sys_ni_syscall
+478	common	eventfd				sys_eventfd
+479	common	recvmmsg			sys_recvmmsg
+480	common	fallocate			sys_fallocate
+481	common	timerfd_create			sys_timerfd_create
+482	common	timerfd_settime			sys_timerfd_settime
+483	common	timerfd_gettime			sys_timerfd_gettime
+484	common	signalfd4			sys_signalfd4
+485	common	eventfd2			sys_eventfd2
+486	common	epoll_create1			sys_epoll_create1
+487	common	dup3				sys_dup3
+488	common	pipe2				sys_pipe2
+489	common	inotify_init1			sys_inotify_init1
+490	common	preadv				sys_preadv
+491	common	pwritev				sys_pwritev
+492	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+493	common	perf_event_open			sys_perf_event_open
+494	common	fanotify_init			sys_fanotify_init
+495	common	fanotify_mark			sys_fanotify_mark
+496	common	prlimit64			sys_prlimit64
+497	common	name_to_handle_at		sys_name_to_handle_at
+498	common	open_by_handle_at		sys_open_by_handle_at
+499	common	clock_adjtime			sys_clock_adjtime
+500	common	syncfs				sys_syncfs
+501	common	setns				sys_setns
+502	common	accept4				sys_accept4
+503	common	sendmmsg			sys_sendmmsg
+504	common	process_vm_readv		sys_process_vm_readv
+505	common	process_vm_writev		sys_process_vm_writev
+506	common	kcmp				sys_kcmp
+507	common	finit_module			sys_finit_module
+508	common	sched_setattr			sys_sched_setattr
+509	common	sched_getattr			sys_sched_getattr
+510	common	renameat2			sys_renameat2
+511	common	getrandom			sys_getrandom
+512	common	memfd_create			sys_memfd_create
+513	common	execveat			sys_execveat
+514	common	seccomp				sys_seccomp
+515	common	bpf				sys_bpf
+516	common	userfaultfd			sys_userfaultfd
+517	common	membarrier			sys_membarrier
+518	common	mlock2				sys_mlock2
+519	common	copy_file_range			sys_copy_file_range
+520	common	preadv2				sys_preadv2
+521	common	pwritev2			sys_pwritev2
+522	common	statx				sys_statx
+523	common	io_pgetevents			sys_io_pgetevents
+524	common	pkey_mprotect			sys_pkey_mprotect
+525	common	pkey_alloc			sys_pkey_alloc
+526	common	pkey_free			sys_pkey_free
+527	common	rseq				sys_rseq
+528	common	statfs64			sys_statfs64
+529	common	fstatfs64			sys_fstatfs64
+530	common	getegid				sys_getegid
+531	common	geteuid				sys_geteuid
+532	common	getppid				sys_getppid
+# all other architectures have common numbers for new syscall, alpha
+# is the exception.
+534	common	pidfd_send_signal		sys_pidfd_send_signal
+535	common	io_uring_setup			sys_io_uring_setup
+536	common	io_uring_enter			sys_io_uring_enter
+537	common	io_uring_register		sys_io_uring_register
+538	common	open_tree			sys_open_tree
+539	common	move_mount			sys_move_mount
+540	common	fsopen				sys_fsopen
+541	common	fsconfig			sys_fsconfig
+542	common	fsmount				sys_fsmount
+543	common	fspick				sys_fspick
+544	common	pidfd_open			sys_pidfd_open
+545	common	clone3				alpha_clone3
+546	common	close_range			sys_close_range
+547	common	openat2				sys_openat2
+548	common	pidfd_getfd			sys_pidfd_getfd
+549	common	faccessat2			sys_faccessat2
+550	common	process_madvise			sys_process_madvise
+551	common	epoll_pwait2			sys_epoll_pwait2
+552	common	mount_setattr			sys_mount_setattr
+553	common	quotactl_fd			sys_quotactl_fd
+554	common	landlock_create_ruleset		sys_landlock_create_ruleset
+555	common	landlock_add_rule		sys_landlock_add_rule
+556	common	landlock_restrict_self		sys_landlock_restrict_self
+# 557 reserved for memfd_secret
+558	common	process_mrelease		sys_process_mrelease
+559	common  futex_waitv                     sys_futex_waitv
+560	common	set_mempolicy_home_node		sys_ni_syscall
+561	common	cachestat			sys_cachestat
+562	common	fchmodat2			sys_fchmodat2
+563	common	map_shadow_stack		sys_map_shadow_stack
+564	common	futex_wake			sys_futex_wake
+565	common	futex_wait			sys_futex_wait
+566	common	futex_requeue			sys_futex_requeue
+567	common	statmount			sys_statmount
+568	common	listmount			sys_listmount
+569	common	lsm_get_self_attr		sys_lsm_get_self_attr
+570	common	lsm_set_self_attr		sys_lsm_set_self_attr
+571	common	lsm_list_modules		sys_lsm_list_modules
+572	common  mseal				sys_mseal
diff --git a/tools/perf/arch/alpha/include/syscall_table.h b/tools/perf/arch/alpha/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..b53e31c15805319a01719c22d489c4037378b02b
--- /dev/null
+++ b/tools/perf/arch/alpha/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index e9e352579e6d33085a1d863441432c81d2353f49..a821df1fd4c0e78c9706304e5b8974cbc5ef4437 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -206,6 +206,7 @@ check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tb
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:55 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:55 -0800
Subject: [PATCH v3 10/16] perf tools: parisc: Support syscall header
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-10-239f032481d5@rivosinc.com>

parisc uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
 .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
 tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++++
 tools/perf/arch/parisc/include/syscall_table.h     |   8 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 482 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 7528e6acaf3b1cf76198dafe094800fc00fd56eb..c4bd151fb7e4fb14a53998e58afae37599696da3 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/parisc/entry/syscalls/Kbuild b/tools/perf/arch/parisc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..ae326fecb83b307fb5b0a885ae109480aafd586f
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscall_abis_64  +=
+
+syscalltbl = $(srctree)/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/parisc/entry/syscalls/syscall.tbl b/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..66dc406b12e4482832b0e8836b8267b0fb37a5ed
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
@@ -0,0 +1,463 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for parisc
+#
+# The format is:
+# <number> <abi> <name> <entry point> <compat entry point>
+#
+# The <abi> can be common, 64, or 32 for this file.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork_wrapper
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open			compat_sys_open
+6	common	close			sys_close
+7	common	waitpid			sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve			compat_sys_execve
+12	common	chdir			sys_chdir
+13	32	time			sys_time32
+13	64	time			sys_time
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown
+17	common	socket			sys_socket
+18	common	stat			sys_newstat			compat_sys_newstat
+19	common	lseek			sys_lseek			compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+22	common	bind			sys_bind
+23	common	setuid			sys_setuid
+24	common	getuid			sys_getuid
+25	32	stime			sys_stime32
+25	64	stime			sys_stime
+26	common	ptrace			sys_ptrace			compat_sys_ptrace
+27	common	alarm			sys_alarm
+28	common	fstat			sys_newfstat			compat_sys_newfstat
+29	common	pause			sys_pause
+30	32	utime			sys_utime32
+30	64	utime			sys_utime
+31	common	connect			sys_connect
+32	common	listen			sys_listen
+33	common	access			sys_access
+34	common	nice			sys_nice
+35	common	accept			sys_accept
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times			compat_sys_times
+44	common	getsockname		sys_getsockname
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid
+47	common	getgid			sys_getgid
+48	common	signal			sys_signal
+49	common	geteuid			sys_geteuid
+50	common	getegid			sys_getegid
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+53	common	getpeername		sys_getpeername
+54	common	ioctl			sys_ioctl			compat_sys_ioctl
+55	common	fcntl			sys_fcntl			compat_sys_fcntl
+56	common	socketpair		sys_socketpair
+57	common	setpgid			sys_setpgid
+58	common	send			sys_send
+59	common	uname			sys_newuname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat			compat_sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	pivot_root		sys_pivot_root
+68	common	sgetmask		sys_sgetmask			sys32_unimplemented
+69	common	ssetmask		sys_ssetmask			sys32_unimplemented
+70	common	setreuid		sys_setreuid
+71	common	setregid		sys_setregid
+72	common	mincore			sys_mincore
+73	common	sigpending		sys_sigpending			compat_sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit			compat_sys_setrlimit
+76	common	getrlimit		sys_getrlimit			compat_sys_getrlimit
+77	common	getrusage		sys_getrusage			compat_sys_getrusage
+78	common	gettimeofday		sys_gettimeofday		compat_sys_gettimeofday
+79	common	settimeofday		sys_settimeofday		compat_sys_settimeofday
+80	common	getgroups		sys_getgroups
+81	common	setgroups		sys_setgroups
+82	common	sendto			sys_sendto
+83	common	symlink			sys_symlink
+84	common	lstat			sys_newlstat			compat_sys_newlstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_ni_syscall
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+89	common	mmap2			sys_mmap2
+90	common	mmap			sys_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate			compat_sys_truncate
+93	common	ftruncate		sys_ftruncate			compat_sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+98	common	recv			sys_recv			compat_sys_recv
+99	common	statfs			sys_statfs			compat_sys_statfs
+100	common	fstatfs			sys_fstatfs			compat_sys_fstatfs
+101	common	stat64			sys_stat64
+# 102 was socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer			compat_sys_setitimer
+105	common	getitimer		sys_getitimer			compat_sys_getitimer
+106	common	capget			sys_capget
+107	common	capset			sys_capset
+108	32	pread64			parisc_pread64
+108	64	pread64			sys_pread64
+109	32	pwrite64		parisc_pwrite64
+109	64	pwrite64		sys_pwrite64
+110	common	getcwd			sys_getcwd
+111	common	vhangup			sys_vhangup
+112	common	fstat64			sys_fstat64
+113	common	vfork			sys_vfork_wrapper
+114	common	wait4			sys_wait4			compat_sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo			compat_sys_sysinfo
+117	common	shutdown		sys_shutdown
+118	common	fsync			sys_fsync
+119	common	madvise			parisc_madvise
+120	common	clone			sys_clone_wrapper
+121	common	setdomainname		sys_setdomainname
+122	common	sendfile		sys_sendfile			compat_sys_sendfile
+123	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
+124	32	adjtimex		sys_adjtimex_time32
+124	64	adjtimex		sys_adjtimex
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask			compat_sys_sigprocmask
+# 127 was create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	32	personality		parisc_personality
+136	64	personality		sys_personality
+# 137 was afs_syscall
+138	common	setfsuid		sys_setfsuid
+139	common	setfsgid		sys_setfsgid
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents			compat_sys_getdents
+142	common	_newselect		sys_select			compat_sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	32	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+161	64	sched_rr_get_interval	sys_sched_rr_get_interval
+162	32	nanosleep		sys_nanosleep_time32
+162	64	nanosleep		sys_nanosleep
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid
+165	common	getresuid		sys_getresuid
+166	common	sigaltstack		sys_sigaltstack			compat_sys_sigaltstack
+# 167 was query_module
+168	common	poll			sys_poll
+# 169 was nfsservctl
+170	common	setresgid		sys_setresgid
+171	common	getresgid		sys_getresgid
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper
+174	common	rt_sigaction		sys_rt_sigaction		compat_sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending		compat_sys_rt_sigpending
+177	32	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+177	64	rt_sigtimedwait		sys_rt_sigtimedwait
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+180	common	chown			sys_chown
+181	common	setsockopt		sys_setsockopt			sys_setsockopt
+182	common	getsockopt		sys_getsockopt			sys_getsockopt
+183	common	sendmsg			sys_sendmsg			compat_sys_sendmsg
+184	common	recvmsg			sys_recvmsg			compat_sys_recvmsg
+185	common	semop			sys_semop
+186	common	semget			sys_semget
+187	common	semctl			sys_semctl			compat_sys_semctl
+188	common	msgsnd			sys_msgsnd			compat_sys_msgsnd
+189	common	msgrcv			sys_msgrcv			compat_sys_msgrcv
+190	common	msgget			sys_msgget
+191	common	msgctl			sys_msgctl			compat_sys_msgctl
+192	common	shmat			sys_shmat			compat_sys_shmat
+193	common	shmdt			sys_shmdt
+194	common	shmget			sys_shmget
+195	common	shmctl			sys_shmctl			compat_sys_shmctl
+# 196 was getpmsg
+# 197 was putpmsg
+198	common	lstat64			sys_lstat64
+199	32	truncate64		parisc_truncate64
+199	64	truncate64		sys_truncate64
+200	32	ftruncate64		parisc_ftruncate64
+200	64	ftruncate64		sys_ftruncate64
+201	common	getdents64		sys_getdents64
+202	common	fcntl64			sys_fcntl64			compat_sys_fcntl64
+# 203 was attrctl
+# 204 was acl_get
+# 205 was acl_set
+206	common	gettid			sys_gettid
+207	32	readahead		parisc_readahead
+207	64	readahead		sys_readahead
+208	common	tkill			sys_tkill
+209	common	sendfile64		sys_sendfile64			compat_sys_sendfile64
+210	32	futex			sys_futex_time32
+210	64	futex			sys_futex
+211	common	sched_setaffinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+212	common	sched_getaffinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+# 213 was set_thread_area
+# 214 was get_thread_area
+215	common	io_setup		sys_io_setup			compat_sys_io_setup
+216	common	io_destroy		sys_io_destroy
+217	32	io_getevents		sys_io_getevents_time32
+217	64	io_getevents		sys_io_getevents
+218	common	io_submit		sys_io_submit			compat_sys_io_submit
+219	common	io_cancel		sys_io_cancel
+# 220 was alloc_hugepages
+# 221 was free_hugepages
+222	common	exit_group		sys_exit_group
+223	common	lookup_dcookie		sys_ni_syscall
+224	common	epoll_create		sys_epoll_create
+225	common	epoll_ctl		sys_epoll_ctl
+226	common	epoll_wait		sys_epoll_wait
+227	common	remap_file_pages	sys_remap_file_pages
+228	32	semtimedop		sys_semtimedop_time32
+228	64	semtimedop		sys_semtimedop
+229	common	mq_open			sys_mq_open			compat_sys_mq_open
+230	common	mq_unlink		sys_mq_unlink
+231	32	mq_timedsend		sys_mq_timedsend_time32
+231	64	mq_timedsend		sys_mq_timedsend
+232	32	mq_timedreceive		sys_mq_timedreceive_time32
+232	64	mq_timedreceive		sys_mq_timedreceive
+233	common	mq_notify		sys_mq_notify			compat_sys_mq_notify
+234	common	mq_getsetattr		sys_mq_getsetattr		compat_sys_mq_getsetattr
+235	common	waitid			sys_waitid			compat_sys_waitid
+236	32	fadvise64_64		parisc_fadvise64_64
+236	64	fadvise64_64		sys_fadvise64_64
+237	common	set_tid_address		sys_set_tid_address
+238	common	setxattr		sys_setxattr
+239	common	lsetxattr		sys_lsetxattr
+240	common	fsetxattr		sys_fsetxattr
+241	common	getxattr		sys_getxattr
+242	common	lgetxattr		sys_lgetxattr
+243	common	fgetxattr		sys_fgetxattr
+244	common	listxattr		sys_listxattr
+245	common	llistxattr		sys_llistxattr
+246	common	flistxattr		sys_flistxattr
+247	common	removexattr		sys_removexattr
+248	common	lremovexattr		sys_lremovexattr
+249	common	fremovexattr		sys_fremovexattr
+250	common	timer_create		sys_timer_create		compat_sys_timer_create
+251	32	timer_settime		sys_timer_settime32
+251	64	timer_settime		sys_timer_settime
+252	32	timer_gettime		sys_timer_gettime32
+252	64	timer_gettime		sys_timer_gettime
+253	common	timer_getoverrun	sys_timer_getoverrun
+254	common	timer_delete		sys_timer_delete
+255	32	clock_settime		sys_clock_settime32
+255	64	clock_settime		sys_clock_settime
+256	32	clock_gettime		sys_clock_gettime32
+256	64	clock_gettime		sys_clock_gettime
+257	32	clock_getres		sys_clock_getres_time32
+257	64	clock_getres		sys_clock_getres
+258	32	clock_nanosleep		sys_clock_nanosleep_time32
+258	64	clock_nanosleep		sys_clock_nanosleep
+259	common	tgkill			sys_tgkill
+260	common	mbind			sys_mbind
+261	common	get_mempolicy		sys_get_mempolicy
+262	common	set_mempolicy		sys_set_mempolicy
+# 263 was vserver
+264	common	add_key			sys_add_key
+265	common	request_key		sys_request_key
+266	common	keyctl			sys_keyctl			compat_sys_keyctl
+267	common	ioprio_set		sys_ioprio_set
+268	common	ioprio_get		sys_ioprio_get
+269	common	inotify_init		sys_inotify_init
+270	common	inotify_add_watch	sys_inotify_add_watch
+271	common	inotify_rm_watch	sys_inotify_rm_watch
+272	common	migrate_pages		sys_migrate_pages
+273	32	pselect6		sys_pselect6_time32		compat_sys_pselect6_time32
+273	64	pselect6		sys_pselect6
+274	32	ppoll			sys_ppoll_time32		compat_sys_ppoll_time32
+274	64	ppoll			sys_ppoll
+275	common	openat			sys_openat			compat_sys_openat
+276	common	mkdirat			sys_mkdirat
+277	common	mknodat			sys_mknodat
+278	common	fchownat		sys_fchownat
+279	32	futimesat		sys_futimesat_time32
+279	64	futimesat		sys_futimesat
+280	common	fstatat64		sys_fstatat64
+281	common	unlinkat		sys_unlinkat
+282	common	renameat		sys_renameat
+283	common	linkat			sys_linkat
+284	common	symlinkat		sys_symlinkat
+285	common	readlinkat		sys_readlinkat
+286	common	fchmodat		sys_fchmodat
+287	common	faccessat		sys_faccessat
+288	common	unshare			sys_unshare
+289	common	set_robust_list		sys_set_robust_list		compat_sys_set_robust_list
+290	common	get_robust_list		sys_get_robust_list		compat_sys_get_robust_list
+291	common	splice			sys_splice
+292	32	sync_file_range		parisc_sync_file_range
+292	64	sync_file_range		sys_sync_file_range
+293	common	tee			sys_tee
+294	common	vmsplice		sys_vmsplice
+295	common	move_pages		sys_move_pages
+296	common	getcpu			sys_getcpu
+297	common	epoll_pwait		sys_epoll_pwait			compat_sys_epoll_pwait
+298	common	statfs64		sys_statfs64			compat_sys_statfs64
+299	common	fstatfs64		sys_fstatfs64			compat_sys_fstatfs64
+300	common	kexec_load		sys_kexec_load			compat_sys_kexec_load
+301	32	utimensat		sys_utimensat_time32
+301	64	utimensat		sys_utimensat
+302	common	signalfd		sys_signalfd			compat_sys_signalfd
+# 303 was timerfd
+304	common	eventfd			sys_eventfd
+305	32	fallocate		parisc_fallocate
+305	64	fallocate		sys_fallocate
+306	common	timerfd_create		parisc_timerfd_create
+307	32	timerfd_settime		sys_timerfd_settime32
+307	64	timerfd_settime		sys_timerfd_settime
+308	32	timerfd_gettime		sys_timerfd_gettime32
+308	64	timerfd_gettime		sys_timerfd_gettime
+309	common	signalfd4		parisc_signalfd4		parisc_compat_signalfd4
+310	common	eventfd2		parisc_eventfd2
+311	common	epoll_create1		sys_epoll_create1
+312	common	dup3			sys_dup3
+313	common	pipe2			parisc_pipe2
+314	common	inotify_init1		parisc_inotify_init1
+315	common	preadv	sys_preadv	compat_sys_preadv
+316	common	pwritev	sys_pwritev	compat_sys_pwritev
+317	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+318	common	perf_event_open		sys_perf_event_open
+319	32	recvmmsg		sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+319	64	recvmmsg		sys_recvmmsg
+320	common	accept4			sys_accept4
+321	common	prlimit64		sys_prlimit64
+322	common	fanotify_init		sys_fanotify_init
+323	common	fanotify_mark		sys_fanotify_mark		compat_sys_fanotify_mark
+324	32	clock_adjtime		sys_clock_adjtime32
+324	64	clock_adjtime		sys_clock_adjtime
+325	common	name_to_handle_at	sys_name_to_handle_at
+326	common	open_by_handle_at	sys_open_by_handle_at		compat_sys_open_by_handle_at
+327	common	syncfs			sys_syncfs
+328	common	setns			sys_setns
+329	common	sendmmsg		sys_sendmmsg			compat_sys_sendmmsg
+330	common	process_vm_readv	sys_process_vm_readv
+331	common	process_vm_writev	sys_process_vm_writev
+332	common	kcmp			sys_kcmp
+333	common	finit_module		sys_finit_module
+334	common	sched_setattr		sys_sched_setattr
+335	common	sched_getattr		sys_sched_getattr
+336	32	utimes			sys_utimes_time32
+336	64	utimes			sys_utimes
+337	common	renameat2		sys_renameat2
+338	common	seccomp			sys_seccomp
+339	common	getrandom		sys_getrandom
+340	common	memfd_create		sys_memfd_create
+341	common	bpf			sys_bpf
+342	common	execveat		sys_execveat			compat_sys_execveat
+343	common	membarrier		sys_membarrier
+344	common	userfaultfd		parisc_userfaultfd
+345	common	mlock2			sys_mlock2
+346	common	copy_file_range		sys_copy_file_range
+347	common	preadv2			sys_preadv2			compat_sys_preadv2
+348	common	pwritev2		sys_pwritev2			compat_sys_pwritev2
+349	common	statx			sys_statx
+350	32	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+350	64	io_pgetevents		sys_io_pgetevents
+351	common	pkey_mprotect		sys_pkey_mprotect
+352	common	pkey_alloc		sys_pkey_alloc
+353	common	pkey_free		sys_pkey_free
+354	common	rseq			sys_rseq
+355	common	kexec_file_load		sys_kexec_file_load		sys_kexec_file_load
+356	common	cacheflush		sys_cacheflush
+# up to 402 is unassigned and reserved for arch specific syscalls
+403	32	clock_gettime64			sys_clock_gettime		sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime		sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime		sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime		sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime		sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat			sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop			sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3_wrapper
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/parisc/include/syscall_table.h b/tools/perf/arch/parisc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/parisc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index a821df1fd4c0e78c9706304e5b8974cbc5ef4437..ae9f00ae79f34fec75ef2c91300ccd771c030529 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -207,6 +207,7 @@ check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/sy
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
+check_2 tools/perf/arch/parisc/entry/syscalls/syscall.tbl arch/parisc/entry/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:56 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:56 -0800
Subject: [PATCH v3 11/16] perf tools: arm64: Use syscall table
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-11-239f032481d5@rivosinc.com>

arm64 uses a syscall table, use that in perf instead of using unistd.h.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   3 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/arm64/Makefile                     |  22 -
 tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
 .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
 .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++++
 .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
 tools/perf/arch/arm64/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   2 +
 tools/perf/util/syscalltbl.c                       |   4 -
 11 files changed, 498 insertions(+), 75 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 218c407c953f8526ea995cc5126a94654ebbae11..1865be464221a4101c0de65942c2b719c2a50e37 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips loongarch))
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -71,7 +71,6 @@ ifeq ($(SRCARCH),arm)
 endif
 
 ifeq ($(SRCARCH),arm64)
-  CFLAGS += -I$(OUTPUT)arch/arm64/include/generated
   LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
 endif
 
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c4bd151fb7e4fb14a53998e58afae37599696da3..bedf58d2a10f1faccb3579c023d5722cfeaae4cf 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
index 91570d5d428e401d940e1c31332ebb40c4b998d8..087e099fb453a9236db34878077a51f711881ce0 100644
--- a/tools/perf/arch/arm64/Makefile
+++ b/tools/perf/arch/arm64/Makefile
@@ -1,25 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/arm64/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/arm64/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, arm64) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/arm64/entry/syscalls/Kbuild b/tools/perf/arch/arm64/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..e7e78c2d1c025b6954a1a22d44a744012e1ca3d4
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 +=
+syscall_abis_64 += renameat rlimit memfd_secret
+
+syscalltbl = $(srctree)/tools/perf/arch/arm64/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 27d747c92d44c04f26ce7aef766a50e3f896f5ff..0000000000000000000000000000000000000000
--- a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-# Changed by: Kim Phillips <kim.phillips at arm.com>
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_ARM64_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_arm64[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl b/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..9a37930d4e26f0c6cb8fe78f76bb1a4f32cbea16
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl
@@ -0,0 +1,476 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# AArch32 (compat) system call definitions.
+#
+# Copyright (C) 2001-2005 Russell King
+# Copyright (C) 2012 ARM Ltd.
+#
+# This file corresponds to arch/arm/tools/syscall.tbl
+# for the native EABI syscalls and should be kept in sync
+# Instead of the OABI syscalls, it contains pointers to
+# the compat entry points where they differ from the native
+# syscalls.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open		compat_sys_open
+6	common	close			sys_close
+# 7 was sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve		compat_sys_execve
+12	common	chdir			sys_chdir
+# 13 was sys_time
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19	common	lseek			sys_lseek		compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+# 22 was sys_umount
+23	common	setuid			sys_setuid16
+24	common	getuid			sys_getuid16
+# 25 was sys_stime
+26	common	ptrace			sys_ptrace		compat_sys_ptrace
+# 27 was sys_alarm
+# 28 was sys_fstat
+29	common	pause			sys_pause
+# 30 was sys_utime
+# 31 was sys_stty
+# 32 was sys_gtty
+33	common	access			sys_access
+34	common	nice			sys_nice
+# 35 was sys_ftime
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times		compat_sys_times
+# 44 was sys_prof
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid16
+47	common	getgid			sys_getgid16
+# 48 was sys_signal
+49	common	geteuid			sys_geteuid16
+50	common	getegid			sys_getegid16
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+# 53 was sys_lock
+54	common	ioctl			sys_ioctl		compat_sys_ioctl
+55	common	fcntl			sys_fcntl		compat_sys_fcntl
+# 56 was sys_mpx
+57	common	setpgid			sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat		compat_sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	sigaction		sys_sigaction		compat_sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70	common	setreuid		sys_setreuid16
+71	common	setregid		sys_setregid16
+72	common	sigsuspend		sys_sigsuspend
+73	common	sigpending		sys_sigpending		compat_sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit		compat_sys_setrlimit
+# 76 was compat_sys_getrlimit
+77	common	getrusage		sys_getrusage		compat_sys_getrusage
+78	common	gettimeofday		sys_gettimeofday	compat_sys_gettimeofday
+79	common	settimeofday		sys_settimeofday	compat_sys_settimeofday
+80	common	getgroups		sys_getgroups16
+81	common	setgroups		sys_setgroups16
+# 82 was compat_sys_select
+83	common	symlink			sys_symlink
+# 84 was sys_lstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_uselib
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+# 89 was sys_readdir
+# 90 was sys_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate		compat_sys_truncate
+93	common	ftruncate		sys_ftruncate		compat_sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown16
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+# 98 was sys_profil
+99	common	statfs			sys_statfs		compat_sys_statfs
+100	common	fstatfs			sys_fstatfs		compat_sys_fstatfs
+# 101 was sys_ioperm
+# 102 was sys_socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer		compat_sys_setitimer
+105	common	getitimer		sys_getitimer		compat_sys_getitimer
+106	common	stat			sys_newstat		compat_sys_newstat
+107	common	lstat			sys_newlstat		compat_sys_newlstat
+108	common	fstat			sys_newfstat		compat_sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111	common	vhangup			sys_vhangup
+# 112 was sys_idle
+# 113 was sys_syscall
+114	common	wait4			sys_wait4		compat_sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo		compat_sys_sysinfo
+# 117 was sys_ipc
+118	common	fsync			sys_fsync
+119	common	sigreturn		sys_sigreturn_wrapper	compat_sys_sigreturn
+120	common	clone			sys_clone
+121	common	setdomainname		sys_setdomainname
+122	common	uname			sys_newuname
+# 123 was sys_modify_ldt
+124	common	adjtimex		sys_adjtimex_time32
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask		compat_sys_sigprocmask
+# 127 was sys_create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was sys_get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	common	personality		sys_personality
+# 137 was sys_afs_syscall
+138	common	setfsuid		sys_setfsuid16
+139	common	setfsgid		sys_setfsgid16
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents		compat_sys_getdents
+142	common	_newselect		sys_select		compat_sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	common	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+162	common	nanosleep		sys_nanosleep_time32
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid16
+165	common	getresuid		sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168	common	poll			sys_poll
+169	common	nfsservctl		sys_ni_syscall
+170	common	setresgid		sys_setresgid16
+171	common	getresgid		sys_getresgid16
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper	compat_sys_rt_sigreturn
+174	common	rt_sigaction		sys_rt_sigaction	compat_sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask	compat_sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending	compat_sys_rt_sigpending
+177	common	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo	compat_sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend	compat_sys_rt_sigsuspend
+180	common	pread64			sys_pread64		compat_sys_aarch32_pread64
+181	common	pwrite64		sys_pwrite64		compat_sys_aarch32_pwrite64
+182	common	chown			sys_chown16
+183	common	getcwd			sys_getcwd
+184	common	capget			sys_capget
+185	common	capset			sys_capset
+186	common	sigaltstack		sys_sigaltstack		compat_sys_sigaltstack
+187	common	sendfile		sys_sendfile		compat_sys_sendfile
+# 188 reserved
+# 189 reserved
+190	common	vfork			sys_vfork
+# SuS compliant getrlimit
+191	common	ugetrlimit		sys_getrlimit		compat_sys_getrlimit
+192	common	mmap2			sys_mmap2		compat_sys_aarch32_mmap2
+193	common	truncate64		sys_truncate64		compat_sys_aarch32_truncate64
+194	common	ftruncate64		sys_ftruncate64		compat_sys_aarch32_ftruncate64
+195	common	stat64			sys_stat64
+196	common	lstat64			sys_lstat64
+197	common	fstat64			sys_fstat64
+198	common	lchown32		sys_lchown
+199	common	getuid32		sys_getuid
+200	common	getgid32		sys_getgid
+201	common	geteuid32		sys_geteuid
+202	common	getegid32		sys_getegid
+203	common	setreuid32		sys_setreuid
+204	common	setregid32		sys_setregid
+205	common	getgroups32		sys_getgroups
+206	common	setgroups32		sys_setgroups
+207	common	fchown32		sys_fchown
+208	common	setresuid32		sys_setresuid
+209	common	getresuid32		sys_getresuid
+210	common	setresgid32		sys_setresgid
+211	common	getresgid32		sys_getresgid
+212	common	chown32			sys_chown
+213	common	setuid32		sys_setuid
+214	common	setgid32		sys_setgid
+215	common	setfsuid32		sys_setfsuid
+216	common	setfsgid32		sys_setfsgid
+217	common	getdents64		sys_getdents64
+218	common	pivot_root		sys_pivot_root
+219	common	mincore			sys_mincore
+220	common	madvise			sys_madvise
+221	common	fcntl64			sys_fcntl64		compat_sys_fcntl64
+# 222 for tux
+# 223 is unused
+224	common	gettid			sys_gettid
+225	common	readahead		sys_readahead		compat_sys_aarch32_readahead
+226	common	setxattr		sys_setxattr
+227	common	lsetxattr		sys_lsetxattr
+228	common	fsetxattr		sys_fsetxattr
+229	common	getxattr		sys_getxattr
+230	common	lgetxattr		sys_lgetxattr
+231	common	fgetxattr		sys_fgetxattr
+232	common	listxattr		sys_listxattr
+233	common	llistxattr		sys_llistxattr
+234	common	flistxattr		sys_flistxattr
+235	common	removexattr		sys_removexattr
+236	common	lremovexattr		sys_lremovexattr
+237	common	fremovexattr		sys_fremovexattr
+238	common	tkill			sys_tkill
+239	common	sendfile64		sys_sendfile64
+240	common	futex			sys_futex_time32
+241	common	sched_setaffinity	sys_sched_setaffinity	compat_sys_sched_setaffinity
+242	common	sched_getaffinity	sys_sched_getaffinity	compat_sys_sched_getaffinity
+243	common	io_setup		sys_io_setup		compat_sys_io_setup
+244	common	io_destroy		sys_io_destroy
+245	common	io_getevents		sys_io_getevents_time32
+246	common	io_submit		sys_io_submit		compat_sys_io_submit
+247	common	io_cancel		sys_io_cancel
+248	common	exit_group		sys_exit_group
+249	common	lookup_dcookie		sys_ni_syscall
+250	common	epoll_create		sys_epoll_create
+251	common	epoll_ctl		sys_epoll_ctl
+252	common	epoll_wait		sys_epoll_wait
+253	common	remap_file_pages	sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256	common	set_tid_address		sys_set_tid_address
+257	common	timer_create		sys_timer_create	compat_sys_timer_create
+258	common	timer_settime		sys_timer_settime32
+259	common	timer_gettime		sys_timer_gettime32
+260	common	timer_getoverrun	sys_timer_getoverrun
+261	common	timer_delete		sys_timer_delete
+262	common	clock_settime		sys_clock_settime32
+263	common	clock_gettime		sys_clock_gettime32
+264	common	clock_getres		sys_clock_getres_time32
+265	common	clock_nanosleep		sys_clock_nanosleep_time32
+266	common	statfs64		sys_statfs64_wrapper	compat_sys_aarch32_statfs64
+267	common	fstatfs64		sys_fstatfs64_wrapper	compat_sys_aarch32_fstatfs64
+268	common	tgkill			sys_tgkill
+269	common	utimes			sys_utimes_time32
+270	common	arm_fadvise64_64	sys_arm_fadvise64_64	compat_sys_aarch32_fadvise64_64
+271	common	pciconfig_iobase	sys_pciconfig_iobase
+272	common	pciconfig_read		sys_pciconfig_read
+273	common	pciconfig_write		sys_pciconfig_write
+274	common	mq_open			sys_mq_open		compat_sys_mq_open
+275	common	mq_unlink		sys_mq_unlink
+276	common	mq_timedsend		sys_mq_timedsend_time32
+277	common	mq_timedreceive		sys_mq_timedreceive_time32
+278	common	mq_notify		sys_mq_notify		compat_sys_mq_notify
+279	common	mq_getsetattr		sys_mq_getsetattr	compat_sys_mq_getsetattr
+280	common	waitid			sys_waitid		compat_sys_waitid
+281	common	socket			sys_socket
+282	common	bind			sys_bind
+283	common	connect			sys_connect
+284	common	listen			sys_listen
+285	common	accept			sys_accept
+286	common	getsockname		sys_getsockname
+287	common	getpeername		sys_getpeername
+288	common	socketpair		sys_socketpair
+289	common	send			sys_send
+290	common	sendto			sys_sendto
+291	common	recv			sys_recv		compat_sys_recv
+292	common	recvfrom		sys_recvfrom		compat_sys_recvfrom
+293	common	shutdown		sys_shutdown
+294	common	setsockopt		sys_setsockopt
+295	common	getsockopt		sys_getsockopt
+296	common	sendmsg			sys_sendmsg		compat_sys_sendmsg
+297	common	recvmsg			sys_recvmsg		compat_sys_recvmsg
+298	common	semop			sys_semop
+299	common	semget			sys_semget
+300	common	semctl			sys_old_semctl		compat_sys_old_semctl
+301	common	msgsnd			sys_msgsnd		compat_sys_msgsnd
+302	common	msgrcv			sys_msgrcv		compat_sys_msgrcv
+303	common	msgget			sys_msgget
+304	common	msgctl			sys_old_msgctl		compat_sys_old_msgctl
+305	common	shmat			sys_shmat		compat_sys_shmat
+306	common	shmdt			sys_shmdt
+307	common	shmget			sys_shmget
+308	common	shmctl			sys_old_shmctl		compat_sys_old_shmctl
+309	common	add_key			sys_add_key
+310	common	request_key		sys_request_key
+311	common	keyctl			sys_keyctl		compat_sys_keyctl
+312	common	semtimedop		sys_semtimedop_time32
+313	common	vserver			sys_ni_syscall
+314	common	ioprio_set		sys_ioprio_set
+315	common	ioprio_get		sys_ioprio_get
+316	common	inotify_init		sys_inotify_init
+317	common	inotify_add_watch	sys_inotify_add_watch
+318	common	inotify_rm_watch	sys_inotify_rm_watch
+319	common	mbind			sys_mbind
+320	common	get_mempolicy		sys_get_mempolicy
+321	common	set_mempolicy		sys_set_mempolicy
+322	common	openat			sys_openat		compat_sys_openat
+323	common	mkdirat			sys_mkdirat
+324	common	mknodat			sys_mknodat
+325	common	fchownat		sys_fchownat
+326	common	futimesat		sys_futimesat_time32
+327	common	fstatat64		sys_fstatat64
+328	common	unlinkat		sys_unlinkat
+329	common	renameat		sys_renameat
+330	common	linkat			sys_linkat
+331	common	symlinkat		sys_symlinkat
+332	common	readlinkat		sys_readlinkat
+333	common	fchmodat		sys_fchmodat
+334	common	faccessat		sys_faccessat
+335	common	pselect6		sys_pselect6_time32	compat_sys_pselect6_time32
+336	common	ppoll			sys_ppoll_time32	compat_sys_ppoll_time32
+337	common	unshare			sys_unshare
+338	common	set_robust_list		sys_set_robust_list	compat_sys_set_robust_list
+339	common	get_robust_list		sys_get_robust_list	compat_sys_get_robust_list
+340	common	splice			sys_splice
+341	common	arm_sync_file_range	sys_sync_file_range2	compat_sys_aarch32_sync_file_range2
+342	common	tee			sys_tee
+343	common	vmsplice		sys_vmsplice
+344	common	move_pages		sys_move_pages
+345	common	getcpu			sys_getcpu
+346	common	epoll_pwait		sys_epoll_pwait		compat_sys_epoll_pwait
+347	common	kexec_load		sys_kexec_load		compat_sys_kexec_load
+348	common	utimensat		sys_utimensat_time32
+349	common	signalfd		sys_signalfd		compat_sys_signalfd
+350	common	timerfd_create		sys_timerfd_create
+351	common	eventfd			sys_eventfd
+352	common	fallocate		sys_fallocate		compat_sys_aarch32_fallocate
+353	common	timerfd_settime		sys_timerfd_settime32
+354	common	timerfd_gettime		sys_timerfd_gettime32
+355	common	signalfd4		sys_signalfd4		compat_sys_signalfd4
+356	common	eventfd2		sys_eventfd2
+357	common	epoll_create1		sys_epoll_create1
+358	common	dup3			sys_dup3
+359	common	pipe2			sys_pipe2
+360	common	inotify_init1		sys_inotify_init1
+361	common	preadv			sys_preadv		compat_sys_preadv
+362	common	pwritev			sys_pwritev		compat_sys_pwritev
+363	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo	compat_sys_rt_tgsigqueueinfo
+364	common	perf_event_open		sys_perf_event_open
+365	common	recvmmsg		sys_recvmmsg_time32	compat_sys_recvmmsg_time32
+366	common	accept4			sys_accept4
+367	common	fanotify_init		sys_fanotify_init
+368	common	fanotify_mark		sys_fanotify_mark	compat_sys_fanotify_mark
+369	common	prlimit64		sys_prlimit64
+370	common	name_to_handle_at	sys_name_to_handle_at
+371	common	open_by_handle_at	sys_open_by_handle_at	compat_sys_open_by_handle_at
+372	common	clock_adjtime		sys_clock_adjtime32
+373	common	syncfs			sys_syncfs
+374	common	sendmmsg		sys_sendmmsg		compat_sys_sendmmsg
+375	common	setns			sys_setns
+376	common	process_vm_readv	sys_process_vm_readv
+377	common	process_vm_writev	sys_process_vm_writev
+378	common	kcmp			sys_kcmp
+379	common	finit_module		sys_finit_module
+380	common	sched_setattr		sys_sched_setattr
+381	common	sched_getattr		sys_sched_getattr
+382	common	renameat2		sys_renameat2
+383	common	seccomp			sys_seccomp
+384	common	getrandom		sys_getrandom
+385	common	memfd_create		sys_memfd_create
+386	common	bpf			sys_bpf
+387	common	execveat		sys_execveat		compat_sys_execveat
+388	common	userfaultfd		sys_userfaultfd
+389	common	membarrier		sys_membarrier
+390	common	mlock2			sys_mlock2
+391	common	copy_file_range		sys_copy_file_range
+392	common	preadv2			sys_preadv2		compat_sys_preadv2
+393	common	pwritev2		sys_pwritev2		compat_sys_pwritev2
+394	common	pkey_mprotect		sys_pkey_mprotect
+395	common	pkey_alloc		sys_pkey_alloc
+396	common	pkey_free		sys_pkey_free
+397	common	statx			sys_statx
+398	common	rseq			sys_rseq
+399	common	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+400	common	migrate_pages		sys_migrate_pages
+401	common	kexec_file_load		sys_kexec_file_load
+# 402 is unused
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	common	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	common	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	common	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl b/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl
new file mode 120000
index 0000000000000000000000000000000000000000..4fdd58f10c155ee45b8d4f6ab1ca4e36ea677c75
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl
@@ -0,0 +1 @@
+../../../../../scripts/syscall.tbl
\ No newline at end of file
diff --git a/tools/perf/arch/arm64/include/syscall_table.h b/tools/perf/arch/arm64/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/arm64/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index ae9f00ae79f34fec75ef2c91300ccd771c030529..d3c6e10dce73f122cfbaa6ca75ea82bec38c6a16 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -208,6 +208,8 @@ check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/sysca
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
 check_2 tools/perf/arch/parisc/entry/syscalls/syscall.tbl arch/parisc/entry/syscalls/syscall.tbl
+check_2 tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl arch/arm64/entry/syscalls/syscall_32.tbl
+check_2 tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl arch/arm64/entry/syscalls/syscall_64.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 02f23483bfff83809c4e649a2d054dba6975d12c..b7c0a4b9245a94b3b245fea59af79081b1f91081 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -26,10 +26,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
 #include <asm/syscalls_32.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
-#elif defined(__aarch64__)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_arm64;
 #elif defined(__mips__)
 #include <asm/syscalls_n64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:57 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:57 -0800
Subject: [PATCH v3 12/16] perf tools: loongarch: Use syscall table
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-12-239f032481d5@rivosinc.com>

loongarch uses a syscall table, use that in perf instead of using unistd.h.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  3 +-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/loongarch/Makefile                 | 22 -----------
 tools/perf/arch/loongarch/entry/syscalls/Kbuild    |  2 +
 .../loongarch/entry/syscalls/Makefile.syscalls     |  3 ++
 .../arch/loongarch/entry/syscalls/mksyscalltbl     | 45 ----------------------
 tools/perf/arch/loongarch/include/syscall_table.h  |  2 +
 tools/perf/util/syscalltbl.c                       |  4 --
 8 files changed, 9 insertions(+), 74 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 1865be464221a4101c0de65942c2b719c2a50e37..d5e1bd03ae0f9d10df2da25a75eab50eb7334b45 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips))
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -75,7 +75,6 @@ ifeq ($(SRCARCH),arm64)
 endif
 
 ifeq ($(SRCARCH),loongarch)
-  CFLAGS += -I$(OUTPUT)arch/loongarch/include/generated
   LIBUNWIND_LIBS = -lunwind -lunwind-loongarch64
 endif
 
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index bedf58d2a10f1faccb3579c023d5722cfeaae4cf..c85262db770d18828fc3d9dc65eca00733645d41 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/loongarch/Makefile b/tools/perf/arch/loongarch/Makefile
index 52544d59245bab5a0fb2baa1e962b2ad4bf25332..087e099fb453a9236db34878077a51f711881ce0 100644
--- a/tools/perf/arch/loongarch/Makefile
+++ b/tools/perf/arch/loongarch/Makefile
@@ -1,25 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/loongarch/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/loongarch/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/loongarch/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, loongarch) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Kbuild b/tools/perf/arch/loongarch/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/loongarch/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls b/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..47d32da2aed8d67a7ac026271600e84723031a6b
--- /dev/null
+++ b/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 +=
diff --git a/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl b/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
deleted file mode 100755
index c10ad3580aef25e48ff0682eca4217cbafdfa333..0000000000000000000000000000000000000000
--- a/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Author(s):  Ming Wang <wangming01 at loongson.cn>
-# Author(s):  Huacai Chen <chenhuacai at loongson.cn>
-# Copyright (C) 2020-2023 Loongson Technology Corporation Limited
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_LOONGARCH_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_loongarch[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/loongarch/include/syscall_table.h b/tools/perf/arch/loongarch/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d0646d3455cdaf1a3db8c8565af8eba9a8df8c6
--- /dev/null
+++ b/tools/perf/arch/loongarch/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscall_table_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index b7c0a4b9245a94b3b245fea59af79081b1f91081..3001386e13a502be5279aa6e4742af0b96202b35 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -30,10 +30,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
 #include <asm/syscalls_n64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_mips_n64;
-#elif defined(__loongarch__)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_loongarch;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:58 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:58 -0800
Subject: [PATCH v3 13/16] perf tools: mips: Use generic syscall scripts
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-13-239f032481d5@rivosinc.com>

Use the generic scripts to generate headers from the syscall table for
mips.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  3 +-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/mips/entry/syscalls/Kbuild         |  2 ++
 .../arch/mips/entry/syscalls/Makefile.syscalls     |  5 ++++
 tools/perf/arch/mips/entry/syscalls/mksyscalltbl   | 32 ----------------------
 tools/perf/arch/mips/include/syscall_table.h       |  2 ++
 tools/perf/util/syscalltbl.c                       |  4 ---
 7 files changed, 11 insertions(+), 39 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index d5e1bd03ae0f9d10df2da25a75eab50eb7334b45..ec2902e8f5f9baf6bed9946a9c7315527b23b8fb 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390))
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -83,7 +83,6 @@ ifeq ($(ARCH),s390)
 endif
 
 ifeq ($(ARCH),mips)
-  CFLAGS += -I$(OUTPUT)arch/mips/include/generated
   LIBUNWIND_LIBS = -lunwind -lunwind-mips
 endif
 
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c85262db770d18828fc3d9dc65eca00733645d41..74c1097f790cba5abfd1f2fbdaf4e7540c553482 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/mips/entry/syscalls/Kbuild b/tools/perf/arch/mips/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/mips/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls b/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..9ee914bdfb05860fdd37a49f1ced03fcf2c9ed78
--- /dev/null
+++ b/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 += n64
+
+syscalltbl = $(srctree)/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
diff --git a/tools/perf/arch/mips/entry/syscalls/mksyscalltbl b/tools/perf/arch/mips/entry/syscalls/mksyscalltbl
deleted file mode 100644
index c0d93f959c4e1b8c12edcb5624bbc131231df7e3..0000000000000000000000000000000000000000
--- a/tools/perf/arch/mips/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# s390 script.
-#
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Tiezhu Yang <yangtiezhu at loongson.cn>
-
-SYSCALL_TBL=$1
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local max_nr nr abi sc discard
-
-	echo 'static const char *const syscalltbl_mips_n64[] = {'
-	while read nr abi sc discard; do
-		printf '\t[%d] = "%s",\n' $nr $sc
-		max_nr=$nr
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_MIPS_N64_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(n64)" $SYSCALL_TBL	\
-	|sort -k1 -n					\
-	|create_table
diff --git a/tools/perf/arch/mips/include/syscall_table.h b/tools/perf/arch/mips/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..b53e31c15805319a01719c22d489c4037378b02b
--- /dev/null
+++ b/tools/perf/arch/mips/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 3001386e13a502be5279aa6e4742af0b96202b35..675702d686d0d1b53dd3ee2017cc9695686b9c63 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -26,10 +26,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
 #include <asm/syscalls_32.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
-#elif defined(__mips__)
-#include <asm/syscalls_n64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_mips_n64;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:32:59 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:32:59 -0800
Subject: [PATCH v3 14/16] perf tools: powerpc: Use generic syscall table
 scripts
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-14-239f032481d5@rivosinc.com>

Use the generic scripts to generate headers from the syscall table
instead of the custom ones for powerpc.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  3 +-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/powerpc/Makefile                   | 25 --------------
 tools/perf/arch/powerpc/entry/syscalls/Kbuild      |  3 ++
 .../arch/powerpc/entry/syscalls/Makefile.syscalls  |  6 ++++
 .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  | 39 ----------------------
 tools/perf/arch/powerpc/include/syscall_table.h    |  8 +++++
 tools/perf/util/syscalltbl.c                       |  8 -----
 8 files changed, 19 insertions(+), 75 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index ec2902e8f5f9baf6bed9946a9c7315527b23b8fb..de7cd12a885f60dc182bfb39493672f884adbacb 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390))
+  ifeq ($(SRCARCH),s390)
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -49,7 +49,6 @@ endif
 
 # Additional ARCH settings for ppc
 ifeq ($(SRCARCH),powerpc)
-  CFLAGS += -I$(OUTPUT)arch/powerpc/include/generated
   LIBUNWIND_LIBS := -lunwind -lunwind-ppc64
 endif
 
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 74c1097f790cba5abfd1f2fbdaf4e7540c553482..f76b23d96fc91aa56807fc581bf820a117c2bda0 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index dc8f4fb8e324ab6679d78b5fee3636ba7d2ff7c0..a295a80ea078199547e816d18531820bfdba7961 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -1,28 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/powerpc/include/generated/asm
-header32 := $(out)/syscalls_32.c
-header64 := $(out)/syscalls_64.c
-sysprf := $(srctree)/tools/perf/arch/powerpc/entry/syscalls
-sysdef := $(sysprf)/syscall.tbl
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header64): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '64' $(sysdef) > $@
-
-$(header32): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '32' $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, powerpc) $(RM) $(header32) $(header64)
-
-archheaders: $(header32) $(header64)
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Kbuild b/tools/perf/arch/powerpc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/powerpc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..f7e87a61401c14a1d3a8a04fe2c8ecc8bedcc1b0
--- /dev/null
+++ b/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += spu nospu
+syscall_abis_64 += spu nospu
+
+syscalltbl = $(srctree)/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl b/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 0eb316fe6dd1175a86035f76f9f3cf7501c376bd..0000000000000000000000000000000000000000
--- a/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# s390 script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-
-wordsize=$1
-SYSCALL_TBL=$2
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local wordsize=$1
-	local max_nr nr abi sc discard
-	max_nr=-1
-	nr=0
-
-	echo "static const char *const syscalltbl_powerpc_${wordsize}[] = {"
-	while read nr abi sc discard; do
-		if [ "$max_nr" -lt "$nr" ]; then
-			printf '\t[%d] = "%s",\n' $nr $sc
-			max_nr=$nr
-		fi
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_POWERPC_${wordsize}_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(common|spu|nospu|${wordsize})" $SYSCALL_TBL \
-	|sort -k1 -n                                                           \
-	|create_table ${wordsize}
diff --git a/tools/perf/arch/powerpc/include/syscall_table.h b/tools/perf/arch/powerpc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/powerpc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 675702d686d0d1b53dd3ee2017cc9695686b9c63..8869fed1a58946c590484816354d8c74aff52ee3 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -18,14 +18,6 @@
 #include <asm/syscalls_64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_s390_64;
-#elif defined(__powerpc64__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
-#elif defined(__powerpc__)
-#include <asm/syscalls_32.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:33:00 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:33:00 -0800
Subject: [PATCH v3 15/16] perf tools: s390: Use generic syscall table
 scripts
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-15-239f032481d5@rivosinc.com>

Use the generic scripts to generate headers from the syscall table
instead of the custom ones for s390.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  6 +---
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/s390/Makefile                      | 21 --------------
 tools/perf/arch/s390/entry/syscalls/Kbuild         |  2 ++
 .../arch/s390/entry/syscalls/Makefile.syscalls     |  5 ++++
 tools/perf/arch/s390/entry/syscalls/mksyscalltbl   | 32 ----------------------
 tools/perf/arch/s390/include/syscall_table.h       |  2 ++
 tools/perf/util/syscalltbl.c                       |  6 +---
 8 files changed, 12 insertions(+), 64 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index de7cd12a885f60dc182bfb39493672f884adbacb..3f82ba907381049213c055ab10c3fe14d9572073 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,10 +31,6 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),s390)
-    NO_SYSCALL_TABLE := 0
-  endif
-
   # architectures that use the generic syscall table scripts
   ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
     NO_SYSCALL_TABLE := 0
@@ -78,7 +74,7 @@ ifeq ($(SRCARCH),loongarch)
 endif
 
 ifeq ($(ARCH),s390)
-  CFLAGS += -fPIC -I$(OUTPUT)arch/s390/include/generated
+  CFLAGS += -fPIC
 endif
 
 ifeq ($(ARCH),mips)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f76b23d96fc91aa56807fc581bf820a117c2bda0..2c6a509c800d3037933c9b49e5a7dafbf78fda0c 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
index c431c21b11ef824535c1b9fb6ca4246d666fc97b..0033698a65ce5d5d7ebcc280399957561dd9d2c6 100644
--- a/tools/perf/arch/s390/Makefile
+++ b/tools/perf/arch/s390/Makefile
@@ -1,24 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/s390/include/generated/asm
-header := $(out)/syscalls_64.c
-sysprf := $(srctree)/tools/perf/arch/s390/entry/syscalls
-sysdef := $(sysprf)/syscall.tbl
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, s390) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/s390/entry/syscalls/Kbuild b/tools/perf/arch/s390/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/s390/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls b/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..9762d7abf17c3f79a6213e7306a5f7b56e833a78
--- /dev/null
+++ b/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 += renameat rlimit memfd_secret
+
+syscalltbl = $(srctree)/tools/perf/arch/s390/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl b/tools/perf/arch/s390/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 52eb88a77c94727aeb8c15427cdd43dfe5f9f2bd..0000000000000000000000000000000000000000
--- a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf
-#
-# Copyright IBM Corp. 2017, 2018
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-#
-
-SYSCALL_TBL=$1
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local max_nr nr abi sc discard
-
-	echo 'static const char *const syscalltbl_s390_64[] = {'
-	while read nr abi sc discard; do
-		printf '\t[%d] = "%s",\n' $nr $sc
-		max_nr=$nr
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_S390_64_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(common|64)" $SYSCALL_TBL	\
-	|sort -k1 -n					\
-	|create_table
diff --git a/tools/perf/arch/s390/include/syscall_table.h b/tools/perf/arch/s390/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..b53e31c15805319a01719c22d489c4037378b02b
--- /dev/null
+++ b/tools/perf/arch/s390/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 8869fed1a58946c590484816354d8c74aff52ee3..210f61b0a7a264a427ebb602185d3a9da2f426f4 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -14,11 +14,7 @@
 #include <string.h>
 #include "string2.h"
 
-#if defined(__s390x__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_s390_64;
-#elif defined(GENERIC_SYSCALL_TABLE)
+#if defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl;

-- 
2.34.1



From charlie at rivosinc.com  Mon Dec 16 22:33:01 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 16 Dec 2024 22:33:01 -0800
Subject: [PATCH v3 16/16] perf tools: Remove dependency on libaudit
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <20241216-perf_syscalltbl-v3-16-239f032481d5@rivosinc.com>

All architectures now support HAVE_SYSCALL_TABLE_SUPPORT, so the flag is
no longer needed. With the removal of the flag, the related
GENERIC_SYSCALL_TABLE can also be removed. libaudit was only used as a
fallback for when HAVE_SYSCALL_TABLE_SUPPORT was not defined, so
libaudit is also no longer needed for any architecture.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 Documentation/admin-guide/workload-tracing.rst |  2 +-
 tools/build/feature/Makefile                   |  4 --
 tools/build/feature/test-libaudit.c            | 11 ------
 tools/perf/Documentation/perf-check.txt        |  1 -
 tools/perf/Makefile.config                     | 31 +--------------
 tools/perf/Makefile.perf                       | 15 --------
 tools/perf/builtin-check.c                     |  1 -
 tools/perf/builtin-help.c                      |  2 -
 tools/perf/builtin-trace.c                     | 30 ---------------
 tools/perf/perf.c                              |  6 +--
 tools/perf/tests/make                          |  7 +---
 tools/perf/util/env.c                          |  4 +-
 tools/perf/util/generate-cmdlist.sh            |  4 +-
 tools/perf/util/syscalltbl.c                   | 52 --------------------------
 14 files changed, 10 insertions(+), 160 deletions(-)

diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
index b2e254ec8ee846afe78eede74a825b51c6ab119b..6be38c1b9c5bb4be899fd261c6d2911abcf959dc 100644
--- a/Documentation/admin-guide/workload-tracing.rst
+++ b/Documentation/admin-guide/workload-tracing.rst
@@ -83,7 +83,7 @@ scripts/ver_linux is a good way to check if your system already has
 the necessary tools::
 
   sudo apt-get build-essentials flex bison yacc
-  sudo apt install libelf-dev systemtap-sdt-dev libaudit-dev libslang2-dev libperl-dev libdw-dev
+  sudo apt install libelf-dev systemtap-sdt-dev libslang2-dev libperl-dev libdw-dev
 
 cscope is a good tool to browse kernel sources. Let's install it now::
 
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 043dfd00fce72d8f651ccd9b3265a0183f500e5c..e0b63e9d0251abe6d5eafc6d2f26b940918b16ee 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -13,7 +13,6 @@ FILES=                                          \
          test-gtk2.bin                          \
          test-gtk2-infobar.bin                  \
          test-hello.bin                         \
-         test-libaudit.bin                      \
          test-libbfd.bin                        \
          test-libbfd-buildid.bin		\
          test-disassembler-four-args.bin        \
@@ -228,9 +227,6 @@ $(OUTPUT)test-libunwind-debug-frame-arm.bin:
 $(OUTPUT)test-libunwind-debug-frame-aarch64.bin:
 	$(BUILD) -lelf -llzma -lunwind-aarch64
 
-$(OUTPUT)test-libaudit.bin:
-	$(BUILD) -laudit
-
 $(OUTPUT)test-libslang.bin:
 	$(BUILD) -lslang
 
diff --git a/tools/build/feature/test-libaudit.c b/tools/build/feature/test-libaudit.c
deleted file mode 100644
index f5b0863fa1ec240795339428d8deed98a946d405..0000000000000000000000000000000000000000
--- a/tools/build/feature/test-libaudit.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <libaudit.h>
-
-extern int printf(const char *format, ...);
-
-int main(void)
-{
-	printf("error message: %s\n", audit_errno_to_name(0));
-
-	return audit_open();
-}
diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt
index 31741499e7867c9b712227f31a2958fd641d474a..e6d2ceeb2ca7de850f41b1baa0375b6f984bb08f 100644
--- a/tools/perf/Documentation/perf-check.txt
+++ b/tools/perf/Documentation/perf-check.txt
@@ -51,7 +51,6 @@ feature::
                 dwarf_getlocations      /  HAVE_LIBDW_SUPPORT
                 dwarf-unwind            /  HAVE_DWARF_UNWIND_SUPPORT
                 auxtrace                /  HAVE_AUXTRACE_SUPPORT
-                libaudit                /  HAVE_LIBAUDIT_SUPPORT
                 libbfd                  /  HAVE_LIBBFD_SUPPORT
                 libcapstone             /  HAVE_LIBCAPSTONE_SUPPORT
                 libcrypto               /  HAVE_LIBCRYPTO_SUPPORT
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 3f82ba907381049213c055ab10c3fe14d9572073..a57b2364578f57e31476f5041a06a0cd22d8b27e 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -28,20 +28,7 @@ include $(srctree)/tools/scripts/Makefile.arch
 
 $(call detected_var,SRCARCH)
 
-ifneq ($(NO_SYSCALL_TABLE),1)
-  NO_SYSCALL_TABLE := 1
-
-  # architectures that use the generic syscall table scripts
-  ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
-    NO_SYSCALL_TABLE := 0
-    CFLAGS += -DGENERIC_SYSCALL_TABLE
-    CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
-  endif
-
-  ifneq ($(NO_SYSCALL_TABLE),1)
-    CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
-  endif
-endif
+CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
 
 # Additional ARCH settings for ppc
 ifeq ($(SRCARCH),powerpc)
@@ -755,21 +742,7 @@ ifndef NO_LIBUNWIND
 endif
 
 ifneq ($(NO_LIBTRACEEVENT),1)
-  ifeq ($(NO_SYSCALL_TABLE),0)
-    $(call detected,CONFIG_TRACE)
-  else
-    ifndef NO_LIBAUDIT
-      $(call feature_check,libaudit)
-      ifneq ($(feature-libaudit), 1)
-        $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev)
-        NO_LIBAUDIT := 1
-      else
-        CFLAGS += -DHAVE_LIBAUDIT_SUPPORT
-        EXTLIBS += -laudit
-        $(call detected,CONFIG_TRACE)
-      endif
-    endif
-  endif
+  $(call detected,CONFIG_TRACE)
 endif
 
 ifndef NO_LIBCRYPTO
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 2c6a509c800d3037933c9b49e5a7dafbf78fda0c..ab2d075ff3a23350a5eea12508cf0376f1d9f4e8 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -59,8 +59,6 @@ include ../scripts/utilities.mak
 #
 # Define NO_LIBNUMA if you do not want numa perf benchmark
 #
-# Define NO_LIBAUDIT if you do not want libaudit support
-#
 # Define NO_LIBBIONIC if you do not want bionic support
 #
 # Define NO_LIBCRYPTO if you do not want libcrypto (openssl) support
@@ -119,10 +117,6 @@ include ../scripts/utilities.mak
 #
 # Define LIBBPF_DYNAMIC to enable libbpf dynamic linking.
 #
-# Define NO_SYSCALL_TABLE=1 to disable the use of syscall id to/from name tables
-# generated from the kernel .tbl or unistd.h files and use, if available, libaudit
-# for doing the conversions to/from strings/id.
-#
 # Define NO_LIBPFM4 to disable libpfm4 events extension.
 #
 # Define NO_LIBDEBUGINFOD if you do not want support debuginfod
@@ -310,11 +304,7 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
 FEATURE_TESTS := all
 endif
 endif
-# architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390
-ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
-endif
 include Makefile.config
 endif
 
@@ -1099,11 +1089,6 @@ endif
 		$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 	$(call QUIET_INSTALL, perf-iostat) \
 		$(INSTALL) $(OUTPUT)perf-iostat -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
-ifndef NO_LIBAUDIT
-	$(call QUIET_INSTALL, strace/groups) \
-		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'; \
-		$(INSTALL) trace/strace/groups/* -m 644 -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'
-endif
 ifndef NO_LIBPERL
 	$(call QUIET_INSTALL, perl-scripts) \
 		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
index 2346536a5ee14f91ecd10bd130a64676e871e1b2..7aed7b9f4f5270527ee1d36327eb6a01f196a46a 100644
--- a/tools/perf/builtin-check.c
+++ b/tools/perf/builtin-check.c
@@ -31,7 +31,6 @@ struct feature_status supported_features[] = {
 	FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT),
 	FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT),
 	FEATURE_STATUS("auxtrace", HAVE_AUXTRACE_SUPPORT),
-	FEATURE_STATUS("libaudit", HAVE_LIBAUDIT_SUPPORT),
 	FEATURE_STATUS("libbfd", HAVE_LIBBFD_SUPPORT),
 	FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT),
 	FEATURE_STATUS("libcrypto", HAVE_LIBCRYPTO_SUPPORT),
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 0854d3cd9f6a304cd9cb50ad430d5706d91df0e9..7be6fb6df595923c15ae51747d5bf17d867ae785 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -447,9 +447,7 @@ int cmd_help(int argc, const char **argv)
 #ifdef HAVE_LIBELF_SUPPORT
 		"probe",
 #endif
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
 		"trace",
-#endif
 	NULL };
 	const char *builtin_help_usage[] = {
 		"perf help [--all] [--man|--web|--info] [command]",
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 6a1a128fe645014d0347ad4ec3e0c9e77ec59aee..0fddf34458db4fe4896d25f427f2ae29cb3aa15f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2069,30 +2069,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
 	const char *name = syscalltbl__name(trace->sctbl, id);
 	int err;
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 	if (trace->syscalls.table == NULL) {
 		trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc));
 		if (trace->syscalls.table == NULL)
 			return -ENOMEM;
 	}
-#else
-	if (id > trace->sctbl->syscalls.max_id || (id == 0 && trace->syscalls.table == NULL)) {
-		// When using libaudit we don't know beforehand what is the max syscall id
-		struct syscall *table = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
-
-		if (table == NULL)
-			return -ENOMEM;
-
-		// Need to memset from offset 0 and +1 members if brand new
-		if (trace->syscalls.table == NULL)
-			memset(table, 0, (id + 1) * sizeof(*sc));
-		else
-			memset(table + trace->sctbl->syscalls.max_id + 1, 0, (id - trace->sctbl->syscalls.max_id) * sizeof(*sc));
-
-		trace->syscalls.table	      = table;
-		trace->sctbl->syscalls.max_id = id;
-	}
-#endif
 	sc = trace->syscalls.table + id;
 	if (sc->nonexistent)
 		return -EEXIST;
@@ -2439,18 +2420,7 @@ static struct syscall *trace__syscall_info(struct trace *trace,
 
 	err = -EINVAL;
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 	if (id > trace->sctbl->syscalls.max_id) {
-#else
-	if (id >= trace->sctbl->syscalls.max_id) {
-		/*
-		 * With libaudit we don't know beforehand what is the max_id,
-		 * so we let trace__read_syscall_info() figure that out as we
-		 * go on reading syscalls.
-		 */
-		err = trace__read_syscall_info(trace, id);
-		if (err)
-#endif
 		goto out_cant_read;
 	}
 
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index a2987f2cfe1a3958f53239ed1a4eec3f87d7466a..f0617cc41f5fe638986e5d8316a6b3056c2c4bc5 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -84,7 +84,7 @@ static struct cmd_struct commands[] = {
 #endif
 	{ "kvm",	cmd_kvm,	0 },
 	{ "test",	cmd_test,	0 },
-#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))
+#if defined(HAVE_LIBTRACEEVENT)
 	{ "trace",	cmd_trace,	0 },
 #endif
 	{ "inject",	cmd_inject,	0 },
@@ -514,10 +514,6 @@ int main(int argc, const char **argv)
 		fprintf(stderr,
 			"trace command not available: missing libtraceevent devel package at build time.\n");
 		goto out;
-#elif !defined(HAVE_LIBAUDIT_SUPPORT) && !defined(HAVE_SYSCALL_TABLE_SUPPORT)
-		fprintf(stderr,
-			"trace command not available: missing audit-libs devel package at build time.\n");
-		goto out;
 #else
 		setup_path();
 		argv[0] = "trace";
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index a7fcbd589752a90459815bd21075528c6dfa4d94..0ee94caf9ec19820a94a87dd46a7ccf1cefb844a 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -86,7 +86,6 @@ make_no_libdw_dwarf_unwind := NO_LIBDW_DWARF_UNWIND=1
 make_no_backtrace   := NO_BACKTRACE=1
 make_no_libcapstone := NO_CAPSTONE=1
 make_no_libnuma     := NO_LIBNUMA=1
-make_no_libaudit    := NO_LIBAUDIT=1
 make_no_libbionic   := NO_LIBBIONIC=1
 make_no_auxtrace    := NO_AUXTRACE=1
 make_no_libbpf	    := NO_LIBBPF=1
@@ -97,7 +96,6 @@ make_no_libllvm     := NO_LIBLLVM=1
 make_with_babeltrace:= LIBBABELTRACE=1
 make_with_coresight := CORESIGHT=1
 make_no_sdt	    := NO_SDT=1
-make_no_syscall_tbl := NO_SYSCALL_TABLE=1
 make_no_libpfm4     := NO_LIBPFM4=1
 make_with_gtk2      := GTK2=1
 make_refcnt_check   := EXTRA_CFLAGS="-DREFCNT_CHECKING=1"
@@ -122,10 +120,10 @@ make_static         := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX3
 # all the NO_* variable combined
 make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_GTK2=1
 make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_BACKTRACE=1
-make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
+make_minimal        += NO_LIBNUMA=1 NO_LIBBIONIC=1
 make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
 make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
-make_minimal        += NO_LIBCAP=1 NO_SYSCALL_TABLE=1 NO_CAPSTONE=1
+make_minimal        += NO_LIBCAP=1 NO_CAPSTONE=1
 
 # $(run) contains all available tests
 run := make_pure
@@ -158,7 +156,6 @@ run += make_no_libdw_dwarf_unwind
 run += make_no_backtrace
 run += make_no_libcapstone
 run += make_no_libnuma
-run += make_no_libaudit
 run += make_no_libbionic
 run += make_no_auxtrace
 run += make_no_libbpf
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index e2843ca2edd92ea5fa1c020ae92b183c496e975e..e9a694350671910d537de599071dbe7fcc18ced4 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -474,13 +474,13 @@ const char *perf_env__arch(struct perf_env *env)
 
 const char *perf_env__arch_strerrno(struct perf_env *env __maybe_unused, int err __maybe_unused)
 {
-#if defined(HAVE_SYSCALL_TABLE_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#if defined(HAVE_LIBTRACEEVENT)
 	if (env->arch_strerrno == NULL)
 		env->arch_strerrno = arch_syscalls__strerrno_function(perf_env__arch(env));
 
 	return env->arch_strerrno ? env->arch_strerrno(err) : "no arch specific strerrno function";
 #else
-	return "!(HAVE_SYSCALL_TABLE_SUPPORT && HAVE_LIBTRACEEVENT)";
+	return "!HAVE_LIBTRACEEVENT";
 #endif
 }
 
diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh
index 1b5140e5ce9975fac87b2674dc694f9d4e439a5f..6a73c903d69050df69267a8aeaeeac1ed170efe1 100755
--- a/tools/perf/util/generate-cmdlist.sh
+++ b/tools/perf/util/generate-cmdlist.sh
@@ -38,7 +38,7 @@ do
 done
 echo "#endif /* HAVE_LIBELF_SUPPORT */"
 
-echo "#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))"
+echo "#if defined(HAVE_LIBTRACEEVENT)"
 sed -n -e 's/^perf-\([^ 	]*\)[ 	].* audit*/\1/p' command-list.txt |
 sort |
 while read cmd
@@ -51,7 +51,7 @@ do
 	    p
      }' "Documentation/perf-$cmd.txt"
 done
-echo "#endif /* HAVE_LIBTRACEEVENT && (HAVE_LIBAUDIT_SUPPORT || HAVE_SYSCALL_TABLE_SUPPORT) */"
+echo "#endif /* HAVE_LIBTRACEEVENT */"
 
 echo "#ifdef HAVE_LIBTRACEEVENT"
 sed -n -e 's/^perf-\([^ 	]*\)[ 	].* traceevent.*/\1/p' command-list.txt |
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 210f61b0a7a264a427ebb602185d3a9da2f426f4..928aca4cd6e9f2f26c5c4fd825b4538c064a4cc3 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -10,20 +10,12 @@
 #include <linux/compiler.h>
 #include <linux/zalloc.h>
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 #include <string.h>
 #include "string2.h"
 
-#if defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl;
-#else
-const int syscalltbl_native_max_id = 0;
-static const char *const syscalltbl_native[] = {
-	[0] = "unknown",
-};
-#endif
 
 struct syscall {
 	int id;
@@ -131,47 +123,3 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
 	*idx = -1;
 	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 }
-
-#else /* HAVE_SYSCALL_TABLE_SUPPORT */
-
-#include <libaudit.h>
-
-struct syscalltbl *syscalltbl__new(void)
-{
-	struct syscalltbl *tbl = zalloc(sizeof(*tbl));
-	if (tbl)
-		tbl->audit_machine = audit_detect_machine();
-	return tbl;
-}
-
-void syscalltbl__delete(struct syscalltbl *tbl)
-{
-	free(tbl);
-}
-
-const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
-{
-	return audit_syscall_to_name(id, tbl->audit_machine);
-}
-
-int syscalltbl__id(struct syscalltbl *tbl, const char *name)
-{
-	return audit_name_to_syscall(name, tbl->audit_machine);
-}
-
-int syscalltbl__id_at_idx(struct syscalltbl *tbl __maybe_unused, int idx)
-{
-	return idx;
-}
-
-int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
-				  const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
-{
-	return -1;
-}
-
-int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
-{
-	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
-}
-#endif /* HAVE_SYSCALL_TABLE_SUPPORT */

-- 
2.34.1



From ck.hu at mediatek.com  Mon Dec 16 22:40:11 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 17 Dec 2024 06:40:11 +0000
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <e5788187-e894-4aab-a41e-a3d7a64762c6@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
	 <803bc2bd802506635dfa9ea9b26a6ca40a7f4912.camel@mediatek.com>
	 <e5788187-e894-4aab-a41e-a3d7a64762c6@collabora.com>
Message-ID: <d64ff9f1525fe3563502e470b2a31303de08a7c6.camel@mediatek.com>

On Mon, 2024-12-16 at 12:04 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Il 16/12/24 09:57, CK Hu (???) ha scritto:
> > Hi, Angelo:
> > 
> > On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> > > External email : Please do not click links or open attachments until you have verified the sender or the content.
> > > 
> > > 
> > > Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> > > found in MediaTek's MT8195, MT8188 SoC and their variants, and
> > > including support for display modes up to 4k60 and for HDMI
> > > Audio, as per the HDMI 2.0 spec.
> > > 
> > > HDCP and CEC functionalities are also supported by this hardware,
> > > but are not included in this commit and that also poses a slight
> > > difference between the V2 and V1 controllers in how they handle
> > > Hotplug Detection (HPD).
> > > 
> > > While the v1 controller was using the CEC controller to check
> > > HDMI cable connection and disconnection, in this driver the v2
> > > one does not.
> > > 
> > > This is due to the fact that on parts with v2 designs, like the
> > > MT8195 SoC, there is one CEC controller shared between the HDMI
> > > Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> > > adding support to use the CEC HW to wake up the HDMI controllers
> > > it is necessary to have support for one TX, one RX *and* for both
> > > at the same time.
> > > 
> > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > > ---
> > 
> > [snip]
> > 
> > > +static int mtk_hdmi_v2_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)
> > > +{
> > 
> > I would like v1 and v2 has the same behavior.
> > Why v2 has atomic check but v1 has no?
> > If this is better to have, add atomic check to v1, and this function would be common function.
> > 
> 
> That's because v2 uses the new helpers, while v1 does not.
> The v1 must be converted to the new helpers in order to use atomic_check() like v2.

I just find the description here, and I don't know why new helper need atomic_check().
Would you provide more information how new helper need atomic_check()?
For example, the call stack to atomic_check(). (You could use dump_stack() to show it)

        /**
        * @atomic_check:
        *
        * This method is responsible for checking bridge state correctness.
        * It can also check the state of the surrounding components in chain
        * to make sure the whole pipeline can work properly.
        *
        * &drm_bridge_funcs.atomic_check() hooks are called in reverse
        * order (from the last to the first bridge).
        *
        * This method is optional. &drm_bridge_funcs.mode_fixup() is not
        * called when &drm_bridge_funcs.atomic_check() is implemented, so only
        * one of them should be provided.
        *
        * If drivers need to tweak &drm_bridge_state.input_bus_cfg.flags or
        * &drm_bridge_state.output_bus_cfg.flags it should happen in
        * this function. By default the &drm_bridge_state.output_bus_cfg.flags
        * field is set to the next bridge
        * &drm_bridge_state.input_bus_cfg.flags value or
        * &drm_connector.display_info.bus_flags if the bridge is the last
        * element in the chain.
        *
        * RETURNS:
        * zero if the check passed, a negative error code otherwise.
        */

Regards,
CK

> 
> Cheers,
> Angelo
> 
> > Regards,
> > CK
> > 
> > > +       return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
> > > +                                                     conn_state->state);
> > > +}
> > > +
> > 
> > 
> 
> 
> 


From ck.hu at mediatek.com  Mon Dec 16 22:47:47 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 17 Dec 2024 06:47:47 +0000
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
Message-ID: <bb01b21cabffc53d603cd52f4542f181d736d4ae.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit and that also poses a slight
> difference between the V2 and V1 controllers in how they handle
> Hotplug Detection (HPD).
> 
> While the v1 controller was using the CEC controller to check
> HDMI cable connection and disconnection, in this driver the v2
> one does not.
> 
> This is due to the fact that on parts with v2 designs, like the
> MT8195 SoC, there is one CEC controller shared between the HDMI
> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> adding support to use the CEC HW to wake up the HDMI controllers
> it is necessary to have support for one TX, one RX *and* for both
> at the same time.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static const struct drm_bridge_funcs mtk_v2_hdmi_bridge_funcs = {
> +       .attach = mtk_hdmi_v2_bridge_attach,
> +       .detach = mtk_hdmi_v2_bridge_detach,
> +       .mode_fixup = mtk_hdmi_bridge_mode_fixup,
> +       .mode_set = mtk_hdmi_bridge_mode_set,
> +       .mode_valid = mtk_hdmi_v2_bridge_mode_valid,
> +       .atomic_pre_enable = mtk_hdmi_v2_bridge_pre_enable,
> +       .atomic_enable = mtk_hdmi_v2_bridge_enable,
> +       .atomic_disable = mtk_hdmi_v2_bridge_disable,
> +       .atomic_post_disable = mtk_hdmi_v2_bridge_post_disable,
> +       .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> +       .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> +       .atomic_check = mtk_hdmi_v2_bridge_atomic_check,
> +       .atomic_reset = drm_atomic_helper_bridge_reset,
> +       .detect = mtk_hdmi_v2_bridge_detect,
> +       .edid_read = mtk_hdmi_v2_bridge_edid_read,
> +       .hdmi_tmds_char_rate_valid = mtk_hdmi_v2_hdmi_tmds_char_rate_valid,
> +       .hdmi_clear_infoframe = mtk_hdmi_v2_hdmi_clear_infoframe,
> +       .hdmi_write_infoframe = mtk_hdmi_v2_hdmi_write_infoframe,
> +       .debugfs_init = mtk_hdmi_v2_debugfs_init,

I would like this patch to be smaller, so separate debugfs to an independent patch.

Regards,
CK

> +};
> +



From Sandor.yu at nxp.com  Mon Dec 16 22:51:44 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:44 +0800
Subject: [PATCH v20 2/9] drm: bridge: cadence: Update mhdp8546 mailbox access functions
In-Reply-To: <cover.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <74bc3f2ff56348afd9d773589236ddf06dc3d45c.1734340233.git.Sandor.yu@nxp.com>

Basic mailbox access functions are removed, they are replaced by
mailbox helper functions:
- cdns_mhdp_mailbox_send()
- cdns_mhdp_mailbox_send_recv()
- cdns_mhdp_mailbox_send_recv_multi()
- cdns_mhdp_secure_mailbox_send()
- cdns_mhdp_secure_mailbox_send_recv()
- cdns_mhdp_secure_mailbox_send_recv_multi()

All MHDP commands that need to be passed through the mailbox
have been rewritten using these new helper functions.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
---
v19->v20:
- remove mhdp helper functions from the patch.

v18->v19:
- Use guard(mutex)
- Add kerneldocs for all new APIs.
- Detail comments for mailbox access specific case.
- Remove cdns_mhdp_dp_reg_write() because it is not needed by driver now.

v17->v18:
- Create three ordinary mailbox access APIs
    cdns_mhdp_mailbox_send
    cdns_mhdp_mailbox_send_recv
    cdns_mhdp_mailbox_send_recv_multi
- Create three secure mailbox access APIs
    cdns_mhdp_secure_mailbox_send
    cdns_mhdp_secure_mailbox_send_recv
    cdns_mhdp_secure_mailbox_send_recv_multi
- MHDP8546 DP and HDCP commands that need access mailbox are rewrited
  with above 6 API functions.

v16->v17:
- Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex

v12->v16:
 *No change.

 drivers/gpu/drm/bridge/cadence/Kconfig        |   1 +
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 487 +++---------------
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  47 +-
 .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   | 212 +-------
 .../drm/bridge/cadence/cdns-mhdp8546-hdcp.h   |  18 +-
 5 files changed, 104 insertions(+), 661 deletions(-)

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
index cced81633ddcd..dbb06533ccab2 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -28,6 +28,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/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index d081850e3c03e..bd897c3ae7642 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -73,302 +73,18 @@ 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)
-{
-	u8 msg[6], reg[5];
-	int ret;
-
-	put_unaligned_be16(1, msg);
-	put_unaligned_be24(addr, msg + 2);
-	msg[5] = value;
-
-	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));
-	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));
-	if (ret)
-		goto out;
-
-	ret = 0;
+	u8 status;
+	int ret;
 
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
+	status = enable ? FW_ACTIVE : FW_STANDBY;
 
+	ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_GENERAL,
+					  GENERAL_MAIN_CONTROL,
+					  sizeof(status), &status,
+					  sizeof(status), &status);
 	if (ret < 0)
 		dev_err(mhdp->dev, "set firmware active failed\n");
 	return ret;
@@ -380,34 +96,18 @@ int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp)
 	u8 status;
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, 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,
-					    DPTX_HPD_STATE,
-					    sizeof(status));
-	if (ret)
-		goto err_get_hpd;
+	ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX,
+					  DPTX_HPD_STATE,
+					  0, NULL,
+					  sizeof(status), &status);
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, &status, sizeof(status));
 	if (ret)
-		goto err_get_hpd;
-
-	mutex_unlock(&mhdp->mbox_mutex);
+		return ret;
 
 	dev_dbg(mhdp->dev, "%s: HPD %splugged\n", __func__,
 		status ? "" : "un");
 
 	return status;
-
-err_get_hpd:
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
 }
 
 static
@@ -418,28 +118,17 @@ int cdns_mhdp_get_edid_block(void *data, u8 *edid,
 	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, 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,
-						    DPTX_GET_EDID,
-						    sizeof(reg) + length);
-		if (ret)
-			continue;
-
-		ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
-		if (ret)
-			continue;
-
-		ret = cdns_mhdp_mailbox_recv_data(mhdp, edid, length);
+		ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base,
+							MB_MODULE_ID_DP_TX,
+							DPTX_GET_EDID,
+							sizeof(msg), msg,
+							DPTX_GET_EDID,
+							sizeof(reg), reg,
+							length, edid);
 		if (ret)
 			continue;
 
@@ -447,8 +136,6 @@ int cdns_mhdp_get_edid_block(void *data, u8 *edid,
 			break;
 	}
 
-	mutex_unlock(&mhdp->mbox_mutex);
-
 	if (ret)
 		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n",
 			block, ret);
@@ -462,21 +149,9 @@ int cdns_mhdp_read_hpd_event(struct cdns_mhdp_device *mhdp)
 	u8 event = 0;
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, 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,
-					    DPTX_READ_EVENT, sizeof(event));
-	if (ret < 0)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, &event, sizeof(event));
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
+	ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX,
+					  DPTX_READ_EVENT,
+					  0, NULL, sizeof(event), &event);
 
 	if (ret < 0)
 		return ret;
@@ -510,35 +185,23 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes,
 	put_unaligned_be16(udelay, payload + 1);
 	memcpy(payload + 3, lanes_data, nlanes);
 
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, 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,
-					    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_send_recv_multi(&mhdp->base,
+						MB_MODULE_ID_DP_TX,
+						DPTX_ADJUST_LT,
+						sizeof(payload), payload,
+						DPTX_READ_DPCD,
+						sizeof(hdr), hdr,
+						DP_LINK_STATUS_SIZE,
+						link_status);
 	if (ret)
 		goto out;
 
 	addr = get_unaligned_be24(hdr + 2);
 	if (addr != DP_LANE0_1_STATUS)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, link_status,
-					  DP_LINK_STATUS_SIZE);
+		ret = -EINVAL;
 
 out:
-	mutex_unlock(&mhdp->mbox_mutex);
-
 	if (ret)
 		dev_err(mhdp->dev, "Failed to adjust Link Training.\n");
 
@@ -847,7 +510,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 +522,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 +550,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 +576,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 +721,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 +985,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 +996,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 +1010,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 +1124,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 +1133,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;
@@ -1834,7 +1497,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;
@@ -1842,10 +1505,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;
@@ -1853,19 +1516,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));
 
@@ -1874,11 +1537,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));
 
@@ -1887,7 +1550,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) &&
@@ -1899,14 +1562,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));
 
@@ -1915,13 +1578,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",
@@ -1930,7 +1593,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,
@@ -1963,15 +1626,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));
 
@@ -2006,13 +1669,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 +1746,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)
@@ -2471,7 +2134,6 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
 
 	mhdp->clk = clk;
 	mhdp->dev = dev;
-	mutex_init(&mhdp->mbox_mutex);
 	mutex_init(&mhdp->link_mutex);
 	spin_lock_init(&mhdp->start_lock);
 
@@ -2502,6 +2164,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.sapb_regs = mhdp->sapb_regs;
+
 	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..535300d040dea 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
@@ -18,6 +18,7 @@
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_connector.h>
+#include <soc/cadence/cdns-mhdp-helper.h>
 
 struct clk;
 struct device;
@@ -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;
@@ -362,9 +326,6 @@ struct cdns_mhdp_device {
 
 	const struct cdns_mhdp_platform_info *info;
 
-	/* This is to protect mailbox communications with the firmware */
-	struct mutex mbox_mutex;
-
 	/*
 	 * "link_mutex" protects the access to all the link parameters
 	 * including the link training process. Link training will be
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
index 42248f179b69d..3944642f2ebbc 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
@@ -15,144 +15,20 @@
 
 #include "cdns-mhdp8546-hdcp.h"
 
-static int cdns_mhdp_secure_mailbox_read(struct cdns_mhdp_device *mhdp)
-{
-	int ret, empty;
-
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-	ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_EMPTY,
-				 empty, !empty, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	return readl(mhdp->sapb_regs + CDNS_MAILBOX_RX_DATA) & 0xff;
-}
-
-static int cdns_mhdp_secure_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->sapb_regs + CDNS_MAILBOX_FULL,
-				 full, !full, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	writel(val, mhdp->sapb_regs + CDNS_MAILBOX_TX_DATA);
-
-	return 0;
-}
-
-static int cdns_mhdp_secure_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_secure_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] ||
-	    (opcode != HDCP_TRAN_IS_REC_ID_VALID && req_size != mbox_size)) {
-		for (i = 0; i < mbox_size; i++)
-			if (cdns_mhdp_secure_mailbox_read(mhdp) < 0)
-				break;
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_secure_mailbox_recv_data(struct cdns_mhdp_device *mhdp,
-					      u8 *buff, u16 buff_size)
-{
-	int ret;
-	u32 i;
-
-	for (i = 0; i < buff_size; i++) {
-		ret = cdns_mhdp_secure_mailbox_read(mhdp);
-		if (ret < 0)
-			return ret;
-
-		buff[i] = ret;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_device *mhdp,
-					 u8 module_id,
-					 u8 opcode,
-					 u16 size,
-					 u8 *message)
-{
-	u8 header[4];
-	int ret;
-	u32 i;
-
-	header[0] = opcode;
-	header[1] = module_id;
-	put_unaligned_be16(size, header + 2);
-
-	for (i = 0; i < sizeof(header); i++) {
-		ret = cdns_mhdp_secure_mailbox_write(mhdp, header[i]);
-		if (ret)
-			return ret;
-	}
-
-	for (i = 0; i < size; i++) {
-		ret = cdns_mhdp_secure_mailbox_write(mhdp, message[i]);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
 static int cdns_mhdp_hdcp_get_status(struct cdns_mhdp_device *mhdp,
 				     u16 *hdcp_port_status)
 {
 	u8 hdcp_status[HDCP_STATUS_SIZE];
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
-	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
-					    HDCP_TRAN_STATUS_CHANGE, 0, NULL);
-	if (ret)
-		goto err_get_hdcp_status;
-
-	ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
-						   HDCP_TRAN_STATUS_CHANGE,
-						   sizeof(hdcp_status));
-	if (ret)
-		goto err_get_hdcp_status;
-
-	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_status,
-						 sizeof(hdcp_status));
+	ret = cdns_mhdp_secure_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_HDCP_TX,
+						 HDCP_TRAN_STATUS_CHANGE, 0, NULL,
+						 sizeof(hdcp_status), hdcp_status);
 	if (ret)
-		goto err_get_hdcp_status;
+		return ret;
 
 	*hdcp_port_status = ((u16)(hdcp_status[0] << 8) | hdcp_status[1]);
 
-err_get_hdcp_status:
-	mutex_unlock(&mhdp->mbox_mutex);
-
 	return ret;
 }
 
@@ -170,98 +46,52 @@ static u8 cdns_mhdp_hdcp_handle_status(struct cdns_mhdp_device *mhdp,
 static int cdns_mhdp_hdcp_rx_id_valid_response(struct cdns_mhdp_device *mhdp,
 					       u8 valid)
 {
-	int ret;
-
-	mutex_lock(&mhdp->mbox_mutex);
-	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
+	return cdns_mhdp_secure_mailbox_send(&mhdp->base, MB_MODULE_ID_HDCP_TX,
 					    HDCP_TRAN_RESPOND_RECEIVER_ID_VALID,
 					    1, &valid);
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
 }
 
 static int cdns_mhdp_hdcp_rx_id_valid(struct cdns_mhdp_device *mhdp,
 				      u8 *recv_num, u8 *hdcp_rx_id)
 {
 	u8 rec_id_hdr[2];
-	u8 status;
 	int ret;
 
-	mutex_lock(&mhdp->mbox_mutex);
-	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
-					    HDCP_TRAN_IS_REC_ID_VALID, 0, NULL);
-	if (ret)
-		goto err_rx_id_valid;
-
-	ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
-						   HDCP_TRAN_IS_REC_ID_VALID,
-						   sizeof(status));
-	if (ret)
-		goto err_rx_id_valid;
-
-	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, rec_id_hdr, 2);
+	ret = cdns_mhdp_secure_mailbox_send_recv_multi(&mhdp->base,
+						       MB_MODULE_ID_HDCP_TX,
+						       HDCP_TRAN_IS_REC_ID_VALID,
+						       0, NULL,
+						       HDCP_TRAN_IS_REC_ID_VALID,
+						       sizeof(rec_id_hdr), rec_id_hdr,
+						       0, hdcp_rx_id);
 	if (ret)
-		goto err_rx_id_valid;
+		return ret;
 
 	*recv_num = rec_id_hdr[0];
 
-	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_rx_id, 5 * *recv_num);
-
-err_rx_id_valid:
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
+	return 0;
 }
 
 static int cdns_mhdp_hdcp_km_stored_resp(struct cdns_mhdp_device *mhdp,
 					 u32 size, u8 *km)
 {
-	int ret;
-
-	mutex_lock(&mhdp->mbox_mutex);
-	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
-					    HDCP2X_TX_RESPOND_KM, size, km);
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
+	return cdns_mhdp_secure_mailbox_send(&mhdp->base, MB_MODULE_ID_HDCP_TX,
+					     HDCP2X_TX_RESPOND_KM, size, km);
 }
 
 static int cdns_mhdp_hdcp_tx_is_km_stored(struct cdns_mhdp_device *mhdp,
 					  u8 *resp, u32 size)
 {
-	int ret;
-
-	mutex_lock(&mhdp->mbox_mutex);
-	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
-					    HDCP2X_TX_IS_KM_STORED, 0, NULL);
-	if (ret)
-		goto err_is_km_stored;
-
-	ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
-						   HDCP2X_TX_IS_KM_STORED,
-						   size);
-	if (ret)
-		goto err_is_km_stored;
-
-	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, resp, size);
-err_is_km_stored:
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
+	return cdns_mhdp_secure_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_HDCP_TX,
+						 HDCP2X_TX_IS_KM_STORED,
+						 0, NULL, size, resp);
 }
 
 static int cdns_mhdp_hdcp_tx_config(struct cdns_mhdp_device *mhdp,
 				    u8 hdcp_cfg)
 {
-	int ret;
-
-	mutex_lock(&mhdp->mbox_mutex);
-	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
-					    HDCP_TRAN_CONFIGURATION, 1, &hdcp_cfg);
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
+	return cdns_mhdp_secure_mailbox_send(&mhdp->base, MB_MODULE_ID_HDCP_TX,
+					     HDCP_TRAN_CONFIGURATION, 1, &hdcp_cfg);
 }
 
 static int cdns_mhdp_hdcp_set_config(struct cdns_mhdp_device *mhdp,
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.h
index 3b6ec9c3a8d8b..1e68530e72229 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.h
@@ -9,6 +9,7 @@
 #ifndef CDNS_MHDP8546_HDCP_H
 #define CDNS_MHDP8546_HDCP_H
 
+#include <soc/cadence/cdns-mhdp-helper.h>
 #include "cdns-mhdp8546-core.h"
 
 #define HDCP_MAX_RECEIVERS 32
@@ -32,23 +33,6 @@ enum {
 	HDCP_SET_SEED,
 };
 
-enum {
-	HDCP_TRAN_CONFIGURATION,
-	HDCP2X_TX_SET_PUBLIC_KEY_PARAMS,
-	HDCP2X_TX_SET_DEBUG_RANDOM_NUMBERS,
-	HDCP2X_TX_RESPOND_KM,
-	HDCP1_TX_SEND_KEYS,
-	HDCP1_TX_SEND_RANDOM_AN,
-	HDCP_TRAN_STATUS_CHANGE,
-	HDCP2X_TX_IS_KM_STORED,
-	HDCP2X_TX_STORE_KM,
-	HDCP_TRAN_IS_REC_ID_VALID,
-	HDCP_TRAN_RESPOND_RECEIVER_ID_VALID,
-	HDCP_TRAN_TEST_KEYS,
-	HDCP2X_TX_SET_KM_KEY_PARAMS,
-	HDCP_NUM_OF_SUPPORTED_MESSAGES
-};
-
 enum {
 	HDCP_CONTENT_TYPE_0,
 	HDCP_CONTENT_TYPE_1,
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Dec 16 22:51:46 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:46 +0800
Subject: [PATCH v20 4/9] dt-bindings: display: bridge: Add Cadence MHDP8501
In-Reply-To: <cover.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <f2b7beebeb99ca69021ca24744e29af3454f5620.1734340233.git.Sandor.yu@nxp.com>

Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
---
v19->v20:
- remove data type link of data-lanes.

v18->v19:
- move data-lanes property to endpoint of port at 1

v17->v18:
- remove lane-mapping and replace it with data-lanes
- remove r-b tag as property changed.

v16->v17:
- Add lane-mapping property

v9->v16:
 *No change

 .../display/bridge/cdns,mhdp8501.yaml         | 121 ++++++++++++++++++
 1 file changed, 121 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..2417f4038b437
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
@@ -0,0 +1,121 @@
+# 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 DP/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#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Output port to DisplayPort or HDMI connector.
+
+        properties:
+          endpoint:
+            $ref: /schemas/media/video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                description: Lane reordering for HDMI or DisplayPort interface.
+                minItems: 4
+                maxItems: 4
+
+            required:
+              - data-lanes
+
+    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 = <&mdhp_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>;
+                    data-lanes = <2 1 0 3>;
+                };
+            };
+        };
+    };
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Dec 16 22:51:47 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:47 +0800
Subject: [PATCH v20 5/9] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <cover.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <fbd12029fab1f60e2ba4fad75ef650298a59cb15.1734340233.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>
---
v19->v20:
- Dump mhdp FW version by debugfs
- Combine HDMI and DP cable detect functions into one function
- Combine HDMI and DP cable bridge_mode_valid() functions into one function
- Rename cdns_hdmi_reset_link() to cdns_hdmi_handle_hotplug()
- Add comments for EDID in cdns_hdmi_handle_hotplug() and cdns_dp_check_link_state()
- Add atomic_get_input_bus_fmts() and bridge_atomic_check() for DP driver
- Remove bpc and color_fmt init in atomic_enable() function.
- More detail comments for DDC adapter only support SCDC_I2C_SLAVE_ADDRESS
  read and write in HDMI driver.


v18->v19:
- Get endpoint for data-lanes as it had move to endpoint of port at 1
- Update clock management as devm_clk_get_enabled() introduced.
- Fix clear_infoframe() function is not work issue.
- Manage PHY power state via phy_power_on() and phy_power_off().

v17->v18:
- MHDP8501 HDMI and DP commands that need access mailbox are rewrited
  with new API functions created in patch #1.
- replace lane-mapping with data-lanes, use the value from data-lanes
  to reorder HDMI and DP lane mapping.
- create I2C adapter for HDMI SCDC, remove cdns_hdmi_scdc_write() function.
- Rewrite cdns_hdmi_sink_config() function, use HDMI SCDC helper function
  drm_scdc_set_high_tmds_clock_ratio() and drm_scdc_set_scrambling()
  to config HDMI sink TMDS.
- Remove struct video_info from HDMI driver.
- Remove tmds_char_rate_valid() be called in bridge_mode_valid(),
  community had patch in reviewing to implement the function.
- Remove warning message print when get unknown HPD cable status.
- Add more detail comments for HDP plugin and plugout interrupt.
- use dev_dbg to repleace DRM_INFO when cable HPD status changed.
- Remove t-b tag as above code change.

 drivers/gpu/drm/bridge/cadence/Kconfig        |  16 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   2 +
 .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 379 +++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 380 +++++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 694 ++++++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 745 ++++++++++++++++++
 6 files changed, 2216 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 dbb06533ccab2..bd979f3e6df48 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -48,3 +48,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 DRM_CDNS_AUDIO
+	select CDNS_MHDP_HELPER
+	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 c95fd5b81d137..ea327287d1c14 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -5,3 +5,5 @@ cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.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..98116ef012fa3
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
@@ -0,0 +1,379 @@
+// 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 ssize_t firmware_version_show(struct device *dev,
+				     struct device_attribute *attr, char *buf);
+static struct device_attribute firmware_version = __ATTR_RO(firmware_version);
+
+ssize_t firmware_version_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(dev);
+
+	u32 version = readl(mhdp->base.regs + VER_L) | readl(mhdp->base.regs + VER_H) << 8;
+	u32 lib_version = readl(mhdp->base.regs + VER_LIB_L_ADDR) |
+			  readl(mhdp->base.regs + VER_LIB_H_ADDR) << 8;
+
+	return sprintf(buf, "FW version %d, Lib version %d\n", version, lib_version);
+}
+
+static void cdns_mhdp8501_create_device_files(struct cdns_mhdp8501_device *mhdp)
+{
+	if (device_create_file(mhdp->dev, &firmware_version)) {
+		DRM_ERROR("Unable to create firmware_version sysfs\n");
+		device_remove_file(mhdp->dev, &firmware_version);
+	}
+}
+
+static void cdns_mhdp8501_remove_device_files(struct cdns_mhdp8501_device *mhdp)
+{
+	device_remove_file(mhdp->dev, &firmware_version);
+}
+
+static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 status;
+	int ret;
+
+	ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_GENERAL,
+					  GENERAL_GET_HPD_STATE,
+					  0, NULL, sizeof(status), &status);
+	if (ret) {
+		dev_err(mhdp->dev, "read hpd failed: %d\n", ret);
+		return ret;
+	}
+
+	return status;
+}
+
+enum drm_connector_status cdns_mhdp8501_detect(struct drm_bridge *bridge)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	u8 hpd = 0xf;
+
+	hpd = cdns_mhdp8501_read_hpd(mhdp);
+	if (hpd == 1)
+		return connector_status_connected;
+	else if (hpd == 0)
+		return connector_status_disconnected;
+
+	return connector_status_unknown;
+}
+
+enum drm_mode_status
+cdns_mhdp8501_mode_valid(struct drm_bridge *bridge,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode)
+{
+	/* We don't support double-clocked */
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		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_OK;
+}
+
+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->bridge);
+
+	drm_bridge_hpd_notify(&mhdp->bridge, status);
+
+	/*
+	 * iMX8MQ has two HPD interrupts: one for plugout and one for plugin.
+	 * These interrupts cannot be masked and cleaned, so we must enable one
+	 * and disable the other to avoid continuous interrupt generation.
+	 */
+	if (status == connector_status_connected) {
+		/* Cable connected  */
+		dev_dbg(mhdp->dev, "HDMI/DP Cable Plug In\n");
+		enable_irq(mhdp->irq[IRQ_OUT]);
+
+		/* Reset HDMI/DP link with sink */
+		if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
+			cdns_hdmi_handle_hotplug(mhdp);
+		else
+			cdns_dp_check_link_state(mhdp);
+
+	} else if (status == connector_status_disconnected) {
+		/* Cable Disconnected  */
+		dev_dbg(mhdp->dev, "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;
+}
+
+#define DATA_LANES_COUNT	4
+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, *endpoint;
+	u32 data_lanes[DATA_LANES_COUNT];
+	u32 lane_value;
+	int ret, i;
+
+	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);
+
+	endpoint = of_graph_get_endpoint_by_regs(np, 1, -1);
+
+	/* Get the data lanes ordering */
+	ret = of_property_count_u32_elems(endpoint, "data-lanes");
+	if (ret < 0)
+		return  -EINVAL;
+	if (ret != DATA_LANES_COUNT) {
+		dev_err(dev, "expected 4 data lanes\n");
+		return  -EINVAL;
+	}
+
+	ret = of_property_read_u32_array(endpoint, "data-lanes",
+					 data_lanes, DATA_LANES_COUNT);
+	if (ret)
+		return  -EINVAL;
+
+	mhdp->lane_mapping  = 0;
+	for (i = 0; i < DATA_LANES_COUNT; i++) {
+		lane_value = (data_lanes[i] >= 0 && data_lanes[i] <= 3) ? data_lanes[i] : 0;
+		mhdp->lane_mapping |= lane_value << (i * 2);
+	}
+
+	return true;
+}
+
+static int cdns_mhdp8501_add_bridge(struct cdns_mhdp8501_device *mhdp)
+{
+	mhdp->bridge.type = mhdp->connector_type;
+	mhdp->bridge.driver_private = mhdp;
+	mhdp->bridge.of_node = mhdp->dev->of_node;
+	mhdp->bridge.vendor = "NXP";
+	mhdp->bridge.product = "i.MX8";
+	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
+			   DRM_BRIDGE_OP_HPD;
+
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+		mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
+		mhdp->bridge.ops |= DRM_BRIDGE_OP_HDMI;
+		mhdp->bridge.ddc = cdns_hdmi_i2c_adapter(mhdp);
+	} 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 -EINVAL;
+	}
+
+	drm_bridge_add(&mhdp->bridge);
+
+	return 0;
+}
+
+static int cdns_mhdp8501_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cdns_mhdp8501_device *mhdp;
+	struct resource *res;
+	enum phy_mode phy_mode;
+	u32 reg;
+	int ret;
+
+	mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
+	if (!mhdp)
+		return -ENOMEM;
+
+	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);
+
+	cdns_mhdp8501_create_device_files(mhdp);
+
+	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;
+	}
+
+	/* cdns_mhdp8501_dt_parse() ensures connector_type is valid */
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+		phy_mode = PHY_MODE_DP;
+	else if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
+		phy_mode = PHY_MODE_HDMI;
+
+	dev_set_drvdata(dev, mhdp);
+
+	/* init base struct for access mhdp mailbox */
+	mhdp->base.dev = mhdp->dev;
+	mhdp->base.regs = mhdp->regs;
+
+	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_enabled(dev, NULL);
+	if (IS_ERR(mhdp->apb_clk))
+		return dev_err_probe(dev, PTR_ERR(mhdp->apb_clk),
+				     "couldn't get apb clk\n");
+	/*
+	 * 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);
+		return ret;
+	}
+
+	ret = phy_init(mhdp->phy);
+	if (ret) {
+		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
+		return ret;
+	}
+
+	ret = phy_set_mode(mhdp->phy, phy_mode);
+	if (ret) {
+		dev_err(dev, "Failed to configure PHY: %d\n", ret);
+		return ret;
+	}
+
+	/* Enable cable hotplug detect */
+	if (cdns_mhdp8501_read_hpd(mhdp))
+		enable_irq(mhdp->irq[IRQ_OUT]);
+	else
+		enable_irq(mhdp->irq[IRQ_IN]);
+
+	return cdns_mhdp8501_add_bridge(mhdp);
+}
+
+static void cdns_mhdp8501_remove(struct platform_device *pdev)
+{
+	struct cdns_mhdp8501_device *mhdp = platform_get_drvdata(pdev);
+
+	cdns_mhdp8501_remove_device_files(mhdp);
+
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+		cdns_dp_aux_destroy(mhdp);
+
+	drm_bridge_remove(&mhdp->bridge);
+}
+
+static const struct of_device_id cdns_mhdp8501_dt_ids[] = {
+	{ .compatible = "fsl,imx8mq-mhdp8501",
+	},
+	{ },
+};
+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..8fc463098ab84
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
@@ -0,0 +1,380 @@
+/* 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/drm_bridge.h>
+#include <drm/drm_connector.h>
+#include <drm/display/drm_dp_helper.h>
+#include <linux/bitops.h>
+#include <linux/i2c.h>
+#include <soc/cadence/cdns-mhdp-helper.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_FLIPPED		0xe4
+#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_HDMI2_CTRL_IL_MODE(x)		(((x) & ((1 << 1) - 1)) << 19)
+#define F_HDMI2_PREAMBLE_EN(x)		(((x) & ((1 << 1) - 1)) << 18)
+#define F_HDMI_ENCODING(x)		(((x) & ((1 << 2) - 1)) << 16)
+#define F_DATA_EN(x)			(((x) & ((1 << 1) - 1)) << 15)
+#define F_CLEAR_AVMUTE(x)		(((x) & ((1 << 1) - 1)) << 14)
+#define F_SET_AVMUTE(x)			(((x) & ((1 << 1) - 1)) << 13)
+#define F_GCP_EN(x)			(((x) & ((1 << 1) - 1)) << 12)
+#define F_BCH_EN(x)			(((x) & ((1 << 1) - 1)) << 11)
+#define F_PIC_3D(x)			(((x) & ((1 << 4) - 1)) << 7)
+#define F_VIF_DATA_WIDTH(x)		(((x) & ((1 << 2) - 1)) << 2)
+#define F_HDMI_MODE(x)			(((x) & ((1 << 2) - 1)) << 0)
+
+#define F_SOURCE_PHY_MHDP_SEL(x)	(((x) & ((1 << 2) - 1)) << 3)
+
+#define F_HPD_GLITCH_WIDTH(x)		(((x) & ((1 << 8) - 1)) << 12)
+#define F_PACKET_TYPE(x)		(((x) & ((1 << 8) - 1)) << 8)
+#define F_HPD_VALID_WIDTH(x)		(((x) & ((1 << 12) - 1)) << 0)
+
+#define F_SOURCE_PHY_LANE3_SWAP(x)	(((x) & ((1 << 2) - 1)) << 6)
+#define F_SOURCE_PHY_LANE2_SWAP(x)	(((x) & ((1 << 2) - 1)) << 4)
+#define F_SOURCE_PHY_LANE1_SWAP(x)	(((x) & ((1 << 2) - 1)) << 2)
+#define F_SOURCE_PHY_LANE0_SWAP(x)	(((x) & ((1 << 2) - 1)) << 0)
+
+#define F_ACTIVE_IDLE_TYPE(x)		(((x) & ((1 << 1) - 1)) << 17)
+#define F_TYPE_VALID(x)			(((x) & ((1 << 1) - 1)) << 16)
+#define F_PKT_ALLOC_ADDRESS(x)		(((x) & ((1 << 4) - 1)) << 0)
+
+#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)
+
+/* 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 cdns_hdmi_i2c {
+	struct i2c_adapter	adap;
+
+	struct mutex		lock;	/* used to serialize data transfers */
+	struct completion	cmp;
+	u8			stat;
+
+	u8			slave_reg;
+	bool			is_regaddr;
+	bool			is_segment;
+};
+
+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;
+
+	int irq[IRQ_NUM];
+	struct delayed_work hotplug_work;
+	int connector_type;
+	u32 lane_mapping;
+
+	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;
+			struct cdns_hdmi_i2c *i2c;
+		} hdmi;
+	};
+};
+
+extern const struct drm_bridge_funcs cdns_dp_bridge_funcs;
+extern const struct drm_bridge_funcs cdns_hdmi_bridge_funcs;
+
+enum drm_connector_status
+cdns_mhdp8501_detect(struct drm_bridge *bridge);
+enum drm_mode_status
+cdns_mhdp8501_mode_valid(struct drm_bridge *bridge,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode);
+
+ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg);
+int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp);
+void cdns_dp_check_link_state(struct cdns_mhdp8501_device *mhdp);
+
+void cdns_hdmi_handle_hotplug(struct cdns_mhdp8501_device *mhdp);
+struct i2c_adapter *cdns_hdmi_i2c_adapter(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..157b4d44b9e2b
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
@@ -0,0 +1,694 @@
+// 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/media-bus-format.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,
+				const struct drm_display_mode *mode)
+{
+	struct video_info *video = &mhdp->video_info;
+	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;
+
+	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);
+
+	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;
+
+	/* start training */
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_TRAINING_CONTROL, sizeof(msg), &msg);
+	if (ret)
+		return ret;
+
+	timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
+	while (time_before(jiffies, timeout)) {
+		msleep(LINK_TRAINING_RETRY_MS);
+		ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX,
+						  DPTX_READ_EVENT,
+						  0, NULL, sizeof(event), event);
+		if (ret)
+			return ret;
+
+		if (event[1] & CLK_RECOVERY_FAILED)
+			dev_err(mhdp->dev, "clock recovery failed\n");
+		else if (event[1] & EQ_PHASE_FINISHED)
+			return 0;
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int cdns_dp_get_training_status(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 status[13];
+	int ret;
+
+	ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX,
+					  DPTX_READ_LINK_STAT,
+					  0, NULL, sizeof(status), status);
+	if (ret)
+		return ret;
+
+	mhdp->dp.rate = drm_dp_bw_code_to_link_rate(status[0]);
+	mhdp->dp.num_lanes = status[1];
+
+	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;
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_SET_HOST_CAPABILITIES,
+				     sizeof(msg), msg);
+	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;
+
+	for (i = 0; i < 4; i++) {
+		msg[0] = block / 2;
+		msg[1] = block % 2;
+
+		ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base,
+							MB_MODULE_ID_DP_TX,
+							DPTX_GET_EDID,
+							sizeof(msg), msg,
+							DPTX_GET_EDID,
+							sizeof(reg), reg,
+							length, edid);
+		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);
+
+	return ret;
+}
+
+static void cdns_dp_mode_set(struct cdns_mhdp8501_device *mhdp,
+			     const struct drm_display_mode *mode)
+{
+	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 = false;
+
+	ret = phy_configure(mhdp->phy, &phy_cfg);
+	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, mode);
+	if (ret)
+		dev_err(mhdp->dev, "Failed to config video %d\n", ret);
+}
+
+static bool
+cdns_dp_needs_link_retrain(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 link_status[DP_LINK_STATUS_SIZE];
+
+	if (drm_dp_dpcd_read_phy_link_status(&mhdp->dp.aux, DP_PHY_DPRX,
+					     link_status) < 0)
+		return false;
+
+	/* Retrain if link not ok */
+	return !drm_dp_channel_eq_ok(link_status, mhdp->dp.num_lanes);
+}
+
+void cdns_dp_check_link_state(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_connector *connector = mhdp->curr_conn;
+	const struct drm_edid *drm_edid;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+
+	if (!connector)
+		return;
+
+	/*
+	 * EDID data needs updating after each cable plugin
+	 * due to potential display monitor changes
+	 */
+	drm_edid = drm_edid_read_custom(connector, cdns_dp_get_edid_block, mhdp);
+	drm_edid_connector_update(connector, drm_edid);
+
+	if (!drm_edid)
+		return;
+
+	drm_edid_free(drm_edid);
+
+	conn_state = connector->state;
+	crtc = conn_state->crtc;
+	if (!crtc)
+		return;
+
+	crtc_state = crtc->state;
+	if (!crtc_state->active)
+		return;
+
+	if (!cdns_dp_needs_link_retrain(mhdp))
+		return;
+
+	/* DP link retrain */
+	if (cdns_dp_train_link(mhdp))
+		dev_err(mhdp->dev, "Failed link train\n");
+}
+
+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 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);
+}
+
+/* Currently supported format */
+static const u32 mhdp8501_input_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_RGB101010_1X30,
+};
+
+static u32 *cdns_dp_bridge_atomic_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)
+{
+	u32 *input_fmts;
+
+	*num_input_fmts = 0;
+
+	input_fmts = kcalloc(ARRAY_SIZE(mhdp8501_input_fmts),
+			     sizeof(*input_fmts),
+			     GFP_KERNEL);
+	if (!input_fmts)
+		return NULL;
+
+	*num_input_fmts = ARRAY_SIZE(mhdp8501_input_fmts);
+	memcpy(input_fmts, mhdp8501_input_fmts, sizeof(mhdp8501_input_fmts));
+
+	return input_fmts;
+}
+
+static int cdns_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 cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	struct video_info *video = &mhdp->video_info;
+
+	if (bridge_state->input_bus_cfg.format == MEDIA_BUS_FMT_RGB888_1X24) {
+		video->bpc = 8;
+		video->color_fmt = DRM_COLOR_FORMAT_RGB444;
+	} else if (bridge_state->input_bus_cfg.format == MEDIA_BUS_FMT_RGB101010_1X30) {
+		video->bpc = 10;
+		video->color_fmt = DRM_COLOR_FORMAT_RGB444;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+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;
+
+	phy_power_off(mhdp->phy);
+}
+
+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 drm_crtc_state *crtc_state;
+	struct drm_connector_state *conn_state;
+	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;
+
+	cdns_dp_mode_set(mhdp, &crtc_state->adjusted_mode);
+
+	/* Power up PHY before link training */
+	phy_power_on(mhdp->phy);
+
+	/* Link training */
+	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_mhdp8501_detect,
+	.edid_read = cdns_dp_bridge_edid_read,
+	.mode_valid = cdns_mhdp8501_mode_valid,
+	.atomic_enable = cdns_dp_bridge_atomic_enable,
+	.atomic_disable = cdns_dp_bridge_atomic_disable,
+	.atomic_get_input_bus_fmts = cdns_dp_bridge_atomic_get_input_bus_fmts,
+	.atomic_check = cdns_dp_bridge_atomic_check,
+	.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..9556d0929e21d
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
@@ -0,0 +1,745 @@
+// 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_hdmi_state_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_config_infoframe() - fill the HDMI infoframe
+ * @mhdp: phandle to mhdp device.
+ * @entry_id: The packet memory address in which the data is written.
+ * @len: length of infoframe.
+ * @buf: point to InfoFrame Packet.
+ * @type: Packet Type of InfoFrame in HDMI Specification.
+ *
+ */
+
+static void cdns_hdmi_clear_infoframe(struct cdns_mhdp8501_device *mhdp,
+				      u8 entry_id, u8 type)
+{
+	u32 val;
+
+	/* invalidate entry */
+	val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id) |
+	      F_PACKET_TYPE(type);
+	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 void cdns_hdmi_config_infoframe(struct cdns_mhdp8501_device *mhdp,
+				       u8 entry_id, u8 len,
+				       const u8 *buf, u8 type)
+{
+	u8 packet[32], packet_len = 32;
+	u32 packet32, len32;
+	u32 val, i;
+
+	/*
+	 * only support 32 bytes now
+	 * packet[0] = 0
+	 * packet[1-3] = HB[0-2]  InfoFrame Packet Header
+	 * packet[4-31 = PB[0-27] InfoFrame Packet Contents
+	 */
+	if (len >= (packet_len - 1))
+		return;
+	packet[0] = 0;
+	memcpy(packet + 1, buf, len);
+
+	cdns_hdmi_clear_infoframe(mhdp, entry_id, type);
+
+	/* 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(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;
+
+	for (i = 0; i < 4; i++) {
+		msg[0] = block / 2;
+		msg[1] = block % 2;
+
+		ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base,
+							MB_MODULE_ID_HDMI_TX,
+							HDMI_TX_EDID,
+							sizeof(msg), msg,
+							HDMI_TX_EDID,
+							sizeof(reg), reg,
+							length, edid);
+
+		if (ret)
+			continue;
+
+		if ((reg[3] << 8 | reg[4]) == length)
+			break;
+	}
+
+	if (ret)
+		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", block, ret);
+	return ret;
+}
+
+static int cdns_hdmi_set_hdmi_mode_type(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_connector_state *conn_state = mhdp->curr_conn->state;
+	u32 protocol = mhdp->hdmi.hdmi_type;
+	u32 val;
+
+	if (protocol == MODE_HDMI_2_0 &&
+	    conn_state->hdmi.tmds_char_rate >= 340000000) {
+		cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, 0);
+		cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, 0xFFFFF);
+	}
+
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+
+	/* set HDMI mode and preemble mode data enable */
+	val |= F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) |
+	       F_HDMI2_CTRL_IL_MODE(1);
+	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+}
+
+static int cdns_hdmi_ctrl_init(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 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;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, 0x7c1f);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, 0x7c1f);
+	if (ret < 0)
+		return ret;
+
+	/* init HDMI Controller */
+	val = F_BCH_EN(1) | F_PIC_3D(0xF) | F_CLEAR_AVMUTE(1);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	return cdns_hdmi_set_hdmi_mode_type(mhdp);
+}
+
+static int cdns_hdmi_mode_config(struct cdns_mhdp8501_device *mhdp,
+				 struct drm_display_mode *mode,
+				 struct drm_connector_hdmi_state *hdmi)
+{
+	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);
+	int ret;
+	u32 val;
+
+	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 (hdmi->output_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 (hdmi->output_format) {
+	case HDMI_COLORSPACE_YUV444:
+		val |= F_HDMI_ENCODING(2);
+		break;
+	case HDMI_COLORSPACE_YUV422:
+		val |= F_HDMI_ENCODING(1);
+		break;
+	case HDMI_COLORSPACE_YUV420:
+		val |= F_HDMI_ENCODING(3);
+		break;
+	case HDMI_COLORSPACE_RGB:
+	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);
+	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+}
+
+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);
+}
+
+#define HDMI_14_MAX_TMDS_CLK   (340 * 1000 * 1000)
+static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp,
+				  unsigned long long tmds_char_rate)
+{
+	struct drm_connector *connector = mhdp->curr_conn;
+	struct drm_display_info *display = &connector->display_info;
+	struct drm_scdc *scdc = &display->hdmi.scdc;
+	bool hdmi_scrambling = false;
+	bool hdmi_high_tmds_clock_ratio = false;
+
+	/* check sink type (HDMI or DVI) */
+	if (!display->is_hdmi) {
+		mhdp->hdmi.hdmi_type = MODE_DVI;
+		return;
+	}
+
+	/* Default work in HDMI1.4 */
+	mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;
+
+	/* check sink support SCDC or not */
+	if (!scdc->supported) {
+		dev_dbg(mhdp->dev, "Sink Not Support SCDC\n");
+		return;
+	}
+
+	if (tmds_char_rate > HDMI_14_MAX_TMDS_CLK) {
+		hdmi_scrambling = true;
+		hdmi_high_tmds_clock_ratio = true;
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	} else if (scdc->scrambling.low_rates) {
+		hdmi_scrambling = true;
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	}
+
+	/* Set TMDS bit clock ratio to 1/40 or 1/10, and enable/disable scrambling */
+	drm_scdc_set_high_tmds_clock_ratio(connector, hdmi_high_tmds_clock_ratio);
+	drm_scdc_set_scrambling(connector, hdmi_scrambling);
+}
+
+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 int reset_pipe(struct drm_crtc *crtc)
+{
+	struct drm_atomic_state *state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_modeset_acquire_ctx ctx;
+	int ret;
+
+	state = drm_atomic_state_alloc(crtc->dev);
+	if (!state)
+		return -ENOMEM;
+
+	drm_modeset_acquire_init(&ctx, 0);
+
+	state->acquire_ctx = &ctx;
+
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state)) {
+		ret = PTR_ERR(crtc_state);
+		goto out;
+	}
+
+	crtc_state->connectors_changed = true;
+
+	ret = drm_atomic_commit(state);
+out:
+	drm_atomic_state_put(state);
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+
+	return ret;
+}
+
+void cdns_hdmi_handle_hotplug(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_connector *connector = mhdp->curr_conn;
+	const struct drm_edid *drm_edid;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+
+	if (!connector)
+		return;
+
+	/*
+	 * EDID data needs updating after each cable plugin
+	 * due to potential display monitor changes
+	 */
+	drm_edid = drm_edid_read_custom(connector, cdns_hdmi_get_edid_block, mhdp);
+	drm_edid_connector_update(connector, drm_edid);
+
+	if (!drm_edid)
+		return;
+
+	drm_edid_free(drm_edid);
+
+	conn_state = connector->state;
+	crtc = conn_state->crtc;
+	if (!crtc)
+		return;
+
+	crtc_state = crtc->state;
+	if (!crtc_state->active)
+		return;
+
+	/*
+	 * HDMI 2.0 says that one should not send scrambled data
+	 * prior to configuring the sink scrambling, and that
+	 * TMDS clock/data transmission should be suspended when
+	 * changing the TMDS clock rate in the sink. So let's
+	 * just do a full modeset here, even though some sinks
+	 * would be perfectly happy if were to just reconfigure
+	 * the SCDC settings on the fly.
+	 */
+	reset_pipe(crtc);
+}
+
+static int cdns_hdmi_i2c_write(struct cdns_mhdp8501_device *mhdp,
+			       struct i2c_msg *msgs)
+{
+	u8 msg[5], reg[5];
+	int ret;
+
+	msg[0] = msgs->addr;
+	msg[1] = msgs->buf[0];
+	msg[2] = 0;
+	msg[3] = 1;
+	msg[4] = msgs->buf[1];
+
+	ret = cdns_mhdp_mailbox_send_recv(&mhdp->base,
+					  MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
+					  sizeof(msg), msg, sizeof(reg), reg);
+	if (ret) {
+		dev_err(mhdp->dev, "I2C write failed: %d\n", ret);
+		return ret;
+	}
+
+	if (reg[0] != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int cdns_hdmi_i2c_read(struct cdns_mhdp8501_device *mhdp,
+			      struct i2c_msg *msgs, int num)
+{
+	u8 msg[4], reg[5];
+	u8 addr, offset, *buf, len;
+	int ret, i;
+
+	for (i = 0; i < num; i++) {
+		if (msgs[i].flags & I2C_M_RD) {
+			addr = msgs[i].addr;
+			buf = msgs[i].buf;
+			len = msgs[i].len;
+		} else {
+			offset = msgs[i].buf[0];
+		}
+	}
+
+	msg[0] = addr;
+	msg[1] = offset;
+	put_unaligned_be16(len, msg + 2);
+
+	ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base,
+						MB_MODULE_ID_HDMI_TX, HDMI_TX_READ,
+						sizeof(msg), msg,
+						HDMI_TX_READ,
+						sizeof(reg), reg,
+						len, buf);
+	if (ret) {
+		dev_err(mhdp->dev, "I2c Read failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+#define  SCDC_I2C_SLAVE_ADDRESS	0x54
+static int cdns_hdmi_i2c_xfer(struct i2c_adapter *adap,
+			      struct i2c_msg *msgs, int num)
+{
+	struct cdns_mhdp8501_device *mhdp = i2c_get_adapdata(adap);
+	struct cdns_hdmi_i2c *i2c = mhdp->hdmi.i2c;
+	int i, ret = 0;
+
+	/*
+	 * MHDP FW provides mailbox APIs for SCDC registers access, but lacks direct I2C APIs.
+	 * While individual I2C registers can be read/written using HDMI general register APIs,
+	 * block reads (e.g., EDID) are not supported, making it a limited I2C interface.
+	 */
+	for (i = 0; i < num; i++) {
+		if (msgs[i].addr != SCDC_I2C_SLAVE_ADDRESS) {
+			dev_err(mhdp->dev, "ADDR=%0x is not supported\n", msgs[i].addr);
+			return -EINVAL;
+		}
+	}
+
+	mutex_lock(&i2c->lock);
+
+	if (num == 1)
+		ret = cdns_hdmi_i2c_write(mhdp, msgs);
+	else
+		ret = cdns_hdmi_i2c_read(mhdp, msgs, num);
+
+	if (!ret)
+		ret = num;
+
+	mutex_unlock(&i2c->lock);
+
+	return ret;
+}
+
+static u32 cdns_hdmi_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm cdns_hdmi_algorithm = {
+	.master_xfer	= cdns_hdmi_i2c_xfer,
+	.functionality	= cdns_hdmi_i2c_func,
+};
+
+struct i2c_adapter *cdns_hdmi_i2c_adapter(struct cdns_mhdp8501_device *mhdp)
+{
+	struct i2c_adapter *adap;
+	struct cdns_hdmi_i2c *i2c;
+	int ret;
+
+	i2c = devm_kzalloc(mhdp->dev, sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&i2c->lock);
+
+	adap = &i2c->adap;
+	adap->owner = THIS_MODULE;
+	adap->dev.parent = mhdp->dev;
+	adap->algo = &cdns_hdmi_algorithm;
+	strscpy(adap->name, "MHDP HDMI", sizeof(adap->name));
+	i2c_set_adapdata(adap, mhdp);
+
+	ret = i2c_add_adapter(adap);
+	if (ret) {
+		dev_warn(mhdp->dev, "cannot add %s I2C adapter\n", adap->name);
+		devm_kfree(mhdp->dev, i2c);
+		return ERR_PTR(ret);
+	}
+
+	mhdp->hdmi.i2c = i2c;
+
+	return adap;
+}
+
+static enum drm_mode_status
+cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
+			       const struct drm_display_mode *mode,
+			       unsigned long long tmds_rate)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
+
+	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
+	if (ret < 0)
+		return MODE_CLOCK_RANGE;
+
+	return MODE_OK;
+}
+
+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;
+
+	phy_power_off(mhdp->phy);
+}
+
+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;
+	struct drm_connector_hdmi_state *hdmi;
+	union phy_configure_opts phy_cfg;
+	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;
+
+	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
+
+	/* Line swapping */
+	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
+
+	hdmi = &conn_state->hdmi;
+	if (WARN_ON(!hdmi))
+		return;
+
+	phy_cfg.hdmi.tmds_char_rate = hdmi->tmds_char_rate;
+	ret = phy_configure(mhdp->phy, &phy_cfg);
+	if (ret) {
+		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+			__func__, ret);
+		return;
+	}
+
+	phy_power_on(mhdp->phy);
+
+	cdns_hdmi_sink_config(mhdp, hdmi->tmds_char_rate);
+
+	ret = cdns_hdmi_ctrl_init(mhdp);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "hdmi ctrl init failed = %d\n",  ret);
+		return;
+	}
+
+	/* Config GCP */
+	if (hdmi->output_bpc == 8)
+		cdns_hdmi_disable_gcp(mhdp);
+	else
+		cdns_hdmi_enable_gcp(mhdp);
+
+	ret = cdns_hdmi_mode_config(mhdp, &crtc_state->adjusted_mode, hdmi);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
+		return;
+	}
+}
+
+static int cdns_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AVI:
+		cdns_hdmi_clear_infoframe(mhdp, 0, HDMI_INFOFRAME_TYPE_AVI);
+		break;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		cdns_hdmi_clear_infoframe(mhdp, 1, HDMI_INFOFRAME_TYPE_SPD);
+		break;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		cdns_hdmi_clear_infoframe(mhdp, 2, HDMI_INFOFRAME_TYPE_VENDOR);
+		break;
+	default:
+		dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n", type);
+	}
+
+	return 0;
+}
+
+static int cdns_hdmi_bridge_write_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type,
+					    const u8 *buffer, size_t len)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AVI:
+		cdns_hdmi_config_infoframe(mhdp, 0, len, buffer, HDMI_INFOFRAME_TYPE_AVI);
+		break;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		cdns_hdmi_config_infoframe(mhdp, 1, len, buffer, HDMI_INFOFRAME_TYPE_SPD);
+		break;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		cdns_hdmi_config_infoframe(mhdp, 2, len, buffer, HDMI_INFOFRAME_TYPE_VENDOR);
+		break;
+	default:
+		dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n", type);
+	}
+
+	return 0;
+}
+
+static int cdns_hdmi_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)
+{
+	return drm_atomic_helper_connector_hdmi_check(conn_state->connector, conn_state->state);
+}
+
+const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
+	.attach = cdns_hdmi_bridge_attach,
+	.detect = cdns_mhdp8501_detect,
+	.edid_read = cdns_hdmi_bridge_edid_read,
+	.mode_valid = cdns_mhdp8501_mode_valid,
+	.atomic_enable = cdns_hdmi_bridge_atomic_enable,
+	.atomic_disable = cdns_hdmi_bridge_atomic_disable,
+	.atomic_check = cdns_hdmi_bridge_atomic_check,
+	.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,
+	.hdmi_clear_infoframe = cdns_hdmi_bridge_clear_infoframe,
+	.hdmi_write_infoframe = cdns_hdmi_bridge_write_infoframe,
+	.hdmi_tmds_char_rate_valid = cdns_hdmi_tmds_char_rate_valid,
+};
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Dec 16 22:51:48 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:48 +0800
Subject: [PATCH v20 6/9] dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
In-Reply-To: <cover.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <1f01892a4e462d451a21ddcb4b114283d998cd1b.1734340233.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->v20:
 *No change.

 .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  | 51 +++++++++++++++++++
 1 file changed, 51 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..c17a645e71bad
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
@@ -0,0 +1,51 @@
+# 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:
+    const: fsl,imx8mq-hdptx-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-hdptx-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 Dec 16 22:51:49 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:49 +0800
Subject: [PATCH v20 7/9] phy: freescale: Add DisplayPort/HDMI Combo-PHY driver for i.MX8MQ
In-Reply-To: <cover.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <f85a57a2657ffe0e7334b7a7982ebcb3c4889eec.1734340233.git.Sandor.yu@nxp.com>

Add Cadence HDP-TX DisplayPort and 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.
DisplayPort or HDMI PHY mode is configured in the driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
v19->v20:
- implify DP configuration handling by directly copying
  the configuration options to the driver's internal structure.
- return the error code directly instead of logging an error message in `hdptx_clk_enable`
- Remove redundant ref_clk_rate check

v18->v19:
- Simplify the PLL tables by removing unused and constant data
- Remove PHY power management, controller driver will handle them.
- Remove enum dp_link_rate
- Introduce read_pll_timeout.
- Update clock management as devm_clk_get_enabled() introduced.
- Remove cdns_hdptx_phy_init() and cdns_hdptx_phy_remove().

v17->v18:
- fix build error as code rebase to latest kernel version.

 drivers/phy/freescale/Kconfig                |   10 +
 drivers/phy/freescale/Makefile               |    1 +
 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c | 1231 ++++++++++++++++++
 3 files changed, 1242 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index dcd9acff6d01a..2b1210367b31c 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_HDPTX
+	tristate "Freescale i.MX8MQ DP/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 DP/HDMI PHY driver
+	  on i.MX8MQ SOC.
+
 config PHY_FSL_IMX8QM_HSIO
 	tristate "Freescale i.MX8QM HSIO PHY"
 	depends on OF && HAS_IOMEM
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index 658eac7d0a622..a946b87905498 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_HDPTX)	+= phy-fsl-imx8mq-hdptx.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-hdptx.c b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
new file mode 100644
index 0000000000000..230b7148639b2
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdptx.c
@@ -0,0 +1,1231 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence DP/HDMI PHY driver
+ *
+ * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
+ */
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/unaligned.h>
+#include <soc/cadence/cdns-mhdp-helper.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_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_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_CTRL			0x00e0
+#define CMN_TXPUCAL_INIT_TMR			0x00e4
+#define CMN_TXPUCAL_ITER_TMR			0x00e5
+#define CMN_TXPDCAL_CTRL			0x00f0
+#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_CTRL			0x0108
+#define CMN_TXPU_ADJ_INIT_TMR			0x010a
+#define CMN_TXPU_ADJ_ITER_TMR			0x010b
+#define CMN_TXPD_ADJ_CTRL			0x010c
+#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_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 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_HSCLK_SEL			0x40e1
+#define XCVR_DIAG_BIDI_CTRL			0x40e8
+#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_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_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_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				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)
+#define HSCLK_PLL0_DIV2				1
+
+/* 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)
+#define DPLL_DATA_RATE_DIV_MODE3_MASK		GENMASK(13, 12)
+
+/* 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
+
+/* FW check alive timeout */
+#define CDNS_KEEP_ALIVE_TIMEOUT		2000
+#define CDNS_KEEP_ALIVE_MASK		GENMASK(7, 0)
+
+#define REF_CLK_27MHZ		27000000
+
+#define LINK_RATE_2_7	270000
+#define MAX_LINK_RATE	540000
+
+#define CMN_REF_CLK_DIG_DIV	1
+#define REF_CLK_DIVIDER_SCALER	1
+
+/* HDMI TX clock control settings */
+struct hdptx_hdmi_ctrl {
+	u32 pixel_clk_freq;
+	u32 feedback_factor;
+	u32 cmnda_pll0_ip_div;
+	u32 pll_fb_div_total;
+	u32 cmnda_pll0_fb_div_low;
+	u32 cmnda_pll0_fb_div_high;
+	u32 cmnda_pll0_pxdiv_low;
+	u32 cmnda_pll0_pxdiv_high;
+	u32 vco_ring_select;
+	u32 cmnda_hs_clk_0_sel;
+	u32 cmnda_hs_clk_1_sel;
+	u32 hsclk_div_tx_sub_rate;
+	u32 cmnda_pll0_hs_sym_div_sel;
+};
+
+struct cdns_hdptx_phy {
+	struct cdns_mhdp_base base;
+
+	void __iomem *regs;	/* DPTX registers base */
+	struct device *dev;
+	struct phy *phy;
+	struct clk *ref_clk, *apb_clk;
+	u32 ref_clk_rate;
+	union {
+		struct phy_configure_opts_hdmi hdmi;
+		struct phy_configure_opts_dp dp;
+	};
+};
+
+/* HDMI TX clock control settings, pixel clock is output */
+static const struct hdptx_hdmi_ctrl pixel_clk_output_ctrl_table[] = {
+	/*  clk   fbak ipd totl div_l  div_h pd_l  pd_h  v h1 h2 sub sym*/
+	{  27000, 1000, 3, 240, 0x0bc, 0x30, 0x26, 0x26, 0, 2, 2, 4, 3 },
+	{  27000, 1250, 3, 300, 0x0ec, 0x3c, 0x30, 0x30, 0, 2, 2, 4, 3 },
+	{  27000, 1500, 3, 360, 0x11c, 0x48, 0x3a, 0x3a, 0, 2, 2, 4, 3 },
+	{  27000, 2000, 3, 240, 0x0bc, 0x30, 0x26, 0x26, 0, 2, 2, 4, 2 },
+	{  54000, 1000, 3, 480, 0x17c, 0x60, 0x26, 0x26, 1, 2, 2, 4, 3 },
+	{  54000, 1250, 4, 400, 0x13c, 0x50, 0x17, 0x17, 0, 1, 1, 4, 2 },
+	{  54000, 1500, 4, 480, 0x17c, 0x60, 0x1c, 0x1c, 0, 2, 2, 2, 2 },
+	{  54000, 2000, 3, 240, 0x0bc, 0x30, 0x12, 0x12, 0, 2, 2, 1, 1 },
+	{  74250, 1000, 3, 660, 0x20c, 0x84, 0x26, 0x26, 1, 2, 2, 4, 3 },
+	{  74250, 1250, 4, 550, 0x1b4, 0x6e, 0x17, 0x17, 1, 1, 1, 4, 2 },
+	{  74250, 1500, 4, 660, 0x20c, 0x84, 0x1c, 0x1c, 1, 2, 2, 2, 2 },
+	{  74250, 2000, 3, 330, 0x104, 0x42, 0x12, 0x12, 0, 2, 2, 1, 1 },
+	{  99000, 1000, 3, 440, 0x15c, 0x58, 0x12, 0x12, 1, 2, 2, 2, 2 },
+	{  99000, 1250, 3, 275, 0x0d8, 0x37, 0x0b, 0x0a, 0, 1, 1, 2, 1 },
+	{  99000, 1500, 3, 330, 0x104, 0x42, 0x0d, 0x0d, 0, 2, 2, 1, 1 },
+	{  99000, 2000, 3, 440, 0x15c, 0x58, 0x12, 0x12, 1, 2, 2, 1, 1 },
+	{ 148500, 1000, 3, 660, 0x20c, 0x84, 0x12, 0x12, 1, 2, 2, 2, 2 },
+	{ 148500, 1250, 4, 550, 0x1b4, 0x6e, 0x0b, 0x0a, 1, 1, 1, 2, 1 },
+	{ 148500, 1500, 3, 495, 0x188, 0x63, 0x0d, 0x0d, 1, 1, 1, 2, 1 },
+	{ 148500, 2000, 3, 660, 0x20c, 0x84, 0x12, 0x12, 1, 2, 2, 1, 1 },
+	{ 198000, 1000, 3, 220, 0x0ac, 0x2c, 0x03, 0x03, 0, 1, 1, 1, 0 },
+	{ 198000, 1250, 3, 550, 0x1b4, 0x6e, 0x0b, 0x0a, 1, 1, 1, 2, 1 },
+	{ 198000, 1500, 3, 330, 0x104, 0x42, 0x06, 0x05, 0, 1, 1, 1, 0 },
+	{ 198000, 2000, 3, 440, 0x15c, 0x58, 0x08, 0x08, 1, 1, 1, 1, 0 },
+	{ 297000, 1000, 3, 330, 0x104, 0x42, 0x03, 0x03, 0, 1, 1, 1, 0 },
+	{ 297000, 1500, 3, 495, 0x188, 0x63, 0x06, 0x05, 1, 1, 1, 1, 0 },
+	{ 297000, 2000, 3, 660, 0x20c, 0x84, 0x08, 0x08, 1, 1, 1, 1, 0 },
+	{ 594000, 1000, 3, 660, 0x20c, 0x84, 0x03, 0x03, 1, 1, 1, 1, 0 },
+	{ 594000,  750, 3, 495, 0x188, 0x63, 0x03, 0x03, 1, 1, 1, 1, 0 },
+	{ 594000,  625, 4, 550, 0x1b4, 0x6e, 0x03, 0x03, 1, 1, 1, 1, 0 },
+	{ 594000,  500, 3, 660, 0x20c, 0x84, 0x03, 0x03, 1, 1, 1, 2, 1 },
+};
+
+/* HDMI TX PLL tuning settings */
+struct hdptx_hdmi_pll_tuning {
+	u32 vco_freq;
+	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 vco_cal_code;
+};
+
+/* HDMI TX PLL tuning settings, pixel clock is output */
+static const struct hdptx_hdmi_pll_tuning pixel_clk_output_pll_table[] = {
+	/*VCO_f  coar cu nd pm ptat fd_d gain  cal */
+	{ 1980000, 4, 3, 0, 9, 0x9, 220, 0x42, 183 },
+	{ 2160000, 4, 3, 0, 9, 0x9, 240, 0x42, 208 },
+	{ 2475000, 5, 3, 1, 0, 0x7, 275, 0x42, 209 },
+	{ 2700000, 5, 3, 1, 0, 0x7, 300, 0x42, 230 },
+	{ 2700000, 5, 3, 1, 0, 0x7, 400, 0x4c, 230 },
+	{ 2970000, 6, 3, 1, 0, 0x7, 330, 0x42, 225 },
+	{ 3240000, 6, 3, 1, 0, 0x7, 360, 0x42, 256 },
+	{ 3240000, 6, 3, 1, 0, 0x7, 480, 0x4c, 256 },
+	{ 3712500, 4, 3, 0, 7, 0xF, 550, 0x4c, 257 },
+	{ 3960000, 5, 3, 0, 7, 0xF, 440, 0x42, 226 },
+	{ 4320000, 5, 3, 1, 7, 0xF, 480, 0x42, 258 },
+	{ 4455000, 5, 3, 0, 7, 0xF, 495, 0x42, 272 },
+	{ 4455000, 5, 3, 0, 7, 0xF, 660, 0x4c, 272 },
+	{ 4950000, 6, 3, 1, 0, 0x7, 550, 0x42, 258 },
+	{ 5940000, 7, 3, 1, 0, 0x7, 660, 0x42, 292 },
+};
+
+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 }
+};
+
+static int dp_link_rate_index(u32 rate)
+{
+	switch (rate) {
+	case 162000:
+		return 0;
+	case 216000:
+		return 1;
+	case 243000:
+		return 2;
+	case 270000:
+		return 3;
+	case 324000:
+		return 4;
+	case 432000:
+		return 5;
+	case 540000:
+		return 6;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int cdns_phy_reg_write(struct cdns_hdptx_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_phy *cdns_phy, u32 addr)
+{
+	u32 reg32;
+
+	cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), &reg32);
+
+	return reg32;
+}
+
+static void hdptx_dp_aux_cfg(struct cdns_hdptx_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_phy *cdns_phy)
+{
+	u32 num_lanes = cdns_phy->dp.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_phy *cdns_phy)
+{
+	u32 num_lanes = cdns_phy->dp.lanes;
+	u32 link_rate = cdns_phy->dp.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 <= LINK_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 <= LINK_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 <= LINK_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 = dp_link_rate_index(link_rate);
+	if (index < 0) {
+		dev_err(cdns_phy->dev, "Not support link rate %d\n", link_rate);
+		return;
+	}
+
+	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 <= LINK_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_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_phy *cdns_phy,
+			u32 reg, u32 mask,
+			const char *err_msg)
+{
+	int ret;
+	u32 val;
+
+	ret = read_poll_timeout(cdns_phy_reg_read,
+				val, val & mask, 20, 1000,
+				false, cdns_phy, reg);
+	if (ret < 0)
+		dev_err(cdns_phy->dev, "%s\n", err_msg);
+
+	return ret;
+}
+
+static int wait_for_ack_clear(struct cdns_hdptx_phy *cdns_phy,
+			      u32 reg, u32 mask,
+			      const char *err_msg)
+{
+	int ret;
+	u32 val;
+
+	ret = read_poll_timeout(cdns_phy_reg_read,
+				val, !(val & mask), 20, 1000,
+				false, cdns_phy, reg);
+	if (ret < 0)
+		dev_err(cdns_phy->dev, "%s\n", err_msg);
+
+	return ret;
+}
+
+static int hdptx_dp_phy_power_up(struct cdns_hdptx_phy *cdns_phy)
+{
+	u32 val;
+	int ret;
+
+	/* 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);
+
+	return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK,
+			   "Wait A0 Ack failed");
+}
+
+static int hdptx_dp_phy_power_down(struct cdns_hdptx_phy *cdns_phy)
+{
+	u16 val;
+	int ret;
+
+	/* Place the PHY lanes in the A3 power state. */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK,
+			   "Wait A3 Ack failed");
+	if (ret)
+		return ret;
+
+	/* 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);
+	ret = wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_CLK_EN_ACK,
+				 "Wait PLL clock Ack clear failed");
+	if (ret)
+		return ret;
+
+	/* 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);
+
+	return  wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_READY,
+				 "Wait PLL Ack clear failed");
+}
+
+static int hdptx_dp_configure(struct phy *phy,
+			      union phy_configure_opts *opts)
+{
+	const struct phy_configure_opts_dp *dp_opts = &opts->dp;
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+
+	if (opts->dp.link_rate > MAX_LINK_RATE) {
+		dev_err(cdns_phy->dev, "Link Rate(%d) Not supported\n", opts->dp.link_rate);
+		return false;
+	}
+
+	memcpy(&cdns_phy->dp, dp_opts, sizeof(*dp_opts));
+
+	hdptx_dp_phy_pma_cmn_cfg_27mhz(cdns_phy);
+	hdptx_dp_phy_pma_cmn_pll0_27mhz(cdns_phy);
+
+	return 0;
+}
+
+static int hdptx_clk_enable(struct cdns_hdptx_phy *cdns_phy)
+{
+	struct device *dev = cdns_phy->dev;
+	u32 ref_clk_rate;
+
+	cdns_phy->ref_clk =  devm_clk_get_enabled(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);
+	}
+
+	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");
+		return -EINVAL;
+	}
+
+	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);
+		return -EINVAL;
+	}
+
+	cdns_phy->apb_clk =  devm_clk_get_enabled(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);
+	}
+
+	return 0;
+}
+
+static void hdptx_hdmi_arc_config(struct cdns_hdptx_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_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_phy_config(struct cdns_hdptx_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, 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, 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_phy *cdns_phy, unsigned long long char_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 char_rate_khz = char_rate / 1000;
+	u32 vco_freq, rate;
+	u32 div_total, i;
+
+	dev_dbg(cdns_phy->dev, "character clock: %d KHz\n ", char_rate_khz);
+
+	/* Get right row from the ctrl_table table.
+	 * check the character rate.
+	 */
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++) {
+		rate = pixel_clk_output_ctrl_table[i].feedback_factor *
+		       pixel_clk_output_ctrl_table[i].pixel_clk_freq / 1000;
+		if (char_rate_khz == rate) {
+			p_ctrl_table = &pixel_clk_output_ctrl_table[i];
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(pixel_clk_output_ctrl_table)) {
+		dev_warn(cdns_phy->dev,
+			 "char clk (%d KHz) not supported\n", char_rate_khz);
+		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 &&
+		    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_phy *cdns_phy)
+{
+	int ret;
+
+	/* 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_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 hdptx_hdmi_configure(struct phy *phy,
+				union phy_configure_opts *opts)
+{
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+	u32 reg;
+	int ret;
+
+	cdns_phy->hdmi.tmds_char_rate = opts->hdmi.tmds_char_rate;
+
+	/* Check HDMI FW alive before HDMI PHY init */
+	ret = readl_poll_timeout(cdns_phy->regs + KEEP_ALIVE, reg,
+				 reg & CDNS_KEEP_ALIVE_MASK, 500,
+				 CDNS_KEEP_ALIVE_TIMEOUT);
+	if (ret < 0) {
+		dev_err(cdns_phy->dev, "NO HDMI FW running\n");
+		return -ENXIO;
+	}
+
+	/* Configure PHY */
+	if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->hdmi.tmds_char_rate) < 0) {
+		dev_err(cdns_phy->dev, "failed to set phy pclock\n");
+		return -EINVAL;
+	}
+
+	hdptx_hdmi_phy_set_vswing(cdns_phy);
+
+	return 0;
+}
+
+static int cdns_hdptx_phy_on(struct phy *phy)
+{
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+
+	if (phy->attrs.mode == PHY_MODE_DP)
+		return hdptx_dp_phy_power_up(cdns_phy);
+	else
+		return hdptx_hdmi_phy_power_up(cdns_phy);
+}
+
+static int cdns_hdptx_phy_off(struct phy *phy)
+{
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+
+	if (phy->attrs.mode == PHY_MODE_DP)
+		return hdptx_dp_phy_power_down(cdns_phy);
+	else
+		return hdptx_hdmi_phy_power_down(cdns_phy);
+}
+
+static int
+cdns_hdptx_phy_valid(struct phy *phy, enum phy_mode mode,
+		     int submode, union phy_configure_opts *opts)
+{
+	u32 rate = opts->hdmi.tmds_char_rate / 1000;
+	int i;
+
+	if (mode == PHY_MODE_DP)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++)
+		if (rate == pixel_clk_output_ctrl_table[i].pixel_clk_freq)
+			return 0;
+
+	return -EINVAL;
+}
+
+static int cdns_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct cdns_hdptx_phy *cdns_phy = phy_get_drvdata(phy);
+	int ret = 0;
+
+	if (mode == PHY_MODE_DP) {
+		hdptx_dp_phy_ref_clock_type(cdns_phy);
+		hdptx_dp_aux_cfg(cdns_phy);
+	} else if (mode != PHY_MODE_HDMI) {
+		dev_err(&phy->dev, "Invalid PHY mode: %u\n", mode);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int cdns_hdptx_configure(struct phy *phy,
+				union phy_configure_opts *opts)
+{
+	if (phy->attrs.mode == PHY_MODE_DP)
+		return hdptx_dp_configure(phy, opts);
+	else
+		return hdptx_hdmi_configure(phy, opts);
+}
+
+static const struct phy_ops cdns_hdptx_phy_ops = {
+	.set_mode = cdns_hdptx_phy_set_mode,
+	.configure = cdns_hdptx_configure,
+	.power_on = cdns_hdptx_phy_on,
+	.power_off = cdns_hdptx_phy_off,
+	.validate = cdns_hdptx_phy_valid,
+	.owner = THIS_MODULE,
+};
+
+static int cdns_hdptx_phy_probe(struct platform_device *pdev)
+{
+	struct cdns_hdptx_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;
+
+	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_phy_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	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;
+
+	ret = hdptx_clk_enable(cdns_phy);
+	if (ret)
+		return -EINVAL;
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
+
+	return 0;
+}
+
+static const struct of_device_id cdns_hdptx_phy_of_match[] = {
+	{.compatible = "fsl,imx8mq-hdptx-phy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cdns_hdptx_phy_of_match);
+
+static struct platform_driver cdns_hdptx_phy_driver = {
+	.probe = cdns_hdptx_phy_probe,
+	.driver = {
+		.name	= "cdns-hdptx-phy",
+		.of_match_table	= cdns_hdptx_phy_of_match,
+	}
+};
+module_platform_driver(cdns_hdptx_phy_driver);
+
+MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("Cadence HDP-TX DP/HDMI PHY driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Dec 16 22:51:50 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:50 +0800
Subject: [PATCH v20 8/9] arm64: dts: imx8mq: Add DCSS + HDMI/DP display pipeline
In-Reply-To: <cover.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <b730433022fc3af7b271827e86fc4193229862e7.1734340233.git.Sandor.yu@nxp.com>

From: Alexander Stein <alexander.stein at ew.tq-group.com>

This adds DCSS + MHDP + MHDP PHY nodes. PHY mode (DP/HDMI) is selected
by the connector type connected to mhdp port at 1 endpoint.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
v17->v20:
 *No change

 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 68 +++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index d51de8d899b2b..df8ba1d5391ae 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1602,6 +1602,74 @@ aips4: bus at 32c00000 { /* AIPS4 */
 			#size-cells = <1>;
 			ranges = <0x32c00000 0x32c00000 0x400000>;
 
+			mdhp_phy: phy at 32c00000 {
+				compatible = "fsl,imx8mq-hdptx-phy";
+				reg = <0x32c00000 0x100000>;
+				#phy-cells = <0>;
+				clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+				clock-names = "ref", "apb";
+			};
+
+			mhdp: 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 = <&mdhp_phy>;
+				status = "disabled";
+
+				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 {
+						};
+					};
+				};
+			};
+
+			dcss: display-controller at 32e00000 {
+				compatible = "nxp,imx8mq-dcss";
+				reg = <0x32e00000 0x2d000>, <0x32e2f000 0x1000>;
+				interrupt-parent = <&irqsteer>;
+				interrupts = <6>, <8>, <9>;
+				interrupt-names = "ctxld", "ctxld_kick", "vblank";
+				clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>,
+					 <&clk IMX8MQ_CLK_DISP_AXI_ROOT>,
+					 <&clk IMX8MQ_CLK_DISP_RTRM_ROOT>,
+					 <&clk IMX8MQ_VIDEO2_PLL_OUT>,
+					 <&clk IMX8MQ_CLK_DISP_DTRC>;
+				clock-names = "apb", "axi", "rtrm", "pix", "dtrc";
+				assigned-clocks = <&clk IMX8MQ_CLK_DISP_AXI>,
+						  <&clk IMX8MQ_CLK_DISP_RTRM>,
+						  <&clk IMX8MQ_VIDEO2_PLL1_REF_SEL>;
+				assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>,
+							 <&clk IMX8MQ_SYS1_PLL_800M>,
+							 <&clk IMX8MQ_CLK_27M>;
+				assigned-clock-rates = <800000000>,
+						       <400000000>;
+				status = "disabled";
+
+				port {
+					dcss_out: endpoint {
+						remote-endpoint = <&mhdp_in>;
+					};
+				};
+			};
+
 			irqsteer: interrupt-controller at 32e2d000 {
 				compatible = "fsl,imx8m-irqsteer", "fsl,imx-irqsteer";
 				reg = <0x32e2d000 0x1000>;
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Dec 16 22:51:45 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:45 +0800
Subject: [PATCH v20 3/9] phy: Add HDMI configuration options
In-Reply-To: <cover.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <d1cff6c03ec3732d2244022029245ab2d954d997.1734340233.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>
Reviewed-by: Maxime Ripard <mripard at kernel.org>
Acked-by: Vinod Koul <vkoul at kernel.org>
---
v19->v20:
- Add a-b tag.

v17->v19:
 *No change.

v16->v17:
- remove headfile hdmi.h
- add 2024 year to copyright
- Add r-b tag.

 include/linux/phy/phy-hdmi.h | 19 +++++++++++++++++++
 include/linux/phy/phy.h      |  7 ++++++-
 2 files changed, 25 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..6a696922bc7f2
--- /dev/null
+++ b/include/linux/phy/phy-hdmi.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022,2024 NXP
+ */
+
+#ifndef __PHY_HDMI_H_
+#define __PHY_HDMI_H_
+
+/**
+ * struct phy_configure_opts_hdmi - HDMI configuration set
+ * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
+ *
+ * This structure is used to represent the configuration state of a HDMI phy.
+ */
+struct phy_configure_opts_hdmi {
+	unsigned long long tmds_char_rate;
+};
+
+#endif /* __PHY_HDMI_H_ */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 03cd5bae92d3f..4ac486b101fe4 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 Dec 16 22:51:43 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 17 Dec 2024 14:51:43 +0800
Subject: [PATCH v20 1/9] soc: cadence: Create helper functions for Cadence MHDP
In-Reply-To: <cover.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <7fd5d54e2594aadd66598888ddf512f3d6d30e5d.1734340233.git.Sandor.yu@nxp.com>

Cadence MHDP IP includes a firmware. Driver and firmware communicate
through a mailbox. The basic mailbox access functions in this patch
are derived from the DRM bridge MHDP8546 driver.
New mailbox access functions have been created based on different mailbox
return values and security types, making them reusable across different
MHDP driver versions and SOCs.

These helper fucntions will be reused in both the DRM bridge driver MDHP8501
and the i.MX8MQ HDPTX PHY driver.

Six mailbox access helper functions are introduced.
Three for non-secure mailbox access:
 - cdns_mhdp_mailbox_send()
 - cdns_mhdp_mailbox_send_recv()
 - cdns_mhdp_mailbox_send_recv_multi()
The other three for secure mailbox access:
 - cdns_mhdp_secure_mailbox_send()
 - cdns_mhdp_secure_mailbox_send_recv()
 - cdns_mhdp_secure_mailbox_send_recv_multi()

All MHDP commands that need to be passed through the mailbox
should be rewritten using these new helper functions.

The register read/write and DP DPCD read/write command functions
are also included in this new helper driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
---
v19->v20:
- new patch in v20.
  The patch split from Patch #1 in v19 and move to a new folder drivers/soc/cadence

 drivers/soc/Kconfig                    |   1 +
 drivers/soc/Makefile                   |   1 +
 drivers/soc/cadence/Kconfig            |   9 +
 drivers/soc/cadence/Makefile           |   3 +
 drivers/soc/cadence/cdns-mhdp-helper.c | 565 +++++++++++++++++++++++++
 include/soc/cadence/cdns-mhdp-helper.h | 129 ++++++
 6 files changed, 708 insertions(+)
 create mode 100644 drivers/soc/cadence/Kconfig
 create mode 100644 drivers/soc/cadence/Makefile
 create mode 100644 drivers/soc/cadence/cdns-mhdp-helper.c
 create mode 100644 include/soc/cadence/cdns-mhdp-helper.h

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 6a8daeb8c4b96..f6c18114b2d68 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -6,6 +6,7 @@ source "drivers/soc/apple/Kconfig"
 source "drivers/soc/aspeed/Kconfig"
 source "drivers/soc/atmel/Kconfig"
 source "drivers/soc/bcm/Kconfig"
+source "drivers/soc/cadence/Kconfig"
 source "drivers/soc/canaan/Kconfig"
 source "drivers/soc/cirrus/Kconfig"
 source "drivers/soc/fsl/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 2037a8695cb28..a5fa4f4d15321 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -7,6 +7,7 @@ obj-y				+= apple/
 obj-y				+= aspeed/
 obj-$(CONFIG_ARCH_AT91)		+= atmel/
 obj-y				+= bcm/
+obj-y				+= cadence/
 obj-$(CONFIG_ARCH_CANAAN)	+= canaan/
 obj-$(CONFIG_EP93XX_SOC)        += cirrus/
 obj-$(CONFIG_ARCH_DOVE)		+= dove/
diff --git a/drivers/soc/cadence/Kconfig b/drivers/soc/cadence/Kconfig
new file mode 100644
index 0000000000000..b668790660fa5
--- /dev/null
+++ b/drivers/soc/cadence/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config CDNS_MHDP_HELPER
+	tristate "Cadence MHDP Helper driver"
+	help
+	  Enable Cadence MHDP helpers for mailbox, HDMI and DP.
+	  This driver provides a foundational layer of mailbox communication for
+	  various Cadence MHDP IP implementations, such as HDMI and DisplayPort.
+
diff --git a/drivers/soc/cadence/Makefile b/drivers/soc/cadence/Makefile
new file mode 100644
index 0000000000000..a1f42e1936ca5
--- /dev/null
+++ b/drivers/soc/cadence/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
diff --git a/drivers/soc/cadence/cdns-mhdp-helper.c b/drivers/soc/cadence/cdns-mhdp-helper.c
new file mode 100644
index 0000000000000..f74b4cae134a2
--- /dev/null
+++ b/drivers/soc/cadence/cdns-mhdp-helper.c
@@ -0,0 +1,565 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <linux/dev_printk.h>
+#include <linux/module.h>
+#include <soc/cadence/cdns-mhdp-helper.h>
+
+/* Protects mailbox communications with the firmware */
+static DEFINE_MUTEX(mhdp_mailbox_mutex);
+
+/* Mailbox helper functions */
+static int mhdp_mailbox_read(void __iomem *regs)
+{
+	int ret, empty;
+
+	WARN_ON(!mutex_is_locked(&mhdp_mailbox_mutex));
+
+	ret = readx_poll_timeout(readl, regs + CDNS_MAILBOX_EMPTY,
+				 empty, !empty, MAILBOX_RETRY_US,
+				 MAILBOX_TIMEOUT_US);
+	if (ret < 0)
+		return ret;
+
+	return readl(regs + CDNS_MAILBOX_RX_DATA) & 0xff;
+}
+
+static int mhdp_mailbox_write(void __iomem *regs, u8 val)
+{
+	int ret, full;
+
+	WARN_ON(!mutex_is_locked(&mhdp_mailbox_mutex));
+
+	ret = readx_poll_timeout(readl, regs + CDNS_MAILBOX_FULL,
+				 full, !full, MAILBOX_RETRY_US,
+				 MAILBOX_TIMEOUT_US);
+	if (ret < 0)
+		return ret;
+
+	writel(val, regs + CDNS_MAILBOX_TX_DATA);
+
+	return 0;
+}
+
+static int mhdp_mailbox_recv_header(void __iomem *regs,
+				    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 = mhdp_mailbox_read(regs);
+		if (ret < 0)
+			return ret;
+
+		header[i] = ret;
+	}
+
+	mbox_size = get_unaligned_be16(header + 2);
+
+	/*
+	 * If the message in mailbox is not what we want, we need to
+	 * clear the mailbox by reading its contents.
+	 * Response data length for HDCP TX HDCP_TRAN_IS_REC_ID_VALID depend on case.
+	 */
+	if (opcode != header[0] ||
+	    module_id != header[1] ||
+	   (opcode != HDCP_TRAN_IS_REC_ID_VALID && req_size != mbox_size)) {
+		for (i = 0; i < mbox_size; i++)
+			if (mhdp_mailbox_read(regs) < 0)
+				break;
+
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mhdp_mailbox_recv_data(void __iomem *regs,
+				  u8 *buff, u16 buff_size)
+{
+	u32 i;
+	int ret;
+
+	for (i = 0; i < buff_size; i++) {
+		ret = mhdp_mailbox_read(regs);
+		if (ret < 0)
+			return ret;
+
+		buff[i] = ret;
+	}
+
+	return 0;
+}
+
+static int mhdp_mailbox_send(void __iomem *regs, 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 = mhdp_mailbox_write(regs, header[i]);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < size; i++) {
+		ret = mhdp_mailbox_write(regs, message[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * cdns_mhdp_mailbox_send - Sends a message via the MHDP mailbox.
+ *
+ * This function sends a message via the MHDP mailbox.
+ *
+ * @base: Pointer to the CDNS MHDP base structure.
+ * @module_id: ID of the module to send the message to.
+ * @opcode: Operation code of the message.
+ * @size: Size of the message data.
+ * @message: Pointer to the message data.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base, u8 module_id,
+			   u8 opcode, u16 size, u8 *message)
+{
+	guard(mutex)(&mhdp_mailbox_mutex);
+
+	return mhdp_mailbox_send(base->regs, module_id, opcode, size, message);
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_send);
+
+/**
+ * cdns_mhdp_mailbox_send_recv - Sends a message and receives a response.
+ *
+ * This function sends a message via the mailbox and then receives a response.
+ *
+ * @base: Pointer to the CDNS MHDP base structure.
+ * @module_id: ID of the module to send the message to.
+ * @opcode: Operation code of the message.
+ * @msg_size: Size of the message data.
+ * @msg: Pointer to the message data.
+ * @resp_size: Size of the response buffer.
+ * @resp: Pointer to the response buffer.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int cdns_mhdp_mailbox_send_recv(struct cdns_mhdp_base *base,
+				u8 module_id, u8 opcode,
+				u16 msg_size, u8 *msg,
+				u16 resp_size, u8 *resp)
+{
+	int ret;
+
+	guard(mutex)(&mhdp_mailbox_mutex);
+
+	ret = mhdp_mailbox_send(base->regs, module_id,
+				opcode, msg_size, msg);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, CMD=%d send failed: %d\n",
+			module_id, opcode, ret);
+		return ret;
+	}
+
+	ret = mhdp_mailbox_recv_header(base->regs, module_id,
+				       opcode, resp_size);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, CMD=%d recv header failed: %d\n",
+			module_id, opcode, ret);
+		return ret;
+	}
+
+	ret = mhdp_mailbox_recv_data(base->regs, resp, resp_size);
+	if (ret)
+		dev_err(base->dev, "ModuleID=%d, CMD=%d recv data failed: %d\n",
+			module_id, opcode, ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_send_recv);
+
+/**
+ * cdns_mhdp_mailbox_send_recv_multi - Sends a message and receives multiple responses.
+ *
+ * This function sends a message to a specified module via the MHDP mailbox and
+ * then receives multiple responses from the module.
+ *
+ * @param base: Pointer to the CDNS MHDP base structure.
+ * @param module_id: ID of the module to send the message to.
+ * @param opcode: Operation code of the message.
+ * @param msg_size: Size of the message data.
+ * @param msg: Pointer to the message data.
+ * @param opcode_resp: Operation code of the response.
+ * @param resp1_size: Size of the first response buffer.
+ * @param resp1: Pointer to the first response buffer.
+ * @param resp2_size: Size of the second response buffer.
+ * @param resp2: Pointer to the second response buffer.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int cdns_mhdp_mailbox_send_recv_multi(struct cdns_mhdp_base *base,
+				      u8 module_id, u8 opcode,
+				      u16 msg_size, u8 *msg,
+				      u8 opcode_resp,
+				      u16 resp1_size, u8 *resp1,
+				      u16 resp2_size, u8 *resp2)
+{
+	int ret;
+
+	guard(mutex)(&mhdp_mailbox_mutex);
+
+	ret = mhdp_mailbox_send(base->regs, module_id,
+				opcode, msg_size, msg);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, CMD=%d send failed: %d\n",
+			module_id, opcode, ret);
+		return ret;
+	}
+
+	ret = mhdp_mailbox_recv_header(base->regs, module_id, opcode_resp,
+				       resp1_size + resp2_size);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv header failed: %d\n",
+			module_id, opcode_resp, ret);
+		return ret;
+	}
+
+	ret = mhdp_mailbox_recv_data(base->regs, resp1, resp1_size);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv data1 failed: %d\n",
+			module_id, opcode_resp, ret);
+		return ret;
+	}
+
+	ret = mhdp_mailbox_recv_data(base->regs, resp2, resp2_size);
+	if (ret)
+		dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv data1 failed: %d\n",
+			module_id, opcode_resp, ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_send_recv_multi);
+
+/**
+ * cdns_mhdp_secure_mailbox_send - Sends a secure message via the mailbox.
+ *
+ * This function sends a secure message to a specified module via the MHDP mailbox.
+ *
+ * @param base: Pointer to the CDNS MHDP base structure.
+ * @param module_id: ID of the module to send the message to.
+ * @param opcode: Operation code of the message.
+ * @param size: Size of the message data.
+ * @param message: Pointer to the message data.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_base *base, u8 module_id,
+				  u8 opcode, u16 size, u8 *message)
+{
+	guard(mutex)(&mhdp_mailbox_mutex);
+
+	return mhdp_mailbox_send(base->sapb_regs, module_id, opcode, size, message);
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_secure_mailbox_send);
+
+/**
+ * cdns_mhdp_secure_mailbox_send_recv - Sends a secure message and receives a response.
+ *
+ * This function sends a secure message to a specified module via the mailbox and
+ * then receives a response from the module.
+ *
+ * @param base: Pointer to the CDNS MHDP base structure.
+ * @param module_id: ID of the module to send the message to.
+ * @param opcode: Operation code of the message.
+ * @param msg_size: Size of the message data.
+ * @param msg: Pointer to the message data.
+ * @param resp_size: Size of the response buffer.
+ * @param resp: Pointer to the response buffer.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int cdns_mhdp_secure_mailbox_send_recv(struct cdns_mhdp_base *base,
+				       u8 module_id, u8 opcode,
+				       u16 msg_size, u8 *msg,
+				       u16 resp_size, u8 *resp)
+{
+	int ret;
+
+	guard(mutex)(&mhdp_mailbox_mutex);
+
+	ret = mhdp_mailbox_send(base->sapb_regs, module_id,
+				opcode, msg_size, msg);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, CMD=%d send failed: %d\n",
+			module_id, opcode, ret);
+		return ret;
+	}
+
+	ret = mhdp_mailbox_recv_header(base->sapb_regs, module_id,
+				       opcode, resp_size);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, CMD=%d recv header failed: %d\n",
+			module_id, opcode, ret);
+		return ret;
+	}
+
+	ret = mhdp_mailbox_recv_data(base->sapb_regs, resp, resp_size);
+	if (ret)
+		dev_err(base->dev, "ModuleID=%d, CMD=%d recv data failed: %d\n",
+			module_id, opcode, ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_secure_mailbox_send_recv);
+
+/**
+ * cdns_mhdp_secure_mailbox_send_recv_multi - Sends a secure message and receives multiple responses.
+ *
+ * This function sends a secure message to a specified module and receives multiple responses.
+ *
+ * @param base: Pointer to the CDNS MHDP base structure.
+ * @param module_id: ID of the module to send the message to.
+ * @param opcode: Operation code of the message.
+ * @param msg_size: Size of the message data.
+ * @param msg: Pointer to the message data.
+ * @param opcode_resp: Operation code of the response.
+ * @param resp1_size: Size of the first response buffer.
+ * @param resp1: Pointer to the first response buffer.
+ * @param resp2_size: Size of the second response buffer.
+ * @param resp2: Pointer to the second response buffer.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int cdns_mhdp_secure_mailbox_send_recv_multi(struct cdns_mhdp_base *base,
+					     u8 module_id, u8 opcode,
+					     u16 msg_size, u8 *msg,
+					     u8 opcode_resp,
+					     u16 resp1_size, u8 *resp1,
+					     u16 resp2_size, u8 *resp2)
+{
+	int ret;
+
+	guard(mutex)(&mhdp_mailbox_mutex);
+
+	ret = mhdp_mailbox_send(base->sapb_regs, module_id,
+				opcode, msg_size, msg);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, CMD=%d send failed: %d\n",
+			module_id, opcode, ret);
+		return ret;
+	}
+
+	ret = mhdp_mailbox_recv_header(base->sapb_regs, module_id,
+				       opcode_resp,
+				       resp1_size + resp2_size);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv header failed: %d\n",
+			module_id, opcode_resp, ret);
+		return ret;
+	}
+
+	ret = mhdp_mailbox_recv_data(base->sapb_regs, resp1, resp1_size);
+	if (ret) {
+		dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv data1 failed: %d\n",
+			module_id, opcode_resp, ret);
+		return ret;
+	}
+
+	/*
+	 * Response data length for HDCP TX HDCP_TRAN_IS_REC_ID_VALID depend on
+	 * the number of HDCP receivers in resp1[0].
+	 * 1 for regular case, more can be in repeater.
+	 */
+	if (module_id == MB_MODULE_ID_HDCP_TX &&
+	    opcode == HDCP_TRAN_IS_REC_ID_VALID)
+		ret = mhdp_mailbox_recv_data(base->sapb_regs, resp2, 5 * resp1[0]);
+	else
+		ret = mhdp_mailbox_recv_data(base->sapb_regs, resp2, resp2_size);
+	if (ret)
+		dev_err(base->dev, "ModuleID=%d, Resp_CMD=%d recv data2 failed: %d\n",
+			module_id, opcode_resp, ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_secure_mailbox_send_recv_multi);
+
+/**
+ * cdns_mhdp_reg_read - Reads a general register value.
+ *
+ * This function reads the value from a general register
+ * using the mailbox.
+ *
+ * @param base: Pointer to the CDNS MHDP base structure.
+ * @param addr: Address of the register to read.
+ * @param value: Pointer to store the read value.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+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);
+
+	ret = cdns_mhdp_mailbox_send_recv(base, MB_MODULE_ID_GENERAL,
+					  GENERAL_REGISTER_READ,
+					  sizeof(msg), msg, sizeof(resp), 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:
+	if (ret) {
+		dev_err(base->dev, "Failed to read register\n");
+		*value = 0;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_read);
+
+/**
+ * cdns_mhdp_reg_write - Writes a value to a general register.
+ *
+ * This function writes a value to a general register using the mailbox.
+ *
+ * @param base: Pointer to the CDNS MHDP base structure.
+ * @param addr: Address of the register to write to.
+ * @param val: Value to write to the register.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int cdns_mhdp_reg_write(struct cdns_mhdp_base *base, u32 addr, u32 val)
+{
+	u8 msg[8];
+
+	put_unaligned_be32(addr, msg);
+	put_unaligned_be32(val, msg + 4);
+
+	return cdns_mhdp_mailbox_send(base, MB_MODULE_ID_GENERAL,
+				     GENERAL_REGISTER_WRITE,
+				     sizeof(msg), msg);
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_write);
+
+/* DPTX helper functions */
+/**
+ * cdns_mhdp_dp_reg_write_bit - Writes a bit field to a DP register.
+ *
+ * This function writes a specific bit field within a DP register
+ * using the MHDP mailbox.
+ *
+ * @param base: Pointer to the CDNS MHDP base structure.
+ * @param addr: Address of the DP register.
+ * @param start_bit: Starting bit position within the register.
+ * @param bits_no: Number of bits to write.
+ * @param val: Value to write to the bit field.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+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];
+
+	put_unaligned_be16(addr, field);
+	field[2] = start_bit;
+	field[3] = bits_no;
+	put_unaligned_be32(val, field + 4);
+
+	return cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				      DPTX_WRITE_FIELD, sizeof(field), field);
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dp_reg_write_bit);
+
+/**
+ * cdns_mhdp_dpcd_read - Reads data from a DPCD register.
+ *
+ * This function reads data from a specified DPCD register
+ * using the MHDP mailbox.
+ *
+ * @param base: Pointer to the CDNS MHDP base structure.
+ * @param addr: Address of the DPCD register to read.
+ * @param data: Buffer to store the read data.
+ * @param len: Length of the data to read.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int cdns_mhdp_dpcd_read(struct cdns_mhdp_base *base,
+			u32 addr, u8 *data, u16 len)
+{
+	u8 msg[5], reg[5];
+
+	put_unaligned_be16(len, msg);
+	put_unaligned_be24(addr, msg + 2);
+
+	return cdns_mhdp_mailbox_send_recv_multi(base,
+						 MB_MODULE_ID_DP_TX,
+						 DPTX_READ_DPCD,
+						 sizeof(msg), msg,
+						 DPTX_READ_DPCD,
+						 sizeof(reg), reg,
+						 len, data);
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dpcd_read);
+
+/**
+ * cdns_mhdp_dpcd_write - Writes data to a DPCD register.
+ *
+ * This function writes data to a specified DPCD register
+ * using the MHDP mailbox.
+ *
+ * @param base: Pointer to the CDNS MHDP base structure.
+ * @param addr: Address of the DPCD register to write to.
+ * @param value: Value to write to the register.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+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;
+
+	ret = cdns_mhdp_mailbox_send_recv(base, MB_MODULE_ID_DP_TX,
+					  DPTX_WRITE_DPCD,
+					  sizeof(msg), msg, sizeof(reg), reg);
+	if (ret) {
+		dev_err(base->dev, "dpcd write failed: %d\n", ret);
+		return ret;
+	}
+
+	if (addr != get_unaligned_be24(reg + 2)) {
+		dev_err(base->dev, "Invalid response: expected address 0x%06x, got 0x%06x\n",
+			addr, get_unaligned_be24(reg + 2));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+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/include/soc/cadence/cdns-mhdp-helper.h b/include/soc/cadence/cdns-mhdp-helper.h
new file mode 100644
index 0000000000000..25b9737de615f
--- /dev/null
+++ b/include/soc/cadence/cdns-mhdp-helper.h
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023-2024 NXP Semiconductor, Inc.
+ */
+#ifndef __CDNS_MHDP_HELPER_H__
+#define __CDNS_MHDP_HELPER_H__
+
+#include <linux/iopoll.h>
+#include <linux/unaligned.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
+
+/* HDCP TX Commands */
+#define HDCP_TRAN_CONFIGURATION			0x00
+#define HDCP2X_TX_SET_PUBLIC_KEY_PARAMS		0x01
+#define HDCP2X_TX_SET_DEBUG_RANDOM_NUMBERS	0x02
+#define HDCP2X_TX_RESPOND_KM			0x03
+#define HDCP1_TX_SEND_KEYS			0x04
+#define HDCP1_TX_SEND_RANDOM_AN			0x05
+#define HDCP_TRAN_STATUS_CHANGE			0x06
+#define HDCP2X_TX_IS_KM_STORED			0x07
+#define HDCP2X_TX_STORE_KM			0x08
+#define HDCP_TRAN_IS_REC_ID_VALID		0x09
+#define HDCP_TRAN_RESPOND_RECEIVER_ID_VALID	0x09
+#define HDCP_TRAN_TEST_KEYS			0x0a
+#define HDCP2X_TX_SET_KM_KEY_PARAMS		0x0b
+#define HDCP_NUM_OF_SUPPORTED_MESSAGES		0x0c
+
+struct cdns_mhdp_base {
+	struct device *dev;
+	void __iomem *regs;
+	void __iomem *sapb_regs;
+};
+
+/* Mailbox helper functions */
+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base,
+			   u8 module_id, u8 opcode,
+			   u16 size, u8 *message);
+int cdns_mhdp_mailbox_send_recv(struct cdns_mhdp_base *base,
+				u8 module_id, u8 opcode,
+				u16 msg_size, u8 *msg,
+				u16 resp_size, u8 *resp);
+int cdns_mhdp_mailbox_send_recv_multi(struct cdns_mhdp_base *base,
+				      u8 module_id, u8 opcode,
+				      u16 msg_size, u8 *msg,
+				      u8 opcode_resp,
+				      u16 resp1_size, u8 *resp1,
+				      u16 resp2_size, u8 *resp2);
+
+/* Secure mailbox helper functions */
+int cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_base *base,
+				  u8 module_id, u8 opcode,
+				  u16 size, u8 *message);
+int cdns_mhdp_secure_mailbox_send_recv(struct cdns_mhdp_base *base,
+				       u8 module_id, u8 opcode,
+				       u16 msg_size, u8 *msg,
+				       u16 resp_size, u8 *resp);
+int cdns_mhdp_secure_mailbox_send_recv_multi(struct cdns_mhdp_base *base,
+					     u8 module_id, u8 opcode,
+					     u16 msg_size, u8 *msg,
+					     u8 opcode_resp,
+					     u16 resp1_size, u8 *resp1,
+					     u16 resp2_size, u8 *resp2);
+
+/* 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_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 wsa+renesas at sang-engineering.com  Mon Dec 16 23:13:26 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Tue, 17 Dec 2024 08:13:26 +0100
Subject: [PATCH] rtc: use boolean values with device_init_wakeup()
Message-ID: <20241217071331.3607-2-wsa+renesas@sang-engineering.com>

device_init_wakeup() second argument is a bool type. Use proper boolean
values when calling it to match the type and to produce unambiguous code
which is easier to understand.

Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
---
Created with a coccinelle script. I opted for a single patch because the change
is rather trivial. I can break out per driver if this is desired. If you
like the change at all, that is.

 drivers/rtc/rtc-88pm80x.c       | 2 +-
 drivers/rtc/rtc-88pm860x.c      | 2 +-
 drivers/rtc/rtc-amlogic-a4.c    | 6 +++---
 drivers/rtc/rtc-armada38x.c     | 2 +-
 drivers/rtc/rtc-as3722.c        | 2 +-
 drivers/rtc/rtc-at91rm9200.c    | 2 +-
 drivers/rtc/rtc-at91sam9.c      | 2 +-
 drivers/rtc/rtc-cadence.c       | 2 +-
 drivers/rtc/rtc-cmos.c          | 2 +-
 drivers/rtc/rtc-cpcap.c         | 2 +-
 drivers/rtc/rtc-cros-ec.c       | 2 +-
 drivers/rtc/rtc-da9055.c        | 2 +-
 drivers/rtc/rtc-ds3232.c        | 2 +-
 drivers/rtc/rtc-isl1208.c       | 2 +-
 drivers/rtc/rtc-jz4740.c        | 2 +-
 drivers/rtc/rtc-loongson.c      | 4 ++--
 drivers/rtc/rtc-lp8788.c        | 2 +-
 drivers/rtc/rtc-lpc32xx.c       | 2 +-
 drivers/rtc/rtc-max77686.c      | 2 +-
 drivers/rtc/rtc-max8925.c       | 2 +-
 drivers/rtc/rtc-max8997.c       | 2 +-
 drivers/rtc/rtc-meson-vrtc.c    | 2 +-
 drivers/rtc/rtc-mpc5121.c       | 2 +-
 drivers/rtc/rtc-mt6397.c        | 2 +-
 drivers/rtc/rtc-mv.c            | 4 ++--
 drivers/rtc/rtc-mxc.c           | 2 +-
 drivers/rtc/rtc-mxc_v2.c        | 2 +-
 drivers/rtc/rtc-omap.c          | 2 +-
 drivers/rtc/rtc-palmas.c        | 2 +-
 drivers/rtc/rtc-pic32.c         | 2 +-
 drivers/rtc/rtc-pm8xxx.c        | 2 +-
 drivers/rtc/rtc-pxa.c           | 2 +-
 drivers/rtc/rtc-rc5t583.c       | 2 +-
 drivers/rtc/rtc-rc5t619.c       | 2 +-
 drivers/rtc/rtc-renesas-rtca3.c | 2 +-
 drivers/rtc/rtc-rk808.c         | 2 +-
 drivers/rtc/rtc-s3c.c           | 2 +-
 drivers/rtc/rtc-s5m.c           | 2 +-
 drivers/rtc/rtc-sa1100.c        | 2 +-
 drivers/rtc/rtc-sc27xx.c        | 4 ++--
 drivers/rtc/rtc-sh.c            | 2 +-
 drivers/rtc/rtc-spear.c         | 4 ++--
 drivers/rtc/rtc-sun6i.c         | 2 +-
 drivers/rtc/rtc-sunplus.c       | 4 ++--
 drivers/rtc/rtc-tegra.c         | 2 +-
 drivers/rtc/rtc-test.c          | 2 +-
 drivers/rtc/rtc-tps6586x.c      | 2 +-
 drivers/rtc/rtc-tps65910.c      | 2 +-
 drivers/rtc/rtc-twl.c           | 2 +-
 drivers/rtc/rtc-wm831x.c        | 2 +-
 drivers/rtc/rtc-wm8350.c        | 2 +-
 drivers/rtc/rtc-xgene.c         | 4 ++--
 drivers/rtc/rtc-zynqmp.c        | 4 ++--
 53 files changed, 62 insertions(+), 62 deletions(-)

diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c
index 5c39cf252392..a3e52a5a708f 100644
--- a/drivers/rtc/rtc-88pm80x.c
+++ b/drivers/rtc/rtc-88pm80x.c
@@ -308,7 +308,7 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
 	/* remember whether this power up is caused by PMIC RTC or not */
 	info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup;
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	return 0;
 out_rtc:
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index 814230d61842..964cd048fcdb 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -326,7 +326,7 @@ static int pm860x_rtc_probe(struct platform_device *pdev)
 	schedule_delayed_work(&info->calib_work, VRTC_CALIB_INTERVAL);
 #endif	/* VRTC_CALIBRATION */
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	return 0;
 }
diff --git a/drivers/rtc/rtc-amlogic-a4.c b/drivers/rtc/rtc-amlogic-a4.c
index 2278b4c98a71..09d78c2cc691 100644
--- a/drivers/rtc/rtc-amlogic-a4.c
+++ b/drivers/rtc/rtc-amlogic-a4.c
@@ -361,7 +361,7 @@ static int aml_rtc_probe(struct platform_device *pdev)
 				     "failed to get_enable rtc sys clk\n");
 	aml_rtc_init(rtc);
 
-	device_init_wakeup(dev, 1);
+	device_init_wakeup(dev, true);
 	platform_set_drvdata(pdev, rtc);
 
 	rtc->rtc_dev = devm_rtc_allocate_device(dev);
@@ -391,7 +391,7 @@ static int aml_rtc_probe(struct platform_device *pdev)
 	return 0;
 err_clk:
 	clk_disable_unprepare(rtc->sys_clk);
-	device_init_wakeup(dev, 0);
+	device_init_wakeup(dev, false);
 
 	return ret;
 }
@@ -426,7 +426,7 @@ static void aml_rtc_remove(struct platform_device *pdev)
 	struct aml_rtc_data *rtc = dev_get_drvdata(&pdev->dev);
 
 	clk_disable_unprepare(rtc->sys_clk);
-	device_init_wakeup(&pdev->dev, 0);
+	device_init_wakeup(&pdev->dev, false);
 }
 
 static const struct aml_rtc_config a5_rtc_config = {
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index 569c1054d6b0..713fa0d077cd 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -527,7 +527,7 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, rtc);
 
 	if (rtc->irq != -1)
-		device_init_wakeup(&pdev->dev, 1);
+		device_init_wakeup(&pdev->dev, true);
 	else
 		clear_bit(RTC_FEATURE_ALARM, rtc->rtc_dev->features);
 
diff --git a/drivers/rtc/rtc-as3722.c b/drivers/rtc/rtc-as3722.c
index 0f21af27f4cf..9682d6457b7f 100644
--- a/drivers/rtc/rtc-as3722.c
+++ b/drivers/rtc/rtc-as3722.c
@@ -187,7 +187,7 @@ static int as3722_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	as3722_rtc->rtc = devm_rtc_device_register(&pdev->dev, "as3722-rtc",
 				&as3722_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 9b3898b8de7c..f6b0102a843a 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -528,7 +528,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
 	 * being wake-capable; if it didn't, do that here.
 	 */
 	if (!device_can_wakeup(&pdev->dev))
-		device_init_wakeup(&pdev->dev, 1);
+		device_init_wakeup(&pdev->dev, true);
 
 	if (at91_rtc_config->has_correction)
 		rtc->ops = &sama5d4_rtc_ops;
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 15b21da2788f..38991cca5930 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -353,7 +353,7 @@ static int at91_rtc_probe(struct platform_device *pdev)
 
 	/* platform setup code should have handled this; sigh */
 	if (!device_can_wakeup(&pdev->dev))
-		device_init_wakeup(&pdev->dev, 1);
+		device_init_wakeup(&pdev->dev, true);
 
 	platform_set_drvdata(pdev, rtc);
 
diff --git a/drivers/rtc/rtc-cadence.c b/drivers/rtc/rtc-cadence.c
index bf2a9a1fdea7..8634eea799ab 100644
--- a/drivers/rtc/rtc-cadence.c
+++ b/drivers/rtc/rtc-cadence.c
@@ -359,7 +359,7 @@ static void cdns_rtc_remove(struct platform_device *pdev)
 	struct cdns_rtc *crtc = platform_get_drvdata(pdev);
 
 	cdns_rtc_alarm_irq_enable(&pdev->dev, 0);
-	device_init_wakeup(&pdev->dev, 0);
+	device_init_wakeup(&pdev->dev, false);
 
 	clk_disable_unprepare(crtc->pclk);
 	clk_disable_unprepare(crtc->ref_clk);
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 78f2ce12c75a..4bd3a3a04d44 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -864,7 +864,7 @@ static void acpi_cmos_wake_setup(struct device *dev)
 		dev_info(dev, "RTC can wake from S4\n");
 
 	/* RTC always wakes from S1/S2/S3, and often S4/STD */
-	device_init_wakeup(dev, 1);
+	device_init_wakeup(dev, true);
 }
 
 static void cmos_check_acpi_rtc_status(struct device *dev,
diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c
index afc8fcba8f88..568a89e79c11 100644
--- a/drivers/rtc/rtc-cpcap.c
+++ b/drivers/rtc/rtc-cpcap.c
@@ -295,7 +295,7 @@ static int cpcap_rtc_probe(struct platform_device *pdev)
 	}
 	disable_irq(rtc->update_irq);
 
-	err = device_init_wakeup(dev, 1);
+	err = device_init_wakeup(dev, true);
 	if (err) {
 		dev_err(dev, "wakeup initialization failed (%d)\n", err);
 		/* ignore error and continue without wakeup support */
diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c
index 60a48c3ba3ca..865c2e82c7a5 100644
--- a/drivers/rtc/rtc-cros-ec.c
+++ b/drivers/rtc/rtc-cros-ec.c
@@ -337,7 +337,7 @@ static int cros_ec_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = device_init_wakeup(&pdev->dev, 1);
+	ret = device_init_wakeup(&pdev->dev, true);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to initialize wakeup\n");
 		return ret;
diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c
index 844168fcae1e..05adec6b77bf 100644
--- a/drivers/rtc/rtc-da9055.c
+++ b/drivers/rtc/rtc-da9055.c
@@ -288,7 +288,7 @@ static int da9055_rtc_probe(struct platform_device *pdev)
 	if (ret & DA9055_RTC_ALM_EN)
 		rtc->alarm_enable = 1;
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 					&da9055_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index dd37b055693c..19c09c418746 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -508,7 +508,7 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
 		return ret;
 
 	if (ds3232->irq > 0)
-		device_init_wakeup(dev, 1);
+		device_init_wakeup(dev, true);
 
 	ds3232_hwmon_register(dev, name);
 
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index 7b82e4a14b7a..f71a6bb77b2a 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -830,7 +830,7 @@ static int isl1208_setup_irq(struct i2c_client *client, int irq)
 					isl1208_driver.driver.name,
 					client);
 	if (!rc) {
-		device_init_wakeup(&client->dev, 1);
+		device_init_wakeup(&client->dev, true);
 		enable_irq_wake(irq);
 	} else {
 		dev_err(&client->dev,
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c
index bafa7d1b9b88..44bba356268c 100644
--- a/drivers/rtc/rtc-jz4740.c
+++ b/drivers/rtc/rtc-jz4740.c
@@ -367,7 +367,7 @@ static int jz4740_rtc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, rtc);
 
-	device_init_wakeup(dev, 1);
+	device_init_wakeup(dev, true);
 
 	ret = dev_pm_set_wake_irq(dev, irq);
 	if (ret)
diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c
index 8d713e563d7c..6f5f4430c2ae 100644
--- a/drivers/rtc/rtc-loongson.c
+++ b/drivers/rtc/rtc-loongson.c
@@ -329,7 +329,7 @@ static int loongson_rtc_probe(struct platform_device *pdev)
 					     alarm_irq);
 
 		priv->pm_base = regs - priv->config->pm_offset;
-		device_init_wakeup(dev, 1);
+		device_init_wakeup(dev, true);
 
 		if (has_acpi_companion(dev))
 			acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
@@ -360,7 +360,7 @@ static void loongson_rtc_remove(struct platform_device *pdev)
 		acpi_remove_fixed_event_handler(ACPI_EVENT_RTC,
 						loongson_rtc_handler);
 
-	device_init_wakeup(dev, 0);
+	device_init_wakeup(dev, false);
 	loongson_rtc_alarm_irq_enable(dev, 0);
 }
 
diff --git a/drivers/rtc/rtc-lp8788.c b/drivers/rtc/rtc-lp8788.c
index c0b8fbce1082..0793d70507f7 100644
--- a/drivers/rtc/rtc-lp8788.c
+++ b/drivers/rtc/rtc-lp8788.c
@@ -293,7 +293,7 @@ static int lp8788_rtc_probe(struct platform_device *pdev)
 	rtc->alarm = lp->pdata ? lp->pdata->alarm_sel : DEFAULT_ALARM_SEL;
 	platform_set_drvdata(pdev, rtc);
 
-	device_init_wakeup(dev, 1);
+	device_init_wakeup(dev, true);
 
 	rtc->rdev = devm_rtc_device_register(dev, "lp8788_rtc",
 					&lp8788_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c
index 76ad7031a13d..74280bffe1b0 100644
--- a/drivers/rtc/rtc-lpc32xx.c
+++ b/drivers/rtc/rtc-lpc32xx.c
@@ -257,7 +257,7 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev)
 			dev_warn(&pdev->dev, "Can't request interrupt.\n");
 			rtc->irq = -1;
 		} else {
-			device_init_wakeup(&pdev->dev, 1);
+			device_init_wakeup(&pdev->dev, true);
 		}
 	}
 
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index a8f4b645c09d..7bb044d2ac25 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -770,7 +770,7 @@ static int max77686_rtc_probe(struct platform_device *pdev)
 		goto err_rtc;
 	}
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	info->rtc_dev = devm_rtc_device_register(&pdev->dev, id->name,
 					&max77686_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c
index 64bb8ac6ef62..6ce8afbeac68 100644
--- a/drivers/rtc/rtc-max8925.c
+++ b/drivers/rtc/rtc-max8925.c
@@ -270,7 +270,7 @@ static int max8925_rtc_probe(struct platform_device *pdev)
 	/* XXX - isn't this redundant? */
 	platform_set_drvdata(pdev, info);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max8925-rtc",
 					&max8925_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c
index 20e50d9fdf88..e7618d715bd8 100644
--- a/drivers/rtc/rtc-max8997.c
+++ b/drivers/rtc/rtc-max8997.c
@@ -473,7 +473,7 @@ static int max8997_rtc_probe(struct platform_device *pdev)
 	max8997_rtc_enable_wtsr(info, true);
 	max8997_rtc_enable_smpl(info, true);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max8997-rtc",
 					&max8997_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-meson-vrtc.c b/drivers/rtc/rtc-meson-vrtc.c
index 648fa362ec44..5849729f7d01 100644
--- a/drivers/rtc/rtc-meson-vrtc.c
+++ b/drivers/rtc/rtc-meson-vrtc.c
@@ -74,7 +74,7 @@ static int meson_vrtc_probe(struct platform_device *pdev)
 	if (IS_ERR(vrtc->io_alarm))
 		return PTR_ERR(vrtc->io_alarm);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	platform_set_drvdata(pdev, vrtc);
 
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
index 600328131603..b90f8337a7e6 100644
--- a/drivers/rtc/rtc-mpc5121.c
+++ b/drivers/rtc/rtc-mpc5121.c
@@ -303,7 +303,7 @@ static int mpc5121_rtc_probe(struct platform_device *op)
 		return PTR_ERR(rtc->regs);
 	}
 
-	device_init_wakeup(&op->dev, 1);
+	device_init_wakeup(&op->dev, true);
 
 	platform_set_drvdata(op, rtc);
 
diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
index 152699219a2b..6979d225a78e 100644
--- a/drivers/rtc/rtc-mt6397.c
+++ b/drivers/rtc/rtc-mt6397.c
@@ -286,7 +286,7 @@ static int mtk_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	rtc->rtc_dev->ops = &mtk_rtc_ops;
 	rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900;
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index 51029c536244..c27ad626d09f 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -264,7 +264,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
 	}
 
 	if (pdata->irq >= 0)
-		device_init_wakeup(&pdev->dev, 1);
+		device_init_wakeup(&pdev->dev, true);
 	else
 		clear_bit(RTC_FEATURE_ALARM, pdata->rtc->features);
 
@@ -287,7 +287,7 @@ static void __exit mv_rtc_remove(struct platform_device *pdev)
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 
 	if (pdata->irq >= 0)
-		device_init_wakeup(&pdev->dev, 0);
+		device_init_wakeup(&pdev->dev, false);
 
 	if (!IS_ERR(pdata->clk))
 		clk_disable_unprepare(pdata->clk);
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index dbb935dbbd8a..608db97d450c 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -377,7 +377,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
 	}
 
 	if (pdata->irq >= 0) {
-		device_init_wakeup(&pdev->dev, 1);
+		device_init_wakeup(&pdev->dev, true);
 		ret = dev_pm_set_wake_irq(&pdev->dev, pdata->irq);
 		if (ret)
 			dev_err(&pdev->dev, "failed to enable irq wake\n");
diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c
index 13c041bb79f1..570f27af4732 100644
--- a/drivers/rtc/rtc-mxc_v2.c
+++ b/drivers/rtc/rtc-mxc_v2.c
@@ -302,7 +302,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
 	if (pdata->irq < 0)
 		return pdata->irq;
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 	ret = dev_pm_set_wake_irq(&pdev->dev, pdata->irq);
 	if (ret)
 		dev_err(&pdev->dev, "failed to enable irq wake\n");
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index c123778e2d9b..0f90065e352c 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -920,7 +920,7 @@ static void omap_rtc_remove(struct platform_device *pdev)
 		omap_rtc_power_off_rtc = NULL;
 	}
 
-	device_init_wakeup(&pdev->dev, 0);
+	device_init_wakeup(&pdev->dev, false);
 
 	if (!IS_ERR(rtc->clk))
 		clk_disable_unprepare(rtc->clk);
diff --git a/drivers/rtc/rtc-palmas.c b/drivers/rtc/rtc-palmas.c
index 7256a88b490c..aecada6bcf8b 100644
--- a/drivers/rtc/rtc-palmas.c
+++ b/drivers/rtc/rtc-palmas.c
@@ -287,7 +287,7 @@ static int palmas_rtc_probe(struct platform_device *pdev)
 
 	palmas_rtc->irq = platform_get_irq(pdev, 0);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 	palmas_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 				&palmas_rtc_ops, THIS_MODULE);
 	if (IS_ERR(palmas_rtc->rtc)) {
diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c
index bed3c27e665f..2812da2c50c5 100644
--- a/drivers/rtc/rtc-pic32.c
+++ b/drivers/rtc/rtc-pic32.c
@@ -330,7 +330,7 @@ static int pic32_rtc_probe(struct platform_device *pdev)
 
 	pic32_rtc_enable(pdata, 1);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	pdata->rtc->ops = &pic32_rtcops;
 	pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index 2f32187ecc8d..b2518aea4218 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -503,7 +503,7 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, rtc_dd);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev);
 	if (IS_ERR(rtc_dd->rtc))
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c
index 34d8545c8e15..62ee6b8f9bcd 100644
--- a/drivers/rtc/rtc-pxa.c
+++ b/drivers/rtc/rtc-pxa.c
@@ -360,7 +360,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	device_init_wakeup(dev, 1);
+	device_init_wakeup(dev, true);
 
 	return 0;
 }
diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c
index eecb49bab56a..8ba9cda74acf 100644
--- a/drivers/rtc/rtc-rc5t583.c
+++ b/drivers/rtc/rtc-rc5t583.c
@@ -245,7 +245,7 @@ static int rc5t583_rtc_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "IRQ is not free.\n");
 		return ret;
 	}
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	ricoh_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 		&rc5t583_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-rc5t619.c b/drivers/rtc/rtc-rc5t619.c
index 711f62eecd79..74d169102074 100644
--- a/drivers/rtc/rtc-rc5t619.c
+++ b/drivers/rtc/rtc-rc5t619.c
@@ -414,7 +414,7 @@ static int rc5t619_rtc_probe(struct platform_device *pdev)
 
 		} else {
 			/* enable wake */
-			device_init_wakeup(&pdev->dev, 1);
+			device_init_wakeup(&pdev->dev, true);
 			enable_irq_wake(rtc->irq);
 		}
 	} else {
diff --git a/drivers/rtc/rtc-renesas-rtca3.c b/drivers/rtc/rtc-renesas-rtca3.c
index d127933bfc8a..a056291d3887 100644
--- a/drivers/rtc/rtc-renesas-rtca3.c
+++ b/drivers/rtc/rtc-renesas-rtca3.c
@@ -768,7 +768,7 @@ static int rtca3_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	priv->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
 	if (IS_ERR(priv->rtc_dev))
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index 2d9bcb3ce1e3..59b8e9a30fe6 100644
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -418,7 +418,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	rk808_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
 	if (IS_ERR(rk808_rtc->rtc))
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index c0ac3bdb2f42..58c957eb753d 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -456,7 +456,7 @@ static int s3c_rtc_probe(struct platform_device *pdev)
 	dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n",
 		readw(info->base + S3C2410_RTCCON));
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	info->rtc = devm_rtc_allocate_device(&pdev->dev);
 	if (IS_ERR(info->rtc)) {
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
index dad294a0ce2a..36acca5b2639 100644
--- a/drivers/rtc/rtc-s5m.c
+++ b/drivers/rtc/rtc-s5m.c
@@ -729,7 +729,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)
 				info->irq, ret);
 			return ret;
 		}
-		device_init_wakeup(&pdev->dev, 1);
+		device_init_wakeup(&pdev->dev, true);
 	}
 
 	return devm_rtc_register_device(info->rtc_dev);
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 13799b1abca1..1ad93648d69c 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -292,7 +292,7 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, info);
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	return sa1100_rtc_init(pdev, info);
 }
diff --git a/drivers/rtc/rtc-sc27xx.c b/drivers/rtc/rtc-sc27xx.c
index ce7a2ddbbc16..2b83561d4d28 100644
--- a/drivers/rtc/rtc-sc27xx.c
+++ b/drivers/rtc/rtc-sc27xx.c
@@ -613,14 +613,14 @@ static int sprd_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	rtc->rtc->ops = &sprd_rtc_ops;
 	rtc->rtc->range_min = 0;
 	rtc->rtc->range_max = 5662310399LL;
 	ret = devm_rtc_register_device(rtc->rtc);
 	if (ret) {
-		device_init_wakeup(&pdev->dev, 0);
+		device_init_wakeup(&pdev->dev, false);
 		return ret;
 	}
 
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index a5df521876ba..9ea40f40188f 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -611,7 +611,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_unmap;
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 	return 0;
 
 err_unmap:
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
index 26eed927f8b3..959acff8faff 100644
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -395,7 +395,7 @@ static int spear_rtc_probe(struct platform_device *pdev)
 		goto err_disable_clock;
 
 	if (!device_can_wakeup(&pdev->dev))
-		device_init_wakeup(&pdev->dev, 1);
+		device_init_wakeup(&pdev->dev, true);
 
 	return 0;
 
@@ -411,7 +411,7 @@ static void spear_rtc_remove(struct platform_device *pdev)
 
 	spear_rtc_disable_interrupt(config);
 	clk_disable_unprepare(config->clk);
-	device_init_wakeup(&pdev->dev, 0);
+	device_init_wakeup(&pdev->dev, false);
 }
 
 #ifdef CONFIG_PM_SLEEP
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index e681c1745866..e5e6013d080e 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -826,7 +826,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 
 	clk_prepare_enable(chip->losc);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	chip->rtc = devm_rtc_allocate_device(&pdev->dev);
 	if (IS_ERR(chip->rtc))
diff --git a/drivers/rtc/rtc-sunplus.c b/drivers/rtc/rtc-sunplus.c
index 9b1ce0e8ba27..519a06e728d6 100644
--- a/drivers/rtc/rtc-sunplus.c
+++ b/drivers/rtc/rtc-sunplus.c
@@ -269,7 +269,7 @@ static int sp_rtc_probe(struct platform_device *plat_dev)
 	if (ret)
 		goto free_reset_assert;
 
-	device_init_wakeup(&plat_dev->dev, 1);
+	device_init_wakeup(&plat_dev->dev, true);
 	dev_set_drvdata(&plat_dev->dev, sp_rtc);
 
 	sp_rtc->rtc = devm_rtc_allocate_device(&plat_dev->dev);
@@ -307,7 +307,7 @@ static void sp_rtc_remove(struct platform_device *plat_dev)
 {
 	struct sunplus_rtc *sp_rtc = dev_get_drvdata(&plat_dev->dev);
 
-	device_init_wakeup(&plat_dev->dev, 0);
+	device_init_wakeup(&plat_dev->dev, false);
 	reset_control_assert(sp_rtc->rstc);
 	clk_disable_unprepare(sp_rtc->rtcclk);
 }
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c
index 79a3102c8354..46788db89953 100644
--- a/drivers/rtc/rtc-tegra.c
+++ b/drivers/rtc/rtc-tegra.c
@@ -319,7 +319,7 @@ static int tegra_rtc_probe(struct platform_device *pdev)
 	writel(0xffffffff, info->base + TEGRA_RTC_REG_INTR_STATUS);
 	writel(0, info->base + TEGRA_RTC_REG_INTR_MASK);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	ret = devm_request_irq(&pdev->dev, info->irq, tegra_rtc_irq_handler,
 			       IRQF_TRIGGER_HIGH, dev_name(&pdev->dev),
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index 7e0d8fb26465..a68b8c884102 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -132,7 +132,7 @@ static int test_probe(struct platform_device *plat_dev)
 		break;
 	default:
 		rtd->rtc->ops = &test_rtc_ops;
-		device_init_wakeup(&plat_dev->dev, 1);
+		device_init_wakeup(&plat_dev->dev, true);
 	}
 
 	timer_setup(&rtd->alarm, test_rtc_alarm_handler, 0);
diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c
index e796729fc817..54c8429b16bf 100644
--- a/drivers/rtc/rtc-tps6586x.c
+++ b/drivers/rtc/rtc-tps6586x.c
@@ -241,7 +241,7 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	platform_set_drvdata(pdev, rtc);
 	rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c
index 2ea1bbfbbc2a..284aa2f0392b 100644
--- a/drivers/rtc/rtc-tps65910.c
+++ b/drivers/rtc/rtc-tps65910.c
@@ -418,7 +418,7 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
 	tps_rtc->irq = irq;
 	if (irq != -1) {
 		if (device_property_present(tps65910->dev, "wakeup-source"))
-			device_init_wakeup(&pdev->dev, 1);
+			device_init_wakeup(&pdev->dev, true);
 		else
 			device_set_wakeup_capable(&pdev->dev, 1);
 	} else {
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index 794429182b34..e6106e67e1f4 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -572,7 +572,7 @@ static int twl_rtc_probe(struct platform_device *pdev)
 		return ret;
 
 	platform_set_drvdata(pdev, twl_rtc);
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	twl_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 					&twl_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c
index 640833e21057..218316be942a 100644
--- a/drivers/rtc/rtc-wm831x.c
+++ b/drivers/rtc/rtc-wm831x.c
@@ -420,7 +420,7 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
 	if (ret & WM831X_RTC_ALM_ENA)
 		wm831x_rtc->alarm_enabled = 1;
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	wm831x_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
 	if (IS_ERR(wm831x_rtc->rtc))
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
index 6797eb4d2e49..3bd60d067a5e 100644
--- a/drivers/rtc/rtc-wm8350.c
+++ b/drivers/rtc/rtc-wm8350.c
@@ -420,7 +420,7 @@ static int wm8350_rtc_probe(struct platform_device *pdev)
 		}
 	}
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	wm_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm8350",
 					&wm8350_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c
index 0813ea1a03c2..6660b664e8dd 100644
--- a/drivers/rtc/rtc-xgene.c
+++ b/drivers/rtc/rtc-xgene.c
@@ -174,7 +174,7 @@ static int xgene_rtc_probe(struct platform_device *pdev)
 	/* Turn on the clock and the crystal */
 	writel(RTC_CCR_EN, pdata->csr_base + RTC_CCR);
 
-	ret = device_init_wakeup(&pdev->dev, 1);
+	ret = device_init_wakeup(&pdev->dev, true);
 	if (ret) {
 		clk_disable_unprepare(pdata->clk);
 		return ret;
@@ -197,7 +197,7 @@ static void xgene_rtc_remove(struct platform_device *pdev)
 	struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev);
 
 	xgene_rtc_alarm_irq_enable(&pdev->dev, 0);
-	device_init_wakeup(&pdev->dev, 0);
+	device_init_wakeup(&pdev->dev, false);
 	clk_disable_unprepare(pdata->clk);
 }
 
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
index af1abb69d1e3..625f708a7caf 100644
--- a/drivers/rtc/rtc-zynqmp.c
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -337,7 +337,7 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
 
 	xlnx_init_rtc(xrtcdev);
 
-	device_init_wakeup(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 
 	return devm_rtc_register_device(xrtcdev->rtc);
 }
@@ -345,7 +345,7 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
 static void xlnx_rtc_remove(struct platform_device *pdev)
 {
 	xlnx_rtc_alarm_irq_enable(&pdev->dev, 0);
-	device_init_wakeup(&pdev->dev, 0);
+	device_init_wakeup(&pdev->dev, false);
 }
 
 static int __maybe_unused xlnx_rtc_suspend(struct device *dev)
-- 
2.45.2



From shijie at os.amperecomputing.com  Mon Dec 16 23:17:15 2024
From: shijie at os.amperecomputing.com (Huang Shijie)
Date: Tue, 17 Dec 2024 15:17:15 +0800
Subject: [PATCH v4 1/2 fix-v2 ] arm64: refactor the rodata=xxx
In-Reply-To: <20241212082426.4110-2-shijie@os.amperecomputing.com>
References: <20241212082426.4110-2-shijie@os.amperecomputing.com>
Message-ID: <20241217071715.24797-1-shijie@os.amperecomputing.com>

As per admin guide documentation, "rodata=on" should be the default on
platforms. Documentation/admin-guide/kernel-parameters.txt describes
these options as

   rodata=         [KNL,EARLY]
           on      Mark read-only kernel memory as read-only (default).
           off     Leave read-only kernel memory writable for debugging.
           full    Mark read-only kernel memory and aliases as read-only
                   [arm64]

But on arm64 platform, "rodata=full" is the default instead. This patch
implements the following changes.

 - Make "rodata=on" behaviour same as the original "rodata=full"
 - Make "rodata=noalias" (new) behaviour same as the original "rodata=on"
 - Drop the original "rodata=full"
 - Add comment for arch_parse_debug_rodata()
 - Update kernel-parameters.txt as required

After this patch, the "rodata=on" will be the default on arm64 platform
as well.

Signed-off-by: Huang Shijie <shijie at os.amperecomputing.com>
---
Add more comment for "rodata=noalias" in arch_parse_debug_rodata() from Ard.
---
 .../admin-guide/kernel-parameters.txt         |  2 +-
 arch/arm64/include/asm/setup.h                | 28 +++++++++++++++++--
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 97c497bdafac..639669324350 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -6105,7 +6105,7 @@
 	rodata=		[KNL,EARLY]
 		on	Mark read-only kernel memory as read-only (default).
 		off	Leave read-only kernel memory writable for debugging.
-		full	Mark read-only kernel memory and aliases as read-only
+		noalias	Use more block mappings,may have better performance.
 		        [arm64]
 
 	rockchip.usb_uart
diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
index ba269a7a3201..6b994d0881d1 100644
--- a/arch/arm64/include/asm/setup.h
+++ b/arch/arm64/include/asm/setup.h
@@ -13,6 +13,30 @@
 extern phys_addr_t __fdt_pointer __initdata;
 extern u64 __cacheline_aligned boot_args[4];
 
+/*
+ * rodata=on (default)
+ *
+ *    This applies read-only attributes to VM areas and to the linear
+ *    alias of the backing pages as well. This prevents code or read-
+ *    only data from being modified (inadvertently or intentionally),
+ *    via another mapping for the same memory page.
+ *
+ *    But this might cause linear map region to be mapped down to base
+ *    pages, which may adversely affect performance in some cases.
+ *
+ * rodata=off
+ *
+ *    This provides more block mappings and contiguous hints for linear
+ *    map region which would minimize TLB footprint. This also leaves
+ *    read-only kernel memory writable for debugging.
+ *
+ * rodata=noalias
+ *
+ *    This provides more block mappings and contiguous hints for linear
+ *    map region which would minimize TLB footprint. This leaves the linear
+ *    alias of read-only mappings in the vmalloc space writeable, making
+ *    them susceptible to inadvertent modification by software.
+ */
 static inline bool arch_parse_debug_rodata(char *arg)
 {
 	extern bool rodata_enabled;
@@ -21,7 +45,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
 	if (!arg)
 		return false;
 
-	if (!strcmp(arg, "full")) {
+	if (!strcmp(arg, "on")) {
 		rodata_enabled = rodata_full = true;
 		return true;
 	}
@@ -31,7 +55,7 @@ static inline bool arch_parse_debug_rodata(char *arg)
 		return true;
 	}
 
-	if (!strcmp(arg, "on")) {
+	if (!strcmp(arg, "noalias")) {
 		rodata_enabled = true;
 		rodata_full = false;
 		return true;
-- 
2.40.1



From tudor.ambarus at linaro.org  Mon Dec 16 23:20:42 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue, 17 Dec 2024 07:20:42 +0000
Subject: [PATCH v2 3/4] arm64: dts: exynos: gs101: add ACPM protocol node
In-Reply-To: <Z2B3V78k2ibIdLYh@google.com>
References: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
 <20241212-b4-acpm-v4-upstream-dts-v2-3-91b7a6f6d0b0@linaro.org>
 <Z2B3V78k2ibIdLYh@google.com>
Message-ID: <45a54924-226e-4a94-b1ae-b0f1f703f854@linaro.org>



On 12/16/24 6:54 PM, William McVicker wrote:
> Hi Tudor,

Hi, William!

> 
> On 12/12/2024, Tudor Ambarus wrote:
>> Add the ACPM protocol node. ACPM protocol provides interface for all
>> the client drivers making use of the features offered by the
>> Active Power Management (APM) module.
>>
>> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
>> ---
>>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>> index 04561e15b96c..8c3f07371912 100644
>> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>> @@ -277,6 +277,28 @@ apm_sram: sram at 2039000 {
>>  		ranges = <0x0 0x0 0x2039000 0x40000>;
>>  	};
>>  
>> +	firmware {
>> +		acpm_ipc: power-management {
>> +			compatible = "google,gs101-acpm-ipc";
>> +			mboxes = <&ap2apm_mailbox 0 0
>> +				  &ap2apm_mailbox 0 1
>> +				  &ap2apm_mailbox 0 2
>> +				  &ap2apm_mailbox 0 3
>> +				  &ap2apm_mailbox 0 4
>> +				  &ap2apm_mailbox 0 5
>> +				  &ap2apm_mailbox 0 6
>> +				  &ap2apm_mailbox 0 7
>> +				  &ap2apm_mailbox 0 8
>> +				  &ap2apm_mailbox 0 9
>> +				  &ap2apm_mailbox 0 10
>> +				  &ap2apm_mailbox 0 11
>> +				  &ap2apm_mailbox 0 12
>> +				  &ap2apm_mailbox 0 13
>> +				  &ap2apm_mailbox 0 14>;
>> +			shmem = <&apm_sram>;
>> +		};
>> +	};
> 
> You mentioned in the previous patch that "GS101 has 14 mailbox controllers",

Right, I got the number from the GS101 memory map.

> but here you have 15 mailboxes. I looked at the downstream driver and see the

Here we have a single mailbox controller, ap2apm_mailbox, with 15 channels.

> number of mailboxes is defined by the ACPM framework (firmware) which is read

s/mailboxes/mailbox channels that ACPM uses/

> from SRAM initdata. Dumping that, I see there are 15 ACPM channels. Have you

Correct.

> looked into into extracting the data from the initdata SRAM address?
> 

Yes, that's the reason why I defined the 15 channels from above for the
ap2apm_mailbox controller.


Cheers,
ta


From krzk at kernel.org  Mon Dec 16 23:33:40 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 08:33:40 +0100
Subject: [PATCH 1/3] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and
 PLL_MIPI
In-Reply-To: <20241215053639.738890-2-anarsoul@gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
 <20241215053639.738890-2-anarsoul@gmail.com>
Message-ID: <qbtp4jvkx3r5azufe4k3vtapqpfs54dyjiu4cy5v5wkkzumrzx@vy3xzkfplbue>

On Sat, Dec 14, 2024 at 09:34:57PM -0800, Vasily Khoruzhick wrote:
> These will be used to explicitly select TCON0 clock parent in dts
> 
> Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
> Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
> ---
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.h      | 2 --
>  include/dt-bindings/clock/sun50i-a64-ccu.h | 2 +

You cannot combine these changes.

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec 16 23:36:32 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 08:36:32 +0100
Subject: [PATCH] arm64: dts: mt8186: Add mt8186-skitty
In-Reply-To: <20241216-skitty_kernel-v1-1-bc75dcdfeb57@pegatron.corp-partner.google.com>
References: <20241216-skitty_kernel-v1-1-bc75dcdfeb57@pegatron.corp-partner.google.com>
Message-ID: <um3ivvtmyk3jjvwpkzg5hg5dd5s2zjs4jzfl3xbg6cdil7mtvq@42wqiqmyuiv2>

On Mon, Dec 16, 2024 at 03:35:12PM +0800, Geoffrey Chien wrote:
> Add Skitty initial device tree.
> Support second source Synaptics trackpad
> Support US2 keyboard.
> Enhance touch screen timing for ELAN
> Based on experiment, set drive-strength to 6mA (default = 8mA)
> Modify sbs battery reg to 0x0f
> 
> Signed-off-by: Geoffrey Chien <geoffrey_chien at pegatron.corp-partner.google.com>
> ---
>  .../devicetree/bindings/arm/mediatek.yaml          |  8 +++
>  arch/arm64/boot/dts/mediatek/Makefile              |  4 ++
>  .../dts/mediatek/mt8186-corsola-skitty-sku1.dts    | 23 +++++++
>  .../dts/mediatek/mt8186-corsola-skitty-sku2.dts    | 13 ++++
>  .../dts/mediatek/mt8186-corsola-skitty-sku3.dts    | 40 ++++++++++++
>  .../dts/mediatek/mt8186-corsola-skitty-sku4.dts    | 30 +++++++++
>  .../boot/dts/mediatek/mt8186-corsola-skitty.dtsi   | 76 ++++++++++++++++++++++

This wasn't ever tested (as robots point out), but also:

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).
Maybe you need to update your dtschema and yamllint. Don't rely on
distro packages for dtschema and be sure you are using the latest
released dtschema.

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

>  7 files changed, 194 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
> index 1d4bb50fcd8d9aadb7b77e144a474b79da005056..29e7555569a772ba042e29af01ea98fdd3be1525 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
> @@ -224,6 +224,14 @@ properties:
>                - google,pico-sku2
>            - const: google,pico
>            - const: mediatek,mt8183
> +      - description: Google Skitty (HP Chromebook G1m 11 inch)
> +        items:
> +          - const: google,skitty-sku1
> +          - const: google,skitty-sku2
> +          - const: google,skitty-sku3
> +          - const: google,skitty-sku4
> +          - const: google,skitty
> +          - const: mediatek,mt8186
>        - description: Google Willow (Acer Chromebook 311 C722/C722T)
>          items:
>            - enum:
> diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> index 8fd7b2bb7a1590341e7bb4ea1ecf039ae3e8eb0d..328e1ee444bd81b5a2aa3d21acb7a5c5a3318a87 100644
> --- a/arch/arm64/boot/dts/mediatek/Makefile
> +++ b/arch/arm64/boot/dts/mediatek/Makefile
> @@ -59,6 +59,10 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-rusty-sku196608.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku1.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku2.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku3.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-skitty-sku4.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131072.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131073.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-tentacool-sku327681.dtb
> diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku1.dts
> new file mode 100644
> index 0000000000000000000000000000000000000000..a0e7b10445333d6f83fc4c461ce8f8d75ffaa697
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-skitty-sku1.dts
> @@ -0,0 +1,23 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright 2024 Google LLC
> + */
> +
> +/dts-v1/;
> +#include "mt8186-corsola-skitty.dtsi"
> +
> +/ {
> +	model = "Google Skitty sku1 board";
> +	compatible = "google,skitty-sku1",
> +		"google,skitty", "google,corsola", "mediatek,mt8186";

Fix alignment.

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec 16 23:40:52 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 08:40:52 +0100
Subject: [PATCH 2/2] dt-bindings: media: imx219: Describe sensor address
 using the reg property
In-Reply-To: <20241217024206.1700170-2-david@ixit.cz>
References: <20241217024206.1700170-1-david@ixit.cz>
 <20241217024206.1700170-2-david@ixit.cz>
Message-ID: <6djxfcuroxlth2th3tpuesauhdnowatzgnyhesewjfz32v6gbz@q2dj7jsxiqlw>

On Mon, Dec 16, 2024 at 09:41:51PM -0500, David Heidelberg wrote:
> Use the reg property instead of text in the description.
> Drop useless description of reg property.
> 
> Signed-off-by: David Heidelberg <david at ixit.cz>
> ---
>  Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml

You are using non-standard tools to generate patches. See checkpatch
warnings.

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

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec 16 23:41:31 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 08:41:31 +0100
Subject: [PATCH] dt-bindings: media: imx283: Describe sensor address
 using the reg property
In-Reply-To: <20241217032821.1712916-1-david@ixit.cz>
References: <20241217032821.1712916-1-david@ixit.cz>
Message-ID: <z7nkfmqubqabfxjpffhl4gaztec67xrfaulzd5d43bsyf2ukeb@ebak7s2bmm7j>

On Mon, Dec 16, 2024 at 10:28:17PM -0500, David Heidelberg wrote:
> Use the reg property instead of text in the description.
> 
> Signed-off-by: David Heidelberg <david at ixit.cz>
> ---
>  .../devicetree/bindings/media/i2c/sony,imx283.yaml         | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml ./Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml

Same problems.

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

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec 16 23:38:48 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 08:38:48 +0100
Subject: [PATCH 3/4] arm64: dts: exynos: gs101-oriole: move common Pixel6
 & 6Pro parts into a .dtsi
In-Reply-To: <20241216-gs101-simplefb-v1-3-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
 <20241216-gs101-simplefb-v1-3-8ccad1830281@linaro.org>
Message-ID: <fw2a6taf4kd3sggmyppeym2uxkuyotxy7ugj3bh73vetnra4m6@jllekadordju>

On Mon, Dec 16, 2024 at 01:06:28PM +0000, Andr? Draszik wrote:
> In order to support Pixel 6 (Oriole) and Pixel 6 Pro (Raven) properly,
> we have to be able to distinguish them properly as we add support for
> more features.
> 
> For example, Raven has a larger display. There are other differences,
> like battery design capacity, etc.
> 
> Move all the parts that are common for now into a gs101-raviole.dtsi,
> and just leave the display related things in gs101-oriole.dts.
> 
> Raviole was chosen as the name because Google uses that when referring
> to the combination of Oriole & Raven, keeping the familiar terminology.
> 
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> 
> ---
> Note: MAINTAINERS doesn't need updating, it covers this whole directory
> ---
>  arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 290 +-------------------
>  .../boot/dts/exynos/google/gs101-raviole.dtsi      | 297 +++++++++++++++++++++
>  2 files changed, 305 insertions(+), 282 deletions(-)
> 

This looks like move of the code, so -M/-B/-C format patch arguments
would create better diff.

Best regards,
Krzysztof



From krzk at kernel.org  Mon Dec 16 23:39:50 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 08:39:50 +0100
Subject: [PATCH 4/4] arm64: dts: exynos: gs101-raven: add new board file
In-Reply-To: <20241216-gs101-simplefb-v1-4-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
 <20241216-gs101-simplefb-v1-4-8ccad1830281@linaro.org>
Message-ID: <2wyjctwn443oxl633qwxsxmyzqhinssrkoafgqhcc34tqgwnh5@ymrr57jxdnl6>

On Mon, Dec 16, 2024 at 01:06:29PM +0000, Andr? Draszik wrote:
> Raven is Google's code name for Pixel 6 Pro. Similar to Pixel 6
> (Oriole), this is also based around its Tensor gs101 SoC.
> 
> For now, the relevant difference here is the display resolution:
> 1440 x 3120 instead of 1080 x 2400.
> 
> Create a new board file to reflect this difference.
> 
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> 
> ---
> Note: MAINTAINERS doesn't need updating, it covers this whole directory
> ---
>  arch/arm64/boot/dts/exynos/google/Makefile        |  1 +
>  arch/arm64/boot/dts/exynos/google/gs101-raven.dts | 27 +++++++++++++++++++++++
>  2 files changed, 28 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/google/Makefile b/arch/arm64/boot/dts/exynos/google/Makefile
> index 0a6d5e1fe4ee..7385f82b03c9 100644
> --- a/arch/arm64/boot/dts/exynos/google/Makefile
> +++ b/arch/arm64/boot/dts/exynos/google/Makefile
> @@ -2,3 +2,4 @@
>  
>  dtb-$(CONFIG_ARCH_EXYNOS) += \
>  	gs101-oriole.dtb \
> +	gs101-raven.dtb
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101-raven.dts b/arch/arm64/boot/dts/exynos/google/gs101-raven.dts
> new file mode 100644
> index 000000000000..75fd34797fa9
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/google/gs101-raven.dts
> @@ -0,0 +1,27 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Raven Device Tree
> + *
> + * Copyright 2021-2023 Google LLC
> + * Copyright 2023-2024 Linaro Ltd
> + */
> +
> +/dts-v1/;
> +
> +#include "gs101-raviole.dtsi"
> +
> +/ {
> +	model = "Raven";
> +	compatible = "google,gs101-raven", "google,gs101";
> +};
> +
> +&framebuffer0 {
> +	reg = <0x0 0xfac00000 (1440 * 3120 * 4)>;
> +	width = <1440>;
> +	height = <3120>;
> +	stride = <(1440 * 4)>;
> +};
> +
> +&cont_splash_mem {

Keep overriding/extending nodes ordered by label name.

Best regards,
Krzysztof



From mripard at kernel.org  Mon Dec 16 23:43:10 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 08:43:10 +0100
Subject: [PATCH v6 03/10] drm/connector: implement generic HDMI codec
 helpers
In-Reply-To: <exocd3b65cy6cy5w47cwx3ykn54ncf34hwyj7ffihs5jjzean5@y677uywnlah2>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-3-50dc145a9c06@linaro.org>
 <20241216-heretic-mackerel-of-wholeness-fcfed7@houat>
 <exocd3b65cy6cy5w47cwx3ykn54ncf34hwyj7ffihs5jjzean5@y677uywnlah2>
Message-ID: <20241217-heretic-hopeful-jaguar-aeabec@houat>

Hi,

On Mon, Dec 16, 2024 at 07:47:32PM +0200, Dmitry Baryshkov wrote:
> On Mon, Dec 16, 2024 at 06:04:41PM +0100, Maxime Ripard wrote:
> > > +struct drm_connector_hdmi_codec_funcs {
> > > +	/**
> > > +	 * @audio_startup:
> > > +	 *
> > > +	 * Called when ASoC starts an audio stream setup. The
> > > +	 * @hdmi_audio_startup is optional.
> > > +	 *
> > > +	 * Returns:
> > > +	 * 0 on success, a negative error code otherwise
> > > +	 */
> > > +	int (*audio_startup)(struct drm_connector *connector);
> > > +
> > > +	/**
> > > +	 * @prepare:
> > > +	 * Configures HDMI-encoder for audio stream. Can be called
> > > +	 * multiple times for each setup. Mandatory.
> > > +	 *
> > > +	 * Returns:
> > > +	 * 0 on success, a negative error code otherwise
> > > +	 */
> > > +	int (*prepare)(struct drm_connector *connector,
> > > +		       struct hdmi_codec_daifmt *fmt,
> > > +		       struct hdmi_codec_params *hparms);
> > 
> > Missing newline
> > 
> > > +	/**
> > > +	 * @audio_shutdown:
> > > +	 *
> > > +	 * Shut down the audio stream. Mandatory.
> > > +	 *
> > > +	 * Returns:
> > > +	 * 0 on success, a negative error code otherwise
> > > +	 */
> > > +	void (*audio_shutdown)(struct drm_connector *connector);
> > 
> > And thus we can probably just call that one shutdown?
> 
> It should be called automatically by the sound system. I'd rather not
> call items directly that we are not supposed to call.

I meant that with my suggestion to call the function
drm_connector_hdmi_audio_init, that structure would be called
drm_connector_hdmi_audio_funcs, and thus the audio prefix in
audio_shutdown is redundant.

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

From quic_jinlmao at quicinc.com  Mon Dec 16 23:47:06 2024
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Tue, 17 Dec 2024 15:47:06 +0800
Subject: [PATCH v2 0/3] Add support to configure TPDM MCMB subunit
In-Reply-To: <20241105123940.39602-1-quic_jinlmao@quicinc.com>
References: <20241105123940.39602-1-quic_jinlmao@quicinc.com>
Message-ID: <65de323b-ee7f-41cf-a300-1cf883494d1d@quicinc.com>



On 2024/11/5 20:39, Mao Jinlong wrote:
> Introduction of TPDM MCMB(Multi-lane Continuous Multi Bit) subunit
> MCMB (Multi-lane CMB) is a special form of CMB dataset type. MCMB
> subunit has the same number and usage of registers as CMB subunit.
> Just like the CMB subunit, the MCMB subunit must be configured prior
> to enablement. This series adds support for TPDM to configure the
> MCMB 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 MCMB subunit. All sysfs files of CMB subunit TPDM are
> included in MCMB subunit TPDM. On this basis, MCMB subunit TPDM will
> have new sysfs files to select and enable the lane.
> 
> Changes in V2:
> 1. Use tdpm_data->cmb instead of (tpdm_has_cmb_dataset(tpdm_data) ||
> tpdm_has_mcmb_dataset(tpdm_data)) for cmb dataset support.
> 2. Embed mcmb_dataset struct into cmb struct.
> 3. Update the date and version in sysfs-bus-coresight-devices-tpdm
> 
> Mao Jinlong (1):
>    coresight-tpdm: Add MCMB dataset support
> 
> Tao Zhang (2):
>    coresight-tpdm: Add support to select lane
>    coresight-tpdm: Add support to enable the lane for MCMB TPDM
> 
>   .../testing/sysfs-bus-coresight-devices-tpdm  |  15 +++
>   drivers/hwtracing/coresight/coresight-tpda.c  |   7 +-
>   drivers/hwtracing/coresight/coresight-tpdm.c  | 124 +++++++++++++++++-
>   drivers/hwtracing/coresight/coresight-tpdm.h  |  33 +++--
>   4 files changed, 158 insertions(+), 21 deletions(-)

Gentle reminder for the review.
> 



From quic_jinlmao at quicinc.com  Mon Dec 16 23:47:42 2024
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Tue, 17 Dec 2024 15:47:42 +0800
Subject: [PATCH v5] arm64: defconfig: Enable STM protocol and source
 configs
In-Reply-To: <20241101084558.36948-1-quic_jinlmao@quicinc.com>
References: <20241101084558.36948-1-quic_jinlmao@quicinc.com>
Message-ID: <e7ca1f47-8ccd-44b4-bfdd-707a1f8aef13@quicinc.com>



On 2024/11/1 16:45, Mao Jinlong wrote:
> STM is used for logging useful softevens from various entities.
> With STM and TMC sink enabled, there will be more buffer size to store
> the logs. STM source and STM protocol need to be configured along with
> STM device for STM function refer to Documentation/trace/stm.rst.
> CONFIG_CORESIGHT_STM is already added as module. Add Coresight STM
> source and Protocol configs as module so that STM functions can be
> used.
> 
> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
> ---
> Changes in v5:
> - Update commit message.
> 
> Changes in v4:
> - Remove Ftrace config.
> 
> Changes in v3:
> - update commit message.
> 
> Changes in v2:
> - select ftrace config explicitly.
>   arch/arm64/configs/defconfig | 5 +++++
>   1 file changed, 5 insertions(+)

Gentle reminder for the review.

> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 5fdbfea7a5b2..ac11cd1a7c06 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -1599,6 +1599,11 @@ CONFIG_NVMEM_SNVS_LPGPR=y
>   CONFIG_NVMEM_SPMI_SDAM=m
>   CONFIG_NVMEM_SUNXI_SID=y
>   CONFIG_NVMEM_UNIPHIER_EFUSE=y
> +CONFIG_STM_PROTO_BASIC=m
> +CONFIG_STM_PROTO_SYS_T=m
> +CONFIG_STM_DUMMY=m
> +CONFIG_STM_SOURCE_CONSOLE=m
> +CONFIG_STM_SOURCE_HEARTBEAT=m
>   CONFIG_FPGA=y
>   CONFIG_FPGA_MGR_ALTERA_CVP=m
>   CONFIG_FPGA_MGR_STRATIX10_SOC=m





From christophe.leroy at csgroup.eu  Mon Dec 16 23:47:54 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Tue, 17 Dec 2024 08:47:54 +0100
Subject: [PATCH] mm/ptdump: Drop GENERIC_PTDUMP
In-Reply-To: <20241217034807.2541349-1-anshuman.khandual@arm.com>
References: <20241217034807.2541349-1-anshuman.khandual@arm.com>
Message-ID: <ddd4439e-6f6f-4513-a7dc-b7f01bec03dc@csgroup.eu>



Le 17/12/2024 ? 04:48, Anshuman Khandual a ?crit?:
> GENERIC_PTDUMP does not guard any code but instead just used for platform's
> subscription into core ptdump defined under PTDUMP_CORE, which is selected.
> Instead use PTDUMP_CORE for platform subscription and drop GENERIC_PTDUMP.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Jonathan Corbet <corbet at lwn.net>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Michael Ellerman <mpe at ellerman.id.au>
> Cc: Nicholas Piggin <npiggin at gmail.com>
> Cc: Paul Walmsley <paul.walmsley at sifive.com>
> Cc: Palmer Dabbelt <palmer at dabbelt.com>
> Cc: Heiko Carstens <hca at linux.ibm.com>
> Cc: Vasily Gorbik <gor at linux.ibm.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: kvmarm at lists.linux.dev
> Cc: linuxppc-dev at lists.ozlabs.org
> Cc: linux-riscv at lists.infradead.org
> Cc: linux-s390 at vger.kernel.org
> Cc: linux-mm at kvack.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
> This patch applies on v6.13-rc3 and has been tested on arm64, although it
> also clears build tests on impacted platforms.
> 
>   Documentation/arch/arm64/ptdump.rst       | 1 -
>   arch/arm64/Kconfig                        | 2 +-
>   arch/arm64/kvm/Kconfig                    | 3 +--
>   arch/powerpc/Kconfig                      | 2 +-
>   arch/powerpc/configs/mpc885_ads_defconfig | 1 -
>   arch/riscv/Kconfig                        | 2 +-
>   arch/s390/Kconfig                         | 2 +-
>   arch/x86/Kconfig                          | 2 +-
>   arch/x86/Kconfig.debug                    | 2 +-
>   kernel/configs/debug.config               | 1 -
>   mm/Kconfig.debug                          | 8 ++------
>   11 files changed, 9 insertions(+), 17 deletions(-)
> 

> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a0ce777f9706..c716f8df10de 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -203,7 +203,7 @@ config PPC
>   	select GENERIC_IRQ_SHOW
>   	select GENERIC_IRQ_SHOW_LEVEL
>   	select GENERIC_PCI_IOMAP		if PCI
> -	select GENERIC_PTDUMP
> +	select PTDUMP_CORE

Please keep alphabetical order.

>   	select GENERIC_SMP_IDLE_THREAD
>   	select GENERIC_TIME_VSYSCALL
>   	select GENERIC_VDSO_TIME_NS

> diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
> index 41a58536531d..b206e5a11f96 100644
> --- a/mm/Kconfig.debug
> +++ b/mm/Kconfig.debug
> @@ -187,7 +187,7 @@ config DEBUG_WX
>   	bool "Warn on W+X mappings at boot"
>   	depends on ARCH_HAS_DEBUG_WX
>   	depends on MMU
> -	select PTDUMP_CORE
> +	depends on PTDUMP_CORE

This change is unclear to me. It works because all arch selecting 
ARCH_HAS_DEBUG_WX also select GENERIC_PTDUMP. For riscv it's even more 
tricking, Riscv only selects GENERIC_PTDUMP when MMU is set, so it works 
because here it also depends on MMU.

But what happens if in the future an architecture selects 
ARCH_HAS_DEBUG_WX without selecting PTDUMP_CORE ?


>   	help
>   	  Generate a warning if any W+X mappings are found at boot.
>   
> @@ -212,9 +212,6 @@ config DEBUG_WX
>   
>   	  If in doubt, say "Y".
>   
> -config GENERIC_PTDUMP
> -	bool
> -
>   config PTDUMP_CORE
>   	bool
>   
> @@ -222,8 +219,7 @@ config PTDUMP_DEBUGFS
>   	bool "Export kernel pagetable layout to userspace via debugfs"
>   	depends on DEBUG_KERNEL
>   	depends on DEBUG_FS
> -	depends on GENERIC_PTDUMP
> -	select PTDUMP_CORE
> +	depends on PTDUMP_CORE
>   	help
>   	  Say Y here if you want to show the kernel pagetable layout in a
>   	  debugfs file. This information is only useful for kernel developers



From ericwouds at gmail.com  Mon Dec 16 23:49:58 2024
From: ericwouds at gmail.com (Eric Woudstra)
Date: Tue, 17 Dec 2024 08:49:58 +0100
Subject: [PATCH net-next 2/3] net: pcs: pcs-mtk-lynxi: implement
 pcs_inband_caps() method
In-Reply-To: <E1tJ8NR-006L5P-E3@rmk-PC.armlinux.org.uk>
References: <Z1F1b8eh8s8T627j@shell.armlinux.org.uk>
 <E1tJ8NR-006L5P-E3@rmk-PC.armlinux.org.uk>
Message-ID: <e1e271e3-b684-46d2-879d-e3481d25a712@gmail.com>


On 12/5/24 10:42 AM, Russell King (Oracle) wrote:
> Report the PCS in-band capabilities to phylink for the LynxI PCS.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Reviewed-by: Daniel Golle <daniel at makrotopia.org>
> ---
>  drivers/net/pcs/pcs-mtk-lynxi.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
> index 4f63abe638c4..7de804535229 100644
> --- a/drivers/net/pcs/pcs-mtk-lynxi.c
> +++ b/drivers/net/pcs/pcs-mtk-lynxi.c
> @@ -88,6 +88,21 @@ static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
>  	return container_of(pcs, struct mtk_pcs_lynxi, pcs);
>  }
>  
> +static unsigned int mtk_pcs_lynxi_inband_caps(struct phylink_pcs *pcs,
> +					      phy_interface_t interface)
> +{
> +	switch (interface) {
> +	case PHY_INTERFACE_MODE_1000BASEX:
> +	case PHY_INTERFACE_MODE_2500BASEX:

Isn't this the place now where to report to phylink, that this PCS does
not support in-band at 2500base-x?

Best regards,

Eric

> +	case PHY_INTERFACE_MODE_SGMII:
> +	case PHY_INTERFACE_MODE_QSGMII:
> +		return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
> +
> +	default:
> +		return 0;
> +	}
> +}
> +
>  static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
>  				    struct phylink_link_state *state)
>  {
> @@ -241,6 +256,7 @@ static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs)
>  }
>  
>  static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
> +	.pcs_inband_caps = mtk_pcs_lynxi_inband_caps,
>  	.pcs_get_state = mtk_pcs_lynxi_get_state,
>  	.pcs_config = mtk_pcs_lynxi_config,
>  	.pcs_an_restart = mtk_pcs_lynxi_restart_an,



From quic_jinlmao at quicinc.com  Mon Dec 16 23:50:47 2024
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Tue, 17 Dec 2024 15:50:47 +0800
Subject: [PATCH v1 0/2] Add Qualcomm extended CTI support
In-Reply-To: <742d1cec-13ec-4f08-b7f3-611c6d602b3b@quicinc.com>
References: <20240903121847.6964-1-quic_jinlmao@quicinc.com>
 <742d1cec-13ec-4f08-b7f3-611c6d602b3b@quicinc.com>
Message-ID: <f839a280-aa76-4963-9580-a6e089136bb5@quicinc.com>



On 2024/10/10 17:49, Jinlong Mao wrote:
> 
> 
> On 2024/9/3 20:18, Mao Jinlong wrote:
>> The QCOM extended CTI is a heavily parameterized version of ARM?s CSCTI.
>> It allows a debugger to send to trigger events to a processor or to send
>> a trigger event to one or more processors when a trigger event occurs on
>> another processor on the same SoC, or even between SoCs.
>>
>> QCOM extended CTI supports up to 128 triggers. And some of the register
>> offsets are changed.
>>
>> The commands to configure CTI triggers are the same as ARM's CTI.
>>
> 
> Hi Reviewers,
> 
> Could you please help to provide some comments from the design point of 
> view for the changes ?
> 
> The main difference of extended CTI to the normal CTI is that the
> address mapping is changed and it supports a max of 128 trigger signals.
> 
> On one soc, there will be both normal arm CTIs and QCOM extended CTIs.
> 
> As max trigger number becomes 128. So triger registers becomes 4.
> 
> Like CTITRIGINSTATUS? --- > CTITRIGINSTATUS_EXTENDED(n)???? (0x040 + (4 
> * n))? n is 0 to 4.
> 
> Thanks
> Jinlong Mao

Gentle reminder for the review from the code design point of view.

> 
>> Mao Jinlong (2):
>> ?? dt-bindings: arm: Add Qualcomm extended CTI
>> ?? coresight: cti: Add Qualcomm extended CTI support
>>
>> ? .../bindings/arm/arm,coresight-cti.yaml?????? |? 14 ++
>> ? .../hwtracing/coresight/coresight-cti-core.c? |? 75 +++++++----
>> ? .../coresight/coresight-cti-platform.c??????? |? 16 ++-
>> ? .../hwtracing/coresight/coresight-cti-sysfs.c | 124 ++++++++++++++----
>> ? drivers/hwtracing/coresight/coresight-cti.h?? | 123 +++++++++++------
>> ? 5 files changed, 253 insertions(+), 99 deletions(-)
>>
> 



From mripard at kernel.org  Tue Dec 17 00:06:37 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 09:06:37 +0100
Subject: [PATCH v20 5/9] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <fbd12029fab1f60e2ba4fad75ef650298a59cb15.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
 <fbd12029fab1f60e2ba4fad75ef650298a59cb15.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <20241217-judicious-stereotyped-centipede-5ddb27@houat>

Hi,

On Tue, Dec 17, 2024 at 02:51:47PM +0800, Sandor Yu wrote:
> +static ssize_t firmware_version_show(struct device *dev,
> +				     struct device_attribute *attr, char *buf);
> +static struct device_attribute firmware_version = __ATTR_RO(firmware_version);
> +
> +ssize_t firmware_version_show(struct device *dev,
> +			      struct device_attribute *attr, char *buf)
> +{
> +	struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(dev);
> +
> +	u32 version = readl(mhdp->base.regs + VER_L) | readl(mhdp->base.regs + VER_H) << 8;
> +	u32 lib_version = readl(mhdp->base.regs + VER_LIB_L_ADDR) |
> +			  readl(mhdp->base.regs + VER_LIB_H_ADDR) << 8;
> +
> +	return sprintf(buf, "FW version %d, Lib version %d\n", version, lib_version);
> +}
> +
> +static void cdns_mhdp8501_create_device_files(struct cdns_mhdp8501_device *mhdp)
> +{
> +	if (device_create_file(mhdp->dev, &firmware_version)) {
> +		DRM_ERROR("Unable to create firmware_version sysfs\n");
> +		device_remove_file(mhdp->dev, &firmware_version);
> +	}
> +}

sysfs files are part of the uABI, and need to be stable and documented.

For these kind of things, you should use debugfs.

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

From krzysztof.kozlowski at linaro.org  Tue Dec 17 00:11:28 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 09:11:28 +0100
Subject: [PATCH v5] arm64: defconfig: Enable STM protocol and source
 configs
In-Reply-To: <e7ca1f47-8ccd-44b4-bfdd-707a1f8aef13@quicinc.com>
References: <20241101084558.36948-1-quic_jinlmao@quicinc.com>
 <e7ca1f47-8ccd-44b4-bfdd-707a1f8aef13@quicinc.com>
Message-ID: <07cc40a5-8b4c-4f5c-8ecb-cbc67b916858@linaro.org>

On 17/12/2024 08:47, Jinlong Mao wrote:
> 
> 
> On 2024/11/1 16:45, Mao Jinlong wrote:
>> STM is used for logging useful softevens from various entities.
>> With STM and TMC sink enabled, there will be more buffer size to store
>> the logs. STM source and STM protocol need to be configured along with
>> STM device for STM function refer to Documentation/trace/stm.rst.
>> CONFIG_CORESIGHT_STM is already added as module. Add Coresight STM
>> source and Protocol configs as module so that STM functions can be
>> used.
>>
>> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
>> ---
>> Changes in v5:
>> - Update commit message.
>>
>> Changes in v4:
>> - Remove Ftrace config.
>>
>> Changes in v3:
>> - update commit message.
>>
>> Changes in v2:
>> - select ftrace config explicitly.
>>   arch/arm64/configs/defconfig | 5 +++++
>>   1 file changed, 5 insertions(+)
> 
> Gentle reminder for the review.
No need to ping for this. It's pending deliberately - on you. If you
want this to be merged, you need to funnel it through SoC maintainer's
tree. get_maintainers.pl (explained also in SoC maintainer profile).

To be clear: I do not object this patch, but I also do not see that many
benefits in having it in defconfig, thus no ack from me.


Best regards,
Krzysztof


From maz at kernel.org  Tue Dec 17 00:13:31 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 08:13:31 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: arm,gic: Correct VGIC interrupt description
In-Reply-To: <20241217061226.14139-1-krzysztof.kozlowski@linaro.org>
References: <20241217061226.14139-1-krzysztof.kozlowski@linaro.org>
Message-ID: <878qsesp5g.wl-maz@kernel.org>

On Tue, 17 Dec 2024 06:12:26 +0000,
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:
> 
> The description of VGIC interrupt referenced obsolete "see below" after
> converting TXT to DT Schema in commit 66ed144f147a ("dt-bindings:
> interrupt-controller: Convert ARM GIC to json-schema"), because there is
> no dedicated "VGIC" chapter anymore below.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>  .../devicetree/bindings/interrupt-controller/arm,gic.yaml     | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
> index a2846e493497..7173c4b5a228 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
> +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
> @@ -110,8 +110,8 @@ properties:
>  
>    interrupts:
>      description: Interrupt source of the parent interrupt controller on
> -      secondary GICs, or VGIC maintenance interrupt on primary GIC (see
> -      below).
> +      secondary GICs, or VGIC maintenance interrupt on primary GIC (see "GICv2
> +      with virtualization extensions" paragraph in the "reg" property).
>      maxItems: 1
>  
>    cpu-offset:

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

	M.

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


From ping.bai at nxp.com  Tue Dec 17 00:23:56 2024
From: ping.bai at nxp.com (Jacky Bai)
Date: Tue, 17 Dec 2024 08:23:56 +0000
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <Z1sT8FQXnxyZUeo3@lizhi-Precision-Tower-5810>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
 <Z1sT8FQXnxyZUeo3@lizhi-Precision-Tower-5810>
Message-ID: <AS8PR04MB86422B57F3B93C5BC045150687042@AS8PR04MB8642.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
> 
> On Thu, Dec 12, 2024 at 05:35:55PM +0800, Jacky Bai wrote:
> > The i.MX 943 applications processors integrate up to four
> > Arm Cortex A55 cores and supports functional safety with
> > built-in 2x Arm Cortex M33 and M7 cores which can be
> > configured asa safety island. Optimizing performance and
> > power efficiency for Industrial, IoT and automotive devices,
> > i.MX 943 processors are built with NXP?s innovative Energy
> > Flex architecture.
> 
> wrap at 75 chars
> 

Will fix in v2.

> >
> > This patch adds the minimal dtsi support for i.MX943 with
> > peripherals like uart, edma, i2c, spi, mu, sai etc.
> 
> Add the the minimal dtsi suppor ...

Will fix in v2.

> 
> >
> > Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/imx943-clock.h  |  196 +++
> >  .../arm64/boot/dts/freescale/imx943-pinfunc.h | 1542
> +++++++++++++++++
> >  arch/arm64/boot/dts/freescale/imx943-power.h  |   41 +
> >  arch/arm64/boot/dts/freescale/imx943.dtsi     | 1284
> ++++++++++++++
> >  4 files changed, 3063 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943-clock.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943-pinfunc.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943-power.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943.dtsi
> >
...

> > diff --git a/arch/arm64/boot/dts/freescale/imx943-pinfunc.h
> b/arch/arm64/boot/dts/freescale/imx943-pinfunc.h
> > new file mode 100644
> > index 000000000000..f042ddf81a1b
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/imx943-pinfunc.h
> > @@ -0,0 +1,1542 @@
> > +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
> > +/*
> > + * Copyright 2024 NXP
> > + */
> > +
> > +#ifndef __DTS_IMX943_PINFUNC_H
> > +#define __DTS_IMX943_PINFUNC_H
> > +
> > +/*
> > + * The pin function ID is a tuple of <mux_reg conf_reg input_reg
> mux_mode input_val>
> > + */
> > +#define IMX943_PAD_DAP_TDI__JTAG_MUX_TDI
> 0x0000 0x0304 0x092C 0x00 0x00
> > +#define IMX943_PAD_DAP_TDI__MQS2_LEFT
> 0x0000 0x0304 0x0000 0x01 0x00
> > +#define IMX943_PAD_DAP_TDI__ECAT_LED_ERR
> 0x0000 0x0304 0x0000 0x02 0x00
> > +#define IMX943_PAD_DAP_TDI__CAN2_TX
> 0x0000 0x0304 0x0000 0x03 0x00
> > +#define IMX943_PAD_DAP_TDI__SINC_FILTER_GLUE3_BREAK
> 0x0000 0x0304 0x0000 0x04 0x00
> > +#define IMX943_PAD_DAP_TDI__GPIO4_IO4
> 0x0000 0x0304 0x0000 0x05 0x00
> > +#define IMX943_PAD_DAP_TDI__LPUART5_RX
> 0x0000 0x0304 0x07BC 0x06 0x00
> > +#define IMX943_PAD_DAP_TDI__XBAR1_XBAR_INOUT26
> 0x0000 0x0304 0x0000 0x07 0x00
> 
> low case for hex value. generate script should be fixed. imx91 have fix it.

will fix it in v2.

> 

...
> > +
> > +++ b/arch/arm64/boot/dts/freescale/imx943.dtsi
> 
> run https://github.com/lznuaa/dt-format for new dts file to order nodes, if
> any issue, let me know
> 

Ok, thx.

> > @@ -0,0 +1,1284 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Copyright 2024 NXP
> > + */
> > +
> > +#include <dt-bindings/dma/fsl-edma.h>
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/input/input.h>
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +
> > +#include "imx943-clock.h"
> > +#include "imx943-pinfunc.h"
> > +#include "imx943-power.h"
> > +
> > +/ {
...

> > +		clock-frequency = <133000000>;
> > +		clock-output-names = "clk_ext1";
> > +	};
> > +
> > +	dummy: clk-dummy {
> 
> clock-dummy?

Will fix it in v2.

> 
> > +		compatible = "fixed-clock";
> > +		#clock-cells = <0>;
> > +		clock-frequency = <0>;
> > +		clock-output-names = "dummy";
> > +	};
> > +
> > +	osc_24m: clock-24m {
> > +		compatible = "fixed-clock";
> > +		#clock-cells = <0>;
> > +		clock-frequency = <24000000>;
> > +		clock-output-names = "osc_24m";
> > +	};
> > +
> > +	sai1_mclk: clock-sai1-mclk1 {
> > +		compatible = "fixed-clock";
> > +		#clock-cells = <0>;
> > +		clock-frequency = <0>;
> > +		clock-output-names = "sai1_mclk";
> > +	};
> > +
> > +	sai2_mclk: clock-sai2-mclk1 {
> > +		compatible = "fixed-clock";
> > +		#clock-cells = <0>;
> > +		clock-frequency = <0>;
> > +		clock-output-names = "sai2_mclk";
> > +	};
> > +
> > +	sai3_mclk: clock-sai3-mclk1 {
> > +		compatible = "fixed-clock";
> > +		#clock-cells = <0>;
> > +		clock-frequency = <0>;
> > +		clock-output-names = "sai3_mclk";
> > +	};
> > +
> > +	sai4_mclk: clock-sai4-mclk1 {
> > +		compatible = "fixed-clock";
> > +		#clock-cells = <0>;
> > +		clock-frequency = <0>;
> > +		clock-output-names = "sai4_mclk";
> > +	};
> > +
> > +	firmware {
> > +		scmi {
> > +			compatible = "arm,scmi";
> > +			mboxes = <&mu2 5 0>, <&mu2 3 0>, <&mu2 3 1>, <&mu2 5 1>;
> > +			shmem = <&scmi_buf0>, <&scmi_buf1>;
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +			arm,max-rx-timeout-ms = <5000>;
> > +
> > +			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_iomuxc: protocol at 19 {
> > +				reg = <0x19>;
> > +			};
> > +
> > +			scmi_bbm: protocol at 81 {
> > +				reg = <0x81>;
> > +			};
> > +		};
> > +	};
> > +
> > +	pmu {
> > +		compatible = "arm,cortex-a55-pmu";
> > +		interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(6) |
> IRQ_TYPE_LEVEL_HIGH)>;
> > +	};
> > +
> > +	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;
> 
> vendor property should be last one.

Will fix it in v2.

> 
> > +		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";
> > +			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>;
> > +			#address-cells = <1>;
> > +			#size-cells = <1>;
> > +			ranges = <0x42000000 0x0 0x42000000 0x8000000>;
> > +
> > +			edma2: dma-controller at 42000000 {
> > +				compatible = "fsl,imx95-edma5";
> > +				reg = <0x42000000 0x210000>;
> > +				#dma-cells = <3>;
> > +				dma-channels = <64>;
> > +				interrupts-extended =
> 
> Does "interrupts-extended" documented?

No, will check and add it binding doc.

> 
> > +					<&a55_irqsteer 0>, <&a55_irqsteer 1>,
> <&a55_irqsteer 2>,
> > +					<&a55_irqsteer 3>, <&a55_irqsteer 4>,
> <&a55_irqsteer 5>,
> > +					<&a55_irqsteer 6>, <&a55_irqsteer 7>,
> <&a55_irqsteer 8>,
> > +					<&a55_irqsteer 9>, <&a55_irqsteer 10>,
> <&a55_irqsteer 11>,
> > +					<&a55_irqsteer 12>, <&a55_irqsteer 13>,
> <&a55_irqsteer 14>,
> > +					<&a55_irqsteer 15>, <&a55_irqsteer 16>,
> <&a55_irqsteer 17>,
> > +					<&a55_irqsteer 18>, <&a55_irqsteer 19>,
> <&a55_irqsteer 20>,
> > +					<&a55_irqsteer 21>, <&a55_irqsteer 22>,
> <&a55_irqsteer 23>,
> > +					<&a55_irqsteer 24>, <&a55_irqsteer 25>,
> <&a55_irqsteer 26>,
> > +					<&a55_irqsteer 27>, <&a55_irqsteer 28>,
> <&a55_irqsteer 29>,
> > +					<&a55_irqsteer 30>, <&a55_irqsteer 31>,
> <&a55_irqsteer 64>,
> > +					<&a55_irqsteer 65>, <&a55_irqsteer 66>,
> <&a55_irqsteer 67>,
> > +					<&a55_irqsteer 68>, <&a55_irqsteer 69>,
> <&a55_irqsteer 70>,
> > +					<&a55_irqsteer 71>, <&a55_irqsteer 72>,
> <&a55_irqsteer 73>,
> > +					<&a55_irqsteer 74>, <&a55_irqsteer 75>,
> <&a55_irqsteer 76>,
> > +					<&a55_irqsteer 77>, <&a55_irqsteer 78>,
> <&a55_irqsteer 79>,
> > +					<&a55_irqsteer 80>, <&a55_irqsteer 81>,
> <&a55_irqsteer 82>,
> > +					<&a55_irqsteer 83>, <&a55_irqsteer 84>,
> <&a55_irqsteer 85>,
> > +					<&a55_irqsteer 86>, <&a55_irqsteer 87>,
> <&a55_irqsteer 88>,
> > +					<&a55_irqsteer 89>, <&a55_irqsteer 90>,
> <&a55_irqsteer 91>,
> > +					<&a55_irqsteer 92>, <&a55_irqsteer 93>,
> <&a55_irqsteer 94>,
> > +					<&a55_irqsteer 95>, <&gic GIC_SPI 98
> IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "dma";
> > +			};
> > +
> > +			edma3: dma-controller at 42210000 {
> > +				compatible = "fsl,imx95-edma5";
> > +				reg = <0x42210000 0x210000>;
> > +				#dma-cells = <3>;
> > +				dma-channels = <64>;
> > +				interrupts-extended =
> > +					<&a55_irqsteer 256>, <&a55_irqsteer 257>,
> > +					<&a55_irqsteer 258>, <&a55_irqsteer 259>,
> > +					<&a55_irqsteer 260>, <&a55_irqsteer 261>,
> > +					<&a55_irqsteer 262>, <&a55_irqsteer 263>,
> > +					<&a55_irqsteer 264>, <&a55_irqsteer 265>,
> > +					<&a55_irqsteer 266>, <&a55_irqsteer 267>,
> > +					<&a55_irqsteer 268>, <&a55_irqsteer 269>,
> > +					<&a55_irqsteer 270>, <&a55_irqsteer 271>,
> > +					<&a55_irqsteer 272>, <&a55_irqsteer 273>,
> > +					<&a55_irqsteer 274>, <&a55_irqsteer 275>,
> > +					<&a55_irqsteer 276>, <&a55_irqsteer 277>,
> > +					<&a55_irqsteer 278>, <&a55_irqsteer 279>,
> > +					<&a55_irqsteer 280>, <&a55_irqsteer 281>,
> > +					<&a55_irqsteer 282>, <&a55_irqsteer 283>,
> > +					<&a55_irqsteer 284>, <&a55_irqsteer 285>,
> > +					<&a55_irqsteer 286>, <&a55_irqsteer 287>,
> > +					<&a55_irqsteer 320>, <&a55_irqsteer 321>,
> > +					<&a55_irqsteer 322>, <&a55_irqsteer 323>,
> > +					<&a55_irqsteer 324>, <&a55_irqsteer 325>,
> > +					<&a55_irqsteer 326>, <&a55_irqsteer 327>,
> > +					<&a55_irqsteer 328>, <&a55_irqsteer 329>,
> > +					<&a55_irqsteer 330>, <&a55_irqsteer 331>,
> > +					<&a55_irqsteer 332>, <&a55_irqsteer 333>,
> > +					<&a55_irqsteer 334>, <&a55_irqsteer 335>,
> > +					<&a55_irqsteer 336>, <&a55_irqsteer 337>,
> > +					<&a55_irqsteer 338>, <&a55_irqsteer 339>,
> > +					<&a55_irqsteer 340>, <&a55_irqsteer 341>,
> > +					<&a55_irqsteer 342>, <&a55_irqsteer 343>,
> > +					<&a55_irqsteer 344>, <&a55_irqsteer 345>,
> > +					<&a55_irqsteer 346>, <&a55_irqsteer 347>,
> > +					<&a55_irqsteer 348>, <&a55_irqsteer 349>,
> > +					<&a55_irqsteer 350>, <&a55_irqsteer 351>,
> > +					<&gic GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "dma";
> > +				status = "disabled";
> 
> DMA should be default enabled.

This is the ACP port edma, maybe we can remove it for now?

> 
> > +			};
> > +
> > +			edma4: dma-controller at 42df0000 {
> > +				compatible = "fsl,imx95-edma5";
> > +				reg = <0x42df0000 0x210000>;
> > +				#dma-cells = <3>;
> > +				dma-channels = <64>;
> > +				interrupts-extended =
> > +					<&a55_irqsteer 128>, <&a55_irqsteer 129>,
> > +					<&a55_irqsteer 130>, <&a55_irqsteer 131>,
> > +					<&a55_irqsteer 132>, <&a55_irqsteer 133>,
> > +					<&a55_irqsteer 134>, <&a55_irqsteer 135>,
> > +					<&a55_irqsteer 136>, <&a55_irqsteer 137>,
> > +					<&a55_irqsteer 138>, <&a55_irqsteer 139>,
> > +					<&a55_irqsteer 140>, <&a55_irqsteer 141>,
> > +					<&a55_irqsteer 142>, <&a55_irqsteer 143>,
> > +					<&a55_irqsteer 144>, <&a55_irqsteer 145>,
> > +					<&a55_irqsteer 146>, <&a55_irqsteer 147>,
> > +					<&a55_irqsteer 148>, <&a55_irqsteer 149>,
> > +					<&a55_irqsteer 150>, <&a55_irqsteer 151>,
> > +					<&a55_irqsteer 152>, <&a55_irqsteer 153>,
> > +					<&a55_irqsteer 154>, <&a55_irqsteer 155>,
> > +					<&a55_irqsteer 156>, <&a55_irqsteer 157>,
> > +					<&a55_irqsteer 158>, <&a55_irqsteer 159>,
> > +					<&a55_irqsteer 192>, <&a55_irqsteer 193>,
> > +					<&a55_irqsteer 194>, <&a55_irqsteer 195>,
> > +					<&a55_irqsteer 196>, <&a55_irqsteer 197>,
> > +					<&a55_irqsteer 198>, <&a55_irqsteer 199>,
> > +					<&a55_irqsteer 200>, <&a55_irqsteer 201>,
> > +					<&a55_irqsteer 202>, <&a55_irqsteer 203>,
> > +					<&a55_irqsteer 204>, <&a55_irqsteer 205>,
> > +					<&a55_irqsteer 206>, <&a55_irqsteer 207>,
> > +					<&a55_irqsteer 208>, <&a55_irqsteer 209>,
> > +					<&a55_irqsteer 210>, <&a55_irqsteer 211>,
> > +					<&a55_irqsteer 212>, <&a55_irqsteer 213>,
> > +					<&a55_irqsteer 214>, <&a55_irqsteer 215>,
> > +					<&a55_irqsteer 216>, <&a55_irqsteer 217>,
> > +					<&a55_irqsteer 218>, <&a55_irqsteer 219>,
> > +					<&a55_irqsteer 220>, <&a55_irqsteer 221>,
> > +					<&a55_irqsteer 222>, <&a55_irqsteer 223>,
> > +					<&gic GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "dma";
> > +			};
> > +
> > +			mu10: mailbox at 42430000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x42430000 0x10000>;
> > +				interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			i3c2: i3c-master at 42520000 {
> > +				#address-cells = <3>;
> > +				#size-cells = <0>;
> > +				compatible = "silvaco,i3c-master-v1";
> > +				reg = <0x42520000 0x10000>;
> 
> compatible should be first one. Please run
> https://github.com/lznuaa/dt-format

Ok, will fix it.
> 
> I will skip all wrong order comments from here.
> 
> > +				interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_I3C2_SLOW>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> > +					 <&dummy>;
> > +				clock-names = "pclk", "fast_clk", "slow_clk";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpi2c3: i2c at 42530000 {
> > +				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
> > +				reg = <0x42530000 0x10000>;
> > +				interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPI2C3>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma2 5 0 0>, <&edma2 6 0 1>;
> 
> Please predefine macro, "1" should FSL_EDMA_RX

Will fix in v2.

BR

> 
> > +				dma-names = "tx", "rx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpi2c4: i2c at 42540000 {
> > +				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
> > +				reg = <0x42540000 0x10000>;
> > +				interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPI2C4>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma4 4 0 0>, <&edma4 5 0 1>;
> > +				dma-names = "tx", "rx";
> > +				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 71 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPSPI3>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma2 7 0 0>, <&edma2 8 0 1>;
> > +				dma-names = "tx", "rx";
> > +				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 72 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPSPI4>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma4 6 0 0>, <&edma4 7 0 1>;
> > +				dma-names = "tx", "rx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart3: serial at 42570000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x42570000 0x1000>;
> > +				interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART3>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma2 10 0 FSL_EDMA_RX>, <&edma2 9 0 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart4: serial at 42580000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x42580000 0x1000>;
> > +				interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART4>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma4 10 0 FSL_EDMA_RX>, <&edma4 9 0 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart5: serial at 42590000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x42590000 0x1000>;
> > +				interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART5>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma2 12 0 FSL_EDMA_RX>, <&edma2 11 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart6: serial at 425a0000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x425a0000 0x1000>;
> > +				interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART6>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma4 12 0 FSL_EDMA_RX>, <&edma4 11 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			flexcan2: can at 425b0000 {
> > +				compatible = "fsl,imx95-flexcan";
> > +				reg = <0x425b0000 0x10000>;
> > +				interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> > +					 <&scmi_clk IMX943_CLK_CAN2>;
> > +				clock-names = "ipg", "per";
> > +				fsl,clk-source = /bits/ 8 <0>;
> > +				status = "disabled";
> > +			};
> > +
> > +			flexcan3: can at 425e0000 {
> > +				compatible = "fsl,imx95-flexcan";
> > +				reg = <0x425e0000 0x10000>;
> > +				interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> > +					 <&scmi_clk IMX943_CLK_CAN3>;
> > +				clock-names = "ipg", "per";
> > +				fsl,clk-source = /bits/ 8 <0>;
> > +				status = "disabled";
> > +			};
> > +
> > +			flexcan4: can at 425f0000 {
> > +				compatible = "fsl,imx95-flexcan";
> > +				reg = <0x425f0000 0x10000>;
> > +				interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> > +					 <&scmi_clk IMX943_CLK_CAN4>;
> > +				clock-names = "ipg", "per";
> > +				fsl,clk-source = /bits/ 8 <0>;
> > +				status = "disabled";
> > +			};
> > +
> > +			flexcan5: can at 42600000 {
> > +				compatible = "fsl,imx95-flexcan";
> > +				reg = <0x42600000 0x10000>;
> > +				interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> > +					 <&scmi_clk IMX943_CLK_CAN5>;
> > +				clock-names = "ipg", "per";
> > +				fsl,clk-source = /bits/ 8 <0>;
> > +				status = "disabled";
> > +			};
> > +
> > +			sai2: sai at 42650000 {
> > +				compatible = "fsl,imx95-sai";
> > +				reg = <0x42650000 0x10000>;
> > +				interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> <&dummy>,
> > +					<&scmi_clk IMX943_CLK_SAI2>, <&dummy>,
> <&dummy>;
> > +				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
> > +				dmas = <&edma2 30 0 1>, <&edma2 29 0 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			sai3: sai at 42660000 {
> > +				compatible = "fsl,imx95-sai";
> > +				reg = <0x42660000 0x10000>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> <&dummy>,
> > +					<&scmi_clk IMX943_CLK_SAI3>, <&dummy>,
> <&dummy>;
> > +				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
> > +				interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
> > +				dmas = <&edma2 32 0 1>, <&edma2 31 0 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			sai4: sai at 42670000 {
> > +				compatible = "fsl,imx95-sai";
> > +				reg = <0x42670000 0x10000>;
> > +				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> <&dummy>,
> > +					<&scmi_clk IMX943_CLK_SAI4>, <&dummy>,
> <&dummy>;
> > +				interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> > +				dmas = <&edma2 36 0 1>, <&edma2 35 0 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart7: serial at 42690000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x42690000 0x1000>;
> > +				interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART7>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma2 46 0 FSL_EDMA_RX>, <&edma2 45 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart8: serial at 426a0000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x426a0000 0x1000>;
> > +				interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART8>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma4 39 0 FSL_EDMA_RX>, <&edma4 38 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpi2c5: i2c at 426b0000 {
> > +				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
> > +				reg = <0x426b0000 0x10000>;
> > +				interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPI2C5>,
> > +					 <&scmi_clk IMX943_CLK_BUS_AON>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma2 37 0 0>, <&edma2 38 0 1>;
> > +				dma-names = "tx", "rx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpi2c6: i2c at 426c0000 {
> > +				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
> > +				reg = <0x426c0000 0x10000>;
> > +				interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPI2C6>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas =<&edma4 30 0 0>, <&edma4 31 0 1>;
> > +				dma-names = "tx", "rx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpi2c7: i2c at 426d0000 {
> > +				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
> > +				reg = <0x426d0000 0x10000>;
> > +				interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPI2C7>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas =<&edma2 39 0 0>, <&edma2 40 0 1>;
> > +				dma-names = "tx", "rx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpi2c8: i2c at 426e0000 {
> > +				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
> > +				reg = <0x426e0000 0x10000>;
> > +				interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPI2C8>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas =<&edma4 32 0 0>, <&edma4 33 0 1>;
> > +				dma-names = "tx", "rx";
> > +				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 104 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPSPI5>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma2 41 0 0>, <&edma2 42 0 1>;
> > +				dma-names = "tx", "rx";
> > +				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 105 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPSPI6>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma4 34 0 0>, <&edma4 35 0 1>;
> > +				dma-names = "tx", "rx";
> > +				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 106 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPSPI7>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma2 43 0 0>, <&edma2 44 0 1>;
> > +				dma-names = "tx", "rx";
> > +				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 107 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPSPI8>,
> > +					 <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma4 36 0 0>, <&edma4 37 0 1>;
> > +				dma-names = "tx", "rx";
> > +				status = "disabled";
> > +			};
> > +
> > +			mu11: mailbox at 42730000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x42730000 0x10000>;
> > +				interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				#mbox-cells = <2>;
> > +				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>,
> > +				 <0x28000000 0x0 0x28000000 0x1000000>;
> > +
> > +			usdhc1: mmc at 42850000 {
> > +				compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
> > +				reg = <0x42850000 0x10000>;
> > +				interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> > +					 <&scmi_clk IMX943_CLK_WAKEUP_AXI>,
> > +					 <&scmi_clk IMX943_CLK_USDHC1>;
> > +				clock-names = "ipg", "ahb", "per";
> > +				assigned-clocks = <&scmi_clk IMX943_CLK_USDHC1>;
> > +				assigned-clock-parents = <&scmi_clk
> IMX943_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 97 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> > +					 <&scmi_clk IMX943_CLK_WAKEUP_AXI>,
> > +					 <&scmi_clk IMX943_CLK_USDHC2>;
> > +				clock-names = "ipg", "ahb", "per";
> > +				assigned-clocks = <&scmi_clk IMX943_CLK_USDHC2>;
> > +				assigned-clock-parents = <&scmi_clk
> IMX943_CLK_SYSPLL1_PFD1>;
> > +				assigned-clock-rates = <200000000>;
> > +				bus-width = <4>;
> > +				fsl,tuning-start-tap = <1>;
> > +				fsl,tuning-step= <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			usdhc3: mmc at 42880000 {
> > +				compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
> > +				reg = <0x428b0000 0x10000>;
> > +				interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>,
> > +					 <&scmi_clk IMX943_CLK_WAKEUP_AXI>,
> > +					 <&scmi_clk IMX943_CLK_USDHC3>;
> > +				clock-names = "ipg", "ahb", "per";
> > +				bus-width = <4>;
> > +				fsl,tuning-start-tap = <1>;
> > +				fsl,tuning-step= <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart9: serial at 42a50000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x42a50000 0x1000>;
> > +				interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART10>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma2 51 0 FSL_EDMA_RX>, <&edma2 50 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart10: serial at 42a60000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x42a60000 0x1000>;
> > +				interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART10>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma4 47 0 FSL_EDMA_RX>, <&edma4 46 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart11: serial at 42a70000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x42a70000 0x1000>;
> > +				interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART11>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma2 53 0 FSL_EDMA_RX>, <&edma2 52 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart12: serial at 42a80000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x42a80000 0x1000>;
> > +				interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART12>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma4 49 0 FSL_EDMA_RX>, <&edma4 48 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			mu12: mailbox at 42ac0000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x42ac0000 0x10000>;
> > +				interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			mu13: mailbox at 42ae0000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x42ae0000 0x10000>;
> > +				interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			mu14: mailbox at 42b00000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x42b00000 0x10000>;
> > +				interrupts = <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			mu15: mailbox at 42b20000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x42b20000 0x10000>;
> > +				interrupts = <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			mu16: mailbox at 42b40000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x42b40000 0x10000>;
> > +				interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			mu17: mailbox at 42b60000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x42b60000 0x10000>;
> > +				interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				#mbox-cells = <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 54 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
> > +			interrupt-controller;
> > +			#interrupt-cells = <2>;
> > +			gpio-ranges = <&scmi_iomuxc 0 4 32>;
> > +		};
> > +
> > +		gpio3: gpio at 43820000 {
> > +			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
> > +			reg = <0x0 0x43820000 0x0 0x1000>;
> > +			gpio-controller;
> > +			#gpio-cells = <2>;
> > +			interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
> > +			interrupt-controller;
> > +			#interrupt-cells = <2>;
> > +			gpio-ranges = <&scmi_iomuxc 0 36 26>;
> > +		};
> > +
> > +		gpio4: gpio at 43840000 {
> > +			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
> > +			reg = <0x0 0x43840000 0x0 0x1000>;
> > +			gpio-controller;
> > +			#gpio-cells = <2>;
> > +			interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
> > +			interrupt-controller;
> > +			#interrupt-cells = <2>;
> > +			gpio-ranges = <&scmi_iomuxc 0 62 4>, <&scmi_iomuxc 4 0 4>,
> > +				      <&scmi_iomuxc 8 140 12>, <&scmi_iomuxc 20 164
> 12>;
> > +		};
> > +
> > +		gpio5: gpio at 43850000 {
> > +			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
> > +			reg = <0x0 0x43850000 0x0 0x1000>;
> > +			gpio-controller;
> > +			#gpio-cells = <2>;
> > +			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
> > +			interrupt-controller;
> > +			#interrupt-cells = <2>;
> > +			gpio-ranges = <&scmi_iomuxc 0 108 32>;
> > +		};
> > +
> > +		gpio6: gpio at 43860000 {
> > +			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
> > +			reg = <0x0 0x43860000 0x0 0x1000>;
> > +			gpio-controller;
> > +			#gpio-cells = <2>;
> > +			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
> > +			interrupt-controller;
> > +			#interrupt-cells = <2>;
> > +			gpio-ranges = <&scmi_iomuxc 0 66 32>;
> > +		};
> > +
> > +		gpio7: gpio at 43870000 {
> > +			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
> > +			reg = <0x0 0x43870000 0x0 0x1000>;
> > +			gpio-controller;
> > +			#gpio-cells = <2>;
> > +			interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
> > +			interrupt-controller;
> > +			#interrupt-cells = <2>;
> > +			gpio-ranges = <&scmi_iomuxc 0 98 10>, <&scmi_iomuxc 16 152
> 12>;
> > +		};
> > +
> > +		aips1: bus at 44000000 {
> > +			compatible = "fsl,aips-bus", "simple-bus";
> > +			reg = <0x0 0x44000000 0x0 0x800000>;
> > +			#address-cells = <1>;
> > +			#size-cells = <1>;
> > +			ranges = <0x44000000 0x0 0x44000000 0x800000>;
> > +
> > +			edma1: dma-controller at 44000000 {
> > +				compatible = "fsl,imx93-edma3";
> > +				reg = <0x44000000 0x210000>;
> > +				#dma-cells = <3>;
> > +				dma-channels = <32>;
> > +				interrupts = <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_AON>;
> > +				clock-names = "dma";
> > +				status = "okay";
> > +			};
> > +
> > +			mu1: mailbox at 44220000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x44220000 0x10000>;
> > +				interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_AON>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			tpm1: pwm at 44310000 {
> > +				compatible = "fsl,imx7ulp-pwm";
> > +				reg = <0x44310000 0x1000>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_AON>;
> > +				#pwm-cells = <3>;
> > +				status = "disabled";
> > +			};
> > +
> > +			tpm2: pwm at 44320000 {
> > +				compatible = "fsl,imx7ulp-pwm";
> > +				reg = <0x44320000 0x1000>;
> > +				clocks = <&scmi_clk IMX943_CLK_TPM2>;
> > +				#pwm-cells = <3>;
> > +				status = "disabled";
> > +			};
> > +
> > +			i3c1: i3c-master at 44330000 {
> > +				#address-cells = <3>;
> > +				#size-cells = <0>;
> > +				compatible = "silvaco,i3c-master-v1";
> > +				reg = <0x44330000 0x10000>;
> > +				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_I3C1_SLOW>,
> > +					 <&scmi_clk IMX943_CLK_BUS_AON>,
> > +					 <&dummy>;
> > +				clock-names = "pclk", "fast_clk", "slow_clk";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpi2c1: i2c at 44340000 {
> > +				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
> > +				reg = <0x44340000 0x10000>;
> > +				interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPI2C1>,
> > +					 <&scmi_clk IMX943_CLK_BUS_AON>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma1 12 0 0>, <&edma1 13 0 1>;
> > +				dma-names = "tx", "rx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpi2c2: i2c at 44350000 {
> > +				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
> > +				reg = <0x44350000 0x10000>;
> > +				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPI2C2>,
> > +					 <&scmi_clk IMX943_CLK_BUS_AON>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma1 14 0 0>, <&edma1 15 0 1>;
> > +				dma-names = "tx", "rx";
> > +				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 18 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPSPI2>,
> > +					 <&scmi_clk IMX943_CLK_BUS_AON>;
> > +				clock-names = "per", "ipg";
> > +				dmas =<&edma1 16 0 0>, <&edma1 17 0 1>;
> > +				dma-names = "tx", "rx";
> > +				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 19 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPSPI2>,
> > +					 <&scmi_clk IMX943_CLK_BUS_AON>;
> > +				clock-names = "per", "ipg";
> > +				dmas = <&edma1 18 0 0>, <&edma1 19 0 1>;
> > +				dma-names = "tx", "rx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart1: serial at 44380000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x44380000 0x1000>;
> > +				interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART1>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma1 21 0 FSL_EDMA_RX>, <&edma1 20 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			lpuart2: serial at 44390000 {
> > +				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
> > +					     "fsl,imx7ulp-lpuart";
> > +				reg = <0x44390000 0x1000>;
> > +				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_LPUART2>;
> > +				clock-names = "ipg";
> > +				dmas = <&edma1 23 0 FSL_EDMA_RX>, <&edma1 22 0
> 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			flexcan1: can at 443a0000 {
> > +				compatible = "fsl,imx95-flexcan";
> > +				reg = <0x443a0000 0x10000>;
> > +				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> > +				status = "disabled";
> > +			};
> > +
> > +			sai1: sai at 443b0000 {
> > +				compatible = "fsl,imx95-sai";
> > +				reg = <0x443b0000 0x10000>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_AON>,
> <&dummy>,
> > +					<&scmi_clk IMX943_CLK_SAI1>, <&dummy>,
> > +					<&dummy>, <&dummy>;
> > +				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
> > +				interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
> > +				dmas = <&edma1 25 0 1>, <&edma1 24 0 0>;
> > +				dma-names = "rx", "tx";
> > +				status = "disabled";
> > +			};
> > +
> > +			adc1: adc at 44530000 {
> > +				compatible = "nxp,imx93-adc";
> > +				reg = <0x44530000 0x10000>;
> > +				interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_ADC>;
> > +				clock-names = "ipg";
> > +				status = "disabled";
> > +			};
> > +
> > +			mu2: mailbox at 445b0000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x445b0000 0x1000>;
> > +				ranges;
> > +				interrupts = <GIC_SPI 264 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 266 IRQ_TYPE_LEVEL_HIGH>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +
> > +			mu4: mailbox at 445f0000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x445f0000 0x10000>;
> > +				interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			mu6: mailbox at 44630000 {
> > +				compatible = "fsl,imx95-mu";
> > +				reg = <0x44630000 0x10000>;
> > +				interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
> > +				#mbox-cells = <2>;
> > +				status = "disabled";
> > +			};
> > +
> > +			a55_irqsteer: interrupt-controller at 446a0000 {
> > +				compatible = "fsl,imx-irqsteer";
> > +				reg = <0x446a0000 0x1000>;
> > +				interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>,
> > +					     <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_AON>;
> > +				clock-names = "ipg";
> > +				fsl,channel = <0>;
> > +				fsl,num-irqs = <960>;
> > +				interrupt-controller;
> > +				#interrupt-cells = <1>;
> > +			};
> > +		};
> > +
> > +		aips4: bus at 49000000 {
> > +			compatible = "fsl,aips-bus", "simple-bus";
> > +			reg = <0x0 0x49000000 0x0 0x800000>;
> > +			#address-cells = <1>;
> > +			#size-cells = <1>;
> > +			ranges = <0x49000000 0x0 0x49000000 0x800000>;
> > +
> > +			wdog3: wdog at 49220000 {
> > +				compatible = "fsl,imx93-wdt";
> > +				reg = <0x49220000 0x10000>;
> > +				interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
> > +				clocks = <&scmi_clk IMX943_CLK_BUS_WAKEUP>;
> > +				timeout-sec = <40>;
> > +				fsl,ext-reset-output;
> > +				status = "disabled";
> > +			};
> > +		};
> > +
> > +		ddr-pmu at 4e090dc0 {
> > +			compatible = "fsl,imx95-ddr-pmu", "fsl,imx93-ddr-pmu";
> > +			reg = <0x0 0x4e090dc0 0x0 0x200>;
> > +			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
> > +		};
> > +	};
> > +};
> > --
> > 2.34.1
> >

From m.felsch at pengutronix.de  Tue Dec 17 00:26:37 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Tue, 17 Dec 2024 09:26:37 +0100
Subject: [PATCH V2] soc: imx8m: Add remove function
In-Reply-To: <20241217015826.1374497-1-peng.fan@oss.nxp.com>
References: <20241217015826.1374497-1-peng.fan@oss.nxp.com>
Message-ID: <20241217082637.i2ou6bbr3tc3uvof@pengutronix.de>

Hi Peng,

thanks for you patch.

On 24-12-17, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Unregister the cpufreq device and soc device in remove path, otherwise

After reconsidiering the patch approach, I think we shouldn't add a
.remove() function and instead should make use of the devm_add_action()
mechanism for the proper unregister calls.

> there will be warning when do removing test:
> sysfs: cannot create duplicate filename '/devices/platform/imx-cpufreq-dt'
> CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.13.0-rc1-next-20241204
> Hardware name: NXP i.MX8MPlus EVK board (DT)
> 
> Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as platform driver")
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
> 
> V2:
>  Add err check when create the cpufreq platform device

thank you for addressing this.

Regards,
  Marco

>  drivers/soc/imx/soc-imx8m.c | 41 +++++++++++++++++++++++++++++++------
>  1 file changed, 35 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
> index 8ac7658e3d52..97c8718c2aa1 100644
> --- a/drivers/soc/imx/soc-imx8m.c
> +++ b/drivers/soc/imx/soc-imx8m.c
> @@ -33,6 +33,11 @@ struct imx8_soc_data {
>  	int (*soc_revision)(u32 *socrev, u64 *socuid);
>  };
>  
> +struct imx8m_soc_priv {
> +	struct soc_device *soc_dev;
> +	struct platform_device *cpufreq_dev;
> +};
> +
>  #ifdef CONFIG_HAVE_ARM_SMCCC
>  static u32 imx8mq_soc_revision_from_atf(void)
>  {
> @@ -195,10 +200,11 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
>  static int imx8m_soc_probe(struct platform_device *pdev)
>  {
>  	struct soc_device_attribute *soc_dev_attr;
> +	struct platform_device *cpufreq_dev;
>  	const struct imx8_soc_data *data;
>  	struct device *dev = &pdev->dev;
>  	const struct of_device_id *id;
> -	struct soc_device *soc_dev;
> +	struct imx8m_soc_priv *priv;
>  	u32 soc_rev = 0;
>  	u64 soc_uid = 0;
>  	int ret;
> @@ -207,6 +213,10 @@ static int imx8m_soc_probe(struct platform_device *pdev)
>  	if (!soc_dev_attr)
>  		return -ENOMEM;
>  
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
>  	soc_dev_attr->family = "Freescale i.MX";
>  
>  	ret = of_property_read_string(of_root, "model", &soc_dev_attr->machine);
> @@ -235,21 +245,40 @@ static int imx8m_soc_probe(struct platform_device *pdev)
>  	if (!soc_dev_attr->serial_number)
>  		return -ENOMEM;
>  
> -	soc_dev = soc_device_register(soc_dev_attr);
> -	if (IS_ERR(soc_dev))
> -		return PTR_ERR(soc_dev);
> +	priv->soc_dev = soc_device_register(soc_dev_attr);
> +	if (IS_ERR(priv->soc_dev))
> +		return PTR_ERR(priv->soc_dev);
>  
>  	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
>  		soc_dev_attr->revision);
>  
> -	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
> -		platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
> +	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) {
> +		cpufreq_dev = platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
> +		if (!IS_ERR(cpufreq_dev))
> +			priv->cpufreq_dev = cpufreq_dev;
> +		else
> +			dev_err(dev, "Failed to create imx-cpufreq-dev device: %ld",
> +				PTR_ERR(cpufreq_dev));
> +	}
> +
> +	platform_set_drvdata(pdev, priv);
>  
>  	return 0;
>  }
>  
> +static void imx8m_soc_remove(struct platform_device *pdev)
> +{
> +	struct imx8m_soc_priv *priv = platform_get_drvdata(pdev);
> +
> +	if (priv->cpufreq_dev)
> +		platform_device_unregister(priv->cpufreq_dev);
> +
> +	soc_device_unregister(priv->soc_dev);
> +}
> +
>  static struct platform_driver imx8m_soc_driver = {
>  	.probe = imx8m_soc_probe,
> +	.remove	= imx8m_soc_remove,
>  	.driver = {
>  		.name = "imx8m-soc",
>  	},
> -- 
> 2.37.1
> 
> 
> 


From maz at kernel.org  Tue Dec 17 00:27:07 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 08:27:07 +0000
Subject: [PATCH v2] arm64/sme: Move storage of reg_smidr to __cpuinfo_store_cpu()
In-Reply-To: <20241216-arm64-fix-boot-cpu-smidr-v2-1-a99ffba2c37f@kernel.org>
References: <20241216-arm64-fix-boot-cpu-smidr-v2-1-a99ffba2c37f@kernel.org>
Message-ID: <877c7ysois.wl-maz@kernel.org>

On Mon, 16 Dec 2024 22:09:57 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> In commit 892f7237b3ff ("arm64: Delay initialisation of
> cpuinfo_arm64::reg_{zcr,smcr}") we moved access to ZCR, SMCR and SMIDR
> later in the boot process in order to ensure that we don't attempt to
> interact with them if SVE or SME is disabled on the command line.
> Unfortunately when initialising the boot CPU in init_cpu_features() we work
> on a copy of the struct cpuinfo_arm64 for the boot CPU used only during
> boot, not the percpu copy used by the sysfs code. The expectation of the
> feature identification code was that the ID registers would be read in
> __cpuinfo_store_cpu() and the values not modified by init_cpu_features().
> 
> The main reason for the original change was to avoid early accesses to
> ZCR on practical systems that were seen shipping with SVE reported in ID
> registers but traps enabled at EL3 and handled as fatal errors, SME was
> rolled in due to the similarity with SVE. Since then we have removed the
> early accesses to ZCR and SMCR in commits:
> 
>   abef0695f9665c3d ("arm64/sve: Remove ZCR pseudo register from cpufeature code")
>   391208485c3ad50f ("arm64/sve: Remove SMCR pseudo register from cpufeature code")
> 
> so only the SMIDR_EL1 part of the change remains. Since SMIDR_EL1 is
> only trapped via FEAT_IDST and not the SME trap it is less likely to be
> affected by similar issues, and the factors that lead to issues with SVE
> are less likely to apply to SME.
> 
> Since we have not yet seen practical SME systems that need to use a
> command line override (and are only just beginning to see SME systems at
> all) let's just remove the override and store SMIDR_EL1 along with all
> the other ID register reads in __cpuinfo_store_cpu().
> 
> This issue wasn't apparent when testing on emulated platforms that do not
> report values in SMIDR_EL1.
> 
> Fixes: 892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")
> Signed-off-by: Mark Brown <broonie at kernel.org>
> Cc: stable at vger.kernel.org
> ---
> Changes in v2:
> - Move the ID register read back to __cpuinfo_store_cpu().
> - Remove the command line option for SME ID register override.
> - Link to v1: https://lore.kernel.org/r/20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd at kernel.org

My reading of the thread was that we don't need to kill the
arm64.nosme option as SMIDR_EL1 wouldn't UNDEF, which is guaranteed if
SME is implemented at all.

What was needed in 6.0 is not there anymore, for all the reasons that
Mark outlined and that you have pasted in the above commit message.

The removal of the arm64.nosme option is still a possibility, but
that's absolutely distinct from fixing the problem at hand.

	M.

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


From maz at kernel.org  Tue Dec 17 00:30:37 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 08:30:37 +0000
Subject: [PATCH] KVM: arm64: Fix set_id_regs selftest for ASIDBITS becoming unwritable
In-Reply-To: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
References: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
Message-ID: <875xnisocy.wl-maz@kernel.org>

On Mon, 16 Dec 2024 19:28:24 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> In commit 03c7527e97f7 ("KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits
> to be overridden") we made that bitfield in the ID registers unwritable
> however the change neglected to make the corresponding update to set_id_regs
> resulting in it failing:
> 
> # ok 56 ID_AA64MMFR0_EL1_BIGEND
> # ==== Test Assertion Failure ====
> #   aarch64/set_id_regs.c:434: masks[idx] & ftr_bits[j].mask == ftr_bits[j].mask
> #   pid=5566 tid=5566 errno=22 - Invalid argument
> #      1	0x00000000004034a7: test_vm_ftr_id_regs at set_id_regs.c:434
> #      2	0x0000000000401b53: main at set_id_regs.c:684
> #      3	0x0000ffff8e6b7543: ?? ??:0
> #      4	0x0000ffff8e6b7617: ?? ??:0
> #      5	0x0000000000401e6f: _start at ??:?
> #   0 != 0xf0 (masks[idx] & ftr_bits[j].mask != ftr_bits[j].mask)
> not ok 8 selftests: kvm: set_id_regs # exit=254
> 
> Remove ID_AA64MMFR1_EL1.ASIDBITS from the set of bitfields we test for
> writeability.
> 
> Fixes: 03c7527e97f7 ("KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden")

A patch for a test doesn't fix anything in the kernel.

> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  tools/testing/selftests/kvm/aarch64/set_id_regs.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/set_id_regs.c b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
> index a79b7f18452d2ec336ae623b8aa5c9cf329b6b4e..3a97c160b5fec990aaf8dfaf100a907b913f057c 100644
> --- a/tools/testing/selftests/kvm/aarch64/set_id_regs.c
> +++ b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
> @@ -152,7 +152,6 @@ static const struct reg_ftr_bits ftr_id_aa64mmfr0_el1[] = {
>  	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, BIGENDEL0, 0),
>  	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, SNSMEM, 0),
>  	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, BIGEND, 0),
> -	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, ASIDBITS, 0),
>  	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, PARANGE, 0),
>  	REG_FTR_END,
>  };
> 

With the Fixes: line dropped,

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

	M.

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


From andre.draszik at linaro.org  Tue Dec 17 00:34:50 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 17 Dec 2024 08:34:50 +0000
Subject: [PATCH 3/4] arm64: dts: exynos: gs101-oriole: move common
 Pixel6 & 6Pro parts into a .dtsi
In-Reply-To: <fw2a6taf4kd3sggmyppeym2uxkuyotxy7ugj3bh73vetnra4m6@jllekadordju>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
	 <20241216-gs101-simplefb-v1-3-8ccad1830281@linaro.org>
	 <fw2a6taf4kd3sggmyppeym2uxkuyotxy7ugj3bh73vetnra4m6@jllekadordju>
Message-ID: <6e22585f8d374f8e26a2a51153680041ad8b1bea.camel@linaro.org>

On Tue, 2024-12-17 at 08:38 +0100, Krzysztof Kozlowski wrote:
> On Mon, Dec 16, 2024 at 01:06:28PM +0000, Andr? Draszik wrote:
> > In order to support Pixel 6 (Oriole) and Pixel 6 Pro (Raven) properly,
> > we have to be able to distinguish them properly as we add support for
> > more features.
> > 
> > For example, Raven has a larger display. There are other differences,
> > like battery design capacity, etc.
> > 
> > Move all the parts that are common for now into a gs101-raviole.dtsi,
> > and just leave the display related things in gs101-oriole.dts.
> > 
> > Raviole was chosen as the name because Google uses that when referring
> > to the combination of Oriole & Raven, keeping the familiar terminology.
> > 
> > Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> > 
> > ---
> > Note: MAINTAINERS doesn't need updating, it covers this whole directory
> > ---
> > ?arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 290 +-------------------
> > ?.../boot/dts/exynos/google/gs101-raviole.dtsi????? | 297 +++++++++++++++++++++
> > ?2 files changed, 305 insertions(+), 282 deletions(-)
> > 
> 
> This looks like move of the code, so -M/-B/-C format patch arguments
> would create better diff.

Ah, yes, forgot about those when I switched to using b4 instead of
custom scripts...

Cheers,
Andre


From andre.draszik at linaro.org  Tue Dec 17 00:35:44 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Tue, 17 Dec 2024 08:35:44 +0000
Subject: [PATCH 4/4] arm64: dts: exynos: gs101-raven: add new board file
In-Reply-To: <2wyjctwn443oxl633qwxsxmyzqhinssrkoafgqhcc34tqgwnh5@ymrr57jxdnl6>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
	 <20241216-gs101-simplefb-v1-4-8ccad1830281@linaro.org>
	 <2wyjctwn443oxl633qwxsxmyzqhinssrkoafgqhcc34tqgwnh5@ymrr57jxdnl6>
Message-ID: <239cf14ad538285cea2f6ccdf2bd8fbdd2180bbc.camel@linaro.org>

On Tue, 2024-12-17 at 08:39 +0100, Krzysztof Kozlowski wrote:
> On Mon, Dec 16, 2024 at 01:06:29PM +0000, Andr? Draszik wrote:
> > Raven is Google's code name for Pixel 6 Pro. Similar to Pixel 6
> > (Oriole), this is also based around its Tensor gs101 SoC.
> > 
> > For now, the relevant difference here is the display resolution:
> > 1440 x 3120 instead of 1080 x 2400.
> > 
> > Create a new board file to reflect this difference.
> > 
> > Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> > 
> > ---
> > Note: MAINTAINERS doesn't need updating, it covers this whole directory
> > ---
> > ?arch/arm64/boot/dts/exynos/google/Makefile??????? |? 1 +
> > ?arch/arm64/boot/dts/exynos/google/gs101-raven.dts | 27 +++++++++++++++++++++++
> > ?2 files changed, 28 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/exynos/google/Makefile b/arch/arm64/boot/dts/exynos/google/Makefile
> > index 0a6d5e1fe4ee..7385f82b03c9 100644
> > --- a/arch/arm64/boot/dts/exynos/google/Makefile
> > +++ b/arch/arm64/boot/dts/exynos/google/Makefile
> > @@ -2,3 +2,4 @@
> > ?
> > ?dtb-$(CONFIG_ARCH_EXYNOS) += \
> > ?	gs101-oriole.dtb \
> > +	gs101-raven.dtb
> > diff --git a/arch/arm64/boot/dts/exynos/google/gs101-raven.dts b/arch/arm64/boot/dts/exynos/google/gs101-raven.dts
> > new file mode 100644
> > index 000000000000..75fd34797fa9
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/exynos/google/gs101-raven.dts
> > @@ -0,0 +1,27 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Raven Device Tree
> > + *
> > + * Copyright 2021-2023 Google LLC
> > + * Copyright 2023-2024 Linaro Ltd
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "gs101-raviole.dtsi"
> > +
> > +/ {
> > +	model = "Raven";
> > +	compatible = "google,gs101-raven", "google,gs101";
> > +};
> > +
> > +&framebuffer0 {
> > +	reg = <0x0 0xfac00000 (1440 * 3120 * 4)>;
> > +	width = <1440>;
> > +	height = <3120>;
> > +	stride = <(1440 * 4)>;
> > +};
> > +
> > +&cont_splash_mem {
> 
> Keep overriding/extending nodes ordered by label name.

OK - I had kept the original order (from dtsi), but will change.

Cheers,
Andre'



From tudor.ambarus at linaro.org  Tue Dec 17 00:38:29 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue, 17 Dec 2024 08:38:29 +0000
Subject: [PATCH v2 3/4] arm64: dts: exynos: gs101: add ACPM protocol node
In-Reply-To: <45a54924-226e-4a94-b1ae-b0f1f703f854@linaro.org>
References: <20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0@linaro.org>
 <20241212-b4-acpm-v4-upstream-dts-v2-3-91b7a6f6d0b0@linaro.org>
 <Z2B3V78k2ibIdLYh@google.com>
 <45a54924-226e-4a94-b1ae-b0f1f703f854@linaro.org>
Message-ID: <4e8936e0-ac69-49e8-919f-b2776dd88779@linaro.org>



On 12/17/24 7:20 AM, Tudor Ambarus wrote:
> 
> 
> On 12/16/24 6:54 PM, William McVicker wrote:
>> Hi Tudor,
> 
> Hi, William!
> 
>>
>> On 12/12/2024, Tudor Ambarus wrote:
>>> Add the ACPM protocol node. ACPM protocol provides interface for all
>>> the client drivers making use of the features offered by the
>>> Active Power Management (APM) module.
>>>
>>> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
>>> ---
>>>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 22 ++++++++++++++++++++++
>>>  1 file changed, 22 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>>> index 04561e15b96c..8c3f07371912 100644
>>> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>>> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>>> @@ -277,6 +277,28 @@ apm_sram: sram at 2039000 {
>>>  		ranges = <0x0 0x0 0x2039000 0x40000>;
>>>  	};
>>>  
>>> +	firmware {
>>> +		acpm_ipc: power-management {
>>> +			compatible = "google,gs101-acpm-ipc";
>>> +			mboxes = <&ap2apm_mailbox 0 0
>>> +				  &ap2apm_mailbox 0 1
>>> +				  &ap2apm_mailbox 0 2
>>> +				  &ap2apm_mailbox 0 3
>>> +				  &ap2apm_mailbox 0 4
>>> +				  &ap2apm_mailbox 0 5
>>> +				  &ap2apm_mailbox 0 6
>>> +				  &ap2apm_mailbox 0 7
>>> +				  &ap2apm_mailbox 0 8
>>> +				  &ap2apm_mailbox 0 9
>>> +				  &ap2apm_mailbox 0 10
>>> +				  &ap2apm_mailbox 0 11
>>> +				  &ap2apm_mailbox 0 12
>>> +				  &ap2apm_mailbox 0 13
>>> +				  &ap2apm_mailbox 0 14>;
>>> +			shmem = <&apm_sram>;
>>> +		};
>>> +	};
>>
>> You mentioned in the previous patch that "GS101 has 14 mailbox controllers",
> 
> Right, I got the number from the GS101 memory map.
> 
>> but here you have 15 mailboxes. I looked at the downstream driver and see the
> 
> Here we have a single mailbox controller, ap2apm_mailbox, with 15 channels.
> 
>> number of mailboxes is defined by the ACPM framework (firmware) which is read
> 
> s/mailboxes/mailbox channels that ACPM uses/
> 
>> from SRAM initdata. Dumping that, I see there are 15 ACPM channels. Have you
> 
> Correct.
> 
>> looked into into extracting the data from the initdata SRAM address?
>>
> 
> Yes, that's the reason why I defined the 15 channels from above for the
> ap2apm_mailbox controller.
> 

Haven't explicitly mentioned in the commit message: the ACPM protocol is
a mailbox client for the ap2apm_mailbox controller. The ACPM protocol
uses 15 mailbox channels of a total of 16 channels that ap2apm_mailbox
controller provides.

Let me know if you think I shall update the commit message.
Thanks,
ta


From anshuman.khandual at arm.com  Tue Dec 17 00:48:27 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 17 Dec 2024 14:18:27 +0530
Subject: [PATCH V3 6/7] arm64/boot: Enable EL2 requirements for
 FEAT_Debugv8p9
In-Reply-To: <20241216234251.GA629562-robh@kernel.org>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
 <20241216040831.2448257-7-anshuman.khandual@arm.com>
 <20241216234251.GA629562-robh@kernel.org>
Message-ID: <c64709f7-e1c6-482e-8665-912be50b15bd@arm.com>

On 12/17/24 05:12, Rob Herring wrote:
> On Mon, Dec 16, 2024 at 09:38:30AM +0530, Anshuman Khandual wrote:
>> Fine grained trap control for MDSELR_EL1 register needs to be configured in
>> HDFGRTR2_EL2, and HDFGWTR2_EL2 registers when kernel enters at EL1, but EL2
>> is also present.
> 
> Shouldn't this be "when kernel enters at EL2, and EL3 is also present"?

AFAICT - HDFGRTR2_EL2 and HDFGWTR2_EL2 registers configure traps into EL2 when
accessed from EL1/EL0, provided all required EL3 trap controls are in place as
well. These EL2 based trap configs need to be set before the kernel finally
enters EL1. Although there is an assumption about EL3 based trap configs being
in place, do we need to mention that in commit message as well. Is not updating 
booting.rst takes care of all EL3 requirements.

> Though it is really "If EL3 set FGTEn2 and the kernel is entered in 
> EL2, then FGT2 must be initialized for MDSELR_EL1."
> 
> If it was me, I'd just plagarize what was written for prior FGT 
> commits for this code. :)

There are many commits that changed __init_el2_fgt() with different description
formats. Do you have particular one in mind which can be followed here ? :)

> 
>> This adds a new helper __init_el2_fgt2() initializing this
>> new FEAT_FGT2 based fine grained registers.
> 
> "This adds" is the same as saying "This patch/commit adds" which is well 
> documented to avoid. Use imperative "Add a new helper...". Though it is 
> clear from the diff that is what you are doing...

Sure, will fix it.

> 
> 
>> MDCR_EL2.EBWE needs to be enabled for additional (beyond 16) breakpoint and
>> watchpoint exceptions when kernel enters at EL1, but EL2 is also present.
>> This updates __init_el2_debug() as required for FEAT_Debugv8p9.
>>
>> While here, also update booting.rst with MDCR_EL3 and SCR_EL3 requirements.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Jonathan Corbet <corbet at lwn.net>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: Oliver Upton <oliver.upton at linux.dev>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-doc at vger.kernel.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: kvmarm at lists.linux.dev
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> Changes in V3:
>>
>> - Dropped MDCR_EL3.TDA boot requirement from documentation (separate series)
>> - Dropped MDCR_EL2_EBWE definition as MDCR_EL2 is now defined in tools sysreg
>>
>> https://lore.kernel.org/all/20241211065425.1106683-1-anshuman.khandual at arm.com/
>>
>>  Documentation/arch/arm64/booting.rst | 18 ++++++++++++++++++
>>  arch/arm64/include/asm/el2_setup.h   | 26 ++++++++++++++++++++++++++
>>  2 files changed, 44 insertions(+)
>>
>> diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
>> index 3278fb4bf219..054cfe1cad18 100644
>> --- a/Documentation/arch/arm64/booting.rst
>> +++ b/Documentation/arch/arm64/booting.rst
>> @@ -288,6 +288,12 @@ Before jumping into the kernel, the following conditions must be met:
>>  
>>      - SCR_EL3.FGTEn (bit 27) must be initialised to 0b1.
>>  
>> +  For CPUs with the Fine Grained Traps (FEAT_FGT2) extension present:
>> +
>> +  - If EL3 is present and the kernel is entered at EL2:
>> +
>> +    - SCR_EL3.FGTEn2 (bit 59) must be initialised to 0b1.
>> +
>>    For CPUs with support for HCRX_EL2 (FEAT_HCX) present:
>>  
>>    - If EL3 is present and the kernel is entered at EL2:
>> @@ -322,6 +328,18 @@ Before jumping into the kernel, the following conditions must be met:
>>      - ZCR_EL2.LEN must be initialised to the same value for all CPUs the
>>        kernel will execute on.
>>  
>> +  For CPUs with FEAT_Debugv8p9 extension present:
>> +
>> +  - If the kernel is entered at EL1 and EL2 is present:
>> +
>> +    - HDFGRTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1
>> +    - HDFGWTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1
>> +    - MDCR_EL2.EBWE (bit 43) must be initialized to 0b1
>> +
>> +  - If EL3 is present:
>> +
>> +    - MDCR_EL3.EBWE (bit 43) must be initialized to 0b1
>> +
>>    For CPUs with the Scalable Matrix Extension (FEAT_SME):
>>  
>>    - If EL3 is present:
>> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
>> index 4ef52d7245bb..2fbfe27d38b5 100644
>> --- a/arch/arm64/include/asm/el2_setup.h
>> +++ b/arch/arm64/include/asm/el2_setup.h
>> @@ -105,6 +105,13 @@
>>  						// to own it.
>>  
>>  .Lskip_trace_\@:
>> +	mrs	x1, id_aa64dfr0_el1
>> +	ubfx	x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
>> +	cmp	x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
>> +	b.lt	.Lskip_dbg_v8p9_\@
>> +
>> +	orr	x2, x2, #MDCR_EL2_EBWE
>> +.Lskip_dbg_v8p9_\@:
>>  	msr	mdcr_el2, x2			// Configure debug traps
>>  .endm
>>  
>> @@ -244,6 +251,24 @@
>>  .Lskip_gcs_\@:
>>  .endm
>>  
>> +.macro __init_el2_fgt2
>> +	mrs	x1, id_aa64mmfr0_el1
>> +	ubfx	x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
>> +	cmp	x1, #ID_AA64MMFR0_EL1_FGT_FGT2
> 
> We already read this field in __init_el2_fgt, shouldn't we leverage that 
> and move all this there rather than read the feature reg twice.

Should not __init_el2_fgt2() remain separate to contain all future FEAT_FGT2
related trap enabled/disable checks ? OTOH reading id_aa64mmfr0_el1 register
should improve some performance as well.

> 
>> +	b.lt	.Lskip_fgt2_\@
>> +
>> +	mrs	x1, id_aa64dfr0_el1
>> +	ubfx	x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
>> +	cmp	x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
>> +	b.lt	.Lskip_dbg_v8p9_\@
>> +
>> +	mov_q   x0, HDFGWTR2_EL2_nMDSELR_EL1
>> +	msr_s	SYS_HDFGWTR2_EL2, x0
>> +	msr_s	SYS_HDFGRTR2_EL2, x0
> 
> If Debug v8.9 is not present, but FGT2 is, shouldn't we write 0 to these 
> registers? That is what we do for FGT.

Just to summerize what's being done in __init_el2_fgt()

.macro __init_el2_fgt
	...............
	mov     x0, xzr
	...............
.Lskip_spe_fgt_\@:
        msr_s   SYS_HDFGRTR_EL2, x0
        msr_s   SYS_HDFGWTR_EL2, x0
	...............
.Lset_fgt_\@:
        msr_s   SYS_HFGRTR_EL2, x0
        msr_s   SYS_HFGWTR_EL2, x0
        msr_s   SYS_HFGITR_EL2, xzr
	...............

If the relevant features are not present and their traps need not be handled,
all FEAT_FGT based trap control registers (SYS_HDFGRTR_EL2, SYS_HDFGWTR_EL2,
SYS_HFGRTR_EL2, SYS_HFGWTR_EL2 and SYS_HFGITR_EL2) get cleared. Hence same
needs to be done for all FEAT_FGT2 register as well. Fair enough, something
like the following makes sense ?

.macro __init_el2_fgt2
        mrs     x1, id_aa64mmfr0_el1
        ubfx    x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
        cmp     x1, #ID_AA64MMFR0_EL1_FGT_FGT2
        b.lt    .Lskip_fgt2_\@

        mov     x0, xzr
        mrs     x1, id_aa64dfr0_el1
        ubfx    x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
        cmp     x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
        b.lt    .Lskip_dbg_v8p9_\@

        orr     x0, x0, #HDFGWTR2_EL2_nMDSELR_EL1
.Lskip_dbg_v8p9_\@:
        msr_s   SYS_HDFGWTR2_EL2, x0
        msr_s   SYS_HDFGRTR2_EL2, x0
        msr_s   SYS_HFGRTR2_EL2, xzr
        msr_s   SYS_HFGWTR2_EL2, xzr
        msr_s   SYS_HFGITR2_EL2, xzr
.Lskip_fgt2_\@:
.endm

Just wondering - following the same principle if clearing these FEAT_FGT2 trap
registers would make sense in itself, even without FEAT_Debugv8p9 enablement ?

Something like the commit

commit 31c00d2aeaa2da89361f5b64a64ca831433be5fc
Author: Mark Brown <broonie at kernel.org>
Date:   Thu Apr 1 19:09:40 2021 +0100

    arm64: Disable fine grained traps on boot
    
    The arm64 FEAT_FGT extension introduces a set of traps to EL2 for accesses
    to small sets of registers and instructions from EL1 and EL0.  Currently
    Linux makes no use of this feature, ensure that it is not active at boot by
    disabling the traps during EL2 setup.


> 
> 
> I just realized I forgot to add FGT2 setup for the PMUv3.9 features I 
> already added in 6.12 and 6.13. So this really needs to land sooner 
> rather than later to add that. 
Not sure if I got this correctly. Are you suggesting to carve out __init_el2_fgt2()
from the series and post separately with PMUv3.9 requirements and fallback clearing
for all FEAT_FGT2 trap config registers as mentioned above ?


From ping.bai at nxp.com  Tue Dec 17 00:42:00 2024
From: ping.bai at nxp.com (Jacky Bai)
Date: Tue, 17 Dec 2024 08:42:00 +0000
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <z6udhrqfmbelspe3eiz2q6twqvn4nkgxnfsdyxdv7ow6llxiz6@qhbaobn63icb>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
 <z6udhrqfmbelspe3eiz2q6twqvn4nkgxnfsdyxdv7ow6llxiz6@qhbaobn63icb>
Message-ID: <AS8PR04MB8642C9A1DA27CD0F3F51DF2287042@AS8PR04MB8642.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
> 
> On Thu, Dec 12, 2024 at 05:35:55PM +0800, Jacky Bai wrote:
> > The i.MX 943 applications processors integrate up to four Arm Cortex
> > A55 cores and supports functional safety with built-in 2x Arm Cortex
> > M33 and M7 cores which can be configured asa safety island. Optimizing
> > performance and power efficiency for Industrial, IoT and automotive
> > devices, i.MX 943 processors are built with NXP?s innovative Energy
> > Flex architecture.
> >
> > This patch adds the minimal dtsi support for i.MX943 with peripherals
> > like uart, edma, i2c, spi, mu, sai etc.
> >
> > Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/imx943-clock.h  |  196 +++
> > .../arm64/boot/dts/freescale/imx943-pinfunc.h | 1542
> +++++++++++++++++
> >  arch/arm64/boot/dts/freescale/imx943-power.h  |   41 +
> >  arch/arm64/boot/dts/freescale/imx943.dtsi     | 1284
> ++++++++++++++
> >  4 files changed, 3063 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943-clock.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943-pinfunc.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943-power.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943.dtsi
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx943-clock.h
> > b/arch/arm64/boot/dts/freescale/imx943-clock.h
> > new file mode 100644
> > index 000000000000..64b9d5d4051e
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/imx943-clock.h
> > @@ -0,0 +1,196 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
> > +/*
> > + * Copyright 2024 NXP
> > + */
> > +
> > +#ifndef __CLOCK_IMX943_H
> > +#define __CLOCK_IMX943_H
> > +
> > +#define IMX943_CLK_EXT				0
> > +#define IMX943_CLK_OSC32K			1
> > +#define IMX943_CLK_OSC24M			2
> 
> 
> Why exactly are you adding clock indices to header files? Nothing in commit
> msg explains that.

These clock index macro defines will be used in dtsi or dts for clock reference.
I just follow the way that we have done for i.MX95. Anything need to be improved or refined?
For commit msg, I will add some explains in v2.

BR
> 
> Best regards,
> Krzysztof


From luca.ceresoli at bootlin.com  Tue Dec 17 00:42:19 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Tue, 17 Dec 2024 09:42:19 +0100
Subject: imx8m-blk-ctrl: WARNING, no release() function
In-Reply-To: <PAXPR04MB8459AB53B142CB43782757D988042@PAXPR04MB8459.eurprd04.prod.outlook.com>
References: <20241212141003.GA44219@francesco-nb>
	<PAXPR04MB8459AB53B142CB43782757D988042@PAXPR04MB8459.eurprd04.prod.outlook.com>
Message-ID: <20241217094219.788cad88@booty>

Hello Peng,

On Tue, 17 Dec 2024 01:39:09 +0000
Peng Fan <peng.fan at nxp.com> wrote:

> > Subject: imx8m-blk-ctrl: WARNING, no release() function  
> 
> Please try this patch.
> https://lore.kernel.org/all/20241206112731.98244-1-peng.fan at oss.nxp.com/

I cherry-picked the two patches from linux-next:

  e1a875703470 ("pmdomain: imx-gpcv2: Suppress bind attrs")
  afb2a86f002b ("pmdomain: imx8m[p]-blk-ctrl: Suppress bind attrs")

but I still have the same warnings:

[    5.427038] Device 'mediablk-mipi-csi2-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
[    6.464219] Device 'mediablk-mipi-dsi-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
[    6.752903] Device 'mediablk-mipi-csi2-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
[    7.303529] Device 'mediablk-mipi-dsi-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
[    8.006575] Device 'mediablk-mipi-csi2-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
[    8.598453] Device 'mediablk-mipi-dsi-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.

This is with 6.13-rc3 on a imx8mp.

Luca

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From mkl at pengutronix.de  Tue Dec 17 00:43:09 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 17 Dec 2024 09:43:09 +0100
Subject: [PATCH 0/2] rockchip: add can for RK3576 Soc
In-Reply-To: <20241217023908.1292999-1-zhangqing@rock-chips.com>
References: <20241217023908.1292999-1-zhangqing@rock-chips.com>
Message-ID: <20241217-hallowed-adder-of-swiftness-3cd239-mkl@pengutronix.de>

On 17.12.2024 10:39:06, Elaine Zhang wrote:
> rk3576 can is a new controller:
> Support CAN and CANFD protocol.
> Support DMA
> 
> There are major differences from the previous rk3568. All errata on the
> rk3568 have been fixed and redesigned.

I'm not convinced that we need a second driver for the hardware that has
the erratas fixed. The mainline driver has quirks that allow you to
specify if the IP core needs workarounds for the errata or not.

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/20241217/7a105a20/attachment.sig>

From tabba at google.com  Tue Dec 17 00:43:05 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:43:05 +0000
Subject: [PATCH v3 01/18] KVM: arm64: Change the layout of enum pkvm_page_state
In-Reply-To: <20241216175803.2716565-2-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-2-qperret@google.com>
Message-ID: <CA+EHjTzYA5tFSR8YUfuEGzPjDYnp1a+T=K6AfwjGUVmxcQudjA@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> The 'concrete' (a.k.a non-meta) page states are currently encoded using
> software bits in PTEs. For performance reasons, the abstract
> pkvm_page_state enum uses the same bits to encode these states as that
> makes conversions from and to PTEs easy.
>
> In order to prepare the ground for moving the 'concrete' state storage
> to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this
> purpose.
>
> No functional changes intended.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 0972faccc2af..8c30362af2b9 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -24,25 +24,27 @@
>   */
>  enum pkvm_page_state {
>         PKVM_PAGE_OWNED                 = 0ULL,
> -       PKVM_PAGE_SHARED_OWNED          = KVM_PGTABLE_PROT_SW0,
> -       PKVM_PAGE_SHARED_BORROWED       = KVM_PGTABLE_PROT_SW1,
> -       __PKVM_PAGE_RESERVED            = KVM_PGTABLE_PROT_SW0 |
> -                                         KVM_PGTABLE_PROT_SW1,
> +       PKVM_PAGE_SHARED_OWNED          = BIT(0),
> +       PKVM_PAGE_SHARED_BORROWED       = BIT(1),
> +       __PKVM_PAGE_RESERVED            = BIT(0) | BIT(1),
>
>         /* Meta-states which aren't encoded directly in the PTE's SW bits */
> -       PKVM_NOPAGE,
> +       PKVM_NOPAGE                     = BIT(2),
>  };
> +#define PKVM_PAGE_META_STATES_MASK     (~(BIT(0) | BIT(1)))
>
>  #define PKVM_PAGE_STATE_PROT_MASK      (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
>  static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
>                                                  enum pkvm_page_state state)
>  {
> -       return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
> +       prot &= ~PKVM_PAGE_STATE_PROT_MASK;
> +       prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
> +       return prot;
>  }
>
>  static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
>  {
> -       return prot & PKVM_PAGE_STATE_PROT_MASK;
> +       return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
>  }
>
>  struct host_mmu {
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 00:43:32 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:43:32 +0000
Subject: [PATCH v3 02/18] KVM: arm64: Move enum pkvm_page_state to memory.h
In-Reply-To: <20241216175803.2716565-3-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-3-qperret@google.com>
Message-ID: <CA+EHjTxmt4QdmiqCCJh9kf9aGL36hVXRXCr+EgdT1TDk_arJ=w@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> In order to prepare the way for storing page-tracking information in
> pKVM's vmemmap, move the enum pkvm_page_state definition to
> nvhe/memory.h.
>
> No functional changes intended.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 34 +------------------
>  arch/arm64/kvm/hyp/include/nvhe/memory.h      | 33 ++++++++++++++++++
>  2 files changed, 34 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 8c30362af2b9..25038ac705d8 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -11,42 +11,10 @@
>  #include <asm/kvm_mmu.h>
>  #include <asm/kvm_pgtable.h>
>  #include <asm/virt.h>
> +#include <nvhe/memory.h>
>  #include <nvhe/pkvm.h>
>  #include <nvhe/spinlock.h>
>
> -/*
> - * SW bits 0-1 are reserved to track the memory ownership state of each page:
> - *   00: The page is owned exclusively by the page-table owner.
> - *   01: The page is owned by the page-table owner, but is shared
> - *       with another entity.
> - *   10: The page is shared with, but not owned by the page-table owner.
> - *   11: Reserved for future use (lending).
> - */
> -enum pkvm_page_state {
> -       PKVM_PAGE_OWNED                 = 0ULL,
> -       PKVM_PAGE_SHARED_OWNED          = BIT(0),
> -       PKVM_PAGE_SHARED_BORROWED       = BIT(1),
> -       __PKVM_PAGE_RESERVED            = BIT(0) | BIT(1),
> -
> -       /* Meta-states which aren't encoded directly in the PTE's SW bits */
> -       PKVM_NOPAGE                     = BIT(2),
> -};
> -#define PKVM_PAGE_META_STATES_MASK     (~(BIT(0) | BIT(1)))
> -
> -#define PKVM_PAGE_STATE_PROT_MASK      (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
> -static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
> -                                                enum pkvm_page_state state)
> -{
> -       prot &= ~PKVM_PAGE_STATE_PROT_MASK;
> -       prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
> -       return prot;
> -}
> -
> -static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
> -{
> -       return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
> -}
> -
>  struct host_mmu {
>         struct kvm_arch arch;
>         struct kvm_pgtable pgt;
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> index ab205c4d6774..c84b24234ac7 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> @@ -7,6 +7,39 @@
>
>  #include <linux/types.h>
>
> +/*
> + * SW bits 0-1 are reserved to track the memory ownership state of each page:
> + *   00: The page is owned exclusively by the page-table owner.
> + *   01: The page is owned by the page-table owner, but is shared
> + *       with another entity.
> + *   10: The page is shared with, but not owned by the page-table owner.
> + *   11: Reserved for future use (lending).
> + */
> +enum pkvm_page_state {
> +       PKVM_PAGE_OWNED                 = 0ULL,
> +       PKVM_PAGE_SHARED_OWNED          = BIT(0),
> +       PKVM_PAGE_SHARED_BORROWED       = BIT(1),
> +       __PKVM_PAGE_RESERVED            = BIT(0) | BIT(1),
> +
> +       /* Meta-states which aren't encoded directly in the PTE's SW bits */
> +       PKVM_NOPAGE                     = BIT(2),
> +};
> +#define PKVM_PAGE_META_STATES_MASK     (~(BIT(0) | BIT(1)))
> +
> +#define PKVM_PAGE_STATE_PROT_MASK      (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
> +static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
> +                                                enum pkvm_page_state state)
> +{
> +       prot &= ~PKVM_PAGE_STATE_PROT_MASK;
> +       prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
> +       return prot;
> +}
> +
> +static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
> +{
> +       return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
> +}
> +
>  struct hyp_page {
>         unsigned short refcount;
>         unsigned short order;
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From peng.fan at oss.nxp.com  Tue Dec 17 00:43:35 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 17 Dec 2024 16:43:35 +0800
Subject: [PATCH v2 0/2] Make i.MX9 OCOTP work as accessing controller
Message-ID: <20241217-imx-ocotp-v2-0-3faa6cbff41b@nxp.com>

Previously there was discussion on using "feature-controller" or
adding a specific node to group the fuse information for U-Boot to
parse and update node. But rejected by DT maintainer(Rob).

Since the STM32 engineers added access controller concept and landed
the support in Linux Kernel, reuse the concept for i.MX.

i.MX OCOTP eFuse has some bits to indicate a specific periphral or
function is avaiable for current chip, for example i.MX93 has variants
that not have NPU. So introduce '#access-controller-cells' for OCOTP,
and add "#access-controllers = <&ocotp [gate_index]>" for periphrals
that needs accessing control checking.

In OCOTP driver, the nodes under "/" will be iterated, and checked
if property "#access-controllers" exsits. If not allow access, detach
the node.

In the end, cpu nodes should still be handled by bootloader.
And I may also update i.MX8M to use same method to support variants
if this patchset is good.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Changes in v2:
- Add R-b for patch 1
- Use '/' root node instead of '/soc' or '/soc at 0' for patch 2
- Link to v1: https://lore.kernel.org/r/20241212-imx-ocotp-v1-0-198bb0af86a0 at nxp.com

---
Peng Fan (2):
      dt-bindings: nvmem: imx-ocotp: Introduce #access-controller-cells
      nvmem: imx-ocotp-ele: Support accessing controller for i.MX9

 .../devicetree/bindings/nvmem/imx-ocotp.yaml       |   5 +
 drivers/nvmem/imx-ocotp-ele.c                      | 184 ++++++++++++++++++++-
 include/dt-bindings/nvmem/fsl,imx93-ocotp.h        |  24 +++
 include/dt-bindings/nvmem/fsl,imx95-ocotp.h        |  43 +++++
 4 files changed, 255 insertions(+), 1 deletion(-)
---
base-commit: d49bc7ced87506bedbcce1ca7782ff942b309f2d
change-id: 20241212-imx-ocotp-cbef304140f5

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Tue Dec 17 00:43:36 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 17 Dec 2024 16:43:36 +0800
Subject: [PATCH v2 1/2] dt-bindings: nvmem: imx-ocotp: Introduce
 #access-controller-cells
In-Reply-To: <20241217-imx-ocotp-v2-0-3faa6cbff41b@nxp.com>
References: <20241217-imx-ocotp-v2-0-3faa6cbff41b@nxp.com>
Message-ID: <20241217-imx-ocotp-v2-1-3faa6cbff41b@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Introduce "#access-controller-cells" to make OCOTP be an accessing
controller, because i.MX Family OCOTP supports a specific peripheral
or function being fused which means being disabled.

Add the i.MX[95,93] OCOTP gate index.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/nvmem/imx-ocotp.yaml       |  5 +++
 include/dt-bindings/nvmem/fsl,imx93-ocotp.h        | 24 ++++++++++++
 include/dt-bindings/nvmem/fsl,imx95-ocotp.h        | 43 ++++++++++++++++++++++
 3 files changed, 72 insertions(+)

diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
index b2cb76cf9053a883a158acaf5eaa108895818afc..c78e202ced22f1c278f7be827b71ba434832d2a7 100644
--- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
+++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
@@ -54,6 +54,11 @@ properties:
   clocks:
     maxItems: 1
 
+  "#access-controller-cells":
+    const: 1
+    description:
+      Contains the gate ID associated to the peripheral.
+
 required:
   - "#address-cells"
   - "#size-cells"
diff --git a/include/dt-bindings/nvmem/fsl,imx93-ocotp.h b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ef525173845fd4ee0e847cf5a17e53a14f71362
--- /dev/null
+++ b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+#ifndef _DT_BINDINGS_NVMEM_IMX93_OTPC_H
+#define _DT_BINDINGS_NVMEM_IMX93_OTPC_H
+
+#define IMX93_OCOTP_NPU_GATE		0
+#define IMX93_OCOTP_A550_GATE		1
+#define IMX93_OCOTP_A551_GATE		2
+#define IMX93_OCOTP_M33_GATE		3
+#define IMX93_OCOTP_CAN1_FD_GATE	4
+#define IMX93_OCOTP_CAN2_FD_GATE	5
+#define IMX93_OCOTP_CAN1_GATE		6
+#define IMX93_OCOTP_CAN2_GATE		7
+#define IMX93_OCOTP_USB1_GATE		8
+#define IMX93_OCOTP_USB2_GATE		9
+#define IMX93_OCOTP_ENET1_GATE		10
+#define IMX93_OCOTP_ENET2_GATE		11
+#define IMX93_OCOTP_PXP_GATE		12
+#define IMX93_OCOTP_MIPI_CSI1_GATE	13
+#define IMX93_OCOTP_MIPI_DSI1_GATE	14
+#define IMX93_OCOTP_LVDS1_GATE		15
+#define IMX93_OCOTP_ADC1_GATE		16
+
+#endif
diff --git a/include/dt-bindings/nvmem/fsl,imx95-ocotp.h b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d21d1f690974d0215c71352168378a150f489af
--- /dev/null
+++ b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+#ifndef _DT_BINDINGS_NVMEM_IMX95_OTPC_H
+#define _DT_BINDINGS_NVMEM_IMX95_OTPC_H
+
+#define IMX95_OCOTP_CANFD1_GATE		0
+#define IMX95_OCOTP_CANFD2_GATE		1
+#define IMX95_OCOTP_CANFD3_GATE		2
+#define IMX95_OCOTP_CANFD4_GATE		3
+#define IMX95_OCOTP_CANFD5_GATE		4
+#define IMX95_OCOTP_CAN1_GATE		5
+#define IMX95_OCOTP_CAN2_GATE		6
+#define IMX95_OCOTP_CAN3_GATE		7
+#define IMX95_OCOTP_CAN4_GATE		8
+#define IMX95_OCOTP_CAN5_GATE		9
+#define IMX95_OCOTP_NPU_GATE		10
+#define IMX95_OCOTP_A550_GATE		11
+#define IMX95_OCOTP_A551_GATE		12
+#define IMX95_OCOTP_A552_GATE		13
+#define IMX95_OCOTP_A553_GATE		14
+#define IMX95_OCOTP_A554_GATE		15
+#define IMX95_OCOTP_A555_GATE		16
+#define IMX95_OCOTP_M7_GATE		17
+#define IMX95_OCOTP_DCSS_GATE		18
+#define IMX95_OCOTP_LVDS1_GATE		19
+#define IMX95_OCOTP_ISP_GATE		20
+#define IMX95_OCOTP_USB1_GATE		21
+#define IMX95_OCOTP_USB2_GATE		22
+#define IMX95_OCOTP_NETC_GATE		23
+#define IMX95_OCOTP_PCIE1_GATE		24
+#define IMX95_OCOTP_PCIE2_GATE		25
+#define IMX95_OCOTP_ADC1_GATE		26
+#define IMX95_OCOTP_EARC_RX_GATE	27
+#define IMX95_OCOTP_GPU3D_GATE		28
+#define IMX95_OCOTP_VPU_GATE		29
+#define IMX95_OCOTP_JPEG_ENC_GATE	30
+#define IMX95_OCOTP_JPEG_DEC_GATE	31
+#define IMX95_OCOTP_MIPI_CSI1_GATE	32
+#define IMX95_OCOTP_MIPI_CSI2_GATE	33
+#define IMX95_OCOTP_MIPI_DSI1_GATE	34
+#define IMX95_OCOTP_V2X_GATE		35
+
+#endif

-- 
2.37.1



From peng.fan at oss.nxp.com  Tue Dec 17 00:43:37 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 17 Dec 2024 16:43:37 +0800
Subject: [PATCH v2 2/2] nvmem: imx-ocotp-ele: Support accessing controller
 for i.MX9
In-Reply-To: <20241217-imx-ocotp-v2-0-3faa6cbff41b@nxp.com>
References: <20241217-imx-ocotp-v2-0-3faa6cbff41b@nxp.com>
Message-ID: <20241217-imx-ocotp-v2-2-3faa6cbff41b@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX9 OCOTP supports a specific peripheral or function being fused
which means disabled, so
 - Introduce ocotp_access_gates to be container of efuse gate info
 - Iterate each node under '/soc' to check accessing permission. If not
   allowed to be accessed, detach the node

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/nvmem/imx-ocotp-ele.c | 184 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 183 insertions(+), 1 deletion(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index ca6dd71d8a2e29888c6e556aaea116c1a967cb5f..2c7b698ae4da0ec22eeeabf4ed35d1b703771f6c 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -5,6 +5,8 @@
  * Copyright 2023 NXP
  */
 
+#include <dt-bindings/nvmem/fsl,imx93-ocotp.h>
+#include <dt-bindings/nvmem/fsl,imx95-ocotp.h>
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -27,6 +29,7 @@ struct ocotp_map_entry {
 };
 
 struct ocotp_devtype_data {
+	const struct ocotp_access_gates *access_gates;
 	u32 reg_off;
 	char *name;
 	u32 size;
@@ -36,11 +39,26 @@ struct ocotp_devtype_data {
 	struct ocotp_map_entry entry[];
 };
 
+#define OCOTP_MAX_NUM_GATE_WORDS 4
+#define IMX93_OCOTP_NUM_GATES 17
+#define IMX95_OCOTP_NUM_GATES 36
+
+struct ocotp_access_gates {
+	u32 num_words;
+	u32 words[OCOTP_MAX_NUM_GATE_WORDS];
+	u32 num_gates;
+	struct access_gate {
+		u32 word;
+		u32 mask;
+	} gates[];
+};
+
 struct imx_ocotp_priv {
 	struct device *dev;
 	void __iomem *base;
 	struct nvmem_config config;
 	struct mutex lock;
+	u32 value[OCOTP_MAX_NUM_GATE_WORDS];
 	const struct ocotp_devtype_data *data;
 };
 
@@ -131,6 +149,97 @@ static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
 	cell->read_post_process = imx_ocotp_cell_pp;
 }
 
+static int imx_ele_ocotp_check_access(struct platform_device *pdev, u32 id)
+{
+	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
+	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
+	u32 word, mask;
+
+	if (id >= access_gates->num_gates) {
+		dev_err(&pdev->dev, "Index %d too large\n", id);
+		return -EACCES;
+	}
+
+	word = access_gates->gates[id].word;
+	mask = access_gates->gates[id].mask;
+
+	dev_dbg(&pdev->dev, "id:%d word:%d mask:0x%08x\n", id, word, mask);
+	/* true means not allow access */
+	if (priv->value[word] & mask)
+		return -EACCES;
+
+	return 0;
+}
+
+static int imx_ele_ocotp_grant_access(struct platform_device *pdev, struct device_node *parent)
+{
+	struct device_node *child;
+	struct device *dev = &pdev->dev;
+
+	for_each_available_child_of_node(parent, child) {
+		struct of_phandle_iterator it;
+		int err;
+		u32 id;
+
+		of_for_each_phandle(&it, err, child, "access-controllers",
+				    "#access-controller-cells", 0) {
+			struct of_phandle_args provider_args;
+			struct device_node *provider = it.node;
+
+			if (err) {
+				dev_err(dev, "Unable to get access-controllers property for node %s\n, err: %d",
+					child->full_name, err);
+				of_node_put(provider);
+				return err;
+			}
+
+			/* Only support one cell */
+			if (of_phandle_iterator_args(&it, provider_args.args, 1) != 1) {
+				dev_err(dev, "wrong args count\n");
+				return -EINVAL;
+			}
+
+			id = provider_args.args[0];
+
+			dev_dbg(dev, "Checking node: %s gate: %d\n", child->full_name, id);
+
+			if (imx_ele_ocotp_check_access(pdev, id)) {
+				of_detach_node(child);
+				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
+					child->full_name);
+			}
+		}
+
+		imx_ele_ocotp_grant_access(pdev, child);
+	}
+
+	return 0;
+}
+
+static int imx_ele_ocotp_access_control(struct platform_device *pdev)
+{
+	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
+	struct device_node *root __free(device_node) = of_find_node_by_path("/");
+	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
+	void __iomem *reg = priv->base + priv->data->reg_off;
+	u32 off;
+	int i;
+
+	if (!priv->data->access_gates)
+		return 0;
+
+	/* This should never happen */
+	WARN_ON(!root);
+
+	for (i = 0; i < access_gates->num_words; i++) {
+		off = access_gates->words[i] << 2;
+		priv->value[i] = readl(reg + off);
+		dev_dbg(&pdev->dev, "word:%d 0x%08x\n", access_gates->words[i], priv->value[i]);
+	}
+
+	return imx_ele_ocotp_grant_access(pdev, root);
+}
+
 static int imx_ele_ocotp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -161,14 +270,43 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
 	mutex_init(&priv->lock);
 
+	platform_set_drvdata(pdev, priv);
+
 	nvmem = devm_nvmem_register(dev, &priv->config);
 	if (IS_ERR(nvmem))
 		return PTR_ERR(nvmem);
 
-	return 0;
+
+	return imx_ele_ocotp_access_control(pdev);
 }
 
+static const struct ocotp_access_gates imx93_access_gates = {
+	.num_words = 3,
+	.words = {19, 20, 21},
+	.num_gates = IMX93_OCOTP_NUM_GATES,
+	.gates = {
+		[IMX93_OCOTP_NPU_GATE]		= { .word = 19, .mask = BIT(13) },
+		[IMX93_OCOTP_A550_GATE]		= { .word = 19, .mask = BIT(14) },
+		[IMX93_OCOTP_A551_GATE]		= { .word = 19, .mask = BIT(15) },
+		[IMX93_OCOTP_M33_GATE]		= { .word = 19, .mask = BIT(24) },
+		[IMX93_OCOTP_CAN1_FD_GATE]	= { .word = 19, .mask = BIT(28) },
+		[IMX93_OCOTP_CAN2_FD_GATE]	= { .word = 19, .mask = BIT(29) },
+		[IMX93_OCOTP_CAN1_GATE]		= { .word = 19, .mask = BIT(30) },
+		[IMX93_OCOTP_CAN2_GATE]		= { .word = 19, .mask = BIT(31) },
+		[IMX93_OCOTP_USB1_GATE]		= { .word = 20, .mask = BIT(3) },
+		[IMX93_OCOTP_USB2_GATE]		= { .word = 20, .mask = BIT(4) },
+		[IMX93_OCOTP_ENET1_GATE]	= { .word = 20, .mask = BIT(5) },
+		[IMX93_OCOTP_ENET2_GATE]	= { .word = 20, .mask = BIT(6) },
+		[IMX93_OCOTP_PXP_GATE]		= { .word = 20, .mask = BIT(10) },
+		[IMX93_OCOTP_MIPI_CSI1_GATE]	= { .word = 20, .mask = BIT(17) },
+		[IMX93_OCOTP_MIPI_DSI1_GATE]	= { .word = 20, .mask = BIT(19) },
+		[IMX93_OCOTP_LVDS1_GATE]	= { .word = 20, .mask = BIT(24) },
+		[IMX93_OCOTP_ADC1_GATE]		= { .word = 21, .mask = BIT(7) },
+	},
+};
+
 static const struct ocotp_devtype_data imx93_ocotp_data = {
+	.access_gates = &imx93_access_gates,
 	.reg_off = 0x8000,
 	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,
@@ -183,7 +321,51 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
 	},
 };
 
+static const struct ocotp_access_gates imx95_access_gates = {
+	.num_words = 3,
+	.words = {17, 18, 19},
+	.num_gates = IMX95_OCOTP_NUM_GATES,
+	.gates = {
+		[IMX95_OCOTP_CANFD1_GATE]	= { .word = 17, .mask = BIT(20) },
+		[IMX95_OCOTP_CANFD2_GATE]	= { .word = 17, .mask = BIT(21) },
+		[IMX95_OCOTP_CANFD3_GATE]	= { .word = 17, .mask = BIT(22) },
+		[IMX95_OCOTP_CANFD4_GATE]	= { .word = 17, .mask = BIT(23) },
+		[IMX95_OCOTP_CANFD5_GATE]	= { .word = 17, .mask = BIT(24) },
+		[IMX95_OCOTP_CAN1_GATE]	= { .word = 17, .mask = BIT(25) },
+		[IMX95_OCOTP_CAN2_GATE]	= { .word = 17, .mask = BIT(26) },
+		[IMX95_OCOTP_CAN3_GATE]	= { .word = 17, .mask = BIT(27) },
+		[IMX95_OCOTP_CAN4_GATE]	= { .word = 17, .mask = BIT(28) },
+		[IMX95_OCOTP_CAN5_GATE]	= { .word = 17, .mask = BIT(29) },
+		[IMX95_OCOTP_NPU_GATE]		= { .word = 18, .mask = BIT(0) },
+		[IMX95_OCOTP_A550_GATE]	= { .word = 18, .mask = BIT(1) },
+		[IMX95_OCOTP_A551_GATE]	= { .word = 18, .mask = BIT(2) },
+		[IMX95_OCOTP_A552_GATE]	= { .word = 18, .mask = BIT(3) },
+		[IMX95_OCOTP_A553_GATE]	= { .word = 18, .mask = BIT(4) },
+		[IMX95_OCOTP_A554_GATE]	= { .word = 18, .mask = BIT(5) },
+		[IMX95_OCOTP_A555_GATE]	= { .word = 18, .mask = BIT(6) },
+		[IMX95_OCOTP_M7_GATE]		= { .word = 18, .mask = BIT(9) },
+		[IMX95_OCOTP_DCSS_GATE]	= { .word = 18, .mask = BIT(22) },
+		[IMX95_OCOTP_LVDS1_GATE]	= { .word = 18, .mask = BIT(27) },
+		[IMX95_OCOTP_ISP_GATE]		= { .word = 18, .mask = BIT(29) },
+		[IMX95_OCOTP_USB1_GATE]	= { .word = 19, .mask = BIT(2) },
+		[IMX95_OCOTP_USB2_GATE]	= { .word = 19, .mask = BIT(3) },
+		[IMX95_OCOTP_NETC_GATE]	= { .word = 19, .mask = BIT(4) },
+		[IMX95_OCOTP_PCIE1_GATE]	= { .word = 19, .mask = BIT(6) },
+		[IMX95_OCOTP_PCIE2_GATE]	= { .word = 19, .mask = BIT(7) },
+		[IMX95_OCOTP_ADC1_GATE]	= { .word = 19, .mask = BIT(8) },
+		[IMX95_OCOTP_EARC_RX_GATE]	= { .word = 19, .mask = BIT(11) },
+		[IMX95_OCOTP_GPU3D_GATE]	= { .word = 19, .mask = BIT(16) },
+		[IMX95_OCOTP_VPU_GATE]		= { .word = 19, .mask = BIT(17) },
+		[IMX95_OCOTP_JPEG_ENC_GATE]	= { .word = 19, .mask = BIT(18) },
+		[IMX95_OCOTP_JPEG_DEC_GATE]	= { .word = 19, .mask = BIT(19) },
+		[IMX95_OCOTP_MIPI_CSI1_GATE]	= { .word = 19, .mask = BIT(21) },
+		[IMX95_OCOTP_MIPI_CSI2_GATE]	= { .word = 19, .mask = BIT(22) },
+		[IMX95_OCOTP_MIPI_DSI1_GATE]	= { .word = 19, .mask = BIT(23) },
+	}
+};
+
 static const struct ocotp_devtype_data imx95_ocotp_data = {
+	.access_gates = &imx95_access_gates,
 	.reg_off = 0x8000,
 	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,

-- 
2.37.1



From tabba at google.com  Tue Dec 17 00:43:45 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:43:45 +0000
Subject: [PATCH v3 03/18] KVM: arm64: Make hyp_page::order a u8
In-Reply-To: <20241216175803.2716565-4-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-4-qperret@google.com>
Message-ID: <CA+EHjTznFMF77kfUTkMeRpHnz9HAD1gSw6Do6tQvYSJ_jXG3gg@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> We don't need 16 bits to store the hyp page order, and we'll need some
> bits to store page ownership data soon, so let's reduce the order
> member.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/kvm/hyp/include/nvhe/gfp.h    |  6 +++---
>  arch/arm64/kvm/hyp/include/nvhe/memory.h |  5 +++--
>  arch/arm64/kvm/hyp/nvhe/page_alloc.c     | 14 +++++++-------
>  3 files changed, 13 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> index 97c527ef53c2..f1725bad6331 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> @@ -7,7 +7,7 @@
>  #include <nvhe/memory.h>
>  #include <nvhe/spinlock.h>
>
> -#define HYP_NO_ORDER   USHRT_MAX
> +#define HYP_NO_ORDER   0xff
>
>  struct hyp_pool {
>         /*
> @@ -19,11 +19,11 @@ struct hyp_pool {
>         struct list_head free_area[NR_PAGE_ORDERS];
>         phys_addr_t range_start;
>         phys_addr_t range_end;
> -       unsigned short max_order;
> +       u8 max_order;
>  };
>
>  /* Allocation */
> -void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order);
> +void *hyp_alloc_pages(struct hyp_pool *pool, u8 order);
>  void hyp_split_page(struct hyp_page *page);
>  void hyp_get_page(struct hyp_pool *pool, void *addr);
>  void hyp_put_page(struct hyp_pool *pool, void *addr);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> index c84b24234ac7..45b8d1840aa4 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> @@ -41,8 +41,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
>  }
>
>  struct hyp_page {
> -       unsigned short refcount;
> -       unsigned short order;
> +       u16 refcount;
> +       u8 order;
> +       u8 reserved;
>  };
>
>  extern u64 __hyp_vmemmap;
> diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
> index e691290d3765..a1eb27a1a747 100644
> --- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
> +++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
> @@ -32,7 +32,7 @@ u64 __hyp_vmemmap;
>   */
>  static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool,
>                                              struct hyp_page *p,
> -                                            unsigned short order)
> +                                            u8 order)
>  {
>         phys_addr_t addr = hyp_page_to_phys(p);
>
> @@ -51,7 +51,7 @@ static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool,
>  /* Find a buddy page currently available for allocation */
>  static struct hyp_page *__find_buddy_avail(struct hyp_pool *pool,
>                                            struct hyp_page *p,
> -                                          unsigned short order)
> +                                          u8 order)
>  {
>         struct hyp_page *buddy = __find_buddy_nocheck(pool, p, order);
>
> @@ -94,7 +94,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
>                               struct hyp_page *p)
>  {
>         phys_addr_t phys = hyp_page_to_phys(p);
> -       unsigned short order = p->order;
> +       u8 order = p->order;
>         struct hyp_page *buddy;
>
>         memset(hyp_page_to_virt(p), 0, PAGE_SIZE << p->order);
> @@ -129,7 +129,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
>
>  static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool,
>                                            struct hyp_page *p,
> -                                          unsigned short order)
> +                                          u8 order)
>  {
>         struct hyp_page *buddy;
>
> @@ -183,7 +183,7 @@ void hyp_get_page(struct hyp_pool *pool, void *addr)
>
>  void hyp_split_page(struct hyp_page *p)
>  {
> -       unsigned short order = p->order;
> +       u8 order = p->order;
>         unsigned int i;
>
>         p->order = 0;
> @@ -195,10 +195,10 @@ void hyp_split_page(struct hyp_page *p)
>         }
>  }
>
> -void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order)
> +void *hyp_alloc_pages(struct hyp_pool *pool, u8 order)
>  {
> -       unsigned short i = order;
>         struct hyp_page *p;
> +       u8 i = order;
>
>         hyp_spin_lock(&pool->lock);
>
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From krzk at kernel.org  Tue Dec 17 00:45:38 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 09:45:38 +0100
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <AS8PR04MB8642C9A1DA27CD0F3F51DF2287042@AS8PR04MB8642.eurprd04.prod.outlook.com>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
 <z6udhrqfmbelspe3eiz2q6twqvn4nkgxnfsdyxdv7ow6llxiz6@qhbaobn63icb>
 <AS8PR04MB8642C9A1DA27CD0F3F51DF2287042@AS8PR04MB8642.eurprd04.prod.outlook.com>
Message-ID: <9c1b3e0b-84d8-4f1b-ba1b-233824d30c44@kernel.org>

On 17/12/2024 09:42, Jacky Bai wrote:
>> Subject: Re: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
>>
>> On Thu, Dec 12, 2024 at 05:35:55PM +0800, Jacky Bai wrote:
>>> The i.MX 943 applications processors integrate up to four Arm Cortex
>>> A55 cores and supports functional safety with built-in 2x Arm Cortex
>>> M33 and M7 cores which can be configured asa safety island. Optimizing
>>> performance and power efficiency for Industrial, IoT and automotive
>>> devices, i.MX 943 processors are built with NXP?s innovative Energy
>>> Flex architecture.
>>>
>>> This patch adds the minimal dtsi support for i.MX943 with peripherals
>>> like uart, edma, i2c, spi, mu, sai etc.
>>>
>>> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
>>> ---
>>>  arch/arm64/boot/dts/freescale/imx943-clock.h  |  196 +++
>>> .../arm64/boot/dts/freescale/imx943-pinfunc.h | 1542
>> +++++++++++++++++
>>>  arch/arm64/boot/dts/freescale/imx943-power.h  |   41 +
>>>  arch/arm64/boot/dts/freescale/imx943.dtsi     | 1284
>> ++++++++++++++
>>>  4 files changed, 3063 insertions(+)
>>>  create mode 100644 arch/arm64/boot/dts/freescale/imx943-clock.h
>>>  create mode 100644 arch/arm64/boot/dts/freescale/imx943-pinfunc.h
>>>  create mode 100644 arch/arm64/boot/dts/freescale/imx943-power.h
>>>  create mode 100644 arch/arm64/boot/dts/freescale/imx943.dtsi
>>>
>>> diff --git a/arch/arm64/boot/dts/freescale/imx943-clock.h
>>> b/arch/arm64/boot/dts/freescale/imx943-clock.h
>>> new file mode 100644
>>> index 000000000000..64b9d5d4051e
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/freescale/imx943-clock.h
>>> @@ -0,0 +1,196 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
>>> +/*
>>> + * Copyright 2024 NXP
>>> + */
>>> +
>>> +#ifndef __CLOCK_IMX943_H
>>> +#define __CLOCK_IMX943_H
>>> +
>>> +#define IMX943_CLK_EXT				0
>>> +#define IMX943_CLK_OSC32K			1
>>> +#define IMX943_CLK_OSC24M			2
>>
>>
>> Why exactly are you adding clock indices to header files? Nothing in commit
>> msg explains that.
> 
> These clock index macro defines will be used in dtsi or dts for clock reference.
> I just follow the way that we have done for i.MX95. Anything need to be improved or refined?
> For commit msg, I will add some explains in v2.

It is fine, just unexpected, so you have entire commit msg to explain this.

Best regards,
Krzysztof


From tabba at google.com  Tue Dec 17 00:46:58 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:46:58 +0000
Subject: [PATCH v3 04/18] KVM: arm64: Move host page ownership tracking to
 the hyp vmemmap
In-Reply-To: <20241216175803.2716565-5-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-5-qperret@google.com>
Message-ID: <CA+EHjTy9P4gt6z+NbxLLANUKJBe32g0HsyGvsobXSfGiFSZ5Lg@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> We currently store part of the page-tracking state in PTE software bits
> for the host, guests and the hypervisor. This is sub-optimal when e.g.
> sharing pages as this forces to break block mappings purely to support
> this software tracking. This causes an unnecessarily fragmented stage-2
> page-table for the host in particular when it shares pages with Secure,
> which can lead to measurable regressions. Moreover, having this state
> stored in the page-table forces us to do multiple costly walks on the
> page transition path, hence causing overhead.
>
> In order to work around these problems, move the host-side page-tracking
> logic from SW bits in its stage-2 PTEs to the hypervisor's vmemmap.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/kvm/hyp/include/nvhe/memory.h |   6 +-
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 100 ++++++++++++++++-------
>  arch/arm64/kvm/hyp/nvhe/setup.c          |   7 +-
>  3 files changed, 77 insertions(+), 36 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> index 45b8d1840aa4..8bd9a539f260 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> @@ -8,7 +8,7 @@
>  #include <linux/types.h>
>
>  /*
> - * SW bits 0-1 are reserved to track the memory ownership state of each page:
> + * Bits 0-1 are reserved to track the memory ownership state of each page:
>   *   00: The page is owned exclusively by the page-table owner.
>   *   01: The page is owned by the page-table owner, but is shared
>   *       with another entity.
> @@ -43,7 +43,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
>  struct hyp_page {
>         u16 refcount;
>         u8 order;
> -       u8 reserved;
> +
> +       /* Host (non-meta) state. Guarded by the host stage-2 lock. */
> +       enum pkvm_page_state host_state : 8;
>  };
>
>  extern u64 __hyp_vmemmap;
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index caba3e4bd09e..12bb5445fe47 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -201,8 +201,8 @@ static void *guest_s2_zalloc_page(void *mc)
>
>         memset(addr, 0, PAGE_SIZE);
>         p = hyp_virt_to_page(addr);
> -       memset(p, 0, sizeof(*p));
>         p->refcount = 1;
> +       p->order = 0;
>
>         return addr;
>  }
> @@ -268,6 +268,7 @@ int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd)
>
>  void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
>  {
> +       struct hyp_page *page;
>         void *addr;
>
>         /* Dump all pgtable pages in the hyp_pool */
> @@ -279,7 +280,9 @@ void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
>         /* Drain the hyp_pool into the memcache */
>         addr = hyp_alloc_pages(&vm->pool, 0);
>         while (addr) {
> -               memset(hyp_virt_to_page(addr), 0, sizeof(struct hyp_page));
> +               page = hyp_virt_to_page(addr);
> +               page->refcount = 0;
> +               page->order = 0;
>                 push_hyp_memcache(mc, addr, hyp_virt_to_phys);
>                 WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1));
>                 addr = hyp_alloc_pages(&vm->pool, 0);
> @@ -382,19 +385,28 @@ bool addr_is_memory(phys_addr_t phys)
>         return !!find_mem_range(phys, &range);
>  }
>
> -static bool addr_is_allowed_memory(phys_addr_t phys)
> +static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
> +{
> +       return range->start <= addr && addr < range->end;
> +}
> +
> +static int check_range_allowed_memory(u64 start, u64 end)
>  {
>         struct memblock_region *reg;
>         struct kvm_mem_range range;
>
> -       reg = find_mem_range(phys, &range);
> +       /*
> +        * Callers can't check the state of a range that overlaps memory and
> +        * MMIO regions, so ensure [start, end[ is in the same kvm_mem_range.
> +        */
> +       reg = find_mem_range(start, &range);
> +       if (!is_in_mem_range(end - 1, &range))
> +               return -EINVAL;
>
> -       return reg && !(reg->flags & MEMBLOCK_NOMAP);
> -}
> +       if (!reg || reg->flags & MEMBLOCK_NOMAP)
> +               return -EPERM;
>
> -static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
> -{
> -       return range->start <= addr && addr < range->end;
> +       return 0;
>  }
>
>  static bool range_is_memory(u64 start, u64 end)
> @@ -454,8 +466,10 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
>         if (kvm_pte_valid(pte))
>                 return -EAGAIN;
>
> -       if (pte)
> +       if (pte) {
> +               WARN_ON(addr_is_memory(addr) && hyp_phys_to_page(addr)->host_state != PKVM_NOPAGE);
>                 return -EPERM;
> +       }
>
>         do {
>                 u64 granule = kvm_granule_size(level);
> @@ -477,10 +491,33 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
>         return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
>  }
>
> +static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm_page_state state)
> +{
> +       phys_addr_t end = addr + size;
> +
> +       for (; addr < end; addr += PAGE_SIZE)
> +               hyp_phys_to_page(addr)->host_state = state;
> +}
> +
>  int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
>  {
> -       return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
> -                              addr, size, &host_s2_pool, owner_id);
> +       int ret;
> +
> +       if (!addr_is_memory(addr))
> +               return -EPERM;
> +
> +       ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
> +                             addr, size, &host_s2_pool, owner_id);
> +       if (ret)
> +               return ret;
> +
> +       /* Don't forget to update the vmemmap tracking for the host */
> +       if (owner_id == PKVM_ID_HOST)
> +               __host_update_page_state(addr, size, PKVM_PAGE_OWNED);
> +       else
> +               __host_update_page_state(addr, size, PKVM_NOPAGE);
> +
> +       return 0;
>  }
>
>  static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
> @@ -604,35 +641,38 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size,
>         return kvm_pgtable_walk(pgt, addr, size, &walker);
>  }
>
> -static enum pkvm_page_state host_get_page_state(kvm_pte_t pte, u64 addr)
> -{
> -       if (!addr_is_allowed_memory(addr))
> -               return PKVM_NOPAGE;
> -
> -       if (!kvm_pte_valid(pte) && pte)
> -               return PKVM_NOPAGE;
> -
> -       return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
> -}
> -
>  static int __host_check_page_state_range(u64 addr, u64 size,
>                                          enum pkvm_page_state state)
>  {
> -       struct check_walk_data d = {
> -               .desired        = state,
> -               .get_page_state = host_get_page_state,
> -       };
> +       u64 end = addr + size;
> +       int ret;
> +
> +       ret = check_range_allowed_memory(addr, end);
> +       if (ret)
> +               return ret;
>
>         hyp_assert_lock_held(&host_mmu.lock);
> -       return check_page_state_range(&host_mmu.pgt, addr, size, &d);
> +       for (; addr < end; addr += PAGE_SIZE) {
> +               if (hyp_phys_to_page(addr)->host_state != state)
> +                       return -EPERM;
> +       }
> +
> +       return 0;
>  }
>
>  static int __host_set_page_state_range(u64 addr, u64 size,
>                                        enum pkvm_page_state state)
>  {
> -       enum kvm_pgtable_prot prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, state);
> +       if (hyp_phys_to_page(addr)->host_state == PKVM_NOPAGE) {
> +               int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT);
>
> -       return host_stage2_idmap_locked(addr, size, prot);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       __host_update_page_state(addr, size, state);
> +
> +       return 0;
>  }
>
>  static int host_request_owned_transition(u64 *completer_addr,
> diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> index cbdd18cd3f98..7e04d1c2a03d 100644
> --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> @@ -180,7 +180,6 @@ static void hpool_put_page(void *addr)
>  static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
>                                      enum kvm_pgtable_walk_flags visit)
>  {
> -       enum kvm_pgtable_prot prot;
>         enum pkvm_page_state state;
>         phys_addr_t phys;
>
> @@ -203,16 +202,16 @@ static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
>         case PKVM_PAGE_OWNED:
>                 return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP);
>         case PKVM_PAGE_SHARED_OWNED:
> -               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED);
> +               hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_BORROWED;
>                 break;
>         case PKVM_PAGE_SHARED_BORROWED:
> -               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
> +               hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_OWNED;
>                 break;
>         default:
>                 return -EINVAL;
>         }
>
> -       return host_stage2_idmap_locked(phys, PAGE_SIZE, prot);
> +       return 0;
>  }
>
>  static int fix_hyp_pgtable_refcnt_walker(const struct kvm_pgtable_visit_ctx *ctx,
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 00:47:24 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:47:24 +0000
Subject: [PATCH v3 05/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_mkyoung
In-Reply-To: <20241216175803.2716565-6-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-6-qperret@google.com>
Message-ID: <CA+EHjTzfqR8=g=VzazL3__TyGpJJtPCoG20sJeUnY+d0b6NSBA@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> kvm_pgtable_stage2_mkyoung currently assumes that it is being called
> from a 'shared' walker, which will not be true once called from pKVM.
> To allow for the re-use of that function, make the walk flags one of
> its parameters.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/include/asm/kvm_pgtable.h | 4 +++-
>  arch/arm64/kvm/hyp/pgtable.c         | 7 +++----
>  arch/arm64/kvm/mmu.c                 | 3 ++-
>  3 files changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index aab04097b505..38b7ec1c8614 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -669,13 +669,15 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
>   * kvm_pgtable_stage2_mkyoung() - Set the access flag in a page-table entry.
>   * @pgt:       Page-table structure initialised by kvm_pgtable_stage2_init*().
>   * @addr:      Intermediate physical address to identify the page-table entry.
> + * @flags:     Flags to control the page-table walk (ex. a shared walk)
>   *
>   * The offset of @addr within a page is ignored.
>   *
>   * If there is a valid, leaf page-table entry used to translate @addr, then
>   * set the access flag in that entry.
>   */
> -void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr);
> +void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
> +                               enum kvm_pgtable_walk_flags flags);
>
>  /**
>   * kvm_pgtable_stage2_test_clear_young() - Test and optionally clear the access
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 40bd55966540..0470aedb4bf4 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -1245,14 +1245,13 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
>                                         NULL, NULL, 0);
>  }
>
> -void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr)
> +void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
> +                               enum kvm_pgtable_walk_flags flags)
>  {
>         int ret;
>
>         ret = stage2_update_leaf_attrs(pgt, addr, 1, KVM_PTE_LEAF_ATTR_LO_S2_AF, 0,
> -                                      NULL, NULL,
> -                                      KVM_PGTABLE_WALK_HANDLE_FAULT |
> -                                      KVM_PGTABLE_WALK_SHARED);
> +                                      NULL, NULL, flags);
>         if (!ret)
>                 dsb(ishst);
>  }
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index c9d46ad57e52..a2339b76c826 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1718,13 +1718,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  /* Resolve the access fault by making the page young again. */
>  static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
>  {
> +       enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED;
>         struct kvm_s2_mmu *mmu;
>
>         trace_kvm_access_fault(fault_ipa);
>
>         read_lock(&vcpu->kvm->mmu_lock);
>         mmu = vcpu->arch.hw_mmu;
> -       kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa);
> +       kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa, flags);
>         read_unlock(&vcpu->kvm->mmu_lock);
>  }
>
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 00:47:35 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:47:35 +0000
Subject: [PATCH v3 06/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_relax_perms
In-Reply-To: <20241216175803.2716565-7-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-7-qperret@google.com>
Message-ID: <CA+EHjTyf+yjBsQ5zGs+PZJGUJSSftyEepo6A7YmgMnf8cTMH1w@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> kvm_pgtable_stage2_relax_perms currently assumes that it is being called
> from a 'shared' walker, which will not be true once called from pKVM. To
> allow for the re-use of that function, make the walk flags one of its
> parameters.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/include/asm/kvm_pgtable.h | 4 +++-
>  arch/arm64/kvm/hyp/pgtable.c         | 6 ++----
>  arch/arm64/kvm/mmu.c                 | 7 +++----
>  3 files changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 38b7ec1c8614..c2f4149283ef 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -707,6 +707,7 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
>   * @pgt:       Page-table structure initialised by kvm_pgtable_stage2_init*().
>   * @addr:      Intermediate physical address to identify the page-table entry.
>   * @prot:      Additional permissions to grant for the mapping.
> + * @flags:     Flags to control the page-table walk (ex. a shared walk)
>   *
>   * The offset of @addr within a page is ignored.
>   *
> @@ -719,7 +720,8 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
>   * Return: 0 on success, negative error code on failure.
>   */
>  int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
> -                                  enum kvm_pgtable_prot prot);
> +                                  enum kvm_pgtable_prot prot,
> +                                  enum kvm_pgtable_walk_flags flags);
>
>  /**
>   * kvm_pgtable_stage2_flush_range() - Clean and invalidate data cache to Point
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 0470aedb4bf4..b7a3b5363235 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -1307,7 +1307,7 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
>  }
>
>  int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
> -                                  enum kvm_pgtable_prot prot)
> +                                  enum kvm_pgtable_prot prot, enum kvm_pgtable_walk_flags flags)
>  {
>         int ret;
>         s8 level;
> @@ -1325,9 +1325,7 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
>         if (prot & KVM_PGTABLE_PROT_X)
>                 clr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
>
> -       ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level,
> -                                      KVM_PGTABLE_WALK_HANDLE_FAULT |
> -                                      KVM_PGTABLE_WALK_SHARED);
> +       ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level, flags);
>         if (!ret || ret == -EAGAIN)
>                 kvm_call_hyp(__kvm_tlb_flush_vmid_ipa_nsh, pgt->mmu, addr, level);
>         return ret;
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index a2339b76c826..641e4fec1659 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1452,6 +1452,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>         enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
>         struct kvm_pgtable *pgt;
>         struct page *page;
> +       enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED;
>
>         if (fault_is_perm)
>                 fault_granule = kvm_vcpu_trap_get_perm_fault_granule(vcpu);
> @@ -1695,13 +1696,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>                  * PTE, which will be preserved.
>                  */
>                 prot &= ~KVM_NV_GUEST_MAP_SZ;
> -               ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot);
> +               ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot, flags);
>         } else {
>                 ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
>                                              __pfn_to_phys(pfn), prot,
> -                                            memcache,
> -                                            KVM_PGTABLE_WALK_HANDLE_FAULT |
> -                                            KVM_PGTABLE_WALK_SHARED);
> +                                            memcache, flags);
>         }
>
>  out_unlock:
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 00:48:17 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:48:17 +0000
Subject: [PATCH v3 08/18] KVM: arm64: Add {get,put}_pkvm_hyp_vm() helpers
In-Reply-To: <20241216175803.2716565-9-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-9-qperret@google.com>
Message-ID: <CA+EHjTxd5euMqYrq510kgqvON1JdGmjhE4ROFuMwTR1pgwLD9w@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> In preparation for accessing pkvm_hyp_vm structures at EL2 in a context
> where we can't always expect a vCPU to be loaded (e.g. MMU notifiers),
> introduce get/put helpers to get temporary references to hyp VMs from
> any context.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  3 +++
>  arch/arm64/kvm/hyp/nvhe/pkvm.c         | 20 ++++++++++++++++++++
>  2 files changed, 23 insertions(+)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> index 24a9a8330d19..f361d8b91930 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> @@ -70,4 +70,7 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
>                                          unsigned int vcpu_idx);
>  void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
>
> +struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
> +void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
> +
>  #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index 071993c16de8..d46a02e24e4a 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -327,6 +327,26 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
>         hyp_spin_unlock(&vm_table_lock);
>  }
>
> +struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
> +{
> +       struct pkvm_hyp_vm *hyp_vm;
> +
> +       hyp_spin_lock(&vm_table_lock);
> +       hyp_vm = get_vm_by_handle(handle);
> +       if (hyp_vm)
> +               hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
> +       hyp_spin_unlock(&vm_table_lock);
> +
> +       return hyp_vm;
> +}
> +
> +void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm)
> +{
> +       hyp_spin_lock(&vm_table_lock);
> +       hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
> +       hyp_spin_unlock(&vm_table_lock);
> +}
> +
>  static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
>  {
>         struct kvm *kvm = &hyp_vm->kvm;
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 00:48:26 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:48:26 +0000
Subject: [PATCH v3 07/18] KVM: arm64: Make kvm_pgtable_stage2_init() a
 static inline function
In-Reply-To: <20241216175803.2716565-8-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-8-qperret@google.com>
Message-ID: <CA+EHjTyYy6JxL0EH2=_VQe8+Qz7iCndPaU0C8gH69UnSkKhgtQ@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> Turn kvm_pgtable_stage2_init() into a static inline function instead of
> a macro. This will allow the usage of typeof() on it later on.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/include/asm/kvm_pgtable.h | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index c2f4149283ef..04418b5e3004 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -526,8 +526,11 @@ int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
>                               enum kvm_pgtable_stage2_flags flags,
>                               kvm_pgtable_force_pte_cb_t force_pte_cb);
>
> -#define kvm_pgtable_stage2_init(pgt, mmu, mm_ops) \
> -       __kvm_pgtable_stage2_init(pgt, mmu, mm_ops, 0, NULL)
> +static inline int kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
> +                                         struct kvm_pgtable_mm_ops *mm_ops)
> +{
> +       return __kvm_pgtable_stage2_init(pgt, mmu, mm_ops, 0, NULL);
> +}
>
>  /**
>   * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 00:48:37 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:48:37 +0000
Subject: [PATCH v3 09/18] KVM: arm64: Introduce __pkvm_vcpu_{load,put}()
In-Reply-To: <20241216175803.2716565-10-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-10-qperret@google.com>
Message-ID: <CA+EHjTyTtQrG+8ONNg8hLiCMwcPfsuf+O-Xh0TOm+RzjW5=MWw@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> From: Marc Zyngier <maz at kernel.org>
>
> Rather than look-up the hyp vCPU on every run hypercall at EL2,
> introduce a per-CPU 'loaded_hyp_vcpu' tracking variable which is updated
> by a pair of load/put hypercalls called directly from
> kvm_arch_vcpu_{load,put}() when pKVM is enabled.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/include/asm/kvm_asm.h       |  2 ++
>  arch/arm64/kvm/arm.c                   | 14 ++++++++
>  arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  7 ++++
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c     | 47 ++++++++++++++++++++------
>  arch/arm64/kvm/hyp/nvhe/pkvm.c         | 29 ++++++++++++++++
>  arch/arm64/kvm/vgic/vgic-v3.c          |  6 ++--
>  6 files changed, 93 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index ca2590344313..89c0fac69551 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -79,6 +79,8 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
>         __KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu,
>         __KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
>  };
>
>  #define DECLARE_KVM_VHE_SYM(sym)       extern char sym[]
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index a102c3aebdbc..55cc62b2f469 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -619,12 +619,26 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>
>         kvm_arch_vcpu_load_debug_state_flags(vcpu);
>
> +       if (is_protected_kvm_enabled()) {
> +               kvm_call_hyp_nvhe(__pkvm_vcpu_load,
> +                                 vcpu->kvm->arch.pkvm.handle,
> +                                 vcpu->vcpu_idx, vcpu->arch.hcr_el2);
> +               kvm_call_hyp(__vgic_v3_restore_vmcr_aprs,
> +                            &vcpu->arch.vgic_cpu.vgic_v3);
> +       }
> +
>         if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus))
>                 vcpu_set_on_unsupported_cpu(vcpu);
>  }
>
>  void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  {
> +       if (is_protected_kvm_enabled()) {
> +               kvm_call_hyp(__vgic_v3_save_vmcr_aprs,
> +                            &vcpu->arch.vgic_cpu.vgic_v3);
> +               kvm_call_hyp_nvhe(__pkvm_vcpu_put);
> +       }
> +
>         kvm_arch_vcpu_put_debug_state_flags(vcpu);
>         kvm_arch_vcpu_put_fp(vcpu);
>         if (has_vhe())
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> index f361d8b91930..be52c5b15e21 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> @@ -20,6 +20,12 @@ struct pkvm_hyp_vcpu {
>
>         /* Backpointer to the host's (untrusted) vCPU instance. */
>         struct kvm_vcpu *host_vcpu;
> +
> +       /*
> +        * If this hyp vCPU is loaded, then this is a backpointer to the
> +        * per-cpu pointer tracking us. Otherwise, NULL if not loaded.
> +        */
> +       struct pkvm_hyp_vcpu **loaded_hyp_vcpu;
>  };
>
>  /*
> @@ -69,6 +75,7 @@ int __pkvm_teardown_vm(pkvm_handle_t handle);
>  struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
>                                          unsigned int vcpu_idx);
>  void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
> +struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void);
>
>  struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
>  void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 6aa0b13d86e5..95d78db315b3 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -141,16 +141,46 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
>                 host_cpu_if->vgic_lr[i] = hyp_cpu_if->vgic_lr[i];
>  }
>
> +static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +       DECLARE_REG(unsigned int, vcpu_idx, host_ctxt, 2);
> +       DECLARE_REG(u64, hcr_el2, host_ctxt, 3);
> +       struct pkvm_hyp_vcpu *hyp_vcpu;
> +
> +       if (!is_protected_kvm_enabled())
> +               return;
> +
> +       hyp_vcpu = pkvm_load_hyp_vcpu(handle, vcpu_idx);
> +       if (!hyp_vcpu)
> +               return;
> +
> +       if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
> +               /* Propagate WFx trapping flags */
> +               hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWE | HCR_TWI);
> +               hyp_vcpu->vcpu.arch.hcr_el2 |= hcr_el2 & (HCR_TWE | HCR_TWI);
> +       }
> +}
> +
> +static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt)
> +{
> +       struct pkvm_hyp_vcpu *hyp_vcpu;
> +
> +       if (!is_protected_kvm_enabled())
> +               return;
> +
> +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> +       if (hyp_vcpu)
> +               pkvm_put_hyp_vcpu(hyp_vcpu);
> +}
> +
>  static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, host_vcpu, host_ctxt, 1);
>         int ret;
>
> -       host_vcpu = kern_hyp_va(host_vcpu);
> -
>         if (unlikely(is_protected_kvm_enabled())) {
> -               struct pkvm_hyp_vcpu *hyp_vcpu;
> -               struct kvm *host_kvm;
> +               struct pkvm_hyp_vcpu *hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
>
>                 /*
>                  * KVM (and pKVM) doesn't support SME guests for now, and
> @@ -163,9 +193,6 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
>                         goto out;
>                 }
>
> -               host_kvm = kern_hyp_va(host_vcpu->kvm);
> -               hyp_vcpu = pkvm_load_hyp_vcpu(host_kvm->arch.pkvm.handle,
> -                                             host_vcpu->vcpu_idx);
>                 if (!hyp_vcpu) {
>                         ret = -EINVAL;
>                         goto out;
> @@ -176,12 +203,10 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
>                 ret = __kvm_vcpu_run(&hyp_vcpu->vcpu);
>
>                 sync_hyp_vcpu(hyp_vcpu);
> -               pkvm_put_hyp_vcpu(hyp_vcpu);
>         } else {
>                 /* The host is fully trusted, run its vCPU directly. */
> -               ret = __kvm_vcpu_run(host_vcpu);
> +               ret = __kvm_vcpu_run(kern_hyp_va(host_vcpu));
>         }
> -
>  out:
>         cpu_reg(host_ctxt, 1) =  ret;
>  }
> @@ -409,6 +434,8 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_init_vm),
>         HANDLE_FUNC(__pkvm_init_vcpu),
>         HANDLE_FUNC(__pkvm_teardown_vm),
> +       HANDLE_FUNC(__pkvm_vcpu_load),
> +       HANDLE_FUNC(__pkvm_vcpu_put),
>  };
>
>  static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index d46a02e24e4a..496d186efb03 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -23,6 +23,12 @@ unsigned int kvm_arm_vmid_bits;
>
>  unsigned int kvm_host_sve_max_vl;
>
> +/*
> + * The currently loaded hyp vCPU for each physical CPU. Used only when
> + * protected KVM is enabled, but for both protected and non-protected VMs.
> + */
> +static DEFINE_PER_CPU(struct pkvm_hyp_vcpu *, loaded_hyp_vcpu);
> +
>  /*
>   * Set trap register values based on features in ID_AA64PFR0.
>   */
> @@ -306,15 +312,30 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
>         struct pkvm_hyp_vcpu *hyp_vcpu = NULL;
>         struct pkvm_hyp_vm *hyp_vm;
>
> +       /* Cannot load a new vcpu without putting the old one first. */
> +       if (__this_cpu_read(loaded_hyp_vcpu))
> +               return NULL;
> +
>         hyp_spin_lock(&vm_table_lock);
>         hyp_vm = get_vm_by_handle(handle);
>         if (!hyp_vm || hyp_vm->nr_vcpus <= vcpu_idx)
>                 goto unlock;
>
>         hyp_vcpu = hyp_vm->vcpus[vcpu_idx];
> +
> +       /* Ensure vcpu isn't loaded on more than one cpu simultaneously. */
> +       if (unlikely(hyp_vcpu->loaded_hyp_vcpu)) {
> +               hyp_vcpu = NULL;
> +               goto unlock;
> +       }
> +
> +       hyp_vcpu->loaded_hyp_vcpu = this_cpu_ptr(&loaded_hyp_vcpu);
>         hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
>  unlock:
>         hyp_spin_unlock(&vm_table_lock);
> +
> +       if (hyp_vcpu)
> +               __this_cpu_write(loaded_hyp_vcpu, hyp_vcpu);
>         return hyp_vcpu;
>  }
>
> @@ -323,10 +344,18 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
>         struct pkvm_hyp_vm *hyp_vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu);
>
>         hyp_spin_lock(&vm_table_lock);
> +       hyp_vcpu->loaded_hyp_vcpu = NULL;
> +       __this_cpu_write(loaded_hyp_vcpu, NULL);
>         hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
>         hyp_spin_unlock(&vm_table_lock);
>  }
>
> +struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void)
> +{
> +       return __this_cpu_read(loaded_hyp_vcpu);
> +
> +}
> +
>  struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
>  {
>         struct pkvm_hyp_vm *hyp_vm;
> diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
> index f267bc2486a1..c2ef41fff079 100644
> --- a/arch/arm64/kvm/vgic/vgic-v3.c
> +++ b/arch/arm64/kvm/vgic/vgic-v3.c
> @@ -734,7 +734,8 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
>  {
>         struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
>
> -       kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
> +       if (likely(!is_protected_kvm_enabled()))
> +               kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
>
>         if (has_vhe())
>                 __vgic_v3_activate_traps(cpu_if);
> @@ -746,7 +747,8 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
>  {
>         struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
>
> -       kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
> +       if (likely(!is_protected_kvm_enabled()))
> +               kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
>         WARN_ON(vgic_v4_put(vcpu));
>
>         if (has_vhe())
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From linux at fw-web.de  Tue Dec 17 01:12:30 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:30 +0100
Subject: [PATCH v3 16/22] arm64: dts: mediatek: mt7988a-bpi-r4: Add default UART stdout
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-17-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add chosen node on Bananapi R4 board with stdout and default bootargs.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes:
v3:
- changed stdout-path to contain serial settings and dropped
  bootargs property
- changed commit title
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 9037f35857a9..46117df7d44c 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -9,6 +9,10 @@ / {
 	model = "Banana Pi BPI-R4";
 	chassis-type = "embedded";
 
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
 	reg_1p8v: regulator-1p8v {
 		compatible = "regulator-fixed";
 		regulator-name = "fixed-1.8V";
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:31 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:31 +0100
Subject: [PATCH v3 17/22] arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C controllers
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-18-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable the I2C0, I2C2 controllers found on the BananaPi R4 board.
Both controllers are not accessible from user and having fixed spare
devices. I2C0 have a pmic connected, I2C2 is used with I2C-multiplexer
for e.g. SFP cages.
The missing I2C1 is connected to GPIO header which can have either GPIO
mode or I2C mode.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts    | 12 ++++++++++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi            |  6 +++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 46117df7d44c..3d165f7b29dc 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -60,6 +60,18 @@ cpu_trip_active_low: active-low {
 	};
 };
 
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_1_pins>;
+	status = "okay";
+};
+
 &pio {
 	mdio0_pins: mdio0-pins {
 		mux {
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 59a1ffc2edfc..c0a49f68834a 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -269,7 +269,7 @@ serial at 11000200 {
 			status = "disabled";
 		};
 
-		i2c at 11003000 {
+		i2c0: i2c at 11003000 {
 			compatible = "mediatek,mt7981-i2c";
 			reg = <0 0x11003000 0 0x1000>,
 			      <0 0x10217080 0 0x80>;
@@ -283,7 +283,7 @@ i2c at 11003000 {
 			status = "disabled";
 		};
 
-		i2c at 11004000 {
+		i2c1: i2c at 11004000 {
 			compatible = "mediatek,mt7981-i2c";
 			reg = <0 0x11004000 0 0x1000>,
 			      <0 0x10217100 0 0x80>;
@@ -297,7 +297,7 @@ i2c at 11004000 {
 			status = "disabled";
 		};
 
-		i2c at 11005000 {
+		i2c2: i2c at 11005000 {
 			compatible = "mediatek,mt7981-i2c";
 			reg = <0 0x11005000 0 0x1000>,
 			      <0 0x10217180 0 0x80>;
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:32 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:32 +0100
Subject: [PATCH v3 18/22] arm64: dts: mediatek: mt7988a-bpi-r4: Add PCA9545 I2C Mux
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-19-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Bananapi R4 uses an i2c multiplexer for SFP slots, rtc and eeprom.
Add its node to the right i2c controller.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes:
v3:
- move reg after compatible
- change commit title
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 3d165f7b29dc..0dc1fd9265c6 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -2,6 +2,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/gpio/gpio.h>
+
 #include "mt7988a.dtsi"
 
 / {
@@ -70,6 +72,45 @@ &i2c2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c2_1_pins>;
 	status = "okay";
+
+	pca9545: i2c-mux at 70 {
+		compatible = "nxp,pca9545";
+		reg = <0x70>;
+		reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			pcf8563: rtc at 51 {
+				compatible = "nxp,pcf8563";
+				reg = <0x51>;
+				#clock-cells = <0>;
+			};
+
+			eeprom at 57 {
+				compatible = "atmel,24c02";
+				reg = <0x57>;
+				size = <256>;
+			};
+
+		};
+
+		i2c_sfp1: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		i2c_sfp2: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+	};
 };
 
 &pio {
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:33 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:33 +0100
Subject: [PATCH v3 19/22] arm64: dts: mediatek: mt7988a-bpi-r4: Enable t-phy for ssusb1
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-20-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Bananapi R4 uses t-phy for usb. Enable its node at board level.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 0dc1fd9265c6..129031b0d784 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -306,6 +306,10 @@ &serial0 {
 	status = "okay";
 };
 
+&tphy {
+	status = "okay";
+};
+
 &watchdog {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index c0a49f68834a..0766ca0dd3f6 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -525,7 +525,7 @@ pcie_intc1: interrupt-controller {
 			};
 		};
 
-		t-phy at 11c50000 {
+		tphy: t-phy at 11c50000 {
 			compatible = "mediatek,mt7986-tphy",
 				     "mediatek,generic-tphy-v2";
 			#address-cells = <2>;
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:34 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:34 +0100
Subject: [PATCH v3 20/22] arm64: dts: mediatek: mt7988a-bpi-r4: Enable ssusb1 on bpi-r4
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-21-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable usb on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes:
v3:
change commit title to have bpi-r4 prefix
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 129031b0d784..08d664d6449b 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -306,6 +306,10 @@ &serial0 {
 	status = "okay";
 };
 
+&ssusb1 {
+	status = "okay";
+};
+
 &tphy {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 0766ca0dd3f6..f3e942db0b99 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -337,7 +337,7 @@ usb at 11190000 {
 			status = "disabled";
 		};
 
-		usb at 11200000 {
+		ssusb1: usb at 11200000 {
 			compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
 			reg = <0 0x11200000 0 0x2e00>,
 			      <0 0x11203e00 0 0x0100>;
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:35 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:35 +0100
Subject: [PATCH v3 21/22] arm64: dts: mediatek: mt7988a-bpi-r4: Enable pwm
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-22-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable pwm on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes:
v3:
- change commit title to habe r4 prefix
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 08d664d6449b..4b1eaf818b66 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -302,6 +302,10 @@ mux {
 	};
 };
 
+&pwm {
+	status = "okay";
+};
+
 &serial0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index f3e942db0b99..6f6a1a1c1d78 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -211,7 +211,7 @@ mux {
 			};
 		};
 
-		pwm at 10048000 {
+		pwm: pwm at 10048000 {
 			compatible = "mediatek,mt7988-pwm";
 			reg = <0 0x10048000 0 0x1000>;
 			clocks = <&infracfg CLK_INFRA_66M_PWM_BCK>,
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:36 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:36 +0100
Subject: [PATCH v3 22/22] arm64: dts: mediatek: mt7988a-bpi-r4: Enable pcie
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-23-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable the pci controllers on BPI-R4.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 20 +++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi     |  8 ++++----
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 4b1eaf818b66..d6f1fca3323c 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -113,6 +113,26 @@ i2c_sfp2: i2c at 2 {
 	};
 };
 
+/* mPCIe SIM2 */
+&pcie0 {
+	status = "okay";
+};
+
+/* mPCIe SIM3 */
+&pcie1 {
+	status = "okay";
+};
+
+/* M.2 key-B SIM1 */
+&pcie2 {
+	status = "okay";
+};
+
+/* M.2 key-M SSD */
+&pcie3 {
+	status = "okay";
+};
+
 &pio {
 	mdio0_pins: mdio0-pins {
 		mux {
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 6f6a1a1c1d78..7a5e16a97476 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -373,7 +373,7 @@ mmc0: mmc at 11230000 {
 			status = "disabled";
 		};
 
-		pcie at 11280000 {
+		pcie2: pcie at 11280000 {
 			compatible = "mediatek,mt7986-pcie",
 				     "mediatek,mt8192-pcie";
 			device_type = "pci";
@@ -411,7 +411,7 @@ pcie_intc2: interrupt-controller {
 			};
 		};
 
-		pcie at 11290000 {
+		pcie3: pcie at 11290000 {
 			compatible = "mediatek,mt7986-pcie",
 				     "mediatek,mt8192-pcie";
 			device_type = "pci";
@@ -449,7 +449,7 @@ pcie_intc3: interrupt-controller {
 			};
 		};
 
-		pcie at 11300000 {
+		pcie0: pcie at 11300000 {
 			compatible = "mediatek,mt7986-pcie",
 				     "mediatek,mt8192-pcie";
 			device_type = "pci";
@@ -487,7 +487,7 @@ pcie_intc0: interrupt-controller {
 			};
 		};
 
-		pcie at 11310000 {
+		pcie1: pcie at 11310000 {
 			compatible = "mediatek,mt7986-pcie",
 				     "mediatek,mt8192-pcie";
 			device_type = "pci";
-- 
2.43.0



From robert.paczkowski at startupcovey.pl  Tue Dec 17 01:15:20 2024
From: robert.paczkowski at startupcovey.pl (Robert Paczkowski)
Date: Tue, 17 Dec 2024 09:15:20 GMT
Subject: =?UTF-8?Q?Wsp=C3=B3=C5=82praca?=
Message-ID: <20241217084500-0.1.8.e7j.0.1qao5l32sg@startupcovey.pl>

Dzie? dobry, 

Czy interesuje Pa?stwa pozyskanie nowych klient?w?

Zajmujemy si? profesjonalnie wsparciem firm w tym zakresie. 

Nasi partnerzy zyskuj? sta?y nap?yw nowych zlece? oraz zam?wie?, a tym samym zwi?kszaj? swoje wyniki sprzeda?y.

Czy mo?emy przedstawi? szczeg??y dotycz?ce zasad i mo?liwo?ci wsp??pracy?


Pozdrawiam serdecznie
Robert Paczkowski


From peng.fan at nxp.com  Tue Dec 17 01:16:43 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Tue, 17 Dec 2024 09:16:43 +0000
Subject: [PATCH V2] soc: imx8m: Add remove function
In-Reply-To: <20241217082637.i2ou6bbr3tc3uvof@pengutronix.de>
References: <20241217015826.1374497-1-peng.fan@oss.nxp.com>
 <20241217082637.i2ou6bbr3tc3uvof@pengutronix.de>
Message-ID: <PAXPR04MB8459A91EEC932F41E24AE04488042@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH V2] soc: imx8m: Add remove function
> 
> Hi Peng,
> 
> thanks for you patch.
> 
> On 24-12-17, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > Unregister the cpufreq device and soc device in remove path,
> otherwise
> 
> After reconsidiering the patch approach, I think we shouldn't add a
> .remove() function and instead should make use of the
> devm_add_action() mechanism for the proper unregister calls.

Would you please share why devm_add_action is preferred?

Something as below?
+static void imx8m_soc_remove(void *data)
+{
+       struct imx8m_soc_priv *priv = data;
+
+       if (priv->cpufreq_dev)
+               platform_device_unregister(priv->cpufreq_dev);
+
+       soc_device_unregister(priv->soc_dev);
+}
+
In Probe:
+       return devm_add_action(&pdev->dev, imx8m_soc_remove, priv);

Regards,
Peng.

> 
> > there will be warning when do removing test:
> > sysfs: cannot create duplicate filename '/devices/platform/imx-
> cpufreq-dt'
> > CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted
> > 6.13.0-rc1-next-20241204 Hardware name: NXP i.MX8MPlus EVK
> board (DT)
> >
> > Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as platform
> > driver")
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >
> > V2:
> >  Add err check when create the cpufreq platform device
> 
> thank you for addressing this.
> 
> Regards,
>   Marco
> 
> >  drivers/soc/imx/soc-imx8m.c | 41
> > +++++++++++++++++++++++++++++++------
> >  1 file changed, 35 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-
> imx8m.c
> > index 8ac7658e3d52..97c8718c2aa1 100644
> > --- a/drivers/soc/imx/soc-imx8m.c
> > +++ b/drivers/soc/imx/soc-imx8m.c
> > @@ -33,6 +33,11 @@ struct imx8_soc_data {
> >  	int (*soc_revision)(u32 *socrev, u64 *socuid);  };
> >
> > +struct imx8m_soc_priv {
> > +	struct soc_device *soc_dev;
> > +	struct platform_device *cpufreq_dev; };
> > +
> >  #ifdef CONFIG_HAVE_ARM_SMCCC
> >  static u32 imx8mq_soc_revision_from_atf(void)
> >  {
> > @@ -195,10 +200,11 @@ static __maybe_unused const struct
> of_device_id
> > imx8_soc_match[] = {  static int imx8m_soc_probe(struct
> > platform_device *pdev)  {
> >  	struct soc_device_attribute *soc_dev_attr;
> > +	struct platform_device *cpufreq_dev;
> >  	const struct imx8_soc_data *data;
> >  	struct device *dev = &pdev->dev;
> >  	const struct of_device_id *id;
> > -	struct soc_device *soc_dev;
> > +	struct imx8m_soc_priv *priv;
> >  	u32 soc_rev = 0;
> >  	u64 soc_uid = 0;
> >  	int ret;
> > @@ -207,6 +213,10 @@ static int imx8m_soc_probe(struct
> platform_device *pdev)
> >  	if (!soc_dev_attr)
> >  		return -ENOMEM;
> >
> > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> >  	soc_dev_attr->family = "Freescale i.MX";
> >
> >  	ret = of_property_read_string(of_root, "model",
> > &soc_dev_attr->machine); @@ -235,21 +245,40 @@ static int
> imx8m_soc_probe(struct platform_device *pdev)
> >  	if (!soc_dev_attr->serial_number)
> >  		return -ENOMEM;
> >
> > -	soc_dev = soc_device_register(soc_dev_attr);
> > -	if (IS_ERR(soc_dev))
> > -		return PTR_ERR(soc_dev);
> > +	priv->soc_dev = soc_device_register(soc_dev_attr);
> > +	if (IS_ERR(priv->soc_dev))
> > +		return PTR_ERR(priv->soc_dev);
> >
> >  	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
> >  		soc_dev_attr->revision);
> >
> > -	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
> > -		platform_device_register_simple("imx-cpufreq-dt", -1,
> NULL, 0);
> > +	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) {
> > +		cpufreq_dev = platform_device_register_simple("imx-
> cpufreq-dt", -1, NULL, 0);
> > +		if (!IS_ERR(cpufreq_dev))
> > +			priv->cpufreq_dev = cpufreq_dev;
> > +		else
> > +			dev_err(dev, "Failed to create imx-cpufreq-
> dev device: %ld",
> > +				PTR_ERR(cpufreq_dev));
> > +	}
> > +
> > +	platform_set_drvdata(pdev, priv);
> >
> >  	return 0;
> >  }
> >
> > +static void imx8m_soc_remove(struct platform_device *pdev) {
> > +	struct imx8m_soc_priv *priv = platform_get_drvdata(pdev);
> > +
> > +	if (priv->cpufreq_dev)
> > +		platform_device_unregister(priv->cpufreq_dev);
> > +
> > +	soc_device_unregister(priv->soc_dev);
> > +}
> > +
> >  static struct platform_driver imx8m_soc_driver = {
> >  	.probe = imx8m_soc_probe,
> > +	.remove	= imx8m_soc_remove,
> >  	.driver = {
> >  		.name = "imx8m-soc",
> >  	},
> > --
> > 2.37.1
> >
> >
> >


From 0x1207 at gmail.com  Tue Dec 17 01:17:12 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Tue, 17 Dec 2024 17:17:12 +0800
Subject: [PATCH net v1] net: stmmac: Drop useless code related to ethtool rx-copybreak
Message-ID: <20241217091712.383911-1-0x1207@gmail.com>

After commit 2af6106ae949 ("net: stmmac: Introducing support for Page
Pool"), these code turned to be useless and users of ethtool may get
confused about the unhandled rx-copybreak parameter.

This patch mostly reverts
commit 22ad38381547 ("stmmac: do not perform zero-copy for rx frames")

Fixes: 2af6106ae949 ("net: stmmac: Introducing support for Page Pool")
Signed-off-by: Furong Xu <0x1207 at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  2 -
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 39 -------------------
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  5 ---
 3 files changed, 46 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 1d86439b8a14..b8d631e559c0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -126,7 +126,6 @@ struct stmmac_rx_queue {
 	unsigned int cur_rx;
 	unsigned int dirty_rx;
 	unsigned int buf_alloc_num;
-	u32 rx_zeroc_thresh;
 	dma_addr_t dma_rx_phy;
 	u32 rx_tail_addr;
 	unsigned int state_saved;
@@ -266,7 +265,6 @@ struct stmmac_priv {
 	int sph_cap;
 	u32 sarc_type;
 
-	unsigned int rx_copybreak;
 	u32 rx_riwt[MTL_MAX_TX_QUEUES];
 	int hwts_rx_en;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 1d77389ce953..16b4d8c21c90 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -1227,43 +1227,6 @@ static int stmmac_get_ts_info(struct net_device *dev,
 		return ethtool_op_get_ts_info(dev, info);
 }
 
-static int stmmac_get_tunable(struct net_device *dev,
-			      const struct ethtool_tunable *tuna, void *data)
-{
-	struct stmmac_priv *priv = netdev_priv(dev);
-	int ret = 0;
-
-	switch (tuna->id) {
-	case ETHTOOL_RX_COPYBREAK:
-		*(u32 *)data = priv->rx_copybreak;
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static int stmmac_set_tunable(struct net_device *dev,
-			      const struct ethtool_tunable *tuna,
-			      const void *data)
-{
-	struct stmmac_priv *priv = netdev_priv(dev);
-	int ret = 0;
-
-	switch (tuna->id) {
-	case ETHTOOL_RX_COPYBREAK:
-		priv->rx_copybreak = *(u32 *)data;
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
 static int stmmac_get_mm(struct net_device *ndev,
 			 struct ethtool_mm_state *state)
 {
@@ -1390,8 +1353,6 @@ static const struct ethtool_ops stmmac_ethtool_ops = {
 	.set_per_queue_coalesce = stmmac_set_per_queue_coalesce,
 	.get_channels = stmmac_get_channels,
 	.set_channels = stmmac_set_channels,
-	.get_tunable = stmmac_get_tunable,
-	.set_tunable = stmmac_set_tunable,
 	.get_link_ksettings = stmmac_ethtool_get_link_ksettings,
 	.set_link_ksettings = stmmac_ethtool_set_link_ksettings,
 	.get_mm = stmmac_get_mm,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 16b8bcfa8b11..6bc10ffe7a2b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -77,7 +77,6 @@ module_param(phyaddr, int, 0444);
 MODULE_PARM_DESC(phyaddr, "Physical device address");
 
 #define STMMAC_TX_THRESH(x)	((x)->dma_conf.dma_tx_size / 4)
-#define STMMAC_RX_THRESH(x)	((x)->dma_conf.dma_rx_size / 4)
 
 /* Limit to make sure XDP TX and slow path can coexist */
 #define STMMAC_XSK_TX_BUDGET_MAX	256
@@ -107,8 +106,6 @@ static int buf_sz = DEFAULT_BUFSIZE;
 module_param(buf_sz, int, 0644);
 MODULE_PARM_DESC(buf_sz, "DMA buffer size");
 
-#define	STMMAC_RX_COPYBREAK	256
-
 static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
 				      NETIF_MSG_LINK | NETIF_MSG_IFUP |
 				      NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
@@ -3927,8 +3924,6 @@ static int __stmmac_open(struct net_device *dev,
 		}
 	}
 
-	priv->rx_copybreak = STMMAC_RX_COPYBREAK;
-
 	buf_sz = dma_conf->dma_buf_sz;
 	for (int i = 0; i < MTL_MAX_TX_QUEUES; i++)
 		if (priv->dma_conf.tx_queue[i].tbs & STMMAC_TBS_EN)
-- 
2.34.1



From oliver.upton at linux.dev  Tue Dec 17 01:19:08 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 01:19:08 -0800
Subject: [PATCH] KVM: arm64: Fix set_id_regs selftest for ASIDBITS becoming unwritable
In-Reply-To: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
References: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
Message-ID: <173442713502.3654654.5293442477717772457.b4-ty@linux.dev>

On Mon, 16 Dec 2024 19:28:24 +0000, Mark Brown wrote:
> In commit 03c7527e97f7 ("KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits
> to be overridden") we made that bitfield in the ID registers unwritable
> however the change neglected to make the corresponding update to set_id_regs
> resulting in it failing:
> 
> # ok 56 ID_AA64MMFR0_EL1_BIGEND
> # ==== Test Assertion Failure ====
> #   aarch64/set_id_regs.c:434: masks[idx] & ftr_bits[j].mask == ftr_bits[j].mask
> #   pid=5566 tid=5566 errno=22 - Invalid argument
> #      1	0x00000000004034a7: test_vm_ftr_id_regs at set_id_regs.c:434
> #      2	0x0000000000401b53: main at set_id_regs.c:684
> #      3	0x0000ffff8e6b7543: ?? ??:0
> #      4	0x0000ffff8e6b7617: ?? ??:0
> #      5	0x0000000000401e6f: _start at ??:?
> #   0 != 0xf0 (masks[idx] & ftr_bits[j].mask != ftr_bits[j].mask)
> not ok 8 selftests: kvm: set_id_regs # exit=254
> 
> [...]

Applied to fixes, thanks!

[1/1] KVM: arm64: Fix set_id_regs selftest for ASIDBITS becoming unwritable
      https://git.kernel.org/kvmarm/kvmarm/c/212fbabe1dfe

--
Best,
Oliver


From ck.hu at mediatek.com  Tue Dec 17 01:21:43 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 17 Dec 2024 09:21:43 +0000
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
	 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
Message-ID: <6ed3b9ee742dcf814f35e15d88db538480ba2d48.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> found in MediaTek's MT8195, MT8188 SoC and their variants, and
> including support for display modes up to 4k60 and for HDMI
> Audio, as per the HDMI 2.0 spec.
> 
> HDCP and CEC functionalities are also supported by this hardware,
> but are not included in this commit and that also poses a slight
> difference between the V2 and V1 controllers in how they handle
> Hotplug Detection (HPD).
> 
> While the v1 controller was using the CEC controller to check
> HDMI cable connection and disconnection, in this driver the v2
> one does not.
> 
> This is due to the fact that on parts with v2 designs, like the
> MT8195 SoC, there is one CEC controller shared between the HDMI
> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> adding support to use the CEC HW to wake up the HDMI controllers
> it is necessary to have support for one TX, one RX *and* for both
> at the same time.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

[snip]

> +static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
> +                                         struct drm_bridge_state *old_state)
> +{
> +       struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +       struct drm_atomic_state *state = old_state->base.state;
> +       struct drm_connector_state *conn_state;
> +       union phy_configure_opts opts = {
> +               .dp = { .link_rate = hdmi->mode.clock * KILO }
> +       };
> +
> +       /* Retrieve the connector through the atomic state */
> +       hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
> +
> +       conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
> +       if (WARN_ON(!conn_state))
> +               return;
> +
> +       /*
> +        * Preconfigure the HDMI controller and the HDMI PHY at pre_enable
> +        * stage to make sure that this IP is ready and clocked before the
> +        * mtk_dpi gets powered on and before it enables the output.

In patch [6/15], you does not power on DPI power in DPI driver.
Could you point out the code about 'mtk_dpi gets powered on'?

Regards,
CK

> +        */
> +       hdmi->dvi_mode = !hdmi->curr_conn->display_info.is_hdmi;
> +       mtk_hdmi_v2_output_set_display_mode(hdmi, &hdmi->mode);
> +
> +       /* Reconfigure phy clock link with appropriate rate */
> +       phy_configure(hdmi->phy, &opts);
> +
> +       /* Power on the PHY here to make sure that DPI_HDMI is clocked */
> +       phy_power_on(hdmi->phy);
> +
> +       hdmi->powered = true;
> +}
> +



From lpieralisi at kernel.org  Tue Dec 17 01:25:59 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Tue, 17 Dec 2024 10:25:59 +0100
Subject: [PATCH v8 2/2] PCI: imx6: Add IOMMU and ITS MSI support for
 i.MX95
In-Reply-To: <Z1xs6GkcdTg2c73F@lizhi-Precision-Tower-5810>
References: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
 <20241210-imx95_lut-v8-2-2e730b2e5fde@nxp.com>
 <Z1sTUaoA5yk9RcIc@lpieralisi>
 <Z1sdbH7N1Ly9eXc0@lizhi-Precision-Tower-5810>
 <Z1v/LCHsGOgnasuf@lpieralisi>
 <Z1xs6GkcdTg2c73F@lizhi-Precision-Tower-5810>
Message-ID: <Z2FDp1zQ7JzxQKJT@lpieralisi>

On Fri, Dec 13, 2024 at 12:20:40PM -0500, Frank Li wrote:
> On Fri, Dec 13, 2024 at 10:32:28AM +0100, Lorenzo Pieralisi wrote:
> > On Thu, Dec 12, 2024 at 12:29:16PM -0500, Frank Li wrote:
> > > On Thu, Dec 12, 2024 at 05:46:09PM +0100, Lorenzo Pieralisi wrote:
> > > > On Tue, Dec 10, 2024 at 05:48:59PM -0500, Frank Li wrote:
> > > > > For the i.MX95, configuration of a LUT is necessary to convert Bus Device
> > > > > Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
> > > > > This involves checking msi-map and iommu-map device tree properties to
> > > > > ensure consistent mapping of PCI BDF to the same stream IDs. Subsequently,
> > > > > LUT-related registers are configured. In the absence of an msi-map, the
> > > > > built-in MSI controller is utilized as a fallback.
> > > >
> > > > This is wrong information. What you want to say is that if an msi-map
> > > > isn't detected this means that the platform relies on DWC built-in
> > > > controller for MSIs (that does not need streamIDs handling).
> > > >
> > > > That's quite different from what you are writing here.
> > >
> > > How about ?
> > >
> > > "If an msi-map isn't detected, platform relies on DWC built-in controller
> > > for MSIs that does not need streamdIDs"
> >
> > Right. Question: what happens if DT shows that there are SMMU and/or
> > ITS bindings/mappings but the SMMU driver and ITS driver are either not
> > enabled or have not probed ?
> 
> It is little bit complex.
> iommu:
> Case 1:
> 	iommu{
> 		status = "disabled"
> 	};
> 
> 	PCI driver normal probed. if RID is in range of iommu-map, not
> any functional impact and harmless.
> 	If RID is out of range of iommu-map, "false alarm" will return.
> enable PCI EP device failure, but actually it can work without IOMMU.

What does "false alarm" mean in practice ? PCI device enable fails
but actually it should not ? That does not look like a false alarm to me.

> 
> Case 2:
> 	iommu {
> 		status = "Okay"
> 	}
> 	but iommu driver have not probed yet.  PCI Host bridge driver
> should defer till iommu probed.
> 
> Worst case is "false alarm". But this happen is very rare if DTS is
> correct.

Explain what this means.

> MSI:
> case 1:
> 	msi-controller {
> 		status = "disabled";
> 	}
> 	Whole all dwc drivers will be broken.

What MSI controller. Please make an effort to be precise and explain.

Thanks,
Lorenzo

> case 2:
> 	msi-controller {
> 		status = "Okay"
> 	}
> 	if msi driver have not probed yet, PCI Host bridge driver will
> defer.
> 
> Frank
> 
> >
> > I assume the LUT programming makes no difference (it is useless yes but
> > should be harmless too) in this case but wanted to check with you.
> >
> > Thanks,
> > Lorenzo
> >
> > >
> > > >
> > > > >
> > > > > Register a PCI bus callback function to handle enable_device() and
> > > > > disable_device() operations, setting up the LUT whenever a new PCI device
> > > > > is enabled.
> > > > >
> > > > > Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
> > > > > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > >
> > > [...]
> > >
> > > > > +	int err_i, err_m;
> > > > > +	u32 sid;
> > > > > +
> > > > > +	dev = imx_pcie->pci->dev;
> > > > > +
> > > > > +	target = NULL;
> > > > > +	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
> > > > > +	if (target) {
> > > > > +		of_node_put(target);
> > > > > +	} else {
> > > > > +		/*
> > > > > +		 * "target == NULL && err_i == 0" means use 1:1 map RID to
> > > >
> > > > Is it what it means ? Or does it mean that the iommu-map property was found
> > > > and RID is out of range ?
> > >
> > > yes, if this happen, sid_i will be equal to RID.
> > >
> > > >
> > > > Could you point me at a sample dts for this host bridge please ?
> > >
> > > https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/boot/dts/freescale/imx95.dtsi
> > >
> > > /* 0x10~0x17 stream id for pci0 */
> > >    iommu-map = <0x000 &smmu 0x10 0x1>,
> > >                <0x100 &smmu 0x11 0x7>;
> > >
> > > /* msi part */
> > >    msi-map = <0x000 &its 0x10 0x1>,
> > >              <0x100 &its 0x11 0x7>;
> > >
> > > >
> > > > > +		 * stream ID. Hardware can't support this because stream ID
> > > > > +		 * only 5bits
> > > >
> > > > It is 5 or 6 bits ? From GENMASK(5, 0) above it should be 6.
> > >
> > > Sorry for typo. it is 6bits.
> > >
> > > >
> > > > > +		 */
> > > > > +		err_i = -EINVAL;
> > > > > +	}
> > > > > +
> > > > > +	target = NULL;
> > > > > +	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
> > > > > +
> > > > > +	/*
> > > > > +	 *   err_m      target
> > > > > +	 *	0	NULL		Use 1:1 map RID to stream ID,
> > > >
> > > > Again, is that what it really means ?
> > > >
> > > > > +	 *				Current hardware can't support it,
> > > > > +	 *				So return -EINVAL.
> > > > > +	 *      != 0    NULL		msi-map not exist, use built-in MSI.
> > > >
> > > > does not exist.
> > > >
> > > > > +	 *	0	!= NULL		Get correct streamID from RID.
> > > > > +	 *	!= 0	!= NULL		Unexisted case, never happen.
> > > >
> > > > "Invalid combination"
> > > >
> > > > > +	 */
> > > > > +	if (!err_m && !target)
> > > > > +		return -EINVAL;
> > > > > +	else if (target)
> > > > > +		of_node_put(target); /* Find stream ID map entry for RID in msi-map */
> > > > > +
> > > > > +	/*
> > > > > +	 * msi-map        iommu-map
> > > > > +	 *   N                N            DWC MSI Ctrl
> > > > > +	 *   Y                Y            ITS + SMMU, require the same sid
> > > > > +	 *   Y                N            ITS
> > > > > +	 *   N                Y            DWC MSI Ctrl + SMMU
> > > > > +	 */
> > > > > +	if (err_i && err_m)
> > > > > +		return 0;
> > > > > +
> > > > > +	if (!err_i && !err_m) {
> > > > > +		/*
> > > > > +		 * MSI glue layer auto add 2 bits controller ID ahead of stream
> > > >
> > > > What's "MSI glue layer" ?
> > >
> > > It is common term for IC desgin, which connect IP's signal to platform with
> > > some simple logic. Inside chip, when connect LUT output 6bit streamIDs
> > > to MSI controller, there are 2bits hardcode controller ID information
> > > append to 6 bits streamID.
> > >
> > >            Glue Layer
> > >           <==========>
> > > ???????                  ????????????
> > > ? LUT ? 6bit stream ID   ?          ?
> > > ?     ????????????????????  MSI     ?
> > > ???????    2bit ctrl ID  ?          ?
> > >             ??????????????          ?
> > >             ?            ?          ?
> > >  00 PCIe0   ?            ?          ?
> > >  01 ENETC   ?            ?          ?
> > >  10 PCIe1   ?            ?          ?
> > >             ?            ????????????
> > >
> > > >
> > > > > +		 * ID, so mask this 2bits to get stream ID.
> > > > > +		 * But IOMMU glue layer doesn't do that.
> > > >
> > > > and "IOMMU glue layer" ?
> > >
> > > See above.
> > >
> > > Frank
> > >
> > > >
> > > > > +		 */
> > > > > +		if (sid_i != (sid_m & IMX95_SID_MASK)) {
> > > > > +			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
> > > > > +			return -EINVAL;
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	sid = sid_i;
> > > >
> > > > err_i could be != 0 here, I understand that the end result is
> > > > fine given how the code is written but it is misleading.
> > > >
> > > > 	if (!err_i)
> > > > 	else if (!err_m)
> > >
> > > Okay
> > >
> > > >
> > > > > +	if (!err_m)
> > > > > +		sid = sid_m & IMX95_SID_MASK;
> > > > > +
> > > > > +	return imx_pcie_add_lut(imx_pcie, rid, sid);
> > > > > +}
> > > > > +
> > > > > +static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> > > > > +{
> > > > > +	struct imx_pcie *imx_pcie;
> > > > > +
> > > > > +	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> > > > > +	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
> > > > > +}
> > > > > +
> > > > >  static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> > > > >  {
> > > > >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > > > @@ -946,6 +1122,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> > > > >  		}
> > > > >  	}
> > > > >
> > > > > +	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
> > > > > +		pp->bridge->enable_device = imx_pcie_enable_device;
> > > > > +		pp->bridge->disable_device = imx_pcie_disable_device;
> > > > > +	}
> > > > > +
> > > > >  	imx_pcie_assert_core_reset(imx_pcie);
> > > > >
> > > > >  	if (imx_pcie->drvdata->init_phy)
> > > > > @@ -1330,6 +1511,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
> > > > >  	imx_pcie->pci = pci;
> > > > >  	imx_pcie->drvdata = of_device_get_match_data(dev);
> > > > >
> > > > > +	mutex_init(&imx_pcie->lock);
> > > > > +
> > > > >  	/* Find the PHY if one is defined, only imx7d uses it */
> > > > >  	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
> > > > >  	if (np) {
> > > > > @@ -1627,7 +1810,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
> > > > >  	},
> > > > >  	[IMX95] = {
> > > > >  		.variant = IMX95,
> > > > > -		.flags = IMX_PCIE_FLAG_HAS_SERDES,
> > > > > +		.flags = IMX_PCIE_FLAG_HAS_SERDES |
> > > > > +			 IMX_PCIE_FLAG_HAS_LUT,
> > > > >  		.clk_names = imx8mq_clks,
> > > > >  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> > > > >  		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> > > > >
> > > > > --
> > > > > 2.34.1
> > > > >


From tabba at google.com  Tue Dec 17 01:25:52 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 09:25:52 +0000
Subject: [PATCH v3 00/18] KVM: arm64: Non-protected guest stage-2 support
 for pKVM
In-Reply-To: <20241216175803.2716565-1-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
Message-ID: <CA+EHjTz7=dRz5X-CjjniJgwd87Q4DQbRdXzi0on4C21urYnhOQ@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> Hi all,
>
> This is the v3 of the series adding support for non-protected guests
> stage-2 to pKVM. Please refer to v1 for all the context:

For the series:

Tested-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad



>
>   https://lore.kernel.org/kvmarm/20241104133204.85208-1-qperret at google.com/
>
> The series is organized as follows:
>
>  - Patches 01 to 04 move the host ownership state tracking from the
>    host's stage-2 page-table to the hypervisor's vmemmap. This avoids
>    fragmenting the host stage-2 for shared pages, which is only needed
>    to store an annotation in the SW bits of the corresponding PTE. All
>    pages mapped into non-protected guests are shared from pKVM's PoV,
>    so the cost of stage-2 fragmentation will increase massively as we
>    start tracking that at EL2. Note that these patches also help with
>    the existing sharing for e.g. FF-A, so they could possibly be merged
>    separately from the rest of the series.
>
>  - Patches 05 to 07 implement a minor refactoring of the pgtable code to
>    ease the integration of the pKVM MMU later on.
>
>  - Patches 08 to 16 introduce all the infrastructure needed on the pKVM
>    side for handling guest stage-2 page-tables at EL2.
>
>  - Patches 17 and 18 plumb the newly introduced pKVM support into
>    KVM/arm64.
>
> Patches based on 6.13-rc3, tested on Pixel 6 and Qemu.
>
> Changes in v3:
>  - Rebased on 6.13-rc3
>  - Applied Marc's rework of the for_each_mapping_in_range() macro mess
>  - Removed mappings_lock in favor the mmu_lock
>  - Dropped BUG_ON() from pkvm_mkstate()
>  - Renamed range_is_allowed_memory() and clarified the comment inside it
>  - Explicitly bail out when using host_stage2_set_owner_locked() on
>    non-memory regions
>  - Check PKVM_NOPAGE state as an equality rather than a bitwise
>    operator
>  - Reworked __pkvm_host_share_guest() to return -EPERM in case of
>    illegal multi-sharing
>  - Added get_np_pkvm_hyp_vm() to simplify HVC error handling in
>    hyp-main.c
>  - Cosmetic changes and improved coding consitency thoughout the series
>
> Changes in v2:
>  - Rebased on 6.13-rc1 (small conflicts with 2362506f7cff ("KVM: arm64:
>    Don't mark "struct page" accessed when making SPTE young") in
>    particular)
>  - Fixed kerneldoc breakage for __unmap_stage2_range()
>  - Fixed pkvm_pgtable_test_clear_young() to use correct HVC
>  - Folded guest_get_valid_pte() into __check_host_unshare_guest() for
>    clarity
>
> Thanks,
> Quentin
>
> Marc Zyngier (1):
>   KVM: arm64: Introduce __pkvm_vcpu_{load,put}()
>
> Quentin Perret (17):
>   KVM: arm64: Change the layout of enum pkvm_page_state
>   KVM: arm64: Move enum pkvm_page_state to memory.h
>   KVM: arm64: Make hyp_page::order a u8
>   KVM: arm64: Move host page ownership tracking to the hyp vmemmap
>   KVM: arm64: Pass walk flags to kvm_pgtable_stage2_mkyoung
>   KVM: arm64: Pass walk flags to kvm_pgtable_stage2_relax_perms
>   KVM: arm64: Make kvm_pgtable_stage2_init() a static inline function
>   KVM: arm64: Add {get,put}_pkvm_hyp_vm() helpers
>   KVM: arm64: Introduce __pkvm_host_share_guest()
>   KVM: arm64: Introduce __pkvm_host_unshare_guest()
>   KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
>   KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
>   KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
>   KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
>   KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
>   KVM: arm64: Introduce the EL1 pKVM MMU
>   KVM: arm64: Plumb the pKVM MMU in KVM
>
>  arch/arm64/include/asm/kvm_asm.h              |   9 +
>  arch/arm64/include/asm/kvm_host.h             |   4 +
>  arch/arm64/include/asm/kvm_mmu.h              |  16 +
>  arch/arm64/include/asm/kvm_pgtable.h          |  38 ++-
>  arch/arm64/include/asm/kvm_pkvm.h             |  23 ++
>  arch/arm64/kvm/arm.c                          |  23 +-
>  arch/arm64/kvm/hyp/include/nvhe/gfp.h         |   6 +-
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  38 +--
>  arch/arm64/kvm/hyp/include/nvhe/memory.h      |  42 ++-
>  arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  16 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 201 ++++++++++-
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 320 ++++++++++++++++--
>  arch/arm64/kvm/hyp/nvhe/page_alloc.c          |  14 +-
>  arch/arm64/kvm/hyp/nvhe/pkvm.c                |  68 ++++
>  arch/arm64/kvm/hyp/nvhe/setup.c               |   7 +-
>  arch/arm64/kvm/hyp/pgtable.c                  |  13 +-
>  arch/arm64/kvm/mmu.c                          | 113 +++++--
>  arch/arm64/kvm/pkvm.c                         | 198 +++++++++++
>  arch/arm64/kvm/vgic/vgic-v3.c                 |   6 +-
>  19 files changed, 1010 insertions(+), 145 deletions(-)
>
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From krzk at kernel.org  Tue Dec 17 01:26:41 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 10:26:41 +0100
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <6e93d59d-71e5-4c09-862f-55b5504121aa@gmail.com>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
 <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
 <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>
 <6e93d59d-71e5-4c09-862f-55b5504121aa@gmail.com>
Message-ID: <69fd1dbc-a29f-488c-a30f-7e5ea8f01a23@kernel.org>

On 17/12/2024 10:08, Ivaylo Ivanov wrote:
>>>>>        - items:
>>>>>            - enum:
>>>>> @@ -94,9 +95,28 @@ allOf:
>>>>>          - clock-names
>>>>>  
>>>>>      else:
>>>>> -      properties:
>>>>> -        clocks:
>>>>> -          maxItems: 1
>>>>> +      if:
>>>>> +        properties:
>>>>> +          compatible:
>>>>> +            contains:
>>>>> +              enum:
>>>>> +                - samsung,exynos8895-hsi2c
>>>>> +
>>>>> +      then:
>>>>> +        properties:
>>>>> +          clocks:
>>>> Missing minItems
>>>>
>>>>> +            maxItems: 2
>>>>> +
>>>>> +          clock-names:
>>>> Ditto
>>>>
>>>>> +            maxItems: 2
>>>>> +
>>>>> +        required:
>>>>> +          - clock-names
>>>> I don't understand why do you need second, same branch in if, basically
>>> Because, as I stated in the commit message, we have HSI2C controllers
>>> both implemented in USIv1 blocks and outside. These that are a part of
>> On Exynos8895? Where? With the same compatible?
> 
> hsi2c_0 which has a clock from BUSC and hsi2c_1 to hsi2c_4 which use clocks
> from PERIC1 (CLK_GOUT_PERIC1_HSI2C_CAM{0,1,2,3}_IPCLK). Why would
> they need a different compatible though? It's functionally the same i2c design
> as the one implemented in USIv1 blocks.
If one block is part of USI and other not, they might not be the same
I2C blocks, even if interface is similar. If they were the same or even
functionally the same, they would have the same clock inputs. However
user manual also suggests that there is only one clock, not two (for
both cases), so they could be functionally equivalent but then number of
clocks looks incorrect.

Best regards,
Krzysztof


From pabeni at redhat.com  Tue Dec 17 01:30:24 2024
From: pabeni at redhat.com (Paolo Abeni)
Date: Tue, 17 Dec 2024 10:30:24 +0100
Subject: [PATCH net-next v1] net: stmmac: TSO: Simplify the code flow of
 DMA descriptor allocations
In-Reply-To: <20241213030006.337695-1-0x1207@gmail.com>
References: <20241213030006.337695-1-0x1207@gmail.com>
Message-ID: <9d0722fe-1547-4b44-8a4a-69a8756bdb39@redhat.com>

On 12/13/24 04:00, Furong Xu wrote:
> The DMA AXI address width of DWMAC cores can be configured to
> 32-bit/40-bit/48-bit, then the format of DMA transmit descriptors
> get a little different between 32-bit and 40-bit/48-bit.
> Current driver code checks priv->dma_cap.addr64 to use certain format
> with certain configuration.
> 
> This patch converts the format of DMA transmit descriptors on platforms
> that the DMA AXI address width is configured to 32-bit (as described by
> function comments of stmmac_tso_xmit() in current code) to a more generic
> format (see the updated function comments after this patch) which is
> actually already used on 40-bit/48-bit platforms to provide better
> compatibility and make code flow cleaner.
> 
> Tested and verified on:
> DWMAC CORE 5.10a with 32-bit DMA AXI address width
> DWXGMAC CORE 3.20a with 40-bit DMA AXI address width
> 
> Signed-off-by: Furong Xu <0x1207 at gmail.com>

Makes sense to me.

Since this could potentially impact multiple versions, it would be great
if we could have a little more 3rd parties testing.

Thanks,

Paolo



From ivo.ivanov.ivanov1 at gmail.com  Tue Dec 17 01:31:30 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Tue, 17 Dec 2024 11:31:30 +0200
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <69fd1dbc-a29f-488c-a30f-7e5ea8f01a23@kernel.org>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
 <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
 <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>
 <6e93d59d-71e5-4c09-862f-55b5504121aa@gmail.com>
 <69fd1dbc-a29f-488c-a30f-7e5ea8f01a23@kernel.org>
Message-ID: <17fbfcdd-8b79-4907-a4c8-798da0ef0526@gmail.com>

On 12/17/24 11:26, Krzysztof Kozlowski wrote:
> On 17/12/2024 10:08, Ivaylo Ivanov wrote:
>>>>>>        - items:
>>>>>>            - enum:
>>>>>> @@ -94,9 +95,28 @@ allOf:
>>>>>>          - clock-names
>>>>>>  
>>>>>>      else:
>>>>>> -      properties:
>>>>>> -        clocks:
>>>>>> -          maxItems: 1
>>>>>> +      if:
>>>>>> +        properties:
>>>>>> +          compatible:
>>>>>> +            contains:
>>>>>> +              enum:
>>>>>> +                - samsung,exynos8895-hsi2c
>>>>>> +
>>>>>> +      then:
>>>>>> +        properties:
>>>>>> +          clocks:
>>>>> Missing minItems
>>>>>
>>>>>> +            maxItems: 2
>>>>>> +
>>>>>> +          clock-names:
>>>>> Ditto
>>>>>
>>>>>> +            maxItems: 2
>>>>>> +
>>>>>> +        required:
>>>>>> +          - clock-names
>>>>> I don't understand why do you need second, same branch in if, basically
>>>> Because, as I stated in the commit message, we have HSI2C controllers
>>>> both implemented in USIv1 blocks and outside. These that are a part of
>>> On Exynos8895? Where? With the same compatible?
>> hsi2c_0 which has a clock from BUSC and hsi2c_1 to hsi2c_4 which use clocks
>> from PERIC1 (CLK_GOUT_PERIC1_HSI2C_CAM{0,1,2,3}_IPCLK). Why would
>> they need a different compatible though? It's functionally the same i2c design
>> as the one implemented in USIv1 blocks.
> If one block is part of USI and other not, they might not be the same
> I2C blocks, even if interface is similar. If they were the same or even
> functionally the same, they would have the same clock inputs. However

I see, so in such case I should make samsung,exynos8895-hsi2c-nonusi or
something like that?

> user manual also suggests that there is only one clock, not two (for
> both cases), so they could be functionally equivalent but then number of
> clocks looks incorrect.

That'd be weird. Both according to downstream and upstream clk driver,
for the USI-implemented i2cs we have a pclk and an sclk_usi.

Best regards,
Ivo.

>
> Best regards,
> Krzysztof



From tabba at google.com  Tue Dec 17 01:34:41 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 09:34:41 +0000
Subject: [PATCH v3 18/18] KVM: arm64: Plumb the pKVM MMU in KVM
In-Reply-To: <20241216175803.2716565-19-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-19-qperret@google.com>
Message-ID: <CA+EHjTyu=CdAaPuNZScjASEKrm4zh1851isPqQfDej-Ms_vATA@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> Introduce the KVM_PGT_S2() helper macro to allow switching from the
> traditional pgtable code to the pKVM version easily in mmu.c. The cost
> of this 'indirection' is expected to be very minimal due to
> is_protected_kvm_enabled() being backed by a static key.
>
> With this, everything is in place to allow the delegation of
> non-protected guest stage-2 page-tables to pKVM, so let's stop using the
> host's kvm_s2_mmu from EL2 and enjoy the ride.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/include/asm/kvm_mmu.h   |  16 +++++
>  arch/arm64/kvm/arm.c               |   9 ++-
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c |   2 -
>  arch/arm64/kvm/mmu.c               | 107 +++++++++++++++++++++--------
>  4 files changed, 101 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index 66d93e320ec8..d116ab4230e8 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -353,6 +353,22 @@ static inline bool kvm_is_nested_s2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
>         return &kvm->arch.mmu != mmu;
>  }
>
> +static inline void kvm_fault_lock(struct kvm *kvm)
> +{
> +       if (is_protected_kvm_enabled())
> +               write_lock(&kvm->mmu_lock);
> +       else
> +               read_lock(&kvm->mmu_lock);
> +}
> +
> +static inline void kvm_fault_unlock(struct kvm *kvm)
> +{
> +       if (is_protected_kvm_enabled())
> +               write_unlock(&kvm->mmu_lock);
> +       else
> +               read_unlock(&kvm->mmu_lock);
> +}
> +
>  #ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
>  void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
>  #else
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 55cc62b2f469..9bcbc7b8ed38 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -502,7 +502,10 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
>
>  void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
>  {
> -       kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
> +       if (!is_protected_kvm_enabled())
> +               kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
> +       else
> +               free_hyp_memcache(&vcpu->arch.pkvm_memcache);
>         kvm_timer_vcpu_terminate(vcpu);
>         kvm_pmu_vcpu_destroy(vcpu);
>         kvm_vgic_vcpu_destroy(vcpu);
> @@ -574,6 +577,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>         struct kvm_s2_mmu *mmu;
>         int *last_ran;
>
> +       if (is_protected_kvm_enabled())
> +               goto nommu;
> +
>         if (vcpu_has_nv(vcpu))
>                 kvm_vcpu_load_hw_mmu(vcpu);
>
> @@ -594,6 +600,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>                 *last_ran = vcpu->vcpu_idx;
>         }
>
> +nommu:
>         vcpu->cpu = cpu;
>
>         kvm_vgic_load(vcpu);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 130f5f23bcb5..258d572eed62 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -103,8 +103,6 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
>         /* Limit guest vector length to the maximum supported by the host.  */
>         hyp_vcpu->vcpu.arch.sve_max_vl  = min(host_vcpu->arch.sve_max_vl, kvm_host_sve_max_vl);
>
> -       hyp_vcpu->vcpu.arch.hw_mmu      = host_vcpu->arch.hw_mmu;
> -
>         hyp_vcpu->vcpu.arch.mdcr_el2    = host_vcpu->arch.mdcr_el2;
>         hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE);
>         hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2) &
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 641e4fec1659..7c2995cb4577 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -15,6 +15,7 @@
>  #include <asm/kvm_arm.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/kvm_pgtable.h>
> +#include <asm/kvm_pkvm.h>
>  #include <asm/kvm_ras.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_emulate.h>
> @@ -31,6 +32,14 @@ static phys_addr_t __ro_after_init hyp_idmap_vector;
>
>  static unsigned long __ro_after_init io_map_base;
>
> +#define KVM_PGT_S2(fn, ...)                                                            \
> +       ({                                                                              \
> +               typeof(kvm_pgtable_stage2_ ## fn) *__fn = kvm_pgtable_stage2_ ## fn;    \
> +               if (is_protected_kvm_enabled())                                         \
> +                       __fn = pkvm_pgtable_ ## fn;                                     \
> +               __fn(__VA_ARGS__);                                                      \
> +       })
> +
>  static phys_addr_t __stage2_range_addr_end(phys_addr_t addr, phys_addr_t end,
>                                            phys_addr_t size)
>  {
> @@ -147,7 +156,7 @@ static int kvm_mmu_split_huge_pages(struct kvm *kvm, phys_addr_t addr,
>                         return -EINVAL;
>
>                 next = __stage2_range_addr_end(addr, end, chunk_size);
> -               ret = kvm_pgtable_stage2_split(pgt, addr, next - addr, cache);
> +               ret = KVM_PGT_S2(split, pgt, addr, next - addr, cache);
>                 if (ret)
>                         break;
>         } while (addr = next, addr != end);
> @@ -168,15 +177,23 @@ static bool memslot_is_logging(struct kvm_memory_slot *memslot)
>   */
>  int kvm_arch_flush_remote_tlbs(struct kvm *kvm)
>  {
> -       kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
> +       if (is_protected_kvm_enabled())
> +               kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
> +       else
> +               kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
>         return 0;
>  }
>
>  int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm,
>                                       gfn_t gfn, u64 nr_pages)
>  {
> -       kvm_tlb_flush_vmid_range(&kvm->arch.mmu,
> -                               gfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT);
> +       u64 size = nr_pages << PAGE_SHIFT;
> +       u64 addr = gfn << PAGE_SHIFT;
> +
> +       if (is_protected_kvm_enabled())
> +               kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
> +       else
> +               kvm_tlb_flush_vmid_range(&kvm->arch.mmu, addr, size);
>         return 0;
>  }
>
> @@ -225,7 +242,7 @@ static void stage2_free_unlinked_table_rcu_cb(struct rcu_head *head)
>         void *pgtable = page_to_virt(page);
>         s8 level = page_private(page);
>
> -       kvm_pgtable_stage2_free_unlinked(&kvm_s2_mm_ops, pgtable, level);
> +       KVM_PGT_S2(free_unlinked, &kvm_s2_mm_ops, pgtable, level);
>  }
>
>  static void stage2_free_unlinked_table(void *addr, s8 level)
> @@ -280,6 +297,11 @@ static void invalidate_icache_guest_page(void *va, size_t size)
>         __invalidate_icache_guest_page(va, size);
>  }
>
> +static int kvm_s2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> +       return KVM_PGT_S2(unmap, pgt, addr, size);
> +}
> +
>  /*
>   * Unmapping vs dcache management:
>   *
> @@ -324,8 +346,7 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
>
>         lockdep_assert_held_write(&kvm->mmu_lock);
>         WARN_ON(size & ~PAGE_MASK);
> -       WARN_ON(stage2_apply_range(mmu, start, end, kvm_pgtable_stage2_unmap,
> -                                  may_block));
> +       WARN_ON(stage2_apply_range(mmu, start, end, kvm_s2_unmap, may_block));
>  }
>
>  void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
> @@ -334,9 +355,14 @@ void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
>         __unmap_stage2_range(mmu, start, size, may_block);
>  }
>
> +static int kvm_s2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> +       return KVM_PGT_S2(flush, pgt, addr, size);
> +}
> +
>  void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
>  {
> -       stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_flush);
> +       stage2_apply_range_resched(mmu, addr, end, kvm_s2_flush);
>  }
>
>  static void stage2_flush_memslot(struct kvm *kvm,
> @@ -942,10 +968,14 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
>                 return -ENOMEM;
>
>         mmu->arch = &kvm->arch;
> -       err = kvm_pgtable_stage2_init(pgt, mmu, &kvm_s2_mm_ops);
> +       err = KVM_PGT_S2(init, pgt, mmu, &kvm_s2_mm_ops);
>         if (err)
>                 goto out_free_pgtable;
>
> +       mmu->pgt = pgt;
> +       if (is_protected_kvm_enabled())
> +               return 0;
> +
>         mmu->last_vcpu_ran = alloc_percpu(typeof(*mmu->last_vcpu_ran));
>         if (!mmu->last_vcpu_ran) {
>                 err = -ENOMEM;
> @@ -959,7 +989,6 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
>         mmu->split_page_chunk_size = KVM_ARM_EAGER_SPLIT_CHUNK_SIZE_DEFAULT;
>         mmu->split_page_cache.gfp_zero = __GFP_ZERO;
>
> -       mmu->pgt = pgt;
>         mmu->pgd_phys = __pa(pgt->pgd);
>
>         if (kvm_is_nested_s2_mmu(kvm, mmu))
> @@ -968,7 +997,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
>         return 0;
>
>  out_destroy_pgtable:
> -       kvm_pgtable_stage2_destroy(pgt);
> +       KVM_PGT_S2(destroy, pgt);
>  out_free_pgtable:
>         kfree(pgt);
>         return err;
> @@ -1065,7 +1094,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
>         write_unlock(&kvm->mmu_lock);
>
>         if (pgt) {
> -               kvm_pgtable_stage2_destroy(pgt);
> +               KVM_PGT_S2(destroy, pgt);
>                 kfree(pgt);
>         }
>  }
> @@ -1082,9 +1111,11 @@ static void *hyp_mc_alloc_fn(void *unused)
>
>  void free_hyp_memcache(struct kvm_hyp_memcache *mc)
>  {
> -       if (is_protected_kvm_enabled())
> -               __free_hyp_memcache(mc, hyp_mc_free_fn,
> -                                   kvm_host_va, NULL);
> +       if (!is_protected_kvm_enabled())
> +               return;
> +
> +       kfree(mc->mapping);
> +       __free_hyp_memcache(mc, hyp_mc_free_fn, kvm_host_va, NULL);
>  }
>
>  int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages)
> @@ -1092,6 +1123,12 @@ int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages)
>         if (!is_protected_kvm_enabled())
>                 return 0;
>
> +       if (!mc->mapping) {
> +               mc->mapping = kzalloc(sizeof(struct pkvm_mapping), GFP_KERNEL_ACCOUNT);
> +               if (!mc->mapping)
> +                       return -ENOMEM;
> +       }
> +
>         return __topup_hyp_memcache(mc, min_pages, hyp_mc_alloc_fn,
>                                     kvm_host_pa, NULL);
>  }
> @@ -1130,8 +1167,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
>                         break;
>
>                 write_lock(&kvm->mmu_lock);
> -               ret = kvm_pgtable_stage2_map(pgt, addr, PAGE_SIZE, pa, prot,
> -                                            &cache, 0);
> +               ret = KVM_PGT_S2(map, pgt, addr, PAGE_SIZE, pa, prot, &cache, 0);
>                 write_unlock(&kvm->mmu_lock);
>                 if (ret)
>                         break;
> @@ -1143,6 +1179,10 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
>         return ret;
>  }
>
> +static int kvm_s2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> +       return KVM_PGT_S2(wrprotect, pgt, addr, size);
> +}
>  /**
>   * kvm_stage2_wp_range() - write protect stage2 memory region range
>   * @mmu:        The KVM stage-2 MMU pointer
> @@ -1151,7 +1191,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
>   */
>  void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
>  {
> -       stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_wrprotect);
> +       stage2_apply_range_resched(mmu, addr, end, kvm_s2_wrprotect);
>  }
>
>  /**
> @@ -1442,9 +1482,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>         unsigned long mmu_seq;
>         phys_addr_t ipa = fault_ipa;
>         struct kvm *kvm = vcpu->kvm;
> -       struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
>         struct vm_area_struct *vma;
>         short vma_shift;
> +       void *memcache;
>         gfn_t gfn;
>         kvm_pfn_t pfn;
>         bool logging_active = memslot_is_logging(memslot);
> @@ -1472,8 +1512,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>          * and a write fault needs to collapse a block entry into a table.
>          */
>         if (!fault_is_perm || (logging_active && write_fault)) {
> -               ret = kvm_mmu_topup_memory_cache(memcache,
> -                                                kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu));
> +               int min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu);
> +
> +               if (!is_protected_kvm_enabled()) {
> +                       memcache = &vcpu->arch.mmu_page_cache;
> +                       ret = kvm_mmu_topup_memory_cache(memcache, min_pages);
> +               } else {
> +                       memcache = &vcpu->arch.pkvm_memcache;
> +                       ret = topup_hyp_memcache(memcache, min_pages);
> +               }
>                 if (ret)
>                         return ret;
>         }
> @@ -1494,7 +1541,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>          * logging_active is guaranteed to never be true for VM_PFNMAP
>          * memslots.
>          */
> -       if (logging_active) {
> +       if (logging_active || is_protected_kvm_enabled()) {
>                 force_pte = true;
>                 vma_shift = PAGE_SHIFT;
>         } else {
> @@ -1634,7 +1681,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>                 prot |= kvm_encode_nested_level(nested);
>         }
>
> -       read_lock(&kvm->mmu_lock);
> +       kvm_fault_lock(kvm);
>         pgt = vcpu->arch.hw_mmu->pgt;
>         if (mmu_invalidate_retry(kvm, mmu_seq)) {
>                 ret = -EAGAIN;
> @@ -1696,16 +1743,16 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>                  * PTE, which will be preserved.
>                  */
>                 prot &= ~KVM_NV_GUEST_MAP_SZ;
> -               ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot, flags);
> +               ret = KVM_PGT_S2(relax_perms, pgt, fault_ipa, prot, flags);
>         } else {
> -               ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
> +               ret = KVM_PGT_S2(map, pgt, fault_ipa, vma_pagesize,
>                                              __pfn_to_phys(pfn), prot,
>                                              memcache, flags);
>         }
>
>  out_unlock:
>         kvm_release_faultin_page(kvm, page, !!ret, writable);
> -       read_unlock(&kvm->mmu_lock);
> +       kvm_fault_unlock(kvm);
>
>         /* Mark the page dirty only if the fault is handled successfully */
>         if (writable && !ret)
> @@ -1724,7 +1771,7 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
>
>         read_lock(&vcpu->kvm->mmu_lock);
>         mmu = vcpu->arch.hw_mmu;
> -       kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa, flags);
> +       KVM_PGT_S2(mkyoung, mmu->pgt, fault_ipa, flags);
>         read_unlock(&vcpu->kvm->mmu_lock);
>  }
>
> @@ -1764,7 +1811,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>                 }
>
>                 /* Falls between the IPA range and the PARange? */
> -               if (fault_ipa >= BIT_ULL(vcpu->arch.hw_mmu->pgt->ia_bits)) {
> +               if (fault_ipa >= BIT_ULL(VTCR_EL2_IPA(vcpu->arch.hw_mmu->vtcr))) {
>                         fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
>
>                         if (is_iabt)
> @@ -1930,7 +1977,7 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
>         if (!kvm->arch.mmu.pgt)
>                 return false;
>
> -       return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
> +       return KVM_PGT_S2(test_clear_young, kvm->arch.mmu.pgt,
>                                                    range->start << PAGE_SHIFT,
>                                                    size, true);
>         /*
> @@ -1946,7 +1993,7 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
>         if (!kvm->arch.mmu.pgt)
>                 return false;
>
> -       return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
> +       return KVM_PGT_S2(test_clear_young, kvm->arch.mmu.pgt,
>                                                    range->start << PAGE_SHIFT,
>                                                    size, false);
>  }
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From l.stach at pengutronix.de  Tue Dec 17 01:37:14 2024
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 17 Dec 2024 10:37:14 +0100
Subject: imx8m-blk-ctrl: WARNING, no release() function
In-Reply-To: <20241217094219.788cad88@booty>
References: <20241212141003.GA44219@francesco-nb>
	 <PAXPR04MB8459AB53B142CB43782757D988042@PAXPR04MB8459.eurprd04.prod.outlook.com>
	 <20241217094219.788cad88@booty>
Message-ID: <8956e0daffc89f8c6791f8a53b1666ca31011a45.camel@pengutronix.de>

Hi Luca,

Am Dienstag, dem 17.12.2024 um 09:42 +0100 schrieb Luca Ceresoli:
> Hello Peng,
> 
> On Tue, 17 Dec 2024 01:39:09 +0000
> Peng Fan <peng.fan at nxp.com> wrote:
> 
> > > Subject: imx8m-blk-ctrl: WARNING, no release() function  
> > 
> > Please try this patch.
> > https://lore.kernel.org/all/20241206112731.98244-1-peng.fan at oss.nxp.com/
> 
> I cherry-picked the two patches from linux-next:
> 
>   e1a875703470 ("pmdomain: imx-gpcv2: Suppress bind attrs")
>   afb2a86f002b ("pmdomain: imx8m[p]-blk-ctrl: Suppress bind attrs")
> 
> but I still have the same warnings:
> 
> [    5.427038] Device 'mediablk-mipi-csi2-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
> [    6.464219] Device 'mediablk-mipi-dsi-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
> [    6.752903] Device 'mediablk-mipi-csi2-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
> [    7.303529] Device 'mediablk-mipi-dsi-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
> [    8.006575] Device 'mediablk-mipi-csi2-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
> [    8.598453] Device 'mediablk-mipi-dsi-1' does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.
> 
> This is with 6.13-rc3 on a imx8mp.

As far as I can see this isn't emitted due to the blk-ctrl device
itself missing the release function, but from the pseudo devices used
by genpd to control the power of the secondary power domains.

I think this needs to be fixed in genpd itself. I'll take a look.

Regards,
Lucas


From tudor.ambarus at linaro.org  Tue Dec 17 01:40:20 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue, 17 Dec 2024 09:40:20 +0000
Subject: [PATCH v5 1/3] dt-bindings: mailbox: add google,gs101-mbox
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
Message-ID: <20241217-acpm-v4-upstream-mbox-v5-1-cd1d3951fe84@linaro.org>

Add bindings for the Samsung Exynos Mailbox Controller.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 .../bindings/mailbox/google,gs101-mbox.yaml        | 79 ++++++++++++++++++++++
 include/dt-bindings/mailbox/google,gs101.h         | 14 ++++
 2 files changed, 93 insertions(+)

diff --git a/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
new file mode 100644
index 000000000000..bc7288923795
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright 2024 Linaro Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/google,gs101-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos Mailbox Controller
+
+maintainers:
+  - Tudor Ambarus <tudor.ambarus at linaro.org>
+
+description: |
+  The samsung exynos mailbox controller has 16 flag bits for hardware interrupt
+  generation and a shared register for passing mailbox messages. When the
+  controller is used by the ACPM protocol the shared register is ignored and
+  the mailbox controller acts as a doorbell. The controller just raises the
+  interrupt to the firmware after the ACPM protocol has written the message to
+  SRAM.
+
+properties:
+  compatible:
+    const: google,gs101-mbox
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: pclk
+
+  interrupts:
+    description: IRQ line for the RX mailbox.
+    maxItems: 1
+
+  '#mbox-cells':
+    description: |
+      <&phandle type channel>
+      phandle : label name of controller.
+      type    : channel type, doorbell or data-transfer.
+      channel : channel number.
+
+      Here is how a client can reference them:
+      mboxes = <&ap2apm_mailbox DOORBELL 2>;
+      mboxes = <&ap2apm_mailbox DATA 3>;
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - '#mbox-cells'
+
+additionalProperties: false
+
+examples:
+  # Doorbell mode.
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/google,gs101.h>
+
+    soc {
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        ap2apm_mailbox: mailbox at 17610000 {
+            compatible = "google,gs101-mbox";
+            reg = <0x17610000 0x1000>;
+            clocks = <&cmu_apm CLK_GOUT_APM_MAILBOX_APM_AP_PCLK>;
+            clock-names = "pclk";
+            interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 0>;
+            #mbox-cells = <2>;
+        };
+    };
diff --git a/include/dt-bindings/mailbox/google,gs101.h b/include/dt-bindings/mailbox/google,gs101.h
new file mode 100644
index 000000000000..7ff4fe669f9e
--- /dev/null
+++ b/include/dt-bindings/mailbox/google,gs101.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright 2024 Linaro Ltd.
+ *
+ * This header provides constants for the defined mailbox channel types.
+ */
+
+#ifndef _DT_BINDINGS_MAILBOX_GOOGLE_GS101_H
+#define _DT_BINDINGS_MAILBOX_GOOGLE_GS101_H
+
+#define DOORBELL	0
+#define DATA		1
+
+#endif /* _DT_BINDINGS_MAILBOX_GOOGLE_GS101_H */

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Tue Dec 17 01:40:19 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue, 17 Dec 2024 09:40:19 +0000
Subject: [PATCH v5 0/3] mailbox: add Samsung Exynos driver
Message-ID: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>

The samsung exynos mailbox controller has 16 flag bits for hardware
interrupt generation and a shared register for passing mailbox messages.
When the controller is used by the ACPM protocol the shared register is
ignored and the mailbox controller acts as a doorbell. The controller
just raises the interrupt to APM after the ACPM protocol has written
the message to SRAM.

Changes in v5:
- fix dt-bindings by using the correct compatible name in the example
- drop redundand "bindings" from the dt-bindings patch subject
- rebase on top of v6.13-rc3
- Link to v4: https://lore.kernel.org/r/20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf at linaro.org

Changes in v4:
- rename bindings file to be based on compatible: google,gs101-acpm-mbox
- specify doorbell or data mode via '#mbox-cells' dt property. Update
  driver and introduce exynos_mbox_of_xlate() to parse the mode.
- s/samsung/Samsung/, s/exynos/Exynos/
- use writel instead of writel_relaxed
- remove stray of_match_ptr()
- Link to v3: https://lore.kernel.org/linux-arm-kernel/20241205174137.190545-1-tudor.ambarus at linaro.org/

Changes in v3:
- decouple the mailbox controller driver from the ACPM protocol driver
- address Krzysztof's review comments

v2:
https://lore.kernel.org/linux-arm-kernel/20241017163649.3007062-1-tudor.ambarus at linaro.org/

v1:
https://lore.kernel.org/linux-arm-kernel/20241004165301.1979527-1-tudor.ambarus at linaro.org/

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Tudor Ambarus (3):
      dt-bindings: mailbox: add google,gs101-mbox
      mailbox: add Samsung Exynos driver
      MAINTAINERS: add entry for Samsung Exynos mailbox driver

 .../bindings/mailbox/google,gs101-mbox.yaml        |  79 +++++++++
 MAINTAINERS                                        |  10 ++
 drivers/mailbox/Kconfig                            |  11 ++
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/exynos-mailbox.c                   | 184 +++++++++++++++++++++
 include/dt-bindings/mailbox/google,gs101.h         |  14 ++
 6 files changed, 300 insertions(+)
---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241212-acpm-v4-upstream-mbox-948714004b05

Best regards,
-- 
Tudor Ambarus <tudor.ambarus at linaro.org>



From tudor.ambarus at linaro.org  Tue Dec 17 01:40:21 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue, 17 Dec 2024 09:40:21 +0000
Subject: [PATCH v5 2/3] mailbox: add Samsung Exynos driver
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
Message-ID: <20241217-acpm-v4-upstream-mbox-v5-2-cd1d3951fe84@linaro.org>

The Samsung Exynos mailbox controller has 16 flag bits for hardware
interrupt generation and a shared register for passing mailbox messages.
When the controller is used by the ACPM protocol the shared register is
ignored and the mailbox controller acts as a doorbell. The controller
just raises the interrupt to APM after the ACPM protocol has written
the message to SRAM.

Add support for the Samsung Exynos mailbox controller.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/mailbox/Kconfig          |  11 +++
 drivers/mailbox/Makefile         |   2 +
 drivers/mailbox/exynos-mailbox.c | 184 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 197 insertions(+)

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 8ecba7fb999e..44b808c4d97f 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -36,6 +36,17 @@ config ARM_MHU_V3
 	  that provides different means of transports: supported extensions
 	  will be discovered and possibly managed at probe-time.
 
+config EXYNOS_MBOX
+	tristate "Exynos Mailbox"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	help
+	  Say Y here if you want to build the Samsung Exynos Mailbox controller
+	  driver. The controller has 16 flag bits for hardware interrupt
+	  generation and a shared register for passing mailbox messages.
+	  When the controller is used by the ACPM protocol the shared register
+	  is ignored and the mailbox controller acts as a doorbell that raises
+	  the interrupt to the ACPM firmware.
+
 config IMX_MBOX
 	tristate "i.MX Mailbox"
 	depends on ARCH_MXC || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 5f4f5b0ce2cc..86192b5c7c32 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -11,6 +11,8 @@ obj-$(CONFIG_ARM_MHU_V2)	+= arm_mhuv2.o
 
 obj-$(CONFIG_ARM_MHU_V3)	+= arm_mhuv3.o
 
+obj-$(CONFIG_EXYNOS_MBOX)	+= exynos-mailbox.o
+
 obj-$(CONFIG_IMX_MBOX)	+= imx-mailbox.o
 
 obj-$(CONFIG_ARMADA_37XX_RWTM_MBOX)	+= armada-37xx-rwtm-mailbox.o
diff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c
new file mode 100644
index 000000000000..9d875806d0f9
--- /dev/null
+++ b/drivers/mailbox/exynos-mailbox.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#include <dt-bindings/mailbox/google,gs101.h>
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define EXYNOS_MBOX_MCUCTRL		0x0	/* Mailbox Control Register */
+#define EXYNOS_MBOX_INTCR0		0x24	/* Interrupt Clear Register 0 */
+#define EXYNOS_MBOX_INTMR0		0x28	/* Interrupt Mask Register 0 */
+#define EXYNOS_MBOX_INTSR0		0x2c	/* Interrupt Status Register 0 */
+#define EXYNOS_MBOX_INTMSR0		0x30	/* Interrupt Mask Status Register 0 */
+#define EXYNOS_MBOX_INTGR1		0x40	/* Interrupt Generation Register 1 */
+#define EXYNOS_MBOX_INTMR1		0x48	/* Interrupt Mask Register 1 */
+#define EXYNOS_MBOX_INTSR1		0x4c	/* Interrupt Status Register 1 */
+#define EXYNOS_MBOX_INTMSR1		0x50	/* Interrupt Mask Status Register 1 */
+
+#define EXYNOS_MBOX_INTMR0_MASK		GENMASK(15, 0)
+#define EXYNOS_MBOX_INTGR1_MASK		GENMASK(15, 0)
+
+#define EXYNOS_MBOX_CHAN_COUNT		HWEIGHT32(EXYNOS_MBOX_INTGR1_MASK)
+
+enum {
+	EXYNOS_MBOX_CELL_TYPE,
+	EXYNOS_MBOX_CELL_ID,
+	EXYNOS_MBOX_CELLS
+};
+
+#define EXYNOS_MBOX_CELL_TYPE_COUNT	2
+
+/**
+ * struct exynos_mbox - driver's private data.
+ * @regs:	mailbox registers base address.
+ * @mbox:	pointer to the mailbox controller.
+ * @dev:	pointer to the mailbox device.
+ * @pclk:	pointer to the mailbox peripheral clock.
+ */
+struct exynos_mbox {
+	void __iomem *regs;
+	struct mbox_controller *mbox;
+	struct device *dev;
+	struct clk *pclk;
+};
+
+static int exynos_mbox_chan_index(struct mbox_chan *chan)
+{
+	struct mbox_controller *mbox = chan->mbox;
+	int i;
+
+	for (i = 0; i < mbox->num_chans; i++)
+		if (chan == &mbox->chans[i])
+			return i;
+	return -EINVAL;
+}
+
+static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct exynos_mbox *exynos_mbox = dev_get_drvdata(chan->mbox->dev);
+	int index;
+
+	index = exynos_mbox_chan_index(chan);
+	if (index < 0)
+		return index;
+
+	writel(BIT(index), exynos_mbox->regs + EXYNOS_MBOX_INTGR1);
+
+	return 0;
+}
+
+static const struct mbox_chan_ops exynos_mbox_chan_ops = {
+	.send_data = exynos_mbox_send_data,
+};
+
+static struct mbox_chan *exynos_mbox_of_xlate(struct mbox_controller *mbox,
+					      const struct of_phandle_args *sp)
+{
+	u32 type, id;
+
+	if (sp->args_count != EXYNOS_MBOX_CELLS) {
+		dev_err(mbox->dev, "Invalid argument count %d\n",
+			sp->args_count);
+		return ERR_PTR(-EINVAL);
+	}
+
+	type = sp->args[EXYNOS_MBOX_CELL_TYPE];
+	if (type >= EXYNOS_MBOX_CELL_TYPE_COUNT) {
+		dev_err(mbox->dev, "Invalid channel type %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (type == DATA) {
+		dev_err(mbox->dev, "DATA channel type [%d] not supported\n",
+			type);
+		return ERR_PTR(-EINVAL);
+	};
+
+	id = sp->args[EXYNOS_MBOX_CELL_ID];
+	if (id >= mbox->num_chans) {
+		dev_err(mbox->dev, "Invalid channel ID %d\n", id);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return &mbox->chans[id];
+}
+
+static const struct of_device_id exynos_mbox_match[] = {
+	{ .compatible = "google,gs101-mbox" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos_mbox_match);
+
+static int exynos_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct exynos_mbox *exynos_mbox;
+	struct mbox_controller *mbox;
+	struct mbox_chan *chans;
+	int i;
+
+	exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL);
+	if (!exynos_mbox)
+		return -ENOMEM;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	chans = devm_kcalloc(dev, EXYNOS_MBOX_CHAN_COUNT, sizeof(*chans),
+			     GFP_KERNEL);
+	if (!chans)
+		return -ENOMEM;
+
+	exynos_mbox->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(exynos_mbox->regs))
+		return PTR_ERR(exynos_mbox->regs);
+
+	exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk");
+	if (IS_ERR(exynos_mbox->pclk))
+		return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk),
+				     "Failed to enable clock.\n");
+
+	mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT;
+	mbox->chans = chans;
+	mbox->dev = dev;
+	mbox->ops = &exynos_mbox_chan_ops;
+	mbox->of_xlate = exynos_mbox_of_xlate;
+
+	for (i = 0; i < EXYNOS_MBOX_CHAN_COUNT; i++)
+		chans[i].mbox = mbox;
+
+	exynos_mbox->dev = dev;
+	exynos_mbox->mbox = mbox;
+
+	platform_set_drvdata(pdev, exynos_mbox);
+
+	/* Mask out all interrupts. We support just polling channels for now. */
+	writel(EXYNOS_MBOX_INTMR0_MASK, exynos_mbox->regs + EXYNOS_MBOX_INTMR0);
+
+	return devm_mbox_controller_register(dev, mbox);
+}
+
+static struct platform_driver exynos_mbox_driver = {
+	.probe	= exynos_mbox_probe,
+	.driver	= {
+		.name = "exynos-acpm-mbox",
+		.of_match_table	= exynos_mbox_match,
+	},
+};
+module_platform_driver(exynos_mbox_driver);
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos mailbox driver");
+MODULE_LICENSE("GPL");

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Tue Dec 17 01:40:22 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue, 17 Dec 2024 09:40:22 +0000
Subject: [PATCH v5 3/3] MAINTAINERS: add entry for Samsung Exynos mailbox
 driver
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
Message-ID: <20241217-acpm-v4-upstream-mbox-v5-3-cd1d3951fe84@linaro.org>

Add entry for the Samsung Exynos mailbox driver.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index baf0eeb9a355..6bef5fc5e4ee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3023,6 +3023,7 @@ F:	drivers/*/*s3c24*
 F:	drivers/*/*s3c64xx*
 F:	drivers/*/*s5pv210*
 F:	drivers/clocksource/samsung_pwm_timer.c
+F:	drivers/mailbox/exynos-mailbox.c
 F:	drivers/memory/samsung/
 F:	drivers/pwm/pwm-samsung.c
 F:	drivers/soc/samsung/
@@ -20717,6 +20718,15 @@ F:	arch/arm64/boot/dts/exynos/exynos850*
 F:	drivers/clk/samsung/clk-exynos850.c
 F:	include/dt-bindings/clock/exynos850.h
 
+SAMSUNG EXYNOS MAILBOX DRIVER
+M:	Tudor Ambarus <tudor.ambarus at linaro.org>
+L:	linux-kernel at vger.kernel.org
+L:	linux-samsung-soc at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
+F:	drivers/mailbox/exynos-mailbox.c
+F:	include/dt-bindings/mailbox/google,gs101.h
+
 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 M:	Krzysztof Kozlowski <krzk at kernel.org>
 L:	linux-crypto at vger.kernel.org

-- 
2.47.1.613.gc27f4b7a9f-goog



From krzk at kernel.org  Tue Dec 17 01:43:05 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 10:43:05 +0100
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <17fbfcdd-8b79-4907-a4c8-798da0ef0526@gmail.com>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
 <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
 <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>
 <6e93d59d-71e5-4c09-862f-55b5504121aa@gmail.com>
 <69fd1dbc-a29f-488c-a30f-7e5ea8f01a23@kernel.org>
 <17fbfcdd-8b79-4907-a4c8-798da0ef0526@gmail.com>
Message-ID: <56c5788a-2d49-4abb-af4b-65a11bdc4094@kernel.org>

On 17/12/2024 10:31, Ivaylo Ivanov wrote:
> On 12/17/24 11:26, Krzysztof Kozlowski wrote:
>> On 17/12/2024 10:08, Ivaylo Ivanov wrote:
>>>>>>>        - items:
>>>>>>>            - enum:
>>>>>>> @@ -94,9 +95,28 @@ allOf:
>>>>>>>          - clock-names
>>>>>>>  
>>>>>>>      else:
>>>>>>> -      properties:
>>>>>>> -        clocks:
>>>>>>> -          maxItems: 1
>>>>>>> +      if:
>>>>>>> +        properties:
>>>>>>> +          compatible:
>>>>>>> +            contains:
>>>>>>> +              enum:
>>>>>>> +                - samsung,exynos8895-hsi2c
>>>>>>> +
>>>>>>> +      then:
>>>>>>> +        properties:
>>>>>>> +          clocks:
>>>>>> Missing minItems
>>>>>>
>>>>>>> +            maxItems: 2
>>>>>>> +
>>>>>>> +          clock-names:
>>>>>> Ditto
>>>>>>
>>>>>>> +            maxItems: 2
>>>>>>> +
>>>>>>> +        required:
>>>>>>> +          - clock-names
>>>>>> I don't understand why do you need second, same branch in if, basically
>>>>> Because, as I stated in the commit message, we have HSI2C controllers
>>>>> both implemented in USIv1 blocks and outside. These that are a part of
>>>> On Exynos8895? Where? With the same compatible?
>>> hsi2c_0 which has a clock from BUSC and hsi2c_1 to hsi2c_4 which use clocks
>>> from PERIC1 (CLK_GOUT_PERIC1_HSI2C_CAM{0,1,2,3}_IPCLK). Why would
>>> they need a different compatible though? It's functionally the same i2c design
>>> as the one implemented in USIv1 blocks.
>> If one block is part of USI and other not, they might not be the same
>> I2C blocks, even if interface is similar. If they were the same or even
>> functionally the same, they would have the same clock inputs. However
> 
> I see, so in such case I should make samsung,exynos8895-hsi2c-nonusi or
> something like that?
> 
>> user manual also suggests that there is only one clock, not two (for
>> both cases), so they could be functionally equivalent but then number of
>> clocks looks incorrect.
> 
> That'd be weird. Both according to downstream and upstream clk driver,
> for the USI-implemented i2cs we have a pclk and an sclk_usi.
Something is not precise here, as usually with Samsung clock topology.

First, the non-USI instances have the IPCLK as well, e.g. things like
PERIC1_UID_HSI2C_CAM1_IPCLKPORT_iPCLK

USI have BLK_PERIC0_UID_USI03_IPCLKPORT_i_SCLK_USI, but that's USI
clock, not HSI2C in USI. Datasheet mentions this is UART and SPI special
clock, but not I2C. The PCLK is used for HSI2C iPCLK.


Best regards,
Krzysztof


From laurent.pinchart at ideasonboard.com  Tue Dec 17 01:45:08 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 17 Dec 2024 11:45:08 +0200
Subject: [PATCH v12 2/8] dt-bindings: media: platform: visconti: Add
 Toshiba Visconti Video Input Interface
In-Reply-To: <d5294015-4790-490e-8136-615039a5c733@kernel.org>
References: <20241125092146.1561901-1-yuji2.ishikawa@toshiba.co.jp>
 <20241125092146.1561901-3-yuji2.ishikawa@toshiba.co.jp>
 <04a7ebf7-2924-4894-bc53-ba77e2f64fae@kernel.org>
 <TY3PR01MB99822E6161ED319B4DE855B492042@TY3PR01MB9982.jpnprd01.prod.outlook.com>
 <d5294015-4790-490e-8136-615039a5c733@kernel.org>
Message-ID: <20241217094508.GD11445@pendragon.ideasonboard.com>

On Tue, Dec 17, 2024 at 06:43:22AM +0100, Krzysztof Kozlowski wrote:
> On 17/12/2024 01:00, yuji2.ishikawa at toshiba.co.jp wrote:
> > Hello Krzysztof
> > 
> > Thank you for your review
> > 
> >> -----Original Message-----
> >> From: Krzysztof Kozlowski <krzk at kernel.org>
> >> Sent: Monday, November 25, 2024 7:08 PM
> >> To: ishikawa yuji(?? ?? ?????????????)
> >> <yuji2.ishikawa at toshiba.co.jp>; Laurent Pinchart
> >> <laurent.pinchart at ideasonboard.com>; Mauro Carvalho Chehab
> >> <mchehab at kernel.org>; Rob Herring <robh at kernel.org>; Krzysztof Kozlowski
> >> <krzk+dt at kernel.org>; Conor Dooley <conor+dt at kernel.org>; Sakari Ailus
> >> <sakari.ailus at linux.intel.com>; Hans Verkuil <hverkuil-cisco at xs4all.nl>;
> >> iwamatsu nobuhiro(?? ?? ?????????????)
> >> <nobuhiro1.iwamatsu at toshiba.co.jp>
> >> Cc: linux-media at vger.kernel.org; linux-kernel at vger.kernel.org;
> >> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org
> >> Subject: Re: [PATCH v12 2/8] dt-bindings: media: platform: visconti: Add
> >> Toshiba Visconti Video Input Interface
> >>
> >> On 25/11/2024 10:21, Yuji Ishikawa wrote:
> >>> Adds the Device Tree binding documentation that allows to describe the
> >>> Video Input Interface found in Toshiba Visconti SoCs.
> >>>
> >>> Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
> >>> Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> >>
> >> Why this tag stayed and other was removed? What was the reason of tag
> >> removal?
> >>
> > 
> > The stayed tag is due to internal review.
> 
> Did the internal review really happened? How is it that immediately new
> version has internal review without any traces?
> 
> I have doubts this review happened in the context of reviewer's
> statement of oversight.
> 
> > The removed tag is due to code's change (split of csi2rx part) after the last review.
> > If the code is largely changed following the instruction of another reviewer
> > after obtaining the tags, how should the tags be handled?
> 
> Drop all reviews and perform reviews on the list.
> 
> Such internal review appearing afterwards is rather a proof it you are
> adding just the tags to satisfy your process. I have no way to even
> verify whether that person performed any reasonable review or maybe just
> acked your patch.

How do you verify that for public reviews ?

> I cannot even verify that that person understands the
> reviewer's statement of oversight.
> 
> 
> ...
> 
> >>>
> >>> Changelog v11:
> >>> - no change
> >>>
> >>> Changelog v12:
> >>> - remove property "clock-noncontinuous" as VIIF switches both modes
> >>> automatically
> >>> - remove property "link-frequencies" as VIIF does not use the
> >>> information
> >>
> >> Driver does not use or hardware supports only one frequency?
> > 
> > My comment was incorrect.
> > It should be "Driver does not use the information"
> 
> Then this is not that helping. Maybe hardware supports only one frequency?

-- 
Regards,

Laurent Pinchart


From ping.bai at nxp.com  Tue Dec 17 01:47:17 2024
From: ping.bai at nxp.com (Jacky Bai)
Date: Tue, 17 Dec 2024 09:47:17 +0000
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <fa130432-bbfe-4d8f-913c-e86488efe203@kernel.org>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
 <bx3r4cs3oklfduvkg65vke3clb3fc6sseske2ellq27ifpmsnm@msz6iqvjwufn>
 <AS8PR04MB8642D11477A37E75BAB71F3087042@AS8PR04MB8642.eurprd04.prod.outlook.com>
 <fa130432-bbfe-4d8f-913c-e86488efe203@kernel.org>
Message-ID: <AS8PR04MB8642F7BF3F5B8E2455EEB0BB87042@AS8PR04MB8642.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
> 
> On 17/12/2024 09:55, Jacky Bai wrote:
> >>
> >>> +			device_type = "cpu";
> >
> > ...
> >
> >>> +			edma2: dma-controller at 42000000 {
> >>> +				compatible = "fsl,imx95-edma5";
> >>
> >> imx943 or imx95?
> >>
> >
> > Compatible with imx95, so I did not add new redundant dt binding entry.
> The entry is not redundant, because allows handling quirks or missing features
> (see writing bindings).
> 

Thx for your time. For the edma node, I can understand we may need to add
imx943 specific compatible string, then fullback compatible imx95 string.
I do have one concern about other node like lpuart, i2c etc, Is it still necessary
to add new compatible string for new soc? Currently I reuse the compatibles
as imx95. I know previously we were asked to add new compatible string for
peripheral nodes when a new SoC is introduced, do we still need follow that
suggestion or some tradeoff?

lpuart1: serial at 44380000 {
	compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
			   "fsl,imx7ulp-lpuart";
	reg = <0x44380000 0x1000>;

BR

> Best regards,
> Krzysztof

From syzbot+62e8b837d5ec5953c8e2 at syzkaller.appspotmail.com  Tue Dec 17 01:48:24 2024
From: syzbot+62e8b837d5ec5953c8e2 at syzkaller.appspotmail.com (syzbot)
Date: Tue, 17 Dec 2024 01:48:24 -0800
Subject: [syzbot] [kvmarm?] BUG: unable to handle kernel paging request in vgic_its_set_attr
Message-ID: <676148e8.050a0220.37aaf.0158.GAE@google.com>

Hello,

syzbot found the following issue on:

HEAD commit:    5db899a34f75 Merge remote-tracking branch 'kernel/kvmarm/n..
git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git fuzzme
console output: https://syzkaller.appspot.com/x/log.txt?x=148b6a0f980000
kernel config:  https://syzkaller.appspot.com/x/.config?x=fde68ab6d6c8c8ab
dashboard link: https://syzkaller.appspot.com/bug?extid=62e8b837d5ec5953c8e2
compiler:       Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
userspace arch: arm64

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/384ffdcca292/non_bootable_disk-5db899a3.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/4938b757ff4a/vmlinux-5db899a3.xz
kernel image: https://storage.googleapis.com/syzbot-assets/936938b47987/Image-5db899a3.gz.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+62e8b837d5ec5953c8e2 at syzkaller.appspotmail.com

Unable to handle kernel paging request at virtual address efff800000000001
KASAN: null-ptr-deref in range [0x0000000000000010-0x000000000000001f]
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
swapper pgtable: 4k pages, 52-bit VAs, pgdp=0000000044a53000
[efff800000000001] pgd=1000000049992003, p4d=1000000049993003, pud=0000000000000000
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 UID: 0 PID: 5975 Comm: syz.1.647 Not tainted 6.12.0-rc7-syzkaller-g5db899a34f75 #0
Hardware name: linux,dummy-virt (DT)
pstate: 60402009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : __hwasan_check_x0_67043362+0x4/0x30
lr : vgic_its_save_ite arch/arm64/kvm/vgic/vgic-its.c:2101 [inline]
lr : vgic_its_save_itt arch/arm64/kvm/vgic/vgic-its.c:2204 [inline]
lr : vgic_its_save_device_tables arch/arm64/kvm/vgic/vgic-its.c:2353 [inline]
lr : vgic_its_save_tables_v0+0x258/0x634 arch/arm64/kvm/vgic/vgic-its.c:2573
sp : ffff80008bd17be0
x29: ffff80008bd17c30 x28: 6cf0000019180180 x27: 5bf000001952a880
x26: 0000000000000008 x25: 0000000000000000 x24: 0000000000000000
x23: 07f000001952a8c0 x22: 07f000001952a8d0 x21: 00000000c0030000
x20: 07f000001952a8d0 x19: efff800000000000 x18: 00000000000000e8
x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000000
x14: 000000000002061b x13: 0000000000000000 x12: 0000000001fbb6cb
x11: 0000000000000000 x10: 0000000000002000 x9 : efff800000000000
x8 : 0000000020000000 x7 : ffff8000800fc528 x6 : 0000000000000000
x5 : 0000000000000000 x4 : 8df00000195be2f0 x3 : 0000000000000008
x2 : ffff8000800fc5a4 x1 : 0000000000000000 x0 : 0000000000000010
Call trace:
 __hwasan_check_x0_67043362+0x4/0x30
 vgic_its_set_attr+0x394/0x508 arch/arm64/kvm/vgic/vgic-its.c:2736
 kvm_device_ioctl_attr+0x150/0x18c virt/kvm/kvm_main.c:4721
 kvm_device_ioctl+0x154/0x1b0
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:907 [inline]
 __se_sys_ioctl fs/ioctl.c:893 [inline]
 __arm64_sys_ioctl+0x108/0x184 fs/ioctl.c:893
 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
 invoke_syscall+0x78/0x1b8 arch/arm64/kernel/syscall.c:49
 el0_svc_common+0xe8/0x1b0 arch/arm64/kernel/syscall.c:132
 do_el0_svc+0x40/0x50 arch/arm64/kernel/syscall.c:151
 el0_svc+0x54/0x14c arch/arm64/kernel/entry-common.c:712
 el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730
 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
Code: a90efbfd d2800401 143a3edf 9344dc10 (38706930) 
---[ end trace 0000000000000000 ]---
----------------
Code disassembly (best guess):
   0:	a90efbfd 	stp	x29, x30, [sp, #232]
   4:	d2800401 	mov	x1, #0x20                  	// #32
   8:	143a3edf 	b	0xe8fb84
   c:	9344dc10 	sbfx	x16, x0, #4, #52
* 10:	38706930 	ldrb	w16, [x9, x16] <-- trapping instruction


---
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 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 christian.bruel at foss.st.com  Tue Dec 17 01:48:43 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 17 Dec 2024 10:48:43 +0100
Subject: [PATCH v2 4/5] PCI: stm32: Add PCIe endpoint support for
 STM32MP25
In-Reply-To: <20241216161700.dtldi7fari6kafrr@thinkpad>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-5-christian.bruel@foss.st.com>
 <20241203152230.5mdrt27u5u5ecwcz@thinkpad>
 <4e257489-4d90-4e47-a4d9-a2444627c356@foss.st.com>
 <20241216161700.dtldi7fari6kafrr@thinkpad>
Message-ID: <fdc487c4-cbdc-45ac-a79f-aff2b8ccafcc@foss.st.com>



On 12/16/24 17:17, Manivannan Sadhasivam wrote:
> On Mon, Dec 16, 2024 at 11:02:07AM +0100, Christian Bruel wrote:
>> Hi Manivanna,
>>
>> On 12/3/24 16:22, Manivannan Sadhasivam wrote:
>>> On Tue, Nov 26, 2024 at 04:51:18PM +0100, Christian Bruel wrote:
>>>
>>> [...]
>>>
>>>> +static int stm32_pcie_start_link(struct dw_pcie *pci)
>>>> +{
>>>> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
>>>> +	int ret;
>>>> +
>>>> +	if (stm32_pcie->link_status == STM32_PCIE_EP_LINK_ENABLED) {
>>>> +		dev_dbg(pci->dev, "Link is already enabled\n");
>>>> +		return 0;
>>>> +	}
>>>> +
>>>> +	ret = stm32_pcie_enable_link(pci);
>>>> +	if (ret) {
>>>> +		dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>
>>> How the REFCLK is supplied to the endpoint? From host or generated locally?
>>
>>  From Host only, we don't support the separated clock model.
>>
> 
> OK. So even without refclk you are still able to access the controller
> registers? So the controller CSRs should be accessible by separate local clock I
> believe.
> 
> Anyhow, please add this limitation (refclk dependency from host) in commit
> message.
> 
> [...]
> 
>>>> +	ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE);
>>>
>>> Hmm, so PHY mode is common for both endpoint and host?
>>
>> Yes it is. We need to init the phy here because it is a clock source for the
>> PCIe core clk
>>
> 
> Clock source? Is it coming directly to PCIe or through RCC? There is no direct
> clock representation from PHY to PCIe in DT binding.

The core_clk is generated directly by the PLL in the COMBOPHY, gated by 
the RCC

> 
> - Mani
> 


From james.clark at linaro.org  Tue Dec 17 01:58:07 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 17 Dec 2024 09:58:07 +0000
Subject: [PATCH v2] perf vendor events arm64: Add FUJITSU-MONAKA pmu event
In-Reply-To: <OS3PR01MB6903A0317D8BB90A9B4DD7E8D4042@OS3PR01MB6903.jpnprd01.prod.outlook.com>
References: <20241111064843.3003093-1-fj5100bi@fujitsu.com>
 <ee89c235-a126-4874-994d-b2489eb1c00f@linaro.org>
 <OS3PR01MB690303F6D0FAF71ADDE7AA4BD43D2@OS3PR01MB6903.jpnprd01.prod.outlook.com>
 <OS3PR01MB6903A0317D8BB90A9B4DD7E8D4042@OS3PR01MB6903.jpnprd01.prod.outlook.com>
Message-ID: <cb11fe5e-e6ab-4653-b925-4c3cb5273b43@linaro.org>



On 17/12/2024 6:35 am, Yoshihiro Furudera (Fujitsu) wrote:
> Hi, James
> 
>>> Also in the common files, we're using the description strings from the
>>> Arm ARM. I noticed that the ones from your spec are slightly different.
>>> This is ok for now, but if we add any new Arm cores that use the same
>>> events this description may get overwritten. For example
>>> ASE_SVE_INST_SPEC in the Arm ARM is currently "Operation speculatively
>> executed, Advanced SIMD or SVE".
>>>
>>> If you have any actual relevant details that are different from the
>>> common string, you should put them in .../arch/arm64/fujitsu/monaka.
>>> But if you are ok with the potential overwrite (which looks like it
>>> should be ok) then you can leave them as is.
>>
>> I think it's okay to overwrite it, but I'll check the specs.
> 
> Regarding this matter, the descriptions of the events added to the common files
> (common-and-microarch.json, recommended.json) will be modified to match Arm ARM.
> Then, we will write current descriptions as "BriefDescription" in .../arch/arm64/fujitsu/monaka.
> We will post this as a v3 patch later.
> 
>>
>>>
>>> [...]
>>>
>>>> diff --git
>>>> a/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
>>>> b/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
>>>> new file mode 100644
>>>> index 000000000000..80bf17fb8f4c
>>>> --- /dev/null
>>>> +++ b/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/general.json
>>>> @@ -0,0 +1,8 @@
>>>> +[
>>>> +    {
>>>> +        "ArchStdEvent": "CPU_CYCLES"
>>>> +    },
>>>
>>> Other cores put CPU_CYCLES in bus.json. For user friendlyness I would
>>> put the common ones into the same existing groups. The same issue
>>> applies for some other common events.
>>>
>>
>> I will update as suggested.
> 
> MONAKA's event grouping is based on the grouping of "neoverse n1/n2".
> We found that the groups in "neoverse n1/n2" may differ from those in other cores.
> For example, "CPU_CYCLES" is classified in general.json in "neoverse n1/n2",
> but in bus.json in many other cores.
> 
> As a result, it is not possible to completely match the event groups of other cores.
> We will be checking the current grouping of events and modifying them as much as possible
> to match the other core, and will post this later as a v3 patch.
> 
> Best Regards,
> Yoshihiro Furudera

Hmmm ok, I didn't realize it was already inconsistent. Still it's better 
to try to not introduce a third variant though.



From ivo.ivanov.ivanov1 at gmail.com  Tue Dec 17 02:04:08 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Tue, 17 Dec 2024 12:04:08 +0200
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <56c5788a-2d49-4abb-af4b-65a11bdc4094@kernel.org>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
 <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
 <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>
 <6e93d59d-71e5-4c09-862f-55b5504121aa@gmail.com>
 <69fd1dbc-a29f-488c-a30f-7e5ea8f01a23@kernel.org>
 <17fbfcdd-8b79-4907-a4c8-798da0ef0526@gmail.com>
 <56c5788a-2d49-4abb-af4b-65a11bdc4094@kernel.org>
Message-ID: <d8d0a1c8-f2b4-425a-858b-610ae7291ebc@gmail.com>

On 12/17/24 11:43, Krzysztof Kozlowski wrote:
> On 17/12/2024 10:31, Ivaylo Ivanov wrote:
>> On 12/17/24 11:26, Krzysztof Kozlowski wrote:
>>> On 17/12/2024 10:08, Ivaylo Ivanov wrote:
>>>>>>>>        - items:
>>>>>>>>            - enum:
>>>>>>>> @@ -94,9 +95,28 @@ allOf:
>>>>>>>>          - clock-names
>>>>>>>>  
>>>>>>>>      else:
>>>>>>>> -      properties:
>>>>>>>> -        clocks:
>>>>>>>> -          maxItems: 1
>>>>>>>> +      if:
>>>>>>>> +        properties:
>>>>>>>> +          compatible:
>>>>>>>> +            contains:
>>>>>>>> +              enum:
>>>>>>>> +                - samsung,exynos8895-hsi2c
>>>>>>>> +
>>>>>>>> +      then:
>>>>>>>> +        properties:
>>>>>>>> +          clocks:
>>>>>>> Missing minItems
>>>>>>>
>>>>>>>> +            maxItems: 2
>>>>>>>> +
>>>>>>>> +          clock-names:
>>>>>>> Ditto
>>>>>>>
>>>>>>>> +            maxItems: 2
>>>>>>>> +
>>>>>>>> +        required:
>>>>>>>> +          - clock-names
>>>>>>> I don't understand why do you need second, same branch in if, basically
>>>>>> Because, as I stated in the commit message, we have HSI2C controllers
>>>>>> both implemented in USIv1 blocks and outside. These that are a part of
>>>>> On Exynos8895? Where? With the same compatible?
>>>> hsi2c_0 which has a clock from BUSC and hsi2c_1 to hsi2c_4 which use clocks
>>>> from PERIC1 (CLK_GOUT_PERIC1_HSI2C_CAM{0,1,2,3}_IPCLK). Why would
>>>> they need a different compatible though? It's functionally the same i2c design
>>>> as the one implemented in USIv1 blocks.
>>> If one block is part of USI and other not, they might not be the same
>>> I2C blocks, even if interface is similar. If they were the same or even
>>> functionally the same, they would have the same clock inputs. However
>> I see, so in such case I should make samsung,exynos8895-hsi2c-nonusi or
>> something like that?
>>
>>> user manual also suggests that there is only one clock, not two (for
>>> both cases), so they could be functionally equivalent but then number of
>>> clocks looks incorrect.
>> That'd be weird. Both according to downstream and upstream clk driver,
>> for the USI-implemented i2cs we have a pclk and an sclk_usi.
> Something is not precise here, as usually with Samsung clock topology.
>
> First, the non-USI instances have the IPCLK as well, e.g. things like
> PERIC1_UID_HSI2C_CAM1_IPCLKPORT_iPCLK
>
> USI have BLK_PERIC0_UID_USI03_IPCLKPORT_i_SCLK_USI, but that's USI
> clock, not HSI2C in USI. Datasheet mentions this is UART and SPI special
> clock, but not I2C.

That's weird. Don't we need the clock enabled in order for the
USIv1's HSI2C to work?

Best regards,
Ivo

>  The PCLK is used for HSI2C iPCLK.
>
>
> Best regards,
> Krzysztof



From jens.wiklander at linaro.org  Tue Dec 17 02:07:36 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 17 Dec 2024 11:07:36 +0100
Subject: [PATCH v4 0/6] TEE subsystem for restricted dma-buf allocations
Message-ID: <20241217100809.3962439-1-jens.wiklander@linaro.org>

Hi,

This patch set allocates the restricted DMA-bufs via the TEE subsystem.

The TEE subsystem handles the DMA-buf allocations since it is the TEE
(OP-TEE, AMD-TEE, TS-TEE, or perhaps a future QCOMTEE) which sets up the
restrictions for the memory used for the DMA-bufs.

I've added a new IOCTL, TEE_IOC_RSTMEM_ALLOC, to allocate the restricted
DMA-bufs. This IOCTL reaches the backend TEE driver, allowing it to choose
how to allocate the restricted physical memory.

TEE_IOC_RSTMEM_ALLOC takes in addition to a size and flags parameters also
a use-case parameter. This is used by the backend TEE driver to decide on
allocation policy and which devices should be able to access the memory.

Three use-cases (Secure Video Playback, Trusted UI, and Secure Video
Recording) has been identified so far to serve as examples of what can be
expected. More use-cases can be added in userspace ABI, but it's up to the
backend TEE drivers to provide the implementation.

Each use-case has it's own restricted memory pool since different use-cases
requires isolation from different parts of the system. A restricted memory
pool can be based on a static carveout instantiated while probing the TEE
backend driver, or dynamically allocated from CMA and made restricted as
needed by the TEE.

This can be tested on QEMU with the following steps:
repo init -u https://github.com/jenswi-linaro/manifest.git -m qemu_v8.xml \
        -b prototype/sdp-v4
repo sync -j8
cd build
make toolchains -j$(nproc)
make SPMC_AT_EL=1 all -j$(nproc)
make SPMC_AT_EL=1 run-only
# login and at the prompt:
xtest --sdp-basic

The SPMC_AT_EL=1 parameter configures the build with FF-A and an SPMC at
S-EL1 inside OP-TEE. The parameter can be changed into SPMC_AT_EL=n to test
without FF-A using the original SMC ABI instead. Please remember to do
%rm -rf ../trusted-firmware-a/build/qemu
for TF-A to be rebuilt properly using the new configuration.

https://optee.readthedocs.io/en/latest/building/prerequisites.html
list dependencies needed to build the above.

The tests are pretty basic, mostly checking that a Trusted Application in
the secure world can access and manipulate the memory. There are also some
negative tests for out of bounds buffers etc.

Thanks,
Jens

Changes since V3:
* Make the use_case and flags field in struct tee_shm u32's instead of
  u16's
* Add more description for TEE_IOC_RSTMEM_ALLOC in the header file
* Import namespace DMA_BUF in module tee, reported by lkp at intel.com
* Added a note in the commit message for "optee: account for direction
  while converting parameters" why it's needed
* Factor out dynamic restricted memory allocation from
  "optee: support restricted memory allocation" into two new commits
  "optee: FF-A: dynamic restricted memory allocation" and
  "optee: smc abi: dynamic restricted memory allocation"
* Guard CMA usage with #ifdef CONFIG_CMA, effectively disabling dynamic
  restricted memory allocate if CMA isn't configured

Changes since the V2 RFC:
* Based on v6.12
* Replaced the flags for SVP and Trusted UID memory with a u32 field with
  unique id for each use case
* Added dynamic allocation of restricted memory pools
* Added OP-TEE ABI both with and without FF-A for dynamic restricted memory
* Added support for FF-A with FFA_LEND

Changes since the V1 RFC:
* Based on v6.11
* Complete rewrite, replacing the restricted heap with TEE_IOC_RSTMEM_ALLOC

Changes since Olivier's post [2]:
* Based on Yong Wu's post [1] where much of dma-buf handling is done in
  the generic restricted heap
* Simplifications and cleanup
* New commit message for "dma-buf: heaps: add Linaro restricted dmabuf heap
  support"
* Replaced the word "secure" with "restricted" where applicable

Jens Wiklander (6):
  tee: add restricted memory allocation
  optee: account for direction while converting parameters
  optee: sync secure world ABI headers
  optee: support restricted memory allocation
  optee: FF-A: dynamic restricted memory allocation
  optee: smc abi: dynamic restricted memory allocation

 drivers/tee/Makefile              |   1 +
 drivers/tee/optee/Makefile        |   1 +
 drivers/tee/optee/call.c          |  10 +-
 drivers/tee/optee/core.c          |   1 +
 drivers/tee/optee/ffa_abi.c       | 178 +++++++++++++-
 drivers/tee/optee/optee_ffa.h     |  27 ++-
 drivers/tee/optee/optee_msg.h     |  65 ++++-
 drivers/tee/optee/optee_private.h |  75 ++++--
 drivers/tee/optee/optee_smc.h     |  71 +++++-
 drivers/tee/optee/rpc.c           |  31 ++-
 drivers/tee/optee/rstmem.c        | 388 ++++++++++++++++++++++++++++++
 drivers/tee/optee/smc_abi.c       | 213 ++++++++++++++--
 drivers/tee/tee_core.c            |  38 ++-
 drivers/tee/tee_private.h         |   2 +
 drivers/tee/tee_rstmem.c          | 201 ++++++++++++++++
 drivers/tee/tee_shm.c             |   2 +
 drivers/tee/tee_shm_pool.c        |  69 +++++-
 include/linux/tee_core.h          |  15 ++
 include/linux/tee_drv.h           |   2 +
 include/uapi/linux/tee.h          |  44 +++-
 20 files changed, 1358 insertions(+), 76 deletions(-)
 create mode 100644 drivers/tee/optee/rstmem.c
 create mode 100644 drivers/tee/tee_rstmem.c


base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
-- 
2.43.0



From jens.wiklander at linaro.org  Tue Dec 17 02:07:37 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 17 Dec 2024 11:07:37 +0100
Subject: [PATCH v4 1/6] tee: add restricted memory allocation
In-Reply-To: <20241217100809.3962439-1-jens.wiklander@linaro.org>
References: <20241217100809.3962439-1-jens.wiklander@linaro.org>
Message-ID: <20241217100809.3962439-2-jens.wiklander@linaro.org>

Add restricted memory allocation to the TEE subsystem.

Restricted memory refers to memory buffers behind a hardware enforced
firewall. It is not accessible to the kernel during normal circumstances
but rather only accessible to certain hardware IPs or CPUs executing in
higher privileged mode than the kernel itself. This interface allows to
allocate and manage such restricted memory buffers via interaction with
a TEE implementation.

A new ioctl TEE_IOC_RSTMEM_ALLOC is added to allocate these restricted
memory buffers.

The restricted memory is allocated for a specific use-case, like Secure
Video Playback, Trusted UI, or Secure Video Recording where certain
hardware devices can access the memory.

More use-cases can be added in userspace ABI, but it's up to the backend
drivers to provide the implementation.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/Makefile       |   1 +
 drivers/tee/tee_core.c     |  38 ++++++-
 drivers/tee/tee_private.h  |   2 +
 drivers/tee/tee_rstmem.c   | 201 +++++++++++++++++++++++++++++++++++++
 drivers/tee/tee_shm.c      |   2 +
 drivers/tee/tee_shm_pool.c |  69 ++++++++++++-
 include/linux/tee_core.h   |  15 +++
 include/linux/tee_drv.h    |   2 +
 include/uapi/linux/tee.h   |  44 +++++++-
 9 files changed, 370 insertions(+), 4 deletions(-)
 create mode 100644 drivers/tee/tee_rstmem.c

diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
index 5488cba30bd2..a4c6b55444b9 100644
--- a/drivers/tee/Makefile
+++ b/drivers/tee/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_TEE) += tee.o
 tee-objs += tee_core.o
 tee-objs += tee_shm.o
 tee-objs += tee_shm_pool.o
+tee-objs += tee_rstmem.o
 obj-$(CONFIG_OPTEE) += optee/
 obj-$(CONFIG_AMDTEE) += amdtee/
 obj-$(CONFIG_ARM_TSTEE) += tstee/
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index d113679b1e2d..f4a45b77753b 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -1,12 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2016, Linaro Limited
+ * Copyright (c) 2015-2022, 2024, Linaro Limited
  */
 
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 #include <linux/cdev.h>
 #include <linux/cred.h>
+#include <linux/dma-buf.h>
 #include <linux/fs.h>
 #include <linux/idr.h>
 #include <linux/module.h>
@@ -815,6 +816,38 @@ static int tee_ioctl_supp_send(struct tee_context *ctx,
 	return rc;
 }
 
+static int
+tee_ioctl_rstmem_alloc(struct tee_context *ctx,
+		       struct tee_ioctl_rstmem_alloc_data __user *udata)
+{
+	struct tee_ioctl_rstmem_alloc_data data;
+	struct dma_buf *dmabuf;
+	int id;
+	int fd;
+
+	if (copy_from_user(&data, udata, sizeof(data)))
+		return -EFAULT;
+
+	if (data.use_case == TEE_IOC_UC_RESERVED)
+		return -EINVAL;
+
+	dmabuf = tee_rstmem_alloc(ctx, data.flags, data.use_case, data.size,
+				  &id);
+	if (IS_ERR(dmabuf))
+		return PTR_ERR(dmabuf);
+	if (put_user(id, &udata->id)) {
+		fd = -EFAULT;
+		goto err;
+	}
+	fd = dma_buf_fd(dmabuf, O_CLOEXEC);
+	if (fd < 0)
+		goto err;
+	return fd;
+err:
+	dma_buf_put(dmabuf);
+	return fd;
+}
+
 static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	struct tee_context *ctx = filp->private_data;
@@ -839,6 +872,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 		return tee_ioctl_supp_recv(ctx, uarg);
 	case TEE_IOC_SUPPL_SEND:
 		return tee_ioctl_supp_send(ctx, uarg);
+	case TEE_IOC_RSTMEM_ALLOC:
+		return tee_ioctl_rstmem_alloc(ctx, uarg);
 	default:
 		return -EINVAL;
 	}
@@ -1286,3 +1321,4 @@ MODULE_AUTHOR("Linaro");
 MODULE_DESCRIPTION("TEE Driver");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("DMA_BUF");
diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h
index 9bc50605227c..bf97796909c0 100644
--- a/drivers/tee/tee_private.h
+++ b/drivers/tee/tee_private.h
@@ -23,5 +23,7 @@ void teedev_ctx_put(struct tee_context *ctx);
 struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size);
 struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx,
 					  unsigned long addr, size_t length);
+struct dma_buf *tee_rstmem_alloc(struct tee_context *ctx, u32 flags,
+				 u32 use_case, size_t size, int *shm_id);
 
 #endif /*TEE_PRIVATE_H*/
diff --git a/drivers/tee/tee_rstmem.c b/drivers/tee/tee_rstmem.c
new file mode 100644
index 000000000000..536bca2901e2
--- /dev/null
+++ b/drivers/tee/tee_rstmem.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Linaro Limited
+ */
+#include <linux/device.h>
+#include <linux/dma-buf.h>
+#include <linux/genalloc.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/tee_core.h>
+#include "tee_private.h"
+
+struct tee_rstmem_attachment {
+	struct sg_table table;
+	struct device *dev;
+};
+
+static int rstmem_dma_attach(struct dma_buf *dmabuf,
+			     struct dma_buf_attachment *attachment)
+{
+	struct tee_shm *shm = dmabuf->priv;
+	struct tee_rstmem_attachment *a;
+	int rc;
+
+	a = kzalloc(sizeof(*a), GFP_KERNEL);
+	if (!a)
+		return -ENOMEM;
+
+	if (shm->pages) {
+		rc = sg_alloc_table_from_pages(&a->table, shm->pages,
+					       shm->num_pages, 0,
+					       shm->num_pages * PAGE_SIZE,
+					       GFP_KERNEL);
+		if (rc)
+			goto err;
+	} else {
+		rc = sg_alloc_table(&a->table, 1, GFP_KERNEL);
+		if (rc)
+			goto err;
+		sg_set_page(a->table.sgl, phys_to_page(shm->paddr), shm->size,
+			    0);
+	}
+
+	a->dev = attachment->dev;
+	attachment->priv = a;
+
+	return 0;
+err:
+	kfree(a);
+	return rc;
+}
+
+static void rstmem_dma_detach(struct dma_buf *dmabuf,
+			      struct dma_buf_attachment *attachment)
+{
+	struct tee_rstmem_attachment *a = attachment->priv;
+
+	sg_free_table(&a->table);
+	kfree(a);
+}
+
+static struct sg_table *
+rstmem_dma_map_dma_buf(struct dma_buf_attachment *attachment,
+		       enum dma_data_direction direction)
+{
+	struct tee_rstmem_attachment *a = attachment->priv;
+	int ret;
+
+	ret = dma_map_sgtable(attachment->dev, &a->table, direction,
+			      DMA_ATTR_SKIP_CPU_SYNC);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &a->table;
+}
+
+static void rstmem_dma_unmap_dma_buf(struct dma_buf_attachment *attachment,
+				     struct sg_table *table,
+				     enum dma_data_direction direction)
+{
+	struct tee_rstmem_attachment *a = attachment->priv;
+
+	WARN_ON(&a->table != table);
+
+	dma_unmap_sgtable(attachment->dev, table, direction,
+			  DMA_ATTR_SKIP_CPU_SYNC);
+}
+
+static int rstmem_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
+					   enum dma_data_direction direction)
+{
+	return -EPERM;
+}
+
+static int rstmem_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
+					 enum dma_data_direction direction)
+{
+	return -EPERM;
+}
+
+static int rstmem_dma_buf_mmap(struct dma_buf *dmabuf,
+			       struct vm_area_struct *vma)
+{
+	return -EPERM;
+}
+
+static void rstmem_dma_buf_free(struct dma_buf *dmabuf)
+{
+	struct tee_shm *shm = dmabuf->priv;
+
+	tee_shm_put(shm);
+}
+
+static const struct dma_buf_ops rstmem_generic_buf_ops = {
+	.attach = rstmem_dma_attach,
+	.detach = rstmem_dma_detach,
+	.map_dma_buf = rstmem_dma_map_dma_buf,
+	.unmap_dma_buf = rstmem_dma_unmap_dma_buf,
+	.begin_cpu_access = rstmem_dma_buf_begin_cpu_access,
+	.end_cpu_access = rstmem_dma_buf_end_cpu_access,
+	.mmap = rstmem_dma_buf_mmap,
+	.release = rstmem_dma_buf_free,
+};
+
+struct dma_buf *tee_rstmem_alloc(struct tee_context *ctx, u32 flags,
+				 u32 use_case, size_t size, int *shm_id)
+{
+	struct tee_device *teedev = ctx->teedev;
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+	struct dma_buf *dmabuf;
+	struct tee_shm *shm;
+	void *ret;
+	int rc;
+
+	if (!tee_device_get(teedev))
+		return ERR_PTR(-EINVAL);
+
+	if (!teedev->desc->ops->rstmem_alloc ||
+	    !teedev->desc->ops->rstmem_free) {
+		dmabuf = ERR_PTR(-EINVAL);
+		goto err;
+	}
+
+	shm = kzalloc(sizeof(*shm), GFP_KERNEL);
+	if (!shm) {
+		dmabuf = ERR_PTR(-ENOMEM);
+		goto err;
+	}
+
+	refcount_set(&shm->refcount, 1);
+	shm->flags = TEE_SHM_RESTRICTED;
+	shm->use_case = use_case;
+	shm->ctx = ctx;
+
+	mutex_lock(&teedev->mutex);
+	shm->id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL);
+	mutex_unlock(&teedev->mutex);
+	if (shm->id < 0) {
+		dmabuf = ERR_PTR(shm->id);
+		goto err_kfree;
+	}
+
+	rc = teedev->desc->ops->rstmem_alloc(ctx, shm, flags, use_case, size);
+	if (rc) {
+		dmabuf = ERR_PTR(rc);
+		goto err_idr_remove;
+	}
+
+	mutex_lock(&teedev->mutex);
+	ret = idr_replace(&teedev->idr, shm, shm->id);
+	mutex_unlock(&teedev->mutex);
+	if (IS_ERR(ret)) {
+		dmabuf = ret;
+		goto err_rstmem_free;
+	}
+	teedev_ctx_get(ctx);
+
+	exp_info.ops = &rstmem_generic_buf_ops;
+	exp_info.size = shm->size;
+	exp_info.priv = shm;
+	dmabuf = dma_buf_export(&exp_info);
+	if (IS_ERR(dmabuf)) {
+		tee_shm_put(shm);
+		return dmabuf;
+	}
+
+	*shm_id = shm->id;
+	return dmabuf;
+
+err_rstmem_free:
+	teedev->desc->ops->rstmem_free(ctx, shm);
+err_idr_remove:
+	mutex_lock(&teedev->mutex);
+	idr_remove(&teedev->idr, shm->id);
+	mutex_unlock(&teedev->mutex);
+err_kfree:
+	kfree(shm);
+err:
+	tee_device_put(teedev);
+	return dmabuf;
+}
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
index daf6e5cfd59a..416f7f25d885 100644
--- a/drivers/tee/tee_shm.c
+++ b/drivers/tee/tee_shm.c
@@ -55,6 +55,8 @@ static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm)
 				"unregister shm %p failed: %d", shm, rc);
 
 		release_registered_pages(shm);
+	} else if (shm->flags & TEE_SHM_RESTRICTED) {
+		teedev->desc->ops->rstmem_free(shm->ctx, shm);
 	}
 
 	teedev_ctx_put(shm->ctx);
diff --git a/drivers/tee/tee_shm_pool.c b/drivers/tee/tee_shm_pool.c
index 80004b55628d..ee57ef157a77 100644
--- a/drivers/tee/tee_shm_pool.c
+++ b/drivers/tee/tee_shm_pool.c
@@ -1,9 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015, 2017, 2022 Linaro Limited
+ * Copyright (c) 2015, 2017, 2022, 2024 Linaro Limited
  */
 #include <linux/device.h>
-#include <linux/dma-buf.h>
 #include <linux/genalloc.h>
 #include <linux/slab.h>
 #include <linux/tee_core.h>
@@ -90,3 +89,69 @@ struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
 	return ERR_PTR(rc);
 }
 EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem);
+
+static int rstmem_pool_op_gen_alloc(struct tee_shm_pool *pool,
+				    struct tee_shm *shm, size_t size,
+				    size_t align)
+{
+	size_t sz = ALIGN(size, PAGE_SIZE);
+	phys_addr_t pa;
+
+	pa = gen_pool_alloc(pool->private_data, sz);
+	if (!pa)
+		return -ENOMEM;
+
+	shm->size = sz;
+	shm->paddr = pa;
+
+	return 0;
+}
+
+static void rstmem_pool_op_gen_free(struct tee_shm_pool *pool,
+				    struct tee_shm *shm)
+{
+	gen_pool_free(pool->private_data, shm->paddr, shm->size);
+	shm->paddr = 0;
+}
+
+static struct tee_shm_pool_ops rstmem_pool_ops_generic = {
+	.alloc = rstmem_pool_op_gen_alloc,
+	.free = rstmem_pool_op_gen_free,
+	.destroy_pool = pool_op_gen_destroy_pool,
+};
+
+struct tee_shm_pool *tee_rstmem_gen_pool_alloc(phys_addr_t paddr, size_t size)
+{
+	const size_t page_mask = PAGE_SIZE - 1;
+	struct tee_shm_pool *pool;
+	int rc;
+
+	/* Check it's page aligned */
+	if ((paddr | size) & page_mask)
+		return ERR_PTR(-EINVAL);
+
+	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
+
+	pool->private_data = gen_pool_create(PAGE_SHIFT, -1);
+	if (!pool->private_data) {
+		rc = -ENOMEM;
+		goto err_free;
+	}
+
+	rc = gen_pool_add(pool->private_data, paddr, size, -1);
+	if (rc)
+		goto err_free_pool;
+
+	pool->ops = &rstmem_pool_ops_generic;
+	return pool;
+
+err_free_pool:
+	gen_pool_destroy(pool->private_data);
+err_free:
+	kfree(pool);
+
+	return ERR_PTR(rc);
+}
+EXPORT_SYMBOL_GPL(tee_rstmem_gen_pool_alloc);
diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h
index a38494d6b5f4..608302f494fe 100644
--- a/include/linux/tee_core.h
+++ b/include/linux/tee_core.h
@@ -26,6 +26,7 @@
 #define TEE_SHM_USER_MAPPED	BIT(1)  /* Memory mapped in user space */
 #define TEE_SHM_POOL		BIT(2)  /* Memory allocated from pool */
 #define TEE_SHM_PRIV		BIT(3)  /* Memory private to TEE driver */
+#define TEE_SHM_RESTRICTED	BIT(4)  /* Restricted memory */
 
 #define TEE_DEVICE_FLAG_REGISTERED	0x1
 #define TEE_MAX_DEV_NAME_LEN		32
@@ -76,6 +77,8 @@ struct tee_device {
  * @supp_send:		called for supplicant to send a response
  * @shm_register:	register shared memory buffer in TEE
  * @shm_unregister:	unregister shared memory buffer in TEE
+ * @rstmem_alloc:	allocate restricted memory
+ * @rstmem_free:	free restricted memory
  */
 struct tee_driver_ops {
 	void (*get_version)(struct tee_device *teedev,
@@ -99,6 +102,9 @@ struct tee_driver_ops {
 			    struct page **pages, size_t num_pages,
 			    unsigned long start);
 	int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm);
+	int (*rstmem_alloc)(struct tee_context *ctx, struct tee_shm *shm,
+			    u32 flags, u32 use_case, size_t size);
+	void (*rstmem_free)(struct tee_context *ctx, struct tee_shm *shm);
 };
 
 /**
@@ -229,6 +235,15 @@ static inline void tee_shm_pool_free(struct tee_shm_pool *pool)
 	pool->ops->destroy_pool(pool);
 }
 
+/**
+ * tee_rstmem_gen_pool_alloc() - Create a restricted memory manager
+ * @paddr:	Physical address of start of pool
+ * @size:	Size in bytes of the pool
+ *
+ * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
+ */
+struct tee_shm_pool *tee_rstmem_gen_pool_alloc(phys_addr_t paddr, size_t size);
+
 /**
  * tee_get_drvdata() - Return driver_data pointer
  * @returns the driver_data pointer supplied to tee_register().
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index a54c203000ed..cba067715d14 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -55,6 +55,7 @@ struct tee_context {
  * @pages:	locked pages from userspace
  * @num_pages:	number of locked pages
  * @refcount:	reference counter
+ * @use_case:	defined by TEE_IOC_UC_* in tee.h
  * @flags:	defined by TEE_SHM_* in tee_core.h
  * @id:		unique id of a shared memory object on this device, shared
  *		with user space
@@ -71,6 +72,7 @@ struct tee_shm {
 	struct page **pages;
 	size_t num_pages;
 	refcount_t refcount;
+	u32 use_case;
 	u32 flags;
 	int id;
 	u64 sec_world_id;
diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
index d0430bee8292..88834448debb 100644
--- a/include/uapi/linux/tee.h
+++ b/include/uapi/linux/tee.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, Linaro Limited
+ * Copyright (c) 2015-2017, 2020, 2024, Linaro Limited
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,7 @@
 #define TEE_GEN_CAP_PRIVILEGED	(1 << 1)/* Privileged device (for supplicant) */
 #define TEE_GEN_CAP_REG_MEM	(1 << 2)/* Supports registering shared memory */
 #define TEE_GEN_CAP_MEMREF_NULL	(1 << 3)/* NULL MemRef support */
+#define TEE_GEN_CAP_RSTMEM	(1 << 4)/* Supports restricted memory */
 
 #define TEE_MEMREF_NULL		(__u64)(-1) /* NULL MemRef Buffer */
 
@@ -389,6 +390,47 @@ struct tee_ioctl_shm_register_data {
  */
 #define TEE_IOC_SHM_REGISTER   _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \
 				     struct tee_ioctl_shm_register_data)
+
+#define TEE_IOC_UC_RESERVED		0
+#define TEE_IOC_UC_SECURE_VIDEO_PLAY	1
+#define TEE_IOC_UC_TRUSTED_UI		2
+#define TEE_IOC_UC_SECURE_VIDEO_RECORD	3
+
+/**
+ * struct tee_ioctl_rstmem_alloc_data - Restricted memory allocate argument
+ * @size:	[in/out] Size of restricted memory to allocate
+ * @flags:	[in/out] Flags to/from allocate
+ * @use_case	[in] Restricted memory use case, TEE_IOC_UC_*
+ * @id:		[out] Identifier of the restricted memory
+ */
+struct tee_ioctl_rstmem_alloc_data {
+	__u64 size;
+	__u32 flags;
+	__u32 use_case;
+	__s32 id;
+};
+
+/**
+ * TEE_IOC_RSTMEM_ALLOC - allocate restricted memory
+ *
+ * Allocates restricted physically memory normally not accessible by the
+ * kernel.
+ *
+ * Restricted memory refers to memory buffers behind a hardware enforced
+ * firewall. It is not accessible to the kernel during normal circumstances
+ * but rather only accessible to certain hardware IPs or CPUs executing in
+ * higher privileged mode than the kernel itself. This interface allows to
+ * allocate and manage such restricted memory buffers via interaction with
+ * a TEE implementation.
+ *
+ * Returns a file descriptor on success or < 0 on failure
+ *
+ * The returned file descriptor is a dma-buf that can be attached and
+ * mapped for device with permission to access the physical memory.
+ */
+#define TEE_IOC_RSTMEM_ALLOC     _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 10, \
+				       struct tee_ioctl_rstmem_alloc_data)
+
 /*
  * Five syscalls are used when communicating with the TEE driver.
  * open(): opens the device associated with the driver
-- 
2.43.0



From othacehe at gnu.org  Tue Dec 17 00:49:42 2024
From: othacehe at gnu.org (Mathieu Othacehe)
Date: Tue, 17 Dec 2024 09:49:42 +0100
Subject: [PATCH] net: dwmac-imx: add imx93 clock input support in RMII mode
Message-ID: <20241217084942.4071-1-othacehe@gnu.org>

If the rmii_refclk_ext boolean is set, configure the ENET QOS TX_CLK pin
direction to input. Otherwise, it defaults to output.

That mirrors what is already happening for the imx8mp in the
imx8mp_set_intf_mode function.

Signed-off-by: Mathieu Othacehe <othacehe at gnu.org>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
index 43e0fbba4f77b..68b3fbdd46647 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
@@ -36,6 +36,8 @@
 #define MX93_GPR_ENET_QOS_INTF_SEL_RMII		(0x4 << 1)
 #define MX93_GPR_ENET_QOS_INTF_SEL_RGMII	(0x1 << 1)
 #define MX93_GPR_ENET_QOS_CLK_GEN_EN		(0x1 << 0)
+#define MX93_GPR_ENET_QOS_CLK_SEL_MASK		BIT_MASK(0)
+#define MX93_GPR_CLK_SEL_OFFSET			(4)
 
 #define DMA_BUS_MODE			0x00001000
 #define DMA_BUS_MODE_SFT_RESET		(0x1 << 0)
@@ -108,13 +110,22 @@ imx8dxl_set_intf_mode(struct plat_stmmacenet_data *plat_dat)
 static int imx93_set_intf_mode(struct plat_stmmacenet_data *plat_dat)
 {
 	struct imx_priv_data *dwmac = plat_dat->bsp_priv;
-	int val;
+	int val, ret;
 
 	switch (plat_dat->mac_interface) {
 	case PHY_INTERFACE_MODE_MII:
 		val = MX93_GPR_ENET_QOS_INTF_SEL_MII;
 		break;
 	case PHY_INTERFACE_MODE_RMII:
+		if (dwmac->rmii_refclk_ext) {
+			ret = regmap_update_bits(dwmac->intf_regmap,
+						 dwmac->intf_reg_off +
+						 MX93_GPR_CLK_SEL_OFFSET,
+						 MX93_GPR_ENET_QOS_CLK_SEL_MASK,
+						 0);
+			if (ret)
+				return ret;
+		}
 		val = MX93_GPR_ENET_QOS_INTF_SEL_RMII;
 		break;
 	case PHY_INTERFACE_MODE_RGMII:
-- 
2.46.0



From tabba at google.com  Tue Dec 17 00:51:27 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:51:27 +0000
Subject: [PATCH v3 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <20241216175803.2716565-11-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-11-qperret@google.com>
Message-ID: <CA+EHjTz6W8YDKmk2Ga84CEYk46fyVXDPizXWbGqqq2Jn8JV0uQ@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> In preparation for handling guest stage-2 mappings at EL2, introduce a
> new pKVM hypercall allowing to share pages with non-protected guests.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

(Apart from a nit below)

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad


> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/include/asm/kvm_host.h             |  3 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/memory.h      |  2 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 34 +++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 72 +++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/pkvm.c                |  7 ++
>  7 files changed, 120 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 89c0fac69551..449337f5b2a3 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -65,6 +65,7 @@ enum __kvm_host_smccc_func {
>         /* Hypercalls available after pKVM finalisation */
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index e18e9244d17a..1246f1d01dbf 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -771,6 +771,9 @@ struct kvm_vcpu_arch {
>         /* Cache some mmu pages needed inside spinlock regions */
>         struct kvm_mmu_memory_cache mmu_page_cache;
>
> +       /* Pages to top-up the pKVM/EL2 guest pool */
> +       struct kvm_hyp_memcache pkvm_memcache;
> +
>         /* Virtual SError ESR to restore when HCR_EL2.VSE is set */
>         u64 vsesr_el2;
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 25038ac705d8..a7976e50f556 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -39,6 +39,7 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages);
>  int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
> +int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> index 8bd9a539f260..cc431820c6ce 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> @@ -46,6 +46,8 @@ struct hyp_page {
>
>         /* Host (non-meta) state. Guarded by the host stage-2 lock. */
>         enum pkvm_page_state host_state : 8;
> +
> +       u32 host_share_guest_count;
>  };
>
>  extern u64 __hyp_vmemmap;
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 95d78db315b3..d659462fbf5d 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -211,6 +211,39 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) =  ret;
>  }
>
> +static int pkvm_refill_memcache(struct pkvm_hyp_vcpu *hyp_vcpu)
> +{
> +       struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
> +
> +       return refill_memcache(&hyp_vcpu->vcpu.arch.pkvm_memcache,
> +                              host_vcpu->arch.pkvm_memcache.nr_pages,
> +                              &host_vcpu->arch.pkvm_memcache);
> +}
> +
> +static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(u64, pfn, host_ctxt, 1);
> +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> +       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 3);
> +       struct pkvm_hyp_vcpu *hyp_vcpu;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> +       if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> +               goto out;
> +
> +       ret = pkvm_refill_memcache(hyp_vcpu);
> +       if (ret)
> +               goto out;
> +
> +       ret = __pkvm_host_share_guest(pfn, gfn, hyp_vcpu, prot);
> +out:
> +       cpu_reg(host_ctxt, 1) =  ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -420,6 +453,7 @@ static const hcall_t host_hcall[] = {
>
>         HANDLE_FUNC(__pkvm_host_share_hyp),
>         HANDLE_FUNC(__pkvm_host_unshare_hyp),
> +       HANDLE_FUNC(__pkvm_host_share_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 12bb5445fe47..fb9592e721cf 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -867,6 +867,27 @@ static int hyp_complete_donation(u64 addr,
>         return pkvm_create_mappings_locked(start, end, prot);
>  }
>
> +static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr)
> +{
> +       if (!kvm_pte_valid(pte))
> +               return PKVM_NOPAGE;
> +
> +       return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
> +}
> +
> +static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
> +                                         u64 size, enum pkvm_page_state state)
> +{
> +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> +       struct check_walk_data d = {
> +               .desired        = state,
> +               .get_page_state = guest_get_page_state,
> +       };
> +
> +       hyp_assert_lock_held(&vm->lock);
> +       return check_page_state_range(&vm->pgt, addr, size, &d);
> +}
> +
>  static int check_share(struct pkvm_mem_share *share)
>  {
>         const struct pkvm_mem_transition *tx = &share->tx;
> @@ -1349,3 +1370,54 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
>
>         return ret;
>  }
> +
> +int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
> +                           enum kvm_pgtable_prot prot)
> +{
> +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> +       u64 phys = hyp_pfn_to_phys(pfn);
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       struct hyp_page *page;
> +       int ret;
> +
> +       if (prot & ~KVM_PGTABLE_PROT_RWX)
> +               return -EINVAL;
> +
> +       ret = check_range_allowed_memory(phys, phys + PAGE_SIZE);
> +       if (ret)
> +               return ret;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __guest_check_page_state_range(vcpu, ipa, PAGE_SIZE, PKVM_NOPAGE);
> +       if (ret)
> +               goto unlock;
> +
> +       page = hyp_phys_to_page(phys);
> +       switch (page->host_state) {
> +       case PKVM_PAGE_OWNED:
> +               WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_OWNED));
> +               break;
> +       case PKVM_PAGE_SHARED_OWNED:
> +               if (page->host_share_guest_count)
> +                       break;
> +               /* Only host to np-guest multi-sharing is tolerated */
> +               WARN_ON(1);
> +               fallthrough;
> +       default:
> +               ret = -EPERM;
> +               goto unlock;
> +       }
> +
> +       WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys,
> +                                      pkvm_mkstate(prot, PKVM_PAGE_SHARED_BORROWED),
> +                                      &vcpu->vcpu.arch.pkvm_memcache, 0));
> +       page->host_share_guest_count++;
> +
> +unlock:
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index 496d186efb03..f2e363fe6b84 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -795,6 +795,13 @@ int __pkvm_teardown_vm(pkvm_handle_t handle)
>         /* Push the metadata pages to the teardown memcache */
>         for (idx = 0; idx < hyp_vm->nr_vcpus; ++idx) {
>                 struct pkvm_hyp_vcpu *hyp_vcpu = hyp_vm->vcpus[idx];
> +               struct kvm_hyp_memcache *vcpu_mc = &hyp_vcpu->vcpu.arch.pkvm_memcache;
> +
> +               while (vcpu_mc->nr_pages) {
> +                       void *addr = pop_hyp_memcache(vcpu_mc, hyp_phys_to_virt);

nit: newline

> +                       push_hyp_memcache(mc, addr, hyp_virt_to_phys);
> +                       unmap_donated_memory_noclear(addr, PAGE_SIZE);
> +               }
>
>                 teardown_donated_memory(mc, hyp_vcpu, sizeof(*hyp_vcpu));
>         }
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 00:53:34 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:53:34 +0000
Subject: [PATCH v3 11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
In-Reply-To: <20241216175803.2716565-12-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-12-qperret@google.com>
Message-ID: <CA+EHjTxRt=XoCZbRLE1UjMg4bzgoLYD9Lh0nzmjvPZ2Q4xQOkg@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> In preparation for letting the host unmap pages from non-protected
> guests, introduce a new hypercall implementing the host-unshare-guest
> transition.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Apart from nit below.
Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad


> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  6 ++
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 21 ++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 67 +++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/pkvm.c                | 12 ++++
>  6 files changed, 108 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 449337f5b2a3..0b6c4d325134 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -66,6 +66,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index a7976e50f556..e528a42ed60e 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -40,6 +40,7 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
> +int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> index be52c5b15e21..0cc2a429f1fb 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> @@ -64,6 +64,11 @@ static inline bool pkvm_hyp_vcpu_is_protected(struct pkvm_hyp_vcpu *hyp_vcpu)
>         return vcpu_is_protected(&hyp_vcpu->vcpu);
>  }
>
> +static inline bool pkvm_hyp_vm_is_protected(struct pkvm_hyp_vm *hyp_vm)
> +{
> +       return kvm_vm_is_protected(&hyp_vm->kvm);
> +}
> +
>  void pkvm_hyp_vm_table_init(void *tbl);
>
>  int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
> @@ -78,6 +83,7 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
>  struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void);
>
>  struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
> +struct pkvm_hyp_vm *get_np_pkvm_hyp_vm(pkvm_handle_t handle);
>  void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
>
>  #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index d659462fbf5d..3c3a27c985a2 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -244,6 +244,26 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) =  ret;
>  }
>
> +static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> +       struct pkvm_hyp_vm *hyp_vm;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vm = get_np_pkvm_hyp_vm(handle);
> +       if (!hyp_vm)
> +               goto out;
> +
> +       ret = __pkvm_host_unshare_guest(gfn, hyp_vm);
> +       put_pkvm_hyp_vm(hyp_vm);
> +out:
> +       cpu_reg(host_ctxt, 1) =  ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -454,6 +474,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_share_hyp),
>         HANDLE_FUNC(__pkvm_host_unshare_hyp),
>         HANDLE_FUNC(__pkvm_host_share_guest),
> +       HANDLE_FUNC(__pkvm_host_unshare_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index fb9592e721cf..30243b7922f1 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1421,3 +1421,70 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
>
>         return ret;
>  }
> +
> +static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)

nit: This parameter in this patch, and others, is sometimes hyp_vm, at
others just vm. It would be nicer if it was always the same.


> +{
> +       enum pkvm_page_state state;
> +       struct hyp_page *page;
> +       kvm_pte_t pte;
> +       u64 phys;
> +       s8 level;
> +       int ret;
> +
> +       ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
> +       if (ret)
> +               return ret;
> +       if (level != KVM_PGTABLE_LAST_LEVEL)
> +               return -E2BIG;
> +       if (!kvm_pte_valid(pte))
> +               return -ENOENT;
> +
> +       state = guest_get_page_state(pte, ipa);
> +       if (state != PKVM_PAGE_SHARED_BORROWED)
> +               return -EPERM;
> +
> +       phys = kvm_pte_to_phys(pte);
> +       ret = check_range_allowed_memory(phys, phys + PAGE_SIZE);
> +       if (WARN_ON(ret))
> +               return ret;
> +
> +       page = hyp_phys_to_page(phys);
> +       if (page->host_state != PKVM_PAGE_SHARED_OWNED)
> +               return -EPERM;
> +       if (WARN_ON(!page->host_share_guest_count))
> +               return -EINVAL;
> +
> +       *__phys = phys;
> +
> +       return 0;
> +}
> +
> +int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *vm)
> +{
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       struct hyp_page *page;
> +       u64 phys;
> +       int ret;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __check_host_shared_guest(vm, &phys, ipa);
> +       if (ret)
> +               goto unlock;
> +
> +       ret = kvm_pgtable_stage2_unmap(&vm->pgt, ipa, PAGE_SIZE);
> +       if (ret)
> +               goto unlock;
> +
> +       page = hyp_phys_to_page(phys);
> +       page->host_share_guest_count--;
> +       if (!page->host_share_guest_count)
> +               WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_OWNED));
> +
> +unlock:
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index f2e363fe6b84..1b0982fa5ba8 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -376,6 +376,18 @@ void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm)
>         hyp_spin_unlock(&vm_table_lock);
>  }
>
> +struct pkvm_hyp_vm *get_np_pkvm_hyp_vm(pkvm_handle_t handle)
> +{
> +       struct pkvm_hyp_vm *hyp_vm = get_pkvm_hyp_vm(handle);
> +
> +       if (hyp_vm && pkvm_hyp_vm_is_protected(hyp_vm)) {
> +               put_pkvm_hyp_vm(hyp_vm);
> +               hyp_vm = NULL;
> +       }
> +
> +       return hyp_vm;
> +}
> +
>  static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
>  {
>         struct kvm *kvm = &hyp_vm->kvm;
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From linux at fw-web.de  Tue Dec 17 00:54:25 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 09:54:25 +0100
Subject: [PATCH v7 0/5] Add pinctrl support for mt7988
Message-ID: <20241217085435.9586-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This series adds pinctrl driver, dt-bindings and dts node for pinctrl
on mediatek mt7988 SoC.

changes in v7:
- add const for pins and mtk_pin_soc as suggested by Christophe JAILLET in v5
- left angelos RB because of minor change (hope this is right)

changes in v6:
- some fixes to binding
- changed title and fixed typo in bpi-r4 patch
- added RB's

changes in v5:
- rebased to 6.13-rc1
- moved dt nodes with mutliple options to BPI-R4 board
- changes suggested by angelo in v4
- changed example in binding and dt node to not using const MTK_DRIVE_8mA

changes in v4:
- fixed fixed string binding error

changes in v3:
- rebase on rafals dts patches
- update binding to have mux subnode as fixed string and conf with optional suffix

changes in v2:
  binding:
  - drop gpio-cells description
  - move ref in mux subnode up
  - order uart-functions alphanumeric and fix typo
  dts:
  - fix indentation of reg-values

Daniel Golle (2):
  pinctrl: mediatek: add support for MTK_PULL_PD_TYPE
  pinctrl: mediatek: add MT7988 pinctrl driver

Frank Wunderlich (3):
  dt-bindings: pinctrl: add binding for MT7988 SoC
  arm64: dts: mediatek: mt7988: Add pinctrl support
  arm64: dts: mediatek: mt7988a-bpi-r4: Add pinctrl subnodes for bpi-r4

 .../pinctrl/mediatek,mt7988-pinctrl.yaml      |  575 ++++++
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  |  189 ++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi     |   54 +
 drivers/pinctrl/mediatek/Kconfig              |    7 +
 drivers/pinctrl/mediatek/Makefile             |    1 +
 drivers/pinctrl/mediatek/pinctrl-mt7988.c     | 1556 +++++++++++++++++
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  |   73 +-
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |    1 +
 8 files changed, 2445 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c

-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 00:54:26 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 09:54:26 +0100
Subject: [PATCH v7 1/5] pinctrl: mediatek: add support for MTK_PULL_PD_TYPE
In-Reply-To: <20241217085435.9586-1-linux@fw-web.de>
References: <20241217085435.9586-1-linux@fw-web.de>
Message-ID: <20241217085435.9586-2-linux@fw-web.de>

From: Daniel Golle <daniel at makrotopia.org>

The MediaTek MT7988 SoC got some pins which only got configurable
pull-down but unlike previous designs there is no pull-up option.
Add new type MTK_PULL_PD_TYPE to support configuring such pins.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v5:
- add changes suggested by angelo (pd_only), long version, tested with emmc
---
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  | 73 ++++++++++++++++---
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |  1 +
 2 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 54301fbba524..7b704cc55c9f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1);
  */
 static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
 				const struct mtk_pin_desc *desc,
-				u32 pullup, u32 arg)
+				u32 pullup, u32 arg, bool pd_only)
 {
 	int err, pu, pd;
 
@@ -587,18 +587,34 @@ static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
 		pu = 0;
 		pd = 1;
 	} else {
-		err = -EINVAL;
-		goto out;
+		return -EINVAL;
 	}
 
-	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
-	if (err)
-		goto out;
+	if (!pd_only) {
+		err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
+		if (err)
+			return err;
+	}
 
-	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+}
+
+static int mtk_pinconf_bias_set_pd(struct mtk_pinctrl *hw,
+				const struct mtk_pin_desc *desc,
+				u32 pullup, u32 arg)
+{
+	int err, pd;
+
+	if (arg != MTK_DISABLE && arg != MTK_ENABLE)
+		return -EINVAL;
+
+	if (arg == MTK_DISABLE || pullup)
+		pd = 0;
+	else if (!pullup)
+		pd = 1;
+
+	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
 
-out:
-	return err;
 }
 
 static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
@@ -737,7 +753,7 @@ static int mtk_pinconf_bias_set_pu_pd_rsel(struct mtk_pinctrl *hw,
 			return err;
 	}
 
-	return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable);
+	return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable, false);
 }
 
 int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
@@ -758,8 +774,14 @@ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
 			return 0;
 	}
 
+	if (try_all_type & MTK_PULL_PD_TYPE) {
+		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, true);
+		if (!err)
+			return err;
+	}
+
 	if (try_all_type & MTK_PULL_PU_PD_TYPE) {
-		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, false);
 		if (!err)
 			return 0;
 	}
@@ -878,6 +900,29 @@ static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
 	return err;
 }
 
+static int mtk_pinconf_bias_get_pd(struct mtk_pinctrl *hw,
+				const struct mtk_pin_desc *desc,
+				u32 *pullup, u32 *enable)
+{
+	int err, pd;
+
+	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
+	if (err)
+		goto out;
+
+	if (pd == 0) {
+		*pullup = 0;
+		*enable = MTK_DISABLE;
+	} else if (pd == 1) {
+		*pullup = 0;
+		*enable = MTK_ENABLE;
+	} else
+		err = -EINVAL;
+
+out:
+	return err;
+}
+
 static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
 				const struct mtk_pin_desc *desc,
 				u32 *pullup, u32 *enable)
@@ -947,6 +992,12 @@ int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
 			return 0;
 	}
 
+	if (try_all_type & MTK_PULL_PD_TYPE) {
+		err = mtk_pinconf_bias_get_pd(hw, desc, pullup, enable);
+		if (!err)
+			return err;
+	}
+
 	if (try_all_type & MTK_PULL_PU_PD_TYPE) {
 		err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
 		if (!err)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 23688ca6d04e..9c271dc2b521 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -24,6 +24,7 @@
  * turned on/off itself. But it can't be selected pull up/down
  */
 #define MTK_PULL_RSEL_TYPE		BIT(3)
+#define MTK_PULL_PD_TYPE        BIT(4)
 /* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by
  * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE.
  */
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 00:54:30 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 09:54:30 +0100
Subject: [PATCH v7 5/5] arm64: dts: mediatek: mt7988a-bpi-r4: Add pinctrl subnodes for bpi-r4
In-Reply-To: <20241217085435.9586-1-linux@fw-web.de>
References: <20241217085435.9586-1-linux@fw-web.de>
Message-ID: <20241217085435.9586-6-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add board specific pinctrl configurations on Bananapi R4.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes in v6:
- fix typo
- start title uppercase
- use bpi-r4 prefix
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 189 ++++++++++++++++++
 1 file changed, 189 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index efc4ad0b08b8..aa2dabc041fd 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -9,3 +9,192 @@ / {
 	model = "Banana Pi BPI-R4";
 	chassis-type = "embedded";
 };
+
+&pio {
+	mdio0_pins: mdio0-pins {
+		mux {
+			function = "eth";
+			groups = "mdc_mdio0";
+		};
+
+		conf {
+			pins = "SMI_0_MDC", "SMI_0_MDIO";
+			drive-strength = <8>;
+		};
+	};
+
+	i2c0_pins: i2c0-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c0_1";
+		};
+	};
+
+	i2c1_pins: i2c1-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_0";
+		};
+	};
+
+	i2c1_sfp_pins: i2c1-sfp-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c1_sfp";
+		};
+	};
+
+	i2c2_0_pins: i2c2-g0-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c2_0";
+		};
+	};
+
+	i2c2_1_pins: i2c2-g1-pins {
+		mux {
+			function = "i2c";
+			groups = "i2c2_1";
+		};
+	};
+
+	gbe0_led0_pins: gbe0-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe0_led0";
+		};
+	};
+
+	gbe1_led0_pins: gbe1-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe1_led0";
+		};
+	};
+
+	gbe2_led0_pins: gbe2-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe2_led0";
+		};
+	};
+
+	gbe3_led0_pins: gbe3-led0-pins {
+		mux {
+			function = "led";
+			groups = "gbe3_led0";
+		};
+	};
+
+	gbe0_led1_pins: gbe0-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe0_led1";
+		};
+	};
+
+	gbe1_led1_pins: gbe1-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe1_led1";
+		};
+	};
+
+	gbe2_led1_pins: gbe2-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe2_led1";
+		};
+	};
+
+	gbe3_led1_pins: gbe3-led1-pins {
+		mux {
+			function = "led";
+			groups = "gbe3_led1";
+		};
+	};
+
+	i2p5gbe_led0_pins: 2p5gbe-led0-pins {
+		mux {
+			function = "led";
+			groups = "2p5gbe_led0";
+		};
+	};
+
+	i2p5gbe_led1_pins: 2p5gbe-led1-pins {
+		mux {
+			function = "led";
+			groups = "2p5gbe_led1";
+		};
+	};
+
+	mmc0_pins_emmc_45: mmc0-emmc-45-pins {
+		mux {
+			function = "flash";
+			groups = "emmc_45";
+		};
+	};
+
+	mmc0_pins_emmc_51: mmc0-emmc-51-pins {
+		mux {
+			function = "flash";
+			groups = "emmc_51";
+		};
+	};
+
+	mmc0_pins_sdcard: mmc0-sdcard-pins {
+		mux {
+			function = "flash";
+			groups = "sdcard";
+		};
+	};
+
+	uart0_pins: uart0-pins {
+		mux {
+			function = "uart";
+			groups =  "uart0";
+		};
+	};
+
+	snfi_pins: snfi-pins {
+		mux {
+			function = "flash";
+			groups = "snfi";
+		};
+	};
+
+	spi0_pins: spi0-pins {
+		mux {
+			function = "spi";
+			groups = "spi0";
+		};
+	};
+
+	spi0_flash_pins: spi0-flash-pins {
+		mux {
+			function = "spi";
+			groups = "spi0", "spi0_wp_hold";
+		};
+	};
+
+	spi1_pins: spi1-pins {
+		mux {
+			function = "spi";
+			groups = "spi1";
+		};
+	};
+
+	spi2_pins: spi2-pins {
+		mux {
+			function = "spi";
+			groups = "spi2";
+		};
+	};
+
+	spi2_flash_pins: spi2-flash-pins {
+		mux {
+			function = "spi";
+			groups = "spi2", "spi2_wp_hold";
+		};
+	};
+};
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 00:54:28 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 09:54:28 +0100
Subject: [PATCH v7 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241217085435.9586-1-linux@fw-web.de>
References: <20241217085435.9586-1-linux@fw-web.de>
Message-ID: <20241217085435.9586-4-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This adds bindings for MT7988 pinctrl driver.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes in v6:
changes suggested by rob
- remove quotes around mux
- use const instead of enum if only one value is possible

changes in v5 (so not adding RB from Rob given in v4):
- do not use MTK_DRIVE_8mA in example
- add _0 functions for pwm

changes in v4:
- dt-binding: pinctrl: fix dt_binding_check fixed-string error

'^mux$' should not be valid under {'pattern': '^\\^[a-zA-Z0-9,\\-._#@]+\\$$'}
	hint: Fixed strings belong in 'properties', not 'patternProperties'

changes in v3:
- limit conf subnode name with optional suffix like mmc on mt7986
- match mux subnode without wildcards

changes in v2:
- drop gpio-cells description
- move ref in mux subnode up
- order uart-functions alphanumeric and fix typo
---
 .../pinctrl/mediatek,mt7988-pinctrl.yaml      | 575 ++++++++++++++++++
 1 file changed, 575 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
new file mode 100644
index 000000000000..26dfe7e7735a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
@@ -0,0 +1,575 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7988-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT7988 Pin Controller
+
+maintainers:
+  - Sean Wang <sean.wang at kernel.org>
+
+description:
+  The MediaTek's MT7988 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7988-pinctrl
+
+  reg:
+    minItems: 7
+    maxItems: 7
+
+  reg-names:
+    items:
+      - const: gpio
+      - const: iocfg_tr
+      - const: iocfg_br
+      - const: iocfg_rb
+      - const: iocfg_lb
+      - const: iocfg_tl
+      - const: eint
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-ranges:
+    minItems: 1
+    maxItems: 5
+    description:
+      GPIO valid number range.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - gpio-controller
+  - "#gpio-cells"
+
+patternProperties:
+  '-pins$':
+    type: object
+    additionalProperties: false
+
+    properties:
+      mux:
+        type: object
+        additionalProperties: false
+        $ref: /schemas/pinctrl/pinmux-node.yaml
+        description: |
+          pinmux configuration nodes.
+
+          The following table shows the effective values of "group", "function"
+          properties and chip pinout pins
+
+          groups               function           pins (in pin#)
+          ---------------------------------------------------------------------
+          "tops_jtag0_0"       "jtag"             0, 1, 2, 3, 4
+          "wo0_jtag"           "jtag"             50, 51, 52, 53, 54
+          "wo1_jtag"           "jtag"             50, 51, 52, 53, 54
+          "wo2_jtag"           "jtag"             50, 51, 52, 53, 54
+          "jtag"               "jtag"             58, 59, 60, 61, 62
+          "tops_jtag0_1"       "jtag"             58, 59, 60, 61, 62
+          "int_usxgmii"        "int_usxgmii"      2, 3
+          "pwm0"               "pwm"              57
+          "pwm1"               "pwm"              21
+          "pwm2"               "pwm"              80
+          "pwm2_0"             "pwm"              58
+          "pwm3"               "pwm"              81
+          "pwm3_0"             "pwm"              59
+          "pwm4"               "pwm"              82
+          "pwm4_0"             "pwm"              60
+          "pwm5"               "pwm"              83
+          "pwm5_0"             "pwm"              61
+          "pwm6"               "pwm"              69
+          "pwm6_0"             "pwm"              62
+          "pwm7"               "pwm"              70
+          "pwm7_0"             "pwm"              4
+          "dfd"                "dfd"              0, 1, 2, 3, 4
+          "xfi_phy0_i2c0"      "i2c"              0, 1
+          "xfi_phy1_i2c0"      "i2c"              0, 1
+          "xfi_phy_pll_i2c0"   "i2c"              3, 4
+          "xfi_phy_pll_i2c1"   "i2c"              3, 4
+          "i2c0_0"             "i2c"              5, 6
+          "i2c1_sfp"           "i2c"              5, 6
+          "xfi_pextp_phy0_i2c" "i2c"              5, 6
+          "xfi_pextp_phy1_i2c" "i2c"              5, 6
+          "i2c0_1"             "i2c"              15, 16
+          "u30_phy_i2c0"       "i2c"              15, 16
+          "u32_phy_i2c0"       "i2c"              15, 16
+          "xfi_phy0_i2c1"      "i2c"              15, 16
+          "xfi_phy1_i2c1"      "i2c"              15, 16
+          "xfi_phy_pll_i2c2"   "i2c"              15, 16
+          "i2c1_0"             "i2c"              17, 18
+          "u30_phy_i2c1"       "i2c"              17, 18
+          "u32_phy_i2c1"       "i2c"              17, 18
+          "xfi_phy_pll_i2c3"   "i2c"              17, 18
+          "sgmii0_i2c"         "i2c"              17, 18
+          "sgmii1_i2c"         "i2c"              17, 18
+          "i2c1_2"             "i2c"              69, 70
+          "i2c2_0"             "i2c"              69, 70
+          "i2c2_1"             "i2c"              71, 72
+          "mdc_mdio0"          "eth"              5, 6
+          "2p5g_ext_mdio"      "eth"              28, 29
+          "gbe_ext_mdio"       "eth"              30, 31
+          "mdc_mdio1"          "eth"              69, 70
+          "pcie_wake_n0_0"     "pcie"             7
+          "pcie_clk_req_n0_0"  "pcie"             8
+          "pcie_wake_n3_0"     "pcie"             9
+          "pcie_clk_req_n3"    "pcie"             10
+          "pcie_clk_req_n0_1"  "pcie"             10
+          "pcie_p0_phy_i2c"    "pcie"             7, 8
+          "pcie_p1_phy_i2c"    "pcie"             7, 8
+          "pcie_p3_phy_i2c"    "pcie"             9, 10
+          "pcie_p2_phy_i2c"    "pcie"             7, 8
+          "ckm_phy_i2c"        "pcie"             9, 10
+          "pcie_wake_n0_1"     "pcie"             13
+          "pcie_wake_n3_1"     "pcie"             14
+          "pcie_2l_0_pereset"  "pcie"             19
+          "pcie_1l_1_pereset"  "pcie"             20
+          "pcie_clk_req_n2_1"  "pcie"             63
+          "pcie_2l_1_pereset"  "pcie"             73
+          "pcie_1l_0_pereset"  "pcie"             74
+          "pcie_wake_n1_0"     "pcie"             75
+          "pcie_clk_req_n1"    "pcie"             76
+          "pcie_wake_n2_0"     "pcie"             77
+          "pcie_clk_req_n2_0"  "pcie"             78
+          "pcie_wake_n2_1"     "pcie"             79
+          "pmic"               "pmic"             11
+          "watchdog"           "watchdog"         12
+          "spi0_wp_hold"       "spi"              22, 23
+          "spi0"               "spi"              24, 25, 26, 27
+          "spi1"               "spi"              28, 29, 30, 31
+          "spi2"               "spi"              32, 33, 34, 35
+          "spi2_wp_hold"       "spi"              36, 37
+          "snfi"               "flash"            22, 23, 24, 25, 26, 27
+          "emmc_45"            "flash"            21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
+          "sdcard"             "flash"            32, 33, 34, 35, 36, 37
+          "emmc_51"            "flash"            38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49
+          "uart2"              "uart"             0, 1, 2, 3
+          "tops_uart0_0"       "uart"             22, 23
+          "uart2_0"            "uart"             28, 29, 30, 31
+          "uart1_0"            "uart"             32, 33, 34, 35
+          "uart2_1"            "uart"             32, 33, 34, 35
+          "net_wo0_uart_txd_0" "uart"             28
+          "net_wo1_uart_txd_0" "uart"             29
+          "net_wo2_uart_txd_0" "uart"             30
+          "tops_uart1_0"       "uart"             28, 29
+          "tops_uart0_1"       "uart"             30, 31
+          "tops_uart1_1"       "uart"             36, 37
+          "uart0"              "uart"             55, 56
+          "tops_uart0_2"       "uart"             55, 56
+          "uart2_2"            "uart"             50, 51, 52, 53
+          "uart1_1"            "uart"             58, 59, 60, 61
+          "uart2_3"            "uart"             58, 59, 60, 61
+          "uart1_2"            "uart"             80, 81, 82, 83
+          "uart1_2_lite"       "uart"             80, 81
+          "tops_uart1_2"       "uart"             80, 81
+          "net_wo0_uart_txd_1" "uart"             80
+          "net_wo1_uart_txd_1" "uart"             81
+          "net_wo2_uart_txd_1" "uart"             82
+          "udi"                "udi"              32, 33, 34, 35, 36
+          "i2s"                "audio"            50, 51, 52, 53, 54
+          "pcm"                "audio"            50, 51, 52, 53
+          "gbe0_led1"          "led"              58
+          "gbe1_led1"          "led"              59
+          "gbe2_led1"          "led"              60
+          "gbe3_led1"          "led"              61
+          "2p5gbe_led1"        "led"              62
+          "gbe0_led0"          "led"              64
+          "gbe1_led0"          "led"              65
+          "gbe2_led0"          "led"              66
+          "gbe3_led0"          "led"              67
+          "2p5gbe_led0"        "led"              68
+          "drv_vbus_p1"        "usb"              63
+          "drv_vbus"           "usb"              79
+
+        properties:
+          function:
+            description:
+              A string containing the name of the function to mux to the group.
+            enum: [audio, dfd, eth, flash, i2c, int_usxgmii, jtag, led, pcie, pmic, pwm, spi,
+                   uart, udi, usb, watchdog]
+          groups:
+            description:
+              An array of strings. Each string contains the name of a group.
+
+        required:
+          - function
+          - groups
+
+        allOf:
+          - if:
+              properties:
+                function:
+                  const: audio
+            then:
+              properties:
+                groups:
+                  enum: [i2s, pcm]
+          - if:
+              properties:
+                function:
+                  const: jtag
+            then:
+              properties:
+                groups:
+                  enum: [jtag, tops_jtag0_0, tops_jtag0_1, wo0_jtag, wo1_jtag, wo2_jtag]
+          - if:
+              properties:
+                function:
+                  const: int_usxgmii
+            then:
+              properties:
+                groups:
+                  const: int_usxgmii
+          - if:
+              properties:
+                function:
+                  const: dfd
+            then:
+              properties:
+                groups:
+                  const: dfd
+          - if:
+              properties:
+                function:
+                  const: flash
+            then:
+              properties:
+                groups:
+                  enum: [emmc_45, emmc_51, sdcard, snfi]
+          - if:
+              properties:
+                function:
+                  const: eth
+            then:
+              properties:
+                groups:
+                  enum: [2p5g_ext_mdio, gbe_ext_mdio, mdc_mdio0, mdc_mdio1]
+          - if:
+              properties:
+                function:
+                  const: i2c
+            then:
+              properties:
+                groups:
+                  enum: [xfi_phy0_i2c0, xfi_phy1_i2c0, xfi_phy_pll_i2c0,
+                         xfi_phy_pll_i2c1, i2c0_0, i2c1_sfp, xfi_pextp_phy0_i2c,
+                         xfi_pextp_phy1_i2c, i2c0_1, u30_phy_i2c0, u32_phy_i2c0,
+                         xfi_phy0_i2c1, xfi_phy1_i2c1, xfi_phy_pll_i2c2, i2c1_0,
+                         u30_phy_i2c1, u32_phy_i2c1, xfi_phy_pll_i2c3, sgmii0_i2c,
+                         sgmii1_i2c, i2c1_2, i2c2_0, i2c2_1]
+          - if:
+              properties:
+                function:
+                  const: led
+            then:
+              properties:
+                groups:
+                  enum: [2p5gbe_led0, 2p5gbe_led1, gbe0_led0, gbe0_led1, gbe1_led0, gbe1_led1,
+                         gbe2_led0, gbe2_led1, gbe3_led0, gbe3_led1, wf5g_led0, wf5g_led1]
+          - if:
+              properties:
+                function:
+                  const: pcie
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [pcie_wake_n0_0, pcie_clk_req_n0_0, pcie_wake_n3_0,
+                           pcie_clk_req_n3, pcie_p0_phy_i2c, pcie_p1_phy_i2c,
+                           pcie_p3_phy_i2c, pcie_p2_phy_i2c, ckm_phy_i2c,
+                           pcie_wake_n0_1, pcie_wake_n3_1, pcie_2l_0_pereset,
+                           pcie_1l_1_pereset, pcie_clk_req_n2_1, pcie_2l_1_pereset,
+                           pcie_1l_0_pereset, pcie_wake_n1_0, pcie_clk_req_n1,
+                           pcie_wake_n2_0, pcie_clk_req_n2_0, pcie_wake_n2_1,
+                           pcie_clk_req_n0_1]
+                  maxItems: 3
+          - if:
+              properties:
+                function:
+                  const: pmic
+            then:
+              properties:
+                groups:
+                  const: pmic
+          - if:
+              properties:
+                function:
+                  const: pwm
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [pwm0, pwm1, pwm2, pwm2_0, pwm3, pwm3_0, pwm4, pwm4_0, pwm5, pwm5_0,
+                           pwm6, pwm6_0, pwm7, pwm7_0]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: spi
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [spi0, spi0_wp_hold, spi1, spi2, spi2_wp_hold]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: uart
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [net_wo0_uart_txd_0, net_wo0_uart_txd_1, net_wo1_uart_txd_0,
+                           net_wo1_uart_txd_1, net_wo2_uart_txd_0, net_wo2_uart_txd_1,
+                           tops_uart0_0, tops_uart0_1, tops_uart0_2, tops_uart1_0,
+                           tops_uart1_1, tops_uart1_2, uart0, uart1_0, uart1_1, uart1_2,
+                           uart1_2_lite, uart2, uart2_0, uart2_1, uart2_3]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: watchdog
+            then:
+              properties:
+                groups:
+                  const: watchdog
+          - if:
+              properties:
+                function:
+                  const: udi
+            then:
+              properties:
+                groups:
+                  const: udi
+          - if:
+              properties:
+                function:
+                  const: usb
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [drv_vbus, drv_vbus_p1]
+                  maxItems: 1
+
+    patternProperties:
+      '^conf(-[-a-z]*)?$':
+        type: object
+        additionalProperties: false
+        description:
+          pinconf configuration nodes.
+        $ref: /schemas/pinctrl/pincfg-node.yaml
+
+        properties:
+          pins:
+            description:
+              An array of strings. Each string contains the name of a pin.
+            items:
+              enum: [UART2_RXD, UART2_TXD, UART2_CTS, UART2_RTS, GPIO_A, SMI_0_MDC,
+                     SMI_0_MDIO, PCIE30_2L_0_WAKE_N, PCIE30_2L_0_CLKREQ_N,
+                     PCIE30_1L_1_WAKE_N, PCIE30_1L_1_CLKREQ_N, GPIO_P, WATCHDOG,
+                     GPIO_RESET, GPIO_WPS, PMIC_I2C_SCL, PMIC_I2C_SDA, I2C_1_SCL,
+                     I2C_1_SDA, PCIE30_2L_0_PRESET_N, PCIE30_1L_1_PRESET_N, PWMD1,
+                     SPI0_WP, SPI0_HOLD, SPI0_CSB, SPI0_MISO, SPI0_MOSI, SPI0_CLK,
+                     SPI1_CSB, SPI1_MISO, SPI1_MOSI, SPI1_CLK, SPI2_CLK, SPI2_MOSI,
+                     SPI2_MISO, SPI2_CSB, SPI2_HOLD, SPI2_WP, EMMC_RSTB, EMMC_DSL,
+                     EMMC_CK, EMMC_CMD, EMMC_DATA_7, EMMC_DATA_6, EMMC_DATA_5,
+                     EMMC_DATA_4, EMMC_DATA_3, EMMC_DATA_2, EMMC_DATA_1,
+                     EMMC_DATA_0, PCM_FS_I2S_LRCK, PCM_CLK_I2S_BCLK,
+                     PCM_DRX_I2S_DIN, PCM_DTX_I2S_DOUT, PCM_MCK_I2S_MCLK,
+                     UART0_RXD, UART0_TXD, PWMD0, JTAG_JTDI, JTAG_JTDO, JTAG_JTMS,
+                     JTAG_JTCLK, JTAG_JTRST_N, USB_DRV_VBUS_P1, LED_A, LED_B, LED_C,
+                     LED_D, LED_E, GPIO_B, GPIO_C, I2C_2_SCL, I2C_2_SDA,
+                     PCIE30_2L_1_PRESET_N, PCIE30_1L_0_PRESET_N,
+                     PCIE30_2L_1_WAKE_N, PCIE30_2L_1_CLKREQ_N,
+                     PCIE30_1L_0_WAKE_N, PCIE30_1L_0_CLKREQ_N, USB_DRV_VBUS_P0,
+                     UART1_RXD, UART1_TXD, UART1_CTS, UART1_RTS]
+            maxItems: 84
+
+          bias-disable: true
+
+          bias-pull-up:
+            oneOf:
+              - type: boolean
+                description: normal pull up.
+              - enum: [100, 101, 102, 103]
+                description:
+                  PUPD/R1/R0 pull down type. See MTK_PUPD_SET_R1R0 defines in
+                  dt-bindings/pinctrl/mt65xx.h.
+
+          bias-pull-down:
+            oneOf:
+              - type: boolean
+                description: normal pull down.
+              - enum: [100, 101, 102, 103]
+                description:
+                  PUPD/R1/R0 pull down type. See MTK_PUPD_SET_R1R0 defines in
+                  dt-bindings/pinctrl/mt65xx.h.
+
+          input-enable: true
+
+          input-disable: true
+
+          output-enable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            enum: [2, 4, 6, 8, 10, 12, 14, 16]
+
+          mediatek,pull-up-adv:
+            description: |
+              Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
+              Pull up settings for 2 pull resistors, R0 and R1. Valid arguments
+              are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,pull-down-adv:
+            description: |
+              Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
+              Pull down settings for 2 pull resistors, R0 and R1. Valid arguments
+              are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+        required:
+          - pins
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/mt65xx.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      pio: pinctrl at 1001f000 {
+        compatible = "mediatek,mt7988-pinctrl";
+        reg = <0 0x1001f000 0 0x1000>,
+        <0 0x11c10000 0 0x1000>,
+        <0 0x11d00000 0 0x1000>,
+        <0 0x11d20000 0 0x1000>,
+        <0 0x11e00000 0 0x1000>,
+        <0 0x11f00000 0 0x1000>,
+        <0 0x1000b000 0 0x1000>;
+        reg-names = "gpio", "iocfg_tr",
+          "iocfg_br", "iocfg_rb",
+          "iocfg_lb", "iocfg_tl", "eint";
+        gpio-controller;
+        #gpio-cells = <2>;
+        gpio-ranges = <&pio 0 0 84>;
+        interrupt-controller;
+        interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-parent = <&gic>;
+        #interrupt-cells = <2>;
+
+        i2c0_pins: i2c0-g0-pins {
+          mux {
+            function = "i2c";
+            groups = "i2c0_1";
+          };
+        };
+
+        mdio0_pins: mdio0-pins {
+          mux {
+            function = "eth";
+            groups = "mdc_mdio0";
+          };
+
+          conf {
+            pins = "SMI_0_MDC", "SMI_0_MDIO";
+            drive-strength = <8>;
+          };
+        };
+
+        mmc0_pins_emmc_51: mmc0-emmc-51-pins {
+          mux {
+            function = "flash";
+            groups = "emmc_51";
+          };
+        };
+
+        mmc0_pins_sdcard: mmc0-sdcard-pins {
+          mux {
+            function = "flash";
+            groups = "sdcard";
+          };
+        };
+
+        pcie0_pins: pcie0-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
+                     "pcie_wake_n0_0";
+          };
+        };
+
+        pcie1_pins: pcie1-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
+                     "pcie_wake_n1_0";
+          };
+        };
+
+        pcie2_pins: pcie2-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
+                     "pcie_wake_n2_0";
+          };
+        };
+
+        pcie3_pins: pcie3-pins {
+          mux {
+            function = "pcie";
+            groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
+                     "pcie_wake_n3_0";
+          };
+        };
+
+        uart0_pins: uart0-pins {
+          mux {
+            function = "uart";
+            groups =  "uart0";
+          };
+        };
+      };
+    };
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 00:54:27 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 09:54:27 +0100
Subject: [PATCH v7 2/5] pinctrl: mediatek: add MT7988 pinctrl driver
In-Reply-To: <20241217085435.9586-1-linux@fw-web.de>
References: <20241217085435.9586-1-linux@fw-web.de>
Message-ID: <20241217085435.9586-3-linux@fw-web.de>

From: Daniel Golle <daniel at makrotopia.org>

Add pinctrl driver for the MediaTek MT7988 SoC.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
[correctly initialise for the function_desc structure]
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v7:
- make pins const
- make mt7988_data const
- leave angelos RB because of no functional change

v5:
- changes requested by angelo
  - lowercase mt7988_pinctrl_reg_page
  - compatible match in one line
  - HW debounce is only available for pins 0 to 15 and does not support
    pins with numbers 16 or higher.
- add additional PWM pingroups
---
 drivers/pinctrl/mediatek/Kconfig          |    7 +
 drivers/pinctrl/mediatek/Makefile         |    1 +
 drivers/pinctrl/mediatek/pinctrl-mt7988.c | 1556 +++++++++++++++++++++
 3 files changed, 1564 insertions(+)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c

diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index a417a031659c..58f32818a0e6 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -202,6 +202,13 @@ config PINCTRL_MT7986
 	default ARM64 && ARCH_MEDIATEK
 	select PINCTRL_MTK_MOORE
 
+config PINCTRL_MT7988
+	bool "Mediatek MT7988 pin control"
+	depends on OF
+	depends on ARM64 || COMPILE_TEST
+	default ARM64 && ARCH_MEDIATEK
+	select PINCTRL_MTK_MOORE
+
 config PINCTRL_MT8167
 	bool "MediaTek MT8167 pin control"
 	depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 1405d434218e..721ae83476d0 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_PINCTRL_MT7623)		+= pinctrl-mt7623.o
 obj-$(CONFIG_PINCTRL_MT7629)		+= pinctrl-mt7629.o
 obj-$(CONFIG_PINCTRL_MT7981)		+= pinctrl-mt7981.o
 obj-$(CONFIG_PINCTRL_MT7986)		+= pinctrl-mt7986.o
+obj-$(CONFIG_PINCTRL_MT7988)		+= pinctrl-mt7988.o
 obj-$(CONFIG_PINCTRL_MT8167)		+= pinctrl-mt8167.o
 obj-$(CONFIG_PINCTRL_MT8173)		+= pinctrl-mt8173.o
 obj-$(CONFIG_PINCTRL_MT8183)		+= pinctrl-mt8183.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7988.c b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
new file mode 100644
index 000000000000..68b4097792b8
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
@@ -0,0 +1,1556 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7988 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2020 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ */
+
+#include "pinctrl-moore.h"
+
+enum mt7988_pinctrl_reg_page {
+	GPIO_BASE,
+	IOCFG_TR_BASE,
+	IOCFG_BR_BASE,
+	IOCFG_RB_BASE,
+	IOCFG_LB_BASE,
+	IOCFG_TL_BASE,
+};
+
+#define MT7988_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+		       _x_bits)                                                \
+	PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+		       _x_bits, 32, 0)
+
+#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,    \
+			_x_bits)                                               \
+	PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+		       _x_bits, 32, 1)
+
+static const struct mtk_pin_field_calc mt7988_pin_mode_range[] = {
+	PIN_FIELD(0, 83, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_dir_range[] = {
+	PIN_FIELD(0, 83, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_di_range[] = {
+	PIN_FIELD(0, 83, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_do_range[] = {
+	PIN_FIELD(0, 83, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_ies_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x30, 0x10, 13, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x30, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0x30, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x40, 0x10, 21, 1),
+	PIN_FIELD_BASE(13, 13, 1, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0x40, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(15, 15, 5, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(16, 16, 5, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(17, 17, 5, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(18, 18, 5, 0x30, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x30, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x50, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x50, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x50, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x50, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x50, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x50, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x50, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x50, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x50, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x50, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x50, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x50, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x50, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x50, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x50, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x50, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x50, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x50, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x50, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x40, 0x10, 13, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(63, 63, 1, 0x40, 0x10, 20, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x40, 0x10, 11, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x40, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(71, 71, 5, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(72, 72, 5, 0x30, 0x10, 6, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(75, 75, 4, 0x30, 0x10, 11, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0x30, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x40, 0x10, 18, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x40, 0x10, 19, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x40, 0x10, 17, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_smt_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0xc0, 0x10, 13, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0xc0, 0x10, 14, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0xc0, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0xc0, 0x10, 12, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0xc0, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0xc0, 0x10, 9, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0xc0, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(7, 7, 4, 0xb0, 0x10, 8, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0xb0, 0x10, 6, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0xb0, 0x10, 5, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0xb0, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0xe0, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0xe0, 0x10, 21, 1),
+	PIN_FIELD_BASE(13, 13, 1, 0xe0, 0x10, 1, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0xe0, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(15, 15, 5, 0xc0, 0x10, 7, 1),
+	PIN_FIELD_BASE(16, 16, 5, 0xc0, 0x10, 8, 1),
+	PIN_FIELD_BASE(17, 17, 5, 0xc0, 0x10, 3, 1),
+	PIN_FIELD_BASE(18, 18, 5, 0xc0, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0xb0, 0x10, 7, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0xb0, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x140, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x140, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x140, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x140, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x140, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x140, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x140, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x140, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x140, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x140, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x140, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x140, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0x150, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x140, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x140, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x140, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x150, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x140, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x140, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x140, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x140, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x140, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x140, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x140, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x140, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x140, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x140, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x140, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x140, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x140, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x140, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x140, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x140, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x140, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0xe0, 0x10, 14, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0xe0, 0x10, 15, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0xe0, 0x10, 13, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0xe0, 0x10, 4, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0xe0, 0x10, 5, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0xe0, 0x10, 6, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0xe0, 0x10, 3, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0xe0, 0x10, 7, 1),
+	PIN_FIELD_BASE(63, 63, 1, 0xe0, 0x10, 20, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0xe0, 0x10, 8, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0xe0, 0x10, 9, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0xe0, 0x10, 10, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0xe0, 0x10, 11, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0xe0, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0xc0, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0xc0, 0x10, 2, 1),
+	PIN_FIELD_BASE(71, 71, 5, 0xc0, 0x10, 5, 1),
+	PIN_FIELD_BASE(72, 72, 5, 0xc0, 0x10, 6, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0xb0, 0x10, 10, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0xb0, 0x10, 1, 1),
+	PIN_FIELD_BASE(75, 75, 4, 0xb0, 0x10, 11, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0xb0, 0x10, 9, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0xb0, 0x10, 2, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0xb0, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0xb0, 0x10, 12, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0xe0, 0x10, 18, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0xe0, 0x10, 19, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0xe0, 0x10, 16, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0xe0, 0x10, 17, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_pu_range[] = {
+	PIN_FIELD_BASE(7, 7, 4, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x60, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0x60, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(13, 13, 1, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(63, 63, 1, 0x70, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(75, 75, 4, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0x60, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_pd_range[] = {
+	PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(10, 10, 4, 0x40, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(13, 13, 1, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(14, 14, 1, 0x50, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(15, 15, 5, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(16, 16, 5, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(17, 17, 5, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(18, 18, 5, 0x40, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(63, 63, 1, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(71, 71, 5, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(72, 72, 5, 0x40, 0x10, 3, 1),
+
+	PIN_FIELD_BASE(75, 75, 4, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(76, 76, 4, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(77, 77, 4, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(78, 78, 4, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(79, 79, 4, 0x40, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_drv_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(1, 1, 5, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(3, 3, 5, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(4, 4, 5, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(5, 5, 5, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(6, 6, 5, 0x00, 0x10, 12, 3),
+
+	PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 28, 3),
+	PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(10, 10, 4, 0x00, 0x10, 9, 3),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(12, 12, 1, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(13, 13, 1, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(14, 14, 1, 0x00, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(20, 20, 4, 0x00, 0x10, 12, 3),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x10, 0x10, 21, 3),
+	PIN_FIELD_BASE(22, 22, 3, 0x20, 0x10, 9, 3),
+	PIN_FIELD_BASE(23, 23, 3, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(24, 24, 3, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(25, 25, 3, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(26, 26, 3, 0x20, 0x10, 6, 3),
+	PIN_FIELD_BASE(27, 27, 3, 0x10, 0x10, 24, 3),
+	PIN_FIELD_BASE(28, 28, 3, 0x20, 0x10, 15, 3),
+	PIN_FIELD_BASE(29, 29, 3, 0x20, 0x10, 18, 3),
+	PIN_FIELD_BASE(30, 30, 3, 0x20, 0x10, 21, 3),
+	PIN_FIELD_BASE(31, 31, 3, 0x20, 0x10, 12, 3),
+	PIN_FIELD_BASE(32, 32, 3, 0x20, 0x10, 24, 3),
+	PIN_FIELD_BASE(33, 33, 3, 0x30, 0x10, 6, 3),
+	PIN_FIELD_BASE(34, 34, 3, 0x30, 0x10, 3, 3),
+	PIN_FIELD_BASE(35, 35, 3, 0x20, 0x10, 27, 3),
+	PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 0, 3),
+	PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 9, 3),
+	PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(40, 40, 3, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(41, 41, 3, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(42, 42, 3, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(43, 43, 3, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(44, 44, 3, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(45, 45, 3, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(46, 46, 3, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(47, 47, 3, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(48, 48, 3, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(49, 49, 3, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(50, 50, 3, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(51, 51, 3, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(52, 52, 3, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(53, 53, 3, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(54, 54, 3, 0x10, 0x10, 18, 3),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(56, 56, 1, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(57, 57, 1, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(58, 58, 1, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(59, 59, 1, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(60, 60, 1, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(61, 61, 1, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(62, 62, 1, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(63, 63, 1, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(64, 64, 1, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(65, 65, 1, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(66, 66, 1, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(67, 67, 1, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(68, 68, 1, 0x10, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(70, 70, 5, 0x00, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(74, 74, 4, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(75, 75, 4, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(76, 76, 4, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(77, 77, 4, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(78, 78, 4, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(79, 79, 4, 0x10, 0x10, 6, 3),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x10, 0x10, 24, 3),
+	PIN_FIELD_BASE(81, 81, 1, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(82, 82, 1, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(83, 83, 1, 0x10, 0x10, 21, 3),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_pupd_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x50, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x60, 0x10, 18, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x50, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x70, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x70, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x70, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x70, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x70, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x70, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x70, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x70, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x70, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x70, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x70, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x70, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x70, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x70, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x70, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x70, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x70, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x70, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x70, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x70, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x70, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x70, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x70, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x70, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x70, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x70, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x70, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x60, 0x10, 12, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x60, 0x10, 13, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x60, 0x10, 11, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x60, 0x10, 4, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x60, 0x10, 9, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x60, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x50, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x50, 0x10, 0, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x60, 0x10, 16, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x60, 0x10, 17, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x60, 0x10, 14, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x60, 0x10, 15, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_r0_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x60, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x80, 0x10, 18, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x70, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0x90, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0x90, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0x90, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0x90, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0x90, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0x90, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0x90, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0x90, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0x90, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0x90, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0x90, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0x90, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0xa0, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0x90, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0x90, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0x90, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0xa0, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0x90, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0x90, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0x90, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0x90, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0x90, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0x90, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0x90, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0x90, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x80, 0x10, 12, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x80, 0x10, 13, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x80, 0x10, 11, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x80, 0x10, 3, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x80, 0x10, 4, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x80, 0x10, 5, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x80, 0x10, 6, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x80, 0x10, 7, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x80, 0x10, 8, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x80, 0x10, 9, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x80, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x60, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x70, 0x10, 0, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x80, 0x10, 16, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x80, 0x10, 17, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x80, 0x10, 14, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x80, 0x10, 15, 1),
+};
+
+static const struct mtk_pin_field_calc mt7988_pin_r1_range[] = {
+	PIN_FIELD_BASE(0, 0, 5, 0x70, 0x10, 7, 1),
+	PIN_FIELD_BASE(1, 1, 5, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(2, 2, 5, 0x70, 0x10, 5, 1),
+	PIN_FIELD_BASE(3, 3, 5, 0x70, 0x10, 6, 1),
+	PIN_FIELD_BASE(4, 4, 5, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, 5, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(6, 6, 5, 0x70, 0x10, 4, 1),
+
+	PIN_FIELD_BASE(11, 11, 1, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(12, 12, 1, 0x90, 0x10, 18, 1),
+
+	PIN_FIELD_BASE(19, 19, 4, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(20, 20, 4, 0x80, 0x10, 1, 1),
+
+	PIN_FIELD_BASE(21, 21, 3, 0xb0, 0x10, 17, 1),
+	PIN_FIELD_BASE(22, 22, 3, 0xb0, 0x10, 23, 1),
+	PIN_FIELD_BASE(23, 23, 3, 0xb0, 0x10, 20, 1),
+	PIN_FIELD_BASE(24, 24, 3, 0xb0, 0x10, 19, 1),
+	PIN_FIELD_BASE(25, 25, 3, 0xb0, 0x10, 21, 1),
+	PIN_FIELD_BASE(26, 26, 3, 0xb0, 0x10, 22, 1),
+	PIN_FIELD_BASE(27, 27, 3, 0xb0, 0x10, 18, 1),
+	PIN_FIELD_BASE(28, 28, 3, 0xb0, 0x10, 25, 1),
+	PIN_FIELD_BASE(29, 29, 3, 0xb0, 0x10, 26, 1),
+	PIN_FIELD_BASE(30, 30, 3, 0xb0, 0x10, 27, 1),
+	PIN_FIELD_BASE(31, 31, 3, 0xb0, 0x10, 24, 1),
+	PIN_FIELD_BASE(32, 32, 3, 0xb0, 0x10, 28, 1),
+	PIN_FIELD_BASE(33, 33, 3, 0xc0, 0x10, 0, 1),
+	PIN_FIELD_BASE(34, 34, 3, 0xb0, 0x10, 31, 1),
+	PIN_FIELD_BASE(35, 35, 3, 0xb0, 0x10, 29, 1),
+	PIN_FIELD_BASE(36, 36, 3, 0xb0, 0x10, 30, 1),
+	PIN_FIELD_BASE(37, 37, 3, 0xc0, 0x10, 1, 1),
+	PIN_FIELD_BASE(38, 38, 3, 0xb0, 0x10, 11, 1),
+	PIN_FIELD_BASE(39, 39, 3, 0xb0, 0x10, 10, 1),
+	PIN_FIELD_BASE(40, 40, 3, 0xb0, 0x10, 0, 1),
+	PIN_FIELD_BASE(41, 41, 3, 0xb0, 0x10, 1, 1),
+	PIN_FIELD_BASE(42, 42, 3, 0xb0, 0x10, 9, 1),
+	PIN_FIELD_BASE(43, 43, 3, 0xb0, 0x10, 8, 1),
+	PIN_FIELD_BASE(44, 44, 3, 0xb0, 0x10, 7, 1),
+	PIN_FIELD_BASE(45, 45, 3, 0xb0, 0x10, 6, 1),
+	PIN_FIELD_BASE(46, 46, 3, 0xb0, 0x10, 5, 1),
+	PIN_FIELD_BASE(47, 47, 3, 0xb0, 0x10, 4, 1),
+	PIN_FIELD_BASE(48, 48, 3, 0xb0, 0x10, 3, 1),
+	PIN_FIELD_BASE(49, 49, 3, 0xb0, 0x10, 2, 1),
+	PIN_FIELD_BASE(50, 50, 3, 0xb0, 0x10, 15, 1),
+	PIN_FIELD_BASE(51, 51, 3, 0xb0, 0x10, 12, 1),
+	PIN_FIELD_BASE(52, 52, 3, 0xb0, 0x10, 13, 1),
+	PIN_FIELD_BASE(53, 53, 3, 0xb0, 0x10, 14, 1),
+	PIN_FIELD_BASE(54, 54, 3, 0xb0, 0x10, 16, 1),
+
+	PIN_FIELD_BASE(55, 55, 1, 0x90, 0x10, 12, 1),
+	PIN_FIELD_BASE(56, 56, 1, 0x90, 0x10, 13, 1),
+	PIN_FIELD_BASE(57, 57, 1, 0x90, 0x10, 11, 1),
+	PIN_FIELD_BASE(58, 58, 1, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(59, 59, 1, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(60, 60, 1, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(61, 61, 1, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(62, 62, 1, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(64, 64, 1, 0x90, 0x10, 6, 1),
+	PIN_FIELD_BASE(65, 65, 1, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(66, 66, 1, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(67, 67, 1, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(68, 68, 1, 0x90, 0x10, 10, 1),
+
+	PIN_FIELD_BASE(69, 69, 5, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, 5, 0x70, 0x10, 2, 1),
+
+	PIN_FIELD_BASE(73, 73, 4, 0x80, 0x10, 3, 1),
+	PIN_FIELD_BASE(74, 74, 4, 0x80, 0x10, 0, 1),
+
+	PIN_FIELD_BASE(80, 80, 1, 0x90, 0x10, 16, 1),
+	PIN_FIELD_BASE(81, 81, 1, 0x90, 0x10, 17, 1),
+	PIN_FIELD_BASE(82, 82, 1, 0x90, 0x10, 14, 1),
+	PIN_FIELD_BASE(83, 83, 1, 0x90, 0x10, 15, 1),
+};
+
+static const unsigned int mt7988_pull_type[] = {
+	MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PU_PD_TYPE,    /*7*/
+	MTK_PULL_PU_PD_TYPE,    /*8*/ MTK_PULL_PU_PD_TYPE,    /*9*/
+	MTK_PULL_PU_PD_TYPE,    /*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PU_PD_TYPE,    /*13*/
+	MTK_PULL_PU_PD_TYPE,    /*14*/ MTK_PULL_PD_TYPE,       /*15*/
+	MTK_PULL_PD_TYPE,       /*16*/ MTK_PULL_PD_TYPE,       /*17*/
+	MTK_PULL_PD_TYPE,       /*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PU_PD_TYPE,    /*63*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PUPD_R1R0_TYPE,/*69*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*70*/ MTK_PULL_PD_TYPE,       /*71*/
+	MTK_PULL_PD_TYPE,       /*72*/ MTK_PULL_PUPD_R1R0_TYPE,/*73*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,    /*75*/
+	MTK_PULL_PU_PD_TYPE,    /*76*/ MTK_PULL_PU_PD_TYPE,    /*77*/
+	MTK_PULL_PU_PD_TYPE,    /*78*/ MTK_PULL_PU_PD_TYPE,    /*79*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*80*/ MTK_PULL_PUPD_R1R0_TYPE,/*81*/
+	MTK_PULL_PUPD_R1R0_TYPE,/*82*/ MTK_PULL_PUPD_R1R0_TYPE,/*83*/
+};
+
+static const struct mtk_pin_reg_calc mt7988_reg_cals[] = {
+	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7988_pin_mode_range),
+	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7988_pin_dir_range),
+	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7988_pin_di_range),
+	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7988_pin_do_range),
+	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7988_pin_smt_range),
+	[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7988_pin_ies_range),
+	[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7988_pin_pu_range),
+	[PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7988_pin_pd_range),
+	[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7988_pin_drv_range),
+	[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7988_pin_pupd_range),
+	[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7988_pin_r0_range),
+	[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7988_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7988_pins[] = {
+	MT7988_PIN(0, "UART2_RXD"),
+	MT7988_PIN(1, "UART2_TXD"),
+	MT7988_PIN(2, "UART2_CTS"),
+	MT7988_PIN(3, "UART2_RTS"),
+	MT7988_PIN(4, "GPIO_A"),
+	MT7988_PIN(5, "SMI_0_MDC"),
+	MT7988_PIN(6, "SMI_0_MDIO"),
+	MT7988_PIN(7, "PCIE30_2L_0_WAKE_N"),
+	MT7988_PIN(8, "PCIE30_2L_0_CLKREQ_N"),
+	MT7988_PIN(9, "PCIE30_1L_1_WAKE_N"),
+	MT7988_PIN(10, "PCIE30_1L_1_CLKREQ_N"),
+	MT7988_PIN(11, "GPIO_P"),
+	MT7988_PIN(12, "WATCHDOG"),
+	MT7988_PIN(13, "GPIO_RESET"),
+	MT7988_PIN(14, "GPIO_WPS"),
+	MT7988_PIN(15, "PMIC_I2C_SCL"),
+	MT7988_PIN(16, "PMIC_I2C_SDA"),
+	MT7988_PIN(17, "I2C_1_SCL"),
+	MT7988_PIN(18, "I2C_1_SDA"),
+	MT7988_PIN(19, "PCIE30_2L_0_PRESET_N"),
+	MT7988_PIN(20, "PCIE30_1L_1_PRESET_N"),
+	MT7988_PIN(21, "PWMD1"),
+	MT7988_PIN(22, "SPI0_WP"),
+	MT7988_PIN(23, "SPI0_HOLD"),
+	MT7988_PIN(24, "SPI0_CSB"),
+	MT7988_PIN(25, "SPI0_MISO"),
+	MT7988_PIN(26, "SPI0_MOSI"),
+	MT7988_PIN(27, "SPI0_CLK"),
+	MT7988_PIN(28, "SPI1_CSB"),
+	MT7988_PIN(29, "SPI1_MISO"),
+	MT7988_PIN(30, "SPI1_MOSI"),
+	MT7988_PIN(31, "SPI1_CLK"),
+	MT7988_PIN(32, "SPI2_CLK"),
+	MT7988_PIN(33, "SPI2_MOSI"),
+	MT7988_PIN(34, "SPI2_MISO"),
+	MT7988_PIN(35, "SPI2_CSB"),
+	MT7988_PIN(36, "SPI2_HOLD"),
+	MT7988_PIN(37, "SPI2_WP"),
+	MT7988_PIN(38, "EMMC_RSTB"),
+	MT7988_PIN(39, "EMMC_DSL"),
+	MT7988_PIN(40, "EMMC_CK"),
+	MT7988_PIN(41, "EMMC_CMD"),
+	MT7988_PIN(42, "EMMC_DATA_7"),
+	MT7988_PIN(43, "EMMC_DATA_6"),
+	MT7988_PIN(44, "EMMC_DATA_5"),
+	MT7988_PIN(45, "EMMC_DATA_4"),
+	MT7988_PIN(46, "EMMC_DATA_3"),
+	MT7988_PIN(47, "EMMC_DATA_2"),
+	MT7988_PIN(48, "EMMC_DATA_1"),
+	MT7988_PIN(49, "EMMC_DATA_0"),
+	MT7988_PIN(50, "PCM_FS_I2S_LRCK"),
+	MT7988_PIN(51, "PCM_CLK_I2S_BCLK"),
+	MT7988_PIN(52, "PCM_DRX_I2S_DIN"),
+	MT7988_PIN(53, "PCM_DTX_I2S_DOUT"),
+	MT7988_PIN(54, "PCM_MCK_I2S_MCLK"),
+	MT7988_PIN(55, "UART0_RXD"),
+	MT7988_PIN(56, "UART0_TXD"),
+	MT7988_PIN(57, "PWMD0"),
+	MT7988_PIN(58, "JTAG_JTDI"),
+	MT7988_PIN(59, "JTAG_JTDO"),
+	MT7988_PIN(60, "JTAG_JTMS"),
+	MT7988_PIN(61, "JTAG_JTCLK"),
+	MT7988_PIN(62, "JTAG_JTRST_N"),
+	MT7988_PIN(63, "USB_DRV_VBUS_P1"),
+	MT7988_PIN(64, "LED_A"),
+	MT7988_PIN(65, "LED_B"),
+	MT7988_PIN(66, "LED_C"),
+	MT7988_PIN(67, "LED_D"),
+	MT7988_PIN(68, "LED_E"),
+	MT7988_PIN(69, "GPIO_B"),
+	MT7988_PIN(70, "GPIO_C"),
+	MT7988_PIN(71, "I2C_2_SCL"),
+	MT7988_PIN(72, "I2C_2_SDA"),
+	MT7988_PIN(73, "PCIE30_2L_1_PRESET_N"),
+	MT7988_PIN(74, "PCIE30_1L_0_PRESET_N"),
+	MT7988_PIN(75, "PCIE30_2L_1_WAKE_N"),
+	MT7988_PIN(76, "PCIE30_2L_1_CLKREQ_N"),
+	MT7988_PIN(77, "PCIE30_1L_0_WAKE_N"),
+	MT7988_PIN(78, "PCIE30_1L_0_CLKREQ_N"),
+	MT7988_PIN(79, "USB_DRV_VBUS_P0"),
+	MT7988_PIN(80, "UART1_RXD"),
+	MT7988_PIN(81, "UART1_TXD"),
+	MT7988_PIN(82, "UART1_CTS"),
+	MT7988_PIN(83, "UART1_RTS"),
+};
+
+/* jtag */
+static const int mt7988_tops_jtag0_0_pins[] = { 0, 1, 2, 3, 4 };
+static int mt7988_tops_jtag0_0_funcs[] = { 2, 2, 2, 2, 2 };
+
+static const int mt7988_wo0_jtag_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_wo0_jtag_funcs[] = { 3, 3, 3, 3, 3 };
+
+static const int mt7988_wo1_jtag_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_wo1_jtag_funcs[] = { 4, 4, 4, 4, 4 };
+
+static const int mt7988_wo2_jtag_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_wo2_jtag_funcs[] = { 5, 5, 5, 5, 5 };
+
+static const int mt7988_jtag_pins[] = { 58, 59, 60, 61, 62 };
+static int mt7988_jtag_funcs[] = { 1, 1, 1, 1, 1 };
+
+static const int mt7988_tops_jtag0_1_pins[] = { 58, 59, 60, 61, 62 };
+static int mt7988_tops_jtag0_1_funcs[] = { 4, 4, 4, 4, 4 };
+
+/* int_usxgmii */
+static const int mt7988_int_usxgmii_pins[] = { 2, 3 };
+static int mt7988_int_usxgmii_funcs[] = { 3, 3 };
+
+/* pwm */
+static const int mt7988_pwm0_pins[] = { 57 };
+static int mt7988_pwm0_funcs[] = { 1 };
+
+static const int mt7988_pwm1_pins[] = { 21 };
+static int mt7988_pwm1_funcs[] = { 1 };
+
+static const int mt7988_pwm2_pins[] = { 80 };
+static int mt7988_pwm2_funcs[] = { 2 };
+
+static const int mt7988_pwm2_0_pins[] = { 58 };
+static int mt7988_pwm2_0_funcs[] = { 5 };
+
+static const int mt7988_pwm3_pins[] = { 81 };
+static int mt7988_pwm3_funcs[] = { 2 };
+
+static const int mt7988_pwm3_0_pins[] = { 59 };
+static int mt7988_pwm3_0_funcs[] = { 5 };
+
+static const int mt7988_pwm4_pins[] = { 82 };
+static int mt7988_pwm4_funcs[] = { 2 };
+
+static const int mt7988_pwm4_0_pins[] = { 60 };
+static int mt7988_pwm4_0_funcs[] = { 5 };
+
+static const int mt7988_pwm5_pins[] = { 83 };
+static int mt7988_pwm5_funcs[] = { 2 };
+
+static const int mt7988_pwm5_0_pins[] = { 61 };
+static int mt7988_pwm5_0_funcs[] = { 5 };
+
+static const int mt7988_pwm6_pins[] = { 69 };
+static int mt7988_pwm6_funcs[] = { 3 };
+
+static const int mt7988_pwm6_0_pins[] = { 62 };
+static int mt7988_pwm6_0_funcs[] = { 5 };
+
+static const int mt7988_pwm7_pins[] = { 70 };
+static int mt7988_pwm7_funcs[] = { 3 };
+
+static const int mt7988_pwm7_0_pins[] = { 4 };
+static int mt7988_pwm7_0_funcs[] = { 3 };
+
+/* dfd */
+static const int mt7988_dfd_pins[] = { 0, 1, 2, 3, 4 };
+static int mt7988_dfd_funcs[] = { 4, 4, 4, 4, 4 };
+
+/* i2c */
+static const int mt7988_xfi_phy0_i2c0_pins[] = { 0, 1 };
+static int mt7988_xfi_phy0_i2c0_funcs[] = { 5, 5 };
+
+static const int mt7988_xfi_phy1_i2c0_pins[] = { 0, 1 };
+static int mt7988_xfi_phy1_i2c0_funcs[] = { 6, 6 };
+
+static const int mt7988_xfi_phy_pll_i2c0_pins[] = { 3, 4 };
+static int mt7988_xfi_phy_pll_i2c0_funcs[] = { 5, 5 };
+
+static const int mt7988_xfi_phy_pll_i2c1_pins[] = { 3, 4 };
+static int mt7988_xfi_phy_pll_i2c1_funcs[] = { 6, 6 };
+
+static const int mt7988_i2c0_0_pins[] = { 5, 6 };
+static int mt7988_i2c0_0_funcs[] = { 2, 2 };
+
+static const int mt7988_i2c1_sfp_pins[] = { 5, 6 };
+static int mt7988_i2c1_sfp_funcs[] = { 4, 4 };
+
+static const int mt7988_xfi_pextp_phy0_i2c_pins[] = { 5, 6 };
+static int mt7988_xfi_pextp_phy0_i2c_funcs[] = { 5, 5 };
+
+static const int mt7988_xfi_pextp_phy1_i2c_pins[] = { 5, 6 };
+static int mt7988_xfi_pextp_phy1_i2c_funcs[] = { 6, 6 };
+
+static const int mt7988_i2c0_1_pins[] = { 15, 16 };
+static int mt7988_i2c0_1_funcs[] = { 1, 1 };
+
+static const int mt7988_u30_phy_i2c0_pins[] = { 15, 16 };
+static int mt7988_u30_phy_i2c0_funcs[] = { 2, 2 };
+
+static const int mt7988_u32_phy_i2c0_pins[] = { 15, 16 };
+static int mt7988_u32_phy_i2c0_funcs[] = { 3, 3 };
+
+static const int mt7988_xfi_phy0_i2c1_pins[] = { 15, 16 };
+static int mt7988_xfi_phy0_i2c1_funcs[] = { 5, 5 };
+
+static const int mt7988_xfi_phy1_i2c1_pins[] = { 15, 16 };
+static int mt7988_xfi_phy1_i2c1_funcs[] = { 6, 6 };
+
+static const int mt7988_xfi_phy_pll_i2c2_pins[] = { 15, 16 };
+static int mt7988_xfi_phy_pll_i2c2_funcs[] = { 7, 7 };
+
+static const int mt7988_i2c1_0_pins[] = { 17, 18 };
+static int mt7988_i2c1_0_funcs[] = { 1, 1 };
+
+static const int mt7988_u30_phy_i2c1_pins[] = { 17, 18 };
+static int mt7988_u30_phy_i2c1_funcs[] = { 2, 2 };
+
+static const int mt7988_u32_phy_i2c1_pins[] = { 17, 18 };
+static int mt7988_u32_phy_i2c1_funcs[] = { 3, 3 };
+
+static const int mt7988_xfi_phy_pll_i2c3_pins[] = { 17, 18 };
+static int mt7988_xfi_phy_pll_i2c3_funcs[] = { 4, 4 };
+
+static const int mt7988_sgmii0_i2c_pins[] = { 17, 18 };
+static int mt7988_sgmii0_i2c_funcs[] = { 5, 5 };
+
+static const int mt7988_sgmii1_i2c_pins[] = { 17, 18 };
+static int mt7988_sgmii1_i2c_funcs[] = { 6, 6 };
+
+static const int mt7988_i2c1_2_pins[] = { 69, 70 };
+static int mt7988_i2c1_2_funcs[] = { 2, 2 };
+
+static const int mt7988_i2c2_0_pins[] = { 69, 70 };
+static int mt7988_i2c2_0_funcs[] = { 4, 4 };
+
+static const int mt7988_i2c2_1_pins[] = { 71, 72 };
+static int mt7988_i2c2_1_funcs[] = { 1, 1 };
+
+/* eth */
+static const int mt7988_mdc_mdio0_pins[] = { 5, 6 };
+static int mt7988_mdc_mdio0_funcs[] = { 1, 1 };
+
+static const int mt7988_2p5g_ext_mdio_pins[] = { 28, 29 };
+static int mt7988_2p5g_ext_mdio_funcs[] = { 6, 6 };
+
+static const int mt7988_gbe_ext_mdio_pins[] = { 30, 31 };
+static int mt7988_gbe_ext_mdio_funcs[] = { 6, 6 };
+
+static const int mt7988_mdc_mdio1_pins[] = { 69, 70 };
+static int mt7988_mdc_mdio1_funcs[] = { 1, 1 };
+
+/* pcie */
+static const int mt7988_pcie_wake_n0_0_pins[] = { 7 };
+static int mt7988_pcie_wake_n0_0_funcs[] = { 1 };
+
+static const int mt7988_pcie_clk_req_n0_0_pins[] = { 8 };
+static int mt7988_pcie_clk_req_n0_0_funcs[] = { 1 };
+
+static const int mt7988_pcie_wake_n3_0_pins[] = { 9 };
+static int mt7988_pcie_wake_n3_0_funcs[] = { 1 };
+
+static const int mt7988_pcie_clk_req_n3_pins[] = { 10 };
+static int mt7988_pcie_clk_req_n3_funcs[] = { 1 };
+
+static const int mt7988_pcie_clk_req_n0_1_pins[] = { 10 };
+static int mt7988_pcie_clk_req_n0_1_funcs[] = { 2 };
+
+static const int mt7988_pcie_p0_phy_i2c_pins[] = { 7, 8 };
+static int mt7988_pcie_p0_phy_i2c_funcs[] = { 3, 3 };
+
+static const int mt7988_pcie_p1_phy_i2c_pins[] = { 7, 8 };
+static int mt7988_pcie_p1_phy_i2c_funcs[] = { 4, 4 };
+
+static const int mt7988_pcie_p3_phy_i2c_pins[] = { 9, 10 };
+static int mt7988_pcie_p3_phy_i2c_funcs[] = { 4, 4 };
+
+static const int mt7988_pcie_p2_phy_i2c_pins[] = { 7, 8 };
+static int mt7988_pcie_p2_phy_i2c_funcs[] = { 5, 5 };
+
+static const int mt7988_ckm_phy_i2c_pins[] = { 9, 10 };
+static int mt7988_ckm_phy_i2c_funcs[] = { 5, 5 };
+
+static const int mt7988_pcie_wake_n0_1_pins[] = { 13 };
+static int mt7988_pcie_wake_n0_1_funcs[] = { 2 };
+
+static const int mt7988_pcie_wake_n3_1_pins[] = { 14 };
+static int mt7988_pcie_wake_n3_1_funcs[] = { 2 };
+
+static const int mt7988_pcie_2l_0_pereset_pins[] = { 19 };
+static int mt7988_pcie_2l_0_pereset_funcs[] = { 1 };
+
+static const int mt7988_pcie_1l_1_pereset_pins[] = { 20 };
+static int mt7988_pcie_1l_1_pereset_funcs[] = { 1 };
+
+static const int mt7988_pcie_clk_req_n2_1_pins[] = { 63 };
+static int mt7988_pcie_clk_req_n2_1_funcs[] = { 2 };
+
+static const int mt7988_pcie_2l_1_pereset_pins[] = { 73 };
+static int mt7988_pcie_2l_1_pereset_funcs[] = { 1 };
+
+static const int mt7988_pcie_1l_0_pereset_pins[] = { 74 };
+static int mt7988_pcie_1l_0_pereset_funcs[] = { 1 };
+
+static const int mt7988_pcie_wake_n1_0_pins[] = { 75 };
+static int mt7988_pcie_wake_n1_0_funcs[] = { 1 };
+
+static const int mt7988_pcie_clk_req_n1_pins[] = { 76 };
+static int mt7988_pcie_clk_req_n1_funcs[] = { 1 };
+
+static const int mt7988_pcie_wake_n2_0_pins[] = { 77 };
+static int mt7988_pcie_wake_n2_0_funcs[] = { 1 };
+
+static const int mt7988_pcie_clk_req_n2_0_pins[] = { 78 };
+static int mt7988_pcie_clk_req_n2_0_funcs[] = { 1 };
+
+static const int mt7988_pcie_wake_n2_1_pins[] = { 79 };
+static int mt7988_pcie_wake_n2_1_funcs[] = { 2 };
+
+/* pmic */
+static const int mt7988_pmic_pins[] = { 11 };
+static int mt7988_pmic_funcs[] = { 1 };
+
+/* watchdog */
+static const int mt7988_watchdog_pins[] = { 12 };
+static int mt7988_watchdog_funcs[] = { 1 };
+
+/* spi */
+static const int mt7988_spi0_wp_hold_pins[] = { 22, 23 };
+static int mt7988_spi0_wp_hold_funcs[] = { 1, 1 };
+
+static const int mt7988_spi0_pins[] = { 24, 25, 26, 27 };
+static int mt7988_spi0_funcs[] = { 1, 1, 1, 1 };
+
+static const int mt7988_spi1_pins[] = { 28, 29, 30, 31 };
+static int mt7988_spi1_funcs[] = { 1, 1, 1, 1 };
+
+static const int mt7988_spi2_pins[] = { 32, 33, 34, 35 };
+static int mt7988_spi2_funcs[] = { 1, 1, 1, 1 };
+
+static const int mt7988_spi2_wp_hold_pins[] = { 36, 37 };
+static int mt7988_spi2_wp_hold_funcs[] = { 1, 1 };
+
+/* flash */
+static const int mt7988_snfi_pins[] = { 22, 23, 24, 25, 26, 27 };
+static int mt7988_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
+
+static const int mt7988_emmc_45_pins[] = {
+	21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
+};
+static int mt7988_emmc_45_funcs[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
+
+static const int mt7988_sdcard_pins[] = { 32, 33, 34, 35, 36, 37 };
+static int mt7988_sdcard_funcs[] = { 5, 5, 5, 5, 5, 5 };
+
+static const int mt7988_emmc_51_pins[] = { 38, 39, 40, 41, 42, 43,
+				     44, 45, 46, 47, 48, 49 };
+static int mt7988_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+
+/* uart */
+static const int mt7988_uart2_pins[] = { 0, 1, 2, 3 };
+static int mt7988_uart2_funcs[] = { 1, 1, 1, 1 };
+
+static const int mt7988_tops_uart0_0_pins[] = { 22, 23 };
+static int mt7988_tops_uart0_0_funcs[] = { 3, 3 };
+
+static const int mt7988_uart2_0_pins[] = { 28, 29, 30, 31 };
+static int mt7988_uart2_0_funcs[] = { 2, 2, 2, 2 };
+
+static const int mt7988_uart1_0_pins[] = { 32, 33, 34, 35 };
+static int mt7988_uart1_0_funcs[] = { 2, 2, 2, 2 };
+
+static const int mt7988_uart2_1_pins[] = { 32, 33, 34, 35 };
+static int mt7988_uart2_1_funcs[] = { 3, 3, 3, 3 };
+
+static const int mt7988_net_wo0_uart_txd_0_pins[] = { 28 };
+static int mt7988_net_wo0_uart_txd_0_funcs[] = { 3 };
+
+static const int mt7988_net_wo1_uart_txd_0_pins[] = { 29 };
+static int mt7988_net_wo1_uart_txd_0_funcs[] = { 3 };
+
+static const int mt7988_net_wo2_uart_txd_0_pins[] = { 30 };
+static int mt7988_net_wo2_uart_txd_0_funcs[] = { 3 };
+
+static const int mt7988_tops_uart1_0_pins[] = { 28, 29 };
+static int mt7988_tops_uart1_0_funcs[] = { 4, 4 };
+
+static const int mt7988_tops_uart0_1_pins[] = { 30, 31 };
+static int mt7988_tops_uart0_1_funcs[] = { 4, 4 };
+
+static const int mt7988_tops_uart1_1_pins[] = { 36, 37 };
+static int mt7988_tops_uart1_1_funcs[] = { 3, 3 };
+
+static const int mt7988_uart0_pins[] = { 55, 56 };
+static int mt7988_uart0_funcs[] = { 1, 1 };
+
+static const int mt7988_tops_uart0_2_pins[] = { 55, 56 };
+static int mt7988_tops_uart0_2_funcs[] = { 2, 2 };
+
+static const int mt7988_uart2_2_pins[] = { 50, 51, 52, 53 };
+static int mt7988_uart2_2_funcs[] = { 2, 2, 2, 2 };
+
+static const int mt7988_uart1_1_pins[] = { 58, 59, 60, 61 };
+static int mt7988_uart1_1_funcs[] = { 2, 2, 2, 2 };
+
+static const int mt7988_uart2_3_pins[] = { 58, 59, 60, 61 };
+static int mt7988_uart2_3_funcs[] = { 3, 3, 3, 3 };
+
+static const int mt7988_uart1_2_pins[] = { 80, 81, 82, 83 };
+static int mt7988_uart1_2_funcs[] = { 1, 1, 1, 1 };
+
+static const int mt7988_uart1_2_lite_pins[] = { 80, 81 };
+static int mt7988_uart1_2_lite_funcs[] = { 1, 1 };
+
+static const int mt7988_tops_uart1_2_pins[] = { 80, 81 };
+static int mt7988_tops_uart1_2_funcs[] = { 4, 4, };
+
+static const int mt7988_net_wo0_uart_txd_1_pins[] = { 80 };
+static int mt7988_net_wo0_uart_txd_1_funcs[] = { 3 };
+
+static const int mt7988_net_wo1_uart_txd_1_pins[] = { 81 };
+static int mt7988_net_wo1_uart_txd_1_funcs[] = { 3 };
+
+static const int mt7988_net_wo2_uart_txd_1_pins[] = { 82 };
+static int mt7988_net_wo2_uart_txd_1_funcs[] = { 3 };
+
+/* udi */
+static const int mt7988_udi_pins[] = { 32, 33, 34, 35, 36 };
+static int mt7988_udi_funcs[] = { 4, 4, 4, 4, 4 };
+
+/* i2s */
+static const int mt7988_i2s_pins[] = { 50, 51, 52, 53, 54 };
+static int mt7988_i2s_funcs[] = { 1, 1, 1, 1, 1 };
+
+/* pcm */
+static const int mt7988_pcm_pins[] = { 50, 51, 52, 53 };
+static int mt7988_pcm_funcs[] = { 1, 1, 1, 1 };
+
+/* led */
+static const int mt7988_gbe0_led1_pins[] = { 58 };
+static int mt7988_gbe0_led1_funcs[] = { 6 };
+static const int mt7988_gbe1_led1_pins[] = { 59 };
+static int mt7988_gbe1_led1_funcs[] = { 6 };
+static const int mt7988_gbe2_led1_pins[] = { 60 };
+static int mt7988_gbe2_led1_funcs[] = { 6 };
+static const int mt7988_gbe3_led1_pins[] = { 61 };
+static int mt7988_gbe3_led1_funcs[] = { 6 };
+
+static const int mt7988_2p5gbe_led1_pins[] = { 62 };
+static int mt7988_2p5gbe_led1_funcs[] = { 6 };
+
+static const int mt7988_gbe0_led0_pins[] = { 64 };
+static int mt7988_gbe0_led0_funcs[] = { 1 };
+static const int mt7988_gbe1_led0_pins[] = { 65 };
+static int mt7988_gbe1_led0_funcs[] = { 1 };
+static const int mt7988_gbe2_led0_pins[] = { 66 };
+static int mt7988_gbe2_led0_funcs[] = { 1 };
+static const int mt7988_gbe3_led0_pins[] = { 67 };
+static int mt7988_gbe3_led0_funcs[] = { 1 };
+
+static const int mt7988_2p5gbe_led0_pins[] = { 68 };
+static int mt7988_2p5gbe_led0_funcs[] = { 1 };
+
+/* usb */
+static const int mt7988_drv_vbus_p1_pins[] = { 63 };
+static int mt7988_drv_vbus_p1_funcs[] = { 1 };
+
+static const int mt7988_drv_vbus_pins[] = { 79 };
+static int mt7988_drv_vbus_funcs[] = { 1 };
+
+static const struct group_desc mt7988_groups[] = {
+	/*  @GPIO(0,1,2,3): uart2 */
+	PINCTRL_PIN_GROUP("uart2", mt7988_uart2),
+	/*  @GPIO(0,1,2,3,4): tops_jtag0_0 */
+	PINCTRL_PIN_GROUP("tops_jtag0_0", mt7988_tops_jtag0_0),
+	/*  @GPIO(2,3): int_usxgmii */
+	PINCTRL_PIN_GROUP("int_usxgmii", mt7988_int_usxgmii),
+	/*  @GPIO(0,1,2,3,4): dfd */
+	PINCTRL_PIN_GROUP("dfd", mt7988_dfd),
+	/*  @GPIO(0,1): xfi_phy0_i2c0 */
+	PINCTRL_PIN_GROUP("xfi_phy0_i2c0", mt7988_xfi_phy0_i2c0),
+	/*  @GPIO(0,1): xfi_phy1_i2c0 */
+	PINCTRL_PIN_GROUP("xfi_phy1_i2c0", mt7988_xfi_phy1_i2c0),
+	/*  @GPIO(3,4): xfi_phy_pll_i2c0 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c0", mt7988_xfi_phy_pll_i2c0),
+	/*  @GPIO(3,4): xfi_phy_pll_i2c1 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c1", mt7988_xfi_phy_pll_i2c1),
+	/*  @GPIO(4): pwm7 */
+	PINCTRL_PIN_GROUP("pwm7_0", mt7988_pwm7_0),
+	/*  @GPIO(5,6) i2c0_0 */
+	PINCTRL_PIN_GROUP("i2c0_0", mt7988_i2c0_0),
+	/*  @GPIO(5,6) i2c1_sfp */
+	PINCTRL_PIN_GROUP("i2c1_sfp", mt7988_i2c1_sfp),
+	/*  @GPIO(5,6) xfi_pextp_phy0_i2c */
+	PINCTRL_PIN_GROUP("xfi_pextp_phy0_i2c", mt7988_xfi_pextp_phy0_i2c),
+	/*  @GPIO(5,6) xfi_pextp_phy1_i2c */
+	PINCTRL_PIN_GROUP("xfi_pextp_phy1_i2c", mt7988_xfi_pextp_phy1_i2c),
+	/*  @GPIO(5,6) mdc_mdio0 */
+	PINCTRL_PIN_GROUP("mdc_mdio0", mt7988_mdc_mdio0),
+	/*  @GPIO(7): pcie_wake_n0_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n0_0", mt7988_pcie_wake_n0_0),
+	/*  @GPIO(8): pcie_clk_req_n0_0 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n0_0", mt7988_pcie_clk_req_n0_0),
+	/*  @GPIO(9): pcie_wake_n3_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n3_0", mt7988_pcie_wake_n3_0),
+	/*  @GPIO(10): pcie_clk_req_n3 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n3", mt7988_pcie_clk_req_n3),
+	/*  @GPIO(10): pcie_clk_req_n0_1 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n0_1", mt7988_pcie_clk_req_n0_1),
+	/*  @GPIO(7,8) pcie_p0_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p0_phy_i2c", mt7988_pcie_p0_phy_i2c),
+	/*  @GPIO(7,8) pcie_p1_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p1_phy_i2c", mt7988_pcie_p1_phy_i2c),
+	/*  @GPIO(7,8) pcie_p2_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p2_phy_i2c", mt7988_pcie_p2_phy_i2c),
+	/*  @GPIO(9,10) pcie_p3_phy_i2c */
+	PINCTRL_PIN_GROUP("pcie_p3_phy_i2c", mt7988_pcie_p3_phy_i2c),
+	/*  @GPIO(9,10) ckm_phy_i2c */
+	PINCTRL_PIN_GROUP("ckm_phy_i2c", mt7988_ckm_phy_i2c),
+	/*  @GPIO(11): pmic */
+	PINCTRL_PIN_GROUP("pcie_pmic", mt7988_pmic),
+	/*  @GPIO(12): watchdog */
+	PINCTRL_PIN_GROUP("watchdog", mt7988_watchdog),
+	/*  @GPIO(13): pcie_wake_n0_1 */
+	PINCTRL_PIN_GROUP("pcie_wake_n0_1", mt7988_pcie_wake_n0_1),
+	/*  @GPIO(14): pcie_wake_n3_1 */
+	PINCTRL_PIN_GROUP("pcie_wake_n3_1", mt7988_pcie_wake_n3_1),
+	/*  @GPIO(15,16) i2c0_1 */
+	PINCTRL_PIN_GROUP("i2c0_1", mt7988_i2c0_1),
+	/*  @GPIO(15,16) u30_phy_i2c0 */
+	PINCTRL_PIN_GROUP("u30_phy_i2c0", mt7988_u30_phy_i2c0),
+	/*  @GPIO(15,16) u32_phy_i2c0 */
+	PINCTRL_PIN_GROUP("u32_phy_i2c0", mt7988_u32_phy_i2c0),
+	/*  @GPIO(15,16) xfi_phy0_i2c1 */
+	PINCTRL_PIN_GROUP("xfi_phy0_i2c1", mt7988_xfi_phy0_i2c1),
+	/*  @GPIO(15,16) xfi_phy1_i2c1 */
+	PINCTRL_PIN_GROUP("xfi_phy1_i2c1", mt7988_xfi_phy1_i2c1),
+	/*  @GPIO(15,16) xfi_phy_pll_i2c2 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c2", mt7988_xfi_phy_pll_i2c2),
+	/*  @GPIO(17,18) i2c1_0 */
+	PINCTRL_PIN_GROUP("i2c1_0", mt7988_i2c1_0),
+	/*  @GPIO(17,18) u30_phy_i2c1 */
+	PINCTRL_PIN_GROUP("u30_phy_i2c1", mt7988_u30_phy_i2c1),
+	/*  @GPIO(17,18) u32_phy_i2c1 */
+	PINCTRL_PIN_GROUP("u32_phy_i2c1", mt7988_u32_phy_i2c1),
+	/*  @GPIO(17,18) xfi_phy_pll_i2c3 */
+	PINCTRL_PIN_GROUP("xfi_phy_pll_i2c3", mt7988_xfi_phy_pll_i2c3),
+	/*  @GPIO(17,18) sgmii0_i2c */
+	PINCTRL_PIN_GROUP("sgmii0_i2c", mt7988_sgmii0_i2c),
+	/*  @GPIO(17,18) sgmii1_i2c */
+	PINCTRL_PIN_GROUP("sgmii1_i2c", mt7988_sgmii1_i2c),
+	/*  @GPIO(19): pcie_2l_0_pereset */
+	PINCTRL_PIN_GROUP("pcie_2l_0_pereset", mt7988_pcie_2l_0_pereset),
+	/*  @GPIO(20): pcie_1l_1_pereset */
+	PINCTRL_PIN_GROUP("pcie_1l_1_pereset", mt7988_pcie_1l_1_pereset),
+	/*  @GPIO(21): pwm1 */
+	PINCTRL_PIN_GROUP("pwm1", mt7988_pwm1),
+	/*  @GPIO(22,23) spi0_wp_hold */
+	PINCTRL_PIN_GROUP("spi0_wp_hold", mt7988_spi0_wp_hold),
+	/*  @GPIO(24,25,26,27) spi0 */
+	PINCTRL_PIN_GROUP("spi0", mt7988_spi0),
+	/*  @GPIO(28,29,30,31) spi1 */
+	PINCTRL_PIN_GROUP("spi1", mt7988_spi1),
+	/*  @GPIO(32,33,34,35) spi2 */
+	PINCTRL_PIN_GROUP("spi2", mt7988_spi2),
+	/*  @GPIO(36,37) spi2_wp_hold */
+	PINCTRL_PIN_GROUP("spi2_wp_hold", mt7988_spi2_wp_hold),
+	/*  @GPIO(22,23,24,25,26,27) snfi */
+	PINCTRL_PIN_GROUP("snfi", mt7988_snfi),
+	/*  @GPIO(22,23) tops_uart0_0 */
+	PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart0_0),
+	/*  @GPIO(28,29,30,31) uart2_0 */
+	PINCTRL_PIN_GROUP("uart2_0", mt7988_uart2_0),
+	/*  @GPIO(32,33,34,35) uart1_0 */
+	PINCTRL_PIN_GROUP("uart1_0", mt7988_uart1_0),
+	/*  @GPIO(32,33,34,35) uart2_1 */
+	PINCTRL_PIN_GROUP("uart2_1", mt7988_uart2_1),
+	/*  @GPIO(28) net_wo0_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
+	/*  @GPIO(29) net_wo1_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
+	/*  @GPIO(30) net_wo2_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
+	/*  @GPIO(28,29) tops_uart1_0 */
+	PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart1_0),
+	/*  @GPIO(30,31) tops_uart0_1 */
+	PINCTRL_PIN_GROUP("tops_uart0_1", mt7988_tops_uart0_1),
+	/*  @GPIO(36,37) tops_uart1_1 */
+	PINCTRL_PIN_GROUP("tops_uart1_1", mt7988_tops_uart1_1),
+	/*  @GPIO(32,33,34,35,36) udi */
+	PINCTRL_PIN_GROUP("udi", mt7988_udi),
+	/*  @GPIO(21,28,29,30,31,32,33,34,35,36,37) emmc_45 */
+	PINCTRL_PIN_GROUP("emmc_45", mt7988_emmc_45),
+	/*  @GPIO(32,33,34,35,36,37) sdcard */
+	PINCTRL_PIN_GROUP("sdcard", mt7988_sdcard),
+	/*  @GPIO(38,39,40,41,42,43,44,45,46,47,48,49) emmc_51 */
+	PINCTRL_PIN_GROUP("emmc_51", mt7988_emmc_51),
+	/*  @GPIO(28,29) 2p5g_ext_mdio */
+	PINCTRL_PIN_GROUP("2p5g_ext_mdio", mt7988_2p5g_ext_mdio),
+	/*  @GPIO(30,31) gbe_ext_mdio */
+	PINCTRL_PIN_GROUP("gbe_ext_mdio", mt7988_gbe_ext_mdio),
+	/*  @GPIO(50,51,52,53,54) i2s */
+	PINCTRL_PIN_GROUP("i2s", mt7988_i2s),
+	/*  @GPIO(50,51,52,53) pcm */
+	PINCTRL_PIN_GROUP("pcm", mt7988_pcm),
+	/*  @GPIO(55,56) uart0 */
+	PINCTRL_PIN_GROUP("uart0", mt7988_uart0),
+	/*  @GPIO(55,56) tops_uart0_2 */
+	PINCTRL_PIN_GROUP("tops_uart0_2", mt7988_tops_uart0_2),
+	/*  @GPIO(50,51,52,53) uart2_2 */
+	PINCTRL_PIN_GROUP("uart2_2", mt7988_uart2_2),
+	/*  @GPIO(50,51,52,53,54) wo0_jtag */
+	PINCTRL_PIN_GROUP("wo0_jtag", mt7988_wo0_jtag),
+	/*  @GPIO(50,51,52,53,54) wo1-wo1_jtag */
+	PINCTRL_PIN_GROUP("wo1_jtag", mt7988_wo1_jtag),
+	/*  @GPIO(50,51,52,53,54) wo2_jtag */
+	PINCTRL_PIN_GROUP("wo2_jtag", mt7988_wo2_jtag),
+	/*  @GPIO(57) pwm0 */
+	PINCTRL_PIN_GROUP("pwm0", mt7988_pwm0),
+	/*  @GPIO(58) pwm2_0 */
+	PINCTRL_PIN_GROUP("pwm2_0", mt7988_pwm2_0),
+	/*  @GPIO(59) pwm3_0 */
+	PINCTRL_PIN_GROUP("pwm3_0", mt7988_pwm3_0),
+	/*  @GPIO(60) pwm4_0 */
+	PINCTRL_PIN_GROUP("pwm4_0", mt7988_pwm4_0),
+	/*  @GPIO(61) pwm5_0 */
+	PINCTRL_PIN_GROUP("pwm5_0", mt7988_pwm5_0),
+	/*  @GPIO(58,59,60,61,62) jtag */
+	PINCTRL_PIN_GROUP("jtag", mt7988_jtag),
+	/*  @GPIO(58,59,60,61,62) tops_jtag0_1 */
+	PINCTRL_PIN_GROUP("tops_jtag0_1", mt7988_tops_jtag0_1),
+	/*  @GPIO(58,59,60,61) uart2_3 */
+	PINCTRL_PIN_GROUP("uart2_3", mt7988_uart2_3),
+	/*  @GPIO(58,59,60,61) uart1_1 */
+	PINCTRL_PIN_GROUP("uart1_1", mt7988_uart1_1),
+	/*  @GPIO(58,59,60,61) gbe_led1 */
+	PINCTRL_PIN_GROUP("gbe0_led1", mt7988_gbe0_led1),
+	PINCTRL_PIN_GROUP("gbe1_led1", mt7988_gbe1_led1),
+	PINCTRL_PIN_GROUP("gbe2_led1", mt7988_gbe2_led1),
+	PINCTRL_PIN_GROUP("gbe3_led1", mt7988_gbe3_led1),
+	/*  @GPIO(62) pwm6_0 */
+	PINCTRL_PIN_GROUP("pwm6_0", mt7988_pwm6_0),
+	/*  @GPIO(62) 2p5gbe_led1 */
+	PINCTRL_PIN_GROUP("2p5gbe_led1", mt7988_2p5gbe_led1),
+	/*  @GPIO(64,65,66,67) gbe_led0 */
+	PINCTRL_PIN_GROUP("gbe0_led0", mt7988_gbe0_led0),
+	PINCTRL_PIN_GROUP("gbe1_led0", mt7988_gbe1_led0),
+	PINCTRL_PIN_GROUP("gbe2_led0", mt7988_gbe2_led0),
+	PINCTRL_PIN_GROUP("gbe3_led0", mt7988_gbe3_led0),
+	/*  @GPIO(68) 2p5gbe_led0 */
+	PINCTRL_PIN_GROUP("2p5gbe_led0", mt7988_2p5gbe_led0),
+	/*  @GPIO(63) drv_vbus_p1 */
+	PINCTRL_PIN_GROUP("drv_vbus_p1", mt7988_drv_vbus_p1),
+	/*  @GPIO(63) pcie_clk_req_n2_1 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n2_1", mt7988_pcie_clk_req_n2_1),
+	/*  @GPIO(69, 70) mdc_mdio1 */
+	PINCTRL_PIN_GROUP("mdc_mdio1", mt7988_mdc_mdio1),
+	/*  @GPIO(69, 70) i2c1_2 */
+	PINCTRL_PIN_GROUP("i2c1_2", mt7988_i2c1_2),
+	/*  @GPIO(69) pwm6 */
+	PINCTRL_PIN_GROUP("pwm6", mt7988_pwm6),
+	/*  @GPIO(70) pwm7 */
+	PINCTRL_PIN_GROUP("pwm7", mt7988_pwm7),
+	/*  @GPIO(69,70) i2c2_0 */
+	PINCTRL_PIN_GROUP("i2c2_0", mt7988_i2c2_0),
+	/*  @GPIO(71,72) i2c2_1 */
+	PINCTRL_PIN_GROUP("i2c2_1", mt7988_i2c2_1),
+	/*  @GPIO(73) pcie_2l_1_pereset */
+	PINCTRL_PIN_GROUP("pcie_2l_1_pereset", mt7988_pcie_2l_1_pereset),
+	/*  @GPIO(74) pcie_1l_0_pereset */
+	PINCTRL_PIN_GROUP("pcie_1l_0_pereset", mt7988_pcie_1l_0_pereset),
+	/*  @GPIO(75) pcie_wake_n1_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n1_0", mt7988_pcie_wake_n1_0),
+	/*  @GPIO(76) pcie_clk_req_n1 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n1", mt7988_pcie_clk_req_n1),
+	/*  @GPIO(77) pcie_wake_n2_0 */
+	PINCTRL_PIN_GROUP("pcie_wake_n2_0", mt7988_pcie_wake_n2_0),
+	/*  @GPIO(78) pcie_clk_req_n2_0 */
+	PINCTRL_PIN_GROUP("pcie_clk_req_n2_0", mt7988_pcie_clk_req_n2_0),
+	/*  @GPIO(79) drv_vbus */
+	PINCTRL_PIN_GROUP("drv_vbus", mt7988_drv_vbus),
+	/*  @GPIO(79) pcie_wake_n2_1 */
+	PINCTRL_PIN_GROUP("pcie_wake_n2_1", mt7988_pcie_wake_n2_1),
+	/*  @GPIO(80,81,82,83) uart1_2 */
+	PINCTRL_PIN_GROUP("uart1_2", mt7988_uart1_2),
+	/*  @GPIO(80,81) uart1_2_lite */
+	PINCTRL_PIN_GROUP("uart1_2_lite", mt7988_uart1_2_lite),
+	/*  @GPIO(80) pwm2 */
+	PINCTRL_PIN_GROUP("pwm2", mt7988_pwm2),
+	/*  @GPIO(81) pwm3 */
+	PINCTRL_PIN_GROUP("pwm3", mt7988_pwm3),
+	/*  @GPIO(82) pwm4 */
+	PINCTRL_PIN_GROUP("pwm4", mt7988_pwm4),
+	/*  @GPIO(83) pwm5 */
+	PINCTRL_PIN_GROUP("pwm5", mt7988_pwm5),
+	/*  @GPIO(80) net_wo0_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
+	/*  @GPIO(81) net_wo1_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
+	/*  @GPIO(82) net_wo2_uart_txd_0 */
+	PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
+	/*  @GPIO(80,81) tops_uart1_2 */
+	PINCTRL_PIN_GROUP("tops_uart1_2", mt7988_tops_uart1_2),
+	/*  @GPIO(80) net_wo0_uart_txd_1 */
+	PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7988_net_wo0_uart_txd_1),
+	/*  @GPIO(81) net_wo1_uart_txd_1 */
+	PINCTRL_PIN_GROUP("net_wo1_uart_txd_1", mt7988_net_wo1_uart_txd_1),
+	/*  @GPIO(82) net_wo2_uart_txd_1 */
+	PINCTRL_PIN_GROUP("net_wo2_uart_txd_1", mt7988_net_wo2_uart_txd_1),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+static const char * const mt7988_jtag_groups[] = {
+	"tops_jtag0_0", "wo0_jtag", "wo1_jtag",
+	"wo2_jtag",	"jtag",	    "tops_jtag0_1",
+};
+static const char * const mt7988_int_usxgmii_groups[] = {
+	"int_usxgmii",
+};
+static const char * const mt7988_pwm_groups[] = {
+	"pwm0", "pwm1", "pwm2", "pwm2_0", "pwm3", "pwm3_0", "pwm4", "pwm4_0",
+	"pwm5", "pwm5_0", "pwm6", "pwm6_0", "pwm7", "pwm7_0",
+
+};
+static const char * const mt7988_dfd_groups[] = {
+	"dfd",
+};
+static const char * const mt7988_i2c_groups[] = {
+	"xfi_phy0_i2c0",
+	"xfi_phy1_i2c0",
+	"xfi_phy_pll_i2c0",
+	"xfi_phy_pll_i2c1",
+	"i2c0_0",
+	"i2c1_sfp",
+	"xfi_pextp_phy0_i2c",
+	"xfi_pextp_phy1_i2c",
+	"i2c0_1",
+	"u30_phy_i2c0",
+	"u32_phy_i2c0",
+	"xfi_phy0_i2c1",
+	"xfi_phy1_i2c1",
+	"xfi_phy_pll_i2c2",
+	"i2c1_0",
+	"u30_phy_i2c1",
+	"u32_phy_i2c1",
+	"xfi_phy_pll_i2c3",
+	"sgmii0_i2c",
+	"sgmii1_i2c",
+	"i2c1_2",
+	"i2c2_0",
+	"i2c2_1",
+};
+static const char * const mt7988_ethernet_groups[] = {
+	"mdc_mdio0",
+	"2p5g_ext_mdio",
+	"gbe_ext_mdio",
+	"mdc_mdio1",
+};
+static const char * const mt7988_pcie_groups[] = {
+	"pcie_wake_n0_0",    "pcie_clk_req_n0_0", "pcie_wake_n3_0",
+	"pcie_clk_req_n3",   "pcie_p0_phy_i2c",	  "pcie_p1_phy_i2c",
+	"pcie_p3_phy_i2c",   "pcie_p2_phy_i2c",	  "ckm_phy_i2c",
+	"pcie_wake_n0_1",    "pcie_wake_n3_1",	  "pcie_2l_0_pereset",
+	"pcie_1l_1_pereset", "pcie_clk_req_n2_1", "pcie_2l_1_pereset",
+	"pcie_1l_0_pereset", "pcie_wake_n1_0",	  "pcie_clk_req_n1",
+	"pcie_wake_n2_0",    "pcie_clk_req_n2_0", "pcie_wake_n2_1",
+	"pcie_clk_req_n0_1"
+};
+static const char * const mt7988_pmic_groups[] = {
+	"pmic",
+};
+static const char * const mt7988_wdt_groups[] = {
+	"watchdog",
+};
+static const char * const mt7988_spi_groups[] = {
+	"spi0", "spi0_wp_hold", "spi1", "spi2", "spi2_wp_hold",
+};
+static const char * const mt7988_flash_groups[] = { "emmc_45", "sdcard", "snfi",
+						    "emmc_51" };
+static const char * const mt7988_uart_groups[] = {
+	"uart2",
+	"tops_uart0_0",
+	"uart2_0",
+	"uart1_0",
+	"uart2_1",
+	"net_wo0_uart_txd_0",
+	"net_wo1_uart_txd_0",
+	"net_wo2_uart_txd_0",
+	"tops_uart1_0",
+	"ops_uart0_1",
+	"ops_uart1_1",
+	"uart0",
+	"tops_uart0_2",
+	"uart1_1",
+	"uart2_3",
+	"uart1_2",
+	"uart1_2_lite",
+	"tops_uart1_2",
+	"net_wo0_uart_txd_1",
+	"net_wo1_uart_txd_1",
+	"net_wo2_uart_txd_1",
+};
+static const char * const mt7988_udi_groups[] = {
+	"udi",
+};
+static const char * const mt7988_audio_groups[] = {
+	"i2s", "pcm",
+};
+static const char * const mt7988_led_groups[] = {
+	"gbe0_led1", "gbe1_led1", "gbe2_led1", "gbe3_led1", "2p5gbe_led1",
+	"gbe0_led0", "gbe1_led0", "gbe2_led0", "gbe3_led0", "2p5gbe_led0",
+	"wf5g_led0",   "wf5g_led1",
+};
+static const char * const mt7988_usb_groups[] = {
+	"drv_vbus",
+	"drv_vbus_p1",
+};
+
+static const struct function_desc mt7988_functions[] = {
+	{ { "audio", mt7988_audio_groups, ARRAY_SIZE(mt7988_audio_groups) },
+	  NULL },
+	{ { "jtag", mt7988_jtag_groups, ARRAY_SIZE(mt7988_jtag_groups) },
+	  NULL },
+	{ { "int_usxgmii", mt7988_int_usxgmii_groups,
+	    ARRAY_SIZE(mt7988_int_usxgmii_groups) },
+	  NULL },
+	{ { "pwm", mt7988_pwm_groups, ARRAY_SIZE(mt7988_pwm_groups) }, NULL },
+	{ { "dfd", mt7988_dfd_groups, ARRAY_SIZE(mt7988_dfd_groups) }, NULL },
+	{ { "i2c", mt7988_i2c_groups, ARRAY_SIZE(mt7988_i2c_groups) }, NULL },
+	{ { "eth", mt7988_ethernet_groups, ARRAY_SIZE(mt7988_ethernet_groups) },
+	  NULL },
+	{ { "pcie", mt7988_pcie_groups, ARRAY_SIZE(mt7988_pcie_groups) },
+	  NULL },
+	{ { "pmic", mt7988_pmic_groups, ARRAY_SIZE(mt7988_pmic_groups) },
+	  NULL },
+	{ { "watchdog", mt7988_wdt_groups, ARRAY_SIZE(mt7988_wdt_groups) },
+	  NULL },
+	{ { "spi", mt7988_spi_groups, ARRAY_SIZE(mt7988_spi_groups) }, NULL },
+	{ { "flash", mt7988_flash_groups, ARRAY_SIZE(mt7988_flash_groups) },
+	  NULL },
+	{ { "uart", mt7988_uart_groups, ARRAY_SIZE(mt7988_uart_groups) },
+	  NULL },
+	{ { "udi", mt7988_udi_groups, ARRAY_SIZE(mt7988_udi_groups) }, NULL },
+	{ { "usb", mt7988_usb_groups, ARRAY_SIZE(mt7988_usb_groups) }, NULL },
+	{ { "led", mt7988_led_groups, ARRAY_SIZE(mt7988_led_groups) }, NULL },
+};
+
+static const struct mtk_eint_hw mt7988_eint_hw = {
+	.port_mask = 7,
+	.ports = 7,
+	.ap_num = ARRAY_SIZE(mt7988_pins),
+	.db_cnt = 16,
+};
+
+static const char * const mt7988_pinctrl_register_base_names[] = {
+	"gpio",	 "iocfg_tr", "iocfg_br",
+	"iocfg_rb", "iocfg_lb", "iocfg_tl",
+};
+
+static const struct mtk_pin_soc mt7988_data = {
+	.reg_cal = mt7988_reg_cals,
+	.pins = mt7988_pins,
+	.npins = ARRAY_SIZE(mt7988_pins),
+	.grps = mt7988_groups,
+	.ngrps = ARRAY_SIZE(mt7988_groups),
+	.funcs = mt7988_functions,
+	.nfuncs = ARRAY_SIZE(mt7988_functions),
+	.eint_hw = &mt7988_eint_hw,
+	.gpio_m = 0,
+	.ies_present = false,
+	.base_names = mt7988_pinctrl_register_base_names,
+	.nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
+	.bias_disable_set = mtk_pinconf_bias_disable_set,
+	.bias_disable_get = mtk_pinconf_bias_disable_get,
+	.bias_set = mtk_pinconf_bias_set,
+	.bias_get = mtk_pinconf_bias_get,
+	.pull_type = mt7988_pull_type,
+	.bias_set_combo = mtk_pinconf_bias_set_combo,
+	.bias_get_combo = mtk_pinconf_bias_get_combo,
+	.drive_set = mtk_pinconf_drive_set_rev1,
+	.drive_get = mtk_pinconf_drive_get_rev1,
+	.adv_pull_get = mtk_pinconf_adv_pull_get,
+	.adv_pull_set = mtk_pinconf_adv_pull_set,
+};
+
+static const struct of_device_id mt7988_pinctrl_of_match[] = {
+	{ .compatible = "mediatek,mt7988-pinctrl" },
+	{}
+};
+
+static int mt7988_pinctrl_probe(struct platform_device *pdev)
+{
+	return mtk_moore_pinctrl_probe(pdev, &mt7988_data);
+}
+
+static struct platform_driver mt7988_pinctrl_driver = {
+	.driver = {
+		.name = "mt7988-pinctrl",
+		.of_match_table = mt7988_pinctrl_of_match,
+	},
+	.probe = mt7988_pinctrl_probe,
+};
+
+static int __init mt7988_pinctrl_init(void)
+{
+	return platform_driver_register(&mt7988_pinctrl_driver);
+}
+arch_initcall(mt7988_pinctrl_init);
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 00:54:29 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 09:54:29 +0100
Subject: [PATCH v7 4/5] arm64: dts: mediatek: mt7988: Add pinctrl support
In-Reply-To: <20241217085435.9586-1-linux@fw-web.de>
References: <20241217085435.9586-1-linux@fw-web.de>
Message-ID: <20241217085435.9586-5-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add mt7988a pinctrl node.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v5:
- drop pins with second function

v2:
- fix wrong alignment of reg values
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 54 +++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index c9649b815276..46969577c87a 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -3,6 +3,7 @@
 #include <dt-bindings/clock/mediatek,mt7988-clk.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
 
 / {
 	compatible = "mediatek,mt7988a";
@@ -105,6 +106,59 @@ clock-controller at 1001e000 {
 			#clock-cells = <1>;
 		};
 
+		pio: pinctrl at 1001f000 {
+			compatible = "mediatek,mt7988-pinctrl";
+			reg = <0 0x1001f000 0 0x1000>,
+			      <0 0x11c10000 0 0x1000>,
+			      <0 0x11d00000 0 0x1000>,
+			      <0 0x11d20000 0 0x1000>,
+			      <0 0x11e00000 0 0x1000>,
+			      <0 0x11f00000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "gpio", "iocfg_tr",
+				    "iocfg_br", "iocfg_rb",
+				    "iocfg_lb", "iocfg_tl", "eint";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pio 0 0 84>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&gic>;
+			#interrupt-cells = <2>;
+
+			pcie0_pins: pcie0-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
+						 "pcie_wake_n0_0";
+				};
+			};
+
+			pcie1_pins: pcie1-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
+						 "pcie_wake_n1_0";
+				};
+			};
+
+			pcie2_pins: pcie2-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
+						 "pcie_wake_n2_0";
+				};
+			};
+
+			pcie3_pins: pcie3-pins {
+				mux {
+					function = "pcie";
+					groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
+						 "pcie_wake_n3_0";
+				};
+			};
+		};
+
 		pwm at 10048000 {
 			compatible = "mediatek,mt7988-pwm";
 			reg = <0 0x10048000 0 0x1000>;
-- 
2.43.0



From ping.bai at nxp.com  Tue Dec 17 00:55:39 2024
From: ping.bai at nxp.com (Jacky Bai)
Date: Tue, 17 Dec 2024 08:55:39 +0000
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <bx3r4cs3oklfduvkg65vke3clb3fc6sseske2ellq27ifpmsnm@msz6iqvjwufn>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
 <bx3r4cs3oklfduvkg65vke3clb3fc6sseske2ellq27ifpmsnm@msz6iqvjwufn>
Message-ID: <AS8PR04MB8642D11477A37E75BAB71F3087042@AS8PR04MB8642.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
> 
> On Thu, Dec 12, 2024 at 05:35:55PM +0800, Jacky Bai wrote:
> > The i.MX 943 applications processors integrate up to four Arm Cortex
> > A55 cores and supports functional safety with built-in 2x Arm Cortex
> > M33 and M7 cores which can be configured asa safety island. Optimizing
> > performance and power efficiency for Industrial, IoT and automotive
> > devices, i.MX 943 processors are built with NXP?s innovative Energy
> > Flex architecture.
> >
> > This patch adds the minimal dtsi support for i.MX943 with peripherals
> > like uart, edma, i2c, spi, mu, sai etc.
> >
> > Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/imx943-clock.h  |  196 +++
> > .../arm64/boot/dts/freescale/imx943-pinfunc.h | 1542
> +++++++++++++++++
> >  arch/arm64/boot/dts/freescale/imx943-power.h  |   41 +
> >  arch/arm64/boot/dts/freescale/imx943.dtsi     | 1284
> ++++++++++++++
> 
> No, this is untested, uncompilable.
> 
> We do not add dead code to the kernel. You need users.

Board dts was planned for later. Will include the minimal board dts part in v2.

> 
> >  4 files changed, 3063 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943-clock.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943-pinfunc.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943-power.h
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx943.dtsi
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx943-clock.h
> > b/arch/arm64/boot/dts/freescale/imx943-clock.h

...

> > +#define IMX943_CLK_EXT2				45
> > +
> > +#define IMX943_CLK_NUM_SRC			46
> 
> Drop and all other clock numbers like that.

Ok, will fix in v2.

> 
> ...
> 
> > +#include <dt-bindings/dma/fsl-edma.h> #include
> > +<dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h>
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +
> > +#include "imx943-clock.h"
> > +#include "imx943-pinfunc.h"
> > +#include "imx943-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>;
> > +			};
> > +		};
> > +
> > +		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_perf IMX943_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 {
> 
> labels are always lowercase.

Thx, will fix in v2.

> 
> > +			device_type = "cpu";

...

> > +			edma2: dma-controller at 42000000 {
> > +				compatible = "fsl,imx95-edma5";
> 
> imx943 or imx95?
> 

Compatible with imx95, so I did not add new redundant dt binding entry.

BR

> Best regards,
> Krzysztof


From tabba at google.com  Tue Dec 17 00:56:40 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:56:40 +0000
Subject: [PATCH v3 13/18] KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
In-Reply-To: <20241216175803.2716565-14-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-14-qperret@google.com>
Message-ID: <CA+EHjTzMOOkcX7GRtUZNDT5cbH5uXbu1ATgAhRq5DZV_Ev5=sw@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> Introduce a new hypercall to remove the write permission from a
> non-protected guest stage-2 mapping. This will be used for e.g. enabling
> dirty logging.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad


> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 21 +++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 +++++++++++++++++
>  4 files changed, 42 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 66ee8542dcc9..8663a588cf34 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -68,6 +68,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index a308dcd3b5b8..fc9fdd5b0a52 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -42,6 +42,7 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
>  int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>  int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
> +int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 287e4ee93ef2..98d317735107 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -283,6 +283,26 @@ static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *host_ct
>         cpu_reg(host_ctxt, 1) = ret;
>  }
>
> +static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> +       struct pkvm_hyp_vm *hyp_vm;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vm = get_np_pkvm_hyp_vm(handle);
> +       if (!hyp_vm)
> +               goto out;
> +
> +       ret = __pkvm_host_wrprotect_guest(gfn, hyp_vm);
> +       put_pkvm_hyp_vm(hyp_vm);
> +out:
> +       cpu_reg(host_ctxt, 1) = ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -495,6 +515,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_share_guest),
>         HANDLE_FUNC(__pkvm_host_unshare_guest),
>         HANDLE_FUNC(__pkvm_host_relax_perms_guest),
> +       HANDLE_FUNC(__pkvm_host_wrprotect_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index aa8e0408aebb..94e4251b5077 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1511,3 +1511,22 @@ int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_
>
>         return ret;
>  }
> +
> +int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
> +{
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       u64 phys;
> +       int ret;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __check_host_shared_guest(vm, &phys, ipa);
> +       if (!ret)
> +               ret = kvm_pgtable_stage2_wrprotect(&vm->pgt, ipa, PAGE_SIZE);
> +
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 00:57:17 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:57:17 +0000
Subject: [PATCH v3 12/18] KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
In-Reply-To: <20241216175803.2716565-13-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-13-qperret@google.com>
Message-ID: <CA+EHjTy-tzmmu0vNCkK_J614FG1QVO79WSfzV78hQRYqGhP7EQ@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> Introduce a new hypercall allowing the host to relax the stage-2
> permissions of mappings in a non-protected guest page-table. It will be
> used later once we start allowing RO memslots and dirty logging.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 20 ++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 23 +++++++++++++++++++
>  4 files changed, 45 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 0b6c4d325134..66ee8542dcc9 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -67,6 +67,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index e528a42ed60e..a308dcd3b5b8 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -41,6 +41,7 @@ int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
>  int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
> +int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 3c3a27c985a2..287e4ee93ef2 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -264,6 +264,25 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) =  ret;
>  }
>
> +static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(u64, gfn, host_ctxt, 1);
> +       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 2);
> +       struct pkvm_hyp_vcpu *hyp_vcpu;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> +       if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> +               goto out;
> +
> +       ret = __pkvm_host_relax_perms_guest(gfn, hyp_vcpu, prot);
> +out:
> +       cpu_reg(host_ctxt, 1) = ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -475,6 +494,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_unshare_hyp),
>         HANDLE_FUNC(__pkvm_host_share_guest),
>         HANDLE_FUNC(__pkvm_host_unshare_guest),
> +       HANDLE_FUNC(__pkvm_host_relax_perms_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 30243b7922f1..aa8e0408aebb 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1488,3 +1488,26 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *vm)
>
>         return ret;
>  }
> +
> +int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot)
> +{
> +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       u64 phys;
> +       int ret;
> +
> +       if (prot & ~KVM_PGTABLE_PROT_RWX)
> +               return -EINVAL;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __check_host_shared_guest(vm, &phys, ipa);
> +       if (!ret)
> +               ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0);
> +
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 00:57:36 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 08:57:36 +0000
Subject: [PATCH v3 14/18] KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
In-Reply-To: <20241216175803.2716565-15-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-15-qperret@google.com>
Message-ID: <CA+EHjTz0sC4idnRMLjVoOcbyZ3kTXM3+hkPHdo=V1XZ3aJ6BbQ@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> Plumb the kvm_stage2_test_clear_young() callback into pKVM for
> non-protected guest. It will be later be called from MMU notifiers.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 22 +++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 ++++++++++++++++
>  4 files changed, 43 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 8663a588cf34..4f97155d6323 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -69,6 +69,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index fc9fdd5b0a52..b3aaad150b3e 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -43,6 +43,7 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum k
>  int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>  int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
>  int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
> +int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 98d317735107..616e172a9c48 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -303,6 +303,27 @@ static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt
>         cpu_reg(host_ctxt, 1) = ret;
>  }
>
> +static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +       DECLARE_REG(u64, gfn, host_ctxt, 2);
> +       DECLARE_REG(bool, mkold, host_ctxt, 3);
> +       struct pkvm_hyp_vm *hyp_vm;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vm = get_np_pkvm_hyp_vm(handle);
> +       if (!hyp_vm)
> +               goto out;
> +
> +       ret = __pkvm_host_test_clear_young_guest(gfn, mkold, hyp_vm);
> +       put_pkvm_hyp_vm(hyp_vm);
> +out:
> +       cpu_reg(host_ctxt, 1) = ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -516,6 +537,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_unshare_guest),
>         HANDLE_FUNC(__pkvm_host_relax_perms_guest),
>         HANDLE_FUNC(__pkvm_host_wrprotect_guest),
> +       HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 94e4251b5077..0e42c3baaf4b 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1530,3 +1530,22 @@ int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
>
>         return ret;
>  }
> +
> +int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm)
> +{
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       u64 phys;
> +       int ret;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __check_host_shared_guest(vm, &phys, ipa);
> +       if (!ret)
> +               ret = kvm_pgtable_stage2_test_clear_young(&vm->pgt, ipa, PAGE_SIZE, mkold);
> +
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 01:00:36 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 09:00:36 +0000
Subject: [PATCH v3 15/18] KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
In-Reply-To: <20241216175803.2716565-16-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-16-qperret@google.com>
Message-ID: <CA+EHjTx-2vBMY67Y6hm4U-DFirM93BK-CQOvcnBgYXO75xhmFw@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> Plumb the kvm_pgtable_stage2_mkyoung() callback into pKVM for
> non-protected guests. It will be called later from the fault handling
> path.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 19 ++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 20 +++++++++++++++++++
>  4 files changed, 41 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 4f97155d6323..a3b07db2776c 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -70,6 +70,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
>         __KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_host_mkyoung_guest,
>         __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>         __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>         __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index b3aaad150b3e..65c34753d86c 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -44,6 +44,7 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>  int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
>  int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>  int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
> +int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 616e172a9c48..32c4627b5b5b 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -324,6 +324,24 @@ static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *ho
>         cpu_reg(host_ctxt, 1) = ret;
>  }
>
> +static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(u64, gfn, host_ctxt, 1);
> +       struct pkvm_hyp_vcpu *hyp_vcpu;
> +       int ret = -EINVAL;
> +
> +       if (!is_protected_kvm_enabled())
> +               goto out;
> +
> +       hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> +       if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> +               goto out;
> +
> +       ret = __pkvm_host_mkyoung_guest(gfn, hyp_vcpu);
> +out:
> +       cpu_reg(host_ctxt, 1) =  ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -538,6 +556,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_host_relax_perms_guest),
>         HANDLE_FUNC(__pkvm_host_wrprotect_guest),
>         HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
> +       HANDLE_FUNC(__pkvm_host_mkyoung_guest),
>         HANDLE_FUNC(__kvm_adjust_pc),
>         HANDLE_FUNC(__kvm_vcpu_run),
>         HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 0e42c3baaf4b..eae03509d371 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1549,3 +1549,23 @@ int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *
>
>         return ret;
>  }
> +
> +int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu)
> +{
> +       struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
> +       u64 ipa = hyp_pfn_to_phys(gfn);
> +       u64 phys;
> +       int ret;
> +
> +       host_lock_component();
> +       guest_lock_component(vm);
> +
> +       ret = __check_host_shared_guest(vm, &phys, ipa);
> +       if (!ret)
> +               kvm_pgtable_stage2_mkyoung(&vm->pgt, ipa, 0);
> +
> +       guest_unlock_component(vm);
> +       host_unlock_component();
> +
> +       return ret;
> +}
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From tabba at google.com  Tue Dec 17 01:00:58 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 09:00:58 +0000
Subject: [PATCH v3 16/18] KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
In-Reply-To: <20241216175803.2716565-17-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-17-qperret@google.com>
Message-ID: <CA+EHjTw7X5fOY+1yLmGdqYbUDCOVCPfmJf--q8dBj3XLzPicBQ@mail.gmail.com>

On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
>
> Introduce a new hypercall to flush the TLBs of non-protected guests. The
> host kernel will be responsible for issuing this hypercall after changing
> stage-2 permissions using the __pkvm_host_relax_guest_perms() or
> __pkvm_host_wrprotect_guest() paths. This is left under the host's
> responsibility for performance reasons.
>
> Note however that the TLB maintenance for all *unmap* operations still
> remains entirely under the hypervisor's responsibility for security
> reasons -- an unmapped page may be donated to another entity, so a stale
> TLB entry could be used to leak private data.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad

> ---
>  arch/arm64/include/asm/kvm_asm.h   |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c | 17 +++++++++++++++++
>  2 files changed, 18 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index a3b07db2776c..002088c6e297 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -87,6 +87,7 @@ enum __kvm_host_smccc_func {
>         __KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
>         __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
>         __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
> +       __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
>  };
>
>  #define DECLARE_KVM_VHE_SYM(sym)       extern char sym[]
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 32c4627b5b5b..130f5f23bcb5 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -389,6 +389,22 @@ static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
>         __kvm_tlb_flush_vmid(kern_hyp_va(mmu));
>  }
>
> +static void handle___pkvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
> +{
> +       DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +       struct pkvm_hyp_vm *hyp_vm;
> +
> +       if (!is_protected_kvm_enabled())
> +               return;
> +
> +       hyp_vm = get_np_pkvm_hyp_vm(handle);
> +       if (!hyp_vm)
> +               return;
> +
> +       __kvm_tlb_flush_vmid(&hyp_vm->kvm.arch.mmu);
> +       put_pkvm_hyp_vm(hyp_vm);
> +}
> +
>  static void handle___kvm_flush_cpu_context(struct kvm_cpu_context *host_ctxt)
>  {
>         DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1);
> @@ -573,6 +589,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_teardown_vm),
>         HANDLE_FUNC(__pkvm_vcpu_load),
>         HANDLE_FUNC(__pkvm_vcpu_put),
> +       HANDLE_FUNC(__pkvm_tlb_flush_vmid),
>  };
>
>  static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From ping.bai at nxp.com  Tue Dec 17 01:02:01 2024
From: ping.bai at nxp.com (Jacky Bai)
Date: Tue, 17 Dec 2024 09:02:01 +0000
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <3c9fe85a-5f86-4df6-92fb-e4ceb033f161@kernel.org>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
 <3c9fe85a-5f86-4df6-92fb-e4ceb033f161@kernel.org>
Message-ID: <AS8PR04MB8642049B19BC7A5C8833FEB487042@AS8PR04MB8642.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
> 
> On 12/12/2024 10:35, Jacky Bai wrote:
> > The i.MX 943 applications processors integrate up to four Arm Cortex
> > A55 cores and supports functional safety with built-in 2x Arm Cortex
> > M33 and M7 cores which can be configured asa safety island. Optimizing
> > performance and power efficiency for Industrial, IoT and automotive
> > devices, i.MX 943 processors are built with NXP's innovative Energy
> > Flex architecture.
> 
> Few more comments:
> 
> Drop all marketing junk talk.

Thx, will drop it in v2. ^_^
> 
> >
> > This patch adds the minimal dtsi support for i.MX943 with
> 
> Please do not use "This commit/patch/change", but imperative mood. See
> longer explanation here:

Thx, will fix in v2.
> 
> > peripherals like uart, edma, i2c, spi, mu, sai etc.
> 
> Explain how can we test it, why this differs from imx95 but uses imx95, why
> this is needed in the first place without users.

Will add more details in the commit msg in v2.

BR

> 
> >
> > Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/imx943-clock.h  |  196 +++
> > .../arm64/boot/dts/freescale/imx943-pinfunc.h | 1542
> +++++++++++++++++
> >  arch/arm64/boot/dts/freescale/imx943-power.h  |   41 +
> >  arch/arm64/boot/dts/freescale/imx943.dtsi     | 1284
> ++++++++++++++
> >  4 files changed, 3063 insertions(+)
> 
> 
> Best regards,
> Krzysztof


From krzk at kernel.org  Tue Dec 17 01:03:18 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 10:03:18 +0100
Subject: [PATCH] arm64: dts: freescale: Add basic dtsi for imx943
In-Reply-To: <AS8PR04MB8642D11477A37E75BAB71F3087042@AS8PR04MB8642.eurprd04.prod.outlook.com>
References: <20241212093555.1376568-1-ping.bai@nxp.com>
 <20241212093555.1376568-2-ping.bai@nxp.com>
 <bx3r4cs3oklfduvkg65vke3clb3fc6sseske2ellq27ifpmsnm@msz6iqvjwufn>
 <AS8PR04MB8642D11477A37E75BAB71F3087042@AS8PR04MB8642.eurprd04.prod.outlook.com>
Message-ID: <fa130432-bbfe-4d8f-913c-e86488efe203@kernel.org>

On 17/12/2024 09:55, Jacky Bai wrote:
>>
>>> +			device_type = "cpu";
> 
> ...
> 
>>> +			edma2: dma-controller at 42000000 {
>>> +				compatible = "fsl,imx95-edma5";
>>
>> imx943 or imx95?
>>
> 
> Compatible with imx95, so I did not add new redundant dt binding entry.
The entry is not redundant, because allows handling quirks or missing
features (see writing bindings).

Best regards,
Krzysztof


From ivo.ivanov.ivanov1 at gmail.com  Tue Dec 17 01:08:26 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Tue, 17 Dec 2024 11:08:26 +0200
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
 <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
 <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>
Message-ID: <6e93d59d-71e5-4c09-862f-55b5504121aa@gmail.com>

On 12/17/24 07:24, Krzysztof Kozlowski wrote:
> On 16/12/2024 21:59, Ivaylo Ivanov wrote:
>> On 12/16/24 10:44, Krzysztof Kozlowski wrote:
>>> On 14/12/2024 23:04, Ivaylo Ivanov wrote:
>>>> Add samsung,exynos8895-hsi2c dedicated compatible for representing
>>>> I2C of Exynos8895 SoC. Since there are I2C buses that aren't implemented
>>>> as a part of USIv1 blocks, they only require a single clock.
>>>>
>>>> Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
>>>> ---
>>>>  .../devicetree/bindings/i2c/i2c-exynos5.yaml  | 26 ++++++++++++++++---
>>>>  1 file changed, 23 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
>>>> index cc8bba553..b029be88e 100644
>>>> --- a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
>>>> +++ b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
>>>> @@ -25,6 +25,7 @@ properties:
>>>>            - samsung,exynos5250-hsi2c    # Exynos5250 and Exynos5420
>>>>            - samsung,exynos5260-hsi2c    # Exynos5260
>>>>            - samsung,exynos7-hsi2c       # Exynos7
>>>> +          - samsung,exynos8895-hsi2c
>>>>            - samsung,exynosautov9-hsi2c
>>>>        - items:
>>>>            - enum:
>>>> @@ -94,9 +95,28 @@ allOf:
>>>>          - clock-names
>>>>  
>>>>      else:
>>>> -      properties:
>>>> -        clocks:
>>>> -          maxItems: 1
>>>> +      if:
>>>> +        properties:
>>>> +          compatible:
>>>> +            contains:
>>>> +              enum:
>>>> +                - samsung,exynos8895-hsi2c
>>>> +
>>>> +      then:
>>>> +        properties:
>>>> +          clocks:
>>> Missing minItems
>>>
>>>> +            maxItems: 2
>>>> +
>>>> +          clock-names:
>>> Ditto
>>>
>>>> +            maxItems: 2
>>>> +
>>>> +        required:
>>>> +          - clock-names
>>> I don't understand why do you need second, same branch in if, basically
>> Because, as I stated in the commit message, we have HSI2C controllers
>> both implemented in USIv1 blocks and outside. These that are a part of
> On Exynos8895? Where? With the same compatible?

hsi2c_0 which has a clock from BUSC and hsi2c_1 to hsi2c_4 which use clocks
from PERIC1 (CLK_GOUT_PERIC1_HSI2C_CAM{0,1,2,3}_IPCLK). Why would
they need a different compatible though? It's functionally the same i2c design
as the one implemented in USIv1 blocks.

>
>> USIv1 need 2 clocks, and those that aren't have only one. So it's not
>> a duplicate for the previous - autov9 sets a minitems of 2 and the
>> others have a maxitems of 1.
> We talk here about branch that says 2 items. You duplicate that one.

I see. I can just define the clocks for all at this point.

Best regards,
Ivo.

>
> Best regards,
> Krzysztof



From linux at fw-web.de  Tue Dec 17 01:12:14 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:14 +0100
Subject: [PATCH v3 00/22] continue mt7988 devicetree work
Message-ID: <20241217091238.16032-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This series adds some missing labels and new nodes to mt7988 DTS.

based on pinctrl-series
https://patchwork.kernel.org/project/linux-mediatek/list/?series=918572

changes:
v3:
- reorder
- small fixes
- add some new patches (t-phy, pcie, mmc overlays)
- dropped pmic and proc-supply for now because we found a mismatch compared with schematic

v2:
- reorder and squash label-commits to where they are used
- add some more nodes
- add changes to bananapi-r4 board
- moving some nodes from SoC dtsi to board dts

Frank Wunderlich (22):
  arm64: dts: mediatek: mt7988: Add reserved memory
  arm64: dts: mediatek: mt7988: Add mmc support
  arm64: dts: mediatek: mt7988: Add lvts node
  arm64: dts: mediatek: mt7988: Add thermal-zone
  arm64: dts: mediatek: mt7988: Add missing clock-div property for i2c
  arm64: dts: mediatek: mt7988: Add mcu-sys node for cpu
  arm64: dts: mediatek: mt7988: Add CPU OPP table for clock scaling
  arm64: dts: mediatek: mt7988: Disable usb controllers by default
  arm64: dts: mediatek: mt7988: Add t-phy for ssusb1
  arm64: dts: mediatek: mt7988: Add pcie nodes
  arm64: dts: mediatek: mt7988a-bpi-r4: Enable watchdog
  arm64: dts: mediatek: mt7988a-bpi-r4: Add fixed regulators for 1v8 and
    3v3
  arm64: dts: mediatek: mt7988a-bpi-r4: Add dt overlays for sd + emmc
  arm64: dts: mediatek: mt7988a-bpi-r4: Add thermal configuration
  arm64: dts: mediatek: mt7988a-bpi-r4: Enable serial0 debug uart
  arm64: dts: mediatek: mt7988a-bpi-r4: Add default UART stdout
  arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C controllers
  arm64: dts: mediatek: mt7988a-bpi-r4: Add PCA9545 I2C Mux
  arm64: dts: mediatek: mt7988a-bpi-r4: Enable t-phy for ssusb1
  arm64: dts: mediatek: mt7988a-bpi-r4: Enable ssusb1 on bpi-r4
  arm64: dts: mediatek: mt7988a-bpi-r4: Enable pwm
  arm64: dts: mediatek: mt7988a-bpi-r4: Enable pcie

 arch/arm64/boot/dts/mediatek/Makefile         |   3 +
 .../mt7988a-bananapi-bpi-r4-emmc.dtso         |  33 ++
 .../mediatek/mt7988a-bananapi-bpi-r4-sd.dtso  |  31 ++
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 143 +++++++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi     | 303 +++++++++++++++++-
 5 files changed, 506 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso

-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:15 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:15 +0100
Subject: [PATCH v3 01/22] arm64: dts: mediatek: mt7988: Add reserved memory
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-2-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add memory range handled by ATF to not be touched by linux kernel.
ATF is SoC specific and not board-specific so add it to mt7988.dtsi.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
changes: v3:
- move commit to first of series
- drop secmon_reserved label
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 46969577c87a..d205717ac78b 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -62,6 +62,18 @@ psci {
 		method = "smc";
 	};
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* 320 KiB reserved for ARM Trusted Firmware (BL31 and BL32) */
+		secmon at 43000000 {
+			reg = <0 0x43000000 0 0x50000>;
+			no-map;
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		ranges;
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:16 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:16 +0100
Subject: [PATCH v3 02/22] arm64: dts: mediatek: mt7988: Add mmc support
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-3-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add devicetree node for MMC controller.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes:
v3:
move clocks in one line
v2:
squash "add missing label for apmixedsys"
---
 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 d205717ac78b..2e224d0d0168 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -112,7 +112,7 @@ watchdog: watchdog at 1001c000 {
 			#reset-cells = <1>;
 		};
 
-		clock-controller at 1001e000 {
+		apmixedsys: clock-controller at 1001e000 {
 			compatible = "mediatek,mt7988-apmixedsys";
 			reg = <0 0x1001e000 0 0x1000>;
 			#clock-cells = <1>;
@@ -290,6 +290,25 @@ usb at 11200000 {
 			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
 		};
 
+		mmc0: mmc at 11230000 {
+			compatible = "mediatek,mt7988-mmc";
+			reg = <0 0x11230000 0 0x1000>,
+			      <0 0x11D60000 0 0x1000>;
+			interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_MSDC400>,
+				 <&infracfg CLK_INFRA_MSDC2_HCK>,
+				 <&infracfg CLK_INFRA_66M_MSDC_0_HCK>,
+				 <&infracfg CLK_INFRA_133M_MSDC_0_HCK>;
+			assigned-clocks = <&topckgen CLK_TOP_EMMC_250M_SEL>,
+					  <&topckgen CLK_TOP_EMMC_400M_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_NET1PLL_D5_D2>,
+						 <&apmixedsys CLK_APMIXED_MSDCPLL>;
+			clock-names = "source", "hclk", "axi_cg", "ahb_cg";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		clock-controller at 11f40000 {
 			compatible = "mediatek,mt7988-xfi-pll";
 			reg = <0 0x11f40000 0 0x1000>;
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:17 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:17 +0100
Subject: [PATCH v3 03/22] arm64: dts: mediatek: mt7988: Add lvts node
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-4-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add Low Voltage Thermal Sensor (LVTS) node for mt7988 SoC.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes:
v3:
dropped efuse label
v2:
squash
- "arm64: dts: mediatek: mt7988: add label for efuse"
- "arm64: dts: mediatek: mt7988: extend efuse node" (drop other efuse subnodes)
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 2e224d0d0168..32bb04ce21b3 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -4,6 +4,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/pinctrl/mt65xx.h>
+#include <dt-bindings/reset/mediatek,mt7988-resets.h>
 
 / {
 	compatible = "mediatek,mt7988a";
@@ -97,6 +98,7 @@ infracfg: clock-controller at 10001000 {
 			compatible = "mediatek,mt7988-infracfg", "syscon";
 			reg = <0 0x10001000 0 0x1000>;
 			#clock-cells = <1>;
+			#reset-cells = <1>;
 		};
 
 		topckgen: clock-controller at 1001b000 {
@@ -262,6 +264,17 @@ i2c at 11005000 {
 			status = "disabled";
 		};
 
+		lvts: lvts at 1100a000 {
+			compatible = "mediatek,mt7988-lvts-ap";
+			#thermal-sensor-cells = <1>;
+			reg = <0 0x1100a000 0 0x1000>;
+			clocks = <&infracfg CLK_INFRA_26M_THERM_SYSTEM>;
+			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+			resets = <&infracfg MT7988_INFRA_RST1_THERM_CTRL_SWRST>;
+			nvmem-cells = <&lvts_calibration>;
+			nvmem-cell-names = "lvts-calib-data-1";
+		};
+
 		usb at 11190000 {
 			compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
 			reg = <0 0x11190000 0 0x2e00>,
@@ -321,6 +334,10 @@ efuse at 11f50000 {
 			reg = <0 0x11f50000 0 0x1000>;
 			#address-cells = <1>;
 			#size-cells = <1>;
+
+			lvts_calibration: calib at 918 {
+				reg = <0x918 0x28>;
+			};
 		};
 
 		clock-controller at 15000000 {
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:18 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:18 +0100
Subject: [PATCH v3 04/22] arm64: dts: mediatek: mt7988: Add thermal-zone
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-5-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add basic thermal-zone node.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v2:
- only add critical trip to SoC dtsi, lower trips have to go to board dts
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 32bb04ce21b3..0e75a8692879 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -355,6 +355,21 @@ clock-controller at 15031000 {
 		};
 	};
 
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+			thermal-sensors = <&lvts 0>;
+			trips {
+				cpu_trip_crit: crit {
+					temperature = <125000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupt-parent = <&gic>;
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:20 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:20 +0100
Subject: [PATCH v3 06/22] arm64: dts: mediatek: mt7988: Add mcu-sys node for cpu
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-7-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

In preparation for adding support for CPU DVFS and clock tables for it,
add the MCUSYS clock controller node.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 16b28fcf1e3c..5e53ea47f159 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -192,6 +192,12 @@ pwm at 10048000 {
 			status = "disabled";
 		};
 
+		mcusys: mcusys at 100e0000 {
+			compatible = "mediatek,mt7988-mcusys", "syscon";
+			reg = <0 0x100e0000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
 		serial at 11000000 {
 			compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
 			reg = <0 0x11000000 0 0x100>;
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:19 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:19 +0100
Subject: [PATCH v3 05/22] arm64: dts: mediatek: mt7988: Add missing clock-div property for i2c
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-6-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

I2C binding requires clock-div property.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Fixes: 660c230bf302 ("arm64: dts: mediatek: mt7988: add I2C controllers")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 0e75a8692879..16b28fcf1e3c 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -230,6 +230,7 @@ i2c at 11003000 {
 			reg = <0 0x11003000 0 0x1000>,
 			      <0 0x10217080 0 0x80>;
 			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+			clock-div = <1>;
 			clocks = <&infracfg CLK_INFRA_I2C_BCK>,
 				 <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
 			clock-names = "main", "dma";
@@ -243,6 +244,7 @@ i2c at 11004000 {
 			reg = <0 0x11004000 0 0x1000>,
 			      <0 0x10217100 0 0x80>;
 			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clock-div = <1>;
 			clocks = <&infracfg CLK_INFRA_I2C_BCK>,
 				 <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
 			clock-names = "main", "dma";
@@ -256,6 +258,7 @@ i2c at 11005000 {
 			reg = <0 0x11005000 0 0x1000>,
 			      <0 0x10217180 0 0x80>;
 			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clock-div = <1>;
 			clocks = <&infracfg CLK_INFRA_I2C_BCK>,
 				 <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
 			clock-names = "main", "dma";
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:21 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:21 +0100
Subject: [PATCH v3 07/22] arm64: dts: mediatek: mt7988: Add CPU OPP table for clock scaling
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-8-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add operating points defining frequency/voltages of cpu cores.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes:
v3:
- change commit-title
v2:
- drop cpu-labels for now
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 38 +++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 5e53ea47f159..a7954bf5c81e 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -21,6 +21,10 @@ cpu at 0 {
 			reg = <0x0>;
 			device_type = "cpu";
 			enable-method = "psci";
+			clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
+				 <&topckgen CLK_TOP_XTAL>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		cpu at 1 {
@@ -28,6 +32,10 @@ cpu at 1 {
 			reg = <0x1>;
 			device_type = "cpu";
 			enable-method = "psci";
+			clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
+				 <&topckgen CLK_TOP_XTAL>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		cpu at 2 {
@@ -35,6 +43,10 @@ cpu at 2 {
 			reg = <0x2>;
 			device_type = "cpu";
 			enable-method = "psci";
+			clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
+				 <&topckgen CLK_TOP_XTAL>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		cpu at 3 {
@@ -42,6 +54,32 @@ cpu at 3 {
 			reg = <0x3>;
 			device_type = "cpu";
 			enable-method = "psci";
+			clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
+				 <&topckgen CLK_TOP_XTAL>;
+			clock-names = "cpu", "intermediate";
+			operating-points-v2 = <&cluster0_opp>;
+		};
+
+		cluster0_opp: opp-table-0 {
+			compatible = "operating-points-v2";
+			opp-shared;
+
+			opp-800000000 {
+				opp-hz = /bits/ 64 <800000000>;
+				opp-microvolt = <850000>;
+			};
+			opp-1100000000 {
+				opp-hz = /bits/ 64 <1100000000>;
+				opp-microvolt = <850000>;
+			};
+			opp-1500000000 {
+				opp-hz = /bits/ 64 <1500000000>;
+				opp-microvolt = <850000>;
+			};
+			opp-1800000000 {
+				opp-hz = /bits/ 64 <1800000000>;
+				opp-microvolt = <900000>;
+			};
 		};
 	};
 
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:23 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:23 +0100
Subject: [PATCH v3 09/22] arm64: dts: mediatek: mt7988: Add t-phy for ssusb1
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-10-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

USB controller needs phys for working properly.
On mt7988 ssusb0 uses a xs-phy, ssusb uses t-phy.
For now add the t-phy for ssusb1. We can reuse the mt7986 compatible
here.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 25 +++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index f8b01f3fff32..209d170bce7f 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -349,6 +349,8 @@ usb at 11200000 {
 				 <&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";
+			phys = <&tphyu2port0 PHY_TYPE_USB2>,
+			       <&tphyu3port0 PHY_TYPE_USB3>;
 			status = "disabled";
 		};
 
@@ -371,6 +373,29 @@ mmc0: mmc at 11230000 {
 			status = "disabled";
 		};
 
+		t-phy at 11c50000 {
+			compatible = "mediatek,mt7986-tphy",
+				     "mediatek,generic-tphy-v2";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			status = "disabled";
+
+			tphyu2port0: usb-phy at 11c50000 {
+				reg = <0 0x11c50000 0 0x700>;
+				clocks = <&infracfg CLK_INFRA_USB_UTMI_CK_P1>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+			};
+
+			tphyu3port0: usb-phy at 11c50700 {
+				reg = <0 0x11c50700 0 0x900>;
+				clocks = <&infracfg CLK_INFRA_USB_PIPE_CK_P1>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+			};
+		};
+
 		clock-controller at 11f40000 {
 			compatible = "mediatek,mt7988-xfi-pll";
 			reg = <0 0x11f40000 0 0x1000>;
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:22 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:22 +0100
Subject: [PATCH v3 08/22] arm64: dts: mediatek: mt7988: Disable usb controllers by default
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-9-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

The controllers should be enabled at board level if used.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index a7954bf5c81e..f8b01f3fff32 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -334,6 +334,7 @@ usb at 11190000 {
 				 <&infracfg CLK_INFRA_133M_USB_HCK>,
 				 <&infracfg CLK_INFRA_USB_XHCI>;
 			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
+			status = "disabled";
 		};
 
 		usb at 11200000 {
@@ -348,6 +349,7 @@ usb at 11200000 {
 				 <&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";
+			status = "disabled";
 		};
 
 		mmc0: mmc at 11230000 {
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:24 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:24 +0100
Subject: [PATCH v3 10/22] arm64: dts: mediatek: mt7988: Add pcie nodes
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-11-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add pcie controllers for mt7988. Reuse mt7986 compatible.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 152 ++++++++++++++++++++++
 1 file changed, 152 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 209d170bce7f..74c75d5149d7 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -373,6 +373,158 @@ mmc0: mmc at 11230000 {
 			status = "disabled";
 		};
 
+		pcie at 11280000 {
+			compatible = "mediatek,mt7986-pcie",
+				     "mediatek,mt8192-pcie";
+			device_type = "pci";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg = <0 0x11280000 0 0x2000>;
+			reg-names = "pcie-mac";
+			linux,pci-domain = <3>;
+			interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+			bus-range = <0x00 0xff>;
+			ranges = <0x81000000 0x00 0x20000000 0x00
+				  0x20000000 0x00 0x00200000>,
+				 <0x82000000 0x00 0x20200000 0x00
+				  0x20200000 0x00 0x07e00000>;
+			clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P2>,
+				 <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P2>,
+				 <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P2>,
+				 <&infracfg CLK_INFRA_133M_PCIE_CK_P2>;
+			clock-names = "pl_250m", "tl_26m", "peri_26m",
+				      "top_133m";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pcie2_pins>;
+			status = "disabled";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &pcie_intc2 0>,
+					<0 0 0 2 &pcie_intc2 1>,
+					<0 0 0 3 &pcie_intc2 2>,
+					<0 0 0 4 &pcie_intc2 3>;
+			pcie_intc2: interrupt-controller {
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-controller;
+			};
+		};
+
+		pcie at 11290000 {
+			compatible = "mediatek,mt7986-pcie",
+				     "mediatek,mt8192-pcie";
+			device_type = "pci";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg = <0 0x11290000 0 0x2000>;
+			reg-names = "pcie-mac";
+			linux,pci-domain = <2>;
+			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+			bus-range = <0x00 0xff>;
+			ranges = <0x81000000 0x00 0x28000000 0x00
+				  0x28000000 0x00 0x00200000>,
+				 <0x82000000 0x00 0x28200000 0x00
+				  0x28200000 0x00 0x07e00000>;
+			clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P3>,
+				 <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P3>,
+				 <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P3>,
+				 <&infracfg CLK_INFRA_133M_PCIE_CK_P3>;
+			clock-names = "pl_250m", "tl_26m", "peri_26m",
+				      "top_133m";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pcie3_pins>;
+			status = "disabled";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &pcie_intc3 0>,
+					<0 0 0 2 &pcie_intc3 1>,
+					<0 0 0 3 &pcie_intc3 2>,
+					<0 0 0 4 &pcie_intc3 3>;
+			pcie_intc3: interrupt-controller {
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-controller;
+			};
+		};
+
+		pcie at 11300000 {
+			compatible = "mediatek,mt7986-pcie",
+				     "mediatek,mt8192-pcie";
+			device_type = "pci";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg = <0 0x11300000 0 0x2000>;
+			reg-names = "pcie-mac";
+			linux,pci-domain = <0>;
+			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+			bus-range = <0x00 0xff>;
+			ranges = <0x81000000 0x00 0x30000000 0x00
+				  0x30000000 0x00 0x00200000>,
+				 <0x82000000 0x00 0x30200000 0x00
+				  0x30200000 0x00 0x07e00000>;
+			clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P0>,
+				 <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P0>,
+				 <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P0>,
+				 <&infracfg CLK_INFRA_133M_PCIE_CK_P0>;
+			clock-names = "pl_250m", "tl_26m", "peri_26m",
+				      "top_133m";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pcie0_pins>;
+			status = "disabled";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+					<0 0 0 2 &pcie_intc0 1>,
+					<0 0 0 3 &pcie_intc0 2>,
+					<0 0 0 4 &pcie_intc0 3>;
+			pcie_intc0: interrupt-controller {
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-controller;
+			};
+		};
+
+		pcie at 11310000 {
+			compatible = "mediatek,mt7986-pcie",
+				     "mediatek,mt8192-pcie";
+			device_type = "pci";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg = <0 0x11310000 0 0x2000>;
+			reg-names = "pcie-mac";
+			linux,pci-domain = <1>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+			bus-range = <0x00 0xff>;
+			ranges = <0x81000000 0x00 0x38000000 0x00
+				  0x38000000 0x00 0x00200000>,
+				 <0x82000000 0x00 0x38200000 0x00
+				  0x38200000 0x00 0x07e00000>;
+			clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P1>,
+				 <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P1>,
+				 <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P1>,
+				 <&infracfg CLK_INFRA_133M_PCIE_CK_P1>;
+			clock-names = "pl_250m", "tl_26m", "peri_26m",
+				      "top_133m";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pcie1_pins>;
+			status = "disabled";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &pcie_intc1 0>,
+					<0 0 0 2 &pcie_intc1 1>,
+					<0 0 0 3 &pcie_intc1 2>,
+					<0 0 0 4 &pcie_intc1 3>;
+			pcie_intc1: interrupt-controller {
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-controller;
+			};
+		};
+
 		t-phy at 11c50000 {
 			compatible = "mediatek,mt7986-tphy",
 				     "mediatek,generic-tphy-v2";
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:25 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:25 +0100
Subject: [PATCH v3 11/22] arm64: dts: mediatek: mt7988a-bpi-r4: Enable watchdog
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-12-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable the watchdog on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes:
v3: change commit title to include prefix for r4
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index aa2dabc041fd..d914eae2b524 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -198,3 +198,7 @@ mux {
 		};
 	};
 };
+
+&watchdog {
+	status = "okay";
+};
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:26 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:26 +0100
Subject: [PATCH v3 12/22] arm64: dts: mediatek: mt7988a-bpi-r4: Add fixed regulators for 1v8 and 3v3
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-13-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add regulator nodes used for mmc to Bananapi R4 board.
This board has 1 MMC controller used for SDMMC and eMMC where only one can
be used at one time, selected by hardware switches. SD uses 3v3 for both
supplies and emmc uses both regulators.
So defining both regulators in board dts and referencing them in the dt
overlay.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
v3:
- change title to include prefix for r4
v2:
- move mmc regulators to board dts of bpi-r4
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts   | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index d914eae2b524..df53512c6890 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -8,6 +8,24 @@ / {
 	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
 	model = "Banana Pi BPI-R4";
 	chassis-type = "embedded";
+
+	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;
+	};
 };
 
 &pio {
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:27 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:27 +0100
Subject: [PATCH v3 13/22] arm64: dts: mediatek: mt7988a-bpi-r4: Add dt overlays for sd + emmc
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-14-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Bananapi R4 can use the mmc controller either with sd card or the onboard
emmc. The used device is selected through hardware-switches and probed in
bootloader.
Add devicetree overlays for both mmc configurations.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/mediatek/Makefile         |  3 ++
 .../mt7988a-bananapi-bpi-r4-emmc.dtso         | 33 +++++++++++++++++++
 .../mediatek/mt7988a-bananapi-bpi-r4-sd.dtso  | 31 +++++++++++++++++
 3 files changed, 67 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 8fd7b2bb7a15..33e244898849 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -21,6 +21,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-emmc.dtbo
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb
@@ -90,3 +92,4 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
 # Device tree overlays support
 DTC_FLAGS_mt7986a-bananapi-bpi-r3 := -@
 DTC_FLAGS_mt7986a-bananapi-bpi-r3-mini := -@
+DTC_FLAGS_mt7988a-bananapi-bpi-r4 := -@
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
new file mode 100644
index 000000000000..3e320b2f83d5
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Frank Wunderlich <frank-w at public-files.de>
+ */
+
+/dts-v1/;
+/plugin/;
+
+/ {
+	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
+};
+
+&{/soc/mmc at 11230000} {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_pins_emmc_51>;
+	pinctrl-1 = <&mmc0_pins_emmc_51>;
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	hs400-ds-delay = <0x12814>;
+	vqmmc-supply = <&reg_1p8v>;
+	vmmc-supply = <&reg_3p3v>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
new file mode 100644
index 000000000000..663c6345dd31
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ * Author: Frank Wunderlich <frank-w at public-files.de>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
+};
+
+&{/soc/mmc at 11230000} {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_pins_sdcard>;
+	pinctrl-1 = <&mmc0_pins_sdcard>;
+	cd-gpios = <&pio 12 GPIO_ACTIVE_LOW>;
+	bus-width = <4>;
+	max-frequency = <52000000>;
+	cap-sd-highspeed;
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_3p3v>;
+	no-mmc;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+};
+
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:28 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:28 +0100
Subject: [PATCH v3 14/22] arm64: dts: mediatek: mt7988a-bpi-r4: Add thermal configuration
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-15-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add additional thermal trips to Bananapi R4 board.
SoC only contains the critical trip.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index df53512c6890..8a320d9da443 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -28,6 +28,34 @@ reg_3p3v: regulator-3p3v {
 	};
 };
 
+&cpu_thermal {
+	trips {
+		cpu_trip_hot: hot {
+			temperature = <120000>;
+			hysteresis = <2000>;
+			type = "hot";
+		};
+
+		cpu_trip_active_high: active-high {
+			temperature = <115000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+
+		cpu_trip_active_med: active-med {
+			temperature = <85000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+
+		cpu_trip_active_low: active-low {
+			temperature = <40000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+	};
+};
+
 &pio {
 	mdio0_pins: mdio0-pins {
 		mux {
-- 
2.43.0



From linux at fw-web.de  Tue Dec 17 01:12:29 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Tue, 17 Dec 2024 10:12:29 +0100
Subject: [PATCH v3 15/22] arm64: dts: mediatek: mt7988a-bpi-r4: Enable serial0 debug uart
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <20241217091238.16032-16-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Enable the debug uart on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 8a320d9da443..9037f35857a9 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -245,6 +245,10 @@ mux {
 	};
 };
 
+&serial0 {
+	status = "okay";
+};
+
 &watchdog {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 74c75d5149d7..59a1ffc2edfc 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -236,7 +236,7 @@ mcusys: mcusys at 100e0000 {
 			#clock-cells = <1>;
 		};
 
-		serial at 11000000 {
+		serial0: serial at 11000000 {
 			compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
 			reg = <0 0x11000000 0 0x100>;
 			interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.43.0



From jens.wiklander at linaro.org  Tue Dec 17 02:07:38 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 17 Dec 2024 11:07:38 +0100
Subject: [PATCH v4 2/6] optee: account for direction while converting parameters
In-Reply-To: <20241217100809.3962439-1-jens.wiklander@linaro.org>
References: <20241217100809.3962439-1-jens.wiklander@linaro.org>
Message-ID: <20241217100809.3962439-3-jens.wiklander@linaro.org>

The OP-TEE backend driver has two internal function pointers to convert
between the subsystem type struct tee_param and the OP-TEE type struct
optee_msg_param.

The conversion is done from one of the types to the other, which is then
involved in some operation and finally converted back to the original
type. When converting to prepare the parameters for the operation, all
fields must be taken into account, but then converting back, it's enough
to update only out-values and out-sizes. So, an update_out parameter is
added to the conversion functions to tell if all or only some fields
must be copied.

This is needed in a later patch where it might get confusing when
converting back in from_msg_param() callback since an allocated
restricted SHM can be using the sec_world_id of the used restricted
memory pool and that doesn't translate back well.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/call.c          | 10 ++--
 drivers/tee/optee/ffa_abi.c       | 43 +++++++++++++----
 drivers/tee/optee/optee_private.h | 42 +++++++++++------
 drivers/tee/optee/rpc.c           | 31 +++++++++----
 drivers/tee/optee/smc_abi.c       | 76 +++++++++++++++++++++++--------
 5 files changed, 144 insertions(+), 58 deletions(-)

diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 16eb953e14bb..f1533b894726 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -400,7 +400,8 @@ int optee_open_session(struct tee_context *ctx,
 	export_uuid(msg_arg->params[1].u.octets, &client_uuid);
 
 	rc = optee->ops->to_msg_param(optee, msg_arg->params + 2,
-				      arg->num_params, param);
+				      arg->num_params, param,
+				      false /*!update_out*/);
 	if (rc)
 		goto out;
 
@@ -427,7 +428,8 @@ int optee_open_session(struct tee_context *ctx,
 	}
 
 	if (optee->ops->from_msg_param(optee, param, arg->num_params,
-				       msg_arg->params + 2)) {
+				       msg_arg->params + 2,
+				       true /*update_out*/)) {
 		arg->ret = TEEC_ERROR_COMMUNICATION;
 		arg->ret_origin = TEEC_ORIGIN_COMMS;
 		/* Close session again to avoid leakage */
@@ -541,7 +543,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 	msg_arg->cancel_id = arg->cancel_id;
 
 	rc = optee->ops->to_msg_param(optee, msg_arg->params, arg->num_params,
-				      param);
+				      param, false /*!update_out*/);
 	if (rc)
 		goto out;
 
@@ -551,7 +553,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 	}
 
 	if (optee->ops->from_msg_param(optee, param, arg->num_params,
-				       msg_arg->params)) {
+				       msg_arg->params, true /*update_out*/)) {
 		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
 		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
 	}
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index f3af5666bb11..02e6175ac5f0 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -122,15 +122,21 @@ static int optee_shm_rem_ffa_handle(struct optee *optee, u64 global_id)
  */
 
 static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
-				   u32 attr, const struct optee_msg_param *mp)
+				   u32 attr, const struct optee_msg_param *mp,
+				   bool update_out)
 {
 	struct tee_shm *shm = NULL;
 	u64 offs_high = 0;
 	u64 offs_low = 0;
 
+	if (update_out) {
+		if (attr == OPTEE_MSG_ATTR_TYPE_FMEM_INPUT)
+			return;
+		goto out;
+	}
+
 	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
 		  attr - OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
-	p->u.memref.size = mp->u.fmem.size;
 
 	if (mp->u.fmem.global_id != OPTEE_MSG_FMEM_INVALID_GLOBAL_ID)
 		shm = optee_shm_from_ffa_handle(optee, mp->u.fmem.global_id);
@@ -141,6 +147,8 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
 		offs_high = mp->u.fmem.offs_high;
 	}
 	p->u.memref.shm_offs = offs_low | offs_high << 32;
+out:
+	p->u.memref.size = mp->u.fmem.size;
 }
 
 /**
@@ -150,12 +158,14 @@ static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
  * @params:	subsystem internal parameter representation
  * @num_params:	number of elements in the parameter arrays
  * @msg_params:	OPTEE_MSG parameters
+ * @update_out: update parameter for output only
  *
  * Returns 0 on success or <0 on failure
  */
 static int optee_ffa_from_msg_param(struct optee *optee,
 				    struct tee_param *params, size_t num_params,
-				    const struct optee_msg_param *msg_params)
+				    const struct optee_msg_param *msg_params,
+				    bool update_out)
 {
 	size_t n;
 
@@ -166,18 +176,20 @@ static int optee_ffa_from_msg_param(struct optee *optee,
 
 		switch (attr) {
 		case OPTEE_MSG_ATTR_TYPE_NONE:
+			if (update_out)
+				break;
 			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
 			memset(&p->u, 0, sizeof(p->u));
 			break;
 		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
-			optee_from_msg_param_value(p, attr, mp);
+			optee_from_msg_param_value(p, attr, mp, update_out);
 			break;
 		case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
-			from_msg_param_ffa_mem(optee, p, attr, mp);
+			from_msg_param_ffa_mem(optee, p, attr, mp, update_out);
 			break;
 		default:
 			return -EINVAL;
@@ -188,10 +200,16 @@ static int optee_ffa_from_msg_param(struct optee *optee,
 }
 
 static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
-				const struct tee_param *p)
+				const struct tee_param *p, bool update_out)
 {
 	struct tee_shm *shm = p->u.memref.shm;
 
+	if (update_out) {
+		if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
+			return 0;
+		goto out;
+	}
+
 	mp->attr = OPTEE_MSG_ATTR_TYPE_FMEM_INPUT + p->attr -
 		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
 
@@ -211,6 +229,7 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
 		memset(&mp->u, 0, sizeof(mp->u));
 		mp->u.fmem.global_id = OPTEE_MSG_FMEM_INVALID_GLOBAL_ID;
 	}
+out:
 	mp->u.fmem.size = p->u.memref.size;
 
 	return 0;
@@ -222,13 +241,15 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
  * @optee:	main service struct
  * @msg_params:	OPTEE_MSG parameters
  * @num_params:	number of elements in the parameter arrays
- * @params:	subsystem itnernal parameter representation
+ * @params:	subsystem internal parameter representation
+ * @update_out: update parameter for output only
  * Returns 0 on success or <0 on failure
  */
 static int optee_ffa_to_msg_param(struct optee *optee,
 				  struct optee_msg_param *msg_params,
 				  size_t num_params,
-				  const struct tee_param *params)
+				  const struct tee_param *params,
+				  bool update_out)
 {
 	size_t n;
 
@@ -238,18 +259,20 @@ static int optee_ffa_to_msg_param(struct optee *optee,
 
 		switch (p->attr) {
 		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
+			if (update_out)
+				break;
 			mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
 			memset(&mp->u, 0, sizeof(mp->u));
 			break;
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
-			optee_to_msg_param_value(mp, p);
+			optee_to_msg_param_value(mp, p, update_out);
 			break;
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
-			if (to_msg_param_ffa_mem(mp, p))
+			if (to_msg_param_ffa_mem(mp, p, update_out))
 				return -EINVAL;
 			break;
 		default:
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index dc0f355ef72a..20eda508dbac 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -185,10 +185,12 @@ struct optee_ops {
 				bool system_thread);
 	int (*to_msg_param)(struct optee *optee,
 			    struct optee_msg_param *msg_params,
-			    size_t num_params, const struct tee_param *params);
+			    size_t num_params, const struct tee_param *params,
+			    bool update_out);
 	int (*from_msg_param)(struct optee *optee, struct tee_param *params,
 			      size_t num_params,
-			      const struct optee_msg_param *msg_params);
+			      const struct optee_msg_param *msg_params,
+			      bool update_out);
 };
 
 /**
@@ -316,23 +318,35 @@ void optee_release(struct tee_context *ctx);
 void optee_release_supp(struct tee_context *ctx);
 
 static inline void optee_from_msg_param_value(struct tee_param *p, u32 attr,
-					      const struct optee_msg_param *mp)
+					      const struct optee_msg_param *mp,
+					      bool update_out)
 {
-	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
-		  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
-	p->u.value.a = mp->u.value.a;
-	p->u.value.b = mp->u.value.b;
-	p->u.value.c = mp->u.value.c;
+	if (!update_out)
+		p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
+			  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
+
+	if (attr == OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT ||
+	    attr == OPTEE_MSG_ATTR_TYPE_VALUE_INOUT || !update_out) {
+		p->u.value.a = mp->u.value.a;
+		p->u.value.b = mp->u.value.b;
+		p->u.value.c = mp->u.value.c;
+	}
 }
 
 static inline void optee_to_msg_param_value(struct optee_msg_param *mp,
-					    const struct tee_param *p)
+					    const struct tee_param *p,
+					    bool update_out)
 {
-	mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
-		   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-	mp->u.value.a = p->u.value.a;
-	mp->u.value.b = p->u.value.b;
-	mp->u.value.c = p->u.value.c;
+	if (!update_out)
+		mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
+			   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
+
+	if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
+	    p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT || !update_out) {
+		mp->u.value.a = p->u.value.a;
+		mp->u.value.b = p->u.value.b;
+		mp->u.value.c = p->u.value.c;
+	}
 }
 
 void optee_cq_init(struct optee_call_queue *cq, int thread_count);
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index ebbbd42b0e3e..580e6b9b0606 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -63,7 +63,7 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 	}
 
 	if (optee->ops->from_msg_param(optee, params, arg->num_params,
-				       arg->params))
+				       arg->params, false /*!update_out*/))
 		goto bad;
 
 	for (i = 0; i < arg->num_params; i++) {
@@ -107,7 +107,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 	} else {
 		params[3].u.value.a = msg.len;
 		if (optee->ops->to_msg_param(optee, arg->params,
-					     arg->num_params, params))
+					     arg->num_params, params,
+					     true /*update_out*/))
 			arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		else
 			arg->ret = TEEC_SUCCESS;
@@ -188,6 +189,7 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
 static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
 				struct optee_msg_arg *arg)
 {
+	bool update_out = false;
 	struct tee_param *params;
 
 	arg->ret_origin = TEEC_ORIGIN_COMMS;
@@ -200,15 +202,21 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
 	}
 
 	if (optee->ops->from_msg_param(optee, params, arg->num_params,
-				       arg->params)) {
+				       arg->params, update_out)) {
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		goto out;
 	}
 
 	arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
 
+	/*
+	 * Special treatment for OPTEE_RPC_CMD_SHM_ALLOC since input is a
+	 * value type, but the output is a memref type.
+	 */
+	if (arg->cmd != OPTEE_RPC_CMD_SHM_ALLOC)
+		update_out = true;
 	if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
-				     params))
+				     params, update_out))
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 out:
 	kfree(params);
@@ -270,7 +278,7 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
 
 	if (arg->num_params != ARRAY_SIZE(params) ||
 	    optee->ops->from_msg_param(optee, params, arg->num_params,
-				       arg->params) ||
+				       arg->params, false /*!update_out*/) ||
 	    params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT) {
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		return;
@@ -280,7 +288,8 @@ static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx,
 	params[0].u.value.b = 0;
 	params[0].u.value.c = 0;
 	if (optee->ops->to_msg_param(optee, arg->params,
-				     arg->num_params, params)) {
+				     arg->num_params, params,
+				     true /*update_out*/)) {
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		return;
 	}
@@ -324,7 +333,7 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
 
 	if (arg->num_params != ARRAY_SIZE(params) ||
 	    optee->ops->from_msg_param(optee, params, arg->num_params,
-				       arg->params) ||
+				       arg->params, false /*!update_out*/) ||
 	    params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT ||
 	    params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -358,7 +367,8 @@ static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx,
 	params[0].u.value.b = rdev->descr.capacity;
 	params[0].u.value.c = rdev->descr.reliable_wr_count;
 	if (optee->ops->to_msg_param(optee, arg->params,
-				     arg->num_params, params)) {
+				     arg->num_params, params,
+				     true /*update_out*/)) {
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		return;
 	}
@@ -384,7 +394,7 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
 
 	if (arg->num_params != ARRAY_SIZE(params) ||
 	    optee->ops->from_msg_param(optee, params, arg->num_params,
-				       arg->params) ||
+				       arg->params, false /*!update_out*/) ||
 	    params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT ||
 	    params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) {
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -401,7 +411,8 @@ static void handle_rpc_func_rpmb_frames(struct tee_context *ctx,
 		goto out;
 	}
 	if (optee->ops->to_msg_param(optee, arg->params,
-				     arg->num_params, params)) {
+				     arg->num_params, params,
+				     true /*update_out*/)) {
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		goto out;
 	}
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index 3e33cf2af73b..788919a473d6 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -81,20 +81,26 @@ static int optee_cpuhp_disable_pcpu_irq(unsigned int cpu)
  */
 
 static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
-				  const struct optee_msg_param *mp)
+				  const struct optee_msg_param *mp,
+				  bool update_out)
 {
 	struct tee_shm *shm;
 	phys_addr_t pa;
 	int rc;
 
+	if (update_out) {
+		if (attr == OPTEE_MSG_ATTR_TYPE_TMEM_INPUT)
+			return 0;
+		goto out;
+	}
+
 	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
 		  attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
-	p->u.memref.size = mp->u.tmem.size;
 	shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
 	if (!shm) {
 		p->u.memref.shm_offs = 0;
 		p->u.memref.shm = NULL;
-		return 0;
+		goto out;
 	}
 
 	rc = tee_shm_get_pa(shm, 0, &pa);
@@ -103,18 +109,25 @@ static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
 
 	p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
 	p->u.memref.shm = shm;
-
+out:
+	p->u.memref.size = mp->u.tmem.size;
 	return 0;
 }
 
 static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
-				   const struct optee_msg_param *mp)
+				   const struct optee_msg_param *mp,
+				   bool update_out)
 {
 	struct tee_shm *shm;
 
+	if (update_out) {
+		if (attr == OPTEE_MSG_ATTR_TYPE_RMEM_INPUT)
+			return;
+		goto out;
+	}
+
 	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
 		  attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
-	p->u.memref.size = mp->u.rmem.size;
 	shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
 
 	if (shm) {
@@ -124,6 +137,8 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
 		p->u.memref.shm_offs = 0;
 		p->u.memref.shm = NULL;
 	}
+out:
+	p->u.memref.size = mp->u.rmem.size;
 }
 
 /**
@@ -133,11 +148,13 @@ static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
  * @params:	subsystem internal parameter representation
  * @num_params:	number of elements in the parameter arrays
  * @msg_params:	OPTEE_MSG parameters
+ * @update_out:	update parameter for output only
  * Returns 0 on success or <0 on failure
  */
 static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
 				size_t num_params,
-				const struct optee_msg_param *msg_params)
+				const struct optee_msg_param *msg_params,
+				bool update_out)
 {
 	int rc;
 	size_t n;
@@ -149,25 +166,27 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
 
 		switch (attr) {
 		case OPTEE_MSG_ATTR_TYPE_NONE:
+			if (update_out)
+				break;
 			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
 			memset(&p->u, 0, sizeof(p->u));
 			break;
 		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
-			optee_from_msg_param_value(p, attr, mp);
+			optee_from_msg_param_value(p, attr, mp, update_out);
 			break;
 		case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
-			rc = from_msg_param_tmp_mem(p, attr, mp);
+			rc = from_msg_param_tmp_mem(p, attr, mp, update_out);
 			if (rc)
 				return rc;
 			break;
 		case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
-			from_msg_param_reg_mem(p, attr, mp);
+			from_msg_param_reg_mem(p, attr, mp, update_out);
 			break;
 
 		default:
@@ -178,20 +197,25 @@ static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
 }
 
 static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
-				const struct tee_param *p)
+				const struct tee_param *p, bool update_out)
 {
 	int rc;
 	phys_addr_t pa;
 
+	if (update_out) {
+		if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
+			return 0;
+		goto out;
+	}
+
 	mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
 		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
 
 	mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
-	mp->u.tmem.size = p->u.memref.size;
 
 	if (!p->u.memref.shm) {
 		mp->u.tmem.buf_ptr = 0;
-		return 0;
+		goto out;
 	}
 
 	rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa);
@@ -201,19 +225,27 @@ static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
 	mp->u.tmem.buf_ptr = pa;
 	mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
 		    OPTEE_MSG_ATTR_CACHE_SHIFT;
-
+out:
+	mp->u.tmem.size = p->u.memref.size;
 	return 0;
 }
 
 static int to_msg_param_reg_mem(struct optee_msg_param *mp,
-				const struct tee_param *p)
+				const struct tee_param *p, bool update_out)
 {
+	if (update_out) {
+		if (p->attr == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
+			return 0;
+		goto out;
+	}
+
 	mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
 		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
 
 	mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm;
-	mp->u.rmem.size = p->u.memref.size;
 	mp->u.rmem.offs = p->u.memref.shm_offs;
+out:
+	mp->u.rmem.size = p->u.memref.size;
 	return 0;
 }
 
@@ -223,11 +255,13 @@ static int to_msg_param_reg_mem(struct optee_msg_param *mp,
  * @msg_params:	OPTEE_MSG parameters
  * @num_params:	number of elements in the parameter arrays
  * @params:	subsystem itnernal parameter representation
+ * @update_out:	update parameter for output only
  * Returns 0 on success or <0 on failure
  */
 static int optee_to_msg_param(struct optee *optee,
 			      struct optee_msg_param *msg_params,
-			      size_t num_params, const struct tee_param *params)
+			      size_t num_params, const struct tee_param *params,
+			      bool update_out)
 {
 	int rc;
 	size_t n;
@@ -238,21 +272,23 @@ static int optee_to_msg_param(struct optee *optee,
 
 		switch (p->attr) {
 		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
+			if (update_out)
+				break;
 			mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
 			memset(&mp->u, 0, sizeof(mp->u));
 			break;
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
-			optee_to_msg_param_value(mp, p);
+			optee_to_msg_param_value(mp, p, update_out);
 			break;
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
 			if (tee_shm_is_dynamic(p->u.memref.shm))
-				rc = to_msg_param_reg_mem(mp, p);
+				rc = to_msg_param_reg_mem(mp, p, update_out);
 			else
-				rc = to_msg_param_tmp_mem(mp, p);
+				rc = to_msg_param_tmp_mem(mp, p, update_out);
 			if (rc)
 				return rc;
 			break;
-- 
2.43.0



From jens.wiklander at linaro.org  Tue Dec 17 02:07:39 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 17 Dec 2024 11:07:39 +0100
Subject: [PATCH v4 3/6] optee: sync secure world ABI headers
In-Reply-To: <20241217100809.3962439-1-jens.wiklander@linaro.org>
References: <20241217100809.3962439-1-jens.wiklander@linaro.org>
Message-ID: <20241217100809.3962439-4-jens.wiklander@linaro.org>

Update the header files describing the secure world ABI, both with and
without FF-A. The ABI is extended to deal with restricted memory, but as
usual backward compatible.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/optee_ffa.h | 27 ++++++++++---
 drivers/tee/optee/optee_msg.h | 65 ++++++++++++++++++++++++++++++--
 drivers/tee/optee/optee_smc.h | 71 ++++++++++++++++++++++++++++++++++-
 3 files changed, 154 insertions(+), 9 deletions(-)

diff --git a/drivers/tee/optee/optee_ffa.h b/drivers/tee/optee/optee_ffa.h
index 257735ae5b56..7bd037200343 100644
--- a/drivers/tee/optee/optee_ffa.h
+++ b/drivers/tee/optee/optee_ffa.h
@@ -81,7 +81,7 @@
  *                   as the second MSG arg struct for
  *                   OPTEE_FFA_YIELDING_CALL_WITH_ARG.
  *        Bit[31:8]: Reserved (MBZ)
- * w5:	  Bitfield of secure world capabilities OPTEE_FFA_SEC_CAP_* below,
+ * w5:	  Bitfield of OP-TEE capabilities OPTEE_FFA_SEC_CAP_*
  * w6:	  The maximum secure world notification number
  * w7:	  Not used (MBZ)
  */
@@ -94,6 +94,8 @@
 #define OPTEE_FFA_SEC_CAP_ASYNC_NOTIF	BIT(1)
 /* OP-TEE supports probing for RPMB device if needed */
 #define OPTEE_FFA_SEC_CAP_RPMB_PROBE	BIT(2)
+/* OP-TEE supports Restricted Memory for secure data path */
+#define OPTEE_FFA_SEC_CAP_RSTMEM	BIT(3)
 
 #define OPTEE_FFA_EXCHANGE_CAPABILITIES OPTEE_FFA_BLOCKING_CALL(2)
 
@@ -108,7 +110,7 @@
  *
  * Return register usage:
  * w3:    Error code, 0 on success
- * w4-w7: Note used (MBZ)
+ * w4-w7: Not used (MBZ)
  */
 #define OPTEE_FFA_UNREGISTER_SHM	OPTEE_FFA_BLOCKING_CALL(3)
 
@@ -119,16 +121,31 @@
  * Call register usage:
  * w3:    Service ID, OPTEE_FFA_ENABLE_ASYNC_NOTIF
  * w4:	  Notification value to request bottom half processing, should be
- *	  less than OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE.
+ *	  less than OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE
  * w5-w7: Not used (MBZ)
  *
  * Return register usage:
  * w3:    Error code, 0 on success
- * w4-w7: Note used (MBZ)
+ * w4-w7: Not used (MBZ)
  */
 #define OPTEE_FFA_ENABLE_ASYNC_NOTIF	OPTEE_FFA_BLOCKING_CALL(5)
 
-#define OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE 64
+#define OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE	64
+
+/*
+ * Release Restricted memory
+ *
+ * Call register usage:
+ * w3:    Service ID, OPTEE_FFA_RECLAIM_RSTMEM
+ * w4:    Shared memory handle, lower bits
+ * w5:    Shared memory handle, higher bits
+ * w6-w7: Not used (MBZ)
+ *
+ * Return register usage:
+ * w3:    Error code, 0 on success
+ * w4-w7: Note used (MBZ)
+ */
+#define OPTEE_FFA_RELEASE_RSTMEM	OPTEE_FFA_BLOCKING_CALL(8)
 
 /*
  * Call with struct optee_msg_arg as argument in the supplied shared memory
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index e8840a82b983..1b558526e7d9 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -133,13 +133,13 @@ struct optee_msg_param_rmem {
 };
 
 /**
- * struct optee_msg_param_fmem - ffa memory reference parameter
+ * struct optee_msg_param_fmem - FF-A memory reference parameter
  * @offs_lower:	   Lower bits of offset into shared memory reference
  * @offs_upper:	   Upper bits of offset into shared memory reference
  * @internal_offs: Internal offset into the first page of shared memory
  *		   reference
  * @size:	   Size of the buffer
- * @global_id:	   Global identifier of Shared memory
+ * @global_id:	   Global identifier of the shared memory
  */
 struct optee_msg_param_fmem {
 	u32 offs_low;
@@ -165,7 +165,7 @@ struct optee_msg_param_value {
  * @attr:	attributes
  * @tmem:	parameter by temporary memory reference
  * @rmem:	parameter by registered memory reference
- * @fmem:	parameter by ffa registered memory reference
+ * @fmem:	parameter by FF-A registered memory reference
  * @value:	parameter by opaque value
  * @octets:	parameter by octet string
  *
@@ -296,6 +296,18 @@ struct optee_msg_arg {
  */
 #define OPTEE_MSG_FUNCID_GET_OS_REVISION	0x0001
 
+/*
+ * Values used in OPTEE_MSG_CMD_LEND_RSTMEM below
+ * OPTEE_MSG_RSTMEM_RESERVED		Reserved
+ * OPTEE_MSG_RSTMEM_SECURE_VIDEO_PLAY	Secure Video Playback
+ * OPTEE_MSG_RSTMEM_TRUSTED_UI		Trused UI
+ * OPTEE_MSG_RSTMEM_SECURE_VIDEO_RECORD	Secure Video Recording
+ */
+#define OPTEE_MSG_RSTMEM_RESERVED		0
+#define OPTEE_MSG_RSTMEM_SECURE_VIDEO_PLAY	1
+#define OPTEE_MSG_RSTMEM_TRUSTED_UI		2
+#define OPTEE_MSG_RSTMEM_SECURE_VIDEO_RECORD	3
+
 /*
  * Do a secure call with struct optee_msg_arg as argument
  * The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd
@@ -337,6 +349,49 @@ struct optee_msg_arg {
  * OPTEE_MSG_CMD_STOP_ASYNC_NOTIF informs secure world that from now is
  * normal world unable to process asynchronous notifications. Typically
  * used when the driver is shut down.
+ *
+ * OPTEE_MSG_CMD_LEND_RSTMEM lends restricted memory. The passed normal
+ * physical memory is restricted from normal world access. The memory
+ * should be unmapped prior to this call since it becomes inaccessible
+ * during the request.
+ * Parameters are passed as:
+ * [in] param[0].attr			OPTEE_MSG_ATTR_TYPE_VALUE_INPUT
+ * [in] param[0].u.value.a		OPTEE_MSG_RSTMEM_* defined above
+ * [in] param[1].attr			OPTEE_MSG_ATTR_TYPE_TMEM_INPUT
+ * [in] param[1].u.tmem.buf_ptr		physical address
+ * [in] param[1].u.tmem.size		size
+ * [in] param[1].u.tmem.shm_ref		holds restricted memory reference
+ *
+ * OPTEE_MSG_CMD_RECLAIM_RSTMEM reclaims a previously lent restricted
+ * memory reference. The physical memory is accessible by the normal world
+ * after this function has return and can be mapped again. The information
+ * is passed as:
+ * [in] param[0].attr			OPTEE_MSG_ATTR_TYPE_VALUE_INPUT
+ * [in] param[0].u.value.a		holds restricted memory cookie
+ *
+ * OPTEE_MSG_CMD_GET_RSTMEM_CONFIG get configuration for a specific
+ * restricted memory use case. Parameters are passed as:
+ * [in] param[0].attr			OPTEE_MSG_ATTR_TYPE_VALUE_INOUT
+ * [in] param[0].value.a		OPTEE_MSG_RSTMEM_*
+ * [in] param[1].attr			OPTEE_MSG_ATTR_TYPE_{R,F}MEM_OUTPUT
+ * [in] param[1].u.{r,f}mem		Buffer or NULL
+ * [in] param[1].u.{r,f}mem.size	Provided size of buffer or 0 for query
+ * output for the restricted use case:
+ * [out] param[0].value.a		Minimal size of SDP memory
+ * [out] param[0].value.b		Required alignment of size and start of
+ *					restricted memory
+ * [out] param[1].{r,f}mem.size		Size of output data
+ * [out] param[1].{r,f}mem		If non-NULL, contains an array of
+ *					uint16_t holding endpoints that
+ *					must be included when lending
+ *					memory for this use case
+ *
+ * OPTEE_MSG_CMD_ASSIGN_RSTMEM assigns use-case to restricted memory
+ * previously lent using the FFA_LEND framework ABI. Parameters are passed
+ * as:
+ * [in] param[0].attr			OPTEE_MSG_ATTR_TYPE_VALUE_INPUT
+ * [in] param[0].u.value.a		holds restricted memory cookie
+ * [in] param[0].u.value.b		OPTEE_MSG_RSTMEM_* defined above
  */
 #define OPTEE_MSG_CMD_OPEN_SESSION	0
 #define OPTEE_MSG_CMD_INVOKE_COMMAND	1
@@ -346,6 +401,10 @@ struct optee_msg_arg {
 #define OPTEE_MSG_CMD_UNREGISTER_SHM	5
 #define OPTEE_MSG_CMD_DO_BOTTOM_HALF	6
 #define OPTEE_MSG_CMD_STOP_ASYNC_NOTIF	7
+#define OPTEE_MSG_CMD_LEND_RSTMEM	8
+#define OPTEE_MSG_CMD_RECLAIM_RSTMEM	9
+#define OPTEE_MSG_CMD_GET_RSTMEM_CONFIG	10
+#define OPTEE_MSG_CMD_ASSIGN_RSTMEM	11
 #define OPTEE_MSG_FUNCID_CALL_WITH_ARG	0x0004
 
 #endif /* _OPTEE_MSG_H */
diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h
index 879426300821..abc379ce190c 100644
--- a/drivers/tee/optee/optee_smc.h
+++ b/drivers/tee/optee/optee_smc.h
@@ -264,7 +264,6 @@ struct optee_smc_get_shm_config_result {
 #define OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM	BIT(0)
 /* Secure world can communicate via previously unregistered shared memory */
 #define OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM	BIT(1)
-
 /*
  * Secure world supports commands "register/unregister shared memory",
  * secure world accepts command buffers located in any parts of non-secure RAM
@@ -280,6 +279,10 @@ struct optee_smc_get_shm_config_result {
 #define OPTEE_SMC_SEC_CAP_RPC_ARG		BIT(6)
 /* Secure world supports probing for RPMB device if needed */
 #define OPTEE_SMC_SEC_CAP_RPMB_PROBE		BIT(7)
+/* Secure world supports Secure Data Path */
+#define OPTEE_SMC_SEC_CAP_SDP			BIT(8)
+/* Secure world supports dynamic restricted memory */
+#define OPTEE_SMC_SEC_CAP_DYNAMIC_RSTMEM	BIT(9)
 
 #define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES	9
 #define OPTEE_SMC_EXCHANGE_CAPABILITIES \
@@ -451,6 +454,72 @@ struct optee_smc_disable_shm_cache_result {
 
 /* See OPTEE_SMC_CALL_WITH_REGD_ARG above */
 #define OPTEE_SMC_FUNCID_CALL_WITH_REGD_ARG	19
+/*
+ * Get Secure Data Path memory config
+ *
+ * Returns the Secure Data Path memory config.
+ *
+ * Call register usage:
+ * a0   SMC Function ID, OPTEE_SMC_GET_SDP_CONFIG
+ * a2-6	Not used, must be zero
+ * a7	Hypervisor Client ID register
+ *
+ * Have config return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1	Physical address of start of SDP memory
+ * a2	Size of SDP memory
+ * a3	Not used
+ * a4-7	Preserved
+ *
+ * Not available register usage:
+ * a0	OPTEE_SMC_RETURN_ENOTAVAIL
+ * a1-3 Not used
+ * a4-7	Preserved
+ */
+#define OPTEE_SMC_FUNCID_GET_SDP_CONFIG		20
+#define OPTEE_SMC_GET_SDP_CONFIG \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_SDP_CONFIG)
+
+struct optee_smc_get_sdp_config_result {
+	unsigned long status;
+	unsigned long start;
+	unsigned long size;
+	unsigned long flags;
+};
+
+/*
+ * Get Secure Data Path dynamic memory config
+ *
+ * Returns the Secure Data Path dynamic memory config.
+ *
+ * Call register usage:
+ * a0	SMC Function ID, OPTEE_SMC_GET_DYN_SHM_CONFIG
+ * a2-6	Not used, must be zero
+ * a7	Hypervisor Client ID register
+ *
+ * Have config return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1	Minamal size of SDP memory
+ * a2	Required alignment of size and start of registered SDP memory
+ * a3	Not used
+ * a4-7	Preserved
+ *
+ * Not available register usage:
+ * a0	OPTEE_SMC_RETURN_ENOTAVAIL
+ * a1-3 Not used
+ * a4-7	Preserved
+ */
+
+#define OPTEE_SMC_FUNCID_GET_DYN_SDP_CONFIG	21
+#define OPTEE_SMC_GET_DYN_SDP_CONFIG \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_DYN_SDP_CONFIG)
+
+struct optee_smc_get_dyn_sdp_config_result {
+	unsigned long status;
+	unsigned long size;
+	unsigned long align;
+	unsigned long flags;
+};
 
 /*
  * Resume from RPC (for example after processing a foreign interrupt)
-- 
2.43.0



From jens.wiklander at linaro.org  Tue Dec 17 02:07:40 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 17 Dec 2024 11:07:40 +0100
Subject: [PATCH v4 4/6] optee: support restricted memory allocation
In-Reply-To: <20241217100809.3962439-1-jens.wiklander@linaro.org>
References: <20241217100809.3962439-1-jens.wiklander@linaro.org>
Message-ID: <20241217100809.3962439-5-jens.wiklander@linaro.org>

Add support in the OP-TEE backend driver for restricted memory
allocation. The support is limited to only the SMC ABI and for secure
video buffers.

OP-TEE is probed for the range of restricted physical memory and a
memory pool allocator is initialized if OP-TEE have support for such
memory.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/Makefile        |  1 +
 drivers/tee/optee/core.c          |  1 +
 drivers/tee/optee/optee_private.h | 23 ++++++++++
 drivers/tee/optee/rstmem.c        | 76 +++++++++++++++++++++++++++++++
 drivers/tee/optee/smc_abi.c       | 69 ++++++++++++++++++++++++++--
 5 files changed, 167 insertions(+), 3 deletions(-)
 create mode 100644 drivers/tee/optee/rstmem.c

diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index a6eff388d300..498969fb8e40 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -4,6 +4,7 @@ optee-objs += core.o
 optee-objs += call.o
 optee-objs += notif.o
 optee-objs += rpc.o
+optee-objs += rstmem.o
 optee-objs += supp.o
 optee-objs += device.o
 optee-objs += smc_abi.o
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index c75fddc83576..f4fa494789a4 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -182,6 +182,7 @@ void optee_remove_common(struct optee *optee)
 	tee_device_unregister(optee->teedev);
 
 	tee_shm_pool_free(optee->pool);
+	optee_rstmem_pools_uninit(optee);
 	optee_supp_uninit(&optee->supp);
 	mutex_destroy(&optee->call_queue.mutex);
 	rpmb_dev_put(optee->rpmb_dev);
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 20eda508dbac..0491889e5b0e 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -193,6 +193,20 @@ struct optee_ops {
 			      bool update_out);
 };
 
+/**
+ * struct optee_rstmem_pools - restricted memory pools
+ * @mutex:	serializes write access to @xa when adding a new pool.
+ * @xa:		XArray of struct tee_shm_pool where the index is the
+ *		use case ID TEE_IOC_UC_* supplied for TEE_IOC_RSTMEM_ALLOC.
+ */
+struct optee_rstmem_pools {
+	/*
+	 * Serializes write access to @xa when adding a new pool.
+	 */
+	struct mutex mutex;
+	struct xarray xa;
+};
+
 /**
  * struct optee - main service struct
  * @supp_teedev:	supplicant device
@@ -206,6 +220,7 @@ struct optee_ops {
  * @notif:		notification synchronization struct
  * @supp:		supplicant synchronization struct for RPC to supplicant
  * @pool:		shared memory pool
+ * @rstmem_pool:	restricted memory pool for secure data path
  * @mutex:		mutex protecting @rpmb_dev
  * @rpmb_dev:		current RPMB device or NULL
  * @rpmb_scan_bus_done	flag if device registation of RPMB dependent devices
@@ -230,6 +245,7 @@ struct optee {
 	struct optee_notif notif;
 	struct optee_supp supp;
 	struct tee_shm_pool *pool;
+	struct optee_rstmem_pools *rstmem_pools;
 	/* Protects rpmb_dev pointer */
 	struct mutex rpmb_dev_mutex;
 	struct rpmb_dev *rpmb_dev;
@@ -286,6 +302,9 @@ void optee_supp_init(struct optee_supp *supp);
 void optee_supp_uninit(struct optee_supp *supp);
 void optee_supp_release(struct optee_supp *supp);
 
+int optee_rstmem_pools_init(struct optee *optee);
+void optee_rstmem_pools_uninit(struct optee *optee);
+
 int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
 		    struct tee_param *param);
 int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
@@ -378,6 +397,10 @@ void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
 int optee_do_bottom_half(struct tee_context *ctx);
 int optee_stop_async_notif(struct tee_context *ctx);
 
+int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
+		       u32 flags, u32 use_case, size_t size);
+void optee_rstmem_free(struct tee_context *ctx, struct tee_shm *shm);
+
 /*
  * Small helpers
  */
diff --git a/drivers/tee/optee/rstmem.c b/drivers/tee/optee/rstmem.c
new file mode 100644
index 000000000000..01456bc3e2f6
--- /dev/null
+++ b/drivers/tee/optee/rstmem.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Linaro Limited
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/dma-map-ops.h>
+#include <linux/errno.h>
+#include <linux/genalloc.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/tee_core.h>
+#include <linux/types.h>
+#include "optee_private.h"
+
+int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
+		       u32 flags, u32 use_case, size_t size)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct tee_shm_pool *pool;
+
+	if (!optee->rstmem_pools)
+		return -EINVAL;
+	if (flags)
+		return -EINVAL;
+
+	pool = xa_load(&optee->rstmem_pools->xa, use_case);
+	if (!pool)
+		return -EINVAL;
+
+	return pool->ops->alloc(pool, shm, size, 0);
+}
+
+void optee_rstmem_free(struct tee_context *ctx, struct tee_shm *shm)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct tee_shm_pool *pool;
+
+	pool = xa_load(&optee->rstmem_pools->xa, shm->use_case);
+	if (pool)
+		pool->ops->free(pool, shm);
+	else
+		pr_err("Can't find pool for use_case %u\n", shm->use_case);
+}
+
+int optee_rstmem_pools_init(struct optee *optee)
+{
+	struct optee_rstmem_pools *pools;
+
+	pools = kmalloc(sizeof(*pools), GFP_KERNEL);
+	if (!pools)
+		return -ENOMEM;
+
+	mutex_init(&pools->mutex);
+	xa_init(&pools->xa);
+	optee->rstmem_pools = pools;
+	return 0;
+}
+
+void optee_rstmem_pools_uninit(struct optee *optee)
+{
+	if (optee->rstmem_pools) {
+		struct tee_shm_pool *pool;
+		u_long idx;
+
+		xa_for_each(&optee->rstmem_pools->xa, idx, pool) {
+			xa_erase(&optee->rstmem_pools->xa, idx);
+			pool->ops->destroy_pool(pool);
+		}
+
+		xa_destroy(&optee->rstmem_pools->xa);
+		mutex_destroy(&optee->rstmem_pools->mutex);
+		kfree(optee->rstmem_pools);
+		optee->rstmem_pools = NULL;
+	}
+}
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index 788919a473d6..f5fd5f1d9a6b 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -1201,6 +1201,8 @@ static void optee_get_version(struct tee_device *teedev,
 		v.gen_caps |= TEE_GEN_CAP_REG_MEM;
 	if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
 		v.gen_caps |= TEE_GEN_CAP_MEMREF_NULL;
+	if (optee->rstmem_pools)
+		v.gen_caps |= TEE_GEN_CAP_RSTMEM;
 	*vers = v;
 }
 
@@ -1223,6 +1225,8 @@ static const struct tee_driver_ops optee_clnt_ops = {
 	.cancel_req = optee_cancel_req,
 	.shm_register = optee_shm_register,
 	.shm_unregister = optee_shm_unregister,
+	.rstmem_alloc = optee_rstmem_alloc,
+	.rstmem_free = optee_rstmem_free,
 };
 
 static const struct tee_desc optee_clnt_desc = {
@@ -1239,6 +1243,8 @@ static const struct tee_driver_ops optee_supp_ops = {
 	.supp_send = optee_supp_send,
 	.shm_register = optee_shm_register_supp,
 	.shm_unregister = optee_shm_unregister_supp,
+	.rstmem_alloc = optee_rstmem_alloc,
+	.rstmem_free = optee_rstmem_free,
 };
 
 static const struct tee_desc optee_supp_desc = {
@@ -1619,6 +1625,57 @@ static inline int optee_load_fw(struct platform_device *pdev,
 }
 #endif
 
+static int optee_sdp_pool_init(struct optee *optee)
+{
+	bool sdp = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP;
+	struct tee_shm_pool *pool;
+	int rc;
+
+	/*
+	 * optee_sdp_pools_init() must be called if secure world has any
+	 * SDP capability. If the static carvout is available initialize
+	 * and add a pool for that.
+	 */
+	if (!sdp)
+		return 0;
+
+	rc = optee_rstmem_pools_init(optee);
+	if (rc)
+		return rc;
+
+	if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP) {
+		union {
+			struct arm_smccc_res smccc;
+			struct optee_smc_get_sdp_config_result result;
+		} res;
+
+		optee->smc.invoke_fn(OPTEE_SMC_GET_SDP_CONFIG, 0, 0, 0, 0, 0, 0,
+				     0, &res.smccc);
+		if (res.result.status != OPTEE_SMC_RETURN_OK) {
+			pr_err("Secure Data Path service not available\n");
+			goto err;
+		}
+
+		pool = tee_rstmem_gen_pool_alloc(res.result.start,
+						 res.result.size);
+		if (IS_ERR(pool)) {
+			rc = PTR_ERR(pool);
+			goto err;
+		}
+		rc = xa_insert(&optee->rstmem_pools->xa,
+			       TEE_IOC_UC_SECURE_VIDEO_PLAY, pool, GFP_KERNEL);
+		if (rc) {
+			pool->ops->destroy_pool(pool);
+			goto err;
+		}
+	}
+
+	return 0;
+err:
+	optee_rstmem_pools_uninit(optee);
+	return rc;
+}
+
 static int optee_probe(struct platform_device *pdev)
 {
 	optee_invoke_fn *invoke_fn;
@@ -1714,7 +1771,7 @@ static int optee_probe(struct platform_device *pdev)
 	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
 	if (!optee) {
 		rc = -ENOMEM;
-		goto err_free_pool;
+		goto err_free_shm_pool;
 	}
 
 	optee->ops = &optee_ops;
@@ -1726,10 +1783,14 @@ static int optee_probe(struct platform_device *pdev)
 	    (sec_caps & OPTEE_SMC_SEC_CAP_RPMB_PROBE))
 		optee->in_kernel_rpmb_routing = true;
 
+	rc = optee_sdp_pool_init(optee);
+	if (rc)
+		goto err_free_optee;
+
 	teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
 	if (IS_ERR(teedev)) {
 		rc = PTR_ERR(teedev);
-		goto err_free_optee;
+		goto err_rstmem_pools_uninit;
 	}
 	optee->teedev = teedev;
 
@@ -1836,9 +1897,11 @@ static int optee_probe(struct platform_device *pdev)
 	tee_device_unregister(optee->supp_teedev);
 err_unreg_teedev:
 	tee_device_unregister(optee->teedev);
+err_rstmem_pools_uninit:
+	optee_rstmem_pools_uninit(optee);
 err_free_optee:
 	kfree(optee);
-err_free_pool:
+err_free_shm_pool:
 	tee_shm_pool_free(pool);
 	if (memremaped_shm)
 		memunmap(memremaped_shm);
-- 
2.43.0



From jens.wiklander at linaro.org  Tue Dec 17 02:07:41 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 17 Dec 2024 11:07:41 +0100
Subject: [PATCH v4 5/6] optee: FF-A: dynamic restricted memory allocation
In-Reply-To: <20241217100809.3962439-1-jens.wiklander@linaro.org>
References: <20241217100809.3962439-1-jens.wiklander@linaro.org>
Message-ID: <20241217100809.3962439-6-jens.wiklander@linaro.org>

Add support in the OP-TEE backend driver dynamic restricted memory
allocation with FF-A.

The restricted memory pools for dynamically allocated restrict memory
are instantiated when requested by user-space. This instantiation can
fail if OP-TEE doesn't support the requested use-case of restricted
memory.

Restricted memory pools based on a static carveout or dynamic allocation
can coexist for different use-cases. We use only dynamic allocation with
FF-A.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/ffa_abi.c       | 135 ++++++++++++-
 drivers/tee/optee/optee_private.h |  10 +-
 drivers/tee/optee/rstmem.c        | 316 +++++++++++++++++++++++++++++-
 3 files changed, 457 insertions(+), 4 deletions(-)

diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index 02e6175ac5f0..f500cf101c8d 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -672,6 +672,122 @@ static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
 	return optee_ffa_yielding_call(ctx, &data, rpc_arg, system_thread);
 }
 
+static int do_call_lend_rstmem(struct optee *optee, u64 cookie, u32 use_case)
+{
+	struct optee_shm_arg_entry *entry;
+	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm;
+	u_int offs;
+	int rc;
+
+	msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs);
+	if (IS_ERR(msg_arg))
+		return PTR_ERR(msg_arg);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_ASSIGN_RSTMEM;
+	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
+	msg_arg->params[0].u.value.a = cookie;
+	msg_arg->params[0].u.value.b = use_case;
+
+	rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
+	if (rc)
+		goto out;
+	if (msg_arg->ret != TEEC_SUCCESS) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+out:
+	optee_free_msg_arg(optee->ctx, entry, offs);
+	return rc;
+}
+
+static int optee_ffa_lend_rstmem(struct optee *optee, struct tee_shm *rstmem,
+				 u16 *end_points, unsigned int ep_count)
+{
+	struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
+	const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops;
+	const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops;
+	struct ffa_send_direct_data data;
+	struct ffa_mem_region_attributes *mem_attr;
+	struct ffa_mem_ops_args args = {
+		.use_txbuf = true,
+		.tag = rstmem->use_case,
+	};
+	struct page *page;
+	struct scatterlist sgl;
+	unsigned int n;
+	int rc;
+
+	mem_attr = kcalloc(ep_count, sizeof(*mem_attr), GFP_KERNEL);
+	for (n = 0; n < ep_count; n++) {
+		mem_attr[n].receiver = end_points[n];
+		mem_attr[n].attrs = FFA_MEM_RW;
+	}
+	args.attrs = mem_attr;
+	args.nattrs = ep_count;
+
+	page = phys_to_page(rstmem->paddr);
+	sg_init_table(&sgl, 1);
+	sg_set_page(&sgl, page, rstmem->size, 0);
+
+	args.sg = &sgl;
+	rc = mem_ops->memory_lend(&args);
+	kfree(mem_attr);
+	if (rc)
+		return rc;
+
+	rc = do_call_lend_rstmem(optee, args.g_handle, rstmem->use_case);
+	if (rc)
+		goto err_reclaim;
+
+	rc = optee_shm_add_ffa_handle(optee, rstmem, args.g_handle);
+	if (rc)
+		goto err_unreg;
+
+	rstmem->sec_world_id = args.g_handle;
+
+	return 0;
+
+err_unreg:
+	data = (struct ffa_send_direct_data){
+		.data0 = OPTEE_FFA_RELEASE_RSTMEM,
+		.data1 = (u32)args.g_handle,
+		.data2 = (u32)(args.g_handle >> 32),
+	};
+	msg_ops->sync_send_receive(ffa_dev, &data);
+err_reclaim:
+	mem_ops->memory_reclaim(args.g_handle, 0);
+	return rc;
+}
+
+static int optee_ffa_reclaim_rstmem(struct optee *optee, struct tee_shm *rstmem)
+{
+	struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
+	const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops;
+	const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops;
+	u64 global_handle = rstmem->sec_world_id;
+	struct ffa_send_direct_data data = {
+		.data0 = OPTEE_FFA_RELEASE_RSTMEM,
+		.data1 = (u32)global_handle,
+		.data2 = (u32)(global_handle >> 32)
+	};
+	int rc;
+
+	optee_shm_rem_ffa_handle(optee, global_handle);
+	rstmem->sec_world_id = 0;
+
+	rc = msg_ops->sync_send_receive(ffa_dev, &data);
+	if (rc)
+		pr_err("Release SHM id 0x%llx rc %d\n", global_handle, rc);
+
+	rc = mem_ops->memory_reclaim(global_handle, 0);
+	if (rc)
+		pr_err("mem_reclaim: 0x%llx %d", global_handle, rc);
+
+	return rc;
+}
+
 /*
  * 6. Driver initialization
  *
@@ -785,7 +901,10 @@ static void optee_ffa_get_version(struct tee_device *teedev,
 		.gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM |
 			    TEE_GEN_CAP_MEMREF_NULL,
 	};
+	struct optee *optee = tee_get_drvdata(teedev);
 
+	if (optee->rstmem_pools)
+		v.gen_caps |= TEE_GEN_CAP_RSTMEM;
 	*vers = v;
 }
 
@@ -804,6 +923,8 @@ static const struct tee_driver_ops optee_ffa_clnt_ops = {
 	.cancel_req = optee_cancel_req,
 	.shm_register = optee_ffa_shm_register,
 	.shm_unregister = optee_ffa_shm_unregister,
+	.rstmem_alloc = optee_rstmem_alloc,
+	.rstmem_free = optee_rstmem_free,
 };
 
 static const struct tee_desc optee_ffa_clnt_desc = {
@@ -820,6 +941,8 @@ static const struct tee_driver_ops optee_ffa_supp_ops = {
 	.supp_send = optee_supp_send,
 	.shm_register = optee_ffa_shm_register, /* same as for clnt ops */
 	.shm_unregister = optee_ffa_shm_unregister_supp,
+	.rstmem_alloc = optee_rstmem_alloc,
+	.rstmem_free = optee_rstmem_free,
 };
 
 static const struct tee_desc optee_ffa_supp_desc = {
@@ -833,6 +956,8 @@ static const struct optee_ops optee_ffa_ops = {
 	.do_call_with_arg = optee_ffa_do_call_with_arg,
 	.to_msg_param = optee_ffa_to_msg_param,
 	.from_msg_param = optee_ffa_from_msg_param,
+	.lend_rstmem = optee_ffa_lend_rstmem,
+	.reclaim_rstmem = optee_ffa_reclaim_rstmem,
 };
 
 static void optee_ffa_remove(struct ffa_device *ffa_dev)
@@ -937,11 +1062,17 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
 	    (sec_caps & OPTEE_FFA_SEC_CAP_RPMB_PROBE))
 		optee->in_kernel_rpmb_routing = true;
 
+	if (sec_caps & OPTEE_FFA_SEC_CAP_RSTMEM) {
+		rc = optee_rstmem_pools_init(optee);
+		if (rc)
+			goto err_free_pool;
+	}
+
 	teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool,
 				  optee);
 	if (IS_ERR(teedev)) {
 		rc = PTR_ERR(teedev);
-		goto err_free_pool;
+		goto err_free_rstmem_pools;
 	}
 	optee->teedev = teedev;
 
@@ -1020,6 +1151,8 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
 	tee_device_unregister(optee->teedev);
 err_free_pool:
 	tee_shm_pool_free(pool);
+err_free_rstmem_pools:
+	optee_rstmem_pools_uninit(optee);
 err_free_optee:
 	kfree(optee);
 	return rc;
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 0491889e5b0e..dd2a3a2224bc 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -174,9 +174,14 @@ struct optee;
  * @do_call_with_arg:	enters OP-TEE in secure world
  * @to_msg_param:	converts from struct tee_param to OPTEE_MSG parameters
  * @from_msg_param:	converts from OPTEE_MSG parameters to struct tee_param
+ * @lend_rstmem:	lends physically contiguous memory as restricted
+ *			memory, inaccessible by the kernel
+ * @reclaim_rstmem:	reclaims restricted memory previously lent with
+ *			@lend_rstmem() and makes it accessible by the
+ *			kernel again
  *
  * These OPs are only supposed to be used internally in the OP-TEE driver
- * as a way of abstracting the different methogs of entering OP-TEE in
+ * as a way of abstracting the different methods of entering OP-TEE in
  * secure world.
  */
 struct optee_ops {
@@ -191,6 +196,9 @@ struct optee_ops {
 			      size_t num_params,
 			      const struct optee_msg_param *msg_params,
 			      bool update_out);
+	int (*lend_rstmem)(struct optee *optee, struct tee_shm *rstmem,
+			   u16 *end_points, unsigned int ep_count);
+	int (*reclaim_rstmem)(struct optee *optee, struct tee_shm *rstmem);
 };
 
 /**
diff --git a/drivers/tee/optee/rstmem.c b/drivers/tee/optee/rstmem.c
index 01456bc3e2f6..8c561d638733 100644
--- a/drivers/tee/optee/rstmem.c
+++ b/drivers/tee/optee/rstmem.c
@@ -4,6 +4,7 @@
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/cma.h>
 #include <linux/dma-map-ops.h>
 #include <linux/errno.h>
 #include <linux/genalloc.h>
@@ -13,11 +14,313 @@
 #include <linux/types.h>
 #include "optee_private.h"
 
+#ifdef CONFIG_CMA
+struct optee_rstmem_cma_pool {
+	struct tee_shm_pool pool;
+	struct page *page;
+	struct optee *optee;
+	size_t page_count;
+	u16 *end_points;
+	u_int end_point_count;
+	u_int align;
+	refcount_t refcount;
+	struct tee_shm rstmem;
+	/* Protects when initializing and tearing down this struct */
+	struct mutex mutex;
+};
+
+static struct optee_rstmem_cma_pool *
+to_rstmem_cma_pool(struct tee_shm_pool *pool)
+{
+	return container_of(pool, struct optee_rstmem_cma_pool, pool);
+}
+
+static int init_cma_rstmem(struct optee_rstmem_cma_pool *rp)
+{
+	struct cma *cma = dev_get_cma_area(&rp->optee->teedev->dev);
+	int rc;
+
+	rp->page = cma_alloc(cma, rp->page_count, rp->align, true/*no_warn*/);
+	if (!rp->page)
+		return -ENOMEM;
+
+	/*
+	 * TODO unmap the memory range since the physical memory will
+	 * become inaccesible after the lend_rstmem() call.
+	 */
+
+	rp->rstmem.paddr = page_to_phys(rp->page);
+	rp->rstmem.size = rp->page_count * PAGE_SIZE;
+	rc = rp->optee->ops->lend_rstmem(rp->optee, &rp->rstmem,
+					 rp->end_points, rp->end_point_count);
+	if (rc)
+		goto err_release;
+
+	rp->pool.private_data = gen_pool_create(PAGE_SHIFT, -1);
+	if (!rp->pool.private_data) {
+		rc = -ENOMEM;
+		goto err_reclaim;
+	}
+
+	rc = gen_pool_add(rp->pool.private_data, rp->rstmem.paddr,
+			  rp->rstmem.size, -1);
+	if (rc)
+		goto err_free_pool;
+
+	refcount_set(&rp->refcount, 1);
+	return 0;
+
+err_free_pool:
+	gen_pool_destroy(rp->pool.private_data);
+err_reclaim:
+	rp->optee->ops->reclaim_rstmem(rp->optee, &rp->rstmem);
+err_release:
+	cma_release(cma, rp->page, rp->page_count);
+	rp->rstmem.paddr = 0;
+	rp->rstmem.size = 0;
+	rp->rstmem.sec_world_id = 0;
+	return rc;
+}
+
+static int get_cma_rstmem(struct optee_rstmem_cma_pool *rp)
+{
+	int rc = 0;
+
+	if (!refcount_inc_not_zero(&rp->refcount)) {
+		mutex_lock(&rp->mutex);
+		if (rp->pool.private_data) {
+			/*
+			 * Another thread has already initialized the pool
+			 * before us, or the pool was just about to be torn
+			 * down. Either way we only need to increase the
+			 * refcount and we're done.
+			 */
+			refcount_inc(&rp->refcount);
+		} else {
+			rc = init_cma_rstmem(rp);
+		}
+		mutex_unlock(&rp->mutex);
+	}
+
+	return rc;
+}
+
+static void release_cma_rstmem(struct optee_rstmem_cma_pool *rp)
+{
+	gen_pool_destroy(rp->pool.private_data);
+	rp->optee->ops->reclaim_rstmem(rp->optee, &rp->rstmem);
+	cma_release(dev_get_cma_area(&rp->optee->teedev->dev), rp->page,
+		    rp->page_count);
+
+	rp->pool.private_data = NULL;
+	rp->page = NULL;
+	rp->rstmem.paddr = 0;
+	rp->rstmem.size = 0;
+	rp->rstmem.sec_world_id = 0;
+}
+
+static void put_cma_rstmem(struct optee_rstmem_cma_pool *rp)
+{
+	if (refcount_dec_and_test(&rp->refcount)) {
+		mutex_lock(&rp->mutex);
+		if (rp->pool.private_data)
+			release_cma_rstmem(rp);
+		mutex_unlock(&rp->mutex);
+	}
+}
+
+static int rstmem_pool_op_cma_alloc(struct tee_shm_pool *pool,
+				    struct tee_shm *shm, size_t size,
+				    size_t align)
+{
+	struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool);
+	size_t sz = ALIGN(size, PAGE_SIZE);
+	phys_addr_t pa;
+	int rc;
+
+	rc = get_cma_rstmem(rp);
+	if (rc)
+		return rc;
+
+	pa = gen_pool_alloc(rp->pool.private_data, sz);
+	if (!pa) {
+		put_cma_rstmem(rp);
+		return -ENOMEM;
+	}
+
+	shm->size = sz;
+	shm->paddr = pa;
+	shm->offset = pa - page_to_phys(rp->page);
+	shm->sec_world_id = rp->rstmem.sec_world_id;
+
+	return 0;
+}
+
+static void rstmem_pool_op_cma_free(struct tee_shm_pool *pool,
+				    struct tee_shm *shm)
+{
+	struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool);
+
+	gen_pool_free(rp->pool.private_data, shm->paddr, shm->size);
+	shm->size = 0;
+	shm->paddr = 0;
+	shm->offset = 0;
+	shm->sec_world_id = 0;
+	put_cma_rstmem(rp);
+}
+
+static void pool_op_cma_destroy_pool(struct tee_shm_pool *pool)
+{
+	struct optee_rstmem_cma_pool *rp = to_rstmem_cma_pool(pool);
+
+	mutex_destroy(&rp->mutex);
+	kfree(rp);
+}
+
+static struct tee_shm_pool_ops rstmem_pool_ops_cma = {
+	.alloc = rstmem_pool_op_cma_alloc,
+	.free = rstmem_pool_op_cma_free,
+	.destroy_pool = pool_op_cma_destroy_pool,
+};
+
+static int get_rstmem_config(struct optee *optee, u32 use_case,
+			     size_t *min_size, u_int *min_align,
+			     u16 *end_points, u_int *ep_count)
+{
+	struct tee_param params[2] = {
+		[0] = {
+			.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT,
+			.u.value.a = use_case,
+		},
+		[1] = {
+			.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT,
+		},
+	};
+	struct optee_shm_arg_entry *entry;
+	struct tee_shm *shm_param = NULL;
+	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm;
+	u_int offs;
+	int rc;
+
+	if (end_points && *ep_count) {
+		params[1].u.memref.size = *ep_count * sizeof(*end_points);
+		shm_param = tee_shm_alloc_priv_buf(optee->ctx,
+						   params[1].u.memref.size);
+		if (IS_ERR(shm_param))
+			return PTR_ERR(shm_param);
+		params[1].u.memref.shm = shm_param;
+	}
+
+	msg_arg = optee_get_msg_arg(optee->ctx, ARRAY_SIZE(params), &entry,
+				    &shm, &offs);
+	if (IS_ERR(msg_arg)) {
+		rc = PTR_ERR(msg_arg);
+		goto out_free_shm;
+	}
+	msg_arg->cmd = OPTEE_MSG_CMD_GET_RSTMEM_CONFIG;
+
+	rc = optee->ops->to_msg_param(optee, msg_arg->params,
+				      ARRAY_SIZE(params), params,
+				      false /*!update_out*/);
+	if (rc)
+		goto out_free_msg;
+
+	rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
+	if (rc)
+		goto out_free_msg;
+	if (msg_arg->ret && msg_arg->ret != TEEC_ERROR_SHORT_BUFFER) {
+		rc = -EINVAL;
+		goto out_free_msg;
+	}
+
+	rc = optee->ops->from_msg_param(optee, params, ARRAY_SIZE(params),
+					msg_arg->params, true /*update_out*/);
+	if (rc)
+		goto out_free_msg;
+
+	if (!msg_arg->ret && end_points &&
+	    *ep_count < params[1].u.memref.size / sizeof(u16)) {
+		rc = -EINVAL;
+		goto out_free_msg;
+	}
+
+	*min_size = params[0].u.value.a;
+	*min_align = params[0].u.value.b;
+	*ep_count = params[1].u.memref.size / sizeof(u16);
+
+	if (msg_arg->ret == TEEC_ERROR_SHORT_BUFFER) {
+		rc = -ENOSPC;
+		goto out_free_msg;
+	}
+
+	if (end_points)
+		memcpy(end_points, tee_shm_get_va(shm_param, 0),
+		       params[1].u.memref.size);
+
+out_free_msg:
+	optee_free_msg_arg(optee->ctx, entry, offs);
+out_free_shm:
+	if (shm_param)
+		tee_shm_free(shm_param);
+	return rc;
+}
+
+static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee, u32 use_case)
+{
+	struct optee_rstmem_cma_pool *rp;
+	size_t min_size;
+	int rc;
+
+	rp = kzalloc(sizeof(*rp), GFP_KERNEL);
+	if (!rp)
+		return ERR_PTR(-ENOMEM);
+	rp->rstmem.use_case = use_case;
+
+	rc = get_rstmem_config(optee, use_case, &min_size, &rp->align, NULL,
+			       &rp->end_point_count);
+	if (rc) {
+		if (rc != -ENOSPC)
+			goto err;
+		rp->end_points = kcalloc(rp->end_point_count,
+					 sizeof(*rp->end_points), GFP_KERNEL);
+		if (!rp->end_points) {
+			rc = -ENOMEM;
+			goto err;
+		}
+		rc = get_rstmem_config(optee, use_case, &min_size, &rp->align,
+				       rp->end_points, &rp->end_point_count);
+		if (rc)
+			goto err_kfree_eps;
+	}
+
+	rp->pool.ops = &rstmem_pool_ops_cma;
+	rp->optee = optee;
+	rp->page_count = min_size / PAGE_SIZE;
+	mutex_init(&rp->mutex);
+
+	return &rp->pool;
+
+err_kfree_eps:
+	kfree(rp->end_points);
+err:
+	kfree(rp);
+	return ERR_PTR(rc);
+}
+#else /*CONFIG_CMA*/
+static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee __unused,
+					      u32 use_case __unused)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif /*CONFIG_CMA*/
+
 int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
 		       u32 flags, u32 use_case, size_t size)
 {
 	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct tee_shm_pool *pool;
+	int rc;
 
 	if (!optee->rstmem_pools)
 		return -EINVAL;
@@ -25,8 +328,17 @@ int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
 		return -EINVAL;
 
 	pool = xa_load(&optee->rstmem_pools->xa, use_case);
-	if (!pool)
-		return -EINVAL;
+	if (!pool) {
+		pool = alloc_rstmem_pool(optee, use_case);
+		if (IS_ERR(pool))
+			return PTR_ERR(pool);
+		rc = xa_insert(&optee->rstmem_pools->xa, use_case, pool,
+			       GFP_KERNEL);
+		if (rc) {
+			pool->ops->destroy_pool(pool);
+			return rc;
+		}
+	}
 
 	return pool->ops->alloc(pool, shm, size, 0);
 }
-- 
2.43.0



From jens.wiklander at linaro.org  Tue Dec 17 02:07:42 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 17 Dec 2024 11:07:42 +0100
Subject: [PATCH v4 6/6] optee: smc abi: dynamic restricted memory allocation
In-Reply-To: <20241217100809.3962439-1-jens.wiklander@linaro.org>
References: <20241217100809.3962439-1-jens.wiklander@linaro.org>
Message-ID: <20241217100809.3962439-7-jens.wiklander@linaro.org>

Add support in the OP-TEE backend driver for dynamic restricted memory
allocation using the SMC ABI.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/smc_abi.c | 74 +++++++++++++++++++++++++++++++++++--
 1 file changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index f5fd5f1d9a6b..25b02dbbc76e 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -1001,6 +1001,67 @@ static int optee_smc_do_call_with_arg(struct tee_context *ctx,
 	return rc;
 }
 
+static int optee_smc_lend_rstmem(struct optee *optee, struct tee_shm *rstmem,
+				 u16 *end_points, unsigned int ep_count)
+{
+	struct optee_shm_arg_entry *entry;
+	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm;
+	u_int offs;
+	int rc;
+
+	msg_arg = optee_get_msg_arg(optee->ctx, 2, &entry, &shm, &offs);
+	if (IS_ERR(msg_arg))
+		return PTR_ERR(msg_arg);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_LEND_RSTMEM;
+	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
+	msg_arg->params[0].u.value.a = OPTEE_MSG_RSTMEM_SECURE_VIDEO_PLAY;
+	msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
+	msg_arg->params[1].u.tmem.buf_ptr = rstmem->paddr;
+	msg_arg->params[1].u.tmem.size = rstmem->size;
+	msg_arg->params[1].u.tmem.shm_ref = (u_long)rstmem;
+
+	rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
+	if (rc)
+		goto out;
+	if (msg_arg->ret != TEEC_SUCCESS) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+out:
+	optee_free_msg_arg(optee->ctx, entry, offs);
+	return rc;
+}
+
+static int optee_smc_reclaim_rstmem(struct optee *optee, struct tee_shm *rstmem)
+{
+	struct optee_shm_arg_entry *entry;
+	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm;
+	u_int offs;
+	int rc;
+
+	msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs);
+	if (IS_ERR(msg_arg))
+		return PTR_ERR(msg_arg);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_RECLAIM_RSTMEM;
+	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
+	msg_arg->params[0].u.rmem.shm_ref = (u_long)rstmem;
+
+	rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false);
+	if (rc)
+		goto out;
+	if (msg_arg->ret != TEEC_SUCCESS)
+		rc = -EINVAL;
+
+out:
+	optee_free_msg_arg(optee->ctx, entry, offs);
+	return rc;
+}
+
 /*
  * 5. Asynchronous notification
  */
@@ -1258,6 +1319,8 @@ static const struct optee_ops optee_ops = {
 	.do_call_with_arg = optee_smc_do_call_with_arg,
 	.to_msg_param = optee_to_msg_param,
 	.from_msg_param = optee_from_msg_param,
+	.lend_rstmem = optee_smc_lend_rstmem,
+	.reclaim_rstmem = optee_smc_reclaim_rstmem,
 };
 
 static int enable_async_notif(optee_invoke_fn *invoke_fn)
@@ -1627,6 +1690,7 @@ static inline int optee_load_fw(struct platform_device *pdev,
 
 static int optee_sdp_pool_init(struct optee *optee)
 {
+	bool dyn_sdp = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_RSTMEM;
 	bool sdp = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_SDP;
 	struct tee_shm_pool *pool;
 	int rc;
@@ -1634,9 +1698,11 @@ static int optee_sdp_pool_init(struct optee *optee)
 	/*
 	 * optee_sdp_pools_init() must be called if secure world has any
 	 * SDP capability. If the static carvout is available initialize
-	 * and add a pool for that.
+	 * and add a pool for that. If there's an error from secure world
+	 * we complain but don't call optee_sdp_pools_uninit() unless we
+	 * know that there is no SDP capability left.
 	 */
-	if (!sdp)
+	if (!dyn_sdp && !sdp)
 		return 0;
 
 	rc = optee_rstmem_pools_init(optee);
@@ -1653,7 +1719,9 @@ static int optee_sdp_pool_init(struct optee *optee)
 				     0, &res.smccc);
 		if (res.result.status != OPTEE_SMC_RETURN_OK) {
 			pr_err("Secure Data Path service not available\n");
-			goto err;
+			if (!dyn_sdp)
+				goto err;
+			return 0;
 		}
 
 		pool = tee_rstmem_gen_pool_alloc(res.result.start,
-- 
2.43.0



From quic_sibis at quicinc.com  Tue Dec 17 02:16:24 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 17 Dec 2024 15:46:24 +0530
Subject: [PATCH V4 4/5] soc: qcom: Introduce SCMI based Memlat (Memory
 Latency) governor
In-Reply-To: <CAA8EJpoN3QSi72UUDV+=YkqySgXkiODUFJvwpBYfSmnkSotuZA@mail.gmail.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-5-quic_sibis@quicinc.com>
 <2aycrvnvivcrqctqmweadcgenwugafdr6ub3bzkscterpenz32@bzabln2hkral>
 <29eef87e-96f6-5105-6f7a-a8e01efcb4a3@quicinc.com>
 <k4lpzxtrq3x6riyv6etxiobn7nbpczf2bp3m4oc752nhjknlit@uo53kbppzim7>
 <ac655bdc-5ccf-c6c6-3203-659f1916c53c@quicinc.com>
 <34p27za5hcpubaxjuddsir2vqnqrvwyesnclu2cocvm3yhbv3r@ak7rcnp67gyd>
 <1f5258f4-7c20-5343-dec6-0847449c821b@quicinc.com>
 <CAA8EJpoN3QSi72UUDV+=YkqySgXkiODUFJvwpBYfSmnkSotuZA@mail.gmail.com>
Message-ID: <4399f7da-9478-57c0-7405-e51dc35d90ba@quicinc.com>



On 12/5/24 17:00, Dmitry Baryshkov wrote:
> On Thu, 5 Dec 2024 at 12:53, Sibi Sankar <quic_sibis at quicinc.com> wrote:
>>
>>
>>
>> On 11/14/24 18:02, Dmitry Baryshkov wrote:
>>> On Thu, Nov 14, 2024 at 09:43:53AM +0530, Sibi Sankar wrote:
>>>>
>>>>
>>>> On 10/26/24 23:46, Dmitry Baryshkov wrote:
>>>>> On Tue, Oct 22, 2024 at 01:48:25PM +0530, Sibi Sankar wrote:
>>>>>>
>>>>>>
>>>>>> On 10/7/24 23:27, Dmitry Baryshkov wrote:
>>>>>>> On Mon, Oct 07, 2024 at 11:40:22AM GMT, Sibi Sankar wrote:
>>>
>>>>>>>
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +struct map_param_msg {
>>>>>>>> +        u32 hw_type;
>>>>>>>> +        u32 mon_idx;
>>>>>>>> +        u32 nr_rows;
>>>>>>>> +        struct map_table tbl[MAX_MAP_ENTRIES];
>>>>>>>> +} __packed;
>>>>>>>> +
>>>>>>>> +struct node_msg {
>>>>>>>> +        u32 cpumask;
>>>>>>>> +        u32 hw_type;
>>>>>>>> +        u32 mon_type;
>>>>>>>> +        u32 mon_idx;
>>>>>>>> +        char mon_name[MAX_NAME_LEN];
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +struct scalar_param_msg {
>>>>>>>> +        u32 hw_type;
>>>>>>>> +        u32 mon_idx;
>>>>>>>> +        u32 val;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +enum common_ev_idx {
>>>>>>>> +        INST_IDX,
>>>>>>>> +        CYC_IDX,
>>>>>>>> +        CONST_CYC_IDX,
>>>>>>>> +        FE_STALL_IDX,
>>>>>>>> +        BE_STALL_IDX,
>>>>>>>> +        NUM_COMMON_EVS
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +enum grp_ev_idx {
>>>>>>>> +        MISS_IDX,
>>>>>>>> +        WB_IDX,
>>>>>>>> +        ACC_IDX,
>>>>>>>> +        NUM_GRP_EVS
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +#define EV_CPU_CYCLES           0
>>>>>>>> +#define EV_INST_RETIRED         2
>>>>>>>> +#define EV_L2_D_RFILL           5
>>>>>>>> +
>>>>>>>> +struct ev_map_msg {
>>>>>>>> +        u32 num_evs;
>>>>>>>> +        u32 hw_type;
>>>>>>>> +        u32 cid[NUM_COMMON_EVS];
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +struct cpufreq_memfreq_map {
>>>>>>>> +        unsigned int cpufreq_mhz;
>>>>>>>> +        unsigned int memfreq_khz;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +struct scmi_monitor_info {
>>>>>>>> +        struct cpufreq_memfreq_map *freq_map;
>>>>>>>> +        char mon_name[MAX_NAME_LEN];
>>>>>>>> +        u32 mon_idx;
>>>>>>>> +        u32 mon_type;
>>>>>>>> +        u32 ipm_ceil;
>>>>>>>> +        u32 mask;
>>>>>>>> +        u32 freq_map_len;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +struct scmi_memory_info {
>>>>>>>> +        struct scmi_monitor_info *monitor[MAX_MONITOR_CNT];
>>>>>>>> +        u32 hw_type;
>>>>>>>> +        int monitor_cnt;
>>>>>>>> +        u32 min_freq;
>>>>>>>> +        u32 max_freq;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +struct scmi_memlat_info {
>>>>>>>> +        struct scmi_protocol_handle *ph;
>>>>>>>> +        const struct qcom_generic_ext_ops *ops;
>>>>>>>> +        struct scmi_memory_info *memory[MAX_MEMORY_TYPES];
>>>>>>>> +        u32 cluster_info[NR_CPUS];
>>>>>>>> +        int memory_cnt;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +static int populate_cluster_info(u32 *cluster_info)
>>>>>>>> +{
>>>>>>>> +        char name[MAX_NAME_LEN];
>>>>>>>> +        int i = 0;
>>>>>>>> +
>>>>>>>> +        struct device_node *cn __free(device_node) = of_find_node_by_path("/cpus");
>>>>>>>> +        if (!cn)
>>>>>>>> +                return -ENODEV;
>>>>>>>> +
>>>>>>>> +        struct device_node *map __free(device_node) = of_get_child_by_name(cn, "cpu-map");
>>>>>>>> +        if (!map)
>>>>>>>> +                return -ENODEV;
>>>>>>>> +
>>>>>>>> +        do {
>>>>>>>> +                snprintf(name, sizeof(name), "cluster%d", i);
>>>>>>>> +                struct device_node *c __free(device_node) = of_get_child_by_name(map, name);
>>>>>>>> +                if (!c)
>>>>>>>> +                        break;
>>>>>>>> +
>>>>>>>> +                *(cluster_info + i) = of_get_child_count(c);
>>>>>>>> +                i++;
>>>>>>>> +        } while (1);
>>>>>>>
>>>>>>> Can you use existing API from drivers/base/arch_topology.c? If not, can
>>>>>>> it be extended to support your usecase?
>>>>>>
>>>>>> ack. But I'm pretty sure it's going to take a while for reaching such
>>>>>> an agreement so I'll drop this feature during the next re-spin.
>>>>>
>>>>> Why? What kind of API do you actually need? The arch_topology.c simply
>>>>> exports a table of struct cpu_topology. Is it somehow different from
>>>>> what you are parsing manually?
>>>>
>>>> yup, we had to figure out the physical id of the cpu
>>>> since cpus can be disabled by the bootloader using
>>>> status = "failed" property and we have to pass this
>>>> onto the cpucp memlat algorithm.
>>>
>>> Isn't it equal to the index in the cpu_topology table?
>>
>> from what I see cpu_topology indexes remain unpopulated
>> for cpus that are disabled since get_cpu_for_node
>> ignores those?
> 
> Why do you need cpu_topology for disabled aka non-existing CPU devices?

sorry was out sick couldn't back earlier. We need the know
what cpus are disbled to pass on the correct mask of cpus
enabled to the SCP.

> 
>>
>>>
>>>>
>>>>>
>>>>>>
>>>>>>>
>>>>>>>> +
>>>>>>>> +        return 0;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static void populate_physical_mask(struct device_node *np, u32 *mask, u32 *cluster_info)
>>>>>>>> +{
>>>>>>>> +        struct device_node *dev_phandle __free(device_node);
>>>>>>>> +        int cpu, i = 0, physical_id;
>>>>>>>> +
>>>>>>>> +        do {
>>>>>>>> +                dev_phandle = of_parse_phandle(np, "cpus", i++);
>>>>>>>> +                cpu = of_cpu_node_to_id(dev_phandle);
>>>>>>>> +                if (cpu != -ENODEV) {
>>>>>>>> +                        physical_id = topology_core_id(cpu);
>>>>>>>> +                        for (int j = 0; j < topology_cluster_id(cpu); j++)
>>>>>>>> +                                physical_id += *(cluster_info + j);
>>>>>>>> +                        *mask |= BIT(physical_id);
>>>>>>>> +                }
>>>>>>>> +        } while (dev_phandle);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static struct cpufreq_memfreq_map *init_cpufreq_memfreq_map(struct device *dev,
>>>>>>>> +                                                            struct scmi_memory_info *memory,
>>>>>>>> +                                                            struct device_node *of_node,
>>>>>>>> +                                                            u32 *cnt)
>>>>>>>> +{
>>>>>>>> +        struct device_node *tbl_np __free(device_node), *opp_np __free(device_node);
>>>>>>>> +        struct cpufreq_memfreq_map *tbl;
>>>>>>>> +        int ret, i = 0;
>>>>>>>> +        u32 level, len;
>>>>>>>> +        u64 rate;
>>>>>>>> +
>>>>>>>> +        tbl_np = of_parse_phandle(of_node, "operating-points-v2", 0);
>>>>>>>
>>>>>>> Please use existing API to parse OPP tables or document a reason why it
>>>>>>> can't be used.
>>>>>>
>>>>>> Thanks, I had them documented as opens in the coverletter. Dropped them
>>>>>> since no one had any comments on it during V3. Will add them as comments
>>>>>> to this driver instead.
>>>>>>
>>>>>> https://lore.kernel.org/lkml/20240702191440.2161623-1-quic_sibis at quicinc.com/
>>>>>>
>>>>>> re-copying things again:
>>>>>> opp-tables are used but they don't get to be added to the scmi device
>>>>>> (thus we rely on a lot of manual parsing) because the memlat client driver
>>>>>> doesn't vote on these resources clocks/interconnects/power-domain
>>>>>> from the kernel and some of the resources aren't modeled in the first
>>>>>> place like DDR_QOS.
>>>>>
>>>>> As discussed offline, please consider extending the OPP to be able to
>>>>> get the struct opp_table for the particular phandle. Another option
>>>>> might be to change the memlat driver by having a separate device for
>>>>> each monitor. This way you can use existing API to parse OPP tables and
>>>>> to get necessary data from those tables.
>>>>
>>>> + Viresh
>>>>
>>>> Spoke with Viresh offline and he had stricter requirements
>>>> than what you proposed. He definitely wanted the opp-tables
>>>> to be assoiciated with devices at the very least and have
>>>> all opp parsing logic within the opp-framework. Given that
>>>> we have to model all these dummy devices just to add the
>>>> tables I'll re-check the feasibility of movign the tables
>>>> into the driver itself. Will move the patch series back
>>>> into RFC and re-post just the vendor protocol since that's
>>>> close to merge
>>>
>>> I don't think it's sensible to move the tables to the driver. Instead
>>> adding a device per monitor sounds like a better idea.
>>
>> yeah, I would like to keep this in dt as well. But in order
>> to be able to do that through the opp core we would need
>> to put in a clock and interconnect paths so that the framework
>> is able to add the table to the device.
>> I should be able
>> to list the scmi perf domain as the clock phandle but inorder
>> to be able to convert the kbps values for the interconnect I
>> would need to store the bus width and so on which is currently
>> abstracted by the interconnect framework. Also in the future
>> we may have to model dummy devices just to get the table parsed
>> if the devices aren't modelled and controlled in the kernel.
>> All of these seems to indicate that having the tables in the
>> driver is a better alternative, lol.
> 
> Or fix the OPP API. I don't think that having monitor tables for the
> SCMI-based platforms in the driver code is going to scale.

There is nothing to fix in the OPP API, looking at number
of clocks, interconnects and regulators to allocate
memory and associate a opp-table to a device is already
the right thing to do. So to adhere to this we would
need to list dummy clocks, interconnects even when it
isn't modelled or controlled by the kernel. Sure I'll
continue to have it in dt in the next re-spin and take
this series back in RFC.

-Sibi

> 
>>
>> -Sibi
>>
>>>
>>>>>>>> +        if (!tbl_np)
>>>>>>>> +                return ERR_PTR(-ENODEV);
>>>>>>>> +
>>>>>>>> +        len = min(of_get_available_child_count(tbl_np), MAX_MAP_ENTRIES);
>>>>>>>> +        if (len == 0)
>>>>>>>> +                return ERR_PTR(-ENODEV);
>>>>>>>> +
>>>>>>>> +        tbl = devm_kzalloc(dev, (len + 1) * sizeof(struct cpufreq_memfreq_map),
>>>>>>>> +                           GFP_KERNEL);
>>>>>>>> +        if (!tbl)
>>>>>>>> +                return ERR_PTR(-ENOMEM);
>>>>>>>> +
>>>>>>>> +        for_each_available_child_of_node(tbl_np, opp_np) {
>>>>>>>> +                ret = of_property_read_u64_index(opp_np, "opp-hz", 0, &rate);
>>>>>>>> +                if (ret < 0)
>>>>>>>> +                        return ERR_PTR(ret);
>>>>>>>> +
>>>>>>>> +                tbl[i].cpufreq_mhz = rate / HZ_PER_MHZ;
>>>>>>>> +
>>>>>>>> +                if (memory->hw_type != QCOM_MEM_TYPE_DDR_QOS) {
>>>>>>>> +                        ret = of_property_read_u64_index(opp_np, "opp-hz", 1, &rate);
>>>>>>>> +                        if (ret < 0)
>>>>>>>> +                                return ERR_PTR(ret);
>>>>>>>> +
>>>>>>>> +                        tbl[i].memfreq_khz = rate / HZ_PER_KHZ;
>>>>>>>> +                } else {
>>>>>>>> +                        ret = of_property_read_u32(opp_np, "opp-level", &level);
>>>>>>>> +                        if (ret < 0)
>>>>>>>> +                                return ERR_PTR(ret);
>>>>>>>> +
>>>>>>>> +                        tbl[i].memfreq_khz = level;
>>>>>>>> +                }
>>>>>>>> +
>>>>>>>> +                dev_dbg(dev, "Entry%d CPU:%u, Mem:%u\n", i, tbl[i].cpufreq_mhz, tbl[i].memfreq_khz);
>>>>>>>> +                i++;
>>>>>>>> +        }
>>>>>>>> +        *cnt = len;
>>>>>>>> +
>>>>>>>> +        return tbl;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static int process_scmi_memlat_of_node(struct scmi_device *sdev, struct scmi_memlat_info *info)
>>>>>>>> +{
>>>>>>>> +        struct scmi_monitor_info *monitor;
>>>>>>>> +        struct scmi_memory_info *memory;
>>>>>>>> +        char name[MAX_NAME_LEN];
>>>>>>>> +        u64 memfreq[2];
>>>>>>>> +        int ret;
>>>>>>>> +
>>>>>>>> +        ret = populate_cluster_info(info->cluster_info);
>>>>>>>> +        if (ret < 0) {
>>>>>>>> +                dev_err_probe(&sdev->dev, ret, "failed to populate cluster info\n");
>>>>>>>> +                goto err;
>>>>>>>> +        }
>>>>>>>> +
>>>>>>>> +        of_node_get(sdev->dev.of_node);
>>>>>>>> +        do {
>>>>>>>> +                snprintf(name, sizeof(name), "memory-%d", info->memory_cnt);
>>>>>>>> +                struct device_node *memory_np __free(device_node) =
>>>>>>>> +                        of_find_node_by_name(sdev->dev.of_node, name);
>>>>>>>> +
>>>>>>>> +                if (!memory_np)
>>>>>>>> +                        break;
>>>>>>>> +
>>>>>>>> +                if (info->memory_cnt >= MAX_MEMORY_TYPES)
>>>>>>>> +                        return dev_err_probe(&sdev->dev, -EINVAL,
>>>>>>>> +                                             "failed to parse unsupported memory type\n");
>>>>>>>> +
>>>>>>>> +                memory = devm_kzalloc(&sdev->dev, sizeof(*memory), GFP_KERNEL);
>>>>>>>> +                if (!memory) {
>>>>>>>> +                        ret = -ENOMEM;
>>>>>>>> +                        goto err;
>>>>>>>> +                }
>>>>>>>> +
>>>>>>>> +                ret = of_property_read_u32(memory_np, "qcom,memory-type", &memory->hw_type);
>>>>>>>> +                if (ret) {
>>>>>>>> +                        dev_err_probe(&sdev->dev, ret, "failed to read memory type\n");
>>>>>>>> +                        goto err;
>>>>>>>> +                }
>>>>>>>> +
>>>>>>>> +                ret = of_property_read_u64_array(memory_np, "freq-table-hz", memfreq, 2);
>>>>>>>> +                if (ret && (ret != -EINVAL)) {
>>>>>>>> +                        dev_err_probe(&sdev->dev, ret, "failed to read min/max freq\n");
>>>>>>>> +                        goto err;
>>>>>>>> +                }
>>>>>>>
>>>>>>> Can we get this information from the OPP table instead?
>>>>>>
>>>>>> we don't list all the available ddr/llcc freqs in the opp-table
>>>>>> so that we can keep the table constant across platforms.
>>>>>
>>>>> NO. Use opp-supported-hw to limit data to a particular platform. There
>>>>> is no reason to keep min/max out of the OPP table.
>>>>
>>>> if we are movign the opp-tables into driver data for the reasons
>>>> described above, this can probably stay?
>>>
>>> No. They duplicate the information that can be a part of the tables. It
>>> doesn't matter if the tables are in the driver or in DT.
>>>
>>>
> 
> 
> 


From cniedermaier at dh-electronics.com  Tue Dec 17 02:21:35 2024
From: cniedermaier at dh-electronics.com (Christoph Niedermaier)
Date: Tue, 17 Dec 2024 10:21:35 +0000
Subject: [PATCH] ARM: dts: stm32: Swap USART3 and UART8 alias on
 STM32MP15xx DHCOM SoM
In-Reply-To: <20241213223658.99802-1-marex@denx.de>
References: <20241213223658.99802-1-marex@denx.de>
Message-ID: <2a960747f48e44daaa3cffe93ceb8ea3@dh-electronics.com>

From: Marek Vasut <marex at denx.de>
Sent: Friday, December 13, 2024 11:36 PM
> Swap USART3 and UART8 aliases on STM32MP15xx DHCOM SoM,
> make sure UART8 is listed first, USART3 second, because
> the UART8 is labeled as UART2 on the SoM pinout, while
> USART3 is labeled as UART3 on the SoM pinout.
> 
> Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2
> board")
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzk+dt at kernel.org>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Rob Herring <robh at kernel.org>
> Cc: devicetree at vger.kernel.org
> Cc: kernel at dh-electronics.com
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> ---
>  arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> index 086d3a60ccce2..142d4a8731f8d 100644
> --- a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> +++ b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> @@ -15,8 +15,8 @@ aliases {
>  		rtc0 = &hwrtc;
>  		rtc1 = &rtc;
>  		serial0 = &uart4;
> -		serial1 = &usart3;
> -		serial2 = &uart8;
> +		serial1 = &uart8;
> +		serial2 = &usart3;
>  	};
> 
>  	chosen {

Reviewed-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>


From ckeepax at opensource.cirrus.com  Tue Dec 17 02:36:22 2024
From: ckeepax at opensource.cirrus.com (Charles Keepax)
Date: Tue, 17 Dec 2024 10:36:22 +0000
Subject: [PATCH] rtc: use boolean values with device_init_wakeup()
In-Reply-To: <20241217071331.3607-2-wsa+renesas@sang-engineering.com>
References: <20241217071331.3607-2-wsa+renesas@sang-engineering.com>
Message-ID: <Z2FUJhC1Iq5mmkEg@opensource.cirrus.com>

On Tue, Dec 17, 2024 at 08:13:26AM +0100, Wolfram Sang wrote:
> device_init_wakeup() second argument is a bool type. Use proper boolean
> values when calling it to match the type and to produce unambiguous code
> which is easier to understand.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
> ---

For the old Wolfson parts:

Reviewed-by: Charles Keepax <ckeepax at opensource.cirrus.com>

Thanks,
Charles


From joey.gouly at arm.com  Tue Dec 17 02:40:58 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 17 Dec 2024 10:40:58 +0000
Subject: [PATCH 6.6 v1] KVM: arm64: Disable MPAM visibility by default
 and ignore VMM writes
In-Reply-To: <2024121528-refurbish-plausibly-31c7@gregkh>
References: <20241212151406.1436382-1-joey.gouly@arm.com>
 <2024121528-refurbish-plausibly-31c7@gregkh>
Message-ID: <20241217104058.GA2151333@e124191.cambridge.arm.com>

On Sun, Dec 15, 2024 at 10:22:53AM +0100, Greg KH wrote:
> On Thu, Dec 12, 2024 at 03:14:06PM +0000, Joey Gouly wrote:
> > From: James Morse <james.morse at arm.com>
> > 
> > commit 6685f5d572c22e1003e7c0d089afe1c64340ab1f upstream.
> > 
> > commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits in
> > ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to guests,
> > but didn't add trap handling. A previous patch supplied the missing trap
> > handling.
> > 
> > Existing VMs that have the MPAM field of ID_AA64PFR0_EL1 set need to
> > be migratable, but there is little point enabling the MPAM CPU
> > interface on new VMs until there is something a guest can do with it.
> > 
> > Clear the MPAM field from the guest's ID_AA64PFR0_EL1 and on hardware
> > that supports MPAM, politely ignore the VMMs attempts to set this bit.
> > 
> > Guests exposed to this bug have the sanitised value of the MPAM field,
> > so only the correct value needs to be ignored. This means the field
> > can continue to be used to block migration to incompatible hardware
> > (between MPAM=1 and MPAM=5), and the VMM can't rely on the field
> > being ignored.
> > 
> > Signed-off-by: James Morse <james.morse at arm.com>
> > Co-developed-by: Joey Gouly <joey.gouly at arm.com>
> > Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> > Reviewed-by: Gavin Shan <gshan at redhat.com>
> > Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> > Reviewed-by: Marc Zyngier <maz at kernel.org>
> > Link: https://lore.kernel.org/r/20241030160317.2528209-7-joey.gouly at arm.com
> > Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> > [ joey: fixed up merge conflict, no ID_FILTERED macro in 6.6 ]
> > Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> > Cc: stable at vger.kernel.org # 6.6.x
> > Cc: Vitaly Chikunov <vt at altlinux.org>
> > Link: https://lore.kernel.org/linux-arm-kernel/20241202045830.e4yy3nkvxtzaybxk at altlinux.org/
> > ---
> > 
> > This fixes an issue seen when using KVM with a 6.6 host kernel, and
> > newer (6.13+) kernels in the guest.
> > 
> > Tested with a stripped down version of set_id_regs from the original
> > patch series.
> 
> What about 6.12.y?  You can't just skip a stable tree, otherwise you
> will get a regression when you upgrade to 6.12.y, right?

I did have it ported/tested locally, but I wasn't sure of the stable process,
so just sent out one!  Next time I will send all the backports at the same
time.

Thanks Marc Z for sending it out!

Joey


From dmitry.baryshkov at linaro.org  Tue Dec 17 02:46:16 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 12:46:16 +0200
Subject: [PATCH V4 4/5] soc: qcom: Introduce SCMI based Memlat (Memory
 Latency) governor
In-Reply-To: <4399f7da-9478-57c0-7405-e51dc35d90ba@quicinc.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-5-quic_sibis@quicinc.com>
 <2aycrvnvivcrqctqmweadcgenwugafdr6ub3bzkscterpenz32@bzabln2hkral>
 <29eef87e-96f6-5105-6f7a-a8e01efcb4a3@quicinc.com>
 <k4lpzxtrq3x6riyv6etxiobn7nbpczf2bp3m4oc752nhjknlit@uo53kbppzim7>
 <ac655bdc-5ccf-c6c6-3203-659f1916c53c@quicinc.com>
 <34p27za5hcpubaxjuddsir2vqnqrvwyesnclu2cocvm3yhbv3r@ak7rcnp67gyd>
 <1f5258f4-7c20-5343-dec6-0847449c821b@quicinc.com>
 <CAA8EJpoN3QSi72UUDV+=YkqySgXkiODUFJvwpBYfSmnkSotuZA@mail.gmail.com>
 <4399f7da-9478-57c0-7405-e51dc35d90ba@quicinc.com>
Message-ID: <uwwiz2o6brn5zczbpaiajdq7yva2qpcpgzwdr26lhg4jvlwvvj@w5bkiuhdalze>

On Tue, Dec 17, 2024 at 03:46:24PM +0530, Sibi Sankar wrote:
> 
> 
> On 12/5/24 17:00, Dmitry Baryshkov wrote:
> > On Thu, 5 Dec 2024 at 12:53, Sibi Sankar <quic_sibis at quicinc.com> wrote:
> > > 
> > > 
> > > 
> > > On 11/14/24 18:02, Dmitry Baryshkov wrote:
> > > > On Thu, Nov 14, 2024 at 09:43:53AM +0530, Sibi Sankar wrote:
> > > > > 
> > > > > 
> > > > > On 10/26/24 23:46, Dmitry Baryshkov wrote:
> > > > > > On Tue, Oct 22, 2024 at 01:48:25PM +0530, Sibi Sankar wrote:
> > > > > > > 
> > > > > > > 
> > > > > > > On 10/7/24 23:27, Dmitry Baryshkov wrote:
> > > > > > > > On Mon, Oct 07, 2024 at 11:40:22AM GMT, Sibi Sankar wrote:
> > > > 
> > > > > > > > 
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +struct map_param_msg {
> > > > > > > > > +        u32 hw_type;
> > > > > > > > > +        u32 mon_idx;
> > > > > > > > > +        u32 nr_rows;
> > > > > > > > > +        struct map_table tbl[MAX_MAP_ENTRIES];
> > > > > > > > > +} __packed;
> > > > > > > > > +
> > > > > > > > > +struct node_msg {
> > > > > > > > > +        u32 cpumask;
> > > > > > > > > +        u32 hw_type;
> > > > > > > > > +        u32 mon_type;
> > > > > > > > > +        u32 mon_idx;
> > > > > > > > > +        char mon_name[MAX_NAME_LEN];
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +struct scalar_param_msg {
> > > > > > > > > +        u32 hw_type;
> > > > > > > > > +        u32 mon_idx;
> > > > > > > > > +        u32 val;
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +enum common_ev_idx {
> > > > > > > > > +        INST_IDX,
> > > > > > > > > +        CYC_IDX,
> > > > > > > > > +        CONST_CYC_IDX,
> > > > > > > > > +        FE_STALL_IDX,
> > > > > > > > > +        BE_STALL_IDX,
> > > > > > > > > +        NUM_COMMON_EVS
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +enum grp_ev_idx {
> > > > > > > > > +        MISS_IDX,
> > > > > > > > > +        WB_IDX,
> > > > > > > > > +        ACC_IDX,
> > > > > > > > > +        NUM_GRP_EVS
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +#define EV_CPU_CYCLES           0
> > > > > > > > > +#define EV_INST_RETIRED         2
> > > > > > > > > +#define EV_L2_D_RFILL           5
> > > > > > > > > +
> > > > > > > > > +struct ev_map_msg {
> > > > > > > > > +        u32 num_evs;
> > > > > > > > > +        u32 hw_type;
> > > > > > > > > +        u32 cid[NUM_COMMON_EVS];
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +struct cpufreq_memfreq_map {
> > > > > > > > > +        unsigned int cpufreq_mhz;
> > > > > > > > > +        unsigned int memfreq_khz;
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +struct scmi_monitor_info {
> > > > > > > > > +        struct cpufreq_memfreq_map *freq_map;
> > > > > > > > > +        char mon_name[MAX_NAME_LEN];
> > > > > > > > > +        u32 mon_idx;
> > > > > > > > > +        u32 mon_type;
> > > > > > > > > +        u32 ipm_ceil;
> > > > > > > > > +        u32 mask;
> > > > > > > > > +        u32 freq_map_len;
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +struct scmi_memory_info {
> > > > > > > > > +        struct scmi_monitor_info *monitor[MAX_MONITOR_CNT];
> > > > > > > > > +        u32 hw_type;
> > > > > > > > > +        int monitor_cnt;
> > > > > > > > > +        u32 min_freq;
> > > > > > > > > +        u32 max_freq;
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +struct scmi_memlat_info {
> > > > > > > > > +        struct scmi_protocol_handle *ph;
> > > > > > > > > +        const struct qcom_generic_ext_ops *ops;
> > > > > > > > > +        struct scmi_memory_info *memory[MAX_MEMORY_TYPES];
> > > > > > > > > +        u32 cluster_info[NR_CPUS];
> > > > > > > > > +        int memory_cnt;
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +static int populate_cluster_info(u32 *cluster_info)
> > > > > > > > > +{
> > > > > > > > > +        char name[MAX_NAME_LEN];
> > > > > > > > > +        int i = 0;
> > > > > > > > > +
> > > > > > > > > +        struct device_node *cn __free(device_node) = of_find_node_by_path("/cpus");
> > > > > > > > > +        if (!cn)
> > > > > > > > > +                return -ENODEV;
> > > > > > > > > +
> > > > > > > > > +        struct device_node *map __free(device_node) = of_get_child_by_name(cn, "cpu-map");
> > > > > > > > > +        if (!map)
> > > > > > > > > +                return -ENODEV;
> > > > > > > > > +
> > > > > > > > > +        do {
> > > > > > > > > +                snprintf(name, sizeof(name), "cluster%d", i);
> > > > > > > > > +                struct device_node *c __free(device_node) = of_get_child_by_name(map, name);
> > > > > > > > > +                if (!c)
> > > > > > > > > +                        break;
> > > > > > > > > +
> > > > > > > > > +                *(cluster_info + i) = of_get_child_count(c);
> > > > > > > > > +                i++;
> > > > > > > > > +        } while (1);
> > > > > > > > 
> > > > > > > > Can you use existing API from drivers/base/arch_topology.c? If not, can
> > > > > > > > it be extended to support your usecase?
> > > > > > > 
> > > > > > > ack. But I'm pretty sure it's going to take a while for reaching such
> > > > > > > an agreement so I'll drop this feature during the next re-spin.
> > > > > > 
> > > > > > Why? What kind of API do you actually need? The arch_topology.c simply
> > > > > > exports a table of struct cpu_topology. Is it somehow different from
> > > > > > what you are parsing manually?
> > > > > 
> > > > > yup, we had to figure out the physical id of the cpu
> > > > > since cpus can be disabled by the bootloader using
> > > > > status = "failed" property and we have to pass this
> > > > > onto the cpucp memlat algorithm.
> > > > 
> > > > Isn't it equal to the index in the cpu_topology table?
> > > 
> > > from what I see cpu_topology indexes remain unpopulated
> > > for cpus that are disabled since get_cpu_for_node
> > > ignores those?
> > 
> > Why do you need cpu_topology for disabled aka non-existing CPU devices?
> 
> sorry was out sick couldn't back earlier. We need the know
> what cpus are disbled to pass on the correct mask of cpus
> enabled to the SCP.

Yes. So isn't it enough to know only the enabled CPUs?


-- 
With best wishes
Dmitry


From m.felsch at pengutronix.de  Tue Dec 17 02:46:34 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Tue, 17 Dec 2024 11:46:34 +0100
Subject: [PATCH V2] soc: imx8m: Add remove function
In-Reply-To: <PAXPR04MB8459A91EEC932F41E24AE04488042@PAXPR04MB8459.eurprd04.prod.outlook.com>
References: <20241217015826.1374497-1-peng.fan@oss.nxp.com>
 <20241217082637.i2ou6bbr3tc3uvof@pengutronix.de>
 <PAXPR04MB8459A91EEC932F41E24AE04488042@PAXPR04MB8459.eurprd04.prod.outlook.com>
Message-ID: <20241217104634.2fc7yo6hprhx2wnt@pengutronix.de>

On 24-12-17, Peng Fan wrote:
> > Subject: Re: [PATCH V2] soc: imx8m: Add remove function
> > 
> > Hi Peng,
> > 
> > thanks for you patch.
> > 
> > On 24-12-17, Peng Fan (OSS) wrote:
> > > From: Peng Fan <peng.fan at nxp.com>
> > >
> > > Unregister the cpufreq device and soc device in remove path,
> > otherwise
> > 
> > After reconsidiering the patch approach, I think we shouldn't add a
> > .remove() function and instead should make use of the
> > devm_add_action() mechanism for the proper unregister calls.
> 
> Would you please share why devm_add_action is preferred?
> 
> Something as below?
> +static void imx8m_soc_remove(void *data)
> +{
> +       struct imx8m_soc_priv *priv = data;
> +
> +       if (priv->cpufreq_dev)
> +               platform_device_unregister(priv->cpufreq_dev);
> +
> +       soc_device_unregister(priv->soc_dev);
> +}

I would split it into two action functions due to the following reasons:
 - cleanup during the probe() if something fails afterwards
 - no need for the if(priv->cpufreq_dev) check.

> In Probe:
> +       return devm_add_action(&pdev->dev, imx8m_soc_remove, priv);

The actions should be added directly after the succeful device
registration, e.g.
 - after soc_device_register(soc_dev_attr) and
 - after platform_device_register_simple()

Regards,
   Marco

> 
> Regards,
> Peng.
> 
> > 
> > > there will be warning when do removing test:
> > > sysfs: cannot create duplicate filename '/devices/platform/imx-
> > cpufreq-dt'
> > > CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted
> > > 6.13.0-rc1-next-20241204 Hardware name: NXP i.MX8MPlus EVK
> > board (DT)
> > >
> > > Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as platform
> > > driver")
> > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > ---
> > >
> > > V2:
> > >  Add err check when create the cpufreq platform device
> > 
> > thank you for addressing this.
> > 
> > Regards,
> >   Marco
> > 
> > >  drivers/soc/imx/soc-imx8m.c | 41
> > > +++++++++++++++++++++++++++++++------
> > >  1 file changed, 35 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-
> > imx8m.c
> > > index 8ac7658e3d52..97c8718c2aa1 100644
> > > --- a/drivers/soc/imx/soc-imx8m.c
> > > +++ b/drivers/soc/imx/soc-imx8m.c
> > > @@ -33,6 +33,11 @@ struct imx8_soc_data {
> > >  	int (*soc_revision)(u32 *socrev, u64 *socuid);  };
> > >
> > > +struct imx8m_soc_priv {
> > > +	struct soc_device *soc_dev;
> > > +	struct platform_device *cpufreq_dev; };
> > > +
> > >  #ifdef CONFIG_HAVE_ARM_SMCCC
> > >  static u32 imx8mq_soc_revision_from_atf(void)
> > >  {
> > > @@ -195,10 +200,11 @@ static __maybe_unused const struct
> > of_device_id
> > > imx8_soc_match[] = {  static int imx8m_soc_probe(struct
> > > platform_device *pdev)  {
> > >  	struct soc_device_attribute *soc_dev_attr;
> > > +	struct platform_device *cpufreq_dev;
> > >  	const struct imx8_soc_data *data;
> > >  	struct device *dev = &pdev->dev;
> > >  	const struct of_device_id *id;
> > > -	struct soc_device *soc_dev;
> > > +	struct imx8m_soc_priv *priv;
> > >  	u32 soc_rev = 0;
> > >  	u64 soc_uid = 0;
> > >  	int ret;
> > > @@ -207,6 +213,10 @@ static int imx8m_soc_probe(struct
> > platform_device *pdev)
> > >  	if (!soc_dev_attr)
> > >  		return -ENOMEM;
> > >
> > > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > > +	if (!priv)
> > > +		return -ENOMEM;
> > > +
> > >  	soc_dev_attr->family = "Freescale i.MX";
> > >
> > >  	ret = of_property_read_string(of_root, "model",
> > > &soc_dev_attr->machine); @@ -235,21 +245,40 @@ static int
> > imx8m_soc_probe(struct platform_device *pdev)
> > >  	if (!soc_dev_attr->serial_number)
> > >  		return -ENOMEM;
> > >
> > > -	soc_dev = soc_device_register(soc_dev_attr);
> > > -	if (IS_ERR(soc_dev))
> > > -		return PTR_ERR(soc_dev);
> > > +	priv->soc_dev = soc_device_register(soc_dev_attr);
> > > +	if (IS_ERR(priv->soc_dev))
> > > +		return PTR_ERR(priv->soc_dev);
> > >
> > >  	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
> > >  		soc_dev_attr->revision);
> > >
> > > -	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
> > > -		platform_device_register_simple("imx-cpufreq-dt", -1,
> > NULL, 0);
> > > +	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) {
> > > +		cpufreq_dev = platform_device_register_simple("imx-
> > cpufreq-dt", -1, NULL, 0);
> > > +		if (!IS_ERR(cpufreq_dev))
> > > +			priv->cpufreq_dev = cpufreq_dev;
> > > +		else
> > > +			dev_err(dev, "Failed to create imx-cpufreq-
> > dev device: %ld",
> > > +				PTR_ERR(cpufreq_dev));
> > > +	}
> > > +
> > > +	platform_set_drvdata(pdev, priv);
> > >
> > >  	return 0;
> > >  }
> > >
> > > +static void imx8m_soc_remove(struct platform_device *pdev) {
> > > +	struct imx8m_soc_priv *priv = platform_get_drvdata(pdev);
> > > +
> > > +	if (priv->cpufreq_dev)
> > > +		platform_device_unregister(priv->cpufreq_dev);
> > > +
> > > +	soc_device_unregister(priv->soc_dev);
> > > +}
> > > +
> > >  static struct platform_driver imx8m_soc_driver = {
> > >  	.probe = imx8m_soc_probe,
> > > +	.remove	= imx8m_soc_remove,
> > >  	.driver = {
> > >  		.name = "imx8m-soc",
> > >  	},
> > > --
> > > 2.37.1
> > >
> > >
> > >
> 


From maz at kernel.org  Tue Dec 17 02:52:08 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 10:52:08 +0000
Subject: [PATCH v3 01/18] KVM: arm64: Change the layout of enum pkvm_page_state
In-Reply-To: <20241216175803.2716565-2-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
	<20241216175803.2716565-2-qperret@google.com>
Message-ID: <861py6sht3.wl-maz@kernel.org>

On Mon, 16 Dec 2024 17:57:46 +0000,
Quentin Perret <qperret at google.com> wrote:
> 
> The 'concrete' (a.k.a non-meta) page states are currently encoded using
> software bits in PTEs. For performance reasons, the abstract
> pkvm_page_state enum uses the same bits to encode these states as that
> makes conversions from and to PTEs easy.
> 
> In order to prepare the ground for moving the 'concrete' state storage
> to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this
> purpose.
> 
> No functional changes intended.
> 
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 0972faccc2af..8c30362af2b9 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -24,25 +24,27 @@
>   */
>  enum pkvm_page_state {
>  	PKVM_PAGE_OWNED			= 0ULL,
> -	PKVM_PAGE_SHARED_OWNED		= KVM_PGTABLE_PROT_SW0,
> -	PKVM_PAGE_SHARED_BORROWED	= KVM_PGTABLE_PROT_SW1,
> -	__PKVM_PAGE_RESERVED		= KVM_PGTABLE_PROT_SW0 |
> -					  KVM_PGTABLE_PROT_SW1,
> +	PKVM_PAGE_SHARED_OWNED		= BIT(0),
> +	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
> +	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
>  
>  	/* Meta-states which aren't encoded directly in the PTE's SW bits */
> -	PKVM_NOPAGE,
> +	PKVM_NOPAGE			= BIT(2),
>  };
> +#define PKVM_PAGE_META_STATES_MASK	(~(BIT(0) | BIT(1)))

Shouldn't that be ~__PKVM_PAGE_RESERVED, given that you just defined it?

>  
>  #define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
>  static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
>  						 enum pkvm_page_state state)
>  {
> -	return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
> +	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
> +	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
> +	return prot;
>  }
>  
>  static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
>  {
> -	return prot & PKVM_PAGE_STATE_PROT_MASK;
> +	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
>  }
>  
>  struct host_mmu {

Thanks,

	M.

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


From maz at kernel.org  Tue Dec 17 02:55:58 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 10:55:58 +0000
Subject: [PATCH v3 03/18] KVM: arm64: Make hyp_page::order a u8
In-Reply-To: <20241216175803.2716565-4-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
	<20241216175803.2716565-4-qperret@google.com>
Message-ID: <86zfkur329.wl-maz@kernel.org>

On Mon, 16 Dec 2024 17:57:48 +0000,
Quentin Perret <qperret at google.com> wrote:
> 
> We don't need 16 bits to store the hyp page order, and we'll need some
> bits to store page ownership data soon, so let's reduce the order
> member.
> 
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/gfp.h    |  6 +++---
>  arch/arm64/kvm/hyp/include/nvhe/memory.h |  5 +++--
>  arch/arm64/kvm/hyp/nvhe/page_alloc.c     | 14 +++++++-------
>  3 files changed, 13 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> index 97c527ef53c2..f1725bad6331 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> @@ -7,7 +7,7 @@
>  #include <nvhe/memory.h>
>  #include <nvhe/spinlock.h>
>  
> -#define HYP_NO_ORDER	USHRT_MAX
> +#define HYP_NO_ORDER	0xff

nit: (u8)(~0)?

	M.

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


From andre.przywara at arm.com  Tue Dec 17 03:01:40 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 17 Dec 2024 11:01:40 +0000
Subject: [PATCH] rtc: use boolean values with device_init_wakeup()
In-Reply-To: <20241217071331.3607-2-wsa+renesas@sang-engineering.com>
References: <20241217071331.3607-2-wsa+renesas@sang-engineering.com>
Message-ID: <20241217110140.22c92138@donnerap.manchester.arm.com>

On Tue, 17 Dec 2024 08:13:26 +0100
Wolfram Sang <wsa+renesas at sang-engineering.com> wrote:

> device_init_wakeup() second argument is a bool type. Use proper boolean
> values when calling it to match the type and to produce unambiguous code
> which is easier to understand.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>

Verified via regexps that it's indeed this pattern: 1 => true, 0 => false.

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
> Created with a coccinelle script. I opted for a single patch because the change
> is rather trivial. I can break out per driver if this is desired. If you
> like the change at all, that is.
> 
>  drivers/rtc/rtc-88pm80x.c       | 2 +-
>  drivers/rtc/rtc-88pm860x.c      | 2 +-
>  drivers/rtc/rtc-amlogic-a4.c    | 6 +++---
>  drivers/rtc/rtc-armada38x.c     | 2 +-
>  drivers/rtc/rtc-as3722.c        | 2 +-
>  drivers/rtc/rtc-at91rm9200.c    | 2 +-
>  drivers/rtc/rtc-at91sam9.c      | 2 +-
>  drivers/rtc/rtc-cadence.c       | 2 +-
>  drivers/rtc/rtc-cmos.c          | 2 +-
>  drivers/rtc/rtc-cpcap.c         | 2 +-
>  drivers/rtc/rtc-cros-ec.c       | 2 +-
>  drivers/rtc/rtc-da9055.c        | 2 +-
>  drivers/rtc/rtc-ds3232.c        | 2 +-
>  drivers/rtc/rtc-isl1208.c       | 2 +-
>  drivers/rtc/rtc-jz4740.c        | 2 +-
>  drivers/rtc/rtc-loongson.c      | 4 ++--
>  drivers/rtc/rtc-lp8788.c        | 2 +-
>  drivers/rtc/rtc-lpc32xx.c       | 2 +-
>  drivers/rtc/rtc-max77686.c      | 2 +-
>  drivers/rtc/rtc-max8925.c       | 2 +-
>  drivers/rtc/rtc-max8997.c       | 2 +-
>  drivers/rtc/rtc-meson-vrtc.c    | 2 +-
>  drivers/rtc/rtc-mpc5121.c       | 2 +-
>  drivers/rtc/rtc-mt6397.c        | 2 +-
>  drivers/rtc/rtc-mv.c            | 4 ++--
>  drivers/rtc/rtc-mxc.c           | 2 +-
>  drivers/rtc/rtc-mxc_v2.c        | 2 +-
>  drivers/rtc/rtc-omap.c          | 2 +-
>  drivers/rtc/rtc-palmas.c        | 2 +-
>  drivers/rtc/rtc-pic32.c         | 2 +-
>  drivers/rtc/rtc-pm8xxx.c        | 2 +-
>  drivers/rtc/rtc-pxa.c           | 2 +-
>  drivers/rtc/rtc-rc5t583.c       | 2 +-
>  drivers/rtc/rtc-rc5t619.c       | 2 +-
>  drivers/rtc/rtc-renesas-rtca3.c | 2 +-
>  drivers/rtc/rtc-rk808.c         | 2 +-
>  drivers/rtc/rtc-s3c.c           | 2 +-
>  drivers/rtc/rtc-s5m.c           | 2 +-
>  drivers/rtc/rtc-sa1100.c        | 2 +-
>  drivers/rtc/rtc-sc27xx.c        | 4 ++--
>  drivers/rtc/rtc-sh.c            | 2 +-
>  drivers/rtc/rtc-spear.c         | 4 ++--
>  drivers/rtc/rtc-sun6i.c         | 2 +-
>  drivers/rtc/rtc-sunplus.c       | 4 ++--
>  drivers/rtc/rtc-tegra.c         | 2 +-
>  drivers/rtc/rtc-test.c          | 2 +-
>  drivers/rtc/rtc-tps6586x.c      | 2 +-
>  drivers/rtc/rtc-tps65910.c      | 2 +-
>  drivers/rtc/rtc-twl.c           | 2 +-
>  drivers/rtc/rtc-wm831x.c        | 2 +-
>  drivers/rtc/rtc-wm8350.c        | 2 +-
>  drivers/rtc/rtc-xgene.c         | 4 ++--
>  drivers/rtc/rtc-zynqmp.c        | 4 ++--
>  53 files changed, 62 insertions(+), 62 deletions(-)
> 


From maz at kernel.org  Tue Dec 17 03:03:08 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 11:03:08 +0000
Subject: [PATCH v3 04/18] KVM: arm64: Move host page ownership tracking to the hyp vmemmap
In-Reply-To: <20241216175803.2716565-5-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
	<20241216175803.2716565-5-qperret@google.com>
Message-ID: <86y10er2qb.wl-maz@kernel.org>

On Mon, 16 Dec 2024 17:57:49 +0000,
Quentin Perret <qperret at google.com> wrote:
> 
> We currently store part of the page-tracking state in PTE software bits
> for the host, guests and the hypervisor. This is sub-optimal when e.g.
> sharing pages as this forces to break block mappings purely to support
> this software tracking. This causes an unnecessarily fragmented stage-2
> page-table for the host in particular when it shares pages with Secure,
> which can lead to measurable regressions. Moreover, having this state
> stored in the page-table forces us to do multiple costly walks on the
> page transition path, hence causing overhead.
> 
> In order to work around these problems, move the host-side page-tracking
> logic from SW bits in its stage-2 PTEs to the hypervisor's vmemmap.
> 
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/memory.h |   6 +-
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 100 ++++++++++++++++-------
>  arch/arm64/kvm/hyp/nvhe/setup.c          |   7 +-
>  3 files changed, 77 insertions(+), 36 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> index 45b8d1840aa4..8bd9a539f260 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> @@ -8,7 +8,7 @@
>  #include <linux/types.h>
>  
>  /*
> - * SW bits 0-1 are reserved to track the memory ownership state of each page:
> + * Bits 0-1 are reserved to track the memory ownership state of each page:
>   *   00: The page is owned exclusively by the page-table owner.
>   *   01: The page is owned by the page-table owner, but is shared
>   *       with another entity.
> @@ -43,7 +43,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
>  struct hyp_page {
>  	u16 refcount;
>  	u8 order;
> -	u8 reserved;
> +
> +	/* Host (non-meta) state. Guarded by the host stage-2 lock. */
> +	enum pkvm_page_state host_state : 8;

An enum as a bitfield? Crazy! :)

You probably want an assert somewhere that ensures that hyp_page is a
32bit quantity, just to make sure (and avoid hard to track bugs).

Thanks,

	M.

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


From quic_sibis at quicinc.com  Tue Dec 17 03:05:15 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 17 Dec 2024 16:35:15 +0530
Subject: [PATCH V4 4/5] soc: qcom: Introduce SCMI based Memlat (Memory
 Latency) governor
In-Reply-To: <uwwiz2o6brn5zczbpaiajdq7yva2qpcpgzwdr26lhg4jvlwvvj@w5bkiuhdalze>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-5-quic_sibis@quicinc.com>
 <2aycrvnvivcrqctqmweadcgenwugafdr6ub3bzkscterpenz32@bzabln2hkral>
 <29eef87e-96f6-5105-6f7a-a8e01efcb4a3@quicinc.com>
 <k4lpzxtrq3x6riyv6etxiobn7nbpczf2bp3m4oc752nhjknlit@uo53kbppzim7>
 <ac655bdc-5ccf-c6c6-3203-659f1916c53c@quicinc.com>
 <34p27za5hcpubaxjuddsir2vqnqrvwyesnclu2cocvm3yhbv3r@ak7rcnp67gyd>
 <1f5258f4-7c20-5343-dec6-0847449c821b@quicinc.com>
 <CAA8EJpoN3QSi72UUDV+=YkqySgXkiODUFJvwpBYfSmnkSotuZA@mail.gmail.com>
 <4399f7da-9478-57c0-7405-e51dc35d90ba@quicinc.com>
 <uwwiz2o6brn5zczbpaiajdq7yva2qpcpgzwdr26lhg4jvlwvvj@w5bkiuhdalze>
Message-ID: <d2d95756-c51d-17bb-ce12-d8ae390a3bac@quicinc.com>



On 12/17/24 16:16, Dmitry Baryshkov wrote:
> On Tue, Dec 17, 2024 at 03:46:24PM +0530, Sibi Sankar wrote:
>>
>>
>> On 12/5/24 17:00, Dmitry Baryshkov wrote:
>>> On Thu, 5 Dec 2024 at 12:53, Sibi Sankar <quic_sibis at quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 11/14/24 18:02, Dmitry Baryshkov wrote:
>>>>> On Thu, Nov 14, 2024 at 09:43:53AM +0530, Sibi Sankar wrote:
>>>>>>
>>>>>>
>>>>>> On 10/26/24 23:46, Dmitry Baryshkov wrote:
>>>>>>> On Tue, Oct 22, 2024 at 01:48:25PM +0530, Sibi Sankar wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 10/7/24 23:27, Dmitry Baryshkov wrote:
>>>>>>>>> On Mon, Oct 07, 2024 at 11:40:22AM GMT, Sibi Sankar wrote:
>>>>>
>>>>>>>>>
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +struct map_param_msg {
>>>>>>>>>> +        u32 hw_type;
>>>>>>>>>> +        u32 mon_idx;
>>>>>>>>>> +        u32 nr_rows;
>>>>>>>>>> +        struct map_table tbl[MAX_MAP_ENTRIES];
>>>>>>>>>> +} __packed;
>>>>>>>>>> +
>>>>>>>>>> +struct node_msg {
>>>>>>>>>> +        u32 cpumask;
>>>>>>>>>> +        u32 hw_type;
>>>>>>>>>> +        u32 mon_type;
>>>>>>>>>> +        u32 mon_idx;
>>>>>>>>>> +        char mon_name[MAX_NAME_LEN];
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +struct scalar_param_msg {
>>>>>>>>>> +        u32 hw_type;
>>>>>>>>>> +        u32 mon_idx;
>>>>>>>>>> +        u32 val;
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +enum common_ev_idx {
>>>>>>>>>> +        INST_IDX,
>>>>>>>>>> +        CYC_IDX,
>>>>>>>>>> +        CONST_CYC_IDX,
>>>>>>>>>> +        FE_STALL_IDX,
>>>>>>>>>> +        BE_STALL_IDX,
>>>>>>>>>> +        NUM_COMMON_EVS
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +enum grp_ev_idx {
>>>>>>>>>> +        MISS_IDX,
>>>>>>>>>> +        WB_IDX,
>>>>>>>>>> +        ACC_IDX,
>>>>>>>>>> +        NUM_GRP_EVS
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +#define EV_CPU_CYCLES           0
>>>>>>>>>> +#define EV_INST_RETIRED         2
>>>>>>>>>> +#define EV_L2_D_RFILL           5
>>>>>>>>>> +
>>>>>>>>>> +struct ev_map_msg {
>>>>>>>>>> +        u32 num_evs;
>>>>>>>>>> +        u32 hw_type;
>>>>>>>>>> +        u32 cid[NUM_COMMON_EVS];
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +struct cpufreq_memfreq_map {
>>>>>>>>>> +        unsigned int cpufreq_mhz;
>>>>>>>>>> +        unsigned int memfreq_khz;
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +struct scmi_monitor_info {
>>>>>>>>>> +        struct cpufreq_memfreq_map *freq_map;
>>>>>>>>>> +        char mon_name[MAX_NAME_LEN];
>>>>>>>>>> +        u32 mon_idx;
>>>>>>>>>> +        u32 mon_type;
>>>>>>>>>> +        u32 ipm_ceil;
>>>>>>>>>> +        u32 mask;
>>>>>>>>>> +        u32 freq_map_len;
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +struct scmi_memory_info {
>>>>>>>>>> +        struct scmi_monitor_info *monitor[MAX_MONITOR_CNT];
>>>>>>>>>> +        u32 hw_type;
>>>>>>>>>> +        int monitor_cnt;
>>>>>>>>>> +        u32 min_freq;
>>>>>>>>>> +        u32 max_freq;
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +struct scmi_memlat_info {
>>>>>>>>>> +        struct scmi_protocol_handle *ph;
>>>>>>>>>> +        const struct qcom_generic_ext_ops *ops;
>>>>>>>>>> +        struct scmi_memory_info *memory[MAX_MEMORY_TYPES];
>>>>>>>>>> +        u32 cluster_info[NR_CPUS];
>>>>>>>>>> +        int memory_cnt;
>>>>>>>>>> +};
>>>>>>>>>> +
>>>>>>>>>> +static int populate_cluster_info(u32 *cluster_info)
>>>>>>>>>> +{
>>>>>>>>>> +        char name[MAX_NAME_LEN];
>>>>>>>>>> +        int i = 0;
>>>>>>>>>> +
>>>>>>>>>> +        struct device_node *cn __free(device_node) = of_find_node_by_path("/cpus");
>>>>>>>>>> +        if (!cn)
>>>>>>>>>> +                return -ENODEV;
>>>>>>>>>> +
>>>>>>>>>> +        struct device_node *map __free(device_node) = of_get_child_by_name(cn, "cpu-map");
>>>>>>>>>> +        if (!map)
>>>>>>>>>> +                return -ENODEV;
>>>>>>>>>> +
>>>>>>>>>> +        do {
>>>>>>>>>> +                snprintf(name, sizeof(name), "cluster%d", i);
>>>>>>>>>> +                struct device_node *c __free(device_node) = of_get_child_by_name(map, name);
>>>>>>>>>> +                if (!c)
>>>>>>>>>> +                        break;
>>>>>>>>>> +
>>>>>>>>>> +                *(cluster_info + i) = of_get_child_count(c);
>>>>>>>>>> +                i++;
>>>>>>>>>> +        } while (1);
>>>>>>>>>
>>>>>>>>> Can you use existing API from drivers/base/arch_topology.c? If not, can
>>>>>>>>> it be extended to support your usecase?
>>>>>>>>
>>>>>>>> ack. But I'm pretty sure it's going to take a while for reaching such
>>>>>>>> an agreement so I'll drop this feature during the next re-spin.
>>>>>>>
>>>>>>> Why? What kind of API do you actually need? The arch_topology.c simply
>>>>>>> exports a table of struct cpu_topology. Is it somehow different from
>>>>>>> what you are parsing manually?
>>>>>>
>>>>>> yup, we had to figure out the physical id of the cpu
>>>>>> since cpus can be disabled by the bootloader using
>>>>>> status = "failed" property and we have to pass this
>>>>>> onto the cpucp memlat algorithm.
>>>>>
>>>>> Isn't it equal to the index in the cpu_topology table?
>>>>
>>>> from what I see cpu_topology indexes remain unpopulated
>>>> for cpus that are disabled since get_cpu_for_node
>>>> ignores those?
>>>
>>> Why do you need cpu_topology for disabled aka non-existing CPU devices?
>>
>> sorry was out sick couldn't back earlier. We need the know
>> what cpus are disbled to pass on the correct mask of cpus
>> enabled to the SCP.
> 
> Yes. So isn't it enough to know only the enabled CPUs?

yes just knowing the physical index of the enabled cpus
should be enough.

> 
> 


From dmitry.baryshkov at linaro.org  Tue Dec 17 03:07:02 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 13:07:02 +0200
Subject: [PATCH v20 1/9] soc: cadence: Create helper functions for
 Cadence MHDP
In-Reply-To: <7fd5d54e2594aadd66598888ddf512f3d6d30e5d.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
 <7fd5d54e2594aadd66598888ddf512f3d6d30e5d.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <rew4x4qxemig7rq4kossrn7cybihrgsizh43wnllgv2daf75gm@ziqsakm7gm56>

On Tue, Dec 17, 2024 at 02:51:43PM +0800, Sandor Yu wrote:
> Cadence MHDP IP includes a firmware. Driver and firmware communicate
> through a mailbox. The basic mailbox access functions in this patch
> are derived from the DRM bridge MHDP8546 driver.
> New mailbox access functions have been created based on different mailbox
> return values and security types, making them reusable across different
> MHDP driver versions and SOCs.
> 
> These helper fucntions will be reused in both the DRM bridge driver MDHP8501
> and the i.MX8MQ HDPTX PHY driver.
> 
> Six mailbox access helper functions are introduced.
> Three for non-secure mailbox access:
>  - cdns_mhdp_mailbox_send()
>  - cdns_mhdp_mailbox_send_recv()
>  - cdns_mhdp_mailbox_send_recv_multi()
> The other three for secure mailbox access:
>  - cdns_mhdp_secure_mailbox_send()
>  - cdns_mhdp_secure_mailbox_send_recv()
>  - cdns_mhdp_secure_mailbox_send_recv_multi()
> 
> All MHDP commands that need to be passed through the mailbox
> should be rewritten using these new helper functions.
> 
> The register read/write and DP DPCD read/write command functions
> are also included in this new helper driver.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> ---
> v19->v20:
> - new patch in v20.
>   The patch split from Patch #1 in v19 and move to a new folder drivers/soc/cadence

It makes it harder to review, but granted that we have already past
that, I think it's fine.

> 
> diff --git a/drivers/soc/cadence/Kconfig b/drivers/soc/cadence/Kconfig
> new file mode 100644
> index 0000000000000..b668790660fa5
> --- /dev/null
> +++ b/drivers/soc/cadence/Kconfig
> @@ -0,0 +1,9 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +config CDNS_MHDP_HELPER
> +	tristate "Cadence MHDP Helper driver"

This symbol isn't supposed to be selected by the user. Please leave just
tristate without the menu entry text (the help text is fine, please keep
it).

LGTM otherwise.

> +	help
> +	  Enable Cadence MHDP helpers for mailbox, HDMI and DP.
> +	  This driver provides a foundational layer of mailbox communication for
> +	  various Cadence MHDP IP implementations, such as HDMI and DisplayPort.
> +

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Tue Dec 17 03:07:45 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 13:07:45 +0200
Subject: [PATCH v20 2/9] drm: bridge: cadence: Update mhdp8546 mailbox
 access functions
In-Reply-To: <74bc3f2ff56348afd9d773589236ddf06dc3d45c.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
 <74bc3f2ff56348afd9d773589236ddf06dc3d45c.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <z4cmwy6vh6nncq445hvm23n4ar4quciemvcj5zvofevulyofx6@w266vucwqv7s>

On Tue, Dec 17, 2024 at 02:51:44PM +0800, Sandor Yu wrote:
> Basic mailbox access functions are removed, they are replaced by
> mailbox helper functions:
> - cdns_mhdp_mailbox_send()
> - cdns_mhdp_mailbox_send_recv()
> - cdns_mhdp_mailbox_send_recv_multi()
> - cdns_mhdp_secure_mailbox_send()
> - cdns_mhdp_secure_mailbox_send_recv()
> - cdns_mhdp_secure_mailbox_send_recv_multi()
> 
> All MHDP commands that need to be passed through the mailbox
> have been rewritten using these new helper functions.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> ---
> v19->v20:
> - remove mhdp helper functions from the patch.
> 
> v18->v19:
> - Use guard(mutex)
> - Add kerneldocs for all new APIs.
> - Detail comments for mailbox access specific case.
> - Remove cdns_mhdp_dp_reg_write() because it is not needed by driver now.
> 
> v17->v18:
> - Create three ordinary mailbox access APIs
>     cdns_mhdp_mailbox_send
>     cdns_mhdp_mailbox_send_recv
>     cdns_mhdp_mailbox_send_recv_multi
> - Create three secure mailbox access APIs
>     cdns_mhdp_secure_mailbox_send
>     cdns_mhdp_secure_mailbox_send_recv
>     cdns_mhdp_secure_mailbox_send_recv_multi
> - MHDP8546 DP and HDCP commands that need access mailbox are rewrited
>   with above 6 API functions.
> 
> v16->v17:
> - Replaces the local mutex mbox_mutex with a global mutex mhdp_mailbox_mutex
> 
> v12->v16:
>  *No change.
> 
>  drivers/gpu/drm/bridge/cadence/Kconfig        |   1 +
>  .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 487 +++---------------
>  .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  47 +-
>  .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c   | 212 +-------
>  .../drm/bridge/cadence/cdns-mhdp8546-hdcp.h   |  18 +-
>  5 files changed, 104 insertions(+), 661 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From eichest at gmail.com  Tue Dec 17 03:15:40 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Tue, 17 Dec 2024 12:15:40 +0100
Subject: [PATCH v1] irqchip/irq-mvebu-icu: Fix irq_set_type for sei and nsr
Message-ID: <20241217111623.92625-1-eichest@gmail.com>

A regression was introduced in commit d929e4db22b6
("irqchip/irq-mvebu-icu: Prepare for real per device MSI") that causes
the Armada thermal driver to fail during probe with the following error:
genirq: Setting trigger mode 4 for irq 85 failed (irq_chip_set_type_parent+0x0/0x34)
armada_thermal f2400000.system-controller:thermal-sensor at 70: Cannot request threaded IRQ 85
armada_thermal f2400000.system-controller:thermal-sensor at 70: probe with driver armada_thermal failed with error -22

The issue occurs because irq_set_type is assigned to
irq_chip_set_type_parent, but the parent IRQ chip does not implement the
irq_set_type operation. This causes the trigger mode configuration to
fail.

This patch resolves the issue by removing the irq_set_type assignment.
With no irq_set_type, __irq_set_trigger safely skips the trigger
configuration, restoring functionality to the thermal driver.

Fixes: d929e4db22b6 ("irqchip/irq-mvebu-icu: Prepare for real per device MSI")
Signed-off-by: Stefan Eichenberger <eichest at gmail.com>
---
 drivers/irqchip/irq-mvebu-icu.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/irqchip/irq-mvebu-icu.c b/drivers/irqchip/irq-mvebu-icu.c
index b337f6c05f18..1d4dde719db6 100644
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -188,7 +188,6 @@ static const struct msi_domain_template mvebu_icu_nsr_msi_template = {
 		.irq_mask		= irq_chip_mask_parent,
 		.irq_unmask		= irq_chip_unmask_parent,
 		.irq_eoi		= irq_chip_eoi_parent,
-		.irq_set_type		= irq_chip_set_type_parent,
 		.irq_write_msi_msg	= mvebu_icu_write_msi_msg,
 		.flags			= IRQCHIP_SUPPORTS_LEVEL_MSI,
 	},
@@ -212,7 +211,6 @@ static const struct msi_domain_template mvebu_icu_sei_msi_template = {
 		.irq_mask		= irq_chip_mask_parent,
 		.irq_unmask		= irq_chip_unmask_parent,
 		.irq_ack		= irq_chip_ack_parent,
-		.irq_set_type		= irq_chip_set_type_parent,
 		.irq_write_msi_msg	= mvebu_icu_write_msi_msg,
 		.flags			= IRQCHIP_SUPPORTS_LEVEL_MSI,
 	},
-- 
2.45.2



From robh at kernel.org  Tue Dec 17 03:21:25 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 17 Dec 2024 05:21:25 -0600
Subject: [PATCH v5] dt-bindings: power: Convert raspberrypi,bcm2835-power
 to Dt schema
In-Reply-To: <20241216-raspberrypi-bcm2835-power-v5-1-222fc244132b@gmail.com>
References: <20241216-raspberrypi-bcm2835-power-v5-1-222fc244132b@gmail.com>
Message-ID: <173443448203.859628.7169765786016335364.robh@kernel.org>


On Mon, 16 Dec 2024 17:07:00 +0000, Karan Sanghavi wrote:
> Convert the raspberrypi,bcm2835-power binding to Dt schema
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Karan Sanghavi <karansanghvi98 at gmail.com>
> ---
> Changes in v5:
> - Added maintainers for the power domain
> - Link to v4: https://lore.kernel.org/r/20241028-raspberrypi-bcm2835-power-v4-1-acf44abd45ff at gmail.com
> 
> Changes in v4:
> - Corrected misindentations and random differences.
> - Link to v3: https://lore.kernel.org/r/20241026-raspberrypi-bcm2835-power-v3-1-6621e075d33f at gmail.com
> 
> Changes in v3:
> - Applied changes as per the feedback received for title and description
> - Removed power label and renamed node to power-controller
> - Moved the file from bindings/soc/bcm to bindings/power
> - Link to v2: https://lore.kernel.org/r/20241022-raspberrypi-bcm2835-power-v2-1-1a4a8a8a5737 at gmail.com
> 
> Changes in v2:
> - Added original file maintainers
> - Removed unnecessary headers from example and formating from description
> - Link to v1: https://lore.kernel.org/r/20241019-raspberrypi-bcm2835-power-v1-1-75e924dc3745 at gmail.com
> ---
>  .../bindings/power/raspberrypi,bcm2835-power.yaml  | 42 +++++++++++++++++++
>  .../bindings/soc/bcm/raspberrypi,bcm2835-power.txt | 47 ----------------------
>  2 files changed, 42 insertions(+), 47 deletions(-)
> 

Applied, thanks!



From maz at kernel.org  Tue Dec 17 03:29:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 11:29:03 +0000
Subject: [PATCH v3 11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
In-Reply-To: <20241216175803.2716565-12-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
	<20241216175803.2716565-12-qperret@google.com>
Message-ID: <86wmfyr1j4.wl-maz@kernel.org>

On Mon, 16 Dec 2024 17:57:56 +0000,
Quentin Perret <qperret at google.com> wrote:
> 
> In preparation for letting the host unmap pages from non-protected
> guests, introduce a new hypercall implementing the host-unshare-guest
> transition.
> 
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  6 ++
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 21 ++++++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 67 +++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/pkvm.c                | 12 ++++
>  6 files changed, 108 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 449337f5b2a3..0b6c4d325134 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -66,6 +66,7 @@ enum __kvm_host_smccc_func {
>  	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
>  	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
>  	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> +	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
>  	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
>  	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
>  	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index a7976e50f556..e528a42ed60e 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -40,6 +40,7 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
>  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
> +int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
>  
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> index be52c5b15e21..0cc2a429f1fb 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> @@ -64,6 +64,11 @@ static inline bool pkvm_hyp_vcpu_is_protected(struct pkvm_hyp_vcpu *hyp_vcpu)
>  	return vcpu_is_protected(&hyp_vcpu->vcpu);
>  }
>  
> +static inline bool pkvm_hyp_vm_is_protected(struct pkvm_hyp_vm *hyp_vm)
> +{
> +	return kvm_vm_is_protected(&hyp_vm->kvm);
> +}
> +
>  void pkvm_hyp_vm_table_init(void *tbl);
>  
>  int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
> @@ -78,6 +83,7 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
>  struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void);
>  
>  struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
> +struct pkvm_hyp_vm *get_np_pkvm_hyp_vm(pkvm_handle_t handle);
>  void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
>  
>  #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index d659462fbf5d..3c3a27c985a2 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -244,6 +244,26 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
>  	cpu_reg(host_ctxt, 1) =  ret;
>  }
>  
> +static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
> +{
> +	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> +	DECLARE_REG(u64, gfn, host_ctxt, 2);
> +	struct pkvm_hyp_vm *hyp_vm;
> +	int ret = -EINVAL;
> +
> +	if (!is_protected_kvm_enabled())
> +		goto out;
> +
> +	hyp_vm = get_np_pkvm_hyp_vm(handle);
> +	if (!hyp_vm)
> +		goto out;
> +
> +	ret = __pkvm_host_unshare_guest(gfn, hyp_vm);
> +	put_pkvm_hyp_vm(hyp_vm);
> +out:
> +	cpu_reg(host_ctxt, 1) =  ret;
> +}
> +
>  static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
>  {
>  	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
> @@ -454,6 +474,7 @@ static const hcall_t host_hcall[] = {
>  	HANDLE_FUNC(__pkvm_host_share_hyp),
>  	HANDLE_FUNC(__pkvm_host_unshare_hyp),
>  	HANDLE_FUNC(__pkvm_host_share_guest),
> +	HANDLE_FUNC(__pkvm_host_unshare_guest),
>  	HANDLE_FUNC(__kvm_adjust_pc),
>  	HANDLE_FUNC(__kvm_vcpu_run),
>  	HANDLE_FUNC(__kvm_flush_vm_context),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index fb9592e721cf..30243b7922f1 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -1421,3 +1421,70 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
>  
>  	return ret;
>  }
> +
> +static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)
> +{
> +	enum pkvm_page_state state;
> +	struct hyp_page *page;
> +	kvm_pte_t pte;
> +	u64 phys;
> +	s8 level;
> +	int ret;
> +
> +	ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
> +	if (ret)
> +		return ret;
> +	if (level != KVM_PGTABLE_LAST_LEVEL)

So there is still a very strong assumption that a guest is only
provided page mappings, and no blocks?

Thanks,

	M.

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


From mike.leach at linaro.org  Tue Dec 17 03:41:11 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Tue, 17 Dec 2024 11:41:11 +0000
Subject: [PATCH v2 2/3] coresight: tmc: Update error logging in tmc common functions
In-Reply-To: <9094b068-ed3a-444d-b790-e43a652ab6e9@arm.com>
References: <20241213144919.110642-1-mike.leach@linaro.org>
 <20241213144919.110642-3-mike.leach@linaro.org> <9094b068-ed3a-444d-b790-e43a652ab6e9@arm.com>
Message-ID: <CAJ9a7VjCK+FGB+EMbcgaRfkv13TYYgBNHTG+AGp=52dZ7EfQAQ@mail.gmail.com>

Hi Suzuki,

On Mon, 16 Dec 2024 at 09:33, Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>
> On 13/12/2024 14:49, Mike Leach wrote:
> > Enhance the error logging in the tmc_wait_for_tmcready() and
> > tmc_flush_and_stop() to print key tmc  register values on error
> > conditions to improve hardware debug information.
> >
> > Signed-off-by: Mike Leach <mike.leach at linaro.org>
> > ---
> >   .../hwtracing/coresight/coresight-tmc-core.c  | 37 +++++++++++++++----
> >   drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
> >   2 files changed, 30 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> > index e9876252a789..1a9299adae93 100644
> > --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> > @@ -34,25 +34,36 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
> >   DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
> >   DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
> >
> > +#define TMC_WAIT_READY_FMT_STR "timeout while waiting for TMC to be Ready [STS=0x%04x]\n"
> > +
> >   int tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
> >   {
> >       struct coresight_device *csdev = drvdata->csdev;
> >       struct csdev_access *csa = &csdev->access;
> > +     u32 tmc_sts = 0;
> >
> >       /* Ensure formatter, unformatter and hardware fifo are empty */
> > -     if (coresight_timeout(csa, TMC_STS, TMC_STS_TMCREADY_BIT, 1)) {
> > -             dev_err(&csdev->dev,
> > -                     "timeout while waiting for TMC to be Ready\n");
> > +     if (coresight_timeout_retval(csa, TMC_STS, TMC_STS_TMCREADY_BIT, 1,
> > +                                  &tmc_sts)) {
> > +             dev_err(&csdev->dev, TMC_WAIT_READY_FMT_STR, tmc_sts);
> >               return -EBUSY;
> >       }
> >       return 0;
> >   }
> >
> > -void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
> > +int tmc_flush_and_stop(struct tmc_drvdata *drvdata)
> >   {
> >       struct coresight_device *csdev = drvdata->csdev;
> >       struct csdev_access *csa = &csdev->access;
> > -     u32 ffcr;
> > +     u32 ffcr, ffsr, tmc_sts;
> > +     int rc = 0;
> > +
> > +     /* note any MemErr present when stopping TMC */
> > +     tmc_sts = readl_relaxed(drvdata->base + TMC_STS);
> > +     if (tmc_sts & TMC_STS_MEMERR)
> > +             dev_err(&csdev->dev,
> > +                     "MemErr detected before Manual Flush; STS[0x%02x]\n",
> > +                     tmc_sts);
> >
> >       ffcr = readl_relaxed(drvdata->base + TMC_FFCR);
> >       ffcr |= TMC_FFCR_STOP_ON_FLUSH;
> > @@ -60,12 +71,22 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
> >       ffcr |= BIT(TMC_FFCR_FLUSHMAN_BIT);
> >       writel_relaxed(ffcr, drvdata->base + TMC_FFCR);
> >       /* Ensure flush completes */
> > -     if (coresight_timeout(csa, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0)) {
> > +     if (coresight_timeout_retval(csa, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0,
> > +                                  &ffcr)) {
> > +             ffsr = readl_relaxed(drvdata->base + TMC_FFSR);
> >               dev_err(&csdev->dev,
> > -             "timeout while waiting for completion of Manual Flush\n");
> > +                     "timeout while waiting for completion of Manual Flush\n");
> > +             dev_err(&csdev->dev,
> > +                     "regs: FFCR[0x%02x] FFSR[0x%02x] STS[0x%02x]\n",
> > +                     ffcr, ffsr, tmc_sts);
> > +             rc = -EBUSY;
> >       }
> >
> > -     tmc_wait_for_tmcready(drvdata);
> > +     if (tmc_wait_for_tmcready(drvdata)) {
> > +             dev_err(&csdev->dev, "TMC ready error after Manual flush\n");
> > +             rc = -EBUSY;
> > +     }
> > +     return rc;
> >   }
>
> All of this looks good to me. Do we need to move the MemErr check post
> the flush ? There is a potential chance of hitting a MemERR on flushing
> and we could miss reproting those ones ?
>

We need the one before - if there is already a Memerr then this will
affect the flush operation - on Memerr the formatter will have stopped
etc. But no harm in putting another check afterwards.

Mike

> Suzuki
>
> >   void tmc_enable_hw(struct tmc_drvdata *drvdata)
> > diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> > index 2671926be62a..34513f07c3aa 100644
> > --- a/drivers/hwtracing/coresight/coresight-tmc.h
> > +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> > @@ -259,7 +259,7 @@ struct tmc_sg_table {
> >
> >   /* Generic functions */
> >   int tmc_wait_for_tmcready(struct tmc_drvdata *drvdata);
> > -void tmc_flush_and_stop(struct tmc_drvdata *drvdata);
> > +int tmc_flush_and_stop(struct tmc_drvdata *drvdata);
> >   void tmc_enable_hw(struct tmc_drvdata *drvdata);
> >   void tmc_disable_hw(struct tmc_drvdata *drvdata);
> >   u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata);
>


-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From quic_sibis at quicinc.com  Tue Dec 17 03:45:39 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 17 Dec 2024 17:15:39 +0530
Subject: [PATCH V4 1/5] dt-bindings: firmware: Document bindings for QCOM
 SCMI Generic Extension
In-Reply-To: <Z1HGVhi5xebqc4d4@bogus>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <20241007061023.1978380-2-quic_sibis@quicinc.com> <Z1HGVhi5xebqc4d4@bogus>
Message-ID: <b31d2e68-e4e0-97e6-158c-1b9ab8308551@quicinc.com>



On 12/5/24 20:57, Sudeep Holla wrote:
> On Mon, Oct 07, 2024 at 11:40:19AM +0530, Sibi Sankar wrote:
>> Document the various memory buses that can be monitored and scaled by
>> the memory latency governor hosted by the QCOM SCMI Generic Extension
>> Protocol v1.0.
>>
>> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
>> ---
>>
>> v3:
>> * Restructure the bindings to mimic IMX [Christian]
>>
>>   .../bindings/firmware/arm,scmi.yaml           |   1 +
>>   .../bindings/firmware/qcom,scmi-memlat.yaml   | 246 ++++++++++++++++++
>>   .../dt-bindings/firmware/qcom,scmi-memlat.h   |  22 ++
>>   3 files changed, 269 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/firmware/qcom,scmi-memlat.yaml
>>   create mode 100644 include/dt-bindings/firmware/qcom,scmi-memlat.h
>>
>> diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
>> index 54d7d11bfed4..1d405f429168 100644
>> --- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
>> +++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
>> @@ -24,6 +24,7 @@ description: |
>>   
>>   anyOf:
>>     - $ref: /schemas/firmware/nxp,imx95-scmi.yaml
>> +  - $ref: /schemas/firmware/qcom,scmi-memlat.yaml
>>   
>>   properties:
>>     $nodename:
>> diff --git a/Documentation/devicetree/bindings/firmware/qcom,scmi-memlat.yaml b/Documentation/devicetree/bindings/firmware/qcom,scmi-memlat.yaml
>> new file mode 100644
>> index 000000000000..0e8ea6dacd6a
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/firmware/qcom,scmi-memlat.yaml
>> @@ -0,0 +1,246 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/firmware/qcom,scmi-memlat.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm SCMI Memory Bus nodes
>> +
>> +maintainers:
>> +  - Sibi Sankar <quic_sibis at quicinc.com>
>> +
>> +description:
>> +  This binding describes the various memory buses that can be monitored and scaled
>> +  by memory latency governor running on the CPU Control Processor (SCMI controller).
>> +
>> +properties:
>> +  protocol at 80:
>> +    $ref: '/schemas/firmware/arm,scmi.yaml#/$defs/protocol-node'
>> +    unevaluatedProperties: false
>> +
>> +    properties:
>> +      reg:
>> +        const: 0x80
>> +
>> +    patternProperties:
>> +      '^memory-[0-9]$':
>> +        type: object
>> +        unevaluatedProperties: false
>> +        description:
>> +          The list of all memory buses that can be monitored and scaled by the
>> +          memory latency governor running on the SCMI controller.
>> +
>> +        properties:
>> +          qcom,memory-type:
>> +            $ref: /schemas/types.yaml#/definitions/uint32
>> +            enum: [0, 1, 2]
>> +            description: |
>> +              Memory Bus Identifier
>> +              0 = QCOM_MEM_TYPE_DDR
>> +              1 = QCOM_MEM_TYPE_LLCC
>> +              2 = QCOM_MEM_TYPE_DDR_QOS
>> +
>> +          freq-table-hz:
>> +            items:
>> +              items:
>> +                - description: Minimum frequency of the memory bus in Hz
>> +                - description: Maximum frequency of the memory bus in Hz
>> +
>> +        patternProperties:
>> +          '^monitor-[0-9]$':
>> +            type: object
>> +            unevaluatedProperties: false
>> +            description:
>> +              The list of all monitors detecting the memory latency bound workloads using
>> +              various counters.
>> +
>> +            properties:
>> +              qcom,compute-type:
>> +                description:
>> +                  Monitors of type compute perform bus dvfs based on a rudimentary CPU
>> +                  frequency to memory frequency map.
>> +                type: boolean
>> +
>> +              qcom,ipm-ceil:
>> +                $ref: /schemas/types.yaml#/definitions/uint32
>> +                description:
>> +                  Monitors having this property perform bus dvfs based on the same
>> +                  rudimentary table but the scaling is performed only if the calculated
>> +                  IPM (Instruction Per Misses) exceeds the given ceiling.
>> +
>> +              cpus:
>> +                $ref: /schemas/types.yaml#/definitions/phandle-array
>> +                description:
>> +                  Should be a list of phandles to CPU nodes (as described in
>> +                  Documentation/devicetree/bindings/arm/cpus.yaml).
> 
> And what exactly this list of cpu phandles represent here ?
> 
>> +
>> +              operating-points-v2: true
> 
> Can you elaborate why the protocol can't add a command to fetch this from
> the firmware to avoid any possible mismatch between the DT and firmware.
> 
>> +              opp-table:
>> +                type: object
>> +
>> +            required:
>> +              - cpus
>> +              - operating-points-v2
>> +
>> +            oneOf:
>> +              - required: [ 'qcom,compute-type' ]
>> +              - required: [ 'qcom,ipm-ceil' ]
>> +
>> +        required:
>> +          - qcom,memory-type
>> +          - freq-table-hz
>> +
>> +additionalProperties: true
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/firmware/qcom,scmi-memlat.h>
>> +
>> +    firmware {
>> +        scmi {
>> +            compatible = "arm,scmi";
>> +            mboxes = <&cpucp_mbox 0>, <&cpucp_mbox 2>;
>> +            mbox-names = "tx", "rx";
>> +            shmem = <&cpu_scp_lpri0>, <&cpu_scp_lpri1>;
>> +
>> +            #address-cells = <1>;
>> +            #size-cells = <0>;
>> +
>> +            protocol at 80 {
>> +                reg = <0x80>;
>> +
>> +                memory-0 {


Hey Sudeep,

Thanks for taking time to review the series :)

> 
> I am not sure if it is just me, but I find this binding hard to understand.
> Hence I thought I will look and the example and get better understanding
> instead.
> 
> So these monitors are numbered ? If there were any meaningful name it would

A memory type can have a variable number of monitors. The
monitors take in a table and memory type. They track the freq
of a group of cpus and put in requests to scale the memory
according to the table. The naming is just arbitrary here
and we can choose whatever that makes the most sense.


> have been slightly better but irrespective of that I find it hard as why
> the communication with firmware is not based on index and why they are not
> part of the bindings though I see indices used in the driver.
> 
>> +                    qcom,memory-type = <QCOM_MEM_TYPE_DDR>;
> 
> Also I see that the type can be easily derived from the index, care to
> elaborate why the firmware expects it to be sent, if not why is that
> information needed here in the DT ?

The firmware doesn't have any information on the memory available
for it to scale and relies of the linux telling it everything in
order to function.


-Sibi


> 


From dmitry.baryshkov at linaro.org  Tue Dec 17 03:47:34 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 13:47:34 +0200
Subject: [PATCH v20 5/9] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <fbd12029fab1f60e2ba4fad75ef650298a59cb15.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
 <fbd12029fab1f60e2ba4fad75ef650298a59cb15.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <3ivd4mdmcb56mrgg2yo3rszksiusfkyxr3eycuw5kspczqcqse@4nub63fnrsur>

On Tue, Dec 17, 2024 at 02:51:47PM +0800, Sandor Yu wrote:
> 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>
> ---
> v19->v20:
> - Dump mhdp FW version by debugfs
> - Combine HDMI and DP cable detect functions into one function
> - Combine HDMI and DP cable bridge_mode_valid() functions into one function
> - Rename cdns_hdmi_reset_link() to cdns_hdmi_handle_hotplug()
> - Add comments for EDID in cdns_hdmi_handle_hotplug() and cdns_dp_check_link_state()
> - Add atomic_get_input_bus_fmts() and bridge_atomic_check() for DP driver
> - Remove bpc and color_fmt init in atomic_enable() function.
> - More detail comments for DDC adapter only support SCDC_I2C_SLAVE_ADDRESS
>   read and write in HDMI driver.
> 
> 
> v18->v19:
> - Get endpoint for data-lanes as it had move to endpoint of port at 1
> - Update clock management as devm_clk_get_enabled() introduced.
> - Fix clear_infoframe() function is not work issue.
> - Manage PHY power state via phy_power_on() and phy_power_off().
> 
> v17->v18:
> - MHDP8501 HDMI and DP commands that need access mailbox are rewrited
>   with new API functions created in patch #1.
> - replace lane-mapping with data-lanes, use the value from data-lanes
>   to reorder HDMI and DP lane mapping.
> - create I2C adapter for HDMI SCDC, remove cdns_hdmi_scdc_write() function.
> - Rewrite cdns_hdmi_sink_config() function, use HDMI SCDC helper function
>   drm_scdc_set_high_tmds_clock_ratio() and drm_scdc_set_scrambling()
>   to config HDMI sink TMDS.
> - Remove struct video_info from HDMI driver.
> - Remove tmds_char_rate_valid() be called in bridge_mode_valid(),
>   community had patch in reviewing to implement the function.
> - Remove warning message print when get unknown HPD cable status.
> - Add more detail comments for HDP plugin and plugout interrupt.
> - use dev_dbg to repleace DRM_INFO when cable HPD status changed.
> - Remove t-b tag as above code change.
> 
>  drivers/gpu/drm/bridge/cadence/Kconfig        |  16 +
>  drivers/gpu/drm/bridge/cadence/Makefile       |   2 +
>  .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 379 +++++++++
>  .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 380 +++++++++
>  .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 694 ++++++++++++++++
>  .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 745 ++++++++++++++++++
>  6 files changed, 2216 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 dbb06533ccab2..bd979f3e6df48 100644
> --- a/drivers/gpu/drm/bridge/cadence/Kconfig
> +++ b/drivers/gpu/drm/bridge/cadence/Kconfig
> @@ -48,3 +48,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 DRM_CDNS_AUDIO
> +	select CDNS_MHDP_HELPER
> +	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 c95fd5b81d137..ea327287d1c14 100644
> --- a/drivers/gpu/drm/bridge/cadence/Makefile
> +++ b/drivers/gpu/drm/bridge/cadence/Makefile
> @@ -5,3 +5,5 @@ cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.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..98116ef012fa3
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> @@ -0,0 +1,379 @@
> +// 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 ssize_t firmware_version_show(struct device *dev,
> +				     struct device_attribute *attr, char *buf);
> +static struct device_attribute firmware_version = __ATTR_RO(firmware_version);
> +
> +ssize_t firmware_version_show(struct device *dev,
> +			      struct device_attribute *attr, char *buf)
> +{
> +	struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(dev);
> +
> +	u32 version = readl(mhdp->base.regs + VER_L) | readl(mhdp->base.regs + VER_H) << 8;
> +	u32 lib_version = readl(mhdp->base.regs + VER_LIB_L_ADDR) |
> +			  readl(mhdp->base.regs + VER_LIB_H_ADDR) << 8;
> +
> +	return sprintf(buf, "FW version %d, Lib version %d\n", version, lib_version);
> +}
> +
> +static void cdns_mhdp8501_create_device_files(struct cdns_mhdp8501_device *mhdp)
> +{
> +	if (device_create_file(mhdp->dev, &firmware_version)) {
> +		DRM_ERROR("Unable to create firmware_version sysfs\n");
> +		device_remove_file(mhdp->dev, &firmware_version);
> +	}
> +}
> +
> +static void cdns_mhdp8501_remove_device_files(struct cdns_mhdp8501_device *mhdp)
> +{
> +	device_remove_file(mhdp->dev, &firmware_version);
> +}
> +
> +static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device *mhdp)
> +{
> +	u8 status;
> +	int ret;
> +
> +	ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_GENERAL,
> +					  GENERAL_GET_HPD_STATE,
> +					  0, NULL, sizeof(status), &status);
> +	if (ret) {
> +		dev_err(mhdp->dev, "read hpd failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return status;
> +}
> +
> +enum drm_connector_status cdns_mhdp8501_detect(struct drm_bridge *bridge)
> +{
> +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> +
> +	u8 hpd = 0xf;
> +
> +	hpd = cdns_mhdp8501_read_hpd(mhdp);
> +	if (hpd == 1)
> +		return connector_status_connected;
> +	else if (hpd == 0)
> +		return connector_status_disconnected;
> +
> +	return connector_status_unknown;
> +}
> +
> +enum drm_mode_status
> +cdns_mhdp8501_mode_valid(struct drm_bridge *bridge,
> +			 const struct drm_display_info *info,
> +			 const struct drm_display_mode *mode)
> +{
> +	/* We don't support double-clocked */
> +	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> +		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_OK;
> +}
> +
> +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->bridge);
> +
> +	drm_bridge_hpd_notify(&mhdp->bridge, status);
> +
> +	/*
> +	 * iMX8MQ has two HPD interrupts: one for plugout and one for plugin.
> +	 * These interrupts cannot be masked and cleaned, so we must enable one
> +	 * and disable the other to avoid continuous interrupt generation.
> +	 */
> +	if (status == connector_status_connected) {
> +		/* Cable connected  */
> +		dev_dbg(mhdp->dev, "HDMI/DP Cable Plug In\n");
> +		enable_irq(mhdp->irq[IRQ_OUT]);
> +
> +		/* Reset HDMI/DP link with sink */
> +		if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
> +			cdns_hdmi_handle_hotplug(mhdp);
> +		else
> +			cdns_dp_check_link_state(mhdp);
> +
> +	} else if (status == connector_status_disconnected) {
> +		/* Cable Disconnected  */
> +		dev_dbg(mhdp->dev, "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;
> +}
> +
> +#define DATA_LANES_COUNT	4
> +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, *endpoint;
> +	u32 data_lanes[DATA_LANES_COUNT];
> +	u32 lane_value;
> +	int ret, i;
> +
> +	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;

Interesting hack. What if somebody wraps DP signals with the USB-C
controller in order to provide DP over USB-C?

Unfortunately I don't have a good solution here. There might be other
format converters after your bridge, so you even can't look at the last
bridge of the chain. You might want to examine the phy-mode property and
use it to specify whether the PHY should work in the HDMI or in the DP
mode.

Also, where do get the next bridge and attach it to the bridge chain?

> +
> +	} else {
> +		dev_err(dev, "Unknown connector type\n");
> +		of_node_put(remote);
> +		return -EINVAL;
> +	}
> +
> +	of_node_put(remote);
> +
> +	endpoint = of_graph_get_endpoint_by_regs(np, 1, -1);
> +
> +	/* Get the data lanes ordering */
> +	ret = of_property_count_u32_elems(endpoint, "data-lanes");
> +	if (ret < 0)
> +		return  -EINVAL;
> +	if (ret != DATA_LANES_COUNT) {
> +		dev_err(dev, "expected 4 data lanes\n");
> +		return  -EINVAL;
> +	}

Isn't it drm_of_get_data_lanes_count_ep()?

> +
> +	ret = of_property_read_u32_array(endpoint, "data-lanes",
> +					 data_lanes, DATA_LANES_COUNT);
> +	if (ret)
> +		return  -EINVAL;
> +
> +	mhdp->lane_mapping  = 0;
> +	for (i = 0; i < DATA_LANES_COUNT; i++) {
> +		lane_value = (data_lanes[i] >= 0 && data_lanes[i] <= 3) ? data_lanes[i] : 0;
> +		mhdp->lane_mapping |= lane_value << (i * 2);
> +	}
> +
> +	return true;
> +}
> +
> +static int cdns_mhdp8501_add_bridge(struct cdns_mhdp8501_device *mhdp)
> +{
> +	mhdp->bridge.type = mhdp->connector_type;
> +	mhdp->bridge.driver_private = mhdp;
> +	mhdp->bridge.of_node = mhdp->dev->of_node;
> +	mhdp->bridge.vendor = "NXP";
> +	mhdp->bridge.product = "i.MX8";
> +	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
> +			   DRM_BRIDGE_OP_HPD;
> +
> +	if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
> +		mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
> +		mhdp->bridge.ops |= DRM_BRIDGE_OP_HDMI;
> +		mhdp->bridge.ddc = cdns_hdmi_i2c_adapter(mhdp);

I'd expect that bridge.ddc provides DDC service. Is it required to
control the SCDC from userspace?

> +	} 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 -EINVAL;
> +	}
> +
> +	drm_bridge_add(&mhdp->bridge);
> +
> +	return 0;
> +}
> +
> +static int cdns_mhdp8501_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct cdns_mhdp8501_device *mhdp;
> +	struct resource *res;
> +	enum phy_mode phy_mode;
> +	u32 reg;
> +	int ret;
> +
> +	mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
> +	if (!mhdp)
> +		return -ENOMEM;
> +
> +	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);
> +
> +	cdns_mhdp8501_create_device_files(mhdp);
> +
> +	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;
> +	}
> +
> +	/* cdns_mhdp8501_dt_parse() ensures connector_type is valid */
> +	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
> +		phy_mode = PHY_MODE_DP;
> +	else if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
> +		phy_mode = PHY_MODE_HDMI;
> +
> +	dev_set_drvdata(dev, mhdp);
> +
> +	/* init base struct for access mhdp mailbox */
> +	mhdp->base.dev = mhdp->dev;
> +	mhdp->base.regs = mhdp->regs;
> +
> +	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_enabled(dev, NULL);
> +	if (IS_ERR(mhdp->apb_clk))
> +		return dev_err_probe(dev, PTR_ERR(mhdp->apb_clk),
> +				     "couldn't get apb clk\n");
> +	/*
> +	 * 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);
> +		return ret;
> +	}
> +
> +	ret = phy_init(mhdp->phy);
> +	if (ret) {
> +		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = phy_set_mode(mhdp->phy, phy_mode);
> +	if (ret) {
> +		dev_err(dev, "Failed to configure PHY: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* Enable cable hotplug detect */
> +	if (cdns_mhdp8501_read_hpd(mhdp))
> +		enable_irq(mhdp->irq[IRQ_OUT]);
> +	else
> +		enable_irq(mhdp->irq[IRQ_IN]);
> +
> +	return cdns_mhdp8501_add_bridge(mhdp);
> +}
> +
> +static void cdns_mhdp8501_remove(struct platform_device *pdev)
> +{
> +	struct cdns_mhdp8501_device *mhdp = platform_get_drvdata(pdev);
> +
> +	cdns_mhdp8501_remove_device_files(mhdp);
> +
> +	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
> +		cdns_dp_aux_destroy(mhdp);
> +
> +	drm_bridge_remove(&mhdp->bridge);
> +}
> +
> +static const struct of_device_id cdns_mhdp8501_dt_ids[] = {
> +	{ .compatible = "fsl,imx8mq-mhdp8501",
> +	},

Strange line wrapping, I'd say. Either it should all be on the same
line, or take three lines.

> +	{ },
> +};
> +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..8fc463098ab84
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
> @@ -0,0 +1,380 @@
> +/* 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/drm_bridge.h>
> +#include <drm/drm_connector.h>
> +#include <drm/display/drm_dp_helper.h>
> +#include <linux/bitops.h>
> +#include <linux/i2c.h>
> +#include <soc/cadence/cdns-mhdp-helper.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_FLIPPED		0xe4
> +#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_HDMI2_CTRL_IL_MODE(x)		(((x) & ((1 << 1) - 1)) << 19)
> +#define F_HDMI2_PREAMBLE_EN(x)		(((x) & ((1 << 1) - 1)) << 18)
> +#define F_HDMI_ENCODING(x)		(((x) & ((1 << 2) - 1)) << 16)
> +#define F_DATA_EN(x)			(((x) & ((1 << 1) - 1)) << 15)
> +#define F_CLEAR_AVMUTE(x)		(((x) & ((1 << 1) - 1)) << 14)
> +#define F_SET_AVMUTE(x)			(((x) & ((1 << 1) - 1)) << 13)
> +#define F_GCP_EN(x)			(((x) & ((1 << 1) - 1)) << 12)
> +#define F_BCH_EN(x)			(((x) & ((1 << 1) - 1)) << 11)
> +#define F_PIC_3D(x)			(((x) & ((1 << 4) - 1)) << 7)
> +#define F_VIF_DATA_WIDTH(x)		(((x) & ((1 << 2) - 1)) << 2)
> +#define F_HDMI_MODE(x)			(((x) & ((1 << 2) - 1)) << 0)
> +
> +#define F_SOURCE_PHY_MHDP_SEL(x)	(((x) & ((1 << 2) - 1)) << 3)
> +
> +#define F_HPD_GLITCH_WIDTH(x)		(((x) & ((1 << 8) - 1)) << 12)
> +#define F_PACKET_TYPE(x)		(((x) & ((1 << 8) - 1)) << 8)
> +#define F_HPD_VALID_WIDTH(x)		(((x) & ((1 << 12) - 1)) << 0)
> +
> +#define F_SOURCE_PHY_LANE3_SWAP(x)	(((x) & ((1 << 2) - 1)) << 6)
> +#define F_SOURCE_PHY_LANE2_SWAP(x)	(((x) & ((1 << 2) - 1)) << 4)
> +#define F_SOURCE_PHY_LANE1_SWAP(x)	(((x) & ((1 << 2) - 1)) << 2)
> +#define F_SOURCE_PHY_LANE0_SWAP(x)	(((x) & ((1 << 2) - 1)) << 0)
> +
> +#define F_ACTIVE_IDLE_TYPE(x)		(((x) & ((1 << 1) - 1)) << 17)
> +#define F_TYPE_VALID(x)			(((x) & ((1 << 1) - 1)) << 16)
> +#define F_PKT_ALLOC_ADDRESS(x)		(((x) & ((1 << 4) - 1)) << 0)
> +
> +#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)
> +
> +/* 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 cdns_hdmi_i2c {
> +	struct i2c_adapter	adap;
> +
> +	struct mutex		lock;	/* used to serialize data transfers */
> +	struct completion	cmp;
> +	u8			stat;
> +
> +	u8			slave_reg;
> +	bool			is_regaddr;
> +	bool			is_segment;
> +};
> +
> +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;
> +
> +	int irq[IRQ_NUM];
> +	struct delayed_work hotplug_work;
> +	int connector_type;
> +	u32 lane_mapping;
> +
> +	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;
> +			struct cdns_hdmi_i2c *i2c;
> +		} hdmi;
> +	};
> +};
> +
> +extern const struct drm_bridge_funcs cdns_dp_bridge_funcs;
> +extern const struct drm_bridge_funcs cdns_hdmi_bridge_funcs;
> +
> +enum drm_connector_status
> +cdns_mhdp8501_detect(struct drm_bridge *bridge);
> +enum drm_mode_status
> +cdns_mhdp8501_mode_valid(struct drm_bridge *bridge,
> +			 const struct drm_display_info *info,
> +			 const struct drm_display_mode *mode);
> +
> +ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg);
> +int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp);
> +void cdns_dp_check_link_state(struct cdns_mhdp8501_device *mhdp);
> +
> +void cdns_hdmi_handle_hotplug(struct cdns_mhdp8501_device *mhdp);
> +struct i2c_adapter *cdns_hdmi_i2c_adapter(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..157b4d44b9e2b
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> @@ -0,0 +1,694 @@
> +// 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/media-bus-format.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,
> +				const struct drm_display_mode *mode)
> +{
> +	struct video_info *video = &mhdp->video_info;
> +	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;
> +
> +	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);
> +
> +	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;
> +
> +	/* start training */
> +	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
> +				     DPTX_TRAINING_CONTROL, sizeof(msg), &msg);
> +	if (ret)
> +		return ret;
> +
> +	timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
> +	while (time_before(jiffies, timeout)) {
> +		msleep(LINK_TRAINING_RETRY_MS);
> +		ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX,
> +						  DPTX_READ_EVENT,
> +						  0, NULL, sizeof(event), event);
> +		if (ret)
> +			return ret;
> +
> +		if (event[1] & CLK_RECOVERY_FAILED)
> +			dev_err(mhdp->dev, "clock recovery failed\n");
> +		else if (event[1] & EQ_PHASE_FINISHED)
> +			return 0;
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static int cdns_dp_get_training_status(struct cdns_mhdp8501_device *mhdp)
> +{
> +	u8 status[13];
> +	int ret;
> +
> +	ret = cdns_mhdp_mailbox_send_recv(&mhdp->base, MB_MODULE_ID_DP_TX,
> +					  DPTX_READ_LINK_STAT,
> +					  0, NULL, sizeof(status), status);
> +	if (ret)
> +		return ret;
> +
> +	mhdp->dp.rate = drm_dp_bw_code_to_link_rate(status[0]);
> +	mhdp->dp.num_lanes = status[1];
> +
> +	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;
> +
> +	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
> +				     DPTX_SET_HOST_CAPABILITIES,
> +				     sizeof(msg), msg);
> +	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;
> +
> +	for (i = 0; i < 4; i++) {
> +		msg[0] = block / 2;
> +		msg[1] = block % 2;
> +
> +		ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base,
> +							MB_MODULE_ID_DP_TX,
> +							DPTX_GET_EDID,
> +							sizeof(msg), msg,
> +							DPTX_GET_EDID,
> +							sizeof(reg), reg,
> +							length, edid);
> +		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);
> +
> +	return ret;
> +}
> +
> +static void cdns_dp_mode_set(struct cdns_mhdp8501_device *mhdp,
> +			     const struct drm_display_mode *mode)
> +{
> +	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 = false;

If all of those are false, then you can skip setting .lanes and
.link_rate.

> +
> +	ret = phy_configure(mhdp->phy, &phy_cfg);
> +	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, mode);
> +	if (ret)
> +		dev_err(mhdp->dev, "Failed to config video %d\n", ret);
> +}
> +
> +static bool
> +cdns_dp_needs_link_retrain(struct cdns_mhdp8501_device *mhdp)
> +{
> +	u8 link_status[DP_LINK_STATUS_SIZE];
> +
> +	if (drm_dp_dpcd_read_phy_link_status(&mhdp->dp.aux, DP_PHY_DPRX,
> +					     link_status) < 0)
> +		return false;
> +
> +	/* Retrain if link not ok */
> +	return !drm_dp_channel_eq_ok(link_status, mhdp->dp.num_lanes);
> +}
> +
> +void cdns_dp_check_link_state(struct cdns_mhdp8501_device *mhdp)
> +{
> +	struct drm_connector *connector = mhdp->curr_conn;
> +	const struct drm_edid *drm_edid;
> +	struct drm_connector_state *conn_state;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_crtc *crtc;
> +
> +	if (!connector)
> +		return;
> +
> +	/*
> +	 * EDID data needs updating after each cable plugin
> +	 * due to potential display monitor changes
> +	 */
> +	drm_edid = drm_edid_read_custom(connector, cdns_dp_get_edid_block, mhdp);
> +	drm_edid_connector_update(connector, drm_edid);
> +
> +	if (!drm_edid)
> +		return;
> +
> +	drm_edid_free(drm_edid);
> +
> +	conn_state = connector->state;
> +	crtc = conn_state->crtc;
> +	if (!crtc)
> +		return;
> +
> +	crtc_state = crtc->state;
> +	if (!crtc_state->active)
> +		return;
> +
> +	if (!cdns_dp_needs_link_retrain(mhdp))
> +		return;
> +
> +	/* DP link retrain */
> +	if (cdns_dp_train_link(mhdp))
> +		dev_err(mhdp->dev, "Failed link train\n");

Won't this cause link traning to happen on the first monitor plug event?
Is it okay to do even with the phy being powered off?

> +}
> +
> +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);

Why is it a part of the _attach callback? If there is anything on the DP
AUX bus, it should be already registered by this point.

> +}
> +
> +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);
> +}
> +
> +/* Currently supported format */
> +static const u32 mhdp8501_input_fmts[] = {
> +	MEDIA_BUS_FMT_RGB888_1X24,
> +	MEDIA_BUS_FMT_RGB101010_1X30,
> +};
> +
> +static u32 *cdns_dp_bridge_atomic_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)
> +{
> +	u32 *input_fmts;
> +
> +	*num_input_fmts = 0;
> +
> +	input_fmts = kcalloc(ARRAY_SIZE(mhdp8501_input_fmts),
> +			     sizeof(*input_fmts),
> +			     GFP_KERNEL);
> +	if (!input_fmts)
> +		return NULL;
> +
> +	*num_input_fmts = ARRAY_SIZE(mhdp8501_input_fmts);
> +	memcpy(input_fmts, mhdp8501_input_fmts, sizeof(mhdp8501_input_fmts));
> +
> +	return input_fmts;
> +}
> +
> +static int cdns_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 cdns_mhdp8501_device *mhdp = bridge->driver_private;
> +	struct video_info *video = &mhdp->video_info;
> +
> +	if (bridge_state->input_bus_cfg.format == MEDIA_BUS_FMT_RGB888_1X24) {
> +		video->bpc = 8;
> +		video->color_fmt = DRM_COLOR_FORMAT_RGB444;
> +	} else if (bridge_state->input_bus_cfg.format == MEDIA_BUS_FMT_RGB101010_1X30) {
> +		video->bpc = 10;
> +		video->color_fmt = DRM_COLOR_FORMAT_RGB444;

Which driver is going to select bus config for you?

> +	} else {
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +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;
> +
> +	phy_power_off(mhdp->phy);
> +}
> +
> +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 drm_crtc_state *crtc_state;
> +	struct drm_connector_state *conn_state;
> +	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;
> +
> +	cdns_dp_mode_set(mhdp, &crtc_state->adjusted_mode);
> +
> +	/* Power up PHY before link training */
> +	phy_power_on(mhdp->phy);
> +
> +	/* Link training */
> +	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_mhdp8501_detect,
> +	.edid_read = cdns_dp_bridge_edid_read,
> +	.mode_valid = cdns_mhdp8501_mode_valid,
> +	.atomic_enable = cdns_dp_bridge_atomic_enable,
> +	.atomic_disable = cdns_dp_bridge_atomic_disable,
> +	.atomic_get_input_bus_fmts = cdns_dp_bridge_atomic_get_input_bus_fmts,
> +	.atomic_check = cdns_dp_bridge_atomic_check,
> +	.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..9556d0929e21d
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> @@ -0,0 +1,745 @@
> +// 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_hdmi_state_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_config_infoframe() - fill the HDMI infoframe
> + * @mhdp: phandle to mhdp device.
> + * @entry_id: The packet memory address in which the data is written.
> + * @len: length of infoframe.
> + * @buf: point to InfoFrame Packet.
> + * @type: Packet Type of InfoFrame in HDMI Specification.
> + *
> + */
> +
> +static void cdns_hdmi_clear_infoframe(struct cdns_mhdp8501_device *mhdp,
> +				      u8 entry_id, u8 type)
> +{
> +	u32 val;
> +
> +	/* invalidate entry */
> +	val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id) |
> +	      F_PACKET_TYPE(type);
> +	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 void cdns_hdmi_config_infoframe(struct cdns_mhdp8501_device *mhdp,
> +				       u8 entry_id, u8 len,
> +				       const u8 *buf, u8 type)
> +{
> +	u8 packet[32], packet_len = 32;
> +	u32 packet32, len32;
> +	u32 val, i;
> +
> +	/*
> +	 * only support 32 bytes now
> +	 * packet[0] = 0
> +	 * packet[1-3] = HB[0-2]  InfoFrame Packet Header
> +	 * packet[4-31 = PB[0-27] InfoFrame Packet Contents
> +	 */
> +	if (len >= (packet_len - 1))
> +		return;
> +	packet[0] = 0;
> +	memcpy(packet + 1, buf, len);
> +
> +	cdns_hdmi_clear_infoframe(mhdp, entry_id, type);
> +
> +	/* 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(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;
> +
> +	for (i = 0; i < 4; i++) {
> +		msg[0] = block / 2;
> +		msg[1] = block % 2;
> +
> +		ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base,
> +							MB_MODULE_ID_HDMI_TX,
> +							HDMI_TX_EDID,
> +							sizeof(msg), msg,
> +							HDMI_TX_EDID,
> +							sizeof(reg), reg,
> +							length, edid);
> +
> +		if (ret)
> +			continue;

Ignoring the error?

> +
> +		if ((reg[3] << 8 | reg[4]) == length)
> +			break;
> +	}
> +
> +	if (ret)
> +		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", block, ret);
> +	return ret;
> +}
> +
> +static int cdns_hdmi_set_hdmi_mode_type(struct cdns_mhdp8501_device *mhdp)
> +{
> +	struct drm_connector_state *conn_state = mhdp->curr_conn->state;
> +	u32 protocol = mhdp->hdmi.hdmi_type;
> +	u32 val;
> +
> +	if (protocol == MODE_HDMI_2_0 &&
> +	    conn_state->hdmi.tmds_char_rate >= 340000000) {
> +		cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, 0);
> +		cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, 0xFFFFF);
> +	}
> +
> +	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
> +
> +	/* set HDMI mode and preemble mode data enable */
> +	val |= F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) |
> +	       F_HDMI2_CTRL_IL_MODE(1);
> +	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
> +}
> +
> +static int cdns_hdmi_ctrl_init(struct cdns_mhdp8501_device *mhdp)
> +{
> +	u32 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;
> +
> +	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, 0x7c1f);
> +	if (ret < 0)
> +		return ret;
> +	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, 0x7c1f);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* init HDMI Controller */
> +	val = F_BCH_EN(1) | F_PIC_3D(0xF) | F_CLEAR_AVMUTE(1);
> +	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
> +	if (ret < 0)
> +		return ret;
> +
> +	return cdns_hdmi_set_hdmi_mode_type(mhdp);
> +}
> +
> +static int cdns_hdmi_mode_config(struct cdns_mhdp8501_device *mhdp,
> +				 struct drm_display_mode *mode,
> +				 struct drm_connector_hdmi_state *hdmi)
> +{
> +	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);
> +	int ret;
> +	u32 val;
> +
> +	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 (hdmi->output_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 (hdmi->output_format) {
> +	case HDMI_COLORSPACE_YUV444:
> +		val |= F_HDMI_ENCODING(2);
> +		break;
> +	case HDMI_COLORSPACE_YUV422:
> +		val |= F_HDMI_ENCODING(1);
> +		break;
> +	case HDMI_COLORSPACE_YUV420:
> +		val |= F_HDMI_ENCODING(3);
> +		break;
> +	case HDMI_COLORSPACE_RGB:
> +	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);
> +	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
> +}
> +
> +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);
> +}
> +
> +#define HDMI_14_MAX_TMDS_CLK   (340 * 1000 * 1000)
> +static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp,
> +				  unsigned long long tmds_char_rate)
> +{
> +	struct drm_connector *connector = mhdp->curr_conn;
> +	struct drm_display_info *display = &connector->display_info;
> +	struct drm_scdc *scdc = &display->hdmi.scdc;
> +	bool hdmi_scrambling = false;
> +	bool hdmi_high_tmds_clock_ratio = false;
> +
> +	/* check sink type (HDMI or DVI) */
> +	if (!display->is_hdmi) {
> +		mhdp->hdmi.hdmi_type = MODE_DVI;
> +		return;
> +	}
> +
> +	/* Default work in HDMI1.4 */
> +	mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;
> +
> +	/* check sink support SCDC or not */
> +	if (!scdc->supported) {
> +		dev_dbg(mhdp->dev, "Sink Not Support SCDC\n");
> +		return;
> +	}
> +
> +	if (tmds_char_rate > HDMI_14_MAX_TMDS_CLK) {
> +		hdmi_scrambling = true;
> +		hdmi_high_tmds_clock_ratio = true;
> +		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
> +	} else if (scdc->scrambling.low_rates) {
> +		hdmi_scrambling = true;
> +		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
> +	}
> +
> +	/* Set TMDS bit clock ratio to 1/40 or 1/10, and enable/disable scrambling */
> +	drm_scdc_set_high_tmds_clock_ratio(connector, hdmi_high_tmds_clock_ratio);
> +	drm_scdc_set_scrambling(connector, hdmi_scrambling);
> +}
> +
> +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 int reset_pipe(struct drm_crtc *crtc)
> +{
> +	struct drm_atomic_state *state;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_modeset_acquire_ctx ctx;
> +	int ret;
> +
> +	state = drm_atomic_state_alloc(crtc->dev);
> +	if (!state)
> +		return -ENOMEM;
> +
> +	drm_modeset_acquire_init(&ctx, 0);
> +
> +	state->acquire_ctx = &ctx;
> +
> +	crtc_state = drm_atomic_get_crtc_state(state, crtc);
> +	if (IS_ERR(crtc_state)) {
> +		ret = PTR_ERR(crtc_state);
> +		goto out;
> +	}
> +
> +	crtc_state->connectors_changed = true;
> +
> +	ret = drm_atomic_commit(state);
> +out:
> +	drm_atomic_state_put(state);
> +	drm_modeset_drop_locks(&ctx);
> +	drm_modeset_acquire_fini(&ctx);
> +
> +	return ret;
> +}
> +
> +void cdns_hdmi_handle_hotplug(struct cdns_mhdp8501_device *mhdp)
> +{
> +	struct drm_connector *connector = mhdp->curr_conn;
> +	const struct drm_edid *drm_edid;
> +	struct drm_connector_state *conn_state;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_crtc *crtc;
> +
> +	if (!connector)
> +		return;
> +
> +	/*
> +	 * EDID data needs updating after each cable plugin
> +	 * due to potential display monitor changes
> +	 */
> +	drm_edid = drm_edid_read_custom(connector, cdns_hdmi_get_edid_block, mhdp);
> +	drm_edid_connector_update(connector, drm_edid);
> +
> +	if (!drm_edid)
> +		return;
> +
> +	drm_edid_free(drm_edid);
> +
> +	conn_state = connector->state;
> +	crtc = conn_state->crtc;
> +	if (!crtc)
> +		return;
> +
> +	crtc_state = crtc->state;
> +	if (!crtc_state->active)
> +		return;
> +
> +	/*
> +	 * HDMI 2.0 says that one should not send scrambled data
> +	 * prior to configuring the sink scrambling, and that
> +	 * TMDS clock/data transmission should be suspended when
> +	 * changing the TMDS clock rate in the sink. So let's
> +	 * just do a full modeset here, even though some sinks
> +	 * would be perfectly happy if were to just reconfigure
> +	 * the SCDC settings on the fly.
> +	 */
> +	reset_pipe(crtc);
> +}
> +
> +static int cdns_hdmi_i2c_write(struct cdns_mhdp8501_device *mhdp,
> +			       struct i2c_msg *msgs)
> +{
> +	u8 msg[5], reg[5];
> +	int ret;
> +
> +	msg[0] = msgs->addr;
> +	msg[1] = msgs->buf[0];
> +	msg[2] = 0;
> +	msg[3] = 1;
> +	msg[4] = msgs->buf[1];
> +
> +	ret = cdns_mhdp_mailbox_send_recv(&mhdp->base,
> +					  MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
> +					  sizeof(msg), msg, sizeof(reg), reg);
> +	if (ret) {
> +		dev_err(mhdp->dev, "I2C write failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	if (reg[0] != 0)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int cdns_hdmi_i2c_read(struct cdns_mhdp8501_device *mhdp,
> +			      struct i2c_msg *msgs, int num)
> +{
> +	u8 msg[4], reg[5];
> +	u8 addr, offset, *buf, len;
> +	int ret, i;
> +
> +	for (i = 0; i < num; i++) {
> +		if (msgs[i].flags & I2C_M_RD) {
> +			addr = msgs[i].addr;
> +			buf = msgs[i].buf;
> +			len = msgs[i].len;
> +		} else {
> +			offset = msgs[i].buf[0];
> +		}
> +	}
> +
> +	msg[0] = addr;
> +	msg[1] = offset;
> +	put_unaligned_be16(len, msg + 2);
> +
> +	ret = cdns_mhdp_mailbox_send_recv_multi(&mhdp->base,
> +						MB_MODULE_ID_HDMI_TX, HDMI_TX_READ,
> +						sizeof(msg), msg,
> +						HDMI_TX_READ,
> +						sizeof(reg), reg,
> +						len, buf);
> +	if (ret) {
> +		dev_err(mhdp->dev, "I2c Read failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +#define  SCDC_I2C_SLAVE_ADDRESS	0x54
> +static int cdns_hdmi_i2c_xfer(struct i2c_adapter *adap,
> +			      struct i2c_msg *msgs, int num)
> +{
> +	struct cdns_mhdp8501_device *mhdp = i2c_get_adapdata(adap);
> +	struct cdns_hdmi_i2c *i2c = mhdp->hdmi.i2c;
> +	int i, ret = 0;
> +
> +	/*
> +	 * MHDP FW provides mailbox APIs for SCDC registers access, but lacks direct I2C APIs.
> +	 * While individual I2C registers can be read/written using HDMI general register APIs,
> +	 * block reads (e.g., EDID) are not supported, making it a limited I2C interface.
> +	 */
> +	for (i = 0; i < num; i++) {
> +		if (msgs[i].addr != SCDC_I2C_SLAVE_ADDRESS) {
> +			dev_err(mhdp->dev, "ADDR=%0x is not supported\n", msgs[i].addr);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	mutex_lock(&i2c->lock);
> +
> +	if (num == 1)
> +		ret = cdns_hdmi_i2c_write(mhdp, msgs);
> +	else
> +		ret = cdns_hdmi_i2c_read(mhdp, msgs, num);
> +
> +	if (!ret)
> +		ret = num;
> +
> +	mutex_unlock(&i2c->lock);
> +
> +	return ret;
> +}
> +
> +static u32 cdns_hdmi_i2c_func(struct i2c_adapter *adapter)
> +{
> +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
> +}
> +
> +static const struct i2c_algorithm cdns_hdmi_algorithm = {
> +	.master_xfer	= cdns_hdmi_i2c_xfer,
> +	.functionality	= cdns_hdmi_i2c_func,
> +};
> +
> +struct i2c_adapter *cdns_hdmi_i2c_adapter(struct cdns_mhdp8501_device *mhdp)
> +{
> +	struct i2c_adapter *adap;
> +	struct cdns_hdmi_i2c *i2c;
> +	int ret;
> +
> +	i2c = devm_kzalloc(mhdp->dev, sizeof(*i2c), GFP_KERNEL);
> +	if (!i2c)
> +		return ERR_PTR(-ENOMEM);
> +
> +	mutex_init(&i2c->lock);
> +
> +	adap = &i2c->adap;
> +	adap->owner = THIS_MODULE;
> +	adap->dev.parent = mhdp->dev;
> +	adap->algo = &cdns_hdmi_algorithm;
> +	strscpy(adap->name, "MHDP HDMI", sizeof(adap->name));
> +	i2c_set_adapdata(adap, mhdp);
> +
> +	ret = i2c_add_adapter(adap);
> +	if (ret) {
> +		dev_warn(mhdp->dev, "cannot add %s I2C adapter\n", adap->name);
> +		devm_kfree(mhdp->dev, i2c);
> +		return ERR_PTR(ret);
> +	}
> +
> +	mhdp->hdmi.i2c = i2c;
> +
> +	return adap;
> +}
> +
> +static enum drm_mode_status
> +cdns_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
> +			       const struct drm_display_mode *mode,
> +			       unsigned long long tmds_rate)
> +{
> +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> +	union phy_configure_opts phy_cfg;
> +	int ret;
> +
> +	phy_cfg.hdmi.tmds_char_rate = tmds_rate;
> +
> +	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
> +	if (ret < 0)
> +		return MODE_CLOCK_RANGE;
> +
> +	return MODE_OK;
> +}
> +
> +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;
> +
> +	phy_power_off(mhdp->phy);
> +}
> +
> +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;
> +	struct drm_connector_hdmi_state *hdmi;
> +	union phy_configure_opts phy_cfg;
> +	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;
> +
> +	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
> +
> +	/* Line swapping */
> +	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
> +
> +	hdmi = &conn_state->hdmi;
> +	if (WARN_ON(!hdmi))
> +		return;
> +
> +	phy_cfg.hdmi.tmds_char_rate = hdmi->tmds_char_rate;
> +	ret = phy_configure(mhdp->phy, &phy_cfg);
> +	if (ret) {
> +		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
> +			__func__, ret);
> +		return;
> +	}
> +
> +	phy_power_on(mhdp->phy);
> +
> +	cdns_hdmi_sink_config(mhdp, hdmi->tmds_char_rate);
> +
> +	ret = cdns_hdmi_ctrl_init(mhdp);
> +	if (ret < 0) {
> +		dev_err(mhdp->dev, "hdmi ctrl init failed = %d\n",  ret);
> +		return;
> +	}
> +
> +	/* Config GCP */
> +	if (hdmi->output_bpc == 8)
> +		cdns_hdmi_disable_gcp(mhdp);
> +	else
> +		cdns_hdmi_enable_gcp(mhdp);
> +
> +	ret = cdns_hdmi_mode_config(mhdp, &crtc_state->adjusted_mode, hdmi);
> +	if (ret < 0) {
> +		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
> +		return;
> +	}
> +}
> +
> +static int cdns_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge,
> +					    enum hdmi_infoframe_type type)
> +{
> +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> +
> +	switch (type) {
> +	case HDMI_INFOFRAME_TYPE_AVI:
> +		cdns_hdmi_clear_infoframe(mhdp, 0, HDMI_INFOFRAME_TYPE_AVI);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_SPD:
> +		cdns_hdmi_clear_infoframe(mhdp, 1, HDMI_INFOFRAME_TYPE_SPD);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_VENDOR:
> +		cdns_hdmi_clear_infoframe(mhdp, 2, HDMI_INFOFRAME_TYPE_VENDOR);
> +		break;
> +	default:
> +		dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n", type);
> +	}
> +
> +	return 0;
> +}
> +
> +static int cdns_hdmi_bridge_write_infoframe(struct drm_bridge *bridge,
> +					    enum hdmi_infoframe_type type,
> +					    const u8 *buffer, size_t len)
> +{
> +	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> +
> +	switch (type) {
> +	case HDMI_INFOFRAME_TYPE_AVI:
> +		cdns_hdmi_config_infoframe(mhdp, 0, len, buffer, HDMI_INFOFRAME_TYPE_AVI);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_SPD:
> +		cdns_hdmi_config_infoframe(mhdp, 1, len, buffer, HDMI_INFOFRAME_TYPE_SPD);
> +		break;
> +	case HDMI_INFOFRAME_TYPE_VENDOR:
> +		cdns_hdmi_config_infoframe(mhdp, 2, len, buffer, HDMI_INFOFRAME_TYPE_VENDOR);
> +		break;
> +	default:
> +		dev_dbg(mhdp->dev, "Unsupported infoframe type %x\n", type);
> +	}
> +
> +	return 0;
> +}
> +
> +static int cdns_hdmi_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)
> +{
> +	return drm_atomic_helper_connector_hdmi_check(conn_state->connector, conn_state->state);
> +}
> +
> +const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
> +	.attach = cdns_hdmi_bridge_attach,
> +	.detect = cdns_mhdp8501_detect,
> +	.edid_read = cdns_hdmi_bridge_edid_read,
> +	.mode_valid = cdns_mhdp8501_mode_valid,
> +	.atomic_enable = cdns_hdmi_bridge_atomic_enable,
> +	.atomic_disable = cdns_hdmi_bridge_atomic_disable,
> +	.atomic_check = cdns_hdmi_bridge_atomic_check,
> +	.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,
> +	.hdmi_clear_infoframe = cdns_hdmi_bridge_clear_infoframe,
> +	.hdmi_write_infoframe = cdns_hdmi_bridge_write_infoframe,
> +	.hdmi_tmds_char_rate_valid = cdns_hdmi_tmds_char_rate_valid,
> +};
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From quic_sibis at quicinc.com  Tue Dec 17 03:49:25 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 17 Dec 2024 17:19:25 +0530
Subject: [PATCH V4 0/5] arm_scmi: vendors: Qualcomm Generic Vendor
 Extensions
In-Reply-To: <Z1HMWUa_QCsNA1-Q@hovoldconsulting.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <ZytnRc94iKUfMYH0@hovoldconsulting.com> <ZyvLktLUZOGP-LH5@pluto>
 <Zy4qvedrmkRdPR3x@hovoldconsulting.com>
 <8d42682b-0fa7-3962-da12-728cfe64903b@quicinc.com>
 <Z0BC203BhGEmXcJi@hovoldconsulting.com>
 <d61bb7bc-d824-883a-4edd-109ae74076c1@quicinc.com>
 <Z1HMWUa_QCsNA1-Q@hovoldconsulting.com>
Message-ID: <132d1404-9009-9fb5-1fb9-63eca03ce9fc@quicinc.com>



On 12/5/24 21:22, Johan Hovold wrote:
> On Thu, Dec 05, 2024 at 04:26:55PM +0530, Sibi Sankar wrote:
>> On 11/22/24 14:07, Johan Hovold wrote:
> 
>>> I have a Lenovo ThinkPad T14s set up now so I gave this series a spin
>>> there too, and there I do *not* see the above mentioned -EOPNOSUPP error
>>> and the memlat driver probes successfully.
>>>
>>> On the other hand, this series seems to have no effect on a kernel
>>> compilation benchmark. Is that expected?
>>
>> I can have a look at your tree. But memlat in general
>> depends on the cpu frequency when your benchmarks max
>> the cpu's the ddr/llcc are scaled accordingly by it.
> 
> A kernel compilation should max out the CPU frequency on all cores.
> 
>>> And does this mean that you should stick with the uppercase "MEMLAT"
>>> string after all? The firmware on my CRD is not the latest one, but I am
>>> using the latest available firmware for the T14s.
>>
>> We should stick with "memlat" if we run into a device in the
>> wild that doesn't support "MEMLAT"
> 
> Ok. So the updated firmware supports both strings?


Sry for the delay, was out sick. Yes the updated firmware supports both
strings.

-Sibi

> 
> Johan


From 0x1207 at gmail.com  Tue Dec 17 03:54:54 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Tue, 17 Dec 2024 19:54:54 +0800
Subject: [PATCH net-next v1] net: stmmac: TSO: Simplify the code flow of
 DMA descriptor allocations
In-Reply-To: <9d0722fe-1547-4b44-8a4a-69a8756bdb39@redhat.com>
References: <20241213030006.337695-1-0x1207@gmail.com>
	<9d0722fe-1547-4b44-8a4a-69a8756bdb39@redhat.com>
Message-ID: <20241217195454.000016ce@gmail.com>

On Tue, 17 Dec 2024 10:30:24 +0100, Paolo Abeni <pabeni at redhat.com> wrote:

> On 12/13/24 04:00, Furong Xu wrote:
> > The DMA AXI address width of DWMAC cores can be configured to
> > 32-bit/40-bit/48-bit, then the format of DMA transmit descriptors
> > get a little different between 32-bit and 40-bit/48-bit.
> > Current driver code checks priv->dma_cap.addr64 to use certain format
> > with certain configuration.
> > 
> > This patch converts the format of DMA transmit descriptors on platforms
> > that the DMA AXI address width is configured to 32-bit (as described by
> > function comments of stmmac_tso_xmit() in current code) to a more generic
> > format (see the updated function comments after this patch) which is
> > actually already used on 40-bit/48-bit platforms to provide better
> > compatibility and make code flow cleaner.
> > 
> > Tested and verified on:
> > DWMAC CORE 5.10a with 32-bit DMA AXI address width
> > DWXGMAC CORE 3.20a with 40-bit DMA AXI address width
> > 
> > Signed-off-by: Furong Xu <0x1207 at gmail.com>  
> 
> Makes sense to me.
> 
> Since this could potentially impact multiple versions, it would be great
> if we could have a little more 3rd parties testing.

Totally agree.

Multiple devices with multiple versions of DWMAC core which is
configured to 32-bit DMA AXI address width seem to very hard to find
and test this patch :(

Jon Hunter @ NVIDIA has two versions of DWMAC cores different from mine,
Tegra186 Jetson TX2 (DWMAC CORE 4.10) and
Tegra194 Jetson AGX Xavier (DWMAC CORE 5.00),
but both of them are configured to 40-bit DMA AXI address width, this does
not match the case that this patch tries to convert. So I decided not to
request him to provide help.


From james.clark at linaro.org  Tue Dec 17 03:56:05 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 17 Dec 2024 11:56:05 +0000
Subject: [PATCH 2/5] perf tool: arm-spe: Pull out functions for aux buffer and tracking setup
In-Reply-To: <20241217115610.371755-1-james.clark@linaro.org>
References: <20241217115610.371755-1-james.clark@linaro.org>
Message-ID: <20241217115610.371755-3-james.clark@linaro.org>

These won't be used in the next commit in discard mode, so put them in
their own functions. No functional changes intended.

Signed-off-by: James Clark <james.clark at linaro.org>
---
 tools/perf/arch/arm64/util/arm-spe.c | 83 +++++++++++++++++-----------
 1 file changed, 51 insertions(+), 32 deletions(-)

diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 22b19dcc6beb..1b543855f206 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -274,33 +274,9 @@ static void arm_spe_setup_evsel(struct evsel *evsel, struct perf_cpu_map *cpus)
 		evsel__set_sample_bit(evsel, PHYS_ADDR);
 }
 
-static int arm_spe_recording_options(struct auxtrace_record *itr,
-				     struct evlist *evlist,
-				     struct record_opts *opts)
+static int arm_spe_setup_aux_buffer(struct record_opts *opts)
 {
-	struct arm_spe_recording *sper =
-			container_of(itr, struct arm_spe_recording, itr);
-	struct evsel *evsel, *tmp;
-	struct perf_cpu_map *cpus = evlist->core.user_requested_cpus;
 	bool privileged = perf_event_paranoid_check(-1);
-	struct evsel *tracking_evsel;
-	int err;
-
-	sper->evlist = evlist;
-
-	evlist__for_each_entry(evlist, evsel) {
-		if (evsel__is_aux_event(evsel)) {
-			if (!strstarts(evsel->pmu->name, ARM_SPE_PMU_NAME)) {
-				pr_err("Found unexpected auxtrace event: %s\n",
-				       evsel->pmu->name);
-				return -EINVAL;
-			}
-			opts->full_auxtrace = true;
-		}
-	}
-
-	if (!opts->full_auxtrace)
-		return 0;
 
 	/*
 	 * we are in snapshot mode.
@@ -330,6 +306,9 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
 			pr_err("Failed to calculate default snapshot size and/or AUX area tracing mmap pages\n");
 			return -EINVAL;
 		}
+
+		pr_debug2("%sx snapshot size: %zu\n", ARM_SPE_PMU_NAME,
+			  opts->auxtrace_snapshot_size);
 	}
 
 	/* We are in full trace mode but '-m,xyz' wasn't specified */
@@ -355,14 +334,15 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
 		}
 	}
 
-	if (opts->auxtrace_snapshot_mode)
-		pr_debug2("%sx snapshot size: %zu\n", ARM_SPE_PMU_NAME,
-			  opts->auxtrace_snapshot_size);
+	return 0;
+}
 
-	evlist__for_each_entry_safe(evlist, tmp, evsel) {
-		if (evsel__is_aux_event(evsel))
-			arm_spe_setup_evsel(evsel, cpus);
-	}
+static int arm_spe_setup_tracking_event(struct evlist *evlist,
+					struct record_opts *opts)
+{
+	int err;
+	struct evsel *tracking_evsel;
+	struct perf_cpu_map *cpus = evlist->core.user_requested_cpus;
 
 	/* Add dummy event to keep tracking */
 	err = parse_event(evlist, "dummy:u");
@@ -388,6 +368,45 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
 	return 0;
 }
 
+static int arm_spe_recording_options(struct auxtrace_record *itr,
+				     struct evlist *evlist,
+				     struct record_opts *opts)
+{
+	struct arm_spe_recording *sper =
+			container_of(itr, struct arm_spe_recording, itr);
+	struct evsel *evsel, *tmp;
+	struct perf_cpu_map *cpus = evlist->core.user_requested_cpus;
+
+	int err;
+
+	sper->evlist = evlist;
+
+	evlist__for_each_entry(evlist, evsel) {
+		if (evsel__is_aux_event(evsel)) {
+			if (!strstarts(evsel->pmu->name, ARM_SPE_PMU_NAME)) {
+				pr_err("Found unexpected auxtrace event: %s\n",
+				       evsel->pmu->name);
+				return -EINVAL;
+			}
+			opts->full_auxtrace = true;
+		}
+	}
+
+	if (!opts->full_auxtrace)
+		return 0;
+
+	evlist__for_each_entry_safe(evlist, tmp, evsel) {
+		if (evsel__is_aux_event(evsel))
+			arm_spe_setup_evsel(evsel, cpus);
+	}
+
+	err = arm_spe_setup_aux_buffer(opts);
+	if (err)
+		return err;
+
+	return arm_spe_setup_tracking_event(evlist, opts);
+}
+
 static int arm_spe_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused,
 					 struct record_opts *opts,
 					 const char *str)
-- 
2.34.1



From james.clark at linaro.org  Tue Dec 17 03:56:06 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 17 Dec 2024 11:56:06 +0000
Subject: [PATCH 3/5] perf tool: arm-spe: Don't allocate buffer or tracking event in discard mode
In-Reply-To: <20241217115610.371755-1-james.clark@linaro.org>
References: <20241217115610.371755-1-james.clark@linaro.org>
Message-ID: <20241217115610.371755-4-james.clark@linaro.org>

The buffer will never be written to so don't bother allocating it. The
tracking event is also not required.

Signed-off-by: James Clark <james.clark at linaro.org>
---
 tools/perf/arch/arm64/util/arm-spe.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 1b543855f206..4301181b8e45 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -376,7 +376,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
 			container_of(itr, struct arm_spe_recording, itr);
 	struct evsel *evsel, *tmp;
 	struct perf_cpu_map *cpus = evlist->core.user_requested_cpus;
-
+	bool discard = false;
 	int err;
 
 	sper->evlist = evlist;
@@ -396,10 +396,17 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
 		return 0;
 
 	evlist__for_each_entry_safe(evlist, tmp, evsel) {
-		if (evsel__is_aux_event(evsel))
+		if (evsel__is_aux_event(evsel)) {
 			arm_spe_setup_evsel(evsel, cpus);
+			if (evsel->core.attr.config &
+			    perf_pmu__format_bits(evsel->pmu, "discard"))
+				discard = true;
+		}
 	}
 
+	if (discard)
+		return 0;
+
 	err = arm_spe_setup_aux_buffer(opts);
 	if (err)
 		return err;
-- 
2.34.1



From james.clark at linaro.org  Tue Dec 17 03:56:07 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 17 Dec 2024 11:56:07 +0000
Subject: [PATCH 4/5] perf test: arm_spe: Add test for discard mode
In-Reply-To: <20241217115610.371755-1-james.clark@linaro.org>
References: <20241217115610.371755-1-james.clark@linaro.org>
Message-ID: <20241217115610.371755-5-james.clark@linaro.org>

Add a test that checks that there were no AUX or AUXTRACE events
recorded when discard mode is used.

Signed-off-by: James Clark <james.clark at linaro.org>
---
 tools/perf/tests/shell/test_arm_spe.sh | 30 ++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tools/perf/tests/shell/test_arm_spe.sh b/tools/perf/tests/shell/test_arm_spe.sh
index 3258368634f7..a69aab70dd8a 100755
--- a/tools/perf/tests/shell/test_arm_spe.sh
+++ b/tools/perf/tests/shell/test_arm_spe.sh
@@ -107,7 +107,37 @@ arm_spe_system_wide_test() {
 	arm_spe_report "SPE system-wide testing" $err
 }
 
+arm_spe_discard_test() {
+	echo "SPE discard mode"
+
+	for f in /sys/bus/event_source/devices/arm_spe_*; do
+		if [ -e "$f/format/discard" ]; then
+			cpu=$(cut -c -1 "$f/cpumask")
+			break
+		fi
+	done
+
+	if [ -z $cpu ]; then
+		arm_spe_report "SPE discard mode not present" 2
+		return
+	fi
+
+	# Test can use wildcard SPE instance and Perf will only open the event
+	# on instances that have that format flag. But make sure the target
+	# runs on an instance with discard mode otherwise we're not testing
+	# anything.
+	perf record -o ${perfdata} -e arm_spe/discard/ -N -B --no-bpf-event \
+		-- taskset --cpu-list $cpu true
+
+	if perf report -i ${perfdata} --stats | grep 'AUX events\|AUXTRACE events'; then
+		arm_spe_report "SPE discard mode found unexpected data" 1
+	else
+		arm_spe_report "SPE discard mode" 0
+	fi
+}
+
 arm_spe_snapshot_test
 arm_spe_system_wide_test
+arm_spe_discard_test
 
 exit $glb_err
-- 
2.34.1



From james.clark at linaro.org  Tue Dec 17 03:56:03 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 17 Dec 2024 11:56:03 +0000
Subject: [PATCH 0/5] perf: arm_spe: Add format option for discard mode
Message-ID: <20241217115610.371755-1-james.clark@linaro.org>

Discard mode is a way to enable SPE related PMU events without the
overhead of recording any data. Add a format option, tests and docs for
it.

In theory we could make the driver drop calls to allocate the aux buffer
when discard mode is enabled. This would give a small memory saving,
but I think there is potential to interfere with any tools that don't
expect this so I left the aux allocation untouched. Even old tools that
don't know about discard mode will be able to use it because we publish
the format option. Not allocating the aux buffer will have to be added
to tools which I've done in Perf.

Tested on the FVP with SAMPLE_FEED_OP (0x812D):

 $ perf stat -e armv8_pmuv3/event=0x812D/ -- true

 Performance counter stats for 'true':

                 0      armv8_pmuv3/event=0x812D/  
 
 $ perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
 $ perf stat -e armv8_pmuv3/event=0x812D/ -- true
 
  Performance counter stats for 'true':

             17350      armv8_pmuv3/event=0x812D/ 

James Clark (5):
  perf: arm_spe: Add format option for discard mode
  perf tool: arm-spe: Pull out functions for aux buffer and tracking
    setup
  perf tool: arm-spe: Don't allocate buffer or tracking event in discard
    mode
  perf test: arm_spe: Add test for discard mode
  perf docs: arm_spe: Document new discard mode

 drivers/perf/arm_spe_pmu.c                | 23 ++++++
 tools/perf/Documentation/perf-arm-spe.txt | 11 +++
 tools/perf/arch/arm64/util/arm-spe.c      | 90 +++++++++++++++--------
 tools/perf/tests/shell/test_arm_spe.sh    | 30 ++++++++
 4 files changed, 122 insertions(+), 32 deletions(-)

-- 
2.34.1



From james.clark at linaro.org  Tue Dec 17 03:56:04 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 17 Dec 2024 11:56:04 +0000
Subject: [PATCH 1/5] perf: arm_spe: Add format option for discard mode
In-Reply-To: <20241217115610.371755-1-james.clark@linaro.org>
References: <20241217115610.371755-1-james.clark@linaro.org>
Message-ID: <20241217115610.371755-2-james.clark@linaro.org>

FEAT_SPEv1p2 (optional from Armv8.6) adds a discard mode that allows all
SPE data to be discarded rather than written to memory. Add a format
bit for this mode.

If the mode isn't supported, the format bit isn't published and attempts
to use it will result in -EOPNOTSUPP. Allocating an aux buffer is still
allowed even though it won't be written to so that old tools continue to
work, but updated tools can choose to skip this step.

Signed-off-by: James Clark <james.clark at linaro.org>
---
 drivers/perf/arm_spe_pmu.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index fd5b78732603..9aaf3f98e6f5 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -193,6 +193,9 @@ static const struct attribute_group arm_spe_pmu_cap_group = {
 #define ATTR_CFG_FLD_store_filter_CFG		config	/* PMSFCR_EL1.ST */
 #define ATTR_CFG_FLD_store_filter_LO		34
 #define ATTR_CFG_FLD_store_filter_HI		34
+#define ATTR_CFG_FLD_discard_CFG		config	/* PMBLIMITR_EL1.FM = DISCARD */
+#define ATTR_CFG_FLD_discard_LO			35
+#define ATTR_CFG_FLD_discard_HI			35
 
 #define ATTR_CFG_FLD_event_filter_CFG		config1	/* PMSEVFR_EL1 */
 #define ATTR_CFG_FLD_event_filter_LO		0
@@ -216,6 +219,7 @@ GEN_PMU_FORMAT_ATTR(store_filter);
 GEN_PMU_FORMAT_ATTR(event_filter);
 GEN_PMU_FORMAT_ATTR(inv_event_filter);
 GEN_PMU_FORMAT_ATTR(min_latency);
+GEN_PMU_FORMAT_ATTR(discard);
 
 static struct attribute *arm_spe_pmu_formats_attr[] = {
 	&format_attr_ts_enable.attr,
@@ -228,9 +232,15 @@ static struct attribute *arm_spe_pmu_formats_attr[] = {
 	&format_attr_event_filter.attr,
 	&format_attr_inv_event_filter.attr,
 	&format_attr_min_latency.attr,
+	&format_attr_discard.attr,
 	NULL,
 };
 
+static bool discard_unsupported(struct arm_spe_pmu *spe_pmu)
+{
+	return spe_pmu->pmsver < ID_AA64DFR0_EL1_PMSVer_V1P2;
+}
+
 static umode_t arm_spe_pmu_format_attr_is_visible(struct kobject *kobj,
 						  struct attribute *attr,
 						  int unused)
@@ -238,6 +248,9 @@ static umode_t arm_spe_pmu_format_attr_is_visible(struct kobject *kobj,
 	struct device *dev = kobj_to_dev(kobj);
 	struct arm_spe_pmu *spe_pmu = dev_get_drvdata(dev);
 
+	if (attr == &format_attr_discard.attr && discard_unsupported(spe_pmu))
+		return 0;
+
 	if (attr == &format_attr_inv_event_filter.attr && !(spe_pmu->features & SPE_PMU_FEAT_INV_FILT_EVT))
 		return 0;
 
@@ -502,6 +515,12 @@ static void arm_spe_perf_aux_output_begin(struct perf_output_handle *handle,
 	u64 base, limit;
 	struct arm_spe_pmu_buf *buf;
 
+	if (ATTR_CFG_GET_FLD(&event->attr, discard)) {
+		limit = FIELD_PREP(PMBLIMITR_EL1_FM, PMBLIMITR_EL1_FM_DISCARD);
+		limit |= PMBLIMITR_EL1_E;
+		goto out_write_limit;
+	}
+
 	/* Start a new aux session */
 	buf = perf_aux_output_begin(handle, event);
 	if (!buf) {
@@ -743,6 +762,10 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
 	    !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT))
 		return -EOPNOTSUPP;
 
+	if (ATTR_CFG_GET_FLD(&event->attr, discard) &&
+	    discard_unsupported(spe_pmu))
+		return -EOPNOTSUPP;
+
 	set_spe_event_has_cx(event);
 	reg = arm_spe_event_to_pmscr(event);
 	if (reg & (PMSCR_EL1_PA | PMSCR_EL1_PCT))
-- 
2.34.1



From james.clark at linaro.org  Tue Dec 17 03:56:08 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 17 Dec 2024 11:56:08 +0000
Subject: [PATCH 5/5] perf docs: arm_spe: Document new discard mode
In-Reply-To: <20241217115610.371755-1-james.clark@linaro.org>
References: <20241217115610.371755-1-james.clark@linaro.org>
Message-ID: <20241217115610.371755-6-james.clark@linaro.org>

Document the flag, hint what it's used for and give an example with
other useful options to get minimal output.

Signed-off-by: James Clark <james.clark at linaro.org>
---
 tools/perf/Documentation/perf-arm-spe.txt | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/tools/perf/Documentation/perf-arm-spe.txt b/tools/perf/Documentation/perf-arm-spe.txt
index de2b0b479249..588eead438bc 100644
--- a/tools/perf/Documentation/perf-arm-spe.txt
+++ b/tools/perf/Documentation/perf-arm-spe.txt
@@ -150,6 +150,7 @@ arm_spe/load_filter=1,min_latency=10/'
   pct_enable=1        - collect physical timestamp instead of virtual timestamp (PMSCR.PCT) - requires privilege
   store_filter=1      - collect stores only (PMSFCR.ST)
   ts_enable=1         - enable timestamping with value of generic timer (PMSCR.TS)
+  discard=1           - enable SPE PMU events but don't collect sample data - see 'Discard mode' (PMBLIMITR.FM = DISCARD)
 
 +++*+++ Latency is the total latency from the point at which sampling started on that instruction, rather
 than only the execution latency.
@@ -220,6 +221,16 @@ Common errors
 
    Increase sampling interval (see above)
 
+Discard mode
+~~~~~~~~~~~~
+
+SPE PMU events can be used without the overhead of collecting sample data if
+discard mode is supported (optional from Armv8.6). First run a system wide SPE
+session (or on the core of interest) using options to minimize output. Then run
+perf stat:
+
+  perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
+  perf stat -e SAMPLE_FEED_LD
 
 SEE ALSO
 --------
-- 
2.34.1



From daniel at fooishbar.org  Tue Dec 17 04:07:54 2024
From: daniel at fooishbar.org (Daniel Stone)
Date: Tue, 17 Dec 2024 12:07:54 +0000
Subject: [PATCH v6 08/16] drm/rockchip: vop2: Support 32x8 superblock afbc
In-Reply-To: <165af58a.697.193d2100239.Coremail.andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com> <20241214081719.3330518-9-andyshrk@163.com>
 <CAPj87rOjqZdyht2y8MK7gVyk_eqEzk1Sy0DcxFtQRuhrHQ_oxA@mail.gmail.com> <165af58a.697.193d2100239.Coremail.andyshrk@163.com>
Message-ID: <CAPj87rMfFXkbyh7UEJQw4JV1R18KLXC3GyF0CznrN1k3UdL0Lw@mail.gmail.com>

Hi Andy,

On Tue, 17 Dec 2024 at 00:41, Andy Yan <andyshrk at 163.com> wrote:
> At 2024-12-16 21:06:07, "Daniel Stone" <daniel at fooishbar.org> wrote:
> >On Sat, 14 Dec 2024 at 08:18, Andy Yan <andyshrk at 163.com> wrote:
> >> This is the only afbc format supported by the upcoming
> >> VOP for rk3576.
> >>
> >> Add support for it.
> >
> >Out of interest, how was this tested? There is no 32x8 modifier in the
> >format list in format_modifiers_afbc[], so it seems like it shouldn't
> >be possible to get a 32x8 buffer on a plane at all.
>
> The 32x8 modifier  added in PATCH 16/16:
>
> +/* used from rk3576, afbc 32*8 half mode */
> +static const uint64_t format_modifiers_rk3576_afbc[] = {
> +       DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
> +                               AFBC_FORMAT_MOD_SPLIT),
> +

Hmmm, that's strange; I applied the whole series with b4 but wasn't
seeing that block defined. Maybe a bad conflict resolution. Sorry for
the confusion.

> I write an ovltest[0] tool which can take linear/AFBC rgb/yuv data from a file, then
> commit to drm driver, I use this tool for most basic format test.
>
> But when tested on weston, I found that weston does not use the AFBC format for display,
> don't know why.

You'll need a Mesa tree with e0f48568c7f2 included; if you have this
then it should just work out of the box.

Cheers,
Daniel


From dmitry.baryshkov at linaro.org  Tue Dec 17 04:10:13 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 14:10:13 +0200
Subject: [PATCH V4 4/5] soc: qcom: Introduce SCMI based Memlat (Memory
 Latency) governor
In-Reply-To: <d2d95756-c51d-17bb-ce12-d8ae390a3bac@quicinc.com>
References: <2aycrvnvivcrqctqmweadcgenwugafdr6ub3bzkscterpenz32@bzabln2hkral>
 <29eef87e-96f6-5105-6f7a-a8e01efcb4a3@quicinc.com>
 <k4lpzxtrq3x6riyv6etxiobn7nbpczf2bp3m4oc752nhjknlit@uo53kbppzim7>
 <ac655bdc-5ccf-c6c6-3203-659f1916c53c@quicinc.com>
 <34p27za5hcpubaxjuddsir2vqnqrvwyesnclu2cocvm3yhbv3r@ak7rcnp67gyd>
 <1f5258f4-7c20-5343-dec6-0847449c821b@quicinc.com>
 <CAA8EJpoN3QSi72UUDV+=YkqySgXkiODUFJvwpBYfSmnkSotuZA@mail.gmail.com>
 <4399f7da-9478-57c0-7405-e51dc35d90ba@quicinc.com>
 <uwwiz2o6brn5zczbpaiajdq7yva2qpcpgzwdr26lhg4jvlwvvj@w5bkiuhdalze>
 <d2d95756-c51d-17bb-ce12-d8ae390a3bac@quicinc.com>
Message-ID: <7xrvku7wfvrpxx6yvamn7so46k4dvezpebj7ctm56ufp5ajadi@jwzup6vkupvd>

On Tue, Dec 17, 2024 at 04:35:15PM +0530, Sibi Sankar wrote:
> 
> 
> On 12/17/24 16:16, Dmitry Baryshkov wrote:
> > On Tue, Dec 17, 2024 at 03:46:24PM +0530, Sibi Sankar wrote:
> > > 
> > > 
> > > On 12/5/24 17:00, Dmitry Baryshkov wrote:
> > > > On Thu, 5 Dec 2024 at 12:53, Sibi Sankar <quic_sibis at quicinc.com> wrote:
> > > > > 
> > > > > 
> > > > > 
> > > > > On 11/14/24 18:02, Dmitry Baryshkov wrote:
> > > > > > On Thu, Nov 14, 2024 at 09:43:53AM +0530, Sibi Sankar wrote:
> > > > > > > 
> > > > > > > 
> > > > > > > On 10/26/24 23:46, Dmitry Baryshkov wrote:
> > > > > > > > On Tue, Oct 22, 2024 at 01:48:25PM +0530, Sibi Sankar wrote:
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > On 10/7/24 23:27, Dmitry Baryshkov wrote:
> > > > > > > > > > On Mon, Oct 07, 2024 at 11:40:22AM GMT, Sibi Sankar wrote:
> > > > > > 
> > > > > > > > > > 
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +struct map_param_msg {
> > > > > > > > > > > +        u32 hw_type;
> > > > > > > > > > > +        u32 mon_idx;
> > > > > > > > > > > +        u32 nr_rows;
> > > > > > > > > > > +        struct map_table tbl[MAX_MAP_ENTRIES];
> > > > > > > > > > > +} __packed;
> > > > > > > > > > > +
> > > > > > > > > > > +struct node_msg {
> > > > > > > > > > > +        u32 cpumask;
> > > > > > > > > > > +        u32 hw_type;
> > > > > > > > > > > +        u32 mon_type;
> > > > > > > > > > > +        u32 mon_idx;
> > > > > > > > > > > +        char mon_name[MAX_NAME_LEN];
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +struct scalar_param_msg {
> > > > > > > > > > > +        u32 hw_type;
> > > > > > > > > > > +        u32 mon_idx;
> > > > > > > > > > > +        u32 val;
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +enum common_ev_idx {
> > > > > > > > > > > +        INST_IDX,
> > > > > > > > > > > +        CYC_IDX,
> > > > > > > > > > > +        CONST_CYC_IDX,
> > > > > > > > > > > +        FE_STALL_IDX,
> > > > > > > > > > > +        BE_STALL_IDX,
> > > > > > > > > > > +        NUM_COMMON_EVS
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +enum grp_ev_idx {
> > > > > > > > > > > +        MISS_IDX,
> > > > > > > > > > > +        WB_IDX,
> > > > > > > > > > > +        ACC_IDX,
> > > > > > > > > > > +        NUM_GRP_EVS
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +#define EV_CPU_CYCLES           0
> > > > > > > > > > > +#define EV_INST_RETIRED         2
> > > > > > > > > > > +#define EV_L2_D_RFILL           5
> > > > > > > > > > > +
> > > > > > > > > > > +struct ev_map_msg {
> > > > > > > > > > > +        u32 num_evs;
> > > > > > > > > > > +        u32 hw_type;
> > > > > > > > > > > +        u32 cid[NUM_COMMON_EVS];
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +struct cpufreq_memfreq_map {
> > > > > > > > > > > +        unsigned int cpufreq_mhz;
> > > > > > > > > > > +        unsigned int memfreq_khz;
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +struct scmi_monitor_info {
> > > > > > > > > > > +        struct cpufreq_memfreq_map *freq_map;
> > > > > > > > > > > +        char mon_name[MAX_NAME_LEN];
> > > > > > > > > > > +        u32 mon_idx;
> > > > > > > > > > > +        u32 mon_type;
> > > > > > > > > > > +        u32 ipm_ceil;
> > > > > > > > > > > +        u32 mask;
> > > > > > > > > > > +        u32 freq_map_len;
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +struct scmi_memory_info {
> > > > > > > > > > > +        struct scmi_monitor_info *monitor[MAX_MONITOR_CNT];
> > > > > > > > > > > +        u32 hw_type;
> > > > > > > > > > > +        int monitor_cnt;
> > > > > > > > > > > +        u32 min_freq;
> > > > > > > > > > > +        u32 max_freq;
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +struct scmi_memlat_info {
> > > > > > > > > > > +        struct scmi_protocol_handle *ph;
> > > > > > > > > > > +        const struct qcom_generic_ext_ops *ops;
> > > > > > > > > > > +        struct scmi_memory_info *memory[MAX_MEMORY_TYPES];
> > > > > > > > > > > +        u32 cluster_info[NR_CPUS];
> > > > > > > > > > > +        int memory_cnt;
> > > > > > > > > > > +};
> > > > > > > > > > > +
> > > > > > > > > > > +static int populate_cluster_info(u32 *cluster_info)
> > > > > > > > > > > +{
> > > > > > > > > > > +        char name[MAX_NAME_LEN];
> > > > > > > > > > > +        int i = 0;
> > > > > > > > > > > +
> > > > > > > > > > > +        struct device_node *cn __free(device_node) = of_find_node_by_path("/cpus");
> > > > > > > > > > > +        if (!cn)
> > > > > > > > > > > +                return -ENODEV;
> > > > > > > > > > > +
> > > > > > > > > > > +        struct device_node *map __free(device_node) = of_get_child_by_name(cn, "cpu-map");
> > > > > > > > > > > +        if (!map)
> > > > > > > > > > > +                return -ENODEV;
> > > > > > > > > > > +
> > > > > > > > > > > +        do {
> > > > > > > > > > > +                snprintf(name, sizeof(name), "cluster%d", i);
> > > > > > > > > > > +                struct device_node *c __free(device_node) = of_get_child_by_name(map, name);
> > > > > > > > > > > +                if (!c)
> > > > > > > > > > > +                        break;
> > > > > > > > > > > +
> > > > > > > > > > > +                *(cluster_info + i) = of_get_child_count(c);
> > > > > > > > > > > +                i++;
> > > > > > > > > > > +        } while (1);
> > > > > > > > > > 
> > > > > > > > > > Can you use existing API from drivers/base/arch_topology.c? If not, can
> > > > > > > > > > it be extended to support your usecase?
> > > > > > > > > 
> > > > > > > > > ack. But I'm pretty sure it's going to take a while for reaching such
> > > > > > > > > an agreement so I'll drop this feature during the next re-spin.
> > > > > > > > 
> > > > > > > > Why? What kind of API do you actually need? The arch_topology.c simply
> > > > > > > > exports a table of struct cpu_topology. Is it somehow different from
> > > > > > > > what you are parsing manually?
> > > > > > > 
> > > > > > > yup, we had to figure out the physical id of the cpu
> > > > > > > since cpus can be disabled by the bootloader using
> > > > > > > status = "failed" property and we have to pass this
> > > > > > > onto the cpucp memlat algorithm.
> > > > > > 
> > > > > > Isn't it equal to the index in the cpu_topology table?
> > > > > 
> > > > > from what I see cpu_topology indexes remain unpopulated
> > > > > for cpus that are disabled since get_cpu_for_node
> > > > > ignores those?
> > > > 
> > > > Why do you need cpu_topology for disabled aka non-existing CPU devices?
> > > 
> > > sorry was out sick couldn't back earlier. We need the know
> > > what cpus are disbled to pass on the correct mask of cpus
> > > enabled to the SCP.
> > 
> > Yes. So isn't it enough to know only the enabled CPUs?
> 
> yes just knowing the physical index of the enabled cpus
> should be enough.

Then exiting cpu_topology is enough for your case, isn't it?

-- 
With best wishes
Dmitry


From quic_sibis at quicinc.com  Tue Dec 17 04:25:35 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 17 Dec 2024 17:55:35 +0530
Subject: [PATCH V4 0/5] arm_scmi: vendors: Qualcomm Generic Vendor
 Extensions
In-Reply-To: <Z1HceQegfMl07qj_@bogus>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <ZytnRc94iKUfMYH0@hovoldconsulting.com> <ZyvLktLUZOGP-LH5@pluto>
 <Zy4qvedrmkRdPR3x@hovoldconsulting.com>
 <8d42682b-0fa7-3962-da12-728cfe64903b@quicinc.com>
 <Z0BC203BhGEmXcJi@hovoldconsulting.com> <Z1HceQegfMl07qj_@bogus>
Message-ID: <d313e40b-fa8f-a534-5037-98536ee25044@quicinc.com>



On 12/5/24 22:31, Sudeep Holla wrote:
> On Fri, Nov 22, 2024 at 09:37:47AM +0100, Johan Hovold wrote:
>> On Thu, Nov 14, 2024 at 09:52:12AM +0530, Sibi Sankar wrote:
>>> On 11/8/24 20:44, Johan Hovold wrote:
>>
>>>>> On Wed, Nov 06, 2024 at 01:55:33PM +0100, Johan Hovold wrote:
>>
>>>>>> Second, after loading the protocol and client drivers manually (in that
>>>>>> order, shouldn't the client driver pull in the protocol?), I got:
>>>>>>
>>>>>> 	scmi_module: Loaded SCMI Vendor Protocol 0x80 - Qualcomm  20000
>>>>>> 	arm-scmi arm-scmi.0.auto: QCOM Generic Vendor Version 1.0
>>>>>> 	scmi-qcom-generic-ext-memlat scmi_dev.5: error -EOPNOTSUPP: failed to configure common events
>>>>>> 	scmi-qcom-generic-ext-memlat scmi_dev.5: probe with driver scmi-qcom-generic-ext-memlat failed with error -95
>>>>>>
>>>>>> which seems to suggest that the firmware on my CRD does not support this
>>>>>> feature. Is that the way this should be interpreted? And does that mean
>>>>>> that non of the commercial laptops supports this either?
>>
>>>> Yeah, hopefully Sibi can shed some light on this. I'm using the DT
>>>> patch (5/5) from this series, which according to the commit message is
>>>> supposed to enable bus scaling on the x1e80100 platform. So I guess
>>>> something is missing in my firmware.
>>>
>>> Nah, it's probably just because of the algo string used.
>>> The past few series used caps MEMLAT string instead of
>>> memlat to pass the tuneables, looks like all the laptops
>>> havn't really switched to it yet. Will revert back to
>>> using to lower case memlat so that all devices are
>>> supported. Thanks for trying the series out!
>>
>> I have a Lenovo ThinkPad T14s set up now so I gave this series a spin
>> there too, and there I do *not* see the above mentioned -EOPNOSUPP error
>> and the memlat driver probes successfully.
>>
>> On the other hand, this series seems to have no effect on a kernel
>> compilation benchmark. Is that expected?
>>
> 
> Hijacking this thread to rant about state of firmware implementation on
> this platform that gives me zero confidence in merging any of these without
> examining each of the interface details in depth and at lengths.
> 

Hey Sudeep,

Thanks for taking time to review the series.

> Also I see the standard protocol like PERF seem to have so many issues which
> adds to my no confidence. I can't comment on that thread for specific reasons.

^^ is largely untrue, a lot of finger pointing and a gross
misrepresentation of reality :/

The only major problem that X1E perf protocol has is a firmware
crash in the LEVEL_GET regular message implementation. This
pretty much went unnoticed because of messaging in perf implementation
in kernel. Given the fastchannel implementation isn't mandatory
according to spec, the kernel clearly says it switches to
regular messaging when it clearly doesn't do that and uses
stale data structures instead. This ensured that level get regular
messaging never got tested.

We pretty much have been good upstream citizens, finding bugs and
sending fixes wherever we can. We clearly don't deserve such a hostile
stance.

> 
> I will briefly mention my suspicion here. This Lenovo ThinkPad T14s being
> primarily targeting other OS using ACPI might have just implemented what is
> required for ACPI CPPC which conveniently doesn't have to discover lot of
> fastchannel details since they are supplied in the tables straight away.
> But that also would mean it could be not fully compliant to SCMI spec.

Not fully compliant to the spec? I am pretty sure this series would
have been shot down completely and NAKd on the list by you if that
was the case lol.

-Sibi

> 
> Either we need to run some compliance test suite(which again may need more
> work as it is unfortunately make platform specific - referring to [1])
> or use the raw interface in the kernel and throw /dev/random at it and see
> how well it can cope up.
> 
> --
> Regards,
> Sudeep
> 
> [1] https://gitlab.arm.com/tests/scmi-tests (Not so great and needs platform
>       specific vectors to check compliance)


From dmitry.baryshkov at linaro.org  Tue Dec 17 04:31:47 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 14:31:47 +0200
Subject: [PATCH v6 03/10] drm/connector: implement generic HDMI codec
 helpers
In-Reply-To: <20241217-heretic-hopeful-jaguar-aeabec@houat>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-3-50dc145a9c06@linaro.org>
 <20241216-heretic-mackerel-of-wholeness-fcfed7@houat>
 <exocd3b65cy6cy5w47cwx3ykn54ncf34hwyj7ffihs5jjzean5@y677uywnlah2>
 <20241217-heretic-hopeful-jaguar-aeabec@houat>
Message-ID: <buem3nnscnyh7latovvnsbhp2ci6pbjpckfmrft2267afzwdwq@2roahluiow7t>

On Tue, Dec 17, 2024 at 08:43:10AM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Mon, Dec 16, 2024 at 07:47:32PM +0200, Dmitry Baryshkov wrote:
> > On Mon, Dec 16, 2024 at 06:04:41PM +0100, Maxime Ripard wrote:
> > > > +struct drm_connector_hdmi_codec_funcs {
> > > > +	/**
> > > > +	 * @audio_startup:
> > > > +	 *
> > > > +	 * Called when ASoC starts an audio stream setup. The
> > > > +	 * @hdmi_audio_startup is optional.
> > > > +	 *
> > > > +	 * Returns:
> > > > +	 * 0 on success, a negative error code otherwise
> > > > +	 */
> > > > +	int (*audio_startup)(struct drm_connector *connector);
> > > > +
> > > > +	/**
> > > > +	 * @prepare:
> > > > +	 * Configures HDMI-encoder for audio stream. Can be called
> > > > +	 * multiple times for each setup. Mandatory.
> > > > +	 *
> > > > +	 * Returns:
> > > > +	 * 0 on success, a negative error code otherwise
> > > > +	 */
> > > > +	int (*prepare)(struct drm_connector *connector,
> > > > +		       struct hdmi_codec_daifmt *fmt,
> > > > +		       struct hdmi_codec_params *hparms);
> > > 
> > > Missing newline
> > > 
> > > > +	/**
> > > > +	 * @audio_shutdown:
> > > > +	 *
> > > > +	 * Shut down the audio stream. Mandatory.
> > > > +	 *
> > > > +	 * Returns:
> > > > +	 * 0 on success, a negative error code otherwise
> > > > +	 */
> > > > +	void (*audio_shutdown)(struct drm_connector *connector);
> > > 
> > > And thus we can probably just call that one shutdown?
> > 
> > It should be called automatically by the sound system. I'd rather not
> > call items directly that we are not supposed to call.
> 
> I meant that with my suggestion to call the function
> drm_connector_hdmi_audio_init, that structure would be called
> drm_connector_hdmi_audio_funcs, and thus the audio prefix in
> audio_shutdown is redundant.

I see. I posted the next iteration already, but I'll try to remember
this change for the next iteration.

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Tue Dec 17 04:34:11 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 14:34:11 +0200
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <d64ff9f1525fe3563502e470b2a31303de08a7c6.camel@mediatek.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
 <803bc2bd802506635dfa9ea9b26a6ca40a7f4912.camel@mediatek.com>
 <e5788187-e894-4aab-a41e-a3d7a64762c6@collabora.com>
 <d64ff9f1525fe3563502e470b2a31303de08a7c6.camel@mediatek.com>
Message-ID: <fm5rbujzu5og25x3nnxnhabrf4mppyy4nakxrskqtug774llnm@j47ce2zz6xsx>

On Tue, Dec 17, 2024 at 06:40:11AM +0000, CK Hu (???) wrote:
> On Mon, 2024-12-16 at 12:04 +0100, AngeloGioacchino Del Regno wrote:
> > External email : Please do not click links or open attachments until you have verified the sender or the content.
> > 
> > 
> > Il 16/12/24 09:57, CK Hu (???) ha scritto:
> > > Hi, Angelo:
> > > 
> > > On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
> > > > External email : Please do not click links or open attachments until you have verified the sender or the content.
> > > > 
> > > > 
> > > > Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
> > > > found in MediaTek's MT8195, MT8188 SoC and their variants, and
> > > > including support for display modes up to 4k60 and for HDMI
> > > > Audio, as per the HDMI 2.0 spec.
> > > > 
> > > > HDCP and CEC functionalities are also supported by this hardware,
> > > > but are not included in this commit and that also poses a slight
> > > > difference between the V2 and V1 controllers in how they handle
> > > > Hotplug Detection (HPD).
> > > > 
> > > > While the v1 controller was using the CEC controller to check
> > > > HDMI cable connection and disconnection, in this driver the v2
> > > > one does not.
> > > > 
> > > > This is due to the fact that on parts with v2 designs, like the
> > > > MT8195 SoC, there is one CEC controller shared between the HDMI
> > > > Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
> > > > adding support to use the CEC HW to wake up the HDMI controllers
> > > > it is necessary to have support for one TX, one RX *and* for both
> > > > at the same time.
> > > > 
> > > > Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > > > ---
> > > 
> > > [snip]
> > > 
> > > > +static int mtk_hdmi_v2_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)
> > > > +{
> > > 
> > > I would like v1 and v2 has the same behavior.
> > > Why v2 has atomic check but v1 has no?
> > > If this is better to have, add atomic check to v1, and this function would be common function.
> > > 
> > 
> > That's because v2 uses the new helpers, while v1 does not.
> > The v1 must be converted to the new helpers in order to use atomic_check() like v2.
> 
> I just find the description here, and I don't know why new helper need atomic_check().
> Would you provide more information how new helper need atomic_check()?

The HDMI helpers requires the driver to use
drm_atomic_helper_connector_hdmi_check() in order to maintain
HDMI-specific connector and CRTC state. Thus drivers using HDMI
Connector framework have to provide .atomic_check() callback which calls
the mentioned function.

> For example, the call stack to atomic_check(). (You could use dump_stack() to show it)

-- 
With best wishes
Dmitry


From didi.debian at cknow.org  Tue Dec 17 04:36:29 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Tue, 17 Dec 2024 13:36:29 +0100
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <D6DZB443IQ7A.3P1135M6DMF2S@cknow.org>

On Tue Dec 17, 2024 at 1:40 AM CET, Dmitry Baryshkov wrote:
> This series depends on the ELD mutex series [1]
>
> [1] https://lore.kernel.org/r/20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03 at linaro.org

There's a v2 of that patch series here:
https://lore.kernel.org/all/20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea at linaro.org/

HTH,
  Diederik
-------------- 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/20241217/f555613e/attachment.sig>

From robh at kernel.org  Tue Dec 17 04:43:16 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Dec 2024 06:43:16 -0600
Subject: [PATCH v2] dt-bindings: mmc: atmel,hsmci: Convert to json schema
In-Reply-To: <20241209-hsmci-v2-1-b5a6d7c59b67@microchip.com>
References: <20241209-hsmci-v2-1-b5a6d7c59b67@microchip.com>
Message-ID: <20241217124316.GA1136537-robh@kernel.org>

On Mon, Dec 09, 2024 at 10:02:30AM +0530, Dharma Balasubiramani wrote:
> Convert atmel,hsmci documentation to yaml format. The new file will inherit
> from mmc-controller.yaml.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> ---
> Changes in v2:
> - Drop the duplicate properties in the slot node.
> - Link to v1: https://lore.kernel.org/r/20241205-hsmci-v1-1-5a25e622dfed at microchip.com
> ---
>  .../devicetree/bindings/mmc/atmel,hsmci.yaml       | 110 +++++++++++++++++++++
>  .../devicetree/bindings/mmc/atmel-hsmci.txt        |  73 --------------
>  2 files changed, 110 insertions(+), 73 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml b/Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml
> new file mode 100644
> index 000000000000..26686ada6288
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml
> @@ -0,0 +1,110 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mmc/atmel,hsmci.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Atmel High-Speed MultiMedia Card Interface (HSMCI)
> +
> +description:
> +  The Atmel HSMCI controller provides an interface for MMC, SD, and SDIO memory
> +  cards.
> +
> +maintainers:
> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
> +  - Aubin Constans <aubin.constans at microchip.com>
> +
> +allOf:
> +  - $ref: mmc-controller.yaml
> +
> +properties:
> +  compatible:
> +    const: atmel,hsmci
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  dmas:
> +    maxItems: 1
> +
> +  dma-names:
> +    const: rxtx
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    const: mci_clk
> +
> +  "#address-cells":
> +    const: 1
> +    description: Used for slot IDs.
> +
> +  "#size-cells":
> +    const: 0
> +
> +patternProperties:
> +  "^slot@[0-9]+$":
> +    type: object
> +    description: A slot node representing an MMC, SD, or SDIO slot.

There's a schema for slots now queued for 6.14[1]. You should use that. 
One issue is 'compatible' is required. Either that would have to be 
dropped as required or you could just add it in your .dts files.

Rob


From peng.fan at nxp.com  Tue Dec 17 04:48:38 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Tue, 17 Dec 2024 12:48:38 +0000
Subject: [PATCH V2] soc: imx8m: Add remove function
In-Reply-To: <20241217104634.2fc7yo6hprhx2wnt@pengutronix.de>
References: <20241217015826.1374497-1-peng.fan@oss.nxp.com>
 <20241217082637.i2ou6bbr3tc3uvof@pengutronix.de>
 <PAXPR04MB8459A91EEC932F41E24AE04488042@PAXPR04MB8459.eurprd04.prod.outlook.com>
 <20241217104634.2fc7yo6hprhx2wnt@pengutronix.de>
Message-ID: <PAXPR04MB84594B482B89EE34A900A53E88042@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH V2] soc: imx8m: Add remove function
> 
> On 24-12-17, Peng Fan wrote:
> > > Subject: Re: [PATCH V2] soc: imx8m: Add remove function
> > >
> > > Hi Peng,
> > >
> > > thanks for you patch.
> > >
> > > On 24-12-17, Peng Fan (OSS) wrote:
> > > > From: Peng Fan <peng.fan at nxp.com>
> > > >
> > > > Unregister the cpufreq device and soc device in remove path,
> > > otherwise
> > >
> > > After reconsidiering the patch approach, I think we shouldn't add a
> > > .remove() function and instead should make use of the
> > > devm_add_action() mechanism for the proper unregister calls.
> >
> > Would you please share why devm_add_action is preferred?
> >
> > Something as below?
> > +static void imx8m_soc_remove(void *data) {
> > +       struct imx8m_soc_priv *priv = data;
> > +
> > +       if (priv->cpufreq_dev)
> > +               platform_device_unregister(priv->cpufreq_dev);
> > +
> > +       soc_device_unregister(priv->soc_dev);
> > +}
> 
> I would split it into two action functions due to the following reasons:
>  - cleanup during the probe() if something fails afterwards
>  - no need for the if(priv->cpufreq_dev) check.
> 
> > In Probe:
> > +       return devm_add_action(&pdev->dev, imx8m_soc_remove,
> priv);
> 
> The actions should be added directly after the succeful device
> registration, e.g.
>  - after soc_device_register(soc_dev_attr) and
>  - after platform_device_register_simple()

With two devm_add_action, I thought below code would work,
devm_add_action(dev, soc_device_unregister, (void *)soc_dev);
devm_add_action(dev, platform_device_unregister, (void *)cpufreq_dev);

But devm_add_action expects: void (*action)(void *),
So I need introduce two functions to wrap soc_device_unregister,
and platform_device_unregister.

This seems not good. Using one devm_add_action just need
one wrap function, comments?

Thanks,
Peng.

> 
> Regards,
>    Marco
> 
> >
> > Regards,
> > Peng.
> >
> > >
> > > > there will be warning when do removing test:
> > > > sysfs: cannot create duplicate filename '/devices/platform/imx-
> > > cpufreq-dt'
> > > > CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted
> > > > 6.13.0-rc1-next-20241204 Hardware name: NXP i.MX8MPlus EVK
> > > board (DT)
> > > >
> > > > Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as
> platform
> > > > driver")
> > > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > > ---
> > > >
> > > > V2:
> > > >  Add err check when create the cpufreq platform device
> > >
> > > thank you for addressing this.
> > >
> > > Regards,
> > >   Marco
> > >
> > > >  drivers/soc/imx/soc-imx8m.c | 41
> > > > +++++++++++++++++++++++++++++++------
> > > >  1 file changed, 35 insertions(+), 6 deletions(-)
> > > >
> > > > diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-
> > > imx8m.c
> > > > index 8ac7658e3d52..97c8718c2aa1 100644
> > > > --- a/drivers/soc/imx/soc-imx8m.c
> > > > +++ b/drivers/soc/imx/soc-imx8m.c
> > > > @@ -33,6 +33,11 @@ struct imx8_soc_data {
> > > >  	int (*soc_revision)(u32 *socrev, u64 *socuid);  };
> > > >
> > > > +struct imx8m_soc_priv {
> > > > +	struct soc_device *soc_dev;
> > > > +	struct platform_device *cpufreq_dev; };
> > > > +
> > > >  #ifdef CONFIG_HAVE_ARM_SMCCC
> > > >  static u32 imx8mq_soc_revision_from_atf(void)
> > > >  {
> > > > @@ -195,10 +200,11 @@ static __maybe_unused const struct
> > > of_device_id
> > > > imx8_soc_match[] = {  static int imx8m_soc_probe(struct
> > > > platform_device *pdev)  {
> > > >  	struct soc_device_attribute *soc_dev_attr;
> > > > +	struct platform_device *cpufreq_dev;
> > > >  	const struct imx8_soc_data *data;
> > > >  	struct device *dev = &pdev->dev;
> > > >  	const struct of_device_id *id;
> > > > -	struct soc_device *soc_dev;
> > > > +	struct imx8m_soc_priv *priv;
> > > >  	u32 soc_rev = 0;
> > > >  	u64 soc_uid = 0;
> > > >  	int ret;
> > > > @@ -207,6 +213,10 @@ static int imx8m_soc_probe(struct
> > > platform_device *pdev)
> > > >  	if (!soc_dev_attr)
> > > >  		return -ENOMEM;
> > > >
> > > > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > > > +	if (!priv)
> > > > +		return -ENOMEM;
> > > > +
> > > >  	soc_dev_attr->family = "Freescale i.MX";
> > > >
> > > >  	ret = of_property_read_string(of_root, "model",
> > > > &soc_dev_attr->machine); @@ -235,21 +245,40 @@ static int
> > > imx8m_soc_probe(struct platform_device *pdev)
> > > >  	if (!soc_dev_attr->serial_number)
> > > >  		return -ENOMEM;
> > > >
> > > > -	soc_dev = soc_device_register(soc_dev_attr);
> > > > -	if (IS_ERR(soc_dev))
> > > > -		return PTR_ERR(soc_dev);
> > > > +	priv->soc_dev = soc_device_register(soc_dev_attr);
> > > > +	if (IS_ERR(priv->soc_dev))
> > > > +		return PTR_ERR(priv->soc_dev);
> > > >
> > > >  	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
> > > >  		soc_dev_attr->revision);
> > > >
> > > > -	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
> > > > -		platform_device_register_simple("imx-cpufreq-dt", -1,
> > > NULL, 0);
> > > > +	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) {
> > > > +		cpufreq_dev = platform_device_register_simple("imx-
> > > cpufreq-dt", -1, NULL, 0);
> > > > +		if (!IS_ERR(cpufreq_dev))
> > > > +			priv->cpufreq_dev = cpufreq_dev;
> > > > +		else
> > > > +			dev_err(dev, "Failed to create imx-cpufreq-
> > > dev device: %ld",
> > > > +				PTR_ERR(cpufreq_dev));
> > > > +	}
> > > > +
> > > > +	platform_set_drvdata(pdev, priv);
> > > >
> > > >  	return 0;
> > > >  }
> > > >
> > > > +static void imx8m_soc_remove(struct platform_device *pdev) {
> > > > +	struct imx8m_soc_priv *priv = platform_get_drvdata(pdev);
> > > > +
> > > > +	if (priv->cpufreq_dev)
> > > > +		platform_device_unregister(priv->cpufreq_dev);
> > > > +
> > > > +	soc_device_unregister(priv->soc_dev);
> > > > +}
> > > > +
> > > >  static struct platform_driver imx8m_soc_driver = {
> > > >  	.probe = imx8m_soc_probe,
> > > > +	.remove	= imx8m_soc_remove,
> > > >  	.driver = {
> > > >  		.name = "imx8m-soc",
> > > >  	},
> > > > --
> > > > 2.37.1
> > > >
> > > >
> > > >
> >


From mripard at redhat.com  Tue Dec 17 04:47:53 2024
From: mripard at redhat.com (Maxime Ripard)
Date: Tue, 17 Dec 2024 13:47:53 +0100
Subject: [PATCH 4/5] clk: Add flag to prevent frequency changes when
 walking subtrees
In-Reply-To: <20241121-ge-ian-debug-imx8-clk-tree-v1-4-0f1b722588fe@bootlin.com>
References: <20241121-ge-ian-debug-imx8-clk-tree-v1-0-0f1b722588fe@bootlin.com>
 <20241121-ge-ian-debug-imx8-clk-tree-v1-4-0f1b722588fe@bootlin.com>
Message-ID: <20241217-brown-wapiti-of-promotion-e3bec6@houat>

On Thu, Nov 21, 2024 at 06:41:14PM +0100, Miquel Raynal wrote:
> There are mainly two ways to change a clock frequency.

There's much more than that :)

Off the top of my head, setting/clearing a min/max rate and changing the
parent might also result in a rate change.

And then, the firmware might get involved too.

> The active way requires calling ->set_rate() in order to ask "on
> purpose" for a frequency change. Otherwise, a clock can passively see
> its frequency being updated depending on upstream clock frequency
> changes. In most cases it is fine to just accept the new upstream
> frequency - which by definition will have an impact on downstream
> frequencies if we do not recalculate internal divisors. But there are
> cases where, upon an upstream frequency change, we would like to
> maintain a specific rate.

Why is clk_set_rate_exclusive not enough?

> As an example, on iMX8MP the video pipeline clocks are looking like this:
> 
>     video_pll1
>        video_pll1_bypass
>           video_pll1_out
>              media_ldb
>                 media_ldb_root_clk
>              media_disp2_pix
>                 media_disp2_pix_root_clk
>              media_disp1_pix
>                 media_disp1_pix_root_clk
> 
> media_ldb, media_disp2_pix and media_disp1_pix are simple divisors from
> which we might require 2 or 3 different rates, whereas video_pll1 is a
> very configurable PLL which can achieve almost any frequency. There are
> however relationships between them, typically the ldb clock must be 3.5
> or 7 times higher than the media_disp* clocks.
> 
> Currently, if eg. media_disp2_pix is set to 71900000Hz, when media_ldb
> is (later) set to 503300000Hz, media_disp2_pix is updated to 503300000Hz
> as well, which clearly does not make sense. We want it to stay at
> 71900000Hz during the subtree walk.
> 
> Achieving this is the purpose of the new clock flag:
> CLK_NO_RATE_CHANGE_DURING_PROPAGATION
> 
> Please note, if the kernel was setting the ldb clock before a pixel
> clock, the result would be different, and this is also what this patch
> is trying to solve.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
> ---
> In all cases, the LDB must be aware of the device configuration, and ask
> for a clever frequency, we will never cope with slightly aware drivers
> when addressing this kind of subtle situation.
> ---
>  drivers/clk/clk.c            | 9 +++++++--
>  include/linux/clk-provider.h | 2 ++
>  2 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index adfc5bfb93b5a65b6f58c52ca2c432d651f7dd7d..94d93470479e77769e63e97462b176261103b552 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -1927,7 +1927,6 @@ long clk_get_accuracy(struct clk *clk)
>  }
>  EXPORT_SYMBOL_GPL(clk_get_accuracy);
>  
> -__maybe_unused
>  static unsigned long clk_determine(struct clk_core *core, unsigned long rate)
>  {
>  	struct clk_rate_request req = {};
> @@ -2272,7 +2271,13 @@ static void clk_calc_subtree(struct clk_core *core)
>  {
>  	struct clk_core *child;
>  
> -	core->new_rate = clk_recalc(core, core->parent->new_rate);
> +	if (core->flags & CLK_NO_RATE_CHANGE_DURING_PROPAGATION) {
> +		core->new_rate = clk_determine(core, core->rate);
> +		if (!core->new_rate)
> +			core->new_rate = clk_recalc(core, core->parent->new_rate);
> +	} else {
> +		core->new_rate = clk_recalc(core, core->parent->new_rate);
> +	}

Sorry, it's not clear to me how it works. How will the parent clocks
will get notified to adjust their dividers in that scenario? Also, what
if they can't?

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

From krzk at kernel.org  Tue Dec 17 04:51:54 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 13:51:54 +0100
Subject: [PATCH v12 2/8] dt-bindings: media: platform: visconti: Add
 Toshiba Visconti Video Input Interface
In-Reply-To: <20241217094508.GD11445@pendragon.ideasonboard.com>
References: <20241125092146.1561901-1-yuji2.ishikawa@toshiba.co.jp>
 <20241125092146.1561901-3-yuji2.ishikawa@toshiba.co.jp>
 <04a7ebf7-2924-4894-bc53-ba77e2f64fae@kernel.org>
 <TY3PR01MB99822E6161ED319B4DE855B492042@TY3PR01MB9982.jpnprd01.prod.outlook.com>
 <d5294015-4790-490e-8136-615039a5c733@kernel.org>
 <20241217094508.GD11445@pendragon.ideasonboard.com>
Message-ID: <7e50e257-9e13-4d32-8de9-8deb53fd30e4@kernel.org>

On 17/12/2024 10:45, Laurent Pinchart wrote:
> On Tue, Dec 17, 2024 at 06:43:22AM +0100, Krzysztof Kozlowski wrote:
>> On 17/12/2024 01:00, yuji2.ishikawa at toshiba.co.jp wrote:
>>> Hello Krzysztof
>>>
>>> Thank you for your review
>>>
>>>> -----Original Message-----
>>>> From: Krzysztof Kozlowski <krzk at kernel.org>
>>>> Sent: Monday, November 25, 2024 7:08 PM
>>>> To: ishikawa yuji(?? ?? ?????????????)
>>>> <yuji2.ishikawa at toshiba.co.jp>; Laurent Pinchart
>>>> <laurent.pinchart at ideasonboard.com>; Mauro Carvalho Chehab
>>>> <mchehab at kernel.org>; Rob Herring <robh at kernel.org>; Krzysztof Kozlowski
>>>> <krzk+dt at kernel.org>; Conor Dooley <conor+dt at kernel.org>; Sakari Ailus
>>>> <sakari.ailus at linux.intel.com>; Hans Verkuil <hverkuil-cisco at xs4all.nl>;
>>>> iwamatsu nobuhiro(?? ?? ?????????????)
>>>> <nobuhiro1.iwamatsu at toshiba.co.jp>
>>>> Cc: linux-media at vger.kernel.org; linux-kernel at vger.kernel.org;
>>>> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org
>>>> Subject: Re: [PATCH v12 2/8] dt-bindings: media: platform: visconti: Add
>>>> Toshiba Visconti Video Input Interface
>>>>
>>>> On 25/11/2024 10:21, Yuji Ishikawa wrote:
>>>>> Adds the Device Tree binding documentation that allows to describe the
>>>>> Video Input Interface found in Toshiba Visconti SoCs.
>>>>>
>>>>> Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
>>>>> Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
>>>>
>>>> Why this tag stayed and other was removed? What was the reason of tag
>>>> removal?
>>>>
>>>
>>> The stayed tag is due to internal review.
>>
>> Did the internal review really happened? How is it that immediately new
>> version has internal review without any traces?
>>
>> I have doubts this review happened in the context of reviewer's
>> statement of oversight.
>>
>>> The removed tag is due to code's change (split of csi2rx part) after the last review.
>>> If the code is largely changed following the instruction of another reviewer
>>> after obtaining the tags, how should the tags be handled?
>>
>> Drop all reviews and perform reviews on the list.
>>
>> Such internal review appearing afterwards is rather a proof it you are
>> adding just the tags to satisfy your process. I have no way to even
>> verify whether that person performed any reasonable review or maybe just
>> acked your patch.
> 
> How do you verify that for public reviews ?

By quality or amount of comments. Or timing. Or reviewing cover letter
without any feedback on individual patches.

There are many, many ways. Considering how many companies were adding
fake manager-review-tags in the past (or fake SoBs), I am pretty picky
on that.

Best regards,
Krzysztof


From mripard at redhat.com  Tue Dec 17 04:54:07 2024
From: mripard at redhat.com (Maxime Ripard)
Date: Tue, 17 Dec 2024 13:54:07 +0100
Subject: [PATCH 0/5] clk: Fix simple video pipelines on i.MX8
In-Reply-To: <87zflrpp8w.fsf@bootlin.com>
References: <20241121-ge-ian-debug-imx8-clk-tree-v1-0-0f1b722588fe@bootlin.com>
 <b98fdf46-3d09-4693-86fe-954fc723e3a6@nxp.com>
 <87zflrpp8w.fsf@bootlin.com>
Message-ID: <20241217-didactic-hedgehog-from-heaven-004c37@houat>

On Fri, Nov 22, 2024 at 10:54:55AM +0100, Miquel Raynal wrote:
> Hello Liu,
> 
> Thanks for the feedback!
> 
> On 22/11/2024 at 14:01:49 +08, Liu Ying <victor.liu at nxp.com> wrote:
> 
> > Hi Miquel,
> >
> > On 11/22/2024, Miquel Raynal wrote:
> >> Recent changes in the clock tree have set CLK_SET_RATE_PARENT to the two
> >> LCDIF pixel clocks. The idea is, instead of using assigned-clock
> >> properties to set upstream PLL rates to high frequencies and hoping that
> >> a single divisor (namely media_disp[12]_pix) will be close enough in
> >> most cases, we should tell the clock core to use the PLL to properly
> >> derive an accurate pixel clock rate in the first place. Here is the
> >> situation.
> >> 
> >> [Before ff06ea04e4cf ("clk: imx: clk-imx8mp: Allow media_disp pixel clock reconfigure parent rate")]
> >> 
> >> Before setting CLK_SET_RATE_PARENT to the media_disp[12]_pix clocks, the sequence of events was:
> >> - PLL is assigned to a high rate,
> >> - media_disp[12]_pix is set to approximately freq A by using a single divisor,
> >> - media_ldb is set to approximately freq 7*A by using another single divisor.
> >> => The display was working, but the pixel clock was inaccurate.
> >> 
> >> [After ff06ea04e4cf ("clk: imx: clk-imx8mp: Allow media_disp pixel clock reconfigure parent rate")]
> >> 
> >> After setting CLK_SET_RATE_PARENT to the media_disp[12]_pix clocks, the
> >> sequence of events became:
> >> - media_disp[12]_pix is set to freq A by using a divisor of 1 and
> >>   setting video_pll1 to freq A.
> >> - media_ldb is trying to compute its divisor to set freq 7*A, but the
> >>   upstream PLL is to low, it does not recompute it, so it ends up
> >>   setting a divisor of 1 and being at freq A instead of 7*A.
> >> => The display is sadly no longer working
> >> 
> >> [After applying PATCH "clk: imx: clk-imx8mp: Allow LDB serializer clock reconfigure parent rate"]
> >> 
> >> This is a commit from Marek, which is, I believe going in the right
> >> direction, so I am including it. Just with this change, the situation is
> >> slightly different, but the result is the same:
> >> - media_disp[12]_pix is set to freq A by using a divisor of 1 and
> >>   setting video_pll1 to freq A.
> >> - media_ldb is set to 7*A by using a divisor of 1 and setting video_pll1
> >>   to freq 7*A.
> >>   /!\ This as the side effect of changing media_disp[12]_pix from freq A
> >>   to freq 7*A.
> >
> > Although I'm not of a fan of setting CLK_SET_RATE_PARENT flag to the
> > LDB clock and pixel clocks,
> 
> I haven't commented much on this. For me, inaccurate pixel clocks mostly
> work fine (if not too inaccurate), but it is true that having very
> powerful PLL like the PLL1443, it is a pity not to use them at their
> highest capabilities. However, I consider "not breaking users" more
> important than having "perfect clock rates".

Whether an inaccurate clock "works" depends on the context. A .5%
deviation will be out of spec for HDMI for example. An inaccurate VBLANK
frequency might also break some use cases.

So that your display still works is not enough to prove it works.

> This series has one unique goal: accepting more accurate frequencies
> *and* not breaking users in the most simplest cases.
> 
> > would it work if the pixel clock rate is
> > set after the LDB clock rate is set in fsl_ldb_atomic_enable()?
> 
> The situation would be:
> - media_ldb is set to 7*A by using a divisor of 1 and setting video_pll1
>   to freq 7*A.
> - media_disp[12]_pix is set to freq A by using a divisor of 7.
> 
> So yes, and the explanation of why is there:
> https://elixir.bootlin.com/linux/v6.11.8/source/drivers/clk/clk-divider.c#L322
> 
> > The
> > pixel clock can be got from LDB's remote input LCDIF DT node by
> > calling of_clk_get_by_name() in fsl_ldb_probe() like the below patch
> > does. Similar to setting pixel clock rate, I think a chance is that
> > pixel clock enablement can be moved from LCDIF driver to
> > fsl_ldb_atomic_enable() to avoid on-the-fly division ratio change.
> 
> TBH, this sounds like a hack and is no longer required with this series.
> 
> You are just trying to circumvent the fact that until now, applying a
> rate in an upper clock would unconfigure the downstream rates, and I
> think this is our first real problem.
> 
> > https://patchwork.kernel.org/project/linux-clk/patch/20241114065759.3341908-6-victor.liu at nxp.com/
> >
> > Actually, one sibling patch of the above patch reverts ff06ea04e4cf
> > because I thought "fixed PLL rate" is the only solution, though I'm
> > discussing any alternative solution of "dynamically changeable PLL
> > rate" with Marek in the thread of the sibling patch.
> 
> I don't think we want fixed PLL rates. Especially if you start using
> external (hot-pluggable) displays with different needs: it just does not
> fly. There is one situation that cannot yet be handled and needs
> manual reparenting: using 3 displays with a non-divisible pixel
> frequency.

Funnily, external interfaces (ie, HDMI, DP) tend to be easier to work
with than panels. HDMI for example works with roughly three frequencies:
148.5MHz, 297MHz and 594MHz. If you set the PLL to 594MHz and the
downstream clock has a basic divider, it works just fine.

> FYI we managed this specific "advanced" case with assigned-clock-parents
> using an audio PLL as hinted by Marek. It mostly works, event though the
> PLL1416 are less precise and offer less accurate pixel clocks.

Note that assigned-clock-parents doesn't provide any guarantee on
whether the parent will change in the future or not. It's strictly
equivalent to calling clk_set_parent in the driver's probe.

> > BTW, as you know the LDB clock rate is 3.5x faster than the pixel
> > clock rate in dual-link LVDS use cases, the lowest PLL rate needs to
> > be explicitly set to 7x faster than the pixel clock rate *before*
> > LDB clock rate is set.  This way, the pixel clock would be derived
> > from the PLL with integer division ratio = 7, not the unsupported
> > 3.5.
> >
> > pixel    LDB         PLL
> > A        3.5*A       7*A      --> OK
> > A        3.5*A       3.5*A    --> not OK
> 
> This series was mostly solving the simpler case, with one display, but I
> agree we should probably also consider the dual case.
> 
> The situation here is that you require the LDB to be aware of some
> clocks constraints, like the fact that the downstream pixel clocks only
> feature simple dividors which cannot achieve a 3.5 rate. That is all.
> 
> It is clearly the LDB driver duty to make this feasible. I cannot test
> the dual case so I didn't brought any solution to it in this series, but
> I already had a solution in mind. Please find a patch below, it is very
> simple, and should, in conjunction with this series, fix the dual case
> as well.
> 
> FYI here is the final clock tree with this trick "manually" enabled. You
> can see video_pll1 is now twice media_ldb, and media ldb is still 7
> times media_disp[12]_pix (video_pll1 is assigned in DT to 1039500000, so
> it has effectively been reconfigured).
> 
>        video_pll1                            1   1   0   1006600000
>           video_pll1_bypass                  1   1   0   1006600000
>              video_pll1_out                  2   2   0   1006600000
>                 media_ldb                    1   1   0    503300000
>                    media_ldb_root_clk        1   1   0    503300000
>                 media_disp2_pix              1   1   0     71900000
>                    media_disp2_pix_root_clk  1   1   0     71900000
>                 media_disp1_pix              0   0   0     71900000
>                    media_disp1_pix_root_clk  0   0   0     71900000
> 
> ---8<---
> Author: Miquel Raynal <miquel.raynal at bootlin.com>
> 
>     drm: bridge: ldb: Make sure the upper PLL is compatible with dual output
>     
>     The i.MX8 display pipeline has a number of clock constraints, among which:
>     - The bridge clock must be 7 times faster than the pixel clock in single mode
>     - The bridge clock must be 3.5 times faster than the pixel clocks in dual mode
>     While a ratio of 7 is easy to build with simple divisors, 3.5 is not
>     achievable. In order to make sure we keep these clock ratios correct is
>     to configure the upper clock (usually video_pll1, but that does not
>     matter really) to twice it's usual value. This way, the bridge clock is
>     configured to divide the upstream rate by 2, and the pixel clocks are
>     configured to divide the upstream rate by 7, achieving a final 3.5 ratio
>     between the two.
>     
>     Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
> 
> diff --git a/drivers/gpu/drm/bridge/fsl-ldb.c b/drivers/gpu/drm/bridge/fsl-ldb.c
> index 81ff4e5f52fa..069c960ee56b 100644
> --- a/drivers/gpu/drm/bridge/fsl-ldb.c
> +++ b/drivers/gpu/drm/bridge/fsl-ldb.c
> @@ -177,6 +177,17 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
>         mode = &crtc_state->adjusted_mode;
>  
>         requested_link_freq = fsl_ldb_link_frequency(fsl_ldb, mode->clock);
> +       /*
> +        * Dual cases require a 3.5 rate division on the pixel clocks, which
> +        * cannot be achieved with regular single divisors. Instead, double the
> +        * parent PLL rate in the first place. In order to do that, we first
> +        * require twice the target clock rate, which will program the upper
> +        * PLL. Then, we ask for the actual targeted rate, which can be achieved
> +        * by dividing by 2 the already configured upper PLL rate, without
> +        * making further changes to it.
> +        */
> +       if (fsl_ldb_is_dual(fsl_ldb))
> +               clk_set_rate(fsl_ldb->clk, requested_link_freq * 2);
>         clk_set_rate(fsl_ldb->clk, requested_link_freq);

This has nothing to do in a DRM driver. The clock driver logic needs to handle it.

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

From maxime.chevallier at bootlin.com  Tue Dec 17 04:59:32 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 17 Dec 2024 13:59:32 +0100
Subject: [PATCH net-next 2/2] net: stmmac: dwmac-socfpga: Set interface
 modes from Lynx PCS as supported
In-Reply-To: <20241216173333.55e35f34@kernel.org>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
	<20241213090526.71516-3-maxime.chevallier@bootlin.com>
	<Z1wnFXlgEU84VX8F@shell.armlinux.org.uk>
	<20241213182904.55eb2504@fedora.home>
	<Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
	<20241216094224.199e8df7@fedora.home>
	<20241216173333.55e35f34@kernel.org>
Message-ID: <20241217135932.60711288@fedora.home>

Hi Jakub,

On Mon, 16 Dec 2024 17:33:33 -0800
Jakub Kicinski <kuba at kernel.org> wrote:

> On Mon, 16 Dec 2024 09:42:24 +0100 Maxime Chevallier wrote:
> > > I've actually already created that series!    
> > 
> > Woaw that was fast ! I'll review and give it a test on my setup then.
> > 
> > Maybe one thing to clarify with the net maintainers is that this work
> > you've done doesn't replace the series this thread is replying to,
> > which still makes sense (we need the
> > stmmac_priv->phylink_config.supported_interfaces to be correctly
> > populated on socfpga).  
> 
> Ah, sorry. Should have asked. 
> 
> I assumed since Lynx PCS will have the SGMII and 1000BASEX set -
> Russell's patch 5 will copy them for you to
> priv->phylink_config.supported_interfaces. Your patch 1 is still needed.
> Did I get it wrong?

Both are needed actually :) There are 2 issues on socfpga :

 - 1000BaseX needs to be understood by the socfpga wrapper
(dwmac-socfpga) so that the internal serdes is enabled in the wrapper,
that would be patch 1

- The priv->phylink_config.supported_interfaces is incomplete on
dwmac-socfpga. Russell's patch 5 intersects these modes with that the
PCS supports :

+		phy_interface_or(priv->phylink_config.supported_interfaces,
+				 priv->phylink_config.supported_interfaces,
+				 pcs->supported_interfaces);

So without patch 2 in the series, we'll be missing
PHY_INTERFACE_MODE_1000BASEX in the end result :)

Thanks,

Maxime


From linus.walleij at linaro.org  Tue Dec 17 05:00:35 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Dec 2024 14:00:35 +0100
Subject: [PATCH v5 02/10] dt-bindings: pinctrl: Add RaspberryPi RP1
 gpio/pinctrl/pinmux bindings
In-Reply-To: <42e09506979d878547d1140d7f6bf68ace76549b.1733136811.git.andrea.porta@suse.com>
References: <cover.1733136811.git.andrea.porta@suse.com> <42e09506979d878547d1140d7f6bf68ace76549b.1733136811.git.andrea.porta@suse.com>
Message-ID: <CACRpkdY+6QPRH-Pd9SwXV6dsdah-otMa8bkt=-avzF6Aiaz7gA@mail.gmail.com>

On Mon, Dec 2, 2024 at 12:19?PM Andrea della Porta
<andrea.porta at suse.com> wrote:

> Add device tree bindings for the gpio/pin/mux controller that is part of
> the RP1 multi function device, and relative entries in MAINTAINERS file.
>
> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

I can also just merge this patch to the pin control tree if you like,
tell me what
you desire.

Yours,
Linus Walleij


From qperret at google.com  Tue Dec 17 05:05:41 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 17 Dec 2024 13:05:41 +0000
Subject: [PATCH v3 00/18] KVM: arm64: Non-protected guest stage-2 support
 for pKVM
In-Reply-To: <CA+EHjTz7=dRz5X-CjjniJgwd87Q4DQbRdXzi0on4C21urYnhOQ@mail.gmail.com>
References: <20241216175803.2716565-1-qperret@google.com>
 <CA+EHjTz7=dRz5X-CjjniJgwd87Q4DQbRdXzi0on4C21urYnhOQ@mail.gmail.com>
Message-ID: <Z2F3JZII0gh8iOH2@google.com>

On Tuesday 17 Dec 2024 at 09:25:52 (+0000), Fuad Tabba wrote:
> On Mon, 16 Dec 2024 at 17:58, Quentin Perret <qperret at google.com> wrote:
> >
> > Hi all,
> >
> > This is the v3 of the series adding support for non-protected guests
> > stage-2 to pKVM. Please refer to v1 for all the context:
> 
> For the series:
> 
> Tested-by: Fuad Tabba <tabba at google.com>

Thank you!
Quentin


From maxime.chevallier at bootlin.com  Tue Dec 17 05:06:18 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 17 Dec 2024 14:06:18 +0100
Subject: [PATCH net-next 1/5] net: phylink: add support for PCS
 supported_interfaces bitmap
In-Reply-To: <E1tMBR5-006vaS-Ou@rmk-PC.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
	<E1tMBR5-006vaS-Ou@rmk-PC.armlinux.org.uk>
Message-ID: <20241217140618.0debd644@fedora.home>

Hi Russell,

On Fri, 13 Dec 2024 19:34:51 +0000
"Russell King (Oracle)" <rmk+kernel at armlinux.org.uk> wrote:

> Add support for the PCS to specify which interfaces it supports, which
> can be used by MAC drivers to build the main supported_interfaces
> bitmap. Phylink also validates that the PCS returned by the MAC driver
> supports the interface that the MAC was asked for.
> 
> An empty supported_interfaces bitmap from the PCS indicates that it
> does not provide this information, and we handle that appropriately.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

Thanks,

Maxime


From maxime.chevallier at bootlin.com  Tue Dec 17 05:07:58 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 17 Dec 2024 14:07:58 +0100
Subject: [PATCH net-next 2/5] net: pcs: xpcs: fill in PCS
 supported_interfaces
In-Reply-To: <E1tMBRA-006vaY-Sv@rmk-PC.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
	<E1tMBRA-006vaY-Sv@rmk-PC.armlinux.org.uk>
Message-ID: <20241217140758.747c329b@fedora.home>

Hi Russell,

On Fri, 13 Dec 2024 19:34:56 +0000
"Russell King (Oracle)" <rmk+kernel at armlinux.org.uk> wrote:

> Fill in the new PCS supported_interfaces member with the interfaces
> that XPCS supports.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

Thanks,

Maxime


From qperret at google.com  Tue Dec 17 05:08:25 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 17 Dec 2024 13:08:25 +0000
Subject: [PATCH v3 03/18] KVM: arm64: Make hyp_page::order a u8
In-Reply-To: <86zfkur329.wl-maz@kernel.org>
References: <20241216175803.2716565-1-qperret@google.com>
 <20241216175803.2716565-4-qperret@google.com>
 <86zfkur329.wl-maz@kernel.org>
Message-ID: <Z2F3yY6DwUBmTtnr@google.com>

On Tuesday 17 Dec 2024 at 10:55:58 (+0000), Marc Zyngier wrote:
> On Mon, 16 Dec 2024 17:57:48 +0000,
> Quentin Perret <qperret at google.com> wrote:
> > 
> > We don't need 16 bits to store the hyp page order, and we'll need some
> > bits to store page ownership data soon, so let's reduce the order
> > member.
> > 
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/nvhe/gfp.h    |  6 +++---
> >  arch/arm64/kvm/hyp/include/nvhe/memory.h |  5 +++--
> >  arch/arm64/kvm/hyp/nvhe/page_alloc.c     | 14 +++++++-------
> >  3 files changed, 13 insertions(+), 12 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> > index 97c527ef53c2..f1725bad6331 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> > @@ -7,7 +7,7 @@
> >  #include <nvhe/memory.h>
> >  #include <nvhe/spinlock.h>
> >  
> > -#define HYP_NO_ORDER	USHRT_MAX
> > +#define HYP_NO_ORDER	0xff
> 
> nit: (u8)(~0)?

SGTM.

Thanks,
Quentin


From qperret at google.com  Tue Dec 17 05:09:19 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 17 Dec 2024 13:09:19 +0000
Subject: [PATCH v3 04/18] KVM: arm64: Move host page ownership tracking
 to the hyp vmemmap
In-Reply-To: <86y10er2qb.wl-maz@kernel.org>
References: <20241216175803.2716565-1-qperret@google.com>
 <20241216175803.2716565-5-qperret@google.com>
 <86y10er2qb.wl-maz@kernel.org>
Message-ID: <Z2F3_8rN3NBFZXRX@google.com>

On Tuesday 17 Dec 2024 at 11:03:08 (+0000), Marc Zyngier wrote:
> On Mon, 16 Dec 2024 17:57:49 +0000,
> Quentin Perret <qperret at google.com> wrote:
> > 
> > We currently store part of the page-tracking state in PTE software bits
> > for the host, guests and the hypervisor. This is sub-optimal when e.g.
> > sharing pages as this forces to break block mappings purely to support
> > this software tracking. This causes an unnecessarily fragmented stage-2
> > page-table for the host in particular when it shares pages with Secure,
> > which can lead to measurable regressions. Moreover, having this state
> > stored in the page-table forces us to do multiple costly walks on the
> > page transition path, hence causing overhead.
> > 
> > In order to work around these problems, move the host-side page-tracking
> > logic from SW bits in its stage-2 PTEs to the hypervisor's vmemmap.
> > 
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/nvhe/memory.h |   6 +-
> >  arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 100 ++++++++++++++++-------
> >  arch/arm64/kvm/hyp/nvhe/setup.c          |   7 +-
> >  3 files changed, 77 insertions(+), 36 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > index 45b8d1840aa4..8bd9a539f260 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
> > @@ -8,7 +8,7 @@
> >  #include <linux/types.h>
> >  
> >  /*
> > - * SW bits 0-1 are reserved to track the memory ownership state of each page:
> > + * Bits 0-1 are reserved to track the memory ownership state of each page:
> >   *   00: The page is owned exclusively by the page-table owner.
> >   *   01: The page is owned by the page-table owner, but is shared
> >   *       with another entity.
> > @@ -43,7 +43,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
> >  struct hyp_page {
> >  	u16 refcount;
> >  	u8 order;
> > -	u8 reserved;
> > +
> > +	/* Host (non-meta) state. Guarded by the host stage-2 lock. */
> > +	enum pkvm_page_state host_state : 8;
> 
> An enum as a bitfield? Crazy! :)

Hehe, it works so why not :)

> You probably want an assert somewhere that ensures that hyp_page is a
> 32bit quantity, just to make sure (and avoid hard to track bugs).

Sounds like a good idea, I'll stick a BUILD_BUG_ON() somewhere.


From qperret at google.com  Tue Dec 17 05:07:58 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 17 Dec 2024 13:07:58 +0000
Subject: [PATCH v3 01/18] KVM: arm64: Change the layout of enum
 pkvm_page_state
In-Reply-To: <861py6sht3.wl-maz@kernel.org>
References: <20241216175803.2716565-1-qperret@google.com>
 <20241216175803.2716565-2-qperret@google.com>
 <861py6sht3.wl-maz@kernel.org>
Message-ID: <Z2F3rveiCEuPwxhN@google.com>

On Tuesday 17 Dec 2024 at 10:52:08 (+0000), Marc Zyngier wrote:
> On Mon, 16 Dec 2024 17:57:46 +0000,
> Quentin Perret <qperret at google.com> wrote:
> > 
> > The 'concrete' (a.k.a non-meta) page states are currently encoded using
> > software bits in PTEs. For performance reasons, the abstract
> > pkvm_page_state enum uses the same bits to encode these states as that
> > makes conversions from and to PTEs easy.
> > 
> > In order to prepare the ground for moving the 'concrete' state storage
> > to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this
> > purpose.
> > 
> > No functional changes intended.
> > 
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 16 +++++++++-------
> >  1 file changed, 9 insertions(+), 7 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > index 0972faccc2af..8c30362af2b9 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > @@ -24,25 +24,27 @@
> >   */
> >  enum pkvm_page_state {
> >  	PKVM_PAGE_OWNED			= 0ULL,
> > -	PKVM_PAGE_SHARED_OWNED		= KVM_PGTABLE_PROT_SW0,
> > -	PKVM_PAGE_SHARED_BORROWED	= KVM_PGTABLE_PROT_SW1,
> > -	__PKVM_PAGE_RESERVED		= KVM_PGTABLE_PROT_SW0 |
> > -					  KVM_PGTABLE_PROT_SW1,
> > +	PKVM_PAGE_SHARED_OWNED		= BIT(0),
> > +	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
> > +	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
> >  
> >  	/* Meta-states which aren't encoded directly in the PTE's SW bits */
> > -	PKVM_NOPAGE,
> > +	PKVM_NOPAGE			= BIT(2),
> >  };
> > +#define PKVM_PAGE_META_STATES_MASK	(~(BIT(0) | BIT(1)))
> 
> Shouldn't that be ~__PKVM_PAGE_RESERVED, given that you just defined it?

Sure thing, I followed the same pattern as PKVM_PAGE_STATE_PROT_MASK
which was explicit in which bits it sets, but very happy to change.

> >  
> >  #define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
> >  static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
> >  						 enum pkvm_page_state state)
> >  {
> > -	return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
> > +	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
> > +	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
> > +	return prot;
> >  }
> >  
> >  static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
> >  {
> > -	return prot & PKVM_PAGE_STATE_PROT_MASK;
> > +	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
> >  }
> >  
> >  struct host_mmu {
> 
> Thanks,
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.


From broonie at kernel.org  Tue Dec 17 05:12:12 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Dec 2024 13:12:12 +0000
Subject: [PATCH] KVM: arm64: Fix set_id_regs selftest for ASIDBITS
 becoming unwritable
In-Reply-To: <875xnisocy.wl-maz@kernel.org>
References: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
 <875xnisocy.wl-maz@kernel.org>
Message-ID: <53b40aa8-f51c-4c4e-a4ad-e6a9512e5197@sirena.org.uk>

On Tue, Dec 17, 2024 at 08:30:37AM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:

> > Fixes: 03c7527e97f7 ("KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden")

> A patch for a test doesn't fix anything in the kernel.

The selftests are shipped as part of the kernel source and frequently
used for testing the kernel, it's all one source base and we want to
ensure that for example the test fix gets backported if the relevant
kernel patch does.
-------------- 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/20241217/d7940a9c/attachment.sig>

From qperret at google.com  Tue Dec 17 05:14:17 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 17 Dec 2024 13:14:17 +0000
Subject: [PATCH v3 11/18] KVM: arm64: Introduce
 __pkvm_host_unshare_guest()
In-Reply-To: <CA+EHjTxRt=XoCZbRLE1UjMg4bzgoLYD9Lh0nzmjvPZ2Q4xQOkg@mail.gmail.com>
References: <20241216175803.2716565-1-qperret@google.com>
 <20241216175803.2716565-12-qperret@google.com>
 <CA+EHjTxRt=XoCZbRLE1UjMg4bzgoLYD9Lh0nzmjvPZ2Q4xQOkg@mail.gmail.com>
Message-ID: <Z2F5KboZewSDClKg@google.com>

On Tuesday 17 Dec 2024 at 08:53:34 (+0000), Fuad Tabba wrote:
> nit: This parameter in this patch, and others, is sometimes hyp_vm, at
> others just vm. It would be nicer if it was always the same.

Argh, where specifically do you see inconsistencies? All changes to
mem_protect.c should use 'vm' consistently in this series now.

The code in hyp-main.c does use 'hyp_vm' consistently however, but
perhaps that is what you meant? I did that to follow the pattern of the
existing code that uses 'hyp_vcpu' in that file.

Thanks!
Quentin


From maxime.chevallier at bootlin.com  Tue Dec 17 05:15:47 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 17 Dec 2024 14:15:47 +0100
Subject: [PATCH net-next 3/5] net: pcs: mtk-lynxi: fill in PCS
 supported_interfaces
In-Reply-To: <E1tMBRF-006vae-WC@rmk-PC.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
	<E1tMBRF-006vae-WC@rmk-PC.armlinux.org.uk>
Message-ID: <20241217141547.7748b3d3@fedora.home>

Hi Russell,

On Fri, 13 Dec 2024 19:35:01 +0000
"Russell King (Oracle)" <rmk+kernel at armlinux.org.uk> wrote:

> Fill in the new PCS supported_interfaces member with the interfaces
> that the Mediatek LynxI supports.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  drivers/net/pcs/pcs-mtk-lynxi.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
> index 7de804535229..1377fb78eaa1 100644
> --- a/drivers/net/pcs/pcs-mtk-lynxi.c
> +++ b/drivers/net/pcs/pcs-mtk-lynxi.c
> @@ -306,6 +306,11 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
>  	mpcs->pcs.poll = true;
>  	mpcs->interface = PHY_INTERFACE_MODE_NA;
>  
> +	__set_bit(PHY_INTERFACE_MODE_SGMII, mpcs->pcs.supported_interfaces);
> +	__set_bit(PHY_INTERFACE_MODE_QSGMII, mpcs->pcs.supported_interfaces);

I'm sorry if I missed something, but I don't find where the QSGMII
support comes from based on the current codebase :/

I didn't spot that in the inband_caps commit, sorry :(

> +	__set_bit(PHY_INTERFACE_MODE_1000BASEX, mpcs->pcs.supported_interfaces);
> +	__set_bit(PHY_INTERFACE_MODE_2500BASEX, mpcs->pcs.supported_interfaces);

Thanks,

Maxime



From lee at kernel.org  Tue Dec 17 05:16:29 2024
From: lee at kernel.org (Lee Jones)
Date: Tue, 17 Dec 2024 13:16:29 +0000
Subject: [GIT PULL] Immutable branch between MFD, HID, HWMON, Input and LEDs
 due for the v6.14 merge window
In-Reply-To: <20241107114712.538976-1-heiko@sntech.de>
References: <20241107114712.538976-1-heiko@sntech.de>
Message-ID: <20241217131629.GJ2418536@google.com>

Enjoy!

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -0800)

are available in the Git repository at:

  ssh://git at gitolite.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git tags/ib-mfd-hid-hwmon-input-leds-v6.14

for you to fetch changes up to 9855caf5d4eb1d8b8bba60be256186ea8e0f907c:

  hwmon: add driver for the hwmon parts of qnap-mcu devices (2024-12-17 13:14:48 +0000)

----------------------------------------------------------------
Immutable branch between MFD, HID, HWMON, Input and LEDs due for the v6.14 merge window

----------------------------------------------------------------
Heiko Stuebner (7):
      HID: hid-sensor-hub: don't use stale platform-data on remove
      mfd: core: Make platform_data pointer const in struct mfd_cell
      dt-bindings: mfd: Add binding for qnap,ts433-mcu devices
      mfd: Add base driver for qnap-mcu devices
      leds: Add driver for LEDs from qnap-mcu devices
      Input: add driver for the input part of qnap-mcu devices
      hwmon: add driver for the hwmon parts of qnap-mcu devices

 .../devicetree/bindings/mfd/qnap,ts433-mcu.yaml    |  42 +++
 Documentation/hwmon/index.rst                      |   1 +
 Documentation/hwmon/qnap-mcu-hwmon.rst             |  27 ++
 MAINTAINERS                                        |   9 +
 drivers/hid/hid-sensor-hub.c                       |  21 +-
 drivers/hwmon/Kconfig                              |  12 +
 drivers/hwmon/Makefile                             |   1 +
 drivers/hwmon/qnap-mcu-hwmon.c                     | 364 +++++++++++++++++++++
 drivers/input/misc/Kconfig                         |  12 +
 drivers/input/misc/Makefile                        |   1 +
 drivers/input/misc/qnap-mcu-input.c                | 153 +++++++++
 drivers/leds/Kconfig                               |  11 +
 drivers/leds/Makefile                              |   1 +
 drivers/leds/leds-qnap-mcu.c                       | 227 +++++++++++++
 drivers/mfd/Kconfig                                |  13 +
 drivers/mfd/Makefile                               |   2 +
 drivers/mfd/qnap-mcu.c                             | 338 +++++++++++++++++++
 include/linux/mfd/core.h                           |   2 +-
 include/linux/mfd/qnap-mcu.h                       |  26 ++
 19 files changed, 1255 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/qnap,ts433-mcu.yaml
 create mode 100644 Documentation/hwmon/qnap-mcu-hwmon.rst
 create mode 100644 drivers/hwmon/qnap-mcu-hwmon.c
 create mode 100644 drivers/input/misc/qnap-mcu-input.c
 create mode 100644 drivers/leds/leds-qnap-mcu.c
 create mode 100644 drivers/mfd/qnap-mcu.c
 create mode 100644 include/linux/mfd/qnap-mcu.h

-- 
Lee Jones [???]


From festevam at gmail.com  Tue Dec 17 05:20:05 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 17 Dec 2024 10:20:05 -0300
Subject: [PATCH v4 1/3] dt-bindings: lcdif: Document a imx6sx-lcdif fallback
In-Reply-To: <173073495749.210192.9138587910771237679.robh@kernel.org>
References: <20241101135406.47836-1-festevam@gmail.com> <173073495749.210192.9138587910771237679.robh@kernel.org>
Message-ID: <CAOMZO5BVLpQecZH4vvmRi=KfZ=MvCgUQ_tUKjvUzMGO=wTU-MA@mail.gmail.com>

Rob,

On Mon, Nov 4, 2024 at 12:42?PM Rob Herring (Arm) <robh at kernel.org> wrote:
>
>
> On Fri, 01 Nov 2024 10:54:04 -0300, Fabio Estevam wrote:
> > From: Fabio Estevam <festevam at denx.de>
> >
> > imx6sx.dtsi has the following lcdif entries:
> >
> > compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
> >
> > This causes the following dt-schema warning:
> >
> > ['fsl,imx6sx-lcdif', 'fsl,imx28-lcdif'] is too long
> >
> > To keep DT compatibility, document 'fsl,imx28-lcdif' as a possible
> > 'fsl,imx6sx-lcdif' fallback.
> >
> > Signed-off-by: Fabio Estevam <festevam at denx.de>

> Acked-by: Rob Herring (Arm) <robh at kernel.org>

Can you apply 1/3 and 2/3?


From m.felsch at pengutronix.de  Tue Dec 17 05:22:22 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Tue, 17 Dec 2024 14:22:22 +0100
Subject: [PATCH V2] soc: imx8m: Add remove function
In-Reply-To: <PAXPR04MB84594B482B89EE34A900A53E88042@PAXPR04MB8459.eurprd04.prod.outlook.com>
References: <20241217015826.1374497-1-peng.fan@oss.nxp.com>
 <20241217082637.i2ou6bbr3tc3uvof@pengutronix.de>
 <PAXPR04MB8459A91EEC932F41E24AE04488042@PAXPR04MB8459.eurprd04.prod.outlook.com>
 <20241217104634.2fc7yo6hprhx2wnt@pengutronix.de>
 <PAXPR04MB84594B482B89EE34A900A53E88042@PAXPR04MB8459.eurprd04.prod.outlook.com>
Message-ID: <20241217132222.sfxfknkkl2hvm2v7@pengutronix.de>

On 24-12-17, Peng Fan wrote:
> > Subject: Re: [PATCH V2] soc: imx8m: Add remove function
> > 
> > On 24-12-17, Peng Fan wrote:
> > > > Subject: Re: [PATCH V2] soc: imx8m: Add remove function
> > > >
> > > > Hi Peng,
> > > >
> > > > thanks for you patch.
> > > >
> > > > On 24-12-17, Peng Fan (OSS) wrote:
> > > > > From: Peng Fan <peng.fan at nxp.com>
> > > > >
> > > > > Unregister the cpufreq device and soc device in remove path,
> > > > otherwise
> > > >
> > > > After reconsidiering the patch approach, I think we shouldn't add a
> > > > .remove() function and instead should make use of the
> > > > devm_add_action() mechanism for the proper unregister calls.
> > >
> > > Would you please share why devm_add_action is preferred?
> > >
> > > Something as below?
> > > +static void imx8m_soc_remove(void *data) {
> > > +       struct imx8m_soc_priv *priv = data;
> > > +
> > > +       if (priv->cpufreq_dev)
> > > +               platform_device_unregister(priv->cpufreq_dev);
> > > +
> > > +       soc_device_unregister(priv->soc_dev);
> > > +}
> > 
> > I would split it into two action functions due to the following reasons:
> >  - cleanup during the probe() if something fails afterwards
> >  - no need for the if(priv->cpufreq_dev) check.
> > 
> > > In Probe:
> > > +       return devm_add_action(&pdev->dev, imx8m_soc_remove,
> > priv);
> > 
> > The actions should be added directly after the succeful device
> > registration, e.g.
> >  - after soc_device_register(soc_dev_attr) and
> >  - after platform_device_register_simple()
> 
> With two devm_add_action, I thought below code would work,
> devm_add_action(dev, soc_device_unregister, (void *)soc_dev);
> devm_add_action(dev, platform_device_unregister, (void *)cpufreq_dev);

Passing the soc_dev and cpufreq_dev as args would remove the
imx8m_soc_priv :)

> But devm_add_action expects: void (*action)(void *),
> So I need introduce two functions to wrap soc_device_unregister,
> and platform_device_unregister.

This is a common pattern.

> This seems not good. Using one devm_add_action just need
> one wrap function, comments?

It's more future proof in case the driver becomes more complex.

Regards,
  Marco

> 
> Thanks,
> Peng.
> 
> > 
> > Regards,
> >    Marco
> > 
> > >
> > > Regards,
> > > Peng.
> > >
> > > >
> > > > > there will be warning when do removing test:
> > > > > sysfs: cannot create duplicate filename '/devices/platform/imx-
> > > > cpufreq-dt'
> > > > > CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted
> > > > > 6.13.0-rc1-next-20241204 Hardware name: NXP i.MX8MPlus EVK
> > > > board (DT)
> > > > >
> > > > > Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as
> > platform
> > > > > driver")
> > > > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > > > ---
> > > > >
> > > > > V2:
> > > > >  Add err check when create the cpufreq platform device
> > > >
> > > > thank you for addressing this.
> > > >
> > > > Regards,
> > > >   Marco
> > > >
> > > > >  drivers/soc/imx/soc-imx8m.c | 41
> > > > > +++++++++++++++++++++++++++++++------
> > > > >  1 file changed, 35 insertions(+), 6 deletions(-)
> > > > >
> > > > > diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-
> > > > imx8m.c
> > > > > index 8ac7658e3d52..97c8718c2aa1 100644
> > > > > --- a/drivers/soc/imx/soc-imx8m.c
> > > > > +++ b/drivers/soc/imx/soc-imx8m.c
> > > > > @@ -33,6 +33,11 @@ struct imx8_soc_data {
> > > > >  	int (*soc_revision)(u32 *socrev, u64 *socuid);  };
> > > > >
> > > > > +struct imx8m_soc_priv {
> > > > > +	struct soc_device *soc_dev;
> > > > > +	struct platform_device *cpufreq_dev; };
> > > > > +
> > > > >  #ifdef CONFIG_HAVE_ARM_SMCCC
> > > > >  static u32 imx8mq_soc_revision_from_atf(void)
> > > > >  {
> > > > > @@ -195,10 +200,11 @@ static __maybe_unused const struct
> > > > of_device_id
> > > > > imx8_soc_match[] = {  static int imx8m_soc_probe(struct
> > > > > platform_device *pdev)  {
> > > > >  	struct soc_device_attribute *soc_dev_attr;
> > > > > +	struct platform_device *cpufreq_dev;
> > > > >  	const struct imx8_soc_data *data;
> > > > >  	struct device *dev = &pdev->dev;
> > > > >  	const struct of_device_id *id;
> > > > > -	struct soc_device *soc_dev;
> > > > > +	struct imx8m_soc_priv *priv;
> > > > >  	u32 soc_rev = 0;
> > > > >  	u64 soc_uid = 0;
> > > > >  	int ret;
> > > > > @@ -207,6 +213,10 @@ static int imx8m_soc_probe(struct
> > > > platform_device *pdev)
> > > > >  	if (!soc_dev_attr)
> > > > >  		return -ENOMEM;
> > > > >
> > > > > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > > > > +	if (!priv)
> > > > > +		return -ENOMEM;
> > > > > +
> > > > >  	soc_dev_attr->family = "Freescale i.MX";
> > > > >
> > > > >  	ret = of_property_read_string(of_root, "model",
> > > > > &soc_dev_attr->machine); @@ -235,21 +245,40 @@ static int
> > > > imx8m_soc_probe(struct platform_device *pdev)
> > > > >  	if (!soc_dev_attr->serial_number)
> > > > >  		return -ENOMEM;
> > > > >
> > > > > -	soc_dev = soc_device_register(soc_dev_attr);
> > > > > -	if (IS_ERR(soc_dev))
> > > > > -		return PTR_ERR(soc_dev);
> > > > > +	priv->soc_dev = soc_device_register(soc_dev_attr);
> > > > > +	if (IS_ERR(priv->soc_dev))
> > > > > +		return PTR_ERR(priv->soc_dev);
> > > > >
> > > > >  	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
> > > > >  		soc_dev_attr->revision);
> > > > >
> > > > > -	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
> > > > > -		platform_device_register_simple("imx-cpufreq-dt", -1,
> > > > NULL, 0);
> > > > > +	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) {
> > > > > +		cpufreq_dev = platform_device_register_simple("imx-
> > > > cpufreq-dt", -1, NULL, 0);
> > > > > +		if (!IS_ERR(cpufreq_dev))
> > > > > +			priv->cpufreq_dev = cpufreq_dev;
> > > > > +		else
> > > > > +			dev_err(dev, "Failed to create imx-cpufreq-
> > > > dev device: %ld",
> > > > > +				PTR_ERR(cpufreq_dev));
> > > > > +	}
> > > > > +
> > > > > +	platform_set_drvdata(pdev, priv);
> > > > >
> > > > >  	return 0;
> > > > >  }
> > > > >
> > > > > +static void imx8m_soc_remove(struct platform_device *pdev) {
> > > > > +	struct imx8m_soc_priv *priv = platform_get_drvdata(pdev);
> > > > > +
> > > > > +	if (priv->cpufreq_dev)
> > > > > +		platform_device_unregister(priv->cpufreq_dev);
> > > > > +
> > > > > +	soc_device_unregister(priv->soc_dev);
> > > > > +}
> > > > > +
> > > > >  static struct platform_driver imx8m_soc_driver = {
> > > > >  	.probe = imx8m_soc_probe,
> > > > > +	.remove	= imx8m_soc_remove,
> > > > >  	.driver = {
> > > > >  		.name = "imx8m-soc",
> > > > >  	},
> > > > > --
> > > > > 2.37.1
> > > > >
> > > > >
> > > > >
> > >
> 


From maxime.chevallier at bootlin.com  Tue Dec 17 05:18:07 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 17 Dec 2024 14:18:07 +0100
Subject: [PATCH net-next 4/5] net: pcs: lynx: fill in PCS
 supported_interfaces
In-Reply-To: <E1tMBRL-006van-3c@rmk-PC.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
	<E1tMBRL-006van-3c@rmk-PC.armlinux.org.uk>
Message-ID: <20241217141807.6b1ed05a@fedora.home>

On Fri, 13 Dec 2024 19:35:07 +0000
"Russell King (Oracle)" <rmk+kernel at armlinux.org.uk> wrote:

> Fill in the new PCS supported_interfaces member with the interfaces
> that Lynx supports.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

Thanks,

Maxime


From robh at kernel.org  Tue Dec 17 05:18:13 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 17 Dec 2024 07:18:13 -0600
Subject: [net-next PATCH v11 1/9] dt-bindings: nvmem: Document support
 for Airoha AN8855 Switch EFUSE
In-Reply-To: <20241209134459.27110-2-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-2-ansuelsmth@gmail.com>
Message-ID: <173444149293.1330948.15339441958855664724.robh@kernel.org>


On Mon, 09 Dec 2024 14:44:18 +0100, Christian Marangi wrote:
> Document support for Airoha AN8855 Switch EFUSE used to calibrate
> internal PHYs and store additional configuration info.
> 
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> ---
>  .../bindings/nvmem/airoha,an8855-efuse.yaml   | 123 ++++++++++++++++++
>  MAINTAINERS                                   |   8 ++
>  2 files changed, 131 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From maxime.chevallier at bootlin.com  Tue Dec 17 05:19:12 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 17 Dec 2024 14:19:12 +0100
Subject: [PATCH net-next 5/5] net: stmmac: use PCS supported_interfaces
In-Reply-To: <E1tMBRQ-006vat-7F@rmk-PC.armlinux.org.uk>
References: <Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
	<E1tMBRQ-006vat-7F@rmk-PC.armlinux.org.uk>
Message-ID: <20241217141912.34cdd5ae@fedora.home>

Hi Russell,

On Fri, 13 Dec 2024 19:35:12 +0000
"Russell King (Oracle)" <rmk+kernel at armlinux.org.uk> wrote:

> Use the PCS' supported_interfaces member to build the MAC level
> supported_interfaces bitmap.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index d45fd7a3acd5..0e45c4a48bb5 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1206,6 +1206,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
>  	struct stmmac_mdio_bus_data *mdio_bus_data;
>  	int mode = priv->plat->phy_interface;
>  	struct fwnode_handle *fwnode;
> +	struct phylink_pcs *pcs;
>  	struct phylink *phylink;
>  
>  	priv->phylink_config.dev = &priv->dev->dev;
> @@ -1227,8 +1228,14 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
>  
>  	/* If we have an xpcs, it defines which PHY interfaces are supported. */
>  	if (priv->hw->xpcs)
> -		xpcs_get_interfaces(priv->hw->xpcs,
> -				    priv->phylink_config.supported_interfaces);
> +		pcs = xpcs_to_phylink_pcs(priv->hw->xpcs);
> +	else
> +		pcs = priv->hw->phylink_pcs;
> +
> +	if (pcs)
> +		phy_interface_or(priv->phylink_config.supported_interfaces,
> +				 priv->phylink_config.supported_interfaces,
> +				 pcs->supported_interfaces);
>  
>  	fwnode = priv->plat->port_node;
>  	if (!fwnode)

I think that we could even make xpcs_get_interfaces a static
non-exported function now :) But this can be done in a subsequent patch.

Thanks for that work !

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

Maxime


From tabba at google.com  Tue Dec 17 05:22:37 2024
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Dec 2024 13:22:37 +0000
Subject: [PATCH v3 11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
In-Reply-To: <Z2F5KboZewSDClKg@google.com>
References: <20241216175803.2716565-1-qperret@google.com> <20241216175803.2716565-12-qperret@google.com>
 <CA+EHjTxRt=XoCZbRLE1UjMg4bzgoLYD9Lh0nzmjvPZ2Q4xQOkg@mail.gmail.com> <Z2F5KboZewSDClKg@google.com>
Message-ID: <CA+EHjTzmEonAUNNHM8X__6XHLko0fksjT0_ZVHhKRVsZp0zQCg@mail.gmail.com>

On Tue, 17 Dec 2024 at 13:14, Quentin Perret <qperret at google.com> wrote:
>
> On Tuesday 17 Dec 2024 at 08:53:34 (+0000), Fuad Tabba wrote:
> > nit: This parameter in this patch, and others, is sometimes hyp_vm, at
> > others just vm. It would be nicer if it was always the same.
>
> Argh, where specifically do you see inconsistencies? All changes to
> mem_protect.c should use 'vm' consistently in this series now.
>
> The code in hyp-main.c does use 'hyp_vm' consistently however, but
> perhaps that is what you meant? I did that to follow the pattern of the
> existing code that uses 'hyp_vcpu' in that file.

You're right, my bad. I was looking at the code in the patch, not in
the files. Sorry for the noise.
/fuad

> Thanks!
> Quentin


From jwerner at chromium.org  Tue Dec 17 05:25:27 2024
From: jwerner at chromium.org (Julius Werner)
Date: Tue, 17 Dec 2024 14:25:27 +0100
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <CAD=FV=UHBA7zXZEw3K6TRpZEN-ApOkmymhRCOkz7h+yrAkR_Dw@mail.gmail.com>
References: <20241214005248.198803-1-dianders@chromium.org>
 <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
 <CAODwPW_c+Ycu_zhiDOKN-fH2FEWf2pxr+FcugpqEjLX-nVjQrg@mail.gmail.com> <CAD=FV=UHBA7zXZEw3K6TRpZEN-ApOkmymhRCOkz7h+yrAkR_Dw@mail.gmail.com>
Message-ID: <CAODwPW8s4GhWGuZMUbWVNLYw_EVJe=EeMDacy1hxDLmnthwoFg@mail.gmail.com>

> > - Refactor max_bhb_k in spectre_bhb_loop_affected() to be a global
> > instead, which starts out as zero, is updated by
> > spectre_bhb_loop_affected(), and is directly read by
> > spectre_bhb_patch_loop_iter() (could probably remove the `scope`
> > argument from spectre_bhb_loop_affected() then).
>
> Refactoring "max_bhb_k" would be a general cleanup and not related to
> anything else here, right?
>
> ...but the function is_spectre_bhb_affected() is called from
> "cpu_errata.c" and has a scope. Can we guarantee that it's always
> "SCOPE_LOCAL_CPU"? I tried reading through the code and it's
> _probably_ SCOPE_LOCAL_CPU most of the time, but it doesn't seem worth
> it to add an assumption here for a small cleanup.
>
> I'm not going to do this, though I will move "max_bhb_k" to be a
> global for the suggestion below.

If you make max_bhb_k a global, then whether you change all
`spectre_bhb_loop_affected(SCOPE_SYSTEM)` calls to read the global
directly or whether you keep it such that
`spectre_bhb_loop_affected()` simply returns that global for
SCOPE_SYSTEM makes no difference. I just think reading the global
directly would look a bit cleaner. Calling a function that's called
"...affected()" when you're really just trying to find out the K-value
feels a bit odd.

For is_spectre_bhb_affected(), I was assuming the change below where
you combine all the `return true` paths, so the scope question
wouldn't matter there.

> > - Change the `return false` into `return true` at the end of
> > is_spectre_bhb_affected (in fact, you can probably take out some of
> > the other calls that result in returning true as well then)
>
> I'm not sure you can take out the other calls. Specifically, both
> spectre_bhb_loop_affected() and is_spectre_bhb_fw_affected() _need_ to
> be called for each CPU so that they update static globals, right?
> Maybe we could get rid of the call to supports_clearbhb(), but that
> _would_ change things in ways that are not obvious. Specifically I
> could believe that someone could have backported "clear BHB" to their
> core but their core is otherwise listed as "loop affected". That would
> affect "max_bhb_k". Maybe (?) it doesn't matter in this case, but I'd
> rather not mess with it unless someone really wants me to and is sure
> it's safe.

Yes, but spectre_bhb_enable_mitigation() already calls all those
functions on its own again anyway, so I'm pretty sure the "must be
called once for each CPU" part of spectre_bhb_loop_affected() is
covered by that. (Besides, it would be really awful if they had made a
function whose name starts with is_... have critical side-effects that
break things when it doesn't get called.)

> > - In spectre_bhb_enable_mitigations(), at the end of the long if-else
> > chain, put a last else block that prints your WARN_ONCE(), sets the
> > max_bhb_k global to 32, and then does the same stuff that the `if
> > (spectre_bhb_loop_affected())` block would have installed (maybe
> > factoring that out into a helper function called from both cases).
>
> ...or just reorder it so that the spectre_bhb_loop_affected() code is
> last and it can be the "else". Then I can WARN_ONCE() if
> spectre_bhb_loop_affected(). ...or I could just do the WARN_ONCE()
> when I get to the end of is_spectre_bhb_affected() and set "max_bhb_k"
> to 32 there. I'd actually rather do that so that "max_bhb_k" is
> consistently set after is_spectre_bhb_affected() is called on all
> cores regardless of whether or not some cores are unknown.

Yeah, you can reorder the loops too. I don't feel like moving this
into is_spectre_bhb_affected() would be a good idea. Functions with a
predicate name like that really shouldn't have such side effects.
Besides, I think is_spectre_bhb_affected() is probably called more
often per CPU, both once from spectre_bhb_enable_mitigation() and by
whatever calls the `matches` pointer in the cpu_errata struct.
spectre_bhb_enable_mitigation() seems to be the function that's called
once for each CPU on boot to install the correct mitigation, so that
feels like the best spot to put the fallback logic to me.


From broonie at kernel.org  Tue Dec 17 05:27:35 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Dec 2024 13:27:35 +0000
Subject: [PATCH] spi: rockchip-sfc: Support pm ops
In-Reply-To: <20241208130311.1324024-1-jon.lin@rock-chips.com>
References: <20241208130311.1324024-1-jon.lin@rock-chips.com>
Message-ID: <173444205510.31817.16108705113990702119.b4-ty@kernel.org>

On Sun, 08 Dec 2024 21:03:11 +0800, Jon Lin wrote:
> Support system_sleep and runtime_pm ops.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: rockchip-sfc: Support pm ops
      commit: 8011709906d0d6ff1ba9589de5a906bf6e430782

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 robh at kernel.org  Tue Dec 17 05:28:32 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 17 Dec 2024 07:28:32 -0600
Subject: [net-next PATCH v11 2/9] dt-bindings: net: Document support for
 Airoha AN8855 Switch Virtual MDIO
In-Reply-To: <20241209134459.27110-3-ansuelsmth@gmail.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-3-ansuelsmth@gmail.com>
Message-ID: <173444211136.1418557.12469782801691992405.robh@kernel.org>


On Mon, 09 Dec 2024 14:44:19 +0100, Christian Marangi wrote:
> Document support for Airoha AN8855 Virtual MDIO Passtrough. This is needed
> as AN8855 require special handling as the same address on the MDIO bus is
> shared for both Switch and PHY and special handling for the page
> configuration is needed to switch accessing to Switch address space
> or PHY.
> 
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> ---
>  .../bindings/net/airoha,an8855-mdio.yaml      | 56 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 57 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From qperret at google.com  Tue Dec 17 05:33:57 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 17 Dec 2024 13:33:57 +0000
Subject: [PATCH v3 11/18] KVM: arm64: Introduce
 __pkvm_host_unshare_guest()
In-Reply-To: <86wmfyr1j4.wl-maz@kernel.org>
References: <20241216175803.2716565-1-qperret@google.com>
 <20241216175803.2716565-12-qperret@google.com>
 <86wmfyr1j4.wl-maz@kernel.org>
Message-ID: <Z2F9xb4jrK1zRtNV@google.com>

On Tuesday 17 Dec 2024 at 11:29:03 (+0000), Marc Zyngier wrote:
> > +static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)
> > +{
> > +	enum pkvm_page_state state;
> > +	struct hyp_page *page;
> > +	kvm_pte_t pte;
> > +	u64 phys;
> > +	s8 level;
> > +	int ret;
> > +
> > +	ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
> > +	if (ret)
> > +		return ret;
> > +	if (level != KVM_PGTABLE_LAST_LEVEL)
> 
> So there is still a very strong assumption that a guest is only
> provided page mappings, and no blocks?

Yep, very much so. It's one of the main limitations of the series as-is
(with the absence of support for mapping anything else than memory in
guests). Those limitations were mentioned in the cover letter of v1, but
I should have kept that mention in later versions, sorry!

The last patch of the series has a tweak to user_mem_abort() to force
mappings to PTE level which is trivial to do as we already need to do
similar things for dirty logging. And __pkvm_host_share_guest() doesn't
take a 'size' parameter in its current form, it assumes it is being
passed a single pfn. So all in all this works well, and simplifies the
series a lot.

Huge-page support should come as a natural extension to this series, but
I was hoping it could be done separately as that should have no
*functional* impact observable from userspace. I'm slightly more
concerned about the lack of support for mapping MMIO, but that too is
going to be some work, and I guess you should just turn pKVM off if
you want that for now...

Happy to address either or both of these limitations as part of this
series if we think they're strictly required to land this stuff
upstream, this is obviously up for debate. But that's going to be quite
a few patches on top :-)

Thanks,
Quentin


From linus.walleij at linaro.org  Tue Dec 17 05:39:03 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Dec 2024 14:39:03 +0100
Subject: [PATCH] pinctrl: sunxi: Use minimal debouncing period as default
In-Reply-To: <ZzyoIABRArkGoZBn@collins>
References: <20241119140805.3345412-1-paulk@sys-base.io> <20241119-prudent-jasmine-lizard-195cef@houat>
 <ZzyoIABRArkGoZBn@collins>
Message-ID: <CACRpkdbqufNVq4Ai6GQpgK2OY0rxLnp1wLQNmRoCv44T0xmFkQ@mail.gmail.com>

Some discussion here, and some emotions involved.

I can't seem to follow the technical matter because of all the
social matters :/

On Tue, Nov 19, 2024 at 4:00?PM Paul Kocialkowski <paulk at sys-base.io> wrote:

> My use-case here was hooking up a sparkfun sensor board by the way,
> not some very advanced corner-case.

Are you adding this as a DT overlay or by modifying an existing device
tree? Does this sensor have an established device tree binding?

Are you using that sparkfun sensor by a kernel driver or from userspace
using the GPIO character device?

I noticed that the sunxi GPIO driver is implementing the
.set_config() callback calling gpiochip_generic_config,
which makes it call down to the pin control driver to set up
the pin config.

which would in turn make it eligible to use
the gpiod_set_debounce() callback to push down the debounce
period.

But pinctrl-sunxi.c's sunxi_pconf_set() does *NOT* implement
support for setting up the debounce, because it is (as I understand
it) not part of the pin config hardware, but part of the interrupt
generator hardware, correct?

In that case I think we the gpiochip .set_config() callback should
be modified something like this (pseudo code):

sunxi_pinctrl_gpio_set_config()
{
    if (irq_is_in_use && param_is_debounce) {
        modify_irq_debounce_according_to_param()
        return 0;
    }
    gpiochip_generic_config()
}

pctl->chip->set_config = sunxi_pinctrl_gpio_set_config()

Maybe the debounce can also be set even if the line is not used
for IRQ? I'm not sure.

In either case the latter would give the GPIO driver a handle
on the debounce, which is good because the irqchip
generally does not.

There is a way it is possible to use the interrupt with desired debounce
setting by first getting the GPIO descriptor and modify the debounce
setting and then getting the interrupt from the GPIO descriptor:

struct gpio_desc *g;
int irq;

g = gpiod_get(dev, "dataready", GPIOD_IN);
gpiod_set_debounce(g, 1);
irq = gpiod_to_irq(g);
...request irq...

Here I assume the line out from the sensor is named "dataready"
the actual component likely has a name like that for the line.

This requires changes in the device tree as well, so that a GPIO
line is assigned to the sensor instead of "just" an interrupt:

sensor {
  dataready-gpios = <&gpio 14>;
  ...
};

instead of:

sensor {
  interrupt-parent = <&gpio>;
  interrupts = <14 IRQ_TYPE_EDGE_RISING>;
};

Unfortunately this is one of the areas where DT bindings are
a bit ambiguous. Some just assign the GPIO line as an interrupt
as both APIs are available, sometimes a proper GPIO line is
preferred for the above reasons.

Yours,
Linus Walleij


From quic_vikramsa at quicinc.com  Tue Dec 17 05:39:54 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:09:54 +0530
Subject: [PATCH v9 3/4] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <20241217133955.946426-1-quic_vikramsa@quicinc.com>
References: <20241217133955.946426-1-quic_vikramsa@quicinc.com>
Message-ID: <20241217133955.946426-4-quic_vikramsa@quicinc.com>

Add changes to support the camera subsystem on the SC7280.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 178 +++++++++++++++++++++++++++
 1 file changed, 178 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 55db1c83ef55..a893aade8165 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -4426,6 +4426,184 @@ cci1_i2c1: i2c-bus at 1 {
 			};
 		};
 
+		camss: isp at acb3000 {
+			compatible = "qcom,sc7280-camss";
+
+			reg = <0x0 0x0acb3000 0x0 0x1000>,
+			      <0x0 0x0acba000 0x0 0x1000>,
+			      <0x0 0x0acc1000 0x0 0x1000>,
+			      <0x0 0x0acc8000 0x0 0x1000>,
+			      <0x0 0x0accf000 0x0 0x1000>,
+			      <0x0 0x0ace0000 0x0 0x2000>,
+			      <0x0 0x0ace2000 0x0 0x2000>,
+			      <0x0 0x0ace4000 0x0 0x2000>,
+			      <0x0 0x0ace6000 0x0 0x2000>,
+			      <0x0 0x0ace8000 0x0 0x2000>,
+			      <0x0 0x0acaf000 0x0 0x4000>,
+			      <0x0 0x0acb6000 0x0 0x4000>,
+			      <0x0 0x0acbd000 0x0 0x4000>,
+			      <0x0 0x0acc4000 0x0 0x4000>,
+			      <0x0 0x0accb000 0x0 0x4000>;
+			reg-names = "csid0",
+				    "csid1",
+				    "csid2",
+				    "csid_lite0",
+				    "csid_lite1",
+				    "csiphy0",
+				    "csiphy1",
+				    "csiphy2",
+				    "csiphy3",
+				    "csiphy4",
+				    "vfe0",
+				    "vfe1",
+				    "vfe2",
+				    "vfe_lite0",
+				    "vfe_lite1";
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_CSIPHY0_CLK>,
+				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY1_CLK>,
+				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY2_CLK>,
+				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY3_CLK>,
+				 <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY4_CLK>,
+				 <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+				 <&gcc GCC_CAMERA_HF_AXI_CLK>,
+				 <&gcc GCC_CAMERA_SF_AXI_CLK>,
+				 <&camcc CAM_CC_ICP_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_0_CLK>,
+				 <&camcc CAM_CC_IFE_0_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_1_CLK>,
+				 <&camcc CAM_CC_IFE_1_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_1_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_2_CLK>,
+				 <&camcc CAM_CC_IFE_2_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_2_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>;
+			clock-names = "camnoc_axi",
+				      "cpas_ahb",
+				      "csiphy0",
+				      "csiphy0_timer",
+				      "csiphy1",
+				      "csiphy1_timer",
+				      "csiphy2",
+				      "csiphy2_timer",
+				      "csiphy3",
+				      "csiphy3_timer",
+				      "csiphy4",
+				      "csiphy4_timer",
+				      "gcc_axi_hf",
+				      "gcc_axi_sf",
+				      "icp_ahb",
+				      "vfe0",
+				      "vfe0_axi",
+				      "vfe0_cphy_rx",
+				      "vfe0_csid",
+				      "vfe1",
+				      "vfe1_axi",
+				      "vfe1_cphy_rx",
+				      "vfe1_csid",
+				      "vfe2",
+				      "vfe2_axi",
+				      "vfe2_cphy_rx",
+				      "vfe2_csid",
+				      "vfe_lite0",
+				      "vfe_lite0_cphy_rx",
+				      "vfe_lite0_csid",
+				      "vfe_lite1",
+				      "vfe_lite1_cphy_rx",
+				      "vfe_lite1_csid";
+
+			interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "csid0",
+					  "csid1",
+					  "csid2",
+					  "csid_lite0",
+					  "csid_lite1",
+					  "csiphy0",
+					  "csiphy1",
+					  "csiphy2",
+					  "csiphy3",
+					  "csiphy4",
+					  "vfe0",
+					  "vfe1",
+					  "vfe2",
+					  "vfe_lite0",
+					  "vfe_lite1";
+
+			interconnects = <&gem_noc  MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &cnoc2 SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&mmss_noc MASTER_CAMNOC_HF  QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "ahb",
+					     "hf_0";
+
+			iommus = <&apps_smmu 0x800 0x4e0>;
+
+			power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
+					<&camcc CAM_CC_IFE_1_GDSC>,
+					<&camcc CAM_CC_IFE_2_GDSC>,
+					<&camcc CAM_CC_TITAN_TOP_GDSC>;
+			power-domain-names = "ife0",
+					     "ife1",
+					     "ife2",
+					     "top";
+
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+				};
+
+				port at 1 {
+					reg = <1>;
+				};
+
+				port at 2 {
+					reg = <2>;
+				};
+
+				port at 3 {
+					reg = <3>;
+				};
+
+				port at 4 {
+					reg = <4>;
+				};
+			};
+		};
+
 		camcc: clock-controller at ad00000 {
 			compatible = "qcom,sc7280-camcc";
 			reg = <0 0x0ad00000 0 0x10000>;
-- 
2.25.1



From quic_vikramsa at quicinc.com  Tue Dec 17 05:39:55 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:09:55 +0530
Subject: [PATCH v9 4/4] arm64: dts: qcom: qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <20241217133955.946426-1-quic_vikramsa@quicinc.com>
References: <20241217133955.946426-1-quic_vikramsa@quicinc.com>
Message-ID: <20241217133955.946426-5-quic_vikramsa@quicinc.com>

The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
Enable the IMX577 on the vision mezzanine.

An example media-ctl pipeline for the imx577 is:

media-ctl --reset
media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'

yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0

Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/Makefile             |   4 +
 .../qcs6490-rb3gen2-vision-mezzanine.dtso     | 109 ++++++++++++++++++
 2 files changed, 113 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 4686f2a8ddd8..a7e88fcabded 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -115,6 +115,10 @@ dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-1000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-4000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs615-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
+
+qcs6490-rb3gen2-vision-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2-vision-mezzanine.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride.dtb
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
new file mode 100644
index 000000000000..7782c4aee576
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/*
+ * Camera Sensor overlay on top of rb3gen2 core kit.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/qcom,camcc-sc7280.h>
+
+/dts-v1/;
+/plugin/;
+
+&camss {
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* The port index denotes CSIPHY id i.e. csiphy3 */
+		port at 3 {
+			reg = <3>;
+
+			csiphy3_ep: endpoint {
+				clock-lanes = <7>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&imx577_ep>;
+			};
+		};
+	};
+};
+
+&cci1 {
+	status = "okay";
+};
+
+&cci1_i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	camera at 1a {
+		compatible = "sony,imx577";
+
+		reg = <0x1a>;
+
+		reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default", "suspend";
+		pinctrl-0 = <&cam2_default>;
+		pinctrl-1 = <&cam2_suspend>;
+
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clock-rates = <24000000>;
+
+		dovdd-supply  = <&vreg_l18b_1p8>;
+		avdd-supply = <&vph_pwr>;
+		dvdd-supply = <&vph_pwr>;
+
+		port {
+			imx577_ep: endpoint {
+				clock-lanes = <7>;
+				link-frequencies = /bits/ 64 <600000000>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&csiphy3_ep>;
+			};
+		};
+	};
+};
+
+&tlmm {
+	cam2_default: cam2-default-state {
+		mclk-pins {
+			pins = "gpio67";
+			function = "cam_mclk";
+			drive-strength = <2>;
+			bias-disable;
+		};
+
+		rst-pins {
+			pins = "gpio78";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+		};
+	};
+
+	cam2_suspend: cam2-suspend-state {
+		mclk-pins {
+			pins = "gpio67";
+			function = "cam_mclk";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		rst-pins {
+			pins = "gpio78";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+			output-low;
+		};
+	};
+};
-- 
2.25.1



From linus.walleij at linaro.org  Tue Dec 17 05:41:36 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Dec 2024 14:41:36 +0100
Subject: [PATCH] pinctrl: sunxi: Use minimal debouncing period as default
In-Reply-To: <20241119-prudent-jasmine-lizard-195cef@houat>
References: <20241119140805.3345412-1-paulk@sys-base.io> <20241119-prudent-jasmine-lizard-195cef@houat>
Message-ID: <CACRpkdbcDwJaLmCa_YoP2zFw3fiWn-d1Q773jGh9kcVN8aWQKQ@mail.gmail.com>

On Tue, Nov 19, 2024 at 3:43?PM Maxime Ripard <mripard at kernel.org> wrote:

> [Paul]
> > The pinctrl code supports an input-debounce device-tree property to set
> > a specific debouncing period and choose which clock source is most
> > relevant. However the property is specified in microseconds, which is
> > longer than the minimal period achievable from the high-frequency
> > oscillator without a pre-scaler.
>
> That can be fixed by introducing a new property with a ns resolution.

Perhaps, but I think a setting of 0 should just yield the minimum
resolution in this case, as apparently the debounce cannot be
turned off? This would also make sense to expose for
gpiod_set_debounce() as explained in my other mail.

Yours,
Linus Walleij


From quic_vikramsa at quicinc.com  Tue Dec 17 05:39:51 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:09:51 +0530
Subject: [PATCH v9 0/4] media: qcom: camss: Add sc7280 support
Message-ID: <20241217133955.946426-1-quic_vikramsa@quicinc.com>

SC7280 is a Qualcomm SoC. This series adds support to bring up the CSIPHY,
CSID, VFE/RDI interfaces in SC7280.

SC7280 provides

- 3 x VFE, 3 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE
- 3 x CSID
- 2 x CSID Lite
- 5 x CSI PHY

We have tested this on qcs6490-rb3gen2-vision-mezzanine board having IMX577
sensor. Verified both TPG and IMX577 sensor.

Used following tools for the sanity check of these changes.

- make CHECK_DTBS=y W=1 DT_SCHEMA_FILES=media/qcom,sc7280-camss.yaml
qcom/qcs6490-rb3gen2-vision-mezzanine.dtb
- make DT_CHECKER_FLAGS=-m W=1
DT_SCHEMA_FILES=media/qcom,sc7280-camss.yaml dt_binding_check
- Smatch: make CHECK="smatch --full-path"
M=drivers/media/platform/qcom/camss/
- Sparse: make C=2 M=drivers/media/platform/qcom/camss/
- coccicheck : make coccicheck M=drivers/media/platform/qcom/camss/
- make -j32 W=1
- ./scripts/checkpatch.pl
 
Changes in V9:
- Removed GCC_CAMERA_AHB_CLK as its always enabled.
- Added GCC_CAMERA_SF_AXI_CLK.
- Renamed gcc_cam_hf_axi to gcc_axi_hf.
- V8 had 5 patches and V9 have 4 patches.
- First 3 patches of V8 are already promoted to linux-next
i.e  
  media: dt-bindings: Add qcom,sc7280-camss
  media: qcom: camss: Sort camss version enums and compatible strings
  media: qcom: camss: Add support for camss driver on sc7280
- 2 new patches are added to handle new comments from Konrad on
  "Patch v8 4/5 arm64: dts: qcom: sc7280: Add support for camss" 
  1 of the 2 new patches make changes in yaml and other one is making
  change in camss driver to handle new comments in dtsi.
- for "Patch v8 4/5 arm64: dts: qcom: sc7280: Add support for camss" I got
  comments from Konrad to make changes for clock names so I had to make
  respective changes in "bindings/media/qcom,sc7280-camss.yaml". As dtsi
  changes are not merged yet, so there is no issues with backward
  compatibility and I am assuming this should be acceptable.
  
Changes in V8:
- Changed node name from camss to isp.
- Added QCOM_ICC_TAG_ACTIVE_ONLY and QCOM_ICC_TAG_ALWAYS tags for
  interconnects. 
- Added blank lines when required.
- Modified power-domain-names from horizontal to vertical list.
- Sorted pinctrl nodes based on gpio index.
- Link to v7: https://lore.kernel.org/linux-arm-msm/20241204100003.300123-1-quic_vikramsa at quicinc.com/

Changes in V7:
- Changed unit address for camss in documention and dts.
- Added avdd-supply and dvdd-supply for sensor.
- Changed reg/clocks/interrupts name for vfe_lite and csid_lite.
- Link to v6: https://lore.kernel.org/linux-arm-msm/20241127100421.3447601-1-quic_vikramsa at quicinc.com/

Changes in V6:
- Changed order of properties in Documentation [PATCH 1/5].
- Updated description for ports in Documentaion [PATCH 1/5].
- Moved regulators from csid to csiphy [PATCH 3/5].
- Link to v5: https://lore.kernel.org/linux-arm-msm/20241112173032.2740119-1-quic_vikramsa at quicinc.com/ 

Changes in V5:
- Updated Commit text for [PATCH v5 1/6].
- Moved reg after compatible string.
- Renamed csi'x' clocks to vfe'x'_csid
- Removed [PATCH v4 4/6] and raised a seprate series for this one.
- Moved gpio states to mezzanine dtso.
- Added more clock levels to address TPG related issues.
- Renamed power-domains-names -> power-domain-names. 
- Link to v4: https://lore.kernel.org/linux-arm-msm/20241030105347.2117034-1-quic_vikramsa at quicinc.com/ 

Changes in V4:
- V3 had 8 patches and V4 is reduced to 6.
- Removed [Patch v3 2/8] as binding change is not required for dtso.
- Removed [Patch v3 3/8] as the fix is already taken care in latest
  kernel tip. 
- Updated alignment for dtsi and dt-bindings.
- Adding qcs6490-rb3gen2-vision-mezzanine as overlay. 
- Link to v3: https://lore.kernel.org/linux-arm-msm/20241011140932.1744124-1-quic_vikramsa at quicinc.com/

Changes in V3:
- Added missed subject line for cover letter of V2.
- Updated Alignment, indentation and properties order.
- edit commit text for [PATCH 02/10] and [PATCH 03/10].
- Refactor camss_link_entities.
- Removed camcc enablement changes as it already done.
- Link to v2: https://lore.kernel.org/linux-arm-msm/20240904-camss_on_sc7280_rb3gen2_vision_v2_patches-v1-0-b18ddcd7d9df at quicinc.com/

Changes in V2:
- Improved indentation/formatting.
- Removed _src clocks and misleading code comments.
- Added name fields for power domains and csid register offset in DTSI.
- Dropped minItems field from YAML file.
- Listed changes in alphabetical order.
- Updated description and commit text to reflect changes
- Changed the compatible string from imx412 to imx577.
- Added board-specific enablement changes in the newly created vision
  board DTSI file.
- Fixed bug encountered during testing.
- Moved logically independent changes to a new/seprate patch.
- Removed cci0 as no sensor is on this port and MCLK2, which was a
  copy-paste error from the RB5 board reference.
- Added power rails, referencing the RB5 board.
- Discarded Patch 5/6 completely (not required).
- Removed unused enums.
- Link to v1: https://lore.kernel.org/linux-arm-msm/20240629-camss_first_post_linux_next-v1-0-bc798edabc3a at quicinc.com/

Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>

Vikram Sharma (4):
  media: dt-bindings: update clocks for sc7280-camss
  media: qcom: camss: update clock names for sc7280
  arm64: dts: qcom: sc7280: Add support for camss
  arm64: dts: qcom: qcs6490-rb3gen2-vision-mezzanine: Add vision
    mezzanine

 .../bindings/media/qcom,sc7280-camss.yaml     |  10 +-
 arch/arm64/boot/dts/qcom/Makefile             |   4 +
 .../qcs6490-rb3gen2-vision-mezzanine.dtso     | 109 +++++++++++
 arch/arm64/boot/dts/qcom/sc7280.dtsi          | 178 ++++++++++++++++++
 drivers/media/platform/qcom/camss/camss.c     |  15 +-
 5 files changed, 306 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso

-- 
2.25.1



From quic_vikramsa at quicinc.com  Tue Dec 17 05:39:52 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:09:52 +0530
Subject: [PATCH v9 1/4] media: dt-bindings: update clocks for sc7280-camss
In-Reply-To: <20241217133955.946426-1-quic_vikramsa@quicinc.com>
References: <20241217133955.946426-1-quic_vikramsa@quicinc.com>
Message-ID: <20241217133955.946426-2-quic_vikramsa@quicinc.com>

This patch change clock names to make it consistent with
existing platforms as gcc_cam_hf_axi -> gcc_axi_hf.
This also adds gcc_axi_sf and remove gcc_camera_ahb.

Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
---
 .../devicetree/bindings/media/qcom,sc7280-camss.yaml   | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
index e11141b812a0..ee35e3bc97ff 100644
--- a/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
@@ -55,8 +55,8 @@ properties:
       - const: csiphy3_timer
       - const: csiphy4
       - const: csiphy4_timer
-      - const: gcc_camera_ahb
-      - const: gcc_cam_hf_axi
+      - const: gcc_axi_hf
+      - const: gcc_axi_sf
       - const: icp_ahb
       - const: vfe0
       - const: vfe0_axi
@@ -310,8 +310,8 @@ examples:
                      <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
                      <&camcc CAM_CC_CSIPHY4_CLK>,
                      <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
-                     <&gcc GCC_CAMERA_AHB_CLK>,
                      <&gcc GCC_CAMERA_HF_AXI_CLK>,
+                     <&gcc GCC_CAMERA_SF_AXI_CLK>,
                      <&camcc CAM_CC_ICP_AHB_CLK>,
                      <&camcc CAM_CC_IFE_0_CLK>,
                      <&camcc CAM_CC_IFE_0_AXI_CLK>,
@@ -343,8 +343,8 @@ examples:
                           "csiphy3_timer",
                           "csiphy4",
                           "csiphy4_timer",
-                          "gcc_camera_ahb",
-                          "gcc_cam_hf_axi",
+                          "gcc_axi_hf",
+                          "gcc_axi_sf",
                           "icp_ahb",
                           "vfe0",
                           "vfe0_axi",
-- 
2.25.1



From quic_vikramsa at quicinc.com  Tue Dec 17 05:39:53 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:09:53 +0530
Subject: [PATCH v9 2/4] media: qcom: camss: update clock names for sc7280
In-Reply-To: <20241217133955.946426-1-quic_vikramsa@quicinc.com>
References: <20241217133955.946426-1-quic_vikramsa@quicinc.com>
Message-ID: <20241217133955.946426-3-quic_vikramsa@quicinc.com>

This patch changes gcc_cam_hf_axi clock name to make consistent
with existing platforms and add gcc_axi_sf clock too.
gcc_cam_hf_axi changed to gcc_axi_hf.
added gcc_axi_sf.

Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
---
 drivers/media/platform/qcom/camss/camss.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 004a74f6b2f6..1d992dc74877 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1443,12 +1443,13 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 		.regulators = {},
 
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0",
-			   "vfe0_axi", "gcc_cam_hf_axi" },
+			   "vfe0_axi", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 380000000, 510000000, 637000000, 760000000 },
 				{ 0 },
+				{ 0 },
 				{ 0 } },
 
 		.reg = { "vfe0" },
@@ -1468,12 +1469,13 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 		.regulators = {},
 
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe1",
-			   "vfe1_axi", "gcc_cam_hf_axi" },
+			   "vfe1_axi", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 380000000, 510000000, 637000000, 760000000 },
 				{ 0 },
+				{ 0 },
 				{ 0 } },
 
 		.reg = { "vfe1" },
@@ -1493,12 +1495,13 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 		.regulators = {},
 
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe2",
-			   "vfe2_axi", "gcc_cam_hf_axi" },
+			   "vfe2_axi", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 380000000, 510000000, 637000000, 760000000 },
 				{ 0 },
+				{ 0 },
 				{ 0 } },
 
 		.reg = { "vfe2" },
@@ -1516,11 +1519,12 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 	/* VFE3 (lite) */
 	{
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
-			   "vfe_lite0", "gcc_cam_hf_axi" },
+			   "vfe_lite0", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 320000000, 400000000, 480000000, 600000000 },
+				{ 0 },
 				{ 0 } },
 
 		.regulators = {},
@@ -1537,11 +1541,12 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 	/* VFE4 (lite) */
 	{
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
-			   "vfe_lite1", "gcc_cam_hf_axi" },
+			   "vfe_lite1", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 320000000, 400000000, 480000000, 600000000 },
+				{ 0 },
 				{ 0 } },
 
 		.regulators = {},
-- 
2.25.1



From linus.walleij at linaro.org  Tue Dec 17 05:45:19 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Dec 2024 14:45:19 +0100
Subject: [PATCH] v1 pinctrl: mtk-eint: add eint new design for mt8196
In-Reply-To: <20241203131302.16022-1-ot_chhao.chang@mediatek.com>
References: <20241203131302.16022-1-ot_chhao.chang@mediatek.com>
Message-ID: <CACRpkdZy7HgkT-FFJh=ubXhdcBRa-vbaNmHC32E3djZdHnwdYg@mail.gmail.com>

Hi Chang,

thanks for your patch!

On Tue, Dec 3, 2024 at 2:13?PM chang hao <ot_chhao.chang at mediatek.com> wrote:

> From: Chhao Chang <ot_chhao.chang at mediatek.com>
>
> Change 1: change EINT from 1 address to 5 addresses,
> Eint number is stored on each base.
> Change 2: Compatible with 1 address design
>
> Signed-off-by: Chhao Chang <ot_chhao.chang at mediatek.com>

This patch looks good to me, as preparation for mt8196,
but can one of the Mediatek experts please
review it? If nothing happens I will just apply it I guess...

Yours,
Linus Walleij


From linus.walleij at linaro.org  Tue Dec 17 05:51:43 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Dec 2024 14:51:43 +0100
Subject: [PATCH] pinctrl: nomadik: Add check for clk_enable()
In-Reply-To: <20241205042214.2410982-1-zmw12306@gmail.com>
References: <20241205042214.2410982-1-zmw12306@gmail.com>
Message-ID: <CACRpkdbcn8FD8v8PYv9g5JObC3ty+6xvKKCpS2uc3WKYXcmLiA@mail.gmail.com>

On Thu, Dec 5, 2024 at 5:19?AM Mingwei Zheng <zmw12306 at gmail.com> wrote:

> Add check for the return value of clk_enable() to catch the potential
> error. Change return type of nmk_gpio_glitch_slpm_init casade.
>
> Fixes: 3a19805920f1 ("pinctrl: nomadik: move all Nomadik drivers to subdir")
> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>

Looks correct, patch applied.
Thanks Mingwei!

Yours,
Linus Walleij


From maz at kernel.org  Tue Dec 17 05:54:39 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 13:54:39 +0000
Subject: [PATCH] KVM: arm64: Fix set_id_regs selftest for ASIDBITS becoming unwritable
In-Reply-To: <53b40aa8-f51c-4c4e-a4ad-e6a9512e5197@sirena.org.uk>
References: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
	<875xnisocy.wl-maz@kernel.org>
	<53b40aa8-f51c-4c4e-a4ad-e6a9512e5197@sirena.org.uk>
Message-ID: <86v7viqusg.wl-maz@kernel.org>

On Tue, 17 Dec 2024 13:12:12 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> [1  <text/plain; us-ascii (7bit)>]
> On Tue, Dec 17, 2024 at 08:30:37AM +0000, Marc Zyngier wrote:
> > Mark Brown <broonie at kernel.org> wrote:
> 
> > > Fixes: 03c7527e97f7 ("KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden")
> 
> > A patch for a test doesn't fix anything in the kernel.
> 
> The selftests are shipped as part of the kernel source and frequently
> used for testing the kernel, it's all one source base and we want to
> ensure that for example the test fix gets backported if the relevant
> kernel patch does.

That's not what Fixes: describes. If you want to invent a new tag that
expresses a dependency, do that. Don't use these tags to misrepresent
what the patches does.

	M.

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


From mripard at kernel.org  Tue Dec 17 05:58:52 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 14:58:52 +0100
Subject: [PATCH] pinctrl: sunxi: Use minimal debouncing period as default
In-Reply-To: <CACRpkdbcDwJaLmCa_YoP2zFw3fiWn-d1Q773jGh9kcVN8aWQKQ@mail.gmail.com>
References: <20241119140805.3345412-1-paulk@sys-base.io>
 <20241119-prudent-jasmine-lizard-195cef@houat>
 <CACRpkdbcDwJaLmCa_YoP2zFw3fiWn-d1Q773jGh9kcVN8aWQKQ@mail.gmail.com>
Message-ID: <20241217-impossible-chameleon-of-flowers-8ce18a@houat>

On Tue, Dec 17, 2024 at 02:41:36PM +0100, Linus Walleij wrote:
> On Tue, Nov 19, 2024 at 3:43?PM Maxime Ripard <mripard at kernel.org> wrote:
> 
> > [Paul]
> > > The pinctrl code supports an input-debounce device-tree property to set
> > > a specific debouncing period and choose which clock source is most
> > > relevant. However the property is specified in microseconds, which is
> > > longer than the minimal period achievable from the high-frequency
> > > oscillator without a pre-scaler.
> >
> > That can be fixed by introducing a new property with a ns resolution.
> 
> Perhaps, but I think a setting of 0 should just yield the minimum
> resolution in this case, as apparently the debounce cannot be
> turned off? This would also make sense to expose for
> gpiod_set_debounce() as explained in my other mail.

Yeah, if we want to have 0 == lowest resolution, I'm all for it.

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

From maz at kernel.org  Tue Dec 17 06:03:37 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:03:37 +0000
Subject: [PATCH v3 18/18] KVM: arm64: Plumb the pKVM MMU in KVM
In-Reply-To: <20241216175803.2716565-19-qperret@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
	<20241216175803.2716565-19-qperret@google.com>
Message-ID: <86ttb2qudi.wl-maz@kernel.org>

On Mon, 16 Dec 2024 17:58:03 +0000,
Quentin Perret <qperret at google.com> wrote:
> 
> Introduce the KVM_PGT_S2() helper macro to allow switching from the
> traditional pgtable code to the pKVM version easily in mmu.c. The cost
> of this 'indirection' is expected to be very minimal due to
> is_protected_kvm_enabled() being backed by a static key.
> 
> With this, everything is in place to allow the delegation of
> non-protected guest stage-2 page-tables to pKVM, so let's stop using the
> host's kvm_s2_mmu from EL2 and enjoy the ride.
> 
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_mmu.h   |  16 +++++
>  arch/arm64/kvm/arm.c               |   9 ++-
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c |   2 -
>  arch/arm64/kvm/mmu.c               | 107 +++++++++++++++++++++--------
>  4 files changed, 101 insertions(+), 33 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index 66d93e320ec8..d116ab4230e8 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -353,6 +353,22 @@ static inline bool kvm_is_nested_s2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
>  	return &kvm->arch.mmu != mmu;
>  }
>  
> +static inline void kvm_fault_lock(struct kvm *kvm)
> +{
> +	if (is_protected_kvm_enabled())
> +		write_lock(&kvm->mmu_lock);
> +	else
> +		read_lock(&kvm->mmu_lock);
> +}
> +
> +static inline void kvm_fault_unlock(struct kvm *kvm)
> +{
> +	if (is_protected_kvm_enabled())
> +		write_unlock(&kvm->mmu_lock);
> +	else
> +		read_unlock(&kvm->mmu_lock);
> +}
> +
>  #ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
>  void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
>  #else
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 55cc62b2f469..9bcbc7b8ed38 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -502,7 +502,10 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
>  
>  void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
>  {
> -	kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
> +	if (!is_protected_kvm_enabled())
> +		kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
> +	else
> +		free_hyp_memcache(&vcpu->arch.pkvm_memcache);
>  	kvm_timer_vcpu_terminate(vcpu);
>  	kvm_pmu_vcpu_destroy(vcpu);
>  	kvm_vgic_vcpu_destroy(vcpu);
> @@ -574,6 +577,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  	struct kvm_s2_mmu *mmu;
>  	int *last_ran;
>  
> +	if (is_protected_kvm_enabled())
> +		goto nommu;
> +
>  	if (vcpu_has_nv(vcpu))
>  		kvm_vcpu_load_hw_mmu(vcpu);
>  
> @@ -594,6 +600,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  		*last_ran = vcpu->vcpu_idx;
>  	}
>  
> +nommu:
>  	vcpu->cpu = cpu;
>  
>  	kvm_vgic_load(vcpu);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 130f5f23bcb5..258d572eed62 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -103,8 +103,6 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
>  	/* Limit guest vector length to the maximum supported by the host.  */
>  	hyp_vcpu->vcpu.arch.sve_max_vl	= min(host_vcpu->arch.sve_max_vl, kvm_host_sve_max_vl);
>  
> -	hyp_vcpu->vcpu.arch.hw_mmu	= host_vcpu->arch.hw_mmu;
> -
>  	hyp_vcpu->vcpu.arch.mdcr_el2	= host_vcpu->arch.mdcr_el2;
>  	hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE);
>  	hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2) &
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 641e4fec1659..7c2995cb4577 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -15,6 +15,7 @@
>  #include <asm/kvm_arm.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/kvm_pgtable.h>
> +#include <asm/kvm_pkvm.h>
>  #include <asm/kvm_ras.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_emulate.h>
> @@ -31,6 +32,14 @@ static phys_addr_t __ro_after_init hyp_idmap_vector;
>  
>  static unsigned long __ro_after_init io_map_base;
>  
> +#define KVM_PGT_S2(fn, ...)								\
> +	({										\
> +		typeof(kvm_pgtable_stage2_ ## fn) *__fn = kvm_pgtable_stage2_ ## fn;	\
> +		if (is_protected_kvm_enabled())						\
> +			__fn = pkvm_pgtable_ ## fn;					\
> +		__fn(__VA_ARGS__);							\
> +	})
> +

My gripe with this is that it makes it much harder to follow what is
happening by using tags (ctags, etags, whatever). I ended up with the
hack below, which is super ugly, but preserves the tagging
functionality for non-pKVM.

I'll scratch my head to find something more elegant...

	M.

diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 76a8b70176a6c..b9b9acb685d8f 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -143,21 +143,21 @@ struct pkvm_mapping {
 	u64 pfn;
 };
 
-int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops);
-void pkvm_pgtable_destroy(struct kvm_pgtable *pgt);
-int pkvm_pgtable_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
+int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops);
+void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
+int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
 			   u64 phys, enum kvm_pgtable_prot prot,
 			   void *mc, enum kvm_pgtable_walk_flags flags);
-int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
-int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
-int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
-bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold);
-int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
+int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
+int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
+int pkvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
+bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold);
+int pkvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
 			     enum kvm_pgtable_walk_flags flags);
-void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags);
-int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc);
-void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level);
-kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
+void pkvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags);
+int pkvm_pgtable_stage2_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc);
+void pkvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level);
+kvm_pte_t *pkvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
 					enum kvm_pgtable_prot prot, void *mc, bool force_pte);
 
 #endif	/* __ARM64_KVM_PKVM_H__ */
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 7c2995cb45773..4b9153468a327 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -32,12 +32,13 @@ static phys_addr_t __ro_after_init hyp_idmap_vector;
 
 static unsigned long __ro_after_init io_map_base;
 
-#define KVM_PGT_S2(fn, ...)								\
-	({										\
-		typeof(kvm_pgtable_stage2_ ## fn) *__fn = kvm_pgtable_stage2_ ## fn;	\
-		if (is_protected_kvm_enabled())						\
-			__fn = pkvm_pgtable_ ## fn;					\
-		__fn(__VA_ARGS__);							\
+#define __S2(fn, ...)							\
+	({								\
+		typeof(fn) *__fn = fn;					\
+		/* upgrade the function name from kvm_* to pkvm_* */	\
+		if (is_protected_kvm_enabled())				\
+			__fn = p ## fn;					\
+		__fn(__VA_ARGS__);					\
 	})
 
 static phys_addr_t __stage2_range_addr_end(phys_addr_t addr, phys_addr_t end,
@@ -156,7 +157,7 @@ static int kvm_mmu_split_huge_pages(struct kvm *kvm, phys_addr_t addr,
 			return -EINVAL;
 
 		next = __stage2_range_addr_end(addr, end, chunk_size);
-		ret = KVM_PGT_S2(split, pgt, addr, next - addr, cache);
+		ret = __S2(kvm_pgtable_stage2_split, pgt, addr, next - addr, cache);
 		if (ret)
 			break;
 	} while (addr = next, addr != end);
@@ -242,7 +243,7 @@ static void stage2_free_unlinked_table_rcu_cb(struct rcu_head *head)
 	void *pgtable = page_to_virt(page);
 	s8 level = page_private(page);
 
-	KVM_PGT_S2(free_unlinked, &kvm_s2_mm_ops, pgtable, level);
+	__S2(kvm_pgtable_stage2_free_unlinked, &kvm_s2_mm_ops, pgtable, level);
 }
 
 static void stage2_free_unlinked_table(void *addr, s8 level)
@@ -299,7 +300,7 @@ static void invalidate_icache_guest_page(void *va, size_t size)
 
 static int kvm_s2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
 {
-	return KVM_PGT_S2(unmap, pgt, addr, size);
+	return __S2(kvm_pgtable_stage2_unmap, pgt, addr, size);
 }
 
 /*
@@ -357,7 +358,7 @@ void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
 
 static int kvm_s2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
 {
-	return KVM_PGT_S2(flush, pgt, addr, size);
+	return __S2(kvm_pgtable_stage2_flush, pgt, addr, size);
 }
 
 void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
@@ -968,7 +969,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 		return -ENOMEM;
 
 	mmu->arch = &kvm->arch;
-	err = KVM_PGT_S2(init, pgt, mmu, &kvm_s2_mm_ops);
+	err = __S2(kvm_pgtable_stage2_init, pgt, mmu, &kvm_s2_mm_ops);
 	if (err)
 		goto out_free_pgtable;
 
@@ -997,7 +998,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 	return 0;
 
 out_destroy_pgtable:
-	KVM_PGT_S2(destroy, pgt);
+	__S2(kvm_pgtable_stage2_destroy, pgt);
 out_free_pgtable:
 	kfree(pgt);
 	return err;
@@ -1094,7 +1095,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
 	write_unlock(&kvm->mmu_lock);
 
 	if (pgt) {
-		KVM_PGT_S2(destroy, pgt);
+		__S2(kvm_pgtable_stage2_destroy, pgt);
 		kfree(pgt);
 	}
 }
@@ -1167,7 +1168,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 			break;
 
 		write_lock(&kvm->mmu_lock);
-		ret = KVM_PGT_S2(map, pgt, addr, PAGE_SIZE, pa, prot, &cache, 0);
+		ret = __S2(kvm_pgtable_stage2_map, pgt, addr, PAGE_SIZE, pa, prot, &cache, 0);
 		write_unlock(&kvm->mmu_lock);
 		if (ret)
 			break;
@@ -1181,7 +1182,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 
 static int kvm_s2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
 {
-	return KVM_PGT_S2(wrprotect, pgt, addr, size);
+	return __S2(kvm_pgtable_stage2_wrprotect, pgt, addr, size);
 }
 /**
  * kvm_stage2_wp_range() - write protect stage2 memory region range
@@ -1743,9 +1744,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		 * PTE, which will be preserved.
 		 */
 		prot &= ~KVM_NV_GUEST_MAP_SZ;
-		ret = KVM_PGT_S2(relax_perms, pgt, fault_ipa, prot, flags);
+		ret = __S2(kvm_pgtable_stage2_relax_perms, pgt, fault_ipa, prot, flags);
 	} else {
-		ret = KVM_PGT_S2(map, pgt, fault_ipa, vma_pagesize,
+		ret = __S2(kvm_pgtable_stage2_map, pgt, fault_ipa, vma_pagesize,
 					     __pfn_to_phys(pfn), prot,
 					     memcache, flags);
 	}
@@ -1771,7 +1772,7 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 
 	read_lock(&vcpu->kvm->mmu_lock);
 	mmu = vcpu->arch.hw_mmu;
-	KVM_PGT_S2(mkyoung, mmu->pgt, fault_ipa, flags);
+	__S2(kvm_pgtable_stage2_mkyoung, mmu->pgt, fault_ipa, flags);
 	read_unlock(&vcpu->kvm->mmu_lock);
 }
 
@@ -1977,7 +1978,7 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
-	return KVM_PGT_S2(test_clear_young, kvm->arch.mmu.pgt,
+	return __S2(kvm_pgtable_stage2_test_clear_young, kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, true);
 	/*
@@ -1993,7 +1994,7 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
-	return KVM_PGT_S2(test_clear_young, kvm->arch.mmu.pgt,
+	return __S2(kvm_pgtable_stage2_test_clear_young, kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, false);
 }
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index 9de9159afa5a1..37d6494d0fd87 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -317,7 +317,7 @@ static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
 			break;										\
 		else
 
-int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops)
+int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kvm_pgtable_mm_ops *mm_ops)
 {
 	pgt->pkvm_mappings	= RB_ROOT;
 	pgt->mmu		= mmu;
@@ -325,7 +325,7 @@ int pkvm_pgtable_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu, struct kv
 	return 0;
 }
 
-void pkvm_pgtable_destroy(struct kvm_pgtable *pgt)
+void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt)
 {
 	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
 	pkvm_handle_t handle = kvm->arch.pkvm.handle;
@@ -345,7 +345,7 @@ void pkvm_pgtable_destroy(struct kvm_pgtable *pgt)
 	}
 }
 
-int pkvm_pgtable_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
+int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
 			   u64 phys, enum kvm_pgtable_prot prot,
 			   void *mc, enum kvm_pgtable_walk_flags flags)
 {
@@ -375,7 +375,7 @@ int pkvm_pgtable_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
 	return ret;
 }
 
-int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
+int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
 {
 	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
 	pkvm_handle_t handle = kvm->arch.pkvm.handle;
@@ -394,7 +394,7 @@ int pkvm_pgtable_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
 	return ret;
 }
 
-int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
+int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
 {
 	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
 	pkvm_handle_t handle = kvm->arch.pkvm.handle;
@@ -411,7 +411,7 @@ int pkvm_pgtable_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
 	return ret;
 }
 
-int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
+int pkvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
 {
 	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
 	struct pkvm_mapping *mapping;
@@ -423,7 +423,7 @@ int pkvm_pgtable_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
 	return 0;
 }
 
-bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold)
+bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold)
 {
 	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
 	pkvm_handle_t handle = kvm->arch.pkvm.handle;
@@ -438,30 +438,30 @@ bool pkvm_pgtable_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size,
 	return young;
 }
 
-int pkvm_pgtable_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
+int pkvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
 			     enum kvm_pgtable_walk_flags flags)
 {
 	return kvm_call_hyp_nvhe(__pkvm_host_relax_perms_guest, addr >> PAGE_SHIFT, prot);
 }
 
-void pkvm_pgtable_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags)
+void pkvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_walk_flags flags)
 {
 	WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_mkyoung_guest, addr >> PAGE_SHIFT));
 }
 
-void pkvm_pgtable_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
+void pkvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
 {
 	WARN_ON_ONCE(1);
 }
 
-kvm_pte_t *pkvm_pgtable_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
+kvm_pte_t *pkvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
 					enum kvm_pgtable_prot prot, void *mc, bool force_pte)
 {
 	WARN_ON_ONCE(1);
 	return NULL;
 }
 
-int pkvm_pgtable_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc)
+int pkvm_pgtable_stage2_split(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_mmu_memory_cache *mc)
 {
 	WARN_ON_ONCE(1);
 	return -EINVAL;

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


From linus.walleij at linaro.org  Tue Dec 17 06:07:00 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Dec 2024 15:07:00 +0100
Subject: [PATCH v2] pinctrl: nomadik: Add check for clk_enable()
In-Reply-To: <20241206221618.3453159-1-zmw12306@gmail.com>
References: <20241206221618.3453159-1-zmw12306@gmail.com>
Message-ID: <CACRpkdZrkt7R+NzjQmo60M9sMom_f4SRU8+g+=UEq7hqG9pKJw@mail.gmail.com>

On Fri, Dec 6, 2024 at 11:13?PM Mingwei Zheng <zmw12306 at gmail.com> wrote:

> Add check for the return value of clk_enable() to catch the potential
> error.
> Disable success clks in the error handling.
> Change return type of nmk_gpio_glitch_slpm_init casade.
>
> Fixes: 3a19805920f1 ("pinctrl: nomadik: move all Nomadik drivers to subdir")
> Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
> Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>

Oh I took out v1 and applied this instead, I didn't see the bug
but luckily you did!

Yours,
Linus Walleij


From quic_vikramsa at quicinc.com  Tue Dec 17 06:06:52 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:36:52 +0530
Subject: [PATCH v10 0/4] media: qcom: camss: Add sc7280 support
Message-ID: <20241217140656.965235-1-quic_vikramsa@quicinc.com>

SC7280 is a Qualcomm SoC. This series adds support to bring up the CSIPHY,
CSID, VFE/RDI interfaces in SC7280.

SC7280 provides

- 3 x VFE, 3 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE
- 3 x CSID
- 2 x CSID Lite
- 5 x CSI PHY

We have tested this on qcs6490-rb3gen2-vision-mezzanine board having IMX577
sensor. Verified both TPG and IMX577 sensor.

Used following tools for the sanity check of these changes.

- make CHECK_DTBS=y W=1 DT_SCHEMA_FILES=media/qcom,sc7280-camss.yaml
qcom/qcs6490-rb3gen2-vision-mezzanine.dtb
- make DT_CHECKER_FLAGS=-m W=1
DT_SCHEMA_FILES=media/qcom,sc7280-camss.yaml dt_binding_check
- Smatch: make CHECK="smatch --full-path"
M=drivers/media/platform/qcom/camss/
- Sparse: make C=2 M=drivers/media/platform/qcom/camss/
- coccicheck : make coccicheck M=drivers/media/platform/qcom/camss/
- make -j32 W=1
- ./scripts/checkpatch.pl
 
Changes in V10:
- Updated cover letter to add link for v8 under changes in v9.
- No change in the patches w.r.t V9
- Link to v9: https://lore.kernel.org/linux-arm-msm/20241217133955.946426-1-quic_vikramsa at quicinc.com/

Changes in V9:
- Removed GCC_CAMERA_AHB_CLK as its always enabled.
- Added GCC_CAMERA_SF_AXI_CLK.
- Renamed gcc_cam_hf_axi to gcc_axi_hf.
- V8 had 5 patches and V9 have 4 patches.
- First 3 patches of V8 are already promoted to linux-next
i.e  
  media: dt-bindings: Add qcom,sc7280-camss
  media: qcom: camss: Sort camss version enums and compatible strings
  media: qcom: camss: Add support for camss driver on sc7280
- 2 new patches are added to handle new comments from Konrad on
  "Patch v8 4/5 arm64: dts: qcom: sc7280: Add support for camss" 
  1 of the 2 new patches make changes in yaml and other one is making
  change in camss driver to handle new comments in dtsi.
- for "Patch v8 4/5 arm64: dts: qcom: sc7280: Add support for camss" I got
  comments from Konrad to make changes for clock names so I had to make
  respective changes in "bindings/media/qcom,sc7280-camss.yaml". As dtsi
  changes are not merged yet, so there is no issues with backward
  compatibility and I am assuming this should be acceptable.
- Link to v8: https://lore.kernel.org/linux-arm-msm/20241206191900.2545069-1-quic_vikramsa at quicinc.com/
  
Changes in V8:
- Changed node name from camss to isp.
- Added QCOM_ICC_TAG_ACTIVE_ONLY and QCOM_ICC_TAG_ALWAYS tags for
  interconnects. 
- Added blank lines when required.
- Modified power-domain-names from horizontal to vertical list.
- Sorted pinctrl nodes based on gpio index.
- Link to v7: https://lore.kernel.org/linux-arm-msm/20241204100003.300123-1-quic_vikramsa at quicinc.com/

Changes in V7:
- Changed unit address for camss in documention and dts.
- Added avdd-supply and dvdd-supply for sensor.
- Changed reg/clocks/interrupts name for vfe_lite and csid_lite.
- Link to v6: https://lore.kernel.org/linux-arm-msm/20241127100421.3447601-1-quic_vikramsa at quicinc.com/

Changes in V6:
- Changed order of properties in Documentation [PATCH 1/5].
- Updated description for ports in Documentaion [PATCH 1/5].
- Moved regulators from csid to csiphy [PATCH 3/5].
- Link to v5: https://lore.kernel.org/linux-arm-msm/20241112173032.2740119-1-quic_vikramsa at quicinc.com/ 

Changes in V5:
- Updated Commit text for [PATCH v5 1/6].
- Moved reg after compatible string.
- Renamed csi'x' clocks to vfe'x'_csid
- Removed [PATCH v4 4/6] and raised a seprate series for this one.
- Moved gpio states to mezzanine dtso.
- Added more clock levels to address TPG related issues.
- Renamed power-domains-names -> power-domain-names. 
- Link to v4: https://lore.kernel.org/linux-arm-msm/20241030105347.2117034-1-quic_vikramsa at quicinc.com/ 

Changes in V4:
- V3 had 8 patches and V4 is reduced to 6.
- Removed [Patch v3 2/8] as binding change is not required for dtso.
- Removed [Patch v3 3/8] as the fix is already taken care in latest
  kernel tip. 
- Updated alignment for dtsi and dt-bindings.
- Adding qcs6490-rb3gen2-vision-mezzanine as overlay. 
- Link to v3: https://lore.kernel.org/linux-arm-msm/20241011140932.1744124-1-quic_vikramsa at quicinc.com/

Changes in V3:
- Added missed subject line for cover letter of V2.
- Updated Alignment, indentation and properties order.
- edit commit text for [PATCH 02/10] and [PATCH 03/10].
- Refactor camss_link_entities.
- Removed camcc enablement changes as it already done.
- Link to v2: https://lore.kernel.org/linux-arm-msm/20240904-camss_on_sc7280_rb3gen2_vision_v2_patches-v1-0-b18ddcd7d9df at quicinc.com/

Changes in V2:
- Improved indentation/formatting.
- Removed _src clocks and misleading code comments.
- Added name fields for power domains and csid register offset in DTSI.
- Dropped minItems field from YAML file.
- Listed changes in alphabetical order.
- Updated description and commit text to reflect changes
- Changed the compatible string from imx412 to imx577.
- Added board-specific enablement changes in the newly created vision
  board DTSI file.
- Fixed bug encountered during testing.
- Moved logically independent changes to a new/seprate patch.
- Removed cci0 as no sensor is on this port and MCLK2, which was a
  copy-paste error from the RB5 board reference.
- Added power rails, referencing the RB5 board.
- Discarded Patch 5/6 completely (not required).
- Removed unused enums.
- Link to v1: https://lore.kernel.org/linux-arm-msm/20240629-camss_first_post_linux_next-v1-0-bc798edabc3a at quicinc.com/

Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>

Vikram Sharma (4):
  media: dt-bindings: update clocks for sc7280-camss
  media: qcom: camss: update clock names for sc7280
  arm64: dts: qcom: sc7280: Add support for camss
  arm64: dts: qcom: qcs6490-rb3gen2-vision-mezzanine: Add vision
    mezzanine

 .../bindings/media/qcom,sc7280-camss.yaml     |  10 +-
 arch/arm64/boot/dts/qcom/Makefile             |   4 +
 .../qcs6490-rb3gen2-vision-mezzanine.dtso     | 109 +++++++++++
 arch/arm64/boot/dts/qcom/sc7280.dtsi          | 178 ++++++++++++++++++
 drivers/media/platform/qcom/camss/camss.c     |  15 +-
 5 files changed, 306 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso

-- 
2.25.1



From quic_vikramsa at quicinc.com  Tue Dec 17 06:06:53 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:36:53 +0530
Subject: [PATCH v10 1/4] media: dt-bindings: update clocks for sc7280-camss
In-Reply-To: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
Message-ID: <20241217140656.965235-2-quic_vikramsa@quicinc.com>

This patch change clock names to make it consistent with
existing platforms as gcc_cam_hf_axi -> gcc_axi_hf.
This also adds gcc_axi_sf and remove gcc_camera_ahb.

Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
---
 .../devicetree/bindings/media/qcom,sc7280-camss.yaml   | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
index e11141b812a0..ee35e3bc97ff 100644
--- a/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
@@ -55,8 +55,8 @@ properties:
       - const: csiphy3_timer
       - const: csiphy4
       - const: csiphy4_timer
-      - const: gcc_camera_ahb
-      - const: gcc_cam_hf_axi
+      - const: gcc_axi_hf
+      - const: gcc_axi_sf
       - const: icp_ahb
       - const: vfe0
       - const: vfe0_axi
@@ -310,8 +310,8 @@ examples:
                      <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
                      <&camcc CAM_CC_CSIPHY4_CLK>,
                      <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
-                     <&gcc GCC_CAMERA_AHB_CLK>,
                      <&gcc GCC_CAMERA_HF_AXI_CLK>,
+                     <&gcc GCC_CAMERA_SF_AXI_CLK>,
                      <&camcc CAM_CC_ICP_AHB_CLK>,
                      <&camcc CAM_CC_IFE_0_CLK>,
                      <&camcc CAM_CC_IFE_0_AXI_CLK>,
@@ -343,8 +343,8 @@ examples:
                           "csiphy3_timer",
                           "csiphy4",
                           "csiphy4_timer",
-                          "gcc_camera_ahb",
-                          "gcc_cam_hf_axi",
+                          "gcc_axi_hf",
+                          "gcc_axi_sf",
                           "icp_ahb",
                           "vfe0",
                           "vfe0_axi",
-- 
2.25.1



From maz at kernel.org  Tue Dec 17 06:06:15 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:06:15 +0000
Subject: [PATCH v3 11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
In-Reply-To: <Z2F9xb4jrK1zRtNV@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
	<20241216175803.2716565-12-qperret@google.com>
	<86wmfyr1j4.wl-maz@kernel.org>
	<Z2F9xb4jrK1zRtNV@google.com>
Message-ID: <86seqmqu94.wl-maz@kernel.org>

On Tue, 17 Dec 2024 13:33:57 +0000,
Quentin Perret <qperret at google.com> wrote:
> 
> On Tuesday 17 Dec 2024 at 11:29:03 (+0000), Marc Zyngier wrote:
> > > +static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)
> > > +{
> > > +	enum pkvm_page_state state;
> > > +	struct hyp_page *page;
> > > +	kvm_pte_t pte;
> > > +	u64 phys;
> > > +	s8 level;
> > > +	int ret;
> > > +
> > > +	ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
> > > +	if (ret)
> > > +		return ret;
> > > +	if (level != KVM_PGTABLE_LAST_LEVEL)
> > 
> > So there is still a very strong assumption that a guest is only
> > provided page mappings, and no blocks?
> 
> Yep, very much so. It's one of the main limitations of the series as-is
> (with the absence of support for mapping anything else than memory in
> guests). Those limitations were mentioned in the cover letter of v1, but
> I should have kept that mention in later versions, sorry!
> 
> The last patch of the series has a tweak to user_mem_abort() to force
> mappings to PTE level which is trivial to do as we already need to do
> similar things for dirty logging. And __pkvm_host_share_guest() doesn't
> take a 'size' parameter in its current form, it assumes it is being
> passed a single pfn. So all in all this works well, and simplifies the
> series a lot.
> 
> Huge-page support should come as a natural extension to this series, but
> I was hoping it could be done separately as that should have no
> *functional* impact observable from userspace. I'm slightly more
> concerned about the lack of support for mapping MMIO, but that too is
> going to be some work, and I guess you should just turn pKVM off if
> you want that for now...
> 
> Happy to address either or both of these limitations as part of this
> series if we think they're strictly required to land this stuff
> upstream, this is obviously up for debate. But that's going to be quite
> a few patches on top :-)

No, I just wanted to make sure I did have the correct interpretation
of what this does. 'd rather have something that works first, and then
add large mapping support. You can even sell it as a performance
improvement! :)

Thanks,

	M.

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


From quic_vikramsa at quicinc.com  Tue Dec 17 06:06:54 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:36:54 +0530
Subject: [PATCH v10 2/4] media: qcom: camss: update clock names for sc7280
In-Reply-To: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
Message-ID: <20241217140656.965235-3-quic_vikramsa@quicinc.com>

This patch changes gcc_cam_hf_axi clock name to make consistent
with existing platforms and add gcc_axi_sf clock too.
gcc_cam_hf_axi changed to gcc_axi_hf.
added gcc_axi_sf.

Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
---
 drivers/media/platform/qcom/camss/camss.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 004a74f6b2f6..1d992dc74877 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1443,12 +1443,13 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 		.regulators = {},
 
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0",
-			   "vfe0_axi", "gcc_cam_hf_axi" },
+			   "vfe0_axi", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 380000000, 510000000, 637000000, 760000000 },
 				{ 0 },
+				{ 0 },
 				{ 0 } },
 
 		.reg = { "vfe0" },
@@ -1468,12 +1469,13 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 		.regulators = {},
 
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe1",
-			   "vfe1_axi", "gcc_cam_hf_axi" },
+			   "vfe1_axi", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 380000000, 510000000, 637000000, 760000000 },
 				{ 0 },
+				{ 0 },
 				{ 0 } },
 
 		.reg = { "vfe1" },
@@ -1493,12 +1495,13 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 		.regulators = {},
 
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe2",
-			   "vfe2_axi", "gcc_cam_hf_axi" },
+			   "vfe2_axi", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 380000000, 510000000, 637000000, 760000000 },
 				{ 0 },
+				{ 0 },
 				{ 0 } },
 
 		.reg = { "vfe2" },
@@ -1516,11 +1519,12 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 	/* VFE3 (lite) */
 	{
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
-			   "vfe_lite0", "gcc_cam_hf_axi" },
+			   "vfe_lite0", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 320000000, 400000000, 480000000, 600000000 },
+				{ 0 },
 				{ 0 } },
 
 		.regulators = {},
@@ -1537,11 +1541,12 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
 	/* VFE4 (lite) */
 	{
 		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb",
-			   "vfe_lite1", "gcc_cam_hf_axi" },
+			   "vfe_lite1", "gcc_axi_hf", "gcc_axi_sf" },
 		.clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 },
 				{ 80000000 },
 				{ 0 },
 				{ 320000000, 400000000, 480000000, 600000000 },
+				{ 0 },
 				{ 0 } },
 
 		.regulators = {},
-- 
2.25.1



From krzk at kernel.org  Tue Dec 17 06:10:17 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 15:10:17 +0100
Subject: [PATCH v10 1/4] media: dt-bindings: update clocks for
 sc7280-camss
In-Reply-To: <20241217140656.965235-2-quic_vikramsa@quicinc.com>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-2-quic_vikramsa@quicinc.com>
Message-ID: <02da691b-1f5d-41a6-847c-c7e9b8239919@kernel.org>

On 17/12/2024 15:06, Vikram Sharma wrote:
> This patch change clock names to make it consistent with
> existing platforms as gcc_cam_hf_axi -> gcc_axi_hf.
> This also adds gcc_axi_sf and remove gcc_camera_ahb.

Don't combine ABI changes with some less important things.

You miss here explanation why doing the ABI change in the first place.
Without that explanation I find it rather churn. But anyway, reason for
ABI break and impact should be documented in commit msg.

> 
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> ---

Best regards,
Krzysztof


From krzk at kernel.org  Tue Dec 17 06:11:37 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 15:11:37 +0100
Subject: [PATCH v10 2/4] media: qcom: camss: update clock names for sc7280
In-Reply-To: <20241217140656.965235-3-quic_vikramsa@quicinc.com>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-3-quic_vikramsa@quicinc.com>
Message-ID: <ae6db654-c19a-4fde-a649-48c63f4e6394@kernel.org>

On 17/12/2024 15:06, Vikram Sharma wrote:
> This patch changes gcc_cam_hf_axi clock name to make consistent

Please do not use "This commit/patch/change", but imperative mood. See
longer explanation here:
https://elixir.bootlin.com/linux/v5.17.1/source/Documentation/process/submitting-patches.rst#L95

> with existing platforms and add gcc_axi_sf clock too.
> gcc_cam_hf_axi changed to gcc_axi_hf.
> added gcc_axi_sf.

Explain ABI impact and don't mix new features with some sort of refactoring.

> 
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> ---
>  drivers/media/platform/qcom/camss/camss.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index 004a74f6b2f6..1d992dc74877 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -1443,12 +1443,13 @@ static const struct camss_subdev_resources vfe_res_7280[] = {
>  		.regulators = {},
>  
>  		.clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0",
> -			   "vfe0_axi", "gcc_cam_hf_axi" },
> +			   "vfe0_axi", "gcc_axi_hf", "gcc_axi_sf" },


I don't get how this works with old DTS.

This looks like pure ABI break without any explanation.

Best regards,
Krzysztof


From mripard at kernel.org  Tue Dec 17 06:07:47 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 15:07:47 +0100
Subject: [PATCH v7 0/7] Add ITE IT6263 LVDS to HDMI converter support
In-Reply-To: <20241114065759.3341908-1-victor.liu@nxp.com>
References: <20241114065759.3341908-1-victor.liu@nxp.com>
Message-ID: <20241217-uppish-sapphire-dinosaur-4c40a2@houat>

Hi,

Thanks for the description, I have several questions here.

On Thu, Nov 14, 2024 at 02:57:52PM +0800, Liu Ying wrote:
> This patch series aims to add ITE IT6263 LVDS to HDMI converter on
> i.MX8MP EVK.
> 
> Since IT6263 DT binding and driver were picked up from v5 and landed
> in drm-misc, this patch series contains patches almost all i.MX8MP
> SoC/platform specific.
> 
> Patch 1 is a preparation patch to allow display mode of an existing
> panel to pass the added mode validation logic in patch 3.
> 
> Patch 2 is a preparation patch to drop CLK_SET_RATE_PARENT flag for
> media_disp{1,2}_pix clocks.  Patch 5 depends on patch 2.
> 
> Patch 3 allows i.MX8MP LVDS Display Bridge(LDB) bridge driver to find
> the next non-panel bridge, that is the IT6263 in this case.
> 
> Patch 4 adds mode validation logic to i.MX8MP LDB bridge driver against
> "ldb" clock so that it can filter out unsupported display modes read
> from EDID.
> 
> Patch 5 adds mode validation logic to i.MX8MP LDB bridge driver against
> "pix" clock so that it can filter out display modes which are not
> supported by pixel clock tree.
> 
> Patch 6 adds DT overlays to support NXP adapter cards[1][2] with IT6263
> populated.
> 
> Patch 7 enables the IT6263 bridge driver in defconfig.
> 
> Note that patch 3 and 4 depend on patch[3] in shawnguo/imx/fixes.
> 
> Since this patch series is related to another one[4] authored by Marek,
> Maxime asked for a proper description[5] about the exact problem.
> 
> Admittedly, it's a bit complicated.  Here, I'm trying to do so and explain
> a bit more.
> 
> [ Description ]
> It's a clock problem about shared i.MX8MP video PLL between MIPI DSI and
> LVDS display pipelines.  The pipelines are driven by separate DRM driver
> instances, hence there is no way to negotiate a dynamically changeable
> PLL rate to satisfy both of them.  The only solution is to assign a
> sensible/unchangeable clock rate for the PLL in DT.
> 
> Admittedly, sys_pll3_out can be another clock source to derive pixel clock
> for i.MX8MP MIPI DSI display pipeline if a particalur i.MX8MP platform
> doesn't use audio(sys_pll3_out is supposed to derive audio AXI clock running
> at nominal 600MHz).  However, for i.MX8MP platforms with audio features,
> the shared video PLL case has to be handled and it determines that the above
> solution(unchangeable PLL rate assigned in DT) has to be used no matter
> sys_pll3_out is for display or audio, because the separate DRM driver
> instances really don't know if they are sharing the video PLL or not.
> 
> [[ i.MX8MP Display Hardware ]]
> i.MX8MP SoC supports three display pipelines:
> 
>  -----------------------------           ------------------------
> | imx8mp_media_disp_pix_sels  |         | imx8mp_media_ldb_sels  |
>  -----------------------------           ------------------------
> |  osc_24m (fixed 24MHz)      |         |  osc_24m (fixed 24MHz) |
> |*-video_pll1_out (video)     |         |  sys_pll2_333m (sys)   |
> |  audio_pll2_out (audio)     |         |  sys_pll2_100m (sys)   |
> |  audio_pll1_out (audio)     |         | -sys_pll1_800m (sys)   |
> | -sys_pll1_800m (sys)        |         | -sys_pll2_1000m (sys)  |
> | -sys_pll2_1000m (sys)       |         |  clk_ext2 (external)   |
> |  sys_pll3_out (audio ?)     |         |  audio_pll2_out (audio)|
> |  clk_ext4 (external)        |         |*-video_pll1_out (video)|
>  -----------------------------           ------------------------
>              ||                                     |
>  -----------------------------           ------------------------
> |   media_disp{1,2}_pix       |         |        media_ldb       |
>  ----------------------------- mux+div   ------------------------ mux+div
>              ||                                     |
>  -----------------------------           ------------------------
> | media_disp{1,2}_pix_root_clk|         |   media_ldb_root_clk   |
>  ----------------------------- gate      ------------------------ gate
>              ||                                     | (LVDS serial clock)
>              ||                                     V
> 	     || (Disp2 Pclk)  --------      ------------------
> 	     | ------------> | LCDIF2 | -> |       LDB        | -> panel/bridge
> 	     |                --------      ------------------
> 	     |  (Disp1 Pclk)  --------      ------------------
> 	      -------------> | LCDIF1 | -> | Samsung MIPI DSI | -> panel/bridge
> 	                      --------      ------------------
>                               --------      ------------------      ----------
>                              | LCDIF3 | -> | Synopsys HDMI TX | -> | HDMI PHY |
>                               --------      ------------------     |     +    |
>                                  ^                                 |    PLL   |
>                                  |                                  ----------
>                                  | (Disp3 pclk)                         | |
>                                   --------------------------------------  |
>                                                                           V
>                                                                     panel/bridge
> 
> * video_pll1_out is supposed to be used by video outputs.
> 
> - LCDIF2 + LDB can only use the *same* video_pll1_out, sys_pll1_800m or
>   sys_pll2_1000m.
> 
> [[ i.MX8MP Display Drivers ]]
> LCDIF: drivers/gpu/drm/mxsfb/lcdif_*.c
> Three LCDIFv3 display controllers are driven by three imx-lcdif DRM instances
> separately.
> 
> LDB: drivers/gpu/drm/bridge/fsl-ldb.c
> 
> Samsung MIPI DSI: drivers/gpu/drm/bridge/samsung-dsim.c
> 
> Synopsys HDMI TX: drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c
> 
> [[ Problem - Shared Video PLL Between Samsung MIPI DSI and LDB ]]
> osc_24m, audio_pll*, sys_pll* and clk_ext* are not for video outputs,
> because:
> a. Aparently, osc_24m runs at fixed 24MHz which is too low for most displays.
> b. Audio subsystem may consume all audio_pll*.
> c. sys_pll* are system clocks which are supposed to run at fixed typical
>    rates, e.g., sys_pll2_1000m runs at 1000MHz.
> d. sys_pll3_out is supposed to derive audio AXI clock running at nominal
>    600MHz(i.MX8MP data sheet specifies the rate), see NXP downstream kernel:
>    https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/boot/dts/freescale/imx8mp-evk-ndm.dts#L19
>    https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/boot/dts/freescale/imx8mp-ddr4-evk.dts#L25

Is there any downside to using any of these clocks, aside from the fact
that their rate must not change?

Also, if they can't change their rate, why do they have
CLK_SET_RATE_PARENT (sys_pll* in particular) ?

> e. clk_ext* are external clocks without known capabilities.
> 
> So, the only eligible video_pll1_out is supposed to be shared between LDB
> and Samsung MIPI DSI in the two separate display pipelines if sys_pll3_out
> is already used to derive the audio AXI clock.
> 
> With the shared video_pll1_out, drivers for the two display pipelines cannot
> change the PLL clock rate in runtime, since the pipelines are driven by two
> DRM driver instances.

What is the typicall frequency on those pipelines? Could setting the PLL
high enough that any frequency required by any of these pipelines can be
accomodated through a divider work?

Something like you run the PLL at 594MHz, and then most HDMI frequencies
can be reached by a 1, 2 or 4 divider.

> [[ Solution ]]
> Assign the PLL clock source(s) and the PLL clock rate(s) in DT.  Disallow
> display drivers to change the PLL clock source(s) or rate(s) in runtime
> including LCDIF driver and bridge drivers.  With sensible PLL clock rate(s),
> typical display modes like 1920x1080 at 60 can be supported if external HDMI
> bridges are connected, and panel display modes can be too.  Also the unneeded
> CLK_SET_RATE_PARENT flag can be dropped for media_disp{1,2}_pix clocks.
> If needed, bridge drivers just call clk_round_rate() to validate clocks so
> that unsupported display modes can be filtered out.  Although the
> unchangeable PLL clock rate disallows more potential display modes, the
> solution works for single/dual/triple display pipelines(OFC, hardware designers
> should pick panel/bridge display devices carefully first by considering clock
> resources).

I think it's a reasonable idea, if not for the hardcode-it it DT stuff.
If we can manage to have a fixed setup work ok for all display use
cases, why would it be in DT? The clock driver seems like a much better
choice to me.

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

From quic_vikramsa at quicinc.com  Tue Dec 17 06:06:55 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:36:55 +0530
Subject: [PATCH v10 3/4] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
Message-ID: <20241217140656.965235-4-quic_vikramsa@quicinc.com>

Add changes to support the camera subsystem on the SC7280.

Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 178 +++++++++++++++++++++++++++
 1 file changed, 178 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 55db1c83ef55..a893aade8165 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -4426,6 +4426,184 @@ cci1_i2c1: i2c-bus at 1 {
 			};
 		};
 
+		camss: isp at acb3000 {
+			compatible = "qcom,sc7280-camss";
+
+			reg = <0x0 0x0acb3000 0x0 0x1000>,
+			      <0x0 0x0acba000 0x0 0x1000>,
+			      <0x0 0x0acc1000 0x0 0x1000>,
+			      <0x0 0x0acc8000 0x0 0x1000>,
+			      <0x0 0x0accf000 0x0 0x1000>,
+			      <0x0 0x0ace0000 0x0 0x2000>,
+			      <0x0 0x0ace2000 0x0 0x2000>,
+			      <0x0 0x0ace4000 0x0 0x2000>,
+			      <0x0 0x0ace6000 0x0 0x2000>,
+			      <0x0 0x0ace8000 0x0 0x2000>,
+			      <0x0 0x0acaf000 0x0 0x4000>,
+			      <0x0 0x0acb6000 0x0 0x4000>,
+			      <0x0 0x0acbd000 0x0 0x4000>,
+			      <0x0 0x0acc4000 0x0 0x4000>,
+			      <0x0 0x0accb000 0x0 0x4000>;
+			reg-names = "csid0",
+				    "csid1",
+				    "csid2",
+				    "csid_lite0",
+				    "csid_lite1",
+				    "csiphy0",
+				    "csiphy1",
+				    "csiphy2",
+				    "csiphy3",
+				    "csiphy4",
+				    "vfe0",
+				    "vfe1",
+				    "vfe2",
+				    "vfe_lite0",
+				    "vfe_lite1";
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_CSIPHY0_CLK>,
+				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY1_CLK>,
+				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY2_CLK>,
+				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY3_CLK>,
+				 <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY4_CLK>,
+				 <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+				 <&gcc GCC_CAMERA_HF_AXI_CLK>,
+				 <&gcc GCC_CAMERA_SF_AXI_CLK>,
+				 <&camcc CAM_CC_ICP_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_0_CLK>,
+				 <&camcc CAM_CC_IFE_0_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_1_CLK>,
+				 <&camcc CAM_CC_IFE_1_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_1_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_2_CLK>,
+				 <&camcc CAM_CC_IFE_2_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_2_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>;
+			clock-names = "camnoc_axi",
+				      "cpas_ahb",
+				      "csiphy0",
+				      "csiphy0_timer",
+				      "csiphy1",
+				      "csiphy1_timer",
+				      "csiphy2",
+				      "csiphy2_timer",
+				      "csiphy3",
+				      "csiphy3_timer",
+				      "csiphy4",
+				      "csiphy4_timer",
+				      "gcc_axi_hf",
+				      "gcc_axi_sf",
+				      "icp_ahb",
+				      "vfe0",
+				      "vfe0_axi",
+				      "vfe0_cphy_rx",
+				      "vfe0_csid",
+				      "vfe1",
+				      "vfe1_axi",
+				      "vfe1_cphy_rx",
+				      "vfe1_csid",
+				      "vfe2",
+				      "vfe2_axi",
+				      "vfe2_cphy_rx",
+				      "vfe2_csid",
+				      "vfe_lite0",
+				      "vfe_lite0_cphy_rx",
+				      "vfe_lite0_csid",
+				      "vfe_lite1",
+				      "vfe_lite1_cphy_rx",
+				      "vfe_lite1_csid";
+
+			interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "csid0",
+					  "csid1",
+					  "csid2",
+					  "csid_lite0",
+					  "csid_lite1",
+					  "csiphy0",
+					  "csiphy1",
+					  "csiphy2",
+					  "csiphy3",
+					  "csiphy4",
+					  "vfe0",
+					  "vfe1",
+					  "vfe2",
+					  "vfe_lite0",
+					  "vfe_lite1";
+
+			interconnects = <&gem_noc  MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &cnoc2 SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&mmss_noc MASTER_CAMNOC_HF  QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "ahb",
+					     "hf_0";
+
+			iommus = <&apps_smmu 0x800 0x4e0>;
+
+			power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
+					<&camcc CAM_CC_IFE_1_GDSC>,
+					<&camcc CAM_CC_IFE_2_GDSC>,
+					<&camcc CAM_CC_TITAN_TOP_GDSC>;
+			power-domain-names = "ife0",
+					     "ife1",
+					     "ife2",
+					     "top";
+
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+				};
+
+				port at 1 {
+					reg = <1>;
+				};
+
+				port at 2 {
+					reg = <2>;
+				};
+
+				port at 3 {
+					reg = <3>;
+				};
+
+				port at 4 {
+					reg = <4>;
+				};
+			};
+		};
+
 		camcc: clock-controller at ad00000 {
 			compatible = "qcom,sc7280-camcc";
 			reg = <0 0x0ad00000 0 0x10000>;
-- 
2.25.1



From quic_vikramsa at quicinc.com  Tue Dec 17 06:06:56 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 19:36:56 +0530
Subject: [PATCH v10 4/4] arm64: dts: qcom: qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
Message-ID: <20241217140656.965235-5-quic_vikramsa@quicinc.com>

The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
Enable the IMX577 on the vision mezzanine.

An example media-ctl pipeline for the imx577 is:

media-ctl --reset
media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'

yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0

Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/Makefile             |   4 +
 .../qcs6490-rb3gen2-vision-mezzanine.dtso     | 109 ++++++++++++++++++
 2 files changed, 113 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 4686f2a8ddd8..a7e88fcabded 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -115,6 +115,10 @@ dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-1000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-4000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs615-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
+
+qcs6490-rb3gen2-vision-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2-vision-mezzanine.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride.dtb
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
new file mode 100644
index 000000000000..7782c4aee576
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/*
+ * Camera Sensor overlay on top of rb3gen2 core kit.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/qcom,camcc-sc7280.h>
+
+/dts-v1/;
+/plugin/;
+
+&camss {
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* The port index denotes CSIPHY id i.e. csiphy3 */
+		port at 3 {
+			reg = <3>;
+
+			csiphy3_ep: endpoint {
+				clock-lanes = <7>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&imx577_ep>;
+			};
+		};
+	};
+};
+
+&cci1 {
+	status = "okay";
+};
+
+&cci1_i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	camera at 1a {
+		compatible = "sony,imx577";
+
+		reg = <0x1a>;
+
+		reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default", "suspend";
+		pinctrl-0 = <&cam2_default>;
+		pinctrl-1 = <&cam2_suspend>;
+
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clock-rates = <24000000>;
+
+		dovdd-supply  = <&vreg_l18b_1p8>;
+		avdd-supply = <&vph_pwr>;
+		dvdd-supply = <&vph_pwr>;
+
+		port {
+			imx577_ep: endpoint {
+				clock-lanes = <7>;
+				link-frequencies = /bits/ 64 <600000000>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&csiphy3_ep>;
+			};
+		};
+	};
+};
+
+&tlmm {
+	cam2_default: cam2-default-state {
+		mclk-pins {
+			pins = "gpio67";
+			function = "cam_mclk";
+			drive-strength = <2>;
+			bias-disable;
+		};
+
+		rst-pins {
+			pins = "gpio78";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+		};
+	};
+
+	cam2_suspend: cam2-suspend-state {
+		mclk-pins {
+			pins = "gpio67";
+			function = "cam_mclk";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		rst-pins {
+			pins = "gpio78";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+			output-low;
+		};
+	};
+};
-- 
2.25.1



From dmitry.baryshkov at linaro.org  Tue Dec 17 06:09:50 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 17 Dec 2024 16:09:50 +0200
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <D6DZB443IQ7A.3P1135M6DMF2S@cknow.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <D6DZB443IQ7A.3P1135M6DMF2S@cknow.org>
Message-ID: <kyytu3nofrjkajwatmxdyav7oekkeigrhx5amddgjtlpsdl2m5@3moqad3gfds5>

On Tue, Dec 17, 2024 at 01:36:29PM +0100, Diederik de Haas wrote:
> On Tue Dec 17, 2024 at 1:40 AM CET, Dmitry Baryshkov wrote:
> > This series depends on the ELD mutex series [1]
> >
> > [1] https://lore.kernel.org/r/20241201-drm-connector-eld-mutex-v1-0-ba56a6545c03 at linaro.org
> 
> There's a v2 of that patch series here:
> https://lore.kernel.org/all/20241206-drm-connector-eld-mutex-v2-0-c9bce1ee8bea at linaro.org/

... and it's even merged to drm-misc-next. I dropped it from b4 deps,
but I forgot to update the cover letter.

-- 
With best wishes
Dmitry


From broonie at kernel.org  Tue Dec 17 06:16:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Dec 2024 14:16:58 +0000
Subject: [PATCH v2] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
In-Reply-To: <877c7ysois.wl-maz@kernel.org>
References: <20241216-arm64-fix-boot-cpu-smidr-v2-1-a99ffba2c37f@kernel.org>
 <877c7ysois.wl-maz@kernel.org>
Message-ID: <7bd307fb-9add-41a8-975a-a0ecfec1a933@sirena.org.uk>

On Tue, Dec 17, 2024 at 08:27:07AM +0000, Marc Zyngier wrote:

> My reading of the thread was that we don't need to kill the
> arm64.nosme option as SMIDR_EL1 wouldn't UNDEF, which is guaranteed if
> SME is implemented at all.

My read had been the other way around, I'll drop the change to the
override.

> What was needed in 6.0 is not there anymore, for all the reasons that
> Mark outlined and that you have pasted in the above commit message.

That's a rewrite of roughly the same stuff!  I pasted the commit IDs but
the rest was a rewrite.
-------------- 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/20241217/148f7bcc/attachment.sig>

From robh at kernel.org  Tue Dec 17 06:20:28 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Dec 2024 08:20:28 -0600
Subject: [PATCH RFC 1/3] dt-bindings: pinctrl: Add support for Amlogic
 SoCs
In-Reply-To: <20241211-amlogic-pinctrl-v1-1-410727335119@amlogic.com>
References: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
 <20241211-amlogic-pinctrl-v1-1-410727335119@amlogic.com>
Message-ID: <20241217142028.GA1441221-robh@kernel.org>

On Wed, Dec 11, 2024 at 02:47:49PM +0800, Xianwei Zhao wrote:
> Add the dt-bindings for Amlogic pin controller, and add a new
> dt-binding header file which document the GPIO bank names and
> alternative func value of all Amlogic subsequent SoCs.
> 
> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
> ---
>  .../bindings/pinctrl/amlogic,pinctrl.yaml          | 150 +++++++++++++++++++++
>  include/dt-bindings/pinctrl/amlogic,pinctrl.h      |  68 ++++++++++
>  2 files changed, 218 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/amlogic,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/amlogic,pinctrl.yaml
> new file mode 100644
> index 000000000000..b0c2ae585d7d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/amlogic,pinctrl.yaml
> @@ -0,0 +1,150 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/amlogic,pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic pinmux controller
> +
> +maintainers:
> +  - Xianwei Zhao <xianwei.zhao at amlogic.com>
> +
> +allOf:
> +  - $ref: pinctrl.yaml#
> +
> +properties:
> +  compatible:
> +    const: amlogic,pinctrl

Only one Amlogic pinctrl block? Pretty sure there's more than 1 SoC and 
pinctrl is unlikely identical for all. This must be SoC specific.

> +
> +  reg:
> +    minItems: 2
> +
> +  reg-names:
> +    items:
> +      - const: mux
> +      - const: gpio
> +
> +  "#address-cells":
> +    const: 2
> +
> +  "#size-cells":
> +    const: 2

Why do you need these? You don't have any child nodes with addresses. 
But maybe you should?

> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - "#address-cells"
> +  - "#size-cells"
> +
> +patternProperties:
> +  "^gpio[a-z]":

This allows "gpioanythingyouwant" for example. If there is no 
unit-address, then it should be '^gpio-[0-9]+$'.

> +    type: object
> +
> +    properties:
> +      gpio-controller: true
> +
> +      "#gpio-cells":
> +        const: 2
> +
> +      bank-name:
> +        $ref: /schemas/types.yaml#/definitions/string

You must define values, but why do you need this? No other GPIO 
controller needs something like this.

> +
> +      npins:

We have a standard property for this: ngpios

> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        minimum: 1
> +        maximum: 32
> +
> +      bank-index:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        minimum: 0
> +        maximum: 29

Consider if 'bank' should be part of the gpio cells rather than 
separate controller nodes. That works better if each bank is not its own 
separate h/w block. If banks share a register, then that's not separate 
blocks.

> +
> +      reg-mux-offset:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +
> +      bit-mux-offset:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +
> +      reg-gpio-offset:
> +        $ref: /schemas/types.yaml#/definitions/uint32

Put these into 'reg'. We even have a way to deal with bit offsets. See 
leds/register-bit-led.yaml for example.


> +
> +    required:
> +      - gpio-controller
> +      - "#gpio-cells"
> +      - npins
> +      - bank-index
> +      - reg-mux-offset
> +      - reg-gpio-offset
> +      - bank-name
> +
> +    additionalProperties: false
> +    unevaluatedProperties: false

Don't need both. 'additionalProperties' is more restrictive, so drop 
unevaluatedProperties.

> +
> +  "^func-[0-9a-z]":

"^func-[0-9a-z-]+$"

> +    type: object
> +    additionalProperties:
> +      type: object
> +      allOf:
> +        - $ref: pincfg-node.yaml#
> +        - $ref: pinmux-node.yaml#
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    apb {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +      periphs_pinctrl: pinctrl at 8e700 {
> +        compatible = "amlogic,pinctrl";
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +        reg = <0x0 0x8e700 0x0 0x04>,
> +              <0x0 0x8e704 0x0 0x60>;
> +        reg-names = "mux", "gpio";
> +
> +        gpiob {
> +          gpio-controller;
> +          #gpio-cells = <2>;
> +          npins = <10>;
> +          bank-index = <1>;
> +          reg-mux-offset = <0x14>;
> +          bit-mux-offset = <0x14>;
> +          reg-gpio-offset = <0x30>;
> +          bank-name = "GPIOB";
> +        };
> +
> +        gpioe {
> +          gpio-controller;
> +          #gpio-cells = <2>;
> +          npins = <10>;
> +          bank-index = <5>;
> +          reg-mux-offset = <0x14>;
> +          reg-gpio-offset = <0x30>;
> +          bank-name = "GPIOE";
> +        };
> +
> +        func-uart-b {
> +          uart-b-default{
> +            pinmux = <3>;
> +            bias-pull-up;
> +            drive-strength-microamp = <4000>;
> +          };
> +
> +          uart-c-default{
> +            pinmux = <4>;
> +            bias-pull-up;
> +            drive-strength-microamp = <4000>;
> +          };
> +        };
> +
> +        func-uart-c {
> +          uart-c-default{
> +            pinmux = <3>;
> +            bias-pull-up;
> +            drive-strength-microamp = <4000>;
> +          };
> +        };
> +      };
> +    };
> diff --git a/include/dt-bindings/pinctrl/amlogic,pinctrl.h b/include/dt-bindings/pinctrl/amlogic,pinctrl.h
> new file mode 100644
> index 000000000000..03db0a730e8b
> --- /dev/null
> +++ b/include/dt-bindings/pinctrl/amlogic,pinctrl.h
> @@ -0,0 +1,68 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> +/*
> + * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
> + * Author: Xianwei Zhao <xianwei.zhao at amlogic.com>
> + */
> +
> +#ifndef _DT_BINDINGS_AMLOGIC_PINCTRL_H
> +#define _DT_BINDINGS_AMLOGIC_PINCTRL_H
> +
> +/* define PIN modes */
> +#define AF0	0x0
> +#define AF1	0x1
> +#define AF2	0x2
> +#define AF3	0x3
> +#define AF4	0x4
> +#define AF5	0x5
> +#define AF6	0x6
> +#define AF7	0x7
> +#define AF8	0x8
> +#define AF9	0x9
> +#define AF10	0xa
> +#define AF11	0xb
> +#define AF12	0xc
> +#define AF13	0xd
> +#define AF14	0xe
> +#define AF15	0xf
> +
> +#define AML_PIN_ALT_FUNC_MASK	0xf
> +
> +/* Normal PIN bank */
> +#define AMLOGIC_GPIO_A		0
> +#define AMLOGIC_GPIO_B		1
> +#define AMLOGIC_GPIO_C		2
> +#define AMLOGIC_GPIO_D		3
> +#define AMLOGIC_GPIO_E		4
> +#define AMLOGIC_GPIO_F		5
> +#define AMLOGIC_GPIO_G		6
> +#define AMLOGIC_GPIO_H		7
> +#define AMLOGIC_GPIO_I		8
> +#define AMLOGIC_GPIO_J		9
> +#define AMLOGIC_GPIO_K		10
> +#define AMLOGIC_GPIO_L		11
> +#define AMLOGIC_GPIO_M		12
> +#define AMLOGIC_GPIO_N		13
> +#define AMLOGIC_GPIO_O		14
> +#define AMLOGIC_GPIO_P		15
> +#define AMLOGIC_GPIO_Q		16
> +#define AMLOGIC_GPIO_R		17
> +#define AMLOGIC_GPIO_S		18
> +#define AMLOGIC_GPIO_T		19
> +#define AMLOGIC_GPIO_U		20
> +#define AMLOGIC_GPIO_V		21
> +#define AMLOGIC_GPIO_W		22
> +#define AMLOGIC_GPIO_X		23
> +#define AMLOGIC_GPIO_Y		24
> +#define AMLOGIC_GPIO_Z		25
> +
> +/* Special PIN bank */
> +#define AMLOGIC_GPIO_DV		26
> +#define AMLOGIC_GPIO_AO		27
> +#define AMLOGIC_GPIO_CC		28
> +#define AMLOGIC_GPIO_TEST_N	29
> +
> +#define AML_PINMUX(bank, offset, mode)	(((((bank) << 8) + (offset)) << 8) | (mode))
> +#define AML_PINMUX_TO_BANK(pinmux)	(((pinmux) >> 16) & 0xff)
> +#define AML_PINMUX_TO_OFFSET(pinmux)	(((pinmux) >> 8) & 0xff)
> +
> +#endif /* _DT_BINDINGS_AMLOGIC_PINCTRL_H */
> 
> -- 
> 2.37.1
> 


From maz at kernel.org  Tue Dec 17 06:23:08 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:08 +0000
Subject: [PATCH v2 00/12] KVM: arm64: Add NV timer support
Message-ID: <20241217142321.763801-1-maz@kernel.org>

Here's another version of the series initially posted at [1], which
implements support for timers in NV context.

>From v1:

- Repainted EL0->EL1 when rambling about the timers

- Simplified access to EL1 counters from HYP context

- Update the status register when handled as an early trap

- Added some documentation about the default PPI numbers

The whole thing has been tested with 6.13-rc3 as part of the my NV
integration branch [2], and is functional enough to run an L3 guest
with kvmtool as the VMM and EDK2 as the firmware. YMMV.

[1] https://lore.kernel.org/r/20241202172134.384923-1-maz at kernel.org
[2] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/nv-next

Marc Zyngier (12):
  KVM: arm64: nv: Add handling of EL2-specific timer registers
  KVM: arm64: nv: Sync nested timer state with FEAT_NV2
  KVM: arm64: nv: Publish emulated timer interrupt state in the
    in-memory state
  KVM: arm64: nv: Use FEAT_ECV to trap access to EL0 timers
  KVM: arm64: nv: Accelerate EL0 timer read accesses when FEAT_ECV in
    use
  KVM: arm64: nv: Accelerate EL0 counter accesses from hypervisor
    context
  KVM: arm64: Handle counter access early in non-HYP context
  KVM: arm64: nv: Add trap routing for
    CNTHCTL_EL2.EL1{NVPCT,NVVCT,TVT,TVCT}
  KVM: arm64: nv: Propagate CNTHCTL_EL2.EL1NV{P,V}CT bits
  KVM: arm64: nv: Sanitise CNTHCTL_EL2
  KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity
  KVM: arm64: nv: Document EL2 timer API

 Documentation/virt/kvm/devices/vcpu.rst |  15 +-
 arch/arm64/include/asm/cputype.h        |   2 +
 arch/arm64/include/asm/kvm_host.h       |   2 +-
 arch/arm64/include/asm/sysreg.h         |   4 +
 arch/arm64/kernel/cpu_errata.c          |   8 ++
 arch/arm64/kernel/image-vars.h          |   3 +
 arch/arm64/kvm/arch_timer.c             | 179 +++++++++++++++++++++---
 arch/arm64/kvm/arm.c                    |   3 +
 arch/arm64/kvm/emulate-nested.c         |  58 +++++++-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  39 ++++--
 arch/arm64/kvm/hyp/nvhe/timer-sr.c      |  16 ++-
 arch/arm64/kvm/hyp/vhe/switch.c         | 107 ++++++++++++++
 arch/arm64/kvm/nested.c                 |  15 ++
 arch/arm64/kvm/sys_regs.c               | 146 ++++++++++++++++++-
 arch/arm64/tools/cpucaps                |   1 +
 include/clocksource/arm_arch_timer.h    |   6 +
 include/kvm/arm_arch_timer.h            |  23 +++
 17 files changed, 580 insertions(+), 47 deletions(-)

-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:09 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:09 +0000
Subject: [PATCH v2 01/12] KVM: arm64: nv: Add handling of EL2-specific timer registers
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-2-maz@kernel.org>

Add the required handling for EL2 and EL02 registers, as
well as EL1 registers used in the E2H context. This includes
handling the virtual timer accesses when CNTHCTL_EL2.EL1TVT
or CNTHCTL_EL2.EL1TVCT are set.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/sysreg.h      |   4 +
 arch/arm64/kvm/sys_regs.c            | 143 +++++++++++++++++++++++++++
 include/clocksource/arm_arch_timer.h |   2 +
 3 files changed, 149 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index b8303a83c0bff..2ed33737c7a99 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -477,6 +477,7 @@
 #define SYS_CNTFRQ_EL0			sys_reg(3, 3, 14, 0, 0)
 
 #define SYS_CNTPCT_EL0			sys_reg(3, 3, 14, 0, 1)
+#define SYS_CNTVCT_EL0			sys_reg(3, 3, 14, 0, 2)
 #define SYS_CNTPCTSS_EL0		sys_reg(3, 3, 14, 0, 5)
 #define SYS_CNTVCTSS_EL0		sys_reg(3, 3, 14, 0, 6)
 
@@ -484,14 +485,17 @@
 #define SYS_CNTP_CTL_EL0		sys_reg(3, 3, 14, 2, 1)
 #define SYS_CNTP_CVAL_EL0		sys_reg(3, 3, 14, 2, 2)
 
+#define SYS_CNTV_TVAL_EL0		sys_reg(3, 3, 14, 3, 0)
 #define SYS_CNTV_CTL_EL0		sys_reg(3, 3, 14, 3, 1)
 #define SYS_CNTV_CVAL_EL0		sys_reg(3, 3, 14, 3, 2)
 
 #define SYS_AARCH32_CNTP_TVAL		sys_reg(0, 0, 14, 2, 0)
 #define SYS_AARCH32_CNTP_CTL		sys_reg(0, 0, 14, 2, 1)
 #define SYS_AARCH32_CNTPCT		sys_reg(0, 0, 0, 14, 0)
+#define SYS_AARCH32_CNTVCT		sys_reg(0, 1, 0, 14, 0)
 #define SYS_AARCH32_CNTP_CVAL		sys_reg(0, 2, 0, 14, 0)
 #define SYS_AARCH32_CNTPCTSS		sys_reg(0, 8, 0, 14, 0)
+#define SYS_AARCH32_CNTVCTSS		sys_reg(0, 9, 0, 14, 0)
 
 #define __PMEV_op2(n)			((n) & 0x7)
 #define __CNTR_CRm(n)			(0x8 | (((n) >> 3) & 0x3))
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 83c6b4a07ef56..986e63d4f9faa 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1412,26 +1412,146 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
 
 	switch (reg) {
 	case SYS_CNTP_TVAL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
+	case SYS_CNTV_TVAL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HVTIMER;
+		else
+			tmr = TIMER_VTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
 	case SYS_AARCH32_CNTP_TVAL:
+	case SYS_CNTP_TVAL_EL02:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_TVAL;
 		break;
+
+	case SYS_CNTV_TVAL_EL02:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
+	case SYS_CNTHP_TVAL_EL2:
+		tmr = TIMER_HPTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
+	case SYS_CNTHV_TVAL_EL2:
+		tmr = TIMER_HVTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
 	case SYS_CNTP_CTL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
+	case SYS_CNTV_CTL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HVTIMER;
+		else
+			tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
 	case SYS_AARCH32_CNTP_CTL:
+	case SYS_CNTP_CTL_EL02:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_CTL;
 		break;
+
+	case SYS_CNTV_CTL_EL02:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
+	case SYS_CNTHP_CTL_EL2:
+		tmr = TIMER_HPTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
+	case SYS_CNTHV_CTL_EL2:
+		tmr = TIMER_HVTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
 	case SYS_CNTP_CVAL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
+	case SYS_CNTV_CVAL_EL0:
+		if (is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HVTIMER;
+		else
+			tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
 	case SYS_AARCH32_CNTP_CVAL:
+	case SYS_CNTP_CVAL_EL02:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_CVAL;
 		break;
+
+	case SYS_CNTV_CVAL_EL02:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
+	case SYS_CNTHP_CVAL_EL2:
+		tmr = TIMER_HPTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
+	case SYS_CNTHV_CVAL_EL2:
+		tmr = TIMER_HVTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
 	case SYS_CNTPCT_EL0:
 	case SYS_CNTPCTSS_EL0:
+		if (is_hyp_ctxt(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_CNT;
+		break;
+
 	case SYS_AARCH32_CNTPCT:
+	case SYS_AARCH32_CNTPCTSS:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_CNT;
 		break;
+
+	case SYS_CNTVCT_EL0:
+	case SYS_CNTVCTSS_EL0:
+		if (is_hyp_ctxt(vcpu))
+			tmr = TIMER_HVTIMER;
+		else
+			tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CNT;
+		break;
+
+	case SYS_AARCH32_CNTVCT:
+	case SYS_AARCH32_CNTVCTSS:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CNT;
+		break;
+
 	default:
 		print_sys_reg_msg(p, "%s", "Unhandled trapped timer register");
 		return undef_access(vcpu, p, r);
@@ -2901,11 +3021,17 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	AMU_AMEVTYPER1_EL0(15),
 
 	{ SYS_DESC(SYS_CNTPCT_EL0), access_arch_timer },
+	{ SYS_DESC(SYS_CNTVCT_EL0), access_arch_timer },
 	{ SYS_DESC(SYS_CNTPCTSS_EL0), access_arch_timer },
+	{ SYS_DESC(SYS_CNTVCTSS_EL0), access_arch_timer },
 	{ SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },
 	{ SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer },
 	{ SYS_DESC(SYS_CNTP_CVAL_EL0), access_arch_timer },
 
+	{ SYS_DESC(SYS_CNTV_TVAL_EL0), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CTL_EL0), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CVAL_EL0), access_arch_timer },
+
 	/* PMEVCNTRn_EL0 */
 	PMU_PMEVCNTR_EL0(0),
 	PMU_PMEVCNTR_EL0(1),
@@ -3057,9 +3183,24 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	EL2_REG_VNCR(CNTVOFF_EL2, reset_val, 0),
 	EL2_REG(CNTHCTL_EL2, access_rw, reset_val, 0),
+	{ SYS_DESC(SYS_CNTHP_TVAL_EL2), access_arch_timer },
+	EL2_REG(CNTHP_CTL_EL2, access_arch_timer, reset_val, 0),
+	EL2_REG(CNTHP_CVAL_EL2, access_arch_timer, reset_val, 0),
+
+	{ SYS_DESC(SYS_CNTHV_TVAL_EL2), access_arch_timer },
+	EL2_REG(CNTHV_CTL_EL2, access_arch_timer, reset_val, 0),
+	EL2_REG(CNTHV_CVAL_EL2, access_arch_timer, reset_val, 0),
 
 	{ SYS_DESC(SYS_CNTKCTL_EL12), access_cntkctl_el12 },
 
+	{ SYS_DESC(SYS_CNTP_TVAL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTP_CTL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTP_CVAL_EL02), access_arch_timer },
+
+	{ SYS_DESC(SYS_CNTV_TVAL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CTL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CVAL_EL02), access_arch_timer },
+
 	EL2_REG(SP_EL2, NULL, reset_unknown, 0),
 };
 
@@ -3879,9 +4020,11 @@ static const struct sys_reg_desc cp15_64_regs[] = {
 	{ SYS_DESC(SYS_AARCH32_CNTPCT),	      access_arch_timer },
 	{ Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, TTBR1_EL1 },
 	{ Op1( 1), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_ASGI1R */
+	{ SYS_DESC(SYS_AARCH32_CNTVCT),	      access_arch_timer },
 	{ Op1( 2), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI0R */
 	{ SYS_DESC(SYS_AARCH32_CNTP_CVAL),    access_arch_timer },
 	{ SYS_DESC(SYS_AARCH32_CNTPCTSS),     access_arch_timer },
+	{ SYS_DESC(SYS_AARCH32_CNTVCTSS),     access_arch_timer },
 };
 
 static bool check_sysreg_table(const struct sys_reg_desc *table, unsigned int n,
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index cbbc9a6dc5715..877dcbb2601ae 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -22,6 +22,8 @@
 #define CNTHCTL_EVNTDIR			(1 << 3)
 #define CNTHCTL_EVNTI			(0xF << 4)
 #define CNTHCTL_ECV			(1 << 12)
+#define CNTHCTL_EL1TVT			(1 << 13)
+#define CNTHCTL_EL1TVCT			(1 << 14)
 
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:10 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:10 +0000
Subject: [PATCH v2 02/12] KVM: arm64: nv: Sync nested timer state with FEAT_NV2
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-3-maz@kernel.org>

Emulating the timers with FEAT_NV2 is a bit odd, as the timers
can be reconfigured behind our back without the hypervisor even
noticing. In the VHE case, that's an actual regression in the
architecture...

Co-developed-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c  | 44 ++++++++++++++++++++++++++++++++++++
 arch/arm64/kvm/arm.c         |  3 +++
 include/kvm/arm_arch_timer.h |  1 +
 3 files changed, 48 insertions(+)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 1215df5904185..ee5f732fbbece 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -905,6 +905,50 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
 		kvm_timer_blocking(vcpu);
 }
 
+void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * When NV2 is on, guest hypervisors have their EL1 timer register
+	 * accesses redirected to the VNCR page. Any guest action taken on
+	 * the timer is postponed until the next exit, leading to a very
+	 * poor quality of emulation.
+	 */
+	if (!is_hyp_ctxt(vcpu))
+		return;
+
+	if (!vcpu_el2_e2h_is_set(vcpu)) {
+		/*
+		 * A non-VHE guest hypervisor doesn't have any direct access
+		 * to its timers: the EL2 registers trap (and the HW is
+		 * fully emulated), while the EL0 registers access memory
+		 * despite the access being notionally direct. Boo.
+		 *
+		 * We update the hardware timer registers with the
+		 * latest value written by the guest to the VNCR page
+		 * and let the hardware take care of the rest.
+		 */
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CTL_EL0),  SYS_CNTV_CTL);
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CVAL_EL0), SYS_CNTV_CVAL);
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CTL_EL0),  SYS_CNTP_CTL);
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CVAL_EL0), SYS_CNTP_CVAL);
+	} else {
+		/*
+		 * For a VHE guest hypervisor, the EL2 state is directly
+		 * stored in the host EL1 timers, while the emulated EL0
+		 * state is stored in the VNCR page. The latter could have
+		 * been updated behind our back, and we must reset the
+		 * emulation of the timers.
+		 */
+		struct timer_map map;
+		get_timer_map(vcpu, &map);
+
+		soft_timer_cancel(&map.emul_vtimer->hrtimer);
+		soft_timer_cancel(&map.emul_ptimer->hrtimer);
+		timer_emulate(map.emul_vtimer);
+		timer_emulate(map.emul_ptimer);
+	}
+}
+
 /*
  * With a userspace irqchip we have to check if the guest de-asserted the
  * timer and if so, unmask the timer irq signal on the host interrupt
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc4..fa3089822f9f3 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1228,6 +1228,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
 			kvm_timer_sync_user(vcpu);
 
+		if (vcpu_has_nv(vcpu))
+			kvm_timer_sync_nested(vcpu);
+
 		kvm_arch_vcpu_ctxsync_fp(vcpu);
 
 		/*
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index fd650a8789b91..6e3f6b7ff2b22 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -98,6 +98,7 @@ int __init kvm_timer_hyp_init(bool has_gic);
 int kvm_timer_enable(struct kvm_vcpu *vcpu);
 void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu);
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
+void kvm_timer_sync_nested(struct kvm_vcpu *vcpu);
 void kvm_timer_sync_user(struct kvm_vcpu *vcpu);
 bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu);
 void kvm_timer_update_run(struct kvm_vcpu *vcpu);
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:16 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:16 +0000
Subject: [PATCH v2 08/12] KVM: arm64: nv: Add trap routing for CNTHCTL_EL2.EL1{NVPCT,NVVCT,TVT,TVCT}
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-9-maz@kernel.org>

For completeness, fun, and cerebral meltdown, add the virtualisation
related traps to the counter and timers.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 58 +++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 1ffbfd1c3cf2e..03d21044c41f5 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -89,6 +89,9 @@ enum cgt_group_id {
 	CGT_HCRX_EnFPM,
 	CGT_HCRX_TCR2En,
 
+	CGT_CNTHCTL_EL1TVT,
+	CGT_CNTHCTL_EL1TVCT,
+
 	CGT_ICH_HCR_TC,
 	CGT_ICH_HCR_TALL0,
 	CGT_ICH_HCR_TALL1,
@@ -124,6 +127,8 @@ enum cgt_group_id {
 	__COMPLEX_CONDITIONS__,
 	CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
 	CGT_CNTHCTL_EL1PTEN,
+	CGT_CNTHCTL_EL1NVPCT,
+	CGT_CNTHCTL_EL1NVVCT,
 
 	CGT_CPTR_TTA,
 	CGT_MDCR_HPMN,
@@ -393,6 +398,18 @@ static const struct trap_bits coarse_trap_bits[] = {
 		.mask		= HCRX_EL2_TCR2En,
 		.behaviour	= BEHAVE_FORWARD_RW,
 	},
+	[CGT_CNTHCTL_EL1TVT] = {
+		.index		= CNTHCTL_EL2,
+		.value		= CNTHCTL_EL1TVT,
+		.mask		= CNTHCTL_EL1TVT,
+		.behaviour	= BEHAVE_FORWARD_RW,
+	},
+	[CGT_CNTHCTL_EL1TVCT] = {
+		.index		= CNTHCTL_EL2,
+		.value		= CNTHCTL_EL1TVCT,
+		.mask		= CNTHCTL_EL1TVCT,
+		.behaviour	= BEHAVE_FORWARD_READ,
+	},
 	[CGT_ICH_HCR_TC] = {
 		.index		= ICH_HCR_EL2,
 		.value		= ICH_HCR_TC,
@@ -487,6 +504,32 @@ static enum trap_behaviour check_cnthctl_el1pten(struct kvm_vcpu *vcpu)
 	return BEHAVE_FORWARD_RW;
 }
 
+static bool is_nested_nv2_guest(struct kvm_vcpu *vcpu)
+{
+	u64 val;
+
+	val = __vcpu_sys_reg(vcpu, HCR_EL2);
+	return ((val & (HCR_E2H | HCR_TGE | HCR_NV2 | HCR_NV1 | HCR_NV)) == (HCR_E2H | HCR_NV2 | HCR_NV));
+}
+
+static enum trap_behaviour check_cnthctl_el1nvpct(struct kvm_vcpu *vcpu)
+{
+	if (!is_nested_nv2_guest(vcpu) ||
+	    !(__vcpu_sys_reg(vcpu, CNTHCTL_EL2) & CNTHCTL_EL1NVPCT))
+		return BEHAVE_HANDLE_LOCALLY;
+
+	return BEHAVE_FORWARD_RW;
+}
+
+static enum trap_behaviour check_cnthctl_el1nvvct(struct kvm_vcpu *vcpu)
+{
+	if (!is_nested_nv2_guest(vcpu) ||
+	    !(__vcpu_sys_reg(vcpu, CNTHCTL_EL2) & CNTHCTL_EL1NVVCT))
+		return BEHAVE_HANDLE_LOCALLY;
+
+	return BEHAVE_FORWARD_RW;
+}
+
 static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
 {
 	u64 val = __vcpu_sys_reg(vcpu, CPTR_EL2);
@@ -534,6 +577,8 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
 static const complex_condition_check ccc[] = {
 	CCC(CGT_CNTHCTL_EL1PCTEN, check_cnthctl_el1pcten),
 	CCC(CGT_CNTHCTL_EL1PTEN, check_cnthctl_el1pten),
+	CCC(CGT_CNTHCTL_EL1NVPCT, check_cnthctl_el1nvpct),
+	CCC(CGT_CNTHCTL_EL1NVVCT, check_cnthctl_el1nvvct),
 	CCC(CGT_CPTR_TTA, check_cptr_tta),
 	CCC(CGT_MDCR_HPMN, check_mdcr_hpmn),
 };
@@ -850,11 +895,15 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
 		      SYS_CNTHP_CVAL_EL2, CGT_HCR_NV),
 	SR_RANGE_TRAP(SYS_CNTHV_TVAL_EL2,
 		      SYS_CNTHV_CVAL_EL2, CGT_HCR_NV),
-	/* All _EL02, _EL12 registers */
+	/* All _EL02, _EL12 registers up to CNTKCTL_EL12*/
 	SR_RANGE_TRAP(sys_reg(3, 5, 0, 0, 0),
 		      sys_reg(3, 5, 10, 15, 7), CGT_HCR_NV),
 	SR_RANGE_TRAP(sys_reg(3, 5, 12, 0, 0),
-		      sys_reg(3, 5, 14, 15, 7), CGT_HCR_NV),
+		      sys_reg(3, 5, 14, 1, 0), CGT_HCR_NV),
+	SR_TRAP(SYS_CNTP_CTL_EL02,	CGT_CNTHCTL_EL1NVPCT),
+	SR_TRAP(SYS_CNTP_CVAL_EL02,	CGT_CNTHCTL_EL1NVPCT),
+	SR_TRAP(SYS_CNTV_CTL_EL02,	CGT_CNTHCTL_EL1NVVCT),
+	SR_TRAP(SYS_CNTV_CVAL_EL02,	CGT_CNTHCTL_EL1NVVCT),
 	SR_TRAP(OP_AT_S1E2R,		CGT_HCR_NV),
 	SR_TRAP(OP_AT_S1E2W,		CGT_HCR_NV),
 	SR_TRAP(OP_AT_S12E1R,		CGT_HCR_NV),
@@ -1184,6 +1233,11 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
 	SR_TRAP(SYS_CNTP_CTL_EL0,	CGT_CNTHCTL_EL1PTEN),
 	SR_TRAP(SYS_CNTPCT_EL0,		CGT_CNTHCTL_EL1PCTEN),
 	SR_TRAP(SYS_CNTPCTSS_EL0,	CGT_CNTHCTL_EL1PCTEN),
+	SR_TRAP(SYS_CNTV_TVAL_EL0,	CGT_CNTHCTL_EL1TVT),
+	SR_TRAP(SYS_CNTV_CVAL_EL0,	CGT_CNTHCTL_EL1TVT),
+	SR_TRAP(SYS_CNTV_CTL_EL0,	CGT_CNTHCTL_EL1TVT),
+	SR_TRAP(SYS_CNTVCT_EL0,		CGT_CNTHCTL_EL1TVCT),
+	SR_TRAP(SYS_CNTVCTSS_EL0,	CGT_CNTHCTL_EL1TVCT),
 	SR_TRAP(SYS_FPMR,		CGT_HCRX_EnFPM),
 	/*
 	 * IMPDEF choice:
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:17 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:17 +0000
Subject: [PATCH v2 09/12] KVM: arm64: nv: Propagate CNTHCTL_EL2.EL1NV{P,V}CT bits
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-10-maz@kernel.org>

Allow a guest hypervisor to trap accesses to CNT{P,V}CT_EL02 by
propagating these trap bits to the host trap configuration.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 6f04f31c0a7f2..e5951e6eaf236 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -824,6 +824,10 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 	 * Apply the enable bits that the guest hypervisor has requested for
 	 * its own guest. We can only add traps that wouldn't have been set
 	 * above.
+	 * Implementation choices: we do not support NV when E2H=0 in the
+	 * guest, and we don't support configuration where E2H is writable
+	 * by the guest (either FEAT_VHE or FEAT_E2H0 is implemented, but
+	 * not both). This simplifies the handling of the EL1NV* bits.
 	 */
 	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
 		u64 val = __vcpu_sys_reg(vcpu, CNTHCTL_EL2);
@@ -834,6 +838,9 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 
 		tpt |= !(val & (CNTHCTL_EL1PCEN << 10));
 		tpc |= !(val & (CNTHCTL_EL1PCTEN << 10));
+
+		tpt02 |= (val & CNTHCTL_EL1NVPCT);
+		tvt02 |= (val & CNTHCTL_EL1NVVCT);
 	}
 
 	/*
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:11 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:11 +0000
Subject: [PATCH v2 03/12] KVM: arm64: nv: Publish emulated timer interrupt state in the in-memory state
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-4-maz@kernel.org>

With FEAT_NV2, the EL0 timer state is entirely stored in memory,
meaning that the hypervisor can only provide a very poor emulation.

The only thing we can really do is to publish the interrupt state
in the guest view of CNT{P,V}_CTL_EL0, and defer everything else
to the next exit.

Only FEAT_ECV will allow us to fix it, at the cost of extra trapping.

Suggested-by: Chase Conklin <chase.conklin at arm.com>
Suggested-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c | 21 +++++++++++++++++++++
 arch/arm64/kvm/arm.c        |  2 +-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index ee5f732fbbece..8bff913ed1264 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -441,11 +441,30 @@ void kvm_timer_update_run(struct kvm_vcpu *vcpu)
 		regs->device_irq_level |= KVM_ARM_DEV_EL1_PTIMER;
 }
 
+static void kvm_timer_update_status(struct arch_timer_context *ctx, bool level)
+{
+	/*
+	 * Paper over NV2 brokenness by publishing the interrupt status
+	 * bit. This still results in a poor quality of emulation (guest
+	 * writes will have no effect until the next exit).
+	 *
+	 * But hey, it's fast, right?
+	 */
+	if (is_hyp_ctxt(ctx->vcpu) &&
+	    (ctx == vcpu_vtimer(ctx->vcpu) || ctx == vcpu_ptimer(ctx->vcpu))) {
+		unsigned long val = timer_get_ctl(ctx);
+		__assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &val, level);
+		timer_set_ctl(ctx, val);
+	}
+}
+
 static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
 				 struct arch_timer_context *timer_ctx)
 {
 	int ret;
 
+	kvm_timer_update_status(timer_ctx, new_level);
+
 	timer_ctx->irq.level = new_level;
 	trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_irq(timer_ctx),
 				   timer_ctx->irq.level);
@@ -471,6 +490,8 @@ static void timer_emulate(struct arch_timer_context *ctx)
 		return;
 	}
 
+	kvm_timer_update_status(ctx, should_fire);
+
 	/*
 	 * If the timer can fire now, we don't need to have a soft timer
 	 * scheduled for the future.  If the timer cannot fire at all,
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index fa3089822f9f3..bda905022df40 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1228,7 +1228,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
 			kvm_timer_sync_user(vcpu);
 
-		if (vcpu_has_nv(vcpu))
+		if (is_hyp_ctxt(vcpu))
 			kvm_timer_sync_nested(vcpu);
 
 		kvm_arch_vcpu_ctxsync_fp(vcpu);
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:13 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:13 +0000
Subject: [PATCH v2 05/12] KVM: arm64: nv: Accelerate EL0 timer read accesses when FEAT_ECV in use
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-6-maz@kernel.org>

Although FEAT_ECV allows us to correctly emulate the timers, it also
reduces performances pretty badly.

Mitigate this by emulating the CTL/CVAL register reads in the
inner run loop, without returning to the general kernel.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c             | 21 +-----
 arch/arm64/kvm/hyp/include/hyp/switch.h |  5 ++
 arch/arm64/kvm/hyp/vhe/switch.c         | 99 +++++++++++++++++++++++++
 include/kvm/arm_arch_timer.h            | 15 ++++
 4 files changed, 122 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index b6a06bda9e534..6f04f31c0a7f2 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -101,21 +101,6 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
 	}
 }
 
-static u64 timer_get_offset(struct arch_timer_context *ctxt)
-{
-	u64 offset = 0;
-
-	if (!ctxt)
-		return 0;
-
-	if (ctxt->offset.vm_offset)
-		offset += *ctxt->offset.vm_offset;
-	if (ctxt->offset.vcpu_offset)
-		offset += *ctxt->offset.vcpu_offset;
-
-	return offset;
-}
-
 static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
 {
 	struct kvm_vcpu *vcpu = ctxt->vcpu;
@@ -964,10 +949,10 @@ void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
 	 * which allows trapping of the timer registers even with NV2.
 	 * Still, this is still worse than FEAT_NV on its own. Meh.
 	 */
-	if (cpus_have_final_cap(ARM64_HAS_ECV) || !is_hyp_ctxt(vcpu))
-		return;
-
 	if (!vcpu_el2_e2h_is_set(vcpu)) {
+		if (cpus_have_final_cap(ARM64_HAS_ECV))
+			return;
+
 		/*
 		 * A non-VHE guest hypervisor doesn't have any direct access
 		 * to its timers: the EL2 registers trap (and the HW is
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 34f53707892df..30e572de28749 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -501,6 +501,11 @@ static inline bool handle_tx2_tvm(struct kvm_vcpu *vcpu)
 	return true;
 }
 
+static inline u64 compute_counter_value(struct arch_timer_context *ctxt)
+{
+	return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
+}
+
 static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_context *ctxt;
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 80581b1c39959..51119d58ecff8 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -256,6 +256,102 @@ void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
 	host_data_ptr(host_ctxt)->__hyp_running_vcpu = NULL;
 }
 
+static u64 compute_emulated_cntx_ctl_el0(struct kvm_vcpu *vcpu,
+					 enum vcpu_sysreg reg)
+{
+	unsigned long ctl;
+	u64 cval, cnt;
+	bool stat;
+
+	switch (reg) {
+	case CNTP_CTL_EL0:
+		cval = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
+		ctl  = __vcpu_sys_reg(vcpu, CNTP_CTL_EL0);
+		cnt  = compute_counter_value(vcpu_ptimer(vcpu));
+		break;
+	case CNTV_CTL_EL0:
+		cval = __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
+		ctl  = __vcpu_sys_reg(vcpu, CNTV_CTL_EL0);
+		cnt  = compute_counter_value(vcpu_vtimer(vcpu));
+		break;
+	default:
+		BUG();
+	}
+
+	stat = cval <= cnt;
+	__assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &ctl, stat);
+
+	return ctl;
+}
+
+static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	u64 esr, val;
+
+	/*
+	 * Having FEAT_ECV allows for a better quality of timer emulation.
+	 * However, this comes at a huge cost in terms of traps. Try and
+	 * satisfy the reads from guest's hypervisor context without
+	 * returning to the kernel if we can.
+	 */
+	if (!is_hyp_ctxt(vcpu))
+		return false;
+
+	esr = kvm_vcpu_get_esr(vcpu);
+	if ((esr & ESR_ELx_SYS64_ISS_DIR_MASK) != ESR_ELx_SYS64_ISS_DIR_READ)
+		return false;
+
+	switch (esr_sys64_to_sysreg(esr)) {
+	case SYS_CNTP_CTL_EL02:
+		val = compute_emulated_cntx_ctl_el0(vcpu, CNTP_CTL_EL0);
+		break;
+	case SYS_CNTP_CTL_EL0:
+		if (vcpu_el2_e2h_is_set(vcpu))
+			val = read_sysreg_el0(SYS_CNTP_CTL);
+		else
+			val = compute_emulated_cntx_ctl_el0(vcpu, CNTP_CTL_EL0);
+		break;
+	case SYS_CNTP_CVAL_EL02:
+		val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
+		break;
+	case SYS_CNTP_CVAL_EL0:
+		if (vcpu_el2_e2h_is_set(vcpu)) {
+			val = read_sysreg_el0(SYS_CNTP_CVAL);
+
+			if (!has_cntpoff())
+				val -= timer_get_offset(vcpu_hptimer(vcpu));
+		} else {
+			val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
+		}
+		break;
+	case SYS_CNTV_CTL_EL02:
+		val = compute_emulated_cntx_ctl_el0(vcpu, CNTV_CTL_EL0);
+		break;
+	case SYS_CNTV_CTL_EL0:
+		if (vcpu_el2_e2h_is_set(vcpu))
+			val = read_sysreg_el0(SYS_CNTV_CTL);
+		else
+			val = compute_emulated_cntx_ctl_el0(vcpu, CNTV_CTL_EL0);
+		break;
+	case SYS_CNTV_CVAL_EL02:
+		val = __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
+		break;
+	case SYS_CNTV_CVAL_EL0:
+		if (vcpu_el2_e2h_is_set(vcpu))
+			val = read_sysreg_el0(SYS_CNTV_CVAL);
+		else
+			val = __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
+		break;
+	default:
+		return false;
+	}
+
+	vcpu_set_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu), val);
+	__kvm_skip_instr(vcpu);
+
+	return true;
+}
+
 static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	u64 esr = kvm_vcpu_get_esr(vcpu);
@@ -409,6 +505,9 @@ static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
 	if (kvm_hyp_handle_tlbi_el2(vcpu, exit_code))
 		return true;
 
+	if (kvm_hyp_handle_timer(vcpu, exit_code))
+		return true;
+
 	if (kvm_hyp_handle_cpacr_el1(vcpu, exit_code))
 		return true;
 
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 6e3f6b7ff2b22..c1ba31fab6f52 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -156,4 +156,19 @@ static inline bool has_cntpoff(void)
 	return (has_vhe() && cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF));
 }
 
+static inline u64 timer_get_offset(struct arch_timer_context *ctxt)
+{
+	u64 offset = 0;
+
+	if (!ctxt)
+		return 0;
+
+	if (ctxt->offset.vm_offset)
+		offset += *ctxt->offset.vm_offset;
+	if (ctxt->offset.vcpu_offset)
+		offset += *ctxt->offset.vcpu_offset;
+
+	return offset;
+}
+
 #endif
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:14 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:14 +0000
Subject: [PATCH v2 06/12] KVM: arm64: nv: Accelerate EL0 counter accesses from hypervisor context
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-7-maz@kernel.org>

Similarly to handling the physical timer accesses early when FEAT_ECV
causes a trap, we try to handle the physical counter without returning
to the general sysreg handling.

More surprisingly, we introduce something similar for the virtual
counter. Although this isn't necessary yet, it will prove useful on
systems that have a broken CNTVOFF_EL2 implementation. Yes, they exist.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 51119d58ecff8..ef344bcff09a1 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -324,6 +324,10 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
 			val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
 		}
 		break;
+	case SYS_CNTPCT_EL0:
+	case SYS_CNTPCTSS_EL0:
+		val = compute_counter_value(vcpu_hptimer(vcpu));
+		break;
 	case SYS_CNTV_CTL_EL02:
 		val = compute_emulated_cntx_ctl_el0(vcpu, CNTV_CTL_EL0);
 		break;
@@ -342,6 +346,10 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
 		else
 			val = __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
 		break;
+	case SYS_CNTVCT_EL0:
+	case SYS_CNTVCTSS_EL0:
+		val = compute_counter_value(vcpu_hvtimer(vcpu));
+		break;
 	default:
 		return false;
 	}
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:18 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:18 +0000
Subject: [PATCH v2 10/12] KVM: arm64: nv: Sanitise CNTHCTL_EL2
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-11-maz@kernel.org>

Inject some sanity in CNTHCTL_EL2, ensuring that we don't handle
more than we advertise to the guest.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h    |  2 +-
 arch/arm64/kvm/nested.c              | 15 +++++++++++++++
 include/clocksource/arm_arch_timer.h |  2 ++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e18e9244d17a4..cf571d41faa89 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -490,7 +490,6 @@ enum vcpu_sysreg {
 	VBAR_EL2,	/* Vector Base Address Register (EL2) */
 	RVBAR_EL2,	/* Reset Vector Base Address Register */
 	CONTEXTIDR_EL2,	/* Context ID Register (EL2) */
-	CNTHCTL_EL2,	/* Counter-timer Hypervisor Control register */
 	SP_EL2,		/* EL2 Stack Pointer */
 	CNTHP_CTL_EL2,
 	CNTHP_CVAL_EL2,
@@ -501,6 +500,7 @@ enum vcpu_sysreg {
 	MARKER(__SANITISED_REG_START__),
 	TCR2_EL2,	/* Extended Translation Control Register (EL2) */
 	MDCR_EL2,	/* Monitor Debug Configuration Register (EL2) */
+	CNTHCTL_EL2,	/* Counter-timer Hypervisor Control register */
 
 	/* Any VNCR-capable reg goes after this point */
 	MARKER(__VNCR_START__),
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 9b36218b48def..9113c6025d6f3 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1271,6 +1271,21 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		res0 |= MDCR_EL2_EnSTEPOP;
 	set_sysreg_masks(kvm, MDCR_EL2, res0, res1);
 
+	/* CNTHCTL_EL2 */
+	res0 = GENMASK(63, 20);
+	res1 = 0;
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RME, IMP))
+		res0 |= CNTHCTL_CNTPMASK | CNTHCTL_CNTVMASK;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, ECV, CNTPOFF)) {
+		res0 |= CNTHCTL_ECV;
+		if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, ECV, IMP))
+			res0 |= (CNTHCTL_EL1TVT | CNTHCTL_EL1TVCT |
+				 CNTHCTL_EL1NVPCT | CNTHCTL_EL1NVVCT);
+	}
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, VH, IMP))
+		res0 |= GENMASK(11, 8);
+	set_sysreg_masks(kvm, CNTHCTL_EL2, res0, res1);
+
 	return 0;
 }
 
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index c62811fb41309..ce6521ad04d12 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -26,6 +26,8 @@
 #define CNTHCTL_EL1TVCT			(1 << 14)
 #define CNTHCTL_EL1NVPCT		(1 << 15)
 #define CNTHCTL_EL1NVVCT		(1 << 16)
+#define CNTHCTL_CNTVMASK		(1 << 18)
+#define CNTHCTL_CNTPMASK		(1 << 19)
 
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:15 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:15 +0000
Subject: [PATCH v2 07/12] KVM: arm64: Handle counter access early in non-HYP context
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-8-maz@kernel.org>

We already deal with CNTPCT_EL0 accesses in non-HYP context.
Let's add CNTVCT_EL0 as a good measure.

This is also an opportunity to simplify things and make it
plain that this code is only for non-HYP context handling.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 34 +++++++++++++++----------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 30e572de28749..719479b42b329 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -506,7 +506,7 @@ static inline u64 compute_counter_value(struct arch_timer_context *ctxt)
 	return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
 }
 
-static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
+static bool kvm_handle_cntxct(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_context *ctxt;
 	u32 sysreg;
@@ -516,18 +516,19 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
 	 * We only get here for 64bit guests, 32bit guests will hit
 	 * the long and winding road all the way to the standard
 	 * handling. Yes, it sucks to be irrelevant.
+	 *
+	 * Also, we only deal with non-hypervisor context here (either
+	 * an EL1 guest, or a non-HYP context of an EL2 guest).
 	 */
+	if (is_hyp_ctxt(vcpu))
+		return false;
+
 	sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
 
 	switch (sysreg) {
 	case SYS_CNTPCT_EL0:
 	case SYS_CNTPCTSS_EL0:
 		if (vcpu_has_nv(vcpu)) {
-			if (is_hyp_ctxt(vcpu)) {
-				ctxt = vcpu_hptimer(vcpu);
-				break;
-			}
-
 			/* Check for guest hypervisor trapping */
 			val = __vcpu_sys_reg(vcpu, CNTHCTL_EL2);
 			if (!vcpu_el2_e2h_is_set(vcpu))
@@ -539,16 +540,23 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
 
 		ctxt = vcpu_ptimer(vcpu);
 		break;
+	case SYS_CNTVCT_EL0:
+	case SYS_CNTVCTSS_EL0:
+		if (vcpu_has_nv(vcpu)) {
+			/* Check for guest hypervisor trapping */
+			val = __vcpu_sys_reg(vcpu, CNTHCTL_EL2);
+
+			if (val & CNTHCTL_EL1TVCT)
+				return false;
+		}
+
+		ctxt = vcpu_vtimer(vcpu);
+		break;
 	default:
 		return false;
 	}
 
-	val = arch_timer_read_cntpct_el0();
-
-	if (ctxt->offset.vm_offset)
-		val -= *kern_hyp_va(ctxt->offset.vm_offset);
-	if (ctxt->offset.vcpu_offset)
-		val -= *kern_hyp_va(ctxt->offset.vcpu_offset);
+	val = compute_counter_value(ctxt);
 
 	vcpu_set_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu), val);
 	__kvm_skip_instr(vcpu);
@@ -593,7 +601,7 @@ static bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
 	    __vgic_v3_perform_cpuif_access(vcpu) == 1)
 		return true;
 
-	if (kvm_hyp_handle_cntpct(vcpu))
+	if (kvm_handle_cntxct(vcpu))
 		return true;
 
 	return false;
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:20 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:20 +0000
Subject: [PATCH v2 12/12] KVM: arm64: nv: Document EL2 timer API
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-13-maz@kernel.org>

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 Documentation/virt/kvm/devices/vcpu.rst | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 31f14ec4a65b6..d62ba86ee1668 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -142,8 +142,9 @@ the cpu field to the processor id.
 
 :Architectures: ARM64
 
-2.1. ATTRIBUTES: KVM_ARM_VCPU_TIMER_IRQ_VTIMER, KVM_ARM_VCPU_TIMER_IRQ_PTIMER
------------------------------------------------------------------------------
+2.1. ATTRIBUTES: KVM_ARM_VCPU_TIMER_IRQ_VTIMER, KVM_ARM_VCPU_TIMER_IRQ_PTIMER,
+                 KVM_ARM_VCPU_TIMER_IRQ_HVTIMER, KVM_ARM_VCPU_TIMER_IRQ_HPTIMER,
+--------------------------------------------------------------------------------
 
 :Parameters: in kvm_device_attr.addr the address for the timer interrupt is a
 	     pointer to an int
@@ -159,10 +160,12 @@ A value describing the architected timer interrupt number when connected to an
 in-kernel virtual GIC.  These must be a PPI (16 <= intid < 32).  Setting the
 attribute overrides the default values (see below).
 
-=============================  ==========================================
-KVM_ARM_VCPU_TIMER_IRQ_VTIMER  The EL1 virtual timer intid (default: 27)
-KVM_ARM_VCPU_TIMER_IRQ_PTIMER  The EL1 physical timer intid (default: 30)
-=============================  ==========================================
+==============================  ==========================================
+KVM_ARM_VCPU_TIMER_IRQ_VTIMER   The EL1 virtual timer intid (default: 27)
+KVM_ARM_VCPU_TIMER_IRQ_PTIMER   The EL1 physical timer intid (default: 30)
+KVM_ARM_VCPU_TIMER_IRQ_HVTIMER  The EL2 virtual timer intid (default: 28)
+KVM_ARM_VCPU_TIMER_IRQ_HPTIMER  The EL2 physical timer intid (default: 26)
+==============================  ==========================================
 
 Setting the same PPI for different timers will prevent the VCPUs from running.
 Setting the interrupt number on a VCPU configures all VCPUs created at that
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:12 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:12 +0000
Subject: [PATCH v2 04/12] KVM: arm64: nv: Use FEAT_ECV to trap access to EL0 timers
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-5-maz@kernel.org>

Although FEAT_NV2 makes most things fast, it also makes it impossible
to correctly emulate the timers, as the sysreg accesses are redirected
to memory.

FEAT_ECV addresses this by giving a hypervisor the ability to trap
the EL02 sysregs as well as the virtual timer.

Add the required trap setting to make use of the feature, allowing
us to elide the ugly resync in the middle of the run loop.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c          | 36 +++++++++++++++++++++++++---
 include/clocksource/arm_arch_timer.h |  2 ++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 8bff913ed1264..b6a06bda9e534 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -783,7 +783,7 @@ static void kvm_timer_vcpu_load_nested_switch(struct kvm_vcpu *vcpu,
 
 static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 {
-	bool tpt, tpc;
+	bool tvt, tpt, tvc, tpc, tvt02, tpt02;
 	u64 clr, set;
 
 	/*
@@ -798,7 +798,29 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 	 * within this function, reality kicks in and we start adding
 	 * traps based on emulation requirements.
 	 */
-	tpt = tpc = false;
+	tvt = tpt = tvc = tpc = false;
+	tvt02 = tpt02 = false;
+
+	/*
+	 * NV2 badly breaks the timer semantics by redirecting accesses to
+	 * the EL1 timer state to memory, so let's call ECV to the rescue if
+	 * available: we trap all CNT{P,V}_{CTL,CVAL,TVAL}_EL0 accesses.
+	 *
+	 * The treatment slightly varies depending whether we run a nVHE or
+	 * VHE guest: nVHE will use the _EL0 registers directly, while VHE
+	 * will use the _EL02 accessors. This translates in different trap
+	 * bits.
+	 *
+	 * None of the trapping is required when running in non-HYP context,
+	 * unless required by the L1 hypervisor settings once we advertise
+	 * ECV+NV in the guest, or that we need trapping for other reasons.
+	 */
+	if (cpus_have_final_cap(ARM64_HAS_ECV) && is_hyp_ctxt(vcpu)) {
+		if (vcpu_el2_e2h_is_set(vcpu))
+			tvt02 = tpt02 = true;
+		else
+			tvt = tpt = true;
+	}
 
 	/*
 	 * We have two possibility to deal with a physical offset:
@@ -838,6 +860,10 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 
 	assign_clear_set_bit(tpt, CNTHCTL_EL1PCEN << 10, set, clr);
 	assign_clear_set_bit(tpc, CNTHCTL_EL1PCTEN << 10, set, clr);
+	assign_clear_set_bit(tvt, CNTHCTL_EL1TVT, clr, set);
+	assign_clear_set_bit(tvc, CNTHCTL_EL1TVCT, clr, set);
+	assign_clear_set_bit(tvt02, CNTHCTL_EL1NVVCT, clr, set);
+	assign_clear_set_bit(tpt02, CNTHCTL_EL1NVPCT, clr, set);
 
 	/* This only happens on VHE, so use the CNTHCTL_EL2 accessor. */
 	sysreg_clear_set(cnthctl_el2, clr, set);
@@ -933,8 +959,12 @@ void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
 	 * accesses redirected to the VNCR page. Any guest action taken on
 	 * the timer is postponed until the next exit, leading to a very
 	 * poor quality of emulation.
+	 *
+	 * This is an unmitigated disaster, only papered over by FEAT_ECV,
+	 * which allows trapping of the timer registers even with NV2.
+	 * Still, this is still worse than FEAT_NV on its own. Meh.
 	 */
-	if (!is_hyp_ctxt(vcpu))
+	if (cpus_have_final_cap(ARM64_HAS_ECV) || !is_hyp_ctxt(vcpu))
 		return;
 
 	if (!vcpu_el2_e2h_is_set(vcpu)) {
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index 877dcbb2601ae..c62811fb41309 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -24,6 +24,8 @@
 #define CNTHCTL_ECV			(1 << 12)
 #define CNTHCTL_EL1TVT			(1 << 13)
 #define CNTHCTL_EL1TVCT			(1 << 14)
+#define CNTHCTL_EL1NVPCT		(1 << 15)
+#define CNTHCTL_EL1NVVCT		(1 << 16)
 
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 06:23:19 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 14:23:19 +0000
Subject: [PATCH v2 11/12] KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity
In-Reply-To: <20241217142321.763801-1-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
Message-ID: <20241217142321.763801-12-maz@kernel.org>

It appears that on Qualcomm's x1e CPU, CNTVOFF_EL2 doesn't really
work, specially with HCR_EL2.E2H=1.

A non-zero offset results in a screaming virtual timer interrupt,
to the tune of a few 100k interrupts per second on a 4 vcpu VM.
This is also evidenced by this CPU's inability to correctly run
any of the timer selftests.

The only case this doesn't break is when this register is set to 0,
which breaks VM migration.

When HCR_EL2.E2H=0, the timer seems to behave normally, and does
not result in an interrupt storm.

As a workaround, use the fact that this CPU implements FEAT_ECV,
and trap all accesses to the virtual timer and counter, keeping
CNTVOFF_EL2 set to zero, and emulate accesses to CVAL/TVAL/CTL
and the counter itself, fixing up the timer to account for the
missing offset.

And if you think this is disgusting, you'd probably be right.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/cputype.h   |  2 ++
 arch/arm64/kernel/cpu_errata.c     |  8 +++++
 arch/arm64/kernel/image-vars.h     |  3 ++
 arch/arm64/kvm/arch_timer.c        | 58 ++++++++++++++++++++++++++++--
 arch/arm64/kvm/hyp/nvhe/timer-sr.c | 16 ++++++---
 arch/arm64/kvm/sys_regs.c          |  3 +-
 arch/arm64/tools/cpucaps           |  1 +
 include/kvm/arm_arch_timer.h       |  7 ++++
 8 files changed, 90 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 488f8e7513495..6f3f4142e214f 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -122,6 +122,7 @@
 #define QCOM_CPU_PART_KRYO_3XX_SILVER	0x803
 #define QCOM_CPU_PART_KRYO_4XX_GOLD	0x804
 #define QCOM_CPU_PART_KRYO_4XX_SILVER	0x805
+#define QCOM_CPU_PART_ORYON_X1		0x001
 
 #define NVIDIA_CPU_PART_DENVER		0x003
 #define NVIDIA_CPU_PART_CARMEL		0x004
@@ -198,6 +199,7 @@
 #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER)
 #define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD)
 #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
+#define MIDR_QCOM_ORYON_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_ORYON_X1)
 #define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER)
 #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL)
 #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index a78f247029aec..7ce5558628951 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -786,6 +786,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_RANGE_LIST(erratum_ac03_cpu_38_list),
 	},
 #endif
+	{
+		.desc = "Broken CNTVOFF_EL2",
+		.capability = ARM64_WORKAROUND_QCOM_ORYON_CNTVOFF,
+		ERRATA_MIDR_RANGE_LIST(((const struct midr_range[]) {
+					MIDR_ALL_VERSIONS(MIDR_QCOM_ORYON_X1),
+					{}
+				})),
+	},
 	{
 	}
 };
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 8f5422ed1b758..ef3a69cc398e5 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -105,6 +105,9 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors);
 KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);
 KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
 
+/* Static key which is set if CNTVOFF_EL2 is unusable */
+KVM_NVHE_ALIAS(broken_cntvoff_key);
+
 /* EL2 exception handling */
 KVM_NVHE_ALIAS(__start___kvm_ex_table);
 KVM_NVHE_ALIAS(__stop___kvm_ex_table);
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index e5951e6eaf236..d3d243366536c 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -30,6 +30,7 @@ static u32 host_vtimer_irq_flags;
 static u32 host_ptimer_irq_flags;
 
 static DEFINE_STATIC_KEY_FALSE(has_gic_active_state);
+DEFINE_STATIC_KEY_FALSE(broken_cntvoff_key);
 
 static const u8 default_ppi[] = {
 	[TIMER_PTIMER]  = 30,
@@ -519,7 +520,12 @@ static void timer_save_state(struct arch_timer_context *ctx)
 	case TIMER_VTIMER:
 	case TIMER_HVTIMER:
 		timer_set_ctl(ctx, read_sysreg_el0(SYS_CNTV_CTL));
-		timer_set_cval(ctx, read_sysreg_el0(SYS_CNTV_CVAL));
+		cval = read_sysreg_el0(SYS_CNTV_CVAL);
+
+		if (has_broken_cntvoff())
+			cval -= timer_get_offset(ctx);
+
+		timer_set_cval(ctx, cval);
 
 		/* Disable the timer */
 		write_sysreg_el0(0, SYS_CNTV_CTL);
@@ -624,8 +630,15 @@ static void timer_restore_state(struct arch_timer_context *ctx)
 
 	case TIMER_VTIMER:
 	case TIMER_HVTIMER:
-		set_cntvoff(timer_get_offset(ctx));
-		write_sysreg_el0(timer_get_cval(ctx), SYS_CNTV_CVAL);
+		cval = timer_get_cval(ctx);
+		offset = timer_get_offset(ctx);
+		if (has_broken_cntvoff()) {
+			set_cntvoff(0);
+			cval += offset;
+		} else {
+			set_cntvoff(offset);
+		}
+		write_sysreg_el0(cval, SYS_CNTV_CVAL);
 		isb();
 		write_sysreg_el0(timer_get_ctl(ctx), SYS_CNTV_CTL);
 		break;
@@ -820,6 +833,13 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
 	if (!has_cntpoff() && timer_get_offset(map->direct_ptimer))
 		tpt = tpc = true;
 
+	/*
+	 * For the poor sods that could not correctly substract one value
+	 * from another, trap the full virtual timer and counter.
+	 */
+	if (has_broken_cntvoff() && timer_get_offset(map->direct_vtimer))
+		tvt = tvc = true;
+
 	/*
 	 * Apply the enable bits that the guest hypervisor has requested for
 	 * its own guest. We can only add traps that wouldn't have been set
@@ -1450,6 +1470,37 @@ static int kvm_irq_init(struct arch_timer_kvm_info *info)
 	return 0;
 }
 
+static void kvm_timer_handle_errata(void)
+{
+	u64 mmfr0, mmfr1, mmfr4;
+
+	/*
+	 * CNTVOFF_EL2 is broken on some implementations. For those, we trap
+	 * all virtual timer/counter accesses, requiring FEAT_ECV.
+	 *
+	 * However, a hypervisor supporting nesting is likely to mitigate the
+	 * erratum at L0, and not require other levels to mitigate it (which
+	 * would otherwise be a terrible performance sink due to trap
+	 * amplification).
+	 *
+	 * Given that the affected HW implements both FEAT_VHE and FEAT_E2H0,
+	 * and that NV is likely not to (because of limitations of the
+	 * architecture), only enable the workaround when FEAT_VHE and
+	 * FEAT_E2H0 are both detected. Time will tell if this actually holds.
+	 */
+	mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
+	mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
+	mmfr4 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR4_EL1);
+	if (SYS_FIELD_GET(ID_AA64MMFR1_EL1, VH, mmfr1)		&&
+	    !SYS_FIELD_GET(ID_AA64MMFR4_EL1, E2H0, mmfr4)	&&
+	    SYS_FIELD_GET(ID_AA64MMFR0_EL1, ECV, mmfr0)		&&
+	    (has_vhe() || has_hvhe())				&&
+	    cpus_have_final_cap(ARM64_WORKAROUND_QCOM_ORYON_CNTVOFF)) {
+		static_branch_enable(&broken_cntvoff_key);
+		kvm_info("Broken CNTVOFF_EL2, trapping virtual timer\n");
+	}
+}
+
 int __init kvm_timer_hyp_init(bool has_gic)
 {
 	struct arch_timer_kvm_info *info;
@@ -1518,6 +1569,7 @@ int __init kvm_timer_hyp_init(bool has_gic)
 		goto out_free_vtimer_irq;
 	}
 
+	kvm_timer_handle_errata();
 	return 0;
 
 out_free_ptimer_irq:
diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index 3aaab20ae5b47..ff176f4ce7deb 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -22,15 +22,16 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
  */
 void __timer_disable_traps(struct kvm_vcpu *vcpu)
 {
-	u64 val, shift = 0;
+	u64 set, clr, shift = 0;
 
 	if (has_hvhe())
 		shift = 10;
 
 	/* Allow physical timer/counter access for the host */
-	val = read_sysreg(cnthctl_el2);
-	val |= (CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN) << shift;
-	write_sysreg(val, cnthctl_el2);
+	set = (CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN) << shift;
+	clr = CNTHCTL_EL1TVT | CNTHCTL_EL1TVCT;
+
+	sysreg_clear_set(cnthctl_el2, clr, set);
 }
 
 /*
@@ -58,5 +59,12 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
 		set <<= 10;
 	}
 
+	/*
+	 * Trap the virtual counter/timer if we have a broken cntvoff
+	 * implementation.
+	 */
+	if (has_broken_cntvoff())
+		set |= CNTHCTL_EL1TVT | CNTHCTL_EL1TVCT;
+
 	sysreg_clear_set(cnthctl_el2, clr, set);
 }
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 986e63d4f9faa..d161d6c05707a 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1721,7 +1721,8 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
 		if (!vcpu_has_ptrauth(vcpu))
 			val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3) |
 				 ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3));
-		if (!cpus_have_final_cap(ARM64_HAS_WFXT))
+		if (!cpus_have_final_cap(ARM64_HAS_WFXT) ||
+		    has_broken_cntvoff())
 			val &= ~ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_WFxT);
 		break;
 	case SYS_ID_AA64MMFR2_EL1:
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index eb17f59e543c4..1e65f2fb45bd1 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -105,6 +105,7 @@ WORKAROUND_CLEAN_CACHE
 WORKAROUND_DEVICE_LOAD_ACQUIRE
 WORKAROUND_NVIDIA_CARMEL_CNP
 WORKAROUND_QCOM_FALKOR_E1003
+WORKAROUND_QCOM_ORYON_CNTVOFF
 WORKAROUND_REPEAT_TLBI
 WORKAROUND_SPECULATIVE_AT
 WORKAROUND_SPECULATIVE_SSBS
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index c1ba31fab6f52..681cf0c8b9df4 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -151,6 +151,13 @@ void kvm_timer_cpu_down(void);
 /* CNTKCTL_EL1 valid bits as of DDI0487J.a */
 #define CNTKCTL_VALID_BITS	(BIT(17) | GENMASK_ULL(9, 0))
 
+DECLARE_STATIC_KEY_FALSE(broken_cntvoff_key);
+
+static inline bool has_broken_cntvoff(void)
+{
+	return static_branch_unlikely(&broken_cntvoff_key);
+}
+
 static inline bool has_cntpoff(void)
 {
 	return (has_vhe() && cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF));
-- 
2.39.2



From qperret at google.com  Tue Dec 17 06:31:35 2024
From: qperret at google.com (Quentin Perret)
Date: Tue, 17 Dec 2024 14:31:35 +0000
Subject: [PATCH v3 18/18] KVM: arm64: Plumb the pKVM MMU in KVM
In-Reply-To: <86ttb2qudi.wl-maz@kernel.org>
References: <20241216175803.2716565-1-qperret@google.com>
 <20241216175803.2716565-19-qperret@google.com>
 <86ttb2qudi.wl-maz@kernel.org>
Message-ID: <Z2GLR8KZzJn1YpUu@google.com>

On Tuesday 17 Dec 2024 at 14:03:37 (+0000), Marc Zyngier wrote:
> My gripe with this is that it makes it much harder to follow what is
> happening by using tags (ctags, etags, whatever). I ended up with the
> hack below, which is super ugly, but preserves the tagging
> functionality for non-pKVM.

Ack.

> I'll scratch my head to find something more elegant...

I find your proposal pretty reasonable -- I had a few different ideas
but they were all really over-engineered, so I figured relying on a
naming convention was the simplest. And any divergence will be flagged
at compile time, so that shouldn't be too hard to maintain looking
forward.

The __S2 name isn't massively descriptive though. Maybe KVM_PGT_CALL()
or something? Thinking about it, this abstraction doesn't need to be
restricted to stage-2 stuff. We could most likely hide the
__pkvm_host_{un}share_hyp() logic behind a pkvm_pgtable_hyp_{un}map()
implementation in pkvm.c as well...


From suzuki.poulose at arm.com  Tue Dec 17 06:36:25 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 17 Dec 2024 14:36:25 +0000
Subject: [PATCH v7 0/4] source filtering for multi-port output
In-Reply-To: <20241213100731.25914-1-quic_taozha@quicinc.com>
References: <20241213100731.25914-1-quic_taozha@quicinc.com>
Message-ID: <173444598114.864570.18416527651218850484.b4-ty@arm.com>

On Fri, 13 Dec 2024 18:07:27 +0800, Tao Zhang wrote:
> In our hardware design, by combining a funnel and a replicator, it
> implement a hardware device with one-to-one correspondence between
> output ports and input ports. The programming usage on this device
> is the same as funnel. The software uses a funnel and a static
> replicator to implement the driver of this device. Since original
> funnels only support a single output connection and original
> replicator only support a single input connection, the code needs
> to be modified to support this new feature. The following is a
> typical topology diagram of multi-port output mechanism.
> |----------|     |---------|     |----------|   |---------|
> |  TPDM 0  |     | Source0 |     | Source 1 |   | TPDM 1  |
> |----------|     |---------|     |----------|   |---------|
>       |                |                |             |
>       |                |                |             |
>       |      --------- |                |             |
>       |      |                          |             |
>       |      |                          |             |
>       |      |                          |             |
>    \-------------/ ----------------------             |
>     \  Funnel 0 /  |                                  |
>      -----------   |     ------------------------------
>           |        |     |
>           |        |     |
>         \------------------/
>          \    Funnel 1    /     ----|
>           \--------------/          |
>                   |                 |----> Combine a funnel and a
>                   |                 |      static replicator
>           /-----------------\       |
>          /    replicator 0   \  ----|
>         /---------------------\
>              |     |      |
>              |     |      |-----------|
>              |     |---------|        |
>              |               |TPDM0   |TPDM1
>              |            \-----------------/
>              |             \   TPDA 0      /
>              |              \-------------/
>              |                    |
>              |                    |
>              |Source0/1           |
>           \-------------------------------/
>            \           Funnel 2          /
>             \---------------------------/
> 
> [...]

Applied, thanks!

[1/4] dt-bindings: arm: qcom,coresight-static-replicator: Add property for source filtering
      https://git.kernel.org/coresight/c/2a0bc219272b
[2/4] coresight: Add a helper to check if a device is source
      https://git.kernel.org/coresight/c/62374ce1876b
[3/4] coresight: Add support for trace filtering by source
      https://git.kernel.org/coresight/c/ec9903d6cc34
[4/4] coresight-tpda: Optimize the function of reading element size
      https://git.kernel.org/coresight/c/56e14a21cee4

Best regards,
-- 
Suzuki K Poulose <suzuki.poulose at arm.com>


From geert+renesas at glider.be  Tue Dec 17 06:37:40 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue, 17 Dec 2024 15:37:40 +0100
Subject: [PATCH] firmware: imx: IMX_SCMI_MISC_DRV should depend on ARCH_MXC
Message-ID: <28f88e536cab0abd5712787350b012bb0f1eacb5.1734445715.git.geert+renesas@glider.be>

The i.MX System Controller Management Interface firmware is only present
on Freescale i.MX SoCs.  Hence add a dependency on ARCH_MXC, to prevent
asking the user about this driver when configuring a kernel without
Freescale i.MX platform support.

Fixes: 514b2262ade48a05 ("firmware: arm_scmi: Fix i.MX build dependency")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 drivers/firmware/imx/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/firmware/imx/Kconfig b/drivers/firmware/imx/Kconfig
index 907cd149c40a8b5f..c964f4924359fcd3 100644
--- a/drivers/firmware/imx/Kconfig
+++ b/drivers/firmware/imx/Kconfig
@@ -25,6 +25,7 @@ config IMX_SCU
 
 config IMX_SCMI_MISC_DRV
 	tristate "IMX SCMI MISC Protocol driver"
+	depends on ARCH_MXC || COMPILE_TEST
 	default y if ARCH_MXC
 	help
 	  The System Controller Management Interface firmware (SCMI FW) is
-- 
2.34.1



From vladimir.zapolskiy at linaro.org  Tue Dec 17 06:40:12 2024
From: vladimir.zapolskiy at linaro.org (Vladimir Zapolskiy)
Date: Tue, 17 Dec 2024 16:40:12 +0200
Subject: [PATCH v10 4/4] arm64: dts: qcom:
 qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <20241217140656.965235-5-quic_vikramsa@quicinc.com>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-5-quic_vikramsa@quicinc.com>
Message-ID: <22479c27-9265-4994-8974-9739ecbae5ee@linaro.org>

On 12/17/24 16:06, Vikram Sharma wrote:
> The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
> Enable the IMX577 on the vision mezzanine.
> 
> An example media-ctl pipeline for the imx577 is:
> 
> media-ctl --reset
> media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
> media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
> media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
> media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
> media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
> media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
> 
> yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0
> 
> Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> ---
>   arch/arm64/boot/dts/qcom/Makefile             |   4 +
>   .../qcs6490-rb3gen2-vision-mezzanine.dtso     | 109 ++++++++++++++++++
>   2 files changed, 113 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
> 
> diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
> index 4686f2a8ddd8..a7e88fcabded 100644
> --- a/arch/arm64/boot/dts/qcom/Makefile
> +++ b/arch/arm64/boot/dts/qcom/Makefile
> @@ -115,6 +115,10 @@ dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-1000.dtb
>   dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-4000.dtb
>   dtb-$(CONFIG_ARCH_QCOM)	+= qcs615-ride.dtb
>   dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
> +
> +qcs6490-rb3gen2-vision-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine.dtbo
> +
> +dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2-vision-mezzanine.dtb
>   dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-ride.dtb
>   dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
>   dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride.dtb
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
> new file mode 100644
> index 000000000000..7782c4aee576
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
> @@ -0,0 +1,109 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +/*
> + * Camera Sensor overlay on top of rb3gen2 core kit.
> + */
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/clock/qcom,camcc-sc7280.h>

Please sort the header files alphabetically.

> +
> +/dts-v1/;
> +/plugin/;
> +

Please put these two lines right after the comments header.

> +&camss {
> +	vdda-phy-supply = <&vreg_l10c_0p88>;
> +	vdda-pll-supply = <&vreg_l6b_1p2>;
> +
> +	status = "okay";
> +
> +	ports {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		/* The port index denotes CSIPHY id i.e. csiphy3 */
> +		port at 3 {
> +			reg = <3>;
> +
> +			csiphy3_ep: endpoint {
> +				clock-lanes = <7>;
> +				data-lanes = <0 1 2 3>;
> +				remote-endpoint = <&imx577_ep>;
> +			};
> +		};
> +	};
> +};
> +
> +&cci1 {
> +	status = "okay";
> +};
> +
> +&cci1_i2c1 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	camera at 1a {
> +		compatible = "sony,imx577";
> +
> +		reg = <0x1a>;
> +
> +		reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>;
> +		pinctrl-names = "default", "suspend";
> +		pinctrl-0 = <&cam2_default>;
> +		pinctrl-1 = <&cam2_suspend>;
> +
> +		clocks = <&camcc CAM_CC_MCLK3_CLK>;
> +		assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>;
> +		assigned-clock-rates = <24000000>;
> +
> +		dovdd-supply  = <&vreg_l18b_1p8>;

Please remove double space before '='.

> +		avdd-supply = <&vph_pwr>;
> +		dvdd-supply = <&vph_pwr>;
> +
> +		port {
> +			imx577_ep: endpoint {
> +				clock-lanes = <7>;

It is an invalid property/value of the sensor, please remove it.

> +				link-frequencies = /bits/ 64 <600000000>;
> +				data-lanes = <0 1 2 3>;

data-lanes = <1 2 3 4>;

> +				remote-endpoint = <&csiphy3_ep>;
> +			};
> +		};
> +	};
> +};
> +
> +&tlmm {
> +	cam2_default: cam2-default-state {
> +		mclk-pins {
> +			pins = "gpio67";
> +			function = "cam_mclk";
> +			drive-strength = <2>;
> +			bias-disable;
> +		};
> +
> +		rst-pins {
> +			pins = "gpio78";
> +			function = "gpio";
> +			drive-strength = <2>;
> +			bias-disable;
> +		};
> +	};
> +
> +	cam2_suspend: cam2-suspend-state {
> +		mclk-pins {
> +			pins = "gpio67";
> +			function = "cam_mclk";
> +			drive-strength = <2>;
> +			bias-pull-down;
> +		};
> +
> +		rst-pins {
> +			pins = "gpio78";
> +			function = "gpio";
> +			drive-strength = <2>;
> +			bias-pull-down;
> +			output-low;
> +		};

I have doubts that it's proper to embed a reset gpio into driver's
pinctrl suspend/resume power management.

Konrad, can you please confirm that it's really accepted?

I'd rather ask to remove this reset pin control.

> +	};
> +};

--
Best wishes,
Vladimir


From cristian.marussi at arm.com  Tue Dec 17 06:45:24 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 17 Dec 2024 14:45:24 +0000
Subject: [PATCH V4 0/5] arm_scmi: vendors: Qualcomm Generic Vendor
 Extensions
In-Reply-To: <d313e40b-fa8f-a534-5037-98536ee25044@quicinc.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <ZytnRc94iKUfMYH0@hovoldconsulting.com>
 <ZyvLktLUZOGP-LH5@pluto>
 <Zy4qvedrmkRdPR3x@hovoldconsulting.com>
 <8d42682b-0fa7-3962-da12-728cfe64903b@quicinc.com>
 <Z0BC203BhGEmXcJi@hovoldconsulting.com>
 <Z1HceQegfMl07qj_@bogus>
 <d313e40b-fa8f-a534-5037-98536ee25044@quicinc.com>
Message-ID: <Z2GOLFqnexEalBx_@pluto>

On Tue, Dec 17, 2024 at 05:55:35PM +0530, Sibi Sankar wrote:
> 
> 
> On 12/5/24 22:31, Sudeep Holla wrote:
> > On Fri, Nov 22, 2024 at 09:37:47AM +0100, Johan Hovold wrote:
> > > On Thu, Nov 14, 2024 at 09:52:12AM +0530, Sibi Sankar wrote:
> > > > On 11/8/24 20:44, Johan Hovold wrote:
> > > 
> > > > > > On Wed, Nov 06, 2024 at 01:55:33PM +0100, Johan Hovold wrote:
> > > 
> > > > > > > Second, after loading the protocol and client drivers manually (in that
> > > > > > > order, shouldn't the client driver pull in the protocol?), I got:
> > > > > > > 
> > > > > > > 	scmi_module: Loaded SCMI Vendor Protocol 0x80 - Qualcomm  20000
> > > > > > > 	arm-scmi arm-scmi.0.auto: QCOM Generic Vendor Version 1.0
> > > > > > > 	scmi-qcom-generic-ext-memlat scmi_dev.5: error -EOPNOTSUPP: failed to configure common events
> > > > > > > 	scmi-qcom-generic-ext-memlat scmi_dev.5: probe with driver scmi-qcom-generic-ext-memlat failed with error -95
> > > > > > > 
> > > > > > > which seems to suggest that the firmware on my CRD does not support this
> > > > > > > feature. Is that the way this should be interpreted? And does that mean
> > > > > > > that non of the commercial laptops supports this either?
> > > 
> > > > > Yeah, hopefully Sibi can shed some light on this. I'm using the DT
> > > > > patch (5/5) from this series, which according to the commit message is
> > > > > supposed to enable bus scaling on the x1e80100 platform. So I guess
> > > > > something is missing in my firmware.
> > > > 
> > > > Nah, it's probably just because of the algo string used.
> > > > The past few series used caps MEMLAT string instead of
> > > > memlat to pass the tuneables, looks like all the laptops
> > > > havn't really switched to it yet. Will revert back to
> > > > using to lower case memlat so that all devices are
> > > > supported. Thanks for trying the series out!
> > > 
> > > I have a Lenovo ThinkPad T14s set up now so I gave this series a spin
> > > there too, and there I do *not* see the above mentioned -EOPNOSUPP error
> > > and the memlat driver probes successfully.
> > > 
> > > On the other hand, this series seems to have no effect on a kernel
> > > compilation benchmark. Is that expected?
> > > 
> > 
> > Hijacking this thread to rant about state of firmware implementation on
> > this platform that gives me zero confidence in merging any of these without
> > examining each of the interface details in depth and at lengths.
> > 
> 

Hi Sibi,

> Hey Sudeep,
> 
> Thanks for taking time to review the series.
> 
> > Also I see the standard protocol like PERF seem to have so many issues which
> > adds to my no confidence. I can't comment on that thread for specific reasons.
> 
> ^^ is largely untrue, a lot of finger pointing and a gross
> misrepresentation of reality :/
> 
> The only major problem that X1E perf protocol has is a firmware
> crash in the LEVEL_GET regular message implementation. This
> pretty much went unnoticed because of messaging in perf implementation
> in kernel. Given the fastchannel implementation isn't mandatory
> according to spec, the kernel clearly says it switches to
> regular messaging when it clearly doesn't do that and uses
> stale data structures instead. This ensured that level get regular
> messaging never got tested.

You claimed this a couple of times here and on IRC, but sincerely,
looking at the fastchannel implementation in SCMI core and Perf, I could
not track down where this could have happened in the recent code
(i.e. with or without your recent, welcomed, patches...)

When FC initialization fails and bailout it says:
	
	"Failed to get FC for protocol %X [MSG_ID:%u / RES_ID:%u] - ret:%d. Using regular messaging."

... and it clears any gathered address for that FC, so that in __scmi_perf_level_get()
you end up skipping the FC machinery and use messaging

	if (dom->fc_info && dom->fc_info[PERF_FC_LEVEL].get_addr) {
		...
	}

	return scmi_perf_msg_level_get(ph, dom->id, level, poll);

Now this is done ONLY for the FC that specifically failed
initialization, i.e. identified by the tuple PROTO_ID/MSG_ID/RES_ID
(as stated in the noisy message above where MSG_ID is specified) NOT for
all Fastchannel, so you can have an FC successfully initialized only on
the GET but failing in the SET, so only the GET FC will be used.

I dont really understand how the Kernel was misbehaving and using
instead stale data, neither, if this was the case, I can see where this
issue would have been fixed.

To be clear, I am not really interested in throwing an argument here, but
I sincerely dont see where the alleged problem was and how was fixed (kernel
side), so I fear it could be still there, hidden maybe by a change in the
platform fw.

Apologies if I missed something along the history of this..

Thanks,
Cristian


From neil.armstrong at linaro.org  Tue Dec 17 06:53:10 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 17 Dec 2024 15:53:10 +0100
Subject: [PATCH RFC 2/3] pinctrl: Add driver support for Amlogic SoCs
In-Reply-To: <CACRpkdbuj-_sPpdfcyg3_QNtzt9r7n-0HBGBKgy-rKUMhvGo4w@mail.gmail.com>
References: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
 <20241211-amlogic-pinctrl-v1-2-410727335119@amlogic.com>
 <CACRpkdbuj-_sPpdfcyg3_QNtzt9r7n-0HBGBKgy-rKUMhvGo4w@mail.gmail.com>
Message-ID: <168829c7-fd56-4fd2-80b0-07c768779559@linaro.org>

Hi,

On 17/12/2024 15:49, Linus Walleij wrote:
> Hi Xianwei,
> 
> thanks for your patch!
> 
> On Wed, Dec 11, 2024 at 7:48?AM Xianwei Zhao via B4 Relay
> <devnull+xianwei.zhao.amlogic.com at kernel.org> wrote:
> 
>> From: Xianwei Zhao <xianwei.zhao at amlogic.com>
>>
>> Add a new pinctrl driver for Amlogic SoCs. All future Amlogic
>> SoCs pinctrl drives use this, such A4, A5, S6, S7 etc. To support
>> new Amlogic SoCs, only need to add the corresponding dts file.
>>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
> 
> First: are we sure these new SoCs have nothing in common
> with sunxi? Because then the sunxi code should be reused.
> 
> In any way I recommend:
> 
> - Renaming drivers/pinctrl/sunxi to drivers/pinctrl/amlogic
>    so we keep this sorted by actual vendor, sunxi is apparently
>    yours (AMlogic:s) isn't it?

Sunxi is Allwinner SoCs.

Neil

> 
> - Also fix MAINTAINERS accordingly.
> 
> - Add new driver under drivers/pinctrl/amlogic
> 
> - Do not change the Kconfig symbols for sunxi and
>    we should be fine.
> 
>> +static int aml_dt_node_to_map(struct pinctrl_dev *pctldev,
>> +                             struct device_node *np,
>> +                             struct pinctrl_map **map,
>> +                             unsigned int *num_maps)
>> +{
>> +       struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
>> +       const struct aml_pctl_group *grp;
>> +       struct device *dev = info->dev;
>> +       struct pinctrl_map *new_map;
>> +       struct device_node *parent;
>> +       int map_num, i;
>> +
>> +       grp = aml_pctl_find_group_by_name(info, np->name);
>> +       if (!grp) {
>> +               dev_err(dev, "unable to find group for node %pOFn\n", np);
>> +               return -EINVAL;
>> +       }
>> +
>> +       if (grp->num_configs)
>> +               map_num = grp->npins + 1;
>> +       else
>> +               map_num = 1;
>> +       new_map = devm_kcalloc(dev, map_num, sizeof(*new_map), GFP_KERNEL);
>> +       if (!new_map)
>> +               return -ENOMEM;
>> +
>> +       parent = of_get_parent(np);
>> +       if (!parent) {
>> +               devm_kfree(dev, new_map);
>> +               return -EINVAL;
>> +       }
>> +
>> +       *map = new_map;
>> +       *num_maps = map_num;
>> +       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);
>> +
>> +       if (grp->num_configs) {
>> +               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->configs;
>> +                       new_map[i].data.configs.num_configs = grp->num_configs;
>> +               }
>> +       }
>> +
>> +       dev_info(dev, "maps: function %s group %s num %d\n",
>> +                (*map)->data.mux.function, grp->name, map_num);
>> +
>> +       return 0;
>> +}
>> +
>> +static void aml_dt_free_map(struct pinctrl_dev *pctldev,
>> +                           struct pinctrl_map *map, unsigned int num_maps)
>> +{
>> +}
>> +
>> +static void aml_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
>> +                            unsigned int offset)
>> +{
>> +       seq_printf(s, " %s", dev_name(pcdev->dev));
>> +}
>> +
>> +static const struct pinctrl_ops aml_pctrl_ops = {
>> +       .get_groups_count       = aml_get_groups_count,
>> +       .get_group_name         = aml_get_group_name,
>> +       .get_group_pins         = aml_get_group_pins,
>> +       .dt_node_to_map         = aml_dt_node_to_map,
>> +       .dt_free_map            = aml_dt_free_map,
>> +       .pin_dbg_show           = aml_pin_dbg_show,
>> +};
>> +
>> +static int aml_pctl_dt_calculate_pin(struct aml_pinctrl *info,
>> +                                    unsigned int bank_idx, unsigned int offset)
>> +{
>> +       struct aml_gpio_bank *bank;
>> +       int retval = -EINVAL;
>> +       int i;
>> +
>> +       for (i = 0; i < info->nbanks; i++) {
>> +               bank = &info->banks[i];
>> +               if (bank->bank_idx == bank_idx) {
>> +                       if (offset < bank->gpio_chip.ngpio)
>> +                               retval = bank->pin_base + offset;
>> +                       break;
>> +               }
>> +       }
>> +       if (retval == -EINVAL)
>> +               dev_err(info->dev, "pin [bank:%d, offset:%d] is not present\n", bank_idx, offset);
>> +
>> +       return retval;
>> +}
>> +
>> +static int aml_pctl_dt_parse_groups(struct device_node *np,
>> +                                   struct aml_pctl_group *grp,
>> +                                   struct aml_pinctrl *info, int idx)
>> +{
>> +       struct device *dev = info->dev;
>> +       struct aml_pinconf *conf;
>> +       struct property *of_pins;
>> +       unsigned int bank_idx;
>> +       unsigned int offset, npins;
>> +       int i = 0;
>> +       int ret;
>> +
>> +       of_pins = of_find_property(np, "pinmux", NULL);
>> +       if (!of_pins) {
>> +               dev_info(dev, "Missing pinmux property\n");
>> +               return -ENOENT;
>> +       }
>> +
>> +       npins = of_pins->length / sizeof(u32);
>> +       grp->npins = npins;
>> +       grp->name = np->name;
>> +       grp->pins = devm_kcalloc(dev, npins, sizeof(*grp->pins), GFP_KERNEL);
>> +       grp->pin_conf = devm_kcalloc(dev, npins, sizeof(*grp->pin_conf), GFP_KERNEL);
>> +
>> +       if (!grp->pins || !grp->pin_conf)
>> +               return -ENOMEM;
>> +
>> +       ret = pinconf_generic_parse_dt_config(np, info->pctl, &grp->configs,
>> +                                             &grp->num_configs);
> 
> But can't you just move this code around? grp->num_configs give the
> number of configs, so why do you have to go and look up pinmux
> above, can't you just use grp->num_configs instead of of_pins
> and npins above?
> 
>> +static int aml_pctl_parse_functions(struct device_node *np,
>> +                                   struct aml_pinctrl *info, u32 index,
>> +                                   int *grp_index)
>> +{
>> +       struct device *dev = info->dev;
>> +       struct aml_pmx_func *func;
>> +       struct aml_pctl_group *grp;
>> +       int ret, i;
>> +
>> +       func = &info->functions[index];
>> +       func->name = np->name;
>> +       func->ngroups = of_get_child_count(np);
>> +       if (func->ngroups == 0)
>> +               return dev_err_probe(dev, -EINVAL, "No groups defined\n");
>> +
>> +       func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL);
>> +       if (!func->groups)
>> +               return -ENOMEM;
>> +
>> +       i = 0;
>> +       for_each_child_of_node_scoped(np, child) {
>> +               func->groups[i] = child->name;
>> +               grp = &info->groups[*grp_index];
>> +               *grp_index += 1;
>> +               ret = aml_pctl_dt_parse_groups(child, grp, info, i++);
>> +               if (ret)
>> +                       return ret;
>> +       }
>> +       dev_info(dev, "Function[%d\t name:%s,\tgroups:%d]\n", index, func->name, func->ngroups);
>> +
>> +       return 0;
>> +}
>> +
>> +static u32 aml_bank_pins(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "npins", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
>> +
>> +static u32 aml_bank_reg_gpio_offset(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "reg-gpio-offset", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
>> +
>> +static u32 aml_bank_reg_mux_offset(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "reg-mux-offset", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
>> +
>> +static u32 aml_bank_bit_mux_offset(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "bit-mux-offset", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
>> +
>> +static u32 aml_bank_index(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "bank-index", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
> 
> Do we really need helpers for all of this? Can't you just
> open code it, at least if it's just used in one place?
> 
>> +static unsigned int aml_count_pins(struct device_node *np)
>> +{
>> +       struct device_node *child;
>> +       unsigned int pins = 0;
>> +
>> +       for_each_child_of_node(np, child) {
>> +               if (of_property_read_bool(child, "gpio-controller"))
>> +                       pins += aml_bank_pins(child);
>> +       }
>> +
>> +       return pins;
>> +}
>> +
>> +static void aml_pctl_dt_child_count(struct aml_pinctrl *info,
>> +                                   struct device_node *np)
>> +{
>> +       struct device_node *child;
>> +
>> +       for_each_child_of_node(np, child) {
>> +               if (of_property_read_bool(child, "gpio-controller")) {
>> +                       info->nbanks++;
>> +               } else {
>> +                       info->nfunctions++;
>> +                       info->ngroups += of_get_child_count(child);
>> +               }
>> +       }
>> +}
> 
> This looks like a weird dependency between gpio chips and
> pins that I don't quite understand. Some comments and
> references to the bindings will be needed so it is clear
> what is going on.
> 
>> +static struct regmap *aml_map_resource(struct aml_pinctrl *info,
>> +                                      struct device_node *node, char *name)
>> +{
>> +       struct resource res;
>> +       void __iomem *base;
>> +       int i;
>> +
>> +       i = of_property_match_string(node, "reg-names", name);
>> +       if (of_address_to_resource(node, i, &res))
>> +               return NULL;
>> +
>> +       base = devm_ioremap_resource(info->dev, &res);
>> +       if (IS_ERR(base))
>> +               return ERR_CAST(base);
> 
> This looks like reimplementation of
> devm_platform_ioremap_resource_byname(), can't you just
> pass your platform device here?
> 
>> +static int aml_pctl_probe_dt(struct platform_device *pdev,
>> +                            struct pinctrl_desc *pctl_desc,
>> +                            struct aml_pinctrl *info)
> 
> Because there is clearly a platform device involved.
> 
> I guess I will have more comments as the series progress, but this
> is a good starting point!
> 
> Yours,
> Linus Walleij



From suzuki.poulose at arm.com  Tue Dec 17 06:54:41 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 17 Dec 2024 14:54:41 +0000
Subject: [PATCH v2 2/3] coresight-tpdm: Add support to select lane
In-Reply-To: <20241105123940.39602-3-quic_jinlmao@quicinc.com>
References: <20241105123940.39602-1-quic_jinlmao@quicinc.com>
 <20241105123940.39602-3-quic_jinlmao@quicinc.com>
Message-ID: <fb0b26ca-8c0a-49ee-ad72-095c60070067@arm.com>

On 05/11/2024 12:39, Mao Jinlong wrote:
> From: Tao Zhang <quic_taozha at quicinc.com>
> 
> TPDM MCMB subunits supports up to 8 lanes CMB. For MCMB
> configurations, the field "XTRIG_LNSEL" in CMB_CR register selects
> which lane participates in the output pattern mach cross trigger
> mechanism governed by the M_CMB_DXPR and M_CMB_XPMR regisers.
> 
> 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  | 51 +++++++++++++++++++
>   drivers/hwtracing/coresight/coresight-tpdm.h  |  3 ++
>   3 files changed, 62 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> index bf710ea6e0ef..e833edfec79e 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -257,3 +257,11 @@ 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 CMB subunit
>   		TPDM.
> +
> +What:		/sys/bus/coresight/devices/<tpdm-name>/mcmb_trig_lane
> +Date:		Nov 2024
> +KernelVersion	6.13

6.14



Suzuki




From kuba at kernel.org  Tue Dec 17 06:49:07 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 17 Dec 2024 06:49:07 -0800
Subject: [PATCH net-next 2/2] net: stmmac: dwmac-socfpga: Set interface
 modes from Lynx PCS as supported
In-Reply-To: <20241217135932.60711288@fedora.home>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
	<20241213090526.71516-3-maxime.chevallier@bootlin.com>
	<Z1wnFXlgEU84VX8F@shell.armlinux.org.uk>
	<20241213182904.55eb2504@fedora.home>
	<Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
	<20241216094224.199e8df7@fedora.home>
	<20241216173333.55e35f34@kernel.org>
	<20241217135932.60711288@fedora.home>
Message-ID: <20241217064907.0e509769@kernel.org>

Let me triple check ;)

On Tue, 17 Dec 2024 13:59:32 +0100 Maxime Chevallier wrote:
> - The priv->phylink_config.supported_interfaces is incomplete on
> dwmac-socfpga. Russell's patch 5 intersects these modes with that the
                                   ^^^^^^^^^^
> PCS supports :
> 
> +		phy_interface_or(priv->phylink_config.supported_interfaces,
                              ^^
> +				 priv->phylink_config.supported_interfaces,
> +				 pcs->supported_interfaces);
> 
> So without patch 2 in the series, we'll be missing
> PHY_INTERFACE_MODE_1000BASEX in the end result :)

"Or" is a sum/union, not intersection.

You set the bits in priv->phylink_config.supported_interfaces.
Russell does:

	priv->phylink_config.supported_interfaces |=
		pcs->supported_interfaces;

If I'm missing the point please repost once Russell's patches 
are merged :)


From linus.walleij at linaro.org  Tue Dec 17 06:49:08 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Dec 2024 15:49:08 +0100
Subject: [PATCH RFC 2/3] pinctrl: Add driver support for Amlogic SoCs
In-Reply-To: <20241211-amlogic-pinctrl-v1-2-410727335119@amlogic.com>
References: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com> <20241211-amlogic-pinctrl-v1-2-410727335119@amlogic.com>
Message-ID: <CACRpkdbuj-_sPpdfcyg3_QNtzt9r7n-0HBGBKgy-rKUMhvGo4w@mail.gmail.com>

Hi Xianwei,

thanks for your patch!

On Wed, Dec 11, 2024 at 7:48?AM Xianwei Zhao via B4 Relay
<devnull+xianwei.zhao.amlogic.com at kernel.org> wrote:

> From: Xianwei Zhao <xianwei.zhao at amlogic.com>
>
> Add a new pinctrl driver for Amlogic SoCs. All future Amlogic
> SoCs pinctrl drives use this, such A4, A5, S6, S7 etc. To support
> new Amlogic SoCs, only need to add the corresponding dts file.
>
> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>

First: are we sure these new SoCs have nothing in common
with sunxi? Because then the sunxi code should be reused.

In any way I recommend:

- Renaming drivers/pinctrl/sunxi to drivers/pinctrl/amlogic
  so we keep this sorted by actual vendor, sunxi is apparently
  yours (AMlogic:s) isn't it?

- Also fix MAINTAINERS accordingly.

- Add new driver under drivers/pinctrl/amlogic

- Do not change the Kconfig symbols for sunxi and
  we should be fine.

> +static int aml_dt_node_to_map(struct pinctrl_dev *pctldev,
> +                             struct device_node *np,
> +                             struct pinctrl_map **map,
> +                             unsigned int *num_maps)
> +{
> +       struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
> +       const struct aml_pctl_group *grp;
> +       struct device *dev = info->dev;
> +       struct pinctrl_map *new_map;
> +       struct device_node *parent;
> +       int map_num, i;
> +
> +       grp = aml_pctl_find_group_by_name(info, np->name);
> +       if (!grp) {
> +               dev_err(dev, "unable to find group for node %pOFn\n", np);
> +               return -EINVAL;
> +       }
> +
> +       if (grp->num_configs)
> +               map_num = grp->npins + 1;
> +       else
> +               map_num = 1;
> +       new_map = devm_kcalloc(dev, map_num, sizeof(*new_map), GFP_KERNEL);
> +       if (!new_map)
> +               return -ENOMEM;
> +
> +       parent = of_get_parent(np);
> +       if (!parent) {
> +               devm_kfree(dev, new_map);
> +               return -EINVAL;
> +       }
> +
> +       *map = new_map;
> +       *num_maps = map_num;
> +       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);
> +
> +       if (grp->num_configs) {
> +               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->configs;
> +                       new_map[i].data.configs.num_configs = grp->num_configs;
> +               }
> +       }
> +
> +       dev_info(dev, "maps: function %s group %s num %d\n",
> +                (*map)->data.mux.function, grp->name, map_num);
> +
> +       return 0;
> +}
> +
> +static void aml_dt_free_map(struct pinctrl_dev *pctldev,
> +                           struct pinctrl_map *map, unsigned int num_maps)
> +{
> +}
> +
> +static void aml_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
> +                            unsigned int offset)
> +{
> +       seq_printf(s, " %s", dev_name(pcdev->dev));
> +}
> +
> +static const struct pinctrl_ops aml_pctrl_ops = {
> +       .get_groups_count       = aml_get_groups_count,
> +       .get_group_name         = aml_get_group_name,
> +       .get_group_pins         = aml_get_group_pins,
> +       .dt_node_to_map         = aml_dt_node_to_map,
> +       .dt_free_map            = aml_dt_free_map,
> +       .pin_dbg_show           = aml_pin_dbg_show,
> +};
> +
> +static int aml_pctl_dt_calculate_pin(struct aml_pinctrl *info,
> +                                    unsigned int bank_idx, unsigned int offset)
> +{
> +       struct aml_gpio_bank *bank;
> +       int retval = -EINVAL;
> +       int i;
> +
> +       for (i = 0; i < info->nbanks; i++) {
> +               bank = &info->banks[i];
> +               if (bank->bank_idx == bank_idx) {
> +                       if (offset < bank->gpio_chip.ngpio)
> +                               retval = bank->pin_base + offset;
> +                       break;
> +               }
> +       }
> +       if (retval == -EINVAL)
> +               dev_err(info->dev, "pin [bank:%d, offset:%d] is not present\n", bank_idx, offset);
> +
> +       return retval;
> +}
> +
> +static int aml_pctl_dt_parse_groups(struct device_node *np,
> +                                   struct aml_pctl_group *grp,
> +                                   struct aml_pinctrl *info, int idx)
> +{
> +       struct device *dev = info->dev;
> +       struct aml_pinconf *conf;
> +       struct property *of_pins;
> +       unsigned int bank_idx;
> +       unsigned int offset, npins;
> +       int i = 0;
> +       int ret;
> +
> +       of_pins = of_find_property(np, "pinmux", NULL);
> +       if (!of_pins) {
> +               dev_info(dev, "Missing pinmux property\n");
> +               return -ENOENT;
> +       }
> +
> +       npins = of_pins->length / sizeof(u32);
> +       grp->npins = npins;
> +       grp->name = np->name;
> +       grp->pins = devm_kcalloc(dev, npins, sizeof(*grp->pins), GFP_KERNEL);
> +       grp->pin_conf = devm_kcalloc(dev, npins, sizeof(*grp->pin_conf), GFP_KERNEL);
> +
> +       if (!grp->pins || !grp->pin_conf)
> +               return -ENOMEM;
> +
> +       ret = pinconf_generic_parse_dt_config(np, info->pctl, &grp->configs,
> +                                             &grp->num_configs);

But can't you just move this code around? grp->num_configs give the
number of configs, so why do you have to go and look up pinmux
above, can't you just use grp->num_configs instead of of_pins
and npins above?

> +static int aml_pctl_parse_functions(struct device_node *np,
> +                                   struct aml_pinctrl *info, u32 index,
> +                                   int *grp_index)
> +{
> +       struct device *dev = info->dev;
> +       struct aml_pmx_func *func;
> +       struct aml_pctl_group *grp;
> +       int ret, i;
> +
> +       func = &info->functions[index];
> +       func->name = np->name;
> +       func->ngroups = of_get_child_count(np);
> +       if (func->ngroups == 0)
> +               return dev_err_probe(dev, -EINVAL, "No groups defined\n");
> +
> +       func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL);
> +       if (!func->groups)
> +               return -ENOMEM;
> +
> +       i = 0;
> +       for_each_child_of_node_scoped(np, child) {
> +               func->groups[i] = child->name;
> +               grp = &info->groups[*grp_index];
> +               *grp_index += 1;
> +               ret = aml_pctl_dt_parse_groups(child, grp, info, i++);
> +               if (ret)
> +                       return ret;
> +       }
> +       dev_info(dev, "Function[%d\t name:%s,\tgroups:%d]\n", index, func->name, func->ngroups);
> +
> +       return 0;
> +}
> +
> +static u32 aml_bank_pins(struct device_node *np)
> +{
> +       u32 value;
> +
> +       if (of_property_read_u32(np, "npins", &value) < 0)
> +               return 0;
> +       else
> +               return value;
> +}
> +
> +static u32 aml_bank_reg_gpio_offset(struct device_node *np)
> +{
> +       u32 value;
> +
> +       if (of_property_read_u32(np, "reg-gpio-offset", &value) < 0)
> +               return 0;
> +       else
> +               return value;
> +}
> +
> +static u32 aml_bank_reg_mux_offset(struct device_node *np)
> +{
> +       u32 value;
> +
> +       if (of_property_read_u32(np, "reg-mux-offset", &value) < 0)
> +               return 0;
> +       else
> +               return value;
> +}
> +
> +static u32 aml_bank_bit_mux_offset(struct device_node *np)
> +{
> +       u32 value;
> +
> +       if (of_property_read_u32(np, "bit-mux-offset", &value) < 0)
> +               return 0;
> +       else
> +               return value;
> +}
> +
> +static u32 aml_bank_index(struct device_node *np)
> +{
> +       u32 value;
> +
> +       if (of_property_read_u32(np, "bank-index", &value) < 0)
> +               return 0;
> +       else
> +               return value;
> +}

Do we really need helpers for all of this? Can't you just
open code it, at least if it's just used in one place?

> +static unsigned int aml_count_pins(struct device_node *np)
> +{
> +       struct device_node *child;
> +       unsigned int pins = 0;
> +
> +       for_each_child_of_node(np, child) {
> +               if (of_property_read_bool(child, "gpio-controller"))
> +                       pins += aml_bank_pins(child);
> +       }
> +
> +       return pins;
> +}
> +
> +static void aml_pctl_dt_child_count(struct aml_pinctrl *info,
> +                                   struct device_node *np)
> +{
> +       struct device_node *child;
> +
> +       for_each_child_of_node(np, child) {
> +               if (of_property_read_bool(child, "gpio-controller")) {
> +                       info->nbanks++;
> +               } else {
> +                       info->nfunctions++;
> +                       info->ngroups += of_get_child_count(child);
> +               }
> +       }
> +}

This looks like a weird dependency between gpio chips and
pins that I don't quite understand. Some comments and
references to the bindings will be needed so it is clear
what is going on.

> +static struct regmap *aml_map_resource(struct aml_pinctrl *info,
> +                                      struct device_node *node, char *name)
> +{
> +       struct resource res;
> +       void __iomem *base;
> +       int i;
> +
> +       i = of_property_match_string(node, "reg-names", name);
> +       if (of_address_to_resource(node, i, &res))
> +               return NULL;
> +
> +       base = devm_ioremap_resource(info->dev, &res);
> +       if (IS_ERR(base))
> +               return ERR_CAST(base);

This looks like reimplementation of
devm_platform_ioremap_resource_byname(), can't you just
pass your platform device here?

> +static int aml_pctl_probe_dt(struct platform_device *pdev,
> +                            struct pinctrl_desc *pctl_desc,
> +                            struct aml_pinctrl *info)

Because there is clearly a platform device involved.

I guess I will have more comments as the series progress, but this
is a good starting point!

Yours,
Linus Walleij


From angelogioacchino.delregno at collabora.com  Tue Dec 17 06:49:18 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 15:49:18 +0100
Subject: [PATCH v2 15/15] drm/mediatek: Introduce HDMI/DDC v2 for
 MT8195/MT8188
In-Reply-To: <6ed3b9ee742dcf814f35e15d88db538480ba2d48.camel@mediatek.com>
References: <20241205114518.53527-1-angelogioacchino.delregno@collabora.com>
 <20241205114518.53527-16-angelogioacchino.delregno@collabora.com>
 <6ed3b9ee742dcf814f35e15d88db538480ba2d48.camel@mediatek.com>
Message-ID: <482ccf9c-fad5-470c-964f-a2c422f79555@collabora.com>

Il 17/12/24 10:21, CK Hu (???) ha scritto:
> Hi, Angelo:
> 
> On Thu, 2024-12-05 at 12:45 +0100, AngeloGioacchino Del Regno wrote:
>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>
>>
>> Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
>> found in MediaTek's MT8195, MT8188 SoC and their variants, and
>> including support for display modes up to 4k60 and for HDMI
>> Audio, as per the HDMI 2.0 spec.
>>
>> HDCP and CEC functionalities are also supported by this hardware,
>> but are not included in this commit and that also poses a slight
>> difference between the V2 and V1 controllers in how they handle
>> Hotplug Detection (HPD).
>>
>> While the v1 controller was using the CEC controller to check
>> HDMI cable connection and disconnection, in this driver the v2
>> one does not.
>>
>> This is due to the fact that on parts with v2 designs, like the
>> MT8195 SoC, there is one CEC controller shared between the HDMI
>> Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
>> adding support to use the CEC HW to wake up the HDMI controllers
>> it is necessary to have support for one TX, one RX *and* for both
>> at the same time.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
> 
> [snip]
> 
>> +static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
>> +                                         struct drm_bridge_state *old_state)
>> +{
>> +       struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
>> +       struct drm_atomic_state *state = old_state->base.state;
>> +       struct drm_connector_state *conn_state;
>> +       union phy_configure_opts opts = {
>> +               .dp = { .link_rate = hdmi->mode.clock * KILO }
>> +       };
>> +
>> +       /* Retrieve the connector through the atomic state */
>> +       hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
>> +
>> +       conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
>> +       if (WARN_ON(!conn_state))
>> +               return;
>> +
>> +       /*
>> +        * Preconfigure the HDMI controller and the HDMI PHY at pre_enable
>> +        * stage to make sure that this IP is ready and clocked before the
>> +        * mtk_dpi gets powered on and before it enables the output.
> 
> In patch [6/15], you does not power on DPI power in DPI driver.
> Could you point out the code about 'mtk_dpi gets powered on'?
> 

DPI gets powered on in mtk_dpi_bridge_enable() -> mtk_dpi_power_on(dpi)

Cheers,
Angelo

> Regards,
> CK
> 
>> +        */
>> +       hdmi->dvi_mode = !hdmi->curr_conn->display_info.is_hdmi;
>> +       mtk_hdmi_v2_output_set_display_mode(hdmi, &hdmi->mode);
>> +
>> +       /* Reconfigure phy clock link with appropriate rate */
>> +       phy_configure(hdmi->phy, &opts);
>> +
>> +       /* Power on the PHY here to make sure that DPI_HDMI is clocked */
>> +       phy_power_on(hdmi->phy);
>> +
>> +       hdmi->powered = true;
>> +}
>> +
> 
> 




From suzuki.poulose at arm.com  Tue Dec 17 06:52:19 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 17 Dec 2024 14:52:19 +0000
Subject: [PATCH v2 1/3] coresight-tpdm: Add MCMB dataset support
In-Reply-To: <20241105123940.39602-2-quic_jinlmao@quicinc.com>
References: <20241105123940.39602-1-quic_jinlmao@quicinc.com>
 <20241105123940.39602-2-quic_jinlmao@quicinc.com>
Message-ID: <065b4ad2-db39-42ed-91d1-d818f82ece79@arm.com>

On 05/11/2024 12:39, Mao Jinlong wrote:
> MCMB (Multi-lane CMB) is a special form of CMB dataset type. MCMB
> subunit TPDM has the same number and usage of registers as CMB
> subunit TPDM. MCMB subunit can be enabled for data collection by
> writing 1 to the first bit of CMB_CR register. The difference is
> that MCMB subunit TPDM needs to select the lane and enable it in
> using it.
> 
> 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 |  7 ++--
>   drivers/hwtracing/coresight/coresight-tpdm.c | 44 +++++++++++++++++---
>   drivers/hwtracing/coresight/coresight-tpdm.h | 27 ++++++------
>   3 files changed, 57 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
> index bfca103f9f84..4b61b9840740 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.c
> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
> @@ -1,6 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0
>   /*
> - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>    */
>   
>   #include <linux/amba/bus.h>
> @@ -68,11 +68,12 @@ static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
>   	int rc = -EINVAL;
>   	struct tpdm_drvdata *tpdm_data = dev_get_drvdata(csdev->dev.parent);
>   
> -	if (tpdm_has_dsb_dataset(tpdm_data)) {
> +	if (tpdm_data->dsb) {
>   		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
>   				"qcom,dsb-element-bits", &drvdata->dsb_esize);
>   	}
> -	if (tpdm_has_cmb_dataset(tpdm_data)) {
> +
> +	if (tpdm_data->cmb) {
>   		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
>   				"qcom,cmb-element-bits", &drvdata->cmb_esize);
>   	}
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
> index b7d99e91ab84..0529858586c1 100644
> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
> @@ -1,6 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0
>   /*
> - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>    */
>   
>   #include <linux/amba/bus.h>
> @@ -21,6 +21,21 @@
>   
>   DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
>   
> +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);
> +}
> +
> +static bool tpdm_has_mcmb_dataset(struct tpdm_drvdata *drvdata)
> +{
> +	return (drvdata->datasets & TPDM_PIDR0_DS_MCMB);
> +}
> +
>   /* Read dataset array member with the index number */
>   static ssize_t tpdm_simple_dataset_show(struct device *dev,
>   					struct device_attribute *attr,
> @@ -198,7 +213,7 @@ static umode_t tpdm_cmb_is_visible(struct kobject *kobj,
>   	struct device *dev = kobj_to_dev(kobj);
>   	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>   
> -	if (drvdata && tpdm_has_cmb_dataset(drvdata))
> +	if (drvdata && drvdata->cmb)
>   		return attr->mode;
>   
>   	return 0;
> @@ -246,8 +261,10 @@ static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
>   		drvdata->dsb->trig_type = false;
>   	}
>   
> -	if (drvdata->cmb)
> +	if (drvdata->cmb) {
>   		memset(drvdata->cmb, 0, sizeof(struct cmb_dataset));
> +		drvdata->cmb->trig_ts = true;

This looks like an unrelated change from the MCMB dataset. Is there an 
explanation ? Is this a mistake ? If it is intended, please make it a
separate patch.

> +	}
>   }
>   
>   static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val)
> @@ -388,7 +405,7 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>   {
>   	u32 val, i;
>   
> -	if (!tpdm_has_cmb_dataset(drvdata))
> +	if (!drvdata->cmb)
>   		return;
>   
>   	/* Configure pattern registers */
> @@ -415,6 +432,19 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>   		val |= TPDM_CMB_CR_MODE;
>   	else
>   		val &= ~TPDM_CMB_CR_MODE;
> +
> +	if (tpdm_has_mcmb_dataset(drvdata)) {
> +		val &= ~TPDM_CMB_CR_XTRIG_LNSEL;
> +		/* Set the lane participates in tghe output pattern */

minor nit: typo "tghe" => "the"

> +		val |= FIELD_PREP(TPDM_CMB_CR_XTRIG_LNSEL,
> +			drvdata->cmb->mcmb.trig_lane);
> +
> +		/* Set the enablement of the lane */
> +		val &= ~TPDM_CMB_CR_E_LN;
> +		val |= FIELD_PREP(TPDM_CMB_CR_E_LN,
> +			drvdata->cmb->mcmb.lane_select);
> +	}
> +
>   	/* Set the enable bit of CMB control register to 1 */
>   	val |= TPDM_CMB_CR_ENA;
>   	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
> @@ -480,7 +510,7 @@ static void tpdm_disable_cmb(struct tpdm_drvdata *drvdata)
>   {
>   	u32 val;
>   
> -	if (!tpdm_has_cmb_dataset(drvdata))
> +	if (!drvdata->cmb)
>   		return;
>   
>   	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
> @@ -542,12 +572,14 @@ static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata)
>   		if (!drvdata->dsb)
>   			return -ENOMEM;
>   	}
> -	if (tpdm_has_cmb_dataset(drvdata) && (!drvdata->cmb)) {
> +	if ((tpdm_has_cmb_dataset(drvdata) || tpdm_has_mcmb_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;
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> index e08d212642e3..fd9153b92335 100644
> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> @@ -1,6 +1,6 @@
>   /* SPDX-License-Identifier: GPL-2.0 */
>   /*
> - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>    */
>   
>   #ifndef _CORESIGHT_CORESIGHT_TPDM_H
> @@ -9,7 +9,7 @@
>   /* The max number of the datasets that TPDM supports */
>   #define TPDM_DATASETS       7
>   
> -/* CMB Subunit Registers */
> +/* CMB/MCMB Subunit Registers */
>   #define TPDM_CMB_CR		(0xA00)
>   /* CMB subunit timestamp insertion enable register */
>   #define TPDM_CMB_TIER		(0xA04)
> @@ -34,6 +34,10 @@
>   #define TPDM_CMB_TIER_XTRIG_TSENAB	BIT(1)
>   /* For timestamp fo all trace */
>   #define TPDM_CMB_TIER_TS_ALL		BIT(2)
> +/* MCMB trigger lane select */
> +#define TPDM_CMB_CR_XTRIG_LNSEL		GENMASK(20, 18)
> +/* MCMB lane enablement */
> +#define TPDM_CMB_CR_E_LN		GENMASK(17, 10)

Please could you move the CMB_CR related defintions together ?
i.e., closer to TPDM_CMB_CR_MODE

Suzuki

>   
>   /* Patten register number */
>   #define TPDM_CMB_MAX_PATT		2
> @@ -112,11 +116,13 @@
>    * 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
> + * PERIPHIDR0[6] : Fix to 1 if MCMB 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_PIDR0_DS_MCMB	BIT(6)
>   
>   #define TPDM_DSB_MAX_LINES	256
>   /* MAX number of EDCR registers */
> @@ -256,6 +262,9 @@ struct dsb_dataset {
>    * @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 mcmb_dataset
> + * @mcmb_trig_lane:       Save data for trigger lane
> + * @mcmb_lane_select:     Save data for lane enablement
>    */
>   struct cmb_dataset {
>   	u32			trace_mode;
> @@ -267,6 +276,10 @@ struct cmb_dataset {
>   	bool			patt_ts;
>   	bool			trig_ts;
>   	bool			ts_all;
> +	struct {
> +		u8		trig_lane;
> +		u8		lane_select;
> +	} mcmb;
>   };
>   
>   /**
> @@ -324,14 +337,4 @@ struct tpdm_dataset_attribute {
>   	enum dataset_mem mem;
>   	u32 idx;
>   };
> -
> -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 */



From suzuki.poulose at arm.com  Tue Dec 17 06:55:10 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 17 Dec 2024 14:55:10 +0000
Subject: [PATCH v2 3/3] coresight-tpdm: Add support to enable the lane for
 MCMB TPDM
In-Reply-To: <20241105123940.39602-4-quic_jinlmao@quicinc.com>
References: <20241105123940.39602-1-quic_jinlmao@quicinc.com>
 <20241105123940.39602-4-quic_jinlmao@quicinc.com>
Message-ID: <8ca3d31b-74a0-497a-9b53-dfe9becd0f7a@arm.com>

On 05/11/2024 12:39, Mao Jinlong wrote:
> From: Tao Zhang <quic_taozha at quicinc.com>
> 
> Add the sysfs file to set/get the enablement of the lane. For MCMB
> configurations, the field "E_LN" in CMB_CR register is the
> individual lane enables. MCMB lane N is enabled for trace
> generation when M_CMB_CR.E=1 and M_CMB_CR.E_LN[N]=1. For lanes
> that are not implemented on a given MCMB configuration, the
> corresponding bits of this field read as 0 and ignore writes.
> 
> 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  |  7 +++++
>   drivers/hwtracing/coresight/coresight-tpdm.c  | 29 +++++++++++++++++++
>   drivers/hwtracing/coresight/coresight-tpdm.h  |  3 ++
>   3 files changed, 39 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> index e833edfec79e..fcc2a8f1f17f 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -265,3 +265,10 @@ Contact:	Tao Zhang (QUIC) <quic_taozha at quicinc.com>
>   Description:
>   		(RW) Set/Get which lane participates in the output pattern
>   		match cross trigger mechanism for the MCMB subunit TPDM.
> +
> +What:		/sys/bus/coresight/devices/<tpdm-name>/mcmb_lanes_select
> +Date:		Nov 2024
> +KernelVersion	6.13

6.14

Suzuki


> +Contact:	Tao Zhang (QUIC) <quic_taozha at quicinc.com>
> +Description:
> +		(RW) Set/Get the enablement of the individual lane.
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
> index 2e4dc86b03ea..bb0d6505ec9f 100644
> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
> @@ -1063,6 +1063,34 @@ static ssize_t mcmb_trig_lane_store(struct device *dev,
>   }
>   static DEVICE_ATTR_RW(mcmb_trig_lane);
>   
> +static ssize_t mcmb_lanes_select_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->mcmb.lane_select);
> +}
> +
> +static ssize_t mcmb_lanes_select_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 & ~TPDM_MCMB_E_LN_MASK))
> +		return -EINVAL;
> +
> +	guard(spinlock)(&drvdata->spinlock);
> +	drvdata->cmb->mcmb.lane_select = val & TPDM_MCMB_E_LN_MASK;
> +
> +	return size;
> +}
> +static DEVICE_ATTR_RW(mcmb_lanes_select);
> +
>   static struct attribute *tpdm_dsb_edge_attrs[] = {
>   	&dev_attr_ctrl_idx.attr,
>   	&dev_attr_ctrl_val.attr,
> @@ -1227,6 +1255,7 @@ static struct attribute *tpdm_cmb_msr_attrs[] = {
>   
>   static struct attribute *tpdm_mcmb_attrs[] = {
>   	&dev_attr_mcmb_trig_lane.attr,
> +	&dev_attr_mcmb_lanes_select.attr,
>   	NULL,
>   };
>   
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> index aa9746b2e77f..a80f3d680995 100644
> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> @@ -48,6 +48,9 @@
>   /* MAX lanes in the output pattern for MCMB configurations*/
>   #define TPDM_MCMB_MAX_LANES 8
>   
> +/* Filter bit 0~7 from the value for CR_E_LN */
> +#define TPDM_MCMB_E_LN_MASK		GENMASK(7, 0)
> +
>   /* DSB Subunit Registers */
>   #define TPDM_DSB_CR		(0x780)
>   #define TPDM_DSB_TIER		(0x784)



From mripard at kernel.org  Tue Dec 17 07:00:38 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 16:00:38 +0100
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes
 handling on RK3588 HDMI0
In-Reply-To: <1756448.izSxrag8PF@diego>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
 <1820767.5KxKD5qtyk@diego>
 <a4ex3s23r4k6wehyoaw3aylpcexfrclrxxykjpabhdfne2jgmu@ii6riiiga2zj>
 <1756448.izSxrag8PF@diego>
Message-ID: <20241217-ubiquitous-refreshing-finch-aceade@houat>

On Wed, Dec 11, 2024 at 07:01:15PM +0100, Heiko St?bner wrote:
> Am Mittwoch, 11. Dezember 2024, 18:47:44 CET schrieb Maxime Ripard:
> > On Wed, Dec 11, 2024 at 06:23:03PM +0100, Heiko St?bner wrote:
> > > Am Mittwoch, 11. Dezember 2024, 18:07:57 CET schrieb Maxime Ripard:
> > > > On Wed, Dec 11, 2024 at 12:15:07PM +0200, Cristian Ciocaltea wrote:
> > > > > The RK3588 specific implementation is currently quite limited in terms
> > > > > of handling the full range of display modes supported by the connected
> > > > > screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
> > > > > few of them.
> > > > > 
> > > > > Additionally, it doesn't cope well with non-integer refresh rates like
> > > > > 59.94, 29.97, 23.98, etc.
> > > > > 
> > > > > Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
> > > > > all display modes up to 4K at 60Hz.
> > > > > 
> > > > > Tested-by: FUKAUMI Naoki <naoki at radxa.com>
> > > > > Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> > > > > ---
> > > > >  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
> > > > >  1 file changed, 34 insertions(+)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > > > > index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
> > > > > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > > > > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> > > > > @@ -158,6 +158,7 @@ struct vop2_video_port {
> > > > >  	struct drm_crtc crtc;
> > > > >  	struct vop2 *vop2;
> > > > >  	struct clk *dclk;
> > > > > +	struct clk *dclk_src;
> > > > >  	unsigned int id;
> > > > >  	const struct vop2_video_port_data *data;
> > > > >  
> > > > > @@ -212,6 +213,7 @@ struct vop2 {
> > > > >  	struct clk *hclk;
> > > > >  	struct clk *aclk;
> > > > >  	struct clk *pclk;
> > > > > +	struct clk *pll_hdmiphy0;
> > > > >  
> > > > >  	/* optional internal rgb encoder */
> > > > >  	struct rockchip_rgb *rgb;
> > > > > @@ -220,6 +222,8 @@ struct vop2 {
> > > > >  	struct vop2_win win[];
> > > > >  };
> > > > >  
> > > > > +#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
> > > > > +
> > > > >  #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
> > > > >  					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
> > > > >  
> > > > > @@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
> > > > >  
> > > > >  	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
> > > > >  
> > > > > +	if (vp->dclk_src)
> > > > > +		clk_set_parent(vp->dclk, vp->dclk_src);
> > > > > +
> > > > >  	clk_disable_unprepare(vp->dclk);
> > > > >  
> > > > >  	vop2->enable_count--;
> > > > > @@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
> > > > >  
> > > > >  	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
> > > > >  
> > > > > +	/*
> > > > > +	 * Switch to HDMI PHY PLL as DCLK source for display modes up
> > > > > +	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
> > > > > +	 */
> > > > > +	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
> > > > > +		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
> > > > > +			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
> > > > > +
> > > > > +			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
> > > > > +				if (!vp->dclk_src)
> > > > > +					vp->dclk_src = clk_get_parent(vp->dclk);
> > > > > +
> > > > > +				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
> > > > > +				if (ret < 0)
> > > > > +					drm_warn(vop2->drm,
> > > > > +						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
> > > > > +				break;
> > > > > +			}
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > 
> > > > It seems pretty fragile to do it at atomic_enable time, even more so
> > > > since you don't lock the parent either.
> > > > 
> > > > Any reason not to do it in the DRM or clock driver probe, and make sure
> > > > you never change the parent somehow?
> > > 
> > > On rk3588 we have 3 dclk_s and 2 hdmi controllers. Each video-port can
> > > use the clock generated from either the hdmi0phy or hdmi1phy, depending
> > > on which hdmi-controller it uses.
> > > 
> > > So you actually need to know which vpX will output to which hdmiY to then
> > > reparent that dclk to the hdmiphy output.
> > 
> > The Rockchip nomenclature isn't super obvious to me, sorry. Is there a
> > datasheet for this somewhere? Also, does this vpX -> HDMI-Y mapping need
> > to be dynamic?
> 
> VPs are CRTCs in drm-language and each of them can drive a differing
> number of output encoders. Those video-ports also have differing output
> characteristics in terms of supported resolution and other properties.
> 
> The rk3588 TRM has leaked in a number of places, and if you find a
> TRM-part2, there is a section labeled "Display Output Interface Description"
> that has a nice graphic for that.
> 
> Or in short:
> - CRTC(VP)0 supports 8K resolution and can drive DP0+1, HDMI0+1, eDP0+1
>   [if I'm reading things correctly, 8K together with CRTC1 somehow)
> - CRTC(VP)1 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP0+1
> - CRTC(VP)2 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP01, DSI0+1
> - CRTC(VP)3 supports 2K resolution and can drive DSI0+1 and some BT1120,BT656
> 
> so for the 3 higher resolution CRTCs there are essentially 6 or 8 output options
> depending on the board design

That's much clearer, thanks. I'm not entirely sure how that links to the
need for the PLL to change its parent depending on the ouput. Do you
need to always have all the outputs on the same PLL?

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

From fabrice.gasnier at foss.st.com  Tue Dec 17 07:00:21 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Tue, 17 Dec 2024 16:00:21 +0100
Subject: [PATCH] pwm: stm32: fix complementary output in round_waveform_tohw
Message-ID: <20241217150021.2030213-1-fabrice.gasnier@foss.st.com>

When the timer supports complementary output, the enable bit is
overridden. It should be OR'ed. This makes all PWM channels for
such timer not to work.

Fixes: deaba9cff809 ("pwm: stm32: Implementation of the waveform callbacks")
Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 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 b889e64522c3..17e591f61efb 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -84,7 +84,7 @@ static int stm32_pwm_round_waveform_tohw(struct pwm_chip *chip,
 
 	wfhw->ccer = TIM_CCER_CCxE(ch + 1);
 	if (priv->have_complementary_output)
-		wfhw->ccer = TIM_CCER_CCxNE(ch + 1);
+		wfhw->ccer |= TIM_CCER_CCxNE(ch + 1);
 
 	rate = clk_get_rate(priv->clk);
 
-- 
2.25.1



From maxime.chevallier at bootlin.com  Tue Dec 17 07:07:00 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 17 Dec 2024 16:07:00 +0100
Subject: [PATCH net-next 2/2] net: stmmac: dwmac-socfpga: Set interface
 modes from Lynx PCS as supported
In-Reply-To: <20241217064907.0e509769@kernel.org>
References: <20241213090526.71516-1-maxime.chevallier@bootlin.com>
	<20241213090526.71516-3-maxime.chevallier@bootlin.com>
	<Z1wnFXlgEU84VX8F@shell.armlinux.org.uk>
	<20241213182904.55eb2504@fedora.home>
	<Z1yJQikqneoFNJT4@shell.armlinux.org.uk>
	<20241216094224.199e8df7@fedora.home>
	<20241216173333.55e35f34@kernel.org>
	<20241217135932.60711288@fedora.home>
	<20241217064907.0e509769@kernel.org>
Message-ID: <20241217160700.1b4256b4@fedora.home>

On Tue, 17 Dec 2024 06:49:07 -0800
Jakub Kicinski <kuba at kernel.org> wrote:

> Let me triple check ;)
> 
> On Tue, 17 Dec 2024 13:59:32 +0100 Maxime Chevallier wrote:
> > - The priv->phylink_config.supported_interfaces is incomplete on
> > dwmac-socfpga. Russell's patch 5 intersects these modes with that the  
>                                    ^^^^^^^^^^
> > PCS supports :
> > 
> > +		phy_interface_or(priv->phylink_config.supported_interfaces,  
>                               ^^
> > +				 priv->phylink_config.supported_interfaces,
> > +				 pcs->supported_interfaces);
> > 
> > So without patch 2 in the series, we'll be missing
> > PHY_INTERFACE_MODE_1000BASEX in the end result :)  
> 
> "Or" is a sum/union, not intersection.
> 
> You set the bits in priv->phylink_config.supported_interfaces.
> Russell does:
> 
> 	priv->phylink_config.supported_interfaces |=
> 		pcs->supported_interfaces;
> 
> If I'm missing the point please repost once Russell's patches 
> are merged :)

Erf no I was missing the point, time to catch-up on some sleep I
guess... I read an 'and' and it was firmly stuck in my mind...

nevermind then, patch 2 isn't required anymore...

Maxime


From broonie at kernel.org  Tue Dec 17 07:10:28 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Dec 2024 15:10:28 +0000
Subject: [PATCH] KVM: arm64: Fix set_id_regs selftest for ASIDBITS
 becoming unwritable
In-Reply-To: <86v7viqusg.wl-maz@kernel.org>
References: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
 <875xnisocy.wl-maz@kernel.org>
 <53b40aa8-f51c-4c4e-a4ad-e6a9512e5197@sirena.org.uk>
 <86v7viqusg.wl-maz@kernel.org>
Message-ID: <b13b14df-00ee-4bee-8f65-d2cb7a9bfa6b@sirena.org.uk>

On Tue, Dec 17, 2024 at 01:54:39PM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:

> > The selftests are shipped as part of the kernel source and frequently
> > used for testing the kernel, it's all one source base and we want to
> > ensure that for example the test fix gets backported if the relevant
> > kernel patch does.

> That's not what Fixes: describes. If you want to invent a new tag that
> expresses a dependency, do that. Don't use these tags to misrepresent
> what the patches does.

No, this isn't a new use - a Fixes: tag indicates that the referenced
commit introduced the problem being fixed and that is exactly what's
going on here.  Like I say the selftests are not a completely separate
project, they are a part of the same source release as the rest of the
kernel and it is helpful to track information like 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/20241217/b4f645e7/attachment.sig>

From maz at kernel.org  Tue Dec 17 07:13:29 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:29 +0000
Subject: [PATCH 14/16] KVM: arm64: nv: Propagate used_lrs between L1 and L0 contexts
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-15-maz@kernel.org>

We have so far made sure that L1 and L0 vgic contexts were
totally independent. There is however one spot of bother with
this approach, and that's in the GICv3 emulation code required by
our fruity friends.

The issue is that the emulation code needs to know how many LRs
are in flight. And while it is easy to reach the L0 version through
the vcpu pointer, doing so for the L1 is much more complicated,
as these structures are private to the nested code.

We could simply expose that structure and pick one or the other
depending on the context, but this seems extra complexity for not
much benefit.

Instead, just propagate the number of used LRs from the nested code
into the L0 context, and be done with it. Should this become a burden,
it can be easily rectified.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/vgic/vgic-v3-nested.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
index fba499a20aec8..b81bfa85ebb19 100644
--- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -323,6 +323,12 @@ void vgic_v3_load_nested(struct kvm_vcpu *vcpu)
 	__vgic_v3_activate_traps(cpu_if);
 
 	__vgic_v3_restore_state(cpu_if);
+
+	/*
+	 * Propagate the number of used LRs for the benefit of the HYP
+	 * GICv3 emulation code. Yes, this is a pretty sorry hack.
+	 */
+	vcpu->arch.vgic_cpu.vgic_v3.used_lrs = cpu_if->used_lrs;
 }
 
 void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
@@ -358,6 +364,7 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
 	}
 
 	shadow_if->lr_map = 0;
+	vcpu->arch.vgic_cpu.vgic_v3.used_lrs = 0;
 }
 
 /*
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:31 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:31 +0000
Subject: [PATCH 16/16] KVM: arm64: nv: Allow userland to set VGIC maintenance IRQ
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-17-maz@kernel.org>

From: Andre Przywara <andre.przywara at arm.com>

The VGIC maintenance IRQ signals various conditions about the LRs, when
the GIC's virtualization extension is used.
So far we didn't need it, but nested virtualization needs to know about
this interrupt, so add a userland interface to setup the IRQ number.
The architecture mandates that it must be a PPI, on top of that this code
only exports a per-device option, so the PPI is the same on all VCPUs.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
[added some bits of documentation]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 .../virt/kvm/devices/arm-vgic-v3.rst          | 12 +++++++-
 arch/arm64/include/uapi/asm/kvm.h             |  1 +
 arch/arm64/kvm/vgic/vgic-kvm-device.c         | 29 +++++++++++++++++--
 tools/arch/arm/include/uapi/asm/kvm.h         |  1 +
 4 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/Documentation/virt/kvm/devices/arm-vgic-v3.rst b/Documentation/virt/kvm/devices/arm-vgic-v3.rst
index 5817edb4e0467..e860498b1e359 100644
--- a/Documentation/virt/kvm/devices/arm-vgic-v3.rst
+++ b/Documentation/virt/kvm/devices/arm-vgic-v3.rst
@@ -291,8 +291,18 @@ Groups:
       |    Aff3    |    Aff2    |    Aff1    |    Aff0    |
 
   Errors:
-
     =======  =============================================
     -EINVAL  vINTID is not multiple of 32 or info field is
 	     not VGIC_LEVEL_INFO_LINE_LEVEL
     =======  =============================================
+
+  KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ
+   Attributes:
+
+    The attr field of kvm_device_attr encodes the following values:
+
+      bits:     | 31   ....    5 | 4  ....  0 |
+      values:   |      RES0      |   vINTID   |
+
+    The vINTID specifies which interrupt is generated when the vGIC
+    must generate a maintenance interrupt. This must be a PPI.
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 66736ff04011e..05d53d3de5b3b 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -406,6 +406,7 @@ enum {
 #define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
 #define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO  7
 #define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8
+#define KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ  9
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT	10
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
 			(0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
index 5f4f57aaa23ec..ff986424e7e5f 100644
--- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
+++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
@@ -303,6 +303,12 @@ static int vgic_get_common_attr(struct kvm_device *dev,
 			     VGIC_NR_PRIVATE_IRQS, uaddr);
 		break;
 	}
+	case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {
+		u32 __user *uaddr = (u32 __user *)(long)attr->addr;
+
+		r = put_user(dev->kvm->arch.vgic.maint_irq, uaddr);
+		break;
+	}
 	}
 
 	return r;
@@ -517,7 +523,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
 	struct vgic_reg_attr reg_attr;
 	gpa_t addr;
 	struct kvm_vcpu *vcpu;
-	bool uaccess;
+	bool uaccess, post_init = true;
 	u32 val;
 	int ret;
 
@@ -533,6 +539,9 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
 		/* Sysregs uaccess is performed by the sysreg handling code */
 		uaccess = false;
 		break;
+	case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
+		post_init = false;
+		fallthrough;
 	default:
 		uaccess = true;
 	}
@@ -552,7 +561,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
 
 	mutex_lock(&dev->kvm->arch.config_lock);
 
-	if (unlikely(!vgic_initialized(dev->kvm))) {
+	if (post_init != vgic_initialized(dev->kvm)) {
 		ret = -EBUSY;
 		goto out;
 	}
@@ -582,6 +591,19 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
 		}
 		break;
 	}
+	case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
+		if (!is_write) {
+			val = dev->kvm->arch.vgic.maint_irq;
+			ret = 0;
+			break;
+		}
+
+		ret = -EINVAL;
+		if ((val < VGIC_NR_PRIVATE_IRQS) && (val >= VGIC_NR_SGIS)) {
+			dev->kvm->arch.vgic.maint_irq = val;
+			ret = 0;
+		}
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -608,6 +630,7 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
 	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
 	case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
 	case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO:
+	case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
 		return vgic_v3_attr_regs_access(dev, attr, true);
 	default:
 		return vgic_set_common_attr(dev, attr);
@@ -622,6 +645,7 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
 	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
 	case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
 	case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO:
+	case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
 		return vgic_v3_attr_regs_access(dev, attr, false);
 	default:
 		return vgic_get_common_attr(dev, attr);
@@ -645,6 +669,7 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
 	case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
 		return vgic_v3_has_attr_regs(dev, attr);
 	case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:
+	case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
 		return 0;
 	case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
 		if (((attr->attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK) >>
diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h
index 03cd7c19a683b..d5dd969028175 100644
--- a/tools/arch/arm/include/uapi/asm/kvm.h
+++ b/tools/arch/arm/include/uapi/asm/kvm.h
@@ -246,6 +246,7 @@ struct kvm_vcpu_events {
 #define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
 #define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO  7
 #define KVM_DEV_ARM_VGIC_GRP_ITS_REGS	8
+#define KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ	9
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT	10
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
 			(0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:28 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:28 +0000
Subject: [PATCH 13/16] KVM: arm64: nv: Request vPE doorbell upon nested ERET to L2
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-14-maz@kernel.org>

From: Oliver Upton <oliver.upton at linux.dev>

Running an L2 guest with GICv4 enabled goes absolutely nowhere, and gets
into a vicious cycle of nested ERET followed by nested exception entry
into the L1.

When KVM does a put on a runnable vCPU, it marks the vPE as nonresident
but does not request a doorbell IRQ. Behind the scenes in the ITS
driver's view of the vCPU, its_vpe::pending_last gets set to true to
indicate that context is still runnable.

This comes to a head when doing the nested ERET into L2. The vPE doesn't
get scheduled on the redistributor as it is exclusively part of the L1's
VGIC context. kvm_vgic_vcpu_pending_irq() returns true because the vPE
appears runnable, and KVM does a nested exception entry into the L1
before L2 ever gets off the ground.

This issue can be papered over by requesting a doorbell IRQ when
descheduling a vPE as part of a nested ERET. KVM needs this anyway to
kick the vCPU out of the L2 when an IRQ becomes pending for the L1.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
Link: https://lore.kernel.org/r/20240823212703.3576061-4-oliver.upton at linux.dev
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  2 ++
 arch/arm64/kvm/emulate-nested.c   |  2 ++
 arch/arm64/kvm/vgic/vgic-v4.c     | 18 +++++++++++++++++-
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index cb969c096d7bd..18d9166761972 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -958,6 +958,8 @@ struct kvm_vcpu_arch {
 #define PMUSERENR_ON_CPU	__vcpu_single_flag(sflags, BIT(4))
 /* WFI instruction trapped */
 #define IN_WFI			__vcpu_single_flag(sflags, BIT(5))
+/* KVM is currently emulating a nested ERET */
+#define IN_NESTED_ERET		__vcpu_single_flag(sflags, BIT(6))
 
 
 /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index c460b8403aec5..69233dcc81a46 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2434,6 +2434,7 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
 	}
 
 	preempt_disable();
+	vcpu_set_flag(vcpu, IN_NESTED_ERET);
 	kvm_arch_vcpu_put(vcpu);
 
 	if (!esr_iss_is_eretax(esr))
@@ -2445,6 +2446,7 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
 	*vcpu_cpsr(vcpu) = spsr;
 
 	kvm_arch_vcpu_load(vcpu, smp_processor_id());
+	vcpu_clear_flag(vcpu, IN_NESTED_ERET);
 	preempt_enable();
 
 	kvm_pmu_nested_transition(vcpu);
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
index eedecbbbcf31b..0d9fb235c0180 100644
--- a/arch/arm64/kvm/vgic/vgic-v4.c
+++ b/arch/arm64/kvm/vgic/vgic-v4.c
@@ -336,6 +336,22 @@ void vgic_v4_teardown(struct kvm *kvm)
 	its_vm->vpes = NULL;
 }
 
+static inline bool vgic_v4_want_doorbell(struct kvm_vcpu *vcpu)
+{
+	if (vcpu_get_flag(vcpu, IN_WFI))
+		return true;
+
+	if (likely(!vcpu_has_nv(vcpu)))
+		return false;
+
+	/*
+	 * GICv4 hardware is only ever used for the L1. Mark the vPE (i.e. the
+	 * L1 context) nonresident and request a doorbell to kick us out of the
+	 * L2 when an IRQ becomes pending.
+	 */
+	return vcpu_get_flag(vcpu, IN_NESTED_ERET);
+}
+
 int vgic_v4_put(struct kvm_vcpu *vcpu)
 {
 	struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
@@ -343,7 +359,7 @@ int vgic_v4_put(struct kvm_vcpu *vcpu)
 	if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident)
 		return 0;
 
-	return its_make_vpe_non_resident(vpe, !!vcpu_get_flag(vcpu, IN_WFI));
+	return its_make_vpe_non_resident(vpe, vgic_v4_want_doorbell(vcpu));
 }
 
 int vgic_v4_load(struct kvm_vcpu *vcpu)
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:30 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:30 +0000
Subject: [PATCH 15/16] KVM: arm64: nv: Fold GICv3 host trapping requirements into guest setup
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-16-maz@kernel.org>

Popular HW that is able to use NV also has a broken vgic implementation
that requires trapping.

On such HW, propagate the host trap bits into the guest's shadow
ICH_HCR_EL2 register, making sure we don't allow an L2 guest to bring
the system down.

This involves a bit of tweaking so that the emulation code correctly
poicks up the shadow state as needed, and to only partially sync
ICH_HCR_EL2 back with the guest state to capture EOIcount.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/vgic/vgic-v3-nested.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
index b81bfa85ebb19..778ffb62de21c 100644
--- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -296,9 +296,19 @@ static void vgic_v3_create_shadow_state(struct kvm_vcpu *vcpu,
 					struct vgic_v3_cpu_if *s_cpu_if)
 {
 	struct vgic_v3_cpu_if *host_if = &vcpu->arch.vgic_cpu.vgic_v3;
+	u64 val = 0;
 	int i;
 
-	s_cpu_if->vgic_hcr = __vcpu_sys_reg(vcpu, ICH_HCR_EL2);
+	/*
+	 * If we're on a system with a broken vgic that requires
+	 * trapping, propagate the trapping requirements.
+	 *
+	 * Ah, the smell of rotten fruits...
+	 */
+	if (static_branch_unlikely(&vgic_v3_cpuif_trap))
+		val = host_if->vgic_hcr & (ICH_HCR_EL2_TALL0 | ICH_HCR_EL2_TALL1 |
+					   ICH_HCR_EL2_TC | ICH_HCR_EL2_TDIR);
+	s_cpu_if->vgic_hcr = __vcpu_sys_reg(vcpu, ICH_HCR_EL2) | val;
 	s_cpu_if->vgic_vmcr = __vcpu_sys_reg(vcpu, ICH_VMCR_EL2);
 	s_cpu_if->vgic_sre = host_if->vgic_sre;
 
@@ -335,6 +345,7 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
 {
 	struct shadow_if *shadow_if = get_shadow_if();
 	struct vgic_v3_cpu_if *s_cpu_if = &shadow_if->cpuif;
+	u64 val;
 	int i;
 
 	__vgic_v3_save_vmcr_aprs(s_cpu_if);
@@ -345,7 +356,10 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
 	 * Translate the shadow state HW fields back to the virtual ones
 	 * before copying the shadow struct back to the nested one.
 	 */
-	__vcpu_sys_reg(vcpu, ICH_HCR_EL2) = s_cpu_if->vgic_hcr;
+	val = __vcpu_sys_reg(vcpu, ICH_HCR_EL2);
+	val &= ~ICH_HCR_EL2_EOIcount_MASK;
+	val |= (s_cpu_if->vgic_hcr & ICH_HCR_EL2_EOIcount_MASK);
+	__vcpu_sys_reg(vcpu, ICH_HCR_EL2) = val;
 	__vcpu_sys_reg(vcpu, ICH_VMCR_EL2) = s_cpu_if->vgic_vmcr;
 
 	for (i = 0; i < 4; i++) {
@@ -354,7 +368,7 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
 	}
 
 	for_each_set_bit(i, &shadow_if->lr_map, kvm_vgic_global_state.nr_lr) {
-		u64 val = __vcpu_sys_reg(vcpu, ICH_LRN(i));
+		val = __vcpu_sys_reg(vcpu, ICH_LRN(i));
 
 		val &= ~ICH_LR_STATE;
 		val |= s_cpu_if->vgic_lr[i] & ICH_LR_STATE;
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:26 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:26 +0000
Subject: [PATCH 11/16] KVM: arm64: nv: Add Maintenance Interrupt emulation
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-12-maz@kernel.org>

Emulating the vGIC means emulating the dreaded Maintenance Interrupt.

This is a two-pronged problem:

- while running L2, getting an MI translates into an MI injected
  in the L1 based on the state of the HW.

- while running L1, we must accurately reflect the state of the
  MI line, based on the in-memory state.

The MI INTID is added to the distributor, as expected on any
virtualisation-capable implementation, and further patches
will allow its configuration.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arm.c                 |  6 ++++
 arch/arm64/kvm/vgic/vgic-init.c      | 22 ++++++++++++++
 arch/arm64/kvm/vgic/vgic-v3-nested.c | 45 ++++++++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic.c           |  9 ++++++
 arch/arm64/kvm/vgic/vgic.h           |  2 ++
 include/kvm/arm_vgic.h               |  4 +++
 6 files changed, 88 insertions(+)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 5e353b2c225b4..756cc4e74e10f 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -824,6 +824,12 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
 	if (ret)
 		return ret;
 
+	if (vcpu_has_nv(vcpu)) {
+		ret = kvm_vgic_vcpu_nv_init(vcpu);
+		if (ret)
+			return ret;
+	}
+
 	/*
 	 * This needs to happen after any restriction has been applied
 	 * to the feature set.
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index bc7e22ab5d812..d2724315a70e9 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -180,6 +180,20 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)
 	return 0;
 }
 
+int kvm_vgic_vcpu_nv_init(struct kvm_vcpu *vcpu)
+{
+	int ret;
+
+	guard(mutex)(&vcpu->kvm->arch.config_lock);
+
+	/* Cope with vintage userspace. Maybe we should fail instead */
+	if (vcpu->kvm->arch.vgic.maint_irq == 0)
+		vcpu->kvm->arch.vgic.maint_irq = kvm_vgic_global_state.maint_irq;
+	ret = kvm_vgic_set_owner(vcpu, vcpu->kvm->arch.vgic.maint_irq, vcpu);
+
+	return ret;
+}
+
 static int vgic_allocate_private_irqs_locked(struct kvm_vcpu *vcpu)
 {
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
@@ -588,12 +602,20 @@ void kvm_vgic_cpu_down(void)
 
 static irqreturn_t vgic_maintenance_handler(int irq, void *data)
 {
+	struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)data;
+
 	/*
 	 * We cannot rely on the vgic maintenance interrupt to be
 	 * delivered synchronously. This means we can only use it to
 	 * exit the VM, and we perform the handling of EOIed
 	 * interrupts on the exit path (see vgic_fold_lr_state).
+	 *
+	 * Of course, NV throws a wrench in this plan, and needs
+	 * something special.
 	 */
+	if (vcpu && vgic_state_is_nested(vcpu))
+		vgic_v3_handle_nested_maint_irq(vcpu);
+
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
index 3d80bfb37de00..fba499a20aec8 100644
--- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -73,6 +73,24 @@ static DEFINE_PER_CPU(struct shadow_if, shadow_if);
  *   interrupt. The L0 active state will be cleared by the HW if the L1
  *   interrupt was itself backed by a HW interrupt.
  *
+ * Maintenance Interrupt (MI) management:
+ *
+ * Since the L2 guest runs the vgic in its full glory, MIs get delivered and
+ * used as a handover point between L2 and L1.
+ *
+ * - on delivery of a MI to L0 while L2 is running: make the L1 MI pending,
+ *   and let it rip. This will initiate a vcpu_put() on L2, and allow L1 to
+ *   run and process the MI.
+ *
+ * - L1 MI is a fully virtual interrupt, not linked to the host's MI. Its
+ *   state must be computed at each entry/exit of the guest, much like we do
+ *   it for the PMU interrupt.
+ *
+ * - because most of the ICH_*_EL2 registers live in the VNCR page, the
+ *   quality of emulation is poor: L1 can setup the vgic so that an MI would
+ *   immediately fire, and not observe anything until the next exit. Trying
+ *   to read ICH_MISR_EL2 would do the trick, for example.
+ *
  * System register emulation:
  *
  * We get two classes of registers:
@@ -341,3 +359,30 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
 
 	shadow_if->lr_map = 0;
 }
+
+/*
+ * If we exit a L2 VM with a pending maintenance interrupt from the GIC,
+ * then we need to forward this to L1 so that it can re-sync the appropriate
+ * LRs and sample level triggered interrupts again.
+ */
+void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu)
+{
+	bool state = read_sysreg_s(SYS_ICH_MISR_EL2);
+
+	/* This will force a switch back to L1 if the level is high */
+	kvm_vgic_inject_irq(vcpu->kvm, vcpu,
+			    vcpu->kvm->arch.vgic.maint_irq, state, vcpu);
+
+	sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EL2_En, 0);
+}
+
+void vgic_v3_nested_update_mi(struct kvm_vcpu *vcpu)
+{
+	bool level;
+
+	level  = __vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_En;
+	if (level)
+		level &= vgic_v3_get_misr(vcpu);
+	kvm_vgic_inject_irq(vcpu->kvm, vcpu,
+			    vcpu->kvm->arch.vgic.maint_irq, level, vcpu);
+}
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 9734a71b85611..8f8096d489252 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -878,6 +878,9 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 		return;
 	}
 
+	if (vcpu_has_nv(vcpu))
+		vgic_v3_nested_update_mi(vcpu);
+
 	/* An empty ap_list_head implies used_lrs == 0 */
 	if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head))
 		return;
@@ -921,6 +924,9 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
 	 *
 	 * - Otherwise, do exactly *NOTHING*. The guest state is
 	 *   already loaded, and we can carry on with running it.
+	 *
+	 * If we have NV, but are not in a nested state, compute the
+	 * maintenance interrupt state, as it may fire.
 	 */
 	if (vgic_state_is_nested(vcpu)) {
 		if (kvm_vgic_vcpu_pending_irq(vcpu))
@@ -929,6 +935,9 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
 		return;
 	}
 
+	if (vcpu_has_nv(vcpu))
+		vgic_v3_nested_update_mi(vcpu);
+
 	/*
 	 * If there are no virtual interrupts active or pending for this
 	 * VCPU, then there is no work to do and we can bail out without
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index cf0c084e5d347..0c5a63712702b 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -356,5 +356,7 @@ static inline bool kvm_has_gicv3(struct kvm *kvm)
 void vgic_v3_sync_nested(struct kvm_vcpu *vcpu);
 void vgic_v3_load_nested(struct kvm_vcpu *vcpu);
 void vgic_v3_put_nested(struct kvm_vcpu *vcpu);
+void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu);
+void vgic_v3_nested_update_mi(struct kvm_vcpu *vcpu);
 
 #endif
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 1b373cb870fe4..b33166f05124c 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -249,6 +249,9 @@ struct vgic_dist {
 
 	int			nr_spis;
 
+	/* The GIC maintenance IRQ for nested hypervisors. */
+	u32			maint_irq;
+
 	/* base addresses in guest physical address space: */
 	gpa_t			vgic_dist_base;		/* distributor */
 	union {
@@ -369,6 +372,7 @@ extern struct static_key_false vgic_v3_cpuif_trap;
 int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev_addr);
 void kvm_vgic_early_init(struct kvm *kvm);
 int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu);
+int kvm_vgic_vcpu_nv_init(struct kvm_vcpu *vcpu);
 int kvm_vgic_create(struct kvm *kvm, u32 type);
 void kvm_vgic_destroy(struct kvm *kvm);
 void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
-- 
2.39.2



From robh at kernel.org  Tue Dec 17 07:18:06 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 17 Dec 2024 09:18:06 -0600
Subject: [PATCH net-next v4 9/9] dt-bindings: net: sparx5: document RGMII
 delays
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-9-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
 <20241213-sparx5-lan969x-switch-driver-4-v4-9-d1a72c9c4714@microchip.com>
Message-ID: <173444868627.1811657.3055323155605621690.robh@kernel.org>


On Fri, 13 Dec 2024 14:41:08 +0100, Daniel Machon wrote:
> The lan969x switch device supports two RGMII port interfaces that can be
> configured for MAC level rx and tx delays. Document two new properties
> {rx,tx}-internal-delay-ps in the bindings, used to select these delays.
> 
> Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
> ---
>  .../bindings/net/microchip,sparx5-switch.yaml          | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From olteanv at gmail.com  Tue Dec 17 07:13:39 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 17 Dec 2024 17:13:39 +0200
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <675da041.050a0220.a8e65.af0e@mx.google.com>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241210211529.osgzd54flq646bcr@skbuf>
 <6758c174.050a0220.52a35.06bc@mx.google.com>
 <20241210234803.pzm7fxrve4dastth@skbuf>
 <675da041.050a0220.a8e65.af0e@mx.google.com>
Message-ID: <20241217151339.gjpdkfbechdjohza@skbuf>

On Sat, Dec 14, 2024 at 04:11:54PM +0100, Christian Marangi wrote:
> We can see that:
> - as suggested regmap doesn't cause any performance penality. It does
>   even produce better result.
> - the read/set/restore implementation gives worse performance.
> 
> So I guess I will follow the path of regmap + cache page. What do you
> think?

I'm not seeing results with the "times" variable changed, but in
general, I guess the "switch regmap + page" and "switch regmap + phy
regmap" will remain neck and neck in terms of performance, surpassing
the "switch regmap restore" techniques more and more as "times"
increases. So going with a PHY regmap probably sounds good.


From maz at kernel.org  Tue Dec 17 07:13:17 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:17 +0000
Subject: [PATCH 02/16] arm64: sysreg: Add layout for ICH_VTR_EL2
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-3-maz@kernel.org>

The ICH_VTR_EL2-related macros are missing a number of config
bits that we are about to handle. Take this opportunity to fully
describe the layout of that register as part of the automatic
generation infrastructure.

This results in a bit of churn to repaint constants that are now
generated with a different format.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/sysreg.h       | 13 -------------
 arch/arm64/kvm/vgic-sys-reg-v3.c      |  8 ++++----
 arch/arm64/kvm/vgic/vgic-v3.c         | 16 +++++++---------
 arch/arm64/tools/sysreg               | 14 ++++++++++++++
 tools/arch/arm64/include/asm/sysreg.h | 13 -------------
 5 files changed, 25 insertions(+), 39 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 3e84ef8f5b311..cf74ebcd46d95 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -561,7 +561,6 @@
 
 #define SYS_ICH_VSEIR_EL2		sys_reg(3, 4, 12, 9, 4)
 #define SYS_ICC_SRE_EL2			sys_reg(3, 4, 12, 9, 5)
-#define SYS_ICH_VTR_EL2			sys_reg(3, 4, 12, 11, 1)
 #define SYS_ICH_MISR_EL2		sys_reg(3, 4, 12, 11, 2)
 #define SYS_ICH_EISR_EL2		sys_reg(3, 4, 12, 11, 3)
 #define SYS_ICH_ELRSR_EL2		sys_reg(3, 4, 12, 11, 5)
@@ -1030,18 +1029,6 @@
 #define ICH_VMCR_ENG1_SHIFT	1
 #define ICH_VMCR_ENG1_MASK	(1 << ICH_VMCR_ENG1_SHIFT)
 
-/* ICH_VTR_EL2 bit definitions */
-#define ICH_VTR_PRI_BITS_SHIFT	29
-#define ICH_VTR_PRI_BITS_MASK	(7 << ICH_VTR_PRI_BITS_SHIFT)
-#define ICH_VTR_ID_BITS_SHIFT	23
-#define ICH_VTR_ID_BITS_MASK	(7 << ICH_VTR_ID_BITS_SHIFT)
-#define ICH_VTR_SEIS_SHIFT	22
-#define ICH_VTR_SEIS_MASK	(1 << ICH_VTR_SEIS_SHIFT)
-#define ICH_VTR_A3V_SHIFT	21
-#define ICH_VTR_A3V_MASK	(1 << ICH_VTR_A3V_SHIFT)
-#define ICH_VTR_TDS_SHIFT	19
-#define ICH_VTR_TDS_MASK	(1 << ICH_VTR_TDS_SHIFT)
-
 /*
  * Permission Indirection Extension (PIE) permission encodings.
  * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
diff --git a/arch/arm64/kvm/vgic-sys-reg-v3.c b/arch/arm64/kvm/vgic-sys-reg-v3.c
index 9e7c486b48c2e..5eacb4b3250a1 100644
--- a/arch/arm64/kvm/vgic-sys-reg-v3.c
+++ b/arch/arm64/kvm/vgic-sys-reg-v3.c
@@ -35,12 +35,12 @@ static int set_gic_ctlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
 
 	vgic_v3_cpu->num_id_bits = host_id_bits;
 
-	host_seis = FIELD_GET(ICH_VTR_SEIS_MASK, kvm_vgic_global_state.ich_vtr_el2);
+	host_seis = FIELD_GET(ICH_VTR_EL2_SEIS, kvm_vgic_global_state.ich_vtr_el2);
 	seis = FIELD_GET(ICC_CTLR_EL1_SEIS_MASK, val);
 	if (host_seis != seis)
 		return -EINVAL;
 
-	host_a3v = FIELD_GET(ICH_VTR_A3V_MASK, kvm_vgic_global_state.ich_vtr_el2);
+	host_a3v = FIELD_GET(ICH_VTR_EL2_A3V, kvm_vgic_global_state.ich_vtr_el2);
 	a3v = FIELD_GET(ICC_CTLR_EL1_A3V_MASK, val);
 	if (host_a3v != a3v)
 		return -EINVAL;
@@ -68,10 +68,10 @@ static int get_gic_ctlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
 	val |= FIELD_PREP(ICC_CTLR_EL1_PRI_BITS_MASK, vgic_v3_cpu->num_pri_bits - 1);
 	val |= FIELD_PREP(ICC_CTLR_EL1_ID_BITS_MASK, vgic_v3_cpu->num_id_bits);
 	val |= FIELD_PREP(ICC_CTLR_EL1_SEIS_MASK,
-			  FIELD_GET(ICH_VTR_SEIS_MASK,
+			  FIELD_GET(ICH_VTR_EL2_SEIS,
 				    kvm_vgic_global_state.ich_vtr_el2));
 	val |= FIELD_PREP(ICC_CTLR_EL1_A3V_MASK,
-			  FIELD_GET(ICH_VTR_A3V_MASK, kvm_vgic_global_state.ich_vtr_el2));
+			  FIELD_GET(ICH_VTR_EL2_A3V, kvm_vgic_global_state.ich_vtr_el2));
 	/*
 	 * The VMCR.CTLR value is in ICC_CTLR_EL1 layout.
 	 * Extract it directly using ICC_CTLR_EL1 reg definitions.
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 6c21be12959d6..0bdecbbe74898 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -283,12 +283,10 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
 		vgic_v3->vgic_sre = 0;
 	}
 
-	vcpu->arch.vgic_cpu.num_id_bits = (kvm_vgic_global_state.ich_vtr_el2 &
-					   ICH_VTR_ID_BITS_MASK) >>
-					   ICH_VTR_ID_BITS_SHIFT;
-	vcpu->arch.vgic_cpu.num_pri_bits = ((kvm_vgic_global_state.ich_vtr_el2 &
-					    ICH_VTR_PRI_BITS_MASK) >>
-					    ICH_VTR_PRI_BITS_SHIFT) + 1;
+	vcpu->arch.vgic_cpu.num_id_bits = FIELD_GET(ICH_VTR_EL2_IDbits,
+						    kvm_vgic_global_state.ich_vtr_el2);
+	vcpu->arch.vgic_cpu.num_pri_bits = FIELD_GET(ICH_VTR_EL2_PRIbits,
+						     kvm_vgic_global_state.ich_vtr_el2) + 1;
 
 	/* Get the show on the road... */
 	vgic_v3->vgic_hcr = ICH_HCR_EL2_En;
@@ -632,7 +630,7 @@ static const struct midr_range broken_seis[] = {
 
 static bool vgic_v3_broken_seis(void)
 {
-	return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) &&
+	return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_EL2_SEIS) &&
 		is_midr_in_range_list(read_cpuid_id(), broken_seis));
 }
 
@@ -706,10 +704,10 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
 	if (vgic_v3_broken_seis()) {
 		kvm_info("GICv3 with broken locally generated SEI\n");
 
-		kvm_vgic_global_state.ich_vtr_el2 &= ~ICH_VTR_SEIS_MASK;
+		kvm_vgic_global_state.ich_vtr_el2 &= ~ICH_VTR_EL2_SEIS;
 		group0_trap = true;
 		group1_trap = true;
-		if (ich_vtr_el2 & ICH_VTR_TDS_MASK)
+		if (ich_vtr_el2 & ICH_VTR_EL2_TDS)
 			dir_trap = true;
 		else
 			common_trap = true;
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 9938926421b5c..f5927d345eea3 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2960,6 +2960,20 @@ Field	1	UIE
 Field	0	En
 EndSysreg
 
+Sysreg	ICH_VTR_EL2	3	4	12	11	1
+Res0	63:32
+Field	31:29	PRIbits
+Field	28:26	PREbits
+Field	25:23	IDbits
+Field	22	SEIS
+Field	21	A3V
+Field	20	nV4
+Field	19	TDS
+Field	18	DVIM
+Res0	17:5
+Field	4:0	ListRegs
+EndSysreg
+
 Sysreg	CONTEXTIDR_EL2	3	4	13	0	1
 Fields	CONTEXTIDR_ELx
 EndSysreg
diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index d314ccab7560a..f43e303d31d25 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -420,7 +420,6 @@
 
 #define SYS_ICH_VSEIR_EL2		sys_reg(3, 4, 12, 9, 4)
 #define SYS_ICC_SRE_EL2			sys_reg(3, 4, 12, 9, 5)
-#define SYS_ICH_VTR_EL2			sys_reg(3, 4, 12, 11, 1)
 #define SYS_ICH_MISR_EL2		sys_reg(3, 4, 12, 11, 2)
 #define SYS_ICH_EISR_EL2		sys_reg(3, 4, 12, 11, 3)
 #define SYS_ICH_ELRSR_EL2		sys_reg(3, 4, 12, 11, 5)
@@ -673,18 +672,6 @@
 #define ICH_VMCR_ENG1_SHIFT	1
 #define ICH_VMCR_ENG1_MASK	(1 << ICH_VMCR_ENG1_SHIFT)
 
-/* ICH_VTR_EL2 bit definitions */
-#define ICH_VTR_PRI_BITS_SHIFT	29
-#define ICH_VTR_PRI_BITS_MASK	(7 << ICH_VTR_PRI_BITS_SHIFT)
-#define ICH_VTR_ID_BITS_SHIFT	23
-#define ICH_VTR_ID_BITS_MASK	(7 << ICH_VTR_ID_BITS_SHIFT)
-#define ICH_VTR_SEIS_SHIFT	22
-#define ICH_VTR_SEIS_MASK	(1 << ICH_VTR_SEIS_SHIFT)
-#define ICH_VTR_A3V_SHIFT	21
-#define ICH_VTR_A3V_MASK	(1 << ICH_VTR_A3V_SHIFT)
-#define ICH_VTR_TDS_SHIFT	19
-#define ICH_VTR_TDS_MASK	(1 << ICH_VTR_TDS_SHIFT)
-
 /*
  * Permission Indirection Extension (PIE) permission encodings.
  * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:16 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:16 +0000
Subject: [PATCH 01/16] arm64: sysreg: Add layout for ICH_HCR_EL2
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-2-maz@kernel.org>

The ICH_HCR_EL2-related macros are missing a number of control
bits that we are about to handle. Take this opportunity to fully
describe the layout of that register as part of the automatic
generation infrastructure.

This results in a bit of churn, unfortunately.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/sysreg.h       | 12 ------------
 arch/arm64/kvm/emulate-nested.c       | 16 ++++++++--------
 arch/arm64/kvm/hyp/vgic-v3-sr.c       | 14 +++++++-------
 arch/arm64/kvm/vgic/vgic-v3.c         | 17 +++++++++--------
 arch/arm64/tools/sysreg               | 22 ++++++++++++++++++++++
 drivers/irqchip/irq-apple-aic.c       |  8 ++++----
 tools/arch/arm64/include/asm/sysreg.h | 12 ------------
 7 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index b8303a83c0bff..3e84ef8f5b311 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -561,7 +561,6 @@
 
 #define SYS_ICH_VSEIR_EL2		sys_reg(3, 4, 12, 9, 4)
 #define SYS_ICC_SRE_EL2			sys_reg(3, 4, 12, 9, 5)
-#define SYS_ICH_HCR_EL2			sys_reg(3, 4, 12, 11, 0)
 #define SYS_ICH_VTR_EL2			sys_reg(3, 4, 12, 11, 1)
 #define SYS_ICH_MISR_EL2		sys_reg(3, 4, 12, 11, 2)
 #define SYS_ICH_EISR_EL2		sys_reg(3, 4, 12, 11, 3)
@@ -1011,17 +1010,6 @@
 #define ICH_LR_PRIORITY_SHIFT	48
 #define ICH_LR_PRIORITY_MASK	(0xffULL << ICH_LR_PRIORITY_SHIFT)
 
-/* ICH_HCR_EL2 bit definitions */
-#define ICH_HCR_EN		(1 << 0)
-#define ICH_HCR_UIE		(1 << 1)
-#define ICH_HCR_NPIE		(1 << 3)
-#define ICH_HCR_TC		(1 << 10)
-#define ICH_HCR_TALL0		(1 << 11)
-#define ICH_HCR_TALL1		(1 << 12)
-#define ICH_HCR_TDIR		(1 << 14)
-#define ICH_HCR_EOIcount_SHIFT	27
-#define ICH_HCR_EOIcount_MASK	(0x1f << ICH_HCR_EOIcount_SHIFT)
-
 /* ICH_VMCR_EL2 bit definitions */
 #define ICH_VMCR_ACK_CTL_SHIFT	2
 #define ICH_VMCR_ACK_CTL_MASK	(1 << ICH_VMCR_ACK_CTL_SHIFT)
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 1ffbfd1c3cf2e..c460b8403aec5 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -395,26 +395,26 @@ static const struct trap_bits coarse_trap_bits[] = {
 	},
 	[CGT_ICH_HCR_TC] = {
 		.index		= ICH_HCR_EL2,
-		.value		= ICH_HCR_TC,
-		.mask		= ICH_HCR_TC,
+		.value		= ICH_HCR_EL2_TC,
+		.mask		= ICH_HCR_EL2_TC,
 		.behaviour	= BEHAVE_FORWARD_RW,
 	},
 	[CGT_ICH_HCR_TALL0] = {
 		.index		= ICH_HCR_EL2,
-		.value		= ICH_HCR_TALL0,
-		.mask		= ICH_HCR_TALL0,
+		.value		= ICH_HCR_EL2_TALL0,
+		.mask		= ICH_HCR_EL2_TALL0,
 		.behaviour	= BEHAVE_FORWARD_RW,
 	},
 	[CGT_ICH_HCR_TALL1] = {
 		.index		= ICH_HCR_EL2,
-		.value		= ICH_HCR_TALL1,
-		.mask		= ICH_HCR_TALL1,
+		.value		= ICH_HCR_EL2_TALL1,
+		.mask		= ICH_HCR_EL2_TALL1,
 		.behaviour	= BEHAVE_FORWARD_RW,
 	},
 	[CGT_ICH_HCR_TDIR] = {
 		.index		= ICH_HCR_EL2,
-		.value		= ICH_HCR_TDIR,
-		.mask		= ICH_HCR_TDIR,
+		.value		= ICH_HCR_EL2_TDIR,
+		.mask		= ICH_HCR_EL2_TDIR,
 		.behaviour	= BEHAVE_FORWARD_RW,
 	},
 };
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
index 3f9741e51d41b..b47dede973b3c 100644
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -218,7 +218,7 @@ void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if)
 
 		elrsr = read_gicreg(ICH_ELRSR_EL2);
 
-		write_gicreg(cpu_if->vgic_hcr & ~ICH_HCR_EN, ICH_HCR_EL2);
+		write_gicreg(cpu_if->vgic_hcr & ~ICH_HCR_EL2_En, ICH_HCR_EL2);
 
 		for (i = 0; i < used_lrs; i++) {
 			if (elrsr & (1 << i))
@@ -274,7 +274,7 @@ void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if)
 	 * system registers to trap to EL1 (duh), force ICC_SRE_EL1.SRE to 1
 	 * so that the trap bits can take effect. Yes, we *loves* the GIC.
 	 */
-	if (!(cpu_if->vgic_hcr & ICH_HCR_EN)) {
+	if (!(cpu_if->vgic_hcr & ICH_HCR_EL2_En)) {
 		write_gicreg(ICC_SRE_EL1_SRE, ICC_SRE_EL1);
 		isb();
 	} else if (!cpu_if->vgic_sre) {
@@ -752,7 +752,7 @@ static void __vgic_v3_bump_eoicount(void)
 	u32 hcr;
 
 	hcr = read_gicreg(ICH_HCR_EL2);
-	hcr += 1 << ICH_HCR_EOIcount_SHIFT;
+	hcr += 1 << ICH_HCR_EL2_EOIcount_SHIFT;
 	write_gicreg(hcr, ICH_HCR_EL2);
 }
 
@@ -1069,7 +1069,7 @@ static bool __vgic_v3_check_trap_forwarding(struct kvm_vcpu *vcpu,
 	case SYS_ICC_EOIR0_EL1:
 	case SYS_ICC_HPPIR0_EL1:
 	case SYS_ICC_IAR0_EL1:
-		return ich_hcr & ICH_HCR_TALL0;
+		return ich_hcr & ICH_HCR_EL2_TALL0;
 
 	case SYS_ICC_IGRPEN1_EL1:
 		if (is_read &&
@@ -1090,10 +1090,10 @@ static bool __vgic_v3_check_trap_forwarding(struct kvm_vcpu *vcpu,
 	case SYS_ICC_EOIR1_EL1:
 	case SYS_ICC_HPPIR1_EL1:
 	case SYS_ICC_IAR1_EL1:
-		return ich_hcr & ICH_HCR_TALL1;
+		return ich_hcr & ICH_HCR_EL2_TALL1;
 
 	case SYS_ICC_DIR_EL1:
-		if (ich_hcr & ICH_HCR_TDIR)
+		if (ich_hcr & ICH_HCR_EL2_TDIR)
 			return true;
 
 		fallthrough;
@@ -1101,7 +1101,7 @@ static bool __vgic_v3_check_trap_forwarding(struct kvm_vcpu *vcpu,
 	case SYS_ICC_RPR_EL1:
 	case SYS_ICC_CTLR_EL1:
 	case SYS_ICC_PMR_EL1:
-		return ich_hcr & ICH_HCR_TC;
+		return ich_hcr & ICH_HCR_EL2_TC;
 
 	default:
 		return false;
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index f267bc2486a18..6c21be12959d6 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -23,7 +23,7 @@ void vgic_v3_set_underflow(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3;
 
-	cpuif->vgic_hcr |= ICH_HCR_UIE;
+	cpuif->vgic_hcr |= ICH_HCR_EL2_UIE;
 }
 
 static bool lr_signals_eoi_mi(u64 lr_val)
@@ -41,7 +41,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
 
 	DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());
 
-	cpuif->vgic_hcr &= ~ICH_HCR_UIE;
+	cpuif->vgic_hcr &= ~ICH_HCR_EL2_UIE;
 
 	for (lr = 0; lr < cpuif->used_lrs; lr++) {
 		u64 val = cpuif->vgic_lr[lr];
@@ -291,7 +291,7 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
 					    ICH_VTR_PRI_BITS_SHIFT) + 1;
 
 	/* Get the show on the road... */
-	vgic_v3->vgic_hcr = ICH_HCR_EN;
+	vgic_v3->vgic_hcr = ICH_HCR_EL2_En;
 }
 
 void vcpu_set_ich_hcr(struct kvm_vcpu *vcpu)
@@ -300,18 +300,19 @@ void vcpu_set_ich_hcr(struct kvm_vcpu *vcpu)
 
 	/* Hide GICv3 sysreg if necessary */
 	if (!kvm_has_gicv3(vcpu->kvm)) {
-		vgic_v3->vgic_hcr |= ICH_HCR_TALL0 | ICH_HCR_TALL1 | ICH_HCR_TC;
+		vgic_v3->vgic_hcr |= (ICH_HCR_EL2_TALL0 | ICH_HCR_EL2_TALL1 |
+				      ICH_HCR_EL2_TC);
 		return;
 	}
 
 	if (group0_trap)
-		vgic_v3->vgic_hcr |= ICH_HCR_TALL0;
+		vgic_v3->vgic_hcr |= ICH_HCR_EL2_TALL0;
 	if (group1_trap)
-		vgic_v3->vgic_hcr |= ICH_HCR_TALL1;
+		vgic_v3->vgic_hcr |= ICH_HCR_EL2_TALL1;
 	if (common_trap)
-		vgic_v3->vgic_hcr |= ICH_HCR_TC;
+		vgic_v3->vgic_hcr |= ICH_HCR_EL2_TC;
 	if (dir_trap)
-		vgic_v3->vgic_hcr |= ICH_HCR_TDIR;
+		vgic_v3->vgic_hcr |= ICH_HCR_EL2_TDIR;
 }
 
 int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq)
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index b081b54d6d227..9938926421b5c 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2938,6 +2938,28 @@ Field	31:16	PhyPARTID29
 Field	15:0	PhyPARTID28
 EndSysreg
 
+Sysreg	ICH_HCR_EL2	3	4	12	11	0
+Res0	63:32
+Field	31:27	EOIcount
+Res0	26:16
+Field	15	DVIM
+Field	14	TDIR
+Field	13	TSEI
+Field	12	TALL1
+Field	11	TALL0
+Field	10	TC
+Res0	9
+Field	8	vSGIEOICount
+Field	7	VGrp1DIE
+Field	6	VGrp1EIE
+Field	5	VGrp0DIE
+Field	4	VGrp0EIE
+Field	3	NPIE
+Field	2	LRENPIE
+Field	1	UIE
+Field	0	En
+EndSysreg
+
 Sysreg	CONTEXTIDR_EL2	3	4	13	0	1
 Fields	CONTEXTIDR_ELx
 EndSysreg
diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
index da5250f0155cf..7a5cc26529f82 100644
--- a/drivers/irqchip/irq-apple-aic.c
+++ b/drivers/irqchip/irq-apple-aic.c
@@ -409,15 +409,15 @@ static void __exception_irq_entry aic_handle_irq(struct pt_regs *regs)
 	 * in use, and be cleared when coming back from the handler.
 	 */
 	if (is_kernel_in_hyp_mode() &&
-	    (read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EN) &&
+	    (read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EL2_En) &&
 	    read_sysreg_s(SYS_ICH_MISR_EL2) != 0) {
 		generic_handle_domain_irq(aic_irqc->hw_domain,
 					  AIC_FIQ_HWIRQ(AIC_VGIC_MI));
 
-		if (unlikely((read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EN) &&
+		if (unlikely((read_sysreg_s(SYS_ICH_HCR_EL2) & ICH_HCR_EL2_En) &&
 			     read_sysreg_s(SYS_ICH_MISR_EL2))) {
 			pr_err_ratelimited("vGIC IRQ fired and not handled by KVM, disabling.\n");
-			sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EN, 0);
+			sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EL2_En, 0);
 		}
 	}
 }
@@ -840,7 +840,7 @@ static int aic_init_cpu(unsigned int cpu)
 				   VM_TMR_FIQ_ENABLE_V | VM_TMR_FIQ_ENABLE_P, 0);
 
 		/* vGIC maintenance IRQ */
-		sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EN, 0);
+		sysreg_clear_set_s(SYS_ICH_HCR_EL2, ICH_HCR_EL2_En, 0);
 	}
 
 	/* PMC FIQ */
diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index cd8420e8c3ad8..d314ccab7560a 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -420,7 +420,6 @@
 
 #define SYS_ICH_VSEIR_EL2		sys_reg(3, 4, 12, 9, 4)
 #define SYS_ICC_SRE_EL2			sys_reg(3, 4, 12, 9, 5)
-#define SYS_ICH_HCR_EL2			sys_reg(3, 4, 12, 11, 0)
 #define SYS_ICH_VTR_EL2			sys_reg(3, 4, 12, 11, 1)
 #define SYS_ICH_MISR_EL2		sys_reg(3, 4, 12, 11, 2)
 #define SYS_ICH_EISR_EL2		sys_reg(3, 4, 12, 11, 3)
@@ -654,17 +653,6 @@
 #define ICH_LR_PRIORITY_SHIFT	48
 #define ICH_LR_PRIORITY_MASK	(0xffULL << ICH_LR_PRIORITY_SHIFT)
 
-/* ICH_HCR_EL2 bit definitions */
-#define ICH_HCR_EN		(1 << 0)
-#define ICH_HCR_UIE		(1 << 1)
-#define ICH_HCR_NPIE		(1 << 3)
-#define ICH_HCR_TC		(1 << 10)
-#define ICH_HCR_TALL0		(1 << 11)
-#define ICH_HCR_TALL1		(1 << 12)
-#define ICH_HCR_TDIR		(1 << 14)
-#define ICH_HCR_EOIcount_SHIFT	27
-#define ICH_HCR_EOIcount_MASK	(0x1f << ICH_HCR_EOIcount_SHIFT)
-
 /* ICH_VMCR_EL2 bit definitions */
 #define ICH_VMCR_ACK_CTL_SHIFT	2
 #define ICH_VMCR_ACK_CTL_MASK	(1 << ICH_VMCR_ACK_CTL_SHIFT)
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:18 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:18 +0000
Subject: [PATCH 03/16] arm64: sysreg: Add layout for ICH_MISR_EL2
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-4-maz@kernel.org>

The ICH_MISR_EL2-related macros are missing a number of status
bits that we are about to handle. Take this opportunity to fully
describe the layout of that register as part of the automatic
generation infrastructure.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/sysreg.h       |  5 -----
 arch/arm64/tools/sysreg               | 12 ++++++++++++
 tools/arch/arm64/include/asm/sysreg.h |  5 -----
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index cf74ebcd46d95..815e9b0bdff27 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -561,7 +561,6 @@
 
 #define SYS_ICH_VSEIR_EL2		sys_reg(3, 4, 12, 9, 4)
 #define SYS_ICC_SRE_EL2			sys_reg(3, 4, 12, 9, 5)
-#define SYS_ICH_MISR_EL2		sys_reg(3, 4, 12, 11, 2)
 #define SYS_ICH_EISR_EL2		sys_reg(3, 4, 12, 11, 3)
 #define SYS_ICH_ELRSR_EL2		sys_reg(3, 4, 12, 11, 5)
 #define SYS_ICH_VMCR_EL2		sys_reg(3, 4, 12, 11, 7)
@@ -991,10 +990,6 @@
 #define TRFCR_ELx_E0TRE			BIT(0)
 
 /* GIC Hypervisor interface registers */
-/* ICH_MISR_EL2 bit definitions */
-#define ICH_MISR_EOI		(1 << 0)
-#define ICH_MISR_U		(1 << 1)
-
 /* ICH_LR*_EL2 bit definitions */
 #define ICH_LR_VIRTUAL_ID_MASK	((1ULL << 32) - 1)
 
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index f5927d345eea3..a601231a088d7 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2974,6 +2974,18 @@ Res0	17:5
 Field	4:0	ListRegs
 EndSysreg
 
+Sysreg	ICH_MISR_EL2	3	4	12	11	2
+Res0	63:8
+Field	7	VGrp1D
+Field	6	VGrp1E
+Field	5	VGrp0D
+Field	4	VGrp0E
+Field	3	NP
+Field	2	LRENP
+Field	1	U
+Field	0	EOI
+EndSysreg
+
 Sysreg	CONTEXTIDR_EL2	3	4	13	0	1
 Fields	CONTEXTIDR_ELx
 EndSysreg
diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index f43e303d31d25..0169bd3137caf 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -420,7 +420,6 @@
 
 #define SYS_ICH_VSEIR_EL2		sys_reg(3, 4, 12, 9, 4)
 #define SYS_ICC_SRE_EL2			sys_reg(3, 4, 12, 9, 5)
-#define SYS_ICH_MISR_EL2		sys_reg(3, 4, 12, 11, 2)
 #define SYS_ICH_EISR_EL2		sys_reg(3, 4, 12, 11, 3)
 #define SYS_ICH_ELRSR_EL2		sys_reg(3, 4, 12, 11, 5)
 #define SYS_ICH_VMCR_EL2		sys_reg(3, 4, 12, 11, 7)
@@ -634,10 +633,6 @@
 #define TRFCR_ELx_E0TRE			BIT(0)
 
 /* GIC Hypervisor interface registers */
-/* ICH_MISR_EL2 bit definitions */
-#define ICH_MISR_EOI		(1 << 0)
-#define ICH_MISR_U		(1 << 1)
-
 /* ICH_LR*_EL2 bit definitions */
 #define ICH_LR_VIRTUAL_ID_MASK	((1ULL << 32) - 1)
 
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:15 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:15 +0000
Subject: [PATCH 00/16] KVM: arm64: Add NV GICv3 support
Message-ID: <20241217151331.934077-1-maz@kernel.org>

As a pendant to the timer code, here's the basic support for GICv3 for
NV.

Compared to the versions that have existed in the past, this is a
significant improvement, as the maintenance interrupt is finally
behaving correctly, and I have dropped the horrible hacks that only
gave the impression something was working.

The code is much simpler, isolated, and can even make some sense if
you have the correct pink-ish glasses.

As for the timer code, this has been tested as part of my integration
branch [1].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/nv-next

Andre Przywara (1):
  KVM: arm64: nv: Allow userland to set VGIC maintenance IRQ

Jintack Lim (1):
  KVM: arm64: nv: Respect virtual HCR_EL2.TWx setting

Marc Zyngier (12):
  arm64: sysreg: Add layout for ICH_HCR_EL2
  arm64: sysreg: Add layout for ICH_VTR_EL2
  arm64: sysreg: Add layout for ICH_MISR_EL2
  KVM: arm64: nv: Load timer before the GIC
  KVM: arm64: nv: Add ICH_*_EL2 registers to vpcu_sysreg
  KVM: arm64: nv: Plumb handling of GICv3 EL2 accesses
  KVM: arm64: nv: Sanitise ICH_HCR_EL2 accesses
  KVM: arm64: nv: Nested GICv3 emulation
  KVM: arm64: nv: Handle L2->L1 transition on interrupt injection
  KVM: arm64: nv: Add Maintenance Interrupt emulation
  KVM: arm64: nv: Propagate used_lrs between L1 and L0 contexts
  KVM: arm64: nv: Fold GICv3 host trapping requirements into guest setup

Oliver Upton (2):
  KVM: arm64: Move host SVE/SME state flags out of vCPU
  KVM: arm64: nv: Request vPE doorbell upon nested ERET to L2

 .../virt/kvm/devices/arm-vgic-v3.rst          |  12 +-
 arch/arm64/include/asm/kvm_emulate.h          |  13 +
 arch/arm64/include/asm/kvm_host.h             |  71 ++-
 arch/arm64/include/asm/kvm_hyp.h              |   2 +
 arch/arm64/include/asm/sysreg.h               |  30 --
 arch/arm64/include/uapi/asm/kvm.h             |   1 +
 arch/arm64/kvm/Makefile                       |   2 +-
 arch/arm64/kvm/arm.c                          |  13 +-
 arch/arm64/kvm/emulate-nested.c               |  18 +-
 arch/arm64/kvm/fpsimd.c                       |  12 +-
 arch/arm64/kvm/handle_exit.c                  |   6 +-
 arch/arm64/kvm/hyp/vgic-v3-sr.c               |  16 +-
 arch/arm64/kvm/nested.c                       |  12 +
 arch/arm64/kvm/sys_regs.c                     |  95 +++-
 arch/arm64/kvm/vgic-sys-reg-v3.c              |   8 +-
 arch/arm64/kvm/vgic/vgic-init.c               |  22 +
 arch/arm64/kvm/vgic/vgic-kvm-device.c         |  29 +-
 arch/arm64/kvm/vgic/vgic-v3-nested.c          | 409 ++++++++++++++++++
 arch/arm64/kvm/vgic/vgic-v3.c                 |  44 +-
 arch/arm64/kvm/vgic/vgic-v4.c                 |  18 +-
 arch/arm64/kvm/vgic/vgic.c                    |  38 ++
 arch/arm64/kvm/vgic/vgic.h                    |   6 +
 arch/arm64/tools/sysreg                       |  48 ++
 drivers/irqchip/irq-apple-aic.c               |   8 +-
 include/kvm/arm_vgic.h                        |  10 +
 tools/arch/arm/include/uapi/asm/kvm.h         |   1 +
 tools/arch/arm64/include/asm/sysreg.h         |  30 --
 27 files changed, 841 insertions(+), 133 deletions(-)
 create mode 100644 arch/arm64/kvm/vgic/vgic-v3-nested.c

-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:19 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:19 +0000
Subject: [PATCH 04/16] KVM: arm64: Move host SVE/SME state flags out of vCPU
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-5-maz@kernel.org>

From: Oliver Upton <oliver.upton at linux.dev>

We're running a bit tight on vCPU state flags, and there's no good
reason for tracking bits of host state in the vCPU. Rather than do the
unspeakable and add another byte of sflags, move some of the obvious
host bits over to kvm_host_data where they really belong.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
Link: https://lore.kernel.org/r/20240823212703.3576061-3-oliver.upton at linux.dev
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 26 ++++++++++++++++----------
 arch/arm64/kvm/fpsimd.c           | 12 ++++++------
 2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e18e9244d17a4..8cc25845b4be3 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -610,6 +610,12 @@ struct cpu_sve_state {
  * field.
  */
 struct kvm_host_data {
+	/* SVE enabled for EL0 */
+#define HOST_SVE_ENABLED	0
+	/* SME enabled for EL0 */
+#define HOST_SME_ENABLED	1
+	unsigned long flags;
+
 	struct kvm_cpu_context host_ctxt;
 
 	/*
@@ -913,22 +919,18 @@ struct kvm_vcpu_arch {
 /* Save TRBE context if active  */
 #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
 
-/* SVE enabled for host EL0 */
-#define HOST_SVE_ENABLED	__vcpu_single_flag(sflags, BIT(0))
-/* SME enabled for EL0 */
-#define HOST_SME_ENABLED	__vcpu_single_flag(sflags, BIT(1))
 /* Physical CPU not in supported_cpus */
-#define ON_UNSUPPORTED_CPU	__vcpu_single_flag(sflags, BIT(2))
+#define ON_UNSUPPORTED_CPU	__vcpu_single_flag(sflags, BIT(0))
 /* WFIT instruction trapped */
-#define IN_WFIT			__vcpu_single_flag(sflags, BIT(3))
+#define IN_WFIT			__vcpu_single_flag(sflags, BIT(1))
 /* vcpu system registers loaded on physical CPU */
-#define SYSREGS_ON_CPU		__vcpu_single_flag(sflags, BIT(4))
+#define SYSREGS_ON_CPU		__vcpu_single_flag(sflags, BIT(2))
 /* Software step state is Active-pending */
-#define DBG_SS_ACTIVE_PENDING	__vcpu_single_flag(sflags, BIT(5))
+#define DBG_SS_ACTIVE_PENDING	__vcpu_single_flag(sflags, BIT(3))
 /* PMUSERENR for the guest EL0 is on physical CPU */
-#define PMUSERENR_ON_CPU	__vcpu_single_flag(sflags, BIT(6))
+#define PMUSERENR_ON_CPU	__vcpu_single_flag(sflags, BIT(4))
 /* WFI instruction trapped */
-#define IN_WFI			__vcpu_single_flag(sflags, BIT(7))
+#define IN_WFI			__vcpu_single_flag(sflags, BIT(5))
 
 
 /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
@@ -1307,6 +1309,10 @@ DECLARE_KVM_HYP_PER_CPU(struct kvm_host_data, kvm_host_data);
 	 &this_cpu_ptr_hyp_sym(kvm_host_data)->f)
 #endif
 
+#define host_data_set_flag(nr)		set_bit(nr, host_data_ptr(flags))
+#define host_data_test_flag(nr)		test_bit(nr, host_data_ptr(flags))
+#define host_data_clear_flag(nr)	clear_bit(nr, host_data_ptr(flags))
+
 /* Check whether the FP regs are owned by the guest */
 static inline bool guest_owns_fp_regs(void)
 {
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index ea5484ce1f3ba..0e0f37d1990a3 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -65,14 +65,14 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
 	*host_data_ptr(fpsimd_state) = kern_hyp_va(&current->thread.uw.fpsimd_state);
 	*host_data_ptr(fpmr_ptr) = kern_hyp_va(&current->thread.uw.fpmr);
 
-	vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
+	host_data_clear_flag(HOST_SVE_ENABLED);
 	if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
-		vcpu_set_flag(vcpu, HOST_SVE_ENABLED);
+		host_data_set_flag(HOST_SVE_ENABLED);
 
 	if (system_supports_sme()) {
-		vcpu_clear_flag(vcpu, HOST_SME_ENABLED);
+		host_data_clear_flag(HOST_SME_ENABLED);
 		if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN)
-			vcpu_set_flag(vcpu, HOST_SME_ENABLED);
+			host_data_set_flag(HOST_SME_ENABLED);
 
 		/*
 		 * If PSTATE.SM is enabled then save any pending FP
@@ -168,7 +168,7 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 	 */
 	if (has_vhe() && system_supports_sme()) {
 		/* Also restore EL0 state seen on entry */
-		if (vcpu_get_flag(vcpu, HOST_SME_ENABLED))
+		if (host_data_test_flag(HOST_SME_ENABLED))
 			sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_SMEN);
 		else
 			sysreg_clear_set(CPACR_EL1,
@@ -227,7 +227,7 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 		 * for EL0.  To avoid spurious traps, restore the trap state
 		 * seen by kvm_arch_vcpu_load_fp():
 		 */
-		if (vcpu_get_flag(vcpu, HOST_SVE_ENABLED))
+		if (host_data_test_flag(HOST_SVE_ENABLED))
 			sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_ZEN_EL0EN);
 		else
 			sysreg_clear_set(CPACR_EL1, CPACR_EL1_ZEN_EL0EN, 0);
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:20 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:20 +0000
Subject: [PATCH 05/16] KVM: arm64: nv: Load timer before the GIC
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-6-maz@kernel.org>

In order for vgic_v3_load_nested to be able to observe which timer
interrupts have the HW bit set for the current context, the timers
must have been loaded in the new mode and the right timer mapped
to their corresponding HW IRQs.

At the moment, we load the GIC first, meaning that timer interrupts
injected to an L2 guest will never have the HW bit set (we see the
old configuration).

Swapping the two loads solves this particular problem.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc4..3115c44ed4042 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -596,8 +596,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 	vcpu->cpu = cpu;
 
-	kvm_vgic_load(vcpu);
 	kvm_timer_vcpu_load(vcpu);
+	kvm_vgic_load(vcpu);
 	if (has_vhe())
 		kvm_vcpu_load_vhe(vcpu);
 	kvm_arch_vcpu_load_fp(vcpu);
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:21 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:21 +0000
Subject: [PATCH 06/16] KVM: arm64: nv: Add ICH_*_EL2 registers to vpcu_sysreg
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-7-maz@kernel.org>

FEAT_NV2 comes with a bunch of register-to-memory redirection
involving the ICH_*_EL2 registers (LRs, APRs, VMCR, HCR).

Adds them to the vcpu_sysreg enumeration.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 8cc25845b4be3..218047cd0296d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -554,7 +554,33 @@ enum vcpu_sysreg {
 	VNCR(CNTP_CVAL_EL0),
 	VNCR(CNTP_CTL_EL0),
 
+	VNCR(ICH_LR0_EL2),
+	VNCR(ICH_LR1_EL2),
+	VNCR(ICH_LR2_EL2),
+	VNCR(ICH_LR3_EL2),
+	VNCR(ICH_LR4_EL2),
+	VNCR(ICH_LR5_EL2),
+	VNCR(ICH_LR6_EL2),
+	VNCR(ICH_LR7_EL2),
+	VNCR(ICH_LR8_EL2),
+	VNCR(ICH_LR9_EL2),
+	VNCR(ICH_LR10_EL2),
+	VNCR(ICH_LR11_EL2),
+	VNCR(ICH_LR12_EL2),
+	VNCR(ICH_LR13_EL2),
+	VNCR(ICH_LR14_EL2),
+	VNCR(ICH_LR15_EL2),
+
+	VNCR(ICH_AP0R0_EL2),
+	VNCR(ICH_AP0R1_EL2),
+	VNCR(ICH_AP0R2_EL2),
+	VNCR(ICH_AP0R3_EL2),
+	VNCR(ICH_AP1R0_EL2),
+	VNCR(ICH_AP1R1_EL2),
+	VNCR(ICH_AP1R2_EL2),
+	VNCR(ICH_AP1R3_EL2),
 	VNCR(ICH_HCR_EL2),
+	VNCR(ICH_VMCR_EL2),
 
 	NR_SYS_REGS	/* Nothing after this line! */
 };
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:22 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:22 +0000
Subject: [PATCH 07/16] KVM: arm64: nv: Plumb handling of GICv3 EL2 accesses
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-8-maz@kernel.org>

Wire the handling of all GICv3 EL2 registers, and provide emulation
for all the non memory-backed registers (ICC_SRE_EL2, ICH_VTR_EL2,
ICH_MISR_EL2, ICH_ELRSR_EL2, and ICH_EISR_EL2).

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/Makefile              |   2 +-
 arch/arm64/kvm/sys_regs.c            |  95 +++++++++++++++++++-
 arch/arm64/kvm/vgic/vgic-v3-nested.c | 125 +++++++++++++++++++++++++++
 include/kvm/arm_vgic.h               |   4 +
 4 files changed, 224 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/kvm/vgic/vgic-v3-nested.c

diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 3cf7adb2b5038..209bc76263f10 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -23,7 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-v3.o vgic/vgic-v4.o \
 	 vgic/vgic-mmio.o vgic/vgic-mmio-v2.o \
 	 vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
-	 vgic/vgic-its.o vgic/vgic-debug.o
+	 vgic/vgic-its.o vgic/vgic-debug.o vgic/vgic-v3-nested.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
 kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 83c6b4a07ef56..c6d09c25b2522 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/printk.h>
 #include <linux/uaccess.h>
+#include <linux/irqchip/arm-gic-v3.h>
 
 #include <asm/arm_pmuv3.h>
 #include <asm/cacheflush.h>
@@ -531,7 +532,13 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu,
 	if (p->is_write)
 		return ignore_write(vcpu, p);
 
-	p->regval = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
+	if (p->Op1 == 4) {	/* ICC_SRE_EL2 */
+		p->regval = (ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE |
+			     ICC_SRE_EL1_DIB | ICC_SRE_EL1_DFB);
+	} else {		/* ICC_SRE_EL1 */
+		p->regval = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
+	}
+
 	return true;
 }
 
@@ -2402,6 +2409,59 @@ static bool access_zcr_el2(struct kvm_vcpu *vcpu,
 	vq = SYS_FIELD_GET(ZCR_ELx, LEN, p->regval) + 1;
 	vq = min(vq, vcpu_sve_max_vq(vcpu));
 	vcpu_write_sys_reg(vcpu, vq - 1, ZCR_EL2);
+
+	return true;
+}
+
+static bool access_gic_vtr(struct kvm_vcpu *vcpu,
+			   struct sys_reg_params *p,
+			   const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	p->regval = kvm_vgic_global_state.ich_vtr_el2;
+	p->regval &= ~(ICH_VTR_EL2_DVIM 	|
+		       ICH_VTR_EL2_A3V		|
+		       ICH_VTR_EL2_IDbits);
+	p->regval |= ICH_VTR_EL2_nV4;
+
+	return true;
+}
+
+static bool access_gic_misr(struct kvm_vcpu *vcpu,
+			    struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	p->regval = vgic_v3_get_misr(vcpu);
+
+	return true;
+}
+
+static bool access_gic_eisr(struct kvm_vcpu *vcpu,
+			    struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	p->regval = vgic_v3_get_eisr(vcpu);
+
+	return true;
+}
+
+static bool access_gic_elrsr(struct kvm_vcpu *vcpu,
+			     struct sys_reg_params *p,
+			     const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	p->regval = vgic_v3_get_elrsr(vcpu);
+
 	return true;
 }
 
@@ -3050,7 +3110,40 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(RVBAR_EL2, access_rw, reset_val, 0),
 	{ SYS_DESC(SYS_RMR_EL2), undef_access },
 
+	EL2_REG_VNCR(ICH_AP0R0_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_AP0R1_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_AP0R2_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_AP0R3_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_AP1R0_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_AP1R1_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_AP1R2_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_AP1R3_EL2, reset_val, 0),
+
+	{ SYS_DESC(SYS_ICC_SRE_EL2), access_gic_sre },
+
 	EL2_REG_VNCR(ICH_HCR_EL2, reset_val, 0),
+	{ SYS_DESC(SYS_ICH_VTR_EL2), access_gic_vtr },
+	{ SYS_DESC(SYS_ICH_MISR_EL2), access_gic_misr },
+	{ SYS_DESC(SYS_ICH_EISR_EL2), access_gic_eisr },
+	{ SYS_DESC(SYS_ICH_ELRSR_EL2), access_gic_elrsr },
+	EL2_REG_VNCR(ICH_VMCR_EL2, reset_val, 0),
+
+	EL2_REG_VNCR(ICH_LR0_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR1_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR2_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR3_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR4_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR5_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR6_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR7_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR8_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR9_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR10_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR11_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR12_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR13_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR14_EL2, reset_val, 0),
+	EL2_REG_VNCR(ICH_LR15_EL2, reset_val, 0),
 
 	EL2_REG(CONTEXTIDR_EL2, access_rw, reset_val, 0),
 	EL2_REG(TPIDR_EL2, access_rw, reset_val, 0),
diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
new file mode 100644
index 0000000000000..48bfd2f556a36
--- /dev/null
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/cpu.h>
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <kvm/arm_vgic.h>
+
+#include <asm/kvm_arm.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_nested.h>
+
+#include "vgic.h"
+
+#define ICH_LRN(n)	(ICH_LR0_EL2 + (n))
+
+struct mi_state {
+	u16	eisr;
+	u16	elrsr;
+	bool	pend;
+};
+
+/*
+ * Nesting GICv3 support
+ *
+ * System register emulation:
+ *
+ * We get two classes of registers:
+ *
+ * - those backed by memory (LRs, APRs, HCR, VMCR): L1 can freely access
+ *   them, and L0 doesn't see a thing.
+ *
+ * - those that always trap (ELRSR, EISR, MISR): these are status registers
+ *   that are built on the fly based on the in-memory state.
+ *
+ * Only L1 can access the ICH_*_EL2 registers. A non-NV L2 obviously cannot,
+ * and a NV L2 would either access the VNCR page provided by L1 (memory
+ * based registers), or see the access redirected to L1 (registers that
+ * trap) thanks to NV being set by L1.
+ */
+
+static bool lr_triggers_eoi(u64 lr)
+{
+	return !(lr & (ICH_LR_STATE | ICH_LR_HW)) && (lr & ICH_LR_EOI);
+}
+
+static void vgic_compute_mi_state(struct kvm_vcpu *vcpu, struct mi_state *mi_state)
+{
+	u16 eisr = 0, elrsr = 0;
+	bool pend = false;
+
+	for (int i = 0; i < kvm_vgic_global_state.nr_lr; i++) {
+		u64 lr = __vcpu_sys_reg(vcpu, ICH_LRN(i));
+
+		if (lr_triggers_eoi(lr))
+			eisr |= BIT(i);
+		if (!(lr & ICH_LR_STATE))
+			elrsr |= BIT(i);
+		pend |= (lr & ICH_LR_PENDING_BIT);
+	}
+
+	mi_state->eisr	= eisr;
+	mi_state->elrsr	= elrsr;
+	mi_state->pend	= pend;
+}
+
+u16 vgic_v3_get_eisr(struct kvm_vcpu *vcpu)
+{
+	struct mi_state mi_state;
+
+	vgic_compute_mi_state(vcpu, &mi_state);
+	return mi_state.eisr;
+}
+
+u16 vgic_v3_get_elrsr(struct kvm_vcpu *vcpu)
+{
+	struct mi_state mi_state;
+
+	vgic_compute_mi_state(vcpu, &mi_state);
+	return mi_state.elrsr;
+}
+
+u64 vgic_v3_get_misr(struct kvm_vcpu *vcpu)
+{
+	struct mi_state mi_state;
+	u64 reg = 0, hcr, vmcr;
+
+	hcr = __vcpu_sys_reg(vcpu, ICH_HCR_EL2);
+	vmcr = __vcpu_sys_reg(vcpu, ICH_VMCR_EL2);
+
+	vgic_compute_mi_state(vcpu, &mi_state);
+
+	if (mi_state.eisr)
+		reg |= ICH_MISR_EL2_EOI;
+
+	if (__vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_UIE) {
+		int used_lrs = kvm_vgic_global_state.nr_lr;
+
+		used_lrs -= hweight16(mi_state.elrsr);
+		reg |= (used_lrs <= 1) ? ICH_MISR_EL2_U : 0;
+	}
+
+	if ((hcr & ICH_HCR_EL2_LRENPIE) && FIELD_GET(ICH_HCR_EL2_EOIcount_MASK, hcr))
+		reg |= ICH_MISR_EL2_LRENP;
+
+	if ((hcr & ICH_HCR_EL2_NPIE) && !mi_state.pend)
+		reg |= ICH_MISR_EL2_NP;
+
+	if ((hcr & ICH_HCR_EL2_VGrp0EIE) && (vmcr & ICH_VMCR_ENG0_MASK))
+		reg |= ICH_MISR_EL2_VGrp0E;
+
+	if ((hcr & ICH_HCR_EL2_VGrp0DIE) && !(vmcr & ICH_VMCR_ENG0_MASK))
+		reg |= ICH_MISR_EL2_VGrp0D;
+
+	if ((hcr & ICH_HCR_EL2_VGrp1EIE) && (vmcr & ICH_VMCR_ENG1_MASK))
+		reg |= ICH_MISR_EL2_VGrp1E;
+
+	if ((hcr & ICH_HCR_EL2_VGrp1DIE) && !(vmcr & ICH_VMCR_ENG1_MASK))
+		reg |= ICH_MISR_EL2_VGrp1D;
+
+	return reg;
+}
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 3a8ccfda34d29..5017fcc71e604 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -389,6 +389,10 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
 void kvm_vgic_load(struct kvm_vcpu *vcpu);
 void kvm_vgic_put(struct kvm_vcpu *vcpu);
 
+u16 vgic_v3_get_eisr(struct kvm_vcpu *vcpu);
+u16 vgic_v3_get_elrsr(struct kvm_vcpu *vcpu);
+u64 vgic_v3_get_misr(struct kvm_vcpu *vcpu);
+
 #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)	((k)->arch.vgic.initialized)
 #define vgic_ready(k)		((k)->arch.vgic.ready)
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:23 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:23 +0000
Subject: [PATCH 08/16] KVM: arm64: nv: Sanitise ICH_HCR_EL2 accesses
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-9-maz@kernel.org>

As ICH_HCR_EL2 is a VNCR accessor when runnintg NV, add some
sanitising to what gets written. Crucially, mark TDIR as RES0
if the HW doesn't support it (unlikely, but hey...), as well
as anything GICv4 related, since we only expose a GICv3 to the
uest.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/nested.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 9b36218b48def..37f7ef2f44bd8 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1271,6 +1271,15 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		res0 |= MDCR_EL2_EnSTEPOP;
 	set_sysreg_masks(kvm, MDCR_EL2, res0, res1);
 
+	/* ICH_HCR_EL2 */
+	res0 = ICH_HCR_EL2_RES0;
+	res1 = ICH_HCR_EL2_RES1;
+	if (!(kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_EL2_TDS))
+		res0 |= ICH_HCR_EL2_TDIR;
+	/* No GICv4 is presented to the guest */
+	res0 |= ICH_HCR_EL2_DVIM | ICH_HCR_EL2_vSGIEOICount;
+	set_sysreg_masks(kvm, ICH_HCR_EL2, res0, res1);
+
 	return 0;
 }
 
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:25 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:25 +0000
Subject: [PATCH 10/16] KVM: arm64: nv: Handle L2->L1 transition on interrupt injection
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-11-maz@kernel.org>

An interrupt being delivered to L1 while running L2 must result
in the correct exception being delivered to L1.

This means that if, on entry to L2, we found ourselves with pending
interrupts in the L1 distributor, we need to take immediate action.
This is done by posting a request which will prevent the entry in
L2, and deliver an IRQ exception to L1, forcing the switch.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 17 +++++++++--------
 arch/arm64/kvm/arm.c              |  5 +++++
 arch/arm64/kvm/nested.c           |  3 +++
 arch/arm64/kvm/vgic/vgic.c        | 23 +++++++++++++++++++++++
 4 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 218047cd0296d..cb969c096d7bd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -44,14 +44,15 @@
 
 #define KVM_REQ_SLEEP \
 	KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
-#define KVM_REQ_IRQ_PENDING	KVM_ARCH_REQ(1)
-#define KVM_REQ_VCPU_RESET	KVM_ARCH_REQ(2)
-#define KVM_REQ_RECORD_STEAL	KVM_ARCH_REQ(3)
-#define KVM_REQ_RELOAD_GICv4	KVM_ARCH_REQ(4)
-#define KVM_REQ_RELOAD_PMU	KVM_ARCH_REQ(5)
-#define KVM_REQ_SUSPEND		KVM_ARCH_REQ(6)
-#define KVM_REQ_RESYNC_PMU_EL0	KVM_ARCH_REQ(7)
-#define KVM_REQ_NESTED_S2_UNMAP	KVM_ARCH_REQ(8)
+#define KVM_REQ_IRQ_PENDING		KVM_ARCH_REQ(1)
+#define KVM_REQ_VCPU_RESET		KVM_ARCH_REQ(2)
+#define KVM_REQ_RECORD_STEAL		KVM_ARCH_REQ(3)
+#define KVM_REQ_RELOAD_GICv4		KVM_ARCH_REQ(4)
+#define KVM_REQ_RELOAD_PMU		KVM_ARCH_REQ(5)
+#define KVM_REQ_SUSPEND			KVM_ARCH_REQ(6)
+#define KVM_REQ_RESYNC_PMU_EL0		KVM_ARCH_REQ(7)
+#define KVM_REQ_NESTED_S2_UNMAP		KVM_ARCH_REQ(8)
+#define KVM_REQ_GUEST_HYP_IRQ_PENDING	KVM_ARCH_REQ(9)
 
 #define KVM_DIRTY_LOG_MANUAL_CAPS   (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
 				     KVM_DIRTY_LOG_INITIALLY_SET)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 3115c44ed4042..5e353b2c225b4 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1153,6 +1153,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		 * preserved on VMID roll-over if the task was preempted,
 		 * making a thread's VMID inactive. So we need to call
 		 * kvm_arm_vmid_update() in non-premptible context.
+		 *
+		 * Note that this must happen after the check_vcpu_request()
+		 * call to pick the correct s2_mmu structure, as a pending
+		 * nested exception (IRQ, for example) can trigger a change
+		 * in translation regime.
 		 */
 		if (kvm_arm_vmid_update(&vcpu->arch.hw_mmu->vmid) &&
 		    has_vhe())
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 37f7ef2f44bd8..2b511d30939b3 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1295,4 +1295,7 @@ void check_nested_vcpu_requests(struct kvm_vcpu *vcpu)
 		}
 		write_unlock(&vcpu->kvm->mmu_lock);
 	}
+
+	if (kvm_check_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu))
+		kvm_inject_nested_irq(vcpu);
 }
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 324c547e1b4d8..9734a71b85611 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -906,6 +906,29 @@ static inline void vgic_restore_state(struct kvm_vcpu *vcpu)
 /* Flush our emulation state into the GIC hardware before entering the guest. */
 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
 {
+	/*
+	 * If in a nested state, we must return early. Two possibilities:
+	 *
+	 * - If we have any pending IRQ for the guest and the guest
+	 *   expects IRQs to be handled in its virtual EL2 mode (the
+	 *   virtual IMO bit is set) and it is not already running in
+	 *   virtual EL2 mode, then we have to emulate an IRQ
+	 *   exception to virtual EL2.
+	 *
+	 *   We do that by placing a request to ourselves which will
+	 *   abort the entry procedure and inject the exception at the
+	 *   beginning of the run loop.
+	 *
+	 * - Otherwise, do exactly *NOTHING*. The guest state is
+	 *   already loaded, and we can carry on with running it.
+	 */
+	if (vgic_state_is_nested(vcpu)) {
+		if (kvm_vgic_vcpu_pending_irq(vcpu))
+			kvm_make_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu);
+
+		return;
+	}
+
 	/*
 	 * If there are no virtual interrupts active or pending for this
 	 * VCPU, then there is no work to do and we can bail out without
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:24 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:24 +0000
Subject: [PATCH 09/16] KVM: arm64: nv: Nested GICv3 emulation
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-10-maz@kernel.org>

When entering a nested VM, we set up the hypervisor control interface
based on what the guest hypervisor has set. Especially, we investigate
each list register written by the guest hypervisor whether HW bit is
set.  If so, we translate hw irq number from the guest's point of view
to the real hardware irq number if there is a mapping.

Co-developed-by: Jintack Lim <jintack at cs.columbia.edu>
Signed-off-by: Jintack Lim <jintack at cs.columbia.edu>
[Christoffer: Redesigned execution flow around vcpu load/put]
Co-developed-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
[maz: Rewritten to support GICv3 instead of GICv2, NV2 support]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_hyp.h     |   2 +
 arch/arm64/kvm/hyp/vgic-v3-sr.c      |   2 +-
 arch/arm64/kvm/vgic/vgic-v3-nested.c | 218 +++++++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic-v3.c        |  11 ++
 arch/arm64/kvm/vgic/vgic.c           |   6 +
 arch/arm64/kvm/vgic/vgic.h           |   4 +
 include/kvm/arm_vgic.h               |   2 +
 7 files changed, 244 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index c838309e4ec47..e6be1f5d0967f 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -76,6 +76,8 @@ DECLARE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
 
 int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
 
+u64 __gic_v3_get_lr(unsigned int lr);
+
 void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if);
 void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if);
 void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if);
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
index b47dede973b3c..ed363aa3027e5 100644
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -18,7 +18,7 @@
 #define vtr_to_nr_pre_bits(v)		((((u32)(v) >> 26) & 7) + 1)
 #define vtr_to_nr_apr_regs(v)		(1 << (vtr_to_nr_pre_bits(v) - 5))
 
-static u64 __gic_v3_get_lr(unsigned int lr)
+u64 __gic_v3_get_lr(unsigned int lr)
 {
 	switch (lr & 0xf) {
 	case 0:
diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
index 48bfd2f556a36..3d80bfb37de00 100644
--- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -16,6 +16,8 @@
 #include "vgic.h"
 
 #define ICH_LRN(n)	(ICH_LR0_EL2 + (n))
+#define ICH_AP0RN(n)	(ICH_AP0R0_EL2 + (n))
+#define ICH_AP1RN(n)	(ICH_AP1R0_EL2 + (n))
 
 struct mi_state {
 	u16	eisr;
@@ -23,9 +25,54 @@ struct mi_state {
 	bool	pend;
 };
 
+/*
+ * The shadow registers loaded to the hardware when running a L2 guest
+ * with the virtual IMO/FMO bits set.
+ */
+struct shadow_if {
+	struct vgic_v3_cpu_if	cpuif;
+	unsigned long		lr_map;
+};
+
+static DEFINE_PER_CPU(struct shadow_if, shadow_if);
+
 /*
  * Nesting GICv3 support
  *
+ * On a non-nesting VM (only running at EL0/EL1), the host hypervisor
+ * completely controls the interrupts injected via the list registers.
+ * Consequently, most of the state that is modified by the guest (by ACK-ing
+ * and EOI-ing interrupts) is synced by KVM on each entry/exit, so that we
+ * keep a semi-consistent view of the interrupts.
+ *
+ * This still applies for a NV guest, but only while "InHost" (either
+ * running at EL2, or at EL0 with HCR_EL2.{E2H.TGE}=={1,1}.
+ *
+ * When running a L2 guest ("not InHost"), things are radically different,
+ * as the L1 guest is in charge of provisioning the interrupts via its own
+ * view of the ICH_LR*_EL2 registers, which conveniently live in the VNCR
+ * page.  This means that the flow described above does work (there is no
+ * state to rebuild in the L0 hypervisor), and that most things happed on L2
+ * load/put:
+ *
+ * - on L2 load: move the in-memory L1 vGIC configuration into a shadow,
+ *   per-CPU data structure that is used to populate the actual LRs. This is
+ *   an extra copy that we could avoid, but life is short. In the process,
+ *   we remap any interrupt that has the HW bit set to the mapped interrupt
+ *   on the host, should the host consider it a HW one. This allows the HW
+ *   deactivation to take its course, such as for the timer.
+ *
+ * - on L2 put: perform the inverse transformation, so that the result of L2
+ *   running becomes visible to L1 in the VNCR-accessible registers.
+ *
+ * - there is nothing to do on L2 entry, as everything will have happenned
+ *   on load. However, this is the point where we detect that an interrupt
+ *   targeting L1 and prepare the grand switcheroo.
+ *
+ * - on L2 exit: emulate the HW bit, and deactivate corresponding the L1
+ *   interrupt. The L0 active state will be cleared by the HW if the L1
+ *   interrupt was itself backed by a HW interrupt.
+ *
  * System register emulation:
  *
  * We get two classes of registers:
@@ -42,6 +89,26 @@ struct mi_state {
  * trap) thanks to NV being set by L1.
  */
 
+bool vgic_state_is_nested(struct kvm_vcpu *vcpu)
+{
+	u64 xmo;
+
+	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
+		xmo = __vcpu_sys_reg(vcpu, HCR_EL2) & (HCR_IMO | HCR_FMO);
+		WARN_ONCE(xmo && xmo != (HCR_IMO | HCR_FMO),
+			  "Separate virtual IRQ/FIQ settings not supported\n");
+
+		return !!xmo;
+	}
+
+	return false;
+}
+
+static struct shadow_if *get_shadow_if(void)
+{
+	return this_cpu_ptr(&shadow_if);
+}
+
 static bool lr_triggers_eoi(u64 lr)
 {
 	return !(lr & (ICH_LR_STATE | ICH_LR_HW)) && (lr & ICH_LR_EOI);
@@ -123,3 +190,154 @@ u64 vgic_v3_get_misr(struct kvm_vcpu *vcpu)
 
 	return reg;
 }
+
+/*
+ * For LRs which have HW bit set such as timer interrupts, we modify them to
+ * have the host hardware interrupt number instead of the virtual one programmed
+ * by the guest hypervisor.
+ */
+static void vgic_v3_create_shadow_lr(struct kvm_vcpu *vcpu,
+				     struct vgic_v3_cpu_if *s_cpu_if)
+{
+	unsigned long lr_map = 0;
+	int index = 0;
+
+	for (int i = 0; i < kvm_vgic_global_state.nr_lr; i++) {
+		u64 lr = __vcpu_sys_reg(vcpu, ICH_LRN(i));
+		struct vgic_irq *irq;
+
+		if (!(lr & ICH_LR_STATE))
+			lr = 0;
+
+		if (!(lr & ICH_LR_HW))
+			goto next;
+
+		/* We have the HW bit set, check for validity of pINTID */
+		irq = vgic_get_vcpu_irq(vcpu, FIELD_GET(ICH_LR_PHYS_ID_MASK, lr));
+		if (!irq || !irq->hw || irq->intid > VGIC_MAX_SPI ) {
+			/* There was no real mapping, so nuke the HW bit */
+			lr &= ~ICH_LR_HW;
+			if (irq)
+				vgic_put_irq(vcpu->kvm, irq);
+			goto next;
+		}
+
+		/* It is illegal to have the EOI bit set with HW */
+		lr &= ~ICH_LR_EOI;
+
+		/* Translate the virtual mapping to the real one */
+		lr &= ~ICH_LR_PHYS_ID_MASK;
+		lr |= FIELD_PREP(ICH_LR_PHYS_ID_MASK, (u64)irq->hwintid);
+
+		vgic_put_irq(vcpu->kvm, irq);
+
+next:
+		s_cpu_if->vgic_lr[index] = lr;
+		if (lr) {
+			lr_map |= BIT(i);
+			index++;
+		}
+	}
+
+	container_of(s_cpu_if, struct shadow_if, cpuif)->lr_map = lr_map;
+	s_cpu_if->used_lrs = index;
+}
+
+void vgic_v3_sync_nested(struct kvm_vcpu *vcpu)
+{
+	struct shadow_if *shadow_if = get_shadow_if();
+	int i, index = 0;
+
+	for_each_set_bit(i, &shadow_if->lr_map, kvm_vgic_global_state.nr_lr) {
+		u64 lr = __vcpu_sys_reg(vcpu, ICH_LRN(i));
+		struct vgic_irq *irq;
+
+		if (!(lr & ICH_LR_HW) || !(lr & ICH_LR_STATE))
+			goto next;
+
+		/*
+		 * If we had a HW lr programmed by the guest hypervisor, we
+		 * need to emulate the HW effect between the guest hypervisor
+		 * and the nested guest.
+		 */
+		irq = vgic_get_vcpu_irq(vcpu, FIELD_GET(ICH_LR_PHYS_ID_MASK, lr));
+		if (WARN_ON(!irq)) /* Shouldn't happen as we check on load */
+			goto next;
+
+		lr = __gic_v3_get_lr(index);
+		if (!(lr & ICH_LR_STATE))
+			irq->active = false;
+
+		vgic_put_irq(vcpu->kvm, irq);
+	next:
+		index++;
+	}
+}
+
+static void vgic_v3_create_shadow_state(struct kvm_vcpu *vcpu,
+					struct vgic_v3_cpu_if *s_cpu_if)
+{
+	struct vgic_v3_cpu_if *host_if = &vcpu->arch.vgic_cpu.vgic_v3;
+	int i;
+
+	s_cpu_if->vgic_hcr = __vcpu_sys_reg(vcpu, ICH_HCR_EL2);
+	s_cpu_if->vgic_vmcr = __vcpu_sys_reg(vcpu, ICH_VMCR_EL2);
+	s_cpu_if->vgic_sre = host_if->vgic_sre;
+
+	for (i = 0; i < 4; i++) {
+		s_cpu_if->vgic_ap0r[i] = __vcpu_sys_reg(vcpu, ICH_AP0RN(i));
+		s_cpu_if->vgic_ap1r[i] = __vcpu_sys_reg(vcpu, ICH_AP1RN(i));
+	}
+
+	vgic_v3_create_shadow_lr(vcpu, s_cpu_if);
+}
+
+void vgic_v3_load_nested(struct kvm_vcpu *vcpu)
+{
+	struct shadow_if *shadow_if = get_shadow_if();
+	struct vgic_v3_cpu_if *cpu_if = &shadow_if->cpuif;
+
+	BUG_ON(!vgic_state_is_nested(vcpu));
+
+	vgic_v3_create_shadow_state(vcpu, cpu_if);
+
+	__vgic_v3_restore_vmcr_aprs(cpu_if);
+	__vgic_v3_activate_traps(cpu_if);
+
+	__vgic_v3_restore_state(cpu_if);
+}
+
+void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
+{
+	struct shadow_if *shadow_if = get_shadow_if();
+	struct vgic_v3_cpu_if *s_cpu_if = &shadow_if->cpuif;
+	int i;
+
+	__vgic_v3_save_vmcr_aprs(s_cpu_if);
+	__vgic_v3_deactivate_traps(s_cpu_if);
+	__vgic_v3_save_state(s_cpu_if);
+
+	/*
+	 * Translate the shadow state HW fields back to the virtual ones
+	 * before copying the shadow struct back to the nested one.
+	 */
+	__vcpu_sys_reg(vcpu, ICH_HCR_EL2) = s_cpu_if->vgic_hcr;
+	__vcpu_sys_reg(vcpu, ICH_VMCR_EL2) = s_cpu_if->vgic_vmcr;
+
+	for (i = 0; i < 4; i++) {
+		__vcpu_sys_reg(vcpu, ICH_AP0RN(i)) = s_cpu_if->vgic_ap0r[i];
+		__vcpu_sys_reg(vcpu, ICH_AP1RN(i)) = s_cpu_if->vgic_ap1r[i];
+	}
+
+	for_each_set_bit(i, &shadow_if->lr_map, kvm_vgic_global_state.nr_lr) {
+		u64 val = __vcpu_sys_reg(vcpu, ICH_LRN(i));
+
+		val &= ~ICH_LR_STATE;
+		val |= s_cpu_if->vgic_lr[i] & ICH_LR_STATE;
+
+		__vcpu_sys_reg(vcpu, ICH_LRN(i)) = val;
+		s_cpu_if->vgic_lr[i] = 0;
+	}
+
+	shadow_if->lr_map = 0;
+}
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 0bdecbbe74898..67e89bf708e6d 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -733,6 +733,12 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
+	/* If the vgic is nested, perform the full state loading */
+	if (vgic_state_is_nested(vcpu)) {
+		vgic_v3_load_nested(vcpu);
+		return;
+	}
+
 	kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
 
 	if (has_vhe())
@@ -745,6 +751,11 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
+	if (vgic_state_is_nested(vcpu)) {
+		vgic_v3_put_nested(vcpu);
+		return;
+	}
+
 	kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
 	WARN_ON(vgic_v4_put(vcpu));
 
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index cc8c6b9b5dd8b..324c547e1b4d8 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -872,6 +872,12 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 {
 	int used_lrs;
 
+	/* If nesting, emulate the HW effect from L0 to L1 */
+	if (vgic_state_is_nested(vcpu)) {
+		vgic_v3_sync_nested(vcpu);
+		return;
+	}
+
 	/* An empty ap_list_head implies used_lrs == 0 */
 	if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head))
 		return;
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index 122d95b4e2845..cf0c084e5d347 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -353,4 +353,8 @@ static inline bool kvm_has_gicv3(struct kvm *kvm)
 	return kvm_has_feat(kvm, ID_AA64PFR0_EL1, GIC, IMP);
 }
 
+void vgic_v3_sync_nested(struct kvm_vcpu *vcpu);
+void vgic_v3_load_nested(struct kvm_vcpu *vcpu);
+void vgic_v3_put_nested(struct kvm_vcpu *vcpu);
+
 #endif
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 5017fcc71e604..1b373cb870fe4 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -437,6 +437,8 @@ int vgic_v4_load(struct kvm_vcpu *vcpu);
 void vgic_v4_commit(struct kvm_vcpu *vcpu);
 int vgic_v4_put(struct kvm_vcpu *vcpu);
 
+bool vgic_state_is_nested(struct kvm_vcpu *vcpu);
+
 /* CPU HP callbacks */
 void kvm_vgic_cpu_up(void);
 void kvm_vgic_cpu_down(void);
-- 
2.39.2



From maz at kernel.org  Tue Dec 17 07:13:27 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:13:27 +0000
Subject: [PATCH 12/16] KVM: arm64: nv: Respect virtual HCR_EL2.TWx setting
In-Reply-To: <20241217151331.934077-1-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
Message-ID: <20241217151331.934077-13-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

Forward exceptions due to WFI or WFE instructions to the virtual EL2 if
they are not coming from the virtual EL2 and virtual HCR_EL2.TWx is set.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h | 13 +++++++++++++
 arch/arm64/kvm/handle_exit.c         |  6 +++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index cf811009a33c9..5d2af20f75890 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -281,6 +281,19 @@ static __always_inline u64 kvm_vcpu_get_esr(const struct kvm_vcpu *vcpu)
 	return vcpu->arch.fault.esr_el2;
 }
 
+static inline bool guest_hyp_wfx_traps_enabled(const struct kvm_vcpu *vcpu)
+{
+	u64 esr = kvm_vcpu_get_esr(vcpu);
+	bool is_wfe = !!(esr & ESR_ELx_WFx_ISS_WFE);
+	u64 hcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
+
+	if (!vcpu_has_nv(vcpu) || vcpu_is_el2(vcpu))
+		return false;
+
+	return ((is_wfe && (hcr_el2 & HCR_TWE)) ||
+		(!is_wfe && (hcr_el2 & HCR_TWI)));
+}
+
 static __always_inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
 {
 	u64 esr = kvm_vcpu_get_esr(vcpu);
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index d7c2990e7c9ed..206eb6698db70 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -129,8 +129,12 @@ static int kvm_handle_fpasimd(struct kvm_vcpu *vcpu)
 static int kvm_handle_wfx(struct kvm_vcpu *vcpu)
 {
 	u64 esr = kvm_vcpu_get_esr(vcpu);
+	bool is_wfe = !!(esr & ESR_ELx_WFx_ISS_WFE);
 
-	if (esr & ESR_ELx_WFx_ISS_WFE) {
+	if (guest_hyp_wfx_traps_enabled(vcpu))
+		return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+
+	if (is_wfe) {
 		trace_kvm_wfx_arm64(*vcpu_pc(vcpu), true);
 		vcpu->stat.wfe_exit_stat++;
 	} else {
-- 
2.39.2



From olteanv at gmail.com  Tue Dec 17 07:18:52 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 17 Dec 2024 17:18:52 +0200
Subject: [net-next PATCH v11 5/9] mfd: an8855: Add support for Airoha
 AN8855 Switch MFD
In-Reply-To: <20241217151339.gjpdkfbechdjohza@skbuf>
References: <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-1-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241209134459.27110-6-ansuelsmth@gmail.com>
 <20241210211529.osgzd54flq646bcr@skbuf>
 <6758c174.050a0220.52a35.06bc@mx.google.com>
 <20241210234803.pzm7fxrve4dastth@skbuf>
 <675da041.050a0220.a8e65.af0e@mx.google.com>
 <20241217151339.gjpdkfbechdjohza@skbuf>
Message-ID: <20241217151852.wj2cbrisv6v4sdl6@skbuf>

On Tue, Dec 17, 2024 at 05:13:39PM +0200, Vladimir Oltean wrote:
> On Sat, Dec 14, 2024 at 04:11:54PM +0100, Christian Marangi wrote:
> > We can see that:
> > - as suggested regmap doesn't cause any performance penality. It does
> >   even produce better result.
> > - the read/set/restore implementation gives worse performance.
> > 
> > So I guess I will follow the path of regmap + cache page. What do you
> > think?
> 
> I'm not seeing results with the "times" variable changed, but in
> general, I guess the "switch regmap + page" and "switch regmap + phy
> regmap" will remain neck and neck in terms of performance, surpassing
> the "switch regmap restore" techniques more and more as "times"
> increases. So going with a PHY regmap probably sounds good.

Could you find a way to reuse Maxime's mdio-regmap.c driver? Either
create separate regmaps for each PHY address, or make that driver
accept a configuration which isn't limited to a single ctx->valid_addr?


From broonie at kernel.org  Tue Dec 17 07:30:46 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Dec 2024 15:30:46 +0000
Subject: [PATCH V2 18/46] arm64/sysreg: Add register fields for PMUACR_EL1
In-Reply-To: <20241216231505.GA601635-robh@kernel.org>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-19-anshuman.khandual@arm.com>
 <20241216231505.GA601635-robh@kernel.org>
Message-ID: <a442bca4-d1c0-4f3e-ae13-4836caec2da9@sirena.org.uk>

On Mon, Dec 16, 2024 at 05:15:05PM -0600, Rob Herring wrote:
> On Tue, Dec 10, 2024 at 11:22:43AM +0530, Anshuman Khandual wrote:

> > +Sysreg	PMUACR_EL1	3	0	9	14	4

> I already added this and various other PMUv3.9 registers you've added 
> here in v6.12 and v6.13. So are you on an old base or the tool allows 
> multiple definitions? If the latter, that should be fixed.

The tool is written in awk and hence *really* dumb so it's not going to
notice this, and so long as the resulting definitions are identical the
compiler won't either.  It would indeed be nice if the tooling were able
to detect 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/20241217/9a177537/attachment.sig>

From broonie at kernel.org  Tue Dec 17 07:32:02 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Dec 2024 15:32:02 +0000
Subject: [PATCH V2 18/46] arm64/sysreg: Add register fields for PMUACR_EL1
In-Reply-To: <0b8a055f-eab9-4b44-baac-ad25756dbbfd@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-19-anshuman.khandual@arm.com>
 <20241216231505.GA601635-robh@kernel.org>
 <0b8a055f-eab9-4b44-baac-ad25756dbbfd@arm.com>
Message-ID: <88f15900-03d2-49f0-bc44-7ded076d9a42@sirena.org.uk>

On Tue, Dec 17, 2024 at 10:03:10AM +0530, Anshuman Khandual wrote:

> I am wondering how this did not cause any re-definition warning ?

If the redefinition is identical to the one that was already there then
the compiler will usually not warn.
-------------- 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/20241217/9f8006b2/attachment.sig>

From maz at kernel.org  Tue Dec 17 07:38:21 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:38:21 +0000
Subject: [PATCH v3 18/18] KVM: arm64: Plumb the pKVM MMU in KVM
In-Reply-To: <Z2GLR8KZzJn1YpUu@google.com>
References: <20241216175803.2716565-1-qperret@google.com>
	<20241216175803.2716565-19-qperret@google.com>
	<86ttb2qudi.wl-maz@kernel.org>
	<Z2GLR8KZzJn1YpUu@google.com>
Message-ID: <86pllqqpzm.wl-maz@kernel.org>

On Tue, 17 Dec 2024 14:31:35 +0000,
Quentin Perret <qperret at google.com> wrote:
> 
> On Tuesday 17 Dec 2024 at 14:03:37 (+0000), Marc Zyngier wrote:
> > My gripe with this is that it makes it much harder to follow what is
> > happening by using tags (ctags, etags, whatever). I ended up with the
> > hack below, which is super ugly, but preserves the tagging
> > functionality for non-pKVM.
> 
> Ack.
> 
> > I'll scratch my head to find something more elegant...
> 
> I find your proposal pretty reasonable -- I had a few different ideas
> but they were all really over-engineered, so I figured relying on a
> naming convention was the simplest. And any divergence will be flagged
> at compile time, so that shouldn't be too hard to maintain looking
> forward.
> 
> The __S2 name isn't massively descriptive though. Maybe KVM_PGT_CALL()
> or something? Thinking about it, this abstraction doesn't need to be
> restricted to stage-2 stuff. We could most likely hide the
> __pkvm_host_{un}share_hyp() logic behind a pkvm_pgtable_hyp_{un}map()
> implementation in pkvm.c as well...

Oh, I'm happy with *any* name. I just changed it to make sure any
missing occurrence would blow up.

And yes, if we can make that more uniform, I'm all for that.

Thanks,

	M.

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


From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:27 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:27 +0100
Subject: [PATCH v3 15/33] drm/mediatek: mtk_hdmi: Disgregate function mtk_hdmi_audio_set_param()
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-16-angelogioacchino.delregno@collabora.com>

As a cleanup, and in preparation for splitting common bits of this
driver, disgregate the code in function mtk_hdmi_audio_set_param()
between mtk_hdmi_audio_params() and mtk_hdmi_audio_hw_params().

The generic hdmi_audio_param copy now gets performed in the former,
and the IP specific mtk_hdmi_aud_output_config() gets called in the
latter, allowing all of the non IP version specific code to get
moved in a common file later.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 8f5ab97a0261..a927d9889818 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1054,20 +1054,6 @@ static void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi)
 	hdmi->audio_enable = false;
 }
 
-static int mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi,
-				    struct hdmi_audio_param *param)
-{
-	if (!hdmi->audio_enable) {
-		dev_err(hdmi->dev, "hdmi audio is in disable state!\n");
-		return -EINVAL;
-	}
-	dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",
-		param->aud_codec, param->aud_input_type,
-		param->aud_input_chan_type, param->codec_params.sample_rate);
-	memcpy(&hdmi->aud_param, param, sizeof(*param));
-	return mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);
-}
-
 static int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi,
 					    struct drm_display_mode *mode)
 {
@@ -1544,6 +1530,11 @@ static int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi,
 		return -EINVAL;
 	}
 	memcpy(&aud_params.codec_params, params, sizeof(aud_params.codec_params));
+	memcpy(&hdmi->aud_param, &aud_params, sizeof(aud_params));
+
+	dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",
+		aud_params.aud_codec, aud_params.aud_input_type,
+		aud_params.aud_input_chan_type, aud_params.codec_params.sample_rate);
 
 	return 0;
 }
@@ -1553,10 +1544,14 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
 				    struct hdmi_codec_params *params)
 {
 	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-	struct hdmi_audio_param hdmi_params;
+
+	if (!hdmi->audio_enable) {
+		dev_err(hdmi->dev, "hdmi audio is in disable state!\n");
+		return -EINVAL;
+	}
 
 	mtk_hdmi_audio_params(hdmi, daifmt, params);
-	mtk_hdmi_audio_set_param(hdmi, &hdmi_params);
+	mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);
 
 	return 0;
 }
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:28 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:28 +0100
Subject: [PATCH v3 16/33] drm/mediatek: mtk_hdmi: Move plugged_cb/codec_dev setting to new function
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-17-angelogioacchino.delregno@collabora.com>

In preparation for splitting common bits of this driver, move the
mutex-protected cable plugged callback and codec device setting
to a new function called mtk_hdmi_audio_set_plugged_cb().

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index a927d9889818..f60c4effe905 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1597,17 +1597,22 @@ static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
 	return 0;
 }
 
-static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,
-					  hdmi_codec_plugged_cb fn,
+static void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn,
 					  struct device *codec_dev)
 {
-	struct mtk_hdmi *hdmi = data;
-
 	mutex_lock(&hdmi->update_plugged_status_lock);
 	hdmi->plugged_cb = fn;
 	hdmi->codec_dev = codec_dev;
 	mutex_unlock(&hdmi->update_plugged_status_lock);
+}
+
+static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,
+					  hdmi_codec_plugged_cb fn,
+					  struct device *codec_dev)
+{
+	struct mtk_hdmi *hdmi = data;
 
+	mtk_hdmi_audio_set_plugged_cb(hdmi, fn, codec_dev);
 	mtk_hdmi_update_plugged_status(hdmi);
 
 	return 0;
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:29 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:29 +0100
Subject: [PATCH v3 17/33] drm/mediatek: mtk_hdmi: Move N/CTS setting to new function
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-18-angelogioacchino.delregno@collabora.com>

In preparation for splitting common bits of this driver, moving
the hdmi_rec_n_table struct array, and the hdmi_recommended_n(),
hdmi_mode_clock_to_hz(), hdmi_expected_cts() functions, add one
function called mtk_hdmi_get_ncts() that sets both N and CTS in
a single call.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index f60c4effe905..ef8dfcb77318 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -682,6 +682,13 @@ static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate,
 				     128 * audio_sample_rate);
 }
 
+static void mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock,
+			      unsigned int *n, unsigned int *cts)
+{
+	*n = hdmi_recommended_n(sample_rate, clock);
+	*cts = hdmi_expected_cts(sample_rate, clock, *n);
+}
+
 static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,
 				    unsigned int cts)
 {
@@ -712,8 +719,7 @@ static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
 {
 	unsigned int n, cts;
 
-	n = hdmi_recommended_n(sample_rate, clock);
-	cts = hdmi_expected_cts(sample_rate, clock, n);
+	mtk_hdmi_get_ncts(sample_rate, clock, &n, &cts);
 
 	dev_dbg(hdmi->dev, "%s: sample_rate=%u, clock=%d, cts=%u, n=%u\n",
 		__func__, sample_rate, clock, n, cts);
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:30 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:30 +0100
Subject: [PATCH v3 18/33] drm/mediatek: mtk_hdmi: Move vendor/product strings to drm_bridge
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-19-angelogioacchino.delregno@collabora.com>

Move the vendor and product strings to the appropriate entries
of struct drm_bridge and use that in mtk_hdmi_setup_spd_infoframe
instead of having the same as function parameters.

While at it, also beautify the strings, setting them to read
"MediaTek On-Chip HDMI".

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index ef8dfcb77318..eb38f4b7674e 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -952,15 +952,14 @@ static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi,
 	return 0;
 }
 
-static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi,
-					const char *vendor,
-					const char *product)
+static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi)
 {
+	struct drm_bridge *bridge = &hdmi->bridge;
 	struct hdmi_spd_infoframe frame;
 	u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE];
 	ssize_t err;
 
-	err = hdmi_spd_infoframe_init(&frame, vendor, product);
+	err = hdmi_spd_infoframe_init(&frame, bridge->vendor, bridge->product);
 	if (err < 0) {
 		dev_err(hdmi->dev, "Failed to initialize SPD infoframe: %zd\n",
 			err);
@@ -1328,7 +1327,7 @@ static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi,
 {
 	mtk_hdmi_setup_audio_infoframe(hdmi);
 	mtk_hdmi_setup_avi_infoframe(hdmi, mode);
-	mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI");
+	mtk_hdmi_setup_spd_infoframe(hdmi);
 	if (mode->flags & DRM_MODE_FLAG_3D_MASK)
 		mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode);
 }
@@ -1709,6 +1708,8 @@ static int mtk_hdmi_probe(struct platform_device *pdev)
 	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
 			 | DRM_BRIDGE_OP_HPD;
 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+	hdmi->bridge.vendor = "MediaTek";
+	hdmi->bridge.product = "On-Chip HDMI";
 	drm_bridge_add(&hdmi->bridge);
 
 	ret = mtk_hdmi_clk_enable_audio(hdmi);
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:31 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:31 +0100
Subject: [PATCH v3 19/33] drm/mediatek: mtk_hdmi: Use dev_err_probe() in mtk_hdmi_dt_parse_pdata()
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-20-angelogioacchino.delregno@collabora.com>

Change error prints to use dev_err_probe() instead of dev_err()
where possible in function mtk_hdmi_dt_parse_pdata(), used only
during device probe.
While at it, also beautify some prints.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index eb38f4b7674e..c20d42ec387a 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1372,30 +1372,23 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
-	struct device_node *cec_np, *remote, *i2c_np;
+	struct device_node *remote, *i2c_np;
 	struct platform_device *cec_pdev;
 	struct regmap *regmap;
 	int ret;
 
 	ret = mtk_hdmi_get_all_clk(hdmi, np);
-	if (ret) {
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get clocks: %d\n", ret);
-
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get clocks\n");
 
 	/* The CEC module handles HDMI hotplug detection */
 	cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
-	if (!cec_np) {
-		dev_err(dev, "Failed to find CEC node\n");
-		return -EINVAL;
-	}
+	if (!cec_np)
+		return dev_err_probe(dev, -EINVAL, "Failed to find CEC node\n");
 
 	cec_pdev = of_find_device_by_node(cec_np);
 	if (!cec_pdev) {
-		dev_err(hdmi->dev, "Waiting for CEC device %pOF\n",
-			cec_np);
+		dev_err(hdmi->dev, "Waiting for CEC device %pOF\n", cec_np);
 		of_node_put(cec_np);
 		return -EPROBE_DEFER;
 	}
@@ -1413,9 +1406,8 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 	if (IS_ERR(regmap))
 		ret = PTR_ERR(regmap);
 	if (ret) {
-		dev_err(dev,
-			"Failed to get system configuration registers: %d\n",
-			ret);
+		dev_err_probe(dev, ret,
+			      "Failed to get system configuration registers\n");
 		goto put_device;
 	}
 	hdmi->sys_regmap = regmap;
@@ -1443,20 +1435,16 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 	}
 
 	i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
+	of_node_put(remote);
 	if (!i2c_np) {
-		dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n",
-			remote);
-		of_node_put(remote);
-		ret = -EINVAL;
+		ret = dev_err_probe(dev, -EINVAL, "No ddc-i2c-bus in connector\n");
 		goto put_device;
 	}
-	of_node_put(remote);
 
 	hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
 	of_node_put(i2c_np);
 	if (!hdmi->ddc_adpt) {
-		dev_err(dev, "Failed to get ddc i2c adapter by node\n");
-		ret = -EINVAL;
+		ret = dev_err_probe(dev, -EINVAL, "Failed to get ddc i2c adapter by node\n");
 		goto put_device;
 	}
 
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:32 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:32 +0100
Subject: [PATCH v3 20/33] drm/mediatek: mtk_hdmi: Move CEC device parsing in new function
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-21-angelogioacchino.delregno@collabora.com>

Move the CEC device parsing logic to a new function called
mtk_hdmi_get_cec_dev(), and move the parsing action to the end
of mtk_hdmi_dt_parse_pdata(), allowing to remove gotos in this
function, reducing code size and improving readability.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index c20d42ec387a..c95c7b55998c 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1367,24 +1367,16 @@ static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = {
 	.edid_read = mtk_hdmi_bridge_edid_read,
 };
 
-static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
-				   struct platform_device *pdev)
+static int mtk_hdmi_get_cec_dev(struct mtk_hdmi *hdmi, struct device *dev, struct device_node *np)
 {
-	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
-	struct device_node *remote, *i2c_np;
 	struct platform_device *cec_pdev;
-	struct regmap *regmap;
+	struct device_node *cec_np;
 	int ret;
 
-	ret = mtk_hdmi_get_all_clk(hdmi, np);
-	if (ret)
-		return dev_err_probe(dev, ret, "Failed to get clocks\n");
-
 	/* The CEC module handles HDMI hotplug detection */
 	cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
 	if (!cec_np)
-		return dev_err_probe(dev, -EINVAL, "Failed to find CEC node\n");
+		return dev_err_probe(dev, -ENOTSUPP, "Failed to find CEC node\n");
 
 	cec_pdev = of_find_device_by_node(cec_np);
 	if (!cec_pdev) {
@@ -1393,65 +1385,69 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 		return -EPROBE_DEFER;
 	}
 	of_node_put(cec_np);
-	hdmi->cec_dev = &cec_pdev->dev;
 
 	/*
 	 * The mediatek,syscon-hdmi property contains a phandle link to the
 	 * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG
 	 * registers it contains.
 	 */
-	regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");
-	ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1,
-					 &hdmi->sys_offset);
-	if (IS_ERR(regmap))
-		ret = PTR_ERR(regmap);
-	if (ret) {
-		dev_err_probe(dev, ret,
-			      "Failed to get system configuration registers\n");
-		goto put_device;
-	}
-	hdmi->sys_regmap = regmap;
+	hdmi->sys_regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");
+	if (IS_ERR(hdmi->sys_regmap))
+		return PTR_ERR(hdmi->sys_regmap);
+
+	ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, &hdmi->sys_offset);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get system configuration registers\n");
+
+	hdmi->cec_dev = &cec_pdev->dev;
+	return 0;
+}
+
+static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
+				   struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *remote, *i2c_np;
+	int ret;
+
+	ret = mtk_hdmi_get_all_clk(hdmi, np);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get clocks\n");
 
 	hdmi->regs = device_node_to_regmap(dev->of_node);
-	if (IS_ERR(hdmi->regs)) {
-		ret = PTR_ERR(hdmi->regs);
-		goto put_device;
-	}
+	if (IS_ERR(hdmi->regs))
+		return PTR_ERR(hdmi->regs);
 
 	remote = of_graph_get_remote_node(np, 1, 0);
-	if (!remote) {
-		ret = -EINVAL;
-		goto put_device;
-	}
+	if (!remote)
+		return -EINVAL;
 
 	if (!of_device_is_compatible(remote, "hdmi-connector")) {
 		hdmi->next_bridge = of_drm_find_bridge(remote);
 		if (!hdmi->next_bridge) {
 			dev_err(dev, "Waiting for external bridge\n");
 			of_node_put(remote);
-			ret = -EPROBE_DEFER;
-			goto put_device;
+			return -EPROBE_DEFER;
 		}
 	}
 
 	i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
 	of_node_put(remote);
-	if (!i2c_np) {
-		ret = dev_err_probe(dev, -EINVAL, "No ddc-i2c-bus in connector\n");
-		goto put_device;
-	}
+	if (!i2c_np)
+		return dev_err_probe(dev, -EINVAL, "No ddc-i2c-bus in connector\n");
 
 	hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
 	of_node_put(i2c_np);
-	if (!hdmi->ddc_adpt) {
-		ret = dev_err_probe(dev, -EINVAL, "Failed to get ddc i2c adapter by node\n");
-		goto put_device;
-	}
+	if (!hdmi->ddc_adpt)
+		return dev_err_probe(dev, -EINVAL, "Failed to get ddc i2c adapter by node\n");
+
+	ret = mtk_hdmi_get_cec_dev(hdmi, dev, np);
+	if (ret)
+		return ret;
 
 	return 0;
-put_device:
-	put_device(hdmi->cec_dev);
-	return ret;
 }
 
 /*
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:33 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:33 +0100
Subject: [PATCH v3 21/33] drm/mediatek: mtk_hdmi: Remove unused members of struct mtk_hdmi
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-22-angelogioacchino.delregno@collabora.com>

The hdmi_colorspace csp member of struct mtk_hdmi is initialized
once but then it's never used at all.
Remove said member and the only assignment to it as a cleanup.

Also remove the ibias, ibias_up, min_clock, max_clock, min_hdisplay
and max_vdisplay members, as those were really completely unused.

This commit brings no functional changes.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index c95c7b55998c..3ecd0ed59851 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -162,16 +162,9 @@ struct mtk_hdmi {
 	struct clk *clk[MTK_HDMI_CLK_COUNT];
 	struct drm_display_mode mode;
 	bool dvi_mode;
-	u32 min_clock;
-	u32 max_clock;
-	u32 max_hdisplay;
-	u32 max_vdisplay;
-	u32 ibias;
-	u32 ibias_up;
 	struct regmap *sys_regmap;
 	unsigned int sys_offset;
 	struct regmap *regs;
-	enum hdmi_colorspace csp;
 	struct platform_device *audio_pdev;
 	struct hdmi_audio_param aud_param;
 	bool audio_enable;
@@ -1036,7 +1029,6 @@ static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
 {
 	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
 
-	hdmi->csp = HDMI_COLORSPACE_RGB;
 	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
 	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
 	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:13 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:13 +0100
Subject: [PATCH v3 01/33] dt-bindings: display: mediatek: dpi: Add MT8195 and MT8188 compat
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-2-angelogioacchino.delregno@collabora.com>

Add compatibles for the Digital Parallel Interface (DPI) block
found in the MT8195 and MT8188 SoCs: inside of the chip, this one
is directly connected to the HDMI block.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../devicetree/bindings/display/mediatek/mediatek,dpi.yaml   | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
index 0f1e556dc8ef..5670715efa5c 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
@@ -27,6 +27,7 @@ properties:
           - mediatek,mt8188-dp-intf
           - mediatek,mt8192-dpi
           - mediatek,mt8195-dp-intf
+          - mediatek,mt8195-dpi
       - items:
           - enum:
               - mediatek,mt6795-dpi
@@ -35,6 +36,10 @@ properties:
           - enum:
               - mediatek,mt8365-dpi
           - const: mediatek,mt8192-dpi
+      - items:
+          - enum:
+              - mediatek,mt8188-dpi
+          - const: mediatek,mt8195-dpi
 
   reg:
     maxItems: 1
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:12 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:12 +0100
Subject: [PATCH v3 00/33] Add support for MT8195/88 DPI, HDMIv2 and DDCv2
Message-ID: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>

Changes in v3:
 - Added hpd_enable() and hpd_disable() callbacks as suggested by Dmitry B
 - Removed audio mute call in bridge_enable() as suggested by CK
 - Reworked commonization commits for mtk_hdmi/mtk_hdmi_common and split
   out debugfs/abist implementation as suggested by CK
 - Removed .mode_valid() callback as it is now provided by the bridge
   API in drm_bridge_connector_helper_funcs
 - A bit of cleanups here and there
 - Tested again on HW especially for new hpd_enable/disable callbacks.

Changes in v2:
 - Merged series "Add support for MT8195/8188 and Pattern Generator"
   and "drm/mediatek: Add support for HDMIv2 and DDCv2 IPs" in one
   as they are directly related, as requested by CK Hu
 - More commonization: moved some audio functions to mtk_hdmi_common
 - Fixed a bug in DDCv2 driver to allow sending a message with len=1
 - Renamed some functions in HDMIv2 to consistently use the prefix
   mtk_hdmi_v2_ across the driver
 - Added .mode_valid() callback to HDMIv2
 - Added .atomic_check() callback to HDMIv2
 - Reordered drm_bridge_funcs in HDMIv2 driver
 - Rewritten .edid_read() callback in HDMIv2 to move checking audio
   availability to bridge_pre_enable() stage, and to stop using the
   drm_edid_read_ddc() in favor of drm_edid_read()
 - Added support for API provided HDMI Helpers
 - Added .tmds_char_rate_valid() callback to HDMIv2 for HDMI helpers
 - Added .hdmi_{read,write}_infoframe() callback to HDMIv2 for helpers
 - Added support for Vendor infoframes in HDMIv2
 - Added missing audio-dai-cells to HDMIv2 binding to fix check error
 - Added more information to the HDMIv2 binding for clocks and PHY
 - Added some comments to the HDMIv2 code to clarify why the controller
   is preconfigured in bridge_pre_enable() instead of bridge_enable()
 - Added a mention of the differences in HPD between v1 and v2 to the
   commit introducing the v2 driver (v2 is not using CEC for HPD)
 - ...and tested again on HW! :-)


This series adds support for the HDMI-TX v2 Encoder and DDCv2, and for
the direct connection DPI as found in MT8195, MT8188 and their variants.

Tested on Genio 700 EVK:
 - ABIST ON: ok, pattern generated internally from HDMI is shown on
   HDMI screen at the correct resolution;
 - ABIST OFF + DPI Pattern Generator ON: ok, pattern coming from DPI is
   shown on HDMI screen at the correct resolution;
 - Can negotiate up to 4k60

and on MT8395 Radxa NIO 12L:
 - ABIST ON: ok, pattern generated internally from HDMI is shown on
   HDMI screen at the correct resolution;
 - ABIST OFF + DPI Pattern Generator ON: ok, pattern coming from DPI is
   shown on HDMI screen at the correct resolution;
 - Dual screen usecase validated (DSI + HDMI 3840x2160p 60Hz)
 - Can negotiate up to 4k60

Please note that this submission does *not* include support for HDCP
nor for CECv2, as I want this to be upstream before implementing
additional features which are not strictly required for simple
HDMI output.

Bonus in this series is the addition of support for the Pattern Generator
found in the DPI HW: since I needed this for debugging during development,
I had to code in the actual support bits and it looked like a waste of
time to just remove it.
I instead decided to clean it up and upstream it, as this will anyway come
handy for multiple things, of which the most important (imo) are:
 - Adding support for new SoCs in the future will be less time consuming
   as this driver already has the pattern generator in;
 - CI Testing might be able to make use of this to validate that the
   data that comes out is not garbled (so, to help testing display
   support in an automated manner).

AngeloGioacchino Del Regno (32):
  dt-bindings: display: mediatek: dpi: Add MT8195 and MT8188 compat
  drm/mediatek: mtk_dpi: Add support for Pattern Generator in debugfs
  drm/mediatek: mtk_dpi: Use an array for pixclk factor calculation
  drm/mediatek: mtk_dpi: Move pixel clock setting flow to function
  drm/mediatek: mtk_dpi: Add checks for reg_h_fre_con existence
  drm/mediatek: Add support for MT8195 Digital Parallel Interface
  dt-bindings: display: mediatek: Add binding for MT8195 HDMI-TX v2
  drm/mediatek: mtk_cec: Switch to register as module_platform_driver
  drm/mediatek: mtk_hdmi_ddc: Switch to register as
    module_platform_driver
  drm/mediatek: mtk_hdmi: Convert to module_platform_driver macro
  drm/mediatek: mtk_hdmi: Unregister audio platform device on failure
  drm/mediatek: mtk_hdmi: Fix typo for aud_sampe_size member
  drm/mediatek: mtk_hdmi: Move audio params selection to new function
  drm/mediatek: mtk_hdmi: Disgregate function mtk_hdmi_audio_set_param()
  drm/mediatek: mtk_hdmi: Move plugged_cb/codec_dev setting to new
    function
  drm/mediatek: mtk_hdmi: Move N/CTS setting to new function
  drm/mediatek: mtk_hdmi: Move vendor/product strings to drm_bridge
  drm/mediatek: mtk_hdmi: Use dev_err_probe() in
    mtk_hdmi_dt_parse_pdata()
  drm/mediatek: mtk_hdmi: Move CEC device parsing in new function
  drm/mediatek: mtk_hdmi: Remove unused members of struct mtk_hdmi
  drm/mediatek: mtk_hdmi: Move output init to
    mtk_hdmi_register_audio_driver()
  drm/mediatek: mtk_hdmi: Use devm managed version of drm_bridge_add
  drm/mediatek: mtk_hdmi: Remove ifdef for CONFIG_PM_SLEEP
  drm/mediatek: mtk_hdmi: Remove goto in mtk_hdmi_clk_enable_audio()
  drm/mediatek: mtk_hdmi: Cleanup function mtk_hdmi_resume()
  drm/mediatek: mtk_hdmi: Improve mtk_hdmi_get_all_clk() flexibility
  drm/mediatek: mtk_hdmi: Split driver and add common probe function
  drm/mediatek: mtk_hdmi_common: Assign DDC adapter pointer to bridge
  drm/mediatek: mtk_hdmi_common: Add OP_HDMI if helper funcs assigned
  drm/mediatek: Introduce HDMI/DDC v2 for MT8195/MT8188
  drm/mediatek: mtk_hdmi_common: Add var to enable interlaced modes
  drm/mediatek: mtk_hdmi_v2: Add debugfs ops and implement ABIST

Guillaume Ranquet (1):
  drm/mediatek: hdmi: Use regmap instead of iomem for main registers

 .../display/mediatek/mediatek,dpi.yaml        |    5 +
 .../mediatek/mediatek,mt8195-hdmi.yaml        |  154 ++
 drivers/gpu/drm/mediatek/Kconfig              |   19 +-
 drivers/gpu/drm/mediatek/Makefile             |    5 +
 drivers/gpu/drm/mediatek/mtk_cec.c            |    5 +-
 drivers/gpu/drm/mediatek/mtk_dpi.c            |  311 +++-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   10 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |    2 +
 drivers/gpu/drm/mediatek/mtk_hdmi.c           |  808 ++-------
 drivers/gpu/drm/mediatek/mtk_hdmi.h           |   14 -
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c    |  438 +++++
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h    |  198 +++
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c       |    2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c    |  403 +++++
 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h   |  263 +++
 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c        | 1508 +++++++++++++++++
 16 files changed, 3354 insertions(+), 791 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
 delete mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c

-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:14 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:14 +0100
Subject: [PATCH v3 02/33] drm/mediatek: mtk_dpi: Add support for Pattern Generator in debugfs
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-3-angelogioacchino.delregno@collabora.com>

This IP includes a Pattern Generator which is useful for debugging
and testing purposes: add the relevant register and bits to the
mtk_dpi_regs.h header, and implement support for it in mtk_dpi.

Adding this required to introduce a .debugfs_init() callback for
the DPI bridge, which creates a "dpi_test_pattern" file in the
directory of the appropriate connector.

The pattern generator can generate various internal patterns and
this submission includes support for:
 - 256 or 1024 shades of gray in a Vertical or Horizontal Pattern
 - Vertical Color Bars
 - Frame border
 - Dot Moire

This generator also supports filling the entire screen with one
custom color, but support for that is not included in this commit.

Enabling and disabling this generator can be done by sending a
string to the dpi_test_pattern debugfs file; the pattern is
expected to be formatted as follows:

         <enable (1) or disable (0)> <pattern number>

where the pattern number can be a number from 0 to 7, excluding 5.

Of course 5 is excluded because that activates custom color fill
which, again, is not supported in this commit.

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_dpi.c      | 107 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |   4 +
 2 files changed, 111 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 1864eb02dbf5..4194ac328b0b 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -6,6 +6,7 @@
 
 #include <linux/clk.h>
 #include <linux/component.h>
+#include <linux/debugfs.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/media-bus-format.h>
@@ -166,6 +167,18 @@ static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
 	writel(tmp, dpi->regs + offset);
 }
 
+static void mtk_dpi_test_pattern_en(struct mtk_dpi *dpi, u8 type, bool enable)
+{
+	u32 val;
+
+	if (enable)
+		val = FIELD_PREP(DPI_PAT_SEL, type) | DPI_PAT_EN;
+	else
+		val = 0;
+
+	mtk_dpi_mask(dpi, DPI_PATTERN0, val, DPI_PAT_SEL | DPI_PAT_EN);
+}
+
 static void mtk_dpi_sw_reset(struct mtk_dpi *dpi, bool reset)
 {
 	mtk_dpi_mask(dpi, DPI_RET, reset ? RST : 0, RST);
@@ -767,6 +780,99 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
 	return MODE_OK;
 }
 
+static int mtk_dpi_debug_tp_show(struct seq_file *m, void *arg)
+{
+	struct mtk_dpi *dpi = m->private;
+	bool en;
+	u32 val;
+
+	if (!dpi)
+		return -EINVAL;
+
+	val = readl(dpi->regs + DPI_PATTERN0);
+	en = val & DPI_PAT_EN;
+	val = FIELD_GET(DPI_PAT_SEL, val);
+
+	seq_printf(m, "DPI Test Pattern: %s\n", en ? "Enabled" : "Disabled");
+
+	if (en) {
+		seq_printf(m, "Internal pattern %d: ", val);
+		switch (val) {
+		case 0:
+			seq_puts(m, "256 Vertical Gray\n");
+			break;
+		case 1:
+			seq_puts(m, "1024 Vertical Gray\n");
+			break;
+		case 2:
+			seq_puts(m, "256 Horizontal Gray\n");
+			break;
+		case 3:
+			seq_puts(m, "1024 Horizontal Gray\n");
+			break;
+		case 4:
+			seq_puts(m, "Vertical Color bars\n");
+			break;
+		case 6:
+			seq_puts(m, "Frame border\n");
+			break;
+		case 7:
+			seq_puts(m, "Dot moire\n");
+			break;
+		default:
+			seq_puts(m, "Invalid selection\n");
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static ssize_t mtk_dpi_debug_tp_write(struct file *file, const char __user *ubuf,
+				      size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	u32 en, type;
+	char buf[6];
+
+	if (!m || !m->private || *offp || len > sizeof(buf) - 1)
+		return -EINVAL;
+
+	memset(buf, 0, sizeof(buf));
+	if (copy_from_user(buf, ubuf, len))
+		return -EFAULT;
+
+	if (sscanf(buf, "%u %u", &en, &type) != 2)
+		return -EINVAL;
+
+	if (en < 0 || en > 1 || type < 0 || type > 7)
+		return -EINVAL;
+
+	mtk_dpi_test_pattern_en((struct mtk_dpi *)m->private, type, en);
+	return len;
+}
+
+static int mtk_dpi_debug_tp_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mtk_dpi_debug_tp_show, inode->i_private);
+}
+
+static const struct file_operations mtk_dpi_debug_tp_fops = {
+	.owner = THIS_MODULE,
+	.open = mtk_dpi_debug_tp_open,
+	.read = seq_read,
+	.write = mtk_dpi_debug_tp_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static void mtk_dpi_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
+{
+	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
+
+	debugfs_create_file("dpi_test_pattern", 0640, root, dpi, &mtk_dpi_debug_tp_fops);
+}
+
 static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
 	.attach = mtk_dpi_bridge_attach,
 	.mode_set = mtk_dpi_bridge_mode_set,
@@ -779,6 +885,7 @@ static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
 	.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,
+	.debugfs_init = mtk_dpi_debugfs_init,
 };
 
 void mtk_dpi_start(struct device *dev)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 62bd4931b344..a0b1d18bbbf7 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -235,4 +235,8 @@
 #define MATRIX_SEL_RGB_TO_JPEG		0
 #define MATRIX_SEL_RGB_TO_BT601		2
 
+#define DPI_PATTERN0		0xf00
+#define DPI_PAT_EN			BIT(0)
+#define DPI_PAT_SEL			GENMASK(6, 4)
+
 #endif /* __MTK_DPI_REGS_H */
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:15 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:15 +0100
Subject: [PATCH v3 03/33] drm/mediatek: mtk_dpi: Use an array for pixclk factor calculation
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-4-angelogioacchino.delregno@collabora.com>

Setting the TVD PLL clock requires to multiply the target pixel
clock by a specific constant factor to achieve the target PLL
frequency, and this is done to reduce jitter to acceptable levels.

On all MediaTek SoCs, the factor is not retrieved by any real kind
of calculation but rather by checking if the target pixel clock
is less than a specified frequency, hence assigning a function
pointer for just a bunch of if branches does enlarge the code
size for little reason.

Remove all SoC-specific functions, add a structure `mtk_dpi_factor`
that holds a clock frequency and corresponding PLL factor, and
declare the constraints for each SoC in form of an array of said
structure.
Instead of function pointers, this structure (and its size) is then
assigned to each SoC's platform data.

The "calculation" is then performed with a new static function
mtk_dpi_calculate_factor(dpi, mode_clk) that iterates through all
of the entries of the aforementioned array and returns the right
factor.

If no factor is found, the lowest possible factor is returned,
mimicking the same flow as all of the old per-SoC calculation
functions.

This commit brings no functional change.

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_dpi.c | 103 +++++++++++++++--------------
 1 file changed, 52 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4194ac328b0b..3bdce932f910 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -117,9 +117,15 @@ struct mtk_dpi_yc_limit {
 	u16 c_bottom;
 };
 
+struct mtk_dpi_factor {
+	u32 clock;
+	u8 factor;
+};
+
 /**
  * struct mtk_dpi_conf - Configuration of mediatek dpi.
- * @cal_factor: Callback function to calculate factor value.
+ * @dpi_factor: SoC-specific pixel clock PLL factor values.
+ * @num_dpi_factor: Number of pixel clock PLL factor values.
  * @reg_h_fre_con: Register address of frequency control.
  * @max_clock_khz: Max clock frequency supported for this SoCs in khz units.
  * @edge_sel_en: Enable of edge selection.
@@ -140,7 +146,8 @@ struct mtk_dpi_yc_limit {
  * @edge_cfg_in_mmsys: If the edge configuration for DPI's output needs to be set in MMSYS.
  */
 struct mtk_dpi_conf {
-	unsigned int (*cal_factor)(int clock);
+	const struct mtk_dpi_factor *dpi_factor;
+	const u8 num_dpi_factor;
 	u32 reg_h_fre_con;
 	u32 max_clock_khz;
 	bool edge_sel_en;
@@ -515,6 +522,20 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return ret;
 }
 
+static unsigned int mtk_dpi_calculate_factor(struct mtk_dpi *dpi, int mode_clk)
+{
+	const struct mtk_dpi_factor *dpi_factor = dpi->conf->dpi_factor;
+	int i;
+
+	for (i = 0; i < dpi->conf->num_dpi_factor; i++) {
+		if (mode_clk <= dpi_factor[i].clock)
+			return dpi_factor[i].factor;
+	}
+
+	/* If no match try the lowest possible factor */
+	return dpi_factor[dpi->conf->num_dpi_factor - 1].factor;
+}
+
 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 				    struct drm_display_mode *mode)
 {
@@ -529,7 +550,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	unsigned int factor;
 
 	/* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
-	factor = dpi->conf->cal_factor(mode->clock);
+	factor = mtk_dpi_calculate_factor(dpi, mode_clk);
 	drm_display_mode_to_videomode(mode, &vm);
 	pll_rate = vm.pixelclock * factor;
 
@@ -964,48 +985,6 @@ static const struct component_ops mtk_dpi_component_ops = {
 	.unbind = mtk_dpi_unbind,
 };
 
-static unsigned int mt8173_calculate_factor(int clock)
-{
-	if (clock <= 27000)
-		return 3 << 4;
-	else if (clock <= 84000)
-		return 3 << 3;
-	else if (clock <= 167000)
-		return 3 << 2;
-	else
-		return 3 << 1;
-}
-
-static unsigned int mt2701_calculate_factor(int clock)
-{
-	if (clock <= 64000)
-		return 4;
-	else if (clock <= 128000)
-		return 2;
-	else
-		return 1;
-}
-
-static unsigned int mt8183_calculate_factor(int clock)
-{
-	if (clock <= 27000)
-		return 8;
-	else if (clock <= 167000)
-		return 4;
-	else
-		return 2;
-}
-
-static unsigned int mt8195_dpintf_calculate_factor(int clock)
-{
-	if (clock < 70000)
-		return 4;
-	else if (clock < 200000)
-		return 2;
-	else
-		return 1;
-}
-
 static const u32 mt8173_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -1020,8 +999,25 @@ static const u32 mt8195_output_fmts[] = {
 	MEDIA_BUS_FMT_YUYV8_1X16,
 };
 
+static const struct mtk_dpi_factor dpi_factor_mt2701[] = {
+	{ 64000, 4 }, { 128000, 2 }, { U32_MAX, 1 }
+};
+
+static const struct mtk_dpi_factor dpi_factor_mt8173[] = {
+	{ 27000, 48 }, { 84000, 24 }, { 167000, 12 }, { U32_MAX, 6 }
+};
+
+static const struct mtk_dpi_factor dpi_factor_mt8183[] = {
+	{ 27000, 8 }, { 167000, 4 }, { U32_MAX, 2 }
+};
+
+static const struct mtk_dpi_factor dpi_factor_mt8195_dp_intf[] = {
+	{ 70000 - 1, 4 }, { 200000 - 1, 2 }, { U32_MAX, 1 }
+};
+
 static const struct mtk_dpi_conf mt8173_conf = {
-	.cal_factor = mt8173_calculate_factor,
+	.dpi_factor = dpi_factor_mt8173,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8173),
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
@@ -1038,7 +1034,8 @@ static const struct mtk_dpi_conf mt8173_conf = {
 };
 
 static const struct mtk_dpi_conf mt2701_conf = {
-	.cal_factor = mt2701_calculate_factor,
+	.dpi_factor = dpi_factor_mt2701,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt2701),
 	.reg_h_fre_con = 0xb0,
 	.edge_sel_en = true,
 	.max_clock_khz = 150000,
@@ -1056,7 +1053,8 @@ static const struct mtk_dpi_conf mt2701_conf = {
 };
 
 static const struct mtk_dpi_conf mt8183_conf = {
-	.cal_factor = mt8183_calculate_factor,
+	.dpi_factor = dpi_factor_mt8183,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8183),
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
@@ -1073,7 +1071,8 @@ static const struct mtk_dpi_conf mt8183_conf = {
 };
 
 static const struct mtk_dpi_conf mt8186_conf = {
-	.cal_factor = mt8183_calculate_factor,
+	.dpi_factor = dpi_factor_mt8183,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8183),
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 150000,
 	.output_fmts = mt8183_output_fmts,
@@ -1091,7 +1090,8 @@ static const struct mtk_dpi_conf mt8186_conf = {
 };
 
 static const struct mtk_dpi_conf mt8192_conf = {
-	.cal_factor = mt8183_calculate_factor,
+	.dpi_factor = dpi_factor_mt8183,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8183),
 	.reg_h_fre_con = 0xe0,
 	.max_clock_khz = 150000,
 	.output_fmts = mt8183_output_fmts,
@@ -1108,7 +1108,8 @@ static const struct mtk_dpi_conf mt8192_conf = {
 };
 
 static const struct mtk_dpi_conf mt8195_dpintf_conf = {
-	.cal_factor = mt8195_dpintf_calculate_factor,
+	.dpi_factor = dpi_factor_mt8195_dp_intf,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8195_dp_intf),
 	.max_clock_khz = 600000,
 	.output_fmts = mt8195_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:16 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:16 +0100
Subject: [PATCH v3 04/33] drm/mediatek: mtk_dpi: Move pixel clock setting flow to function
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-5-angelogioacchino.delregno@collabora.com>

In preparation for adding support for the DPI IP found in MT8195
and in MT8188 used for HDMI, move the code flow for calculation
and setting of the DPI pixel clock to a separate function called
mtk_dpi_set_pixel_clk().

This was done because, on those platforms, the DPI instance that
is used for HDMI will get its pixel clock from the HDMI clock,
hence it is not necessary, nor desirable, to calculate or set
the pixel clock in DPI.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 3bdce932f910..f931baf9c3fa 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -536,26 +536,17 @@ static unsigned int mtk_dpi_calculate_factor(struct mtk_dpi *dpi, int mode_clk)
 	return dpi_factor[dpi->conf->num_dpi_factor - 1].factor;
 }
 
-static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
-				    struct drm_display_mode *mode)
+static void mtk_dpi_set_pixel_clk(struct mtk_dpi *dpi, struct videomode *vm, int mode_clk)
 {
-	struct mtk_dpi_polarities dpi_pol;
-	struct mtk_dpi_sync_param hsync;
-	struct mtk_dpi_sync_param vsync_lodd = { 0 };
-	struct mtk_dpi_sync_param vsync_leven = { 0 };
-	struct mtk_dpi_sync_param vsync_rodd = { 0 };
-	struct mtk_dpi_sync_param vsync_reven = { 0 };
-	struct videomode vm = { 0 };
 	unsigned long pll_rate;
 	unsigned int factor;
 
 	/* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
 	factor = mtk_dpi_calculate_factor(dpi, mode_clk);
-	drm_display_mode_to_videomode(mode, &vm);
-	pll_rate = vm.pixelclock * factor;
+	pll_rate = vm->pixelclock * factor;
 
 	dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
-		pll_rate, vm.pixelclock);
+		pll_rate, vm->pixelclock);
 
 	clk_set_rate(dpi->tvd_clk, pll_rate);
 	pll_rate = clk_get_rate(dpi->tvd_clk);
@@ -565,20 +556,34 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	 * pixels for each iteration: divide the clock by this number and
 	 * adjust the display porches accordingly.
 	 */
-	vm.pixelclock = pll_rate / factor;
-	vm.pixelclock /= dpi->conf->pixels_per_iter;
+	vm->pixelclock = pll_rate / factor;
+	vm->pixelclock /= dpi->conf->pixels_per_iter;
 
 	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
 	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
-		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
+		clk_set_rate(dpi->pixel_clk, vm->pixelclock * 2);
 	else
-		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
+		clk_set_rate(dpi->pixel_clk, vm->pixelclock);
 
-
-	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
+	vm->pixelclock = clk_get_rate(dpi->pixel_clk);
 
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
-		pll_rate, vm.pixelclock);
+		pll_rate, vm->pixelclock);
+}
+
+static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
+				    struct drm_display_mode *mode)
+{
+	struct mtk_dpi_polarities dpi_pol;
+	struct mtk_dpi_sync_param hsync;
+	struct mtk_dpi_sync_param vsync_lodd = { 0 };
+	struct mtk_dpi_sync_param vsync_leven = { 0 };
+	struct mtk_dpi_sync_param vsync_rodd = { 0 };
+	struct mtk_dpi_sync_param vsync_reven = { 0 };
+	struct videomode vm = { 0 };
+
+	drm_display_mode_to_videomode(mode, &vm);
+	mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
 
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:17 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:17 +0100
Subject: [PATCH v3 05/33] drm/mediatek: mtk_dpi: Add checks for reg_h_fre_con existence
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-6-angelogioacchino.delregno@collabora.com>

In preparation for adding support for newer DPI instances which
do support direct-pin but do not have any H_FRE_CON register,
like the one found in MT8195 and MT8188, add a branch to check
if the reg_h_fre_con variable was declared in the mtk_dpi_conf
structure for the probed SoC DPI version.

As a note, this is useful specifically only for cases in which
the support_direct_pin variable is true, so mt8195-dpintf is
not affected by any issue.

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_dpi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index f931baf9c3fa..ed9849ad3e79 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -430,12 +430,13 @@ static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
 
 static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi)
 {
-	mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N);
+	if (dpi->conf->reg_h_fre_con)
+		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N);
 }
 
 static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
 {
-	if (dpi->conf->edge_sel_en)
+	if (dpi->conf->edge_sel_en && dpi->conf->reg_h_fre_con)
 		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
 }
 
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:18 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:18 +0100
Subject: [PATCH v3 06/33] drm/mediatek: Add support for MT8195 Digital Parallel Interface
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-7-angelogioacchino.delregno@collabora.com>

Add support for the DPI block found in the MT8195 and MT8188 SoCs.
Inside of the SoC, this block is directly connected to the HDMI IP.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 55 ++++++++++++++++++++++---
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  6 +++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  2 +
 3 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index ed9849ad3e79..334ab9be2f31 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -144,6 +144,7 @@ struct mtk_dpi_factor {
  * @csc_enable_bit: Enable bit of CSC.
  * @pixels_per_iter: Quantity of transferred pixels per iteration.
  * @edge_cfg_in_mmsys: If the edge configuration for DPI's output needs to be set in MMSYS.
+ * @is_internal_hdmi: Specifies whether the DPI is internally connected to the HDMI block
  */
 struct mtk_dpi_conf {
 	const struct mtk_dpi_factor *dpi_factor;
@@ -164,6 +165,7 @@ struct mtk_dpi_conf {
 	u32 csc_enable_bit;
 	u32 pixels_per_iter;
 	bool edge_cfg_in_mmsys;
+	bool is_internal_hdmi;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -492,6 +494,7 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 
 	mtk_dpi_disable(dpi);
 	clk_disable_unprepare(dpi->pixel_clk);
+	clk_disable_unprepare(dpi->tvd_clk);
 	clk_disable_unprepare(dpi->engine_clk);
 }
 
@@ -508,6 +511,12 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 		goto err_refcount;
 	}
 
+	ret = clk_prepare_enable(dpi->tvd_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
+		goto err_engine;
+	}
+
 	ret = clk_prepare_enable(dpi->pixel_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
@@ -517,6 +526,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return 0;
 
 err_pixel:
+	clk_disable_unprepare(dpi->tvd_clk);
+err_engine:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
 	dpi->refcount--;
@@ -584,7 +595,9 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	struct videomode vm = { 0 };
 
 	drm_display_mode_to_videomode(mode, &vm);
-	mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
+
+	if (!dpi->conf->is_internal_hdmi)
+		mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
 
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
@@ -647,10 +660,18 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	if (dpi->conf->support_direct_pin) {
 		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 		mtk_dpi_config_2n_h_fre(dpi);
-		mtk_dpi_dual_edge(dpi);
+		/* DPI can connect to either an external bridge or the internal HDMI encoder */
+		if (dpi->conf->is_internal_hdmi) {
+			mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN, DPI_OUTPUT_1T1P_EN);
+			mtk_dpi_mask(dpi, DPI_CON,
+				     dpi->conf->input_2pixel ? DPI_INPUT_2P_EN : 0,
+				     DPI_INPUT_2P_EN);
+		} else {
+			mtk_dpi_dual_edge(dpi);
+		}
 		mtk_dpi_config_disable_edge(dpi);
 	}
-	if (dpi->conf->input_2pixel) {
+	if (dpi->conf->input_2pixel && !dpi->conf->is_internal_hdmi) {
 		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
 			     DPINTF_INPUT_2P_EN);
 	}
@@ -919,14 +940,16 @@ void mtk_dpi_start(struct device *dev)
 {
 	struct mtk_dpi *dpi = dev_get_drvdata(dev);
 
-	mtk_dpi_power_on(dpi);
+	if (!dpi->conf->is_internal_hdmi)
+		mtk_dpi_power_on(dpi);
 }
 
 void mtk_dpi_stop(struct device *dev)
 {
 	struct mtk_dpi *dpi = dev_get_drvdata(dev);
 
-	mtk_dpi_power_off(dpi);
+	if (!dpi->conf->is_internal_hdmi)
+		mtk_dpi_power_off(dpi);
 }
 
 unsigned int mtk_dpi_encoder_index(struct device *dev)
@@ -1021,6 +1044,8 @@ static const struct mtk_dpi_factor dpi_factor_mt8195_dp_intf[] = {
 	{ 70000 - 1, 4 }, { 200000 - 1, 2 }, { U32_MAX, 1 }
 };
 
+static const struct mtk_dpi_factor dpi_factor_mt8195_dpi = { U32_MAX, 1 };
+
 static const struct mtk_dpi_conf mt8173_conf = {
 	.dpi_factor = dpi_factor_mt8173,
 	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8173),
@@ -1113,6 +1138,25 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.csc_enable_bit = CSC_ENABLE,
 };
 
+static const struct mtk_dpi_conf mt8195_conf = {
+	.dpi_factor = &dpi_factor_mt8195_dpi,
+	.num_dpi_factor = 1,
+	.max_clock_khz = 594000,
+	.output_fmts = mt8183_output_fmts,
+	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.pixels_per_iter = 1,
+	.is_ck_de_pol = true,
+	.swap_input_support = true,
+	.support_direct_pin = true,
+	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
+	.is_internal_hdmi = true,
+	.input_2pixel = true,
+};
+
 static const struct mtk_dpi_conf mt8195_dpintf_conf = {
 	.dpi_factor = dpi_factor_mt8195_dp_intf,
 	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8195_dp_intf),
@@ -1216,6 +1260,7 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8188-dp-intf", .data = &mt8195_dpintf_conf },
 	{ .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf },
 	{ .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf },
+	{ .compatible = "mediatek,mt8195-dpi", .data = &mt8195_conf },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index a0b1d18bbbf7..3c24d9e9f241 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -40,6 +40,12 @@
 #define FAKE_DE_LEVEN			BIT(21)
 #define FAKE_DE_RODD			BIT(22)
 #define FAKE_DE_REVEN			BIT(23)
+
+/* DPI_CON: DPI instances */
+#define DPI_OUTPUT_1T1P_EN		BIT(24)
+#define DPI_INPUT_2P_EN			BIT(25)
+
+/* DPI_CON: DPINTF instances */
 #define DPINTF_YUV422_EN		BIT(24)
 #define DPINTF_CSC_ENABLE		BIT(26)
 #define DPINTF_INPUT_2P_EN		BIT(29)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 49af2b19a85a..ad1eb91067c0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -805,6 +805,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt8195-dp-intf",
 	  .data = (void *)MTK_DP_INTF },
+	{ .compatible = "mediatek,mt8195-dpi",
+	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt2701-dsi",
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8173-dsi",
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:19 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:19 +0100
Subject: [PATCH v3 07/33] dt-bindings: display: mediatek: Add binding for MT8195 HDMI-TX v2
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>

Add a binding for the HDMI TX v2 Encoder found in MediaTek MT8195
and MT8188 SoCs.

This fully supports the HDMI Specification 2.0b, hence it provides
support for 3D-HDMI, Polarity inversion, up to 16 bits Deep Color,
color spaces including RGB444, YCBCR420/422/444 (ITU601/ITU709) and
xvYCC, with output resolutions up to 3840x2160p at 60Hz.

Moreover, it also supports HDCP 1.4 and 2.3, Variable Refresh Rate
(VRR) and Consumer Electronics Control (CEC).

This IP also includes support for HDMI Audio, including IEC60958
and IEC61937 SPDIF, 8-channel PCM, DSD, and other lossless audio
according to HDMI 2.0.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../mediatek/mediatek,mt8195-hdmi.yaml        | 154 ++++++++++++++++++
 1 file changed, 154 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
new file mode 100644
index 000000000000..73b1dfaa1adb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
@@ -0,0 +1,154 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek HDMI-TX v2 Encoder
+
+maintainers:
+  - AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+  - CK Hu <ck.hu at mediatek.com>
+
+description:
+  The MediaTek HDMI-TX v2 encoder can generate HDMI format data based on
+  the HDMI Specification 2.0b.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8188-hdmi-tx
+      - mediatek,mt8195-hdmi-tx
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: HDMI Peripheral Bus (APB) clock
+      - description: HDCP and HDMI_TOP clock
+      - description: HDCP and HDMI_TOP reference clock
+      - description: VPP HDMI Split clock
+
+  clock-names:
+    items:
+      - const: bus
+      - const: hdcp
+      - const: hdcp24m
+      - const: hdmi-split
+
+  i2c:
+    type: object
+    $ref: /schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
+    unevaluatedProperties: false
+    description: HDMI DDC I2C controller
+
+  phys:
+    maxItems: 1
+    description: PHY providing clocking TMDS and pixel to controller
+
+  phy-names:
+    items:
+      - const: hdmi
+
+  pinctrl-0: true
+
+  pinctrl-names:
+    items:
+      - const: default
+
+  power-domains:
+    maxItems: 1
+
+  '#sound-dai-cells':
+    const: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Input port, usually connected to the output port of a DPI
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port that must be connected either to the input port of
+          a HDMI connector node containing a ddc-i2c-bus, or to the input
+          port of an attached bridge chip, such as a SlimPort transmitter.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - power-domains
+  - phys
+  - phy-names
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/mt8195-power.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        hdmi-tx at 1c300000 {
+            compatible = "mediatek,mt8195-hdmi-tx";
+            reg = <0 0x1c300000 0 0x1000>;
+            clocks = <&topckgen CLK_TOP_HDMI_APB>,
+                     <&topckgen CLK_TOP_HDCP>,
+                     <&topckgen CLK_TOP_HDCP_24M>,
+                     <&vppsys1 CLK_VPP1_VPP_SPLIT_HDMI>;
+            clock-names = "bus", "hdcp", "hdcp24m", "hdmi-split";
+            interrupts = <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH 0>;
+            phys = <&hdmi_phy>;
+            phy-names = "hdmi";
+            power-domains = <&spm MT8195_POWER_DOMAIN_HDMI_TX>;
+            pinctrl-names = "default";
+            pinctrl-0 = <&hdmi_pins>;
+            #sound-dai-cells = <1>;
+
+            hdmitx_ddc: i2c {
+                compatible = "mediatek,mt8195-hdmi-ddc";
+                clocks = <&clk26m>;
+            };
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port at 0 {
+                    reg = <0>;
+
+                    hdmi_in: endpoint {
+                        remote-endpoint = <&dpi1_out>;
+                    };
+                };
+
+                port at 1 {
+                    reg = <1>;
+
+                    hdmi_out: endpoint {
+                        remote-endpoint = <&hdmi_connector_in>;
+                    };
+                };
+            };
+        };
+    };
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:20 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:20 +0100
Subject: [PATCH v3 08/33] drm/mediatek: mtk_cec: Switch to register as module_platform_driver
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-9-angelogioacchino.delregno@collabora.com>

In preparation for splitting out the common bits from the HDMI
driver, change the mtk_cec driver from being registered from the
HDMI driver itself to be a module_platform_driver of its own.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_cec.c  | 5 ++++-
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 1 -
 drivers/gpu/drm/mediatek/mtk_hdmi.h | 1 -
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c
index b42c0d87eba3..8dad762e24b8 100644
--- a/drivers/gpu/drm/mediatek/mtk_cec.c
+++ b/drivers/gpu/drm/mediatek/mtk_cec.c
@@ -12,7 +12,6 @@
 #include <linux/platform_device.h>
 
 #include "mtk_cec.h"
-#include "mtk_hdmi.h"
 #include "mtk_drm_drv.h"
 
 #define TR_CONFIG		0x00
@@ -247,3 +246,7 @@ struct platform_driver mtk_cec_driver = {
 		.of_match_table = mtk_cec_of_ids,
 	},
 };
+module_platform_driver(mtk_cec_driver);
+
+MODULE_DESCRIPTION("MediaTek HDMI CEC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 70dc1d4460ad..b389c08a371a 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1805,7 +1805,6 @@ static struct platform_driver mtk_hdmi_driver = {
 
 static struct platform_driver * const mtk_hdmi_drivers[] = {
 	&mtk_hdmi_ddc_driver,
-	&mtk_cec_driver,
 	&mtk_hdmi_driver,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.h b/drivers/gpu/drm/mediatek/mtk_hdmi.h
index 472bf141c92b..e40bc4651995 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.h
@@ -8,7 +8,6 @@
 
 struct platform_driver;
 
-extern struct platform_driver mtk_cec_driver;
 extern struct platform_driver mtk_hdmi_ddc_driver;
 
 #endif /* _MTK_HDMI_CTRL_H */
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:21 +0100
Subject: [PATCH v3 09/33] drm/mediatek: mtk_hdmi_ddc: Switch to register as module_platform_driver
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-10-angelogioacchino.delregno@collabora.com>

In preparation for splitting out the common bits from the HDMI
driver, change the mtk_cec driver from being registered from the
HDMI driver itself to be a module_platform_driver of its own.

With this change, there are no more users of the mtk_hdmi.h header
so, while at it, also remove it.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c     |  2 --
 drivers/gpu/drm/mediatek/mtk_hdmi.h     | 13 -------------
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c |  2 +-
 3 files changed, 1 insertion(+), 16 deletions(-)
 delete mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi.h

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index b389c08a371a..f620a61db2e0 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -31,7 +31,6 @@
 #include <drm/drm_probe_helper.h>
 
 #include "mtk_cec.h"
-#include "mtk_hdmi.h"
 #include "mtk_hdmi_regs.h"
 
 #define NCTS_BYTES	7
@@ -1804,7 +1803,6 @@ static struct platform_driver mtk_hdmi_driver = {
 };
 
 static struct platform_driver * const mtk_hdmi_drivers[] = {
-	&mtk_hdmi_ddc_driver,
 	&mtk_hdmi_driver,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.h b/drivers/gpu/drm/mediatek/mtk_hdmi.h
deleted file mode 100644
index e40bc4651995..000000000000
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2014 MediaTek Inc.
- * Author: Jie Qiu <jie.qiu at mediatek.com>
- */
-#ifndef _MTK_HDMI_CTRL_H
-#define _MTK_HDMI_CTRL_H
-
-struct platform_driver;
-
-extern struct platform_driver mtk_hdmi_ddc_driver;
-
-#endif /* _MTK_HDMI_CTRL_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c
index 07db68067844..6358e1af69b4 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c
@@ -20,7 +20,6 @@
 #include <linux/of_platform.h>
 
 #include "mtk_drm_drv.h"
-#include "mtk_hdmi.h"
 
 #define SIF1_CLOK		(288)
 #define DDC_DDCMCTL0		(0x0)
@@ -337,6 +336,7 @@ struct platform_driver mtk_hdmi_ddc_driver = {
 		.of_match_table = mtk_hdmi_ddc_match,
 	},
 };
+module_platform_driver(mtk_hdmi_ddc_driver);
 
 MODULE_AUTHOR("Jie Qiu <jie.qiu at mediatek.com>");
 MODULE_DESCRIPTION("MediaTek HDMI DDC Driver");
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:22 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:22 +0100
Subject: [PATCH v3 10/33] drm/mediatek: mtk_hdmi: Convert to module_platform_driver macro
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-11-angelogioacchino.delregno@collabora.com>

Now that all of the mtk_hdmi subdrivers are a platform driver on
their own it is possible to remove the custom init/exit functions
in this driver and just use the module_platform_driver() macro.

While at it, also compress struct of_device_id entries and remove
stray commas in mtk_hdmi_driver assignments.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index f620a61db2e0..59a8a81fa0ec 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1780,15 +1780,10 @@ static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 = {
 };
 
 static const struct of_device_id mtk_hdmi_of_ids[] = {
-	{ .compatible = "mediatek,mt2701-hdmi",
-	  .data = &mtk_hdmi_conf_mt2701,
-	},
-	{ .compatible = "mediatek,mt8167-hdmi",
-	  .data = &mtk_hdmi_conf_mt8167,
-	},
-	{ .compatible = "mediatek,mt8173-hdmi",
-	},
-	{}
+	{ .compatible = "mediatek,mt2701-hdmi", .data = &mtk_hdmi_conf_mt2701 },
+	{ .compatible = "mediatek,mt8167-hdmi", .data = &mtk_hdmi_conf_mt8167 },
+	{ .compatible = "mediatek,mt8173-hdmi" },
+	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mtk_hdmi_of_ids);
 
@@ -1798,28 +1793,10 @@ static struct platform_driver mtk_hdmi_driver = {
 	.driver = {
 		.name = "mediatek-drm-hdmi",
 		.of_match_table = mtk_hdmi_of_ids,
-		.pm = &mtk_hdmi_pm_ops,
-	},
-};
-
-static struct platform_driver * const mtk_hdmi_drivers[] = {
-	&mtk_hdmi_driver,
+		.pm = &mtk_hdmi_pm_ops
+	}
 };
-
-static int __init mtk_hdmitx_init(void)
-{
-	return platform_register_drivers(mtk_hdmi_drivers,
-					 ARRAY_SIZE(mtk_hdmi_drivers));
-}
-
-static void __exit mtk_hdmitx_exit(void)
-{
-	platform_unregister_drivers(mtk_hdmi_drivers,
-				    ARRAY_SIZE(mtk_hdmi_drivers));
-}
-
-module_init(mtk_hdmitx_init);
-module_exit(mtk_hdmitx_exit);
+module_platform_driver(mtk_hdmi_driver);
 
 MODULE_AUTHOR("Jie Qiu <jie.qiu at mediatek.com>");
 MODULE_DESCRIPTION("MediaTek HDMI Driver");
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:23 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:23 +0100
Subject: [PATCH v3 11/33] drm/mediatek: mtk_hdmi: Unregister audio platform device on failure
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-12-angelogioacchino.delregno@collabora.com>

The probe function of this driver may fail after registering the
audio platform device: in that case, the state is not getting
cleaned up, leaving this device registered.

Adding up to the mix, should the probe function of this driver
return a probe deferral for N times, we're registering up to N
audio platform devices and, again, never freeing them up.

To fix this, add a pointer to the audio platform device in the
mtk_hdmi structure, and add a devm action to unregister it upon
driver removal or probe failure.

Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 59a8a81fa0ec..9131c2fdfba8 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -172,6 +172,7 @@ struct mtk_hdmi {
 	unsigned int sys_offset;
 	void __iomem *regs;
 	enum hdmi_colorspace csp;
+	struct platform_device *audio_pdev;
 	struct hdmi_audio_param aud_param;
 	bool audio_enable;
 	bool powered;
@@ -1662,6 +1663,11 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
 	.no_capture_mute = 1,
 };
 
+static void mtk_hdmi_unregister_audio_driver(void *data)
+{
+	platform_device_unregister(data);
+}
+
 static int mtk_hdmi_register_audio_driver(struct device *dev)
 {
 	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
@@ -1671,13 +1677,22 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
 		.i2s = 1,
 		.data = hdmi,
 	};
-	struct platform_device *pdev;
+	int ret;
 
-	pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-					     PLATFORM_DEVID_AUTO, &codec_data,
-					     sizeof(codec_data));
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
+	hdmi->audio_pdev = platform_device_register_data(dev,
+							 HDMI_CODEC_DRV_NAME,
+							 PLATFORM_DEVID_AUTO,
+							 &codec_data,
+							 sizeof(codec_data));
+	if (IS_ERR(hdmi->audio_pdev))
+		return PTR_ERR(hdmi->audio_pdev);
+
+	ret = devm_add_action_or_reset(dev, mtk_hdmi_unregister_audio_driver,
+				       hdmi->audio_pdev);
+	if (ret) {
+		platform_device_unregister(hdmi->audio_pdev);
+		return ret;
+	}
 
 	DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
 	return 0;
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:24 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:24 +0100
Subject: [PATCH v3 12/33] drm/mediatek: hdmi: Use regmap instead of iomem for main registers
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-13-angelogioacchino.delregno@collabora.com>

From: Guillaume Ranquet <granquet at baylibre.com>

In preparation for the addition of a new version of the HDMI IP
which will need to share its iospace between multiple subdrivers,
and in preparation for moving out the common bits between the two,
migrate this driver to fully use regmap.

Signed-off-by: Guillaume Ranquet <granquet at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 173 +++++++++++-----------------
 1 file changed, 65 insertions(+), 108 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 9131c2fdfba8..d84fae1de2b0 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -170,7 +170,7 @@ struct mtk_hdmi {
 	u32 ibias_up;
 	struct regmap *sys_regmap;
 	unsigned int sys_offset;
-	void __iomem *regs;
+	struct regmap *regs;
 	enum hdmi_colorspace csp;
 	struct platform_device *audio_pdev;
 	struct hdmi_audio_param aud_param;
@@ -187,50 +187,10 @@ static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
 	return container_of(b, struct mtk_hdmi, bridge);
 }
 
-static u32 mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset)
-{
-	return readl(hdmi->regs + offset);
-}
-
-static void mtk_hdmi_write(struct mtk_hdmi *hdmi, u32 offset, u32 val)
-{
-	writel(val, hdmi->regs + offset);
-}
-
-static void mtk_hdmi_clear_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits)
-{
-	void __iomem *reg = hdmi->regs + offset;
-	u32 tmp;
-
-	tmp = readl(reg);
-	tmp &= ~bits;
-	writel(tmp, reg);
-}
-
-static void mtk_hdmi_set_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits)
-{
-	void __iomem *reg = hdmi->regs + offset;
-	u32 tmp;
-
-	tmp = readl(reg);
-	tmp |= bits;
-	writel(tmp, reg);
-}
-
-static void mtk_hdmi_mask(struct mtk_hdmi *hdmi, u32 offset, u32 val, u32 mask)
-{
-	void __iomem *reg = hdmi->regs + offset;
-	u32 tmp;
-
-	tmp = readl(reg);
-	tmp = (tmp & ~mask) | (val & mask);
-	writel(tmp, reg);
-}
-
 static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)
 {
-	mtk_hdmi_mask(hdmi, VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH,
-		      VIDEO_SOURCE_SEL);
+	regmap_update_bits(hdmi->regs, VIDEO_SOURCE_SEL,
+			   VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH);
 }
 
 static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable)
@@ -265,12 +225,12 @@ static void mtk_hdmi_hw_1p4_version_enable(struct mtk_hdmi *hdmi, bool enable)
 
 static void mtk_hdmi_hw_aud_mute(struct mtk_hdmi *hdmi)
 {
-	mtk_hdmi_set_bits(hdmi, GRL_AUDIO_CFG, AUDIO_ZERO);
+	regmap_set_bits(hdmi->regs, GRL_AUDIO_CFG, AUDIO_ZERO);
 }
 
 static void mtk_hdmi_hw_aud_unmute(struct mtk_hdmi *hdmi)
 {
-	mtk_hdmi_clear_bits(hdmi, GRL_AUDIO_CFG, AUDIO_ZERO);
+	regmap_clear_bits(hdmi->regs, GRL_AUDIO_CFG, AUDIO_ZERO);
 }
 
 static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi)
@@ -279,25 +239,25 @@ static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi)
 			   HDMI_RST, HDMI_RST);
 	regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C,
 			   HDMI_RST, 0);
-	mtk_hdmi_clear_bits(hdmi, GRL_CFG3, CFG3_CONTROL_PACKET_DELAY);
+	regmap_clear_bits(hdmi->regs, GRL_CFG3, CFG3_CONTROL_PACKET_DELAY);
 	regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C,
 			   ANLG_ON, ANLG_ON);
 }
 
 static void mtk_hdmi_hw_enable_notice(struct mtk_hdmi *hdmi, bool enable_notice)
 {
-	mtk_hdmi_mask(hdmi, GRL_CFG2, enable_notice ? CFG2_NOTICE_EN : 0,
-		      CFG2_NOTICE_EN);
+	regmap_update_bits(hdmi->regs, GRL_CFG2, CFG2_NOTICE_EN,
+			   enable_notice ? CFG2_NOTICE_EN : 0);
 }
 
 static void mtk_hdmi_hw_write_int_mask(struct mtk_hdmi *hdmi, u32 int_mask)
 {
-	mtk_hdmi_write(hdmi, GRL_INT_MASK, int_mask);
+	regmap_write(hdmi->regs, GRL_INT_MASK, int_mask);
 }
 
 static void mtk_hdmi_hw_enable_dvi_mode(struct mtk_hdmi *hdmi, bool enable)
 {
-	mtk_hdmi_mask(hdmi, GRL_CFG1, enable ? CFG1_DVI : 0, CFG1_DVI);
+	regmap_update_bits(hdmi->regs, GRL_CFG1, CFG1_DVI, enable ? CFG1_DVI : 0);
 }
 
 static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer,
@@ -343,22 +303,22 @@ static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer,
 		dev_err(hdmi->dev, "Unknown infoframe type %d\n", frame_type);
 		return;
 	}
-	mtk_hdmi_clear_bits(hdmi, ctrl_reg, ctrl_frame_en);
-	mtk_hdmi_write(hdmi, GRL_INFOFRM_TYPE, frame_type);
-	mtk_hdmi_write(hdmi, GRL_INFOFRM_VER, frame_ver);
-	mtk_hdmi_write(hdmi, GRL_INFOFRM_LNG, frame_len);
+	regmap_clear_bits(hdmi->regs, ctrl_reg, ctrl_frame_en);
+	regmap_write(hdmi->regs, GRL_INFOFRM_TYPE, frame_type);
+	regmap_write(hdmi->regs, GRL_INFOFRM_VER, frame_ver);
+	regmap_write(hdmi->regs, GRL_INFOFRM_LNG, frame_len);
 
-	mtk_hdmi_write(hdmi, GRL_IFM_PORT, checksum);
+	regmap_write(hdmi->regs, GRL_IFM_PORT, checksum);
 	for (i = 0; i < frame_len; i++)
-		mtk_hdmi_write(hdmi, GRL_IFM_PORT, frame_data[i]);
+		regmap_write(hdmi->regs, GRL_IFM_PORT, frame_data[i]);
 
-	mtk_hdmi_set_bits(hdmi, ctrl_reg, ctrl_frame_en);
+	regmap_set_bits(hdmi->regs, ctrl_reg, ctrl_frame_en);
 }
 
 static void mtk_hdmi_hw_send_aud_packet(struct mtk_hdmi *hdmi, bool enable)
 {
-	mtk_hdmi_mask(hdmi, GRL_SHIFT_R2, enable ? 0 : AUDIO_PACKET_OFF,
-		      AUDIO_PACKET_OFF);
+	regmap_update_bits(hdmi->regs, AUDIO_PACKET_OFF,
+			   GRL_SHIFT_R2, enable ? 0 : AUDIO_PACKET_OFF);
 }
 
 static void mtk_hdmi_hw_config_sys(struct mtk_hdmi *hdmi)
@@ -379,44 +339,44 @@ static void mtk_hdmi_hw_set_deep_color_mode(struct mtk_hdmi *hdmi)
 
 static void mtk_hdmi_hw_send_av_mute(struct mtk_hdmi *hdmi)
 {
-	mtk_hdmi_clear_bits(hdmi, GRL_CFG4, CTRL_AVMUTE);
+	regmap_clear_bits(hdmi->regs, GRL_CFG4, CTRL_AVMUTE);
 	usleep_range(2000, 4000);
-	mtk_hdmi_set_bits(hdmi, GRL_CFG4, CTRL_AVMUTE);
+	regmap_set_bits(hdmi->regs, GRL_CFG4, CTRL_AVMUTE);
 }
 
 static void mtk_hdmi_hw_send_av_unmute(struct mtk_hdmi *hdmi)
 {
-	mtk_hdmi_mask(hdmi, GRL_CFG4, CFG4_AV_UNMUTE_EN,
-		      CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET);
+	regmap_update_bits(hdmi->regs, GRL_CFG4, CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET,
+			   CFG4_AV_UNMUTE_EN);
 	usleep_range(2000, 4000);
-	mtk_hdmi_mask(hdmi, GRL_CFG4, CFG4_AV_UNMUTE_SET,
-		      CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET);
+	regmap_update_bits(hdmi->regs, GRL_CFG4, CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET,
+			   CFG4_AV_UNMUTE_SET);
 }
 
 static void mtk_hdmi_hw_ncts_enable(struct mtk_hdmi *hdmi, bool on)
 {
-	mtk_hdmi_mask(hdmi, GRL_CTS_CTRL, on ? 0 : CTS_CTRL_SOFT,
-		      CTS_CTRL_SOFT);
+	regmap_update_bits(hdmi->regs, GRL_CTS_CTRL, CTS_CTRL_SOFT,
+			   on ? 0 : CTS_CTRL_SOFT);
 }
 
 static void mtk_hdmi_hw_ncts_auto_write_enable(struct mtk_hdmi *hdmi,
 					       bool enable)
 {
-	mtk_hdmi_mask(hdmi, GRL_CTS_CTRL, enable ? NCTS_WRI_ANYTIME : 0,
-		      NCTS_WRI_ANYTIME);
+	regmap_update_bits(hdmi->regs, GRL_CTS_CTRL, NCTS_WRI_ANYTIME,
+			   enable ? NCTS_WRI_ANYTIME : 0);
 }
 
 static void mtk_hdmi_hw_msic_setting(struct mtk_hdmi *hdmi,
 				     struct drm_display_mode *mode)
 {
-	mtk_hdmi_clear_bits(hdmi, GRL_CFG4, CFG4_MHL_MODE);
+	regmap_clear_bits(hdmi->regs, GRL_CFG4, CFG4_MHL_MODE);
 
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE &&
 	    mode->clock == 74250 &&
 	    mode->vdisplay == 1080)
-		mtk_hdmi_clear_bits(hdmi, GRL_CFG2, CFG2_MHL_DE_SEL);
+		regmap_clear_bits(hdmi->regs, GRL_CFG2, CFG2_MHL_DE_SEL);
 	else
-		mtk_hdmi_set_bits(hdmi, GRL_CFG2, CFG2_MHL_DE_SEL);
+		regmap_set_bits(hdmi->regs, GRL_CFG2, CFG2_MHL_DE_SEL);
 }
 
 static void mtk_hdmi_hw_aud_set_channel_swap(struct mtk_hdmi *hdmi,
@@ -444,7 +404,7 @@ static void mtk_hdmi_hw_aud_set_channel_swap(struct mtk_hdmi *hdmi,
 		swap_bit = LFE_CC_SWAP;
 		break;
 	}
-	mtk_hdmi_mask(hdmi, GRL_CH_SWAP, swap_bit, 0xff);
+	regmap_update_bits(hdmi->regs, GRL_CH_SWAP, 0xff, swap_bit);
 }
 
 static void mtk_hdmi_hw_aud_set_bit_num(struct mtk_hdmi *hdmi,
@@ -465,7 +425,7 @@ static void mtk_hdmi_hw_aud_set_bit_num(struct mtk_hdmi *hdmi,
 		break;
 	}
 
-	mtk_hdmi_mask(hdmi, GRL_AOUT_CFG, val, AOUT_BNUM_SEL_MASK);
+	regmap_update_bits(hdmi->regs, GRL_AOUT_CFG, AOUT_BNUM_SEL_MASK, val);
 }
 
 static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi,
@@ -473,7 +433,7 @@ static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi,
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_CFG0);
+	regmap_read(hdmi->regs, GRL_CFG0, &val);
 	val &= ~(CFG0_W_LENGTH_MASK | CFG0_I2S_MODE_MASK);
 
 	switch (i2s_fmt) {
@@ -497,7 +457,7 @@ static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi,
 		val |= CFG0_I2S_MODE_I2S | CFG0_W_LENGTH_16BIT;
 		break;
 	}
-	mtk_hdmi_write(hdmi, GRL_CFG0, val);
+	regmap_write(hdmi->regs, GRL_CFG0, val);
 }
 
 static void mtk_hdmi_hw_audio_config(struct mtk_hdmi *hdmi, bool dst)
@@ -506,14 +466,14 @@ static void mtk_hdmi_hw_audio_config(struct mtk_hdmi *hdmi, bool dst)
 	u8 val;
 
 	/* Disable high bitrate, set DST packet normal/double */
-	mtk_hdmi_clear_bits(hdmi, GRL_AOUT_CFG, HIGH_BIT_RATE_PACKET_ALIGN);
+	regmap_clear_bits(hdmi->regs, GRL_AOUT_CFG, HIGH_BIT_RATE_PACKET_ALIGN);
 
 	if (dst)
 		val = DST_NORMAL_DOUBLE | SACD_DST;
 	else
 		val = 0;
 
-	mtk_hdmi_mask(hdmi, GRL_AUDIO_CFG, val, mask);
+	regmap_update_bits(hdmi->regs, GRL_AUDIO_CFG, mask, val);
 }
 
 static void mtk_hdmi_hw_aud_set_i2s_chan_num(struct mtk_hdmi *hdmi,
@@ -554,10 +514,10 @@ static void mtk_hdmi_hw_aud_set_i2s_chan_num(struct mtk_hdmi *hdmi,
 		i2s_uv = I2S_UV_CH_EN(0);
 	}
 
-	mtk_hdmi_write(hdmi, GRL_CH_SW0, ch_switch & 0xff);
-	mtk_hdmi_write(hdmi, GRL_CH_SW1, (ch_switch >> 8) & 0xff);
-	mtk_hdmi_write(hdmi, GRL_CH_SW2, (ch_switch >> 16) & 0xff);
-	mtk_hdmi_write(hdmi, GRL_I2S_UV, i2s_uv);
+	regmap_write(hdmi->regs, GRL_CH_SW0, ch_switch & 0xff);
+	regmap_write(hdmi->regs, GRL_CH_SW1, (ch_switch >> 8) & 0xff);
+	regmap_write(hdmi->regs, GRL_CH_SW2, (ch_switch >> 16) & 0xff);
+	regmap_write(hdmi->regs, GRL_I2S_UV, i2s_uv);
 }
 
 static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi,
@@ -565,7 +525,7 @@ static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi,
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_CFG1);
+	regmap_read(hdmi->regs, GRL_CFG1, &val);
 	if (input_type == HDMI_AUD_INPUT_I2S &&
 	    (val & CFG1_SPDIF) == CFG1_SPDIF) {
 		val &= ~CFG1_SPDIF;
@@ -573,7 +533,7 @@ static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi,
 		(val & CFG1_SPDIF) == 0) {
 		val |= CFG1_SPDIF;
 	}
-	mtk_hdmi_write(hdmi, GRL_CFG1, val);
+	regmap_write(hdmi->regs, GRL_CFG1, val);
 }
 
 static void mtk_hdmi_hw_aud_set_channel_status(struct mtk_hdmi *hdmi,
@@ -582,13 +542,13 @@ static void mtk_hdmi_hw_aud_set_channel_status(struct mtk_hdmi *hdmi,
 	int i;
 
 	for (i = 0; i < 5; i++) {
-		mtk_hdmi_write(hdmi, GRL_I2S_C_STA0 + i * 4, channel_status[i]);
-		mtk_hdmi_write(hdmi, GRL_L_STATUS_0 + i * 4, channel_status[i]);
-		mtk_hdmi_write(hdmi, GRL_R_STATUS_0 + i * 4, channel_status[i]);
+		regmap_write(hdmi->regs, GRL_I2S_C_STA0 + i * 4, channel_status[i]);
+		regmap_write(hdmi->regs, GRL_L_STATUS_0 + i * 4, channel_status[i]);
+		regmap_write(hdmi->regs, GRL_R_STATUS_0 + i * 4, channel_status[i]);
 	}
 	for (; i < 24; i++) {
-		mtk_hdmi_write(hdmi, GRL_L_STATUS_0 + i * 4, 0);
-		mtk_hdmi_write(hdmi, GRL_R_STATUS_0 + i * 4, 0);
+		regmap_write(hdmi->regs, GRL_L_STATUS_0 + i * 4, 0);
+		regmap_write(hdmi->regs, GRL_R_STATUS_0 + i * 4, 0);
 	}
 }
 
@@ -596,13 +556,13 @@ static void mtk_hdmi_hw_aud_src_reenable(struct mtk_hdmi *hdmi)
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL);
+	regmap_read(hdmi->regs, GRL_MIX_CTRL, &val);
 	if (val & MIX_CTRL_SRC_EN) {
 		val &= ~MIX_CTRL_SRC_EN;
-		mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);
+		regmap_write(hdmi->regs, GRL_MIX_CTRL, val);
 		usleep_range(255, 512);
 		val |= MIX_CTRL_SRC_EN;
-		mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);
+		regmap_write(hdmi->regs, GRL_MIX_CTRL, val);
 	}
 }
 
@@ -610,10 +570,10 @@ static void mtk_hdmi_hw_aud_src_disable(struct mtk_hdmi *hdmi)
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL);
+	regmap_read(hdmi->regs, GRL_MIX_CTRL, &val);
 	val &= ~MIX_CTRL_SRC_EN;
-	mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);
-	mtk_hdmi_write(hdmi, GRL_SHIFT_L1, 0x00);
+	regmap_write(hdmi->regs, GRL_MIX_CTRL, val);
+	regmap_write(hdmi->regs, GRL_SHIFT_L1, 0x00);
 }
 
 static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
@@ -621,7 +581,7 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
 {
 	u32 val;
 
-	val = mtk_hdmi_read(hdmi, GRL_CFG5);
+	regmap_read(hdmi->regs, GRL_CFG5, &val);
 	val &= CFG5_CD_RATIO_MASK;
 
 	switch (mclk) {
@@ -644,7 +604,7 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
 		val |= CFG5_FS256;
 		break;
 	}
-	mtk_hdmi_write(hdmi, GRL_CFG5, val);
+	regmap_write(hdmi->regs, GRL_CFG5, val);
 }
 
 struct hdmi_acr_n {
@@ -728,9 +688,9 @@ static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,
 	unsigned char val[NCTS_BYTES];
 	int i;
 
-	mtk_hdmi_write(hdmi, GRL_NCTS, 0);
-	mtk_hdmi_write(hdmi, GRL_NCTS, 0);
-	mtk_hdmi_write(hdmi, GRL_NCTS, 0);
+	regmap_write(hdmi->regs, GRL_NCTS, 0);
+	regmap_write(hdmi->regs, GRL_NCTS, 0);
+	regmap_write(hdmi->regs, GRL_NCTS, 0);
 	memset(val, 0, sizeof(val));
 
 	val[0] = (cts >> 24) & 0xff;
@@ -743,7 +703,7 @@ static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,
 	val[6] = n & 0xff;
 
 	for (i = 0; i < NCTS_BYTES; i++)
-		mtk_hdmi_write(hdmi, GRL_NCTS, val[i]);
+		regmap_write(hdmi->regs, GRL_NCTS, val[i]);
 }
 
 static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
@@ -758,8 +718,7 @@ static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
 	dev_dbg(hdmi->dev, "%s: sample_rate=%u, clock=%d, cts=%u, n=%u\n",
 		__func__, sample_rate, clock, n, cts);
 
-	mtk_hdmi_mask(hdmi, DUMMY_304, AUDIO_I2S_NCTS_SEL_64,
-		      AUDIO_I2S_NCTS_SEL);
+	regmap_update_bits(hdmi->regs, DUMMY_304, AUDIO_I2S_NCTS_SEL, AUDIO_I2S_NCTS_SEL_64);
 	do_hdmi_hw_aud_set_ncts(hdmi, n, cts);
 }
 
@@ -879,7 +838,7 @@ static void mtk_hdmi_aud_set_input(struct mtk_hdmi *hdmi)
 	bool dst;
 
 	mtk_hdmi_hw_aud_set_channel_swap(hdmi, HDMI_AUD_SWAP_LFE_CC);
-	mtk_hdmi_set_bits(hdmi, GRL_MIX_CTRL, MIX_CTRL_FLAT);
+	regmap_set_bits(hdmi->regs, GRL_MIX_CTRL, MIX_CTRL_FLAT);
 
 	if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_SPDIF &&
 	    hdmi->aud_param.aud_codec == HDMI_AUDIO_CODING_TYPE_DST) {
@@ -911,7 +870,7 @@ static int mtk_hdmi_aud_set_src(struct mtk_hdmi *hdmi,
 
 	mtk_hdmi_hw_ncts_enable(hdmi, false);
 	mtk_hdmi_hw_aud_src_disable(hdmi);
-	mtk_hdmi_clear_bits(hdmi, GRL_CFG2, CFG2_ACLK_INV);
+	regmap_clear_bits(hdmi->regs, GRL_CFG2, CFG2_ACLK_INV);
 
 	if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_I2S) {
 		switch (sample_rate) {
@@ -1425,7 +1384,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 	struct device_node *cec_np, *remote, *i2c_np;
 	struct platform_device *cec_pdev;
 	struct regmap *regmap;
-	struct resource *mem;
 	int ret;
 
 	ret = mtk_hdmi_get_all_clk(hdmi, np);
@@ -1471,8 +1429,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 	}
 	hdmi->sys_regmap = regmap;
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdmi->regs = devm_ioremap_resource(dev, mem);
+	hdmi->regs = device_node_to_regmap(dev->of_node);
 	if (IS_ERR(hdmi->regs)) {
 		ret = PTR_ERR(hdmi->regs);
 		goto put_device;
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:25 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:25 +0100
Subject: [PATCH v3 13/33] drm/mediatek: mtk_hdmi: Fix typo for aud_sampe_size member
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-14-angelogioacchino.delregno@collabora.com>

Rename member aud_sampe_size of struct hdmi_audio_param to
aud_sample_size to fix a typo and enhance readability.

This commit brings no functional changes.

Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index d84fae1de2b0..d2f1d6286fbc 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -136,7 +136,7 @@ enum hdmi_aud_channel_swap_type {
 
 struct hdmi_audio_param {
 	enum hdmi_audio_coding_type aud_codec;
-	enum hdmi_audio_sample_size aud_sampe_size;
+	enum hdmi_audio_sample_size aud_sample_size;
 	enum hdmi_aud_input_type aud_input_type;
 	enum hdmi_aud_i2s_fmt aud_i2s_fmt;
 	enum hdmi_aud_mclk aud_mclk;
@@ -1033,7 +1033,7 @@ static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
 
 	hdmi->csp = HDMI_COLORSPACE_RGB;
 	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-	aud_param->aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
 	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
 	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
 	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
@@ -1529,14 +1529,14 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
 	switch (daifmt->fmt) {
 	case HDMI_I2S:
 		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
 		hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
 		hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
 		hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
 		break;
 	case HDMI_SPDIF:
 		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
 		hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
 		break;
 	default:
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:26 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:26 +0100
Subject: [PATCH v3 14/33] drm/mediatek: mtk_hdmi: Move audio params selection to new function
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-15-angelogioacchino.delregno@collabora.com>

In preparation for splitting common bits of this driver, move the
audio params (codec, sample rate/size, input type, i2s format, etc)
selection to a new function called mtk_hdmi_audio_params().

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index d2f1d6286fbc..8f5ab97a0261 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1479,12 +1479,11 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
  * HDMI audio codec callbacks
  */
 
-static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
-				    struct hdmi_codec_daifmt *daifmt,
-				    struct hdmi_codec_params *params)
+static int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi,
+				 struct hdmi_codec_daifmt *daifmt,
+				 struct hdmi_codec_params *params)
 {
-	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-	struct hdmi_audio_param hdmi_params;
+	struct hdmi_audio_param aud_params = { 0 };
 	unsigned int chan = params->cea.channels;
 
 	dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
@@ -1495,16 +1494,16 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
 
 	switch (chan) {
 	case 2:
-		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
 		break;
 	case 4:
-		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
 		break;
 	case 6:
-		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
 		break;
 	case 8:
-		hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
 		break;
 	default:
 		dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
@@ -1528,26 +1527,35 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
 
 	switch (daifmt->fmt) {
 	case HDMI_I2S:
-		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
-		hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
-		hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
-		hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
+		aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+		aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		aud_params.aud_input_type = HDMI_AUD_INPUT_I2S;
+		aud_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
+		aud_params.aud_mclk = HDMI_AUD_MCLK_128FS;
 		break;
 	case HDMI_SPDIF:
-		hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
-		hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
+		aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+		aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		aud_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
 		break;
 	default:
 		dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,
 			daifmt->fmt);
 		return -EINVAL;
 	}
+	memcpy(&aud_params.codec_params, params, sizeof(aud_params.codec_params));
+
+	return 0;
+}
 
-	memcpy(&hdmi_params.codec_params, params,
-	       sizeof(hdmi_params.codec_params));
+static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
+				    struct hdmi_codec_daifmt *daifmt,
+				    struct hdmi_codec_params *params)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	struct hdmi_audio_param hdmi_params;
 
+	mtk_hdmi_audio_params(hdmi, daifmt, params);
 	mtk_hdmi_audio_set_param(hdmi, &hdmi_params);
 
 	return 0;
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:34 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:34 +0100
Subject: [PATCH v3 22/33] drm/mediatek: mtk_hdmi: Move output init to mtk_hdmi_register_audio_driver()
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-23-angelogioacchino.delregno@collabora.com>

In preparation for moving the common bits of this driver, merge the
contents of mtk_hdmi_output_init in mtk_hdmi_register_audio_driver
function.

While at it, also remove the "%s driver bound to HDMI" debugging
print disguised as informative.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 3ecd0ed59851..2d5cf7352ed2 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1025,20 +1025,6 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi,
 	return 0;
 }
 
-static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
-{
-	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
-
-	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
-	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
-	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
-	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
-	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
-
-	return 0;
-}
-
 static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)
 {
 	mtk_hdmi_hw_send_aud_packet(hdmi, true);
@@ -1617,6 +1603,7 @@ static void mtk_hdmi_unregister_audio_driver(void *data)
 static int mtk_hdmi_register_audio_driver(struct device *dev)
 {
 	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
 	struct hdmi_codec_pdata codec_data = {
 		.ops = &mtk_hdmi_audio_codec_ops,
 		.max_i2s_channels = 2,
@@ -1625,6 +1612,13 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
 	};
 	int ret;
 
+	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
+	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
+	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
+	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
+
 	hdmi->audio_pdev = platform_device_register_data(dev,
 							 HDMI_CODEC_DRV_NAME,
 							 PLATFORM_DEVID_AUTO,
@@ -1640,7 +1634,6 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
 		return ret;
 	}
 
-	DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
 	return 0;
 }
 
@@ -1669,11 +1662,6 @@ static int mtk_hdmi_probe(struct platform_device *pdev)
 	mutex_init(&hdmi->update_plugged_status_lock);
 	platform_set_drvdata(pdev, hdmi);
 
-	ret = mtk_hdmi_output_init(hdmi);
-	if (ret)
-		return dev_err_probe(dev, ret,
-				     "Failed to initialize hdmi output\n");
-
 	ret = mtk_hdmi_register_audio_driver(dev);
 	if (ret)
 		return dev_err_probe(dev, ret,
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:35 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:35 +0100
Subject: [PATCH v3 23/33] drm/mediatek: mtk_hdmi: Use devm managed version of drm_bridge_add
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-24-angelogioacchino.delregno@collabora.com>

Simplify the probe/remove functions by using devm_drm_bridge_add()
as now there is no more need to manually remove the bridge.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 2d5cf7352ed2..5d46d486c68f 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1674,14 +1674,15 @@ static int mtk_hdmi_probe(struct platform_device *pdev)
 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	hdmi->bridge.vendor = "MediaTek";
 	hdmi->bridge.product = "On-Chip HDMI";
-	drm_bridge_add(&hdmi->bridge);
+
+	ret = devm_drm_bridge_add(dev, &hdmi->bridge);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to add bridge\n");
 
 	ret = mtk_hdmi_clk_enable_audio(hdmi);
-	if (ret) {
-		drm_bridge_remove(&hdmi->bridge);
+	if (ret)
 		return dev_err_probe(dev, ret,
 				     "Failed to enable audio clocks\n");
-	}
 
 	return 0;
 }
@@ -1690,7 +1691,6 @@ static void mtk_hdmi_remove(struct platform_device *pdev)
 {
 	struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
 
-	drm_bridge_remove(&hdmi->bridge);
 	mtk_hdmi_clk_disable_audio(hdmi);
 }
 
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:36 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:36 +0100
Subject: [PATCH v3 24/33] drm/mediatek: mtk_hdmi: Remove ifdef for CONFIG_PM_SLEEP
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-25-angelogioacchino.delregno@collabora.com>

Since the SIMPLE_DEV_PM_OPS macro and the pm pointer are anyway
defined when CONFIG_PM_SLEEP is not set, remove the ifdef for it
and indicate that the mtk_hdmi_{remove,suspend} functions may be
unused (as they are, in case PM support is not built-in).

While at it, to improve readability, also compress the
SIMPLE_DEV_PM_OPS declaration as it even fits in less
than 80 columns.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 5d46d486c68f..7e4536391cfb 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1694,8 +1694,7 @@ static void mtk_hdmi_remove(struct platform_device *pdev)
 	mtk_hdmi_clk_disable_audio(hdmi);
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int mtk_hdmi_suspend(struct device *dev)
+static __maybe_unused int mtk_hdmi_suspend(struct device *dev)
 {
 	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
 
@@ -1704,7 +1703,7 @@ static int mtk_hdmi_suspend(struct device *dev)
 	return 0;
 }
 
-static int mtk_hdmi_resume(struct device *dev)
+static __maybe_unused int mtk_hdmi_resume(struct device *dev)
 {
 	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
 	int ret = 0;
@@ -1717,9 +1716,8 @@ static int mtk_hdmi_resume(struct device *dev)
 
 	return 0;
 }
-#endif
-static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops,
-			 mtk_hdmi_suspend, mtk_hdmi_resume);
+
+static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops, mtk_hdmi_suspend, mtk_hdmi_resume);
 
 static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = {
 	.tz_disabled = true,
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:37 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:37 +0100
Subject: [PATCH v3 25/33] drm/mediatek: mtk_hdmi: Remove goto in mtk_hdmi_clk_enable_audio()
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-26-angelogioacchino.delregno@collabora.com>

If the clk_prepare_enable() call for the SPDIF clock fails, just
disable and unprepare the clock in the error check branch and
return immediately instead of jumping to the end with a goto,
slightly reducing code size.

This commit brings no functional changes.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 7e4536391cfb..dbcb9fb09edd 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1095,13 +1095,12 @@ static int mtk_hdmi_clk_enable_audio(struct mtk_hdmi *hdmi)
 		return ret;
 
 	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]);
-	if (ret)
-		goto err;
+	if (ret) {
+		clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);
+		return ret;
+	}
 
 	return 0;
-err:
-	clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);
-	return ret;
 }
 
 static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi)
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:38 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:38 +0100
Subject: [PATCH v3 26/33] drm/mediatek: mtk_hdmi: Cleanup function mtk_hdmi_resume()
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-27-angelogioacchino.delregno@collabora.com>

Remove the error print in case of mtk_hdmi_clk_enable_audio()
failures: since the APIs will already print on their own, having
one in there is redundant.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index dbcb9fb09edd..6c9d046809b2 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1705,15 +1705,8 @@ static __maybe_unused int mtk_hdmi_suspend(struct device *dev)
 static __maybe_unused int mtk_hdmi_resume(struct device *dev)
 {
 	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-	int ret = 0;
 
-	ret = mtk_hdmi_clk_enable_audio(hdmi);
-	if (ret) {
-		dev_err(dev, "hdmi resume failed!\n");
-		return ret;
-	}
-
-	return 0;
+	return mtk_hdmi_clk_enable_audio(hdmi);
 }
 
 static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops, mtk_hdmi_suspend, mtk_hdmi_resume);
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:39 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:39 +0100
Subject: [PATCH v3 27/33] drm/mediatek: mtk_hdmi: Improve mtk_hdmi_get_all_clk() flexibility
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-28-angelogioacchino.delregno@collabora.com>

In preparation for splitting common bits of this driver and for
introducing a new version of the MediaTek HDMI Encoder IP, improve
the flexibility	of function mtk_hdmi_get_all_clk() by adding a
pointer to the clock names array and size of it to its parameters.

Also change the array of struct clock pointers in the mtk_hdmi
structure to be dynamically allocated, and allocate it in probe.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 6c9d046809b2..4dc7113fee10 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -159,7 +159,7 @@ struct mtk_hdmi {
 	struct phy *phy;
 	struct device *cec_dev;
 	struct i2c_adapter *ddc_adpt;
-	struct clk *clk[MTK_HDMI_CLK_COUNT];
+	struct clk **clk;
 	struct drm_display_mode mode;
 	bool dvi_mode;
 	struct regmap *sys_regmap;
@@ -1072,17 +1072,18 @@ static const char * const mtk_hdmi_clk_names[MTK_HDMI_CLK_COUNT] = {
 	[MTK_HDMI_CLK_AUD_SPDIF] = "spdif",
 };
 
-static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi,
-				struct device_node *np)
+static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi, struct device_node *np,
+				const char * const *clock_names, size_t num_clocks)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(mtk_hdmi_clk_names); i++) {
-		hdmi->clk[i] = of_clk_get_by_name(np,
-						  mtk_hdmi_clk_names[i]);
+	for (i = 0; i < num_clocks; i++) {
+		hdmi->clk[i] = of_clk_get_by_name(np, clock_names[i]);
+
 		if (IS_ERR(hdmi->clk[i]))
 			return PTR_ERR(hdmi->clk[i]);
 	}
+
 	return 0;
 }
 
@@ -1381,15 +1382,15 @@ static int mtk_hdmi_get_cec_dev(struct mtk_hdmi *hdmi, struct device *dev, struc
 	return 0;
 }
 
-static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
-				   struct platform_device *pdev)
+static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device *pdev,
+				   const char * const *clk_names, size_t num_clocks)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct device_node *remote, *i2c_np;
 	int ret;
 
-	ret = mtk_hdmi_get_all_clk(hdmi, np);
+	ret = mtk_hdmi_get_all_clk(hdmi, np, clk_names, num_clocks);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to get clocks\n");
 
@@ -1640,6 +1641,7 @@ static int mtk_hdmi_probe(struct platform_device *pdev)
 {
 	struct mtk_hdmi *hdmi;
 	struct device *dev = &pdev->dev;
+	const int num_clocks = MTK_HDMI_CLK_COUNT;
 	int ret;
 
 	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
@@ -1649,7 +1651,11 @@ static int mtk_hdmi_probe(struct platform_device *pdev)
 	hdmi->dev = dev;
 	hdmi->conf = of_device_get_match_data(dev);
 
-	ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev);
+	hdmi->clk = devm_kcalloc(dev, num_clocks, sizeof(*hdmi->clk), GFP_KERNEL);
+	if (!hdmi->clk)
+		return -ENOMEM;
+
+	ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, mtk_hdmi_clk_names, num_clocks);
 	if (ret)
 		return ret;
 
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:40 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:40 +0100
Subject: [PATCH v3 28/33] drm/mediatek: mtk_hdmi: Split driver and add common probe function
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-29-angelogioacchino.delregno@collabora.com>

In preparation for adding a new driver for the HDMI TX v2 IP,
split out the functions that will be common between the already
present mtk_hdmi (v1) driver and the new one.

Since the probe flow for both drivers is 90% similar, add a common
probe function that will be called from each driver's .probe()
callback, avoiding lots of code duplication.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/Kconfig           |  11 +-
 drivers/gpu/drm/mediatek/Makefile          |   1 +
 drivers/gpu/drm/mediatek/mtk_hdmi.c        | 553 +--------------------
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 421 ++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h | 188 +++++++
 5 files changed, 642 insertions(+), 532 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.h

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index f496e6cfdfe0..73459f07dae3 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -34,10 +34,19 @@ config DRM_MEDIATEK_DP
 	help
 	  DRM/KMS Display Port driver for MediaTek SoCs.
 
+config DRM_MEDIATEK_HDMI_COMMON
+	tristate
+	depends on DRM_MEDIATEK
+	select DRM_DISPLAY_HDMI_HELPER
+	select DRM_DISPLAY_HELPER
+	select SND_SOC_HDMI_CODEC if SND_SOC
+	help
+	  MediaTek SoC HDMI common library
+
 config DRM_MEDIATEK_HDMI
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
-	select SND_SOC_HDMI_CODEC if SND_SOC
+	select DRM_MEDIATEK_HDMI_COMMON
 	select PHY_MTK_HDMI
 	help
 	  DRM/KMS HDMI driver for Mediatek SoCs
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 32a2ed6c0cfe..8973d7ba37d3 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -25,6 +25,7 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
 			  mtk_hdmi.o \
 			  mtk_hdmi_ddc.o
 
+obj-$(CONFIG_DRM_MEDIATEK_HDMI_COMMON) += mtk_hdmi_common.o
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
 
 obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 4dc7113fee10..b8d5c3e1f494 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -31,6 +31,7 @@
 #include <drm/drm_probe_helper.h>
 
 #include "mtk_cec.h"
+#include "mtk_hdmi_common.h"
 #include "mtk_hdmi_regs.h"
 
 #define NCTS_BYTES	7
@@ -43,143 +44,6 @@ enum mtk_hdmi_clk_id {
 	MTK_HDMI_CLK_COUNT
 };
 
-enum hdmi_aud_input_type {
-	HDMI_AUD_INPUT_I2S = 0,
-	HDMI_AUD_INPUT_SPDIF,
-};
-
-enum hdmi_aud_i2s_fmt {
-	HDMI_I2S_MODE_RJT_24BIT = 0,
-	HDMI_I2S_MODE_RJT_16BIT,
-	HDMI_I2S_MODE_LJT_24BIT,
-	HDMI_I2S_MODE_LJT_16BIT,
-	HDMI_I2S_MODE_I2S_24BIT,
-	HDMI_I2S_MODE_I2S_16BIT
-};
-
-enum hdmi_aud_mclk {
-	HDMI_AUD_MCLK_128FS,
-	HDMI_AUD_MCLK_192FS,
-	HDMI_AUD_MCLK_256FS,
-	HDMI_AUD_MCLK_384FS,
-	HDMI_AUD_MCLK_512FS,
-	HDMI_AUD_MCLK_768FS,
-	HDMI_AUD_MCLK_1152FS,
-};
-
-enum hdmi_aud_channel_type {
-	HDMI_AUD_CHAN_TYPE_1_0 = 0,
-	HDMI_AUD_CHAN_TYPE_1_1,
-	HDMI_AUD_CHAN_TYPE_2_0,
-	HDMI_AUD_CHAN_TYPE_2_1,
-	HDMI_AUD_CHAN_TYPE_3_0,
-	HDMI_AUD_CHAN_TYPE_3_1,
-	HDMI_AUD_CHAN_TYPE_4_0,
-	HDMI_AUD_CHAN_TYPE_4_1,
-	HDMI_AUD_CHAN_TYPE_5_0,
-	HDMI_AUD_CHAN_TYPE_5_1,
-	HDMI_AUD_CHAN_TYPE_6_0,
-	HDMI_AUD_CHAN_TYPE_6_1,
-	HDMI_AUD_CHAN_TYPE_7_0,
-	HDMI_AUD_CHAN_TYPE_7_1,
-	HDMI_AUD_CHAN_TYPE_3_0_LRS,
-	HDMI_AUD_CHAN_TYPE_3_1_LRS,
-	HDMI_AUD_CHAN_TYPE_4_0_CLRS,
-	HDMI_AUD_CHAN_TYPE_4_1_CLRS,
-	HDMI_AUD_CHAN_TYPE_6_1_CS,
-	HDMI_AUD_CHAN_TYPE_6_1_CH,
-	HDMI_AUD_CHAN_TYPE_6_1_OH,
-	HDMI_AUD_CHAN_TYPE_6_1_CHR,
-	HDMI_AUD_CHAN_TYPE_7_1_LH_RH,
-	HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR,
-	HDMI_AUD_CHAN_TYPE_7_1_LC_RC,
-	HDMI_AUD_CHAN_TYPE_7_1_LW_RW,
-	HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD,
-	HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS,
-	HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS,
-	HDMI_AUD_CHAN_TYPE_7_1_CS_CH,
-	HDMI_AUD_CHAN_TYPE_7_1_CS_OH,
-	HDMI_AUD_CHAN_TYPE_7_1_CS_CHR,
-	HDMI_AUD_CHAN_TYPE_7_1_CH_OH,
-	HDMI_AUD_CHAN_TYPE_7_1_CH_CHR,
-	HDMI_AUD_CHAN_TYPE_7_1_OH_CHR,
-	HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR,
-	HDMI_AUD_CHAN_TYPE_6_0_CS,
-	HDMI_AUD_CHAN_TYPE_6_0_CH,
-	HDMI_AUD_CHAN_TYPE_6_0_OH,
-	HDMI_AUD_CHAN_TYPE_6_0_CHR,
-	HDMI_AUD_CHAN_TYPE_7_0_LH_RH,
-	HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR,
-	HDMI_AUD_CHAN_TYPE_7_0_LC_RC,
-	HDMI_AUD_CHAN_TYPE_7_0_LW_RW,
-	HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD,
-	HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS,
-	HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS,
-	HDMI_AUD_CHAN_TYPE_7_0_CS_CH,
-	HDMI_AUD_CHAN_TYPE_7_0_CS_OH,
-	HDMI_AUD_CHAN_TYPE_7_0_CS_CHR,
-	HDMI_AUD_CHAN_TYPE_7_0_CH_OH,
-	HDMI_AUD_CHAN_TYPE_7_0_CH_CHR,
-	HDMI_AUD_CHAN_TYPE_7_0_OH_CHR,
-	HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR,
-	HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS,
-	HDMI_AUD_CHAN_TYPE_UNKNOWN = 0xFF
-};
-
-enum hdmi_aud_channel_swap_type {
-	HDMI_AUD_SWAP_LR,
-	HDMI_AUD_SWAP_LFE_CC,
-	HDMI_AUD_SWAP_LSRS,
-	HDMI_AUD_SWAP_RLS_RRS,
-	HDMI_AUD_SWAP_LR_STATUS,
-};
-
-struct hdmi_audio_param {
-	enum hdmi_audio_coding_type aud_codec;
-	enum hdmi_audio_sample_size aud_sample_size;
-	enum hdmi_aud_input_type aud_input_type;
-	enum hdmi_aud_i2s_fmt aud_i2s_fmt;
-	enum hdmi_aud_mclk aud_mclk;
-	enum hdmi_aud_channel_type aud_input_chan_type;
-	struct hdmi_codec_params codec_params;
-};
-
-struct mtk_hdmi_conf {
-	bool tz_disabled;
-	bool cea_modes_only;
-	unsigned long max_mode_clock;
-};
-
-struct mtk_hdmi {
-	struct drm_bridge bridge;
-	struct drm_bridge *next_bridge;
-	struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */
-	struct device *dev;
-	const struct mtk_hdmi_conf *conf;
-	struct phy *phy;
-	struct device *cec_dev;
-	struct i2c_adapter *ddc_adpt;
-	struct clk **clk;
-	struct drm_display_mode mode;
-	bool dvi_mode;
-	struct regmap *sys_regmap;
-	unsigned int sys_offset;
-	struct regmap *regs;
-	struct platform_device *audio_pdev;
-	struct hdmi_audio_param aud_param;
-	bool audio_enable;
-	bool powered;
-	bool enabled;
-	hdmi_codec_plugged_cb plugged_cb;
-	struct device *codec_dev;
-	struct mutex update_plugged_status_lock;
-};
-
-static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
-{
-	return container_of(b, struct mtk_hdmi, bridge);
-}
-
 static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)
 {
 	regmap_update_bits(hdmi->regs, VIDEO_SOURCE_SEL,
@@ -600,88 +464,6 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,
 	regmap_write(hdmi->regs, GRL_CFG5, val);
 }
 
-struct hdmi_acr_n {
-	unsigned int clock;
-	unsigned int n[3];
-};
-
-/* Recommended N values from HDMI specification, tables 7-1 to 7-3 */
-static const struct hdmi_acr_n hdmi_rec_n_table[] = {
-	/* Clock, N: 32kHz 44.1kHz 48kHz */
-	{  25175, {  4576,  7007,  6864 } },
-	{  74176, { 11648, 17836, 11648 } },
-	{ 148352, { 11648,  8918,  5824 } },
-	{ 296703, {  5824,  4459,  5824 } },
-	{ 297000, {  3072,  4704,  5120 } },
-	{      0, {  4096,  6272,  6144 } }, /* all other TMDS clocks */
-};
-
-/**
- * hdmi_recommended_n() - Return N value recommended by HDMI specification
- * @freq: audio sample rate in Hz
- * @clock: rounded TMDS clock in kHz
- */
-static unsigned int hdmi_recommended_n(unsigned int freq, unsigned int clock)
-{
-	const struct hdmi_acr_n *recommended;
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(hdmi_rec_n_table) - 1; i++) {
-		if (clock == hdmi_rec_n_table[i].clock)
-			break;
-	}
-	recommended = hdmi_rec_n_table + i;
-
-	switch (freq) {
-	case 32000:
-		return recommended->n[0];
-	case 44100:
-		return recommended->n[1];
-	case 48000:
-		return recommended->n[2];
-	case 88200:
-		return recommended->n[1] * 2;
-	case 96000:
-		return recommended->n[2] * 2;
-	case 176400:
-		return recommended->n[1] * 4;
-	case 192000:
-		return recommended->n[2] * 4;
-	default:
-		return (128 * freq) / 1000;
-	}
-}
-
-static unsigned int hdmi_mode_clock_to_hz(unsigned int clock)
-{
-	switch (clock) {
-	case 25175:
-		return 25174825;	/* 25.2/1.001 MHz */
-	case 74176:
-		return 74175824;	/* 74.25/1.001 MHz */
-	case 148352:
-		return 148351648;	/* 148.5/1.001 MHz */
-	case 296703:
-		return 296703297;	/* 297/1.001 MHz */
-	default:
-		return clock * 1000;
-	}
-}
-
-static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate,
-				      unsigned int tmds_clock, unsigned int n)
-{
-	return DIV_ROUND_CLOSEST_ULL((u64)hdmi_mode_clock_to_hz(tmds_clock) * n,
-				     128 * audio_sample_rate);
-}
-
-static void mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock,
-			      unsigned int *n, unsigned int *cts)
-{
-	*n = hdmi_recommended_n(sample_rate, clock);
-	*cts = hdmi_expected_cts(sample_rate, clock, *n);
-}
-
 static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,
 				    unsigned int cts)
 {
@@ -1072,21 +854,6 @@ static const char * const mtk_hdmi_clk_names[MTK_HDMI_CLK_COUNT] = {
 	[MTK_HDMI_CLK_AUD_SPDIF] = "spdif",
 };
 
-static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi, struct device_node *np,
-				const char * const *clock_names, size_t num_clocks)
-{
-	int i;
-
-	for (i = 0; i < num_clocks; i++) {
-		hdmi->clk[i] = of_clk_get_by_name(np, clock_names[i]);
-
-		if (IS_ERR(hdmi->clk[i]))
-			return PTR_ERR(hdmi->clk[i]);
-	}
-
-	return 0;
-}
-
 static int mtk_hdmi_clk_enable_audio(struct mtk_hdmi *hdmi)
 {
 	int ret;
@@ -1229,13 +996,6 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge,
 	return 0;
 }
 
-static bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
-				       const struct drm_display_mode *mode,
-				       struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
 static void mtk_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
 					   struct drm_bridge_state *old_bridge_state)
 {
@@ -1267,28 +1027,6 @@ static void mtk_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
 	hdmi->powered = false;
 }
 
-static void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode)
-{
-	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
-
-	dev_dbg(hdmi->dev, "cur info: name:%s, hdisplay:%d\n",
-		adjusted_mode->name, adjusted_mode->hdisplay);
-	dev_dbg(hdmi->dev, "hsync_start:%d,hsync_end:%d, htotal:%d",
-		adjusted_mode->hsync_start, adjusted_mode->hsync_end,
-		adjusted_mode->htotal);
-	dev_dbg(hdmi->dev, "hskew:%d, vdisplay:%d\n",
-		adjusted_mode->hskew, adjusted_mode->vdisplay);
-	dev_dbg(hdmi->dev, "vsync_start:%d, vsync_end:%d, vtotal:%d",
-		adjusted_mode->vsync_start, adjusted_mode->vsync_end,
-		adjusted_mode->vtotal);
-	dev_dbg(hdmi->dev, "vscan:%d, flag:%d\n",
-		adjusted_mode->vscan, adjusted_mode->flags);
-
-	drm_mode_copy(&hdmi->mode, adjusted_mode);
-}
-
 static void mtk_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
 					      struct drm_bridge_state *old_state)
 {
@@ -1345,167 +1083,10 @@ static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = {
 	.edid_read = mtk_hdmi_bridge_edid_read,
 };
 
-static int mtk_hdmi_get_cec_dev(struct mtk_hdmi *hdmi, struct device *dev, struct device_node *np)
-{
-	struct platform_device *cec_pdev;
-	struct device_node *cec_np;
-	int ret;
-
-	/* The CEC module handles HDMI hotplug detection */
-	cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
-	if (!cec_np)
-		return dev_err_probe(dev, -ENOTSUPP, "Failed to find CEC node\n");
-
-	cec_pdev = of_find_device_by_node(cec_np);
-	if (!cec_pdev) {
-		dev_err(hdmi->dev, "Waiting for CEC device %pOF\n", cec_np);
-		of_node_put(cec_np);
-		return -EPROBE_DEFER;
-	}
-	of_node_put(cec_np);
-
-	/*
-	 * The mediatek,syscon-hdmi property contains a phandle link to the
-	 * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG
-	 * registers it contains.
-	 */
-	hdmi->sys_regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");
-	if (IS_ERR(hdmi->sys_regmap))
-		return PTR_ERR(hdmi->sys_regmap);
-
-	ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, &hdmi->sys_offset);
-	if (ret)
-		return dev_err_probe(dev, ret,
-				     "Failed to get system configuration registers\n");
-
-	hdmi->cec_dev = &cec_pdev->dev;
-	return 0;
-}
-
-static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device *pdev,
-				   const char * const *clk_names, size_t num_clocks)
-{
-	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
-	struct device_node *remote, *i2c_np;
-	int ret;
-
-	ret = mtk_hdmi_get_all_clk(hdmi, np, clk_names, num_clocks);
-	if (ret)
-		return dev_err_probe(dev, ret, "Failed to get clocks\n");
-
-	hdmi->regs = device_node_to_regmap(dev->of_node);
-	if (IS_ERR(hdmi->regs))
-		return PTR_ERR(hdmi->regs);
-
-	remote = of_graph_get_remote_node(np, 1, 0);
-	if (!remote)
-		return -EINVAL;
-
-	if (!of_device_is_compatible(remote, "hdmi-connector")) {
-		hdmi->next_bridge = of_drm_find_bridge(remote);
-		if (!hdmi->next_bridge) {
-			dev_err(dev, "Waiting for external bridge\n");
-			of_node_put(remote);
-			return -EPROBE_DEFER;
-		}
-	}
-
-	i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
-	of_node_put(remote);
-	if (!i2c_np)
-		return dev_err_probe(dev, -EINVAL, "No ddc-i2c-bus in connector\n");
-
-	hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
-	of_node_put(i2c_np);
-	if (!hdmi->ddc_adpt)
-		return dev_err_probe(dev, -EINVAL, "Failed to get ddc i2c adapter by node\n");
-
-	ret = mtk_hdmi_get_cec_dev(hdmi, dev, np);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
 /*
  * HDMI audio codec callbacks
  */
 
-static int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi,
-				 struct hdmi_codec_daifmt *daifmt,
-				 struct hdmi_codec_params *params)
-{
-	struct hdmi_audio_param aud_params = { 0 };
-	unsigned int chan = params->cea.channels;
-
-	dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
-		params->sample_rate, params->sample_width, chan);
-
-	if (!hdmi->bridge.encoder)
-		return -ENODEV;
-
-	switch (chan) {
-	case 2:
-		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
-		break;
-	case 4:
-		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
-		break;
-	case 6:
-		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
-		break;
-	case 8:
-		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
-		break;
-	default:
-		dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
-		return -EINVAL;
-	}
-
-	switch (params->sample_rate) {
-	case 32000:
-	case 44100:
-	case 48000:
-	case 88200:
-	case 96000:
-	case 176400:
-	case 192000:
-		break;
-	default:
-		dev_err(hdmi->dev, "rate[%d] not supported!\n",
-			params->sample_rate);
-		return -EINVAL;
-	}
-
-	switch (daifmt->fmt) {
-	case HDMI_I2S:
-		aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
-		aud_params.aud_input_type = HDMI_AUD_INPUT_I2S;
-		aud_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
-		aud_params.aud_mclk = HDMI_AUD_MCLK_128FS;
-		break;
-	case HDMI_SPDIF:
-		aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-		aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
-		aud_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
-		break;
-	default:
-		dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,
-			daifmt->fmt);
-		return -EINVAL;
-	}
-	memcpy(&aud_params.codec_params, params, sizeof(aud_params.codec_params));
-	memcpy(&hdmi->aud_param, &aud_params, sizeof(aud_params));
-
-	dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",
-		aud_params.aud_codec, aud_params.aud_input_type,
-		aud_params.aud_input_chan_type, aud_params.codec_params.sample_rate);
-
-	return 0;
-}
-
 static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
 				    struct hdmi_codec_daifmt *daifmt,
 				    struct hdmi_codec_params *params)
@@ -1553,26 +1134,6 @@ mtk_hdmi_audio_mute(struct device *dev, void *data,
 	return 0;
 }
 
-static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len)
-{
-	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-
-	if (hdmi->enabled)
-		memcpy(buf, hdmi->curr_conn->eld, min(sizeof(hdmi->curr_conn->eld), len));
-	else
-		memset(buf, 0, len);
-	return 0;
-}
-
-static void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn,
-					  struct device *codec_dev)
-{
-	mutex_lock(&hdmi->update_plugged_status_lock);
-	hdmi->plugged_cb = fn;
-	hdmi->codec_dev = codec_dev;
-	mutex_unlock(&hdmi->update_plugged_status_lock);
-}
-
 static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,
 					  hdmi_codec_plugged_cb fn,
 					  struct device *codec_dev)
@@ -1595,101 +1156,18 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
 	.no_capture_mute = 1,
 };
 
-static void mtk_hdmi_unregister_audio_driver(void *data)
-{
-	platform_device_unregister(data);
-}
-
-static int mtk_hdmi_register_audio_driver(struct device *dev)
-{
-	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
-	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
-	struct hdmi_codec_pdata codec_data = {
-		.ops = &mtk_hdmi_audio_codec_ops,
-		.max_i2s_channels = 2,
-		.i2s = 1,
-		.data = hdmi,
-	};
-	int ret;
-
-	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
-	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
-	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
-	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
-	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
-	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
-
-	hdmi->audio_pdev = platform_device_register_data(dev,
-							 HDMI_CODEC_DRV_NAME,
-							 PLATFORM_DEVID_AUTO,
-							 &codec_data,
-							 sizeof(codec_data));
-	if (IS_ERR(hdmi->audio_pdev))
-		return PTR_ERR(hdmi->audio_pdev);
-
-	ret = devm_add_action_or_reset(dev, mtk_hdmi_unregister_audio_driver,
-				       hdmi->audio_pdev);
-	if (ret) {
-		platform_device_unregister(hdmi->audio_pdev);
-		return ret;
-	}
-
-	return 0;
-}
-
 static int mtk_hdmi_probe(struct platform_device *pdev)
 {
 	struct mtk_hdmi *hdmi;
-	struct device *dev = &pdev->dev;
-	const int num_clocks = MTK_HDMI_CLK_COUNT;
-	int ret;
-
-	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
-	if (!hdmi)
-		return -ENOMEM;
 
-	hdmi->dev = dev;
-	hdmi->conf = of_device_get_match_data(dev);
+	hdmi = mtk_hdmi_common_probe(pdev);
+	if (IS_ERR(hdmi))
+		return PTR_ERR(hdmi);
 
-	hdmi->clk = devm_kcalloc(dev, num_clocks, sizeof(*hdmi->clk), GFP_KERNEL);
-	if (!hdmi->clk)
-		return -ENOMEM;
-
-	ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, mtk_hdmi_clk_names, num_clocks);
-	if (ret)
-		return ret;
-
-	hdmi->phy = devm_phy_get(dev, "hdmi");
-	if (IS_ERR(hdmi->phy))
-		return dev_err_probe(dev, PTR_ERR(hdmi->phy),
-				     "Failed to get HDMI PHY\n");
-
-	mutex_init(&hdmi->update_plugged_status_lock);
-	platform_set_drvdata(pdev, hdmi);
-
-	ret = mtk_hdmi_register_audio_driver(dev);
-	if (ret)
-		return dev_err_probe(dev, ret,
-				     "Failed to register audio driver\n");
-
-	hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs;
-	hdmi->bridge.of_node = pdev->dev.of_node;
-	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
-			 | DRM_BRIDGE_OP_HPD;
-	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
-	hdmi->bridge.vendor = "MediaTek";
-	hdmi->bridge.product = "On-Chip HDMI";
-
-	ret = devm_drm_bridge_add(dev, &hdmi->bridge);
-	if (ret)
-		return dev_err_probe(dev, ret, "Failed to add bridge\n");
+	if (!hdmi->cec_dev)
+		return dev_err_probe(hdmi->dev, -ENODEV, "CEC is required by HDMIv1\n");
 
-	ret = mtk_hdmi_clk_enable_audio(hdmi);
-	if (ret)
-		return dev_err_probe(dev, ret,
-				     "Failed to enable audio clocks\n");
-
-	return 0;
+	return mtk_hdmi_clk_enable_audio(hdmi);
 }
 
 static void mtk_hdmi_remove(struct platform_device *pdev)
@@ -1717,19 +1195,32 @@ static __maybe_unused int mtk_hdmi_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops, mtk_hdmi_suspend, mtk_hdmi_resume);
 
+static const struct mtk_hdmi_ver_conf mtk_hdmi_v1_ver_conf = {
+	.bridge_funcs = &mtk_hdmi_bridge_funcs,
+	.codec_ops = &mtk_hdmi_audio_codec_ops,
+	.mtk_hdmi_clock_names = mtk_hdmi_clk_names,
+	.num_clocks = ARRAY_SIZE(mtk_hdmi_clk_names)
+};
+
 static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = {
 	.tz_disabled = true,
+	.ver_conf = &mtk_hdmi_v1_ver_conf
 };
 
 static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 = {
-	.max_mode_clock = 148500,
 	.cea_modes_only = true,
+	.max_mode_clock = 148500,
+	.ver_conf = &mtk_hdmi_v1_ver_conf
+};
+
+static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8173 = {
+	.ver_conf = &mtk_hdmi_v1_ver_conf
 };
 
 static const struct of_device_id mtk_hdmi_of_ids[] = {
 	{ .compatible = "mediatek,mt2701-hdmi", .data = &mtk_hdmi_conf_mt2701 },
 	{ .compatible = "mediatek,mt8167-hdmi", .data = &mtk_hdmi_conf_mt8167 },
-	{ .compatible = "mediatek,mt8173-hdmi" },
+	{ .compatible = "mediatek,mt8173-hdmi", .data = &mtk_hdmi_conf_mt8173 },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mtk_hdmi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
new file mode 100644
index 000000000000..c7ccbd117487
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -0,0 +1,421 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Copyright (c) 2024 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+ */
+
+#include <drm/drm_modes.h>
+#include <linux/device.h>
+#include <linux/hdmi.h>
+#include <linux/i2c.h>
+#include <linux/math.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+#include <sound/hdmi-codec.h>
+
+#include "mtk_hdmi_common.h"
+
+struct hdmi_acr_n {
+	unsigned int clock;
+	unsigned int n[3];
+};
+
+/* Recommended N values from HDMI specification, tables 7-1 to 7-3 */
+static const struct hdmi_acr_n hdmi_rec_n_table[] = {
+	/* Clock, N: 32kHz 44.1kHz 48kHz */
+	{  25175, {  4576,  7007,  6864 } },
+	{  74176, { 11648, 17836, 11648 } },
+	{ 148352, { 11648,  8918,  5824 } },
+	{ 296703, {  5824,  4459,  5824 } },
+	{ 297000, {  3072,  4704,  5120 } },
+	{      0, {  4096,  6272,  6144 } }, /* all other TMDS clocks */
+};
+
+/**
+ * hdmi_recommended_n() - Return N value recommended by HDMI specification
+ * @freq: audio sample rate in Hz
+ * @clock: rounded TMDS clock in kHz
+ */
+static unsigned int hdmi_recommended_n(unsigned int freq, unsigned int clock)
+{
+	const struct hdmi_acr_n *recommended;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_rec_n_table) - 1; i++) {
+		if (clock == hdmi_rec_n_table[i].clock)
+			break;
+	}
+	recommended = hdmi_rec_n_table + i;
+
+	switch (freq) {
+	case 32000:
+		return recommended->n[0];
+	case 44100:
+		return recommended->n[1];
+	case 48000:
+		return recommended->n[2];
+	case 88200:
+		return recommended->n[1] * 2;
+	case 96000:
+		return recommended->n[2] * 2;
+	case 176400:
+		return recommended->n[1] * 4;
+	case 192000:
+		return recommended->n[2] * 4;
+	default:
+		return (128 * freq) / 1000;
+	}
+}
+
+static unsigned int hdmi_mode_clock_to_hz(unsigned int clock)
+{
+	switch (clock) {
+	case 25175:
+		return 25174825;	/* 25.2/1.001 MHz */
+	case 74176:
+		return 74175824;	/* 74.25/1.001 MHz */
+	case 148352:
+		return 148351648;	/* 148.5/1.001 MHz */
+	case 296703:
+		return 296703297;	/* 297/1.001 MHz */
+	default:
+		return clock * 1000;
+	}
+}
+
+static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate,
+				      unsigned int tmds_clock, unsigned int n)
+{
+	return DIV_ROUND_CLOSEST_ULL((u64)hdmi_mode_clock_to_hz(tmds_clock) * n,
+				     128 * audio_sample_rate);
+}
+
+void mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock,
+		       unsigned int *n, unsigned int *cts)
+{
+	*n = hdmi_recommended_n(sample_rate, clock);
+	*cts = hdmi_expected_cts(sample_rate, clock, *n);
+}
+
+int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi,
+			  struct hdmi_codec_daifmt *daifmt,
+			  struct hdmi_codec_params *params)
+{
+	struct hdmi_audio_param aud_params = { 0 };
+	unsigned int chan = params->cea.channels;
+
+	dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
+		params->sample_rate, params->sample_width, chan);
+
+	if (!hdmi->bridge.encoder)
+		return -ENODEV;
+
+	switch (chan) {
+	case 2:
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
+		break;
+	case 4:
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
+		break;
+	case 6:
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
+		break;
+	case 8:
+		aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
+		break;
+	default:
+		dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
+		return -EINVAL;
+	}
+
+	switch (params->sample_rate) {
+	case 32000:
+	case 44100:
+	case 48000:
+	case 88200:
+	case 96000:
+	case 176400:
+	case 192000:
+		break;
+	default:
+		dev_err(hdmi->dev, "rate[%d] not supported!\n",
+			params->sample_rate);
+		return -EINVAL;
+	}
+
+	switch (daifmt->fmt) {
+	case HDMI_I2S:
+		aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+		aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		aud_params.aud_input_type = HDMI_AUD_INPUT_I2S;
+		aud_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
+		aud_params.aud_mclk = HDMI_AUD_MCLK_128FS;
+		break;
+	case HDMI_SPDIF:
+		aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+		aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+		aud_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
+		break;
+	default:
+		dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,
+			daifmt->fmt);
+		return -EINVAL;
+	}
+	memcpy(&aud_params.codec_params, params, sizeof(aud_params.codec_params));
+	memcpy(&hdmi->aud_param, &aud_params, sizeof(aud_params));
+
+	dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",
+		aud_params.aud_codec, aud_params.aud_input_type,
+		aud_params.aud_input_chan_type, aud_params.codec_params.sample_rate);
+
+	return 0;
+}
+
+int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	if (hdmi->enabled)
+		memcpy(buf, hdmi->curr_conn->eld, min(sizeof(hdmi->curr_conn->eld), len));
+	else
+		memset(buf, 0, len);
+
+	return 0;
+}
+
+void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn,
+				   struct device *codec_dev)
+{
+	mutex_lock(&hdmi->update_plugged_status_lock);
+	hdmi->plugged_cb = fn;
+	hdmi->codec_dev = codec_dev;
+	mutex_unlock(&hdmi->update_plugged_status_lock);
+}
+
+static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi, struct device_node *np,
+				const char * const *clock_names, size_t num_clocks)
+{
+	int i;
+
+	for (i = 0; i < num_clocks; i++) {
+		hdmi->clk[i] = of_clk_get_by_name(np, clock_names[i]);
+
+		if (IS_ERR(hdmi->clk[i]))
+			return PTR_ERR(hdmi->clk[i]);
+	}
+
+	return 0;
+}
+
+bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+				const struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+			      const struct drm_display_mode *mode,
+			      const struct drm_display_mode *adjusted_mode)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	dev_dbg(hdmi->dev, "cur info: name:%s, hdisplay:%d\n",
+		adjusted_mode->name, adjusted_mode->hdisplay);
+	dev_dbg(hdmi->dev, "hsync_start:%d,hsync_end:%d, htotal:%d",
+		adjusted_mode->hsync_start, adjusted_mode->hsync_end,
+		adjusted_mode->htotal);
+	dev_dbg(hdmi->dev, "hskew:%d, vdisplay:%d\n",
+		adjusted_mode->hskew, adjusted_mode->vdisplay);
+	dev_dbg(hdmi->dev, "vsync_start:%d, vsync_end:%d, vtotal:%d",
+		adjusted_mode->vsync_start, adjusted_mode->vsync_end,
+		adjusted_mode->vtotal);
+	dev_dbg(hdmi->dev, "vscan:%d, flag:%d\n",
+		adjusted_mode->vscan, adjusted_mode->flags);
+
+	drm_mode_copy(&hdmi->mode, adjusted_mode);
+}
+
+static int mtk_hdmi_get_cec_dev(struct mtk_hdmi *hdmi, struct device *dev, struct device_node *np)
+{
+	struct platform_device *cec_pdev;
+	struct device_node *cec_np;
+	int ret;
+
+	/* The CEC module handles HDMI hotplug detection */
+	cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");
+	if (!cec_np)
+		return dev_err_probe(dev, -ENOTSUPP, "Failed to find CEC node\n");
+
+	cec_pdev = of_find_device_by_node(cec_np);
+	if (!cec_pdev) {
+		dev_err(hdmi->dev, "Waiting for CEC device %pOF\n", cec_np);
+		of_node_put(cec_np);
+		return -EPROBE_DEFER;
+	}
+	of_node_put(cec_np);
+
+	/*
+	 * The mediatek,syscon-hdmi property contains a phandle link to the
+	 * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG
+	 * registers it contains.
+	 */
+	hdmi->sys_regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");
+	if (IS_ERR(hdmi->sys_regmap))
+		return PTR_ERR(hdmi->sys_regmap);
+
+	ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, &hdmi->sys_offset);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get system configuration registers\n");
+
+	hdmi->cec_dev = &cec_pdev->dev;
+	return 0;
+}
+
+static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device *pdev,
+				   const char * const *clk_names, size_t num_clocks)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *remote, *i2c_np;
+	int ret;
+
+	ret = mtk_hdmi_get_all_clk(hdmi, np, clk_names, num_clocks);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get clocks\n");
+
+	hdmi->regs = device_node_to_regmap(dev->of_node);
+	if (IS_ERR(hdmi->regs))
+		return PTR_ERR(hdmi->regs);
+
+	remote = of_graph_get_remote_node(np, 1, 0);
+	if (!remote)
+		return -EINVAL;
+
+	if (!of_device_is_compatible(remote, "hdmi-connector")) {
+		hdmi->next_bridge = of_drm_find_bridge(remote);
+		if (!hdmi->next_bridge) {
+			dev_err(dev, "Waiting for external bridge\n");
+			of_node_put(remote);
+			return -EPROBE_DEFER;
+		}
+	}
+
+	i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
+	of_node_put(remote);
+	if (!i2c_np)
+		return dev_err_probe(dev, -EINVAL, "No ddc-i2c-bus in connector\n");
+
+	hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
+	of_node_put(i2c_np);
+	if (!hdmi->ddc_adpt)
+		return dev_err_probe(dev, -EINVAL, "Failed to get ddc i2c adapter by node\n");
+
+	ret = mtk_hdmi_get_cec_dev(hdmi, dev, np);
+	if (ret == -ENOTSUPP)
+		dev_info(dev, "CEC support unavailable: node not found\n");
+	else if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void mtk_hdmi_unregister_audio_driver(void *data)
+{
+	platform_device_unregister(data);
+}
+
+static int mtk_hdmi_register_audio_driver(struct device *dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
+	struct hdmi_codec_pdata codec_data = {
+		.ops = hdmi->conf->ver_conf->codec_ops,
+		.max_i2s_channels = 2,
+		.i2s = 1,
+		.data = hdmi,
+	};
+	int ret;
+
+	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+	aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
+	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
+	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
+	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
+
+	hdmi->audio_pdev = platform_device_register_data(dev,
+							 HDMI_CODEC_DRV_NAME,
+							 PLATFORM_DEVID_AUTO,
+							 &codec_data,
+							 sizeof(codec_data));
+	if (IS_ERR(hdmi->audio_pdev))
+		return PTR_ERR(hdmi->audio_pdev);
+
+	ret = devm_add_action_or_reset(dev, mtk_hdmi_unregister_audio_driver,
+				       hdmi->audio_pdev);
+	if (ret) {
+		platform_device_unregister(hdmi->audio_pdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
+{
+	const struct mtk_hdmi_ver_conf *ver_conf;
+	struct device *dev = &pdev->dev;
+	struct mtk_hdmi *hdmi;
+	int ret;
+
+	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return ERR_PTR(-ENOMEM);
+
+	hdmi->dev = dev;
+	hdmi->conf = of_device_get_match_data(dev);
+	ver_conf = hdmi->conf->ver_conf;
+
+	hdmi->clk = devm_kcalloc(dev, ver_conf->num_clocks, sizeof(*hdmi->clk), GFP_KERNEL);
+	if (!hdmi->clk)
+		return ERR_PTR(-ENOMEM);
+
+	ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, ver_conf->mtk_hdmi_clock_names,
+				      ver_conf->num_clocks);
+	if (ret)
+		return ERR_PTR(ret);
+
+	hdmi->phy = devm_phy_get(dev, "hdmi");
+	if (IS_ERR(hdmi->phy))
+		return dev_err_cast_probe(dev, hdmi->phy, "Failed to get HDMI PHY\n");
+
+	mutex_init(&hdmi->update_plugged_status_lock);
+	platform_set_drvdata(pdev, hdmi);
+
+	ret = mtk_hdmi_register_audio_driver(dev);
+	if (ret)
+		return dev_err_ptr_probe(dev, ret, "Cannot register HDMI Audio driver\n");
+
+	hdmi->bridge.funcs = ver_conf->bridge_funcs;
+	hdmi->bridge.of_node = pdev->dev.of_node;
+	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
+			 | DRM_BRIDGE_OP_HPD;
+	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+	hdmi->bridge.vendor = "MediaTek";
+	hdmi->bridge.product = "On-Chip HDMI";
+
+	ret = devm_drm_bridge_add(dev, &hdmi->bridge);
+	if (ret)
+		return dev_err_ptr_probe(dev, ret, "Failed to add bridge\n");
+
+	return hdmi;
+}
+
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>");
+MODULE_DESCRIPTION("MediaTek HDMI Common Library");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
new file mode 100644
index 000000000000..d3de8afff40f
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
@@ -0,0 +1,188 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Copyright (c) 2024 Collabora Ltd.
+ */
+
+#ifndef _MTK_HDMI_COMMON_H
+#define _MTK_HDMI_COMMON_H
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/hdmi.h>
+#include <linux/i2c.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mutex.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+#include <sound/hdmi-codec.h>
+
+enum hdmi_aud_input_type {
+	HDMI_AUD_INPUT_I2S = 0,
+	HDMI_AUD_INPUT_SPDIF,
+};
+
+enum hdmi_aud_i2s_fmt {
+	HDMI_I2S_MODE_RJT_24BIT = 0,
+	HDMI_I2S_MODE_RJT_16BIT,
+	HDMI_I2S_MODE_LJT_24BIT,
+	HDMI_I2S_MODE_LJT_16BIT,
+	HDMI_I2S_MODE_I2S_24BIT,
+	HDMI_I2S_MODE_I2S_16BIT
+};
+
+enum hdmi_aud_mclk {
+	HDMI_AUD_MCLK_128FS,
+	HDMI_AUD_MCLK_192FS,
+	HDMI_AUD_MCLK_256FS,
+	HDMI_AUD_MCLK_384FS,
+	HDMI_AUD_MCLK_512FS,
+	HDMI_AUD_MCLK_768FS,
+	HDMI_AUD_MCLK_1152FS,
+};
+
+enum hdmi_aud_channel_type {
+	HDMI_AUD_CHAN_TYPE_1_0 = 0,
+	HDMI_AUD_CHAN_TYPE_1_1,
+	HDMI_AUD_CHAN_TYPE_2_0,
+	HDMI_AUD_CHAN_TYPE_2_1,
+	HDMI_AUD_CHAN_TYPE_3_0,
+	HDMI_AUD_CHAN_TYPE_3_1,
+	HDMI_AUD_CHAN_TYPE_4_0,
+	HDMI_AUD_CHAN_TYPE_4_1,
+	HDMI_AUD_CHAN_TYPE_5_0,
+	HDMI_AUD_CHAN_TYPE_5_1,
+	HDMI_AUD_CHAN_TYPE_6_0,
+	HDMI_AUD_CHAN_TYPE_6_1,
+	HDMI_AUD_CHAN_TYPE_7_0,
+	HDMI_AUD_CHAN_TYPE_7_1,
+	HDMI_AUD_CHAN_TYPE_3_0_LRS,
+	HDMI_AUD_CHAN_TYPE_3_1_LRS,
+	HDMI_AUD_CHAN_TYPE_4_0_CLRS,
+	HDMI_AUD_CHAN_TYPE_4_1_CLRS,
+	HDMI_AUD_CHAN_TYPE_6_1_CS,
+	HDMI_AUD_CHAN_TYPE_6_1_CH,
+	HDMI_AUD_CHAN_TYPE_6_1_OH,
+	HDMI_AUD_CHAN_TYPE_6_1_CHR,
+	HDMI_AUD_CHAN_TYPE_7_1_LH_RH,
+	HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR,
+	HDMI_AUD_CHAN_TYPE_7_1_LC_RC,
+	HDMI_AUD_CHAN_TYPE_7_1_LW_RW,
+	HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD,
+	HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS,
+	HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS,
+	HDMI_AUD_CHAN_TYPE_7_1_CS_CH,
+	HDMI_AUD_CHAN_TYPE_7_1_CS_OH,
+	HDMI_AUD_CHAN_TYPE_7_1_CS_CHR,
+	HDMI_AUD_CHAN_TYPE_7_1_CH_OH,
+	HDMI_AUD_CHAN_TYPE_7_1_CH_CHR,
+	HDMI_AUD_CHAN_TYPE_7_1_OH_CHR,
+	HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR,
+	HDMI_AUD_CHAN_TYPE_6_0_CS,
+	HDMI_AUD_CHAN_TYPE_6_0_CH,
+	HDMI_AUD_CHAN_TYPE_6_0_OH,
+	HDMI_AUD_CHAN_TYPE_6_0_CHR,
+	HDMI_AUD_CHAN_TYPE_7_0_LH_RH,
+	HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR,
+	HDMI_AUD_CHAN_TYPE_7_0_LC_RC,
+	HDMI_AUD_CHAN_TYPE_7_0_LW_RW,
+	HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD,
+	HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS,
+	HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS,
+	HDMI_AUD_CHAN_TYPE_7_0_CS_CH,
+	HDMI_AUD_CHAN_TYPE_7_0_CS_OH,
+	HDMI_AUD_CHAN_TYPE_7_0_CS_CHR,
+	HDMI_AUD_CHAN_TYPE_7_0_CH_OH,
+	HDMI_AUD_CHAN_TYPE_7_0_CH_CHR,
+	HDMI_AUD_CHAN_TYPE_7_0_OH_CHR,
+	HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR,
+	HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS,
+	HDMI_AUD_CHAN_TYPE_UNKNOWN = 0xFF
+};
+
+enum hdmi_aud_channel_swap_type {
+	HDMI_AUD_SWAP_LR,
+	HDMI_AUD_SWAP_LFE_CC,
+	HDMI_AUD_SWAP_LSRS,
+	HDMI_AUD_SWAP_RLS_RRS,
+	HDMI_AUD_SWAP_LR_STATUS,
+};
+
+struct hdmi_audio_param {
+	enum hdmi_audio_coding_type aud_codec;
+	enum hdmi_audio_sample_size aud_sample_size;
+	enum hdmi_aud_input_type aud_input_type;
+	enum hdmi_aud_i2s_fmt aud_i2s_fmt;
+	enum hdmi_aud_mclk aud_mclk;
+	enum hdmi_aud_channel_type aud_input_chan_type;
+	struct hdmi_codec_params codec_params;
+};
+
+struct mtk_hdmi_ver_conf {
+	const struct drm_bridge_funcs *bridge_funcs;
+	const struct hdmi_codec_ops *codec_ops;
+	const char * const *mtk_hdmi_clock_names;
+	int num_clocks;
+};
+
+struct mtk_hdmi_conf {
+	const struct mtk_hdmi_ver_conf *ver_conf;
+	bool tz_disabled;
+	bool cea_modes_only;
+	unsigned long max_mode_clock;
+};
+
+struct mtk_hdmi {
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */
+	struct device *dev;
+	const struct mtk_hdmi_conf *conf;
+	struct phy *phy;
+	struct device *cec_dev;
+	struct i2c_adapter *ddc_adpt;
+	struct clk **clk;
+	struct drm_display_mode mode;
+	bool dvi_mode;
+	struct regmap *sys_regmap;
+	unsigned int sys_offset;
+	struct regmap *regs;
+	struct platform_device *audio_pdev;
+	struct hdmi_audio_param aud_param;
+	bool audio_enable;
+	bool powered;
+	bool enabled;
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
+	struct mutex update_plugged_status_lock;
+};
+
+static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
+{
+	return container_of(b, struct mtk_hdmi, bridge);
+}
+
+
+int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len);
+void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn,
+				   struct device *codec_dev);
+int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi, struct hdmi_codec_daifmt *daifmt,
+			  struct hdmi_codec_params *params);
+void mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock,
+		       unsigned int *n, unsigned int *cts);
+bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+				const struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode);
+void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+			      const struct drm_display_mode *mode,
+			      const struct drm_display_mode *adjusted_mode);
+struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev);
+#endif /* _MTK_HDMI_COMMON_H */
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:41 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:41 +0100
Subject: [PATCH v3 29/33] drm/mediatek: mtk_hdmi_common: Assign DDC adapter pointer to bridge
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-30-angelogioacchino.delregno@collabora.com>

In preparation for adding the new HDMI TX v2 IP driver, assign the
pointer to the DDC adapter to struct drm_bridge during probe.

This commit brings no functional changes.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index c7ccbd117487..153d7f7d5da2 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -406,6 +406,7 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
 	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
 			 | DRM_BRIDGE_OP_HPD;
 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+	hdmi->bridge.ddc = hdmi->ddc_adpt;
 	hdmi->bridge.vendor = "MediaTek";
 	hdmi->bridge.product = "On-Chip HDMI";
 
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:42 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:42 +0100
Subject: [PATCH v3 30/33] drm/mediatek: mtk_hdmi_common: Add OP_HDMI if helper funcs assigned
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-31-angelogioacchino.delregno@collabora.com>

In preparation for adding the HDMI TX v2 driver, and to allow
a future modernization of the HDMI v1 one, perform changes
that enable the usage of the HDMI Helpers provided by DRM.

Check if the HDMI driver provides the function pointers to
hdmi_{clear,write}_infoframe used by the HDMI Helper API and,
if present, add DRM_BRIDGE_OP_HDMI to the drm_bridge ops,
enabling the drm API to register the bridge as HDMI and to use
the HDMI Helper functions.

If the hdmi_{write,clear}_infoframe pointers are not assigned,
vendor and product strings and HDMI helpers will not be used,
hence this commit brings no functional changes to drivers that
have not been refactored to use the new helpers.

This also means that, in the current state, there is effectively
no functional change to mtk_hdmi and its other components.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index 153d7f7d5da2..78ed6e0630c6 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -405,6 +405,11 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
 	hdmi->bridge.of_node = pdev->dev.of_node;
 	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
 			 | DRM_BRIDGE_OP_HPD;
+
+	if (ver_conf->bridge_funcs->hdmi_write_infoframe &&
+	    ver_conf->bridge_funcs->hdmi_clear_infoframe)
+		hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI;
+
 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	hdmi->bridge.ddc = hdmi->ddc_adpt;
 	hdmi->bridge.vendor = "MediaTek";
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:43 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:43 +0100
Subject: [PATCH v3 31/33] drm/mediatek: Introduce HDMI/DDC v2 for MT8195/MT8188
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-32-angelogioacchino.delregno@collabora.com>

Add support for the newer HDMI-TX (Encoder) v2 and DDC v2 IPs
found in MediaTek's MT8195, MT8188 SoC and their variants, and
including support for display modes up to 4k60 and for HDMI
Audio, as per the HDMI 2.0 spec.

HDCP and CEC functionalities are also supported by this hardware,
but are not included in this commit and that also poses a slight
difference between the V2 and V1 controllers in how they handle
Hotplug Detection (HPD).

While the v1 controller was using the CEC controller to check
HDMI cable connection and disconnection, in this driver the v2
one does not.

This is due to the fact that on parts with v2 designs, like the
MT8195 SoC, there is one CEC controller shared between the HDMI
Transmitter (HDMI-TX) and Receiver (HDMI-RX): before eventually
adding support to use the CEC HW to wake up the HDMI controllers
it is necessary to have support for one TX, one RX *and* for both
at the same time.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/Kconfig            |    8 +
 drivers/gpu/drm/mediatek/Makefile           |    4 +
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c  |   10 +
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h  |    9 +
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c  |  403 ++++++
 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h |  263 ++++
 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c      | 1384 +++++++++++++++++++
 7 files changed, 2081 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index 73459f07dae3..8127576be1eb 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -50,3 +50,11 @@ config DRM_MEDIATEK_HDMI
 	select PHY_MTK_HDMI
 	help
 	  DRM/KMS HDMI driver for Mediatek SoCs
+
+config DRM_MEDIATEK_HDMI_V2
+	tristate "DRM HDMI v2 IP support for MediaTek SoCs"
+	depends on DRM_MEDIATEK
+	select DRM_MEDIATEK_HDMI_COMMON
+	select PHY_MTK_HDMI
+	help
+	  DRM/KMS HDMI driver for MediaTek SoCs with HDMIv2 IP
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 8973d7ba37d3..928a850f707f 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -25,7 +25,11 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
 			  mtk_hdmi.o \
 			  mtk_hdmi_ddc.o
 
+mediatek-drm-hdmi-v2-objs := mtk_hdmi_ddc_v2.o \
+			     mtk_hdmi_v2.o
+
 obj-$(CONFIG_DRM_MEDIATEK_HDMI_COMMON) += mtk_hdmi_common.o
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
+obj-$(CONFIG_DRM_MEDIATEK_HDMI_V2) += mediatek-drm-hdmi-v2.o
 
 obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index 78ed6e0630c6..c076e4efcd29 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -288,10 +288,20 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to get clocks\n");
 
+
+	hdmi->irq = platform_get_irq(pdev, 0);
+	if (!hdmi->irq)
+		return hdmi->irq;
+
 	hdmi->regs = device_node_to_regmap(dev->of_node);
 	if (IS_ERR(hdmi->regs))
 		return PTR_ERR(hdmi->regs);
 
+	/* Populate HDMI sub-devices if present */
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret)
+		return ret;
+
 	remote = of_graph_get_remote_node(np, 1, 0);
 	if (!remote)
 		return -EINVAL;
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
index d3de8afff40f..e74fe1371324 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
@@ -126,6 +126,12 @@ struct hdmi_audio_param {
 	struct hdmi_codec_params codec_params;
 };
 
+enum hdmi_hpd_state {
+	HDMI_PLUG_OUT = 0,
+	HDMI_PLUG_IN_AND_SINK_POWER_ON,
+	HDMI_PLUG_IN_ONLY,
+};
+
 struct mtk_hdmi_ver_conf {
 	const struct drm_bridge_funcs *bridge_funcs;
 	const struct hdmi_codec_ops *codec_ops;
@@ -138,6 +144,7 @@ struct mtk_hdmi_conf {
 	bool tz_disabled;
 	bool cea_modes_only;
 	unsigned long max_mode_clock;
+	u32 reg_hdmi_tx_cfg;
 };
 
 struct mtk_hdmi {
@@ -160,6 +167,8 @@ struct mtk_hdmi {
 	bool audio_enable;
 	bool powered;
 	bool enabled;
+	unsigned int irq;
+	enum hdmi_hpd_state hpd;
 	hdmi_codec_plugged_cb plugged_cb;
 	struct device *codec_dev;
 	struct mutex update_plugged_status_lock;
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
new file mode 100644
index 000000000000..3d9c9e63e017
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc_v2.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek HDMI v2 Display Data Channel Driver
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre, SAS
+ * Copyright (c) 2024 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#include <drm/drm_edid.h>
+
+#include "mtk_hdmi_common.h"
+#include "mtk_hdmi_regs_v2.h"
+
+#define DDC2_DLY_CNT 572 /* BIM=208M/(v*4) = 90Khz */
+#define DDC2_DLY_CNT_EDID 832 /* BIM=208M/(v*4) = 62.5Khz */
+#define SI2C_ADDR_READ 0xf4
+#define SCDC_I2C_SLAVE_ADDRESS 0x54
+
+struct mtk_hdmi_ddc {
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *clk;
+	struct i2c_adapter adap;
+	/* Serialize read/write operations */
+	struct mutex mtx;
+};
+
+static int mtk_ddc_check_and_rise_low_bus(struct mtk_hdmi_ddc *ddc)
+{
+	u32 val;
+
+	regmap_read(ddc->regs, HDCP2X_DDCM_STATUS, &val);
+	if (val & DDC_I2C_BUS_LOW) {
+		regmap_update_bits(ddc->regs, DDC_CTRL, DDC_CTRL_CMD,
+				   FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_CLOCK_SCL));
+		usleep_range(250, 300);
+	}
+
+	if (val & DDC_I2C_NO_ACK) {
+		u32 ddc_ctrl, hpd_ddc_ctrl, hpd_ddc_status;
+
+		regmap_read(ddc->regs, DDC_CTRL, &ddc_ctrl);
+		regmap_read(ddc->regs, HPD_DDC_CTRL, &hpd_ddc_ctrl);
+		regmap_read(ddc->regs, HPD_DDC_STATUS, &hpd_ddc_status);
+	}
+
+	if (val & DDC_I2C_NO_ACK)
+		return -EIO;
+
+	return 0;
+}
+
+static int mtk_ddc_wr_one(struct mtk_hdmi_ddc *ddc, u16 addr_id,
+			  u16 offset_id, u8 wr_data)
+{
+	u32 val;
+	int ret;
+
+	/* If down, rise bus for write operation */
+	mtk_ddc_check_and_rise_low_bus(ddc);
+
+	regmap_update_bits(ddc->regs, HPD_DDC_CTRL, HPD_DDC_DELAY_CNT,
+			   FIELD_PREP(HPD_DDC_DELAY_CNT, DDC2_DLY_CNT));
+
+	regmap_write(ddc->regs, SI2C_CTRL,
+		     FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
+		     FIELD_PREP(SI2C_WDATA, wr_data) |
+		     SI2C_WR);
+
+	regmap_write(ddc->regs, DDC_CTRL,
+		     FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_SEQ_WRITE) |
+		     FIELD_PREP(DDC_CTRL_DIN_CNT, 1) |
+		     FIELD_PREP(DDC_CTRL_OFFSET, offset_id) |
+		     FIELD_PREP(DDC_CTRL_ADDR, addr_id));
+	usleep_range(1000, 1250);
+
+	ret = regmap_read_poll_timeout(ddc->regs, HPD_DDC_STATUS, val,
+				       !(val & DDC_I2C_IN_PROG), 500, 1000);
+	if (ret) {
+		dev_err(ddc->dev, "DDC I2C write timeout\n");
+		return ret;
+	}
+
+	/* The I2C bus might be down after WR operation: rise it again */
+	ret = mtk_ddc_check_and_rise_low_bus(ddc);
+	if (ret) {
+		dev_err(ddc->dev, "Error during write operation: No ACK\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mtk_ddcm_read_hdmi(struct mtk_hdmi_ddc *ddc, u16 dly_cnt, u16 uc_dev,
+			      u8 addr, u8 *puc_value, u16 data_cnt)
+{
+	u16 i, loop_counter, temp_length, uc_idx;
+	u32 rem, uc_read_count, val;
+	int ret;
+
+	if (!puc_value || !data_cnt || !dly_cnt) {
+		dev_err(ddc->dev, "Bad DDCM read request\n");
+		return 0;
+	}
+
+	mtk_ddc_check_and_rise_low_bus(ddc);
+
+	regmap_update_bits(ddc->regs, DDC_CTRL, DDC_CTRL_CMD,
+			   FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_CLEAR_FIFO));
+
+	if (data_cnt >= 16) {
+		temp_length = 16;
+		loop_counter = data_cnt;
+
+		rem = do_div(loop_counter, temp_length);
+		if (rem)
+			loop_counter++;
+	} else {
+		temp_length = data_cnt;
+		loop_counter = 1;
+	}
+
+	if (uc_dev >= DDC_ADDR && dly_cnt < DDC2_DLY_CNT_EDID)
+		dly_cnt = DDC2_DLY_CNT_EDID;
+
+	regmap_update_bits(ddc->regs, HPD_DDC_CTRL, HPD_DDC_DELAY_CNT,
+			   FIELD_PREP(HPD_DDC_DELAY_CNT, dly_cnt));
+
+	for (i = 0; i < loop_counter; i++) {
+		rem = data_cnt % 16;
+
+		if (i > 0 && i == (loop_counter - 1) && rem)
+			temp_length = rem;
+
+		/* 0x51 - 0x53: Flow control */
+		if (uc_dev > DDC_ADDR && uc_dev <= 0x53) {
+			regmap_update_bits(ddc->regs, SCDC_CTRL, SCDC_DDC_SEGMENT,
+					   FIELD_PREP(SCDC_DDC_SEGMENT, uc_dev - DDC_ADDR));
+
+			regmap_write(ddc->regs, DDC_CTRL,
+				     FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_ENH_READ_NOACK) |
+				     FIELD_PREP(DDC_CTRL_DIN_CNT, temp_length) |
+				     FIELD_PREP(DDC_CTRL_OFFSET, addr + i * temp_length) |
+				     FIELD_PREP(DDC_CTRL_ADDR, DDC_ADDR));
+		} else {
+			u16 offset;
+
+			if (addr != 0x43)
+				offset = i * 16;
+			else
+				offset = 0;
+
+			regmap_write(ddc->regs, DDC_CTRL,
+				     FIELD_PREP(DDC_CTRL_CMD, DDC_CMD_SEQ_READ_NOACK) |
+				     FIELD_PREP(DDC_CTRL_DIN_CNT, temp_length) |
+				     FIELD_PREP(DDC_CTRL_OFFSET, addr + offset) |
+				     FIELD_PREP(DDC_CTRL_ADDR, uc_dev));
+		}
+		usleep_range(5000, 5500);
+
+		ret = regmap_read_poll_timeout(ddc->regs, HPD_DDC_STATUS, val,
+					       !(val & DDC_I2C_IN_PROG), 1000,
+					       500 * (temp_length + 5));
+		if (ret) {
+			dev_err(ddc->dev, "Timeout waiting for DDC I2C\n");
+			return ret;
+		}
+
+		ret = mtk_ddc_check_and_rise_low_bus(ddc);
+		if (ret) {
+			dev_err(ddc->dev, "Error during read operation: No ACK\n");
+			return ret;
+		}
+
+		for (uc_idx = 0; uc_idx < temp_length; uc_idx++) {
+			unsigned int read_idx = i * 16 + uc_idx;
+
+			regmap_write(ddc->regs, SI2C_CTRL,
+				     FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
+				     SI2C_RD);
+
+			regmap_read(ddc->regs, HPD_DDC_STATUS, &val);
+			puc_value[read_idx] = FIELD_GET(DDC_DATA_OUT, val);
+
+			regmap_write(ddc->regs, SI2C_CTRL,
+				     FIELD_PREP(SI2C_ADDR, SI2C_ADDR_READ) |
+				     SI2C_CONFIRM_READ);
+
+			/*
+			 * If HDMI IP gets reset during EDID read, DDC read
+			 * operation will fail and its delay counter will be
+			 * reset to 400.
+			 */
+			regmap_read(ddc->regs, HPD_DDC_CTRL, &val);
+			if (FIELD_GET(HPD_DDC_DELAY_CNT, val) < DDC2_DLY_CNT)
+				return 0;
+
+			uc_read_count = read_idx + 1;
+		}
+	}
+	if (uc_read_count > U8_MAX)
+		dev_warn(ddc->dev, "Invalid read data count %u\n", uc_read_count);
+
+	return uc_read_count;
+}
+
+static int mtk_hdmi_fg_ddc_data_read(struct mtk_hdmi_ddc *ddc, u16 b_dev,
+				     u8 data_addr, u16 data_cnt, u8 *pr_data)
+{
+	int read_data_cnt;
+	u16 req_data_cnt;
+
+	if (!pr_data || !data_cnt)
+		return -EINVAL;
+
+	req_data_cnt = U8_MAX - data_addr + 1;
+	if (req_data_cnt > data_cnt)
+		req_data_cnt = data_cnt;
+
+	mutex_lock(&ddc->mtx);
+
+	regmap_set_bits(ddc->regs, HDCP2X_POL_CTRL, HDCP2X_DIS_POLL_EN);
+
+	read_data_cnt = mtk_ddcm_read_hdmi(ddc, DDC2_DLY_CNT, b_dev, data_addr,
+					   pr_data, req_data_cnt);
+
+	mutex_unlock(&ddc->mtx);
+
+	if (read_data_cnt < 0)
+		return read_data_cnt;
+	else if (read_data_cnt != req_data_cnt)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int mtk_hdmi_ddc_fg_data_write(struct mtk_hdmi_ddc *ddc, u16 b_dev,
+				      u8 data_addr, u16 data_cnt, u8 *pr_data)
+{
+	int i = 0, ret;
+
+	mutex_lock(&ddc->mtx);
+
+	regmap_set_bits(ddc->regs, HDCP2X_POL_CTRL, HDCP2X_DIS_POLL_EN);
+	do {
+		ret = mtk_ddc_wr_one(ddc, b_dev, data_addr + i, pr_data[i]);
+		if (ret)
+			break;
+	} while (++i < data_cnt);
+
+	mutex_unlock(&ddc->mtx);
+
+	return ret;
+}
+
+static int mtk_hdmi_ddc_v2_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+	struct mtk_hdmi_ddc *ddc;
+	u8 offset = 0;
+	int i, ret;
+
+	if (!adapter || !adapter->algo_data || !msgs)
+		return -EINVAL;
+
+	ddc = adapter->algo_data;
+
+	for (i = 0; i < num; i++) {
+		struct i2c_msg *msg = &msgs[i];
+
+		if (!msg->buf) {
+			pr_err("XFER: No message buffer\n");
+			return -EINVAL;
+		}
+
+		if (msg->flags & I2C_M_RD) {
+			/*
+			 * The underlying DDC hardware always issues a write request
+			 * that assigns the read offset as part of the read operation,
+			 * therefore, use the `offset` value assigned in the previous
+			 * write request from drm_edid
+			 */
+			ret = mtk_hdmi_fg_ddc_data_read(ddc, msg->addr, offset,
+							msg->len, &msg->buf[0]);
+			if (ret)
+				return ret;
+		} else {
+			ret = mtk_hdmi_ddc_fg_data_write(ddc, msg->addr, msg->buf[0],
+							 msg->len - 1, &msg->buf[1]);
+			if (ret)
+				return ret;
+
+			/*
+			 * Store the offset value requested by drm_edid or by
+			 * scdc to use in subsequent read requests.
+			 */
+			if ((msg->addr == DDC_ADDR || msg->addr == SCDC_I2C_SLAVE_ADDRESS) &&
+			    msg->len == 1) {
+				offset = msg->buf[0];
+			}
+		}
+	}
+
+	return i;
+}
+
+static u32 mtk_hdmi_ddc_v2_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm mtk_hdmi_ddc_v2_algorithm = {
+	.master_xfer = mtk_hdmi_ddc_v2_xfer,
+	.functionality = mtk_hdmi_ddc_v2_func,
+};
+
+static int mtk_hdmi_ddc_v2_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_hdmi_ddc *ddc;
+	int ret;
+
+	ddc = devm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL);
+	if (!ddc)
+		return -ENOMEM;
+
+	ddc->dev = dev;
+	ddc->regs = device_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR_OR_NULL(ddc->regs))
+		return dev_err_probe(dev,
+				     IS_ERR(ddc->regs) ? PTR_ERR(ddc->regs) : -EINVAL,
+				     "Cannot get regmap\n");
+
+	ddc->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(ddc->clk))
+		return dev_err_probe(dev, PTR_ERR(ddc->clk), "Cannot get DDC clock\n");
+
+	mutex_init(&ddc->mtx);
+
+	strscpy(ddc->adap.name, "mediatek-hdmi-ddc-v2", sizeof(ddc->adap.name));
+	ddc->adap.owner = THIS_MODULE;
+	ddc->adap.algo = &mtk_hdmi_ddc_v2_algorithm;
+	ddc->adap.retries = 3;
+	ddc->adap.dev.of_node = dev->of_node;
+	ddc->adap.algo_data = ddc;
+	ddc->adap.dev.parent = &pdev->dev;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Cannot enable Runtime PM\n");
+
+	pm_runtime_get_sync(dev);
+
+	ret = devm_i2c_add_adapter(dev, &ddc->adap);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Cannot add DDC I2C adapter\n");
+
+	platform_set_drvdata(pdev, ddc);
+	return 0;
+}
+
+static const struct of_device_id mtk_hdmi_ddc_v2_match[] = {
+	{ .compatible = "mediatek,mt8195-hdmi-ddc" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_v2_match);
+
+struct platform_driver mtk_hdmi_ddc_v2_driver = {
+	.probe = mtk_hdmi_ddc_v2_probe,
+	.driver = {
+		.name = "mediatek-hdmi-ddc-v2",
+		.of_match_table = mtk_hdmi_ddc_v2_match,
+	},
+};
+module_platform_driver(mtk_hdmi_ddc_v2_driver);
+
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>");
+MODULE_AUTHOR("Can Zeng <can.zeng at mediatek.com>");
+MODULE_DESCRIPTION("MediaTek HDMIv2 DDC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h b/drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
new file mode 100644
index 000000000000..521b35c7e14d
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_regs_v2.h
@@ -0,0 +1,263 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre, SAS
+ * Copyright (c) 2024 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+ */
+
+#ifndef _MTK_HDMI_REGS_H
+#define _MTK_HDMI_REGS_H
+
+/* HDMI_TOP Config */
+#define TOP_CFG00			0x000
+#define  HDMI2_ON			BIT(2)
+#define  HDMI_MODE_HDMI			BIT(3)
+#define  SCR_ON				BIT(4)
+#define  TMDS_PACK_MODE			GENMASK(9, 8)
+#define   TMDS_PACK_MODE_8BPP		0
+#define   TMDS_PACK_MODE_10BPP		1
+#define   TMDS_PACK_MODE_12BPP		2
+#define   TMDS_PACK_MODE_16BPP		3
+#define  DEEPCOLOR_PKT_EN		BIT(12)
+#define  HDMI_ABIST_VIDEO_FORMAT	GENMASK(21, 16)
+#define  HDMI_ABIST_ENABLE		BIT(31)
+#define TOP_CFG01 0x004
+#define  CP_SET_MUTE_EN			BIT(0)
+#define  CP_CLR_MUTE_EN			BIT(1)
+#define  NULL_PKT_EN			BIT(2)
+#define  NULL_PKT_VSYNC_HIGH_EN		BIT(3)
+
+/* HDMI_TOP Audio: Channel Mapping */
+#define TOP_AUD_MAP			0x00c
+#define  SD0_MAP			GENMASK(2, 0)
+#define  SD1_MAP			GENMASK(6, 4)
+#define  SD2_MAP			GENMASK(10, 8)
+#define  SD3_MAP			GENMASK(14, 12)
+#define  SD4_MAP			GENMASK(18, 16)
+#define  SD5_MAP			GENMASK(22, 20)
+#define  SD6_MAP			GENMASK(26, 24)
+#define  SD7_MAP			GENMASK(30, 28)
+
+/* Auxiliary Video Information (AVI) Infoframe */
+#define TOP_AVI_HEADER			0x024
+#define TOP_AVI_PKT00			0x028
+#define TOP_AVI_PKT01			0x02C
+#define TOP_AVI_PKT02			0x030
+#define TOP_AVI_PKT03			0x034
+#define TOP_AVI_PKT04			0x038
+#define TOP_AVI_PKT05			0x03C
+
+/* Audio Interface Infoframe */
+#define TOP_AIF_HEADER			0x040
+#define TOP_AIF_PKT00			0x044
+#define TOP_AIF_PKT01			0x048
+#define TOP_AIF_PKT02			0x04c
+#define TOP_AIF_PKT03			0x050
+
+/* Audio SPDIF Infoframe */
+#define TOP_SPDIF_HEADER		0x054
+#define TOP_SPDIF_PKT00			0x058
+#define TOP_SPDIF_PKT01			0x05c
+#define TOP_SPDIF_PKT02			0x060
+#define TOP_SPDIF_PKT03			0x064
+#define TOP_SPDIF_PKT04			0x068
+#define TOP_SPDIF_PKT05			0x06c
+#define TOP_SPDIF_PKT06			0x070
+#define TOP_SPDIF_PKT07			0x074
+
+/* Infoframes Configuration */
+#define TOP_INFO_EN			0x01c
+#define  AVI_EN				BIT(0)
+#define  SPD_EN				BIT(1)
+#define  AUD_EN				BIT(2)
+#define  CP_EN				BIT(5)
+#define  VSIF_EN			BIT(11)
+#define  AVI_EN_WR			BIT(16)
+#define  SPD_EN_WR			BIT(17)
+#define  AUD_EN_WR			BIT(18)
+#define  CP_EN_WR			BIT(21)
+#define  VSIF_EN_WR			BIT(27)
+#define TOP_INFO_RPT			0x020
+#define  AVI_RPT_EN			BIT(0)
+#define  SPD_RPT_EN			BIT(1)
+#define  AUD_RPT_EN			BIT(2)
+#define  CP_RPT_EN			BIT(5)
+#define  VSIF_RPT_EN			BIT(11)
+
+/* Vendor Specific Infoframe */
+#define TOP_VSIF_HEADER			0x174
+#define TOP_VSIF_PKT00			0x178
+#define TOP_VSIF_PKT01			0x17c
+#define TOP_VSIF_PKT02			0x180
+#define TOP_VSIF_PKT03			0x184
+#define TOP_VSIF_PKT04			0x188
+#define TOP_VSIF_PKT05			0x18c
+#define TOP_VSIF_PKT06			0x190
+#define TOP_VSIF_PKT07			0x194
+
+/* HDMI_TOP Misc */
+#define TOP_MISC_CTLR			0x1a4
+#define  DEEP_COLOR_ADD			BIT(4)
+
+/* Hardware interrupts */
+#define TOP_INT_STA00			0x1a8
+#define TOP_INT_ENABLE00		0x1b0
+#define  HTPLG_R_INT			BIT(0)
+#define  HTPLG_F_INT			BIT(1)
+#define  PORD_R_INT			BIT(2)
+#define  PORD_F_INT			BIT(3)
+#define  HDMI_VSYNC_INT			BIT(4)
+#define  HDMI_AUDIO_INT			BIT(5)
+#define  HDCP2X_RX_REAUTH_REQ_DDCM_INT	BIT(25)
+#define TOP_INT_ENABLE01		0x1b4
+#define TOP_INT_CLR00			0x1b8
+#define TOP_INT_CLR01			0x1bc
+
+
+/* Video Mute */
+#define TOP_VMUTE_CFG1			0x1c8
+#define  REG_VMUTE_EN			BIT(16)
+
+/* HDMI Audio IP */
+#define AIP_CTRL			0x400
+#define  CTS_SW_SEL			BIT(0)
+#define  CTS_REQ_EN			BIT(1)
+#define  MCLK_EN			BIT(2)
+#define  NO_MCLK_CTSGEN_SEL		BIT(3)
+#define  AUD_IN_EN			BIT(8)
+#define  AUD_SEL_OWRT			BIT(9)
+#define  SPDIF_EN			BIT(13)
+#define  HBRA_ON			BIT(14)
+#define  DSD_EN				BIT(15)
+#define  I2S_EN				GENMASK(19, 16)
+#define  HBR_FROM_SPDIF			BIT(20)
+#define  CTS_CAL_N4			BIT(23)
+#define  SPDIF_INTERNAL_MODULE		BIT(24)
+#define AIP_N_VAL			0x404
+#define AIP_CTS_SVAL			0x408
+#define AIP_SPDIF_CTRL			0x40c
+#define  WR_1UI_LOCK			BIT(0)
+#define  FS_OVERRIDE_WRITE		BIT(1)
+#define  WR_2UI_LOCK			BIT(2)
+#define  MAX_1UI_WRITE			GENMASK(15, 8)
+#define  MAX_2UI_SPDIF_WRITE		GENMASK(23, 16)
+#define  MAX_2UI_I2S_HI_WRITE		GENMASK(23, 20)
+#define   MAX_2UI_I2S_LFE_CC_SWAP	BIT(1)
+#define  MAX_2UI_I2S_LO_WRITE		GENMASK(19, 16)
+#define  AUD_ERR_THRESH			GENMASK(29, 24)
+#define  I2S2DSD_EN			BIT(30)
+#define AIP_I2S_CTRL			0x410
+#define  FIFO0_MAP			GENMASK(1, 0)
+#define  FIFO1_MAP			GENMASK(3, 2)
+#define  FIFO2_MAP			GENMASK(5, 4)
+#define  FIFO3_MAP			GENMASK(7, 6)
+#define  I2S_1ST_BIT_NOSHIFT		BIT(8)
+#define  I2S_DATA_DIR_LSB		BIT(9)
+#define  JUSTIFY_RIGHT			BIT(10)
+#define  WS_HIGH			BIT(11)
+#define  VBIT_COMPRESSED		BIT(12)
+#define  CBIT_ORDER_SAME		BIT(13)
+#define  SCK_EDGE_RISE			BIT(14)
+#define AIP_I2S_CHST0			0x414
+#define AIP_I2S_CHST1			0x418
+#define AIP_TXCTRL			0x424
+#define  RST4AUDIO			BIT(0)
+#define  RST4AUDIO_FIFO			BIT(1)
+#define  RST4AUDIO_ACR			BIT(2)
+#define  AUD_LAYOUT_1			BIT(4)
+#define  AUD_MUTE_FIFO_EN		BIT(5)
+#define  AUD_PACKET_DROP		BIT(6)
+#define  DSD_MUTE_EN			BIT(7)
+#define AIP_TPI_CTRL			0x428
+#define  TPI_AUDIO_LOOKUP_EN		BIT(2)
+
+/* Video downsampling configuration */
+#define VID_DOWNSAMPLE_CONFIG		0x8d0
+#define  C444_C422_CONFIG_ENABLE	BIT(0)
+#define  C422_C420_CONFIG_ENABLE	BIT(4)
+#define  C422_C420_CONFIG_BYPASS	BIT(5)
+#define  C422_C420_CONFIG_OUT_CB_OR_CR	BIT(6)
+#define VID_OUT_FORMAT			0x8fc
+#define  OUTPUT_FORMAT_DEMUX_420_ENABLE	BIT(10)
+
+/* HDCP registers */
+#define HDCP_TOP_CTRL			0xc00
+#define HDCP2X_CTRL_0			0xc20
+#define  HDCP2X_EN			BIT(0)
+#define  HDCP2X_ENCRYPT_EN		BIT(7)
+#define  HDCP2X_HPD_OVR			BIT(10)
+#define  HDCP2X_HPD_SW			BIT(11)
+#define HDCP2X_POL_CTRL			0xc54
+#define  HDCP2X_DIS_POLL_EN		BIT(16)
+#define HDCP1X_CTRL			0xcd0
+#define  HDCP1X_ENC_EN			BIT(6)
+
+/* HDMI DDC registers */
+#define HPD_DDC_CTRL			0xc08
+#define  HPD_DDC_DELAY_CNT		GENMASK(31, 16)
+#define  HPD_DDC_HPD_DBNC_EN		BIT(2)
+#define  HPD_DDC_PORD_DBNC_EN		BIT(3)
+#define DDC_CTRL			0xc10
+#define  DDC_CTRL_ADDR			GENMASK(7, 1)
+#define  DDC_CTRL_OFFSET		GENMASK(15, 8)
+#define  DDC_CTRL_DIN_CNT		GENMASK(25, 16)
+#define  DDC_CTRL_CMD			GENMASK(31, 28)
+#define SCDC_CTRL			0xc18
+#define  SCDC_DDC_SEGMENT		GENMASK(15, 8)
+#define HPD_DDC_STATUS			0xc60
+#define  HPD_STATE			GENMASK(1, 0)
+#define   HPD_STATE_CONNECTED		2
+#define  HPD_PIN_STA			BIT(4)
+#define  PORD_PIN_STA			BIT(5)
+#define  DDC_I2C_IN_PROG		BIT(13)
+#define  DDC_DATA_OUT			GENMASK(23, 16)
+#define SI2C_CTRL			0xcac
+#define  SI2C_WR			BIT(0)
+#define  SI2C_RD			BIT(1)
+#define  SI2C_CONFIRM_READ		BIT(2)
+#define  SI2C_WDATA			GENMASK(15, 8)
+#define  SI2C_ADDR			GENMASK(23, 16)
+
+/* HDCP DDC registers */
+#define HDCP2X_DDCM_STATUS		0xc68
+#define  DDC_I2C_NO_ACK			BIT(10)
+#define  DDC_I2C_BUS_LOW		BIT(11)
+
+/* HDMI TX registers */
+#define HDMITX_CONFIG_MT8188		0xea0
+#define HDMITX_CONFIG_MT8195		0x900
+#define  HDMI_YUV420_MODE		BIT(10)
+#define  HDMITX_SW_HPD			BIT(29)
+#define  HDMITX_SW_RSTB			BIT(31)
+
+/**
+ * enum mtk_hdmi_ddc_v2_cmds - DDC_CMD register commands
+ * @DDC_CMD_READ_NOACK:      Current address read with no ACK on last byte
+ * @DDC_CMD_READ:            Current address read with ACK on last byte
+ * @DDC_CMD_SEQ_READ_NOACK:  Sequential read with no ACK on last byte
+ * @DDC_CMD_SEQ_READ:        Sequential read with ACK on last byte
+ * @DDC_CMD_ENH_READ_NOACK:  Enhanced read with no ACK on last byte
+ * @DDC_CMD_ENH_READ:        Enhanced read with ACK on last byte
+ * @DDC_CMD_SEQ_WRITE_NOACK: Sequential write ignoring ACK on last byte
+ * @DDC_CMD_SEQ_WRITE:       Sequential write requiring ACK on last byte
+ * @DDC_CMD_RSVD:            Reserved for future use
+ * @DDC_CMD_CLEAR_FIFO:      Clear DDC I2C FIFO
+ * @DDC_CMD_CLOCK_SCL:       Start clocking DDC I2C SCL
+ * @DDC_CMD_ABORT_XFER:      Abort DDC I2C transaction
+ */
+enum mtk_hdmi_ddc_v2_cmds {
+	DDC_CMD_READ_NOACK = 0x0,
+	DDC_CMD_READ,
+	DDC_CMD_SEQ_READ_NOACK,
+	DDC_CMD_SEQ_READ,
+	DDC_CMD_ENH_READ_NOACK,
+	DDC_CMD_ENH_READ,
+	DDC_CMD_SEQ_WRITE_NOACK,
+	DDC_CMD_SEQ_WRITE = 0x07,
+	DDC_CMD_CLEAR_FIFO = 0x09,
+	DDC_CMD_CLOCK_SCL = 0x0a,
+	DDC_CMD_ABORT_XFER = 0x0f
+};
+
+#endif /* _MTK_HDMI_REGS_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
new file mode 100644
index 000000000000..c71ecc3c1711
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
@@ -0,0 +1,1384 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek HDMI v2 IP driver
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre, SAS
+ * Copyright (c) 2024 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/suspend.h>
+#include <linux/timer.h>
+#include <linux/units.h>
+
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_hdmi_state_helper.h>
+#include <drm/display/drm_scdc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+
+#include "mtk_hdmi_common.h"
+#include "mtk_hdmi_regs_v2.h"
+
+#define MTK_HDMI_V2_CLOCK_MIN	27000
+#define MTK_HDMI_V2_CLOCK_MAX	594000
+
+#define HPD_PORD_HWIRQS		(HTPLG_R_INT | HTPLG_F_INT | PORD_F_INT | PORD_R_INT)
+
+enum mtk_hdmi_v2_clk_id {
+	MTK_HDMI_V2_CLK_HDCP_SEL,
+	MTK_HDMI_V2_CLK_HDCP_24M_SEL,
+	MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI,
+	MTK_HDMI_V2_CLK_HDMI_APB_SEL,
+	MTK_HDMI_V2_CLK_COUNT,
+};
+
+const char *const mtk_hdmi_v2_clk_names[MTK_HDMI_V2_CLK_COUNT] = {
+	[MTK_HDMI_V2_CLK_HDMI_APB_SEL] = "bus",
+	[MTK_HDMI_V2_CLK_HDCP_SEL] = "hdcp",
+	[MTK_HDMI_V2_CLK_HDCP_24M_SEL] = "hdcp24m",
+	[MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI] = "hdmi-split",
+};
+
+static inline void mtk_hdmi_v2_hwirq_disable(struct mtk_hdmi *hdmi)
+{
+	regmap_write(hdmi->regs, TOP_INT_ENABLE00, 0);
+	regmap_write(hdmi->regs, TOP_INT_ENABLE01, 0);
+}
+
+static inline void mtk_hdmi_v2_enable_hpd_pord_irq(struct mtk_hdmi *hdmi, bool enable)
+{
+	if (enable)
+		regmap_set_bits(hdmi->regs, TOP_INT_ENABLE00, HPD_PORD_HWIRQS);
+	else
+		regmap_clear_bits(hdmi->regs, TOP_INT_ENABLE00, HPD_PORD_HWIRQS);
+}
+
+static inline void mtk_hdmi_v2_clear_hpd_pord_irq(struct mtk_hdmi *hdmi)
+{
+	regmap_set_bits(hdmi->regs, TOP_INT_CLR00, HPD_PORD_HWIRQS);
+	regmap_clear_bits(hdmi->regs, TOP_INT_CLR00, HPD_PORD_HWIRQS);
+}
+
+static inline void mtk_hdmi_v2_set_sw_hpd(struct mtk_hdmi *hdmi, bool enable)
+{
+	if (enable) {
+		regmap_set_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_HPD);
+		regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_OVR);
+		regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_SW);
+	} else {
+		regmap_clear_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_OVR);
+		regmap_clear_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_SW);
+		regmap_clear_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_HPD);
+	}
+}
+
+static void mtk_hdmi_v2_disable_hdcp_encrypt(struct mtk_hdmi *hdmi)
+{
+	regmap_clear_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_ENCRYPT_EN);
+	regmap_clear_bits(hdmi->regs, HDCP1X_CTRL, HDCP1X_ENC_EN);
+}
+
+static inline void mtk_hdmi_v2_enable_scrambling(struct mtk_hdmi *hdmi, bool enable)
+{
+	struct drm_scdc *scdc = &hdmi->curr_conn->display_info.hdmi.scdc;
+
+	if (enable)
+		regmap_set_bits(hdmi->regs, TOP_CFG00, SCR_ON | HDMI2_ON);
+	else
+		regmap_clear_bits(hdmi->regs, TOP_CFG00, SCR_ON | HDMI2_ON);
+
+	if (scdc->supported) {
+		if (scdc->scrambling.supported)
+			drm_scdc_set_scrambling(hdmi->curr_conn, enable);
+		drm_scdc_set_high_tmds_clock_ratio(hdmi->curr_conn, enable);
+	}
+}
+
+static void mtk_hdmi_v2_hw_vid_mute(struct mtk_hdmi *hdmi, bool enable)
+{
+	/* If enabled, sends a black image */
+	if (enable)
+		regmap_set_bits(hdmi->regs, TOP_VMUTE_CFG1, REG_VMUTE_EN);
+	else
+		regmap_clear_bits(hdmi->regs, TOP_VMUTE_CFG1, REG_VMUTE_EN);
+}
+
+static void mtk_hdmi_v2_hw_aud_mute(struct mtk_hdmi *hdmi, bool enable)
+{
+	u32 aip, val;
+
+	if (!enable) {
+		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, AUD_MUTE_FIFO_EN);
+		return;
+	}
+
+	regmap_read(hdmi->regs, AIP_CTRL, &aip);
+
+	val = AUD_MUTE_FIFO_EN;
+	if (aip & DSD_EN)
+		val |= DSD_MUTE_EN;
+
+	regmap_update_bits(hdmi->regs, AIP_TXCTRL, val, val);
+}
+
+static void mtk_hdmi_v2_hw_reset(struct mtk_hdmi *hdmi)
+{
+	regmap_clear_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_RSTB);
+	udelay(5);
+	regmap_set_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg, HDMITX_SW_RSTB);
+}
+
+static inline u32 mtk_hdmi_v2_format_hw_packet(const u8 *buffer, u8 len)
+{
+	unsigned short i;
+	u32 val = 0;
+
+	for (i = 0; i < len; i++)
+		val |= buffer[i] << (i * 8);
+
+	return val;
+}
+
+static void mtk_hdmi_v2_hw_write_audio_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
+{
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
+
+	regmap_write(hdmi->regs, TOP_AIF_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
+	regmap_write(hdmi->regs, TOP_AIF_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 3));
+	regmap_write(hdmi->regs, TOP_AIF_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 2));
+	regmap_write(hdmi->regs, TOP_AIF_PKT02, 0);
+	regmap_write(hdmi->regs, TOP_AIF_PKT03, 0);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR);
+}
+
+static void mtk_hdmi_v2_hw_write_avi_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
+{
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
+
+	regmap_write(hdmi->regs, TOP_AVI_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
+	regmap_write(hdmi->regs, TOP_AVI_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 4));
+	regmap_write(hdmi->regs, TOP_AVI_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 3));
+	regmap_write(hdmi->regs, TOP_AVI_PKT02, mtk_hdmi_v2_format_hw_packet(&buffer[10], 4));
+	regmap_write(hdmi->regs, TOP_AVI_PKT03, mtk_hdmi_v2_format_hw_packet(&buffer[14], 3));
+	regmap_write(hdmi->regs, TOP_AVI_PKT04, 0);
+	regmap_write(hdmi->regs, TOP_AVI_PKT05, 0);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
+}
+
+static void mtk_hdmi_v2_hw_write_spd_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
+{
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
+
+	regmap_write(hdmi->regs, TOP_SPDIF_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 4));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 3));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT02, mtk_hdmi_v2_format_hw_packet(&buffer[10], 4));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT03, mtk_hdmi_v2_format_hw_packet(&buffer[14], 3));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT04, mtk_hdmi_v2_format_hw_packet(&buffer[17], 4));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT05, mtk_hdmi_v2_format_hw_packet(&buffer[21], 3));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT06, mtk_hdmi_v2_format_hw_packet(&buffer[24], 4));
+	regmap_write(hdmi->regs, TOP_SPDIF_PKT07, buffer[28]);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
+}
+
+static void mtk_hdmi_v2_hw_write_vendor_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer)
+{
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
+
+	regmap_write(hdmi->regs, TOP_VSIF_HEADER, mtk_hdmi_v2_format_hw_packet(&buffer[0], 3));
+	regmap_write(hdmi->regs, TOP_VSIF_PKT00, mtk_hdmi_v2_format_hw_packet(&buffer[3], 4));
+	regmap_write(hdmi->regs, TOP_VSIF_PKT01, mtk_hdmi_v2_format_hw_packet(&buffer[7], 2));
+	regmap_write(hdmi->regs, TOP_VSIF_PKT02, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT03, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT04, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT05, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT06, 0);
+	regmap_write(hdmi->regs, TOP_VSIF_PKT07, 0);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
+}
+
+static void mtk_hdmi_yuv420_downsampling(struct mtk_hdmi *hdmi, bool enable)
+{
+	u32 val;
+
+	regmap_read(hdmi->regs, VID_DOWNSAMPLE_CONFIG, &val);
+
+	if (enable) {
+		regmap_set_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg,
+				HDMI_YUV420_MODE | HDMITX_SW_HPD);
+
+		val |= C444_C422_CONFIG_ENABLE | C422_C420_CONFIG_ENABLE;
+		val |= C422_C420_CONFIG_OUT_CB_OR_CR;
+		val &= ~C422_C420_CONFIG_BYPASS;
+		regmap_write(hdmi->regs, VID_DOWNSAMPLE_CONFIG, val);
+
+		regmap_set_bits(hdmi->regs, VID_OUT_FORMAT, OUTPUT_FORMAT_DEMUX_420_ENABLE);
+	} else {
+		regmap_update_bits(hdmi->regs, hdmi->conf->reg_hdmi_tx_cfg,
+				   HDMI_YUV420_MODE | HDMITX_SW_HPD, HDMITX_SW_HPD);
+
+		val &= ~(C444_C422_CONFIG_ENABLE | C422_C420_CONFIG_ENABLE);
+		val &= ~C422_C420_CONFIG_OUT_CB_OR_CR;
+		val |= C422_C420_CONFIG_BYPASS;
+		regmap_write(hdmi->regs, VID_DOWNSAMPLE_CONFIG, val);
+
+		regmap_clear_bits(hdmi->regs, VID_OUT_FORMAT, OUTPUT_FORMAT_DEMUX_420_ENABLE);
+	}
+}
+
+static int mtk_hdmi_v2_setup_audio_infoframe(struct mtk_hdmi *hdmi)
+{
+	struct hdmi_codec_params *params = &hdmi->aud_param.codec_params;
+	struct hdmi_audio_infoframe frame;
+	u8 buffer[14];
+	ssize_t ret;
+
+	memcpy(&frame, &params->cea, sizeof(frame));
+
+	ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
+	if (ret < 0)
+		return ret;
+
+	mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
+
+	return 0;
+}
+
+static inline void mtk_hdmi_v2_hw_reset_av_mute_regs(struct mtk_hdmi *hdmi)
+{
+	/* GCP packet */
+	regmap_clear_bits(hdmi->regs, TOP_CFG01, CP_CLR_MUTE_EN | CP_SET_MUTE_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, CP_RPT_EN);
+	regmap_clear_bits(hdmi->regs, TOP_INFO_EN, CP_EN | CP_EN_WR);
+}
+
+static inline void mtk_hdmi_v2_hw_av_mute(struct mtk_hdmi *hdmi, bool mute)
+{
+	mtk_hdmi_v2_hw_reset_av_mute_regs(hdmi);
+
+	if (mute)
+		regmap_set_bits(hdmi->regs, TOP_CFG01, CP_SET_MUTE_EN);
+	else
+		regmap_set_bits(hdmi->regs, TOP_CFG01, CP_CLR_MUTE_EN);
+
+	regmap_set_bits(hdmi->regs, TOP_INFO_RPT, CP_RPT_EN);
+	regmap_set_bits(hdmi->regs, TOP_INFO_EN, CP_EN | CP_EN_WR);
+}
+
+static void mtk_hdmi_v2_hw_ncts_enable(struct mtk_hdmi *hdmi, bool enable)
+{
+	if (enable)
+		regmap_set_bits(hdmi->regs, AIP_CTRL, CTS_SW_SEL);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_CTRL, CTS_SW_SEL);
+}
+
+static void mtk_hdmi_v2_hw_aud_set_channel_status(struct mtk_hdmi *hdmi)
+{
+	u8 *ch_status = hdmi->aud_param.codec_params.iec.status;
+
+	/* Only the first 5 to 7 bytes of Channel Status contain useful information */
+	regmap_write(hdmi->regs, AIP_I2S_CHST0, mtk_hdmi_v2_format_hw_packet(&ch_status[0], 4));
+	regmap_write(hdmi->regs, AIP_I2S_CHST1, mtk_hdmi_v2_format_hw_packet(&ch_status[4], 3));
+}
+
+static void mtk_hdmi_v2_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
+				     unsigned int sample_rate,
+				     unsigned int clock)
+{
+	unsigned int n, cts;
+
+	mtk_hdmi_get_ncts(sample_rate, clock, &n, &cts);
+
+	regmap_write(hdmi->regs, AIP_N_VAL, n);
+	regmap_write(hdmi->regs, AIP_CTS_SVAL, cts);
+}
+
+static void mtk_hdmi_v2_hw_aud_enable(struct mtk_hdmi *hdmi, bool enable)
+{
+	if (enable)
+		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, AUD_PACKET_DROP);
+	else
+		regmap_set_bits(hdmi->regs, AIP_TXCTRL, AUD_PACKET_DROP);
+}
+
+static u32 mtk_hdmi_v2_aud_output_channel_map(u8 sd0, u8 sd1, u8 sd2, u8 sd3,
+					      u8 sd4, u8 sd5, u8 sd6, u8 sd7)
+{
+	u32 val;
+
+	/*
+	 * Each of the Output Channels (0-7) can be mapped to get their input
+	 * from any of the available Input Channels (0-7): this function
+	 * takes input channel numbers and formats a value that must then
+	 * be written to the TOP_AUD_MAP hardware register by the caller.
+	 */
+	val = FIELD_PREP(SD0_MAP, sd0) | FIELD_PREP(SD1_MAP, sd1);
+	val |= FIELD_PREP(SD2_MAP, sd2) | FIELD_PREP(SD3_MAP, sd3);
+	val |= FIELD_PREP(SD4_MAP, sd4) | FIELD_PREP(SD5_MAP, sd5);
+	val |= FIELD_PREP(SD6_MAP, sd6) | FIELD_PREP(SD7_MAP, sd7);
+
+	return val;
+}
+
+static void mtk_hdmi_audio_dsd_config(struct mtk_hdmi *hdmi,
+				      unsigned char chnum, bool dsd_bypass)
+{
+	u32 channel_map;
+
+	regmap_update_bits(hdmi->regs, AIP_CTRL, SPDIF_EN | DSD_EN | HBRA_ON, DSD_EN);
+	regmap_set_bits(hdmi->regs, AIP_TXCTRL, DSD_MUTE_EN);
+
+	if (dsd_bypass)
+		channel_map = mtk_hdmi_v2_aud_output_channel_map(0, 2, 4, 6, 1, 3, 5, 7);
+	else
+		channel_map = mtk_hdmi_v2_aud_output_channel_map(0, 5, 1, 0, 3, 2, 4, 0);
+
+	regmap_write(hdmi->regs, TOP_AUD_MAP, channel_map);
+	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, I2S2DSD_EN);
+}
+
+static inline void mtk_hdmi_v2_hw_i2s_fifo_map(struct mtk_hdmi *hdmi, u32 fifo_mapping)
+{
+	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL,
+			   FIFO0_MAP | FIFO1_MAP | FIFO2_MAP | FIFO3_MAP, fifo_mapping);
+}
+
+static inline void mtk_hdmi_v2_hw_i2s_ch_number(struct mtk_hdmi *hdmi, u8 chnum)
+{
+	regmap_update_bits(hdmi->regs, AIP_CTRL, I2S_EN, FIELD_PREP(I2S_EN, chnum));
+}
+
+static void mtk_hdmi_v2_hw_i2s_ch_mapping(struct mtk_hdmi *hdmi, u8 chnum, u8 mapping)
+{
+	u32 fifo_map;
+	u8 bdata;
+
+	switch (chnum) {
+	default:
+	case 2:
+		bdata = 0x1;
+		break;
+	case 3:
+		bdata = 0x3;
+		break;
+	case 6:
+		if (mapping == 0x0e) {
+			bdata = 0xf;
+			break;
+		}
+		fallthrough;
+	case 5:
+		bdata = 0x7;
+		break;
+	case 7:
+	case 8:
+		bdata = 0xf;
+		break;
+	}
+
+	/* Assign default FIFO mapping: SD0 to FIFO0, SD1 to FIFO1, etc. */
+	fifo_map = FIELD_PREP(FIFO0_MAP, 0) | FIELD_PREP(FIFO1_MAP, 1);
+	fifo_map |= FIELD_PREP(FIFO2_MAP, 2) | FIELD_PREP(FIFO3_MAP, 3);
+	mtk_hdmi_v2_hw_i2s_fifo_map(hdmi, fifo_map);
+	mtk_hdmi_v2_hw_i2s_ch_number(hdmi, bdata);
+
+	/*
+	 * Set HDMI Audio packet layout indicator:
+	 * Layout 0 is for two channels
+	 * Layout 1 is for up to eight channels
+	 */
+	if (chnum == 2)
+		regmap_set_bits(hdmi->regs, AIP_TXCTRL, AUD_LAYOUT_1);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, AUD_LAYOUT_1);
+}
+
+static void mtk_hdmi_i2s_data_fmt(struct mtk_hdmi *hdmi, unsigned char fmt)
+{
+	u32 val;
+
+	regmap_read(hdmi->regs, AIP_I2S_CTRL, &val);
+	val &= ~(WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT);
+
+	switch (fmt) {
+	case HDMI_I2S_MODE_RJT_24BIT:
+	case HDMI_I2S_MODE_RJT_16BIT:
+		val |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT);
+		break;
+	case HDMI_I2S_MODE_LJT_24BIT:
+	case HDMI_I2S_MODE_LJT_16BIT:
+		val |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT);
+		break;
+	case HDMI_I2S_MODE_I2S_24BIT:
+	case HDMI_I2S_MODE_I2S_16BIT:
+	default:
+		break;
+	}
+
+	regmap_write(hdmi->regs, AIP_I2S_CTRL, val);
+}
+
+static inline void mtk_hdmi_i2s_sck_edge_rise(struct mtk_hdmi *hdmi, bool rise)
+{
+	if (rise)
+		regmap_set_bits(hdmi->regs, AIP_I2S_CTRL, SCK_EDGE_RISE);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_I2S_CTRL, SCK_EDGE_RISE);
+}
+
+static inline void mtk_hdmi_i2s_cbit_order(struct mtk_hdmi *hdmi, unsigned int cbit)
+{
+	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL, CBIT_ORDER_SAME, cbit);
+}
+
+static inline void mtk_hdmi_i2s_vbit(struct mtk_hdmi *hdmi, unsigned int vbit)
+{
+	/* V bit: 0 for PCM, 1 for Compressed data */
+	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL, VBIT_COMPRESSED, vbit);
+}
+
+static inline void mtk_hdmi_i2s_data_direction(struct mtk_hdmi *hdmi, unsigned int is_lsb)
+{
+	regmap_update_bits(hdmi->regs, AIP_I2S_CTRL, I2S_DATA_DIR_LSB, is_lsb);
+}
+
+static inline void mtk_hdmi_v2_hw_audio_type(struct mtk_hdmi *hdmi, unsigned int spdif_i2s)
+{
+	regmap_update_bits(hdmi->regs, AIP_CTRL, SPDIF_EN, FIELD_PREP(SPDIF_EN, spdif_i2s));
+}
+
+static u8 mtk_hdmi_v2_get_i2s_ch_mapping(struct mtk_hdmi *hdmi, u8 channel_type)
+{
+	switch (channel_type) {
+	case HDMI_AUD_CHAN_TYPE_1_1:
+	case HDMI_AUD_CHAN_TYPE_2_1:
+		return 0x01;
+	case HDMI_AUD_CHAN_TYPE_3_0:
+		return 0x02;
+	case HDMI_AUD_CHAN_TYPE_3_1:
+		return 0x03;
+	case HDMI_AUD_CHAN_TYPE_3_0_LRS:
+	case HDMI_AUD_CHAN_TYPE_4_0:
+		return 0x08;
+	case HDMI_AUD_CHAN_TYPE_5_1:
+		return 0x0b;
+	case HDMI_AUD_CHAN_TYPE_4_1_CLRS:
+	case HDMI_AUD_CHAN_TYPE_6_0:
+	case HDMI_AUD_CHAN_TYPE_6_0_CS:
+	case HDMI_AUD_CHAN_TYPE_6_0_CH:
+	case HDMI_AUD_CHAN_TYPE_6_0_OH:
+	case HDMI_AUD_CHAN_TYPE_6_0_CHR:
+		return 0x0e;
+	case HDMI_AUD_CHAN_TYPE_1_0:
+	case HDMI_AUD_CHAN_TYPE_2_0:
+	case HDMI_AUD_CHAN_TYPE_3_1_LRS:
+	case HDMI_AUD_CHAN_TYPE_4_1:
+	case HDMI_AUD_CHAN_TYPE_5_0:
+	case HDMI_AUD_CHAN_TYPE_4_0_CLRS:
+	case HDMI_AUD_CHAN_TYPE_6_1:
+	case HDMI_AUD_CHAN_TYPE_6_1_CS:
+	case HDMI_AUD_CHAN_TYPE_6_1_CH:
+	case HDMI_AUD_CHAN_TYPE_6_1_OH:
+	case HDMI_AUD_CHAN_TYPE_6_1_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_0:
+	case HDMI_AUD_CHAN_TYPE_7_0_LH_RH:
+	case HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR:
+	case HDMI_AUD_CHAN_TYPE_7_0_LC_RC:
+	case HDMI_AUD_CHAN_TYPE_7_0_LW_RW:
+	case HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD:
+	case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS:
+	case HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS:
+	case HDMI_AUD_CHAN_TYPE_7_0_CS_CH:
+	case HDMI_AUD_CHAN_TYPE_7_0_CS_OH:
+	case HDMI_AUD_CHAN_TYPE_7_0_CS_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_0_CH_OH:
+	case HDMI_AUD_CHAN_TYPE_7_0_CH_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_0_OH_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR:
+	case HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS:
+	case HDMI_AUD_CHAN_TYPE_7_1:
+	case HDMI_AUD_CHAN_TYPE_7_1_LH_RH:
+	case HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR:
+	case HDMI_AUD_CHAN_TYPE_7_1_LC_RC:
+	case HDMI_AUD_CHAN_TYPE_7_1_LW_RW:
+	case HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD:
+	case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS:
+	case HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS:
+	case HDMI_AUD_CHAN_TYPE_7_1_CS_CH:
+	case HDMI_AUD_CHAN_TYPE_7_1_CS_OH:
+	case HDMI_AUD_CHAN_TYPE_7_1_CS_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_1_CH_OH:
+	case HDMI_AUD_CHAN_TYPE_7_1_CH_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_1_OH_CHR:
+	case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR:
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
+static inline void mtk_hdmi_v2_hw_i2s_ch_swap(struct mtk_hdmi *hdmi, unsigned char swapbit)
+{
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_2UI_I2S_HI_WRITE,
+			   FIELD_PREP(MAX_2UI_I2S_HI_WRITE, swapbit));
+}
+
+static void mtk_hdmi_hbr_config(struct mtk_hdmi *hdmi, bool dsd_bypass)
+{
+	const u32 hbr_mask = SPDIF_EN | DSD_EN | HBRA_ON;
+
+	if (dsd_bypass) {
+		regmap_update_bits(hdmi->regs, AIP_CTRL, hbr_mask, HBRA_ON);
+		regmap_set_bits(hdmi->regs, AIP_CTRL, I2S_EN);
+	} else {
+		regmap_update_bits(hdmi->regs, AIP_CTRL, hbr_mask, SPDIF_EN);
+		regmap_set_bits(hdmi->regs, AIP_CTRL, SPDIF_INTERNAL_MODULE);
+		regmap_set_bits(hdmi->regs, AIP_CTRL, HBR_FROM_SPDIF);
+		regmap_set_bits(hdmi->regs, AIP_CTRL, CTS_CAL_N4);
+	}
+}
+
+static inline void mtk_hdmi_v2_hw_spdif_config(struct mtk_hdmi *hdmi)
+{
+	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, WR_1UI_LOCK);
+	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, FS_OVERRIDE_WRITE);
+	regmap_clear_bits(hdmi->regs, AIP_SPDIF_CTRL, WR_2UI_LOCK);
+
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_1UI_WRITE,
+			   FIELD_PREP(MAX_1UI_WRITE, 4));
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_2UI_SPDIF_WRITE,
+			   FIELD_PREP(MAX_2UI_SPDIF_WRITE, 9));
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, AUD_ERR_THRESH,
+			   FIELD_PREP(AUD_ERR_THRESH, 4));
+
+	regmap_set_bits(hdmi->regs, AIP_SPDIF_CTRL, I2S2DSD_EN);
+}
+
+static void mtk_hdmi_v2_aud_set_input(struct mtk_hdmi *hdmi)
+{
+	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
+	struct hdmi_codec_params *codec_params = &aud_param->codec_params;
+	u8 i2s_ch_map;
+	u32 out_ch_map;
+
+	/* Write the default output channel map. CH0 maps to SD0, CH1 maps to SD1, etc */
+	out_ch_map = mtk_hdmi_v2_aud_output_channel_map(0, 1, 2, 3, 4, 5, 6, 7);
+	regmap_write(hdmi->regs, TOP_AUD_MAP, out_ch_map);
+
+	regmap_update_bits(hdmi->regs, AIP_SPDIF_CTRL, MAX_2UI_I2S_HI_WRITE, 0);
+	regmap_clear_bits(hdmi->regs, AIP_CTRL,
+			  SPDIF_EN | DSD_EN | HBRA_ON | CTS_CAL_N4 |
+			  HBR_FROM_SPDIF | SPDIF_INTERNAL_MODULE);
+	regmap_clear_bits(hdmi->regs, AIP_TXCTRL, DSD_MUTE_EN | AUD_LAYOUT_1);
+
+	if (aud_param->aud_input_type == HDMI_AUD_INPUT_I2S) {
+		switch (aud_param->aud_codec) {
+		case HDMI_AUDIO_CODING_TYPE_DTS_HD:
+		case HDMI_AUDIO_CODING_TYPE_MLP:
+			mtk_hdmi_i2s_data_fmt(hdmi, aud_param->aud_i2s_fmt);
+			mtk_hdmi_hbr_config(hdmi, true);
+			break;
+		case HDMI_AUDIO_CODING_TYPE_DSD:
+			mtk_hdmi_audio_dsd_config(hdmi, codec_params->channels, 0);
+			mtk_hdmi_v2_hw_i2s_ch_mapping(hdmi, codec_params->channels, 1);
+			break;
+		default:
+			mtk_hdmi_i2s_data_fmt(hdmi, aud_param->aud_i2s_fmt);
+			mtk_hdmi_i2s_sck_edge_rise(hdmi, true);
+			mtk_hdmi_i2s_cbit_order(hdmi, CBIT_ORDER_SAME);
+			mtk_hdmi_i2s_vbit(hdmi, 0); /* PCM data */
+			mtk_hdmi_i2s_data_direction(hdmi, 0); /* MSB first */
+			mtk_hdmi_v2_hw_audio_type(hdmi, HDMI_AUD_INPUT_I2S);
+			i2s_ch_map = mtk_hdmi_v2_get_i2s_ch_mapping(hdmi,
+						aud_param->aud_input_chan_type);
+			mtk_hdmi_v2_hw_i2s_ch_mapping(hdmi, codec_params->channels, i2s_ch_map);
+			mtk_hdmi_v2_hw_i2s_ch_swap(hdmi, MAX_2UI_I2S_LFE_CC_SWAP);
+		}
+	} else {
+		if (codec_params->sample_rate == 768000 &&
+		    (aud_param->aud_codec == HDMI_AUDIO_CODING_TYPE_DTS_HD ||
+		     aud_param->aud_codec == HDMI_AUDIO_CODING_TYPE_MLP)) {
+			mtk_hdmi_hbr_config(hdmi, false);
+		} else {
+			mtk_hdmi_v2_hw_spdif_config(hdmi);
+			mtk_hdmi_v2_hw_i2s_ch_mapping(hdmi, 2, 0);
+		}
+	}
+}
+
+static void mtk_hdmi_v2_aud_set_sw_ncts(struct mtk_hdmi *hdmi,
+					struct drm_display_mode *display_mode)
+{
+	mtk_hdmi_v2_hw_ncts_enable(hdmi, false);
+	mtk_hdmi_v2_hw_aud_set_ncts(hdmi, hdmi->aud_param.codec_params.sample_rate,
+				 display_mode->clock);
+}
+
+static inline void mtk_hdmi_v2_hw_audio_input_enable(struct mtk_hdmi *hdmi, bool ena)
+{
+	if (ena)
+		regmap_set_bits(hdmi->regs, AIP_CTRL, AUD_IN_EN);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_CTRL, AUD_IN_EN);
+}
+
+static void mtk_hdmi_v2_aip_ctrl_init(struct mtk_hdmi *hdmi)
+{
+	regmap_set_bits(hdmi->regs, AIP_CTRL,
+			AUD_SEL_OWRT | NO_MCLK_CTSGEN_SEL | MCLK_EN | CTS_REQ_EN);
+	regmap_clear_bits(hdmi->regs, AIP_TPI_CTRL, TPI_AUDIO_LOOKUP_EN);
+}
+
+static void mtk_hdmi_v2_audio_reset(struct mtk_hdmi *hdmi, bool reset)
+{
+	const u32 arst_bits = RST4AUDIO | RST4AUDIO_FIFO | RST4AUDIO_ACR;
+
+	if (reset)
+		regmap_set_bits(hdmi->regs, AIP_TXCTRL, arst_bits);
+	else
+		regmap_clear_bits(hdmi->regs, AIP_TXCTRL, arst_bits);
+}
+
+static void mtk_hdmi_v2_aud_output_config(struct mtk_hdmi *hdmi,
+					  struct drm_display_mode *display_mode)
+{
+	mtk_hdmi_v2_hw_aud_mute(hdmi, true);
+	mtk_hdmi_v2_hw_aud_enable(hdmi, false);
+	mtk_hdmi_v2_audio_reset(hdmi, true);
+	mtk_hdmi_v2_aip_ctrl_init(hdmi);
+	mtk_hdmi_v2_aud_set_input(hdmi);
+	mtk_hdmi_v2_hw_aud_set_channel_status(hdmi);
+	mtk_hdmi_v2_setup_audio_infoframe(hdmi);
+	mtk_hdmi_v2_hw_audio_input_enable(hdmi, true);
+	mtk_hdmi_v2_audio_reset(hdmi, false);
+	mtk_hdmi_v2_aud_set_sw_ncts(hdmi, display_mode);
+
+	/* Wait for the HW to apply settings */
+	usleep_range(25, 50);
+
+	mtk_hdmi_v2_hw_ncts_enable(hdmi, true);
+	mtk_hdmi_v2_hw_aud_enable(hdmi, true);
+	mtk_hdmi_v2_hw_aud_mute(hdmi, false);
+}
+
+static void mtk_hdmi_v2_change_video_resolution(struct mtk_hdmi *hdmi)
+{
+	mtk_hdmi_v2_hw_reset(hdmi);
+	mtk_hdmi_v2_set_sw_hpd(hdmi, true);
+	udelay(2);
+
+	regmap_write(hdmi->regs, HDCP_TOP_CTRL, 0);
+
+	/* Enable HDCP reauthentication interrupt */
+	regmap_set_bits(hdmi->regs, TOP_INT_ENABLE00, HDCP2X_RX_REAUTH_REQ_DDCM_INT);
+
+	/* Enable hotplug and pord interrupts */
+	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
+
+	/* Force enabling HDCP HPD */
+	regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_OVR);
+	regmap_set_bits(hdmi->regs, HDCP2X_CTRL_0, HDCP2X_HPD_SW);
+
+	/* Set 8 bits per pixel */
+	regmap_update_bits(hdmi->regs, TOP_CFG00, TMDS_PACK_MODE,
+			   FIELD_PREP(TMDS_PACK_MODE, TMDS_PACK_MODE_8BPP));
+	/* Disable generating deepcolor packets */
+	regmap_clear_bits(hdmi->regs, TOP_CFG00, DEEPCOLOR_PKT_EN);
+	/* Disable adding deepcolor information to the general packet */
+	regmap_clear_bits(hdmi->regs, TOP_MISC_CTLR, DEEP_COLOR_ADD);
+
+	if (hdmi->curr_conn->display_info.is_hdmi)
+		regmap_set_bits(hdmi->regs, TOP_CFG00, HDMI_MODE_HDMI);
+	else
+		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_MODE_HDMI);
+
+	udelay(5);
+	mtk_hdmi_v2_hw_vid_mute(hdmi, true);
+	mtk_hdmi_v2_hw_aud_mute(hdmi, true);
+	mtk_hdmi_v2_hw_av_mute(hdmi, false);
+
+	regmap_update_bits(hdmi->regs, TOP_CFG01,
+			   NULL_PKT_VSYNC_HIGH_EN | NULL_PKT_EN, NULL_PKT_VSYNC_HIGH_EN);
+	usleep_range(100, 150);
+
+	/* Enable scrambling if tmds clock is 340MHz or more */
+	mtk_hdmi_v2_enable_scrambling(hdmi, hdmi->mode.clock >= 340 * KILO);
+
+	/* Disable YUV420 downsampling */
+	mtk_hdmi_yuv420_downsampling(hdmi, false);
+}
+
+static void mtk_hdmi_v2_output_set_display_mode(struct mtk_hdmi *hdmi,
+						struct drm_display_mode *mode)
+{
+	union phy_configure_opts opts = {
+		.dp = { .link_rate = hdmi->mode.clock * KILO }
+	};
+	int ret;
+
+	ret = phy_configure(hdmi->phy, &opts);
+	if (ret)
+		dev_err(hdmi->dev, "Setting clock=%d failed: %d", mode->clock, ret);
+
+	mtk_hdmi_v2_change_video_resolution(hdmi);
+	mtk_hdmi_v2_aud_output_config(hdmi, mode);
+}
+
+static int mtk_hdmi_v2_clk_enable(struct mtk_hdmi *hdmi)
+{
+	int ret;
+
+	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_24M_SEL]);
+	if (ret)
+		goto disable_hdcp_clk;
+
+	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_HDMI_APB_SEL]);
+	if (ret)
+		goto disable_hdcp_24m_clk;
+
+	ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI]);
+	if (ret)
+		goto disable_bus_clk;
+
+	return 0;
+
+disable_bus_clk:
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDMI_APB_SEL]);
+disable_hdcp_24m_clk:
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_24M_SEL]);
+disable_hdcp_clk:
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
+
+	return ret;
+}
+
+static void mtk_hdmi_v2_clk_disable(struct mtk_hdmi *hdmi)
+{
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_VPP_SPLIT_HDMI]);
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDMI_APB_SEL]);
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_24M_SEL]);
+	clk_disable_unprepare(hdmi->clk[MTK_HDMI_V2_CLK_HDCP_SEL]);
+}
+
+static void mtk_hdmi_hpd_event(enum hdmi_hpd_state hpd, struct device *dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	if (hdmi && hdmi->bridge.encoder && hdmi->bridge.encoder->dev)
+		drm_helper_hpd_irq_event(hdmi->bridge.encoder->dev);
+}
+
+static enum hdmi_hpd_state mtk_hdmi_v2_hpd_pord_status(struct mtk_hdmi *hdmi)
+{
+	u8 hpd_pin_sta, pord_pin_sta;
+	u32 hpd_status;
+
+	regmap_read(hdmi->regs, HPD_DDC_STATUS, &hpd_status);
+	hpd_pin_sta = FIELD_GET(HPD_PIN_STA, hpd_status);
+	pord_pin_sta = FIELD_GET(PORD_PIN_STA, hpd_status);
+
+	if (hpd_pin_sta && pord_pin_sta)
+		return HDMI_PLUG_IN_AND_SINK_POWER_ON;
+	else if (hpd_pin_sta)
+		return HDMI_PLUG_IN_ONLY;
+	else
+		return HDMI_PLUG_OUT;
+}
+
+static irqreturn_t mtk_hdmi_v2_isr(int irq, void *arg)
+{
+	struct mtk_hdmi *hdmi = arg;
+	unsigned int irq_sta;
+	int ret = IRQ_HANDLED;
+
+	regmap_read(hdmi->regs, TOP_INT_STA00, &irq_sta);
+
+	/* Handle Hotplug Detection interrupt */
+	if (irq_sta & (HTPLG_R_INT | HTPLG_F_INT | PORD_F_INT | PORD_R_INT)) {
+		mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, false);
+		ret = IRQ_WAKE_THREAD;
+	}
+
+	/*
+	 * Clear all 32 + 19 interrupts in CLR00 and CLR01: this is important
+	 * to avoid unwanted retriggering of any interrupts
+	 */
+	regmap_write(hdmi->regs, TOP_INT_CLR00, GENMASK(31, 0));
+	regmap_write(hdmi->regs, TOP_INT_CLR01, GENMASK(18, 0));
+
+	/* Restore interrupt clearing registers to zero */
+	regmap_write(hdmi->regs, TOP_INT_CLR00, 0);
+	regmap_write(hdmi->regs, TOP_INT_CLR01, 0);
+
+	return ret;
+}
+
+static irqreturn_t __mtk_hdmi_v2_isr_thread(struct mtk_hdmi *hdmi)
+{
+	enum hdmi_hpd_state hpd;
+
+	hpd = mtk_hdmi_v2_hpd_pord_status(hdmi);
+	if (hpd != hdmi->hpd) {
+		hdmi->hpd = hpd;
+		mtk_hdmi_hpd_event(hpd, hdmi->dev);
+	}
+
+	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t mtk_hdmi_v2_isr_thread(int irq, void *arg)
+{
+	struct mtk_hdmi *hdmi = arg;
+
+	/*
+	 * Debounce HDMI monitor HPD status.
+	 * Empirical testing shows that 30ms is enough wait
+	 */
+	msleep(30);
+
+	return __mtk_hdmi_v2_isr_thread(hdmi);
+}
+
+static int mtk_hdmi_v2_enable(struct mtk_hdmi *hdmi)
+{
+	bool was_active = pm_runtime_active(hdmi->dev);
+	int ret;
+
+	ret = pm_runtime_resume_and_get(hdmi->dev);
+	if (ret) {
+		dev_err(hdmi->dev, "Cannot resume HDMI\n");
+		return ret;
+	}
+
+	mtk_hdmi_v2_clk_enable(hdmi);
+	if (!was_active) {
+		mtk_hdmi_v2_hw_reset(hdmi);
+		mtk_hdmi_v2_set_sw_hpd(hdmi, true);
+	}
+
+	return 0;
+}
+
+static void mtk_hdmi_v2_disable(struct mtk_hdmi *hdmi)
+{
+	mtk_hdmi_v2_clk_disable(hdmi);
+	pm_runtime_put_sync(hdmi->dev);
+}
+
+/*
+ * Bridge callbacks
+ */
+
+static int mtk_hdmi_v2_bridge_attach(struct drm_bridge *bridge,
+				     enum drm_bridge_attach_flags flags)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+	int ret;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		DRM_ERROR("The flag DRM_BRIDGE_ATTACH_NO_CONNECTOR must be supplied\n");
+		return -EINVAL;
+	}
+	if (hdmi->next_bridge) {
+		ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge, bridge, flags);
+		if (ret)
+			return ret;
+	}
+
+	ret = mtk_hdmi_v2_enable(hdmi);
+	if (ret)
+		return ret;
+
+	/* Enable Hotplug and Pord pins internal debouncing */
+	regmap_set_bits(hdmi->regs, HPD_DDC_CTRL,
+			HPD_DDC_HPD_DBNC_EN | HPD_DDC_PORD_DBNC_EN);
+
+	irq_clear_status_flags(hdmi->irq, IRQ_NOAUTOEN);
+	enable_irq(hdmi->irq);
+
+	/*
+	 * Check if any HDMI monitor was connected before probing this driver
+	 * and/or attaching the bridge, without debouncing: if so, we want to
+	 * notify the DRM so that we start outputting an image ASAP.
+	 * Note that calling the ISR thread function will also perform a HW
+	 * registers write that enables both the HPD and Pord interrupts.
+	 */
+	__mtk_hdmi_v2_isr_thread(hdmi);
+
+	mtk_hdmi_v2_disable(hdmi);
+
+	return 0;
+}
+
+static void mtk_hdmi_v2_bridge_detach(struct drm_bridge *bridge)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	WARN_ON(pm_runtime_active(hdmi->dev));
+
+	/* The controller is already powered off, just disable irq here */
+	disable_irq(hdmi->irq);
+
+	/* Disable interrupts */
+//	mtk_hdmi_v2_hwirq_disable(hdmi);
+//	disable_irq(hdmi->irq);
+//	pm_runtime_put_sync(hdmi->dev);
+}
+
+static void mtk_hdmi_v2_handle_plugged_change(struct mtk_hdmi *hdmi, bool plugged)
+{
+	mutex_lock(&hdmi->update_plugged_status_lock);
+	if (hdmi->plugged_cb && hdmi->codec_dev)
+		hdmi->plugged_cb(hdmi->codec_dev, plugged);
+	mutex_unlock(&hdmi->update_plugged_status_lock);
+}
+
+static void mtk_hdmi_v2_bridge_pre_enable(struct drm_bridge *bridge,
+					  struct drm_bridge_state *old_state)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector_state *conn_state;
+	union phy_configure_opts opts = {
+		.dp = { .link_rate = hdmi->mode.clock * KILO }
+	};
+	int ret;
+
+	/* Power on the controller before trying to write to registers */
+	ret = mtk_hdmi_v2_enable(hdmi);
+	if (WARN_ON(ret))
+		return;
+
+	/* Retrieve the connector through the atomic state */
+	hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
+
+	conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
+	if (WARN_ON(!conn_state))
+		return;
+
+	/*
+	 * Preconfigure the HDMI controller and the HDMI PHY at pre_enable
+	 * stage to make sure that this IP is ready and clocked before the
+	 * mtk_dpi gets powered on and before it enables the output.
+	 */
+	mtk_hdmi_v2_output_set_display_mode(hdmi, &hdmi->mode);
+
+	/* Reconfigure phy clock link with appropriate rate */
+	phy_configure(hdmi->phy, &opts);
+
+	/* Power on the PHY here to make sure that DPI_HDMI is clocked */
+	phy_power_on(hdmi->phy);
+
+	hdmi->powered = true;
+}
+
+static void mtk_hdmi_v2_bridge_enable(struct drm_bridge *bridge,
+				      struct drm_bridge_state *old_state)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+	struct drm_atomic_state *state = old_state->base.state;
+	int ret;
+
+	if (WARN_ON(!hdmi->powered))
+		return;
+
+	ret = drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
+	if (ret)
+		dev_err(hdmi->dev, "Could not update infoframes: %d\n", ret);
+
+	mtk_hdmi_v2_hw_vid_mute(hdmi, false);
+
+	/* signal the connect event to audio codec */
+	mtk_hdmi_v2_handle_plugged_change(hdmi, true);
+
+	hdmi->enabled = true;
+}
+
+static void mtk_hdmi_v2_bridge_disable(struct drm_bridge *bridge,
+				       struct drm_bridge_state *old_bridge_state)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	if (!hdmi->enabled)
+		return;
+
+	mtk_hdmi_v2_hw_av_mute(hdmi, true);
+	msleep(50);
+	mtk_hdmi_v2_hw_vid_mute(hdmi, true);
+	mtk_hdmi_v2_hw_aud_mute(hdmi, true);
+	mtk_hdmi_v2_disable_hdcp_encrypt(hdmi);
+	msleep(50);
+
+	hdmi->enabled = false;
+}
+
+static void mtk_hdmi_v2_bridge_post_disable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *old_state)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	if (!hdmi->powered)
+		return;
+
+	/* Disable VSync interrupt */
+	regmap_clear_bits(hdmi->regs, TOP_INT_ENABLE00, HDMI_VSYNC_INT);
+
+	phy_power_off(hdmi->phy);
+	hdmi->powered = false;
+
+	/* signal the disconnect event to audio codec */
+	mtk_hdmi_v2_handle_plugged_change(hdmi, false);
+
+	/* Power off */
+	mtk_hdmi_v2_disable(hdmi);
+}
+
+static enum drm_connector_status mtk_hdmi_v2_bridge_detect(struct drm_bridge *bridge)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	return hdmi->hpd != HDMI_PLUG_OUT ?
+	       connector_status_connected : connector_status_disconnected;
+}
+
+static const struct drm_edid *mtk_hdmi_v2_bridge_edid_read(struct drm_bridge *bridge,
+							   struct drm_connector *connector)
+{
+	return drm_edid_read(connector);
+}
+
+static void mtk_hdmi_v2_hpd_enable(struct drm_bridge *bridge)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+	int ret;
+
+	ret = mtk_hdmi_v2_enable(hdmi);
+	if (ret) {
+		dev_err(hdmi->dev, "Cannot power on controller for HPD: %d\n", ret);
+		return;
+	}
+
+	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
+}
+
+static void mtk_hdmi_v2_hpd_disable(struct drm_bridge *bridge)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, false);
+	mtk_hdmi_v2_disable(hdmi);
+}
+
+static int mtk_hdmi_v2_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
+						 const struct drm_display_mode *mode,
+						 unsigned long long tmds_rate)
+{
+	if (mode->clock < MTK_HDMI_V2_CLOCK_MIN)
+		return MODE_CLOCK_LOW;
+	else if (mode->clock > MTK_HDMI_V2_CLOCK_MAX)
+		return MODE_CLOCK_HIGH;
+	else
+		return MODE_OK;
+}
+
+static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN_WR | AUD_EN);
+		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN);
+		break;
+	case HDMI_INFOFRAME_TYPE_AVI:
+		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN);
+		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN);
+		break;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN);
+		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN);
+		break;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN);
+		regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN);
+		break;
+	case HDMI_INFOFRAME_TYPE_DRM:
+	default:
+		break;
+	};
+
+	return 0;
+}
+
+static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type,
+					    const u8 *buffer, size_t len)
+{
+	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+
+	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer);
+		break;
+	case HDMI_INFOFRAME_TYPE_AVI:
+		mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer);
+		break;
+	case HDMI_INFOFRAME_TYPE_SPD:
+		mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer);
+		break;
+	case HDMI_INFOFRAME_TYPE_VENDOR:
+		mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer);
+		break;
+	case HDMI_INFOFRAME_TYPE_DRM:
+	default:
+		dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type);
+		break;
+	};
+
+	return 0;
+}
+
+static int mtk_hdmi_v2_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)
+{
+	return drm_atomic_helper_connector_hdmi_check(conn_state->connector,
+						      conn_state->state);
+}
+
+static const struct drm_bridge_funcs mtk_v2_hdmi_bridge_funcs = {
+	.attach = mtk_hdmi_v2_bridge_attach,
+	.detach = mtk_hdmi_v2_bridge_detach,
+	.mode_fixup = mtk_hdmi_bridge_mode_fixup,
+	.mode_set = mtk_hdmi_bridge_mode_set,
+	.atomic_pre_enable = mtk_hdmi_v2_bridge_pre_enable,
+	.atomic_enable = mtk_hdmi_v2_bridge_enable,
+	.atomic_disable = mtk_hdmi_v2_bridge_disable,
+	.atomic_post_disable = mtk_hdmi_v2_bridge_post_disable,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_check = mtk_hdmi_v2_bridge_atomic_check,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.detect = mtk_hdmi_v2_bridge_detect,
+	.edid_read = mtk_hdmi_v2_bridge_edid_read,
+	.hpd_enable = mtk_hdmi_v2_hpd_enable,
+	.hpd_disable = mtk_hdmi_v2_hpd_disable,
+	.hdmi_tmds_char_rate_valid = mtk_hdmi_v2_hdmi_tmds_char_rate_valid,
+	.hdmi_clear_infoframe = mtk_hdmi_v2_hdmi_clear_infoframe,
+	.hdmi_write_infoframe = mtk_hdmi_v2_hdmi_write_infoframe,
+};
+
+/*
+ * HDMI audio codec callbacks
+ */
+static int mtk_hdmi_v2_audio_hook_plugged_cb(struct device *dev, void *data,
+					     hdmi_codec_plugged_cb fn,
+					     struct device *codec_dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	bool plugged;
+
+	if (!hdmi)
+		return -ENODEV;
+
+	mtk_hdmi_audio_set_plugged_cb(hdmi, fn, codec_dev);
+	plugged = (hdmi->hpd == HDMI_PLUG_IN_AND_SINK_POWER_ON);
+	mtk_hdmi_v2_handle_plugged_change(hdmi, plugged);
+
+	return 0;
+}
+
+static int mtk_hdmi_v2_audio_hw_params(struct device *dev, void *data,
+				       struct hdmi_codec_daifmt *daifmt,
+				       struct hdmi_codec_params *params)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	if (hdmi->audio_enable) {
+		mtk_hdmi_audio_params(hdmi, daifmt, params);
+		mtk_hdmi_v2_aud_output_config(hdmi, &hdmi->mode);
+	}
+	return 0;
+}
+
+static int mtk_hdmi_v2_audio_startup(struct device *dev, void *data)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	mtk_hdmi_v2_hw_aud_enable(hdmi, true);
+	hdmi->audio_enable = true;
+
+	return 0;
+}
+
+static void mtk_hdmi_v2_audio_shutdown(struct device *dev, void *data)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	hdmi->audio_enable = false;
+	mtk_hdmi_v2_hw_aud_enable(hdmi, false);
+}
+
+static int mtk_hdmi_v2_audio_mute(struct device *dev, void *data, bool enable, int dir)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	mtk_hdmi_v2_hw_aud_mute(hdmi, enable);
+
+	return 0;
+}
+
+static const struct hdmi_codec_ops mtk_hdmi_v2_audio_codec_ops = {
+	.hw_params = mtk_hdmi_v2_audio_hw_params,
+	.audio_startup = mtk_hdmi_v2_audio_startup,
+	.audio_shutdown = mtk_hdmi_v2_audio_shutdown,
+	.mute_stream = mtk_hdmi_v2_audio_mute,
+	.get_eld = mtk_hdmi_audio_get_eld,
+	.hook_plugged_cb = mtk_hdmi_v2_audio_hook_plugged_cb,
+};
+
+static __maybe_unused int mtk_hdmi_v2_suspend(struct device *dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+
+	mtk_hdmi_v2_disable(hdmi);
+
+	return 0;
+}
+
+static __maybe_unused int mtk_hdmi_v2_resume(struct device *dev)
+{
+	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+	int ret;
+
+	pm_runtime_get_sync(dev);
+
+	ret = mtk_hdmi_v2_clk_enable(hdmi);
+	if (ret)
+		return ret;
+
+	mtk_hdmi_v2_enable_hpd_pord_irq(hdmi, true);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mtk_hdmi_v2_pm_ops, mtk_hdmi_v2_suspend, mtk_hdmi_v2_resume);
+
+static const struct mtk_hdmi_ver_conf mtk_hdmi_conf_v2 = {
+	.bridge_funcs = &mtk_v2_hdmi_bridge_funcs,
+	.codec_ops = &mtk_hdmi_v2_audio_codec_ops,
+	.mtk_hdmi_clock_names = mtk_hdmi_v2_clk_names,
+	.num_clocks = MTK_HDMI_V2_CLK_COUNT
+};
+
+static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8188 = {
+	.ver_conf = &mtk_hdmi_conf_v2,
+	.reg_hdmi_tx_cfg = HDMITX_CONFIG_MT8188
+};
+
+static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8195 = {
+	.ver_conf = &mtk_hdmi_conf_v2,
+	.reg_hdmi_tx_cfg = HDMITX_CONFIG_MT8195
+};
+
+static int mtk_hdmi_v2_probe(struct platform_device *pdev)
+{
+	struct mtk_hdmi *hdmi;
+	int ret;
+
+	hdmi = mtk_hdmi_common_probe(pdev);
+	if (IS_ERR(hdmi))
+		return PTR_ERR(hdmi);
+
+	hdmi->hpd = HDMI_PLUG_OUT;
+
+	/*
+	 * Disable all HW interrupts at probe stage and install the ISR
+	 * but keep it disabled, as the rest of the interrupts setup is
+	 * done in the .bridge_attach() callback, which will enable both
+	 * the right HW IRQs and the ISR.
+	 */
+	mtk_hdmi_v2_hwirq_disable(hdmi);
+	irq_set_status_flags(hdmi->irq, IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(&pdev->dev, hdmi->irq, mtk_hdmi_v2_isr,
+					mtk_hdmi_v2_isr_thread,
+					IRQ_TYPE_LEVEL_HIGH,
+					dev_name(&pdev->dev), hdmi);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Cannot request IRQ\n");
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Cannot enable Runtime PM\n");
+
+	return 0;
+}
+
+static void mtk_hdmi_v2_remove(struct platform_device *pdev)
+{
+	struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
+
+	pm_runtime_disable(&pdev->dev);
+	i2c_put_adapter(hdmi->ddc_adpt);
+}
+
+static const struct of_device_id mtk_drm_hdmi_v2_of_ids[] = {
+	{ .compatible = "mediatek,mt8188-hdmi-tx", .data = &mtk_hdmi_conf_mt8188 },
+	{ .compatible = "mediatek,mt8195-hdmi-tx", .data = &mtk_hdmi_conf_mt8195 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_v2_of_ids);
+
+static struct platform_driver mtk_hdmi_v2_driver = {
+	.probe = mtk_hdmi_v2_probe,
+	.remove = mtk_hdmi_v2_remove,
+	.driver = {
+		.name = "mediatek-drm-hdmi-v2",
+		.of_match_table = mtk_drm_hdmi_v2_of_ids,
+		.pm = &mtk_hdmi_v2_pm_ops,
+	},
+};
+module_platform_driver(mtk_hdmi_v2_driver);
+
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>>");
+MODULE_AUTHOR("Guillaume Ranquet <granquet at baylibre.com>");
+MODULE_DESCRIPTION("MediaTek HDMIv2 Driver");
+MODULE_LICENSE("GPL");
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:44 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:44 +0100
Subject: [PATCH v3 32/33] drm/mediatek: mtk_hdmi_common: Add var to enable interlaced modes
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-33-angelogioacchino.delregno@collabora.com>

Add an interlace_allowed bool member to struct mtk_hdmi_ver_conf
which will be used to signal whether interlaced modes are supported
by the bridge (in our case, the HDMI IP), and enable it for HDMIv2.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 1 +
 drivers/gpu/drm/mediatek/mtk_hdmi_common.h | 1 +
 drivers/gpu/drm/mediatek/mtk_hdmi_v2.c     | 3 ++-
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
index c076e4efcd29..40b4b1d1c837 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
@@ -424,6 +424,7 @@ struct mtk_hdmi *mtk_hdmi_common_probe(struct platform_device *pdev)
 	hdmi->bridge.ddc = hdmi->ddc_adpt;
 	hdmi->bridge.vendor = "MediaTek";
 	hdmi->bridge.product = "On-Chip HDMI";
+	hdmi->bridge.interlace_allowed = ver_conf->interlace_allowed;
 
 	ret = devm_drm_bridge_add(dev, &hdmi->bridge);
 	if (ret)
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
index e74fe1371324..de5e064585f8 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
@@ -137,6 +137,7 @@ struct mtk_hdmi_ver_conf {
 	const struct hdmi_codec_ops *codec_ops;
 	const char * const *mtk_hdmi_clock_names;
 	int num_clocks;
+	bool interlace_allowed;
 };
 
 struct mtk_hdmi_conf {
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
index c71ecc3c1711..5b708fcc0e03 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
@@ -1306,7 +1306,8 @@ static const struct mtk_hdmi_ver_conf mtk_hdmi_conf_v2 = {
 	.bridge_funcs = &mtk_v2_hdmi_bridge_funcs,
 	.codec_ops = &mtk_hdmi_v2_audio_codec_ops,
 	.mtk_hdmi_clock_names = mtk_hdmi_v2_clk_names,
-	.num_clocks = MTK_HDMI_V2_CLK_COUNT
+	.num_clocks = MTK_HDMI_V2_CLK_COUNT,
+	.interlace_allowed = true
 };
 
 static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8188 = {
-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Tue Dec 17 07:43:45 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 17 Dec 2024 16:43:45 +0100
Subject: [PATCH v3 33/33] drm/mediatek: mtk_hdmi_v2: Add debugfs ops and implement ABIST
In-Reply-To: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241217154345.276919-34-angelogioacchino.delregno@collabora.com>

Implement the Automated Built-In Self-Test ABIST functionality
provided by the HDMIv2 IP and expose it through the "hdmi_abist"
debugfs file.

Write "1" to this file to activate ABIST, or "0" to deactivate.

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

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
index 5b708fcc0e03..7daa0c8dd311 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
@@ -1184,6 +1184,128 @@ static int mtk_hdmi_v2_bridge_atomic_check(struct drm_bridge *bridge,
 						      conn_state->state);
 }
 
+static int mtk_hdmi_v2_set_abist(struct mtk_hdmi *hdmi, bool enable)
+{
+	struct drm_display_mode *mode = &hdmi->mode;
+	int abist_format = -EINVAL;
+	bool interlaced;
+
+	if (!enable) {
+		regmap_clear_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
+		return 0;
+	}
+
+	if (!mode->hdisplay || !mode->vdisplay)
+		return -EINVAL;
+
+	interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
+
+	switch (mode->hdisplay) {
+	case 720:
+		if (mode->vdisplay == 480)
+			abist_format = 2;
+		else if (mode->vdisplay == 576)
+			abist_format = 11;
+		break;
+	case 1280:
+		if (mode->vdisplay == 720)
+			abist_format = 3;
+		break;
+	case 1440:
+		if (mode->vdisplay == 480)
+			abist_format = interlaced ? 5 : 9;
+		else if (mode->vdisplay == 576)
+			abist_format = interlaced ? 14 : 18;
+		break;
+	case 1920:
+		if (mode->vdisplay == 1080)
+			abist_format = interlaced ? 4 : 10;
+		break;
+	case 3840:
+		if (mode->vdisplay == 2160)
+			abist_format = 25;
+		break;
+	case 4096:
+		if (mode->vdisplay == 2160)
+			abist_format = 26;
+		break;
+	default:
+		break;
+	}
+	if (!abist_format)
+		return -EINVAL;
+
+	regmap_update_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_VIDEO_FORMAT,
+			   FIELD_PREP(HDMI_ABIST_VIDEO_FORMAT, abist_format));
+	regmap_set_bits(hdmi->regs, TOP_CFG00, HDMI_ABIST_ENABLE);
+	return 0;
+}
+
+static int mtk_hdmi_v2_debug_abist_show(struct seq_file *m, void *arg)
+{
+	struct mtk_hdmi *hdmi = m->private;
+	bool en;
+	u32 val;
+	int ret;
+
+	if (!hdmi)
+		return -EINVAL;
+
+	ret = regmap_read(hdmi->regs, TOP_CFG00, &val);
+	if (ret)
+		return ret;
+
+	en = FIELD_GET(HDMI_ABIST_ENABLE, val);
+
+	seq_printf(m, "HDMI Automated Built-In Self Test: %s\n",
+		   en ? "Enabled" : "Disabled");
+
+	return 0;
+}
+
+static ssize_t mtk_hdmi_v2_debug_abist_write(struct file *file,
+					     const char __user *ubuf,
+					     size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	int ret;
+	u32 en;
+
+	if (!m || !m->private || *offp)
+		return -EINVAL;
+
+	ret = kstrtouint_from_user(ubuf, len, 0, &en);
+	if (ret)
+		return ret;
+
+	if (en < 0 || en > 1)
+		return -EINVAL;
+
+	mtk_hdmi_v2_set_abist((struct mtk_hdmi *)m->private, en);
+	return len;
+}
+
+static int mtk_hdmi_v2_debug_abist_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mtk_hdmi_v2_debug_abist_show, inode->i_private);
+}
+
+static const struct file_operations mtk_hdmi_debug_abist_fops = {
+	.owner = THIS_MODULE,
+	.open = mtk_hdmi_v2_debug_abist_open,
+	.read = seq_read,
+	.write = mtk_hdmi_v2_debug_abist_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static void mtk_hdmi_v2_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
+{
+	struct mtk_hdmi *dpi = hdmi_ctx_from_bridge(bridge);
+
+	debugfs_create_file("hdmi_abist", 0640, root, dpi, &mtk_hdmi_debug_abist_fops);
+}
+
 static const struct drm_bridge_funcs mtk_v2_hdmi_bridge_funcs = {
 	.attach = mtk_hdmi_v2_bridge_attach,
 	.detach = mtk_hdmi_v2_bridge_detach,
@@ -1204,6 +1326,7 @@ static const struct drm_bridge_funcs mtk_v2_hdmi_bridge_funcs = {
 	.hdmi_tmds_char_rate_valid = mtk_hdmi_v2_hdmi_tmds_char_rate_valid,
 	.hdmi_clear_infoframe = mtk_hdmi_v2_hdmi_clear_infoframe,
 	.hdmi_write_infoframe = mtk_hdmi_v2_hdmi_write_infoframe,
+	.debugfs_init = mtk_hdmi_v2_debugfs_init,
 };
 
 /*
-- 
2.47.0



From ukleinek at kernel.org  Tue Dec 17 07:46:21 2024
From: ukleinek at kernel.org (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Tue, 17 Dec 2024 16:46:21 +0100
Subject: [PATCH] pwm: stm32: fix complementary output in
 round_waveform_tohw
In-Reply-To: <20241217150021.2030213-1-fabrice.gasnier@foss.st.com>
References: <20241217150021.2030213-1-fabrice.gasnier@foss.st.com>
Message-ID: <dwwbefhhvjczcakd4nrrunzoq7mhzwrxxpm7gdtabgm6flk4cp@5w4usax4n67h>

On Tue, Dec 17, 2024 at 04:00:21PM +0100, Fabrice Gasnier wrote:
> When the timer supports complementary output, the enable bit is
> overridden. It should be OR'ed. This makes all PWM channels for
> such timer not to work.
> 
> Fixes: deaba9cff809 ("pwm: stm32: Implementation of the waveform callbacks")
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> ---
>  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 b889e64522c3..17e591f61efb 100644
> --- a/drivers/pwm/pwm-stm32.c
> +++ b/drivers/pwm/pwm-stm32.c
> @@ -84,7 +84,7 @@ static int stm32_pwm_round_waveform_tohw(struct pwm_chip *chip,
>  
>  	wfhw->ccer = TIM_CCER_CCxE(ch + 1);
>  	if (priv->have_complementary_output)
> -		wfhw->ccer = TIM_CCER_CCxNE(ch + 1);
> +		wfhw->ccer |= TIM_CCER_CCxNE(ch + 1);

Oh, indeed. Thanks for the fix.

Applied to 
https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/fixes
and I will send it to Linus later this week.

Best regards
Uwe
-------------- 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/20241217/a8354b81/attachment.sig>

From Frank.li at nxp.com  Tue Dec 17 07:50:22 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 17 Dec 2024 10:50:22 -0500
Subject: [PATCH v8 2/2] PCI: imx6: Add IOMMU and ITS MSI support for
 i.MX95
In-Reply-To: <Z2FDp1zQ7JzxQKJT@lpieralisi>
References: <20241210-imx95_lut-v8-0-2e730b2e5fde@nxp.com>
 <20241210-imx95_lut-v8-2-2e730b2e5fde@nxp.com>
 <Z1sTUaoA5yk9RcIc@lpieralisi>
 <Z1sdbH7N1Ly9eXc0@lizhi-Precision-Tower-5810>
 <Z1v/LCHsGOgnasuf@lpieralisi>
 <Z1xs6GkcdTg2c73F@lizhi-Precision-Tower-5810>
 <Z2FDp1zQ7JzxQKJT@lpieralisi>
Message-ID: <Z2GdvpzT6MOygG4W@lizhi-Precision-Tower-5810>

On Tue, Dec 17, 2024 at 10:25:59AM +0100, Lorenzo Pieralisi wrote:
> On Fri, Dec 13, 2024 at 12:20:40PM -0500, Frank Li wrote:
> > On Fri, Dec 13, 2024 at 10:32:28AM +0100, Lorenzo Pieralisi wrote:
> > > On Thu, Dec 12, 2024 at 12:29:16PM -0500, Frank Li wrote:
> > > > On Thu, Dec 12, 2024 at 05:46:09PM +0100, Lorenzo Pieralisi wrote:
> > > > > On Tue, Dec 10, 2024 at 05:48:59PM -0500, Frank Li wrote:
> > > > > > For the i.MX95, configuration of a LUT is necessary to convert Bus Device
> > > > > > Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS.
> > > > > > This involves checking msi-map and iommu-map device tree properties to
> > > > > > ensure consistent mapping of PCI BDF to the same stream IDs. Subsequently,
> > > > > > LUT-related registers are configured. In the absence of an msi-map, the
> > > > > > built-in MSI controller is utilized as a fallback.
> > > > >
> > > > > This is wrong information. What you want to say is that if an msi-map
> > > > > isn't detected this means that the platform relies on DWC built-in
> > > > > controller for MSIs (that does not need streamIDs handling).
> > > > >
> > > > > That's quite different from what you are writing here.
> > > >
> > > > How about ?
> > > >
> > > > "If an msi-map isn't detected, platform relies on DWC built-in controller
> > > > for MSIs that does not need streamdIDs"
> > >
> > > Right. Question: what happens if DT shows that there are SMMU and/or
> > > ITS bindings/mappings but the SMMU driver and ITS driver are either not
> > > enabled or have not probed ?
> >
> > It is little bit complex.
> > iommu:
> > Case 1:
> > 	iommu{
> > 		status = "disabled"
> > 	};
> >
> > 	PCI driver normal probed. if RID is in range of iommu-map, not
> > any functional impact and harmless.
> > 	If RID is out of range of iommu-map, "false alarm" will return.
> > enable PCI EP device failure, but actually it can work without IOMMU.
>
> What does "false alarm" mean in practice ? PCI device enable fails
> but actually it should not ?

Yes, you are right. It should work without iommu. but return failure for
this case.

> That does not look like a false alarm to me.

My means:  return failure but it should work without iommu. Ideally
of_map_id() should return failure when iommu is disabled. It needs more
work for that. I think we can improve it later.

>
> >
> > Case 2:
> > 	iommu {
> > 		status = "Okay"
> > 	}
> > 	but iommu driver have not probed yet.  PCI Host bridge driver
> > should defer till iommu probed.
> >
> > Worst case is "false alarm". But this happen is very rare if DTS is
> > correct.
>
> Explain what this means.

It return failure, but it should return success if "iommu disabled" and
"RID is out of iommu-map range".

>
> > MSI:
> > case 1:
> > 	msi-controller {
> > 		status = "disabled";
> > 	}
> > 	Whole all dwc drivers will be broken.
>
> What MSI controller. Please make an effort to be precise and explain.

For example: ARM its, I use general term here because some other platform
such as RISC V have not use ARM ITS.

pcie {
	...
	msi-map= <...>
	...
}

DWC common driver will check property "msi-map". if it exist, built-in
MSI controller will skip init by history reason. That is also the another
reason why Rob don't want us to check these standard property.

Without MSI, system will failure back to INTx mode, same to no-msi=yes.
But some EP devices require MSI support.

Frank

>
> Thanks,
> Lorenzo
>
> > case 2:
> > 	msi-controller {
> > 		status = "Okay"
> > 	}
> > 	if msi driver have not probed yet, PCI Host bridge driver will
> > defer.
> >
> > Frank
> >
> > >
> > > I assume the LUT programming makes no difference (it is useless yes but
> > > should be harmless too) in this case but wanted to check with you`.
> > >
> > > Thanks,
> > > Lorenzo
> > >
> > > >
> > > > >
> > > > > >
> > > > > > Register a PCI bus callback function to handle enable_device() and
> > > > > > disable_device() operations, setting up the LUT whenever a new PCI device
> > > > > > is enabled.
> > > > > >
> > > > > > Acked-by: Richard Zhu <hongxing.zhu at nxp.com>
> > > > > > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > > >
> > > > [...]
> > > >
> > > > > > +	int err_i, err_m;
> > > > > > +	u32 sid;
> > > > > > +
> > > > > > +	dev = imx_pcie->pci->dev;
> > > > > > +
> > > > > > +	target = NULL;
> > > > > > +	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", &target, &sid_i);
> > > > > > +	if (target) {
> > > > > > +		of_node_put(target);
> > > > > > +	} else {
> > > > > > +		/*
> > > > > > +		 * "target == NULL && err_i == 0" means use 1:1 map RID to
> > > > >
> > > > > Is it what it means ? Or does it mean that the iommu-map property was found
> > > > > and RID is out of range ?
> > > >
> > > > yes, if this happen, sid_i will be equal to RID.
> > > >
> > > > >
> > > > > Could you point me at a sample dts for this host bridge please ?
> > > >
> > > > https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/boot/dts/freescale/imx95.dtsi
> > > >
> > > > /* 0x10~0x17 stream id for pci0 */
> > > >    iommu-map = <0x000 &smmu 0x10 0x1>,
> > > >                <0x100 &smmu 0x11 0x7>;
> > > >
> > > > /* msi part */
> > > >    msi-map = <0x000 &its 0x10 0x1>,
> > > >              <0x100 &its 0x11 0x7>;
> > > >
> > > > >
> > > > > > +		 * stream ID. Hardware can't support this because stream ID
> > > > > > +		 * only 5bits
> > > > >
> > > > > It is 5 or 6 bits ? From GENMASK(5, 0) above it should be 6.
> > > >
> > > > Sorry for typo. it is 6bits.
> > > >
> > > > >
> > > > > > +		 */
> > > > > > +		err_i = -EINVAL;
> > > > > > +	}
> > > > > > +
> > > > > > +	target = NULL;
> > > > > > +	err_m = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", &target, &sid_m);
> > > > > > +
> > > > > > +	/*
> > > > > > +	 *   err_m      target
> > > > > > +	 *	0	NULL		Use 1:1 map RID to stream ID,
> > > > >
> > > > > Again, is that what it really means ?
> > > > >
> > > > > > +	 *				Current hardware can't support it,
> > > > > > +	 *				So return -EINVAL.
> > > > > > +	 *      != 0    NULL		msi-map not exist, use built-in MSI.
> > > > >
> > > > > does not exist.
> > > > >
> > > > > > +	 *	0	!= NULL		Get correct streamID from RID.
> > > > > > +	 *	!= 0	!= NULL		Unexisted case, never happen.
> > > > >
> > > > > "Invalid combination"
> > > > >
> > > > > > +	 */
> > > > > > +	if (!err_m && !target)
> > > > > > +		return -EINVAL;
> > > > > > +	else if (target)
> > > > > > +		of_node_put(target); /* Find stream ID map entry for RID in msi-map */
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * msi-map        iommu-map
> > > > > > +	 *   N                N            DWC MSI Ctrl
> > > > > > +	 *   Y                Y            ITS + SMMU, require the same sid
> > > > > > +	 *   Y                N            ITS
> > > > > > +	 *   N                Y            DWC MSI Ctrl + SMMU
> > > > > > +	 */
> > > > > > +	if (err_i && err_m)
> > > > > > +		return 0;
> > > > > > +
> > > > > > +	if (!err_i && !err_m) {
> > > > > > +		/*
> > > > > > +		 * MSI glue layer auto add 2 bits controller ID ahead of stream
> > > > >
> > > > > What's "MSI glue layer" ?
> > > >
> > > > It is common term for IC desgin, which connect IP's signal to platform with
> > > > some simple logic. Inside chip, when connect LUT output 6bit streamIDs
> > > > to MSI controller, there are 2bits hardcode controller ID information
> > > > append to 6 bits streamID.
> > > >
> > > >            Glue Layer
> > > >           <==========>
> > > > ???????                  ????????????
> > > > ? LUT ? 6bit stream ID   ?          ?
> > > > ?     ????????????????????  MSI     ?
> > > > ???????    2bit ctrl ID  ?          ?
> > > >             ??????????????          ?
> > > >             ?            ?          ?
> > > >  00 PCIe0   ?            ?          ?
> > > >  01 ENETC   ?            ?          ?
> > > >  10 PCIe1   ?            ?          ?
> > > >             ?            ????????????
> > > >
> > > > >
> > > > > > +		 * ID, so mask this 2bits to get stream ID.
> > > > > > +		 * But IOMMU glue layer doesn't do that.
> > > > >
> > > > > and "IOMMU glue layer" ?
> > > >
> > > > See above.
> > > >
> > > > Frank
> > > >
> > > > >
> > > > > > +		 */
> > > > > > +		if (sid_i != (sid_m & IMX95_SID_MASK)) {
> > > > > > +			dev_err(dev, "iommu-map and msi-map entries mismatch!\n");
> > > > > > +			return -EINVAL;
> > > > > > +		}
> > > > > > +	}
> > > > > > +
> > > > > > +	sid = sid_i;
> > > > >
> > > > > err_i could be != 0 here, I understand that the end result is
> > > > > fine given how the code is written but it is misleading.
> > > > >
> > > > > 	if (!err_i)
> > > > > 	else if (!err_m)
> > > >
> > > > Okay
> > > >
> > > > >
> > > > > > +	if (!err_m)
> > > > > > +		sid = sid_m & IMX95_SID_MASK;
> > > > > > +
> > > > > > +	return imx_pcie_add_lut(imx_pcie, rid, sid);
> > > > > > +}
> > > > > > +
> > > > > > +static void imx_pcie_disable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
> > > > > > +{
> > > > > > +	struct imx_pcie *imx_pcie;
> > > > > > +
> > > > > > +	imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
> > > > > > +	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
> > > > > > +}
> > > > > > +
> > > > > >  static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> > > > > >  {
> > > > > >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > > > > @@ -946,6 +1122,11 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> > > > > >  		}
> > > > > >  	}
> > > > > >
> > > > > > +	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
> > > > > > +		pp->bridge->enable_device = imx_pcie_enable_device;
> > > > > > +		pp->bridge->disable_device = imx_pcie_disable_device;
> > > > > > +	}
> > > > > > +
> > > > > >  	imx_pcie_assert_core_reset(imx_pcie);
> > > > > >
> > > > > >  	if (imx_pcie->drvdata->init_phy)
> > > > > > @@ -1330,6 +1511,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
> > > > > >  	imx_pcie->pci = pci;
> > > > > >  	imx_pcie->drvdata = of_device_get_match_data(dev);
> > > > > >
> > > > > > +	mutex_init(&imx_pcie->lock);
> > > > > > +
> > > > > >  	/* Find the PHY if one is defined, only imx7d uses it */
> > > > > >  	np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
> > > > > >  	if (np) {
> > > > > > @@ -1627,7 +1810,8 @@ static const struct imx_pcie_drvdata drvdata[] = {
> > > > > >  	},
> > > > > >  	[IMX95] = {
> > > > > >  		.variant = IMX95,
> > > > > > -		.flags = IMX_PCIE_FLAG_HAS_SERDES,
> > > > > > +		.flags = IMX_PCIE_FLAG_HAS_SERDES |
> > > > > > +			 IMX_PCIE_FLAG_HAS_LUT,
> > > > > >  		.clk_names = imx8mq_clks,
> > > > > >  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> > > > > >  		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> > > > > >
> > > > > > --
> > > > > > 2.34.1
> > > > > >


From michael.riesch at wolfvision.net  Tue Dec 17 07:55:12 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 17 Dec 2024 16:55:12 +0100
Subject: [PATCH v2 0/6] media: rockchip: add a driver for the rockchip
 camera interface (cif)
Message-ID: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>

Habidere,

TL;DR:

This series introduces support for the Rockchip Camera Interface (CIF),
which can be found (in the form of variants that differ significantly) in
different Rockchip SoCs in general, and for the Rockchip RK3568 Video
Capture (VICAP) variant in particular.

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.

The long story (gather 'round children):

The Rockchip Camera Interface (CIF) is featured in many Rockchip SoCs
in different variations. For example, the PX30 Video Input Processor (VIP)
is able to receive video data via the Digital Video Port (DVP, a parallel
data interface and transfer it into system memory using a double-buffering
mechanism called ping-pong mode. The RK3568 Video Capture (VICAP) unit,
on the other hand, features a DVP and a MIPI CSI-2 receiver that can
receive video data independently (both using the ping-pong scheme).
The different variants may have additional features, such as scaling
and/or cropping.
Finally, the RK3588 VICAP unit constitutes an essential piece of the camera
interface with one DVP, six MIPI CSI-2 receivers, scale/crop units, and
different data path multiplexers (to system memory, to ISP, ...).

This submission 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. This process has been going on for several
years now, with Maxime Chevallier working on the topic up to v5 [0] and
Mehdi Djait taking over until v13 [1].
In the review feedback on v13 a major rework with a media controller
centric driver as a goal was requested. This motivated me to take over
(with no clue about the MC framework whatsoever, though).

I decided to merge Mehdi's v13 with my v1 of the RK3568 VICAP support [2]
and refactor the whole thing. The resulting v2 of the series now adds a
basic media controller centric V4L2 driver for the Rockchip CIF with
 - support for the PX30 VIP (not tested, though, due to the lack of HW)
 - support for the RK3568 VICAP DVP
 - abstraction for the ping-pong scheme to allow for future extensions 

However, several features are not yet addressed, such as
 - support for the RK3568 MIPI CSI-2 receiver
 - support for the RK3588 variant
 - support for the scaling/cropping units that can be found in some
   variants
 - support for capturing different virtual channels (up to four IDs
   possible)
This needs to be in the scope of future work.

Finally, please forgive me if I forgot to address reviewer comments from
the previous iterations. Between v1 and v13 they have seen significant
feedback including renaming the complete driver twice (from rkcif to vip
and back to cif) and I am pretty sure that I was not able to gather
everything.

Looking forward to your comments!

[0] https://lore.kernel.org/linux-media/20201229161724.511102-1-maxime.chevallier at bootlin.com/
[1] https://lore.kernel.org/linux-media/cover.1707677804.git.mehdi.djait.k at gmail.com/
[2] https://lore.kernel.org/all/20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b at wolfvision.net/

To: Mehdi Djait <mehdi.djait at linux.intel.com>
To: Maxime Chevallier <maxime.chevallier at bootlin.com>
To: Th?o Lebrun <theo.lebrun at bootlin.com>
To: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
To: Sakari Ailus <sakari.ailus at iki.fi>
To: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
To: Mauro Carvalho Chehab <mchehab at kernel.org>
To: Rob Herring <robh+dt at kernel.org>
To: Krzysztof Kozlowski <krzk+dt at kernel.org>
To: Conor Dooley <conor+dt at kernel.org>
To: Heiko Stuebner <heiko at sntech.de>
To: Kever Yang <kever.yang at rock-chips.com>
To: Nicolas Dufresne <nicolas at ndufresne.ca>
To: Sebastian Fricke <sebastian.fricke at collabora.com>
To: Alexander Shiyan <eagle.alexander923 at gmail.com>
To: Val Packett <val at packett.cool>
To: Rob Herring <robh at kernel.org>
To: Philipp Zabel <p.zabel at pengutronix.de>
Cc: linux-media at vger.kernel.org
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-rockchip at lists.infradead.org
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>

Changes in v2:
- merged with Mehdi's v13
- refactored the complete driver towards a media controller centric driver
- abstracted the generic ping-pong stream (can be used for DVP as well as for CSI-2)
- switched to MPLANE API
- added support for notifications
- Link to v1: https://lore.kernel.org/r/20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b at wolfvision.net

---
Mehdi Djait (2):
      media: dt-bindings: media: add bindings for rockchip px30 vip
      arm64: dts: rockchip: add the vip node to px30

Michael Riesch (4):
      media: dt-bindings: media: video-interfaces: add defines for sampling modes
      media: dt-bindings: media: add bindings for rockchip rk3568 vicap
      media: rockchip: add a driver for the rockchip camera interface (cif)
      arm64: dts: rockchip: add vicap node to rk356x

 .../bindings/media/rockchip,px30-vip.yaml          | 123 ++++
 .../bindings/media/rockchip,rk3568-vicap.yaml      | 168 +++++
 MAINTAINERS                                        |   9 +
 arch/arm64/boot/dts/rockchip/px30.dtsi             |  12 +
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi      |  44 ++
 drivers/media/platform/rockchip/Kconfig            |   1 +
 drivers/media/platform/rockchip/Makefile           |   1 +
 drivers/media/platform/rockchip/cif/Kconfig        |  15 +
 drivers/media/platform/rockchip/cif/Makefile       |   3 +
 .../media/platform/rockchip/cif/cif-capture-dvp.c  | 794 +++++++++++++++++++++
 .../media/platform/rockchip/cif/cif-capture-dvp.h  |  24 +
 drivers/media/platform/rockchip/cif/cif-common.h   | 163 +++++
 drivers/media/platform/rockchip/cif/cif-dev.c      | 405 +++++++++++
 drivers/media/platform/rockchip/cif/cif-regs.h     | 132 ++++
 drivers/media/platform/rockchip/cif/cif-stream.c   | 676 ++++++++++++++++++
 drivers/media/platform/rockchip/cif/cif-stream.h   |  24 +
 include/dt-bindings/media/video-interfaces.h       |   4 +
 17 files changed, 2598 insertions(+)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
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 Dec 17 07:55:13 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 17 Dec 2024 16:55:13 +0100
Subject: [PATCH v2 1/6] media: dt-bindings: media: video-interfaces: add
 defines for sampling modes
In-Reply-To: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
References: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
Message-ID: <20241217-v6-8-topic-rk3568-vicap-v2-1-b1d488fcc0d3@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>
Acked-by: Rob Herring <robh at kernel.org>
---
 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.34.1



From michael.riesch at wolfvision.net  Tue Dec 17 07:55:14 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 17 Dec 2024 16:55:14 +0100
Subject: [PATCH v2 2/6] media: dt-bindings: media: add bindings for
 rockchip px30 vip
In-Reply-To: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
References: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
Message-ID: <20241217-v6-8-topic-rk3568-vicap-v2-2-b1d488fcc0d3@wolfvision.net>

From: Mehdi Djait <mehdi.djait at bootlin.com>

Add documentation for the Rockchip PX30 Video Input Processor (VIP).

Signed-off-by: Mehdi Djait <mehdi.djait at bootlin.com>
[revised description]
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../bindings/media/rockchip,px30-vip.yaml          | 123 +++++++++++++++++++++
 MAINTAINERS                                        |   7 ++
 2 files changed, 130 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
new file mode 100644
index 000000000000..d34c0974204f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
@@ -0,0 +1,123 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/rockchip,px30-vip.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip PX30 Video Input Processor (VIP)
+
+maintainers:
+  - Mehdi Djait <mehdi.djait at linux.intel.com>
+  - Michael Riesch <michael.riesch at wolfvision.net>
+
+description:
+  The Rockchip PX30 Video Input Processor (VIP) receives the data from a camera
+  sensor or CCIR656 encoder and transfers it into system main memory by AXI bus.
+
+properties:
+  compatible:
+    const: rockchip,px30-vip
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  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
+
+  power-domains:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: input port on the parallel interface
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              bus-type:
+                enum: [5, 6]
+
+            required:
+              - bus-type
+
+    required:
+      - port at 0
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/px30-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/media/video-interfaces.h>
+    #include <dt-bindings/power/px30-power.h>
+
+    parent {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        video-capture at ff490000 {
+            compatible = "rockchip,px30-vip";
+            reg = <0x0 0xff490000 0x0 0x200>;
+            interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>;
+            clock-names = "aclk", "hclk", "pclk";
+            power-domains = <&power PX30_PD_VI>;
+            resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>;
+            reset-names = "axi", "ahb", "pclkin";
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port at 0 {
+                    reg = <0>;
+
+                    cif_in: endpoint {
+                        remote-endpoint = <&tw9900_out>;
+                        bus-type = <MEDIA_BUS_TYPE_BT656>;
+                    };
+                };
+            };
+        };
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 1e930c7a58b1..1138c8858bc7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20217,6 +20217,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
 F:	drivers/net/can/rockchip/
 
+ROCKCHIP CIF DRIVER
+M:	Mehdi Djait <mehdi.djait at linux.intel.com>
+M:	Michael Riesch <michael.riesch at wolfvision.net>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
+
 ROCKCHIP CRYPTO DRIVERS
 M:	Corentin Labbe <clabbe at baylibre.com>
 L:	linux-crypto at vger.kernel.org

-- 
2.34.1



From michael.riesch at wolfvision.net  Tue Dec 17 07:55:15 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 17 Dec 2024 16:55:15 +0100
Subject: [PATCH v2 3/6] media: dt-bindings: media: add bindings for
 rockchip rk3568 vicap
In-Reply-To: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
References: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
Message-ID: <20241217-v6-8-topic-rk3568-vicap-v2-3-b1d488fcc0d3@wolfvision.net>

Add documentation for the Rockchip RK3568 Video Capture (VICAP) unit.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../bindings/media/rockchip,rk3568-vicap.yaml      | 168 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 169 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
new file mode 100644
index 000000000000..ef7b14ca6879
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
@@ -0,0 +1,168 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/rockchip,rk3568-vicap.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3568 Video Capture (VICAP)
+
+maintainers:
+  - Michael Riesch <michael.riesch at wolfvision.net>
+
+description:
+  The Rockchip RK3568 Video Capture (VICAP) block features a digital video
+  port (DVP, a parallel video interface) and a MIPI CSI-2 port. It receives
+  the data from camera sensors, video decoders, or other companion ICs and
+  transfers it into system main memory by AXI bus.
+
+properties:
+  compatible:
+    const: rockchip,rk3568-vicap
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: ACLK
+      - description: HCLK
+      - description: DCLK
+      - description: ICLK
+
+  clock-names:
+    items:
+      - const: aclk
+      - const: hclk
+      - const: dclk
+      - const: iclk
+
+  rockchip,cif-clk-delaynum:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 127
+    description:
+      Delay the DVP path clock input to align the sampling phase, only valid
+      in dual edge sampling mode.
+
+  iommus:
+    maxItems: 1
+
+  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
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to general register file used for video input block control.
+
+  power-domains:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: input port on the parallel interface
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              bus-type:
+                enum: [5, 6]
+
+            required:
+              - bus-type
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #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/power/rk3568-power.h>
+    #include <dt-bindings/media/video-interfaces.h>
+
+    parent {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        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>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                vicap_dvp: port at 0 {
+                    reg = <0>;
+
+                    vicap_dvp_input: endpoint {
+                        bus-type = <MEDIA_BUS_TYPE_BT656>;
+                        bus-width = <16>;
+                        pclk-sample = <MEDIA_PCLK_SAMPLE_DUAL_EDGE>;
+                        remote-endpoint = <&it6801_output>;
+                    };
+                };
+
+                vicap_mipi: port at 1 {
+                    reg = <1>;
+                };
+            };
+        };
+
+        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;
+        };
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 1138c8858bc7..8dbeb2927a08 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20223,6 +20223,7 @@ M:	Michael Riesch <michael.riesch at wolfvision.net>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
+F:	Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
 
 ROCKCHIP CRYPTO DRIVERS
 M:	Corentin Labbe <clabbe at baylibre.com>

-- 
2.34.1



From michael.riesch at wolfvision.net  Tue Dec 17 07:55:16 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 17 Dec 2024 16:55:16 +0100
Subject: [PATCH v2 4/6] media: rockchip: add a driver for the rockchip
 camera interface (cif)
In-Reply-To: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
References: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
Message-ID: <20241217-v6-8-topic-rk3568-vicap-v2-4-b1d488fcc0d3@wolfvision.net>

The Rockchip Camera Interface (CIF) is featured in many Rockchip SoCs
in different variations. For example, the PX30 Video Input Processor (VIP)
is able to receive video data via the Digital Video Port (DVP, a parallel
data interface and transfer it into system memory using a double-buffering
mechanism called ping-pong mode. The RK3568 Video Capture (VICAP) unit,
on the other hand, features a DVP and a MIPI CSI-2 receiver that can
receive video data independently (both using the ping-pong scheme).
The different variants may have additional features, such as scaling
and/or cropping.
Finally, the RK3588 VICAP unit constitutes an essential piece of the
camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
units, and different data path multiplexers (to system memory, to ISP,
...).

Add a basic media controller centric V4L2 driver for the Rockchip CIF with
 - support for the PX30 VIP
 - support for the RK3568 VICAP DVP
 - abstraction for the ping-pong scheme to allow for future extensions

[PX30 VIP support v1-v5]
Co-developed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
[PX30 VIP support v6-v13]
Co-developed-by: Mehdi Djait <mehdi.djait at bootlin.com>
Signed-off-by: Mehdi Djait <mehdi.djait at bootlin.com>
[added RK3568 VICAP DVP support]
[refactored to media controller centric driver, added mplane support]
Co-developed-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Signed-off-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 MAINTAINERS                                        |   1 +
 drivers/media/platform/rockchip/Kconfig            |   1 +
 drivers/media/platform/rockchip/Makefile           |   1 +
 drivers/media/platform/rockchip/cif/Kconfig        |  15 +
 drivers/media/platform/rockchip/cif/Makefile       |   3 +
 .../media/platform/rockchip/cif/cif-capture-dvp.c  | 794 +++++++++++++++++++++
 .../media/platform/rockchip/cif/cif-capture-dvp.h  |  24 +
 drivers/media/platform/rockchip/cif/cif-common.h   | 163 +++++
 drivers/media/platform/rockchip/cif/cif-dev.c      | 405 +++++++++++
 drivers/media/platform/rockchip/cif/cif-regs.h     | 132 ++++
 drivers/media/platform/rockchip/cif/cif-stream.c   | 676 ++++++++++++++++++
 drivers/media/platform/rockchip/cif/cif-stream.h   |  24 +
 12 files changed, 2239 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8dbeb2927a08..fefa848ea37c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20224,6 +20224,7 @@ L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
 F:	Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
+F:	drivers/media/platform/rockchip/cif/
 
 ROCKCHIP CRYPTO DRIVERS
 M:	Corentin Labbe <clabbe at baylibre.com>
diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platform/rockchip/Kconfig
index b41d3960c1b4..f73d68d1d2b6 100644
--- a/drivers/media/platform/rockchip/Kconfig
+++ b/drivers/media/platform/rockchip/Kconfig
@@ -2,5 +2,6 @@
 
 comment "Rockchip media platform drivers"
 
+source "drivers/media/platform/rockchip/cif/Kconfig"
 source "drivers/media/platform/rockchip/rga/Kconfig"
 source "drivers/media/platform/rockchip/rkisp1/Kconfig"
diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platform/rockchip/Makefile
index 4f782b876ac9..1a7aa1f8e134 100644
--- a/drivers/media/platform/rockchip/Makefile
+++ b/drivers/media/platform/rockchip/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
+obj-y += cif/
 obj-y += rga/
 obj-y += rkisp1/
diff --git a/drivers/media/platform/rockchip/cif/Kconfig b/drivers/media/platform/rockchip/cif/Kconfig
new file mode 100644
index 000000000000..f53e79a4b42d
--- /dev/null
+++ b/drivers/media/platform/rockchip/cif/Kconfig
@@ -0,0 +1,15 @@
+config VIDEO_ROCKCHIP_CIF
+	tristate "Rockchip Camera Interface (CIF)"
+	depends on VIDEO_DEV
+	depends on ARCH_ROCKCHIP || COMPILE_TEST
+	depends on V4L_PLATFORM_DRIVERS
+	depends on PM && COMMON_CLK
+	select MEDIA_CONTROLLER
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_FWNODE
+	select VIDEO_V4L2_SUBDEV_API
+	help
+	  This is a driver for Rockchip Camera Interface (CIF). It is featured
+	  in many Rockchips SoCs in different variations, such as the PX30
+	  Video Input Processor (VIP, one Digital Video Port (DVP)) or the
+	  RK3568 Video Capture (VICAP, one DVP, one MIPI CSI-2 receiver) unit.
diff --git a/drivers/media/platform/rockchip/cif/Makefile b/drivers/media/platform/rockchip/cif/Makefile
new file mode 100644
index 000000000000..1bd0d17ba1c4
--- /dev/null
+++ b/drivers/media/platform/rockchip/cif/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) += rockchip-cif.o
+rockchip-cif-objs += cif-dev.o cif-capture-dvp.o cif-stream.o
diff --git a/drivers/media/platform/rockchip/cif/cif-capture-dvp.c b/drivers/media/platform/rockchip/cif/cif-capture-dvp.c
new file mode 100644
index 000000000000..95ff8a986e01
--- /dev/null
+++ b/drivers/media/platform/rockchip/cif/cif-capture-dvp.c
@@ -0,0 +1,794 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2020 Maxime Chevallier <maxime.chevallier at bootlin.com>
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2024 Michael Riesch <michael.riesch at wolfvision.net>
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "cif-capture-dvp.h"
+#include "cif-common.h"
+#include "cif-regs.h"
+#include "cif-stream.h"
+
+static struct cif_output_fmt dvp_out_fmts[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_NV16,
+		.dvp_fmt_val = CIF_FORMAT_YUV_OUTPUT_422 |
+			       CIF_FORMAT_UV_STORAGE_ORDER_UVUV,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV61,
+		.dvp_fmt_val = CIF_FORMAT_YUV_OUTPUT_422 |
+			       CIF_FORMAT_UV_STORAGE_ORDER_VUVU,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV12,
+		.dvp_fmt_val = CIF_FORMAT_YUV_OUTPUT_420 |
+			       CIF_FORMAT_UV_STORAGE_ORDER_UVUV,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV21,
+		.dvp_fmt_val = CIF_FORMAT_YUV_OUTPUT_420 |
+			       CIF_FORMAT_UV_STORAGE_ORDER_VUVU,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_RGB24,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_RGB565,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_BGR666,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB8,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG8,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG8,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR8,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB10,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG10,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG10,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR10,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB12,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG12,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG12,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR12,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR16,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_Y16,
+		.cplanes = 1,
+	},
+};
+
+static const struct cif_input_fmt px30_dvp_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,
+	}
+};
+
+const struct cif_dvp_match_data px30_vip_dvp_match_data = {
+	.in_fmts = px30_dvp_in_fmts,
+	.in_fmts_num = ARRAY_SIZE(px30_dvp_in_fmts),
+	.out_fmts = dvp_out_fmts,
+	.out_fmts_num = ARRAY_SIZE(dvp_out_fmts),
+	.has_scaler = true,
+	.regs = {
+		[CIF_DVP_CTRL] = 0x00,
+		[CIF_DVP_INTEN] = 0x04,
+		[CIF_DVP_INTSTAT] = 0x08,
+		[CIF_DVP_FOR] = 0x0c,
+		[CIF_DVP_LINE_NUM_ADDR] = 0x10,
+		[CIF_DVP_FRM0_ADDR_Y] = 0x14,
+		[CIF_DVP_FRM0_ADDR_UV] = 0x18,
+		[CIF_DVP_FRM1_ADDR_Y] = 0x1c,
+		[CIF_DVP_FRM1_ADDR_UV] = 0x20,
+		[CIF_DVP_VIR_LINE_WIDTH] = 0x24,
+		[CIF_DVP_SET_SIZE] = 0x28,
+		[CIF_DVP_SCL_CTRL] = 0x48,
+		[CIF_DVP_FRAME_STATUS] = 0x60,
+		[CIF_DVP_LAST_LINE] = 0x68,
+		[CIF_DVP_LAST_PIX] = 0x6c,
+	},
+};
+
+static const struct cif_input_fmt rk3568_dvp_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 void rk3568_dvp_grf_setup(struct cif_device *cif_dev)
+{
+	u32 con1 = RK3568_GRF_WRITE_ENABLE(RK3568_GRF_VI_CON1_CIF_DATAPATH |
+					   RK3568_GRF_VI_CON1_CIF_CLK_DELAYNUM);
+
+	if (!cif_dev->grf)
+		return;
+
+	con1 |= RK3568_GRF_SET_CLK_DELAYNUM(cif_dev->dvp.cif_clk_delaynum);
+
+	if (cif_dev->dvp.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);
+}
+
+const struct cif_dvp_match_data rk3568_vicap_dvp_match_data = {
+	.in_fmts = rk3568_dvp_in_fmts,
+	.in_fmts_num = ARRAY_SIZE(rk3568_dvp_in_fmts),
+	.out_fmts = dvp_out_fmts,
+	.out_fmts_num = ARRAY_SIZE(dvp_out_fmts),
+	.setup = rk3568_dvp_grf_setup,
+	.has_scaler = false,
+	.regs = {
+		[CIF_DVP_CTRL] = 0x00,
+		[CIF_DVP_INTEN] = 0x04,
+		[CIF_DVP_INTSTAT] = 0x08,
+		[CIF_DVP_FOR] = 0x0c,
+		[CIF_DVP_LINE_NUM_ADDR] = 0x2c,
+		[CIF_DVP_FRM0_ADDR_Y] = 0x14,
+		[CIF_DVP_FRM0_ADDR_UV] = 0x18,
+		[CIF_DVP_FRM1_ADDR_Y] = 0x1c,
+		[CIF_DVP_FRM1_ADDR_UV] = 0x20,
+		[CIF_DVP_VIR_LINE_WIDTH] = 0x24,
+		[CIF_DVP_SET_SIZE] = 0x28,
+		[CIF_DVP_FRAME_STATUS] = 0x3c,
+		[CIF_DVP_LAST_LINE] = 0x44,
+		[CIF_DVP_LAST_PIX] = 0x48,
+	},
+};
+
+static inline unsigned int cif_dvp_get_addr(struct cif_device *cif_device,
+					    unsigned int index)
+{
+	if (index >= CIF_DVP_REGISTER_MAX)
+		return CIF_DVP_REGISTER_INVALID;
+
+	return cif_device->match_data->dvp->regs[index];
+}
+
+static inline void cif_dvp_write(struct cif_device *cif_dev, unsigned int index,
+				 u32 val)
+{
+	unsigned int addr = cif_dvp_get_addr(cif_dev, index);
+
+	if (addr == CIF_DVP_REGISTER_INVALID)
+		return;
+
+	writel(val, cif_dev->base_addr + addr);
+}
+
+static inline u32 cif_dvp_read(struct cif_device *cif_dev, unsigned int index)
+{
+	unsigned int addr = cif_dvp_get_addr(cif_dev, index);
+
+	if (addr == CIF_DVP_REGISTER_INVALID)
+		return 0;
+
+	return readl(cif_dev->base_addr + addr);
+}
+
+static void cif_dvp_queue_buffer(struct cif_stream *stream, unsigned int index)
+{
+	struct cif_device *cif_dev = stream->cif_dev;
+	struct cif_buffer *buffer = stream->buffers[index];
+	u32 frm_addr_y, frm_addr_uv;
+
+	frm_addr_y = index ? CIF_DVP_FRM1_ADDR_Y : CIF_DVP_FRM0_ADDR_Y;
+	frm_addr_uv = index ? CIF_DVP_FRM1_ADDR_UV : CIF_DVP_FRM0_ADDR_UV;
+
+	cif_dvp_write(cif_dev, frm_addr_y, buffer->buff_addr[CIF_PLANE_Y]);
+	cif_dvp_write(cif_dev, frm_addr_uv, buffer->buff_addr[CIF_PLANE_UV]);
+}
+
+static int cif_dvp_start_streaming(struct cif_stream *stream)
+{
+	u32 val, fmt_type, xfer_mode = 0;
+	struct cif_device *cif_dev = stream->cif_dev;
+	struct v4l2_mbus_config_parallel *parallel;
+
+	fmt_type = stream->active_in_fmt->fmt_type;
+
+	parallel = &cif_dev->dvp.vep.bus.parallel;
+	if ((parallel->bus_width == 16) &&
+	    (parallel->flags & V4L2_MBUS_PCLK_SAMPLE_DUALEDGE))
+		xfer_mode |= CIF_FORMAT_BT1120_CLOCK_DOUBLE_EDGES;
+
+	val = stream->active_out_fmt->dvp_fmt_val |
+	      stream->active_in_fmt->dvp_fmt_val | xfer_mode;
+	cif_dvp_write(cif_dev, CIF_DVP_FOR, val);
+
+	val = stream->pix.width;
+	if (stream->active_in_fmt->fmt_type == CIF_FMT_TYPE_RAW)
+		val = stream->pix.width * 2;
+
+	cif_dvp_write(cif_dev, CIF_DVP_VIR_LINE_WIDTH, val);
+	cif_dvp_write(cif_dev, CIF_DVP_SET_SIZE,
+		      stream->pix.width | (stream->pix.height << 16));
+
+	cif_dvp_write(cif_dev, CIF_DVP_FRAME_STATUS, CIF_FRAME_STAT_CLS);
+	cif_dvp_write(cif_dev, CIF_DVP_INTSTAT, CIF_INTSTAT_CLS);
+	if (cif_dev->match_data->dvp->has_scaler)
+		cif_dvp_write(cif_dev, CIF_DVP_SCL_CTRL,
+			      (fmt_type == CIF_FMT_TYPE_YUV) ?
+				      CIF_SCL_CTRL_ENABLE_YUV_16BIT_BYPASS :
+				      CIF_SCL_CTRL_ENABLE_RAW_16BIT_BYPASS);
+
+	cif_dvp_write(cif_dev, CIF_DVP_INTEN,
+		      CIF_INTEN_FRAME_END_EN | CIF_INTEN_PST_INF_FRAME_END_EN);
+
+	cif_dvp_write(cif_dev, CIF_DVP_CTRL,
+		      CIF_CTRL_AXI_BURST_16 | CIF_CTRL_MODE_PINGPONG |
+			      CIF_CTRL_ENABLE_CAPTURE);
+	return 0;
+}
+
+static void cif_dvp_stop_streaming(struct cif_stream *stream)
+{
+	struct cif_device *cif_dev = stream->cif_dev;
+	u32 val;
+
+	val = cif_dvp_read(cif_dev, CIF_DVP_CTRL);
+	cif_dvp_write(cif_dev, CIF_DVP_CTRL, val & (~CIF_CTRL_ENABLE_CAPTURE));
+	cif_dvp_write(cif_dev, CIF_DVP_INTEN, 0x0);
+	cif_dvp_write(cif_dev, CIF_DVP_INTSTAT, 0x3ff);
+	cif_dvp_write(cif_dev, CIF_DVP_FRAME_STATUS, 0x0);
+
+	stream->stopping = false;
+}
+
+static void cif_dvp_reset_stream(struct cif_device *cif_dev)
+{
+	u32 ctl = cif_dvp_read(cif_dev, CIF_DVP_CTRL);
+
+	cif_dvp_write(cif_dev, CIF_DVP_CTRL, ctl & (~CIF_CTRL_ENABLE_CAPTURE));
+	cif_dvp_write(cif_dev, CIF_DVP_CTRL, ctl | CIF_CTRL_ENABLE_CAPTURE);
+}
+
+irqreturn_t cif_dvp_isr(int irq, void *ctx)
+{
+	struct device *dev = ctx;
+	struct cif_device *cif_dev = dev_get_drvdata(dev);
+	struct cif_stream *stream = &cif_dev->dvp.stream;
+	unsigned int intstat;
+	u32 lastline, lastpix, ctl, cif_frmst;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (!cif_dev->match_data->dvp)
+		return ret;
+
+	intstat = cif_dvp_read(cif_dev, CIF_DVP_INTSTAT);
+	cif_frmst = cif_dvp_read(cif_dev, CIF_DVP_FRAME_STATUS);
+	lastline =
+		CIF_FETCH_Y_LAST_LINE(cif_dvp_read(cif_dev, CIF_DVP_LAST_LINE));
+	lastpix =
+		CIF_FETCH_Y_LAST_LINE(cif_dvp_read(cif_dev, CIF_DVP_LAST_PIX));
+	ctl = cif_dvp_read(cif_dev, CIF_DVP_CTRL);
+
+	/*
+	 * The following IRQs are enabled:
+	 *  - PST_INF_FRAME_END: cif FIFO is ready, this is prior to FRAME_END
+	 *  - FRAME_END: cif has saved frame to memory
+	 */
+
+	if (intstat & CIF_INTSTAT_PST_INF_FRAME_END) {
+		cif_dvp_write(cif_dev, CIF_DVP_INTSTAT,
+			      CIF_INTSTAT_PST_INF_FRAME_END_CLR);
+
+		if (stream->stopping)
+			/* To stop cif ASAP, before FRAME_END IRQ */
+			cif_dvp_write(cif_dev, CIF_DVP_CTRL,
+				      ctl & (~CIF_CTRL_ENABLE_CAPTURE));
+
+		ret = IRQ_HANDLED;
+	}
+
+	if (intstat & CIF_INTSTAT_FRAME_END) {
+		cif_dvp_write(cif_dev, CIF_DVP_INTSTAT,
+			      CIF_INTSTAT_FRAME_END_CLR |
+				      CIF_INTSTAT_LINE_END_CLR);
+
+		if (stream->stopping) {
+			cif_dvp_stop_streaming(stream);
+			wake_up(&stream->wq_stopped);
+			return IRQ_HANDLED;
+		}
+
+		if (lastline != stream->pix.height) {
+			v4l2_err(&cif_dev->v4l2_dev,
+				 "bad frame, irq:%#x frmst:%#x size:%dx%d\n",
+				 intstat, cif_frmst, lastpix, lastline);
+
+			cif_dvp_reset_stream(cif_dev);
+		}
+
+		cif_stream_pingpong(stream);
+
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+int cif_dvp_register(struct cif_device *cif_dev)
+{
+	struct cif_stream *stream = &cif_dev->dvp.stream;
+	const struct cif_stream_config config = {
+		.name = CIF_DRIVER_NAME "-dvp",
+	};
+	int ret;
+
+	stream->in_fmts = cif_dev->match_data->dvp->in_fmts;
+	stream->in_fmts_num = cif_dev->match_data->dvp->in_fmts_num;
+	stream->out_fmts = cif_dev->match_data->dvp->out_fmts;
+	stream->out_fmts_num = cif_dev->match_data->dvp->out_fmts_num;
+	stream->queue_buffer = cif_dvp_queue_buffer;
+	stream->start_streaming = cif_dvp_start_streaming;
+	stream->stop_streaming = cif_dvp_stop_streaming;
+
+	if (cif_dev->match_data->dvp->setup)
+		cif_dev->match_data->dvp->setup(cif_dev);
+
+	ret = cif_stream_register(cif_dev, stream, &config);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+void cif_dvp_unregister(struct cif_device *cif_dev)
+{
+	struct cif_stream *stream = &cif_dev->dvp.stream;
+
+	cif_stream_unregister(stream);
+}
diff --git a/drivers/media/platform/rockchip/cif/cif-capture-dvp.h b/drivers/media/platform/rockchip/cif/cif-capture-dvp.h
new file mode 100644
index 000000000000..48dd1b7185dc
--- /dev/null
+++ b/drivers/media/platform/rockchip/cif/cif-capture-dvp.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2024 Michael Riesch <michael.riesch at wolfvision.net>
+ */
+
+#ifndef _CIF_CAPTURE_DVP_H
+#define _CIF_CAPTURE_DVP_H
+
+#include "cif-common.h"
+
+extern const struct cif_dvp_match_data px30_vip_dvp_match_data;
+extern const struct cif_dvp_match_data rk3568_vicap_dvp_match_data;
+
+int cif_dvp_register(struct cif_device *dev);
+
+void cif_dvp_unregister(struct cif_device *dev);
+
+irqreturn_t cif_dvp_isr(int irq, void *ctx);
+
+#endif
diff --git a/drivers/media/platform/rockchip/cif/cif-common.h b/drivers/media/platform/rockchip/cif/cif-common.h
new file mode 100644
index 000000000000..c90b705d6bb4
--- /dev/null
+++ b/drivers/media/platform/rockchip/cif/cif-common.h
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2024 Michael Riesch <michael.riesch at wolfvision.net>
+ */
+
+#ifndef _CIF_COMMON_H
+#define _CIF_COMMON_H
+
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+
+#include <media/media-device.h>
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "cif-regs.h"
+
+#define CIF_DRIVER_NAME "rockchip-cif"
+#define CIF_DEFAULT_WIDTH 640
+#define CIF_DEFAULT_HEIGHT 480
+#define CIF_CLKS_MAX 4
+
+enum cif_fmt_type {
+	CIF_FMT_TYPE_YUV = 0,
+	CIF_FMT_TYPE_RAW,
+};
+
+enum cif_plane_index {
+	CIF_PLANE_Y = 0,
+	CIF_PLANE_UV = 1,
+};
+
+struct cif_input_fmt {
+	u32 mbus_code;
+
+	enum cif_fmt_type fmt_type;
+	enum v4l2_field field;
+
+	union {
+		u32 dvp_fmt_val;
+	};
+};
+
+struct cif_output_fmt {
+	u32 fourcc;
+	u32 mbus_code;
+	u8 cplanes;
+
+	union {
+		u32 dvp_fmt_val;
+	};
+};
+
+struct cif_buffer {
+	struct vb2_v4l2_buffer vb;
+	struct list_head queue;
+	dma_addr_t buff_addr[VIDEO_MAX_PLANES];
+	bool is_dummy;
+};
+
+struct cif_dummy_buffer {
+	struct cif_buffer buffer;
+	void *vaddr;
+	u32 size;
+};
+
+struct cif_stream;
+
+struct cif_remote {
+	struct v4l2_async_connection async_conn;
+	struct v4l2_subdev *sd;
+	struct cif_stream *stream;
+	int source_pad;
+};
+
+struct cif_stream {
+	struct cif_device *cif_dev;
+	struct cif_remote *remote;
+
+	/* in ping-pong mode, two buffers can be provided to the HW */
+	struct cif_buffer *buffers[2];
+	int frame_idx;
+	int frame_phase;
+
+	/* in case of no available buffer, HW can write to the dummy buffer */
+	struct cif_dummy_buffer dummy;
+
+	bool stopping;
+	wait_queue_head_t wq_stopped;
+
+	/* queue of available buffers plus spinlock that protects it */
+	spinlock_t driver_queue_lock;
+	struct list_head driver_queue;
+
+	/* Lock used by the V4L core. */
+	struct mutex vlock;
+	struct video_device vdev;
+	struct vb2_queue buf_queue;
+	struct media_pad pad;
+	struct media_pipeline pipeline;
+
+	struct v4l2_pix_format_mplane pix;
+	const struct cif_input_fmt *active_in_fmt;
+	const struct cif_output_fmt *active_out_fmt;
+
+	const struct cif_input_fmt *in_fmts;
+	unsigned int in_fmts_num;
+	const struct cif_output_fmt *out_fmts;
+	unsigned int out_fmts_num;
+
+	void (*queue_buffer)(struct cif_stream *stream, unsigned int index);
+	int (*start_streaming)(struct cif_stream *stream);
+	void (*stop_streaming)(struct cif_stream *stream);
+};
+
+struct cif_dvp {
+	struct cif_stream stream;
+	struct v4l2_fwnode_endpoint vep;
+	u32 cif_clk_delaynum;
+};
+
+struct cif_dvp_match_data {
+	const struct cif_input_fmt *in_fmts;
+	unsigned int in_fmts_num;
+	const struct cif_output_fmt *out_fmts;
+	unsigned int out_fmts_num;
+	void (*setup)(struct cif_device *cif_dev);
+	bool has_scaler;
+	unsigned int regs[CIF_DVP_REGISTER_MAX];
+};
+
+struct cif_match_data {
+	const char *const *clks;
+	unsigned int clks_num;
+	const struct cif_dvp_match_data *dvp;
+};
+
+struct cif_device {
+	struct device *dev;
+
+	struct clk_bulk_data clks[CIF_CLKS_MAX];
+	unsigned int clks_num;
+	struct regmap *grf;
+	struct reset_control *cif_rst;
+	int irq;
+	void __iomem *base_addr;
+
+	const struct cif_match_data *match_data;
+	struct cif_dvp dvp;
+
+	struct media_device media_dev;
+	struct v4l2_device v4l2_dev;
+	struct v4l2_async_notifier notifier;
+};
+
+#endif
diff --git a/drivers/media/platform/rockchip/cif/cif-dev.c b/drivers/media/platform/rockchip/cif/cif-dev.c
new file mode 100644
index 000000000000..c3aafcf740f1
--- /dev/null
+++ b/drivers/media/platform/rockchip/cif/cif-dev.c
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2020 Maxime Chevallier <maxime.chevallier at bootlin.com>
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2024 Michael Riesch <michael.riesch at wolfvision.net>
+ */
+
+#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>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+
+#include "cif-capture-dvp.h"
+#include "cif-common.h"
+
+const char *const px30_vip_clks[] = {
+	"aclk",
+	"hclk",
+	"pclk",
+};
+
+static const struct cif_match_data px30_vip_match_data = {
+	.clks = px30_vip_clks,
+	.clks_num = ARRAY_SIZE(px30_vip_clks),
+	.dvp = &px30_vip_dvp_match_data,
+};
+
+const char *const rk3568_vicap_clks[] = {
+	"aclk",
+	"hclk",
+	"dclk",
+	"iclk",
+};
+
+static const struct cif_match_data rk3568_vicap_match_data = {
+	.clks = rk3568_vicap_clks,
+	.clks_num = ARRAY_SIZE(rk3568_vicap_clks),
+	.dvp = &rk3568_vicap_dvp_match_data,
+};
+
+static const struct of_device_id cif_plat_of_match[] = {
+	{
+		.compatible = "rockchip,px30-vip",
+		.data = &px30_vip_match_data,
+	},
+	{
+		.compatible = "rockchip,rk3568-vicap",
+		.data = &rk3568_vicap_match_data,
+	},
+	{},
+};
+
+static void cif_notify(struct v4l2_subdev *sd, unsigned int notification,
+		       void *arg)
+{
+	struct v4l2_device *v4l2_dev = sd->v4l2_dev;
+	struct cif_device *cif =
+		container_of(v4l2_dev, struct cif_device, v4l2_dev);
+	struct video_device *vdev = NULL;
+
+	if ((cif->dvp.stream.remote) && (cif->dvp.stream.remote->sd == sd))
+		vdev = &cif->dvp.stream.vdev;
+
+	if (!vdev)
+		return;
+
+	switch (notification) {
+	case V4L2_DEVICE_NOTIFY_EVENT:
+		v4l2_event_queue(vdev, arg);
+		break;
+	default:
+		break;
+	}
+}
+
+static int cif_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+				     struct v4l2_subdev *sd,
+				     struct v4l2_async_connection *asd)
+{
+	struct cif_device *cif_dev =
+		container_of(notifier, struct cif_device, notifier);
+	struct cif_remote *remote =
+		container_of(asd, struct cif_remote, async_conn);
+	int source_pad;
+	int ret;
+
+	source_pad = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
+						 MEDIA_PAD_FL_SOURCE);
+	if (source_pad < 0) {
+		dev_err(cif_dev->dev, "failed to find source pad for %s\n",
+			sd->name);
+		return source_pad;
+	}
+
+	remote->sd = sd;
+	remote->source_pad = source_pad;
+
+	ret = media_create_pad_link(&sd->entity, source_pad,
+				    &remote->stream->vdev.entity, 0,
+				    MEDIA_LNK_FL_ENABLED);
+	if (ret) {
+		dev_err(cif_dev->dev, "failed to link source pad of %s\n",
+			sd->name);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cif_subdev_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+	struct cif_device *cif_dev =
+		container_of(notifier, struct cif_device, notifier);
+
+	return v4l2_device_register_subdev_nodes(&cif_dev->v4l2_dev);
+}
+
+static const struct v4l2_async_notifier_operations cif_subdev_notifier_ops = {
+	.bound = cif_subdev_notifier_bound,
+	.complete = cif_subdev_notifier_complete,
+};
+
+static int cif_subdev_notifier_register(struct cif_device *cif_dev, int index)
+{
+	struct v4l2_async_notifier *ntf = &cif_dev->notifier;
+	struct v4l2_fwnode_endpoint *vep;
+	struct cif_remote *remote;
+	struct device *dev = cif_dev->dev;
+	struct fwnode_handle *ep;
+	int ret;
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), index, 0,
+					     FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!ep)
+		return -ENODEV;
+
+	if (index == 0) {
+		vep = &cif_dev->dvp.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) {
+			v4l2_err(&cif_dev->v4l2_dev, "unsupported bus type\n");
+			goto complete;
+		}
+
+		remote = v4l2_async_nf_add_fwnode_remote(ntf, ep,
+							 struct cif_remote);
+		if (IS_ERR(remote)) {
+			ret = PTR_ERR(remote);
+			goto complete;
+		}
+
+		cif_dev->dvp.stream.remote = remote;
+		remote->stream = &cif_dev->dvp.stream;
+	} else {
+		ret = -ENODEV;
+		goto complete;
+	}
+
+complete:
+	fwnode_handle_put(ep);
+
+	return ret;
+}
+
+static void cif_subdev_notifier_unregister(struct cif_device *cif_dev,
+					   int index)
+{
+}
+
+static int cif_entities_register(struct cif_device *cif_dev)
+{
+	struct v4l2_async_notifier *ntf = &cif_dev->notifier;
+	struct device *dev = cif_dev->dev;
+	int ret;
+
+	v4l2_async_nf_init(ntf, &cif_dev->v4l2_dev);
+	ntf->ops = &cif_subdev_notifier_ops;
+
+	if (cif_dev->match_data->dvp) {
+		ret = cif_subdev_notifier_register(cif_dev, 0);
+		if (ret) {
+			dev_err(dev,
+				"failed to register notifier for dvp: %d\n",
+				ret);
+			goto err;
+		}
+
+		ret = cif_dvp_register(cif_dev);
+		if (ret) {
+			dev_err(dev, "failed to register dvp: %d\n", ret);
+			goto err_dvp_notifier_unregister;
+		}
+	}
+
+	ret = v4l2_async_nf_register(ntf);
+	if (ret)
+		goto err_notifier_cleanup;
+
+	return 0;
+
+err_notifier_cleanup:
+	if (cif_dev->match_data->dvp)
+		cif_dvp_unregister(cif_dev);
+err_dvp_notifier_unregister:
+	if (cif_dev->match_data->dvp)
+		cif_subdev_notifier_unregister(cif_dev, 0);
+	v4l2_async_nf_cleanup(ntf);
+err:
+	return ret;
+}
+
+static void cif_entities_unregister(struct cif_device *cif_dev)
+{
+	v4l2_async_nf_unregister(&cif_dev->notifier);
+	v4l2_async_nf_cleanup(&cif_dev->notifier);
+
+	if (cif_dev->match_data->dvp) {
+		cif_subdev_notifier_unregister(cif_dev, 0);
+		cif_dvp_unregister(cif_dev);
+	}
+}
+
+static irqreturn_t cif_isr(int irq, void *ctx)
+{
+	irqreturn_t ret = IRQ_NONE;
+
+	if (cif_dvp_isr(irq, ctx) == IRQ_HANDLED)
+		ret = IRQ_HANDLED;
+
+	return ret;
+}
+
+static int cif_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cif_device *cif_dev;
+	u32 cif_clk_delaynum = 0;
+	int ret, irq, i;
+
+	cif_dev = devm_kzalloc(dev, sizeof(*cif_dev), GFP_KERNEL);
+	if (!cif_dev)
+		return -ENOMEM;
+
+	cif_dev->match_data = of_device_get_match_data(dev);
+	if (!cif_dev->match_data)
+		return -ENODEV;
+
+	dev_set_drvdata(dev, cif_dev);
+	cif_dev->dev = dev;
+
+	cif_dev->base_addr = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(cif_dev->base_addr))
+		return PTR_ERR(cif_dev->base_addr);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_irq(dev, irq, cif_isr, IRQF_SHARED,
+			       dev_driver_string(dev), dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to request irq\n");
+	cif_dev->irq = irq;
+
+	cif_dev->clks_num = cif_dev->match_data->clks_num;
+	for (i = 0; (i < cif_dev->clks_num) && (i < CIF_CLKS_MAX); i++)
+		cif_dev->clks[i].id = cif_dev->match_data->clks[i];
+	ret = devm_clk_bulk_get(dev, cif_dev->clks_num, cif_dev->clks);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to get clocks\n");
+
+	cif_dev->cif_rst = devm_reset_control_array_get_exclusive(dev);
+	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");
+	if (IS_ERR(cif_dev->grf))
+		cif_dev->grf = NULL;
+
+	if (cif_dev->match_data->dvp) {
+		of_property_read_u32(dev->of_node, "rockchip,cif-clk-delaynum",
+				     &cif_clk_delaynum);
+		cif_dev->dvp.cif_clk_delaynum = cif_clk_delaynum;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	cif_dev->media_dev.dev = dev;
+	strscpy(cif_dev->media_dev.model, CIF_DRIVER_NAME,
+		sizeof(cif_dev->media_dev.model));
+	media_device_init(&cif_dev->media_dev);
+
+	cif_dev->v4l2_dev.mdev = &cif_dev->media_dev;
+	cif_dev->v4l2_dev.notify = cif_notify;
+	strscpy(cif_dev->v4l2_dev.name, CIF_DRIVER_NAME,
+		sizeof(cif_dev->v4l2_dev.name));
+
+	ret = v4l2_device_register(dev, &cif_dev->v4l2_dev);
+	if (ret)
+		goto err_media_dev_cleanup;
+
+	ret = media_device_register(&cif_dev->media_dev);
+	if (ret < 0) {
+		dev_err(dev, "failed to register media device: %d\n", ret);
+		goto err_v4l2_dev_unregister;
+	}
+
+	ret = cif_entities_register(cif_dev);
+	if (ret) {
+		dev_err(dev, "failed to register media entities: %d\n", ret);
+		goto err_media_dev_unregister;
+	}
+
+	return 0;
+
+err_media_dev_unregister:
+	media_device_unregister(&cif_dev->media_dev);
+err_v4l2_dev_unregister:
+	v4l2_device_unregister(&cif_dev->v4l2_dev);
+err_media_dev_cleanup:
+	media_device_cleanup(&cif_dev->media_dev);
+	pm_runtime_disable(&pdev->dev);
+	return ret;
+}
+
+static void cif_remove(struct platform_device *pdev)
+{
+	struct cif_device *cif_dev = platform_get_drvdata(pdev);
+
+	cif_entities_unregister(cif_dev);
+	media_device_unregister(&cif_dev->media_dev);
+	v4l2_device_unregister(&cif_dev->v4l2_dev);
+	media_device_cleanup(&cif_dev->media_dev);
+	pm_runtime_disable(&pdev->dev);
+}
+
+static int cif_runtime_suspend(struct device *dev)
+{
+	struct cif_device *cif_dev = dev_get_drvdata(dev);
+
+	/*
+	 * Reset CIF (CRU, DMA, FIFOs) to allow a clean resume.
+	 * Since this resets the IOMMU too, we cannot issue this reset when
+	 * resuming.
+	 */
+	reset_control_assert(cif_dev->cif_rst);
+	udelay(5);
+	reset_control_deassert(cif_dev->cif_rst);
+
+	clk_bulk_disable_unprepare(cif_dev->clks_num, cif_dev->clks);
+
+	return 0;
+}
+
+static int cif_runtime_resume(struct device *dev)
+{
+	struct cif_device *cif_dev = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(cif_dev->clks_num, cif_dev->clks);
+	if (ret) {
+		dev_err(dev, "failed to enable clocks\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops cif_plat_pm_ops = {
+	.runtime_suspend = cif_runtime_suspend,
+	.runtime_resume = cif_runtime_resume,
+};
+
+static struct platform_driver cif_plat_drv = {
+	.driver = {
+		   .name = CIF_DRIVER_NAME,
+		   .of_match_table = cif_plat_of_match,
+		   .pm = &cif_plat_pm_ops,
+	},
+	.probe = cif_probe,
+	.remove_new = cif_remove,
+};
+module_platform_driver(cif_plat_drv);
+
+MODULE_DESCRIPTION("Rockchip Camera Interface (CIF) platform driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/rockchip/cif/cif-regs.h b/drivers/media/platform/rockchip/cif/cif-regs.h
new file mode 100644
index 000000000000..eb32998ae056
--- /dev/null
+++ b/drivers/media/platform/rockchip/cif/cif-regs.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2024 Michael Riesch <michael.riesch at wolfvision.net>
+ */
+
+#ifndef _CIF_REGS_H
+#define _CIF_REGS_H
+
+enum cif_dvp_register {
+	CIF_DVP_CTRL,
+	CIF_DVP_INTEN,
+	CIF_DVP_INTSTAT,
+	CIF_DVP_FOR,
+	CIF_DVP_LINE_NUM_ADDR,
+	CIF_DVP_FRM0_ADDR_Y,
+	CIF_DVP_FRM0_ADDR_UV,
+	CIF_DVP_FRM1_ADDR_Y,
+	CIF_DVP_FRM1_ADDR_UV,
+	CIF_DVP_VIR_LINE_WIDTH,
+	CIF_DVP_SET_SIZE,
+	CIF_DVP_SCL_CTRL,
+	CIF_DVP_FRAME_STATUS,
+	CIF_DVP_LAST_LINE,
+	CIF_DVP_LAST_PIX,
+	CIF_DVP_REGISTER_MAX,
+	CIF_DVP_REGISTER_INVALID,
+};
+
+#define CIF_FETCH_Y_LAST_LINE(VAL)		((VAL) & 0x1fff)
+
+#define CIF_CTRL_ENABLE_CAPTURE			BIT(0)
+#define CIF_CTRL_MODE_PINGPONG			BIT(1)
+#define CIF_CTRL_MODE_LINELOOP			BIT(2)
+#define CIF_CTRL_AXI_BURST_16			(0xf << 12)
+
+#define CIF_INTEN_FRAME_END_EN			BIT(0)
+#define CIF_INTEN_LINE_ERR_EN			BIT(2)
+#define CIF_INTEN_BUS_ERR_EN			BIT(6)
+#define CIF_INTEN_SCL_ERR_EN			BIT(7)
+#define CIF_INTEN_PST_INF_FRAME_END_EN		BIT(9)
+
+#define CIF_INTSTAT_CLS				0x3ff
+#define CIF_INTSTAT_FRAME_END			BIT(0)
+#define CIF_INTSTAT_LINE_END			BIT(1)
+#define CIF_INTSTAT_LINE_ERR			BIT(2)
+#define CIF_INTSTAT_PIX_ERR			BIT(3)
+#define CIF_INTSTAT_DFIFO_OF			BIT(5)
+#define CIF_INTSTAT_BUS_ERR			BIT(6)
+#define CIF_INTSTAT_PRE_INF_FRAME_END		BIT(8)
+#define CIF_INTSTAT_PST_INF_FRAME_END		BIT(9)
+#define CIF_INTSTAT_FRAME_END_CLR		BIT(0)
+#define CIF_INTSTAT_LINE_END_CLR		BIT(1)
+#define CIF_INTSTAT_LINE_ERR_CLR		BIT(2)
+#define CIF_INTSTAT_PST_INF_FRAME_END_CLR	BIT(9)
+#define CIF_INTSTAT_ERR				0xfc
+
+#define CIF_FRAME_STAT_CLS			0x00
+#define CIF_FRAME_FRM0_STAT_CLS			0x20
+
+#define CIF_FORMAT_VSY_HIGH_ACTIVE		BIT(0)
+#define CIF_FORMAT_HSY_LOW_ACTIVE		BIT(1)
+
+#define CIF_FORMAT_INPUT_MODE_YUV		(0x00 << 2)
+#define CIF_FORMAT_INPUT_MODE_PAL		(0x02 << 2)
+#define CIF_FORMAT_INPUT_MODE_NTSC		(0x03 << 2)
+#define CIF_FORMAT_INPUT_MODE_BT1120		(0x07 << 2)
+#define CIF_FORMAT_INPUT_MODE_RAW		(0x04 << 2)
+#define CIF_FORMAT_INPUT_MODE_JPEG		(0x05 << 2)
+#define CIF_FORMAT_INPUT_MODE_MIPI		(0x06 << 2)
+
+#define CIF_FORMAT_YUV_INPUT_ORDER_UYVY		(0x00 << 5)
+#define CIF_FORMAT_YUV_INPUT_ORDER_YVYU		(0x01 << 5)
+#define CIF_FORMAT_YUV_INPUT_ORDER_VYUY		(0x02 << 5)
+#define CIF_FORMAT_YUV_INPUT_ORDER_YUYV		(0x03 << 5)
+#define CIF_FORMAT_YUV_INPUT_422		(0x00 << 7)
+#define CIF_FORMAT_YUV_INPUT_420		BIT(7)
+
+#define CIF_FORMAT_INPUT_420_ORDER_ODD		BIT(8)
+
+#define CIF_FORMAT_CCIR_INPUT_ORDER_EVEN	BIT(9)
+
+#define CIF_FORMAT_RAW_DATA_WIDTH_8		(0x00 << 11)
+#define CIF_FORMAT_RAW_DATA_WIDTH_10		(0x01 << 11)
+#define CIF_FORMAT_RAW_DATA_WIDTH_12		(0x02 << 11)
+
+#define CIF_FORMAT_YUV_OUTPUT_422		(0x00 << 16)
+#define CIF_FORMAT_YUV_OUTPUT_420		BIT(16)
+
+#define CIF_FORMAT_OUTPUT_420_ORDER_EVEN	(0x00 << 17)
+#define CIF_FORMAT_OUTPUT_420_ORDER_ODD		BIT(17)
+
+#define CIF_FORMAT_RAWD_DATA_LITTLE_ENDIAN	(0x00 << 18)
+#define CIF_FORMAT_RAWD_DATA_BIG_ENDIAN		BIT(18)
+
+#define CIF_FORMAT_UV_STORAGE_ORDER_UVUV	(0x00 << 19)
+#define CIF_FORMAT_UV_STORAGE_ORDER_VUVU	BIT(19)
+
+#define CIF_FORMAT_BT1120_CLOCK_SINGLE_EDGES	(0x00 << 24)
+#define CIF_FORMAT_BT1120_CLOCK_DOUBLE_EDGES	BIT(24)
+#define CIF_FORMAT_BT1120_TRANSMIT_INTERFACE	(0x00 << 25)
+#define CIF_FORMAT_BT1120_TRANSMIT_PROGRESS	BIT(25)
+#define CIF_FORMAT_BT1120_YC_SWAP		BIT(26)
+
+#define CIF_SCL_CTRL_ENABLE_SCL_DOWN		BIT(0)
+#define CIF_SCL_CTRL_ENABLE_SCL_UP		BIT(1)
+#define CIF_SCL_CTRL_ENABLE_YUV_16BIT_BYPASS	BIT(4)
+#define CIF_SCL_CTRL_ENABLE_RAW_16BIT_BYPASS	BIT(5)
+#define CIF_SCL_CTRL_ENABLE_32BIT_BYPASS	BIT(6)
+#define CIF_SCL_CTRL_DISABLE_32BIT_BYPASS	(0x00 << 6)
+
+#define CIF_INTSTAT_F0_READY			BIT(0)
+#define CIF_INTSTAT_F1_READY			BIT(1)
+
+#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_VI_CON1_CIF_CLK_DELAYNUM	0x7f
+#define RK3568_GRF_SET_CLK_DELAYNUM(x)		((x) & 0x7f)
+
+#define RK3568_GRF_WRITE_ENABLE(x)		((x) << 16)
+
+#endif
diff --git a/drivers/media/platform/rockchip/cif/cif-stream.c b/drivers/media/platform/rockchip/cif/cif-stream.c
new file mode 100644
index 000000000000..a56ec3ac675c
--- /dev/null
+++ b/drivers/media/platform/rockchip/cif/cif-stream.c
@@ -0,0 +1,676 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2024 Michael Riesch <michael.riesch at wolfvision.net>
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "cif-common.h"
+#include "cif-stream.h"
+
+#define CIF_REQ_BUFS_MIN 8
+#define CIF_MIN_WIDTH 64
+#define CIF_MIN_HEIGHT 64
+#define CIF_MAX_WIDTH 8192
+#define CIF_MAX_HEIGHT 8192
+
+static inline struct cif_buffer *to_cif_buffer(struct vb2_v4l2_buffer *vb)
+{
+	return container_of(vb, struct cif_buffer, vb);
+}
+
+static inline struct cif_stream *to_cif_stream(struct video_device *vdev)
+{
+	return container_of(vdev, struct cif_stream, vdev);
+}
+
+static const struct cif_output_fmt *
+cif_stream_find_output_fmt(struct cif_stream *stream, u32 pixelfmt)
+{
+	const struct cif_output_fmt *fmt;
+	unsigned int i;
+
+	for (i = 0; i < stream->out_fmts_num; i++) {
+		fmt = &stream->out_fmts[i];
+		if (fmt->fourcc == pixelfmt)
+			return fmt;
+	}
+
+	return NULL;
+}
+
+static struct cif_buffer *cif_stream_pop_buffer(struct cif_stream *stream)
+{
+	struct cif_buffer *buffer = NULL;
+	unsigned long lock_flags;
+
+	spin_lock_irqsave(&stream->driver_queue_lock, lock_flags);
+
+	if (list_empty(&stream->driver_queue))
+		goto err_empty;
+
+	buffer = list_first_entry(&stream->driver_queue, struct cif_buffer,
+				  queue);
+	list_del(&buffer->queue);
+
+err_empty:
+	spin_unlock_irqrestore(&stream->driver_queue_lock, lock_flags);
+	return buffer;
+}
+
+static void cif_stream_push_buffer(struct cif_stream *stream,
+				   struct cif_buffer *buffer)
+{
+	unsigned long lock_flags;
+
+	spin_lock_irqsave(&stream->driver_queue_lock, lock_flags);
+	list_add_tail(&buffer->queue, &stream->driver_queue);
+	spin_unlock_irqrestore(&stream->driver_queue_lock, lock_flags);
+}
+
+static inline void cif_stream_return_buffer(struct cif_stream *stream,
+					    struct cif_buffer *buffer,
+					    enum vb2_buffer_state state)
+{
+	struct vb2_v4l2_buffer *vb = &buffer->vb;
+
+	vb2_buffer_done(&vb->vb2_buf, state);
+}
+
+static void cif_stream_complete_buffer(struct cif_stream *stream,
+				       struct cif_buffer *buffer)
+{
+	struct vb2_v4l2_buffer *vb = &buffer->vb;
+
+	vb->vb2_buf.timestamp = ktime_get_ns();
+	vb->sequence = stream->frame_idx;
+	vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE);
+	stream->frame_idx++;
+}
+
+void cif_stream_pingpong(struct cif_stream *stream)
+{
+	struct cif_buffer *buffer;
+
+	if (!stream->buffers[stream->frame_phase]->is_dummy)
+		cif_stream_complete_buffer(
+			stream, stream->buffers[stream->frame_phase]);
+
+	buffer = cif_stream_pop_buffer(stream);
+	if (buffer) {
+		stream->buffers[stream->frame_phase] = buffer;
+		stream->buffers[stream->frame_phase]->is_dummy = false;
+	} else {
+		stream->buffers[stream->frame_phase] = &stream->dummy.buffer;
+		stream->buffers[stream->frame_phase]->is_dummy = true;
+		dev_warn(stream->cif_dev->dev,
+			 "no buffer available, frame will be dropped\n");
+	}
+
+	if (stream->queue_buffer)
+		stream->queue_buffer(stream, stream->frame_phase);
+
+	stream->frame_phase = 1 - stream->frame_phase;
+}
+
+static int cif_stream_init_buffers(struct cif_stream *stream)
+{
+	const struct cif_output_fmt *fmt = stream->active_out_fmt;
+	struct v4l2_pix_format_mplane *pix = &stream->pix;
+	int i;
+
+	stream->buffers[0] = cif_stream_pop_buffer(stream);
+	if (!stream->buffers[0])
+		goto err_buff_0;
+
+	stream->buffers[1] = cif_stream_pop_buffer(stream);
+	if (!stream->buffers[1])
+		goto err_buff_1;
+
+	if (stream->queue_buffer) {
+		stream->queue_buffer(stream, 0);
+		stream->queue_buffer(stream, 1);
+	}
+
+	stream->dummy.size = fmt->cplanes * pix->plane_fmt[0].sizeimage;
+	stream->dummy.vaddr =
+		dma_alloc_attrs(stream->cif_dev->dev, stream->dummy.size,
+				&stream->dummy.buffer.buff_addr[0], GFP_KERNEL,
+				DMA_ATTR_NO_KERNEL_MAPPING);
+	if (!stream->dummy.vaddr)
+		goto err_dummy;
+
+	for (i = 1; i < fmt->cplanes; i++)
+		stream->dummy.buffer.buff_addr[i] =
+			stream->dummy.buffer.buff_addr[i - 1] +
+			pix->plane_fmt[i - 1].bytesperline * pix->height;
+
+	return 0;
+
+err_dummy:
+	cif_stream_return_buffer(stream, stream->buffers[1],
+				 VB2_BUF_STATE_QUEUED);
+	stream->buffers[1] = NULL;
+
+err_buff_1:
+	cif_stream_return_buffer(stream, stream->buffers[0],
+				 VB2_BUF_STATE_QUEUED);
+	stream->buffers[0] = NULL;
+err_buff_0:
+	return -EINVAL;
+}
+
+static void cif_stream_return_all_buffers(struct cif_stream *stream,
+					  enum vb2_buffer_state state)
+{
+	struct cif_buffer *buffer;
+
+	dma_free_attrs(stream->cif_dev->dev, stream->dummy.size,
+		       stream->dummy.vaddr, stream->dummy.buffer.buff_addr[0],
+		       DMA_ATTR_NO_KERNEL_MAPPING);
+
+	if (stream->buffers[0]) {
+		cif_stream_return_buffer(stream, stream->buffers[0], state);
+		stream->buffers[0] = NULL;
+	}
+
+	if (stream->buffers[1]) {
+		cif_stream_return_buffer(stream, stream->buffers[1], state);
+		stream->buffers[1] = NULL;
+	}
+
+	while ((buffer = cif_stream_pop_buffer(stream)))
+		cif_stream_return_buffer(stream, buffer, state);
+}
+
+static int cif_stream_setup_queue(struct vb2_queue *queue,
+				  unsigned int *num_buffers,
+				  unsigned int *num_planes,
+				  unsigned int sizes[],
+				  struct device *alloc_devs[])
+{
+	struct cif_stream *stream = queue->drv_priv;
+	struct v4l2_pix_format_mplane *pix = &stream->pix;
+	unsigned int i;
+
+	if (*num_planes) {
+		if (*num_planes != pix->num_planes)
+			return -EINVAL;
+
+		for (i = 0; i < pix->num_planes; i++)
+			if (sizes[i] < pix->plane_fmt[i].sizeimage)
+				return -EINVAL;
+	} else {
+		*num_planes = pix->num_planes;
+		for (i = 0; i < pix->num_planes; i++)
+			sizes[i] = pix->plane_fmt[i].sizeimage;
+	}
+
+	return 0;
+}
+
+static int cif_stream_prepare_buffer(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct cif_buffer *buffer = to_cif_buffer(vbuf);
+	struct cif_stream *stream = vb->vb2_queue->drv_priv;
+	const struct cif_output_fmt *fmt = stream->active_out_fmt;
+	struct v4l2_pix_format_mplane *pix = &stream->pix;
+	unsigned int i;
+
+	memset(buffer->buff_addr, 0, sizeof(buffer->buff_addr));
+	for (i = 0; i < pix->num_planes; i++)
+		buffer->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
+
+	/* apply fallback for non-mplane formats, if required */
+	if (pix->num_planes == 1) {
+		for (i = 1; i < fmt->cplanes; i++)
+			buffer->buff_addr[i] =
+				buffer->buff_addr[i - 1] +
+				pix->plane_fmt[i - 1].bytesperline *
+					pix->height;
+	}
+
+	for (i = 0; i < pix->num_planes; i++) {
+		unsigned long size = pix->plane_fmt[i].sizeimage;
+
+		if (vb2_plane_size(vb, i) < size) {
+			dev_err(stream->cif_dev->dev,
+				"user buffer too small (%ld < %ld)\n",
+				vb2_plane_size(vb, i), size);
+			return -EINVAL;
+		}
+
+		vb2_set_plane_payload(vb, i, size);
+	}
+
+	return 0;
+}
+
+static void cif_stream_queue_buffer(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct cif_buffer *buffer = to_cif_buffer(vbuf);
+	struct cif_stream *stream = vb->vb2_queue->drv_priv;
+
+	cif_stream_push_buffer(stream, buffer);
+}
+
+static int cif_stream_start_streaming(struct vb2_queue *queue,
+				      unsigned int count)
+{
+	struct cif_stream *stream = queue->drv_priv;
+	struct cif_device *cif_dev = stream->cif_dev;
+	struct v4l2_subdev *sd = stream->remote->sd;
+	int ret;
+
+	stream->frame_idx = 0;
+	stream->frame_phase = 0;
+
+	ret = video_device_pipeline_start(&stream->vdev, &stream->pipeline);
+	if (ret) {
+		dev_err(cif_dev->dev, "failed to start pipeline %d\n", ret);
+		goto err_out;
+	}
+
+	ret = pm_runtime_resume_and_get(cif_dev->dev);
+	if (ret < 0) {
+		dev_err(cif_dev->dev, "failed to get runtime pm, %d\n", ret);
+		goto err_pipeline_stop;
+	}
+
+	ret = cif_stream_init_buffers(stream);
+	if (ret)
+		goto err_runtime_put;
+
+	if (stream->start_streaming) {
+		ret = stream->start_streaming(stream);
+		if (ret < 0)
+			goto err_runtime_put;
+	}
+
+	ret = v4l2_subdev_call(sd, video, s_stream, 1);
+	if (ret < 0)
+		goto err_stop_stream;
+
+	return 0;
+
+err_stop_stream:
+	if (stream->stop_streaming)
+		stream->stop_streaming(stream);
+err_runtime_put:
+	pm_runtime_put(cif_dev->dev);
+err_pipeline_stop:
+	video_device_pipeline_stop(&stream->vdev);
+err_out:
+	cif_stream_return_all_buffers(stream, VB2_BUF_STATE_QUEUED);
+	return ret;
+}
+
+static void cif_stream_stop_streaming(struct vb2_queue *queue)
+{
+	struct cif_stream *stream = queue->drv_priv;
+	struct cif_device *cif_dev = stream->cif_dev;
+	struct v4l2_subdev *sd = stream->remote->sd;
+	int ret;
+
+	v4l2_subdev_call(sd, video, s_stream, 0);
+
+	stream->stopping = true;
+	ret = wait_event_timeout(stream->wq_stopped, !stream->stopping,
+				 msecs_to_jiffies(1000));
+
+	if (!ret && stream->stop_streaming)
+		stream->stop_streaming(stream);
+
+	pm_runtime_put(cif_dev->dev);
+
+	cif_stream_return_all_buffers(stream, VB2_BUF_STATE_ERROR);
+
+	video_device_pipeline_stop(&stream->vdev);
+}
+
+static const struct vb2_ops cif_stream_vb2_ops = {
+	.queue_setup = cif_stream_setup_queue,
+	.buf_prepare = cif_stream_prepare_buffer,
+	.buf_queue = cif_stream_queue_buffer,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.start_streaming = cif_stream_start_streaming,
+	.stop_streaming = cif_stream_stop_streaming,
+};
+
+static int cif_stream_try_format(struct file *file, void *fh,
+				 struct v4l2_format *f)
+{
+	struct cif_stream *stream = video_drvdata(file);
+	const struct cif_output_fmt *fmt;
+	struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+	struct v4l2_subdev *sd = stream->remote->sd;
+	struct v4l2_subdev_format sd_fmt = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+	};
+	u32 height, width;
+	int ret;
+
+	fmt = cif_stream_find_output_fmt(stream, pix->pixelformat);
+	if (!fmt)
+		fmt = &stream->out_fmts[0];
+
+	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
+	if (ret < 0)
+		return ret;
+
+	height = clamp_t(u32, sd_fmt.format.height, CIF_MIN_HEIGHT,
+			 CIF_MAX_HEIGHT);
+	width = clamp_t(u32, sd_fmt.format.width, CIF_MIN_WIDTH, CIF_MAX_WIDTH);
+
+	pix->field = sd_fmt.format.field;
+	pix->colorspace = sd_fmt.format.colorspace;
+	pix->ycbcr_enc = sd_fmt.format.ycbcr_enc;
+	pix->quantization = sd_fmt.format.quantization;
+	pix->xfer_func = sd_fmt.format.xfer_func;
+
+	v4l2_fill_pixfmt_mp(pix, fmt->fourcc, width, height);
+
+	return 0;
+}
+
+static int cif_stream_set_format(struct file *file, void *priv,
+				 struct v4l2_format *f)
+{
+	struct cif_stream *stream = video_drvdata(file);
+	int ret;
+
+	if (vb2_is_busy(&stream->buf_queue))
+		return -EBUSY;
+
+	ret = cif_stream_try_format(file, priv, f);
+	if (ret)
+		return ret;
+
+	stream->pix = f->fmt.pix_mp;
+	stream->active_out_fmt =
+		cif_stream_find_output_fmt(stream, f->fmt.pix_mp.pixelformat);
+
+	return 0;
+}
+
+static int cif_stream_get_format(struct file *file, void *fh,
+				 struct v4l2_format *f)
+{
+	struct cif_stream *stream = video_drvdata(file);
+
+	f->fmt.pix_mp = stream->pix;
+
+	return 0;
+}
+
+static int cif_stream_enum_formats(struct file *file, void *priv,
+				   struct v4l2_fmtdesc *f)
+{
+	struct cif_stream *stream = video_drvdata(file);
+
+	if (f->index >= stream->out_fmts_num)
+		return -EINVAL;
+
+	f->pixelformat = stream->out_fmts[f->index].fourcc;
+
+	return 0;
+}
+
+static int cif_stream_enum_framesizes(struct file *file, void *fh,
+				      struct v4l2_frmsizeenum *fsize)
+{
+	struct cif_stream *stream = video_drvdata(file);
+	struct v4l2_subdev_frame_size_enum fse = {
+		.index = fsize->index,
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+	};
+	struct v4l2_subdev *sd = stream->remote->sd;
+	const struct cif_output_fmt *fmt;
+	int ret;
+
+	fmt = cif_stream_find_output_fmt(stream, fsize->pixel_format);
+	if (!fmt)
+		return -EINVAL;
+
+	fse.code = fmt->mbus_code;
+
+	ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse);
+	if (ret)
+		return ret;
+
+	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+	fsize->discrete.width = fse.max_width;
+	fsize->discrete.height = fse.max_height;
+
+	/* some variants may have a scaler in the path. */
+	/* TODO: add support for them */
+
+	return 0;
+}
+
+static int cif_stream_enum_frameintervals(struct file *file, void *fh,
+					  struct v4l2_frmivalenum *fival)
+{
+	struct cif_stream *stream = video_drvdata(file);
+	struct v4l2_subdev *sd = stream->remote->sd;
+	struct v4l2_subdev_frame_interval_enum fie = {
+		.index = fival->index,
+		.width = fival->width,
+		.height = fival->height,
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+	};
+	const struct cif_output_fmt *fmt;
+	int ret;
+
+	fmt = cif_stream_find_output_fmt(stream, fival->pixel_format);
+	if (!fmt)
+		return -EINVAL;
+
+	fie.code = fmt->mbus_code;
+
+	ret = v4l2_subdev_call(sd, pad, enum_frame_interval, NULL, &fie);
+	if (ret)
+		return ret;
+
+	fival->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+	fival->discrete = fie.interval;
+
+	return 0;
+}
+
+static int cif_stream_querycap(struct file *file, void *priv,
+			       struct v4l2_capability *cap)
+{
+	struct cif_stream *stream = video_drvdata(file);
+	struct device *dev = stream->cif_dev->dev;
+
+	strscpy(cap->driver, dev->driver->name, sizeof(cap->driver));
+	strscpy(cap->card, dev->driver->name, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+		 dev_name(dev));
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops cif_stream_ioctl_ops = {
+	.vidioc_reqbufs = vb2_ioctl_reqbufs,
+	.vidioc_querybuf = vb2_ioctl_querybuf,
+	.vidioc_create_bufs = vb2_ioctl_create_bufs,
+	.vidioc_qbuf = vb2_ioctl_qbuf,
+	.vidioc_expbuf = vb2_ioctl_expbuf,
+	.vidioc_dqbuf = vb2_ioctl_dqbuf,
+	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+	.vidioc_streamon = vb2_ioctl_streamon,
+	.vidioc_streamoff = vb2_ioctl_streamoff,
+	.vidioc_try_fmt_vid_cap_mplane = cif_stream_try_format,
+	.vidioc_s_fmt_vid_cap_mplane = cif_stream_set_format,
+	.vidioc_g_fmt_vid_cap_mplane = cif_stream_get_format,
+	.vidioc_enum_fmt_vid_cap = cif_stream_enum_formats,
+	.vidioc_enum_framesizes = cif_stream_enum_framesizes,
+	.vidioc_enum_frameintervals = cif_stream_enum_frameintervals,
+	.vidioc_querycap = cif_stream_querycap,
+	.vidioc_subscribe_event = v4l2_src_change_event_subscribe,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static int cif_stream_link_validate(struct media_link *link)
+{
+	struct video_device *vdev =
+		media_entity_to_video_device(link->sink->entity);
+	struct v4l2_subdev *sd =
+		media_entity_to_v4l2_subdev(link->source->entity);
+	struct cif_stream *stream = to_cif_stream(vdev);
+	struct v4l2_subdev_format sd_fmt = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad = 0,
+	};
+	const struct cif_input_fmt *cif_in_fmt = NULL;
+	unsigned int i;
+	int ret;
+
+	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
+	if (ret < 0)
+		goto err_out;
+
+	for (i = 0; i < stream->in_fmts_num; i++) {
+		if (sd_fmt.format.code == stream->in_fmts[i].mbus_code &&
+		    sd_fmt.format.field == stream->in_fmts[i].field) {
+			cif_in_fmt = &stream->in_fmts[i];
+			break;
+		}
+	}
+	if (!cif_in_fmt) {
+		dev_err(stream->cif_dev->dev,
+			"remote's mbus code not supported\n");
+		goto err_out;
+	}
+
+	if (sd_fmt.format.height != stream->pix.height ||
+	    sd_fmt.format.width != stream->pix.width) {
+		dev_err(stream->cif_dev->dev,
+			"link '%s':%u -> '%s':%u not valid: %ux%u != %ux%u\n",
+			link->source->entity->name, link->source->index,
+			link->sink->entity->name, link->sink->index,
+			sd_fmt.format.width, sd_fmt.format.height,
+			stream->pix.width, stream->pix.height);
+		goto err_out;
+	}
+
+	stream->active_in_fmt = cif_in_fmt;
+	return 0;
+
+err_out:
+	stream->active_in_fmt = NULL;
+	return -EPIPE;
+}
+
+static const struct media_entity_operations cif_stream_media_ops = {
+	.link_validate = cif_stream_link_validate,
+};
+
+static const struct v4l2_file_operations cif_stream_file_ops = {
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = vb2_fop_poll,
+	.mmap = vb2_fop_mmap,
+};
+
+static int cif_stream_init_vb2_queue(struct vb2_queue *q,
+				     struct cif_stream *stream)
+{
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	q->io_modes = VB2_MMAP | VB2_DMABUF;
+	q->drv_priv = stream;
+	q->ops = &cif_stream_vb2_ops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->buf_struct_size = sizeof(struct cif_buffer);
+	q->min_queued_buffers = CIF_REQ_BUFS_MIN;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &stream->vlock;
+	q->dev = stream->cif_dev->dev;
+
+	return vb2_queue_init(q);
+}
+
+int cif_stream_register(struct cif_device *cif_dev, struct cif_stream *stream,
+			const struct cif_stream_config *config)
+{
+	struct v4l2_device *v4l2_dev = &cif_dev->v4l2_dev;
+	struct video_device *vdev = &stream->vdev;
+	int ret;
+
+	stream->cif_dev = cif_dev;
+
+	INIT_LIST_HEAD(&stream->driver_queue);
+	spin_lock_init(&stream->driver_queue_lock);
+
+	init_waitqueue_head(&stream->wq_stopped);
+
+	mutex_init(&stream->vlock);
+
+	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING |
+			    V4L2_CAP_IO_MC;
+	vdev->entity.ops = &cif_stream_media_ops;
+	vdev->fops = &cif_stream_file_ops;
+	vdev->ioctl_ops = &cif_stream_ioctl_ops;
+	vdev->lock = &stream->vlock;
+	vdev->minor = -1;
+	vdev->release = video_device_release_empty;
+	vdev->v4l2_dev = v4l2_dev;
+	vdev->vfl_dir = VFL_DIR_RX;
+	video_set_drvdata(vdev, stream);
+
+	stream->pad.flags = MEDIA_PAD_FL_SINK;
+
+	cif_stream_init_vb2_queue(&stream->buf_queue, stream);
+
+	vdev->queue = &stream->buf_queue;
+	if (config->name)
+		strscpy(vdev->name, config->name, sizeof(vdev->name));
+
+	ret = media_entity_pads_init(&vdev->entity, 1, &stream->pad);
+	if (ret < 0) {
+		dev_err(cif_dev->dev, "failed to initialize media pads: %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	if (ret < 0) {
+		dev_err(cif_dev->dev, "failed to register video device: %d\n",
+			ret);
+		goto err_media_entity_cleanup;
+	}
+
+	v4l2_info(v4l2_dev, "registered %s as /dev/video%d\n", vdev->name,
+		  vdev->num);
+
+	return 0;
+
+err_media_entity_cleanup:
+	media_entity_cleanup(&stream->vdev.entity);
+	return ret;
+}
+
+void cif_stream_unregister(struct cif_stream *stream)
+{
+	video_unregister_device(&stream->vdev);
+	media_entity_cleanup(&stream->vdev.entity);
+}
diff --git a/drivers/media/platform/rockchip/cif/cif-stream.h b/drivers/media/platform/rockchip/cif/cif-stream.h
new file mode 100644
index 000000000000..5bfa260eda83
--- /dev/null
+++ b/drivers/media/platform/rockchip/cif/cif-stream.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2024 Michael Riesch <michael.riesch at wolfvision.net>
+ */
+
+#ifndef _CIF_STREAM_H
+#define _CIF_STREAM_H
+
+#include "cif-common.h"
+
+struct cif_stream_config {
+	const char *name;
+};
+
+void cif_stream_pingpong(struct cif_stream *stream);
+
+int cif_stream_register(struct cif_device *cif_dev, struct cif_stream *stream,
+			const struct cif_stream_config *config);
+
+void cif_stream_unregister(struct cif_stream *stream);
+
+#endif

-- 
2.34.1



From michael.riesch at wolfvision.net  Tue Dec 17 07:55:17 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 17 Dec 2024 16:55:17 +0100
Subject: [PATCH v2 5/6] arm64: dts: rockchip: add the vip node to px30
In-Reply-To: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
References: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
Message-ID: <20241217-v6-8-topic-rk3568-vicap-v2-5-b1d488fcc0d3@wolfvision.net>

From: Mehdi Djait <mehdi.djait at bootlin.com>

Add the device tree node for the PX30 Video Input Processor (VIP).

Signed-off-by: Mehdi Djait <mehdi.djait at bootlin.com>
[added cosmetic changes]
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/px30.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index 9137dd76e72c..c2acf5952d08 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -1282,6 +1282,18 @@ isp_mmu: iommu at ff4a8000 {
 		#iommu-cells = <0>;
 	};
 
+	cif: video-capture at ff490000 {
+		compatible = "rockchip,px30-vip";
+		reg = <0x0 0xff490000 0x0 0x200>;
+		interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>;
+		clock-names = "aclk", "hclk", "pclk";
+		power-domains = <&power PX30_PD_VI>;
+		resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>;
+		reset-names = "axi", "ahb", "pclkin";
+		status = "disabled";
+	};
+
 	qos_gmac: qos at ff518000 {
 		compatible = "rockchip,px30-qos", "syscon";
 		reg = <0x0 0xff518000 0x0 0x20>;

-- 
2.34.1



From michael.riesch at wolfvision.net  Tue Dec 17 07:55:18 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 17 Dec 2024 16:55:18 +0100
Subject: [PATCH v2 6/6] arm64: dts: rockchip: add vicap node to rk356x
In-Reply-To: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
References: <20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3@wolfvision.net>
Message-ID: <20241217-v6-8-topic-rk3568-vicap-v2-6-b1d488fcc0d3@wolfvision.net>

Add the device tree node for the RK356x Video Capture (VICAP) unit.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 44 +++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
index 62be06f3b863..73ff1ff01e24 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -553,6 +553,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 0 {
+				reg = <0>;
+			};
+
+			vicap_mipi: port at 1 {
+				reg = <1>;
+			};
+		};
+	};
+
+	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.34.1



From maz at kernel.org  Tue Dec 17 07:55:57 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 15:55:57 +0000
Subject: [PATCH] KVM: arm64: Fix set_id_regs selftest for ASIDBITS becoming unwritable
In-Reply-To: <b13b14df-00ee-4bee-8f65-d2cb7a9bfa6b@sirena.org.uk>
References: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
	<875xnisocy.wl-maz@kernel.org>
	<53b40aa8-f51c-4c4e-a4ad-e6a9512e5197@sirena.org.uk>
	<86v7viqusg.wl-maz@kernel.org>
	<b13b14df-00ee-4bee-8f65-d2cb7a9bfa6b@sirena.org.uk>
Message-ID: <86o71aqp6a.wl-maz@kernel.org>

On Tue, 17 Dec 2024 15:10:28 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> [1  <text/plain; us-ascii (7bit)>]
> On Tue, Dec 17, 2024 at 01:54:39PM +0000, Marc Zyngier wrote:
> > Mark Brown <broonie at kernel.org> wrote:
> 
> > > The selftests are shipped as part of the kernel source and frequently
> > > used for testing the kernel, it's all one source base and we want to
> > > ensure that for example the test fix gets backported if the relevant
> > > kernel patch does.
> 
> > That's not what Fixes: describes. If you want to invent a new tag that
> > expresses a dependency, do that. Don't use these tags to misrepresent
> > what the patches does.
> 
> No, this isn't a new use - a Fixes: tag indicates that the referenced
> commit introduced the problem being fixed and that is exactly what's
> going on here.  Like I say the selftests are not a completely separate
> project, they are a part of the same source release as the rest of the
> kernel and it is helpful to track information like this.

Well, we'll have to agree to disagree.

	M.

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


From christian.bruel at foss.st.com  Tue Dec 17 07:53:48 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Tue, 17 Dec 2024 16:53:48 +0100
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <20241205172022.GA3053765@bhelgaas>
References: <20241205172022.GA3053765@bhelgaas>
Message-ID: <d976d74c-80c0-4446-bb9b-960a990c552b@foss.st.com>


> Makes sense.  What about phys, resets, etc?  I'm pretty sure a PHY
> would be a per-Root Port thing, and some resets and wakeup signals
> also.
> 
> For new drivers, I think we should start adding Root Port stanzas to
> specifically associate those things with the Root Port, e.g.,
> something like this?
> 
>    pcie at 48400000 {
>      compatible = "st,stm32mp25-pcie-rc";
> 
>      pcie at 0,0 {
>        reg = <0x0000 0 0 0 0>;
>        phys = <&combophy PHY_TYPE_PCIE>;
>        phy-names = "pcie-phy";
>      };
>    };
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pci/mediatek,mt7621-pcie.yaml?id=v6.12#n111
> is one binding that does this, others include apple,pcie.yaml,
> brcm,stb-pcie.yaml, hisilicon,kirin-pcie.yaml.
> 

On a second thought, moving the PHY to the root-port part would 
introduce a discrepancy with the pcie_ep binding, whereas the PHY is 
required on the pcie_ep node.

Even for the pcie_rc, the PHY is needed to enable the core_clk to access
the PCIe core registers,

So that would make 2 different required PHY locations for RC and EP:

     pcie_rc: pcie at 48400000 {
       compatible = "st,stm32mp25-pcie-rc";

       pcie at 0,0 {
         reg = <0x0000 0 0 0 0>;
         phys = <&combophy PHY_TYPE_PCIE>;
         phy-names = "pcie-phy";
       };
     };

     pcie_ep pcie at 48400000 {
       compatible = "st,stm32mp25-pcie-ep";
       phys = <&combophy PHY_TYPE_PCIE>;
       phy-names = "pcie-phy";
     };

Simplest seems to keep the PHY required for the pcie core regardless of 
the mode and keep the empty root port to split the design

     pcie_rc: pcie at 48400000 {
       compatible = "st,stm32mp25-pcie-rc";
       phys = <&combophy PHY_TYPE_PCIE>;
       phy-names = "pcie-phy";

         pcie at 0,0 {
         reg = <0x0000 0 0 0 0>;
       };
     };

     pcie_ep: pcie at 48400000 {
       compatible = "st,stm32mp25-pcie-ep";
       phys = <&combophy PHY_TYPE_PCIE>;
       phy-names = "pcie-phy";
     };

But I have no experience with multiple root-port systems, I'm open for 
the best :)

Thanks

Christian


From bryan.odonoghue at linaro.org  Tue Dec 17 08:12:34 2024
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Tue, 17 Dec 2024 16:12:34 +0000
Subject: [PATCH v10 1/4] media: dt-bindings: update clocks for
 sc7280-camss
In-Reply-To: <02da691b-1f5d-41a6-847c-c7e9b8239919@kernel.org>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-2-quic_vikramsa@quicinc.com>
 <02da691b-1f5d-41a6-847c-c7e9b8239919@kernel.org>
Message-ID: <c14493b0-c9d3-4e1c-9f86-991b4cb25c98@linaro.org>

On 17/12/2024 14:10, Krzysztof Kozlowski wrote:
> On 17/12/2024 15:06, Vikram Sharma wrote:
>> This patch change clock names to make it consistent with
>> existing platforms as gcc_cam_hf_axi -> gcc_axi_hf.
>> This also adds gcc_axi_sf and remove gcc_camera_ahb.
> 
> Don't combine ABI changes with some less important things.
> 
> You miss here explanation why doing the ABI change in the first place.
> Without that explanation I find it rather churn. But anyway, reason for
> ABI break and impact should be documented in commit msg.
> 
>>
>> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
>> ---
> 
> Best regards,
> Krzysztof

This change should be fine since we haven't committed and upstream dtsi, 
so there's no ABI to break yet.

Agree the cover letter should have been explicit in explaining.

---
bod


From wahrenst at gmx.net  Tue Dec 17 08:29:29 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Tue, 17 Dec 2024 17:29:29 +0100
Subject: [PATCH V7] dmaengine: bcm2835-dma: Prevent suspend if DMA channel
 is busy
In-Reply-To: <20241204165546.77941-1-wahrenst@gmx.net>
References: <20241204165546.77941-1-wahrenst@gmx.net>
Message-ID: <da2113a5-301b-4421-a651-9922d4ffb0de@gmx.net>

Am 04.12.24 um 17:55 schrieb Stefan Wahren:
> bcm2835-dma provides the service to others, so it should suspend
> late and resume early. Suspend should be prevented in case a DMA
> channel is still busy.
>
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
gentle ping ...
> ---
>   drivers/dma/bcm2835-dma.c | 22 ++++++++++++++++++++++
>   1 file changed, 22 insertions(+)
>
> Changes in V7:
> - improve patch title and changelog
> - add explaining comment and drop warning in suspend
> - drop empty resume callback
>
> Changes in V6:
> - split out of series because there is no dependency
>
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index 7ba52dee40a9..20b10c15c696 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -875,6 +875,27 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
>   	return chan;
>   }
>
> +static int bcm2835_dma_suspend_late(struct device *dev)
> +{
> +	struct bcm2835_dmadev *od = dev_get_drvdata(dev);
> +	struct bcm2835_chan *c, *next;
> +
> +	list_for_each_entry_safe(c, next, &od->ddev.channels,
> +				 vc.chan.device_node) {
> +		void __iomem *chan_base = c->chan_base;
> +
> +		/* Check if DMA channel is busy */
> +		if (readl(chan_base + BCM2835_DMA_ADDR))
> +			return -EBUSY;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops bcm2835_dma_pm_ops = {
> +	SET_LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late, NULL)
> +};
> +
>   static int bcm2835_dma_probe(struct platform_device *pdev)
>   {
>   	struct bcm2835_dmadev *od;
> @@ -1033,6 +1054,7 @@ static struct platform_driver bcm2835_dma_driver = {
>   	.driver = {
>   		.name = "bcm2835-dma",
>   		.of_match_table = of_match_ptr(bcm2835_dma_of_match),
> +		.pm = pm_ptr(&bcm2835_dma_pm_ops),
>   	},
>   };
>
> --
> 2.34.1
>



From bryan.odonoghue at linaro.org  Tue Dec 17 08:30:37 2024
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Tue, 17 Dec 2024 16:30:37 +0000
Subject: [PATCH v10 1/4] media: dt-bindings: update clocks for
 sc7280-camss
In-Reply-To: <fe28a9bc-82ef-4fef-af50-9d9261ed9b39@kernel.org>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-2-quic_vikramsa@quicinc.com>
 <02da691b-1f5d-41a6-847c-c7e9b8239919@kernel.org>
 <c14493b0-c9d3-4e1c-9f86-991b4cb25c98@linaro.org>
 <fe28a9bc-82ef-4fef-af50-9d9261ed9b39@kernel.org>
Message-ID: <a1032d53-6f3e-48f6-a2e9-1315bb1a3232@linaro.org>

On 17/12/2024 16:23, Krzysztof Kozlowski wrote:
> On 17/12/2024 17:12, Bryan O'Donoghue wrote:
>> On 17/12/2024 14:10, Krzysztof Kozlowski wrote:
>>> On 17/12/2024 15:06, Vikram Sharma wrote:
>>>> This patch change clock names to make it consistent with
>>>> existing platforms as gcc_cam_hf_axi -> gcc_axi_hf.
>>>> This also adds gcc_axi_sf and remove gcc_camera_ahb.
>>>
>>> Don't combine ABI changes with some less important things.
>>>
>>> You miss here explanation why doing the ABI change in the first place.
>>> Without that explanation I find it rather churn. But anyway, reason for
>>> ABI break and impact should be documented in commit msg.
>>>
>>>>
>>>> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
>>>> ---
>>>
>>> Best regards,
>>> Krzysztof
>>
>> This change should be fine since we haven't committed and upstream dtsi,
>> so there's no ABI to break yet.
>>
>> Agree the cover letter should have been explicit in explaining.
> 
> So these are recently added bindings (sc7280 is not particularly new)?
> If so mention in the commit msg that no users are affected because of this.
> 
> Best regards,
> Krzysztof

Agreed.

The commit log should make clear that the ABI hasn't been cemented yet.

20241217140656.965235-4-quic_vikramsa at quicinc.com <- is still pending

---
bod


From horms at kernel.org  Tue Dec 17 08:35:38 2024
From: horms at kernel.org (Simon Horman)
Date: Tue, 17 Dec 2024 16:35:38 +0000
Subject: [PATCH net v1] net: stmmac: Drop useless code related to ethtool
 rx-copybreak
In-Reply-To: <20241217091712.383911-1-0x1207@gmail.com>
References: <20241217091712.383911-1-0x1207@gmail.com>
Message-ID: <20241217163538.GU780307@kernel.org>

On Tue, Dec 17, 2024 at 05:17:12PM +0800, Furong Xu wrote:
> After commit 2af6106ae949 ("net: stmmac: Introducing support for Page
> Pool"), these code turned to be useless and users of ethtool may get
> confused about the unhandled rx-copybreak parameter.

Hi Furong Xu,

I think it would be useful to explain why the change cited above
renders the copybreak implementation unnecessary.

> 
> This patch mostly reverts
> commit 22ad38381547 ("stmmac: do not perform zero-copy for rx frames")
> 
> Fixes: 2af6106ae949 ("net: stmmac: Introducing support for Page Pool")

Based on your description this feels more like an enhancement
for net-next, without a Fixes tag, than a fix for net.

> Signed-off-by: Furong Xu <0x1207 at gmail.com>

...


From cristian.ciocaltea at collabora.com  Tue Dec 17 08:36:41 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 17 Dec 2024 18:36:41 +0200
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes handling
 on RK3588 HDMI0
In-Reply-To: <20241217-ubiquitous-refreshing-finch-aceade@houat>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
 <1820767.5KxKD5qtyk@diego>
 <a4ex3s23r4k6wehyoaw3aylpcexfrclrxxykjpabhdfne2jgmu@ii6riiiga2zj>
 <1756448.izSxrag8PF@diego>
 <20241217-ubiquitous-refreshing-finch-aceade@houat>
Message-ID: <c45ff74a-c9a4-4cf1-8530-04087e06b07a@collabora.com>

On 12/17/24 5:00 PM, Maxime Ripard wrote:
> On Wed, Dec 11, 2024 at 07:01:15PM +0100, Heiko St?bner wrote:
>> Am Mittwoch, 11. Dezember 2024, 18:47:44 CET schrieb Maxime Ripard:
>>> On Wed, Dec 11, 2024 at 06:23:03PM +0100, Heiko St?bner wrote:
>>>> Am Mittwoch, 11. Dezember 2024, 18:07:57 CET schrieb Maxime Ripard:
>>>>> On Wed, Dec 11, 2024 at 12:15:07PM +0200, Cristian Ciocaltea wrote:
>>>>>> The RK3588 specific implementation is currently quite limited in terms
>>>>>> of handling the full range of display modes supported by the connected
>>>>>> screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
>>>>>> few of them.
>>>>>>
>>>>>> Additionally, it doesn't cope well with non-integer refresh rates like
>>>>>> 59.94, 29.97, 23.98, etc.
>>>>>>
>>>>>> Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
>>>>>> all display modes up to 4K at 60Hz.
>>>>>>
>>>>>> Tested-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
>>>>>> ---
>>>>>>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
>>>>>>  1 file changed, 34 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>>>>>> index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
>>>>>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>>>>>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>>>>>> @@ -158,6 +158,7 @@ struct vop2_video_port {
>>>>>>  	struct drm_crtc crtc;
>>>>>>  	struct vop2 *vop2;
>>>>>>  	struct clk *dclk;
>>>>>> +	struct clk *dclk_src;
>>>>>>  	unsigned int id;
>>>>>>  	const struct vop2_video_port_data *data;
>>>>>>  
>>>>>> @@ -212,6 +213,7 @@ struct vop2 {
>>>>>>  	struct clk *hclk;
>>>>>>  	struct clk *aclk;
>>>>>>  	struct clk *pclk;
>>>>>> +	struct clk *pll_hdmiphy0;
>>>>>>  
>>>>>>  	/* optional internal rgb encoder */
>>>>>>  	struct rockchip_rgb *rgb;
>>>>>> @@ -220,6 +222,8 @@ struct vop2 {
>>>>>>  	struct vop2_win win[];
>>>>>>  };
>>>>>>  
>>>>>> +#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
>>>>>> +
>>>>>>  #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
>>>>>>  					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
>>>>>>  
>>>>>> @@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
>>>>>>  
>>>>>>  	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
>>>>>>  
>>>>>> +	if (vp->dclk_src)
>>>>>> +		clk_set_parent(vp->dclk, vp->dclk_src);
>>>>>> +
>>>>>>  	clk_disable_unprepare(vp->dclk);
>>>>>>  
>>>>>>  	vop2->enable_count--;
>>>>>> @@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
>>>>>>  
>>>>>>  	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
>>>>>>  
>>>>>> +	/*
>>>>>> +	 * Switch to HDMI PHY PLL as DCLK source for display modes up
>>>>>> +	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
>>>>>> +	 */
>>>>>> +	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
>>>>>> +		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
>>>>>> +			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
>>>>>> +
>>>>>> +			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
>>>>>> +				if (!vp->dclk_src)
>>>>>> +					vp->dclk_src = clk_get_parent(vp->dclk);
>>>>>> +
>>>>>> +				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
>>>>>> +				if (ret < 0)
>>>>>> +					drm_warn(vop2->drm,
>>>>>> +						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
>>>>>> +				break;
>>>>>> +			}
>>>>>> +		}
>>>>>> +	}
>>>>>> +
>>>>>
>>>>> It seems pretty fragile to do it at atomic_enable time, even more so
>>>>> since you don't lock the parent either.
>>>>>
>>>>> Any reason not to do it in the DRM or clock driver probe, and make sure
>>>>> you never change the parent somehow?
>>>>
>>>> On rk3588 we have 3 dclk_s and 2 hdmi controllers. Each video-port can
>>>> use the clock generated from either the hdmi0phy or hdmi1phy, depending
>>>> on which hdmi-controller it uses.
>>>>
>>>> So you actually need to know which vpX will output to which hdmiY to then
>>>> reparent that dclk to the hdmiphy output.
>>>
>>> The Rockchip nomenclature isn't super obvious to me, sorry. Is there a
>>> datasheet for this somewhere? Also, does this vpX -> HDMI-Y mapping need
>>> to be dynamic?
>>
>> VPs are CRTCs in drm-language and each of them can drive a differing
>> number of output encoders. Those video-ports also have differing output
>> characteristics in terms of supported resolution and other properties.
>>
>> The rk3588 TRM has leaked in a number of places, and if you find a
>> TRM-part2, there is a section labeled "Display Output Interface Description"
>> that has a nice graphic for that.
>>
>> Or in short:
>> - CRTC(VP)0 supports 8K resolution and can drive DP0+1, HDMI0+1, eDP0+1
>>   [if I'm reading things correctly, 8K together with CRTC1 somehow)
>> - CRTC(VP)1 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP0+1
>> - CRTC(VP)2 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP01, DSI0+1
>> - CRTC(VP)3 supports 2K resolution and can drive DSI0+1 and some BT1120,BT656
>>
>> so for the 3 higher resolution CRTCs there are essentially 6 or 8 output options
>> depending on the board design
> 
> That's much clearer, thanks. I'm not entirely sure how that links to the
> need for the PLL to change its parent depending on the ouput. Do you
> need to always have all the outputs on the same PLL?

One of the problems is that the PHY PLLs cannot be used as clock sources
for resolutions above 4K at 60Hz, while VOP2 on RK3588 supports up to 8K at 60Hz,
which is supposed to be handled by the system CRU.

Moreover, the 2 PLLs are shared between 3 out of the 4 video ports already
mentioned by Heiko.  There is quite a bit of complexity in downstream
driver to handle all possible usecases - see [1] for a brief description on
how was that designed to work.

Regards,
Cristian

[1] https://github.com/radxa/kernel/blob/linux-6.1-stan-rkr4.1/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c#L4742


From Frank.li at nxp.com  Tue Dec 17 08:02:24 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 17 Dec 2024 11:02:24 -0500
Subject: [PATCH v2 2/2] nvmem: imx-ocotp-ele: Support accessing
 controller for i.MX9
In-Reply-To: <20241217-imx-ocotp-v2-2-3faa6cbff41b@nxp.com>
References: <20241217-imx-ocotp-v2-0-3faa6cbff41b@nxp.com>
 <20241217-imx-ocotp-v2-2-3faa6cbff41b@nxp.com>
Message-ID: <Z2GgkELx2EdF8fKl@lizhi-Precision-Tower-5810>

On Tue, Dec 17, 2024 at 04:43:37PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
>
> i.MX9 OCOTP supports a specific peripheral or function being fused
> which means disabled, so
>  - Introduce ocotp_access_gates to be container of efuse gate info
>  - Iterate each node under '/soc' to check accessing permission. If not
>    allowed to be accessed, detach the node
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/nvmem/imx-ocotp-ele.c | 184 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 183 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
> index ca6dd71d8a2e29888c6e556aaea116c1a967cb5f..2c7b698ae4da0ec22eeeabf4ed35d1b703771f6c 100644
> --- a/drivers/nvmem/imx-ocotp-ele.c
> +++ b/drivers/nvmem/imx-ocotp-ele.c
> @@ -5,6 +5,8 @@
>   * Copyright 2023 NXP
>   */
>
> +#include <dt-bindings/nvmem/fsl,imx93-ocotp.h>
> +#include <dt-bindings/nvmem/fsl,imx95-ocotp.h>
>  #include <linux/device.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
> @@ -27,6 +29,7 @@ struct ocotp_map_entry {
>  };
>
>  struct ocotp_devtype_data {
> +	const struct ocotp_access_gates *access_gates;
>  	u32 reg_off;
>  	char *name;
>  	u32 size;
> @@ -36,11 +39,26 @@ struct ocotp_devtype_data {
>  	struct ocotp_map_entry entry[];
>  };
>
> +#define OCOTP_MAX_NUM_GATE_WORDS 4
> +#define IMX93_OCOTP_NUM_GATES 17
> +#define IMX95_OCOTP_NUM_GATES 36
> +
> +struct ocotp_access_gates {
> +	u32 num_words;
> +	u32 words[OCOTP_MAX_NUM_GATE_WORDS];
> +	u32 num_gates;
> +	struct access_gate {
> +		u32 word;
> +		u32 mask;
> +	} gates[];
> +};
> +
>  struct imx_ocotp_priv {
>  	struct device *dev;
>  	void __iomem *base;
>  	struct nvmem_config config;
>  	struct mutex lock;
> +	u32 value[OCOTP_MAX_NUM_GATE_WORDS];
>  	const struct ocotp_devtype_data *data;
>  };
>
> @@ -131,6 +149,97 @@ static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
>  	cell->read_post_process = imx_ocotp_cell_pp;
>  }
>
> +static int imx_ele_ocotp_check_access(struct platform_device *pdev, u32 id)
> +{
> +	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
> +	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
> +	u32 word, mask;
> +
> +	if (id >= access_gates->num_gates) {
> +		dev_err(&pdev->dev, "Index %d too large\n", id);
> +		return -EACCES;
> +	}
> +
> +	word = access_gates->gates[id].word;
> +	mask = access_gates->gates[id].mask;
> +
> +	dev_dbg(&pdev->dev, "id:%d word:%d mask:0x%08x\n", id, word, mask);
> +	/* true means not allow access */
> +	if (priv->value[word] & mask)
> +		return -EACCES;
> +
> +	return 0;
> +}
> +
> +static int imx_ele_ocotp_grant_access(struct platform_device *pdev, struct device_node *parent)
> +{
> +	struct device_node *child;
> +	struct device *dev = &pdev->dev;

move 'dev' before child.

> +
> +	for_each_available_child_of_node(parent, child) {

for_each_child_of_node_scoped() ?

I am not sure if you need of_node_put for child node.

Frank

> +		struct of_phandle_iterator it;
> +		int err;
> +		u32 id;
> +
> +		of_for_each_phandle(&it, err, child, "access-controllers",
> +				    "#access-controller-cells", 0) {
> +			struct of_phandle_args provider_args;
> +			struct device_node *provider = it.node;
> +
> +			if (err) {
> +				dev_err(dev, "Unable to get access-controllers property for node %s\n, err: %d",
> +					child->full_name, err);
> +				of_node_put(provider);
> +				return err;
> +			}
> +
> +			/* Only support one cell */
> +			if (of_phandle_iterator_args(&it, provider_args.args, 1) != 1) {
> +				dev_err(dev, "wrong args count\n");
> +				return -EINVAL;
> +			}
> +
> +			id = provider_args.args[0];
> +
> +			dev_dbg(dev, "Checking node: %s gate: %d\n", child->full_name, id);
> +
> +			if (imx_ele_ocotp_check_access(pdev, id)) {
> +				of_detach_node(child);
> +				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
> +					child->full_name);
> +			}
> +		}
> +
> +		imx_ele_ocotp_grant_access(pdev, child);
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx_ele_ocotp_access_control(struct platform_device *pdev)
> +{
> +	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
> +	struct device_node *root __free(device_node) = of_find_node_by_path("/");
> +	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
> +	void __iomem *reg = priv->base + priv->data->reg_off;
> +	u32 off;
> +	int i;
> +
> +	if (!priv->data->access_gates)
> +		return 0;
> +
> +	/* This should never happen */
> +	WARN_ON(!root);
> +
> +	for (i = 0; i < access_gates->num_words; i++) {
> +		off = access_gates->words[i] << 2;
> +		priv->value[i] = readl(reg + off);
> +		dev_dbg(&pdev->dev, "word:%d 0x%08x\n", access_gates->words[i], priv->value[i]);
> +	}
> +
> +	return imx_ele_ocotp_grant_access(pdev, root);
> +}
> +
>  static int imx_ele_ocotp_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -161,14 +270,43 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
>  	priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
>  	mutex_init(&priv->lock);
>
> +	platform_set_drvdata(pdev, priv);
> +
>  	nvmem = devm_nvmem_register(dev, &priv->config);
>  	if (IS_ERR(nvmem))
>  		return PTR_ERR(nvmem);
>
> -	return 0;
> +
> +	return imx_ele_ocotp_access_control(pdev);
>  }
>
> +static const struct ocotp_access_gates imx93_access_gates = {
> +	.num_words = 3,
> +	.words = {19, 20, 21},
> +	.num_gates = IMX93_OCOTP_NUM_GATES,
> +	.gates = {
> +		[IMX93_OCOTP_NPU_GATE]		= { .word = 19, .mask = BIT(13) },
> +		[IMX93_OCOTP_A550_GATE]		= { .word = 19, .mask = BIT(14) },
> +		[IMX93_OCOTP_A551_GATE]		= { .word = 19, .mask = BIT(15) },
> +		[IMX93_OCOTP_M33_GATE]		= { .word = 19, .mask = BIT(24) },
> +		[IMX93_OCOTP_CAN1_FD_GATE]	= { .word = 19, .mask = BIT(28) },
> +		[IMX93_OCOTP_CAN2_FD_GATE]	= { .word = 19, .mask = BIT(29) },
> +		[IMX93_OCOTP_CAN1_GATE]		= { .word = 19, .mask = BIT(30) },
> +		[IMX93_OCOTP_CAN2_GATE]		= { .word = 19, .mask = BIT(31) },
> +		[IMX93_OCOTP_USB1_GATE]		= { .word = 20, .mask = BIT(3) },
> +		[IMX93_OCOTP_USB2_GATE]		= { .word = 20, .mask = BIT(4) },
> +		[IMX93_OCOTP_ENET1_GATE]	= { .word = 20, .mask = BIT(5) },
> +		[IMX93_OCOTP_ENET2_GATE]	= { .word = 20, .mask = BIT(6) },
> +		[IMX93_OCOTP_PXP_GATE]		= { .word = 20, .mask = BIT(10) },
> +		[IMX93_OCOTP_MIPI_CSI1_GATE]	= { .word = 20, .mask = BIT(17) },
> +		[IMX93_OCOTP_MIPI_DSI1_GATE]	= { .word = 20, .mask = BIT(19) },
> +		[IMX93_OCOTP_LVDS1_GATE]	= { .word = 20, .mask = BIT(24) },
> +		[IMX93_OCOTP_ADC1_GATE]		= { .word = 21, .mask = BIT(7) },
> +	},
> +};
> +
>  static const struct ocotp_devtype_data imx93_ocotp_data = {
> +	.access_gates = &imx93_access_gates,
>  	.reg_off = 0x8000,
>  	.reg_read = imx_ocotp_reg_read,
>  	.size = 2048,
> @@ -183,7 +321,51 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
>  	},
>  };
>
> +static const struct ocotp_access_gates imx95_access_gates = {
> +	.num_words = 3,
> +	.words = {17, 18, 19},
> +	.num_gates = IMX95_OCOTP_NUM_GATES,
> +	.gates = {
> +		[IMX95_OCOTP_CANFD1_GATE]	= { .word = 17, .mask = BIT(20) },
> +		[IMX95_OCOTP_CANFD2_GATE]	= { .word = 17, .mask = BIT(21) },
> +		[IMX95_OCOTP_CANFD3_GATE]	= { .word = 17, .mask = BIT(22) },
> +		[IMX95_OCOTP_CANFD4_GATE]	= { .word = 17, .mask = BIT(23) },
> +		[IMX95_OCOTP_CANFD5_GATE]	= { .word = 17, .mask = BIT(24) },
> +		[IMX95_OCOTP_CAN1_GATE]	= { .word = 17, .mask = BIT(25) },
> +		[IMX95_OCOTP_CAN2_GATE]	= { .word = 17, .mask = BIT(26) },
> +		[IMX95_OCOTP_CAN3_GATE]	= { .word = 17, .mask = BIT(27) },
> +		[IMX95_OCOTP_CAN4_GATE]	= { .word = 17, .mask = BIT(28) },
> +		[IMX95_OCOTP_CAN5_GATE]	= { .word = 17, .mask = BIT(29) },
> +		[IMX95_OCOTP_NPU_GATE]		= { .word = 18, .mask = BIT(0) },
> +		[IMX95_OCOTP_A550_GATE]	= { .word = 18, .mask = BIT(1) },
> +		[IMX95_OCOTP_A551_GATE]	= { .word = 18, .mask = BIT(2) },
> +		[IMX95_OCOTP_A552_GATE]	= { .word = 18, .mask = BIT(3) },
> +		[IMX95_OCOTP_A553_GATE]	= { .word = 18, .mask = BIT(4) },
> +		[IMX95_OCOTP_A554_GATE]	= { .word = 18, .mask = BIT(5) },
> +		[IMX95_OCOTP_A555_GATE]	= { .word = 18, .mask = BIT(6) },
> +		[IMX95_OCOTP_M7_GATE]		= { .word = 18, .mask = BIT(9) },
> +		[IMX95_OCOTP_DCSS_GATE]	= { .word = 18, .mask = BIT(22) },
> +		[IMX95_OCOTP_LVDS1_GATE]	= { .word = 18, .mask = BIT(27) },
> +		[IMX95_OCOTP_ISP_GATE]		= { .word = 18, .mask = BIT(29) },
> +		[IMX95_OCOTP_USB1_GATE]	= { .word = 19, .mask = BIT(2) },
> +		[IMX95_OCOTP_USB2_GATE]	= { .word = 19, .mask = BIT(3) },
> +		[IMX95_OCOTP_NETC_GATE]	= { .word = 19, .mask = BIT(4) },
> +		[IMX95_OCOTP_PCIE1_GATE]	= { .word = 19, .mask = BIT(6) },
> +		[IMX95_OCOTP_PCIE2_GATE]	= { .word = 19, .mask = BIT(7) },
> +		[IMX95_OCOTP_ADC1_GATE]	= { .word = 19, .mask = BIT(8) },
> +		[IMX95_OCOTP_EARC_RX_GATE]	= { .word = 19, .mask = BIT(11) },
> +		[IMX95_OCOTP_GPU3D_GATE]	= { .word = 19, .mask = BIT(16) },
> +		[IMX95_OCOTP_VPU_GATE]		= { .word = 19, .mask = BIT(17) },
> +		[IMX95_OCOTP_JPEG_ENC_GATE]	= { .word = 19, .mask = BIT(18) },
> +		[IMX95_OCOTP_JPEG_DEC_GATE]	= { .word = 19, .mask = BIT(19) },
> +		[IMX95_OCOTP_MIPI_CSI1_GATE]	= { .word = 19, .mask = BIT(21) },
> +		[IMX95_OCOTP_MIPI_CSI2_GATE]	= { .word = 19, .mask = BIT(22) },
> +		[IMX95_OCOTP_MIPI_DSI1_GATE]	= { .word = 19, .mask = BIT(23) },
> +	}
> +};
> +
>  static const struct ocotp_devtype_data imx95_ocotp_data = {
> +	.access_gates = &imx95_access_gates,
>  	.reg_off = 0x8000,
>  	.reg_read = imx_ocotp_reg_read,
>  	.size = 2048,
>
> --
> 2.37.1
>


From krzk at kernel.org  Tue Dec 17 08:23:36 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 17 Dec 2024 17:23:36 +0100
Subject: [PATCH v10 1/4] media: dt-bindings: update clocks for
 sc7280-camss
In-Reply-To: <c14493b0-c9d3-4e1c-9f86-991b4cb25c98@linaro.org>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-2-quic_vikramsa@quicinc.com>
 <02da691b-1f5d-41a6-847c-c7e9b8239919@kernel.org>
 <c14493b0-c9d3-4e1c-9f86-991b4cb25c98@linaro.org>
Message-ID: <fe28a9bc-82ef-4fef-af50-9d9261ed9b39@kernel.org>

On 17/12/2024 17:12, Bryan O'Donoghue wrote:
> On 17/12/2024 14:10, Krzysztof Kozlowski wrote:
>> On 17/12/2024 15:06, Vikram Sharma wrote:
>>> This patch change clock names to make it consistent with
>>> existing platforms as gcc_cam_hf_axi -> gcc_axi_hf.
>>> This also adds gcc_axi_sf and remove gcc_camera_ahb.
>>
>> Don't combine ABI changes with some less important things.
>>
>> You miss here explanation why doing the ABI change in the first place.
>> Without that explanation I find it rather churn. But anyway, reason for
>> ABI break and impact should be documented in commit msg.
>>
>>>
>>> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
>>> ---
>>
>> Best regards,
>> Krzysztof
> 
> This change should be fine since we haven't committed and upstream dtsi, 
> so there's no ABI to break yet.
> 
> Agree the cover letter should have been explicit in explaining.

So these are recently added bindings (sc7280 is not particularly new)?
If so mention in the commit msg that no users are affected because of this.

Best regards,
Krzysztof


From mripard at kernel.org  Tue Dec 17 08:53:29 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 17:53:29 +0100
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes
 handling on RK3588 HDMI0
In-Reply-To: <c45ff74a-c9a4-4cf1-8530-04087e06b07a@collabora.com>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
 <1820767.5KxKD5qtyk@diego>
 <a4ex3s23r4k6wehyoaw3aylpcexfrclrxxykjpabhdfne2jgmu@ii6riiiga2zj>
 <1756448.izSxrag8PF@diego>
 <20241217-ubiquitous-refreshing-finch-aceade@houat>
 <c45ff74a-c9a4-4cf1-8530-04087e06b07a@collabora.com>
Message-ID: <20241217-zealous-boisterous-llama-52bfcc@houat>

On Tue, Dec 17, 2024 at 06:36:41PM +0200, Cristian Ciocaltea wrote:
> On 12/17/24 5:00 PM, Maxime Ripard wrote:
> > On Wed, Dec 11, 2024 at 07:01:15PM +0100, Heiko St?bner wrote:
> >> Am Mittwoch, 11. Dezember 2024, 18:47:44 CET schrieb Maxime Ripard:
> >>> On Wed, Dec 11, 2024 at 06:23:03PM +0100, Heiko St?bner wrote:
> >>>> Am Mittwoch, 11. Dezember 2024, 18:07:57 CET schrieb Maxime Ripard:
> >>>>> On Wed, Dec 11, 2024 at 12:15:07PM +0200, Cristian Ciocaltea wrote:
> >>>>>> The RK3588 specific implementation is currently quite limited in terms
> >>>>>> of handling the full range of display modes supported by the connected
> >>>>>> screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
> >>>>>> few of them.
> >>>>>>
> >>>>>> Additionally, it doesn't cope well with non-integer refresh rates like
> >>>>>> 59.94, 29.97, 23.98, etc.
> >>>>>>
> >>>>>> Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
> >>>>>> all display modes up to 4K at 60Hz.
> >>>>>>
> >>>>>> Tested-by: FUKAUMI Naoki <naoki at radxa.com>
> >>>>>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> >>>>>> ---
> >>>>>>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
> >>>>>>  1 file changed, 34 insertions(+)
> >>>>>>
> >>>>>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> >>>>>> index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
> >>>>>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> >>>>>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> >>>>>> @@ -158,6 +158,7 @@ struct vop2_video_port {
> >>>>>>  	struct drm_crtc crtc;
> >>>>>>  	struct vop2 *vop2;
> >>>>>>  	struct clk *dclk;
> >>>>>> +	struct clk *dclk_src;
> >>>>>>  	unsigned int id;
> >>>>>>  	const struct vop2_video_port_data *data;
> >>>>>>  
> >>>>>> @@ -212,6 +213,7 @@ struct vop2 {
> >>>>>>  	struct clk *hclk;
> >>>>>>  	struct clk *aclk;
> >>>>>>  	struct clk *pclk;
> >>>>>> +	struct clk *pll_hdmiphy0;
> >>>>>>  
> >>>>>>  	/* optional internal rgb encoder */
> >>>>>>  	struct rockchip_rgb *rgb;
> >>>>>> @@ -220,6 +222,8 @@ struct vop2 {
> >>>>>>  	struct vop2_win win[];
> >>>>>>  };
> >>>>>>  
> >>>>>> +#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
> >>>>>> +
> >>>>>>  #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
> >>>>>>  					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
> >>>>>>  
> >>>>>> @@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
> >>>>>>  
> >>>>>>  	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
> >>>>>>  
> >>>>>> +	if (vp->dclk_src)
> >>>>>> +		clk_set_parent(vp->dclk, vp->dclk_src);
> >>>>>> +
> >>>>>>  	clk_disable_unprepare(vp->dclk);
> >>>>>>  
> >>>>>>  	vop2->enable_count--;
> >>>>>> @@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
> >>>>>>  
> >>>>>>  	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
> >>>>>>  
> >>>>>> +	/*
> >>>>>> +	 * Switch to HDMI PHY PLL as DCLK source for display modes up
> >>>>>> +	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
> >>>>>> +	 */
> >>>>>> +	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
> >>>>>> +		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
> >>>>>> +			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
> >>>>>> +
> >>>>>> +			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
> >>>>>> +				if (!vp->dclk_src)
> >>>>>> +					vp->dclk_src = clk_get_parent(vp->dclk);
> >>>>>> +
> >>>>>> +				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
> >>>>>> +				if (ret < 0)
> >>>>>> +					drm_warn(vop2->drm,
> >>>>>> +						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
> >>>>>> +				break;
> >>>>>> +			}
> >>>>>> +		}
> >>>>>> +	}
> >>>>>> +
> >>>>>
> >>>>> It seems pretty fragile to do it at atomic_enable time, even more so
> >>>>> since you don't lock the parent either.
> >>>>>
> >>>>> Any reason not to do it in the DRM or clock driver probe, and make sure
> >>>>> you never change the parent somehow?
> >>>>
> >>>> On rk3588 we have 3 dclk_s and 2 hdmi controllers. Each video-port can
> >>>> use the clock generated from either the hdmi0phy or hdmi1phy, depending
> >>>> on which hdmi-controller it uses.
> >>>>
> >>>> So you actually need to know which vpX will output to which hdmiY to then
> >>>> reparent that dclk to the hdmiphy output.
> >>>
> >>> The Rockchip nomenclature isn't super obvious to me, sorry. Is there a
> >>> datasheet for this somewhere? Also, does this vpX -> HDMI-Y mapping need
> >>> to be dynamic?
> >>
> >> VPs are CRTCs in drm-language and each of them can drive a differing
> >> number of output encoders. Those video-ports also have differing output
> >> characteristics in terms of supported resolution and other properties.
> >>
> >> The rk3588 TRM has leaked in a number of places, and if you find a
> >> TRM-part2, there is a section labeled "Display Output Interface Description"
> >> that has a nice graphic for that.
> >>
> >> Or in short:
> >> - CRTC(VP)0 supports 8K resolution and can drive DP0+1, HDMI0+1, eDP0+1
> >>   [if I'm reading things correctly, 8K together with CRTC1 somehow)
> >> - CRTC(VP)1 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP0+1
> >> - CRTC(VP)2 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP01, DSI0+1
> >> - CRTC(VP)3 supports 2K resolution and can drive DSI0+1 and some BT1120,BT656
> >>
> >> so for the 3 higher resolution CRTCs there are essentially 6 or 8 output options
> >> depending on the board design
> > 
> > That's much clearer, thanks. I'm not entirely sure how that links to the
> > need for the PLL to change its parent depending on the ouput. Do you
> > need to always have all the outputs on the same PLL?
> 
> One of the problems is that the PHY PLLs cannot be used as clock sources
> for resolutions above 4K at 60Hz, while VOP2 on RK3588 supports up to 8K at 60Hz,
> which is supposed to be handled by the system CRU.

But can that system CRU drive resolutions lower than 4k at 60? If so, why
do we bother with PHYs?

> Moreover, the 2 PLLs are shared between 3 out of the 4 video ports already
> mentioned by Heiko.  There is quite a bit of complexity in downstream
> driver to handle all possible usecases - see [1] for a brief description on
> how was that designed to work.

That's a generic allocation issue. Multiple drivers (vc4 for example)
has this issue for other components. It can be fairly easily dealt with
at atomic_check time.

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

From cristian.ciocaltea at collabora.com  Tue Dec 17 08:59:57 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 17 Dec 2024 18:59:57 +0200
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes handling
 on RK3588 HDMI0
In-Reply-To: <20241217-zealous-boisterous-llama-52bfcc@houat>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
 <1820767.5KxKD5qtyk@diego>
 <a4ex3s23r4k6wehyoaw3aylpcexfrclrxxykjpabhdfne2jgmu@ii6riiiga2zj>
 <1756448.izSxrag8PF@diego>
 <20241217-ubiquitous-refreshing-finch-aceade@houat>
 <c45ff74a-c9a4-4cf1-8530-04087e06b07a@collabora.com>
 <20241217-zealous-boisterous-llama-52bfcc@houat>
Message-ID: <2ba24dc6-b6e7-4964-af84-a5374903ce36@collabora.com>

On 12/17/24 6:53 PM, Maxime Ripard wrote:
> On Tue, Dec 17, 2024 at 06:36:41PM +0200, Cristian Ciocaltea wrote:
>> On 12/17/24 5:00 PM, Maxime Ripard wrote:
>>> On Wed, Dec 11, 2024 at 07:01:15PM +0100, Heiko St?bner wrote:
>>>> Am Mittwoch, 11. Dezember 2024, 18:47:44 CET schrieb Maxime Ripard:
>>>>> On Wed, Dec 11, 2024 at 06:23:03PM +0100, Heiko St?bner wrote:
>>>>>> Am Mittwoch, 11. Dezember 2024, 18:07:57 CET schrieb Maxime Ripard:
>>>>>>> On Wed, Dec 11, 2024 at 12:15:07PM +0200, Cristian Ciocaltea wrote:
>>>>>>>> The RK3588 specific implementation is currently quite limited in terms
>>>>>>>> of handling the full range of display modes supported by the connected
>>>>>>>> screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
>>>>>>>> few of them.
>>>>>>>>
>>>>>>>> Additionally, it doesn't cope well with non-integer refresh rates like
>>>>>>>> 59.94, 29.97, 23.98, etc.
>>>>>>>>
>>>>>>>> Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
>>>>>>>> all display modes up to 4K at 60Hz.
>>>>>>>>
>>>>>>>> Tested-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
>>>>>>>> ---
>>>>>>>>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
>>>>>>>>  1 file changed, 34 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>>>>>>>> index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
>>>>>>>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>>>>>>>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>>>>>>>> @@ -158,6 +158,7 @@ struct vop2_video_port {
>>>>>>>>  	struct drm_crtc crtc;
>>>>>>>>  	struct vop2 *vop2;
>>>>>>>>  	struct clk *dclk;
>>>>>>>> +	struct clk *dclk_src;
>>>>>>>>  	unsigned int id;
>>>>>>>>  	const struct vop2_video_port_data *data;
>>>>>>>>  
>>>>>>>> @@ -212,6 +213,7 @@ struct vop2 {
>>>>>>>>  	struct clk *hclk;
>>>>>>>>  	struct clk *aclk;
>>>>>>>>  	struct clk *pclk;
>>>>>>>> +	struct clk *pll_hdmiphy0;
>>>>>>>>  
>>>>>>>>  	/* optional internal rgb encoder */
>>>>>>>>  	struct rockchip_rgb *rgb;
>>>>>>>> @@ -220,6 +222,8 @@ struct vop2 {
>>>>>>>>  	struct vop2_win win[];
>>>>>>>>  };
>>>>>>>>  
>>>>>>>> +#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
>>>>>>>> +
>>>>>>>>  #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
>>>>>>>>  					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
>>>>>>>>  
>>>>>>>> @@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
>>>>>>>>  
>>>>>>>>  	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
>>>>>>>>  
>>>>>>>> +	if (vp->dclk_src)
>>>>>>>> +		clk_set_parent(vp->dclk, vp->dclk_src);
>>>>>>>> +
>>>>>>>>  	clk_disable_unprepare(vp->dclk);
>>>>>>>>  
>>>>>>>>  	vop2->enable_count--;
>>>>>>>> @@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
>>>>>>>>  
>>>>>>>>  	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
>>>>>>>>  
>>>>>>>> +	/*
>>>>>>>> +	 * Switch to HDMI PHY PLL as DCLK source for display modes up
>>>>>>>> +	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
>>>>>>>> +	 */
>>>>>>>> +	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
>>>>>>>> +		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
>>>>>>>> +			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
>>>>>>>> +
>>>>>>>> +			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
>>>>>>>> +				if (!vp->dclk_src)
>>>>>>>> +					vp->dclk_src = clk_get_parent(vp->dclk);
>>>>>>>> +
>>>>>>>> +				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
>>>>>>>> +				if (ret < 0)
>>>>>>>> +					drm_warn(vop2->drm,
>>>>>>>> +						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
>>>>>>>> +				break;
>>>>>>>> +			}
>>>>>>>> +		}
>>>>>>>> +	}
>>>>>>>> +
>>>>>>>
>>>>>>> It seems pretty fragile to do it at atomic_enable time, even more so
>>>>>>> since you don't lock the parent either.
>>>>>>>
>>>>>>> Any reason not to do it in the DRM or clock driver probe, and make sure
>>>>>>> you never change the parent somehow?
>>>>>>
>>>>>> On rk3588 we have 3 dclk_s and 2 hdmi controllers. Each video-port can
>>>>>> use the clock generated from either the hdmi0phy or hdmi1phy, depending
>>>>>> on which hdmi-controller it uses.
>>>>>>
>>>>>> So you actually need to know which vpX will output to which hdmiY to then
>>>>>> reparent that dclk to the hdmiphy output.
>>>>>
>>>>> The Rockchip nomenclature isn't super obvious to me, sorry. Is there a
>>>>> datasheet for this somewhere? Also, does this vpX -> HDMI-Y mapping need
>>>>> to be dynamic?
>>>>
>>>> VPs are CRTCs in drm-language and each of them can drive a differing
>>>> number of output encoders. Those video-ports also have differing output
>>>> characteristics in terms of supported resolution and other properties.
>>>>
>>>> The rk3588 TRM has leaked in a number of places, and if you find a
>>>> TRM-part2, there is a section labeled "Display Output Interface Description"
>>>> that has a nice graphic for that.
>>>>
>>>> Or in short:
>>>> - CRTC(VP)0 supports 8K resolution and can drive DP0+1, HDMI0+1, eDP0+1
>>>>   [if I'm reading things correctly, 8K together with CRTC1 somehow)
>>>> - CRTC(VP)1 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP0+1
>>>> - CRTC(VP)2 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP01, DSI0+1
>>>> - CRTC(VP)3 supports 2K resolution and can drive DSI0+1 and some BT1120,BT656
>>>>
>>>> so for the 3 higher resolution CRTCs there are essentially 6 or 8 output options
>>>> depending on the board design
>>>
>>> That's much clearer, thanks. I'm not entirely sure how that links to the
>>> need for the PLL to change its parent depending on the ouput. Do you
>>> need to always have all the outputs on the same PLL?
>>
>> One of the problems is that the PHY PLLs cannot be used as clock sources
>> for resolutions above 4K at 60Hz, while VOP2 on RK3588 supports up to 8K at 60Hz,
>> which is supposed to be handled by the system CRU.
> 
> But can that system CRU drive resolutions lower than 4k at 60? If so, why
> do we bother with PHYs?

It can, but it's not accurate enough to support all modes, e.g. those
having fractional refresh rates, among others.  That's actually the
reason we'd want to make use of the PHY PLLs.

>> Moreover, the 2 PLLs are shared between 3 out of the 4 video ports already
>> mentioned by Heiko.  There is quite a bit of complexity in downstream
>> driver to handle all possible usecases - see [1] for a brief description on
>> how was that designed to work.
> 
> That's a generic allocation issue. Multiple drivers (vc4 for example)
> has this issue for other components. It can be fairly easily dealt with
> at atomic_check time.
> 
> Maxime



From robh at kernel.org  Tue Dec 17 09:02:57 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Dec 2024 11:02:57 -0600
Subject: [PATCH V2 18/46] arm64/sysreg: Add register fields for PMUACR_EL1
In-Reply-To: <a442bca4-d1c0-4f3e-ae13-4836caec2da9@sirena.org.uk>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-19-anshuman.khandual@arm.com> <20241216231505.GA601635-robh@kernel.org>
 <a442bca4-d1c0-4f3e-ae13-4836caec2da9@sirena.org.uk>
Message-ID: <CAL_Jsq+45YNGNEcDVFvKH3Tiwtz0HF9_O4tPfQH0dbXra2bcRQ@mail.gmail.com>

On Tue, Dec 17, 2024 at 9:30?AM Mark Brown <broonie at kernel.org> wrote:
>
> On Mon, Dec 16, 2024 at 05:15:05PM -0600, Rob Herring wrote:
> > On Tue, Dec 10, 2024 at 11:22:43AM +0530, Anshuman Khandual wrote:
>
> > > +Sysreg     PMUACR_EL1      3       0       9       14      4
>
> > I already added this and various other PMUv3.9 registers you've added
> > here in v6.12 and v6.13. So are you on an old base or the tool allows
> > multiple definitions? If the latter, that should be fixed.
>
> The tool is written in awk and hence *really* dumb so it's not going to
> notice this, and so long as the resulting definitions are identical the
> compiler won't either.  It would indeed be nice if the tooling were able
> to detect this.

Something like this should work:

git grep -h '^Sysreg\s' arch/arm64/tools/sysreg | tr -s ' \t' ' ' |
sort | uniq -c | sort -n | grep -E '^\s+([2-9]|1[0-9])'

No duplicates currently.

Rob


From james.clark at linaro.org  Tue Dec 17 09:11:31 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 17 Dec 2024 17:11:31 +0000
Subject: [PATCH] coresight: Add a KUnit test for coresight_find_default_sink()
Message-ID: <20241217171132.834943-1-james.clark@linaro.org>

Add a test to confirm that default sink selection skips over an ETF
and returns an ETR even if it's further away.

This also makes it easier to add new unit tests in the future.

Signed-off-by: James Clark <james.clark at linaro.org>
---
 drivers/hwtracing/coresight/Kconfig           |  9 ++
 drivers/hwtracing/coresight/Makefile          |  1 +
 drivers/hwtracing/coresight/coresight-core.c  |  1 +
 .../coresight/coresight-kunit-tests.c         | 90 +++++++++++++++++++
 4 files changed, 101 insertions(+)
 create mode 100644 drivers/hwtracing/coresight/coresight-kunit-tests.c

diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 06f0a7594169..056d04bc540a 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -247,4 +247,13 @@ config CORESIGHT_DUMMY
 
 	  To compile this driver as a module, choose M here: the module will be
 	  called coresight-dummy.
+
+config CORESIGHT_KUNIT_TESTS
+	  tristate "Enable Coresight unit tests"
+	  depends on KUNIT
+	  default KUNIT_ALL_TESTS
+	  help
+	    Enable Coresight unit tests. Only useful for development and not
+	    intended for production.
+
 endif
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 4ba478211b31..c170a41b3056 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -51,3 +51,4 @@ coresight-cti-y := coresight-cti-core.o	coresight-cti-platform.o \
 		   coresight-cti-sysfs.o
 obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o
 obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o
+obj-$(CONFIG_CORESIGHT_KUNIT_TESTS) += coresight-kunit-tests.o
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index ea38ecf26fcb..ce63b68d5503 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -869,6 +869,7 @@ coresight_find_default_sink(struct coresight_device *csdev)
 	}
 	return csdev->def_sink;
 }
+EXPORT_SYMBOL_GPL(coresight_find_default_sink);
 
 static int coresight_remove_sink_ref(struct device *dev, void *data)
 {
diff --git a/drivers/hwtracing/coresight/coresight-kunit-tests.c b/drivers/hwtracing/coresight/coresight-kunit-tests.c
new file mode 100644
index 000000000000..d022bacc8357
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-kunit-tests.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <kunit/test.h>
+#include <kunit/device.h>
+#include <linux/coresight.h>
+
+#include "coresight-priv.h"
+
+static struct coresight_device *coresight_test_device(struct device *dev)
+{
+	struct coresight_device *csdev = devm_kcalloc(dev, 1,
+						     sizeof(struct coresight_device),
+						     GFP_KERNEL);
+	csdev->pdata = devm_kcalloc(dev, 1,
+				   sizeof(struct coresight_platform_data),
+				   GFP_KERNEL);
+	return csdev;
+}
+
+static void coresight_free_test_device(struct device *dev,
+				       struct coresight_device *csdev)
+{
+	devm_kfree(dev, csdev->pdata->out_conns);
+	devm_kfree(dev, csdev->pdata);
+	devm_kfree(dev, csdev);
+}
+
+static int coresight_test_cpuid(struct coresight_device *csdev)
+{
+	return 0;
+}
+
+static void test_default_sink(struct kunit *test)
+{
+	/*
+	 * ETM -> ETF -> ETR -> CATU
+	 *                ^
+	 *                | default
+	 */
+	struct device *dev = kunit_device_register(test, "coresight_kunit");
+	struct coresight_device *etm = coresight_test_device(dev),
+				*etf = coresight_test_device(dev),
+				*etr = coresight_test_device(dev),
+				*catu = coresight_test_device(dev);
+	struct coresight_connection conn = {};
+	struct coresight_ops_source src_ops = {.cpu_id = coresight_test_cpuid };
+	struct coresight_ops etm_cs_ops = { .source_ops	= &src_ops };
+
+	etm->type = CORESIGHT_DEV_TYPE_SOURCE;
+	etm->ops = &etm_cs_ops;
+	etf->type = CORESIGHT_DEV_TYPE_LINKSINK;
+	etf->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER;
+	etr->type = CORESIGHT_DEV_TYPE_SINK;
+	etr->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
+	catu->type = CORESIGHT_DEV_TYPE_HELPER;
+
+	conn.src_dev = etm;
+	conn.dest_dev = etf;
+	coresight_add_out_conn(dev, etm->pdata, &conn);
+
+	conn.src_dev = etf;
+	conn.dest_dev = etr;
+	coresight_add_out_conn(dev, etf->pdata, &conn);
+
+	conn.src_dev = etr;
+	conn.dest_dev = catu;
+	coresight_add_out_conn(dev, etr->pdata, &conn);
+
+	KUNIT_ASSERT_PTR_EQ(test, coresight_find_default_sink(etm), etr);
+
+	coresight_free_test_device(dev, etm);
+	coresight_free_test_device(dev, etf);
+	coresight_free_test_device(dev, etr);
+	coresight_free_test_device(dev, catu);
+}
+
+static struct kunit_case coresight_testcases[] = {
+	KUNIT_CASE(test_default_sink),
+	{}
+};
+
+static struct kunit_suite coresight_test_suite = {
+	.name = "coresight_test_suite",
+	.test_cases = coresight_testcases,
+};
+
+kunit_test_suites(&coresight_test_suite);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Clark <james.clark at linaro.org>");
+MODULE_DESCRIPTION("Arm CoreSight KUnit tests");
-- 
2.34.1



From mripard at kernel.org  Tue Dec 17 09:13:27 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 18:13:27 +0100
Subject: [PATCH v6 09/10] drm/vc4: hdmi: stop rereading EDID in
 get_modes()
In-Reply-To: <73xdxb575n4ncmadffkwqzczoewbadq3forpvqt4vp7zfln2nq@o2wmbbbepwgg>
References: <20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06@linaro.org>
 <20241206-drm-bridge-hdmi-connector-v6-9-50dc145a9c06@linaro.org>
 <20241206-caped-proficient-rattlesnake-c882f3@houat>
 <73xdxb575n4ncmadffkwqzczoewbadq3forpvqt4vp7zfln2nq@o2wmbbbepwgg>
Message-ID: <20241217-curly-mauve-scallop-d84a3d@houat>

On Sun, Dec 08, 2024 at 01:06:46PM +0200, Dmitry Baryshkov wrote:
> On Fri, Dec 06, 2024 at 03:34:52PM +0100, Maxime Ripard wrote:
> > Hi,
> > 
> > On Fri, Dec 06, 2024 at 12:16:03PM +0200, Dmitry Baryshkov wrote:
> > > The vc4_hdmi_connector_detect_ctx() via vc4_hdmi_handle_hotplug()
> > > already reads EDID and propagates it to the drm_connector. Stop
> > > rereading EDID as a part of the .get_modes() callback and just update
> > > the list of modes. This matches the behaviour of the i915 driver.
> > > 
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > ---
> > >  drivers/gpu/drm/vc4/vc4_hdmi.c | 21 ---------------------
> > >  1 file changed, 21 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > index e5ab42f72f618b90f956482db6c9c8074c1e3bf1..3364ef90968dad3074800f02926300ffceb75c69 100644
> > > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> > > @@ -470,31 +470,10 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
> > >  
> > >  static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
> > >  {
> > > -	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
> > >  	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
> > > -	const struct drm_edid *drm_edid;
> > >  	int ret = 0;
> > >  
> > > -	/*
> > > -	 * NOTE: This function should really take vc4_hdmi->mutex, but doing so
> > > -	 * results in reentrancy issues since cec_s_phys_addr() might call
> > > -	 * .adap_enable, which leads to that funtion being called with our mutex
> > > -	 * held.
> > > -	 *
> > > -	 * Concurrency isn't an issue at the moment since we don't share
> > > -	 * any state with any of the other frameworks so we can ignore
> > > -	 * the lock for now.
> > > -	 */
> > > -
> > > -	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
> > > -	drm_edid_connector_update(connector, drm_edid);
> > > -	cec_s_phys_addr(vc4_hdmi->cec_adap,
> > > -			connector->display_info.source_physical_address, false);
> > > -	if (!drm_edid)
> > > -		return 0;
> > > -
> > >  	ret = drm_edid_connector_add_modes(connector);
> > > -	drm_edid_free(drm_edid);
> > 
> > I don't think that works though, for mostly two reasons:
> > 
> >  1) We're not sure we'll even have an hotplug interrupt if the system
> >     boots with the connector plugged in for example.
> > 
> >  2) afaik, the get_modes ioctl directly calls get_modes too.
> 
> I think both paths use .fill_modes, not get_modes.

The standard fill_modes helper calls get_modes.

> And fill_modes explicitly calls .detect / .detect_ctx. It would be
> nice if somebody can verify the change on the acual hw. But as I
> wrote, i915 driver does exactly the same: the EDID is read / updated
> in .detect_ctx(), while .get_modes() only performs
> drm_edid_connector_add_modes(). Okay, there is one significant
> difference which we should probably patch out: the .force() is also
> implemented to update EDID in the forced case. I should probably do
> the same for the drivers being handled in this patchset.

Ack. Worst case scenario we can fix it later on.

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

From james.clark at linaro.org  Tue Dec 17 09:17:01 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 17 Dec 2024 17:17:01 +0000
Subject: [PATCH] coresight: docs: Remove target sink from examples
In-Reply-To: <75ce4def-b0ca-428f-99a5-19ca98e876a0@os.amperecomputing.com>
References: <20241210144933.295798-1-james.clark@linaro.org>
 <9e53f5b9-d8a9-46b8-8ff1-7f018e2d9c06@os.amperecomputing.com>
 <24299600-277f-48f4-9be5-cbd65ab6ddb7@linaro.org>
 <75ce4def-b0ca-428f-99a5-19ca98e876a0@os.amperecomputing.com>
Message-ID: <50e4aab7-d262-48a0-b956-2c2df0faeb25@linaro.org>



On 12/12/2024 7:38 pm, Steve Clevenger wrote:
> 
> 
> On 12/12/2024 7:27 AM, James Clark wrote:
>>
>>
>> On 11/12/2024 6:01 pm, Steve Clevenger wrote:
>>>
>>> Hi James,
>>>
>>> I thought I'd mention this issue with multicore self-hosted trace. The
>>> perf command line syntax does not allow a sink "type" to be specified
>>> (e.g. @tmc_etf or @tmc_etr). For multicore, it doesn't make sense to
>>> specify a processor mapped sink as would be the case for single core
>>> trace. A sink "type" should be allowed to avoid the auto select default.
>>> In our case, the default is the ETF sink.
>>>
>>> Thanks,
>>> Steve C.
>>>
>>
>> I'm sure it would be possible to add support for this, but I'm wondering
>> if the real issue is that the default selection logic is wrong? Are you
>> saying the default you get is ETF but you want ETR? And there is both
>> for each ETM? The default selection logic isn't easy to summarize but it
>> should prefer ETR (sysmem) over ETF (link sink), see coresight_find_sink().
>>
>> It's probably better to fix that rather than add a new sink selection
>> feature. Maybe if you shared a diagram of your coresight architecture it
>> would help.
>>
>> Thanks
>> James
> 
> Hi James,
> 
> It appears the default sink selection is ETF for multicore trace. In any
> case, for the Arm? CoreSight Base System Architecture STC Level
> compliance, I need to be able to specify the sink type.

Yep it makes sense to add support for selecting it then then, I will put 
it on the list but not sure about the priority. I think looking into why 
the default isn't working is more important for now.

> 
> The Ampere CoreSight hierarchy is described to the ACPI as follows:
> 
> 
> +-----------------+
> |                 |
> |       ETM       |
> |                 |
> +--------+--------+
>           |
>           |
> +--------+--------+
> |                 |
> |       ETF       |
> |                 |
> +--------+--------+
>           |
>           |
> +--------+--------+
> |                 |
> |       ETR       |
> |                 |
> +--------+--------+
>           |
>           |
> +--------+--------+
> |                 |
> |      CATU       |
> |                 |
> +--------+--------+
> 
> Steve C.
> 

I recreated this in the test here: 
https://lore.kernel.org/linux-kernel/20241217171132.834943-1-james.clark at linaro.org/T/#u

But it looks like it correctly selects ETR rather than ETF, so I'm not 
sure what the difference is between your setup and that. If you can have 
a look at that test and compare it that would be very helpful.

Thanks
James




From mripard at kernel.org  Tue Dec 17 09:21:10 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 18:21:10 +0100
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
Message-ID: <20241217-vivacious-chameleon-of-swiftness-f1edc4@houat>

Hi,

On Tue, Dec 17, 2024 at 02:40:22AM +0200, Dmitry Baryshkov wrote:
> While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
> framework, I stumbled upon an issue while handling the Audio InfoFrames.
> The HDMI codec callbacks weren't receiving the drm_atomic_state, so
> there was no simple way to get the drm_connector that stayed at the end
> of the bridge chain. At the same point the drm_hdmi_connector functions
> expected to get drm_connector instance.
> 
> While looking for a way to solve the issue, I stumbled upon several
> deficiencies in existing hdmi_codec_ops implementations. Only few of the
> implementations were able to handle codec's 'plugged' callback. One
> third of the drivers didn't implement the get_eld() callback.
> 
> Most of the issues can be solved if drm_connector handles
> hdmi-audio-codec on its own, delegating functionality to the actual
> implementation, be it a driver that implements drm_connector or
> drm_bridge.
> 
> Implement such high-level framework, adding proper support for Audio
> InfoFrame generation to the LT9611 driver.
> 
> Several design decisions to be kept in mind:
> 
> - drm_connector_hdmi_codec is kept as simple as possible. It implements
>   generic functionality (ELD, hotplug, registration).
> 
> - drm_hdmi_connector sets up HDMI codec device if the connector
>   is setup correspondingly (either I2S or S/PDIF is marked as
>   supported).
> 
> - drm_bridge_connector provides a way to link HDMI audio codec
>   funcionality in the drm_bridge with the drm_connector_hdmi_codec
>   framework.
> 
> - It might be worth reverting the no_i2s_capture / no_spdif_capture
>   bits. Only TDA889x driver sets them, while it's safe to assume that
>   most of HDMI / DP devices do not support ARC / capture. I think the
>   drivers should opt-in capture support rather than having to opt-out of
>   it.

Sorry if this isn't clear to me and I'm quite late to the party, but did
you test this on vc4 with both a pi3 and pi4, or was it just compile
tested?

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

From manivannan.sadhasivam at linaro.org  Tue Dec 17 09:20:33 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Tue, 17 Dec 2024 22:50:33 +0530
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <20241203222515.GA2967814@bhelgaas>
References: <20241126155119.1574564-2-christian.bruel@foss.st.com>
 <20241203222515.GA2967814@bhelgaas>
Message-ID: <20241217172033.zxl4bufakzx7eww5@thinkpad>

On Tue, Dec 03, 2024 at 04:25:15PM -0600, Bjorn Helgaas wrote:
> On Tue, Nov 26, 2024 at 04:51:15PM +0100, Christian Bruel wrote:
> > Document the bindings for STM32MP25 PCIe Controller configured in
> > root complex mode.
> > 
> > Supports 4 legacy interrupts and MSI interrupts from the ARM
> > GICv2m controller.
> 
> s/legacy/INTx/
> 
> > STM32 PCIe may be in a power domain which is the case for the STM32MP25
> > based boards.
> > 
> > Supports wake# from wake-gpios
> 
> s/wake#/WAKE#/
> 
> > +  wake-gpios:
> > +    description: GPIO controlled connection to WAKE# input signal
> 
> I'm not a hardware guy, but this sounds like a GPIO that *reads*
> WAKE#, not controls it.
> 
> > +    pcie at 48400000 {
> > +        compatible = "st,stm32mp25-pcie-rc";
> > +        device_type = "pci";
> > +        num-lanes = <1>;
> 
> num-lanes applies to a Root Port, not to a Root Complex.  I know most
> bindings conflate Root Ports with the Root Complex, maybe because many
> of these controllers only support a single Root Port?
> 
> But are we ever going to separate these out?  I assume someday
> controllers will support multiple Root Ports and/or additional devices
> on the root bus, like RCiEPs, RCECs, etc., and we'll need per-RP phys,
> max-link-speed, num-lanes, reset-gpios, etc.
> 
> Seems like it would be to our benefit to split out the Root Ports when
> we can, even if the current hardware only supports one, so we can
> start untangling the code and data structures.
> 

+1 for moving the properties to RP node where they should belong to. The
controller driver might have to do some extra work to parse the RP node and get
these properties, but it is worth the effort.

- Mani

-- 
????????? ????????


From mripard at kernel.org  Tue Dec 17 09:22:37 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 18:22:37 +0100
Subject: [PATCH v7 03/10] drm/connector: implement generic HDMI codec
 helpers
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-3-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-drm-bridge-hdmi-connector-v7-3-cb9df2b6a515@linaro.org>
Message-ID: <20241217-thistle-rattlesnake-of-current-dfd247@houat>

On Tue, Dec 17, 2024 at 02:40:25AM +0200, Dmitry Baryshkov wrote:
> Several DRM drivers implement HDMI codec support (despite its name it
> applies to both HDMI and DisplayPort drivers). Implement generic
> framework to be used by these drivers. This removes a requirement to
> implement get_eld() callback and provides default implementation for
> codec's plug handling.
> 
> The framework is integrated with the DRM HDMI Connector framework, but
> can be used by DisplayPort drivers.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/gpu/drm/Makefile                   |   1 +
>  drivers/gpu/drm/drm_connector.c            |   5 +
>  drivers/gpu/drm/drm_connector_hdmi_codec.c | 189 +++++++++++++++++++++++++++++
>  include/drm/drm_connector.h                | 125 +++++++++++++++++++
>  4 files changed, 320 insertions(+)
> 
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 19fb370fbc56772077973c864df71e4b8e0bf99b..46e6dbc355afe4015ff2327ba04211cdc011a0b7 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -42,6 +42,7 @@ drm-y := \
>  	drm_cache.o \
>  	drm_color_mgmt.o \
>  	drm_connector.o \
> +	drm_connector_hdmi_codec.o \
>  	drm_crtc.o \
>  	drm_displayid.o \
>  	drm_drv.o \
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index bbdaaf7022b62d84594a29f1b60144920903a99a..4abfbded962bf45b793a2bd5b1b5c4d9f478a1f7 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -33,6 +33,7 @@
>  #include <drm/drm_sysfs.h>
>  #include <drm/drm_utils.h>
>  
> +#include <linux/platform_device.h>
>  #include <linux/property.h>
>  #include <linux/uaccess.h>
>  
> @@ -280,6 +281,7 @@ static int __drm_connector_init(struct drm_device *dev,
>  	mutex_init(&connector->eld_mutex);
>  	mutex_init(&connector->edid_override_mutex);
>  	mutex_init(&connector->hdmi.infoframes.lock);
> +	mutex_init(&connector->hdmi_codec.lock);
>  	connector->edid_blob_ptr = NULL;
>  	connector->epoch_counter = 0;
>  	connector->tile_blob_ptr = NULL;
> @@ -632,6 +634,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
>  		    DRM_CONNECTOR_REGISTERED))
>  		drm_connector_unregister(connector);
>  
> +	platform_device_unregister(connector->hdmi_codec.codec_pdev);
> +
>  	if (connector->privacy_screen) {
>  		drm_privacy_screen_put(connector->privacy_screen);
>  		connector->privacy_screen = NULL;
> @@ -670,6 +674,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
>  		connector->funcs->atomic_destroy_state(connector,
>  						       connector->state);
>  
> +	mutex_destroy(&connector->hdmi_codec.lock);
>  	mutex_destroy(&connector->hdmi.infoframes.lock);
>  	mutex_destroy(&connector->mutex);
>  
> diff --git a/drivers/gpu/drm/drm_connector_hdmi_codec.c b/drivers/gpu/drm/drm_connector_hdmi_codec.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..a6e2f27c3f7ff9d57cf19c055870001daff4c676
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_connector_hdmi_codec.c
> @@ -0,0 +1,189 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright (c) 2024 Linaro Ltd
> + */
> +
> +#include <linux/mutex.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +
> +#include <drm/drm_connector.h>
> +#include <drm/drm_device.h>
> +
> +#include <sound/hdmi-codec.h>
> +
> +static int drm_connector_hdmi_codec_audio_startup(struct device *dev, void *data)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi_codec.funcs;
> +
> +	if (funcs->audio_startup)
> +		return funcs->audio_startup(connector);
> +
> +	return 0;
> +}
> +
> +static int drm_connector_hdmi_codec_prepare(struct device *dev, void *data,
> +					    struct hdmi_codec_daifmt *fmt,
> +					    struct hdmi_codec_params *hparms)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi_codec.funcs;
> +
> +	return funcs->prepare(connector, fmt, hparms);
> +}
> +
> +static void drm_connector_hdmi_codec_audio_shutdown(struct device *dev, void *data)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi_codec.funcs;
> +
> +	return funcs->audio_shutdown(connector);
> +}
> +
> +static int drm_connector_hdmi_codec_mute_stream(struct device *dev, void *data,
> +						bool enable, int direction)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi_codec.funcs;
> +
> +	if (funcs->mute_stream)
> +		return funcs->mute_stream(connector, enable, direction);
> +
> +	return -ENOTSUPP;
> +}
> +
> +static int drm_connector_hdmi_codec_get_dai_id(struct snd_soc_component *comment,
> +		  struct device_node *endpoint,
> +		  void *data)
> +{
> +	struct drm_connector *connector = data;
> +	struct of_endpoint of_ep;
> +	int ret;
> +
> +	if (connector->hdmi_codec.dai_port < 0)
> +		return -ENOTSUPP;
> +
> +	ret = of_graph_parse_endpoint(endpoint, &of_ep);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (of_ep.port == connector->hdmi_codec.dai_port)
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +
> +static int drm_connector_hdmi_codec_get_eld(struct device *dev, void *data,
> +					    uint8_t *buf, size_t len)
> +{
> +	struct drm_connector *connector = data;
> +
> +	mutex_lock(&connector->eld_mutex);
> +	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
> +	mutex_unlock(&connector->eld_mutex);
> +
> +	return 0;
> +}
> +
> +static int drm_connector_hdmi_codec_hook_plugged_cb(struct device *dev,
> +						    void *data,
> +						    hdmi_codec_plugged_cb fn,
> +						    struct device *codec_dev)
> +{
> +	struct drm_connector *connector = data;
> +
> +	mutex_lock(&connector->hdmi_codec.lock);
> +
> +	connector->hdmi_codec.plugged_cb = fn;
> +	connector->hdmi_codec.plugged_cb_dev = codec_dev;
> +
> +	fn(codec_dev, connector->hdmi_codec.last_state);
> +
> +	mutex_unlock(&connector->hdmi_codec.lock);
> +
> +	return 0;
> +}
> +
> +void drm_connector_hdmi_codec_plugged_notify(struct drm_connector *connector,
> +					     bool plugged)
> +{
> +	mutex_lock(&connector->hdmi_codec.lock);
> +
> +	connector->hdmi_codec.last_state = plugged;
> +
> +	if (connector->hdmi_codec.plugged_cb &&
> +	    connector->hdmi_codec.plugged_cb_dev)
> +		connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev,
> +						 connector->hdmi_codec.last_state);
> +
> +	mutex_unlock(&connector->hdmi_codec.lock);
> +}
> +EXPORT_SYMBOL(drm_connector_hdmi_codec_plugged_notify);
> +
> +static const struct hdmi_codec_ops drm_connector_hdmi_codec_ops = {
> +	.audio_startup = drm_connector_hdmi_codec_audio_startup,
> +	.prepare = drm_connector_hdmi_codec_prepare,
> +	.audio_shutdown = drm_connector_hdmi_codec_audio_shutdown,
> +	.mute_stream = drm_connector_hdmi_codec_mute_stream,
> +	.get_eld = drm_connector_hdmi_codec_get_eld,
> +	.get_dai_id = drm_connector_hdmi_codec_get_dai_id,
> +	.hook_plugged_cb = drm_connector_hdmi_codec_hook_plugged_cb,
> +};
> +
> +/**
> + * drm_connector_hdmi_audio_init - Initialize HDMI Codec device for the DRM connector
> + * @connector: A pointer to the connector to allocate codec for
> + * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
> + * @funcs: callbacks for this HDMI Codec
> + * @max_i2s_playback_channels: maximum number of playback I2S channels
> + * @spdif_playback: set if HDMI codec has S/PDIF playback port
> + * @dai_port: sound DAI port, -1 if it is not enabled
> + *
> + * Create a HDMI codec device to be used with the specified connector.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int drm_connector_hdmi_audio_init(struct drm_connector *connector,
> +				  struct device *hdmi_codec_dev,
> +				  const struct drm_connector_hdmi_codec_funcs *funcs,
> +				  unsigned int max_i2s_playback_channels,
> +				  bool spdif_playback,
> +				  int dai_port)
> +{
> +	struct hdmi_codec_pdata codec_pdata = {
> +		.ops = &drm_connector_hdmi_codec_ops,
> +		.max_i2s_channels = max_i2s_playback_channels,
> +		.i2s = !!max_i2s_playback_channels,
> +		.spdif = spdif_playback,
> +		.no_i2s_capture = true,
> +		.no_spdif_capture = true,
> +		.data = connector,
> +	};
> +	struct platform_device *pdev;
> +
> +	if (!funcs ||
> +	    !funcs->prepare ||
> +	    !funcs->audio_shutdown)
> +		return -EINVAL;
> +
> +	connector->hdmi_codec.funcs = funcs;
> +	connector->hdmi_codec.dai_port = dai_port;
> +
> +	pdev = platform_device_register_data(hdmi_codec_dev,
> +					     HDMI_CODEC_DRV_NAME,
> +					     PLATFORM_DEVID_AUTO,
> +					     &codec_pdata, sizeof(codec_pdata));
> +	if (IS_ERR(pdev))
> +		return PTR_ERR(pdev);
> +
> +	connector->hdmi_codec.codec_pdev = pdev;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_connector_hdmi_audio_init);
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 1e2b25e204cb523d61d30f5409faa059bf2b86eb..536d604b6fb27368c43805a2ecf57fac06b3d472 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -46,6 +46,8 @@ struct drm_property_blob;
>  struct drm_printer;
>  struct drm_privacy_screen;
>  struct edid;
> +struct hdmi_codec_daifmt;
> +struct hdmi_codec_params;
>  struct i2c_adapter;
>  
>  enum drm_connector_force {
> @@ -1141,6 +1143,53 @@ struct drm_connector_state {
>  	struct drm_connector_hdmi_state hdmi;
>  };
>  
> +struct drm_connector_hdmi_codec_funcs {
> +	/**
> +	 * @audio_startup:
> +	 *
> +	 * Called when ASoC starts an audio stream setup. The
> +	 * @hdmi_audio_startup is optional.
> +	 *
> +	 * Returns:
> +	 * 0 on success, a negative error code otherwise
> +	 */
> +	int (*audio_startup)(struct drm_connector *connector);

With the naming comment I made on the previous version addressed, and
assuming it's been tested on a pi3 and pi4,

Acked-by: Maxime Ripard <mripard at kernel.org>

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

From mripard at kernel.org  Tue Dec 17 09:27:26 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 18:27:26 +0100
Subject: [PATCH v7 09/10] drm/vc4: hdmi: stop rereading EDID in
 get_modes()
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-9-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-drm-bridge-hdmi-connector-v7-9-cb9df2b6a515@linaro.org>
Message-ID: <20241217-optimal-chocolate-magpie-6c15c7@houat>

On Tue, Dec 17, 2024 at 02:40:31AM +0200, Dmitry Baryshkov wrote:
> The vc4_hdmi_connector_detect_ctx() via vc4_hdmi_handle_hotplug()
> already reads EDID and propagates it to the drm_connector. Stop
> rereading EDID as a part of the .get_modes() callback and just update
> the list of modes. This matches the behaviour of the i915 driver.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Assuming it's been tested:
Acked-by: Maxime Ripard <mripard at kernel.org>

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

From mripard at kernel.org  Tue Dec 17 09:28:16 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 18:28:16 +0100
Subject: [PATCH v7 10/10] drm/vc4: hdmi: use
 drm_atomic_helper_connector_hdmi_hotplug_edid()
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-10-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-drm-bridge-hdmi-connector-v7-10-cb9df2b6a515@linaro.org>
Message-ID: <20241217-orthodox-jellyfish-from-ganymede-a1d136@houat>

On Tue, Dec 17, 2024 at 02:40:32AM +0200, Dmitry Baryshkov wrote:
> Use the helper function to update the connector's information. This
> makes sure that HDMI-related events are handled in a generic way.
> Currently it is limited to the HDMI state reporting to the sound system.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

drm_atomic_helper_connector_hdmi_hotplug_edid in the commit title doesn't exist anymore :)

With that fixed, and assuming it's been tested
Acked-by: Maxime Ripard <mripard at kernel.org>

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

From markuss.broks at gmail.com  Tue Dec 17 09:28:57 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Tue, 17 Dec 2024 19:28:57 +0200
Subject: [PATCH 2/3] soc: samsung: Add a driver for Samsung SPEEDY host
 controller
In-Reply-To: <3c067b26-cfe8-4939-afce-5c8753767715@wanadoo.fr>
References: <20241212-speedy-v1-0-544ad7bcfb6a@gmail.com>
 <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
 <3c067b26-cfe8-4939-afce-5c8753767715@wanadoo.fr>
Message-ID: <9d7b9ee1-9b45-4892-826b-e2802adff990@gmail.com>

Hi Christophe,

On 12/14/24 5:52 PM, Christophe JAILLET wrote:
> Le 12/12/2024 ? 22:09, Markuss Broks a ?crit?:
>> Add a driver for Samsung SPEEDY serial bus host controller.
>> SPEEDY is a proprietary 1 wire serial bus used by Samsung
>> in various devices (usually mobile), like Samsung Galaxy
>> phones. It is usually used for connecting PMIC or various
>> other peripherals, like audio codecs or RF components.
>>
>> This bus can address at most 1MiB (4 bit device address,
>> 8 bit registers per device, 8 bit wide registers:
>> 256*256*16 = 1MiB of address space.
>
> ...
>
>> +static int _speedy_read(struct speedy_controller *speedy, u32 reg, 
>> u32 addr, u32 *val)
>> +{
>> +??? int ret;
>> +??? u32 cmd, int_ctl, int_status;
>> +
>> +??? mutex_lock(&speedy->io_lock);
>
> All error handling paths fail to release the mutex.
> guard(mutex) would help here.

True, I didn't know that such a thing existed, thanks for the tip! :)


>
>> +
>> +??? ret = speedy_fifo_reset(speedy);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
>> +????????????????? SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_READ |
>> +????????? SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
>> +
>> +??? int_ctl = SPEEDY_TRANSFER_DONE_EN | SPEEDY_FIFO_RX_ALMOST_FULL_EN |
>> +????????? SPEEDY_RX_FIFO_INT_TRAILER_EN | SPEEDY_RX_MODEBIT_ERR_EN |
>> +????????? SPEEDY_RX_GLITCH_ERR_EN | SPEEDY_RX_ENDBIT_ERR_EN |
>> +????????? SPEEDY_REMOTE_RESET_REQ_EN;
>> +
>> +??? ret = speedy_int_clear(speedy);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? /* Wait for xfer done */
>> +??? ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, 
>> int_status,
>> +?????????????????????? int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = regmap_read(speedy->map, SPEEDY_RX_DATA, val);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = speedy_int_clear(speedy);
>> +
>> +??? mutex_unlock(&speedy->io_lock);
>> +
>> +??? return ret;
>> +}
>
> ...
>
>> +static int _speedy_write(struct speedy_controller *speedy, u32 reg, 
>> u32 addr, u32 val)
>> +{
>> +??? int ret;
>> +??? u32 cmd, int_ctl, int_status;
>> +
>> +??? mutex_lock(&speedy->io_lock);
>> +
>> +??? ret = speedy_fifo_reset(speedy);
>> +??? if (ret)
>> +??????? return ret;
>
> All error handling paths fail to release the mutex.
> guard(mutex) would help here.
>
>> +
>> +??? ret = regmap_set_bits(speedy->map, SPEEDY_FIFO_CTRL,
>> +????????????????? SPEEDY_RX_LENGTH(1) | SPEEDY_TX_LENGTH(1));
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? cmd = SPEEDY_ACCESS_RANDOM | SPEEDY_DIRECTION_WRITE |
>> +????????? SPEEDY_DEVICE(reg) | SPEEDY_ADDRESS(addr);
>> +
>> +??? int_ctl = (SPEEDY_TRANSFER_DONE_EN |
>> +?????????? SPEEDY_FIFO_TX_ALMOST_EMPTY_EN |
>> +?????????? SPEEDY_TX_LINE_BUSY_ERR_EN |
>> +?????????? SPEEDY_TX_STOPBIT_ERR_EN |
>> +?????????? SPEEDY_REMOTE_RESET_REQ_EN);
>> +
>> +??? ret = speedy_int_clear(speedy);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = regmap_write(speedy->map, SPEEDY_INT_ENABLE, int_ctl);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = regmap_write(speedy->map, SPEEDY_CMD, cmd);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = regmap_write(speedy->map, SPEEDY_TX_DATA, val);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? /* Wait for xfer done */
>> +??? ret = regmap_read_poll_timeout(speedy->map, SPEEDY_INT_STATUS, 
>> int_status,
>> +?????????????????????? int_status & SPEEDY_TRANSFER_DONE, 5000, 50000);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? speedy_int_clear(speedy);
>> +
>> +??? mutex_unlock(&speedy->io_lock);
>> +
>> +??? return 0;
>> +}
>
> ...
>
>> +/**
>> + * speedy_get_by_phandle() - internal get speedy device handle
>> + * @np:??? pointer to OF device node of device
>> + *
>> + * Return: 0 on success, -errno otherwise
>
> On success, a handle is returned, not 0.
>
>> + */
>> +static const struct speedy_device *speedy_get_device(struct 
>> device_node *np)
>> +{
> ...
>
>> +out:
>> +??? of_node_put(speedy_np);
>> +??? return handle;
>> +}
>
> ...
>
>> +static int speedy_probe(struct platform_device *pdev)
>> +{
>> +??? struct device *dev = &pdev->dev;
>> +??? struct speedy_controller *speedy;
>> +??? void __iomem *mem;
>> +??? int ret;
>> +
>> +??? speedy = devm_kzalloc(dev, sizeof(struct speedy_controller), 
>> GFP_KERNEL);
>> +??? if (!speedy)
>> +??????? return -ENOMEM;
>> +
>> +??? platform_set_drvdata(pdev, speedy);
>> +??? speedy->pdev = pdev;
>> +
>> +??? mutex_init(&speedy->io_lock);
>> +
>> +??? mem = devm_platform_ioremap_resource(pdev, 0);
>> +??? if (IS_ERR(mem))
>> +??????? return dev_err_probe(dev, PTR_ERR(mem), "Failed to ioremap 
>> memory\n");
>> +
>> +??? speedy->map = devm_regmap_init_mmio(dev, mem, &speedy_map_cfg);
>> +??? if (IS_ERR(speedy->map))
>> +??????? return dev_err_probe(dev, PTR_ERR(speedy->map), "Failed to 
>> init the regmap\n");
>> +
>> +??? /* Clear any interrupt status remaining */
>> +??? ret = speedy_int_clear(speedy);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? /* Reset the controller */
>> +??? ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_SW_RST);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? msleep(20);
>> +
>> +??? /* Enable the hw */
>> +??? ret = regmap_set_bits(speedy->map, SPEEDY_CTRL, SPEEDY_ENABLE);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? msleep(20);
>> +
>> +??? /* Probe child devices */
>> +??? ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev);
>> +??? if (ret)
>> +??????? dev_err(dev, "Failed to populate child devices: %d\n", ret);
>
> Could be dev_err_probe() as well, at least for consistency.


I agree, will fix in the next revision.


>
>> +
>> +??? return ret;
>> +}
>
> ...
>
> CJ


- Markuss



From mripard at kernel.org  Tue Dec 17 09:24:52 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 17:24:52 +0000
Subject: [PATCH v7 06/10] drm/display/hdmi: implement hotplug functions
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-6-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-6-cb9df2b6a515@linaro.org>
Message-ID: <2dad2c52bb2babf3af0196f17c74a9fa@kernel.org>

On Tue, 17 Dec 2024 02:40:28 +0200, Dmitry Baryshkov wrote:
> The HDMI Connectors need to perform a variety of tasks when the HDMI
> connector state changes. Such tasks include setting or invalidating CEC
> address, notifying HDMI codec driver, updating scrambler data, etc.
> 
> Implementing such tasks in a driver-specific callbacks is error prone.
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From mripard at kernel.org  Tue Dec 17 09:25:06 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 17:25:06 +0000
Subject: [PATCH v7 07/10] drm/bridge_connector: hook
 drm_atomic_helper_connector_hdmi_hotplug()
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-7-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-7-cb9df2b6a515@linaro.org>
Message-ID: <b2ad15d2d5049701f34099e0df7fb727@kernel.org>

On Tue, 17 Dec 2024 02:40:29 +0200, Dmitry Baryshkov wrote:
> Extend drm_bridge_connector code to read the EDID and use it to update
> connector status if the bridge chain implements HDMI bridge. Performing
> it from the generic location minimizes individual bridge's code and
> enforces standard behaviour from all corresponding drivers.
> 
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From manivannan.sadhasivam at linaro.org  Tue Dec 17 09:25:02 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Tue, 17 Dec 2024 22:55:02 +0530
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <d976d74c-80c0-4446-bb9b-960a990c552b@foss.st.com>
References: <20241205172022.GA3053765@bhelgaas>
 <d976d74c-80c0-4446-bb9b-960a990c552b@foss.st.com>
Message-ID: <20241217172502.borj2oy4rpxcteag@thinkpad>

On Tue, Dec 17, 2024 at 04:53:48PM +0100, Christian Bruel wrote:
> 
> > Makes sense.  What about phys, resets, etc?  I'm pretty sure a PHY
> > would be a per-Root Port thing, and some resets and wakeup signals
> > also.
> > 
> > For new drivers, I think we should start adding Root Port stanzas to
> > specifically associate those things with the Root Port, e.g.,
> > something like this?
> > 
> >    pcie at 48400000 {
> >      compatible = "st,stm32mp25-pcie-rc";
> > 
> >      pcie at 0,0 {
> >        reg = <0x0000 0 0 0 0>;
> >        phys = <&combophy PHY_TYPE_PCIE>;
> >        phy-names = "pcie-phy";
> >      };
> >    };
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pci/mediatek,mt7621-pcie.yaml?id=v6.12#n111
> > is one binding that does this, others include apple,pcie.yaml,
> > brcm,stb-pcie.yaml, hisilicon,kirin-pcie.yaml.
> > 
> 
> On a second thought, moving the PHY to the root-port part would introduce a
> discrepancy with the pcie_ep binding, whereas the PHY is required on the
> pcie_ep node.
> 
> Even for the pcie_rc, the PHY is needed to enable the core_clk to access
> the PCIe core registers,
> 

But why that matters? You can still parse the child nodes, enable PHY and
configure PCIe registers.

> So that would make 2 different required PHY locations for RC and EP:
> 
>     pcie_rc: pcie at 48400000 {
>       compatible = "st,stm32mp25-pcie-rc";
> 
>       pcie at 0,0 {
>         reg = <0x0000 0 0 0 0>;
>         phys = <&combophy PHY_TYPE_PCIE>;
>         phy-names = "pcie-phy";
>       };
>     };
> 
>     pcie_ep pcie at 48400000 {
>       compatible = "st,stm32mp25-pcie-ep";
>       phys = <&combophy PHY_TYPE_PCIE>;
>       phy-names = "pcie-phy";
>     };
> 
> Simplest seems to keep the PHY required for the pcie core regardless of the
> mode and keep the empty root port to split the design
> 

No please. Try to do the right thing from the start itself.

- Mani

-- 
????????? ????????


From mripard at kernel.org  Tue Dec 17 09:26:52 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Dec 2024 18:26:52 +0100
Subject: [PATCH v7 08/10] drm/vc4: hdmi: switch to using generic HDMI
 Codec infrastructure
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-8-cb9df2b6a515@linaro.org>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-drm-bridge-hdmi-connector-v7-8-cb9df2b6a515@linaro.org>
Message-ID: <20241217-maize-jackrabbit-of-valor-3e7272@houat>

On Tue, Dec 17, 2024 at 02:40:30AM +0200, Dmitry Baryshkov wrote:
> Drop driver-specific implementation and use the generic HDMI Codec
> framework in order to implement the HDMI audio support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Assuming it's been tested:

Acked-by: Maxime Ripard <mripard at kernel.org>

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

From markuss.broks at gmail.com  Tue Dec 17 09:31:05 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Tue, 17 Dec 2024 19:31:05 +0200
Subject: [PATCH 2/3] soc: samsung: Add a driver for Samsung SPEEDY host
 controller
In-Reply-To: <44419be4-65b3-41eb-a696-cfefae84a423@web.de>
References: <20241212-speedy-v1-2-544ad7bcfb6a@gmail.com>
 <44419be4-65b3-41eb-a696-cfefae84a423@web.de>
Message-ID: <6b257549-b166-4772-a824-894b4b84e322@gmail.com>

Hi Markus,

On 12/14/24 4:43 PM, Markus Elfring wrote:
> ?
>> SPEEDY is a proprietary 1 wire serial bus used by Samsung
>> in various devices ?
> You may occasionally put more than 57 characters into text lines
> of such a change description.

But does it really matter where I break the line? For me, it just seems 
ugly no matter where I do it...

>
>
> ?
>> +++ b/drivers/soc/samsung/exynos-speedy.c
>> @@ -0,0 +1,457 @@
> ?
>> +static int _speedy_read(struct speedy_controller *speedy, u32 reg, u32 addr, u32 *val)
>> +{
>> +	int ret;
>> +	u32 cmd, int_ctl, int_status;
>> +
>> +	mutex_lock(&speedy->io_lock);
> ?
>> +	ret = speedy_int_clear(speedy);
>> +
>> +	mutex_unlock(&speedy->io_lock);
>> +
>> +	return ret;
>> +}
> ?
>
> Under which circumstances would you become interested to apply a statement
> like ?guard(mutex)(&speedy->io_lock);??
> https://elixir.bootlin.com/linux/v6.13-rc2/source/include/linux/mutex.h#L201


I did not know such statement existed, thanks for the tip, it definitely 
helps and makes it simpler!


>
> Regards,
> Markus


- Markuss



From dianders at chromium.org  Tue Dec 17 09:44:13 2024
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 17 Dec 2024 09:44:13 -0800
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <CAODwPW8s4GhWGuZMUbWVNLYw_EVJe=EeMDacy1hxDLmnthwoFg@mail.gmail.com>
References: <20241214005248.198803-1-dianders@chromium.org>
 <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
 <CAODwPW_c+Ycu_zhiDOKN-fH2FEWf2pxr+FcugpqEjLX-nVjQrg@mail.gmail.com>
 <CAD=FV=UHBA7zXZEw3K6TRpZEN-ApOkmymhRCOkz7h+yrAkR_Dw@mail.gmail.com> <CAODwPW8s4GhWGuZMUbWVNLYw_EVJe=EeMDacy1hxDLmnthwoFg@mail.gmail.com>
Message-ID: <CAD=FV=X61y+RmbWCiZut_HHVS4jPdv_ZB8F+_Hs0R-1aKHdK4w@mail.gmail.com>

Hi,

On Tue, Dec 17, 2024 at 5:25?AM Julius Werner <jwerner at chromium.org> wrote:
>
> > > - Refactor max_bhb_k in spectre_bhb_loop_affected() to be a global
> > > instead, which starts out as zero, is updated by
> > > spectre_bhb_loop_affected(), and is directly read by
> > > spectre_bhb_patch_loop_iter() (could probably remove the `scope`
> > > argument from spectre_bhb_loop_affected() then).
> >
> > Refactoring "max_bhb_k" would be a general cleanup and not related to
> > anything else here, right?
> >
> > ...but the function is_spectre_bhb_affected() is called from
> > "cpu_errata.c" and has a scope. Can we guarantee that it's always
> > "SCOPE_LOCAL_CPU"? I tried reading through the code and it's
> > _probably_ SCOPE_LOCAL_CPU most of the time, but it doesn't seem worth
> > it to add an assumption here for a small cleanup.
> >
> > I'm not going to do this, though I will move "max_bhb_k" to be a
> > global for the suggestion below.
>
> If you make max_bhb_k a global, then whether you change all
> `spectre_bhb_loop_affected(SCOPE_SYSTEM)` calls to read the global
> directly or whether you keep it such that
> `spectre_bhb_loop_affected()` simply returns that global for
> SCOPE_SYSTEM makes no difference. I just think reading the global
> directly would look a bit cleaner. Calling a function that's called
> "...affected()" when you're really just trying to find out the K-value
> feels a bit odd.
>
> For is_spectre_bhb_affected(), I was assuming the change below where
> you combine all the `return true` paths, so the scope question
> wouldn't matter there.

Ah, right. OK.


> > > - Change the `return false` into `return true` at the end of
> > > is_spectre_bhb_affected (in fact, you can probably take out some of
> > > the other calls that result in returning true as well then)
> >
> > I'm not sure you can take out the other calls. Specifically, both
> > spectre_bhb_loop_affected() and is_spectre_bhb_fw_affected() _need_ to
> > be called for each CPU so that they update static globals, right?
> > Maybe we could get rid of the call to supports_clearbhb(), but that
> > _would_ change things in ways that are not obvious. Specifically I
> > could believe that someone could have backported "clear BHB" to their
> > core but their core is otherwise listed as "loop affected". That would
> > affect "max_bhb_k". Maybe (?) it doesn't matter in this case, but I'd
> > rather not mess with it unless someone really wants me to and is sure
> > it's safe.
>
> Yes, but spectre_bhb_enable_mitigation() already calls all those
> functions on its own again anyway, so I'm pretty sure the "must be
> called once for each CPU" part of spectre_bhb_loop_affected() is
> covered by that. (Besides, it would be really awful if they had made a
> function whose name starts with is_... have critical side-effects that
> break things when it doesn't get called.)

The existing predicates already do change globals before my patch and
changing that is outside of the scope of what I'm willing to entertain
with my patchset

Given that I'm not going to change the way the existing predicates
work, if I move the "fallback" setting `max_bhb_k` to 32 to
spectre_bhb_enable_mitigation() then when we set `max_bhb_k` becomes
inconsistent between recognized and unrecognized CPUs. One gets set in
the predicate and one doesn't. Even if it works, this inconsistency
feels like bad design to me. Also, setting `max_bhb_k` to the max at
the end of is_spectre_bhb_affected() would perhaps _help_ someone
realize that the predicate has side effects because they'd see it in
the function itself and not have to dig down.

I would also say that having `max_bhb_k` get set in an inconsistent
place opens us up for bugs in the future. Even if it works today, I
imagine someone could change things in the future such that
spectre_bhb_enable_mitigation() reads `max_bhb_k` and essentially
caches it (maybe it constructs an instruction based on it). If that
happened things could be subtly broken for the "unrecognized CPU" case
because the first CPU would "cache" the value without it having been
called on all CPUs.

In case you can't tell, I'm still not convinced and will plan to keep
setting `max_bhb_k = 32` in is_spectre_bhb_affected().


> > > - In spectre_bhb_enable_mitigations(), at the end of the long if-else
> > > chain, put a last else block that prints your WARN_ONCE(), sets the
> > > max_bhb_k global to 32, and then does the same stuff that the `if
> > > (spectre_bhb_loop_affected())` block would have installed (maybe
> > > factoring that out into a helper function called from both cases).
> >
> > ...or just reorder it so that the spectre_bhb_loop_affected() code is
> > last and it can be the "else". Then I can WARN_ONCE() if
> > spectre_bhb_loop_affected(). ...or I could just do the WARN_ONCE()
> > when I get to the end of is_spectre_bhb_affected() and set "max_bhb_k"
> > to 32 there. I'd actually rather do that so that "max_bhb_k" is
> > consistently set after is_spectre_bhb_affected() is called on all
> > cores regardless of whether or not some cores are unknown.
>
> Yeah, you can reorder the loops too. I don't feel like moving this
> into is_spectre_bhb_affected() would be a good idea. Functions with a
> predicate name like that really shouldn't have such side effects.
> Besides, I think is_spectre_bhb_affected() is probably called more
> often per CPU, both once from spectre_bhb_enable_mitigation() and by
> whatever calls the `matches` pointer in the cpu_errata struct.
> spectre_bhb_enable_mitigation() seems to be the function that's called
> once for each CPU on boot to install the correct mitigation, so that
> feels like the best spot to put the fallback logic to me.

As per above, while I agree that having predicate functions w/ side
effects is not ideal, that predates my patch series and I'd rather
things work consistently.

-Doug


From alain.volmat at foss.st.com  Tue Dec 17 09:41:44 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:41:44 +0100
Subject: [PATCH v4 02/15] dt-bindings: media: add description of stm32 csi
In-Reply-To: <Z17JItE-98IIrnMv@valkosipuli.retiisi.eu>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
 <20241212-csi_dcmipp_mp25-v4-2-fbeb55a05ed7@foss.st.com>
 <Z17JItE-98IIrnMv@valkosipuli.retiisi.eu>
Message-ID: <20241217174144.GA3784949@gnbcxd0016.gnb.st.com>

Hi Sakari,

On Sun, Dec 15, 2024 at 12:18:42PM +0000, Sakari Ailus wrote:
> Hi Alain,
> 
> On Thu, Dec 12, 2024 at 10:17:26AM +0100, Alain Volmat wrote:
> > Add the stm32 csi controller description.
> > 
> > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> > Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> > ---
> > v2:
> >   - rename into st,stm32mp25-csi.yaml to match compatible
> >   - correct port / data-lanes (remove useless lines &
> >     use data-lanes 1 and 2 instead of 0 and 1)
> >   - correct commit log
> > ---
> >  .../bindings/media/st,stm32mp25-csi.yaml           | 125 +++++++++++++++++++++
> >  1 file changed, 125 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> > new file mode 100644
> > index 000000000000..33bedfe41924
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> > @@ -0,0 +1,125 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/media/st,stm32mp25-csi.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: STMicroelectronics STM32 CSI controller
> > +
> > +description:
> > +  The STM32 CSI controller allows connecting a CSI based
> > +  camera to the DCMIPP camera pipeline.
> 
> CSI-2 I presume?
> 
> You should also document it here it has D-PHY...
> 
> > +
> > +maintainers:
> > +  - Alain Volmat <alain.volmat at foss.st.com>
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - st,stm32mp25-csi
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 3
> > +
> > +  clock-names:
> > +    items:
> > +      - const: pclk
> > +      - const: txesc
> > +      - const: csi2phy
> > +
> > +  resets:
> > +    maxItems: 1
> > +
> > +  vdd-supply:
> > +    description: Digital core power supply (0.91V)
> > +
> > +  vdda18-supply:
> > +    description: System analog power supply (1.8V)
> > +
> > +  access-controllers:
> > +    minItems: 1
> > +    maxItems: 2
> > +
> > +  ports:
> > +    $ref: /schemas/graph.yaml#/properties/ports
> > +
> > +    properties:
> > +      port at 0:
> > +        $ref: /schemas/graph.yaml#/$defs/port-base
> > +        unevaluatedProperties: false
> > +        description:
> > +          Input port node
> > +
> > +        properties:
> > +          endpoint:
> > +            $ref: video-interfaces.yaml#
> > +            unevaluatedProperties: false
> > +
> > +            properties:
> > +              data-lanes:
> > +                minItems: 1
> > +                items:
> > +                  - const: 1
> > +                  - const: 2
> > +
> > +            required:
> > +              - data-lanes
> > +
> > +      port at 1:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description:
> > +          Output port node
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - clocks
> > +  - clock-names
> > +  - resets
> > +  - ports
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/media/video-interfaces.h>
> > +    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
> > +    csi at 48020000 {
> > +        compatible = "st,stm32mp25-csi";
> > +        reg = <0x48020000 0x2000>;
> > +        interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
> > +        resets = <&rcc CSI_R>;
> > +        clocks = <&rcc CK_KER_CSI>, <&rcc CK_KER_CSITXESC>, <&rcc CK_KER_CSIPHY>;
> > +        clock-names = "pclk", "txesc", "csi2phy";
> > +
> > +        ports {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +            port at 0 {
> > +                reg = <0>;
> > +                endpoint {
> > +                    remote-endpoint = <&imx335_ep>;
> > +                    data-lanes = <1 2>;
> > +                    bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
> 
> ...and drop bus-type property.
> 
> > +                };
> > +            };
> > +
> > +            port at 1 {
> > +                reg = <1>;
> > +                endpoint {
> > +                    remote-endpoint = <&dcmipp_0>;
> > +                };
> > +            };
> > +        };
> > +    };
> > +
> > +...
> > 

all 3 points corrected within the new serie I just pushed on top of this
one since it has already been merged.

Regards,

Alain


From nathan at kernel.org  Tue Dec 17 09:46:28 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Tue, 17 Dec 2024 10:46:28 -0700
Subject: [PATCH] media: mediatek: vcodec: mark
 vdec_vp9_slice_map_counts_eob_coef noinline
In-Reply-To: <20241119110226.dbd54clp46klvjl5@basti-XPS-13-9310>
References: <20241018151448.3694052-1-arnd@kernel.org>
 <20241118200641.GA768549@thelio-3990X>
 <20241119110226.dbd54clp46klvjl5@basti-XPS-13-9310>
Message-ID: <20241217174628.GA2654633@ax162>

Hi Sebastian,

On Tue, Nov 19, 2024 at 12:02:26PM +0100, Sebastian Fricke wrote:
> Hey Nathan,
> 
> On 18.11.2024 13:06, Nathan Chancellor wrote:
> > On Fri, Oct 18, 2024 at 03:14:42PM +0000, Arnd Bergmann wrote:
> > > From: Arnd Bergmann <arnd at arndb.de>
> > > 
> > > With KASAN enabled, clang fails to optimize the inline version of
> > > vdec_vp9_slice_map_counts_eob_coef() properly, leading to kilobytes
> > > of temporary values spilled to the stack:
> > > 
> > > drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c:1526:12: error: stack frame size (2160) exceeds limit (2048) in 'vdec_vp9_slice_update_prob' [-Werror,-Wframe-larger-than]
> > > 
> > > This seems to affect all versions of clang including the latest (clang-20),
> > > but the degree of stack overhead is different per release.
> > > 
> > > Marking the function as noinline_for_stack is harmless here and avoids
> > > the problem completely.
> > > 
> > > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> > 
> > Unfortunately, I have seen no moment on my upstream report and this
> > warning is breaking allmodconfig builds because of -Werror. Can this be
> > applied as a workaround for now (preferrably with a Cc: stable on it)?
> > 
> > Reviewed-by: Nathan Chancellor <nathan at kernel.org>
> 
> I'll handle it asap, it will be part of 6.13

Is there any update here? I don't see this patch applied in -next.

Cheers,
Nathan

> > > ---
> > > I have not come to a conclusion on how exactly clang fails to do this
> > > right, but can provide the .config and/or preprocessed source files
> > > and command line if we think this should be fixed in clang.
> > > ---
> > >  .../mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c         | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > 
> > > 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 eea709d93820..47c302745c1d 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
> > > @@ -1188,7 +1188,8 @@ static int vdec_vp9_slice_setup_lat(struct vdec_vp9_slice_instance *instance,
> > >  	return ret;
> > >  }
> > > 
> > > -static
> > > +/* clang stack usage explodes if this is inlined */
> > > +static noinline_for_stack
> > >  void vdec_vp9_slice_map_counts_eob_coef(unsigned int i, unsigned int j, unsigned int k,
> > >  					struct vdec_vp9_slice_frame_counts *counts,
> > >  					struct v4l2_vp9_frame_symbol_counts *counts_helper)
> > > --
> > > 2.39.5
> > > 
> > 


From mhklinux at outlook.com  Tue Dec 17 09:48:00 2024
From: mhklinux at outlook.com (Michael Kelley)
Date: Tue, 17 Dec 2024 17:48:00 +0000
Subject: [PATCH 0/2] hyperv: Move some features to common code
In-Reply-To: <6cf69fbd-b6a0-4e88-85a6-749a4e2dbdaa@linux.microsoft.com>
References: <1733523707-15954-1-git-send-email-nunodasneves@linux.microsoft.com>
 <SN6PR02MB41573F55DBAAF124CFD92840D4332@SN6PR02MB4157.namprd02.prod.outlook.com>
 <6cf69fbd-b6a0-4e88-85a6-749a4e2dbdaa@linux.microsoft.com>
Message-ID: <SN6PR02MB415783BB8A3844F5ADD142B2D4042@SN6PR02MB4157.namprd02.prod.outlook.com>

From: Nuno Das Neves <nunodasneves at linux.microsoft.com> Sent: Monday, December 9, 2024 12:20 PM
> 
> On 12/7/2024 6:59 PM, Michael Kelley wrote:
> > From: Nuno Das Neves <nunodasneves at linux.microsoft.com> Sent: Friday, December 6, 2024 2:22 PM
> >>
> >> There are several bits of Hyper-V-related code that today live in
> >> arch/x86 but are not really specific to x86_64 and will work on arm64
> >> too.
> >>
> >> Some of these will be needed in the upcoming mshv driver code (for
> >> Linux as root partition on Hyper-V).
> >
> > Previously, Linux as the root partition on Hyper-V was x86 only, which is
> > why the code is currently under arch/x86. So evidently the mshv driver
> > is being expanded to support both x86 and arm64, correct? Assuming
> > that's the case, I have some thoughts about how the source code should
> > be organized and built. It's probably best to get this right to start with so
> > it doesn't need to be changed again.
> 
> Yes, we plan on supporting both architectures (eventually). I completely agree
> that it's better to sort out these issues now rather than later.
> 
> >
> > * Patch 2 of this series moves hv_call_deposit_pages() and
> >    hv_call_create_vp() to common code, but does not move
> >    hv_call_add_logical_proc(). All three are used together, so
> >    I'm wondering why hv_call_add_logical_proc() isn't moved.
> >
> 
> The only reason is that in our internal tree there's no common or arm64 code
> yet that uses it - there is no reason it can't also become common code!

Maybe I'm missing your point, but hv_call_add_logical_proc() and
hv_call_create_vp() are called in succession in hv_smp_prepare_cpus(),
so it seems like they very much go together. Presumably a similar
sequence will be needed on the arm64 side when running as the
root partition?

> 
> > * These three functions were originally put in a separate source
> >    code file because of being specific to running in the root partition,
> >    and not needed for generic Linux guest support. I think there's
> >    value in keeping them in a separate file, rather than merging them
> >    into hv_common.c. Maybe just move the entire hv_proc.c file?
> 
> Agreed. I think it should be renamed too - this file will eventually
> contain some additional hypercall helper functions, some of which may also be
> shared by the driver code. Something like "hv_call_common.c"?

I went back and looked at your patch series from a year ago [1], and
got a better understanding of where this work is headed. I wanted
to comment on that series back then, but got subsumed in wrapping
things up for my retirement. :-(  I see significant portions of that
series have been posted independently and accepted, so my further
comments here assume the rest of the series is still the macro-level
approach you are taking.

>From that series, you are planning three modules, controlled by
CONFIG_MSHV, CONFIG_MSHV_ROOT, and CONFIG_MSHV_VTL.
That makes sense, and addresses one of my top-level concerns,
which is that normal guest kernels shouldn't include all that code.
And apparently that code works as a module as well as built-in.

The code currently in hv_proc.c is similar to the code in hv_call.c
and mshv_root_hv_call.c from that series -- it's a wrapper around
Hyper-V hypercalls. But a difference is that the code in hv_proc.c
can't be a module because it is called from hv_smp_prepare_cpus(),
which must be built-in. So it can't be added to the proposed
hv_call.c without making all of hv_call.c built-in. Ideally, there
would be a separate source file just for the code that must be
built-in. I'm not familiar enough with root partition requirements
to understand what hv_smp_prepare_cpus() and its calls to
hv_call_add_logical_proc() and hv_call_create_vp() are doing.
Evidently it is related to bringing up CPUs in the root partition,
and not related to guest VMs. But those two hv_call_* functions
would also be used for managing guest VMs from /dev/mshv.

As for the name, I don't really like "common", even though I'm the
one who created "hv_common.c" back when doing the initial arm64
support on Hyper-V. :-( My thinking is that anything that isn't under
arch/x86 or arch/arm64 is by definition shared across architectures,
so having "common" in the name is superfluous. Maybe just
staying with hv_proc.c is OK.

> 
> >    And then later, perhaps move the entire irqdomain.c file as well?
> Yes, may as well move it too.

irqdomain.c is also in that category of needing to be built-in. But
looking more closely, it is x86 specific and should stay where it is. I
can't immediately tell whether it's feasible to make the Hyper-V
IOMMU driver (and irqdomain.c) architecture neutral, or whether
a separate arm64 implementation will be needed. My guess is the
latter.

> 
> >    There's also an interesting question of whether to move them into
> >    drivers/hv, or create a new directory virt/hyperv. Hyper-V support
> >    started out 15 years ago structured as a driver, hence "drivers/hv".
> >    But over the time, the support has become significantly more than
> >    just a driver, so "virt/hyperv" might be a better location for
> >    non-driver code that had previously been under arch/x86 but is
> >    now common to all architectures.
> >
> I'd be fine with using "virt/hyperv", but I thought "virt" was only for
> KVM.

Now that I see the bigger picture from your previous patch series,
keeping the files in drivers/hv seems OK to me. The 'mshv' code *is*
a driver that implements /dev/mshv. :-)

> 
> Another option would be to create subdirectories in "drivers/hv" to
> organize the different modules more cleanly (i.e. when the /dev/mshv
> driver code is introduced).

Putting all the mshv and "running as root partition" files in a single
sub-directory might make sense. Multiple sub-directories might be
overkill. But I don't have a strong opinion either way. Putting them
all directly in drivers/hv seems OK, as does one or more sub-directories.

One thing I encountered back when first doing the arm64 support is
that everything in the drivers/hv directory could be built as a module.
The Hyper-V support under arch/x86 was always built-in, and the
arch/arm64 code I added was as well. But there was no obvious place
to put common code that must always be built-in. At the time, I thought
about introducing virt/hyperv, but had only a single relatively small source
code file, and introducing that new pathname with its own Makefile, etc.
seemed like overkill. So drivers/hv/hv_common.c came into existence. I
tweaked the existing drivers/hv/Makefile so hv_common.c is always
built-in even when CONFIG_HYPERV=m. It's a little messy, but not too
bad.

The difference in what can be built as a module vs. must be built-in
might be a factor in the directory structure, along with the
CONFIG options that control whether the root partition code
gets built at all (see below). The details will govern what works
well and what ends up being a bit of a mess.

> 
> > * Today, the code for running in the root partition is built along
> >    with the rest of the Hyper-V support, and so is present in kernels
> >    built for normal Linux guests on Hyper-V. I haven't thought about
> >    all the implications, but perhaps there's value in having a CONFIG
> >    option to build for the root partition, so that code can be dropped
> >    from normal kernels. There's a significant amount of new code still
> >    to come for mshv that could be excluded from normal guests in this
> >    way. Also, the tests of the hv_root_partition variable could be
> >    changed to a function the compiler detects is always "false" in a
> >    kernel built without the CONFIG option, in which case it can drop
> >    the code for where hv_root_partition is "true".
> >
> Using hv_root_partition is a good way to do it, since it won't require
> many #ifdefs or moving the existing code around too much.
> 
> I can certainly give it a try, and create a separate patch series
> introducing the option. I suppose "CONFIG_HYPERV_ROOT" makes sense as a
> name?

Now that I see you have CONFIG_MSHV, CONFIG_MSHV_ROOT, and
CONFIG_MSHV_VTL planned, could building the hv_root_partition code
just be under control of CONFIG_MSHV_ROOT without introducing
another CONFIG variable? Is any of the root partition code like
hv_proc.c and irqdomain.c needed if CONFIG_MSHV_ROOT=n?
Stubs will be needed for functions called from the generic kernel code
when CONFIG_MSHV_ROOT=n, but those are easily supplied in
asm/mshyperv.h. If hv_root_partition becomes a function whose
return value is gated by CONFIG_MSHV_ROOT, then the compiler
can know when the value is always "false" and drop even the code
that calls the stubs. But I'm pretty sure the stubs are still needed to
avoid compile errors, even when the compiler drops the code.

With this approach, you can avoid #ifdefs except in asm/mshyperv.h
for the stubs, and in the hv_root_partition() function.

One more code structure topic:  In the previous patch series,
some of the mshv code is x86 specific. There is x86 assembler
code, and references to x86 specific registers (all the HV_X64_*
registers). Do you plan to put architecture specific code under
drivers/hv, or under arch/[x86/arm64]/hyperv? We've made
drivers/hv be architecture neutral -- currently there's only one
"cheat" with an #ifdef CONFIG_ARM64 in the hv_balloon.c driver
that turns off some functionality.

As we discussed previously, the new Hyper-V #include files
provide the union of x86 and arm64 definitions, with just an
occasional #ifdef where needed. That was justified because
that's how the definitions come from the Windows/Hyper-V
world. But it seems like the mshv code should be structured
with arch specific code is under arch, not in drivers/hv with
#ifdefs. The Makefiles in arch/[x86,arm64]/hyperv will need
to use CONFIG_MSHV, CONFIG_MSHV_ROOT, and
CONFIG_MSHV_VTL to decide what to build, and whether to
build as a module vs. built-in.

Maybe putting the mshv code in a "mshv" subdirectory under
both drivers/hv and arch/[x86,arm64]/hyperv would conceptually
help tie together the arch neutral and arch specific portions.
Or something like that ....

> 
> > * The code currently in hv_proc.c is built for x86 only, and validly
> >    assumes the page size is 4K. But when the code moves to be
> >    common across architectures, that assumption is no longer
> >    valid in the general case. Perhaps the intent is that kernels for
> >    the root partition should always be built with page size 4K on
> >    arm64, but nothing enforces that intent. Personally, I think the code
> >    should be made to work with page sizes other than 4K so as to not
> >    leave technical debt. But I realize you may have other priorities. If
> >    there were a CONFIG option for building for the root partition,
> >    that option could be setup to enforce the 4K page size on arm64.
> >
> That makes sense. I suppose this can be done by selecting PAGE_SIZE_4KB
> under HYPERV in drivers/hv/Kconfig?

Since the PAGE_SIZE value is independently selectable in the .config
file, I'm not sure if you can override it when CONFIG_MSHV_ROOT is
set. But you can allow CONFIG_MSHV_ROOT to be set only if
PAGE_SIZE_4KB is selected on arm64. I'd have to look in more detail
to figure out the best way to create an appropriate dependency.

> 
> I'm not how easy it will be to make the code work with different page
> sizes, since we use alloc_page() and similar in a few places, assuming 4k.

alloc_page() is not the problem as it is relatively easy to break up a
16K or 64K page into multiple 4K pages when depositing memory.
And you can round up the amount of deposited memory to the
larger boundary without doing any harm. But in your previous patch
series, I see hv_call_withdraw_memory(), wherein Hyper-V gives
back individual 4K pages in no particular order. That's the killer, as
it is not feasible to re-assemble a random set of 4K pages into larger
16K or 64K pages for free_page().

So scratch that idea. :-( The root partition must run with a page
size that matches the size Hyper-V uses to do memory deposits to
and from a partition, and that's 4K.

Michael

[1] https://lore.kernel.org/lkml/1696010501-24584-1-git-send-email-nunodasneves at linux.microsoft.com/


From alain.volmat at foss.st.com  Tue Dec 17 09:45:57 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:45:57 +0100
Subject: [PATCH v4 03/15] media: stm32: csi: addition of the STM32 CSI
 driver
In-Reply-To: <Z17OR258tjFZJq9K@valkosipuli.retiisi.eu>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
 <20241212-csi_dcmipp_mp25-v4-3-fbeb55a05ed7@foss.st.com>
 <Z17OR258tjFZJq9K@valkosipuli.retiisi.eu>
Message-ID: <20241217174557.GB3784949@gnbcxd0016.gnb.st.com>

Hi Sakari,

On Sun, Dec 15, 2024 at 12:40:39PM +0000, Sakari Ailus wrote:
> Hi Alain,
> 
> On Thu, Dec 12, 2024 at 10:17:27AM +0100, Alain Volmat wrote:
> > The STM32 CSI controller is tightly coupled with the DCMIPP and act as an
> > input stage to receive data coming from the sensor and transferring
> > them into the DCMIPP.
> > 
> > Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> > 
> > ---
> > v3: get reset controller within probe function and remove it
> >     from the driver structure
> >     use devm_clk_bulk apis rather 3 separate clks
> > 
> > v2: correct data-lanes handling, using values 1 & 2
> >     update yaml filename in MAINTAINERS
> > ---
> >  MAINTAINERS                                 |    8 +
> >  drivers/media/platform/st/stm32/Kconfig     |   14 +
> >  drivers/media/platform/st/stm32/Makefile    |    1 +
> >  drivers/media/platform/st/stm32/stm32-csi.c | 1137 +++++++++++++++++++++++++++
> >  4 files changed, 1160 insertions(+)
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 1e930c7a58b1..2ffa10e38e52 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -14495,6 +14495,14 @@ W:	https://linuxtv.org
> >  T:	git git://linuxtv.org/media.git
> >  F:	drivers/media/dvb-frontends/stv6111*
> >  
> > +MEDIA DRIVERS FOR STM32 - CSI
> > +M:	Alain Volmat <alain.volmat at foss.st.com>
> > +L:	linux-media at vger.kernel.org
> > +S:	Supported
> > +T:	git git://linuxtv.org/media_tree.git
> > +F:	Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> > +F:	drivers/media/platform/stm32/stm32-csi.c
> > +
> >  MEDIA DRIVERS FOR STM32 - DCMI / DCMIPP
> >  M:	Hugues Fruchet <hugues.fruchet at foss.st.com>
> >  M:	Alain Volmat <alain.volmat at foss.st.com>
> > diff --git a/drivers/media/platform/st/stm32/Kconfig b/drivers/media/platform/st/stm32/Kconfig
> > index 9df9a2a17728..f12e67bcc9bc 100644
> > --- a/drivers/media/platform/st/stm32/Kconfig
> > +++ b/drivers/media/platform/st/stm32/Kconfig
> > @@ -1,6 +1,20 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >  
> >  # V4L drivers
> > +config VIDEO_STM32_CSI
> > +	tristate "STM32 Camera Serial Interface (CSI) support"
> > +	depends on V4L_PLATFORM_DRIVERS
> > +	depends on VIDEO_DEV && OF
> > +	depends on ARCH_STM32 || COMPILE_TEST
> > +	select MEDIA_CONTROLLER
> > +	select V4L2_FWNODE
> > +	help
> > +	  This module makes the STM32 Camera Serial Interface (CSI)
> > +	  available as a v4l2 device.
> > +
> > +	  To compile this driver as a module, choose M here: the module
> > +	  will be called stm32-csi.
> > +
> >  config VIDEO_STM32_DCMI
> >  	tristate "STM32 Digital Camera Memory Interface (DCMI) support"
> >  	depends on V4L_PLATFORM_DRIVERS
> > diff --git a/drivers/media/platform/st/stm32/Makefile b/drivers/media/platform/st/stm32/Makefile
> > index 7ed8297b9b19..9ae57897f030 100644
> > --- a/drivers/media/platform/st/stm32/Makefile
> > +++ b/drivers/media/platform/st/stm32/Makefile
> > @@ -1,4 +1,5 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> > +obj-$(CONFIG_VIDEO_STM32_CSI) += stm32-csi.o
> >  obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32-dcmi.o
> >  obj-$(CONFIG_VIDEO_STM32_DCMIPP) += stm32-dcmipp/
> >  stm32-dma2d-objs := dma2d/dma2d.o dma2d/dma2d-hw.o
> > diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
> > new file mode 100644
> > index 000000000000..48941aae8c9b
> > --- /dev/null
> > +++ b/drivers/media/platform/st/stm32/stm32-csi.c
> > @@ -0,0 +1,1137 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Driver for STM32 Camera Serial Interface
> > + *
> > + * Copyright (C) STMicroelectronics SA 2024
> > + * Author: Alain Volmat <alain.volmat at foss.st.com>
> > + * for STMicroelectronics.
> > + */
> > +
> > +#include <linux/clk.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>
> > +#include <linux/reset.h>
> > +#include <linux/slab.h>
> > +
> > +#include <media/mipi-csi2.h>
> > +#include <media/v4l2-fwnode.h>
> > +#include <media/v4l2-subdev.h>
> > +
> > +#define STM32_CSI_CR				0x0000
> > +#define STM32_CSI_CR_CSIEN			BIT(0)
> > +#define STM32_CSI_CR_VCXSTART(x)		BIT(2 + ((x) * 4))
> > +#define STM32_CSI_CR_VCXSTOP(x)			BIT(3 + ((x) * 4))
> > +#define STM32_CSI_PCR				0x0004
> > +#define STM32_CSI_PCR_DL1EN			BIT(3)
> > +#define STM32_CSI_PCR_DL0EN			BIT(2)
> > +#define STM32_CSI_PCR_CLEN			BIT(1)
> > +#define STM32_CSI_PCR_PWRDOWN			BIT(0)
> > +#define STM32_CSI_VCXCFGR1(x)			((((x) + 1) * 0x0010) + 0x0)
> > +#define STM32_CSI_VCXCFGR1_ALLDT		BIT(0)
> > +#define STM32_CSI_VCXCFGR1_DT0EN		BIT(1)
> > +#define STM32_CSI_VCXCFGR1_DT1EN		BIT(2)
> > +#define STM32_CSI_VCXCFGR1_CDTFT_SHIFT		8
> > +#define STM32_CSI_VCXCFGR1_DT0_SHIFT		16
> > +#define STM32_CSI_VCXCFGR1_DT0FT_SHIFT		24
> > +#define STM32_CSI_VCXCFGR2(x)			((((x) + 1) * 0x0010) + 0x4)
> > +#define STM32_CSI_VCXCFGR2_DT1_SHIFT		0
> > +#define STM32_CSI_VCXCFGR2_DT1FT_SHIFT		8
> > +#define STM32_CSI_INPUT_BPP8			2
> > +#define STM32_CSI_INPUT_BPP10			3
> > +#define STM32_CSI_INPUT_BPP12			4
> > +#define STM32_CSI_INPUT_BPP14			5
> > +#define STM32_CSI_LMCFGR			0x0070
> > +#define STM32_CSI_LMCFGR_LANENB_SHIFT		8
> > +#define STM32_CSI_LMCFGR_DLMAP_SHIFT		16
> > +#define STM32_CSI_IER0				0x0080
> > +#define STM32_CSI_IER1				0x0084
> > +#define STM32_CSI_SR0				0x0090
> > +#define STM32_CSI_SR0_SYNCERRF			BIT(30)
> > +#define STM32_CSI_SR0_SPKTERRF			BIT(28)
> > +#define STM32_CSI_SR0_IDERRF			BIT(27)
> > +#define STM32_CSI_SR0_CECCERRF			BIT(26)
> > +#define STM32_CSI_SR0_ECCERRF			BIT(25)
> > +#define STM32_CSI_SR0_CRCERRF			BIT(24)
> > +#define STM32_CSI_SR0_CCFIFOFF			BIT(21)
> > +#define STM32_CSI_SR0_VCXSTATEF(x)		BIT(17 + (x))
> > +#define STM32_CSI_SR1				0x0094
> > +#define STM32_CSI_SR1_ECTRLDL1F			BIT(12)
> > +#define STM32_CSI_SR1_ESYNCESCDL1F		BIT(11)
> > +#define STM32_CSI_SR1_EESCDL1F			BIT(10)
> > +#define STM32_CSI_SR1_ESOTSYNCDL1F		BIT(9)
> > +#define STM32_CSI_SR1_ESOTDL1F			BIT(8)
> > +#define STM32_CSI_SR1_ECTRLDL0F			BIT(4)
> > +#define STM32_CSI_SR1_ESYNCESCDL0F		BIT(3)
> > +#define STM32_CSI_SR1_EESCDL0F			BIT(2)
> > +#define STM32_CSI_SR1_ESOTSYNCDL0F		BIT(1)
> > +#define STM32_CSI_SR1_ESOTDL0F			BIT(0)
> > +#define STM32_CSI_FCR0				0x0100
> > +#define STM32_CSI_FCR1				0x0104
> > +#define STM32_CSI_SPDFR				0x0110
> > +#define STM32_CSI_DT_MASK			0x3f
> > +#define STM32_CSI_VC_MASK			0x03
> > +#define STM32_CSI_ERR1				0x0114
> > +#define STM32_CSI_ERR1_IDVCERR_SHIFT		22
> > +#define STM32_CSI_ERR1_IDDTERR_SHIFT		16
> > +#define STM32_CSI_ERR1_CECCVCERR_SHIFT		14
> > +#define STM32_CSI_ERR1_CECCDTERR_SHIFT		8
> > +#define STM32_CSI_ERR1_CRCVCERR_SHIFT		6
> > +#define STM32_CSI_ERR1_CRCDTERR_SHIFT		0
> > +#define STM32_CSI_ERR2				0x0118
> > +#define STM32_CSI_ERR2_SYNCVCERR_SHIFT		18
> > +#define STM32_CSI_ERR2_SPKTVCERR_SHIFT		6
> > +#define STM32_CSI_ERR2_SPKTDTERR_SHIFT		0
> > +#define STM32_CSI_PRCR				0x1000
> > +#define STM32_CSI_PRCR_PEN			BIT(1)
> > +#define STM32_CSI_PMCR				0x1004
> > +#define STM32_CSI_PFCR				0x1008
> > +#define STM32_CSI_PFCR_CCFR_MASK		GENMASK(5, 0)
> > +#define STM32_CSI_PFCR_CCFR_SHIFT		0
> > +#define STM32_CSI_PFCR_HSFR_MASK		GENMASK(14, 8)
> > +#define STM32_CSI_PFCR_HSFR_SHIFT		8
> > +#define STM32_CSI_PFCR_DLD			BIT(16)
> > +#define STM32_CSI_PTCR0				0x1010
> > +#define STM32_CSI_PTCR0_TCKEN			BIT(0)
> > +#define STM32_CSI_PTCR1				0x1014
> > +#define STM32_CSI_PTCR1_TWM			BIT(16)
> > +#define STM32_CSI_PTCR1_TDI_MASK		GENMASK(7, 0)
> > +#define STM32_CSI_PTCR1_TDI_SHIFT		0
> > +#define STM32_CSI_PTSR				0x1018
> > +
> > +#define STM32_CSI_LANES_MAX	2
> > +
> > +#define STM32_CSI_SR0_ERRORS	(STM32_CSI_SR0_SYNCERRF | STM32_CSI_SR0_SPKTERRF |\
> > +				 STM32_CSI_SR0_IDERRF | STM32_CSI_SR0_CECCERRF |\
> > +				 STM32_CSI_SR0_ECCERRF | STM32_CSI_SR0_CRCERRF |\
> > +				 STM32_CSI_SR0_CCFIFOFF)
> > +#define STM32_CSI_SR1_DL0_ERRORS	(STM32_CSI_SR1_ECTRLDL0F | STM32_CSI_SR1_ESYNCESCDL0F |\
> > +				 STM32_CSI_SR1_EESCDL0F | STM32_CSI_SR1_ESOTSYNCDL0F |\
> > +				 STM32_CSI_SR1_ESOTDL0F)
> > +#define STM32_CSI_SR1_DL1_ERRORS	(STM32_CSI_SR1_ECTRLDL1F | STM32_CSI_SR1_ESYNCESCDL1F |\
> > +				 STM32_CSI_SR1_EESCDL1F | STM32_CSI_SR1_ESOTSYNCDL1F |\
> > +				 STM32_CSI_SR1_ESOTDL1F)
> > +#define STM32_CSI_SR1_ERRORS	(STM32_CSI_SR1_DL0_ERRORS | STM32_CSI_SR1_DL1_ERRORS)
> > +
> > +enum stm32_csi_pads {
> > +	STM32_CSI_PAD_SINK,
> > +	STM32_CSI_PAD_SOURCE,
> > +	STM32_CSI_PAD_MAX,
> > +};
> > +
> > +struct stm32_csi_event {
> > +	u32 mask;
> > +	const char * const name;
> > +};
> > +
> > +static const struct stm32_csi_event stm32_csi_events_sr0[] = {
> > +	{STM32_CSI_SR0_SYNCERRF,	"Synchronization error"},
> > +	{STM32_CSI_SR0_SPKTERRF,	"Short packet error"},
> > +	{STM32_CSI_SR0_IDERRF,		"Data type ID error"},
> > +	{STM32_CSI_SR0_CECCERRF,	"Corrected ECC error"},
> > +	{STM32_CSI_SR0_ECCERRF,		"ECC error"},
> > +	{STM32_CSI_SR0_CRCERRF,		"CRC error"},
> > +	{STM32_CSI_SR0_CCFIFOFF,	"Clk changer FIFO full error"},
> > +};
> > +
> > +#define STM32_CSI_NUM_SR0_EVENTS ARRAY_SIZE(stm32_csi_events_sr0)
> > +
> > +static const struct stm32_csi_event stm32_csi_events_sr1[] = {
> > +	{STM32_CSI_SR1_ECTRLDL1F,	"L1: D-PHY control error"},
> > +	{STM32_CSI_SR1_ESYNCESCDL1F,
> > +		"L1: D-PHY low power data transmission synchro error"},
> > +	{STM32_CSI_SR1_EESCDL1F,	"L1: D-PHY escape entry error"},
> > +	{STM32_CSI_SR1_ESOTSYNCDL1F,
> > +		"L1: Start of transmission synchro error"},
> > +	{STM32_CSI_SR1_ESOTDL1F,	"L1: Start of transmission error"},
> > +	{STM32_CSI_SR1_ECTRLDL0F,	"L0: D-PHY control error"},
> > +	{STM32_CSI_SR1_ESYNCESCDL0F,
> > +		"L0: D-PHY low power data transmission synchro error"},
> > +	{STM32_CSI_SR1_EESCDL0F,	"L0: D-PHY escape entry error"},
> > +	{STM32_CSI_SR1_ESOTSYNCDL0F,
> > +		"L0: Start of transmission synchro error"},
> > +	{STM32_CSI_SR1_ESOTDL0F,	"L0: Start of transmission error"},
> > +};
> > +
> > +#define STM32_CSI_NUM_SR1_EVENTS ARRAY_SIZE(stm32_csi_events_sr1)
> > +
> > +enum stm32_csi_clk {
> > +	STM32_CSI_CLK_PCLK,
> > +	STM32_CSI_CLK_TXESC,
> > +	STM32_CSI_CLK_CSI2PHY,
> > +	STM32_CSI_CLK_NB,
> > +};
> > +
> > +static const char * const stm32_csi_clks_id[] = {
> > +	"pclk",
> > +	"txesc",
> > +	"csi2phy",
> > +};
> > +
> > +struct stm32_csi_dev {
> > +	struct device			*dev;
> > +
> > +	void __iomem			*base;
> > +
> > +	struct clk_bulk_data		clks[STM32_CSI_CLK_NB];
> > +	struct regulator_bulk_data	supplies[2];
> > +
> > +	u8				lanes[STM32_CSI_LANES_MAX];
> > +	u8				num_lanes;
> > +
> > +	/*
> > +	 * spinlock slock is used to protect to srX_counters tables being
> > +	 * accessed from log_status and interrupt context
> > +	 */
> > +	spinlock_t			slock;
> > +
> > +	u32				sr0_counters[STM32_CSI_NUM_SR0_EVENTS];
> > +	u32				sr1_counters[STM32_CSI_NUM_SR1_EVENTS];
> > +
> > +	struct v4l2_subdev		sd;
> > +	struct v4l2_async_notifier	notifier;
> > +	struct media_pad		pads[STM32_CSI_PAD_MAX];
> > +
> > +	/* Remote source */
> > +	struct v4l2_subdev		*s_subdev;
> > +	u32				s_subdev_pad_nb;
> > +};
> > +
> > +struct stm32_csi_fmts {
> > +	u32 code;
> > +	u32 datatype;
> > +	u32 input_fmt;
> > +	u8 bpp;
> > +};
> > +
> > +#define FMT_MBUS_DT_DTFMT_BPP(mbus, dt, input, byteperpixel)		\
> > +	{								\
> > +		.code = MEDIA_BUS_FMT_##mbus,				\
> > +		.datatype = MIPI_CSI2_DT_##dt,				\
> > +		.input_fmt = STM32_CSI_INPUT_##input,	\
> > +		.bpp = byteperpixel,					\
> > +	}
> > +static const struct stm32_csi_fmts stm32_csi_formats[] = {
> > +	/* YUV 422 8 bit */
> > +	FMT_MBUS_DT_DTFMT_BPP(UYVY8_1X16, YUV422_8B, BPP8, 8),
> > +	FMT_MBUS_DT_DTFMT_BPP(YUYV8_1X16, YUV422_8B, BPP8, 8),
> > +	FMT_MBUS_DT_DTFMT_BPP(YVYU8_1X16, YUV422_8B, BPP8, 8),
> > +	FMT_MBUS_DT_DTFMT_BPP(VYUY8_1X16, YUV422_8B, BPP8, 8),
> > +
> > +	/* Raw Bayer */
> > +	/* 8 bit */
> > +	FMT_MBUS_DT_DTFMT_BPP(SBGGR8_1X8, RAW8, BPP8, 8),
> > +	FMT_MBUS_DT_DTFMT_BPP(SGBRG8_1X8, RAW8, BPP8, 8),
> > +	FMT_MBUS_DT_DTFMT_BPP(SGRBG8_1X8, RAW8, BPP8, 8),
> > +	FMT_MBUS_DT_DTFMT_BPP(SRGGB8_1X8, RAW8, BPP8, 8),
> > +	/* 10 bit */
> > +	FMT_MBUS_DT_DTFMT_BPP(SRGGB10_1X10, RAW10, BPP10, 10),
> > +	FMT_MBUS_DT_DTFMT_BPP(SGBRG10_1X10, RAW10, BPP10, 10),
> > +	FMT_MBUS_DT_DTFMT_BPP(SGRBG10_1X10, RAW10, BPP10, 10),
> > +	FMT_MBUS_DT_DTFMT_BPP(SRGGB10_1X10, RAW10, BPP10, 10),
> > +	/* 12 bit */
> > +	FMT_MBUS_DT_DTFMT_BPP(SRGGB12_1X12, RAW12, BPP12, 12),
> > +	FMT_MBUS_DT_DTFMT_BPP(SGBRG12_1X12, RAW12, BPP12, 12),
> > +	FMT_MBUS_DT_DTFMT_BPP(SGRBG12_1X12, RAW12, BPP12, 12),
> > +	FMT_MBUS_DT_DTFMT_BPP(SRGGB12_1X12, RAW12, BPP12, 12),
> > +	/* 14 bit */
> > +	FMT_MBUS_DT_DTFMT_BPP(SRGGB14_1X14, RAW14, BPP14, 14),
> > +	FMT_MBUS_DT_DTFMT_BPP(SGBRG14_1X14, RAW14, BPP14, 14),
> > +	FMT_MBUS_DT_DTFMT_BPP(SGRBG14_1X14, RAW14, BPP14, 14),
> > +	FMT_MBUS_DT_DTFMT_BPP(SRGGB14_1X14, RAW14, BPP14, 14),
> > +
> > +	/* RGB 565 */
> > +	FMT_MBUS_DT_DTFMT_BPP(RGB565_1X16, RGB565, BPP8, 8),
> > +
> > +	/* JPEG (datatype isn't used) */
> > +	FMT_MBUS_DT_DTFMT_BPP(JPEG_1X8, NULL, BPP8, 8),
> > +};
> > +
> > +struct stm32_csi_mbps_phy_reg {
> > +	unsigned int mbps;
> > +	unsigned int hsfreqrange;
> > +	unsigned int osc_freq_target;
> > +};
> > +
> > +/*
> > + * Table describing configuration of the PHY depending on the
> > + * intended Bit Rate. From table 5-8 Frequency Ranges and Defaults
> > + * of the Synopsis DWC MIPI PHY databook
> > + */
> > +static const struct stm32_csi_mbps_phy_reg snps_stm32mp25[] = {
> > +	{ .mbps =   80,	.hsfreqrange = 0x00,	.osc_freq_target = 460 },
> > +	{ .mbps =   90, .hsfreqrange = 0x10,	.osc_freq_target = 460 },
> > +	{ .mbps =  100, .hsfreqrange = 0x20,	.osc_freq_target = 460 },
> > +	{ .mbps =  110, .hsfreqrange = 0x30,	.osc_freq_target = 460 },
> > +	{ .mbps =  120, .hsfreqrange = 0x01,	.osc_freq_target = 460 },
> > +	{ .mbps =  130, .hsfreqrange = 0x11,	.osc_freq_target = 460 },
> > +	{ .mbps =  140, .hsfreqrange = 0x21,	.osc_freq_target = 460 },
> > +	{ .mbps =  150, .hsfreqrange = 0x31,	.osc_freq_target = 460 },
> > +	{ .mbps =  160, .hsfreqrange = 0x02,	.osc_freq_target = 460 },
> > +	{ .mbps =  170, .hsfreqrange = 0x12,	.osc_freq_target = 460 },
> > +	{ .mbps =  180, .hsfreqrange = 0x22,	.osc_freq_target = 460 },
> > +	{ .mbps =  190, .hsfreqrange = 0x32,	.osc_freq_target = 460 },
> > +	{ .mbps =  205, .hsfreqrange = 0x03,	.osc_freq_target = 460 },
> > +	{ .mbps =  220, .hsfreqrange = 0x13,	.osc_freq_target = 460 },
> > +	{ .mbps =  235, .hsfreqrange = 0x23,	.osc_freq_target = 460 },
> > +	{ .mbps =  250, .hsfreqrange = 0x33,	.osc_freq_target = 460 },
> > +	{ .mbps =  275, .hsfreqrange = 0x04,	.osc_freq_target = 460 },
> > +	{ .mbps =  300, .hsfreqrange = 0x14,	.osc_freq_target = 460 },
> > +	{ .mbps =  325, .hsfreqrange = 0x25,	.osc_freq_target = 460 },
> > +	{ .mbps =  350, .hsfreqrange = 0x35,	.osc_freq_target = 460 },
> > +	{ .mbps =  400, .hsfreqrange = 0x05,	.osc_freq_target = 460 },
> > +	{ .mbps =  450, .hsfreqrange = 0x16,	.osc_freq_target = 460 },
> > +	{ .mbps =  500, .hsfreqrange = 0x26,	.osc_freq_target = 460 },
> > +	{ .mbps =  550, .hsfreqrange = 0x37,	.osc_freq_target = 460 },
> > +	{ .mbps =  600, .hsfreqrange = 0x07,	.osc_freq_target = 460 },
> > +	{ .mbps =  650, .hsfreqrange = 0x18,	.osc_freq_target = 460 },
> > +	{ .mbps =  700, .hsfreqrange = 0x28,	.osc_freq_target = 460 },
> > +	{ .mbps =  750, .hsfreqrange = 0x39,	.osc_freq_target = 460 },
> > +	{ .mbps =  800, .hsfreqrange = 0x09,	.osc_freq_target = 460 },
> > +	{ .mbps =  850, .hsfreqrange = 0x19,	.osc_freq_target = 460 },
> > +	{ .mbps =  900, .hsfreqrange = 0x29,	.osc_freq_target = 460 },
> > +	{ .mbps =  950, .hsfreqrange = 0x3a,	.osc_freq_target = 460 },
> > +	{ .mbps = 1000, .hsfreqrange = 0x0a,	.osc_freq_target = 460 },
> > +	{ .mbps = 1050, .hsfreqrange = 0x1a,	.osc_freq_target = 460 },
> > +	{ .mbps = 1100, .hsfreqrange = 0x2a,	.osc_freq_target = 460 },
> > +	{ .mbps = 1150, .hsfreqrange = 0x3b,	.osc_freq_target = 460 },
> > +	{ .mbps = 1200, .hsfreqrange = 0x0b,	.osc_freq_target = 460 },
> > +	{ .mbps = 1250, .hsfreqrange = 0x1b,	.osc_freq_target = 460 },
> > +	{ .mbps = 1300, .hsfreqrange = 0x2b,	.osc_freq_target = 460 },
> > +	{ .mbps = 1350, .hsfreqrange = 0x3c,	.osc_freq_target = 460 },
> > +	{ .mbps = 1400, .hsfreqrange = 0x0c,	.osc_freq_target = 460 },
> > +	{ .mbps = 1450, .hsfreqrange = 0x1c,	.osc_freq_target = 460 },
> > +	{ .mbps = 1500, .hsfreqrange = 0x2c,	.osc_freq_target = 460 },
> > +	{ .mbps = 1550, .hsfreqrange = 0x3d,	.osc_freq_target = 285 },
> > +	{ .mbps = 1600, .hsfreqrange = 0x0d,	.osc_freq_target = 295 },
> > +	{ .mbps = 1650, .hsfreqrange = 0x1d,	.osc_freq_target = 304 },
> > +	{ .mbps = 1700, .hsfreqrange = 0x2e,	.osc_freq_target = 313 },
> > +	{ .mbps = 1750, .hsfreqrange = 0x3e,	.osc_freq_target = 322 },
> > +	{ .mbps = 1800, .hsfreqrange = 0x0e,	.osc_freq_target = 331 },
> > +	{ .mbps = 1850, .hsfreqrange = 0x1e,	.osc_freq_target = 341 },
> > +	{ .mbps = 1900, .hsfreqrange = 0x2f,	.osc_freq_target = 350 },
> > +	{ .mbps = 1950, .hsfreqrange = 0x3f,	.osc_freq_target = 359 },
> > +	{ .mbps = 2000, .hsfreqrange = 0x0f,	.osc_freq_target = 368 },
> > +	{ .mbps = 2050, .hsfreqrange = 0x40,	.osc_freq_target = 377 },
> > +	{ .mbps = 2100, .hsfreqrange = 0x41,	.osc_freq_target = 387 },
> > +	{ .mbps = 2150, .hsfreqrange = 0x42,	.osc_freq_target = 396 },
> > +	{ .mbps = 2200, .hsfreqrange = 0x43,	.osc_freq_target = 405 },
> > +	{ .mbps = 2250, .hsfreqrange = 0x44,	.osc_freq_target = 414 },
> > +	{ .mbps = 2300, .hsfreqrange = 0x45,	.osc_freq_target = 423 },
> > +	{ .mbps = 2350, .hsfreqrange = 0x46,	.osc_freq_target = 432 },
> > +	{ .mbps = 2400, .hsfreqrange = 0x47,	.osc_freq_target = 442 },
> > +	{ .mbps = 2450, .hsfreqrange = 0x48,	.osc_freq_target = 451 },
> > +	{ .mbps = 2500, .hsfreqrange = 0x49,	.osc_freq_target = 460 },
> > +	{ /* sentinel */ }
> > +};
> > +
> > +static const struct v4l2_mbus_framefmt fmt_default = {
> > +	.width = 640,
> > +	.height = 480,
> > +	.code = MEDIA_BUS_FMT_RGB565_1X16,
> > +	.field = V4L2_FIELD_NONE,
> > +	.colorspace = V4L2_COLORSPACE_REC709,
> > +	.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
> > +	.quantization = V4L2_QUANTIZATION_DEFAULT,
> > +	.xfer_func = V4L2_XFER_FUNC_DEFAULT,
> > +};
> > +
> > +static const struct stm32_csi_fmts *stm32_csi_code_to_fmt(unsigned int code)
> > +{
> > +	unsigned int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(stm32_csi_formats); i++)
> > +		if (stm32_csi_formats[i].code == code)
> > +			return &stm32_csi_formats[i];
> > +
> > +	return NULL;
> > +}
> > +
> > +static inline struct stm32_csi_dev *to_csidev(struct v4l2_subdev *sd)
> > +{
> > +	return container_of(sd, struct stm32_csi_dev, sd);
> > +}
> > +
> > +static int stm32_csi_setup_lane_merger(struct stm32_csi_dev *csidev)
> > +{
> > +	u32 lmcfgr = 0;
> > +	int i;
> 
> unsigned int i?

Done

> 
> > +
> > +	for (i = 0; i < csidev->num_lanes; i++) {
> > +		if (!csidev->lanes[i] || csidev->lanes[i] > STM32_CSI_LANES_MAX) {
> > +			dev_err(csidev->dev, "Invalid lane id (%d)\n", csidev->lanes[i]);
> > +			return -EINVAL;
> > +		}
> > +		lmcfgr |= (csidev->lanes[i] << ((i * 4) + STM32_CSI_LMCFGR_DLMAP_SHIFT));
> > +	}
> > +
> > +	lmcfgr |= (csidev->num_lanes << STM32_CSI_LMCFGR_LANENB_SHIFT);
> > +
> > +	writel_relaxed(lmcfgr, csidev->base + STM32_CSI_LMCFGR);
> > +
> > +	return 0;
> > +}
> > +
> > +static void stm32_csi_phy_reg_write(struct stm32_csi_dev *csidev,
> > +				    u32 addr, u32 val)
> > +{
> > +	/* Based on sequence described at section 5.2.3.2 of DesignWave document */
> > +	/* For writing the 4-bit testcode MSBs */
> > +	/* Set testen to high */
> > +	writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1);
> > +
> > +	/* Set testclk to high */
> > +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> > +
> > +	/* Place 0x00 in testdin */
> > +	writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1);
> > +
> > +	/*
> > +	 * Set testclk to low (with the falling edge on testclk, the testdin
> > +	 * signal content is latched internally)
> > +	 */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> > +
> > +	/* Set testen to low */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR1);
> > +
> > +	/* Place the 8-bit word corresponding to the testcode MSBs in testdin */
> > +	writel_relaxed(((addr >> 8) & STM32_CSI_PTCR1_TDI_MASK) << STM32_CSI_PTCR1_TDI_SHIFT,
> > +		       csidev->base + STM32_CSI_PTCR1);
> > +
> > +	/* Set testclk to high */
> > +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> > +
> > +	/* For writing the 8-bit testcode LSBs */
> > +	/* Set testclk to low */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> > +
> > +	/* Set testen to high */
> > +	writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1);
> > +
> > +	/* Set testclk to high */
> > +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> > +
> > +	/* Place the 8-bit word test data in testdin */
> > +	writel_relaxed((addr & STM32_CSI_PTCR1_TDI_MASK) <<
> > +		       STM32_CSI_PTCR1_TDI_SHIFT | STM32_CSI_PTCR1_TWM,
> > +		       csidev->base + STM32_CSI_PTCR1);
> > +
> > +	/*
> > +	 * Set testclk to low (with the falling edge on testclk, the testdin
> > +	 * signal content is latched internally)
> > +	 */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> > +
> > +	/* Set testen to low */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR1);
> > +
> > +	/* For writing the data */
> > +	/* Place the 8-bit word corresponding to the page offset in testdin */
> > +	writel_relaxed((val & STM32_CSI_PTCR1_TDI_MASK) << STM32_CSI_PTCR1_TDI_SHIFT,
> > +		       csidev->base + STM32_CSI_PTCR1);
> > +
> > +	/* Set testclk to high (test data is programmed internally */
> > +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> > +
> > +	/* Finish by setting testclk to low */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> > +}
> > +
> > +static int stm32_csi_start(struct stm32_csi_dev *csidev,
> > +			   struct v4l2_subdev_state *state)
> > +{
> > +	const struct stm32_csi_mbps_phy_reg *phy_regs;
> > +	struct v4l2_mbus_framefmt *sink_fmt;
> > +	const struct stm32_csi_fmts *fmt;
> > +	unsigned long phy_clk_frate;
> > +	unsigned int mbps;
> > +	u32 lanes_ie = 0;
> > +	u32 lanes_en = 0;
> > +	s64 link_freq;
> > +	int ret;
> > +	u32 ccfr;
> > +
> > +	dev_dbg(csidev->dev, "Starting the CSI2\n");
> > +
> > +	/* Get the bpp value on pad0 (input of CSI) */
> > +	sink_fmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SINK);
> > +	fmt = stm32_csi_code_to_fmt(sink_fmt->code);
> > +
> > +	/* Get the remote sensor link frequency */
> > +	if (!csidev->s_subdev)
> > +		return -EIO;
> > +
> > +	link_freq = v4l2_get_link_freq(csidev->s_subdev->ctrl_handler,
> > +				       fmt->bpp, 2 * csidev->num_lanes);
> 
> You'll be able to pass sub-device to the function soon, see e.g.
> <URL:https://git.linuxtv.org/sailus/media_tree.git/commit/?h=devel&id=ac10f4525fd5f48ad33a79d9f261539dcc800039>.
> I intend to send a PR with that early next week.

I've pushed modifications without this change since it isn't yet
available.

> 
> > +	if (link_freq < 0)
> > +		return link_freq;
> > +
> > +	/* MBPS is expressed in Mbps, hence link_freq / 100000 * 2 */
> > +	mbps = div_s64(link_freq, 500000);
> > +	dev_dbg(csidev->dev, "Computed Mbps: %u\n", mbps);
> > +
> > +	for (phy_regs = snps_stm32mp25; phy_regs->mbps != 0; phy_regs++)
> 
> I'd use ARRAY_SIZE() there instead. There's also bsearch.

Done with ARRAY_SIZE

> 
> > +		if (phy_regs->mbps >= mbps)
> > +			break;
> > +
> > +	if (!phy_regs->mbps) {
> > +		dev_err(csidev->dev, "Unsupported PHY speed (%u Mbps)", mbps);
> > +		return -ERANGE;
> > +	}
> > +
> > +	dev_dbg(csidev->dev, "PHY settings: (%u Mbps, %u HS FRange, %u OSC Freq)\n",
> > +		phy_regs->mbps, phy_regs->hsfreqrange,
> > +		phy_regs->osc_freq_target);
> > +
> > +	/* Prepare lanes related configuration bits */
> > +	lanes_ie |= STM32_CSI_SR1_DL0_ERRORS;
> > +	lanes_en |= STM32_CSI_PCR_DL0EN;
> 
> You could initialise these here instead of in variable declaration.

Done

> 
> > +	if (csidev->num_lanes == 2) {
> > +		lanes_ie |= STM32_CSI_SR1_DL1_ERRORS;
> > +		lanes_en |= STM32_CSI_PCR_DL1EN;
> > +	}
> > +
> > +	ret = pm_runtime_get_sync(csidev->dev);
> > +	if (ret < 0)
> 
> This requires pm_runtime_put(). Or alternatively, use
> pm_runtime_resume_and_get().
> 
> In the first case I'd add a label for handling this, considering you have
> already two other cases doign more than returning the error code.

Done with pm_runtime_put & label.

> 
> > +		return ret;
> > +
> > +	/* Retrieve CSI2PHY clock rate to compute CCFR value */
> > +	phy_clk_frate = clk_get_rate(csidev->clks[STM32_CSI_CLK_CSI2PHY].clk);
> > +	if (!phy_clk_frate) {
> > +		pm_runtime_put(csidev->dev);
> > +		dev_err(csidev->dev, "CSI2PHY clock rate invalid (0)\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = stm32_csi_setup_lane_merger(csidev);
> > +	if (ret) {
> > +		pm_runtime_put(csidev->dev);
> > +		return ret;
> > +	}
> > +
> > +	/* Enable the CSI */
> > +	writel_relaxed(STM32_CSI_CR_CSIEN, csidev->base + STM32_CSI_CR);
> > +
> > +	/* Enable some global CSI related interrupts - bits are same as SR0 */
> > +	writel_relaxed(STM32_CSI_SR0_ERRORS, csidev->base + STM32_CSI_IER0);
> > +
> > +	/* Enable lanes related error interrupts */
> > +	writel_relaxed(lanes_ie, csidev->base + STM32_CSI_IER1);
> > +
> > +	/* Initialization of the D-PHY */
> > +	/* Stop the D-PHY */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PRCR);
> > +
> > +	/* Keep the D-PHY in power down state */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PCR);
> > +
> > +	/* Enable testclr clock during 15ns */
> > +	writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0);
> > +	udelay(1);
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PTCR0);
> > +
> > +	/* Set hsfreqrange */
> > +	phy_clk_frate /= 1000000;
> > +	ccfr = (phy_clk_frate - 17) * 4;
> > +	writel_relaxed((ccfr << STM32_CSI_PFCR_CCFR_SHIFT) |
> > +		       (phy_regs->hsfreqrange << STM32_CSI_PFCR_HSFR_SHIFT),
> > +		       csidev->base + STM32_CSI_PFCR);
> > +
> > +	/* set reg @08 deskew_polarity_rw 1'b1 */
> > +	stm32_csi_phy_reg_write(csidev, 0x08, 0x38);
> > +
> > +	/* set reg @0xE4 counter_for_des_en_config_if_rx 0x10 + DLL prog EN */
> > +	/* This is because 13<= cfgclkfreqrange[5:0]<=38 */
> > +	stm32_csi_phy_reg_write(csidev, 0xe4, 0x11);
> > +
> > +	/* set reg @0xe2 & reg @0xe3 value DLL target oscilation freq */
> > +	/* Based on the table page 77, osc_freq_target */
> > +	stm32_csi_phy_reg_write(csidev, 0xe2, phy_regs->osc_freq_target & 0xFF);
> > +	stm32_csi_phy_reg_write(csidev, 0xe3, (phy_regs->osc_freq_target >> 8) & 0x0F);
> > +
> > +	writel_relaxed(STM32_CSI_PFCR_DLD | readl_relaxed(csidev->base + STM32_CSI_PFCR),
> > +		       csidev->base + STM32_CSI_PFCR);
> > +
> > +	/* Enable Lanes */
> > +	writel_relaxed(lanes_en | STM32_CSI_PCR_CLEN, csidev->base + STM32_CSI_PCR);
> > +	writel_relaxed(lanes_en | STM32_CSI_PCR_CLEN | STM32_CSI_PCR_PWRDOWN,
> > +		       csidev->base + STM32_CSI_PCR);
> > +
> > +	writel_relaxed(STM32_CSI_PRCR_PEN, csidev->base + STM32_CSI_PRCR);
> > +
> > +	/* Remove the force */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PMCR);
> > +
> > +	return ret;
> > +}
> > +
> > +static void stm32_csi_stop(struct stm32_csi_dev *csidev)
> > +{
> > +	dev_dbg(csidev->dev, "Stopping the CSI2\n");
> > +
> > +	/* Disable the D-PHY */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_PCR);
> > +
> > +	/* Disable ITs */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_IER0);
> > +	writel_relaxed(0, csidev->base + STM32_CSI_IER1);
> > +
> > +	/* Disable the CSI */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_CR);
> > +
> > +	pm_runtime_put(csidev->dev);
> > +}
> > +
> > +static int stm32_csi_start_vc(struct stm32_csi_dev *csidev,
> > +			      struct v4l2_subdev_state *state, u32 vc)
> > +{
> > +	struct v4l2_mbus_framefmt *mbus_fmt;
> > +	const struct stm32_csi_fmts *fmt;
> > +	u32 cfgr1 = 0;
> > +	int ret = 0;
> 
> Redundant initialisation.

Initialisation removed.

> 
> > +	u32 status;
> > +
> > +	mbus_fmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SOURCE);
> > +	fmt = stm32_csi_code_to_fmt(mbus_fmt->code);
> > +
> > +	/* If the mbus code is JPEG, don't enable filtering */
> > +	if (mbus_fmt->code == MEDIA_BUS_FMT_JPEG_1X8) {
> > +		cfgr1 |= STM32_CSI_VCXCFGR1_ALLDT;
> > +		cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_CDTFT_SHIFT;
> > +		dev_dbg(csidev->dev, "VC%d: enable AllDT mode\n", vc);
> > +	} else {
> > +		cfgr1 |= fmt->datatype << STM32_CSI_VCXCFGR1_DT0_SHIFT;
> > +		cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_DT0FT_SHIFT;
> > +		cfgr1 |= STM32_CSI_VCXCFGR1_DT0EN;
> > +		dev_dbg(csidev->dev, "VC%d: enable DT0(0x%x)/DT0FT(0x%x)\n",
> > +			vc, fmt->datatype, fmt->input_fmt);
> > +	}
> > +	writel_relaxed(cfgr1, csidev->base + STM32_CSI_VCXCFGR1(vc));
> > +
> > +	/* Enable processing of the virtual-channel and wait for its status */
> > +	writel_relaxed(STM32_CSI_CR_VCXSTART(vc) | STM32_CSI_CR_CSIEN,
> > +		       csidev->base + STM32_CSI_CR);
> > +
> > +	ret = readl_relaxed_poll_timeout(csidev->base + STM32_CSI_SR0,
> > +					 status,
> > +					 status & STM32_CSI_SR0_VCXSTATEF(vc),
> > +					 1000, 1000000);
> > +	if (ret) {
> > +		dev_err(csidev->dev, "failed to start VC(%d)\n", vc);
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int stm32_csi_stop_vc(struct stm32_csi_dev *csidev, u32 vc)
> > +{
> > +	int ret = 0;
> 
> Redundant initialisation.

Initialisation removed.

> 
> > +	u32 status;
> > +
> > +	/* Stop the Virtual Channel */
> > +	writel_relaxed(STM32_CSI_CR_VCXSTOP(vc) | STM32_CSI_CR_CSIEN,
> > +		       csidev->base + STM32_CSI_CR);
> > +
> > +	ret = readl_relaxed_poll_timeout(csidev->base + STM32_CSI_SR0,
> > +					 status,
> > +					 !(status & STM32_CSI_SR0_VCXSTATEF(vc)),
> > +					 1000, 1000000);
> > +	if (ret) {
> > +		dev_err(csidev->dev, "failed to stop VC(%d)\n", vc);
> > +		return ret;
> > +	}
> > +
> > +	/* Disable all DTs */
> > +	writel_relaxed(0, csidev->base + STM32_CSI_VCXCFGR1(vc));
> > +	writel_relaxed(0, csidev->base + STM32_CSI_VCXCFGR2(vc));
> > +
> > +	return 0;
> > +}
> > +
> > +static int stm32_csi_disable_streams(struct v4l2_subdev *sd,
> > +				     struct v4l2_subdev_state *state, u32 pad,
> > +				     u64 streams_mask)
> > +{
> > +	struct stm32_csi_dev *csidev = to_csidev(sd);
> > +	int ret;
> > +
> > +	ret = v4l2_subdev_disable_streams(csidev->s_subdev,
> > +					  csidev->s_subdev_pad_nb, BIT_ULL(0));
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Stop the VC0 */
> > +	ret = stm32_csi_stop_vc(csidev, 0);
> > +	if (ret)
> > +		dev_err(csidev->dev, "Failed to stop VC0\n");
> > +
> > +	stm32_csi_stop(csidev);
> > +
> > +	return 0;
> > +}
> > +
> > +static int stm32_csi_enable_streams(struct v4l2_subdev *sd,
> > +				    struct v4l2_subdev_state *state, u32 pad,
> > +				    u64 streams_mask)
> > +{
> > +	struct stm32_csi_dev *csidev = to_csidev(sd);
> > +	int ret;
> > +
> > +	ret = stm32_csi_start(csidev, state);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Configure & start the VC0 */
> > +	ret = stm32_csi_start_vc(csidev, state, 0);
> > +	if (ret) {
> > +		dev_err(csidev->dev, "Failed to start VC0\n");
> > +		stm32_csi_stop(csidev);
> > +		return ret;
> > +	}
> > +
> > +	ret = v4l2_subdev_enable_streams(csidev->s_subdev,
> > +					 csidev->s_subdev_pad_nb, BIT_ULL(0));
> > +	if (ret) {
> > +		stm32_csi_stop_vc(csidev, 0);
> > +		stm32_csi_stop(csidev);
> 
> Maybe a label or a few could be useful here?

Done

> 
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int stm32_csi_init_state(struct v4l2_subdev *sd,
> > +				struct v4l2_subdev_state *state)
> > +{
> > +	int i;
> 
> unsigned int i

Done

> 
> > +
> > +	for (i = 0; i < sd->entity.num_pads; i++)
> > +		*v4l2_subdev_state_get_format(state, i) = fmt_default;
> > +
> > +	return 0;
> > +}
> > +
> > +static int stm32_csi_enum_mbus_code(struct v4l2_subdev *sd,
> > +				    struct v4l2_subdev_state *state,
> > +				    struct v4l2_subdev_mbus_code_enum *code)
> > +{
> > +	if (code->index >= ARRAY_SIZE(stm32_csi_formats))
> > +		return -EINVAL;
> > +
> > +	code->code = stm32_csi_formats[code->index].code;
> > +	return 0;
> > +}
> > +
> > +static int stm32_csi_set_pad_format(struct v4l2_subdev *sd,
> > +				    struct v4l2_subdev_state *state,
> > +				    struct v4l2_subdev_format *format)
> > +{
> > +	struct stm32_csi_dev *csidev = to_csidev(sd);
> > +	struct v4l2_mbus_framefmt *framefmt;
> > +	const struct stm32_csi_fmts *fmt;
> > +
> > +	fmt = stm32_csi_code_to_fmt(format->format.code);
> > +	if (!fmt) {
> > +		dev_dbg(csidev->dev, "Unsupported code %d, use default\n",
> > +			format->format.code);
> > +		format->format.code = fmt_default.code;
> > +	}
> > +
> > +	framefmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SINK);
> > +
> > +	if (format->pad == STM32_CSI_PAD_SOURCE)
> > +		format->format = *framefmt;
> > +	else
> > +		*framefmt = format->format;
> > +
> > +	framefmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SOURCE);
> > +	*framefmt = format->format;
> > +
> > +	return 0;
> > +}
> > +
> > +static int stm32_csi_log_status(struct v4l2_subdev *sd)
> > +{
> > +	struct stm32_csi_dev *csidev = to_csidev(sd);
> > +	unsigned long flags;
> > +	unsigned int i;
> > +
> > +	spin_lock_irqsave(&csidev->slock, flags);
> > +
> > +	for (i = 0; i < STM32_CSI_NUM_SR0_EVENTS; i++) {
> > +		if (csidev->sr0_counters[i])
> > +			dev_info(csidev->dev, "%s events: %d\n",
> > +				 stm32_csi_events_sr0[i].name,
> > +				 csidev->sr0_counters[i]);
> > +	}
> > +
> > +	for (i = 0; i < STM32_CSI_NUM_SR1_EVENTS; i++) {
> > +		if (csidev->sr1_counters[i])
> > +			dev_info(csidev->dev, "%s events: %d\n",
> > +				 stm32_csi_events_sr1[i].name,
> > +				 csidev->sr1_counters[i]);
> > +	}
> > +
> > +	spin_unlock_irqrestore(&csidev->slock, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct v4l2_subdev_core_ops stm32_csi_core_ops = {
> > +	.log_status = stm32_csi_log_status,
> > +};
> > +
> > +static const struct v4l2_subdev_video_ops stm32_csi_video_ops = {
> > +	.s_stream = v4l2_subdev_s_stream_helper,
> > +};
> > +
> > +static const struct v4l2_subdev_pad_ops stm32_csi_pad_ops = {
> > +	.enum_mbus_code = stm32_csi_enum_mbus_code,
> > +	.set_fmt = stm32_csi_set_pad_format,
> > +	.get_fmt = v4l2_subdev_get_fmt,
> > +	.enable_streams = stm32_csi_enable_streams,
> > +	.disable_streams = stm32_csi_disable_streams,
> > +};
> > +
> > +static const struct v4l2_subdev_ops stm32_csi_subdev_ops = {
> > +	.core		= &stm32_csi_core_ops,
> > +	.pad		= &stm32_csi_pad_ops,
> > +	.video		= &stm32_csi_video_ops,
> > +};
> > +
> > +static const struct v4l2_subdev_internal_ops stm32_csi_subdev_internal_ops = {
> > +	.init_state = stm32_csi_init_state,
> > +};
> > +
> > +static int stm32_csi_async_bound(struct v4l2_async_notifier *notifier,
> > +				 struct v4l2_subdev *s_subdev,
> > +				 struct v4l2_async_connection *asd)
> > +{
> > +	struct v4l2_subdev *sd = notifier->sd;
> > +	struct stm32_csi_dev *csidev = to_csidev(sd);
> > +	int remote_pad;
> > +
> > +	remote_pad = media_entity_get_fwnode_pad(&s_subdev->entity,
> > +						 s_subdev->fwnode,
> > +						 MEDIA_PAD_FL_SOURCE);
> > +	if (remote_pad < 0) {
> > +		dev_err(csidev->dev, "Couldn't find output pad for subdev %s\n",
> > +			s_subdev->name);
> > +		return remote_pad;
> > +	}
> > +
> > +	csidev->s_subdev = s_subdev;
> > +	csidev->s_subdev_pad_nb = remote_pad;
> > +
> > +	return media_create_pad_link(&csidev->s_subdev->entity,
> > +				     remote_pad, &csidev->sd.entity,
> > +				     STM32_CSI_PAD_SINK,
> > +				     MEDIA_LNK_FL_ENABLED |
> > +				     MEDIA_LNK_FL_IMMUTABLE);
> > +}
> > +
> > +static const struct v4l2_async_notifier_operations stm32_csi_notifier_ops = {
> > +	.bound		= stm32_csi_async_bound,
> > +};
> > +
> > +static irqreturn_t stm32_csi_irq_thread(int irq, void *arg)
> > +{
> > +	struct stm32_csi_dev *csidev = arg;
> > +	unsigned long flags;
> > +	u32 sr0, sr1;
> > +	int i;
> > +
> > +	sr0 = readl_relaxed(csidev->base + STM32_CSI_SR0);
> > +	sr1 = readl_relaxed(csidev->base + STM32_CSI_SR1);
> > +
> > +	/* Clear interrupt */
> > +	writel_relaxed(sr0 & STM32_CSI_SR0_ERRORS,
> > +		       csidev->base + STM32_CSI_FCR0);
> > +	writel_relaxed(sr1 & STM32_CSI_SR1_ERRORS,
> > +		       csidev->base + STM32_CSI_FCR1);
> > +
> > +	spin_lock_irqsave(&csidev->slock, flags);
> > +
> > +	for (i = 0; i < STM32_CSI_NUM_SR0_EVENTS; i++)
> > +		if (sr0 & stm32_csi_events_sr0[i].mask)
> > +			csidev->sr0_counters[i]++;
> > +
> > +	for (i = 0; i < STM32_CSI_NUM_SR1_EVENTS; i++)
> > +		if (sr1 & stm32_csi_events_sr1[i].mask)
> > +			csidev->sr1_counters[i]++;
> > +
> > +	spin_unlock_irqrestore(&csidev->slock, flags);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int stm32_csi_get_resources(struct stm32_csi_dev *csidev,
> > +				   struct platform_device *pdev)
> > +{
> > +	int irq, ret, i;
> 
> unsigned int i

Done

> 
> ?
> 
> > +
> > +	csidev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
> > +	if (IS_ERR(csidev->base))
> > +		return dev_err_probe(&pdev->dev, PTR_ERR(csidev->base),
> > +				     "Failed to ioremap resource\n");
> > +
> > +	for (i = 0; i < STM32_CSI_CLK_NB; i++)
> > +		csidev->clks[i].id = stm32_csi_clks_id[i];
> > +
> > +	ret = devm_clk_bulk_get(&pdev->dev, STM32_CSI_CLK_NB,
> > +				csidev->clks);
> 
> Fits on the previous line.
> 
> > +	if (ret < 0)
> > +		return dev_err_probe(&pdev->dev, ret, "Couldn't get clks\n");
> > +
> > +	csidev->supplies[0].supply = "vdd";
> > +	csidev->supplies[1].supply = "vdda18";
> > +	ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(csidev->supplies),
> > +				      csidev->supplies);
> > +	if (ret)
> > +		return dev_err_probe(&pdev->dev, ret,
> > +				     "Failed to request regulator vdd\n");
> > +
> > +	irq = platform_get_irq(pdev, 0);
> > +	if (irq < 0)
> > +		return irq;
> > +
> > +	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
> > +					stm32_csi_irq_thread, IRQF_ONESHOT,
> > +					dev_name(&pdev->dev), csidev);
> > +	if (ret)
> > +		return dev_err_probe(&pdev->dev, ret,
> > +				     "Unable to request irq");
> > +
> > +	return 0;
> > +}
> > +
> > +static int stm32_csi_parse_dt(struct stm32_csi_dev *csidev)
> > +{
> > +	struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
> > +	struct v4l2_async_connection *asd;
> > +	struct fwnode_handle *ep;
> > +	int ret;
> > +
> > +	/* Get bus characteristics from devicetree */
> > +	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csidev->dev), 0, 0,
> > +					     FWNODE_GRAPH_ENDPOINT_NEXT);
> > +	if (!ep) {
> > +		dev_err(csidev->dev, "Could not find the endpoint\n");
> > +		return -ENODEV;
> > +	}
> > +
> > +	ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
> > +	fwnode_handle_put(ep);
> > +	if (ret) {
> > +		dev_err(csidev->dev, "Could not parse v4l2 endpoint\n");
> > +		return ret;
> > +	}
> > +
> > +	csidev->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
> > +	if (csidev->num_lanes > STM32_CSI_LANES_MAX) {
> > +		dev_err(csidev->dev, "Unsupported number of data-lanes: %d\n",
> > +			csidev->num_lanes);
> > +		return -EINVAL;
> > +	}
> > +
> > +	memcpy(csidev->lanes, v4l2_ep.bus.mipi_csi2.data_lanes,
> > +	       sizeof(csidev->lanes));
> > +
> > +	ep = fwnode_graph_get_next_endpoint(dev_fwnode(csidev->dev), NULL);
> 
> How about:
> 
> 	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csidev->dev), 1, 0,
> 					     FWNODE_GRAPH_ENDPOINT_NEXT);

Actually I removed this call and kept the endpoint got at the beginning
of the function.

> 
> > +	if (!ep) {
> > +		dev_err(csidev->dev, "Failed to get next endpoint\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	v4l2_async_subdev_nf_init(&csidev->notifier, &csidev->sd);
> > +
> > +	asd = v4l2_async_nf_add_fwnode_remote(&csidev->notifier, ep,
> > +					      struct v4l2_async_connection);
> > +
> > +	fwnode_handle_put(ep);
> > +
> > +	if (IS_ERR(asd)) {
> > +		dev_err(csidev->dev, "Failed to add fwnode remote subdev\n");
> > +		return PTR_ERR(asd);
> > +	}
> > +
> > +	csidev->notifier.ops = &stm32_csi_notifier_ops;
> > +
> > +	ret = v4l2_async_nf_register(&csidev->notifier);
> > +	if (ret) {
> > +		dev_err(csidev->dev, "Failed to register notifier\n");
> > +		v4l2_async_nf_cleanup(&csidev->notifier);
> > +		return ret;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static int stm32_csi_probe(struct platform_device *pdev)
> > +{
> > +	struct stm32_csi_dev *csidev;
> > +	struct reset_control *rstc;
> > +	int ret;
> > +
> > +	csidev = devm_kzalloc(&pdev->dev, sizeof(*csidev), GFP_KERNEL);
> > +	if (!csidev)
> > +		return -ENOMEM;
> > +
> > +	platform_set_drvdata(pdev, csidev);
> > +	csidev->dev = &pdev->dev;
> > +
> > +	spin_lock_init(&csidev->slock);
> > +
> > +	ret = stm32_csi_get_resources(csidev, pdev);
> > +	if (ret)
> 
> You could just return the error here. The label naming is misleading, too.
> Same below.

Done

> 
> > +		goto err_free_priv;
> > +
> > +	ret = stm32_csi_parse_dt(csidev);
> > +	if (ret)
> > +		goto err_free_priv;
> > +
> > +	csidev->sd.owner = THIS_MODULE;
> > +	csidev->sd.dev = &pdev->dev;
> > +	csidev->sd.internal_ops = &stm32_csi_subdev_internal_ops;
> > +	v4l2_subdev_init(&csidev->sd, &stm32_csi_subdev_ops);
> > +	v4l2_set_subdevdata(&csidev->sd, &pdev->dev);
> > +	snprintf(csidev->sd.name, sizeof(csidev->sd.name), "%s",
> > +		 dev_name(&pdev->dev));
> > +
> > +	/* Create our media pads */
> > +	csidev->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
> > +	csidev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> > +	csidev->pads[STM32_CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> > +	csidev->pads[STM32_CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
> > +
> > +	ret = media_entity_pads_init(&csidev->sd.entity, STM32_CSI_PAD_MAX,
> > +				     csidev->pads);
> > +	if (ret)
> > +		goto err_cleanup;
> > +
> > +	ret = v4l2_subdev_init_finalize(&csidev->sd);
> > +	if (ret < 0)
> > +		goto err_cleanup;
> > +
> > +	ret = v4l2_async_register_subdev(&csidev->sd);
> > +	if (ret < 0)
> > +		goto err_cleanup;
> 
> You should hold registering the async sub-device until all initialisation
> has been done. Otherwise, you may get callbacks that end up accessing
> what has not been set up yet (below).

Done, moved after the pm_runtime_enable

> 
> > +
> > +	/* Reset device */
> > +	rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> > +	if (IS_ERR(rstc)) {
> > +		ret = dev_err_probe(&pdev->dev, PTR_ERR(rstc),
> > +				    "Couldn't get reset control\n");
> > +		goto err_cleanup;
> > +	}
> > +
> > +	ret = reset_control_assert(rstc);
> > +	if (ret) {
> > +		ret = dev_err_probe(&pdev->dev, ret,
> > +				    "Failed to assert the reset line\n");
> > +		goto err_cleanup;
> > +	}
> > +
> > +	usleep_range(3000, 5000);
> > +
> > +	ret = reset_control_deassert(rstc);
> > +	if (ret) {
> > +		ret = dev_err_probe(&pdev->dev, ret,
> > +				    "Failed to deassert the reset line\n");
> > +		goto err_cleanup;
> > +	}
> > +
> > +	pm_runtime_enable(&pdev->dev);
> > +
> > +	dev_info(&pdev->dev,
> > +		 "Probed CSI with %u lanes\n", csidev->num_lanes);
> > +
> > +	return 0;
> > +
> > +err_cleanup:
> > +	v4l2_async_nf_cleanup(&csidev->notifier);
> > +err_free_priv:
> > +	return ret;
> > +}
> > +
> > +static void stm32_csi_remove(struct platform_device *pdev)
> > +{
> > +	struct stm32_csi_dev *csidev = platform_get_drvdata(pdev);
> > +
> > +	v4l2_async_unregister_subdev(&csidev->sd);
> > +
> > +	pm_runtime_disable(&pdev->dev);
> > +}
> > +
> > +static int stm32_csi_runtime_suspend(struct device *dev)
> > +{
> > +	struct stm32_csi_dev *csidev = dev_get_drvdata(dev);
> > +	int ret;
> > +
> > +	clk_bulk_disable_unprepare(STM32_CSI_CLK_NB, csidev->clks);
> > +
> > +	ret = regulator_bulk_disable(ARRAY_SIZE(csidev->supplies),
> > +				     csidev->supplies);
> > +	if (ret < 0)
> > +		dev_err(dev, "cannot disable regulators %d\n", ret);
> > +
> > +	return 0;
> > +}
> > +
> > +static int stm32_csi_runtime_resume(struct device *dev)
> > +{
> > +	struct stm32_csi_dev *csidev = dev_get_drvdata(dev);
> > +	int ret;
> > +
> > +	ret = regulator_bulk_enable(ARRAY_SIZE(csidev->supplies),
> > +				    csidev->supplies);
> > +	if (ret)
> > +		goto error_out;
> > +
> > +	ret = clk_bulk_prepare_enable(STM32_CSI_CLK_NB, csidev->clks);
> > +	if (ret)
> > +		goto error_disable_supplies;
> > +
> > +	return 0;
> > +
> > +error_disable_supplies:
> > +	ret = regulator_bulk_disable(ARRAY_SIZE(csidev->supplies), csidev->supplies);
> 
> Over 80, please wrap.
> 
> > +	if (ret < 0)
> > +		dev_err(dev, "cannot disable regulators %d\n", ret);
> > +error_out:
> > +	dev_err(csidev->dev, "Failed to resume: %d\n", ret);
> > +
> > +	return ret;
> > +}
> > +
> > +static const struct of_device_id stm32_csi_of_table[] = {
> > +	{ .compatible = "st,stm32mp25-csi", },
> > +	{ /* end node */ },
> > +};
> > +MODULE_DEVICE_TABLE(of, stm32_csi_of_table);
> > +
> > +static const struct dev_pm_ops stm32_csi_pm_ops = {
> > +	RUNTIME_PM_OPS(stm32_csi_runtime_suspend,
> > +		       stm32_csi_runtime_resume, NULL)
> > +};
> > +
> > +static struct platform_driver stm32_csi_driver = {
> > +	.driver	= {
> > +		.name = "stm32-csi",
> > +		.of_match_table = stm32_csi_of_table,
> > +		.pm = pm_ptr(&stm32_csi_pm_ops),
> > +	},
> > +	.probe	= stm32_csi_probe,
> > +	.remove = stm32_csi_remove,
> > +};
> > +
> > +module_platform_driver(stm32_csi_driver);
> > +
> > +MODULE_AUTHOR("Alain Volmat <alain.volmat at foss.st.com>");
> > +MODULE_DESCRIPTION("STM32 CSI controller");
> > +MODULE_LICENSE("GPL");
> > 
> 
> -- 
> Kind regards,
> 
> Sakari Ailus


From quic_vikramsa at quicinc.com  Tue Dec 17 09:49:11 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 23:19:11 +0530
Subject: [PATCH v10 4/4] arm64: dts: qcom:
 qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <22479c27-9265-4994-8974-9739ecbae5ee@linaro.org>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-5-quic_vikramsa@quicinc.com>
 <22479c27-9265-4994-8974-9739ecbae5ee@linaro.org>
Message-ID: <3e6ab7aa-c606-49bc-8cc5-24c8a1edc081@quicinc.com>

On 12/17/2024 8:10 PM, Vladimir Zapolskiy wrote:
> On 12/17/24 16:06, Vikram Sharma wrote:
>> The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
>> Enable the IMX577 on the vision mezzanine.
>>
>> An example media-ctl pipeline for the imx577 is:
>>
>> media-ctl --reset
>> media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
>> media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
>> media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
>> media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
>> media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
>> media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
>>
>> yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F 
>> /dev/video0
>>
>> Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
>> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
>> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
>> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
>> Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>> ---
>> ? arch/arm64/boot/dts/qcom/Makefile???????????? |?? 4 +
>> ? .../qcs6490-rb3gen2-vision-mezzanine.dtso???? | 109 ++++++++++++++++++
>> ? 2 files changed, 113 insertions(+)
>> ? create mode 100644 
>> arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
>>
>> diff --git a/arch/arm64/boot/dts/qcom/Makefile 
>> b/arch/arm64/boot/dts/qcom/Makefile
>> index 4686f2a8ddd8..a7e88fcabded 100644
>> --- a/arch/arm64/boot/dts/qcom/Makefile
>> +++ b/arch/arm64/boot/dts/qcom/Makefile
>> @@ -115,6 +115,10 @@ dtb-$(CONFIG_ARCH_QCOM)??? += qcs404-evb-1000.dtb
>> ? dtb-$(CONFIG_ARCH_QCOM)??? += qcs404-evb-4000.dtb
>> ? dtb-$(CONFIG_ARCH_QCOM)??? += qcs615-ride.dtb
>> ? dtb-$(CONFIG_ARCH_QCOM)??? += qcs6490-rb3gen2.dtb
>> +
>> +qcs6490-rb3gen2-vision-mezzanine-dtbs := qcs6490-rb3gen2.dtb 
>> qcs6490-rb3gen2-vision-mezzanine.dtbo
>> +
>> +dtb-$(CONFIG_ARCH_QCOM)??? += qcs6490-rb3gen2-vision-mezzanine.dtb
>> ? dtb-$(CONFIG_ARCH_QCOM)??? += qcs8300-ride.dtb
>> ? dtb-$(CONFIG_ARCH_QCOM)??? += qcs8550-aim300-aiot.dtb
>> ? dtb-$(CONFIG_ARCH_QCOM)??? += qcs9100-ride.dtb
>> diff --git 
>> a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso 
>> b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
>> new file mode 100644
>> index 000000000000..7782c4aee576
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
>> @@ -0,0 +1,109 @@
>> +// SPDX-License-Identifier: BSD-3-Clause
>> +/*
>> + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights 
>> reserved.
>> + */
>> +
>> +/*
>> + * Camera Sensor overlay on top of rb3gen2 core kit.
>> + */
>> +
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/clock/qcom,camcc-sc7280.h>
>
> Please sort the header files alphabetically.
Thanks for your comments Vladimir.
Will take care in next version.
>
>> +
>> +/dts-v1/;
>> +/plugin/;
>> +
>
> Please put these two lines right after the comments header.
ACK.
>
>> +&camss {
>> +??? vdda-phy-supply = <&vreg_l10c_0p88>;
>> +??? vdda-pll-supply = <&vreg_l6b_1p2>;
>> +
>> +??? status = "okay";
>> +
>> +??? ports {
>> +??????? #address-cells = <1>;
>> +??????? #size-cells = <0>;
>> +
>> +??????? /* The port index denotes CSIPHY id i.e. csiphy3 */
>> +??????? port at 3 {
>> +??????????? reg = <3>;
>> +
>> +??????????? csiphy3_ep: endpoint {
>> +??????????????? clock-lanes = <7>;
>> +??????????????? data-lanes = <0 1 2 3>;
>> +??????????????? remote-endpoint = <&imx577_ep>;
>> +??????????? };
>> +??????? };
>> +??? };
>> +};
>> +
>> +&cci1 {
>> +??? status = "okay";
>> +};
>> +
>> +&cci1_i2c1 {
>> +??? #address-cells = <1>;
>> +??? #size-cells = <0>;
>> +
>> +??? camera at 1a {
>> +??????? compatible = "sony,imx577";
>> +
>> +??????? reg = <0x1a>;
>> +
>> +??????? reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>;
>> +??????? pinctrl-names = "default", "suspend";
>> +??????? pinctrl-0 = <&cam2_default>;
>> +??????? pinctrl-1 = <&cam2_suspend>;
>> +
>> +??????? clocks = <&camcc CAM_CC_MCLK3_CLK>;
>> +??????? assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>;
>> +??????? assigned-clock-rates = <24000000>;
>> +
>> +??????? dovdd-supply? = <&vreg_l18b_1p8>;
>
> Please remove double space before '='.
Sure.
>
>> +??????? avdd-supply = <&vph_pwr>;
>> +??????? dvdd-supply = <&vph_pwr>;
>> +
>> +??????? port {
>> +??????????? imx577_ep: endpoint {
>> +??????????????? clock-lanes = <7>;
>
> It is an invalid property/value of the sensor, please remove it.
Will check more on this internally and respond back.
>
>> +??????????????? link-frequencies = /bits/ 64 <600000000>;
>> +??????????????? data-lanes = <0 1 2 3>;
>
> data-lanes = <1 2 3 4>;
Will check more on this internally and respond back
>
>> +??????????????? remote-endpoint = <&csiphy3_ep>;
>> +??????????? };
>> +??????? };
>> +??? };
>> +};
>> +
>> +&tlmm {
>> +??? cam2_default: cam2-default-state {
>> +??????? mclk-pins {
>> +??????????? pins = "gpio67";
>> +??????????? function = "cam_mclk";
>> +??????????? drive-strength = <2>;
>> +??????????? bias-disable;
>> +??????? };
>> +
>> +??????? rst-pins {
>> +??????????? pins = "gpio78";
>> +??????????? function = "gpio";
>> +??????????? drive-strength = <2>;
>> +??????????? bias-disable;
>> +??????? };
>> +??? };
>> +
>> +??? cam2_suspend: cam2-suspend-state {
>> +??????? mclk-pins {
>> +??????????? pins = "gpio67";
>> +??????????? function = "cam_mclk";
>> +??????????? drive-strength = <2>;
>> +??????????? bias-pull-down;
>> +??????? };
>> +
>> +??????? rst-pins {
>> +??????????? pins = "gpio78";
>> +??????????? function = "gpio";
>> +??????????? drive-strength = <2>;
>> +??????????? bias-pull-down;
>> +??????????? output-low;
>> +??????? };
>
> I have doubts that it's proper to embed a reset gpio into driver's
> pinctrl suspend/resume power management.
>
> Konrad, can you please confirm that it's really accepted?
>
> I'd rather ask to remove this reset pin control.
Will discuss this with Konrad and respond.
>> +??? };
>> +};
>
> -- 
> Best wishes,
> Vladimir

Best Regards,
Vikram



From alain.volmat at foss.st.com  Tue Dec 17 09:47:22 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:47:22 +0100
Subject: [PATCH v4 13/15] media: stm32: dcmipp: add core support for the
 stm32mp25
In-Reply-To: <Z17Ry6Z9OMqP1MV-@valkosipuli.retiisi.eu>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
 <20241212-csi_dcmipp_mp25-v4-13-fbeb55a05ed7@foss.st.com>
 <Z17Ry6Z9OMqP1MV-@valkosipuli.retiisi.eu>
Message-ID: <20241217174722.GC3784949@gnbcxd0016.gnb.st.com>

Hi Sakari,

On Sun, Dec 15, 2024 at 12:55:39PM +0000, Sakari Ailus wrote:
> Hi Alain,
> 
> On Thu, Dec 12, 2024 at 10:17:37AM +0100, Alain Volmat wrote:
> > The stm32mp25 supports both parallel & csi inputs.
> > An additional clock control is necessary.
> > Skeleton of the subdev structures for the stm32mp25 is added,
> > identical for the time being to the stm32mp13 however more subdeves
> > will be added in further commits.
> > 
> > Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> > ---
> > v4:
> >   - correct clock handling within dcmipp_runtime_resume
> > ---
> >  .../platform/st/stm32/stm32-dcmipp/dcmipp-core.c   | 104 +++++++++++++++++----
> >  1 file changed, 85 insertions(+), 19 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 62dd17e0488d..71acf539e1f3 100644
> > --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
> > +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
> > @@ -40,6 +40,7 @@ struct dcmipp_device {
> >  
> >  	/* Hardware resources */
> >  	void __iomem			*regs;
> > +	struct clk			*mclk;
> >  	struct clk			*kclk;
> >  
> >  	/* The pipeline configuration */
> > @@ -132,6 +133,40 @@ static const struct dcmipp_pipeline_config stm32mp13_pipe_cfg = {
> >  	.hw_revision	= DCMIPP_STM32MP13_VERR
> >  };
> >  
> > +static const struct dcmipp_ent_config stm32mp25_ent_config[] = {
> > +	{
> > +		.name = "dcmipp_input",
> > +		.init = dcmipp_inp_ent_init,
> > +		.release = dcmipp_inp_ent_release,
> > +	},
> > +	{
> > +		.name = "dcmipp_dump_postproc",
> > +		.init = dcmipp_byteproc_ent_init,
> > +		.release = dcmipp_byteproc_ent_release,
> > +	},
> > +	{
> > +		.name = "dcmipp_dump_capture",
> > +		.init = dcmipp_bytecap_ent_init,
> > +		.release = dcmipp_bytecap_ent_release,
> > +	},
> > +};
> > +
> > +static const struct dcmipp_ent_link stm32mp25_ent_links[] = {
> > +	DCMIPP_ENT_LINK(ID_INPUT, 1, ID_DUMP_BYTEPROC, 0,
> > +			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
> > +	DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE,  0,
> > +			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
> > +};
> > +
> > +#define DCMIPP_STM32MP25_VERR  0x30
> > +static const struct dcmipp_pipeline_config stm32mp25_pipe_cfg = {
> > +	.ents		= stm32mp25_ent_config,
> > +	.num_ents	= ARRAY_SIZE(stm32mp25_ent_config),
> > +	.links		= stm32mp25_ent_links,
> > +	.num_links	= ARRAY_SIZE(stm32mp25_ent_links),
> > +	.hw_revision    = DCMIPP_STM32MP25_VERR
> > +};
> > +
> >  #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\
> >  			     (f) == MEDIA_LNK_FL_ENABLED ? "ENABLED" :\
> >  			     (f) == MEDIA_LNK_FL_IMMUTABLE ? "IMMUTABLE" :\
> > @@ -212,6 +247,7 @@ static int dcmipp_create_subdevs(struct dcmipp_device *dcmipp)
> >  
> >  static const struct of_device_id dcmipp_of_match[] = {
> >  	{ .compatible = "st,stm32mp13-dcmipp", .data = &stm32mp13_pipe_cfg },
> > +	{ .compatible = "st,stm32mp25-dcmipp", .data = &stm32mp25_pipe_cfg },
> >  	{ /* end node */ },
> >  };
> >  MODULE_DEVICE_TABLE(of, dcmipp_of_match);
> > @@ -261,13 +297,22 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
> >  {
> >  	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
> >  	unsigned int ret;
> > -	int src_pad;
> > +	int src_pad, i;
> 
> unsigned int?

Done

> 
> >  	struct dcmipp_ent_device *sink;
> > -	struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL };
> > +	struct v4l2_fwnode_endpoint vep = { 0 };
> >  	struct fwnode_handle *ep;
> > +	enum v4l2_mbus_type supported_types[] = {
> > +		V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, V4L2_MBUS_CSI2_DPHY
> > +	};
> > +	int supported_types_nb = ARRAY_SIZE(supported_types);
> >  
> >  	dev_dbg(dcmipp->dev, "Subdev \"%s\" bound\n", subdev->name);
> >  
> > +	/* Only MP25 supports CSI input */
> > +	if (!of_device_is_compatible(dcmipp->dev->of_node,
> > +				     "st,stm32mp25-dcmipp"))
> 
> This would be much cleaner with match data. You seem to already be using it
> for other purposes. 

Added a new boolean within the match structure to indicate if csi is
supported or not.

> 
> > +		supported_types_nb--;
> > +
> >  	/*
> >  	 * Link this sub-device to DCMIPP, it could be
> >  	 * a parallel camera sensor or a CSI-2 to parallel bridge
> > @@ -284,21 +329,23 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
> >  		return -ENODEV;
> >  	}
> >  
> > -	/* Check for parallel bus-type first, then bt656 */
> > -	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> > -	if (ret) {
> > -		vep.bus_type = V4L2_MBUS_BT656;
> > +	/* Check for supported MBUS type */
> > +	for (i = 0; i < supported_types_nb; i++) {
> > +		vep.bus_type = supported_types[i];
> >  		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> > -		if (ret) {
> > -			dev_err(dcmipp->dev, "Could not parse the endpoint\n");
> > -			fwnode_handle_put(ep);
> > -			return ret;
> > -		}
> > +		if (!ret)
> > +			break;
> >  	}
> >  
> >  	fwnode_handle_put(ep);
> >  
> > -	if (vep.bus.parallel.bus_width == 0) {
> > +	if (ret) {
> > +		dev_err(dcmipp->dev, "Could not parse the endpoint\n");
> > +		return ret;
> > +	}
> > +
> > +	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY &&
> > +	    vep.bus.parallel.bus_width == 0) {
> >  		dev_err(dcmipp->dev, "Invalid parallel interface bus-width\n");
> >  		return -ENODEV;
> >  	}
> > @@ -311,11 +358,13 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
> >  		return -ENODEV;
> >  	}
> >  
> > -	/* Parallel input device detected, connect it to parallel subdev */
> > +	/* Connect input device to the dcmipp_input subdev */
> >  	sink = dcmipp->entity[ID_INPUT];
> > -	sink->bus.flags = vep.bus.parallel.flags;
> > -	sink->bus.bus_width = vep.bus.parallel.bus_width;
> > -	sink->bus.data_shift = vep.bus.parallel.data_shift;
> > +	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) {
> > +		sink->bus.flags = vep.bus.parallel.flags;
> > +		sink->bus.bus_width = vep.bus.parallel.bus_width;
> > +		sink->bus.data_shift = vep.bus.parallel.data_shift;
> > +	}
> >  	sink->bus_type = vep.bus_type;
> >  	ret = media_create_pad_link(&subdev->entity, src_pad, sink->ent, 0,
> >  				    MEDIA_LNK_FL_IMMUTABLE |
> > @@ -414,7 +463,7 @@ static int dcmipp_graph_init(struct dcmipp_device *dcmipp)
> >  static int dcmipp_probe(struct platform_device *pdev)
> >  {
> >  	struct dcmipp_device *dcmipp;
> > -	struct clk *kclk;
> > +	struct clk *kclk, *mclk;
> >  	const struct dcmipp_pipeline_config *pipe_cfg;
> >  	struct reset_control *rstc;
> >  	int irq;
> > @@ -474,12 +523,20 @@ static int dcmipp_probe(struct platform_device *pdev)
> >  		return ret;
> >  	}
> >  
> > -	kclk = devm_clk_get(&pdev->dev, NULL);
> > +	kclk = devm_clk_get(&pdev->dev, "kclk");
> >  	if (IS_ERR(kclk))
> >  		return dev_err_probe(&pdev->dev, PTR_ERR(kclk),
> >  				     "Unable to get kclk\n");
> >  	dcmipp->kclk = kclk;
> >  
> > +	if (!of_device_is_compatible(pdev->dev.of_node, "st,stm32mp13-dcmipp")) {
> 
> Same here.

Done as well via match structure.

> 
> > +		mclk = devm_clk_get(&pdev->dev, "mclk");
> > +		if (IS_ERR(mclk))
> > +			return dev_err_probe(&pdev->dev, PTR_ERR(mclk),
> > +					     "Unable to get mclk\n");
> > +		dcmipp->mclk = mclk;
> > +	}
> > +
> >  	dcmipp->entity = devm_kcalloc(&pdev->dev, dcmipp->pipe_cfg->num_ents,
> >  				      sizeof(*dcmipp->entity), GFP_KERNEL);
> >  	if (!dcmipp->entity)
> > @@ -542,6 +599,7 @@ static int dcmipp_runtime_suspend(struct device *dev)
> >  	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
> >  
> >  	clk_disable_unprepare(dcmipp->kclk);
> > +	clk_disable_unprepare(dcmipp->mclk);
> >  
> >  	return 0;
> >  }
> > @@ -551,9 +609,17 @@ static int dcmipp_runtime_resume(struct device *dev)
> >  	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
> >  	int ret;
> >  
> > +	ret = clk_prepare_enable(dcmipp->mclk);
> > +	if (ret) {
> > +		dev_err(dev, "%s: Failed to prepare_enable mclk\n", __func__);
> > +		return ret;
> > +	}
> > +
> >  	ret = clk_prepare_enable(dcmipp->kclk);
> > -	if (ret)
> > +	if (ret) {
> > +		clk_disable_unprepare(dcmipp->mclk);
> >  		dev_err(dev, "%s: Failed to prepare_enable kclk\n", __func__);
> > +	}
> >  
> >  	return ret;
> >  }
> > 
> > 
> 
> -- 
> Kind regards,
> 
> Sakari Ailus


From ninad at linux.ibm.com  Tue Dec 17 09:35:32 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Tue, 17 Dec 2024 11:35:32 -0600
Subject: [PATCH v4 1/4] hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
In-Reply-To: <20241217173537.192331-1-ninad@linux.ibm.com>
References: <20241217173537.192331-1-ninad@linux.ibm.com>
Message-ID: <20241217173537.192331-2-ninad@linux.ibm.com>

Add debugfs file for the PMBUS_REVISION command. This command provides
information about PMBus protocol revision number.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 drivers/hwmon/pmbus/pmbus_core.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index a7000314e5ad..787683e83db6 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -3534,11 +3534,11 @@ static int pmbus_init_debugfs(struct i2c_client *client,
 
 	/*
 	 * Allocate the max possible entries we need.
-	 * 6 entries device-specific
+	 * 7 entries device-specific
 	 * 10 entries page-specific
 	 */
 	entries = devm_kcalloc(data->dev,
-			       6 + data->info->pages * 10, sizeof(*entries),
+			       7 + data->info->pages * 10, sizeof(*entries),
 			       GFP_KERNEL);
 	if (!entries)
 		return -ENOMEM;
@@ -3551,6 +3551,15 @@ static int pmbus_init_debugfs(struct i2c_client *client,
 	 * assume that values of the following registers are the same for all
 	 * pages and report values only for page 0.
 	 */
+	if (pmbus_check_byte_register(client, 0, PMBUS_REVISION)) {
+		entries[idx].client = client;
+		entries[idx].page = 0;
+		entries[idx].reg = PMBUS_REVISION;
+		debugfs_create_file("revision", 0444, data->debugfs,
+				    &entries[idx++],
+				    &pmbus_debugfs_ops);
+	}
+
 	if (pmbus_check_block_register(client, 0, PMBUS_MFR_ID)) {
 		entries[idx].client = client;
 		entries[idx].page = 0;
-- 
2.43.0



From ninad at linux.ibm.com  Tue Dec 17 09:35:35 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Tue, 17 Dec 2024 11:35:35 -0600
Subject: [PATCH v4 4/4] ARM: dts: aspeed: system1: Use crps PSU driver
In-Reply-To: <20241217173537.192331-1-ninad@linux.ibm.com>
References: <20241217173537.192331-1-ninad@linux.ibm.com>
Message-ID: <20241217173537.192331-5-ninad@linux.ibm.com>

The system1 uses Intel common redundant (crps185) power supplies so move
to correct new crps driver.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
index 8f77bc9e860c..360b9ce3c850 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-system1.dts
@@ -681,22 +681,22 @@ &i2c2 {
 	status = "okay";
 
 	power-supply at 58 {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x58>;
 	};
 
 	power-supply at 59 {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x59>;
 	};
 
 	power-supply at 5a {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x5a>;
 	};
 
 	power-supply at 5b {
-		compatible = "ibm,cffps";
+		compatible = "intel,crps185";
 		reg = <0x5b>;
 	};
 };
-- 
2.43.0



From ninad at linux.ibm.com  Tue Dec 17 09:35:31 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Tue, 17 Dec 2024 11:35:31 -0600
Subject: [PATCH v4 0/4] Add support for Intel CRPS PSU
Message-ID: <20241217173537.192331-1-ninad@linux.ibm.com>

Hello,

Please review the version 3 of patchset.

V4:
---
  - Improved commit message.

V3:
---
  - Improved documentation as per suggestion.
  - Fixed issues in the probe function.
  - Add ACKed string in the commit message
V2:
---
  - Fixed documentation issues.
  - Added pmbus revision debugfs file in the core
  - Remove debugfs and read word from crps185
  - Improved commit messages

Ninad Palsule (4):
  hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
  hwmon: (pmbus/crps) Add Intel CRPS185 power supply
  dt-bindings: hwmon: intel,crps185: Add to trivial
  ARM: dts: aspeed: system1: Use crps PSU driver

 .../devicetree/bindings/trivial-devices.yaml  |  2 +
 Documentation/hwmon/crps.rst                  | 97 +++++++++++++++++++
 Documentation/hwmon/index.rst                 |  1 +
 MAINTAINERS                                   |  7 ++
 .../dts/aspeed/aspeed-bmc-ibm-system1.dts     |  8 +-
 drivers/hwmon/pmbus/Kconfig                   |  9 ++
 drivers/hwmon/pmbus/Makefile                  |  1 +
 drivers/hwmon/pmbus/crps.c                    | 74 ++++++++++++++
 drivers/hwmon/pmbus/pmbus_core.c              | 13 ++-
 9 files changed, 206 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/hwmon/crps.rst
 create mode 100644 drivers/hwmon/pmbus/crps.c

-- 
2.43.0



From ninad at linux.ibm.com  Tue Dec 17 09:35:33 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Tue, 17 Dec 2024 11:35:33 -0600
Subject: [PATCH v4 2/4] hwmon: (pmbus/crps) Add Intel CRPS185 power supply
In-Reply-To: <20241217173537.192331-1-ninad@linux.ibm.com>
References: <20241217173537.192331-1-ninad@linux.ibm.com>
Message-ID: <20241217173537.192331-3-ninad@linux.ibm.com>

Add the driver to monitor Intel common redundant power supply (crps185)
with hwmon over pmbus.

Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 Documentation/hwmon/crps.rst  | 97 +++++++++++++++++++++++++++++++++++
 Documentation/hwmon/index.rst |  1 +
 MAINTAINERS                   |  7 +++
 drivers/hwmon/pmbus/Kconfig   |  9 ++++
 drivers/hwmon/pmbus/Makefile  |  1 +
 drivers/hwmon/pmbus/crps.c    | 74 ++++++++++++++++++++++++++
 6 files changed, 189 insertions(+)
 create mode 100644 Documentation/hwmon/crps.rst
 create mode 100644 drivers/hwmon/pmbus/crps.c

diff --git a/Documentation/hwmon/crps.rst b/Documentation/hwmon/crps.rst
new file mode 100644
index 000000000000..87380b496558
--- /dev/null
+++ b/Documentation/hwmon/crps.rst
@@ -0,0 +1,97 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver crps
+==================
+
+Supported chips:
+
+  * Intel CRPS185
+
+    Prefix: 'crps185'
+
+    Addresses scanned: -
+
+    Datasheet: Only available under NDA.
+
+Authors:
+    Ninad Palsule <ninad at linux.ibm.com>
+
+
+Description
+-----------
+
+This driver implements support for Intel Common Redundant Power supply with
+PMBus support.
+
+The driver is a client driver to the core PMBus driver.
+Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers.
+
+
+Usage Notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices.rst for
+details.
+
+
+Sysfs entries
+-------------
+
+======================= ======================================================
+curr1_label		"iin"
+curr1_input		Measured input current
+curr1_max		Maximum input current
+curr1_max_alarm		Input maximum current high alarm
+curr1_crit		Critial high input current
+curr1_crit_alarm	Input critical current high alarm
+curr1_rated_max		Maximum rated input current
+
+curr2_label		"iout1"
+curr2_input		Measured output current
+curr2_max		Maximum output current
+curr2_max_alarm		Output maximum current high alarm
+curr2_crit		Critial high output current
+curr2_crit_alarm	Output critical current high alarm
+curr2_rated_max		Maximum rated output current
+
+in1_label		"vin"
+in1_input		Measured input voltage
+in1_crit		Critical input over voltage
+in1_crit_alarm		Critical input over voltage alarm
+in1_max			Maximum input over voltage
+in1_max_alarm		Maximum input over voltage alarm
+in1_rated_min		Minimum rated input voltage
+in1_rated_max		Maximum rated input voltage
+
+in2_label		"vout1"
+in2_input		Measured input voltage
+in2_crit		Critical input over voltage
+in2_crit_alarm		Critical input over voltage alarm
+in2_lcrit		Critical input under voltage fault
+in2_lcrit_alarm		Critical input under voltage fault alarm
+in2_max			Maximum input over voltage
+in2_max_alarm		Maximum input over voltage alarm
+in2_min			Minimum input under voltage warning
+in2_min_alarm		Minimum input under voltage warning alarm
+in2_rated_min		Minimum rated input voltage
+in2_rated_max		Maximum rated input voltage
+
+power1_label		"pin"
+power1_input		Measured input power
+power1_alarm		Input power high alarm
+power1_max  		Maximum input power
+power1_rated_max	Maximum rated input power
+
+temp[1-2]_input		Measured temperature
+temp[1-2]_crit 		Critical temperature
+temp[1-2]_crit_alarm	Critical temperature alarm
+temp[1-2]_max		Maximum temperature
+temp[1-2]_max_alarm	Maximum temperature alarm
+temp[1-2]_rated_max	Maximum rated temperature
+
+fan1_alarm		Fan 1 warning.
+fan1_fault		Fan 1 fault.
+fan1_input		Fan 1 speed in RPM.
+fan1_target		Fan 1 target.
+======================= ======================================================
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 1a3cb0a59f72..b1ea445479b0 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -58,6 +58,7 @@ Hardware Monitoring Kernel Drivers
    corsair-cpro
    corsair-psu
    cros_ec_hwmon
+   crps
    da9052
    da9055
    dell-smm-hwmon
diff --git a/MAINTAINERS b/MAINTAINERS
index 7523a456fd6f..e194478ecc55 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6118,6 +6118,13 @@ L:	linux-input at vger.kernel.org
 S:	Maintained
 F:	drivers/hid/hid-creative-sb0540.c
 
+INTEL CRPS COMMON REDUNDANT PSU DRIVER
+M:	Ninad Palsule <ninad at linux.ibm.com>
+L:	linux-hwmon at vger.kernel.org
+S:	Maintained
+F:	Documentation/hwmon/crps.rst
+F:	drivers/hwmon/pmbus/crps.c
+
 CRYPTO API
 M:	Herbert Xu <herbert at gondor.apana.org.au>
 M:	"David S. Miller" <davem at davemloft.net>
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 22418a05ced0..43b6df04e0f9 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -85,6 +85,15 @@ config SENSORS_BPA_RS600
 	  This driver can also be built as a module. If so, the module will
 	  be called bpa-rs600.
 
+config SENSORS_CRPS
+	tristate "Intel Common Redundant Power Supply"
+	help
+	  If you say yes here you get hardware monitoring support for the Intel
+	  Common Redundant Power Supply.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called crps.
+
 config SENSORS_DELTA_AHE50DC_FAN
 	tristate "Delta AHE-50DC fan control module"
 	help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 3d3183f8d2a7..c7eb7739b7f8 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -62,3 +62,4 @@ obj-$(CONFIG_SENSORS_XDPE122)	+= xdpe12284.o
 obj-$(CONFIG_SENSORS_XDPE152)	+= xdpe152c4.o
 obj-$(CONFIG_SENSORS_ZL6100)	+= zl6100.o
 obj-$(CONFIG_SENSORS_PIM4328)	+= pim4328.o
+obj-$(CONFIG_SENSORS_CRPS)	+= crps.o
diff --git a/drivers/hwmon/pmbus/crps.c b/drivers/hwmon/pmbus/crps.c
new file mode 100644
index 000000000000..164b33fed312
--- /dev/null
+++ b/drivers/hwmon/pmbus/crps.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2024 IBM Corp.
+ */
+
+#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/pmbus.h>
+
+#include "pmbus.h"
+
+static const struct i2c_device_id crps_id[] = {
+	{ "intel_crps185" },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, crps_id);
+
+static struct pmbus_driver_info crps_info = {
+	.pages = 1,
+	/* PSU uses default linear data format. */
+	.func[0] = PMBUS_HAVE_PIN | PMBUS_HAVE_IOUT |
+		PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_IIN |
+		PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
+		PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+		PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
+		PMBUS_HAVE_STATUS_TEMP |
+		PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
+};
+
+static int crps_probe(struct i2c_client *client)
+{
+	int rc;
+	struct device *dev = &client->dev;
+	char buf[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
+
+	rc = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
+	if (rc < 0)
+		return dev_err_probe(dev, rc, "Failed to read PMBUS_MFR_MODEL\n");
+
+	if (rc != 7 || strncmp(buf, "03NK260", 7)) {
+		buf[rc] = '\0';
+		return dev_err_probe(dev, -ENODEV, "Model '%s' not supported\n", buf);
+	}
+
+	rc = pmbus_do_probe(client, &crps_info);
+	if (rc)
+		return dev_err_probe(dev, rc, "Failed to probe\n");
+
+	return 0;
+}
+
+static const struct of_device_id crps_of_match[] = {
+	{
+		.compatible = "intel,crps185",
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, crps_of_match);
+
+static struct i2c_driver crps_driver = {
+	.driver = {
+		.name = "crps",
+		.of_match_table = crps_of_match,
+	},
+	.probe = crps_probe,
+	.id_table = crps_id,
+};
+
+module_i2c_driver(crps_driver);
+
+MODULE_AUTHOR("Ninad Palsule");
+MODULE_DESCRIPTION("PMBus driver for Intel Common Redundant power supplies");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("PMBUS");
-- 
2.43.0



From ninad at linux.ibm.com  Tue Dec 17 09:35:34 2024
From: ninad at linux.ibm.com (Ninad Palsule)
Date: Tue, 17 Dec 2024 11:35:34 -0600
Subject: [PATCH v4 3/4] dt-bindings: hwmon: intel,crps185: Add to trivial
In-Reply-To: <20241217173537.192331-1-ninad@linux.ibm.com>
References: <20241217173537.192331-1-ninad@linux.ibm.com>
Message-ID: <20241217173537.192331-4-ninad@linux.ibm.com>

Add INTEL Common Redundant Power Supply Versions crps185 bindings as
trivial. The hardware does not have any resources like clocks which are
required to be included in the device tree.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>
---
 Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index 34e8ac1ddc24..fadbd3c041c8 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -149,6 +149,8 @@ properties:
           - injoinic,ip5306
             # Inspur Power System power supply unit version 1
           - inspur,ipsps1
+            # Intel common redudant power supply crps185
+          - intel,crps185
             # Intersil ISL29028 Ambient Light and Proximity Sensor
           - isil,isl29028
             # Intersil ISL29030 Ambient Light and Proximity Sensor
-- 
2.43.0



From maz at kernel.org  Tue Dec 17 09:38:25 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 17 Dec 2024 17:38:25 +0000
Subject: [PATCH 11/16] KVM: arm64: nv: Add Maintenance Interrupt emulation
In-Reply-To: <20241217151331.934077-12-maz@kernel.org>
References: <20241217151331.934077-1-maz@kernel.org>
	<20241217151331.934077-12-maz@kernel.org>
Message-ID: <86ldweqkfi.wl-maz@kernel.org>

On Tue, 17 Dec 2024 15:13:26 +0000,
Marc Zyngier <maz at kernel.org> wrote:
> 
> Emulating the vGIC means emulating the dreaded Maintenance Interrupt.
> 
> This is a two-pronged problem:
> 
> - while running L2, getting an MI translates into an MI injected
>   in the L1 based on the state of the HW.
> 
> - while running L1, we must accurately reflect the state of the
>   MI line, based on the in-memory state.
> 
> The MI INTID is added to the distributor, as expected on any
> virtualisation-capable implementation, and further patches
> will allow its configuration.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/arm.c                 |  6 ++++
>  arch/arm64/kvm/vgic/vgic-init.c      | 22 ++++++++++++++
>  arch/arm64/kvm/vgic/vgic-v3-nested.c | 45 ++++++++++++++++++++++++++++
>  arch/arm64/kvm/vgic/vgic.c           |  9 ++++++
>  arch/arm64/kvm/vgic/vgic.h           |  2 ++
>  include/kvm/arm_vgic.h               |  4 +++
>  6 files changed, 88 insertions(+)
> 
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 5e353b2c225b4..756cc4e74e10f 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -824,6 +824,12 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
>  	if (ret)
>  		return ret;
>  
> +	if (vcpu_has_nv(vcpu)) {
> +		ret = kvm_vgic_vcpu_nv_init(vcpu);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	/*
>  	 * This needs to happen after any restriction has been applied
>  	 * to the feature set.
> diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
> index bc7e22ab5d812..d2724315a70e9 100644
> --- a/arch/arm64/kvm/vgic/vgic-init.c
> +++ b/arch/arm64/kvm/vgic/vgic-init.c
> @@ -180,6 +180,20 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)
>  	return 0;
>  }
>  
> +int kvm_vgic_vcpu_nv_init(struct kvm_vcpu *vcpu)
> +{
> +	int ret;
> +
> +	guard(mutex)(&vcpu->kvm->arch.config_lock);
> +
> +	/* Cope with vintage userspace. Maybe we should fail instead */
> +	if (vcpu->kvm->arch.vgic.maint_irq == 0)
> +		vcpu->kvm->arch.vgic.maint_irq = kvm_vgic_global_state.maint_irq;

Well, that didn't take too long, and Joey did hit a bug here. Although
the two fields have the same name, they represent something totally
different:

- kvm_vgic_global_state.maint_irq is the interrupt number Linux uses
  for the host. It's just a number, without any signification other
  than for the kernel's own stuff.

- vcpu->kvm->arch.vgic.maint_irq is an GIC INTID. Really not the same
  thing as the above.

What this should read is something like:

diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index d2724315a70e9..8d92b05639588 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -188,7 +188,7 @@ int kvm_vgic_vcpu_nv_init(struct kvm_vcpu *vcpu)
 
 	/* Cope with vintage userspace. Maybe we should fail instead */
 	if (vcpu->kvm->arch.vgic.maint_irq == 0)
-		vcpu->kvm->arch.vgic.maint_irq = kvm_vgic_global_state.maint_irq;
+		vcpu->kvm->arch.vgic.maint_irq = irq_get_irq_data(kvm_vgic_global_state.maint_irq)->hwirq;
 	ret = kvm_vgic_set_owner(vcpu, vcpu->kvm->arch.vgic.maint_irq, vcpu);
 
 	return ret;

So I guess there are two things that need to happen:

- rename vcpu->kvm->arch.vgic.maint_irq to something like "mi_intid"

- make the damn thing fail, as the comment suggests. We don't have any
  legacy worth speaking of anyway.

Another thing is that Joey (who really didn't waste any time finding
issues) pointed out that we happily allow NV without GICv3. Clearly,
this should also be prevented.

Thanks Joey!

	M.

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


From alain.volmat at foss.st.com  Tue Dec 17 09:39:21 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:21 +0100
Subject: [PATCH 4/9] media: stm32: csi: register subdev only at end of
 probe
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-4-2b432805d17d@foss.st.com>

Call v4l2_async_register_subdev only whenever all initialization
are completed at the end of the probe function.
Remove as well useless err_free_priv label by returning directly
upon error.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-csi.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
index e2f63bb47d33..89fcd7d07904 100644
--- a/drivers/media/platform/st/stm32/stm32-csi.c
+++ b/drivers/media/platform/st/stm32/stm32-csi.c
@@ -991,11 +991,11 @@ static int stm32_csi_probe(struct platform_device *pdev)
 
 	ret = stm32_csi_get_resources(csidev, pdev);
 	if (ret)
-		goto err_free_priv;
+		return ret;
 
 	ret = stm32_csi_parse_dt(csidev);
 	if (ret)
-		goto err_free_priv;
+		return ret;
 
 	csidev->sd.owner = THIS_MODULE;
 	csidev->sd.dev = &pdev->dev;
@@ -1020,10 +1020,6 @@ static int stm32_csi_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err_cleanup;
 
-	ret = v4l2_async_register_subdev(&csidev->sd);
-	if (ret < 0)
-		goto err_cleanup;
-
 	/* Reset device */
 	rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(rstc)) {
@@ -1050,6 +1046,10 @@ static int stm32_csi_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(&pdev->dev);
 
+	ret = v4l2_async_register_subdev(&csidev->sd);
+	if (ret < 0)
+		goto err_cleanup;
+
 	dev_info(&pdev->dev,
 		 "Probed CSI with %u lanes\n", csidev->num_lanes);
 
@@ -1057,7 +1057,6 @@ static int stm32_csi_probe(struct platform_device *pdev)
 
 err_cleanup:
 	v4l2_async_nf_cleanup(&csidev->notifier);
-err_free_priv:
 	return ret;
 }
 

-- 
2.34.1



From alain.volmat at foss.st.com  Tue Dec 17 09:39:19 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:19 +0100
Subject: [PATCH 2/9] dt-bindings: media: clarify stm32 csi & simplify
 example
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-2-2b432805d17d@foss.st.com>

Clarify the description of the stm32 csi by mentioning CSI-2 and
D-PHY.
Remove the bus-type property from the example.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
index 33bedfe41924..e9fa3cfea5d2 100644
--- a/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
+++ b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
@@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: STMicroelectronics STM32 CSI controller
 
 description:
-  The STM32 CSI controller allows connecting a CSI based
-  camera to the DCMIPP camera pipeline.
+  The STM32 CSI controller, coupled with a D-PHY allows connecting a CSI-2
+  based camera to the DCMIPP camera pipeline.
 
 maintainers:
   - Alain Volmat <alain.volmat at foss.st.com>
@@ -109,7 +109,6 @@ examples:
                 endpoint {
                     remote-endpoint = <&imx335_ep>;
                     data-lanes = <1 2>;
-                    bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
                 };
             };
 

-- 
2.34.1



From alain.volmat at foss.st.com  Tue Dec 17 09:39:26 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:26 +0100
Subject: [PATCH 9/9] media: stm32: dcmipp: add has_csi2 & needs_mclk in
 match data
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-9-2b432805d17d@foss.st.com>

Introduce two variable has_csi and has_mclk within the
match data of the driver in order to know, depending on
the compatible if CSI-2 interface is available and if
the mclk clk should be retrieved.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 .../platform/st/stm32/stm32-dcmipp/dcmipp-core.c   | 23 ++++++++++++----------
 1 file changed, 13 insertions(+), 10 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 5a04018a6a9d..1b7bae3266c8 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
@@ -89,6 +89,8 @@ struct dcmipp_pipeline_config {
 	const struct dcmipp_ent_link *links;
 	size_t num_links;
 	u32 hw_revision;
+	bool has_csi2;
+	bool needs_mclk;
 };
 
 /* --------------------------------------------------------------------------
@@ -164,7 +166,9 @@ static const struct dcmipp_pipeline_config stm32mp25_pipe_cfg = {
 	.num_ents	= ARRAY_SIZE(stm32mp25_ent_config),
 	.links		= stm32mp25_ent_links,
 	.num_links	= ARRAY_SIZE(stm32mp25_ent_links),
-	.hw_revision    = DCMIPP_STM32MP25_VERR
+	.hw_revision    = DCMIPP_STM32MP25_VERR,
+	.has_csi2	= true,
+	.needs_mclk	= true
 };
 
 #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\
@@ -296,7 +300,7 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
 				     struct v4l2_async_connection *asd)
 {
 	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
-	int ret;
+	int ret = -EINVAL;
 	int src_pad, i;
 	struct dcmipp_ent_device *sink;
 	struct v4l2_fwnode_endpoint vep = { 0 };
@@ -304,15 +308,9 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
 	enum v4l2_mbus_type supported_types[] = {
 		V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, V4L2_MBUS_CSI2_DPHY
 	};
-	int supported_types_nb = ARRAY_SIZE(supported_types);
 
 	dev_dbg(dcmipp->dev, "Subdev \"%s\" bound\n", subdev->name);
 
-	/* Only MP25 supports CSI input */
-	if (!of_device_is_compatible(dcmipp->dev->of_node,
-				     "st,stm32mp25-dcmipp"))
-		supported_types_nb--;
-
 	/*
 	 * Link this sub-device to DCMIPP, it could be
 	 * a parallel camera sensor or a CSI-2 to parallel bridge
@@ -330,7 +328,12 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
 	}
 
 	/* Check for supported MBUS type */
-	for (i = 0; i < supported_types_nb; i++) {
+	for (i = 0; i < ARRAY_SIZE(supported_types); i++) {
+		/* Only MP25 supports CSI input */
+		if (supported_types[i] == V4L2_MBUS_CSI2_DPHY &&
+		    !dcmipp->pipe_cfg->has_csi2)
+			continue;
+
 		vep.bus_type = supported_types[i];
 		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
 		if (!ret)
@@ -529,7 +532,7 @@ static int dcmipp_probe(struct platform_device *pdev)
 				     "Unable to get kclk\n");
 	dcmipp->kclk = kclk;
 
-	if (!of_device_is_compatible(pdev->dev.of_node, "st,stm32mp13-dcmipp")) {
+	if (dcmipp->pipe_cfg->needs_mclk) {
 		mclk = devm_clk_get(&pdev->dev, "mclk");
 		if (IS_ERR(mclk))
 			return dev_err_probe(&pdev->dev, PTR_ERR(mclk),

-- 
2.34.1



From alain.volmat at foss.st.com  Tue Dec 17 09:39:25 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:25 +0100
Subject: [PATCH 8/9] media: stm32: csi: correct unsigned or useless
 variable settings
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-8-2b432805d17d@foss.st.com>

Correct several missing unsigned type missing for loop variables
and also remove useless initialization of variables.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-csi.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
index 1be12c9dcf55..602b0879f21e 100644
--- a/drivers/media/platform/st/stm32/stm32-csi.c
+++ b/drivers/media/platform/st/stm32/stm32-csi.c
@@ -357,7 +357,7 @@ static inline struct stm32_csi_dev *to_csidev(struct v4l2_subdev *sd)
 static int stm32_csi_setup_lane_merger(struct stm32_csi_dev *csidev)
 {
 	u32 lmcfgr = 0;
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < csidev->num_lanes; i++) {
 		if (!csidev->lanes[i] || csidev->lanes[i] > STM32_CSI_LANES_MAX) {
@@ -595,20 +595,20 @@ static int stm32_csi_start_vc(struct stm32_csi_dev *csidev,
 {
 	struct v4l2_mbus_framefmt *mbus_fmt;
 	const struct stm32_csi_fmts *fmt;
-	u32 cfgr1 = 0;
-	int ret = 0;
 	u32 status;
+	u32 cfgr1;
+	int ret;
 
 	mbus_fmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SOURCE);
 	fmt = stm32_csi_code_to_fmt(mbus_fmt->code);
 
 	/* If the mbus code is JPEG, don't enable filtering */
 	if (mbus_fmt->code == MEDIA_BUS_FMT_JPEG_1X8) {
-		cfgr1 |= STM32_CSI_VCXCFGR1_ALLDT;
+		cfgr1 = STM32_CSI_VCXCFGR1_ALLDT;
 		cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_CDTFT_SHIFT;
 		dev_dbg(csidev->dev, "VC%d: enable AllDT mode\n", vc);
 	} else {
-		cfgr1 |= fmt->datatype << STM32_CSI_VCXCFGR1_DT0_SHIFT;
+		cfgr1 = fmt->datatype << STM32_CSI_VCXCFGR1_DT0_SHIFT;
 		cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_DT0FT_SHIFT;
 		cfgr1 |= STM32_CSI_VCXCFGR1_DT0EN;
 		dev_dbg(csidev->dev, "VC%d: enable DT0(0x%x)/DT0FT(0x%x)\n",
@@ -634,8 +634,8 @@ static int stm32_csi_start_vc(struct stm32_csi_dev *csidev,
 
 static int stm32_csi_stop_vc(struct stm32_csi_dev *csidev, u32 vc)
 {
-	int ret = 0;
 	u32 status;
+	int ret;
 
 	/* Stop the Virtual Channel */
 	writel_relaxed(STM32_CSI_CR_VCXSTOP(vc) | STM32_CSI_CR_CSIEN,
@@ -714,7 +714,7 @@ static int stm32_csi_enable_streams(struct v4l2_subdev *sd,
 static int stm32_csi_init_state(struct v4l2_subdev *sd,
 				struct v4l2_subdev_state *state)
 {
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < sd->entity.num_pads; i++)
 		*v4l2_subdev_state_get_format(state, i) = fmt_default;
@@ -879,7 +879,8 @@ static irqreturn_t stm32_csi_irq_thread(int irq, void *arg)
 static int stm32_csi_get_resources(struct stm32_csi_dev *csidev,
 				   struct platform_device *pdev)
 {
-	int irq, ret, i;
+	unsigned int i;
+	int irq, ret;
 
 	csidev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
 	if (IS_ERR(csidev->base))

-- 
2.34.1



From alain.volmat at foss.st.com  Tue Dec 17 09:39:20 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:20 +0100
Subject: [PATCH 3/9] media: stm32: csi: add missing pm_runtime_put on error
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-3-2b432805d17d@foss.st.com>

Within the stm32_csi_start function, pm_runtime_put should
be called upon error following pm_runtime_get_sync.
Rework the function error handling by putting a label in
order to have common error handling for all calls requiring
pm_runtime_put.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-csi.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
index 48941aae8c9b..e2f63bb47d33 100644
--- a/drivers/media/platform/st/stm32/stm32-csi.c
+++ b/drivers/media/platform/st/stm32/stm32-csi.c
@@ -497,21 +497,19 @@ static int stm32_csi_start(struct stm32_csi_dev *csidev,
 
 	ret = pm_runtime_get_sync(csidev->dev);
 	if (ret < 0)
-		return ret;
+		goto error_put;
 
 	/* Retrieve CSI2PHY clock rate to compute CCFR value */
 	phy_clk_frate = clk_get_rate(csidev->clks[STM32_CSI_CLK_CSI2PHY].clk);
 	if (!phy_clk_frate) {
-		pm_runtime_put(csidev->dev);
 		dev_err(csidev->dev, "CSI2PHY clock rate invalid (0)\n");
-		return ret;
+		ret = -EINVAL;
+		goto error_put;
 	}
 
 	ret = stm32_csi_setup_lane_merger(csidev);
-	if (ret) {
-		pm_runtime_put(csidev->dev);
-		return ret;
-	}
+	if (ret)
+		goto error_put;
 
 	/* Enable the CSI */
 	writel_relaxed(STM32_CSI_CR_CSIEN, csidev->base + STM32_CSI_CR);
@@ -567,6 +565,10 @@ static int stm32_csi_start(struct stm32_csi_dev *csidev,
 	writel_relaxed(0, csidev->base + STM32_CSI_PMCR);
 
 	return ret;
+
+error_put:
+	pm_runtime_put(csidev->dev);
+	return ret;
 }
 
 static void stm32_csi_stop(struct stm32_csi_dev *csidev)

-- 
2.34.1



From alain.volmat at foss.st.com  Tue Dec 17 09:39:17 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:17 +0100
Subject: [PATCH 0/9] media: stm32: csi / dcmipp corrections
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>

Various fixes within the stm32 csi bindings/drivers and
stm32 dcmipp driver.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
Alain Volmat (9):
      media: stm32: dcmipp: correct ret type in dcmipp_graph_notify_bound
      dt-bindings: media: clarify stm32 csi & simplify example
      media: stm32: csi: add missing pm_runtime_put on error
      media: stm32: csi: register subdev only at end of probe
      media: stm32: csi: use ARRAY_SIZE to search D-PHY table
      media: stm32: csi: simplify enable_streams error handling
      media: stm32: csi: remove useless fwnode_graph_get_endpoint call
      media: stm32: csi: correct unsigned or useless variable settings
      media: stm32: dcmipp: add has_csi2 & needs_mclk in match data

 .../bindings/media/st,stm32mp25-csi.yaml           |   5 +-
 drivers/media/platform/st/stm32/stm32-csi.c        | 102 +++++++++++----------
 .../platform/st/stm32/stm32-dcmipp/dcmipp-core.c   |  23 +++--
 3 files changed, 67 insertions(+), 63 deletions(-)
---
base-commit: d216d9cb4dd854ef0a2ec1701f403facb298af51
change-id: 20241217-csi_dcmipp_mp25_enhancements-89e0eef194bf

Best regards,
-- 
Alain Volmat <alain.volmat at foss.st.com>



From alain.volmat at foss.st.com  Tue Dec 17 09:39:24 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:24 +0100
Subject: [PATCH 7/9] media: stm32: csi: remove useless
 fwnode_graph_get_endpoint call
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-7-2b432805d17d@foss.st.com>

The endpoint is already retrieved at the beginning of the function
stm32_csi_parse_dt hence keep the endpoint pointer until the end
instead of getting a new one.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-csi.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
index 4affbc00b042..1be12c9dcf55 100644
--- a/drivers/media/platform/st/stm32/stm32-csi.c
+++ b/drivers/media/platform/st/stm32/stm32-csi.c
@@ -932,38 +932,32 @@ static int stm32_csi_parse_dt(struct stm32_csi_dev *csidev)
 	}
 
 	ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
-	fwnode_handle_put(ep);
 	if (ret) {
 		dev_err(csidev->dev, "Could not parse v4l2 endpoint\n");
-		return ret;
+		goto out;
 	}
 
 	csidev->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
 	if (csidev->num_lanes > STM32_CSI_LANES_MAX) {
 		dev_err(csidev->dev, "Unsupported number of data-lanes: %d\n",
 			csidev->num_lanes);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	memcpy(csidev->lanes, v4l2_ep.bus.mipi_csi2.data_lanes,
 	       sizeof(csidev->lanes));
 
-	ep = fwnode_graph_get_next_endpoint(dev_fwnode(csidev->dev), NULL);
-	if (!ep) {
-		dev_err(csidev->dev, "Failed to get next endpoint\n");
-		return -EINVAL;
-	}
-
 	v4l2_async_subdev_nf_init(&csidev->notifier, &csidev->sd);
 
 	asd = v4l2_async_nf_add_fwnode_remote(&csidev->notifier, ep,
 					      struct v4l2_async_connection);
 
-	fwnode_handle_put(ep);
 
 	if (IS_ERR(asd)) {
 		dev_err(csidev->dev, "Failed to add fwnode remote subdev\n");
-		return PTR_ERR(asd);
+		ret = PTR_ERR(asd);
+		goto out;
 	}
 
 	csidev->notifier.ops = &stm32_csi_notifier_ops;
@@ -972,9 +966,11 @@ static int stm32_csi_parse_dt(struct stm32_csi_dev *csidev)
 	if (ret) {
 		dev_err(csidev->dev, "Failed to register notifier\n");
 		v4l2_async_nf_cleanup(&csidev->notifier);
-		return ret;
+		goto out;
 	}
 
+out:
+	fwnode_handle_put(ep);
 	return ret;
 }
 

-- 
2.34.1



From alain.volmat at foss.st.com  Tue Dec 17 09:39:18 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:18 +0100
Subject: [PATCH 1/9] media: stm32: dcmipp: correct ret type in
 dcmipp_graph_notify_bound
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-1-2b432805d17d@foss.st.com>

The ret variable used within the function dcmipp_graph_notify_bound is
wrongly defined as unsigned int while it can also be signed.

Fixes: 28e0f3772296 ("media: stm32-dcmipp: STM32 DCMIPP camera interface driver")
Cc: stable at vger.kernel.org
Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 71acf539e1f3..5a04018a6a9d 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
@@ -296,7 +296,7 @@ static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
 				     struct v4l2_async_connection *asd)
 {
 	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
-	unsigned int ret;
+	int ret;
 	int src_pad, i;
 	struct dcmipp_ent_device *sink;
 	struct v4l2_fwnode_endpoint vep = { 0 };

-- 
2.34.1



From alain.volmat at foss.st.com  Tue Dec 17 09:39:22 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:22 +0100
Subject: [PATCH 5/9] media: stm32: csi: use ARRAY_SIZE to search D-PHY
 table
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-5-2b432805d17d@foss.st.com>

Within stm32_csi_start, use ARRAY_SIZE loop in order to search
for the right setting.
Avoid useless init of lanes_ie / lanes_en.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-csi.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
index 89fcd7d07904..3654f9895dbc 100644
--- a/drivers/media/platform/st/stm32/stm32-csi.c
+++ b/drivers/media/platform/st/stm32/stm32-csi.c
@@ -325,7 +325,6 @@ static const struct stm32_csi_mbps_phy_reg snps_stm32mp25[] = {
 	{ .mbps = 2400, .hsfreqrange = 0x47,	.osc_freq_target = 442 },
 	{ .mbps = 2450, .hsfreqrange = 0x48,	.osc_freq_target = 451 },
 	{ .mbps = 2500, .hsfreqrange = 0x49,	.osc_freq_target = 460 },
-	{ /* sentinel */ }
 };
 
 static const struct v4l2_mbus_framefmt fmt_default = {
@@ -444,13 +443,13 @@ static void stm32_csi_phy_reg_write(struct stm32_csi_dev *csidev,
 static int stm32_csi_start(struct stm32_csi_dev *csidev,
 			   struct v4l2_subdev_state *state)
 {
-	const struct stm32_csi_mbps_phy_reg *phy_regs;
+	const struct stm32_csi_mbps_phy_reg *phy_regs = NULL;
 	struct v4l2_mbus_framefmt *sink_fmt;
 	const struct stm32_csi_fmts *fmt;
 	unsigned long phy_clk_frate;
+	u32 lanes_ie, lanes_en;
 	unsigned int mbps;
-	u32 lanes_ie = 0;
-	u32 lanes_en = 0;
+	unsigned int i;
 	s64 link_freq;
 	int ret;
 	u32 ccfr;
@@ -474,11 +473,14 @@ static int stm32_csi_start(struct stm32_csi_dev *csidev,
 	mbps = div_s64(link_freq, 500000);
 	dev_dbg(csidev->dev, "Computed Mbps: %u\n", mbps);
 
-	for (phy_regs = snps_stm32mp25; phy_regs->mbps != 0; phy_regs++)
-		if (phy_regs->mbps >= mbps)
+	for (i = 0; i < ARRAY_SIZE(snps_stm32mp25); i++) {
+		if (snps_stm32mp25[i].mbps >= mbps) {
+			phy_regs = &snps_stm32mp25[i];
 			break;
+		}
+	}
 
-	if (!phy_regs->mbps) {
+	if (!phy_regs) {
 		dev_err(csidev->dev, "Unsupported PHY speed (%u Mbps)", mbps);
 		return -ERANGE;
 	}
@@ -488,8 +490,8 @@ static int stm32_csi_start(struct stm32_csi_dev *csidev,
 		phy_regs->osc_freq_target);
 
 	/* Prepare lanes related configuration bits */
-	lanes_ie |= STM32_CSI_SR1_DL0_ERRORS;
-	lanes_en |= STM32_CSI_PCR_DL0EN;
+	lanes_ie = STM32_CSI_SR1_DL0_ERRORS;
+	lanes_en = STM32_CSI_PCR_DL0EN;
 	if (csidev->num_lanes == 2) {
 		lanes_ie |= STM32_CSI_SR1_DL1_ERRORS;
 		lanes_en |= STM32_CSI_PCR_DL1EN;

-- 
2.34.1



From alain.volmat at foss.st.com  Tue Dec 17 09:39:23 2024
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Tue, 17 Dec 2024 18:39:23 +0100
Subject: [PATCH 6/9] media: stm32: csi: simplify enable_streams error
 handling
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
Message-ID: <20241217-csi_dcmipp_mp25_enhancements-v1-6-2b432805d17d@foss.st.com>

Put all error handling for VC stop and CSI stop together
to avoid duplication of code.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/st/stm32/stm32-csi.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
index 3654f9895dbc..4affbc00b042 100644
--- a/drivers/media/platform/st/stm32/stm32-csi.c
+++ b/drivers/media/platform/st/stm32/stm32-csi.c
@@ -694,19 +694,21 @@ static int stm32_csi_enable_streams(struct v4l2_subdev *sd,
 	ret = stm32_csi_start_vc(csidev, state, 0);
 	if (ret) {
 		dev_err(csidev->dev, "Failed to start VC0\n");
-		stm32_csi_stop(csidev);
-		return ret;
+		goto failed_start_vc;
 	}
 
 	ret = v4l2_subdev_enable_streams(csidev->s_subdev,
 					 csidev->s_subdev_pad_nb, BIT_ULL(0));
-	if (ret) {
-		stm32_csi_stop_vc(csidev, 0);
-		stm32_csi_stop(csidev);
-		return ret;
-	}
+	if (ret)
+		goto failed_enable_streams;
 
 	return 0;
+
+failed_enable_streams:
+	stm32_csi_stop_vc(csidev, 0);
+failed_start_vc:
+	stm32_csi_stop(csidev);
+	return ret;
 }
 
 static int stm32_csi_init_state(struct v4l2_subdev *sd,

-- 
2.34.1



From markuss.broks at gmail.com  Tue Dec 17 09:42:32 2024
From: markuss.broks at gmail.com (Markuss Broks)
Date: Tue, 17 Dec 2024 19:42:32 +0200
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <56c5788a-2d49-4abb-af4b-65a11bdc4094@kernel.org>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
 <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
 <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>
 <6e93d59d-71e5-4c09-862f-55b5504121aa@gmail.com>
 <69fd1dbc-a29f-488c-a30f-7e5ea8f01a23@kernel.org>
 <17fbfcdd-8b79-4907-a4c8-798da0ef0526@gmail.com>
 <56c5788a-2d49-4abb-af4b-65a11bdc4094@kernel.org>
Message-ID: <685eb8ab-2767-43da-80d0-ec77ff779d86@gmail.com>

Hi Krzysztof,

On 12/17/24 11:43 AM, Krzysztof Kozlowski wrote:
> On 17/12/2024 10:31, Ivaylo Ivanov wrote:
>> On 12/17/24 11:26, Krzysztof Kozlowski wrote:
>>> On 17/12/2024 10:08, Ivaylo Ivanov wrote:
>>>>>>>>         - items:
>>>>>>>>             - enum:
>>>>>>>> @@ -94,9 +95,28 @@ allOf:
>>>>>>>>           - clock-names
>>>>>>>>   
>>>>>>>>       else:
>>>>>>>> -      properties:
>>>>>>>> -        clocks:
>>>>>>>> -          maxItems: 1
>>>>>>>> +      if:
>>>>>>>> +        properties:
>>>>>>>> +          compatible:
>>>>>>>> +            contains:
>>>>>>>> +              enum:
>>>>>>>> +                - samsung,exynos8895-hsi2c
>>>>>>>> +
>>>>>>>> +      then:
>>>>>>>> +        properties:
>>>>>>>> +          clocks:
>>>>>>> Missing minItems
>>>>>>>
>>>>>>>> +            maxItems: 2
>>>>>>>> +
>>>>>>>> +          clock-names:
>>>>>>> Ditto
>>>>>>>
>>>>>>>> +            maxItems: 2
>>>>>>>> +
>>>>>>>> +        required:
>>>>>>>> +          - clock-names
>>>>>>> I don't understand why do you need second, same branch in if, basically
>>>>>> Because, as I stated in the commit message, we have HSI2C controllers
>>>>>> both implemented in USIv1 blocks and outside. These that are a part of
>>>>> On Exynos8895? Where? With the same compatible?
>>>> hsi2c_0 which has a clock from BUSC and hsi2c_1 to hsi2c_4 which use clocks
>>>> from PERIC1 (CLK_GOUT_PERIC1_HSI2C_CAM{0,1,2,3}_IPCLK). Why would
>>>> they need a different compatible though? It's functionally the same i2c design
>>>> as the one implemented in USIv1 blocks.
>>> If one block is part of USI and other not, they might not be the same
>>> I2C blocks, even if interface is similar. If they were the same or even
>>> functionally the same, they would have the same clock inputs. However
>> I see, so in such case I should make samsung,exynos8895-hsi2c-nonusi or
>> something like that?
>>
>>> user manual also suggests that there is only one clock, not two (for
>>> both cases), so they could be functionally equivalent but then number of
>>> clocks looks incorrect.
>> That'd be weird. Both according to downstream and upstream clk driver,
>> for the USI-implemented i2cs we have a pclk and an sclk_usi.
> Something is not precise here, as usually with Samsung clock topology.
>
> First, the non-USI instances have the IPCLK as well, e.g. things like
> PERIC1_UID_HSI2C_CAM1_IPCLKPORT_iPCLK
>
> USI have BLK_PERIC0_UID_USI03_IPCLKPORT_i_SCLK_USI, but that's USI
> clock, not HSI2C in USI. Datasheet mentions this is UART and SPI special
> clock, but not I2C. The PCLK is used for HSI2C iPCLK.

In USI, USI PCLK is used for the internal AMBA APB bus clock and the 
IPCLK signal is used for the peripheral controller blocks (i2c/spi/uart).

So perhaps we have it described incorrectly, and the hsi2c controllers 
(at least on E8895) should take only one clock input (IPCLK), and USI 
block should take the PCLK input.


>
>
> Best regards,
> Krzysztof
>

- Markuss



From quic_vikramsa at quicinc.com  Tue Dec 17 09:43:21 2024
From: quic_vikramsa at quicinc.com (Vikram Sharma)
Date: Tue, 17 Dec 2024 23:13:21 +0530
Subject: [PATCH v10 1/4] media: dt-bindings: update clocks for
 sc7280-camss
In-Reply-To: <a1032d53-6f3e-48f6-a2e9-1315bb1a3232@linaro.org>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-2-quic_vikramsa@quicinc.com>
 <02da691b-1f5d-41a6-847c-c7e9b8239919@kernel.org>
 <c14493b0-c9d3-4e1c-9f86-991b4cb25c98@linaro.org>
 <fe28a9bc-82ef-4fef-af50-9d9261ed9b39@kernel.org>
 <a1032d53-6f3e-48f6-a2e9-1315bb1a3232@linaro.org>
Message-ID: <a9f99bdf-1f77-416e-a13b-83338212186d@quicinc.com>


On 12/17/2024 10:00 PM, Bryan O'Donoghue wrote:
> On 17/12/2024 16:23, Krzysztof Kozlowski wrote:
>> On 17/12/2024 17:12, Bryan O'Donoghue wrote:
>>> On 17/12/2024 14:10, Krzysztof Kozlowski wrote:
>>>> On 17/12/2024 15:06, Vikram Sharma wrote:
>>>>> This patch change clock names to make it consistent with
>>>>> existing platforms as gcc_cam_hf_axi -> gcc_axi_hf.
>>>>> This also adds gcc_axi_sf and remove gcc_camera_ahb.
>>>>
>>>> Don't combine ABI changes with some less important things.
>>>>
>>>> You miss here explanation why doing the ABI change in the first place.
>>>> Without that explanation I find it rather churn. But anyway, reason 
>>>> for
>>>> ABI break and impact should be documented in commit msg.
>>>>
>>>>>
>>>>> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
>>>>> ---
>>>>
>>>> Best regards,
>>>> Krzysztof
>>>
>>> This change should be fine since we haven't committed and upstream 
>>> dtsi,
>>> so there's no ABI to break yet.
>>>
>>> Agree the cover letter should have been explicit in explaining.
>>
>> So these are recently added bindings (sc7280 is not particularly new)?
>> If so mention in the commit msg that no users are affected because of 
>> this.
>>
>> Best regards,
>> Krzysztof
>
> Agreed.
>
> The commit log should make clear that the ABI hasn't been cemented yet.
>
> 20241217140656.965235-4-quic_vikramsa at quicinc.com <- is still pending
Thanks Krzysztof and Bryan.
I will update commit text to explain why ABI is not braking with this 
change.
>
> ---
> bod


From robh at kernel.org  Tue Dec 17 09:53:41 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Dec 2024 11:53:41 -0600
Subject: [PATCH V3 6/7] arm64/boot: Enable EL2 requirements for FEAT_Debugv8p9
In-Reply-To: <c64709f7-e1c6-482e-8665-912be50b15bd@arm.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
 <20241216040831.2448257-7-anshuman.khandual@arm.com> <20241216234251.GA629562-robh@kernel.org>
 <c64709f7-e1c6-482e-8665-912be50b15bd@arm.com>
Message-ID: <CAL_Jsq+EO_s49sSK3JQQEDDpcndf4hSpM_gfoe8tZ8=4y3f-tg@mail.gmail.com>

On Tue, Dec 17, 2024 at 2:48?AM Anshuman Khandual
<anshuman.khandual at arm.com> wrote:
>
> On 12/17/24 05:12, Rob Herring wrote:
> > On Mon, Dec 16, 2024 at 09:38:30AM +0530, Anshuman Khandual wrote:
> >> Fine grained trap control for MDSELR_EL1 register needs to be configured in
> >> HDFGRTR2_EL2, and HDFGWTR2_EL2 registers when kernel enters at EL1, but EL2
> >> is also present.
> >
> > Shouldn't this be "when kernel enters at EL2, and EL3 is also present"?
>
> AFAICT - HDFGRTR2_EL2 and HDFGWTR2_EL2 registers configure traps into EL2 when
> accessed from EL1/EL0, provided all required EL3 trap controls are in place as
> well. These EL2 based trap configs need to be set before the kernel finally
> enters EL1. Although there is an assumption about EL3 based trap configs being
> in place, do we need to mention that in commit message as well. Is not updating
> booting.rst takes care of all EL3 requirements.

My point is just I read 'kernel enters at EL1' as meaning the kernel
booted at EL1 and EL2 is not accessible. Maybe should reworded as
'before/if the kernel drops to EL1'

> > Though it is really "If EL3 set FGTEn2 and the kernel is entered in
> > EL2, then FGT2 must be initialized for MDSELR_EL1."
> >
> > If it was me, I'd just plagarize what was written for prior FGT
> > commits for this code. :)
>
> There are many commits that changed __init_el2_fgt() with different description
> formats. Do you have particular one in mind which can be followed here ? :)
>
> >
> >> This adds a new helper __init_el2_fgt2() initializing this
> >> new FEAT_FGT2 based fine grained registers.
> >
> > "This adds" is the same as saying "This patch/commit adds" which is well
> > documented to avoid. Use imperative "Add a new helper...". Though it is
> > clear from the diff that is what you are doing...
>
> Sure, will fix it.
>
> >
> >
> >> MDCR_EL2.EBWE needs to be enabled for additional (beyond 16) breakpoint and
> >> watchpoint exceptions when kernel enters at EL1, but EL2 is also present.
> >> This updates __init_el2_debug() as required for FEAT_Debugv8p9.
> >>
> >> While here, also update booting.rst with MDCR_EL3 and SCR_EL3 requirements.
> >>
> >> Cc: Catalin Marinas <catalin.marinas at arm.com>
> >> Cc: Will Deacon <will at kernel.org>
> >> Cc: Jonathan Corbet <corbet at lwn.net>
> >> Cc: Marc Zyngier <maz at kernel.org>
> >> Cc: Oliver Upton <oliver.upton at linux.dev>
> >> Cc: linux-arm-kernel at lists.infradead.org
> >> Cc: linux-doc at vger.kernel.org
> >> Cc: linux-kernel at vger.kernel.org
> >> Cc: kvmarm at lists.linux.dev
> >> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> >> ---
> >> Changes in V3:
> >>
> >> - Dropped MDCR_EL3.TDA boot requirement from documentation (separate series)
> >> - Dropped MDCR_EL2_EBWE definition as MDCR_EL2 is now defined in tools sysreg
> >>
> >> https://lore.kernel.org/all/20241211065425.1106683-1-anshuman.khandual at arm.com/
> >>
> >>  Documentation/arch/arm64/booting.rst | 18 ++++++++++++++++++
> >>  arch/arm64/include/asm/el2_setup.h   | 26 ++++++++++++++++++++++++++
> >>  2 files changed, 44 insertions(+)
> >>
> >> diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
> >> index 3278fb4bf219..054cfe1cad18 100644
> >> --- a/Documentation/arch/arm64/booting.rst
> >> +++ b/Documentation/arch/arm64/booting.rst
> >> @@ -288,6 +288,12 @@ Before jumping into the kernel, the following conditions must be met:
> >>
> >>      - SCR_EL3.FGTEn (bit 27) must be initialised to 0b1.
> >>
> >> +  For CPUs with the Fine Grained Traps (FEAT_FGT2) extension present:
> >> +
> >> +  - If EL3 is present and the kernel is entered at EL2:
> >> +
> >> +    - SCR_EL3.FGTEn2 (bit 59) must be initialised to 0b1.
> >> +
> >>    For CPUs with support for HCRX_EL2 (FEAT_HCX) present:
> >>
> >>    - If EL3 is present and the kernel is entered at EL2:
> >> @@ -322,6 +328,18 @@ Before jumping into the kernel, the following conditions must be met:
> >>      - ZCR_EL2.LEN must be initialised to the same value for all CPUs the
> >>        kernel will execute on.
> >>
> >> +  For CPUs with FEAT_Debugv8p9 extension present:
> >> +
> >> +  - If the kernel is entered at EL1 and EL2 is present:
> >> +
> >> +    - HDFGRTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1
> >> +    - HDFGWTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1
> >> +    - MDCR_EL2.EBWE (bit 43) must be initialized to 0b1
> >> +
> >> +  - If EL3 is present:
> >> +
> >> +    - MDCR_EL3.EBWE (bit 43) must be initialized to 0b1
> >> +
> >>    For CPUs with the Scalable Matrix Extension (FEAT_SME):
> >>
> >>    - If EL3 is present:
> >> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> >> index 4ef52d7245bb..2fbfe27d38b5 100644
> >> --- a/arch/arm64/include/asm/el2_setup.h
> >> +++ b/arch/arm64/include/asm/el2_setup.h
> >> @@ -105,6 +105,13 @@
> >>                                              // to own it.
> >>
> >>  .Lskip_trace_\@:
> >> +    mrs     x1, id_aa64dfr0_el1
> >> +    ubfx    x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
> >> +    cmp     x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
> >> +    b.lt    .Lskip_dbg_v8p9_\@
> >> +
> >> +    orr     x2, x2, #MDCR_EL2_EBWE
> >> +.Lskip_dbg_v8p9_\@:
> >>      msr     mdcr_el2, x2                    // Configure debug traps
> >>  .endm
> >>
> >> @@ -244,6 +251,24 @@
> >>  .Lskip_gcs_\@:
> >>  .endm
> >>
> >> +.macro __init_el2_fgt2
> >> +    mrs     x1, id_aa64mmfr0_el1
> >> +    ubfx    x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
> >> +    cmp     x1, #ID_AA64MMFR0_EL1_FGT_FGT2
> >
> > We already read this field in __init_el2_fgt, shouldn't we leverage that
> > and move all this there rather than read the feature reg twice.
>
> Should not __init_el2_fgt2() remain separate to contain all future FEAT_FGT2
> related trap enabled/disable checks ? OTOH reading id_aa64mmfr0_el1 register
> should improve some performance as well.

That's the tradeoff. I'll defer to others whether a single id register
read here is preferred.

> >> +    b.lt    .Lskip_fgt2_\@
> >> +
> >> +    mrs     x1, id_aa64dfr0_el1
> >> +    ubfx    x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
> >> +    cmp     x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
> >> +    b.lt    .Lskip_dbg_v8p9_\@
> >> +
> >> +    mov_q   x0, HDFGWTR2_EL2_nMDSELR_EL1
> >> +    msr_s   SYS_HDFGWTR2_EL2, x0
> >> +    msr_s   SYS_HDFGRTR2_EL2, x0
> >
> > If Debug v8.9 is not present, but FGT2 is, shouldn't we write 0 to these
> > registers? That is what we do for FGT.
>
> Just to summerize what's being done in __init_el2_fgt()
>
> .macro __init_el2_fgt
>         ...............
>         mov     x0, xzr
>         ...............
> .Lskip_spe_fgt_\@:
>         msr_s   SYS_HDFGRTR_EL2, x0
>         msr_s   SYS_HDFGWTR_EL2, x0
>         ...............
> .Lset_fgt_\@:
>         msr_s   SYS_HFGRTR_EL2, x0
>         msr_s   SYS_HFGWTR_EL2, x0
>         msr_s   SYS_HFGITR_EL2, xzr
>         ...............
>
> If the relevant features are not present and their traps need not be handled,
> all FEAT_FGT based trap control registers (SYS_HDFGRTR_EL2, SYS_HDFGWTR_EL2,
> SYS_HFGRTR_EL2, SYS_HFGWTR_EL2 and SYS_HFGITR_EL2) get cleared. Hence same
> needs to be done for all FEAT_FGT2 register as well. Fair enough, something
> like the following makes sense ?
>
> .macro __init_el2_fgt2
>         mrs     x1, id_aa64mmfr0_el1
>         ubfx    x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
>         cmp     x1, #ID_AA64MMFR0_EL1_FGT_FGT2
>         b.lt    .Lskip_fgt2_\@
>
>         mov     x0, xzr
>         mrs     x1, id_aa64dfr0_el1
>         ubfx    x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
>         cmp     x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
>         b.lt    .Lskip_dbg_v8p9_\@
>
>         orr     x0, x0, #HDFGWTR2_EL2_nMDSELR_EL1
> .Lskip_dbg_v8p9_\@:
>         msr_s   SYS_HDFGWTR2_EL2, x0
>         msr_s   SYS_HDFGRTR2_EL2, x0
>         msr_s   SYS_HFGRTR2_EL2, xzr
>         msr_s   SYS_HFGWTR2_EL2, xzr
>         msr_s   SYS_HFGITR2_EL2, xzr
> .Lskip_fgt2_\@:
> .endm

Looks good.

>
> Just wondering - following the same principle if clearing these FEAT_FGT2 trap
> registers would make sense in itself, even without FEAT_Debugv8p9 enablement ?

Probably and there's a Jira for it. Though there was some debate about
whether anything was needed before any users. But that's kind of a
mute point anyway because I need it for PMU now, too.

> Something like the commit
>
> commit 31c00d2aeaa2da89361f5b64a64ca831433be5fc
> Author: Mark Brown <broonie at kernel.org>
> Date:   Thu Apr 1 19:09:40 2021 +0100
>
>     arm64: Disable fine grained traps on boot
>
>     The arm64 FEAT_FGT extension introduces a set of traps to EL2 for accesses
>     to small sets of registers and instructions from EL1 and EL0.  Currently
>     Linux makes no use of this feature, ensure that it is not active at boot by
>     disabling the traps during EL2 setup.
>
>
> >
> >
> > I just realized I forgot to add FGT2 setup for the PMUv3.9 features I
> > already added in 6.12 and 6.13. So this really needs to land sooner
> > rather than later to add that.
> Not sure if I got this correctly. Are you suggesting to carve out __init_el2_fgt2()
> from the series and post separately with PMUv3.9 requirements and fallback clearing
> for all FEAT_FGT2 trap config registers as mentioned above ?

Yes, as it needs to not be held up by any of the debug issues Mark
raised. Also, it may need to be back ported to 6.12. And for that we'd
want the PMU parts, but not the Debug. I still have to figure out what
needs to be done on the KVM side.

Rob


From sudeep.holla at arm.com  Tue Dec 17 09:59:34 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 17 Dec 2024 17:59:34 +0000
Subject: [PATCH V4 0/5] arm_scmi: vendors: Qualcomm Generic Vendor
 Extensions
In-Reply-To: <d313e40b-fa8f-a534-5037-98536ee25044@quicinc.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <ZytnRc94iKUfMYH0@hovoldconsulting.com>
 <ZyvLktLUZOGP-LH5@pluto>
 <Zy4qvedrmkRdPR3x@hovoldconsulting.com>
 <8d42682b-0fa7-3962-da12-728cfe64903b@quicinc.com>
 <Z0BC203BhGEmXcJi@hovoldconsulting.com>
 <Z1HceQegfMl07qj_@bogus>
 <d313e40b-fa8f-a534-5037-98536ee25044@quicinc.com>
Message-ID: <20241217175934.GC2016149@bogus>

On Tue, Dec 17, 2024 at 05:55:35PM +0530, Sibi Sankar wrote:
> 
> 
> On 12/5/24 22:31, Sudeep Holla wrote:
> > On Fri, Nov 22, 2024 at 09:37:47AM +0100, Johan Hovold wrote:
> > > On Thu, Nov 14, 2024 at 09:52:12AM +0530, Sibi Sankar wrote:
> > > > On 11/8/24 20:44, Johan Hovold wrote:
> > > 
> > > > > > On Wed, Nov 06, 2024 at 01:55:33PM +0100, Johan Hovold wrote:
> > > 
> > > > > > > Second, after loading the protocol and client drivers manually (in that
> > > > > > > order, shouldn't the client driver pull in the protocol?), I got:
> > > > > > > 
> > > > > > > 	scmi_module: Loaded SCMI Vendor Protocol 0x80 - Qualcomm  20000
> > > > > > > 	arm-scmi arm-scmi.0.auto: QCOM Generic Vendor Version 1.0
> > > > > > > 	scmi-qcom-generic-ext-memlat scmi_dev.5: error -EOPNOTSUPP: failed to configure common events
> > > > > > > 	scmi-qcom-generic-ext-memlat scmi_dev.5: probe with driver scmi-qcom-generic-ext-memlat failed with error -95
> > > > > > > 
> > > > > > > which seems to suggest that the firmware on my CRD does not support this
> > > > > > > feature. Is that the way this should be interpreted? And does that mean
> > > > > > > that non of the commercial laptops supports this either?
> > > 
> > > > > Yeah, hopefully Sibi can shed some light on this. I'm using the DT
> > > > > patch (5/5) from this series, which according to the commit message is
> > > > > supposed to enable bus scaling on the x1e80100 platform. So I guess
> > > > > something is missing in my firmware.
> > > > 
> > > > Nah, it's probably just because of the algo string used.
> > > > The past few series used caps MEMLAT string instead of
> > > > memlat to pass the tuneables, looks like all the laptops
> > > > havn't really switched to it yet. Will revert back to
> > > > using to lower case memlat so that all devices are
> > > > supported. Thanks for trying the series out!
> > > 
> > > I have a Lenovo ThinkPad T14s set up now so I gave this series a spin
> > > there too, and there I do *not* see the above mentioned -EOPNOSUPP error
> > > and the memlat driver probes successfully.
> > > 
> > > On the other hand, this series seems to have no effect on a kernel
> > > compilation benchmark. Is that expected?
> > > 
> > 
> > Hijacking this thread to rant about state of firmware implementation on
> > this platform that gives me zero confidence in merging any of these without
> > examining each of the interface details in depth and at lengths.
> > 
> 
> Hey Sudeep,
> 
> Thanks for taking time to review the series.
> 
> > Also I see the standard protocol like PERF seem to have so many issues which
> > adds to my no confidence. I can't comment on that thread for specific reasons.
> 
> ^^ is largely untrue, a lot of finger pointing and a gross
> misrepresentation of reality :/
>

Sorry if I was not clear, I just said I don't have confidence yet and if
the firmware is stable, then it is just the impression I have arrived based
on the discussions.

> crash in the LEVEL_GET regular message implementation. This
> pretty much went unnoticed because of messaging in perf implementation
> in kernel.

OK, is there any scope to improve in your opinion ? Please suggest and
discuss or post a patch to have separate discussion.

> Given the fastchannel implementation isn't mandatory
> according to spec, the kernel clearly says it switches to
> regular messaging when it clearly doesn't do that and uses
> stale data structures instead.

Interesting, it sounds like a bug. Please provide details or patch to
fix the bug. That would probably fix it on whatever platform we are
concerned here.

> This ensured that level get regular messaging never got tested.
>

You seem to point at this bug several time now, we need to get it fixed,
but we need to understand it first if you want us to fix it or as mentioned
before you can as well post the patch.

> We pretty much have been good upstream citizens, finding bugs and
> sending fixes wherever we can. We clearly don't deserve such a hostile
> stance.
>

Not sure what made you think we are hostile towards your contributions.
We just need a maintainable solution merged upstream and we are working
towards the same. The documents written as part of this series is not
there yet to help me understand the protocol yet. I have asked questions
and answer to those can be made part of the next version to improve it
IMO.

> > I will briefly mention my suspicion here. This Lenovo ThinkPad T14s being
> > primarily targeting other OS using ACPI might have just implemented what is
> > required for ACPI CPPC which conveniently doesn't have to discover lot of
> > fastchannel details since they are supplied in the tables straight away.
> > But that also would mean it could be not fully compliant to SCMI spec.
>
> Not fully compliant to the spec? I am pretty sure this series would
> have been shot down completely and NAKd on the list by you if that
> was the case lol.
>

Honestly I am still trying to make any sense out of this vendor protocols.
The documents produced as part of this series doesn't help me understand
the same and that is my main feedback so far on this thread. I haven't
looked at the code yet so I can't comment on the same as I first need
to understand the vendor protocol document/specification.

-- 
Regards,
Sudeep


From oliver.upton at linux.dev  Tue Dec 17 10:00:44 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 10:00:44 -0800
Subject: [PATCH] KVM: arm64: Fix set_id_regs selftest for ASIDBITS
 becoming unwritable
In-Reply-To: <b13b14df-00ee-4bee-8f65-d2cb7a9bfa6b@sirena.org.uk>
References: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
 <875xnisocy.wl-maz@kernel.org>
 <53b40aa8-f51c-4c4e-a4ad-e6a9512e5197@sirena.org.uk>
 <86v7viqusg.wl-maz@kernel.org>
 <b13b14df-00ee-4bee-8f65-d2cb7a9bfa6b@sirena.org.uk>
Message-ID: <Z2G8TFw4wg7bnwzB@linux.dev>

On Tue, Dec 17, 2024 at 03:10:28PM +0000, Mark Brown wrote:
> On Tue, Dec 17, 2024 at 01:54:39PM +0000, Marc Zyngier wrote:
> > Mark Brown <broonie at kernel.org> wrote:
> 
> > > The selftests are shipped as part of the kernel source and frequently
> > > used for testing the kernel, it's all one source base and we want to
> > > ensure that for example the test fix gets backported if the relevant
> > > kernel patch does.
> 
> > That's not what Fixes: describes. If you want to invent a new tag that
> > expresses a dependency, do that. Don't use these tags to misrepresent
> > what the patches does.
> 
> No, this isn't a new use - a Fixes: tag indicates that the referenced
> commit introduced the problem being fixed and that is exactly what's
> going on here.  Like I say the selftests are not a completely separate
> project, they are a part of the same source release as the rest of the
> kernel and it is helpful to track information like this.

A Fixes tag suggests a bug in the referenced commit, which isn't the
case here.

I agree that having some relation between the two is useful for
determining the scope of a backport, but conveniently in this case the
test failure was introduced in 6.13.

I've taken the fix for 6.13, w/ the tag dropped.

-- 
Thanks,
Oliver


From anarsoul at gmail.com  Tue Dec 17 10:00:45 2024
From: anarsoul at gmail.com (Vasily Khoruzhick)
Date: Tue, 17 Dec 2024 10:00:45 -0800
Subject: [PATCH 1/3] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
In-Reply-To: <qbtp4jvkx3r5azufe4k3vtapqpfs54dyjiu4cy5v5wkkzumrzx@vy3xzkfplbue>
References: <20241215053639.738890-1-anarsoul@gmail.com> <20241215053639.738890-2-anarsoul@gmail.com>
 <qbtp4jvkx3r5azufe4k3vtapqpfs54dyjiu4cy5v5wkkzumrzx@vy3xzkfplbue>
Message-ID: <CA+E=qVeQ8uHBCeFtw6_2cY3252-YXc6eWrf5_YdeVgbp5LJo5g@mail.gmail.com>

On Mon, Dec 16, 2024 at 11:33?PM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On Sat, Dec 14, 2024 at 09:34:57PM -0800, Vasily Khoruzhick wrote:
> > These will be used to explicitly select TCON0 clock parent in dts
> >
> > Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
> > Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
> > ---
> >  drivers/clk/sunxi-ng/ccu-sun50i-a64.h      | 2 --
> >  include/dt-bindings/clock/sun50i-a64-ccu.h | 2 +

Hi Krzysztof,

> You cannot combine these changes.

The patch basically moves defines out from ccu-sun50i-a64.h to
sun50i-a64-ccu.h. How do I split the change without introducing
compilation failure?

> Please run scripts/checkpatch.pl and fix reported warnings. Then please
> run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
> Some warnings can be ignored, especially from --strict run, but the code
> here looks like it needs a fix. Feel free to get in touch if the warning
> is not clear.

Yeah, it is not clear what do you want me to do, assuming the previous
similar change to sun50i-a64-ccu.h did essentially the same, see
71b597ef5d46a326fb0d5cbfc1c6ff1d73cdc7f9

Regards,
Vasily

> Best regards,
> Krzysztof
>


From robh at kernel.org  Tue Dec 17 10:11:41 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 17 Dec 2024 12:11:41 -0600
Subject: [PATCH v2 2/3] mfd: syscon: Remove the platform driver support
In-Reply-To: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
Message-ID: <20241217-syscon-fixes-v2-2-4f56d750541d@kernel.org>

The platform driver is dead code. It is not used by DT platforms since
commit bdb0066df96e ("mfd: syscon: Decouple syscon interface from
platform devices") which said:

    For non-DT based platforms, this patch keeps syscon platform driver
    structure so that syscon can be probed and such non-DT based drivers
    can use syscon_regmap_lookup_by_pdev API and access regmap handles.
    Once all users of "syscon_regmap_lookup_by_pdev" migrated to DT based,
    we can completely remove platform driver of syscon, and keep only helper
    functions to get regmap handles.

The last user of syscon_regmap_lookup_by_pdevname() was removed in 2018.
syscon_regmap_lookup_by_pdevname() was then removed in 2019, but that
commit failed to remove the rest of the platform driver.

Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
 drivers/mfd/syscon.c                 | 66 ------------------------------------
 drivers/mfd/vexpress-sysreg.c        |  1 -
 include/linux/platform_data/syscon.h |  9 -----
 3 files changed, 76 deletions(-)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 72f20de9652da2d7bad12e4bc2c43ac0c9a97f76..bfb1f69fcff1d3cd35cf04ccd4c449e7d0395c79 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -12,22 +12,15 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/hwspinlock.h>
-#include <linux/io.h>
-#include <linux/init.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/platform_data/syscon.h>
-#include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
 #include <linux/mfd/syscon.h>
 #include <linux/slab.h>
 
-static struct platform_driver syscon_driver;
-
 static DEFINE_MUTEX(syscon_list_lock);
 static LIST_HEAD(syscon_list);
 
@@ -337,62 +330,3 @@ struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np,
 	return regmap;
 }
 EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle_optional);
-
-static int syscon_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct syscon_platform_data *pdata = dev_get_platdata(dev);
-	struct syscon *syscon;
-	struct regmap_config syscon_config = syscon_regmap_config;
-	struct resource *res;
-	void __iomem *base;
-
-	syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
-	if (!syscon)
-		return -ENOMEM;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENOENT;
-
-	base = devm_ioremap(dev, res->start, resource_size(res));
-	if (!base)
-		return -ENOMEM;
-
-	syscon_config.max_register = resource_size(res) - 4;
-	if (!syscon_config.max_register)
-		syscon_config.max_register_is_0 = true;
-
-	if (pdata)
-		syscon_config.name = pdata->label;
-	syscon->regmap = devm_regmap_init_mmio(dev, base, &syscon_config);
-	if (IS_ERR(syscon->regmap)) {
-		dev_err(dev, "regmap init failed\n");
-		return PTR_ERR(syscon->regmap);
-	}
-
-	platform_set_drvdata(pdev, syscon);
-
-	dev_dbg(dev, "regmap %pR registered\n", res);
-
-	return 0;
-}
-
-static const struct platform_device_id syscon_ids[] = {
-	{ "syscon", },
-	{ }
-};
-
-static struct platform_driver syscon_driver = {
-	.driver = {
-		.name = "syscon",
-	},
-	.probe		= syscon_probe,
-	.id_table	= syscon_ids,
-};
-
-static int __init syscon_init(void)
-{
-	return platform_driver_register(&syscon_driver);
-}
-postcore_initcall(syscon_init);
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
index d34d58ce46db2ad0d53b3daeabc9d3763883b39a..ef03d6cec9ff6927668d051ca459eb1d8ff7269e 100644
--- a/drivers/mfd/vexpress-sysreg.c
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -10,7 +10,6 @@
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
-#include <linux/platform_data/syscon.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
diff --git a/include/linux/platform_data/syscon.h b/include/linux/platform_data/syscon.h
deleted file mode 100644
index 2c089dd3e2bda3baf5cef201ef43bca709e12c0b..0000000000000000000000000000000000000000
--- a/include/linux/platform_data/syscon.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef PLATFORM_DATA_SYSCON_H
-#define PLATFORM_DATA_SYSCON_H
-
-struct syscon_platform_data {
-	const char *label;
-};
-
-#endif

-- 
2.45.2



From robh at kernel.org  Tue Dec 17 10:11:39 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 17 Dec 2024 12:11:39 -0600
Subject: [PATCH v2 0/3] mfd: syscon: Cleanup, fix race condition and remove
 platform driver
Message-ID: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>

Questions from Krzysztof and a syscon related binding review got me 
looking at the syscon "driver". This series is the result.

This short series drops the stale platform driver part of syscon 
support, fixes a race condition in device_node_get_regmap()
which is used by all the lookup functions, and allows for registering 
nodes without "syscon" compatibles.

Compile tested only. Testing on Tensor, the one user of 
of_syscon_register_regmap(), would be helpful.

Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
Changes in v2:
- Fix patch 3 logic when a syscon is found in list to not return an 
  error
- Add tags
- Link to v1: https://lore.kernel.org/r/20241211-syscon-fixes-v1-0-b5ac8c219e96 at kernel.org

---
Rob Herring (Arm) (3):
      mfd: syscon: Fix race in device_node_get_regmap()
      mfd: syscon: Remove the platform driver support
      mfd: syscon: Allow syscon nodes without a "syscon" compatible

 drivers/mfd/syscon.c                 | 95 ++++++------------------------------
 drivers/mfd/vexpress-sysreg.c        |  1 -
 include/linux/platform_data/syscon.h |  9 ----
 3 files changed, 15 insertions(+), 90 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241211-syscon-fixes-9f35ecb9bfbe

Best regards,
-- 
Rob Herring (Arm) <robh at kernel.org>



From robh at kernel.org  Tue Dec 17 10:11:40 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 17 Dec 2024 12:11:40 -0600
Subject: [PATCH v2 1/3] mfd: syscon: Fix race in device_node_get_regmap()
In-Reply-To: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
Message-ID: <20241217-syscon-fixes-v2-1-4f56d750541d@kernel.org>

It is possible for multiple, simultaneous callers calling
device_node_get_regmap() with the same node to fail to find an entry in
the syscon_list. There is a period of time while the first caller is
calling of_syscon_register() that subsequent callers also fail to find
an entry in the syscon_list and then call of_syscon_register() a second
time.

Fix this by keeping the lock held until after of_syscon_register()
completes and adds the node to syscon_list. Convert the spinlock to a
mutex as many of the functions called in of_syscon_register() such as
kzalloc() and of_clk_get() may sleep.

Fixes: bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform devices")
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
 drivers/mfd/syscon.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 3e1d699ba9340f8135dfdeae6feca474980cc48d..72f20de9652da2d7bad12e4bc2c43ac0c9a97f76 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
@@ -27,7 +28,7 @@
 
 static struct platform_driver syscon_driver;
 
-static DEFINE_SPINLOCK(syscon_list_slock);
+static DEFINE_MUTEX(syscon_list_lock);
 static LIST_HEAD(syscon_list);
 
 struct syscon {
@@ -54,6 +55,8 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
 	struct resource res;
 	struct reset_control *reset;
 
+	WARN_ON(!mutex_is_locked(&syscon_list_lock));
+
 	struct syscon *syscon __free(kfree) = kzalloc(sizeof(*syscon), GFP_KERNEL);
 	if (!syscon)
 		return ERR_PTR(-ENOMEM);
@@ -146,9 +149,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
 	syscon->regmap = regmap;
 	syscon->np = np;
 
-	spin_lock(&syscon_list_slock);
 	list_add_tail(&syscon->list, &syscon_list);
-	spin_unlock(&syscon_list_slock);
 
 	return_ptr(syscon);
 
@@ -169,7 +170,7 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
 {
 	struct syscon *entry, *syscon = NULL;
 
-	spin_lock(&syscon_list_slock);
+	mutex_lock(&syscon_list_lock);
 
 	list_for_each_entry(entry, &syscon_list, list)
 		if (entry->np == np) {
@@ -177,11 +178,11 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
 			break;
 		}
 
-	spin_unlock(&syscon_list_slock);
-
 	if (!syscon)
 		syscon = of_syscon_register(np, check_res);
 
+	mutex_unlock(&syscon_list_lock);
+
 	if (IS_ERR(syscon))
 		return ERR_CAST(syscon);
 
@@ -212,7 +213,7 @@ int of_syscon_register_regmap(struct device_node *np, struct regmap *regmap)
 		return -ENOMEM;
 
 	/* check if syscon entry already exists */
-	spin_lock(&syscon_list_slock);
+	mutex_lock(&syscon_list_lock);
 
 	list_for_each_entry(entry, &syscon_list, list)
 		if (entry->np == np) {
@@ -225,12 +226,12 @@ int of_syscon_register_regmap(struct device_node *np, struct regmap *regmap)
 
 	/* register the regmap in syscon list */
 	list_add_tail(&syscon->list, &syscon_list);
-	spin_unlock(&syscon_list_slock);
+	mutex_unlock(&syscon_list_lock);
 
 	return 0;
 
 err_unlock:
-	spin_unlock(&syscon_list_slock);
+	mutex_unlock(&syscon_list_lock);
 	kfree(syscon);
 	return ret;
 }

-- 
2.45.2



From robh at kernel.org  Tue Dec 17 10:11:42 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 17 Dec 2024 12:11:42 -0600
Subject: [PATCH v2 3/3] mfd: syscon: Allow syscon nodes without a "syscon"
 compatible
In-Reply-To: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
Message-ID: <20241217-syscon-fixes-v2-3-4f56d750541d@kernel.org>

of_syscon_register_regmap() was added for nodes which need a custom
regmap setup. It's not really correct for those nodes to claim they are
compatible with "syscon" as the default handling likely doesn't work in
those cases. If device_node_get_regmap() happens to be called first,
then of_syscon_register() will be called and an incorrect regmap will be
created (barring some other error). That may lead to unknown results in
the worst case. In the best case, of_syscon_register_regmap() will fail
with -EEXIST. This problem remains unless these cases drop "syscon" (an
ABI issue) or we exclude them using their specific compatible. ATM,
there is only one user: "google,gs101-pmu"

There are also cases of adding "syscon" compatible to existing nodes
after the fact in order to register the syscon. That presents a
potential DT ABI problem. Instead, if there's a kernel change needing a
syscon for a node, then it should be possible to allow the kernel to
register a syscon without a DT change. That's only possible by using
of_syscon_register_regmap() currently, but in the future we may want to
support a match list for cases which don't need a custom regmap.

With this change, the lookup functions will succeed for any node
registered by of_syscon_register_regmap() regardless of whether the node
compatible contains "syscon".

Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
v2:
 - Fix logic when a syscon is found in list to not return an error
---
 drivers/mfd/syscon.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index bfb1f69fcff1d3cd35cf04ccd4c449e7d0395c79..226915ca3c93dcaf47bdd46b58e00e10e155f952 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -171,9 +171,12 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
 			break;
 		}
 
-	if (!syscon)
-		syscon = of_syscon_register(np, check_res);
-
+	if (!syscon) {
+		if (of_device_is_compatible(np, "syscon"))
+			syscon = of_syscon_register(np, check_res);
+		else
+			syscon = ERR_PTR(-EINVAL);
+	}
 	mutex_unlock(&syscon_list_lock);
 
 	if (IS_ERR(syscon))
@@ -238,9 +241,6 @@ EXPORT_SYMBOL_GPL(device_node_to_regmap);
 
 struct regmap *syscon_node_to_regmap(struct device_node *np)
 {
-	if (!of_device_is_compatible(np, "syscon"))
-		return ERR_PTR(-EINVAL);
-
 	return device_node_get_regmap(np, true);
 }
 EXPORT_SYMBOL_GPL(syscon_node_to_regmap);

-- 
2.45.2



From conor at kernel.org  Tue Dec 17 10:20:51 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 17 Dec 2024 18:20:51 +0000
Subject: [PATCH v2 1/2] dt-bindings: nvmem: imx-ocotp: Introduce
 #access-controller-cells
In-Reply-To: <20241217-imx-ocotp-v2-1-3faa6cbff41b@nxp.com>
References: <20241217-imx-ocotp-v2-0-3faa6cbff41b@nxp.com>
 <20241217-imx-ocotp-v2-1-3faa6cbff41b@nxp.com>
Message-ID: <20241217-compare-craftily-94425c53b4d8@spud>

On Tue, Dec 17, 2024 at 04:43:36PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Introduce "#access-controller-cells" to make OCOTP be an accessing
> controller, because i.MX Family OCOTP supports a specific peripheral
> or function being fused which means being disabled.
> 
> Add the i.MX[95,93] OCOTP gate index.
> 
> Reviewed-by: Frank Li <Frank.Li at nxp.com>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>

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/20241217/fd7279f4/attachment.sig>

From conor at kernel.org  Tue Dec 17 10:23:36 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 17 Dec 2024 18:23:36 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: arm,gic: Correct VGIC
 interrupt description
In-Reply-To: <20241217061226.14139-1-krzysztof.kozlowski@linaro.org>
References: <20241217061226.14139-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20241217-refresh-decency-bf5b9e1ac493@spud>

On Tue, Dec 17, 2024 at 07:12:26AM +0100, Krzysztof Kozlowski wrote:
> The description of VGIC interrupt referenced obsolete "see below" after
> converting TXT to DT Schema in commit 66ed144f147a ("dt-bindings:
> interrupt-controller: Convert ARM GIC to json-schema"), because there is
> no dedicated "VGIC" chapter anymore below.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>  .../devicetree/bindings/interrupt-controller/arm,gic.yaml     | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
> index a2846e493497..7173c4b5a228 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
> +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
> @@ -110,8 +110,8 @@ properties:
>  
>    interrupts:
>      description: Interrupt source of the parent interrupt controller on
> -      secondary GICs, or VGIC maintenance interrupt on primary GIC (see
> -      below).
> +      secondary GICs, or VGIC maintenance interrupt on primary GIC (see "GICv2
> +      with virtualization extensions" paragraph in the "reg" property).

I don't think things like this /should/ need a dt ack, even if they
weren't from a dt maintainer - but in case one's expected
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/20241217/7fe1e2b7/attachment.sig>

From conor at kernel.org  Tue Dec 17 10:24:42 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 17 Dec 2024 18:24:42 +0000
Subject: [PATCH 2/9] dt-bindings: media: clarify stm32 csi & simplify
 example
In-Reply-To: <20241217-csi_dcmipp_mp25_enhancements-v1-2-2b432805d17d@foss.st.com>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
 <20241217-csi_dcmipp_mp25_enhancements-v1-2-2b432805d17d@foss.st.com>
Message-ID: <20241217-crawfish-tiring-792c535301d0@spud>

On Tue, Dec 17, 2024 at 06:39:19PM +0100, Alain Volmat wrote:
> Clarify the description of the stm32 csi by mentioning CSI-2 and
> D-PHY.

> Remove the bus-type property from the example.

Why? What's there to gain from the example being (seemingly?) less
comprehensive?

> 
> Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> ---
>  Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> index 33bedfe41924..e9fa3cfea5d2 100644
> --- a/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> +++ b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> @@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
>  title: STMicroelectronics STM32 CSI controller
>  
>  description:
> -  The STM32 CSI controller allows connecting a CSI based
> -  camera to the DCMIPP camera pipeline.
> +  The STM32 CSI controller, coupled with a D-PHY allows connecting a CSI-2
> +  based camera to the DCMIPP camera pipeline.
>  
>  maintainers:
>    - Alain Volmat <alain.volmat at foss.st.com>
> @@ -109,7 +109,6 @@ examples:
>                  endpoint {
>                      remote-endpoint = <&imx335_ep>;
>                      data-lanes = <1 2>;
> -                    bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
>                  };
>              };
>  
> 
> -- 
> 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/20241217/541cf114/attachment.sig>

From conor at kernel.org  Tue Dec 17 10:25:47 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 17 Dec 2024 18:25:47 +0000
Subject: [PATCH] dt-bindings: media: imx283: Describe sensor address
 using the reg property
In-Reply-To: <20241217032821.1712916-1-david@ixit.cz>
References: <20241217032821.1712916-1-david@ixit.cz>
Message-ID: <20241217-moving-rubble-712bba91af4d@spud>

On Mon, Dec 16, 2024 at 10:28:17PM -0500, David Heidelberg wrote:
> Use the reg property instead of text in the description.
> 
> Signed-off-by: David Heidelberg <david at ixit.cz>

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/20241217/8fb22df1/attachment.sig>

From conor at kernel.org  Tue Dec 17 10:27:19 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 17 Dec 2024 18:27:19 +0000
Subject: [PATCH] dt-bindings: media: imx283: Describe sensor address
 using the reg property
In-Reply-To: <20241217-moving-rubble-712bba91af4d@spud>
References: <20241217032821.1712916-1-david@ixit.cz>
 <20241217-moving-rubble-712bba91af4d@spud>
Message-ID: <20241217-strongly-twiddle-b9e1ade32570@spud>

On Tue, Dec 17, 2024 at 06:25:47PM +0000, Conor Dooley wrote:
> On Mon, Dec 16, 2024 at 10:28:17PM -0500, David Heidelberg wrote:
> > Use the reg property instead of text in the description.
> > 
> > Signed-off-by: David Heidelberg <david at ixit.cz>
> 
> Acked-by: Conor Dooley <conor.dooley at microchip.com>

Heh, I was super confused as to why I couldn't find this in patchwork
but then realised Krzk had already acked it, d'oh. 
-------------- 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/20241217/36dd3fe1/attachment.sig>

From broonie at kernel.org  Tue Dec 17 10:27:44 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Dec 2024 18:27:44 +0000
Subject: [PATCH v3 0/2] spi: atmel-quadspi: Refactor to allow
 supporting SAMA7G5 O/QSPI
In-Reply-To: <20241128174316.3209354-1-csokas.bence@prolan.hu>
References: <20241128174316.3209354-1-csokas.bence@prolan.hu>
Message-ID: <173446006475.142278.5557207366372183006.b4-ty@kernel.org>

On Thu, 28 Nov 2024 18:43:13 +0100, Cs?k?s, Bence wrote:
> This is based on Tudor Ambarus' submission from 2021, and my refactor
> of said sumbission from roughly a month ago.
> Link: https://lore.kernel.org/linux-spi/20211214133404.121739-1-tudor.ambarus at microchip.com/
> Link: https://lore.kernel.org/linux-spi/20241030084445.2438750-1-csokas.bence at prolan.hu/
> 
> This time, I submit both my refactor and the diff between it and the
> original submission, rebased on top of Linus' master, namely:
> commit 7d4050728c83 ("Merge tag 'vfs-6.13-rc1.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs")
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/2] spi: atmel-quadspi: Create `atmel_qspi_ops` to support newer SoC families
      commit: c0a0203cf57963792d59b3e4317a1d07b73df42a
[2/2] spi: atmel-quadspi: Add support for sama7g5 QSPI
      commit: 5af42209a4d23adc9a09e59e586d1b47fef3cc86

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  Tue Dec 17 11:05:47 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 17 Dec 2024 11:05:47 -0800
Subject: [GIT PULL 1/1] Broadcom devicetree-arm64 fixes for 6.13
Message-ID: <20241217190547.868744-1-florian.fainelli@broadcom.com>

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -0800)

are available in the Git repository at:

  https://github.com/Broadcom/stblinux.git tags/arm-soc/for-6.13/devicetree-arm64-fixes

for you to fetch changes up to 058387d9c6b70e225da82492e1e193635c3fac3f:

  arm64: dts: broadcom: Fix L2 linesize for Raspberry Pi 5 (2024-12-17 11:03:22 -0800)

----------------------------------------------------------------
This pull request contains Broadcom ARM64-based SoCs Device Tree fixes
for 6.13, please pull the following:

- Willow corrects the L2 cache line size on the Raspberry Pi 5 (2712) to
  the correct value of 64 bytes

----------------------------------------------------------------
Willow Cunningham (1):
      arm64: dts: broadcom: Fix L2 linesize for Raspberry Pi 5

 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)


From florian.fainelli at broadcom.com  Tue Dec 17 11:14:12 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 17 Dec 2024 11:14:12 -0800
Subject: [PATCH] arm64: dts: bcm4908: nvmem-layout conversion
In-Reply-To: <20241203233632.184861-1-rosenp@gmail.com>
References: <20241203233632.184861-1-rosenp@gmail.com>
Message-ID: <20241217191412.872240-1-florian.fainelli@broadcom.com>

From: Florian Fainelli <f.fainelli at gmail.com>

On Tue,  3 Dec 2024 15:36:32 -0800, Rosen Penev <rosenp at gmail.com> wrote:
> nvmem-layout is a more flexible replacement for nvmem-cells.
> 
> Signed-off-by: Rosen Penev <rosenp at gmail.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree-arm64/next, thanks!
--
Florian


From broonie at kernel.org  Tue Dec 17 11:22:14 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Dec 2024 19:22:14 +0000
Subject: [PATCH] KVM: arm64: Fix set_id_regs selftest for ASIDBITS
 becoming unwritable
In-Reply-To: <Z2G8TFw4wg7bnwzB@linux.dev>
References: <20241216-kvm-arm64-fix-set-id-asidbits-v1-1-8b105b888fc3@kernel.org>
 <875xnisocy.wl-maz@kernel.org>
 <53b40aa8-f51c-4c4e-a4ad-e6a9512e5197@sirena.org.uk>
 <86v7viqusg.wl-maz@kernel.org>
 <b13b14df-00ee-4bee-8f65-d2cb7a9bfa6b@sirena.org.uk>
 <Z2G8TFw4wg7bnwzB@linux.dev>
Message-ID: <9b657364-140b-482d-82fe-01c59711e764@sirena.org.uk>

On Tue, Dec 17, 2024 at 10:00:44AM -0800, Oliver Upton wrote:
> On Tue, Dec 17, 2024 at 03:10:28PM +0000, Mark Brown wrote:

> > No, this isn't a new use - a Fixes: tag indicates that the referenced
> > commit introduced the problem being fixed and that is exactly what's
> > going on here.  Like I say the selftests are not a completely separate
> > project, they are a part of the same source release as the rest of the
> > kernel and it is helpful to track information like this.

> A Fixes tag suggests a bug in the referenced commit, which isn't the
> case here.

> I agree that having some relation between the two is useful for
> determining the scope of a backport, but conveniently in this case the
> test failure was introduced in 6.13.

While the patch introducing the test failure was introduced in -rc3 it
was tagged as a fix for d5a32b60dc18 ("KVM: arm64: Allow userspace to
change ID_AA64MMFR{0-2}_EL1") which was in v6.7 so I'm expecting to see
it being backported to relevant stable kernels, which will in turn cause
testsuite failures in those stable kernels if this change doesn't go
back with it.  Hopefully they'll find it from the commit message.

I would say there's a case that leaving the tests broken is a bug, it's
certainly some kind of problem.  Obviously we're sometimes a bit relaxed
on that within a series, though it's fortunately relatively rare.
-------------- 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/20241217/b5c209c8/attachment.sig>

From wahrenst at gmx.net  Tue Dec 17 11:33:56 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Tue, 17 Dec 2024 20:33:56 +0100
Subject: [PATCH] arm64: defconfig: Enable pinctrl-based I2C mux
Message-ID: <20241217193356.111102-1-wahrenst@gmx.net>

The commit 84b1d6cc3e4c ("ARM: dts: bcm2711-rpi: Add pinctrl-based
multiplexing for I2C0") introduced multiplexing for I2C on BCM2711-based
Raspberry Pi boards. Unfortunately we missed to enable the necessary
driver in the defconfig.

Cc: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Link: https://lore.kernel.org/linux-devicetree/961b3d43-b4c9-4573-82d7-844aa129d994 at notapiano/
Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..0fee3848d03a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -516,6 +516,7 @@ CONFIG_TCG_TIS_I2C_INFINEON=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_MUX_PINCTRL=m
 CONFIG_I2C_BCM2835=m
 CONFIG_I2C_CADENCE=m
 CONFIG_I2C_DESIGNWARE_CORE=y
--
2.34.1



From willmcvicker at google.com  Tue Dec 17 11:35:16 2024
From: willmcvicker at google.com (William McVicker)
Date: Tue, 17 Dec 2024 11:35:16 -0800
Subject: [PATCH v2 1/3] mfd: syscon: Fix race in device_node_get_regmap()
In-Reply-To: <20241217-syscon-fixes-v2-1-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
 <20241217-syscon-fixes-v2-1-4f56d750541d@kernel.org>
Message-ID: <Z2HSdK0wwaHXEWMJ@google.com>

On 12/17/2024, Rob Herring (Arm) wrote:
> It is possible for multiple, simultaneous callers calling
> device_node_get_regmap() with the same node to fail to find an entry in
> the syscon_list. There is a period of time while the first caller is
> calling of_syscon_register() that subsequent callers also fail to find
> an entry in the syscon_list and then call of_syscon_register() a second
> time.
> 
> Fix this by keeping the lock held until after of_syscon_register()
> completes and adds the node to syscon_list. Convert the spinlock to a
> mutex as many of the functions called in of_syscon_register() such as
> kzalloc() and of_clk_get() may sleep.
> 
> Fixes: bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform devices")
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>

I verified this works on my Pixel 6. Thanks!

Tested-by: Will McVicker <willmcvicker at google.com>

Thanks,
Will


From florian.fainelli at broadcom.com  Tue Dec 17 11:37:24 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 17 Dec 2024 11:37:24 -0800
Subject: [PATCH v3 6/7] arm64: dts: broadcom: Correct hdmi device node names
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-6-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com> <20241212-dt-bcm2712-fixes-v3-6-44a7f3390331@raspberrypi.com>
Message-ID: <20241217193724.899605-1-florian.fainelli@broadcom.com>

From: Florian Fainelli <f.fainelli at gmail.com>

On Thu, 12 Dec 2024 18:36:33 +0000, Dave Stevenson <dave.stevenson at raspberrypi.com> wrote:
> The names of the hdmi0 and hdmi1 nodes had addresses that
> didn't match the reg properties for the nodes.
> 
> Fixes: f66b382affd8 ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree-arm64/next, thanks!
--
Florian


From willmcvicker at google.com  Tue Dec 17 11:37:36 2024
From: willmcvicker at google.com (William McVicker)
Date: Tue, 17 Dec 2024 11:37:36 -0800
Subject: [PATCH v2 3/3] mfd: syscon: Allow syscon nodes without a
 "syscon" compatible
In-Reply-To: <20241217-syscon-fixes-v2-3-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
 <20241217-syscon-fixes-v2-3-4f56d750541d@kernel.org>
Message-ID: <Z2HTAJmBeIUlWysh@google.com>

On 12/17/2024, Rob Herring (Arm) wrote:
> of_syscon_register_regmap() was added for nodes which need a custom
> regmap setup. It's not really correct for those nodes to claim they are
> compatible with "syscon" as the default handling likely doesn't work in
> those cases. If device_node_get_regmap() happens to be called first,
> then of_syscon_register() will be called and an incorrect regmap will be
> created (barring some other error). That may lead to unknown results in
> the worst case. In the best case, of_syscon_register_regmap() will fail
> with -EEXIST. This problem remains unless these cases drop "syscon" (an
> ABI issue) or we exclude them using their specific compatible. ATM,
> there is only one user: "google,gs101-pmu"
> 
> There are also cases of adding "syscon" compatible to existing nodes
> after the fact in order to register the syscon. That presents a
> potential DT ABI problem. Instead, if there's a kernel change needing a
> syscon for a node, then it should be possible to allow the kernel to
> register a syscon without a DT change. That's only possible by using
> of_syscon_register_regmap() currently, but in the future we may want to
> support a match list for cases which don't need a custom regmap.
> 
> With this change, the lookup functions will succeed for any node
> registered by of_syscon_register_regmap() regardless of whether the node
> compatible contains "syscon".
> 
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>

I verified this works on my Pixel 6. Thanks!

Tested-by: Will McVicker <willmcvicker at google.com>

Thanks,
Will


From florian.fainelli at broadcom.com  Tue Dec 17 11:37:38 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 17 Dec 2024 11:37:38 -0800
Subject: [PATCH v3 7/7] arm64: dts: broadcom: Remove intc controller on BCM2712.
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-7-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com> <20241212-dt-bcm2712-fixes-v3-7-44a7f3390331@raspberrypi.com>
Message-ID: <20241217193738.901055-1-florian.fainelli@broadcom.com>

From: Florian Fainelli <f.fainelli at gmail.com>

On Thu, 12 Dec 2024 18:36:34 +0000, Dave Stevenson <dave.stevenson at raspberrypi.com> wrote:
> The brcm,bcm2836-l1-intc controller isn't used on this platform.
> It is used on 32-bit kernels for the smp_boot_secondary hook, but
> BCM2712 can't run a 32-bit kernel.
> 
> Remove the node.
> 
> Fixes: e1417095a139 ("arm64: dts: broadcom: Add firmware clocks and power nodes to Pi5 DT")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree-arm64/next, thanks!
--
Florian


From willmcvicker at google.com  Tue Dec 17 11:36:57 2024
From: willmcvicker at google.com (William McVicker)
Date: Tue, 17 Dec 2024 11:36:57 -0800
Subject: [PATCH v2 2/3] mfd: syscon: Remove the platform driver support
In-Reply-To: <20241217-syscon-fixes-v2-2-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
 <20241217-syscon-fixes-v2-2-4f56d750541d@kernel.org>
Message-ID: <Z2HS2Y0nGBMgvz8U@google.com>

On 12/17/2024, Rob Herring (Arm) wrote:
> The platform driver is dead code. It is not used by DT platforms since
> commit bdb0066df96e ("mfd: syscon: Decouple syscon interface from
> platform devices") which said:
> 
>     For non-DT based platforms, this patch keeps syscon platform driver
>     structure so that syscon can be probed and such non-DT based drivers
>     can use syscon_regmap_lookup_by_pdev API and access regmap handles.
>     Once all users of "syscon_regmap_lookup_by_pdev" migrated to DT based,
>     we can completely remove platform driver of syscon, and keep only helper
>     functions to get regmap handles.
> 
> The last user of syscon_regmap_lookup_by_pdevname() was removed in 2018.
> syscon_regmap_lookup_by_pdevname() was then removed in 2019, but that
> commit failed to remove the rest of the platform driver.
> 
> Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>

I verified this works on my Pixel 6. Thanks!

Tested-by: Will McVicker <willmcvicker at google.com>

Thanks,
Will


From florian.fainelli at broadcom.com  Tue Dec 17 11:37:05 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 17 Dec 2024 11:37:05 -0800
Subject: [PATCH v3 5/7] arm64: dts: broadcom: Rename bcm2712 interrupt controllers
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-5-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com> <20241212-dt-bcm2712-fixes-v3-5-44a7f3390331@raspberrypi.com>
Message-ID: <20241217193705.897820-1-florian.fainelli@broadcom.com>

From: Florian Fainelli <f.fainelli at gmail.com>

On Thu, 12 Dec 2024 18:36:32 +0000, Dave Stevenson <dave.stevenson at raspberrypi.com> wrote:
> CHECK_DTBS produces errors on bcm2712-rpi-5-b.dtb and bcm2712-d-rpi-5-b.dtb
> of:
> intc at 7d508380: $nodename:0: 'intc at 7d508380' does not match '^interrupt-controller(@[0-9a-f,]+)*$'
>         from schema $id: http://devicetree.org/schemas/interrupt-controller/brcm,l2-intc.yaml#
> intc at 7d508400: $nodename:0: 'intc at 7d508400' does not match '^interrupt-controller(@[0-9a-f,]+)*$'
>         from schema $id: http://devicetree.org/schemas/interrupt-controller/brcm,l2-intc.yaml#
> 
> Rename the nodes from intc to interrupt-controller.
> 
> Fixes: f66b382affd8 ("arm64: dts: broadcom: Add display pipeline support to BCM2712")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree-arm64/next, thanks!
--
Florian


From florian.fainelli at broadcom.com  Tue Dec 17 11:41:55 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 17 Dec 2024 11:41:55 -0800
Subject: [PATCH v3 0/7] drm/vc4: Fixup DT and DT binding issues from
 recent patchset
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
Message-ID: <9952cc14-72a1-4a56-977d-58177d6c553e@broadcom.com>

On 12/12/24 10:36, Dave Stevenson wrote:
> I missed the DT errors from the recent patchset[1] (DT patches
> in linux-next via Florian, DRM bindings patches on dri-misc-next)
> as Rob's bot report got spam filtered, so this is a fixup set.
> 
> Largely it was changes to number of interrupts or clocks in the
> bindings, so those are now covered.
> 
> I've fixed up the missing "interrupt-controller" flags for 2711
> and 2712 whilst here.
> 
> I can't get my head around what is meant to happen with ranges:
> "soc at 107c000000: firmware: 'ranges' is a required property"
> The meaning seems obvious.
> 
> However if I add it then I get:
> "firmware: '#address-cells', '#size-cells', 'dma-ranges', 'ranges' do
> not match any of the regexes: 'pinctrl-[0-9]+'
> from schema $id: http://devicetree.org/schemas/arm/bcm/raspberrypi,bcm2835-firmware.yaml#
> 
> There's obviously some other flag I need to set in the bindings,
> but I can't work it out. We have similar errors for all the Pi
> platforms for one or more nodes.
> Please advise and I'll happily fix them all.

Dave, as proposed earlier, I have squashed/fixed up the fixes into their 
original commit since those were only in linux-next. Thanks!
-- 
Florian


From florian.fainelli at broadcom.com  Tue Dec 17 11:44:37 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 17 Dec 2024 11:44:37 -0800
Subject: [PATCH 0/2] memory: brcmstb_memc: Support for BCM74165
Message-ID: <20241217194439.929040-1-florian.fainelli@broadcom.com>

This patch series documents and matches the compatible string used on
BCM74165, thanks!

Florian Fainelli (2):
  dt-bindings: memory-controller: Document rev c.1.5 compatible
  memory: brcmstb_memc: Match rev c.1.5 compatible string

 .../bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml    | 1 +
 drivers/memory/brcmstb_memc.c                                 | 4 ++++
 2 files changed, 5 insertions(+)

-- 
2.43.0



From florian.fainelli at broadcom.com  Tue Dec 17 11:44:38 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 17 Dec 2024 11:44:38 -0800
Subject: [PATCH 1/2] dt-bindings: memory-controller: Document rev c.1.5 compatible
In-Reply-To: <20241217194439.929040-1-florian.fainelli@broadcom.com>
References: <20241217194439.929040-1-florian.fainelli@broadcom.com>
Message-ID: <20241217194439.929040-2-florian.fainelli@broadcom.com>

Document the revision c.1.5 compatible string that is present on newer
Broadcom STB memory controllers (74165 and onwards).

Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
---
 .../bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml       | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
index 4b072c879b02..99d79ccd1036 100644
--- a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
@@ -29,6 +29,7 @@ properties:
           - brcm,brcmstb-memc-ddr-rev-c.1.2
           - brcm,brcmstb-memc-ddr-rev-c.1.3
           - brcm,brcmstb-memc-ddr-rev-c.1.4
+          - brcm,brcmstb-memc-ddr-rev-c.1.5
       - const: brcm,brcmstb-memc-ddr
 
   reg:
-- 
2.43.0



From florian.fainelli at broadcom.com  Tue Dec 17 11:44:39 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Tue, 17 Dec 2024 11:44:39 -0800
Subject: [PATCH 2/2] memory: brcmstb_memc: Match rev c.1.5 compatible string
In-Reply-To: <20241217194439.929040-1-florian.fainelli@broadcom.com>
References: <20241217194439.929040-1-florian.fainelli@broadcom.com>
Message-ID: <20241217194439.929040-3-florian.fainelli@broadcom.com>

Match the revision c.1.5 compatible string and apply the v2.1x register
layout such that we can properly control the Self Refresh Power Down
timeouts with those controller version(s).

Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
---
 drivers/memory/brcmstb_memc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/memory/brcmstb_memc.c b/drivers/memory/brcmstb_memc.c
index 4f17a93aa028..a2750142cef7 100644
--- a/drivers/memory/brcmstb_memc.c
+++ b/drivers/memory/brcmstb_memc.c
@@ -236,6 +236,10 @@ static const struct of_device_id brcmstb_memc_of_match[] = {
 		.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.4",
 		.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
 	},
+	{
+		.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.5",
+		.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
+	},
 	/* default to the original offset */
 	{
 		.compatible = "brcm,brcmstb-memc-ddr",
-- 
2.43.0



From laurent.pinchart at ideasonboard.com  Tue Dec 17 11:50:10 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 17 Dec 2024 21:50:10 +0200
Subject: [PATCH] arm64: defconfig: Enable pinctrl-based I2C mux
In-Reply-To: <20241217193356.111102-1-wahrenst@gmx.net>
References: <20241217193356.111102-1-wahrenst@gmx.net>
Message-ID: <20241217195010.GE23470@pendragon.ideasonboard.com>

On Tue, Dec 17, 2024 at 08:33:56PM +0100, Stefan Wahren wrote:
> The commit 84b1d6cc3e4c ("ARM: dts: bcm2711-rpi: Add pinctrl-based
> multiplexing for I2C0") introduced multiplexing for I2C on BCM2711-based
> Raspberry Pi boards. Unfortunately we missed to enable the necessary
> driver in the defconfig.
> 
> Cc: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Link: https://lore.kernel.org/linux-devicetree/961b3d43-b4c9-4573-82d7-844aa129d994 at notapiano/
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index c62831e61586..0fee3848d03a 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -516,6 +516,7 @@ CONFIG_TCG_TIS_I2C_INFINEON=y
>  CONFIG_I2C_CHARDEV=y
>  CONFIG_I2C_MUX=y
>  CONFIG_I2C_MUX_PCA954x=y
> +CONFIG_I2C_MUX_PINCTRL=m
>  CONFIG_I2C_BCM2835=m
>  CONFIG_I2C_CADENCE=m
>  CONFIG_I2C_DESIGNWARE_CORE=y
> --
> 2.34.1
> 

-- 
Regards,

Laurent Pinchart


From beata.michalska at arm.com  Tue Dec 17 12:10:43 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Tue, 17 Dec 2024 21:10:43 +0100
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <20241217042726.isllh5bulpnwql7i@vireshk-i7>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
 <20241212065100.sjb7lrlmksbm2hdk@vireshk-i7>
 <Z2CmcelSy89NULtz@arm.com>
 <20241217042726.isllh5bulpnwql7i@vireshk-i7>
Message-ID: <Z2Haw_o8gF-Ce1gx@arm.com>

On Tue, Dec 17, 2024 at 09:57:26AM +0530, Viresh Kumar wrote:
> On 16-12-24, 23:15, Beata Michalska wrote:
> > My bad as I must have misinterpreted that message. Although I am not entirely
> > sure why this might be unacceptable as it is not such uncommon approach to use
> > signed int space to cover both: expected positive value as well as potential
> > error code case failure.
> 
> This part is fine. The problem is with handling frequency here. Signed int can
> capture up to 2 GHz of freq, where as unsigned int can capture up to 4 GHz and
> so we would really like to keep it at 4 GHz..
Right, though the arch_freq_get_on_cpu operates on kHz values.

---
BR
Beata
> 
> Maybe we need to move to 64 bits for frequency at some point of time, but at
> least we should try to not break it for now.
> 
> > Enabling the new attribute for all is an option, tough not entirely compelling
> > one as exposing a feature that is known not to be supported seems bit
> > counterintuitive. On the other hand using cpufreq driver flags won't help much
> > as the support for the new attrib is platform-specific, not driver-specific.
> 
> -- 
> viresh


From sboyd at kernel.org  Tue Dec 17 12:16:46 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 17 Dec 2024 12:16:46 -0800
Subject: [PATCH 4/5] clk: mediatek: mt2701-mm: add missing dummy clk
In-Reply-To: <9de23440fcba1ffef9e77d58c9f505105e57a250.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org> <9de23440fcba1ffef9e77d58c9f505105e57a250.1734300668.git.daniel@makrotopia.org>
Message-ID: <0c57146b35f7f15510220ca25ebf565c.sboyd@kernel.org>

Quoting Daniel Golle (2024-12-15 14:14:34)
> Add dummy clk which was missed during the conversion to
> mtk_clk_pdev_probe() and is required for the existing DT bindings to
> keep working.
> 
> Fixes: 65c10c50c9c7 ("clk: mediatek: Migrate to mtk_clk_pdev_probe() for multimedia clocks")
> Cc: stable at vger.kernel.org
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---

Applied to clk-next


From jeremy.linton at arm.com  Tue Dec 17 12:16:59 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Tue, 17 Dec 2024 14:16:59 -0600
Subject: [PATCH v3 1/1] arm64: rsi: Add automatic arm-cca-guest module
 loading
In-Reply-To: <Z1Uiz7Hn2XisyP-N@vm3>
References: <20241207012128.247522-1-jeremy.linton@arm.com>
 <20241207012128.247522-2-jeremy.linton@arm.com> <Z1Uiz7Hn2XisyP-N@vm3>
Message-ID: <8ef0a63c-bde2-443b-b2fd-59d24c5e18e6@arm.com>

Hi,

On 12/7/24 10:38 PM, Itaru Kitayama wrote:
> Hi Jeremy,
> 
> On Fri, Dec 06, 2024 at 07:21:28PM -0600, Jeremy Linton wrote:
>> The TSM module provides guest identification and attestation when a
>> guest runs in CCA mode. By creating a dummy platform device, let's
> 
> Perhaps could you spell out like; a guest runs in the Realm state?

Thanks for looking at this.

I thought that was evident from the rest of the commits here, but sure.

Thanks again.


> 
> Thanks,
> Itaru.
>   
>> ensure the module is automatically loaded. The udev daemon loads the
>> TSM module after it receives a device addition event. Once that
>> happens, it can be used earlier in the boot process to decrypt the
>> rootfs.
>>
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> Reviewed-by: Gavin Shan <gshan at redhat.com>
>> ---
>>   arch/arm64/include/asm/rsi.h                    |  2 ++
>>   arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
>>   drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
>>   3 files changed, 25 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
>> index 188cbb9b23f5..b42aeac05340 100644
>> --- a/arch/arm64/include/asm/rsi.h
>> +++ b/arch/arm64/include/asm/rsi.h
>> @@ -10,6 +10,8 @@
>>   #include <linux/jump_label.h>
>>   #include <asm/rsi_cmds.h>
>>   
>> +#define RSI_PDEV_NAME "arm-cca-dev"
>> +
>>   DECLARE_STATIC_KEY_FALSE(rsi_present);
>>   
>>   void __init arm64_rsi_init(void);
>> diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
>> index 3031f25c32ef..5434e5496ac2 100644
>> --- a/arch/arm64/kernel/rsi.c
>> +++ b/arch/arm64/kernel/rsi.c
>> @@ -8,6 +8,7 @@
>>   #include <linux/psci.h>
>>   #include <linux/swiotlb.h>
>>   #include <linux/cc_platform.h>
>> +#include <linux/platform_device.h>
>>   
>>   #include <asm/io.h>
>>   #include <asm/mem_encrypt.h>
>> @@ -140,3 +141,17 @@ void __init arm64_rsi_init(void)
>>   	static_branch_enable(&rsi_present);
>>   }
>>   
>> +static struct platform_device rsi_dev = {
>> +	.name = RSI_PDEV_NAME,
>> +	.id = PLATFORM_DEVID_NONE
>> +};
>> +
>> +static int __init rsi_init(void)
>> +{
>> +	if (is_realm_world() &&
>> +	    platform_device_register(&rsi_dev))
>> +		pr_err("failed to register rsi platform device\n");
>> +	return 0;
>> +}
>> +
>> +arch_initcall(rsi_init)
>> diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
>> index 488153879ec9..87f162736b2e 100644
>> --- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
>> +++ b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
>> @@ -6,6 +6,7 @@
>>   #include <linux/arm-smccc.h>
>>   #include <linux/cc_platform.h>
>>   #include <linux/kernel.h>
>> +#include <linux/mod_devicetable.h>
>>   #include <linux/module.h>
>>   #include <linux/smp.h>
>>   #include <linux/tsm.h>
>> @@ -219,6 +220,13 @@ static void __exit arm_cca_guest_exit(void)
>>   }
>>   module_exit(arm_cca_guest_exit);
>>   
>> +/* modalias, so userspace can autoload this module when RSI is available */
>> +static const struct platform_device_id arm_cca_match[] __maybe_unused = {
>> +	{ RSI_PDEV_NAME, 0},
>> +	{ }
>> +};
>> +
>> +MODULE_DEVICE_TABLE(platform, arm_cca_match);
>>   MODULE_AUTHOR("Sami Mujawar <sami.mujawar at arm.com>");
>>   MODULE_DESCRIPTION("Arm CCA Guest TSM Driver");
>>   MODULE_LICENSE("GPL");
>> -- 
>> 2.46.0
>>



From sboyd at kernel.org  Tue Dec 17 12:16:59 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 17 Dec 2024 12:16:59 -0800
Subject: [PATCH 5/5] clk: mediatek: mt2701-img: add missing dummy clk
In-Reply-To: <d677486a5c563fe5c47aa995841adc2aaa183b8a.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org> <d677486a5c563fe5c47aa995841adc2aaa183b8a.1734300668.git.daniel@makrotopia.org>
Message-ID: <2c3885eb1bbaca8a939b9233fb593ace.sboyd@kernel.org>

Quoting Daniel Golle (2024-12-15 14:14:48)
> Add dummy clk for index 0 which was missed during the conversion to
> mtk_clk_simple_probe().
> 
> Fixes: 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver")
> Cc: stable at vger.kernel.org
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Tue Dec 17 12:16:04 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 17 Dec 2024 12:16:04 -0800
Subject: [PATCH 1/5] clk: mediatek: mt2701-vdec: fix conversion to mtk_clk_simple_probe
In-Reply-To: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org>
Message-ID: <fab3fb3ad72809ef2ab94098b18eae73.sboyd@kernel.org>

Quoting Daniel Golle (2024-12-15 14:13:49)
> Commit 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to
> simplify driver") broke DT bindings as the highest index was reduced by
> 1 because the id count starts from 1 and not from 0.
> 
> Fix this, like for other drivers which had the same issue, by adding a
> dummy clk at index 0.
> 
> Fixes: 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver")
> Cc: stable at vger.kernel.org
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Tue Dec 17 12:16:13 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 17 Dec 2024 12:16:13 -0800
Subject: [PATCH 2/5] clk: mediatek: mt2701-aud: fix conversion to mtk_clk_simple_probe
In-Reply-To: <a07584d803af57b9ce4b5df5e122c09bf5a56ac9.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org> <a07584d803af57b9ce4b5df5e122c09bf5a56ac9.1734300668.git.daniel@makrotopia.org>
Message-ID: <6e302efdddee29149a324562ea2b9972.sboyd@kernel.org>

Quoting Daniel Golle (2024-12-15 14:14:11)
> Some of the audio subsystem clocks defined in clk-mt2701.h aren't
> actually used by the driver. This broke conversion to
> mtk_clk_simple_probe which expects that the highest possible clk id is
> defined by the ARRAY_SIZE.
> 
> Add additional dummy clocks to fill the gaps and remain compatible with
> the existing DT bindings.
> 
> Fixes: 0f69a423c458 ("clk: mediatek: Switch to mtk_clk_simple_probe() where possible")
> Cc: stable at vger.kernel.org
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Tue Dec 17 12:16:31 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 17 Dec 2024 12:16:31 -0800
Subject: [PATCH 3/5] clk: mediatek: mt2701-bdp: add missing dummy clk
In-Reply-To: <b8526c882a50f2b158df0eccb4a165956fd8fa13.1734300668.git.daniel@makrotopia.org>
References: <b126a5577f3667ef19b1b5feea5e70174084fb03.1734300668.git.daniel@makrotopia.org> <b8526c882a50f2b158df0eccb4a165956fd8fa13.1734300668.git.daniel@makrotopia.org>
Message-ID: <9f9f82956607d47881091bdb0eb6b380.sboyd@kernel.org>

Quoting Daniel Golle (2024-12-15 14:14:24)
> Add dummy clk for index 0 which was missed during the conversion to
> mtk_clk_simple_probe().
> 
> Fixes: 973d1607d936 ("clk: mediatek: mt2701: use mtk_clk_simple_probe to simplify driver")
> Cc: stable at vger.kernel.org
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---

Applied to clk-next


From derek.foreman at collabora.com  Tue Dec 17 12:17:07 2024
From: derek.foreman at collabora.com (Derek Foreman)
Date: Tue, 17 Dec 2024 14:17:07 -0600
Subject: [PATCH] drm/rockchip: Don't change hdmi reference clock rate
Message-ID: <20241217201708.3320673-1-derek.foreman@collabora.com>

The code that changes hdmi->ref_clk was accidentally copied from
downstream code that sets a different clock. We don't actually
want to set any clock here at all.

Setting this clock incorrectly leads to incorrect timings for
DDC, CEC, and HDCP signal generation.

No Fixes listed, as the theoretical timing error in DDC appears to
still be within tolerances and harmless - and HDCP and CEC are not
yet supported.

Signed-off-by: Derek Foreman <derek.foreman at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index e498767a0a66..cebd72bf1ef2 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -54,7 +54,6 @@ struct rockchip_hdmi_qp {
 	struct regmap *regmap;
 	struct regmap *vo_regmap;
 	struct rockchip_encoder encoder;
-	struct clk *ref_clk;
 	struct dw_hdmi_qp *hdmi;
 	struct phy *phy;
 	struct gpio_desc *enable_gpio;
@@ -81,7 +80,6 @@ static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder)
 	if (crtc && crtc->state) {
 		rate = drm_hdmi_compute_mode_clock(&crtc->state->adjusted_mode,
 						   8, HDMI_COLORSPACE_RGB);
-		clk_set_rate(hdmi->ref_clk, rate);
 		/*
 		 * FIXME: Temporary workaround to pass pixel clock rate
 		 * to the PHY driver until phy_configure_opts_hdmi
@@ -330,17 +328,6 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
-	for (i = 0; i < ret; i++) {
-		if (!strcmp(clks[i].id, "ref")) {
-			hdmi->ref_clk = clks[1].clk;
-			break;
-		}
-	}
-	if (!hdmi->ref_clk) {
-		drm_err(hdmi, "Missing ref clock\n");
-		return -EINVAL;
-	}
-
 	hdmi->enable_gpio = devm_gpiod_get_optional(hdmi->dev, "enable",
 						    GPIOD_OUT_HIGH);
 	if (IS_ERR(hdmi->enable_gpio)) {
-- 
2.45.2



From robh at kernel.org  Tue Dec 17 12:35:57 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 17 Dec 2024 14:35:57 -0600
Subject: [PATCH v3 07/33] dt-bindings: display: mediatek: Add binding
 for MT8195 HDMI-TX v2
In-Reply-To: <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
 <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>
Message-ID: <173446775715.3082463.16696683643191966577.robh@kernel.org>


On Tue, 17 Dec 2024 16:43:19 +0100, AngeloGioacchino Del Regno wrote:
> Add a binding for the HDMI TX v2 Encoder found in MediaTek MT8195
> and MT8188 SoCs.
> 
> This fully supports the HDMI Specification 2.0b, hence it provides
> support for 3D-HDMI, Polarity inversion, up to 16 bits Deep Color,
> color spaces including RGB444, YCBCR420/422/444 (ITU601/ITU709) and
> xvYCC, with output resolutions up to 3840x2160p at 60Hz.
> 
> Moreover, it also supports HDCP 1.4 and 2.3, Variable Refresh Rate
> (VRR) and Consumer Electronics Control (CEC).
> 
> This IP also includes support for HDMI Audio, including IEC60958
> and IEC61937 SPDIF, 8-channel PCM, DSD, and other lossless audio
> according to HDMI 2.0.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  .../mediatek/mediatek,mt8195-hdmi.yaml        | 154 ++++++++++++++++++
>  1 file changed, 154 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml:
Error in referenced schema matching $id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.example.dtb: hdmi-tx at 1c300000: i2c: False schema does not allow {'compatible': ['mediatek,mt8195-hdmi-ddc'], 'clocks': [[4294967295]]}
	from schema $id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.example.dtb: hdmi-tx at 1c300000: i2c: Unevaluated properties are not allowed ('clocks', 'compatible' were unexpected)
	from schema $id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml#
Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.example.dtb: /example-0/soc/hdmi-tx at 1c300000/i2c: failed to match any schema with compatible: ['mediatek,mt8195-hdmi-ddc']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241217154345.276919-8-angelogioacchino.delregno 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 cristian.ciocaltea at collabora.com  Tue Dec 17 12:52:23 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 17 Dec 2024 22:52:23 +0200
Subject: [PATCH] drm/rockchip: Don't change hdmi reference clock rate
In-Reply-To: <20241217201708.3320673-1-derek.foreman@collabora.com>
References: <20241217201708.3320673-1-derek.foreman@collabora.com>
Message-ID: <2be9721e-62f3-41cc-83a8-5189b750a655@collabora.com>

On 12/17/24 10:17 PM, Derek Foreman wrote:
> The code that changes hdmi->ref_clk was accidentally copied from
> downstream code that sets a different clock. We don't actually
> want to set any clock here at all.
> 
> Setting this clock incorrectly leads to incorrect timings for
> DDC, CEC, and HDCP signal generation.
> 
> No Fixes listed, as the theoretical timing error in DDC appears to
> still be within tolerances and harmless - and HDCP and CEC are not
> yet supported.
> 
> Signed-off-by: Derek Foreman <derek.foreman at collabora.com>
> ---
>  drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 13 -------------
>  1 file changed, 13 deletions(-)

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>


From sakari.ailus at linux.intel.com  Tue Dec 17 13:12:55 2024
From: sakari.ailus at linux.intel.com (Sakari Ailus)
Date: Tue, 17 Dec 2024 21:12:55 +0000
Subject: [PATCH 2/9] dt-bindings: media: clarify stm32 csi & simplify
 example
In-Reply-To: <20241217-crawfish-tiring-792c535301d0@spud>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
 <20241217-csi_dcmipp_mp25_enhancements-v1-2-2b432805d17d@foss.st.com>
 <20241217-crawfish-tiring-792c535301d0@spud>
Message-ID: <Z2HpVyVEs7jn0VPd@kekkonen.localdomain>

Hi Conor,

On Tue, Dec 17, 2024 at 06:24:42PM +0000, Conor Dooley wrote:
> On Tue, Dec 17, 2024 at 06:39:19PM +0100, Alain Volmat wrote:
> > Clarify the description of the stm32 csi by mentioning CSI-2 and
> > D-PHY.
> 
> > Remove the bus-type property from the example.
> 
> Why? What's there to gain from the example being (seemingly?) less
> comprehensive?

As the device has D-PHY, other options are excluded. I.e. that property is
redundant for this device.

> 
> > 
> > Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> > ---
> >  Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> > index 33bedfe41924..e9fa3cfea5d2 100644
> > --- a/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> > +++ b/Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
> > @@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
> >  title: STMicroelectronics STM32 CSI controller
> >  
> >  description:
> > -  The STM32 CSI controller allows connecting a CSI based
> > -  camera to the DCMIPP camera pipeline.
> > +  The STM32 CSI controller, coupled with a D-PHY allows connecting a CSI-2
> > +  based camera to the DCMIPP camera pipeline.
> >  
> >  maintainers:
> >    - Alain Volmat <alain.volmat at foss.st.com>
> > @@ -109,7 +109,6 @@ examples:
> >                  endpoint {
> >                      remote-endpoint = <&imx335_ep>;
> >                      data-lanes = <1 2>;
> > -                    bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
> >                  };
> >              };
> >  
> > 

-- 
Kind regards,

Sakari Ailus


From andre.przywara at arm.com  Tue Dec 17 13:15:05 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 17 Dec 2024 21:15:05 +0000
Subject: [PATCH 1/3] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and
 PLL_MIPI
In-Reply-To: <CA+E=qVeQ8uHBCeFtw6_2cY3252-YXc6eWrf5_YdeVgbp5LJo5g@mail.gmail.com>
References: <20241215053639.738890-1-anarsoul@gmail.com>
	<20241215053639.738890-2-anarsoul@gmail.com>
	<qbtp4jvkx3r5azufe4k3vtapqpfs54dyjiu4cy5v5wkkzumrzx@vy3xzkfplbue>
	<CA+E=qVeQ8uHBCeFtw6_2cY3252-YXc6eWrf5_YdeVgbp5LJo5g@mail.gmail.com>
Message-ID: <20241217211505.7f9c9e4e@minigeek.lan>

On Tue, 17 Dec 2024 10:00:45 -0800
Vasily Khoruzhick <anarsoul at gmail.com> wrote:

Hi,

> On Mon, Dec 16, 2024 at 11:33?PM Krzysztof Kozlowski <krzk at kernel.org> wrote:
> >
> > On Sat, Dec 14, 2024 at 09:34:57PM -0800, Vasily Khoruzhick wrote:  
> > > These will be used to explicitly select TCON0 clock parent in dts
> > >
> > > Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
> > > Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
> > > ---
> > >  drivers/clk/sunxi-ng/ccu-sun50i-a64.h      | 2 --
> > >  include/dt-bindings/clock/sun50i-a64-ccu.h | 2 +  
> 
> Hi Krzysztof,
> 
> > You cannot combine these changes.  
> 
> The patch basically moves defines out from ccu-sun50i-a64.h to
> sun50i-a64-ccu.h. How do I split the change without introducing
> compilation failure?

You can just have the binding part first, adding the (same) definition
to the binding headers. As long as the #define's are not conflicting,
this is fine.
Then remove the now redundant definitions in the kernel headers, with a
subsequent patch.

Cheers,
Andre


> 
> > Please run scripts/checkpatch.pl and fix reported warnings. Then please
> > run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
> > Some warnings can be ignored, especially from --strict run, but the code
> > here looks like it needs a fix. Feel free to get in touch if the warning
> > is not clear.  
> 
> Yeah, it is not clear what do you want me to do, assuming the previous
> similar change to sun50i-a64-ccu.h did essentially the same, see
> 71b597ef5d46a326fb0d5cbfc1c6ff1d73cdc7f9
> 
> Regards,
> Vasily
> 
> > Best regards,
> > Krzysztof
> >  
> 



From oliver.upton at linux.dev  Tue Dec 17 13:20:33 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:33 -0800
Subject: [PATCH 03/18] drivers/perf: apple_m1: Map generic branch events
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-4-oliver.upton@linux.dev>

Map the generic perf events for branch prediction stats to the
corresponding hardware events.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 drivers/perf/apple_m1_cpu_pmu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index 2a34523500f8..d6d4ff6da862 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -170,6 +170,8 @@ static const unsigned m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
 	PERF_MAP_ALL_UNSUPPORTED,
 	[PERF_COUNT_HW_CPU_CYCLES]		= M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE,
 	[PERF_COUNT_HW_INSTRUCTIONS]		= M1_PMU_PERFCTR_INST_ALL,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= M1_PMU_PERFCTR_INST_BRANCH,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= M1_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,
 };
 
 /* sysfs definitions */
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:34 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:34 -0800
Subject: [PATCH 04/18] drivers/perf: apple_m1: Provide helper for mapping PMUv3 events
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-5-oliver.upton@linux.dev>

Apple M* parts carry some IMP DEF traps for guest accesses to PMUv3
registers, even though the underlying hardware doesn't implement PMUv3.
This means it is possible to virtualize PMUv3 for KVM guests.

Add a helper for mapping common PMUv3 event IDs onto hardware event IDs,
keeping the implementation-specific crud in the PMU driver rather than
KVM proper.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 drivers/perf/apple_m1_cpu_pmu.c | 32 ++++++++++++++++++++++++++++++++
 include/linux/perf/arm_pmu.h    |  1 +
 2 files changed, 33 insertions(+)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index d6d4ff6da862..b4fe247543a6 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -12,6 +12,7 @@
 
 #include <linux/of.h>
 #include <linux/perf/arm_pmu.h>
+#include <linux/perf/arm_pmuv3.h>
 #include <linux/platform_device.h>
 
 #include <asm/apple_m1_pmu.h>
@@ -174,6 +175,14 @@ static const unsigned m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
 	[PERF_COUNT_HW_BRANCH_MISSES]		= M1_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,
 };
 
+#define M1_PMUV3_EVENT_MAP(pmuv3_event, m1_event)							\
+	[ARMV8_PMUV3_PERFCTR_##pmuv3_event]			= M1_PMU_PERFCTR_##m1_event
+
+static const unsigned int m1_pmu_pmceid_map[ARMV8_PMUV3_MAX_COMMON_EVENTS] = {
+	[0 ... ARMV8_PMUV3_MAX_COMMON_EVENTS - 1]	= HW_OP_UNSUPPORTED,
+	M1_PMUV3_EVENT_MAP(CPU_CYCLES,		CORE_ACTIVE_CYCLE),
+};
+
 /* sysfs definitions */
 static ssize_t m1_pmu_events_sysfs_show(struct device *dev,
 					struct device_attribute *attr,
@@ -558,6 +567,26 @@ static int m2_pmu_map_event(struct perf_event *event)
 	return armpmu_map_event(event, &m1_pmu_perf_map, NULL, M1_PMU_CFG_EVENT);
 }
 
+static int m1_pmu_map_pmuv3_event(unsigned int eventsel)
+{
+	int m1_event = HW_OP_UNSUPPORTED;
+
+	if (eventsel < ARMV8_PMUV3_MAX_COMMON_EVENTS)
+		m1_event = m1_pmu_pmceid_map[eventsel];
+
+	return m1_event == HW_OP_UNSUPPORTED ? -EOPNOTSUPP : m1_event;
+}
+
+static void m1_pmu_init_pmceid(struct arm_pmu *pmu)
+{
+	unsigned int event;
+
+	for (event = 0; event < ARMV8_PMUV3_MAX_COMMON_EVENTS; event++) {
+		if (m1_pmu_map_pmuv3_event(event) >= 0)
+			set_bit(event, pmu->pmceid_bitmap);
+	}
+}
+
 static void m1_pmu_reset(void *info)
 {
 	int i;
@@ -618,6 +647,9 @@ static int m1_pmu_init(struct arm_pmu *cpu_pmu, u32 flags)
 	cpu_pmu->reset		  = m1_pmu_reset;
 	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
 
+	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
+	m1_pmu_init_pmceid(cpu_pmu);
+
 	bitmap_set(cpu_pmu->cntr_mask, 0, M1_PMU_NR_COUNTERS);
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 4b5b83677e3f..35f3778ae20e 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -100,6 +100,7 @@ struct arm_pmu {
 	void		(*stop)(struct arm_pmu *);
 	void		(*reset)(void *);
 	int		(*map_event)(struct perf_event *event);
+	int		(*map_pmuv3_event)(unsigned int eventsel);
 	DECLARE_BITMAP(cntr_mask, ARMPMU_MAX_HWEVENTS);
 	bool		secure_access; /* 32-bit ARM only */
 #define ARMV8_PMUV3_MAX_COMMON_EVENTS		0x40
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:35 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:35 -0800
Subject: [PATCH 05/18] KVM: arm64: Compute PMCEID from arm_pmu's event bitmaps
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-6-oliver.upton@linux.dev>

The PMUv3 driver populates a couple of bitmaps with the values of
PMCEID{0,1}, from which the guest's PMCEID{0,1} can be derived. This
is particularly convenient when virtualizing PMUv3 on IMP DEF hardware,
as reading the nonexistent PMCEID registers leads to a rather unpleasant
UNDEF.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 47 ++++++++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 456102bc0b55..809d65b912e8 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -861,8 +861,42 @@ static struct arm_pmu *kvm_pmu_probe_armpmu(void)
 	return pmu;
 }
 
+static u64 __compute_pmceid(struct arm_pmu *pmu, bool pmceid1)
+{
+	u32 hi[2], lo[2];
+
+	bitmap_to_arr32(lo, pmu->pmceid_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
+	bitmap_to_arr32(hi, pmu->pmceid_ext_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
+
+	return ((u64)hi[pmceid1] << 32) | lo[pmceid1];
+}
+
+static u64 compute_pmceid0(struct arm_pmu *pmu)
+{
+	u64 val = __compute_pmceid(pmu, 0);
+
+	/* always support CHAIN */
+	val |= BIT(ARMV8_PMUV3_PERFCTR_CHAIN);
+	return val;
+}
+
+static u64 compute_pmceid1(struct arm_pmu *pmu)
+{
+	u64 val = __compute_pmceid(pmu, 1);
+
+	/*
+	 * Don't advertise STALL_SLOT*, as PMMIR_EL0 is handled
+	 * as RAZ
+	 */
+	val &= ~(BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32) |
+		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND - 32) |
+		 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND - 32));
+	return val;
+}
+
 u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
 {
+	struct arm_pmu *cpu_pmu = vcpu->kvm->arch.arm_pmu;
 	unsigned long *bmap = vcpu->kvm->arch.pmu_filter;
 	u64 val, mask = 0;
 	int base, i, nr_events;
@@ -871,19 +905,10 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
 		return 0;
 
 	if (!pmceid1) {
-		val = read_sysreg(pmceid0_el0);
-		/* always support CHAIN */
-		val |= BIT(ARMV8_PMUV3_PERFCTR_CHAIN);
+		val = compute_pmceid0(cpu_pmu);
 		base = 0;
 	} else {
-		val = read_sysreg(pmceid1_el0);
-		/*
-		 * Don't advertise STALL_SLOT*, as PMMIR_EL0 is handled
-		 * as RAZ
-		 */
-		val &= ~(BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32) |
-			 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND - 32) |
-			 BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND - 32));
+		val = compute_pmceid1(cpu_pmu);
 		base = 32;
 	}
 
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:30 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:30 -0800
Subject: [PATCH 00/18] KVM: arm64: Support FEAT_PMUv3 on Apple hardware
Message-ID: <20241217212048.3709204-1-oliver.upton@linux.dev>

One of the interesting features of some Apple M* parts is an IMPDEF trap
that routes EL1/EL0 accesses of the PMUv3 registers to EL2. This allows
a hypervisor to emulate an architectural PMUv3 on top of the IMPDEF PMU
hardware present in the CPU.

And if you squint, this _might_ look like a CPU erratum :-)

This series takes advantage of these IMPDEF traps to provide PMUv3 to
KVM guests. As a starting point, only expose the fixed CPU cycle counter
and no event counters. Conveniently, this is enough to get Windows
running as a KVM guest on Apple hardware.

I've tried to keep the deviation to a minimum by refactoring some of the
flows used for PMUv3, e.g. computing PMCEID from the arm_pmu bitmap
instead of reading hardware directly.

RFC -> v1:
 - Rebase to 6.13-rc3
 - Add support for 1 event counter in addition to CPU cycle counter
 - Don't sneak past the PMU event filter (Marc)
 - Have the PMU driver provide a PMUv3 -> HW event ID mapping (Marc)

Tested on my M2 with Linux and Windows guests. If possible, I'd
appreciate someone testing on an M1 as I haven't added those MIDRs to
the erratum yet.

Oliver Upton (18):
  drivers/perf: apple_m1: Refactor event select/filter configuration
  drivers/perf: apple_m1: Support host/guest event filtering
  drivers/perf: apple_m1: Map generic branch events
  drivers/perf: apple_m1: Provide helper for mapping PMUv3 events
  KVM: arm64: Compute PMCEID from arm_pmu's event bitmaps
  KVM: arm64: Always support SW_INCR PMU event
  KVM: arm64: Remap PMUv3 events onto hardware
  KVM: arm64: Use a cpucap to determine if system supports FEAT_PMUv3
  KVM: arm64: Drop kvm_arm_pmu_available static key
  KVM: arm64: Use guard() to cleanup usage of arm_pmus_lock
  KVM: arm64: Move PMUVer filtering into KVM code
  KVM: arm64: Compute synthetic sysreg ESR for Apple PMUv3 traps
  KVM: arm64: Advertise PMUv3 if IMPDEF traps are present
  KVM: arm64: Advertise 0 event counters for IMPDEF PMU
  arm64: Enable IMP DEF PMUv3 traps on Apple M2
  drivers/perf: apple_m1: Map a few more PMUv3 events
  KVM: arm64: Provide 1 event counter on IMPDEF hardware
  KVM: arm64: selftests: Add test for probing PMUv3 sysregs

 arch/arm64/include/asm/apple_m1_pmu.h         |   1 +
 arch/arm64/include/asm/cpufeature.h           |  28 +---
 arch/arm64/kernel/cpu_errata.c                |  38 +++++
 arch/arm64/kernel/cpufeature.c                |  19 +++
 arch/arm64/kernel/image-vars.h                |   5 -
 arch/arm64/kvm/arm.c                          |   4 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h       |   4 +-
 arch/arm64/kvm/hyp/vhe/switch.c               |  22 +++
 arch/arm64/kvm/pmu-emul.c                     | 127 +++++++++++-----
 arch/arm64/kvm/pmu.c                          |  10 +-
 arch/arm64/tools/cpucaps                      |   2 +
 drivers/perf/apple_m1_cpu_pmu.c               | 103 ++++++++++---
 include/kvm/arm_pmu.h                         |  15 +-
 include/linux/perf/arm_pmu.h                  |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/aarch64/pmuv3_register_probe.c        | 135 ++++++++++++++++++
 16 files changed, 407 insertions(+), 108 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/aarch64/pmuv3_register_probe.c


base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:31 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:31 -0800
Subject: [PATCH 01/18] drivers/perf: apple_m1: Refactor event select/filter configuration
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-2-oliver.upton@linux.dev>

Supporting guest mode events will necessitate programming two event
filters. Prepare by splitting up the programming of the event selector +
event filter into separate headers.

Opportunistically replace RMW patterns with sysreg_clear_set_s().

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/include/asm/apple_m1_pmu.h |  1 +
 drivers/perf/apple_m1_cpu_pmu.c       | 52 ++++++++++++++++-----------
 2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/apple_m1_pmu.h b/arch/arm64/include/asm/apple_m1_pmu.h
index 99483b19b99f..02e05d05851f 100644
--- a/arch/arm64/include/asm/apple_m1_pmu.h
+++ b/arch/arm64/include/asm/apple_m1_pmu.h
@@ -37,6 +37,7 @@
 #define PMCR0_PMI_ENABLE_8_9	GENMASK(45, 44)
 
 #define SYS_IMP_APL_PMCR1_EL1	sys_reg(3, 1, 15, 1, 0)
+#define SYS_IMP_APL_PMCR1_EL12	sys_reg(3, 1, 15, 7, 2)
 #define PMCR1_COUNT_A64_EL0_0_7	GENMASK(15, 8)
 #define PMCR1_COUNT_A64_EL1_0_7	GENMASK(23, 16)
 #define PMCR1_COUNT_A64_EL0_8_9	GENMASK(41, 40)
diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index 1d4d01e1275e..ecc71f6808dd 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -325,11 +325,10 @@ static void m1_pmu_disable_counter_interrupt(unsigned int index)
 	__m1_pmu_enable_counter_interrupt(index, false);
 }
 
-static void m1_pmu_configure_counter(unsigned int index, u8 event,
-				     bool user, bool kernel)
+static void __m1_pmu_configure_event_filter(unsigned int index, bool user,
+					    bool kernel)
 {
-	u64 val, user_bit, kernel_bit;
-	int shift;
+	u64 clear, set, user_bit, kernel_bit;
 
 	switch (index) {
 	case 0 ... 7:
@@ -344,19 +343,24 @@ static void m1_pmu_configure_counter(unsigned int index, u8 event,
 		BUG();
 	}
 
-	val = read_sysreg_s(SYS_IMP_APL_PMCR1_EL1);
-
+	clear = set = 0;
 	if (user)
-		val |= user_bit;
+		set |= user_bit;
 	else
-		val &= ~user_bit;
+		clear |= user_bit;
 
 	if (kernel)
-		val |= kernel_bit;
+		set |= kernel_bit;
 	else
-		val &= ~kernel_bit;
+		clear |= kernel_bit;
 
-	write_sysreg_s(val, SYS_IMP_APL_PMCR1_EL1);
+	sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL1, clear, set);
+}
+
+static void __m1_pmu_configure_eventsel(unsigned int index, u8 event)
+{
+	u64 clear = 0, set = 0;
+	int shift;
 
 	/*
 	 * Counters 0 and 1 have fixed events. For anything else,
@@ -369,21 +373,29 @@ static void m1_pmu_configure_counter(unsigned int index, u8 event,
 		break;
 	case 2 ... 5:
 		shift = (index - 2) * 8;
-		val = read_sysreg_s(SYS_IMP_APL_PMESR0_EL1);
-		val &= ~((u64)0xff << shift);
-		val |= (u64)event << shift;
-		write_sysreg_s(val, SYS_IMP_APL_PMESR0_EL1);
+		clear |= (u64)0xff << shift;
+		set |= (u64)event << shift;
+		sysreg_clear_set_s(SYS_IMP_APL_PMESR0_EL1, clear, set);
 		break;
 	case 6 ... 9:
 		shift = (index - 6) * 8;
-		val = read_sysreg_s(SYS_IMP_APL_PMESR1_EL1);
-		val &= ~((u64)0xff << shift);
-		val |= (u64)event << shift;
-		write_sysreg_s(val, SYS_IMP_APL_PMESR1_EL1);
+		clear |= (u64)0xff << shift;
+		set |= (u64)event << shift;
+		sysreg_clear_set_s(SYS_IMP_APL_PMESR1_EL1, clear, set);
 		break;
 	}
 }
 
+static void m1_pmu_configure_counter(unsigned int index, unsigned long config_base)
+{
+	bool kernel = config_base & M1_PMU_CFG_COUNT_KERNEL;
+	bool user = config_base & M1_PMU_CFG_COUNT_USER;
+	u8 evt = config_base & M1_PMU_CFG_EVENT;
+
+	__m1_pmu_configure_event_filter(index, user, kernel);
+	__m1_pmu_configure_eventsel(index, evt);
+}
+
 /* arm_pmu backend */
 static void m1_pmu_enable_event(struct perf_event *event)
 {
@@ -398,7 +410,7 @@ static void m1_pmu_enable_event(struct perf_event *event)
 	m1_pmu_disable_counter(event->hw.idx);
 	isb();
 
-	m1_pmu_configure_counter(event->hw.idx, evt, user, kernel);
+	m1_pmu_configure_counter(event->hw.idx, event->hw.config_base);
 	m1_pmu_enable_counter(event->hw.idx);
 	m1_pmu_enable_counter_interrupt(event->hw.idx);
 	isb();
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:32 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:32 -0800
Subject: [PATCH 02/18] drivers/perf: apple_m1: Support host/guest event filtering
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-3-oliver.upton@linux.dev>

The PMU appears to have a separate register for filtering 'guest'
exception levels (i.e. EL1 and !ELIsInHost(EL0)) which has the same
layout as PMCR1_EL1. Conveniently, there exists a VHE register alias
(PMCR1_EL12) that can be used to configure it.

Support guest events by programming the EL12 register with the intended
guest kernel/userspace filters. Limit support for guest events to VHE
(i.e. kernel running at EL2), as it avoids involving KVM to context
switch PMU registers. VHE is the only supported mode on M* parts anyway,
so this isn't an actual feature limitation.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 drivers/perf/apple_m1_cpu_pmu.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index ecc71f6808dd..2a34523500f8 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -120,6 +120,8 @@ enum m1_pmu_events {
 	 */
 	M1_PMU_CFG_COUNT_USER					= BIT(8),
 	M1_PMU_CFG_COUNT_KERNEL					= BIT(9),
+	M1_PMU_CFG_COUNT_HOST					= BIT(10),
+	M1_PMU_CFG_COUNT_GUEST					= BIT(11),
 };
 
 /*
@@ -326,7 +328,7 @@ static void m1_pmu_disable_counter_interrupt(unsigned int index)
 }
 
 static void __m1_pmu_configure_event_filter(unsigned int index, bool user,
-					    bool kernel)
+					    bool kernel, bool host)
 {
 	u64 clear, set, user_bit, kernel_bit;
 
@@ -354,7 +356,10 @@ static void __m1_pmu_configure_event_filter(unsigned int index, bool user,
 	else
 		clear |= kernel_bit;
 
-	sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL1, clear, set);
+	if (host)
+		sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL1, clear, set);
+	else if (is_kernel_in_hyp_mode())
+		sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL12, clear, set);
 }
 
 static void __m1_pmu_configure_eventsel(unsigned int index, u8 event)
@@ -389,10 +394,13 @@ static void __m1_pmu_configure_eventsel(unsigned int index, u8 event)
 static void m1_pmu_configure_counter(unsigned int index, unsigned long config_base)
 {
 	bool kernel = config_base & M1_PMU_CFG_COUNT_KERNEL;
+	bool guest = config_base & M1_PMU_CFG_COUNT_GUEST;
+	bool host = config_base & M1_PMU_CFG_COUNT_HOST;
 	bool user = config_base & M1_PMU_CFG_COUNT_USER;
 	u8 evt = config_base & M1_PMU_CFG_EVENT;
 
-	__m1_pmu_configure_event_filter(index, user, kernel);
+	__m1_pmu_configure_event_filter(index, user && host, kernel && host, true);
+	__m1_pmu_configure_event_filter(index, user && guest, kernel && guest, false);
 	__m1_pmu_configure_eventsel(index, evt);
 }
 
@@ -568,7 +576,7 @@ static int m1_pmu_set_event_filter(struct hw_perf_event *event,
 {
 	unsigned long config_base = 0;
 
-	if (!attr->exclude_guest) {
+	if (!attr->exclude_guest && !is_kernel_in_hyp_mode()) {
 		pr_debug("ARM performance counters do not support mode exclusion\n");
 		return -EOPNOTSUPP;
 	}
@@ -576,6 +584,10 @@ static int m1_pmu_set_event_filter(struct hw_perf_event *event,
 		config_base |= M1_PMU_CFG_COUNT_KERNEL;
 	if (!attr->exclude_user)
 		config_base |= M1_PMU_CFG_COUNT_USER;
+	if (!attr->exclude_host)
+		config_base |= M1_PMU_CFG_COUNT_HOST;
+	if (!attr->exclude_guest)
+		config_base |= M1_PMU_CFG_COUNT_GUEST;
 
 	event->config_base = config_base;
 
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:36 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:36 -0800
Subject: [PATCH 06/18] KVM: arm64: Always support SW_INCR PMU event
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-7-oliver.upton@linux.dev>

Support for SW_INCR is unconditional, as KVM traps accesses to
PMSWINC_EL0 and emulates the intended event increment. While it is
expected that ~all PMUv3 implementations already advertise this event,
non-PMUv3 hardware may not.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 809d65b912e8..7f20da32266e 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -875,6 +875,8 @@ static u64 compute_pmceid0(struct arm_pmu *pmu)
 {
 	u64 val = __compute_pmceid(pmu, 0);
 
+	/* always support SW_INCR */
+	val |= BIT(ARMV8_PMUV3_PERFCTR_SW_INCR);
 	/* always support CHAIN */
 	val |= BIT(ARMV8_PMUV3_PERFCTR_CHAIN);
 	return val;
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:42 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:42 -0800
Subject: [PATCH 12/18] KVM: arm64: Compute synthetic sysreg ESR for Apple PMUv3 traps
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-13-oliver.upton@linux.dev>

Apple M* CPUs provide an IMPDEF trap for PMUv3 sysregs, where ESR_EL2.EC
is a reserved value (0x3F) and a sysreg-like ISS is reported in
AFSR1_EL2.

Compute a synthetic ESR for these PMUv3 traps, giving the illusion of
something architectural to the rest of KVM.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 22 ++++++++++++++++++++++
 arch/arm64/tools/cpucaps        |  1 +
 2 files changed, 23 insertions(+)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 80581b1c3995..da2ccaefaf6f 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -418,6 +418,25 @@ static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return kvm_hyp_handle_sysreg(vcpu, exit_code);
 }
 
+static bool kvm_hyp_handle_impdef(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	u64 iss;
+
+	if (!cpus_have_final_cap(ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS))
+		return false;
+
+	/*
+	 * Compute a synthetic ESR for a sysreg trap. Conveniently, AFSR1_EL2
+	 * is populated with a correct ISS for a sysreg trap. These fruity
+	 * parts are 64bit only, so unconditionally set IL.
+	 */
+	iss = ESR_ELx_ISS(read_sysreg_s(SYS_AFSR1_EL2));
+	vcpu->arch.fault.esr_el2 = FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SYS64) |
+				   FIELD_PREP(ESR_ELx_ISS_MASK, iss) |
+				   ESR_ELx_IL;
+	return false;
+}
+
 static const exit_handler_fn hyp_exit_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= NULL,
 	[ESR_ELx_EC_CP15_32]		= kvm_hyp_handle_cp15_32,
@@ -429,6 +448,9 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[ESR_ELx_EC_WATCHPT_LOW]	= kvm_hyp_handle_watchpt_low,
 	[ESR_ELx_EC_ERET]		= kvm_hyp_handle_eret,
 	[ESR_ELx_EC_MOPS]		= kvm_hyp_handle_mops,
+
+	/* Apple shenanigans */
+	[0x3F]				= kvm_hyp_handle_impdef,
 };
 
 static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b291eb73f5e0..a9c7111b831e 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -105,6 +105,7 @@ WORKAROUND_CAVIUM_TX2_219_TVM
 WORKAROUND_CLEAN_CACHE
 WORKAROUND_DEVICE_LOAD_ACQUIRE
 WORKAROUND_NVIDIA_CARMEL_CNP
+WORKAROUND_PMUV3_IMPDEF_TRAPS
 WORKAROUND_QCOM_FALKOR_E1003
 WORKAROUND_REPEAT_TLBI
 WORKAROUND_SPECULATIVE_AT
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:43 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:43 -0800
Subject: [PATCH 13/18] KVM: arm64: Advertise PMUv3 if IMPDEF traps are present
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-14-oliver.upton@linux.dev>

Advertise a baseline PMUv3 implementation when running on hardware with
IMPDEF traps of the PMUv3 sysregs.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 98690e53dc73..553d02a03877 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -1262,7 +1262,17 @@ u8 kvm_arm_pmu_get_pmuver_limit(void)
 	pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer,
 			       read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1));
 
-	/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
+	/*
+	 * Spoof a barebones PMUv3 implementation if the system supports IMPDEF
+	 * traps of the PMUv3 sysregs
+	 */
+	if (cpus_have_final_cap(ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS))
+		return ID_AA64DFR0_EL1_PMUVer_IMP;
+
+	/*
+	 * Otherwise, treat IMPLEMENTATION DEFINED functionality as
+	 * unimplemented
+	 */
 	if (pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
 		return 0;
 
-- 
2.39.5



From david at ixit.cz  Tue Dec 17 13:22:29 2024
From: david at ixit.cz (David Heidelberg)
Date: Tue, 17 Dec 2024 16:22:29 -0500
Subject: [PATCH 2/2] dt-bindings: media: imx219: Describe sensor address
 using the reg property
In-Reply-To: <6djxfcuroxlth2th3tpuesauhdnowatzgnyhesewjfz32v6gbz@q2dj7jsxiqlw>
References: <20241217024206.1700170-1-david@ixit.cz>
 <20241217024206.1700170-2-david@ixit.cz>
 <6djxfcuroxlth2th3tpuesauhdnowatzgnyhesewjfz32v6gbz@q2dj7jsxiqlw>
Message-ID: <bf619a0e-f470-4bdb-8d09-2cea172bfe8e@ixit.cz>

Oh, the checkpatch script keeps warning me every time I commit?I guess 
it needs to be addressed.

I currently use:

[diff]
   srcprefix = ./
   dstprefix = ./

Originally, my intention was to use:

[diff]
   noprefix = true

This was to make it easier to copy-paste directly into the shell (git 
log -p, etc.). However, it ended up breaking too many applications. 
Setting srcprefix and dstprefix instead keeps everything working properly.

Is there any chance a patch allowing a ./ prefix could make it into 
checkpatch? What do you think, Krzysztof?

Thank you,
David

On 17/12/2024 02:40, Krzysztof Kozlowski wrote:
> On Mon, Dec 16, 2024 at 09:41:51PM -0500, David Heidelberg wrote:
>> Use the reg property instead of text in the description.
>> Drop useless description of reg property.
>>
>> Signed-off-by: David Heidelberg <david at ixit.cz>
>> ---
>>   Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml | 5 ++---
>>   1 file changed, 2 insertions(+), 3 deletions(-)
>>
>> diff --git ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml ./Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml
> 
> You are using non-standard tools to generate patches. See checkpatch
> warnings.
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> Best regards,
> Krzysztof
> 

-- 
David Heidelberg



From oliver.upton at linux.dev  Tue Dec 17 13:22:33 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:22:33 -0800
Subject: [PATCH 14/18] KVM: arm64: Advertise 0 event counters for IMPDEF PMU
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212233.3709321-1-oliver.upton@linux.dev>

The programmable event counters on Apple M* parts are quite different
from what's available in PMUv3, as the event counters aren't fungible
(some events only work on specific counters) and the event ID space
doesn't match the architecture.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 553d02a03877..3803737cbf7c 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -1046,6 +1046,9 @@ u8 kvm_arm_pmu_get_max_counters(struct kvm *kvm)
 {
 	struct arm_pmu *arm_pmu = kvm->arch.arm_pmu;
 
+	if (cpus_have_final_cap(ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS))
+		return 0;
+
 	/*
 	 * The arm_pmu->cntr_mask considers the fixed counter(s) as well.
 	 * Ignore those and return only the general-purpose counters.
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:22:55 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:22:55 -0800
Subject: [PATCH 15/18] arm64: Enable IMP DEF PMUv3 traps on Apple M2
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212255.3709400-1-oliver.upton@linux.dev>

Apple M2 CPUs support IMPDEF traps of the PMUv3 sysregs, allowing a
hypervisor to virtualize an architectural PMU for a VM. Flip the
appropriate bit in HACR_EL2 on supporting hardware.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kernel/cpu_errata.c | 38 ++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index a78f247029ae..441ee4ffc770 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -194,6 +194,37 @@ has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
 	return is_midr_in_range(midr, &range) && has_dic;
 }
 
+static const struct midr_range impdef_pmuv3_cpus[] = {
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_PRO),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_PRO),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_MAX),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_MAX),
+	{},
+};
+
+static bool has_impdef_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
+	unsigned int pmuver;
+
+	if (!is_kernel_in_hyp_mode())
+		return false;
+
+	pmuver = cpuid_feature_extract_unsigned_field(dfr0,
+						      ID_AA64DFR0_EL1_PMUVer_SHIFT);
+	if (pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
+		return false;
+
+	return is_midr_in_range_list(read_cpuid_id(), impdef_pmuv3_cpus);
+}
+
+static void cpu_enable_impdef_pmuv3_traps(const struct arm64_cpu_capabilities *__unused)
+{
+	sysreg_clear_set_s(SYS_HACR_EL2, 0, BIT(56));
+}
+
 #ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
 static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
 #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009
@@ -786,6 +817,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_RANGE_LIST(erratum_ac03_cpu_38_list),
 	},
 #endif
+	{
+		.desc = "Apple IMPDEF PMUv3 Traps",
+		.capability = ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS,
+		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+		.matches = has_impdef_pmuv3,
+		.cpu_enable = cpu_enable_impdef_pmuv3_traps,
+	},
 	{
 	}
 };
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:23:17 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:23:17 -0800
Subject: [RFC PATCH 16/18] drivers/perf: apple_m1: Map a few more PMUv3 events
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212317.3709478-1-oliver.upton@linux.dev>

Map some more PMUv3 events onto hardware so 'perf stat' in a KVM VM can
show some useful information (e.g. IPC, branch prediction rate).

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 drivers/perf/apple_m1_cpu_pmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index b4fe247543a6..0e54d3f900a7 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -180,7 +180,10 @@ static const unsigned m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
 
 static const unsigned int m1_pmu_pmceid_map[ARMV8_PMUV3_MAX_COMMON_EVENTS] = {
 	[0 ... ARMV8_PMUV3_MAX_COMMON_EVENTS - 1]	= HW_OP_UNSUPPORTED,
+	M1_PMUV3_EVENT_MAP(INST_RETIRED,	INST_ALL),
 	M1_PMUV3_EVENT_MAP(CPU_CYCLES,		CORE_ACTIVE_CYCLE),
+	M1_PMUV3_EVENT_MAP(BR_RETIRED,		INST_BRANCH),
+	M1_PMUV3_EVENT_MAP(BR_MIS_PRED_RETIRED,	BRANCH_MISPRED_NONSPEC),
 };
 
 /* sysfs definitions */
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:23:38 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:23:38 -0800
Subject: [RFC PATCH 17/18] KVM: arm64: Provide 1 event counter on IMPDEF hardware
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212338.3709556-1-oliver.upton@linux.dev>

PMUv3 requires that all programmable event counters are capable of
counting any event. The Apple M* PMU is quite a bit different, and
events have affinities for particular PMCs.

Expose 1 event counter on IMPDEF hardware, allowing the guest to do
something useful with its PMU while also upholding the requirements of
the architecture.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---

Jury is still out on whether we want to do this, which is why this patch
is RFC.

 arch/arm64/kvm/pmu-emul.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 3803737cbf7c..8f96a34d3da5 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -1046,8 +1046,12 @@ u8 kvm_arm_pmu_get_max_counters(struct kvm *kvm)
 {
 	struct arm_pmu *arm_pmu = kvm->arch.arm_pmu;
 
+	/*
+	 * PMUv3 requires that all event counters are capable of counting any
+	 * event, though the same may not be true of non-PMUv3 hardware.
+	 */
 	if (cpus_have_final_cap(ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS))
-		return 0;
+		return 1;
 
 	/*
 	 * The arm_pmu->cntr_mask considers the fixed counter(s) as well.
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:23:58 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:23:58 -0800
Subject: [HACK PATCH 18/18] KVM: arm64: selftests: Add test for probing PMUv3 sysregs
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212358.3709634-1-oliver.upton@linux.dev>

Add a test for sniffing out PMUv3 register traps.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---

Not intended to be applied, just sharing in case someone finds it
useful.

 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/aarch64/pmuv3_register_probe.c        | 135 ++++++++++++++++++
 2 files changed, 136 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/aarch64/pmuv3_register_probe.c

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 41593d2e7de9..739542928306 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -159,6 +159,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
 TEST_GEN_PROGS_aarch64 += aarch64/mmio_abort
 TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
+TEST_GEN_PROGS_aarch64 += aarch64/pmuv3_register_probe
 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/pmuv3_register_probe.c b/tools/testing/selftests/kvm/aarch64/pmuv3_register_probe.c
new file mode 100644
index 000000000000..859b0162dbeb
--- /dev/null
+++ b/tools/testing/selftests/kvm/aarch64/pmuv3_register_probe.c
@@ -0,0 +1,135 @@
+#include <perf/arm_pmuv3.h>
+
+#include "vgic.h"
+#include "test_util.h"
+#include "processor.h"
+
+static bool undef_taken;
+
+#define test_read(sr)							\
+do {									\
+	u64 __val = read_sysreg(sr);					\
+									\
+	if (READ_ONCE(undef_taken))					\
+		GUEST_PRINTF("read_sysreg("#sr"): UNDEFINED\n");	\
+	else								\
+		GUEST_PRINTF("read_sysreg("#sr"): %lx\n", __val);	\
+	WRITE_ONCE(undef_taken, false);					\
+} while (0)
+
+#define test_write(val, sr)							\
+do {										\
+	write_sysreg(val, sr);							\
+										\
+	if (READ_ONCE(undef_taken))						\
+		GUEST_PRINTF("write_sysreg(%x, "#sr"): UNDEFINED\n", val);	\
+	else									\
+		GUEST_PRINTF("write_sysreg(%x, "#sr"): OK\n", val);		\
+	WRITE_ONCE(undef_taken, false);						\
+} while (0)
+
+static void guest_undef_handler(struct ex_regs *regs)
+{
+	WRITE_ONCE(undef_taken, true);
+	regs->pc += 4;
+}
+
+#define READ_PMEVCNTRN(n)	test_read(pmevcntr##n##_el0)
+static void test_read_evcntr(int n)
+{
+	PMEVN_SWITCH(n, READ_PMEVCNTRN);
+}
+
+#define READ_PMEVTYPERN(n)	test_read(pmevtyper##n##_el0);
+static void test_read_evtyper(int n)
+{
+	PMEVN_SWITCH(n, READ_PMEVTYPERN);
+}
+
+static void guest_code(void)
+{
+	test_read(pmcr_el0);
+	test_read(pmcntenset_el0);
+	test_read(pmcntenclr_el0);
+	test_read(pmovsset_el0);
+	test_read(pmovsclr_el0);
+	test_read(pmintenset_el1);
+	test_read(pmintenclr_el1);
+	test_read(pmceid0_el0);
+	test_read(pmceid1_el0);
+
+	test_read(pmccntr_el0);
+	test_read(pmccfiltr_el0);
+	test_write(0, pmswinc_el0);
+
+	test_write(0, pmselr_el0);
+	test_read(pmxevcntr_el0);
+	test_read(pmxevtyper_el0);
+
+	test_read(pmuserenr_el0);
+
+	for (int i = 0; i < 31; i++) {
+		test_read_evcntr(i);
+		test_read_evtyper(i);
+	}
+
+	GUEST_DONE();
+}
+
+static void run_test(struct kvm_vcpu *vcpu)
+{
+	struct ucall uc;
+
+	while (true) {
+		vcpu_run(vcpu);
+
+		switch (get_ucall(vcpu, &uc)) {
+		case UCALL_PRINTF:
+			REPORT_GUEST_PRINTF(uc);
+			break;
+		case UCALL_DONE:
+			return;
+		default:
+			TEST_FAIL("Unknown ucall %lu", uc.cmd);
+		}
+	}
+}
+
+int main(void)
+{
+	struct kvm_device_attr attr;
+	struct kvm_vcpu_init init;
+	struct kvm_vcpu *vcpu;
+	struct kvm_vm *vm;
+	int irq = 23;
+
+	TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_PMU_V3));
+
+	vm = vm_create(1);
+	vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init);
+	init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
+	vcpu = aarch64_vcpu_add(vm, 0, &init, guest_code);
+
+	__TEST_REQUIRE(vgic_v3_setup(vm, 1, 64) >= 0,
+		       "Failed to create vgic-v3, skipping");
+
+	vm_init_descriptor_tables(vm);
+	vcpu_init_descriptor_tables(vcpu);
+	vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT, ESR_ELx_EC_UNKNOWN,
+				guest_undef_handler);
+
+	attr = (struct kvm_device_attr) {
+		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
+		.attr	= KVM_ARM_VCPU_PMU_V3_IRQ,
+		.addr	= (u64)&irq,
+	};
+	vcpu_ioctl(vcpu, KVM_SET_DEVICE_ATTR, &attr);
+
+	attr = (struct kvm_device_attr) {
+		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
+		.attr	= KVM_ARM_VCPU_PMU_V3_INIT,
+	};
+	vcpu_ioctl(vcpu, KVM_SET_DEVICE_ATTR, &attr);
+
+	run_test(vcpu);
+}
-- 
2.39.5



From cristian.ciocaltea at collabora.com  Tue Dec 17 13:41:50 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 17 Dec 2024 23:41:50 +0200
Subject: [PATCH v5 0/3] Provide devm_clk_bulk_get_all_enabled() helper
Message-ID: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>

Commit 265b07df758a ("clk: Provide managed helper to get and enable bulk
clocks") added devm_clk_bulk_get_all_enable() function, but missed to
return the number of clocks stored in the clk_bulk_data table referenced
by the clks argument.

That is required in case there is a need to iterate these clocks later,
therefore I couldn't see any use case of this parameter and should have
been simply removed from the function declaration.

The first patch in the series provides devm_clk_bulk_get_all_enabled()
variant, which is consistent with devm_clk_bulk_get_all() in terms of
the returned value:

 > 0 if one or more clocks have been stored
 = 0 if there are no clocks
 < 0 if an error occurred

Moreover, the naming is consistent with devm_clk_get_enabled(), i.e. use
the past form of 'enable'.

The next two patches switch existing users of devm_clk_get_enable() to
the new helper - there were only two, as of next-20240913.

The last patch drops the now obsolete devm_clk_bulk_get_all_enable()
helper.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
Changes in v5:
- Rebased series onto next-20241217
- Removed the patch introducing the new helper - merged in v6.13-rc1
- Updated last patch to fix a rebase conflict
- Link to v4: https://lore.kernel.org/r/20241019-clk_bulk_ena_fix-v4-0-57f108f64e70 at collabora.com

Changes in v4:
- Dropped usage of gotos in the new helper implementation to further
  minimize the diff (Stephen)
- Link to v3: https://lore.kernel.org/r/20241018-clk_bulk_ena_fix-v3-0-57e8bb82460c at collabora.com

Changes in v3:
- Made devm_clk_bulk_get_all_enable() use the new helper, as suggested
  by Stephen to improve diff readability
- Rebased series onto next-20241017
- Link to v2: https://lore.kernel.org/r/20240926-clk_bulk_ena_fix-v2-0-9c767510fbb5 at collabora.com

Changes in v2:
- Dropped references to 'broken' API in commit descriptions, per Mani's
  suggestion
- Added R-b tags from Angelo and Mani
- Link to v1: https://lore.kernel.org/r/20240914-clk_bulk_ena_fix-v1-0-ce3537585c06 at collabora.com

---
Cristian Ciocaltea (3):
      soc: mediatek: pwrap: Switch to devm_clk_bulk_get_all_enabled()
      PCI: exynos: Switch to devm_clk_bulk_get_all_enabled()
      clk: Drop obsolete devm_clk_bulk_get_all_enable() helper

 drivers/pci/controller/dwc/pci-exynos.c | 2 +-
 drivers/soc/mediatek/mtk-pmic-wrap.c    | 4 ++--
 include/linux/clk.h                     | 9 ---------
 3 files changed, 3 insertions(+), 12 deletions(-)
---
base-commit: fdb298fa865b0136f7be842e6c2e6310dede421a
change-id: 20240912-clk_bulk_ena_fix-16ba77358ddf



From cristian.ciocaltea at collabora.com  Tue Dec 17 13:41:51 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 17 Dec 2024 23:41:51 +0200
Subject: [PATCH v5 1/3] soc: mediatek: pwrap: Switch to
 devm_clk_bulk_get_all_enabled()
In-Reply-To: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>
References: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>
Message-ID: <20241217-clk_bulk_ena_fix-v5-1-aafbbb245155@collabora.com>

The helper devm_clk_bulk_get_all_enable() missed to return the number of
clocks stored in the clk_bulk_data table referenced by the clks
argument and, therefore, will be dropped.

Use the newly introduced devm_clk_bulk_get_all_enabled() variant
instead, which is consistent with devm_clk_bulk_get_all() in terms of
the returned value:

 > 0 if one or more clocks have been stored
 = 0 if there are no clocks
 < 0 if an error occurred

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/soc/mediatek/mtk-pmic-wrap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
index 9fdc0ef79202618d0bd0188d0bf53152285c6c51..0bcd8582637550c90c1c6df619077b7df7bb0048 100644
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
@@ -2518,8 +2518,8 @@ static int pwrap_probe(struct platform_device *pdev)
 		}
 	}
 
-	ret = devm_clk_bulk_get_all_enable(wrp->dev, &clk);
-	if (ret)
+	ret = devm_clk_bulk_get_all_enabled(wrp->dev, &clk);
+	if (ret < 0)
 		return dev_err_probe(wrp->dev, ret,
 				     "failed to get clocks\n");
 

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Tue Dec 17 13:41:52 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 17 Dec 2024 23:41:52 +0200
Subject: [PATCH v5 2/3] PCI: exynos: Switch to
 devm_clk_bulk_get_all_enabled()
In-Reply-To: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>
References: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>
Message-ID: <20241217-clk_bulk_ena_fix-v5-2-aafbbb245155@collabora.com>

The helper devm_clk_bulk_get_all_enable() missed to return the number of
clocks stored in the clk_bulk_data table referenced by the clks
argument and, therefore, will be dropped.

Use the newly introduced devm_clk_bulk_get_all_enabled() variant
instead, which is consistent with devm_clk_bulk_get_all() in terms of
the returned value:

 > 0 if one or more clocks have been stored
 = 0 if there are no clocks
 < 0 if an error occurred

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/pci/controller/dwc/pci-exynos.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index 6a830166d37fff5bbbc35aaa7cc1b67b03e6ec3b..ace736b025b1b7d4cdcbd51d2e9d99af29f21149 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -300,7 +300,7 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 	if (IS_ERR(ep->elbi_base))
 		return PTR_ERR(ep->elbi_base);
 
-	ret = devm_clk_bulk_get_all_enable(dev, &ep->clks);
+	ret = devm_clk_bulk_get_all_enabled(dev, &ep->clks);
 	if (ret < 0)
 		return ret;
 

-- 
2.47.0



From cristian.ciocaltea at collabora.com  Tue Dec 17 13:41:53 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 17 Dec 2024 23:41:53 +0200
Subject: [PATCH v5 3/3] clk: Drop obsolete devm_clk_bulk_get_all_enable()
 helper
In-Reply-To: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>
References: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>
Message-ID: <20241217-clk_bulk_ena_fix-v5-3-aafbbb245155@collabora.com>

Commit 265b07df758a ("clk: Provide managed helper to get and enable bulk
clocks") added devm_clk_bulk_get_all_enable() function, but missed to
return the number of clocks stored in the clk_bulk_data table referenced
by the clks argument.  Without knowing the number, it's not possible to
iterate these clocks when needed, hence the argument is useless and
could have been simply removed.

A new helper devm_clk_bulk_get_all_enabled() has been introduced, which
is consistent with devm_clk_bulk_get_all() in terms of the returned
value.

Drop the obsolete function since all users switched to the new helper.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 include/linux/clk.h | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1dcee6d701e439f35effd86ca3ee3b47a9839bd0..b607482ca77e987b9344c38f25ebb5c8d35c1d39 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -1138,15 +1138,6 @@ static inline void clk_restore_context(void) {}
 
 #endif
 
-/* Deprecated. Use devm_clk_bulk_get_all_enabled() */
-static inline int __must_check
-devm_clk_bulk_get_all_enable(struct device *dev, struct clk_bulk_data **clks)
-{
-	int ret = devm_clk_bulk_get_all_enabled(dev, clks);
-
-	return ret > 0 ? 0 : ret;
-}
-
 /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
 static inline int clk_prepare_enable(struct clk *clk)
 {

-- 
2.47.0



From oliver.upton at linux.dev  Tue Dec 17 13:20:37 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:37 -0800
Subject: [PATCH 07/18] KVM: arm64: Remap PMUv3 events onto hardware
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-8-oliver.upton@linux.dev>

Use the provided helper to map PMUv3 event IDs onto hardware, if the
driver exposes such a helper. This is expected to be quite rare, and
only useful for non-PMUv3 hardware.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 7f20da32266e..6d7fc0051ad8 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -692,6 +692,18 @@ static bool kvm_pmc_counts_at_el2(struct kvm_pmc *pmc)
 	return kvm_pmc_read_evtreg(pmc) & ARMV8_PMU_INCLUDE_EL2;
 }
 
+static u64 kvm_map_pmu_event(struct kvm *kvm, u64 eventsel)
+{
+	struct arm_pmu *pmu = kvm->arch.arm_pmu;
+	int hw_event;
+
+	if (!pmu->map_pmuv3_event)
+		return eventsel;
+
+	hw_event = pmu->map_pmuv3_event(eventsel);
+	return (hw_event < 0) ? eventsel : hw_event;
+}
+
 /**
  * kvm_pmu_create_perf_event - create a perf event for a counter
  * @pmc: Counter context
@@ -730,13 +742,13 @@ static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc)
 
 	memset(&attr, 0, sizeof(struct perf_event_attr));
 	attr.type = arm_pmu->pmu.type;
+	attr.config = kvm_map_pmu_event(vcpu->kvm, eventsel);
 	attr.size = sizeof(attr);
 	attr.pinned = 1;
 	attr.disabled = !kvm_pmu_counter_is_enabled(pmc);
 	attr.exclude_user = !kvm_pmc_counts_at_el0(pmc);
 	attr.exclude_hv = 1; /* Don't count EL2 events */
 	attr.exclude_host = 1; /* Don't count host events */
-	attr.config = eventsel;
 
 	/*
 	 * Filter events at EL1 (i.e. vEL2) when in a hyp context based on the
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:38 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:38 -0800
Subject: [PATCH 08/18] KVM: arm64: Use a cpucap to determine if system supports FEAT_PMUv3
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-9-oliver.upton@linux.dev>

KVM is about to learn some new tricks to virtualize PMUv3 on IMPDEF
hardware. As part of that, we now need to differentiate host support
from guest support for PMUv3.

Add a cpucap to determine if an architectural PMUv3 is present to guard
host usage of PMUv3 controls.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/include/asm/cpufeature.h     |  5 +++++
 arch/arm64/kernel/cpufeature.c          | 19 +++++++++++++++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 ++--
 arch/arm64/kvm/pmu.c                    | 10 +++++-----
 arch/arm64/tools/cpucaps                |  1 +
 include/kvm/arm_pmu.h                   |  2 +-
 6 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 8b4e5a3cd24c..6a989927926a 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -866,6 +866,11 @@ static __always_inline bool system_supports_mpam_hcr(void)
 	return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
 }
 
+static inline bool system_supports_pmuv3(void)
+{
+	return cpus_have_final_cap(ARM64_HAS_PMUV3);
+}
+
 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 6ce71f444ed8..fa73fbdd8617 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1889,6 +1889,19 @@ static bool has_lpa2(const struct arm64_cpu_capabilities *entry, int scope)
 }
 #endif
 
+static bool has_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
+	unsigned int pmuver;
+
+	pmuver = cpuid_feature_extract_unsigned_field(dfr0,
+						      ID_AA64DFR0_EL1_PMUVer_SHIFT);
+	if (pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
+		return false;
+
+	return pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP;
+}
+
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 #define KPTI_NG_TEMP_VA		(-(1UL << PMD_SHIFT))
 
@@ -2990,6 +3003,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, GCS, IMP)
 	},
 #endif
+	{
+		.desc = "PMUv3",
+		.capability = ARM64_HAS_PMUV3,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_pmuv3,
+	},
 	{},
 };
 
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 34f53707892d..995aca419b1e 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -244,7 +244,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
 	 * counter, which could make a PMXEVCNTR_EL0 access UNDEF at
 	 * EL1 instead of being trapped to EL2.
 	 */
-	if (kvm_arm_support_pmu_v3()) {
+	if (system_supports_pmuv3()) {
 		struct kvm_cpu_context *hctxt;
 
 		write_sysreg(0, pmselr_el0);
@@ -281,7 +281,7 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
 	write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);
 
 	write_sysreg(0, hstr_el2);
-	if (kvm_arm_support_pmu_v3()) {
+	if (system_supports_pmuv3()) {
 		struct kvm_cpu_context *hctxt;
 
 		hctxt = host_data_ptr(host_ctxt);
diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c
index 0b3adf3e17b4..6b48a3d16d0d 100644
--- a/arch/arm64/kvm/pmu.c
+++ b/arch/arm64/kvm/pmu.c
@@ -41,7 +41,7 @@ void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr)
 {
 	struct kvm_pmu_events *pmu = kvm_get_pmu_events();
 
-	if (!kvm_arm_support_pmu_v3() || !kvm_pmu_switch_needed(attr))
+	if (!system_supports_pmuv3() || !kvm_pmu_switch_needed(attr))
 		return;
 
 	if (!attr->exclude_host)
@@ -57,7 +57,7 @@ void kvm_clr_pmu_events(u64 clr)
 {
 	struct kvm_pmu_events *pmu = kvm_get_pmu_events();
 
-	if (!kvm_arm_support_pmu_v3())
+	if (!system_supports_pmuv3())
 		return;
 
 	pmu->events_host &= ~clr;
@@ -133,7 +133,7 @@ void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu)
 	struct kvm_pmu_events *pmu;
 	u64 events_guest, events_host;
 
-	if (!kvm_arm_support_pmu_v3() || !has_vhe())
+	if (!system_supports_pmuv3() || !has_vhe())
 		return;
 
 	preempt_disable();
@@ -154,7 +154,7 @@ void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu)
 	struct kvm_pmu_events *pmu;
 	u64 events_guest, events_host;
 
-	if (!kvm_arm_support_pmu_v3() || !has_vhe())
+	if (!system_supports_pmuv3() || !has_vhe())
 		return;
 
 	pmu = kvm_get_pmu_events();
@@ -180,7 +180,7 @@ bool kvm_set_pmuserenr(u64 val)
 	struct kvm_cpu_context *hctxt;
 	struct kvm_vcpu *vcpu;
 
-	if (!kvm_arm_support_pmu_v3() || !has_vhe())
+	if (!system_supports_pmuv3() || !has_vhe())
 		return false;
 
 	vcpu = kvm_get_running_vcpu();
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index eb17f59e543c..b291eb73f5e0 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -45,6 +45,7 @@ HAS_LSE_ATOMICS
 HAS_MOPS
 HAS_NESTED_VIRT
 HAS_PAN
+HAS_PMUV3
 HAS_S1PIE
 HAS_S1POE
 HAS_RAS_EXTN
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index e61dd7dd2286..7ef9eb3cede5 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -87,7 +87,7 @@ void kvm_vcpu_pmu_resync_el0(void);
  */
 #define kvm_pmu_update_vcpu_events(vcpu)				\
 	do {								\
-		if (!has_vhe() && kvm_arm_support_pmu_v3())		\
+		if (!has_vhe() && system_supports_pmuv3())		\
 			vcpu->arch.pmu.events = *kvm_get_pmu_events();	\
 	} while (0)
 
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:39 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:39 -0800
Subject: [PATCH 09/18] KVM: arm64: Drop kvm_arm_pmu_available static key
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-10-oliver.upton@linux.dev>

With the PMUv3 cpucap, kvm_arm_pmu_available is no longer used in the
hot path of guest entry/exit. On top of that, guest support for PMUv3
may not correlate with host support for the feature, e.g. on IMPDEF
hardware.

Throw out the static key and just inspect the list of PMUs to determine
if PMUv3 is supported for KVM guests.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kernel/image-vars.h |  5 -----
 arch/arm64/kvm/arm.c           |  4 ++--
 arch/arm64/kvm/pmu-emul.c      | 11 ++++++-----
 include/kvm/arm_pmu.h          | 13 +------------
 4 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 8f5422ed1b75..5919320bc802 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -109,11 +109,6 @@ KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
 KVM_NVHE_ALIAS(__start___kvm_ex_table);
 KVM_NVHE_ALIAS(__stop___kvm_ex_table);
 
-/* PMU available static key */
-#ifdef CONFIG_HW_PERF_EVENTS
-KVM_NVHE_ALIAS(kvm_arm_pmu_available);
-#endif
-
 /* Position-independent library routines */
 KVM_NVHE_ALIAS_HYP(clear_page, __pi_clear_page);
 KVM_NVHE_ALIAS_HYP(copy_page, __pi_copy_page);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..081e638c674f 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -391,7 +391,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		r = get_num_wrps();
 		break;
 	case KVM_CAP_ARM_PMU_V3:
-		r = kvm_arm_support_pmu_v3();
+		r = kvm_supports_guest_pmuv3();
 		break;
 	case KVM_CAP_ARM_INJECT_SERROR_ESR:
 		r = cpus_have_final_cap(ARM64_HAS_RAS_EXTN);
@@ -1397,7 +1397,7 @@ static unsigned long system_supported_vcpu_features(void)
 	if (!cpus_have_final_cap(ARM64_HAS_32BIT_EL1))
 		clear_bit(KVM_ARM_VCPU_EL1_32BIT, &features);
 
-	if (!kvm_arm_support_pmu_v3())
+	if (!kvm_supports_guest_pmuv3())
 		clear_bit(KVM_ARM_VCPU_PMU_V3, &features);
 
 	if (!system_supports_sve())
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 6d7fc0051ad8..33cd694c754f 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -17,14 +17,18 @@
 
 #define PERF_ATTR_CFG1_COUNTER_64BIT	BIT(0)
 
-DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
-
 static LIST_HEAD(arm_pmus);
 static DEFINE_MUTEX(arm_pmus_lock);
 
 static void kvm_pmu_create_perf_event(struct kvm_pmc *pmc);
 static void kvm_pmu_release_perf_event(struct kvm_pmc *pmc);
 
+bool kvm_supports_guest_pmuv3(void)
+{
+	guard(mutex)(&arm_pmus_lock);
+	return !list_empty(&arm_pmus);
+}
+
 static struct kvm_vcpu *kvm_pmc_to_vcpu(const struct kvm_pmc *pmc)
 {
 	return container_of(pmc, struct kvm_vcpu, arch.pmu.pmc[pmc->idx]);
@@ -826,9 +830,6 @@ void kvm_host_pmu_init(struct arm_pmu *pmu)
 	entry->arm_pmu = pmu;
 	list_add_tail(&entry->entry, &arm_pmus);
 
-	if (list_is_singular(&arm_pmus))
-		static_branch_enable(&kvm_arm_pmu_available);
-
 out_unlock:
 	mutex_unlock(&arm_pmus_lock);
 }
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 7ef9eb3cede5..d3dcf5438315 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -37,13 +37,7 @@ struct arm_pmu_entry {
 	struct arm_pmu *arm_pmu;
 };
 
-DECLARE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
-
-static __always_inline bool kvm_arm_support_pmu_v3(void)
-{
-	return static_branch_likely(&kvm_arm_pmu_available);
-}
-
+bool kvm_supports_guest_pmuv3(void);
 #define kvm_arm_pmu_irq_initialized(v)	((v)->arch.pmu.irq_num >= VGIC_NR_SGIS)
 u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx);
 void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64 select_idx, u64 val);
@@ -103,11 +97,6 @@ void kvm_pmu_nested_transition(struct kvm_vcpu *vcpu);
 struct kvm_pmu {
 };
 
-static inline bool kvm_arm_support_pmu_v3(void)
-{
-	return false;
-}
-
 #define kvm_arm_pmu_irq_initialized(v)	(false)
 static inline u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu,
 					    u64 select_idx)
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:40 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:40 -0800
Subject: [PATCH 10/18] KVM: arm64: Use guard() to cleanup usage of arm_pmus_lock
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-11-oliver.upton@linux.dev>

Get rid of some goto label patterns by using guard() to drop the
arm_pmus_lock when returning from a function.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/kvm/pmu-emul.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 33cd694c754f..2c98cf24bef3 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -821,26 +821,23 @@ void kvm_host_pmu_init(struct arm_pmu *pmu)
 	if (!pmuv3_implemented(kvm_arm_pmu_get_pmuver_limit()))
 		return;
 
-	mutex_lock(&arm_pmus_lock);
+	guard(mutex)(&arm_pmus_lock);
 
 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
 	if (!entry)
-		goto out_unlock;
+		return;
 
 	entry->arm_pmu = pmu;
 	list_add_tail(&entry->entry, &arm_pmus);
-
-out_unlock:
-	mutex_unlock(&arm_pmus_lock);
 }
 
 static struct arm_pmu *kvm_pmu_probe_armpmu(void)
 {
-	struct arm_pmu *tmp, *pmu = NULL;
 	struct arm_pmu_entry *entry;
+	struct arm_pmu *pmu;
 	int cpu;
 
-	mutex_lock(&arm_pmus_lock);
+	guard(mutex)(&arm_pmus_lock);
 
 	/*
 	 * It is safe to use a stale cpu to iterate the list of PMUs so long as
@@ -861,17 +858,13 @@ static struct arm_pmu *kvm_pmu_probe_armpmu(void)
 	 */
 	cpu = raw_smp_processor_id();
 	list_for_each_entry(entry, &arm_pmus, entry) {
-		tmp = entry->arm_pmu;
+		pmu = entry->arm_pmu;
 
-		if (cpumask_test_cpu(cpu, &tmp->supported_cpus)) {
-			pmu = tmp;
-			break;
-		}
+		if (cpumask_test_cpu(cpu, &pmu->supported_cpus))
+			return pmu;
 	}
 
-	mutex_unlock(&arm_pmus_lock);
-
-	return pmu;
+	return NULL;
 }
 
 static u64 __compute_pmceid(struct arm_pmu *pmu, bool pmceid1)
-- 
2.39.5



From oliver.upton at linux.dev  Tue Dec 17 13:20:41 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 17 Dec 2024 13:20:41 -0800
Subject: [PATCH 11/18] KVM: arm64: Move PMUVer filtering into KVM code
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241217212048.3709204-12-oliver.upton@linux.dev>

The supported guest PMU version on a particular platform is ultimately a
KVM decision. Move PMUVer filtering into KVM code.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/include/asm/cpufeature.h | 23 -----------------------
 arch/arm64/kvm/pmu-emul.c           | 15 +++++++++------
 2 files changed, 9 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 6a989927926a..d49e9c7e201c 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -525,29 +525,6 @@ cpuid_feature_extract_unsigned_field(u64 features, int field)
 	return cpuid_feature_extract_unsigned_field_width(features, field, 4);
 }
 
-/*
- * Fields that identify the version of the Performance Monitors Extension do
- * not follow the standard ID scheme. See ARM DDI 0487E.a page D13-2825,
- * "Alternative ID scheme used for the Performance Monitors Extension version".
- */
-static inline u64 __attribute_const__
-cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap)
-{
-	u64 val = cpuid_feature_extract_unsigned_field(features, field);
-	u64 mask = GENMASK_ULL(field + 3, field);
-
-	/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
-	if (val == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
-		val = 0;
-
-	if (val > cap) {
-		features &= ~mask;
-		features |= (cap << field) & mask;
-	}
-
-	return features;
-}
-
 static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp)
 {
 	return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 2c98cf24bef3..98690e53dc73 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -1257,13 +1257,16 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 
 u8 kvm_arm_pmu_get_pmuver_limit(void)
 {
-	u64 tmp;
+	unsigned int pmuver;
 
-	tmp = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
-	tmp = cpuid_feature_cap_perfmon_field(tmp,
-					      ID_AA64DFR0_EL1_PMUVer_SHIFT,
-					      ID_AA64DFR0_EL1_PMUVer_V3P5);
-	return FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), tmp);
+	pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer,
+			       read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1));
+
+	/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
+	if (pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
+		return 0;
+
+	return min(pmuver, ID_AA64DFR0_EL1_PMUVer_V3P5);
 }
 
 /**
-- 
2.39.5



From cristian.ciocaltea at collabora.com  Tue Dec 17 13:46:19 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 17 Dec 2024 23:46:19 +0200
Subject: [PATCH v5 0/3] Provide devm_clk_bulk_get_all_enabled() helper
In-Reply-To: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>
References: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>
Message-ID: <b13cbeda-79b6-4700-a2e7-083a50541c80@collabora.com>

On 12/17/24 11:41 PM, Cristian Ciocaltea wrote:
> Commit 265b07df758a ("clk: Provide managed helper to get and enable bulk
> clocks") added devm_clk_bulk_get_all_enable() function, but missed to
> return the number of clocks stored in the clk_bulk_data table referenced
> by the clks argument.
> 
> That is required in case there is a need to iterate these clocks later,
> therefore I couldn't see any use case of this parameter and should have
> been simply removed from the function declaration.
> 
> The first patch in the series provides devm_clk_bulk_get_all_enabled()
> variant, which is consistent with devm_clk_bulk_get_all() in terms of
> the returned value:
> 
>  > 0 if one or more clocks have been stored
>  = 0 if there are no clocks
>  < 0 if an error occurred
> 
> Moreover, the naming is consistent with devm_clk_get_enabled(), i.e. use
> the past form of 'enable'.
> 
> The next two patches switch existing users of devm_clk_get_enable() to
> the new helper - there were only two, as of next-20240913.
> 
> The last patch drops the now obsolete devm_clk_bulk_get_all_enable()
> helper.
> 
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
> Changes in v5:
> - Rebased series onto next-20241217
> - Removed the patch introducing the new helper - merged in v6.13-rc1
> - Updated last patch to fix a rebase conflict
> - Link to v4: https://lore.kernel.org/r/20241019-clk_bulk_ena_fix-v4-0-57f108f64e70 at collabora.com

@Angelo, Matthias, Bjorn:

Could you please provide an ack for the first two patches so that
Stephen can apply them to the clk tree along with the last one removing
the obsolete helper - there are no other users of it as of next-20241217.

Thanks,
Cristian


From broonie at kernel.org  Tue Dec 17 13:59:48 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Dec 2024 21:59:48 +0000
Subject: [PATCH v3] arm64/sme: Move storage of reg_smidr to
 __cpuinfo_store_cpu()
Message-ID: <20241217-arm64-fix-boot-cpu-smidr-v3-1-7be278a85623@kernel.org>

In commit 892f7237b3ff ("arm64: Delay initialisation of
cpuinfo_arm64::reg_{zcr,smcr}") we moved access to ZCR, SMCR and SMIDR
later in the boot process in order to ensure that we don't attempt to
interact with them if SVE or SME is disabled on the command line.
Unfortunately when initialising the boot CPU in init_cpu_features() we work
on a copy of the struct cpuinfo_arm64 for the boot CPU used only during
boot, not the percpu copy used by the sysfs code. The expectation of the
feature identification code was that the ID registers would be read in
__cpuinfo_store_cpu() and the values not modified by init_cpu_features().

The main reason for the original change was to avoid early accesses to
ZCR on practical systems that were seen shipping with SVE reported in ID
registers but traps enabled at EL3 and handled as fatal errors, SME was
rolled in due to the similarity with SVE. Since then we have removed the
early accesses to ZCR and SMCR in commits:

  abef0695f9665c3d ("arm64/sve: Remove ZCR pseudo register from cpufeature code")
  391208485c3ad50f ("arm64/sve: Remove SMCR pseudo register from cpufeature code")

so only the SMIDR_EL1 part of the change remains. Since SMIDR_EL1 is
only trapped via FEAT_IDST and not the SME trap it is less likely to be
affected by similar issues, and the factors that lead to issues with SVE
are less likely to apply to SME.

Since we have not yet seen practical SME systems that need to use a
command line override (and are only just beginning to see SME systems at
all) and the ID register read is much more likely to be safe let's just
store SMIDR_EL1 along with all the other ID register reads in
__cpuinfo_store_cpu().

This issue wasn't apparent when testing on emulated platforms that do not
report values in SMIDR_EL1.

Fixes: 892f7237b3ff ("arm64: Delay initialisation of cpuinfo_arm64::reg_{zcr,smcr}")
Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: stable at vger.kernel.org
---
Changes in v3:
- Leave the override in place.
- Link to v2: https://lore.kernel.org/r/20241216-arm64-fix-boot-cpu-smidr-v2-1-a99ffba2c37f at kernel.org

Changes in v2:
- Move the ID register read back to __cpuinfo_store_cpu().
- Remove the command line option for SME ID register override.
- Link to v1: https://lore.kernel.org/r/20241214-arm64-fix-boot-cpu-smidr-v1-1-0745c40772dd at kernel.org
---
 arch/arm64/kernel/cpufeature.c | 13 -------------
 arch/arm64/kernel/cpuinfo.c    | 10 ++++++++++
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed84f9056196bb21bbfac61c9687e30..818aca922ca6066eb4bdf79e153cccb24246c61b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1167,12 +1167,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
 		unsigned long cpacr = cpacr_save_enable_kernel_sme();
 
-		/*
-		 * We mask out SMPS since even if the hardware
-		 * supports priorities the kernel does not at present
-		 * and we block access to them.
-		 */
-		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
 		vec_init_vq_map(ARM64_VEC_SME);
 
 		cpacr_restore(cpacr);
@@ -1423,13 +1417,6 @@ void update_cpu_features(int cpu,
 	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
 		unsigned long cpacr = cpacr_save_enable_kernel_sme();
 
-		/*
-		 * We mask out SMPS since even if the hardware
-		 * supports priorities the kernel does not at present
-		 * and we block access to them.
-		 */
-		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
-
 		/* Probe vector lengths */
 		if (!system_capabilities_finalized())
 			vec_update_vq_map(ARM64_VEC_SME);
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index d79e88fccdfce427507e7a34c5959ce6309cbd12..c45633b5ae233fe78607fce3d623efb28a9f341a 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -482,6 +482,16 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
 		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+		/*
+		 * We mask out SMPS since even if the hardware
+		 * supports priorities the kernel does not at present
+		 * and we block access to them.
+		 */
+		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
+	}
+
 	cpuinfo_detect_icache_policy(info);
 }
 

---
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
change-id: 20241213-arm64-fix-boot-cpu-smidr-386b8db292b2

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From dsimic at manjaro.org  Tue Dec 17 14:02:43 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 17 Dec 2024 23:02:43 +0100
Subject: [PATCH 1/3] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and
 PLL_MIPI
In-Reply-To: <20241217211505.7f9c9e4e@minigeek.lan>
References: <20241215053639.738890-1-anarsoul@gmail.com>
 <20241215053639.738890-2-anarsoul@gmail.com>
 <qbtp4jvkx3r5azufe4k3vtapqpfs54dyjiu4cy5v5wkkzumrzx@vy3xzkfplbue>
 <CA+E=qVeQ8uHBCeFtw6_2cY3252-YXc6eWrf5_YdeVgbp5LJo5g@mail.gmail.com>
 <20241217211505.7f9c9e4e@minigeek.lan>
Message-ID: <d0bf0d9cd2df65dc2e17eb203d56eb13@manjaro.org>

Hello all,

On 2024-12-17 22:15, Andre Przywara wrote:
> On Tue, 17 Dec 2024 10:00:45 -0800
> Vasily Khoruzhick <anarsoul at gmail.com> wrote:
>> On Mon, Dec 16, 2024 at 11:33?PM Krzysztof Kozlowski <krzk at kernel.org> 
>> wrote:
>> >
>> > On Sat, Dec 14, 2024 at 09:34:57PM -0800, Vasily Khoruzhick wrote:
>> > > These will be used to explicitly select TCON0 clock parent in dts
>> > >
>> > > Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
>> > > Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
>> > > ---
>> > >  drivers/clk/sunxi-ng/ccu-sun50i-a64.h      | 2 --
>> > >  include/dt-bindings/clock/sun50i-a64-ccu.h | 2 +
>> 
>> > You cannot combine these changes.
>> 
>> The patch basically moves defines out from ccu-sun50i-a64.h to
>> sun50i-a64-ccu.h. How do I split the change without introducing
>> compilation failure?
> 
> You can just have the binding part first, adding the (same) definition
> to the binding headers. As long as the #define's are not conflicting,
> this is fine.
> Then remove the now redundant definitions in the kernel headers, with a
> subsequent patch.

Yes, that would be a way to make it formally correct, but also much
less readable and understandable later, as part of the source code
repository.  FWIW, I find this to be an example of the form being
more important than the actual function.

>> > Please run scripts/checkpatch.pl and fix reported warnings. Then please
>> > run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
>> > Some warnings can be ignored, especially from --strict run, but the code
>> > here looks like it needs a fix. Feel free to get in touch if the warning
>> > is not clear.
>> 
>> Yeah, it is not clear what do you want me to do, assuming the previous
>> similar change to sun50i-a64-ccu.h did essentially the same, see
>> 71b597ef5d46a326fb0d5cbfc1c6ff1d73cdc7f9


From david at redhat.com  Tue Dec 17 14:06:25 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 17 Dec 2024 23:06:25 +0100
Subject: [PATCH v4 09/25] mm/gup.c: Remove redundant check for PCI P2PDMA
 page
In-Reply-To: <3f20b8d258d4eb72e1eadd5926d892bc61f0e0d4.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <3f20b8d258d4eb72e1eadd5926d892bc61f0e0d4.1734407924.git-series.apopple@nvidia.com>
Message-ID: <ea6eda57-f150-47ea-97b8-fc8eeaf81bd3@redhat.com>

On 17.12.24 06:12, Alistair Popple wrote:
> PCI P2PDMA pages are not mapped with pXX_devmap PTEs therefore the
> check in __gup_device_huge() is redundant. Remove it
> 
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
> Reviewed-by: Dan Wiliams <dan.j.williams at intel.com>
> Acked-by: David Hildenbrand <david at redhat.com>
> ---

Nit: patch subject should start with "mm/gup: ...".

-- 
Cheers,

David / dhildenb



From david at redhat.com  Tue Dec 17 14:14:42 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 17 Dec 2024 23:14:42 +0100
Subject: [PATCH v4 10/25] mm/mm_init: Move p2pdma page refcount
 initialisation to p2pdma
In-Reply-To: <aaa23e6f315a2d9b30a422c3769100cdfa42e85a.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <aaa23e6f315a2d9b30a422c3769100cdfa42e85a.1734407924.git-series.apopple@nvidia.com>
Message-ID: <359a1cf2-c5b0-4682-ba3c-980d77c4cfdb@redhat.com>

On 17.12.24 06:12, Alistair Popple wrote:
> Currently ZONE_DEVICE page reference counts are initialised by core
> memory management code in __init_zone_device_page() as part of the
> memremap() call which driver modules make to obtain ZONE_DEVICE
> pages. This initialises page refcounts to 1 before returning them to
> the driver.
> 
> This was presumably done because it drivers had a reference of sorts
> on the page. It also ensured the page could always be mapped with
> vm_insert_page() for example and would never get freed (ie. have a
> zero refcount), freeing drivers of manipulating page reference counts.

It probably dates back to copying that code from other zone-init code 
where we
(a) Treat all available-at-boot memory as allocated before we release it 
to the buddy
(b) Treat all hotplugged memory as allocated until we release it to the 
buddy

As a side note, I'm working on converting (b) -- PageOffline pages -- to 
have a refcount of 0 ("frozen").

> 
> However it complicates figuring out whether or not a page is free from
> the mm perspective because it is no longer possible to just look at
> the refcount. Instead the page type must be known and if GUP is used a
> secondary pgmap reference is also sometimes needed.
> 
> To simplify this it is desirable to remove the page reference count
> for the driver, so core mm can just use the refcount without having to
> account for page type or do other types of tracking. This is possible
> because drivers can always assume the page is valid as core kernel
> will never offline or remove the struct page.
> 
> This means it is now up to drivers to initialise the page refcount as
> required. P2PDMA uses vm_insert_page() to map the page, and that
> requires a non-zero reference count when initialising the page so set
> that when the page is first mapped.
> 
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> Reviewed-by: Dan Williams <dan.j.williams at intel.com>
> 
> ---
> 
> Changes since v2:
> 
>   - Initialise the page refcount for all pages covered by the kaddr
> ---
>   drivers/pci/p2pdma.c | 13 +++++++++++--
>   mm/memremap.c        | 17 +++++++++++++----
>   mm/mm_init.c         | 22 ++++++++++++++++++----
>   3 files changed, 42 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
> index 0cb7e0a..04773a8 100644
> --- a/drivers/pci/p2pdma.c
> +++ b/drivers/pci/p2pdma.c
> @@ -140,13 +140,22 @@ static int p2pmem_alloc_mmap(struct file *filp, struct kobject *kobj,
>   	rcu_read_unlock();
>   
>   	for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
> -		ret = vm_insert_page(vma, vaddr, virt_to_page(kaddr));
> +		struct page *page = virt_to_page(kaddr);
> +
> +		/*
> +		 * Initialise the refcount for the freshly allocated page. As
> +		 * we have just allocated the page no one else should be
> +		 * using it.
> +		 */
> +		VM_WARN_ON_ONCE_PAGE(!page_ref_count(page), page);
> +		set_page_count(page, 1);
> +		ret = vm_insert_page(vma, vaddr, page);
>   		if (ret) {
>   			gen_pool_free(p2pdma->pool, (uintptr_t)kaddr, len);
>   			return ret;
>   		}
>   		percpu_ref_get(ref);
> -		put_page(virt_to_page(kaddr));
> +		put_page(page);
>   		kaddr += PAGE_SIZE;
>   		len -= PAGE_SIZE;
>   	}
> diff --git a/mm/memremap.c b/mm/memremap.c
> index 40d4547..07bbe0e 100644
> --- a/mm/memremap.c
> +++ b/mm/memremap.c
> @@ -488,15 +488,24 @@ void free_zone_device_folio(struct folio *folio)
>   	folio->mapping = NULL;
>   	folio->page.pgmap->ops->page_free(folio_page(folio, 0));
>   
> -	if (folio->page.pgmap->type != MEMORY_DEVICE_PRIVATE &&
> -	    folio->page.pgmap->type != MEMORY_DEVICE_COHERENT)
> +	switch (folio->page.pgmap->type) {
> +	case MEMORY_DEVICE_PRIVATE:
> +	case MEMORY_DEVICE_COHERENT:
> +		put_dev_pagemap(folio->page.pgmap);
> +		break;
> +
> +	case MEMORY_DEVICE_FS_DAX:
> +	case MEMORY_DEVICE_GENERIC:
>   		/*
>   		 * Reset the refcount to 1 to prepare for handing out the page
>   		 * again.
>   		 */
>   		folio_set_count(folio, 1);
> -	else
> -		put_dev_pagemap(folio->page.pgmap);
> +		break;
> +
> +	case MEMORY_DEVICE_PCI_P2PDMA:
> +		break;
> +	}
>   }
>   
>   void zone_device_page_init(struct page *page)
> diff --git a/mm/mm_init.c b/mm/mm_init.c
> index 24b68b4..f021e63 100644
> --- a/mm/mm_init.c
> +++ b/mm/mm_init.c
> @@ -1017,12 +1017,26 @@ static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,
>   	}
>   
>   	/*
> -	 * ZONE_DEVICE pages are released directly to the driver page allocator
> -	 * which will set the page count to 1 when allocating the page.
> +	 * ZONE_DEVICE pages other than MEMORY_TYPE_GENERIC and
> +	 * MEMORY_TYPE_FS_DAX pages are released directly to the driver page
> +	 * allocator which will set the page count to 1 when allocating the
> +	 * page.
> +	 *
> +	 * MEMORY_TYPE_GENERIC and MEMORY_TYPE_FS_DAX pages automatically have
> +	 * their refcount reset to one whenever they are freed (ie. after
> +	 * their refcount drops to 0).
>   	 */
> -	if (pgmap->type == MEMORY_DEVICE_PRIVATE ||
> -	    pgmap->type == MEMORY_DEVICE_COHERENT)
> +	switch (pgmap->type) {
> +	case MEMORY_DEVICE_PRIVATE:
> +	case MEMORY_DEVICE_COHERENT:
> +	case MEMORY_DEVICE_PCI_P2PDMA:
>   		set_page_count(page, 0);
> +		break;
> +
> +	case MEMORY_DEVICE_FS_DAX:
> +	case MEMORY_DEVICE_GENERIC:
> +		break;
> +	}
>   }
>   
>   /*


But that's a bit weird: we call __init_single_page()->init_page_count() 
to initialize it to 1, to then set it back to 0.


Maybe we can just pass to __init_single_page() the refcount we want to 
have directly? Can be a patch on top of course.

Apart from that

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From david at redhat.com  Tue Dec 17 14:27:13 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 17 Dec 2024 23:27:13 +0100
Subject: [PATCH v4 14/25] rmap: Add support for PUD sized mappings to rmap
In-Reply-To: <7f739c9e9f0a25cafb76a482e31e632c8f72102e.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <7f739c9e9f0a25cafb76a482e31e632c8f72102e.1734407924.git-series.apopple@nvidia.com>
Message-ID: <4b5768b7-96e0-4864-9dbe-88fd1f0e87b8@redhat.com>

On 17.12.24 06:12, Alistair Popple wrote:
> The rmap doesn't currently support adding a PUD mapping of a
> folio. This patch adds support for entire PUD mappings of folios,
> primarily to allow for more standard refcounting of device DAX
> folios. Currently DAX is the only user of this and it doesn't require
> support for partially mapped PUD-sized folios so we don't support for
> that for now.
> 
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> 
> ---
> 
> David - Thanks for your previous comments, I'm less familiar with the
> rmap code so I would appreciate you taking another look. In particular
> I haven't added a stat for PUD mapped folios as it seemed like
> overkill for just the device DAX case but let me know if you think
> otherwise.
> 
> Changes for v4:
> 
>   - New for v4, split out rmap changes as suggested by David.
> ---
>   include/linux/rmap.h | 15 ++++++++++++-
>   mm/rmap.c            | 56 +++++++++++++++++++++++++++++++++++++++++++++-
>   2 files changed, 71 insertions(+)
> 
> diff --git a/include/linux/rmap.h b/include/linux/rmap.h
> index 683a040..7043914 100644
> --- a/include/linux/rmap.h
> +++ b/include/linux/rmap.h
> @@ -192,6 +192,7 @@ typedef int __bitwise rmap_t;
>   enum rmap_level {
>   	RMAP_LEVEL_PTE = 0,
>   	RMAP_LEVEL_PMD,
> +	RMAP_LEVEL_PUD,
>   };
>   
>   static inline void __folio_rmap_sanity_checks(const struct folio *folio,
> @@ -228,6 +229,14 @@ static inline void __folio_rmap_sanity_checks(const struct folio *folio,
>   		VM_WARN_ON_FOLIO(folio_nr_pages(folio) != HPAGE_PMD_NR, folio);
>   		VM_WARN_ON_FOLIO(nr_pages != HPAGE_PMD_NR, folio);
>   		break;
> +	case RMAP_LEVEL_PUD:
> +		/*
> +		 * Assume that we are creating * a single "entire" mapping of the
> +		 * folio.
> +		 */
> +		VM_WARN_ON_FOLIO(folio_nr_pages(folio) != HPAGE_PUD_NR, folio);
> +		VM_WARN_ON_FOLIO(nr_pages != HPAGE_PUD_NR, folio);
> +		break;
>   	default:
>   		VM_WARN_ON_ONCE(true);
>   	}
> @@ -251,12 +260,16 @@ void folio_add_file_rmap_ptes(struct folio *, struct page *, int nr_pages,
>   	folio_add_file_rmap_ptes(folio, page, 1, vma)
>   void folio_add_file_rmap_pmd(struct folio *, struct page *,
>   		struct vm_area_struct *);
> +void folio_add_file_rmap_pud(struct folio *, struct page *,
> +		struct vm_area_struct *);
>   void folio_remove_rmap_ptes(struct folio *, struct page *, int nr_pages,
>   		struct vm_area_struct *);
>   #define folio_remove_rmap_pte(folio, page, vma) \
>   	folio_remove_rmap_ptes(folio, page, 1, vma)
>   void folio_remove_rmap_pmd(struct folio *, struct page *,
>   		struct vm_area_struct *);
> +void folio_remove_rmap_pud(struct folio *, struct page *,
> +		struct vm_area_struct *);
>   
>   void hugetlb_add_anon_rmap(struct folio *, struct vm_area_struct *,
>   		unsigned long address, rmap_t flags);
> @@ -341,6 +354,7 @@ static __always_inline void __folio_dup_file_rmap(struct folio *folio,
>   		atomic_add(orig_nr_pages, &folio->_large_mapcount);
>   		break;
>   	case RMAP_LEVEL_PMD:
> +	case RMAP_LEVEL_PUD:
>   		atomic_inc(&folio->_entire_mapcount);
>   		atomic_inc(&folio->_large_mapcount);
>   		break;
> @@ -437,6 +451,7 @@ static __always_inline int __folio_try_dup_anon_rmap(struct folio *folio,
>   		atomic_add(orig_nr_pages, &folio->_large_mapcount);
>   		break;
>   	case RMAP_LEVEL_PMD:
> +	case RMAP_LEVEL_PUD:
>   		if (PageAnonExclusive(page)) {
>   			if (unlikely(maybe_pinned))
>   				return -EBUSY;
> diff --git a/mm/rmap.c b/mm/rmap.c
> index c6c4d4e..39d0439 100644
> --- a/mm/rmap.c
> +++ b/mm/rmap.c
> @@ -1203,6 +1203,11 @@ static __always_inline unsigned int __folio_add_rmap(struct folio *folio,
>   		}
>   		atomic_inc(&folio->_large_mapcount);
>   		break;
> +	case RMAP_LEVEL_PUD:
> +		/* We only support entire mappings of PUD sized folios in rmap */
> +		atomic_inc(&folio->_entire_mapcount);
> +		atomic_inc(&folio->_large_mapcount);
> +		break;


This way you don't account the pages at all as mapped, whereby PTE-mapping it
would? And IIRC, these PUD-sized pages can be either mapped using PTEs or
using a single PUD.

I suspect what you want is to

diff --git a/mm/rmap.c b/mm/rmap.c
index c6c4d4ea29a7e..1477028d3a176 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1187,12 +1187,19 @@ static __always_inline unsigned int __folio_add_rmap(struct folio *folio,
                 atomic_add(orig_nr_pages, &folio->_large_mapcount);
                 break;
         case RMAP_LEVEL_PMD:
+       case RMAP_LEVEL_PUD:
                 first = atomic_inc_and_test(&folio->_entire_mapcount);
                 if (first) {
                         nr = atomic_add_return_relaxed(ENTIRELY_MAPPED, mapped);
                         if (likely(nr < ENTIRELY_MAPPED + ENTIRELY_MAPPED)) {
-                               *nr_pmdmapped = folio_nr_pages(folio);
-                               nr = *nr_pmdmapped - (nr & FOLIO_PAGES_MAPPED);
+                               nr_pages = folio_nr_pages(folio);
+                               /*
+                                * We only track PMD mappings of PMD-sized
+                                * folios separately.
+                                */
+                               if (level == RMAP_LEVEL_PMD)
+                                       *nr_pmdmapped = nr_pages;
+                               nr = nr_pages - (nr & FOLIO_PAGES_MAPPED);
                                 /* Raced ahead of a remove and another add? */
                                 if (unlikely(nr < 0))
                                         nr = 0;

Similar on the removal path.


-- 
Cheers,

David / dhildenb



From david at redhat.com  Tue Dec 17 14:28:06 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 17 Dec 2024 23:28:06 +0100
Subject: [PATCH v4 20/25] mm/mlock: Skip ZONE_DEVICE PMDs during mlock
In-Reply-To: <e1fe10474fc06aaf24b17fcd916efffcc8c13f78.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <e1fe10474fc06aaf24b17fcd916efffcc8c13f78.1734407924.git-series.apopple@nvidia.com>
Message-ID: <b5111052-4bc2-481c-8510-c1b86c70bf30@redhat.com>

On 17.12.24 06:13, Alistair Popple wrote:
> At present mlock skips ptes mapping ZONE_DEVICE pages. A future change
> to remove pmd_devmap will allow pmd_trans_huge_lock() to return
> ZONE_DEVICE folios so make sure we continue to skip those.
> 
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> ---
>   mm/mlock.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/mm/mlock.c b/mm/mlock.c
> index cde076f..3cb72b5 100644
> --- a/mm/mlock.c
> +++ b/mm/mlock.c
> @@ -368,6 +368,8 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
>   		if (is_huge_zero_pmd(*pmd))
>   			goto out;
>   		folio = pmd_folio(*pmd);
> +		if (folio_is_zone_device(folio))
> +			goto out;
>   		if (vma->vm_flags & VM_LOCKED)
>   			mlock_folio(folio);
>   		else

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From david at redhat.com  Tue Dec 17 14:31:25 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 17 Dec 2024 23:31:25 +0100
Subject: [PATCH v4 19/25] proc/task_mmu: Ignore ZONE_DEVICE pages
In-Reply-To: <f3ebda542373feb70ed3e5d83b276a2e8347609f.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <f3ebda542373feb70ed3e5d83b276a2e8347609f.1734407924.git-series.apopple@nvidia.com>
Message-ID: <c7bd9b00-6920-4dc0-8e2e-36c16ef7ad5a@redhat.com>

On 17.12.24 06:13, Alistair Popple wrote:
> The procfs mmu files such as smaps currently ignore device dax and fs
> dax pages because these pages are considered special. To maintain
> existing behaviour once these pages are treated as normal pages and
> returned from vm_normal_page() add tests to explicitly skip them.
> 
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> ---
>   fs/proc/task_mmu.c | 18 ++++++++++++++----
>   1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
> index 38a5a3e..c9b227a 100644
> --- a/fs/proc/task_mmu.c
> +++ b/fs/proc/task_mmu.c
> @@ -801,6 +801,8 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
>   
>   	if (pte_present(ptent)) {
>   		page = vm_normal_page(vma, addr, ptent);
> +		if (page && (is_device_dax_page(page) || is_fsdax_page(page)))

This "is_device_dax_page(page) || is_fsdax_page(page)" is a common theme 
here, likely we should have a special helper?


But, don't we actually want to include them in the smaps output now? I 
think we want.

The rmap code will indicate these pages in /proc/meminfo, per-node info, 
in the memcg ... as "Mapped:" etc.

So likely we just want to also indicate them here, or is there any 
downsides we know of?

-- 
Cheers,

David / dhildenb



From david at redhat.com  Tue Dec 17 14:33:09 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 17 Dec 2024 23:33:09 +0100
Subject: [PATCH v4 18/25] gup: Don't allow FOLL_LONGTERM pinning of FS DAX
 pages
In-Reply-To: <f315b61169d0671301e4a793ecbb1a6c46b69bef.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <f315b61169d0671301e4a793ecbb1a6c46b69bef.1734407924.git-series.apopple@nvidia.com>
Message-ID: <e7f9433e-bd4b-4284-990b-9ea074064f0a@redhat.com>

On 17.12.24 06:13, Alistair Popple wrote:
> Longterm pinning of FS DAX pages should already be disallowed by
> various pXX_devmap checks. However a future change will cause these
> checks to be invalid for FS DAX pages so make
> folio_is_longterm_pinnable() return false for FS DAX pages.

Nit: I'd consistently use "mm/gup:" as prefix for GUP-related patches. 
(similarly, mm/huge_memory and mm/rmap in the other patches)

> 
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> Reviewed-by: John Hubbard <jhubbard at nvidia.com>
> ---
>   include/linux/mm.h | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index f267b06..01edca9 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2078,6 +2078,10 @@ static inline bool folio_is_longterm_pinnable(struct folio *folio)
>   	if (folio_is_device_coherent(folio))
>   		return false;
>   
> +	/* DAX must also always allow eviction. */
> +	if (folio_is_fsdax(folio))
> +		return false;
> +
>   	/* Otherwise, non-movable zone folios can be pinned. */
>   	return !folio_is_zone_movable(folio);
>   

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From tglx at linutronix.de  Tue Dec 17 14:56:18 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 17 Dec 2024 23:56:18 +0100
Subject: [PATCH v12 2/9] PCI: endpoint: Add RC-to-EP doorbell support
 using platform MSI controller
In-Reply-To: <20241211-ep-msi-v12-2-33d4532fa520@nxp.com>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
 <20241211-ep-msi-v12-2-33d4532fa520@nxp.com>
Message-ID: <87o7197wbx.ffs@tglx>

On Wed, Dec 11 2024 at 15:57, Frank Li wrote:
> +static int pci_epf_msi_prepare(struct irq_domain *domain, struct device *dev,
> +			       int nvec, msi_alloc_info_t *arg)
> +{
> +	struct pci_epf *epf = to_pci_epf(dev);
> +	struct msi_domain_info *msi_info;
> +	struct pci_epc *epc = epf->epc;
> +
> +	memset(arg, 0, sizeof(*arg));
> +	arg->scratchpad[0].ul = of_msi_map_id(epc->dev.parent, NULL,
> +					      (epf->func_no << 8) | epf->vfunc_no);
> +
> +	/*
> +	 * @domain->msi_domain_info->hwsize contains the size of the device
> +	 * domain, but vector allocation happens one by one.
> +	 */
> +	msi_info = msi_get_domain_info(domain);
> +	if (msi_info->hwsize > nvec)
> +		nvec = msi_info->hwsize;
> +
> +	/* Allocate at least 32 MSIs, and always as a power of 2 */
> +	nvec = max_t(int, 32, roundup_pow_of_two(nvec));
> +
> +	msi_info = msi_get_domain_info(domain->parent);
> +	return msi_info->ops->msi_prepare(domain->parent, dev, nvec, arg);

While I was trying to make sense of the change log of patch [1/9] I
looked at this function to understand why this needs an override.

This is a copy of its_msi_prepare() except for the scratchpad[0].ul
part. But that's a GIC-V3 implementation specific detail, which has
absolutely no business in code which claims to be a generic library for
PCI endpoints.

Worse you created a GIC-V3 only PCI endpoint library under the
assumption that the underlying ITS/MSI implementation is immutable. Of
course there is no safety net either to validate that the underlying
parent domain is actually GIC-V3-ITS. That's wrong in every aspect.

So let's take a step back and analyze what is actually required to make
this a proper generic library.

The endpoint function device needs its own device ID which is required
to set up a device specific translation in the interrupt remapping unit.

Now you decided that this is bound to a DT mapping, which is odd to
begin with. What's DT specific about this? The cirumstance that your
hardware is DT based and the endpoint controller ID map needs to be
retrieved from there? How is this generic in any way? How is this
supposed to work with ACPI enumerated hardware? Not to ask the question
how this should work with non GIC-V3-ITS based hardware.

That's all but generic, it's an ad hoc hack to support your particular
setup implemented by layering violations.

In fact the mapping ID is composed by the parent mapping ID and the
function numbers, right?

The general PCIe convention here is:

    domain:bus:slot.func

That's well defined and if you look at real devices then lspci shows:

0000:3d:00.1 Ethernet controller: Ethernet Connection for 10GBASE-T
0000:3d:06.0 Ethernet controller: Ethernet Virtual Function
0000:...
0000:3d:06.7 Ethernet controller: Ethernet Virtual Function
0000:3d:07.0 Ethernet controller: Ethernet Virtual Function
0000:...
0000:3d:07.7 Ethernet controller: Ethernet Virtual Function

In PCI address representation:

   domain:bus:slot:function

which is usually condensed into a single word based on the range limits
of function, device and bus:

   function:    bit 0-2         (max. 8)
   device:      bit 3-7         (max. 32)
   bus:         bit 8-15        (max. 256)
   domain:      bit 16-31       (mostly theoretical)

Endpoint devices should follow exactly the same scheme, no?

Now looking at your ID retrieval:

> +	arg->scratchpad[0].ul = of_msi_map_id(epc->dev.parent, NULL,
> +					      (epf->func_no << 8) | epf->vfunc_no);

I really have to ask why this is making up its own representation
instead of simply using the standard PCI B/D/F conventions?

Whatever the reason is, fact is that the actual interrupt domain support
needs to be done differently. There is no way that the endpoint library
makes assumption about the underlying interrupt domain and copies a
function just because. This has to be completely agnostic, no if, no
but.

So the consequence is that the underlying MSI parent domains needs to
know about the endpoint requirements, which is how all MSI variants are
modeled, i.e. with a MSI domain bus.

That also solves the problem of immutable MSI messages without any
further magic. Interrupt domains, which do not provide them, won't
provide the endpoint MSI domain bus and therefore the lookup of the
parent MSI domain for the endpoint fails.

The uncompilable mockup below should give you a hint.

Thanks,

        tglx
---
 drivers/irqchip/irq-gic-v3-its-msi-parent.c |   50 ++++++++++++++++++++--------
 drivers/irqchip/irq-msi-lib.c               |    5 ++
 drivers/irqchip/irq-msi-lib.h               |   12 +++++-
 include/linux/irqdomain_defs.h              |    2 +
 4 files changed, 51 insertions(+), 18 deletions(-)

--- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
@@ -126,20 +126,9 @@ int __weak iort_pmsi_get_dev_id(struct d
 	return -1;
 }
 
-static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
-			    int nvec, msi_alloc_info_t *info)
+static int __its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
+			      int nvec, msi_alloc_info_t *info, u32 dev_id)
 {
-	struct msi_domain_info *msi_info;
-	u32 dev_id;
-	int ret;
-
-	if (dev->of_node)
-		ret = of_pmsi_get_dev_id(domain->parent, dev, &dev_id);
-	else
-		ret = iort_pmsi_get_dev_id(dev, &dev_id);
-	if (ret)
-		return ret;
-
 	/* ITS specific DeviceID, as the core ITS ignores dev. */
 	info->scratchpad[0].ul = dev_id;
 
@@ -159,6 +148,36 @@ static int its_pmsi_prepare(struct irq_d
 					  dev, nvec, info);
 }
 
+static int its_pci_ep_msi_prepare(struct irq_domain *domain, struct device *dev,
+				  int nvec, msi_alloc_info_t *info)
+{
+	u32 dev_id = dev_get_pci_ep_id(dev);
+	struct msi_domain_info *msi_info;
+	int ret = -ENOTSUPP;
+
+	if (dev->of_node)
+		ret = do_magic_ep_id_map();
+	if (ret)
+		return ret;
+	return __its_pmsi_prepare(domain, dev, nvec, info, dev_id);
+}
+
+static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
+			    int nvec, msi_alloc_info_t *info)
+{
+	struct msi_domain_info *msi_info;
+	u32 dev_id;
+	int ret;
+
+	if (dev->of_node)
+		ret = of_pmsi_get_dev_id(domain->parent, dev, &dev_id);
+	else
+		ret = iort_pmsi_get_dev_id(dev, &dev_id);
+	if (ret)
+		return ret;
+	return __its_pmsi_prepare(domain, dev, nvec, info, dev_id);
+}
+
 static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 				  struct irq_domain *real_parent, struct msi_domain_info *info)
 {
@@ -183,6 +202,9 @@ static bool its_init_dev_msi_info(struct
 		 */
 		info->ops->msi_prepare = its_pci_msi_prepare;
 		break;
+	case DOMAIN_BUS_PCI_DEVICE_EP_MSI:
+		info->ops->msi_prepare = its_pci_ep_msi_prepare;
+		break;
 	case DOMAIN_BUS_DEVICE_MSI:
 	case DOMAIN_BUS_WIRED_TO_MSI:
 		/*
@@ -204,7 +226,7 @@ const struct msi_parent_ops gic_v3_its_m
 	.supported_flags	= ITS_MSI_FLAGS_SUPPORTED,
 	.required_flags		= ITS_MSI_FLAGS_REQUIRED,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
-	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
+	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_PCI_EP_MSI | MATCH_PLATFORM_MSI,
 	.prefix			= "ITS-",
 	.init_dev_msi_info	= its_init_dev_msi_info,
 };
--- a/drivers/irqchip/irq-msi-lib.c
+++ b/drivers/irqchip/irq-msi-lib.c
@@ -55,8 +55,11 @@ bool msi_lib_init_dev_msi_info(struct de
 	case DOMAIN_BUS_PCI_DEVICE_MSIX:
 		if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_PCI_MSI)))
 			return false;
-
 		break;
+	case DOMAIN_BUS_DEVICE_PCI_EP_MSI:
+		if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_PCI_ENDPOINT)))
+			return false;
+		fallthrough;
 	case DOMAIN_BUS_DEVICE_MSI:
 		/*
 		 * Per device MSI should never have any MSI feature bits
--- a/drivers/irqchip/irq-msi-lib.h
+++ b/drivers/irqchip/irq-msi-lib.h
@@ -10,12 +10,18 @@
 #include <linux/msi.h>
 
 #ifdef CONFIG_PCI_MSI
-#define MATCH_PCI_MSI		BIT(DOMAIN_BUS_PCI_MSI)
+#define MATCH_PCI_MSI			BIT(DOMAIN_BUS_PCI_MSI)
 #else
-#define MATCH_PCI_MSI		(0)
+#define MATCH_PCI_MSI			(0)
 #endif
 
-#define MATCH_PLATFORM_MSI	BIT(DOMAIN_BUS_PLATFORM_MSI)
+#ifdef CONFIG_PCI_ENDPOINT
+#define MATCH_PLATFORM_PCI_EP_MSI	BIT(DOMAIN_BUS_PLATFORM_PCI_EP_MSI)
+#else
+#define MATCH_PLATFORM_PCI_EP_MSI	(0)
+#endif
+
+#define MATCH_PLATFORM_MSI		BIT(DOMAIN_BUS_PLATFORM_MSI)
 
 int msi_lib_irq_domain_select(struct irq_domain *d, struct irq_fwspec *fwspec,
 			      enum irq_domain_bus_token bus_token);
--- a/include/linux/irqdomain_defs.h
+++ b/include/linux/irqdomain_defs.h
@@ -15,6 +15,7 @@ enum irq_domain_bus_token {
 	DOMAIN_BUS_GENERIC_MSI,
 	DOMAIN_BUS_PCI_MSI,
 	DOMAIN_BUS_PLATFORM_MSI,
+	DOMAIN_BUS_PLATFORM_PCI_EP_MSI,
 	DOMAIN_BUS_NEXUS,
 	DOMAIN_BUS_IPI,
 	DOMAIN_BUS_FSL_MC_MSI,
@@ -27,6 +28,7 @@ enum irq_domain_bus_token {
 	DOMAIN_BUS_AMDVI,
 	DOMAIN_BUS_DEVICE_MSI,
 	DOMAIN_BUS_WIRED_TO_MSI,
+	DOMAIN_BUS_DEVICE_PCI_EP_MSI,
 };
 
 #endif /* _LINUX_IRQDOMAIN_DEFS_H */


From irogers at google.com  Tue Dec 17 15:36:27 2024
From: irogers at google.com (Ian Rogers)
Date: Tue, 17 Dec 2024 15:36:27 -0800
Subject: [PATCH v3 16/16] perf tools: Remove dependency on libaudit
In-Reply-To: <20241216-perf_syscalltbl-v3-16-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com> <20241216-perf_syscalltbl-v3-16-239f032481d5@rivosinc.com>
Message-ID: <CAP-5=fUNmqnYBLgOJOT9q6QbnhnDKxDXDEAtC-ZZ6orhXa5x3w@mail.gmail.com>

On Mon, Dec 16, 2024 at 10:40?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
>
> All architectures now support HAVE_SYSCALL_TABLE_SUPPORT, so the flag is
> no longer needed. With the removal of the flag, the related
> GENERIC_SYSCALL_TABLE can also be removed. libaudit was only used as a
> fallback for when HAVE_SYSCALL_TABLE_SUPPORT was not defined, so
> libaudit is also no longer needed for any architecture.
>
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> ---
>  Documentation/admin-guide/workload-tracing.rst |  2 +-
>  tools/build/feature/Makefile                   |  4 --
>  tools/build/feature/test-libaudit.c            | 11 ------
>  tools/perf/Documentation/perf-check.txt        |  1 -
>  tools/perf/Makefile.config                     | 31 +--------------
>  tools/perf/Makefile.perf                       | 15 --------
>  tools/perf/builtin-check.c                     |  1 -
>  tools/perf/builtin-help.c                      |  2 -
>  tools/perf/builtin-trace.c                     | 30 ---------------
>  tools/perf/perf.c                              |  6 +--
>  tools/perf/tests/make                          |  7 +---
>  tools/perf/util/env.c                          |  4 +-
>  tools/perf/util/generate-cmdlist.sh            |  4 +-
>  tools/perf/util/syscalltbl.c                   | 52 --------------------------
>  14 files changed, 10 insertions(+), 160 deletions(-)
>
> diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
> index b2e254ec8ee846afe78eede74a825b51c6ab119b..6be38c1b9c5bb4be899fd261c6d2911abcf959dc 100644
> --- a/Documentation/admin-guide/workload-tracing.rst
> +++ b/Documentation/admin-guide/workload-tracing.rst
> @@ -83,7 +83,7 @@ scripts/ver_linux is a good way to check if your system already has
>  the necessary tools::
>
>    sudo apt-get build-essentials flex bison yacc
> -  sudo apt install libelf-dev systemtap-sdt-dev libaudit-dev libslang2-dev libperl-dev libdw-dev
> +  sudo apt install libelf-dev systemtap-sdt-dev libslang2-dev libperl-dev libdw-dev
>
>  cscope is a good tool to browse kernel sources. Let's install it now::
>
> diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
> index 043dfd00fce72d8f651ccd9b3265a0183f500e5c..e0b63e9d0251abe6d5eafc6d2f26b940918b16ee 100644
> --- a/tools/build/feature/Makefile
> +++ b/tools/build/feature/Makefile
> @@ -13,7 +13,6 @@ FILES=                                          \
>           test-gtk2.bin                          \
>           test-gtk2-infobar.bin                  \
>           test-hello.bin                         \
> -         test-libaudit.bin                      \
>           test-libbfd.bin                        \
>           test-libbfd-buildid.bin               \
>           test-disassembler-four-args.bin        \
> @@ -228,9 +227,6 @@ $(OUTPUT)test-libunwind-debug-frame-arm.bin:
>  $(OUTPUT)test-libunwind-debug-frame-aarch64.bin:
>         $(BUILD) -lelf -llzma -lunwind-aarch64
>
> -$(OUTPUT)test-libaudit.bin:
> -       $(BUILD) -laudit
> -
>  $(OUTPUT)test-libslang.bin:
>         $(BUILD) -lslang
>
> diff --git a/tools/build/feature/test-libaudit.c b/tools/build/feature/test-libaudit.c
> deleted file mode 100644
> index f5b0863fa1ec240795339428d8deed98a946d405..0000000000000000000000000000000000000000
> --- a/tools/build/feature/test-libaudit.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -#include <libaudit.h>
> -
> -extern int printf(const char *format, ...);
> -
> -int main(void)
> -{
> -       printf("error message: %s\n", audit_errno_to_name(0));
> -
> -       return audit_open();
> -}
> diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt
> index 31741499e7867c9b712227f31a2958fd641d474a..e6d2ceeb2ca7de850f41b1baa0375b6f984bb08f 100644
> --- a/tools/perf/Documentation/perf-check.txt
> +++ b/tools/perf/Documentation/perf-check.txt
> @@ -51,7 +51,6 @@ feature::
>                  dwarf_getlocations      /  HAVE_LIBDW_SUPPORT
>                  dwarf-unwind            /  HAVE_DWARF_UNWIND_SUPPORT
>                  auxtrace                /  HAVE_AUXTRACE_SUPPORT
> -                libaudit                /  HAVE_LIBAUDIT_SUPPORT
>                  libbfd                  /  HAVE_LIBBFD_SUPPORT
>                  libcapstone             /  HAVE_LIBCAPSTONE_SUPPORT
>                  libcrypto               /  HAVE_LIBCRYPTO_SUPPORT
> diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> index 3f82ba907381049213c055ab10c3fe14d9572073..a57b2364578f57e31476f5041a06a0cd22d8b27e 100644
> --- a/tools/perf/Makefile.config
> +++ b/tools/perf/Makefile.config
> @@ -28,20 +28,7 @@ include $(srctree)/tools/scripts/Makefile.arch
>
>  $(call detected_var,SRCARCH)
>
> -ifneq ($(NO_SYSCALL_TABLE),1)
> -  NO_SYSCALL_TABLE := 1
> -
> -  # architectures that use the generic syscall table scripts
> -  ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
> -    NO_SYSCALL_TABLE := 0
> -    CFLAGS += -DGENERIC_SYSCALL_TABLE
> -    CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
> -  endif
> -
> -  ifneq ($(NO_SYSCALL_TABLE),1)
> -    CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
> -  endif
> -endif
> +CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
>
>  # Additional ARCH settings for ppc
>  ifeq ($(SRCARCH),powerpc)
> @@ -755,21 +742,7 @@ ifndef NO_LIBUNWIND
>  endif
>
>  ifneq ($(NO_LIBTRACEEVENT),1)
> -  ifeq ($(NO_SYSCALL_TABLE),0)
> -    $(call detected,CONFIG_TRACE)
> -  else
> -    ifndef NO_LIBAUDIT
> -      $(call feature_check,libaudit)
> -      ifneq ($(feature-libaudit), 1)
> -        $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev)
> -        NO_LIBAUDIT := 1
> -      else
> -        CFLAGS += -DHAVE_LIBAUDIT_SUPPORT
> -        EXTLIBS += -laudit
> -        $(call detected,CONFIG_TRACE)
> -      endif
> -    endif
> -  endif
> +  $(call detected,CONFIG_TRACE)
>  endif
>
>  ifndef NO_LIBCRYPTO
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index 2c6a509c800d3037933c9b49e5a7dafbf78fda0c..ab2d075ff3a23350a5eea12508cf0376f1d9f4e8 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -59,8 +59,6 @@ include ../scripts/utilities.mak
>  #
>  # Define NO_LIBNUMA if you do not want numa perf benchmark
>  #
> -# Define NO_LIBAUDIT if you do not want libaudit support
> -#
>  # Define NO_LIBBIONIC if you do not want bionic support
>  #
>  # Define NO_LIBCRYPTO if you do not want libcrypto (openssl) support
> @@ -119,10 +117,6 @@ include ../scripts/utilities.mak
>  #
>  # Define LIBBPF_DYNAMIC to enable libbpf dynamic linking.
>  #
> -# Define NO_SYSCALL_TABLE=1 to disable the use of syscall id to/from name tables
> -# generated from the kernel .tbl or unistd.h files and use, if available, libaudit
> -# for doing the conversions to/from strings/id.
> -#
>  # Define NO_LIBPFM4 to disable libpfm4 events extension.
>  #
>  # Define NO_LIBDEBUGINFOD if you do not want support debuginfod
> @@ -310,11 +304,7 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
>  FEATURE_TESTS := all
>  endif
>  endif
> -# architectures that use the generic syscall table
> -generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390
> -ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
>  include $(srctree)/tools/perf/scripts/Makefile.syscalls
> -endif
>  include Makefile.config
>  endif
>
> @@ -1099,11 +1089,6 @@ endif
>                 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
>         $(call QUIET_INSTALL, perf-iostat) \
>                 $(INSTALL) $(OUTPUT)perf-iostat -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
> -ifndef NO_LIBAUDIT
> -       $(call QUIET_INSTALL, strace/groups) \
> -               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'; \
> -               $(INSTALL) trace/strace/groups/* -m 644 -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'
> -endif
>  ifndef NO_LIBPERL
>         $(call QUIET_INSTALL, perl-scripts) \
>                 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
> diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
> index 2346536a5ee14f91ecd10bd130a64676e871e1b2..7aed7b9f4f5270527ee1d36327eb6a01f196a46a 100644
> --- a/tools/perf/builtin-check.c
> +++ b/tools/perf/builtin-check.c
> @@ -31,7 +31,6 @@ struct feature_status supported_features[] = {
>         FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT),
>         FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT),
>         FEATURE_STATUS("auxtrace", HAVE_AUXTRACE_SUPPORT),
> -       FEATURE_STATUS("libaudit", HAVE_LIBAUDIT_SUPPORT),
>         FEATURE_STATUS("libbfd", HAVE_LIBBFD_SUPPORT),
>         FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT),
>         FEATURE_STATUS("libcrypto", HAVE_LIBCRYPTO_SUPPORT),
> diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
> index 0854d3cd9f6a304cd9cb50ad430d5706d91df0e9..7be6fb6df595923c15ae51747d5bf17d867ae785 100644
> --- a/tools/perf/builtin-help.c
> +++ b/tools/perf/builtin-help.c
> @@ -447,9 +447,7 @@ int cmd_help(int argc, const char **argv)
>  #ifdef HAVE_LIBELF_SUPPORT
>                 "probe",
>  #endif
> -#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
>                 "trace",
> -#endif
>         NULL };
>         const char *builtin_help_usage[] = {
>                 "perf help [--all] [--man|--web|--info] [command]",
> diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
> index 6a1a128fe645014d0347ad4ec3e0c9e77ec59aee..0fddf34458db4fe4896d25f427f2ae29cb3aa15f 100644
> --- a/tools/perf/builtin-trace.c
> +++ b/tools/perf/builtin-trace.c
> @@ -2069,30 +2069,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
>         const char *name = syscalltbl__name(trace->sctbl, id);
>         int err;
>
> -#ifdef HAVE_SYSCALL_TABLE_SUPPORT
>         if (trace->syscalls.table == NULL) {
>                 trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc));
>                 if (trace->syscalls.table == NULL)
>                         return -ENOMEM;
>         }
> -#else
> -       if (id > trace->sctbl->syscalls.max_id || (id == 0 && trace->syscalls.table == NULL)) {
> -               // When using libaudit we don't know beforehand what is the max syscall id
> -               struct syscall *table = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
> -
> -               if (table == NULL)
> -                       return -ENOMEM;
> -
> -               // Need to memset from offset 0 and +1 members if brand new
> -               if (trace->syscalls.table == NULL)
> -                       memset(table, 0, (id + 1) * sizeof(*sc));
> -               else
> -                       memset(table + trace->sctbl->syscalls.max_id + 1, 0, (id - trace->sctbl->syscalls.max_id) * sizeof(*sc));
> -
> -               trace->syscalls.table         = table;
> -               trace->sctbl->syscalls.max_id = id;
> -       }
> -#endif
>         sc = trace->syscalls.table + id;
>         if (sc->nonexistent)
>                 return -EEXIST;
> @@ -2439,18 +2420,7 @@ static struct syscall *trace__syscall_info(struct trace *trace,
>
>         err = -EINVAL;
>
> -#ifdef HAVE_SYSCALL_TABLE_SUPPORT
>         if (id > trace->sctbl->syscalls.max_id) {
> -#else
> -       if (id >= trace->sctbl->syscalls.max_id) {
> -               /*
> -                * With libaudit we don't know beforehand what is the max_id,
> -                * so we let trace__read_syscall_info() figure that out as we
> -                * go on reading syscalls.
> -                */
> -               err = trace__read_syscall_info(trace, id);
> -               if (err)
> -#endif
>                 goto out_cant_read;
>         }
>
> diff --git a/tools/perf/perf.c b/tools/perf/perf.c
> index a2987f2cfe1a3958f53239ed1a4eec3f87d7466a..f0617cc41f5fe638986e5d8316a6b3056c2c4bc5 100644
> --- a/tools/perf/perf.c
> +++ b/tools/perf/perf.c
> @@ -84,7 +84,7 @@ static struct cmd_struct commands[] = {
>  #endif
>         { "kvm",        cmd_kvm,        0 },
>         { "test",       cmd_test,       0 },
> -#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))
> +#if defined(HAVE_LIBTRACEEVENT)
>         { "trace",      cmd_trace,      0 },
>  #endif
>         { "inject",     cmd_inject,     0 },
> @@ -514,10 +514,6 @@ int main(int argc, const char **argv)
>                 fprintf(stderr,
>                         "trace command not available: missing libtraceevent devel package at build time.\n");
>                 goto out;
> -#elif !defined(HAVE_LIBAUDIT_SUPPORT) && !defined(HAVE_SYSCALL_TABLE_SUPPORT)
> -               fprintf(stderr,
> -                       "trace command not available: missing audit-libs devel package at build time.\n");
> -               goto out;
>  #else
>                 setup_path();
>                 argv[0] = "trace";
> diff --git a/tools/perf/tests/make b/tools/perf/tests/make
> index a7fcbd589752a90459815bd21075528c6dfa4d94..0ee94caf9ec19820a94a87dd46a7ccf1cefb844a 100644
> --- a/tools/perf/tests/make
> +++ b/tools/perf/tests/make
> @@ -86,7 +86,6 @@ make_no_libdw_dwarf_unwind := NO_LIBDW_DWARF_UNWIND=1
>  make_no_backtrace   := NO_BACKTRACE=1
>  make_no_libcapstone := NO_CAPSTONE=1
>  make_no_libnuma     := NO_LIBNUMA=1
> -make_no_libaudit    := NO_LIBAUDIT=1
>  make_no_libbionic   := NO_LIBBIONIC=1
>  make_no_auxtrace    := NO_AUXTRACE=1
>  make_no_libbpf     := NO_LIBBPF=1
> @@ -97,7 +96,6 @@ make_no_libllvm     := NO_LIBLLVM=1
>  make_with_babeltrace:= LIBBABELTRACE=1
>  make_with_coresight := CORESIGHT=1
>  make_no_sdt        := NO_SDT=1
> -make_no_syscall_tbl := NO_SYSCALL_TABLE=1
>  make_no_libpfm4     := NO_LIBPFM4=1
>  make_with_gtk2      := GTK2=1
>  make_refcnt_check   := EXTRA_CFLAGS="-DREFCNT_CHECKING=1"
> @@ -122,10 +120,10 @@ make_static         := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX3
>  # all the NO_* variable combined
>  make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_GTK2=1
>  make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_BACKTRACE=1
> -make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
> +make_minimal        += NO_LIBNUMA=1 NO_LIBBIONIC=1
>  make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
>  make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
> -make_minimal        += NO_LIBCAP=1 NO_SYSCALL_TABLE=1 NO_CAPSTONE=1
> +make_minimal        += NO_LIBCAP=1 NO_CAPSTONE=1
>
>  # $(run) contains all available tests
>  run := make_pure
> @@ -158,7 +156,6 @@ run += make_no_libdw_dwarf_unwind
>  run += make_no_backtrace
>  run += make_no_libcapstone
>  run += make_no_libnuma
> -run += make_no_libaudit
>  run += make_no_libbionic
>  run += make_no_auxtrace
>  run += make_no_libbpf
> diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
> index e2843ca2edd92ea5fa1c020ae92b183c496e975e..e9a694350671910d537de599071dbe7fcc18ced4 100644
> --- a/tools/perf/util/env.c
> +++ b/tools/perf/util/env.c
> @@ -474,13 +474,13 @@ const char *perf_env__arch(struct perf_env *env)
>
>  const char *perf_env__arch_strerrno(struct perf_env *env __maybe_unused, int err __maybe_unused)
>  {
> -#if defined(HAVE_SYSCALL_TABLE_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
> +#if defined(HAVE_LIBTRACEEVENT)
>         if (env->arch_strerrno == NULL)
>                 env->arch_strerrno = arch_syscalls__strerrno_function(perf_env__arch(env));
>
>         return env->arch_strerrno ? env->arch_strerrno(err) : "no arch specific strerrno function";
>  #else
> -       return "!(HAVE_SYSCALL_TABLE_SUPPORT && HAVE_LIBTRACEEVENT)";
> +       return "!HAVE_LIBTRACEEVENT";
>  #endif
>  }
>
> diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh
> index 1b5140e5ce9975fac87b2674dc694f9d4e439a5f..6a73c903d69050df69267a8aeaeeac1ed170efe1 100755
> --- a/tools/perf/util/generate-cmdlist.sh
> +++ b/tools/perf/util/generate-cmdlist.sh
> @@ -38,7 +38,7 @@ do
>  done
>  echo "#endif /* HAVE_LIBELF_SUPPORT */"
>
> -echo "#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))"
> +echo "#if defined(HAVE_LIBTRACEEVENT)"
>  sed -n -e 's/^perf-\([^        ]*\)[   ].* audit*/\1/p' command-list.txt |
>  sort |
>  while read cmd
> @@ -51,7 +51,7 @@ do
>             p
>       }' "Documentation/perf-$cmd.txt"
>  done
> -echo "#endif /* HAVE_LIBTRACEEVENT && (HAVE_LIBAUDIT_SUPPORT || HAVE_SYSCALL_TABLE_SUPPORT) */"
> +echo "#endif /* HAVE_LIBTRACEEVENT */"
>
>  echo "#ifdef HAVE_LIBTRACEEVENT"
>  sed -n -e 's/^perf-\([^        ]*\)[   ].* traceevent.*/\1/p' command-list.txt |
> diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
> index 210f61b0a7a264a427ebb602185d3a9da2f426f4..928aca4cd6e9f2f26c5c4fd825b4538c064a4cc3 100644
> --- a/tools/perf/util/syscalltbl.c
> +++ b/tools/perf/util/syscalltbl.c
> @@ -10,20 +10,12 @@
>  #include <linux/compiler.h>
>  #include <linux/zalloc.h>
>
> -#ifdef HAVE_SYSCALL_TABLE_SUPPORT
>  #include <string.h>
>  #include "string2.h"
>
> -#if defined(GENERIC_SYSCALL_TABLE)
>  #include <syscall_table.h>
>  const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
>  static const char *const *syscalltbl_native = syscalltbl;
> -#else
> -const int syscalltbl_native_max_id = 0;
> -static const char *const syscalltbl_native[] = {
> -       [0] = "unknown",
> -};
> -#endif
>
>  struct syscall {
>         int id;
> @@ -131,47 +123,3 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
>         *idx = -1;
>         return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
>  }
> -
> -#else /* HAVE_SYSCALL_TABLE_SUPPORT */
> -
> -#include <libaudit.h>
> -
> -struct syscalltbl *syscalltbl__new(void)
> -{
> -       struct syscalltbl *tbl = zalloc(sizeof(*tbl));
> -       if (tbl)
> -               tbl->audit_machine = audit_detect_machine();

struct syscalltbl's audit_machine is now unused, remove?

Thanks,
Ian

> -       return tbl;
> -}
> -
> -void syscalltbl__delete(struct syscalltbl *tbl)
> -{
> -       free(tbl);
> -}
> -
> -const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
> -{
> -       return audit_syscall_to_name(id, tbl->audit_machine);
> -}
> -
> -int syscalltbl__id(struct syscalltbl *tbl, const char *name)
> -{
> -       return audit_name_to_syscall(name, tbl->audit_machine);
> -}
> -
> -int syscalltbl__id_at_idx(struct syscalltbl *tbl __maybe_unused, int idx)
> -{
> -       return idx;
> -}
> -
> -int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
> -                                 const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
> -{
> -       return -1;
> -}
> -
> -int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
> -{
> -       return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
> -}
> -#endif /* HAVE_SYSCALL_TABLE_SUPPORT */
>
> --
> 2.34.1
>


From festevam at gmail.com  Tue Dec 17 15:43:51 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 17 Dec 2024 20:43:51 -0300
Subject: [PATCH] ARM: dts: imx: 
Message-ID: <20241217234351.71130-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

mdio-gpio is not a valid pattern according to mdio-gpio.yaml.

Use the generic 'mdio' name to fix the following dt-schema warnings:

'mdio-gpio' does not match '^mdio(-(bus|external))?(@.+|-([0-9]+))?$'

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts      | 2 +-
 arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi       | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
index 7cd17b43b4b2..06545a6052f7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
@@ -160,7 +160,7 @@ eeprom at 0 {
 		};
 	};
 
-	mdio_gpio: mdio-gpio {
+	mdio_gpio: mdio {
 		compatible = "virtual,mdio-gpio";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_swmdio>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts b/arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts
index 625f9ac671ae..26eb7a9506e4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts
@@ -37,7 +37,7 @@ usb_vbus: regulator-usb-vbus {
 		regulator-max-microvolt = <5000000>;
 	};
 
-	mdio_gpio: mdio-gpio {
+	mdio_gpio: mdio {
 		compatible = "virtual,mdio-gpio";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_swmdio>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi
index c1ae7c47b442..aa1adcc74019 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi
@@ -94,7 +94,7 @@ aliases {
 		mdio-gpio0 = &mdio0;
 	};
 
-	mdio0: mdio-gpio {
+	mdio0: mdio {
 		compatible = "virtual,mdio-gpio";
 		gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>, /* mdc */
 			<&gpio2 7 GPIO_ACTIVE_HIGH>; /* mdio */
-- 
2.34.1



From charlie at rivosinc.com  Tue Dec 17 16:02:54 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Tue, 17 Dec 2024 16:02:54 -0800
Subject: [PATCH v3 16/16] perf tools: Remove dependency on libaudit
In-Reply-To: <CAP-5=fUNmqnYBLgOJOT9q6QbnhnDKxDXDEAtC-ZZ6orhXa5x3w@mail.gmail.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
 <20241216-perf_syscalltbl-v3-16-239f032481d5@rivosinc.com>
 <CAP-5=fUNmqnYBLgOJOT9q6QbnhnDKxDXDEAtC-ZZ6orhXa5x3w@mail.gmail.com>
Message-ID: <Z2IRLtRX6V18ktqq@ghost>

On Tue, Dec 17, 2024 at 03:36:27PM -0800, Ian Rogers wrote:
> On Mon, Dec 16, 2024 at 10:40?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
> >
> > All architectures now support HAVE_SYSCALL_TABLE_SUPPORT, so the flag is
> > no longer needed. With the removal of the flag, the related
> > GENERIC_SYSCALL_TABLE can also be removed. libaudit was only used as a
> > fallback for when HAVE_SYSCALL_TABLE_SUPPORT was not defined, so
> > libaudit is also no longer needed for any architecture.
> >
> > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > ---
> >  Documentation/admin-guide/workload-tracing.rst |  2 +-
> >  tools/build/feature/Makefile                   |  4 --
> >  tools/build/feature/test-libaudit.c            | 11 ------
> >  tools/perf/Documentation/perf-check.txt        |  1 -
> >  tools/perf/Makefile.config                     | 31 +--------------
> >  tools/perf/Makefile.perf                       | 15 --------
> >  tools/perf/builtin-check.c                     |  1 -
> >  tools/perf/builtin-help.c                      |  2 -
> >  tools/perf/builtin-trace.c                     | 30 ---------------
> >  tools/perf/perf.c                              |  6 +--
> >  tools/perf/tests/make                          |  7 +---
> >  tools/perf/util/env.c                          |  4 +-
> >  tools/perf/util/generate-cmdlist.sh            |  4 +-
> >  tools/perf/util/syscalltbl.c                   | 52 --------------------------
> >  14 files changed, 10 insertions(+), 160 deletions(-)
> >
> > diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
> > index b2e254ec8ee846afe78eede74a825b51c6ab119b..6be38c1b9c5bb4be899fd261c6d2911abcf959dc 100644
> > --- a/Documentation/admin-guide/workload-tracing.rst
> > +++ b/Documentation/admin-guide/workload-tracing.rst
> > @@ -83,7 +83,7 @@ scripts/ver_linux is a good way to check if your system already has
> >  the necessary tools::
> >
> >    sudo apt-get build-essentials flex bison yacc
> > -  sudo apt install libelf-dev systemtap-sdt-dev libaudit-dev libslang2-dev libperl-dev libdw-dev
> > +  sudo apt install libelf-dev systemtap-sdt-dev libslang2-dev libperl-dev libdw-dev
> >
> >  cscope is a good tool to browse kernel sources. Let's install it now::
> >
> > diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
> > index 043dfd00fce72d8f651ccd9b3265a0183f500e5c..e0b63e9d0251abe6d5eafc6d2f26b940918b16ee 100644
> > --- a/tools/build/feature/Makefile
> > +++ b/tools/build/feature/Makefile
> > @@ -13,7 +13,6 @@ FILES=                                          \
> >           test-gtk2.bin                          \
> >           test-gtk2-infobar.bin                  \
> >           test-hello.bin                         \
> > -         test-libaudit.bin                      \
> >           test-libbfd.bin                        \
> >           test-libbfd-buildid.bin               \
> >           test-disassembler-four-args.bin        \
> > @@ -228,9 +227,6 @@ $(OUTPUT)test-libunwind-debug-frame-arm.bin:
> >  $(OUTPUT)test-libunwind-debug-frame-aarch64.bin:
> >         $(BUILD) -lelf -llzma -lunwind-aarch64
> >
> > -$(OUTPUT)test-libaudit.bin:
> > -       $(BUILD) -laudit
> > -
> >  $(OUTPUT)test-libslang.bin:
> >         $(BUILD) -lslang
> >
> > diff --git a/tools/build/feature/test-libaudit.c b/tools/build/feature/test-libaudit.c
> > deleted file mode 100644
> > index f5b0863fa1ec240795339428d8deed98a946d405..0000000000000000000000000000000000000000
> > --- a/tools/build/feature/test-libaudit.c
> > +++ /dev/null
> > @@ -1,11 +0,0 @@
> > -// SPDX-License-Identifier: GPL-2.0
> > -#include <libaudit.h>
> > -
> > -extern int printf(const char *format, ...);
> > -
> > -int main(void)
> > -{
> > -       printf("error message: %s\n", audit_errno_to_name(0));
> > -
> > -       return audit_open();
> > -}
> > diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt
> > index 31741499e7867c9b712227f31a2958fd641d474a..e6d2ceeb2ca7de850f41b1baa0375b6f984bb08f 100644
> > --- a/tools/perf/Documentation/perf-check.txt
> > +++ b/tools/perf/Documentation/perf-check.txt
> > @@ -51,7 +51,6 @@ feature::
> >                  dwarf_getlocations      /  HAVE_LIBDW_SUPPORT
> >                  dwarf-unwind            /  HAVE_DWARF_UNWIND_SUPPORT
> >                  auxtrace                /  HAVE_AUXTRACE_SUPPORT
> > -                libaudit                /  HAVE_LIBAUDIT_SUPPORT
> >                  libbfd                  /  HAVE_LIBBFD_SUPPORT
> >                  libcapstone             /  HAVE_LIBCAPSTONE_SUPPORT
> >                  libcrypto               /  HAVE_LIBCRYPTO_SUPPORT
> > diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> > index 3f82ba907381049213c055ab10c3fe14d9572073..a57b2364578f57e31476f5041a06a0cd22d8b27e 100644
> > --- a/tools/perf/Makefile.config
> > +++ b/tools/perf/Makefile.config
> > @@ -28,20 +28,7 @@ include $(srctree)/tools/scripts/Makefile.arch
> >
> >  $(call detected_var,SRCARCH)
> >
> > -ifneq ($(NO_SYSCALL_TABLE),1)
> > -  NO_SYSCALL_TABLE := 1
> > -
> > -  # architectures that use the generic syscall table scripts
> > -  ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
> > -    NO_SYSCALL_TABLE := 0
> > -    CFLAGS += -DGENERIC_SYSCALL_TABLE
> > -    CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
> > -  endif
> > -
> > -  ifneq ($(NO_SYSCALL_TABLE),1)
> > -    CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
> > -  endif
> > -endif
> > +CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
> >
> >  # Additional ARCH settings for ppc
> >  ifeq ($(SRCARCH),powerpc)
> > @@ -755,21 +742,7 @@ ifndef NO_LIBUNWIND
> >  endif
> >
> >  ifneq ($(NO_LIBTRACEEVENT),1)
> > -  ifeq ($(NO_SYSCALL_TABLE),0)
> > -    $(call detected,CONFIG_TRACE)
> > -  else
> > -    ifndef NO_LIBAUDIT
> > -      $(call feature_check,libaudit)
> > -      ifneq ($(feature-libaudit), 1)
> > -        $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev)
> > -        NO_LIBAUDIT := 1
> > -      else
> > -        CFLAGS += -DHAVE_LIBAUDIT_SUPPORT
> > -        EXTLIBS += -laudit
> > -        $(call detected,CONFIG_TRACE)
> > -      endif
> > -    endif
> > -  endif
> > +  $(call detected,CONFIG_TRACE)
> >  endif
> >
> >  ifndef NO_LIBCRYPTO
> > diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> > index 2c6a509c800d3037933c9b49e5a7dafbf78fda0c..ab2d075ff3a23350a5eea12508cf0376f1d9f4e8 100644
> > --- a/tools/perf/Makefile.perf
> > +++ b/tools/perf/Makefile.perf
> > @@ -59,8 +59,6 @@ include ../scripts/utilities.mak
> >  #
> >  # Define NO_LIBNUMA if you do not want numa perf benchmark
> >  #
> > -# Define NO_LIBAUDIT if you do not want libaudit support
> > -#
> >  # Define NO_LIBBIONIC if you do not want bionic support
> >  #
> >  # Define NO_LIBCRYPTO if you do not want libcrypto (openssl) support
> > @@ -119,10 +117,6 @@ include ../scripts/utilities.mak
> >  #
> >  # Define LIBBPF_DYNAMIC to enable libbpf dynamic linking.
> >  #
> > -# Define NO_SYSCALL_TABLE=1 to disable the use of syscall id to/from name tables
> > -# generated from the kernel .tbl or unistd.h files and use, if available, libaudit
> > -# for doing the conversions to/from strings/id.
> > -#
> >  # Define NO_LIBPFM4 to disable libpfm4 events extension.
> >  #
> >  # Define NO_LIBDEBUGINFOD if you do not want support debuginfod
> > @@ -310,11 +304,7 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
> >  FEATURE_TESTS := all
> >  endif
> >  endif
> > -# architectures that use the generic syscall table
> > -generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390
> > -ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
> >  include $(srctree)/tools/perf/scripts/Makefile.syscalls
> > -endif
> >  include Makefile.config
> >  endif
> >
> > @@ -1099,11 +1089,6 @@ endif
> >                 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
> >         $(call QUIET_INSTALL, perf-iostat) \
> >                 $(INSTALL) $(OUTPUT)perf-iostat -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
> > -ifndef NO_LIBAUDIT
> > -       $(call QUIET_INSTALL, strace/groups) \
> > -               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'; \
> > -               $(INSTALL) trace/strace/groups/* -m 644 -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'
> > -endif
> >  ifndef NO_LIBPERL
> >         $(call QUIET_INSTALL, perl-scripts) \
> >                 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
> > diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
> > index 2346536a5ee14f91ecd10bd130a64676e871e1b2..7aed7b9f4f5270527ee1d36327eb6a01f196a46a 100644
> > --- a/tools/perf/builtin-check.c
> > +++ b/tools/perf/builtin-check.c
> > @@ -31,7 +31,6 @@ struct feature_status supported_features[] = {
> >         FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT),
> >         FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT),
> >         FEATURE_STATUS("auxtrace", HAVE_AUXTRACE_SUPPORT),
> > -       FEATURE_STATUS("libaudit", HAVE_LIBAUDIT_SUPPORT),
> >         FEATURE_STATUS("libbfd", HAVE_LIBBFD_SUPPORT),
> >         FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT),
> >         FEATURE_STATUS("libcrypto", HAVE_LIBCRYPTO_SUPPORT),
> > diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
> > index 0854d3cd9f6a304cd9cb50ad430d5706d91df0e9..7be6fb6df595923c15ae51747d5bf17d867ae785 100644
> > --- a/tools/perf/builtin-help.c
> > +++ b/tools/perf/builtin-help.c
> > @@ -447,9 +447,7 @@ int cmd_help(int argc, const char **argv)
> >  #ifdef HAVE_LIBELF_SUPPORT
> >                 "probe",
> >  #endif
> > -#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
> >                 "trace",
> > -#endif
> >         NULL };
> >         const char *builtin_help_usage[] = {
> >                 "perf help [--all] [--man|--web|--info] [command]",
> > diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
> > index 6a1a128fe645014d0347ad4ec3e0c9e77ec59aee..0fddf34458db4fe4896d25f427f2ae29cb3aa15f 100644
> > --- a/tools/perf/builtin-trace.c
> > +++ b/tools/perf/builtin-trace.c
> > @@ -2069,30 +2069,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
> >         const char *name = syscalltbl__name(trace->sctbl, id);
> >         int err;
> >
> > -#ifdef HAVE_SYSCALL_TABLE_SUPPORT
> >         if (trace->syscalls.table == NULL) {
> >                 trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc));
> >                 if (trace->syscalls.table == NULL)
> >                         return -ENOMEM;
> >         }
> > -#else
> > -       if (id > trace->sctbl->syscalls.max_id || (id == 0 && trace->syscalls.table == NULL)) {
> > -               // When using libaudit we don't know beforehand what is the max syscall id
> > -               struct syscall *table = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
> > -
> > -               if (table == NULL)
> > -                       return -ENOMEM;
> > -
> > -               // Need to memset from offset 0 and +1 members if brand new
> > -               if (trace->syscalls.table == NULL)
> > -                       memset(table, 0, (id + 1) * sizeof(*sc));
> > -               else
> > -                       memset(table + trace->sctbl->syscalls.max_id + 1, 0, (id - trace->sctbl->syscalls.max_id) * sizeof(*sc));
> > -
> > -               trace->syscalls.table         = table;
> > -               trace->sctbl->syscalls.max_id = id;
> > -       }
> > -#endif
> >         sc = trace->syscalls.table + id;
> >         if (sc->nonexistent)
> >                 return -EEXIST;
> > @@ -2439,18 +2420,7 @@ static struct syscall *trace__syscall_info(struct trace *trace,
> >
> >         err = -EINVAL;
> >
> > -#ifdef HAVE_SYSCALL_TABLE_SUPPORT
> >         if (id > trace->sctbl->syscalls.max_id) {
> > -#else
> > -       if (id >= trace->sctbl->syscalls.max_id) {
> > -               /*
> > -                * With libaudit we don't know beforehand what is the max_id,
> > -                * so we let trace__read_syscall_info() figure that out as we
> > -                * go on reading syscalls.
> > -                */
> > -               err = trace__read_syscall_info(trace, id);
> > -               if (err)
> > -#endif
> >                 goto out_cant_read;
> >         }
> >
> > diff --git a/tools/perf/perf.c b/tools/perf/perf.c
> > index a2987f2cfe1a3958f53239ed1a4eec3f87d7466a..f0617cc41f5fe638986e5d8316a6b3056c2c4bc5 100644
> > --- a/tools/perf/perf.c
> > +++ b/tools/perf/perf.c
> > @@ -84,7 +84,7 @@ static struct cmd_struct commands[] = {
> >  #endif
> >         { "kvm",        cmd_kvm,        0 },
> >         { "test",       cmd_test,       0 },
> > -#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))
> > +#if defined(HAVE_LIBTRACEEVENT)
> >         { "trace",      cmd_trace,      0 },
> >  #endif
> >         { "inject",     cmd_inject,     0 },
> > @@ -514,10 +514,6 @@ int main(int argc, const char **argv)
> >                 fprintf(stderr,
> >                         "trace command not available: missing libtraceevent devel package at build time.\n");
> >                 goto out;
> > -#elif !defined(HAVE_LIBAUDIT_SUPPORT) && !defined(HAVE_SYSCALL_TABLE_SUPPORT)
> > -               fprintf(stderr,
> > -                       "trace command not available: missing audit-libs devel package at build time.\n");
> > -               goto out;
> >  #else
> >                 setup_path();
> >                 argv[0] = "trace";
> > diff --git a/tools/perf/tests/make b/tools/perf/tests/make
> > index a7fcbd589752a90459815bd21075528c6dfa4d94..0ee94caf9ec19820a94a87dd46a7ccf1cefb844a 100644
> > --- a/tools/perf/tests/make
> > +++ b/tools/perf/tests/make
> > @@ -86,7 +86,6 @@ make_no_libdw_dwarf_unwind := NO_LIBDW_DWARF_UNWIND=1
> >  make_no_backtrace   := NO_BACKTRACE=1
> >  make_no_libcapstone := NO_CAPSTONE=1
> >  make_no_libnuma     := NO_LIBNUMA=1
> > -make_no_libaudit    := NO_LIBAUDIT=1
> >  make_no_libbionic   := NO_LIBBIONIC=1
> >  make_no_auxtrace    := NO_AUXTRACE=1
> >  make_no_libbpf     := NO_LIBBPF=1
> > @@ -97,7 +96,6 @@ make_no_libllvm     := NO_LIBLLVM=1
> >  make_with_babeltrace:= LIBBABELTRACE=1
> >  make_with_coresight := CORESIGHT=1
> >  make_no_sdt        := NO_SDT=1
> > -make_no_syscall_tbl := NO_SYSCALL_TABLE=1
> >  make_no_libpfm4     := NO_LIBPFM4=1
> >  make_with_gtk2      := GTK2=1
> >  make_refcnt_check   := EXTRA_CFLAGS="-DREFCNT_CHECKING=1"
> > @@ -122,10 +120,10 @@ make_static         := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX3
> >  # all the NO_* variable combined
> >  make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_GTK2=1
> >  make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_BACKTRACE=1
> > -make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
> > +make_minimal        += NO_LIBNUMA=1 NO_LIBBIONIC=1
> >  make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
> >  make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
> > -make_minimal        += NO_LIBCAP=1 NO_SYSCALL_TABLE=1 NO_CAPSTONE=1
> > +make_minimal        += NO_LIBCAP=1 NO_CAPSTONE=1
> >
> >  # $(run) contains all available tests
> >  run := make_pure
> > @@ -158,7 +156,6 @@ run += make_no_libdw_dwarf_unwind
> >  run += make_no_backtrace
> >  run += make_no_libcapstone
> >  run += make_no_libnuma
> > -run += make_no_libaudit
> >  run += make_no_libbionic
> >  run += make_no_auxtrace
> >  run += make_no_libbpf
> > diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
> > index e2843ca2edd92ea5fa1c020ae92b183c496e975e..e9a694350671910d537de599071dbe7fcc18ced4 100644
> > --- a/tools/perf/util/env.c
> > +++ b/tools/perf/util/env.c
> > @@ -474,13 +474,13 @@ const char *perf_env__arch(struct perf_env *env)
> >
> >  const char *perf_env__arch_strerrno(struct perf_env *env __maybe_unused, int err __maybe_unused)
> >  {
> > -#if defined(HAVE_SYSCALL_TABLE_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
> > +#if defined(HAVE_LIBTRACEEVENT)
> >         if (env->arch_strerrno == NULL)
> >                 env->arch_strerrno = arch_syscalls__strerrno_function(perf_env__arch(env));
> >
> >         return env->arch_strerrno ? env->arch_strerrno(err) : "no arch specific strerrno function";
> >  #else
> > -       return "!(HAVE_SYSCALL_TABLE_SUPPORT && HAVE_LIBTRACEEVENT)";
> > +       return "!HAVE_LIBTRACEEVENT";
> >  #endif
> >  }
> >
> > diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh
> > index 1b5140e5ce9975fac87b2674dc694f9d4e439a5f..6a73c903d69050df69267a8aeaeeac1ed170efe1 100755
> > --- a/tools/perf/util/generate-cmdlist.sh
> > +++ b/tools/perf/util/generate-cmdlist.sh
> > @@ -38,7 +38,7 @@ do
> >  done
> >  echo "#endif /* HAVE_LIBELF_SUPPORT */"
> >
> > -echo "#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))"
> > +echo "#if defined(HAVE_LIBTRACEEVENT)"
> >  sed -n -e 's/^perf-\([^        ]*\)[   ].* audit*/\1/p' command-list.txt |
> >  sort |
> >  while read cmd
> > @@ -51,7 +51,7 @@ do
> >             p
> >       }' "Documentation/perf-$cmd.txt"
> >  done
> > -echo "#endif /* HAVE_LIBTRACEEVENT && (HAVE_LIBAUDIT_SUPPORT || HAVE_SYSCALL_TABLE_SUPPORT) */"
> > +echo "#endif /* HAVE_LIBTRACEEVENT */"
> >
> >  echo "#ifdef HAVE_LIBTRACEEVENT"
> >  sed -n -e 's/^perf-\([^        ]*\)[   ].* traceevent.*/\1/p' command-list.txt |
> > diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
> > index 210f61b0a7a264a427ebb602185d3a9da2f426f4..928aca4cd6e9f2f26c5c4fd825b4538c064a4cc3 100644
> > --- a/tools/perf/util/syscalltbl.c
> > +++ b/tools/perf/util/syscalltbl.c
> > @@ -10,20 +10,12 @@
> >  #include <linux/compiler.h>
> >  #include <linux/zalloc.h>
> >
> > -#ifdef HAVE_SYSCALL_TABLE_SUPPORT
> >  #include <string.h>
> >  #include "string2.h"
> >
> > -#if defined(GENERIC_SYSCALL_TABLE)
> >  #include <syscall_table.h>
> >  const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
> >  static const char *const *syscalltbl_native = syscalltbl;
> > -#else
> > -const int syscalltbl_native_max_id = 0;
> > -static const char *const syscalltbl_native[] = {
> > -       [0] = "unknown",
> > -};
> > -#endif
> >
> >  struct syscall {
> >         int id;
> > @@ -131,47 +123,3 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
> >         *idx = -1;
> >         return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
> >  }
> > -
> > -#else /* HAVE_SYSCALL_TABLE_SUPPORT */
> > -
> > -#include <libaudit.h>
> > -
> > -struct syscalltbl *syscalltbl__new(void)
> > -{
> > -       struct syscalltbl *tbl = zalloc(sizeof(*tbl));
> > -       if (tbl)
> > -               tbl->audit_machine = audit_detect_machine();
> 
> struct syscalltbl's audit_machine is now unused, remove?

Good point, thank you! Will remove in next version.

- Charlie

> 
> Thanks,
> Ian
> 
> > -       return tbl;
> > -}
> > -
> > -void syscalltbl__delete(struct syscalltbl *tbl)
> > -{
> > -       free(tbl);
> > -}
> > -
> > -const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
> > -{
> > -       return audit_syscall_to_name(id, tbl->audit_machine);
> > -}
> > -
> > -int syscalltbl__id(struct syscalltbl *tbl, const char *name)
> > -{
> > -       return audit_name_to_syscall(name, tbl->audit_machine);
> > -}
> > -
> > -int syscalltbl__id_at_idx(struct syscalltbl *tbl __maybe_unused, int idx)
> > -{
> > -       return idx;
> > -}
> > -
> > -int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
> > -                                 const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
> > -{
> > -       return -1;
> > -}
> > -
> > -int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
> > -{
> > -       return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
> > -}
> > -#endif /* HAVE_SYSCALL_TABLE_SUPPORT */
> >
> > --
> > 2.34.1
> >


From festevam at gmail.com  Tue Dec 17 16:02:32 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 17 Dec 2024 21:02:32 -0300
Subject: [PATCH v2] ARM: dts: imx: Use the correct mdio pattern
Message-ID: <20241218000232.74643-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

mdio-gpio is not a valid pattern according to mdio-gpio.yaml.

Use the generic 'mdio' name to fix the following dt-schema warnings:

'mdio-gpio' does not match '^mdio(-(bus|external))?(@.+|-([0-9]+))?$'

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
Changes since v1:
- Fix the Subject.

 arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts      | 2 +-
 arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi       | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
index 7cd17b43b4b2..06545a6052f7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
@@ -160,7 +160,7 @@ eeprom at 0 {
 		};
 	};
 
-	mdio_gpio: mdio-gpio {
+	mdio_gpio: mdio {
 		compatible = "virtual,mdio-gpio";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_swmdio>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts b/arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts
index 625f9ac671ae..26eb7a9506e4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx51-zii-scu2-mezz.dts
@@ -37,7 +37,7 @@ usb_vbus: regulator-usb-vbus {
 		regulator-max-microvolt = <5000000>;
 	};
 
-	mdio_gpio: mdio-gpio {
+	mdio_gpio: mdio {
 		compatible = "virtual,mdio-gpio";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_swmdio>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi
index c1ae7c47b442..aa1adcc74019 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi
@@ -94,7 +94,7 @@ aliases {
 		mdio-gpio0 = &mdio0;
 	};
 
-	mdio0: mdio-gpio {
+	mdio0: mdio {
 		compatible = "virtual,mdio-gpio";
 		gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>, /* mdc */
 			<&gpio2 7 GPIO_ACTIVE_HIGH>; /* mdio */
-- 
2.34.1



From irogers at google.com  Tue Dec 17 16:03:29 2024
From: irogers at google.com (Ian Rogers)
Date: Tue, 17 Dec 2024 16:03:29 -0800
Subject: [PATCH v3 00/16] perf tools: Use generic syscall scripts for all archs
In-Reply-To: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
Message-ID: <CAP-5=fWEUq_nLx7PUx96ixMrX0NqqF8W0EmXV9Zvc449zj0Z7A@mail.gmail.com>

On Mon, Dec 16, 2024 at 10:39?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
>
> Standardize the generation of syscall headers around syscall tables.
> Previously each architecture independently selected how syscall headers
> would be generated, or would not define a way and fallback onto
> libaudit. Convert all architectures to use a standard syscall header
> generation script and allow each architecture to override the syscall
> table to use if they do not use the generic table.
>
> As a result of these changes, no architecture will require libaudit, and
> so the fallback case of using libaudit is removed by this series.
>
> Testing:
>
> I have tested that the syscall mappings of id to name generation works
> as expected for every architecture, but I have only validated that perf
> trace compiles and runs as expected on riscv, arm64, and x86_64.
>
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>

This is really great, thanks for taking the time for a substantial
clean up. I had difficulty applying the patches to the perf-tools-next
branch:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/log/?h=perf-tools-next
using patch and dealing with rejects I was able to test.

Reviewed-by: Ian Rogers <irogers at google.com>
On x86-64:
Tested-by: Ian Rogers <irogers at google.com>

I think there are follow up patches that clean up the ABI, allow >1
table at a time, .. but those things are best saved for a follow up.

Thanks,
Ian

> ---
> Changes in v3:
> - Fix compiliation when OUTPUT is empty
> - Correct unused headers to be .h instead of .c  (Namhyung)
> - Make variable definition of supported archs (Namhyung)
> - Convert += into := for syscalls headers (Namhyung)
> - Link to v2: https://lore.kernel.org/r/20241212-perf_syscalltbl-v2-0-f8ca984ffe40 at rivosinc.com
>
> Changes in v2:
> - Rebase onto 6.13-rc2
> - Fix output path so it generates to /tools/perf/arch properly
> - Link to v1: https://lore.kernel.org/r/20241104-perf_syscalltbl-v1-0-9adae5c761ef at rivosinc.com
>
> ---
> Charlie Jenkins (16):
>       perf tools: Create generic syscall table support
>       perf tools: arc: Support generic syscall headers
>       perf tools: csky: Support generic syscall headers
>       perf tools: arm: Support syscall headers
>       perf tools: sh: Support syscall headers
>       perf tools: sparc: Support syscall headers
>       perf tools: xtensa: Support syscall header
>       perf tools: x86: Use generic syscall scripts
>       perf tools: alpha: Support syscall header
>       perf tools: parisc: Support syscall header
>       perf tools: arm64: Use syscall table
>       perf tools: loongarch: Use syscall table
>       perf tools: mips: Use generic syscall scripts
>       perf tools: powerpc: Use generic syscall table scripts
>       perf tools: s390: Use generic syscall table scripts
>       perf tools: Remove dependency on libaudit
>
>  Documentation/admin-guide/workload-tracing.rst     |   2 +-
>  tools/build/feature/Makefile                       |   4 -
>  tools/build/feature/test-libaudit.c                |  11 -
>  tools/perf/Documentation/perf-check.txt            |   1 -
>  tools/perf/Makefile.config                         |  39 +-
>  tools/perf/Makefile.perf                           |  12 +-
>  tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
>  .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
>  tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 ++++++++++++++++++++
>  tools/perf/arch/alpha/include/syscall_table.h      |   2 +
>  tools/perf/arch/arc/entry/syscalls/Kbuild          |   2 +
>  .../perf/arch/arc/entry/syscalls/Makefile.syscalls |   3 +
>  tools/perf/arch/arc/include/syscall_table.h        |   2 +
>  tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
>  .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
>  tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 483 +++++++++++++++++++
>  tools/perf/arch/arm/include/syscall_table.h        |   2 +
>  tools/perf/arch/arm64/Makefile                     |  22 -
>  tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
>  .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
>  tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
>  .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++
>  .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
>  tools/perf/arch/arm64/include/syscall_table.h      |   8 +
>  tools/perf/arch/csky/entry/syscalls/Kbuild         |   2 +
>  .../arch/csky/entry/syscalls/Makefile.syscalls     |   3 +
>  tools/perf/arch/csky/include/syscall_table.h       |   2 +
>  tools/perf/arch/loongarch/Makefile                 |  22 -
>  tools/perf/arch/loongarch/entry/syscalls/Kbuild    |   2 +
>  .../loongarch/entry/syscalls/Makefile.syscalls     |   3 +
>  .../arch/loongarch/entry/syscalls/mksyscalltbl     |  45 --
>  tools/perf/arch/loongarch/include/syscall_table.h  |   2 +
>  tools/perf/arch/mips/entry/syscalls/Kbuild         |   2 +
>  .../arch/mips/entry/syscalls/Makefile.syscalls     |   5 +
>  tools/perf/arch/mips/entry/syscalls/mksyscalltbl   |  32 --
>  tools/perf/arch/mips/include/syscall_table.h       |   2 +
>  tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
>  .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
>  tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++
>  tools/perf/arch/parisc/include/syscall_table.h     |   8 +
>  tools/perf/arch/powerpc/Makefile                   |  25 -
>  tools/perf/arch/powerpc/entry/syscalls/Kbuild      |   3 +
>  .../arch/powerpc/entry/syscalls/Makefile.syscalls  |   6 +
>  .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  |  39 --
>  tools/perf/arch/powerpc/include/syscall_table.h    |   8 +
>  tools/perf/arch/riscv/Makefile                     |  22 -
>  tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
>  .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
>  tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 --
>  tools/perf/arch/riscv/include/syscall_table.h      |   8 +
>  tools/perf/arch/s390/Makefile                      |  21 -
>  tools/perf/arch/s390/entry/syscalls/Kbuild         |   2 +
>  .../arch/s390/entry/syscalls/Makefile.syscalls     |   5 +
>  tools/perf/arch/s390/entry/syscalls/mksyscalltbl   |  32 --
>  tools/perf/arch/s390/include/syscall_table.h       |   2 +
>  tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
>  .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
>  tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 472 +++++++++++++++++++
>  tools/perf/arch/sh/include/syscall_table.h         |   2 +
>  tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
>  .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
>  tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 514 +++++++++++++++++++++
>  tools/perf/arch/sparc/include/syscall_table.h      |   8 +
>  tools/perf/arch/x86/Build                          |   1 -
>  tools/perf/arch/x86/Makefile                       |  25 -
>  tools/perf/arch/x86/entry/syscalls/Kbuild          |   3 +
>  .../perf/arch/x86/entry/syscalls/Makefile.syscalls |   6 +
>  tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   |  42 --
>  tools/perf/arch/x86/include/syscall_table.h        |   8 +
>  tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
>  .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
>  tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 439 ++++++++++++++++++
>  tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
>  tools/perf/builtin-check.c                         |   1 -
>  tools/perf/builtin-help.c                          |   2 -
>  tools/perf/builtin-trace.c                         |  30 --
>  tools/perf/check-headers.sh                        |   9 +
>  tools/perf/perf.c                                  |   6 +-
>  tools/perf/scripts/Makefile.syscalls               |  61 +++
>  tools/perf/scripts/syscalltbl.sh                   |  86 ++++
>  tools/perf/tests/make                              |   7 +-
>  tools/perf/util/env.c                              |   4 +-
>  tools/perf/util/generate-cmdlist.sh                |   4 +-
>  tools/perf/util/syscalltbl.c                       |  90 +---
>  tools/scripts/syscall.tbl                          | 409 ++++++++++++++++
>  85 files changed, 4102 insertions(+), 619 deletions(-)
> ---
> base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
> change-id: 20240913-perf_syscalltbl-6f98defcc6f5
> --
> - Charlie
>


From paul at os.amperecomputing.com  Tue Dec 17 16:13:38 2024
From: paul at os.amperecomputing.com (Paul Benoit)
Date: Tue, 17 Dec 2024 16:13:38 -0800
Subject: [PATCH v3] firmware: smccc: Support optional Arm SMC SOC_ID name
In-Reply-To: <20241114030452.10149-1-paul@os.amperecomputing.com>
References: <20241114030452.10149-1-paul@os.amperecomputing.com>
Message-ID: <20241218001338.6247-1-paul@os.amperecomputing.com>

Issue Number 1.6 of the Arm SMC Calling Convention introduces an
optional SOC_ID name string.  If available, point the 'machine' field of
the SoC Device Attributes at this string so that it will appear under
/sys/bus/soc/devices/soc0/machine.  On Arm SMC compliant SoCs, this will
allow things like 'lscpu' to eventually get a SoC provider model name
from there rather than each tool/utility needing to get a possibly
inconsistent, obsolete, or incorrect model/machine name from its own
hardcoded model/machine name table.

Signed-off-by: Paul Benoit <paul at os.amperecomputing.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
---

v2->v3: Add conditionalization to exclude SOC_ID Name from 32-bit builds.
v1->v2: Address code review identified issues.

 drivers/firmware/smccc/soc_id.c | 79 +++++++++++++++++++++++++++++++++
 include/linux/arm-smccc.h       | 37 +++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/drivers/firmware/smccc/soc_id.c b/drivers/firmware/smccc/soc_id.c
index 1990263fbba0..3b50ff5d2cbd 100644
--- a/drivers/firmware/smccc/soc_id.c
+++ b/drivers/firmware/smccc/soc_id.c
@@ -32,6 +32,12 @@
 static struct soc_device *soc_dev;
 static struct soc_device_attribute *soc_dev_attr;
 
+static char __init *smccc_soc_name_init(void);
+
+#ifdef CONFIG_ARM64
+static char __ro_after_init smccc_soc_id_name[136] = "";
+#endif
+
 static int __init smccc_soc_init(void)
 {
 	int soc_id_rev, soc_id_version;
@@ -72,6 +78,7 @@ static int __init smccc_soc_init(void)
 	soc_dev_attr->soc_id = soc_id_str;
 	soc_dev_attr->revision = soc_id_rev_str;
 	soc_dev_attr->family = soc_id_jep106_id_str;
+	soc_dev_attr->machine = smccc_soc_name_init();
 
 	soc_dev = soc_device_register(soc_dev_attr);
 	if (IS_ERR(soc_dev)) {
@@ -93,3 +100,75 @@ static void __exit smccc_soc_exit(void)
 	kfree(soc_dev_attr);
 }
 module_exit(smccc_soc_exit);
+
+
+#ifdef CONFIG_ARM64
+static inline void str_fragment_from_reg(char *dst, unsigned long reg)
+{
+	dst[0] = (reg >> 0)  & 0xff;
+	dst[1] = (reg >> 8)  & 0xff;
+	dst[2] = (reg >> 16) & 0xff;
+	dst[3] = (reg >> 24) & 0xff;
+	dst[4] = (reg >> 32) & 0xff;
+	dst[5] = (reg >> 40) & 0xff;
+	dst[6] = (reg >> 48) & 0xff;
+	dst[7] = (reg >> 56) & 0xff;
+}
+#endif
+
+static char __init *smccc_soc_name_init(void)
+{
+#ifdef CONFIG_ARM64
+	struct arm_smccc_1_2_regs args;
+	struct arm_smccc_1_2_regs res;
+	size_t len;
+
+	/*
+	 * Issue Number 1.6 of the Arm SMC Calling Convention
+	 * specification introduces an optional "name" string
+	 * to the ARM_SMCCC_ARCH_SOC_ID function.  Fetch it if
+	 * available.
+	 */
+	args.a0 = ARM_SMCCC_ARCH_SOC_ID;
+	args.a1 = 2;    /* SOC_ID name */
+	arm_smccc_1_2_invoke(&args, &res);
+	if ((u32)res.a0 == 0) {
+		const unsigned int regsize = sizeof(res.a1);
+
+		/*
+		 * Copy res.a1..res.a17 to the smccc_soc_id_name string
+		 * 8 bytes at a time.  As per Issue 1.6 of the Arm SMC
+		 * Calling Convention, the string will be NUL terminated
+		 * and padded, from the end of the string to the end of the
+		 * 136 byte buffer, with NULs.
+		 */
+		str_fragment_from_reg(smccc_soc_id_name + 0*regsize, res.a1);
+		str_fragment_from_reg(smccc_soc_id_name + 1*regsize, res.a2);
+		str_fragment_from_reg(smccc_soc_id_name + 2*regsize, res.a3);
+		str_fragment_from_reg(smccc_soc_id_name + 3*regsize, res.a4);
+		str_fragment_from_reg(smccc_soc_id_name + 4*regsize, res.a5);
+		str_fragment_from_reg(smccc_soc_id_name + 5*regsize, res.a6);
+		str_fragment_from_reg(smccc_soc_id_name + 6*regsize, res.a7);
+		str_fragment_from_reg(smccc_soc_id_name + 7*regsize, res.a8);
+		str_fragment_from_reg(smccc_soc_id_name + 8*regsize, res.a9);
+		str_fragment_from_reg(smccc_soc_id_name + 9*regsize, res.a10);
+		str_fragment_from_reg(smccc_soc_id_name + 10*regsize, res.a11);
+		str_fragment_from_reg(smccc_soc_id_name + 11*regsize, res.a12);
+		str_fragment_from_reg(smccc_soc_id_name + 12*regsize, res.a13);
+		str_fragment_from_reg(smccc_soc_id_name + 13*regsize, res.a14);
+		str_fragment_from_reg(smccc_soc_id_name + 14*regsize, res.a15);
+		str_fragment_from_reg(smccc_soc_id_name + 15*regsize, res.a16);
+		str_fragment_from_reg(smccc_soc_id_name + 16*regsize, res.a17);
+
+		len = strnlen(smccc_soc_id_name, sizeof(smccc_soc_id_name));
+		if (len) {
+			if (len == sizeof(smccc_soc_id_name))
+				pr_warn(FW_BUG "Ignoring improperly formatted Name\n");
+			else
+				return smccc_soc_id_name;
+		}
+	}
+#endif
+
+	return NULL;
+}
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 67f6fdf2e7cd..9d444e5862fe 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -607,6 +607,12 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 			___res->a0 = SMCCC_RET_NOT_SUPPORTED;		\
 	} while (0)
 
+#define __fail_smccc_1_2(___res)					\
+	do {								\
+		if (___res)						\
+			___res->a0 = SMCCC_RET_NOT_SUPPORTED;		\
+	} while (0)
+
 /*
  * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
  *
@@ -639,5 +645,36 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 		method;							\
 	})
 
+/*
+ * arm_smccc_1_2_invoke() - make an SMCCC v1.2 compliant call
+ *
+ * @args: SMC args are in the a0..a17 fields of the arm_smcc_1_2_regs structure
+ * @res: result values from registers 0 to 17
+ *
+ * This macro will make either an HVC call or an SMC call depending on the
+ * current SMCCC conduit. If no valid conduit is available then -1
+ * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
+ *
+ * The return value also provides the conduit that was used.
+ */
+#define arm_smccc_1_2_invoke(args, res) ({				\
+		struct arm_smccc_1_2_regs *__args = args;		\
+		struct arm_smccc_1_2_regs *__res = res;			\
+		int method = arm_smccc_1_1_get_conduit();		\
+		switch (method) {					\
+		case SMCCC_CONDUIT_HVC:					\
+			arm_smccc_1_2_hvc(__args, __res);		\
+			break;						\
+		case SMCCC_CONDUIT_SMC:					\
+			arm_smccc_1_2_smc(__args, __res);		\
+			break;						\
+		default:						\
+			__fail_smccc_1_2(__res);			\
+			method = SMCCC_CONDUIT_NONE;			\
+			break;						\
+		}							\
+		method;							\
+	})
+
 #endif /*__ASSEMBLY__*/
 #endif /*__LINUX_ARM_SMCCC_H*/
-- 
2.47.0



From irogers at google.com  Tue Dec 17 16:54:19 2024
From: irogers at google.com (Ian Rogers)
Date: Tue, 17 Dec 2024 16:54:19 -0800
Subject: [PATCH 5/5] perf docs: arm_spe: Document new discard mode
In-Reply-To: <20241217115610.371755-6-james.clark@linaro.org>
References: <20241217115610.371755-1-james.clark@linaro.org> <20241217115610.371755-6-james.clark@linaro.org>
Message-ID: <CAP-5=fU7RNzvzxBcAQy3RT9Ge3YtqPhDonupNWS7Wgb8HGQkGg@mail.gmail.com>

On Tue, Dec 17, 2024 at 3:56?AM James Clark <james.clark at linaro.org> wrote:
>
> Document the flag, hint what it's used for and give an example with
> other useful options to get minimal output.
>
> Signed-off-by: James Clark <james.clark at linaro.org>
> ---
>  tools/perf/Documentation/perf-arm-spe.txt | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/tools/perf/Documentation/perf-arm-spe.txt b/tools/perf/Documentation/perf-arm-spe.txt
> index de2b0b479249..588eead438bc 100644
> --- a/tools/perf/Documentation/perf-arm-spe.txt
> +++ b/tools/perf/Documentation/perf-arm-spe.txt
> @@ -150,6 +150,7 @@ arm_spe/load_filter=1,min_latency=10/'
>    pct_enable=1        - collect physical timestamp instead of virtual timestamp (PMSCR.PCT) - requires privilege
>    store_filter=1      - collect stores only (PMSFCR.ST)
>    ts_enable=1         - enable timestamping with value of generic timer (PMSCR.TS)
> +  discard=1           - enable SPE PMU events but don't collect sample data - see 'Discard mode' (PMBLIMITR.FM = DISCARD)
>
>  +++*+++ Latency is the total latency from the point at which sampling started on that instruction, rather
>  than only the execution latency.
> @@ -220,6 +221,16 @@ Common errors
>
>     Increase sampling interval (see above)
>
> +Discard mode
> +~~~~~~~~~~~~
> +
> +SPE PMU events can be used without the overhead of collecting sample data if
> +discard mode is supported (optional from Armv8.6). First run a system wide SPE
> +session (or on the core of interest) using options to minimize output. Then run
> +perf stat:
> +
> +  perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
> +  perf stat -e SAMPLE_FEED_LD

Perhaps clarify this should be an ARM SPE event? It seems strange to
have one perf command affect a later one, the purpose of things like
event multiplexing is to hide the hardware limits. I'd prefer if the
last bit was like:
```
Then run perf stat with an SPE event on the same PMU:

perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
perf stat -e arm_spe/SAMPLE_FEED_LD/
``

Thanks,
Ian


From andyshrk at 163.com  Tue Dec 17 16:55:48 2024
From: andyshrk at 163.com (Andy Yan)
Date: Wed, 18 Dec 2024 08:55:48 +0800 (CST)
Subject: [PATCH v6 08/16] drm/rockchip: vop2: Support 32x8
 superblock afbc
In-Reply-To: <CAPj87rMfFXkbyh7UEJQw4JV1R18KLXC3GyF0CznrN1k3UdL0Lw@mail.gmail.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
 <20241214081719.3330518-9-andyshrk@163.com>
 <CAPj87rOjqZdyht2y8MK7gVyk_eqEzk1Sy0DcxFtQRuhrHQ_oxA@mail.gmail.com>
 <165af58a.697.193d2100239.Coremail.andyshrk@163.com>
 <CAPj87rMfFXkbyh7UEJQw4JV1R18KLXC3GyF0CznrN1k3UdL0Lw@mail.gmail.com>
Message-ID: <32246002.9ef.193d7438b96.Coremail.andyshrk@163.com>


Hi  Daniel,

At 2024-12-17 20:07:54, "Daniel Stone" <daniel at fooishbar.org> wrote:
>Hi Andy,
>
>On Tue, 17 Dec 2024 at 00:41, Andy Yan <andyshrk at 163.com> wrote:
>> At 2024-12-16 21:06:07, "Daniel Stone" <daniel at fooishbar.org> wrote:
>> >On Sat, 14 Dec 2024 at 08:18, Andy Yan <andyshrk at 163.com> wrote:
>> >> This is the only afbc format supported by the upcoming
>> >> VOP for rk3576.
>> >>
>> >> Add support for it.
>> >
>> >Out of interest, how was this tested? There is no 32x8 modifier in the
>> >format list in format_modifiers_afbc[], so it seems like it shouldn't
>> >be possible to get a 32x8 buffer on a plane at all.
>>
>> The 32x8 modifier  added in PATCH 16/16:
>>
>> +/* used from rk3576, afbc 32*8 half mode */
>> +static const uint64_t format_modifiers_rk3576_afbc[] = {
>> +       DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
>> +                               AFBC_FORMAT_MOD_SPLIT),
>> +
>
>Hmmm, that's strange; I applied the whole series with b4 but wasn't
>seeing that block defined. Maybe a bad conflict resolution. Sorry for
>the confusion.

I think that might have been caused by my mistake. I initially sent the V6 version as a -in-reply to the V5 version.
When I realized the mistake, a part of it had already been sent out. Then I sent the entire V6 series separately
again. Maybe that make b4 and lore confused?

>
>> I write an ovltest[0] tool which can take linear/AFBC rgb/yuv data from a file, then
>> commit to drm driver, I use this tool for most basic format test.
>>
>> But when tested on weston, I found that weston does not use the AFBC format for display,
>> don't know why.
>
>You'll need a Mesa tree with e0f48568c7f2 included; if you have this
>then it should just work out of the box.

Thanks, I will check it.

>
>Cheers,
>Daniel

From charlie at rivosinc.com  Tue Dec 17 17:11:09 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Tue, 17 Dec 2024 17:11:09 -0800
Subject: [PATCH v3 00/16] perf tools: Use generic syscall scripts for all
 archs
In-Reply-To: <CAP-5=fWEUq_nLx7PUx96ixMrX0NqqF8W0EmXV9Zvc449zj0Z7A@mail.gmail.com>
References: <20241216-perf_syscalltbl-v3-0-239f032481d5@rivosinc.com>
 <CAP-5=fWEUq_nLx7PUx96ixMrX0NqqF8W0EmXV9Zvc449zj0Z7A@mail.gmail.com>
Message-ID: <Z2IhLZ8mfTWvbCvI@ghost>

On Tue, Dec 17, 2024 at 04:03:29PM -0800, Ian Rogers wrote:
> On Mon, Dec 16, 2024 at 10:39?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
> >
> > Standardize the generation of syscall headers around syscall tables.
> > Previously each architecture independently selected how syscall headers
> > would be generated, or would not define a way and fallback onto
> > libaudit. Convert all architectures to use a standard syscall header
> > generation script and allow each architecture to override the syscall
> > table to use if they do not use the generic table.
> >
> > As a result of these changes, no architecture will require libaudit, and
> > so the fallback case of using libaudit is removed by this series.
> >
> > Testing:
> >
> > I have tested that the syscall mappings of id to name generation works
> > as expected for every architecture, but I have only validated that perf
> > trace compiles and runs as expected on riscv, arm64, and x86_64.
> >
> > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> 
> This is really great, thanks for taking the time for a substantial
> clean up. I had difficulty applying the patches to the perf-tools-next
> branch:
> https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/log/?h=perf-tools-next
> using patch and dealing with rejects I was able to test.
> 
> Reviewed-by: Ian Rogers <irogers at google.com>
> On x86-64:
> Tested-by: Ian Rogers <irogers at google.com>

Thank you! I will base my next version on perf-tools-next.

- Charlie

> 
> I think there are follow up patches that clean up the ABI, allow >1
> table at a time, .. but those things are best saved for a follow up.
> 
> Thanks,
> Ian
> 
> > ---
> > Changes in v3:
> > - Fix compiliation when OUTPUT is empty
> > - Correct unused headers to be .h instead of .c  (Namhyung)
> > - Make variable definition of supported archs (Namhyung)
> > - Convert += into := for syscalls headers (Namhyung)
> > - Link to v2: https://lore.kernel.org/r/20241212-perf_syscalltbl-v2-0-f8ca984ffe40 at rivosinc.com
> >
> > Changes in v2:
> > - Rebase onto 6.13-rc2
> > - Fix output path so it generates to /tools/perf/arch properly
> > - Link to v1: https://lore.kernel.org/r/20241104-perf_syscalltbl-v1-0-9adae5c761ef at rivosinc.com
> >
> > ---
> > Charlie Jenkins (16):
> >       perf tools: Create generic syscall table support
> >       perf tools: arc: Support generic syscall headers
> >       perf tools: csky: Support generic syscall headers
> >       perf tools: arm: Support syscall headers
> >       perf tools: sh: Support syscall headers
> >       perf tools: sparc: Support syscall headers
> >       perf tools: xtensa: Support syscall header
> >       perf tools: x86: Use generic syscall scripts
> >       perf tools: alpha: Support syscall header
> >       perf tools: parisc: Support syscall header
> >       perf tools: arm64: Use syscall table
> >       perf tools: loongarch: Use syscall table
> >       perf tools: mips: Use generic syscall scripts
> >       perf tools: powerpc: Use generic syscall table scripts
> >       perf tools: s390: Use generic syscall table scripts
> >       perf tools: Remove dependency on libaudit
> >
> >  Documentation/admin-guide/workload-tracing.rst     |   2 +-
> >  tools/build/feature/Makefile                       |   4 -
> >  tools/build/feature/test-libaudit.c                |  11 -
> >  tools/perf/Documentation/perf-check.txt            |   1 -
> >  tools/perf/Makefile.config                         |  39 +-
> >  tools/perf/Makefile.perf                           |  12 +-
> >  tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
> >  .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
> >  tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 ++++++++++++++++++++
> >  tools/perf/arch/alpha/include/syscall_table.h      |   2 +
> >  tools/perf/arch/arc/entry/syscalls/Kbuild          |   2 +
> >  .../perf/arch/arc/entry/syscalls/Makefile.syscalls |   3 +
> >  tools/perf/arch/arc/include/syscall_table.h        |   2 +
> >  tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
> >  .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
> >  tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 483 +++++++++++++++++++
> >  tools/perf/arch/arm/include/syscall_table.h        |   2 +
> >  tools/perf/arch/arm64/Makefile                     |  22 -
> >  tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
> >  .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
> >  tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
> >  .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++
> >  .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
> >  tools/perf/arch/arm64/include/syscall_table.h      |   8 +
> >  tools/perf/arch/csky/entry/syscalls/Kbuild         |   2 +
> >  .../arch/csky/entry/syscalls/Makefile.syscalls     |   3 +
> >  tools/perf/arch/csky/include/syscall_table.h       |   2 +
> >  tools/perf/arch/loongarch/Makefile                 |  22 -
> >  tools/perf/arch/loongarch/entry/syscalls/Kbuild    |   2 +
> >  .../loongarch/entry/syscalls/Makefile.syscalls     |   3 +
> >  .../arch/loongarch/entry/syscalls/mksyscalltbl     |  45 --
> >  tools/perf/arch/loongarch/include/syscall_table.h  |   2 +
> >  tools/perf/arch/mips/entry/syscalls/Kbuild         |   2 +
> >  .../arch/mips/entry/syscalls/Makefile.syscalls     |   5 +
> >  tools/perf/arch/mips/entry/syscalls/mksyscalltbl   |  32 --
> >  tools/perf/arch/mips/include/syscall_table.h       |   2 +
> >  tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
> >  .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
> >  tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++
> >  tools/perf/arch/parisc/include/syscall_table.h     |   8 +
> >  tools/perf/arch/powerpc/Makefile                   |  25 -
> >  tools/perf/arch/powerpc/entry/syscalls/Kbuild      |   3 +
> >  .../arch/powerpc/entry/syscalls/Makefile.syscalls  |   6 +
> >  .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  |  39 --
> >  tools/perf/arch/powerpc/include/syscall_table.h    |   8 +
> >  tools/perf/arch/riscv/Makefile                     |  22 -
> >  tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
> >  .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
> >  tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 --
> >  tools/perf/arch/riscv/include/syscall_table.h      |   8 +
> >  tools/perf/arch/s390/Makefile                      |  21 -
> >  tools/perf/arch/s390/entry/syscalls/Kbuild         |   2 +
> >  .../arch/s390/entry/syscalls/Makefile.syscalls     |   5 +
> >  tools/perf/arch/s390/entry/syscalls/mksyscalltbl   |  32 --
> >  tools/perf/arch/s390/include/syscall_table.h       |   2 +
> >  tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
> >  .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
> >  tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 472 +++++++++++++++++++
> >  tools/perf/arch/sh/include/syscall_table.h         |   2 +
> >  tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
> >  .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
> >  tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 514 +++++++++++++++++++++
> >  tools/perf/arch/sparc/include/syscall_table.h      |   8 +
> >  tools/perf/arch/x86/Build                          |   1 -
> >  tools/perf/arch/x86/Makefile                       |  25 -
> >  tools/perf/arch/x86/entry/syscalls/Kbuild          |   3 +
> >  .../perf/arch/x86/entry/syscalls/Makefile.syscalls |   6 +
> >  tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   |  42 --
> >  tools/perf/arch/x86/include/syscall_table.h        |   8 +
> >  tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
> >  .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
> >  tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 439 ++++++++++++++++++
> >  tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
> >  tools/perf/builtin-check.c                         |   1 -
> >  tools/perf/builtin-help.c                          |   2 -
> >  tools/perf/builtin-trace.c                         |  30 --
> >  tools/perf/check-headers.sh                        |   9 +
> >  tools/perf/perf.c                                  |   6 +-
> >  tools/perf/scripts/Makefile.syscalls               |  61 +++
> >  tools/perf/scripts/syscalltbl.sh                   |  86 ++++
> >  tools/perf/tests/make                              |   7 +-
> >  tools/perf/util/env.c                              |   4 +-
> >  tools/perf/util/generate-cmdlist.sh                |   4 +-
> >  tools/perf/util/syscalltbl.c                       |  90 +---
> >  tools/scripts/syscall.tbl                          | 409 ++++++++++++++++
> >  85 files changed, 4102 insertions(+), 619 deletions(-)
> > ---
> > base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
> > change-id: 20240913-perf_syscalltbl-6f98defcc6f5
> > --
> > - Charlie
> >


From andyshrk at 163.com  Tue Dec 17 17:36:21 2024
From: andyshrk at 163.com (Andy Yan)
Date: Wed, 18 Dec 2024 09:36:21 +0800 (CST)
Subject: [PATCH v2 3/5] drm/rockchip: vop2: Improve display modes
 handling on RK3588 HDMI0
In-Reply-To: <2ba24dc6-b6e7-4964-af84-a5374903ce36@collabora.com>
References: <20241211-vop2-hdmi0-disp-modes-v2-0-471cf5001e45@collabora.com>
 <1820767.5KxKD5qtyk@diego>
 <a4ex3s23r4k6wehyoaw3aylpcexfrclrxxykjpabhdfne2jgmu@ii6riiiga2zj>
 <1756448.izSxrag8PF@diego>
 <20241217-ubiquitous-refreshing-finch-aceade@houat>
 <c45ff74a-c9a4-4cf1-8530-04087e06b07a@collabora.com>
 <20241217-zealous-boisterous-llama-52bfcc@houat>
 <2ba24dc6-b6e7-4964-af84-a5374903ce36@collabora.com>
Message-ID: <8dff095.1555.193d768ad5e.Coremail.andyshrk@163.com>


Hi,

? 2024-12-18 00:59:57?"Cristian Ciocaltea" <cristian.ciocaltea at collabora.com> ???
>On 12/17/24 6:53 PM, Maxime Ripard wrote:
>> On Tue, Dec 17, 2024 at 06:36:41PM +0200, Cristian Ciocaltea wrote:
>>> On 12/17/24 5:00 PM, Maxime Ripard wrote:
>>>> On Wed, Dec 11, 2024 at 07:01:15PM +0100, Heiko St?bner wrote:
>>>>> Am Mittwoch, 11. Dezember 2024, 18:47:44 CET schrieb Maxime Ripard:
>>>>>> On Wed, Dec 11, 2024 at 06:23:03PM +0100, Heiko St?bner wrote:
>>>>>>> Am Mittwoch, 11. Dezember 2024, 18:07:57 CET schrieb Maxime Ripard:
>>>>>>>> On Wed, Dec 11, 2024 at 12:15:07PM +0200, Cristian Ciocaltea wrote:
>>>>>>>>> The RK3588 specific implementation is currently quite limited in terms
>>>>>>>>> of handling the full range of display modes supported by the connected
>>>>>>>>> screens, e.g. 2560x1440 at 75Hz, 2048x1152 at 60Hz, 1024x768 at 60Hz are just a
>>>>>>>>> few of them.
>>>>>>>>>
>>>>>>>>> Additionally, it doesn't cope well with non-integer refresh rates like
>>>>>>>>> 59.94, 29.97, 23.98, etc.
>>>>>>>>>
>>>>>>>>> Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
>>>>>>>>> all display modes up to 4K at 60Hz.
>>>>>>>>>
>>>>>>>>> Tested-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>>>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
>>>>>>>>> ---
>>>>>>>>>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 34 ++++++++++++++++++++++++++++
>>>>>>>>>  1 file changed, 34 insertions(+)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>>>>>>>>> index 8b2f53ffefdbf1cc8737b3a86e630a03a7fd9348..393fe6aa170aaee9663c4a6d98c1cd6a5ef79392 100644
>>>>>>>>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>>>>>>>>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>>>>>>>>> @@ -158,6 +158,7 @@ struct vop2_video_port {
>>>>>>>>>  	struct drm_crtc crtc;
>>>>>>>>>  	struct vop2 *vop2;
>>>>>>>>>  	struct clk *dclk;
>>>>>>>>> +	struct clk *dclk_src;
>>>>>>>>>  	unsigned int id;
>>>>>>>>>  	const struct vop2_video_port_data *data;
>>>>>>>>>  
>>>>>>>>> @@ -212,6 +213,7 @@ struct vop2 {
>>>>>>>>>  	struct clk *hclk;
>>>>>>>>>  	struct clk *aclk;
>>>>>>>>>  	struct clk *pclk;
>>>>>>>>> +	struct clk *pll_hdmiphy0;
>>>>>>>>>  
>>>>>>>>>  	/* optional internal rgb encoder */
>>>>>>>>>  	struct rockchip_rgb *rgb;
>>>>>>>>> @@ -220,6 +222,8 @@ struct vop2 {
>>>>>>>>>  	struct vop2_win win[];
>>>>>>>>>  };
>>>>>>>>>  
>>>>>>>>> +#define VOP2_MAX_DCLK_RATE		600000 /* kHz */
>>>>>>>>> +
>>>>>>>>>  #define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
>>>>>>>>>  					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
>>>>>>>>>  
>>>>>>>>> @@ -1033,6 +1037,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
>>>>>>>>>  
>>>>>>>>>  	vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
>>>>>>>>>  
>>>>>>>>> +	if (vp->dclk_src)
>>>>>>>>> +		clk_set_parent(vp->dclk, vp->dclk_src);
>>>>>>>>> +
>>>>>>>>>  	clk_disable_unprepare(vp->dclk);
>>>>>>>>>  
>>>>>>>>>  	vop2->enable_count--;
>>>>>>>>> @@ -2049,6 +2056,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
>>>>>>>>>  
>>>>>>>>>  	vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
>>>>>>>>>  
>>>>>>>>> +	/*
>>>>>>>>> +	 * Switch to HDMI PHY PLL as DCLK source for display modes up
>>>>>>>>> +	 * to 4K at 60Hz, if available, otherwise keep using the system CRU.
>>>>>>>>> +	 */
>>>>>>>>> +	if (vop2->pll_hdmiphy0 && mode->crtc_clock <= VOP2_MAX_DCLK_RATE) {
>>>>>>>>> +		drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
>>>>>>>>> +			struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
>>>>>>>>> +
>>>>>>>>> +			if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
>>>>>>>>> +				if (!vp->dclk_src)
>>>>>>>>> +					vp->dclk_src = clk_get_parent(vp->dclk);
>>>>>>>>> +
>>>>>>>>> +				ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
>>>>>>>>> +				if (ret < 0)
>>>>>>>>> +					drm_warn(vop2->drm,
>>>>>>>>> +						 "Could not switch to HDMI0 PHY PLL: %d\n", ret);
>>>>>>>>> +				break;
>>>>>>>>> +			}
>>>>>>>>> +		}
>>>>>>>>> +	}
>>>>>>>>> +
>>>>>>>>
>>>>>>>> It seems pretty fragile to do it at atomic_enable time, even more so
>>>>>>>> since you don't lock the parent either.
>>>>>>>>
>>>>>>>> Any reason not to do it in the DRM or clock driver probe, and make sure
>>>>>>>> you never change the parent somehow?
>>>>>>>
>>>>>>> On rk3588 we have 3 dclk_s and 2 hdmi controllers. Each video-port can
>>>>>>> use the clock generated from either the hdmi0phy or hdmi1phy, depending
>>>>>>> on which hdmi-controller it uses.
>>>>>>>
>>>>>>> So you actually need to know which vpX will output to which hdmiY to then
>>>>>>> reparent that dclk to the hdmiphy output.
>>>>>>
>>>>>> The Rockchip nomenclature isn't super obvious to me, sorry. Is there a
>>>>>> datasheet for this somewhere? Also, does this vpX -> HDMI-Y mapping need
>>>>>> to be dynamic?
>>>>>
>>>>> VPs are CRTCs in drm-language and each of them can drive a differing
>>>>> number of output encoders. Those video-ports also have differing output
>>>>> characteristics in terms of supported resolution and other properties.
>>>>>
>>>>> The rk3588 TRM has leaked in a number of places, and if you find a
>>>>> TRM-part2, there is a section labeled "Display Output Interface Description"
>>>>> that has a nice graphic for that.
>>>>>
>>>>> Or in short:
>>>>> - CRTC(VP)0 supports 8K resolution and can drive DP0+1, HDMI0+1, eDP0+1
>>>>>   [if I'm reading things correctly, 8K together with CRTC1 somehow)
>>>>> - CRTC(VP)1 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP0+1
>>>>> - CRTC(VP)2 supports 4K resolution and can drive DP0+1, HDMI0+1, eDP01, DSI0+1
>>>>> - CRTC(VP)3 supports 2K resolution and can drive DSI0+1 and some BT1120,BT656
>>>>>
>>>>> so for the 3 higher resolution CRTCs there are essentially 6 or 8 output options
>>>>> depending on the board design
>>>>
>>>> That's much clearer, thanks. I'm not entirely sure how that links to the
>>>> need for the PLL to change its parent depending on the ouput. Do you
>>>> need to always have all the outputs on the same PLL?
>>>
>>> One of the problems is that the PHY PLLs cannot be used as clock sources
>>> for resolutions above 4K at 60Hz, while VOP2 on RK3588 supports up to 8K at 60Hz,
>>> which is supposed to be handled by the system CRU.
>> 
>> But can that system CRU drive resolutions lower than 4k at 60? If so, why
>> do we bother with PHYs?
>
>It can, but it's not accurate enough to support all modes, e.g. those
>having fractional refresh rates, among others.  That's actually the
>reason we'd want to make use of the PHY PLLs.

Not only that. For resolutions lower than 4k at 60, if we use system cur as dclk parent,
it can't  sync with HDMI TMDS clock , this could lead to stability/compatibility i issues,
which may not be easy to encounter, but we have indeed experienced them  few timems
in a large amount of productization practice.

>
>>> Moreover, the 2 PLLs are shared between 3 out of the 4 video ports already
>>> mentioned by Heiko.  There is quite a bit of complexity in downstream
>>> driver to handle all possible usecases - see [1] for a brief description on
>>> how was that designed to work.
>> 
>> That's a generic allocation issue. Multiple drivers (vc4 for example)
>> has this issue for other components. It can be fairly easily dealt with
>> at atomic_check time.
>> 
>> Maxime
>

From andre.przywara at arm.com  Tue Dec 17 17:38:36 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 18 Dec 2024 01:38:36 +0000
Subject: [PATCH 1/3] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and
 PLL_MIPI
In-Reply-To: <d0bf0d9cd2df65dc2e17eb203d56eb13@manjaro.org>
References: <20241215053639.738890-1-anarsoul@gmail.com>
	<20241215053639.738890-2-anarsoul@gmail.com>
	<qbtp4jvkx3r5azufe4k3vtapqpfs54dyjiu4cy5v5wkkzumrzx@vy3xzkfplbue>
	<CA+E=qVeQ8uHBCeFtw6_2cY3252-YXc6eWrf5_YdeVgbp5LJo5g@mail.gmail.com>
	<20241217211505.7f9c9e4e@minigeek.lan>
	<d0bf0d9cd2df65dc2e17eb203d56eb13@manjaro.org>
Message-ID: <20241218013836.421cc616@minigeek.lan>

On Tue, 17 Dec 2024 23:02:43 +0100
Dragan Simic <dsimic at manjaro.org> wrote:

Hi Dragan,

> Hello all,
> 
> On 2024-12-17 22:15, Andre Przywara wrote:
> > On Tue, 17 Dec 2024 10:00:45 -0800
> > Vasily Khoruzhick <anarsoul at gmail.com> wrote:  
> >> On Mon, Dec 16, 2024 at 11:33?PM Krzysztof Kozlowski <krzk at kernel.org> 
> >> wrote:  
> >> >
> >> > On Sat, Dec 14, 2024 at 09:34:57PM -0800, Vasily Khoruzhick wrote:  
> >> > > These will be used to explicitly select TCON0 clock parent in dts
> >> > >
> >> > > Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
> >> > > Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
> >> > > ---
> >> > >  drivers/clk/sunxi-ng/ccu-sun50i-a64.h      | 2 --
> >> > >  include/dt-bindings/clock/sun50i-a64-ccu.h | 2 +  
> >>   
> >> > You cannot combine these changes.  
> >> 
> >> The patch basically moves defines out from ccu-sun50i-a64.h to
> >> sun50i-a64-ccu.h. How do I split the change without introducing
> >> compilation failure?  
> > 
> > You can just have the binding part first, adding the (same) definition
> > to the binding headers. As long as the #define's are not conflicting,
> > this is fine.
> > Then remove the now redundant definitions in the kernel headers, with a
> > subsequent patch.  
> 
> Yes, that would be a way to make it formally correct, but also much
> less readable and understandable later, as part of the source code
> repository.  FWIW, I find this to be an example of the form being
> more important than the actual function.

Not sure I understand your last sentence, exactly, but what
Krzysztof pointed out is that one part (the header change in
include/dt-bindings) is a DT binding patch, so part of a spec, if you
like, the other is Linux *code*. There is the DT rebasing repo, which
cherry-picks DT patches, so they form a separate history there, and
Linux code has no place in there. U-Boot for instance pull this
repo now on a regular basis. So keeping those things strictly separate
is really important here.

Cheers,
Andre.

> >> > Please run scripts/checkpatch.pl and fix reported warnings. Then please
> >> > run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
> >> > Some warnings can be ignored, especially from --strict run, but the code
> >> > here looks like it needs a fix. Feel free to get in touch if the warning
> >> > is not clear.  
> >> 
> >> Yeah, it is not clear what do you want me to do, assuming the previous
> >> similar change to sun50i-a64-ccu.h did essentially the same, see
> >> 71b597ef5d46a326fb0d5cbfc1c6ff1d73cdc7f9  
> 



From 0x1207 at gmail.com  Tue Dec 17 18:32:10 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Wed, 18 Dec 2024 10:32:10 +0800
Subject: [PATCH net v1] net: stmmac: Drop useless code related to
 ethtool rx-copybreak
In-Reply-To: <20241217163538.GU780307@kernel.org>
References: <20241217091712.383911-1-0x1207@gmail.com>
	<20241217163538.GU780307@kernel.org>
Message-ID: <20241218103210.00000dc4@gmail.com>

On Tue, 17 Dec 2024 16:35:38 +0000, Simon Horman <horms at kernel.org> wrote:

> Based on your description this feels more like an enhancement
> for net-next, without a Fixes tag, than a fix for net.

Thanks, I will send to net-next.

pw-bot: changes-requested


From andyshrk at 163.com  Tue Dec 17 18:42:36 2024
From: andyshrk at 163.com (Andy Yan)
Date: Wed, 18 Dec 2024 10:42:36 +0800 (CST)
Subject: [PATCH v6 08/16] drm/rockchip: vop2: Support 32x8
 superblock afbc
In-Reply-To: <32246002.9ef.193d7438b96.Coremail.andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
 <20241214081719.3330518-9-andyshrk@163.com>
 <CAPj87rOjqZdyht2y8MK7gVyk_eqEzk1Sy0DcxFtQRuhrHQ_oxA@mail.gmail.com>
 <165af58a.697.193d2100239.Coremail.andyshrk@163.com>
 <CAPj87rMfFXkbyh7UEJQw4JV1R18KLXC3GyF0CznrN1k3UdL0Lw@mail.gmail.com>
 <32246002.9ef.193d7438b96.Coremail.andyshrk@163.com>
Message-ID: <3cf0785a.2c2e.193d7a55527.Coremail.andyshrk@163.com>


Hi Daniel,

At 2024-12-18 08:55:48, "Andy Yan" <andyshrk at 163.com> wrote:
>
>Hi  Daniel,
>
>At 2024-12-17 20:07:54, "Daniel Stone" <daniel at fooishbar.org> wrote:
>>Hi Andy,
>>
>>On Tue, 17 Dec 2024 at 00:41, Andy Yan <andyshrk at 163.com> wrote:
>>> At 2024-12-16 21:06:07, "Daniel Stone" <daniel at fooishbar.org> wrote:
>>> >On Sat, 14 Dec 2024 at 08:18, Andy Yan <andyshrk at 163.com> wrote:
>>> >> This is the only afbc format supported by the upcoming
>>> >> VOP for rk3576.
>>> >>
>>> >> Add support for it.
>>> >
>>> >Out of interest, how was this tested? There is no 32x8 modifier in the
>>> >format list in format_modifiers_afbc[], so it seems like it shouldn't
>>> >be possible to get a 32x8 buffer on a plane at all.
>>>
>>> The 32x8 modifier  added in PATCH 16/16:
>>>
>>> +/* used from rk3576, afbc 32*8 half mode */
>>> +static const uint64_t format_modifiers_rk3576_afbc[] = {
>>> +       DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
>>> +                               AFBC_FORMAT_MOD_SPLIT),
>>> +
>>
>>Hmmm, that's strange; I applied the whole series with b4 but wasn't
>>seeing that block defined. Maybe a bad conflict resolution. Sorry for
>>the confusion.
>
>I think that might have been caused by my mistake. I initially sent the V6 version as a -in-reply to the V5 version.
>When I realized the mistake, a part of it had already been sent out. Then I sent the entire V6 series separately
>again. Maybe that make b4 and lore confused?
>
>>
>>> I write an ovltest[0] tool which can take linear/AFBC rgb/yuv data from a file, then
>>> commit to drm driver, I use this tool for most basic format test.
>>>
>>> But when tested on weston, I found that weston does not use the AFBC format for display,
>>> don't know why.
>>
>>You'll need a Mesa tree with e0f48568c7f2 included; if you have this
>>then it should just work out of the box.
>
>Thanks, I will check it.

When update to lasted mesa: GL version: OpenGL ES 3.1 Mesa 25.0.0-devel
I can get 32x8 AFBC output in weston for rk3576:

# cat /sys/kernel/debug/dri/0/vop2/summary 
Video Port0: ACTIVE
    Connector: HDMI-A-1
        bus_format[0]: Unknown
        output_mode[f] color_space[0]
    Display mode: 1920x1080p60
        clk[148500] real_clk[148500] type[48] flag[5]
        H: 1920 2008 2052 2200
        V: 1080 1084 1089 1125
    Cluster0-win0: ACTIVE
        win_id: 0
        format: XR24 little-endian (0x34325258)[AFBC] glb_alpha[0xff]
        rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
        zpos: 0
        src: pos[0, 0] rect[1920 x 1080]
        dst: pos[0, 0] rect[1920 x 1080]
        buf[0]: addr: 0x000000000081a000 pitch: 7680 offset: 0
    Cluster1-win0: ACTIVE
        win_id: 1
        format: AR24 little-endian (0x34325241)[AFBC] glb_alpha[0xff]
        rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
        zpos: 1
        src: pos[0, 0] rect[250 x 250]
        dst: pos[736, 503] rect[250 x 250]
        buf[0]: addr: 0x00000000010b6000 pitch: 1024 offset: 0

301 frames in 5 seconds: 60.200001 fps
302 frames in 5 seconds: 60.400002 fps
300 frames in 5 seconds: 60.000000 fps
301 frames in 5 seconds: 60.200001 fps
>
>>
>>Cheers,
>>Daniel

From kevin_chen at aspeedtech.com  Tue Dec 17 18:50:34 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Wed, 18 Dec 2024 02:50:34 +0000
Subject: [PATCH v3 4/6] arm64: dts: aspeed: Add initial AST27XX device
 tree
In-Reply-To: <dbfe7c42-cc9b-4471-93ed-846260db42e6@kernel.org>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-7-kevin_chen@aspeedtech.com>
 <dbfe7c42-cc9b-4471-93ed-846260db42e6@kernel.org>
Message-ID: <PSAPR06MB49496308CDFF36C38EFEAFAD89052@PSAPR06MB4949.apcprd06.prod.outlook.com>

Hi Krzk,

> > Add aspeed-g7.dtsi to be AST27XX device tree.
> >
> > Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
> 
> Where are all the bindings? Why are you silent about this? The patchset adding
> new SoC DTS, when separate, is supposed to explain where we can find the
> bindings.
Do you mean apseed,ast2700-scu0 and aspeed,ast2700-scu1?
Could I make sure this new SoC DTS how to submit?

Thanks.

> 
> > ---
> >  arch/arm64/boot/dts/Makefile              |   1 +
> >  arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi | 236
> > ++++++++++++++++++++++
> >  2 files changed, 237 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/aspeed/aspeed-g7.
> 
> 
> Best regards,
> Krzysztof

Best Regards,
Kevin. Chen

From kevin_chen at aspeedtech.com  Tue Dec 17 18:55:51 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Wed, 18 Dec 2024 02:55:51 +0000
Subject: [PATCH v3 2/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
In-Reply-To: <7b991fca-6e2f-454f-a94d-6a583854769b@kernel.org>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-4-kevin_chen@aspeedtech.com>
 <7289a50a-e139-453f-a512-3dd68a0839a2@kernel.org>
 <7b991fca-6e2f-454f-a94d-6a583854769b@kernel.org>
Message-ID: <PSAPR06MB49495C182D0B64687E0174A389052@PSAPR06MB4949.apcprd06.prod.outlook.com>

Hi Krzk,

> > On 12/12/2024 16:52, Kevin Chen wrote:
> >> Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
> >> ---
> >>  Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 6 ++++++
> >>  1 file changed, 6 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> >> b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> >> index 2f92b8ab08fa..20191fee1f5b 100644
> >> --- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> >> +++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> >> @@ -101,4 +101,10 @@ properties:
> >>                - ufispace,ncplite-bmc
> >>            - const: aspeed,ast2600
> >>
> >> +      - description: AST2700 based boards
> >> +        items:
> >> +          - enum:
> >> +              - aspeed,ast2700-evb
> >> +          - const: aspeed,ast2700
> >> +
> >>  additionalProperties: true
> >
> >
> >
> > This patchset is just corrupted. You already sent it as patch #1.
> >
> > Please run scripts/checkpatch.pl and fix reported warnings. Then
> > please run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
> > Some warnings can be ignored, especially from --strict run, but the
> > code here looks like it needs a fix. Feel free to get in touch if the
> > warning is not clear.
> BTW, you already got here same comments before and this is third time you
> send exactly the same without implementing what we asked you.
Please check the following message.
https://lore.kernel.org/lkml/PSAPR06MB494943F3F34881D23CEEBD9A897D2 at PSAPR06MB4949.apcprd06.prod.outlook.com/

Or, how do you think what is better for me to add ast2700-evb?

> 
> Three times same issue.
> 
> NAK
> 
> Best regards,
> Krzysztof

Best Regards,
Kevin. Chen

From kevin_chen at aspeedtech.com  Tue Dec 17 19:04:32 2024
From: kevin_chen at aspeedtech.com (Kevin Chen)
Date: Wed, 18 Dec 2024 03:04:32 +0000
Subject: [PATCH v3 1/6] dt-bindings: interrupt-controller: Refine
 size/interrupt-cell usage.
In-Reply-To: <11ad5a97-b066-4bea-8829-50e0416cea9d@kernel.org>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-3-kevin_chen@aspeedtech.com>
 <11ad5a97-b066-4bea-8829-50e0416cea9d@kernel.org>
Message-ID: <PSAPR06MB4949CF57BD69B2F7C1D141CD89052@PSAPR06MB4949.apcprd06.prod.outlook.com>

Hi Krzk,

> > 1. Because size-cells is no need to use 2, modify to 1 for use.
> 
> ???
So, is it OK that I change the size-cells back to 2 include the aspeed,ast2700-intc.yaml examples and aspeed-g7.dtsi?

> 
> > 2. Add minItems to 1 for interrupts for intc1.
> 
> ???
For variable interrupt numbers, I need to fix the below warnings by minItems.
  DTC [C] arch/arm64/boot/dts/aspeed/ast2700-evb.dtb
/home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 100: interrupts-extended: [[3, 0, 3844]] is too short
        from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
/home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 110: interrupts-extended: [[3, 1, 3844]] is too short
        from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
/home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 120: interrupts-extended: [[3, 2, 3844]] is too short
        from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
/home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 130: interrupts-extended: [[3, 3, 3844]] is too short
        from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
/home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 140: interrupts-extended: [[3, 4, 3844]] is too short
        from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
/home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 150: interrupts-extended: [[3, 5, 3844]] is too short
        from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#

> 
> > 3. Add 1 interrupt of intc1 example into yaml file.
> 
> > 4. Add intc1 sub-module of uart12 as example using the intc0 and intc1.
> 
> What is all this?
> 
> BTW, there was no such patch in previous version and your changelog is silent
> about it.
Agree, I will restore the previous version.

> 
> Subject: drop all full stops. Subject never ends with full stop.
> 
> > ---
> >  .../aspeed,ast2700-intc.yaml                  | 60
> +++++++++++++++----
> >  1 file changed, 47 insertions(+), 13 deletions(-)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast270
> > 0-intc.yaml
> > b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast270
> > 0-intc.yaml index 55636d06a674..eadfbc45326b 100644
> > ---
> > a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast270
> > 0-intc.yaml
> > +++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,as
> > +++ t2700-intc.yaml
> > @@ -31,6 +31,7 @@ properties:
> >        type as defined in interrupt.txt in this directory.
> >
> >    interrupts:
> > +    minItems: 1
> 
> Nope, not explained, not constrained. Your schema is supposed to be
> constrained.
> 
> 
> >      maxItems: 6
> >      description: |
> >        Depend to which INTC0 or INTC1 used.
> > @@ -68,19 +69,52 @@ examples:
> >      #include <dt-bindings/interrupt-controller/arm-gic.h>
> >
> >      bus {
> > +      #address-cells = <2>;
> > +      #size-cells = <1>;
> > +
> > +      intc0: interrupt-controller at 12100000 {
> > +        compatible = "simple-mfd";
> > +        reg = <0 0x12100000 0x4000>;
> > +        ranges = <0x0 0x0 0x0 0x12100000 0x4000>;
> >          #address-cells = <2>;
> > -        #size-cells = <2>;
> > -
> > -        interrupt-controller at 12101b00 {
> > -            compatible = "aspeed,ast2700-intc-ic";
> > -            reg = <0 0x12101b00 0 0x10>;
> > -            #interrupt-cells = <2>;
> > -            interrupt-controller;
> > -            interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
> > -                         <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>,
> > -                         <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>,
> > -                         <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>,
> > -                         <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
> > -                         <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
> 
> 
> I don't understand what is all this.
> 
> > +        #size-cells = <1>;
> > +
> > +        intc0_11: interrupt-controller at 1b00 {
> > +          compatible = "aspeed,ast2700-intc-ic";
> > +          reg = <0 0x12101b00 0x10>;
> > +          #interrupt-cells = <2>;
> > +          interrupt-controller;
> > +          interrupts = <GIC_SPI 192 (GIC_CPU_MASK_SIMPLE(4) |
> IRQ_TYPE_LEVEL_HIGH)>,
> > +                       <GIC_SPI 193 (GIC_CPU_MASK_SIMPLE(4) |
> IRQ_TYPE_LEVEL_HIGH)>,
> > +                       <GIC_SPI 194 (GIC_CPU_MASK_SIMPLE(4) |
> IRQ_TYPE_LEVEL_HIGH)>,
> > +                       <GIC_SPI 195 (GIC_CPU_MASK_SIMPLE(4) |
> IRQ_TYPE_LEVEL_HIGH)>,
> > +                       <GIC_SPI 196 (GIC_CPU_MASK_SIMPLE(4) |
> IRQ_TYPE_LEVEL_HIGH)>,
> > +                       <GIC_SPI 197 (GIC_CPU_MASK_SIMPLE(4) |
> > + IRQ_TYPE_LEVEL_HIGH)>;
> >          };
> > +      };
> > +
> > +      intc1: interrupt-controller at 14c18000 {
> > +        compatible = "simple-mfd";
> > +        reg = <0 0x14c18000 0x400>;
> > +        ranges = <0x0 0x0 0x0 0x14c18000 0x400>;
> > +        #address-cells = <2>;
> > +        #size-cells = <1>;
> > +
> > +        intc1_4: interrupt-controller at 140 {
> > +          compatible = "aspeed,ast2700-intc-ic";
> > +          reg = <0x0 0x140 0x10>;
> > +          #interrupt-cells = <2>;
> > +          interrupt-controller;
> > +          interrupts-extended = <&intc0_11 4
> (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> > +        };
> > +      };
> > +
> > +      uart12: serial at 14c33b00 {
> > +        compatible = "ns16550a";
> > +        reg = <0x0 0x14c33b00 0x100>;
> > +        interrupts-extended = <&intc1_4 18 (GIC_CPU_MASK_SIMPLE(4)
> | IRQ_TYPE_LEVEL_HIGH)>;
> > +        reg-shift = <2>;
> > +        reg-io-width = <4>;
> > +        no-loopback-test;
> > +      };
> 
> And above is not related at all. Don't add entirely unrelated changes. Drop.
> 
> 
> Best regards,
> Krzysztof

Best Regards,
Kevin. Chen

From charan.pedumuru at microchip.com  Tue Dec 17 19:54:54 2024
From: charan.pedumuru at microchip.com (Charan Pedumuru)
Date: Wed, 18 Dec 2024 09:24:54 +0530
Subject: [PATCH v2] dt-bindings: mfd: atmel,at91sam9260: Convert to json
 schema
Message-ID: <20241218-matrix-v2-1-f3a8809ee5cd@microchip.com>

Convert old text based binding to json schema.
Changes during conversion:
Add a missing fallback `atmel,at91sam9x5-matrix` for
`microchip,sam9x60-matrix` which is not defined in the text binding.

Signed-off-by: Charan Pedumuru <charan.pedumuru at microchip.com>
---
Changes in v2:
- Modified the commit messsage.
- Replaced `anyOf` with `oneOf` in compatible under properties.
- Removed additional items group and added both `microchip,sam9x60-matrix` and 
  `microchip,sam9x7-matrix` as an enum under one items group
- Replaced `matrix@` with `syscon@` in examples.
- Link to v1: https://lore.kernel.org/r/20241211-matrix-v1-1-5ef0104a3af4 at microchip.com
---
 .../bindings/mfd/atmel,at91sam9260-matrix.yaml     | 52 ++++++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-matrix.txt       | 26 -----------
 2 files changed, 52 insertions(+), 26 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml
new file mode 100644
index 000000000000..447b3a3edbfc
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/atmel,at91sam9260-matrix.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip AT91 Bus Matrix
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+
+description:
+  The Bus Matrix (MATRIX) implements a multi-layer AHB, based on the
+  AHB-Lite protocol, that enables parallel access paths between multiple
+  masters and slaves in a system, thus increasing the overall bandwidth.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - atmel,at91sam9260-matrix
+              - atmel,at91sam9261-matrix
+              - atmel,at91sam9263-matrix
+              - atmel,at91sam9rl-matrix
+              - atmel,at91sam9g45-matrix
+              - atmel,at91sam9n12-matrix
+              - atmel,at91sam9x5-matrix
+              - atmel,sama5d3-matrix
+          - const: syscon
+      - items:
+          - enum:
+              - microchip,sam9x60-matrix
+              - microchip,sam9x7-matrix
+          - const: atmel,at91sam9x5-matrix
+          - const: syscon
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    syscon at ffffec00 {
+        compatible = "atmel,sama5d3-matrix", "syscon";
+        reg = <0xffffec00 0x200>;
+    };
diff --git a/Documentation/devicetree/bindings/mfd/atmel-matrix.txt b/Documentation/devicetree/bindings/mfd/atmel-matrix.txt
deleted file mode 100644
index 6e5f83614e83..000000000000
--- a/Documentation/devicetree/bindings/mfd/atmel-matrix.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-* Device tree bindings for Atmel Bus Matrix
-
-The Bus Matrix registers are used to configure Atmel SoCs internal bus
-behavior (master/slave priorities, undefined burst length type, ...)
-
-Required properties:
-- compatible:		Should be one of the following
-			"atmel,at91sam9260-matrix", "syscon"
-			"atmel,at91sam9261-matrix", "syscon"
-			"atmel,at91sam9263-matrix", "syscon"
-			"atmel,at91sam9rl-matrix", "syscon"
-			"atmel,at91sam9g45-matrix", "syscon"
-			"atmel,at91sam9n12-matrix", "syscon"
-			"atmel,at91sam9x5-matrix", "syscon"
-			"atmel,sama5d3-matrix", "syscon"
-			"microchip,sam9x60-matrix", "syscon"
-			"microchip,sam9x7-matrix", "atmel,at91sam9x5-matrix", "syscon"
-- reg:			Contains offset/length value of the Bus Matrix
-			memory region.
-
-Example:
-
-matrix: matrix at ffffec00 {
-	compatible = "atmel,sama5d3-matrix", "syscon";
-	reg = <0xffffec00 0x200>;
-};

---
base-commit: 1b2ab8149928c1cea2d7eca30cd35bb7fe014053
change-id: 20241210-matrix-30021676fb6f

Best regards,
-- 
Charan Pedumuru <charan.pedumuru at microchip.com>



From viresh.kumar at linaro.org  Tue Dec 17 20:11:27 2024
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 18 Dec 2024 09:41:27 +0530
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <Z2Haw_o8gF-Ce1gx@arm.com>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
 <20241212065100.sjb7lrlmksbm2hdk@vireshk-i7>
 <Z2CmcelSy89NULtz@arm.com>
 <20241217042726.isllh5bulpnwql7i@vireshk-i7>
 <Z2Haw_o8gF-Ce1gx@arm.com>
Message-ID: <20241218041127.khdwo3hzmywcwuh5@vireshk-i7>

On 17-12-24, 21:10, Beata Michalska wrote:
> On Tue, Dec 17, 2024 at 09:57:26AM +0530, Viresh Kumar wrote:
> > On 16-12-24, 23:15, Beata Michalska wrote:
> > > My bad as I must have misinterpreted that message. Although I am not entirely
> > > sure why this might be unacceptable as it is not such uncommon approach to use
> > > signed int space to cover both: expected positive value as well as potential
> > > error code case failure.
> > 
> > This part is fine. The problem is with handling frequency here. Signed int can
> > capture up to 2 GHz of freq, where as unsigned int can capture up to 4 GHz and
> > so we would really like to keep it at 4 GHz..
> Right, though the arch_freq_get_on_cpu operates on kHz values.

Hmm.. Missed that.

If you still want to keep it, make that change in a separate patch and
the new sysfs entry in a different one, so related people can easily
review.

-- 
viresh


From carlos.song at nxp.com  Tue Dec 17 20:35:41 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Wed, 18 Dec 2024 12:35:41 +0800
Subject: [PATCH v5] i2c: imx: support DMA defer probing
Message-ID: <20241218043541.143194-1-carlos.song@nxp.com>

Return -EPROBE_DEFER when dma_request_slave_channel() because DMA driver
have not ready yet.

Move i2c_imx_dma_request() before registering I2C adapter to avoid
infinite loop of .probe() calls to the same driver, see "e8c220fac415
Revert "i2c: imx: improve the error handling in i2c_imx_dma_request()""
and "Documentation/driver-api/driver-model/driver.rst".

Use CPU mode to avoid stuck registering i2c adapter when DMA resources
are unavailable.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Signed-off-by: Clark Wang <xiaoning.wang at nxp.com>
Acked-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
Change for V5:
- Add Ahmad Acked-by. No code change.
Change for V4:
- Output "Only use PIO mode" log in debug level when no DMA configure.
Change for V3:
- According to Marc's comment, remove error print when defer probe.
  Add info log when DMA has not been enabled and add error log when
  DMA error, both won't stuck the i2c adapter register, just for reminding,
  i2c adapter is working only in PIO mode.
Change for V2:
- According to Frank's comments, wrap at 75 char and Simplify fix code
  at i2c_imx_dma_request().
- Use strict patch check, fix alignment warning at i2c_imx_dma_request()
---
 drivers/i2c/busses/i2c-imx.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 9d5caa032c5c..0a5ddedf4dc1 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -397,17 +397,16 @@ static void i2c_imx_reset_regs(struct imx_i2c_struct *i2c_imx)
 }
 
 /* Functions for DMA support */
-static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
-						dma_addr_t phy_addr)
+static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx, dma_addr_t phy_addr)
 {
 	struct imx_i2c_dma *dma;
 	struct dma_slave_config dma_sconfig;
-	struct device *dev = &i2c_imx->adapter.dev;
+	struct device *dev = i2c_imx->adapter.dev.parent;
 	int ret;
 
 	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
 	if (!dma)
-		return;
+		return -ENOMEM;
 
 	dma->chan_tx = dma_request_chan(dev, "tx");
 	if (IS_ERR(dma->chan_tx)) {
@@ -452,7 +451,7 @@ static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 	dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n",
 		dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx));
 
-	return;
+	return 0;
 
 fail_rx:
 	dma_release_channel(dma->chan_rx);
@@ -460,6 +459,8 @@ static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 	dma_release_channel(dma->chan_tx);
 fail_al:
 	devm_kfree(dev, dma);
+
+	return ret;
 }
 
 static void i2c_imx_dma_callback(void *arg)
@@ -1804,6 +1805,23 @@ static int i2c_imx_probe(struct platform_device *pdev)
 	if (ret == -EPROBE_DEFER)
 		goto clk_notifier_unregister;
 
+	/*
+	 * Init DMA config if supported, -ENODEV means DMA not enabled at
+	 * this platform, that is not a real error, so just remind "only
+	 * PIO mode is used". If DMA is enabled, but meet error when request
+	 * DMA channel, error should be showed in probe error log. PIO mode
+	 * should be available regardless of DMA.
+	 */
+	ret = i2c_imx_dma_request(i2c_imx, phy_addr);
+	if (ret) {
+		if (ret == -EPROBE_DEFER)
+			goto clk_notifier_unregister;
+		else if (ret == -ENODEV)
+			dev_dbg(&pdev->dev, "Only use PIO mode\n");
+		else
+			dev_err_probe(&pdev->dev, ret, "Failed to setup DMA, only use PIO mode\n");
+	}
+
 	/* Add I2C adapter */
 	ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
 	if (ret < 0)
@@ -1818,9 +1836,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
 		i2c_imx->adapter.name);
 	dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
 
-	/* Init DMA config if supported */
-	i2c_imx_dma_request(i2c_imx, phy_addr);
-
 	return 0;   /* Return OK */
 
 clk_notifier_unregister:
-- 
2.34.1



From carlos.song at nxp.com  Tue Dec 17 20:41:14 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Wed, 18 Dec 2024 12:41:14 +0800
Subject: [PATCH v2] i2c: imx: switch different pinctrl state in different system power status
Message-ID: <20241218044114.143358-1-carlos.song@nxp.com>

Switch different pinctrl state in different system power status.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Reviewed-by: Frank Li <Frank.Li at nxp.com>
---
Change for V2:
- Add Frank reviewed-by. No code change.
---
 drivers/i2c/busses/i2c-imx.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index b6ed270dd04b..350346a7892c 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -1871,6 +1871,7 @@ static int i2c_imx_runtime_suspend(struct device *dev)
 	struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
 
 	clk_disable(i2c_imx->clk);
+	pinctrl_pm_select_sleep_state(dev);
 
 	return 0;
 }
@@ -1880,6 +1881,7 @@ static int i2c_imx_runtime_resume(struct device *dev)
 	struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
 	int ret;
 
+	pinctrl_pm_select_default_state(dev);
 	ret = clk_enable(i2c_imx->clk);
 	if (ret)
 		dev_err(dev, "can't enable I2C clock, ret=%d\n", ret);
-- 
2.34.1



From carlos.song at nxp.com  Tue Dec 17 20:42:38 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Wed, 18 Dec 2024 12:42:38 +0800
Subject: [PATCH v3] i2c: imx: add imx7d compatible string for applying errata ERR007805
Message-ID: <20241218044238.143414-1-carlos.song@nxp.com>

Compatible string "fsl,imx7d-i2c" is not exited at i2c-imx driver
compatible string table, at the result, "fsl,imx21-i2c" will be
matched, but it will cause errata ERR007805 not be applied in fact.

So Add "fsl,imx7d-i2c" compatible string in i2c-imx driver to apply
the errata ERR007805(https://www.nxp.com/webapp/Download?colCode=
IMX7DS_2N09P).

"fsl,imx7d-i2c" already is documented in binding doc. This errata
fix has been included in imx6_i2c_hwdata and it is the same in all
I.MX6/7/8, so just reuse it.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
Change for V3:
- No ACK, so resend this patch.
Change for V2:
- I have tried to fix this issue at imx7s.dtsi in V1, according to
  the community suggestion, I make V2 patch for i2c-imx driver to
  avoid updating the FDT to fix an errata. Discussion in V1:
  Subject: [PATCH] ARM: dts: imx7s: change i2c compatible string for applying errata ERR007805
  Message-ID: <20241021031148.2682015-1-carlos.song at nxp.com> (raw)
---
 drivers/i2c/busses/i2c-imx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 350346a7892c..9d5caa032c5c 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -335,6 +335,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
 	{ .compatible = "fsl,imx6sll-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx6sx-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx6ul-i2c", .data = &imx6_i2c_hwdata, },
+	{ .compatible = "fsl,imx7d-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx7s-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx8mm-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx8mn-i2c", .data = &imx6_i2c_hwdata, },
-- 
2.34.1



From nicolinc at nvidia.com  Tue Dec 17 21:00:19 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:19 -0800
Subject: [PATCH v3 06/14] iommufd: Add IOMMUFD_OBJ_VIRQ and IOMMUFD_CMD_VIRQ_ALLOC
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <dc1252de7ff06c944cb7d91c91b4f61c25182f91.1734477608.git.nicolinc@nvidia.com>

Allow a vIOMMU object to allocate vIRQ Event Queues, with a condition that
each vIOMMU can only have one single vIRQ event queue per type.

Add iommufd_eventq_virq_alloc with an iommufd_eventq_virq_ops for this new
ioctl.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/iommufd_private.h |  57 +++++++++++
 include/linux/iommufd.h                 |   3 +
 include/uapi/linux/iommufd.h            |  31 ++++++
 drivers/iommu/iommufd/eventq.c          | 129 ++++++++++++++++++++++++
 drivers/iommu/iommufd/main.c            |   6 ++
 drivers/iommu/iommufd/viommu.c          |   2 +
 6 files changed, 228 insertions(+)

diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index dfbc5cfbd164..fab3b21ac687 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -547,6 +547,49 @@ static inline int iommufd_hwpt_replace_device(struct iommufd_device *idev,
 	return iommu_group_replace_domain(idev->igroup->group, hwpt->domain);
 }
 
+/*
+ * An iommufd_virq object represents an interface to deliver vIOMMU interrupts
+ * to the user space. These objects are created/destroyed by the user space and
+ * associated with vIOMMU object(s) during the allocations.
+ */
+struct iommufd_virq {
+	struct iommufd_eventq common;
+	struct iommufd_viommu *viommu;
+	struct list_head node;
+
+	unsigned int type;
+};
+
+static inline struct iommufd_virq *eventq_to_virq(struct iommufd_eventq *eventq)
+{
+	return container_of(eventq, struct iommufd_virq, common);
+}
+
+static inline struct iommufd_virq *iommufd_get_virq(struct iommufd_ucmd *ucmd,
+						    u32 id)
+{
+	return container_of(iommufd_get_object(ucmd->ictx, id,
+					       IOMMUFD_OBJ_VIRQ),
+			    struct iommufd_virq, common.obj);
+}
+
+int iommufd_virq_alloc(struct iommufd_ucmd *ucmd);
+void iommufd_virq_destroy(struct iommufd_object *obj);
+void iommufd_virq_abort(struct iommufd_object *obj);
+
+/* An iommufd_virq_header packs a vIOMMU interrupt in an iommufd_virq queue */
+struct iommufd_virq_header {
+	struct list_head node;
+	ssize_t irq_len;
+	void *irq_data;
+};
+
+static inline int iommufd_virq_handler(struct iommufd_virq *virq,
+				       struct iommufd_virq_header *virq_header)
+{
+	return iommufd_eventq_notify(&virq->common, &virq_header->node);
+}
+
 static inline struct iommufd_viommu *
 iommufd_get_viommu(struct iommufd_ucmd *ucmd, u32 id)
 {
@@ -555,6 +598,20 @@ iommufd_get_viommu(struct iommufd_ucmd *ucmd, u32 id)
 			    struct iommufd_viommu, obj);
 }
 
+static inline struct iommufd_virq *
+iommufd_viommu_find_virq(struct iommufd_viommu *viommu, u32 type)
+{
+	struct iommufd_virq *virq, *next;
+
+	lockdep_assert_held(&viommu->virqs_rwsem);
+
+	list_for_each_entry_safe(virq, next, &viommu->virqs, node) {
+		if (virq->type == type)
+			return virq;
+	}
+	return NULL;
+}
+
 int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd);
 void iommufd_viommu_destroy(struct iommufd_object *obj);
 int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd);
diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 11110c749200..b082676c9e43 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -34,6 +34,7 @@ enum iommufd_object_type {
 	IOMMUFD_OBJ_FAULT,
 	IOMMUFD_OBJ_VIOMMU,
 	IOMMUFD_OBJ_VDEVICE,
+	IOMMUFD_OBJ_VIRQ,
 #ifdef CONFIG_IOMMUFD_TEST
 	IOMMUFD_OBJ_SELFTEST,
 #endif
@@ -93,6 +94,8 @@ struct iommufd_viommu {
 	const struct iommufd_viommu_ops *ops;
 
 	struct xarray vdevs;
+	struct list_head virqs;
+	struct rw_semaphore virqs_rwsem;
 
 	unsigned int type;
 };
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index 34810f6ae2b5..cdf2dba28d4a 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -55,6 +55,7 @@ enum {
 	IOMMUFD_CMD_VIOMMU_ALLOC = 0x90,
 	IOMMUFD_CMD_VDEVICE_ALLOC = 0x91,
 	IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92,
+	IOMMUFD_CMD_VIRQ_ALLOC = 0x93,
 };
 
 /**
@@ -1012,4 +1013,34 @@ struct iommu_ioas_change_process {
 #define IOMMU_IOAS_CHANGE_PROCESS \
 	_IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS)
 
+/**
+ * enum iommu_virq_type - Virtual IRQ Type
+ * @IOMMU_VIRQ_TYPE_NONE: INVALID type
+ */
+enum iommu_virq_type {
+	IOMMU_VIRQ_TYPE_NONE = 0,
+};
+
+/**
+ * struct iommu_virq_alloc - ioctl(IOMMU_VIRQ_ALLOC)
+ * @size: sizeof(struct iommu_virq_alloc)
+ * @flags: Must be 0
+ * @viommu: virtual IOMMU ID to associate the virtual IRQ with
+ * @type: Type of the virtual IRQ. Must be defined in enum iommu_virq_type
+ * @out_virq_id: The ID of the new virtual IRQ
+ * @out_virq_fd: The fd of the new virtual IRQ. User space must close the
+ *               successfully returned fd after using it
+ *
+ * Explicitly allocate a virtual IRQ interface for a vIOMMU. A vIOMMU can have
+ * multiple FDs for different @type, but is confined to one FD per @type.
+ */
+struct iommu_virq_alloc {
+	__u32 size;
+	__u32 flags;
+	__u32 viommu_id;
+	__u32 type;
+	__u32 out_virq_id;
+	__u32 out_virq_fd;
+};
+#define IOMMU_VIRQ_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VIRQ_ALLOC)
 #endif
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
index e386b6c3e6ab..a8921c745d36 100644
--- a/drivers/iommu/iommufd/eventq.c
+++ b/drivers/iommu/iommufd/eventq.c
@@ -346,6 +346,73 @@ static const struct iommufd_eventq_ops iommufd_fault_ops = {
 	.write = &iommufd_fault_fops_write,
 };
 
+/* IOMMUFD_OBJ_VIRQ Functions */
+
+void iommufd_virq_abort(struct iommufd_object *obj)
+{
+	struct iommufd_eventq *eventq =
+		container_of(obj, struct iommufd_eventq, obj);
+	struct iommufd_virq *virq = eventq_to_virq(eventq);
+	struct iommufd_viommu *viommu = virq->viommu;
+	struct iommufd_virq_header *cur, *next;
+
+	lockdep_assert_held_write(&viommu->virqs_rwsem);
+
+	list_for_each_entry_safe(cur, next, &eventq->deliver, node) {
+		list_del(&cur->node);
+		kfree(cur);
+	}
+
+	refcount_dec(&viommu->obj.users);
+	mutex_destroy(&eventq->mutex);
+	list_del(&virq->node);
+}
+
+void iommufd_virq_destroy(struct iommufd_object *obj)
+{
+	struct iommufd_virq *virq =
+		eventq_to_virq(container_of(obj, struct iommufd_eventq, obj));
+
+	down_write(&virq->viommu->virqs_rwsem);
+	iommufd_virq_abort(obj);
+	up_write(&virq->viommu->virqs_rwsem);
+}
+
+static ssize_t iommufd_virq_fops_read(struct iommufd_eventq *eventq,
+				      char __user *buf, size_t count,
+				      loff_t *ppos)
+{
+	size_t done = 0;
+	int rc = 0;
+
+	if (*ppos)
+		return -ESPIPE;
+
+	mutex_lock(&eventq->mutex);
+	while (!list_empty(&eventq->deliver) && count > done) {
+		struct iommufd_virq_header *cur = list_first_entry(
+			&eventq->deliver, struct iommufd_virq_header, node);
+
+		if (cur->irq_len > count - done)
+			break;
+
+		if (copy_to_user(buf + done, cur->irq_data, cur->irq_len)) {
+			rc = -EFAULT;
+			break;
+		}
+		done += cur->irq_len;
+		list_del(&cur->node);
+		kfree(cur);
+	}
+	mutex_unlock(&eventq->mutex);
+
+	return done == 0 ? rc : done;
+}
+
+static const struct iommufd_eventq_ops iommufd_virq_ops = {
+	.read = &iommufd_virq_fops_read,
+};
+
 /* Common Event Queue Functions */
 
 static ssize_t iommufd_eventq_fops_read(struct file *filep, char __user *buf,
@@ -473,3 +540,65 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 
 	return rc;
 }
+
+int iommufd_virq_alloc(struct iommufd_ucmd *ucmd)
+{
+	struct iommu_virq_alloc *cmd = ucmd->cmd;
+	struct iommufd_viommu *viommu;
+	struct iommufd_virq *virq;
+	int fdno;
+	int rc;
+
+	if (cmd->flags || cmd->type == IOMMU_VIRQ_TYPE_NONE)
+		return -EOPNOTSUPP;
+
+	viommu = iommufd_get_viommu(ucmd, cmd->viommu_id);
+	if (IS_ERR(viommu))
+		return PTR_ERR(viommu);
+	down_write(&viommu->virqs_rwsem);
+
+	if (iommufd_viommu_find_virq(viommu, cmd->type)) {
+		rc = -EEXIST;
+		goto out_unlock_virqs;
+	}
+
+	virq = __iommufd_object_alloc(ucmd->ictx, virq, IOMMUFD_OBJ_VIRQ,
+				      common.obj);
+	if (IS_ERR(virq)) {
+		rc = PTR_ERR(virq);
+		goto out_unlock_virqs;
+	}
+
+	virq->type = cmd->type;
+	virq->viommu = viommu;
+	refcount_inc(&viommu->obj.users);
+	list_add_tail(&virq->node, &viommu->virqs);
+
+	fdno = iommufd_eventq_init(&virq->common, "[iommufd-viommu-irq]",
+				   ucmd->ictx, &iommufd_virq_ops);
+	if (fdno < 0) {
+		rc = fdno;
+		goto out_abort;
+	}
+
+	cmd->out_virq_id = virq->common.obj.id;
+	cmd->out_virq_fd = fdno;
+
+	rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
+	if (rc)
+		goto out_put_fdno;
+
+	iommufd_object_finalize(ucmd->ictx, &virq->common.obj);
+	fd_install(fdno, virq->common.filep);
+	goto out_unlock_virqs;
+
+out_put_fdno:
+	put_unused_fd(fdno);
+	fput(virq->common.filep);
+out_abort:
+	iommufd_object_abort_and_destroy(ucmd->ictx, &virq->common.obj);
+out_unlock_virqs:
+	up_write(&viommu->virqs_rwsem);
+	iommufd_put_object(ucmd->ictx, &viommu->obj);
+	return rc;
+}
diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index cfbdf7b0e3c1..9d15978ef882 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -367,6 +367,8 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = {
 		 __reserved),
 	IOCTL_OP(IOMMU_VIOMMU_ALLOC, iommufd_viommu_alloc_ioctl,
 		 struct iommu_viommu_alloc, out_viommu_id),
+	IOCTL_OP(IOMMU_VIRQ_ALLOC, iommufd_virq_alloc, struct iommu_virq_alloc,
+		 out_virq_fd),
 #ifdef CONFIG_IOMMUFD_TEST
 	IOCTL_OP(IOMMU_TEST_CMD, iommufd_test, struct iommu_test_cmd, last),
 #endif
@@ -502,6 +504,10 @@ static const struct iommufd_object_ops iommufd_object_ops[] = {
 	[IOMMUFD_OBJ_FAULT] = {
 		.destroy = iommufd_fault_destroy,
 	},
+	[IOMMUFD_OBJ_VIRQ] = {
+		.destroy = iommufd_virq_destroy,
+		.abort = iommufd_virq_abort,
+	},
 	[IOMMUFD_OBJ_VIOMMU] = {
 		.destroy = iommufd_viommu_destroy,
 	},
diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c
index 69b88e8c7c26..075b6aed79bc 100644
--- a/drivers/iommu/iommufd/viommu.c
+++ b/drivers/iommu/iommufd/viommu.c
@@ -59,6 +59,8 @@ int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd)
 	viommu->ictx = ucmd->ictx;
 	viommu->hwpt = hwpt_paging;
 	refcount_inc(&viommu->hwpt->common.obj.users);
+	INIT_LIST_HEAD(&viommu->virqs);
+	init_rwsem(&viommu->virqs_rwsem);
 	/*
 	 * It is the most likely case that a physical IOMMU is unpluggable. A
 	 * pluggable IOMMU instance (if exists) is responsible for refcounting
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:18 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:18 -0800
Subject: [PATCH v3 05/14] iommufd: Rename fault.c to eventq.c
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <e1b19408b6dd865c4b7629924e6f62fa61f1f75a.1734477608.git.nicolinc@nvidia.com>

Rename the file, aligning with the new eventq object.

Reviewed-by: Kevin Tian <kevin.tian at intel.com>
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/Makefile              | 2 +-
 drivers/iommu/iommufd/{fault.c => eventq.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/iommu/iommufd/{fault.c => eventq.c} (100%)

diff --git a/drivers/iommu/iommufd/Makefile b/drivers/iommu/iommufd/Makefile
index cb784da6cddc..71d692c9a8f4 100644
--- a/drivers/iommu/iommufd/Makefile
+++ b/drivers/iommu/iommufd/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 iommufd-y := \
 	device.o \
-	fault.o \
+	eventq.o \
 	hw_pagetable.o \
 	io_pagetable.o \
 	ioas.o \
diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/eventq.c
similarity index 100%
rename from drivers/iommu/iommufd/fault.c
rename to drivers/iommu/iommufd/eventq.c
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:20 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:20 -0800
Subject: [PATCH v3 07/14] iommufd/viommu: Add iommufd_viommu_get_vdev_id helper
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <21d7e63b97d81d0acf9127418a67efe386787261.1734477608.git.nicolinc@nvidia.com>

This is a reverse search v.s. iommufd_viommu_find_dev, as drivers may want
to convert a struct device pointer (physical) to its virtual device ID for
an event injection to the user space VM.

Again, this avoids exposing more core structures to the drivers, than the
iommufd_viommu alone.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 include/linux/iommufd.h        |  8 ++++++++
 drivers/iommu/iommufd/driver.c | 20 ++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index b082676c9e43..ac1f1897d290 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -190,6 +190,8 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
 					     enum iommufd_object_type type);
 struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 				       unsigned long vdev_id);
+unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
+					 struct device *dev);
 #else /* !CONFIG_IOMMUFD_DRIVER_CORE */
 static inline struct iommufd_object *
 _iommufd_object_alloc(struct iommufd_ctx *ictx, size_t size,
@@ -203,6 +205,12 @@ iommufd_viommu_find_dev(struct iommufd_viommu *viommu, unsigned long vdev_id)
 {
 	return NULL;
 }
+
+static inline unsigned long
+iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu, struct device *dev)
+{
+	return 0;
+}
 #endif /* CONFIG_IOMMUFD_DRIVER_CORE */
 
 /*
diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c
index 2d98b04ff1cb..e5d7397c0a6c 100644
--- a/drivers/iommu/iommufd/driver.c
+++ b/drivers/iommu/iommufd/driver.c
@@ -49,5 +49,25 @@ struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_viommu_find_dev, "IOMMUFD");
 
+/* Return 0 if device is not associated to the vIOMMU */
+unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
+					 struct device *dev)
+{
+	struct iommufd_vdevice *vdev;
+	unsigned long vdev_id = 0;
+	unsigned long index;
+
+	xa_lock(&viommu->vdevs);
+	xa_for_each(&viommu->vdevs, index, vdev) {
+		if (vdev && vdev->dev == dev) {
+			vdev_id = (unsigned long)vdev->id;
+			break;
+		}
+	}
+	xa_unlock(&viommu->vdevs);
+	return vdev_id;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_viommu_get_vdev_id, "IOMMUFD");
+
 MODULE_DESCRIPTION("iommufd code shared with builtin modules");
 MODULE_LICENSE("GPL");
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:21 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:21 -0800
Subject: [PATCH v3 08/14] iommufd/viommu: Add iommufd_viommu_report_irq helper
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <3d2298e45c9d5e433cb2c65a17c6d3bbe570918f.1734477608.git.nicolinc@nvidia.com>

Similar to iommu_report_device_fault, this allows IOMMU drivers to report,
from threaded IRQ handlers to user space hypervisors, IRQs or events that
belong to a vIOMMU.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 include/linux/iommufd.h        |  9 +++++++++
 drivers/iommu/iommufd/driver.c | 37 ++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index ac1f1897d290..c5909125775a 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -192,6 +192,8 @@ struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 				       unsigned long vdev_id);
 unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
 					 struct device *dev);
+int iommufd_viommu_report_irq(struct iommufd_viommu *viommu, unsigned int type,
+			      void *irq_ptr, size_t irq_len);
 #else /* !CONFIG_IOMMUFD_DRIVER_CORE */
 static inline struct iommufd_object *
 _iommufd_object_alloc(struct iommufd_ctx *ictx, size_t size,
@@ -211,6 +213,13 @@ iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu, struct device *dev)
 {
 	return 0;
 }
+
+static inline int iommufd_viommu_report_irq(struct iommufd_viommu *viommu,
+					    unsigned int type, void *irq_ptr,
+					    size_t irq_len)
+{
+	return -EOPNOTSUPP;
+}
 #endif /* CONFIG_IOMMUFD_DRIVER_CORE */
 
 /*
diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c
index e5d7397c0a6c..2ab793f27f72 100644
--- a/drivers/iommu/iommufd/driver.c
+++ b/drivers/iommu/iommufd/driver.c
@@ -69,5 +69,42 @@ unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_viommu_get_vdev_id, "IOMMUFD");
 
+/* Typically called in driver's threaded IRQ handler */
+int iommufd_viommu_report_irq(struct iommufd_viommu *viommu, unsigned int type,
+			      void *irq_ptr, size_t irq_len)
+{
+	struct iommufd_virq_header *header;
+	struct iommufd_virq *virq;
+	int rc = 0;
+
+	if (!viommu)
+		return -ENODEV;
+	if (WARN_ON_ONCE(!irq_len || !irq_ptr))
+		return -EINVAL;
+
+	down_read(&viommu->virqs_rwsem);
+
+	virq = iommufd_viommu_find_virq(viommu, type);
+	if (!virq) {
+		rc = -EOPNOTSUPP;
+		goto out_unlock_virqs;
+	}
+
+	header = kzalloc(sizeof(*header) + irq_len, GFP_KERNEL);
+	if (!header) {
+		rc = -ENOMEM;
+		goto out_unlock_virqs;
+	}
+	header->irq_data = (void *)header + sizeof(*header);
+	memcpy(header->irq_data, irq_ptr, irq_len);
+	header->irq_len = irq_len;
+
+	iommufd_virq_handler(virq, header);
+out_unlock_virqs:
+	up_read(&viommu->virqs_rwsem);
+	return rc;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_viommu_report_irq, "IOMMUFD");
+
 MODULE_DESCRIPTION("iommufd code shared with builtin modules");
 MODULE_LICENSE("GPL");
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:22 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:22 -0800
Subject: [PATCH v3 09/14] iommufd/selftest: Require vdev_id when attaching to a nested domain
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <c20899ecf9adf3cf5bf7ddebad40e9c8c6fccec2.1734477608.git.nicolinc@nvidia.com>

When attaching a device to a vIOMMU-based nested domain, vdev_id must be
present. Add a piece of code hard-requesting it, for vIRQ support in the
following patch. Then, update the TEST_F.

A HWPT-based nested domain will return a NULL new_viommu, thus no such a
vDEVICE requirement.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/selftest.c        | 23 +++++++++++++++++++++++
 tools/testing/selftests/iommu/iommufd.c |  5 +++++
 2 files changed, 28 insertions(+)

diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index a0de6d6d4e68..d1438d81e664 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -161,7 +161,10 @@ enum selftest_obj_type {
 
 struct mock_dev {
 	struct device dev;
+	struct mock_viommu *viommu;
+	struct rw_semaphore viommu_rwsem;
 	unsigned long flags;
+	unsigned long vdev_id;
 	int id;
 	u32 cache[MOCK_DEV_CACHE_NUM];
 };
@@ -193,10 +196,29 @@ static int mock_domain_nop_attach(struct iommu_domain *domain,
 				  struct device *dev)
 {
 	struct mock_dev *mdev = to_mock_dev(dev);
+	struct mock_viommu *new_viommu = NULL;
+	unsigned long vdev_id = 0;
 
 	if (domain->dirty_ops && (mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
 		return -EINVAL;
 
+	iommu_group_mutex_assert(dev);
+	if (domain->type == IOMMU_DOMAIN_NESTED) {
+		new_viommu = to_mock_nested(domain)->mock_viommu;
+		if (new_viommu) {
+			vdev_id = iommufd_viommu_get_vdev_id(&new_viommu->core,
+							     dev);
+			if (!vdev_id)
+				return -ENOENT;
+		}
+	}
+	if (new_viommu != mdev->viommu) {
+		down_write(&mdev->viommu_rwsem);
+		mdev->viommu = new_viommu;
+		mdev->vdev_id = vdev_id;
+		up_write(&mdev->viommu_rwsem);
+	}
+
 	return 0;
 }
 
@@ -861,6 +883,7 @@ static struct mock_dev *mock_dev_create(unsigned long dev_flags)
 	if (!mdev)
 		return ERR_PTR(-ENOMEM);
 
+	init_rwsem(&mdev->viommu_rwsem);
 	device_initialize(&mdev->dev);
 	mdev->flags = dev_flags;
 	mdev->dev.release = mock_dev_release;
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index a1b2b657999d..212e5d62e13d 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -2736,6 +2736,7 @@ TEST_F(iommufd_viommu, viommu_alloc_nested_iopf)
 	uint32_t iopf_hwpt_id;
 	uint32_t fault_id;
 	uint32_t fault_fd;
+	uint32_t vdev_id;
 
 	if (self->device_id) {
 		test_ioctl_fault_alloc(&fault_id, &fault_fd);
@@ -2752,6 +2753,10 @@ TEST_F(iommufd_viommu, viommu_alloc_nested_iopf)
 			&iopf_hwpt_id, IOMMU_HWPT_DATA_SELFTEST, &data,
 			sizeof(data));
 
+		/* Must allocate vdevice before attaching to a nested hwpt */
+		test_err_mock_domain_replace(ENOENT, self->stdev_id,
+					     iopf_hwpt_id);
+		test_cmd_vdevice_alloc(viommu_id, dev_id, 0x99, &vdev_id);
 		test_cmd_mock_domain_replace(self->stdev_id, iopf_hwpt_id);
 		EXPECT_ERRNO(EBUSY,
 			     _test_ioctl_destroy(self->fd, iopf_hwpt_id));
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:23 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:23 -0800
Subject: [PATCH v3 10/14] iommufd/selftest: Add IOMMU_TEST_OP_TRIGGER_VIRQ for vIRQ coverage
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <3ec98f083ad03aec737fe17c5f8b691d8fea644c.1734477608.git.nicolinc@nvidia.com>

The handler will get vDEVICE object from the given mdev and convert it to
its per-vIOMMU virtual ID to mimic a real IOMMU driver.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/iommufd_test.h | 10 ++++++++++
 drivers/iommu/iommufd/selftest.c     | 30 ++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h
index a6b7a163f636..3037904f2e52 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -24,6 +24,7 @@ enum {
 	IOMMU_TEST_OP_MD_CHECK_IOTLB,
 	IOMMU_TEST_OP_TRIGGER_IOPF,
 	IOMMU_TEST_OP_DEV_CHECK_CACHE,
+	IOMMU_TEST_OP_TRIGGER_VIRQ,
 };
 
 enum {
@@ -145,6 +146,9 @@ struct iommu_test_cmd {
 			__u32 id;
 			__u32 cache;
 		} check_dev_cache;
+		struct {
+			__u32 dev_id;
+		} trigger_virq;
 	};
 	__u32 last;
 };
@@ -212,4 +216,10 @@ struct iommu_viommu_invalidate_selftest {
 	__u32 cache_id;
 };
 
+#define IOMMU_VIRQ_TYPE_SELFTEST 0xbeefbeef
+
+struct iommu_viommu_irq_selftest {
+	__u32 virt_id;
+};
+
 #endif
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index d1438d81e664..0785c9447102 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -1631,6 +1631,34 @@ static int iommufd_test_trigger_iopf(struct iommufd_ucmd *ucmd,
 	return 0;
 }
 
+static int iommufd_test_trigger_virq(struct iommufd_ucmd *ucmd,
+				     struct iommu_test_cmd *cmd)
+{
+	struct iommu_viommu_irq_selftest test = {};
+	struct iommufd_device *idev;
+	struct mock_dev *mdev;
+	int rc = -ENOENT;
+
+	idev = iommufd_get_device(ucmd, cmd->trigger_virq.dev_id);
+	if (IS_ERR(idev))
+		return PTR_ERR(idev);
+	mdev = to_mock_dev(idev->dev);
+
+	down_read(&mdev->viommu_rwsem);
+	if (!mdev->viommu || !mdev->vdev_id)
+		goto out_unlock;
+
+	test.virt_id = mdev->vdev_id;
+	rc = iommufd_viommu_report_irq(&mdev->viommu->core,
+				       IOMMU_VIRQ_TYPE_SELFTEST, &test,
+				       sizeof(test));
+out_unlock:
+	up_read(&mdev->viommu_rwsem);
+	iommufd_put_object(ucmd->ictx, &idev->obj);
+
+	return rc;
+}
+
 void iommufd_selftest_destroy(struct iommufd_object *obj)
 {
 	struct selftest_obj *sobj = to_selftest_obj(obj);
@@ -1712,6 +1740,8 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
 					  cmd->dirty.flags);
 	case IOMMU_TEST_OP_TRIGGER_IOPF:
 		return iommufd_test_trigger_iopf(ucmd, cmd);
+	case IOMMU_TEST_OP_TRIGGER_VIRQ:
+		return iommufd_test_trigger_virq(ucmd, cmd);
 	default:
 		return -EOPNOTSUPP;
 	}
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:14 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:14 -0800
Subject: [PATCH v3 01/14] iommufd: Keep IOCTL list in an alphabetical order
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <0bdb04c6dc32f428a7f181471a0d78642e80d3b8.1734477608.git.nicolinc@nvidia.com>

Move VDEVICE upward to keep the order. Also run clang-format keep the same
coding style at line wrappings. No functional change.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/main.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index 97c5e3567d33..cfbdf7b0e3c1 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -333,8 +333,8 @@ struct iommufd_ioctl_op {
 	}
 static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = {
 	IOCTL_OP(IOMMU_DESTROY, iommufd_destroy, struct iommu_destroy, id),
-	IOCTL_OP(IOMMU_FAULT_QUEUE_ALLOC, iommufd_fault_alloc, struct iommu_fault_alloc,
-		 out_fault_fd),
+	IOCTL_OP(IOMMU_FAULT_QUEUE_ALLOC, iommufd_fault_alloc,
+		 struct iommu_fault_alloc, out_fault_fd),
 	IOCTL_OP(IOMMU_GET_HW_INFO, iommufd_get_hw_info, struct iommu_hw_info,
 		 __reserved),
 	IOCTL_OP(IOMMU_HWPT_ALLOC, iommufd_hwpt_alloc, struct iommu_hwpt_alloc,
@@ -355,20 +355,18 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = {
 		 src_iova),
 	IOCTL_OP(IOMMU_IOAS_IOVA_RANGES, iommufd_ioas_iova_ranges,
 		 struct iommu_ioas_iova_ranges, out_iova_alignment),
-	IOCTL_OP(IOMMU_IOAS_MAP, iommufd_ioas_map, struct iommu_ioas_map,
-		 iova),
+	IOCTL_OP(IOMMU_IOAS_MAP, iommufd_ioas_map, struct iommu_ioas_map, iova),
 	IOCTL_OP(IOMMU_IOAS_MAP_FILE, iommufd_ioas_map_file,
 		 struct iommu_ioas_map_file, iova),
 	IOCTL_OP(IOMMU_IOAS_UNMAP, iommufd_ioas_unmap, struct iommu_ioas_unmap,
 		 length),
-	IOCTL_OP(IOMMU_OPTION, iommufd_option, struct iommu_option,
-		 val64),
+	IOCTL_OP(IOMMU_OPTION, iommufd_option, struct iommu_option, val64),
+	IOCTL_OP(IOMMU_VDEVICE_ALLOC, iommufd_vdevice_alloc_ioctl,
+		 struct iommu_vdevice_alloc, virt_id),
 	IOCTL_OP(IOMMU_VFIO_IOAS, iommufd_vfio_ioas, struct iommu_vfio_ioas,
 		 __reserved),
 	IOCTL_OP(IOMMU_VIOMMU_ALLOC, iommufd_viommu_alloc_ioctl,
 		 struct iommu_viommu_alloc, out_viommu_id),
-	IOCTL_OP(IOMMU_VDEVICE_ALLOC, iommufd_vdevice_alloc_ioctl,
-		 struct iommu_vdevice_alloc, virt_id),
 #ifdef CONFIG_IOMMUFD_TEST
 	IOCTL_OP(IOMMU_TEST_CMD, iommufd_test, struct iommu_test_cmd, last),
 #endif
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:13 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:13 -0800
Subject: [PATCH v3 00/14] iommufd: Add vIOMMU infrastructure (Part-3: vIRQ)
Message-ID: <cover.1734477608.git.nicolinc@nvidia.com>

As the part-3 of the vIOMMU infrastructure, this series introduces a vIRQ
object. The existing FAULT object provides a nice notification pathway to
the user space already, so let vIRQ reuse the infrastructure.

Mimicing the HWPT structure, add a common EVENTQ structure to support its
derivatives: IOMMUFD_OBJ_FAULT (existing) and IOMMUFD_OBJ_VIRQ (new).

IOMMUFD_CMD_VIRQ_ALLOC is introduced to allocate vIRQ objects for vIOMMUs.
One vIOMMU can have multiple vIRQs in different types but can not support
multiple vIRQs with the same types.

The forwarding part is fairly simple but might need to replace a physical
device ID with a virtual device ID in a driver-level IRQ data structure.
So, this comes with some helpers for drivers to use.

As usual, this series comes with the selftest coverage for this new vIRQ,
and with a real world use case in the ARM SMMUv3 driver.

This is on Github:
https://github.com/nicolinc/iommufd/commits/iommufd_virq-v3

Testing with RMR patches for MSI:
https://github.com/nicolinc/iommufd/commits/iommufd_virq-v3-with-rmr
Paring QEMU branch for testing:
https://github.com/nicolinc/qemu/commits/wip/for_iommufd_virq-v3

Changelog
v3
 * Rebase on Will's for-joerg/arm-smmu/updates for arm_smmu_event series
 * Add "Reviewed-by" lines from Kevin
 * Fix typos in comments, kdocs, and jump tags
 * Add a patch to sort struct iommufd_ioctl_op
 * Update iommufd's userpsace-api documentation
 * Update uAPI kdoc to quote SMMUv3 offical spec
 * Drop the unused workqueue in struct iommufd_virq
 * Drop might_sleep() in iommufd_viommu_report_irq() helper
 * Add missing "break" in iommufd_viommu_get_vdev_id() helper
 * Shrink the scope of the vmaster's read lock in SMMUv3 driver
 * Pass in two arguments to iommufd_eventq_virq_handler() helper
 * Move "!ops || !ops->read" validation into iommufd_eventq_init()
 * Move "fault->ictx = ictx" closer to iommufd_ctx_get(fault->ictx)
 * Update commit message for arm_smmu_attach_prepare/commit_vmaster()
 * Keep "iommufd_fault" as-is and rename "iommufd_eventq_virq" to just
   "iommufd_virq"
v2
 https://lore.kernel.org/all/cover.1733263737.git.nicolinc at nvidia.com/
 * Rebase on v6.13-rc1
 * Add IOPF and vIRQ in iommufd.rst (userspace-api)
 * Add a proper locking in iommufd_event_virq_destroy
 * Add iommufd_event_virq_abort with a lockdep_assert_held
 * Rename "EVENT_*" to "EVENTQ_*" to describe the objects better
 * Reorganize flows in iommufd_eventq_virq_alloc for abort() to work
 * Adde struct arm_smmu_vmaster to store vSID upon attaching to a nested
   domain, calling a newly added iommufd_viommu_get_vdev_id helper
 * Adde an arm_vmaster_report_event helper in arm-smmu-v3-iommufd file
   to simplify the routine in arm_smmu_handle_evt() of the main driver
v1
 https://lore.kernel.org/all/cover.1724777091.git.nicolinc at nvidia.com/

Thanks!
Nicolin

Nicolin Chen (14):
  iommufd: Keep IOCTL list in an alphabetical order
  iommufd/fault: Add an iommufd_fault_init() helper
  iommufd/fault: Move iommufd_fault_iopf_handler() to header
  iommufd: Abstract an iommufd_eventq from iommufd_fault
  iommufd: Rename fault.c to eventq.c
  iommufd: Add IOMMUFD_OBJ_VIRQ and IOMMUFD_CMD_VIRQ_ALLOC
  iommufd/viommu: Add iommufd_viommu_get_vdev_id helper
  iommufd/viommu: Add iommufd_viommu_report_irq helper
  iommufd/selftest: Require vdev_id when attaching to a nested domain
  iommufd/selftest: Add IOMMU_TEST_OP_TRIGGER_VIRQ for vIRQ coverage
  iommufd/selftest: Add IOMMU_VIRQ_ALLOC test coverage
  Documentation: userspace-api: iommufd: Update FAULT and VIRQ
  iommu/arm-smmu-v3: Introduce struct arm_smmu_vmaster
  iommu/arm-smmu-v3: Report IRQs that belong to devices attached to
    vIOMMU

 drivers/iommu/iommufd/Makefile                |   2 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  30 ++
 drivers/iommu/iommufd/iommufd_private.h       | 115 ++++++-
 drivers/iommu/iommufd/iommufd_test.h          |  10 +
 include/linux/iommufd.h                       |  20 ++
 include/uapi/linux/iommufd.h                  |  46 +++
 tools/testing/selftests/iommu/iommufd_utils.h |  63 ++++
 .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c     |  65 ++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  90 ++++--
 drivers/iommu/iommufd/driver.c                |  57 ++++
 drivers/iommu/iommufd/{fault.c => eventq.c}   | 298 ++++++++++++++----
 drivers/iommu/iommufd/hw_pagetable.c          |   6 +-
 drivers/iommu/iommufd/main.c                  |  20 +-
 drivers/iommu/iommufd/selftest.c              |  53 ++++
 drivers/iommu/iommufd/viommu.c                |   2 +
 tools/testing/selftests/iommu/iommufd.c       |  27 ++
 .../selftests/iommu/iommufd_fail_nth.c        |   6 +
 Documentation/userspace-api/iommufd.rst       |  16 +
 18 files changed, 809 insertions(+), 117 deletions(-)
 rename drivers/iommu/iommufd/{fault.c => eventq.c} (55%)


base-commit: 376ce8b35ed15d5deee57bdecd8449f6a4df4c42
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:16 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:16 -0800
Subject: [PATCH v3 03/14] iommufd/fault: Move iommufd_fault_iopf_handler() to header
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <298800fb1997fb9106600d0f5531cdebb0fa3871.1734477608.git.nicolinc@nvidia.com>

The new vIRQ object will need a similar function for drivers to report the
vIOMMU related interrupts. Split the common part out to a smaller helper,
and place it in the header so that CONFIG_IOMMUFD_DRIVER_CORE can include
that in the driver.c file for drivers to use.

Then keep iommufd_fault_iopf_handler() in the header too, since it's quite
simple after all.

Reviewed-by: Kevin Tian <kevin.tian at intel.com>
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/iommufd_private.h | 20 +++++++++++++++++++-
 drivers/iommu/iommufd/fault.c           | 17 -----------------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index b6d706cf2c66..8b378705ee71 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -451,6 +451,17 @@ struct iommufd_fault {
 	struct wait_queue_head wait_queue;
 };
 
+static inline int iommufd_fault_notify(struct iommufd_fault *fault,
+				       struct list_head *new_fault)
+{
+	mutex_lock(&fault->mutex);
+	list_add_tail(new_fault, &fault->deliver);
+	mutex_unlock(&fault->mutex);
+
+	wake_up_interruptible(&fault->wait_queue);
+	return 0;
+}
+
 struct iommufd_attach_handle {
 	struct iommu_attach_handle handle;
 	struct iommufd_device *idev;
@@ -469,7 +480,14 @@ iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id)
 
 int iommufd_fault_alloc(struct iommufd_ucmd *ucmd);
 void iommufd_fault_destroy(struct iommufd_object *obj);
-int iommufd_fault_iopf_handler(struct iopf_group *group);
+
+static inline int iommufd_fault_iopf_handler(struct iopf_group *group)
+{
+	struct iommufd_hw_pagetable *hwpt =
+		group->attach_handle->domain->fault_data;
+
+	return iommufd_fault_notify(hwpt->fault, &group->node);
+}
 
 int iommufd_fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
 				    struct iommufd_device *idev);
diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
index 1d1095fc8224..d188994e4e84 100644
--- a/drivers/iommu/iommufd/fault.c
+++ b/drivers/iommu/iommufd/fault.c
@@ -433,20 +433,3 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 
 	return rc;
 }
-
-int iommufd_fault_iopf_handler(struct iopf_group *group)
-{
-	struct iommufd_hw_pagetable *hwpt;
-	struct iommufd_fault *fault;
-
-	hwpt = group->attach_handle->domain->fault_data;
-	fault = hwpt->fault;
-
-	mutex_lock(&fault->mutex);
-	list_add_tail(&group->node, &fault->deliver);
-	mutex_unlock(&fault->mutex);
-
-	wake_up_interruptible(&fault->wait_queue);
-
-	return 0;
-}
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:15 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:15 -0800
Subject: [PATCH v3 02/14] iommufd/fault: Add an iommufd_fault_init() helper
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <d2e570487d95771ff0a48c143c6f62e2626dd5a9.1734477608.git.nicolinc@nvidia.com>

The infrastructure of a fault object will be shared with a new vIRQ object
in a following change. Add a helper for a vIRQ allocator to call it too.

Reorder the iommufd_ctx_get and refcount_inc to keep them symmetrical with
the iommufd_fault_fops_release().

Since the new vIRQ object doesn't need "response", leave the xa_init_flags
in its original location.

Reviewed-by: Kevin Tian <kevin.tian at intel.com>
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/fault.c | 48 ++++++++++++++++++++---------------
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
index 1fe804e28a86..1d1095fc8224 100644
--- a/drivers/iommu/iommufd/fault.c
+++ b/drivers/iommu/iommufd/fault.c
@@ -367,11 +367,35 @@ static const struct file_operations iommufd_fault_fops = {
 	.release	= iommufd_fault_fops_release,
 };
 
+static int iommufd_fault_init(struct iommufd_fault *fault, char *name,
+			      struct iommufd_ctx *ictx)
+{
+	struct file *filep;
+	int fdno;
+
+	mutex_init(&fault->mutex);
+	INIT_LIST_HEAD(&fault->deliver);
+	init_waitqueue_head(&fault->wait_queue);
+
+	filep = anon_inode_getfile(name, &iommufd_fault_fops, fault, O_RDWR);
+	if (IS_ERR(filep))
+		return PTR_ERR(filep);
+
+	fault->ictx = ictx;
+	iommufd_ctx_get(fault->ictx);
+	fault->filep = filep;
+	refcount_inc(&fault->obj.users);
+
+	fdno = get_unused_fd_flags(O_CLOEXEC);
+	if (fdno < 0)
+		fput(filep);
+	return fdno;
+}
+
 int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 {
 	struct iommu_fault_alloc *cmd = ucmd->cmd;
 	struct iommufd_fault *fault;
-	struct file *filep;
 	int fdno;
 	int rc;
 
@@ -382,27 +406,12 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 	if (IS_ERR(fault))
 		return PTR_ERR(fault);
 
-	fault->ictx = ucmd->ictx;
-	INIT_LIST_HEAD(&fault->deliver);
 	xa_init_flags(&fault->response, XA_FLAGS_ALLOC1);
-	mutex_init(&fault->mutex);
-	init_waitqueue_head(&fault->wait_queue);
-
-	filep = anon_inode_getfile("[iommufd-pgfault]", &iommufd_fault_fops,
-				   fault, O_RDWR);
-	if (IS_ERR(filep)) {
-		rc = PTR_ERR(filep);
-		goto out_abort;
-	}
 
-	refcount_inc(&fault->obj.users);
-	iommufd_ctx_get(fault->ictx);
-	fault->filep = filep;
-
-	fdno = get_unused_fd_flags(O_CLOEXEC);
+	fdno = iommufd_fault_init(fault, "[iommufd-pgfault]", ucmd->ictx);
 	if (fdno < 0) {
 		rc = fdno;
-		goto out_fput;
+		goto out_abort;
 	}
 
 	cmd->out_fault_id = fault->obj.id;
@@ -418,8 +427,7 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 	return 0;
 out_put_fdno:
 	put_unused_fd(fdno);
-out_fput:
-	fput(filep);
+	fput(fault->filep);
 out_abort:
 	iommufd_object_abort_and_destroy(ucmd->ictx, &fault->obj);
 
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:17 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:17 -0800
Subject: [PATCH v3 04/14] iommufd: Abstract an iommufd_eventq from iommufd_fault
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <b6ad96bb6404069460871a2662e305241742e72c.1734477608.git.nicolinc@nvidia.com>

The fault object was designed exclusively for hwpt's IO page faults (PRI).
But its queue implementation can be reused for other purposes too, such as
hardware IRQ and event injections to user space.

Meanwhile, a fault object holds a list of faults. So it's more accurate to
call it a "fault queue". Combining the reusing idea above, abstract a new
iommufd_eventq as a common structure embedded into struct iommufd_fault,
similar to hwpt_paging holding a common hwpt.

Add a common iommufd_eventq_ops and iommufd_eventq_init to prepare for an
IOMMUFD_OBJ_VIRQ.

Also, add missing xa_destroy and mutex_destroy in iommufd_fault_destroy().

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommufd/iommufd_private.h |  52 ++++++---
 drivers/iommu/iommufd/fault.c           | 142 +++++++++++++++---------
 drivers/iommu/iommufd/hw_pagetable.c    |   6 +-
 3 files changed, 130 insertions(+), 70 deletions(-)

diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index 8b378705ee71..dfbc5cfbd164 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -18,6 +18,7 @@ struct iommu_domain;
 struct iommu_group;
 struct iommu_option;
 struct iommufd_device;
+struct iommufd_eventq;
 
 struct iommufd_ctx {
 	struct file *file;
@@ -433,32 +434,35 @@ void iopt_remove_access(struct io_pagetable *iopt,
 			u32 iopt_access_list_id);
 void iommufd_access_destroy_object(struct iommufd_object *obj);
 
-/*
- * An iommufd_fault object represents an interface to deliver I/O page faults
- * to the user space. These objects are created/destroyed by the user space and
- * associated with hardware page table objects during page-table allocation.
- */
-struct iommufd_fault {
+struct iommufd_eventq_ops {
+	ssize_t (*read)(struct iommufd_eventq *eventq, char __user *buf,
+			size_t count, loff_t *ppos); /* Mandatory op */
+	ssize_t (*write)(struct iommufd_eventq *eventq, const char __user *buf,
+			 size_t count, loff_t *ppos); /* Optional op */
+};
+
+struct iommufd_eventq {
 	struct iommufd_object obj;
 	struct iommufd_ctx *ictx;
 	struct file *filep;
 
-	/* The lists of outstanding faults protected by below mutex. */
+	const struct iommufd_eventq_ops *ops;
+
+	/* The lists of outstanding events protected by below mutex. */
 	struct mutex mutex;
 	struct list_head deliver;
-	struct xarray response;
 
 	struct wait_queue_head wait_queue;
 };
 
-static inline int iommufd_fault_notify(struct iommufd_fault *fault,
-				       struct list_head *new_fault)
+static inline int iommufd_eventq_notify(struct iommufd_eventq *eventq,
+					struct list_head *new_event)
 {
-	mutex_lock(&fault->mutex);
-	list_add_tail(new_fault, &fault->deliver);
-	mutex_unlock(&fault->mutex);
+	mutex_lock(&eventq->mutex);
+	list_add_tail(new_event, &eventq->deliver);
+	mutex_unlock(&eventq->mutex);
 
-	wake_up_interruptible(&fault->wait_queue);
+	wake_up_interruptible(&eventq->wait_queue);
 	return 0;
 }
 
@@ -470,12 +474,28 @@ struct iommufd_attach_handle {
 /* Convert an iommu attach handle to iommufd handle. */
 #define to_iommufd_handle(hdl)	container_of(hdl, struct iommufd_attach_handle, handle)
 
+/*
+ * An iommufd_fault object represents an interface to deliver I/O page faults
+ * to the user space. These objects are created/destroyed by the user space and
+ * associated with hardware page table objects during page-table allocation.
+ */
+struct iommufd_fault {
+	struct iommufd_eventq common;
+	struct xarray response;
+};
+
+static inline struct iommufd_fault *
+eventq_to_fault(struct iommufd_eventq *eventq)
+{
+	return container_of(eventq, struct iommufd_fault, common);
+}
+
 static inline struct iommufd_fault *
 iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id)
 {
 	return container_of(iommufd_get_object(ucmd->ictx, id,
 					       IOMMUFD_OBJ_FAULT),
-			    struct iommufd_fault, obj);
+			    struct iommufd_fault, common.obj);
 }
 
 int iommufd_fault_alloc(struct iommufd_ucmd *ucmd);
@@ -486,7 +506,7 @@ static inline int iommufd_fault_iopf_handler(struct iopf_group *group)
 	struct iommufd_hw_pagetable *hwpt =
 		group->attach_handle->domain->fault_data;
 
-	return iommufd_fault_notify(hwpt->fault, &group->node);
+	return iommufd_eventq_notify(&hwpt->fault->common, &group->node);
 }
 
 int iommufd_fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
index d188994e4e84..e386b6c3e6ab 100644
--- a/drivers/iommu/iommufd/fault.c
+++ b/drivers/iommu/iommufd/fault.c
@@ -17,6 +17,8 @@
 #include "../iommu-priv.h"
 #include "iommufd_private.h"
 
+/* IOMMUFD_OBJ_FAULT Functions */
+
 static int iommufd_fault_iopf_enable(struct iommufd_device *idev)
 {
 	struct device *dev = idev->dev;
@@ -108,8 +110,8 @@ static void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
 	if (!fault)
 		return;
 
-	mutex_lock(&fault->mutex);
-	list_for_each_entry_safe(group, next, &fault->deliver, node) {
+	mutex_lock(&fault->common.mutex);
+	list_for_each_entry_safe(group, next, &fault->common.deliver, node) {
 		if (group->attach_handle != &handle->handle)
 			continue;
 		list_del(&group->node);
@@ -124,7 +126,7 @@ static void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
 		iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
 		iopf_free_group(group);
 	}
-	mutex_unlock(&fault->mutex);
+	mutex_unlock(&fault->common.mutex);
 }
 
 static struct iommufd_attach_handle *
@@ -211,7 +213,8 @@ int iommufd_fault_domain_replace_dev(struct iommufd_device *idev,
 
 void iommufd_fault_destroy(struct iommufd_object *obj)
 {
-	struct iommufd_fault *fault = container_of(obj, struct iommufd_fault, obj);
+	struct iommufd_eventq *eventq =
+		container_of(obj, struct iommufd_eventq, obj);
 	struct iopf_group *group, *next;
 
 	/*
@@ -220,11 +223,13 @@ void iommufd_fault_destroy(struct iommufd_object *obj)
 	 * accessing this pointer. Therefore, acquiring the mutex here
 	 * is unnecessary.
 	 */
-	list_for_each_entry_safe(group, next, &fault->deliver, node) {
+	list_for_each_entry_safe(group, next, &eventq->deliver, node) {
 		list_del(&group->node);
 		iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
 		iopf_free_group(group);
 	}
+	xa_destroy(&eventq_to_fault(eventq)->response);
+	mutex_destroy(&eventq->mutex);
 }
 
 static void iommufd_compose_fault_message(struct iommu_fault *fault,
@@ -242,11 +247,12 @@ static void iommufd_compose_fault_message(struct iommu_fault *fault,
 	hwpt_fault->cookie = cookie;
 }
 
-static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
-				       size_t count, loff_t *ppos)
+static ssize_t iommufd_fault_fops_read(struct iommufd_eventq *eventq,
+				       char __user *buf, size_t count,
+				       loff_t *ppos)
 {
 	size_t fault_size = sizeof(struct iommu_hwpt_pgfault);
-	struct iommufd_fault *fault = filep->private_data;
+	struct iommufd_fault *fault = eventq_to_fault(eventq);
 	struct iommu_hwpt_pgfault data;
 	struct iommufd_device *idev;
 	struct iopf_group *group;
@@ -257,10 +263,10 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
 	if (*ppos || count % fault_size)
 		return -ESPIPE;
 
-	mutex_lock(&fault->mutex);
-	while (!list_empty(&fault->deliver) && count > done) {
-		group = list_first_entry(&fault->deliver,
-					 struct iopf_group, node);
+	mutex_lock(&eventq->mutex);
+	while (!list_empty(&eventq->deliver) && count > done) {
+		group = list_first_entry(&eventq->deliver, struct iopf_group,
+					 node);
 
 		if (group->fault_count * fault_size > count - done)
 			break;
@@ -285,16 +291,17 @@ static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
 
 		list_del(&group->node);
 	}
-	mutex_unlock(&fault->mutex);
+	mutex_unlock(&eventq->mutex);
 
 	return done == 0 ? rc : done;
 }
 
-static ssize_t iommufd_fault_fops_write(struct file *filep, const char __user *buf,
-					size_t count, loff_t *ppos)
+static ssize_t iommufd_fault_fops_write(struct iommufd_eventq *eventq,
+					const char __user *buf, size_t count,
+					loff_t *ppos)
 {
 	size_t response_size = sizeof(struct iommu_hwpt_page_response);
-	struct iommufd_fault *fault = filep->private_data;
+	struct iommufd_fault *fault = eventq_to_fault(eventq);
 	struct iommu_hwpt_page_response response;
 	struct iopf_group *group;
 	size_t done = 0;
@@ -303,7 +310,7 @@ static ssize_t iommufd_fault_fops_write(struct file *filep, const char __user *b
 	if (*ppos || count % response_size)
 		return -ESPIPE;
 
-	mutex_lock(&fault->mutex);
+	mutex_lock(&eventq->mutex);
 	while (count > done) {
 		rc = copy_from_user(&response, buf + done, response_size);
 		if (rc)
@@ -329,62 +336,93 @@ static ssize_t iommufd_fault_fops_write(struct file *filep, const char __user *b
 		iopf_free_group(group);
 		done += response_size;
 	}
-	mutex_unlock(&fault->mutex);
+	mutex_unlock(&eventq->mutex);
 
 	return done == 0 ? rc : done;
 }
 
-static __poll_t iommufd_fault_fops_poll(struct file *filep,
-					struct poll_table_struct *wait)
+static const struct iommufd_eventq_ops iommufd_fault_ops = {
+	.read = &iommufd_fault_fops_read,
+	.write = &iommufd_fault_fops_write,
+};
+
+/* Common Event Queue Functions */
+
+static ssize_t iommufd_eventq_fops_read(struct file *filep, char __user *buf,
+					size_t count, loff_t *ppos)
 {
-	struct iommufd_fault *fault = filep->private_data;
+	struct iommufd_eventq *eventq = filep->private_data;
+
+	return eventq->ops->read(eventq, buf, count, ppos);
+}
+
+static ssize_t iommufd_eventq_fops_write(struct file *filep,
+					 const char __user *buf, size_t count,
+					 loff_t *ppos)
+{
+	struct iommufd_eventq *eventq = filep->private_data;
+
+	if (!eventq->ops->write)
+		return -EOPNOTSUPP;
+	return eventq->ops->write(eventq, buf, count, ppos);
+}
+
+static __poll_t iommufd_eventq_fops_poll(struct file *filep,
+					 struct poll_table_struct *wait)
+{
+	struct iommufd_eventq *eventq = filep->private_data;
 	__poll_t pollflags = EPOLLOUT;
 
-	poll_wait(filep, &fault->wait_queue, wait);
-	mutex_lock(&fault->mutex);
-	if (!list_empty(&fault->deliver))
+	poll_wait(filep, &eventq->wait_queue, wait);
+	mutex_lock(&eventq->mutex);
+	if (!list_empty(&eventq->deliver))
 		pollflags |= EPOLLIN | EPOLLRDNORM;
-	mutex_unlock(&fault->mutex);
+	mutex_unlock(&eventq->mutex);
 
 	return pollflags;
 }
 
-static int iommufd_fault_fops_release(struct inode *inode, struct file *filep)
+static int iommufd_eventq_fops_release(struct inode *inode, struct file *filep)
 {
-	struct iommufd_fault *fault = filep->private_data;
+	struct iommufd_eventq *eventq = filep->private_data;
 
-	refcount_dec(&fault->obj.users);
-	iommufd_ctx_put(fault->ictx);
+	refcount_dec(&eventq->obj.users);
+	iommufd_ctx_put(eventq->ictx);
 	return 0;
 }
 
-static const struct file_operations iommufd_fault_fops = {
+static const struct file_operations iommufd_eventq_fops = {
 	.owner		= THIS_MODULE,
 	.open		= nonseekable_open,
-	.read		= iommufd_fault_fops_read,
-	.write		= iommufd_fault_fops_write,
-	.poll		= iommufd_fault_fops_poll,
-	.release	= iommufd_fault_fops_release,
+	.read		= iommufd_eventq_fops_read,
+	.write		= iommufd_eventq_fops_write,
+	.poll		= iommufd_eventq_fops_poll,
+	.release	= iommufd_eventq_fops_release,
 };
 
-static int iommufd_fault_init(struct iommufd_fault *fault, char *name,
-			      struct iommufd_ctx *ictx)
+static int iommufd_eventq_init(struct iommufd_eventq *eventq, char *name,
+			       struct iommufd_ctx *ictx,
+			       const struct iommufd_eventq_ops *ops)
 {
 	struct file *filep;
 	int fdno;
 
-	mutex_init(&fault->mutex);
-	INIT_LIST_HEAD(&fault->deliver);
-	init_waitqueue_head(&fault->wait_queue);
+	if (WARN_ON_ONCE(!ops || !ops->read))
+		return -EINVAL;
+
+	mutex_init(&eventq->mutex);
+	INIT_LIST_HEAD(&eventq->deliver);
+	init_waitqueue_head(&eventq->wait_queue);
 
-	filep = anon_inode_getfile(name, &iommufd_fault_fops, fault, O_RDWR);
+	filep = anon_inode_getfile(name, &iommufd_eventq_fops, eventq, O_RDWR);
 	if (IS_ERR(filep))
 		return PTR_ERR(filep);
 
-	fault->ictx = ictx;
-	iommufd_ctx_get(fault->ictx);
-	fault->filep = filep;
-	refcount_inc(&fault->obj.users);
+	eventq->ops = ops;
+	eventq->ictx = ictx;
+	iommufd_ctx_get(eventq->ictx);
+	refcount_inc(&eventq->obj.users);
+	eventq->filep = filep;
 
 	fdno = get_unused_fd_flags(O_CLOEXEC);
 	if (fdno < 0)
@@ -402,34 +440,36 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 	if (cmd->flags)
 		return -EOPNOTSUPP;
 
-	fault = iommufd_object_alloc(ucmd->ictx, fault, IOMMUFD_OBJ_FAULT);
+	fault = __iommufd_object_alloc(ucmd->ictx, fault, IOMMUFD_OBJ_FAULT,
+				       common.obj);
 	if (IS_ERR(fault))
 		return PTR_ERR(fault);
 
 	xa_init_flags(&fault->response, XA_FLAGS_ALLOC1);
 
-	fdno = iommufd_fault_init(fault, "[iommufd-pgfault]", ucmd->ictx);
+	fdno = iommufd_eventq_init(&fault->common, "[iommufd-pgfault]",
+				   ucmd->ictx, &iommufd_fault_ops);
 	if (fdno < 0) {
 		rc = fdno;
 		goto out_abort;
 	}
 
-	cmd->out_fault_id = fault->obj.id;
+	cmd->out_fault_id = fault->common.obj.id;
 	cmd->out_fault_fd = fdno;
 
 	rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
 	if (rc)
 		goto out_put_fdno;
-	iommufd_object_finalize(ucmd->ictx, &fault->obj);
+	iommufd_object_finalize(ucmd->ictx, &fault->common.obj);
 
-	fd_install(fdno, fault->filep);
+	fd_install(fdno, fault->common.filep);
 
 	return 0;
 out_put_fdno:
 	put_unused_fd(fdno);
-	fput(fault->filep);
+	fput(fault->common.filep);
 out_abort:
-	iommufd_object_abort_and_destroy(ucmd->ictx, &fault->obj);
+	iommufd_object_abort_and_destroy(ucmd->ictx, &fault->common.obj);
 
 	return rc;
 }
diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c
index ce03c3804651..12a576f1f13d 100644
--- a/drivers/iommu/iommufd/hw_pagetable.c
+++ b/drivers/iommu/iommufd/hw_pagetable.c
@@ -14,7 +14,7 @@ static void __iommufd_hwpt_destroy(struct iommufd_hw_pagetable *hwpt)
 		iommu_domain_free(hwpt->domain);
 
 	if (hwpt->fault)
-		refcount_dec(&hwpt->fault->obj.users);
+		refcount_dec(&hwpt->fault->common.obj.users);
 }
 
 void iommufd_hwpt_paging_destroy(struct iommufd_object *obj)
@@ -403,8 +403,8 @@ int iommufd_hwpt_alloc(struct iommufd_ucmd *ucmd)
 		hwpt->fault = fault;
 		hwpt->domain->iopf_handler = iommufd_fault_iopf_handler;
 		hwpt->domain->fault_data = hwpt;
-		refcount_inc(&fault->obj.users);
-		iommufd_put_object(ucmd->ictx, &fault->obj);
+		refcount_inc(&fault->common.obj.users);
+		iommufd_put_object(ucmd->ictx, &fault->common.obj);
 	}
 
 	cmd->out_hwpt_id = hwpt->obj.id;
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:24 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:24 -0800
Subject: [PATCH v3 11/14] iommufd/selftest: Add IOMMU_VIRQ_ALLOC test coverage
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <6421cf753e6084c872e337e8c5df8a5acb20f050.1734477608.git.nicolinc@nvidia.com>

Trigger a vIRQ giving an idev ID, to test the loopback whether receiving
or not the vdev_id that was set to the idev by the line above.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 tools/testing/selftests/iommu/iommufd_utils.h | 63 +++++++++++++++++++
 tools/testing/selftests/iommu/iommufd.c       | 22 +++++++
 .../selftests/iommu/iommufd_fail_nth.c        |  6 ++
 3 files changed, 91 insertions(+)

diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
index d979f5b0efe8..9f03955cb198 100644
--- a/tools/testing/selftests/iommu/iommufd_utils.h
+++ b/tools/testing/selftests/iommu/iommufd_utils.h
@@ -9,6 +9,7 @@
 #include <sys/ioctl.h>
 #include <stdint.h>
 #include <assert.h>
+#include <poll.h>
 
 #include "../kselftest_harness.h"
 #include "../../../../drivers/iommu/iommufd/iommufd_test.h"
@@ -936,3 +937,65 @@ static int _test_cmd_vdevice_alloc(int fd, __u32 viommu_id, __u32 idev_id,
 	EXPECT_ERRNO(_errno,                                                 \
 		     _test_cmd_vdevice_alloc(self->fd, viommu_id, idev_id,   \
 					     virt_id, vdev_id))
+
+static int _test_cmd_virq_alloc(int fd, __u32 viommu_id, __u32 type,
+				__u32 *virq_id, __u32 *virq_fd)
+{
+	struct iommu_virq_alloc cmd = {
+		.size = sizeof(cmd),
+		.type = type,
+		.viommu_id = viommu_id,
+	};
+	int ret;
+
+	ret = ioctl(fd, IOMMU_VIRQ_ALLOC, &cmd);
+	if (ret)
+		return ret;
+	if (virq_id)
+		*virq_id = cmd.out_virq_id;
+	if (virq_fd)
+		*virq_fd = cmd.out_virq_fd;
+	return 0;
+}
+
+#define test_cmd_virq_alloc(viommu_id, type, virq_id, virq_fd)                \
+	ASSERT_EQ(0, _test_cmd_virq_alloc(self->fd, viommu_id, type, virq_id, \
+					  virq_fd))
+#define test_err_virq_alloc(_errno, viommu_id, type, virq_id, virq_fd)       \
+	EXPECT_ERRNO(_errno, _test_cmd_virq_alloc(self->fd, viommu_id, type, \
+						  virq_id, virq_fd))
+
+static int _test_cmd_trigger_virq(int fd, __u32 dev_id, __u32 event_fd,
+				  __u32 virt_id)
+{
+	struct iommu_test_cmd trigger_virq_cmd = {
+		.size = sizeof(trigger_virq_cmd),
+		.op = IOMMU_TEST_OP_TRIGGER_VIRQ,
+		.trigger_virq = {
+			.dev_id = dev_id,
+		},
+	};
+	struct pollfd pollfd = { .fd = event_fd, .events = POLLIN };
+	struct iommu_viommu_irq_selftest irq;
+	ssize_t bytes;
+	int ret;
+
+	ret = ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_TRIGGER_VIRQ),
+		    &trigger_virq_cmd);
+	if (ret)
+		return ret;
+
+	ret = poll(&pollfd, 1, 1000);
+	if (ret < 0)
+		return ret;
+
+	bytes = read(event_fd, &irq, sizeof(irq));
+	if (bytes <= 0)
+		return -EIO;
+
+	return irq.virt_id == virt_id ? 0 : -EINVAL;
+}
+
+#define test_cmd_trigger_virq(dev_id, event_fd, vdev_id) \
+	ASSERT_EQ(0,                                     \
+		  _test_cmd_trigger_virq(self->fd, dev_id, event_fd, vdev_id))
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index 212e5d62e13d..b15ebc963e56 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -2774,15 +2774,37 @@ TEST_F(iommufd_viommu, vdevice_alloc)
 	uint32_t viommu_id = self->viommu_id;
 	uint32_t dev_id = self->device_id;
 	uint32_t vdev_id = 0;
+	uint32_t virq_id;
+	uint32_t virq_fd;
 
 	if (dev_id) {
+		/* Must allocate vdevice before attaching to a nested hwpt */
+		test_err_mock_domain_replace(ENOENT, self->stdev_id,
+					     self->nested_hwpt_id);
+
+		test_cmd_virq_alloc(viommu_id, IOMMU_VIRQ_TYPE_SELFTEST,
+				    &virq_id, &virq_fd);
+		test_err_virq_alloc(EEXIST, viommu_id, IOMMU_VIRQ_TYPE_SELFTEST,
+				    NULL, NULL);
 		/* Set vdev_id to 0x99, unset it, and set to 0x88 */
 		test_cmd_vdevice_alloc(viommu_id, dev_id, 0x99, &vdev_id);
+		test_cmd_mock_domain_replace(self->stdev_id,
+					     self->nested_hwpt_id);
+		test_cmd_trigger_virq(dev_id, virq_fd, 0x99);
 		test_err_vdevice_alloc(EEXIST, viommu_id, dev_id, 0x99,
 				       &vdev_id);
+		test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
 		test_ioctl_destroy(vdev_id);
+
+		/* Try again with 0x88 */
 		test_cmd_vdevice_alloc(viommu_id, dev_id, 0x88, &vdev_id);
+		test_cmd_mock_domain_replace(self->stdev_id,
+					     self->nested_hwpt_id);
+		test_cmd_trigger_virq(dev_id, virq_fd, 0x88);
+		close(virq_fd);
+		test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
 		test_ioctl_destroy(vdev_id);
+		test_ioctl_destroy(virq_id);
 	} else {
 		test_err_vdevice_alloc(ENOENT, viommu_id, dev_id, 0x99, NULL);
 	}
diff --git a/tools/testing/selftests/iommu/iommufd_fail_nth.c b/tools/testing/selftests/iommu/iommufd_fail_nth.c
index 64b1f8e1b0cf..442442de3a75 100644
--- a/tools/testing/selftests/iommu/iommufd_fail_nth.c
+++ b/tools/testing/selftests/iommu/iommufd_fail_nth.c
@@ -620,6 +620,7 @@ TEST_FAIL_NTH(basic_fail_nth, device)
 	};
 	struct iommu_test_hw_info info;
 	uint32_t fault_id, fault_fd;
+	uint32_t virq_id, virq_fd;
 	uint32_t fault_hwpt_id;
 	uint32_t ioas_id;
 	uint32_t ioas_id2;
@@ -692,6 +693,11 @@ TEST_FAIL_NTH(basic_fail_nth, device)
 				 IOMMU_HWPT_DATA_SELFTEST, &data, sizeof(data)))
 		return -1;
 
+	if (_test_cmd_virq_alloc(self->fd, viommu_id, IOMMU_VIRQ_TYPE_SELFTEST,
+				 &virq_id, &virq_fd))
+		return -1;
+	close(virq_fd);
+
 	return 0;
 }
 
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:25 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:25 -0800
Subject: [PATCH v3 12/14] Documentation: userspace-api: iommufd: Update FAULT and VIRQ
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <9026d32c1ef46ca867e27777f653c736551ba692.1734477608.git.nicolinc@nvidia.com>

With the introduction of the new objects, update the doc to reflect that.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 Documentation/userspace-api/iommufd.rst | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/userspace-api/iommufd.rst b/Documentation/userspace-api/iommufd.rst
index 70289d6815d2..5b4ef5d74fd1 100644
--- a/Documentation/userspace-api/iommufd.rst
+++ b/Documentation/userspace-api/iommufd.rst
@@ -63,6 +63,13 @@ Following IOMMUFD objects are exposed to userspace:
   space usually has mappings from guest-level I/O virtual addresses to guest-
   level physical addresses.
 
+- IOMMUFD_FAULT, representing a software queue for an HWPT reporting IO page
+  faults using the IOMMU HW's PRI (Page Request Interface). This queue object
+  provides user space an FD to poll the page fault events and also to respond
+  to those events. A FAULT object must be created first to get a fault_id that
+  could be then used to allocate a fault-enabled HWPT via the IOMMU_HWPT_ALLOC
+  command by setting the IOMMU_HWPT_FAULT_ID_VALID bit in its flags field.
+
 - IOMMUFD_OBJ_VIOMMU, representing a slice of the physical IOMMU instance,
   passed to or shared with a VM. It may be some HW-accelerated virtualization
   features and some SW resources used by the VM. For examples:
@@ -109,6 +116,13 @@ Following IOMMUFD objects are exposed to userspace:
   vIOMMU, which is a separate ioctl call from attaching the same device to an
   HWPT_PAGING that the vIOMMU holds.
 
+- IOMMUFD_OBJ_VIRQ, representing a software queue for a vIOMMU reporting events
+  such as translation faults occurred to a nested stage-1 and HW-specific irqs.
+  This queue object provides user space an FD to poll the vIOMMU events/virqs.
+  A vIOMMU object must be created first to get its viommu_id that could be then
+  used to allocate a VIRQ. Each vIOMMU can support multiple types of VIRQs, but
+  is confined to one VIRQ per vIRQ type.
+
 All user-visible objects are destroyed via the IOMMU_DESTROY uAPI.
 
 The diagrams below show relationships between user-visible objects and kernel
@@ -251,8 +265,10 @@ User visible objects are backed by following datastructures:
 - iommufd_device for IOMMUFD_OBJ_DEVICE.
 - iommufd_hwpt_paging for IOMMUFD_OBJ_HWPT_PAGING.
 - iommufd_hwpt_nested for IOMMUFD_OBJ_HWPT_NESTED.
+- iommufd_fault for IOMMUFD_OBJ_FAULT.
 - iommufd_viommu for IOMMUFD_OBJ_VIOMMU.
 - iommufd_vdevice for IOMMUFD_OBJ_VDEVICE.
+- iommufd_virq for IOMMUFD_OBJ_VIRQ.
 
 Several terminologies when looking at these datastructures:
 
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:27 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:27 -0800
Subject: [PATCH v3 14/14] iommu/arm-smmu-v3: Report IRQs that belong to devices attached to vIOMMU
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <18cf51aa592840e9cd92a9ea1a157607db1a681a.1734477608.git.nicolinc@nvidia.com>

Aside from the IOPF framework, iommufd provides an additional pathway to
report a hardware event or IRQ, via the vIRQ of vIOMMU infrastructure.

Define an iommu_virq_arm_smmuv3 uAPI structure, and report stage-1 faults
in the threaded IRQ handler.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  7 +++
 include/uapi/linux/iommufd.h                  | 15 +++++
 .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c     | 16 +++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 58 +++++++++++--------
 4 files changed, 71 insertions(+), 25 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 4435ad7db776..d24c3d8ee397 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -1066,6 +1066,7 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
 int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
 				    struct iommu_domain *domain);
 void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state);
+int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt);
 #else
 #define arm_smmu_hw_info NULL
 #define arm_vsmmu_alloc NULL
@@ -1081,6 +1082,12 @@ static inline void
 arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
 {
 }
+
+static inline int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster,
+					   u64 *evt)
+{
+	return -EOPNOTSUPP;
+}
 #endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
 
 #endif /* _ARM_SMMU_V3_H */
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index cdf2dba28d4a..579529ff6fa7 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -1016,9 +1016,24 @@ struct iommu_ioas_change_process {
 /**
  * enum iommu_virq_type - Virtual IRQ Type
  * @IOMMU_VIRQ_TYPE_NONE: INVALID type
+ * @IOMMU_VIRQ_TYPE_ARM_SMMUV3: ARM SMMUv3 Virtual Event
  */
 enum iommu_virq_type {
 	IOMMU_VIRQ_TYPE_NONE = 0,
+	IOMMU_VIRQ_TYPE_ARM_SMMUV3 = 1,
+};
+
+/**
+ * struct iommu_virq_arm_smmuv3 - ARM SMMUv3 Virtual IRQ
+ *                                (IOMMU_VIRQ_TYPE_ARM_SMMUV3)
+ * @evt: 256-bit ARM SMMUv3 Event record, little-endian.
+ *       (Refer to "7.3 Event records" in SMMUv3 HW Spec)
+ *
+ * StreamID field reports a virtual device ID. To receive a virtual IRQ for a
+ * device, a vDEVICE must be allocated via IOMMU_VDEVICE_ALLOC.
+ */
+struct iommu_virq_arm_smmuv3 {
+	__aligned_le64 evt[4];
 };
 
 /**
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 2b6253ef0e8f..e85456c7ff52 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -447,4 +447,20 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
 	return &vsmmu->core;
 }
 
+int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt)
+{
+	struct iommu_virq_arm_smmuv3 virq_data =
+		*(struct iommu_virq_arm_smmuv3 *)evt;
+
+	virq_data.evt[0] &= ~EVTQ_0_SID;
+	virq_data.evt[0] |= FIELD_PREP(EVTQ_0_SID, vmaster->vsid);
+
+	virq_data.evt[0] = cpu_to_le64(virq_data.evt[0]);
+	virq_data.evt[1] = cpu_to_le64(virq_data.evt[1]);
+
+	return iommufd_viommu_report_irq(&vmaster->vsmmu->core,
+					 IOMMU_VIRQ_TYPE_ARM_SMMUV3, &virq_data,
+					 sizeof(virq_data));
+}
+
 MODULE_IMPORT_NS("IOMMUFD");
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 686c171dd273..59fbc342a095 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1812,8 +1812,8 @@ static void arm_smmu_decode_event(struct arm_smmu_device *smmu, u64 *raw,
 	mutex_unlock(&smmu->streams_mutex);
 }
 
-static int arm_smmu_handle_event(struct arm_smmu_device *smmu,
-			       struct arm_smmu_event *event)
+static int arm_smmu_handle_event(struct arm_smmu_device *smmu, u64 *evt,
+				 struct arm_smmu_event *event)
 {
 	int ret = 0;
 	u32 perm = 0;
@@ -1831,31 +1831,30 @@ static int arm_smmu_handle_event(struct arm_smmu_device *smmu,
 		return -EOPNOTSUPP;
 	}
 
-	if (!event->stall)
-		return -EOPNOTSUPP;
-
-	if (event->read)
-		perm |= IOMMU_FAULT_PERM_READ;
-	else
-		perm |= IOMMU_FAULT_PERM_WRITE;
+	if (event->stall) {
+		if (event->read)
+			perm |= IOMMU_FAULT_PERM_READ;
+		else
+			perm |= IOMMU_FAULT_PERM_WRITE;
 
-	if (event->instruction)
-		perm |= IOMMU_FAULT_PERM_EXEC;
+		if (event->instruction)
+			perm |= IOMMU_FAULT_PERM_EXEC;
 
-	if (event->privileged)
-		perm |= IOMMU_FAULT_PERM_PRIV;
+		if (event->privileged)
+			perm |= IOMMU_FAULT_PERM_PRIV;
 
-	flt->type = IOMMU_FAULT_PAGE_REQ;
-	flt->prm = (struct iommu_fault_page_request) {
-		.flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
-		.grpid = event->stag,
-		.perm = perm,
-		.addr = event->iova,
-	};
+		flt->type = IOMMU_FAULT_PAGE_REQ;
+		flt->prm = (struct iommu_fault_page_request){
+			.flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
+			.grpid = event->stag,
+			.perm = perm,
+			.addr = event->iova,
+		};
 
-	if (event->ssv) {
-		flt->prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
-		flt->prm.pasid = event->ssid;
+		if (event->ssv) {
+			flt->prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
+			flt->prm.pasid = event->ssid;
+		}
 	}
 
 	mutex_lock(&smmu->streams_mutex);
@@ -1865,7 +1864,16 @@ static int arm_smmu_handle_event(struct arm_smmu_device *smmu,
 		goto out_unlock;
 	}
 
-	ret = iommu_report_device_fault(master->dev, &fault_evt);
+	if (event->stall) {
+		ret = iommu_report_device_fault(master->dev, &fault_evt);
+	} else {
+		down_read(&master->vmaster_rwsem);
+		if (master->vmaster && !event->s2)
+			ret = arm_vmaster_report_event(master->vmaster, evt);
+		else
+			ret = -EFAULT; /* Unhandled events should be pinned */
+		up_read(&master->vmaster_rwsem);
+	}
 out_unlock:
 	mutex_unlock(&smmu->streams_mutex);
 	return ret;
@@ -1943,7 +1951,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
 	do {
 		while (!queue_remove_raw(q, evt)) {
 			arm_smmu_decode_event(smmu, evt, &event);
-			if (arm_smmu_handle_event(smmu, &event))
+			if (arm_smmu_handle_event(smmu, evt, &event))
 				arm_smmu_dump_event(smmu, evt, &event, &rs);
 
 			put_device(event.dev);
-- 
2.43.0



From nicolinc at nvidia.com  Tue Dec 17 21:00:26 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 17 Dec 2024 21:00:26 -0800
Subject: [PATCH v3 13/14] iommu/arm-smmu-v3: Introduce struct arm_smmu_vmaster
In-Reply-To: <cover.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
Message-ID: <7cb77321246cd7266068c8f2047d00c53bd245ef.1734477608.git.nicolinc@nvidia.com>

Use it to store all vSMMU-related data. The vsid (Virtual Stream ID) will
be the first use case. Then, add a rw_semaphore to protect it.

Also add a pair of arm_smmu_attach_prepare/commit_vmaster helpers to set
or unset the master->vmaster point. Put these helpers inside the existing
arm_smmu_attach_prepare/commit(). Note that identity and blocked ops don't
call arm_smmu_attach_prepare/commit(), thus simply call the new helpers at
the top, so a device attaching to an identity/blocked domain can unset the
master->vmaster when the device is moving away from a nested domain.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   | 23 +++++++++
 .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c     | 49 +++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 32 +++++++++++-
 3 files changed, 103 insertions(+), 1 deletion(-)

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 bd9d7c85576a..4435ad7db776 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -799,6 +799,11 @@ struct arm_smmu_stream {
 	struct rb_node			node;
 };
 
+struct arm_smmu_vmaster {
+	struct arm_vsmmu		*vsmmu;
+	unsigned long			vsid;
+};
+
 struct arm_smmu_event {
 	u8				stall : 1,
 					ssv : 1,
@@ -824,6 +829,8 @@ struct arm_smmu_master {
 	struct arm_smmu_device		*smmu;
 	struct device			*dev;
 	struct arm_smmu_stream		*streams;
+	struct arm_smmu_vmaster		*vmaster;
+	struct rw_semaphore		vmaster_rwsem;
 	/* Locked by the iommu core using the group mutex */
 	struct arm_smmu_ctx_desc_cfg	cd_table;
 	unsigned int			num_streams;
@@ -972,6 +979,7 @@ struct arm_smmu_attach_state {
 	bool disable_ats;
 	ioasid_t ssid;
 	/* Resulting state */
+	struct arm_smmu_vmaster *vmaster;
 	bool ats_enabled;
 };
 
@@ -1055,9 +1063,24 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
 				       struct iommu_domain *parent,
 				       struct iommufd_ctx *ictx,
 				       unsigned int viommu_type);
+int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+				    struct iommu_domain *domain);
+void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state);
 #else
 #define arm_smmu_hw_info NULL
 #define arm_vsmmu_alloc NULL
+
+static inline int
+arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+				struct iommu_domain *domain)
+{
+	return 0; /* NOP */
+}
+
+static inline void
+arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
+{
+}
 #endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
 
 #endif /* _ARM_SMMU_V3_H */
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index c7cc613050d9..2b6253ef0e8f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -85,6 +85,55 @@ static void arm_smmu_make_nested_domain_ste(
 	}
 }
 
+int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+				    struct iommu_domain *domain)
+{
+	struct arm_smmu_nested_domain *nested_domain;
+	struct arm_smmu_vmaster *vmaster;
+	unsigned long vsid;
+	unsigned int cfg;
+
+	iommu_group_mutex_assert(state->master->dev);
+
+	if (domain->type != IOMMU_DOMAIN_NESTED)
+		return 0;
+	nested_domain = to_smmu_nested_domain(domain);
+
+	/* Skip ABORT/BYPASS or invalid vSTE */
+	cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(nested_domain->ste[0]));
+	if (cfg == STRTAB_STE_0_CFG_ABORT || cfg == STRTAB_STE_0_CFG_BYPASS)
+		return 0;
+	if (!(nested_domain->ste[0] & cpu_to_le64(STRTAB_STE_0_V)))
+		return 0;
+
+	vsid = iommufd_viommu_get_vdev_id(&nested_domain->vsmmu->core,
+					  state->master->dev);
+	/* Fail the attach if vSID is not correct set by the user space */
+	if (!vsid)
+		return -ENOENT;
+
+	vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
+	if (!vmaster)
+		return -ENOMEM;
+	vmaster->vsmmu = nested_domain->vsmmu;
+	vmaster->vsid = vsid;
+	state->vmaster = vmaster;
+
+	return 0;
+}
+
+void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
+{
+	struct arm_smmu_master *master = state->master;
+
+	down_write(&master->vmaster_rwsem);
+	if (state->vmaster != master->vmaster) {
+		kfree(master->vmaster);
+		master->vmaster = state->vmaster;
+	}
+	up_write(&master->vmaster_rwsem);
+}
+
 static int arm_smmu_attach_dev_nested(struct iommu_domain *domain,
 				      struct device *dev)
 {
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 ea76f25c0661..686c171dd273 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2802,6 +2802,7 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
 	struct arm_smmu_domain *smmu_domain =
 		to_smmu_domain_devices(new_domain);
 	unsigned long flags;
+	int ret;
 
 	/*
 	 * arm_smmu_share_asid() must not see two domains pointing to the same
@@ -2831,9 +2832,15 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
 	}
 
 	if (smmu_domain) {
+		ret = arm_smmu_attach_prepare_vmaster(state, new_domain);
+		if (ret)
+			return ret;
+
 		master_domain = kzalloc(sizeof(*master_domain), GFP_KERNEL);
-		if (!master_domain)
+		if (!master_domain) {
+			kfree(state->vmaster);
 			return -ENOMEM;
+		}
 		master_domain->master = master;
 		master_domain->ssid = state->ssid;
 		if (new_domain->type == IOMMU_DOMAIN_NESTED)
@@ -2860,6 +2867,7 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
 			spin_unlock_irqrestore(&smmu_domain->devices_lock,
 					       flags);
 			kfree(master_domain);
+			kfree(state->vmaster);
 			return -EINVAL;
 		}
 
@@ -2892,6 +2900,8 @@ void arm_smmu_attach_commit(struct arm_smmu_attach_state *state)
 
 	lockdep_assert_held(&arm_smmu_asid_lock);
 
+	arm_smmu_attach_commit_vmaster(state);
+
 	if (state->ats_enabled && !master->ats_enabled) {
 		arm_smmu_enable_ats(master);
 	} else if (state->ats_enabled && master->ats_enabled) {
@@ -3158,8 +3168,17 @@ static void arm_smmu_attach_dev_ste(struct iommu_domain *domain,
 static int arm_smmu_attach_dev_identity(struct iommu_domain *domain,
 					struct device *dev)
 {
+	int ret;
 	struct arm_smmu_ste ste;
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct arm_smmu_attach_state state = {
+		.master = master,
+	};
+
+	ret = arm_smmu_attach_prepare_vmaster(&state, domain);
+	if (ret)
+		return ret;
+	arm_smmu_attach_commit_vmaster(&state);
 
 	arm_smmu_make_bypass_ste(master->smmu, &ste);
 	arm_smmu_attach_dev_ste(domain, dev, &ste, STRTAB_STE_1_S1DSS_BYPASS);
@@ -3178,7 +3197,17 @@ static struct iommu_domain arm_smmu_identity_domain = {
 static int arm_smmu_attach_dev_blocked(struct iommu_domain *domain,
 					struct device *dev)
 {
+	int ret;
 	struct arm_smmu_ste ste;
+	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct arm_smmu_attach_state state = {
+		.master = master,
+	};
+
+	ret = arm_smmu_attach_prepare_vmaster(&state, domain);
+	if (ret)
+		return ret;
+	arm_smmu_attach_commit_vmaster(&state);
 
 	arm_smmu_make_abort_ste(&ste);
 	arm_smmu_attach_dev_ste(domain, dev, &ste,
@@ -3428,6 +3457,7 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 
 	master->dev = dev;
 	master->smmu = smmu;
+	init_rwsem(&master->vmaster_rwsem);
 	dev_iommu_priv_set(dev, master);
 
 	ret = arm_smmu_insert_master(smmu, master);
-- 
2.43.0



From dsimic at manjaro.org  Tue Dec 17 21:19:17 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 18 Dec 2024 06:19:17 +0100
Subject: [PATCH 1/3] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and
 PLL_MIPI
In-Reply-To: <20241218013836.421cc616@minigeek.lan>
References: <20241215053639.738890-1-anarsoul@gmail.com>
 <20241215053639.738890-2-anarsoul@gmail.com>
 <qbtp4jvkx3r5azufe4k3vtapqpfs54dyjiu4cy5v5wkkzumrzx@vy3xzkfplbue>
 <CA+E=qVeQ8uHBCeFtw6_2cY3252-YXc6eWrf5_YdeVgbp5LJo5g@mail.gmail.com>
 <20241217211505.7f9c9e4e@minigeek.lan>
 <d0bf0d9cd2df65dc2e17eb203d56eb13@manjaro.org>
 <20241218013836.421cc616@minigeek.lan>
Message-ID: <96ce1cce894a8bd5aa302d5f5183f64c@manjaro.org>

Hello Andre,

On 2024-12-18 02:38, Andre Przywara wrote:
> On Tue, 17 Dec 2024 23:02:43 +0100
> Dragan Simic <dsimic at manjaro.org> wrote:
>> On 2024-12-17 22:15, Andre Przywara wrote:
>> > On Tue, 17 Dec 2024 10:00:45 -0800
>> > Vasily Khoruzhick <anarsoul at gmail.com> wrote:
>> >> On Mon, Dec 16, 2024 at 11:33?PM Krzysztof Kozlowski <krzk at kernel.org>
>> >> wrote:
>> >> >
>> >> > On Sat, Dec 14, 2024 at 09:34:57PM -0800, Vasily Khoruzhick wrote:
>> >> > > These will be used to explicitly select TCON0 clock parent in dts
>> >> > >
>> >> > > Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
>> >> > > Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
>> >> > > ---
>> >> > >  drivers/clk/sunxi-ng/ccu-sun50i-a64.h      | 2 --
>> >> > >  include/dt-bindings/clock/sun50i-a64-ccu.h | 2 +
>> >>
>> >> > You cannot combine these changes.
>> >>
>> >> The patch basically moves defines out from ccu-sun50i-a64.h to
>> >> sun50i-a64-ccu.h. How do I split the change without introducing
>> >> compilation failure?
>> >
>> > You can just have the binding part first, adding the (same) definition
>> > to the binding headers. As long as the #define's are not conflicting,
>> > this is fine.
>> > Then remove the now redundant definitions in the kernel headers, with a
>> > subsequent patch.
>> 
>> Yes, that would be a way to make it formally correct, but also much
>> less readable and understandable later, as part of the source code
>> repository.  FWIW, I find this to be an example of the form being
>> more important than the actual function.
> 
> Not sure I understand your last sentence, exactly,

Ah, sorry, I also saw the need to expand that sentence a bit, but only
after I had already sent my message. :/

> but what Krzysztof pointed out is that one part (the header change in
> include/dt-bindings) is a DT binding patch, so part of a spec, if you
> like, the other is Linux *code*. There is the DT rebasing repo, which
> cherry-picks DT patches, so they form a separate history there, and
> Linux code has no place in there. U-Boot for instance pull this
> repo now on a regular basis. So keeping those things strictly separate
> is really important here.

Thanks a lot for your detailed explanation and for reminding me about
the DT rebasing repository. [*]  I forgot about it for a moment, despite
being active in U-Boot development when the repository was introduced,
so yes, you're right that we're now in need to keep the bindings and the
kernel code separate in patches.

However, I can't stop myself from noticing that the way Krzysztof 
replied
left a lot to be desired when it comes to friendliness in general.  Such
an approach is probably what contributed to me forgetting about the DT
rebasing repository for a moment.

[*] 
https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/

>> >> > Please run scripts/checkpatch.pl and fix reported warnings. Then please
>> >> > run 'scripts/checkpatch.pl --strict' and (probably) fix more warnings.
>> >> > Some warnings can be ignored, especially from --strict run, but the code
>> >> > here looks like it needs a fix. Feel free to get in touch if the warning
>> >> > is not clear.
>> >>
>> >> Yeah, it is not clear what do you want me to do, assuming the previous
>> >> similar change to sun50i-a64-ccu.h did essentially the same, see
>> >> 71b597ef5d46a326fb0d5cbfc1c6ff1d73cdc7f9


From dmitry.baryshkov at linaro.org  Tue Dec 17 21:24:23 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 18 Dec 2024 07:24:23 +0200
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <20241217-vivacious-chameleon-of-swiftness-f1edc4@houat>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org> <20241217-vivacious-chameleon-of-swiftness-f1edc4@houat>
Message-ID: <CAA8EJprjCyWBNkRrc4W24uCwPtf_kxZLqNeNP8EJffbutYQ21w@mail.gmail.com>

On Tue, 17 Dec 2024 at 19:21, Maxime Ripard <mripard at kernel.org> wrote:
>
> Hi,
>
> On Tue, Dec 17, 2024 at 02:40:22AM +0200, Dmitry Baryshkov wrote:
> > While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
> > framework, I stumbled upon an issue while handling the Audio InfoFrames.
> > The HDMI codec callbacks weren't receiving the drm_atomic_state, so
> > there was no simple way to get the drm_connector that stayed at the end
> > of the bridge chain. At the same point the drm_hdmi_connector functions
> > expected to get drm_connector instance.
> >
> > While looking for a way to solve the issue, I stumbled upon several
> > deficiencies in existing hdmi_codec_ops implementations. Only few of the
> > implementations were able to handle codec's 'plugged' callback. One
> > third of the drivers didn't implement the get_eld() callback.
> >
> > Most of the issues can be solved if drm_connector handles
> > hdmi-audio-codec on its own, delegating functionality to the actual
> > implementation, be it a driver that implements drm_connector or
> > drm_bridge.
> >
> > Implement such high-level framework, adding proper support for Audio
> > InfoFrame generation to the LT9611 driver.
> >
> > Several design decisions to be kept in mind:
> >
> > - drm_connector_hdmi_codec is kept as simple as possible. It implements
> >   generic functionality (ELD, hotplug, registration).
> >
> > - drm_hdmi_connector sets up HDMI codec device if the connector
> >   is setup correspondingly (either I2S or S/PDIF is marked as
> >   supported).
> >
> > - drm_bridge_connector provides a way to link HDMI audio codec
> >   funcionality in the drm_bridge with the drm_connector_hdmi_codec
> >   framework.
> >
> > - It might be worth reverting the no_i2s_capture / no_spdif_capture
> >   bits. Only TDA889x driver sets them, while it's safe to assume that
> >   most of HDMI / DP devices do not support ARC / capture. I think the
> >   drivers should opt-in capture support rather than having to opt-out of
> >   it.
>
> Sorry if this isn't clear to me and I'm quite late to the party, but did
> you test this on vc4 with both a pi3 and pi4, or was it just compile
> tested?

LT9611 is actually tested, VC4 is only compile-tested. Should I put an RFT tag?


-- 
With best wishes
Dmitry


From anshuman.khandual at arm.com  Tue Dec 17 21:25:43 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 18 Dec 2024 10:55:43 +0530
Subject: [PATCH V3 6/7] arm64/boot: Enable EL2 requirements for
 FEAT_Debugv8p9
In-Reply-To: <CAL_Jsq+EO_s49sSK3JQQEDDpcndf4hSpM_gfoe8tZ8=4y3f-tg@mail.gmail.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
 <20241216040831.2448257-7-anshuman.khandual@arm.com>
 <20241216234251.GA629562-robh@kernel.org>
 <c64709f7-e1c6-482e-8665-912be50b15bd@arm.com>
 <CAL_Jsq+EO_s49sSK3JQQEDDpcndf4hSpM_gfoe8tZ8=4y3f-tg@mail.gmail.com>
Message-ID: <96bae61a-c9a0-4b9a-af4f-b6fc6202bccd@arm.com>

[....]

On 12/17/24 23:23, Rob Herring wrote:
>> Something like the commit
>>
>> commit 31c00d2aeaa2da89361f5b64a64ca831433be5fc
>> Author: Mark Brown <broonie at kernel.org>
>> Date:   Thu Apr 1 19:09:40 2021 +0100
>>
>>     arm64: Disable fine grained traps on boot
>>
>>     The arm64 FEAT_FGT extension introduces a set of traps to EL2 for accesses
>>     to small sets of registers and instructions from EL1 and EL0.  Currently
>>     Linux makes no use of this feature, ensure that it is not active at boot by
>>     disabling the traps during EL2 setup.
>>
>>
>>>
>>> I just realized I forgot to add FGT2 setup for the PMUv3.9 features I
>>> already added in 6.12 and 6.13. So this really needs to land sooner
>>> rather than later to add that.
>> Not sure if I got this correctly. Are you suggesting to carve out __init_el2_fgt2()
>> from the series and post separately with PMUv3.9 requirements and fallback clearing
>> for all FEAT_FGT2 trap config registers as mentioned above ?
> Yes, as it needs to not be held up by any of the debug issues Mark
> raised. Also, it may need to be back ported to 6.12. And for that we'd
> want the PMU parts, but not the Debug. I still have to figure out what
> needs to be done on the KVM side.

Hi Rob,

I did go through all the five FEAT_FGT2 trap control registers and it
seems like the following are the controls available for FEAT_PMUv3p9
based registers. Although PMZR_EL0 does not get used in kernel right
now but still might be a good idea to include anyway. Please let me
know, if I might have missed something else related to FEAT_PMUv3p9.

HDFGRTR2_EL2_nPMUACR_EL1	(mrs PMUACR_EL1)
HDFGWTR2_EL2_nPMUACR_EL1	(msr PMUACR_EL1)
HDFGWTR2_EL2_nPMZR_EL0		(msr PMZR_EL0)

Following will be the change required for __init_el2_fgt2() along with
all the tools sysreg updates required for the mentioned registers here.

--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -233,6 +233,31 @@
 .Lskip_fgt_\@:
 .endm
 
+.macro __init_el2_fgt2
+       mrs     x1, id_aa64mmfr0_el1
+       ubfx    x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
+       cmp     x1, #ID_AA64MMFR0_EL1_FGT_FGT2
+       b.lt    .Lskip_fgt2_\@
+
+       mov     x0, xzr
+       mov     x2, xzr
+       mrs     x1, id_aa64dfr0_el1
+       ubfx    x1, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
+       cmp     x1, #ID_AA64DFR0_EL1_PMUVer_V3P9
+       b.lt    .Lskip_pmuv3p9_\@
+
+       orr     x0, x0, #HDFGRTR2_EL2_nPMUACR_EL1
+       orr     x2, x2, #HDFGWTR2_EL2_nPMUACR_EL1
+       orr     x2, x2, #HDFGWTR2_EL2_nPMZR_EL0
+.Lskip_pmuv3p9_\@:
+       msr_s   SYS_HDFGRTR2_EL2, x0
+       msr_s   SYS_HDFGWTR2_EL2, x2
+       msr_s   SYS_HFGRTR2_EL2, xzr
+       msr_s   SYS_HFGWTR2_EL2, xzr
+       msr_s   SYS_HFGITR2_EL2, xzr
+.Lskip_fgt2_\@:
+.endm
+
 .macro __init_el2_gcs
        mrs_s   x1, SYS_ID_AA64PFR1_EL1
        ubfx    x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
@@ -283,6 +308,7 @@
        __init_el2_nvhe_idregs
        __init_el2_cptr
        __init_el2_fgt
+       __init_el2_fgt2
         __init_el2_gcs
 .endm


From victor.liu at nxp.com  Tue Dec 17 22:02:18 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Wed, 18 Dec 2024 14:02:18 +0800
Subject: [PATCH v7 0/7] Add ITE IT6263 LVDS to HDMI converter support
In-Reply-To: <20241217-uppish-sapphire-dinosaur-4c40a2@houat>
References: <20241114065759.3341908-1-victor.liu@nxp.com>
 <20241217-uppish-sapphire-dinosaur-4c40a2@houat>
Message-ID: <aba80c42-1b48-426f-b29d-88bf18473602@nxp.com>

On 12/17/2024, Maxime Ripard wrote:
> Hi,

Hi,

> 
> Thanks for the description, I have several questions here.

Thanks for the feedback!

> 
> On Thu, Nov 14, 2024 at 02:57:52PM +0800, Liu Ying wrote:
>> This patch series aims to add ITE IT6263 LVDS to HDMI converter on
>> i.MX8MP EVK.
>>
>> Since IT6263 DT binding and driver were picked up from v5 and landed
>> in drm-misc, this patch series contains patches almost all i.MX8MP
>> SoC/platform specific.
>>
>> Patch 1 is a preparation patch to allow display mode of an existing
>> panel to pass the added mode validation logic in patch 3.
>>
>> Patch 2 is a preparation patch to drop CLK_SET_RATE_PARENT flag for
>> media_disp{1,2}_pix clocks.  Patch 5 depends on patch 2.
>>
>> Patch 3 allows i.MX8MP LVDS Display Bridge(LDB) bridge driver to find
>> the next non-panel bridge, that is the IT6263 in this case.
>>
>> Patch 4 adds mode validation logic to i.MX8MP LDB bridge driver against
>> "ldb" clock so that it can filter out unsupported display modes read
>> from EDID.
>>
>> Patch 5 adds mode validation logic to i.MX8MP LDB bridge driver against
>> "pix" clock so that it can filter out display modes which are not
>> supported by pixel clock tree.
>>
>> Patch 6 adds DT overlays to support NXP adapter cards[1][2] with IT6263
>> populated.
>>
>> Patch 7 enables the IT6263 bridge driver in defconfig.
>>
>> Note that patch 3 and 4 depend on patch[3] in shawnguo/imx/fixes.
>>
>> Since this patch series is related to another one[4] authored by Marek,
>> Maxime asked for a proper description[5] about the exact problem.
>>
>> Admittedly, it's a bit complicated.  Here, I'm trying to do so and explain
>> a bit more.
>>
>> [ Description ]
>> It's a clock problem about shared i.MX8MP video PLL between MIPI DSI and
>> LVDS display pipelines.  The pipelines are driven by separate DRM driver
>> instances, hence there is no way to negotiate a dynamically changeable
>> PLL rate to satisfy both of them.  The only solution is to assign a
>> sensible/unchangeable clock rate for the PLL in DT.
>>
>> Admittedly, sys_pll3_out can be another clock source to derive pixel clock
>> for i.MX8MP MIPI DSI display pipeline if a particalur i.MX8MP platform
>> doesn't use audio(sys_pll3_out is supposed to derive audio AXI clock running
>> at nominal 600MHz).  However, for i.MX8MP platforms with audio features,
>> the shared video PLL case has to be handled and it determines that the above
>> solution(unchangeable PLL rate assigned in DT) has to be used no matter
>> sys_pll3_out is for display or audio, because the separate DRM driver
>> instances really don't know if they are sharing the video PLL or not.
>>
>> [[ i.MX8MP Display Hardware ]]
>> i.MX8MP SoC supports three display pipelines:
>>
>>  -----------------------------           ------------------------
>> | imx8mp_media_disp_pix_sels  |         | imx8mp_media_ldb_sels  |
>>  -----------------------------           ------------------------
>> |  osc_24m (fixed 24MHz)      |         |  osc_24m (fixed 24MHz) |
>> |*-video_pll1_out (video)     |         |  sys_pll2_333m (sys)   |
>> |  audio_pll2_out (audio)     |         |  sys_pll2_100m (sys)   |
>> |  audio_pll1_out (audio)     |         | -sys_pll1_800m (sys)   |
>> | -sys_pll1_800m (sys)        |         | -sys_pll2_1000m (sys)  |
>> | -sys_pll2_1000m (sys)       |         |  clk_ext2 (external)   |
>> |  sys_pll3_out (audio ?)     |         |  audio_pll2_out (audio)|
>> |  clk_ext4 (external)        |         |*-video_pll1_out (video)|
>>  -----------------------------           ------------------------
>>              ||                                     |
>>  -----------------------------           ------------------------
>> |   media_disp{1,2}_pix       |         |        media_ldb       |
>>  ----------------------------- mux+div   ------------------------ mux+div
>>              ||                                     |
>>  -----------------------------           ------------------------
>> | media_disp{1,2}_pix_root_clk|         |   media_ldb_root_clk   |
>>  ----------------------------- gate      ------------------------ gate
>>              ||                                     | (LVDS serial clock)
>>              ||                                     V
>> 	     || (Disp2 Pclk)  --------      ------------------
>> 	     | ------------> | LCDIF2 | -> |       LDB        | -> panel/bridge
>> 	     |                --------      ------------------
>> 	     |  (Disp1 Pclk)  --------      ------------------
>> 	      -------------> | LCDIF1 | -> | Samsung MIPI DSI | -> panel/bridge
>> 	                      --------      ------------------
>>                               --------      ------------------      ----------
>>                              | LCDIF3 | -> | Synopsys HDMI TX | -> | HDMI PHY |
>>                               --------      ------------------     |     +    |
>>                                  ^                                 |    PLL   |
>>                                  |                                  ----------
>>                                  | (Disp3 pclk)                         | |
>>                                   --------------------------------------  |
>>                                                                           V
>>                                                                     panel/bridge
>>
>> * video_pll1_out is supposed to be used by video outputs.
>>
>> - LCDIF2 + LDB can only use the *same* video_pll1_out, sys_pll1_800m or
>>   sys_pll2_1000m.
>>
>> [[ i.MX8MP Display Drivers ]]
>> LCDIF: drivers/gpu/drm/mxsfb/lcdif_*.c
>> Three LCDIFv3 display controllers are driven by three imx-lcdif DRM instances
>> separately.
>>
>> LDB: drivers/gpu/drm/bridge/fsl-ldb.c
>>
>> Samsung MIPI DSI: drivers/gpu/drm/bridge/samsung-dsim.c
>>
>> Synopsys HDMI TX: drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c
>>
>> [[ Problem - Shared Video PLL Between Samsung MIPI DSI and LDB ]]
>> osc_24m, audio_pll*, sys_pll* and clk_ext* are not for video outputs,
>> because:
>> a. Aparently, osc_24m runs at fixed 24MHz which is too low for most displays.
>> b. Audio subsystem may consume all audio_pll*.
>> c. sys_pll* are system clocks which are supposed to run at fixed typical
>>    rates, e.g., sys_pll2_1000m runs at 1000MHz.
>> d. sys_pll3_out is supposed to derive audio AXI clock running at nominal
>>    600MHz(i.MX8MP data sheet specifies the rate), see NXP downstream kernel:
>>    https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/boot/dts/freescale/imx8mp-evk-ndm.dts#L19
>>    https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/boot/dts/freescale/imx8mp-ddr4-evk.dts#L25
> 
> Is there any downside to using any of these clocks, aside from the fact
> that their rate must not change?

osc_24m and sys_pll* don't support spread spectrum while audio_pll* and
video_pll1_out support it. Other than that, I don't see any downside to
use any of these clocks, if their clock rates happen to meet the clock
rate requirements of the MIPI DSI and LDB display pipelines.

> 
> Also, if they can't change their rate, why do they have
> CLK_SET_RATE_PARENT (sys_pll* in particular) ?

If media_disp{1,2}_pix and media_ldb clocks have no CLK_SET_RATE_PARENT,
it doesn't mattter whether their parent clocks(these clocks) have it or not.
Note that patch 2 drops CLK_SET_RATE_PARENT for media_disp{1,2}_pix clocks.

Anyway, why have sys_pll* clocks got CLK_SET_RATE_PARENT? The reason I can
think of is that it makes some potential i.MX8MP platforms possible to set
the sys_pll* rates with the parent clock rates(sys_pll1/2/3) updated
accordingly, e.g., if sys_pll2_1000m is the only active child of sys_pll2_out,
sys_pll2_1000m's rate can be assigned to 800MHz(not typical 1000MHz) in DT.
Or, maybe, the sys_pll* rates can be assigned to some particular values to
support nominal/overdrive modes of various i.MX8MP clock roots(some are
derived from the sys_pll* clocks).

> 
>> e. clk_ext* are external clocks without known capabilities.
>>
>> So, the only eligible video_pll1_out is supposed to be shared between LDB
>> and Samsung MIPI DSI in the two separate display pipelines if sys_pll3_out
>> is already used to derive the audio AXI clock.
>>
>> With the shared video_pll1_out, drivers for the two display pipelines cannot
>> change the PLL clock rate in runtime, since the pipelines are driven by two
>> DRM driver instances.
> 
> What is the typicall frequency on those pipelines? Could setting the PLL

For MIPI DSI to HDMI(ADV7535) and LVDS to HDMI(IT6263), the typical pixel
rates are 148.5MHz(1080p60Hz) and 74.25MHz(720p60Hz) and the typical LDB
clock rate is 519.75MHz.

For MIPI DSI panel and LVDS panel, there no typical pixel rates. It depends
on individual panels. However, it's possible to override panel's pixel clock
rate in DT to use a fixed PLL clock rate if the pixel clock rate deviation
is still acceptable by the panel.

> high enough that any frequency required by any of these pipelines can be
> accomodated through a divider work?

Yes, that's why media_blk_ctrl node in imx8mp.dtsi assigns video_pll1 clock
rate to 1.0395GHz. That rate supports the typical 148.5MHz and 74.25MHz
pixel clock rates. With this patch series applied, i.MX8MP EVK would use
this fixed 1.0395GHz video_pll1 clock to drive both MIPI DSI to HDMI and
LVDS to HDMI simultaneously.

> 
> Something like you run the PLL at 594MHz, and then most HDMI frequencies
> can be reached by a 1, 2 or 4 divider.

PLL running at 594MHz does support the typical pixel clock rates for MIPI
DSI to HDMI, but not for LVDS to HDMI due to the 7x(single-LVDS link) or
3.5x(dual-LVDS link) folder between LDB clock rate and pixel clock rate.
PLL running at 1.0395GHz is the one chosen to support both MIPI DSI to
HDMI and LVDS to HDMI, e.g., with dual-LVDS link, 148.5MHz pixel clock rate
= 1.0395GHz / 7 and 519.75MHz LDB clock rate(148.5MHz * 3.5) = 1.0395GHz / 2.

> 
>> [[ Solution ]]
>> Assign the PLL clock source(s) and the PLL clock rate(s) in DT.  Disallow
>> display drivers to change the PLL clock source(s) or rate(s) in runtime
>> including LCDIF driver and bridge drivers.  With sensible PLL clock rate(s),
>> typical display modes like 1920x1080 at 60 can be supported if external HDMI
>> bridges are connected, and panel display modes can be too.  Also the unneeded
>> CLK_SET_RATE_PARENT flag can be dropped for media_disp{1,2}_pix clocks.
>> If needed, bridge drivers just call clk_round_rate() to validate clocks so
>> that unsupported display modes can be filtered out.  Although the
>> unchangeable PLL clock rate disallows more potential display modes, the
>> solution works for single/dual/triple display pipelines(OFC, hardware designers
>> should pick panel/bridge display devices carefully first by considering clock
>> resources).
> 
> I think it's a reasonable idea, if not for the hardcode-it it DT stuff.
> If we can manage to have a fixed setup work ok for all display use
> cases, why would it be in DT? The clock driver seems like a much better
> choice to me.

Different i.MX8MP platforms may have different display devices(panel(s)
and/or bridge(s)). It's flexible to allow each platform to assign the PLL
rate(s) in DT. It doesn't look doable with clock driver, does it?

> 
> Maxime

-- 
Regards,
Liu Ying


From fujita.tomonori at gmail.com  Tue Dec 17 22:20:06 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Wed, 18 Dec 2024 15:20:06 +0900
Subject: [PATCH v2 2/5] riscv/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust
In-Reply-To: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
References: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
Message-ID: <20241218062009.2402650-3-fujita.tomonori@gmail.com>

Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
Rust to avoid the duplication.

No functional changes.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 arch/riscv/include/asm/bug.h | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h
index 1aaea81fb141..ee6b9b787e46 100644
--- a/arch/riscv/include/asm/bug.h
+++ b/arch/riscv/include/asm/bug.h
@@ -31,40 +31,45 @@ typedef u32 bug_insn_t;
 
 #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 #define __BUG_ENTRY_ADDR	RISCV_INT " 1b - ."
-#define __BUG_ENTRY_FILE	RISCV_INT " %0 - ."
+#define __BUG_ENTRY_FILE(file)	RISCV_INT " " file " - ."
 #else
 #define __BUG_ENTRY_ADDR	RISCV_PTR " 1b"
-#define __BUG_ENTRY_FILE	RISCV_PTR " %0"
+#define __BUG_ENTRY_FILE(file)	RISCV_PTR " " file
 #endif
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
-#define __BUG_ENTRY			\
+#define __BUG_ENTRY(file, line, flags)	\
 	__BUG_ENTRY_ADDR "\n\t"		\
-	__BUG_ENTRY_FILE "\n\t"		\
-	RISCV_SHORT " %1\n\t"		\
-	RISCV_SHORT " %2"
+	__BUG_ENTRY_FILE(file) "\n\t"	\
+	RISCV_SHORT " " line "\n\t"	\
+	RISCV_SHORT " " flags
 #else
-#define __BUG_ENTRY			\
-	__BUG_ENTRY_ADDR "\n\t"		\
-	RISCV_SHORT " %2"
+#define __BUG_ENTRY(file, line, flags)		\
+	__BUG_ENTRY_ADDR "\n\t"			\
+	RISCV_SHORT " " flags
 #endif
 
 #ifdef CONFIG_GENERIC_BUG
-#define __BUG_FLAGS(flags)					\
-do {								\
-	__asm__ __volatile__ (					\
+
+#define ARCH_WARN_ASM(file, line, flags, size)			\
 		"1:\n\t"					\
 			"ebreak\n"				\
 			".pushsection __bug_table,\"aw\"\n\t"	\
 		"2:\n\t"					\
-			__BUG_ENTRY "\n\t"			\
-			".org 2b + %3\n\t"                      \
-			".popsection"				\
+		__BUG_ENTRY(file, line, flags) "\n\t"		\
+			".org 2b + " size "\n\t"                \
+			".popsection\n"				\
+
+#define __BUG_FLAGS(flags)					\
+do {								\
+	__asm__ __volatile__ (					\
+		ARCH_WARN_ASM("%0", "%1", "%2", "%3")		\
 		:						\
 		: "i" (__FILE__), "i" (__LINE__),		\
 		  "i" (flags),					\
 		  "i" (sizeof(struct bug_entry)));              \
 } while (0)
+
 #else /* CONFIG_GENERIC_BUG */
 #define __BUG_FLAGS(flags) do {					\
 	__asm__ __volatile__ ("ebreak\n");			\
-- 
2.43.0



From fujita.tomonori at gmail.com  Tue Dec 17 22:20:07 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Wed, 18 Dec 2024 15:20:07 +0900
Subject: [PATCH v2 3/5] arm64/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust
In-Reply-To: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
References: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
Message-ID: <20241218062009.2402650-4-fujita.tomonori@gmail.com>

Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
Rust to avoid the duplication.

No functional changes.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 arch/arm64/include/asm/asm-bug.h | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/asm-bug.h b/arch/arm64/include/asm/asm-bug.h
index 6e73809f6492..822e9d51d3e9 100644
--- a/arch/arm64/include/asm/asm-bug.h
+++ b/arch/arm64/include/asm/asm-bug.h
@@ -21,16 +21,21 @@
 #endif
 
 #ifdef CONFIG_GENERIC_BUG
-
-#define __BUG_ENTRY(flags) 				\
+#define __BUG_ENTRY_START				\
 		.pushsection __bug_table,"aw";		\
 		.align 2;				\
 	14470:	.long 14471f - .;			\
-_BUGVERBOSE_LOCATION(__FILE__, __LINE__)		\
-		.short flags; 				\
+
+#define __BUG_ENTRY_END					\
 		.align 2;				\
 		.popsection;				\
 	14471:
+
+#define __BUG_ENTRY(flags)				\
+		__BUG_ENTRY_START			\
+_BUGVERBOSE_LOCATION(__FILE__, __LINE__)		\
+		.short flags;				\
+		__BUG_ENTRY_END
 #else
 #define __BUG_ENTRY(flags)
 #endif
@@ -41,4 +46,22 @@ _BUGVERBOSE_LOCATION(__FILE__, __LINE__)		\
 
 #define ASM_BUG()	ASM_BUG_FLAGS(0)
 
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#define __BUG_LOCATION_STRING(file, line)		\
+		".long " file "- .;"			\
+		".short " line ";"
+#else
+#define __BUG_LOCATION_STRING(file, line)
+#endif
+
+#define __BUG_ENTRY_STRING(file, line, flags)		\
+		__stringify(__BUG_ENTRY_START)		\
+		__BUG_LOCATION_STRING(file, line)	\
+		".short " flags ";"			\
+		__stringify(__BUG_ENTRY_END)
+
+#define ARCH_WARN_ASM(file, line, flags, size)		\
+	__BUG_ENTRY_STRING(file, line, flags)		\
+	__stringify(brk BUG_BRK_IMM)
+
 #endif /* __ASM_ASM_BUG_H */
-- 
2.43.0



From fujita.tomonori at gmail.com  Tue Dec 17 22:20:08 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Wed, 18 Dec 2024 15:20:08 +0900
Subject: [PATCH v2 4/5] loongarch/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust
In-Reply-To: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
References: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
Message-ID: <20241218062009.2402650-5-fujita.tomonori@gmail.com>

Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
Rust to avoid the duplication.

No functional changes.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 arch/loongarch/include/asm/bug.h | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/arch/loongarch/include/asm/bug.h b/arch/loongarch/include/asm/bug.h
index 08388876ade4..5cac2d3efd75 100644
--- a/arch/loongarch/include/asm/bug.h
+++ b/arch/loongarch/include/asm/bug.h
@@ -21,14 +21,21 @@
 #ifndef CONFIG_GENERIC_BUG
 #define __BUG_ENTRY(flags)
 #else
-#define __BUG_ENTRY(flags) 					\
+
+#define __BUG_ENTRY_START					\
 		.pushsection __bug_table, "aw";			\
 		.align 2;					\
 	10000:	.long 10001f - .;				\
-		_BUGVERBOSE_LOCATION(__FILE__, __LINE__)	\
-		.short flags; 					\
+
+#define __BUG_ENTRY_END						\
 		.popsection;					\
 	10001:
+
+#define __BUG_ENTRY(flags)					\
+		__BUG_ENTRY_START			\
+		_BUGVERBOSE_LOCATION(__FILE__, __LINE__)	\
+		.short flags;					\
+		__BUG_ENTRY_END
 #endif
 
 #define ASM_BUG_FLAGS(flags)					\
@@ -55,6 +62,24 @@ do {								\
 	unreachable();						\
 } while (0)
 
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#define __BUG_LOCATION_STRING(file, line)			\
+		".long " file "- .;"				\
+		".short " line ";"
+#else
+#define __BUG_LOCATION_STRING(file, line)
+#endif
+
+#define __BUG_ENTRY_STRING(file, line, flags)			\
+		__stringify(__BUG_ENTRY_START)			\
+		__BUG_LOCATION_STRING(file, line)		\
+		".short " flags ";"				\
+		__stringify(__BUG_ENTRY_END)
+
+#define ARCH_WARN_ASM(file, line, flags, size)			\
+	__BUG_ENTRY_STRING(file, line, flags)			\
+	__stringify(break BRK_BUG) ";"
+
 #define HAVE_ARCH_BUG
 
 #include <asm-generic/bug.h>
-- 
2.43.0



From fujita.tomonori at gmail.com  Tue Dec 17 22:20:04 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Wed, 18 Dec 2024 15:20:04 +0900
Subject: [PATCH v2 0/5] rust: Add bug/warn abstractions
Message-ID: <20241218062009.2402650-1-fujita.tomonori@gmail.com>

This patchset adds warn_on and warn_on_once macros with the bug/warn
abstraction.

Wrapping C's BUG/WARN macros does not work the same way on
architectures that support Rust (x86, RISC-V, ARM64, LoongArch). Rust
code needs to directly execute the same assembly code used on the C
side. To avoid duplicating the assembly code, this approach mirrors
what the static branch code does: it dynamically generates the
assembly code for Rust using the C preprocessor.

The 1st to 4th patches export the BUG/WARN assembly code for Rust on
each architecture, with no functional changes on the C side. The
changes for x86 and RISC-V are straightforward. However, the ARM64 and
LoongArch assembly code are designed differently; they are used by
both C inline assembly and assembly code. As a result, sharing this
code with Rust is complicated.

The last patch adds the bug abstraction with warn_on and warn_on_once
implementations.

This has been tested on x86, ARM64, and RISC-V (QEMU), with only a
compile test performed for LoongArch.

The assembly code can be used for both BUG and WARN, but currently
only supports warn_on and warn_on_once. I will work on the remaining
functionality after this abstraction is merged.

v2:
- remove target_arch cfg by using asm comment
- clean up the changes to loongarch asm
v1: https://lore.kernel.org/linux-arm-kernel/20241210001802.228725-1-fujita.tomonori at gmail.com/


FUJITA Tomonori (5):
  x86/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with
    Rust
  riscv/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with
    Rust
  arm64/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with
    Rust
  loongarch/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing
    with Rust
  rust: Add warn_on and warn_on_once

 arch/arm64/include/asm/asm-bug.h              |  31 +++++-
 arch/loongarch/include/asm/bug.h              |  31 +++++-
 arch/riscv/include/asm/bug.h                  |  35 +++---
 arch/x86/include/asm/bug.h                    |  51 +++++----
 rust/Makefile                                 |   8 ++
 rust/kernel/.gitignore                        |   2 +
 rust/kernel/bug.rs                            | 100 ++++++++++++++++++
 rust/kernel/generated_arch_reachable_asm.rs.S |   7 ++
 rust/kernel/generated_arch_warn_asm.rs.S      |   7 ++
 rust/kernel/lib.rs                            |   1 +
 10 files changed, 224 insertions(+), 49 deletions(-)
 create mode 100644 rust/kernel/bug.rs
 create mode 100644 rust/kernel/generated_arch_reachable_asm.rs.S
 create mode 100644 rust/kernel/generated_arch_warn_asm.rs.S


base-commit: 517743c4e303252cd8c1a1fb1bed28e7d94d4678
-- 
2.43.0



From fujita.tomonori at gmail.com  Tue Dec 17 22:20:05 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Wed, 18 Dec 2024 15:20:05 +0900
Subject: [PATCH v2 1/5] x86/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm code sharing with Rust
In-Reply-To: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
References: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
Message-ID: <20241218062009.2402650-2-fujita.tomonori@gmail.com>

Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
Rust to avoid the duplication.

No functional changes.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 arch/x86/include/asm/bug.h | 51 ++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 27 deletions(-)

diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index 806649c7f23d..71df68e2a731 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -28,45 +28,42 @@
 #ifdef CONFIG_GENERIC_BUG
 
 #ifdef CONFIG_X86_32
-# define __BUG_REL(val)	".long " __stringify(val)
+# define __BUG_REL(val)	".long " val
 #else
-# define __BUG_REL(val)	".long " __stringify(val) " - ."
+# define __BUG_REL(val)	".long " val " - ."
 #endif
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+#define __BUG_ENTRY(file, line, flags)					\
+	"2:\t" __BUG_REL("1b") "\t# bug_entry::bug_addr\n"		\
+	"\t" __BUG_REL(file)   "\t# bug_entry::file\n"			\
+	"\t.word " line        "\t# bug_entry::line\n"			\
+	"\t.word " flags       "\t# bug_entry::flags\n"
+#else
+#define __BUG_ENTRY(file, ine, flags)					\
+	"2:\t" __BUG_REL("1b") "\t# bug_entry::bug_addr\n"		\
+	"\t.word " flags       "\t# bug_entry::flags\n"
+#endif
+
+#define _BUG_FLAGS_ASM(ins, file, line, flags, size, extra)		\
+	"1:\t" ins "\n"							\
+	".pushsection __bug_table,\"aw\"\n"				\
+	__BUG_ENTRY(file, line, flags)					\
+	"\t.org 2b + " size "\n"					\
+	".popsection\n"							\
+	extra
 
 #define _BUG_FLAGS(ins, flags, extra)					\
 do {									\
-	asm_inline volatile("1:\t" ins "\n"				\
-		     ".pushsection __bug_table,\"aw\"\n"		\
-		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
-		     "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"	\
-		     "\t.word %c1"        "\t# bug_entry::line\n"	\
-		     "\t.word %c2"        "\t# bug_entry::flags\n"	\
-		     "\t.org 2b+%c3\n"					\
-		     ".popsection\n"					\
-		     extra						\
+	asm_inline volatile(_BUG_FLAGS_ASM(ins, "%c0",			\
+					   "%c1", "%c2", "%c3", extra)	\
 		     : : "i" (__FILE__), "i" (__LINE__),		\
 			 "i" (flags),					\
 			 "i" (sizeof(struct bug_entry)));		\
 } while (0)
 
-#else /* !CONFIG_DEBUG_BUGVERBOSE */
-
-#define _BUG_FLAGS(ins, flags, extra)					\
-do {									\
-	asm_inline volatile("1:\t" ins "\n"				\
-		     ".pushsection __bug_table,\"aw\"\n"		\
-		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
-		     "\t.word %c0"        "\t# bug_entry::flags\n"	\
-		     "\t.org 2b+%c1\n"					\
-		     ".popsection\n"					\
-		     extra						\
-		     : : "i" (flags),					\
-			 "i" (sizeof(struct bug_entry)));		\
-} while (0)
-
-#endif /* CONFIG_DEBUG_BUGVERBOSE */
+#define ARCH_WARN_ASM(file, line, flags, size)				\
+	_BUG_FLAGS_ASM(ASM_UD2, file, line, flags, size, "")
 
 #else
 
-- 
2.43.0



From fujita.tomonori at gmail.com  Tue Dec 17 22:20:09 2024
From: fujita.tomonori at gmail.com (FUJITA Tomonori)
Date: Wed, 18 Dec 2024 15:20:09 +0900
Subject: [PATCH v2 5/5] rust: Add warn_on and warn_on_once
In-Reply-To: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
References: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
Message-ID: <20241218062009.2402650-6-fujita.tomonori@gmail.com>

Add warn_on and warn_on_once macros. Wrapping the C's WARN_* and BUG_*
macros doesn't work so this uses the assembly code exported by the C
side via ARCH_WARN_ASM macro. Like the static branch code, this
generates the assembly code for rust dynamically by using the C
preprocessor.

file()! macro doesn't work for the Rust inline assembly in the same
way as __FILE__ for the C inline assembly. So the code to handle a
file name is different from the C assembly code (similar to the
arm64/loongarch assembly).

ASM_REACHABLE definition works in the same way to get objtool's
reachable asm code. The architectures which use objtool (x86 and
loongarch) needs it.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
---
 rust/Makefile                                 |   8 ++
 rust/kernel/.gitignore                        |   2 +
 rust/kernel/bug.rs                            | 100 ++++++++++++++++++
 rust/kernel/generated_arch_reachable_asm.rs.S |   7 ++
 rust/kernel/generated_arch_warn_asm.rs.S      |   7 ++
 rust/kernel/lib.rs                            |   1 +
 6 files changed, 125 insertions(+)
 create mode 100644 rust/kernel/bug.rs
 create mode 100644 rust/kernel/generated_arch_reachable_asm.rs.S
 create mode 100644 rust/kernel/generated_arch_warn_asm.rs.S

diff --git a/rust/Makefile b/rust/Makefile
index a40a3936126d..633b2c28605c 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -37,6 +37,9 @@ obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.o
 obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.o
 
 always-$(subst y,$(CONFIG_RUST),$(CONFIG_JUMP_LABEL)) += kernel/generated_arch_static_branch_asm.rs
+ifndef CONFIG_UML
+always-$(subst y,$(CONFIG_RUST),$(CONFIG_BUG)) += kernel/generated_arch_warn_asm.rs kernel/generated_arch_reachable_asm.rs
+endif
 
 # Avoids running `$(RUSTC)` for the sysroot when it may not be available.
 ifdef CONFIG_RUST
@@ -449,5 +452,10 @@ $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \
 ifdef CONFIG_JUMP_LABEL
 $(obj)/kernel.o: $(obj)/kernel/generated_arch_static_branch_asm.rs
 endif
+ifndef CONFIG_UML
+ifdef CONFIG_BUG
+$(obj)/kernel.o: $(obj)/kernel/generated_arch_warn_asm.rs $(obj)/kernel/generated_arch_reachable_asm.rs
+endif
+endif
 
 endif # CONFIG_RUST
diff --git a/rust/kernel/.gitignore b/rust/kernel/.gitignore
index 6ba39a178f30..f1d7f4225332 100644
--- a/rust/kernel/.gitignore
+++ b/rust/kernel/.gitignore
@@ -1,3 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
 /generated_arch_static_branch_asm.rs
+/generated_arch_warn_asm.rs
+/generated_arch_reachable_asm.rs
\ No newline at end of file
diff --git a/rust/kernel/bug.rs b/rust/kernel/bug.rs
new file mode 100644
index 000000000000..7ffd9cb1ad75
--- /dev/null
+++ b/rust/kernel/bug.rs
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+
+// Copyright (C) 2024 FUJITA Tomonori
+
+//! Support for BUG_* and WARN_* functionality.
+//!
+//! C header: [`include/asm-generic/bug.h`](srctree/include/asm-generic/bug.h)
+
+#[macro_export]
+#[doc(hidden)]
+#[cfg(all(CONFIG_BUG, not(CONFIG_UML)))]
+macro_rules! warn_flags {
+    ($flags:expr) => {
+        const FLAGS: u32 = $crate::bindings::BUGFLAG_WARNING | $flags;
+        // SAFETY: Just an FFI call.
+        #[cfg(CONFIG_DEBUG_BUGVERBOSE)]
+        unsafe {
+            $crate::asm!(concat!(
+                "/* {size} */",
+                ".pushsection .rodata.str1.1, \"aMS\", at progbits, 1\n",
+                "111:\t .string ", "\"", file!(), "\"\n",
+                ".popsection\n",
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
+            line = const line!(),
+            flags = const FLAGS,
+            size = const ::core::mem::size_of::<$crate::bindings::bug_entry>(),
+            );
+        }
+        // SAFETY: Just an FFI call.
+        #[cfg(not(CONFIG_DEBUG_BUGVERBOSE))]
+        unsafe {
+            $crate::asm!(
+            concat!(
+                "/* {size} */",
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
+                include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
+            flags = const FLAGS,
+            size = const ::core::mem::size_of::<$crate::bindings::bug_entry>(),
+            );
+        }
+    }
+}
+
+#[macro_export]
+#[doc(hidden)]
+#[cfg(all(CONFIG_BUG, CONFIG_UML))]
+macro_rules! warn_flags {
+    ($flags:expr) => {
+        // SAFETY: Just an FFI call.
+        unsafe {
+            $crate::bindings::warn_slowpath_fmt(
+                $crate::c_str!(::core::file!()).as_ptr() as *const ::core::ffi::c_char,
+                line!() as i32,
+                $flags as u32,
+                ::core::ptr::null() as *const ::core::ffi::c_char,
+            );
+        }
+    };
+}
+
+#[macro_export]
+#[doc(hidden)]
+#[cfg(not(CONFIG_BUG))]
+macro_rules! warn_flags {
+    ($flags:expr) => {};
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! bugflag_taint {
+    ($taint:expr) => {
+        $taint << 8
+    };
+}
+
+/// Report a warning only once.
+#[macro_export]
+macro_rules! warn_on_once {
+    ($cond:expr) => {
+        if $cond {
+            $crate::warn_flags!(
+                $crate::bindings::BUGFLAG_ONCE
+                    | $crate::bugflag_taint!($crate::bindings::TAINT_WARN)
+            );
+        }
+        $cond
+    };
+}
+
+/// Report a warning.
+#[macro_export]
+macro_rules! warn_on {
+    ($cond:expr) => {
+        if $cond {
+            $crate::warn_flags!($crate::bugflag_taint!($crate::bindings::TAINT_WARN));
+        }
+        $cond
+    };
+}
diff --git a/rust/kernel/generated_arch_reachable_asm.rs.S b/rust/kernel/generated_arch_reachable_asm.rs.S
new file mode 100644
index 000000000000..4e65525e4464
--- /dev/null
+++ b/rust/kernel/generated_arch_reachable_asm.rs.S
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/objtool.h>
+
+// Cut here.
+
+::kernel::concat_literals!(ASM_REACHABLE)
diff --git a/rust/kernel/generated_arch_warn_asm.rs.S b/rust/kernel/generated_arch_warn_asm.rs.S
new file mode 100644
index 000000000000..8f239b431aa4
--- /dev/null
+++ b/rust/kernel/generated_arch_warn_asm.rs.S
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/bug.h>
+
+// Cut here.
+
+::kernel::concat_literals!(ARCH_WARN_ASM("111b", "{line}",  "{flags}", "{size}"))
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index e1065a7551a3..913f3a5b2a98 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -32,6 +32,7 @@
 pub mod alloc;
 #[cfg(CONFIG_BLOCK)]
 pub mod block;
+pub mod bug;
 mod build_assert;
 pub mod cred;
 pub mod device;
-- 
2.43.0



From wei.fang at nxp.com  Tue Dec 17 22:17:25 2024
From: wei.fang at nxp.com (Wei Fang)
Date: Wed, 18 Dec 2024 14:17:25 +0800
Subject: [PATCH 2/2] arm64: dts: imx95: add ENETC 0 support
In-Reply-To: <20241218061725.1608466-1-wei.fang@nxp.com>
References: <20241218061725.1608466-1-wei.fang@nxp.com>
Message-ID: <20241218061725.1608466-3-wei.fang@nxp.com>

Add ENETC 0 (1G ethernet port) support for i.MX95-19x19-EVK board. In
addition, because all ENETC instances share MDIO bus, so enable EMDIO
at the same time.

Signed-off-by: Wei Fang <wei.fang at nxp.com>
---
 .../boot/dts/freescale/imx95-19x19-evk.dts    | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
index 6086cb7fa5a0..e838234c8317 100644
--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -38,6 +38,7 @@ aliases {
 		mmc0 = &usdhc1;
 		mmc1 = &usdhc2;
 		serial0 = &lpuart1;
+		ethernet0 = &enetc_port0;
 	};
 
 	bt_sco_codec: audio-codec-bt-sco {
@@ -428,6 +429,33 @@ &wdog3 {
 	status = "okay";
 };
 
+&netcmix_blk_ctrl {
+	status = "okay";
+};
+
+&netc_blk_ctrl {
+	status = "okay";
+};
+
+&enetc_port0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enetc0>;
+	phy-handle = <&ethphy0>;
+	phy-mode = "rgmii-id";
+	status = "okay";
+};
+
+&netc_emdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_emdio>;
+	status = "okay";
+
+	ethphy0: ethernet-phy at 1 {
+		reg = <1>;
+		realtek,clkout-disable;
+	};
+};
+
 &scmi_iomuxc {
 	pinctrl_flexspi1: flexspi1grp {
 		fsl,pins = <
@@ -665,6 +693,30 @@ IMX95_PAD_SD2_DATA3__USDHC2_DATA3		0x13fe
 			IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT		0x51e
 		>;
 	};
+
+	pinctrl_enetc0: enetc0grp {
+		fsl,pins = <
+			IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3		0x57e
+			IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2		0x57e
+			IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1		0x57e
+			IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0		0x57e
+			IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL	0x57e
+			IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK	0x58e
+			IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL	0x57e
+			IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK	0x58e
+			IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0		0x57e
+			IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1		0x57e
+			IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2		0x57e
+			IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3		0x57e
+		>;
+	};
+
+	pinctrl_emdio: emdiogrp{
+		fsl,pins = <
+			IMX95_PAD_ENET1_MDC__NETCMIX_TOP_NETC_MDC		0x57e
+			IMX95_PAD_ENET1_MDIO__NETCMIX_TOP_NETC_MDIO		0x97e
+		>;
+	};
 };
 
 &thermal_zones {
-- 
2.34.1



From wei.fang at nxp.com  Tue Dec 17 22:17:23 2024
From: wei.fang at nxp.com (Wei Fang)
Date: Wed, 18 Dec 2024 14:17:23 +0800
Subject: [PATCH 0/2] Add NETC support for i.MX95
Message-ID: <20241218061725.1608466-1-wei.fang@nxp.com>

We have added support for i.MX95 NETC related drivers, so it's time to
add NETC related nodes in DTS and enable the use of ENETC 0.

Wei Fang (2):
  arm64: dts: imx95: add NETC related nodes
  arm64: dts: imx95: add ENETC 0 support

 .../boot/dts/freescale/imx95-19x19-evk.dts    | 52 +++++++++++
 arch/arm64/boot/dts/freescale/imx95.dtsi      | 93 +++++++++++++++++++
 2 files changed, 145 insertions(+)

-- 
2.34.1



From wei.fang at nxp.com  Tue Dec 17 22:17:24 2024
From: wei.fang at nxp.com (Wei Fang)
Date: Wed, 18 Dec 2024 14:17:24 +0800
Subject: [PATCH 1/2] arm64: dts: imx95: add NETC related nodes
In-Reply-To: <20241218061725.1608466-1-wei.fang@nxp.com>
References: <20241218061725.1608466-1-wei.fang@nxp.com>
Message-ID: <20241218061725.1608466-2-wei.fang@nxp.com>

Add NETC related nodes for i.MX95.

Signed-off-by: Wei Fang <wei.fang at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx95.dtsi | 93 ++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index e9c7a8265d71..86f9fed9998c 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -1702,5 +1702,98 @@ ddr-pmu at 4e090dc0 {
 			reg = <0x0 0x4e090dc0 0x0 0x200>;
 			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 		};
+
+		netc_blk_ctrl: system-controller at 4cde0000 {
+			compatible = "nxp,imx95-netc-blk-ctrl";
+			reg = <0x0 0x4cde0000 0x0 0x10000>,
+			      <0x0 0x4cdf0000 0x0 0x10000>,
+			      <0x0 0x4c81000c 0x0 0x18>;
+			reg-names = "ierb", "prb", "netcmix";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			power-domains = <&scmi_devpd IMX95_PD_NETC>;
+			assigned-clocks = <&scmi_clk IMX95_CLK_ENET>,
+					  <&scmi_clk IMX95_CLK_ENETREF>;
+			assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD2>,
+						 <&scmi_clk IMX95_CLK_SYSPLL1_PFD0>;
+			assigned-clock-rates = <666666666>, <250000000>;
+			clocks = <&scmi_clk IMX95_CLK_ENET>;
+			clock-names = "ipg";
+			status = "disabled";
+
+			netc_bus0: pcie at 4ca00000 {
+				compatible = "pci-host-ecam-generic";
+				reg = <0x0 0x4ca00000 0x0 0x100000>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
+				bus-range = <0x0 0x0>;
+				msi-map = <0x0 &its 0x60 0x1>,	//ENETC0 PF
+					  <0x10 &its 0x61 0x1>, //ENETC0 VF0
+					  <0x20 &its 0x62 0x1>, //ENETC0 VF1
+					  <0x40 &its 0x63 0x1>, //ENETC1 PF
+					  <0x80 &its 0x64 0x1>, //ENETC2 PF
+					  <0x90 &its 0x65 0x1>, //ENETC2 VF0
+					  <0xa0 &its 0x66 0x1>, //ENETC2 VF1
+					  <0xc0 &its 0x67 0x1>; //NETC Timer
+					 /* ENETC0~2 and Timer BAR0 - non-prefetchable memory */
+				ranges = <0x82000000 0x0 0x4cc00000  0x0 0x4cc00000  0x0 0xe0000
+					 /* Timer BAR2 - prefetchable memory */
+					 0xc2000000 0x0 0x4cd00000  0x0 0x4cd00000  0x0 0x10000
+					 /* ENETC0~2: VF0-1 BAR0 - non-prefetchable memory */
+					 0x82000000 0x0 0x4cd20000  0x0 0x4cd20000  0x0 0x60000
+					 /* ENETC0~2: VF0-1 BAR2 - prefetchable memory */
+					 0xc2000000 0x0 0x4cd80000  0x0 0x4cd80000  0x0 0x60000>;
+
+				enetc_port0: ethernet at 0,0 {
+					compatible = "pci1131,e101";
+					reg = <0x000000 0 0 0 0>;
+					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
+					clock-names = "ref";
+					status = "disabled";
+				};
+
+				enetc_port1: ethernet at 8,0 {
+					compatible = "pci1131,e101";
+					reg = <0x004000 0 0 0 0>;
+					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
+					clock-names = "ref";
+					status = "disabled";
+				};
+
+				enetc_port2: ethernet at 10,0 {
+					compatible = "pci1131,e101";
+					reg = <0x008000 0 0 0 0>;
+					status = "disabled";
+				};
+
+				netc_timer: ethernet at 18,0 {
+					reg = <0x00c000 0 0 0 0>;
+					status = "disabled";
+				};
+			};
+
+			netc_bus1: pcie at 4cb00000 {
+				compatible = "pci-host-ecam-generic";
+				reg = <0x0 0x4cb00000 0x0 0x100000>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
+				bus-range = <0x1 0x1>;
+					 /* EMDIO BAR0 - non-prefetchable memory */
+				ranges = <0x82000000 0x0 0x4cce0000  0x0 0x4cce0000  0x0 0x20000
+					 /* EMDIO BAR2 - prefetchable memory */
+					 0xc2000000 0x0 0x4cd10000  0x0 0x4cd10000  0x0 0x10000>;
+
+				netc_emdio: mdio at 0,0 {
+					compatible = "pci1131,ee00";
+					reg = <0x010000 0 0 0 0>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+					status = "disabled";
+				};
+			};
+		};
 	};
 };
-- 
2.34.1



From anarsoul at gmail.com  Tue Dec 17 22:35:53 2024
From: anarsoul at gmail.com (Vasily Khoruzhick)
Date: Tue, 17 Dec 2024 22:35:53 -0800
Subject: [PATCH 1/3] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
In-Reply-To: <20241217211505.7f9c9e4e@minigeek.lan>
References: <20241215053639.738890-1-anarsoul@gmail.com> <20241215053639.738890-2-anarsoul@gmail.com>
 <qbtp4jvkx3r5azufe4k3vtapqpfs54dyjiu4cy5v5wkkzumrzx@vy3xzkfplbue>
 <CA+E=qVeQ8uHBCeFtw6_2cY3252-YXc6eWrf5_YdeVgbp5LJo5g@mail.gmail.com> <20241217211505.7f9c9e4e@minigeek.lan>
Message-ID: <CA+E=qVcU9V+8LZ0Xnh+oDROVf8H99t_kiku7iSdXTHP43d9E_A@mail.gmail.com>

On Tue, Dec 17, 2024 at 1:15?PM Andre Przywara <andre.przywara at arm.com> wrote:
>
> On Tue, 17 Dec 2024 10:00:45 -0800
> Vasily Khoruzhick <anarsoul at gmail.com> wrote:
>
> Hi,
>
> > On Mon, Dec 16, 2024 at 11:33?PM Krzysztof Kozlowski <krzk at kernel.org> wrote:
> > >
> > > On Sat, Dec 14, 2024 at 09:34:57PM -0800, Vasily Khoruzhick wrote:
> > > > These will be used to explicitly select TCON0 clock parent in dts
> > > >
> > > > Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux")
> > > > Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
> > > > ---
> > > >  drivers/clk/sunxi-ng/ccu-sun50i-a64.h      | 2 --
> > > >  include/dt-bindings/clock/sun50i-a64-ccu.h | 2 +
> >
> > Hi Krzysztof,
> >
> > > You cannot combine these changes.
> >
> > The patch basically moves defines out from ccu-sun50i-a64.h to
> > sun50i-a64-ccu.h. How do I split the change without introducing
> > compilation failure?
>
> You can just have the binding part first, adding the (same) definition
> to the binding headers. As long as the #define's are not conflicting,
> this is fine.
> Then remove the now redundant definitions in the kernel headers, with a
> subsequent patch.

Thanks for the suggestion! I'll address it in v2.


From poojaamonica94 at gmail.com  Tue Dec 17 22:58:48 2024
From: poojaamonica94 at gmail.com (Poojaa R)
Date: Wed, 18 Dec 2024 12:28:48 +0530
Subject: [PATCH] dtoverlays: Added DT overlay file for MAX98090 and the detailed steps for its usage is included in https://github.com/Poojaa-Rangaiah/DeviceTreeOverlay-for-MAX98090 .
Message-ID: <20241218065848.12254-1-poojaamonica94@gmail.com>

Only the driver files were existing for max98090 audio codec (playback and capture) but now the max98090.dts file is also included in linux/arch/arm/boot/dts/overlays/.
new file:   arch/arm/boot/dts/overlays/max98090.dts

Signed-off-by: Poojaa R <poojaamonica94 at gmail.com>
---
 arch/arm/boot/dts/overlays/max98090.dts | 96 +++++++++++++++++++++++++
 1 file changed, 96 insertions(+)
 create mode 100644 arch/arm/boot/dts/overlays/max98090.dts

diff --git a/arch/arm/boot/dts/overlays/max98090.dts b/arch/arm/boot/dts/overlays/max98090.dts
new file mode 100644
index 000000000000..eaf197384edb
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/max98090.dts
@@ -0,0 +1,96 @@
+/*
+ * Device Tree Overlay for MAX98090, MAX98091 Audio Codec.
+ * https://github.com/Poojaa-Rangaiah/DeviceTreeOverlay-for-MAX98090 => for more details.
+ * MAX98090 audio codec as master and Raspberry Pi as slave.
+ */
+
+/dts-v1/;
+/plugin/;
+
+/ {
+    compatible = "brcm,bcm2835", "brcm,bcm2711";
+
+    fragment at 0 {
+        target = <&i2s_clk_consumer>;
+        __overlay__ {
+            status = "okay";
+        };
+    };
+
+    fragment at 1 {
+        target = <&i2c1>;
+        __overlay__ {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            status = "okay";
+            max98090_codec: max98090 at 10 {
+                #sound-dai-cells = <0>;
+                compatible = "maxim,max98090","maxim,max98091";
+                reg = <0x10>;
+                interrupt-parent = <&gpio>;
+                interrupts = <27 2>;	/* GPIO 27 as Edge_Falling_IRQ (2) */
+                maxim,micbias = <3>;
+                status = "okay";
+            };
+        };
+    };
+
+    fragment at 2 {
+        target-path = "/";
+        __overlay__ {
+            clk_oscillator: oscillator {
+                compatible = "fixed-clock";
+                #clock-cells = <0>;
+                clock-frequency = <12288000>;  /* Frequency of the external oscillator (mclk = 12.288 MHz) but can also be 11.2896 MHz/12 MHz/13 MHz/26 MHz/19.2 MHz. */
+                clock-output-names = "mclk";
+            };
+        };
+    };
+
+    fragment at 3 {
+        target = <&sound>;
+        sound_overlay: __overlay__ {
+            compatible = "simple-audio-card";
+            simple-audio-card,format = "i2s";
+            simple-audio-card,name = "MAX98090-Codec";
+            simple-audio-card,bitclock-master = <&dailink0_master>;
+            simple-audio-card,frame-master = <&dailink0_master>;
+
+            simple-audio-card,widgets =
+                "Microphone", "Mic Jack",
+                "Speaker", "Speaker",
+                "Line", "Line In",
+                "Line", "Line Out",
+                "Headphone", "Headphone Jack";
+
+            simple-audio-card,routing =
+                "Headphone Jack", "HPL",
+                "Headphone Jack", "HPR",
+                "Line Out", "RCVL",
+                "Line Out", "RCVR", 
+                /* Uncomment any of these below lines if the Line Input(s) is(are) used else leave it as such. */
+                //"IN5", "Line In",  /* IN1/IN2/IN3/IN4/IN6 (For single ended input) */
+                //"IN56", "Line In", /* IN34 (For differential inputs) */
+                "MIC1", "Mic Jack",
+                "MIC2", "Mic Jack",
+                "Speaker", "SPKL",
+                "Speaker", "SPKR";
+
+            status = "okay";
+
+            simple-audio-card,cpu {
+                sound-dai = <&i2s_clk_consumer>;
+            };
+
+            dailink0_master: simple-audio-card,codec {
+                sound-dai = <&max98090_codec>;
+                clocks = <&clk_oscillator>;
+            };
+        };
+    };
+    
+    __overrides__ {
+        card-name = <&sound_overlay>, "simple-audio-card,name";
+    };
+};
+
-- 
2.34.1



From anshuman.khandual at arm.com  Tue Dec 17 22:59:40 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 18 Dec 2024 12:29:40 +0530
Subject: [PATCH] mm/ptdump: Drop GENERIC_PTDUMP
In-Reply-To: <ddd4439e-6f6f-4513-a7dc-b7f01bec03dc@csgroup.eu>
References: <20241217034807.2541349-1-anshuman.khandual@arm.com>
 <ddd4439e-6f6f-4513-a7dc-b7f01bec03dc@csgroup.eu>
Message-ID: <27980882-4433-443f-abd1-ea5d96b687ea@arm.com>



On 12/17/24 13:17, Christophe Leroy wrote:
> 
> 
> Le 17/12/2024 ? 04:48, Anshuman Khandual a ?crit?:
>> GENERIC_PTDUMP does not guard any code but instead just used for platform's
>> subscription into core ptdump defined under PTDUMP_CORE, which is selected.
>> Instead use PTDUMP_CORE for platform subscription and drop GENERIC_PTDUMP.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Jonathan Corbet <corbet at lwn.net>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: Michael Ellerman <mpe at ellerman.id.au>
>> Cc: Nicholas Piggin <npiggin at gmail.com>
>> Cc: Paul Walmsley <paul.walmsley at sifive.com>
>> Cc: Palmer Dabbelt <palmer at dabbelt.com>
>> Cc: Heiko Carstens <hca at linux.ibm.com>
>> Cc: Vasily Gorbik <gor at linux.ibm.com>
>> Cc: Thomas Gleixner <tglx at linutronix.de>
>> Cc: Ingo Molnar <mingo at redhat.com>
>> Cc: Andrew Morton <akpm at linux-foundation.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-doc at vger.kernel.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: kvmarm at lists.linux.dev
>> Cc: linuxppc-dev at lists.ozlabs.org
>> Cc: linux-riscv at lists.infradead.org
>> Cc: linux-s390 at vger.kernel.org
>> Cc: linux-mm at kvack.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> This patch applies on v6.13-rc3 and has been tested on arm64, although it
>> also clears build tests on impacted platforms.
>>
>> ? Documentation/arch/arm64/ptdump.rst?????? | 1 -
>> ? arch/arm64/Kconfig??????????????????????? | 2 +-
>> ? arch/arm64/kvm/Kconfig??????????????????? | 3 +--
>> ? arch/powerpc/Kconfig????????????????????? | 2 +-
>> ? arch/powerpc/configs/mpc885_ads_defconfig | 1 -
>> ? arch/riscv/Kconfig??????????????????????? | 2 +-
>> ? arch/s390/Kconfig???????????????????????? | 2 +-
>> ? arch/x86/Kconfig????????????????????????? | 2 +-
>> ? arch/x86/Kconfig.debug??????????????????? | 2 +-
>> ? kernel/configs/debug.config?????????????? | 1 -
>> ? mm/Kconfig.debug????????????????????????? | 8 ++------
>> ? 11 files changed, 9 insertions(+), 17 deletions(-)
>>
> 
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index a0ce777f9706..c716f8df10de 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -203,7 +203,7 @@ config PPC
>> ????? select GENERIC_IRQ_SHOW
>> ????? select GENERIC_IRQ_SHOW_LEVEL
>> ????? select GENERIC_PCI_IOMAP??????? if PCI
>> -??? select GENERIC_PTDUMP
>> +??? select PTDUMP_CORE
> 
> Please keep alphabetical order.

Sure, will do that.

> 
>> ????? select GENERIC_SMP_IDLE_THREAD
>> ????? select GENERIC_TIME_VSYSCALL
>> ????? select GENERIC_VDSO_TIME_NS
> 
>> diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
>> index 41a58536531d..b206e5a11f96 100644
>> --- a/mm/Kconfig.debug
>> +++ b/mm/Kconfig.debug
>> @@ -187,7 +187,7 @@ config DEBUG_WX
>> ????? bool "Warn on W+X mappings at boot"
>> ????? depends on ARCH_HAS_DEBUG_WX
>> ????? depends on MMU
>> -??? select PTDUMP_CORE
>> +??? depends on PTDUMP_CORE
> 
> This change is unclear to me. It works because all arch selecting ARCH_HAS_DEBUG_WX also select GENERIC_PTDUMP. For riscv it's even more tricking, Riscv only selects GENERIC_PTDUMP when MMU is set, so it works because here it also depends on MMU.

Right, all the archs selecting ARCH_HAS_DEBUG_WX also select PTDUMP_CORE.
DEBUG_WX dependency on PTDUMP_CORE will always be met, when the platform
selects ARCH_HAS_DEBUG_WX as expected.

git grep "select PTDUMP_CORE" arch/
arch/arm64/Kconfig:     select PTDUMP_CORE
arch/powerpc/Kconfig:   select PTDUMP_CORE
arch/riscv/Kconfig:     select PTDUMP_CORE if MMU
arch/s390/Kconfig:      select PTDUMP_CORE
arch/x86/Kconfig:       select PTDUMP_CORE

git grep ARCH_HAS_DEBUG_WX arch/
arch/arm64/Kconfig:     select ARCH_HAS_DEBUG_WX
arch/powerpc/Kconfig:   select ARCH_HAS_DEBUG_WX                if STRICT_KERNEL_RWX
arch/riscv/Kconfig:     select ARCH_HAS_DEBUG_WX
arch/s390/Kconfig:      select ARCH_HAS_DEBUG_WX
arch/x86/Kconfig:       select ARCH_HAS_DEBUG_WX

On riscv platform, does not PTDUMP_CORE implicitly imply existence of MMU ?
Could there be a page table dumper without a MMU.

> 
> But what happens if in the future an architecture selects ARCH_HAS_DEBUG_WX without selecting PTDUMP_CORE ?

Should DEBUG_WX just select PTDUMP_CORE as it exists now. A platform
will be able to get PTDUMP_CORE via DEBUG_WX if ARCH_HAS_DEBUG_WX is
subscribed into. Would that be better ?

> 
> 
>> ????? help
>> ??????? Generate a warning if any W+X mappings are found at boot.
>> ? @@ -212,9 +212,6 @@ config DEBUG_WX
>> ? ??????? If in doubt, say "Y".
>> ? -config GENERIC_PTDUMP
>> -??? bool
>> -
>> ? config PTDUMP_CORE
>> ????? bool
>> ? @@ -222,8 +219,7 @@ config PTDUMP_DEBUGFS
>> ????? bool "Export kernel pagetable layout to userspace via debugfs"
>> ????? depends on DEBUG_KERNEL
>> ????? depends on DEBUG_FS
>> -??? depends on GENERIC_PTDUMP
>> -??? select PTDUMP_CORE
>> +??? depends on PTDUMP_CORE
>> ????? help
>> ??????? Say Y here if you want to show the kernel pagetable layout in a
>> ??????? debugfs file. This information is only useful for kernel developers
> 


From christophe.leroy at csgroup.eu  Tue Dec 17 23:20:51 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Wed, 18 Dec 2024 08:20:51 +0100
Subject: [PATCH 12/17] powerpc/vdso: Switch to generic storage
 implementation
In-Reply-To: <20241216-vdso-store-rng-v1-12-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-12-f7aed1bdb3b2@linutronix.de>
Message-ID: <12120bbe-1d79-425b-982d-46af1fa5d70d@csgroup.eu>



Le 16/12/2024 ? 15:10, Thomas Wei?schuh a ?crit?:
> The generic storage implementation provides the same features as the
> custom one. However it can be shared between architectures, making
> maintenance easier.
> 
> Co-developed-by: Nam Cao <namcao at linutronix.de>
> Signed-off-by: Nam Cao <namcao at linutronix.de>
> Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
> ---
>   arch/powerpc/Kconfig                         |   2 +
>   arch/powerpc/include/asm/vdso.h              |   1 +
>   arch/powerpc/include/asm/vdso/arch_data.h    |  37 +++++++++
>   arch/powerpc/include/asm/vdso/getrandom.h    |  11 +--
>   arch/powerpc/include/asm/vdso/gettimeofday.h |  36 +++++----
>   arch/powerpc/include/asm/vdso/vsyscall.h     |  13 ---
>   arch/powerpc/include/asm/vdso_datapage.h     |  44 +---------
>   arch/powerpc/kernel/asm-offsets.c            |   1 -
>   arch/powerpc/kernel/time.c                   |   2 +-
>   arch/powerpc/kernel/vdso.c                   | 115 +++------------------------
>   arch/powerpc/kernel/vdso/cacheflush.S        |   2 +-
>   arch/powerpc/kernel/vdso/datapage.S          |   4 +-
>   arch/powerpc/kernel/vdso/gettimeofday.S      |   4 +-
>   arch/powerpc/kernel/vdso/vdso32.lds.S        |   4 +-
>   arch/powerpc/kernel/vdso/vdso64.lds.S        |   4 +-
>   arch/powerpc/kernel/vdso/vgettimeofday.c     |  14 ++--
>   16 files changed, 101 insertions(+), 193 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a0ce777f97063bf858942c60654d8411bcf2a3dc..600fa3b917ee902d016f2a04376950a9dc49074f 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -156,6 +156,7 @@ config PPC
>   	select ARCH_HAS_TICK_BROADCAST		if GENERIC_CLOCKEVENTS_BROADCAST
>   	select ARCH_HAS_UACCESS_FLUSHCACHE
>   	select ARCH_HAS_UBSAN
> +	select ARCH_HAS_VDSO_ARCH_DATA
>   	select ARCH_HAVE_NMI_SAFE_CMPXCHG
>   	select ARCH_HAVE_EXTRA_ELF_NOTES        if SPU_BASE
>   	select ARCH_KEEP_MEMBLOCK
> @@ -206,6 +207,7 @@ config PPC
>   	select GENERIC_PTDUMP
>   	select GENERIC_SMP_IDLE_THREAD
>   	select GENERIC_TIME_VSYSCALL
> +	select GENERIC_VDSO_DATA_STORE
>   	select GENERIC_VDSO_TIME_NS
>   	select HAS_IOPORT			if PCI
>   	select HAVE_ARCH_AUDITSYSCALL
> diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h
> index 8d972bc98b55fe916f23488ca9e2a5918046b9aa..1ca23fbfe087ae90b90c4286335f86d9f8121078 100644
> --- a/arch/powerpc/include/asm/vdso.h
> +++ b/arch/powerpc/include/asm/vdso.h
> @@ -3,6 +3,7 @@
>   #define _ASM_POWERPC_VDSO_H
>   
>   #define VDSO_VERSION_STRING	LINUX_2.6.15
> +#define __VDSO_PAGES		4
>   
>   #ifndef __ASSEMBLY__
>   
> diff --git a/arch/powerpc/include/asm/vdso/arch_data.h b/arch/powerpc/include/asm/vdso/arch_data.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..c240a6b875181ac4159f2e80b11f9bf214e22808
> --- /dev/null
> +++ b/arch/powerpc/include/asm/vdso/arch_data.h
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2002 Peter Bergner <bergner at vnet.ibm.com>, IBM
> + * Copyright (C) 2005 Benjamin Herrenschmidy <benh at kernel.crashing.org>,
> + * 		      IBM Corp.
> + */
> +#ifndef _ASM_POWERPC_VDSO_ARCH_DATA_H
> +#define _ASM_POWERPC_VDSO_ARCH_DATA_H
> +
> +#include <linux/unistd.h>
> +#include <linux/types.h>
> +
> +#define SYSCALL_MAP_SIZE      ((NR_syscalls + 31) / 32)
> +
> +#ifdef CONFIG_PPC64
> +
> +struct vdso_arch_data {
> +	__u64 tb_ticks_per_sec;			/* Timebase tics / sec */
> +	__u32 dcache_block_size;		/* L1 d-cache block size     */
> +	__u32 icache_block_size;		/* L1 i-cache block size     */
> +	__u32 dcache_log_block_size;		/* L1 d-cache log block size */
> +	__u32 icache_log_block_size;		/* L1 i-cache log block size */
> +	__u32 syscall_map[SYSCALL_MAP_SIZE];	/* Map of syscalls  */
> +	__u32 compat_syscall_map[SYSCALL_MAP_SIZE];	/* Map of compat syscalls */
> +};
> +
> +#else /* CONFIG_PPC64 */
> +
> +struct vdso_arch_data {
> +	__u64 tb_ticks_per_sec;		/* Timebase tics / sec */
> +	__u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */
> +	__u32 compat_syscall_map[0];	/* No compat syscalls on PPC32 */
> +};
> +
> +#endif /* CONFIG_PPC64 */
> +
> +#endif /* _ASM_POWERPC_VDSO_ARCH_DATA_H */
> diff --git a/arch/powerpc/include/asm/vdso/getrandom.h b/arch/powerpc/include/asm/vdso/getrandom.h
> index 80ce0709725eb89c1f3b69e0733038b458fbf24f..c82eb0d8237681a7396abfe7d161292636b8cce4 100644
> --- a/arch/powerpc/include/asm/vdso/getrandom.h
> +++ b/arch/powerpc/include/asm/vdso/getrandom.h
> @@ -43,20 +43,21 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig
>   			    (unsigned long)len, (unsigned long)flags);
>   }
>   
> -static __always_inline struct vdso_rng_data *__arch_get_vdso_rng_data(void)
> +static __always_inline const struct vdso_rng_data *__ppc_get_vdso_u_rng_data(void)
>   {
> -	struct vdso_arch_data *data;
> +	struct vdso_rng_data *data;
>   
>   	asm (
>   		"	bcl	20, 31, .+4 ;"
>   		"0:	mflr	%0 ;"
> -		"	addis	%0, %0, (_vdso_datapage - 0b)@ha ;"
> -		"	addi	%0, %0, (_vdso_datapage - 0b)@l  ;"
> +		"	addis	%0, %0, (vdso_u_rng_data - 0b)@ha ;"
> +		"	addi	%0, %0, (vdso_u_rng_data - 0b)@l  ;"
>   		: "=r" (data) : : "lr"
>   	);
>   
> -	return &data->rng_data;
> +	return data;
>   }
> +#define __arch_get_vdso_u_rng_data __ppc_get_vdso_u_rng_data
>   
>   ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
>   			     size_t opaque_len);
> diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h
> index c6390890a60c2fdcb608bf321b2945c3fb372f54..bddd9cde97db197d0d3daba6c2289cb29e6b5a75 100644
> --- a/arch/powerpc/include/asm/vdso/gettimeofday.h
> +++ b/arch/powerpc/include/asm/vdso/gettimeofday.h
> @@ -94,22 +94,29 @@ int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
>   #endif
>   
>   static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
> -						 const struct vdso_data *vd)
> +						 const struct vdso_time_data *vd)
>   {
>   	return get_tb();
>   }
>   
> -const struct vdso_data *__arch_get_vdso_data(void);
> -
>   #ifdef CONFIG_TIME_NS
> -static __always_inline
> -const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
> +static __always_inline const struct vdso_time_data *__ppc_get_vdso_u_timens_data(void)
>   {
> -	return (void *)vd + (1U << CONFIG_PAGE_SHIFT);
> +	struct vdso_time_data *time_data;
> +
> +	asm(
> +		"	bcl	20, 31, .+4\n"
> +		"0:	mflr	%0\n"
> +		"	addis	%0, %0, (vdso_u_timens_data - 0b)@ha\n"
> +		"	addi	%0, %0, (vdso_u_timens_data - 0b)@l\n"
> +	: "=r" (time_data) :: "lr");
> +
> +	return time_data;

Please don't do that, it kills optimisation efforts done when 
implementing VDSO time. Commit ce7d8056e38b ("powerpc/vdso: Prepare for 
switching VDSO to generic C implementation.") explains why.

For time data, the bcl/mflr dance is done by get_datapage macro called 
by cvdso_call macro in gettimeofday.S, and given to 
__cvdso_clock_gettime_data() by __c_kernel_clock_gettime() in 
vgettimeofday.c . Use that information and don't redo the bcl/mflr sequence.

See for instance function __c_kernel_clock_getres():

Before your series it is 30 instructions.
After your series it is 59 instructions.

Before:
000010f8 <__c_kernel_clock_getres>:
     10f8:	28 03 00 0f 	cmplwi  r3,15
     10fc:	41 81 00 60 	bgt     115c <__c_kernel_clock_getres+0x64>
     1100:	81 45 00 04 	lwz     r10,4(r5)
     1104:	3d 20 7f ff 	lis     r9,32767
     1108:	61 29 ff ff 	ori     r9,r9,65535
     110c:	7c 0a 48 00 	cmpw    r10,r9
     1110:	40 a2 00 08 	bne     1118 <__c_kernel_clock_getres+0x20>
     1114:	38 a5 40 00 	addi    r5,r5,16384
     1118:	39 20 00 01 	li      r9,1
     111c:	7d 29 18 30 	slw     r9,r9,r3
     1120:	71 2a 08 93 	andi.   r10,r9,2195
     1124:	40 82 00 30 	bne     1154 <__c_kernel_clock_getres+0x5c>
     1128:	71 29 00 60 	andi.   r9,r9,96
     112c:	41 82 00 30 	beq     115c <__c_kernel_clock_getres+0x64>
     1130:	3d 20 00 98 	lis     r9,152
     1134:	61 29 96 80 	ori     r9,r9,38528
     1138:	2c 04 00 00 	cmpwi   r4,0
     113c:	41 82 00 10 	beq     114c <__c_kernel_clock_getres+0x54>
     1140:	39 40 00 00 	li      r10,0
     1144:	91 24 00 04 	stw     r9,4(r4)
     1148:	91 44 00 00 	stw     r10,0(r4)
     114c:	38 60 00 00 	li      r3,0
     1150:	4e 80 00 20 	blr
     1154:	81 25 00 e8 	lwz     r9,232(r5)
     1158:	4b ff ff e0 	b       1138 <__c_kernel_clock_getres+0x40>
     115c:	38 00 00 f7 	li      r0,247
     1160:	44 00 00 02 	sc
     1164:	40 a3 00 08 	bns     116c <__c_kernel_clock_getres+0x74>
     1168:	7c 63 00 d0 	neg     r3,r3
     116c:	4e 80 00 20 	blr

After:
000011ac <__c_kernel_clock_getres>:
     11ac:	28 03 00 0f 	cmplwi  r3,15
     11b0:	41 81 00 c0 	bgt     1270 <__c_kernel_clock_getres+0xc4>
     11b4:	81 45 00 04 	lwz     r10,4(r5)
     11b8:	3d 20 7f ff 	lis     r9,32767
     11bc:	61 29 ff ff 	ori     r9,r9,65535
     11c0:	7c 0a 48 00 	cmpw    r10,r9
     11c4:	41 82 00 48 	beq     120c <__c_kernel_clock_getres+0x60>
     11c8:	39 20 00 01 	li      r9,1
     11cc:	7d 29 18 30 	slw     r9,r9,r3
     11d0:	71 2a 08 93 	andi.   r10,r9,2195
     11d4:	40 82 00 30 	bne     1204 <__c_kernel_clock_getres+0x58>
     11d8:	71 29 00 60 	andi.   r9,r9,96
     11dc:	41 82 00 94 	beq     1270 <__c_kernel_clock_getres+0xc4>
     11e0:	3d 20 00 98 	lis     r9,152
     11e4:	61 29 96 80 	ori     r9,r9,38528
     11e8:	2c 04 00 00 	cmpwi   r4,0
     11ec:	41 82 00 10 	beq     11fc <__c_kernel_clock_getres+0x50>
     11f0:	39 40 00 00 	li      r10,0
     11f4:	91 24 00 04 	stw     r9,4(r4)
     11f8:	91 44 00 00 	stw     r10,0(r4)
     11fc:	38 60 00 00 	li      r3,0
     1200:	4e 80 00 20 	blr
     1204:	81 25 00 e8 	lwz     r9,232(r5)
     1208:	4b ff ff e0 	b       11e8 <__c_kernel_clock_getres+0x3c>
     120c:	39 20 00 01 	li      r9,1
     1210:	7d 29 18 30 	slw     r9,r9,r3
     1214:	71 2a 08 93 	andi.   r10,r9,2195
     1218:	7c 08 02 a6 	mflr    r0
     121c:	90 01 00 04 	stw     r0,4(r1)
     1220:	42 9f 00 05 	bcl     20,4*cr7+so,1224 
<__c_kernel_clock_getres+0x78>
     1224:	7c a8 02 a6 	mflr    r5
     1228:	3c a5 ff ff 	addis   r5,r5,-1
     122c:	38 a5 2d dc 	addi    r5,r5,11740
     1230:	40 82 00 38 	bne     1268 <__c_kernel_clock_getres+0xbc>
     1234:	71 29 00 60 	andi.   r9,r9,96
     1238:	41 82 00 4c 	beq     1284 <__c_kernel_clock_getres+0xd8>
     123c:	3d 20 00 98 	lis     r9,152
     1240:	61 29 96 80 	ori     r9,r9,38528
     1244:	2c 04 00 00 	cmpwi   r4,0
     1248:	41 82 00 10 	beq     1258 <__c_kernel_clock_getres+0xac>
     124c:	39 40 00 00 	li      r10,0
     1250:	91 24 00 04 	stw     r9,4(r4)
     1254:	91 44 00 00 	stw     r10,0(r4)
     1258:	38 60 00 00 	li      r3,0
     125c:	80 01 00 04 	lwz     r0,4(r1)
     1260:	7c 08 03 a6 	mtlr    r0
     1264:	4e 80 00 20 	blr
     1268:	81 25 00 e8 	lwz     r9,232(r5)
     126c:	4b ff ff d8 	b       1244 <__c_kernel_clock_getres+0x98>
     1270:	38 00 00 f7 	li      r0,247
     1274:	44 00 00 02 	sc
     1278:	40 a3 00 08 	bns     1280 <__c_kernel_clock_getres+0xd4>
     127c:	7c 63 00 d0 	neg     r3,r3
     1280:	4e 80 00 20 	blr
     1284:	38 00 00 f7 	li      r0,247
     1288:	44 00 00 02 	sc
     128c:	40 a3 00 08 	bns     1294 <__c_kernel_clock_getres+0xe8>
     1290:	7c 63 00 d0 	neg     r3,r3
     1294:	4b ff ff c8 	b       125c <__c_kernel_clock_getres+0xb0>

>   }
> +#define __arch_get_vdso_u_timens_data __ppc_get_vdso_u_timens_data

There is not #ifdef __arch_get_vdso_u_timens_data anywhere, this #define 
is not needed, the function should be called 
__arch_get_vdso_u_timens_data() directly as before, unnecessary 
indirections reduce readability.

>   #endif
>   
> -static inline bool vdso_clocksource_ok(const struct vdso_data *vd)
> +static inline bool vdso_clocksource_ok(const struct vdso_time_data *vd)
>   {
>   	return true;
>   }


From christophe.leroy at csgroup.eu  Tue Dec 17 23:32:14 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Wed, 18 Dec 2024 08:32:14 +0100
Subject: [PATCH 03/17] vdso: Add generic time data storage
In-Reply-To: <20241216-vdso-store-rng-v1-3-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-3-f7aed1bdb3b2@linutronix.de>
Message-ID: <3b44defd-cd2a-4a3c-b72d-bcc0530336da@csgroup.eu>



Le 16/12/2024 ? 15:09, Thomas Wei?schuh a ?crit?:
> Historically each architecture defined their own way to store the vDSO
> data page. Add a generic mechanism to provide storage for that page.
> 
> Furthermore this generic storage will be extended to also provide
> uniform storage for *non*-time-related data, like the random state or
> architecture-specific data. These will have their own pages and data
> structures, so rename 'vdso_data' into 'vdso_time_data' to make that
> split clear from the name.
> 
> Also introduce a new consistent naming scheme for the symbols related to
> the vDSO, which makes it clear if the symbol is accessible from
> userspace or kernel space and the type of data behind the symbol.
> 
> The generic fault handler contains an optimization to prefault the vvar
> page when the timens page is accessed. This was lifted from s390 and x86.
> 
> Co-developed-by: Nam Cao <namcao at linutronix.de>
> Signed-off-by: Nam Cao <namcao at linutronix.de>
> Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
> ---
>   MAINTAINERS                    |  1 +
>   include/linux/time_namespace.h |  1 +
>   include/linux/vdso_datastore.h | 10 +++++
>   include/vdso/datapage.h        | 69 +++++++++++++++++++++++++----
>   lib/Kconfig                    |  1 +
>   lib/Makefile                   |  2 +
>   lib/vdso_kernel/Kconfig        |  7 +++
>   lib/vdso_kernel/Makefile       |  3 ++
>   lib/vdso_kernel/datastore.c    | 99 ++++++++++++++++++++++++++++++++++++++++++

There is only one single file, namely datastore.c. You don't need a new 
directory for that, I should go in lib/vdso/


>   9 files changed, 185 insertions(+), 8 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1e930c7a58b13d8bbe6bf133ba7b36aa24c2b5e0..9d947e1e90ff3c6060e56f3b7eaa28cd60d6191c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -9677,6 +9677,7 @@ F:	include/asm-generic/vdso/vsyscall.h
>   F:	include/vdso/
>   F:	kernel/time/vsyscall.c
>   F:	lib/vdso/
> +F:	lib/vdso_kernel/

New dir not needed

>   
>   GENWQE (IBM Generic Workqueue Card)
>   M:	Frank Haverkamp <haver at linux.ibm.com>
> diff --git a/include/linux/time_namespace.h b/include/linux/time_namespace.h
> index 876e31b4461d0ee01fe2bd3d136acdea2611789f..4b81db223f5450218dfaf553b24195be9ba97c08 100644
> --- a/include/linux/time_namespace.h
> +++ b/include/linux/time_namespace.h
> @@ -8,6 +8,7 @@
>   #include <linux/ns_common.h>
>   #include <linux/err.h>
>   #include <linux/time64.h>
> +#include <vdso/datapage.h>
>   
>   struct user_namespace;
>   extern struct user_namespace init_user_ns;
> diff --git a/include/linux/vdso_datastore.h b/include/linux/vdso_datastore.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..a91fa24b06e09321fdff8c2c7bdfbc1b206db574
> --- /dev/null
> +++ b/include/linux/vdso_datastore.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _LINUX_VDSO_DATASTORE_H
> +#define _LINUX_VDSO_DATASTORE_H
> +
> +#include <linux/mm_types.h>
> +
> +extern const struct vm_special_mapping vdso_vvar_mapping;
> +struct vm_area_struct *vdso_install_vvar_mapping(struct mm_struct *mm, unsigned long addr);
> +
> +#endif /* _LINUX_VDSO_DATASTORE_H */
> diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
> index d967baa0cd0c65784e38dc4fcd7b9e8273923947..69af424413db1f265607d0f1bdbf88550548c5ba 100644
> --- a/include/vdso/datapage.h
> +++ b/include/vdso/datapage.h
> @@ -45,11 +45,11 @@ struct arch_vdso_time_data {};
>    *
>    * There is one vdso_timestamp object in vvar for each vDSO-accelerated
>    * clock_id. For high-resolution clocks, this encodes the time
> - * corresponding to vdso_data.cycle_last. For coarse clocks this encodes
> + * corresponding to vdso_time_data.cycle_last. For coarse clocks this encodes
>    * the actual time.
>    *
>    * To be noticed that for highres clocks nsec is left-shifted by
> - * vdso_data.cs[x].shift.
> + * vdso_time_data[x].shift.
>    */
>   struct vdso_timestamp {
>   	u64	sec;
> @@ -57,7 +57,7 @@ struct vdso_timestamp {
>   };
>   
>   /**
> - * struct vdso_data - vdso datapage representation
> + * struct vdso_time_data - vdso datapage representation
>    * @seq:		timebase sequence counter
>    * @clock_mode:		clock mode
>    * @cycle_last:		timebase at clocksource init
> @@ -74,7 +74,7 @@ struct vdso_timestamp {
>    * @arch_data:		architecture specific data (optional, defaults
>    *			to an empty struct)
>    *
> - * vdso_data will be accessed by 64 bit and compat code at the same time
> + * vdso_time_data will be accessed by 64 bit and compat code at the same time
>    * so we should be careful before modifying this structure.
>    *
>    * The ordering of the struct members is optimized to have fast access to the
> @@ -92,7 +92,7 @@ struct vdso_timestamp {
>    * For clocks which are not affected by time namespace adjustment the
>    * offset must be zero.
>    */
> -struct vdso_data {
> +struct vdso_time_data {
>   	u32			seq;
>   
>   	s32			clock_mode;
> @@ -117,6 +117,8 @@ struct vdso_data {
>   	struct arch_vdso_time_data arch_data;
>   };
>   
> +#define vdso_data vdso_time_data
> +
>   /**
>    * struct vdso_rng_data - vdso RNG state information
>    * @generation:	counter representing the number of RNG reseeds
> @@ -136,18 +138,55 @@ struct vdso_rng_data {
>    * With the hidden visibility, the compiler simply generates a PC-relative
>    * relocation, and this is what we need.
>    */
> -extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
> -extern struct vdso_data _timens_data[CS_BASES] __attribute__((visibility("hidden")));
> +#ifndef CONFIG_GENERIC_VDSO_DATA_STORE
> +extern struct vdso_time_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
> +extern struct vdso_time_data _timens_data[CS_BASES] __attribute__((visibility("hidden")));
>   extern struct vdso_rng_data _vdso_rng_data __attribute__((visibility("hidden")));
> +#else
> +extern const struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
> +extern const struct vdso_time_data vdso_u_timens_data[CS_BASES] __attribute__((visibility("hidden")));
> +
> +extern struct vdso_time_data *vdso_k_time_data;
> +#endif
>   
>   /**
>    * union vdso_data_store - Generic vDSO data page
>    */
>   union vdso_data_store {
> -	struct vdso_data	data[CS_BASES];
> +	struct vdso_time_data	data[CS_BASES];
>   	u8			page[1U << CONFIG_PAGE_SHIFT];
>   };
>   
> +#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
> +
> +enum vdso_pages {
> +	VDSO_TIME_PAGE_OFFSET,
> +	VDSO_TIMENS_PAGE_OFFSET,
> +	VDSO_NR_PAGES
> +};

Naming that VDSO_ is confusing. Most macros called VDSO_ are related to 
the VDSO Code. VDSO data related macros should be prefixed with VVAR_

> +
> +static __always_inline struct vdso_time_data *__arch_get_vdso_k_time_data(void)
> +{
> +	return vdso_k_time_data;
> +}
> +#define __arch_get_k_vdso_data __arch_get_vdso_k_time_data
> +
> +static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
> +{
> +	return vdso_u_time_data;
> +}
> +#define __arch_get_vdso_data __arch_get_vdso_u_time_data
> +
> +#ifdef CONFIG_TIME_NS
> +static __always_inline const struct vdso_time_data *__arch_get_vdso_u_timens_data(void)
> +{
> +	return vdso_u_timens_data;
> +}
> +#define __arch_get_timens_vdso_data(vd) __arch_get_vdso_u_timens_data()
> +#endif /* CONFIG_TIME_NS */
> +
> +#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
> +
>   /*
>    * The generic vDSO implementation requires that gettimeofday.h
>    * provides:
> @@ -164,6 +203,20 @@ union vdso_data_store {
>   #include <asm/vdso/gettimeofday.h>
>   #endif /* ENABLE_COMPAT_VDSO */
>   
> +#else /* !__ASSEMBLY__ */
> +
> +#ifdef CONFIG_TIME_NS
> +#define __vdso_u_timens_data	PROVIDE(vdso_u_timens_data = vdso_u_data + PAGE_SIZE);
> +#else
> +#define __vdso_u_timens_data
> +#endif
> +
> +#define VDSO_VVAR_SYMS						\
> +	PROVIDE(vdso_u_data = . - __VDSO_PAGES * PAGE_SIZE);	\
> +	PROVIDE(vdso_u_time_data = vdso_u_data);		\
> +	__vdso_u_timens_data					\
> +
> +
>   #endif /* !__ASSEMBLY__ */
>   
>   #endif /* __VDSO_DATAPAGE_H */
> diff --git a/lib/Kconfig b/lib/Kconfig
> index 5a318f753b2f44cb0a7905cc0092e81c133bc112..7d59b2c10ce5ffab03378ead254d9f9017a4482f 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -659,6 +659,7 @@ config UCS2_STRING
>   # generic vdso
>   #
>   source "lib/vdso/Kconfig"
> +source "lib/vdso_kernel/Kconfig"
>   
>   source "lib/fonts/Kconfig"
>   
> diff --git a/lib/Makefile b/lib/Makefile
> index a8155c972f02856fcc61ee949ddda436cfe211ff..aeedeea86b26cee50d7ced18f9b77b3c51201930 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -401,3 +401,5 @@ obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
>   obj-$(CONFIG_FIRMWARE_TABLE) += fw_table.o
>   
>   subdir-$(CONFIG_FORTIFY_SOURCE) += test_fortify
> +
> +obj-y += vdso_kernel/

No need for a new directory

> diff --git a/lib/vdso_kernel/Kconfig b/lib/vdso_kernel/Kconfig
> new file mode 100644
> index 0000000000000000000000000000000000000000..0c7ade9b3ece67c0c0ca892544b9e29e53c860c4
> --- /dev/null
> +++ b/lib/vdso_kernel/Kconfig
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +config GENERIC_VDSO_DATA_STORE
> +	bool
> +	depends on HAVE_GENERIC_VDSO
> +	help
> +	  Selected by architectures that use the generic vDSO data store.
> diff --git a/lib/vdso_kernel/Makefile b/lib/vdso_kernel/Makefile
> new file mode 100644
> index 0000000000000000000000000000000000000000..4826e49f9edbdb48506b50957584ed89bde5f37f
> --- /dev/null
> +++ b/lib/vdso_kernel/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_GENERIC_VDSO_DATA_STORE) += datastore.o
> diff --git a/lib/vdso_kernel/datastore.c b/lib/vdso_kernel/datastore.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..c9cd269b1ed1b6cdd5fdf9fe929d0b778314b962
> --- /dev/null
> +++ b/lib/vdso_kernel/datastore.c
> @@ -0,0 +1,99 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include <linux/linkage.h>
> +#include <linux/mmap_lock.h>
> +#include <linux/mm.h>
> +#include <linux/time_namespace.h>
> +#include <linux/types.h>
> +#include <linux/vdso_datastore.h>
> +#include <vdso/datapage.h>
> +
> +/*
> + * The vDSO data page.
> + */
> +static union vdso_data_store vdso_time_data_store __page_aligned_data;
> +struct vdso_time_data *vdso_k_time_data = vdso_time_data_store.data;
> +static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE);
> +
> +static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
> +			     struct vm_area_struct *vma, struct vm_fault *vmf)
> +{
> +	struct page *timens_page = find_timens_vvar_page(vma);
> +	unsigned long addr, pfn;
> +	vm_fault_t err;
> +
> +	switch (vmf->pgoff) {
> +	case VDSO_TIME_PAGE_OFFSET:
> +		pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data));
> +		if (timens_page) {
> +			/*
> +			 * Fault in VVAR page too, since it will be accessed
> +			 * to get clock data anyway.
> +			 */
> +			addr = vmf->address + VDSO_TIMENS_PAGE_OFFSET * PAGE_SIZE;
> +			err = vmf_insert_pfn(vma, addr, pfn);
> +			if (unlikely(err & VM_FAULT_ERROR))
> +				return err;
> +			pfn = page_to_pfn(timens_page);
> +		}
> +		break;
> +	case VDSO_TIMENS_PAGE_OFFSET:
> +		/*
> +		 * If a task belongs to a time namespace then a namespace
> +		 * specific VVAR is mapped with the VVAR_DATA_PAGE_OFFSET and
> +		 * the real VVAR page is mapped with the VVAR_TIMENS_PAGE_OFFSET
> +		 * offset.
> +		 * See also the comment near timens_setup_vdso_data().
> +		 */
> +		if (!IS_ENABLED(CONFIG_TIME_NS) || !timens_page)
> +			return VM_FAULT_SIGBUS;
> +		pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data));
> +		break;
> +	default:
> +		return VM_FAULT_SIGBUS;
> +	}
> +
> +	return vmf_insert_pfn(vma, vmf->address, pfn);
> +}
> +
> +const struct vm_special_mapping vdso_vvar_mapping = {
> +	.name	= "[vvar]",
> +	.fault	= vvar_fault,
> +};
> +
> +struct vm_area_struct *vdso_install_vvar_mapping(struct mm_struct *mm, unsigned long addr)
> +{
> +	return _install_special_mapping(mm, addr, VDSO_NR_PAGES * PAGE_SIZE,
> +					VM_READ | VM_MAYREAD | VM_IO | VM_DONTDUMP | VM_PFNMAP,
> +					&vdso_vvar_mapping);
> +}
> +
> +#ifdef CONFIG_TIME_NS
> +/*
> + * The vvar page layout depends on whether a task belongs to the root or
> + * non-root time namespace. Whenever a task changes its namespace, the VVAR
> + * page tables are cleared and then they will be re-faulted with a
> + * corresponding layout.
> + * See also the comment near timens_setup_vdso_data() for details.
> + */
> +int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
> +{
> +	struct mm_struct *mm = task->mm;
> +	struct vm_area_struct *vma;
> +	VMA_ITERATOR(vmi, mm, 0);
> +
> +	mmap_read_lock(mm);
> +	for_each_vma(vmi, vma) {
> +		if (vma_is_special_mapping(vma, &vdso_vvar_mapping))
> +			zap_vma_pages(vma);
> +	}
> +	mmap_read_unlock(mm);
> +
> +	return 0;
> +}
> +#endif
> +
> +struct vdso_time_data *arch_get_vdso_data(void *vvar_page)
> +{
> +	return (struct vdso_time_data *)vvar_page;
> +}
> 



From anshuman.khandual at arm.com  Tue Dec 17 23:49:31 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 18 Dec 2024 13:19:31 +0530
Subject: [PATCH 0/2] docs: arm64: Document MDCR_EL3 boot requirements
In-Reply-To: <20241211065425.1106683-1-anshuman.khandual@arm.com>
References: <20241211065425.1106683-1-anshuman.khandual@arm.com>
Message-ID: <809ddd0a-3fad-4e3a-a106-070d2235b3dc@arm.com>

On 12/11/24 12:24, Anshuman Khandual wrote:
> This series adds missing MDCR_EL3 boot requirements for debug and pmu
> registers that are currently being accessed in the kernel. Please refer
> the following link for some earlier discussions on this.
> 
> https://lore.kernel.org/all/ZxfOeqyb3RvsdYbU at J2N7QTR9R3/
> 
> This series applies on v6.13-rc1
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Jonathan Corbet <corbet at lwn.net>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> 
> Anshuman Khandual (2):
>   docs: arm64: Document EL3 requirements for cpu debug architecture
>   docs: arm64: Document EL3 requirements for FEAT_PMUv3
> 
>  Documentation/arch/arm64/booting.rst | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 

Gentle ping, any updates on this.


From zhangkunbo at huawei.com  Tue Dec 17 23:45:52 2024
From: zhangkunbo at huawei.com (Zhang Kunbo)
Date: Wed, 18 Dec 2024 07:45:52 +0000
Subject: [PATCH -next] wifi: mt76: mt7925:: replace zero-length array with flexible-array member
Message-ID: <20241218074552.3271542-1-zhangkunbo@huawei.com>

The current codebase makes use of the zero-length array language
extension to the C90 standard, but the preferred mechanism to declare
variable-length types such as these ones is a flexible array member[1],
introduced in C99:

struct foo {
	int stuff;
	struct boo array[];
};

By making use of the mechanism above, we will get a compiler warning
in case the flexible array does not occur last, which is beneficial
to cultivate a high-quality code.[2]

This issue was found with the help of Coccinelle.

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")

Signed-off-by: Zhang Kunbo <zhangkunbo at huawei.com>
---
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index 748ea6adbc6b..956d62062730 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -388,7 +388,7 @@ mt7925_mcu_tx_done_event(struct mt792x_dev *dev, struct sk_buff *skb)
 	struct mt7925_mcu_txs_event {
 		u8 ver;
 		u8 rsv[3];
-		u8 data[0];
+		u8 data[];
 	} __packed * txs;
 	struct tlv *tlv;
 	u32 tlv_len;
-- 
2.34.1



From mripard at kernel.org  Tue Dec 17 23:59:43 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Wed, 18 Dec 2024 08:59:43 +0100
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <CAA8EJprjCyWBNkRrc4W24uCwPtf_kxZLqNeNP8EJffbutYQ21w@mail.gmail.com>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-vivacious-chameleon-of-swiftness-f1edc4@houat>
 <CAA8EJprjCyWBNkRrc4W24uCwPtf_kxZLqNeNP8EJffbutYQ21w@mail.gmail.com>
Message-ID: <20241218-wild-red-manatee-bb2a34@houat>

On Wed, Dec 18, 2024 at 07:24:23AM +0200, Dmitry Baryshkov wrote:
> On Tue, 17 Dec 2024 at 19:21, Maxime Ripard <mripard at kernel.org> wrote:
> > On Tue, Dec 17, 2024 at 02:40:22AM +0200, Dmitry Baryshkov wrote:
> > > While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
> > > framework, I stumbled upon an issue while handling the Audio InfoFrames.
> > > The HDMI codec callbacks weren't receiving the drm_atomic_state, so
> > > there was no simple way to get the drm_connector that stayed at the end
> > > of the bridge chain. At the same point the drm_hdmi_connector functions
> > > expected to get drm_connector instance.
> > >
> > > While looking for a way to solve the issue, I stumbled upon several
> > > deficiencies in existing hdmi_codec_ops implementations. Only few of the
> > > implementations were able to handle codec's 'plugged' callback. One
> > > third of the drivers didn't implement the get_eld() callback.
> > >
> > > Most of the issues can be solved if drm_connector handles
> > > hdmi-audio-codec on its own, delegating functionality to the actual
> > > implementation, be it a driver that implements drm_connector or
> > > drm_bridge.
> > >
> > > Implement such high-level framework, adding proper support for Audio
> > > InfoFrame generation to the LT9611 driver.
> > >
> > > Several design decisions to be kept in mind:
> > >
> > > - drm_connector_hdmi_codec is kept as simple as possible. It implements
> > >   generic functionality (ELD, hotplug, registration).
> > >
> > > - drm_hdmi_connector sets up HDMI codec device if the connector
> > >   is setup correspondingly (either I2S or S/PDIF is marked as
> > >   supported).
> > >
> > > - drm_bridge_connector provides a way to link HDMI audio codec
> > >   funcionality in the drm_bridge with the drm_connector_hdmi_codec
> > >   framework.
> > >
> > > - It might be worth reverting the no_i2s_capture / no_spdif_capture
> > >   bits. Only TDA889x driver sets them, while it's safe to assume that
> > >   most of HDMI / DP devices do not support ARC / capture. I think the
> > >   drivers should opt-in capture support rather than having to opt-out of
> > >   it.
> >
> > Sorry if this isn't clear to me and I'm quite late to the party, but did
> > you test this on vc4 with both a pi3 and pi4, or was it just compile
> > tested?
> 
> LT9611 is actually tested, VC4 is only compile-tested. Should I put an RFT tag?

Yeah, we definitely need to test it on the pi3 (polling-based) and the
pi4 (irq-based) at least.

Dave, Maira, could you give it a try?

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

From krzk at kernel.org  Wed Dec 18 00:02:29 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 09:02:29 +0100
Subject: [PATCH v4 6/7] arm64: defconfig: enable cpu idle injection and
 cpu idle cooling device
In-Reply-To: <20241217064856.2772305-7-quic_wasimn@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
 <20241217064856.2772305-7-quic_wasimn@quicinc.com>
Message-ID: <59e96784-9efc-4958-baf0-a51e766e47e8@kernel.org>

On 17/12/2024 07:48, Wasim Nazir wrote:
> From: Manaf Meethalavalappu Pallikunhi <quic_manafm at quicinc.com>
> 
> Enable cpu idle injection framework and thermal cpu idle cooling device
> to throttle the cpu by injecting idle cycle during high thermal condition.
I know what they do, but why do we need it in the defconfig? This is not
a product defconfig, just in case you mirrored downstream patches.

Best regards,
Krzysztof


From mihai.sain at microchip.com  Wed Dec 18 00:03:31 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Wed, 18 Dec 2024 10:03:31 +0200
Subject: [PATCH 0/2] Add address/size properties to spi-controller nodes
Message-ID: <20241218080333.2225-1-mihai.sain@microchip.com>

This patch series adds common properties like address/size to spi-controller nodes.

Mihai Sain (2):
  ARM: dts: microchip: sam9x60: Add address/size to spi-controller nodes
  ARM: dts: microchip: sam9x7: Add address/size to spi-controller nodes

 arch/arm/boot/dts/microchip/sam9x60.dtsi | 12 ++++++++++++
 arch/arm/boot/dts/microchip/sam9x7.dtsi  | 12 ++++++++++++
 2 files changed, 24 insertions(+)


base-commit: aef25be35d23ec768eed08bfcf7ca3cf9685bc28
-- 
2.47.1



From mihai.sain at microchip.com  Wed Dec 18 00:03:33 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Wed, 18 Dec 2024 10:03:33 +0200
Subject: [PATCH 2/2] ARM: dts: microchip: sam9x7: Add address/size to spi-controller nodes
In-Reply-To: <20241218080333.2225-1-mihai.sain@microchip.com>
References: <20241218080333.2225-1-mihai.sain@microchip.com>
Message-ID: <20241218080333.2225-3-mihai.sain@microchip.com>

Since these properties are common for all spi subnodes,
add them to SoC dtsi instead of board dts.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/sam9x7.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/sam9x7.dtsi b/arch/arm/boot/dts/microchip/sam9x7.dtsi
index aedba0a8318f..b217a908f525 100644
--- a/arch/arm/boot/dts/microchip/sam9x7.dtsi
+++ b/arch/arm/boot/dts/microchip/sam9x7.dtsi
@@ -132,6 +132,8 @@ spi4: spi at 400 {
 				compatible = "microchip,sam9x7-spi", "atmel,at91rm9200-spi";
 				reg = <0x400 0x200>;
 				interrupts = <13 IRQ_TYPE_LEVEL_HIGH 7>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 13>;
 				clock-names = "spi_clk";
 				dmas = <&dma0
@@ -203,6 +205,8 @@ spi5: spi at 400 {
 				compatible = "microchip,sam9x7-spi", "atmel,at91rm9200-spi";
 				reg = <0x400 0x200>;
 				interrupts = <14 IRQ_TYPE_LEVEL_HIGH 7>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 14>;
 				clock-names = "spi_clk";
 				dmas = <&dma0
@@ -697,6 +701,8 @@ spi0: spi at 400 {
 				compatible = "microchip,sam9x7-spi", "atmel,at91rm9200-spi";
 				reg = <0x400 0x200>;
 				interrupts = <5 IRQ_TYPE_LEVEL_HIGH 7>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 5>;
 				clock-names = "spi_clk";
 				dmas = <&dma0
@@ -768,6 +774,8 @@ spi1: spi at 400 {
 				compatible = "microchip,sam9x7-spi", "atmel,at91rm9200-spi";
 				reg = <0x400 0x200>;
 				interrupts = <6 IRQ_TYPE_LEVEL_HIGH 7>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 6>;
 				clock-names = "spi_clk";
 				dmas = <&dma0
@@ -839,6 +847,8 @@ spi2: spi at 400 {
 				compatible = "microchip,sam9x7-spi", "atmel,at91rm9200-spi";
 				reg = <0x400 0x200>;
 				interrupts = <7 IRQ_TYPE_LEVEL_HIGH 7>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 7>;
 				clock-names = "spi_clk";
 				dmas = <&dma0
@@ -910,6 +920,8 @@ spi3: spi at 400 {
 				compatible = "microchip,sam9x7-spi", "atmel,at91rm9200-spi";
 				reg = <0x400 0x200>;
 				interrupts = <8 IRQ_TYPE_LEVEL_HIGH 7>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 8>;
 				clock-names = "spi_clk";
 				dmas = <&dma0
-- 
2.47.1



From mihai.sain at microchip.com  Wed Dec 18 00:03:32 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Wed, 18 Dec 2024 10:03:32 +0200
Subject: [PATCH 1/2] ARM: dts: microchip: sam9x60: Add address/size to spi-controller nodes
In-Reply-To: <20241218080333.2225-1-mihai.sain@microchip.com>
References: <20241218080333.2225-1-mihai.sain@microchip.com>
Message-ID: <20241218080333.2225-2-mihai.sain@microchip.com>

Since these properties are common for all spi subnodes,
add them to SoC dtsi instead of board dts.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/sam9x60.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/sam9x60.dtsi b/arch/arm/boot/dts/microchip/sam9x60.dtsi
index 36944e18a329..b8b2c1ddf3f1 100644
--- a/arch/arm/boot/dts/microchip/sam9x60.dtsi
+++ b/arch/arm/boot/dts/microchip/sam9x60.dtsi
@@ -197,6 +197,8 @@ spi4: spi at 400 {
 					compatible = "microchip,sam9x60-spi", "atmel,at91rm9200-spi";
 					reg = <0x400 0x200>;
 					interrupts = <13 IRQ_TYPE_LEVEL_HIGH 7>;
+					#address-cells = <1>;
+					#size-cells = <0>;
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 13>;
 					clock-names = "spi_clk";
 					dmas = <&dma0
@@ -268,6 +270,8 @@ spi5: spi at 400 {
 					compatible = "microchip,sam9x60-spi", "atmel,at91rm9200-spi";
 					reg = <0x400 0x200>;
 					interrupts = <14 IRQ_TYPE_LEVEL_HIGH 7>;
+					#address-cells = <1>;
+					#size-cells = <0>;
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 14>;
 					clock-names = "spi_clk";
 					dmas = <&dma0
@@ -768,6 +772,8 @@ spi0: spi at 400 {
 					compatible = "microchip,sam9x60-spi", "atmel,at91rm9200-spi";
 					reg = <0x400 0x200>;
 					interrupts = <5 IRQ_TYPE_LEVEL_HIGH 7>;
+					#address-cells = <1>;
+					#size-cells = <0>;
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 5>;
 					clock-names = "spi_clk";
 					dmas = <&dma0
@@ -839,6 +845,8 @@ spi1: spi at 400 {
 					compatible = "microchip,sam9x60-spi", "atmel,at91rm9200-spi";
 					reg = <0x400 0x200>;
 					interrupts = <6 IRQ_TYPE_LEVEL_HIGH 7>;
+					#address-cells = <1>;
+					#size-cells = <0>;
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 6>;
 					clock-names = "spi_clk";
 					dmas = <&dma0
@@ -910,6 +918,8 @@ spi2: spi at 400 {
 					compatible = "microchip,sam9x60-spi", "atmel,at91rm9200-spi";
 					reg = <0x400 0x200>;
 					interrupts = <7 IRQ_TYPE_LEVEL_HIGH 7>;
+					#address-cells = <1>;
+					#size-cells = <0>;
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 7>;
 					clock-names = "spi_clk";
 					dmas = <&dma0
@@ -981,6 +991,8 @@ spi3: spi at 400 {
 					compatible = "microchip,sam9x60-spi", "atmel,at91rm9200-spi";
 					reg = <0x400 0x200>;
 					interrupts = <8 IRQ_TYPE_LEVEL_HIGH 7>;
+					#address-cells = <1>;
+					#size-cells = <0>;
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 8>;
 					clock-names = "spi_clk";
 					dmas = <&dma0
-- 
2.47.1



From krzk at kernel.org  Wed Dec 18 00:07:21 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 09:07:21 +0100
Subject: [PATCH v3 1/6] dt-bindings: interrupt-controller: Refine
 size/interrupt-cell usage.
In-Reply-To: <PSAPR06MB4949CF57BD69B2F7C1D141CD89052@PSAPR06MB4949.apcprd06.prod.outlook.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-3-kevin_chen@aspeedtech.com>
 <11ad5a97-b066-4bea-8829-50e0416cea9d@kernel.org>
 <PSAPR06MB4949CF57BD69B2F7C1D141CD89052@PSAPR06MB4949.apcprd06.prod.outlook.com>
Message-ID: <4ce799f1-e8c6-4a0d-aca5-dfb3dcb0c1d8@kernel.org>

On 18/12/2024 04:04, Kevin Chen wrote:
> Hi Krzk,
> 
>>> 1. Because size-cells is no need to use 2, modify to 1 for use.
>>
>> ???
> So, is it OK that I change the size-cells back to 2 include the aspeed,ast2700-intc.yaml examples and aspeed-g7.dtsi?

No, my total surprise is that I did not understand what it maens. Is
this changelog? Commit msg? Why such change is made?

> 
>>
>>> 2. Add minItems to 1 for interrupts for intc1.
>>
>> ???
> For variable interrupt numbers, I need to fix the below warnings by minItems.
>   DTC [C] arch/arm64/boot/dts/aspeed/ast2700-evb.dtb
> /home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 100: interrupts-extended: [[3, 0, 3844]] is too short
>         from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
> /home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 110: interrupts-extended: [[3, 1, 3844]] is too short
>         from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
> /home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 120: interrupts-extended: [[3, 2, 3844]] is too short
>         from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
> /home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 130: interrupts-extended: [[3, 3, 3844]] is too short
>         from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
> /home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 140: interrupts-extended: [[3, 4, 3844]] is too short
>         from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
> /home/kevin/linux-mainline/arch/arm64/boot/dts/aspeed/ast2700-evb.dtb: interrupt-controller at 150: interrupts-extended: [[3, 5, 3844]] is too short
>         from schema $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
> 
>>
>>> 3. Add 1 interrupt of intc1 example into yaml file.
>>
>>> 4. Add intc1 sub-module of uart12 as example using the intc0 and intc1.
>>
>> What is all this?
>>
>> BTW, there was no such patch in previous version and your changelog is silent
>> about it.
> Agree, I will restore the previous version.
> 
>>
>> Subject: drop all full stops. Subject never ends with full stop.
>>
>>> ---
>>>  .../aspeed,ast2700-intc.yaml                  | 60
>> +++++++++++++++----
>>>  1 file changed, 47 insertions(+), 13 deletions(-)
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast270
>>> 0-intc.yaml
>>> b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast270
>>> 0-intc.yaml index 55636d06a674..eadfbc45326b 100644
>>> ---
>>> a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast270
>>> 0-intc.yaml
>>> +++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,as
>>> +++ t2700-intc.yaml
>>> @@ -31,6 +31,7 @@ properties:
>>>        type as defined in interrupt.txt in this directory.
>>>
>>>    interrupts:
>>> +    minItems: 1
>>
>> Nope, not explained, not constrained. Your schema is supposed to be
>> constrained.

I still do not understand this commit at all.


Best regards,
Krzysztof


From krzk at kernel.org  Wed Dec 18 00:11:31 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 09:11:31 +0100
Subject: [PATCH v3 2/6] dt-bindings: arm: aspeed: Add ASPEED AST27XX SoC
In-Reply-To: <PSAPR06MB49495C182D0B64687E0174A389052@PSAPR06MB4949.apcprd06.prod.outlook.com>
References: <20241212155237.848336-1-kevin_chen@aspeedtech.com>
 <20241212155237.848336-4-kevin_chen@aspeedtech.com>
 <7289a50a-e139-453f-a512-3dd68a0839a2@kernel.org>
 <7b991fca-6e2f-454f-a94d-6a583854769b@kernel.org>
 <PSAPR06MB49495C182D0B64687E0174A389052@PSAPR06MB4949.apcprd06.prod.outlook.com>
Message-ID: <4717dbb3-4fea-4ca0-800e-07ceed4dfec0@kernel.org>

On 18/12/2024 03:55, Kevin Chen wrote:
> Hi Krzk,
> 
>>> On 12/12/2024 16:52, Kevin Chen wrote:
>>>> Signed-off-by: Kevin Chen <kevin_chen at aspeedtech.com>
>>>> ---
>>>>  Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 6 ++++++
>>>>  1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
>>>> b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
>>>> index 2f92b8ab08fa..20191fee1f5b 100644
>>>> --- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
>>>> +++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
>>>> @@ -101,4 +101,10 @@ properties:
>>>>                - ufispace,ncplite-bmc
>>>>            - const: aspeed,ast2600
>>>>
>>>> +      - description: AST2700 based boards
>>>> +        items:
>>>> +          - enum:
>>>> +              - aspeed,ast2700-evb
>>>> +          - const: aspeed,ast2700
>>>> +
>>>>  additionalProperties: true
>>>
>>>
>>>
>>> This patchset is just corrupted. You already sent it as patch #1.
>>>
>>> Please run scripts/checkpatch.pl and fix reported warnings. Then
>>> please run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
>>> Some warnings can be ignored, especially from --strict run, but the
>>> code here looks like it needs a fix. Feel free to get in touch if the
>>> warning is not clear.
>> BTW, you already got here same comments before and this is third time you
>> send exactly the same without implementing what we asked you.
> Please check the following message.
> https://lore.kernel.org/lkml/PSAPR06MB494943F3F34881D23CEEBD9A897D2 at PSAPR06MB4949.apcprd06.prod.outlook.com/
> 
> Or, how do you think what is better for me to add ast2700-evb?
Please stop responding just to make me go away.

Read the comments from half a year ago, which you have never implemented:

https://lore.kernel.org/lkml/e6cb6f26-fef2-49bc-ab25-fdc9a659f593 at kernel.org/

On every new patch I was asking you to go back, but again you were
ignoring each of such messages.

Best regards,
Krzysztof


From krzk at kernel.org  Wed Dec 18 00:20:59 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 09:20:59 +0100
Subject: [PATCH v3 07/33] dt-bindings: display: mediatek: Add binding for
 MT8195 HDMI-TX v2
In-Reply-To: <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
 <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>
Message-ID: <rsnyljmkdf7i74bkrlf5nesp2sa3n6xcnzsqao4znmczjpfyq2@dsakz56s4ypt>

On Tue, Dec 17, 2024 at 04:43:19PM +0100, AngeloGioacchino Del Regno wrote:
> +  i2c:
> +    type: object
> +    $ref: /schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
> +    unevaluatedProperties: false
> +    description: HDMI DDC I2C controller
> +
> +  phys:
> +    maxItems: 1
> +    description: PHY providing clocking TMDS and pixel to controller
> +
> +  phy-names:
> +    items:
> +      - const: hdmi
> +
> +  pinctrl-0: true
> +
> +  pinctrl-names:
> +    items:
> +      - const: default

Drop both pinctrl entries.

> +
> +  power-domains:
> +    maxItems: 1
> +
> +  '#sound-dai-cells':
> +    const: 1
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Input port, usually connected to the output port of a DPI
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Output port that must be connected either to the input port of
> +          a HDMI connector node containing a ddc-i2c-bus, or to the input
> +          port of an attached bridge chip, such as a SlimPort transmitter.
> +
> +    required:
> +      - port at 0
> +      - port at 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names

Please keep the same order of things here and in main properties
section.

> +  - interrupts
> +  - power-domains
> +  - phys
> +  - phy-names
> +  - ports
> +

You need allOf: with ref to dai-common.yaml.

> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt8195-clk.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        hdmi-tx at 1c300000 {

hdmi@

Best regards,
Krzysztof



From 0x1207 at gmail.com  Wed Dec 18 00:34:07 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Wed, 18 Dec 2024 16:34:07 +0800
Subject: [PATCH net-next v1] net: stmmac: Drop useless code related to ethtool rx-copybreak
Message-ID: <20241218083407.390509-1-0x1207@gmail.com>

After commit 2af6106ae949 ("net: stmmac: Introducing support for Page
Pool"), the driver always copies frames to get a better performance,
zero-copy for RX frames is no more, then these code turned to be
useless and users of ethtool may get confused about the unhandled
rx-copybreak parameter.

This patch mostly reverts
commit 22ad38381547 ("stmmac: do not perform zero-copy for rx frames")

Signed-off-by: Furong Xu <0x1207 at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  2 -
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 39 -------------------
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  5 ---
 3 files changed, 46 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 1d86439b8a14..b8d631e559c0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -126,7 +126,6 @@ struct stmmac_rx_queue {
 	unsigned int cur_rx;
 	unsigned int dirty_rx;
 	unsigned int buf_alloc_num;
-	u32 rx_zeroc_thresh;
 	dma_addr_t dma_rx_phy;
 	u32 rx_tail_addr;
 	unsigned int state_saved;
@@ -266,7 +265,6 @@ struct stmmac_priv {
 	int sph_cap;
 	u32 sarc_type;
 
-	unsigned int rx_copybreak;
 	u32 rx_riwt[MTL_MAX_TX_QUEUES];
 	int hwts_rx_en;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 1d77389ce953..16b4d8c21c90 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -1227,43 +1227,6 @@ static int stmmac_get_ts_info(struct net_device *dev,
 		return ethtool_op_get_ts_info(dev, info);
 }
 
-static int stmmac_get_tunable(struct net_device *dev,
-			      const struct ethtool_tunable *tuna, void *data)
-{
-	struct stmmac_priv *priv = netdev_priv(dev);
-	int ret = 0;
-
-	switch (tuna->id) {
-	case ETHTOOL_RX_COPYBREAK:
-		*(u32 *)data = priv->rx_copybreak;
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static int stmmac_set_tunable(struct net_device *dev,
-			      const struct ethtool_tunable *tuna,
-			      const void *data)
-{
-	struct stmmac_priv *priv = netdev_priv(dev);
-	int ret = 0;
-
-	switch (tuna->id) {
-	case ETHTOOL_RX_COPYBREAK:
-		priv->rx_copybreak = *(u32 *)data;
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
 static int stmmac_get_mm(struct net_device *ndev,
 			 struct ethtool_mm_state *state)
 {
@@ -1390,8 +1353,6 @@ static const struct ethtool_ops stmmac_ethtool_ops = {
 	.set_per_queue_coalesce = stmmac_set_per_queue_coalesce,
 	.get_channels = stmmac_get_channels,
 	.set_channels = stmmac_set_channels,
-	.get_tunable = stmmac_get_tunable,
-	.set_tunable = stmmac_set_tunable,
 	.get_link_ksettings = stmmac_ethtool_get_link_ksettings,
 	.set_link_ksettings = stmmac_ethtool_set_link_ksettings,
 	.get_mm = stmmac_get_mm,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 16b8bcfa8b11..6bc10ffe7a2b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -77,7 +77,6 @@ module_param(phyaddr, int, 0444);
 MODULE_PARM_DESC(phyaddr, "Physical device address");
 
 #define STMMAC_TX_THRESH(x)	((x)->dma_conf.dma_tx_size / 4)
-#define STMMAC_RX_THRESH(x)	((x)->dma_conf.dma_rx_size / 4)
 
 /* Limit to make sure XDP TX and slow path can coexist */
 #define STMMAC_XSK_TX_BUDGET_MAX	256
@@ -107,8 +106,6 @@ static int buf_sz = DEFAULT_BUFSIZE;
 module_param(buf_sz, int, 0644);
 MODULE_PARM_DESC(buf_sz, "DMA buffer size");
 
-#define	STMMAC_RX_COPYBREAK	256
-
 static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
 				      NETIF_MSG_LINK | NETIF_MSG_IFUP |
 				      NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
@@ -3927,8 +3924,6 @@ static int __stmmac_open(struct net_device *dev,
 		}
 	}
 
-	priv->rx_copybreak = STMMAC_RX_COPYBREAK;
-
 	buf_sz = dma_conf->dma_buf_sz;
 	for (int i = 0; i < MTL_MAX_TX_QUEUES; i++)
 		if (priv->dma_conf.tx_queue[i].tbs & STMMAC_TBS_EN)
-- 
2.34.1



From xianwei.zhao at amlogic.com  Wed Dec 18 00:47:10 2024
From: xianwei.zhao at amlogic.com (Xianwei Zhao)
Date: Wed, 18 Dec 2024 16:47:10 +0800
Subject: [PATCH RFC 1/3] dt-bindings: pinctrl: Add support for Amlogic
 SoCs
In-Reply-To: <20241217142028.GA1441221-robh@kernel.org>
References: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
 <20241211-amlogic-pinctrl-v1-1-410727335119@amlogic.com>
 <20241217142028.GA1441221-robh@kernel.org>
Message-ID: <6185966d-ad60-48e3-b4a2-3808f3b53b3c@amlogic.com>

Hi Rob,
    Thanks for your reply.

On 2024/12/17 22:20, Rob Herring wrote:
> [ EXTERNAL EMAIL ]
> 
> On Wed, Dec 11, 2024 at 02:47:49PM +0800, Xianwei Zhao wrote:
>> Add the dt-bindings for Amlogic pin controller, and add a new
>> dt-binding header file which document the GPIO bank names and
>> alternative func value of all Amlogic subsequent SoCs.
>>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
>> ---
>>   .../bindings/pinctrl/amlogic,pinctrl.yaml          | 150 +++++++++++++++++++++
>>   include/dt-bindings/pinctrl/amlogic,pinctrl.h      |  68 ++++++++++
>>   2 files changed, 218 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pinctrl/amlogic,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/amlogic,pinctrl.yaml
>> new file mode 100644
>> index 000000000000..b0c2ae585d7d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pinctrl/amlogic,pinctrl.yaml
>> @@ -0,0 +1,150 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/pinctrl/amlogic,pinctrl.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Amlogic pinmux controller
>> +
>> +maintainers:
>> +  - Xianwei Zhao <xianwei.zhao at amlogic.com>
>> +
>> +allOf:
>> +  - $ref: pinctrl.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    const: amlogic,pinctrl
> 
> Only one Amlogic pinctrl block? Pretty sure there's more than 1 SoC and
> pinctrl is unlikely identical for all. This must be SoC specific.
>

Will do, "amlogic,pinctrl" -> "amlogic,pinctrl-a4".

>> +
>> +  reg:
>> +    minItems: 2
>> +
>> +  reg-names:
>> +    items:
>> +      - const: mux
>> +      - const: gpio
>> +
>> +  "#address-cells":
>> +    const: 2
>> +
>> +  "#size-cells":
>> +    const: 2
> 
> Why do you need these? You don't have any child nodes with addresses.
> But maybe you should?
> 

I will modify "reg_mux_offset" to "reg", So
#address-cells = <1>
#size-cells = <0>

>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - reg-names
>> +  - "#address-cells"
>> +  - "#size-cells"
>> +
>> +patternProperties:
>> +  "^gpio[a-z]":
> 
> This allows "gpioanythingyouwant" for example. If there is no
> unit-address, then it should be '^gpio-[0-9]+$'.
> 

Will do.

>> +    type: object
>> +
>> +    properties:
>> +      gpio-controller: true
>> +
>> +      "#gpio-cells":
>> +        const: 2
>> +
>> +      bank-name:
>> +        $ref: /schemas/types.yaml#/definitions/string
> 
> You must define values, but why do you need this? No other GPIO
> controller needs something like this.
> 

We define the bank name(GPIOA,GPIOB) on the chip specification, so it is 
more readable to describe the source code with such a name in the 
pin(GPIOA-0,GPIOA-1).

Bank indexes are defined primarily for use in pinmux implicit queries.

Bank-name and bank-index, they both describe the characteristics of the 
Bank, they just use it differently. I can keep bank-index, I can query 
the bank-name through bank-index.

I will delete this property, keep bank-index property.

>> +
>> +      npins:
> 
> We have a standard property for this: ngpios
> 

Will do.

>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        minimum: 1
>> +        maximum: 32
>> +
>> +      bank-index:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        minimum: 0
>> +        maximum: 29
> 
> Consider if 'bank' should be part of the gpio cells rather than
> separate controller nodes. That works better if each bank is not its own
> separate h/w block. If banks share a register, then that's not separate
> blocks.
>

Each bank is its own separate h/w block(With TEST_N bank exception,it 
share mux reg with AO bank).

Change the name of this property to "bank-identity" make it more 
appropriate.

>> +
>> +      reg-mux-offset:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +
>> +      bit-mux-offset:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +
>> +      reg-gpio-offset:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
> 
> Put these into 'reg'. We even have a way to deal with bit offsets. See
> leds/register-bit-led.yaml for example.
> 

Will do.

>  >> +
>> +    required:
>> +      - gpio-controller
>> +      - "#gpio-cells"
>> +      - npins
>> +      - bank-index
>> +      - reg-mux-offset
>> +      - reg-gpio-offset
>> +      - bank-name
>> +
>> +    additionalProperties: false
>> +    unevaluatedProperties: false
> 
> Don't need both. 'additionalProperties' is more restrictive, so drop
> unevaluatedProperties.
> 
Will drop  unevaluatedProperties.

>> +
>> +  "^func-[0-9a-z]":
> 
> "^func-[0-9a-z-]+$"
> 
Will do.

>> +    type: object
>> +    additionalProperties:
>> +      type: object
>> +      allOf:
>> +        - $ref: pincfg-node.yaml#
>> +        - $ref: pinmux-node.yaml#
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    apb {
>> +      #address-cells = <2>;
>> +      #size-cells = <2>;
>> +      periphs_pinctrl: pinctrl at 8e700 {
>> +        compatible = "amlogic,pinctrl";
>> +        #address-cells = <2>;
>> +        #size-cells = <2>;
>> +        reg = <0x0 0x8e700 0x0 0x04>,
>> +              <0x0 0x8e704 0x0 0x60>;
>> +        reg-names = "mux", "gpio";
>> +
>> +        gpiob {
>> +          gpio-controller;
>> +          #gpio-cells = <2>;
>> +          npins = <10>;
>> +          bank-index = <1>;
>> +          reg-mux-offset = <0x14>;
>> +          bit-mux-offset = <0x14>;
>> +          reg-gpio-offset = <0x30>;
>> +          bank-name = "GPIOB";
>> +        };
>> +
>> +        gpioe {
>> +          gpio-controller;
>> +          #gpio-cells = <2>;
>> +          npins = <10>;
>> +          bank-index = <5>;
>> +          reg-mux-offset = <0x14>;
>> +          reg-gpio-offset = <0x30>;
>> +          bank-name = "GPIOE";
>> +        };
>> +
>> +        func-uart-b {
>> +          uart-b-default{
>> +            pinmux = <3>;
>> +            bias-pull-up;
>> +            drive-strength-microamp = <4000>;
>> +          };
>> +
>> +          uart-c-default{
>> +            pinmux = <4>;
>> +            bias-pull-up;
>> +            drive-strength-microamp = <4000>;
>> +          };
>> +        };
>> +
>> +        func-uart-c {
>> +          uart-c-default{
>> +            pinmux = <3>;
>> +            bias-pull-up;
>> +            drive-strength-microamp = <4000>;
>> +          };
>> +        };
>> +      };
>> +    };
>> diff --git a/include/dt-bindings/pinctrl/amlogic,pinctrl.h b/include/dt-bindings/pinctrl/amlogic,pinctrl.h
>> new file mode 100644
>> index 000000000000..03db0a730e8b
>> --- /dev/null
>> +++ b/include/dt-bindings/pinctrl/amlogic,pinctrl.h
>> @@ -0,0 +1,68 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>> +/*
>> + * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
>> + * Author: Xianwei Zhao <xianwei.zhao at amlogic.com>
>> + */
>> +
>> +#ifndef _DT_BINDINGS_AMLOGIC_PINCTRL_H
>> +#define _DT_BINDINGS_AMLOGIC_PINCTRL_H
>> +
>> +/* define PIN modes */
>> +#define AF0  0x0
>> +#define AF1  0x1
>> +#define AF2  0x2
>> +#define AF3  0x3
>> +#define AF4  0x4
>> +#define AF5  0x5
>> +#define AF6  0x6
>> +#define AF7  0x7
>> +#define AF8  0x8
>> +#define AF9  0x9
>> +#define AF10 0xa
>> +#define AF11 0xb
>> +#define AF12 0xc
>> +#define AF13 0xd
>> +#define AF14 0xe
>> +#define AF15 0xf
>> +
>> +#define AML_PIN_ALT_FUNC_MASK        0xf
>> +
>> +/* Normal PIN bank */
>> +#define AMLOGIC_GPIO_A               0
>> +#define AMLOGIC_GPIO_B               1
>> +#define AMLOGIC_GPIO_C               2
>> +#define AMLOGIC_GPIO_D               3
>> +#define AMLOGIC_GPIO_E               4
>> +#define AMLOGIC_GPIO_F               5
>> +#define AMLOGIC_GPIO_G               6
>> +#define AMLOGIC_GPIO_H               7
>> +#define AMLOGIC_GPIO_I               8
>> +#define AMLOGIC_GPIO_J               9
>> +#define AMLOGIC_GPIO_K               10
>> +#define AMLOGIC_GPIO_L               11
>> +#define AMLOGIC_GPIO_M               12
>> +#define AMLOGIC_GPIO_N               13
>> +#define AMLOGIC_GPIO_O               14
>> +#define AMLOGIC_GPIO_P               15
>> +#define AMLOGIC_GPIO_Q               16
>> +#define AMLOGIC_GPIO_R               17
>> +#define AMLOGIC_GPIO_S               18
>> +#define AMLOGIC_GPIO_T               19
>> +#define AMLOGIC_GPIO_U               20
>> +#define AMLOGIC_GPIO_V               21
>> +#define AMLOGIC_GPIO_W               22
>> +#define AMLOGIC_GPIO_X               23
>> +#define AMLOGIC_GPIO_Y               24
>> +#define AMLOGIC_GPIO_Z               25
>> +
>> +/* Special PIN bank */
>> +#define AMLOGIC_GPIO_DV              26
>> +#define AMLOGIC_GPIO_AO              27
>> +#define AMLOGIC_GPIO_CC              28
>> +#define AMLOGIC_GPIO_TEST_N  29
>> +
>> +#define AML_PINMUX(bank, offset, mode)       (((((bank) << 8) + (offset)) << 8) | (mode))
>> +#define AML_PINMUX_TO_BANK(pinmux)   (((pinmux) >> 16) & 0xff)
>> +#define AML_PINMUX_TO_OFFSET(pinmux) (((pinmux) >> 8) & 0xff)
>> +
>> +#endif /* _DT_BINDINGS_AMLOGIC_PINCTRL_H */
>>
>> --
>> 2.37.1
>>


From christian.bruel at foss.st.com  Wed Dec 18 00:42:45 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 18 Dec 2024 09:42:45 +0100
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <20241217172502.borj2oy4rpxcteag@thinkpad>
References: <20241205172022.GA3053765@bhelgaas>
 <d976d74c-80c0-4446-bb9b-960a990c552b@foss.st.com>
 <20241217172502.borj2oy4rpxcteag@thinkpad>
Message-ID: <5b835381-55bc-4fc8-b848-535f6e881420@foss.st.com>



On 12/17/24 18:25, Manivannan Sadhasivam wrote:
> On Tue, Dec 17, 2024 at 04:53:48PM +0100, Christian Bruel wrote:
>>
>>> Makes sense.  What about phys, resets, etc?  I'm pretty sure a PHY
>>> would be a per-Root Port thing, and some resets and wakeup signals
>>> also.
>>>
>>> For new drivers, I think we should start adding Root Port stanzas to
>>> specifically associate those things with the Root Port, e.g.,
>>> something like this?
>>>
>>>     pcie at 48400000 {
>>>       compatible = "st,stm32mp25-pcie-rc";
>>>
>>>       pcie at 0,0 {
>>>         reg = <0x0000 0 0 0 0>;
>>>         phys = <&combophy PHY_TYPE_PCIE>;
>>>         phy-names = "pcie-phy";
>>>       };
>>>     };
>>>
>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pci/mediatek,mt7621-pcie.yaml?id=v6.12#n111
>>> is one binding that does this, others include apple,pcie.yaml,
>>> brcm,stb-pcie.yaml, hisilicon,kirin-pcie.yaml.
>>>
>>
>> On a second thought, moving the PHY to the root-port part would introduce a
>> discrepancy with the pcie_ep binding, whereas the PHY is required on the
>> pcie_ep node.
>>
>> Even for the pcie_rc, the PHY is needed to enable the core_clk to access
>> the PCIe core registers,
>>
> 
> But why that matters? You can still parse the child nodes, enable PHY and
> configure PCIe registers. >
>> So that would make 2 different required PHY locations for RC and EP:
>>
>>      pcie_rc: pcie at 48400000 {
>>        compatible = "st,stm32mp25-pcie-rc";
>>
>>        pcie at 0,0 {
>>          reg = <0x0000 0 0 0 0>;
>>          phys = <&combophy PHY_TYPE_PCIE>;
>>          phy-names = "pcie-phy";
>>        };
>>      };
>>
>>      pcie_ep pcie at 48400000 {
>>        compatible = "st,stm32mp25-pcie-ep";
>>        phys = <&combophy PHY_TYPE_PCIE>;
>>        phy-names = "pcie-phy";
>>      };
>>
>> Simplest seems to keep the PHY required for the pcie core regardless of the
>> mode and keep the empty root port to split the design
>>
> 
> No please. Try to do the right thing from the start itself.

Parsing the child node to clock the IP seems weird. Note that 
hisilicon,kirin-pcie.yaml also declares the PHY at the controller level.

thanks

Christian




> 
> - Mani
> 


From yeoreum.yun at arm.com  Wed Dec 18 00:48:33 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Wed, 18 Dec 2024 08:48:33 +0000
Subject: [PATCH 1/1] coresight: prevent deactivate active config while enable the config
Message-ID: <20241218084833.609876-1-yeoreum.yun@arm.com>

While enable active config via cscfg_csdev_enable_active_config(),
active config could be deactivated via configfs' sysfs interface.
This could make UAF issue in below scenario:

CPU0                                          CPU1
(perf or sysfs enable)                        load module
                                              cscfg_load_config_sets()
                                              activate config. // sysfs
                                              (sys_active_cnt == 1)
...
cscfg_csdev_enable_active_config()
  lock(csdev->cscfg_csdev_lock)
  // here load config activate by CPU1
  unlock(csdev->cscfg_csdev_lock)

                                              deactivate config // sysfs
                                              (sys_activec_cnt == 0)
                                              cscfg_unload_config_sets()
                                              unload module

  // access to config_desc which freed
  // while unloading module.
  cfs_csdev_enable_config

To address this, introduce sys_enable_cnt in cscfg_mgr to prevent
deactivate while there is enabled configuration.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-etm4x-core.c |  3 +++
 drivers/hwtracing/coresight/coresight-syscfg.c | 18 ++++++++++++++++--
 drivers/hwtracing/coresight/coresight-syscfg.h |  2 ++
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 86893115df17..6218ef40acbc 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -986,6 +986,9 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
 
 	raw_spin_unlock(&drvdata->spinlock);
+
+	cscfg_csdev_disable_active_config(csdev);
+
 	cpus_read_unlock();
 
 	/*
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index a70c1454b410..dfa7dcbaf25d 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -953,7 +953,8 @@ int cscfg_config_sysfs_activate(struct cscfg_config_desc *config_desc, bool acti
 			cscfg_mgr->sysfs_active_config = cfg_hash;
 	} else {
 		/* disable if matching current value */
-		if (cscfg_mgr->sysfs_active_config == cfg_hash) {
+		if (cscfg_mgr->sysfs_active_config == cfg_hash &&
+		    !atomic_read(&cscfg_mgr->sys_enable_cnt)) {
 			_cscfg_deactivate_config(cfg_hash);
 			cscfg_mgr->sysfs_active_config = 0;
 		} else
@@ -1055,6 +1056,12 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 	if (!atomic_read(&cscfg_mgr->sys_active_cnt))
 		return 0;
 
+	/*
+	 * increment sys_enable_cnt first to prevent deactivate the config
+	 * while enable active config.
+	 */
+	atomic_inc(&cscfg_mgr->sys_enable_cnt);
+
 	/*
 	 * Look for matching configuration - set the active configuration
 	 * context if found.
@@ -1098,6 +1105,10 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 			raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 		}
 	}
+
+	if (!config_csdev_active || err)
+		atomic_dec(&cscfg_mgr->sys_enable_cnt);
+
 	return err;
 }
 EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);
@@ -1129,8 +1140,10 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
 	if (config_csdev) {
 		if (!config_csdev->enabled)
 			config_csdev = NULL;
-		else
+		else {
 			config_csdev->enabled = false;
+			atomic_dec(&cscfg_mgr->sys_enable_cnt);
+		}
 	}
 	csdev->active_cscfg_ctxt = NULL;
 	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
@@ -1179,6 +1192,7 @@ static int cscfg_create_device(void)
 	INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
 	INIT_LIST_HEAD(&cscfg_mgr->load_order_list);
 	atomic_set(&cscfg_mgr->sys_active_cnt, 0);
+	atomic_set(&cscfg_mgr->sys_enable_cnt, 0);
 	cscfg_mgr->load_state = CSCFG_NONE;
 
 	/* setup the device */
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
index 66e2db890d82..2fc397919985 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.h
+++ b/drivers/hwtracing/coresight/coresight-syscfg.h
@@ -38,6 +38,7 @@ enum cscfg_load_ops {
  * @config_desc_list:	List of system configuration descriptors to load into registered devices.
  * @load_order_list:    Ordered list of owners for dynamically loaded configurations.
  * @sys_active_cnt:	Total number of active config descriptor references.
+ * @sys_enable_cnt:	Total number of enable of active config descriptor references.
  * @cfgfs_subsys:	configfs subsystem used to manage configurations.
  * @sysfs_active_config:Active config hash used if CoreSight controlled from sysfs.
  * @sysfs_active_preset:Active preset index used if CoreSight controlled from sysfs.
@@ -50,6 +51,7 @@ struct cscfg_manager {
 	struct list_head config_desc_list;
 	struct list_head load_order_list;
 	atomic_t sys_active_cnt;
+	atomic_t sys_enable_cnt;
 	struct configfs_subsystem cfgfs_subsys;
 	u32 sysfs_active_config;
 	int sysfs_active_preset;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From arnd at kernel.org  Wed Dec 18 00:58:31 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Dec 2024 09:58:31 +0100
Subject: [PATCH] drm/mediatek: stop selecting foreign drivers
Message-ID: <20241218085837.2670434-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

The PHY portion of the mediatek hdmi driver was originally part of
the driver it self and later split out into drivers/phy, which a
'select' to keep the prior behavior.

However, this leads to build failures when the PHY driver cannot
be built:

WARNING: unmet direct dependencies detected for PHY_MTK_HDMI
  Depends on [n]: (ARCH_MEDIATEK || COMPILE_TEST [=y]) && COMMON_CLK [=y] && OF [=y] && REGULATOR [=n]
  Selected by [m]:
  - DRM_MEDIATEK_HDMI [=m] && HAS_IOMEM [=y] && DRM [=m] && DRM_MEDIATEK [=m]
ERROR: modpost: "devm_regulator_register" [drivers/phy/mediatek/phy-mtk-hdmi-drv.ko] undefined!
ERROR: modpost: "rdev_get_drvdata" [drivers/phy/mediatek/phy-mtk-hdmi-drv.ko] undefined!

The best option here is to just not select the phy driver and leave that
up to the defconfig. Do the same for the other PHY and memory drivers
selected here as well for consistency.

Fixes: a481bf2f0ca4 ("drm/mediatek: Separate mtk_hdmi_phy to an independent module")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/gpu/drm/mediatek/Kconfig | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index 1c2f56b75716..1d4f20a4f265 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -15,9 +15,6 @@ config DRM_MEDIATEK
 	select DRM_BRIDGE_CONNECTOR
 	select DRM_MIPI_DSI
 	select DRM_PANEL
-	select MEMORY
-	select MTK_SMI
-	select PHY_MTK_MIPI_DSI
 	select VIDEOMODE_HELPERS
 	help
 	  Choose this option if you have a Mediatek SoCs.
@@ -28,7 +25,6 @@ config DRM_MEDIATEK
 config DRM_MEDIATEK_DP
 	tristate "DRM DPTX Support for MediaTek SoCs"
 	depends on DRM_MEDIATEK
-	select PHY_MTK_DP
 	select DRM_DISPLAY_HELPER
 	select DRM_DISPLAY_DP_HELPER
 	select DRM_DISPLAY_DP_AUX_BUS
@@ -39,6 +35,5 @@ config DRM_MEDIATEK_HDMI
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
 	select SND_SOC_HDMI_CODEC if SND_SOC
-	select PHY_MTK_HDMI
 	help
 	  DRM/KMS HDMI driver for Mediatek SoCs
-- 
2.39.5



From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:48 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:48 +0100
Subject: [PATCH 4/9] counter: stm32-timer-cnt: add support for stm32mp25
In-Reply-To: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241218090153.742869-5-fabrice.gasnier@foss.st.com>

Add support for STM32MP25 SoC. There are new counter modes that may be
implemented in later. Still, use newly introduced compatible to handle
this new HW variant and avoid being blocked with existing compatible
in SoC dtsi file. Modes supported currently still remains compatible.
New timer 20 has encoder capability, add it to the list.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 drivers/counter/stm32-timer-cnt.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
index e75b69476a00..3d3384cbea87 100644
--- a/drivers/counter/stm32-timer-cnt.c
+++ b/drivers/counter/stm32-timer-cnt.c
@@ -669,12 +669,14 @@ static void stm32_timer_cnt_detect_channels(struct device *dev,
 	dev_dbg(dev, "has %d cc channels\n", priv->nchannels);
 }
 
-/* encoder supported on TIM1 TIM2 TIM3 TIM4 TIM5 TIM8 */
-#define STM32_TIM_ENCODER_SUPPORTED	(BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(7))
+/* encoder supported on TIM1 TIM2 TIM3 TIM4 TIM5 TIM8 TIM20 */
+#define STM32_TIM_ENCODER_SUPPORTED	(BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(7) | \
+					 BIT(19))
 
 static const char * const stm32_timer_trigger_compat[] = {
 	"st,stm32-timer-trigger",
 	"st,stm32h7-timer-trigger",
+	"st,stm32mp25-timer-trigger",
 };
 
 static int stm32_timer_cnt_probe_encoder(struct device *dev,
@@ -846,6 +848,7 @@ static SIMPLE_DEV_PM_OPS(stm32_timer_cnt_pm_ops, stm32_timer_cnt_suspend,
 
 static const struct of_device_id stm32_timer_cnt_of_match[] = {
 	{ .compatible = "st,stm32-timer-counter", },
+	{ .compatible = "st,stm32mp25-timer-counter", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, stm32_timer_cnt_of_match);
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:51 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:51 +0100
Subject: [PATCH 7/9] arm64: dts: st: add timer nodes on stm32mp251
In-Reply-To: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241218090153.742869-8-fabrice.gasnier@foss.st.com>

Add timers support on STM32MP25 SoC. Use dedicated compatible to handle
new features and instances introduced with this SoC. STM32MP25 SoC has
various timer flavours, each group has its own specific feature list:
- Advanced-control timers (TIM1/TIM8/TIM20)
- General-purpose timers (TIM2/TIM3/TIM4/TIM5)
- Basic timers (TIM6/TIM7)
- General-purpose timers (TIM10/TIM11/TIM12/TIM13/TIM14)
- General purpose timers (TIM15/TIM16/TIM17)

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 524 +++++++++++++++++++++++++
 1 file changed, 524 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 6fe12e3bd7dd..220fb1a3da71 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -237,6 +237,273 @@ rifsc: bus at 42080000 {
 			#access-controller-cells = <1>;
 			ranges;
 
+			timers2: timer at 40000000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40000000 0x400>;
+				interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM2>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 1>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 1 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <1>;
+					status = "disabled";
+				};
+			};
+
+			timers3: timer at 40010000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40010000 0x400>;
+				interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM3>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 2>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 2 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <2>;
+					status = "disabled";
+				};
+			};
+
+			timers4: timer at 40020000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40020000 0x400>;
+				interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM4>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 3>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 3 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <3>;
+					status = "disabled";
+				};
+			};
+
+			timers5: timer at 40030000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40030000 0x400>;
+				interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM5>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 4>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 4 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+
+			timers6: timer at 40040000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40040000 0x400>;
+				interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM6>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 5>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				timer at 5 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <5>;
+					status = "disabled";
+				};
+			};
+
+			timers7: timer at 40050000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40050000 0x400>;
+				interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM7>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 6>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				timer at 6 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <6>;
+					status = "disabled";
+				};
+			};
+
+			timers12: timer at 40060000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40060000 0x400>;
+				interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM12>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 10>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 11 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <11>;
+					status = "disabled";
+				};
+			};
+
+			timers13: timer at 40070000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40070000 0x400>;
+				interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM13>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 11>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 12 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <12>;
+					status = "disabled";
+				};
+			};
+
+			timers14: timer at 40080000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40080000 0x400>;
+				interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM14>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 12>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 13 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <13>;
+					status = "disabled";
+				};
+			};
+
 			spi2: spi at 400b0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -427,6 +694,136 @@ i2c7: i2c at 40180000 {
 				status = "disabled";
 			};
 
+			timers10: timer at 401c0000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x401c0000 0x400>;
+				interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM10>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 8>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 9 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <9>;
+					status = "disabled";
+				};
+			};
+
+			timers11: timer at 401d0000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x401d0000 0x400>;
+				interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM11>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 9>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 10 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <10>;
+					status = "disabled";
+				};
+			};
+
+			timers1: timer at 40200000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40200000 0x400>;
+				interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "brk", "up", "trg-com", "cc";
+				clocks = <&rcc CK_KER_TIM1>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 0>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 0 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <0>;
+					status = "disabled";
+				};
+			};
+
+			timers8: timer at 40210000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40210000 0x400>;
+				interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "brk", "up", "trg-com", "cc";
+				clocks = <&rcc CK_KER_TIM8>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 7>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 7 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <7>;
+					status = "disabled";
+				};
+			};
+
 			usart6: serial at 40220000 {
 				compatible = "st,stm32h7-uart";
 				reg = <0x40220000 0x400>;
@@ -469,6 +866,99 @@ spi4: spi at 40240000 {
 				status = "disabled";
 			};
 
+			timers15: timer at 40250000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40250000 0x400>;
+				interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM15>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 13>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 14 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <14>;
+					status = "disabled";
+				};
+			};
+
+			timers16: timer at 40260000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40260000 0x400>;
+				interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM16>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 14>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 15 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <15>;
+					status = "disabled";
+				};
+			};
+
+			timers17: timer at 40270000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40270000 0x400>;
+				interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM17>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 15>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 16 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <16>;
+					status = "disabled";
+				};
+			};
+
 			spi5: spi at 40280000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -496,6 +986,40 @@ uart9: serial at 402c0000 {
 				status = "disabled";
 			};
 
+			timers20: timer at 40320000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40320000 0x400>;
+				interrupts = <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>;
+				interrupt-names = "brk", "up", "trg-com", "cc";
+				clocks = <&rcc CK_KER_TIM20>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 16>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 19 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <19>;
+					status = "disabled";
+				};
+			};
+
 			usart1: serial at 40330000 {
 				compatible = "st,stm32h7-uart";
 				reg = <0x40330000 0x400>;
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:53 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:53 +0100
Subject: [PATCH 9/9] arm64: dts: st: add timer nodes on stm32mp257f-ev1
In-Reply-To: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241218090153.742869-10-fabrice.gasnier@foss.st.com>

Configure timer nodes on stm32mp257f-ev1:
- Timer3 CH2 is available on mikroBUS connector for PWM
- timer8 CH1, timer8 CH4, timer10 CH1 and timer12 CH2 are available
  on EXPANSION connector.
Timers are kept disabled by default, so the pins can be used for any
other purpose (and the timers can be assigned to any of the processors).
Arbitrary choice is to use all these timers as PWM (or counter on
internal clock signal), except for timer10 that is configured with
CH1 as an input (for capture).

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 58 ++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index 6f393b082789..6601ca411006 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -156,6 +156,64 @@ &spi8 {
 	status = "disabled";
 };
 
+&timers3 {
+	status = "disabled";
+	counter {
+		status = "okay";
+	};
+	pwm {
+		pinctrl-0 = <&pwm3_pins_a>;
+		pinctrl-1 = <&pwm3_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer at 2 {
+		status = "okay";
+	};
+};
+
+&timers8 {
+	status = "disabled";
+	counter {
+		status = "okay";
+	};
+	pwm {
+		pinctrl-0 = <&pwm8_pins_a>;
+		pinctrl-1 = <&pwm8_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer at 7 {
+		status = "okay";
+	};
+};
+
+&timers10 {
+	status = "disabled";
+	counter {
+		pinctrl-0 = <&tim10_counter_pins_a>;
+		pinctrl-1 = <&tim10_counter_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+};
+
+&timers12 {
+	status = "disabled";
+	counter {
+		status = "okay";
+	};
+	pwm {
+		pinctrl-0 = <&pwm12_pins_a>;
+		pinctrl-1 = <&pwm12_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer at 11 {
+		status = "okay";
+	};
+};
+
 &usart2 {
 	pinctrl-names = "default", "idle", "sleep";
 	pinctrl-0 = <&usart2_pins_a>;
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:52 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:52 +0100
Subject: [PATCH 8/9] arm64: dts: st: add timer pins for stm32mp257f-ev1
In-Reply-To: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241218090153.742869-9-fabrice.gasnier@foss.st.com>

Add timer pins available on stm32mp257f-ev1, configured for PWM:
- timer3 CH2 is available on mikroBUS connector
- timer8 CH1, timer8 CH4, timer10 CH1 and timer12 CH2 are available
  on EXPANSION connector
Arbitrary define all these pins to be used as PWM (output) channels,
except for timer10 CH1, to be used as counter input.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
index 8fdd5f020425..bb9dc82d3dd5 100644
--- a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
@@ -82,6 +82,53 @@ pins {
 		};
 	};
 
+	pwm3_pins_a: pwm3-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 15, AF7)>; /* TIM3_CH2 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm3_sleep_pins_a: pwm3-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 15, ANALOG)>; /* TIM3_CH2 */
+		};
+	};
+
+	pwm8_pins_a: pwm8-0 {
+		pins {
+			pinmux = <STM32_PINMUX('J', 5, AF8)>, /* TIM8_CH1 */
+				 <STM32_PINMUX('J', 4, AF8)>; /* TIM8_CH4 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm8_sleep_pins_a: pwm8-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('J', 5, ANALOG)>, /* TIM8_CH1 */
+				 <STM32_PINMUX('J', 4, ANALOG)>; /* TIM8_CH4 */
+		};
+	};
+
+	pwm12_pins_a: pwm12-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 11, AF9)>; /* TIM12_CH2 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm12_sleep_pins_a: pwm12-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 11, ANALOG)>; /* TIM12_CH2 */
+		};
+	};
+
 	sdmmc1_b4_pins_a: sdmmc1-b4-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
@@ -158,6 +205,20 @@ pins1 {
 		};
 	};
 
+	tim10_counter_pins_a: tim10-counter-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 9, AF9)>; /* TIM10_CH1 */
+			bias-disable;
+		};
+	};
+
+	tim10_counter_sleep_pins_a: tim10-counter-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 9, ANALOG)>; /* TIM10_CH1 */
+			bias-disable;
+		};
+	};
+
 	usart2_pins_a: usart2-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('A', 4, AF6)>; /* USART2_TX */
-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Wed Dec 18 01:06:41 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 18 Dec 2024 14:36:41 +0530
Subject: [PATCH v2 1/5] dt-bindings: PCI: Add STM32MP25 PCIe root complex
 bindings
In-Reply-To: <5b835381-55bc-4fc8-b848-535f6e881420@foss.st.com>
References: <20241205172022.GA3053765@bhelgaas>
 <d976d74c-80c0-4446-bb9b-960a990c552b@foss.st.com>
 <20241217172502.borj2oy4rpxcteag@thinkpad>
 <5b835381-55bc-4fc8-b848-535f6e881420@foss.st.com>
Message-ID: <20241218090641.dtn4niamg6gcvxml@thinkpad>

On Wed, Dec 18, 2024 at 09:42:45AM +0100, Christian Bruel wrote:
> 
> 
> On 12/17/24 18:25, Manivannan Sadhasivam wrote:
> > On Tue, Dec 17, 2024 at 04:53:48PM +0100, Christian Bruel wrote:
> > > 
> > > > Makes sense.  What about phys, resets, etc?  I'm pretty sure a PHY
> > > > would be a per-Root Port thing, and some resets and wakeup signals
> > > > also.
> > > > 
> > > > For new drivers, I think we should start adding Root Port stanzas to
> > > > specifically associate those things with the Root Port, e.g.,
> > > > something like this?
> > > > 
> > > >     pcie at 48400000 {
> > > >       compatible = "st,stm32mp25-pcie-rc";
> > > > 
> > > >       pcie at 0,0 {
> > > >         reg = <0x0000 0 0 0 0>;
> > > >         phys = <&combophy PHY_TYPE_PCIE>;
> > > >         phy-names = "pcie-phy";
> > > >       };
> > > >     };
> > > > 
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pci/mediatek,mt7621-pcie.yaml?id=v6.12#n111
> > > > is one binding that does this, others include apple,pcie.yaml,
> > > > brcm,stb-pcie.yaml, hisilicon,kirin-pcie.yaml.
> > > > 
> > > 
> > > On a second thought, moving the PHY to the root-port part would introduce a
> > > discrepancy with the pcie_ep binding, whereas the PHY is required on the
> > > pcie_ep node.
> > > 
> > > Even for the pcie_rc, the PHY is needed to enable the core_clk to access
> > > the PCIe core registers,
> > > 
> > 
> > But why that matters? You can still parse the child nodes, enable PHY and
> > configure PCIe registers. >
> > > So that would make 2 different required PHY locations for RC and EP:
> > > 
> > >      pcie_rc: pcie at 48400000 {
> > >        compatible = "st,stm32mp25-pcie-rc";
> > > 
> > >        pcie at 0,0 {
> > >          reg = <0x0000 0 0 0 0>;
> > >          phys = <&combophy PHY_TYPE_PCIE>;
> > >          phy-names = "pcie-phy";
> > >        };
> > >      };
> > > 
> > >      pcie_ep pcie at 48400000 {
> > >        compatible = "st,stm32mp25-pcie-ep";
> > >        phys = <&combophy PHY_TYPE_PCIE>;
> > >        phy-names = "pcie-phy";
> > >      };
> > > 
> > > Simplest seems to keep the PHY required for the pcie core regardless of the
> > > mode and keep the empty root port to split the design
> > > 
> > 
> > No please. Try to do the right thing from the start itself.
> 
> Parsing the child node to clock the IP seems weird. Note that
> hisilicon,kirin-pcie.yaml also declares the PHY at the controller level.
> 

Nothing is weird here. Almost all multi port controller drivers does the same.
Most of the single port controller instances define port properties in
controller node only, but that's what we want to avoid now.

- Mani

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Wed Dec 18 01:08:34 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 18 Dec 2024 14:38:34 +0530
Subject: [PATCH v2 4/5] PCI: stm32: Add PCIe endpoint support for
 STM32MP25
In-Reply-To: <fdc487c4-cbdc-45ac-a79f-aff2b8ccafcc@foss.st.com>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-5-christian.bruel@foss.st.com>
 <20241203152230.5mdrt27u5u5ecwcz@thinkpad>
 <4e257489-4d90-4e47-a4d9-a2444627c356@foss.st.com>
 <20241216161700.dtldi7fari6kafrr@thinkpad>
 <fdc487c4-cbdc-45ac-a79f-aff2b8ccafcc@foss.st.com>
Message-ID: <20241218090834.bz5htywl3sjbzq6w@thinkpad>

On Tue, Dec 17, 2024 at 10:48:43AM +0100, Christian Bruel wrote:
> 
> 
> On 12/16/24 17:17, Manivannan Sadhasivam wrote:
> > On Mon, Dec 16, 2024 at 11:02:07AM +0100, Christian Bruel wrote:
> > > Hi Manivanna,
> > > 
> > > On 12/3/24 16:22, Manivannan Sadhasivam wrote:
> > > > On Tue, Nov 26, 2024 at 04:51:18PM +0100, Christian Bruel wrote:
> > > > 
> > > > [...]
> > > > 
> > > > > +static int stm32_pcie_start_link(struct dw_pcie *pci)
> > > > > +{
> > > > > +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
> > > > > +	int ret;
> > > > > +
> > > > > +	if (stm32_pcie->link_status == STM32_PCIE_EP_LINK_ENABLED) {
> > > > > +		dev_dbg(pci->dev, "Link is already enabled\n");
> > > > > +		return 0;
> > > > > +	}
> > > > > +
> > > > > +	ret = stm32_pcie_enable_link(pci);
> > > > > +	if (ret) {
> > > > > +		dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret);
> > > > > +		return ret;
> > > > > +	}
> > > > 
> > > > How the REFCLK is supplied to the endpoint? From host or generated locally?
> > > 
> > >  From Host only, we don't support the separated clock model.
> > > 
> > 
> > OK. So even without refclk you are still able to access the controller
> > registers? So the controller CSRs should be accessible by separate local clock I
> > believe.
> > 
> > Anyhow, please add this limitation (refclk dependency from host) in commit
> > message.
> > 
> > [...]
> > 
> > > > > +	ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE);
> > > > 
> > > > Hmm, so PHY mode is common for both endpoint and host?
> > > 
> > > Yes it is. We need to init the phy here because it is a clock source for the
> > > PCIe core clk
> > > 
> > 
> > Clock source? Is it coming directly to PCIe or through RCC? There is no direct
> > clock representation from PHY to PCIe in DT binding.
> 
> The core_clk is generated directly by the PLL in the COMBOPHY, gated by the
> RCC
> 

In that case, phy should be the clock provider to RCC and PCIe should get the
gated clock it.

- Mani

-- 
????????? ????????


From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:47 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:47 +0100
Subject: [PATCH 3/9] iio: trigger: stm32-timer: add support for stm32mp25
In-Reply-To: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241218090153.742869-4-fabrice.gasnier@foss.st.com>

Add support for STM32MP25 SoC. Use newly introduced compatible to handle
this new HW variant. Add TIM20 trigger definitions that can be used by
the stm32 analog-to-digital converter. Use compatible data to identify
it.
As the counter framework is now superseding the deprecated IIO counter
interface (IIO_COUNT), don't support it. Only register IIO trigger
devices for ADC usage. So, make the valids_table a cfg option.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 drivers/iio/trigger/stm32-timer-trigger.c     | 21 +++++++++++++++++--
 include/linux/iio/timer/stm32-timer-trigger.h |  6 ++++++
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c
index bb60b2d7b2ec..8aaf3abf044e 100644
--- a/drivers/iio/trigger/stm32-timer-trigger.c
+++ b/drivers/iio/trigger/stm32-timer-trigger.c
@@ -38,6 +38,9 @@ static const void *triggers_table[][MAX_TRIGGERS] = {
 	{ TIM15_TRGO,},
 	{ TIM16_OC1,},
 	{ TIM17_OC1,},
+	{ }, /* timer 18 */
+	{ }, /* timer 19 */
+	{ TIM20_TRGO, TIM20_TRGO2, TIM20_OC1, TIM20_OC2, TIM20_OC3, },
 };
 
 /* List the triggers accepted by each timer */
@@ -781,7 +784,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	/* Create an IIO device only if we have triggers to be validated */
-	if (*cfg->valids_table[index])
+	if (cfg->valids_table && *cfg->valids_table[index])
 		priv = stm32_setup_counter_device(dev);
 	else
 		priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -794,7 +797,8 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
 	priv->clk = ddata->clk;
 	priv->max_arr = ddata->max_arr;
 	priv->triggers = triggers_table[index];
-	priv->valids = cfg->valids_table[index];
+	if (cfg->valids_table && *cfg->valids_table[index])
+		priv->valids = cfg->valids_table[index];
 	stm32_timer_detect_trgo2(priv);
 	mutex_init(&priv->lock);
 
@@ -886,6 +890,16 @@ static const struct stm32_timer_trigger_cfg stm32h7_timer_trg_cfg = {
 	.num_valids_table = ARRAY_SIZE(stm32h7_valids_table),
 };
 
+static const struct stm32_timer_trigger_cfg stm32mp25_timer_trg_cfg = {
+	/*
+	 * valids_table not used: counter framework is now superseding the deprecated IIO
+	 * counter interface (IIO_COUNT), so don't support it. num_valids_table is only
+	 * kept here to register the IIO HW triggers. valids_table should be moved at some
+	 * point to the stm32-timer-cnt driver instead.
+	 */
+	.num_valids_table = ARRAY_SIZE(triggers_table),
+};
+
 static const struct of_device_id stm32_trig_of_match[] = {
 	{
 		.compatible = "st,stm32-timer-trigger",
@@ -893,6 +907,9 @@ static const struct of_device_id stm32_trig_of_match[] = {
 	}, {
 		.compatible = "st,stm32h7-timer-trigger",
 		.data = (void *)&stm32h7_timer_trg_cfg,
+	}, {
+		.compatible = "st,stm32mp25-timer-trigger",
+		.data = (void *)&stm32mp25_timer_trg_cfg,
 	},
 	{ /* end node */ },
 };
diff --git a/include/linux/iio/timer/stm32-timer-trigger.h b/include/linux/iio/timer/stm32-timer-trigger.h
index 37572e4dc73a..1ee237b56183 100644
--- a/include/linux/iio/timer/stm32-timer-trigger.h
+++ b/include/linux/iio/timer/stm32-timer-trigger.h
@@ -72,6 +72,12 @@
 
 #define TIM17_OC1	"tim17_oc1"
 
+#define TIM20_OC1	"tim20_oc1"
+#define TIM20_OC2	"tim20_oc2"
+#define TIM20_OC3	"tim20_oc3"
+#define TIM20_TRGO	"tim20_trgo"
+#define TIM20_TRGO2	"tim20_trgo2"
+
 #if IS_REACHABLE(CONFIG_IIO_STM32_TIMER_TRIGGER)
 bool is_stm32_timer_trigger(struct iio_trigger *trig);
 #else
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:44 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:44 +0100
Subject: [PATCH 0/9] Add STM32MP25 timers support: MFD, PWM, IIO and counter drivers
Message-ID: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>

This series adds STM32MP25 support on MFD PWM, IIO, counter timer drivers.
This new timer variant is managed by using a new DT compatible string.
It comes with a slightly updated register set, some new features and new
interconnect signals inside the SoC. There is also a new instance (TIM20).
Same feature list as on STM32MP1x is supported currently, except for PWM
capture (not enabled, by DT).
The device tree files add all instances in stm32mp251 dtsi. PWM, counter
and trigger examples are provided for stm32mp257f-ev1 board.

Fabrice Gasnier (9):
  dt-bindings: mfd: stm32-timers: add support for stm32mp25
  mfd: stm32-timers: add support for stm32mp25
  iio: trigger: stm32-timer: add support for stm32mp25
  counter: stm32-timer-cnt: add support for stm32mp25
  pwm: stm32: add support for stm32mp25
  arm64: defconfig: enable STM32 timers drivers
  arm64: dts: st: add timer nodes on stm32mp251
  arm64: dts: st: add timer pins for stm32mp257f-ev1
  arm64: dts: st: add timer nodes on stm32mp257f-ev1

 .../bindings/mfd/st,stm32-timers.yaml         |  18 +-
 arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi |  61 ++
 arch/arm64/boot/dts/st/stm32mp251.dtsi        | 524 ++++++++++++++++++
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts    |  58 ++
 arch/arm64/configs/defconfig                  |   4 +
 drivers/counter/stm32-timer-cnt.c             |   7 +-
 drivers/iio/trigger/stm32-timer-trigger.c     |  21 +-
 drivers/mfd/stm32-timers.c                    |  32 +-
 drivers/pwm/pwm-stm32.c                       |  39 +-
 include/linux/iio/timer/stm32-timer-trigger.h |   6 +
 include/linux/mfd/stm32-timers.h              |   9 +
 11 files changed, 766 insertions(+), 13 deletions(-)

-- 
2.25.1



From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:49 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:49 +0100
Subject: [PATCH 5/9] pwm: stm32: add support for stm32mp25
In-Reply-To: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241218090153.742869-6-fabrice.gasnier@foss.st.com>

Add support for STM32MP25 SoC. Use newly introduced compatible to handle
new features along with registers and bits diversity.
The MFD part of the driver fills in ipidr, so it is used to check the
hardware configuration register, when available to gather the number
of PWM channels and complementary outputs.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 drivers/pwm/pwm-stm32.c | 39 +++++++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index 17e591f61efb..99383e09920e 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -19,6 +19,7 @@
 #define CCMR_CHANNEL_SHIFT 8
 #define CCMR_CHANNEL_MASK  0xFF
 #define MAX_BREAKINPUT 2
+#define MAX_PWM_OUTPUT 4
 
 struct stm32_breakinput {
 	u32 index;
@@ -775,10 +776,19 @@ static int stm32_pwm_probe_breakinputs(struct stm32_pwm *priv,
 	return stm32_pwm_apply_breakinputs(priv);
 }
 
-static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
+static void stm32_pwm_detect_complementary(struct stm32_pwm *priv, struct stm32_timers *ddata)
 {
 	u32 ccer;
 
+	if (ddata->ipidr) {
+		u32 val;
+
+		/* Simply read from HWCFGR the number of complementary outputs (MP25). */
+		regmap_read(priv->regmap, TIM_HWCFGR1, &val);
+		priv->have_complementary_output = !!FIELD_GET(TIM_HWCFGR1_NB_OF_DT, val);
+		return;
+	}
+
 	/*
 	 * If complementary bit doesn't exist writing 1 will have no
 	 * effect so we can detect it.
@@ -790,11 +800,31 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
 	priv->have_complementary_output = (ccer != 0);
 }
 
-static unsigned int stm32_pwm_detect_channels(struct regmap *regmap,
+static unsigned int stm32_pwm_detect_channels(struct stm32_timers *ddata,
 					      unsigned int *num_enabled)
 {
+	struct regmap *regmap = ddata->regmap;
 	u32 ccer, ccer_backup;
 
+	if (ddata->ipidr) {
+		unsigned int npwm = 0;
+		u32 val;
+
+		/* Simply deduce from HWCFGR the number of outputs (MP25). */
+		regmap_read(regmap, TIM_HWCFGR1, &val);
+
+		/*
+		 * Timers may have more capture/compare channels than the
+		 * actual number of PWM channel outputs (e.g. TIM_CH[1..4]).
+		 */
+		npwm = FIELD_GET(TIM_HWCFGR1_NB_OF_CC, val);
+
+		regmap_read(regmap, TIM_CCER, &ccer);
+		*num_enabled = hweight32(ccer & TIM_CCER_CCXE);
+
+		return npwm < MAX_PWM_OUTPUT ? npwm : MAX_PWM_OUTPUT;
+	}
+
 	/*
 	 * If channels enable bits don't exist writing 1 will have no
 	 * effect so we can detect and count them.
@@ -820,7 +850,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 	unsigned int i;
 	int ret;
 
-	npwm = stm32_pwm_detect_channels(ddata->regmap, &num_enabled);
+	npwm = stm32_pwm_detect_channels(ddata, &num_enabled);
 
 	chip = devm_pwmchip_alloc(dev, npwm, sizeof(*priv));
 	if (IS_ERR(chip))
@@ -841,7 +871,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, ret,
 				     "Failed to configure breakinputs\n");
 
-	stm32_pwm_detect_complementary(priv);
+	stm32_pwm_detect_complementary(priv, ddata);
 
 	ret = devm_clk_rate_exclusive_get(dev, priv->clk);
 	if (ret)
@@ -911,6 +941,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stm32_pwm_pm_ops, stm32_pwm_suspend, stm32_pwm_r
 
 static const struct of_device_id stm32_pwm_of_match[] = {
 	{ .compatible = "st,stm32-pwm",	},
+	{ .compatible = "st,stm32mp25-pwm", },
 	{ /* end node */ },
 };
 MODULE_DEVICE_TABLE(of, stm32_pwm_of_match);
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:45 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:45 +0100
Subject: [PATCH 1/9] dt-bindings: mfd: stm32-timers: add support for stm32mp25
In-Reply-To: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241218090153.742869-2-fabrice.gasnier@foss.st.com>

Add a new stm32mp25 compatible to stm32-timer dt-bindings in order to
support the STM32MP25 SoC. Some features has been added or updated in
the stm32-timer timer such as:
- hardware configuration and identification registers to read the timer
  version and capabilities (counter width, number of channels...)
- dithering mode (can be used to extend PWM resolution)
- input triggers list
- new counter modes
- various bit-field updates
- power-domains property
Timer trigger identifier can be up to 19 (from timer 20)

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 .../bindings/mfd/st,stm32-timers.yaml          | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml b/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
index b0e438ff4950..66aa1550a4e5 100644
--- a/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
+++ b/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
@@ -21,7 +21,9 @@ maintainers:
 
 properties:
   compatible:
-    const: st,stm32-timers
+    enum:
+      - st,stm32-timers
+      - st,stm32mp25-timers
 
   reg:
     maxItems: 1
@@ -36,6 +38,9 @@ properties:
   resets:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
   dmas:
     minItems: 1
     maxItems: 7
@@ -77,7 +82,9 @@ properties:
 
     properties:
       compatible:
-        const: st,stm32-pwm
+        enum:
+          - st,stm32-pwm
+          - st,stm32mp25-pwm
 
       "#pwm-cells":
         const: 3
@@ -113,7 +120,9 @@ properties:
 
     properties:
       compatible:
-        const: st,stm32-timer-counter
+        enum:
+          - st,stm32-timer-counter
+          - st,stm32mp25-timer-counter
 
     required:
       - compatible
@@ -128,12 +137,13 @@ patternProperties:
         enum:
           - st,stm32-timer-trigger
           - st,stm32h7-timer-trigger
+          - st,stm32mp25-timer-trigger
 
       reg:
         description: Identify trigger hardware block.
         items:
           minimum: 0
-          maximum: 16
+          maximum: 19
 
     required:
       - compatible
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:50 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:50 +0100
Subject: [PATCH 6/9] arm64: defconfig: enable STM32 timers drivers
In-Reply-To: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241218090153.742869-7-fabrice.gasnier@foss.st.com>

Enable the STM32 timer drivers: MFD, counter, PWM and trigger as module.
These drivers can be used on STM32MP25.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm64/configs/defconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..d6aabdc103d7 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -764,6 +764,7 @@ CONFIG_MFD_TI_LP873X=m
 CONFIG_MFD_TPS65219=y
 CONFIG_MFD_TPS6594_I2C=m
 CONFIG_MFD_ROHM_BD718XX=y
+CONFIG_MFD_STM32_TIMERS=m
 CONFIG_MFD_WCD934X=m
 CONFIG_MFD_KHADAS_MCU=m
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -1499,6 +1500,7 @@ CONFIG_IIO_CROS_EC_LIGHT_PROX=m
 CONFIG_SENSORS_ISL29018=m
 CONFIG_VCNL4000=m
 CONFIG_IIO_ST_MAGN_3AXIS=m
+CONFIG_IIO_STM32_TIMER_TRIGGER=m
 CONFIG_IIO_CROS_EC_BARO=m
 CONFIG_MPL3115=m
 CONFIG_PWM=y
@@ -1516,6 +1518,7 @@ CONFIG_PWM_ROCKCHIP=y
 CONFIG_PWM_RZ_MTU3=m
 CONFIG_PWM_SAMSUNG=y
 CONFIG_PWM_SL28CPLD=m
+CONFIG_PWM_STM32=m
 CONFIG_PWM_SUN4I=m
 CONFIG_PWM_TEGRA=m
 CONFIG_PWM_TIECAP=m
@@ -1650,6 +1653,7 @@ CONFIG_INTERCONNECT_QCOM_SM8650=y
 CONFIG_INTERCONNECT_QCOM_X1E80100=y
 CONFIG_COUNTER=m
 CONFIG_RZ_MTU3_CNT=m
+CONFIG_STM32_TIMER_CNT=m
 CONFIG_HTE=y
 CONFIG_HTE_TEGRA194=y
 CONFIG_HTE_TEGRA194_TEST=m
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Wed Dec 18 01:01:46 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Wed, 18 Dec 2024 10:01:46 +0100
Subject: [PATCH 2/9] mfd: stm32-timers: add support for stm32mp25
In-Reply-To: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241218090153.742869-3-fabrice.gasnier@foss.st.com>

Add support for STM32MP25 SoC. Use newly introduced compatible, to handle
new features.
Identification and hardware configuration registers allow to read the
timer version and capabilities (counter width, number of channels...).
So, rework the probe to avoid touching ARR register by simply read the
counter width when available. This may avoid messing with a possibly
running timer.
Also add useful bit fields to stm32-timers header file.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 drivers/mfd/stm32-timers.c       | 32 +++++++++++++++++++++++++++++++-
 include/linux/mfd/stm32-timers.h |  9 +++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/stm32-timers.c b/drivers/mfd/stm32-timers.c
index 650724e19b88..6f217c32482c 100644
--- a/drivers/mfd/stm32-timers.c
+++ b/drivers/mfd/stm32-timers.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/reset.h>
 
 #define STM32_TIMERS_MAX_REGISTERS	0x3fc
@@ -173,6 +174,32 @@ static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
 	regmap_write(ddata->regmap, TIM_ARR, arr);
 }
 
+static int stm32_timers_probe_hwcfgr(struct device *dev, struct stm32_timers *ddata)
+{
+	u32 val;
+
+	ddata->ipidr = (uintptr_t)device_get_match_data(dev);
+	if (!ddata->ipidr) {
+		/* fallback to legacy method for probing counter width */
+		stm32_timers_get_arr_size(ddata);
+		return 0;
+	}
+
+	regmap_read(ddata->regmap, TIM_IPIDR, &val);
+	/* Sanity check on IP identification register */
+	if (val != ddata->ipidr) {
+		dev_err(dev, "Unexpected identification: %u\n", val);
+		return -EINVAL;
+	}
+
+	regmap_read(ddata->regmap, TIM_HWCFGR2, &val);
+	/* Counter width in bits, max reload value is BIT(width) - 1 */
+	ddata->max_arr = BIT(FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val)) - 1;
+	dev_dbg(dev, "TIM width: %ld\n", FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val));
+
+	return 0;
+}
+
 static int stm32_timers_dma_probe(struct device *dev,
 				   struct stm32_timers *ddata)
 {
@@ -285,7 +312,9 @@ static int stm32_timers_probe(struct platform_device *pdev)
 	if (IS_ERR(ddata->clk))
 		return PTR_ERR(ddata->clk);
 
-	stm32_timers_get_arr_size(ddata);
+	ret = stm32_timers_probe_hwcfgr(dev, ddata);
+	if (ret)
+		return ret;
 
 	ret = stm32_timers_irq_probe(pdev, ddata);
 	if (ret)
@@ -320,6 +349,7 @@ static void stm32_timers_remove(struct platform_device *pdev)
 
 static const struct of_device_id stm32_timers_of_match[] = {
 	{ .compatible = "st,stm32-timers", },
+	{ .compatible = "st,stm32mp25-timers", .data = (void *)STM32MP25_TIM_IPIDR },
 	{ /* end node */ },
 };
 MODULE_DEVICE_TABLE(of, stm32_timers_of_match);
diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h
index f09ba598c97a..23b0cae4a9f8 100644
--- a/include/linux/mfd/stm32-timers.h
+++ b/include/linux/mfd/stm32-timers.h
@@ -33,6 +33,9 @@
 #define TIM_DCR		0x48			/* DMA control register			*/
 #define TIM_DMAR	0x4C			/* DMA register for transfer		*/
 #define TIM_TISEL	0x68			/* Input Selection			*/
+#define TIM_HWCFGR2	0x3EC			/* hardware configuration 2 Reg (MP25)	*/
+#define TIM_HWCFGR1	0x3F0			/* hardware configuration 1 Reg (MP25)	*/
+#define TIM_IPIDR	0x3F8			/* IP identification Reg (MP25)		*/
 
 #define TIM_CR1_CEN		BIT(0)					/* Counter Enable				*/
 #define TIM_CR1_DIR		BIT(4)					/* Counter Direction				*/
@@ -100,6 +103,9 @@
 #define TIM_BDTR_BKF(x)		(0xf << (16 + (x) * 4))
 #define TIM_DCR_DBA		GENMASK(4, 0)				/* DMA base addr				*/
 #define TIM_DCR_DBL		GENMASK(12, 8)				/* DMA burst len				*/
+#define TIM_HWCFGR1_NB_OF_CC	GENMASK(3, 0)				/* Capture/compare channels			*/
+#define TIM_HWCFGR1_NB_OF_DT	GENMASK(7, 4)				/* Complementary outputs & dead-time generators */
+#define TIM_HWCFGR2_CNT_WIDTH	GENMASK(15, 8)				/* Counter width				*/
 
 #define MAX_TIM_PSC				0xFFFF
 #define MAX_TIM_ICPSC				0x3
@@ -113,6 +119,8 @@
 #define TIM_BDTR_BKF_MASK			0xF
 #define TIM_BDTR_BKF_SHIFT(x)			(16 + (x) * 4)
 
+#define STM32MP25_TIM_IPIDR	0x00120002
+
 enum stm32_timers_dmas {
 	STM32_TIMERS_DMA_CH1,
 	STM32_TIMERS_DMA_CH2,
@@ -151,6 +159,7 @@ struct stm32_timers_dma {
 
 struct stm32_timers {
 	struct clk *clk;
+	u32 ipidr;
 	struct regmap *regmap;
 	u32 max_arr;
 	struct stm32_timers_dma dma; /* Only to be used by the parent */
-- 
2.25.1



From maz at kernel.org  Wed Dec 18 01:10:51 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Dec 2024 09:10:51 +0000
Subject: [PATCH V3 6/7] arm64/boot: Enable EL2 requirements for FEAT_Debugv8p9
In-Reply-To: <CAL_Jsq+EO_s49sSK3JQQEDDpcndf4hSpM_gfoe8tZ8=4y3f-tg@mail.gmail.com>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
	<20241216040831.2448257-7-anshuman.khandual@arm.com>
	<20241216234251.GA629562-robh@kernel.org>
	<c64709f7-e1c6-482e-8665-912be50b15bd@arm.com>
	<CAL_Jsq+EO_s49sSK3JQQEDDpcndf4hSpM_gfoe8tZ8=4y3f-tg@mail.gmail.com>
Message-ID: <86jzbxqrtw.wl-maz@kernel.org>

On Tue, 17 Dec 2024 17:53:41 +0000,
Rob Herring <robh at kernel.org> wrote:
> 
> On Tue, Dec 17, 2024 at 2:48?AM Anshuman Khandual
> <anshuman.khandual at arm.com> wrote:
> >
> > On 12/17/24 05:12, Rob Herring wrote:
> > > On Mon, Dec 16, 2024 at 09:38:30AM +0530, Anshuman Khandual wrote:
> > >> Fine grained trap control for MDSELR_EL1 register needs to be configured in
> > >> HDFGRTR2_EL2, and HDFGWTR2_EL2 registers when kernel enters at EL1, but EL2
> > >> is also present.
> > >
> > > Shouldn't this be "when kernel enters at EL2, and EL3 is also present"?
> >
> > AFAICT - HDFGRTR2_EL2 and HDFGWTR2_EL2 registers configure traps into EL2 when
> > accessed from EL1/EL0, provided all required EL3 trap controls are in place as
> > well. These EL2 based trap configs need to be set before the kernel finally
> > enters EL1. Although there is an assumption about EL3 based trap configs being
> > in place, do we need to mention that in commit message as well. Is not updating
> > booting.rst takes care of all EL3 requirements.
> 
> My point is just I read 'kernel enters at EL1' as meaning the kernel
> booted at EL1 and EL2 is not accessible. Maybe should reworded as
> 'before/if the kernel drops to EL1'

The EL2->EL1 downgrade is internal to the kernel. If we get it wrong,
that's our fault, and there isn't anything to document. This document
is about booting the kernel at any NS EL, so only the "external"
requirements matter.

But I don't think we should be prescriptive about the state of these
registers, as long as the potential traps are correctly handled.

For the above, I'd rather have something like:

"The MDSELR_EL1 register must be freely accessible when the kernel is
 entered at EL1 and that higher ELs are present in the system."

On its own, that should be enough. You can subsequently add:

"This includes HDFGRTR2_EL2, HDFGWTR2_EL2 and MDCR_EL2 when EL2 is
 present, as well as MDCR_EL3 when EL3 is present".

but that's paraphrasing the architecture, and is definitely incomplete
(see the MDSELR_EL1 pseudocode for reference).

> 
> > > Though it is really "If EL3 set FGTEn2 and the kernel is entered in
> > > EL2, then FGT2 must be initialized for MDSELR_EL1."
> > >
> > > If it was me, I'd just plagarize what was written for prior FGT
> > > commits for this code. :)
> >
> > There are many commits that changed __init_el2_fgt() with different description
> > formats. Do you have particular one in mind which can be followed here ? :)
> >
> > >
> > >> This adds a new helper __init_el2_fgt2() initializing this
> > >> new FEAT_FGT2 based fine grained registers.
> > >
> > > "This adds" is the same as saying "This patch/commit adds" which is well
> > > documented to avoid. Use imperative "Add a new helper...". Though it is
> > > clear from the diff that is what you are doing...
> >
> > Sure, will fix it.
> >
> > >
> > >
> > >> MDCR_EL2.EBWE needs to be enabled for additional (beyond 16) breakpoint and
> > >> watchpoint exceptions when kernel enters at EL1, but EL2 is also present.
> > >> This updates __init_el2_debug() as required for FEAT_Debugv8p9.
> > >>
> > >> While here, also update booting.rst with MDCR_EL3 and SCR_EL3 requirements.
> > >>
> > >> Cc: Catalin Marinas <catalin.marinas at arm.com>
> > >> Cc: Will Deacon <will at kernel.org>
> > >> Cc: Jonathan Corbet <corbet at lwn.net>
> > >> Cc: Marc Zyngier <maz at kernel.org>
> > >> Cc: Oliver Upton <oliver.upton at linux.dev>
> > >> Cc: linux-arm-kernel at lists.infradead.org
> > >> Cc: linux-doc at vger.kernel.org
> > >> Cc: linux-kernel at vger.kernel.org
> > >> Cc: kvmarm at lists.linux.dev
> > >> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> > >> ---
> > >> Changes in V3:
> > >>
> > >> - Dropped MDCR_EL3.TDA boot requirement from documentation (separate series)
> > >> - Dropped MDCR_EL2_EBWE definition as MDCR_EL2 is now defined in tools sysreg
> > >>
> > >> https://lore.kernel.org/all/20241211065425.1106683-1-anshuman.khandual at arm.com/
> > >>
> > >>  Documentation/arch/arm64/booting.rst | 18 ++++++++++++++++++
> > >>  arch/arm64/include/asm/el2_setup.h   | 26 ++++++++++++++++++++++++++
> > >>  2 files changed, 44 insertions(+)
> > >>
> > >> diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
> > >> index 3278fb4bf219..054cfe1cad18 100644
> > >> --- a/Documentation/arch/arm64/booting.rst
> > >> +++ b/Documentation/arch/arm64/booting.rst
> > >> @@ -288,6 +288,12 @@ Before jumping into the kernel, the following conditions must be met:
> > >>
> > >>      - SCR_EL3.FGTEn (bit 27) must be initialised to 0b1.
> > >>
> > >> +  For CPUs with the Fine Grained Traps (FEAT_FGT2) extension present:
> > >> +
> > >> +  - If EL3 is present and the kernel is entered at EL2:
> > >> +
> > >> +    - SCR_EL3.FGTEn2 (bit 59) must be initialised to 0b1.
> > >> +
> > >>    For CPUs with support for HCRX_EL2 (FEAT_HCX) present:
> > >>
> > >>    - If EL3 is present and the kernel is entered at EL2:
> > >> @@ -322,6 +328,18 @@ Before jumping into the kernel, the following conditions must be met:
> > >>      - ZCR_EL2.LEN must be initialised to the same value for all CPUs the
> > >>        kernel will execute on.
> > >>
> > >> +  For CPUs with FEAT_Debugv8p9 extension present:
> > >> +
> > >> +  - If the kernel is entered at EL1 and EL2 is present:
> > >> +
> > >> +    - HDFGRTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1
> > >> +    - HDFGWTR2_EL2.nMDSELR_EL1 (bit 5) must be initialized to 0b1

But then you don't say anything about SCR_EL3.FGTEn2. And what if the
hypervisor wants to trap things in order to emulate on lazy switch
things?

The more I look at those, the more I think these requirements are not
saying what we want to express, which is that some registers must be
accessible one way or another.

> > >> +    - MDCR_EL2.EBWE (bit 43) must be initialized to 0b1
> > >> +
> > >> +  - If EL3 is present:
> > >> +
> > >> +    - MDCR_EL3.EBWE (bit 43) must be initialized to 0b1
> > >> +
> > >>    For CPUs with the Scalable Matrix Extension (FEAT_SME):
> > >>
> > >>    - If EL3 is present:
> > >> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> > >> index 4ef52d7245bb..2fbfe27d38b5 100644
> > >> --- a/arch/arm64/include/asm/el2_setup.h
> > >> +++ b/arch/arm64/include/asm/el2_setup.h
> > >> @@ -105,6 +105,13 @@
> > >>                                              // to own it.
> > >>
> > >>  .Lskip_trace_\@:
> > >> +    mrs     x1, id_aa64dfr0_el1
> > >> +    ubfx    x1, x1, #ID_AA64DFR0_EL1_DebugVer_SHIFT, #4
> > >> +    cmp     x1, #ID_AA64DFR0_EL1_DebugVer_V8P9
> > >> +    b.lt    .Lskip_dbg_v8p9_\@
> > >> +
> > >> +    orr     x2, x2, #MDCR_EL2_EBWE
> > >> +.Lskip_dbg_v8p9_\@:
> > >>      msr     mdcr_el2, x2                    // Configure debug traps
> > >>  .endm
> > >>
> > >> @@ -244,6 +251,24 @@
> > >>  .Lskip_gcs_\@:
> > >>  .endm
> > >>
> > >> +.macro __init_el2_fgt2
> > >> +    mrs     x1, id_aa64mmfr0_el1
> > >> +    ubfx    x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
> > >> +    cmp     x1, #ID_AA64MMFR0_EL1_FGT_FGT2
> > >
> > > We already read this field in __init_el2_fgt, shouldn't we leverage that
> > > and move all this there rather than read the feature reg twice.
> >
> > Should not __init_el2_fgt2() remain separate to contain all future FEAT_FGT2
> > related trap enabled/disable checks ? OTOH reading id_aa64mmfr0_el1 register
> > should improve some performance as well.
> 
> That's the tradeoff. I'll defer to others whether a single id register
> read here is preferred.

Are we *really* talking about *performance* here?  For something that
is executed once per CPU boot? Just keep the damn thing readable, if
at all possible...

	M.

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


From krzk at kernel.org  Wed Dec 18 01:15:14 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 10:15:14 +0100
Subject: [PATCH v20 4/9] dt-bindings: display: bridge: Add Cadence
 MHDP8501
In-Reply-To: <f2b7beebeb99ca69021ca24744e29af3454f5620.1734340233.git.Sandor.yu@nxp.com>
References: <cover.1734340233.git.Sandor.yu@nxp.com>
 <f2b7beebeb99ca69021ca24744e29af3454f5620.1734340233.git.Sandor.yu@nxp.com>
Message-ID: <euujxcd22nake5s4wioc7ew4rxhqwijh5vucozjorotn3nqdvc@q65uqqj2bjwj>

On Tue, Dec 17, 2024 at 02:51:46PM +0800, Sandor Yu wrote:
> Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> ---
> v19->v20:
> - remove data type link of data-lanes.

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

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec 18 01:21:00 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 10:21:00 +0100
Subject: [PATCH v6 1/2] dt-bindings: arm: Add label in the coresight
 components
In-Reply-To: <20241217063324.33781-2-quic_jinlmao@quicinc.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-2-quic_jinlmao@quicinc.com>
Message-ID: <tida22chffj2znikeotmo52aqnzvmedn3aa7a2coarz2dwjc7w@duw5fby4hexk>

On Tue, Dec 17, 2024 at 02:33:23PM +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 label to show hardware context information of each coresight
> device. There will be a sysfs node label in each device folder.
> 
> cat /sys/bus/coresight/devices/cti_sys0/label
> 
> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>

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

Best regards,
Krzysztof



From krzk at kernel.org  Wed Dec 18 01:22:21 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 10:22:21 +0100
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <d8d0a1c8-f2b4-425a-858b-610ae7291ebc@gmail.com>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
 <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
 <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>
 <6e93d59d-71e5-4c09-862f-55b5504121aa@gmail.com>
 <69fd1dbc-a29f-488c-a30f-7e5ea8f01a23@kernel.org>
 <17fbfcdd-8b79-4907-a4c8-798da0ef0526@gmail.com>
 <56c5788a-2d49-4abb-af4b-65a11bdc4094@kernel.org>
 <d8d0a1c8-f2b4-425a-858b-610ae7291ebc@gmail.com>
Message-ID: <3fb8ba3f-3016-4823-bf48-130f173c8f66@kernel.org>

On 17/12/2024 11:04, Ivaylo Ivanov wrote:
> On 12/17/24 11:43, Krzysztof Kozlowski wrote:
>> On 17/12/2024 10:31, Ivaylo Ivanov wrote:
>>> On 12/17/24 11:26, Krzysztof Kozlowski wrote:
>>>> On 17/12/2024 10:08, Ivaylo Ivanov wrote:
>>>>>>>>>        - items:
>>>>>>>>>            - enum:
>>>>>>>>> @@ -94,9 +95,28 @@ allOf:
>>>>>>>>>          - clock-names
>>>>>>>>>  
>>>>>>>>>      else:
>>>>>>>>> -      properties:
>>>>>>>>> -        clocks:
>>>>>>>>> -          maxItems: 1
>>>>>>>>> +      if:
>>>>>>>>> +        properties:
>>>>>>>>> +          compatible:
>>>>>>>>> +            contains:
>>>>>>>>> +              enum:
>>>>>>>>> +                - samsung,exynos8895-hsi2c
>>>>>>>>> +
>>>>>>>>> +      then:
>>>>>>>>> +        properties:
>>>>>>>>> +          clocks:
>>>>>>>> Missing minItems
>>>>>>>>
>>>>>>>>> +            maxItems: 2
>>>>>>>>> +
>>>>>>>>> +          clock-names:
>>>>>>>> Ditto
>>>>>>>>
>>>>>>>>> +            maxItems: 2
>>>>>>>>> +
>>>>>>>>> +        required:
>>>>>>>>> +          - clock-names
>>>>>>>> I don't understand why do you need second, same branch in if, basically
>>>>>>> Because, as I stated in the commit message, we have HSI2C controllers
>>>>>>> both implemented in USIv1 blocks and outside. These that are a part of
>>>>>> On Exynos8895? Where? With the same compatible?
>>>>> hsi2c_0 which has a clock from BUSC and hsi2c_1 to hsi2c_4 which use clocks
>>>>> from PERIC1 (CLK_GOUT_PERIC1_HSI2C_CAM{0,1,2,3}_IPCLK). Why would
>>>>> they need a different compatible though? It's functionally the same i2c design
>>>>> as the one implemented in USIv1 blocks.
>>>> If one block is part of USI and other not, they might not be the same
>>>> I2C blocks, even if interface is similar. If they were the same or even
>>>> functionally the same, they would have the same clock inputs. However
>>> I see, so in such case I should make samsung,exynos8895-hsi2c-nonusi or
>>> something like that?
>>>
>>>> user manual also suggests that there is only one clock, not two (for
>>>> both cases), so they could be functionally equivalent but then number of
>>>> clocks looks incorrect.
>>> That'd be weird. Both according to downstream and upstream clk driver,
>>> for the USI-implemented i2cs we have a pclk and an sclk_usi.
>> Something is not precise here, as usually with Samsung clock topology.
>>
>> First, the non-USI instances have the IPCLK as well, e.g. things like
>> PERIC1_UID_HSI2C_CAM1_IPCLKPORT_iPCLK
>>
>> USI have BLK_PERIC0_UID_USI03_IPCLKPORT_i_SCLK_USI, but that's USI
>> clock, not HSI2C in USI. Datasheet mentions this is UART and SPI special
>> clock, but not I2C.
> 
> That's weird. Don't we need the clock enabled in order for the
> USIv1's HSI2C to work?
The clock goes to USI, so it is enabled, no?

Best regards,
Krzysztof


From charlie at rivosinc.com  Wed Dec 18 01:23:58 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:23:58 -0800
Subject: [PATCH v4 00/16] perf tools: Use generic syscall scripts for all
 archs
Message-ID: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>

Standardize the generation of syscall headers around syscall tables.
Previously each architecture independently selected how syscall headers
would be generated, or would not define a way and fallback onto
libaudit. Convert all architectures to use a standard syscall header
generation script and allow each architecture to override the syscall
table to use if they do not use the generic table.

As a result of these changes, no architecture will require libaudit, and
so the fallback case of using libaudit is removed by this series.

Testing:

I have tested that the syscall mappings of id to name generation works
as expected for every architecture, but I have only validated that perf
trace compiles and runs as expected on riscv, arm64, and x86_64.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Reviewed-by: Ian Rogers <irogers at google.com>

On x86-64:
Tested-by: Ian Rogers <irogers at google.com>

---
Changes in v4:
- Remove audit_machine member of syscalltbl struct (Ian)
- Rebase on perf-tools-next
- Link to v3: https://lore.kernel.org/r/20241216-perf_syscalltbl-v3-0-239f032481d5 at rivosinc.com

Changes in v3:
- Fix compiliation when OUTPUT is empty
- Correct unused headers to be .h instead of .c  (Namhyung)
- Make variable definition of supported archs (Namhyung)
- Convert += into := for syscalls headers (Namhyung)
- Link to v2: https://lore.kernel.org/r/20241212-perf_syscalltbl-v2-0-f8ca984ffe40 at rivosinc.com

Changes in v2:
- Rebase onto 6.13-rc2
- Fix output path so it generates to /tools/perf/arch properly
- Link to v1: https://lore.kernel.org/r/20241104-perf_syscalltbl-v1-0-9adae5c761ef at rivosinc.com

---
Charlie Jenkins (16):
      perf tools: Create generic syscall table support
      perf tools: arc: Support generic syscall headers
      perf tools: csky: Support generic syscall headers
      perf tools: arm: Support syscall headers
      perf tools: sh: Support syscall headers
      perf tools: sparc: Support syscall headers
      perf tools: xtensa: Support syscall header
      perf tools: x86: Use generic syscall scripts
      perf tools: alpha: Support syscall header
      perf tools: parisc: Support syscall header
      perf tools: arm64: Use syscall table
      perf tools: loongarch: Use syscall table
      perf tools: mips: Use generic syscall scripts
      perf tools: powerpc: Use generic syscall table scripts
      perf tools: s390: Use generic syscall table scripts
      perf tools: Remove dependency on libaudit

 Documentation/admin-guide/workload-tracing.rst     |   2 +-
 tools/build/feature/Makefile                       |   4 -
 tools/build/feature/test-libaudit.c                |  11 -
 tools/perf/Documentation/perf-check.txt            |   1 -
 tools/perf/Makefile.config                         |  39 +-
 tools/perf/Makefile.perf                           |  12 +-
 tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
 .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 ++++++++++++++++++++
 tools/perf/arch/alpha/include/syscall_table.h      |   2 +
 tools/perf/arch/arc/entry/syscalls/Kbuild          |   2 +
 .../perf/arch/arc/entry/syscalls/Makefile.syscalls |   3 +
 tools/perf/arch/arc/include/syscall_table.h        |   2 +
 tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
 .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
 tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 483 +++++++++++++++++++
 tools/perf/arch/arm/include/syscall_table.h        |   2 +
 tools/perf/arch/arm64/Makefile                     |  22 -
 tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
 .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
 .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++
 .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
 tools/perf/arch/arm64/include/syscall_table.h      |   8 +
 tools/perf/arch/csky/entry/syscalls/Kbuild         |   2 +
 .../arch/csky/entry/syscalls/Makefile.syscalls     |   3 +
 tools/perf/arch/csky/include/syscall_table.h       |   2 +
 tools/perf/arch/loongarch/Makefile                 |  22 -
 tools/perf/arch/loongarch/entry/syscalls/Kbuild    |   2 +
 .../loongarch/entry/syscalls/Makefile.syscalls     |   3 +
 .../arch/loongarch/entry/syscalls/mksyscalltbl     |  45 --
 tools/perf/arch/loongarch/include/syscall_table.h  |   2 +
 tools/perf/arch/mips/entry/syscalls/Kbuild         |   2 +
 .../arch/mips/entry/syscalls/Makefile.syscalls     |   5 +
 tools/perf/arch/mips/entry/syscalls/mksyscalltbl   |  32 --
 tools/perf/arch/mips/include/syscall_table.h       |   2 +
 tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
 .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
 tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++
 tools/perf/arch/parisc/include/syscall_table.h     |   8 +
 tools/perf/arch/powerpc/Makefile                   |  25 -
 tools/perf/arch/powerpc/entry/syscalls/Kbuild      |   3 +
 .../arch/powerpc/entry/syscalls/Makefile.syscalls  |   6 +
 .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  |  39 --
 tools/perf/arch/powerpc/include/syscall_table.h    |   8 +
 tools/perf/arch/riscv/Makefile                     |  22 -
 tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
 .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
 tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 --
 tools/perf/arch/riscv/include/syscall_table.h      |   8 +
 tools/perf/arch/s390/Makefile                      |  21 -
 tools/perf/arch/s390/entry/syscalls/Kbuild         |   2 +
 .../arch/s390/entry/syscalls/Makefile.syscalls     |   5 +
 tools/perf/arch/s390/entry/syscalls/mksyscalltbl   |  32 --
 tools/perf/arch/s390/include/syscall_table.h       |   2 +
 tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
 .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
 tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 472 +++++++++++++++++++
 tools/perf/arch/sh/include/syscall_table.h         |   2 +
 tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
 .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 514 +++++++++++++++++++++
 tools/perf/arch/sparc/include/syscall_table.h      |   8 +
 tools/perf/arch/x86/Build                          |   1 -
 tools/perf/arch/x86/Makefile                       |  25 -
 tools/perf/arch/x86/entry/syscalls/Kbuild          |   3 +
 .../perf/arch/x86/entry/syscalls/Makefile.syscalls |   6 +
 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   |  42 --
 tools/perf/arch/x86/include/syscall_table.h        |   8 +
 tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
 .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 439 ++++++++++++++++++
 tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
 tools/perf/builtin-check.c                         |   1 -
 tools/perf/builtin-help.c                          |   2 -
 tools/perf/builtin-trace.c                         |  30 --
 tools/perf/check-headers.sh                        |   9 +
 tools/perf/perf.c                                  |   6 +-
 tools/perf/scripts/Makefile.syscalls               |  61 +++
 tools/perf/scripts/syscalltbl.sh                   |  86 ++++
 tools/perf/tests/make                              |   7 +-
 tools/perf/util/env.c                              |   4 +-
 tools/perf/util/generate-cmdlist.sh                |   4 +-
 tools/perf/util/syscalltbl.c                       |  90 +---
 tools/perf/util/syscalltbl.h                       |   1 -
 tools/scripts/syscall.tbl                          | 409 ++++++++++++++++
 86 files changed, 4102 insertions(+), 620 deletions(-)
---
base-commit: e8b3012cbd8f2263777347c2e8310b3f00d494f5
change-id: 20240913-perf_syscalltbl-6f98defcc6f5
-- 
- Charlie



From charlie at rivosinc.com  Wed Dec 18 01:24:07 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:07 -0800
Subject: [PATCH v4 09/16] perf tools: alpha: Support syscall header
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-9-bc8caef2ca8e@rivosinc.com>

alpha uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
 .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 +++++++++++++++++++++
 tools/perf/arch/alpha/include/syscall_table.h      |   2 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 515 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 698967f50ceb5cfc29dc5c2947c995980120e64e..7528e6acaf3b1cf76198dafe094800fc00fd56eb 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/alpha/entry/syscalls/Kbuild b/tools/perf/arch/alpha/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls b/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..690168aac34db9f1b96346210993675defcfc300
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64  +=
+
+syscalltbl = $(srctree)/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/alpha/entry/syscalls/syscall.tbl b/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..74720667fe091768800a22fd4ce68b5324abff09
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
@@ -0,0 +1,504 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for alpha
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	osf_syscall			alpha_syscall_zero
+1	common	exit				sys_exit
+2	common	fork				alpha_fork
+3	common	read				sys_read
+4	common	write				sys_write
+5	common	osf_old_open			sys_ni_syscall
+6	common	close				sys_close
+7	common	osf_wait4			sys_osf_wait4
+8	common	osf_old_creat			sys_ni_syscall
+9	common	link				sys_link
+10	common	unlink				sys_unlink
+11	common	osf_execve			sys_ni_syscall
+12	common	chdir				sys_chdir
+13	common	fchdir				sys_fchdir
+14	common	mknod				sys_mknod
+15	common	chmod				sys_chmod
+16	common	chown				sys_chown
+17	common	brk				sys_osf_brk
+18	common	osf_getfsstat			sys_ni_syscall
+19	common	lseek				sys_lseek
+20	common	getxpid				sys_getxpid
+21	common	osf_mount			sys_osf_mount
+22	common	umount2				sys_umount
+23	common	setuid				sys_setuid
+24	common	getxuid				sys_getxuid
+25	common	exec_with_loader		sys_ni_syscall
+26	common	ptrace				sys_ptrace
+27	common	osf_nrecvmsg			sys_ni_syscall
+28	common	osf_nsendmsg			sys_ni_syscall
+29	common	osf_nrecvfrom			sys_ni_syscall
+30	common	osf_naccept			sys_ni_syscall
+31	common	osf_ngetpeername		sys_ni_syscall
+32	common	osf_ngetsockname		sys_ni_syscall
+33	common	access				sys_access
+34	common	osf_chflags			sys_ni_syscall
+35	common	osf_fchflags			sys_ni_syscall
+36	common	sync				sys_sync
+37	common	kill				sys_kill
+38	common	osf_old_stat			sys_ni_syscall
+39	common	setpgid				sys_setpgid
+40	common	osf_old_lstat			sys_ni_syscall
+41	common	dup				sys_dup
+42	common	pipe				sys_alpha_pipe
+43	common	osf_set_program_attributes	sys_osf_set_program_attributes
+44	common	osf_profil			sys_ni_syscall
+45	common	open				sys_open
+46	common	osf_old_sigaction		sys_ni_syscall
+47	common	getxgid				sys_getxgid
+48	common	osf_sigprocmask			sys_osf_sigprocmask
+49	common	osf_getlogin			sys_ni_syscall
+50	common	osf_setlogin			sys_ni_syscall
+51	common	acct				sys_acct
+52	common	sigpending			sys_sigpending
+54	common	ioctl				sys_ioctl
+55	common	osf_reboot			sys_ni_syscall
+56	common	osf_revoke			sys_ni_syscall
+57	common	symlink				sys_symlink
+58	common	readlink			sys_readlink
+59	common	execve				sys_execve
+60	common	umask				sys_umask
+61	common	chroot				sys_chroot
+62	common	osf_old_fstat			sys_ni_syscall
+63	common	getpgrp				sys_getpgrp
+64	common	getpagesize			sys_getpagesize
+65	common	osf_mremap			sys_ni_syscall
+66	common	vfork				alpha_vfork
+67	common	stat				sys_newstat
+68	common	lstat				sys_newlstat
+69	common	osf_sbrk			sys_ni_syscall
+70	common	osf_sstk			sys_ni_syscall
+71	common	mmap				sys_osf_mmap
+72	common	osf_old_vadvise			sys_ni_syscall
+73	common	munmap				sys_munmap
+74	common	mprotect			sys_mprotect
+75	common	madvise				sys_madvise
+76	common	vhangup				sys_vhangup
+77	common	osf_kmodcall			sys_ni_syscall
+78	common	osf_mincore			sys_ni_syscall
+79	common	getgroups			sys_getgroups
+80	common	setgroups			sys_setgroups
+81	common	osf_old_getpgrp			sys_ni_syscall
+82	common	setpgrp				sys_setpgid
+83	common	osf_setitimer			compat_sys_setitimer
+84	common	osf_old_wait			sys_ni_syscall
+85	common	osf_table			sys_ni_syscall
+86	common	osf_getitimer			compat_sys_getitimer
+87	common	gethostname			sys_gethostname
+88	common	sethostname			sys_sethostname
+89	common	getdtablesize			sys_getdtablesize
+90	common	dup2				sys_dup2
+91	common	fstat				sys_newfstat
+92	common	fcntl				sys_fcntl
+93	common	osf_select			sys_osf_select
+94	common	poll				sys_poll
+95	common	fsync				sys_fsync
+96	common	setpriority			sys_setpriority
+97	common	socket				sys_socket
+98	common	connect				sys_connect
+99	common	accept				sys_accept
+100	common	getpriority			sys_osf_getpriority
+101	common	send				sys_send
+102	common	recv				sys_recv
+103	common	sigreturn			sys_sigreturn
+104	common	bind				sys_bind
+105	common	setsockopt			sys_setsockopt
+106	common	listen				sys_listen
+107	common	osf_plock			sys_ni_syscall
+108	common	osf_old_sigvec			sys_ni_syscall
+109	common	osf_old_sigblock		sys_ni_syscall
+110	common	osf_old_sigsetmask		sys_ni_syscall
+111	common	sigsuspend			sys_sigsuspend
+112	common	osf_sigstack			sys_osf_sigstack
+113	common	recvmsg				sys_recvmsg
+114	common	sendmsg				sys_sendmsg
+115	common	osf_old_vtrace			sys_ni_syscall
+116	common	osf_gettimeofday		sys_osf_gettimeofday
+117	common	osf_getrusage			sys_osf_getrusage
+118	common	getsockopt			sys_getsockopt
+120	common	readv				sys_readv
+121	common	writev				sys_writev
+122	common	osf_settimeofday		sys_osf_settimeofday
+123	common	fchown				sys_fchown
+124	common	fchmod				sys_fchmod
+125	common	recvfrom			sys_recvfrom
+126	common	setreuid			sys_setreuid
+127	common	setregid			sys_setregid
+128	common	rename				sys_rename
+129	common	truncate			sys_truncate
+130	common	ftruncate			sys_ftruncate
+131	common	flock				sys_flock
+132	common	setgid				sys_setgid
+133	common	sendto				sys_sendto
+134	common	shutdown			sys_shutdown
+135	common	socketpair			sys_socketpair
+136	common	mkdir				sys_mkdir
+137	common	rmdir				sys_rmdir
+138	common	osf_utimes			sys_osf_utimes
+139	common	osf_old_sigreturn		sys_ni_syscall
+140	common	osf_adjtime			sys_ni_syscall
+141	common	getpeername			sys_getpeername
+142	common	osf_gethostid			sys_ni_syscall
+143	common	osf_sethostid			sys_ni_syscall
+144	common	getrlimit			sys_getrlimit
+145	common	setrlimit			sys_setrlimit
+146	common	osf_old_killpg			sys_ni_syscall
+147	common	setsid				sys_setsid
+148	common	quotactl			sys_quotactl
+149	common	osf_oldquota			sys_ni_syscall
+150	common	getsockname			sys_getsockname
+153	common	osf_pid_block			sys_ni_syscall
+154	common	osf_pid_unblock			sys_ni_syscall
+156	common	sigaction			sys_osf_sigaction
+157	common	osf_sigwaitprim			sys_ni_syscall
+158	common	osf_nfssvc			sys_ni_syscall
+159	common	osf_getdirentries		sys_osf_getdirentries
+160	common	osf_statfs			sys_osf_statfs
+161	common	osf_fstatfs			sys_osf_fstatfs
+163	common	osf_asynch_daemon		sys_ni_syscall
+164	common	osf_getfh			sys_ni_syscall
+165	common	osf_getdomainname		sys_osf_getdomainname
+166	common	setdomainname			sys_setdomainname
+169	common	osf_exportfs			sys_ni_syscall
+181	common	osf_alt_plock			sys_ni_syscall
+184	common	osf_getmnt			sys_ni_syscall
+187	common	osf_alt_sigpending		sys_ni_syscall
+188	common	osf_alt_setsid			sys_ni_syscall
+199	common	osf_swapon			sys_swapon
+200	common	msgctl				sys_old_msgctl
+201	common	msgget				sys_msgget
+202	common	msgrcv				sys_msgrcv
+203	common	msgsnd				sys_msgsnd
+204	common	semctl				sys_old_semctl
+205	common	semget				sys_semget
+206	common	semop				sys_semop
+207	common	osf_utsname			sys_osf_utsname
+208	common	lchown				sys_lchown
+209	common	shmat				sys_shmat
+210	common	shmctl				sys_old_shmctl
+211	common	shmdt				sys_shmdt
+212	common	shmget				sys_shmget
+213	common	osf_mvalid			sys_ni_syscall
+214	common	osf_getaddressconf		sys_ni_syscall
+215	common	osf_msleep			sys_ni_syscall
+216	common	osf_mwakeup			sys_ni_syscall
+217	common	msync				sys_msync
+218	common	osf_signal			sys_ni_syscall
+219	common	osf_utc_gettime			sys_ni_syscall
+220	common	osf_utc_adjtime			sys_ni_syscall
+222	common	osf_security			sys_ni_syscall
+223	common	osf_kloadcall			sys_ni_syscall
+224	common	osf_stat			sys_osf_stat
+225	common	osf_lstat			sys_osf_lstat
+226	common	osf_fstat			sys_osf_fstat
+227	common	osf_statfs64			sys_osf_statfs64
+228	common	osf_fstatfs64			sys_osf_fstatfs64
+233	common	getpgid				sys_getpgid
+234	common	getsid				sys_getsid
+235	common	sigaltstack			sys_sigaltstack
+236	common	osf_waitid			sys_ni_syscall
+237	common	osf_priocntlset			sys_ni_syscall
+238	common	osf_sigsendset			sys_ni_syscall
+239	common	osf_set_speculative		sys_ni_syscall
+240	common	osf_msfs_syscall		sys_ni_syscall
+241	common	osf_sysinfo			sys_osf_sysinfo
+242	common	osf_uadmin			sys_ni_syscall
+243	common	osf_fuser			sys_ni_syscall
+244	common	osf_proplist_syscall		sys_osf_proplist_syscall
+245	common	osf_ntp_adjtime			sys_ni_syscall
+246	common	osf_ntp_gettime			sys_ni_syscall
+247	common	osf_pathconf			sys_ni_syscall
+248	common	osf_fpathconf			sys_ni_syscall
+250	common	osf_uswitch			sys_ni_syscall
+251	common	osf_usleep_thread		sys_osf_usleep_thread
+252	common	osf_audcntl			sys_ni_syscall
+253	common	osf_audgen			sys_ni_syscall
+254	common	sysfs				sys_sysfs
+255	common	osf_subsys_info			sys_ni_syscall
+256	common	osf_getsysinfo			sys_osf_getsysinfo
+257	common	osf_setsysinfo			sys_osf_setsysinfo
+258	common	osf_afs_syscall			sys_ni_syscall
+259	common	osf_swapctl			sys_ni_syscall
+260	common	osf_memcntl			sys_ni_syscall
+261	common	osf_fdatasync			sys_ni_syscall
+300	common	bdflush				sys_ni_syscall
+301	common	sethae				sys_sethae
+302	common	mount				sys_mount
+303	common	old_adjtimex			sys_old_adjtimex
+304	common	swapoff				sys_swapoff
+305	common	getdents			sys_getdents
+306	common	create_module			sys_ni_syscall
+307	common	init_module			sys_init_module
+308	common	delete_module			sys_delete_module
+309	common	get_kernel_syms			sys_ni_syscall
+310	common	syslog				sys_syslog
+311	common	reboot				sys_reboot
+312	common	clone				alpha_clone
+313	common	uselib				sys_uselib
+314	common	mlock				sys_mlock
+315	common	munlock				sys_munlock
+316	common	mlockall			sys_mlockall
+317	common	munlockall			sys_munlockall
+318	common	sysinfo				sys_sysinfo
+319	common	_sysctl				sys_ni_syscall
+# 320 was sys_idle
+321	common	oldumount			sys_oldumount
+322	common	swapon				sys_swapon
+323	common	times				sys_times
+324	common	personality			sys_personality
+325	common	setfsuid			sys_setfsuid
+326	common	setfsgid			sys_setfsgid
+327	common	ustat				sys_ustat
+328	common	statfs				sys_statfs
+329	common	fstatfs				sys_fstatfs
+330	common	sched_setparam			sys_sched_setparam
+331	common	sched_getparam			sys_sched_getparam
+332	common	sched_setscheduler		sys_sched_setscheduler
+333	common	sched_getscheduler		sys_sched_getscheduler
+334	common	sched_yield			sys_sched_yield
+335	common	sched_get_priority_max		sys_sched_get_priority_max
+336	common	sched_get_priority_min		sys_sched_get_priority_min
+337	common	sched_rr_get_interval		sys_sched_rr_get_interval
+338	common	afs_syscall			sys_ni_syscall
+339	common	uname				sys_newuname
+340	common	nanosleep			sys_nanosleep
+341	common	mremap				sys_mremap
+342	common	nfsservctl			sys_ni_syscall
+343	common	setresuid			sys_setresuid
+344	common	getresuid			sys_getresuid
+345	common	pciconfig_read			sys_pciconfig_read
+346	common	pciconfig_write			sys_pciconfig_write
+347	common	query_module			sys_ni_syscall
+348	common	prctl				sys_prctl
+349	common	pread64				sys_pread64
+350	common	pwrite64			sys_pwrite64
+351	common	rt_sigreturn			sys_rt_sigreturn
+352	common	rt_sigaction			sys_rt_sigaction
+353	common	rt_sigprocmask			sys_rt_sigprocmask
+354	common	rt_sigpending			sys_rt_sigpending
+355	common	rt_sigtimedwait			sys_rt_sigtimedwait
+356	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+357	common	rt_sigsuspend			sys_rt_sigsuspend
+358	common	select				sys_select
+359	common	gettimeofday			sys_gettimeofday
+360	common	settimeofday			sys_settimeofday
+361	common	getitimer			sys_getitimer
+362	common	setitimer			sys_setitimer
+363	common	utimes				sys_utimes
+364	common	getrusage			sys_getrusage
+365	common	wait4				sys_wait4
+366	common	adjtimex			sys_adjtimex
+367	common	getcwd				sys_getcwd
+368	common	capget				sys_capget
+369	common	capset				sys_capset
+370	common	sendfile			sys_sendfile64
+371	common	setresgid			sys_setresgid
+372	common	getresgid			sys_getresgid
+373	common	dipc				sys_ni_syscall
+374	common	pivot_root			sys_pivot_root
+375	common	mincore				sys_mincore
+376	common	pciconfig_iobase		sys_pciconfig_iobase
+377	common	getdents64			sys_getdents64
+378	common	gettid				sys_gettid
+379	common	readahead			sys_readahead
+# 380 is unused
+381	common	tkill				sys_tkill
+382	common	setxattr			sys_setxattr
+383	common	lsetxattr			sys_lsetxattr
+384	common	fsetxattr			sys_fsetxattr
+385	common	getxattr			sys_getxattr
+386	common	lgetxattr			sys_lgetxattr
+387	common	fgetxattr			sys_fgetxattr
+388	common	listxattr			sys_listxattr
+389	common	llistxattr			sys_llistxattr
+390	common	flistxattr			sys_flistxattr
+391	common	removexattr			sys_removexattr
+392	common	lremovexattr			sys_lremovexattr
+393	common	fremovexattr			sys_fremovexattr
+394	common	futex				sys_futex
+395	common	sched_setaffinity		sys_sched_setaffinity
+396	common	sched_getaffinity		sys_sched_getaffinity
+397	common	tuxcall				sys_ni_syscall
+398	common	io_setup			sys_io_setup
+399	common	io_destroy			sys_io_destroy
+400	common	io_getevents			sys_io_getevents
+401	common	io_submit			sys_io_submit
+402	common	io_cancel			sys_io_cancel
+405	common	exit_group			sys_exit_group
+406	common	lookup_dcookie			sys_ni_syscall
+407	common	epoll_create			sys_epoll_create
+408	common	epoll_ctl			sys_epoll_ctl
+409	common	epoll_wait			sys_epoll_wait
+410	common	remap_file_pages		sys_remap_file_pages
+411	common	set_tid_address			sys_set_tid_address
+412	common	restart_syscall			sys_restart_syscall
+413	common	fadvise64			sys_fadvise64
+414	common	timer_create			sys_timer_create
+415	common	timer_settime			sys_timer_settime
+416	common	timer_gettime			sys_timer_gettime
+417	common	timer_getoverrun		sys_timer_getoverrun
+418	common	timer_delete			sys_timer_delete
+419	common	clock_settime			sys_clock_settime
+420	common	clock_gettime			sys_clock_gettime
+421	common	clock_getres			sys_clock_getres
+422	common	clock_nanosleep			sys_clock_nanosleep
+423	common	semtimedop			sys_semtimedop
+424	common	tgkill				sys_tgkill
+425	common	stat64				sys_stat64
+426	common	lstat64				sys_lstat64
+427	common	fstat64				sys_fstat64
+428	common	vserver				sys_ni_syscall
+429	common	mbind				sys_ni_syscall
+430	common	get_mempolicy			sys_ni_syscall
+431	common	set_mempolicy			sys_ni_syscall
+432	common	mq_open				sys_mq_open
+433	common	mq_unlink			sys_mq_unlink
+434	common	mq_timedsend			sys_mq_timedsend
+435	common	mq_timedreceive			sys_mq_timedreceive
+436	common	mq_notify			sys_mq_notify
+437	common	mq_getsetattr			sys_mq_getsetattr
+438	common	waitid				sys_waitid
+439	common	add_key				sys_add_key
+440	common	request_key			sys_request_key
+441	common	keyctl				sys_keyctl
+442	common	ioprio_set			sys_ioprio_set
+443	common	ioprio_get			sys_ioprio_get
+444	common	inotify_init			sys_inotify_init
+445	common	inotify_add_watch		sys_inotify_add_watch
+446	common	inotify_rm_watch		sys_inotify_rm_watch
+447	common	fdatasync			sys_fdatasync
+448	common	kexec_load			sys_kexec_load
+449	common	migrate_pages			sys_migrate_pages
+450	common	openat				sys_openat
+451	common	mkdirat				sys_mkdirat
+452	common	mknodat				sys_mknodat
+453	common	fchownat			sys_fchownat
+454	common	futimesat			sys_futimesat
+455	common	fstatat64			sys_fstatat64
+456	common	unlinkat			sys_unlinkat
+457	common	renameat			sys_renameat
+458	common	linkat				sys_linkat
+459	common	symlinkat			sys_symlinkat
+460	common	readlinkat			sys_readlinkat
+461	common	fchmodat			sys_fchmodat
+462	common	faccessat			sys_faccessat
+463	common	pselect6			sys_pselect6
+464	common	ppoll				sys_ppoll
+465	common	unshare				sys_unshare
+466	common	set_robust_list			sys_set_robust_list
+467	common	get_robust_list			sys_get_robust_list
+468	common	splice				sys_splice
+469	common	sync_file_range			sys_sync_file_range
+470	common	tee				sys_tee
+471	common	vmsplice			sys_vmsplice
+472	common	move_pages			sys_move_pages
+473	common	getcpu				sys_getcpu
+474	common	epoll_pwait			sys_epoll_pwait
+475	common	utimensat			sys_utimensat
+476	common	signalfd			sys_signalfd
+477	common	timerfd				sys_ni_syscall
+478	common	eventfd				sys_eventfd
+479	common	recvmmsg			sys_recvmmsg
+480	common	fallocate			sys_fallocate
+481	common	timerfd_create			sys_timerfd_create
+482	common	timerfd_settime			sys_timerfd_settime
+483	common	timerfd_gettime			sys_timerfd_gettime
+484	common	signalfd4			sys_signalfd4
+485	common	eventfd2			sys_eventfd2
+486	common	epoll_create1			sys_epoll_create1
+487	common	dup3				sys_dup3
+488	common	pipe2				sys_pipe2
+489	common	inotify_init1			sys_inotify_init1
+490	common	preadv				sys_preadv
+491	common	pwritev				sys_pwritev
+492	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+493	common	perf_event_open			sys_perf_event_open
+494	common	fanotify_init			sys_fanotify_init
+495	common	fanotify_mark			sys_fanotify_mark
+496	common	prlimit64			sys_prlimit64
+497	common	name_to_handle_at		sys_name_to_handle_at
+498	common	open_by_handle_at		sys_open_by_handle_at
+499	common	clock_adjtime			sys_clock_adjtime
+500	common	syncfs				sys_syncfs
+501	common	setns				sys_setns
+502	common	accept4				sys_accept4
+503	common	sendmmsg			sys_sendmmsg
+504	common	process_vm_readv		sys_process_vm_readv
+505	common	process_vm_writev		sys_process_vm_writev
+506	common	kcmp				sys_kcmp
+507	common	finit_module			sys_finit_module
+508	common	sched_setattr			sys_sched_setattr
+509	common	sched_getattr			sys_sched_getattr
+510	common	renameat2			sys_renameat2
+511	common	getrandom			sys_getrandom
+512	common	memfd_create			sys_memfd_create
+513	common	execveat			sys_execveat
+514	common	seccomp				sys_seccomp
+515	common	bpf				sys_bpf
+516	common	userfaultfd			sys_userfaultfd
+517	common	membarrier			sys_membarrier
+518	common	mlock2				sys_mlock2
+519	common	copy_file_range			sys_copy_file_range
+520	common	preadv2				sys_preadv2
+521	common	pwritev2			sys_pwritev2
+522	common	statx				sys_statx
+523	common	io_pgetevents			sys_io_pgetevents
+524	common	pkey_mprotect			sys_pkey_mprotect
+525	common	pkey_alloc			sys_pkey_alloc
+526	common	pkey_free			sys_pkey_free
+527	common	rseq				sys_rseq
+528	common	statfs64			sys_statfs64
+529	common	fstatfs64			sys_fstatfs64
+530	common	getegid				sys_getegid
+531	common	geteuid				sys_geteuid
+532	common	getppid				sys_getppid
+# all other architectures have common numbers for new syscall, alpha
+# is the exception.
+534	common	pidfd_send_signal		sys_pidfd_send_signal
+535	common	io_uring_setup			sys_io_uring_setup
+536	common	io_uring_enter			sys_io_uring_enter
+537	common	io_uring_register		sys_io_uring_register
+538	common	open_tree			sys_open_tree
+539	common	move_mount			sys_move_mount
+540	common	fsopen				sys_fsopen
+541	common	fsconfig			sys_fsconfig
+542	common	fsmount				sys_fsmount
+543	common	fspick				sys_fspick
+544	common	pidfd_open			sys_pidfd_open
+545	common	clone3				alpha_clone3
+546	common	close_range			sys_close_range
+547	common	openat2				sys_openat2
+548	common	pidfd_getfd			sys_pidfd_getfd
+549	common	faccessat2			sys_faccessat2
+550	common	process_madvise			sys_process_madvise
+551	common	epoll_pwait2			sys_epoll_pwait2
+552	common	mount_setattr			sys_mount_setattr
+553	common	quotactl_fd			sys_quotactl_fd
+554	common	landlock_create_ruleset		sys_landlock_create_ruleset
+555	common	landlock_add_rule		sys_landlock_add_rule
+556	common	landlock_restrict_self		sys_landlock_restrict_self
+# 557 reserved for memfd_secret
+558	common	process_mrelease		sys_process_mrelease
+559	common  futex_waitv                     sys_futex_waitv
+560	common	set_mempolicy_home_node		sys_ni_syscall
+561	common	cachestat			sys_cachestat
+562	common	fchmodat2			sys_fchmodat2
+563	common	map_shadow_stack		sys_map_shadow_stack
+564	common	futex_wake			sys_futex_wake
+565	common	futex_wait			sys_futex_wait
+566	common	futex_requeue			sys_futex_requeue
+567	common	statmount			sys_statmount
+568	common	listmount			sys_listmount
+569	common	lsm_get_self_attr		sys_lsm_get_self_attr
+570	common	lsm_set_self_attr		sys_lsm_set_self_attr
+571	common	lsm_list_modules		sys_lsm_list_modules
+572	common  mseal				sys_mseal
diff --git a/tools/perf/arch/alpha/include/syscall_table.h b/tools/perf/arch/alpha/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..b53e31c15805319a01719c22d489c4037378b02b
--- /dev/null
+++ b/tools/perf/arch/alpha/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index e9e352579e6d33085a1d863441432c81d2353f49..a821df1fd4c0e78c9706304e5b8974cbc5ef4437 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -206,6 +206,7 @@ check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tb
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:08 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:08 -0800
Subject: [PATCH v4 10/16] perf tools: parisc: Support syscall header
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-10-bc8caef2ca8e@rivosinc.com>

parisc uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
 .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
 tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++++
 tools/perf/arch/parisc/include/syscall_table.h     |   8 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 482 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 7528e6acaf3b1cf76198dafe094800fc00fd56eb..c4bd151fb7e4fb14a53998e58afae37599696da3 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/parisc/entry/syscalls/Kbuild b/tools/perf/arch/parisc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..ae326fecb83b307fb5b0a885ae109480aafd586f
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscall_abis_64  +=
+
+syscalltbl = $(srctree)/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/parisc/entry/syscalls/syscall.tbl b/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..66dc406b12e4482832b0e8836b8267b0fb37a5ed
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
@@ -0,0 +1,463 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for parisc
+#
+# The format is:
+# <number> <abi> <name> <entry point> <compat entry point>
+#
+# The <abi> can be common, 64, or 32 for this file.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork_wrapper
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open			compat_sys_open
+6	common	close			sys_close
+7	common	waitpid			sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve			compat_sys_execve
+12	common	chdir			sys_chdir
+13	32	time			sys_time32
+13	64	time			sys_time
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown
+17	common	socket			sys_socket
+18	common	stat			sys_newstat			compat_sys_newstat
+19	common	lseek			sys_lseek			compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+22	common	bind			sys_bind
+23	common	setuid			sys_setuid
+24	common	getuid			sys_getuid
+25	32	stime			sys_stime32
+25	64	stime			sys_stime
+26	common	ptrace			sys_ptrace			compat_sys_ptrace
+27	common	alarm			sys_alarm
+28	common	fstat			sys_newfstat			compat_sys_newfstat
+29	common	pause			sys_pause
+30	32	utime			sys_utime32
+30	64	utime			sys_utime
+31	common	connect			sys_connect
+32	common	listen			sys_listen
+33	common	access			sys_access
+34	common	nice			sys_nice
+35	common	accept			sys_accept
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times			compat_sys_times
+44	common	getsockname		sys_getsockname
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid
+47	common	getgid			sys_getgid
+48	common	signal			sys_signal
+49	common	geteuid			sys_geteuid
+50	common	getegid			sys_getegid
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+53	common	getpeername		sys_getpeername
+54	common	ioctl			sys_ioctl			compat_sys_ioctl
+55	common	fcntl			sys_fcntl			compat_sys_fcntl
+56	common	socketpair		sys_socketpair
+57	common	setpgid			sys_setpgid
+58	common	send			sys_send
+59	common	uname			sys_newuname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat			compat_sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	pivot_root		sys_pivot_root
+68	common	sgetmask		sys_sgetmask			sys32_unimplemented
+69	common	ssetmask		sys_ssetmask			sys32_unimplemented
+70	common	setreuid		sys_setreuid
+71	common	setregid		sys_setregid
+72	common	mincore			sys_mincore
+73	common	sigpending		sys_sigpending			compat_sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit			compat_sys_setrlimit
+76	common	getrlimit		sys_getrlimit			compat_sys_getrlimit
+77	common	getrusage		sys_getrusage			compat_sys_getrusage
+78	common	gettimeofday		sys_gettimeofday		compat_sys_gettimeofday
+79	common	settimeofday		sys_settimeofday		compat_sys_settimeofday
+80	common	getgroups		sys_getgroups
+81	common	setgroups		sys_setgroups
+82	common	sendto			sys_sendto
+83	common	symlink			sys_symlink
+84	common	lstat			sys_newlstat			compat_sys_newlstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_ni_syscall
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+89	common	mmap2			sys_mmap2
+90	common	mmap			sys_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate			compat_sys_truncate
+93	common	ftruncate		sys_ftruncate			compat_sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+98	common	recv			sys_recv			compat_sys_recv
+99	common	statfs			sys_statfs			compat_sys_statfs
+100	common	fstatfs			sys_fstatfs			compat_sys_fstatfs
+101	common	stat64			sys_stat64
+# 102 was socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer			compat_sys_setitimer
+105	common	getitimer		sys_getitimer			compat_sys_getitimer
+106	common	capget			sys_capget
+107	common	capset			sys_capset
+108	32	pread64			parisc_pread64
+108	64	pread64			sys_pread64
+109	32	pwrite64		parisc_pwrite64
+109	64	pwrite64		sys_pwrite64
+110	common	getcwd			sys_getcwd
+111	common	vhangup			sys_vhangup
+112	common	fstat64			sys_fstat64
+113	common	vfork			sys_vfork_wrapper
+114	common	wait4			sys_wait4			compat_sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo			compat_sys_sysinfo
+117	common	shutdown		sys_shutdown
+118	common	fsync			sys_fsync
+119	common	madvise			parisc_madvise
+120	common	clone			sys_clone_wrapper
+121	common	setdomainname		sys_setdomainname
+122	common	sendfile		sys_sendfile			compat_sys_sendfile
+123	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
+124	32	adjtimex		sys_adjtimex_time32
+124	64	adjtimex		sys_adjtimex
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask			compat_sys_sigprocmask
+# 127 was create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	32	personality		parisc_personality
+136	64	personality		sys_personality
+# 137 was afs_syscall
+138	common	setfsuid		sys_setfsuid
+139	common	setfsgid		sys_setfsgid
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents			compat_sys_getdents
+142	common	_newselect		sys_select			compat_sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	32	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+161	64	sched_rr_get_interval	sys_sched_rr_get_interval
+162	32	nanosleep		sys_nanosleep_time32
+162	64	nanosleep		sys_nanosleep
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid
+165	common	getresuid		sys_getresuid
+166	common	sigaltstack		sys_sigaltstack			compat_sys_sigaltstack
+# 167 was query_module
+168	common	poll			sys_poll
+# 169 was nfsservctl
+170	common	setresgid		sys_setresgid
+171	common	getresgid		sys_getresgid
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper
+174	common	rt_sigaction		sys_rt_sigaction		compat_sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending		compat_sys_rt_sigpending
+177	32	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+177	64	rt_sigtimedwait		sys_rt_sigtimedwait
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+180	common	chown			sys_chown
+181	common	setsockopt		sys_setsockopt			sys_setsockopt
+182	common	getsockopt		sys_getsockopt			sys_getsockopt
+183	common	sendmsg			sys_sendmsg			compat_sys_sendmsg
+184	common	recvmsg			sys_recvmsg			compat_sys_recvmsg
+185	common	semop			sys_semop
+186	common	semget			sys_semget
+187	common	semctl			sys_semctl			compat_sys_semctl
+188	common	msgsnd			sys_msgsnd			compat_sys_msgsnd
+189	common	msgrcv			sys_msgrcv			compat_sys_msgrcv
+190	common	msgget			sys_msgget
+191	common	msgctl			sys_msgctl			compat_sys_msgctl
+192	common	shmat			sys_shmat			compat_sys_shmat
+193	common	shmdt			sys_shmdt
+194	common	shmget			sys_shmget
+195	common	shmctl			sys_shmctl			compat_sys_shmctl
+# 196 was getpmsg
+# 197 was putpmsg
+198	common	lstat64			sys_lstat64
+199	32	truncate64		parisc_truncate64
+199	64	truncate64		sys_truncate64
+200	32	ftruncate64		parisc_ftruncate64
+200	64	ftruncate64		sys_ftruncate64
+201	common	getdents64		sys_getdents64
+202	common	fcntl64			sys_fcntl64			compat_sys_fcntl64
+# 203 was attrctl
+# 204 was acl_get
+# 205 was acl_set
+206	common	gettid			sys_gettid
+207	32	readahead		parisc_readahead
+207	64	readahead		sys_readahead
+208	common	tkill			sys_tkill
+209	common	sendfile64		sys_sendfile64			compat_sys_sendfile64
+210	32	futex			sys_futex_time32
+210	64	futex			sys_futex
+211	common	sched_setaffinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+212	common	sched_getaffinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+# 213 was set_thread_area
+# 214 was get_thread_area
+215	common	io_setup		sys_io_setup			compat_sys_io_setup
+216	common	io_destroy		sys_io_destroy
+217	32	io_getevents		sys_io_getevents_time32
+217	64	io_getevents		sys_io_getevents
+218	common	io_submit		sys_io_submit			compat_sys_io_submit
+219	common	io_cancel		sys_io_cancel
+# 220 was alloc_hugepages
+# 221 was free_hugepages
+222	common	exit_group		sys_exit_group
+223	common	lookup_dcookie		sys_ni_syscall
+224	common	epoll_create		sys_epoll_create
+225	common	epoll_ctl		sys_epoll_ctl
+226	common	epoll_wait		sys_epoll_wait
+227	common	remap_file_pages	sys_remap_file_pages
+228	32	semtimedop		sys_semtimedop_time32
+228	64	semtimedop		sys_semtimedop
+229	common	mq_open			sys_mq_open			compat_sys_mq_open
+230	common	mq_unlink		sys_mq_unlink
+231	32	mq_timedsend		sys_mq_timedsend_time32
+231	64	mq_timedsend		sys_mq_timedsend
+232	32	mq_timedreceive		sys_mq_timedreceive_time32
+232	64	mq_timedreceive		sys_mq_timedreceive
+233	common	mq_notify		sys_mq_notify			compat_sys_mq_notify
+234	common	mq_getsetattr		sys_mq_getsetattr		compat_sys_mq_getsetattr
+235	common	waitid			sys_waitid			compat_sys_waitid
+236	32	fadvise64_64		parisc_fadvise64_64
+236	64	fadvise64_64		sys_fadvise64_64
+237	common	set_tid_address		sys_set_tid_address
+238	common	setxattr		sys_setxattr
+239	common	lsetxattr		sys_lsetxattr
+240	common	fsetxattr		sys_fsetxattr
+241	common	getxattr		sys_getxattr
+242	common	lgetxattr		sys_lgetxattr
+243	common	fgetxattr		sys_fgetxattr
+244	common	listxattr		sys_listxattr
+245	common	llistxattr		sys_llistxattr
+246	common	flistxattr		sys_flistxattr
+247	common	removexattr		sys_removexattr
+248	common	lremovexattr		sys_lremovexattr
+249	common	fremovexattr		sys_fremovexattr
+250	common	timer_create		sys_timer_create		compat_sys_timer_create
+251	32	timer_settime		sys_timer_settime32
+251	64	timer_settime		sys_timer_settime
+252	32	timer_gettime		sys_timer_gettime32
+252	64	timer_gettime		sys_timer_gettime
+253	common	timer_getoverrun	sys_timer_getoverrun
+254	common	timer_delete		sys_timer_delete
+255	32	clock_settime		sys_clock_settime32
+255	64	clock_settime		sys_clock_settime
+256	32	clock_gettime		sys_clock_gettime32
+256	64	clock_gettime		sys_clock_gettime
+257	32	clock_getres		sys_clock_getres_time32
+257	64	clock_getres		sys_clock_getres
+258	32	clock_nanosleep		sys_clock_nanosleep_time32
+258	64	clock_nanosleep		sys_clock_nanosleep
+259	common	tgkill			sys_tgkill
+260	common	mbind			sys_mbind
+261	common	get_mempolicy		sys_get_mempolicy
+262	common	set_mempolicy		sys_set_mempolicy
+# 263 was vserver
+264	common	add_key			sys_add_key
+265	common	request_key		sys_request_key
+266	common	keyctl			sys_keyctl			compat_sys_keyctl
+267	common	ioprio_set		sys_ioprio_set
+268	common	ioprio_get		sys_ioprio_get
+269	common	inotify_init		sys_inotify_init
+270	common	inotify_add_watch	sys_inotify_add_watch
+271	common	inotify_rm_watch	sys_inotify_rm_watch
+272	common	migrate_pages		sys_migrate_pages
+273	32	pselect6		sys_pselect6_time32		compat_sys_pselect6_time32
+273	64	pselect6		sys_pselect6
+274	32	ppoll			sys_ppoll_time32		compat_sys_ppoll_time32
+274	64	ppoll			sys_ppoll
+275	common	openat			sys_openat			compat_sys_openat
+276	common	mkdirat			sys_mkdirat
+277	common	mknodat			sys_mknodat
+278	common	fchownat		sys_fchownat
+279	32	futimesat		sys_futimesat_time32
+279	64	futimesat		sys_futimesat
+280	common	fstatat64		sys_fstatat64
+281	common	unlinkat		sys_unlinkat
+282	common	renameat		sys_renameat
+283	common	linkat			sys_linkat
+284	common	symlinkat		sys_symlinkat
+285	common	readlinkat		sys_readlinkat
+286	common	fchmodat		sys_fchmodat
+287	common	faccessat		sys_faccessat
+288	common	unshare			sys_unshare
+289	common	set_robust_list		sys_set_robust_list		compat_sys_set_robust_list
+290	common	get_robust_list		sys_get_robust_list		compat_sys_get_robust_list
+291	common	splice			sys_splice
+292	32	sync_file_range		parisc_sync_file_range
+292	64	sync_file_range		sys_sync_file_range
+293	common	tee			sys_tee
+294	common	vmsplice		sys_vmsplice
+295	common	move_pages		sys_move_pages
+296	common	getcpu			sys_getcpu
+297	common	epoll_pwait		sys_epoll_pwait			compat_sys_epoll_pwait
+298	common	statfs64		sys_statfs64			compat_sys_statfs64
+299	common	fstatfs64		sys_fstatfs64			compat_sys_fstatfs64
+300	common	kexec_load		sys_kexec_load			compat_sys_kexec_load
+301	32	utimensat		sys_utimensat_time32
+301	64	utimensat		sys_utimensat
+302	common	signalfd		sys_signalfd			compat_sys_signalfd
+# 303 was timerfd
+304	common	eventfd			sys_eventfd
+305	32	fallocate		parisc_fallocate
+305	64	fallocate		sys_fallocate
+306	common	timerfd_create		parisc_timerfd_create
+307	32	timerfd_settime		sys_timerfd_settime32
+307	64	timerfd_settime		sys_timerfd_settime
+308	32	timerfd_gettime		sys_timerfd_gettime32
+308	64	timerfd_gettime		sys_timerfd_gettime
+309	common	signalfd4		parisc_signalfd4		parisc_compat_signalfd4
+310	common	eventfd2		parisc_eventfd2
+311	common	epoll_create1		sys_epoll_create1
+312	common	dup3			sys_dup3
+313	common	pipe2			parisc_pipe2
+314	common	inotify_init1		parisc_inotify_init1
+315	common	preadv	sys_preadv	compat_sys_preadv
+316	common	pwritev	sys_pwritev	compat_sys_pwritev
+317	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+318	common	perf_event_open		sys_perf_event_open
+319	32	recvmmsg		sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+319	64	recvmmsg		sys_recvmmsg
+320	common	accept4			sys_accept4
+321	common	prlimit64		sys_prlimit64
+322	common	fanotify_init		sys_fanotify_init
+323	common	fanotify_mark		sys_fanotify_mark		compat_sys_fanotify_mark
+324	32	clock_adjtime		sys_clock_adjtime32
+324	64	clock_adjtime		sys_clock_adjtime
+325	common	name_to_handle_at	sys_name_to_handle_at
+326	common	open_by_handle_at	sys_open_by_handle_at		compat_sys_open_by_handle_at
+327	common	syncfs			sys_syncfs
+328	common	setns			sys_setns
+329	common	sendmmsg		sys_sendmmsg			compat_sys_sendmmsg
+330	common	process_vm_readv	sys_process_vm_readv
+331	common	process_vm_writev	sys_process_vm_writev
+332	common	kcmp			sys_kcmp
+333	common	finit_module		sys_finit_module
+334	common	sched_setattr		sys_sched_setattr
+335	common	sched_getattr		sys_sched_getattr
+336	32	utimes			sys_utimes_time32
+336	64	utimes			sys_utimes
+337	common	renameat2		sys_renameat2
+338	common	seccomp			sys_seccomp
+339	common	getrandom		sys_getrandom
+340	common	memfd_create		sys_memfd_create
+341	common	bpf			sys_bpf
+342	common	execveat		sys_execveat			compat_sys_execveat
+343	common	membarrier		sys_membarrier
+344	common	userfaultfd		parisc_userfaultfd
+345	common	mlock2			sys_mlock2
+346	common	copy_file_range		sys_copy_file_range
+347	common	preadv2			sys_preadv2			compat_sys_preadv2
+348	common	pwritev2		sys_pwritev2			compat_sys_pwritev2
+349	common	statx			sys_statx
+350	32	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+350	64	io_pgetevents		sys_io_pgetevents
+351	common	pkey_mprotect		sys_pkey_mprotect
+352	common	pkey_alloc		sys_pkey_alloc
+353	common	pkey_free		sys_pkey_free
+354	common	rseq			sys_rseq
+355	common	kexec_file_load		sys_kexec_file_load		sys_kexec_file_load
+356	common	cacheflush		sys_cacheflush
+# up to 402 is unassigned and reserved for arch specific syscalls
+403	32	clock_gettime64			sys_clock_gettime		sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime		sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime		sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime		sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime		sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat			sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop			sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3_wrapper
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/parisc/include/syscall_table.h b/tools/perf/arch/parisc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/parisc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index a821df1fd4c0e78c9706304e5b8974cbc5ef4437..ae9f00ae79f34fec75ef2c91300ccd771c030529 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -207,6 +207,7 @@ check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/sy
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
+check_2 tools/perf/arch/parisc/entry/syscalls/syscall.tbl arch/parisc/entry/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:09 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:09 -0800
Subject: [PATCH v4 11/16] perf tools: arm64: Use syscall table
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-11-bc8caef2ca8e@rivosinc.com>

arm64 uses a syscall table, use that in perf instead of using unistd.h.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   3 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/arm64/Makefile                     |  22 -
 tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
 .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
 .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++++
 .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
 tools/perf/arch/arm64/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   2 +
 tools/perf/util/syscalltbl.c                       |   4 -
 11 files changed, 498 insertions(+), 75 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 7accb54e60aac2e615ddf03e8f4ffa8cff539aaa..83ed03f16209b2edff3e81d4e8a79fa058c35a48 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips loongarch))
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -79,7 +79,6 @@ ifeq ($(SRCARCH),arm)
 endif
 
 ifeq ($(SRCARCH),arm64)
-  CFLAGS += -I$(OUTPUT)arch/arm64/include/generated
   ifndef NO_LIBUNWIND
     LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
   endif
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c4bd151fb7e4fb14a53998e58afae37599696da3..bedf58d2a10f1faccb3579c023d5722cfeaae4cf 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
index 91570d5d428e401d940e1c31332ebb40c4b998d8..087e099fb453a9236db34878077a51f711881ce0 100644
--- a/tools/perf/arch/arm64/Makefile
+++ b/tools/perf/arch/arm64/Makefile
@@ -1,25 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/arm64/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/arm64/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, arm64) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/arm64/entry/syscalls/Kbuild b/tools/perf/arch/arm64/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..e7e78c2d1c025b6954a1a22d44a744012e1ca3d4
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 +=
+syscall_abis_64 += renameat rlimit memfd_secret
+
+syscalltbl = $(srctree)/tools/perf/arch/arm64/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 27d747c92d44c04f26ce7aef766a50e3f896f5ff..0000000000000000000000000000000000000000
--- a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-# Changed by: Kim Phillips <kim.phillips at arm.com>
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_ARM64_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_arm64[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl b/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..9a37930d4e26f0c6cb8fe78f76bb1a4f32cbea16
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl
@@ -0,0 +1,476 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# AArch32 (compat) system call definitions.
+#
+# Copyright (C) 2001-2005 Russell King
+# Copyright (C) 2012 ARM Ltd.
+#
+# This file corresponds to arch/arm/tools/syscall.tbl
+# for the native EABI syscalls and should be kept in sync
+# Instead of the OABI syscalls, it contains pointers to
+# the compat entry points where they differ from the native
+# syscalls.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open		compat_sys_open
+6	common	close			sys_close
+# 7 was sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve		compat_sys_execve
+12	common	chdir			sys_chdir
+# 13 was sys_time
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19	common	lseek			sys_lseek		compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+# 22 was sys_umount
+23	common	setuid			sys_setuid16
+24	common	getuid			sys_getuid16
+# 25 was sys_stime
+26	common	ptrace			sys_ptrace		compat_sys_ptrace
+# 27 was sys_alarm
+# 28 was sys_fstat
+29	common	pause			sys_pause
+# 30 was sys_utime
+# 31 was sys_stty
+# 32 was sys_gtty
+33	common	access			sys_access
+34	common	nice			sys_nice
+# 35 was sys_ftime
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times		compat_sys_times
+# 44 was sys_prof
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid16
+47	common	getgid			sys_getgid16
+# 48 was sys_signal
+49	common	geteuid			sys_geteuid16
+50	common	getegid			sys_getegid16
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+# 53 was sys_lock
+54	common	ioctl			sys_ioctl		compat_sys_ioctl
+55	common	fcntl			sys_fcntl		compat_sys_fcntl
+# 56 was sys_mpx
+57	common	setpgid			sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat		compat_sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	sigaction		sys_sigaction		compat_sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70	common	setreuid		sys_setreuid16
+71	common	setregid		sys_setregid16
+72	common	sigsuspend		sys_sigsuspend
+73	common	sigpending		sys_sigpending		compat_sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit		compat_sys_setrlimit
+# 76 was compat_sys_getrlimit
+77	common	getrusage		sys_getrusage		compat_sys_getrusage
+78	common	gettimeofday		sys_gettimeofday	compat_sys_gettimeofday
+79	common	settimeofday		sys_settimeofday	compat_sys_settimeofday
+80	common	getgroups		sys_getgroups16
+81	common	setgroups		sys_setgroups16
+# 82 was compat_sys_select
+83	common	symlink			sys_symlink
+# 84 was sys_lstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_uselib
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+# 89 was sys_readdir
+# 90 was sys_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate		compat_sys_truncate
+93	common	ftruncate		sys_ftruncate		compat_sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown16
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+# 98 was sys_profil
+99	common	statfs			sys_statfs		compat_sys_statfs
+100	common	fstatfs			sys_fstatfs		compat_sys_fstatfs
+# 101 was sys_ioperm
+# 102 was sys_socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer		compat_sys_setitimer
+105	common	getitimer		sys_getitimer		compat_sys_getitimer
+106	common	stat			sys_newstat		compat_sys_newstat
+107	common	lstat			sys_newlstat		compat_sys_newlstat
+108	common	fstat			sys_newfstat		compat_sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111	common	vhangup			sys_vhangup
+# 112 was sys_idle
+# 113 was sys_syscall
+114	common	wait4			sys_wait4		compat_sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo		compat_sys_sysinfo
+# 117 was sys_ipc
+118	common	fsync			sys_fsync
+119	common	sigreturn		sys_sigreturn_wrapper	compat_sys_sigreturn
+120	common	clone			sys_clone
+121	common	setdomainname		sys_setdomainname
+122	common	uname			sys_newuname
+# 123 was sys_modify_ldt
+124	common	adjtimex		sys_adjtimex_time32
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask		compat_sys_sigprocmask
+# 127 was sys_create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was sys_get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	common	personality		sys_personality
+# 137 was sys_afs_syscall
+138	common	setfsuid		sys_setfsuid16
+139	common	setfsgid		sys_setfsgid16
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents		compat_sys_getdents
+142	common	_newselect		sys_select		compat_sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	common	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+162	common	nanosleep		sys_nanosleep_time32
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid16
+165	common	getresuid		sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168	common	poll			sys_poll
+169	common	nfsservctl		sys_ni_syscall
+170	common	setresgid		sys_setresgid16
+171	common	getresgid		sys_getresgid16
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper	compat_sys_rt_sigreturn
+174	common	rt_sigaction		sys_rt_sigaction	compat_sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask	compat_sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending	compat_sys_rt_sigpending
+177	common	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo	compat_sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend	compat_sys_rt_sigsuspend
+180	common	pread64			sys_pread64		compat_sys_aarch32_pread64
+181	common	pwrite64		sys_pwrite64		compat_sys_aarch32_pwrite64
+182	common	chown			sys_chown16
+183	common	getcwd			sys_getcwd
+184	common	capget			sys_capget
+185	common	capset			sys_capset
+186	common	sigaltstack		sys_sigaltstack		compat_sys_sigaltstack
+187	common	sendfile		sys_sendfile		compat_sys_sendfile
+# 188 reserved
+# 189 reserved
+190	common	vfork			sys_vfork
+# SuS compliant getrlimit
+191	common	ugetrlimit		sys_getrlimit		compat_sys_getrlimit
+192	common	mmap2			sys_mmap2		compat_sys_aarch32_mmap2
+193	common	truncate64		sys_truncate64		compat_sys_aarch32_truncate64
+194	common	ftruncate64		sys_ftruncate64		compat_sys_aarch32_ftruncate64
+195	common	stat64			sys_stat64
+196	common	lstat64			sys_lstat64
+197	common	fstat64			sys_fstat64
+198	common	lchown32		sys_lchown
+199	common	getuid32		sys_getuid
+200	common	getgid32		sys_getgid
+201	common	geteuid32		sys_geteuid
+202	common	getegid32		sys_getegid
+203	common	setreuid32		sys_setreuid
+204	common	setregid32		sys_setregid
+205	common	getgroups32		sys_getgroups
+206	common	setgroups32		sys_setgroups
+207	common	fchown32		sys_fchown
+208	common	setresuid32		sys_setresuid
+209	common	getresuid32		sys_getresuid
+210	common	setresgid32		sys_setresgid
+211	common	getresgid32		sys_getresgid
+212	common	chown32			sys_chown
+213	common	setuid32		sys_setuid
+214	common	setgid32		sys_setgid
+215	common	setfsuid32		sys_setfsuid
+216	common	setfsgid32		sys_setfsgid
+217	common	getdents64		sys_getdents64
+218	common	pivot_root		sys_pivot_root
+219	common	mincore			sys_mincore
+220	common	madvise			sys_madvise
+221	common	fcntl64			sys_fcntl64		compat_sys_fcntl64
+# 222 for tux
+# 223 is unused
+224	common	gettid			sys_gettid
+225	common	readahead		sys_readahead		compat_sys_aarch32_readahead
+226	common	setxattr		sys_setxattr
+227	common	lsetxattr		sys_lsetxattr
+228	common	fsetxattr		sys_fsetxattr
+229	common	getxattr		sys_getxattr
+230	common	lgetxattr		sys_lgetxattr
+231	common	fgetxattr		sys_fgetxattr
+232	common	listxattr		sys_listxattr
+233	common	llistxattr		sys_llistxattr
+234	common	flistxattr		sys_flistxattr
+235	common	removexattr		sys_removexattr
+236	common	lremovexattr		sys_lremovexattr
+237	common	fremovexattr		sys_fremovexattr
+238	common	tkill			sys_tkill
+239	common	sendfile64		sys_sendfile64
+240	common	futex			sys_futex_time32
+241	common	sched_setaffinity	sys_sched_setaffinity	compat_sys_sched_setaffinity
+242	common	sched_getaffinity	sys_sched_getaffinity	compat_sys_sched_getaffinity
+243	common	io_setup		sys_io_setup		compat_sys_io_setup
+244	common	io_destroy		sys_io_destroy
+245	common	io_getevents		sys_io_getevents_time32
+246	common	io_submit		sys_io_submit		compat_sys_io_submit
+247	common	io_cancel		sys_io_cancel
+248	common	exit_group		sys_exit_group
+249	common	lookup_dcookie		sys_ni_syscall
+250	common	epoll_create		sys_epoll_create
+251	common	epoll_ctl		sys_epoll_ctl
+252	common	epoll_wait		sys_epoll_wait
+253	common	remap_file_pages	sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256	common	set_tid_address		sys_set_tid_address
+257	common	timer_create		sys_timer_create	compat_sys_timer_create
+258	common	timer_settime		sys_timer_settime32
+259	common	timer_gettime		sys_timer_gettime32
+260	common	timer_getoverrun	sys_timer_getoverrun
+261	common	timer_delete		sys_timer_delete
+262	common	clock_settime		sys_clock_settime32
+263	common	clock_gettime		sys_clock_gettime32
+264	common	clock_getres		sys_clock_getres_time32
+265	common	clock_nanosleep		sys_clock_nanosleep_time32
+266	common	statfs64		sys_statfs64_wrapper	compat_sys_aarch32_statfs64
+267	common	fstatfs64		sys_fstatfs64_wrapper	compat_sys_aarch32_fstatfs64
+268	common	tgkill			sys_tgkill
+269	common	utimes			sys_utimes_time32
+270	common	arm_fadvise64_64	sys_arm_fadvise64_64	compat_sys_aarch32_fadvise64_64
+271	common	pciconfig_iobase	sys_pciconfig_iobase
+272	common	pciconfig_read		sys_pciconfig_read
+273	common	pciconfig_write		sys_pciconfig_write
+274	common	mq_open			sys_mq_open		compat_sys_mq_open
+275	common	mq_unlink		sys_mq_unlink
+276	common	mq_timedsend		sys_mq_timedsend_time32
+277	common	mq_timedreceive		sys_mq_timedreceive_time32
+278	common	mq_notify		sys_mq_notify		compat_sys_mq_notify
+279	common	mq_getsetattr		sys_mq_getsetattr	compat_sys_mq_getsetattr
+280	common	waitid			sys_waitid		compat_sys_waitid
+281	common	socket			sys_socket
+282	common	bind			sys_bind
+283	common	connect			sys_connect
+284	common	listen			sys_listen
+285	common	accept			sys_accept
+286	common	getsockname		sys_getsockname
+287	common	getpeername		sys_getpeername
+288	common	socketpair		sys_socketpair
+289	common	send			sys_send
+290	common	sendto			sys_sendto
+291	common	recv			sys_recv		compat_sys_recv
+292	common	recvfrom		sys_recvfrom		compat_sys_recvfrom
+293	common	shutdown		sys_shutdown
+294	common	setsockopt		sys_setsockopt
+295	common	getsockopt		sys_getsockopt
+296	common	sendmsg			sys_sendmsg		compat_sys_sendmsg
+297	common	recvmsg			sys_recvmsg		compat_sys_recvmsg
+298	common	semop			sys_semop
+299	common	semget			sys_semget
+300	common	semctl			sys_old_semctl		compat_sys_old_semctl
+301	common	msgsnd			sys_msgsnd		compat_sys_msgsnd
+302	common	msgrcv			sys_msgrcv		compat_sys_msgrcv
+303	common	msgget			sys_msgget
+304	common	msgctl			sys_old_msgctl		compat_sys_old_msgctl
+305	common	shmat			sys_shmat		compat_sys_shmat
+306	common	shmdt			sys_shmdt
+307	common	shmget			sys_shmget
+308	common	shmctl			sys_old_shmctl		compat_sys_old_shmctl
+309	common	add_key			sys_add_key
+310	common	request_key		sys_request_key
+311	common	keyctl			sys_keyctl		compat_sys_keyctl
+312	common	semtimedop		sys_semtimedop_time32
+313	common	vserver			sys_ni_syscall
+314	common	ioprio_set		sys_ioprio_set
+315	common	ioprio_get		sys_ioprio_get
+316	common	inotify_init		sys_inotify_init
+317	common	inotify_add_watch	sys_inotify_add_watch
+318	common	inotify_rm_watch	sys_inotify_rm_watch
+319	common	mbind			sys_mbind
+320	common	get_mempolicy		sys_get_mempolicy
+321	common	set_mempolicy		sys_set_mempolicy
+322	common	openat			sys_openat		compat_sys_openat
+323	common	mkdirat			sys_mkdirat
+324	common	mknodat			sys_mknodat
+325	common	fchownat		sys_fchownat
+326	common	futimesat		sys_futimesat_time32
+327	common	fstatat64		sys_fstatat64
+328	common	unlinkat		sys_unlinkat
+329	common	renameat		sys_renameat
+330	common	linkat			sys_linkat
+331	common	symlinkat		sys_symlinkat
+332	common	readlinkat		sys_readlinkat
+333	common	fchmodat		sys_fchmodat
+334	common	faccessat		sys_faccessat
+335	common	pselect6		sys_pselect6_time32	compat_sys_pselect6_time32
+336	common	ppoll			sys_ppoll_time32	compat_sys_ppoll_time32
+337	common	unshare			sys_unshare
+338	common	set_robust_list		sys_set_robust_list	compat_sys_set_robust_list
+339	common	get_robust_list		sys_get_robust_list	compat_sys_get_robust_list
+340	common	splice			sys_splice
+341	common	arm_sync_file_range	sys_sync_file_range2	compat_sys_aarch32_sync_file_range2
+342	common	tee			sys_tee
+343	common	vmsplice		sys_vmsplice
+344	common	move_pages		sys_move_pages
+345	common	getcpu			sys_getcpu
+346	common	epoll_pwait		sys_epoll_pwait		compat_sys_epoll_pwait
+347	common	kexec_load		sys_kexec_load		compat_sys_kexec_load
+348	common	utimensat		sys_utimensat_time32
+349	common	signalfd		sys_signalfd		compat_sys_signalfd
+350	common	timerfd_create		sys_timerfd_create
+351	common	eventfd			sys_eventfd
+352	common	fallocate		sys_fallocate		compat_sys_aarch32_fallocate
+353	common	timerfd_settime		sys_timerfd_settime32
+354	common	timerfd_gettime		sys_timerfd_gettime32
+355	common	signalfd4		sys_signalfd4		compat_sys_signalfd4
+356	common	eventfd2		sys_eventfd2
+357	common	epoll_create1		sys_epoll_create1
+358	common	dup3			sys_dup3
+359	common	pipe2			sys_pipe2
+360	common	inotify_init1		sys_inotify_init1
+361	common	preadv			sys_preadv		compat_sys_preadv
+362	common	pwritev			sys_pwritev		compat_sys_pwritev
+363	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo	compat_sys_rt_tgsigqueueinfo
+364	common	perf_event_open		sys_perf_event_open
+365	common	recvmmsg		sys_recvmmsg_time32	compat_sys_recvmmsg_time32
+366	common	accept4			sys_accept4
+367	common	fanotify_init		sys_fanotify_init
+368	common	fanotify_mark		sys_fanotify_mark	compat_sys_fanotify_mark
+369	common	prlimit64		sys_prlimit64
+370	common	name_to_handle_at	sys_name_to_handle_at
+371	common	open_by_handle_at	sys_open_by_handle_at	compat_sys_open_by_handle_at
+372	common	clock_adjtime		sys_clock_adjtime32
+373	common	syncfs			sys_syncfs
+374	common	sendmmsg		sys_sendmmsg		compat_sys_sendmmsg
+375	common	setns			sys_setns
+376	common	process_vm_readv	sys_process_vm_readv
+377	common	process_vm_writev	sys_process_vm_writev
+378	common	kcmp			sys_kcmp
+379	common	finit_module		sys_finit_module
+380	common	sched_setattr		sys_sched_setattr
+381	common	sched_getattr		sys_sched_getattr
+382	common	renameat2		sys_renameat2
+383	common	seccomp			sys_seccomp
+384	common	getrandom		sys_getrandom
+385	common	memfd_create		sys_memfd_create
+386	common	bpf			sys_bpf
+387	common	execveat		sys_execveat		compat_sys_execveat
+388	common	userfaultfd		sys_userfaultfd
+389	common	membarrier		sys_membarrier
+390	common	mlock2			sys_mlock2
+391	common	copy_file_range		sys_copy_file_range
+392	common	preadv2			sys_preadv2		compat_sys_preadv2
+393	common	pwritev2		sys_pwritev2		compat_sys_pwritev2
+394	common	pkey_mprotect		sys_pkey_mprotect
+395	common	pkey_alloc		sys_pkey_alloc
+396	common	pkey_free		sys_pkey_free
+397	common	statx			sys_statx
+398	common	rseq			sys_rseq
+399	common	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+400	common	migrate_pages		sys_migrate_pages
+401	common	kexec_file_load		sys_kexec_file_load
+# 402 is unused
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	common	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	common	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	common	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl b/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl
new file mode 120000
index 0000000000000000000000000000000000000000..4fdd58f10c155ee45b8d4f6ab1ca4e36ea677c75
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl
@@ -0,0 +1 @@
+../../../../../scripts/syscall.tbl
\ No newline at end of file
diff --git a/tools/perf/arch/arm64/include/syscall_table.h b/tools/perf/arch/arm64/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/arm64/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index ae9f00ae79f34fec75ef2c91300ccd771c030529..d3c6e10dce73f122cfbaa6ca75ea82bec38c6a16 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -208,6 +208,8 @@ check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/sysca
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
 check_2 tools/perf/arch/parisc/entry/syscalls/syscall.tbl arch/parisc/entry/syscalls/syscall.tbl
+check_2 tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl arch/arm64/entry/syscalls/syscall_32.tbl
+check_2 tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl arch/arm64/entry/syscalls/syscall_64.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 02f23483bfff83809c4e649a2d054dba6975d12c..b7c0a4b9245a94b3b245fea59af79081b1f91081 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -26,10 +26,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
 #include <asm/syscalls_32.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
-#elif defined(__aarch64__)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_arm64;
 #elif defined(__mips__)
 #include <asm/syscalls_n64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:10 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:10 -0800
Subject: [PATCH v4 12/16] perf tools: loongarch: Use syscall table
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-12-bc8caef2ca8e@rivosinc.com>

loongarch uses a syscall table, use that in perf instead of using unistd.h.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  3 +-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/loongarch/Makefile                 | 22 -----------
 tools/perf/arch/loongarch/entry/syscalls/Kbuild    |  2 +
 .../loongarch/entry/syscalls/Makefile.syscalls     |  3 ++
 .../arch/loongarch/entry/syscalls/mksyscalltbl     | 45 ----------------------
 tools/perf/arch/loongarch/include/syscall_table.h  |  2 +
 tools/perf/util/syscalltbl.c                       |  4 --
 8 files changed, 9 insertions(+), 74 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 83ed03f16209b2edff3e81d4e8a79fa058c35a48..dd1a5409e65ef38eb4132cd74c2e18dd2c8af920 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips))
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -85,7 +85,6 @@ ifeq ($(SRCARCH),arm64)
 endif
 
 ifeq ($(SRCARCH),loongarch)
-  CFLAGS += -I$(OUTPUT)arch/loongarch/include/generated
   ifndef NO_LIBUNWIND
     LIBUNWIND_LIBS = -lunwind -lunwind-loongarch64
   endif
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index bedf58d2a10f1faccb3579c023d5722cfeaae4cf..c85262db770d18828fc3d9dc65eca00733645d41 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/loongarch/Makefile b/tools/perf/arch/loongarch/Makefile
index 52544d59245bab5a0fb2baa1e962b2ad4bf25332..087e099fb453a9236db34878077a51f711881ce0 100644
--- a/tools/perf/arch/loongarch/Makefile
+++ b/tools/perf/arch/loongarch/Makefile
@@ -1,25 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/loongarch/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/loongarch/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/loongarch/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, loongarch) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Kbuild b/tools/perf/arch/loongarch/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/loongarch/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls b/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..47d32da2aed8d67a7ac026271600e84723031a6b
--- /dev/null
+++ b/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 +=
diff --git a/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl b/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
deleted file mode 100755
index c10ad3580aef25e48ff0682eca4217cbafdfa333..0000000000000000000000000000000000000000
--- a/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Author(s):  Ming Wang <wangming01 at loongson.cn>
-# Author(s):  Huacai Chen <chenhuacai at loongson.cn>
-# Copyright (C) 2020-2023 Loongson Technology Corporation Limited
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_LOONGARCH_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_loongarch[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/loongarch/include/syscall_table.h b/tools/perf/arch/loongarch/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d0646d3455cdaf1a3db8c8565af8eba9a8df8c6
--- /dev/null
+++ b/tools/perf/arch/loongarch/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscall_table_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index b7c0a4b9245a94b3b245fea59af79081b1f91081..3001386e13a502be5279aa6e4742af0b96202b35 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -30,10 +30,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
 #include <asm/syscalls_n64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_mips_n64;
-#elif defined(__loongarch__)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_loongarch;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:11 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:11 -0800
Subject: [PATCH v4 13/16] perf tools: mips: Use generic syscall scripts
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-13-bc8caef2ca8e@rivosinc.com>

Use the generic scripts to generate headers from the syscall table for
mips.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  3 +-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/mips/entry/syscalls/Kbuild         |  2 ++
 .../arch/mips/entry/syscalls/Makefile.syscalls     |  5 ++++
 tools/perf/arch/mips/entry/syscalls/mksyscalltbl   | 32 ----------------------
 tools/perf/arch/mips/include/syscall_table.h       |  2 ++
 tools/perf/util/syscalltbl.c                       |  4 ---
 7 files changed, 11 insertions(+), 39 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index dd1a5409e65ef38eb4132cd74c2e18dd2c8af920..972af3a363c7bbbf5f5226377fea9bd0d306fa38 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390))
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -95,7 +95,6 @@ ifeq ($(ARCH),s390)
 endif
 
 ifeq ($(ARCH),mips)
-  CFLAGS += -I$(OUTPUT)arch/mips/include/generated
   ifndef NO_LIBUNWIND
     LIBUNWIND_LIBS = -lunwind -lunwind-mips
   endif
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c85262db770d18828fc3d9dc65eca00733645d41..74c1097f790cba5abfd1f2fbdaf4e7540c553482 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/mips/entry/syscalls/Kbuild b/tools/perf/arch/mips/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/mips/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls b/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..9ee914bdfb05860fdd37a49f1ced03fcf2c9ed78
--- /dev/null
+++ b/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 += n64
+
+syscalltbl = $(srctree)/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
diff --git a/tools/perf/arch/mips/entry/syscalls/mksyscalltbl b/tools/perf/arch/mips/entry/syscalls/mksyscalltbl
deleted file mode 100644
index c0d93f959c4e1b8c12edcb5624bbc131231df7e3..0000000000000000000000000000000000000000
--- a/tools/perf/arch/mips/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# s390 script.
-#
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Tiezhu Yang <yangtiezhu at loongson.cn>
-
-SYSCALL_TBL=$1
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local max_nr nr abi sc discard
-
-	echo 'static const char *const syscalltbl_mips_n64[] = {'
-	while read nr abi sc discard; do
-		printf '\t[%d] = "%s",\n' $nr $sc
-		max_nr=$nr
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_MIPS_N64_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(n64)" $SYSCALL_TBL	\
-	|sort -k1 -n					\
-	|create_table
diff --git a/tools/perf/arch/mips/include/syscall_table.h b/tools/perf/arch/mips/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..b53e31c15805319a01719c22d489c4037378b02b
--- /dev/null
+++ b/tools/perf/arch/mips/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 3001386e13a502be5279aa6e4742af0b96202b35..675702d686d0d1b53dd3ee2017cc9695686b9c63 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -26,10 +26,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
 #include <asm/syscalls_32.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
-#elif defined(__mips__)
-#include <asm/syscalls_n64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_mips_n64;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:12 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:12 -0800
Subject: [PATCH v4 14/16] perf tools: powerpc: Use generic syscall table
 scripts
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-14-bc8caef2ca8e@rivosinc.com>

Use the generic scripts to generate headers from the syscall table
instead of the custom ones for powerpc.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  3 +-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/powerpc/Makefile                   | 25 --------------
 tools/perf/arch/powerpc/entry/syscalls/Kbuild      |  3 ++
 .../arch/powerpc/entry/syscalls/Makefile.syscalls  |  6 ++++
 .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  | 39 ----------------------
 tools/perf/arch/powerpc/include/syscall_table.h    |  8 +++++
 tools/perf/util/syscalltbl.c                       |  8 -----
 8 files changed, 19 insertions(+), 75 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 972af3a363c7bbbf5f5226377fea9bd0d306fa38..478045f29b04e2f848e76cf86bc8bc457e37b07a 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390))
+  ifeq ($(SRCARCH),s390)
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -49,7 +49,6 @@ endif
 
 # Additional ARCH settings for ppc
 ifeq ($(SRCARCH),powerpc)
-  CFLAGS += -I$(OUTPUT)arch/powerpc/include/generated
   ifndef NO_LIBUNWIND
     LIBUNWIND_LIBS := -lunwind -lunwind-ppc64
   endif
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 74c1097f790cba5abfd1f2fbdaf4e7540c553482..f76b23d96fc91aa56807fc581bf820a117c2bda0 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index dc8f4fb8e324ab6679d78b5fee3636ba7d2ff7c0..a295a80ea078199547e816d18531820bfdba7961 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -1,28 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/powerpc/include/generated/asm
-header32 := $(out)/syscalls_32.c
-header64 := $(out)/syscalls_64.c
-sysprf := $(srctree)/tools/perf/arch/powerpc/entry/syscalls
-sysdef := $(sysprf)/syscall.tbl
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header64): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '64' $(sysdef) > $@
-
-$(header32): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '32' $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, powerpc) $(RM) $(header32) $(header64)
-
-archheaders: $(header32) $(header64)
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Kbuild b/tools/perf/arch/powerpc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/powerpc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..f7e87a61401c14a1d3a8a04fe2c8ecc8bedcc1b0
--- /dev/null
+++ b/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += spu nospu
+syscall_abis_64 += spu nospu
+
+syscalltbl = $(srctree)/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl b/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 0eb316fe6dd1175a86035f76f9f3cf7501c376bd..0000000000000000000000000000000000000000
--- a/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# s390 script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-
-wordsize=$1
-SYSCALL_TBL=$2
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local wordsize=$1
-	local max_nr nr abi sc discard
-	max_nr=-1
-	nr=0
-
-	echo "static const char *const syscalltbl_powerpc_${wordsize}[] = {"
-	while read nr abi sc discard; do
-		if [ "$max_nr" -lt "$nr" ]; then
-			printf '\t[%d] = "%s",\n' $nr $sc
-			max_nr=$nr
-		fi
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_POWERPC_${wordsize}_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(common|spu|nospu|${wordsize})" $SYSCALL_TBL \
-	|sort -k1 -n                                                           \
-	|create_table ${wordsize}
diff --git a/tools/perf/arch/powerpc/include/syscall_table.h b/tools/perf/arch/powerpc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/powerpc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 675702d686d0d1b53dd3ee2017cc9695686b9c63..8869fed1a58946c590484816354d8c74aff52ee3 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -18,14 +18,6 @@
 #include <asm/syscalls_64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_s390_64;
-#elif defined(__powerpc64__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
-#elif defined(__powerpc__)
-#include <asm/syscalls_32.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:13 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:13 -0800
Subject: [PATCH v4 15/16] perf tools: s390: Use generic syscall table
 scripts
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-15-bc8caef2ca8e@rivosinc.com>

Use the generic scripts to generate headers from the syscall table
instead of the custom ones for s390.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  6 +---
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/s390/Makefile                      | 21 --------------
 tools/perf/arch/s390/entry/syscalls/Kbuild         |  2 ++
 .../arch/s390/entry/syscalls/Makefile.syscalls     |  5 ++++
 tools/perf/arch/s390/entry/syscalls/mksyscalltbl   | 32 ----------------------
 tools/perf/arch/s390/include/syscall_table.h       |  2 ++
 tools/perf/util/syscalltbl.c                       |  6 +---
 8 files changed, 12 insertions(+), 64 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 478045f29b04e2f848e76cf86bc8bc457e37b07a..2da9fd705f187a8e4881b3b6ebbe5e0ec8584474 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,10 +31,6 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),s390)
-    NO_SYSCALL_TABLE := 0
-  endif
-
   # architectures that use the generic syscall table scripts
   ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
     NO_SYSCALL_TABLE := 0
@@ -90,7 +86,7 @@ ifeq ($(SRCARCH),loongarch)
 endif
 
 ifeq ($(ARCH),s390)
-  CFLAGS += -fPIC -I$(OUTPUT)arch/s390/include/generated
+  CFLAGS += -fPIC
 endif
 
 ifeq ($(ARCH),mips)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f76b23d96fc91aa56807fc581bf820a117c2bda0..2c6a509c800d3037933c9b49e5a7dafbf78fda0c 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
index c431c21b11ef824535c1b9fb6ca4246d666fc97b..0033698a65ce5d5d7ebcc280399957561dd9d2c6 100644
--- a/tools/perf/arch/s390/Makefile
+++ b/tools/perf/arch/s390/Makefile
@@ -1,24 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/s390/include/generated/asm
-header := $(out)/syscalls_64.c
-sysprf := $(srctree)/tools/perf/arch/s390/entry/syscalls
-sysdef := $(sysprf)/syscall.tbl
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, s390) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/s390/entry/syscalls/Kbuild b/tools/perf/arch/s390/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/s390/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls b/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..9762d7abf17c3f79a6213e7306a5f7b56e833a78
--- /dev/null
+++ b/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 += renameat rlimit memfd_secret
+
+syscalltbl = $(srctree)/tools/perf/arch/s390/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl b/tools/perf/arch/s390/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 52eb88a77c94727aeb8c15427cdd43dfe5f9f2bd..0000000000000000000000000000000000000000
--- a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf
-#
-# Copyright IBM Corp. 2017, 2018
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-#
-
-SYSCALL_TBL=$1
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local max_nr nr abi sc discard
-
-	echo 'static const char *const syscalltbl_s390_64[] = {'
-	while read nr abi sc discard; do
-		printf '\t[%d] = "%s",\n' $nr $sc
-		max_nr=$nr
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_S390_64_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(common|64)" $SYSCALL_TBL	\
-	|sort -k1 -n					\
-	|create_table
diff --git a/tools/perf/arch/s390/include/syscall_table.h b/tools/perf/arch/s390/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..b53e31c15805319a01719c22d489c4037378b02b
--- /dev/null
+++ b/tools/perf/arch/s390/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 8869fed1a58946c590484816354d8c74aff52ee3..210f61b0a7a264a427ebb602185d3a9da2f426f4 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -14,11 +14,7 @@
 #include <string.h>
 #include "string2.h"
 
-#if defined(__s390x__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_s390_64;
-#elif defined(GENERIC_SYSCALL_TABLE)
+#if defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl;

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:14 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:14 -0800
Subject: [PATCH v4 16/16] perf tools: Remove dependency on libaudit
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-16-bc8caef2ca8e@rivosinc.com>

All architectures now support HAVE_SYSCALL_TABLE_SUPPORT, so the flag is
no longer needed. With the removal of the flag, the related
GENERIC_SYSCALL_TABLE can also be removed. libaudit was only used as a
fallback for when HAVE_SYSCALL_TABLE_SUPPORT was not defined, so
libaudit is also no longer needed for any architecture.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 Documentation/admin-guide/workload-tracing.rst |  2 +-
 tools/build/feature/Makefile                   |  4 --
 tools/build/feature/test-libaudit.c            | 11 ------
 tools/perf/Documentation/perf-check.txt        |  1 -
 tools/perf/Makefile.config                     | 31 +--------------
 tools/perf/Makefile.perf                       | 15 --------
 tools/perf/builtin-check.c                     |  1 -
 tools/perf/builtin-help.c                      |  2 -
 tools/perf/builtin-trace.c                     | 30 ---------------
 tools/perf/perf.c                              |  6 +--
 tools/perf/tests/make                          |  7 +---
 tools/perf/util/env.c                          |  4 +-
 tools/perf/util/generate-cmdlist.sh            |  4 +-
 tools/perf/util/syscalltbl.c                   | 52 --------------------------
 tools/perf/util/syscalltbl.h                   |  1 -
 15 files changed, 10 insertions(+), 161 deletions(-)

diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
index b2e254ec8ee846afe78eede74a825b51c6ab119b..6be38c1b9c5bb4be899fd261c6d2911abcf959dc 100644
--- a/Documentation/admin-guide/workload-tracing.rst
+++ b/Documentation/admin-guide/workload-tracing.rst
@@ -83,7 +83,7 @@ scripts/ver_linux is a good way to check if your system already has
 the necessary tools::
 
   sudo apt-get build-essentials flex bison yacc
-  sudo apt install libelf-dev systemtap-sdt-dev libaudit-dev libslang2-dev libperl-dev libdw-dev
+  sudo apt install libelf-dev systemtap-sdt-dev libslang2-dev libperl-dev libdw-dev
 
 cscope is a good tool to browse kernel sources. Let's install it now::
 
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 680f9b07150f906c0bae1ab990cc01bb0d6b0de6..cb1e3e2feedf39d7b95442bafc87d43dc84a740d 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -13,7 +13,6 @@ FILES=                                          \
          test-gtk2.bin                          \
          test-gtk2-infobar.bin                  \
          test-hello.bin                         \
-         test-libaudit.bin                      \
          test-libbfd.bin                        \
          test-libbfd-buildid.bin		\
          test-disassembler-four-args.bin        \
@@ -232,9 +231,6 @@ $(OUTPUT)test-libunwind-debug-frame-arm.bin:
 $(OUTPUT)test-libunwind-debug-frame-aarch64.bin:
 	$(BUILD) -lelf -llzma -lunwind-aarch64
 
-$(OUTPUT)test-libaudit.bin:
-	$(BUILD) -laudit
-
 $(OUTPUT)test-libslang.bin:
 	$(BUILD) -lslang
 
diff --git a/tools/build/feature/test-libaudit.c b/tools/build/feature/test-libaudit.c
deleted file mode 100644
index f5b0863fa1ec240795339428d8deed98a946d405..0000000000000000000000000000000000000000
--- a/tools/build/feature/test-libaudit.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <libaudit.h>
-
-extern int printf(const char *format, ...);
-
-int main(void)
-{
-	printf("error message: %s\n", audit_errno_to_name(0));
-
-	return audit_open();
-}
diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt
index 31741499e7867c9b712227f31a2958fd641d474a..e6d2ceeb2ca7de850f41b1baa0375b6f984bb08f 100644
--- a/tools/perf/Documentation/perf-check.txt
+++ b/tools/perf/Documentation/perf-check.txt
@@ -51,7 +51,6 @@ feature::
                 dwarf_getlocations      /  HAVE_LIBDW_SUPPORT
                 dwarf-unwind            /  HAVE_DWARF_UNWIND_SUPPORT
                 auxtrace                /  HAVE_AUXTRACE_SUPPORT
-                libaudit                /  HAVE_LIBAUDIT_SUPPORT
                 libbfd                  /  HAVE_LIBBFD_SUPPORT
                 libcapstone             /  HAVE_LIBCAPSTONE_SUPPORT
                 libcrypto               /  HAVE_LIBCRYPTO_SUPPORT
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 2da9fd705f187a8e4881b3b6ebbe5e0ec8584474..878e4cec8fdefaf6a7ae3c964d9c62ebd8d1d149 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -28,20 +28,7 @@ include $(srctree)/tools/scripts/Makefile.arch
 
 $(call detected_var,SRCARCH)
 
-ifneq ($(NO_SYSCALL_TABLE),1)
-  NO_SYSCALL_TABLE := 1
-
-  # architectures that use the generic syscall table scripts
-  ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
-    NO_SYSCALL_TABLE := 0
-    CFLAGS += -DGENERIC_SYSCALL_TABLE
-    CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
-  endif
-
-  ifneq ($(NO_SYSCALL_TABLE),1)
-    CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
-  endif
-endif
+CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
 
 # Additional ARCH settings for ppc
 ifeq ($(SRCARCH),powerpc)
@@ -776,21 +763,7 @@ ifndef NO_LIBUNWIND
 endif
 
 ifneq ($(NO_LIBTRACEEVENT),1)
-  ifeq ($(NO_SYSCALL_TABLE),0)
-    $(call detected,CONFIG_TRACE)
-  else
-    ifndef NO_LIBAUDIT
-      $(call feature_check,libaudit)
-      ifneq ($(feature-libaudit), 1)
-        $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev)
-        NO_LIBAUDIT := 1
-      else
-        CFLAGS += -DHAVE_LIBAUDIT_SUPPORT
-        EXTLIBS += -laudit
-        $(call detected,CONFIG_TRACE)
-      endif
-    endif
-  endif
+  $(call detected,CONFIG_TRACE)
 endif
 
 ifndef NO_LIBCRYPTO
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 2c6a509c800d3037933c9b49e5a7dafbf78fda0c..ab2d075ff3a23350a5eea12508cf0376f1d9f4e8 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -59,8 +59,6 @@ include ../scripts/utilities.mak
 #
 # Define NO_LIBNUMA if you do not want numa perf benchmark
 #
-# Define NO_LIBAUDIT if you do not want libaudit support
-#
 # Define NO_LIBBIONIC if you do not want bionic support
 #
 # Define NO_LIBCRYPTO if you do not want libcrypto (openssl) support
@@ -119,10 +117,6 @@ include ../scripts/utilities.mak
 #
 # Define LIBBPF_DYNAMIC to enable libbpf dynamic linking.
 #
-# Define NO_SYSCALL_TABLE=1 to disable the use of syscall id to/from name tables
-# generated from the kernel .tbl or unistd.h files and use, if available, libaudit
-# for doing the conversions to/from strings/id.
-#
 # Define NO_LIBPFM4 to disable libpfm4 events extension.
 #
 # Define NO_LIBDEBUGINFOD if you do not want support debuginfod
@@ -310,11 +304,7 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
 FEATURE_TESTS := all
 endif
 endif
-# architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390
-ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
-endif
 include Makefile.config
 endif
 
@@ -1099,11 +1089,6 @@ endif
 		$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 	$(call QUIET_INSTALL, perf-iostat) \
 		$(INSTALL) $(OUTPUT)perf-iostat -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
-ifndef NO_LIBAUDIT
-	$(call QUIET_INSTALL, strace/groups) \
-		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'; \
-		$(INSTALL) trace/strace/groups/* -m 644 -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'
-endif
 ifndef NO_LIBPERL
 	$(call QUIET_INSTALL, perl-scripts) \
 		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
index 2346536a5ee14f91ecd10bd130a64676e871e1b2..7aed7b9f4f5270527ee1d36327eb6a01f196a46a 100644
--- a/tools/perf/builtin-check.c
+++ b/tools/perf/builtin-check.c
@@ -31,7 +31,6 @@ struct feature_status supported_features[] = {
 	FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT),
 	FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT),
 	FEATURE_STATUS("auxtrace", HAVE_AUXTRACE_SUPPORT),
-	FEATURE_STATUS("libaudit", HAVE_LIBAUDIT_SUPPORT),
 	FEATURE_STATUS("libbfd", HAVE_LIBBFD_SUPPORT),
 	FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT),
 	FEATURE_STATUS("libcrypto", HAVE_LIBCRYPTO_SUPPORT),
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 0854d3cd9f6a304cd9cb50ad430d5706d91df0e9..7be6fb6df595923c15ae51747d5bf17d867ae785 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -447,9 +447,7 @@ int cmd_help(int argc, const char **argv)
 #ifdef HAVE_LIBELF_SUPPORT
 		"probe",
 #endif
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
 		"trace",
-#endif
 	NULL };
 	const char *builtin_help_usage[] = {
 		"perf help [--all] [--man|--web|--info] [command]",
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 3c46de1a8d79bfe64ad6661929f2bdc98ebba55e..80941db5bd48f11236c759babcc1c545149c8e3f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2074,30 +2074,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
 	const char *name = syscalltbl__name(trace->sctbl, id);
 	int err;
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 	if (trace->syscalls.table == NULL) {
 		trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc));
 		if (trace->syscalls.table == NULL)
 			return -ENOMEM;
 	}
-#else
-	if (id > trace->sctbl->syscalls.max_id || (id == 0 && trace->syscalls.table == NULL)) {
-		// When using libaudit we don't know beforehand what is the max syscall id
-		struct syscall *table = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
-
-		if (table == NULL)
-			return -ENOMEM;
-
-		// Need to memset from offset 0 and +1 members if brand new
-		if (trace->syscalls.table == NULL)
-			memset(table, 0, (id + 1) * sizeof(*sc));
-		else
-			memset(table + trace->sctbl->syscalls.max_id + 1, 0, (id - trace->sctbl->syscalls.max_id) * sizeof(*sc));
-
-		trace->syscalls.table	      = table;
-		trace->sctbl->syscalls.max_id = id;
-	}
-#endif
 	sc = trace->syscalls.table + id;
 	if (sc->nonexistent)
 		return -EEXIST;
@@ -2448,18 +2429,7 @@ static struct syscall *trace__syscall_info(struct trace *trace,
 
 	err = -EINVAL;
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 	if (id > trace->sctbl->syscalls.max_id) {
-#else
-	if (id >= trace->sctbl->syscalls.max_id) {
-		/*
-		 * With libaudit we don't know beforehand what is the max_id,
-		 * so we let trace__read_syscall_info() figure that out as we
-		 * go on reading syscalls.
-		 */
-		err = trace__read_syscall_info(trace, id);
-		if (err)
-#endif
 		goto out_cant_read;
 	}
 
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index a2987f2cfe1a3958f53239ed1a4eec3f87d7466a..f0617cc41f5fe638986e5d8316a6b3056c2c4bc5 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -84,7 +84,7 @@ static struct cmd_struct commands[] = {
 #endif
 	{ "kvm",	cmd_kvm,	0 },
 	{ "test",	cmd_test,	0 },
-#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))
+#if defined(HAVE_LIBTRACEEVENT)
 	{ "trace",	cmd_trace,	0 },
 #endif
 	{ "inject",	cmd_inject,	0 },
@@ -514,10 +514,6 @@ int main(int argc, const char **argv)
 		fprintf(stderr,
 			"trace command not available: missing libtraceevent devel package at build time.\n");
 		goto out;
-#elif !defined(HAVE_LIBAUDIT_SUPPORT) && !defined(HAVE_SYSCALL_TABLE_SUPPORT)
-		fprintf(stderr,
-			"trace command not available: missing audit-libs devel package at build time.\n");
-		goto out;
 #else
 		setup_path();
 		argv[0] = "trace";
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index a7fcbd589752a90459815bd21075528c6dfa4d94..0ee94caf9ec19820a94a87dd46a7ccf1cefb844a 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -86,7 +86,6 @@ make_no_libdw_dwarf_unwind := NO_LIBDW_DWARF_UNWIND=1
 make_no_backtrace   := NO_BACKTRACE=1
 make_no_libcapstone := NO_CAPSTONE=1
 make_no_libnuma     := NO_LIBNUMA=1
-make_no_libaudit    := NO_LIBAUDIT=1
 make_no_libbionic   := NO_LIBBIONIC=1
 make_no_auxtrace    := NO_AUXTRACE=1
 make_no_libbpf	    := NO_LIBBPF=1
@@ -97,7 +96,6 @@ make_no_libllvm     := NO_LIBLLVM=1
 make_with_babeltrace:= LIBBABELTRACE=1
 make_with_coresight := CORESIGHT=1
 make_no_sdt	    := NO_SDT=1
-make_no_syscall_tbl := NO_SYSCALL_TABLE=1
 make_no_libpfm4     := NO_LIBPFM4=1
 make_with_gtk2      := GTK2=1
 make_refcnt_check   := EXTRA_CFLAGS="-DREFCNT_CHECKING=1"
@@ -122,10 +120,10 @@ make_static         := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX3
 # all the NO_* variable combined
 make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_GTK2=1
 make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_BACKTRACE=1
-make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
+make_minimal        += NO_LIBNUMA=1 NO_LIBBIONIC=1
 make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
 make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
-make_minimal        += NO_LIBCAP=1 NO_SYSCALL_TABLE=1 NO_CAPSTONE=1
+make_minimal        += NO_LIBCAP=1 NO_CAPSTONE=1
 
 # $(run) contains all available tests
 run := make_pure
@@ -158,7 +156,6 @@ run += make_no_libdw_dwarf_unwind
 run += make_no_backtrace
 run += make_no_libcapstone
 run += make_no_libnuma
-run += make_no_libaudit
 run += make_no_libbionic
 run += make_no_auxtrace
 run += make_no_libbpf
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index 919fe6f205937cea11318fbf53f592aab7578040..be3081ff6204aa80f2855f5e4184e66412627ad3 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -482,13 +482,13 @@ const char *perf_env__arch(struct perf_env *env)
 
 const char *perf_env__arch_strerrno(struct perf_env *env __maybe_unused, int err __maybe_unused)
 {
-#if defined(HAVE_SYSCALL_TABLE_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#if defined(HAVE_LIBTRACEEVENT)
 	if (env->arch_strerrno == NULL)
 		env->arch_strerrno = arch_syscalls__strerrno_function(perf_env__arch(env));
 
 	return env->arch_strerrno ? env->arch_strerrno(err) : "no arch specific strerrno function";
 #else
-	return "!(HAVE_SYSCALL_TABLE_SUPPORT && HAVE_LIBTRACEEVENT)";
+	return "!HAVE_LIBTRACEEVENT";
 #endif
 }
 
diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh
index 1b5140e5ce9975fac87b2674dc694f9d4e439a5f..6a73c903d69050df69267a8aeaeeac1ed170efe1 100755
--- a/tools/perf/util/generate-cmdlist.sh
+++ b/tools/perf/util/generate-cmdlist.sh
@@ -38,7 +38,7 @@ do
 done
 echo "#endif /* HAVE_LIBELF_SUPPORT */"
 
-echo "#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))"
+echo "#if defined(HAVE_LIBTRACEEVENT)"
 sed -n -e 's/^perf-\([^ 	]*\)[ 	].* audit*/\1/p' command-list.txt |
 sort |
 while read cmd
@@ -51,7 +51,7 @@ do
 	    p
      }' "Documentation/perf-$cmd.txt"
 done
-echo "#endif /* HAVE_LIBTRACEEVENT && (HAVE_LIBAUDIT_SUPPORT || HAVE_SYSCALL_TABLE_SUPPORT) */"
+echo "#endif /* HAVE_LIBTRACEEVENT */"
 
 echo "#ifdef HAVE_LIBTRACEEVENT"
 sed -n -e 's/^perf-\([^ 	]*\)[ 	].* traceevent.*/\1/p' command-list.txt |
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 210f61b0a7a264a427ebb602185d3a9da2f426f4..928aca4cd6e9f2f26c5c4fd825b4538c064a4cc3 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -10,20 +10,12 @@
 #include <linux/compiler.h>
 #include <linux/zalloc.h>
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 #include <string.h>
 #include "string2.h"
 
-#if defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl;
-#else
-const int syscalltbl_native_max_id = 0;
-static const char *const syscalltbl_native[] = {
-	[0] = "unknown",
-};
-#endif
 
 struct syscall {
 	int id;
@@ -131,47 +123,3 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
 	*idx = -1;
 	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 }
-
-#else /* HAVE_SYSCALL_TABLE_SUPPORT */
-
-#include <libaudit.h>
-
-struct syscalltbl *syscalltbl__new(void)
-{
-	struct syscalltbl *tbl = zalloc(sizeof(*tbl));
-	if (tbl)
-		tbl->audit_machine = audit_detect_machine();
-	return tbl;
-}
-
-void syscalltbl__delete(struct syscalltbl *tbl)
-{
-	free(tbl);
-}
-
-const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
-{
-	return audit_syscall_to_name(id, tbl->audit_machine);
-}
-
-int syscalltbl__id(struct syscalltbl *tbl, const char *name)
-{
-	return audit_name_to_syscall(name, tbl->audit_machine);
-}
-
-int syscalltbl__id_at_idx(struct syscalltbl *tbl __maybe_unused, int idx)
-{
-	return idx;
-}
-
-int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
-				  const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
-{
-	return -1;
-}
-
-int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
-{
-	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
-}
-#endif /* HAVE_SYSCALL_TABLE_SUPPORT */
diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h
index 2b53b7ed25a6affefd3d85012198eab2f2af550c..362411a6d849b1f67ec54b34345364c04ad90f89 100644
--- a/tools/perf/util/syscalltbl.h
+++ b/tools/perf/util/syscalltbl.h
@@ -3,7 +3,6 @@
 #define __PERF_SYSCALLTBL_H
 
 struct syscalltbl {
-	int audit_machine;
 	struct {
 		int max_id;
 		int nr_entries;

-- 
2.34.1



From christian.bruel at foss.st.com  Wed Dec 18 01:21:48 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 18 Dec 2024 10:21:48 +0100
Subject: [PATCH v2 4/5] PCI: stm32: Add PCIe endpoint support for
 STM32MP25
In-Reply-To: <20241218090834.bz5htywl3sjbzq6w@thinkpad>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-5-christian.bruel@foss.st.com>
 <20241203152230.5mdrt27u5u5ecwcz@thinkpad>
 <4e257489-4d90-4e47-a4d9-a2444627c356@foss.st.com>
 <20241216161700.dtldi7fari6kafrr@thinkpad>
 <fdc487c4-cbdc-45ac-a79f-aff2b8ccafcc@foss.st.com>
 <20241218090834.bz5htywl3sjbzq6w@thinkpad>
Message-ID: <3f060b95-53c7-46b5-b65a-c594cd8d6050@foss.st.com>



On 12/18/24 10:08, Manivannan Sadhasivam wrote:
> On Tue, Dec 17, 2024 at 10:48:43AM +0100, Christian Bruel wrote:
>>
>>
>> On 12/16/24 17:17, Manivannan Sadhasivam wrote:
>>> On Mon, Dec 16, 2024 at 11:02:07AM +0100, Christian Bruel wrote:
>>>> Hi Manivanna,
>>>>
>>>> On 12/3/24 16:22, Manivannan Sadhasivam wrote:
>>>>> On Tue, Nov 26, 2024 at 04:51:18PM +0100, Christian Bruel wrote:
>>>>>
>>>>> [...]
>>>>>
>>>>>> +static int stm32_pcie_start_link(struct dw_pcie *pci)
>>>>>> +{
>>>>>> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
>>>>>> +	int ret;
>>>>>> +
>>>>>> +	if (stm32_pcie->link_status == STM32_PCIE_EP_LINK_ENABLED) {
>>>>>> +		dev_dbg(pci->dev, "Link is already enabled\n");
>>>>>> +		return 0;
>>>>>> +	}
>>>>>> +
>>>>>> +	ret = stm32_pcie_enable_link(pci);
>>>>>> +	if (ret) {
>>>>>> +		dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret);
>>>>>> +		return ret;
>>>>>> +	}
>>>>>
>>>>> How the REFCLK is supplied to the endpoint? From host or generated locally?
>>>>
>>>>   From Host only, we don't support the separated clock model.
>>>>
>>>
>>> OK. So even without refclk you are still able to access the controller
>>> registers? So the controller CSRs should be accessible by separate local clock I
>>> believe.
>>>
>>> Anyhow, please add this limitation (refclk dependency from host) in commit
>>> message.
>>>
>>> [...]
>>>
>>>>>> +	ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE);
>>>>>
>>>>> Hmm, so PHY mode is common for both endpoint and host?
>>>>
>>>> Yes it is. We need to init the phy here because it is a clock source for the
>>>> PCIe core clk
>>>>
>>>
>>> Clock source? Is it coming directly to PCIe or through RCC? There is no direct
>>> clock representation from PHY to PCIe in DT binding.
>>
>> The core_clk is generated directly by the PLL in the COMBOPHY, gated by the
>> RCC
>>
> 
> In that case, phy should be the clock provider to RCC and PCIe should get the
> gated clock it.

ok, seems sensible.



> 
> - Mani
> 


From krzk at kernel.org  Wed Dec 18 01:29:28 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 10:29:28 +0100
Subject: [PATCH v5 1/3] dt-bindings: mailbox: add google,gs101-mbox
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-1-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
 <20241217-acpm-v4-upstream-mbox-v5-1-cd1d3951fe84@linaro.org>
Message-ID: <wlvvuq2ldv4funye2ylnccq7soyrqkqggg36oimnvmhxbbjvnl@yyy4y5nyruzn>

On Tue, Dec 17, 2024 at 09:40:20AM +0000, Tudor Ambarus wrote:
> +description: |
> +  The samsung exynos mailbox controller has 16 flag bits for hardware interrupt

If there is going to be any new posting:

The Samsung Exynos mailbox controller, used on Google GS101 SoC, ....

> +  generation and a shared register for passing mailbox messages. When the
> +  controller is used by the ACPM protocol the shared register is ignored and
> +  the mailbox controller acts as a doorbell. The controller just raises the
> +  interrupt to the firmware after the ACPM protocol has written the message to
> +  SRAM.
> +
> +properties:
> +  compatible:
> +    const: google,gs101-mbox
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    items:
> +      - const: pclk
> +
> +  interrupts:
> +    description: IRQ line for the RX mailbox.
> +    maxItems: 1
> +
> +  '#mbox-cells':
> +    description: |
> +      <&phandle type channel>
> +      phandle : label name of controller.
> +      type    : channel type, doorbell or data-transfer.
> +      channel : channel number.
> +
> +      Here is how a client can reference them:
> +      mboxes = <&ap2apm_mailbox DOORBELL 2>;
> +      mboxes = <&ap2apm_mailbox DATA 3>;

This ordering assumes there is channel "2" in doorbel and in data, so
two times "2" and of course the same for all others. If this is
configuration of one channel, so "2" is either doorbell or data, then
type should be the last.

With that assumption:

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

Best regards,
Krzysztof



From ivo.ivanov.ivanov1 at gmail.com  Wed Dec 18 01:30:31 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Wed, 18 Dec 2024 11:30:31 +0200
Subject: [PATCH v1 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <3fb8ba3f-3016-4823-bf48-130f173c8f66@kernel.org>
References: <20241214220419.723100-1-ivo.ivanov.ivanov1@gmail.com>
 <20241214220419.723100-2-ivo.ivanov.ivanov1@gmail.com>
 <0ebc12ed-fe91-4c8a-a626-b735b0eeecf1@kernel.org>
 <007559c5-f566-4625-99b7-e761a916fba3@gmail.com>
 <cccca881-dd59-43c0-9072-dcd91d01671d@kernel.org>
 <6e93d59d-71e5-4c09-862f-55b5504121aa@gmail.com>
 <69fd1dbc-a29f-488c-a30f-7e5ea8f01a23@kernel.org>
 <17fbfcdd-8b79-4907-a4c8-798da0ef0526@gmail.com>
 <56c5788a-2d49-4abb-af4b-65a11bdc4094@kernel.org>
 <d8d0a1c8-f2b4-425a-858b-610ae7291ebc@gmail.com>
 <3fb8ba3f-3016-4823-bf48-130f173c8f66@kernel.org>
Message-ID: <80d33e99-6a04-4985-b704-42d731313d9f@gmail.com>

On 12/18/24 11:22, Krzysztof Kozlowski wrote:
> On 17/12/2024 11:04, Ivaylo Ivanov wrote:
>> On 12/17/24 11:43, Krzysztof Kozlowski wrote:
>>> On 17/12/2024 10:31, Ivaylo Ivanov wrote:
>>>> On 12/17/24 11:26, Krzysztof Kozlowski wrote:
>>>>> On 17/12/2024 10:08, Ivaylo Ivanov wrote:
>>>>>>>>>>        - items:
>>>>>>>>>>            - enum:
>>>>>>>>>> @@ -94,9 +95,28 @@ allOf:
>>>>>>>>>>          - clock-names
>>>>>>>>>>  
>>>>>>>>>>      else:
>>>>>>>>>> -      properties:
>>>>>>>>>> -        clocks:
>>>>>>>>>> -          maxItems: 1
>>>>>>>>>> +      if:
>>>>>>>>>> +        properties:
>>>>>>>>>> +          compatible:
>>>>>>>>>> +            contains:
>>>>>>>>>> +              enum:
>>>>>>>>>> +                - samsung,exynos8895-hsi2c
>>>>>>>>>> +
>>>>>>>>>> +      then:
>>>>>>>>>> +        properties:
>>>>>>>>>> +          clocks:
>>>>>>>>> Missing minItems
>>>>>>>>>
>>>>>>>>>> +            maxItems: 2
>>>>>>>>>> +
>>>>>>>>>> +          clock-names:
>>>>>>>>> Ditto
>>>>>>>>>
>>>>>>>>>> +            maxItems: 2
>>>>>>>>>> +
>>>>>>>>>> +        required:
>>>>>>>>>> +          - clock-names
>>>>>>>>> I don't understand why do you need second, same branch in if, basically
>>>>>>>> Because, as I stated in the commit message, we have HSI2C controllers
>>>>>>>> both implemented in USIv1 blocks and outside. These that are a part of
>>>>>>> On Exynos8895? Where? With the same compatible?
>>>>>> hsi2c_0 which has a clock from BUSC and hsi2c_1 to hsi2c_4 which use clocks
>>>>>> from PERIC1 (CLK_GOUT_PERIC1_HSI2C_CAM{0,1,2,3}_IPCLK). Why would
>>>>>> they need a different compatible though? It's functionally the same i2c design
>>>>>> as the one implemented in USIv1 blocks.
>>>>> If one block is part of USI and other not, they might not be the same
>>>>> I2C blocks, even if interface is similar. If they were the same or even
>>>>> functionally the same, they would have the same clock inputs. However
>>>> I see, so in such case I should make samsung,exynos8895-hsi2c-nonusi or
>>>> something like that?
>>>>
>>>>> user manual also suggests that there is only one clock, not two (for
>>>>> both cases), so they could be functionally equivalent but then number of
>>>>> clocks looks incorrect.
>>>> That'd be weird. Both according to downstream and upstream clk driver,
>>>> for the USI-implemented i2cs we have a pclk and an sclk_usi.
>>> Something is not precise here, as usually with Samsung clock topology.
>>>
>>> First, the non-USI instances have the IPCLK as well, e.g. things like
>>> PERIC1_UID_HSI2C_CAM1_IPCLKPORT_iPCLK
>>>
>>> USI have BLK_PERIC0_UID_USI03_IPCLKPORT_i_SCLK_USI, but that's USI
>>> clock, not HSI2C in USI. Datasheet mentions this is UART and SPI special
>>> clock, but not I2C.
>> That's weird. Don't we need the clock enabled in order for the
>> USIv1's HSI2C to work?
> The clock goes to USI, so it is enabled, no?

Yes, and as Markuss said:
"USI PCLK is used for the internal AMBA APB bus clock and the IPCLK
signal is used for the peripheral controller blocks (i2c/spi/uart)."

So perhaps referencing the USI PCLK in the hsi2c driver for USIv2, as
well as USIv1, is a wrong approach and should be dropped/fixed?

Best regards,
Ivo

>
> Best regards,
> Krzysztof



From ada at thorsis.com  Wed Dec 18 01:32:48 2024
From: ada at thorsis.com (Alexander Dahl)
Date: Wed, 18 Dec 2024 10:32:48 +0100
Subject: [PATCH v3 2/2] spi: atmel-quadspi: Add support for sama7g5 QSPI
In-Reply-To: <20241128174316.3209354-3-csokas.bence@prolan.hu>
References: <20241128174316.3209354-1-csokas.bence@prolan.hu>
 <20241128174316.3209354-3-csokas.bence@prolan.hu>
Message-ID: <20241218-appliance-jaws-90773405977a@thorsis.com>

Hello,

sorry for being late to the party, but I have some remarks below ?

Am Thu, Nov 28, 2024 at 06:43:15PM +0100 schrieb Cs?k?s, Bence:
> From: Tudor Ambarus <tudor.ambarus at microchip.com>
> 
> The sama7g5 QSPI controller uses dedicated clocks for the
> QSPI Controller Interface and the QSPI Controller Core, and
> requires synchronization before accessing registers or bit
> fields.
> 
> QSPI_SR.SYNCBSY must be zero before accessing any of the bits:
> QSPI_CR.QSPIEN, QSPI_CR.QSPIDIS, QSPI_CR.SRFRSH, QSPI_CR.SWRST,
> QSPI_CR.UPDCFG, QSPI_CR.STTFR, QSPI_CR.RTOUT, QSPI_CR.LASTXFER.
> 
> Also, the QSPI controller core configuration can be updated by
> writing the QSPI_CR.UPDCFG bit to ?1?. This is needed by the
> following registers: QSPI_MR, QSPI_SCR, QSPI_IAR, QSPI_WICR,
> QSPI_IFR, QSPI_RICR, QSPI_SMR, QSPI_SKR,QSPI_REFRESH, QSPI_WRACNT
> QSPI_PCALCFG.
> 
> The Octal SPI supports frequencies up to 200 MHZ DDR. The need
> for output impedance calibration arises. To avoid the degradation
> of the signal quality, a PAD calibration cell is used to adjust
> the output impedance to the driven I/Os.
> 
> The transmission flow requires different sequences for setting
> the configuration and for the actual transfer, than what is in
> the sama5d2 and sam9x60 versions of the IP. Different interrupts
> are handled. aq->ops->set_cfg() and aq->ops->transfer() are
> introduced to help differentiating the flows.
> 
> Tested single and octal SPI mode with mx66lm1g45g.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> Link: https://lore.kernel.org/r/20211214133404.121739-1-tudor.ambarus at microchip.com
> [varshini.rajendran at microchip.com: Fixed conflicts and ported to 6.1.4]
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> [ csokas.bence: Forward-port to master and address feedback ]
> Signed-off-by: Cs?k?s, Bence <csokas.bence at prolan.hu>
> ---
>  drivers/spi/atmel-quadspi.c | 816 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 798 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
> index c84aefa03ae8..dfb8e36687e8 100644
> --- a/drivers/spi/atmel-quadspi.c
> +++ b/drivers/spi/atmel-quadspi.c
> @@ -11,11 +11,15 @@
>   * This driver is based on drivers/mtd/spi-nor/fsl-quadspi.c from Freescale.
>   */
>  
> +#include <linux/bitfield.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/dmaengine.h>
>  #include <linux/err.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
> +#include <linux/iopoll.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> @@ -34,6 +38,7 @@
>  #define QSPI_IDR     0x0018  /* Interrupt Disable Register */
>  #define QSPI_IMR     0x001c  /* Interrupt Mask Register */
>  #define QSPI_SCR     0x0020  /* Serial Clock Register */
> +#define QSPI_SR2     0x0024  /* SAMA7G5 Status Register */
>  
>  #define QSPI_IAR     0x0030  /* Instruction Address Register */
>  #define QSPI_ICR     0x0034  /* Instruction Code Register */
> @@ -44,16 +49,32 @@
>  #define QSPI_SMR     0x0040  /* Scrambling Mode Register */
>  #define QSPI_SKR     0x0044  /* Scrambling Key Register */
>  
> +#define QSPI_REFRESH	0x0050	/* Refresh Register */
> +#define QSPI_WRACNT	0x0054	/* Write Access Counter Register */
> +#define QSPI_DLLCFG	0x0058	/* DLL Configuration Register */
> +#define QSPI_PCALCFG	0x005C	/* Pad Calibration Configuration Register */
> +#define QSPI_PCALBP	0x0060	/* Pad Calibration Bypass Register */
> +#define QSPI_TOUT	0x0064	/* Timeout Register */
> +
>  #define QSPI_WPMR    0x00E4  /* Write Protection Mode Register */
>  #define QSPI_WPSR    0x00E8  /* Write Protection Status Register */
>  
>  #define QSPI_VERSION 0x00FC  /* Version Register */
>  
> +#define SAMA7G5_QSPI0_MAX_SPEED_HZ	200000000
> +#define SAMA7G5_QSPI1_SDR_MAX_SPEED_HZ	133000000
>  
>  /* Bitfields in QSPI_CR (Control Register) */
>  #define QSPI_CR_QSPIEN                  BIT(0)
>  #define QSPI_CR_QSPIDIS                 BIT(1)
> +#define QSPI_CR_DLLON			BIT(2)
> +#define QSPI_CR_DLLOFF			BIT(3)
> +#define QSPI_CR_STPCAL			BIT(4)
> +#define QSPI_CR_SRFRSH			BIT(5)
>  #define QSPI_CR_SWRST                   BIT(7)
> +#define QSPI_CR_UPDCFG			BIT(8)
> +#define QSPI_CR_STTFR			BIT(9)
> +#define QSPI_CR_RTOUT			BIT(10)
>  #define QSPI_CR_LASTXFER                BIT(24)
>  
>  /* Bitfields in QSPI_MR (Mode Register) */
> @@ -61,12 +82,14 @@
>  #define QSPI_MR_LLB                     BIT(1)
>  #define QSPI_MR_WDRBT                   BIT(2)
>  #define QSPI_MR_SMRM                    BIT(3)
> +#define QSPI_MR_DQSDLYEN		BIT(3)
>  #define QSPI_MR_CSMODE_MASK             GENMASK(5, 4)
>  #define QSPI_MR_CSMODE_NOT_RELOADED     (0 << 4)
>  #define QSPI_MR_CSMODE_LASTXFER         (1 << 4)
>  #define QSPI_MR_CSMODE_SYSTEMATICALLY   (2 << 4)
>  #define QSPI_MR_NBBITS_MASK             GENMASK(11, 8)
>  #define QSPI_MR_NBBITS(n)               ((((n) - 8) << 8) & QSPI_MR_NBBITS_MASK)
> +#define QSPI_MR_OENSD			BIT(15)
>  #define QSPI_MR_DLYBCT_MASK             GENMASK(23, 16)
>  #define QSPI_MR_DLYBCT(n)               (((n) << 16) & QSPI_MR_DLYBCT_MASK)
>  #define QSPI_MR_DLYCS_MASK              GENMASK(31, 24)
> @@ -80,6 +103,13 @@
>  #define QSPI_SR_CSR                     BIT(8)
>  #define QSPI_SR_CSS                     BIT(9)
>  #define QSPI_SR_INSTRE                  BIT(10)
> +#define QSPI_SR_LWRA			BIT(11)
> +#define QSPI_SR_QITF			BIT(12)
> +#define QSPI_SR_QITR			BIT(13)
> +#define QSPI_SR_CSFA			BIT(14)
> +#define QSPI_SR_CSRA			BIT(15)
> +#define QSPI_SR_RFRSHD			BIT(16)
> +#define QSPI_SR_TOUT			BIT(17)
>  #define QSPI_SR_QSPIENS                 BIT(24)
>  
>  #define QSPI_SR_CMD_COMPLETED	(QSPI_SR_INSTRE | QSPI_SR_CSR)
> @@ -92,9 +122,22 @@
>  #define QSPI_SCR_DLYBS_MASK             GENMASK(23, 16)
>  #define QSPI_SCR_DLYBS(n)               (((n) << 16) & QSPI_SCR_DLYBS_MASK)
>  
> +/* Bitfields in QSPI_SR2 (SAMA7G5 Status Register) */
> +#define QSPI_SR2_SYNCBSY		BIT(0)
> +#define QSPI_SR2_QSPIENS		BIT(1)
> +#define QSPI_SR2_CSS			BIT(2)
> +#define QSPI_SR2_RBUSY			BIT(3)
> +#define QSPI_SR2_HIDLE			BIT(4)
> +#define QSPI_SR2_DLOCK			BIT(5)
> +#define QSPI_SR2_CALBSY			BIT(6)
> +
> +/* Bitfields in QSPI_IAR (Instruction Address Register) */
> +#define QSPI_IAR_ADDR			GENMASK(31, 0)
> +
>  /* Bitfields in QSPI_ICR (Read/Write Instruction Code Register) */
>  #define QSPI_ICR_INST_MASK              GENMASK(7, 0)
>  #define QSPI_ICR_INST(inst)             (((inst) << 0) & QSPI_ICR_INST_MASK)
> +#define QSPI_ICR_INST_MASK_SAMA7G5	GENMASK(15, 0)
>  #define QSPI_ICR_OPT_MASK               GENMASK(23, 16)
>  #define QSPI_ICR_OPT(opt)               (((opt) << 16) & QSPI_ICR_OPT_MASK)
>  
> @@ -107,6 +150,9 @@
>  #define QSPI_IFR_WIDTH_QUAD_IO          (4 << 0)
>  #define QSPI_IFR_WIDTH_DUAL_CMD         (5 << 0)
>  #define QSPI_IFR_WIDTH_QUAD_CMD         (6 << 0)
> +#define QSPI_IFR_WIDTH_OCT_OUTPUT	(7 << 0)
> +#define QSPI_IFR_WIDTH_OCT_IO		(8 << 0)
> +#define QSPI_IFR_WIDTH_OCT_CMD		(9 << 0)
>  #define QSPI_IFR_INSTEN                 BIT(4)
>  #define QSPI_IFR_ADDREN                 BIT(5)
>  #define QSPI_IFR_OPTEN                  BIT(6)
> @@ -117,19 +163,60 @@
>  #define QSPI_IFR_OPTL_4BIT              (2 << 8)
>  #define QSPI_IFR_OPTL_8BIT              (3 << 8)
>  #define QSPI_IFR_ADDRL                  BIT(10)
> +#define QSPI_IFR_ADDRL_SAMA7G5		GENMASK(11, 10)
>  #define QSPI_IFR_TFRTYP_MEM		BIT(12)
>  #define QSPI_IFR_SAMA5D2_WRITE_TRSFR	BIT(13)
>  #define QSPI_IFR_CRM                    BIT(14)
> +#define QSPI_IFR_DDREN			BIT(15)
>  #define QSPI_IFR_NBDUM_MASK             GENMASK(20, 16)
>  #define QSPI_IFR_NBDUM(n)               (((n) << 16) & QSPI_IFR_NBDUM_MASK)
> +#define QSPI_IFR_END			BIT(22)
> +#define QSPI_IFR_SMRM			BIT(23)
>  #define QSPI_IFR_APBTFRTYP_READ		BIT(24)	/* Defined in SAM9X60 */
> +#define QSPI_IFR_DQSEN			BIT(25)
> +#define QSPI_IFR_DDRCMDEN		BIT(26)
> +#define QSPI_IFR_HFWBEN			BIT(27)
> +#define QSPI_IFR_PROTTYP		GENMASK(29, 28)
> +#define QSPI_IFR_PROTTYP_STD_SPI	0
> +#define QSPI_IFR_PROTTYP_TWIN_QUAD	1
> +#define QSPI_IFR_PROTTYP_OCTAFLASH	2
> +#define QSPI_IFR_PROTTYP_HYPERFLASH	3
>  
>  /* Bitfields in QSPI_SMR (Scrambling Mode Register) */
>  #define QSPI_SMR_SCREN                  BIT(0)
>  #define QSPI_SMR_RVDIS                  BIT(1)
> +#define QSPI_SMR_SCRKL                  BIT(2)
> +
> +/* Bitfields in QSPI_REFRESH (Refresh Register) */
> +#define QSPI_REFRESH_DELAY_COUNTER	GENMASK(31, 0)
> +
> +/* Bitfields in QSPI_WRACNT (Write Access Counter Register) */
> +#define QSPI_WRACNT_NBWRA		GENMASK(31, 0)
> +
> +/* Bitfields in QSPI_DLLCFG (DLL Configuration Register) */
> +#define QSPI_DLLCFG_RANGE		BIT(0)
> +
> +/* Bitfields in QSPI_PCALCFG (DLL Pad Calibration Configuration Register) */
> +#define QSPI_PCALCFG_AAON		BIT(0)
> +#define QSPI_PCALCFG_DAPCAL		BIT(1)
> +#define QSPI_PCALCFG_DIFFPM		BIT(2)
> +#define QSPI_PCALCFG_CLKDIV		GENMASK(6, 4)
> +#define QSPI_PCALCFG_CALCNT		GENMASK(16, 8)
> +#define QSPI_PCALCFG_CALP		GENMASK(27, 24)
> +#define QSPI_PCALCFG_CALN		GENMASK(31, 28)
> +
> +/* Bitfields in QSPI_PCALBP (DLL Pad Calibration Bypass Register) */
> +#define QSPI_PCALBP_BPEN		BIT(0)
> +#define QSPI_PCALBP_CALPBP		GENMASK(11, 8)
> +#define QSPI_PCALBP_CALNBP		GENMASK(19, 16)
> +
> +/* Bitfields in QSPI_TOUT (Timeout Register) */
> +#define QSPI_TOUT_TCNTM			GENMASK(15, 0)
>  
>  /* Bitfields in QSPI_WPMR (Write Protection Mode Register) */
>  #define QSPI_WPMR_WPEN                  BIT(0)
> +#define QSPI_WPMR_WPITEN		BIT(1)
> +#define QSPI_WPMR_WPCREN		BIT(2)
>  #define QSPI_WPMR_WPKEY_MASK            GENMASK(31, 8)
>  #define QSPI_WPMR_WPKEY(wpkey)          (((wpkey) << 8) & QSPI_WPMR_WPKEY_MASK)
>  
> @@ -139,10 +226,42 @@
>  #define QSPI_WPSR_WPVSRC(src)           (((src) << 8) & QSPI_WPSR_WPVSRC)
>  
>  #define ATMEL_QSPI_TIMEOUT		1000	/* ms */
> +#define ATMEL_QSPI_SYNC_TIMEOUT		300	/* ms */
> +#define QSPI_DLLCFG_THRESHOLD_FREQ	90000000U
> +#define QSPI_CALIB_TIME			2000	/* 2 us */
> +
> +/* Use PIO for small transfers. */
> +#define ATMEL_QSPI_DMA_MIN_BYTES	16
> +/**
> + * struct atmel_qspi_pcal - Pad Calibration Clock Division
> + * @pclk_rate: peripheral clock rate.
> + * @pclkdiv: calibration clock division. The clock applied to the calibration
> + *           cell is divided by pclkdiv + 1.
> + */
> +struct atmel_qspi_pcal {
> +	u32 pclk_rate;
> +	u8 pclk_div;
> +};
> +
> +#define ATMEL_QSPI_PCAL_ARRAY_SIZE	8
> +static const struct atmel_qspi_pcal pcal[ATMEL_QSPI_PCAL_ARRAY_SIZE] = {
> +	{25000000, 0},
> +	{50000000, 1},
> +	{75000000, 2},
> +	{100000000, 3},
> +	{125000000, 4},
> +	{150000000, 5},
> +	{175000000, 6},
> +	{200000000, 7},
> +};
>  
>  struct atmel_qspi_caps {
> +	u32 max_speed_hz;
>  	bool has_qspick;
> +	bool has_gclk;
>  	bool has_ricr;
> +	bool octal;
> +	bool has_dma;
>  };
>  
>  struct atmel_qspi_ops;
> @@ -152,6 +271,7 @@ struct atmel_qspi {
>  	void __iomem		*mem;
>  	struct clk		*pclk;
>  	struct clk		*qspick;
> +	struct clk		*gclk;
>  	struct platform_device	*pdev;
>  	const struct atmel_qspi_caps *caps;
>  	const struct atmel_qspi_ops *ops;
> @@ -160,7 +280,12 @@ struct atmel_qspi {
>  	u32			irq_mask;
>  	u32			mr;
>  	u32			scr;
> +	u32			slave_max_speed_hz;
>  	struct completion	cmd_completion;
> +	struct completion	dma_completion;
> +	dma_addr_t		mmap_phys_base;
> +	struct dma_chan		*rx_chan;
> +	struct dma_chan		*tx_chan;
>  };
>  
>  struct atmel_qspi_ops {
> @@ -187,6 +312,19 @@ static const struct atmel_qspi_mode atmel_qspi_modes[] = {
>  	{ 4, 4, 4, QSPI_IFR_WIDTH_QUAD_CMD },
>  };
>  
> +static const struct atmel_qspi_mode atmel_qspi_sama7g5_modes[] = {
> +	{ 1, 1, 1, QSPI_IFR_WIDTH_SINGLE_BIT_SPI },
> +	{ 1, 1, 2, QSPI_IFR_WIDTH_DUAL_OUTPUT },
> +	{ 1, 1, 4, QSPI_IFR_WIDTH_QUAD_OUTPUT },
> +	{ 1, 2, 2, QSPI_IFR_WIDTH_DUAL_IO },
> +	{ 1, 4, 4, QSPI_IFR_WIDTH_QUAD_IO },
> +	{ 2, 2, 2, QSPI_IFR_WIDTH_DUAL_CMD },
> +	{ 4, 4, 4, QSPI_IFR_WIDTH_QUAD_CMD },
> +	{ 1, 1, 8, QSPI_IFR_WIDTH_OCT_OUTPUT },
> +	{ 1, 8, 8, QSPI_IFR_WIDTH_OCT_IO },
> +	{ 8, 8, 8, QSPI_IFR_WIDTH_OCT_CMD },
> +};
> +
>  #ifdef VERBOSE_DEBUG
>  static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz)
>  {
> @@ -209,6 +347,8 @@ static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz)
>  		return "IMR";
>  	case QSPI_SCR:
>  		return "SCR";
> +	case QSPI_SR2:
> +		return "SR2";
>  	case QSPI_IAR:
>  		return "IAR";
>  	case QSPI_ICR:
> @@ -221,6 +361,18 @@ static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz)
>  		return "SMR";
>  	case QSPI_SKR:
>  		return "SKR";
> +	case QSPI_REFRESH:
> +		return "REFRESH";
> +	case QSPI_WRACNT:
> +		return "WRACNT";
> +	case QSPI_DLLCFG:
> +		return "DLLCFG";
> +	case QSPI_PCALCFG:
> +		return "PCALCFG";
> +	case QSPI_PCALBP:
> +		return "PCALBP";
> +	case QSPI_TOUT:
> +		return "TOUT";
>  	case QSPI_WPMR:
>  		return "WPMR";
>  	case QSPI_WPSR:
> @@ -288,12 +440,31 @@ static int atmel_qspi_find_mode(const struct spi_mem_op *op)
>  	return -EOPNOTSUPP;
>  }
>  
> +static int atmel_qspi_sama7g5_find_mode(const struct spi_mem_op *op)
> +{
> +	u32 i;
> +
> +	for (i = 0; i < ARRAY_SIZE(atmel_qspi_sama7g5_modes); i++)
> +		if (atmel_qspi_is_compatible(op, &atmel_qspi_sama7g5_modes[i]))
> +			return i;
> +
> +	return -EOPNOTSUPP;
> +}
> +
>  static bool atmel_qspi_supports_op(struct spi_mem *mem,
>  				   const struct spi_mem_op *op)
>  {
> +	struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller);
>  	if (!spi_mem_default_supports_op(mem, op))
>  		return false;
>  
> +	if (aq->caps->octal) {
> +		if (atmel_qspi_sama7g5_find_mode(op) < 0)
> +			return false;
> +		else
> +			return true;
> +	}
> +
>  	if (atmel_qspi_find_mode(op) < 0)
>  		return false;
>  
> @@ -467,6 +638,296 @@ static int atmel_qspi_transfer(struct spi_mem *mem,
>  	return atmel_qspi_wait_for_completion(aq, QSPI_SR_CMD_COMPLETED);
>  }
>  
> +static int atmel_qspi_reg_sync(struct atmel_qspi *aq)
> +{
> +	u32 val;
> +	int ret;
> +
> +	ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +				 !(val & QSPI_SR2_SYNCBSY), 40,
> +				 ATMEL_QSPI_SYNC_TIMEOUT);
> +	return ret;
> +}
> +
> +static int atmel_qspi_update_config(struct atmel_qspi *aq)
> +{
> +	int ret;
> +
> +	ret = atmel_qspi_reg_sync(aq);
> +	if (ret)
> +		return ret;
> +	atmel_qspi_write(QSPI_CR_UPDCFG, aq, QSPI_CR);
> +	return atmel_qspi_reg_sync(aq);
> +}
> +
> +static int atmel_qspi_sama7g5_set_cfg(struct atmel_qspi *aq,
> +				      const struct spi_mem_op *op, u32 *offset)
> +{
> +	u32 iar, icr, ifr;
> +	int mode, ret;
> +
> +	iar = 0;
> +	icr = FIELD_PREP(QSPI_ICR_INST_MASK_SAMA7G5, op->cmd.opcode);
> +	ifr = QSPI_IFR_INSTEN;
> +
> +	mode = atmel_qspi_sama7g5_find_mode(op);
> +	if (mode < 0)
> +		return mode;
> +	ifr |= atmel_qspi_sama7g5_modes[mode].config;
> +
> +	if (op->dummy.buswidth && op->dummy.nbytes) {
> +		if (op->addr.dtr && op->dummy.dtr && op->data.dtr)
> +			ifr |= QSPI_IFR_NBDUM(op->dummy.nbytes * 8 /
> +					      (2 * op->dummy.buswidth));
> +		else
> +			ifr |= QSPI_IFR_NBDUM(op->dummy.nbytes * 8 /
> +					      op->dummy.buswidth);
> +	}
> +
> +	if (op->addr.buswidth && op->addr.nbytes) {
> +		ifr |= FIELD_PREP(QSPI_IFR_ADDRL_SAMA7G5, op->addr.nbytes - 1) |
> +		       QSPI_IFR_ADDREN;
> +		iar = FIELD_PREP(QSPI_IAR_ADDR, op->addr.val);
> +	}
> +
> +	if (op->addr.dtr && op->dummy.dtr && op->data.dtr) {
> +		ifr |= QSPI_IFR_DDREN;
> +		if (op->cmd.dtr)
> +			ifr |= QSPI_IFR_DDRCMDEN;
> +
> +		ifr |= QSPI_IFR_DQSEN;
> +	}
> +
> +	if (op->cmd.buswidth == 8 || op->addr.buswidth == 8 ||
> +	    op->data.buswidth == 8)
> +		ifr |= FIELD_PREP(QSPI_IFR_PROTTYP, QSPI_IFR_PROTTYP_OCTAFLASH);
> +
> +	/* offset of the data access in the QSPI memory space */
> +	*offset = iar;
> +
> +	/* Set data enable */
> +	if (op->data.nbytes) {
> +		ifr |= QSPI_IFR_DATAEN;
> +
> +		if (op->addr.nbytes)
> +			ifr |= QSPI_IFR_TFRTYP_MEM;
> +	}
> +
> +	/*
> +	 * If the QSPI controller is set in regular SPI mode, set it in
> +	 * Serial Memory Mode (SMM).
> +	 */
> +	if (aq->mr != QSPI_MR_SMM) {
> +		atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR);
> +		aq->mr = QSPI_MR_SMM;
> +
> +		ret = atmel_qspi_update_config(aq);
> +		if (ret)
> +			return ret;
> +	}

This re-introduces a mistake already fixed with commit 329ca3eed4a9
("spi: atmel-quadspi: Avoid overwriting delay register settings") for
v6.12.  Probably by copy and paste from an older version?

What is done in your code: the shadow copy of the MR register (aq->mr)
is not tested for the single flag QSPI_MR_SMM, and only the flag
updated, but you write two flags to the register and update the
shadow copy with only one flag, without considering the actual
register content, and thus overwriting any other things set in that
register in other places.


> +
> +	/* Clear pending interrupts */
> +	(void)atmel_qspi_read(aq, QSPI_SR);
> +
> +	/* Set QSPI Instruction Frame registers */
> +	if (op->addr.nbytes && !op->data.nbytes)
> +		atmel_qspi_write(iar, aq, QSPI_IAR);
> +
> +	if (op->data.dir == SPI_MEM_DATA_IN) {
> +		atmel_qspi_write(icr, aq, QSPI_RICR);
> +	} else {
> +		atmel_qspi_write(icr, aq, QSPI_WICR);
> +		if (op->data.nbytes)
> +			atmel_qspi_write(FIELD_PREP(QSPI_WRACNT_NBWRA,
> +						    op->data.nbytes),
> +					 aq, QSPI_WRACNT);
> +	}
> +
> +	atmel_qspi_write(ifr, aq, QSPI_IFR);
> +
> +	return atmel_qspi_update_config(aq);
> +}
> +
> +static void atmel_qspi_dma_callback(void *param)
> +{
> +	struct atmel_qspi *aq = param;
> +
> +	complete(&aq->dma_completion);
> +}
> +
> +static int atmel_qspi_dma_xfer(struct atmel_qspi *aq, struct dma_chan *chan,
> +			       dma_addr_t dma_dst, dma_addr_t dma_src,
> +			       unsigned int len)
> +{
> +	struct dma_async_tx_descriptor *tx;
> +	dma_cookie_t cookie;
> +	int ret;
> +
> +	tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src, len,
> +				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +	if (!tx) {
> +		dev_err(&aq->pdev->dev, "device_prep_dma_memcpy error\n");
> +		return -EIO;
> +	}
> +
> +	reinit_completion(&aq->dma_completion);
> +	tx->callback = atmel_qspi_dma_callback;
> +	tx->callback_param = aq;
> +	cookie = tx->tx_submit(tx);
> +	ret = dma_submit_error(cookie);
> +	if (ret) {
> +		dev_err(&aq->pdev->dev, "dma_submit_error %d\n", cookie);
> +		return ret;
> +	}
> +
> +	dma_async_issue_pending(chan);
> +	ret = wait_for_completion_timeout(&aq->dma_completion,
> +					  msecs_to_jiffies(20 * ATMEL_QSPI_TIMEOUT));
> +	if (ret == 0) {
> +		dmaengine_terminate_sync(chan);
> +		dev_err(&aq->pdev->dev, "DMA wait_for_completion_timeout\n");
> +		return -ETIMEDOUT;
> +	}
> +
> +	return 0;
> +}
> +
> +static int atmel_qspi_dma_rx_xfer(struct spi_mem *mem,
> +				  const struct spi_mem_op *op,
> +				  struct sg_table *sgt, loff_t loff)
> +{
> +	struct atmel_qspi *aq =
> +		spi_controller_get_devdata(mem->spi->controller);
> +	struct scatterlist *sg;
> +	dma_addr_t dma_src;
> +	unsigned int i, len;
> +	int ret;
> +
> +	dma_src = aq->mmap_phys_base + loff;
> +
> +	for_each_sg(sgt->sgl, sg, sgt->nents, i) {
> +		len = sg_dma_len(sg);
> +		ret = atmel_qspi_dma_xfer(aq, aq->rx_chan, sg_dma_address(sg),
> +					  dma_src, len);
> +		if (ret)
> +			return ret;
> +		dma_src += len;
> +	}
> +
> +	return 0;
> +}
> +
> +static int atmel_qspi_dma_tx_xfer(struct spi_mem *mem,
> +				  const struct spi_mem_op *op,
> +				  struct sg_table *sgt, loff_t loff)
> +{
> +	struct atmel_qspi *aq =
> +		spi_controller_get_devdata(mem->spi->controller);
> +	struct scatterlist *sg;
> +	dma_addr_t dma_dst;
> +	unsigned int i, len;
> +	int ret;
> +
> +	dma_dst = aq->mmap_phys_base + loff;
> +
> +	for_each_sg(sgt->sgl, sg, sgt->nents, i) {
> +		len = sg_dma_len(sg);
> +		ret = atmel_qspi_dma_xfer(aq, aq->tx_chan, dma_dst,
> +					  sg_dma_address(sg), len);
> +		if (ret)
> +			return ret;
> +		dma_dst += len;
> +	}
> +
> +	return 0;
> +}
> +
> +static int atmel_qspi_dma_transfer(struct spi_mem *mem,
> +				   const struct spi_mem_op *op, loff_t loff)
> +{
> +	struct sg_table sgt;
> +	int ret;
> +
> +	ret = spi_controller_dma_map_mem_op_data(mem->spi->controller, op,
> +						 &sgt);
> +	if (ret)
> +		return ret;
> +
> +	if (op->data.dir == SPI_MEM_DATA_IN)
> +		ret = atmel_qspi_dma_rx_xfer(mem, op, &sgt, loff);
> +	else
> +		ret = atmel_qspi_dma_tx_xfer(mem, op, &sgt, loff);
> +
> +	spi_controller_dma_unmap_mem_op_data(mem->spi->controller, op, &sgt);
> +
> +	return ret;
> +}
> +
> +static int atmel_qspi_sama7g5_transfer(struct spi_mem *mem,
> +				       const struct spi_mem_op *op, u32 offset)
> +{
> +	struct atmel_qspi *aq =
> +		spi_controller_get_devdata(mem->spi->controller);
> +	u32 val;
> +	int ret;
> +
> +	if (!op->data.nbytes) {
> +		/* Start the transfer. */
> +		ret = atmel_qspi_reg_sync(aq);
> +		if (ret)
> +			return ret;
> +		atmel_qspi_write(QSPI_CR_STTFR, aq, QSPI_CR);
> +
> +		return atmel_qspi_wait_for_completion(aq, QSPI_SR_CSRA);
> +	}
> +
> +	/* Send/Receive data. */
> +	if (op->data.dir == SPI_MEM_DATA_IN) {
> +		if (aq->rx_chan && op->addr.nbytes &&
> +		    op->data.nbytes > ATMEL_QSPI_DMA_MIN_BYTES) {
> +			ret = atmel_qspi_dma_transfer(mem, op, offset);
> +			if (ret)
> +				return ret;
> +		} else {
> +			memcpy_fromio(op->data.buf.in, aq->mem + offset,
> +				      op->data.nbytes);
> +		}
> +
> +		if (op->addr.nbytes) {
> +			ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +						 !(val & QSPI_SR2_RBUSY), 40,
> +						 ATMEL_QSPI_SYNC_TIMEOUT);
> +			if (ret)
> +				return ret;
> +		}
> +	} else {
> +		if (aq->tx_chan && op->addr.nbytes &&
> +		    op->data.nbytes > ATMEL_QSPI_DMA_MIN_BYTES) {
> +			ret = atmel_qspi_dma_transfer(mem, op, offset);
> +			if (ret)
> +				return ret;
> +		} else {
> +			memcpy_toio(aq->mem + offset, op->data.buf.out,
> +				    op->data.nbytes);
> +		}
> +
> +		ret = atmel_qspi_wait_for_completion(aq, QSPI_SR_LWRA);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	/* Release the chip-select. */
> +	ret = atmel_qspi_reg_sync(aq);
> +	if (ret) {
> +		pm_runtime_mark_last_busy(&aq->pdev->dev);
> +		pm_runtime_put_autosuspend(&aq->pdev->dev);
> +		return ret;
> +	}
> +	atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
> +
> +	return atmel_qspi_wait_for_completion(aq, QSPI_SR_CSRA);
> +}
> +
>  static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
>  {
>  	struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller);
> @@ -511,6 +972,160 @@ static const struct spi_controller_mem_ops atmel_qspi_mem_ops = {
>  	.get_name = atmel_qspi_get_name
>  };
>  
> +static int atmel_qspi_set_pad_calibration(struct atmel_qspi *aq)
> +{
> +	unsigned long pclk_rate;
> +	u32 status, val;
> +	int i, ret;
> +	u8 pclk_div = 0;
> +
> +	pclk_rate = clk_get_rate(aq->pclk);
> +	if (!pclk_rate)
> +		return -EINVAL;
> +
> +	for (i = 0; i < ATMEL_QSPI_PCAL_ARRAY_SIZE; i++) {
> +		if (pclk_rate <= pcal[i].pclk_rate) {
> +			pclk_div = pcal[i].pclk_div;
> +			break;
> +		}
> +	}
> +
> +	/*
> +	 * Use the biggest divider in case the peripheral clock exceeds
> +	 * 200MHZ.
> +	 */
> +	if (pclk_rate > pcal[ATMEL_QSPI_PCAL_ARRAY_SIZE - 1].pclk_rate)
> +		pclk_div = pcal[ATMEL_QSPI_PCAL_ARRAY_SIZE - 1].pclk_div;
> +
> +	/* Disable QSPI while configuring the pad calibration. */
> +	status = atmel_qspi_read(aq, QSPI_SR2);
> +	if (status & QSPI_SR2_QSPIENS) {
> +		ret = atmel_qspi_reg_sync(aq);
> +		if (ret)
> +			return ret;
> +		atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
> +	}
> +
> +	/*
> +	 * The analog circuitry is not shut down at the end of the calibration
> +	 * and the start-up time is only required for the first calibration
> +	 * sequence, thus increasing performance. Set the delay between the Pad
> +	 * calibration analog circuitry and the calibration request to 2us.
> +	 */
> +	atmel_qspi_write(QSPI_PCALCFG_AAON |
> +			 FIELD_PREP(QSPI_PCALCFG_CLKDIV, pclk_div) |
> +			 FIELD_PREP(QSPI_PCALCFG_CALCNT,
> +				    2 * (pclk_rate / 1000000)),
> +			 aq, QSPI_PCALCFG);
> +
> +	/* DLL On + start calibration. */
> +	atmel_qspi_write(QSPI_CR_DLLON | QSPI_CR_STPCAL, aq, QSPI_CR);
> +
> +	/* Check synchronization status before updating configuration. */
> +	ret =  readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +				  (val & QSPI_SR2_DLOCK) &&
> +				  !(val & QSPI_SR2_CALBSY), 40,
> +				  ATMEL_QSPI_TIMEOUT);
> +
> +	/* Refresh analogic blocks every 1 ms.*/
> +	atmel_qspi_write(FIELD_PREP(QSPI_REFRESH_DELAY_COUNTER,
> +				    aq->slave_max_speed_hz / 1000),
> +			 aq, QSPI_REFRESH);
> +
> +	return ret;
> +}
> +
> +static int atmel_qspi_set_gclk(struct atmel_qspi *aq)
> +{
> +	u32 status, val;
> +	int ret;
> +
> +	/* Disable DLL before setting GCLK */
> +	status = atmel_qspi_read(aq, QSPI_SR2);
> +	if (status & QSPI_SR2_DLOCK) {
> +		atmel_qspi_write(QSPI_CR_DLLOFF, aq, QSPI_CR);
> +
> +		ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +					 !(val & QSPI_SR2_DLOCK), 40,
> +					 ATMEL_QSPI_TIMEOUT);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	if (aq->slave_max_speed_hz > QSPI_DLLCFG_THRESHOLD_FREQ)
> +		atmel_qspi_write(QSPI_DLLCFG_RANGE, aq, QSPI_DLLCFG);
> +	else
> +		atmel_qspi_write(0, aq, QSPI_DLLCFG);
> +
> +	ret = clk_set_rate(aq->gclk, aq->slave_max_speed_hz);
> +	if (ret) {
> +		dev_err(&aq->pdev->dev, "Failed to set generic clock rate.\n");
> +		return ret;
> +	}
> +
> +	/* Enable the QSPI generic clock */
> +	ret = clk_prepare_enable(aq->gclk);
> +	if (ret)
> +		dev_err(&aq->pdev->dev, "Failed to enable generic clock.\n");
> +
> +	return ret;
> +}
> +
> +static int atmel_qspi_sama7g5_init(struct atmel_qspi *aq)
> +{
> +	u32 val;
> +	int ret;
> +
> +	ret = atmel_qspi_set_gclk(aq);
> +	if (ret)
> +		return ret;
> +
> +	if (aq->caps->octal) {
> +		ret = atmel_qspi_set_pad_calibration(aq);
> +		if (ret)
> +			return ret;
> +	} else {
> +		atmel_qspi_write(QSPI_CR_DLLON, aq, QSPI_CR);
> +		ret =  readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +					  (val & QSPI_SR2_DLOCK), 40,
> +					  ATMEL_QSPI_TIMEOUT);
> +	}
> +
> +	/* Set the QSPI controller by default in Serial Memory Mode */
> +	atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR);
> +	aq->mr = QSPI_MR_SMM;

Same here.

This probably breaks atmel_qspi_set_cs_timing() which also updates the
MR register.

Greets
Alex

> +	ret = atmel_qspi_update_config(aq);
> +	if (ret)
> +		return ret;
> +
> +	/* Enable the QSPI controller. */
> +	atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR);
> +	ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +				 val & QSPI_SR2_QSPIENS, 40,
> +				 ATMEL_QSPI_SYNC_TIMEOUT);
> +	if (ret)
> +		return ret;
> +
> +	if (aq->caps->octal) {
> +		ret = readl_poll_timeout(aq->regs + QSPI_SR, val,
> +					 val & QSPI_SR_RFRSHD, 40,
> +					 ATMEL_QSPI_TIMEOUT);
> +	}
> +
> +	atmel_qspi_write(QSPI_TOUT_TCNTM, aq, QSPI_TOUT);
> +	return ret;
> +}
> +
> +static int atmel_qspi_sama7g5_setup(struct spi_device *spi)
> +{
> +	struct atmel_qspi *aq = spi_controller_get_devdata(spi->controller);
> +
> +	/* The controller can communicate with a single slave. */
> +	aq->slave_max_speed_hz = spi->max_speed_hz;
> +
> +	return atmel_qspi_sama7g5_init(aq);
> +}
> +
>  static int atmel_qspi_setup(struct spi_device *spi)
>  {
>  	struct spi_controller *ctrl = spi->controller;
> @@ -525,6 +1140,9 @@ static int atmel_qspi_setup(struct spi_device *spi)
>  	if (!spi->max_speed_hz)
>  		return -EINVAL;
>  
> +	if (aq->caps->has_gclk)
> +		return atmel_qspi_sama7g5_setup(spi);
> +
>  	src_rate = clk_get_rate(aq->pclk);
>  	if (!src_rate)
>  		return -EINVAL;
> @@ -610,8 +1228,18 @@ static int atmel_qspi_set_cs_timing(struct spi_device *spi)
>  	return 0;
>  }
>  
> -static void atmel_qspi_init(struct atmel_qspi *aq)
> +static int atmel_qspi_init(struct atmel_qspi *aq)
>  {
> +	int ret;
> +
> +	if (aq->caps->has_gclk) {
> +		ret = atmel_qspi_reg_sync(aq);
> +		if (ret)
> +			return ret;
> +		atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR);
> +		return 0;
> +	}
> +
>  	/* Reset the QSPI controller */
>  	atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR);
>  
> @@ -621,6 +1249,7 @@ static void atmel_qspi_init(struct atmel_qspi *aq)
>  
>  	/* Enable the QSPI controller */
>  	atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR);
> +	return 0;
>  }
>  
>  static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id)
> @@ -642,11 +1271,59 @@ static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>  
> +static int atmel_qspi_dma_init(struct spi_controller *ctrl)
> +{
> +	struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
> +	int ret;
> +
> +	aq->rx_chan = dma_request_chan(&aq->pdev->dev, "rx");
> +	if (IS_ERR(aq->rx_chan)) {
> +		aq->rx_chan = NULL;
> +		return dev_err_probe(&aq->pdev->dev, PTR_ERR(aq->rx_chan),
> +				     "RX DMA channel is not available\n");
> +	}
> +
> +	aq->tx_chan = dma_request_chan(&aq->pdev->dev, "tx");
> +	if (IS_ERR(aq->tx_chan)) {
> +		ret = dev_err_probe(&aq->pdev->dev, PTR_ERR(aq->tx_chan),
> +				    "TX DMA channel is not available\n");
> +		goto release_rx_chan;
> +	}
> +
> +	ctrl->dma_rx = aq->rx_chan;
> +	ctrl->dma_tx = aq->tx_chan;
> +	init_completion(&aq->dma_completion);
> +
> +	dev_info(&aq->pdev->dev, "Using %s (tx) and %s (rx) for DMA transfers\n",
> +		 dma_chan_name(aq->tx_chan), dma_chan_name(aq->rx_chan));
> +
> +	return 0;
> +
> +release_rx_chan:
> +	dma_release_channel(aq->rx_chan);
> +	aq->rx_chan = NULL;
> +	aq->tx_chan = NULL;
> +	return ret;
> +}
> +
> +static void atmel_qspi_dma_release(struct atmel_qspi *aq)
> +{
> +	if (aq->rx_chan)
> +		dma_release_channel(aq->rx_chan);
> +	if (aq->tx_chan)
> +		dma_release_channel(aq->tx_chan);
> +}
> +
>  static const struct atmel_qspi_ops atmel_qspi_ops = {
>  	.set_cfg = atmel_qspi_set_cfg,
>  	.transfer = atmel_qspi_transfer,
>  };
>  
> +static const struct atmel_qspi_ops atmel_qspi_sama7g5_ops = {
> +	.set_cfg = atmel_qspi_sama7g5_set_cfg,
> +	.transfer = atmel_qspi_sama7g5_transfer,
> +};
> +
>  static int atmel_qspi_probe(struct platform_device *pdev)
>  {
>  	struct spi_controller *ctrl;
> @@ -658,7 +1335,27 @@ static int atmel_qspi_probe(struct platform_device *pdev)
>  	if (!ctrl)
>  		return -ENOMEM;
>  
> +	aq = spi_controller_get_devdata(ctrl);
> +
> +	aq->caps = of_device_get_match_data(&pdev->dev);
> +	if (!aq->caps) {
> +		dev_err(&pdev->dev, "Could not retrieve QSPI caps\n");
> +		return -EINVAL;
> +	}
> +
> +	init_completion(&aq->cmd_completion);
> +	aq->pdev = pdev;
> +
>  	ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD;
> +	if (aq->caps->octal)
> +		ctrl->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL;
> +
> +	if (aq->caps->has_gclk)
> +		aq->ops = &atmel_qspi_sama7g5_ops;
> +	else
> +		aq->ops = &atmel_qspi_ops;
> +
> +	ctrl->max_speed_hz = aq->caps->max_speed_hz;
>  	ctrl->setup = atmel_qspi_setup;
>  	ctrl->set_cs_timing = atmel_qspi_set_cs_timing;
>  	ctrl->bus_num = -1;
> @@ -667,12 +1364,6 @@ static int atmel_qspi_probe(struct platform_device *pdev)
>  	ctrl->dev.of_node = pdev->dev.of_node;
>  	platform_set_drvdata(pdev, ctrl);
>  
> -	aq = spi_controller_get_devdata(ctrl);
> -
> -	init_completion(&aq->cmd_completion);
> -	aq->pdev = pdev;
> -	aq->ops = &atmel_qspi_ops;
> -
>  	/* Map the registers */
>  	aq->regs = devm_platform_ioremap_resource_byname(pdev, "qspi_base");
>  	if (IS_ERR(aq->regs))
> @@ -687,6 +1378,7 @@ static int atmel_qspi_probe(struct platform_device *pdev)
>  				     "missing AHB memory\n");
>  
>  	aq->mmap_size = resource_size(res);
> +	aq->mmap_phys_base = (dma_addr_t)res->start;
>  
>  	/* Get the peripheral clock */
>  	aq->pclk = devm_clk_get(&pdev->dev, "pclk");
> @@ -703,13 +1395,6 @@ static int atmel_qspi_probe(struct platform_device *pdev)
>  		return dev_err_probe(&pdev->dev, err,
>  				     "failed to enable the peripheral clock\n");
>  
> -	aq->caps = of_device_get_match_data(&pdev->dev);
> -	if (!aq->caps) {
> -		dev_err(&pdev->dev, "Could not retrieve QSPI caps\n");
> -		err = -EINVAL;
> -		goto disable_pclk;
> -	}
> -
>  	if (aq->caps->has_qspick) {
>  		/* Get the QSPI system clock */
>  		aq->qspick = devm_clk_get(&pdev->dev, "qspick");
> @@ -726,18 +1411,32 @@ static int atmel_qspi_probe(struct platform_device *pdev)
>  				"failed to enable the QSPI system clock\n");
>  			goto disable_pclk;
>  		}
> +	} else if (aq->caps->has_gclk) {
> +		/* Get the QSPI generic clock */
> +		aq->gclk = devm_clk_get(&pdev->dev, "gclk");
> +		if (IS_ERR(aq->gclk)) {
> +			dev_err(&pdev->dev, "missing Generic clock\n");
> +			err = PTR_ERR(aq->gclk);
> +			goto disable_pclk;
> +		}
> +	}
> +
> +	if (aq->caps->has_dma) {
> +		err = atmel_qspi_dma_init(ctrl);
> +		if (err == -EPROBE_DEFER)
> +			goto disable_qspick;
>  	}
>  
>  	/* Request the IRQ */
>  	irq = platform_get_irq(pdev, 0);
>  	if (irq < 0) {
>  		err = irq;
> -		goto disable_qspick;
> +		goto dma_release;
>  	}
>  	err = devm_request_irq(&pdev->dev, irq, atmel_qspi_interrupt,
>  			       0, dev_name(&pdev->dev), aq);
>  	if (err)
> -		goto disable_qspick;
> +		goto dma_release;
>  
>  	pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
>  	pm_runtime_use_autosuspend(&pdev->dev);
> @@ -745,7 +1444,9 @@ static int atmel_qspi_probe(struct platform_device *pdev)
>  	pm_runtime_enable(&pdev->dev);
>  	pm_runtime_get_noresume(&pdev->dev);
>  
> -	atmel_qspi_init(aq);
> +	err = atmel_qspi_init(aq);
> +	if (err)
> +		goto dma_release;
>  
>  	err = spi_register_controller(ctrl);
>  	if (err) {
> @@ -753,13 +1454,16 @@ static int atmel_qspi_probe(struct platform_device *pdev)
>  		pm_runtime_disable(&pdev->dev);
>  		pm_runtime_set_suspended(&pdev->dev);
>  		pm_runtime_dont_use_autosuspend(&pdev->dev);
> -		goto disable_qspick;
> +		goto dma_release;
>  	}
>  	pm_runtime_mark_last_busy(&pdev->dev);
>  	pm_runtime_put_autosuspend(&pdev->dev);
>  
>  	return 0;
>  
> +dma_release:
> +	if (aq->caps->has_dma)
> +		atmel_qspi_dma_release(aq);
>  disable_qspick:
>  	clk_disable_unprepare(aq->qspick);
>  disable_pclk:
> @@ -768,6 +1472,44 @@ static int atmel_qspi_probe(struct platform_device *pdev)
>  	return err;
>  }
>  
> +static int atmel_qspi_sama7g5_suspend(struct atmel_qspi *aq)
> +{
> +	int ret;
> +	u32 val;
> +
> +	ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +				 !(val & QSPI_SR2_RBUSY) &&
> +				 (val & QSPI_SR2_HIDLE), 40,
> +				 ATMEL_QSPI_SYNC_TIMEOUT);
> +	if (ret)
> +		return ret;
> +
> +	atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
> +	ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +				 !(val & QSPI_SR2_QSPIENS), 40,
> +				 ATMEL_QSPI_SYNC_TIMEOUT);
> +	if (ret)
> +		return ret;
> +
> +	clk_disable_unprepare(aq->gclk);
> +
> +	atmel_qspi_write(QSPI_CR_DLLOFF, aq, QSPI_CR);
> +	ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +				 !(val & QSPI_SR2_DLOCK), 40,
> +				 ATMEL_QSPI_TIMEOUT);
> +	if (ret)
> +		return ret;
> +
> +	ret =  readl_poll_timeout(aq->regs + QSPI_SR2, val,
> +				  !(val & QSPI_SR2_CALBSY), 40,
> +				  ATMEL_QSPI_TIMEOUT);
> +	if (ret)
> +		return ret;
> +
> +	clk_disable_unprepare(aq->pclk);
> +	return 0;
> +}
> +
>  static void atmel_qspi_remove(struct platform_device *pdev)
>  {
>  	struct spi_controller *ctrl = platform_get_drvdata(pdev);
> @@ -778,6 +1520,16 @@ static void atmel_qspi_remove(struct platform_device *pdev)
>  
>  	ret = pm_runtime_get_sync(&pdev->dev);
>  	if (ret >= 0) {
> +		if (aq->caps->has_dma)
> +			atmel_qspi_dma_release(aq);
> +
> +		if (aq->caps->has_gclk) {
> +			ret = atmel_qspi_sama7g5_suspend(aq);
> +			if (ret)
> +				dev_warn(&pdev->dev, "Failed to de-init device on remove: %d\n", ret);
> +			return;
> +		}
> +
>  		atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
>  		clk_disable(aq->qspick);
>  		clk_disable(aq->pclk);
> @@ -808,6 +1560,9 @@ static int __maybe_unused atmel_qspi_suspend(struct device *dev)
>  	if (ret < 0)
>  		return ret;
>  
> +	if (aq->caps->has_gclk)
> +		return atmel_qspi_sama7g5_suspend(aq);
> +
>  	atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
>  
>  	pm_runtime_mark_last_busy(dev);
> @@ -835,6 +1590,9 @@ static int __maybe_unused atmel_qspi_resume(struct device *dev)
>  		return ret;
>  	}
>  
> +	if (aq->caps->has_gclk)
> +		return atmel_qspi_sama7g5_init(aq);
> +
>  	ret = pm_runtime_force_resume(dev);
>  	if (ret < 0)
>  		return ret;
> @@ -890,6 +1648,19 @@ static const struct atmel_qspi_caps atmel_sam9x60_qspi_caps = {
>  	.has_ricr = true,
>  };
>  
> +static const struct atmel_qspi_caps atmel_sama7g5_ospi_caps = {
> +	.max_speed_hz = SAMA7G5_QSPI0_MAX_SPEED_HZ,
> +	.has_gclk = true,
> +	.octal = true,
> +	.has_dma = true,
> +};
> +
> +static const struct atmel_qspi_caps atmel_sama7g5_qspi_caps = {
> +	.max_speed_hz = SAMA7G5_QSPI1_SDR_MAX_SPEED_HZ,
> +	.has_gclk = true,
> +	.has_dma = true,
> +};
> +
>  static const struct of_device_id atmel_qspi_dt_ids[] = {
>  	{
>  		.compatible = "atmel,sama5d2-qspi",
> @@ -899,6 +1670,15 @@ static const struct of_device_id atmel_qspi_dt_ids[] = {
>  		.compatible = "microchip,sam9x60-qspi",
>  		.data = &atmel_sam9x60_qspi_caps,
>  	},
> +	{
> +		.compatible = "microchip,sama7g5-ospi",
> +		.data = &atmel_sama7g5_ospi_caps,
> +	},
> +	{
> +		.compatible = "microchip,sama7g5-qspi",
> +		.data = &atmel_sama7g5_qspi_caps,
> +	},
> +
>  	{ /* sentinel */ }
>  };
>  
> -- 
> 2.34.1
> 
> 
> 


From xianwei.zhao at amlogic.com  Wed Dec 18 01:37:11 2024
From: xianwei.zhao at amlogic.com (Xianwei Zhao)
Date: Wed, 18 Dec 2024 17:37:11 +0800
Subject: [PATCH RFC 2/3] pinctrl: Add driver support for Amlogic SoCs
In-Reply-To: <CACRpkdbuj-_sPpdfcyg3_QNtzt9r7n-0HBGBKgy-rKUMhvGo4w@mail.gmail.com>
References: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
 <20241211-amlogic-pinctrl-v1-2-410727335119@amlogic.com>
 <CACRpkdbuj-_sPpdfcyg3_QNtzt9r7n-0HBGBKgy-rKUMhvGo4w@mail.gmail.com>
Message-ID: <23899c54-14ad-4724-9336-2df6fb485fd6@amlogic.com>

Hi Linus,
    Thanks for your reply.

On 2024/12/17 22:49, Linus Walleij wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Xianwei,
> 
> thanks for your patch!
> 
> On Wed, Dec 11, 2024 at 7:48?AM Xianwei Zhao via B4 Relay
> <devnull+xianwei.zhao.amlogic.com at kernel.org> wrote:
> 
>> From: Xianwei Zhao <xianwei.zhao at amlogic.com>
>>
>> Add a new pinctrl driver for Amlogic SoCs. All future Amlogic
>> SoCs pinctrl drives use this, such A4, A5, S6, S7 etc. To support
>> new Amlogic SoCs, only need to add the corresponding dts file.
>>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
> 
> First: are we sure these new SoCs have nothing in common
> with sunxi? Because then the sunxi code should be reused.
> 
> In any way I recommend:
> 
> - Renaming drivers/pinctrl/sunxi to drivers/pinctrl/amlogic
>    so we keep this sorted by actual vendor, sunxi is apparently
>    yours (AMlogic:s) isn't it?
> 

It isn't. Sunxi is Allwinner SoCs.

> - Also fix MAINTAINERS accordingly.
> 

Sending the official version will be synchronized.

> - Add new driver under drivers/pinctrl/amlogic
> 
> - Do not change the Kconfig symbols for sunxi and
>    we should be fine.
> >> +static int aml_dt_node_to_map(struct pinctrl_dev *pctldev,
>> +                             struct device_node *np,
>> +                             struct pinctrl_map **map,
>> +                             unsigned int *num_maps)
>> +{
>> +       struct aml_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
>> +       const struct aml_pctl_group *grp;
>> +       struct device *dev = info->dev;
>> +       struct pinctrl_map *new_map;
>> +       struct device_node *parent;
>> +       int map_num, i;
>> +
>> +       grp = aml_pctl_find_group_by_name(info, np->name);
>> +       if (!grp) {
>> +               dev_err(dev, "unable to find group for node %pOFn\n", np);
>> +               return -EINVAL;
>> +       }
>> +
>> +       if (grp->num_configs)
>> +               map_num = grp->npins + 1;
>> +       else
>> +               map_num = 1;
>> +       new_map = devm_kcalloc(dev, map_num, sizeof(*new_map), GFP_KERNEL);
>> +       if (!new_map)
>> +               return -ENOMEM;
>> +
>> +       parent = of_get_parent(np);
>> +       if (!parent) {
>> +               devm_kfree(dev, new_map);
>> +               return -EINVAL;
>> +       }
>> +
>> +       *map = new_map;
>> +       *num_maps = map_num;
>> +       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);
>> +
>> +       if (grp->num_configs) {
>> +               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->configs;
>> +                       new_map[i].data.configs.num_configs = grp->num_configs;
>> +               }
>> +       }
>> +
>> +       dev_info(dev, "maps: function %s group %s num %d\n",
>> +                (*map)->data.mux.function, grp->name, map_num);
>> +
>> +       return 0;
>> +}
>> +
>> +static void aml_dt_free_map(struct pinctrl_dev *pctldev,
>> +                           struct pinctrl_map *map, unsigned int num_maps)
>> +{
>> +}
>> +
>> +static void aml_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
>> +                            unsigned int offset)
>> +{
>> +       seq_printf(s, " %s", dev_name(pcdev->dev));
>> +}
>> +
>> +static const struct pinctrl_ops aml_pctrl_ops = {
>> +       .get_groups_count       = aml_get_groups_count,
>> +       .get_group_name         = aml_get_group_name,
>> +       .get_group_pins         = aml_get_group_pins,
>> +       .dt_node_to_map         = aml_dt_node_to_map,
>> +       .dt_free_map            = aml_dt_free_map,
>> +       .pin_dbg_show           = aml_pin_dbg_show,
>> +};
>> +
>> +static int aml_pctl_dt_calculate_pin(struct aml_pinctrl *info,
>> +                                    unsigned int bank_idx, unsigned int offset)
>> +{
>> +       struct aml_gpio_bank *bank;
>> +       int retval = -EINVAL;
>> +       int i;
>> +
>> +       for (i = 0; i < info->nbanks; i++) {
>> +               bank = &info->banks[i];
>> +               if (bank->bank_idx == bank_idx) {
>> +                       if (offset < bank->gpio_chip.ngpio)
>> +                               retval = bank->pin_base + offset;
>> +                       break;
>> +               }
>> +       }
>> +       if (retval == -EINVAL)
>> +               dev_err(info->dev, "pin [bank:%d, offset:%d] is not present\n", bank_idx, offset);
>> +
>> +       return retval;
>> +}
>> +
>> +static int aml_pctl_dt_parse_groups(struct device_node *np,
>> +                                   struct aml_pctl_group *grp,
>> +                                   struct aml_pinctrl *info, int idx)
>> +{
>> +       struct device *dev = info->dev;
>> +       struct aml_pinconf *conf;
>> +       struct property *of_pins;
>> +       unsigned int bank_idx;
>> +       unsigned int offset, npins;
>> +       int i = 0;
>> +       int ret;
>> +
>> +       of_pins = of_find_property(np, "pinmux", NULL);
>> +       if (!of_pins) {
>> +               dev_info(dev, "Missing pinmux property\n");
>> +               return -ENOENT;
>> +       }
>> +
>> +       npins = of_pins->length / sizeof(u32);
>> +       grp->npins = npins;
>> +       grp->name = np->name;
>> +       grp->pins = devm_kcalloc(dev, npins, sizeof(*grp->pins), GFP_KERNEL);
>> +       grp->pin_conf = devm_kcalloc(dev, npins, sizeof(*grp->pin_conf), GFP_KERNEL);
>> +
>> +       if (!grp->pins || !grp->pin_conf)
>> +               return -ENOMEM;
>> +
>> +       ret = pinconf_generic_parse_dt_config(np, info->pctl, &grp->configs,
>> +                                             &grp->num_configs);
> 
> But can't you just move this code around? grp->num_configs give the
> number of configs, so why do you have to go and look up pinmux
> above, can't you just use grp->num_configs instead of of_pins
> and npins above?
> 
They are different.
The of_pins(grp->npins) specifies the mux values for pin-mux register 
and pin index in pinctrl. It can include multiple pins in groups.

The grp->configs and grp->num_configs specify the configuration 
information for all pins of this groups(such as bias-pull-up, 
drive-strength-microamp)

uart-d-pins2{
	pinmux= <AML_PINMUX(AMLOGIC_GPIO_T, 7, AF2)>,
         	<AML_PINMUX(AMLOGIC_GPIO_T, 8, AF2)>,
         	<AML_PINMUX(AMLOGIC_GPIO_T, 9, AF2)>,
         	<AML_PINMUX(AMLOGIC_GPIO_T, 10, AF2)>;
	bias-pull-up;
	drive-strength-microamp = <4000>;
};

>> +static int aml_pctl_parse_functions(struct device_node *np,
>> +                                   struct aml_pinctrl *info, u32 index,
>> +                                   int *grp_index)
>> +{
>> +       struct device *dev = info->dev;
>> +       struct aml_pmx_func *func;
>> +       struct aml_pctl_group *grp;
>> +       int ret, i;
>> +
>> +       func = &info->functions[index];
>> +       func->name = np->name;
>> +       func->ngroups = of_get_child_count(np);
>> +       if (func->ngroups == 0)
>> +               return dev_err_probe(dev, -EINVAL, "No groups defined\n");
>> +
>> +       func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL);
>> +       if (!func->groups)
>> +               return -ENOMEM;
>> +
>> +       i = 0;
>> +       for_each_child_of_node_scoped(np, child) {
>> +               func->groups[i] = child->name;
>> +               grp = &info->groups[*grp_index];
>> +               *grp_index += 1;
>> +               ret = aml_pctl_dt_parse_groups(child, grp, info, i++);
>> +               if (ret)
>> +                       return ret;
>> +       }
>> +       dev_info(dev, "Function[%d\t name:%s,\tgroups:%d]\n", index, func->name, func->ngroups);
>> +
>> +       return 0;
>> +}
>> +
>> +static u32 aml_bank_pins(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "npins", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
>> +
>> +static u32 aml_bank_reg_gpio_offset(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "reg-gpio-offset", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
>> +
>> +static u32 aml_bank_reg_mux_offset(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "reg-mux-offset", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
>> +
>> +static u32 aml_bank_bit_mux_offset(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "bit-mux-offset", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
>> +
>> +static u32 aml_bank_index(struct device_node *np)
>> +{
>> +       u32 value;
>> +
>> +       if (of_property_read_u32(np, "bank-index", &value) < 0)
>> +               return 0;
>> +       else
>> +               return value;
>> +}
> 
> Do we really need helpers for all of this? Can't you just
> open code it, at least if it's just used in one place?
>
  I will delete this function, I will move the logic to where it was called.

>> +static unsigned int aml_count_pins(struct device_node *np)
>> +{
>> +       struct device_node *child;
>> +       unsigned int pins = 0;
>> +
>> +       for_each_child_of_node(np, child) {
>> +               if (of_property_read_bool(child, "gpio-controller"))
>> +                       pins += aml_bank_pins(child);
>> +       }
>> +
>> +       return pins;
>> +}
>> +
>> +static void aml_pctl_dt_child_count(struct aml_pinctrl *info,
>> +                                   struct device_node *np)
>> +{
>> +       struct device_node *child;
>> +
>> +       for_each_child_of_node(np, child) {
>> +               if (of_property_read_bool(child, "gpio-controller")) {
>> +                       info->nbanks++;
>> +               } else {
>> +                       info->nfunctions++;
>> +                       info->ngroups += of_get_child_count(child);
>> +               }
>> +       }
>> +}
> 
> This looks like a weird dependency between gpio chips and
> pins that I don't quite understand. Some comments and
> references to the bindings will be needed so it is clear
> what is going on.
> 

A pinctrl device contains two types of nodes. The one named GPIO bank 
which includes "gpio-controller" property. The other one named function 
which includes one or more pin groups.
The pin group include pinmux property(pin index in pinctrl dev,and mux 
vlaue in mux reg) and pin configuration properties.

I will add comment in next verison.
>> +static struct regmap *aml_map_resource(struct aml_pinctrl *info,
>> +                                      struct device_node *node, char *name)
>> +{
>> +       struct resource res;
>> +       void __iomem *base;
>> +       int i;
>> +
>> +       i = of_property_match_string(node, "reg-names", name);
>> +       if (of_address_to_resource(node, i, &res))
>> +               return NULL;
>> +
>> +       base = devm_ioremap_resource(info->dev, &res);
>> +       if (IS_ERR(base))
>> +               return ERR_CAST(base);
> 
> This looks like reimplementation of
> devm_platform_ioremap_resource_byname(), can't you just
> pass your platform device here?
>

I will fix it.

>> +static int aml_pctl_probe_dt(struct platform_device *pdev,
>> +                            struct pinctrl_desc *pctl_desc,
>> +                            struct aml_pinctrl *info)
> 
> Because there is clearly a platform device involved.
> 
> I guess I will have more comments as the series progress, but this
> is a good starting point!
> 
> Yours,
> Linus Walleij


From charlie at rivosinc.com  Wed Dec 18 01:23:59 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:23:59 -0800
Subject: [PATCH v4 01/16] perf tools: Create generic syscall table support
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-1-bc8caef2ca8e@rivosinc.com>

Currently each architecture in perf independently generates syscall
headers. Adapt the work that has gone into unifying syscall header
implementations in the kernel to work with perf tools. Introduce this
framework with riscv at first. riscv previously relied on libaudit, but
with this change, perf tools for riscv no longer needs this external
dependency.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  11 +-
 tools/perf/Makefile.perf                           |   4 +
 tools/perf/arch/riscv/Makefile                     |  22 --
 tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
 .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
 tools/perf/arch/riscv/entry/syscalls/mksyscalltbl  |  47 ---
 tools/perf/arch/riscv/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   1 +
 tools/perf/scripts/Makefile.syscalls               |  61 +++
 tools/perf/scripts/syscalltbl.sh                   |  86 +++++
 tools/perf/util/syscalltbl.c                       |   8 +-
 tools/scripts/syscall.tbl                          | 409 +++++++++++++++++++++
 12 files changed, 586 insertions(+), 77 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index f71afc04fd7a45c08fd3b3f4ba872cc6d5315c5a..9ff49aeb4fa5d6015dea068f23ea3a135155eb6e 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -35,6 +35,13 @@ ifneq ($(NO_SYSCALL_TABLE),1)
     NO_SYSCALL_TABLE := 0
   endif
 
+  # architectures that use the generic syscall table scripts
+  ifeq ($(SRCARCH),riscv)
+    NO_SYSCALL_TABLE := 0
+    CFLAGS += -DGENERIC_SYSCALL_TABLE
+    CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
+  endif
+
   ifneq ($(NO_SYSCALL_TABLE),1)
     CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
   endif
@@ -97,10 +104,6 @@ ifeq ($(ARCH),mips)
   endif
 endif
 
-ifeq ($(ARCH),riscv)
-  CFLAGS += -I$(OUTPUT)arch/riscv/include/generated
-endif
-
 # So far there's only x86 and arm libdw unwind support merged in perf.
 # Disable it on all other architectures in case libdw unwind
 # support is detected in system. Add supported architectures
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index d74241a151313bd09101aabb5d765a5a0a6efc84..f5278ed9f778f928436693a14e016c5c3c5171c1 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -310,6 +310,10 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
 FEATURE_TESTS := all
 endif
 endif
+# architectures that use the generic syscall table
+ifeq ($(SRCARCH),riscv)
+include $(srctree)/tools/perf/scripts/Makefile.syscalls
+endif
 include Makefile.config
 endif
 
diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
index 18ad078000e2bba595f92efc5d97a63fdb83ef45..087e099fb453a9236db34878077a51f711881ce0 100644
--- a/tools/perf/arch/riscv/Makefile
+++ b/tools/perf/arch/riscv/Makefile
@@ -1,25 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/riscv/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/riscv/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/riscv/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, riscv) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/riscv/entry/syscalls/Kbuild b/tools/perf/arch/riscv/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9a41e3572c3afd4f202321fd9e492714540e8fd3
--- /dev/null
+++ b/tools/perf/arch/riscv/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..9668fd1faf60e828ed2786c2ee84739ac1f153fc
--- /dev/null
+++ b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += riscv memfd_secret
+syscall_abis_64 += riscv rlimit memfd_secret
diff --git a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl b/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
deleted file mode 100755
index c59f5e852b97712a9a879b89e6ef6999ed4b6cd7..0000000000000000000000000000000000000000
--- a/tools/perf/arch/riscv/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-# Changed by: Kim Phillips <kim.phillips at arm.com>
-# Changed by: Bj?rn T?pel <bjorn at rivosinc.com>
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_RISCV_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_riscv[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/riscv/include/syscall_table.h b/tools/perf/arch/riscv/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/riscv/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index a05c1c105c51bf1bd18a59195220894598eb7461..692f48db810ccbef229e240db29261f0c60db632 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -71,6 +71,7 @@ FILES=(
   "include/uapi/asm-generic/ioctls.h"
   "include/uapi/asm-generic/mman-common.h"
   "include/uapi/asm-generic/unistd.h"
+  "scripts/syscall.tbl"
 )
 
 declare -a SYNC_CHECK_FILES
diff --git a/tools/perf/scripts/Makefile.syscalls b/tools/perf/scripts/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..0bf27d679b5bb2da6c0eefbc44e10bc44b51da0f
--- /dev/null
+++ b/tools/perf/scripts/Makefile.syscalls
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: GPL-2.0
+# This Makefile generates headers in
+# tools/perf/arch/$(SRCARCH)/include/generated/asm from the architecture's
+# syscall table. This will either be from the generic syscall table, or from a
+# table that is specific to that architecture.
+
+PHONY := all
+all:
+
+obj := $(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated/asm
+
+syscall_abis_32  := common,32
+syscall_abis_64  := common,64
+syscalltbl := $(srctree)/tools/scripts/syscall.tbl
+
+# let architectures override $(syscall_abis_%) and $(syscalltbl)
+-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Makefile.syscalls
+include $(srctree)/scripts/Kbuild.include
+-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Kbuild
+
+systbl := $(srctree)/tools/perf/scripts/syscalltbl.sh
+
+syscall-y   := $(addprefix $(obj)/, $(syscall-y))
+
+# Remove stale wrappers when the corresponding files are removed from generic-y
+old-headers := $(wildcard $(obj)/*.h)
+unwanted    := $(filter-out $(syscall-y),$(old-headers))
+
+quiet_cmd_remove = REMOVE  $(unwanted)
+      cmd_remove = rm -f $(unwanted)
+
+quiet_cmd_systbl = SYSTBL  $@
+      cmd_systbl = $(CONFIG_SHELL) $(systbl) \
+		   $(if $(systbl-args-$*),$(systbl-args-$*),$(systbl-args)) \
+		   --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \
+		   $< $@
+
+all: $(syscall-y)
+	$(if $(unwanted),$(call cmd,remove))
+	@:
+
+$(obj)/syscalls_%.h: $(syscalltbl) $(systbl) FORCE
+	$(call if_changed,systbl)
+
+targets := $(syscall-y)
+
+# Create output directory. Skip it if at least one old header exists
+# since we know the output directory already exists.
+ifeq ($(old-headers),)
+$(shell mkdir -p $(obj))
+endif
+
+PHONY += FORCE
+
+FORCE:
+
+existing-targets := $(wildcard $(sort $(targets)))
+
+-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
+
+.PHONY: $(PHONY)
diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1ce0d5aa8b506427a66be50f0f441cf6e9705b33
--- /dev/null
+++ b/tools/perf/scripts/syscalltbl.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generate a syscall table header.
+#
+# Each line of the syscall table should have the following format:
+#
+# NR ABI NAME [NATIVE] [COMPAT]
+#
+# NR       syscall number
+# ABI      ABI name
+# NAME     syscall name
+# NATIVE   native entry point (optional)
+# COMPAT   compat entry point (optional)
+
+set -e
+
+usage() {
+	echo >&2 "usage: $0 [--abis ABIS] INFILE OUTFILE" >&2
+	echo >&2
+	echo >&2 "  INFILE    input syscall table"
+	echo >&2 "  OUTFILE   output header file"
+	echo >&2
+	echo >&2 "options:"
+	echo >&2 "  --abis ABIS        ABI(s) to handle (By default, all lines are handled)"
+	exit 1
+}
+
+# default unless specified by options
+abis=
+
+while [ $# -gt 0 ]
+do
+	case $1 in
+	--abis)
+		abis=$(echo "($2)" | tr ',' '|')
+		shift 2;;
+	-*)
+		echo "$1: unknown option" >&2
+		usage;;
+	*)
+		break;;
+	esac
+done
+
+if [ $# -ne 2 ]; then
+	usage
+fi
+
+infile="$1"
+outfile="$2"
+
+nxt=0
+
+syscall_macro() {
+    nr="$1"
+    name="$2"
+
+    echo "	[$nr] = \"$name\","
+}
+
+emit() {
+    nr="$1"
+    entry="$2"
+
+    syscall_macro "$nr" "$entry"
+}
+
+echo "static const char *const syscalltbl[] = {" > $outfile
+
+sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
+grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table
+
+max_nr=0
+# the params are: nr abi name entry compat
+# use _ for intentionally unused variables according to SC2034
+while read nr _ name _ _; do
+    emit "$nr" "$name" >> $outfile
+    max_nr=$nr
+done < $sorted_table
+
+rm -f $sorted_table
+
+echo "};" >> $outfile
+
+echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 69d8dcf5cf28c4e8a0e403153c92bd6436e2a0b2..ccf234a54366f9921c3b9a02ffb0a365d17244bc 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -46,10 +46,10 @@ static const char *const *syscalltbl_native = syscalltbl_mips_n64;
 #include <asm/syscalls.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_loongarch;
-#elif defined(__riscv)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_RISCV_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_riscv;
+#elif defined(GENERIC_SYSCALL_TABLE)
+#include <syscall_table.h>
+const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
+static const char *const *syscalltbl_native = syscalltbl;
 #else
 const int syscalltbl_native_max_id = 0;
 static const char *const syscalltbl_native[] = {
diff --git a/tools/scripts/syscall.tbl b/tools/scripts/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..ebbdb3c42e9f74613b003014c0baf44c842bb756
--- /dev/null
+++ b/tools/scripts/syscall.tbl
@@ -0,0 +1,409 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# This file contains the system call numbers for all of the
+# more recently added architectures.
+#
+# As a basic principle, no duplication of functionality
+# should be added, e.g. we don't use lseek when llseek
+# is present. New architectures should use this file
+# and implement the less feature-full calls in user space.
+#
+0	common	io_setup			sys_io_setup			compat_sys_io_setup
+1	common	io_destroy			sys_io_destroy
+2	common	io_submit			sys_io_submit			compat_sys_io_submit
+3	common	io_cancel			sys_io_cancel
+4	time32	io_getevents			sys_io_getevents_time32
+4	64	io_getevents			sys_io_getevents
+5	common	setxattr			sys_setxattr
+6	common	lsetxattr			sys_lsetxattr
+7	common	fsetxattr			sys_fsetxattr
+8	common	getxattr			sys_getxattr
+9	common	lgetxattr			sys_lgetxattr
+10	common	fgetxattr			sys_fgetxattr
+11	common	listxattr			sys_listxattr
+12	common	llistxattr			sys_llistxattr
+13	common	flistxattr			sys_flistxattr
+14	common	removexattr			sys_removexattr
+15	common	lremovexattr			sys_lremovexattr
+16	common	fremovexattr			sys_fremovexattr
+17	common	getcwd				sys_getcwd
+18	common	lookup_dcookie			sys_ni_syscall
+19	common	eventfd2			sys_eventfd2
+20	common	epoll_create1			sys_epoll_create1
+21	common	epoll_ctl			sys_epoll_ctl
+22	common	epoll_pwait			sys_epoll_pwait			compat_sys_epoll_pwait
+23	common	dup				sys_dup
+24	common	dup3				sys_dup3
+25	32	fcntl64				sys_fcntl64			compat_sys_fcntl64
+25	64	fcntl				sys_fcntl
+26	common	inotify_init1			sys_inotify_init1
+27	common	inotify_add_watch		sys_inotify_add_watch
+28	common	inotify_rm_watch		sys_inotify_rm_watch
+29	common	ioctl				sys_ioctl			compat_sys_ioctl
+30	common	ioprio_set			sys_ioprio_set
+31	common	ioprio_get			sys_ioprio_get
+32	common	flock				sys_flock
+33	common	mknodat				sys_mknodat
+34	common	mkdirat				sys_mkdirat
+35	common	unlinkat			sys_unlinkat
+36	common	symlinkat			sys_symlinkat
+37	common	linkat				sys_linkat
+# renameat is superseded with flags by renameat2
+38	renameat renameat			sys_renameat
+39	common	umount2				sys_umount
+40	common	mount				sys_mount
+41	common	pivot_root			sys_pivot_root
+42	common	nfsservctl			sys_ni_syscall
+43	32	statfs64			sys_statfs64			compat_sys_statfs64
+43	64	statfs				sys_statfs
+44	32	fstatfs64			sys_fstatfs64			compat_sys_fstatfs64
+44	64	fstatfs				sys_fstatfs
+45	32	truncate64			sys_truncate64			compat_sys_truncate64
+45	64	truncate			sys_truncate
+46	32	ftruncate64			sys_ftruncate64			compat_sys_ftruncate64
+46	64	ftruncate			sys_ftruncate
+47	common	fallocate			sys_fallocate			compat_sys_fallocate
+48	common	faccessat			sys_faccessat
+49	common	chdir				sys_chdir
+50	common	fchdir				sys_fchdir
+51	common	chroot				sys_chroot
+52	common	fchmod				sys_fchmod
+53	common	fchmodat			sys_fchmodat
+54	common	fchownat			sys_fchownat
+55	common	fchown				sys_fchown
+56	common	openat				sys_openat
+57	common	close				sys_close
+58	common	vhangup				sys_vhangup
+59	common	pipe2				sys_pipe2
+60	common	quotactl			sys_quotactl
+61	common	getdents64			sys_getdents64
+62	32	llseek				sys_llseek
+62	64	lseek				sys_lseek
+63	common	read				sys_read
+64	common	write				sys_write
+65	common	readv				sys_readv			sys_readv
+66	common	writev				sys_writev			sys_writev
+67	common	pread64				sys_pread64			compat_sys_pread64
+68	common	pwrite64			sys_pwrite64			compat_sys_pwrite64
+69	common	preadv				sys_preadv			compat_sys_preadv
+70	common	pwritev				sys_pwritev			compat_sys_pwritev
+71	32	sendfile64			sys_sendfile64
+71	64	sendfile			sys_sendfile64
+72	time32	pselect6			sys_pselect6_time32		compat_sys_pselect6_time32
+72	64	pselect6			sys_pselect6
+73	time32	ppoll				sys_ppoll_time32		compat_sys_ppoll_time32
+73	64	ppoll				sys_ppoll
+74	common	signalfd4			sys_signalfd4			compat_sys_signalfd4
+75	common	vmsplice			sys_vmsplice
+76	common	splice				sys_splice
+77	common	tee				sys_tee
+78	common	readlinkat			sys_readlinkat
+79	stat64	fstatat64			sys_fstatat64
+79	64	newfstatat			sys_newfstatat
+80	stat64	fstat64				sys_fstat64
+80	64	fstat				sys_newfstat
+81	common	sync				sys_sync
+82	common	fsync				sys_fsync
+83	common	fdatasync			sys_fdatasync
+84	common	sync_file_range			sys_sync_file_range		compat_sys_sync_file_range
+85	common	timerfd_create			sys_timerfd_create
+86	time32	timerfd_settime			sys_timerfd_settime32
+86	64	timerfd_settime			sys_timerfd_settime
+87	time32	timerfd_gettime			sys_timerfd_gettime32
+87	64	timerfd_gettime			sys_timerfd_gettime
+88	time32	utimensat			sys_utimensat_time32
+88	64	utimensat			sys_utimensat
+89	common	acct				sys_acct
+90	common	capget				sys_capget
+91	common	capset				sys_capset
+92	common	personality			sys_personality
+93	common	exit				sys_exit
+94	common	exit_group			sys_exit_group
+95	common	waitid				sys_waitid			compat_sys_waitid
+96	common	set_tid_address			sys_set_tid_address
+97	common	unshare				sys_unshare
+98	time32	futex				sys_futex_time32
+98	64	futex				sys_futex
+99	common	set_robust_list			sys_set_robust_list		compat_sys_set_robust_list
+100	common	get_robust_list			sys_get_robust_list		compat_sys_get_robust_list
+101	time32	nanosleep			sys_nanosleep_time32
+101	64	nanosleep			sys_nanosleep
+102	common	getitimer			sys_getitimer			compat_sys_getitimer
+103	common	setitimer			sys_setitimer			compat_sys_setitimer
+104	common	kexec_load			sys_kexec_load			compat_sys_kexec_load
+105	common	init_module			sys_init_module
+106	common	delete_module			sys_delete_module
+107	common	timer_create			sys_timer_create		compat_sys_timer_create
+108	time32	timer_gettime			sys_timer_gettime32
+108	64	timer_gettime			sys_timer_gettime
+109	common	timer_getoverrun		sys_timer_getoverrun
+110	time32	timer_settime			sys_timer_settime32
+110	64	timer_settime			sys_timer_settime
+111	common	timer_delete			sys_timer_delete
+112	time32	clock_settime			sys_clock_settime32
+112	64	clock_settime			sys_clock_settime
+113	time32	clock_gettime			sys_clock_gettime32
+113	64	clock_gettime			sys_clock_gettime
+114	time32	clock_getres			sys_clock_getres_time32
+114	64	clock_getres			sys_clock_getres
+115	time32	clock_nanosleep			sys_clock_nanosleep_time32
+115	64	clock_nanosleep			sys_clock_nanosleep
+116	common	syslog				sys_syslog
+117	common	ptrace				sys_ptrace			compat_sys_ptrace
+118	common	sched_setparam			sys_sched_setparam
+119	common	sched_setscheduler		sys_sched_setscheduler
+120	common	sched_getscheduler		sys_sched_getscheduler
+121	common	sched_getparam			sys_sched_getparam
+122	common	sched_setaffinity		sys_sched_setaffinity		compat_sys_sched_setaffinity
+123	common	sched_getaffinity		sys_sched_getaffinity		compat_sys_sched_getaffinity
+124	common	sched_yield			sys_sched_yield
+125	common	sched_get_priority_max		sys_sched_get_priority_max
+126	common	sched_get_priority_min		sys_sched_get_priority_min
+127	time32	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+127	64	sched_rr_get_interval		sys_sched_rr_get_interval
+128	common	restart_syscall			sys_restart_syscall
+129	common	kill				sys_kill
+130	common	tkill				sys_tkill
+131	common	tgkill				sys_tgkill
+132	common	sigaltstack			sys_sigaltstack			compat_sys_sigaltstack
+133	common	rt_sigsuspend			sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+134	common	rt_sigaction			sys_rt_sigaction		compat_sys_rt_sigaction
+135	common	rt_sigprocmask			sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+136	common	rt_sigpending			sys_rt_sigpending		compat_sys_rt_sigpending
+137	time32	rt_sigtimedwait			sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+137	64	rt_sigtimedwait			sys_rt_sigtimedwait
+138	common	rt_sigqueueinfo			sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+139	common	rt_sigreturn			sys_rt_sigreturn		compat_sys_rt_sigreturn
+140	common	setpriority			sys_setpriority
+141	common	getpriority			sys_getpriority
+142	common	reboot				sys_reboot
+143	common	setregid			sys_setregid
+144	common	setgid				sys_setgid
+145	common	setreuid			sys_setreuid
+146	common	setuid				sys_setuid
+147	common	setresuid			sys_setresuid
+148	common	getresuid			sys_getresuid
+149	common	setresgid			sys_setresgid
+150	common	getresgid			sys_getresgid
+151	common	setfsuid			sys_setfsuid
+152	common	setfsgid			sys_setfsgid
+153	common	times				sys_times			compat_sys_times
+154	common	setpgid				sys_setpgid
+155	common	getpgid				sys_getpgid
+156	common	getsid				sys_getsid
+157	common	setsid				sys_setsid
+158	common	getgroups			sys_getgroups
+159	common	setgroups			sys_setgroups
+160	common	uname				sys_newuname
+161	common	sethostname			sys_sethostname
+162	common	setdomainname			sys_setdomainname
+# getrlimit and setrlimit are superseded with prlimit64
+163	rlimit	getrlimit			sys_getrlimit			compat_sys_getrlimit
+164	rlimit	setrlimit			sys_setrlimit			compat_sys_setrlimit
+165	common	getrusage			sys_getrusage			compat_sys_getrusage
+166	common	umask				sys_umask
+167	common	prctl				sys_prctl
+168	common	getcpu				sys_getcpu
+169	time32	gettimeofday			sys_gettimeofday		compat_sys_gettimeofday
+169	64	gettimeofday			sys_gettimeofday
+170	time32	settimeofday			sys_settimeofday		compat_sys_settimeofday
+170	64	settimeofday			sys_settimeofday
+171	time32	adjtimex			sys_adjtimex_time32
+171	64	adjtimex			sys_adjtimex
+172	common	getpid				sys_getpid
+173	common	getppid				sys_getppid
+174	common	getuid				sys_getuid
+175	common	geteuid				sys_geteuid
+176	common	getgid				sys_getgid
+177	common	getegid				sys_getegid
+178	common	gettid				sys_gettid
+179	common	sysinfo				sys_sysinfo			compat_sys_sysinfo
+180	common	mq_open				sys_mq_open			compat_sys_mq_open
+181	common	mq_unlink			sys_mq_unlink
+182	time32	mq_timedsend			sys_mq_timedsend_time32
+182	64	mq_timedsend			sys_mq_timedsend
+183	time32	mq_timedreceive			sys_mq_timedreceive_time32
+183	64	mq_timedreceive			sys_mq_timedreceive
+184	common	mq_notify			sys_mq_notify			compat_sys_mq_notify
+185	common	mq_getsetattr			sys_mq_getsetattr		compat_sys_mq_getsetattr
+186	common	msgget				sys_msgget
+187	common	msgctl				sys_msgctl			compat_sys_msgctl
+188	common	msgrcv				sys_msgrcv			compat_sys_msgrcv
+189	common	msgsnd				sys_msgsnd			compat_sys_msgsnd
+190	common	semget				sys_semget
+191	common	semctl				sys_semctl			compat_sys_semctl
+192	time32	semtimedop			sys_semtimedop_time32
+192	64	semtimedop			sys_semtimedop
+193	common	semop				sys_semop
+194	common	shmget				sys_shmget
+195	common	shmctl				sys_shmctl			compat_sys_shmctl
+196	common	shmat				sys_shmat			compat_sys_shmat
+197	common	shmdt				sys_shmdt
+198	common	socket				sys_socket
+199	common	socketpair			sys_socketpair
+200	common	bind				sys_bind
+201	common	listen				sys_listen
+202	common	accept				sys_accept
+203	common	connect				sys_connect
+204	common	getsockname			sys_getsockname
+205	common	getpeername			sys_getpeername
+206	common	sendto				sys_sendto
+207	common	recvfrom			sys_recvfrom			compat_sys_recvfrom
+208	common	setsockopt			sys_setsockopt			sys_setsockopt
+209	common	getsockopt			sys_getsockopt			sys_getsockopt
+210	common	shutdown			sys_shutdown
+211	common	sendmsg				sys_sendmsg			compat_sys_sendmsg
+212	common	recvmsg				sys_recvmsg			compat_sys_recvmsg
+213	common	readahead			sys_readahead			compat_sys_readahead
+214	common	brk				sys_brk
+215	common	munmap				sys_munmap
+216	common	mremap				sys_mremap
+217	common	add_key				sys_add_key
+218	common	request_key			sys_request_key
+219	common	keyctl				sys_keyctl			compat_sys_keyctl
+220	common	clone				sys_clone
+221	common	execve				sys_execve			compat_sys_execve
+222	32	mmap2				sys_mmap2
+222	64	mmap				sys_mmap
+223	32	fadvise64_64			sys_fadvise64_64		compat_sys_fadvise64_64
+223	64	fadvise64			sys_fadvise64_64
+224	common	swapon				sys_swapon
+225	common	swapoff				sys_swapoff
+226	common	mprotect			sys_mprotect
+227	common	msync				sys_msync
+228	common	mlock				sys_mlock
+229	common	munlock				sys_munlock
+230	common	mlockall			sys_mlockall
+231	common	munlockall			sys_munlockall
+232	common	mincore				sys_mincore
+233	common	madvise				sys_madvise
+234	common	remap_file_pages		sys_remap_file_pages
+235	common	mbind				sys_mbind
+236	common	get_mempolicy			sys_get_mempolicy
+237	common	set_mempolicy			sys_set_mempolicy
+238	common	migrate_pages			sys_migrate_pages
+239	common	move_pages			sys_move_pages
+240	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+241	common	perf_event_open			sys_perf_event_open
+242	common	accept4				sys_accept4
+243	time32	recvmmsg			sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+243	64	recvmmsg			sys_recvmmsg
+# Architectures may provide up to 16 syscalls of their own between 244 and 259
+244	arc	cacheflush			sys_cacheflush
+245	arc	arc_settls			sys_arc_settls
+246	arc	arc_gettls			sys_arc_gettls
+247	arc	sysfs				sys_sysfs
+248	arc	arc_usr_cmpxchg			sys_arc_usr_cmpxchg
+
+244	csky	set_thread_area			sys_set_thread_area
+245	csky	cacheflush			sys_cacheflush
+
+244	nios2	cacheflush			sys_cacheflush
+
+244	or1k	or1k_atomic			sys_or1k_atomic
+
+258	riscv	riscv_hwprobe			sys_riscv_hwprobe
+259	riscv	riscv_flush_icache		sys_riscv_flush_icache
+
+260	time32	wait4				sys_wait4			compat_sys_wait4
+260	64	wait4				sys_wait4
+261	common	prlimit64			sys_prlimit64
+262	common	fanotify_init			sys_fanotify_init
+263	common	fanotify_mark			sys_fanotify_mark
+264	common	name_to_handle_at		sys_name_to_handle_at
+265	common	open_by_handle_at		sys_open_by_handle_at
+266	time32	clock_adjtime			sys_clock_adjtime32
+266	64	clock_adjtime			sys_clock_adjtime
+267	common	syncfs				sys_syncfs
+268	common	setns				sys_setns
+269	common	sendmmsg			sys_sendmmsg			compat_sys_sendmmsg
+270	common	process_vm_readv		sys_process_vm_readv
+271	common	process_vm_writev		sys_process_vm_writev
+272	common	kcmp				sys_kcmp
+273	common	finit_module			sys_finit_module
+274	common	sched_setattr			sys_sched_setattr
+275	common	sched_getattr			sys_sched_getattr
+276	common	renameat2			sys_renameat2
+277	common	seccomp				sys_seccomp
+278	common	getrandom			sys_getrandom
+279	common	memfd_create			sys_memfd_create
+280	common	bpf				sys_bpf
+281	common	execveat			sys_execveat			compat_sys_execveat
+282	common	userfaultfd			sys_userfaultfd
+283	common	membarrier			sys_membarrier
+284	common	mlock2				sys_mlock2
+285	common	copy_file_range			sys_copy_file_range
+286	common	preadv2				sys_preadv2			compat_sys_preadv2
+287	common	pwritev2			sys_pwritev2			compat_sys_pwritev2
+288	common	pkey_mprotect			sys_pkey_mprotect
+289	common	pkey_alloc			sys_pkey_alloc
+290	common	pkey_free			sys_pkey_free
+291	common	statx				sys_statx
+292	time32	io_pgetevents			sys_io_pgetevents_time32	compat_sys_io_pgetevents
+292	64	io_pgetevents			sys_io_pgetevents
+293	common	rseq				sys_rseq
+294	common	kexec_file_load			sys_kexec_file_load
+# 295 through 402 are unassigned to sync up with generic numbers don't use
+403	32	clock_gettime64			sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+447	memfd_secret	memfd_secret		sys_memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:00 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:00 -0800
Subject: [PATCH v4 02/16] perf tools: arc: Support generic syscall headers
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-2-bc8caef2ca8e@rivosinc.com>

Arc uses the generic syscall table, use that in perf instead of
requiring libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                           | 2 +-
 tools/perf/Makefile.perf                             | 3 ++-
 tools/perf/arch/arc/entry/syscalls/Kbuild            | 2 ++
 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls | 3 +++
 tools/perf/arch/arc/include/syscall_table.h          | 2 ++
 5 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 9ff49aeb4fa5d6015dea068f23ea3a135155eb6e..a09e2245a9ba00db79cf3a65e8772a6cb9b6c78e 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),riscv)
+  ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)tools/perf/arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f5278ed9f778f928436693a14e016c5c3c5171c1..f717e4628d9e4632f53fed16524a659a3e4feea5 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,8 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),riscv)
+generic_syscall_table_archs := riscv arc
+ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/arc/entry/syscalls/Kbuild b/tools/perf/arch/arc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/arc/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..391d30ab7a831b72d2ed3f2e7966fdbf558a9ed7
--- /dev/null
+++ b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += arc time32 renameat stat64 rlimit
diff --git a/tools/perf/arch/arc/include/syscall_table.h b/tools/perf/arch/arc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/arc/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>

-- 
2.34.1



From clement.legoffic at foss.st.com  Wed Dec 18 01:22:27 2024
From: clement.legoffic at foss.st.com (=?UTF-8?q?Cl=C3=A9ment=20Le=20Goffic?=)
Date: Wed, 18 Dec 2024 10:22:27 +0100
Subject: [PATCH v3] watchdog: stm32_iwdg: fix error message during driver probe
In-Reply-To: <20241212102050.374501-1-clement.legoffic@foss.st.com>
References: <20241212102050.374501-1-clement.legoffic@foss.st.com>
Message-ID: <20241218092227.771133-1-clement.legoffic@foss.st.com>

The commit 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
introduces the support for the pre-timeout interrupt.

The support for this interrupt is optional but the driver uses the
platform_get_irq() which produces an error message during the driver
probe if we don't have any `interrupts` property in the DT.

Use the platform_get_irq_optional() API to get rid of the error message
as this property is optional.

Fixes: 3ab1663af6c1 ("watchdog: stm32_iwdg: Add pretimeout support")
Signed-off-by: Cl?ment Le Goffic <clement.legoffic at foss.st.com>
Reviewed-by: Marek Vasut <marex at denx.de>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
---
v1 -> v2: Change the commit message because it only prints an error
message and dont break the DT backward compatibility.

v2 -> v3: Fix typo in commit message 's/wich/which/g'.

drivers/watchdog/stm32_iwdg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index d700e0d49bb95..8ad06b54c5adc 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -286,7 +286,7 @@ static int stm32_iwdg_irq_init(struct platform_device *pdev,
 	if (!wdt->data->has_early_wakeup)
 		return 0;

-	irq = platform_get_irq(pdev, 0);
+	irq = platform_get_irq_optional(pdev, 0);
 	if (irq <= 0)
 		return 0;


base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
--
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:01 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:01 -0800
Subject: [PATCH v4 03/16] perf tools: csky: Support generic syscall headers
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-3-bc8caef2ca8e@rivosinc.com>

csky uses the generic syscall table, use that in perf instead of
requiring libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                              | 2 +-
 tools/perf/arch/csky/entry/syscalls/Kbuild            | 2 ++
 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls | 3 +++
 tools/perf/arch/csky/include/syscall_table.h          | 2 ++
 4 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f717e4628d9e4632f53fed16524a659a3e4feea5..b20daf3769771a7c23cc0f7dd46f562510bc3199 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc
+generic_syscall_table_archs := riscv arc csky
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/csky/entry/syscalls/Kbuild b/tools/perf/arch/csky/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/csky/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls b/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..ea2dd10d0571df464574a9c0232ada0ac1f79a3f
--- /dev/null
+++ b/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += csky time32 stat64 rlimit
diff --git a/tools/perf/arch/csky/include/syscall_table.h b/tools/perf/arch/csky/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/csky/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:02 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:02 -0800
Subject: [PATCH v4 04/16] perf tools: arm: Support syscall headers
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-4-bc8caef2ca8e@rivosinc.com>

arm uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
 .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
 tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 483 +++++++++++++++++++++
 tools/perf/arch/arm/include/syscall_table.h        |   2 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 493 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index b20daf3769771a7c23cc0f7dd46f562510bc3199..fa69b056bab31568baba78a9903312bd37b98067 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky
+generic_syscall_table_archs := riscv arc csky arm
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/arm/entry/syscalls/Kbuild b/tools/perf/arch/arm/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..9d777540f08987908a6532c5ece66553dffc52df
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/Kbuild
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += oabi
+syscalltbl = $(srctree)/tools/perf/arch/arm/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arm/entry/syscalls/syscall.tbl b/tools/perf/arch/arm/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..49eeb2ad8dbd8e074c6240417693f23fb328afa8
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/syscall.tbl
@@ -0,0 +1,483 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# Linux system call numbers and entry vectors
+#
+# The format is:
+# <num>	<abi>	<name>			[<entry point>			[<oabi compat entry point>]]
+#
+# Where abi is:
+#  common - for system calls shared between oabi and eabi (may have compat)
+#  oabi   - for oabi-only system calls (may have compat)
+#  eabi   - for eabi-only system calls
+#
+# For each syscall number, "common" is mutually exclusive with oabi and eabi
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open
+6	common	close			sys_close
+# 7 was sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve
+12	common	chdir			sys_chdir
+13	oabi	time			sys_time32
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19	common	lseek			sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+22	oabi	umount			sys_oldumount
+23	common	setuid			sys_setuid16
+24	common	getuid			sys_getuid16
+25	oabi	stime			sys_stime32
+26	common	ptrace			sys_ptrace
+27	oabi	alarm			sys_alarm
+# 28 was sys_fstat
+29	common	pause			sys_pause
+30	oabi	utime			sys_utime32
+# 31 was sys_stty
+# 32 was sys_gtty
+33	common	access			sys_access
+34	common	nice			sys_nice
+# 35 was sys_ftime
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times
+# 44 was sys_prof
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid16
+47	common	getgid			sys_getgid16
+# 48 was sys_signal
+49	common	geteuid			sys_geteuid16
+50	common	getegid			sys_getegid16
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+# 53 was sys_lock
+54	common	ioctl			sys_ioctl
+55	common	fcntl			sys_fcntl
+# 56 was sys_mpx
+57	common	setpgid			sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	sigaction		sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70	common	setreuid		sys_setreuid16
+71	common	setregid		sys_setregid16
+72	common	sigsuspend		sys_sigsuspend
+73	common	sigpending		sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit
+# Back compat 2GB limited rlimit
+76	oabi	getrlimit		sys_old_getrlimit
+77	common	getrusage		sys_getrusage
+78	common	gettimeofday		sys_gettimeofday
+79	common	settimeofday		sys_settimeofday
+80	common	getgroups		sys_getgroups16
+81	common	setgroups		sys_setgroups16
+82	oabi	select			sys_old_select
+83	common	symlink			sys_symlink
+# 84 was sys_lstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_uselib
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+89	oabi	readdir			sys_old_readdir
+90	oabi	mmap			sys_old_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate
+93	common	ftruncate		sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown16
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+# 98 was sys_profil
+99	common	statfs			sys_statfs
+100	common	fstatfs			sys_fstatfs
+# 101 was sys_ioperm
+102	oabi	socketcall		sys_socketcall		sys_oabi_socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer
+105	common	getitimer		sys_getitimer
+106	common	stat			sys_newstat
+107	common	lstat			sys_newlstat
+108	common	fstat			sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111	common	vhangup			sys_vhangup
+# 112 was sys_idle
+# syscall to call a syscall!
+113	oabi	syscall			sys_syscall
+114	common	wait4			sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo
+117	oabi	ipc			sys_ipc			sys_oabi_ipc
+118	common	fsync			sys_fsync
+119	common	sigreturn		sys_sigreturn_wrapper
+120	common	clone			sys_clone
+121	common	setdomainname		sys_setdomainname
+122	common	uname			sys_newuname
+# 123 was sys_modify_ldt
+124	common	adjtimex		sys_adjtimex_time32
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask
+# 127 was sys_create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was sys_get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	common	personality		sys_personality
+# 137 was sys_afs_syscall
+138	common	setfsuid		sys_setfsuid16
+139	common	setfsgid		sys_setfsgid16
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents
+142	common	_newselect		sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	common	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+162	common	nanosleep		sys_nanosleep_time32
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid16
+165	common	getresuid		sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168	common	poll			sys_poll
+169	common	nfsservctl
+170	common	setresgid		sys_setresgid16
+171	common	getresgid		sys_getresgid16
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper
+174	common	rt_sigaction		sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending
+177	common	rt_sigtimedwait		sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend
+180	common	pread64			sys_pread64		sys_oabi_pread64
+181	common	pwrite64		sys_pwrite64		sys_oabi_pwrite64
+182	common	chown			sys_chown16
+183	common	getcwd			sys_getcwd
+184	common	capget			sys_capget
+185	common	capset			sys_capset
+186	common	sigaltstack		sys_sigaltstack
+187	common	sendfile		sys_sendfile
+# 188 reserved
+# 189 reserved
+190	common	vfork			sys_vfork
+# SuS compliant getrlimit
+191	common	ugetrlimit		sys_getrlimit
+192	common	mmap2			sys_mmap2
+193	common	truncate64		sys_truncate64		sys_oabi_truncate64
+194	common	ftruncate64		sys_ftruncate64		sys_oabi_ftruncate64
+195	common	stat64			sys_stat64		sys_oabi_stat64
+196	common	lstat64			sys_lstat64		sys_oabi_lstat64
+197	common	fstat64			sys_fstat64		sys_oabi_fstat64
+198	common	lchown32		sys_lchown
+199	common	getuid32		sys_getuid
+200	common	getgid32		sys_getgid
+201	common	geteuid32		sys_geteuid
+202	common	getegid32		sys_getegid
+203	common	setreuid32		sys_setreuid
+204	common	setregid32		sys_setregid
+205	common	getgroups32		sys_getgroups
+206	common	setgroups32		sys_setgroups
+207	common	fchown32		sys_fchown
+208	common	setresuid32		sys_setresuid
+209	common	getresuid32		sys_getresuid
+210	common	setresgid32		sys_setresgid
+211	common	getresgid32		sys_getresgid
+212	common	chown32			sys_chown
+213	common	setuid32		sys_setuid
+214	common	setgid32		sys_setgid
+215	common	setfsuid32		sys_setfsuid
+216	common	setfsgid32		sys_setfsgid
+217	common	getdents64		sys_getdents64
+218	common	pivot_root		sys_pivot_root
+219	common	mincore			sys_mincore
+220	common	madvise			sys_madvise
+221	common	fcntl64			sys_fcntl64		sys_oabi_fcntl64
+# 222 for tux
+# 223 is unused
+224	common	gettid			sys_gettid
+225	common	readahead		sys_readahead		sys_oabi_readahead
+226	common	setxattr		sys_setxattr
+227	common	lsetxattr		sys_lsetxattr
+228	common	fsetxattr		sys_fsetxattr
+229	common	getxattr		sys_getxattr
+230	common	lgetxattr		sys_lgetxattr
+231	common	fgetxattr		sys_fgetxattr
+232	common	listxattr		sys_listxattr
+233	common	llistxattr		sys_llistxattr
+234	common	flistxattr		sys_flistxattr
+235	common	removexattr		sys_removexattr
+236	common	lremovexattr		sys_lremovexattr
+237	common	fremovexattr		sys_fremovexattr
+238	common	tkill			sys_tkill
+239	common	sendfile64		sys_sendfile64
+240	common	futex			sys_futex_time32
+241	common	sched_setaffinity	sys_sched_setaffinity
+242	common	sched_getaffinity	sys_sched_getaffinity
+243	common	io_setup		sys_io_setup
+244	common	io_destroy		sys_io_destroy
+245	common	io_getevents		sys_io_getevents_time32
+246	common	io_submit		sys_io_submit
+247	common	io_cancel		sys_io_cancel
+248	common	exit_group		sys_exit_group
+249	common	lookup_dcookie		sys_ni_syscall
+250	common	epoll_create		sys_epoll_create
+251	common	epoll_ctl		sys_epoll_ctl		sys_oabi_epoll_ctl
+252	common	epoll_wait		sys_epoll_wait
+253	common	remap_file_pages	sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256	common	set_tid_address		sys_set_tid_address
+257	common	timer_create		sys_timer_create
+258	common	timer_settime		sys_timer_settime32
+259	common	timer_gettime		sys_timer_gettime32
+260	common	timer_getoverrun	sys_timer_getoverrun
+261	common	timer_delete		sys_timer_delete
+262	common	clock_settime		sys_clock_settime32
+263	common	clock_gettime		sys_clock_gettime32
+264	common	clock_getres		sys_clock_getres_time32
+265	common	clock_nanosleep		sys_clock_nanosleep_time32
+266	common	statfs64		sys_statfs64_wrapper
+267	common	fstatfs64		sys_fstatfs64_wrapper
+268	common	tgkill			sys_tgkill
+269	common	utimes			sys_utimes_time32
+270	common	arm_fadvise64_64	sys_arm_fadvise64_64
+271	common	pciconfig_iobase	sys_pciconfig_iobase
+272	common	pciconfig_read		sys_pciconfig_read
+273	common	pciconfig_write		sys_pciconfig_write
+274	common	mq_open			sys_mq_open
+275	common	mq_unlink		sys_mq_unlink
+276	common	mq_timedsend		sys_mq_timedsend_time32
+277	common	mq_timedreceive		sys_mq_timedreceive_time32
+278	common	mq_notify		sys_mq_notify
+279	common	mq_getsetattr		sys_mq_getsetattr
+280	common	waitid			sys_waitid
+281	common	socket			sys_socket
+282	common	bind			sys_bind		sys_oabi_bind
+283	common	connect			sys_connect		sys_oabi_connect
+284	common	listen			sys_listen
+285	common	accept			sys_accept
+286	common	getsockname		sys_getsockname
+287	common	getpeername		sys_getpeername
+288	common	socketpair		sys_socketpair
+289	common	send			sys_send
+290	common	sendto			sys_sendto		sys_oabi_sendto
+291	common	recv			sys_recv
+292	common	recvfrom		sys_recvfrom
+293	common	shutdown		sys_shutdown
+294	common	setsockopt		sys_setsockopt
+295	common	getsockopt		sys_getsockopt
+296	common	sendmsg			sys_sendmsg		sys_oabi_sendmsg
+297	common	recvmsg			sys_recvmsg
+298	common	semop			sys_semop		sys_oabi_semop
+299	common	semget			sys_semget
+300	common	semctl			sys_old_semctl
+301	common	msgsnd			sys_msgsnd
+302	common	msgrcv			sys_msgrcv
+303	common	msgget			sys_msgget
+304	common	msgctl			sys_old_msgctl
+305	common	shmat			sys_shmat
+306	common	shmdt			sys_shmdt
+307	common	shmget			sys_shmget
+308	common	shmctl			sys_old_shmctl
+309	common	add_key			sys_add_key
+310	common	request_key		sys_request_key
+311	common	keyctl			sys_keyctl
+312	common	semtimedop		sys_semtimedop_time32	sys_oabi_semtimedop
+313	common	vserver
+314	common	ioprio_set		sys_ioprio_set
+315	common	ioprio_get		sys_ioprio_get
+316	common	inotify_init		sys_inotify_init
+317	common	inotify_add_watch	sys_inotify_add_watch
+318	common	inotify_rm_watch	sys_inotify_rm_watch
+319	common	mbind			sys_mbind
+320	common	get_mempolicy		sys_get_mempolicy
+321	common	set_mempolicy		sys_set_mempolicy
+322	common	openat			sys_openat
+323	common	mkdirat			sys_mkdirat
+324	common	mknodat			sys_mknodat
+325	common	fchownat		sys_fchownat
+326	common	futimesat		sys_futimesat_time32
+327	common	fstatat64		sys_fstatat64		sys_oabi_fstatat64
+328	common	unlinkat		sys_unlinkat
+329	common	renameat		sys_renameat
+330	common	linkat			sys_linkat
+331	common	symlinkat		sys_symlinkat
+332	common	readlinkat		sys_readlinkat
+333	common	fchmodat		sys_fchmodat
+334	common	faccessat		sys_faccessat
+335	common	pselect6		sys_pselect6_time32
+336	common	ppoll			sys_ppoll_time32
+337	common	unshare			sys_unshare
+338	common	set_robust_list		sys_set_robust_list
+339	common	get_robust_list		sys_get_robust_list
+340	common	splice			sys_splice
+341	common	arm_sync_file_range	sys_sync_file_range2
+342	common	tee			sys_tee
+343	common	vmsplice		sys_vmsplice
+344	common	move_pages		sys_move_pages
+345	common	getcpu			sys_getcpu
+346	common	epoll_pwait		sys_epoll_pwait
+347	common	kexec_load		sys_kexec_load
+348	common	utimensat		sys_utimensat_time32
+349	common	signalfd		sys_signalfd
+350	common	timerfd_create		sys_timerfd_create
+351	common	eventfd			sys_eventfd
+352	common	fallocate		sys_fallocate
+353	common	timerfd_settime		sys_timerfd_settime32
+354	common	timerfd_gettime		sys_timerfd_gettime32
+355	common	signalfd4		sys_signalfd4
+356	common	eventfd2		sys_eventfd2
+357	common	epoll_create1		sys_epoll_create1
+358	common	dup3			sys_dup3
+359	common	pipe2			sys_pipe2
+360	common	inotify_init1		sys_inotify_init1
+361	common	preadv			sys_preadv
+362	common	pwritev			sys_pwritev
+363	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo
+364	common	perf_event_open		sys_perf_event_open
+365	common	recvmmsg		sys_recvmmsg_time32
+366	common	accept4			sys_accept4
+367	common	fanotify_init		sys_fanotify_init
+368	common	fanotify_mark		sys_fanotify_mark
+369	common	prlimit64		sys_prlimit64
+370	common	name_to_handle_at	sys_name_to_handle_at
+371	common	open_by_handle_at	sys_open_by_handle_at
+372	common	clock_adjtime		sys_clock_adjtime32
+373	common	syncfs			sys_syncfs
+374	common	sendmmsg		sys_sendmmsg
+375	common	setns			sys_setns
+376	common	process_vm_readv	sys_process_vm_readv
+377	common	process_vm_writev	sys_process_vm_writev
+378	common	kcmp			sys_kcmp
+379	common	finit_module		sys_finit_module
+380	common	sched_setattr		sys_sched_setattr
+381	common	sched_getattr		sys_sched_getattr
+382	common	renameat2		sys_renameat2
+383	common	seccomp			sys_seccomp
+384	common	getrandom		sys_getrandom
+385	common	memfd_create		sys_memfd_create
+386	common	bpf			sys_bpf
+387	common	execveat		sys_execveat
+388	common	userfaultfd		sys_userfaultfd
+389	common	membarrier		sys_membarrier
+390	common	mlock2			sys_mlock2
+391	common	copy_file_range		sys_copy_file_range
+392	common	preadv2			sys_preadv2
+393	common	pwritev2		sys_pwritev2
+394	common	pkey_mprotect		sys_pkey_mprotect
+395	common	pkey_alloc		sys_pkey_alloc
+396	common	pkey_free		sys_pkey_free
+397	common	statx			sys_statx
+398	common	rseq			sys_rseq
+399	common	io_pgetevents		sys_io_pgetevents_time32
+400	common	migrate_pages		sys_migrate_pages
+401	common	kexec_file_load		sys_kexec_file_load
+# 402 is unused
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/arm/include/syscall_table.h b/tools/perf/arch/arm/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/arm/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 692f48db810ccbef229e240db29261f0c60db632..542f3bee1501c751a831df460c4e585ab756c8fc 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -202,6 +202,7 @@ check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscall
 check_2 tools/perf/arch/powerpc/entry/syscalls/syscall.tbl arch/powerpc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
+check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:03 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:03 -0800
Subject: [PATCH v4 05/16] perf tools: sh: Support syscall headers
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-5-bc8caef2ca8e@rivosinc.com>

sh uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
 .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
 tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 472 +++++++++++++++++++++
 tools/perf/arch/sh/include/syscall_table.h         |   2 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 482 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index fa69b056bab31568baba78a9903312bd37b98067..9eb909edbc4a51937c6dc777ada23b82906d19ac 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm
+generic_syscall_table_archs := riscv arc csky arm sh
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/sh/entry/syscalls/Kbuild b/tools/perf/arch/sh/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..25080390e4ed49ae56f314ad712007e674a9168e
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 +=
+syscalltbl = $(srctree)/tools/perf/arch/sh/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sh/entry/syscalls/syscall.tbl b/tools/perf/arch/sh/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..c8cad33bf250ea110de37bd1407f5a43ec5e38f2
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/syscall.tbl
@@ -0,0 +1,472 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for sh
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	restart_syscall			sys_restart_syscall
+1	common	exit				sys_exit
+2	common	fork				sys_fork
+3	common	read				sys_read
+4	common	write				sys_write
+5	common	open				sys_open
+6	common	close				sys_close
+7	common	waitpid				sys_waitpid
+8	common	creat				sys_creat
+9	common	link				sys_link
+10	common	unlink				sys_unlink
+11	common	execve				sys_execve
+12	common	chdir				sys_chdir
+13	common	time				sys_time32
+14	common	mknod				sys_mknod
+15	common	chmod				sys_chmod
+16	common	lchown				sys_lchown16
+# 17 was break
+18	common	oldstat				sys_stat
+19	common	lseek				sys_lseek
+20	common	getpid				sys_getpid
+21	common	mount				sys_mount
+22	common	umount				sys_oldumount
+23	common	setuid				sys_setuid16
+24	common	getuid				sys_getuid16
+25	common	stime				sys_stime32
+26	common	ptrace				sys_ptrace
+27	common	alarm				sys_alarm
+28	common	oldfstat			sys_fstat
+29	common	pause				sys_pause
+30	common	utime				sys_utime32
+# 31 was stty
+# 32 was gtty
+33	common	access				sys_access
+34	common	nice				sys_nice
+# 35 was ftime
+36	common	sync				sys_sync
+37	common	kill				sys_kill
+38	common	rename				sys_rename
+39	common	mkdir				sys_mkdir
+40	common	rmdir				sys_rmdir
+41	common	dup				sys_dup
+42	common	pipe				sys_sh_pipe
+43	common	times				sys_times
+# 44 was prof
+45	common	brk				sys_brk
+46	common	setgid				sys_setgid16
+47	common	getgid				sys_getgid16
+48	common	signal				sys_signal
+49	common	geteuid				sys_geteuid16
+50	common	getegid				sys_getegid16
+51	common	acct				sys_acct
+52	common	umount2				sys_umount
+# 53 was lock
+54	common	ioctl				sys_ioctl
+55	common	fcntl				sys_fcntl
+# 56 was mpx
+57	common	setpgid				sys_setpgid
+# 58 was ulimit
+# 59 was olduname
+60	common	umask				sys_umask
+61	common	chroot				sys_chroot
+62	common	ustat				sys_ustat
+63	common	dup2				sys_dup2
+64	common	getppid				sys_getppid
+65	common	getpgrp				sys_getpgrp
+66	common	setsid				sys_setsid
+67	common	sigaction			sys_sigaction
+68	common	sgetmask			sys_sgetmask
+69	common	ssetmask			sys_ssetmask
+70	common	setreuid			sys_setreuid16
+71	common	setregid			sys_setregid16
+72	common	sigsuspend			sys_sigsuspend
+73	common	sigpending			sys_sigpending
+74	common	sethostname			sys_sethostname
+75	common	setrlimit			sys_setrlimit
+76	common	getrlimit			sys_old_getrlimit
+77	common	getrusage			sys_getrusage
+78	common	gettimeofday			sys_gettimeofday
+79	common	settimeofday			sys_settimeofday
+80	common	getgroups			sys_getgroups16
+81	common	setgroups			sys_setgroups16
+# 82 was select
+83	common	symlink				sys_symlink
+84	common	oldlstat			sys_lstat
+85	common	readlink			sys_readlink
+86	common	uselib				sys_uselib
+87	common	swapon				sys_swapon
+88	common	reboot				sys_reboot
+89	common	readdir				sys_old_readdir
+90	common	mmap				old_mmap
+91	common	munmap				sys_munmap
+92	common	truncate			sys_truncate
+93	common	ftruncate			sys_ftruncate
+94	common	fchmod				sys_fchmod
+95	common	fchown				sys_fchown16
+96	common	getpriority			sys_getpriority
+97	common	setpriority			sys_setpriority
+# 98 was profil
+99	common	statfs				sys_statfs
+100	common	fstatfs				sys_fstatfs
+# 101 was ioperm
+102	common	socketcall			sys_socketcall
+103	common	syslog				sys_syslog
+104	common	setitimer			sys_setitimer
+105	common	getitimer			sys_getitimer
+106	common	stat				sys_newstat
+107	common	lstat				sys_newlstat
+108	common	fstat				sys_newfstat
+109	common	olduname			sys_uname
+# 110 was iopl
+111	common	vhangup				sys_vhangup
+# 112 was idle
+# 113 was vm86old
+114	common	wait4				sys_wait4
+115	common	swapoff				sys_swapoff
+116	common	sysinfo				sys_sysinfo
+117	common	ipc				sys_ipc
+118	common	fsync				sys_fsync
+119	common	sigreturn			sys_sigreturn
+120	common	clone				sys_clone
+121	common	setdomainname			sys_setdomainname
+122	common	uname				sys_newuname
+123	common	cacheflush			sys_cacheflush
+124	common	adjtimex			sys_adjtimex_time32
+125	common	mprotect			sys_mprotect
+126	common	sigprocmask			sys_sigprocmask
+# 127 was create_module
+128	common	init_module			sys_init_module
+129	common	delete_module			sys_delete_module
+# 130 was get_kernel_syms
+131	common	quotactl			sys_quotactl
+132	common	getpgid				sys_getpgid
+133	common	fchdir				sys_fchdir
+134	common	bdflush				sys_ni_syscall
+135	common	sysfs				sys_sysfs
+136	common	personality			sys_personality
+# 137 was afs_syscall
+138	common	setfsuid			sys_setfsuid16
+139	common	setfsgid			sys_setfsgid16
+140	common	_llseek				sys_llseek
+141	common	getdents			sys_getdents
+142	common	_newselect			sys_select
+143	common	flock				sys_flock
+144	common	msync				sys_msync
+145	common	readv				sys_readv
+146	common	writev				sys_writev
+147	common	getsid				sys_getsid
+148	common	fdatasync			sys_fdatasync
+149	common	_sysctl				sys_ni_syscall
+150	common	mlock				sys_mlock
+151	common	munlock				sys_munlock
+152	common	mlockall			sys_mlockall
+153	common	munlockall			sys_munlockall
+154	common	sched_setparam			sys_sched_setparam
+155	common	sched_getparam			sys_sched_getparam
+156	common	sched_setscheduler		sys_sched_setscheduler
+157	common	sched_getscheduler		sys_sched_getscheduler
+158	common	sched_yield			sys_sched_yield
+159	common	sched_get_priority_max		sys_sched_get_priority_max
+160	common	sched_get_priority_min		sys_sched_get_priority_min
+161	common	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+162	common	nanosleep			sys_nanosleep_time32
+163	common	mremap				sys_mremap
+164	common	setresuid			sys_setresuid16
+165	common	getresuid			sys_getresuid16
+# 166 was vm86
+# 167 was query_module
+168	common	poll				sys_poll
+169	common	nfsservctl			sys_ni_syscall
+170	common	setresgid			sys_setresgid16
+171	common	getresgid			sys_getresgid16
+172	common	prctl				sys_prctl
+173	common	rt_sigreturn			sys_rt_sigreturn
+174	common	rt_sigaction			sys_rt_sigaction
+175	common	rt_sigprocmask			sys_rt_sigprocmask
+176	common	rt_sigpending			sys_rt_sigpending
+177	common	rt_sigtimedwait			sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+179	common	rt_sigsuspend			sys_rt_sigsuspend
+180	common	pread64				sys_pread_wrapper
+181	common	pwrite64			sys_pwrite_wrapper
+182	common	chown				sys_chown16
+183	common	getcwd				sys_getcwd
+184	common	capget				sys_capget
+185	common	capset				sys_capset
+186	common	sigaltstack			sys_sigaltstack
+187	common	sendfile			sys_sendfile
+# 188 is reserved for getpmsg
+# 189 is reserved for putpmsg
+190	common	vfork				sys_vfork
+191	common	ugetrlimit			sys_getrlimit
+192	common	mmap2				sys_mmap2
+193	common	truncate64			sys_truncate64
+194	common	ftruncate64			sys_ftruncate64
+195	common	stat64				sys_stat64
+196	common	lstat64				sys_lstat64
+197	common	fstat64				sys_fstat64
+198	common	lchown32			sys_lchown
+199	common	getuid32			sys_getuid
+200	common	getgid32			sys_getgid
+201	common	geteuid32			sys_geteuid
+202	common	getegid32			sys_getegid
+203	common	setreuid32			sys_setreuid
+204	common	setregid32			sys_setregid
+205	common	getgroups32			sys_getgroups
+206	common	setgroups32			sys_setgroups
+207	common	fchown32			sys_fchown
+208	common	setresuid32			sys_setresuid
+209	common	getresuid32			sys_getresuid
+210	common	setresgid32			sys_setresgid
+211	common	getresgid32			sys_getresgid
+212	common	chown32				sys_chown
+213	common	setuid32			sys_setuid
+214	common	setgid32			sys_setgid
+215	common	setfsuid32			sys_setfsuid
+216	common	setfsgid32			sys_setfsgid
+217	common	pivot_root			sys_pivot_root
+218	common	mincore				sys_mincore
+219	common	madvise				sys_madvise
+220	common	getdents64			sys_getdents64
+221	common	fcntl64				sys_fcntl64
+# 222 is reserved for tux
+# 223 is unused
+224	common	gettid				sys_gettid
+225	common	readahead			sys_readahead
+226	common	setxattr			sys_setxattr
+227	common	lsetxattr			sys_lsetxattr
+228	common	fsetxattr			sys_fsetxattr
+229	common	getxattr			sys_getxattr
+230	common	lgetxattr			sys_lgetxattr
+231	common	fgetxattr			sys_fgetxattr
+232	common	listxattr			sys_listxattr
+233	common	llistxattr			sys_llistxattr
+234	common	flistxattr			sys_flistxattr
+235	common	removexattr			sys_removexattr
+236	common	lremovexattr			sys_lremovexattr
+237	common	fremovexattr			sys_fremovexattr
+238	common	tkill				sys_tkill
+239	common	sendfile64			sys_sendfile64
+240	common	futex				sys_futex_time32
+241	common	sched_setaffinity		sys_sched_setaffinity
+242	common	sched_getaffinity		sys_sched_getaffinity
+# 243 is reserved for set_thread_area
+# 244 is reserved for get_thread_area
+245	common	io_setup			sys_io_setup
+246	common	io_destroy			sys_io_destroy
+247	common	io_getevents			sys_io_getevents_time32
+248	common	io_submit			sys_io_submit
+249	common	io_cancel			sys_io_cancel
+250	common	fadvise64			sys_fadvise64
+# 251 is unused
+252	common	exit_group			sys_exit_group
+253	common	lookup_dcookie			sys_ni_syscall
+254	common	epoll_create			sys_epoll_create
+255	common	epoll_ctl			sys_epoll_ctl
+256	common	epoll_wait			sys_epoll_wait
+257	common	remap_file_pages		sys_remap_file_pages
+258	common	set_tid_address			sys_set_tid_address
+259	common	timer_create			sys_timer_create
+260	common	timer_settime			sys_timer_settime32
+261	common	timer_gettime			sys_timer_gettime32
+262	common	timer_getoverrun		sys_timer_getoverrun
+263	common	timer_delete			sys_timer_delete
+264	common	clock_settime			sys_clock_settime32
+265	common	clock_gettime			sys_clock_gettime32
+266	common	clock_getres			sys_clock_getres_time32
+267	common	clock_nanosleep			sys_clock_nanosleep_time32
+268	common	statfs64			sys_statfs64
+269	common	fstatfs64			sys_fstatfs64
+270	common	tgkill				sys_tgkill
+271	common	utimes				sys_utimes_time32
+272	common	fadvise64_64			sys_fadvise64_64_wrapper
+# 273 is reserved for vserver
+274	common	mbind				sys_mbind
+275	common	get_mempolicy			sys_get_mempolicy
+276	common	set_mempolicy			sys_set_mempolicy
+277	common	mq_open				sys_mq_open
+278	common	mq_unlink			sys_mq_unlink
+279	common	mq_timedsend			sys_mq_timedsend_time32
+280	common	mq_timedreceive			sys_mq_timedreceive_time32
+281	common	mq_notify			sys_mq_notify
+282	common	mq_getsetattr			sys_mq_getsetattr
+283	common	kexec_load			sys_kexec_load
+284	common	waitid				sys_waitid
+285	common	add_key				sys_add_key
+286	common	request_key			sys_request_key
+287	common	keyctl				sys_keyctl
+288	common	ioprio_set			sys_ioprio_set
+289	common	ioprio_get			sys_ioprio_get
+290	common	inotify_init			sys_inotify_init
+291	common	inotify_add_watch		sys_inotify_add_watch
+292	common	inotify_rm_watch		sys_inotify_rm_watch
+# 293 is unused
+294	common	migrate_pages			sys_migrate_pages
+295	common	openat				sys_openat
+296	common	mkdirat				sys_mkdirat
+297	common	mknodat				sys_mknodat
+298	common	fchownat			sys_fchownat
+299	common	futimesat			sys_futimesat_time32
+300	common	fstatat64			sys_fstatat64
+301	common	unlinkat			sys_unlinkat
+302	common	renameat			sys_renameat
+303	common	linkat				sys_linkat
+304	common	symlinkat			sys_symlinkat
+305	common	readlinkat			sys_readlinkat
+306	common	fchmodat			sys_fchmodat
+307	common	faccessat			sys_faccessat
+308	common	pselect6			sys_pselect6_time32
+309	common	ppoll				sys_ppoll_time32
+310	common	unshare				sys_unshare
+311	common	set_robust_list			sys_set_robust_list
+312	common	get_robust_list			sys_get_robust_list
+313	common	splice				sys_splice
+314	common	sync_file_range			sys_sh_sync_file_range6
+315	common	tee				sys_tee
+316	common	vmsplice			sys_vmsplice
+317	common	move_pages			sys_move_pages
+318	common	getcpu				sys_getcpu
+319	common	epoll_pwait			sys_epoll_pwait
+320	common	utimensat			sys_utimensat_time32
+321	common	signalfd			sys_signalfd
+322	common	timerfd_create			sys_timerfd_create
+323	common	eventfd				sys_eventfd
+324	common	fallocate			sys_fallocate
+325	common	timerfd_settime			sys_timerfd_settime32
+326	common	timerfd_gettime			sys_timerfd_gettime32
+327	common	signalfd4			sys_signalfd4
+328	common	eventfd2			sys_eventfd2
+329	common	epoll_create1			sys_epoll_create1
+330	common	dup3				sys_dup3
+331	common	pipe2				sys_pipe2
+332	common	inotify_init1			sys_inotify_init1
+333	common	preadv				sys_preadv
+334	common	pwritev				sys_pwritev
+335	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+336	common	perf_event_open			sys_perf_event_open
+337	common	fanotify_init			sys_fanotify_init
+338	common	fanotify_mark			sys_fanotify_mark
+339	common	prlimit64			sys_prlimit64
+340	common	socket				sys_socket
+341	common	bind				sys_bind
+342	common	connect				sys_connect
+343	common	listen				sys_listen
+344	common	accept				sys_accept
+345	common	getsockname			sys_getsockname
+346	common	getpeername			sys_getpeername
+347	common	socketpair			sys_socketpair
+348	common	send				sys_send
+349	common	sendto				sys_sendto
+350	common	recv				sys_recv
+351	common	recvfrom			sys_recvfrom
+352	common	shutdown			sys_shutdown
+353	common	setsockopt			sys_setsockopt
+354	common	getsockopt			sys_getsockopt
+355	common	sendmsg				sys_sendmsg
+356	common	recvmsg				sys_recvmsg
+357	common	recvmmsg			sys_recvmmsg_time32
+358	common	accept4				sys_accept4
+359	common	name_to_handle_at		sys_name_to_handle_at
+360	common	open_by_handle_at		sys_open_by_handle_at
+361	common	clock_adjtime			sys_clock_adjtime32
+362	common	syncfs				sys_syncfs
+363	common	sendmmsg			sys_sendmmsg
+364	common	setns				sys_setns
+365	common	process_vm_readv		sys_process_vm_readv
+366	common	process_vm_writev		sys_process_vm_writev
+367	common	kcmp				sys_kcmp
+368	common	finit_module			sys_finit_module
+369	common	sched_getattr			sys_sched_getattr
+370	common	sched_setattr			sys_sched_setattr
+371	common	renameat2			sys_renameat2
+372	common	seccomp				sys_seccomp
+373	common	getrandom			sys_getrandom
+374	common	memfd_create			sys_memfd_create
+375	common	bpf				sys_bpf
+376	common	execveat			sys_execveat
+377	common	userfaultfd			sys_userfaultfd
+378	common	membarrier			sys_membarrier
+379	common	mlock2				sys_mlock2
+380	common	copy_file_range			sys_copy_file_range
+381	common	preadv2				sys_preadv2
+382	common	pwritev2			sys_pwritev2
+383	common	statx				sys_statx
+384	common	pkey_mprotect			sys_pkey_mprotect
+385	common	pkey_alloc			sys_pkey_alloc
+386	common	pkey_free			sys_pkey_free
+387	common	rseq				sys_rseq
+388	common	sync_file_range2		sys_sync_file_range2
+# room for arch specific syscalls
+393	common	semget				sys_semget
+394	common	semctl				sys_semctl
+395	common	shmget				sys_shmget
+396	common	shmctl				sys_shmctl
+397	common	shmat				sys_shmat
+398	common	shmdt				sys_shmdt
+399	common	msgget				sys_msgget
+400	common	msgsnd				sys_msgsnd
+401	common	msgrcv				sys_msgrcv
+402	common	msgctl				sys_msgctl
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+# 435 reserved for clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/sh/include/syscall_table.h b/tools/perf/arch/sh/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/sh/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 542f3bee1501c751a831df460c4e585ab756c8fc..2f1b42bf337b3d601f0f2e792bd79413f46e583a 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -203,6 +203,7 @@ check_2 tools/perf/arch/powerpc/entry/syscalls/syscall.tbl arch/powerpc/kernel/s
 check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
+check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:04 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:04 -0800
Subject: [PATCH v4 06/16] perf tools: sparc: Support syscall headers
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-6-bc8caef2ca8e@rivosinc.com>

sparc uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
 .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 514 +++++++++++++++++++++
 tools/perf/arch/sparc/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 532 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 9eb909edbc4a51937c6dc777ada23b82906d19ac..2772c05c661bb1a8084255d19a1a75941a8ac8b8 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh
+generic_syscall_table_archs := riscv arc csky arm sh sparc
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/sparc/entry/syscalls/Kbuild b/tools/perf/arch/sparc/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..212c1800b64477c615b8963176d873db5ccabe0c
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscall_abis_64  +=
+syscalltbl = $(srctree)/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sparc/entry/syscalls/syscall.tbl b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..727f99d333b304b3db0711953a3d91ece18a28eb
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
@@ -0,0 +1,514 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for sparc
+#
+# The format is:
+# <number> <abi> <name> <entry point> <compat entry point>
+#
+# The <abi> can be common, 64, or 32 for this file.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	32	exit			sys_exit			sparc_exit
+1	64	exit			sparc_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open			compat_sys_open
+6	common	close			sys_close
+7	common	wait4			sys_wait4			compat_sys_wait4
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	32	execv			sunos_execv
+11	64	execv			sys_nis_syscall
+12	common	chdir			sys_chdir
+13	32    	chown			sys_chown16
+13	64	chown			sys_chown
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	32	lchown			sys_lchown16
+16	64	lchown			sys_lchown
+17	common	brk			sys_brk
+18	common	perfctr			sys_nis_syscall
+19	common	lseek			sys_lseek			compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	capget			sys_capget
+22	common	capset			sys_capset
+23	32    	setuid			sys_setuid16
+23	64    	setuid			sys_setuid
+24	32	getuid			sys_getuid16
+24	64   	getuid			sys_getuid
+25	common	vmsplice		sys_vmsplice
+26	common	ptrace			sys_ptrace			compat_sys_ptrace
+27	common	alarm			sys_alarm
+28	common	sigaltstack		sys_sigaltstack			compat_sys_sigaltstack
+29	32    	pause			sys_pause
+29	64    	pause			sys_nis_syscall
+30	32	utime			sys_utime32
+30	64	utime			sys_utime
+31	32    	lchown32		sys_lchown
+32	32    	fchown32		sys_fchown
+33	common	access			sys_access
+34	common	nice			sys_nice
+35	32    	chown32			sys_chown
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	stat			sys_newstat			compat_sys_newstat
+39	32	sendfile		sys_sendfile			compat_sys_sendfile
+39	64	sendfile		sys_sendfile64
+40	common	lstat			sys_newlstat			compat_sys_newlstat
+41	common	dup			sys_dup
+42	common	pipe			sys_sparc_pipe
+43	common	times			sys_times			compat_sys_times
+44	32    	getuid32		sys_getuid
+45	common	umount2			sys_umount
+46	32	setgid			sys_setgid16
+46	64	setgid			sys_setgid
+47	32	getgid			sys_getgid16
+47	64	getgid			sys_getgid
+48	common	signal			sys_signal
+49	32	geteuid			sys_geteuid16
+49	64	geteuid			sys_geteuid
+50	32	getegid			sys_getegid16
+50	64	getegid			sys_getegid
+51	common	acct			sys_acct
+52	64	memory_ordering		sys_memory_ordering
+53	32	getgid32		sys_getgid
+54	common	ioctl			sys_ioctl			compat_sys_ioctl
+55	common	reboot			sys_reboot
+56	32    	mmap2			sys_mmap2			sys32_mmap2
+57	common	symlink			sys_symlink
+58	common	readlink		sys_readlink
+59	32	execve			sys_execve			sys32_execve
+59	64	execve			sys64_execve
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	fstat			sys_newfstat			compat_sys_newfstat
+63	common	fstat64			sys_fstat64			compat_sys_fstat64
+64	common	getpagesize		sys_getpagesize
+65	common	msync			sys_msync
+66	common	vfork			sys_vfork
+67	common	pread64			sys_pread64			compat_sys_pread64
+68	common	pwrite64		sys_pwrite64			compat_sys_pwrite64
+69	32    	geteuid32		sys_geteuid
+70	32	getegid32		sys_getegid
+71	common	mmap			sys_mmap
+72	32	setreuid32		sys_setreuid
+73	32	munmap			sys_munmap
+73	64	munmap			sys_64_munmap
+74	common	mprotect		sys_mprotect
+75	common	madvise			sys_madvise
+76	common	vhangup			sys_vhangup
+77	32	truncate64		sys_truncate64			compat_sys_truncate64
+78	common	mincore			sys_mincore
+79	32	getgroups		sys_getgroups16
+79	64	getgroups		sys_getgroups
+80	32	setgroups		sys_setgroups16
+80	64	setgroups		sys_setgroups
+81	common	getpgrp			sys_getpgrp
+82	32	setgroups32		sys_setgroups
+83	common	setitimer		sys_setitimer			compat_sys_setitimer
+84	32	ftruncate64		sys_ftruncate64			compat_sys_ftruncate64
+85	common	swapon			sys_swapon
+86	common	getitimer		sys_getitimer			compat_sys_getitimer
+87	32	setuid32		sys_setuid
+88	common	sethostname		sys_sethostname
+89	32	setgid32		sys_setgid
+90	common	dup2			sys_dup2
+91	32	setfsuid32		sys_setfsuid
+92	common	fcntl			sys_fcntl			compat_sys_fcntl
+93	common	select			sys_select			compat_sys_select
+94	32	setfsgid32		sys_setfsgid
+95	common	fsync			sys_fsync
+96	common	setpriority		sys_setpriority
+97	common	socket			sys_socket
+98	common	connect			sys_connect
+99	common	accept			sys_accept
+100	common	getpriority		sys_getpriority
+101	common	rt_sigreturn		sys_rt_sigreturn		sys32_rt_sigreturn
+102	common	rt_sigaction		sys_rt_sigaction		compat_sys_rt_sigaction
+103	common	rt_sigprocmask		sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+104	common	rt_sigpending		sys_rt_sigpending		compat_sys_rt_sigpending
+105	32	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+105	64	rt_sigtimedwait		sys_rt_sigtimedwait
+106	common	rt_sigqueueinfo		sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+107	common	rt_sigsuspend		sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+108	32	setresuid32		sys_setresuid
+108	64	setresuid		sys_setresuid
+109	32	getresuid32		sys_getresuid
+109	64	getresuid		sys_getresuid
+110	32	setresgid32		sys_setresgid
+110	64	setresgid		sys_setresgid
+111	32	getresgid32		sys_getresgid
+111	64	getresgid		sys_getresgid
+112	32	setregid32		sys_setregid
+113	common	recvmsg			sys_recvmsg			compat_sys_recvmsg
+114	common	sendmsg			sys_sendmsg			compat_sys_sendmsg
+115	32	getgroups32		sys_getgroups
+116	common	gettimeofday		sys_gettimeofday		compat_sys_gettimeofday
+117	common	getrusage		sys_getrusage			compat_sys_getrusage
+118	common	getsockopt		sys_getsockopt			sys_getsockopt
+119	common	getcwd			sys_getcwd
+120	common	readv			sys_readv
+121	common	writev			sys_writev
+122	common	settimeofday		sys_settimeofday		compat_sys_settimeofday
+123	32	fchown			sys_fchown16
+123	64	fchown			sys_fchown
+124	common	fchmod			sys_fchmod
+125	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
+126	32	setreuid		sys_setreuid16
+126	64	setreuid		sys_setreuid
+127	32	setregid		sys_setregid16
+127	64	setregid		sys_setregid
+128	common	rename			sys_rename
+129	common	truncate		sys_truncate			compat_sys_truncate
+130	common	ftruncate		sys_ftruncate			compat_sys_ftruncate
+131	common	flock			sys_flock
+132	common	lstat64			sys_lstat64			compat_sys_lstat64
+133	common	sendto			sys_sendto
+134	common	shutdown		sys_shutdown
+135	common	socketpair		sys_socketpair
+136	common	mkdir			sys_mkdir
+137	common	rmdir			sys_rmdir
+138	32	utimes			sys_utimes_time32
+138	64	utimes			sys_utimes
+139	common	stat64			sys_stat64			compat_sys_stat64
+140	common	sendfile64		sys_sendfile64
+141	common	getpeername		sys_getpeername
+142	32	futex			sys_futex_time32
+142	64	futex			sys_futex
+143	common	gettid			sys_gettid
+144	common	getrlimit		sys_getrlimit			compat_sys_getrlimit
+145	common	setrlimit		sys_setrlimit			compat_sys_setrlimit
+146	common	pivot_root		sys_pivot_root
+147	common	prctl			sys_prctl
+148	common	pciconfig_read		sys_pciconfig_read
+149	common	pciconfig_write		sys_pciconfig_write
+150	common	getsockname		sys_getsockname
+151	common	inotify_init		sys_inotify_init
+152	common	inotify_add_watch	sys_inotify_add_watch
+153	common	poll			sys_poll
+154	common	getdents64		sys_getdents64
+155	32	fcntl64			sys_fcntl64			compat_sys_fcntl64
+156	common	inotify_rm_watch	sys_inotify_rm_watch
+157	common	statfs			sys_statfs			compat_sys_statfs
+158	common	fstatfs			sys_fstatfs			compat_sys_fstatfs
+159	common	umount			sys_oldumount
+160	common	sched_set_affinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+161	common	sched_get_affinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+162	common	getdomainname		sys_getdomainname
+163	common	setdomainname		sys_setdomainname
+164	64	utrap_install		sys_utrap_install
+165	common	quotactl		sys_quotactl
+166	common	set_tid_address		sys_set_tid_address
+167	common	mount			sys_mount
+168	common	ustat			sys_ustat			compat_sys_ustat
+169	common	setxattr		sys_setxattr
+170	common	lsetxattr		sys_lsetxattr
+171	common	fsetxattr		sys_fsetxattr
+172	common	getxattr		sys_getxattr
+173	common	lgetxattr		sys_lgetxattr
+174	common	getdents		sys_getdents			compat_sys_getdents
+175	common	setsid			sys_setsid
+176	common	fchdir			sys_fchdir
+177	common	fgetxattr		sys_fgetxattr
+178	common	listxattr		sys_listxattr
+179	common	llistxattr		sys_llistxattr
+180	common	flistxattr		sys_flistxattr
+181	common	removexattr		sys_removexattr
+182	common	lremovexattr		sys_lremovexattr
+183	32	sigpending		sys_sigpending			compat_sys_sigpending
+183	64	sigpending		sys_nis_syscall
+184	common	query_module		sys_ni_syscall
+185	common	setpgid			sys_setpgid
+186	common	fremovexattr		sys_fremovexattr
+187	common	tkill			sys_tkill
+188	32	exit_group		sys_exit_group			sparc_exit_group
+188	64	exit_group		sparc_exit_group
+189	common	uname			sys_newuname
+190	common	init_module		sys_init_module
+191	32	personality		sys_personality			sys_sparc64_personality
+191	64	personality		sys_sparc64_personality
+192	32	remap_file_pages	sys_sparc_remap_file_pages	sys_remap_file_pages
+192	64	remap_file_pages	sys_remap_file_pages
+193	common	epoll_create		sys_epoll_create
+194	common	epoll_ctl		sys_epoll_ctl
+195	common	epoll_wait		sys_epoll_wait
+196	common	ioprio_set		sys_ioprio_set
+197	common	getppid			sys_getppid
+198	32	sigaction		sys_sparc_sigaction		compat_sys_sparc_sigaction
+198	64	sigaction		sys_nis_syscall
+199	common	sgetmask		sys_sgetmask
+200	common	ssetmask		sys_ssetmask
+201	32	sigsuspend		sys_sigsuspend
+201	64	sigsuspend		sys_nis_syscall
+202	common	oldlstat		sys_newlstat			compat_sys_newlstat
+203	common	uselib			sys_uselib
+204	32	readdir			sys_old_readdir			compat_sys_old_readdir
+204	64	readdir			sys_nis_syscall
+205	common	readahead		sys_readahead			compat_sys_readahead
+206	common	socketcall		sys_socketcall			compat_sys_socketcall
+207	common	syslog			sys_syslog
+208	common	lookup_dcookie		sys_ni_syscall
+209	common	fadvise64		sys_fadvise64			compat_sys_fadvise64
+210	common	fadvise64_64		sys_fadvise64_64		compat_sys_fadvise64_64
+211	common	tgkill			sys_tgkill
+212	common	waitpid			sys_waitpid
+213	common	swapoff			sys_swapoff
+214	common	sysinfo			sys_sysinfo			compat_sys_sysinfo
+215	32	ipc			sys_ipc				compat_sys_ipc
+215	64	ipc			sys_sparc_ipc
+216	32	sigreturn		sys_sigreturn			sys32_sigreturn
+216	64	sigreturn		sys_nis_syscall
+217	common	clone			sys_clone
+218	common	ioprio_get		sys_ioprio_get
+219	32	adjtimex		sys_adjtimex_time32
+219	64	adjtimex		sys_sparc_adjtimex
+220	32	sigprocmask		sys_sigprocmask			compat_sys_sigprocmask
+220	64	sigprocmask		sys_nis_syscall
+221	common	create_module		sys_ni_syscall
+222	common	delete_module		sys_delete_module
+223	common	get_kernel_syms		sys_ni_syscall
+224	common	getpgid			sys_getpgid
+225	common	bdflush			sys_ni_syscall
+226	common	sysfs			sys_sysfs
+227	common	afs_syscall		sys_nis_syscall
+228	common	setfsuid		sys_setfsuid16
+229	common	setfsgid		sys_setfsgid16
+230	common	_newselect		sys_select			compat_sys_select
+231	32	time			sys_time32
+232	common	splice			sys_splice
+233	32	stime			sys_stime32
+233	64	stime			sys_stime
+234	common	statfs64		sys_statfs64			compat_sys_statfs64
+235	common	fstatfs64		sys_fstatfs64			compat_sys_fstatfs64
+236	common	_llseek			sys_llseek
+237	common	mlock			sys_mlock
+238	common	munlock			sys_munlock
+239	common	mlockall		sys_mlockall
+240	common	munlockall		sys_munlockall
+241	common	sched_setparam		sys_sched_setparam
+242	common	sched_getparam		sys_sched_getparam
+243	common	sched_setscheduler	sys_sched_setscheduler
+244	common	sched_getscheduler	sys_sched_getscheduler
+245	common	sched_yield		sys_sched_yield
+246	common	sched_get_priority_max	sys_sched_get_priority_max
+247	common	sched_get_priority_min	sys_sched_get_priority_min
+248	32	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+248	64	sched_rr_get_interval	sys_sched_rr_get_interval
+249	32	nanosleep		sys_nanosleep_time32
+249	64	nanosleep		sys_nanosleep
+250	32	mremap			sys_mremap
+250	64	mremap			sys_64_mremap
+251	common	_sysctl			sys_ni_syscall
+252	common	getsid			sys_getsid
+253	common	fdatasync		sys_fdatasync
+254	32	nfsservctl		sys_ni_syscall			sys_nis_syscall
+254	64	nfsservctl		sys_nis_syscall
+255	common	sync_file_range		sys_sync_file_range		compat_sys_sync_file_range
+256	32	clock_settime		sys_clock_settime32
+256	64	clock_settime		sys_clock_settime
+257	32	clock_gettime		sys_clock_gettime32
+257	64	clock_gettime		sys_clock_gettime
+258	32	clock_getres		sys_clock_getres_time32
+258	64	clock_getres		sys_clock_getres
+259	32	clock_nanosleep		sys_clock_nanosleep_time32
+259	64	clock_nanosleep		sys_clock_nanosleep
+260	common	sched_getaffinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+261	common	sched_setaffinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+262	32	timer_settime		sys_timer_settime32
+262	64	timer_settime		sys_timer_settime
+263	32	timer_gettime		sys_timer_gettime32
+263	64	timer_gettime		sys_timer_gettime
+264	common	timer_getoverrun	sys_timer_getoverrun
+265	common	timer_delete		sys_timer_delete
+266	common	timer_create		sys_timer_create		compat_sys_timer_create
+# 267 was vserver
+267	common	vserver			sys_nis_syscall
+268	common	io_setup		sys_io_setup			compat_sys_io_setup
+269	common	io_destroy		sys_io_destroy
+270	common	io_submit		sys_io_submit			compat_sys_io_submit
+271	common	io_cancel		sys_io_cancel
+272	32	io_getevents		sys_io_getevents_time32
+272	64	io_getevents		sys_io_getevents
+273	common	mq_open			sys_mq_open			compat_sys_mq_open
+274	common	mq_unlink		sys_mq_unlink
+275	32	mq_timedsend		sys_mq_timedsend_time32
+275	64	mq_timedsend		sys_mq_timedsend
+276	32	mq_timedreceive		sys_mq_timedreceive_time32
+276	64	mq_timedreceive		sys_mq_timedreceive
+277	common	mq_notify		sys_mq_notify			compat_sys_mq_notify
+278	common	mq_getsetattr		sys_mq_getsetattr		compat_sys_mq_getsetattr
+279	common	waitid			sys_waitid			compat_sys_waitid
+280	common	tee			sys_tee
+281	common	add_key			sys_add_key
+282	common	request_key		sys_request_key
+283	common	keyctl			sys_keyctl			compat_sys_keyctl
+284	common	openat			sys_openat			compat_sys_openat
+285	common	mkdirat			sys_mkdirat
+286	common	mknodat			sys_mknodat
+287	common	fchownat		sys_fchownat
+288	32	futimesat		sys_futimesat_time32
+288	64	futimesat		sys_futimesat
+289	common	fstatat64		sys_fstatat64			compat_sys_fstatat64
+290	common	unlinkat		sys_unlinkat
+291	common	renameat		sys_renameat
+292	common	linkat			sys_linkat
+293	common	symlinkat		sys_symlinkat
+294	common	readlinkat		sys_readlinkat
+295	common	fchmodat		sys_fchmodat
+296	common	faccessat		sys_faccessat
+297	32	pselect6		sys_pselect6_time32		compat_sys_pselect6_time32
+297	64	pselect6		sys_pselect6
+298	32	ppoll			sys_ppoll_time32		compat_sys_ppoll_time32
+298	64	ppoll			sys_ppoll
+299	common	unshare			sys_unshare
+300	common	set_robust_list		sys_set_robust_list		compat_sys_set_robust_list
+301	common	get_robust_list		sys_get_robust_list		compat_sys_get_robust_list
+302	common	migrate_pages		sys_migrate_pages
+303	common	mbind			sys_mbind
+304	common	get_mempolicy		sys_get_mempolicy
+305	common	set_mempolicy		sys_set_mempolicy
+306	common	kexec_load		sys_kexec_load			compat_sys_kexec_load
+307	common	move_pages		sys_move_pages
+308	common	getcpu			sys_getcpu
+309	common	epoll_pwait		sys_epoll_pwait			compat_sys_epoll_pwait
+310	32	utimensat		sys_utimensat_time32
+310	64	utimensat		sys_utimensat
+311	common	signalfd		sys_signalfd			compat_sys_signalfd
+312	common	timerfd_create		sys_timerfd_create
+313	common	eventfd			sys_eventfd
+314	common	fallocate		sys_fallocate			compat_sys_fallocate
+315	32	timerfd_settime		sys_timerfd_settime32
+315	64	timerfd_settime		sys_timerfd_settime
+316	32	timerfd_gettime		sys_timerfd_gettime32
+316	64	timerfd_gettime		sys_timerfd_gettime
+317	common	signalfd4		sys_signalfd4			compat_sys_signalfd4
+318	common	eventfd2		sys_eventfd2
+319	common	epoll_create1		sys_epoll_create1
+320	common	dup3			sys_dup3
+321	common	pipe2			sys_pipe2
+322	common	inotify_init1		sys_inotify_init1
+323	common	accept4			sys_accept4
+324	common	preadv			sys_preadv			compat_sys_preadv
+325	common	pwritev			sys_pwritev			compat_sys_pwritev
+326	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+327	common	perf_event_open		sys_perf_event_open
+328	32	recvmmsg		sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+328	64	recvmmsg		sys_recvmmsg
+329	common	fanotify_init		sys_fanotify_init
+330	common	fanotify_mark		sys_fanotify_mark		compat_sys_fanotify_mark
+331	common	prlimit64		sys_prlimit64
+332	common	name_to_handle_at	sys_name_to_handle_at
+333	common	open_by_handle_at	sys_open_by_handle_at		compat_sys_open_by_handle_at
+334	32	clock_adjtime		sys_clock_adjtime32
+334	64	clock_adjtime		sys_sparc_clock_adjtime
+335	common	syncfs			sys_syncfs
+336	common	sendmmsg		sys_sendmmsg			compat_sys_sendmmsg
+337	common	setns			sys_setns
+338	common	process_vm_readv	sys_process_vm_readv
+339	common	process_vm_writev	sys_process_vm_writev
+340	32	kern_features		sys_ni_syscall			sys_kern_features
+340	64	kern_features		sys_kern_features
+341	common	kcmp			sys_kcmp
+342	common	finit_module		sys_finit_module
+343	common	sched_setattr		sys_sched_setattr
+344	common	sched_getattr		sys_sched_getattr
+345	common	renameat2		sys_renameat2
+346	common	seccomp			sys_seccomp
+347	common	getrandom		sys_getrandom
+348	common	memfd_create		sys_memfd_create
+349	common	bpf			sys_bpf
+350	32	execveat		sys_execveat			sys32_execveat
+350	64	execveat		sys64_execveat
+351	common	membarrier		sys_membarrier
+352	common	userfaultfd		sys_userfaultfd
+353	common	bind			sys_bind
+354	common	listen			sys_listen
+355	common	setsockopt		sys_setsockopt			sys_setsockopt
+356	common	mlock2			sys_mlock2
+357	common	copy_file_range		sys_copy_file_range
+358	common	preadv2			sys_preadv2			compat_sys_preadv2
+359	common	pwritev2		sys_pwritev2			compat_sys_pwritev2
+360	common	statx			sys_statx
+361	32	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+361	64	io_pgetevents		sys_io_pgetevents
+362	common	pkey_mprotect		sys_pkey_mprotect
+363	common	pkey_alloc		sys_pkey_alloc
+364	common	pkey_free		sys_pkey_free
+365	common	rseq			sys_rseq
+# room for arch specific syscalls
+392	64	semtimedop			sys_semtimedop
+393	common	semget			sys_semget
+394	common	semctl			sys_semctl			compat_sys_semctl
+395	common	shmget			sys_shmget
+396	common	shmctl			sys_shmctl			compat_sys_shmctl
+397	common	shmat			sys_shmat			compat_sys_shmat
+398	common	shmdt			sys_shmdt
+399	common	msgget			sys_msgget
+400	common	msgsnd			sys_msgsnd			compat_sys_msgsnd
+401	common	msgrcv			sys_msgrcv			compat_sys_msgrcv
+402	common	msgctl			sys_msgctl			compat_sys_msgctl
+403	32	clock_gettime64			sys_clock_gettime		sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime		sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime		sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime		sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime		sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat			sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop			sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+# 435 reserved for clone3
+436	common	close_range			sys_close_range
+437	common	openat2			sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal 				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/sparc/include/syscall_table.h b/tools/perf/arch/sparc/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/sparc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 2f1b42bf337b3d601f0f2e792bd79413f46e583a..99a278a3f1b5bf44132c817ed1f2623a232d3dc5 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -204,6 +204,7 @@ check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscall
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:05 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:05 -0800
Subject: [PATCH v4 07/16] perf tools: xtensa: Support syscall header
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-7-bc8caef2ca8e@rivosinc.com>

xtensa uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
 .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 439 +++++++++++++++++++++
 tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
 tools/perf/check-headers.sh                        |   1 +
 6 files changed, 449 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 2772c05c661bb1a8084255d19a1a75941a8ac8b8..47fe3c41fa13a388803ba804a7c3a4aac81d20ae 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Kbuild b/tools/perf/arch/xtensa/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..11707c481a24ecf4e220e51eb1aca890fe929a13
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls b/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..d4aa2358460c13945a8299b6513c93d35a5c5ea4
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscalltbl = $(srctree)/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
new file mode 100644
index 0000000000000000000000000000000000000000..37effc1b134eea061f2c350c1d68b4436b65a4dd
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
@@ -0,0 +1,439 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for xtensa
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	spill				sys_ni_syscall
+1	common	xtensa				sys_ni_syscall
+2	common	available4			sys_ni_syscall
+3	common	available5			sys_ni_syscall
+4	common	available6			sys_ni_syscall
+5	common	available7			sys_ni_syscall
+6	common	available8			sys_ni_syscall
+7	common	available9			sys_ni_syscall
+# File Operations
+8	common	open				sys_open
+9	common	close				sys_close
+10	common	dup				sys_dup
+11	common	dup2				sys_dup2
+12	common	read				sys_read
+13	common	write				sys_write
+14	common	select				sys_select
+15	common	lseek				sys_lseek
+16	common	poll				sys_poll
+17	common	_llseek				sys_llseek
+18	common	epoll_wait			sys_epoll_wait
+19	common	epoll_ctl			sys_epoll_ctl
+20	common	epoll_create			sys_epoll_create
+21	common	creat				sys_creat
+22	common	truncate			sys_truncate
+23	common	ftruncate			sys_ftruncate
+24	common	readv				sys_readv
+25	common	writev				sys_writev
+26	common	fsync				sys_fsync
+27	common	fdatasync			sys_fdatasync
+28	common	truncate64			sys_truncate64
+29	common	ftruncate64			sys_ftruncate64
+30	common	pread64				sys_pread64
+31	common	pwrite64			sys_pwrite64
+32	common	link				sys_link
+33	common	rename				sys_rename
+34	common	symlink				sys_symlink
+35	common	readlink			sys_readlink
+36	common	mknod				sys_mknod
+37	common	pipe				sys_pipe
+38	common	unlink				sys_unlink
+39	common	rmdir				sys_rmdir
+40	common	mkdir				sys_mkdir
+41	common	chdir				sys_chdir
+42	common	fchdir				sys_fchdir
+43	common	getcwd				sys_getcwd
+44	common	chmod				sys_chmod
+45	common	chown				sys_chown
+46	common	stat				sys_newstat
+47	common	stat64				sys_stat64
+48	common	lchown				sys_lchown
+49	common	lstat				sys_newlstat
+50	common	lstat64				sys_lstat64
+51	common	available51			sys_ni_syscall
+52	common	fchmod				sys_fchmod
+53	common	fchown				sys_fchown
+54	common	fstat				sys_newfstat
+55	common	fstat64				sys_fstat64
+56	common	flock				sys_flock
+57	common	access				sys_access
+58	common	umask				sys_umask
+59	common	getdents			sys_getdents
+60	common	getdents64			sys_getdents64
+61	common	fcntl64				sys_fcntl64
+62	common	fallocate			sys_fallocate
+63	common	fadvise64_64			xtensa_fadvise64_64
+64	common	utime				sys_utime32
+65	common	utimes				sys_utimes_time32
+66	common	ioctl				sys_ioctl
+67	common	fcntl				sys_fcntl
+68	common	setxattr			sys_setxattr
+69	common	getxattr			sys_getxattr
+70	common	listxattr			sys_listxattr
+71	common	removexattr			sys_removexattr
+72	common	lsetxattr			sys_lsetxattr
+73	common	lgetxattr			sys_lgetxattr
+74	common	llistxattr			sys_llistxattr
+75	common	lremovexattr			sys_lremovexattr
+76	common	fsetxattr			sys_fsetxattr
+77	common	fgetxattr			sys_fgetxattr
+78	common	flistxattr			sys_flistxattr
+79	common	fremovexattr			sys_fremovexattr
+# File Map / Shared Memory Operations
+80	common	mmap2				sys_mmap_pgoff
+81	common	munmap				sys_munmap
+82	common	mprotect			sys_mprotect
+83	common	brk				sys_brk
+84	common	mlock				sys_mlock
+85	common	munlock				sys_munlock
+86	common	mlockall			sys_mlockall
+87	common	munlockall			sys_munlockall
+88	common	mremap				sys_mremap
+89	common	msync				sys_msync
+90	common	mincore				sys_mincore
+91	common	madvise				sys_madvise
+92	common	shmget				sys_shmget
+93	common	shmat				xtensa_shmat
+94	common	shmctl				sys_old_shmctl
+95	common	shmdt				sys_shmdt
+# Socket Operations
+96	common	socket				sys_socket
+97	common	setsockopt			sys_setsockopt
+98	common	getsockopt			sys_getsockopt
+99	common	shutdown			sys_shutdown
+100	common	bind				sys_bind
+101	common	connect				sys_connect
+102	common	listen				sys_listen
+103	common	accept				sys_accept
+104	common	getsockname			sys_getsockname
+105	common	getpeername			sys_getpeername
+106	common	sendmsg				sys_sendmsg
+107	common	recvmsg				sys_recvmsg
+108	common	send				sys_send
+109	common	recv				sys_recv
+110	common	sendto				sys_sendto
+111	common	recvfrom			sys_recvfrom
+112	common	socketpair			sys_socketpair
+113	common	sendfile			sys_sendfile
+114	common	sendfile64			sys_sendfile64
+115	common	sendmmsg			sys_sendmmsg
+# Process Operations
+116	common	clone				sys_clone
+117	common	execve				sys_execve
+118	common	exit				sys_exit
+119	common	exit_group			sys_exit_group
+120	common	getpid				sys_getpid
+121	common	wait4				sys_wait4
+122	common	waitid				sys_waitid
+123	common	kill				sys_kill
+124	common	tkill				sys_tkill
+125	common	tgkill				sys_tgkill
+126	common	set_tid_address			sys_set_tid_address
+127	common	gettid				sys_gettid
+128	common	setsid				sys_setsid
+129	common	getsid				sys_getsid
+130	common	prctl				sys_prctl
+131	common	personality			sys_personality
+132	common	getpriority			sys_getpriority
+133	common	setpriority			sys_setpriority
+134	common	setitimer			sys_setitimer
+135	common	getitimer			sys_getitimer
+136	common	setuid				sys_setuid
+137	common	getuid				sys_getuid
+138	common	setgid				sys_setgid
+139	common	getgid				sys_getgid
+140	common	geteuid				sys_geteuid
+141	common	getegid				sys_getegid
+142	common	setreuid			sys_setreuid
+143	common	setregid			sys_setregid
+144	common	setresuid			sys_setresuid
+145	common	getresuid			sys_getresuid
+146	common	setresgid			sys_setresgid
+147	common	getresgid			sys_getresgid
+148	common	setpgid				sys_setpgid
+149	common	getpgid				sys_getpgid
+150	common	getppid				sys_getppid
+151	common	getpgrp				sys_getpgrp
+# 152 was set_thread_area
+152	common	reserved152			sys_ni_syscall
+# 153 was get_thread_area
+153	common	reserved153			sys_ni_syscall
+154	common	times				sys_times
+155	common	acct				sys_acct
+156	common	sched_setaffinity		sys_sched_setaffinity
+157	common	sched_getaffinity		sys_sched_getaffinity
+158	common	capget				sys_capget
+159	common	capset				sys_capset
+160	common	ptrace				sys_ptrace
+161	common	semtimedop			sys_semtimedop_time32
+162	common	semget				sys_semget
+163	common	semop				sys_semop
+164	common	semctl				sys_old_semctl
+165	common	available165			sys_ni_syscall
+166	common	msgget				sys_msgget
+167	common	msgsnd				sys_msgsnd
+168	common	msgrcv				sys_msgrcv
+169	common	msgctl				sys_old_msgctl
+170	common	available170			sys_ni_syscall
+# File System
+171	common	umount2				sys_umount
+172	common	mount				sys_mount
+173	common	swapon				sys_swapon
+174	common	chroot				sys_chroot
+175	common	pivot_root			sys_pivot_root
+176	common	umount				sys_oldumount
+177	common	swapoff				sys_swapoff
+178	common	sync				sys_sync
+179	common	syncfs				sys_syncfs
+180	common	setfsuid			sys_setfsuid
+181	common	setfsgid			sys_setfsgid
+182	common	sysfs				sys_sysfs
+183	common	ustat				sys_ustat
+184	common	statfs				sys_statfs
+185	common	fstatfs				sys_fstatfs
+186	common	statfs64			sys_statfs64
+187	common	fstatfs64			sys_fstatfs64
+# System
+188	common	setrlimit			sys_setrlimit
+189	common	getrlimit			sys_getrlimit
+190	common	getrusage			sys_getrusage
+191	common	futex				sys_futex_time32
+192	common	gettimeofday			sys_gettimeofday
+193	common	settimeofday			sys_settimeofday
+194	common	adjtimex			sys_adjtimex_time32
+195	common	nanosleep			sys_nanosleep_time32
+196	common	getgroups			sys_getgroups
+197	common	setgroups			sys_setgroups
+198	common	sethostname			sys_sethostname
+199	common	setdomainname			sys_setdomainname
+200	common	syslog				sys_syslog
+201	common	vhangup				sys_vhangup
+202	common	uselib				sys_uselib
+203	common	reboot				sys_reboot
+204	common	quotactl			sys_quotactl
+# 205 was old nfsservctl
+205	common	nfsservctl			sys_ni_syscall
+206	common	_sysctl				sys_ni_syscall
+207	common	bdflush				sys_ni_syscall
+208	common	uname				sys_newuname
+209	common	sysinfo				sys_sysinfo
+210	common	init_module			sys_init_module
+211	common	delete_module			sys_delete_module
+212	common	sched_setparam			sys_sched_setparam
+213	common	sched_getparam			sys_sched_getparam
+214	common	sched_setscheduler		sys_sched_setscheduler
+215	common	sched_getscheduler		sys_sched_getscheduler
+216	common	sched_get_priority_max		sys_sched_get_priority_max
+217	common	sched_get_priority_min		sys_sched_get_priority_min
+218	common	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+219	common	sched_yield			sys_sched_yield
+222	common	available222			sys_ni_syscall
+# Signal Handling
+223	common	restart_syscall			sys_restart_syscall
+224	common	sigaltstack			sys_sigaltstack
+225	common	rt_sigreturn			xtensa_rt_sigreturn
+226	common	rt_sigaction			sys_rt_sigaction
+227	common	rt_sigprocmask			sys_rt_sigprocmask
+228	common	rt_sigpending			sys_rt_sigpending
+229	common	rt_sigtimedwait			sys_rt_sigtimedwait_time32
+230	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+231	common	rt_sigsuspend			sys_rt_sigsuspend
+# Message
+232	common	mq_open				sys_mq_open
+233	common	mq_unlink			sys_mq_unlink
+234	common	mq_timedsend			sys_mq_timedsend_time32
+235	common	mq_timedreceive			sys_mq_timedreceive_time32
+236	common	mq_notify			sys_mq_notify
+237	common	mq_getsetattr			sys_mq_getsetattr
+238	common	available238			sys_ni_syscall
+239	common	io_setup			sys_io_setup
+# IO
+240	common	io_destroy			sys_io_destroy
+241	common	io_submit			sys_io_submit
+242	common	io_getevents			sys_io_getevents_time32
+243	common	io_cancel			sys_io_cancel
+244	common	clock_settime			sys_clock_settime32
+245	common	clock_gettime			sys_clock_gettime32
+246	common	clock_getres			sys_clock_getres_time32
+247	common	clock_nanosleep			sys_clock_nanosleep_time32
+# Timer
+248	common	timer_create			sys_timer_create
+249	common	timer_delete			sys_timer_delete
+250	common	timer_settime			sys_timer_settime32
+251	common	timer_gettime			sys_timer_gettime32
+252	common	timer_getoverrun		sys_timer_getoverrun
+# System
+253	common	reserved253			sys_ni_syscall
+254	common	lookup_dcookie			sys_ni_syscall
+255	common	available255			sys_ni_syscall
+256	common	add_key				sys_add_key
+257	common	request_key			sys_request_key
+258	common	keyctl				sys_keyctl
+259	common	available259			sys_ni_syscall
+260	common	readahead			sys_readahead
+261	common	remap_file_pages		sys_remap_file_pages
+262	common	migrate_pages			sys_migrate_pages
+263	common	mbind				sys_mbind
+264	common	get_mempolicy			sys_get_mempolicy
+265	common	set_mempolicy			sys_set_mempolicy
+266	common	unshare				sys_unshare
+267	common	move_pages			sys_move_pages
+268	common	splice				sys_splice
+269	common	tee				sys_tee
+270	common	vmsplice			sys_vmsplice
+271	common	available271			sys_ni_syscall
+272	common	pselect6			sys_pselect6_time32
+273	common	ppoll				sys_ppoll_time32
+274	common	epoll_pwait			sys_epoll_pwait
+275	common	epoll_create1			sys_epoll_create1
+276	common	inotify_init			sys_inotify_init
+277	common	inotify_add_watch		sys_inotify_add_watch
+278	common	inotify_rm_watch		sys_inotify_rm_watch
+279	common	inotify_init1			sys_inotify_init1
+280	common	getcpu				sys_getcpu
+281	common	kexec_load			sys_ni_syscall
+282	common	ioprio_set			sys_ioprio_set
+283	common	ioprio_get			sys_ioprio_get
+284	common	set_robust_list			sys_set_robust_list
+285	common	get_robust_list			sys_get_robust_list
+286	common	available286			sys_ni_syscall
+287	common	available287			sys_ni_syscall
+# Relative File Operations
+288	common	openat				sys_openat
+289	common	mkdirat				sys_mkdirat
+290	common	mknodat				sys_mknodat
+291	common	unlinkat			sys_unlinkat
+292	common	renameat			sys_renameat
+293	common	linkat				sys_linkat
+294	common	symlinkat			sys_symlinkat
+295	common	readlinkat			sys_readlinkat
+296	common	utimensat			sys_utimensat_time32
+297	common	fchownat			sys_fchownat
+298	common	futimesat			sys_futimesat_time32
+299	common	fstatat64			sys_fstatat64
+300	common	fchmodat			sys_fchmodat
+301	common	faccessat			sys_faccessat
+302	common	available302			sys_ni_syscall
+303	common	available303			sys_ni_syscall
+304	common	signalfd			sys_signalfd
+# 305 was timerfd
+306	common	eventfd				sys_eventfd
+307	common	recvmmsg			sys_recvmmsg_time32
+308	common	setns				sys_setns
+309	common	signalfd4			sys_signalfd4
+310	common	dup3				sys_dup3
+311	common	pipe2				sys_pipe2
+312	common	timerfd_create			sys_timerfd_create
+313	common	timerfd_settime			sys_timerfd_settime32
+314	common	timerfd_gettime			sys_timerfd_gettime32
+315	common	available315			sys_ni_syscall
+316	common	eventfd2			sys_eventfd2
+317	common	preadv				sys_preadv
+318	common	pwritev				sys_pwritev
+319	common	available319			sys_ni_syscall
+320	common	fanotify_init			sys_fanotify_init
+321	common	fanotify_mark			sys_fanotify_mark
+322	common	process_vm_readv		sys_process_vm_readv
+323	common	process_vm_writev		sys_process_vm_writev
+324	common	name_to_handle_at		sys_name_to_handle_at
+325	common	open_by_handle_at		sys_open_by_handle_at
+326	common	sync_file_range2		sys_sync_file_range2
+327	common	perf_event_open			sys_perf_event_open
+328	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+329	common	clock_adjtime			sys_clock_adjtime32
+330	common	prlimit64			sys_prlimit64
+331	common	kcmp				sys_kcmp
+332	common	finit_module			sys_finit_module
+333	common	accept4				sys_accept4
+334	common	sched_setattr			sys_sched_setattr
+335	common	sched_getattr			sys_sched_getattr
+336	common	renameat2			sys_renameat2
+337	common	seccomp				sys_seccomp
+338	common	getrandom			sys_getrandom
+339	common	memfd_create			sys_memfd_create
+340	common	bpf				sys_bpf
+341	common	execveat			sys_execveat
+342	common	userfaultfd			sys_userfaultfd
+343	common	membarrier			sys_membarrier
+344	common	mlock2				sys_mlock2
+345	common	copy_file_range			sys_copy_file_range
+346	common	preadv2				sys_preadv2
+347	common	pwritev2			sys_pwritev2
+348	common	pkey_mprotect			sys_pkey_mprotect
+349	common	pkey_alloc			sys_pkey_alloc
+350	common	pkey_free			sys_pkey_free
+351	common	statx				sys_statx
+352	common	rseq				sys_rseq
+# 353 through 402 are unassigned to sync up with generic numbers
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal 				sys_mseal
+463	common	setxattrat			sys_setxattrat
+464	common	getxattrat			sys_getxattrat
+465	common	listxattrat			sys_listxattrat
+466	common	removexattrat			sys_removexattrat
diff --git a/tools/perf/arch/xtensa/include/syscall_table.h b/tools/perf/arch/xtensa/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c942821662d95216765b176a84d5fc7974e1064
--- /dev/null
+++ b/tools/perf/arch/xtensa/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 99a278a3f1b5bf44132c817ed1f2623a232d3dc5..e9e352579e6d33085a1d863441432c81d2353f49 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -205,6 +205,7 @@ check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/sys
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Wed Dec 18 01:24:06 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 18 Dec 2024 01:24:06 -0800
Subject: [PATCH v4 08/16] perf tools: x86: Use generic syscall scripts
In-Reply-To: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
References: <20241218-perf_syscalltbl-v4-0-bc8caef2ca8e@rivosinc.com>
Message-ID: <20241218-perf_syscalltbl-v4-8-bc8caef2ca8e@rivosinc.com>

Use the generic scripts to generate headers from the syscall table for
both 32- and 64-bit x86.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  3 +-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/x86/Build                          |  1 -
 tools/perf/arch/x86/Makefile                       | 25 -------------
 tools/perf/arch/x86/entry/syscalls/Kbuild          |  3 ++
 .../perf/arch/x86/entry/syscalls/Makefile.syscalls |  6 ++++
 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   | 42 ----------------------
 tools/perf/arch/x86/include/syscall_table.h        |  8 +++++
 tools/perf/util/syscalltbl.c                       | 10 +-----
 9 files changed, 20 insertions(+), 80 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index a09e2245a9ba00db79cf3a65e8772a6cb9b6c78e..7accb54e60aac2e615ddf03e8f4ffa8cff539aaa 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,7 +31,7 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 powerpc arm64 s390 mips loongarch riscv))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips loongarch))
     NO_SYSCALL_TABLE := 0
   endif
 
@@ -58,7 +58,6 @@ endif
 # Additional ARCH settings for x86
 ifeq ($(SRCARCH),x86)
   $(call detected,CONFIG_X86)
-  CFLAGS += -I$(OUTPUT)arch/x86/include/generated
   ifeq (${IS_64_BIT}, 1)
     CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT
     ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 47fe3c41fa13a388803ba804a7c3a4aac81d20ae..698967f50ceb5cfc29dc5c2947c995980120e64e 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa
+generic_syscall_table_archs := riscv arc csky arm sh sparc xtensa x86
 ifneq ($(filter $(SRCARCH), $(generic_syscall_table_archs)),)
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
diff --git a/tools/perf/arch/x86/Build b/tools/perf/arch/x86/Build
index 87d0574913431b7c4505caf78f41d48b180a2fbc..02a1ca780a2071d322f75fb2885c3a36bc278e8d 100644
--- a/tools/perf/arch/x86/Build
+++ b/tools/perf/arch/x86/Build
@@ -2,7 +2,6 @@ perf-util-y += util/
 perf-test-y += tests/
 
 ifdef SHELLCHECK
-  SHELL_TESTS := entry/syscalls/syscalltbl.sh
   TEST_LOGS := $(SHELL_TESTS:%=%.shellcheck_log)
 else
   SHELL_TESTS :=
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index a6b6e0a9308a8e401c65eb802e5815a41fbdefe9..a295a80ea078199547e816d18531820bfdba7961 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -1,28 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
-
-###
-# Syscall table generation
-#
-
-generated := $(OUTPUT)arch/x86/include/generated
-out       := $(generated)/asm
-header    := $(out)/syscalls_64.c
-header_32 := $(out)/syscalls_32.c
-sys       := $(srctree)/tools/perf/arch/x86/entry/syscalls
-systbl    := $(sys)/syscalltbl.sh
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sys)/syscall_64.tbl $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
-
-$(header_32): $(sys)/syscall_32.tbl $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_32.tbl 'x86' > $@
-
-clean::
-	$(call QUIET_CLEAN, x86) $(RM) -r $(header) $(generated)
-
-archheaders: $(header) $(header_32)
diff --git a/tools/perf/arch/x86/entry/syscalls/Kbuild b/tools/perf/arch/x86/entry/syscalls/Kbuild
new file mode 100644
index 0000000000000000000000000000000000000000..84c6599b4ea6a160217a3496449b205f2263f0fb
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls b/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
new file mode 100644
index 0000000000000000000000000000000000000000..db3d5d6d4e5699d338afc55f6415612ef924d985
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += i386
+syscall_abis_64 +=
+
+syscalltbl = $(srctree)/tools/perf/arch/x86/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh b/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
deleted file mode 100755
index 2b71f99933a549607b0c18aa2b8be16b860f603c..0000000000000000000000000000000000000000
--- a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-in="$1"
-arch="$2"
-
-syscall_macro() {
-    nr="$1"
-    name="$2"
-
-    echo "	[$nr] = \"$name\","
-}
-
-emit() {
-    nr="$1"
-    entry="$2"
-
-    syscall_macro "$nr" "$entry"
-}
-
-echo "static const char *const syscalltbl_${arch}[] = {"
-
-sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
-grep '^[0-9]' "$in" | sort -n > $sorted_table
-
-max_nr=0
-# the params are: nr abi name entry compat
-# use _ for intentionally unused variables according to SC2034
-while read nr _ name _ _; do
-    if [ $nr -ge 512 ] ; then # discard compat sycalls
-        break
-    fi
-
-    emit "$nr" "$name"
-    max_nr=$nr
-done < $sorted_table
-
-rm -f $sorted_table
-
-echo "};"
-
-echo "#define SYSCALLTBL_${arch}_MAX_ID ${max_nr}"
diff --git a/tools/perf/arch/x86/include/syscall_table.h b/tools/perf/arch/x86/include/syscall_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ff51b783000d727ec48be960730b81ecdb05575
--- /dev/null
+++ b/tools/perf/arch/x86/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index ccf234a54366f9921c3b9a02ffb0a365d17244bc..02f23483bfff83809c4e649a2d054dba6975d12c 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -14,15 +14,7 @@
 #include <string.h>
 #include "string2.h"
 
-#if defined(__x86_64__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_x86_64;
-#elif defined(__i386__)
-#include <asm/syscalls_32.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_x86_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_x86;
-#elif defined(__s390x__)
+#if defined(__s390x__)
 #include <asm/syscalls_64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_s390_64;

-- 
2.34.1



From suzuki.poulose at arm.com  Wed Dec 18 01:38:19 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 18 Dec 2024 09:38:19 +0000
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <20241217063324.33781-3-quic_jinlmao@quicinc.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-3-quic_jinlmao@quicinc.com>
Message-ID: <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>

On 17/12/2024 06:33, Mao Jinlong wrote:
> For some coresight components like CTI and TPDM, there could be
> numerous of them. From the node name, we can only get the type and
> register address of the component. We can't identify the HW or the
> system the component belongs to. Add label sysfs node support for
> showing the intuitive name of the device.
> 
> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
> ---
>   .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
>   .../sysfs-bus-coresight-devices-funnel        |  6 ++++
>   .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
>   drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++++++++++++++++++
>   4 files changed, 50 insertions(+)

Do you think we need to name the devices using the label ? Or is this 
enough ?

Suzuki


> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> index bf2869c413e7..909670e0451a 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> @@ -239,3 +239,9 @@ Date:		March 2020
>   KernelVersion	5.7
>   Contact:	Mike Leach or Mathieu Poirier
>   Description:	(Write) Clear all channel / trigger programming.
> +
> +What:           /sys/bus/coresight/devices/<cti-name>/label
> +Date:           Dec 2024
> +KernelVersion   6.14
> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> +Description:    (Read) Show hardware context information of device.
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> index d75acda5e1b3..944aad879aeb 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> @@ -10,3 +10,9 @@ Date:		November 2014
>   KernelVersion:	3.19
>   Contact:	Mathieu Poirier <mathieu.poirier at linaro.org>
>   Description:	(RW) Defines input port priority order.
> +
> +What:           /sys/bus/coresight/devices/<memory_map>.funnel/label
> +Date:           Dec 2024
> +KernelVersion   6.14
> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> +Description:    (Read) Show hardware context information of device.
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> index bf710ea6e0ef..309802246398 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -257,3 +257,9 @@ 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 CMB subunit
>   		TPDM.
> +
> +What:           /sys/bus/coresight/devices/<tpdm-name>/label
> +Date:           Dec 2024
> +KernelVersion   6.14
> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> +Description:    (Read) Show hardware context information of device.
> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
> index a01c9e54e2ed..4af40cd7d75a 100644
> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
> @@ -7,6 +7,7 @@
>   #include <linux/device.h>
>   #include <linux/idr.h>
>   #include <linux/kernel.h>
> +#include <linux/property.h>
>   
>   #include "coresight-priv.h"
>   #include "coresight-trace-id.h"
> @@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device *dev,
>   }
>   static DEVICE_ATTR_RW(enable_source);
>   
> +static ssize_t label_show(struct device *dev,
> +		struct device_attribute *attr, char *buf)
> +{
> +
> +	const char *str;
> +	int ret = 0;
> +
> +	ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
> +	if (ret == 0)
> +		return scnprintf(buf, PAGE_SIZE, "%s\n", str);
> +	else
> +		return ret;
> +}
> +static DEVICE_ATTR_RO(label);
> +
>   static struct attribute *coresight_sink_attrs[] = {
>   	&dev_attr_enable_sink.attr,
> +	&dev_attr_label.attr,
>   	NULL,
>   };
>   ATTRIBUTE_GROUPS(coresight_sink);
>   
>   static struct attribute *coresight_source_attrs[] = {
>   	&dev_attr_enable_source.attr,
> +	&dev_attr_label.attr,
>   	NULL,
>   };
>   ATTRIBUTE_GROUPS(coresight_source);
>   
> +static struct attribute *coresight_link_attrs[] = {
> +	&dev_attr_label.attr,
> +	NULL,
> +};
> +ATTRIBUTE_GROUPS(coresight_link);
> +
> +static struct attribute *coresight_helper_attrs[] = {
> +	&dev_attr_label.attr,
> +	NULL,
> +};
> +ATTRIBUTE_GROUPS(coresight_helper);
> +
>   const struct device_type coresight_dev_type[] = {
>   	[CORESIGHT_DEV_TYPE_SINK] = {
>   		.name = "sink",
> @@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
>   	},
>   	[CORESIGHT_DEV_TYPE_LINK] = {
>   		.name = "link",
> +		.groups = coresight_link_groups,
>   	},
>   	[CORESIGHT_DEV_TYPE_LINKSINK] = {
>   		.name = "linksink",
> @@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
>   	},
>   	[CORESIGHT_DEV_TYPE_HELPER] = {
>   		.name = "helper",
> +		.groups = coresight_helper_groups,
>   	}
>   };
>   /* Ensure the enum matches the names and groups */



From manivannan.sadhasivam at linaro.org  Wed Dec 18 01:46:06 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 18 Dec 2024 15:16:06 +0530
Subject: [PATCH v2 2/5] PCI: stm32: Add PCIe host support for STM32MP25
In-Reply-To: <ced7a55a-d968-497f-abc2-663855882a3f@foss.st.com>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-3-christian.bruel@foss.st.com>
 <20241203145244.trgrobtfmumtiwuc@thinkpad>
 <ced7a55a-d968-497f-abc2-663855882a3f@foss.st.com>
Message-ID: <20241218094606.sljdx2w27thc5ahj@thinkpad>

On Mon, Dec 16, 2024 at 10:00:27AM +0100, Christian Bruel wrote:

[...]

> > 
> > > +		msleep(PCIE_T_RRS_READY_MS);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static void stm32_pcie_stop_link(struct dw_pcie *pci)
> > > +{
> > > +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
> > > +
> > > +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
> > > +			   STM32MP25_PCIECR_LTSSM_EN, 0);
> > > +
> > > +	/* Assert PERST# */
> > > +	if (stm32_pcie->perst_gpio)
> > > +		gpiod_set_value(stm32_pcie->perst_gpio, 1);
> > 
> > I don't like tying PERST# handling with start/stop link. PERST# should be
> > handled based on the power/clock state.
> 
> I don't understand your point: We turn off the PHY in suspend_noirq(), so
> that seems a logical place to de-assert in resume_noirq after the refclk is
> ready. PERST# should be kept active until the PHY stablilizes the clock in
> resume. From the PCIe electromechanical specs, PERST# goes active while the
> refclk is not stable/
> 

While your understanding about PERST# is correct, your implementation is not.
You are toggling PERST# from start/stop link callbacks which are supposed to
control the LTSSM state only. I don't have issues with toggling PERST# in
stm32_pcie_{suspend/resume}_noirq().

> 
> > 
> > > +}
> > > +
> > > +static int stm32_pcie_suspend(struct device *dev)
> > > +{
> > > +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> > > +
> > > +	if (device_may_wakeup(dev) || device_wakeup_path(dev))
> > > +		enable_irq_wake(stm32_pcie->wake_irq);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int stm32_pcie_resume(struct device *dev)
> > > +{
> > > +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> > > +
> > > +	if (device_may_wakeup(dev) || device_wakeup_path(dev))
> > > +		disable_irq_wake(stm32_pcie->wake_irq);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int stm32_pcie_suspend_noirq(struct device *dev)
> > > +{
> > > +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> > > +
> > > +	stm32_pcie->link_is_up = dw_pcie_link_up(stm32_pcie->pci);
> > > +
> > > +	stm32_pcie_stop_link(stm32_pcie->pci);
> > 
> > I don't understand how endpoint can wakeup the host if PERST# gets asserted.
> 
> The stm32 PCIe doesn't support L2, we don't expect an in-band beacon for the
> wakeup. We support wakeup only from sideband WAKE#, that will restart the
> link from IRQ
> 

I don't understand how WAKE# is supported without L2. Only in L2 state, endpoint
will make use of Vaux and it will wakeup the host using either beacon or WAKE#.
If you don't support L2, then the endpoint will reach L3 (link off) state.

> > 
> > > +	clk_disable_unprepare(stm32_pcie->clk);
> > > +
> > > +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev))
> > > +		phy_exit(stm32_pcie->phy);
> > > +
> > > +	return pinctrl_pm_select_sleep_state(dev);
> > > +}
> > > +
> > > +static int stm32_pcie_resume_noirq(struct device *dev)
> > > +{
> > > +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> > > +	struct dw_pcie *pci = stm32_pcie->pci;
> > > +	struct dw_pcie_rp *pp = &pci->pp;
> > > +	int ret;
> > > +
> > > +	/* init_state must be called first to force clk_req# gpio when no
> > 
> > CLKREQ#
> > 
> > Why RC should control CLKREQ#?
> 
> REFCLK is gated with CLKREQ#, So we cannot access the core
> without CLKREQ# if no device is present. So force it with a init pinmux
> the time to init the PHY and the core DBI registers
> 

Ok. You should add a comment to clarify it in the code as this is not a standard
behavior.

> > 
> > Also please use preferred style for multi-line comments:
> > 
> > 	/*
> > 	 * ...
> > 	 */
> > 
> > > +	 * device is plugged.
> > > +	 */
> > > +	if (!IS_ERR(dev->pins->init_state))
> > > +		ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
> > > +	else
> > > +		ret = pinctrl_pm_select_default_state(dev);
> > > +
> > > +	if (ret) {
> > > +		dev_err(dev, "Failed to activate pinctrl pm state: %d\n", ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev)) {
> > > +		ret = phy_init(stm32_pcie->phy);
> > > +		if (ret) {
> > > +			pinctrl_pm_select_default_state(dev);
> > > +			return ret;
> > > +		}
> > > +	}
> > > +
> > > +	ret = clk_prepare_enable(stm32_pcie->clk);
> > > +	if (ret)
> > > +		goto clk_err;
> > 
> > Please name the goto labels of their purpose. Like err_phy_exit.
> 
> OK
> 
> > 
> > > +
> > > +	ret = dw_pcie_setup_rc(pp);
> > > +	if (ret)
> > > +		goto pcie_err;
> > 
> > This should be, 'err_disable_clk'.
> > 
> > > +
> > > +	if (stm32_pcie->link_is_up) {
> > 
> > Why do you need this check? You cannot start the link in the absence of an
> > endpoint?
> > 
> 
> It is an optimization to avoid unnecessary "dw_pcie_wait_for_link" if no
> device is present during suspend
> 

In that case you'll not trigger LTSSM if there was no endpoint connected before
suspend. What if users connect an endpoint after resume?

- Mani

-- 
????????? ????????


From Mike.Leach at arm.com  Wed Dec 18 01:56:49 2024
From: Mike.Leach at arm.com (Mike Leach)
Date: Wed, 18 Dec 2024 09:56:49 +0000
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-3-quic_jinlmao@quicinc.com>
 <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>
Message-ID: <PAVPR08MB967401DC65384CBA26B6829C8C052@PAVPR08MB9674.eurprd08.prod.outlook.com>

Hi

> -----Original Message-----
> From: Suzuki K Poulose <suzuki.poulose at arm.com>
> Sent: Wednesday, December 18, 2024 9:38 AM
> To: Mao Jinlong <quic_jinlmao at quicinc.com>; Mike Leach
> <mike.leach at linaro.org>; James Clark <James.Clark at arm.com>; Rob Herring
> <robh at kernel.org>; Krzysztof Kozlowski <krzk+dt at kernel.org>; Conor Dooley
> <conor+dt at kernel.org>; Mathieu Poirier <mathieu.poirier at linaro.org>; Bjorn
> Andersson <andersson at kernel.org>; Konrad Dybcio
> <konradybcio at kernel.org>
> Cc: coresight at lists.linaro.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> msm at vger.kernel.org
> Subject: Re: [PATCH v6 2/2] coresight: Add label sysfs node support
> 
> On 17/12/2024 06:33, Mao Jinlong wrote:
> > For some coresight components like CTI and TPDM, there could be
> > numerous of them. From the node name, we can only get the type and
> > register address of the component. We can't identify the HW or the
> > system the component belongs to. Add label sysfs node support for
> > showing the intuitive name of the device.
> >
> > Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
> > ---
> >   .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
> >   .../sysfs-bus-coresight-devices-funnel        |  6 ++++
> >   .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
> >   drivers/hwtracing/coresight/coresight-sysfs.c | 32
> +++++++++++++++++++
> >   4 files changed, 50 insertions(+)
> 
> Do you think we need to name the devices using the label ? 
> 

No - absolutely not. If we use label to name devices then we have to validate that the string is a correctly formed device name and that it has not been previously used.

Using the canonical driver selected names works best as we are guaranteed a unique name and the information label can be used to provide flexible context information that best matches the users requirements.

Mike

> Or is this enough ?

> Suzuki
> 
> 
> >
> > diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> > b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> > index bf2869c413e7..909670e0451a 100644
> > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> > @@ -239,3 +239,9 @@ Date:		March 2020
> >   KernelVersion	5.7
> >   Contact:	Mike Leach or Mathieu Poirier
> >   Description:	(Write) Clear all channel / trigger programming.
> > +
> > +What:           /sys/bus/coresight/devices/<cti-name>/label
> > +Date:           Dec 2024
> > +KernelVersion   6.14
> > +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> > +Description:    (Read) Show hardware context information of device.
> > diff --git
> > a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> > b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> > index d75acda5e1b3..944aad879aeb 100644
> > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> > @@ -10,3 +10,9 @@ Date:		November 2014
> >   KernelVersion:	3.19
> >   Contact:	Mathieu Poirier <mathieu.poirier at linaro.org>
> >   Description:	(RW) Defines input port priority order.
> > +
> > +What:           /sys/bus/coresight/devices/<memory_map>.funnel/label
> > +Date:           Dec 2024
> > +KernelVersion   6.14
> > +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> > +Description:    (Read) Show hardware context information of device.
> > diff --git
> > a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> > b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> > index bf710ea6e0ef..309802246398 100644
> > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> > @@ -257,3 +257,9 @@ 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 CMB
> subunit
> >   		TPDM.
> > +
> > +What:           /sys/bus/coresight/devices/<tpdm-name>/label
> > +Date:           Dec 2024
> > +KernelVersion   6.14
> > +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> > +Description:    (Read) Show hardware context information of device.
> > diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c
> > b/drivers/hwtracing/coresight/coresight-sysfs.c
> > index a01c9e54e2ed..4af40cd7d75a 100644
> > --- a/drivers/hwtracing/coresight/coresight-sysfs.c
> > +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
> > @@ -7,6 +7,7 @@
> >   #include <linux/device.h>
> >   #include <linux/idr.h>
> >   #include <linux/kernel.h>
> > +#include <linux/property.h>
> >
> >   #include "coresight-priv.h"
> >   #include "coresight-trace-id.h"
> > @@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device
> *dev,
> >   }
> >   static DEVICE_ATTR_RW(enable_source);
> >
> > +static ssize_t label_show(struct device *dev,
> > +		struct device_attribute *attr, char *buf) {
> > +
> > +	const char *str;
> > +	int ret = 0;
> > +
> > +	ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
> > +	if (ret == 0)
> > +		return scnprintf(buf, PAGE_SIZE, "%s\n", str);
> > +	else
> > +		return ret;
> > +}
> > +static DEVICE_ATTR_RO(label);
> > +
> >   static struct attribute *coresight_sink_attrs[] = {
> >   	&dev_attr_enable_sink.attr,
> > +	&dev_attr_label.attr,
> >   	NULL,
> >   };
> >   ATTRIBUTE_GROUPS(coresight_sink);
> >
> >   static struct attribute *coresight_source_attrs[] = {
> >   	&dev_attr_enable_source.attr,
> > +	&dev_attr_label.attr,
> >   	NULL,
> >   };
> >   ATTRIBUTE_GROUPS(coresight_source);
> >
> > +static struct attribute *coresight_link_attrs[] = {
> > +	&dev_attr_label.attr,
> > +	NULL,
> > +};
> > +ATTRIBUTE_GROUPS(coresight_link);
> > +
> > +static struct attribute *coresight_helper_attrs[] = {
> > +	&dev_attr_label.attr,
> > +	NULL,
> > +};
> > +ATTRIBUTE_GROUPS(coresight_helper);
> > +
> >   const struct device_type coresight_dev_type[] = {
> >   	[CORESIGHT_DEV_TYPE_SINK] = {
> >   		.name = "sink",
> > @@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
> >   	},
> >   	[CORESIGHT_DEV_TYPE_LINK] = {
> >   		.name = "link",
> > +		.groups = coresight_link_groups,
> >   	},
> >   	[CORESIGHT_DEV_TYPE_LINKSINK] = {
> >   		.name = "linksink",
> > @@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
> >   	},
> >   	[CORESIGHT_DEV_TYPE_HELPER] = {
> >   		.name = "helper",
> > +		.groups = coresight_helper_groups,
> >   	}
> >   };
> >   /* Ensure the enum matches the names and groups */
> 
> _______________________________________________
> CoreSight mailing list -- coresight at lists.linaro.org To unsubscribe send an
> email to coresight-leave at lists.linaro.org


From quic_jinlmao at quicinc.com  Wed Dec 18 01:57:10 2024
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Wed, 18 Dec 2024 17:57:10 +0800
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-3-quic_jinlmao@quicinc.com>
 <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>
Message-ID: <f1c6da16-fbfd-40aa-a158-36ab713ce541@quicinc.com>



On 2024/12/18 17:38, Suzuki K Poulose wrote:
> On 17/12/2024 06:33, Mao Jinlong wrote:
>> For some coresight components like CTI and TPDM, there could be
>> numerous of them. From the node name, we can only get the type and
>> register address of the component. We can't identify the HW or the
>> system the component belongs to. Add label sysfs node support for
>> showing the intuitive name of the device.
>>
>> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
>> ---
>> ? .../testing/sysfs-bus-coresight-devices-cti?? |? 6 ++++
>> ? .../sysfs-bus-coresight-devices-funnel??????? |? 6 ++++
>> ? .../testing/sysfs-bus-coresight-devices-tpdm? |? 6 ++++
>> ? drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++++++++++++++++++
>> ? 4 files changed, 50 insertions(+)
> 
> Do you think we need to name the devices using the label ? Or is this 
> enough ?
> 
> Suzuki
Hi Suzuki,

In my opinion, we should use label as the device name.

It will be easier to identify the component with the folder name in 
/sys/bus/coresight/devices/


Thanks
Jinlong Mao

> 
> 
>>
>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti 
>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>> index bf2869c413e7..909670e0451a 100644
>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>> @@ -239,3 +239,9 @@ Date:??????? March 2020
>> ? KernelVersion??? 5.7
>> ? Contact:??? Mike Leach or Mathieu Poirier
>> ? Description:??? (Write) Clear all channel / trigger programming.
>> +
>> +What:?????????? /sys/bus/coresight/devices/<cti-name>/label
>> +Date:?????????? Dec 2024
>> +KernelVersion?? 6.14
>> +Contact:??????? Mao Jinlong <quic_jinlmao at quicinc.com>
>> +Description:??? (Read) Show hardware context information of device.
>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices- 
>> funnel b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>> index d75acda5e1b3..944aad879aeb 100644
>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>> @@ -10,3 +10,9 @@ Date:??????? November 2014
>> ? KernelVersion:??? 3.19
>> ? Contact:??? Mathieu Poirier <mathieu.poirier at linaro.org>
>> ? Description:??? (RW) Defines input port priority order.
>> +
>> +What:?????????? /sys/bus/coresight/devices/<memory_map>.funnel/label
>> +Date:?????????? Dec 2024
>> +KernelVersion?? 6.14
>> +Contact:??????? Mao Jinlong <quic_jinlmao at quicinc.com>
>> +Description:??? (Read) Show hardware context information of device.
>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices- 
>> tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> index bf710ea6e0ef..309802246398 100644
>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> @@ -257,3 +257,9 @@ 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 CMB subunit
>> ????????? TPDM.
>> +
>> +What:?????????? /sys/bus/coresight/devices/<tpdm-name>/label
>> +Date:?????????? Dec 2024
>> +KernelVersion?? 6.14
>> +Contact:??????? Mao Jinlong <quic_jinlmao at quicinc.com>
>> +Description:??? (Read) Show hardware context information of device.
>> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/ 
>> hwtracing/coresight/coresight-sysfs.c
>> index a01c9e54e2ed..4af40cd7d75a 100644
>> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
>> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
>> @@ -7,6 +7,7 @@
>> ? #include <linux/device.h>
>> ? #include <linux/idr.h>
>> ? #include <linux/kernel.h>
>> +#include <linux/property.h>
>> ? #include "coresight-priv.h"
>> ? #include "coresight-trace-id.h"
>> @@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device 
>> *dev,
>> ? }
>> ? static DEVICE_ATTR_RW(enable_source);
>> +static ssize_t label_show(struct device *dev,
>> +??????? struct device_attribute *attr, char *buf)
>> +{
>> +
>> +??? const char *str;
>> +??? int ret = 0;
>> +
>> +??? ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
>> +??? if (ret == 0)
>> +??????? return scnprintf(buf, PAGE_SIZE, "%s\n", str);
>> +??? else
>> +??????? return ret;
>> +}
>> +static DEVICE_ATTR_RO(label);
>> +
>> ? static struct attribute *coresight_sink_attrs[] = {
>> ????? &dev_attr_enable_sink.attr,
>> +??? &dev_attr_label.attr,
>> ????? NULL,
>> ? };
>> ? ATTRIBUTE_GROUPS(coresight_sink);
>> ? static struct attribute *coresight_source_attrs[] = {
>> ????? &dev_attr_enable_source.attr,
>> +??? &dev_attr_label.attr,
>> ????? NULL,
>> ? };
>> ? ATTRIBUTE_GROUPS(coresight_source);
>> +static struct attribute *coresight_link_attrs[] = {
>> +??? &dev_attr_label.attr,
>> +??? NULL,
>> +};
>> +ATTRIBUTE_GROUPS(coresight_link);
>> +
>> +static struct attribute *coresight_helper_attrs[] = {
>> +??? &dev_attr_label.attr,
>> +??? NULL,
>> +};
>> +ATTRIBUTE_GROUPS(coresight_helper);
>> +
>> ? const struct device_type coresight_dev_type[] = {
>> ????? [CORESIGHT_DEV_TYPE_SINK] = {
>> ????????? .name = "sink",
>> @@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
>> ????? },
>> ????? [CORESIGHT_DEV_TYPE_LINK] = {
>> ????????? .name = "link",
>> +??????? .groups = coresight_link_groups,
>> ????? },
>> ????? [CORESIGHT_DEV_TYPE_LINKSINK] = {
>> ????????? .name = "linksink",
>> @@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
>> ????? },
>> ????? [CORESIGHT_DEV_TYPE_HELPER] = {
>> ????????? .name = "helper",
>> +??????? .groups = coresight_helper_groups,
>> ????? }
>> ? };
>> ? /* Ensure the enum matches the names and groups */
> 



From lkp at intel.com  Wed Dec 18 01:59:35 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 18 Dec 2024 17:59:35 +0800
Subject: [arm-platforms:kvm-arm64/nv-next 14/20]
 arch/arm64/include/asm/kvm_nested.h:341:16: error: 'FIX_VNCR' undeclared
Message-ID: <202412181757.mImympcW-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/nv-next
head:   1e2a09d0a43f9c19dae9d321b4a5c840d45fc88b
commit: 0cb2c18e124cd31e01221ed6c60fddc478e3286b [14/20] KVM: arm64: nv: Handle mapping of VNCR_EL2 at EL2
config: arm64-randconfig-003-20241218 (https://download.01.org/0day-ci/archive/20241218/202412181757.mImympcW-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241218/202412181757.mImympcW-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/202412181757.mImympcW-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from arch/arm64/include/asm/kvm_emulate.h:21,
                    from arch/arm64/include/asm/kvm_mmu.h:99,
                    from arch/arm64/kernel/smp.c:46:
   arch/arm64/include/asm/kvm_nested.h: In function 'vncr_fixmap':
>> arch/arm64/include/asm/kvm_nested.h:341:16: error: 'FIX_VNCR' undeclared (first use in this function)
     341 |         return FIX_VNCR - cpu;
         |                ^~~~~~~~
   arch/arm64/include/asm/kvm_nested.h:341:16: note: each undeclared identifier is reported only once for each function it appears in


vim +/FIX_VNCR +341 arch/arm64/include/asm/kvm_nested.h

   337	
   338	static inline unsigned int vncr_fixmap(unsigned int cpu)
   339	{
   340		BUG_ON(cpu > NR_CPUS);
 > 341		return FIX_VNCR - cpu;
   342	}
   343	

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


From geert at linux-m68k.org  Wed Dec 18 02:01:20 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 18 Dec 2024 11:01:20 +0100
Subject: [PATCH] drm/mediatek: stop selecting foreign drivers
In-Reply-To: <20241218085837.2670434-1-arnd@kernel.org>
References: <20241218085837.2670434-1-arnd@kernel.org>
Message-ID: <CAMuHMdW-PEnkRugFVw2=0Xozw6TQaAJN_FzNucPMTZazZ3--hw@mail.gmail.com>

Hi Arnd,

On Wed, Dec 18, 2024 at 9:58?AM Arnd Bergmann <arnd at kernel.org> wrote:
> From: Arnd Bergmann <arnd at arndb.de>
>
> The PHY portion of the mediatek hdmi driver was originally part of
> the driver it self and later split out into drivers/phy, which a
> 'select' to keep the prior behavior.
>
> However, this leads to build failures when the PHY driver cannot
> be built:
>
> WARNING: unmet direct dependencies detected for PHY_MTK_HDMI
>   Depends on [n]: (ARCH_MEDIATEK || COMPILE_TEST [=y]) && COMMON_CLK [=y] && OF [=y] && REGULATOR [=n]
>   Selected by [m]:
>   - DRM_MEDIATEK_HDMI [=m] && HAS_IOMEM [=y] && DRM [=m] && DRM_MEDIATEK [=m]
> ERROR: modpost: "devm_regulator_register" [drivers/phy/mediatek/phy-mtk-hdmi-drv.ko] undefined!
> ERROR: modpost: "rdev_get_drvdata" [drivers/phy/mediatek/phy-mtk-hdmi-drv.ko] undefined!
>
> The best option here is to just not select the phy driver and leave that
> up to the defconfig. Do the same for the other PHY and memory drivers
> selected here as well for consistency.
>
> Fixes: a481bf2f0ca4 ("drm/mediatek: Separate mtk_hdmi_phy to an independent module")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Thanks for your patch!

> --- a/drivers/gpu/drm/mediatek/Kconfig
> +++ b/drivers/gpu/drm/mediatek/Kconfig
> @@ -15,9 +15,6 @@ config DRM_MEDIATEK
>         select DRM_BRIDGE_CONNECTOR
>         select DRM_MIPI_DSI
>         select DRM_PANEL
> -       select MEMORY
> -       select MTK_SMI
> -       select PHY_MTK_MIPI_DSI
>         select VIDEOMODE_HELPERS
>         help
>           Choose this option if you have a Mediatek SoCs.
> @@ -28,7 +25,6 @@ config DRM_MEDIATEK
>  config DRM_MEDIATEK_DP
>         tristate "DRM DPTX Support for MediaTek SoCs"
>         depends on DRM_MEDIATEK
> -       select PHY_MTK_DP
>         select DRM_DISPLAY_HELPER
>         select DRM_DISPLAY_DP_HELPER
>         select DRM_DISPLAY_DP_AUX_BUS
> @@ -39,6 +35,5 @@ config DRM_MEDIATEK_HDMI
>         tristate "DRM HDMI Support for Mediatek SoCs"
>         depends on DRM_MEDIATEK
>         select SND_SOC_HDMI_CODEC if SND_SOC
> -       select PHY_MTK_HDMI
>         help
>           DRM/KMS HDMI driver for Mediatek SoCs

What about replacing select by imply?

Alternatively, PHY_MTK_HDMI could default to DRM_MEDIATEK ||
DRM_MEDIATEK_DP || DRM_MEDIATEK_HDMI.

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 ukleinek at kernel.org  Wed Dec 18 02:05:03 2024
From: ukleinek at kernel.org (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Wed, 18 Dec 2024 11:05:03 +0100
Subject: [PATCH 5/9] pwm: stm32: add support for stm32mp25
In-Reply-To: <20241218090153.742869-6-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
 <20241218090153.742869-6-fabrice.gasnier@foss.st.com>
Message-ID: <lptm6gh2lzjqxm26lbmdw4yr2fowo6ytxwzqwl65khrx5xpcox@u25yzz6ssdy5>

On Wed, Dec 18, 2024 at 10:01:49AM +0100, Fabrice Gasnier wrote:
> diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
> index 17e591f61efb..99383e09920e 100644
> --- a/drivers/pwm/pwm-stm32.c
> +++ b/drivers/pwm/pwm-stm32.c
> @@ -19,6 +19,7 @@
>  #define CCMR_CHANNEL_SHIFT 8
>  #define CCMR_CHANNEL_MASK  0xFF
>  #define MAX_BREAKINPUT 2
> +#define MAX_PWM_OUTPUT 4

I would prefer a less generic name. Something like STM32_PWM_MAX_OUTPUT.
 
>  struct stm32_breakinput {
>  	u32 index;
> [...]
> @@ -790,11 +800,31 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
>  	priv->have_complementary_output = (ccer != 0);
>  }
>  
> -static unsigned int stm32_pwm_detect_channels(struct regmap *regmap,
> +static unsigned int stm32_pwm_detect_channels(struct stm32_timers *ddata,
>  					      unsigned int *num_enabled)
>  {
> +	struct regmap *regmap = ddata->regmap;
>  	u32 ccer, ccer_backup;
>  
> +	if (ddata->ipidr) {
> +		unsigned int npwm = 0;

No need to initialize npwm.

> +		u32 val;
> +
> +		/* Simply deduce from HWCFGR the number of outputs (MP25). */
> +		regmap_read(regmap, TIM_HWCFGR1, &val);
> +
> +		/*
> +		 * Timers may have more capture/compare channels than the
> +		 * actual number of PWM channel outputs (e.g. TIM_CH[1..4]).
> +		 */
> +		npwm = FIELD_GET(TIM_HWCFGR1_NB_OF_CC, val);
> +
> +		regmap_read(regmap, TIM_CCER, &ccer);
> +		*num_enabled = hweight32(ccer & TIM_CCER_CCXE);

So the part that determines *num_enabled is the same for both variants.
Maybe it's possible to share the code for that?

> +		return npwm < MAX_PWM_OUTPUT ? npwm : MAX_PWM_OUTPUT;
> +	}
> +
>  	/*
>  	 * If channels enable bits don't exist writing 1 will have no
>  	 * effect so we can detect and count them.

Best regards
Uwe
-------------- 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/20241218/7ccabae7/attachment.sig>

From james.clark at linaro.org  Wed Dec 18 02:07:45 2024
From: james.clark at linaro.org (James Clark)
Date: Wed, 18 Dec 2024 10:07:45 +0000
Subject: [PATCH 5/5] perf docs: arm_spe: Document new discard mode
In-Reply-To: <CAP-5=fU7RNzvzxBcAQy3RT9Ge3YtqPhDonupNWS7Wgb8HGQkGg@mail.gmail.com>
References: <20241217115610.371755-1-james.clark@linaro.org>
 <20241217115610.371755-6-james.clark@linaro.org>
 <CAP-5=fU7RNzvzxBcAQy3RT9Ge3YtqPhDonupNWS7Wgb8HGQkGg@mail.gmail.com>
Message-ID: <8c15786c-47b6-47ff-b1dc-ecbf32d582fb@linaro.org>



On 18/12/2024 12:54 am, Ian Rogers wrote:
> On Tue, Dec 17, 2024 at 3:56?AM James Clark <james.clark at linaro.org> wrote:
>>
>> Document the flag, hint what it's used for and give an example with
>> other useful options to get minimal output.
>>
>> Signed-off-by: James Clark <james.clark at linaro.org>
>> ---
>>   tools/perf/Documentation/perf-arm-spe.txt | 11 +++++++++++
>>   1 file changed, 11 insertions(+)
>>
>> diff --git a/tools/perf/Documentation/perf-arm-spe.txt b/tools/perf/Documentation/perf-arm-spe.txt
>> index de2b0b479249..588eead438bc 100644
>> --- a/tools/perf/Documentation/perf-arm-spe.txt
>> +++ b/tools/perf/Documentation/perf-arm-spe.txt
>> @@ -150,6 +150,7 @@ arm_spe/load_filter=1,min_latency=10/'
>>     pct_enable=1        - collect physical timestamp instead of virtual timestamp (PMSCR.PCT) - requires privilege
>>     store_filter=1      - collect stores only (PMSFCR.ST)
>>     ts_enable=1         - enable timestamping with value of generic timer (PMSCR.TS)
>> +  discard=1           - enable SPE PMU events but don't collect sample data - see 'Discard mode' (PMBLIMITR.FM = DISCARD)
>>
>>   +++*+++ Latency is the total latency from the point at which sampling started on that instruction, rather
>>   than only the execution latency.
>> @@ -220,6 +221,16 @@ Common errors
>>
>>      Increase sampling interval (see above)
>>
>> +Discard mode
>> +~~~~~~~~~~~~
>> +
>> +SPE PMU events can be used without the overhead of collecting sample data if
>> +discard mode is supported (optional from Armv8.6). First run a system wide SPE
>> +session (or on the core of interest) using options to minimize output. Then run
>> +perf stat:
>> +
>> +  perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
>> +  perf stat -e SAMPLE_FEED_LD
> 
> Perhaps clarify this should be an ARM SPE event? It seems strange to
> have one perf command affect a later one, the purpose of things like
> event multiplexing is to hide the hardware limits. I'd prefer if the
> last bit was like:
> ```
> Then run perf stat with an SPE event on the same PMU:
> 
> perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
> perf stat -e arm_spe/SAMPLE_FEED_LD/
> ``
> 
> Thanks,
> Ian

Hi Ian,

Confusingly this isn't an SPE event, it is a normal PMU event. The fact 
that one Perf command affects the other is because these events only 
count when SPE is enabled. When it's enabled it has an effect on a 
per-core level which is why in the example I made it simpler by enabling 
SPE system wide.

SPE is an exclusive PMU like Coresight and some others so it can't be 
affected by multiplexing or anything like that. The SAMPLE_FEED_LD PMU 
would be, but as long as SPE stays enabled it will count the right thing 
regardless of multiplexing.

THanks
James





From lkp at intel.com  Wed Dec 18 02:10:33 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 18 Dec 2024 18:10:33 +0800
Subject: [arm-platforms:kvm-arm64/nv-next 14/20]
 arch/arm64/include/asm/kvm_nested.h:341:9: error: use of undeclared
 identifier 'FIX_VNCR'
Message-ID: <202412181841.zAqOqCRd-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/nv-next
head:   1e2a09d0a43f9c19dae9d321b4a5c840d45fc88b
commit: 0cb2c18e124cd31e01221ed6c60fddc478e3286b [14/20] KVM: arm64: nv: Handle mapping of VNCR_EL2 at EL2
config: arm64-randconfig-001-20241218 (https://download.01.org/0day-ci/archive/20241218/202412181841.zAqOqCRd-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 2dc22615fd46ab2566d0f26d5ba234ab12dc4bf8)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241218/202412181841.zAqOqCRd-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/202412181841.zAqOqCRd-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from arch/arm64/kernel/smp.c:21:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   In file included from arch/arm64/kernel/smp.c:46:
   In file included from arch/arm64/include/asm/kvm_mmu.h:99:
   In file included from arch/arm64/include/asm/kvm_emulate.h:21:
>> arch/arm64/include/asm/kvm_nested.h:341:9: error: use of undeclared identifier 'FIX_VNCR'
     341 |         return FIX_VNCR - cpu;
         |                ^
   4 warnings and 1 error generated.


vim +/FIX_VNCR +341 arch/arm64/include/asm/kvm_nested.h

   337	
   338	static inline unsigned int vncr_fixmap(unsigned int cpu)
   339	{
   340		BUG_ON(cpu > NR_CPUS);
 > 341		return FIX_VNCR - cpu;
   342	}
   343	

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


From liviu.dudau at arm.com  Wed Dec 18 02:10:48 2024
From: liviu.dudau at arm.com (Liviu Dudau)
Date: Wed, 18 Dec 2024 10:10:48 +0000
Subject: [PATCH v2 2/3] mfd: syscon: Remove the platform driver support
In-Reply-To: <20241217-syscon-fixes-v2-2-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
 <20241217-syscon-fixes-v2-2-4f56d750541d@kernel.org>
Message-ID: <Z2KfqFVz272M_iiP@e110455-lin.cambridge.arm.com>

On Tue, Dec 17, 2024 at 12:11:41PM -0600, Rob Herring (Arm) wrote:
> The platform driver is dead code. It is not used by DT platforms since
> commit bdb0066df96e ("mfd: syscon: Decouple syscon interface from
> platform devices") which said:
> 
>     For non-DT based platforms, this patch keeps syscon platform driver
>     structure so that syscon can be probed and such non-DT based drivers
>     can use syscon_regmap_lookup_by_pdev API and access regmap handles.
>     Once all users of "syscon_regmap_lookup_by_pdev" migrated to DT based,
>     we can completely remove platform driver of syscon, and keep only helper
>     functions to get regmap handles.
> 
> The last user of syscon_regmap_lookup_by_pdevname() was removed in 2018.
> syscon_regmap_lookup_by_pdevname() was then removed in 2019, but that
> commit failed to remove the rest of the platform driver.
> 
> Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>

(Mostly for the vexpress-sysreg.c part, but hey, it's all code being removed):

Acked-by: Liviu Dudau <liviu.dudau at arm.com>

Best regards,
Liviu

> ---
>  drivers/mfd/syscon.c                 | 66 ------------------------------------
>  drivers/mfd/vexpress-sysreg.c        |  1 -
>  include/linux/platform_data/syscon.h |  9 -----
>  3 files changed, 76 deletions(-)
> 
> diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> index 72f20de9652da2d7bad12e4bc2c43ac0c9a97f76..bfb1f69fcff1d3cd35cf04ccd4c449e7d0395c79 100644
> --- a/drivers/mfd/syscon.c
> +++ b/drivers/mfd/syscon.c
> @@ -12,22 +12,15 @@
>  #include <linux/clk.h>
>  #include <linux/err.h>
>  #include <linux/hwspinlock.h>
> -#include <linux/io.h>
> -#include <linux/init.h>
>  #include <linux/list.h>
>  #include <linux/mutex.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
> -#include <linux/of_platform.h>
> -#include <linux/platform_data/syscon.h>
> -#include <linux/platform_device.h>
>  #include <linux/regmap.h>
>  #include <linux/reset.h>
>  #include <linux/mfd/syscon.h>
>  #include <linux/slab.h>
>  
> -static struct platform_driver syscon_driver;
> -
>  static DEFINE_MUTEX(syscon_list_lock);
>  static LIST_HEAD(syscon_list);
>  
> @@ -337,62 +330,3 @@ struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np,
>  	return regmap;
>  }
>  EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle_optional);
> -
> -static int syscon_probe(struct platform_device *pdev)
> -{
> -	struct device *dev = &pdev->dev;
> -	struct syscon_platform_data *pdata = dev_get_platdata(dev);
> -	struct syscon *syscon;
> -	struct regmap_config syscon_config = syscon_regmap_config;
> -	struct resource *res;
> -	void __iomem *base;
> -
> -	syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL);
> -	if (!syscon)
> -		return -ENOMEM;
> -
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	if (!res)
> -		return -ENOENT;
> -
> -	base = devm_ioremap(dev, res->start, resource_size(res));
> -	if (!base)
> -		return -ENOMEM;
> -
> -	syscon_config.max_register = resource_size(res) - 4;
> -	if (!syscon_config.max_register)
> -		syscon_config.max_register_is_0 = true;
> -
> -	if (pdata)
> -		syscon_config.name = pdata->label;
> -	syscon->regmap = devm_regmap_init_mmio(dev, base, &syscon_config);
> -	if (IS_ERR(syscon->regmap)) {
> -		dev_err(dev, "regmap init failed\n");
> -		return PTR_ERR(syscon->regmap);
> -	}
> -
> -	platform_set_drvdata(pdev, syscon);
> -
> -	dev_dbg(dev, "regmap %pR registered\n", res);
> -
> -	return 0;
> -}
> -
> -static const struct platform_device_id syscon_ids[] = {
> -	{ "syscon", },
> -	{ }
> -};
> -
> -static struct platform_driver syscon_driver = {
> -	.driver = {
> -		.name = "syscon",
> -	},
> -	.probe		= syscon_probe,
> -	.id_table	= syscon_ids,
> -};
> -
> -static int __init syscon_init(void)
> -{
> -	return platform_driver_register(&syscon_driver);
> -}
> -postcore_initcall(syscon_init);
> diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
> index d34d58ce46db2ad0d53b3daeabc9d3763883b39a..ef03d6cec9ff6927668d051ca459eb1d8ff7269e 100644
> --- a/drivers/mfd/vexpress-sysreg.c
> +++ b/drivers/mfd/vexpress-sysreg.c
> @@ -10,7 +10,6 @@
>  #include <linux/mfd/core.h>
>  #include <linux/module.h>
>  #include <linux/of_platform.h>
> -#include <linux/platform_data/syscon.h>
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
>  #include <linux/stat.h>
> diff --git a/include/linux/platform_data/syscon.h b/include/linux/platform_data/syscon.h
> deleted file mode 100644
> index 2c089dd3e2bda3baf5cef201ef43bca709e12c0b..0000000000000000000000000000000000000000
> --- a/include/linux/platform_data/syscon.h
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef PLATFORM_DATA_SYSCON_H
> -#define PLATFORM_DATA_SYSCON_H
> -
> -struct syscon_platform_data {
> -	const char *label;
> -};
> -
> -#endif
> 
> -- 
> 2.45.2
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?


From mike.leach at linaro.org  Wed Dec 18 02:12:12 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Wed, 18 Dec 2024 10:12:12 +0000
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <f1c6da16-fbfd-40aa-a158-36ab713ce541@quicinc.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-3-quic_jinlmao@quicinc.com> <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>
 <f1c6da16-fbfd-40aa-a158-36ab713ce541@quicinc.com>
Message-ID: <CAJ9a7Vh6EZij9ZTMOj4601QbUZ3S6mqh7USod=uXMrJsXawkkQ@mail.gmail.com>

Hi

On Wed, 18 Dec 2024 at 09:57, Jinlong Mao <quic_jinlmao at quicinc.com> wrote:
>
>
>
> On 2024/12/18 17:38, Suzuki K Poulose wrote:
> > On 17/12/2024 06:33, Mao Jinlong wrote:
> >> For some coresight components like CTI and TPDM, there could be
> >> numerous of them. From the node name, we can only get the type and
> >> register address of the component. We can't identify the HW or the
> >> system the component belongs to. Add label sysfs node support for
> >> showing the intuitive name of the device.
> >>
> >> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
> >> ---
> >>   .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
> >>   .../sysfs-bus-coresight-devices-funnel        |  6 ++++
> >>   .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
> >>   drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++++++++++++++++++
> >>   4 files changed, 50 insertions(+)
> >
> > Do you think we need to name the devices using the label ? Or is this
> > enough ?
> >
> > Suzuki
> Hi Suzuki,
>
> In my opinion, we should use label as the device name.
>
> It will be easier to identify the component with the folder name in
> /sys/bus/coresight/devices/
>
>

Please see the my comments from v4 of this patchset that explains why
this should not be done- re uniqueness and allowing scripting to
work:-

https://lists.linaro.org/archives/list/coresight at lists.linaro.org/message/Y65RKVUJUQGNARMWCOLSD636K7LROLYA/

Mike


> Thanks
> Jinlong Mao
>
> >
> >
> >>
> >> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> >> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> >> index bf2869c413e7..909670e0451a 100644
> >> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> >> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> >> @@ -239,3 +239,9 @@ Date:        March 2020
> >>   KernelVersion    5.7
> >>   Contact:    Mike Leach or Mathieu Poirier
> >>   Description:    (Write) Clear all channel / trigger programming.
> >> +
> >> +What:           /sys/bus/coresight/devices/<cti-name>/label
> >> +Date:           Dec 2024
> >> +KernelVersion   6.14
> >> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> >> +Description:    (Read) Show hardware context information of device.
> >> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-
> >> funnel b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> >> index d75acda5e1b3..944aad879aeb 100644
> >> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> >> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> >> @@ -10,3 +10,9 @@ Date:        November 2014
> >>   KernelVersion:    3.19
> >>   Contact:    Mathieu Poirier <mathieu.poirier at linaro.org>
> >>   Description:    (RW) Defines input port priority order.
> >> +
> >> +What:           /sys/bus/coresight/devices/<memory_map>.funnel/label
> >> +Date:           Dec 2024
> >> +KernelVersion   6.14
> >> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> >> +Description:    (Read) Show hardware context information of device.
> >> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-
> >> tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> >> index bf710ea6e0ef..309802246398 100644
> >> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> >> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> >> @@ -257,3 +257,9 @@ 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 CMB subunit
> >>           TPDM.
> >> +
> >> +What:           /sys/bus/coresight/devices/<tpdm-name>/label
> >> +Date:           Dec 2024
> >> +KernelVersion   6.14
> >> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> >> +Description:    (Read) Show hardware context information of device.
> >> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/
> >> hwtracing/coresight/coresight-sysfs.c
> >> index a01c9e54e2ed..4af40cd7d75a 100644
> >> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
> >> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
> >> @@ -7,6 +7,7 @@
> >>   #include <linux/device.h>
> >>   #include <linux/idr.h>
> >>   #include <linux/kernel.h>
> >> +#include <linux/property.h>
> >>   #include "coresight-priv.h"
> >>   #include "coresight-trace-id.h"
> >> @@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device
> >> *dev,
> >>   }
> >>   static DEVICE_ATTR_RW(enable_source);
> >> +static ssize_t label_show(struct device *dev,
> >> +        struct device_attribute *attr, char *buf)
> >> +{
> >> +
> >> +    const char *str;
> >> +    int ret = 0;
> >> +
> >> +    ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
> >> +    if (ret == 0)
> >> +        return scnprintf(buf, PAGE_SIZE, "%s\n", str);
> >> +    else
> >> +        return ret;
> >> +}
> >> +static DEVICE_ATTR_RO(label);
> >> +
> >>   static struct attribute *coresight_sink_attrs[] = {
> >>       &dev_attr_enable_sink.attr,
> >> +    &dev_attr_label.attr,
> >>       NULL,
> >>   };
> >>   ATTRIBUTE_GROUPS(coresight_sink);
> >>   static struct attribute *coresight_source_attrs[] = {
> >>       &dev_attr_enable_source.attr,
> >> +    &dev_attr_label.attr,
> >>       NULL,
> >>   };
> >>   ATTRIBUTE_GROUPS(coresight_source);
> >> +static struct attribute *coresight_link_attrs[] = {
> >> +    &dev_attr_label.attr,
> >> +    NULL,
> >> +};
> >> +ATTRIBUTE_GROUPS(coresight_link);
> >> +
> >> +static struct attribute *coresight_helper_attrs[] = {
> >> +    &dev_attr_label.attr,
> >> +    NULL,
> >> +};
> >> +ATTRIBUTE_GROUPS(coresight_helper);
> >> +
> >>   const struct device_type coresight_dev_type[] = {
> >>       [CORESIGHT_DEV_TYPE_SINK] = {
> >>           .name = "sink",
> >> @@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
> >>       },
> >>       [CORESIGHT_DEV_TYPE_LINK] = {
> >>           .name = "link",
> >> +        .groups = coresight_link_groups,
> >>       },
> >>       [CORESIGHT_DEV_TYPE_LINKSINK] = {
> >>           .name = "linksink",
> >> @@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
> >>       },
> >>       [CORESIGHT_DEV_TYPE_HELPER] = {
> >>           .name = "helper",
> >> +        .groups = coresight_helper_groups,
> >>       }
> >>   };
> >>   /* Ensure the enum matches the names and groups */
> >
>


-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From thomas.weissschuh at linutronix.de  Wed Dec 18 02:16:53 2024
From: thomas.weissschuh at linutronix.de (Thomas =?utf-8?Q?Wei=C3=9Fschuh?=)
Date: Wed, 18 Dec 2024 11:16:53 +0100
Subject: [PATCH 12/17] powerpc/vdso: Switch to generic storage
 implementation
In-Reply-To: <12120bbe-1d79-425b-982d-46af1fa5d70d@csgroup.eu>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-12-f7aed1bdb3b2@linutronix.de>
 <12120bbe-1d79-425b-982d-46af1fa5d70d@csgroup.eu>
Message-ID: <20241218105556-6d6d0bcb-f2d7-418e-a4e6-1222c506d2cb@linutronix.de>

Hi Christophe,

On Wed, Dec 18, 2024 at 08:20:51AM +0100, Christophe Leroy wrote:
> Le 16/12/2024 ? 15:10, Thomas Wei?schuh a ?crit?:

[..]

> >   #ifdef CONFIG_TIME_NS
> > -static __always_inline
> > -const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
> > +static __always_inline const struct vdso_time_data *__ppc_get_vdso_u_timens_data(void)
> >   {
> > -	return (void *)vd + (1U << CONFIG_PAGE_SHIFT);
> > +	struct vdso_time_data *time_data;
> > +
> > +	asm(
> > +		"	bcl	20, 31, .+4\n"
> > +		"0:	mflr	%0\n"
> > +		"	addis	%0, %0, (vdso_u_timens_data - 0b)@ha\n"
> > +		"	addi	%0, %0, (vdso_u_timens_data - 0b)@l\n"
> > +	: "=r" (time_data) :: "lr");
> > +
> > +	return time_data;
> 
> Please don't do that, it kills optimisation efforts done when implementing
> VDSO time. Commit ce7d8056e38b ("powerpc/vdso: Prepare for switching VDSO to
> generic C implementation.") explains why.
> 
> For time data, the bcl/mflr dance is done by get_datapage macro called by
> cvdso_call macro in gettimeofday.S, and given to
> __cvdso_clock_gettime_data() by __c_kernel_clock_gettime() in
> vgettimeofday.c . Use that information and don't redo the bcl/mflr sequence.

So instead keeping the logic of this:

static __always_inline
const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
{
	return (void *)vd + (1U << CONFIG_PAGE_SHIFT);
}

Makes sense.

Adding a constant value should be cheaper or just as cheap as a
PC-relative addressing for all architectures, so it can go into the
generic code, too.

[..]

> >   }
> > +#define __arch_get_vdso_u_timens_data __ppc_get_vdso_u_timens_data
> 
> There is not #ifdef __arch_get_vdso_u_timens_data anywhere, this #define is
> not needed, the function should be called __arch_get_vdso_u_timens_data()
> directly as before, unnecessary indirections reduce readability.

I'll see how this works out with the include order and conflicts with
symbols in include/vdso/datapage.h.

> >   #endif
> > -static inline bool vdso_clocksource_ok(const struct vdso_data *vd)
> > +static inline bool vdso_clocksource_ok(const struct vdso_time_data *vd)
> >   {
> >   	return true;
> >   }


Thanks!
Thomas


From krzk at kernel.org  Wed Dec 18 02:20:32 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 11:20:32 +0100
Subject: [PATCH v5 2/3] mailbox: add Samsung Exynos driver
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-2-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
 <20241217-acpm-v4-upstream-mbox-v5-2-cd1d3951fe84@linaro.org>
Message-ID: <ld6s5c3b6vfvn7l3yjxst6cyrq5xb3r4fmkqcjxawopjzoijjp@gt2ld2bm5562>

On Tue, Dec 17, 2024 at 09:40:21AM +0000, Tudor Ambarus wrote:
> The Samsung Exynos mailbox controller has 16 flag bits for hardware
> interrupt generation and a shared register for passing mailbox messages.
> When the controller is used by the ACPM protocol the shared register is
> ignored and the mailbox controller acts as a doorbell. The controller
> just raises the interrupt to APM after the ACPM protocol has written
> the message to SRAM.
> 
> Add support for the Samsung Exynos mailbox controller.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  drivers/mailbox/Kconfig          |  11 +++
>  drivers/mailbox/Makefile         |   2 +
>  drivers/mailbox/exynos-mailbox.c | 184 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 197 insertions(+)

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

Best regards,
Krzysztof



From christophe.leroy at csgroup.eu  Wed Dec 18 02:20:10 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Wed, 18 Dec 2024 11:20:10 +0100
Subject: [PATCH 12/17] powerpc/vdso: Switch to generic storage
 implementation
In-Reply-To: <12120bbe-1d79-425b-982d-46af1fa5d70d@csgroup.eu>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-12-f7aed1bdb3b2@linutronix.de>
 <12120bbe-1d79-425b-982d-46af1fa5d70d@csgroup.eu>
Message-ID: <e69b2927-b415-4e16-a346-8d874c9a8b39@csgroup.eu>



>> ? #ifdef CONFIG_TIME_NS
>> -static __always_inline
>> -const struct vdso_data *__arch_get_timens_vdso_data(const struct 
>> vdso_data *vd)
>> +static __always_inline const struct vdso_time_data 
>> *__ppc_get_vdso_u_timens_data(void)
>> ? {
>> -??? return (void *)vd + (1U << CONFIG_PAGE_SHIFT);
>> +??? struct vdso_time_data *time_data;
>> +
>> +??? asm(
>> +??????? "??? bcl??? 20, 31, .+4\n"
>> +??????? "0:??? mflr??? %0\n"
>> +??????? "??? addis??? %0, %0, (vdso_u_timens_data - 0b)@ha\n"
>> +??????? "??? addi??? %0, %0, (vdso_u_timens_data - 0b)@l\n"
>> +??? : "=r" (time_data) :: "lr");
>> +
>> +??? return time_data;
> 
> Please don't do that, it kills optimisation efforts done when 
> implementing VDSO time. Commit ce7d8056e38b ("powerpc/vdso: Prepare for 
> switching VDSO to generic C implementation.") explains why.
> 
> For time data, the bcl/mflr dance is done by get_datapage macro called 
> by cvdso_call macro in gettimeofday.S, and given to 
> __cvdso_clock_gettime_data() by __c_kernel_clock_gettime() in 
> vgettimeofday.c . Use that information and don't redo the bcl/mflr 
> sequence.
> 
> See for instance function __c_kernel_clock_getres():
> 
> Before your series it is 30 instructions.
> After your series it is 59 instructions.
> 

It is even more obvious with __c_kernel_time()

Before your series it has 12 instructions,
After your series it has 26 instructions.

Before

00001408 <__c_kernel_time>:
     1408:	81 44 00 04 	lwz     r10,4(r4)
     140c:	6d 49 80 00 	xoris   r9,r10,32768
     1410:	2c 09 ff ff 	cmpwi   r9,-1
     1414:	40 82 00 08 	bne     141c <__c_kernel_time+0x14>
     1418:	38 84 40 00 	addi    r4,r4,16384
     141c:	2c 03 00 00 	cmpwi   r3,0
     1420:	81 44 00 20 	lwz     r10,32(r4)
     1424:	81 64 00 24 	lwz     r11,36(r4)
     1428:	41 82 00 08 	beq     1430 <__c_kernel_time+0x28>
     142c:	91 63 00 00 	stw     r11,0(r3)
     1430:	7d 63 5b 78 	mr      r3,r11
     1434:	4e 80 00 20 	blr

Versus after

00001534 <__c_kernel_time>:
     1534:	81 44 00 04 	lwz     r10,4(r4)
     1538:	6d 49 80 00 	xoris   r9,r10,32768
     153c:	2c 09 ff ff 	cmpwi   r9,-1
     1540:	41 82 00 20 	beq     1560 <__c_kernel_time+0x2c>
     1544:	2c 03 00 00 	cmpwi   r3,0
     1548:	81 44 00 20 	lwz     r10,32(r4)
     154c:	81 64 00 24 	lwz     r11,36(r4)
     1550:	41 82 00 08 	beq     1558 <__c_kernel_time+0x24>
     1554:	91 63 00 00 	stw     r11,0(r3)
     1558:	7d 63 5b 78 	mr      r3,r11
     155c:	4e 80 00 20 	blr
     1560:	7c 08 02 a6 	mflr    r0
     1564:	2c 03 00 00 	cmpwi   r3,0
     1568:	90 01 00 04 	stw     r0,4(r1)
     156c:	42 9f 00 05 	bcl     20,4*cr7+so,1570 <__c_kernel_time+0x3c>
     1570:	7c 88 02 a6 	mflr    r4
     1574:	3c 84 ff ff 	addis   r4,r4,-1
     1578:	38 84 2a 90 	addi    r4,r4,10896
     157c:	81 44 00 20 	lwz     r10,32(r4)
     1580:	81 64 00 24 	lwz     r11,36(r4)
     1584:	41 82 00 08 	beq     158c <__c_kernel_time+0x58>
     1588:	91 63 00 00 	stw     r11,0(r3)
     158c:	80 01 00 04 	lwz     r0,4(r1)
     1590:	7d 63 5b 78 	mr      r3,r11
     1594:	7c 08 03 a6 	mtlr    r0
     1598:	4e 80 00 20 	blr

Christophe


From krzk at kernel.org  Wed Dec 18 02:20:51 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 11:20:51 +0100
Subject: [PATCH v5 3/3] MAINTAINERS: add entry for Samsung Exynos mailbox
 driver
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-3-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
 <20241217-acpm-v4-upstream-mbox-v5-3-cd1d3951fe84@linaro.org>
Message-ID: <67thhhblxntdoej3gzxj6qqwaalloztazujfydv22dl34lemir@ixipa4h2fnwm>

On Tue, Dec 17, 2024 at 09:40:22AM +0000, Tudor Ambarus wrote:
> Add entry for the Samsung Exynos mailbox driver.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  MAINTAINERS | 10 ++++++++++
>  1 file changed, 10 insertions(+)

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

Best regards,
Krzysztof



From thomas.weissschuh at linutronix.de  Wed Dec 18 02:25:44 2024
From: thomas.weissschuh at linutronix.de (Thomas =?utf-8?Q?Wei=C3=9Fschuh?=)
Date: Wed, 18 Dec 2024 11:25:44 +0100
Subject: [PATCH 03/17] vdso: Add generic time data storage
In-Reply-To: <3b44defd-cd2a-4a3c-b72d-bcc0530336da@csgroup.eu>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-3-f7aed1bdb3b2@linutronix.de>
 <3b44defd-cd2a-4a3c-b72d-bcc0530336da@csgroup.eu>
Message-ID: <20241218111724-41f5e3c6-f41d-41ec-beed-bd05cca05016@linutronix.de>

Hi Christophe,

On Wed, Dec 18, 2024 at 08:32:14AM +0100, Christophe Leroy wrote:
> Le 16/12/2024 ? 15:09, Thomas Wei?schuh a ?crit?:
> > Historically each architecture defined their own way to store the vDSO
> > data page. Add a generic mechanism to provide storage for that page.
> > 
> > Furthermore this generic storage will be extended to also provide
> > uniform storage for *non*-time-related data, like the random state or
> > architecture-specific data. These will have their own pages and data
> > structures, so rename 'vdso_data' into 'vdso_time_data' to make that
> > split clear from the name.
> > 
> > Also introduce a new consistent naming scheme for the symbols related to
> > the vDSO, which makes it clear if the symbol is accessible from
> > userspace or kernel space and the type of data behind the symbol.
> > 
> > The generic fault handler contains an optimization to prefault the vvar
> > page when the timens page is accessed. This was lifted from s390 and x86.
> > 
> > Co-developed-by: Nam Cao <namcao at linutronix.de>
> > Signed-off-by: Nam Cao <namcao at linutronix.de>
> > Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
> > ---
> >   MAINTAINERS                    |  1 +
> >   include/linux/time_namespace.h |  1 +
> >   include/linux/vdso_datastore.h | 10 +++++
> >   include/vdso/datapage.h        | 69 +++++++++++++++++++++++++----
> >   lib/Kconfig                    |  1 +
> >   lib/Makefile                   |  2 +
> >   lib/vdso_kernel/Kconfig        |  7 +++
> >   lib/vdso_kernel/Makefile       |  3 ++
> >   lib/vdso_kernel/datastore.c    | 99 ++++++++++++++++++++++++++++++++++++++++++
> 
> There is only one single file, namely datastore.c. You don't need a new
> directory for that, I should go in lib/vdso/

lib/vdso/ currently only contains userspace code.
I don't have a strong opinion on that.
The lib/vdso_kernel location was suggested by tglx, maybe he has some
feedback. (Originally I put it into kernel/vdso_storage.c)

[..]

> > +enum vdso_pages {
> > +	VDSO_TIME_PAGE_OFFSET,
> > +	VDSO_TIMENS_PAGE_OFFSET,
> > +	VDSO_NR_PAGES
> > +};
> 
> Naming that VDSO_ is confusing. Most macros called VDSO_ are related to the
> VDSO Code. VDSO data related macros should be prefixed with VVAR_

Also a request from tglx.

[..]


Thanks!
Thomas


From anshuman.khandual at arm.com  Wed Dec 18 02:37:21 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 18 Dec 2024 16:07:21 +0530
Subject: [PATCH V2 46/46] KVM: arm64: nv: Add trap forwarding for
 FEAT_FGT2 described registers
In-Reply-To: <87frmvsya0.wl-maz@kernel.org>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-47-anshuman.khandual@arm.com>
 <87frmvsya0.wl-maz@kernel.org>
Message-ID: <ca5d8db3-b980-464f-8069-86bf769128e0@arm.com>

On 12/10/24 14:35, Marc Zyngier wrote:
> On Tue, 10 Dec 2024 05:53:11 +0000,
> Anshuman Khandual <anshuman.khandual at arm.com> wrote:
>>
>> Describe remaining MDCR_EL2 register, and associate that with all FEAT_FGT2
>> exposed system registers it allows to trap.
> 
> MDCR_EL2 register *bits*? How is that related to FGT2 at all?
> 
>>
>> 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: linux-arm-kernel at lists.infradead.org
>> Cc: kvmarm at lists.linux.dev
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> Changes in V2:
>>
>> - Dropped check_cntr_accessible_N and CGT_CNTR_ACCESSIBLE_N constructs
>> - SYS_PMEVCNTSVR_EL1(N) access traps have been forwarded to CGT_MDCR_HPMN
>> - Updated check_mdcr_hpmn() to handle SYS_PMEVCNTSVR_EL1(N) registers
>> - Changed behaviour as BEHAVE_FORWARD_RW for CGT_MDCR_EnSPM
>>
>>  arch/arm64/include/asm/kvm_host.h |   2 +
>>  arch/arm64/kvm/emulate-nested.c   | 158 ++++++++++++++++++++++++++++++
>>  2 files changed, 160 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index c80c07be3358..4cdce62642d1 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -441,6 +441,7 @@ enum vcpu_sysreg {
>>  	PMINTENSET_EL1,	/* Interrupt Enable Set Register */
>>  	PMOVSSET_EL0,	/* Overflow Flag Status Set Register */
>>  	PMUSERENR_EL0,	/* User Enable Register */
>> +	SPMSELR_EL0,	/* System PMU Select Register */
> 
> How could a system PMU be relevant to a VM?  What is the point of
> bloating the vcpu for something that we will hopefully *never* make
> visible to guests?
> 
>>  
>>  	/* Pointer Authentication Registers in a strict increasing order. */
>>  	APIAKEYLO_EL1,
>> @@ -501,6 +502,7 @@ enum vcpu_sysreg {
>>  	CNTHP_CVAL_EL2,
>>  	CNTHV_CTL_EL2,
>>  	CNTHV_CVAL_EL2,
>> +	SPMACCESSR_EL2, /* System PMU Access Register */
> 
> Same here. It is pretty striking that these registers are never
> saved/restored or handled as traps, which is a good indication that
> this is pretty pointless.
> 
>>  
>>  	/* Anything from this can be RES0/RES1 sanitised */
>>  	MARKER(__SANITISED_REG_START__),
>> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
>> index 6c63cbfc11ea..c7d6d2034f27 100644
>> --- a/arch/arm64/kvm/emulate-nested.c
>> +++ b/arch/arm64/kvm/emulate-nested.c
>> @@ -79,6 +79,7 @@ enum cgt_group_id {
>>  	CGT_MDCR_TDRA,
>>  	CGT_MDCR_E2PB,
>>  	CGT_MDCR_TPMS,
>> +	CGT_MDCR_EnSPM,
>>  	CGT_MDCR_TTRF,
>>  	CGT_MDCR_E2TB,
>>  	CGT_MDCR_TDCC,
>> @@ -125,6 +126,7 @@ enum cgt_group_id {
>>  	CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
>>  	CGT_CNTHCTL_EL1PTEN,
>>  
>> +	CGT_SPMSEL_SPMACCESS,
>>  	CGT_CPTR_TTA,
>>  	CGT_MDCR_HPMN,
>>  
>> @@ -351,6 +353,12 @@ static const struct trap_bits coarse_trap_bits[] = {
>>  		.mask		= MDCR_EL2_TPMS,
>>  		.behaviour	= BEHAVE_FORWARD_RW,
>>  	},
>> +	[CGT_MDCR_EnSPM] = {
>> +		.index		= MDCR_EL2,
>> +		.value		= MDCR_EL2_EnSPM,
>> +		.mask		= MDCR_EL2_EnSPM,
>> +		.behaviour	= BEHAVE_FORWARD_RW,
>> +	},
>>  	[CGT_MDCR_TTRF] = {
>>  		.index		= MDCR_EL2,
>>  		.value		= MDCR_EL2_TTRF,
>> @@ -509,6 +517,7 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
>>  	switch (sysreg) {
>>  	case SYS_PMEVTYPERn_EL0(0) ... SYS_PMEVTYPERn_EL0(30):
>>  	case SYS_PMEVCNTRn_EL0(0) ... SYS_PMEVCNTRn_EL0(30):
>> +	case SYS_PMEVCNTSVR_EL1(0) ... SYS_PMEVCNTSVR_EL1(30):
>>  		idx = (sys_reg_CRm(sysreg) & 0x3) << 3 | sys_reg_Op2(sysreg);
>>  		break;
>>  	case SYS_PMXEVTYPER_EL0:
>> @@ -528,6 +537,22 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
>>  	return BEHAVE_HANDLE_LOCALLY;
>>  }
>>  
>> +static enum trap_behaviour check_spmsel_spmaccess(struct kvm_vcpu *vcpu)
>> +{
>> +	u64 spmaccessr_el2, spmselr_el2;
>> +	int syspmusel;
>> +
>> +	if (__vcpu_sys_reg(vcpu, MDCR_EL2) & MDCR_EL2_EnSPM) {
> 
> I don't mind the test, but I don't see any sanitising of MDCR_EL2 to
> make EnSPM as RES0 when FEAT_SPMU is not implemented, which will be
> 100% of the cases.
> 
>> +		spmselr_el2 = __vcpu_sys_reg(vcpu, SPMSELR_EL0);
>> +		spmaccessr_el2 = __vcpu_sys_reg(vcpu, SPMACCESSR_EL2);
> 
> So these two values are *guaranteed* to be zero. At this stage, what
> is the point?
> 
>> +		syspmusel = FIELD_GET(SPMSELR_EL0_SYSPMUSEL_MASK, spmselr_el2);
>> +
>> +		if (((spmaccessr_el2 >> (syspmusel * 2)) & 0x3) == 0x0)
>> +			return BEHAVE_FORWARD_RW;
> 
> What about value 0b01, which causes *writes* to be trapped?
> 
>> +	}
>> +	return BEHAVE_HANDLE_LOCALLY;
> 
> And then what? How do we handle this locally?
> 
> Honestly, short of any additional handling, we would be better off
> just injecting an UNDEF back into the guest.
> 
> 	M.
> 

Hello Marc,

Thanks for your review and apologies for the delayed response. I am still
processing some of your review comments, and need some more time to fully
understand them in the given context. I will get back to you after doing
some more reading.

- Anshuman


From YeoReum.Yun at arm.com  Wed Dec 18 02:39:21 2024
From: YeoReum.Yun at arm.com (Yeo Reum Yun)
Date: Wed, 18 Dec 2024 10:39:21 +0000
Subject: [PATCH 0/5] perf: arm_spe: Add format option for discard mode
In-Reply-To: <20241217115610.371755-1-james.clark@linaro.org>
References: <20241217115610.371755-1-james.clark@linaro.org>
Message-ID: <GV1PR08MB105212F0EF7B3CE7FAD9CE36DFB052@GV1PR08MB10521.eurprd08.prod.outlook.com>

This patch series looks good to me.

Reviewed-by: Yeoreum Yun <yeoreum.yun at arm.com>

________________________________________
From: James Clark <james.clark at linaro.org>
Sent: 17 December 2024 11:56
To: linux-arm-kernel at lists.infradead.org; linux-perf-users at vger.kernel.org
Cc: James Clark; Will Deacon; Mark Rutland; Peter Zijlstra; Ingo Molnar; Arnaldo Carvalho de Melo; Namhyung Kim; Alexander Shishkin; Jiri Olsa; Ian Rogers; Adrian Hunter; Liang, Kan; John Garry; Mike Leach; Leo Yan; Graham Woodward; linux-kernel at vger.kernel.org; bpf at vger.kernel.org
Subject: [PATCH 0/5] perf: arm_spe: Add format option for discard mode

Discard mode is a way to enable SPE related PMU events without the
overhead of recording any data. Add a format option, tests and docs for
it.

In theory we could make the driver drop calls to allocate the aux buffer
when discard mode is enabled. This would give a small memory saving,
but I think there is potential to interfere with any tools that don't
expect this so I left the aux allocation untouched. Even old tools that
don't know about discard mode will be able to use it because we publish
the format option. Not allocating the aux buffer will have to be added
to tools which I've done in Perf.

Tested on the FVP with SAMPLE_FEED_OP (0x812D):

 $ perf stat -e armv8_pmuv3/event=0x812D/ -- true

 Performance counter stats for 'true':

                 0      armv8_pmuv3/event=0x812D/

 $ perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
 $ perf stat -e armv8_pmuv3/event=0x812D/ -- true

  Performance counter stats for 'true':

             17350      armv8_pmuv3/event=0x812D/

James Clark (5):
  perf: arm_spe: Add format option for discard mode
  perf tool: arm-spe: Pull out functions for aux buffer and tracking
    setup
  perf tool: arm-spe: Don't allocate buffer or tracking event in discard
    mode
  perf test: arm_spe: Add test for discard mode
  perf docs: arm_spe: Document new discard mode

 drivers/perf/arm_spe_pmu.c                | 23 ++++++
 tools/perf/Documentation/perf-arm-spe.txt | 11 +++
 tools/perf/arch/arm64/util/arm-spe.c      | 90 +++++++++++++++--------
 tools/perf/tests/shell/test_arm_spe.sh    | 30 ++++++++
 4 files changed, 122 insertions(+), 32 deletions(-)

--
2.34.1




From danishanwar at ti.com  Wed Dec 18 02:44:24 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Wed, 18 Dec 2024 16:14:24 +0530
Subject: [PATCH 2/2] MAINTAINERS: Add entry for linux/pruss_driver.h
In-Reply-To: <20241218104424.1257880-1-danishanwar@ti.com>
References: <20241218104424.1257880-1-danishanwar@ti.com>
Message-ID: <20241218104424.1257880-3-danishanwar@ti.com>

include/linux/pruss_driver.h is an orphan file. Add entry for this in
the MAINATAINERS file.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bc992f10a2f6..069817391e9f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23638,6 +23638,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
 F:	Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
 F:	drivers/pmdomain/ti/omap_prm.c
 F:	drivers/soc/ti/*
+F:	include/linux/pruss_driver.h
 
 TI LM49xxx FAMILY ASoC CODEC DRIVERS
 M:	M R Swami Reddy <mr.swami.reddy at ti.com>
-- 
2.34.1



From michael.riesch at wolfvision.net  Wed Dec 18 02:43:11 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed, 18 Dec 2024 11:43:11 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: fix num-channels property of
 wolfvision pf5 mic
In-Reply-To: <20241218-b4-wolfvision-pf5-update-v1-0-1d1959858708@wolfvision.net>
References: <20241218-b4-wolfvision-pf5-update-v1-0-1d1959858708@wolfvision.net>
Message-ID: <20241218-b4-wolfvision-pf5-update-v1-1-1d1959858708@wolfvision.net>

The Rockchip RK3568 PDM block always considers stereo inputs. Therefore,
the number of channels must be always an even number, even if a single
mono microphone is attached.

Fixes: 0be29f76633a ("arm64: dts: rockchip: add wolfvision pf5 mainboard")
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts
index e8243c908542..c6e413731241 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts
@@ -53,7 +53,7 @@ hdmi_tx_5v: regulator-hdmi-tx-5v {
 
 	pdm_codec: pdm-codec {
 		compatible = "dmic-codec";
-		num-channels = <1>;
+		num-channels = <2>;
 		#sound-dai-cells = <0>;
 	};
 

-- 
2.34.1



From michael.riesch at wolfvision.net  Wed Dec 18 02:43:12 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed, 18 Dec 2024 11:43:12 +0100
Subject: [PATCH 2/2] arm64: dts: rockchip: enable hdmi out audio on
 wolfvision pf5
In-Reply-To: <20241218-b4-wolfvision-pf5-update-v1-0-1d1959858708@wolfvision.net>
References: <20241218-b4-wolfvision-pf5-update-v1-0-1d1959858708@wolfvision.net>
Message-ID: <20241218-b4-wolfvision-pf5-update-v1-2-1d1959858708@wolfvision.net>

Enable HDMI out audio on the WolfVision PF5 mainboard.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts
index c6e413731241..bb33fabae16e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts
@@ -167,6 +167,10 @@ hdmi_tx_out: endpoint {
 	};
 };
 
+&hdmi_sound {
+	status = "okay";
+};
+
 &i2c0 {
 	status = "okay";
 
@@ -414,6 +418,10 @@ &i2c4 {
 	pinctrl-0 = <&i2c4m1_xfer>;
 };
 
+&i2s0_8ch {
+	status = "okay";
+};
+
 &pdm {
 	pinctrl-0 = <&pdmm0_clk
 		     &pdmm0_sdi0>;

-- 
2.34.1



From michael.riesch at wolfvision.net  Wed Dec 18 02:43:10 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed, 18 Dec 2024 11:43:10 +0100
Subject: [PATCH 0/2] arm64: dts: rockchip: update wolfvision pf5 mainboard
Message-ID: <20241218-b4-wolfvision-pf5-update-v1-0-1d1959858708@wolfvision.net>

Habidere,
    
Two updates for the WolfVision PF5 mainboard:
 - The onboard microphone is mono, but needs to be treated as stereo
   microphone due to restrictions of the RK3568 PDM block. Fix this.
 - Enable the HDMI TX audio.
    
Regards,
Michael

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
Michael Riesch (2):
      arm64: dts: rockchip: fix num-channels property of wolfvision pf5 mic
      arm64: dts: rockchip: enable hdmi out audio on wolfvision pf5

 arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241218-b4-wolfvision-pf5-update-1c381d1d3471

Best regards,
-- 
Michael Riesch <michael.riesch at wolfvision.net>



From danishanwar at ti.com  Wed Dec 18 02:44:22 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Wed, 18 Dec 2024 16:14:22 +0530
Subject: [PATCH 0/2] Fix compilation errors with pruss APIs
Message-ID: <20241218104424.1257880-1-danishanwar@ti.com>

The APIs in 'include/linux/pruss_driver.h' produce compilation errors and
warnings when config symbol CONFIG_TI_PRUSS is not enabled.

This series fixes those errors / warnings.

Also the header file 'include/linux/pruss_driver.h' is orphan and has no
entry in MAINTAINERS file. Patch 2/2 of the series adds the entry for this
file in MAINTAINERS file

MD Danish Anwar (2):
  soc: ti: pruss: Fix pruss APIs
  MAINTAINERS: Add entry for linux/pruss_driver.h

 MAINTAINERS                  |  1 +
 include/linux/pruss_driver.h | 12 ++++++------
 2 files changed, 7 insertions(+), 6 deletions(-)


base-commit: 7fa366f1b6e376c38966faa42da7f0f2e013fdab
-- 
2.34.1



From danishanwar at ti.com  Wed Dec 18 02:44:23 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Wed, 18 Dec 2024 16:14:23 +0530
Subject: [PATCH 1/2] soc: ti: pruss: Fix pruss APIs
In-Reply-To: <20241218104424.1257880-1-danishanwar@ti.com>
References: <20241218104424.1257880-1-danishanwar@ti.com>
Message-ID: <20241218104424.1257880-2-danishanwar@ti.com>

PRUSS APIs in pruss_driver.h produce lots of compilation errors when
CONFIG_TI_PRUSS is not set.

The errors and warnings,
warning: returning 'void *' from a function with return type 'int' makes
	integer from pointer without a cast [-Wint-conversion]
error: expected identifier or '(' before '{' token

Fix these warnings and errors by fixing the return type of pruss APIs as
well as removing the misplaced semicolon from pruss_cfg_xfr_enable()

Fixes: 0211cc1e4fbb ("soc: ti: pruss: Add helper functions to set GPI mode, MII_RT_event and XFR")
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 include/linux/pruss_driver.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h
index c9a31c567e85..2e18fef1a2e1 100644
--- a/include/linux/pruss_driver.h
+++ b/include/linux/pruss_driver.h
@@ -144,32 +144,32 @@ static inline int pruss_release_mem_region(struct pruss *pruss,
 static inline int pruss_cfg_get_gpmux(struct pruss *pruss,
 				      enum pruss_pru_id pru_id, u8 *mux)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 static inline int pruss_cfg_set_gpmux(struct pruss *pruss,
 				      enum pruss_pru_id pru_id, u8 mux)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 static inline int pruss_cfg_gpimode(struct pruss *pruss,
 				    enum pruss_pru_id pru_id,
 				    enum pruss_gpi_mode mode)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 static inline int pruss_cfg_xfr_enable(struct pruss *pruss,
 				       enum pru_type pru_type,
-				       bool enable);
+				       bool enable)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 #endif /* CONFIG_TI_PRUSS */
-- 
2.34.1



From angelogioacchino.delregno at collabora.com  Wed Dec 18 02:50:17 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:50:17 +0100
Subject: [PATCH] drm/mediatek: stop selecting foreign drivers
In-Reply-To: <20241218085837.2670434-1-arnd@kernel.org>
References: <20241218085837.2670434-1-arnd@kernel.org>
Message-ID: <46f871e3-bb1e-4bee-95f3-2121c6a6eef7@collabora.com>

Il 18/12/24 09:58, Arnd Bergmann ha scritto:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> The PHY portion of the mediatek hdmi driver was originally part of
> the driver it self and later split out into drivers/phy, which a
> 'select' to keep the prior behavior.
> 
> However, this leads to build failures when the PHY driver cannot
> be built:
> 
> WARNING: unmet direct dependencies detected for PHY_MTK_HDMI
>    Depends on [n]: (ARCH_MEDIATEK || COMPILE_TEST [=y]) && COMMON_CLK [=y] && OF [=y] && REGULATOR [=n]
>    Selected by [m]:
>    - DRM_MEDIATEK_HDMI [=m] && HAS_IOMEM [=y] && DRM [=m] && DRM_MEDIATEK [=m]
> ERROR: modpost: "devm_regulator_register" [drivers/phy/mediatek/phy-mtk-hdmi-drv.ko] undefined!
> ERROR: modpost: "rdev_get_drvdata" [drivers/phy/mediatek/phy-mtk-hdmi-drv.ko] undefined!
> 
> The best option here is to just not select the phy driver and leave that
> up to the defconfig. Do the same for the other PHY and memory drivers
> selected here as well for consistency.
> 
> Fixes: a481bf2f0ca4 ("drm/mediatek: Separate mtk_hdmi_phy to an independent module")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

The problem is - no PHY no party, it's not going to work without... but I get the
reasons behind this change.

Are we sure that we can't just add a `depends on PHY_MTK_xxxx` (or extend
depends on DRM_MEDIATEK && PHY_MTK_xxx)?

Cheers,
Angelo

> ---
>   drivers/gpu/drm/mediatek/Kconfig | 5 -----
>   1 file changed, 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
> index 1c2f56b75716..1d4f20a4f265 100644
> --- a/drivers/gpu/drm/mediatek/Kconfig
> +++ b/drivers/gpu/drm/mediatek/Kconfig
> @@ -15,9 +15,6 @@ config DRM_MEDIATEK
>   	select DRM_BRIDGE_CONNECTOR
>   	select DRM_MIPI_DSI
>   	select DRM_PANEL
> -	select MEMORY
> -	select MTK_SMI
> -	select PHY_MTK_MIPI_DSI
>   	select VIDEOMODE_HELPERS
>   	help
>   	  Choose this option if you have a Mediatek SoCs.
> @@ -28,7 +25,6 @@ config DRM_MEDIATEK
>   config DRM_MEDIATEK_DP
>   	tristate "DRM DPTX Support for MediaTek SoCs"
>   	depends on DRM_MEDIATEK
> -	select PHY_MTK_DP
>   	select DRM_DISPLAY_HELPER
>   	select DRM_DISPLAY_DP_HELPER
>   	select DRM_DISPLAY_DP_AUX_BUS
> @@ -39,6 +35,5 @@ config DRM_MEDIATEK_HDMI
>   	tristate "DRM HDMI Support for Mediatek SoCs"
>   	depends on DRM_MEDIATEK
>   	select SND_SOC_HDMI_CODEC if SND_SOC
> -	select PHY_MTK_HDMI
>   	help
>   	  DRM/KMS HDMI driver for Mediatek SoCs



From john.madieu.xa at bp.renesas.com  Wed Dec 18 02:50:14 2024
From: john.madieu.xa at bp.renesas.com (John Madieu)
Date: Wed, 18 Dec 2024 10:50:14 +0000
Subject: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a "syscon"
 compatible
In-Reply-To: <CAL_Jsq+DEWibue5DVB=gSNB7cvaE85rV5XPf8HPqQDz0DgjCXw@mail.gmail.com>
References: <20241211-syscon-fixes-v1-3-b5ac8c219e96@kernel.org>
 <20241215203344.46158-1-john.madieu.xa@bp.renesas.com>
 <CAL_Jsq+DEWibue5DVB=gSNB7cvaE85rV5XPf8HPqQDz0DgjCXw@mail.gmail.com>
Message-ID: <OSBPR01MB27755C4089DF9546954E2422FF052@OSBPR01MB2775.jpnprd01.prod.outlook.com>

Hi Rob,

> -----Original Message-----
> From: Rob Herring <robh at kernel.org>
> Sent: Monday, December 16, 2024 6:40 PM
> To: John Madieu <john.madieu.xa at bp.renesas.com>
> Cc: arnd at arndb.de; heiko at sntech.de; krzysztof.kozlowski at linaro.org;
> lee at kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; liviu.dudau at arm.com; lpieralisi at kernel.org;
> pankaj.dubey at samsung.com; peter.griffin at linaro.org; sudeep.holla at arm.com;
> willmcvicker at google.com; Biju Das <biju.das.jz at bp.renesas.com>
> Subject: Re: [PATCH 3/3] mfd: syscon: Allow syscon nodes without a
> "syscon" compatible
> 
> On Sun, Dec 15, 2024 at 2:34?PM John Madieu
> <john.madieu.xa at bp.renesas.com> wrote:
> >
> > Hi Rob,
> >
> > On Wed, 11 Dec 2024 14:57:14 -0600 Rob Herring wrote:
> > > diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index
> > > bfb1f69fcff1..e6df2825c14d 100644
> > > --- a/drivers/mfd/syscon.c
> > > +++ b/drivers/mfd/syscon.c
> > > @@ -171,8 +171,10 @@ static struct regmap
> *device_node_get_regmap(struct device_node *np,
> > >                       break;
> > >               }
> > >
> > > -     if (!syscon)
> > > +     if (!syscon && of_device_is_compatible(np, "syscon"))
> > >               syscon = of_syscon_register(np, check_res);
> > > +     else
> > > +             syscon = ERR_PTR(-EINVAL);
> >
> > The current modification will make device_node_get_regmap() return
> > -EINVAL even for syscons that were already found in the syscon_list,
> > which I believe is not the intended behavior.
> 
> Yes, it is. Doesn't Will's fix work for you?

Did not see Will's answer while doing my tests. I however tested it and it
works. I did also test your v2 series, which worked with me as well.

I'll then drop syscon compatible string in my series and send the v2.

Thanks,
John

> 
> >
> > I suggest modifying it this way to maintain lookup functionality for
> > registered syscons while implementing your intended changes:
> >
> > static struct regmap *device_node_get_regmap(struct device_node *np,
> >                                              bool check_res) {
> >         struct syscon *entry, *syscon = NULL;
> >         struct regmap *regmap;
> >
> >         mutex_lock(&syscon_list_lock);
> >
> >         list_for_each_entry(entry, &syscon_list, list)
> >                 if (entry->np == np) {
> >                         syscon = entry;
> >                         break;
> >                 }
> >
> >         if (syscon) {
> >                 regmap = syscon->regmap;
> >                 mut ix_unlock(&syscon_list_lock);
> >                 return regmap;
> >         }
> >
> >         if (of_device_is_compatible(np, "syscon")) {
> >                 syscon = of_syscon_register(np, check_res);
> >                 mutex_unlock(&syscon_list_lock);
> >                 if (IS_ERR(syscon))
> >                         return ERR_CAST(syscon);
> >                 return syscon->regmap;
> >         }
> >
> >         mutex_unlock(&syscon_list_lock);
> 
> 3 unlock calls is a sign the code structure could be improved. A goto or a
> guard() for example. However, I think this is the same logic as what Will
> suggested.
> 
> Rob

From shameerali.kolothum.thodi at huawei.com  Wed Dec 18 02:53:42 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Wed, 18 Dec 2024 10:53:42 +0000
Subject: [PATCH v4 0/3] KVM: arm64: Errata management for VM Live migration
Message-ID: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>

Hi,

v3 --> v4(Minor updates)
https://lore.kernel.org/kvmarm/20241209115311.40496-1-shameerali.kolothum.thodi at huawei.com/

 -Changed MIDR/REVIDR to 64 bits based on feedback from Connie
  and Marc(Patch #3).
 -Added R-by tags from Sebastian (Thanks!).

Thanks,
Shameer

RFC v2 --> v3
https://lore.kernel.org/kvmarm/20241024094012.29452-1-shameerali.kolothum.thodi at huawei.com/

 -Addressed comments from Oliver(Thanks!).
 -Using implementation CPUs MIDR/REVIDR when it is set for
  _midr_range() functions(Patch 1 & 3)
 -New hypercall for retrieving implementation CPUs(Patch #2).
 -Dropped RFC.

RFC v1 --> RFCv2:
https://lore.kernel.org/kvmarm/20241011075053.80540-1-shameerali.kolothum.thodi at huawei.com/
 -Introduced hypercalls to retrieve target CPUs info from user space VMM.
  see patch #1 for details.
 -Patch #2 uses the hypercall to retrieve the target CPU info if any.
 -Use the target CPUs MIDR/REVIDR in errata enablement. See patch #3.

Background from v1:

On ARM64 platforms most of the errata workarounds are based on CPU
MIDR/REVIDR values and a number of these workarounds need to be
implemented by the Guest kernel as well. This creates a problem when
Guest needs to be migrated to a platform that differs in these
MIDR/REVIDR values even if the VMM can come up with a common minimum
feature list for the Guest using the recently introduced "Writable
ID registers" support.

(This is roughly based on a discussion I had with Marc and Oliver
at KVM forum. Marc outlined his idea for a solution and this is an
attempt to implement it. Thanks to both and I take all the blame
if this is nowhere near what is intended/required)

Shameer Kolothum (3):
  arm64: Modify _midr_range() functions to read MIDR/REVIDR internally
  KVM: arm64: Introduce hypercall support for retrieving target
    implementations
  arm64: paravirt: Enable errata based on implementation CPUs

 Documentation/virt/kvm/arm/hypercalls.rst | 30 +++++++++++++
 arch/arm64/include/asm/cputype.h          | 51 ++++++++++++++++-------
 arch/arm64/include/asm/mmu.h              |  3 +-
 arch/arm64/include/asm/paravirt.h         |  3 ++
 arch/arm64/kernel/cpu_errata.c            | 37 +++++++++++-----
 arch/arm64/kernel/cpufeature.c            |  8 ++--
 arch/arm64/kernel/image-vars.h            |  2 +
 arch/arm64/kernel/paravirt.c              | 31 ++++++++++++++
 arch/arm64/kernel/proton-pack.c           | 17 ++++----
 arch/arm64/kvm/vgic/vgic-v3.c             |  2 +-
 drivers/clocksource/arm_arch_timer.c      |  2 +-
 include/linux/arm-smccc.h                 |  7 ++++
 12 files changed, 152 insertions(+), 41 deletions(-)

-- 
2.47.0



From angelogioacchino.delregno at collabora.com  Wed Dec 18 02:54:13 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:54:13 +0100
Subject: [PATCH v1 0/2] clk: mediatek: Add missing clock for MT8188 HDMITX
Message-ID: <20241218105415.39206-1-angelogioacchino.delregno@collabora.com>

This adds a missing clock for MT8188's HDMI TX block.

AngeloGioacchino Del Regno (2):
  dt-bindings: clock: mediatek,mt8188: Add VDO1_DPI1_HDMI clock
  clk: mediatek: mt8188-vdo1: Add VDO1_DPI1_HDMI clock for hdmitx

 drivers/clk/mediatek/clk-mt8188-vdo1.c          | 11 +++++++++++
 include/dt-bindings/clock/mediatek,mt8188-clk.h |  3 ++-
 2 files changed, 13 insertions(+), 1 deletion(-)

-- 
2.46.1



From angelogioacchino.delregno at collabora.com  Wed Dec 18 02:54:14 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:54:14 +0100
Subject: [PATCH v1 1/2] dt-bindings: clock: mediatek,mt8188: Add VDO1_DPI1_HDMI clock
In-Reply-To: <20241218105415.39206-1-angelogioacchino.delregno@collabora.com>
References: <20241218105415.39206-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241218105415.39206-2-angelogioacchino.delregno@collabora.com>

Add binding for the HDMI TX clock found in the VDO1 controller

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 include/dt-bindings/clock/mediatek,mt8188-clk.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/dt-bindings/clock/mediatek,mt8188-clk.h b/include/dt-bindings/clock/mediatek,mt8188-clk.h
index bd5cd100b796..8af44560a74c 100644
--- a/include/dt-bindings/clock/mediatek,mt8188-clk.h
+++ b/include/dt-bindings/clock/mediatek,mt8188-clk.h
@@ -721,6 +721,7 @@
 #define CLK_VDO1_DPINTF				58
 #define CLK_VDO1_DISP_MONITOR_DPINTF		59
 #define CLK_VDO1_26M_SLOW			60
-#define CLK_VDO1_NR_CLK				61
+#define CLK_VDO1_DPI1_HDMI			61
+#define CLK_VDO1_NR_CLK				62
 
 #endif /* _DT_BINDINGS_CLK_MT8188_H */
-- 
2.46.1



From angelogioacchino.delregno at collabora.com  Wed Dec 18 02:54:15 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:54:15 +0100
Subject: [PATCH v1 2/2] clk: mediatek: mt8188-vdo1: Add VDO1_DPI1_HDMI clock for hdmitx
In-Reply-To: <20241218105415.39206-1-angelogioacchino.delregno@collabora.com>
References: <20241218105415.39206-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241218105415.39206-3-angelogioacchino.delregno@collabora.com>

Add a missing clock found in the VDO1 controller for the HDMI TX
controller over DPI1.

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

diff --git a/drivers/clk/mediatek/clk-mt8188-vdo1.c b/drivers/clk/mediatek/clk-mt8188-vdo1.c
index 4fa355f8f0c2..f715d45e545e 100644
--- a/drivers/clk/mediatek/clk-mt8188-vdo1.c
+++ b/drivers/clk/mediatek/clk-mt8188-vdo1.c
@@ -43,6 +43,12 @@ static const struct mtk_gate_regs vdo1_4_cg_regs = {
 	.sta_ofs = 0x140,
 };
 
+static const struct mtk_gate_regs vdo1_5_cg_regs = {
+	.set_ofs = 0x400,
+	.clr_ofs = 0x400,
+	.sta_ofs = 0x400,
+};
+
 #define GATE_VDO1_0(_id, _name, _parent, _shift)			\
 	GATE_MTK(_id, _name, _parent, &vdo1_0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
@@ -62,6 +68,9 @@ static const struct mtk_gate_regs vdo1_4_cg_regs = {
 #define GATE_VDO1_4(_id, _name, _parent, _shift)			\
 	GATE_MTK(_id, _name, _parent, &vdo1_4_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
+#define GATE_VDO1_5(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdo1_5_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
 static const struct mtk_gate vdo1_clks[] = {
 	/* VDO1_0 */
 	GATE_VDO1_0(CLK_VDO1_SMI_LARB2, "vdo1_smi_larb2", "top_vpp", 0),
@@ -129,6 +138,8 @@ static const struct mtk_gate vdo1_clks[] = {
 	GATE_VDO1_3(CLK_VDO1_DISP_MONITOR_DPINTF, "vdo1_disp_monitor_dpintf_ck", "top_vpp", 17),
 	/* VDO1_4 */
 	GATE_VDO1_4(CLK_VDO1_26M_SLOW, "vdo1_26m_slow_ck", "clk26m", 8),
+	/* VDO1_5 */
+	GATE_VDO1_5(CLK_VDO1_DPI1_HDMI, "vdo1_dpi1_hdmi", "hdmi_txpll", 0),
 };
 
 static const struct mtk_clk_desc vdo1_desc = {
-- 
2.46.1



From shameerali.kolothum.thodi at huawei.com  Wed Dec 18 02:53:43 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Wed, 18 Dec 2024 10:53:43 +0000
Subject: [PATCH v4 1/3] arm64: Modify _midr_range() functions to read MIDR/REVIDR internally
In-Reply-To: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20241218105345.73472-2-shameerali.kolothum.thodi@huawei.com>

These changes lay the groundwork for adding support for guest kernels,
allowing them to leverage target CPU implementations provided by the
VMM.

No functional changes intended.

Suggested-by: Oliver Upton <oliver.upton at linux.dev>
Reviewed-by: Sebastian Ott <sebott at redhat.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 arch/arm64/include/asm/cputype.h     | 28 ++++++++++++++--------------
 arch/arm64/include/asm/mmu.h         |  3 +--
 arch/arm64/kernel/cpu_errata.c       | 23 +++++++++++++----------
 arch/arm64/kernel/cpufeature.c       |  6 +++---
 arch/arm64/kernel/proton-pack.c      | 17 ++++++++---------
 arch/arm64/kvm/vgic/vgic-v3.c        |  2 +-
 drivers/clocksource/arm_arch_timer.c |  2 +-
 7 files changed, 41 insertions(+), 40 deletions(-)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 488f8e751349..dcf0e1ce892d 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -229,6 +229,16 @@
 
 #define read_cpuid(reg)			read_sysreg_s(SYS_ ## reg)
 
+/*
+ * The CPU ID never changes at run time, so we might as well tell the
+ * compiler that it's constant.  Use this function to read the CPU ID
+ * rather than directly reading processor_id or read_cpuid() directly.
+ */
+static inline u32 __attribute_const__ read_cpuid_id(void)
+{
+	return read_cpuid(MIDR_EL1);
+}
+
 /*
  * Represent a range of MIDR values for a given CPU model and a
  * range of variant/revision values.
@@ -264,31 +274,21 @@ static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
 	return _model == model && rv >= rv_min && rv <= rv_max;
 }
 
-static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
+static inline bool is_midr_in_range(struct midr_range const *range)
 {
-	return midr_is_cpu_model_range(midr, range->model,
+	return midr_is_cpu_model_range(read_cpuid_id(), range->model,
 				       range->rv_min, range->rv_max);
 }
 
 static inline bool
-is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
+is_midr_in_range_list(struct midr_range const *ranges)
 {
 	while (ranges->model)
-		if (is_midr_in_range(midr, ranges++))
+		if (is_midr_in_range(ranges++))
 			return true;
 	return false;
 }
 
-/*
- * The CPU ID never changes at run time, so we might as well tell the
- * compiler that it's constant.  Use this function to read the CPU ID
- * rather than directly reading processor_id or read_cpuid() directly.
- */
-static inline u32 __attribute_const__ read_cpuid_id(void)
-{
-	return read_cpuid(MIDR_EL1);
-}
-
 static inline u64 __attribute_const__ read_cpuid_mpidr(void)
 {
 	return read_cpuid(MPIDR_EL1);
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 2ec96d91acc6..bfd303e074be 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -101,8 +101,7 @@ static inline bool kaslr_requires_kpti(void)
 	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))
+		if (is_midr_in_range_list(cavium_erratum_27456_cpus))
 			return false;
 	}
 
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index a78f247029ae..929685c00263 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -15,30 +15,34 @@
 #include <asm/smp_plat.h>
 
 static bool __maybe_unused
-is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
+__is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
+			 u32 midr, u32 revidr)
 {
 	const struct arm64_midr_revidr *fix;
-	u32 midr = read_cpuid_id(), revidr;
-
-	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	if (!is_midr_in_range(midr, &entry->midr_range))
+	if (!is_midr_in_range(&entry->midr_range))
 		return false;
 
 	midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;
-	revidr = read_cpuid(REVIDR_EL1);
 	for (fix = entry->fixed_revs; fix && fix->revidr_mask; fix++)
 		if (midr == fix->midr_rv && (revidr & fix->revidr_mask))
 			return false;
-
 	return true;
 }
 
+static bool __maybe_unused
+is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+	return __is_affected_midr_range(entry, read_cpuid_id(),
+					read_cpuid(REVIDR_EL1));
+}
+
 static bool __maybe_unused
 is_affected_midr_range_list(const struct arm64_cpu_capabilities *entry,
 			    int scope)
 {
 	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	return is_midr_in_range_list(read_cpuid_id(), entry->midr_range_list);
+	return is_midr_in_range_list(entry->midr_range_list);
 }
 
 static bool __maybe_unused
@@ -186,12 +190,11 @@ static bool __maybe_unused
 has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
 				int scope)
 {
-	u32 midr = read_cpuid_id();
 	bool has_dic = read_cpuid_cachetype() & BIT(CTR_EL0_DIC_SHIFT);
 	const struct midr_range range = MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1);
 
 	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	return is_midr_in_range(midr, &range) && has_dic;
+	return is_midr_in_range(&range) && has_dic;
 }
 
 #ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed8..4cc4ae16b28d 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1783,7 +1783,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
 	char const *str = "kpti command line option";
 	bool meltdown_safe;
 
-	meltdown_safe = is_midr_in_range_list(read_cpuid_id(), kpti_safe_list);
+	meltdown_safe = is_midr_in_range_list(kpti_safe_list);
 
 	/* Defer to CPU feature registers */
 	if (has_cpuid_feature(entry, scope))
@@ -1853,7 +1853,7 @@ static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
 
 	return (__system_matches_cap(ARM64_HAS_NESTED_VIRT) &&
 		!(has_cpuid_feature(entry, scope) ||
-		  is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
+		  is_midr_in_range_list(nv1_ni_list)));
 }
 
 #if defined(ID_AA64MMFR0_EL1_TGRAN_LPA2) && defined(ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2)
@@ -2036,7 +2036,7 @@ static bool cpu_has_broken_dbm(void)
 		{},
 	};
 
-	return is_midr_in_range_list(read_cpuid_id(), cpus);
+	return is_midr_in_range_list(cpus);
 }
 
 static bool cpu_can_use_dbm(const struct arm64_cpu_capabilities *cap)
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index da53722f95d4..a573fa40d4b6 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -172,7 +172,7 @@ static enum mitigation_state spectre_v2_get_cpu_hw_mitigation_state(void)
 		return SPECTRE_UNAFFECTED;
 
 	/* Alternatively, we have a list of unaffected CPUs */
-	if (is_midr_in_range_list(read_cpuid_id(), spectre_v2_safe_list))
+	if (is_midr_in_range_list(spectre_v2_safe_list))
 		return SPECTRE_UNAFFECTED;
 
 	return SPECTRE_VULNERABLE;
@@ -331,7 +331,7 @@ bool has_spectre_v3a(const struct arm64_cpu_capabilities *entry, int scope)
 	};
 
 	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	return is_midr_in_range_list(read_cpuid_id(), spectre_v3a_unsafe_list);
+	return is_midr_in_range_list(spectre_v3a_unsafe_list);
 }
 
 void spectre_v3a_enable_mitigation(const struct arm64_cpu_capabilities *__unused)
@@ -475,7 +475,7 @@ static enum mitigation_state spectre_v4_get_cpu_hw_mitigation_state(void)
 		{ /* sentinel */ },
 	};
 
-	if (is_midr_in_range_list(read_cpuid_id(), spectre_v4_safe_list))
+	if (is_midr_in_range_list(spectre_v4_safe_list))
 		return SPECTRE_UNAFFECTED;
 
 	/* CPU features are detected first */
@@ -878,13 +878,13 @@ u8 spectre_bhb_loop_affected(int scope)
 			{},
 		};
 
-		if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
+		if (is_midr_in_range_list(spectre_bhb_k32_list))
 			k = 32;
-		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
+		else if (is_midr_in_range_list(spectre_bhb_k24_list))
 			k = 24;
-		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
+		else if (is_midr_in_range_list(spectre_bhb_k11_list))
 			k = 11;
-		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
+		else if (is_midr_in_range_list(spectre_bhb_k8_list))
 			k =  8;
 
 		max_bhb_k = max(max_bhb_k, k);
@@ -926,8 +926,7 @@ static bool is_spectre_bhb_fw_affected(int scope)
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
 		{},
 	};
-	bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
-					 spectre_bhb_firmware_mitigated_list);
+	bool cpu_in_list = is_midr_in_range_list(spectre_bhb_firmware_mitigated_list);
 
 	if (scope != SCOPE_LOCAL_CPU)
 		return system_affected;
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index f267bc2486a1..b815d910c7e4 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -632,7 +632,7 @@ static const struct midr_range broken_seis[] = {
 static bool vgic_v3_broken_seis(void)
 {
 	return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) &&
-		is_midr_in_range_list(read_cpuid_id(), broken_seis));
+		is_midr_in_range_list(broken_seis));
 }
 
 /**
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 808f259781fd..981a578043a5 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -842,7 +842,7 @@ static u64 __arch_timer_check_delta(void)
 		{},
 	};
 
-	if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) {
+	if (is_midr_in_range_list(broken_cval_midrs)) {
 		pr_warn_once("Broken CNTx_CVAL_EL1, using 31 bit TVAL instead.\n");
 		return CLOCKSOURCE_MASK(31);
 	}
-- 
2.47.0



From shameerali.kolothum.thodi at huawei.com  Wed Dec 18 02:53:45 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Wed, 18 Dec 2024 10:53:45 +0000
Subject: [PATCH v4 3/3] arm64: paravirt: Enable errata based on implementation CPUs
In-Reply-To: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20241218105345.73472-4-shameerali.kolothum.thodi@huawei.com>

Retrieve any migration target implementation CPUs using the hypercall
and enable associated errata.

Reviewed-by: Sebastian Ott <sebott at redhat.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 arch/arm64/include/asm/cputype.h  | 25 +++++++++++++++++++++++--
 arch/arm64/include/asm/paravirt.h |  3 +++
 arch/arm64/kernel/cpu_errata.c    | 20 +++++++++++++++++---
 arch/arm64/kernel/cpufeature.c    |  2 ++
 arch/arm64/kernel/image-vars.h    |  2 ++
 arch/arm64/kernel/paravirt.c      | 31 +++++++++++++++++++++++++++++++
 6 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index dcf0e1ce892d..019d1b7dae80 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -265,6 +265,16 @@ struct midr_range {
 #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r)
 #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
 
+#define MAX_TARGET_IMPL_CPUS 64
+
+struct target_impl_cpu {
+	u64 midr;
+	u64 revidr;
+};
+
+extern u32 target_impl_cpu_num;
+extern struct target_impl_cpu target_impl_cpus[];
+
 static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
 					   u32 rv_max)
 {
@@ -276,8 +286,19 @@ static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
 
 static inline bool is_midr_in_range(struct midr_range const *range)
 {
-	return midr_is_cpu_model_range(read_cpuid_id(), range->model,
-				       range->rv_min, range->rv_max);
+	int i;
+
+	if (!target_impl_cpu_num)
+		return midr_is_cpu_model_range(read_cpuid_id(), range->model,
+					       range->rv_min, range->rv_max);
+
+	for (i = 0; i < target_impl_cpu_num; i++) {
+		if (midr_is_cpu_model_range(target_impl_cpus[i].midr,
+					    range->model,
+					    range->rv_min, range->rv_max))
+			return true;
+	}
+	return false;
 }
 
 static inline bool
diff --git a/arch/arm64/include/asm/paravirt.h b/arch/arm64/include/asm/paravirt.h
index 9aa193e0e8f2..95f1c15bbb7d 100644
--- a/arch/arm64/include/asm/paravirt.h
+++ b/arch/arm64/include/asm/paravirt.h
@@ -19,11 +19,14 @@ static inline u64 paravirt_steal_clock(int cpu)
 }
 
 int __init pv_time_init(void);
+void __init pv_target_impl_cpu_init(void);
 
 #else
 
 #define pv_time_init() do {} while (0)
 
+#define pv_target_impl_cpu_init() do {} while (0)
+
 #endif // CONFIG_PARAVIRT
 
 #endif
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 929685c00263..4055082ce69b 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -14,6 +14,9 @@
 #include <asm/kvm_asm.h>
 #include <asm/smp_plat.h>
 
+u32 target_impl_cpu_num;
+struct target_impl_cpu target_impl_cpus[MAX_TARGET_IMPL_CPUS];
+
 static bool __maybe_unused
 __is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
 			 u32 midr, u32 revidr)
@@ -32,9 +35,20 @@ __is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
 static bool __maybe_unused
 is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
 {
-	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
-	return __is_affected_midr_range(entry, read_cpuid_id(),
-					read_cpuid(REVIDR_EL1));
+	int i;
+
+	if (!target_impl_cpu_num) {
+		WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+		return __is_affected_midr_range(entry, read_cpuid_id(),
+						read_cpuid(REVIDR_EL1));
+	}
+
+	for (i = 0; i < target_impl_cpu_num; i++) {
+		if (__is_affected_midr_range(entry, target_impl_cpus[i].midr,
+					     target_impl_cpus[i].midr))
+			return true;
+	}
+	return false;
 }
 
 static bool __maybe_unused
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 4cc4ae16b28d..d32c767bf189 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -85,6 +85,7 @@
 #include <asm/kvm_host.h>
 #include <asm/mmu_context.h>
 #include <asm/mte.h>
+#include <asm/paravirt.h>
 #include <asm/processor.h>
 #include <asm/smp.h>
 #include <asm/sysreg.h>
@@ -3642,6 +3643,7 @@ unsigned long cpu_get_elf_hwcap3(void)
 
 static void __init setup_boot_cpu_capabilities(void)
 {
+	pv_target_impl_cpu_init();
 	/*
 	 * The boot CPU's feature register values have been recorded. Detect
 	 * boot cpucaps and local cpucaps for the boot CPU, then enable and
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 8f5422ed1b75..694e19709c46 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -49,6 +49,8 @@ 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);
+PROVIDE(__pi_target_impl_cpu_num	= target_impl_cpu_num);
+PROVIDE(__pi_target_impl_cpus		= target_impl_cpus);
 #endif
 PROVIDE(__pi__ctype			= _ctype);
 PROVIDE(__pi_memstart_offset_seed	= memstart_offset_seed);
diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c
index aa718d6a9274..95fc3aae4a27 100644
--- a/arch/arm64/kernel/paravirt.c
+++ b/arch/arm64/kernel/paravirt.c
@@ -153,6 +153,37 @@ static bool __init has_pv_steal_clock(void)
 	return (res.a0 == SMCCC_RET_SUCCESS);
 }
 
+void  __init pv_target_impl_cpu_init(void)
+{
+	struct arm_smccc_res res;
+	int index = 0, max_idx = -1;
+
+	/* Check we have already set targets */
+	if (target_impl_cpu_num)
+		return;
+
+	do {
+		arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID,
+				     index, &res);
+		if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
+			return;
+
+		if (max_idx < 0) {
+			/* res.a0 should have a valid maximum CPU implementation index */
+			if (res.a0 >= MAX_TARGET_IMPL_CPUS)
+				return;
+			max_idx = res.a0;
+		}
+
+		target_impl_cpus[index].midr = res.a1;
+		target_impl_cpus[index].revidr = res.a2;
+		index++;
+	} while (index <= max_idx);
+
+	target_impl_cpu_num = index;
+	pr_info("Number of target implementation CPUs is %d\n", target_impl_cpu_num);
+}
+
 int __init pv_time_init(void)
 {
 	int ret;
-- 
2.47.0



From shameerali.kolothum.thodi at huawei.com  Wed Dec 18 02:53:44 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Wed, 18 Dec 2024 10:53:44 +0000
Subject: [PATCH v4 2/3] KVM: arm64: Introduce hypercall support for retrieving target implementations
In-Reply-To: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20241218105345.73472-3-shameerali.kolothum.thodi@huawei.com>

If the Guest requires migration to multiple targets, this hypercall
will provide a way to retrieve the target CPU implementations from
the user space VMM.

Subsequent patch will use this to enable the associated errata.

Suggested-by: Oliver Upton <oliver.upton at linux.dev>
Reviewed-by: Sebastian Ott <sebott at redhat.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 Documentation/virt/kvm/arm/hypercalls.rst | 30 +++++++++++++++++++++++
 include/linux/arm-smccc.h                 |  7 ++++++
 2 files changed, 37 insertions(+)

diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index af7bc2c2e0cb..16b4c02cf9d9 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -142,3 +142,33 @@ region is equal to the memory protection granule advertised by
 |                     |          |    +---------------------------------------------+
 |                     |          |    | ``INVALID_PARAMETER (-3)``                  |
 +---------------------+----------+----+---------------------------------------------+
+
+``ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID``
+-------------------------------------------------------
+
+Request the target CPU implementation information for the Guest VM. This hypercall
+must be handled by the userspace VMM. The Guest kernel will use this information to
+enable the associated errata. A maximum of 64 implementations is supported.
+
++---------------------+-------------------------------------------------------------+
+| Presence:           | Optional;  KVM/ARM64 Guests only                            |
++---------------------+-------------------------------------------------------------+
+| Calling convention: | HVC64                                                       |
++---------------------+----------+--------------------------------------------------+
+| Function ID:        | (uint32) | 0xC600007E                                       |
++---------------------+----------+----+---------------------------------------------+
+| Arguments:          | (uint64) | R1 | selected implementation index               |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R2 | Reserved / Must be zero                     |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R3 | Reserved / Must be zero                     |
++---------------------+----------+----+---------------------------------------------+
+| Return Values:      | (int64)  | R0 | -1 on error else the maximum required CPU   |
+|                     |          |    | implementation index.                       |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R1 | MIDR_EL1 of the selected implementation     |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R2 | REVIDR_EL1 of the selected implementation   |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R3 | Reserved / Must be zero                     |
++---------------------+----------+----+---------------------------------------------+
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 67f6fdf2e7cd..6c080fa9d345 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -179,6 +179,7 @@
 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62		62
 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63		63
 /* End of pKVM hypercall range */
+#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS	126
 #define ARM_SMCCC_KVM_FUNC_FEATURES_2		127
 #define ARM_SMCCC_KVM_NUM_FUNCS			128
 
@@ -225,6 +226,12 @@
 			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
 			   ARM_SMCCC_KVM_FUNC_MMIO_GUARD)
 
+#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID		\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_64,				\
+			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
+			   ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS)
+
 /* ptp_kvm counter type ID */
 #define KVM_PTP_VIRT_COUNTER			0
 #define KVM_PTP_PHYS_COUNTER			1
-- 
2.47.0



From peterz at infradead.org  Wed Dec 18 03:04:08 2024
From: peterz at infradead.org (Peter Zijlstra)
Date: Wed, 18 Dec 2024 12:04:08 +0100
Subject: [PATCH v2 1/5] x86/bug: Add ARCH_WARN_ASM macro for BUG/WARN asm
 code sharing with Rust
In-Reply-To: <20241218062009.2402650-2-fujita.tomonori@gmail.com>
References: <20241218062009.2402650-1-fujita.tomonori@gmail.com>
 <20241218062009.2402650-2-fujita.tomonori@gmail.com>
Message-ID: <20241218110408.GF2484@noisy.programming.kicks-ass.net>

On Wed, Dec 18, 2024 at 03:20:05PM +0900, FUJITA Tomonori wrote:
> Add new ARCH_WARN_ASM macro for BUG/WARN assembly code sharing with
> Rust to avoid the duplication.

This conflicts with some patches I've been sitting on, but nothing that
I can't resolve I think.

Acked-by: Peter Zijlstra (Intel) <peterz at infradead.org>

> Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
> ---
>  arch/x86/include/asm/bug.h | 51 ++++++++++++++++++--------------------
>  1 file changed, 24 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
> index 806649c7f23d..71df68e2a731 100644
> --- a/arch/x86/include/asm/bug.h
> +++ b/arch/x86/include/asm/bug.h
> @@ -28,45 +28,42 @@
>  #ifdef CONFIG_GENERIC_BUG
>  
>  #ifdef CONFIG_X86_32
> -# define __BUG_REL(val)	".long " __stringify(val)
> +# define __BUG_REL(val)	".long " val
>  #else
> -# define __BUG_REL(val)	".long " __stringify(val) " - ."
> +# define __BUG_REL(val)	".long " val " - ."
>  #endif
>  
>  #ifdef CONFIG_DEBUG_BUGVERBOSE
> +#define __BUG_ENTRY(file, line, flags)					\
> +	"2:\t" __BUG_REL("1b") "\t# bug_entry::bug_addr\n"		\
> +	"\t" __BUG_REL(file)   "\t# bug_entry::file\n"			\
> +	"\t.word " line        "\t# bug_entry::line\n"			\
> +	"\t.word " flags       "\t# bug_entry::flags\n"
> +#else
> +#define __BUG_ENTRY(file, ine, flags)					\
> +	"2:\t" __BUG_REL("1b") "\t# bug_entry::bug_addr\n"		\
> +	"\t.word " flags       "\t# bug_entry::flags\n"
> +#endif
> +
> +#define _BUG_FLAGS_ASM(ins, file, line, flags, size, extra)		\
> +	"1:\t" ins "\n"							\
> +	".pushsection __bug_table,\"aw\"\n"				\
> +	__BUG_ENTRY(file, line, flags)					\
> +	"\t.org 2b + " size "\n"					\
> +	".popsection\n"							\
> +	extra
>  
>  #define _BUG_FLAGS(ins, flags, extra)					\
>  do {									\
> -	asm_inline volatile("1:\t" ins "\n"				\
> -		     ".pushsection __bug_table,\"aw\"\n"		\
> -		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
> -		     "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"	\
> -		     "\t.word %c1"        "\t# bug_entry::line\n"	\
> -		     "\t.word %c2"        "\t# bug_entry::flags\n"	\
> -		     "\t.org 2b+%c3\n"					\
> -		     ".popsection\n"					\
> -		     extra						\
> +	asm_inline volatile(_BUG_FLAGS_ASM(ins, "%c0",			\
> +					   "%c1", "%c2", "%c3", extra)	\
>  		     : : "i" (__FILE__), "i" (__LINE__),		\
>  			 "i" (flags),					\
>  			 "i" (sizeof(struct bug_entry)));		\
>  } while (0)
>  
> -#else /* !CONFIG_DEBUG_BUGVERBOSE */
> -
> -#define _BUG_FLAGS(ins, flags, extra)					\
> -do {									\
> -	asm_inline volatile("1:\t" ins "\n"				\
> -		     ".pushsection __bug_table,\"aw\"\n"		\
> -		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
> -		     "\t.word %c0"        "\t# bug_entry::flags\n"	\
> -		     "\t.org 2b+%c1\n"					\
> -		     ".popsection\n"					\
> -		     extra						\
> -		     : : "i" (flags),					\
> -			 "i" (sizeof(struct bug_entry)));		\
> -} while (0)
> -
> -#endif /* CONFIG_DEBUG_BUGVERBOSE */
> +#define ARCH_WARN_ASM(file, line, flags, size)				\
> +	_BUG_FLAGS_ASM(ASM_UD2, file, line, flags, size, "")
>  
>  #else
>  
> -- 
> 2.43.0
> 
> 


From simona.vetter at ffwll.ch  Wed Dec 18 03:06:32 2024
From: simona.vetter at ffwll.ch (Simona Vetter)
Date: Wed, 18 Dec 2024 12:06:32 +0100
Subject: [PATCH v4 0/6] TEE subsystem for restricted dma-buf allocations
In-Reply-To: <20241217100809.3962439-1-jens.wiklander@linaro.org>
References: <20241217100809.3962439-1-jens.wiklander@linaro.org>
Message-ID: <Z2KsuAs-Dd4ZDaXR@phenom.ffwll.local>

On Tue, Dec 17, 2024 at 11:07:36AM +0100, Jens Wiklander wrote:
> Hi,
> 
> This patch set allocates the restricted DMA-bufs via the TEE subsystem.
> 
> The TEE subsystem handles the DMA-buf allocations since it is the TEE
> (OP-TEE, AMD-TEE, TS-TEE, or perhaps a future QCOMTEE) which sets up the
> restrictions for the memory used for the DMA-bufs.
> 
> I've added a new IOCTL, TEE_IOC_RSTMEM_ALLOC, to allocate the restricted
> DMA-bufs. This IOCTL reaches the backend TEE driver, allowing it to choose
> how to allocate the restricted physical memory.
> 
> TEE_IOC_RSTMEM_ALLOC takes in addition to a size and flags parameters also
> a use-case parameter. This is used by the backend TEE driver to decide on
> allocation policy and which devices should be able to access the memory.
> 
> Three use-cases (Secure Video Playback, Trusted UI, and Secure Video
> Recording) has been identified so far to serve as examples of what can be
> expected. More use-cases can be added in userspace ABI, but it's up to the
> backend TEE drivers to provide the implementation.
> 
> Each use-case has it's own restricted memory pool since different use-cases
> requires isolation from different parts of the system. A restricted memory
> pool can be based on a static carveout instantiated while probing the TEE
> backend driver, or dynamically allocated from CMA and made restricted as
> needed by the TEE.
> 
> This can be tested on QEMU with the following steps:
> repo init -u https://github.com/jenswi-linaro/manifest.git -m qemu_v8.xml \
>         -b prototype/sdp-v4
> repo sync -j8
> cd build
> make toolchains -j$(nproc)
> make SPMC_AT_EL=1 all -j$(nproc)
> make SPMC_AT_EL=1 run-only
> # login and at the prompt:
> xtest --sdp-basic
> 
> The SPMC_AT_EL=1 parameter configures the build with FF-A and an SPMC at
> S-EL1 inside OP-TEE. The parameter can be changed into SPMC_AT_EL=n to test
> without FF-A using the original SMC ABI instead. Please remember to do
> %rm -rf ../trusted-firmware-a/build/qemu
> for TF-A to be rebuilt properly using the new configuration.
> 
> https://optee.readthedocs.io/en/latest/building/prerequisites.html
> list dependencies needed to build the above.
> 
> The tests are pretty basic, mostly checking that a Trusted Application in
> the secure world can access and manipulate the memory. There are also some
> negative tests for out of bounds buffers etc.

I think I've dropped this on earlier encrypted dma-buf discussions for
TEE, but can't find one right now ...

Do we have some open source userspace for this? To my knowledge we have
two implementations of encrypted/content protected dma-buf in upstream
right now in the amd and intel gpu drivers, and unless I'm mistaken they
both have some minimal userspace supporting EXT_protected_textures:

https://github.com/KhronosGroup/OpenGL-Registry/blob/main/extensions/EXT/EXT_protected_textures.txt

It's not great, but it does just barely clear the bar in my opinion. I
guess something in gstreamer or similar video pipeline framework would
also do the job.

Especially with the context of the uapi discussion in the v1/RFC thread I
think we need more than a bare-bones testcase to make sure this works in
actual use.

Cheers, Sima

> 
> Thanks,
> Jens
> 
> Changes since V3:
> * Make the use_case and flags field in struct tee_shm u32's instead of
>   u16's
> * Add more description for TEE_IOC_RSTMEM_ALLOC in the header file
> * Import namespace DMA_BUF in module tee, reported by lkp at intel.com
> * Added a note in the commit message for "optee: account for direction
>   while converting parameters" why it's needed
> * Factor out dynamic restricted memory allocation from
>   "optee: support restricted memory allocation" into two new commits
>   "optee: FF-A: dynamic restricted memory allocation" and
>   "optee: smc abi: dynamic restricted memory allocation"
> * Guard CMA usage with #ifdef CONFIG_CMA, effectively disabling dynamic
>   restricted memory allocate if CMA isn't configured
> 
> Changes since the V2 RFC:
> * Based on v6.12
> * Replaced the flags for SVP and Trusted UID memory with a u32 field with
>   unique id for each use case
> * Added dynamic allocation of restricted memory pools
> * Added OP-TEE ABI both with and without FF-A for dynamic restricted memory
> * Added support for FF-A with FFA_LEND
> 
> Changes since the V1 RFC:
> * Based on v6.11
> * Complete rewrite, replacing the restricted heap with TEE_IOC_RSTMEM_ALLOC
> 
> Changes since Olivier's post [2]:
> * Based on Yong Wu's post [1] where much of dma-buf handling is done in
>   the generic restricted heap
> * Simplifications and cleanup
> * New commit message for "dma-buf: heaps: add Linaro restricted dmabuf heap
>   support"
> * Replaced the word "secure" with "restricted" where applicable
> 
> Jens Wiklander (6):
>   tee: add restricted memory allocation
>   optee: account for direction while converting parameters
>   optee: sync secure world ABI headers
>   optee: support restricted memory allocation
>   optee: FF-A: dynamic restricted memory allocation
>   optee: smc abi: dynamic restricted memory allocation
> 
>  drivers/tee/Makefile              |   1 +
>  drivers/tee/optee/Makefile        |   1 +
>  drivers/tee/optee/call.c          |  10 +-
>  drivers/tee/optee/core.c          |   1 +
>  drivers/tee/optee/ffa_abi.c       | 178 +++++++++++++-
>  drivers/tee/optee/optee_ffa.h     |  27 ++-
>  drivers/tee/optee/optee_msg.h     |  65 ++++-
>  drivers/tee/optee/optee_private.h |  75 ++++--
>  drivers/tee/optee/optee_smc.h     |  71 +++++-
>  drivers/tee/optee/rpc.c           |  31 ++-
>  drivers/tee/optee/rstmem.c        | 388 ++++++++++++++++++++++++++++++
>  drivers/tee/optee/smc_abi.c       | 213 ++++++++++++++--
>  drivers/tee/tee_core.c            |  38 ++-
>  drivers/tee/tee_private.h         |   2 +
>  drivers/tee/tee_rstmem.c          | 201 ++++++++++++++++
>  drivers/tee/tee_shm.c             |   2 +
>  drivers/tee/tee_shm_pool.c        |  69 +++++-
>  include/linux/tee_core.h          |  15 ++
>  include/linux/tee_drv.h           |   2 +
>  include/uapi/linux/tee.h          |  44 +++-
>  20 files changed, 1358 insertions(+), 76 deletions(-)
>  create mode 100644 drivers/tee/optee/rstmem.c
>  create mode 100644 drivers/tee/tee_rstmem.c
> 
> 
> base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
> -- 
> 2.43.0
> 

-- 
Simona Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From peter.griffin at linaro.org  Wed Dec 18 03:08:48 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 18 Dec 2024 11:08:48 +0000
Subject: [PATCH v5 3/3] MAINTAINERS: add entry for Samsung Exynos mailbox driver
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-3-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org> <20241217-acpm-v4-upstream-mbox-v5-3-cd1d3951fe84@linaro.org>
Message-ID: <CADrjBPr82hvSSyULxi0k08ts2d1vO41qXvmr08+9wP-MB9fhvQ@mail.gmail.com>

Hi Tudor,

On Tue, 17 Dec 2024 at 09:40, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> Add entry for the Samsung Exynos mailbox driver.
>
> 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  Wed Dec 18 02:53:17 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:53:17 +0100
Subject: [PATCH v1 0/3] MediaTek MT8188 MDP3 Enablement
Message-ID: <20241218105320.38980-1-angelogioacchino.delregno@collabora.com>

This series adds the necessary bindings and devicetree nodes to enable
the entire Multimedia Data Path 3 (MDP3) macro-block, found in MediaTek's
MT8188 SoC.

This was tested on a MediaTek Genio 700 EVK board.

AngeloGioacchino Del Regno (3):
  dt-bindings: display: mediatek: Add compatibles for MT8188 MDP3
  dt-bindings: media: mediatek: mdp3: Add compatibles for MT8188 MDP3
  arm64: dts: mediatek: mt8188: Add all Multimedia Data Path 3 nodes

 .../display/mediatek/mediatek,aal.yaml        |   4 +
 .../display/mediatek/mediatek,color.yaml      |   4 +
 .../display/mediatek/mediatek,merge.yaml      |   4 +
 .../display/mediatek/mediatek,padding.yaml    |  10 +-
 .../bindings/media/mediatek,mdp3-fg.yaml      |   8 +-
 .../bindings/media/mediatek,mdp3-hdr.yaml     |   8 +-
 .../bindings/media/mediatek,mdp3-rsz.yaml     |   1 +
 .../bindings/media/mediatek,mdp3-stitch.yaml  |   8 +-
 .../bindings/media/mediatek,mdp3-tcc.yaml     |   8 +-
 .../bindings/media/mediatek,mdp3-tdshp.yaml   |   8 +-
 .../bindings/media/mediatek,mdp3-wrot.yaml    |   1 +
 arch/arm64/boot/dts/mediatek/mt8188.dtsi      | 313 ++++++++++++++++++
 12 files changed, 364 insertions(+), 13 deletions(-)

-- 
2.46.1



From angelogioacchino.delregno at collabora.com  Wed Dec 18 02:53:18 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:53:18 +0100
Subject: [PATCH v1 1/3] dt-bindings: display: mediatek: Add compatibles for MT8188 MDP3
In-Reply-To: <20241218105320.38980-1-angelogioacchino.delregno@collabora.com>
References: <20241218105320.38980-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241218105320.38980-2-angelogioacchino.delregno@collabora.com>

Add compatible strings for the AAL, COLOR, MERGE and PADDING
hardware components found in MediaTek's MT8188 SoC.

This hardware is compatible with MT8195.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../bindings/display/mediatek/mediatek,aal.yaml        |  4 ++++
 .../bindings/display/mediatek/mediatek,color.yaml      |  4 ++++
 .../bindings/display/mediatek/mediatek,merge.yaml      |  4 ++++
 .../bindings/display/mediatek/mediatek,padding.yaml    | 10 +++++++---
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
index cf24434854ff..1479035da409 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -25,6 +25,10 @@ properties:
           - mediatek,mt8173-disp-aal
           - mediatek,mt8183-disp-aal
           - mediatek,mt8195-mdp3-aal
+      - items:
+          - enum:
+              - mediatek,mt8188-mdp3-aal
+          - const: mediatek,mt8195-mdp3-aal
       - items:
           - enum:
               - mediatek,mt2712-disp-aal
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
index 7df786bbad20..799c0b8fc1f9 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -27,6 +27,10 @@ properties:
           - mediatek,mt8167-disp-color
           - mediatek,mt8173-disp-color
           - mediatek,mt8195-mdp3-color
+      - items:
+          - enum:
+              - mediatek,mt8188-mdp3-color
+          - const: mediatek,mt8195-mdp3-color
       - items:
           - enum:
               - mediatek,mt7623-disp-color
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index dae839279950..415a25bc18fa 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -25,6 +25,10 @@ properties:
           - mediatek,mt8173-disp-merge
           - mediatek,mt8195-disp-merge
           - mediatek,mt8195-mdp3-merge
+      - items:
+          - enum:
+              - mediatek,mt8188-mdp3-merge
+          - const: mediatek,mt8195-mdp3-merge
       - items:
           - const: mediatek,mt6795-disp-merge
           - const: mediatek,mt8173-disp-merge
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,padding.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,padding.yaml
index be07bbdc54e3..86787866ced0 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,padding.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,padding.yaml
@@ -20,9 +20,13 @@ description:
 
 properties:
   compatible:
-    enum:
-      - mediatek,mt8188-disp-padding
-      - mediatek,mt8195-mdp3-padding
+    oneOf:
+      - enum:
+          - mediatek,mt8188-disp-padding
+          - mediatek,mt8195-mdp3-padding
+      - items:
+          - const: mediatek,mt8188-mdp3-padding
+          - const: mediatek,mt8195-mdp3-padding
 
   reg:
     maxItems: 1
-- 
2.46.1



From angelogioacchino.delregno at collabora.com  Wed Dec 18 02:53:19 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:53:19 +0100
Subject: [PATCH v1 2/3] dt-bindings: media: mediatek: mdp3: Add compatibles for MT8188 MDP3
In-Reply-To: <20241218105320.38980-1-angelogioacchino.delregno@collabora.com>
References: <20241218105320.38980-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241218105320.38980-3-angelogioacchino.delregno@collabora.com>

Add compatible strings for the FG, HDR, RSZ, STITCH, TCC, TDSHP
and WROT hardware components found in MediaTek's MT8188 SoC.

This hardware is compatible with MT8195.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../devicetree/bindings/media/mediatek,mdp3-fg.yaml       | 8 ++++++--
 .../devicetree/bindings/media/mediatek,mdp3-hdr.yaml      | 8 ++++++--
 .../devicetree/bindings/media/mediatek,mdp3-rsz.yaml      | 1 +
 .../devicetree/bindings/media/mediatek,mdp3-stitch.yaml   | 8 ++++++--
 .../devicetree/bindings/media/mediatek,mdp3-tcc.yaml      | 8 ++++++--
 .../devicetree/bindings/media/mediatek,mdp3-tdshp.yaml    | 8 ++++++--
 .../devicetree/bindings/media/mediatek,mdp3-wrot.yaml     | 1 +
 7 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml
index 03f31b009085..40fda59fa8a8 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml
@@ -16,8 +16,12 @@ description:
 
 properties:
   compatible:
-    enum:
-      - mediatek,mt8195-mdp3-fg
+    oneOf:
+      - enum:
+          - mediatek,mt8195-mdp3-fg
+      - items:
+          - const: mediatek,mt8188-mdp3-fg
+          - const: mediatek,mt8195-mdp3-fg
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml
index d4609bba6578..d9f926c20220 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml
@@ -16,8 +16,12 @@ description:
 
 properties:
   compatible:
-    enum:
-      - mediatek,mt8195-mdp3-hdr
+    oneOf:
+      - enum:
+          - mediatek,mt8195-mdp3-hdr
+      - items:
+          - const: mediatek,mt8188-mdp3-hdr
+          - const: mediatek,mt8195-mdp3-hdr
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
index f5676bec4326..8124c39d73e9 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
@@ -20,6 +20,7 @@ properties:
           - mediatek,mt8183-mdp3-rsz
       - items:
           - enum:
+              - mediatek,mt8188-mdp3-rsz
               - mediatek,mt8195-mdp3-rsz
           - const: mediatek,mt8183-mdp3-rsz
 
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml
index d815bea29154..1d8e7e202c42 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml
@@ -16,8 +16,12 @@ description:
 
 properties:
   compatible:
-    enum:
-      - mediatek,mt8195-mdp3-stitch
+    oneOf:
+      - enum:
+          - mediatek,mt8195-mdp3-stitch
+      - items:
+          - const: mediatek,mt8188-mdp3-stitch
+          - const: mediatek,mt8195-mdp3-stitch
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
index 14ea556d4f82..6cff7c073ce4 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
@@ -17,8 +17,12 @@ description:
 
 properties:
   compatible:
-    enum:
-      - mediatek,mt8195-mdp3-tcc
+    oneOf:
+      - enum:
+          - mediatek,mt8195-mdp3-tcc
+      - items:
+          - const: mediatek,mt8188-mdp3-tcc
+          - const: mediatek,mt8195-mdp3-tcc
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml
index 8ab7f2d8e148..cdfa27324738 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml
@@ -16,8 +16,12 @@ description:
 
 properties:
   compatible:
-    enum:
-      - mediatek,mt8195-mdp3-tdshp
+    oneOf:
+      - enum:
+          - mediatek,mt8195-mdp3-tdshp
+      - items:
+          - const: mediatek,mt8188-mdp3-tdshp
+          - const: mediatek,mt8195-mdp3-tdshp
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
index 53a679338402..b6269f4f9fd6 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
@@ -20,6 +20,7 @@ properties:
           - mediatek,mt8183-mdp3-wrot
       - items:
           - enum:
+              - mediatek,mt8188-mdp3-wrot
               - mediatek,mt8195-mdp3-wrot
           - const: mediatek,mt8183-mdp3-wrot
 
-- 
2.46.1



From angelogioacchino.delregno at collabora.com  Wed Dec 18 02:53:20 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:53:20 +0100
Subject: [PATCH v1 3/3] arm64: dts: mediatek: mt8188: Add all Multimedia Data Path 3 nodes
In-Reply-To: <20241218105320.38980-1-angelogioacchino.delregno@collabora.com>
References: <20241218105320.38980-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20241218105320.38980-4-angelogioacchino.delregno@collabora.com>

Add all of the Multimedia Data Path 3 (MDP3) related nodes
including its Mutex instances, one for each VPPSYS block, and
all of its DMA controllers, Film Grain (FG), HDR, Adaptive Ambient
Light (AAL), Frame Resizer (RSZ), Tone Curve Conversion (TCC),
Two-Dimensional Sharpness (TDSHP), and others, enabling the entire
MDP3 macro-block.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8188.dtsi | 313 +++++++++++++++++++++++
 1 file changed, 313 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index faccc7f16259..137bd39808ea 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -2164,6 +2164,126 @@ vppsys0: syscon at 14000000 {
 			#clock-cells = <1>;
 		};
 
+		dma-controller at 14001000 {
+			compatible = "mediatek,mt8188-mdp3-rdma", "mediatek,mt8195-mdp3-rdma";
+			reg = <0 0x14001000 0 0x1000>;
+			#dma-cells = <1>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_RDMA>,
+				 <&topckgen CLK_TOP_CFGREG_CLOCK_EN_VPP0>,
+				 <&topckgen CLK_TOP_CFGREG_F26M_VPP0>,
+				 <&vppsys0 CLK_VPP0_WARP0_ASYNC_TX>,
+				 <&vppsys0 CLK_VPP0_WARP0_RELAY>,
+				 <&vppsys0 CLK_VPP0_WARP0_ASYNC>,
+				 <&vppsys0 CLK_VPP02VPP1_RELAY>,
+				 <&vppsys1 CLK_VPP1_VPP0_DL_ASYNC>,
+				 <&vppsys1 CLK_VPP1_VPP0_DL1_RELAY>,
+				 <&vppsys0 CLK_VPP0_VPP12VPP0_ASYNC>;
+			mboxes = <&gce0 13 CMDQ_THR_PRIO_1>,
+				 <&gce0 14 CMDQ_THR_PRIO_1>,
+				 <&gce0 16 CMDQ_THR_PRIO_1>,
+				 <&gce0 21 CMDQ_THR_PRIO_1>;
+			iommus = <&vpp_iommu M4U_PORT_L4_MDP_RDMA>,
+				 <&vpp_iommu M4U_PORT_L4_MDP_WROT>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>,
+					<&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x1000 0x1000>;
+			mediatek,gce-events = <CMDQ_EVENT_VPP0_MDP_RDMA_SOF>,
+					      <CMDQ_EVENT_VPP0_MDP_RDMA_FRAME_DONE>;
+			mediatek,scp = <&scp>;
+		};
+
+		display at 14002000 {
+			compatible = "mediatek,mt8188-mdp3-fg", "mediatek,mt8195-mdp3-fg";
+			reg = <0 0x14002000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_FG>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x2000 0x1000>;
+		};
+
+		display at 14004000 {
+			compatible = "mediatek,mt8188-mdp3-hdr", "mediatek,mt8195-mdp3-hdr";
+			reg = <0 0x14004000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_HDR>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x4000 0x1000>;
+		};
+
+		display at 14005000 {
+			compatible = "mediatek,mt8188-mdp3-aal", "mediatek,mt8195-mdp3-aal";
+			reg = <0 0x14005000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_AAL>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x5000 0x1000>;
+		};
+
+		display at 14006000 {
+			compatible = "mediatek,mt8188-mdp3-rsz", "mediatek,mt8183-mdp3-rsz";
+			reg = <0 0x14006000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_RSZ>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x6000 0x1000>;
+		};
+
+		display at 14007000 {
+			compatible = "mediatek,mt8188-mdp3-tdshp", "mediatek,mt8195-mdp3-tdshp";
+			reg = <0 0x14007000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_TDSHP>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x7000 0x1000>;
+		};
+
+		display at 14008000 {
+			compatible = "mediatek,mt8188-mdp3-color", "mediatek,mt8195-mdp3-color";
+			reg = <0 0x14008000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_COLOR>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x8000 0x1000>;
+		};
+
+		display at 14009000 {
+			compatible = "mediatek,mt8188-mdp3-ovl", "mediatek,mt8195-mdp3-ovl";
+			reg = <0 0x14009000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_OVL>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x9000 0x1000>;
+		};
+
+		display at 1400a000 {
+			compatible = "mediatek,mt8188-mdp3-padding", "mediatek,mt8195-mdp3-padding";
+			reg = <0 0x1400a000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_PADDING>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0xa000 0x1000>;
+		};
+
+		display at 1400b000 {
+			compatible = "mediatek,mt8188-mdp3-tcc", "mediatek,mt8195-mdp3-tcc";
+			reg = <0 0x1400b000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_TCC>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0xb000 0x1000>;
+		};
+
+		display at 1400c000 {
+			compatible = "mediatek,mt8188-mdp3-wrot", "mediatek,mt8183-mdp3-wrot";
+			reg = <0 0x1400c000 0 0x1000>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_WROT>;
+			iommus = <&vpp_iommu M4U_PORT_L4_MDP_WROT>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0xc000 0x1000>;
+			mediatek,gce-events = <CMDQ_EVENT_VPP0_MDP_WROT_SOF>,
+					      <CMDQ_EVENT_VPP0_MDP_WROT_VIDO_WDONE>;
+		};
+
+		mutex at 1400f000 {
+			compatible = "mediatek,mt8188-vpp-mutex";
+			reg = <0 0x1400f000 0 0x1000>;
+			interrupts = <GIC_SPI 592 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MUTEX>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0xf000 0x1000>;
+		};
+
 		vpp_smi_common: smi at 14012000 {
 			compatible = "mediatek,mt8188-smi-common-vpp";
 			reg = <0 0x14012000 0 0x1000>;
@@ -2195,6 +2315,190 @@ vpp_iommu: iommu at 14018000 {
 			mediatek,larbs = <&larb1 &larb3 &larb4 &larb6 &larb7 &larb23>;
 		};
 
+		dma-controller at 14f09000 {
+			compatible = "mediatek,mt8188-mdp3-rdma", "mediatek,mt8195-mdp3-rdma";
+			reg = <0 0x14f09000 0 0x1000>;
+			#dma-cells = <1>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_RDMA>,
+				 <&topckgen CLK_TOP_CFGREG_CLOCK_EN_VPP1>,
+				 <&topckgen CLK_TOP_CFGREG_F26M_VPP1>;
+			iommus = <&vdo_iommu M4U_PORT_L5_SVPP2_MDP_RDMA>,
+				 <&vdo_iommu M4U_PORT_L5_SVPP2_MDP_WROT>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0x9000 0x1000>;
+			mediatek,gce-events = <CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_SOF>,
+					      <CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_FRAME_DONE>;
+		};
+
+		dma-controller at 14f0a000 {
+			compatible = "mediatek,mt8188-mdp3-rdma", "mediatek,mt8195-mdp3-rdma";
+			reg = <0 0x14f0a000 0 0x1000>;
+			#dma-cells = <1>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_RDMA>,
+				 <&topckgen CLK_TOP_CFGREG_CLOCK_EN_VPP1>,
+				 <&topckgen CLK_TOP_CFGREG_F26M_VPP1>;
+			iommus = <&vpp_iommu M4U_PORT_L6_SVPP3_MDP_RDMA>,
+				 <&vpp_iommu M4U_PORT_L6_SVPP3_MDP_WROT>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xa000 0x1000>;
+			mediatek,gce-events = <CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_SOF>,
+					      <CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_FRAME_DONE>;
+		};
+
+		display at 14f0c000 {
+			compatible = "mediatek,mt8188-mdp3-fg", "mediatek,mt8195-mdp3-fg";
+			reg = <0 0x14f0c000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_FG>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xc000 0x1000>;
+		};
+
+		display at 14f0d000 {
+			compatible = "mediatek,mt8188-mdp3-fg", "mediatek,mt8195-mdp3-fg";
+			reg = <0 0x14f0d000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_FG>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xd000 0x1000>;
+		};
+
+		display at 14f0f000 {
+			compatible = "mediatek,mt8188-mdp3-hdr", "mediatek,mt8195-mdp3-hdr";
+			reg = <0 0x14f0f000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_HDR>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xf000 0x1000>;
+		};
+
+		display at 14f10000 {
+			compatible = "mediatek,mt8188-mdp3-hdr", "mediatek,mt8195-mdp3-hdr";
+			reg = <0 0x14f10000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_HDR>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0 0x1000>;
+		};
+
+		display at 14f12000 {
+			compatible = "mediatek,mt8188-mdp3-aal", "mediatek,mt8195-mdp3-aal";
+			reg = <0 0x14f12000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_AAL>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x2000 0x1000>;
+		};
+
+		display at 14f13000 {
+			compatible = "mediatek,mt8188-mdp3-aal", "mediatek,mt8195-mdp3-aal";
+			reg = <0 0x14f13000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_AAL>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x3000 0x1000>;
+		};
+
+		display at 14f15000 {
+			compatible = "mediatek,mt8188-mdp3-rsz", "mediatek,mt8183-mdp3-rsz";
+			reg = <0 0x14f15000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_RSZ>,
+				 <&vppsys1 CLK_VPP1_SVPP2_VPP_MERGE>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x5000 0x1000>;
+		};
+
+		display at 14f16000 {
+			compatible = "mediatek,mt8188-mdp3-rsz", "mediatek,mt8183-mdp3-rsz";
+			reg = <0 0x14f16000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_RSZ>,
+				 <&vppsys1 CLK_VPP1_SVPP3_VPP_MERGE>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x6000 0x1000>;
+		};
+
+		display at 14f18000 {
+			compatible = "mediatek,mt8188-mdp3-tdshp", "mediatek,mt8195-mdp3-tdshp";
+			reg = <0 0x14f18000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_TDSHP>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x8000 0x1000>;
+		};
+
+		display at 14f19000 {
+			compatible = "mediatek,mt8188-mdp3-tdshp", "mediatek,mt8195-mdp3-tdshp";
+			reg = <0 0x14f19000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_TDSHP>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x9000 0x1000>;
+		};
+
+		display at 14f1a000 {
+			compatible = "mediatek,mt8188-mdp3-merge", "mediatek,mt8195-mdp3-merge";
+			reg = <0 0x14f1a000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_VPP_MERGE>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xa000 0x1000>;
+		};
+
+		display at 14f1b000 {
+			compatible = "mediatek,mt8188-mdp3-merge", "mediatek,mt8195-mdp3-merge";
+			reg = <0 0x14f1b000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_VPP_MERGE>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xb000 0x1000>;
+		};
+
+		display at 14f1d000 {
+			compatible = "mediatek,mt8188-mdp3-color", "mediatek,mt8195-mdp3-color";
+			reg = <0 0x14f1d000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_COLOR>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xd000 0x1000>;
+		};
+
+		display at 14f1e000 {
+			compatible = "mediatek,mt8188-mdp3-color", "mediatek,mt8195-mdp3-color";
+			reg = <0 0x14f1e000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_COLOR>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xe000 0x1000>;
+		};
+
+		display at 14f21000 {
+			compatible = "mediatek,mt8188-mdp3-padding",
+				     "mediatek,mt8195-mdp3-padding";
+			reg = <0 0x14f21000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_VPP_PAD>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0x1000 0x1000>;
+		};
+
+		display at 14f22000 {
+			compatible = "mediatek,mt8188-mdp3-padding",
+				     "mediatek,mt8195-mdp3-padding";
+			reg = <0 0x14f22000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_VPP_PAD>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0x2000 0x1000>;
+		};
+
+		display at 14f24000 {
+			compatible = "mediatek,mt8188-mdp3-wrot", "mediatek,mt8183-mdp3-wrot";
+			reg = <0 0x14f24000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_WROT>;
+			iommus = <&vdo_iommu M4U_PORT_L5_SVPP2_MDP_WROT>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0x4000 0x1000>;
+			mediatek,gce-events = <CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_SOF>,
+					      <CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_FRAME_DONE>;
+		};
+
+		display at 14f25000 {
+			compatible = "mediatek,mt8188-mdp3-wrot", "mediatek,mt8183-mdp3-wrot";
+			reg = <0 0x14f25000 0 0x1000>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_WROT>;
+			iommus = <&vpp_iommu M4U_PORT_L6_SVPP3_MDP_WROT>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0x5000 0x1000>;
+			mediatek,gce-events = <CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_SOF>,
+					      <CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_FRAME_DONE>;
+		};
+
 		wpesys: clock-controller at 14e00000 {
 			compatible = "mediatek,mt8188-wpesys";
 			reg = <0 0x14e00000 0 0x1000>;
@@ -2224,6 +2528,15 @@ vppsys1: syscon at 14f00000 {
 			#clock-cells = <1>;
 		};
 
+		mutex at 14f01000 {
+			compatible = "mediatek,mt8188-vpp-mutex";
+			reg = <0 0x14f01000 0 0x1000>;
+			interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_DISP_MUTEX>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VPPSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0x1000 0x1000>;
+		};
+
 		larb5: smi at 14f02000 {
 			compatible = "mediatek,mt8188-smi-larb";
 			reg = <0 0x14f02000 0 0x1000>;
-- 
2.46.1



From angelogioacchino.delregno at collabora.com  Wed Dec 18 02:53:56 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:53:56 +0100
Subject: [PATCH] arm64: dts: mediatek: mt8188: Add VDO0's DSC and MERGE block nodes
Message-ID: <20241218105356.39111-1-angelogioacchino.delregno@collabora.com>

Add nodes for the DSC0 and MERGE0 blocks, located in VDOSYS0 and
necessary to add support for Display Stream Compression with a
display pipeline that looks like:

    [other components] -> DSC0 -> MERGE0 -> Display Interface

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8188.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index 137bd39808ea..6ef385072c9f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -26,9 +26,11 @@ / {
 	aliases {
 		dp-intf0 = &dp_intf0;
 		dp-intf1 = &dp_intf1;
+		dsc0 = &dsc0;
 		ethdr0 = &ethdr0;
 		gce0 = &gce0;
 		gce1 = &gce1;
+		merge0 = &merge0;
 		merge1 = &merge1;
 		merge2 = &merge2;
 		merge3 = &merge3;
@@ -2880,6 +2882,15 @@ disp_dsi0: dsi at 1c008000 {
 			status = "disabled";
 		};
 
+		dsc0: dsc at 1c009000 {
+			compatible = "mediatek,mt8188-disp-dsc", "mediatek,mt8195-disp-dsc";
+			reg = <0 0x1c009000 0 0x1000>;
+			clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+			interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VDOSYS0>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c00XXXX 0x9000 0x1000>;
+		};
+
 		disp_dsi1: dsi at 1c012000 {
 			compatible = "mediatek,mt8188-dsi";
 			reg = <0 0x1c012000 0 0x1000>;
@@ -2895,6 +2906,17 @@ disp_dsi1: dsi at 1c012000 {
 			status = "disabled";
 		};
 
+		merge0: merge0 at 1c014000 {
+			compatible = "mediatek,mt8188-disp-merge", "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c014000 0 0x1000>;
+			clocks = <&vdosys0 CLK_VDO0_VPP_MERGE0>,
+				 <&vdosys1 CLK_VDO1_MERGE_VDO1_DL_ASYNC>;
+			clock-names = "merge", "merge_async";
+			interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8188_POWER_DOMAIN_VDOSYS0>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0x4000 0x1000>;
+		};
+
 		dp_intf0: dp-intf at 1c015000 {
 			compatible = "mediatek,mt8188-dp-intf";
 			reg = <0 0x1c015000 0 0x1000>;
-- 
2.46.1



From angelogioacchino.delregno at collabora.com  Wed Dec 18 02:54:09 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 11:54:09 +0100
Subject: [PATCH] arm64: dts: mediatek: mt8188: Add tertiary eMMC/SD/SDIO controller
Message-ID: <20241218105409.39165-1-angelogioacchino.delregno@collabora.com>

Add a node for the third instance of the eMMC/SD/SDIO controller
found on the MT8188 SoC and keep it disabled.

It is expected that only boards that are using this controller
instance will configure and enable it.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8188.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index 6ef385072c9f..f2d71da50ea3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -1794,6 +1794,20 @@ mmc1: mmc at 11240000 {
 			status = "disabled";
 		};
 
+		mmc2: mmc at 11250000 {
+			compatible = "mediatek,mt8188-mmc", "mediatek,mt8183-mmc";
+			reg = <0 0x11250000 0 0x1000>,
+			      <0 0x11e60000 0 0x1000>;
+			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC30_2>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC2>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC30_2>;
+			clock-names = "source", "hclk", "source_cg";
+			assigned-clocks = <&topckgen CLK_TOP_MSDC30_2>;
+			assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+			status = "disabled";
+		};
+
 		lvts_mcu: thermal-sensor at 11278000 {
 			compatible = "mediatek,mt8188-lvts-mcu";
 			reg = <0 0x11278000 0 0x1000>;
-- 
2.46.1



From mike.leach at linaro.org  Wed Dec 18 03:08:52 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Wed, 18 Dec 2024 11:08:52 +0000
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <20241217063324.33781-3-quic_jinlmao@quicinc.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com> <20241217063324.33781-3-quic_jinlmao@quicinc.com>
Message-ID: <CAJ9a7VhjZSM-5kSwbF142s4AGdCRvcvmZspAUsQA5cdnHvnGEg@mail.gmail.com>

Hi

On Tue, 17 Dec 2024 at 06:33, Mao Jinlong <quic_jinlmao at quicinc.com> wrote:
>
> For some coresight components like CTI and TPDM, there could be
> numerous of them. From the node name, we can only get the type and
> register address of the component. We can't identify the HW or the
> system the component belongs to. Add label sysfs node support for
> showing the intuitive name of the device.
>
> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
> ---
>  .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
>  .../sysfs-bus-coresight-devices-funnel        |  6 ++++
>  .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
>  drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++++++++++++++++++
>  4 files changed, 50 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> index bf2869c413e7..909670e0451a 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> @@ -239,3 +239,9 @@ Date:               March 2020
>  KernelVersion  5.7
>  Contact:       Mike Leach or Mathieu Poirier
>  Description:   (Write) Clear all channel / trigger programming.
> +
> +What:           /sys/bus/coresight/devices/<cti-name>/label
> +Date:           Dec 2024
> +KernelVersion   6.14
> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> +Description:    (Read) Show hardware context information of device.
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> index d75acda5e1b3..944aad879aeb 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> @@ -10,3 +10,9 @@ Date:         November 2014
>  KernelVersion: 3.19
>  Contact:       Mathieu Poirier <mathieu.poirier at linaro.org>
>  Description:   (RW) Defines input port priority order.
> +
> +What:           /sys/bus/coresight/devices/<memory_map>.funnel/label
> +Date:           Dec 2024
> +KernelVersion   6.14
> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> +Description:    (Read) Show hardware context information of device.
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> index bf710ea6e0ef..309802246398 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -257,3 +257,9 @@ 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 CMB subunit
>                 TPDM.
> +
> +What:           /sys/bus/coresight/devices/<tpdm-name>/label
> +Date:           Dec 2024
> +KernelVersion   6.14
> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> +Description:    (Read) Show hardware context information of device.
> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
> index a01c9e54e2ed..4af40cd7d75a 100644
> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
> @@ -7,6 +7,7 @@
>  #include <linux/device.h>
>  #include <linux/idr.h>
>  #include <linux/kernel.h>
> +#include <linux/property.h>
>
>  #include "coresight-priv.h"
>  #include "coresight-trace-id.h"
> @@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device *dev,
>  }
>  static DEVICE_ATTR_RW(enable_source);
>
> +static ssize_t label_show(struct device *dev,
> +               struct device_attribute *attr, char *buf)
> +{
> +
> +       const char *str;
> +       int ret = 0;
> +
> +       ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
> +       if (ret == 0)
> +               return scnprintf(buf, PAGE_SIZE, "%s\n", str);
> +       else
> +               return ret;
> +}
> +static DEVICE_ATTR_RO(label);
> +
>  static struct attribute *coresight_sink_attrs[] = {
>         &dev_attr_enable_sink.attr,
> +       &dev_attr_label.attr,
>         NULL,
>  };
>  ATTRIBUTE_GROUPS(coresight_sink);
>
>  static struct attribute *coresight_source_attrs[] = {
>         &dev_attr_enable_source.attr,
> +       &dev_attr_label.attr,
>         NULL,
>  };
>  ATTRIBUTE_GROUPS(coresight_source);
>
> +static struct attribute *coresight_link_attrs[] = {
> +       &dev_attr_label.attr,
> +       NULL,
> +};
> +ATTRIBUTE_GROUPS(coresight_link);
> +
> +static struct attribute *coresight_helper_attrs[] = {
> +       &dev_attr_label.attr,
> +       NULL,
> +};
> +ATTRIBUTE_GROUPS(coresight_helper);
> +
>  const struct device_type coresight_dev_type[] = {
>         [CORESIGHT_DEV_TYPE_SINK] = {
>                 .name = "sink",
> @@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
>         },
>         [CORESIGHT_DEV_TYPE_LINK] = {
>                 .name = "link",
> +               .groups = coresight_link_groups,
>         },
>         [CORESIGHT_DEV_TYPE_LINKSINK] = {
>                 .name = "linksink",
> @@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
>         },
>         [CORESIGHT_DEV_TYPE_HELPER] = {
>                 .name = "helper",
> +               .groups = coresight_helper_groups,
>         }
>  };
>  /* Ensure the enum matches the names and groups */
> --
> 2.17.1
>

This is a clean and simple solution to this issue. In this form...

Reviewed-by: Mike Leach <mike.leach at linaro.org>

-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Wed Dec 18 03:09:41 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Wed, 18 Dec 2024 11:09:41 +0000
Subject: [PATCH v6 1/2] dt-bindings: arm: Add label in the coresight components
In-Reply-To: <tida22chffj2znikeotmo52aqnzvmedn3aa7a2coarz2dwjc7w@duw5fby4hexk>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-2-quic_jinlmao@quicinc.com> <tida22chffj2znikeotmo52aqnzvmedn3aa7a2coarz2dwjc7w@duw5fby4hexk>
Message-ID: <CAJ9a7VhR5AX9QD3fHiT_aU5yHShcZFaHLEDDcBJbu2xcRbWGVA@mail.gmail.com>

On Wed, 18 Dec 2024 at 09:21, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On Tue, Dec 17, 2024 at 02:33:23PM +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 label to show hardware context information of each coresight
> > device. There will be a sysfs node label in each device folder.
> >
> > cat /sys/bus/coresight/devices/cti_sys0/label
> >
> > Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>
> Best regards,
> Krzysztof
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From quic_luoj at quicinc.com  Wed Dec 18 03:17:04 2024
From: quic_luoj at quicinc.com (Jie Luo)
Date: Wed, 18 Dec 2024 19:17:04 +0800
Subject: [PATCH v6 5/5] arm64: dts: qcom: Update IPQ9574 xo_board_clk to
 use fixed factor clock
In-Reply-To: <8063460d-18ad-4e54-8232-716bad9d37c3@quicinc.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-5-a5cfe09de485@quicinc.com>
 <0776a26e-56cd-4838-9b52-210ae9a1f281@oss.qualcomm.com>
 <8063460d-18ad-4e54-8232-716bad9d37c3@quicinc.com>
Message-ID: <2456ab36-f48e-4aa3-88e1-aeb7895c9816@quicinc.com>



On 12/13/2024 6:30 PM, Jie Luo wrote:
> 
> 
> On 12/13/2024 2:33 AM, Konrad Dybcio wrote:
>> On 7.11.2024 10:50 AM, Luo Jie wrote:
>>> xo_board_clk is fixed to 24 MHZ, which is routed from WiFi output clock
>>> 48 MHZ (also being the reference clock of CMN PLL) divided 2 by analog
>>> block routing channel.
>>>
>>> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
>>> ---
>>> ? arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 7 ++++++-
>>> ? arch/arm64/boot/dts/qcom/ipq9574.dtsi??????????? | 3 ++-
>>> ? 2 files changed, 8 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/ 
>>> arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>> index 78f6a2e053d5..9a8692377176 100644
>>> --- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>> +++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>> @@ -174,8 +174,13 @@ &ref_48mhz_clk {
>>> ????? clock-mult = <1>;
>>> ? };
>>> +/*
>>> + * The frequency of xo_board_clk is fixed to 24 MHZ, which is routed
>>> + * from WiFi output clock 48 MHZ divided by 2.
>>> + */
>>> ? &xo_board_clk {
>>> -??? clock-frequency = <24000000>;
>>> +??? clock-div = <2>;
>>> +??? clock-mult = <1>;
>>> ? };
>>> ? &xo_clk {
>>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/ 
>>> dts/qcom/ipq9574.dtsi
>>> index 8246a00a3e3e..25aed33e9358 100644
>>> --- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>>> +++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>>> @@ -32,7 +32,8 @@ sleep_clk: sleep-clk {
>>> ????????? };
>>> ????????? xo_board_clk: xo-board-clk {
>>> -??????????? compatible = "fixed-clock";
>>> +??????????? compatible = "fixed-factor-clock";
>>> +??????????? clocks = <&ref_48mhz_clk>;
>>
>> This must be squashed with the previous patch, you can't introduce
>> code and replace it immediately afterwards.
>>
>> Konrad

Hi Konrad,

Looking at this comment again, there may have been some
misunderstanding. We are not introducing xo_board_clk in patch 4 of this
series. xo_board_clk is a pre-existing node.

As part of this additional patch 5, we wanted to address Dmitry's
comment earlier in v5 (reference to comment below), by converting the
xo_board_clk as well to a fixed-factor clock. So it is better to keep
this change as a separate patch in my view. Hope this is OK.

https://lore.kernel.org/linux-arm-msm/CAA8EJpoQO7=v8QWeH8MAgX4uU=m4VJqfC3J5PKyySM2TBcHWiw at mail.gmail.com/

> 
> Ok, I will update the patch series with this patch dislodged, and push
> this single patch in next update. Thanks.
> 
> 



From peter.griffin at linaro.org  Wed Dec 18 03:23:38 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 18 Dec 2024 11:23:38 +0000
Subject: [PATCH v5 1/3] dt-bindings: mailbox: add google,gs101-mbox
In-Reply-To: <wlvvuq2ldv4funye2ylnccq7soyrqkqggg36oimnvmhxbbjvnl@yyy4y5nyruzn>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
 <20241217-acpm-v4-upstream-mbox-v5-1-cd1d3951fe84@linaro.org> <wlvvuq2ldv4funye2ylnccq7soyrqkqggg36oimnvmhxbbjvnl@yyy4y5nyruzn>
Message-ID: <CADrjBPq4mTsvCivBJPmADP3pfUORBV8hGeP5GrTg9YxASJLHXg@mail.gmail.com>

Hi,

On Wed, 18 Dec 2024 at 09:29, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On Tue, Dec 17, 2024 at 09:40:20AM +0000, Tudor Ambarus wrote:
> > +description: |
> > +  The samsung exynos mailbox controller has 16 flag bits for hardware interrupt
>
> If there is going to be any new posting:
>
> The Samsung Exynos mailbox controller, used on Google GS101 SoC, ....
>
> > +  generation and a shared register for passing mailbox messages. When the
> > +  controller is used by the ACPM protocol the shared register is ignored and
> > +  the mailbox controller acts as a doorbell. The controller just raises the
> > +  interrupt to the firmware after the ACPM protocol has written the message to
> > +  SRAM.
> > +
> > +properties:
> > +  compatible:
> > +    const: google,gs101-mbox
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 1
> > +
> > +  clock-names:
> > +    items:
> > +      - const: pclk
> > +
> > +  interrupts:
> > +    description: IRQ line for the RX mailbox.
> > +    maxItems: 1
> > +
> > +  '#mbox-cells':
> > +    description: |
> > +      <&phandle type channel>
> > +      phandle : label name of controller.
> > +      type    : channel type, doorbell or data-transfer.
> > +      channel : channel number.
> > +
> > +      Here is how a client can reference them:
> > +      mboxes = <&ap2apm_mailbox DOORBELL 2>;
> > +      mboxes = <&ap2apm_mailbox DATA 3>;
>
> This ordering assumes there is channel "2" in doorbel and in data, so
> two times "2" and of course the same for all others. If this is
> configuration of one channel, so "2" is either doorbell or data, then
> type should be the last.

My understanding was each channel is either configured for doorbell or
data, but Tudor can confirm. With Krzysztof's feedback addressed:

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>

regards,

Peter.


From christian.bruel at foss.st.com  Wed Dec 18 03:24:21 2024
From: christian.bruel at foss.st.com (Christian Bruel)
Date: Wed, 18 Dec 2024 12:24:21 +0100
Subject: [PATCH v2 2/5] PCI: stm32: Add PCIe host support for STM32MP25
In-Reply-To: <20241218094606.sljdx2w27thc5ahj@thinkpad>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-3-christian.bruel@foss.st.com>
 <20241203145244.trgrobtfmumtiwuc@thinkpad>
 <ced7a55a-d968-497f-abc2-663855882a3f@foss.st.com>
 <20241218094606.sljdx2w27thc5ahj@thinkpad>
Message-ID: <d15cec4e-e06a-47f7-aa8a-744c0829d244@foss.st.com>



On 12/18/24 10:46, Manivannan Sadhasivam wrote:
> On Mon, Dec 16, 2024 at 10:00:27AM +0100, Christian Bruel wrote:
> 
> [...]
> 
>>>
>>>> +		msleep(PCIE_T_RRS_READY_MS);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +static void stm32_pcie_stop_link(struct dw_pcie *pci)
>>>> +{
>>>> +	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
>>>> +
>>>> +	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
>>>> +			   STM32MP25_PCIECR_LTSSM_EN, 0);
>>>> +
>>>> +	/* Assert PERST# */
>>>> +	if (stm32_pcie->perst_gpio)
>>>> +		gpiod_set_value(stm32_pcie->perst_gpio, 1);
>>>
>>> I don't like tying PERST# handling with start/stop link. PERST# should be
>>> handled based on the power/clock state.
>>
>> I don't understand your point: We turn off the PHY in suspend_noirq(), so
>> that seems a logical place to de-assert in resume_noirq after the refclk is
>> ready. PERST# should be kept active until the PHY stablilizes the clock in
>> resume. From the PCIe electromechanical specs, PERST# goes active while the
>> refclk is not stable/
>>
> 
> While your understanding about PERST# is correct, your implementation is not.
> You are toggling PERST# from start/stop link callbacks which are supposed to
> control the LTSSM state only. I don't have issues with toggling PERST# in
> stm32_pcie_{suspend/resume}_noirq().

Ah OK. this function is split now into 2 functional blocks in the 
upcoming version

> 
>>
>>>
>>>> +}
>>>> +
>>>> +static int stm32_pcie_suspend(struct device *dev)
>>>> +{
>>>> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
>>>> +
>>>> +	if (device_may_wakeup(dev) || device_wakeup_path(dev))
>>>> +		enable_irq_wake(stm32_pcie->wake_irq);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int stm32_pcie_resume(struct device *dev)
>>>> +{
>>>> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
>>>> +
>>>> +	if (device_may_wakeup(dev) || device_wakeup_path(dev))
>>>> +		disable_irq_wake(stm32_pcie->wake_irq);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int stm32_pcie_suspend_noirq(struct device *dev)
>>>> +{
>>>> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
>>>> +
>>>> +	stm32_pcie->link_is_up = dw_pcie_link_up(stm32_pcie->pci);
>>>> +
>>>> +	stm32_pcie_stop_link(stm32_pcie->pci);
>>>
>>> I don't understand how endpoint can wakeup the host if PERST# gets asserted.
>>
>> The stm32 PCIe doesn't support L2, we don't expect an in-band beacon for the
>> wakeup. We support wakeup only from sideband WAKE#, that will restart the
>> link from IRQ
>>
> 
> I don't understand how WAKE# is supported without L2. Only in L2 state, endpoint
> will make use of Vaux and it will wakeup the host using either beacon or WAKE#.
> If you don't support L2, then the endpoint will reach L3 (link off) state.

I think this is what happens, my understanding is that the device is 
still powered to get the wakeup event (eg WoL magic packet), triggers 
the PCIe wake_IRQ from the WAKE#.

> 
>>>
>>>> +	clk_disable_unprepare(stm32_pcie->clk);
>>>> +
>>>> +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev))
>>>> +		phy_exit(stm32_pcie->phy);
>>>> +
>>>> +	return pinctrl_pm_select_sleep_state(dev);
>>>> +}
>>>> +
>>>> +static int stm32_pcie_resume_noirq(struct device *dev)
>>>> +{
>>>> +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
>>>> +	struct dw_pcie *pci = stm32_pcie->pci;
>>>> +	struct dw_pcie_rp *pp = &pci->pp;
>>>> +	int ret;
>>>> +
>>>> +	/* init_state must be called first to force clk_req# gpio when no
>>>
>>> CLKREQ#
>>>
>>> Why RC should control CLKREQ#?
>>
>> REFCLK is gated with CLKREQ#, So we cannot access the core
>> without CLKREQ# if no device is present. So force it with a init pinmux
>> the time to init the PHY and the core DBI registers
>>
> 
> Ok. You should add a comment to clarify it in the code as this is not a standard
> behavior.
> 

OK

>>>
>>> Also please use preferred style for multi-line comments:
>>>
>>> 	/*
>>> 	 * ...
>>> 	 */
>>>
>>>> +	 * device is plugged.
>>>> +	 */
>>>> +	if (!IS_ERR(dev->pins->init_state))
>>>> +		ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
>>>> +	else
>>>> +		ret = pinctrl_pm_select_default_state(dev);
>>>> +
>>>> +	if (ret) {
>>>> +		dev_err(dev, "Failed to activate pinctrl pm state: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev)) {
>>>> +		ret = phy_init(stm32_pcie->phy);
>>>> +		if (ret) {
>>>> +			pinctrl_pm_select_default_state(dev);
>>>> +			return ret;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	ret = clk_prepare_enable(stm32_pcie->clk);
>>>> +	if (ret)
>>>> +		goto clk_err;
>>>
>>> Please name the goto labels of their purpose. Like err_phy_exit.
>>
>> OK
>>
>>>
>>>> +
>>>> +	ret = dw_pcie_setup_rc(pp);
>>>> +	if (ret)
>>>> +		goto pcie_err;
>>>
>>> This should be, 'err_disable_clk'.
>>>
>>>> +
>>>> +	if (stm32_pcie->link_is_up) {
>>>
>>> Why do you need this check? You cannot start the link in the absence of an
>>> endpoint?
>>>
>>
>> It is an optimization to avoid unnecessary "dw_pcie_wait_for_link" if no
>> device is present during suspend
>>
> 
> In that case you'll not trigger LTSSM if there was no endpoint connected before
> suspend. What if users connect an endpoint after resume?

Yes, exactly. We don't support hotplug, and plugging a device while the 
system is in stand-by is something that we don't expect. The imx6 
platform does this also.

thanks,

Christian

> 
> - Mani
> 


From liankun.yang at mediatek.com  Wed Dec 18 03:34:07 2024
From: liankun.yang at mediatek.com (Liankun Yang)
Date: Wed, 18 Dec 2024 19:34:07 +0800
Subject: [PATCH v3 1/1] drm/mediatek: Add return value check when reading DPCD
Message-ID: <20241218113448.2992-1-liankun.yang@mediatek.com>

Returns the number of bytes transferred (1) on success.
Check the return value to confirm that AUX communication is successful.

Fixes: f70ac097a2cf ("drm/mediatek: Add MT8195 Embedded DisplayPort driver")

Signed-off-by: Liankun Yang <liankun.yang at mediatek.com>
---
Changes in V3:
- Using drm_dp_read_sink_count() to improve patch.
Per suggestion from the previous thread:
https://patchwork.kernel.org/project/linux-mediatek/patch/20241128030940.25657-1-liankun.yang at mediatek.com/

Changes in V2:
- Modify Fixes in Commit Message.
Per suggestion from the previous thread:
https://patchwork.kernel.org/project/linux-mediatek/patch/20240930092000.5385-1-liankun.yang at mediatek.com/
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 36713c176cfc..b26dad8783be 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -2100,7 +2100,6 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 	enum drm_connector_status ret = connector_status_disconnected;
 	bool enabled = mtk_dp->enabled;
-	u8 sink_count = 0;
 
 	if (!mtk_dp->train_info.cable_plugged_in)
 		return ret;
@@ -2115,8 +2114,8 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
 	 * function, we just need to check the HPD connection to check
 	 * whether we connect to a sink device.
 	 */
-	drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
-	if (DP_GET_SINK_COUNT(sink_count))
+
+	if (drm_dp_read_sink_count(&mtk_dp->aux))
 		ret = connector_status_connected;
 
 	if (!enabled)
-- 
2.45.2



From 0x1207 at gmail.com  Wed Dec 18 03:37:43 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Wed, 18 Dec 2024 19:37:43 +0800
Subject: [PATCH net-next v1] net: stmmac: TSO: Simplify the code flow of
 DMA descriptor allocations
In-Reply-To: <20241213030006.337695-1-0x1207@gmail.com>
References: <20241213030006.337695-1-0x1207@gmail.com>
Message-ID: <20241218193743.0000521f@gmail.com>

On Fri, 13 Dec 2024 11:00:06 +0800, Furong Xu <0x1207 at gmail.com> wrote:

> The DMA AXI address width of DWMAC cores can be configured to
> 32-bit/40-bit/48-bit, then the format of DMA transmit descriptors
> get a little different between 32-bit and 40-bit/48-bit.
> Current driver code checks priv->dma_cap.addr64 to use certain format
> with certain configuration.
> 
> This patch converts the format of DMA transmit descriptors on platforms
> that the DMA AXI address width is configured to 32-bit (as described by
> function comments of stmmac_tso_xmit() in current code) to a more generic
> format (see the updated function comments after this patch) which is
> actually already used on 40-bit/48-bit platforms to provide better
> compatibility and make code flow cleaner.
> 
> Tested and verified on:
> DWMAC CORE 5.10a with 32-bit DMA AXI address width
> DWXGMAC CORE 3.20a with 40-bit DMA AXI address width

One more DWMAC core tested and verified:
DWMAC CORE 5.00a with 32-bit DMA AXI address width



From dmitry.baryshkov at linaro.org  Wed Dec 18 03:36:56 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 18 Dec 2024 13:36:56 +0200
Subject: [PATCH v10 1/4] media: dt-bindings: update clocks for
 sc7280-camss
In-Reply-To: <a1032d53-6f3e-48f6-a2e9-1315bb1a3232@linaro.org>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-2-quic_vikramsa@quicinc.com>
 <02da691b-1f5d-41a6-847c-c7e9b8239919@kernel.org>
 <c14493b0-c9d3-4e1c-9f86-991b4cb25c98@linaro.org>
 <fe28a9bc-82ef-4fef-af50-9d9261ed9b39@kernel.org>
 <a1032d53-6f3e-48f6-a2e9-1315bb1a3232@linaro.org>
Message-ID: <hevfx4sgsatohz4ndgrlidj5kqxaiizmakjqjghlkbmguluzi5@ezxa36uasb32>

On Tue, Dec 17, 2024 at 04:30:37PM +0000, Bryan O'Donoghue wrote:
> On 17/12/2024 16:23, Krzysztof Kozlowski wrote:
> > On 17/12/2024 17:12, Bryan O'Donoghue wrote:
> > > On 17/12/2024 14:10, Krzysztof Kozlowski wrote:
> > > > On 17/12/2024 15:06, Vikram Sharma wrote:
> > > > > This patch change clock names to make it consistent with
> > > > > existing platforms as gcc_cam_hf_axi -> gcc_axi_hf.
> > > > > This also adds gcc_axi_sf and remove gcc_camera_ahb.
> > > > 
> > > > Don't combine ABI changes with some less important things.
> > > > 
> > > > You miss here explanation why doing the ABI change in the first place.
> > > > Without that explanation I find it rather churn. But anyway, reason for
> > > > ABI break and impact should be documented in commit msg.
> > > > 
> > > > > 
> > > > > Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> > > > > ---
> > > > 
> > > > Best regards,
> > > > Krzysztof
> > > 
> > > This change should be fine since we haven't committed and upstream dtsi,
> > > so there's no ABI to break yet.
> > > 
> > > Agree the cover letter should have been explicit in explaining.
> > 
> > So these are recently added bindings (sc7280 is not particularly new)?
> > If so mention in the commit msg that no users are affected because of this.
> > 
> > Best regards,
> > Krzysztof
> 
> Agreed.
> 
> The commit log should make clear that the ABI hasn't been cemented yet.
> 
> 20241217140656.965235-4-quic_vikramsa at quicinc.com <- is still pending

If it hasn't been comitted yet, isn't it better to post a fixed version
rather than committing a version which has known issues?

> 
> ---
> bod

-- 
With best wishes
Dmitry


From krzk at kernel.org  Wed Dec 18 03:37:59 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 12:37:59 +0100
Subject: [PATCH 1/2] dt-bindings: memory-controller: Document rev c.1.5
 compatible
In-Reply-To: <20241217194439.929040-2-florian.fainelli@broadcom.com>
References: <20241217194439.929040-1-florian.fainelli@broadcom.com>
 <20241217194439.929040-2-florian.fainelli@broadcom.com>
Message-ID: <2e33t7ft5ermsfr7c4ympxrn6l5sqdef3wml4hlbnhdupoouwj@gfjpbmowjadi>

On Tue, Dec 17, 2024 at 11:44:38AM -0800, Florian Fainelli wrote:
> Document the revision c.1.5 compatible string that is present on newer
> Broadcom STB memory controllers (74165 and onwards).
> 
> Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
> ---
>  .../bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml       | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
> index 4b072c879b02..99d79ccd1036 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
> +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
> @@ -29,6 +29,7 @@ properties:
>            - brcm,brcmstb-memc-ddr-rev-c.1.2
>            - brcm,brcmstb-memc-ddr-rev-c.1.3
>            - brcm,brcmstb-memc-ddr-rev-c.1.4
> +          - brcm,brcmstb-memc-ddr-rev-c.1.5

You should use v2.1 fallback and drop driver patch. Or explain in
commit briefly why different approach is suitable.

Best regards,
Krzysztof



From manivannan.sadhasivam at linaro.org  Wed Dec 18 03:46:22 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Wed, 18 Dec 2024 17:16:22 +0530
Subject: [PATCH v2 2/5] PCI: stm32: Add PCIe host support for STM32MP25
In-Reply-To: <d15cec4e-e06a-47f7-aa8a-744c0829d244@foss.st.com>
References: <20241126155119.1574564-1-christian.bruel@foss.st.com>
 <20241126155119.1574564-3-christian.bruel@foss.st.com>
 <20241203145244.trgrobtfmumtiwuc@thinkpad>
 <ced7a55a-d968-497f-abc2-663855882a3f@foss.st.com>
 <20241218094606.sljdx2w27thc5ahj@thinkpad>
 <d15cec4e-e06a-47f7-aa8a-744c0829d244@foss.st.com>
Message-ID: <20241218114622.3fgdooag6hwlmipr@thinkpad>

On Wed, Dec 18, 2024 at 12:24:21PM +0100, Christian Bruel wrote:

[...]

> > > > > +static int stm32_pcie_suspend_noirq(struct device *dev)
> > > > > +{
> > > > > +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> > > > > +
> > > > > +	stm32_pcie->link_is_up = dw_pcie_link_up(stm32_pcie->pci);
> > > > > +
> > > > > +	stm32_pcie_stop_link(stm32_pcie->pci);
> > > > 
> > > > I don't understand how endpoint can wakeup the host if PERST# gets asserted.
> > > 
> > > The stm32 PCIe doesn't support L2, we don't expect an in-band beacon for the
> > > wakeup. We support wakeup only from sideband WAKE#, that will restart the
> > > link from IRQ
> > > 
> > 
> > I don't understand how WAKE# is supported without L2. Only in L2 state, endpoint
> > will make use of Vaux and it will wakeup the host using either beacon or WAKE#.
> > If you don't support L2, then the endpoint will reach L3 (link off) state.
> 
> I think this is what happens, my understanding is that the device is still
> powered to get the wakeup event (eg WoL magic packet), triggers the PCIe
> wake_IRQ from the WAKE#.
> 

Honestly, I still cannot understand how this can happen.

> > 
> > > > 
> > > > > +	clk_disable_unprepare(stm32_pcie->clk);
> > > > > +
> > > > > +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev))
> > > > > +		phy_exit(stm32_pcie->phy);
> > > > > +
> > > > > +	return pinctrl_pm_select_sleep_state(dev);
> > > > > +}
> > > > > +
> > > > > +static int stm32_pcie_resume_noirq(struct device *dev)
> > > > > +{
> > > > > +	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
> > > > > +	struct dw_pcie *pci = stm32_pcie->pci;
> > > > > +	struct dw_pcie_rp *pp = &pci->pp;
> > > > > +	int ret;
> > > > > +
> > > > > +	/* init_state must be called first to force clk_req# gpio when no
> > > > 
> > > > CLKREQ#
> > > > 
> > > > Why RC should control CLKREQ#?
> > > 
> > > REFCLK is gated with CLKREQ#, So we cannot access the core
> > > without CLKREQ# if no device is present. So force it with a init pinmux
> > > the time to init the PHY and the core DBI registers
> > > 
> > 
> > Ok. You should add a comment to clarify it in the code as this is not a standard
> > behavior.
> > 
> 
> OK
> 
> > > > 
> > > > Also please use preferred style for multi-line comments:
> > > > 
> > > > 	/*
> > > > 	 * ...
> > > > 	 */
> > > > 
> > > > > +	 * device is plugged.
> > > > > +	 */
> > > > > +	if (!IS_ERR(dev->pins->init_state))
> > > > > +		ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
> > > > > +	else
> > > > > +		ret = pinctrl_pm_select_default_state(dev);
> > > > > +
> > > > > +	if (ret) {
> > > > > +		dev_err(dev, "Failed to activate pinctrl pm state: %d\n", ret);
> > > > > +		return ret;
> > > > > +	}
> > > > > +
> > > > > +	if (!device_may_wakeup(dev) && !device_wakeup_path(dev)) {
> > > > > +		ret = phy_init(stm32_pcie->phy);
> > > > > +		if (ret) {
> > > > > +			pinctrl_pm_select_default_state(dev);
> > > > > +			return ret;
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	ret = clk_prepare_enable(stm32_pcie->clk);
> > > > > +	if (ret)
> > > > > +		goto clk_err;
> > > > 
> > > > Please name the goto labels of their purpose. Like err_phy_exit.
> > > 
> > > OK
> > > 
> > > > 
> > > > > +
> > > > > +	ret = dw_pcie_setup_rc(pp);
> > > > > +	if (ret)
> > > > > +		goto pcie_err;
> > > > 
> > > > This should be, 'err_disable_clk'.
> > > > 
> > > > > +
> > > > > +	if (stm32_pcie->link_is_up) {
> > > > 
> > > > Why do you need this check? You cannot start the link in the absence of an
> > > > endpoint?
> > > > 
> > > 
> > > It is an optimization to avoid unnecessary "dw_pcie_wait_for_link" if no
> > > device is present during suspend
> > > 
> > 
> > In that case you'll not trigger LTSSM if there was no endpoint connected before
> > suspend. What if users connect an endpoint after resume?
> 
> Yes, exactly. We don't support hotplug, and plugging a device while the
> system is in stand-by is something that we don't expect. The imx6 platform
> does this also.
> 

You should reconsider this approach. You'll never know how the OEMs are going to
use the PCIe slot. And lack of standard hotplug is not preventing users from
doing hotplug (they could try to do rescan themselves etc...)

- Mani

-- 
????????? ????????


From a0987203069 at gmail.com  Wed Dec 18 03:44:39 2024
From: a0987203069 at gmail.com (Joey Lu)
Date: Wed, 18 Dec 2024 19:44:39 +0800
Subject: [PATCH v5 0/3] Add support for Nuvoton MA35D1 GMAC
Message-ID: <20241218114442.137884-1-a0987203069@gmail.com>

This patch series is submitted to add GMAC support for Nuvoton MA35D1
SoC platform. This work involves implementing a GMAC driver glue layer
based on Synopsys DWMAC driver framework to leverage MA35D1's dual GMAC
interface capabilities.

Overview:
  1. Added a GMAC driver glue layer for MA35D1 SoC, providing support for
  the platform's two GMAC interfaces.
  2. Added device tree settings, with specific configurations for our
  development boards:
    a. SOM board: Configured for two RGMII interfaces.
    b. IoT board: Configured with one RGMII and one RMII interface.
  3. Added dt-bindings for the GMAC interfaces.

v5:
  - Update nuvoton,ma35d1-dwmac.yaml
    - Remove the properties already defined in snps,dwmac.yaml.
  - Update dwmac-nuvoton driver
    - Add a comment to explain the override of PMT flag.

v4:
  - Update nuvoton,ma35d1-dwmac.yaml
    - Remove unnecessary property 'select'.
    - Remove unnecessary compatible entries and fix items.
    - Specify number of entries for 'reg'.
    - Remove already defined property 'phy-handle'.
    - Update example.
    - Modify the property internal path delay to match the driver.
  - Update dtsi
    - Move 'status' to be the last property.
  - Update dwmac-nuvoton driver
    - Use .remove instead of .remove_new.
    - Use dev_err_probe instead.

v3:
  - Update nuvoton,ma35d1-dwmac.yaml
    - Fix for dt_binding_check warnings/errors.
    - Add compatible in snps,dwmac.yaml.
  - Update dtsi
    - Update dtsi to follow examples in yaml.
  - Update dwmac-nuvoton driver
    - Fix for auto build test warnings.
    - Invalid path delay arguments will be returned.

v2:
  - Update nuvoton,ma35d1-dwmac.yaml
    - Rename file to align with the compatible property.
    - Add an argument to syscon to replace mac-id,
      with corresponding descriptions.
    - Use tx-internal-delay-ps and rx-internal-delay-ps properties for
      configurable path delay with corresponding descriptions,
      allowing selection between GMAC internal and PHY.
    - Add all supported phy-mode options.
    - Remove unused properties.
  - Update dtsi
    - Modify syscon configuration to include an argument for
      GMAC interface selection.
  - Update dwmac-nuvoton driver
    - Remove redundant device information print statements.
    - Remove non-global parameters.
    - Retrieve GMAC interface selection from the syscon argument.
    - Parse Tx and Rx path delays by correct properties.
    - Update configurations to support Wake-on-LAN.

Joey Lu (3):
  dt-bindings: net: nuvoton: Add schema for Nuvoton MA35 family GMAC
  arm64: dts: nuvoton: Add Ethernet nodes
  net: stmmac: dwmac-nuvoton: Add dwmac glue for Nuvoton MA35 family

 .../bindings/net/nuvoton,ma35d1-dwmac.yaml    | 126 ++++++++++++
 .../devicetree/bindings/net/snps,dwmac.yaml   |   1 +
 .../boot/dts/nuvoton/ma35d1-iot-512m.dts      |  12 ++
 .../boot/dts/nuvoton/ma35d1-som-256m.dts      |  10 +
 arch/arm64/boot/dts/nuvoton/ma35d1.dtsi       |  54 ++++++
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../ethernet/stmicro/stmmac/dwmac-nuvoton.c   | 182 ++++++++++++++++++
 8 files changed, 397 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c

-- 
2.34.1



From a0987203069 at gmail.com  Wed Dec 18 03:44:40 2024
From: a0987203069 at gmail.com (Joey Lu)
Date: Wed, 18 Dec 2024 19:44:40 +0800
Subject: [PATCH v5 1/3] dt-bindings: net: nuvoton: Add schema for Nuvoton MA35 family GMAC
In-Reply-To: <20241218114442.137884-1-a0987203069@gmail.com>
References: <20241218114442.137884-1-a0987203069@gmail.com>
Message-ID: <20241218114442.137884-2-a0987203069@gmail.com>

Create initial schema for Nuvoton MA35 family Gigabit MAC.

Signed-off-by: Joey Lu <a0987203069 at gmail.com>
---
 .../bindings/net/nuvoton,ma35d1-dwmac.yaml    | 126 ++++++++++++++++++
 .../devicetree/bindings/net/snps,dwmac.yaml   |   1 +
 2 files changed, 127 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml

diff --git a/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml b/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
new file mode 100644
index 000000000000..c3f2ad423cc0
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/nuvoton,ma35d1-dwmac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton DWMAC glue layer controller
+
+maintainers:
+  - Joey Lu <yclu4 at nuvoton.com>
+
+description:
+  Nuvoton 10/100/1000Mbps Gigabit Ethernet MAC Controller is based on
+  Synopsys DesignWare MAC (version 3.73a).
+
+allOf:
+  - $ref: snps,dwmac.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - nuvoton,ma35d1-dwmac
+
+  reg:
+    maxItems: 1
+    description:
+      Register range should be one of the GMAC interface.
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: MAC clock
+      - description: PTP clock
+
+  clock-names:
+    items:
+      - const: stmmaceth
+      - const: ptp_ref
+
+  nuvoton,sys:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle to access syscon registers.
+          - description: GMAC interface ID.
+            enum:
+              - 0
+              - 1
+    description:
+      A phandle to the syscon with one argument that configures system registers
+      for MA35D1's two GMACs. The argument specifies the GMAC interface ID.
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    items:
+      - const: stmmaceth
+
+  phy-mode:
+    enum:
+      - rmii
+      - rgmii
+      - rgmii-id
+      - rgmii-txid
+      - rgmii-rxid
+
+  tx-internal-delay-ps:
+    default: 0
+    minimum: 0
+    maximum: 2000
+    description:
+      RGMII TX path delay used only when PHY operates in RGMII mode with
+      internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds.
+      Allowed values are from 0 to 2000.
+
+  rx-internal-delay-ps:
+    default: 0
+    minimum: 0
+    maximum: 2000
+    description:
+      RGMII RX path delay used only when PHY operates in RGMII mode with
+      internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds.
+      Allowed values are from 0 to 2000.
+
+required:
+  - clocks
+  - clock-names
+  - nuvoton,sys
+  - resets
+  - reset-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+    #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
+    ethernet at 40120000 {
+        compatible = "nuvoton,ma35d1-dwmac";
+        reg = <0x40120000 0x10000>;
+        interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "macirq";
+        clocks = <&clk EMAC0_GATE>, <&clk EPLL_DIV8>;
+        clock-names = "stmmaceth", "ptp_ref";
+
+        nuvoton,sys = <&sys 0>;
+        resets = <&sys MA35D1_RESET_GMAC0>;
+        reset-names = "stmmaceth";
+
+        phy-mode = "rgmii-id";
+        phy-handle = <&eth_phy0>;
+        mdio {
+            compatible = "snps,dwmac-mdio";
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            ethernet-phy at 0 {
+                reg = <0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index eb1f3ae41ab9..4bf59ab910cc 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -67,6 +67,7 @@ properties:
         - ingenic,x2000-mac
         - loongson,ls2k-dwmac
         - loongson,ls7a-dwmac
+        - nuvoton,ma35d1-dwmac
         - qcom,qcs404-ethqos
         - qcom,sa8775p-ethqos
         - qcom,sc8280xp-ethqos
-- 
2.34.1



From arnd at arndb.de  Wed Dec 18 03:44:30 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 18 Dec 2024 12:44:30 +0100
Subject: [PATCH] drm/mediatek: stop selecting foreign drivers
In-Reply-To: <46f871e3-bb1e-4bee-95f3-2121c6a6eef7@collabora.com>
References: <20241218085837.2670434-1-arnd@kernel.org>
 <46f871e3-bb1e-4bee-95f3-2121c6a6eef7@collabora.com>
Message-ID: <1d8c6f65-5baa-459e-ba34-4e45ca20baf6@app.fastmail.com>

On Wed, Dec 18, 2024, at 11:50, AngeloGioacchino Del Regno wrote:
> Il 18/12/24 09:58, Arnd Bergmann ha scritto:
>> From: Arnd Bergmann <arnd at arndb.de>
>
> The problem is - no PHY no party, it's not going to work without... but 
> I get the
> reasons behind this change.
>
> Are we sure that we can't just add a `depends on PHY_MTK_xxxx` (or extend
> depends on DRM_MEDIATEK && PHY_MTK_xxx)?

Doing this wouldn't cause any problems, but it also doesn't
really help much, you just have to know which devices are
present and enable all their drivers anyway.

We used to just select all drivers from arch/arm/mach-*/Kconfig
on some older platforms, but this was too much of a hassle.

      Arnd


From a0987203069 at gmail.com  Wed Dec 18 03:44:41 2024
From: a0987203069 at gmail.com (Joey Lu)
Date: Wed, 18 Dec 2024 19:44:41 +0800
Subject: [PATCH v5 2/3] arm64: dts: nuvoton: Add Ethernet nodes
In-Reply-To: <20241218114442.137884-1-a0987203069@gmail.com>
References: <20241218114442.137884-1-a0987203069@gmail.com>
Message-ID: <20241218114442.137884-3-a0987203069@gmail.com>

Add GMAC nodes for our MA35D1 development boards:
two RGMII interfaces for SOM board, and one RGMII and one RMII
interface for IoT board.

Signed-off-by: Joey Lu <a0987203069 at gmail.com>
---
 .../boot/dts/nuvoton/ma35d1-iot-512m.dts      | 12 +++++
 .../boot/dts/nuvoton/ma35d1-som-256m.dts      | 10 ++++
 arch/arm64/boot/dts/nuvoton/ma35d1.dtsi       | 54 +++++++++++++++++++
 3 files changed, 76 insertions(+)

diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts b/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
index 9482bec1aa57..5cc712ae92d8 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
@@ -18,6 +18,8 @@ aliases {
 		serial12 = &uart12;
 		serial13 = &uart13;
 		serial14 = &uart14;
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
 	};
 
 	chosen {
@@ -126,3 +128,13 @@ &uart14 {
 	pinctrl-0 = <&pinctrl_uart14>;
 	status = "okay";
 };
+
+&gmac0 {
+	phy-mode = "rgmii-id";
+	status = "okay";
+};
+
+&gmac1 {
+	phy-mode = "rmii";
+	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 f6f20a17e501..1d9ac350a1f1 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
@@ -18,6 +18,8 @@ aliases {
 		serial12 = &uart12;
 		serial14 = &uart14;
 		serial16 = &uart16;
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
 	};
 
 	chosen {
@@ -129,3 +131,11 @@ &uart16 {
 	pinctrl-0 = <&pinctrl_uart16>;
 	status = "okay";
 };
+
+&gmac0 {
+	status = "okay";
+};
+
+&gmac1 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
index e51b98f5bdce..89712e262ee6 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
@@ -379,5 +379,59 @@ uart16: serial at 40880000 {
 			clocks = <&clk UART16_GATE>;
 			status = "disabled";
 		};
+
+		gmac0: ethernet at 40120000 {
+			compatible = "nuvoton,ma35d1-dwmac";
+			reg = <0x0 0x40120000 0x0 0x10000>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+			clocks = <&clk EMAC0_GATE>, <&clk EPLL_DIV8>;
+			clock-names = "stmmaceth", "ptp_ref";
+
+			nuvoton,sys = <&sys 0>;
+			resets = <&sys MA35D1_RESET_GMAC0>;
+			reset-names = "stmmaceth";
+
+			phy-mode = "rgmii-id";
+			phy-handle = <&eth_phy0>;
+			status = "disabled";
+
+			mdio0: mdio {
+				compatible = "snps,dwmac-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				eth_phy0: ethernet-phy at 0 {
+					reg = <0>;
+				};
+			};
+		};
+
+		gmac1: ethernet at 40130000 {
+			compatible = "nuvoton,ma35d1-dwmac";
+			reg = <0x0 0x40130000 0x0 0x10000>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+			clocks = <&clk EMAC1_GATE>, <&clk EPLL_DIV8>;
+			clock-names = "stmmaceth", "ptp_ref";
+
+			nuvoton,sys = <&sys 1>;
+			resets = <&sys MA35D1_RESET_GMAC1>;
+			reset-names = "stmmaceth";
+
+			phy-mode = "rgmii-id";
+			phy-handle = <&eth_phy1>;
+			status = "disabled";
+
+			mdio1: mdio {
+				compatible = "snps,dwmac-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				eth_phy1: ethernet-phy at 1 {
+					reg = <1>;
+				};
+			};
+		};
 	};
 };
-- 
2.34.1



From a0987203069 at gmail.com  Wed Dec 18 03:44:42 2024
From: a0987203069 at gmail.com (Joey Lu)
Date: Wed, 18 Dec 2024 19:44:42 +0800
Subject: [PATCH v5 3/3] net: stmmac: dwmac-nuvoton: Add dwmac glue for Nuvoton MA35 family
In-Reply-To: <20241218114442.137884-1-a0987203069@gmail.com>
References: <20241218114442.137884-1-a0987203069@gmail.com>
Message-ID: <20241218114442.137884-4-a0987203069@gmail.com>

Add support for Gigabit Ethernet on Nuvoton MA35 series using dwmac driver.

Signed-off-by: Joey Lu <a0987203069 at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../ethernet/stmicro/stmmac/dwmac-nuvoton.c   | 182 ++++++++++++++++++
 3 files changed, 194 insertions(+)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 6658536a4e17..c8cbc0ec1311 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -121,6 +121,17 @@ config DWMAC_MESON
 	  the stmmac device driver. This driver is used for Meson6,
 	  Meson8, Meson8b and GXBB SoCs.
 
+config DWMAC_NUVOTON
+	tristate "Nuvoton MA35 dwmac support"
+	default ARCH_MA35
+	depends on OF && (ARCH_MA35 || COMPILE_TEST)
+	select MFD_SYSCON
+	help
+	  Support for Ethernet controller on Nuvoton MA35 series SoC.
+
+	  This selects the Nuvoton MA35 series SoC glue layer support
+	  for the stmmac device driver.
+
 config DWMAC_QCOM_ETHQOS
 	tristate "Qualcomm ETHQOS support"
 	default ARCH_QCOM
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 2389fd261344..9812b824459f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_DWMAC_IPQ806X)	+= dwmac-ipq806x.o
 obj-$(CONFIG_DWMAC_LPC18XX)	+= dwmac-lpc18xx.o
 obj-$(CONFIG_DWMAC_MEDIATEK)	+= dwmac-mediatek.o
 obj-$(CONFIG_DWMAC_MESON)	+= dwmac-meson.o dwmac-meson8b.o
+obj-$(CONFIG_DWMAC_NUVOTON)	+= dwmac-nuvoton.o
 obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-ethqos.o
 obj-$(CONFIG_DWMAC_ROCKCHIP)	+= dwmac-rk.o
 obj-$(CONFIG_DWMAC_RZN1)	+= dwmac-rzn1.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c
new file mode 100644
index 000000000000..c5b8933c1f44
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Nuvoton DWMAC specific glue layer
+ *
+ * Copyright (C) 2024 Nuvoton Technology Corp.
+ *
+ * Author: Joey Lu <yclu4 at nuvoton.com>
+ */
+
+#include <linux/mfd/syscon.h>
+#include <linux/of_device.h>
+#include <linux/of_net.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/stmmac.h>
+
+#include "stmmac.h"
+#include "stmmac_platform.h"
+
+#define REG_SYS_GMAC0MISCR  0x108
+#define REG_SYS_GMAC1MISCR  0x10C
+
+#define MISCR_RMII          BIT(0)
+
+/* 2000ps is mapped to 0 ~ 0xF */
+#define PATH_DELAY_DEC      134
+#define TX_DELAY_OFFSET     16
+#define TX_DELAY_MASK       GENMASK(19, 16)
+#define RX_DELAY_OFFSET     20
+#define RX_DELAY_MASK       GENMASK(23, 20)
+
+struct nvt_priv_data {
+	struct platform_device *pdev;
+	struct regmap *regmap;
+};
+
+static struct nvt_priv_data *
+nuvoton_gmac_setup(struct platform_device *pdev, struct plat_stmmacenet_data *plat)
+{
+	struct device *dev = &pdev->dev;
+	struct nvt_priv_data *bsp_priv;
+	phy_interface_t phy_mode;
+	u32 tx_delay, rx_delay;
+	u32 macid, arg, reg;
+
+	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
+	if (!bsp_priv)
+		return ERR_PTR(-ENOMEM);
+
+	bsp_priv->regmap =
+		syscon_regmap_lookup_by_phandle_args(dev->of_node, "nuvoton,sys", 1, &macid);
+	if (IS_ERR(bsp_priv->regmap)) {
+		dev_err_probe(dev, PTR_ERR(bsp_priv->regmap), "Failed to get sys register\n");
+		return ERR_PTR(-ENODEV);
+	}
+	if (macid > 1) {
+		dev_err_probe(dev, -EINVAL, "Invalid sys arguments\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dev->of_node, "tx-internal-delay-ps", &arg)) {
+		tx_delay = 0; /* Default value is 0 */
+	} else {
+		if (arg <= 2000) {
+			tx_delay = (arg == 2000) ? 0xF : (arg / PATH_DELAY_DEC);
+			dev_dbg(dev, "Set Tx path delay to 0x%x\n", tx_delay);
+		} else {
+			dev_err(dev, "Invalid Tx path delay argument.\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
+	if (of_property_read_u32(dev->of_node, "rx-internal-delay-ps", &arg)) {
+		rx_delay = 0; /* Default value is 0 */
+	} else {
+		if (arg <= 2000) {
+			rx_delay = (arg == 2000) ? 0xF : (arg / PATH_DELAY_DEC);
+			dev_dbg(dev, "Set Rx path delay to 0x%x\n", rx_delay);
+		} else {
+			dev_err(dev, "Invalid Rx path delay argument.\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
+	regmap_read(bsp_priv->regmap,
+		    macid == 0 ? REG_SYS_GMAC0MISCR : REG_SYS_GMAC1MISCR, &reg);
+	reg &= ~(TX_DELAY_MASK | RX_DELAY_MASK);
+
+	if (of_get_phy_mode(pdev->dev.of_node, &phy_mode)) {
+		dev_err(dev, "missing phy mode property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	switch (phy_mode) {
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		reg &= ~MISCR_RMII;
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		reg |= MISCR_RMII;
+		break;
+	default:
+		dev_err(dev, "Unsupported phy-mode (%d)\n", phy_mode);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (!(reg & MISCR_RMII)) {
+		reg |= tx_delay << TX_DELAY_OFFSET;
+		reg |= rx_delay << RX_DELAY_OFFSET;
+	}
+
+	regmap_write(bsp_priv->regmap,
+		     macid == 0 ? REG_SYS_GMAC0MISCR : REG_SYS_GMAC1MISCR, reg);
+
+	bsp_priv->pdev = pdev;
+
+	return bsp_priv;
+}
+
+static int nuvoton_gmac_probe(struct platform_device *pdev)
+{
+	struct plat_stmmacenet_data *plat_dat;
+	struct stmmac_resources stmmac_res;
+	int ret;
+
+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
+	if (ret)
+		return ret;
+
+	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	if (IS_ERR(plat_dat))
+		return PTR_ERR(plat_dat);
+
+	/* Nuvoton DWMAC configs */
+	plat_dat->has_gmac = 1;
+	plat_dat->tx_fifo_size = 2048;
+	plat_dat->rx_fifo_size = 4096;
+	plat_dat->multicast_filter_bins = 0;
+	plat_dat->unicast_filter_entries = 8;
+	plat_dat->flags &= ~STMMAC_FLAG_USE_PHY_WOL;
+
+	plat_dat->bsp_priv = nuvoton_gmac_setup(pdev, plat_dat);
+	if (IS_ERR(plat_dat->bsp_priv)) {
+		ret = PTR_ERR(plat_dat->bsp_priv);
+		return ret;
+	}
+
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		return ret;
+
+	/* The PMT flag is determined by the RWK property.
+	 * However, our hardware is configured to support only MGK.
+	 * This is an override on PMT to enable WoL capability.
+	 */
+	plat_dat->pmt = 1;
+	device_set_wakeup_capable(&pdev->dev, 1);
+
+	return 0;
+}
+
+static const struct of_device_id nuvoton_dwmac_match[] = {
+	{ .compatible = "nuvoton,ma35d1-dwmac"},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, nuvoton_dwmac_match);
+
+static struct platform_driver nuvoton_dwmac_driver = {
+	.probe  = nuvoton_gmac_probe,
+	.remove = stmmac_pltfr_remove,
+	.driver = {
+		.name           = "nuvoton-dwmac",
+		.pm		= &stmmac_pltfr_pm_ops,
+		.of_match_table = nuvoton_dwmac_match,
+	},
+};
+module_platform_driver(nuvoton_dwmac_driver);
+
+MODULE_AUTHOR("Joey Lu <yclu4 at nuvoton.com>");
+MODULE_DESCRIPTION("Nuvoton DWMAC specific glue layer");
+MODULE_LICENSE("GPL v2");
-- 
2.34.1



From tomi.valkeinen at ideasonboard.com  Wed Dec 18 03:49:01 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 18 Dec 2024 13:49:01 +0200
Subject: [PATCH 01/10] drm/fourcc: Add warning for bad bpp
In-Reply-To: <BL1PR12MB596954886CC5E28EC8E735BA9C372@BL1PR12MB5969.namprd12.prod.outlook.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
 <20241204-xilinx-formats-v1-1-0bf2c5147db1@ideasonboard.com>
 <BL1PR12MB596954886CC5E28EC8E735BA9C372@BL1PR12MB5969.namprd12.prod.outlook.com>
Message-ID: <02da12fe-4d94-4a40-86b6-6dad28588843@ideasonboard.com>

Hi Vishal,

On 04/12/2024 18:26, Sagar, Vishal wrote:
> [AMD Official Use Only - AMD Internal Distribution Only]
> 
> Hi Tomi,
> 
> Thanks for the patch.
> 
>> -----Original Message-----
>> From: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>> Sent: Wednesday, December 4, 2024 10:31 AM
>> To: Sagar, Vishal <vishal.sagar at amd.com>; Klymenko, Anatoliy
>> <Anatoliy.Klymenko at amd.com>; Maarten Lankhorst
>> <maarten.lankhorst at linux.intel.com>; Maxime Ripard <mripard at kernel.org>;
>> Thomas Zimmermann <tzimmermann at suse.de>; David Airlie
>> <airlied at gmail.com>; Simona Vetter <simona at ffwll.ch>; Laurent Pinchart
>> <laurent.pinchart at ideasonboard.com>; Simek, Michal <michal.simek at amd.com>
>> Cc: dri-devel at lists.freedesktop.org; linux-kernel at vger.kernel.org; linux-arm-
>> kernel at lists.infradead.org; Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>> Subject: [PATCH 01/10] drm/fourcc: Add warning for bad bpp
>>
>> drm_format_info_bpp() cannot be used for formats which do not have an
>> integer bits-per-pixel. Handle wrong calls by printing a warning and
>> returning 0.
> 
> It would be good to add an example of pixel format that may cause this issue.

Indeed, the description is perhaps a bit lacking. I'll change it to:

drm_format_info_bpp() cannot be used for formats which do not have an
integer bits-per-pixel in a pixel block.

E.g. DRM_FORMAT_XV15's (not yet in upstream) plane 0 has three 10-bit 
pixels (Y components), and two padding bits, in a 4 byte block. That is 
10.666... bits per pixel when considering the whole 4 byte block, which 
is what drm_format_info_bpp() does. Thus a driver that supports such 
formats cannot use drm_format_info_bpp(),

It is a driver bug if this happens, but so handle wrong calls by 
printing a warning and returning 0.

  Tomi

>>
>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>> ---
>>   drivers/gpu/drm/drm_fourcc.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
>> index 193cf8ed7912..e84c4ed6928c 100644
>> --- a/drivers/gpu/drm/drm_fourcc.c
>> +++ b/drivers/gpu/drm/drm_fourcc.c
>> @@ -429,6 +429,13 @@ unsigned int drm_format_info_bpp(const struct
>> drm_format_info *info, int plane)
>>        if (!info || plane < 0 || plane >= info->num_planes)
>>                return 0;
>>
>> +     if (info->char_per_block[plane] * 8 %
>> +         (drm_format_info_block_width(info, plane) *
>> +          drm_format_info_block_height(info, plane))) {
>> +             pr_warn("unable to return an integer bpp\n");
>> +             return 0;
>> +     }
>> +
>>        return info->char_per_block[plane] * 8 /
>>               (drm_format_info_block_width(info, plane) *
>>                drm_format_info_block_height(info, plane));
>>
>> --
>> 2.43.0
> 
> Regards
> Vishal Sagar



From peter.griffin at linaro.org  Wed Dec 18 03:58:47 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 18 Dec 2024 11:58:47 +0000
Subject: [PATCH v5 2/3] mailbox: add Samsung Exynos driver
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-2-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org> <20241217-acpm-v4-upstream-mbox-v5-2-cd1d3951fe84@linaro.org>
Message-ID: <CADrjBPp5M8+3eX75XEVPUO_voVBHP_ZbMXP6YRJbrw0xj8ftRQ@mail.gmail.com>

Hi Tudor,

On Tue, 17 Dec 2024 at 09:40, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> The Samsung Exynos mailbox controller has 16 flag bits for hardware
> interrupt generation and a shared register for passing mailbox messages.
> When the controller is used by the ACPM protocol the shared register is
> ignored and the mailbox controller acts as a doorbell. The controller
> just raises the interrupt to APM after the ACPM protocol has written
> the message to SRAM.
>
> Add support for the Samsung Exynos mailbox controller.
>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>

regards,

Peter

[..]


From tomi.valkeinen at ideasonboard.com  Wed Dec 18 04:03:30 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 18 Dec 2024 14:03:30 +0200
Subject: [PATCH 04/10] drm/fourcc: Add DRM_FORMAT_Y10_LE32
In-Reply-To: <20241204-xilinx-formats-v1-4-0bf2c5147db1@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
 <20241204-xilinx-formats-v1-4-0bf2c5147db1@ideasonboard.com>
Message-ID: <a4949e09-b4f3-4224-80fc-913ab5dace64@ideasonboard.com>

Hi,

On 04/12/2024 11:31, Tomi Valkeinen wrote:
> Add Y10_LE32, a 10 bit greyscale format, with 3 pixels packed into
> 32-bit container.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
>   drivers/gpu/drm/drm_fourcc.c  | 4 ++++
>   include/uapi/drm/drm_fourcc.h | 1 +
>   2 files changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index d721d9fdbe98..6048e0a191dc 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -327,6 +327,10 @@ const struct drm_format_info *__drm_format_info(u32 format)
>   		  .num_planes = 2, .char_per_block = { 4, 8, 0 },
>   		  .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
>   		  .vsub = 1, .is_yuv = true },
> +		{ .format = DRM_FORMAT_Y10_LE32,        .depth = 0,
> +		  .num_planes = 1, .char_per_block =  { 4, 0, 0 },
> +		  .block_w = { 3, 0, 0 }, .block_h = { 1, 0, 0 }, .hsub = 1,
> +		  .vsub = 1, .is_yuv = true },
>   	};
>   
>   	unsigned int i;
> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> index f79ee3b93f09..82f255eb3d1b 100644
> --- a/include/uapi/drm/drm_fourcc.h
> +++ b/include/uapi/drm/drm_fourcc.h
> @@ -408,6 +408,7 @@ extern "C" {
>   /* Greyscale formats */
>   
>   #define DRM_FORMAT_Y8		fourcc_code('G', 'R', 'E', 'Y')  /* 8-bit Y-only */
> +#define DRM_FORMAT_Y10_LE32	fourcc_code('Y', '1', '0', 'P')  /* [31:0] x:Y2:Y1:Y0 2:10:10:10 little endian */

I realized that V4L2 already has "Y10P" fourcc: V4L2_PIX_FMT_Y10P, which 
is MIPI CSI style packed 10-bit format.

While it's not strictly speaking a problem, maybe it's best to try to 
avoid overlapping fourccs. So... "Y04P"? I'm being a bit inventive here 
=). 0 would be for "10". 4 as in 4 bytes. P for packed.

  Tomi



From qperret at google.com  Wed Dec 18 04:06:55 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 12:06:55 +0000
Subject: [PATCH v3 18/18] KVM: arm64: Plumb the pKVM MMU in KVM
In-Reply-To: <86pllqqpzm.wl-maz@kernel.org>
References: <20241216175803.2716565-1-qperret@google.com>
 <20241216175803.2716565-19-qperret@google.com>
 <86ttb2qudi.wl-maz@kernel.org>
 <Z2GLR8KZzJn1YpUu@google.com>
 <86pllqqpzm.wl-maz@kernel.org>
Message-ID: <Z2K63zlpoQz76hnl@google.com>

On Tuesday 17 Dec 2024 at 15:38:21 (+0000), Marc Zyngier wrote:
> On Tue, 17 Dec 2024 14:31:35 +0000,
> Quentin Perret <qperret at google.com> wrote:
> > 
> > On Tuesday 17 Dec 2024 at 14:03:37 (+0000), Marc Zyngier wrote:
> > > My gripe with this is that it makes it much harder to follow what is
> > > happening by using tags (ctags, etags, whatever). I ended up with the
> > > hack below, which is super ugly, but preserves the tagging
> > > functionality for non-pKVM.
> > 
> > Ack.
> > 
> > > I'll scratch my head to find something more elegant...
> > 
> > I find your proposal pretty reasonable -- I had a few different ideas
> > but they were all really over-engineered, so I figured relying on a
> > naming convention was the simplest. And any divergence will be flagged
> > at compile time, so that shouldn't be too hard to maintain looking
> > forward.
> > 
> > The __S2 name isn't massively descriptive though. Maybe KVM_PGT_CALL()
> > or something? Thinking about it, this abstraction doesn't need to be
> > restricted to stage-2 stuff. We could most likely hide the
> > __pkvm_host_{un}share_hyp() logic behind a pkvm_pgtable_hyp_{un}map()
> > implementation in pkvm.c as well...
> 
> Oh, I'm happy with *any* name. I just changed it to make sure any
> missing occurrence would blow up.
> 
> And yes, if we can make that more uniform, I'm all for that.

I had a go at porting the hyp stage-1 code to the same logic and
ended up with the diff below.

It's not completely obvious it is much better than the existing code
TBH. I ended up resorting to odd things like passing a NULL pgt to the
pkvm_pgtable_hyp_*() functions and such. All the mess comes from the
pKVM boot flow, where Linux originally creates the hyp stage-1
page-table, but then frees it after pKVM has initialized and switches to
using hypercalls.

None of this is needed for this series though, so I won't include that
in v4. I'll post it separately once that series lands, and then we can
decide if it's worth it, or if it should be done differently.

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index d116ab4230e8..b35c909f4d0a 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -152,8 +152,7 @@ static __always_inline unsigned long __kern_hyp_va(unsigned long v)
 #include <asm/kvm_pgtable.h>
 #include <asm/stage2_pgtable.h>
 
-int kvm_share_hyp(void *from, void *to);
-void kvm_unshare_hyp(void *from, void *to);
+void remove_hyp_mappings(void *from, void *to);
 int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
 int __create_hyp_mappings(unsigned long start, unsigned long size,
 			  unsigned long phys, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 65f988b6fe0d..db7851459ef3 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -143,6 +143,11 @@ struct pkvm_mapping {
 	u64 pfn;
 };
 
+int pkvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits, struct kvm_pgtable_mm_ops *mm_ops);
+void pkvm_pgtable_hyp_destroy(struct kvm_pgtable *pgt);
+int pkvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
+			 enum kvm_pgtable_prot prot);
+u64 pkvm_pgtable_hyp_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
 int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
 			     struct kvm_pgtable_mm_ops *mm_ops);
 void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 9bcbc7b8ed38..2dada891c199 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -183,7 +183,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 
 	kvm_init_nested(kvm);
 
-	ret = kvm_share_hyp(kvm, kvm + 1);
+	ret = create_hyp_mappings(kvm, kvm + 1, PAGE_HYP);
 	if (ret)
 		return ret;
 
@@ -217,7 +217,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 err_free_cpumask:
 	free_cpumask_var(kvm->arch.supported_cpus);
 err_unshare_kvm:
-	kvm_unshare_hyp(kvm, kvm + 1);
+	remove_hyp_mappings(kvm, kvm + 1);
 	return ret;
 }
 
@@ -268,7 +268,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 	kfree(kvm->arch.sysreg_masks);
 	kvm_destroy_vcpus(kvm);
 
-	kvm_unshare_hyp(kvm, kvm + 1);
+	remove_hyp_mappings(kvm, kvm + 1);
 
 	kvm_arm_teardown_hypercalls(kvm);
 }
@@ -493,7 +493,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 	if (err)
 		return err;
 
-	return kvm_share_hyp(vcpu, vcpu + 1);
+	return create_hyp_mappings(vcpu, vcpu + 1, PAGE_HYP);
 }
 
 void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index ea5484ce1f3b..49acdda3f1d0 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -33,7 +33,7 @@ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
 		return 0;
 
 	/* Make sure the host task fpsimd state is visible to hyp: */
-	ret = kvm_share_hyp(fpsimd, fpsimd + 1);
+	ret = create_hyp_mappings(fpsimd, fpsimd + 1, PAGE_HYP);
 	if (ret)
 		return ret;
 
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 4e6cf4a1a6eb..53e584a5e8d7 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -407,44 +407,20 @@ void __init free_hyp_pgds(void)
 {
 	mutex_lock(&kvm_hyp_pgd_mutex);
 	if (hyp_pgtable) {
-		kvm_pgtable_hyp_destroy(hyp_pgtable);
+		KVM_PGT_CALL(kvm_pgtable_hyp_destroy, hyp_pgtable);
 		kfree(hyp_pgtable);
 		hyp_pgtable = NULL;
 	}
 	mutex_unlock(&kvm_hyp_pgd_mutex);
 }
 
-static bool kvm_host_owns_hyp_mappings(void)
-{
-	if (is_kernel_in_hyp_mode())
-		return false;
-
-	if (static_branch_likely(&kvm_protected_mode_initialized))
-		return false;
-
-	/*
-	 * This can happen at boot time when __create_hyp_mappings() is called
-	 * after the hyp protection has been enabled, but the static key has
-	 * not been flipped yet.
-	 */
-	if (!hyp_pgtable && is_protected_kvm_enabled())
-		return false;
-
-	WARN_ON(!hyp_pgtable);
-
-	return true;
-}
-
 int __create_hyp_mappings(unsigned long start, unsigned long size,
 			  unsigned long phys, enum kvm_pgtable_prot prot)
 {
 	int err;
 
-	if (WARN_ON(!kvm_host_owns_hyp_mappings()))
-		return -EINVAL;
-
 	mutex_lock(&kvm_hyp_pgd_mutex);
-	err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot);
+	err = KVM_PGT_CALL(kvm_pgtable_hyp_map, hyp_pgtable, start, size, phys, prot);
 	mutex_unlock(&kvm_hyp_pgd_mutex);
 
 	return err;
@@ -461,138 +437,18 @@ static phys_addr_t kvm_kaddr_to_phys(void *kaddr)
 	}
 }
 
-struct hyp_shared_pfn {
-	u64 pfn;
-	int count;
-	struct rb_node node;
-};
-
-static DEFINE_MUTEX(hyp_shared_pfns_lock);
-static struct rb_root hyp_shared_pfns = RB_ROOT;
-
-static struct hyp_shared_pfn *find_shared_pfn(u64 pfn, struct rb_node ***node,
-					      struct rb_node **parent)
-{
-	struct hyp_shared_pfn *this;
-
-	*node = &hyp_shared_pfns.rb_node;
-	*parent = NULL;
-	while (**node) {
-		this = container_of(**node, struct hyp_shared_pfn, node);
-		*parent = **node;
-		if (this->pfn < pfn)
-			*node = &((**node)->rb_left);
-		else if (this->pfn > pfn)
-			*node = &((**node)->rb_right);
-		else
-			return this;
-	}
-
-	return NULL;
-}
-
-static int share_pfn_hyp(u64 pfn)
-{
-	struct rb_node **node, *parent;
-	struct hyp_shared_pfn *this;
-	int ret = 0;
-
-	mutex_lock(&hyp_shared_pfns_lock);
-	this = find_shared_pfn(pfn, &node, &parent);
-	if (this) {
-		this->count++;
-		goto unlock;
-	}
-
-	this = kzalloc(sizeof(*this), GFP_KERNEL);
-	if (!this) {
-		ret = -ENOMEM;
-		goto unlock;
-	}
-
-	this->pfn = pfn;
-	this->count = 1;
-	rb_link_node(&this->node, parent, node);
-	rb_insert_color(&this->node, &hyp_shared_pfns);
-	ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp, pfn, 1);
-unlock:
-	mutex_unlock(&hyp_shared_pfns_lock);
-
-	return ret;
-}
-
-static int unshare_pfn_hyp(u64 pfn)
-{
-	struct rb_node **node, *parent;
-	struct hyp_shared_pfn *this;
-	int ret = 0;
-
-	mutex_lock(&hyp_shared_pfns_lock);
-	this = find_shared_pfn(pfn, &node, &parent);
-	if (WARN_ON(!this)) {
-		ret = -ENOENT;
-		goto unlock;
-	}
-
-	this->count--;
-	if (this->count)
-		goto unlock;
-
-	rb_erase(&this->node, &hyp_shared_pfns);
-	kfree(this);
-	ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_hyp, pfn, 1);
-unlock:
-	mutex_unlock(&hyp_shared_pfns_lock);
-
-	return ret;
-}
-
-int kvm_share_hyp(void *from, void *to)
-{
-	phys_addr_t start, end, cur;
-	u64 pfn;
-	int ret;
-
-	if (is_kernel_in_hyp_mode())
-		return 0;
-
-	/*
-	 * The share hcall maps things in the 'fixed-offset' region of the hyp
-	 * VA space, so we can only share physically contiguous data-structures
-	 * for now.
-	 */
-	if (is_vmalloc_or_module_addr(from) || is_vmalloc_or_module_addr(to))
-		return -EINVAL;
-
-	if (kvm_host_owns_hyp_mappings())
-		return create_hyp_mappings(from, to, PAGE_HYP);
-
-	start = ALIGN_DOWN(__pa(from), PAGE_SIZE);
-	end = PAGE_ALIGN(__pa(to));
-	for (cur = start; cur < end; cur += PAGE_SIZE) {
-		pfn = __phys_to_pfn(cur);
-		ret = share_pfn_hyp(pfn);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-void kvm_unshare_hyp(void *from, void *to)
+void remove_hyp_mappings(void *from, void *to)
 {
-	phys_addr_t start, end, cur;
-	u64 pfn;
+	unsigned long start = kern_hyp_va((unsigned long)from);
+	unsigned long end = kern_hyp_va((unsigned long)to);
+	unsigned long size = end - start;
 
-	if (is_kernel_in_hyp_mode() || kvm_host_owns_hyp_mappings() || !from)
+	if (!is_protected_kvm_enabled() || !from)
 		return;
 
-	start = ALIGN_DOWN(__pa(from), PAGE_SIZE);
-	end = PAGE_ALIGN(__pa(to));
-	for (cur = start; cur < end; cur += PAGE_SIZE) {
-		pfn = __phys_to_pfn(cur);
-		WARN_ON(unshare_pfn_hyp(pfn));
-	}
+	mutex_lock(&kvm_hyp_pgd_mutex);
+	WARN_ON(KVM_PGT_CALL(kvm_pgtable_hyp_unmap, hyp_pgtable, start, size) != size);
+	mutex_unlock(&kvm_hyp_pgd_mutex);
 }
 
 /**
@@ -615,9 +471,6 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
 	if (is_kernel_in_hyp_mode())
 		return 0;
 
-	if (!kvm_host_owns_hyp_mappings())
-		return -EPERM;
-
 	start = start & PAGE_MASK;
 	end = PAGE_ALIGN(end);
 
@@ -699,16 +552,6 @@ static int __create_hyp_private_mapping(phys_addr_t phys_addr, size_t size,
 	unsigned long addr;
 	int ret = 0;
 
-	if (!kvm_host_owns_hyp_mappings()) {
-		addr = kvm_call_hyp_nvhe(__pkvm_create_private_mapping,
-					 phys_addr, size, prot);
-		if (IS_ERR_VALUE(addr))
-			return addr;
-		*haddr = addr;
-
-		return 0;
-	}
-
 	size = PAGE_ALIGN(size + offset_in_page(phys_addr));
 	ret = hyp_alloc_private_va_range(size, &addr);
 	if (ret)
@@ -2094,7 +1937,7 @@ int __init kvm_mmu_init(u32 *hyp_va_bits)
 		goto out;
 	}
 
-	err = kvm_pgtable_hyp_init(hyp_pgtable, *hyp_va_bits, &kvm_hyp_mm_ops);
+	err = KVM_PGT_CALL(kvm_pgtable_hyp_init, hyp_pgtable, *hyp_va_bits, &kvm_hyp_mm_ops);
 	if (err)
 		goto out_free_pgtable;
 
@@ -2106,7 +1949,7 @@ int __init kvm_mmu_init(u32 *hyp_va_bits)
 	return 0;
 
 out_destroy_pgtable:
-	kvm_pgtable_hyp_destroy(hyp_pgtable);
+	KVM_PGT_CALL(kvm_pgtable_hyp_destroy, hyp_pgtable);
 out_free_pgtable:
 	kfree(hyp_pgtable);
 	hyp_pgtable = NULL;
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index 64de20e8001d..f5a02b4039b1 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -270,6 +270,124 @@ static int __init finalize_pkvm(void)
 }
 device_initcall_sync(finalize_pkvm);
 
+struct hyp_shared_page {
+	struct rb_node node;
+	phys_addr_t phys;
+	void *hyp_va;
+	int count;
+};
+static struct rb_root hyp_shared_pages = RB_ROOT;
+
+static struct hyp_shared_page *find_shared_page(void *hyp_va, struct rb_node ***node,
+					       struct rb_node **parent)
+{
+	struct hyp_shared_page *page;
+
+	*node = &hyp_shared_pages.rb_node;
+	*parent = NULL;
+	while (**node) {
+		page = container_of(**node, struct hyp_shared_page, node);
+		*parent = **node;
+		if (page->hyp_va < hyp_va)
+			*node = &((**node)->rb_left);
+		else if (page->hyp_va > hyp_va)
+			*node = &((**node)->rb_right);
+		else
+			return page;
+	}
+
+	return NULL;
+}
+
+int pkvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits, struct kvm_pgtable_mm_ops *mm_ops)
+{
+	if (pgt)
+		return kvm_pgtable_hyp_init(pgt, va_bits, mm_ops);
+	return 0;
+}
+
+void pkvm_pgtable_hyp_destroy(struct kvm_pgtable *pgt)
+{
+	if (pgt)
+		return kvm_pgtable_hyp_destroy(pgt);
+}
+
+static int share_page_hyp(void *hyp_va, phys_addr_t phys)
+{
+	struct rb_node **node, *parent;
+	struct hyp_shared_page *page;
+
+	page = find_shared_page(hyp_va, &node, &parent);
+	if (page) {
+		page->count++;
+		return 0;
+	}
+
+	page = kzalloc(sizeof(*page), GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+	page->hyp_va = hyp_va;
+	page->phys = phys;
+	page->count = 1;
+	rb_link_node(&page->node, parent, node);
+	rb_insert_color(&page->node, &hyp_shared_pages);
+
+	return kvm_call_hyp_nvhe(__pkvm_host_share_hyp, phys >> PAGE_SHIFT, 1);
+}
+
+int pkvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
+			 enum kvm_pgtable_prot prot)
+{
+	u64 off;
+	int ret;
+
+	if (pgt)
+		return kvm_pgtable_hyp_map(pgt, addr, size, phys, prot);
+
+	addr = ALIGN_DOWN(addr, PAGE_SIZE);
+	phys = ALIGN_DOWN(phys, PAGE_SIZE);
+	size = PAGE_ALIGN(size);
+	if (addr != (u64)kern_hyp_va(__va(phys)))
+		return -EINVAL;
+	if (prot != PAGE_HYP)
+		return -EPERM;
+
+	for (off = 0; off < size; off += PAGE_SIZE) {
+		ret = share_page_hyp((void *)(addr + off), phys + off);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+u64 pkvm_pgtable_hyp_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	struct rb_node **node, *parent, *next;
+	struct hyp_shared_page *page;
+	u64 pfn, off = 0;
+
+	if (pgt)
+		return kvm_pgtable_hyp_unmap(pgt, addr, size);
+
+	page = find_shared_page((void *)addr, &node, &parent);
+	while (page && ((u64)page->hyp_va == addr + off) && off < size) {
+		next = rb_next(&page->node);
+		page->count--;
+		if (!page->count) {
+			pfn = page->phys >> PAGE_SHIFT;
+			rb_erase(&page->node, &hyp_shared_pages);
+			kfree(page);
+			if (kvm_call_hyp_nvhe(__pkvm_host_unshare_hyp, pfn, 1))
+				break;
+		}
+		off += PAGE_SIZE;
+		page = next ? container_of(next, struct hyp_shared_page, node) : NULL;
+	}
+
+	return off;
+}
+
 static int cmp_mappings(struct rb_node *node, const struct rb_node *parent)
 {
 	struct pkvm_mapping *a = rb_entry(node, struct pkvm_mapping, node);
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 470524b31951..e8b3d08e26dd 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -115,7 +115,7 @@ static int kvm_vcpu_finalize_sve(struct kvm_vcpu *vcpu)
 	if (!buf)
 		return -ENOMEM;
 
-	ret = kvm_share_hyp(buf, buf + reg_sz);
+	ret = create_hyp_mappings(buf, buf + reg_sz, PAGE_HYP);
 	if (ret) {
 		kfree(buf);
 		return ret;
@@ -154,9 +154,9 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
 	void *sve_state = vcpu->arch.sve_state;
 
-	kvm_unshare_hyp(vcpu, vcpu + 1);
+	remove_hyp_mappings(vcpu, vcpu + 1);
 	if (sve_state)
-		kvm_unshare_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
+		remove_hyp_mappings(sve_state, sve_state + vcpu_sve_state_size(vcpu));
 	kfree(sve_state);
 	kfree(vcpu->arch.ccsidr);
 }
-- 
2.47.1.613.gc27f4b7a9f-goog



From eb at emlix.com  Wed Dec 18 04:13:24 2024
From: eb at emlix.com (Rolf Eike Beer)
Date: Wed, 18 Dec 2024 13:13:24 +0100
Subject: [PATCH] arm32: simplify ARM_MMU_KEEP usage
In-Reply-To: <2200295.irdbgypaU6@devpool47.emlix.com>
References: <2200295.irdbgypaU6@devpool47.emlix.com>
Message-ID: <1811814.VLH7GnMWUR@devpool47.emlix.com>

On Montag, 7. Oktober 2024 15:11:40 Mitteleurop?ische Normalzeit Rolf Eike 
Beer wrote:
> All current users need to add a KEEP() around the argument so the value is
> actually kept, which doesn't feel very natural and is prone to upcoming bugs
> as the name suggests that this macro alone already keeps things. Move that
> directly into the definition.
> 
> Signed-off-by: Rolf Eike Beer <eb at emlix.com>
> ---

Ping?

> I'm unsure if ARM_MMU_DISCARD() needs the same treatment for the non-MMU
> case. I suspect noone has tried dead code elimination for non-MMU?
> 
>  arch/arm/include/asm/vmlinux.lds.h | 2 +-
>  arch/arm/kernel/vmlinux-xip.lds.S  | 2 +-
>  arch/arm/kernel/vmlinux.lds.S      | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/include/asm/vmlinux.lds.h
> b/arch/arm/include/asm/vmlinux.lds.h index d60f6e83a9f7..89697f204715
> 100644
> --- a/arch/arm/include/asm/vmlinux.lds.h
> +++ b/arch/arm/include/asm/vmlinux.lds.h
> @@ -19,7 +19,7 @@
>  #endif
> 
>  #ifdef CONFIG_MMU
> -#define ARM_MMU_KEEP(x)		x
> +#define ARM_MMU_KEEP(x)		KEEP(x)
>  #define ARM_MMU_DISCARD(x)
>  #else
>  #define ARM_MMU_KEEP(x)
> diff --git a/arch/arm/kernel/vmlinux-xip.lds.S
> b/arch/arm/kernel/vmlinux-xip.lds.S index 5eddb75a7174..f2e8d4fac068 100644
> --- 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(KEEP(*(__ex_table)))
> +		ARM_MMU_KEEP(*(__ex_table))
>  		__stop___ex_table = .;
>  	}
> 
> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
> index de373c6c2ae8..d592a203f9c6 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(KEEP(*(__ex_table)))
> +		ARM_MMU_KEEP(*(__ex_table))
>  		__stop___ex_table = .;
>  	}


-- 
Rolf Eike Beer

emlix GmbH
Headquarters: Berliner Str. 12, 37073 G?ttingen, Germany
Phone +49 (0)551 30664-0, e-mail info at emlix.com
District Court of G?ttingen, Registry Number HR B 3160
Managing Directors: Heike Jordan, Dr. Uwe Kracke
VAT ID No. DE 205 198 055
Office Berlin: Panoramastr. 1, 10178 Berlin, Germany
Office Bonn: Bachstr. 6, 53115 Bonn, Germany
http://www.emlix.com

emlix - your embedded Linux partner
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 313 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241218/62df7b3d/attachment.sig>

From peter.griffin at linaro.org  Wed Dec 18 04:14:39 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 18 Dec 2024 12:14:39 +0000
Subject: [PATCH 3/4] arm64: dts: exynos: gs101-oriole: move common Pixel6
 & 6Pro parts into a .dtsi
In-Reply-To: <20241216-gs101-simplefb-v1-3-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org> <20241216-gs101-simplefb-v1-3-8ccad1830281@linaro.org>
Message-ID: <CADrjBPqUcsiX5u80ASfWOe17Cwnr6EA0g2bxfgc-e8YpmWkUYg@mail.gmail.com>

Hi Andr?,

On Mon, 16 Dec 2024 at 13:06, Andr? Draszik <andre.draszik at linaro.org> wrote:
>
> In order to support Pixel 6 (Oriole) and Pixel 6 Pro (Raven) properly,
> we have to be able to distinguish them properly as we add support for
> more features.
>
> For example, Raven has a larger display. There are other differences,
> like battery design capacity, etc.
>
> Move all the parts that are common for now into a gs101-raviole.dtsi,
> and just leave the display related things in gs101-oriole.dts.
>
> Raviole was chosen as the name because Google uses that when referring
> to the combination of Oriole & Raven, keeping the familiar terminology.

As discussed off list lets not use the "raviole" terminology (as it
precludes Pixel 6a / Bluejay which is also based on gs101). I think
something like gs101-board-common.dtsi would be better.

Additionally I tested this series on a Pixel 6 Oriole device (with the
latest Yocto initramfs) and the frame-buffer was functional.

With the above comments addressed

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>

regards,

Peter


From peter.griffin at linaro.org  Wed Dec 18 04:15:47 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 18 Dec 2024 12:15:47 +0000
Subject: [PATCH 1/4] dt-bindings: arm: google: add gs101-raven
In-Reply-To: <20241216-gs101-simplefb-v1-1-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org> <20241216-gs101-simplefb-v1-1-8ccad1830281@linaro.org>
Message-ID: <CADrjBPptsP1XeY1Z9ZsPrVKMPn-pgFwaq71e-+2Rjb+4rsnWQg@mail.gmail.com>

Hi Andr?,

On Mon, 16 Dec 2024 at 13:06, Andr? Draszik <andre.draszik at linaro.org> wrote:
>
> Raven is Google's code name for Pixel 6 Pro. Since there are
> differences compared to Pixel 6 (Oriole), we need to add a separate
> compatible for it.
>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>

regards,

Peter


From peter.griffin at linaro.org  Wed Dec 18 04:17:23 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 18 Dec 2024 12:17:23 +0000
Subject: [PATCH 2/4] arm64: dts: exynos: gs101-oriole: configure simple-framebuffer
In-Reply-To: <20241216-gs101-simplefb-v1-2-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org> <20241216-gs101-simplefb-v1-2-8ccad1830281@linaro.org>
Message-ID: <CADrjBPq4hH+kiuObXCkJXf6Ft-zEDnSVM5HuYNd=xMvaLicryg@mail.gmail.com>

Hi Andre

On Mon, 16 Dec 2024 at 13:06, Andr? Draszik <andre.draszik at linaro.org> wrote:
>
> The bootloader configures the display hardware for a framebuffer at the
> given address, let's add a simple-framebuffer node here until we get a
> proper DRM driver.
>
> This has several benefits since it's an OLED display:
> * energy consumption goes down significantly, as it changes from white
>   (as left by bootloader) to black (linux console), and we generally
>   don't run out of battery anymore when plugged into a USB port
> * less of a burn-in effect I assume
> * phone stays cooler due to reduced energy consumption by display
>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>

Tested on Oriole device, with latest initramfs and framebuffer was functional.

regards,

Peter


From bryan.odonoghue at linaro.org  Wed Dec 18 04:17:27 2024
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Wed, 18 Dec 2024 12:17:27 +0000
Subject: [PATCH v10 1/4] media: dt-bindings: update clocks for
 sc7280-camss
In-Reply-To: <hevfx4sgsatohz4ndgrlidj5kqxaiizmakjqjghlkbmguluzi5@ezxa36uasb32>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-2-quic_vikramsa@quicinc.com>
 <02da691b-1f5d-41a6-847c-c7e9b8239919@kernel.org>
 <c14493b0-c9d3-4e1c-9f86-991b4cb25c98@linaro.org>
 <fe28a9bc-82ef-4fef-af50-9d9261ed9b39@kernel.org>
 <a1032d53-6f3e-48f6-a2e9-1315bb1a3232@linaro.org>
 <hevfx4sgsatohz4ndgrlidj5kqxaiizmakjqjghlkbmguluzi5@ezxa36uasb32>
Message-ID: <23ae6fb9-2c66-4d16-83e7-d53c1a6685c2@linaro.org>

On 18/12/2024 11:36, Dmitry Baryshkov wrote:
>> Agreed.
>>
>> The commit log should make clear that the ABI hasn't been cemented yet.
>>
>> 20241217140656.965235-4-quic_vikramsa at quicinc.com <- is still pending
> If it hasn't been comitted yet, isn't it better to post a fixed version
> rather than committing a version which has known issues?

Yes.

- yaml
- driver

are merged but

- dtsi is not

So we can still change yaml and driver prior to fixing dtsi.

---
bod


From bryan.odonoghue at linaro.org  Wed Dec 18 04:18:37 2024
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Wed, 18 Dec 2024 12:18:37 +0000
Subject: [PATCH v10 1/4] media: dt-bindings: update clocks for
 sc7280-camss
In-Reply-To: <23ae6fb9-2c66-4d16-83e7-d53c1a6685c2@linaro.org>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-2-quic_vikramsa@quicinc.com>
 <02da691b-1f5d-41a6-847c-c7e9b8239919@kernel.org>
 <c14493b0-c9d3-4e1c-9f86-991b4cb25c98@linaro.org>
 <fe28a9bc-82ef-4fef-af50-9d9261ed9b39@kernel.org>
 <a1032d53-6f3e-48f6-a2e9-1315bb1a3232@linaro.org>
 <hevfx4sgsatohz4ndgrlidj5kqxaiizmakjqjghlkbmguluzi5@ezxa36uasb32>
 <23ae6fb9-2c66-4d16-83e7-d53c1a6685c2@linaro.org>
Message-ID: <f7bccde8-80d9-4be7-b280-7d171059b4b4@linaro.org>

On 18/12/2024 12:17, Bryan O'Donoghue wrote:
> On 18/12/2024 11:36, Dmitry Baryshkov wrote:
>>> Agreed.
>>>
>>> The commit log should make clear that the ABI hasn't been cemented yet.
>>>
>>> 20241217140656.965235-4-quic_vikramsa at quicinc.com <- is still pending
>> If it hasn't been comitted yet, isn't it better to post a fixed version
>> rather than committing a version which has known issues?
> 
> Yes.
> 
> - yaml
> - driver
> 
> are merged but
> 
> - dtsi is not
> 
> So we can still change yaml and driver prior to fixing dtsi.
> 
> ---
> bod

Excuse me; prior to _committing_ the dtsi


From heiko at sntech.de  Wed Dec 18 04:35:24 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 18 Dec 2024 13:35:24 +0100
Subject: [PATCH v2 04/11] phy: phy-rockchip-samsung-hdptx: Add support for eDP
 mode
In-Reply-To: <20241216031225.3746-5-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-5-damon.ding@rock-chips.com>
Message-ID: <867267676.0ifERbkFSE@diego>

Hi Damon,

Am Montag, 16. Dezember 2024, 04:12:18 CET schrieb Damon Ding:
> Add basic support for RBR/HBR/HBR2 link rates, and the voltage swing and
> pre-emphasis configurations of each link rate have been verified according
> to the eDP 1.3 requirements.
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> 
> ---
> 
> Changes in v2:
> - Add the module author
> ---

> @@ -255,6 +364,19 @@ struct ropll_config {
>  	u8 cd_tx_ser_rate_sel;
>  };
>  
> +struct tx_drv_ctrl {
> +	u8 tx_drv_lvl_ctrl;
> +	u8 tx_drv_post_lvl_ctrl;
> +	u8 ana_tx_drv_idrv_idn_ctrl;
> +	u8 ana_tx_drv_idrv_iup_ctrl;
> +	u8 ana_tx_drv_accdrv_en;
> +	u8 ana_tx_drv_accdrv_ctrl;
> +	u8 tx_drv_pre_lvl_ctrl;
> +	u8 ana_tx_jeq_en;
> +	u8 tx_jeq_even_ctrl;
> +	u8 tx_jeq_odd_ctrl;
> +};
> +
>  enum rk_hdptx_reset {
>  	RST_PHY = 0,
>  	RST_APB,

not a full review (yet), but this part conflicts with
commit f2dbca169790 ("phy: phy-rockchip-samsung-hdptx: Don't request RST_PHY/RST_ROPLL/RST_LCPLL")

[0] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=f2dbca169790ea1e436ffdd9ef37d7c3a4401c46




From krzk at kernel.org  Wed Dec 18 04:36:53 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 18 Dec 2024 13:36:53 +0100
Subject: [PATCH 3/4] arm64: dts: exynos: gs101-oriole: move common Pixel6
 & 6Pro parts into a .dtsi
In-Reply-To: <CADrjBPqUcsiX5u80ASfWOe17Cwnr6EA0g2bxfgc-e8YpmWkUYg@mail.gmail.com>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
 <20241216-gs101-simplefb-v1-3-8ccad1830281@linaro.org>
 <CADrjBPqUcsiX5u80ASfWOe17Cwnr6EA0g2bxfgc-e8YpmWkUYg@mail.gmail.com>
Message-ID: <8e2a0c11-65f6-4cd9-9b75-5a5f6464fa92@kernel.org>

On 18/12/2024 13:14, Peter Griffin wrote:
> Hi Andr?,
> 
> On Mon, 16 Dec 2024 at 13:06, Andr? Draszik <andre.draszik at linaro.org> wrote:
>>
>> In order to support Pixel 6 (Oriole) and Pixel 6 Pro (Raven) properly,
>> we have to be able to distinguish them properly as we add support for
>> more features.
>>
>> For example, Raven has a larger display. There are other differences,
>> like battery design capacity, etc.
>>
>> Move all the parts that are common for now into a gs101-raviole.dtsi,
>> and just leave the display related things in gs101-oriole.dts.
>>
>> Raviole was chosen as the name because Google uses that when referring
>> to the combination of Oriole & Raven, keeping the familiar terminology.
> 
> As discussed off list lets not use the "raviole" terminology (as it
> precludes Pixel 6a / Bluejay which is also based on gs101). I think
> something like gs101-board-common.dtsi would be better.


gs101 is a SoC not a phone and you need here something common for
boards. Choose whatever name you like, but there should be a name (so
gs101-foo-common).


Best regards,
Krzysztof


From tudor.ambarus at linaro.org  Wed Dec 18 04:39:07 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed, 18 Dec 2024 12:39:07 +0000
Subject: [PATCH v5 1/3] dt-bindings: mailbox: add google,gs101-mbox
In-Reply-To: <CADrjBPq4mTsvCivBJPmADP3pfUORBV8hGeP5GrTg9YxASJLHXg@mail.gmail.com>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
 <20241217-acpm-v4-upstream-mbox-v5-1-cd1d3951fe84@linaro.org>
 <wlvvuq2ldv4funye2ylnccq7soyrqkqggg36oimnvmhxbbjvnl@yyy4y5nyruzn>
 <CADrjBPq4mTsvCivBJPmADP3pfUORBV8hGeP5GrTg9YxASJLHXg@mail.gmail.com>
Message-ID: <878f75cb-e85a-44d3-aae8-22ede6e7afde@linaro.org>



On 12/18/24 11:23 AM, Peter Griffin wrote:
> Hi,
> 
> On Wed, 18 Dec 2024 at 09:29, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>>
>> On Tue, Dec 17, 2024 at 09:40:20AM +0000, Tudor Ambarus wrote:
>>> +description: |
>>> +  The samsung exynos mailbox controller has 16 flag bits for hardware interrupt
>>
>> If there is going to be any new posting:
>>
>> The Samsung Exynos mailbox controller, used on Google GS101 SoC, ....
>>
>>> +  generation and a shared register for passing mailbox messages. When the
>>> +  controller is used by the ACPM protocol the shared register is ignored and
>>> +  the mailbox controller acts as a doorbell. The controller just raises the
>>> +  interrupt to the firmware after the ACPM protocol has written the message to
>>> +  SRAM.
>>> +
>>> +properties:
>>> +  compatible:
>>> +    const: google,gs101-mbox
>>> +
>>> +  reg:
>>> +    maxItems: 1
>>> +
>>> +  clocks:
>>> +    maxItems: 1
>>> +
>>> +  clock-names:
>>> +    items:
>>> +      - const: pclk
>>> +
>>> +  interrupts:
>>> +    description: IRQ line for the RX mailbox.
>>> +    maxItems: 1
>>> +
>>> +  '#mbox-cells':
>>> +    description: |
>>> +      <&phandle type channel>
>>> +      phandle : label name of controller.
>>> +      type    : channel type, doorbell or data-transfer.
>>> +      channel : channel number.
>>> +
>>> +      Here is how a client can reference them:
>>> +      mboxes = <&ap2apm_mailbox DOORBELL 2>;
>>> +      mboxes = <&ap2apm_mailbox DATA 3>;
>>
>> This ordering assumes there is channel "2" in doorbel and in data, so
>> two times "2" and of course the same for all others. If this is
>> configuration of one channel, so "2" is either doorbell or data, then
>> type should be the last.

ha, nice observation!

> My understanding was each channel is either configured for doorbell or
> data, but Tudor can confirm. With Krzysztof's feedback addressed:

For the ACPM interface use case, mailbox is always used as a doorbell
indeed. Regardless if the ACPM interface writes data or not to SRAM, it
will use the mailbox controller just to flip the interrupt bit without
touching the mbox controller data registers.

For the other cases where the mailbox controller is used to (also?) pass
data via its data registers, I can't tell whether the passing of data is
mandatory or not. At least not by reading the gs101 mailbox datasheet
that I have, it doesn't describe the SR registers. However, Exynos850 -
which has the same registers, says that:
```CPU cores can use these registers for sharing data```.
"Can" implies that writing to SR is optional.

So I assume a channel can work in both modes and clients use mboxes to
specify which mode to use. Shall I still switch the order?

Thanks,
ta


From sebastian.fricke at collabora.com  Wed Dec 18 04:45:05 2024
From: sebastian.fricke at collabora.com (Sebastian Fricke)
Date: Wed, 18 Dec 2024 13:45:05 +0100
Subject: [PATCH] media: mediatek: vcodec: mark
 vdec_vp9_slice_map_counts_eob_coef noinline
In-Reply-To: <20241217174628.GA2654633@ax162>
References: <20241018151448.3694052-1-arnd@kernel.org>
 <20241118200641.GA768549@thelio-3990X>
 <20241119110226.dbd54clp46klvjl5@basti-XPS-13-9310>
 <20241217174628.GA2654633@ax162>
Message-ID: <20241218124505.xwgsnpi2rvbngqvs@basti-XPS-13-9310>

Hey Nathan,

On 17.12.2024 10:46, Nathan Chancellor wrote:
>Hi Sebastian,
>
>On Tue, Nov 19, 2024 at 12:02:26PM +0100, Sebastian Fricke wrote:
>> Hey Nathan,
>>
>> On 18.11.2024 13:06, Nathan Chancellor wrote:
>> > On Fri, Oct 18, 2024 at 03:14:42PM +0000, Arnd Bergmann wrote:
>> > > From: Arnd Bergmann <arnd at arndb.de>
>> > >
>> > > With KASAN enabled, clang fails to optimize the inline version of
>> > > vdec_vp9_slice_map_counts_eob_coef() properly, leading to kilobytes
>> > > of temporary values spilled to the stack:
>> > >
>> > > drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c:1526:12: error: stack frame size (2160) exceeds limit (2048) in 'vdec_vp9_slice_update_prob' [-Werror,-Wframe-larger-than]
>> > >
>> > > This seems to affect all versions of clang including the latest (clang-20),
>> > > but the degree of stack overhead is different per release.
>> > >
>> > > Marking the function as noinline_for_stack is harmless here and avoids
>> > > the problem completely.
>> > >
>> > > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
>> >
>> > Unfortunately, I have seen no moment on my upstream report and this
>> > warning is breaking allmodconfig builds because of -Werror. Can this be
>> > applied as a workaround for now (preferrably with a Cc: stable on it)?
>> >
>> > Reviewed-by: Nathan Chancellor <nathan at kernel.org>
>>
>> I'll handle it asap, it will be part of 6.13
>
>Is there any update here? I don't see this patch applied in -next.

I have sent out the PR and it has been applied to the -fixes branch in
the media tree, due to the holiday period there might be some delays but
I expect the change to soon land in Linux-next.

>
>Cheers,
>Nathan

Regards,
Sebastian

>
>> > > ---
>> > > I have not come to a conclusion on how exactly clang fails to do this
>> > > right, but can provide the .config and/or preprocessed source files
>> > > and command line if we think this should be fixed in clang.
>> > > ---
>> > >  .../mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c         | 3 ++-
>> > >  1 file changed, 2 insertions(+), 1 deletion(-)
>> > >
>> > > 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 eea709d93820..47c302745c1d 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
>> > > @@ -1188,7 +1188,8 @@ static int vdec_vp9_slice_setup_lat(struct vdec_vp9_slice_instance *instance,
>> > >  	return ret;
>> > >  }
>> > >
>> > > -static
>> > > +/* clang stack usage explodes if this is inlined */
>> > > +static noinline_for_stack
>> > >  void vdec_vp9_slice_map_counts_eob_coef(unsigned int i, unsigned int j, unsigned int k,
>> > >  					struct vdec_vp9_slice_frame_counts *counts,
>> > >  					struct v4l2_vp9_frame_symbol_counts *counts_helper)
>> > > --
>> > > 2.39.5
>> > >
>> >
Sebastian Fricke
Consultant Software Engineer

Collabora Ltd
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales no 5513718.


From heiko at sntech.de  Wed Dec 18 04:45:54 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 18 Dec 2024 13:45:54 +0100
Subject: [PATCH v2 11/11] arm64: dts: rockchip: Add nodes related to eDP1 for
 RK3588
In-Reply-To: <20241216031225.3746-12-damon.ding@rock-chips.com>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-12-damon.ding@rock-chips.com>
Message-ID: <2173171.OBFZWjSADL@diego>

Hi Damon,

Am Montag, 16. Dezember 2024, 04:12:25 CET schrieb Damon Ding:
> The related nodes are hdptxphy1_grf, hdptxphy1 and edp1. And the
> aliases edp0 and edp1 are added to separate two independent eDP
> devices.
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> ---
>  .../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 55 +++++++++++++++++++
>  1 file changed, 55 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
> index 0ce0934ec6b7..17cc0b619744 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
> @@ -7,6 +7,11 @@
>  #include "rk3588-extra-pinctrl.dtsi"
>  
>  / {
> +	aliases {
> +		edp0 = &edp0;
> +		edp1 = &edp1;
> +	};
> +

drop aliases please


> @@ -67,6 +72,11 @@ u2phy1_otg: otg-port {
>  		};
>  	};
>  
> +	hdptxphy1_grf: syscon at fd5e4000 {
> +		compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
> +		reg = <0x0 0xfd5e4000 0x0 0x100>;
> +	};
> +
>  	i2s8_8ch: i2s at fddc8000 {
>  		compatible = "rockchip,rk3588-i2s-tdm";
>  		reg = <0x0 0xfddc8000 0x0 0x1000>;

> @@ -395,6 +434,22 @@ sata-port at 0 {
>  		};
>  	};
>  
> +	hdptxphy1: phy at fed70000 {
> +		compatible = "rockchip,rk3588-hdptx-phy";
> +		reg = <0x0 0xfed70000 0x0 0x2000>;
> +		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>;
> +		clock-names = "ref", "apb";
> +		#phy-cells = <0>;
> +		resets = <&cru SRST_HDPTX1>, <&cru SRST_P_HDPTX1>,
> +			 <&cru SRST_HDPTX1_INIT>, <&cru SRST_HDPTX1_CMN>,
> +			 <&cru SRST_HDPTX1_LANE>, <&cru SRST_HDPTX1_ROPLL>,
> +			 <&cru SRST_HDPTX1_LCPLL>;
> +		reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
> +			      "lcpll";
> +		rockchip,grf = <&hdptxphy1_grf>;
> +		status = "disabled";
> +	};

the hdptxphy nodes should be their own patch, also because most likely
Cristian's patch for hdmi1 [0] will be slightly faster.


[0] https://lore.kernel.org/r/20241211-rk3588-hdmi1-v2-2-02cdca22ff68 at collabora.com





From daniel.baluta at gmail.com  Wed Dec 18 05:01:11 2024
From: daniel.baluta at gmail.com (Daniel Baluta)
Date: Wed, 18 Dec 2024 15:01:11 +0200
Subject: [PATCH v2 4/5] ASoC: SOF: imx: add driver for imx95
In-Reply-To: <c3c9389f-5116-4a5f-99f6-1b37c1e8c457@gmail.com>
References: <20241113195240.3699-1-laurentiumihalcea111@gmail.com>
 <20241113195240.3699-5-laurentiumihalcea111@gmail.com> <ZzUJQCeWclsrr/lr@lizhi-Precision-Tower-5810>
 <c47710a5-7e53-48b1-bd6b-c0123865aee5@gmail.com> <Z1r9hWH1ioR5vI5H@lizhi-Precision-Tower-5810>
 <c3c9389f-5116-4a5f-99f6-1b37c1e8c457@gmail.com>
Message-ID: <CAEnQRZArKSOtka46A_SOiV2=8bs9B36ubAJM3GqYJZkKyBt_4A@mail.gmail.com>

> >>> Frank
> >> the SOF drivers do indeed have some similarities, but each of them has their own quirks which IMO makes it a bit harder to add the 95 support. We need to figure out the common parts and then move them to imx-common, but I believe this can be solved incrementally.
> > You should create common part firstly, then implement equal function with
> > existed part. Finially add imx95 part.
> >
> > Frank
>
> Yes, I'm aware of how this _should_ be done, but, like I mentioned, the change is not trivial and will
> require tweaking the other drivers as well. As such, I'd like to get the 95 support in as-is firstly.
>
> Are there any other thoughts on this?

Laurentiu, Frank please trim the emails and keep only the relevant
part for discussion.

As for this matter I think we should go with the current version Laurentiu sent.

It is inline with the implementation for imx8qxp, imx8qm, imx8mp and
imx8ulp which we already have upstream.

There is always space for refactorization and improvements. The
current version of the code
is simple enough to go in as it is.

With this,

Reviewed-by: Daniel Baluta <daniel.baluta at nxp.com>

thanks,
Daniel.


From masterr3c0rd at epochal.quest  Wed Dec 18 05:01:17 2024
From: masterr3c0rd at epochal.quest (Cody Eksal)
Date: Wed, 18 Dec 2024 09:01:17 -0400
Subject: [PATCH v2 0/2] sunxi: Add A100 syscon nodes
Message-ID: <20241218-a100-syscon-v2-0-dae60b9ce192@epochal.quest>

Hello! Here is a V2 of
https://msgid.link/20241202-a100-syscon-v1-0-86c6524f24d7 at epochal.quest.
Only changes here are fixing missing newlines between child nodes and
rebasing on 6.13-rc3.

***

Here are some very small patches to add syscon nodes to the A100's
device tree. These had not been added yet, as they hadn't been needed up
to this point. However, Parthiban and I have been working on patch
series in parallel that require either the syscon or the SRAM nodes it
is responsible for; specifically my patches add support for the A100's
ethernet controller, while Parthiban has been working hard on bringing
up the Display Engine.

Thanks as always!
- Cody

Signed-off-by: Cody Eksal <masterr3c0rd at epochal.quest>
---
Changes in v2:
- Add missing empty newlines between syscon child nodes
- Rebase on v6.13-rc3
- Link to v1: https://lore.kernel.org/r/20241202-a100-syscon-v1-0-86c6524f24d7 at epochal.quest

---
Cody Eksal (2):
      dt-bindings: sram: sunxi-sram: Add A100 compatible
      arm64: dts: allwinner: a100: Add syscon nodes

 .../sram/allwinner,sun4i-a10-system-control.yaml   |  4 ++-
 arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi     | 33 ++++++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)
---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241126-a100-syscon-7316bea62e42

Best regards,
-- 
Cody Eksal <masterr3c0rd at epochal.quest>



From masterr3c0rd at epochal.quest  Wed Dec 18 05:01:19 2024
From: masterr3c0rd at epochal.quest (Cody Eksal)
Date: Wed, 18 Dec 2024 09:01:19 -0400
Subject: [PATCH v2 2/2] arm64: dts: allwinner: a100: Add syscon nodes
In-Reply-To: <20241218-a100-syscon-v2-0-dae60b9ce192@epochal.quest>
References: <20241218-a100-syscon-v2-0-dae60b9ce192@epochal.quest>
Message-ID: <20241218-a100-syscon-v2-2-dae60b9ce192@epochal.quest>

The Allwinner A100 has a system configuration block, denoted as SYS_CFG
in the user manual's memory map. It is undocumented in the manual, but
a glance at the vendor tree shows this block is similar to its
predecessors in the A64 and H6. The A100 also has 3 SRAM blocks: A1, A2,
and C. Add all of these to the SoC's device tree.

Reviewed-by: Parthiban Nallathambi <parthiban at linumiz.com>
Signed-off-by: Cody Eksal <masterr3c0rd at epochal.quest>
---
 arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 33 ++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
index 29ac7716c7a5284ccf8af675db9c7d016785f0ff..a24adba201af29a3a117222c67da5d269629fa47 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
@@ -101,6 +101,39 @@ soc {
 		#size-cells = <1>;
 		ranges = <0 0 0 0x3fffffff>;
 
+		syscon: syscon at 3000000 {
+			compatible = "allwinner,sun50i-a100-system-control",
+				     "allwinner,sun50i-a64-system-control";
+			reg = <0x03000000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			sram_a1: sram at 20000 {
+				compatible = "mmio-sram";
+				reg = <0x00020000 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x00020000 0x4000>;
+			};
+
+			sram_c: sram at 24000 {
+				compatible = "mmio-sram";
+				reg = <0x024000 0x21000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x024000 0x21000>;
+			};
+
+			sram_a2: sram at 100000 {
+				compatible = "mmio-sram";
+				reg = <0x0100000 0x14000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x0100000 0x14000>;
+			};
+		};
+
 		ccu: clock at 3001000 {
 			compatible = "allwinner,sun50i-a100-ccu";
 			reg = <0x03001000 0x1000>;

-- 
2.47.1



From masterr3c0rd at epochal.quest  Wed Dec 18 05:01:18 2024
From: masterr3c0rd at epochal.quest (Cody Eksal)
Date: Wed, 18 Dec 2024 09:01:18 -0400
Subject: [PATCH v2 1/2] dt-bindings: sram: sunxi-sram: Add A100 compatible
In-Reply-To: <20241218-a100-syscon-v2-0-dae60b9ce192@epochal.quest>
References: <20241218-a100-syscon-v2-0-dae60b9ce192@epochal.quest>
Message-ID: <20241218-a100-syscon-v2-1-dae60b9ce192@epochal.quest>

The Allwinner A100 has a system configuration block similar to that of
the A64 and H6. Add a compatible for it.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Cody Eksal <masterr3c0rd at epochal.quest>
---
 .../devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml b/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml
index d9322704f3588e036280d08deaf59972f1dfeb7f..a7236f7db4ec34d44c4e2268f76281ef8ed83189 100644
--- a/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml
+++ b/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml
@@ -47,7 +47,9 @@ properties:
           - const: allwinner,sun8i-v3s-system-control
           - const: allwinner,sun8i-h3-system-control
       - items:
-          - const: allwinner,sun50i-h6-system-control
+          - enum:
+              - allwinner,sun50i-a100-system-control
+              - allwinner,sun50i-h6-system-control
           - const: allwinner,sun50i-a64-system-control
 
   reg:

-- 
2.47.1



From zhengqi.arch at bytedance.com  Wed Dec 18 05:04:42 2024
From: zhengqi.arch at bytedance.com (Qi Zheng)
Date: Wed, 18 Dec 2024 21:04:42 +0800
Subject: [PATCH v2 06/15] arm: pgtable: move pagetable_dtor() to __tlb_remove_table()
In-Reply-To: <cover.1734526570.git.zhengqi.arch@bytedance.com>
References: <cover.1734526570.git.zhengqi.arch@bytedance.com>
Message-ID: <dd9808c1a850a0b9974355b51182e2c98fe29c91.1734526570.git.zhengqi.arch@bytedance.com>

Move pagetable_dtor() to __tlb_remove_table(), so that ptlock and page
table pages can be freed together (regardless of whether RCU is used).
This prevents the use-after-free problem where the ptlock is freed
immediately but the page table pages is freed later via RCU.

Page tables shouldn't have swap cache, so use pagetable_free() instead of
free_page_and_swap_cache() to free page table pages.

Signed-off-by: Qi Zheng <zhengqi.arch at bytedance.com>
Suggested-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/include/asm/tlb.h | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index ef79bf1e8563f..264ab635e807a 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -26,12 +26,14 @@
 
 #else /* !CONFIG_MMU */
 
-#include <linux/swap.h>
 #include <asm/tlbflush.h>
 
 static inline void __tlb_remove_table(void *_table)
 {
-	free_page_and_swap_cache((struct page *)_table);
+	struct ptdesc *ptdesc = (struct ptdesc *)_table;
+
+	pagetable_dtor(ptdesc);
+	pagetable_free(ptdesc);
 }
 
 #include <asm-generic/tlb.h>
@@ -41,8 +43,6 @@ __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long addr)
 {
 	struct ptdesc *ptdesc = page_ptdesc(pte);
 
-	pagetable_dtor(ptdesc);
-
 #ifndef CONFIG_ARM_LPAE
 	/*
 	 * With the classic ARM MMU, a pte page has two corresponding pmd
@@ -61,7 +61,6 @@ __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr)
 #ifdef CONFIG_ARM_LPAE
 	struct ptdesc *ptdesc = virt_to_ptdesc(pmdp);
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 #endif
 }
-- 
2.20.1



From zhengqi.arch at bytedance.com  Wed Dec 18 05:04:39 2024
From: zhengqi.arch at bytedance.com (Qi Zheng)
Date: Wed, 18 Dec 2024 21:04:39 +0800
Subject: [PATCH v2 03/15] arm64: pgtable: use mmu gather to free p4d level page table
In-Reply-To: <cover.1734526570.git.zhengqi.arch@bytedance.com>
References: <cover.1734526570.git.zhengqi.arch@bytedance.com>
Message-ID: <cd3bd742cbd45e9deb0f102b6c282f1e86b6efd7.1734526570.git.zhengqi.arch@bytedance.com>

Like other levels of page tables, also use mmu gather mechanism to free
p4d level page table.

Signed-off-by: Qi Zheng <zhengqi.arch at bytedance.com>
Originally-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/include/asm/pgalloc.h |  2 --
 arch/arm64/include/asm/tlb.h     | 14 ++++++++++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 679c530549327..58cc260b6bee8 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -100,8 +100,6 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
 	if (pgtable_l5_enabled())
 		__p4d_free(mm, 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)
 {
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index a947c6e784ed2..445282cde9afb 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -111,4 +111,18 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
 }
 #endif
 
+#if CONFIG_PGTABLE_LEVELS > 4
+static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4dp,
+				  unsigned long addr)
+{
+	struct ptdesc *ptdesc = virt_to_ptdesc(p4dp);
+
+	if (!pgtable_l5_enabled())
+		return;
+
+	pagetable_p4d_dtor(ptdesc);
+	tlb_remove_ptdesc(tlb, ptdesc);
+}
+#endif
+
 #endif
-- 
2.20.1



From zhengqi.arch at bytedance.com  Wed Dec 18 05:04:43 2024
From: zhengqi.arch at bytedance.com (Qi Zheng)
Date: Wed, 18 Dec 2024 21:04:43 +0800
Subject: [PATCH v2 07/15] arm64: pgtable: move pagetable_dtor() to __tlb_remove_table()
In-Reply-To: <cover.1734526570.git.zhengqi.arch@bytedance.com>
References: <cover.1734526570.git.zhengqi.arch@bytedance.com>
Message-ID: <634f0236b4b4effc528b06e108b7bda51cd0ea2c.1734526570.git.zhengqi.arch@bytedance.com>

Move pagetable_dtor() to __tlb_remove_table(), so that ptlock and page
table pages can be freed together (regardless of whether RCU is used).
This prevents the use-after-free problem where the ptlock is freed
immediately but the page table pages is freed later via RCU.

Page tables shouldn't have swap cache, so use pagetable_free() instead of
free_page_and_swap_cache() to free page table pages.

Signed-off-by: Qi Zheng <zhengqi.arch at bytedance.com>
Suggested-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/include/asm/tlb.h | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 408d0f36a8a8f..93591a80b5bfb 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -9,11 +9,13 @@
 #define __ASM_TLB_H
 
 #include <linux/pagemap.h>
-#include <linux/swap.h>
 
 static inline void __tlb_remove_table(void *_table)
 {
-	free_page_and_swap_cache((struct page *)_table);
+	struct ptdesc *ptdesc = (struct ptdesc *)_table;
+
+	pagetable_dtor(ptdesc);
+	pagetable_free(ptdesc);
 }
 
 #define tlb_flush tlb_flush
@@ -82,7 +84,6 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 {
 	struct ptdesc *ptdesc = page_ptdesc(pte);
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 }
 
@@ -92,7 +93,6 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
 {
 	struct ptdesc *ptdesc = virt_to_ptdesc(pmdp);
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 }
 #endif
@@ -106,7 +106,6 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
 	if (!pgtable_l4_enabled())
 		return;
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 }
 #endif
@@ -120,7 +119,6 @@ static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4dp,
 	if (!pgtable_l5_enabled())
 		return;
 
-	pagetable_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 }
 #endif
-- 
2.20.1



From broonie at kernel.org  Wed Dec 18 05:15:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 18 Dec 2024 13:15:58 +0000
Subject: [PATCH V3 6/7] arm64/boot: Enable EL2 requirements for
 FEAT_Debugv8p9
In-Reply-To: <86jzbxqrtw.wl-maz@kernel.org>
References: <20241216040831.2448257-1-anshuman.khandual@arm.com>
 <20241216040831.2448257-7-anshuman.khandual@arm.com>
 <20241216234251.GA629562-robh@kernel.org>
 <c64709f7-e1c6-482e-8665-912be50b15bd@arm.com>
 <CAL_Jsq+EO_s49sSK3JQQEDDpcndf4hSpM_gfoe8tZ8=4y3f-tg@mail.gmail.com>
 <86jzbxqrtw.wl-maz@kernel.org>
Message-ID: <bdd53fdb-9ba2-4d55-870f-9cb40e1e6b21@sirena.org.uk>

On Wed, Dec 18, 2024 at 09:10:51AM +0000, Marc Zyngier wrote:

> But I don't think we should be prescriptive about the state of these
> registers, as long as the potential traps are correctly handled.

The rest of the document is written in terms of explicit register
values, if we're changing approach we should probably update all the
existing requirements to be written in the same way since having a mix
of approaches tends to be a big red flag that there should be different
handling.  Consistency will make the document clearer and easier for
people to work with.

FWIW there is an explict note in the document about the fact that it's
an as-if rule:

|                                                Where the values documented
| disable traps it is permissible for these traps to be enabled so long as
| those traps are handled transparently by higher exception levels as though
| the values documented were set.

from when I raised this before.
-------------- 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/20241218/9e4b5631/attachment.sig>

From rogerq at kernel.org  Wed Dec 18 05:22:34 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 18 Dec 2024 15:22:34 +0200
Subject: [PATCH 1/2] soc: ti: pruss: Fix pruss APIs
In-Reply-To: <20241218104424.1257880-2-danishanwar@ti.com>
References: <20241218104424.1257880-1-danishanwar@ti.com>
 <20241218104424.1257880-2-danishanwar@ti.com>
Message-ID: <17906a8a-279c-4412-8ca7-5ecbbbf9b21e@kernel.org>



On 18/12/2024 12:44, MD Danish Anwar wrote:
> PRUSS APIs in pruss_driver.h produce lots of compilation errors when
> CONFIG_TI_PRUSS is not set.
> 
> The errors and warnings,
> warning: returning 'void *' from a function with return type 'int' makes
> 	integer from pointer without a cast [-Wint-conversion]
> error: expected identifier or '(' before '{' token
> 
> Fix these warnings and errors by fixing the return type of pruss APIs as
> well as removing the misplaced semicolon from pruss_cfg_xfr_enable()
> 
> Fixes: 0211cc1e4fbb ("soc: ti: pruss: Add helper functions to set GPI mode, MII_RT_event and XFR")
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>

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



From rogerq at kernel.org  Wed Dec 18 05:23:46 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 18 Dec 2024 15:23:46 +0200
Subject: [PATCH 2/2] MAINTAINERS: Add entry for linux/pruss_driver.h
In-Reply-To: <20241218104424.1257880-3-danishanwar@ti.com>
References: <20241218104424.1257880-1-danishanwar@ti.com>
 <20241218104424.1257880-3-danishanwar@ti.com>
Message-ID: <d599c3ad-2c3e-4fda-8008-bd5051beecca@kernel.org>



On 18/12/2024 12:44, MD Danish Anwar wrote:
> include/linux/pruss_driver.h is an orphan file. Add entry for this in
> the MAINATAINERS file.

s/MAINATAINERS/MAINTAINERS

> 
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index bc992f10a2f6..069817391e9f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -23638,6 +23638,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
>  F:	Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
>  F:	drivers/pmdomain/ti/omap_prm.c
>  F:	drivers/soc/ti/*
> +F:	include/linux/pruss_driver.h
>  
>  TI LM49xxx FAMILY ASoC CODEC DRIVERS
>  M:	M R Swami Reddy <mr.swami.reddy at ti.com>




From przemyslaw.kitszel at intel.com  Wed Dec 18 05:26:33 2024
From: przemyslaw.kitszel at intel.com (Przemek Kitszel)
Date: Wed, 18 Dec 2024 14:26:33 +0100
Subject: [PATCH v5 3/3] net: stmmac: dwmac-nuvoton: Add dwmac glue for
 Nuvoton MA35 family
In-Reply-To: <20241218114442.137884-4-a0987203069@gmail.com>
References: <20241218114442.137884-1-a0987203069@gmail.com>
 <20241218114442.137884-4-a0987203069@gmail.com>
Message-ID: <7a4f5769-0010-40fd-8bb7-a20f2725114f@intel.com>

On 12/18/24 12:44, Joey Lu wrote:
> Add support for Gigabit Ethernet on Nuvoton MA35 series using dwmac driver.
> 
> Signed-off-by: Joey Lu <a0987203069 at gmail.com>
> ---
>   drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 ++
>   drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
>   .../ethernet/stmicro/stmmac/dwmac-nuvoton.c   | 182 ++++++++++++++++++
>   3 files changed, 194 insertions(+)
>   create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
> index 6658536a4e17..c8cbc0ec1311 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
> +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
> @@ -121,6 +121,17 @@ config DWMAC_MESON
>   	  the stmmac device driver. This driver is used for Meson6,
>   	  Meson8, Meson8b and GXBB SoCs.
>   
> +config DWMAC_NUVOTON
> +	tristate "Nuvoton MA35 dwmac support"
> +	default ARCH_MA35
> +	depends on OF && (ARCH_MA35 || COMPILE_TEST)
> +	select MFD_SYSCON
> +	help
> +	  Support for Ethernet controller on Nuvoton MA35 series SoC.
> +
> +	  This selects the Nuvoton MA35 series SoC glue layer support
> +	  for the stmmac device driver.
> +
>   config DWMAC_QCOM_ETHQOS
>   	tristate "Qualcomm ETHQOS support"
>   	default ARCH_QCOM
> diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
> index 2389fd261344..9812b824459f 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/Makefile
> +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
> @@ -19,6 +19,7 @@ obj-$(CONFIG_DWMAC_IPQ806X)	+= dwmac-ipq806x.o
>   obj-$(CONFIG_DWMAC_LPC18XX)	+= dwmac-lpc18xx.o
>   obj-$(CONFIG_DWMAC_MEDIATEK)	+= dwmac-mediatek.o
>   obj-$(CONFIG_DWMAC_MESON)	+= dwmac-meson.o dwmac-meson8b.o
> +obj-$(CONFIG_DWMAC_NUVOTON)	+= dwmac-nuvoton.o
>   obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-ethqos.o
>   obj-$(CONFIG_DWMAC_ROCKCHIP)	+= dwmac-rk.o
>   obj-$(CONFIG_DWMAC_RZN1)	+= dwmac-rzn1.o
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c
> new file mode 100644
> index 000000000000..c5b8933c1f44
> --- /dev/null
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c
> @@ -0,0 +1,182 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Nuvoton DWMAC specific glue layer
> + *
> + * Copyright (C) 2024 Nuvoton Technology Corp.
> + *
> + * Author: Joey Lu <yclu4 at nuvoton.com>
> + */
> +
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_device.h>
> +#include <linux/of_net.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/stmmac.h>
> +
> +#include "stmmac.h"
> +#include "stmmac_platform.h"
> +
> +#define REG_SYS_GMAC0MISCR  0x108
> +#define REG_SYS_GMAC1MISCR  0x10C
> +
> +#define MISCR_RMII          BIT(0)
> +
> +/* 2000ps is mapped to 0 ~ 0xF */
> +#define PATH_DELAY_DEC      134

would be great to previx your macros by NVT_

why 134 and not 125?

> +#define TX_DELAY_OFFSET     16

please remove and replace the usage point by FIELD_PREP()

> +#define TX_DELAY_MASK       GENMASK(19, 16)
> +#define RX_DELAY_OFFSET     20

ditto

> +#define RX_DELAY_MASK       GENMASK(23, 20)
> +
> +struct nvt_priv_data {
> +	struct platform_device *pdev;
> +	struct regmap *regmap;
> +};
> +
> +static struct nvt_priv_data *
> +nuvoton_gmac_setup(struct platform_device *pdev, struct plat_stmmacenet_data *plat)

please stick to one previx for all functions, structs, and defines,
NVT/nvt looks good
s/nuvoton/nvt/

> +{
> +	struct device *dev = &pdev->dev;
> +	struct nvt_priv_data *bsp_priv;
> +	phy_interface_t phy_mode;
> +	u32 tx_delay, rx_delay;
> +	u32 macid, arg, reg;
> +
> +	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
> +	if (!bsp_priv)
> +		return ERR_PTR(-ENOMEM);
> +
> +	bsp_priv->regmap =
> +		syscon_regmap_lookup_by_phandle_args(dev->of_node, "nuvoton,sys", 1, &macid);
> +	if (IS_ERR(bsp_priv->regmap)) {
> +		dev_err_probe(dev, PTR_ERR(bsp_priv->regmap), "Failed to get sys register\n");
> +		return ERR_PTR(-ENODEV);
> +	}
> +	if (macid > 1) {
> +		dev_err_probe(dev, -EINVAL, "Invalid sys arguments\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (of_property_read_u32(dev->of_node, "tx-internal-delay-ps", &arg)) {
> +		tx_delay = 0; /* Default value is 0 */

please remove obvious comments

> +	} else {
> +		if (arg <= 2000) {
> +			tx_delay = (arg == 2000) ? 0xF : (arg / PATH_DELAY_DEC);
> +			dev_dbg(dev, "Set Tx path delay to 0x%x\n", tx_delay);
> +		} else {
> +			dev_err(dev, "Invalid Tx path delay argument.\n");
> +			return ERR_PTR(-EINVAL);
> +		}
> +	}
> +	if (of_property_read_u32(dev->of_node, "rx-internal-delay-ps", &arg)) {
> +		rx_delay = 0; /* Default value is 0 */
> +	} else {
> +		if (arg <= 2000) {
> +			rx_delay = (arg == 2000) ? 0xF : (arg / PATH_DELAY_DEC);
> +			dev_dbg(dev, "Set Rx path delay to 0x%x\n", rx_delay);
> +		} else {
> +			dev_err(dev, "Invalid Rx path delay argument.\n");
> +			return ERR_PTR(-EINVAL);
> +		}
> +	}
> +
> +	regmap_read(bsp_priv->regmap,
> +		    macid == 0 ? REG_SYS_GMAC0MISCR : REG_SYS_GMAC1MISCR, &reg);
> +	reg &= ~(TX_DELAY_MASK | RX_DELAY_MASK);
> +
> +	if (of_get_phy_mode(pdev->dev.of_node, &phy_mode)) {
> +		dev_err(dev, "missing phy mode property\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	switch (phy_mode) {
> +	case PHY_INTERFACE_MODE_RGMII:
> +	case PHY_INTERFACE_MODE_RGMII_ID:
> +	case PHY_INTERFACE_MODE_RGMII_RXID:
> +	case PHY_INTERFACE_MODE_RGMII_TXID:
> +		reg &= ~MISCR_RMII;
> +		break;
> +	case PHY_INTERFACE_MODE_RMII:
> +		reg |= MISCR_RMII;
> +		break;
> +	default:
> +		dev_err(dev, "Unsupported phy-mode (%d)\n", phy_mode);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (!(reg & MISCR_RMII)) {
> +		reg |= tx_delay << TX_DELAY_OFFSET;
> +		reg |= rx_delay << RX_DELAY_OFFSET;
> +	}
> +
> +	regmap_write(bsp_priv->regmap,
> +		     macid == 0 ? REG_SYS_GMAC0MISCR : REG_SYS_GMAC1MISCR, reg);
> +
> +	bsp_priv->pdev = pdev;
> +
> +	return bsp_priv;
> +}
> +
> +static int nuvoton_gmac_probe(struct platform_device *pdev)
> +{
> +	struct plat_stmmacenet_data *plat_dat;
> +	struct stmmac_resources stmmac_res;
> +	int ret;
> +
> +	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
> +	if (ret)
> +		return ret;
> +
> +	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
> +	if (IS_ERR(plat_dat))
> +		return PTR_ERR(plat_dat);
> +
> +	/* Nuvoton DWMAC configs */
> +	plat_dat->has_gmac = 1;
> +	plat_dat->tx_fifo_size = 2048;
> +	plat_dat->rx_fifo_size = 4096;
> +	plat_dat->multicast_filter_bins = 0;
> +	plat_dat->unicast_filter_entries = 8;
> +	plat_dat->flags &= ~STMMAC_FLAG_USE_PHY_WOL;
> +
> +	plat_dat->bsp_priv = nuvoton_gmac_setup(pdev, plat_dat);

would be great to extend plat_stmmacenet_data allocation to allocate
also the space for the priv data - but this is outside of the scope
of this patchset

> +	if (IS_ERR(plat_dat->bsp_priv)) {
> +		ret = PTR_ERR(plat_dat->bsp_priv);
> +		return ret;

just return PTR_ERR(...)

> +	}
> +
> +	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
> +	if (ret)
> +		return ret;
> +
> +	/* The PMT flag is determined by the RWK property.
> +	 * However, our hardware is configured to support only MGK.
> +	 * This is an override on PMT to enable WoL capability.
> +	 */
> +	plat_dat->pmt = 1;
> +	device_set_wakeup_capable(&pdev->dev, 1);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id nuvoton_dwmac_match[] = {
> +	{ .compatible = "nuvoton,ma35d1-dwmac"},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, nuvoton_dwmac_match);
> +
> +static struct platform_driver nuvoton_dwmac_driver = {
> +	.probe  = nuvoton_gmac_probe,
> +	.remove = stmmac_pltfr_remove,
> +	.driver = {
> +		.name           = "nuvoton-dwmac",
> +		.pm		= &stmmac_pltfr_pm_ops,
> +		.of_match_table = nuvoton_dwmac_match,
> +	},
> +};
> +module_platform_driver(nuvoton_dwmac_driver);
> +
> +MODULE_AUTHOR("Joey Lu <yclu4 at nuvoton.com>");
> +MODULE_DESCRIPTION("Nuvoton DWMAC specific glue layer");
> +MODULE_LICENSE("GPL v2");



From mike.leach at linaro.org  Wed Dec 18 05:44:41 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Wed, 18 Dec 2024 13:44:41 +0000
Subject: [PATCH v2 0/9] coresight: change some driver' spinlock type to raw_spinlock_t
In-Reply-To: <20241203114942.697188-1-yeoreum.yun@arm.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7Vis9vcdJOzu9tvNQ4eAacmXkbhbZBaRYd1acOrd8G-ZUQ@mail.gmail.com>

This change seems to omit devices:

etm3x - which provides support for ETMv3 and PTM, both of which are
valid trace sources in the cs_etm handling code.
stm - can be integrated into the kernel STM via configfs providing a
MIPI source for ftrace.

Mike

On Tue, 3 Dec 2024 at 11:49, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In some coresight drivers, drvdata->spinlock can be held during __schedule()
> by perf_event_task_sched_out()/in().
>
> Since drvdata->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this,change type drvdata->spinlock in some coresight drivers,
> which can be called by perf_event_task_sched_out()/in(),
> from spinlock_t to raw_spinlock_t.
>
> Reviewed-by: James Clark <james.clark at linaro.org>
>
> v1 to v2:
>     - seperate patchsets to change locktype and apply gurad API.
>
> Levi Yun (9):
>   coresight: change coresight_device lock type to raw_spinlock_t
>   coresight-etm4x: change etmv4_drvdata spinlock type to raw_spinlock_t
>   coresight: change coresight_trace_id_map's lock type to raw_spinlock_t
>   coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
>   coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
>   coresight-funnel: change funnel_drvdata spinlock's type to
>     raw_spinlock_t
>   coresight-replicator: change replicator_drvdata spinlock's type to
>     raw_spinlock_t
>   coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
>   coresight/ultrasoc: change cti_drvdata spinlock's type to
>     raw_spinlock_t
>
>  .../hwtracing/coresight/coresight-config.c    |  21 +-
>  .../hwtracing/coresight/coresight-config.h    |   2 +-
>  drivers/hwtracing/coresight/coresight-core.c  |   2 +-
>  .../hwtracing/coresight/coresight-cti-core.c  |  65 +-
>  .../hwtracing/coresight/coresight-cti-sysfs.c | 135 +++--
>  drivers/hwtracing/coresight/coresight-cti.h   |   2 +-
>  drivers/hwtracing/coresight/coresight-etb10.c |  62 +-
>  .../coresight/coresight-etm4x-core.c          |  71 ++-
>  .../coresight/coresight-etm4x-sysfs.c         | 566 +++++++++---------
>  drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
>  .../hwtracing/coresight/coresight-funnel.c    |  34 +-
>  .../coresight/coresight-replicator.c          |  36 +-
>  .../hwtracing/coresight/coresight-syscfg.c    |  75 ++-
>  .../hwtracing/coresight/coresight-tmc-core.c  |   9 +-
>  .../hwtracing/coresight/coresight-tmc-etf.c   | 195 +++---
>  .../hwtracing/coresight/coresight-tmc-etr.c   | 199 +++---
>  drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
>  .../hwtracing/coresight/coresight-trace-id.c  |  93 ++-
>  drivers/hwtracing/coresight/ultrasoc-smb.c    |  12 +-
>  drivers/hwtracing/coresight/ultrasoc-smb.h    |   2 +-
>  include/linux/coresight.h                     |   4 +-
>  21 files changed, 751 insertions(+), 838 deletions(-)
>
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>


-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From angelogioacchino.delregno at collabora.com  Wed Dec 18 06:10:05 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 15:10:05 +0100
Subject: [PATCH v3 00/22] continue mt7988 devicetree work
In-Reply-To: <20241217091238.16032-1-linux@fw-web.de>
References: <20241217091238.16032-1-linux@fw-web.de>
Message-ID: <1b10a0ef-b6fa-4758-b3fc-0a44d840bce9@collabora.com>

Il 17/12/24 10:12, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> This series adds some missing labels and new nodes to mt7988 DTS.
> 
> based on pinctrl-series
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=918572
> 

The whole series is

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Good job!

Cheers,
Angelo

> changes:
> v3:
> - reorder
> - small fixes
> - add some new patches (t-phy, pcie, mmc overlays)
> - dropped pmic and proc-supply for now because we found a mismatch compared with schematic
> 
> v2:
> - reorder and squash label-commits to where they are used
> - add some more nodes
> - add changes to bananapi-r4 board
> - moving some nodes from SoC dtsi to board dts
> 
> Frank Wunderlich (22):
>    arm64: dts: mediatek: mt7988: Add reserved memory
>    arm64: dts: mediatek: mt7988: Add mmc support
>    arm64: dts: mediatek: mt7988: Add lvts node
>    arm64: dts: mediatek: mt7988: Add thermal-zone
>    arm64: dts: mediatek: mt7988: Add missing clock-div property for i2c
>    arm64: dts: mediatek: mt7988: Add mcu-sys node for cpu
>    arm64: dts: mediatek: mt7988: Add CPU OPP table for clock scaling
>    arm64: dts: mediatek: mt7988: Disable usb controllers by default
>    arm64: dts: mediatek: mt7988: Add t-phy for ssusb1
>    arm64: dts: mediatek: mt7988: Add pcie nodes
>    arm64: dts: mediatek: mt7988a-bpi-r4: Enable watchdog
>    arm64: dts: mediatek: mt7988a-bpi-r4: Add fixed regulators for 1v8 and
>      3v3
>    arm64: dts: mediatek: mt7988a-bpi-r4: Add dt overlays for sd + emmc
>    arm64: dts: mediatek: mt7988a-bpi-r4: Add thermal configuration
>    arm64: dts: mediatek: mt7988a-bpi-r4: Enable serial0 debug uart
>    arm64: dts: mediatek: mt7988a-bpi-r4: Add default UART stdout
>    arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C controllers
>    arm64: dts: mediatek: mt7988a-bpi-r4: Add PCA9545 I2C Mux
>    arm64: dts: mediatek: mt7988a-bpi-r4: Enable t-phy for ssusb1
>    arm64: dts: mediatek: mt7988a-bpi-r4: Enable ssusb1 on bpi-r4
>    arm64: dts: mediatek: mt7988a-bpi-r4: Enable pwm
>    arm64: dts: mediatek: mt7988a-bpi-r4: Enable pcie
> 
>   arch/arm64/boot/dts/mediatek/Makefile         |   3 +
>   .../mt7988a-bananapi-bpi-r4-emmc.dtso         |  33 ++
>   .../mediatek/mt7988a-bananapi-bpi-r4-sd.dtso  |  31 ++
>   .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 143 +++++++++
>   arch/arm64/boot/dts/mediatek/mt7988a.dtsi     | 303 +++++++++++++++++-
>   5 files changed, 506 insertions(+), 7 deletions(-)
>   create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
>   create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
> 



From angelogioacchino.delregno at collabora.com  Wed Dec 18 06:12:32 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 15:12:32 +0100
Subject: [PATCH v7 0/5] Add pinctrl support for mt7988
In-Reply-To: <20241217085435.9586-1-linux@fw-web.de>
References: <20241217085435.9586-1-linux@fw-web.de>
Message-ID: <e1b8084d-cfc2-4541-8264-91be777a8783@collabora.com>

Il 17/12/24 09:54, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> This series adds pinctrl driver, dt-bindings and dts node for pinctrl
> on mediatek mt7988 SoC.
> 
> changes in v7:
> - add const for pins and mtk_pin_soc as suggested by Christophe JAILLET in v5
> - left angelos RB because of minor change (hope this is right)

It's fine, I re-reviewed it and it's good (actually, better!) :-)

Cheers,
Angelo

> 
> changes in v6:
> - some fixes to binding
> - changed title and fixed typo in bpi-r4 patch
> - added RB's
> 
> changes in v5:
> - rebased to 6.13-rc1
> - moved dt nodes with mutliple options to BPI-R4 board
> - changes suggested by angelo in v4
> - changed example in binding and dt node to not using const MTK_DRIVE_8mA
> 
> changes in v4:
> - fixed fixed string binding error
> 
> changes in v3:
> - rebase on rafals dts patches
> - update binding to have mux subnode as fixed string and conf with optional suffix
> 
> changes in v2:
>    binding:
>    - drop gpio-cells description
>    - move ref in mux subnode up
>    - order uart-functions alphanumeric and fix typo
>    dts:
>    - fix indentation of reg-values
> 
> Daniel Golle (2):
>    pinctrl: mediatek: add support for MTK_PULL_PD_TYPE
>    pinctrl: mediatek: add MT7988 pinctrl driver
> 
> Frank Wunderlich (3):
>    dt-bindings: pinctrl: add binding for MT7988 SoC
>    arm64: dts: mediatek: mt7988: Add pinctrl support
>    arm64: dts: mediatek: mt7988a-bpi-r4: Add pinctrl subnodes for bpi-r4
> 
>   .../pinctrl/mediatek,mt7988-pinctrl.yaml      |  575 ++++++
>   .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  |  189 ++
>   arch/arm64/boot/dts/mediatek/mt7988a.dtsi     |   54 +
>   drivers/pinctrl/mediatek/Kconfig              |    7 +
>   drivers/pinctrl/mediatek/Makefile             |    1 +
>   drivers/pinctrl/mediatek/pinctrl-mt7988.c     | 1556 +++++++++++++++++
>   .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  |   73 +-
>   .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |    1 +
>   8 files changed, 2445 insertions(+), 11 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
>   create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c
> 




From conor at kernel.org  Wed Dec 18 06:28:43 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 14:28:43 +0000
Subject: [PATCH] dtoverlays: Added DT overlay file for MAX98090 and the
 detailed steps for its usage is included in
 https://github.com/Poojaa-Rangaiah/DeviceTreeOverlay-for-MAX98090 .
In-Reply-To: <20241218065848.12254-1-poojaamonica94@gmail.com>
References: <20241218065848.12254-1-poojaamonica94@gmail.com>
Message-ID: <20241218-arrange-pointer-cdd39770b48b@spud>

On Wed, Dec 18, 2024 at 12:28:48PM +0530, Poojaa R wrote:
> Only the driver files were existing for max98090 audio codec (playback and capture) but now the max98090.dts file is also included in linux/arch/arm/boot/dts/overlays/.
> new file:   arch/arm/boot/dts/overlays/max98090.dts
> 
> Signed-off-by: Poojaa R <poojaamonica94 at gmail.com>

Why have you send this patch for your random github tree to lkml?

Thanks,
Conor.

> ---
>  arch/arm/boot/dts/overlays/max98090.dts | 96 +++++++++++++++++++++++++
>  1 file changed, 96 insertions(+)
>  create mode 100644 arch/arm/boot/dts/overlays/max98090.dts
> 
> diff --git a/arch/arm/boot/dts/overlays/max98090.dts b/arch/arm/boot/dts/overlays/max98090.dts
> new file mode 100644
> index 000000000000..eaf197384edb
> --- /dev/null
> +++ b/arch/arm/boot/dts/overlays/max98090.dts
> @@ -0,0 +1,96 @@
> +/*
> + * Device Tree Overlay for MAX98090, MAX98091 Audio Codec.
> + * https://github.com/Poojaa-Rangaiah/DeviceTreeOverlay-for-MAX98090 => for more details.
> + * MAX98090 audio codec as master and Raspberry Pi as slave.
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +/ {
> +    compatible = "brcm,bcm2835", "brcm,bcm2711";
> +
> +    fragment at 0 {
> +        target = <&i2s_clk_consumer>;
> +        __overlay__ {
> +            status = "okay";
> +        };
> +    };
> +
> +    fragment at 1 {
> +        target = <&i2c1>;
> +        __overlay__ {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +            status = "okay";
> +            max98090_codec: max98090 at 10 {
> +                #sound-dai-cells = <0>;
> +                compatible = "maxim,max98090","maxim,max98091";
> +                reg = <0x10>;
> +                interrupt-parent = <&gpio>;
> +                interrupts = <27 2>;	/* GPIO 27 as Edge_Falling_IRQ (2) */
> +                maxim,micbias = <3>;
> +                status = "okay";
> +            };
> +        };
> +    };
> +
> +    fragment at 2 {
> +        target-path = "/";
> +        __overlay__ {
> +            clk_oscillator: oscillator {
> +                compatible = "fixed-clock";
> +                #clock-cells = <0>;
> +                clock-frequency = <12288000>;  /* Frequency of the external oscillator (mclk = 12.288 MHz) but can also be 11.2896 MHz/12 MHz/13 MHz/26 MHz/19.2 MHz. */
> +                clock-output-names = "mclk";
> +            };
> +        };
> +    };
> +
> +    fragment at 3 {
> +        target = <&sound>;
> +        sound_overlay: __overlay__ {
> +            compatible = "simple-audio-card";
> +            simple-audio-card,format = "i2s";
> +            simple-audio-card,name = "MAX98090-Codec";
> +            simple-audio-card,bitclock-master = <&dailink0_master>;
> +            simple-audio-card,frame-master = <&dailink0_master>;
> +
> +            simple-audio-card,widgets =
> +                "Microphone", "Mic Jack",
> +                "Speaker", "Speaker",
> +                "Line", "Line In",
> +                "Line", "Line Out",
> +                "Headphone", "Headphone Jack";
> +
> +            simple-audio-card,routing =
> +                "Headphone Jack", "HPL",
> +                "Headphone Jack", "HPR",
> +                "Line Out", "RCVL",
> +                "Line Out", "RCVR", 
> +                /* Uncomment any of these below lines if the Line Input(s) is(are) used else leave it as such. */
> +                //"IN5", "Line In",  /* IN1/IN2/IN3/IN4/IN6 (For single ended input) */
> +                //"IN56", "Line In", /* IN34 (For differential inputs) */
> +                "MIC1", "Mic Jack",
> +                "MIC2", "Mic Jack",
> +                "Speaker", "SPKL",
> +                "Speaker", "SPKR";
> +
> +            status = "okay";
> +
> +            simple-audio-card,cpu {
> +                sound-dai = <&i2s_clk_consumer>;
> +            };
> +
> +            dailink0_master: simple-audio-card,codec {
> +                sound-dai = <&max98090_codec>;
> +                clocks = <&clk_oscillator>;
> +            };
> +        };
> +    };
> +    
> +    __overrides__ {
> +        card-name = <&sound_overlay>, "simple-audio-card,name";
> +    };
> +};
> +
> -- 
> 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/20241218/89206605/attachment.sig>

From daniel.machon at microchip.com  Wed Dec 18 06:33:54 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Wed, 18 Dec 2024 14:33:54 +0000
Subject: [PATCH net-next v4 0/9] net: lan969x: add RGMII support
In-Reply-To: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
References: <20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714@microchip.com>
Message-ID: <20241218143354.eh6iinemupxncblj@DEN-DL-M70577>

I would like to defer the pontential removal of sparx5_port_verify_speed()
function to a separate series (see comments on patch 6/9).  Any chance for a
maintainer to give the OK for that? I would like to give this series another
spin before net-next closes. No changes in next version - except adding TB and
RB tags.

/Daniel 


From vishal.sagar at amd.com  Wed Dec 18 06:35:00 2024
From: vishal.sagar at amd.com (Sagar, Vishal)
Date: Wed, 18 Dec 2024 14:35:00 +0000
Subject: [PATCH 01/10] drm/fourcc: Add warning for bad bpp
In-Reply-To: <02da12fe-4d94-4a40-86b6-6dad28588843@ideasonboard.com>
References: <20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com>
 <20241204-xilinx-formats-v1-1-0bf2c5147db1@ideasonboard.com>
 <BL1PR12MB596954886CC5E28EC8E735BA9C372@BL1PR12MB5969.namprd12.prod.outlook.com>
 <02da12fe-4d94-4a40-86b6-6dad28588843@ideasonboard.com>
Message-ID: <BL1PR12MB596972D7D77F48C6BD91DFEA9C052@BL1PR12MB5969.namprd12.prod.outlook.com>

[AMD Official Use Only - AMD Internal Distribution Only]

Hi Tomi

> -----Original Message-----
> From: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> Sent: Wednesday, December 18, 2024 12:49 PM
> To: Sagar, Vishal <vishal.sagar at amd.com>
> Cc: dri-devel at lists.freedesktop.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; Klymenko, Anatoliy <Anatoliy.Klymenko at amd.com>;
> Maarten Lankhorst <maarten.lankhorst at linux.intel.com>; Maxime Ripard
> <mripard at kernel.org>; Thomas Zimmermann <tzimmermann at suse.de>; David
> Airlie <airlied at gmail.com>; Simona Vetter <simona at ffwll.ch>; Laurent Pinchart
> <laurent.pinchart at ideasonboard.com>; Simek, Michal <michal.simek at amd.com>
> Subject: Re: [PATCH 01/10] drm/fourcc: Add warning for bad bpp
>
> Hi Vishal,
>
> On 04/12/2024 18:26, Sagar, Vishal wrote:
> > [AMD Official Use Only - AMD Internal Distribution Only]
> >
> > Hi Tomi,
> >
> > Thanks for the patch.
> >
> >> -----Original Message-----
> >> From: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> >> Sent: Wednesday, December 4, 2024 10:31 AM
> >> To: Sagar, Vishal <vishal.sagar at amd.com>; Klymenko, Anatoliy
> >> <Anatoliy.Klymenko at amd.com>; Maarten Lankhorst
> >> <maarten.lankhorst at linux.intel.com>; Maxime Ripard <mripard at kernel.org>;
> >> Thomas Zimmermann <tzimmermann at suse.de>; David Airlie
> >> <airlied at gmail.com>; Simona Vetter <simona at ffwll.ch>; Laurent Pinchart
> >> <laurent.pinchart at ideasonboard.com>; Simek, Michal
> <michal.simek at amd.com>
> >> Cc: dri-devel at lists.freedesktop.org; linux-kernel at vger.kernel.org; linux-arm-
> >> kernel at lists.infradead.org; Tomi Valkeinen
> <tomi.valkeinen at ideasonboard.com>
> >> Subject: [PATCH 01/10] drm/fourcc: Add warning for bad bpp
> >>
> >> drm_format_info_bpp() cannot be used for formats which do not have an
> >> integer bits-per-pixel. Handle wrong calls by printing a warning and
> >> returning 0.
> >
> > It would be good to add an example of pixel format that may cause this issue.
>
> Indeed, the description is perhaps a bit lacking. I'll change it to:
>
> drm_format_info_bpp() cannot be used for formats which do not have an
> integer bits-per-pixel in a pixel block.
>
> E.g. DRM_FORMAT_XV15's (not yet in upstream) plane 0 has three 10-bit
> pixels (Y components), and two padding bits, in a 4 byte block. That is
> 10.666... bits per pixel when considering the whole 4 byte block, which
> is what drm_format_info_bpp() does. Thus a driver that supports such
> formats cannot use drm_format_info_bpp(),
>
> It is a driver bug if this happens, but so handle wrong calls by
> printing a warning and returning 0.
>

This looks good to me.

Vishal

>   Tomi
>
> >>
> >> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> >> ---
> >>   drivers/gpu/drm/drm_fourcc.c | 7 +++++++
> >>   1 file changed, 7 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> >> index 193cf8ed7912..e84c4ed6928c 100644
> >> --- a/drivers/gpu/drm/drm_fourcc.c
> >> +++ b/drivers/gpu/drm/drm_fourcc.c
> >> @@ -429,6 +429,13 @@ unsigned int drm_format_info_bpp(const struct
> >> drm_format_info *info, int plane)
> >>        if (!info || plane < 0 || plane >= info->num_planes)
> >>                return 0;
> >>
> >> +     if (info->char_per_block[plane] * 8 %
> >> +         (drm_format_info_block_width(info, plane) *
> >> +          drm_format_info_block_height(info, plane))) {
> >> +             pr_warn("unable to return an integer bpp\n");
> >> +             return 0;
> >> +     }
> >> +
> >>        return info->char_per_block[plane] * 8 /
> >>               (drm_format_info_block_width(info, plane) *
> >>                drm_format_info_block_height(info, plane));
> >>
> >> --
> >> 2.43.0
> >
> > Regards
> > Vishal Sagar

From james.clark at linaro.org  Wed Dec 18 06:38:07 2024
From: james.clark at linaro.org (James Clark)
Date: Wed, 18 Dec 2024 14:38:07 +0000
Subject: [PATCH v2 0/9] coresight: change some driver' spinlock type to
 raw_spinlock_t
In-Reply-To: <CAJ9a7Vis9vcdJOzu9tvNQ4eAacmXkbhbZBaRYd1acOrd8G-ZUQ@mail.gmail.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
 <CAJ9a7Vis9vcdJOzu9tvNQ4eAacmXkbhbZBaRYd1acOrd8G-ZUQ@mail.gmail.com>
Message-ID: <7a370fb3-f5eb-4d6a-a42d-b43960efb930@linaro.org>



On 18/12/2024 1:44 pm, Mike Leach wrote:
> This change seems to omit devices:
> 
> etm3x - which provides support for ETMv3 and PTM, both of which are
> valid trace sources in the cs_etm handling code.
> stm - can be integrated into the kernel STM via configfs providing a
> MIPI source for ftrace.
> 
> Mike
> 

Isn't ETMv3 32 bit only? arm32 is still missing ARCH_SUPPORTS_RT so we 
could technically leave the spinlocks as is. It might be better to 
update them anyway though or add !PREEMPT_RT to 
CONFIG_CORESIGHT_SOURCE_ETM3X.

> On Tue, 3 Dec 2024 at 11:49, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>>
>> In some coresight drivers, drvdata->spinlock can be held during __schedule()
>> by perf_event_task_sched_out()/in().
>>
>> Since drvdata->spinlock type is spinlock_t and
>> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
>> which is raw_spinlock_t (an unsleepable lock),
>> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>>
>> To address this,change type drvdata->spinlock in some coresight drivers,
>> which can be called by perf_event_task_sched_out()/in(),
>> from spinlock_t to raw_spinlock_t.
>>
>> Reviewed-by: James Clark <james.clark at linaro.org>
>>
>> v1 to v2:
>>      - seperate patchsets to change locktype and apply gurad API.
>>
>> Levi Yun (9):
>>    coresight: change coresight_device lock type to raw_spinlock_t
>>    coresight-etm4x: change etmv4_drvdata spinlock type to raw_spinlock_t
>>    coresight: change coresight_trace_id_map's lock type to raw_spinlock_t
>>    coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
>>    coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
>>    coresight-funnel: change funnel_drvdata spinlock's type to
>>      raw_spinlock_t
>>    coresight-replicator: change replicator_drvdata spinlock's type to
>>      raw_spinlock_t
>>    coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
>>    coresight/ultrasoc: change cti_drvdata spinlock's type to
>>      raw_spinlock_t
>>
>>   .../hwtracing/coresight/coresight-config.c    |  21 +-
>>   .../hwtracing/coresight/coresight-config.h    |   2 +-
>>   drivers/hwtracing/coresight/coresight-core.c  |   2 +-
>>   .../hwtracing/coresight/coresight-cti-core.c  |  65 +-
>>   .../hwtracing/coresight/coresight-cti-sysfs.c | 135 +++--
>>   drivers/hwtracing/coresight/coresight-cti.h   |   2 +-
>>   drivers/hwtracing/coresight/coresight-etb10.c |  62 +-
>>   .../coresight/coresight-etm4x-core.c          |  71 ++-
>>   .../coresight/coresight-etm4x-sysfs.c         | 566 +++++++++---------
>>   drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
>>   .../hwtracing/coresight/coresight-funnel.c    |  34 +-
>>   .../coresight/coresight-replicator.c          |  36 +-
>>   .../hwtracing/coresight/coresight-syscfg.c    |  75 ++-
>>   .../hwtracing/coresight/coresight-tmc-core.c  |   9 +-
>>   .../hwtracing/coresight/coresight-tmc-etf.c   | 195 +++---
>>   .../hwtracing/coresight/coresight-tmc-etr.c   | 199 +++---
>>   drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
>>   .../hwtracing/coresight/coresight-trace-id.c  |  93 ++-
>>   drivers/hwtracing/coresight/ultrasoc-smb.c    |  12 +-
>>   drivers/hwtracing/coresight/ultrasoc-smb.h    |   2 +-
>>   include/linux/coresight.h                     |   4 +-
>>   21 files changed, 751 insertions(+), 838 deletions(-)
>>
>> --
>> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>>
> 
> 



From eauger at redhat.com  Wed Dec 18 06:40:16 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 15:40:16 +0100
Subject: [PATCH V2 02/46] arm64/sysreg: Update register fields for
 ID_AA64MMFR4_EL1
In-Reply-To: <20241210055311.780688-3-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-3-anshuman.khandual@arm.com>
Message-ID: <ed883097-c1a1-498d-97af-f0a306893b26@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This updates ID_AA64MMFR4_EL1 register as per the definitions based on
> DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric

> ---
>  arch/arm64/tools/sysreg | 19 ++++++++++++++++---
>  1 file changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index a6cbe0dcd63b..b5bda7c94689 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -1872,12 +1872,21 @@ EndEnum
>  EndSysreg
>  
>  Sysreg	ID_AA64MMFR4_EL1	3	0	0	7	4
> -Res0	63:40
> +Res0	63:48
> +UnsignedEnum	47:44	SRMASK
> +	0b0000	NI
> +	0b0001	IMP
> +EndEnum
> +Res0	43:40
>  UnsignedEnum	39:36	E3DSE
>  	0b0000	NI
>  	0b0001	IMP
>  EndEnum
> -Res0	35:28
> +Res0	35:32
> +UnsignedEnum	31:28	RMEGDI
> +	0b0000	NI
> +	0b0001	IMP
> +EndEnum
>  SignedEnum	27:24	E2H0
>  	0b0000	IMP
>  	0b1110	NI_NV1
> @@ -1886,6 +1895,7 @@ EndEnum
>  UnsignedEnum	23:20	NV_frac
>  	0b0000	NV_NV2
>  	0b0001	NV2_ONLY
> +	0b0010	SOFTWARE
>  EndEnum
>  UnsignedEnum	19:16	FGWTE3
>  	0b0000	NI
> @@ -1905,7 +1915,10 @@ SignedEnum	7:4	EIESB
>  	0b0010	ToELx
>  	0b1111	ANY
>  EndEnum
> -Res0	3:0
> +UnsignedEnum	3:0	PoPS
> +	0b0000	NI
> +	0b0001	IMP
> +EndEnum
>  EndSysreg
>  
>  Sysreg	SCTLR_EL1	3	0	1	0	0



From eauger at redhat.com  Wed Dec 18 06:40:13 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 15:40:13 +0100
Subject: [PATCH V2 04/46] arm64/sysreg: Update register fields for
 TRBIDR_EL1
In-Reply-To: <20241210055311.780688-5-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-5-anshuman.khandual@arm.com>
Message-ID: <36aba488-26d7-4dc9-9ca0-a14e3de028e9@redhat.com>

Hi Anshuman

On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for TRBIDR_EL1 as per the definitions based
> on DDI0601 2024-09.
> 
> 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 | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 59351931d907..10b1a0998d99 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -3295,13 +3295,24 @@ Field	31:0	TRG
>  EndSysreg
>  
>  Sysreg	TRBIDR_EL1	3	0	9	11	7
> -Res0	63:12
> +Res0	63:48
> +Field	47:32	MaxBuffSize
> +Res0	31:16
> +UnsignedEnum	15:12	MPAM
> +	0b0000	NI
> +	0b0001	PMG
Out of curiosity how did you choose the PMG terminology?
I see "MPAM implemented by the Trace Buffer Unit, using default PARTID
and PMG values in External mode". Wouldn't be TBU more meaningful?

Eric
> +	0b0010	IMP
> +EndEnum
>  Enum	11:8	EA
>  	0b0000	NON_DESC
>  	0b0001	IGNORE
>  	0b0010	SERROR
>  EndEnum
> -Res0	7:6
> +UnsignedEnum 7:6	AddrMode
> +	0b00	VIRT_PHYS
> +	0b01	VIRT_ONLY
> +	0b10	PHYS_ONLY
> +EndEnum
>  Field	5	F
>  Field	4	P
>  Field	3:0	Align



From eauger at redhat.com  Wed Dec 18 06:40:15 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 15:40:15 +0100
Subject: [PATCH V2 03/46] arm64/sysreg: Update register fields for
 ID_AA64PFR0_EL1
In-Reply-To: <20241210055311.780688-4-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-4-anshuman.khandual@arm.com>
Message-ID: <5b46b684-3223-41d6-9da5-4e59a1de990b@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This updates ID_AA64PFR0_EL1.RAS and ID_AA64PFR0_EL1.RME register fields as
> per the definitions based on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>
> ---
>  arch/arm64/tools/sysreg | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index b5bda7c94689..59351931d907 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -873,6 +873,8 @@ EndEnum
>  UnsignedEnum	55:52	RME
>  	0b0000	NI
>  	0b0001	IMP
> +	0b0010	GPC2
> +	0b0011	GPC3
>  EndEnum
>  UnsignedEnum	51:48	DIT
>  	0b0000	NI
> @@ -899,6 +901,7 @@ UnsignedEnum	31:28	RAS
>  	0b0000	NI
>  	0b0001	IMP
>  	0b0010	V1P1
> +	0b0011	V2
>  EndEnum
>  UnsignedEnum	27:24	GIC
>  	0b0000	NI



From eauger at redhat.com  Wed Dec 18 06:40:17 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 15:40:17 +0100
Subject: [PATCH V2 01/46] arm64/sysreg: Update register fields for
 ID_AA64MMFR0_EL1
In-Reply-To: <20241210055311.780688-2-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-2-anshuman.khandual@arm.com>
Message-ID: <283bed34-4fe8-4c8e-aad3-b6d7f2e1a0bc@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This updates ID_AA64MMFR0_EL1.FGT and ID_AA64MMFR0_EL1.PARANGE register
> fields as per the definitions based on DDI0601 2024-09.
> 
> 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
> Reviewed-by: Mark Brown <broonie at kernel.org>
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric

> ---
>  arch/arm64/tools/sysreg | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index b081b54d6d22..a6cbe0dcd63b 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -1591,6 +1591,7 @@ EndEnum
>  UnsignedEnum	59:56	FGT
>  	0b0000	NI
>  	0b0001	IMP
> +	0b0010	FGT2
>  EndEnum
>  Res0	55:48
>  UnsignedEnum	47:44	EXS
> @@ -1652,6 +1653,7 @@ Enum	3:0	PARANGE
>  	0b0100	44
>  	0b0101	48
>  	0b0110	52
> +	0b0111	56
>  EndEnum
>  EndSysreg
>  



From eauger at redhat.com  Wed Dec 18 06:45:26 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 15:45:26 +0100
Subject: [PATCH V2 05/46] arm64/sysreg: Add register fields for
 HDFGRTR2_EL2
In-Reply-To: <20241210055311.780688-6-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-6-anshuman.khandual@arm.com>
Message-ID: <4734d430-1d07-41ab-8679-d1fc39cebdf6@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for HDFGRTR2_EL2 as per the definitions based
> on DDI0601 2024-09.
> 
> 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
> Reviewed-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/tools/sysreg | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 10b1a0998d99..a56f7384d0db 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2562,6 +2562,35 @@ Field	1	ICIALLU
>  Field	0	ICIALLUIS
>  EndSysreg
>  
> +Sysreg HDFGRTR2_EL2	3	4	3	1	0
> +Res0	63:25
> +Field	24	nPMBMAR_EL1
> +Field	23	nMDSTEPOP_EL1
> +Field	22	nTRBMPAM_EL1
> +Res0	21
> +Field	20	nTRCITECR_EL1
> +Field	19	nPMSDSFR_EL1
> +Field	18	nSPMDEVAFF_EL1
> +Field	17	nSPMID
> +Field	16	nSPMSCR_EL1
> +Field	15	nSPMACCESSR_EL1
> +Field	14	nSPMCR_EL0
> +Field	13	nSPMOVS
> +Field	12	nSPMINTEN
> +Field	11	nSPMCNTEN
> +Field	10	nSPMSELR_EL0
> +Field	9	nSPMEVTYPERn_EL0
> +Field	8	nSPMEVCNTRn_EL0
> +Field	7	nPMSSCR_EL1
> +Field	6	nPMSSDATA
> +Field	5	nMDSELR_EL1
> +Field	4	nPMUACR_EL1
> +Field	3	nPMICFILTR_EL0
> +Field	2	nPMICNTR_EL0
> +Field	1	nPMIAR_EL1
> +Field	0	nPMECR_EL1
> +EndSysreg
> +
>  Sysreg HDFGRTR_EL2	3	4	3	1	4
>  Field	63	PMBIDR_EL1
>  Field	62	nPMSNEVFR_EL1



From dave.stevenson at raspberrypi.com  Wed Dec 18 06:48:31 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Wed, 18 Dec 2024 14:48:31 +0000
Subject: [PATCH v4 0/3] drm/vc4: Fixup DT and DT binding issues from recent
 patchset
Message-ID: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>

I missed the DT errors from the recent patchset[1] (DT patches
in linux-next via Florian, DRM bindings patches on dri-misc-next)
as Rob's bot report got spam filtered, so this is a fixup set.

Largely it was changes to number of interrupts or clocks in the
bindings, so those are now covered.

I've fixed up the missing "interrupt-controller" flags for 2711
and 2712 whilst here.

I can't get my head around what is meant to happen with ranges:
"soc at 107c000000: firmware: 'ranges' is a required property"
The meaning seems obvious.

However if I add it then I get:
"firmware: '#address-cells', '#size-cells', 'dma-ranges', 'ranges' do
not match any of the regexes: 'pinctrl-[0-9]+'
from schema $id: http://devicetree.org/schemas/arm/bcm/raspberrypi,bcm2835-firmware.yaml#

There's obviously some other flag I need to set in the bindings,
but I can't work it out. We have similar errors for all the Pi
platforms for one or more nodes.
Please advise and I'll happily fix them all.

Thanks
  Dave

[1] https://lore.kernel.org/linux-arm-kernel/20241025-drm-vc4-2712-support-v2-0-35efa83c8fc0 at raspberrypi.com/

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
Changes in v4:
- 1/7 Removed the duplication
- 2/7 Added "minItems: 2" and added to the commit text that the clock
  and interrupt names are required for bcm2712
- 3/7 Already applied by Bartosz, and 5-7/7 applied by Florian
- 4/7 added Krzysztof Acked-by
- Link to v3: https://lore.kernel.org/r/20241212-dt-bcm2712-fixes-v3-0-44a7f3390331 at raspberrypi.com

Thanks Krzysztof for your comments. Terms such as "widest constraints"
may be obvious to those regularly doing dtschemas, but not to me who
does them once in a blue-moon.

Changes in v3:
- Fixed up indentation on 1/7. (I fixed it once, but obviously reworked
  things and lost it).
- Link to v2: https://lore.kernel.org/r/20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4 at raspberrypi.com

Thanks to Stefan and Krzysztof for their reviews.
Hopefully I've addressed all points raised in the correct manner.

Changes in v2:
- Commits have now be merged from drm-misc-next to linux-next, so all
  commit hashes are valid on linux-next.
- 1/7 Removed references to "previous commit". Fixed up indentation.
  Added maxItems
- 2/7 Defined widest constraints
- 3/7 Added maxItems and removed reference to Linux
- 4/7 Described the errors. Split into two for fix of node name vs addr
  being wrong.
- Added new patch removing "required" for interrupt-controller and
  interrupt-cells for bcm2836-l1-intc
- 5/7 (now 7/7) Removed the intc node for 2712 - it's irrelevant on 64bit systems
- 6/7 dropped as updating the binding is the correct answer
- 7/7 dropped. simple-bus claims ranges is required, but adding it
  creates other errors. I'm unclear as to the right solution.

- Link to v1: https://lore.kernel.org/r/20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a at raspberrypi.com

---
Dave Stevenson (3):
      dt-bindings: display: bcm2711-hdmi: Add interrupt details for BCM2712
      dt-bindings: display: Fix BCM2835 HVS bindings for BCM2712
      dt-bindings: interrupt-controller: brcm,bcm2836-l1-intc: Drop interrupt-controller requirement

 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 81 +++++++++++++++++----
 .../bindings/display/brcm,bcm2835-hvs.yaml         | 84 ++++++++++++++++++----
 .../interrupt-controller/brcm,bcm2836-l1-intc.yaml |  2 -
 3 files changed, 137 insertions(+), 30 deletions(-)
---
base-commit: 29978a81e62128d2cee56f066ec92de584f4ab5f
change-id: 20241128-dt-bcm2712-fixes-afb0e8a0a476

Best regards,
-- 
Dave Stevenson <dave.stevenson at raspberrypi.com>



From dave.stevenson at raspberrypi.com  Wed Dec 18 06:48:32 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Wed, 18 Dec 2024 14:48:32 +0000
Subject: [PATCH v4 1/3] dt-bindings: display: bcm2711-hdmi: Add interrupt
 details for BCM2712
In-Reply-To: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
References: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
Message-ID: <20241218-dt-bcm2712-fixes-v4-1-54cc88b6c229@raspberrypi.com>

Commit 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
added the compatible strings for BCM2712, but missed out that the
number of interrupts changed.

Update the schema to include the interrupt requirements.

Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 81 ++++++++++++++++++----
 1 file changed, 67 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
index 6d11f5955b51..83c058728ef1 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
@@ -56,22 +56,12 @@ properties:
       - const: cec
 
   interrupts:
-    items:
-      - description: CEC TX interrupt
-      - description: CEC RX interrupt
-      - description: CEC stuck at low interrupt
-      - description: Wake-up interrupt
-      - description: Hotplug connected interrupt
-      - description: Hotplug removed interrupt
+    minItems: 5
+    maxItems: 6
 
   interrupt-names:
-    items:
-      - const: cec-tx
-      - const: cec-rx
-      - const: cec-low
-      - const: wakeup
-      - const: hpd-connected
-      - const: hpd-removed
+    minItems: 5
+    maxItems: 6
 
   ddc:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -112,6 +102,66 @@ required:
 
 additionalProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - brcm,bcm2711-hdmi0
+              - brcm,bcm2711-hdmi1
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: CEC TX interrupt
+            - description: CEC RX interrupt
+            - description: CEC stuck at low interrupt
+            - description: Wake-up interrupt
+            - description: Hotplug connected interrupt
+            - description: Hotplug removed interrupt
+        interrupt-names:
+          items:
+            - const: cec-tx
+            - const: cec-rx
+            - const: cec-low
+            - const: wakeup
+            - const: hpd-connected
+            - const: hpd-removed
+
+
+      required:
+        - interrupts
+        - interrupt-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - brcm,bcm2712-hdmi0
+              - brcm,bcm2712-hdmi1
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: CEC TX interrupt
+            - description: CEC RX interrupt
+            - description: CEC stuck at low interrupt
+            - description: Hotplug connected interrupt
+            - description: Hotplug removed interrupt
+        interrupts-names:
+          items:
+            - const: cec-tx
+            - const: cec-rx
+            - const: cec-low
+            - const: hpd-connected
+            - const: hpd-removed
+
+      required:
+        - interrupts
+        - interrupt-names
+
 examples:
   - |
     hdmi0: hdmi at 7ef00700 {
@@ -136,6 +186,9 @@ examples:
                     "hd";
         clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
         clock-names = "hdmi", "bvb", "audio", "cec";
+        interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
+        interrupt-names = "cec-tx", "cec-rx", "cec-low", "wakeup",
+                "hpd-connected", "hpd-removed";
         resets = <&dvp 0>;
         ddc = <&ddc0>;
     };

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Wed Dec 18 06:48:33 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Wed, 18 Dec 2024 14:48:33 +0000
Subject: [PATCH v4 2/3] dt-bindings: display: Fix BCM2835 HVS bindings for
 BCM2712
In-Reply-To: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
References: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
Message-ID: <20241218-dt-bcm2712-fixes-v4-2-54cc88b6c229@raspberrypi.com>

Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
added the compatible string for BCM2712, but missed out that
the number of interrupts and clocks changed too, and both need to be
named.

Update to validate clock, interrupts, and their names for the variants.

Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2835-hvs.yaml         | 84 ++++++++++++++++++----
 1 file changed, 70 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
index f91c9dce2a44..fd25ee5ce301 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
@@ -20,11 +20,20 @@ properties:
     maxItems: 1
 
   interrupts:
-    maxItems: 1
+    minItems: 1
+    maxItems: 3
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 3
 
   clocks:
-    maxItems: 1
-    description: Core Clock
+    minItems: 1
+    maxItems: 2
+
+  clock-names:
+    minItems: 1
+    maxItems: 2
 
 required:
   - compatible
@@ -33,17 +42,64 @@ required:
 
 additionalProperties: false
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - brcm,bcm2711-hvs
-          - brcm,bcm2712-hvs
-
-then:
-  required:
-    - clocks
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2711-hvs
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Core Clock
+        interrupts:
+          maxItems: 1
+
+      required:
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2712-hvs
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: core
+            - const: disp
+        interrupts:
+          items:
+            - description: Channel 0 End of frame
+            - description: Channel 1 End of frame
+            - description: Channel 2 End of frame
+        interrupt-names:
+          items:
+            - const: ch0-eof
+            - const: ch1-eof
+            - const: ch2-eof
+      required:
+        - clocks
+        - clock-names
+        - interrupt-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2835-hvs
+
+    then:
+      properties:
+        interrupts:
+          maxItems: 1
 
 examples:
   - |

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Wed Dec 18 06:48:34 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Wed, 18 Dec 2024 14:48:34 +0000
Subject: [PATCH v4 3/3] dt-bindings: interrupt-controller:
 brcm,bcm2836-l1-intc: Drop interrupt-controller requirement
In-Reply-To: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
References: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
Message-ID: <20241218-dt-bcm2712-fixes-v4-3-54cc88b6c229@raspberrypi.com>

Since commit 88bbe85dcd37 ("irqchip: bcm2836: Move SMP startup code to
arch/arm (v2)") the bcm2836-l1-intc block on bcm2711 is only used as a
base address for the smp_boot_secondary hook on 32 bit kernels. It is
not used as an interrupt controller.

Drop the binding requirement for interrupt-controller and interrupt-cells
to satisfy validation on this platform.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml  | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
index 5fda626c80ce..2ff390c1705b 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
@@ -34,8 +34,6 @@ properties:
 required:
   - compatible
   - reg
-  - interrupt-controller
-  - '#interrupt-cells'
 
 additionalProperties: false
 

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Wed Dec 18 06:52:04 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Wed, 18 Dec 2024 14:52:04 +0000
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <20241218-wild-red-manatee-bb2a34@houat>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-vivacious-chameleon-of-swiftness-f1edc4@houat> <CAA8EJprjCyWBNkRrc4W24uCwPtf_kxZLqNeNP8EJffbutYQ21w@mail.gmail.com>
 <20241218-wild-red-manatee-bb2a34@houat>
Message-ID: <CAPY8ntDdcOXuWVgx6+cbgX5ct_-MXcE7CWDKgGP57EX6bvBLaw@mail.gmail.com>

Hi Maxime & Dmitry

On Wed, 18 Dec 2024 at 07:59, Maxime Ripard <mripard at kernel.org> wrote:
>
> On Wed, Dec 18, 2024 at 07:24:23AM +0200, Dmitry Baryshkov wrote:
> > On Tue, 17 Dec 2024 at 19:21, Maxime Ripard <mripard at kernel.org> wrote:
> > > On Tue, Dec 17, 2024 at 02:40:22AM +0200, Dmitry Baryshkov wrote:
> > > > While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
> > > > framework, I stumbled upon an issue while handling the Audio InfoFrames.
> > > > The HDMI codec callbacks weren't receiving the drm_atomic_state, so
> > > > there was no simple way to get the drm_connector that stayed at the end
> > > > of the bridge chain. At the same point the drm_hdmi_connector functions
> > > > expected to get drm_connector instance.
> > > >
> > > > While looking for a way to solve the issue, I stumbled upon several
> > > > deficiencies in existing hdmi_codec_ops implementations. Only few of the
> > > > implementations were able to handle codec's 'plugged' callback. One
> > > > third of the drivers didn't implement the get_eld() callback.
> > > >
> > > > Most of the issues can be solved if drm_connector handles
> > > > hdmi-audio-codec on its own, delegating functionality to the actual
> > > > implementation, be it a driver that implements drm_connector or
> > > > drm_bridge.
> > > >
> > > > Implement such high-level framework, adding proper support for Audio
> > > > InfoFrame generation to the LT9611 driver.
> > > >
> > > > Several design decisions to be kept in mind:
> > > >
> > > > - drm_connector_hdmi_codec is kept as simple as possible. It implements
> > > >   generic functionality (ELD, hotplug, registration).
> > > >
> > > > - drm_hdmi_connector sets up HDMI codec device if the connector
> > > >   is setup correspondingly (either I2S or S/PDIF is marked as
> > > >   supported).
> > > >
> > > > - drm_bridge_connector provides a way to link HDMI audio codec
> > > >   funcionality in the drm_bridge with the drm_connector_hdmi_codec
> > > >   framework.
> > > >
> > > > - It might be worth reverting the no_i2s_capture / no_spdif_capture
> > > >   bits. Only TDA889x driver sets them, while it's safe to assume that
> > > >   most of HDMI / DP devices do not support ARC / capture. I think the
> > > >   drivers should opt-in capture support rather than having to opt-out of
> > > >   it.
> > >
> > > Sorry if this isn't clear to me and I'm quite late to the party, but did
> > > you test this on vc4 with both a pi3 and pi4, or was it just compile
> > > tested?
> >
> > LT9611 is actually tested, VC4 is only compile-tested. Should I put an RFT tag?
>
> Yeah, we definitely need to test it on the pi3 (polling-based) and the
> pi4 (irq-based) at least.
>
> Dave, Maira, could you give it a try?

I'm on it.

  Dave

> Maxime


From svarbanov at suse.de  Wed Dec 18 06:54:57 2024
From: svarbanov at suse.de (Stanimir Varbanov)
Date: Wed, 18 Dec 2024 16:54:57 +0200
Subject: [PATCH v4 06/10] PCI: brcmstb: Enable external MSI-X if available
In-Reply-To: <f0a734d9-6bf6-4d28-b30b-99b6be9f62dc@broadcom.com>
References: <20241025124515.14066-1-svarbanov@suse.de>
 <20241025124515.14066-7-svarbanov@suse.de>
 <f0a734d9-6bf6-4d28-b30b-99b6be9f62dc@broadcom.com>
Message-ID: <ab136131-a306-4344-adaf-904e3b32326e@suse.de>

Hi Jim,

Thanks for comments!

On 12/11/24 10:01 PM, James Quinlan wrote:
> On 10/25/24 08:45, Stanimir Varbanov wrote:
>> On RPi5 there is an external MIP MSI-X interrupt controller
>> which can handle up to 64 interrupts.
>>
>> Signed-off-by: Stanimir Varbanov <svarbanov at suse.de>
>> ---
>> v3 -> v4:
>> ? - no changes.
>>
>> ? drivers/pci/controller/pcie-brcmstb.c | 63 +++++++++++++++++++++++++--
>> ? 1 file changed, 59 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/
>> controller/pcie-brcmstb.c
>> index c01462b07eea..af01a7915c94 100644
>> --- a/drivers/pci/controller/pcie-brcmstb.c
>> +++ b/drivers/pci/controller/pcie-brcmstb.c
>> @@ -1318,6 +1318,52 @@ static int brcm_pcie_start_link(struct
>> brcm_pcie *pcie)
>> ????? return 0;
>> ? }
>> ? +static int brcm_pcie_enable_external_msix(struct brcm_pcie *pcie,
>> +????????????????????? struct device_node *msi_np)
>> +{
>> +??? struct inbound_win inbound_wins[PCIE_BRCM_MAX_INBOUND_WINS];
>> +??? u64 msi_pci_addr, msi_phys_addr;
>> +??? struct resource r;
>> +??? int mip_bar, ret;
>> +??? u32 val, reg;
>> +
>> +??? ret = of_property_read_reg(msi_np, 1, &msi_pci_addr, NULL);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = of_address_to_resource(msi_np, 0, &r);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? msi_phys_addr = r.start;
>> +
>> +??? /* Find free inbound window for MIP access */
>> +??? mip_bar = brcm_pcie_get_inbound_wins(pcie, inbound_wins);
>> +??? if (mip_bar < 0)
>> +??????? return mip_bar;
>> +
>> +??? mip_bar += 1;
>> +??? reg = brcm_bar_reg_offset(mip_bar);
>> +
>> +??? val = lower_32_bits(msi_pci_addr);
>> +??? val |= brcm_pcie_encode_ibar_size(SZ_4K);
>> +??? writel(val, pcie->base + reg);
>> +
>> +??? val = upper_32_bits(msi_pci_addr);
>> +??? writel(val, pcie->base + reg + 4);
>> +
>> +??? reg = brcm_ubus_reg_offset(mip_bar);
>> +
>> +??? val = lower_32_bits(msi_phys_addr);
>> +??? val |= PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_ACCESS_EN_MASK;
>> +??? writel(val, pcie->base + reg);
>> +
>> +??? val = upper_32_bits(msi_phys_addr);
>> +??? writel(val, pcie->base + reg + 4);
> 
> Hi Stan,
> 
> It looks like all this is doing is setting up an identity-mapped inbound
> window, is that correct?? If so, couldn't you get the same effect by
> adding an identity-mapped dma-range in the PCIe DT node?

Yes, that approach could work, I verified it.

Do you want me to drop this patch from the series and make the relevant
changes in PCIe dma-ranges properties?

~Stan





From conor at kernel.org  Wed Dec 18 07:08:28 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 15:08:28 +0000
Subject: [PATCH 07/17] riscv: vdso: Switch to generic storage
 implementation
In-Reply-To: <20241216-vdso-store-rng-v1-7-f7aed1bdb3b2@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-7-f7aed1bdb3b2@linutronix.de>
Message-ID: <20241218-action-matchbook-571b597b7f55@spud>

On Mon, Dec 16, 2024 at 03:10:03PM +0100, Thomas Wei?schuh wrote:
> The generic storage implementation provides the same features as the
> custom one. However it can be shared between architectures, making
> maintenance easier.
> 
> Co-developed-by: Nam Cao <namcao at linutronix.de>
> Signed-off-by: Nam Cao <namcao at linutronix.de>
> Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
> ---
>  arch/riscv/Kconfig                                 |  3 +-
>  arch/riscv/include/asm/vdso.h                      |  2 +-
>  .../include/asm/vdso/{time_data.h => arch_data.h}  |  8 +-
>  arch/riscv/include/asm/vdso/gettimeofday.h         | 14 +---
>  arch/riscv/include/asm/vdso/vsyscall.h             |  9 ---
>  arch/riscv/kernel/sys_hwprobe.c                    |  3 +-
>  arch/riscv/kernel/vdso.c                           | 90 +---------------------
>  arch/riscv/kernel/vdso/hwprobe.c                   |  6 +-
>  arch/riscv/kernel/vdso/vdso.lds.S                  |  7 +-
>  9 files changed, 18 insertions(+), 124 deletions(-)

Fails to build:
Patch 7/17: Test 1/12: .github/scripts/patches/tests/build_rv32_defconfig.sh
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:11:33: warning: declaration of 'struct riscv_hwprobe' will not be visible outside of this function [-Wvisibility]
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:15:41: warning: declaration of 'struct riscv_hwprobe' will not be visible outside of this function [-Wvisibility]
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:19:37: error: call to undeclared function '__arch_get_vdso_u_arch_data'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:19:31: error: incompatible integer to pointer conversion initializing 'const struct vdso_arch_data *' with an expression of type 'int' [-Wint-conversion]
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:22:36: error: arithmetic on a pointer to an incomplete type 'struct riscv_hwprobe'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:30:40: error: incomplete definition of type 'const struct vdso_arch_data'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:31:24: error: incompatible pointer types passing 'struct riscv_hwprobe *' to parameter of type 'struct riscv_hwprobe *' [-Werror,-Wincompatible-pointer-types]
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:35:7: error: call to undeclared function 'riscv_hwprobe_key_is_valid'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:35:35: error: incomplete definition of type 'struct riscv_hwprobe'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:36:5: error: incomplete definition of type 'struct riscv_hwprobe'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:36:18: error: incomplete definition of type 'const struct vdso_arch_data'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:36:44: error: incomplete definition of type 'struct riscv_hwprobe'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:39:5: error: incomplete definition of type 'struct riscv_hwprobe'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:40:5: error: incomplete definition of type 'struct riscv_hwprobe'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:43:4: error: arithmetic on a pointer to an incomplete type 'struct riscv_hwprobe'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:49:39: warning: declaration of 'struct riscv_hwprobe' will not be visible outside of this function [-Wvisibility]
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:53:37: error: call to undeclared function '__arch_get_vdso_u_arch_data'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:53:31: error: incompatible integer to pointer conversion initializing 'const struct vdso_arch_data *' with an expression of type 'int' [-Wint-conversion]
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:55:36: error: arithmetic on a pointer to an incomplete type 'struct riscv_hwprobe'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:71:61: error: incomplete definition of type 'const struct vdso_arch_data'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:71:29: error: use of undeclared identifier 'RISCV_HWPROBE_WHICH_CPUS'
  /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:72:24: error: incompatible pointer types passing 'struct riscv_hwprobe *' to parameter of type 'struct riscv_hwprobe *' [-Werror,-Wincompatible-pointer-types]
  fatal error: too many errors emitted, stopping now [-ferror-limit=]

Might be a clang thing, allmodconfig with clang doesn't build either.
-------------- 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/20241218/e19b53c6/attachment.sig>

From linux at roeck-us.net  Wed Dec 18 07:09:30 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 18 Dec 2024 07:09:30 -0800
Subject: [PATCH v4 1/4] hwmon: (pmbus/core) Add PMBUS_REVISION in debugfs
In-Reply-To: <20241217173537.192331-2-ninad@linux.ibm.com>
References: <20241217173537.192331-1-ninad@linux.ibm.com>
 <20241217173537.192331-2-ninad@linux.ibm.com>
Message-ID: <89ff7229-2e86-4d36-9349-50af109b0085@roeck-us.net>

On Tue, Dec 17, 2024 at 11:35:32AM -0600, Ninad Palsule wrote:
> Add debugfs file for the PMBUS_REVISION command. This command provides
> information about PMBus protocol revision number.
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>

I already applied this patch, so there is no need to re-send it.
If it turns out to have a bug, please send an update on top of it.

Thanks,
Guenter


From eauger at redhat.com  Wed Dec 18 07:11:39 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:11:39 +0100
Subject: [PATCH V2 06/46] arm64/sysreg: Add register fields for
 HDFGWTR2_EL2
In-Reply-To: <20241210055311.780688-7-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-7-anshuman.khandual@arm.com>
Message-ID: <8df1140d-5364-4979-b572-127067b18f90@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for HDFGWTR2_EL2 as per the definitions based
> on DDI0601 2024-09.
> 
> 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
> Reviewed-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/tools/sysreg | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index a56f7384d0db..1a7d8c03f844 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2591,6 +2591,34 @@ Field	1	nPMIAR_EL1
>  Field	0	nPMECR_EL1
>  EndSysreg
>  
> +Sysreg HDFGWTR2_EL2	3	4	3	1	1
> +Res0	63:25
> +Field	24	nPMBMAR_EL1
> +Field	23	nMDSTEPOP_EL1
> +Field	22	nTRBMPAM_EL1
> +Field	21	nPMZR_EL0
> +Field	20	nTRCITECR_EL1
> +Field	19	nPMSDSFR_EL1
> +Res0	18:17
> +Field	16	nSPMSCR_EL1
> +Field	15	nSPMACCESSR_EL1
> +Field	14	nSPMCR_EL0
> +Field	13	nSPMOVS
> +Field	12	nSPMINTEN
> +Field	11	nSPMCNTEN
> +Field	10	nSPMSELR_EL0
> +Field	9	nSPMEVTYPERn_EL0
> +Field	8	nSPMEVCNTRn_EL0
> +Field	7	nPMSSCR_EL1
> +Res0	6
> +Field	5	nMDSELR_EL1
> +Field	4	nPMUACR_EL1
> +Field	3	nPMICFILTR_EL0
> +Field	2	nPMICNTR_EL0
> +Field	1	nPMIAR_EL1
> +Field	0	nPMECR_EL1
> +EndSysreg
> +
>  Sysreg HDFGRTR_EL2	3	4	3	1	4
>  Field	63	PMBIDR_EL1
>  Field	62	nPMSNEVFR_EL1



From angelogioacchino.delregno at collabora.com  Wed Dec 18 07:12:45 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 16:12:45 +0100
Subject: [PATCH] drm/mediatek: stop selecting foreign drivers
In-Reply-To: <1d8c6f65-5baa-459e-ba34-4e45ca20baf6@app.fastmail.com>
References: <20241218085837.2670434-1-arnd@kernel.org>
 <46f871e3-bb1e-4bee-95f3-2121c6a6eef7@collabora.com>
 <1d8c6f65-5baa-459e-ba34-4e45ca20baf6@app.fastmail.com>
Message-ID: <db89c62e-5346-4e46-b6b3-6cc6b3e5a256@collabora.com>

Il 18/12/24 12:44, Arnd Bergmann ha scritto:
> On Wed, Dec 18, 2024, at 11:50, AngeloGioacchino Del Regno wrote:
>> Il 18/12/24 09:58, Arnd Bergmann ha scritto:
>>> From: Arnd Bergmann <arnd at arndb.de>
>>
>> The problem is - no PHY no party, it's not going to work without... but
>> I get the
>> reasons behind this change.
>>
>> Are we sure that we can't just add a `depends on PHY_MTK_xxxx` (or extend
>> depends on DRM_MEDIATEK && PHY_MTK_xxx)?
> 
> Doing this wouldn't cause any problems, but it also doesn't
> really help much, you just have to know which devices are
> present and enable all their drivers anyway.
> 
> We used to just select all drivers from arch/arm/mach-*/Kconfig
> on some older platforms, but this was too much of a hassle.
> 
>        Arnd

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From csokas.bence at prolan.hu  Wed Dec 18 07:17:54 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?=)
Date: Wed, 18 Dec 2024 16:17:54 +0100
Subject: [PATCH] spi: atmel-quadspi: Factor out switching to Serial Memory Mode to function
Message-ID: <20241218151754.365519-1-csokas.bence@prolan.hu>

SAMA7G5 support (that was forward-ported from v6.1) re-introduced
a bug that was fixed in v6.12, thankfully only in the codepath of
the new SoC. But to prevent similar mistakes in the future, we
split out the offending code to a function, and use this, fixed
version everywhere.

To facilitate this, support function `atmel_qspi_update_config()`
also had to be moved upwards. For best viewing experience, use
`--color-moved-ws="allow-indentation-change" --color-moved`.

Fixes: 5af42209a4d2 ("spi: atmel-quadspi: Add support for sama7g5 QSPI")
Reported-by: Alexander Dahl <ada at thorsis.com>
Closes: https://lore.kernel.org/linux-spi/20241218-appliance-jaws-90773405977a at thorsis.com/
Signed-off-by: Bence Cs?k?s <csokas.bence at prolan.hu>
---
 drivers/spi/atmel-quadspi.c | 101 +++++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 48 deletions(-)

diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index 73cf0c3f1477..f46da363574f 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -414,6 +414,28 @@ static void atmel_qspi_write(u32 value, struct atmel_qspi *aq, u32 offset)
 	writel_relaxed(value, aq->regs + offset);
 }
 
+static int atmel_qspi_reg_sync(struct atmel_qspi *aq)
+{
+	u32 val;
+	int ret;
+
+	ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
+				 !(val & QSPI_SR2_SYNCBSY), 40,
+				 ATMEL_QSPI_SYNC_TIMEOUT);
+	return ret;
+}
+
+static int atmel_qspi_update_config(struct atmel_qspi *aq)
+{
+	int ret;
+
+	ret = atmel_qspi_reg_sync(aq);
+	if (ret)
+		return ret;
+	atmel_qspi_write(QSPI_CR_UPDCFG, aq, QSPI_CR);
+	return atmel_qspi_reg_sync(aq);
+}
+
 static inline bool atmel_qspi_is_compatible(const struct spi_mem_op *op,
 					    const struct atmel_qspi_mode *mode)
 {
@@ -476,6 +498,25 @@ static bool atmel_qspi_supports_op(struct spi_mem *mem,
 	return true;
 }
 
+/*
+ * If the QSPI controller is set in regular SPI mode, set it in
+ * Serial Memory Mode (SMM).
+ */
+static int atmel_qspi_set_serial_memory_mode(struct atmel_qspi *aq)
+{
+	int ret = 0;
+
+	if (!(aq->mr & QSPI_MR_SMM)) {
+		aq->mr |= QSPI_MR_SMM;
+		atmel_qspi_write(aq->mr, aq, QSPI_MR);
+
+		if (aq->caps->has_gclk)
+			ret = atmel_qspi_update_config(aq);
+	}
+
+	return ret;
+}
+
 static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
 			      const struct spi_mem_op *op, u32 *offset)
 {
@@ -555,14 +596,9 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
 			ifr |= QSPI_IFR_TFRTYP_MEM;
 	}
 
-	/*
-	 * If the QSPI controller is set in regular SPI mode, set it in
-	 * Serial Memory Mode (SMM).
-	 */
-	if (!(aq->mr & QSPI_MR_SMM)) {
-		aq->mr |= QSPI_MR_SMM;
-		atmel_qspi_write(aq->mr, aq, QSPI_MR);
-	}
+	mode = atmel_qspi_set_serial_memory_mode(aq);
+	if (mode < 0)
+		return mode;
 
 	/* Clear pending interrupts */
 	(void)atmel_qspi_read(aq, QSPI_SR);
@@ -638,28 +674,6 @@ static int atmel_qspi_transfer(struct spi_mem *mem,
 	return atmel_qspi_wait_for_completion(aq, QSPI_SR_CMD_COMPLETED);
 }
 
-static int atmel_qspi_reg_sync(struct atmel_qspi *aq)
-{
-	u32 val;
-	int ret;
-
-	ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
-				 !(val & QSPI_SR2_SYNCBSY), 40,
-				 ATMEL_QSPI_SYNC_TIMEOUT);
-	return ret;
-}
-
-static int atmel_qspi_update_config(struct atmel_qspi *aq)
-{
-	int ret;
-
-	ret = atmel_qspi_reg_sync(aq);
-	if (ret)
-		return ret;
-	atmel_qspi_write(QSPI_CR_UPDCFG, aq, QSPI_CR);
-	return atmel_qspi_reg_sync(aq);
-}
-
 static int atmel_qspi_sama7g5_set_cfg(struct atmel_qspi *aq,
 				      const struct spi_mem_op *op, u32 *offset)
 {
@@ -713,18 +727,9 @@ static int atmel_qspi_sama7g5_set_cfg(struct atmel_qspi *aq,
 			ifr |= QSPI_IFR_TFRTYP_MEM;
 	}
 
-	/*
-	 * If the QSPI controller is set in regular SPI mode, set it in
-	 * Serial Memory Mode (SMM).
-	 */
-	if (aq->mr != QSPI_MR_SMM) {
-		atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR);
-		aq->mr = QSPI_MR_SMM;
-
-		ret = atmel_qspi_update_config(aq);
-		if (ret)
-			return ret;
-	}
+	ret = atmel_qspi_set_serial_memory_mode(aq);
+	if (ret < 0)
+		return ret;
 
 	/* Clear pending interrupts */
 	(void)atmel_qspi_read(aq, QSPI_SR);
@@ -1092,10 +1097,9 @@ static int atmel_qspi_sama7g5_init(struct atmel_qspi *aq)
 	}
 
 	/* Set the QSPI controller by default in Serial Memory Mode */
-	atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR);
-	aq->mr = QSPI_MR_SMM;
-	ret = atmel_qspi_update_config(aq);
-	if (ret)
+	aq->mr |= QSPI_MR_DQSDLYEN;
+	ret = atmel_qspi_set_serial_memory_mode(aq);
+	if (ret < 0)
 		return ret;
 
 	/* Enable the QSPI controller. */
@@ -1244,8 +1248,9 @@ static int atmel_qspi_init(struct atmel_qspi *aq)
 	atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR);
 
 	/* Set the QSPI controller by default in Serial Memory Mode */
-	aq->mr |= QSPI_MR_SMM;
-	atmel_qspi_write(aq->mr, aq, QSPI_MR);
+	ret = atmel_qspi_set_serial_memory_mode(aq);
+	if (ret < 0)
+		return ret;
 
 	/* Enable the QSPI controller */
 	atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR);
-- 
2.34.1




From linux at roeck-us.net  Wed Dec 18 07:14:13 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 18 Dec 2024 07:14:13 -0800
Subject: [PATCH v4 3/4] dt-bindings: hwmon: intel,crps185: Add to trivial
In-Reply-To: <20241217173537.192331-4-ninad@linux.ibm.com>
References: <20241217173537.192331-1-ninad@linux.ibm.com>
 <20241217173537.192331-4-ninad@linux.ibm.com>
Message-ID: <4f8c8445-0d98-4905-8cc3-752dba3ec11b@roeck-us.net>

On Tue, Dec 17, 2024 at 11:35:34AM -0600, Ninad Palsule wrote:
> Add INTEL Common Redundant Power Supply Versions crps185 bindings as
> trivial. The hardware does not have any resources like clocks which are
> required to be included in the device tree.
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>

Applied.

In the future, please base your patches on a well known baseline.
I had to apply it manually since "git am -3" didn't work.

Thanks,
Guenter


From linux at roeck-us.net  Wed Dec 18 07:15:09 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 18 Dec 2024 07:15:09 -0800
Subject: [PATCH v4 2/4] hwmon: (pmbus/crps) Add Intel CRPS185 power supply
In-Reply-To: <20241217173537.192331-3-ninad@linux.ibm.com>
References: <20241217173537.192331-1-ninad@linux.ibm.com>
 <20241217173537.192331-3-ninad@linux.ibm.com>
Message-ID: <3c7d8856-d58c-4ac2-84fe-7a7374fdddc8@roeck-us.net>

On Tue, Dec 17, 2024 at 11:35:33AM -0600, Ninad Palsule wrote:
> Add the driver to monitor Intel common redundant power supply (crps185)
> with hwmon over pmbus.
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>

Applied.

Thanks,
Guenter


From linux at roeck-us.net  Wed Dec 18 07:16:18 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 18 Dec 2024 07:16:18 -0800
Subject: [PATCH v4 4/4] ARM: dts: aspeed: system1: Use crps PSU driver
In-Reply-To: <20241217173537.192331-5-ninad@linux.ibm.com>
References: <20241217173537.192331-1-ninad@linux.ibm.com>
 <20241217173537.192331-5-ninad@linux.ibm.com>
Message-ID: <d3de9f99-1cc2-491e-8dac-1a5d243e17f0@roeck-us.net>

On Tue, Dec 17, 2024 at 11:35:35AM -0600, Ninad Palsule wrote:
> The system1 uses Intel common redundant (crps185) power supplies so move
> to correct new crps driver.
> 
> Signed-off-by: Ninad Palsule <ninad at linux.ibm.com>

Acked-by: Guenter Roeck <linux at roeck-us.net>

This patch will need to be applied through an arm tree.

Thanks,
Guenter


From eauger at redhat.com  Wed Dec 18 07:17:18 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:17:18 +0100
Subject: [PATCH V2 07/46] arm64/sysreg: Add register fields for
 HFGITR2_EL2
In-Reply-To: <20241210055311.780688-8-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-8-anshuman.khandual@arm.com>
Message-ID: <53889259-fc3e-46a2-9dc9-1aa7cd36e953@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for HFGITR2_EL2 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 1a7d8c03f844..9d339f735648 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2791,6 +2791,12 @@ Field	1	AMEVCNTR00_EL0
>  Field	0	AMCNTEN0
>  EndSysreg
>  
> +Sysreg	HFGITR2_EL2	3	4	3	1	7
> +Res0	63:2
> +Field	1	nDCCIVAPS
> +Field	0	TSBCSYNC
> +EndSysreg
> +
>  Sysreg	ZCR_EL2	3	4	1	2	0
>  Fields	ZCR_ELx
>  EndSysreg



From eauger at redhat.com  Wed Dec 18 07:17:20 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:17:20 +0100
Subject: [PATCH V2 07/46] arm64/sysreg: Add register fields for
 HFGITR2_EL2
In-Reply-To: <20241210055311.780688-8-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-8-anshuman.khandual@arm.com>
Message-ID: <f6f7ab18-1bfc-4f38-a48a-afebed370a44@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for HFGITR2_EL2 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 1a7d8c03f844..9d339f735648 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2791,6 +2791,12 @@ Field	1	AMEVCNTR00_EL0
>  Field	0	AMCNTEN0
>  EndSysreg
>  
> +Sysreg	HFGITR2_EL2	3	4	3	1	7
> +Res0	63:2
> +Field	1	nDCCIVAPS
> +Field	0	TSBCSYNC
> +EndSysreg
> +
>  Sysreg	ZCR_EL2	3	4	1	2	0
>  Fields	ZCR_ELx
>  EndSysreg



From eauger at redhat.com  Wed Dec 18 07:19:21 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:19:21 +0100
Subject: [PATCH V2 08/46] arm64/sysreg: Add register fields for
 HFGRTR2_EL2
In-Reply-To: <20241210055311.780688-9-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-9-anshuman.khandual@arm.com>
Message-ID: <287abeb0-8660-49b0-bf69-97eaa5bbe6a2@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for HFGRTR2_EL2 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 9d339f735648..9513ae05dc93 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2619,6 +2619,25 @@ Field	1	nPMIAR_EL1
>  Field	0	nPMECR_EL1
>  EndSysreg
>  
> +Sysreg	HFGRTR2_EL2	3	4	3	1	2
> +Res0	63:15
> +Field	14	nACTLRALIAS_EL1
> +Field	13	nACTLRMASK_EL1
> +Field	12	nTCR2ALIAS_EL1
> +Field	11	nTCRALIAS_EL1
> +Field	10	nSCTLRALIAS2_EL1
> +Field	9	nSCTLRALIAS_EL1
> +Field	8	nCPACRALIAS_EL1
> +Field	7	nTCR2MASK_EL1
> +Field	6	nTCRMASK_EL1
> +Field	5	nSCTLR2MASK_EL1
> +Field	4	nSCTLRMASK_EL1
> +Field	3	nCPACRMASK_EL1
> +Field	2	nRCWSMASK_EL1
> +Field	1	nERXGSR_EL1
> +Field	0	nPFAR_EL1
> +EndSysreg
> +
>  Sysreg HDFGRTR_EL2	3	4	3	1	4
>  Field	63	PMBIDR_EL1
>  Field	62	nPMSNEVFR_EL1



From eauger at redhat.com  Wed Dec 18 07:22:41 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:22:41 +0100
Subject: [PATCH V2 09/46] arm64/sysreg: Add register fields for
 HFGWTR2_EL2
In-Reply-To: <20241210055311.780688-10-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-10-anshuman.khandual@arm.com>
Message-ID: <b77f9c33-0161-4891-b3cc-a629c6380e63@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for HFGWTR2_EL2 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 9513ae05dc93..30a0d3ee71a7 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2638,6 +2638,25 @@ Field	1	nERXGSR_EL1
>  Field	0	nPFAR_EL1
>  EndSysreg
>  
> +Sysreg	HFGWTR2_EL2	3	4	3	1	3
> +Res0	63:15
> +Field	14	nACTLRALIAS_EL1
> +Field	13	nACTLRMASK_EL1
> +Field	12	nTCR2ALIAS_EL1
> +Field	11	nTCRALIAS_EL1
> +Field	10	nSCTLRALIAS2_EL1
> +Field	9	nSCTLRALIAS_EL1
> +Field	8	nCPACRALIAS_EL1
> +Field	7	nTCR2MASK_EL1
> +Field	6	nTCRMASK_EL1
> +Field	5	nSCTLR2MASK_EL1
> +Field	4	nSCTLRMASK_EL1
> +Field	3	nCPACRMASK_EL1
> +Field	2	nRCWSMASK_EL1
> +Res0	1
> +Field	0	nPFAR_EL1
> +EndSysreg
> +
>  Sysreg HDFGRTR_EL2	3	4	3	1	4
>  Field	63	PMBIDR_EL1
>  Field	62	nPMSNEVFR_EL1



From YeoReum.Yun at arm.com  Wed Dec 18 07:22:33 2024
From: YeoReum.Yun at arm.com (Yeo Reum Yun)
Date: Wed, 18 Dec 2024 15:22:33 +0000
Subject: [PATCH v2 0/9] coresight: change some driver' spinlock type to
 raw_spinlock_t
In-Reply-To: <CAJ9a7Vis9vcdJOzu9tvNQ4eAacmXkbhbZBaRYd1acOrd8G-ZUQ@mail.gmail.com>
References: <20241203114942.697188-1-yeoreum.yun@arm.com>
 <CAJ9a7Vis9vcdJOzu9tvNQ4eAacmXkbhbZBaRYd1acOrd8G-ZUQ@mail.gmail.com>
Message-ID: <GV1PR08MB1052108680D14C3AD04282270FB052@GV1PR08MB10521.eurprd08.prod.outlook.com>

Hi Mike.

> etm3x - which provides support for ETMv3 and PTM, both of which are
> valid trace sources in the cs_etm handling code.
> stm - can be integrated into the kernel STM via configfs providing a
> MIPI source for ftrace.

about etm3x, I have a the same opinion with James.

But, In case of STM, Is it enabled via perf interface?
The cs devices which could be called in perf patch were changed but not for cs devices which never used via perf.

Am I missing?

Thanks.

________________________________________
From: Mike Leach <mike.leach at linaro.org>
Sent: 18 December 2024 13:44
To: Yeo Reum Yun
Cc: Suzuki Poulose; james.clark at linaro.org; alexander.shishkin at linux.intel.com; bigeasy at linutronix.de; clrkwllms at kernel.org; rostedt at goodmis.org; coresight at lists.linaro.org; linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; linux-rt-devel at lists.linux.dev; nd
Subject: Re: [PATCH v2 0/9] coresight: change some driver' spinlock type to raw_spinlock_t

This change seems to omit devices:

etm3x - which provides support for ETMv3 and PTM, both of which are
valid trace sources in the cs_etm handling code.
stm - can be integrated into the kernel STM via configfs providing a
MIPI source for ftrace.

Mike

On Tue, 3 Dec 2024 at 11:49, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In some coresight drivers, drvdata->spinlock can be held during __schedule()
> by perf_event_task_sched_out()/in().
>
> Since drvdata->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this,change type drvdata->spinlock in some coresight drivers,
> which can be called by perf_event_task_sched_out()/in(),
> from spinlock_t to raw_spinlock_t.
>
> Reviewed-by: James Clark <james.clark at linaro.org>
>
> v1 to v2:
>     - seperate patchsets to change locktype and apply gurad API.
>
> Levi Yun (9):
>   coresight: change coresight_device lock type to raw_spinlock_t
>   coresight-etm4x: change etmv4_drvdata spinlock type to raw_spinlock_t
>   coresight: change coresight_trace_id_map's lock type to raw_spinlock_t
>   coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
>   coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
>   coresight-funnel: change funnel_drvdata spinlock's type to
>     raw_spinlock_t
>   coresight-replicator: change replicator_drvdata spinlock's type to
>     raw_spinlock_t
>   coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
>   coresight/ultrasoc: change cti_drvdata spinlock's type to
>     raw_spinlock_t
>
>  .../hwtracing/coresight/coresight-config.c    |  21 +-
>  .../hwtracing/coresight/coresight-config.h    |   2 +-
>  drivers/hwtracing/coresight/coresight-core.c  |   2 +-
>  .../hwtracing/coresight/coresight-cti-core.c  |  65 +-
>  .../hwtracing/coresight/coresight-cti-sysfs.c | 135 +++--
>  drivers/hwtracing/coresight/coresight-cti.h   |   2 +-
>  drivers/hwtracing/coresight/coresight-etb10.c |  62 +-
>  .../coresight/coresight-etm4x-core.c          |  71 ++-
>  .../coresight/coresight-etm4x-sysfs.c         | 566 +++++++++---------
>  drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
>  .../hwtracing/coresight/coresight-funnel.c    |  34 +-
>  .../coresight/coresight-replicator.c          |  36 +-
>  .../hwtracing/coresight/coresight-syscfg.c    |  75 ++-
>  .../hwtracing/coresight/coresight-tmc-core.c  |   9 +-
>  .../hwtracing/coresight/coresight-tmc-etf.c   | 195 +++---
>  .../hwtracing/coresight/coresight-tmc-etr.c   | 199 +++---
>  drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
>  .../hwtracing/coresight/coresight-trace-id.c  |  93 ++-
>  drivers/hwtracing/coresight/ultrasoc-smb.c    |  12 +-
>  drivers/hwtracing/coresight/ultrasoc-smb.h    |   2 +-
>  include/linux/coresight.h                     |   4 +-
>  21 files changed, 751 insertions(+), 838 deletions(-)
>
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From eauger at redhat.com  Wed Dec 18 07:25:13 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:25:13 +0100
Subject: [PATCH V2 10/46] arm64/sysreg: Add register fields for MDSELR_EL1
In-Reply-To: <20241210055311.780688-11-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-11-anshuman.khandual@arm.com>
Message-ID: <b92db5c5-199f-406f-83d4-9d694701359f@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for MDSELR_EL1 as per the definitions based
> on DDI0601 2024-09.
> 
> 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
> Reviewed-by: Mark Brown <broonie at kernel.org>
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 30a0d3ee71a7..be0091060350 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -93,6 +93,17 @@ Res0	63:32
>  Field	31:0	DTRTX
>  EndSysreg
>  
> +Sysreg	MDSELR_EL1	2	0	0	4	2
> +Res0	63:6
> +Enum	5:4	BANK
> +	0b00	BANK_0
> +	0b01	BANK_1
> +	0b10	BANK_2
> +	0b11	BANK_3
> +EndEnum
> +Res0	3:0
> +EndSysreg
> +
>  Sysreg	OSECCR_EL1	2	0	0	6	2
>  Res0	63:32
>  Field	31:0	EDECCR



From eauger at redhat.com  Wed Dec 18 07:28:34 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:28:34 +0100
Subject: [PATCH V2 11/46] arm64/sysreg: Add register fields for PMSIDR_EL1
In-Reply-To: <20241210055311.780688-12-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-12-anshuman.khandual@arm.com>
Message-ID: <a7988236-eb81-406d-a74a-5ad1355981e3@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for PMSIDR_EL1 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index be0091060350..a5e31e4c4474 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2172,7 +2172,16 @@ Field	15:0	MINLAT
>  EndSysreg
>  
>  Sysreg	PMSIDR_EL1	3	0	9	9	7
> -Res0	63:25
> +Res0	63:33
> +Field	32	SME
> +UnsignedEnum	31:28	ALTCLK
> +	0b0000	NI
> +	0b0001	IMP
> +	0b1111	IMP_DEF
> +EndEnum
> +Field	27	FPF
> +Field	26	EFT
> +Field	25	CRR
>  Field	24	PBT
>  Field	23:20	FORMAT
>  Enum	19:16	COUNTSIZE
> @@ -2190,7 +2199,10 @@ Enum	11:8	INTERVAL
>  	0b0111	3072
>  	0b1000	4096
>  EndEnum
> -Res0	7
> +UnsignedEnum	7	FDS
> +	0b0	NI
> +	0b1	IMP
> +EndEnum
>  Field	6	FnE
>  Field	5	ERND
>  Field	4	LDS



From frieder at fris.de  Wed Dec 18 07:27:31 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:31 +0100
Subject: [PATCH v3 8/9] arm64: dts: imx93-kontron: Fix SD card IO voltage control
In-Reply-To: <20241218152842.97483-1-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
Message-ID: <20241218152842.97483-9-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

The OSM-S i.MX93 SoM doesn't have the VSELECT signal of the USDHC
controller connected to the PMICs SD_VSEL input. Instead SD_VSEL
is hardwired to low level. Let the driver know this in order to
use the proper register for reading and writing the voltage level.

This fixes SD card access with the latest hardware revision of
the Kontron OSM-S i.MX93 SoM.

Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
Changes for v3:
* Rebase to next-20241218

Changes for v2:
* new patch
---
 arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
index 47c1363a2f99a..119a162070596 100644
--- a/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
@@ -189,6 +189,7 @@ reg_nvcc_sd: LDO5 {
 				regulator-name = "NVCC_SD (LDO5)";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3300000>;
+				nxp,sd-vsel-fixed-low;
 			};
 		};
 	};
@@ -282,6 +283,7 @@ &usdhc2 { /* OSM-S SDIO_A */
 	pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
 	pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
 	vmmc-supply = <&reg_usdhc2_vcc>;
+	vqmmc-supply = <&reg_nvcc_sd>;
 	cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
 };
 
@@ -553,7 +555,6 @@ MX93_PAD_SD2_DATA0__USDHC2_DATA0		0x40001382 /* SDIO_A_D0 */
 			MX93_PAD_SD2_DATA1__USDHC2_DATA1		0x40001382 /* SDIO_A_D1 */
 			MX93_PAD_SD2_DATA2__USDHC2_DATA2		0x40001382 /* SDIO_A_D2 */
 			MX93_PAD_SD2_DATA3__USDHC2_DATA3		0x40001382 /* SDIO_A_D3 */
-			MX93_PAD_SD2_VSELECT__USDHC2_VSELECT		0x1d0
 		>;
 	};
 
@@ -565,7 +566,6 @@ MX93_PAD_SD2_DATA0__USDHC2_DATA0		0x4000138e /* SDIO_A_D0 */
 			MX93_PAD_SD2_DATA1__USDHC2_DATA1		0x4000138e /* SDIO_A_D1 */
 			MX93_PAD_SD2_DATA2__USDHC2_DATA2		0x4000138e /* SDIO_A_D2 */
 			MX93_PAD_SD2_DATA3__USDHC2_DATA3		0x4000138e /* SDIO_A_D3 */
-			MX93_PAD_SD2_VSELECT__USDHC2_VSELECT		0x1d0
 		>;
 	};
 
@@ -577,7 +577,6 @@ MX93_PAD_SD2_DATA0__USDHC2_DATA0		0x400013fe /* SDIO_A_D0 */
 			MX93_PAD_SD2_DATA1__USDHC2_DATA1		0x400013fe /* SDIO_A_D1 */
 			MX93_PAD_SD2_DATA2__USDHC2_DATA2		0x400013fe /* SDIO_A_D2 */
 			MX93_PAD_SD2_DATA3__USDHC2_DATA3		0x400013fe /* SDIO_A_D3 */
-			MX93_PAD_SD2_VSELECT__USDHC2_VSELECT		0x1d0
 		>;
 	};
 
-- 
2.47.1



From frieder at fris.de  Wed Dec 18 07:27:32 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:32 +0100
Subject: [PATCH v3 9/9] arm64: dts: imx8mp-kontron: Add support for reading SD_VSEL signal
In-Reply-To: <20241218152842.97483-1-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
Message-ID: <20241218152842.97483-10-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

This fixes the LDO5 regulator handling of the pca9450 driver by
taking the status of the SD_VSEL into account to determine which
configuration register is used for the voltage setting.

Even without this change there is no functional issue, as the code
for switching the voltage in sdhci.c currently switches both, the
VSELECT/SD_VSEL signal and the regulator voltage at the same time
and doesn't run into an invalid corner case.

We should still make sure, that we always use the correct register
when controlling the regulator. At least in U-Boot this fixes an
actual bug where the wrong IO voltage is used and it makes sure
that the correct voltage can be read from sysfs.

Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
Changes for v3:
* Rebase to next-20241218

Changes for v2:
* new patch
---
 arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi
index e0e9f6f7616d9..b97bfeb1c30f8 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi
@@ -311,6 +311,7 @@ reg_nvcc_sd: LDO5 {
 				regulator-name = "NVCC_SD (LDO5)";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3300000>;
+				sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
 			};
 		};
 	};
@@ -808,7 +809,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0		0x1d0 /* SDIO_A_D0 */
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1		0x1d0 /* SDIO_A_D1 */
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2		0x1d0 /* SDIO_A_D2 */
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3		0x1d0 /* SDIO_A_D3 */
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT		0x1d0
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT		0x400001d0
 		>;
 	};
 
@@ -820,7 +821,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0		0x1d4 /* SDIO_A_D0 */
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1		0x1d4 /* SDIO_A_D1 */
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2		0x1d4 /* SDIO_A_D2 */
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3		0x1d4 /* SDIO_A_D3 */
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT		0x1d0
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT		0x400001d0
 		>;
 	};
 
@@ -832,7 +833,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0		0x1d6 /* SDIO_A_D0 */
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1		0x1d6 /* SDIO_A_D1 */
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2		0x1d6 /* SDIO_A_D2 */
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3		0x1d6 /* SDIO_A_D3 */
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT		0x1d0
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT		0x400001d0
 		>;
 	};
 
-- 
2.47.1



From eauger at redhat.com  Wed Dec 18 07:30:32 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:30:32 +0100
Subject: [PATCH V2 12/46] arm64/sysreg: Add register fields for
 TRBMPAM_EL1
In-Reply-To: <20241210055311.780688-13-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-13-anshuman.khandual@arm.com>
Message-ID: <ac2744ad-728b-487f-af9f-1eee1ae0bab5@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for TRBMPAM_EL1 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index a5e31e4c4474..78564b24b187 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -3413,6 +3413,19 @@ EndEnum
>  Field	7:0	Attr
>  EndSysreg
>  
> +Sysreg	TRBMPAM_EL1	3	0	9	11	5
> +Res0	63:27
> +Field 	26	EN
> +UnsignedEnum	25:24	MPAM_SP
> +	0b00	SECURE_PARTID
> +	0b01	NON_SECURE_PARTID
> +	0b10	ROOT_PARTID
> +	0b11	REALM_PARTID
> +EndEnum
> +Field	23:16	PMG
> +Field	15:0	PARTID
> +EndSysreg
> +
>  Sysreg	TRBTRG_EL1	3	0	9	11	6
>  Res0	63:32
>  Field	31:0	TRG



From eauger at redhat.com  Wed Dec 18 07:34:02 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:34:02 +0100
Subject: [PATCH V2 13/46] arm64/sysreg: Add register fields for
 PMSDSFR_EL1
In-Reply-To: <20241210055311.780688-14-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-14-anshuman.khandual@arm.com>
Message-ID: <345a1627-edf7-40d4-a4a4-a7c00b994859@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for PMSDSFR_EL1 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 67 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 67 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 78564b24b187..fcb4ecd85d35 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2245,6 +2245,73 @@ Field	16	COLL
>  Field	15:0	MSS
>  EndSysreg
>  
> +Sysreg	PMSDSFR_EL1	3	0	9	10	4
> +Field	63	S63
> +Field	62	S62
> +Field	61	S61
> +Field	60	S60
> +Field	59	S59
> +Field	58	S58
> +Field	57	S57
> +Field	56	S56
> +Field	55	S55
> +Field	54	S54
> +Field	53	S53
> +Field	52	S52
> +Field	51	S51
> +Field	50	S50
> +Field	49	S49
> +Field	48	S48
> +Field	47	S47
> +Field	46	S46
> +Field	45	S45
> +Field	44	S44
> +Field	43	S43
> +Field	42	S42
> +Field	41	S41
> +Field	40	S40
> +Field	39	S39
> +Field	38	S38
> +Field	37	S37
> +Field	36	S36
> +Field	35	S35
> +Field	34	S34
> +Field	33	S33
> +Field	32	S32
> +Field	31	S31
> +Field	30	S30
> +Field	29	S29
> +Field	28	S28
> +Field	27	S27
> +Field	26	S26
> +Field	25	S25
> +Field	24	S24
> +Field	23	S23
> +Field	22	S22
> +Field	21	S21
> +Field	20	S20
> +Field	19	S19
> +Field	18	S18
> +Field	17	S17
> +Field	16	S16
> +Field	15	S15
> +Field	14	S14
> +Field	13	S13
> +Field	12	S12
> +Field	11	S11
> +Field	10	S10
> +Field	9	S9
> +Field	8	S8
> +Field	7	S7
> +Field	6	S6
> +Field	5	S5
> +Field	4	S4
> +Field	3	S3
> +Field	2	S2
> +Field	1	S1
> +Field	0	S0
> +EndSysreg
> +
>  Sysreg	PMBIDR_EL1	3	0	9	10	7
>  Res0	63:12
>  Enum	11:8	EA



From angelogioacchino.delregno at collabora.com  Wed Dec 18 07:35:02 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 18 Dec 2024 16:35:02 +0100
Subject: [PATCH v5 1/3] soc: mediatek: pwrap: Switch to
 devm_clk_bulk_get_all_enabled()
In-Reply-To: <20241217-clk_bulk_ena_fix-v5-1-aafbbb245155@collabora.com>
References: <20241217-clk_bulk_ena_fix-v5-0-aafbbb245155@collabora.com>
 <20241217-clk_bulk_ena_fix-v5-1-aafbbb245155@collabora.com>
Message-ID: <54598909-979a-40b6-aa68-78ad87105088@collabora.com>

Il 17/12/24 22:41, Cristian Ciocaltea ha scritto:
> The helper devm_clk_bulk_get_all_enable() missed to return the number of
> clocks stored in the clk_bulk_data table referenced by the clks
> argument and, therefore, will be dropped.
> 
> Use the newly introduced devm_clk_bulk_get_all_enabled() variant
> instead, which is consistent with devm_clk_bulk_get_all() in terms of
> the returned value:
> 
>   > 0 if one or more clocks have been stored
>   = 0 if there are no clocks
>   < 0 if an error occurred
> 
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>


Stephen, sorry for missing the discussion about needing an ack on older versions -
Cristian just pointed that out to me.

Anyway, if you want to take this one with patch [3/3] I'm fine with that, so

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


Cheers!


From kevin.brodsky at arm.com  Wed Dec 18 07:36:15 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Wed, 18 Dec 2024 15:36:15 +0000
Subject: [PATCH] selftests/mm: Fix -Wnull-dereference on Clang
In-Reply-To: <20241209095019.1732120-5-kevin.brodsky@arm.com>
References: <20241209095019.1732120-5-kevin.brodsky@arm.com>
Message-ID: <20241218153615.2267571-1-kevin.brodsky@arm.com>

Dereferencing a null pointer on Clang is not a good idea - it will
entirely optimise out the dereference. Make the pointer volatile to
force the access (and fault).

Reported-by: kernel test robot <lkp at intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202412140850.4TW4YBqc-lkp at intel.com/
Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---

Hi Andrew,

Another fixup for an issue reported by the LKP CI (building with Clang
instead of GCC). This should be squashed into the patch I'm replying to:
"selftests/mm: Fix -Warray-bounds warnings in pkey_sighandler_tests"

Cheers,
- Kevin

Cc: aruna.ramakrishna at oracle.com
Cc: catalin.marinas at arm.com
Cc: dave.hansen at linux.intel.com
Cc: joey.gouly at arm.com
Cc: keith.lucas at oracle.com
Cc: ryan.roberts at arm.com
Cc: shuah at kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kselftest at vger.kernel.org
Cc: linux-mm at kvack.org
Cc: x86 at kernel.org
---
 tools/testing/selftests/mm/pkey_sighandler_tests.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/mm/pkey_sighandler_tests.c b/tools/testing/selftests/mm/pkey_sighandler_tests.c
index 17bbfcd552c6..1ac8c8809880 100644
--- a/tools/testing/selftests/mm/pkey_sighandler_tests.c
+++ b/tools/testing/selftests/mm/pkey_sighandler_tests.c
@@ -161,7 +161,7 @@ static void *thread_segv_with_pkey0_disabled(void *ptr)
 	__write_pkey_reg(pkey_reg_restrictive_default());
 
 	/* Segfault (with SEGV_MAPERR) */
-	*(int *)NULL = 1;
+	*(volatile int *)NULL = 1;
 	return NULL;
 }
 
@@ -192,7 +192,7 @@ static void *thread_segv_maperr_ptr(void *ptr)
 	__write_pkey_reg(pkey_reg);
 
 	/* Segfault */
-	*(int *)NULL = 1;
+	*(volatile int *)NULL = 1;
 	syscall_raw(SYS_exit, 0, 0, 0, 0, 0, 0);
 	return NULL;
 }
-- 
2.47.0



From eauger at redhat.com  Wed Dec 18 07:38:17 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:38:17 +0100
Subject: [PATCH V2 14/46] arm64/sysreg: Add register fields for
 SPMDEVAFF_EL1
In-Reply-To: <20241210055311.780688-15-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-15-anshuman.khandual@arm.com>
Message-ID: <4ecf7136-e9ff-4eb0-b464-47356ec1adab@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for SPMDEVAFF_EL1 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index fcb4ecd85d35..18b814ff2c41 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -114,6 +114,18 @@ Res0	63:1
>  Field	0	OSLK
>  EndSysreg
>  
> +Sysreg	SPMDEVAFF_EL1	2	0	9	13	6
> +Res0	63:40
> +Field	39:32	Aff3
> +Field	31	F0V
> +Field	30	U
> +Res0	29:25
> +Field	24	MT
> +Field	23:16	Aff2
> +Field	15:8	Aff1
> +Field	7:0	Aff0
> +EndSysreg
> +
>  Sysreg ID_PFR0_EL1	3	0	0	1	0
>  Res0	63:32
>  UnsignedEnum	31:28	RAS



From eauger at redhat.com  Wed Dec 18 07:42:58 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:42:58 +0100
Subject: [PATCH V2 15/46] arm64/sysreg: Add register fields for PFAR_EL1
In-Reply-To: <20241210055311.780688-16-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-16-anshuman.khandual@arm.com>
Message-ID: <5203176c-2646-425b-b375-edb7931ef54f@redhat.com>

Hi Anshuman,

On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for PFAR_EL1 as per the definitions based on
> DDI0601 2024-09.
> 
> 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 | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 18b814ff2c41..e33edb41721a 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -3533,3 +3533,10 @@ Field	5	F
>  Field	4	P
>  Field	3:0	Align
>  EndSysreg
> +
> +Sysreg	PFAR_EL1	3	0	6	0	5
> +Field	63	NS
> +Field	62	NSE
> +Res0	61:56
> +Field	55:0	PA
Just wondering: part of the PA definition depends on FEAT_D128 or
FEAT_LPA and the reset field value is UNKNOWN if the feature is not
available. Shouldn't introduce separate fields directly?

Eric
> +EndSysreg



From eauger at redhat.com  Wed Dec 18 07:44:34 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:44:34 +0100
Subject: [PATCH V2 16/46] arm64/sysreg: Add register fields for PMIAR_EL1
In-Reply-To: <20241210055311.780688-17-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-17-anshuman.khandual@arm.com>
Message-ID: <196ef833-e3f6-4314-8448-7053850d3e49@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for PMIAR_EL1 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index e33edb41721a..ff09da6c0b1e 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2349,6 +2349,10 @@ Res0	63:5
>  Field	4:0	SEL
>  EndSysreg
>  
> +Sysreg	PMIAR_EL1	3	0	9	14	7
> +Field	63:0 ADDRESS
> +EndSysreg
> +
>  SysregFields	CONTEXTIDR_ELx
>  Res0	63:32
>  Field	31:0	PROCID



From thomas.weissschuh at linutronix.de  Wed Dec 18 07:46:17 2024
From: thomas.weissschuh at linutronix.de (Thomas =?utf-8?Q?Wei=C3=9Fschuh?=)
Date: Wed, 18 Dec 2024 16:46:17 +0100
Subject: [PATCH 07/17] riscv: vdso: Switch to generic storage
 implementation
In-Reply-To: <20241218-action-matchbook-571b597b7f55@spud>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-7-f7aed1bdb3b2@linutronix.de>
 <20241218-action-matchbook-571b597b7f55@spud>
Message-ID: <20241218162031-ee920684-db10-4f17-b1cb-50373d7ea954@linutronix.de>

Hi Conor,

On Wed, Dec 18, 2024 at 03:08:28PM +0000, Conor Dooley wrote:
> On Mon, Dec 16, 2024 at 03:10:03PM +0100, Thomas Wei?schuh wrote:
> > The generic storage implementation provides the same features as the
> > custom one. However it can be shared between architectures, making
> > maintenance easier.
> > 
> > Co-developed-by: Nam Cao <namcao at linutronix.de>
> > Signed-off-by: Nam Cao <namcao at linutronix.de>
> > Signed-off-by: Thomas Wei?schuh <thomas.weissschuh at linutronix.de>
> > ---
> >  arch/riscv/Kconfig                                 |  3 +-
> >  arch/riscv/include/asm/vdso.h                      |  2 +-
> >  .../include/asm/vdso/{time_data.h => arch_data.h}  |  8 +-
> >  arch/riscv/include/asm/vdso/gettimeofday.h         | 14 +---
> >  arch/riscv/include/asm/vdso/vsyscall.h             |  9 ---
> >  arch/riscv/kernel/sys_hwprobe.c                    |  3 +-
> >  arch/riscv/kernel/vdso.c                           | 90 +---------------------
> >  arch/riscv/kernel/vdso/hwprobe.c                   |  6 +-
> >  arch/riscv/kernel/vdso/vdso.lds.S                  |  7 +-
> >  9 files changed, 18 insertions(+), 124 deletions(-)
> 
> Fails to build:
> Patch 7/17: Test 1/12: .github/scripts/patches/tests/build_rv32_defconfig.sh
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:11:33: warning: declaration of 'struct riscv_hwprobe' will not be visible outside of this function [-Wvisibility]
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:15:41: warning: declaration of 'struct riscv_hwprobe' will not be visible outside of this function [-Wvisibility]
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:19:37: error: call to undeclared function '__arch_get_vdso_u_arch_data'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:19:31: error: incompatible integer to pointer conversion initializing 'const struct vdso_arch_data *' with an expression of type 'int' [-Wint-conversion]
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:22:36: error: arithmetic on a pointer to an incomplete type 'struct riscv_hwprobe'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:30:40: error: incomplete definition of type 'const struct vdso_arch_data'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:31:24: error: incompatible pointer types passing 'struct riscv_hwprobe *' to parameter of type 'struct riscv_hwprobe *' [-Werror,-Wincompatible-pointer-types]
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:35:7: error: call to undeclared function 'riscv_hwprobe_key_is_valid'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:35:35: error: incomplete definition of type 'struct riscv_hwprobe'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:36:5: error: incomplete definition of type 'struct riscv_hwprobe'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:36:18: error: incomplete definition of type 'const struct vdso_arch_data'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:36:44: error: incomplete definition of type 'struct riscv_hwprobe'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:39:5: error: incomplete definition of type 'struct riscv_hwprobe'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:40:5: error: incomplete definition of type 'struct riscv_hwprobe'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:43:4: error: arithmetic on a pointer to an incomplete type 'struct riscv_hwprobe'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:49:39: warning: declaration of 'struct riscv_hwprobe' will not be visible outside of this function [-Wvisibility]
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:53:37: error: call to undeclared function '__arch_get_vdso_u_arch_data'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:53:31: error: incompatible integer to pointer conversion initializing 'const struct vdso_arch_data *' with an expression of type 'int' [-Wint-conversion]
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:55:36: error: arithmetic on a pointer to an incomplete type 'struct riscv_hwprobe'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:71:61: error: incomplete definition of type 'const struct vdso_arch_data'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:71:29: error: use of undeclared identifier 'RISCV_HWPROBE_WHICH_CPUS'
>   /build/tmp.cAQOaMfDA3/arch/riscv/kernel/vdso/hwprobe.c:72:24: error: incompatible pointer types passing 'struct riscv_hwprobe *' to parameter of type 'struct riscv_hwprobe *' [-Werror,-Wincompatible-pointer-types]
>   fatal error: too many errors emitted, stopping now [-ferror-limit=]
> 
> Might be a clang thing, allmodconfig with clang doesn't build either.

The proposed generic storage infrastructure currently expects that all
its users also use HAVE_GENERIC_VDSO.
I missed rv32 when checking this assumption.

I can add a bunch of ifdefs into the storage code to handle this.

Or we re-add the time vDSO functions which were removed in commit
d4c08b9776b3 ("riscv: Use latest system call ABI").
Today there are upstream ports of musl and glibc which can use them.
(currently musl even tries to use __vdso_clock_gettime() as 64-bit only
on rv32 due to a copy-and-paste error from its rv64 code)

There is precedence in providing 64bit only vDSO functions, for example
__vdso_clock_gettime64() in arm.
I do have a small, so far untested, proof-of-concept patch for it.
This would even be less code than the ifdefs.

What do you think about it?


Thomas


From eauger at redhat.com  Wed Dec 18 07:46:44 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 18 Dec 2024 16:46:44 +0100
Subject: [PATCH V2 17/46] arm64/sysreg: Add register fields for PMECR_EL1
In-Reply-To: <20241210055311.780688-18-anshuman.khandual@arm.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-18-anshuman.khandual@arm.com>
Message-ID: <7987c825-5ce1-4401-85ed-e7192e54e0b7@redhat.com>



On 12/10/24 06:52, Anshuman Khandual wrote:
> This adds register fields for PMECR_EL1 as per the definitions based
> on DDI0601 2024-09.
> 
> 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>
Reviewed-by: Eric Auger <eric.auger at redhat.com>

Eric
> ---
>  arch/arm64/tools/sysreg | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index ff09da6c0b1e..214ad6da1dff 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2349,6 +2349,21 @@ Res0	63:5
>  Field	4:0	SEL
>  EndSysreg
>  
> +Sysreg	PMECR_EL1	3	0	9	14	5
> +Res0	63:5
> +UnsignedEnum	4:3	SSE
> +	0b00	DISABLED
> +	0b10	ENABLED_PROHIBITED
> +	0b11	ENABLED_ALLOWED
> +EndEnum
> +Field	2	KPME
> +UnsignedEnum	1:0	PMEE
> +	0b00	PMUIRQ_E_PMU_D
> +	0b10	PMUIRQ_D_PMU_D
> +	0b11	PMUIRQ_D_PMU_E
> +EndEnum
> +EndSysreg
> +
>  Sysreg	PMIAR_EL1	3	0	9	14	7
>  Field	63:0 ADDRESS
>  EndSysreg



From frieder at fris.de  Wed Dec 18 07:27:25 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:25 +0100
Subject: [PATCH v3 2/9] arm64: dts: imx8mp-skov-reva: Use hardware signal for SD card VSELECT
In-Reply-To: <20241218152842.97483-1-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
Message-ID: <20241218152842.97483-3-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

The USDHC controller is able to control the IO voltage of the SD card.
There is no reason to use a GPIO to control it.

Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
Changes for v3:
* Rebase to next-20241218

Changes for v2:
* new patch
---
 arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
index 59813ef8e2bb3..33031e946329d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
@@ -232,7 +232,6 @@ pmic at 25 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_pmic>;
 		interrupts-extended = <&gpio1 3 IRQ_TYPE_EDGE_RISING>;
-		sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
 
 		regulators {
 			reg_vdd_soc: BUCK1 {
@@ -555,7 +554,6 @@ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA				0x400001c3
 	pinctrl_pmic: pmicirqgrp {
 		fsl,pins = <
 			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03			0x41
-			MX8MP_IOMUXC_GPIO1_IO04__GPIO1_IO04			0x41
 		>;
 	};
 
@@ -623,6 +621,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0			0x1d0
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1			0x1d0
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2			0x1d0
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3			0x1d0
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT			0xc0
 		>;
 	};
 
@@ -634,6 +633,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0			0x1d4
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1			0x1d4
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2			0x1d4
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3			0x1d4
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT			0xc0
 		>;
 	};
 
@@ -645,6 +645,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0			0x1d6
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1			0x1d6
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2			0x1d6
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3			0x1d6
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT			0xc0
 		>;
 	};
 
-- 
2.47.1



From frieder at fris.de  Wed Dec 18 07:27:23 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:23 +0100
Subject: [PATCH v3 0/9] Use correct LDO5 control registers for PCA9450
Message-ID: <20241218152842.97483-1-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

This is a follow-up of [1].

The main objective of this is to fix the PCA9450 driver to
use the correct control register for the LDO5 regulator.

Currently the control register to use for LDO5 is hardcoded to
LDO5CTRL_H. This is wrong for two reasons:

1. LDO5CTRL_H doesn't contain the bits for enabling/disabling
   the regulator. Only LDO5CTRL_L does.

2. The actual output voltage of the regulator is determined by
   the LDO5CTRL_H only if the SD_VSEL input is HIGH. If it is
   low, then LDO5CTRL_L is used. The driver does not take this
   into account.

This can cause several problems:

1. LDO5 can not be turned on/off and we rely on the bootloader
   to leave it turned on. On the other hand we can't save
   power if LDO5 is unused.

2. There is a potential for corner-cases where switching
   SD_VSEL via USDHC_VSELECT and writing to the (wrong)
   control register can cause wrong output voltage and therfore
   SD card failures (not observed yet).

3. Reading the current voltage of the LDO5 regulator (e. g. via
   sysfs can yield the wrong value as the voltage is read from
   the wrong control register.

At the same time there is now hardware that hardwires SD_VSEL
to a fixed LOW level and therefore relies on switching the
voltage only via a single control register. We add support for
this through an additional property "nxp,sd-vsel-fixed-low" in
the LDO5 node.

Summary of binding changes (patch 1):

1. Adjust the bindings to remove the old and abandoned use of
   sd-vsel-gpios property.

2. Adjust the bindings to use sd-vsel-gpios in the LDO5 node to
   retrieve an input that can be used to sample the SD_VSEL
   status.

3. Adjust bindings to allow "nxp,sd-vsel-fixed-low" to be used
   for boards that have SD_VSEL hardwired to low level.

Summary of driver changes (patch 2-6):

1. Remove the old sd-vsel-gpios handling.

2. Use the new sd-vsel-gpios property to determine the correct
   control register for LDO5.

3. Fix the enable register for LDO5.

4. Support hardware with fixed low level of SD_VSEL.

Summary of devicetree changes (patch 7-9):

Implement the changes in the devicetrees for Kontron hardware
(i.MX8MM, i.MX8MP and i.MX93).

Changelog:

v2 -> v3:

* Merge binding patches into one and extend commit message
* Rebase to next-20241218

v1 -> v2:

* Split binding patch
* Add solution for hardwired SD_VSEL
* Leave regulator core untouched as requested by Mark
* Add devicetree changes for i.MX8MP and i.MX93

[1] https://lore.kernel.org/lkml/20230213155833.1644366-1-frieder at fris.de/

Frieder Schrempf (9):
  dt-bindings: regulator: pca9450: Add properties for handling LDO5
  arm64: dts: imx8mp-skov-reva: Use hardware signal for SD card VSELECT
  Revert "regulator: pca9450: Add SD_VSEL GPIO for LDO5"
  regulator: pca9450: Fix control register for LDO5
  regulator: pca9450: Fix enable register for LDO5
  regulator: pca9450: Handle hardware with fixed SD_VSEL for LDO5
  arm64: dts: imx8mm-kontron: Add support for reading SD_VSEL signal
  arm64: dts: imx93-kontron: Fix SD card IO voltage control
  arm64: dts: imx8mp-kontron: Add support for reading SD_VSEL signal

 .../regulator/nxp,pca9450-regulator.yaml      |  29 ++++-
 .../boot/dts/freescale/imx8mm-kontron-bl.dts  |  10 +-
 .../dts/freescale/imx8mm-kontron-osm-s.dtsi   |   7 +-
 .../dts/freescale/imx8mp-kontron-osm-s.dtsi   |   7 +-
 .../boot/dts/freescale/imx8mp-skov-reva.dtsi  |   5 +-
 .../dts/freescale/imx93-kontron-osm-s.dtsi    |   5 +-
 drivers/regulator/pca9450-regulator.c         | 103 +++++++++++++++---
 7 files changed, 133 insertions(+), 33 deletions(-)

-- 
2.47.1



From frieder at fris.de  Wed Dec 18 07:27:26 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:26 +0100
Subject: [PATCH v3 3/9] Revert "regulator: pca9450: Add SD_VSEL GPIO for LDO5"
In-Reply-To: <20241218152842.97483-1-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
Message-ID: <20241218152842.97483-4-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

This reverts commit 8c67a11bae889f51fe5054364c3c789dfae3ad73.

It turns out that all boards using the PCA9450 actually have the
SD_VSEL input connected to the VSELECT signal of the SoCs SD/MMC
interface or use a fixed level.

The assumptions on which this was implemented were wrong. There
is no need for a GPIO-only-based approach and keeping this will
cause confusion and lead people to implement non-standard setups.

All in-tree users of this have been migrated and we can savely
remove this now and allow for a more future-proof approach
of syncing the actual status of SD_VSEL and the PMIC driver.

Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
Changes for v3:
* Rebase to next-20241218

Changes for v2:
* rebase to current master
---
 drivers/regulator/pca9450-regulator.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index faa6b79c27d75..9e5e81a9315f6 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -5,7 +5,6 @@
  */
 
 #include <linux/err.h>
-#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
@@ -32,7 +31,6 @@ struct pca9450_regulator_desc {
 struct pca9450 {
 	struct device *dev;
 	struct regmap *regmap;
-	struct gpio_desc *sd_vsel_gpio;
 	enum pca9450_chip_type type;
 	unsigned int rcnt;
 	int irq;
@@ -1031,17 +1029,6 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 					     "Failed to enable I2C level translator\n");
 	}
 
-	/*
-	 * The driver uses the LDO5CTRL_H register to control the LDO5 regulator.
-	 * This is only valid if the SD_VSEL input of the PMIC is high. Let's
-	 * check if the pin is available as GPIO and set it to high.
-	 */
-	pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH);
-
-	if (IS_ERR(pca9450->sd_vsel_gpio))
-		return dev_err_probe(&i2c->dev, PTR_ERR(pca9450->sd_vsel_gpio),
-				     "Failed to get SD_VSEL GPIO\n");
-
 	dev_info(&i2c->dev, "%s probed.\n",
 		type == PCA9450_TYPE_PCA9450A ? "pca9450a" :
 		(type == PCA9450_TYPE_PCA9451A ? "pca9451a" : "pca9450bc"));
-- 
2.47.1



From frieder at fris.de  Wed Dec 18 07:27:24 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:24 +0100
Subject: [PATCH v3 1/9] dt-bindings: regulator: pca9450: Add properties for handling LDO5
In-Reply-To: <20241218152842.97483-1-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
Message-ID: <20241218152842.97483-2-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

This reverts commit 27866e3e8a7e93494f8374f48061aa73ee46ceb2 and
implements a new future-proof way of handling the mismatch between
the PMIC driver and the hardware for LDO5.

It turned out that this feature was implemented based on the wrong
assumption that the SD_VSEL signal needs to be controlled as GPIO
in any case.

In fact the straight-forward approach is to mux the signal as
USDHC_VSELECT and let the USDHC controller do the job.

Most users never even used this property and the few who did have
been or are getting migrated to the alternative approach.

In order to know the current status (which of the two control
registers is used) for the LDO5 regulator, we need to route back the
USDHC_VSELECT signal by setting the SION bit in the IOMUX.

By adding the according GPIO as sd-vsel-gpios to the LDO5 node, we
allow the regulator driver to sample the current status of the
SD_VSEL signal that is used to select the correct control register.

The SD_VSEL on the PMIC is always an input. It's driven by the SoC's
VSELECT signal (controlled by the USDHC controller) and we use the
SION bit in the IOMUX to internally loop back the signal in order to
sample it using the GPIO.

As the SD_VSEL pin is directly routed to the LDO5 regulator in the
PMIC, make the sd-vsel-gpios property part of the LDO5 node.

SoC                                  PMIC
+-----------------------+           +-------------------+
|                       |           |                   |
|                       |           |                   |
|  GPIO <----------+    |           |                   |
|                  |    |    SD_VSEL|   +-------+       |
|  USDHC_VSELECT ->+------------------->| LDO5  |       |
|                       |           |   +-------+       |
|                       |           |                   |
+-----------------------+           +-------------------+

For boards which have the SD_VSEL tied to a fixed low level, we add
'nxp,sd-vsel-fixed-low'. The voltage of LDO5 is therefore only controlled
by writing to the LDO5CTRL_L register.

If none of 'nxp,sd-vsel-fixed-low' or 'sd-vsel-gpios' is set, we keep
the same behavior as before. The driver assumes that SD_VSEL is tied
high and the LDO5CTRL_H register can be used, which is in fact not true
for all known boards and works merely by chance.

Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
Changes for v3:
* Merge binding patches into single patch
* Rebase to next-20241218

Changes for v2:
* split revert into separate patch
* extend commit message
* add 'nxp,sd-vsel-fixed-low'
---
 .../regulator/nxp,pca9450-regulator.yaml      | 29 +++++++++++++++----
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
index 68709a7dc43f1..7605a05a9eedf 100644
--- a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
@@ -42,8 +42,30 @@ properties:
     description: |
       list of regulators provided by this controller
 
+    properties:
+      LDO5:
+        type: object
+        $ref: regulator.yaml#
+        description:
+          Properties for single LDO5 regulator.
+
+        properties:
+          nxp,sd-vsel-fixed-low:
+            type: boolean
+            description:
+              Let the driver know that SD_VSEL is hardwired to low level and
+              there is no GPIO to get the actual value from.
+
+          sd-vsel-gpios:
+            description:
+              GPIO that can be used to read the current status of the SD_VSEL
+              signal in order for the driver to know if LDO5CTRL_L or LDO5CTRL_H
+              is used by the hardware.
+
+        unevaluatedProperties: false
+
     patternProperties:
-      "^LDO[1-5]$":
+      "^LDO[1-4]$":
         type: object
         $ref: regulator.yaml#
         description:
@@ -78,11 +100,6 @@ properties:
 
     additionalProperties: false
 
-  sd-vsel-gpios:
-    description: GPIO that is used to switch LDO5 between being configured by
-      LDO5CTRL_L or LDO5CTRL_H register. Use this if the SD_VSEL signal is
-      connected to a host GPIO.
-
   nxp,i2c-lt-enable:
     type: boolean
     description:
-- 
2.47.1



From frieder at fris.de  Wed Dec 18 07:27:27 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:27 +0100
Subject: [PATCH v3 4/9] regulator: pca9450: Fix control register for LDO5
In-Reply-To: <20241218152842.97483-1-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
Message-ID: <20241218152842.97483-5-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

For LDO5 we need to be able to check the status of the SD_VSEL input in
order to know which control register is used. Read the status of the
SD_VSEL signal via GPIO and use the correct register accordingly.

To use this, the LDO5 node in the devicetree needs the sd-vsel-gpios
property to reference the GPIO that is used to read back the SD_VSEL
status internally. Please note that the SION bit in the IOMUX must be
set if the signal is muxed as VSELECT and controlled by the USDHC
controller.

Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
Changes for v3:
* Rebase to next-20241218

Changes for v2:
* rebase to current master and stop using generic helper from
  regulator core
---
 drivers/regulator/pca9450-regulator.c | 89 ++++++++++++++++++++++++++-
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index 9e5e81a9315f6..4cf5fa73765b7 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
@@ -31,6 +32,7 @@ struct pca9450_regulator_desc {
 struct pca9450 {
 	struct device *dev;
 	struct regmap *regmap;
+	struct gpio_desc *sd_vsel_gpio;
 	enum pca9450_chip_type type;
 	unsigned int rcnt;
 	int irq;
@@ -96,6 +98,58 @@ static const struct regulator_ops pca9450_ldo_regulator_ops = {
 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
 };
 
+static unsigned int pca9450_ldo5_get_reg_voltage_sel(struct regulator_dev *rdev)
+{
+	struct pca9450 *pca9450 = rdev_get_drvdata(rdev);
+
+	if (pca9450->sd_vsel_gpio && !gpiod_get_value(pca9450->sd_vsel_gpio))
+		return PCA9450_REG_LDO5CTRL_L;
+
+	return rdev->desc->vsel_reg;
+}
+
+static int pca9450_ldo5_get_voltage_sel_regmap(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(rdev->regmap, pca9450_ldo5_get_reg_voltage_sel(rdev), &val);
+	if (ret != 0)
+		return ret;
+
+	val &= rdev->desc->vsel_mask;
+	val >>= ffs(rdev->desc->vsel_mask) - 1;
+
+	return val;
+}
+
+static int pca9450_ldo5_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned int sel)
+{
+	int ret;
+
+	sel <<= ffs(rdev->desc->vsel_mask) - 1;
+
+	ret = regmap_update_bits(rdev->regmap, pca9450_ldo5_get_reg_voltage_sel(rdev),
+				  rdev->desc->vsel_mask, sel);
+	if (ret)
+		return ret;
+
+	if (rdev->desc->apply_bit)
+		ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
+					 rdev->desc->apply_bit,
+					 rdev->desc->apply_bit);
+	return ret;
+}
+
+static const struct regulator_ops pca9450_ldo5_regulator_ops = {
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_linear_range,
+	.set_voltage_sel = pca9450_ldo5_set_voltage_sel_regmap,
+	.get_voltage_sel = pca9450_ldo5_get_voltage_sel_regmap,
+};
+
 /*
  * BUCK1/2/3
  * 0.60 to 2.1875V (12.5mV step)
@@ -451,7 +505,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
 			.of_match = of_match_ptr("LDO5"),
 			.regulators_node = of_match_ptr("regulators"),
 			.id = PCA9450_LDO5,
-			.ops = &pca9450_ldo_regulator_ops,
+			.ops = &pca9450_ldo5_regulator_ops,
 			.type = REGULATOR_VOLTAGE,
 			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
 			.linear_ranges = pca9450_ldo5_volts,
@@ -665,7 +719,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
 			.of_match = of_match_ptr("LDO5"),
 			.regulators_node = of_match_ptr("regulators"),
 			.id = PCA9450_LDO5,
-			.ops = &pca9450_ldo_regulator_ops,
+			.ops = &pca9450_ldo5_regulator_ops,
 			.type = REGULATOR_VOLTAGE,
 			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
 			.linear_ranges = pca9450_ldo5_volts,
@@ -855,7 +909,7 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = {
 			.of_match = of_match_ptr("LDO5"),
 			.regulators_node = of_match_ptr("regulators"),
 			.id = PCA9450_LDO5,
-			.ops = &pca9450_ldo_regulator_ops,
+			.ops = &pca9450_ldo5_regulator_ops,
 			.type = REGULATOR_VOLTAGE,
 			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
 			.linear_ranges = pca9450_ldo5_volts,
@@ -913,6 +967,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 				      of_device_get_match_data(&i2c->dev);
 	const struct pca9450_regulator_desc	*regulator_desc;
 	struct regulator_config config = { };
+	struct regulator_dev *ldo5;
 	struct pca9450 *pca9450;
 	unsigned int device_id, i;
 	unsigned int reset_ctrl;
@@ -978,11 +1033,15 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 
 		config.regmap = pca9450->regmap;
 		config.dev = pca9450->dev;
+		config.driver_data = pca9450;
 
 		rdev = devm_regulator_register(pca9450->dev, desc, &config);
 		if (IS_ERR(rdev))
 			return dev_err_probe(pca9450->dev, PTR_ERR(rdev),
 					     "Failed to register regulator(%s)\n", desc->name);
+
+		if (!strcmp(desc->name, "ldo5"))
+			ldo5 = rdev;
 	}
 
 	if (pca9450->irq) {
@@ -1029,6 +1088,30 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 					     "Failed to enable I2C level translator\n");
 	}
 
+	/*
+	 * For LDO5 we need to be able to check the status of the SD_VSEL input in
+	 * order to know which control register is used. Most boards connect SD_VSEL
+	 * to the VSELECT signal, so we can use the GPIO that is internally routed
+	 * to this signal (if SION bit is set in IOMUX).
+	 */
+	pca9450->sd_vsel_gpio = gpiod_get_optional(&ldo5->dev, "sd-vsel", GPIOD_IN);
+	if (IS_ERR(pca9450->sd_vsel_gpio)) {
+		dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
+		return ret;
+	}
+
+	/*
+	 * For LDO5 we need to be able to check the status of the SD_VSEL input in
+	 * order to know which control register is used. Most boards connect SD_VSEL
+	 * to the VSELECT signal, so we can use the GPIO that is internally routed
+	 * to this signal (if SION bit is set in IOMUX).
+	 */
+	pca9450->sd_vsel_gpio = gpiod_get_optional(&ldo5->dev, "sd-vsel", GPIOD_IN);
+	if (IS_ERR(pca9450->sd_vsel_gpio)) {
+		dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
+		return ret;
+	}
+
 	dev_info(&i2c->dev, "%s probed.\n",
 		type == PCA9450_TYPE_PCA9450A ? "pca9450a" :
 		(type == PCA9450_TYPE_PCA9451A ? "pca9451a" : "pca9450bc"));
-- 
2.47.1



From frieder at fris.de  Wed Dec 18 07:27:28 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:28 +0100
Subject: [PATCH v3 5/9] regulator: pca9450: Fix enable register for LDO5
In-Reply-To: <20241218152842.97483-1-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
Message-ID: <20241218152842.97483-6-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

The LDO5 regulator has two configuration registers, but only
LDO5CTRL_L contains the bits for enabling/disabling the regulator.

Fixes: 0935ff5f1f0a ("regulator: pca9450: add pca9450 pmic driver")
Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Reviewed-by: Marek Vasut <marex at denx.de>
---
Changes for v3:
* Rebase to next-20241218

Changes for v2:
* none
---
 drivers/regulator/pca9450-regulator.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index 4cf5fa73765b7..4519e725706cd 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -512,7 +512,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
 			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
 			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
 			.vsel_mask = LDO5HOUT_MASK,
-			.enable_reg = PCA9450_REG_LDO5CTRL_H,
+			.enable_reg = PCA9450_REG_LDO5CTRL_L,
 			.enable_mask = LDO5H_EN_MASK,
 			.owner = THIS_MODULE,
 		},
@@ -726,7 +726,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
 			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
 			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
 			.vsel_mask = LDO5HOUT_MASK,
-			.enable_reg = PCA9450_REG_LDO5CTRL_H,
+			.enable_reg = PCA9450_REG_LDO5CTRL_L,
 			.enable_mask = LDO5H_EN_MASK,
 			.owner = THIS_MODULE,
 		},
@@ -916,7 +916,7 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = {
 			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
 			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
 			.vsel_mask = LDO5HOUT_MASK,
-			.enable_reg = PCA9450_REG_LDO5CTRL_H,
+			.enable_reg = PCA9450_REG_LDO5CTRL_L,
 			.enable_mask = LDO5H_EN_MASK,
 			.owner = THIS_MODULE,
 		},
-- 
2.47.1



From frieder at fris.de  Wed Dec 18 07:27:29 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:29 +0100
Subject: [PATCH v3 6/9] regulator: pca9450: Handle hardware with fixed SD_VSEL for LDO5
In-Reply-To: <20241218152842.97483-1-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
Message-ID: <20241218152842.97483-7-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

There are two ways to set the output voltage of the LD05
regulator. First by writing to the voltage selection registers
and second by toggling the SD_VSEL signal.

Usually board designers connect SD_VSEL to the VSELECT signal
controlled by the USDHC controller, but in some cases the
signal is hardwired to a fixed low level (therefore selecting
3.3V as initial value for allowing to boot from the SD card).

In these cases, the voltage is only determined by the value
of the LDO5CTRL_L register. Introduce a property
nxp,sd-vsel-fixed-low to let the driver know that SD_VSEL
is low and there is no GPIO to actually get that
information from dynamically.

Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
Changes for v3:
* Rebase to next-20241218

Changes for v2:
* new patch
---
 drivers/regulator/pca9450-regulator.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index 4519e725706cd..fd40b50318d96 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -36,6 +36,7 @@ struct pca9450 {
 	enum pca9450_chip_type type;
 	unsigned int rcnt;
 	int irq;
+	bool sd_vsel_fixed_low;
 };
 
 static const struct regmap_range pca9450_status_range = {
@@ -102,6 +103,9 @@ static unsigned int pca9450_ldo5_get_reg_voltage_sel(struct regulator_dev *rdev)
 {
 	struct pca9450 *pca9450 = rdev_get_drvdata(rdev);
 
+	if (pca9450->sd_vsel_fixed_low)
+		return PCA9450_REG_LDO5CTRL_L;
+
 	if (pca9450->sd_vsel_gpio && !gpiod_get_value(pca9450->sd_vsel_gpio))
 		return PCA9450_REG_LDO5CTRL_L;
 
@@ -1112,6 +1116,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
 		return ret;
 	}
 
+	pca9450->sd_vsel_fixed_low =
+		of_property_read_bool(ldo5->dev.of_node, "nxp,sd-vsel-fixed-low");
+
 	dev_info(&i2c->dev, "%s probed.\n",
 		type == PCA9450_TYPE_PCA9450A ? "pca9450a" :
 		(type == PCA9450_TYPE_PCA9451A ? "pca9451a" : "pca9450bc"));
-- 
2.47.1



From frieder at fris.de  Wed Dec 18 07:27:30 2024
From: frieder at fris.de (Frieder Schrempf)
Date: Wed, 18 Dec 2024 16:27:30 +0100
Subject: [PATCH v3 7/9] arm64: dts: imx8mm-kontron: Add support for reading SD_VSEL signal
In-Reply-To: <20241218152842.97483-1-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
Message-ID: <20241218152842.97483-8-frieder@fris.de>

From: Frieder Schrempf <frieder.schrempf at kontron.de>

This fixes the LDO5 regulator handling of the pca9450 driver by
taking the status of the SD_VSEL into account to determine which
configuration register is used for the voltage setting.

Even without this change there is no functional issue, as the code
for switching the voltage in sdhci.c currently switches both, the
VSELECT/SD_VSEL signal and the regulator voltage at the same time
and doesn't run into an invalid corner case.

We should still make sure, that we always use the correct register
when controlling the regulator. At least in U-Boot this fixes an
actual bug where the wrong IO voltage is used and it makes sure
that the correct voltage can be read from sysfs.

Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
---
Changes for v3:
* Rebase to next-20241218

Changes for v2:
* rebase to current master
---
 arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts    | 10 +++++++---
 .../arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi |  7 ++++---
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
index a8ef4fba16a9e..d16490d876874 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
@@ -254,6 +254,10 @@ &pwm2 {
 	status = "okay";
 };
 
+&reg_nvcc_sd {
+	sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+};
+
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1>;
@@ -454,7 +458,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d0
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d0
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d0
 			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x19
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xd0
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x40000d0
 		>;
 	};
 
@@ -467,7 +471,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d4
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d4
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d4
 			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x19
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xd0
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x40000d0
 		>;
 	};
 
@@ -480,7 +484,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d6
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d6
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d6
 			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x19
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xd0
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x40000d0
 		>;
 	};
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
index 663ae52b48526..d455429652305 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
@@ -342,6 +342,7 @@ reg_nvcc_sd: LDO5 {
 				regulator-name = "NVCC_SD (LDO5)";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3300000>;
+				sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
 			};
 		};
 	};
@@ -794,7 +795,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d0 /* SDIO_A_D1 */
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d0 /* SDIO_A_D2 */
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d0 /* SDIO_A_D3 */
 			MX8MM_IOMUXC_SD2_WP_USDHC2_WP			0x400000d6 /* SDIO_A_WP */
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x90
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x40000090
 		>;
 	};
 
@@ -807,7 +808,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d4 /* SDIO_A_D1 */
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d4 /* SDIO_A_D2 */
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d4 /* SDIO_A_D3 */
 			MX8MM_IOMUXC_SD2_WP_USDHC2_WP			0x400000d6 /* SDIO_A_WP */
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x90
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x40000090
 		>;
 	};
 
@@ -820,7 +821,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d6 /* SDIO_A_D1 */
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d6 /* SDIO_A_D2 */
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d6 /* SDIO_A_D3 */
 			MX8MM_IOMUXC_SD2_WP_USDHC2_WP			0x400000d6 /* SDIO_A_WP */
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x90
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x40000090
 		>;
 	};
 
-- 
2.47.1



From jon.lin at rock-chips.com  Wed Dec 18 07:47:41 2024
From: jon.lin at rock-chips.com (Jon Lin)
Date: Wed, 18 Dec 2024 23:47:41 +0800
Subject: [PATCH] spi: rockchip-sfc: Fix error in remove progress
Message-ID: <20241218154741.901591-1-jon.lin@rock-chips.com>

Fix error in remove progress:
	[   43.026148] Call trace:
	[   43.026370]  klist_next+0x1c/0x1d4
	[   43.026671]  device_for_each_child+0x48/0xac
	[   43.027049]  spi_unregister_controller+0x30/0x130
	[   43.027469]  rockchip_sfc_remove+0x48/0x80 [spi_rockchip_sfc]

Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

 drivers/spi/spi-rockchip-sfc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
index 9146b56713b6..ca4f20283d23 100644
--- a/drivers/spi/spi-rockchip-sfc.c
+++ b/drivers/spi/spi-rockchip-sfc.c
@@ -184,6 +184,7 @@ struct rockchip_sfc {
 	bool use_dma;
 	u32 max_iosize;
 	u16 version;
+	struct spi_controller *host;
 };
 
 static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
@@ -603,6 +604,7 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
 
 	sfc = spi_controller_get_devdata(host);
 	sfc->dev = dev;
+	sfc->host = host;
 
 	sfc->regbase = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(sfc->regbase))
@@ -708,8 +710,8 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
 
 static void rockchip_sfc_remove(struct platform_device *pdev)
 {
-	struct spi_controller *host = platform_get_drvdata(pdev);
 	struct rockchip_sfc *sfc = platform_get_drvdata(pdev);
+	struct spi_controller *host = sfc->host;
 
 	spi_unregister_controller(host);
 
-- 
2.34.1



From aleksander.lobakin at intel.com  Wed Dec 18 07:48:38 2024
From: aleksander.lobakin at intel.com (Alexander Lobakin)
Date: Wed, 18 Dec 2024 16:48:38 +0100
Subject: [PATCH net-next v1] net: stmmac: Drop useless code related to
 ethtool rx-copybreak
In-Reply-To: <20241218083407.390509-1-0x1207@gmail.com>
References: <20241218083407.390509-1-0x1207@gmail.com>
Message-ID: <b2ae6b80-83e3-4b22-8301-c91569c89494@intel.com>

From: Furong Xu <0x1207 at gmail.com>
Date: Wed, 18 Dec 2024 16:34:07 +0800

> After commit 2af6106ae949 ("net: stmmac: Introducing support for Page
> Pool"), the driver always copies frames to get a better performance,
> zero-copy for RX frames is no more, then these code turned to be
> useless and users of ethtool may get confused about the unhandled
> rx-copybreak parameter.
> 
> This patch mostly reverts
> commit 22ad38381547 ("stmmac: do not perform zero-copy for rx frames")
> 
> Signed-off-by: Furong Xu <0x1207 at gmail.com>

The patch itself is fine, *but*

> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  2 -
>  .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 39 -------------------
>  .../net/ethernet/stmicro/stmmac/stmmac_main.c |  5 ---
>  3 files changed, 46 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index 1d86439b8a14..b8d631e559c0 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -126,7 +126,6 @@ struct stmmac_rx_queue {
>  	unsigned int cur_rx;
>  	unsigned int dirty_rx;
>  	unsigned int buf_alloc_num;
> -	u32 rx_zeroc_thresh;
>  	dma_addr_t dma_rx_phy;

If sizeof(dma_addr_t) == 8, you're clearly introducing a 4-byte hole
here. Perhaps you could reshuffle the struct a bit to avoid this.

It's always good to inspect the .kos with pahole after modifying
structures to make sure there are no regressions.

>  	u32 rx_tail_addr;
>  	unsigned int state_saved;

Thanks,
Olek


From broonie at kernel.org  Wed Dec 18 07:54:05 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 18 Dec 2024 15:54:05 +0000
Subject: [PATCH v3 3/9] Revert "regulator: pca9450: Add SD_VSEL GPIO for
 LDO5"
In-Reply-To: <20241218152842.97483-4-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
 <20241218152842.97483-4-frieder@fris.de>
Message-ID: <5ddc7b3e-5d2f-4cf8-91e3-566008074ec0@sirena.org.uk>

On Wed, Dec 18, 2024 at 04:27:26PM +0100, Frieder Schrempf wrote:
> From: Frieder Schrempf <frieder.schrempf at kontron.de>
> 
> This reverts commit 8c67a11bae889f51fe5054364c3c789dfae3ad73.

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.

Please include human readable descriptions of things like commits and
issues being discussed in e-mail in your mails, this makes them much
easier for humans to read especially when they have no internet access.
I do frequently catch up on my mail on flights or while otherwise
travelling so this is even more pressing for me than just being about
making things a bit easier to read.
-------------- 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/20241218/acb5aa74/attachment.sig>

From ulf.hansson at linaro.org  Wed Dec 18 07:55:16 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 18 Dec 2024 16:55:16 +0100
Subject: [PATCH v2 0/2] mmc: mtk-sd: Limit second register range to SoCs
 requiring it
In-Reply-To: <20241210073212.3917912-1-wenst@chromium.org>
References: <20241210073212.3917912-1-wenst@chromium.org>
Message-ID: <CAPDyKFrJYvMvBby5mhOAsyp2_Dx+KuOEnGaELMydKBHFcyO_VA@mail.gmail.com>

On Tue, 10 Dec 2024 at 08:32, Chen-Yu Tsai <wenst at chromium.org> wrote:
>
> Changes since v1:
> - Added MT7988 compatible string to list that needs second register
>   range
> - Dropped comment about uncertainty of MT6779 from commit message
> - Picked up Angelo's Reviewed-by
>
> Currently the usage of a second register range for MediaTek's MMC
> controller is seen only on a few platforms. However the driver tries
> to grab the register base regardless, and then ignores any errors.
> This makes all the other platforms that don't need it produce confusing
> error messages.
>
> Instead, make the driver only grab the register range for platforms that
> actually require it, and correctly handle the error. Also fix up the
> binding so that validation of the "reg" property is as strict as
> possible.
>
> Please take a look.
>
>
> Thanks
> ChenYu
>
> Chen-Yu Tsai (2):
>   dt-bindings: mmc: mtk-sd: Document compatibles that need two register
>     ranges
>   mmc: mtk-sd: Limit getting top_base to SoCs that require it
>
>  Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 10 +++++++++-
>  drivers/mmc/host/mtk-sd.c                         | 15 +++++++++++----
>  2 files changed, 20 insertions(+), 5 deletions(-)
>

Both patches applied for next, thanks!

Kind regards
Uffe


From vishal.sagar at amd.com  Wed Dec 18 07:57:05 2024
From: vishal.sagar at amd.com (Sagar, Vishal)
Date: Wed, 18 Dec 2024 16:57:05 +0100
Subject: [PATCH v4 3/3] drm: xlnx: zynqmp_dpsub: Add DP audio support
In-Reply-To: <20241023-xilinx-dp-audio-v4-3-5128881457be@ideasonboard.com>
References: <20241023-xilinx-dp-audio-v4-0-5128881457be@ideasonboard.com>
 <20241023-xilinx-dp-audio-v4-3-5128881457be@ideasonboard.com>
Message-ID: <4f93b51f-ec7b-48e2-974c-9514194c6a07@amd.com>

Hi Tomi,

Thanks for the patch.

On 10/23/2024 1:52 PM, Tomi Valkeinen wrote:
> Add basic DisplayPort audio support.
> 
> Support non-live audio playback from two PCMs (DMA channels), and the
> volume control in the audio mixer.
> 
> As older dtb files may not have the audio DMA channels defined, the
> driver will just mark the audio support as disabled if the audio DMA is
> missing, and will continue with only display support.
> 
> Note: Reset doesn't seem to work (ZYNQMP_DISP_AUD_SOFT_RESET). If we do
> a reset, audio playback won't start again even if, afaics, we do set up
> all the necessary registers. So, at the moment, resetting the audio
> block in dp_dai_hw_free() is commented out.
> 
> Tested-by: Anatoliy Klymenko <anatoliy.klymenko at amd.com>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
>   drivers/gpu/drm/xlnx/Kconfig            |   9 +
>   drivers/gpu/drm/xlnx/Makefile           |   1 +
>   drivers/gpu/drm/xlnx/zynqmp_disp.c      |  48 ----
>   drivers/gpu/drm/xlnx/zynqmp_disp_regs.h |   7 +-
>   drivers/gpu/drm/xlnx/zynqmp_dp.c        |  54 ++--
>   drivers/gpu/drm/xlnx/zynqmp_dp.h        |   7 +
>   drivers/gpu/drm/xlnx/zynqmp_dp_audio.c  | 447 ++++++++++++++++++++++++++++++++
>   drivers/gpu/drm/xlnx/zynqmp_dpsub.c     |  39 +--
>   drivers/gpu/drm/xlnx/zynqmp_dpsub.h     |  15 +-
>   9 files changed, 526 insertions(+), 101 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/Kconfig b/drivers/gpu/drm/xlnx/Kconfig
> index 626e5ac4c33d..ecd7be347300 100644
> --- a/drivers/gpu/drm/xlnx/Kconfig
> +++ b/drivers/gpu/drm/xlnx/Kconfig
> @@ -16,3 +16,12 @@ config DRM_ZYNQMP_DPSUB
>   	  This is a DRM/KMS driver for ZynqMP DisplayPort controller. Choose
>   	  this option if you have a Xilinx ZynqMP SoC with DisplayPort
>   	  subsystem.
> +
> +config DRM_ZYNQMP_DPSUB_AUDIO
> +	bool "ZynqMP DisplayPort Audio Support"
> +	depends on DRM_ZYNQMP_DPSUB
> +	depends on SND && SND_SOC
> +	select SND_SOC_GENERIC_DMAENGINE_PCM
> +	help
> +	  Choose this option to enable DisplayPort audio support in the ZynqMP
> +	  DisplayPort driver.
> diff --git a/drivers/gpu/drm/xlnx/Makefile b/drivers/gpu/drm/xlnx/Makefile
> index ea1422a39502..ab6e2ffd7e8d 100644
> --- a/drivers/gpu/drm/xlnx/Makefile
> +++ b/drivers/gpu/drm/xlnx/Makefile
> @@ -1,2 +1,3 @@
>   zynqmp-dpsub-y := zynqmp_disp.o zynqmp_dpsub.o zynqmp_dp.o zynqmp_kms.o
> +zynqmp-dpsub-$(CONFIG_DRM_ZYNQMP_DPSUB_AUDIO) += zynqmp_dp_audio.o
>   obj-$(CONFIG_DRM_ZYNQMP_DPSUB) += zynqmp-dpsub.o
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> index 9368acf56eaf..77dc485c0887 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> @@ -143,7 +143,6 @@ struct zynqmp_disp_layer {
>    * @dpsub: Display subsystem
>    * @blend: Register I/O base address for the blender
>    * @avbuf: Register I/O base address for the audio/video buffer manager
> - * @audio: Registers I/O base address for the audio mixer
>    * @layers: Layers (planes)
>    */
>   struct zynqmp_disp {
> @@ -152,7 +151,6 @@ struct zynqmp_disp {
>   
>   	void __iomem *blend;
>   	void __iomem *avbuf;
> -	void __iomem *audio;
>   
>   	struct zynqmp_disp_layer layers[ZYNQMP_DPSUB_NUM_LAYERS];
>   };
> @@ -865,42 +863,6 @@ static void zynqmp_disp_blend_layer_disable(struct zynqmp_disp *disp,
>   					csc_zero_offsets);
>   }
>   
> -/* -----------------------------------------------------------------------------
> - * Audio Mixer
> - */
> -
> -static void zynqmp_disp_audio_write(struct zynqmp_disp *disp, int reg, u32 val)
> -{
> -	writel(val, disp->audio + reg);
> -}
> -
> -/**
> - * zynqmp_disp_audio_enable - Enable the audio mixer
> - * @disp: Display controller
> - *
> - * Enable the audio mixer by de-asserting the soft reset. The audio state is set to
> - * default values by the reset, set the default mixer volume explicitly.
> - */
> -static void zynqmp_disp_audio_enable(struct zynqmp_disp *disp)
> -{
> -	/* Clear the audio soft reset register as it's an non-reset flop. */
> -	zynqmp_disp_audio_write(disp, ZYNQMP_DISP_AUD_SOFT_RESET, 0);
> -	zynqmp_disp_audio_write(disp, ZYNQMP_DISP_AUD_MIXER_VOLUME,
> -				ZYNQMP_DISP_AUD_MIXER_VOLUME_NO_SCALE);
> -}
> -
> -/**
> - * zynqmp_disp_audio_disable - Disable the audio mixer
> - * @disp: Display controller
> - *
> - * Disable the audio mixer by asserting its soft reset.
> - */
> -static void zynqmp_disp_audio_disable(struct zynqmp_disp *disp)
> -{
> -	zynqmp_disp_audio_write(disp, ZYNQMP_DISP_AUD_SOFT_RESET,
> -				ZYNQMP_DISP_AUD_SOFT_RESET_AUD_SRST);
> -}
> -
>   /* -----------------------------------------------------------------------------
>    * ZynqMP Display Layer & DRM Plane
>    */
> @@ -1338,8 +1300,6 @@ void zynqmp_disp_enable(struct zynqmp_disp *disp)
>   					     disp->dpsub->vid_clk_from_ps);
>   	zynqmp_disp_avbuf_enable_channels(disp);
>   	zynqmp_disp_avbuf_enable_audio(disp);
> -
> -	zynqmp_disp_audio_enable(disp);
>   }
>   
>   /**
> @@ -1348,8 +1308,6 @@ void zynqmp_disp_enable(struct zynqmp_disp *disp)
>    */
>   void zynqmp_disp_disable(struct zynqmp_disp *disp)
>   {
> -	zynqmp_disp_audio_disable(disp);
> -
>   	zynqmp_disp_avbuf_disable_audio(disp);
>   	zynqmp_disp_avbuf_disable_channels(disp);
>   	zynqmp_disp_avbuf_disable(disp);
> @@ -1418,12 +1376,6 @@ int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub)
>   		goto error;
>   	}
>   
> -	disp->audio = devm_platform_ioremap_resource_byname(pdev, "aud");
> -	if (IS_ERR(disp->audio)) {
> -		ret = PTR_ERR(disp->audio);
> -		goto error;
> -	}
> -
>   	ret = zynqmp_disp_create_layers(disp);
>   	if (ret)
>   		goto error;
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h b/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> index fa3935384834..9a4ff094e276 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> @@ -177,12 +177,7 @@
>   #define ZYNQMP_DISP_AUD_MIXER_VOLUME			0x0
>   #define ZYNQMP_DISP_AUD_MIXER_VOLUME_NO_SCALE		0x20002000
>   #define ZYNQMP_DISP_AUD_MIXER_META_DATA			0x4
> -#define ZYNQMP_DISP_AUD_CH_STATUS0			0x8
> -#define ZYNQMP_DISP_AUD_CH_STATUS1			0xc
> -#define ZYNQMP_DISP_AUD_CH_STATUS2			0x10
> -#define ZYNQMP_DISP_AUD_CH_STATUS3			0x14
> -#define ZYNQMP_DISP_AUD_CH_STATUS4			0x18
> -#define ZYNQMP_DISP_AUD_CH_STATUS5			0x1c
> +#define ZYNQMP_DISP_AUD_CH_STATUS(x)			(0x8 + ((x) * 4))
>   #define ZYNQMP_DISP_AUD_CH_A_DATA0			0x20
>   #define ZYNQMP_DISP_AUD_CH_A_DATA1			0x24
>   #define ZYNQMP_DISP_AUD_CH_A_DATA2			0x28
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index 129beac4c073..af1b4b104067 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -1221,7 +1221,6 @@ static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp,
>   {
>   	u8 lane_cnt = dp->mode.lane_cnt;
>   	u32 reg, wpl;
> -	unsigned int rate;
>   
>   	zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HTOTAL, mode->htotal);
>   	zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VTOTAL, mode->vtotal);
> @@ -1246,18 +1245,8 @@ static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp,
>   		reg = drm_dp_bw_code_to_link_rate(dp->mode.bw_code);
>   		zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_N_VID, reg);
>   		zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_M_VID, mode->clock);
> -		rate = zynqmp_dpsub_get_audio_clk_rate(dp->dpsub);
> -		if (rate) {
> -			dev_dbg(dp->dev, "Audio rate: %d\n", rate / 512);
> -			zynqmp_dp_write(dp, ZYNQMP_DP_TX_N_AUD, reg);
> -			zynqmp_dp_write(dp, ZYNQMP_DP_TX_M_AUD, rate / 1000);
> -		}
>   	}
>   
> -	/* Only 2 channel audio is supported now */
> -	if (zynqmp_dpsub_audio_enabled(dp->dpsub))
> -		zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CHANNELS, 1);
> -
>   	zynqmp_dp_write(dp, ZYNQMP_DP_USER_PIX_WIDTH, 1);
>   
>   	/* Translate to the native 16 bit datapath based on IP core spec */
> @@ -1266,6 +1255,44 @@ static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp,
>   	zynqmp_dp_write(dp, ZYNQMP_DP_USER_DATA_COUNT_PER_LANE, reg);
>   }
>   
> +/* -----------------------------------------------------------------------------
> + * Audio
> + */
> +
> +void zynqmp_dp_audio_set_channels(struct zynqmp_dp *dp,
> +				  unsigned int num_channels)
> +{
> +	zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CHANNELS, num_channels - 1);
> +}
> +
> +void zynqmp_dp_audio_enable(struct zynqmp_dp *dp)
> +{
> +	zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 1);
> +}
> +
> +void zynqmp_dp_audio_disable(struct zynqmp_dp *dp)
> +{
> +	zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 0);
> +}
> +
> +void zynqmp_dp_audio_write_n_m(struct zynqmp_dp *dp)
> +{
> +	unsigned int rate;
> +	u32 link_rate;
> +
> +	if (!(dp->config.misc0 & ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK))
> +		return;
> +
> +	link_rate = drm_dp_bw_code_to_link_rate(dp->mode.bw_code);
> +
> +	rate = clk_get_rate(dp->dpsub->aud_clk);
> +
> +	dev_dbg(dp->dev, "Audio rate: %d\n", rate / 512);
> +
> +	zynqmp_dp_write(dp, ZYNQMP_DP_TX_N_AUD, link_rate);
> +	zynqmp_dp_write(dp, ZYNQMP_DP_TX_M_AUD, rate / 1000);
> +}
> +
>   /* -----------------------------------------------------------------------------
>    * DISP Configuration
>    */
> @@ -1453,8 +1480,7 @@ static void zynqmp_dp_bridge_atomic_enable(struct drm_bridge *bridge,
>   	/* Enable the encoder */
>   	dp->enabled = true;
>   	zynqmp_dp_update_misc(dp);
> -	if (zynqmp_dpsub_audio_enabled(dp->dpsub))
> -		zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 1);
> +
>   	zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, 0);
>   	if (dp->status == connector_status_connected) {
>   		for (i = 0; i < 3; i++) {
> @@ -1487,8 +1513,6 @@ static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge,
>   	drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
>   	zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN,
>   			ZYNQMP_DP_TX_PHY_POWER_DOWN_ALL);
> -	if (zynqmp_dpsub_audio_enabled(dp->dpsub))
> -		zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 0);
>   
>   	zynqmp_dp_disp_disable(dp, old_bridge_state);
>   
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.h b/drivers/gpu/drm/xlnx/zynqmp_dp.h
> index f077d7fbd0ad..a3257793e23a 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.h
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.h
> @@ -22,4 +22,11 @@ void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp);
>   int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub);
>   void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub);
>   
> +void zynqmp_dp_audio_set_channels(struct zynqmp_dp *dp,
> +				  unsigned int num_channels);
> +void zynqmp_dp_audio_enable(struct zynqmp_dp *dp);
> +void zynqmp_dp_audio_disable(struct zynqmp_dp *dp);
> +
> +void zynqmp_dp_audio_write_n_m(struct zynqmp_dp *dp);
> +
>   #endif /* _ZYNQMP_DP_H_ */
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp_audio.c b/drivers/gpu/drm/xlnx/zynqmp_dp_audio.c
> new file mode 100644
> index 000000000000..fa5f0ace6084
> --- /dev/null
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp_audio.c
> @@ -0,0 +1,447 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * ZynqMP DisplayPort Subsystem Driver - Audio support
> + *
> + * Copyright (C) 2015 - 2024 Xilinx, Inc.
> + *
> + * Authors:
> + * - Hyun Woo Kwon <hyun.kwon at xilinx.com>
> + * - Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/device.h>
> +#include <linux/mutex.h>
> +#include <linux/pm_runtime.h>
> +
> +#include <sound/asoundef.h>
> +#include <sound/core.h>
> +#include <sound/dmaengine_pcm.h>
> +#include <sound/initval.h>
> +#include <sound/pcm.h>
> +#include <sound/soc.h>
> +#include <sound/tlv.h>
> +
> +#include "zynqmp_disp_regs.h"
> +#include "zynqmp_dp.h"
> +#include "zynqmp_dpsub.h"
> +
> +#define ZYNQMP_DISP_AUD_SMPL_RATE_TO_CLK 512
> +#define ZYNQMP_NUM_PCMS 2
> +
> +struct zynqmp_dpsub_audio {
> +	void __iomem *base;
> +
> +	struct snd_soc_card card;
> +
> +	const char *dai_name;
> +	const char *link_names[ZYNQMP_NUM_PCMS];
> +	const char *pcm_names[ZYNQMP_NUM_PCMS];
> +
> +	struct snd_soc_dai_driver dai_driver;
> +	struct snd_dmaengine_pcm_config pcm_configs[2];
> +
> +	struct snd_soc_dai_link links[ZYNQMP_NUM_PCMS];
> +
> +	struct {
> +		struct snd_soc_dai_link_component cpu;
> +		struct snd_soc_dai_link_component codec;
> +		struct snd_soc_dai_link_component platform;
> +	} components[ZYNQMP_NUM_PCMS];
> +
> +	/*
> +	 * Protects:
> +	 * - enabled_streams
> +	 * - volumes
> +	 * - current_rate
> +	 */
> +	struct mutex enable_lock;
> +
> +	u32 enabled_streams;
> +	u32 current_rate;
> +
> +	u16 volumes[2];
> +};
> +
> +static const struct snd_pcm_hardware zynqmp_dp_pcm_hw = {
> +	.info = SNDRV_PCM_INFO_MMAP |
> +		SNDRV_PCM_INFO_MMAP_VALID |
> +		SNDRV_PCM_INFO_INTERLEAVED |
> +		SNDRV_PCM_INFO_PAUSE |
> +		SNDRV_PCM_INFO_RESUME |
> +		SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
> +
> +	.buffer_bytes_max       = 128 * 1024,
> +	.period_bytes_min       = 256,
> +	.period_bytes_max       = 1024 * 1024,
> +	.periods_min            = 2,
> +	.periods_max            = 256,
> +};
> +
> +static int zynqmp_dp_startup(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +
> +	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
> +				   256);
> +
> +	return 0;
> +}
> +
> +static const struct snd_soc_ops zynqmp_dp_ops = {
> +	.startup = zynqmp_dp_startup,
> +};
> +
> +static void zynqmp_dp_audio_write(struct zynqmp_dpsub_audio *audio, int reg,
> +				  u32 val)
> +{
> +	writel(val, audio->base + reg);
> +}
> +
> +static int dp_dai_hw_params(struct snd_pcm_substream *substream,
> +			    struct snd_pcm_hw_params *params,
> +			    struct snd_soc_dai *socdai)
> +{
> +	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> +	struct zynqmp_dpsub *dpsub =
> +		snd_soc_dai_get_drvdata(snd_soc_rtd_to_cpu(rtd, 0));
> +	struct zynqmp_dpsub_audio *audio = dpsub->audio;
> +	int ret;
> +	u32 sample_rate;
> +	struct snd_aes_iec958 iec = { 0 };
> +	unsigned long rate;
> +
> +	sample_rate = params_rate(params);
> +
> +	if (sample_rate != 48000 && sample_rate != 44100)
> +		return -EINVAL;
> +
> +	guard(mutex)(&audio->enable_lock);
> +
> +	if (audio->enabled_streams && audio->current_rate != sample_rate) {
> +		dev_err(dpsub->dev,
> +			"Can't change rate while playback enabled\n");
> +		return -EINVAL;
> +	}
> +
> +	if (audio->enabled_streams > 0) {
> +		/* Nothing to do */
> +		audio->enabled_streams++;
> +		return 0;
> +	}
> +
> +	audio->current_rate = sample_rate;
> +
> +	/* Note: clock rate can only be changed if the clock is disabled */
> +	ret = clk_set_rate(dpsub->aud_clk,
> +			   sample_rate * ZYNQMP_DISP_AUD_SMPL_RATE_TO_CLK);
> +	if (ret) {
> +		dev_err(dpsub->dev, "can't set aud_clk to %u err:%d\n",
> +			sample_rate * ZYNQMP_DISP_AUD_SMPL_RATE_TO_CLK, ret);
> +		return ret;
> +	}
> +
> +	clk_prepare_enable(dpsub->aud_clk);
> +
> +	rate = clk_get_rate(dpsub->aud_clk);
> +
> +	/* Ignore some offset +- 10 */
> +	if (abs(sample_rate * ZYNQMP_DISP_AUD_SMPL_RATE_TO_CLK - rate) > 10) {
> +		dev_err(dpsub->dev, "aud_clk offset is higher: %ld\n",
> +			sample_rate * ZYNQMP_DISP_AUD_SMPL_RATE_TO_CLK - rate);
> +		clk_disable_unprepare(dpsub->aud_clk);
> +		return -EINVAL;
> +	}
> +
> +	pm_runtime_get_sync(dpsub->dev);
> +
> +	zynqmp_dp_audio_write(audio, ZYNQMP_DISP_AUD_MIXER_VOLUME,
> +			      audio->volumes[0] | (audio->volumes[1] << 16));
> +
> +	/* Clear the audio soft reset register as it's an non-reset flop. */
> +	zynqmp_dp_audio_write(audio, ZYNQMP_DISP_AUD_SOFT_RESET, 0);
> +
> +	/* Only 2 channel audio is supported now */
> +	zynqmp_dp_audio_set_channels(dpsub->dp, 2);
> +
> +	zynqmp_dp_audio_write_n_m(dpsub->dp);
> +
> +	/* Channel status */
> +
> +	if (sample_rate == 48000)
> +		iec.status[3] = IEC958_AES3_CON_FS_48000;
> +	else
> +		iec.status[3] = IEC958_AES3_CON_FS_44100;
> +
> +	for (unsigned int i = 0; i < AES_IEC958_STATUS_SIZE / 4; ++i) {
> +		u32 v;
> +
> +		v = (iec.status[(i * 4) + 0] << 0) |
> +		    (iec.status[(i * 4) + 1] << 8) |
> +		    (iec.status[(i * 4) + 2] << 16) |
> +		    (iec.status[(i * 4) + 3] << 24);
> +
> +		zynqmp_dp_audio_write(audio, ZYNQMP_DISP_AUD_CH_STATUS(i), v);
> +	}
> +
> +	zynqmp_dp_audio_enable(dpsub->dp);
> +
> +	audio->enabled_streams++;
> +
> +	return 0;
> +}
> +
> +static int dp_dai_hw_free(struct snd_pcm_substream *substream,
> +			  struct snd_soc_dai *socdai)
> +{
> +	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> +	struct zynqmp_dpsub *dpsub =
> +		snd_soc_dai_get_drvdata(snd_soc_rtd_to_cpu(rtd, 0));
> +	struct zynqmp_dpsub_audio *audio = dpsub->audio;
> +
> +	guard(mutex)(&audio->enable_lock);
> +
> +	/* Nothing to do */
> +	if (audio->enabled_streams > 1) {
> +		audio->enabled_streams--;
> +		return 0;
> +	}
> +
> +	pm_runtime_put(dpsub->dev);
> +
> +	zynqmp_dp_audio_disable(dpsub->dp);
> +
> +	/*
> +	 * Reset doesn't work. If we assert reset between audio stop and start,
> +	 * the audio won't start anymore. Probably we are missing writing
> +	 * some audio related registers. A/B buf?
> +	 */
> +	/*
> +	zynqmp_disp_audio_write(audio, ZYNQMP_DISP_AUD_SOFT_RESET,
> +				ZYNQMP_DISP_AUD_SOFT_RESET_AUD_SRST);
> +	*/
> +
> +	clk_disable_unprepare(dpsub->aud_clk);
> +
> +	audio->current_rate = 0;
> +	audio->enabled_streams--;
> +
> +	return 0;
> +}
> +
> +static const struct snd_soc_dai_ops zynqmp_dp_dai_ops = {
> +	.hw_params	= dp_dai_hw_params,
> +	.hw_free	= dp_dai_hw_free,
> +};
> +
> +/*
> + * Min = 10 * log10(0x1 / 0x2000) = -39.13
> + * Max = 10 * log10(0xffffff / 0x2000) = 9.03
> + */
> +static const DECLARE_TLV_DB_RANGE(zynqmp_dp_tlv,
> +	0x0, 0x0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, -3913, 1),
> +	0x1, 0x2000, TLV_DB_LINEAR_ITEM(-3913, 0),
> +	0x2000, 0xffff, TLV_DB_LINEAR_ITEM(0, 903),
> +);
> +
> +static const struct snd_kcontrol_new zynqmp_dp_snd_controls[] = {
> +	SOC_SINGLE_TLV("Input0 Playback Volume", 0,
> +		       0, 0xffff, 0, zynqmp_dp_tlv),
> +	SOC_SINGLE_TLV("Input1 Playback Volume", 1,
> +		       0, 0xffff, 0, zynqmp_dp_tlv),
> +};
> +
> +/*
> + * Note: these read & write functions only support two "registers", 0 and 1,
> + * for volume 0 and 1. In other words, these are not real register read/write
> + * functions.
> + *
> + * This is done to support caching the volume value for the case where the
> + * hardware is not enabled, and also to support locking as volumes 0 and 1
> + * are in the same register.
> + */
> +static unsigned int zynqmp_dp_dai_read(struct snd_soc_component *component,
> +				       unsigned int reg)
> +{
> +	struct zynqmp_dpsub *dpsub = dev_get_drvdata(component->dev);
> +	struct zynqmp_dpsub_audio *audio = dpsub->audio;
> +
> +	return audio->volumes[reg];
> +}
> +
> +static int zynqmp_dp_dai_write(struct snd_soc_component *component,
> +			       unsigned int reg, unsigned int val)
> +{
> +	struct zynqmp_dpsub *dpsub = dev_get_drvdata(component->dev);
> +	struct zynqmp_dpsub_audio *audio = dpsub->audio;
> +
> +	guard(mutex)(&audio->enable_lock);
> +
> +	audio->volumes[reg] = val;
> +
> +	if (audio->enabled_streams)
> +		zynqmp_dp_audio_write(audio, ZYNQMP_DISP_AUD_MIXER_VOLUME,
> +				      audio->volumes[0] |
> +				      (audio->volumes[1] << 16));
> +
> +	return 0;
> +}
> +
> +static const struct snd_soc_component_driver zynqmp_dp_component_driver = {
> +	.idle_bias_on		= 1,
> +	.use_pmdown_time	= 1,
> +	.endianness		= 1,
> +	.controls		= zynqmp_dp_snd_controls,
> +	.num_controls		= ARRAY_SIZE(zynqmp_dp_snd_controls),
> +	.read			= zynqmp_dp_dai_read,
> +	.write			= zynqmp_dp_dai_write,
> +};
> +
> +int zynqmp_audio_init(struct zynqmp_dpsub *dpsub)
> +{
> +	struct platform_device *pdev = to_platform_device(dpsub->dev);
> +	struct device *dev = dpsub->dev;
> +	struct zynqmp_dpsub_audio *audio;
> +	struct snd_soc_card *card;
> +	void *dev_data;
> +	int ret;
> +
> +	if (!dpsub->aud_clk)
> +		return 0;
> +
> +	audio = devm_kzalloc(dev, sizeof(*audio), GFP_KERNEL);
> +	if (!audio)
> +		return -ENOMEM;
> +
> +	dpsub->audio = audio;
> +
> +	mutex_init(&audio->enable_lock);
> +
> +	/* 0x2000 is the zero level, no change */
> +	audio->volumes[0] = 0x2000;
> +	audio->volumes[1] = 0x2000;
> +
> +	audio->dai_name = devm_kasprintf(dev, GFP_KERNEL,
> +					 "%s-dai", dev_name(dev));
> +
> +	for (unsigned int i = 0; i < ZYNQMP_NUM_PCMS; ++i) {
> +		audio->link_names[i] = devm_kasprintf(dev, GFP_KERNEL,
> +						      "%s-dp-%u", dev_name(dev), i);
> +		audio->pcm_names[i] = devm_kasprintf(dev, GFP_KERNEL,
> +						     "%s-pcm-%u", dev_name(dev), i);
> +	}
> +
> +	audio->base = devm_platform_ioremap_resource_byname(pdev, "aud");
> +	if (IS_ERR(audio->base))
> +		return PTR_ERR(audio->base);
> +
> +	/* Create CPU DAI */
> +
> +	audio->dai_driver = (struct snd_soc_dai_driver) {
> +		.name		= audio->dai_name,
> +		.ops		= &zynqmp_dp_dai_ops,
> +		.playback	= {
> +			.channels_min	= 2,
> +			.channels_max	= 2,
> +			.rates		= SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
> +			.formats	= SNDRV_PCM_FMTBIT_S16_LE,
> +		},
> +	};
> +
> +	ret = devm_snd_soc_register_component(dev, &zynqmp_dp_component_driver,
> +					      &audio->dai_driver, 1);
> +	if (ret) {
> +		dev_err(dev, "Failed to register CPU DAI\n");
> +		return ret;
> +	}
> +
> +	/* Create PCMs */
> +
> +	for (unsigned int i = 0; i < ZYNQMP_NUM_PCMS; ++i) {
> +		struct snd_dmaengine_pcm_config *pcm_config =
> +			&audio->pcm_configs[i];
> +
> +		*pcm_config = (struct snd_dmaengine_pcm_config){
> +			.name = audio->pcm_names[i],
> +			.pcm_hardware = &zynqmp_dp_pcm_hw,
> +			.prealloc_buffer_size = 64 * 1024,
> +			.chan_names[SNDRV_PCM_STREAM_PLAYBACK] =
> +				i == 0 ? "aud0" : "aud1",
> +		};
> +
> +		ret = devm_snd_dmaengine_pcm_register(dev, pcm_config, 0);
> +		if (ret) {
> +			dev_err(dev, "Failed to register PCM %u\n", i);
> +			return ret;
> +		}
> +	}
> +
> +	/* Create card */
> +
> +	card = &audio->card;
> +	card->name = "DisplayPort";
> +	card->long_name = "DisplayPort Monitor";
> +	card->driver_name = "zynqmp_dpsub";
> +	card->dev = dev;
> +	card->owner = THIS_MODULE;
> +	card->num_links = ZYNQMP_NUM_PCMS;
> +	card->dai_link = audio->links;
> +
> +	for (unsigned int i = 0; i < ZYNQMP_NUM_PCMS; ++i) {
> +		struct snd_soc_dai_link *link = &card->dai_link[i];
> +
> +		link->ops = &zynqmp_dp_ops;
> +
> +		link->name = audio->link_names[i];
> +		link->stream_name = audio->link_names[i];
> +
> +		link->cpus = &audio->components[i].cpu;
> +		link->num_cpus = 1;
> +		link->cpus[0].dai_name = audio->dai_name;
> +
> +		link->codecs = &audio->components[i].codec;
> +		link->num_codecs = 1;
> +		link->codecs[0].name = "snd-soc-dummy";
> +		link->codecs[0].dai_name = "snd-soc-dummy-dai";
> +
> +		link->platforms = &audio->components[i].platform;
> +		link->num_platforms = 1;
> +		link->platforms[0].name = audio->pcm_names[i];
> +	}
> +
> +	/*
> +	 * HACK: devm_snd_soc_register_card() overwrites current drvdata
> +	 * so we need to hack it back.
> +	 */
> +	dev_data = dev_get_drvdata(dev);
> +	ret = devm_snd_soc_register_card(dev, card);
> +	dev_set_drvdata(dev, dev_data);
> +	if (ret) {
> +		/*
> +		 * As older dtbs may not have the audio channel dmas defined,
> +		 * instead of returning an error here we'll continue and just
> +		 * mark the audio as disabled.
> +		 */
> +		dev_err(dev, "Failed to register sound card, disabling audio support\n");
> +
> +		devm_kfree(dev, audio);
> +		dpsub->audio = NULL;
> +
> +		return 0;
> +	}
> +
> +	return 0;
> +}
> +
> +void zynqmp_audio_uninit(struct zynqmp_dpsub *dpsub)
> +{
> +	struct zynqmp_dpsub_audio *audio = dpsub->audio;
> +
> +	if (!audio)
> +		return;
> +
> +	if (!dpsub->aud_clk)
> +		return;
> +
> +	mutex_destroy(&audio->enable_lock);
> +}
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
> index f5781939de9c..a72ffb31a2e8 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
> @@ -56,36 +56,6 @@ static const struct dev_pm_ops zynqmp_dpsub_pm_ops = {
>   	SET_SYSTEM_SLEEP_PM_OPS(zynqmp_dpsub_suspend, zynqmp_dpsub_resume)
>   };
>   
> -/* -----------------------------------------------------------------------------
> - * DPSUB Configuration
> - */
> -
> -/**
> - * zynqmp_dpsub_audio_enabled - If the audio is enabled
> - * @dpsub: DisplayPort subsystem
> - *
> - * Return if the audio is enabled depending on the audio clock.
> - *
> - * Return: true if audio is enabled, or false.
> - */
> -bool zynqmp_dpsub_audio_enabled(struct zynqmp_dpsub *dpsub)
> -{
> -	return !!dpsub->aud_clk;
> -}
> -
> -/**
> - * zynqmp_dpsub_get_audio_clk_rate - Get the current audio clock rate
> - * @dpsub: DisplayPort subsystem
> - *
> - * Return: the current audio clock rate.
> - */
> -unsigned int zynqmp_dpsub_get_audio_clk_rate(struct zynqmp_dpsub *dpsub)
> -{
> -	if (zynqmp_dpsub_audio_enabled(dpsub))
> -		return 0;
> -	return clk_get_rate(dpsub->aud_clk);
> -}
> -
>   /* -----------------------------------------------------------------------------
>    * Probe & Remove
>    */
> @@ -264,10 +234,17 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev)
>   			goto err_disp;
>   	}
>   
> +	ret = zynqmp_audio_init(dpsub);
> +	if (ret)
> +		goto err_drm_cleanup;
> +
>   	dev_info(&pdev->dev, "ZynqMP DisplayPort Subsystem driver probed");
>   
>   	return 0;
>   
> +err_drm_cleanup:
> +	if (dpsub->drm)
> +		zynqmp_dpsub_drm_cleanup(dpsub);
>   err_disp:
>   	drm_bridge_remove(dpsub->bridge);
>   	zynqmp_disp_remove(dpsub);
> @@ -287,6 +264,8 @@ static void zynqmp_dpsub_remove(struct platform_device *pdev)
>   {
>   	struct zynqmp_dpsub *dpsub = platform_get_drvdata(pdev);
>   
> +	zynqmp_audio_uninit(dpsub);
> +
>   	if (dpsub->drm)
>   		zynqmp_dpsub_drm_cleanup(dpsub);
>   
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
> index b18554467e9c..49875529c2a4 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
> @@ -12,6 +12,8 @@
>   #ifndef _ZYNQMP_DPSUB_H_
>   #define _ZYNQMP_DPSUB_H_
>   
> +#include <linux/types.h>
> +
>   struct clk;
>   struct device;
>   struct drm_bridge;
> @@ -39,6 +41,8 @@ enum zynqmp_dpsub_format {
>   	ZYNQMP_DPSUB_FORMAT_YONLY,
>   };
>   
> +struct zynqmp_dpsub_audio;
> +
>   /**
>    * struct zynqmp_dpsub - ZynqMP DisplayPort Subsystem
>    * @dev: The physical device
> @@ -77,10 +81,17 @@ struct zynqmp_dpsub {
>   	struct zynqmp_dp *dp;
>   
>   	unsigned int dma_align;
> +
> +	struct zynqmp_dpsub_audio *audio;
>   };
>   
> -bool zynqmp_dpsub_audio_enabled(struct zynqmp_dpsub *dpsub);
> -unsigned int zynqmp_dpsub_get_audio_clk_rate(struct zynqmp_dpsub *dpsub);
> +#ifdef CONFIG_DRM_ZYNQMP_DPSUB_AUDIO
> +int zynqmp_audio_init(struct zynqmp_dpsub *dpsub);
> +void zynqmp_audio_uninit(struct zynqmp_dpsub *dpsub);
> +#else
> +static inline int zynqmp_audio_init(struct zynqmp_dpsub *dpsub) { return 0; }
> +static inline void zynqmp_audio_uninit(struct zynqmp_dpsub *dpsub) { }
> +#endif
>   
>   void zynqmp_dpsub_release(struct zynqmp_dpsub *dpsub);
>   
> 

This looks good to me. Please feel free to add -

Reviewed-by: Vishal Sagar <vishal.sagar at amd.com>

Regards
Vishal Sagar


From james.clark at linaro.org  Wed Dec 18 08:07:39 2024
From: james.clark at linaro.org (James Clark)
Date: Wed, 18 Dec 2024 16:07:39 +0000
Subject: [PATCH v7 8/9] coresight: tools: Add configuration table test
 tools
In-Reply-To: <CAJ9a7VhG0Mxo=66JpGkPYDBLwo_fmv6BbLx2jPLeDd76f2gfCQ@mail.gmail.com>
References: <20241127134256.2254851-1-mike.leach@linaro.org>
 <20241127134256.2254851-9-mike.leach@linaro.org>
 <9cb1ef5e-eb61-4177-a039-4049850196a5@linaro.org>
 <CAJ9a7VhG0Mxo=66JpGkPYDBLwo_fmv6BbLx2jPLeDd76f2gfCQ@mail.gmail.com>
Message-ID: <5e89efa7-6780-404b-977f-76e96602e298@linaro.org>



On 12/12/2024 12:03 pm, Mike Leach wrote:
> Hi James
> 
> On Tue, 3 Dec 2024 at 14:25, James Clark <james.clark at linaro.org> wrote:
>>
>>
>>
>> On 27/11/2024 1:42 pm, Mike Leach wrote:
>>> Add an example config table generator to test loading configuration
>>> tables.
>>>
>>> Provides a table buffer writer function that can be re-used in other
>>> userspace programs.
>>>
>>> Table write format matches that expected by the corresponding reader
>>> in the configfs driver code.
>>>
>>> Generates tables and outputs in form of binary files.
>>>
>>> Add a config table file reader and printer. Takes in config table files
>>> and prints the contents. Uses table reader source from kernel driver.
>>>
>>> Signed-off-by: Mike Leach <mike.leach at linaro.org>
>>> ---
>>>    MAINTAINERS                                   |   1 +
>>>    .../coresight/coresight-config-table.h        |   5 +
>>
>> Hi Mike,
>>
>> Isn't there some convention about maintaining a copy of kernel headers
>> in the tools? Especially as you wouldn't rebuild the tools after
>> updating the kernel headers so breakages might go unnoticed.
>>
> 
> Not sure - perf keeps a copy and has a check script on build to ensure
> the copy matches the kernel version.
> Keeping two copies of the same thing always strikes me as poor
> practice, so I went for copying over.
> 
> Both methods risk breakages when something in the kernel changes.
> 

You might want to check tools/include/uapi/README which goes over it in 
more detail. I don't think it claims that it's perfect, but just better 
than alternatives. It would make sense to follow it for consistency more 
than anything.

>> [...]
>>
>>> +
>>> +/*
>>> + * sets of presets leaves strobing window constant while varying period to allow
>>> + * experimentation with mark / space ratios for various workloads
>>> + */
>>> +static u64 afdo_set_a_presets[AFDO_NR_PRESETS][AFDO_NR_PARAM_SUM] = {
>>> +     { 2000, 100 },
>>> +     { 2000, 1000 },
>>> +     { 2000, 5000 },
>>> +     { 2000, 10000 },
>>> +     { 4000, 100 },
>>
>> The comment above here looks like its for example1, this one does vary
>> the window size.
>>
>> Probably only example2 is enough, I assumed they were different but
>> example2 is basically the same as example1 with an extra preset list. We
>> could comment that the second preset list is optional and delete
>> example1. Saves people reading more and wondering what the difference is.
>>
> 
> Yes - perhaps both examples were not necessary - but the point was you
> can have two configs in a single loadable table.
> 
>> I tried to make an example that doesn't use an existing feature by
>> reacreating afdo from scratch which I thought would be a good example.
>> It's pasted at the end. I had to copy paste the ETMv4 macros and
>> constants though, I couldn't include them in the userspace generator
>> because of this error:
>>
> 
> The updated ETM config set that is to follow addresses this issue -
> the macros are split off into a separate file  (and adds in a whole
> lot of validation - ensuring a configuration cannot specify and
> allocate more resources than are available.)
> This is also the reason that the examples provided were very simple.
> More complex ones are to follow!
> 
> This set was focused on loading tables so that the next patchsets
> dealing with resource validating ETM configs and CTI configs had an
> easy to use test platform.
> 
> 
>>     coresight-config.h:10:10: fatal error: linux/coresight.h: No such
>> file
>>     or directory
>>      10 | #include <linux/coresight.h>
>>
>> I also got this error when loading it:
>>
>> Unable to handle kernel NULL pointer dereference at virtual address
>> 0000000000000008
>>
>> cscfg_reset_feat (drivers/hwtracing/coresight/coresight-config.c:64
>> coresight-config.c:124) coresight
>> cscfg_load_config_sets
>> (drivers/hwtracing/coresight/coresight-syscfg.c:217
>> coresight-syscfg.c:262 coresight-syscfg.c:492 coresight-syscfg.c:610)
>> coresight
>> cscfg_dyn_load_cfg_table
>> (drivers/hwtracing/coresight/coresight-syscfg-configfs.c:294) coresight
>> cscfg_cfg_load_table_write
>> (drivers/hwtracing/coresight/coresight-syscfg-configfs.c:799) coresight
>> configfs_release_bin_file (fs/configfs/file.c:415)
>> __fput (fs/file_table.c:432)
>> __fput_sync (fs/file_table.c:517)
>> __arm64_sys_close (fs/open.c:1568 fs/open.c:1550 fs/open.c:1550)
>> invoke_syscall (arch/arm64/kernel/syscall.c:?
>> arch/arm64/kernel/syscall.c:49)
>> el0_svc_common (include/linux/thread_info.h:127
>> arch/arm64/kernel/syscall.c:140)
>> do_el0_svc (arch/arm64/kernel/syscall.c:152)
>>
> 
> I'll go back to my tests to check I was testing what I thought I was -
> and didn't accidentally change something after testing and before
> sending the patchset.
> 
>>
>> So I'm wondering if we can do the same thing by setting values via
>> individual files rather than one binary blob which would avoid some of
>> these issues. From what I understand the feature params can already be
>> set directly this way via
>> /sys/kernel/config/cs-syscfg/features/strobing/params/period/value
>>
> 
> 
>> We'd have to add a way to add new configs with a mkdir, then the same
>> things can be configured without needing an additional tool. Links
>> between features and configs can be done with symlinks which is also
>> mentioned in the configfs docs.
>>
>> Something like this would be a bit like the current version:
>>
>>    # ls /config/cs-syscfg
>>    configurations
>>    features
>>
>>    # mkdir /config/cs-syscfg/features/my_config
>>    # ls /config/cs-syscfg/features/my_config
>>    description
>>    matches
>>    regs_desc
>>    params
>>
>>    # mkdir /config/cs-syscfg/features/my_config/regs_desc/TRCRSCTLRn0
>>    # ls /config/cs-syscfg/features/my_config/TRCRSCTLRn0
>>    type
>>    offset
>>    val
>>    mask
>>
> 
> This is precisely what I wanted to avoid. Doing it this way is both
> time consuming for the user and ends up reproducing most of the sysfs
> files in configfs.
> 

I thought I'd suggest the alternative in case Christoph's previous 
comment about not loading a binary blob was a hard nack. I understand 
your counter points about why the blob is better automatically, but I 
don't think any of them are completely unsolvable or blocking with the 
alternate implementation.

For the point about being time consuming, personally I found it quite 
time consuming to use the compiler and write in C. Rather than a pasted 
bash script that just lists each config element:

   echo "12" > /config/cs-syscfg/features/my_config/TRCRSCTLRn0
   echo "11" > /config/cs-syscfg/features/my_config/TRCRSCTLRn1
   ... etc ...

> Parameters are there to allow a limited amount of relevent runtime
> adjustment. Parameter values may also only populate part of a hw
> register depending on use case.
> 
 > The resource approach allows us to define certain bitfields e.g.> 
Branch broadcast - as user configurable - but omit anything users are
> not allowed to meddle with.
> 

This sounds like a mask file along side each register could be used to 
determine which bits to populate for a specific use case. And there 
could be kernel and user provided masks to limit which bits are written.

> The table load is atomic - it is validated and succeeds or fails
> completely. The load mechanism prevents the new configuration from
> becoming visible until it is loaded. The configfs per file method has
> an issue in deciding when the configuration is "complete". If you look
> in the configfs docs/source there was at one time  a  "commit"
> methodology proposed, but this never came to fruition.
> 

Yeah I was going to suggest some kind of "commit" file or "active" flag. 
Or by creating a symlink into an "active" folder at which point the 
config becomes write only (or writes are cached until the next use of 
the config which Suzuki suggested for another sysfs change on the list 
at the moment).

For validation, each field would be validated on write whether the 
config is already active or not. So presumably a script writing a list 
of config values would fail before reaching the "activation" or "commit" 
step.

> Table load  re-uses the same mechanisms as the built-in and loadable
> module methods for adding configurations, but without the need for
> re-compiling the kernel / compiling against a specific kernel -
> meaning loadable tables are dependent only on the hardware available,
 > not the kernel version.

Isn't this the same as with the file approach? Even with the binary blob 
you can't configure a device that the kernel doesn't know about. And 
plain text files can be written to and reconfigured without recompiling 
or using a specific kernel version.

> Adding a per file option means that the new
> configurations would be different from the current load methods
> upstream
> 

This is true, but this binary blob compiler also felt quite different, 
and I wasn't able to blindly copy paste the existing autofdo config into 
it. It needed just as much work to get it to compile as it would have 
been to write the equivalent bash script echoing the config values.

 > - and appear differently in configfs.

I don't think that my suggestion requires that it appears differently at 
the point of use though. After a successful activation the configs could 
appear for use in the same way as the existing module loaded configs.

With all of that said both mechanisms accomplish the same thing, so I 
can't really say to definitely not to it the binary way. Just that it 
feels a bit unusual. Apart from the ACPI example, which is more of a 
firmware thing than something that's controlled by a user at runtime, 
I'm not sure if there is an example of a configfs interface like this?

James

>> But another way could be to enumerate all possible regs for each device.
>> This would remove the need to have all the #defines in whatever tool is
>> making the config (avoiding the #include issue from above):
>>
>>    # mkdir /config/cs-syscfg/features/my_config
>>    # ls /config/cs-syscfg/features/my_config/regs_desc
>>
>>    regs_desc is initially empty, but specify what device it's for to make
>>    all the properties appear (or the mkdir could be done in an etmv4
>>    folder):
>>
>>    # echo "SRC_ETM4" > matches
>>    # ls /config/cs-syscfg/features/my_config/regs_desc
>>    TRCRSCTLRn0
>>    TRCRSCTLRn1
>>    TRCRSCTLRn2
>>    ... etc ...
>>
>>    Now type and offset don't need to be set:
>>
>>    # ls /config/cs-syscfg/features/my_config/regs_desc/TRCRSCTLRn0
>>    val
>>    mask
>>    save
>>
>> Don't we already have the full list of parameters in
>> etm4_cfg_map_reg_offset(), so we can expose this to users via configfs
>> directly rather than needing any tooling. And doesn't any new device
>> that's supported by the config mechanism need to know about all its
>> parameters, so it wouldn't remove any flexibility?
>>
> 
> Mike
> 
> 
>>
> 
> 
> 
> --
> Mike Leach
> Principal Engineer, ARM Ltd.
> Manchester Design Centre. UK



From conor at kernel.org  Wed Dec 18 08:10:59 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 16:10:59 +0000
Subject: [PATCH] dtoverlays: Added DT overlay file for MAX98090 and the
 detailed steps for its usage is included in
 https://github.com/Poojaa-Rangaiah/DeviceTreeOverlay-for-MAX98090 .
In-Reply-To: <CAOnmTr91ufdFAci2OR0ZnQbtrw94DzN+uEnkgoB6kiXFK+b4bA@mail.gmail.com>
References: <20241218065848.12254-1-poojaamonica94@gmail.com>
 <20241218-arrange-pointer-cdd39770b48b@spud>
 <CAOnmTr91ufdFAci2OR0ZnQbtrw94DzN+uEnkgoB6kiXFK+b4bA@mail.gmail.com>
Message-ID: <20241218-widen-ladies-8539476e3b80@spud>

On Wed, Dec 18, 2024 at 09:25:13PM +0530, Poojaa Rangaiah wrote:
> 
> On Wed, Dec 18, 2024, 7:58?PM Conor Dooley <conor at kernel.org> wrote:
> 
> > On Wed, Dec 18, 2024 at 12:28:48PM +0530, Poojaa R wrote:
> > > Only the driver files were existing for max98090 audio codec (playback
> > and capture) but now the max98090.dts file is also included in
> > linux/arch/arm/boot/dts/overlays/.
> > > new file:   arch/arm/boot/dts/overlays/max98090.dts
> > >
> > > Signed-off-by: Poojaa R <poojaamonica94 at gmail.com>
> >
> > Why have you send this patch for your random github tree to lkml?

> Sorry for that, I wanted it to be just mentioned in commits so people who
> don't have an idea can refer to it. But I didn't expect that to be
> mentioned in the subject.

Right, so it is not a random patch but one you want included in
mainline? Given this is something only usable on the RPi, you should
move this file to the broadcom directory and CC the relevant
maintainers.

Additionally, the correct filetype for overlays is .dtso nor should
there be dtso files in the kernel tree that are never built.

Cheers,
Conor.

> >
> > Thanks,
> > Conor.
> >
> > > ---
> > >  arch/arm/boot/dts/overlays/max98090.dts | 96 +++++++++++++++++++++++++
> > >  1 file changed, 96 insertions(+)
> > >  create mode 100644 arch/arm/boot/dts/overlays/max98090.dts
> > >
> > > diff --git a/arch/arm/boot/dts/overlays/max98090.dts
> > b/arch/arm/boot/dts/overlays/max98090.dts
> > > new file mode 100644
> > > index 000000000000..eaf197384edb
> > > --- /dev/null
> > > +++ b/arch/arm/boot/dts/overlays/max98090.dts
> > > @@ -0,0 +1,96 @@
> > > +/*
> > > + * Device Tree Overlay for MAX98090, MAX98091 Audio Codec.
> > > + * https://github.com/Poojaa-Rangaiah/DeviceTreeOverlay-for-MAX98090
> > => for more details.
> > > + * MAX98090 audio codec as master and Raspberry Pi as slave.
> > > + */
> > > +
> > > +/dts-v1/;
> > > +/plugin/;
> > > +
> > > +/ {
> > > +    compatible = "brcm,bcm2835", "brcm,bcm2711";
> > > +
> > > +    fragment at 0 {
> > > +        target = <&i2s_clk_consumer>;
> > > +        __overlay__ {
> > > +            status = "okay";
> > > +        };
> > > +    };
> > > +
> > > +    fragment at 1 {
> > > +        target = <&i2c1>;
> > > +        __overlay__ {
> > > +            #address-cells = <1>;
> > > +            #size-cells = <0>;
> > > +            status = "okay";
> > > +            max98090_codec: max98090 at 10 {
> > > +                #sound-dai-cells = <0>;
> > > +                compatible = "maxim,max98090","maxim,max98091";
> > > +                reg = <0x10>;
> > > +                interrupt-parent = <&gpio>;
> > > +                interrupts = <27 2>; /* GPIO 27 as Edge_Falling_IRQ (2)
> > */
> > > +                maxim,micbias = <3>;
> > > +                status = "okay";
> > > +            };
> > > +        };
> > > +    };
> > > +
> > > +    fragment at 2 {
> > > +        target-path = "/";
> > > +        __overlay__ {
> > > +            clk_oscillator: oscillator {
> > > +                compatible = "fixed-clock";
> > > +                #clock-cells = <0>;
> > > +                clock-frequency = <12288000>;  /* Frequency of the
> > external oscillator (mclk = 12.288 MHz) but can also be 11.2896 MHz/12
> > MHz/13 MHz/26 MHz/19.2 MHz. */
> > > +                clock-output-names = "mclk";
> > > +            };
> > > +        };
> > > +    };
> > > +
> > > +    fragment at 3 {
> > > +        target = <&sound>;
> > > +        sound_overlay: __overlay__ {
> > > +            compatible = "simple-audio-card";
> > > +            simple-audio-card,format = "i2s";
> > > +            simple-audio-card,name = "MAX98090-Codec";
> > > +            simple-audio-card,bitclock-master = <&dailink0_master>;
> > > +            simple-audio-card,frame-master = <&dailink0_master>;
> > > +
> > > +            simple-audio-card,widgets =
> > > +                "Microphone", "Mic Jack",
> > > +                "Speaker", "Speaker",
> > > +                "Line", "Line In",
> > > +                "Line", "Line Out",
> > > +                "Headphone", "Headphone Jack";
> > > +
> > > +            simple-audio-card,routing =
> > > +                "Headphone Jack", "HPL",
> > > +                "Headphone Jack", "HPR",
> > > +                "Line Out", "RCVL",
> > > +                "Line Out", "RCVR",
> > > +                /* Uncomment any of these below lines if the Line
> > Input(s) is(are) used else leave it as such. */
> > > +                //"IN5", "Line In",  /* IN1/IN2/IN3/IN4/IN6 (For single
> > ended input) */
> > > +                //"IN56", "Line In", /* IN34 (For differential inputs)
> > */
> > > +                "MIC1", "Mic Jack",
> > > +                "MIC2", "Mic Jack",
> > > +                "Speaker", "SPKL",
> > > +                "Speaker", "SPKR";
> > > +
> > > +            status = "okay";
> > > +
> > > +            simple-audio-card,cpu {
> > > +                sound-dai = <&i2s_clk_consumer>;
> > > +            };
> > > +
> > > +            dailink0_master: simple-audio-card,codec {
> > > +                sound-dai = <&max98090_codec>;
> > > +                clocks = <&clk_oscillator>;
> > > +            };
> > > +        };
> > > +    };
> > > +
> > > +    __overrides__ {
> > > +        card-name = <&sound_overlay>, "simple-audio-card,name";
> > > +    };
> > > +};
> > > +
> > > --
> > > 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/20241218/1e450d7f/attachment.sig>

From james.quinlan at broadcom.com  Wed Dec 18 08:20:26 2024
From: james.quinlan at broadcom.com (Jim Quinlan)
Date: Wed, 18 Dec 2024 11:20:26 -0500
Subject: [PATCH v4 06/10] PCI: brcmstb: Enable external MSI-X if available
In-Reply-To: <ab136131-a306-4344-adaf-904e3b32326e@suse.de>
References: <20241025124515.14066-1-svarbanov@suse.de> <20241025124515.14066-7-svarbanov@suse.de>
 <f0a734d9-6bf6-4d28-b30b-99b6be9f62dc@broadcom.com> <ab136131-a306-4344-adaf-904e3b32326e@suse.de>
Message-ID: <CA+-6iNytvANeUb3ugW0q3B18MTNwnJps_yggonKRjXh_sTWHmA@mail.gmail.com>

On Wed, Dec 18, 2024 at 9:54?AM Stanimir Varbanov <svarbanov at suse.de> wrote:
>
> Hi Jim,
>
> Thanks for comments!
>
> On 12/11/24 10:01 PM, James Quinlan wrote:
> > On 10/25/24 08:45, Stanimir Varbanov wrote:
> >> On RPi5 there is an external MIP MSI-X interrupt controller
> >> which can handle up to 64 interrupts.
> >>
> >> Signed-off-by: Stanimir Varbanov <svarbanov at suse.de>
> >> ---
> >> v3 -> v4:
> >>   - no changes.
> >>
> >>   drivers/pci/controller/pcie-brcmstb.c | 63 +++++++++++++++++++++++++--
> >>   1 file changed, 59 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/
> >> controller/pcie-brcmstb.c
> >> index c01462b07eea..af01a7915c94 100644
> >> --- a/drivers/pci/controller/pcie-brcmstb.c
> >> +++ b/drivers/pci/controller/pcie-brcmstb.c
> >> @@ -1318,6 +1318,52 @@ static int brcm_pcie_start_link(struct
> >> brcm_pcie *pcie)
> >>       return 0;
> >>   }
> >>   +static int brcm_pcie_enable_external_msix(struct brcm_pcie *pcie,
> >> +                      struct device_node *msi_np)
> >> +{
> >> +    struct inbound_win inbound_wins[PCIE_BRCM_MAX_INBOUND_WINS];
> >> +    u64 msi_pci_addr, msi_phys_addr;
> >> +    struct resource r;
> >> +    int mip_bar, ret;
> >> +    u32 val, reg;
> >> +
> >> +    ret = of_property_read_reg(msi_np, 1, &msi_pci_addr, NULL);
> >> +    if (ret)
> >> +        return ret;
> >> +
> >> +    ret = of_address_to_resource(msi_np, 0, &r);
> >> +    if (ret)
> >> +        return ret;
> >> +
> >> +    msi_phys_addr = r.start;
> >> +
> >> +    /* Find free inbound window for MIP access */
> >> +    mip_bar = brcm_pcie_get_inbound_wins(pcie, inbound_wins);
> >> +    if (mip_bar < 0)
> >> +        return mip_bar;
> >> +
> >> +    mip_bar += 1;
> >> +    reg = brcm_bar_reg_offset(mip_bar);
> >> +
> >> +    val = lower_32_bits(msi_pci_addr);
> >> +    val |= brcm_pcie_encode_ibar_size(SZ_4K);
> >> +    writel(val, pcie->base + reg);
> >> +
> >> +    val = upper_32_bits(msi_pci_addr);
> >> +    writel(val, pcie->base + reg + 4);
> >> +
> >> +    reg = brcm_ubus_reg_offset(mip_bar);
> >> +
> >> +    val = lower_32_bits(msi_phys_addr);
> >> +    val |= PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_ACCESS_EN_MASK;
> >> +    writel(val, pcie->base + reg);
> >> +
> >> +    val = upper_32_bits(msi_phys_addr);
> >> +    writel(val, pcie->base + reg + 4);
> >
> > Hi Stan,
> >
> > It looks like all this is doing is setting up an identity-mapped inbound
> > window, is that correct?  If so, couldn't you get the same effect by
> > adding an identity-mapped dma-range in the PCIe DT node?
>
> Yes, that approach could work, I verified it.
>
> Do you want me to drop this patch from the series and make the relevant
> changes in PCIe dma-ranges properties?
>
Hi Stan,

Yes please, that was what I was hoping for -- the less code the
better, assuming everything still works :-)

Thanks & regards,
Jim Quinlan
Broadcom STB/CM

> ~Stan
>
>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4210 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241218/631630ae/attachment.p7s>

From nicolas.dufresne at collabora.com  Wed Dec 18 08:31:30 2024
From: nicolas.dufresne at collabora.com (Nicolas Dufresne)
Date: Wed, 18 Dec 2024 11:31:30 -0500
Subject: [PATCH] arm64: defconfig: Enable RFKILL GPIO
Message-ID: <20241218-rk3588-rfkill-gpio-config-v1-1-dfdf464f97d4@collabora.com>

Enable as a module the RFKILL GPIO driver. This is needed to power WiFi
and Bluetooth radio on various RK3588 board. Without this module, rfkill
will report the switch has hard blocked, which prevents using the WiFi
or Bluetooth feature.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne 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 c62831e6158633f07c1f3532fba62f09b31e7448..9293e988789f10cf074dc80188839a32485bee16 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -200,6 +200,7 @@ CONFIG_CFG80211=m
 CONFIG_MAC80211=m
 CONFIG_MAC80211_LEDS=y
 CONFIG_RFKILL=m
+CONFIG_RFKILL_GPIO=m
 CONFIG_NET_9P=y
 CONFIG_NET_9P_VIRTIO=y
 CONFIG_NFC=m

---
base-commit: e0fc7a7869452b877c26644fdf0b38dd9a6cf8d2
change-id: 20241218-rk3588-rfkill-gpio-config-5c8e0333dae9

Best regards,
-- 
Nicolas Dufresne <nicolas.dufresne at collabora.com>



From jwerner at chromium.org  Wed Dec 18 08:35:45 2024
From: jwerner at chromium.org (Julius Werner)
Date: Wed, 18 Dec 2024 17:35:45 +0100
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <CAD=FV=X61y+RmbWCiZut_HHVS4jPdv_ZB8F+_Hs0R-1aKHdK4w@mail.gmail.com>
References: <20241214005248.198803-1-dianders@chromium.org>
 <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
 <CAODwPW_c+Ycu_zhiDOKN-fH2FEWf2pxr+FcugpqEjLX-nVjQrg@mail.gmail.com>
 <CAD=FV=UHBA7zXZEw3K6TRpZEN-ApOkmymhRCOkz7h+yrAkR_Dw@mail.gmail.com>
 <CAODwPW8s4GhWGuZMUbWVNLYw_EVJe=EeMDacy1hxDLmnthwoFg@mail.gmail.com> <CAD=FV=X61y+RmbWCiZut_HHVS4jPdv_ZB8F+_Hs0R-1aKHdK4w@mail.gmail.com>
Message-ID: <CAODwPW_UNVkyXKxyhZv830bhzsy5idu6GiuR9mut+-qGOtv1pw@mail.gmail.com>

> Given that I'm not going to change the way the existing predicates
> work, if I move the "fallback" setting `max_bhb_k` to 32 to
> spectre_bhb_enable_mitigation() then when we set `max_bhb_k` becomes
> inconsistent between recognized and unrecognized CPUs.

A clean way to fix that could be to change spectre_bhb_loop_affected()
to just return the K-value (rather than change max_bhb_k directly),
and then set max_bhb_k to the max() of that return value and the
existing value when it is called from spectre_bhb_enable_mitigation().
That way, max_bhb_k would only be updated from
spectre_bhb_enable_mitigation().

> I would also say that having `max_bhb_k` get set in an inconsistent
> place opens us up for bugs in the future. Even if it works today, I
> imagine someone could change things in the future such that
> spectre_bhb_enable_mitigation() reads `max_bhb_k` and essentially
> caches it (maybe it constructs an instruction based on it). If that
> happened things could be subtly broken for the "unrecognized CPU" case
> because the first CPU would "cache" the value without it having been
> called on all CPUs.

This would likely already be a problem with the current code, since
spectre_bhb_enable_mitigations() is called one at a time for each CPU
and the max_bhb_k value is only valid once it has been called on all
CPUs. If someone tried to just immediately use the value inside the
function that would just be a bug either way. (Right now this should
not be a problem because max_bhb_k is only used by
spectre_bhb_patch_loop_iter() which ends up being called through
apply_alternatives_all(), which should only run after all those CPU
errata cpu_enable callbacks have been called.)


From arnd at arndb.de  Wed Dec 18 08:35:31 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 18 Dec 2024 17:35:31 +0100
Subject: [PATCH 07/17] riscv: vdso: Switch to generic storage implementation
In-Reply-To: <20241218162031-ee920684-db10-4f17-b1cb-50373d7ea954@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-7-f7aed1bdb3b2@linutronix.de>
 <20241218-action-matchbook-571b597b7f55@spud>
 <20241218162031-ee920684-db10-4f17-b1cb-50373d7ea954@linutronix.de>
Message-ID: <137c0594-e178-4c91-bc8b-5f99b3ddb2f0@app.fastmail.com>

On Wed, Dec 18, 2024, at 16:46, Thomas Wei?schuh wrote:
> On Wed, Dec 18, 2024 at 03:08:28PM +0000, Conor Dooley wrote:
>> On Mon, Dec 16, 2024 at 03:10:03PM +0100, Thomas Wei?schuh wrote:

>> Might be a clang thing, allmodconfig with clang doesn't build either.
>
> The proposed generic storage infrastructure currently expects that all
> its users also use HAVE_GENERIC_VDSO.
> I missed rv32 when checking this assumption.
>
> I can add a bunch of ifdefs into the storage code to handle this.
>
> Or we re-add the time vDSO functions which were removed in commit
> d4c08b9776b3 ("riscv: Use latest system call ABI").
> Today there are upstream ports of musl and glibc which can use them.
> (currently musl even tries to use __vdso_clock_gettime() as 64-bit only
> on rv32 due to a copy-and-paste error from its rv64 code)

Adding back __vdso_clock_gettime() wouldn't work on rv32 because there
is no fallback syscall for it, and it wouldn't really help since
there is no existing userspace that uses time32 structures.

> There is precedence in providing 64bit only vDSO functions, for example
> __vdso_clock_gettime64() in arm.
> I do have a small, so far untested, proof-of-concept patch for it.
> This would even be less code than the ifdefs.
>
> What do you think about it?

Yes, simply exposing the normal time64 syscalls through vdso
should be fine. I think this currently works on everything except
rv32 and sparc32, probably because neither of them have actual
users that are able to test.

       Arnd


From heiko at sntech.de  Wed Dec 18 08:42:29 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 18 Dec 2024 17:42:29 +0100
Subject: (subset) [PATCH v6 00/16] VOP Support for rk3576
In-Reply-To: <20241214081719.3330518-1-andyshrk@163.com>
References: <20241214081719.3330518-1-andyshrk@163.com>
Message-ID: <173454013836.591676.16677827979094919661.b4-ty@sntech.de>


On Sat, 14 Dec 2024 16:16:59 +0800, Andy Yan wrote:
> Thanks for the basic work from Collabora, I can bringup a HDMI
> display out on rk3576.
> 
> PATCH 1 is a carryover from the working when add support for
>     rk3588[0], is very usefull when some people want me
>     help debug some issue online, so I really hope it can
>     be merged at this round.
> PATCH 2~8 are bugfix of rk3588 alpha blending which report and
>     test by Derek
> PATCH 9~13 are preparations for rk3576 support
> PATCH 17~18 are real support for rk376
> 
> [...]

Applied, thanks!

[03/16] drm/rockchip: vop2: Set AXI id for rk3588
        commit: 7b256880fdb2d7f23393b87bb557090f049e686a
[04/16] drm/rockchip: vop2: Setup delay cycle for Esmart2/3
        commit: c766998ba6df126ab6934d32ff2ff080316ec630
[05/16] drm/rockchip: vop2: Check linear format for Cluster windows on rk3566/8
        commit: df063c0b8ffbdca486ab2f802e716973985d8f86
[06/16] drm/rockchip: vop2: Add check for 32 bpp format for rk3588
        commit: 7e8a56c703c67bfa8d3f71a0c1c297bb1252b897
[07/16] drm/rockchip: vop2: include rockchip_drm_drv.h
        commit: 77b1ccb2a27c7b3b118a03bf1730def92070d31b

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From conor at kernel.org  Wed Dec 18 08:42:03 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 16:42:03 +0000
Subject: [PATCH v3 1/9] dt-bindings: regulator: pca9450: Add properties
 for handling LDO5
In-Reply-To: <20241218152842.97483-2-frieder@fris.de>
References: <20241218152842.97483-1-frieder@fris.de>
 <20241218152842.97483-2-frieder@fris.de>
Message-ID: <20241218-yapping-driver-d67cf1662b57@spud>

On Wed, Dec 18, 2024 at 04:27:24PM +0100, Frieder Schrempf wrote:
> From: Frieder Schrempf <frieder.schrempf at kontron.de>
> 
> This reverts commit 27866e3e8a7e93494f8374f48061aa73ee46ceb2 and
> implements a new future-proof way of handling the mismatch between
> the PMIC driver and the hardware for LDO5.
> 
> It turned out that this feature was implemented based on the wrong
> assumption that the SD_VSEL signal needs to be controlled as GPIO
> in any case.
> 
> In fact the straight-forward approach is to mux the signal as
> USDHC_VSELECT and let the USDHC controller do the job.
> 
> Most users never even used this property and the few who did have
> been or are getting migrated to the alternative approach.
> 
> In order to know the current status (which of the two control
> registers is used) for the LDO5 regulator, we need to route back the
> USDHC_VSELECT signal by setting the SION bit in the IOMUX.
> 
> By adding the according GPIO as sd-vsel-gpios to the LDO5 node, we
> allow the regulator driver to sample the current status of the
> SD_VSEL signal that is used to select the correct control register.
> 
> The SD_VSEL on the PMIC is always an input. It's driven by the SoC's
> VSELECT signal (controlled by the USDHC controller) and we use the
> SION bit in the IOMUX to internally loop back the signal in order to
> sample it using the GPIO.
> 
> As the SD_VSEL pin is directly routed to the LDO5 regulator in the
> PMIC, make the sd-vsel-gpios property part of the LDO5 node.
> 
> SoC                                  PMIC
> +-----------------------+           +-------------------+
> |                       |           |                   |
> |                       |           |                   |
> |  GPIO <----------+    |           |                   |
> |                  |    |    SD_VSEL|   +-------+       |
> |  USDHC_VSELECT ->+------------------->| LDO5  |       |
> |                       |           |   +-------+       |
> |                       |           |                   |
> +-----------------------+           +-------------------+
> 
> For boards which have the SD_VSEL tied to a fixed low level, we add
> 'nxp,sd-vsel-fixed-low'. The voltage of LDO5 is therefore only controlled
> by writing to the LDO5CTRL_L register.
> 
> If none of 'nxp,sd-vsel-fixed-low' or 'sd-vsel-gpios' is set, we keep
> the same behavior as before. The driver assumes that SD_VSEL is tied
> high and the LDO5CTRL_H register can be used, which is in fact not true
> for all known boards and works merely by chance.
> 
> Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>

Reviewed-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/20241218/8d695f9b/attachment.sig>

From conor at kernel.org  Wed Dec 18 08:44:06 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 16:44:06 +0000
Subject: [PATCH v1 1/2] dt-bindings: clock: mediatek,mt8188: Add
 VDO1_DPI1_HDMI clock
In-Reply-To: <20241218105415.39206-2-angelogioacchino.delregno@collabora.com>
References: <20241218105415.39206-1-angelogioacchino.delregno@collabora.com>
 <20241218105415.39206-2-angelogioacchino.delregno@collabora.com>
Message-ID: <20241218-twelve-requisite-c63827edfbad@spud>

On Wed, Dec 18, 2024 at 11:54:14AM +0100, AngeloGioacchino Del Regno wrote:
> Add binding for the HDMI TX clock found in the VDO1 controller
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  include/dt-bindings/clock/mediatek,mt8188-clk.h | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/include/dt-bindings/clock/mediatek,mt8188-clk.h b/include/dt-bindings/clock/mediatek,mt8188-clk.h
> index bd5cd100b796..8af44560a74c 100644
> --- a/include/dt-bindings/clock/mediatek,mt8188-clk.h
> +++ b/include/dt-bindings/clock/mediatek,mt8188-clk.h
> @@ -721,6 +721,7 @@
>  #define CLK_VDO1_DPINTF				58
>  #define CLK_VDO1_DISP_MONITOR_DPINTF		59
>  #define CLK_VDO1_26M_SLOW			60
> +#define CLK_VDO1_DPI1_HDMI			61

> -#define CLK_VDO1_NR_CLK				61
> +#define CLK_VDO1_NR_CLK				62

If you can change this, you can delete it ;)
Please do.
-------------- 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/20241218/db0924ce/attachment.sig>

From conor at kernel.org  Wed Dec 18 08:54:44 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 16:54:44 +0000
Subject: [PATCH v1 1/3] dt-bindings: display: mediatek: Add compatibles
 for MT8188 MDP3
In-Reply-To: <20241218105320.38980-2-angelogioacchino.delregno@collabora.com>
References: <20241218105320.38980-1-angelogioacchino.delregno@collabora.com>
 <20241218105320.38980-2-angelogioacchino.delregno@collabora.com>
Message-ID: <20241218-skeleton-rockband-e25b7d60e7f3@spud>

On Wed, Dec 18, 2024 at 11:53:18AM +0100, AngeloGioacchino Del Regno wrote:
> Add compatible strings for the AAL, COLOR, MERGE and PADDING
> hardware components found in MediaTek's MT8188 SoC.
> 
> This hardware is compatible with MT8195.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

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/20241218/3ff808e7/attachment.sig>

From yazen.ghannam at amd.com  Wed Dec 18 08:53:31 2024
From: yazen.ghannam at amd.com (Yazen Ghannam)
Date: Wed, 18 Dec 2024 11:53:31 -0500
Subject: [PATCH v17 3/3] ACPI: APEI: handle synchronous exceptions in
 task work
In-Reply-To: <20241202030527.20586-4-xueshuai@linux.alibaba.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
 <20241202030527.20586-4-xueshuai@linux.alibaba.com>
Message-ID: <20241218165331.GF1155365@yaz-khff2.amd.com>

On Mon, Dec 02, 2024 at 11:05:27AM +0800, Shuai Xue wrote:
> The memory uncorrected error could be signaled by asynchronous interrupt
> (specifically, SPI in arm64 platform), e.g. when an error is detected by
> a background scrubber, or signaled by synchronous exception
> (specifically, data abort exception in arm64 platform), e.g. when a CPU
> tries to access a poisoned cache line. Currently, both synchronous and
> asynchronous error use memory_failure_queue() to schedule
> memory_failure() to exectute in a kworker context.
> 
> As a result, when a user-space process is accessing a poisoned data, a
> data abort is taken and the memory_failure() is executed in the kworker
> context, memory_failure():
> 
>   - will send wrong si_code by SIGBUS signal in early_kill mode, and
>   - can not kill the user-space in some cases resulting a synchronous
>     error infinite loop
> 
> Issue 1: send wrong si_code in early_kill mode
> 
> Since commit a70297d22132 ("ACPI: APEI: set memory failure flags as
> MF_ACTION_REQUIRED on synchronous events")', the flag MF_ACTION_REQUIRED
> could be used to determine whether a synchronous exception occurs on
> ARM64 platform.  When a synchronous exception is detected, the kernel is
> expected to terminate the current process which has accessed poisoned
> page. This is done by sending a SIGBUS signal with an error code
> BUS_MCEERR_AR, indicating an action-required machine check error on
> read.
> 
> However, when kill_proc() is called to terminate the processes who have
> the poisoned page mapped, it sends the incorrect SIGBUS error code
> BUS_MCEERR_AO because the context in which it operates is not the one
> where the error was triggered.
> 
> To reproduce this problem:
> 
>   #sysctl -w vm.memory_failure_early_kill=1
>   vm.memory_failure_early_kill = 1
> 
>   # STEP2: inject an UCE error and consume it to trigger a synchronous error
>   #einj_mem_uc single
>   0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>   injecting ...
>   triggering ...
>   signal 7 code 5 addr 0xffffb0d75000
>   page not present
>   Test passed
> 
> The si_code (code 5) from einj_mem_uc indicates that it is BUS_MCEERR_AO
> error and it is not the fact.
> 
> After this patch:
> 
>   # STEP1: enable early kill mode
>   #sysctl -w vm.memory_failure_early_kill=1
>   vm.memory_failure_early_kill = 1
>   # STEP2: inject an UCE error and consume it to trigger a synchronous error
>   #einj_mem_uc single
>   0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>   injecting ...
>   triggering ...
>   signal 7 code 4 addr 0xffffb0d75000
>   page not present
>   Test passed
> 
> The si_code (code 4) from einj_mem_uc indicates that it is a BUS_MCEERR_AR
> error as we expected.
> 
> Issue 2: a synchronous error infinite loop
> 
> If a user-space process, e.g. devmem, accesses a poisoned page for which
> the HWPoison flag is set, kill_accessing_process() is called to send
> SIGBUS to current processs with error info. Because the memory_failure()
> is executed in the kworker context, it will just do nothing but return
> EFAULT. So, devmem will access the posioned page and trigger an
> exception again, resulting in a synchronous error infinite loop. Such
> exception loop may cause platform firmware to exceed some threshold and
> reboot when Linux could have recovered from this error.
> 
> To reproduce this problem:
> 
>   # STEP 1: inject an UCE error, and kernel will set HWPosion flag for related page
>   #einj_mem_uc single
>   0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>   injecting ...
>   triggering ...
>   signal 7 code 4 addr 0xffffb0d75000
>   page not present
>   Test passed
> 
>   # STEP 2: access the same page and it will trigger a synchronous error infinite loop
>   devmem 0x4092d55b400
> 
> To fix above two issues, queue memory_failure() as a task_work so that
> it runs in the context of the process that is actually consuming the
> poisoned data.
> 
> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
> Tested-by: Ma Wupeng <mawupeng1 at huawei.com>
> Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> Reviewed-by: Xiaofei Tan <tanxiaofei at huawei.com>
> Reviewed-by: Baolin Wang <baolin.wang at linux.alibaba.com>
> Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> ---
>  drivers/acpi/apei/ghes.c | 77 +++++++++++++++++++++++-----------------
>  include/acpi/ghes.h      |  3 --
>  include/linux/mm.h       |  1 -
>  mm/memory-failure.c      | 13 -------
>  4 files changed, 44 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 106486bdfefc..70f2ee3ad1a8 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -467,28 +467,41 @@ static void ghes_clear_estatus(struct ghes *ghes,
>  }
>  
>  /*

The "kernel-doc" format needs an opening "/**".

> - * Called as task_work before returning to user-space.
> - * Ensure any queued work has been done before we return to the context that
> - * triggered the notification.
> + * struct ghes_task_work - for synchronous RAS event
> + *
> + * @twork:                callback_head for task work
> + * @pfn:                  page frame number of corrupted page
> + * @flags:                work control flags
> + *
> + * Structure to pass task work to be handled before
> + * returning to user-space via task_work_add().
>   */
> -static void ghes_kick_task_work(struct callback_head *head)
> +struct ghes_task_work {
> +	struct callback_head twork;
> +	u64 pfn;
> +	int flags;
> +};
> +
> +static void memory_failure_cb(struct callback_head *twork)
>  {
> -	struct acpi_hest_generic_status *estatus;
> -	struct ghes_estatus_node *estatus_node;
> -	u32 node_len;
> +	struct ghes_task_work *twcb = container_of(twork, struct ghes_task_work, twork);
> +	int ret;
>  
> -	estatus_node = container_of(head, struct ghes_estatus_node, task_work);
> -	if (IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
> -		memory_failure_queue_kick(estatus_node->task_work_cpu);
> +	ret = memory_failure(twcb->pfn, twcb->flags);
> +	gen_pool_free(ghes_estatus_pool, (unsigned long)twcb, sizeof(*twcb));
>  
> -	estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
> -	node_len = GHES_ESTATUS_NODE_LEN(cper_estatus_len(estatus));
> -	gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len);
> +	if (!ret || ret == -EHWPOISON || ret == -EOPNOTSUPP)
> +		return;
> +
> +	pr_err("%#llx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",
> +			twcb->pfn, current->comm, task_pid_nr(current));

This is basically the same as the message in kill_proc(). Was there any
consideration to have a shared function? Maybe this could be a future
patch.

> +	force_sig(SIGBUS);
>  }
>  
>  static bool ghes_do_memory_failure(u64 physical_addr, int flags)
>  {
>  	unsigned long pfn;
> +	struct ghes_task_work *twcb;

Minor nit: A common preference I've seen is to order variable
declarations from longest->shortest line length.

But overall, looks okay to me.

Reviewed-by: Yazen Ghannam <yazen.ghannam at amd.com>

Thanks,
Yazen


From conor at kernel.org  Wed Dec 18 08:55:01 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 16:55:01 +0000
Subject: [PATCH v1 2/3] dt-bindings: media: mediatek: mdp3: Add
 compatibles for MT8188 MDP3
In-Reply-To: <20241218105320.38980-3-angelogioacchino.delregno@collabora.com>
References: <20241218105320.38980-1-angelogioacchino.delregno@collabora.com>
 <20241218105320.38980-3-angelogioacchino.delregno@collabora.com>
Message-ID: <20241218-easiness-appraiser-4bbd32caa2cd@spud>

On Wed, Dec 18, 2024 at 11:53:19AM +0100, AngeloGioacchino Del Regno wrote:
> Add compatible strings for the FG, HDR, RSZ, STITCH, TCC, TDSHP
> and WROT hardware components found in MediaTek's MT8188 SoC.
> 
> This hardware is compatible with MT8195.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

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/20241218/4219a5df/attachment.sig>

From larysa.zaremba at intel.com  Wed Dec 18 08:59:51 2024
From: larysa.zaremba at intel.com (Larysa Zaremba)
Date: Wed, 18 Dec 2024 17:59:51 +0100
Subject: [PATCH net-next 1/4] net: ti: Kconfig: Select HSR for ICSSG
 Driver
In-Reply-To: <20241216100044.577489-2-danishanwar@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-2-danishanwar@ti.com>
Message-ID: <Z2L/hwH5pgBV9pSB@lzaremba-mobl.ger.corp.intel.com>

On Mon, Dec 16, 2024 at 03:30:41PM +0530, MD Danish Anwar wrote:
> HSR offloading is supported by ICSSG driver. Select the symbol HSR for
> TI_ICSSG_PRUETH. Also select NET_SWITCHDEV instead of depending on it to
> remove recursive dependency.
>

2 things:
1) The explanation from the cover should have been included in the commit 
   message.
2) Why not `depends on HSR`?
 
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> ---
>  drivers/net/ethernet/ti/Kconfig | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
> index 0d5a862cd78a..ad366abfa746 100644
> --- a/drivers/net/ethernet/ti/Kconfig
> +++ b/drivers/net/ethernet/ti/Kconfig
> @@ -187,8 +187,9 @@ config TI_ICSSG_PRUETH
>  	select PHYLIB
>  	select TI_ICSS_IEP
>  	select TI_K3_CPPI_DESC_POOL
> +	select NET_SWITCHDEV
> +	select HSR
>  	depends on PRU_REMOTEPROC
> -	depends on NET_SWITCHDEV
>  	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
>  	depends on PTP_1588_CLOCK_OPTIONAL
>  	help
> -- 
> 2.34.1
> 
> 


From jassisinghbrar at gmail.com  Wed Dec 18 08:58:09 2024
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Wed, 18 Dec 2024 10:58:09 -0600
Subject: [PATCH v5 2/3] mailbox: add Samsung Exynos driver
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-2-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org> <20241217-acpm-v4-upstream-mbox-v5-2-cd1d3951fe84@linaro.org>
Message-ID: <CABb+yY1W7HM1pry+wf03HFur3F3YdZwpRjrdtZ6aJtWQ2Ed3wQ@mail.gmail.com>

On Tue, Dec 17, 2024 at 3:40?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
....
> +
> +static int exynos_mbox_chan_index(struct mbox_chan *chan)
> +{
> +       struct mbox_controller *mbox = chan->mbox;
> +       int i;
> +
> +       for (i = 0; i < mbox->num_chans; i++)
> +               if (chan == &mbox->chans[i])
> +                       return i;
> +       return -EINVAL;
> +}
>
Maybe simply return (chan - mbox->chans) ?

Cheers!


From csokas.bence at prolan.hu  Wed Dec 18 08:58:49 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?=)
Date: Wed, 18 Dec 2024 17:58:49 +0100
Subject: [PATCH] spi: atmel-qspi: Memory barriers after memory-mapped I/O
Message-ID: <20241218165850.378909-1-csokas.bence@prolan.hu>

The QSPI peripheral control and status registers are
accessible via the SoC's APB bus, whereas MMIO transactions'
data travels on the AHB bus.

Microchip documentation and even sample code from Atmel
emphasises the need for a memory barrier before the first
MMIO transaction to the AHB-connected QSPI, and before the
last write to its registers via APB. This is achieved by
the following lines in `atmel_qspi_transfer()`:

	/* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
	(void)atmel_qspi_read(aq, QSPI_IFR);

However, the current documentation makes no mention to
synchronization requirements in the other direction, i.e.
after the last data written via AHB, and before the first
register access on APB.

---

In our case, we were facing an issue where the QSPI peripheral
would cease to send any new CSR (nCS Rise) interrupts,
leading to a timeout in `atmel_qspi_wait_for_completion()`
and ultimately this panic in higher levels:

	ubi0 error: ubi_io_write: error -110 while writing 63108 bytes to PEB 491:128, written 63104 bytes

After months of extensive research of the codebase, fiddling
around the debugger with kgdb, and back-and-forth with
Microchip, we came to the conclusion that the issue is
probably that the peripheral is still busy receiving on AHB
when the LASTXFER bit is written to its Control Register
on APB, therefore this write gets lost, and the peripheral
still thinks there is more data to come in the MMIO transfer.
This was first formulated when we noticed that doubling the
write() of QSPI_CR_LASTXFER seemed to solve the problem.

Ultimately, the solution is to introduce memory barriers
after the AHB-mapped MMIO transfers, to ensure ordering.

Fixes: d5433def3153 ("mtd: spi-nor: atmel-quadspi: Add spi-mem support to atmel-quadspi")
Cc: Hari.PrasathGE at microchip.com
Cc: Mahesh.Abotula at microchip.com
Cc: Marco.Cardellini at microchip.com
Cc: <stable at vger.kernel.org> # c0a0203cf579: ("spi: atmel-quadspi: Create `atmel_qspi_ops`"...)
Cc: <stable at vger.kernel.org> # 6.x.y
Signed-off-by: Bence Cs?k?s <csokas.bence at prolan.hu>
---
 drivers/spi/atmel-quadspi.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index 73cf0c3f1477..96fc1c56a221 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -625,13 +625,20 @@ static int atmel_qspi_transfer(struct spi_mem *mem,
 	(void)atmel_qspi_read(aq, QSPI_IFR);
 
 	/* Send/Receive data */
-	if (op->data.dir == SPI_MEM_DATA_IN)
+	if (op->data.dir == SPI_MEM_DATA_IN) {
 		memcpy_fromio(op->data.buf.in, aq->mem + offset,
 			      op->data.nbytes);
-	else
+
+		/* Synchronize AHB and APB accesses again */
+		rmb();
+	} else {
 		memcpy_toio(aq->mem + offset, op->data.buf.out,
 			    op->data.nbytes);
 
+		/* Synchronize AHB and APB accesses again */
+		wmb();
+	}
+
 	/* Release the chip-select */
 	atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
 
-- 
2.34.1




From broonie at kernel.org  Wed Dec 18 09:01:06 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 18 Dec 2024 17:01:06 +0000
Subject: [PATCH] spi: atmel-qspi: Memory barriers after memory-mapped I/O
In-Reply-To: <20241218165850.378909-1-csokas.bence@prolan.hu>
References: <20241218165850.378909-1-csokas.bence@prolan.hu>
Message-ID: <b1661e3f-cc62-489b-a4f8-9964ccf65fae@sirena.org.uk>

On Wed, Dec 18, 2024 at 05:58:49PM +0100, Bence Cs?k?s wrote:

> However, the current documentation makes no mention to
> synchronization requirements in the other direction, i.e.
> after the last data written via AHB, and before the first
> register access on APB.
> 
> ---
> 
> Fixes: d5433def3153 ("mtd: spi-nor: atmel-quadspi: Add spi-mem support to atmel-quadspi")
> Cc: Hari.PrasathGE at microchip.com
> Cc: Mahesh.Abotula at microchip.com
> Cc: Marco.Cardellini at microchip.com
> Cc: <stable at vger.kernel.org> # c0a0203cf579: ("spi: atmel-quadspi: Create `atmel_qspi_ops`"...)
> Cc: <stable at vger.kernel.org> # 6.x.y
> Signed-off-by: Bence Cs?k?s <csokas.bence at prolan.hu>
> ---

Your signoffs and whatnot need to go before the --- so they don't get
cut off by tools, any any ancilliary stuff should go after.
-------------- 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/20241218/93452c6b/attachment.sig>

From conor at kernel.org  Wed Dec 18 09:05:29 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 17:05:29 +0000
Subject: [PATCH 1/9] dt-bindings: mfd: stm32-timers: add support for
 stm32mp25
In-Reply-To: <20241218090153.742869-2-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
 <20241218090153.742869-2-fabrice.gasnier@foss.st.com>
Message-ID: <20241218-debating-campus-1d92c4fb5730@spud>

On Wed, Dec 18, 2024 at 10:01:45AM +0100, Fabrice Gasnier wrote:
> Add a new stm32mp25 compatible to stm32-timer dt-bindings in order to
> support the STM32MP25 SoC. Some features has been added or updated in
> the stm32-timer timer such as:
> - hardware configuration and identification registers to read the timer
>   version and capabilities (counter width, number of channels...)
> - dithering mode (can be used to extend PWM resolution)
> - input triggers list
> - new counter modes
> - various bit-field updates
> - power-domains property
> Timer trigger identifier can be up to 19 (from timer 20)
> 
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>

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/20241218/a2d6756c/attachment.sig>

From Frank.li at nxp.com  Wed Dec 18 09:06:16 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 12:06:16 -0500
Subject: [PATCH v2 4/5] ASoC: SOF: imx: add driver for imx95
In-Reply-To: <CAEnQRZArKSOtka46A_SOiV2=8bs9B36ubAJM3GqYJZkKyBt_4A@mail.gmail.com>
References: <20241113195240.3699-1-laurentiumihalcea111@gmail.com>
 <20241113195240.3699-5-laurentiumihalcea111@gmail.com>
 <ZzUJQCeWclsrr/lr@lizhi-Precision-Tower-5810>
 <c47710a5-7e53-48b1-bd6b-c0123865aee5@gmail.com>
 <Z1r9hWH1ioR5vI5H@lizhi-Precision-Tower-5810>
 <c3c9389f-5116-4a5f-99f6-1b37c1e8c457@gmail.com>
 <CAEnQRZArKSOtka46A_SOiV2=8bs9B36ubAJM3GqYJZkKyBt_4A@mail.gmail.com>
Message-ID: <Z2MBCPP4G055Jbbs@lizhi-Precision-Tower-5810>

On Wed, Dec 18, 2024 at 03:01:11PM +0200, Daniel Baluta wrote:
> > >>> Frank
> > >> the SOF drivers do indeed have some similarities, but each of them has their own quirks which IMO makes it a bit harder to add the 95 support. We need to figure out the common parts and then move them to imx-common, but I believe this can be solved incrementally.
> > > You should create common part firstly, then implement equal function with
> > > existed part. Finially add imx95 part.
> > >
> > > Frank
> >
> > Yes, I'm aware of how this _should_ be done, but, like I mentioned, the change is not trivial and will
> > require tweaking the other drivers as well. As such, I'd like to get the 95 support in as-is firstly.
> >
> > Are there any other thoughts on this?
>
> Laurentiu, Frank please trim the emails and keep only the relevant
> part for discussion.
>
> As for this matter I think we should go with the current version Laurentiu sent.
>
> It is inline with the implementation for imx8qxp, imx8qm, imx8mp and
> imx8ulp which we already have upstream.
>
> There is always space for refactorization and improvements. The
> current version of the code
> is simple enough to go in as it is.

Need provide enough reason in commit message show why need create new one,
and but not reused existed one, which help maintainer and reviewer to judge
if it make sense.

Frank

>
> With this,
>
> Reviewed-by: Daniel Baluta <daniel.baluta at nxp.com>
>
> thanks,
> Daniel.


From florian.fainelli at broadcom.com  Wed Dec 18 09:15:08 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Wed, 18 Dec 2024 09:15:08 -0800
Subject: [PATCH 1/2] dt-bindings: memory-controller: Document rev c.1.5
 compatible
In-Reply-To: <2e33t7ft5ermsfr7c4ympxrn6l5sqdef3wml4hlbnhdupoouwj@gfjpbmowjadi>
References: <20241217194439.929040-1-florian.fainelli@broadcom.com>
 <20241217194439.929040-2-florian.fainelli@broadcom.com>
 <2e33t7ft5ermsfr7c4ympxrn6l5sqdef3wml4hlbnhdupoouwj@gfjpbmowjadi>
Message-ID: <93a1333d-442f-4cec-b823-9b1a5ff6dc6b@broadcom.com>

On 12/18/24 03:37, Krzysztof Kozlowski wrote:
> On Tue, Dec 17, 2024 at 11:44:38AM -0800, Florian Fainelli wrote:
>> Document the revision c.1.5 compatible string that is present on newer
>> Broadcom STB memory controllers (74165 and onwards).
>>
>> Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
>> ---
>>   .../bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml       | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
>> index 4b072c879b02..99d79ccd1036 100644
>> --- a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
>> +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
>> @@ -29,6 +29,7 @@ properties:
>>             - brcm,brcmstb-memc-ddr-rev-c.1.2
>>             - brcm,brcmstb-memc-ddr-rev-c.1.3
>>             - brcm,brcmstb-memc-ddr-rev-c.1.4
>> +          - brcm,brcmstb-memc-ddr-rev-c.1.5
> 
> You should use v2.1 fallback and drop driver patch. Or explain in
> commit briefly why different approach is suitable.

Are you suggesting that we should have fallback compatible strings, such 
that we have something like this:

compatible = "brcm,brcmstb-memc-ddr-rev-c.1.5", 
"brcm,brcmstb-memc-ddr-rev-c", "brcm,brcmstb-memc-ddr"

and the driver only needs to match on "brcm,brcmstb-memc-ddr-rev-c" and 
apply the adequate register offset table?

If so, that is not how the current binding, and therefore DTBs are being 
deployed, so that will introduce a breakage until we update all DTBs in 
the field...
-- 
Florian


From florian.fainelli at broadcom.com  Wed Dec 18 09:30:52 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Wed, 18 Dec 2024 09:30:52 -0800
Subject: [PATCH v4 3/3] dt-bindings: interrupt-controller:
 brcm,bcm2836-l1-intc: Drop interrupt-controller requirement
In-Reply-To: <20241218-dt-bcm2712-fixes-v4-3-54cc88b6c229@raspberrypi.com>
References: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
 <20241218-dt-bcm2712-fixes-v4-3-54cc88b6c229@raspberrypi.com>
Message-ID: <5d7fbb08-4f24-4c98-ba44-f3a457729dde@broadcom.com>

On 12/18/24 06:48, Dave Stevenson wrote:
> Since commit 88bbe85dcd37 ("irqchip: bcm2836: Move SMP startup code to
> arch/arm (v2)") the bcm2836-l1-intc block on bcm2711 is only used as a
> base address for the smp_boot_secondary hook on 32 bit kernels. It is
> not used as an interrupt controller.
> 
> Drop the binding requirement for interrupt-controller and interrupt-cells
> to satisfy validation on this platform.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian



From dianders at chromium.org  Wed Dec 18 09:38:15 2024
From: dianders at chromium.org (Doug Anderson)
Date: Wed, 18 Dec 2024 09:38:15 -0800
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <CAODwPW_UNVkyXKxyhZv830bhzsy5idu6GiuR9mut+-qGOtv1pw@mail.gmail.com>
References: <20241214005248.198803-1-dianders@chromium.org>
 <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
 <CAODwPW_c+Ycu_zhiDOKN-fH2FEWf2pxr+FcugpqEjLX-nVjQrg@mail.gmail.com>
 <CAD=FV=UHBA7zXZEw3K6TRpZEN-ApOkmymhRCOkz7h+yrAkR_Dw@mail.gmail.com>
 <CAODwPW8s4GhWGuZMUbWVNLYw_EVJe=EeMDacy1hxDLmnthwoFg@mail.gmail.com>
 <CAD=FV=X61y+RmbWCiZut_HHVS4jPdv_ZB8F+_Hs0R-1aKHdK4w@mail.gmail.com> <CAODwPW_UNVkyXKxyhZv830bhzsy5idu6GiuR9mut+-qGOtv1pw@mail.gmail.com>
Message-ID: <CAD=FV=VtTsUsOmW+SxiUXuUZoXSFYXY4ApzmMm_ZzxWKAvTMBA@mail.gmail.com>

Hi,

On Wed, Dec 18, 2024 at 8:36?AM Julius Werner <jwerner at chromium.org> wrote:
>
> > Given that I'm not going to change the way the existing predicates
> > work, if I move the "fallback" setting `max_bhb_k` to 32 to
> > spectre_bhb_enable_mitigation() then when we set `max_bhb_k` becomes
> > inconsistent between recognized and unrecognized CPUs.
>
> A clean way to fix that could be to change spectre_bhb_loop_affected()
> to just return the K-value (rather than change max_bhb_k directly),
> and then set max_bhb_k to the max() of that return value and the
> existing value when it is called from spectre_bhb_enable_mitigation().
> That way, max_bhb_k would only be updated from
> spectre_bhb_enable_mitigation().

Sure, you could do that. ...but in my patch series I need to add
_another_ static boolean that's updated in is_spectre_bhb_affected()
anyway. I need to add one to the new is_spectre_bhb_safe() function
that you requested. Specifically, the moment I detect any CPU ID
that's not in the "safe" list then I need to note that down. If I
don't do that then later calls to
is_spectre_bhb_affected(SCOPE_SYSTEM) will return the wrong value. So
while all the other "static" caches in is_spectre_bhb_affected() could
be removed because we changed the default return to "true", the one in
is_spectre_bhb_safe() (which causes the function to return "false")
can't be removed.

In any case, the predicates updating the static caches predates my
series and IMO my series doesn't make it worse. If you want to post a
followup series changing how the predicates work and can convince
others that it's worth doing then great, but I don't think it should
block forward progress here.


> > I would also say that having `max_bhb_k` get set in an inconsistent
> > place opens us up for bugs in the future. Even if it works today, I
> > imagine someone could change things in the future such that
> > spectre_bhb_enable_mitigation() reads `max_bhb_k` and essentially
> > caches it (maybe it constructs an instruction based on it). If that
> > happened things could be subtly broken for the "unrecognized CPU" case
> > because the first CPU would "cache" the value without it having been
> > called on all CPUs.
>
> This would likely already be a problem with the current code, since
> spectre_bhb_enable_mitigations() is called one at a time for each CPU
> and the max_bhb_k value is only valid once it has been called on all
> CPUs. If someone tried to just immediately use the value inside the
> function that would just be a bug either way. (Right now this should
> not be a problem because max_bhb_k is only used by
> spectre_bhb_patch_loop_iter() which ends up being called through
> apply_alternatives_all(), which should only run after all those CPU
> errata cpu_enable callbacks have been called.)

Actually, today is_spectre_bhb_affected() is called much earlier I
believe. It's installed (via cpu_errata.c) and called like this:

  is_spectre_bhb_affected+0x124/0x2d8
  update_cpu_capabilities+0xa0/0x158
  setup_boot_cpu_capabilities+0x20/0x40
  setup_boot_cpu_features+0x38/0x50
  smp_prepare_boot_cpu+0x38/0x60
  start_kernel+0x90/0x438

...but then spectre_bhb_enable_mitigations() is called later and by
that time is_spectre_bhb_affected() should have been called for each
of the CPUs:

  spectre_bhb_enable_mitigation+0xbc/0x340
  cpu_enable_non_boot_scope_capabilities+0x74/0xc8
  multi_cpu_stop+0xf0/0x1b8
  cpu_stopper_thread+0xac/0x148
  smpboot_thread_fn+0xb0/0x238

I agree that it doesn't seem to be a problem today, though.

-Doug


From conor at kernel.org  Wed Dec 18 09:44:15 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 17:44:15 +0000
Subject: [PATCH v2] dt-bindings: mfd: atmel,at91sam9260: Convert to json
 schema
In-Reply-To: <20241218-matrix-v2-1-f3a8809ee5cd@microchip.com>
References: <20241218-matrix-v2-1-f3a8809ee5cd@microchip.com>
Message-ID: <20241218-effects-apple-2ac14c51d21d@spud>

On Wed, Dec 18, 2024 at 09:24:54AM +0530, Charan Pedumuru wrote:
> Convert old text based binding to json schema.
> Changes during conversion:
> Add a missing fallback `atmel,at91sam9x5-matrix` for
> `microchip,sam9x60-matrix` which is not defined in the text binding.
> 
> Signed-off-by: Charan Pedumuru <charan.pedumuru at microchip.com>
> ---
> Changes in v2:
> - Modified the commit messsage.
> - Replaced `anyOf` with `oneOf` in compatible under properties.
> - Removed additional items group and added both `microchip,sam9x60-matrix` and 
>   `microchip,sam9x7-matrix` as an enum under one items group
> - Replaced `matrix@` with `syscon@` in examples.
> - Link to v1: https://lore.kernel.org/r/20241211-matrix-v1-1-5ef0104a3af4 at microchip.com
> ---
>  .../bindings/mfd/atmel,at91sam9260-matrix.yaml     | 52 ++++++++++++++++++++++
>  .../devicetree/bindings/mfd/atmel-matrix.txt       | 26 -----------
>  2 files changed, 52 insertions(+), 26 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml
> new file mode 100644
> index 000000000000..447b3a3edbfc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-matrix.yaml
> @@ -0,0 +1,52 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/atmel,at91sam9260-matrix.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Microchip AT91 Bus Matrix
> +
> +maintainers:
> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
> +
> +description:
> +  The Bus Matrix (MATRIX) implements a multi-layer AHB, based on the
> +  AHB-Lite protocol, that enables parallel access paths between multiple
> +  masters and slaves in a system, thus increasing the overall bandwidth.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - enum:
> +              - atmel,at91sam9260-matrix
> +              - atmel,at91sam9261-matrix
> +              - atmel,at91sam9263-matrix
> +              - atmel,at91sam9rl-matrix
> +              - atmel,at91sam9g45-matrix
> +              - atmel,at91sam9n12-matrix

FYI, the sort order is alphanumeric, which means your 9rl should be
after g45 and n12. Not worth resending 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/20241218/db9f48ff/attachment.sig>

From Frank.li at nxp.com  Wed Dec 18 09:44:40 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 12:44:40 -0500
Subject: [PATCH v12 2/9] PCI: endpoint: Add RC-to-EP doorbell support
 using platform MSI controller
In-Reply-To: <87o7197wbx.ffs@tglx>
References: <20241211-ep-msi-v12-0-33d4532fa520@nxp.com>
 <20241211-ep-msi-v12-2-33d4532fa520@nxp.com>
 <87o7197wbx.ffs@tglx>
Message-ID: <Z2MKCIImpnDjS1zd@lizhi-Precision-Tower-5810>

On Tue, Dec 17, 2024 at 11:56:18PM +0100, Thomas Gleixner wrote:
> On Wed, Dec 11 2024 at 15:57, Frank Li wrote:
> > +static int pci_epf_msi_prepare(struct irq_domain *domain, struct device *dev,
> > +			       int nvec, msi_alloc_info_t *arg)
> > +{
> > +	struct pci_epf *epf = to_pci_epf(dev);
> > +	struct msi_domain_info *msi_info;
> > +	struct pci_epc *epc = epf->epc;
> > +
> > +	memset(arg, 0, sizeof(*arg));
> > +	arg->scratchpad[0].ul = of_msi_map_id(epc->dev.parent, NULL,
> > +					      (epf->func_no << 8) | epf->vfunc_no);
> > +
> > +	/*
> > +	 * @domain->msi_domain_info->hwsize contains the size of the device
> > +	 * domain, but vector allocation happens one by one.
> > +	 */
> > +	msi_info = msi_get_domain_info(domain);
> > +	if (msi_info->hwsize > nvec)
> > +		nvec = msi_info->hwsize;
> > +
> > +	/* Allocate at least 32 MSIs, and always as a power of 2 */
> > +	nvec = max_t(int, 32, roundup_pow_of_two(nvec));
> > +
> > +	msi_info = msi_get_domain_info(domain->parent);
> > +	return msi_info->ops->msi_prepare(domain->parent, dev, nvec, arg);
>
> While I was trying to make sense of the change log of patch [1/9] I
> looked at this function to understand why this needs an override.
>
> This is a copy of its_msi_prepare() except for the scratchpad[0].ul
> part. But that's a GIC-V3 implementation specific detail, which has
> absolutely no business in code which claims to be a generic library for
> PCI endpoints.
>
> Worse you created a GIC-V3 only PCI endpoint library under the
> assumption that the underlying ITS/MSI implementation is immutable. Of
> course there is no safety net either to validate that the underlying
> parent domain is actually GIC-V3-ITS. That's wrong in every aspect.
>
> So let's take a step back and analyze what is actually required to make
> this a proper generic library.
>
> The endpoint function device needs its own device ID which is required
> to set up a device specific translation in the interrupt remapping unit.
>
> Now you decided that this is bound to a DT mapping, which is odd to
> begin with. What's DT specific about this? The cirumstance that your
> hardware is DT based and the endpoint controller ID map needs to be
> retrieved from there? How is this generic in any way? How is this
> supposed to work with ACPI enumerated hardware? Not to ask the question
> how this should work with non GIC-V3-ITS based hardware.
>
> That's all but generic, it's an ad hoc hack to support your particular
> setup implemented by layering violations.
>
> In fact the mapping ID is composed by the parent mapping ID and the
> function numbers, right?
>
> The general PCIe convention here is:
>
>     domain:bus:slot.func
>
> That's well defined and if you look at real devices then lspci shows:
>
> 0000:3d:00.1 Ethernet controller: Ethernet Connection for 10GBASE-T
> 0000:3d:06.0 Ethernet controller: Ethernet Virtual Function
> 0000:...
> 0000:3d:06.7 Ethernet controller: Ethernet Virtual Function
> 0000:3d:07.0 Ethernet controller: Ethernet Virtual Function
> 0000:...
> 0000:3d:07.7 Ethernet controller: Ethernet Virtual Function
>
> In PCI address representation:
>
>    domain:bus:slot:function
>
> which is usually condensed into a single word based on the range limits
> of function, device and bus:
>
>    function:    bit 0-2         (max. 8)
>    device:      bit 3-7         (max. 32)
>    bus:         bit 8-15        (max. 256)
>    domain:      bit 16-31       (mostly theoretical)
>
> Endpoint devices should follow exactly the same scheme, no?

Can't reuse BDF beasue Bus because device have not any means for EP side.
such as PCI EP controller have 8 physical functions. called EP.1 EP.2 ....

EP.n may connect PCI host 1, which bus number is 1. so BDF
	0000.01.00.1: sampe EP devices

but if it connect another PCI bus 3,  so BDF is
	0000.03.00.1 sampe EP devices.

At EP side, it don't care connect to RC bus1 or bus3.

	EP.1  use MSI irq 3
	EP.2  use MSI ire 4

regardless EP connect bus 1 or bus 3, door bell always trigger EP side
irq 3 for EP.1,  irq 4 for EP.2

So only function and vfunction should be used for as request id.

I worry about some hardware (I have not met yet) direct use BDF from RC
side because it is simple hardware implementation for dual role pci
controller.

>
> Now looking at your ID retrieval:
>
> > +	arg->scratchpad[0].ul = of_msi_map_id(epc->dev.parent, NULL,
> > +					      (epf->func_no << 8) | epf->vfunc_no);
>
> I really have to ask why this is making up its own representation
> instead of simply using the standard PCI B/D/F conventions?

See above!

Addtional difference vfunc need difference doorbell msi domain.
I have not sure how virtual function to map to BDF. If it map D, we just
simple mask B. I want reserve it to avoid ABI change in future if vfunc
support since my hardware don't support EP's side vfunc yet.

Anyway, let me implement what your below suggestion then fine tune this.

>
> Whatever the reason is, fact is that the actual interrupt domain support
> needs to be done differently. There is no way that the endpoint library
> makes assumption about the underlying interrupt domain and copies a
> function just because. This has to be completely agnostic, no if, no
> but.
>
> So the consequence is that the underlying MSI parent domains needs to
> know about the endpoint requirements, which is how all MSI variants are
> modeled, i.e. with a MSI domain bus.
>
> That also solves the problem of immutable MSI messages without any
> further magic. Interrupt domains, which do not provide them, won't
> provide the endpoint MSI domain bus and therefore the lookup of the
> parent MSI domain for the endpoint fails.
>
> The uncompilable mockup below should give you a hint.

Thank for your example, let me try to implement it.

Frank

>
> Thanks,
>
>         tglx
> ---
>  drivers/irqchip/irq-gic-v3-its-msi-parent.c |   50 ++++++++++++++++++++--------
>  drivers/irqchip/irq-msi-lib.c               |    5 ++
>  drivers/irqchip/irq-msi-lib.h               |   12 +++++-
>  include/linux/irqdomain_defs.h              |    2 +
>  4 files changed, 51 insertions(+), 18 deletions(-)
>
> --- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
> +++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
> @@ -126,20 +126,9 @@ int __weak iort_pmsi_get_dev_id(struct d
>  	return -1;
>  }
>
> -static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
> -			    int nvec, msi_alloc_info_t *info)
> +static int __its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
> +			      int nvec, msi_alloc_info_t *info, u32 dev_id)
>  {
> -	struct msi_domain_info *msi_info;
> -	u32 dev_id;
> -	int ret;
> -
> -	if (dev->of_node)
> -		ret = of_pmsi_get_dev_id(domain->parent, dev, &dev_id);
> -	else
> -		ret = iort_pmsi_get_dev_id(dev, &dev_id);
> -	if (ret)
> -		return ret;
> -
>  	/* ITS specific DeviceID, as the core ITS ignores dev. */
>  	info->scratchpad[0].ul = dev_id;
>
> @@ -159,6 +148,36 @@ static int its_pmsi_prepare(struct irq_d
>  					  dev, nvec, info);
>  }
>
> +static int its_pci_ep_msi_prepare(struct irq_domain *domain, struct device *dev,
> +				  int nvec, msi_alloc_info_t *info)
> +{
> +	u32 dev_id = dev_get_pci_ep_id(dev);
> +	struct msi_domain_info *msi_info;
> +	int ret = -ENOTSUPP;
> +
> +	if (dev->of_node)
> +		ret = do_magic_ep_id_map();
> +	if (ret)
> +		return ret;
> +	return __its_pmsi_prepare(domain, dev, nvec, info, dev_id);
> +}
> +
> +static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
> +			    int nvec, msi_alloc_info_t *info)
> +{
> +	struct msi_domain_info *msi_info;
> +	u32 dev_id;
> +	int ret;
> +
> +	if (dev->of_node)
> +		ret = of_pmsi_get_dev_id(domain->parent, dev, &dev_id);
> +	else
> +		ret = iort_pmsi_get_dev_id(dev, &dev_id);
> +	if (ret)
> +		return ret;
> +	return __its_pmsi_prepare(domain, dev, nvec, info, dev_id);
> +}
> +
>  static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
>  				  struct irq_domain *real_parent, struct msi_domain_info *info)
>  {
> @@ -183,6 +202,9 @@ static bool its_init_dev_msi_info(struct
>  		 */
>  		info->ops->msi_prepare = its_pci_msi_prepare;
>  		break;
> +	case DOMAIN_BUS_PCI_DEVICE_EP_MSI:
> +		info->ops->msi_prepare = its_pci_ep_msi_prepare;
> +		break;
>  	case DOMAIN_BUS_DEVICE_MSI:
>  	case DOMAIN_BUS_WIRED_TO_MSI:
>  		/*
> @@ -204,7 +226,7 @@ const struct msi_parent_ops gic_v3_its_m
>  	.supported_flags	= ITS_MSI_FLAGS_SUPPORTED,
>  	.required_flags		= ITS_MSI_FLAGS_REQUIRED,
>  	.bus_select_token	= DOMAIN_BUS_NEXUS,
> -	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
> +	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_PCI_EP_MSI | MATCH_PLATFORM_MSI,
>  	.prefix			= "ITS-",
>  	.init_dev_msi_info	= its_init_dev_msi_info,
>  };
> --- a/drivers/irqchip/irq-msi-lib.c
> +++ b/drivers/irqchip/irq-msi-lib.c
> @@ -55,8 +55,11 @@ bool msi_lib_init_dev_msi_info(struct de
>  	case DOMAIN_BUS_PCI_DEVICE_MSIX:
>  		if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_PCI_MSI)))
>  			return false;
> -
>  		break;
> +	case DOMAIN_BUS_DEVICE_PCI_EP_MSI:
> +		if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_PCI_ENDPOINT)))
> +			return false;
> +		fallthrough;
>  	case DOMAIN_BUS_DEVICE_MSI:
>  		/*
>  		 * Per device MSI should never have any MSI feature bits
> --- a/drivers/irqchip/irq-msi-lib.h
> +++ b/drivers/irqchip/irq-msi-lib.h
> @@ -10,12 +10,18 @@
>  #include <linux/msi.h>
>
>  #ifdef CONFIG_PCI_MSI
> -#define MATCH_PCI_MSI		BIT(DOMAIN_BUS_PCI_MSI)
> +#define MATCH_PCI_MSI			BIT(DOMAIN_BUS_PCI_MSI)
>  #else
> -#define MATCH_PCI_MSI		(0)
> +#define MATCH_PCI_MSI			(0)
>  #endif
>
> -#define MATCH_PLATFORM_MSI	BIT(DOMAIN_BUS_PLATFORM_MSI)
> +#ifdef CONFIG_PCI_ENDPOINT
> +#define MATCH_PLATFORM_PCI_EP_MSI	BIT(DOMAIN_BUS_PLATFORM_PCI_EP_MSI)
> +#else
> +#define MATCH_PLATFORM_PCI_EP_MSI	(0)
> +#endif
> +
> +#define MATCH_PLATFORM_MSI		BIT(DOMAIN_BUS_PLATFORM_MSI)
>
>  int msi_lib_irq_domain_select(struct irq_domain *d, struct irq_fwspec *fwspec,
>  			      enum irq_domain_bus_token bus_token);
> --- a/include/linux/irqdomain_defs.h
> +++ b/include/linux/irqdomain_defs.h
> @@ -15,6 +15,7 @@ enum irq_domain_bus_token {
>  	DOMAIN_BUS_GENERIC_MSI,
>  	DOMAIN_BUS_PCI_MSI,
>  	DOMAIN_BUS_PLATFORM_MSI,
> +	DOMAIN_BUS_PLATFORM_PCI_EP_MSI,
>  	DOMAIN_BUS_NEXUS,
>  	DOMAIN_BUS_IPI,
>  	DOMAIN_BUS_FSL_MC_MSI,
> @@ -27,6 +28,7 @@ enum irq_domain_bus_token {
>  	DOMAIN_BUS_AMDVI,
>  	DOMAIN_BUS_DEVICE_MSI,
>  	DOMAIN_BUS_WIRED_TO_MSI,
> +	DOMAIN_BUS_DEVICE_PCI_EP_MSI,
>  };
>
>  #endif /* _LINUX_IRQDOMAIN_DEFS_H */


From andi.shyti at kernel.org  Wed Dec 18 10:00:47 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Wed, 18 Dec 2024 19:00:47 +0100
Subject: [PATCH v1] i2c: imx: fix missing stop condition in single-master
 mode
In-Reply-To: <Z2BWtjPT1sTUCZ82@lizhi-Precision-Tower-5810>
References: <20241216151829.74056-1-eichest@gmail.com>
 <Z2BWtjPT1sTUCZ82@lizhi-Precision-Tower-5810>
Message-ID: <i5b2b622jmp2daco62wljolnjz5p35e67ldpkiqd3jv2z4ruqo@go2b4znun6z7>

Hi,

...

> > diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> > index f751d231ded8..cbf66a69e20b 100644
> > --- a/drivers/i2c/busses/i2c-imx.c
> > +++ b/drivers/i2c/busses/i2c-imx.c
> > @@ -534,20 +534,18 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a
> >  {
> >  	unsigned long orig_jiffies = jiffies;
> >  	unsigned int temp;
> > -
> > -	if (!i2c_imx->multi_master)
> > -		return 0;
> > +	bool multi_master = i2c_imx->multi_master;
> 
> Move "bool multi_master = i2c_imx->multi_master;" before
> "unsigned long orig_jiffies = jiffies;" to keep reverse christmas tree
> order.

I will take care of it.

Thanks, Stefan.

Andi


From Frank.li at nxp.com  Wed Dec 18 10:01:42 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 13:01:42 -0500
Subject: [PATCH 1/2] arm64: dts: imx95: add NETC related nodes
In-Reply-To: <20241218061725.1608466-2-wei.fang@nxp.com>
References: <20241218061725.1608466-1-wei.fang@nxp.com>
 <20241218061725.1608466-2-wei.fang@nxp.com>
Message-ID: <Z2MOBmqM0iXQnRrc@lizhi-Precision-Tower-5810>

On Wed, Dec 18, 2024 at 02:17:24PM +0800, Wei Fang wrote:
> Add NETC related nodes for i.MX95.
>
> Signed-off-by: Wei Fang <wei.fang at nxp.com>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>  arch/arm64/boot/dts/freescale/imx95.dtsi | 93 ++++++++++++++++++++++++
>  1 file changed, 93 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
> index e9c7a8265d71..86f9fed9998c 100644
> --- a/arch/arm64/boot/dts/freescale/imx95.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
> @@ -1702,5 +1702,98 @@ ddr-pmu at 4e090dc0 {
>  			reg = <0x0 0x4e090dc0 0x0 0x200>;
>  			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
>  		};
> +
> +		netc_blk_ctrl: system-controller at 4cde0000 {
> +			compatible = "nxp,imx95-netc-blk-ctrl";
> +			reg = <0x0 0x4cde0000 0x0 0x10000>,
> +			      <0x0 0x4cdf0000 0x0 0x10000>,
> +			      <0x0 0x4c81000c 0x0 0x18>;
> +			reg-names = "ierb", "prb", "netcmix";
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			ranges;
> +			power-domains = <&scmi_devpd IMX95_PD_NETC>;
> +			assigned-clocks = <&scmi_clk IMX95_CLK_ENET>,
> +					  <&scmi_clk IMX95_CLK_ENETREF>;
> +			assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD2>,
> +						 <&scmi_clk IMX95_CLK_SYSPLL1_PFD0>;
> +			assigned-clock-rates = <666666666>, <250000000>;
> +			clocks = <&scmi_clk IMX95_CLK_ENET>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +
> +			netc_bus0: pcie at 4ca00000 {
> +				compatible = "pci-host-ecam-generic";
> +				reg = <0x0 0x4ca00000 0x0 0x100000>;
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				device_type = "pci";
> +				bus-range = <0x0 0x0>;
> +				msi-map = <0x0 &its 0x60 0x1>,	//ENETC0 PF
> +					  <0x10 &its 0x61 0x1>, //ENETC0 VF0
> +					  <0x20 &its 0x62 0x1>, //ENETC0 VF1
> +					  <0x40 &its 0x63 0x1>, //ENETC1 PF
> +					  <0x80 &its 0x64 0x1>, //ENETC2 PF
> +					  <0x90 &its 0x65 0x1>, //ENETC2 VF0
> +					  <0xa0 &its 0x66 0x1>, //ENETC2 VF1
> +					  <0xc0 &its 0x67 0x1>; //NETC Timer
> +					 /* ENETC0~2 and Timer BAR0 - non-prefetchable memory */
> +				ranges = <0x82000000 0x0 0x4cc00000  0x0 0x4cc00000  0x0 0xe0000
> +					 /* Timer BAR2 - prefetchable memory */
> +					 0xc2000000 0x0 0x4cd00000  0x0 0x4cd00000  0x0 0x10000
> +					 /* ENETC0~2: VF0-1 BAR0 - non-prefetchable memory */
> +					 0x82000000 0x0 0x4cd20000  0x0 0x4cd20000  0x0 0x60000
> +					 /* ENETC0~2: VF0-1 BAR2 - prefetchable memory */
> +					 0xc2000000 0x0 0x4cd80000  0x0 0x4cd80000  0x0 0x60000>;
> +
> +				enetc_port0: ethernet at 0,0 {
> +					compatible = "pci1131,e101";
> +					reg = <0x000000 0 0 0 0>;
> +					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
> +					clock-names = "ref";
> +					status = "disabled";
> +				};
> +
> +				enetc_port1: ethernet at 8,0 {
> +					compatible = "pci1131,e101";
> +					reg = <0x004000 0 0 0 0>;
> +					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
> +					clock-names = "ref";
> +					status = "disabled";
> +				};
> +
> +				enetc_port2: ethernet at 10,0 {
> +					compatible = "pci1131,e101";
> +					reg = <0x008000 0 0 0 0>;
> +					status = "disabled";
> +				};
> +
> +				netc_timer: ethernet at 18,0 {
> +					reg = <0x00c000 0 0 0 0>;
> +					status = "disabled";
> +				};
> +			};
> +
> +			netc_bus1: pcie at 4cb00000 {
> +				compatible = "pci-host-ecam-generic";
> +				reg = <0x0 0x4cb00000 0x0 0x100000>;
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				device_type = "pci";
> +				bus-range = <0x1 0x1>;
> +					 /* EMDIO BAR0 - non-prefetchable memory */
> +				ranges = <0x82000000 0x0 0x4cce0000  0x0 0x4cce0000  0x0 0x20000
> +					 /* EMDIO BAR2 - prefetchable memory */
> +					 0xc2000000 0x0 0x4cd10000  0x0 0x4cd10000  0x0 0x10000>;
> +
> +				netc_emdio: mdio at 0,0 {
> +					compatible = "pci1131,ee00";
> +					reg = <0x010000 0 0 0 0>;
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +					status = "disabled";
> +				};
> +			};
> +		};
>  	};
>  };
> --
> 2.34.1
>


From Frank.li at nxp.com  Wed Dec 18 10:04:58 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 13:04:58 -0500
Subject: [PATCH 2/2] arm64: dts: imx95: add ENETC 0 support
In-Reply-To: <20241218061725.1608466-3-wei.fang@nxp.com>
References: <20241218061725.1608466-1-wei.fang@nxp.com>
 <20241218061725.1608466-3-wei.fang@nxp.com>
Message-ID: <Z2MOysEbkh1j5eds@lizhi-Precision-Tower-5810>

On Wed, Dec 18, 2024 at 02:17:25PM +0800, Wei Fang wrote:

nit: arm64: dts: imx95-19x19-evk: add ENETC 0 support

> Add ENETC 0 (1G ethernet port) support for i.MX95-19x19-EVK board. In
> addition, because all ENETC instances share MDIO bus, so enable EMDIO
> at the same time.
>
> Signed-off-by: Wei Fang <wei.fang at nxp.com>
> ---
>  .../boot/dts/freescale/imx95-19x19-evk.dts    | 52 +++++++++++++++++++
>  1 file changed, 52 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> index 6086cb7fa5a0..e838234c8317 100644
> --- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> @@ -38,6 +38,7 @@ aliases {
>  		mmc0 = &usdhc1;
>  		mmc1 = &usdhc2;
>  		serial0 = &lpuart1;
> +		ethernet0 = &enetc_port0;
>  	};
>
>  	bt_sco_codec: audio-codec-bt-sco {
> @@ -428,6 +429,33 @@ &wdog3 {
>  	status = "okay";
>  };
>
> +&netcmix_blk_ctrl {
> +	status = "okay";
> +};
> +
> +&netc_blk_ctrl {
> +	status = "okay";
> +};
> +
> +&enetc_port0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_enetc0>;
> +	phy-handle = <&ethphy0>;
> +	phy-mode = "rgmii-id";
> +	status = "okay";
> +};
> +
> +&netc_emdio {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_emdio>;
> +	status = "okay";
> +
> +	ethphy0: ethernet-phy at 1 {
> +		reg = <1>;
> +		realtek,clkout-disable;
> +	};
> +};

Please keep order by these node. netc should after enetc

> +
>  &scmi_iomuxc {
>  	pinctrl_flexspi1: flexspi1grp {
>  		fsl,pins = <
> @@ -665,6 +693,30 @@ IMX95_PAD_SD2_DATA3__USDHC2_DATA3		0x13fe
>  			IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT		0x51e
>  		>;
>  	};
> +
> +	pinctrl_enetc0: enetc0grp {
> +		fsl,pins = <
> +			IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3		0x57e
> +			IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2		0x57e
> +			IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1		0x57e
> +			IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0		0x57e
> +			IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL	0x57e
> +			IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK	0x58e
> +			IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL	0x57e
> +			IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK	0x58e
> +			IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0		0x57e
> +			IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1		0x57e
> +			IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2		0x57e
> +			IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3		0x57e
> +		>;
> +	};
> +
> +	pinctrl_emdio: emdiogrp{
> +		fsl,pins = <
> +			IMX95_PAD_ENET1_MDC__NETCMIX_TOP_NETC_MDC		0x57e
> +			IMX95_PAD_ENET1_MDIO__NETCMIX_TOP_NETC_MDIO		0x97e
> +		>;
> +	};

some here, keep order,
enetc0grp should before flexspi1grp

Frank

>  };
>
>  &thermal_zones {
> --
> 2.34.1
>


From Frank.li at nxp.com  Wed Dec 18 10:06:52 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 13:06:52 -0500
Subject: [PATCH 1/2] arm64: dts: imx95: add NETC related nodes
In-Reply-To: <20241218061725.1608466-2-wei.fang@nxp.com>
References: <20241218061725.1608466-1-wei.fang@nxp.com>
 <20241218061725.1608466-2-wei.fang@nxp.com>
Message-ID: <Z2MPPFZ9hETCXfVl@lizhi-Precision-Tower-5810>

On Wed, Dec 18, 2024 at 02:17:24PM +0800, Wei Fang wrote:
> Add NETC related nodes for i.MX95.
>
> Signed-off-by: Wei Fang <wei.fang at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx95.dtsi | 93 ++++++++++++++++++++++++
>  1 file changed, 93 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
> index e9c7a8265d71..86f9fed9998c 100644
> --- a/arch/arm64/boot/dts/freescale/imx95.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
> @@ -1702,5 +1702,98 @@ ddr-pmu at 4e090dc0 {
>  			reg = <0x0 0x4e090dc0 0x0 0x200>;
>  			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
>  		};
> +
> +		netc_blk_ctrl: system-controller at 4cde0000 {

keep order by hex address value.

4cde0000 should ahead ddr-pmu at 4e090dc0.

Frank

> +			compatible = "nxp,imx95-netc-blk-ctrl";
> +			reg = <0x0 0x4cde0000 0x0 0x10000>,
> +			      <0x0 0x4cdf0000 0x0 0x10000>,
> +			      <0x0 0x4c81000c 0x0 0x18>;
> +			reg-names = "ierb", "prb", "netcmix";
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			ranges;
> +			power-domains = <&scmi_devpd IMX95_PD_NETC>;
> +			assigned-clocks = <&scmi_clk IMX95_CLK_ENET>,
> +					  <&scmi_clk IMX95_CLK_ENETREF>;
> +			assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD2>,
> +						 <&scmi_clk IMX95_CLK_SYSPLL1_PFD0>;
> +			assigned-clock-rates = <666666666>, <250000000>;
> +			clocks = <&scmi_clk IMX95_CLK_ENET>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +
> +			netc_bus0: pcie at 4ca00000 {
> +				compatible = "pci-host-ecam-generic";
> +				reg = <0x0 0x4ca00000 0x0 0x100000>;
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				device_type = "pci";
> +				bus-range = <0x0 0x0>;
> +				msi-map = <0x0 &its 0x60 0x1>,	//ENETC0 PF
> +					  <0x10 &its 0x61 0x1>, //ENETC0 VF0
> +					  <0x20 &its 0x62 0x1>, //ENETC0 VF1
> +					  <0x40 &its 0x63 0x1>, //ENETC1 PF
> +					  <0x80 &its 0x64 0x1>, //ENETC2 PF
> +					  <0x90 &its 0x65 0x1>, //ENETC2 VF0
> +					  <0xa0 &its 0x66 0x1>, //ENETC2 VF1
> +					  <0xc0 &its 0x67 0x1>; //NETC Timer
> +					 /* ENETC0~2 and Timer BAR0 - non-prefetchable memory */
> +				ranges = <0x82000000 0x0 0x4cc00000  0x0 0x4cc00000  0x0 0xe0000
> +					 /* Timer BAR2 - prefetchable memory */
> +					 0xc2000000 0x0 0x4cd00000  0x0 0x4cd00000  0x0 0x10000
> +					 /* ENETC0~2: VF0-1 BAR0 - non-prefetchable memory */
> +					 0x82000000 0x0 0x4cd20000  0x0 0x4cd20000  0x0 0x60000
> +					 /* ENETC0~2: VF0-1 BAR2 - prefetchable memory */
> +					 0xc2000000 0x0 0x4cd80000  0x0 0x4cd80000  0x0 0x60000>;
> +
> +				enetc_port0: ethernet at 0,0 {
> +					compatible = "pci1131,e101";
> +					reg = <0x000000 0 0 0 0>;
> +					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
> +					clock-names = "ref";
> +					status = "disabled";
> +				};
> +
> +				enetc_port1: ethernet at 8,0 {
> +					compatible = "pci1131,e101";
> +					reg = <0x004000 0 0 0 0>;
> +					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
> +					clock-names = "ref";
> +					status = "disabled";
> +				};
> +
> +				enetc_port2: ethernet at 10,0 {
> +					compatible = "pci1131,e101";
> +					reg = <0x008000 0 0 0 0>;
> +					status = "disabled";
> +				};
> +
> +				netc_timer: ethernet at 18,0 {
> +					reg = <0x00c000 0 0 0 0>;
> +					status = "disabled";
> +				};
> +			};
> +
> +			netc_bus1: pcie at 4cb00000 {
> +				compatible = "pci-host-ecam-generic";
> +				reg = <0x0 0x4cb00000 0x0 0x100000>;
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				device_type = "pci";
> +				bus-range = <0x1 0x1>;
> +					 /* EMDIO BAR0 - non-prefetchable memory */
> +				ranges = <0x82000000 0x0 0x4cce0000  0x0 0x4cce0000  0x0 0x20000
> +					 /* EMDIO BAR2 - prefetchable memory */
> +					 0xc2000000 0x0 0x4cd10000  0x0 0x4cd10000  0x0 0x10000>;
> +
> +				netc_emdio: mdio at 0,0 {
> +					compatible = "pci1131,ee00";
> +					reg = <0x010000 0 0 0 0>;
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +					status = "disabled";
> +				};
> +			};
> +		};
>  	};
>  };
> --
> 2.34.1
>


From nathan at kernel.org  Wed Dec 18 10:11:48 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Wed, 18 Dec 2024 11:11:48 -0700
Subject: [PATCH] media: mediatek: vcodec: mark
 vdec_vp9_slice_map_counts_eob_coef noinline
In-Reply-To: <20241218124505.xwgsnpi2rvbngqvs@basti-XPS-13-9310>
References: <20241018151448.3694052-1-arnd@kernel.org>
 <20241118200641.GA768549@thelio-3990X>
 <20241119110226.dbd54clp46klvjl5@basti-XPS-13-9310>
 <20241217174628.GA2654633@ax162>
 <20241218124505.xwgsnpi2rvbngqvs@basti-XPS-13-9310>
Message-ID: <20241218181148.GA2948182@ax162>

On Wed, Dec 18, 2024 at 01:45:05PM +0100, Sebastian Fricke wrote:
> I have sent out the PR and it has been applied to the -fixes branch in
> the media tree, due to the holiday period there might be some delays but
> I expect the change to soon land in Linux-next.

Ah, thanks a lot! I was looking at the main media tree's fixes branch
but I see it is only in the media-pending tree right now:

https://git.linuxtv.org/media-ci/media-pending.git/commit/?id=8b55f8818900c99dd4f55a59a103f5b29e41eb2c

As long as it is on its way, that's all that matters to me. Appreciate
you getting that process moving!

Cheers,
Nathan


From broonie at kernel.org  Wed Dec 18 10:14:14 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 18 Dec 2024 18:14:14 +0000
Subject: [PATCH] spi: rockchip-sfc: Fix error in remove progress
In-Reply-To: <20241218154741.901591-1-jon.lin@rock-chips.com>
References: <20241218154741.901591-1-jon.lin@rock-chips.com>
Message-ID: <173454565468.177553.7095093662126161024.b4-ty@kernel.org>

On Wed, 18 Dec 2024 23:47:41 +0800, Jon Lin wrote:
> Fix error in remove progress:
> 	[   43.026148] Call trace:
> 	[   43.026370]  klist_next+0x1c/0x1d4
> 	[   43.026671]  device_for_each_child+0x48/0xac
> 	[   43.027049]  spi_unregister_controller+0x30/0x130
> 	[   43.027469]  rockchip_sfc_remove+0x48/0x80 [spi_rockchip_sfc]
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: rockchip-sfc: Fix error in remove progress
      commit: 7f9a1eed1ad8b274ed9163a02cef891a90427237

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 andi.shyti at kernel.org  Wed Dec 18 10:16:23 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Wed, 18 Dec 2024 19:16:23 +0100
Subject: [PATCH v1] i2c: imx: fix missing stop condition in single-master
 mode
In-Reply-To: <20241216151829.74056-1-eichest@gmail.com>
References: <20241216151829.74056-1-eichest@gmail.com>
Message-ID: <w3x46is2s463ektusvnyu5tt2rinz7eae2ekzyqw2urw5yh5ga@pfzrgzpxjc4y>

Hi Stefan,

On Mon, Dec 16, 2024 at 04:16:40PM +0100, Stefan Eichenberger wrote:
> From: Stefan Eichenberger <stefan.eichenberger at toradex.com>
> 
> A regression was introduced with the implementation of single-master
> mode, preventing proper stop conditions from being generated. Devices
> that require a valid stop condition, such as EEPROMs, fail to function
> correctly as a result.
> 
> The issue only affects devices with the single-master property enabled.
> 
> This commit resolves the issue by re-enabling I2C bus busy bit (IBB)
> polling for single-master mode when generating a stop condition. The fix
> further ensures that the i2c_imx->stopped flag is cleared at the start
> of each transfer, allowing the stop condition to be correctly generated
> in i2c_imx_stop().
> 
> According to the reference manual (IMX8MMRM, Rev. 2, 09/2019, page
> 5270), polling the IBB bit to determine if the bus is free is only
> necessary in multi-master mode. Consequently, the IBB bit is not polled
> for the start condition in single-master mode.
> 
> Fixes: 6692694aca86 ("i2c: imx: do not poll for bus busy in single master mode")
> Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>
> ---
>  drivers/i2c/busses/i2c-imx.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index f751d231ded8..cbf66a69e20b 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -534,20 +534,18 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a
>  {
>  	unsigned long orig_jiffies = jiffies;
>  	unsigned int temp;
> -
> -	if (!i2c_imx->multi_master)
> -		return 0;
> +	bool multi_master = i2c_imx->multi_master;

with this small adjustment, I have applied your patch to 
i2c/i2c-host-fixes.

The idea behind the change is that variables are sorted by 
length, forming a kind of reversed Christmas tree shape. It's 
not a strict rule?some communities enforce it, others don't, and 
some follow entirely different conventions.

Since it feels somewhat arbitrary to me, I don't enforce it 
strictly. However, I personally try to adhere to the reversed 
Christmas tree rule whenever possible.

Andi

>  
>  	while (1) {
>  		temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
>  
>  		/* check for arbitration lost */
> -		if (temp & I2SR_IAL) {
> +		if (multi_master && (temp & I2SR_IAL)) {
>  			i2c_imx_clear_irq(i2c_imx, I2SR_IAL);
>  			return -EAGAIN;
>  		}
>  
> -		if (for_busy && (temp & I2SR_IBB)) {
> +		if (for_busy && (!multi_master || (temp & I2SR_IBB))) {
>  			i2c_imx->stopped = 0;
>  			break;
>  		}
> -- 
> 2.45.2
> 


From suzuki.poulose at arm.com  Wed Dec 18 10:16:45 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 18 Dec 2024 18:16:45 +0000
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <PAVPR08MB967401DC65384CBA26B6829C8C052@PAVPR08MB9674.eurprd08.prod.outlook.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-3-quic_jinlmao@quicinc.com>
 <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>
 <PAVPR08MB967401DC65384CBA26B6829C8C052@PAVPR08MB9674.eurprd08.prod.outlook.com>
Message-ID: <53354e84-73c0-403b-bbc0-af619196596d@arm.com>

Hi Mike

On 18/12/2024 09:56, Mike Leach wrote:
> Hi
> 
>> -----Original Message-----
>> From: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Sent: Wednesday, December 18, 2024 9:38 AM
>> To: Mao Jinlong <quic_jinlmao at quicinc.com>; Mike Leach
>> <mike.leach at linaro.org>; James Clark <James.Clark at arm.com>; Rob Herring
>> <robh at kernel.org>; Krzysztof Kozlowski <krzk+dt at kernel.org>; Conor Dooley
>> <conor+dt at kernel.org>; Mathieu Poirier <mathieu.poirier at linaro.org>; Bjorn
>> Andersson <andersson at kernel.org>; Konrad Dybcio
>> <konradybcio at kernel.org>
>> Cc: coresight at lists.linaro.org; linux-arm-kernel at lists.infradead.org;
>> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
>> msm at vger.kernel.org
>> Subject: Re: [PATCH v6 2/2] coresight: Add label sysfs node support
>>
>> On 17/12/2024 06:33, Mao Jinlong wrote:
>>> For some coresight components like CTI and TPDM, there could be
>>> numerous of them. From the node name, we can only get the type and
>>> register address of the component. We can't identify the HW or the
>>> system the component belongs to. Add label sysfs node support for
>>> showing the intuitive name of the device.
>>>
>>> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
>>> ---
>>>    .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
>>>    .../sysfs-bus-coresight-devices-funnel        |  6 ++++
>>>    .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
>>>    drivers/hwtracing/coresight/coresight-sysfs.c | 32
>> +++++++++++++++++++
>>>    4 files changed, 50 insertions(+)
>>
>> Do you think we need to name the devices using the label ?
>>
> 
> No - absolutely not. If we use label to name devices then we have to validate that the string is a correctly formed device name and that it has not been previously used.

Anything that doesn't contain '/' can be a device name ? And it is very 
easy to find if the device name has been used in the coresight bus, 
after all these devices only appear there.

It is as good as :

bus_find_device_by_name(coresight_bus_type, NULL, name) == NULL

Of course with coresight_mutex() held.

Suzuki


> 
> Using the canonical driver selected names works best as we are guaranteed a unique name and the information label can be used to provide flexible context information that best matches the users requirements.
> 
> Mike
> 
>> Or is this enough ?
> 
>> Suzuki
>>
>>
>>>
>>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>>> index bf2869c413e7..909670e0451a 100644
>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>>> @@ -239,3 +239,9 @@ Date:		March 2020
>>>    KernelVersion	5.7
>>>    Contact:	Mike Leach or Mathieu Poirier
>>>    Description:	(Write) Clear all channel / trigger programming.
>>> +
>>> +What:           /sys/bus/coresight/devices/<cti-name>/label
>>> +Date:           Dec 2024
>>> +KernelVersion   6.14
>>> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
>>> +Description:    (Read) Show hardware context information of device.
>>> diff --git
>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>>> index d75acda5e1b3..944aad879aeb 100644
>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>>> @@ -10,3 +10,9 @@ Date:		November 2014
>>>    KernelVersion:	3.19
>>>    Contact:	Mathieu Poirier <mathieu.poirier at linaro.org>
>>>    Description:	(RW) Defines input port priority order.
>>> +
>>> +What:           /sys/bus/coresight/devices/<memory_map>.funnel/label
>>> +Date:           Dec 2024
>>> +KernelVersion   6.14
>>> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
>>> +Description:    (Read) Show hardware context information of device.
>>> diff --git
>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> index bf710ea6e0ef..309802246398 100644
>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> @@ -257,3 +257,9 @@ 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 CMB
>> subunit
>>>    		TPDM.
>>> +
>>> +What:           /sys/bus/coresight/devices/<tpdm-name>/label
>>> +Date:           Dec 2024
>>> +KernelVersion   6.14
>>> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
>>> +Description:    (Read) Show hardware context information of device.
>>> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c
>>> b/drivers/hwtracing/coresight/coresight-sysfs.c
>>> index a01c9e54e2ed..4af40cd7d75a 100644
>>> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
>>> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
>>> @@ -7,6 +7,7 @@
>>>    #include <linux/device.h>
>>>    #include <linux/idr.h>
>>>    #include <linux/kernel.h>
>>> +#include <linux/property.h>
>>>
>>>    #include "coresight-priv.h"
>>>    #include "coresight-trace-id.h"
>>> @@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device
>> *dev,
>>>    }
>>>    static DEVICE_ATTR_RW(enable_source);
>>>
>>> +static ssize_t label_show(struct device *dev,
>>> +		struct device_attribute *attr, char *buf) {
>>> +
>>> +	const char *str;
>>> +	int ret = 0;
>>> +
>>> +	ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
>>> +	if (ret == 0)
>>> +		return scnprintf(buf, PAGE_SIZE, "%s\n", str);
>>> +	else
>>> +		return ret;
>>> +}
>>> +static DEVICE_ATTR_RO(label);
>>> +
>>>    static struct attribute *coresight_sink_attrs[] = {
>>>    	&dev_attr_enable_sink.attr,
>>> +	&dev_attr_label.attr,
>>>    	NULL,
>>>    };
>>>    ATTRIBUTE_GROUPS(coresight_sink);
>>>
>>>    static struct attribute *coresight_source_attrs[] = {
>>>    	&dev_attr_enable_source.attr,
>>> +	&dev_attr_label.attr,
>>>    	NULL,
>>>    };
>>>    ATTRIBUTE_GROUPS(coresight_source);
>>>
>>> +static struct attribute *coresight_link_attrs[] = {
>>> +	&dev_attr_label.attr,
>>> +	NULL,
>>> +};
>>> +ATTRIBUTE_GROUPS(coresight_link);
>>> +
>>> +static struct attribute *coresight_helper_attrs[] = {
>>> +	&dev_attr_label.attr,
>>> +	NULL,
>>> +};
>>> +ATTRIBUTE_GROUPS(coresight_helper);
>>> +
>>>    const struct device_type coresight_dev_type[] = {
>>>    	[CORESIGHT_DEV_TYPE_SINK] = {
>>>    		.name = "sink",
>>> @@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
>>>    	},
>>>    	[CORESIGHT_DEV_TYPE_LINK] = {
>>>    		.name = "link",
>>> +		.groups = coresight_link_groups,
>>>    	},
>>>    	[CORESIGHT_DEV_TYPE_LINKSINK] = {
>>>    		.name = "linksink",
>>> @@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
>>>    	},
>>>    	[CORESIGHT_DEV_TYPE_HELPER] = {
>>>    		.name = "helper",
>>> +		.groups = coresight_helper_groups,
>>>    	}
>>>    };
>>>    /* Ensure the enum matches the names and groups */
>>
>> _______________________________________________
>> CoreSight mailing list -- coresight at lists.linaro.org To unsubscribe send an
>> email to coresight-leave at lists.linaro.org



From conor at kernel.org  Wed Dec 18 10:25:11 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 18 Dec 2024 18:25:11 +0000
Subject: [PATCH 2/9] dt-bindings: media: clarify stm32 csi & simplify
 example
In-Reply-To: <Z2HpVyVEs7jn0VPd@kekkonen.localdomain>
References: <20241217-csi_dcmipp_mp25_enhancements-v1-0-2b432805d17d@foss.st.com>
 <20241217-csi_dcmipp_mp25_enhancements-v1-2-2b432805d17d@foss.st.com>
 <20241217-crawfish-tiring-792c535301d0@spud>
 <Z2HpVyVEs7jn0VPd@kekkonen.localdomain>
Message-ID: <20241218-yelling-palm-da676b67afb9@spud>

On Tue, Dec 17, 2024 at 09:12:55PM +0000, Sakari Ailus wrote:
> Hi Conor,
> 
> On Tue, Dec 17, 2024 at 06:24:42PM +0000, Conor Dooley wrote:
> > On Tue, Dec 17, 2024 at 06:39:19PM +0100, Alain Volmat wrote:
> > > Clarify the description of the stm32 csi by mentioning CSI-2 and
> > > D-PHY.
> > 
> > > Remove the bus-type property from the example.
> > 
> > Why? What's there to gain from the example being (seemingly?) less
> > comprehensive?
> 
> As the device has D-PHY, other options are excluded. I.e. that property is
> redundant for this device.

That should be mentioned in the commit message.
-------------- 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/20241218/8dbb1efc/attachment.sig>

From broonie at kernel.org  Wed Dec 18 10:25:37 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 18 Dec 2024 18:25:37 +0000
Subject: [PATCH] spi: atmel-quadspi: Factor out switching to Serial
 Memory Mode to function
In-Reply-To: <20241218151754.365519-1-csokas.bence@prolan.hu>
References: <20241218151754.365519-1-csokas.bence@prolan.hu>
Message-ID: <173454633792.186813.10395351752792939671.b4-ty@kernel.org>

On Wed, 18 Dec 2024 16:17:54 +0100, Bence Cs?k?s wrote:
> SAMA7G5 support (that was forward-ported from v6.1) re-introduced
> a bug that was fixed in v6.12, thankfully only in the codepath of
> the new SoC. But to prevent similar mistakes in the future, we
> split out the offending code to a function, and use this, fixed
> version everywhere.
> 
> To facilitate this, support function `atmel_qspi_update_config()`
> also had to be moved upwards. For best viewing experience, use
> `--color-moved-ws="allow-indentation-change" --color-moved`.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: atmel-quadspi: Factor out switching to Serial Memory Mode to function
      commit: f663898d047a7a0a04d30732b1405ee007fdd243

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 towinchenmi at gmail.com  Wed Dec 18 10:25:07 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 19 Dec 2024 02:25:07 +0800
Subject: [PATCH v3 5/7] cpufreq: apple-soc: Increase cluster switch timeout to 400us
In-Reply-To: <20241218182834.22334-1-towinchenmi@gmail.com>
References: <20241218182834.22334-1-towinchenmi@gmail.com>
Message-ID: <20241218182834.22334-6-towinchenmi@gmail.com>

Apple A11 SoC takes a long time to switch. Maximum switch time
observed is 345us, so increase the cluster switch timeout to 400us
to be safe.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index b27d261fe5a6..94e57f055a5f 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -53,7 +53,7 @@
 #define APPLE_DVFS_PLL_FACTOR_MULT	GENMASK(31, 16)
 #define APPLE_DVFS_PLL_FACTOR_DIV	GENMASK(15, 0)
 
-#define APPLE_DVFS_TRANSITION_TIMEOUT 100
+#define APPLE_DVFS_TRANSITION_TIMEOUT 400
 
 struct apple_soc_cpufreq_info {
 	bool has_ps2;
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 18 10:25:08 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 19 Dec 2024 02:25:08 +0800
Subject: [PATCH v3 6/7] cpufreq: apple-soc: Set fallback transition latency to APPLE_DVFS_TRANSITION_TIMEOUT
In-Reply-To: <20241218182834.22334-1-towinchenmi@gmail.com>
References: <20241218182834.22334-1-towinchenmi@gmail.com>
Message-ID: <20241218182834.22334-7-towinchenmi@gmail.com>

The driver already assumes transitions will not take longer than
APPLE_DVFS_TRANSITION_TIMEOUT in apple_soc_cpufreq_set_target(), so it
makes little sense to set CPUFREQ_ETERNAL as the transition latency
when the transistion latency is not given by the opp-table.

Reviewed-by: Christian Loehle <christian.loehle at arm.com>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 94e57f055a5f..879ddec9e557 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -291,7 +291,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy)
 
 	transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
 	if (!transition_latency)
-		transition_latency = CPUFREQ_ETERNAL;
+		transition_latency = APPLE_DVFS_TRANSITION_TIMEOUT * NSEC_PER_USEC;
 
 	policy->cpuinfo.transition_latency = transition_latency;
 	policy->dvfs_possible_from_any_cpu = true;
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 18 10:25:02 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 19 Dec 2024 02:25:02 +0800
Subject: [PATCH v3 0/7] Apple A7-A11, T2 SoC cpufreq support
Message-ID: <20241218182834.22334-1-towinchenmi@gmail.com>

This series add driver support for cpufreq Apple A7-A11, T2 SoCs.
Device Tree nodes will be included in another series.

Changes since v2:
- Use NSEC_PER_USEC instead of 1000 as multplier.

v2: https://lore.kernel.org/asahi/20241212070344.3858-1-towinchenmi at gmail.com/T

Changes since v1:
- transition_latency is in ns, APPLE_DVFS_TRANSITION_TIMEOUT in us.
Multiply APPLE_DVFS_TRANSITION_TIMEOUT by 1000 before setting it as
transition_latency.

v1: https://lore.kernel.org/asahi/20241211112244.18393-1-towinchenmi at gmail.com/T

Nick Chan
---

Hector Martin (1):
  cpufreq: apple-soc: Drop setting the PS2 field on M2+

Nick Chan (6):
  dt-bindings: cpufreq: apple,cluster-cpufreq: Add A7-A11, T2
    compatibles
  cpufreq: apple-soc: Allow per-SoC configuration of APPLE_DVFS_CMD_PS1
  cpufreq: apple-soc: Use 32-bit read for status register
  cpufreq: apple-soc: Increase cluster switch timeout to 400us
  cpufreq: apple-soc: Set fallback transition latency to
    APPLE_DVFS_TRANSITION_TIMEOUT
  cpufreq: apple-soc: Add Apple A7-A8X SoC cpufreq support

 .../cpufreq/apple,cluster-cpufreq.yaml        | 10 +++-
 drivers/cpufreq/apple-soc-cpufreq.c           | 56 +++++++++++++++----
 2 files changed, 54 insertions(+), 12 deletions(-)


base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 18 10:25:03 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 19 Dec 2024 02:25:03 +0800
Subject: [PATCH v3 1/7] dt-bindings: cpufreq: apple,cluster-cpufreq: Add A7-A11, T2 compatibles
In-Reply-To: <20241218182834.22334-1-towinchenmi@gmail.com>
References: <20241218182834.22334-1-towinchenmi@gmail.com>
Message-ID: <20241218182834.22334-2-towinchenmi@gmail.com>

Add compatibles for Apple A7-A11, T2 SoCs.

Apple A7, A8, A8X gets the per-SoC compatible and the A7
"apple,s5l8960x-cluster-cpufreq" compatible.

Apple A9, A9X, A10, A10X, T2, A11 gets the per-SoC compatible, M1
"apple,t8103-cluster-cpufreq" compatible, then the
"apple,cluster-cpufreq" fallback compatible.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../bindings/cpufreq/apple,cluster-cpufreq.yaml        | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml b/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml
index 76cb9726660e..896276b8c6bb 100644
--- a/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml
+++ b/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml
@@ -24,9 +24,17 @@ properties:
               - apple,t8112-cluster-cpufreq
           - const: apple,cluster-cpufreq
       - items:
-          - const: apple,t6000-cluster-cpufreq
+          - enum:
+              - apple,s8000-cluster-cpufreq
+              - apple,t8010-cluster-cpufreq
+              - apple,t8015-cluster-cpufreq
+              - apple,t6000-cluster-cpufreq
           - const: apple,t8103-cluster-cpufreq
           - const: apple,cluster-cpufreq
+      - items:
+          - const: apple,t7000-cluster-cpufreq
+          - const: apple,s5l8960x-cluster-cpufreq
+      - const: apple,s5l8960x-cluster-cpufreq
 
   reg:
     maxItems: 1
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 18 10:25:04 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 19 Dec 2024 02:25:04 +0800
Subject: [PATCH v3 2/7] cpufreq: apple-soc: Drop setting the PS2 field on M2+
In-Reply-To: <20241218182834.22334-1-towinchenmi@gmail.com>
References: <20241218182834.22334-1-towinchenmi@gmail.com>
Message-ID: <20241218182834.22334-3-towinchenmi@gmail.com>

From: Hector Martin <marcan at marcan.st>

Newer device do not use this. It is not known what this field does,
but change the behavior to be same as macOS to be safe.

Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 4dcacab9b4bf..ad6c7b8f290c 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -25,7 +25,7 @@
 #define APPLE_DVFS_CMD			0x20
 #define APPLE_DVFS_CMD_BUSY		BIT(31)
 #define APPLE_DVFS_CMD_SET		BIT(25)
-#define APPLE_DVFS_CMD_PS2		GENMASK(16, 12)
+#define APPLE_DVFS_CMD_PS2		GENMASK(15, 12)
 #define APPLE_DVFS_CMD_PS1		GENMASK(4, 0)
 
 /* Same timebase as CPU counter (24MHz) */
@@ -55,6 +55,7 @@
 #define APPLE_DVFS_TRANSITION_TIMEOUT 100
 
 struct apple_soc_cpufreq_info {
+	bool has_ps2;
 	u64 max_pstate;
 	u64 cur_pstate_mask;
 	u64 cur_pstate_shift;
@@ -69,18 +70,21 @@ struct apple_cpu_priv {
 static struct cpufreq_driver apple_soc_cpufreq_driver;
 
 static const struct apple_soc_cpufreq_info soc_t8103_info = {
+	.has_ps2 = true,
 	.max_pstate = 15,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8103,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103,
 };
 
 static const struct apple_soc_cpufreq_info soc_t8112_info = {
+	.has_ps2 = false,
 	.max_pstate = 31,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8112,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8112,
 };
 
 static const struct apple_soc_cpufreq_info soc_default_info = {
+	.has_ps2 = false,
 	.max_pstate = 15,
 	.cur_pstate_mask = 0, /* fallback */
 };
@@ -148,9 +152,12 @@ static int apple_soc_cpufreq_set_target(struct cpufreq_policy *policy,
 		return -EIO;
 	}
 
-	reg &= ~(APPLE_DVFS_CMD_PS1 | APPLE_DVFS_CMD_PS2);
+	reg &= ~APPLE_DVFS_CMD_PS1;
 	reg |= FIELD_PREP(APPLE_DVFS_CMD_PS1, pstate);
-	reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
+	if (priv->info->has_ps2) {
+		reg &= ~APPLE_DVFS_CMD_PS2;
+		reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
+	}
 	reg |= APPLE_DVFS_CMD_SET;
 
 	writeq_relaxed(reg, priv->reg_base + APPLE_DVFS_CMD);
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 18 10:25:05 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 19 Dec 2024 02:25:05 +0800
Subject: [PATCH v3 3/7] cpufreq: apple-soc: Allow per-SoC configuration of APPLE_DVFS_CMD_PS1
In-Reply-To: <20241218182834.22334-1-towinchenmi@gmail.com>
References: <20241218182834.22334-1-towinchenmi@gmail.com>
Message-ID: <20241218182834.22334-4-towinchenmi@gmail.com>

Support for SoC that has a different APPLE_DVFS_CMD_PS1 will be added soon,
so modify the driver first to allow it to be configured per-SoC.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index ad6c7b8f290c..90e34105b50b 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -27,6 +27,7 @@
 #define APPLE_DVFS_CMD_SET		BIT(25)
 #define APPLE_DVFS_CMD_PS2		GENMASK(15, 12)
 #define APPLE_DVFS_CMD_PS1		GENMASK(4, 0)
+#define APPLE_DVFS_CMD_PS1_SHIFT	0
 
 /* Same timebase as CPU counter (24MHz) */
 #define APPLE_DVFS_LAST_CHG_TIME	0x38
@@ -59,6 +60,8 @@ struct apple_soc_cpufreq_info {
 	u64 max_pstate;
 	u64 cur_pstate_mask;
 	u64 cur_pstate_shift;
+	u64 ps1_mask;
+	u64 ps1_shift;
 };
 
 struct apple_cpu_priv {
@@ -74,6 +77,8 @@ static const struct apple_soc_cpufreq_info soc_t8103_info = {
 	.max_pstate = 15,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8103,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103,
+	.ps1_mask = APPLE_DVFS_CMD_PS1,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_SHIFT,
 };
 
 static const struct apple_soc_cpufreq_info soc_t8112_info = {
@@ -81,12 +86,16 @@ static const struct apple_soc_cpufreq_info soc_t8112_info = {
 	.max_pstate = 31,
 	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_T8112,
 	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8112,
+	.ps1_mask = APPLE_DVFS_CMD_PS1,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_SHIFT,
 };
 
 static const struct apple_soc_cpufreq_info soc_default_info = {
 	.has_ps2 = false,
 	.max_pstate = 15,
 	.cur_pstate_mask = 0, /* fallback */
+	.ps1_mask = APPLE_DVFS_CMD_PS1,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_SHIFT,
 };
 
 static const struct of_device_id apple_soc_cpufreq_of_match[] __maybe_unused = {
@@ -152,8 +161,8 @@ static int apple_soc_cpufreq_set_target(struct cpufreq_policy *policy,
 		return -EIO;
 	}
 
-	reg &= ~APPLE_DVFS_CMD_PS1;
-	reg |= FIELD_PREP(APPLE_DVFS_CMD_PS1, pstate);
+	reg &= ~priv->info->ps1_mask;
+	reg |= pstate << priv->info->ps1_shift;
 	if (priv->info->has_ps2) {
 		reg &= ~APPLE_DVFS_CMD_PS2;
 		reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 18 10:25:06 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 19 Dec 2024 02:25:06 +0800
Subject: [PATCH v3 4/7] cpufreq: apple-soc: Use 32-bit read for status register
In-Reply-To: <20241218182834.22334-1-towinchenmi@gmail.com>
References: <20241218182834.22334-1-towinchenmi@gmail.com>
Message-ID: <20241218182834.22334-5-towinchenmi@gmail.com>

Apple A7-A9(X) SoCs requires 32-bit reads on the status register. Newer
SoCs accepts 32-bit reads on the status register as well.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 90e34105b50b..b27d261fe5a6 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -122,7 +122,7 @@ static unsigned int apple_soc_cpufreq_get_rate(unsigned int cpu)
 	unsigned int pstate;
 
 	if (priv->info->cur_pstate_mask) {
-		u64 reg = readq_relaxed(priv->reg_base + APPLE_DVFS_STATUS);
+		u32 reg = readl_relaxed(priv->reg_base + APPLE_DVFS_STATUS);
 
 		pstate = (reg & priv->info->cur_pstate_mask) >>  priv->info->cur_pstate_shift;
 	} else {
-- 
2.47.1



From towinchenmi at gmail.com  Wed Dec 18 10:25:09 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Thu, 19 Dec 2024 02:25:09 +0800
Subject: [PATCH v3 7/7] cpufreq: apple-soc: Add Apple A7-A8X SoC cpufreq support
In-Reply-To: <20241218182834.22334-1-towinchenmi@gmail.com>
References: <20241218182834.22334-1-towinchenmi@gmail.com>
Message-ID: <20241218182834.22334-8-towinchenmi@gmail.com>

These SoCs only use 3 bits for p-states, and have a different
APPLE_DVFS_CMD_PS1 mask value.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 drivers/cpufreq/apple-soc-cpufreq.c | 30 +++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
index 879ddec9e557..269b18c62d04 100644
--- a/drivers/cpufreq/apple-soc-cpufreq.c
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
@@ -22,12 +22,14 @@
 #include <linux/pm_opp.h>
 #include <linux/slab.h>
 
-#define APPLE_DVFS_CMD			0x20
-#define APPLE_DVFS_CMD_BUSY		BIT(31)
-#define APPLE_DVFS_CMD_SET		BIT(25)
-#define APPLE_DVFS_CMD_PS2		GENMASK(15, 12)
-#define APPLE_DVFS_CMD_PS1		GENMASK(4, 0)
-#define APPLE_DVFS_CMD_PS1_SHIFT	0
+#define APPLE_DVFS_CMD				0x20
+#define APPLE_DVFS_CMD_BUSY			BIT(31)
+#define APPLE_DVFS_CMD_SET			BIT(25)
+#define APPLE_DVFS_CMD_PS1_S5L8960X		GENMASK(24, 22)
+#define APPLE_DVFS_CMD_PS1_S5L8960X_SHIFT	22
+#define APPLE_DVFS_CMD_PS2			GENMASK(15, 12)
+#define APPLE_DVFS_CMD_PS1			GENMASK(4, 0)
+#define APPLE_DVFS_CMD_PS1_SHIFT		0
 
 /* Same timebase as CPU counter (24MHz) */
 #define APPLE_DVFS_LAST_CHG_TIME	0x38
@@ -36,6 +38,9 @@
  * Apple ran out of bits and had to shift this in T8112...
  */
 #define APPLE_DVFS_STATUS			0x50
+#define APPLE_DVFS_STATUS_CUR_PS_S5L8960X	GENMASK(5, 3)
+#define APPLE_DVFS_STATUS_CUR_PS_SHIFT_S5L8960X	3
+#define APPLE_DVFS_STATUS_TGT_PS_S5L8960X	GENMASK(2, 0)
 #define APPLE_DVFS_STATUS_CUR_PS_T8103		GENMASK(7, 4)
 #define APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103	4
 #define APPLE_DVFS_STATUS_TGT_PS_T8103		GENMASK(3, 0)
@@ -72,6 +77,15 @@ struct apple_cpu_priv {
 
 static struct cpufreq_driver apple_soc_cpufreq_driver;
 
+static const struct apple_soc_cpufreq_info soc_s5l8960x_info = {
+	.has_ps2 = false,
+	.max_pstate = 7,
+	.cur_pstate_mask = APPLE_DVFS_STATUS_CUR_PS_S5L8960X,
+	.cur_pstate_shift = APPLE_DVFS_STATUS_CUR_PS_SHIFT_S5L8960X,
+	.ps1_mask = APPLE_DVFS_CMD_PS1_S5L8960X,
+	.ps1_shift = APPLE_DVFS_CMD_PS1_S5L8960X_SHIFT,
+};
+
 static const struct apple_soc_cpufreq_info soc_t8103_info = {
 	.has_ps2 = true,
 	.max_pstate = 15,
@@ -99,6 +113,10 @@ static const struct apple_soc_cpufreq_info soc_default_info = {
 };
 
 static const struct of_device_id apple_soc_cpufreq_of_match[] __maybe_unused = {
+	{
+		.compatible = "apple,s5l8960x-cluster-cpufreq",
+		.data = &soc_s5l8960x_info,
+	},
 	{
 		.compatible = "apple,t8103-cluster-cpufreq",
 		.data = &soc_t8103_info,
-- 
2.47.1



From robh at kernel.org  Wed Dec 18 11:05:17 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 18 Dec 2024 13:05:17 -0600
Subject: [PATCH v4 0/7] arm64: qcom: Add support for QCS9075 boards
In-Reply-To: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
Message-ID: <173454864189.2147955.17810187271585604985.robh@kernel.org>


On Tue, 17 Dec 2024 12:18:49 +0530, Wasim Nazir wrote:
> This series:
> 
> Add support for Qualcomm's rb8, ride/ride-r3 boards using QCS9075 SoC.
> 
> QCS9075 is compatible IoT-industrial grade variant of SA8775p SoC.
> Unlike QCS9100, it doesn't have safety monitoring feature of
> Safety-Island(SAIL) subsystem, which affects thermal management.
> 
> In QCS9100 SoC, the safety subsystem monitors all thermal sensors and
> does corrective action for each subsystem based on sensor violation
> to comply safety standards. But as QCS9075 is non-safe SoC it requires
> conventional thermal mitigation for thermal management.
> 
> Difference between Ride & ride-r3 boards is ethernet phy,
> ride uses 1G ethernet phy while ride-r3 uses 2.5G ethernet phy.
> 
> This series depends on [1] for thermal functionality to work.
> 
> [1]: https://lore.kernel.org/all/20241112-sa8775p_cpuidle-v1-1-66ff3ba72464 at quicinc.com/
> 
> ---
> Changelog:
> 
> v4:
>   - Replace dts to dtsi in Ride/Ride-r3 platform files
>   - Add thermal patch to differentiate between 9100 vs 9075
>   - Add proper abbreviation and update commit for 9100 vs 9075
>   - v3: https://lore.kernel.org/all/20241119174954.1219002-1-quic_wasimn at quicinc.com/
> 
> v3:
>   - Fix RB8 board compatible string
>   - v2: https://lore.kernel.org/all/20241115225152.3264396-1-quic_wasimn at quicinc.com/
> 
> v2:
>   - Remove unused dp nodes & update commit for ride vs ride-r3.
>   - v1: https://lore.kernel.org/all/20241110145339.3635437-1-quic_wasimn at quicinc.com/
> 
> Manaf Meethalavalappu Pallikunhi (2):
>   arm64: defconfig: enable cpu idle injection and cpu idle cooling
>     device
>   arm64: dts: qcom: Enable cpu cooling devices for QCS9075 platforms
> 
> Wasim Nazir (5):
>   dt-bindings: arm: qcom,ids: add SoC ID for QCS9075
>   soc: qcom: socinfo: add QCS9075 SoC ID
>   dt-bindings: arm: qcom: Document rb8/ride/ride-r3 on QCS9075
>   arm64: dts: qcom: Add support for QCS9075 RB8
>   arm64: dts: qcom: Add support for QCS9075 Ride & Ride-r3
> 
>  .../devicetree/bindings/arm/qcom.yaml         |   9 +
>  arch/arm64/boot/dts/qcom/Makefile             |   3 +
>  arch/arm64/boot/dts/qcom/qcs9075-rb8.dts      | 282 +++++++++++++++++
>  arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts  |  47 +++
>  arch/arm64/boot/dts/qcom/qcs9075-ride.dts     |  47 +++
>  arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi | 287 ++++++++++++++++++
>  arch/arm64/configs/defconfig                  |   3 +
>  drivers/soc/qcom/socinfo.c                    |   1 +
>  include/dt-bindings/arm/qcom,ids.h            |   1 +
>  9 files changed, 680 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-rb8.dts
>  create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
>  create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-ride.dts
>  create mode 100644 arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi
> 
> 
> base-commit: 4176cf5c5651c33769de83bb61b0287f4ec7719f
> --
> 2.47.0
> 
> 
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y qcom/qcs9075-rb8.dtb qcom/qcs9075-ride-r3.dtb qcom/qcs9075-ride.dtb' for 20241217064856.2772305-1-quic_wasimn at quicinc.com:

arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: qcom,gpi-dma at 800000: $nodename:0: 'qcom,gpi-dma at 800000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-rb8.dtb: qcom,gpi-dma at 800000: $nodename:0: 'qcom,gpi-dma at 800000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: qcom,gpi-dma at 800000: $nodename:0: 'qcom,gpi-dma at 800000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: bluetooth: 'vddwlcx-supply' is a required property
	from schema $id: http://devicetree.org/schemas/net/bluetooth/qualcomm-bluetooth.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: bluetooth: 'vddwlmx-supply' is a required property
	from schema $id: http://devicetree.org/schemas/net/bluetooth/qualcomm-bluetooth.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: bluetooth: 'vddrfa1p8-supply' is a required property
	from schema $id: http://devicetree.org/schemas/net/bluetooth/qualcomm-bluetooth.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: bluetooth: 'vddwlcx-supply' is a required property
	from schema $id: http://devicetree.org/schemas/net/bluetooth/qualcomm-bluetooth.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: bluetooth: 'vddwlmx-supply' is a required property
	from schema $id: http://devicetree.org/schemas/net/bluetooth/qualcomm-bluetooth.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: bluetooth: 'vddrfa1p8-supply' is a required property
	from schema $id: http://devicetree.org/schemas/net/bluetooth/qualcomm-bluetooth.yaml#
arch/arm64/boot/dts/qcom/qcs9075-rb8.dtb: qcom,gpi-dma at 900000: $nodename:0: 'qcom,gpi-dma at 900000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: qcom,gpi-dma at 900000: $nodename:0: 'qcom,gpi-dma at 900000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: qcom,gpi-dma at 900000: $nodename:0: 'qcom,gpi-dma at 900000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: qcom,gpi-dma at a00000: $nodename:0: 'qcom,gpi-dma at a00000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-rb8.dtb: qcom,gpi-dma at a00000: $nodename:0: 'qcom,gpi-dma at a00000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: qcom,gpi-dma at a00000: $nodename:0: 'qcom,gpi-dma at a00000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-rb8.dtb: qcom,gpi-dma at b00000: $nodename:0: 'qcom,gpi-dma at b00000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: qcom,gpi-dma at b00000: $nodename:0: 'qcom,gpi-dma at b00000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: qcom,gpi-dma at b00000: $nodename:0: 'qcom,gpi-dma at b00000' does not match '^dma-controller(@.*)?$'
	from schema $id: http://devicetree.org/schemas/dma/qcom,gpi.yaml#
arch/arm64/boot/dts/qcom/qcs9075-rb8.dtb: crypto at 1dfa000: compatible: 'oneOf' conditional failed, one must be fixed:
	['qcom,sa8775p-qce', 'qcom,qce'] is too long
	['qcom,sa8775p-qce', 'qcom,qce'] is too short
	'qcom,crypto-v5.1' was expected
	'qcom,crypto-v5.4' was expected
	'qcom,sa8775p-qce' is not one of ['qcom,ipq4019-qce', 'qcom,sm8150-qce']
	'qcom,sa8775p-qce' is not one of ['qcom,ipq6018-qce', 'qcom,ipq8074-qce', 'qcom,ipq9574-qce', 'qcom,msm8996-qce', 'qcom,qcm2290-qce', 'qcom,sdm845-qce', 'qcom,sm6115-qce']
	'qcom,ipq4019-qce' was expected
	'qcom,sm8150-qce' was expected
	from schema $id: http://devicetree.org/schemas/crypto/qcom-qce.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: crypto at 1dfa000: compatible: 'oneOf' conditional failed, one must be fixed:
	['qcom,sa8775p-qce', 'qcom,qce'] is too long
	['qcom,sa8775p-qce', 'qcom,qce'] is too short
	'qcom,crypto-v5.1' was expected
	'qcom,crypto-v5.4' was expected
	'qcom,sa8775p-qce' is not one of ['qcom,ipq4019-qce', 'qcom,sm8150-qce']
	'qcom,sa8775p-qce' is not one of ['qcom,ipq6018-qce', 'qcom,ipq8074-qce', 'qcom,ipq9574-qce', 'qcom,msm8996-qce', 'qcom,qcm2290-qce', 'qcom,sdm845-qce', 'qcom,sm6115-qce']
	'qcom,ipq4019-qce' was expected
	'qcom,sm8150-qce' was expected
	from schema $id: http://devicetree.org/schemas/crypto/qcom-qce.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: crypto at 1dfa000: compatible: 'oneOf' conditional failed, one must be fixed:
	['qcom,sa8775p-qce', 'qcom,qce'] is too long
	['qcom,sa8775p-qce', 'qcom,qce'] is too short
	'qcom,crypto-v5.1' was expected
	'qcom,crypto-v5.4' was expected
	'qcom,sa8775p-qce' is not one of ['qcom,ipq4019-qce', 'qcom,sm8150-qce']
	'qcom,sa8775p-qce' is not one of ['qcom,ipq6018-qce', 'qcom,ipq8074-qce', 'qcom,ipq9574-qce', 'qcom,msm8996-qce', 'qcom,qcm2290-qce', 'qcom,sdm845-qce', 'qcom,sm6115-qce']
	'qcom,ipq4019-qce' was expected
	'qcom,sm8150-qce' was expected
	from schema $id: http://devicetree.org/schemas/crypto/qcom-qce.yaml#
arch/arm64/boot/dts/qcom/qcs9075-rb8.dtb: rsc at 18200000: 'power-domains' is a required property
	from schema $id: http://devicetree.org/schemas/soc/qcom/qcom,rpmh-rsc.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: rsc at 18200000: 'power-domains' is a required property
	from schema $id: http://devicetree.org/schemas/soc/qcom/qcom,rpmh-rsc.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: rsc at 18200000: 'power-domains' is a required property
	from schema $id: http://devicetree.org/schemas/soc/qcom/qcom,rpmh-rsc.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: ethernet at 23000000: tx-queues-config: 'snps,tx-sched-sp' does not match any of the regexes: '^queue[0-9]$', 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/net/qcom,ethqos.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: ethernet at 23000000: Unevaluated properties are not allowed ('interconnect-names', 'interconnects', 'phy-handle', 'phy-mode', 'power-domains', 'rx-fifo-depth', 'rx-queues-config', 'snps,mtl-rx-config', 'snps,mtl-tx-config', 'snps,pbl', 'snps,ps-speed', 'snps,tso', 'tx-fifo-depth', 'tx-queues-config' were unexpected)
	from schema $id: http://devicetree.org/schemas/net/qcom,ethqos.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: ethernet at 23000000: tx-queues-config: 'snps,tx-sched-sp' does not match any of the regexes: '^queue[0-9]$', 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/net/qcom,ethqos.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: ethernet at 23000000: Unevaluated properties are not allowed ('interconnect-names', 'interconnects', 'phy-handle', 'phy-mode', 'power-domains', 'rx-fifo-depth', 'rx-queues-config', 'snps,mtl-rx-config', 'snps,mtl-tx-config', 'snps,pbl', 'snps,ps-speed', 'snps,tso', 'tx-fifo-depth', 'tx-queues-config' were unexpected)
	from schema $id: http://devicetree.org/schemas/net/qcom,ethqos.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: ethernet at 23040000: tx-queues-config: 'snps,tx-sched-sp' does not match any of the regexes: '^queue[0-9]$', 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/net/qcom,ethqos.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: ethernet at 23040000: Unevaluated properties are not allowed ('interconnect-names', 'interconnects', 'mdio', 'phy-handle', 'phy-mode', 'power-domains', 'rx-fifo-depth', 'rx-queues-config', 'snps,mtl-rx-config', 'snps,mtl-tx-config', 'snps,pbl', 'snps,ps-speed', 'snps,tso', 'tx-fifo-depth', 'tx-queues-config' were unexpected)
	from schema $id: http://devicetree.org/schemas/net/qcom,ethqos.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: ethernet at 23040000: tx-queues-config: 'snps,tx-sched-sp' does not match any of the regexes: '^queue[0-9]$', 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/net/qcom,ethqos.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: ethernet at 23040000: Unevaluated properties are not allowed ('interconnect-names', 'interconnects', 'mdio', 'phy-handle', 'phy-mode', 'power-domains', 'rx-fifo-depth', 'rx-queues-config', 'snps,mtl-rx-config', 'snps,mtl-tx-config', 'snps,pbl', 'snps,ps-speed', 'snps,tso', 'tx-fifo-depth', 'tx-queues-config' were unexpected)
	from schema $id: http://devicetree.org/schemas/net/qcom,ethqos.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: wcn6855-pmu: 'vddpmumx-supply' is a required property
	from schema $id: http://devicetree.org/schemas/regulator/qcom,qca6390-pmu.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dtb: wcn6855-pmu: 'vddpmucx-supply' is a required property
	from schema $id: http://devicetree.org/schemas/regulator/qcom,qca6390-pmu.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: wcn6855-pmu: 'vddpmumx-supply' is a required property
	from schema $id: http://devicetree.org/schemas/regulator/qcom,qca6390-pmu.yaml#
arch/arm64/boot/dts/qcom/qcs9075-ride.dtb: wcn6855-pmu: 'vddpmucx-supply' is a required property
	from schema $id: http://devicetree.org/schemas/regulator/qcom,qca6390-pmu.yaml#







From Frank.li at nxp.com  Wed Dec 18 11:10:14 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 14:10:14 -0500
Subject: [PATCH v3] i2c: imx: add imx7d compatible string for applying
 errata ERR007805
In-Reply-To: <20241218044238.143414-1-carlos.song@nxp.com>
References: <20241218044238.143414-1-carlos.song@nxp.com>
Message-ID: <Z2MeFp8sDfDlqrOc@lizhi-Precision-Tower-5810>

On Wed, Dec 18, 2024 at 12:42:38PM +0800, Carlos Song wrote:
> Compatible string "fsl,imx7d-i2c" is not exited at i2c-imx driver
> compatible string table, at the result, "fsl,imx21-i2c" will be
> matched, but it will cause errata ERR007805 not be applied in fact.
>
> So Add "fsl,imx7d-i2c" compatible string in i2c-imx driver to apply
> the errata ERR007805(https://www.nxp.com/webapp/Download?colCode=
> IMX7DS_2N09P).
>
> "fsl,imx7d-i2c" already is documented in binding doc. This errata
> fix has been included in imx6_i2c_hwdata and it is the same in all
> I.MX6/7/8, so just reuse it.
>
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
> Change for V3:
> - No ACK, so resend this patch.
> Change for V2:
> - I have tried to fix this issue at imx7s.dtsi in V1, according to
>   the community suggestion, I make V2 patch for i2c-imx driver to
>   avoid updating the FDT to fix an errata. Discussion in V1:
>   Subject: [PATCH] ARM: dts: imx7s: change i2c compatible string for applying errata ERR007805
>   Message-ID: <20241021031148.2682015-1-carlos.song at nxp.com> (raw)
> ---
>  drivers/i2c/busses/i2c-imx.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index 350346a7892c..9d5caa032c5c 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -335,6 +335,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
>  	{ .compatible = "fsl,imx6sll-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx6sx-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx6ul-i2c", .data = &imx6_i2c_hwdata, },
> +	{ .compatible = "fsl,imx7d-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx7s-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx8mm-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx8mn-i2c", .data = &imx6_i2c_hwdata, },
> --
> 2.34.1
>


From robh at kernel.org  Wed Dec 18 11:16:31 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Dec 2024 13:16:31 -0600
Subject: [PATCH 3/4] arm64: dts: exynos: gs101-oriole: move common Pixel6
 & 6Pro parts into a .dtsi
In-Reply-To: <6e22585f8d374f8e26a2a51153680041ad8b1bea.camel@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
 <20241216-gs101-simplefb-v1-3-8ccad1830281@linaro.org>
 <fw2a6taf4kd3sggmyppeym2uxkuyotxy7ugj3bh73vetnra4m6@jllekadordju>
 <6e22585f8d374f8e26a2a51153680041ad8b1bea.camel@linaro.org>
Message-ID: <20241218191631.GA1837559-robh@kernel.org>

On Tue, Dec 17, 2024 at 08:34:50AM +0000, Andr? Draszik wrote:
> On Tue, 2024-12-17 at 08:38 +0100, Krzysztof Kozlowski wrote:
> > On Mon, Dec 16, 2024 at 01:06:28PM +0000, Andr? Draszik wrote:
> > > In order to support Pixel 6 (Oriole) and Pixel 6 Pro (Raven) properly,
> > > we have to be able to distinguish them properly as we add support for
> > > more features.
> > > 
> > > For example, Raven has a larger display. There are other differences,
> > > like battery design capacity, etc.
> > > 
> > > Move all the parts that are common for now into a gs101-raviole.dtsi,
> > > and just leave the display related things in gs101-oriole.dts.
> > > 
> > > Raviole was chosen as the name because Google uses that when referring
> > > to the combination of Oriole & Raven, keeping the familiar terminology.
> > > 
> > > Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> > > 
> > > ---
> > > Note: MAINTAINERS doesn't need updating, it covers this whole directory
> > > ---
> > > ?arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 290 +-------------------
> > > ?.../boot/dts/exynos/google/gs101-raviole.dtsi????? | 297 +++++++++++++++++++++
> > > ?2 files changed, 305 insertions(+), 282 deletions(-)
> > > 
> > 
> > This looks like move of the code, so -M/-B/-C format patch arguments
> > would create better diff.
> 
> Ah, yes, forgot about those when I switched to using b4 instead of
> custom scripts...

If b4 does not do that by default, then it should set the option. One 
less thing to get right for users. I sent a patch for that.

Rob


From robh at kernel.org  Wed Dec 18 11:17:23 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 18 Dec 2024 13:17:23 -0600
Subject: [PATCH 1/4] dt-bindings: arm: google: add gs101-raven
In-Reply-To: <20241216-gs101-simplefb-v1-1-8ccad1830281@linaro.org>
References: <20241216-gs101-simplefb-v1-0-8ccad1830281@linaro.org>
 <20241216-gs101-simplefb-v1-1-8ccad1830281@linaro.org>
Message-ID: <173454944244.2180961.12803549865520284851.robh@kernel.org>


On Mon, 16 Dec 2024 13:06:26 +0000, Andr? Draszik wrote:
> Raven is Google's code name for Pixel 6 Pro. Since there are
> differences compared to Pixel 6 (Oriole), we need to add a separate
> compatible for it.
> 
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> ---
>  Documentation/devicetree/bindings/arm/google.yaml | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From robh at kernel.org  Wed Dec 18 11:29:42 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 18 Dec 2024 13:29:42 -0600
Subject: [PATCH] dt-bindings: interrupt-controller: arm,gic: Correct VGIC
 interrupt description
In-Reply-To: <20241217061226.14139-1-krzysztof.kozlowski@linaro.org>
References: <20241217061226.14139-1-krzysztof.kozlowski@linaro.org>
Message-ID: <173455018100.2198330.12077558801772545243.robh@kernel.org>


On Tue, 17 Dec 2024 07:12:26 +0100, Krzysztof Kozlowski wrote:
> The description of VGIC interrupt referenced obsolete "see below" after
> converting TXT to DT Schema in commit 66ed144f147a ("dt-bindings:
> interrupt-controller: Convert ARM GIC to json-schema"), because there is
> no dedicated "VGIC" chapter anymore below.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>  .../devicetree/bindings/interrupt-controller/arm,gic.yaml     | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 

Applied, thanks!



From qperret at google.com  Wed Dec 18 11:40:44 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:44 +0000
Subject: [PATCH v4 03/18] KVM: arm64: Make hyp_page::order a u8
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-4-qperret@google.com>

We don't need 16 bits to store the hyp page order, and we'll need some
bits to store page ownership data soon, so let's reduce the order
member.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/gfp.h    |  6 +++---
 arch/arm64/kvm/hyp/include/nvhe/memory.h |  5 +++--
 arch/arm64/kvm/hyp/nvhe/page_alloc.c     | 14 +++++++-------
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
index 97c527ef53c2..3766333bace9 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
@@ -7,7 +7,7 @@
 #include <nvhe/memory.h>
 #include <nvhe/spinlock.h>
 
-#define HYP_NO_ORDER	USHRT_MAX
+#define HYP_NO_ORDER	((u8)(~0))
 
 struct hyp_pool {
 	/*
@@ -19,11 +19,11 @@ struct hyp_pool {
 	struct list_head free_area[NR_PAGE_ORDERS];
 	phys_addr_t range_start;
 	phys_addr_t range_end;
-	unsigned short max_order;
+	u8 max_order;
 };
 
 /* Allocation */
-void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order);
+void *hyp_alloc_pages(struct hyp_pool *pool, u8 order);
 void hyp_split_page(struct hyp_page *page);
 void hyp_get_page(struct hyp_pool *pool, void *addr);
 void hyp_put_page(struct hyp_pool *pool, void *addr);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index 0964c461da92..8f2b42bcc8e1 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -41,8 +41,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
 }
 
 struct hyp_page {
-	unsigned short refcount;
-	unsigned short order;
+	u16 refcount;
+	u8 order;
+	u8 reserved;
 };
 
 extern u64 __hyp_vmemmap;
diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
index e691290d3765..a1eb27a1a747 100644
--- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
+++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
@@ -32,7 +32,7 @@ u64 __hyp_vmemmap;
  */
 static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool,
 					     struct hyp_page *p,
-					     unsigned short order)
+					     u8 order)
 {
 	phys_addr_t addr = hyp_page_to_phys(p);
 
@@ -51,7 +51,7 @@ static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool,
 /* Find a buddy page currently available for allocation */
 static struct hyp_page *__find_buddy_avail(struct hyp_pool *pool,
 					   struct hyp_page *p,
-					   unsigned short order)
+					   u8 order)
 {
 	struct hyp_page *buddy = __find_buddy_nocheck(pool, p, order);
 
@@ -94,7 +94,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
 			      struct hyp_page *p)
 {
 	phys_addr_t phys = hyp_page_to_phys(p);
-	unsigned short order = p->order;
+	u8 order = p->order;
 	struct hyp_page *buddy;
 
 	memset(hyp_page_to_virt(p), 0, PAGE_SIZE << p->order);
@@ -129,7 +129,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
 
 static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool,
 					   struct hyp_page *p,
-					   unsigned short order)
+					   u8 order)
 {
 	struct hyp_page *buddy;
 
@@ -183,7 +183,7 @@ void hyp_get_page(struct hyp_pool *pool, void *addr)
 
 void hyp_split_page(struct hyp_page *p)
 {
-	unsigned short order = p->order;
+	u8 order = p->order;
 	unsigned int i;
 
 	p->order = 0;
@@ -195,10 +195,10 @@ void hyp_split_page(struct hyp_page *p)
 	}
 }
 
-void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order)
+void *hyp_alloc_pages(struct hyp_pool *pool, u8 order)
 {
-	unsigned short i = order;
 	struct hyp_page *p;
+	u8 i = order;
 
 	hyp_spin_lock(&pool->lock);
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:45 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:45 +0000
Subject: [PATCH v4 04/18] KVM: arm64: Move host page ownership tracking to the
 hyp vmemmap
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-5-qperret@google.com>

We currently store part of the page-tracking state in PTE software bits
for the host, guests and the hypervisor. This is sub-optimal when e.g.
sharing pages as this forces to break block mappings purely to support
this software tracking. This causes an unnecessarily fragmented stage-2
page-table for the host in particular when it shares pages with Secure,
which can lead to measurable regressions. Moreover, having this state
stored in the page-table forces us to do multiple costly walks on the
page transition path, hence causing overhead.

In order to work around these problems, move the host-side page-tracking
logic from SW bits in its stage-2 PTEs to the hypervisor's vmemmap.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/memory.h |  14 +++-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c    | 100 ++++++++++++++++-------
 arch/arm64/kvm/hyp/nvhe/setup.c          |   7 +-
 3 files changed, 84 insertions(+), 37 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index 8f2b42bcc8e1..2a5eabf4b753 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -8,7 +8,7 @@
 #include <linux/types.h>
 
 /*
- * SW bits 0-1 are reserved to track the memory ownership state of each page:
+ * Bits 0-1 are reserved to track the memory ownership state of each page:
  *   00: The page is owned exclusively by the page-table owner.
  *   01: The page is owned by the page-table owner, but is shared
  *       with another entity.
@@ -43,7 +43,9 @@ static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
 struct hyp_page {
 	u16 refcount;
 	u8 order;
-	u8 reserved;
+
+	/* Host (non-meta) state. Guarded by the host stage-2 lock. */
+	enum pkvm_page_state host_state : 8;
 };
 
 extern u64 __hyp_vmemmap;
@@ -63,7 +65,13 @@ static inline phys_addr_t hyp_virt_to_phys(void *addr)
 
 #define hyp_phys_to_pfn(phys)	((phys) >> PAGE_SHIFT)
 #define hyp_pfn_to_phys(pfn)	((phys_addr_t)((pfn) << PAGE_SHIFT))
-#define hyp_phys_to_page(phys)	(&hyp_vmemmap[hyp_phys_to_pfn(phys)])
+
+static inline struct hyp_page *hyp_phys_to_page(phys_addr_t phys)
+{
+	BUILD_BUG_ON(sizeof(struct hyp_page) != sizeof(u32));
+	return &hyp_vmemmap[hyp_phys_to_pfn(phys)];
+}
+
 #define hyp_virt_to_page(virt)	hyp_phys_to_page(__hyp_pa(virt))
 #define hyp_virt_to_pfn(virt)	hyp_phys_to_pfn(__hyp_pa(virt))
 
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index caba3e4bd09e..12bb5445fe47 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -201,8 +201,8 @@ static void *guest_s2_zalloc_page(void *mc)
 
 	memset(addr, 0, PAGE_SIZE);
 	p = hyp_virt_to_page(addr);
-	memset(p, 0, sizeof(*p));
 	p->refcount = 1;
+	p->order = 0;
 
 	return addr;
 }
@@ -268,6 +268,7 @@ int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd)
 
 void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
 {
+	struct hyp_page *page;
 	void *addr;
 
 	/* Dump all pgtable pages in the hyp_pool */
@@ -279,7 +280,9 @@ void reclaim_guest_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
 	/* Drain the hyp_pool into the memcache */
 	addr = hyp_alloc_pages(&vm->pool, 0);
 	while (addr) {
-		memset(hyp_virt_to_page(addr), 0, sizeof(struct hyp_page));
+		page = hyp_virt_to_page(addr);
+		page->refcount = 0;
+		page->order = 0;
 		push_hyp_memcache(mc, addr, hyp_virt_to_phys);
 		WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1));
 		addr = hyp_alloc_pages(&vm->pool, 0);
@@ -382,19 +385,28 @@ bool addr_is_memory(phys_addr_t phys)
 	return !!find_mem_range(phys, &range);
 }
 
-static bool addr_is_allowed_memory(phys_addr_t phys)
+static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
+{
+	return range->start <= addr && addr < range->end;
+}
+
+static int check_range_allowed_memory(u64 start, u64 end)
 {
 	struct memblock_region *reg;
 	struct kvm_mem_range range;
 
-	reg = find_mem_range(phys, &range);
+	/*
+	 * Callers can't check the state of a range that overlaps memory and
+	 * MMIO regions, so ensure [start, end[ is in the same kvm_mem_range.
+	 */
+	reg = find_mem_range(start, &range);
+	if (!is_in_mem_range(end - 1, &range))
+		return -EINVAL;
 
-	return reg && !(reg->flags & MEMBLOCK_NOMAP);
-}
+	if (!reg || reg->flags & MEMBLOCK_NOMAP)
+		return -EPERM;
 
-static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range)
-{
-	return range->start <= addr && addr < range->end;
+	return 0;
 }
 
 static bool range_is_memory(u64 start, u64 end)
@@ -454,8 +466,10 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
 	if (kvm_pte_valid(pte))
 		return -EAGAIN;
 
-	if (pte)
+	if (pte) {
+		WARN_ON(addr_is_memory(addr) && hyp_phys_to_page(addr)->host_state != PKVM_NOPAGE);
 		return -EPERM;
+	}
 
 	do {
 		u64 granule = kvm_granule_size(level);
@@ -477,10 +491,33 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
 	return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
 }
 
+static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm_page_state state)
+{
+	phys_addr_t end = addr + size;
+
+	for (; addr < end; addr += PAGE_SIZE)
+		hyp_phys_to_page(addr)->host_state = state;
+}
+
 int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
 {
-	return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
-			       addr, size, &host_s2_pool, owner_id);
+	int ret;
+
+	if (!addr_is_memory(addr))
+		return -EPERM;
+
+	ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_mmu.pgt,
+			      addr, size, &host_s2_pool, owner_id);
+	if (ret)
+		return ret;
+
+	/* Don't forget to update the vmemmap tracking for the host */
+	if (owner_id == PKVM_ID_HOST)
+		__host_update_page_state(addr, size, PKVM_PAGE_OWNED);
+	else
+		__host_update_page_state(addr, size, PKVM_NOPAGE);
+
+	return 0;
 }
 
 static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
@@ -604,35 +641,38 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size,
 	return kvm_pgtable_walk(pgt, addr, size, &walker);
 }
 
-static enum pkvm_page_state host_get_page_state(kvm_pte_t pte, u64 addr)
-{
-	if (!addr_is_allowed_memory(addr))
-		return PKVM_NOPAGE;
-
-	if (!kvm_pte_valid(pte) && pte)
-		return PKVM_NOPAGE;
-
-	return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
-}
-
 static int __host_check_page_state_range(u64 addr, u64 size,
 					 enum pkvm_page_state state)
 {
-	struct check_walk_data d = {
-		.desired	= state,
-		.get_page_state	= host_get_page_state,
-	};
+	u64 end = addr + size;
+	int ret;
+
+	ret = check_range_allowed_memory(addr, end);
+	if (ret)
+		return ret;
 
 	hyp_assert_lock_held(&host_mmu.lock);
-	return check_page_state_range(&host_mmu.pgt, addr, size, &d);
+	for (; addr < end; addr += PAGE_SIZE) {
+		if (hyp_phys_to_page(addr)->host_state != state)
+			return -EPERM;
+	}
+
+	return 0;
 }
 
 static int __host_set_page_state_range(u64 addr, u64 size,
 				       enum pkvm_page_state state)
 {
-	enum kvm_pgtable_prot prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, state);
+	if (hyp_phys_to_page(addr)->host_state == PKVM_NOPAGE) {
+		int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT);
 
-	return host_stage2_idmap_locked(addr, size, prot);
+		if (ret)
+			return ret;
+	}
+
+	__host_update_page_state(addr, size, state);
+
+	return 0;
 }
 
 static int host_request_owned_transition(u64 *completer_addr,
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index cbdd18cd3f98..7e04d1c2a03d 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -180,7 +180,6 @@ static void hpool_put_page(void *addr)
 static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
 				     enum kvm_pgtable_walk_flags visit)
 {
-	enum kvm_pgtable_prot prot;
 	enum pkvm_page_state state;
 	phys_addr_t phys;
 
@@ -203,16 +202,16 @@ static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,
 	case PKVM_PAGE_OWNED:
 		return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP);
 	case PKVM_PAGE_SHARED_OWNED:
-		prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED);
+		hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_BORROWED;
 		break;
 	case PKVM_PAGE_SHARED_BORROWED:
-		prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
+		hyp_phys_to_page(phys)->host_state = PKVM_PAGE_SHARED_OWNED;
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	return host_stage2_idmap_locked(phys, PAGE_SIZE, prot);
+	return 0;
 }
 
 static int fix_hyp_pgtable_refcnt_walker(const struct kvm_pgtable_visit_ctx *ctx,
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:46 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:46 +0000
Subject: [PATCH v4 05/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_mkyoung
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-6-qperret@google.com>

kvm_pgtable_stage2_mkyoung currently assumes that it is being called
from a 'shared' walker, which will not be true once called from pKVM.
To allow for the re-use of that function, make the walk flags one of
its parameters.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 4 +++-
 arch/arm64/kvm/hyp/pgtable.c         | 7 +++----
 arch/arm64/kvm/mmu.c                 | 3 ++-
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index aab04097b505..38b7ec1c8614 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -669,13 +669,15 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
  * kvm_pgtable_stage2_mkyoung() - Set the access flag in a page-table entry.
  * @pgt:	Page-table structure initialised by kvm_pgtable_stage2_init*().
  * @addr:	Intermediate physical address to identify the page-table entry.
+ * @flags:	Flags to control the page-table walk (ex. a shared walk)
  *
  * The offset of @addr within a page is ignored.
  *
  * If there is a valid, leaf page-table entry used to translate @addr, then
  * set the access flag in that entry.
  */
-void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr);
+void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
+				enum kvm_pgtable_walk_flags flags);
 
 /**
  * kvm_pgtable_stage2_test_clear_young() - Test and optionally clear the access
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 40bd55966540..0470aedb4bf4 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -1245,14 +1245,13 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
 					NULL, NULL, 0);
 }
 
-void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr)
+void kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
+				enum kvm_pgtable_walk_flags flags)
 {
 	int ret;
 
 	ret = stage2_update_leaf_attrs(pgt, addr, 1, KVM_PTE_LEAF_ATTR_LO_S2_AF, 0,
-				       NULL, NULL,
-				       KVM_PGTABLE_WALK_HANDLE_FAULT |
-				       KVM_PGTABLE_WALK_SHARED);
+				       NULL, NULL, flags);
 	if (!ret)
 		dsb(ishst);
 }
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index c9d46ad57e52..a2339b76c826 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1718,13 +1718,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 /* Resolve the access fault by making the page young again. */
 static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 {
+	enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED;
 	struct kvm_s2_mmu *mmu;
 
 	trace_kvm_access_fault(fault_ipa);
 
 	read_lock(&vcpu->kvm->mmu_lock);
 	mmu = vcpu->arch.hw_mmu;
-	kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa);
+	kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa, flags);
 	read_unlock(&vcpu->kvm->mmu_lock);
 }
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:47 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:47 +0000
Subject: [PATCH v4 06/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_relax_perms
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-7-qperret@google.com>

kvm_pgtable_stage2_relax_perms currently assumes that it is being called
from a 'shared' walker, which will not be true once called from pKVM. To
allow for the re-use of that function, make the walk flags one of its
parameters.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 4 +++-
 arch/arm64/kvm/hyp/pgtable.c         | 6 ++----
 arch/arm64/kvm/mmu.c                 | 7 +++----
 3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 38b7ec1c8614..c2f4149283ef 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -707,6 +707,7 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
  * @pgt:	Page-table structure initialised by kvm_pgtable_stage2_init*().
  * @addr:	Intermediate physical address to identify the page-table entry.
  * @prot:	Additional permissions to grant for the mapping.
+ * @flags:	Flags to control the page-table walk (ex. a shared walk)
  *
  * The offset of @addr within a page is ignored.
  *
@@ -719,7 +720,8 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
  * Return: 0 on success, negative error code on failure.
  */
 int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
-				   enum kvm_pgtable_prot prot);
+				   enum kvm_pgtable_prot prot,
+				   enum kvm_pgtable_walk_flags flags);
 
 /**
  * kvm_pgtable_stage2_flush_range() - Clean and invalidate data cache to Point
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 0470aedb4bf4..b7a3b5363235 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -1307,7 +1307,7 @@ bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
 }
 
 int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
-				   enum kvm_pgtable_prot prot)
+				   enum kvm_pgtable_prot prot, enum kvm_pgtable_walk_flags flags)
 {
 	int ret;
 	s8 level;
@@ -1325,9 +1325,7 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
 	if (prot & KVM_PGTABLE_PROT_X)
 		clr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
 
-	ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level,
-				       KVM_PGTABLE_WALK_HANDLE_FAULT |
-				       KVM_PGTABLE_WALK_SHARED);
+	ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level, flags);
 	if (!ret || ret == -EAGAIN)
 		kvm_call_hyp(__kvm_tlb_flush_vmid_ipa_nsh, pgt->mmu, addr, level);
 	return ret;
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index a2339b76c826..641e4fec1659 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1452,6 +1452,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
 	struct kvm_pgtable *pgt;
 	struct page *page;
+	enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED;
 
 	if (fault_is_perm)
 		fault_granule = kvm_vcpu_trap_get_perm_fault_granule(vcpu);
@@ -1695,13 +1696,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		 * PTE, which will be preserved.
 		 */
 		prot &= ~KVM_NV_GUEST_MAP_SZ;
-		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot);
+		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot, flags);
 	} else {
 		ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
 					     __pfn_to_phys(pfn), prot,
-					     memcache,
-					     KVM_PGTABLE_WALK_HANDLE_FAULT |
-					     KVM_PGTABLE_WALK_SHARED);
+					     memcache, flags);
 	}
 
 out_unlock:
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:48 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:48 +0000
Subject: [PATCH v4 07/18] KVM: arm64: Make kvm_pgtable_stage2_init() a static
 inline function
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-8-qperret@google.com>

Turn kvm_pgtable_stage2_init() into a static inline function instead of
a macro. This will allow the usage of typeof() on it later on.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index c2f4149283ef..04418b5e3004 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -526,8 +526,11 @@ int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
 			      enum kvm_pgtable_stage2_flags flags,
 			      kvm_pgtable_force_pte_cb_t force_pte_cb);
 
-#define kvm_pgtable_stage2_init(pgt, mmu, mm_ops) \
-	__kvm_pgtable_stage2_init(pgt, mmu, mm_ops, 0, NULL)
+static inline int kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
+					  struct kvm_pgtable_mm_ops *mm_ops)
+{
+	return __kvm_pgtable_stage2_init(pgt, mmu, mm_ops, 0, NULL);
+}
 
 /**
  * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:49 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:49 +0000
Subject: [PATCH v4 08/18] KVM: arm64: Add {get,put}_pkvm_hyp_vm() helpers
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-9-qperret@google.com>

In preparation for accessing pkvm_hyp_vm structures at EL2 in a context
where we can't always expect a vCPU to be loaded (e.g. MMU notifiers),
introduce get/put helpers to get temporary references to hyp VMs from
any context.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  3 +++
 arch/arm64/kvm/hyp/nvhe/pkvm.c         | 20 ++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 24a9a8330d19..f361d8b91930 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -70,4 +70,7 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 					 unsigned int vcpu_idx);
 void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
 
+struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
+void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
+
 #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 071993c16de8..d46a02e24e4a 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -327,6 +327,26 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 	hyp_spin_unlock(&vm_table_lock);
 }
 
+struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
+{
+	struct pkvm_hyp_vm *hyp_vm;
+
+	hyp_spin_lock(&vm_table_lock);
+	hyp_vm = get_vm_by_handle(handle);
+	if (hyp_vm)
+		hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
+	hyp_spin_unlock(&vm_table_lock);
+
+	return hyp_vm;
+}
+
+void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm)
+{
+	hyp_spin_lock(&vm_table_lock);
+	hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
+	hyp_spin_unlock(&vm_table_lock);
+}
+
 static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
 {
 	struct kvm *kvm = &hyp_vm->kvm;
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:50 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:50 +0000
Subject: [PATCH v4 09/18] KVM: arm64: Introduce __pkvm_vcpu_{load,put}()
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-10-qperret@google.com>

From: Marc Zyngier <maz at kernel.org>

Rather than look-up the hyp vCPU on every run hypercall at EL2,
introduce a per-CPU 'loaded_hyp_vcpu' tracking variable which is updated
by a pair of load/put hypercalls called directly from
kvm_arch_vcpu_{load,put}() when pKVM is enabled.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h       |  2 ++
 arch/arm64/kvm/arm.c                   | 14 ++++++++
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  7 ++++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c     | 47 ++++++++++++++++++++------
 arch/arm64/kvm/hyp/nvhe/pkvm.c         | 29 ++++++++++++++++
 arch/arm64/kvm/vgic/vgic-v3.c          |  6 ++--
 6 files changed, 93 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index ca2590344313..89c0fac69551 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -79,6 +79,8 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
 	__KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu,
 	__KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
+	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
+	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
 };
 
 #define DECLARE_KVM_VHE_SYM(sym)	extern char sym[]
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a102c3aebdbc..55cc62b2f469 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -619,12 +619,26 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 	kvm_arch_vcpu_load_debug_state_flags(vcpu);
 
+	if (is_protected_kvm_enabled()) {
+		kvm_call_hyp_nvhe(__pkvm_vcpu_load,
+				  vcpu->kvm->arch.pkvm.handle,
+				  vcpu->vcpu_idx, vcpu->arch.hcr_el2);
+		kvm_call_hyp(__vgic_v3_restore_vmcr_aprs,
+			     &vcpu->arch.vgic_cpu.vgic_v3);
+	}
+
 	if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus))
 		vcpu_set_on_unsupported_cpu(vcpu);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+	if (is_protected_kvm_enabled()) {
+		kvm_call_hyp(__vgic_v3_save_vmcr_aprs,
+			     &vcpu->arch.vgic_cpu.vgic_v3);
+		kvm_call_hyp_nvhe(__pkvm_vcpu_put);
+	}
+
 	kvm_arch_vcpu_put_debug_state_flags(vcpu);
 	kvm_arch_vcpu_put_fp(vcpu);
 	if (has_vhe())
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index f361d8b91930..be52c5b15e21 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -20,6 +20,12 @@ struct pkvm_hyp_vcpu {
 
 	/* Backpointer to the host's (untrusted) vCPU instance. */
 	struct kvm_vcpu *host_vcpu;
+
+	/*
+	 * If this hyp vCPU is loaded, then this is a backpointer to the
+	 * per-cpu pointer tracking us. Otherwise, NULL if not loaded.
+	 */
+	struct pkvm_hyp_vcpu **loaded_hyp_vcpu;
 };
 
 /*
@@ -69,6 +75,7 @@ int __pkvm_teardown_vm(pkvm_handle_t handle);
 struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 					 unsigned int vcpu_idx);
 void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
+struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void);
 
 struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
 void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 6aa0b13d86e5..95d78db315b3 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -141,16 +141,46 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 		host_cpu_if->vgic_lr[i] = hyp_cpu_if->vgic_lr[i];
 }
 
+static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(unsigned int, vcpu_idx, host_ctxt, 2);
+	DECLARE_REG(u64, hcr_el2, host_ctxt, 3);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+
+	if (!is_protected_kvm_enabled())
+		return;
+
+	hyp_vcpu = pkvm_load_hyp_vcpu(handle, vcpu_idx);
+	if (!hyp_vcpu)
+		return;
+
+	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
+		/* Propagate WFx trapping flags */
+		hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWE | HCR_TWI);
+		hyp_vcpu->vcpu.arch.hcr_el2 |= hcr_el2 & (HCR_TWE | HCR_TWI);
+	}
+}
+
+static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt)
+{
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+
+	if (!is_protected_kvm_enabled())
+		return;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (hyp_vcpu)
+		pkvm_put_hyp_vcpu(hyp_vcpu);
+}
+
 static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, host_vcpu, host_ctxt, 1);
 	int ret;
 
-	host_vcpu = kern_hyp_va(host_vcpu);
-
 	if (unlikely(is_protected_kvm_enabled())) {
-		struct pkvm_hyp_vcpu *hyp_vcpu;
-		struct kvm *host_kvm;
+		struct pkvm_hyp_vcpu *hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
 
 		/*
 		 * KVM (and pKVM) doesn't support SME guests for now, and
@@ -163,9 +193,6 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 			goto out;
 		}
 
-		host_kvm = kern_hyp_va(host_vcpu->kvm);
-		hyp_vcpu = pkvm_load_hyp_vcpu(host_kvm->arch.pkvm.handle,
-					      host_vcpu->vcpu_idx);
 		if (!hyp_vcpu) {
 			ret = -EINVAL;
 			goto out;
@@ -176,12 +203,10 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 		ret = __kvm_vcpu_run(&hyp_vcpu->vcpu);
 
 		sync_hyp_vcpu(hyp_vcpu);
-		pkvm_put_hyp_vcpu(hyp_vcpu);
 	} else {
 		/* The host is fully trusted, run its vCPU directly. */
-		ret = __kvm_vcpu_run(host_vcpu);
+		ret = __kvm_vcpu_run(kern_hyp_va(host_vcpu));
 	}
-
 out:
 	cpu_reg(host_ctxt, 1) =  ret;
 }
@@ -409,6 +434,8 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_init_vm),
 	HANDLE_FUNC(__pkvm_init_vcpu),
 	HANDLE_FUNC(__pkvm_teardown_vm),
+	HANDLE_FUNC(__pkvm_vcpu_load),
+	HANDLE_FUNC(__pkvm_vcpu_put),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index d46a02e24e4a..496d186efb03 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -23,6 +23,12 @@ unsigned int kvm_arm_vmid_bits;
 
 unsigned int kvm_host_sve_max_vl;
 
+/*
+ * The currently loaded hyp vCPU for each physical CPU. Used only when
+ * protected KVM is enabled, but for both protected and non-protected VMs.
+ */
+static DEFINE_PER_CPU(struct pkvm_hyp_vcpu *, loaded_hyp_vcpu);
+
 /*
  * Set trap register values based on features in ID_AA64PFR0.
  */
@@ -306,15 +312,30 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
 	struct pkvm_hyp_vcpu *hyp_vcpu = NULL;
 	struct pkvm_hyp_vm *hyp_vm;
 
+	/* Cannot load a new vcpu without putting the old one first. */
+	if (__this_cpu_read(loaded_hyp_vcpu))
+		return NULL;
+
 	hyp_spin_lock(&vm_table_lock);
 	hyp_vm = get_vm_by_handle(handle);
 	if (!hyp_vm || hyp_vm->nr_vcpus <= vcpu_idx)
 		goto unlock;
 
 	hyp_vcpu = hyp_vm->vcpus[vcpu_idx];
+
+	/* Ensure vcpu isn't loaded on more than one cpu simultaneously. */
+	if (unlikely(hyp_vcpu->loaded_hyp_vcpu)) {
+		hyp_vcpu = NULL;
+		goto unlock;
+	}
+
+	hyp_vcpu->loaded_hyp_vcpu = this_cpu_ptr(&loaded_hyp_vcpu);
 	hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
 unlock:
 	hyp_spin_unlock(&vm_table_lock);
+
+	if (hyp_vcpu)
+		__this_cpu_write(loaded_hyp_vcpu, hyp_vcpu);
 	return hyp_vcpu;
 }
 
@@ -323,10 +344,18 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 	struct pkvm_hyp_vm *hyp_vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu);
 
 	hyp_spin_lock(&vm_table_lock);
+	hyp_vcpu->loaded_hyp_vcpu = NULL;
+	__this_cpu_write(loaded_hyp_vcpu, NULL);
 	hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
 	hyp_spin_unlock(&vm_table_lock);
 }
 
+struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void)
+{
+	return __this_cpu_read(loaded_hyp_vcpu);
+
+}
+
 struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
 {
 	struct pkvm_hyp_vm *hyp_vm;
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index f267bc2486a1..c2ef41fff079 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -734,7 +734,8 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
-	kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
+	if (likely(!is_protected_kvm_enabled()))
+		kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
 
 	if (has_vhe())
 		__vgic_v3_activate_traps(cpu_if);
@@ -746,7 +747,8 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
-	kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
+	if (likely(!is_protected_kvm_enabled()))
+		kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
 	WARN_ON(vgic_v4_put(vcpu));
 
 	if (has_vhe())
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:51 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:51 +0000
Subject: [PATCH v4 10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-11-qperret@google.com>

In preparation for handling guest stage-2 mappings at EL2, introduce a
new pKVM hypercall allowing to share pages with non-protected guests.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/include/asm/kvm_host.h             |  3 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 +
 arch/arm64/kvm/hyp/include/nvhe/memory.h      |  4 +-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 34 +++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 72 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  8 +++
 7 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 89c0fac69551..449337f5b2a3 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -65,6 +65,7 @@ enum __kvm_host_smccc_func {
 	/* Hypercalls available after pKVM finalisation */
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e18e9244d17a..1246f1d01dbf 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -771,6 +771,9 @@ struct kvm_vcpu_arch {
 	/* Cache some mmu pages needed inside spinlock regions */
 	struct kvm_mmu_memory_cache mmu_page_cache;
 
+	/* Pages to top-up the pKVM/EL2 guest pool */
+	struct kvm_hyp_memcache pkvm_memcache;
+
 	/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
 	u64 vsesr_el2;
 
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 25038ac705d8..15b8956051b6 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -39,6 +39,8 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages);
 int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
+int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
+			    enum kvm_pgtable_prot prot);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index 2a5eabf4b753..34233d586060 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -46,6 +46,8 @@ struct hyp_page {
 
 	/* Host (non-meta) state. Guarded by the host stage-2 lock. */
 	enum pkvm_page_state host_state : 8;
+
+	u32 host_share_guest_count;
 };
 
 extern u64 __hyp_vmemmap;
@@ -68,7 +70,7 @@ static inline phys_addr_t hyp_virt_to_phys(void *addr)
 
 static inline struct hyp_page *hyp_phys_to_page(phys_addr_t phys)
 {
-	BUILD_BUG_ON(sizeof(struct hyp_page) != sizeof(u32));
+	BUILD_BUG_ON(sizeof(struct hyp_page) != sizeof(u64));
 	return &hyp_vmemmap[hyp_phys_to_pfn(phys)];
 }
 
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 95d78db315b3..d659462fbf5d 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -211,6 +211,39 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+static int pkvm_refill_memcache(struct pkvm_hyp_vcpu *hyp_vcpu)
+{
+	struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
+
+	return refill_memcache(&hyp_vcpu->vcpu.arch.pkvm_memcache,
+			       host_vcpu->arch.pkvm_memcache.nr_pages,
+			       &host_vcpu->arch.pkvm_memcache);
+}
+
+static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, pfn, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 3);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		goto out;
+
+	ret = pkvm_refill_memcache(hyp_vcpu);
+	if (ret)
+		goto out;
+
+	ret = __pkvm_host_share_guest(pfn, gfn, hyp_vcpu, prot);
+out:
+	cpu_reg(host_ctxt, 1) =  ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -420,6 +453,7 @@ static const hcall_t host_hcall[] = {
 
 	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
+	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 12bb5445fe47..fb9592e721cf 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -867,6 +867,27 @@ static int hyp_complete_donation(u64 addr,
 	return pkvm_create_mappings_locked(start, end, prot);
 }
 
+static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr)
+{
+	if (!kvm_pte_valid(pte))
+		return PKVM_NOPAGE;
+
+	return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
+}
+
+static int __guest_check_page_state_range(struct pkvm_hyp_vcpu *vcpu, u64 addr,
+					  u64 size, enum pkvm_page_state state)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	struct check_walk_data d = {
+		.desired	= state,
+		.get_page_state	= guest_get_page_state,
+	};
+
+	hyp_assert_lock_held(&vm->lock);
+	return check_page_state_range(&vm->pgt, addr, size, &d);
+}
+
 static int check_share(struct pkvm_mem_share *share)
 {
 	const struct pkvm_mem_transition *tx = &share->tx;
@@ -1349,3 +1370,54 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages)
 
 	return ret;
 }
+
+int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
+			    enum kvm_pgtable_prot prot)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	u64 phys = hyp_pfn_to_phys(pfn);
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	struct hyp_page *page;
+	int ret;
+
+	if (prot & ~KVM_PGTABLE_PROT_RWX)
+		return -EINVAL;
+
+	ret = check_range_allowed_memory(phys, phys + PAGE_SIZE);
+	if (ret)
+		return ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __guest_check_page_state_range(vcpu, ipa, PAGE_SIZE, PKVM_NOPAGE);
+	if (ret)
+		goto unlock;
+
+	page = hyp_phys_to_page(phys);
+	switch (page->host_state) {
+	case PKVM_PAGE_OWNED:
+		WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_OWNED));
+		break;
+	case PKVM_PAGE_SHARED_OWNED:
+		if (page->host_share_guest_count)
+			break;
+		/* Only host to np-guest multi-sharing is tolerated */
+		WARN_ON(1);
+		fallthrough;
+	default:
+		ret = -EPERM;
+		goto unlock;
+	}
+
+	WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys,
+				       pkvm_mkstate(prot, PKVM_PAGE_SHARED_BORROWED),
+				       &vcpu->vcpu.arch.pkvm_memcache, 0));
+	page->host_share_guest_count++;
+
+unlock:
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 496d186efb03..0109c36566c8 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -795,6 +795,14 @@ int __pkvm_teardown_vm(pkvm_handle_t handle)
 	/* Push the metadata pages to the teardown memcache */
 	for (idx = 0; idx < hyp_vm->nr_vcpus; ++idx) {
 		struct pkvm_hyp_vcpu *hyp_vcpu = hyp_vm->vcpus[idx];
+		struct kvm_hyp_memcache *vcpu_mc = &hyp_vcpu->vcpu.arch.pkvm_memcache;
+
+		while (vcpu_mc->nr_pages) {
+			void *addr = pop_hyp_memcache(vcpu_mc, hyp_phys_to_virt);
+
+			push_hyp_memcache(mc, addr, hyp_virt_to_phys);
+			unmap_donated_memory_noclear(addr, PAGE_SIZE);
+		}
 
 		teardown_donated_memory(mc, hyp_vcpu, sizeof(*hyp_vcpu));
 	}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:52 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:52 +0000
Subject: [PATCH v4 11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-12-qperret@google.com>

In preparation for letting the host unmap pages from non-protected
guests, introduce a new hypercall implementing the host-unshare-guest
transition.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  6 ++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 21 ++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 67 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/pkvm.c                | 12 ++++
 6 files changed, 108 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 449337f5b2a3..0b6c4d325134 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -66,6 +66,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 15b8956051b6..e6d080b71779 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -41,6 +41,7 @@ int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
 			    enum kvm_pgtable_prot prot);
+int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index be52c5b15e21..0cc2a429f1fb 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -64,6 +64,11 @@ static inline bool pkvm_hyp_vcpu_is_protected(struct pkvm_hyp_vcpu *hyp_vcpu)
 	return vcpu_is_protected(&hyp_vcpu->vcpu);
 }
 
+static inline bool pkvm_hyp_vm_is_protected(struct pkvm_hyp_vm *hyp_vm)
+{
+	return kvm_vm_is_protected(&hyp_vm->kvm);
+}
+
 void pkvm_hyp_vm_table_init(void *tbl);
 
 int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
@@ -78,6 +83,7 @@ void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu);
 struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void);
 
 struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle);
+struct pkvm_hyp_vm *get_np_pkvm_hyp_vm(pkvm_handle_t handle);
 void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm);
 
 #endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index d659462fbf5d..3c3a27c985a2 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -244,6 +244,26 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	struct pkvm_hyp_vm *hyp_vm;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vm = get_np_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		goto out;
+
+	ret = __pkvm_host_unshare_guest(gfn, hyp_vm);
+	put_pkvm_hyp_vm(hyp_vm);
+out:
+	cpu_reg(host_ctxt, 1) =  ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -454,6 +474,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
 	HANDLE_FUNC(__pkvm_host_share_guest),
+	HANDLE_FUNC(__pkvm_host_unshare_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index fb9592e721cf..30243b7922f1 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1421,3 +1421,70 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
 
 	return ret;
 }
+
+static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa)
+{
+	enum pkvm_page_state state;
+	struct hyp_page *page;
+	kvm_pte_t pte;
+	u64 phys;
+	s8 level;
+	int ret;
+
+	ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level);
+	if (ret)
+		return ret;
+	if (level != KVM_PGTABLE_LAST_LEVEL)
+		return -E2BIG;
+	if (!kvm_pte_valid(pte))
+		return -ENOENT;
+
+	state = guest_get_page_state(pte, ipa);
+	if (state != PKVM_PAGE_SHARED_BORROWED)
+		return -EPERM;
+
+	phys = kvm_pte_to_phys(pte);
+	ret = check_range_allowed_memory(phys, phys + PAGE_SIZE);
+	if (WARN_ON(ret))
+		return ret;
+
+	page = hyp_phys_to_page(phys);
+	if (page->host_state != PKVM_PAGE_SHARED_OWNED)
+		return -EPERM;
+	if (WARN_ON(!page->host_share_guest_count))
+		return -EINVAL;
+
+	*__phys = phys;
+
+	return 0;
+}
+
+int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *vm)
+{
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	struct hyp_page *page;
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (ret)
+		goto unlock;
+
+	ret = kvm_pgtable_stage2_unmap(&vm->pgt, ipa, PAGE_SIZE);
+	if (ret)
+		goto unlock;
+
+	page = hyp_phys_to_page(phys);
+	page->host_share_guest_count--;
+	if (!page->host_share_guest_count)
+		WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_OWNED));
+
+unlock:
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 0109c36566c8..2c618f2f2769 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -376,6 +376,18 @@ void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm)
 	hyp_spin_unlock(&vm_table_lock);
 }
 
+struct pkvm_hyp_vm *get_np_pkvm_hyp_vm(pkvm_handle_t handle)
+{
+	struct pkvm_hyp_vm *hyp_vm = get_pkvm_hyp_vm(handle);
+
+	if (hyp_vm && pkvm_hyp_vm_is_protected(hyp_vm)) {
+		put_pkvm_hyp_vm(hyp_vm);
+		hyp_vm = NULL;
+	}
+
+	return hyp_vm;
+}
+
 static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
 {
 	struct kvm *kvm = &hyp_vm->kvm;
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:53 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:53 +0000
Subject: [PATCH v4 12/18] KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-13-qperret@google.com>

Introduce a new hypercall allowing the host to relax the stage-2
permissions of mappings in a non-protected guest page-table. It will be
used later once we start allowing RO memslots and dirty logging.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 20 ++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 23 +++++++++++++++++++
 4 files changed, 45 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 0b6c4d325134..66ee8542dcc9 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -67,6 +67,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index e6d080b71779..181aec2d5bc1 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -42,6 +42,7 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
 int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
 			    enum kvm_pgtable_prot prot);
 int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
+int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 3c3a27c985a2..287e4ee93ef2 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -264,6 +264,25 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, gfn, host_ctxt, 1);
+	DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 2);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		goto out;
+
+	ret = __pkvm_host_relax_perms_guest(gfn, hyp_vcpu, prot);
+out:
+	cpu_reg(host_ctxt, 1) = ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -475,6 +494,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
 	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
+	HANDLE_FUNC(__pkvm_host_relax_perms_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 30243b7922f1..aa8e0408aebb 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1488,3 +1488,26 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *vm)
 
 	return ret;
 }
+
+int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	if (prot & ~KVM_PGTABLE_PROT_RWX)
+		return -EINVAL;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (!ret)
+		ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:54 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:54 +0000
Subject: [PATCH v4 13/18] KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-14-qperret@google.com>

Introduce a new hypercall to remove the write permission from a
non-protected guest stage-2 mapping. This will be used for e.g. enabling
dirty logging.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 21 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 +++++++++++++++++
 4 files changed, 42 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 66ee8542dcc9..8663a588cf34 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -68,6 +68,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 181aec2d5bc1..0bbfb0e1734c 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -43,6 +43,7 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
 			    enum kvm_pgtable_prot prot);
 int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
+int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 287e4ee93ef2..98d317735107 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -283,6 +283,26 @@ static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *host_ct
 	cpu_reg(host_ctxt, 1) = ret;
 }
 
+static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	struct pkvm_hyp_vm *hyp_vm;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vm = get_np_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		goto out;
+
+	ret = __pkvm_host_wrprotect_guest(gfn, hyp_vm);
+	put_pkvm_hyp_vm(hyp_vm);
+out:
+	cpu_reg(host_ctxt, 1) = ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -495,6 +515,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
 	HANDLE_FUNC(__pkvm_host_relax_perms_guest),
+	HANDLE_FUNC(__pkvm_host_wrprotect_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index aa8e0408aebb..94e4251b5077 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1511,3 +1511,22 @@ int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_
 
 	return ret;
 }
+
+int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
+{
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (!ret)
+		ret = kvm_pgtable_stage2_wrprotect(&vm->pgt, ipa, PAGE_SIZE);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:55 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:55 +0000
Subject: [PATCH v4 14/18] KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-15-qperret@google.com>

Plumb the kvm_stage2_test_clear_young() callback into pKVM for
non-protected guest. It will be later be called from MMU notifiers.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 22 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 ++++++++++++++++
 4 files changed, 43 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 8663a588cf34..4f97155d6323 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -69,6 +69,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 0bbfb0e1734c..74bd6c72fff2 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -44,6 +44,7 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
 int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
+int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 98d317735107..616e172a9c48 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -303,6 +303,27 @@ static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt
 	cpu_reg(host_ctxt, 1) = ret;
 }
 
+static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	DECLARE_REG(u64, gfn, host_ctxt, 2);
+	DECLARE_REG(bool, mkold, host_ctxt, 3);
+	struct pkvm_hyp_vm *hyp_vm;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vm = get_np_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		goto out;
+
+	ret = __pkvm_host_test_clear_young_guest(gfn, mkold, hyp_vm);
+	put_pkvm_hyp_vm(hyp_vm);
+out:
+	cpu_reg(host_ctxt, 1) = ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -516,6 +537,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
 	HANDLE_FUNC(__pkvm_host_relax_perms_guest),
 	HANDLE_FUNC(__pkvm_host_wrprotect_guest),
+	HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 94e4251b5077..0e42c3baaf4b 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1530,3 +1530,22 @@ int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
 
 	return ret;
 }
+
+int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm)
+{
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (!ret)
+		ret = kvm_pgtable_stage2_test_clear_young(&vm->pgt, ipa, PAGE_SIZE, mkold);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:56 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:56 +0000
Subject: [PATCH v4 15/18] KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-16-qperret@google.com>

Plumb the kvm_pgtable_stage2_mkyoung() callback into pKVM for
non-protected guests. It will be called later from the fault handling
path.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  1 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 19 ++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 20 +++++++++++++++++++
 4 files changed, 41 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 4f97155d6323..a3b07db2776c 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -70,6 +70,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_mkyoung_guest,
 	__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
 	__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
 	__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 74bd6c72fff2..978f38c386ee 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -45,6 +45,7 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
 int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
 int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *vm);
+int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 616e172a9c48..32c4627b5b5b 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -324,6 +324,24 @@ static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *ho
 	cpu_reg(host_ctxt, 1) = ret;
 }
 
+static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(u64, gfn, host_ctxt, 1);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int ret = -EINVAL;
+
+	if (!is_protected_kvm_enabled())
+		goto out;
+
+	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+	if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
+		goto out;
+
+	ret = __pkvm_host_mkyoung_guest(gfn, hyp_vcpu);
+out:
+	cpu_reg(host_ctxt, 1) =  ret;
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -538,6 +556,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_relax_perms_guest),
 	HANDLE_FUNC(__pkvm_host_wrprotect_guest),
 	HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
+	HANDLE_FUNC(__pkvm_host_mkyoung_guest),
 	HANDLE_FUNC(__kvm_adjust_pc),
 	HANDLE_FUNC(__kvm_vcpu_run),
 	HANDLE_FUNC(__kvm_flush_vm_context),
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 0e42c3baaf4b..eae03509d371 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -1549,3 +1549,23 @@ int __pkvm_host_test_clear_young_guest(u64 gfn, bool mkold, struct pkvm_hyp_vm *
 
 	return ret;
 }
+
+int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu)
+{
+	struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
+	u64 ipa = hyp_pfn_to_phys(gfn);
+	u64 phys;
+	int ret;
+
+	host_lock_component();
+	guest_lock_component(vm);
+
+	ret = __check_host_shared_guest(vm, &phys, ipa);
+	if (!ret)
+		kvm_pgtable_stage2_mkyoung(&vm->pgt, ipa, 0);
+
+	guest_unlock_component(vm);
+	host_unlock_component();
+
+	return ret;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:57 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:57 +0000
Subject: [PATCH v4 16/18] KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-17-qperret@google.com>

Introduce a new hypercall to flush the TLBs of non-protected guests. The
host kernel will be responsible for issuing this hypercall after changing
stage-2 permissions using the __pkvm_host_relax_guest_perms() or
__pkvm_host_wrprotect_guest() paths. This is left under the host's
responsibility for performance reasons.

Note however that the TLB maintenance for all *unmap* operations still
remains entirely under the hypervisor's responsibility for security
reasons -- an unmapped page may be donated to another entity, so a stale
TLB entry could be used to leak private data.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h   |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index a3b07db2776c..002088c6e297 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -87,6 +87,7 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,
 	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
 	__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
+	__KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
 };
 
 #define DECLARE_KVM_VHE_SYM(sym)	extern char sym[]
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 32c4627b5b5b..130f5f23bcb5 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -389,6 +389,22 @@ static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
 	__kvm_tlb_flush_vmid(kern_hyp_va(mmu));
 }
 
+static void handle___pkvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
+	struct pkvm_hyp_vm *hyp_vm;
+
+	if (!is_protected_kvm_enabled())
+		return;
+
+	hyp_vm = get_np_pkvm_hyp_vm(handle);
+	if (!hyp_vm)
+		return;
+
+	__kvm_tlb_flush_vmid(&hyp_vm->kvm.arch.mmu);
+	put_pkvm_hyp_vm(hyp_vm);
+}
+
 static void handle___kvm_flush_cpu_context(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1);
@@ -573,6 +589,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_teardown_vm),
 	HANDLE_FUNC(__pkvm_vcpu_load),
 	HANDLE_FUNC(__pkvm_vcpu_put),
+	HANDLE_FUNC(__pkvm_tlb_flush_vmid),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:58 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:58 +0000
Subject: [PATCH v4 17/18] KVM: arm64: Introduce the EL1 pKVM MMU
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-18-qperret@google.com>

Introduce a set of helper functions allowing to manipulate the pKVM
guest stage-2 page-tables from EL1 using pKVM's HVC interface.

Each helper has an exact one-to-one correspondance with the traditional
kvm_pgtable_stage2_*() functions from pgtable.c, with a strictly
matching prototype. This will ease plumbing later on in mmu.c.

These callbacks track the gfn->pfn mappings in a simple rb_tree indexed
by IPA in lieu of a page-table. This rb-tree is kept in sync with pKVM's
state and is protected by the mmu_lock like a traditional stage-2
page-table.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_host.h    |   1 +
 arch/arm64/include/asm/kvm_pgtable.h |  23 +--
 arch/arm64/include/asm/kvm_pkvm.h    |  26 ++++
 arch/arm64/kvm/pkvm.c                | 201 +++++++++++++++++++++++++++
 4 files changed, 242 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 1246f1d01dbf..f23f4ea9ec8b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -85,6 +85,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
 struct kvm_hyp_memcache {
 	phys_addr_t head;
 	unsigned long nr_pages;
+	struct pkvm_mapping *mapping; /* only used from EL1 */
 };
 
 static inline void push_hyp_memcache(struct kvm_hyp_memcache *mc,
diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 04418b5e3004..6b9d274052c7 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -412,15 +412,20 @@ static inline bool kvm_pgtable_walk_lock_held(void)
  *			be used instead of block mappings.
  */
 struct kvm_pgtable {
-	u32					ia_bits;
-	s8					start_level;
-	kvm_pteref_t				pgd;
-	struct kvm_pgtable_mm_ops		*mm_ops;
-
-	/* Stage-2 only */
-	struct kvm_s2_mmu			*mmu;
-	enum kvm_pgtable_stage2_flags		flags;
-	kvm_pgtable_force_pte_cb_t		force_pte_cb;
+	union {
+		struct rb_root					pkvm_mappings;
+		struct {
+			u32					ia_bits;
+			s8					start_level;
+			kvm_pteref_t				pgd;
+			struct kvm_pgtable_mm_ops		*mm_ops;
+
+			/* Stage-2 only */
+			enum kvm_pgtable_stage2_flags		flags;
+			kvm_pgtable_force_pte_cb_t		force_pte_cb;
+		};
+	};
+	struct kvm_s2_mmu					*mmu;
 };
 
 /**
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index cd56acd9a842..65f988b6fe0d 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -137,4 +137,30 @@ static inline size_t pkvm_host_sve_state_size(void)
 			SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_sve_max_vl)));
 }
 
+struct pkvm_mapping {
+	struct rb_node node;
+	u64 gfn;
+	u64 pfn;
+};
+
+int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
+			     struct kvm_pgtable_mm_ops *mm_ops);
+void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
+int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
+			    enum kvm_pgtable_prot prot, void *mc,
+			    enum kvm_pgtable_walk_flags flags);
+int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
+int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
+int pkvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
+bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold);
+int pkvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
+				    enum kvm_pgtable_walk_flags flags);
+void pkvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
+				 enum kvm_pgtable_walk_flags flags);
+int pkvm_pgtable_stage2_split(struct kvm_pgtable *pgt, u64 addr, u64 size,
+			      struct kvm_mmu_memory_cache *mc);
+void pkvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level);
+kvm_pte_t *pkvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
+					       enum kvm_pgtable_prot prot, void *mc,
+					       bool force_pte);
 #endif	/* __ARM64_KVM_PKVM_H__ */
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index 85117ea8f351..930b677eb9b0 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/kmemleak.h>
 #include <linux/kvm_host.h>
+#include <asm/kvm_mmu.h>
 #include <linux/memblock.h>
 #include <linux/mutex.h>
 #include <linux/sort.h>
@@ -268,3 +269,203 @@ static int __init finalize_pkvm(void)
 	return ret;
 }
 device_initcall_sync(finalize_pkvm);
+
+static int cmp_mappings(struct rb_node *node, const struct rb_node *parent)
+{
+	struct pkvm_mapping *a = rb_entry(node, struct pkvm_mapping, node);
+	struct pkvm_mapping *b = rb_entry(parent, struct pkvm_mapping, node);
+
+	if (a->gfn < b->gfn)
+		return -1;
+	if (a->gfn > b->gfn)
+		return 1;
+	return 0;
+}
+
+static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
+{
+	struct rb_node *node = root->rb_node, *prev = NULL;
+	struct pkvm_mapping *mapping;
+
+	while (node) {
+		mapping = rb_entry(node, struct pkvm_mapping, node);
+		if (mapping->gfn == gfn)
+			return node;
+		prev = node;
+		node = (gfn < mapping->gfn) ? node->rb_left : node->rb_right;
+	}
+
+	return prev;
+}
+
+/*
+ * __tmp is updated to rb_next(__tmp) *before* entering the body of the loop to allow freeing
+ * of __map inline.
+ */
+#define for_each_mapping_in_range_safe(__pgt, __start, __end, __map)				\
+	for (struct rb_node *__tmp = find_first_mapping_node(&(__pgt)->pkvm_mappings,		\
+							     ((__start) >> PAGE_SHIFT));	\
+	     __tmp && ({									\
+				__map = rb_entry(__tmp, struct pkvm_mapping, node);		\
+				__tmp = rb_next(__tmp);						\
+				true;								\
+		       });									\
+	    )											\
+		if (__map->gfn < ((__start) >> PAGE_SHIFT))					\
+			continue;								\
+		else if (__map->gfn >= ((__end) >> PAGE_SHIFT))					\
+			break;									\
+		else
+
+int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
+			     struct kvm_pgtable_mm_ops *mm_ops)
+{
+	pgt->pkvm_mappings	= RB_ROOT;
+	pgt->mmu		= mmu;
+
+	return 0;
+}
+
+void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	pkvm_handle_t handle = kvm->arch.pkvm.handle;
+	struct pkvm_mapping *mapping;
+	struct rb_node *node;
+
+	if (!handle)
+		return;
+
+	node = rb_first(&pgt->pkvm_mappings);
+	while (node) {
+		mapping = rb_entry(node, struct pkvm_mapping, node);
+		kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
+		node = rb_next(node);
+		rb_erase(&mapping->node, &pgt->pkvm_mappings);
+		kfree(mapping);
+	}
+}
+
+int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
+			   u64 phys, enum kvm_pgtable_prot prot,
+			   void *mc, enum kvm_pgtable_walk_flags flags)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	struct pkvm_mapping *mapping = NULL;
+	struct kvm_hyp_memcache *cache = mc;
+	u64 gfn = addr >> PAGE_SHIFT;
+	u64 pfn = phys >> PAGE_SHIFT;
+	int ret;
+
+	if (size != PAGE_SIZE)
+		return -EINVAL;
+
+	lockdep_assert_held_write(&kvm->mmu_lock);
+	ret = kvm_call_hyp_nvhe(__pkvm_host_share_guest, pfn, gfn, prot);
+	if (ret) {
+		/* Is the gfn already mapped due to a racing vCPU? */
+		if (ret == -EPERM)
+			return -EAGAIN;
+	}
+
+	swap(mapping, cache->mapping);
+	mapping->gfn = gfn;
+	mapping->pfn = pfn;
+	WARN_ON(rb_find_add(&mapping->node, &pgt->pkvm_mappings, cmp_mappings));
+
+	return ret;
+}
+
+int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	pkvm_handle_t handle = kvm->arch.pkvm.handle;
+	struct pkvm_mapping *mapping;
+	int ret = 0;
+
+	lockdep_assert_held_write(&kvm->mmu_lock);
+	for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
+		if (WARN_ON(ret))
+			break;
+		rb_erase(&mapping->node, &pgt->pkvm_mappings);
+		kfree(mapping);
+	}
+
+	return ret;
+}
+
+int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	pkvm_handle_t handle = kvm->arch.pkvm.handle;
+	struct pkvm_mapping *mapping;
+	int ret = 0;
+
+	lockdep_assert_held(&kvm->mmu_lock);
+	for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn);
+		if (WARN_ON(ret))
+			break;
+	}
+
+	return ret;
+}
+
+int pkvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	struct pkvm_mapping *mapping;
+
+	lockdep_assert_held(&kvm->mmu_lock);
+	for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping)
+		__clean_dcache_guest_page(pfn_to_kaddr(mapping->pfn), PAGE_SIZE);
+
+	return 0;
+}
+
+bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold)
+{
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
+	pkvm_handle_t handle = kvm->arch.pkvm.handle;
+	struct pkvm_mapping *mapping;
+	bool young = false;
+
+	lockdep_assert_held(&kvm->mmu_lock);
+	for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping)
+		young |= kvm_call_hyp_nvhe(__pkvm_host_test_clear_young_guest, handle, mapping->gfn,
+					   mkold);
+
+	return young;
+}
+
+int pkvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
+				    enum kvm_pgtable_walk_flags flags)
+{
+	return kvm_call_hyp_nvhe(__pkvm_host_relax_perms_guest, addr >> PAGE_SHIFT, prot);
+}
+
+void pkvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
+				 enum kvm_pgtable_walk_flags flags)
+{
+	WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_mkyoung_guest, addr >> PAGE_SHIFT));
+}
+
+void pkvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
+{
+	WARN_ON_ONCE(1);
+}
+
+kvm_pte_t *pkvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
+					enum kvm_pgtable_prot prot, void *mc, bool force_pte)
+{
+	WARN_ON_ONCE(1);
+	return NULL;
+}
+
+int pkvm_pgtable_stage2_split(struct kvm_pgtable *pgt, u64 addr, u64 size,
+			      struct kvm_mmu_memory_cache *mc)
+{
+	WARN_ON_ONCE(1);
+	return -EINVAL;
+}
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:59 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:59 +0000
Subject: [PATCH v4 18/18] KVM: arm64: Plumb the pKVM MMU in KVM
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-19-qperret@google.com>

Introduce the KVM_PGT_CALL() helper macro to allow switching from the
traditional pgtable code to the pKVM version easily in mmu.c. The cost
of this 'indirection' is expected to be very minimal due to
is_protected_kvm_enabled() being backed by a static key.

With this, everything is in place to allow the delegation of
non-protected guest stage-2 page-tables to pKVM, so let's stop using the
host's kvm_s2_mmu from EL2 and enjoy the ride.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_mmu.h   | 16 ++++++
 arch/arm64/kvm/arm.c               |  9 +++-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c |  2 -
 arch/arm64/kvm/mmu.c               | 87 ++++++++++++++++++++----------
 4 files changed, 82 insertions(+), 32 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 66d93e320ec8..d116ab4230e8 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -353,6 +353,22 @@ static inline bool kvm_is_nested_s2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
 	return &kvm->arch.mmu != mmu;
 }
 
+static inline void kvm_fault_lock(struct kvm *kvm)
+{
+	if (is_protected_kvm_enabled())
+		write_lock(&kvm->mmu_lock);
+	else
+		read_lock(&kvm->mmu_lock);
+}
+
+static inline void kvm_fault_unlock(struct kvm *kvm)
+{
+	if (is_protected_kvm_enabled())
+		write_unlock(&kvm->mmu_lock);
+	else
+		read_unlock(&kvm->mmu_lock);
+}
+
 #ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
 void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
 #else
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 55cc62b2f469..9bcbc7b8ed38 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -502,7 +502,10 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 
 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
-	kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+	if (!is_protected_kvm_enabled())
+		kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+	else
+		free_hyp_memcache(&vcpu->arch.pkvm_memcache);
 	kvm_timer_vcpu_terminate(vcpu);
 	kvm_pmu_vcpu_destroy(vcpu);
 	kvm_vgic_vcpu_destroy(vcpu);
@@ -574,6 +577,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	struct kvm_s2_mmu *mmu;
 	int *last_ran;
 
+	if (is_protected_kvm_enabled())
+		goto nommu;
+
 	if (vcpu_has_nv(vcpu))
 		kvm_vcpu_load_hw_mmu(vcpu);
 
@@ -594,6 +600,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		*last_ran = vcpu->vcpu_idx;
 	}
 
+nommu:
 	vcpu->cpu = cpu;
 
 	kvm_vgic_load(vcpu);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 130f5f23bcb5..258d572eed62 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -103,8 +103,6 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 	/* Limit guest vector length to the maximum supported by the host.  */
 	hyp_vcpu->vcpu.arch.sve_max_vl	= min(host_vcpu->arch.sve_max_vl, kvm_host_sve_max_vl);
 
-	hyp_vcpu->vcpu.arch.hw_mmu	= host_vcpu->arch.hw_mmu;
-
 	hyp_vcpu->vcpu.arch.mdcr_el2	= host_vcpu->arch.mdcr_el2;
 	hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE);
 	hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2) &
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 641e4fec1659..9403524c11c6 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -15,6 +15,7 @@
 #include <asm/kvm_arm.h>
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_pgtable.h>
+#include <asm/kvm_pkvm.h>
 #include <asm/kvm_ras.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
@@ -31,6 +32,8 @@ static phys_addr_t __ro_after_init hyp_idmap_vector;
 
 static unsigned long __ro_after_init io_map_base;
 
+#define KVM_PGT_FN(fn)		(!is_protected_kvm_enabled() ? fn : p ## fn)
+
 static phys_addr_t __stage2_range_addr_end(phys_addr_t addr, phys_addr_t end,
 					   phys_addr_t size)
 {
@@ -147,7 +150,7 @@ static int kvm_mmu_split_huge_pages(struct kvm *kvm, phys_addr_t addr,
 			return -EINVAL;
 
 		next = __stage2_range_addr_end(addr, end, chunk_size);
-		ret = kvm_pgtable_stage2_split(pgt, addr, next - addr, cache);
+		ret = KVM_PGT_FN(kvm_pgtable_stage2_split)(pgt, addr, next - addr, cache);
 		if (ret)
 			break;
 	} while (addr = next, addr != end);
@@ -168,15 +171,23 @@ static bool memslot_is_logging(struct kvm_memory_slot *memslot)
  */
 int kvm_arch_flush_remote_tlbs(struct kvm *kvm)
 {
-	kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
+	if (is_protected_kvm_enabled())
+		kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
+	else
+		kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
 	return 0;
 }
 
 int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm,
 				      gfn_t gfn, u64 nr_pages)
 {
-	kvm_tlb_flush_vmid_range(&kvm->arch.mmu,
-				gfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT);
+	u64 size = nr_pages << PAGE_SHIFT;
+	u64 addr = gfn << PAGE_SHIFT;
+
+	if (is_protected_kvm_enabled())
+		kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
+	else
+		kvm_tlb_flush_vmid_range(&kvm->arch.mmu, addr, size);
 	return 0;
 }
 
@@ -225,7 +236,7 @@ static void stage2_free_unlinked_table_rcu_cb(struct rcu_head *head)
 	void *pgtable = page_to_virt(page);
 	s8 level = page_private(page);
 
-	kvm_pgtable_stage2_free_unlinked(&kvm_s2_mm_ops, pgtable, level);
+	KVM_PGT_FN(kvm_pgtable_stage2_free_unlinked)(&kvm_s2_mm_ops, pgtable, level);
 }
 
 static void stage2_free_unlinked_table(void *addr, s8 level)
@@ -324,7 +335,7 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
 
 	lockdep_assert_held_write(&kvm->mmu_lock);
 	WARN_ON(size & ~PAGE_MASK);
-	WARN_ON(stage2_apply_range(mmu, start, end, kvm_pgtable_stage2_unmap,
+	WARN_ON(stage2_apply_range(mmu, start, end, KVM_PGT_FN(kvm_pgtable_stage2_unmap),
 				   may_block));
 }
 
@@ -336,7 +347,7 @@ void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
 
 void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
 {
-	stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_flush);
+	stage2_apply_range_resched(mmu, addr, end, KVM_PGT_FN(kvm_pgtable_stage2_flush));
 }
 
 static void stage2_flush_memslot(struct kvm *kvm,
@@ -942,10 +953,14 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 		return -ENOMEM;
 
 	mmu->arch = &kvm->arch;
-	err = kvm_pgtable_stage2_init(pgt, mmu, &kvm_s2_mm_ops);
+	err = KVM_PGT_FN(kvm_pgtable_stage2_init)(pgt, mmu, &kvm_s2_mm_ops);
 	if (err)
 		goto out_free_pgtable;
 
+	mmu->pgt = pgt;
+	if (is_protected_kvm_enabled())
+		return 0;
+
 	mmu->last_vcpu_ran = alloc_percpu(typeof(*mmu->last_vcpu_ran));
 	if (!mmu->last_vcpu_ran) {
 		err = -ENOMEM;
@@ -959,7 +974,6 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 	mmu->split_page_chunk_size = KVM_ARM_EAGER_SPLIT_CHUNK_SIZE_DEFAULT;
 	mmu->split_page_cache.gfp_zero = __GFP_ZERO;
 
-	mmu->pgt = pgt;
 	mmu->pgd_phys = __pa(pgt->pgd);
 
 	if (kvm_is_nested_s2_mmu(kvm, mmu))
@@ -968,7 +982,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
 	return 0;
 
 out_destroy_pgtable:
-	kvm_pgtable_stage2_destroy(pgt);
+	KVM_PGT_FN(kvm_pgtable_stage2_destroy)(pgt);
 out_free_pgtable:
 	kfree(pgt);
 	return err;
@@ -1065,7 +1079,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
 	write_unlock(&kvm->mmu_lock);
 
 	if (pgt) {
-		kvm_pgtable_stage2_destroy(pgt);
+		KVM_PGT_FN(kvm_pgtable_stage2_destroy)(pgt);
 		kfree(pgt);
 	}
 }
@@ -1082,9 +1096,11 @@ static void *hyp_mc_alloc_fn(void *unused)
 
 void free_hyp_memcache(struct kvm_hyp_memcache *mc)
 {
-	if (is_protected_kvm_enabled())
-		__free_hyp_memcache(mc, hyp_mc_free_fn,
-				    kvm_host_va, NULL);
+	if (!is_protected_kvm_enabled())
+		return;
+
+	kfree(mc->mapping);
+	__free_hyp_memcache(mc, hyp_mc_free_fn, kvm_host_va, NULL);
 }
 
 int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages)
@@ -1092,6 +1108,12 @@ int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages)
 	if (!is_protected_kvm_enabled())
 		return 0;
 
+	if (!mc->mapping) {
+		mc->mapping = kzalloc(sizeof(struct pkvm_mapping), GFP_KERNEL_ACCOUNT);
+		if (!mc->mapping)
+			return -ENOMEM;
+	}
+
 	return __topup_hyp_memcache(mc, min_pages, hyp_mc_alloc_fn,
 				    kvm_host_pa, NULL);
 }
@@ -1130,8 +1152,8 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 			break;
 
 		write_lock(&kvm->mmu_lock);
-		ret = kvm_pgtable_stage2_map(pgt, addr, PAGE_SIZE, pa, prot,
-					     &cache, 0);
+		ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, addr, PAGE_SIZE,
+				 pa, prot, &cache, 0);
 		write_unlock(&kvm->mmu_lock);
 		if (ret)
 			break;
@@ -1151,7 +1173,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
  */
 void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
 {
-	stage2_apply_range_resched(mmu, addr, end, kvm_pgtable_stage2_wrprotect);
+	stage2_apply_range_resched(mmu, addr, end, KVM_PGT_FN(kvm_pgtable_stage2_wrprotect));
 }
 
 /**
@@ -1442,9 +1464,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	unsigned long mmu_seq;
 	phys_addr_t ipa = fault_ipa;
 	struct kvm *kvm = vcpu->kvm;
-	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
 	struct vm_area_struct *vma;
 	short vma_shift;
+	void *memcache;
 	gfn_t gfn;
 	kvm_pfn_t pfn;
 	bool logging_active = memslot_is_logging(memslot);
@@ -1472,8 +1494,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * and a write fault needs to collapse a block entry into a table.
 	 */
 	if (!fault_is_perm || (logging_active && write_fault)) {
-		ret = kvm_mmu_topup_memory_cache(memcache,
-						 kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu));
+		int min_pages = kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu);
+
+		if (!is_protected_kvm_enabled()) {
+			memcache = &vcpu->arch.mmu_page_cache;
+			ret = kvm_mmu_topup_memory_cache(memcache, min_pages);
+		} else {
+			memcache = &vcpu->arch.pkvm_memcache;
+			ret = topup_hyp_memcache(memcache, min_pages);
+		}
 		if (ret)
 			return ret;
 	}
@@ -1494,7 +1523,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * logging_active is guaranteed to never be true for VM_PFNMAP
 	 * memslots.
 	 */
-	if (logging_active) {
+	if (logging_active || is_protected_kvm_enabled()) {
 		force_pte = true;
 		vma_shift = PAGE_SHIFT;
 	} else {
@@ -1634,7 +1663,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		prot |= kvm_encode_nested_level(nested);
 	}
 
-	read_lock(&kvm->mmu_lock);
+	kvm_fault_lock(kvm);
 	pgt = vcpu->arch.hw_mmu->pgt;
 	if (mmu_invalidate_retry(kvm, mmu_seq)) {
 		ret = -EAGAIN;
@@ -1696,16 +1725,16 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		 * PTE, which will be preserved.
 		 */
 		prot &= ~KVM_NV_GUEST_MAP_SZ;
-		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot, flags);
+		ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, fault_ipa, prot, flags);
 	} else {
-		ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
+		ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, fault_ipa, vma_pagesize,
 					     __pfn_to_phys(pfn), prot,
 					     memcache, flags);
 	}
 
 out_unlock:
 	kvm_release_faultin_page(kvm, page, !!ret, writable);
-	read_unlock(&kvm->mmu_lock);
+	kvm_fault_unlock(kvm);
 
 	/* Mark the page dirty only if the fault is handled successfully */
 	if (writable && !ret)
@@ -1724,7 +1753,7 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 
 	read_lock(&vcpu->kvm->mmu_lock);
 	mmu = vcpu->arch.hw_mmu;
-	kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa, flags);
+	KVM_PGT_FN(kvm_pgtable_stage2_mkyoung)(mmu->pgt, fault_ipa, flags);
 	read_unlock(&vcpu->kvm->mmu_lock);
 }
 
@@ -1764,7 +1793,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		}
 
 		/* Falls between the IPA range and the PARange? */
-		if (fault_ipa >= BIT_ULL(vcpu->arch.hw_mmu->pgt->ia_bits)) {
+		if (fault_ipa >= BIT_ULL(VTCR_EL2_IPA(vcpu->arch.hw_mmu->vtcr))) {
 			fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
 
 			if (is_iabt)
@@ -1930,7 +1959,7 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
-	return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
+	return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, true);
 	/*
@@ -1946,7 +1975,7 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 	if (!kvm->arch.mmu.pgt)
 		return false;
 
-	return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
+	return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt,
 						   range->start << PAGE_SHIFT,
 						   size, false);
 }
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:41 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:41 +0000
Subject: [PATCH v4 00/18] KVM: arm64: Non-protected guest stage-2 support for pKVM
Message-ID: <20241218194059.3670226-1-qperret@google.com>

Hi all,

This is the v4 of the series adding support for non-protected guests
stage-2 to pKVM. Please refer to v1 for all the context:

  https://lore.kernel.org/kvmarm/20241104133204.85208-1-qperret at google.com/

Please note that in its current form, this series has two main
limitations that will be addressed separately:

 - We don't support mapping devices into guests: this requires
   additional hypervisor support for tracking the 'state' of devices.
   No device assignment until then.

 - Stage-2 mappings are forced to page-granularity even when backed by a
   huge page for the sake of simplicity of this series. I'm only aiming
   at functional parity-ish (from userspace's PoV) for now, support for
   HP can be added on top later as a perf improvement.

The series is organized as follows:

 - Patches 01 to 04 move the host ownership state tracking from the
   host's stage-2 page-table to the hypervisor's vmemmap. This avoids
   fragmenting the host stage-2 for shared pages, which is only needed
   to store an annotation in the SW bits of the corresponding PTE. All
   pages mapped into non-protected guests are shared from pKVM's PoV,
   so the cost of stage-2 fragmentation will increase massively as we
   start tracking that at EL2. Note that these patches also help with
   the existing sharing for e.g. FF-A, so they could possibly be merged
   separately from the rest of the series.

 - Patches 05 to 07 implement a minor refactoring of the pgtable code to
   ease the integration of the pKVM MMU later on.

 - Patches 08 to 16 introduce all the infrastructure needed on the pKVM
   side for handling guest stage-2 page-tables at EL2.

 - Patches 17 and 18 plumb the newly introduced pKVM support into
   KVM/arm64.

Patches based on 6.13-rc3, tested on Pixel 6 and Qemu.

Changes in v4:
 - Collected Tested-by and Reviewed-by tags
 - Reworked KVM_S2_PGT to help ctags/grepping kvm_pgtable_* functions
 - Minor cleanups throughout

Changes in v3:
 - Rebased on 6.13-rc3
 - Applied Marc's rework of the for_each_mapping_in_range() macro mess
 - Removed mappings_lock in favor the mmu_lock
 - Dropped BUG_ON() from pkvm_mkstate()
 - Renamed range_is_allowed_memory() and clarified the comment inside it
 - Explicitly bail out when using host_stage2_set_owner_locked() on
   non-memory regions
 - Check PKVM_NOPAGE state as an equality rather than a bitwise
   operator
 - Reworked __pkvm_host_share_guest() to return -EPERM in case of
   illegal multi-sharing
 - Added get_np_pkvm_hyp_vm() to simplify HVC error handling in
   hyp-main.c
 - Cosmetic changes and improved coding consitency thoughout the series

Changes in v2:
 - Rebased on 6.13-rc1 (small conflicts with commit 2362506f7cff ("KVM:
   arm64: Don't mark "struct page" accessed when making SPTE young") in
   particular)
 - Fixed kerneldoc breakage for __unmap_stage2_range()
 - Fixed pkvm_pgtable_test_clear_young() to use correct HVC
 - Folded guest_get_valid_pte() into __check_host_unshare_guest() for
   clarity

Thanks,
Quentin

Marc Zyngier (1):
  KVM: arm64: Introduce __pkvm_vcpu_{load,put}()

Quentin Perret (17):
  KVM: arm64: Change the layout of enum pkvm_page_state
  KVM: arm64: Move enum pkvm_page_state to memory.h
  KVM: arm64: Make hyp_page::order a u8
  KVM: arm64: Move host page ownership tracking to the hyp vmemmap
  KVM: arm64: Pass walk flags to kvm_pgtable_stage2_mkyoung
  KVM: arm64: Pass walk flags to kvm_pgtable_stage2_relax_perms
  KVM: arm64: Make kvm_pgtable_stage2_init() a static inline function
  KVM: arm64: Add {get,put}_pkvm_hyp_vm() helpers
  KVM: arm64: Introduce __pkvm_host_share_guest()
  KVM: arm64: Introduce __pkvm_host_unshare_guest()
  KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
  KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
  KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
  KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
  KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
  KVM: arm64: Introduce the EL1 pKVM MMU
  KVM: arm64: Plumb the pKVM MMU in KVM

 arch/arm64/include/asm/kvm_asm.h              |   9 +
 arch/arm64/include/asm/kvm_host.h             |   4 +
 arch/arm64/include/asm/kvm_mmu.h              |  16 +
 arch/arm64/include/asm/kvm_pgtable.h          |  38 ++-
 arch/arm64/include/asm/kvm_pkvm.h             |  26 ++
 arch/arm64/kvm/arm.c                          |  23 +-
 arch/arm64/kvm/hyp/include/nvhe/gfp.h         |   6 +-
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  39 +--
 arch/arm64/kvm/hyp/include/nvhe/memory.h      |  50 ++-
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h        |  16 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 201 ++++++++++-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 320 ++++++++++++++++--
 arch/arm64/kvm/hyp/nvhe/page_alloc.c          |  14 +-
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  69 ++++
 arch/arm64/kvm/hyp/nvhe/setup.c               |   7 +-
 arch/arm64/kvm/hyp/pgtable.c                  |  13 +-
 arch/arm64/kvm/mmu.c                          |  93 +++--
 arch/arm64/kvm/pkvm.c                         | 201 +++++++++++
 arch/arm64/kvm/vgic/vgic-v3.c                 |   6 +-
 19 files changed, 1006 insertions(+), 145 deletions(-)

-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:42 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:42 +0000
Subject: [PATCH v4 01/18] KVM: arm64: Change the layout of enum pkvm_page_state
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-2-qperret@google.com>

The 'concrete' (a.k.a non-meta) page states are currently encoded using
software bits in PTEs. For performance reasons, the abstract
pkvm_page_state enum uses the same bits to encode these states as that
makes conversions from and to PTEs easy.

In order to prepare the ground for moving the 'concrete' state storage
to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this
purpose.

No functional changes intended.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 0972faccc2af..5462faf6bfee 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -24,25 +24,27 @@
  */
 enum pkvm_page_state {
 	PKVM_PAGE_OWNED			= 0ULL,
-	PKVM_PAGE_SHARED_OWNED		= KVM_PGTABLE_PROT_SW0,
-	PKVM_PAGE_SHARED_BORROWED	= KVM_PGTABLE_PROT_SW1,
-	__PKVM_PAGE_RESERVED		= KVM_PGTABLE_PROT_SW0 |
-					  KVM_PGTABLE_PROT_SW1,
+	PKVM_PAGE_SHARED_OWNED		= BIT(0),
+	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
+	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
 
 	/* Meta-states which aren't encoded directly in the PTE's SW bits */
-	PKVM_NOPAGE,
+	PKVM_NOPAGE			= BIT(2),
 };
+#define PKVM_PAGE_META_STATES_MASK	(~__PKVM_PAGE_RESERVED)
 
 #define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
 static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
 						 enum pkvm_page_state state)
 {
-	return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
+	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
+	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
+	return prot;
 }
 
 static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
 {
-	return prot & PKVM_PAGE_STATE_PROT_MASK;
+	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
 }
 
 struct host_mmu {
-- 
2.47.1.613.gc27f4b7a9f-goog



From qperret at google.com  Wed Dec 18 11:40:43 2024
From: qperret at google.com (Quentin Perret)
Date: Wed, 18 Dec 2024 19:40:43 +0000
Subject: [PATCH v4 02/18] KVM: arm64: Move enum pkvm_page_state to memory.h
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <20241218194059.3670226-3-qperret@google.com>

In order to prepare the way for storing page-tracking information in
pKVM's vmemmap, move the enum pkvm_page_state definition to
nvhe/memory.h.

No functional changes intended.

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 34 +------------------
 arch/arm64/kvm/hyp/include/nvhe/memory.h      | 33 ++++++++++++++++++
 2 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 5462faf6bfee..25038ac705d8 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -11,42 +11,10 @@
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_pgtable.h>
 #include <asm/virt.h>
+#include <nvhe/memory.h>
 #include <nvhe/pkvm.h>
 #include <nvhe/spinlock.h>
 
-/*
- * SW bits 0-1 are reserved to track the memory ownership state of each page:
- *   00: The page is owned exclusively by the page-table owner.
- *   01: The page is owned by the page-table owner, but is shared
- *       with another entity.
- *   10: The page is shared with, but not owned by the page-table owner.
- *   11: Reserved for future use (lending).
- */
-enum pkvm_page_state {
-	PKVM_PAGE_OWNED			= 0ULL,
-	PKVM_PAGE_SHARED_OWNED		= BIT(0),
-	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
-	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
-
-	/* Meta-states which aren't encoded directly in the PTE's SW bits */
-	PKVM_NOPAGE			= BIT(2),
-};
-#define PKVM_PAGE_META_STATES_MASK	(~__PKVM_PAGE_RESERVED)
-
-#define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
-static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
-						 enum pkvm_page_state state)
-{
-	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
-	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
-	return prot;
-}
-
-static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
-{
-	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
-}
-
 struct host_mmu {
 	struct kvm_arch arch;
 	struct kvm_pgtable pgt;
diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h
index ab205c4d6774..0964c461da92 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/memory.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h
@@ -7,6 +7,39 @@
 
 #include <linux/types.h>
 
+/*
+ * SW bits 0-1 are reserved to track the memory ownership state of each page:
+ *   00: The page is owned exclusively by the page-table owner.
+ *   01: The page is owned by the page-table owner, but is shared
+ *       with another entity.
+ *   10: The page is shared with, but not owned by the page-table owner.
+ *   11: Reserved for future use (lending).
+ */
+enum pkvm_page_state {
+	PKVM_PAGE_OWNED			= 0ULL,
+	PKVM_PAGE_SHARED_OWNED		= BIT(0),
+	PKVM_PAGE_SHARED_BORROWED	= BIT(1),
+	__PKVM_PAGE_RESERVED		= BIT(0) | BIT(1),
+
+	/* Meta-states which aren't encoded directly in the PTE's SW bits */
+	PKVM_NOPAGE			= BIT(2),
+};
+#define PKVM_PAGE_META_STATES_MASK	(~__PKVM_PAGE_RESERVED)
+
+#define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
+static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
+						 enum pkvm_page_state state)
+{
+	prot &= ~PKVM_PAGE_STATE_PROT_MASK;
+	prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state);
+	return prot;
+}
+
+static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
+{
+	return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot);
+}
+
 struct hyp_page {
 	unsigned short refcount;
 	unsigned short order;
-- 
2.47.1.613.gc27f4b7a9f-goog



From irogers at google.com  Wed Dec 18 11:47:09 2024
From: irogers at google.com (Ian Rogers)
Date: Wed, 18 Dec 2024 11:47:09 -0800
Subject: [PATCH 5/5] perf docs: arm_spe: Document new discard mode
In-Reply-To: <8c15786c-47b6-47ff-b1dc-ecbf32d582fb@linaro.org>
References: <20241217115610.371755-1-james.clark@linaro.org>
 <20241217115610.371755-6-james.clark@linaro.org> <CAP-5=fU7RNzvzxBcAQy3RT9Ge3YtqPhDonupNWS7Wgb8HGQkGg@mail.gmail.com>
 <8c15786c-47b6-47ff-b1dc-ecbf32d582fb@linaro.org>
Message-ID: <CAP-5=fXV6LXrUtvgRKuyurmu5SoSZLTf6MN=+BBXkqv7drvOjg@mail.gmail.com>

On Wed, Dec 18, 2024 at 2:07?AM James Clark <james.clark at linaro.org> wrote:
>
> On 18/12/2024 12:54 am, Ian Rogers wrote:
> > On Tue, Dec 17, 2024 at 3:56?AM James Clark <james.clark at linaro.org> wrote:
> >>
> >> Document the flag, hint what it's used for and give an example with
> >> other useful options to get minimal output.
> >>
> >> Signed-off-by: James Clark <james.clark at linaro.org>
> >> ---
> >>   tools/perf/Documentation/perf-arm-spe.txt | 11 +++++++++++
> >>   1 file changed, 11 insertions(+)
> >>
> >> diff --git a/tools/perf/Documentation/perf-arm-spe.txt b/tools/perf/Documentation/perf-arm-spe.txt
> >> index de2b0b479249..588eead438bc 100644
> >> --- a/tools/perf/Documentation/perf-arm-spe.txt
> >> +++ b/tools/perf/Documentation/perf-arm-spe.txt
> >> @@ -150,6 +150,7 @@ arm_spe/load_filter=1,min_latency=10/'
> >>     pct_enable=1        - collect physical timestamp instead of virtual timestamp (PMSCR.PCT) - requires privilege
> >>     store_filter=1      - collect stores only (PMSFCR.ST)
> >>     ts_enable=1         - enable timestamping with value of generic timer (PMSCR.TS)
> >> +  discard=1           - enable SPE PMU events but don't collect sample data - see 'Discard mode' (PMBLIMITR.FM = DISCARD)
> >>
> >>   +++*+++ Latency is the total latency from the point at which sampling started on that instruction, rather
> >>   than only the execution latency.
> >> @@ -220,6 +221,16 @@ Common errors
> >>
> >>      Increase sampling interval (see above)
> >>
> >> +Discard mode
> >> +~~~~~~~~~~~~
> >> +
> >> +SPE PMU events can be used without the overhead of collecting sample data if
> >> +discard mode is supported (optional from Armv8.6). First run a system wide SPE
> >> +session (or on the core of interest) using options to minimize output. Then run
> >> +perf stat:
> >> +
> >> +  perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
> >> +  perf stat -e SAMPLE_FEED_LD
> >
> > Perhaps clarify this should be an ARM SPE event? It seems strange to
> > have one perf command affect a later one, the purpose of things like
> > event multiplexing is to hide the hardware limits. I'd prefer if the
> > last bit was like:
> > ```
> > Then run perf stat with an SPE event on the same PMU:
> >
> > perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
> > perf stat -e arm_spe/SAMPLE_FEED_LD/
> > ``
> >
> > Thanks,
> > Ian
>
> Hi Ian,
>
> Confusingly this isn't an SPE event, it is a normal PMU event. The fact
> that one Perf command affects the other is because these events only
> count when SPE is enabled. When it's enabled it has an effect on a
> per-core level which is why in the example I made it simpler by enabling
> SPE system wide.
>
> SPE is an exclusive PMU like Coresight and some others so it can't be
> affected by multiplexing or anything like that. The SAMPLE_FEED_LD PMU
> would be, but as long as SPE stays enabled it will count the right thing
> regardless of multiplexing.

Thanks James, sorry for my SPE ignorance. I'm smiling about the use of
the word exclusive. When I was trying to make the tests run in
parallel I used a file lock - so shared and exclusive. There were a
lot of issues with that, hence switching to 2 phases in the test,
parallel then sequential but I kept the "exclusive" tag for want of a
better word. Perhaps the notion of an exclusive PMU existed previously
but maybe I've accidentally invented the term by way of a failed file
lock experiment :-)

Presumably the two PMUs side-effecting each other is a known thing. I
wonder if we can capture this in the documentation. When you say
"normal PMU event" you mean core PMU events?

Thanks,
Ian


From heiko at sntech.de  Wed Dec 18 13:06:23 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 18 Dec 2024 22:06:23 +0100
Subject: (subset) [PATCH v9 0/9] Drivers to support the MCU on QNAP NAS devices
In-Reply-To: <20241107114712.538976-1-heiko@sntech.de>
References: <20241107114712.538976-1-heiko@sntech.de>
Message-ID: <173455598053.629326.7463057625807840374.b4-ty@sntech.de>


On Thu, 07 Nov 2024 12:47:03 +0100, Heiko Stuebner wrote:
> This implements a set of drivers for the MCU used on QNAP NAS devices.
> 
> Of course no documentation for the serial protocol is available, so
> thankfully QNAP has a tool on their rescue-inird to talk to the MCU and
> I found interceptty [0] to listen to what goes over the serial connection.
> 
> In general it looks like there are two different generations in general,
> an "EC" device and now this "MCU" - referenced in the strings of the
> userspace handlers for those devices.
> 
> [...]

Applied, thanks!

[8/9] arm64: dts: rockchip: hook up the MCU on the QNAP TS433
      commit: 989e3dd871349e76919911ac628e97ff6cb1ad51
[9/9] arm64: dts: rockchip: set hdd led labels on qnap-ts433
      commit: 47f34eab58294d7bb2583f9519b4022e74d56437

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From patrick at stwcx.xyz  Wed Dec 18 13:24:57 2024
From: patrick at stwcx.xyz (Patrick Williams)
Date: Wed, 18 Dec 2024 16:24:57 -0500
Subject: [PATCH] ARM: dts: aspeed: yosemite4: adjust secondary flash name
Message-ID: <20241218212458.3050775-1-patrick@stwcx.xyz>

Meta (Facebook) has a preference for all of our secondary flash
chips to be labelled "alt-bmc" for consistency of userspace tools
deal with updates.  Bletchley, Harma, Minerva, and Catalina all
follow this convention but for some reason Yosemite4 is different.

Adjust the label in the dts to match the other platforms.

Signed-off-by: Patrick Williams <patrick at stwcx.xyz>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
index 98477792aa00..e20816d9e077 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
@@ -112,7 +112,7 @@ flash at 0 {
 	flash at 1 {
 		status = "okay";
 		m25p,fast-read;
-		label = "bmc2";
+		label = "alt-bmc";
 		spi-rx-bus-width = <4>;
 		spi-max-frequency = <50000000>;
 	};
-- 
2.44.2



From Frank.li at nxp.com  Wed Dec 18 13:25:51 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 16:25:51 -0500
Subject: [PATCH v2] i2c: imx: switch different pinctrl state in different
 system power status
In-Reply-To: <20241218044114.143358-1-carlos.song@nxp.com>
References: <20241218044114.143358-1-carlos.song@nxp.com>
Message-ID: <Z2M938ZSobeYk+1G@lizhi-Precision-Tower-5810>

On Wed, Dec 18, 2024 at 12:41:14PM +0800, Carlos Song wrote:
> Switch different pinctrl state in different system power status.
>
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Reviewed-by: Frank Li <Frank.Li at nxp.com>
> ---
> Change for V2:
> - Add Frank reviewed-by. No code change.

Needn't send v2 if only add review-by tags without any code change.

Frank

> ---
>  drivers/i2c/busses/i2c-imx.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index b6ed270dd04b..350346a7892c 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -1871,6 +1871,7 @@ static int i2c_imx_runtime_suspend(struct device *dev)
>  	struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
>
>  	clk_disable(i2c_imx->clk);
> +	pinctrl_pm_select_sleep_state(dev);
>
>  	return 0;
>  }
> @@ -1880,6 +1881,7 @@ static int i2c_imx_runtime_resume(struct device *dev)
>  	struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
>  	int ret;
>
> +	pinctrl_pm_select_default_state(dev);
>  	ret = clk_enable(i2c_imx->clk);
>  	if (ret)
>  		dev_err(dev, "can't enable I2C clock, ret=%d\n", ret);
> --
> 2.34.1
>


From oliver.upton at linux.dev  Wed Dec 18 13:30:15 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 18 Dec 2024 13:30:15 -0800
Subject: [PATCH] KVM: arm64: Always check the state from hyp_ack_unshare()
In-Reply-To: <20241128154406.602875-1-qperret@google.com>
References: <20241128154406.602875-1-qperret@google.com>
Message-ID: <173455738564.3742443.9773591453026966218.b4-ty@linux.dev>

On Thu, 28 Nov 2024 15:44:06 +0000, Quentin Perret wrote:
> There are multiple pKVM memory transitions where the state of a page is
> not cross-checked from the completer's PoV for performance reasons.
> For example, if a page is PKVM_PAGE_OWNED from the initiator's PoV,
> we should be guaranteed by construction that it is PKVM_NOPAGE for
> everybody else, hence allowing us to save a page-table lookup.
> 
> When it was introduced, hyp_ack_unshare() followed that logic and bailed
> out without checking the PKVM_PAGE_SHARED_BORROWED state in the
> hypervisor's stage-1. This was correct as we could safely assume that
> all host-initiated shares were directed at the hypervisor at the time.
> But with the introduction of other types of shares (e.g. for FF-A or
> non-protected guests), it is now very much required to cross check this
> state to prevent the host from running __pkvm_host_unshare_hyp() on a
> page shared with TZ or a non-protected guest.
> 
> [...]

Sorry for letting this one slip.

Applied to fixes, thanks!

[1/1] KVM: arm64: Always check the state from hyp_ack_unshare()
      https://git.kernel.org/kvmarm/kvmarm/c/985bb51f17ab

--
Best,
Oliver


From seanjc at google.com  Wed Dec 18 13:56:27 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 18 Dec 2024 13:56:27 -0800
Subject: [PATCH v4 00/16] KVM: selftests: "tree" wide overhauls
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <173455833964.3185228.5614329030867008316.b4-ty@google.com>

On Wed, 27 Nov 2024 16:55:31 -0800, Sean Christopherson wrote:
> Two separate series (mmu_stress_test[1] and $ARCH[2]), posted as one to
> avoid unpleasant conflicts, and because I hope to land both in kvm/next
> shortly after 6.12-rc1 since they impact all of KVM selftests.
> 
> mmu_stress_test
> ---------------
> Convert the max_guest_memory_test into a more generic mmu_stress_test.
> The basic gist of the "conversion" is to have the test do mprotect() on
> guest memory while vCPUs are accessing said memory, e.g. to verify KVM
> and mmu_notifiers are working as intended.
> 
> [...]

As I am running out of time before I disappear for two weeks, applied to:

   https://github.com/kvm-x86/linux.git selftests_arch

Other KVM maintainers, that branch is officially immutable.  I also pushed a tag,
kvm-selftests-arch-6.14, just in case I pull a stupid and manage to clobber the
branch.  My apologies if this causes pain.  AFAICT, there aren't any queued or
in-flight patches that git's rename magic can't automatically handle, so hopefully
this ends up being pain-free.

Paolo, here's a pull request if you want to pull this into kvm/next long before
the 6.14 merge window.  Diff stats at the very bottom (hilariously long).

---
The following changes since commit 3522c419758ee8dca5a0e8753ee0070a22157bc1:

  Merge tag 'kvm-riscv-fixes-6.13-1' of https://github.com/kvm-riscv/linux into HEAD (2024-12-13 13:59:20 -0500)

are available in the Git repository at:

  https://github.com/kvm-x86/linux.git tags/kvm-selftests-arch-6.14

for you to fetch changes up to d76fe926b6c443f912bbb14bbcd42a8b9e5d68f6:

  KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR (2024-12-17 08:49:49 -0800)

----------------------------------------------------------------
KVM selftests "tree"-wide changes for 6.14:

 - Rework vcpu_get_reg() to return a value instead of using an out-param, and
   update all affected arch code accordingly.

 - Convert the max_guest_memory_test into a more generic mmu_stress_test.
   The basic gist of the "conversion" is to have the test do mprotect() on
   guest memory while vCPUs are accessing said memory, e.g. to verify KVM
   and mmu_notifiers are working as intended.

 - Play nice with treewrite builds of unsupported architectures, e.g. arm
   (32-bit), as KVM selftests' Makefile doesn't do anything to ensure the
   target architecture is actually one KVM selftests supports.

  - Use the kernel's $(ARCH) definition instead of the target triple for arch
    specific directories, e.g. arm64 instead of aarch64, mainly so as not to
    be different from the rest of the kernel.

----------------------------------------------------------------
Sean Christopherson (16):
      KVM: Move KVM_REG_SIZE() definition to common uAPI header
      KVM: selftests: Return a value from vcpu_get_reg() instead of using an out-param
      KVM: selftests: Assert that vcpu_{g,s}et_reg() won't truncate
      KVM: selftests: Check for a potential unhandled exception iff KVM_RUN succeeded
      KVM: selftests: Rename max_guest_memory_test to mmu_stress_test
      KVM: selftests: Only muck with SREGS on x86 in mmu_stress_test
      KVM: selftests: Compute number of extra pages needed in mmu_stress_test
      KVM: sefltests: Explicitly include ucall_common.h in mmu_stress_test.c
      KVM: selftests: Enable mmu_stress_test on arm64
      KVM: selftests: Use vcpu_arch_put_guest() in mmu_stress_test
      KVM: selftests: Precisely limit the number of guest loops in mmu_stress_test
      KVM: selftests: Add a read-only mprotect() phase to mmu_stress_test
      KVM: selftests: Verify KVM correctly handles mprotect(PROT_READ)
      KVM: selftests: Provide empty 'all' and 'clean' targets for unsupported ARCHs
      KVM: selftests: Use canonical $(ARCH) paths for KVM selftests directories
      KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR
---


[01/16] KVM: Move KVM_REG_SIZE() definition to common uAPI header
        https://github.com/kvm-x86/linux/commit/915d2f0718a4
[02/16] KVM: selftests: Return a value from vcpu_get_reg() instead of using an out-param
        https://github.com/kvm-x86/linux/commit/411e22037f8c
[03/16] KVM: selftests: Assert that vcpu_{g,s}et_reg() won't truncate
        https://github.com/kvm-x86/linux/commit/446d7f483be3
[04/16] KVM: selftests: Check for a potential unhandled exception iff KVM_RUN succeeded
        https://github.com/kvm-x86/linux/commit/f3c4e02e4da2
[05/16] KVM: selftests: Rename max_guest_memory_test to mmu_stress_test
        https://github.com/kvm-x86/linux/commit/356ebe558f55
[06/16] KVM: selftests: Only muck with SREGS on x86 in mmu_stress_test
        https://github.com/kvm-x86/linux/commit/66d612d32fe3
[07/16] KVM: selftests: Compute number of extra pages needed in mmu_stress_test
        https://github.com/kvm-x86/linux/commit/f1e0b743b12e
[08/16] KVM: sefltests: Explicitly include ucall_common.h in mmu_stress_test.c
        https://github.com/kvm-x86/linux/commit/0ce51ad9d565
[09/16] KVM: selftests: Enable mmu_stress_test on arm64
        https://github.com/kvm-x86/linux/commit/d2fa5a3b80c6
[10/16] KVM: selftests: Use vcpu_arch_put_guest() in mmu_stress_test
        https://github.com/kvm-x86/linux/commit/c1797c2be44d
[11/16] KVM: selftests: Precisely limit the number of guest loops in mmu_stress_test
        https://github.com/kvm-x86/linux/commit/9615ab61eb54
[12/16] KVM: selftests: Add a read-only mprotect() phase to mmu_stress_test
        https://github.com/kvm-x86/linux/commit/d9a3b8ab6643
[13/16] KVM: selftests: Verify KVM correctly handles mprotect(PROT_READ)
        https://github.com/kvm-x86/linux/commit/a606855e27b3
[14/16] KVM: selftests: Provide empty 'all' and 'clean' targets for unsupported ARCHs
        https://github.com/kvm-x86/linux/commit/1f13ec4de22d
[15/16] KVM: selftests: Use canonical $(ARCH) paths for KVM selftests directories
        https://github.com/kvm-x86/linux/commit/022d78205681
[16/16] KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR
        https://github.com/kvm-x86/linux/commit/d76fe926b6c4

--
https://github.com/kvm-x86/linux/tree/next



 MAINTAINERS                                                                          |  12 +--
 arch/arm64/include/uapi/asm/kvm.h                                                    |   3 -
 arch/riscv/include/uapi/asm/kvm.h                                                    |   3 -
 include/uapi/linux/kvm.h                                                             |   4 +
 tools/testing/selftests/kvm/.gitignore                                               |   1 +
 tools/testing/selftests/kvm/Makefile                                                 | 345 ++------------------------------------------------------------------------------
 tools/testing/selftests/kvm/Makefile.kvm                                             | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/testing/selftests/kvm/{aarch64 => arm64}/aarch32_id_regs.c                     |  10 +--
 tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer.c                          |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer_edge_cases.c               |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/debug-exceptions.c                    |   4 +-
 tools/testing/selftests/kvm/{aarch64 => arm64}/get-reg-list.c                        |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/hypercalls.c                          |   6 +-
 tools/testing/selftests/kvm/{aarch64 => arm64}/mmio_abort.c                          |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/no-vgic-v3.c                          |   2 +-
 tools/testing/selftests/kvm/{aarch64 => arm64}/page_fault_test.c                     |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/psci_test.c                           |   6 +-
 tools/testing/selftests/kvm/{aarch64 => arm64}/set_id_regs.c                         |  18 ++---
 tools/testing/selftests/kvm/{aarch64 => arm64}/smccc_filter.c                        |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vcpu_width_config.c                   |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_init.c                           |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_irq.c                            |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_lpi_stress.c                     |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vpmu_counter_access.c                 |  19 +++--
 tools/testing/selftests/kvm/dirty_log_perf_test.c                                    |   2 +-
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/arch_timer.h                  |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/delay.h                       |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic.h                         |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3.h                      |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3_its.h                  |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/kvm_util_arch.h               |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/processor.h                   |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/spinlock.h                    |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/ucall.h                       |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/vgic.h                        |   0
 tools/testing/selftests/kvm/include/kvm_util.h                                       |  10 ++-
 tools/testing/selftests/kvm/include/{s390x => s390}/debug_print.h                    |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/diag318_test_handler.h           |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/facility.h                       |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/kvm_util_arch.h                  |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/processor.h                      |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/sie.h                            |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/ucall.h                          |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/apic.h                           |   2 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/evmcs.h                          |   3 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/hyperv.h                         |   3 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/kvm_util_arch.h                  |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/mce.h                            |   2 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/pmu.h                            |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/processor.h                      |   2 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/sev.h                            |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/svm.h                            |   6 --
 tools/testing/selftests/kvm/include/{x86_64 => x86}/svm_util.h                       |   3 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/ucall.h                          |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/vmx.h                            |   2 -
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic.c                             |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_private.h                     |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3.c                          |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3_its.c                      |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/handlers.S                        |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/processor.c                       |   8 +-
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/spinlock.c                        |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/ucall.c                           |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/vgic.c                            |   0
 tools/testing/selftests/kvm/lib/kvm_util.c                                           |   3 +-
 tools/testing/selftests/kvm/lib/riscv/processor.c                                    |  66 ++++++++--------
 tools/testing/selftests/kvm/lib/{s390x => s390}/diag318_test_handler.c               |   0
 tools/testing/selftests/kvm/lib/{s390x => s390}/facility.c                           |   0
 tools/testing/selftests/kvm/lib/{s390x => s390}/processor.c                          |   0
 tools/testing/selftests/kvm/lib/{s390x => s390}/ucall.c                              |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/apic.c                               |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/handlers.S                           |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/hyperv.c                             |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/memstress.c                          |   2 +-
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/pmu.c                                |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/processor.c                          |   2 -
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/sev.c                                |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/svm.c                                |   1 -
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/ucall.c                              |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/vmx.c                                |   2 -
 tools/testing/selftests/kvm/{max_guest_memory_test.c => mmu_stress_test.c}           | 162 ++++++++++++++++++++++++++++++++++----
 tools/testing/selftests/kvm/riscv/arch_timer.c                                       |   2 +-
 tools/testing/selftests/kvm/riscv/ebreak_test.c                                      |   2 +-
 tools/testing/selftests/kvm/riscv/sbi_pmu_test.c                                     |   2 +-
 tools/testing/selftests/kvm/{s390x => s390}/cmma_test.c                              |   0
 tools/testing/selftests/kvm/{s390x => s390}/config                                   |   0
 tools/testing/selftests/kvm/{s390x => s390}/cpumodel_subfuncs_test.c                 |   0
 tools/testing/selftests/kvm/{s390x => s390}/debug_test.c                             |   0
 tools/testing/selftests/kvm/{s390x => s390}/memop.c                                  |   0
 tools/testing/selftests/kvm/{s390x => s390}/resets.c                                 |   2 +-
 tools/testing/selftests/kvm/{s390x => s390}/shared_zeropage_test.c                   |   0
 tools/testing/selftests/kvm/{s390x => s390}/sync_regs_test.c                         |   0
 tools/testing/selftests/kvm/{s390x => s390}/tprot.c                                  |   0
 tools/testing/selftests/kvm/{s390x => s390}/ucontrol_test.c                          |   0
 tools/testing/selftests/kvm/set_memory_region_test.c                                 |   6 +-
 tools/testing/selftests/kvm/steal_time.c                                             |   3 +-
 tools/testing/selftests/kvm/{x86_64 => x86}/amx_test.c                               |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/apic_bus_clock_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/cpuid_test.c                             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/debug_regs.c                             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/dirty_log_page_splitting_test.c          |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/exit_on_emulation_failure_test.c         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/feature_msrs_test.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/fix_hypercall_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/flds_emulation.h                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hwcr_msr_test.c                          |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_clock.c                           |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_cpuid.c                           |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_evmcs.c                           |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_extended_hypercalls.c             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_features.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_ipi.c                             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_svm_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_tlb_flush.c                       |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/kvm_clock_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/kvm_pv_test.c                            |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/max_vcpuid_cap_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/monitor_mwait_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/nested_exceptions_test.c                 |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.sh                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/platform_info_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/pmu_counters_test.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/pmu_event_filter_test.c                  |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_conversions_test.c           |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_kvm_exits_test.c             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/recalc_apic_map_test.c                   |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/set_boot_cpu_id.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/set_sregs_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/sev_init2_tests.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/sev_migrate_tests.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/sev_smoke_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/smaller_maxphyaddr_emulation_test.c      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/smm_test.c                               |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/state_test.c                             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/svm_int_ctl_test.c                       |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_shutdown_test.c               |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_soft_inject_test.c            |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/svm_vmcall_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/sync_regs_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/triple_fault_event_test.c                |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/tsc_msrs_test.c                          |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/tsc_scaling_sync.c                       |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/ucna_injection_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/userspace_io_test.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/userspace_msr_exit_test.c                |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_apic_access_test.c                   |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_close_while_nested_test.c            |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_dirty_log_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_exception_with_invalid_guest_state.c |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_invalid_nested_guest_state.c         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_msrs_test.c                          |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_nested_tsc_scaling_test.c            |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_pmu_caps_test.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_preemption_timer_test.c              |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_set_nested_state_test.c              |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xapic_ipi_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xapic_state_test.c                       |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xcr0_cpuid_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xen_shinfo_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xen_vmcall_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xss_msr_test.c                           |   0
 164 files changed, 584 insertions(+), 477 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/Makefile.kvm
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/aarch32_id_regs.c (95%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer_edge_cases.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/debug-exceptions.c (99%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/get-reg-list.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/hypercalls.c (98%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/mmio_abort.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/no-vgic-v3.c (98%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/page_fault_test.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/psci_test.c (97%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/set_id_regs.c (97%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/smccc_filter.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vcpu_width_config.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_init.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_irq.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_lpi_stress.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vpmu_counter_access.c (97%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/arch_timer.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/delay.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3_its.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/processor.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/spinlock.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/vgic.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/debug_print.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/diag318_test_handler.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/facility.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/processor.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/sie.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/apic.h (98%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/evmcs.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/hyperv.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/mce.h (94%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/pmu.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/processor.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/sev.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm.h (98%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm_util.h (94%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/vmx.h (99%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_private.h (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3_its.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/handlers.S (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/processor.c (98%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/spinlock.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/vgic.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/diag318_test_handler.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/facility.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/processor.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/apic.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/handlers.S (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/hyperv.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/memstress.c (98%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/pmu.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/processor.c (99%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/sev.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/svm.c (99%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/vmx.c (99%)
 rename tools/testing/selftests/kvm/{max_guest_memory_test.c => mmu_stress_test.c} (60%)
 rename tools/testing/selftests/kvm/{s390x => s390}/cmma_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/config (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/cpumodel_subfuncs_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/debug_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/memop.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/resets.c (99%)
 rename tools/testing/selftests/kvm/{s390x => s390}/shared_zeropage_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/sync_regs_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/tprot.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/ucontrol_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/amx_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/apic_bus_clock_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/cpuid_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/debug_regs.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/dirty_log_page_splitting_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/exit_on_emulation_failure_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/feature_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/fix_hypercall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/flds_emulation.h (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hwcr_msr_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_clock.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_cpuid.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_evmcs.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_extended_hypercalls.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_features.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_ipi.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_svm_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_tlb_flush.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_clock_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_pv_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/max_vcpuid_cap_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/monitor_mwait_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nested_exceptions_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.sh (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/platform_info_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_counters_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_event_filter_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_conversions_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_kvm_exits_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/recalc_apic_map_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/set_boot_cpu_id.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/set_sregs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_init2_tests.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_migrate_tests.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_smoke_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/smaller_maxphyaddr_emulation_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/smm_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_int_ctl_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_shutdown_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_soft_inject_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_vmcall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sync_regs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/triple_fault_event_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_scaling_sync.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/ucna_injection_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_io_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_msr_exit_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_apic_access_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_close_while_nested_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_dirty_log_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_exception_with_invalid_guest_state.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_invalid_nested_guest_state.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_nested_tsc_scaling_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_pmu_caps_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_preemption_timer_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_set_nested_state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_ipi_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xcr0_cpuid_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_shinfo_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_vmcall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xss_msr_test.c (100%)


From nfraprado at collabora.com  Wed Dec 18 14:01:08 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Wed, 18 Dec 2024 19:01:08 -0300
Subject: [PATCH] arm64: dts: mediatek: mt8195: Remove suspend-breaking
 reset from pcie1
Message-ID: <20241218-mt8195-pcie1-reset-suspend-fix-v1-1-1c021dda42a6@collabora.com>

The MAC reset for PCIe port 1 on MT8195 when asserted during suspend
causes the system to hang during resume with the following error (with
no_console_suspend enabled):

  mtk-pcie-gen3 112f8000.pcie: PCIe link down, current LTSSM state: detect.quiet (0x0)
  mtk-pcie-gen3 112f8000.pcie: PM: dpm_run_callback(): genpd_resume_noirq+0x0/0x24 returns -110
  mtk-pcie-gen3 112f8000.pcie: PM: failed to resume noirq: error -110

This issue is specific to MT8195. On MT8192 with the PCIe reset,
MT8192_INFRA_RST4_PCIE_TOP_SWRST, added to the DT node, the issue is not
observed.

Since without the reset, the PCIe controller and WiFi card connected to
it, work just as well, remove the reset to allow the system to suspend
and resume properly.

Fixes: ecc0af6a3fe6 ("arm64: dts: mt8195: Add pcie and pcie phy nodes")
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index ade685ed2190b7339d5daad55ce81c092bd7b39e..04e41b557d44810c5be097dab40b5b94f63b1843 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1611,9 +1611,6 @@ pcie1: pcie at 112f8000 {
 			phy-names = "pcie-phy";
 			power-domains = <&spm MT8195_POWER_DOMAIN_PCIE_MAC_P1>;
 
-			resets = <&infracfg_ao MT8195_INFRA_RST2_PCIE_P1_SWRST>;
-			reset-names = "mac";
-
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 7>;
 			interrupt-map = <0 0 0 1 &pcie_intc1 0>,

---
base-commit: e25c8d66f6786300b680866c0e0139981273feba
change-id: 20241218-mt8195-pcie1-reset-suspend-fix-3e14122149e2

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From seanjc at google.com  Wed Dec 18 14:12:18 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 18 Dec 2024 14:12:18 -0800
Subject: [PATCH v4 00/16] KVM: selftests: "tree" wide overhauls
In-Reply-To: <173455833964.3185228.5614329030867008316.b4-ty@google.com>
References: <20241128005547.4077116-1-seanjc@google.com> <173455833964.3185228.5614329030867008316.b4-ty@google.com>
Message-ID: <Z2NIwmRDaZBc_V4o@google.com>

On Wed, Dec 18, 2024, Sean Christopherson wrote:
> On Wed, 27 Nov 2024 16:55:31 -0800, Sean Christopherson wrote:
> > Two separate series (mmu_stress_test[1] and $ARCH[2]), posted as one to
> > avoid unpleasant conflicts, and because I hope to land both in kvm/next
> > shortly after 6.12-rc1 since they impact all of KVM selftests.
> > 
> > mmu_stress_test
> > ---------------
> > Convert the max_guest_memory_test into a more generic mmu_stress_test.
> > The basic gist of the "conversion" is to have the test do mprotect() on
> > guest memory while vCPUs are accessing said memory, e.g. to verify KVM
> > and mmu_notifiers are working as intended.
> > 
> > [...]
> 
> As I am running out of time before I disappear for two weeks, applied to:
> 
>    https://github.com/kvm-x86/linux.git selftests_arch
> 
> Other KVM maintainers, that branch is officially immutable.  I also pushed a tag,
> kvm-selftests-arch-6.14, just in case I pull a stupid and manage to clobber the
> branch.  My apologies if this causes pain.  AFAICT, there aren't any queued or
> in-flight patches that git's rename magic can't automatically handle, so hopefully
> this ends up being pain-free.
> 
> Paolo, here's a pull request if you want to pull this into kvm/next long before
> the 6.14 merge window.  Diff stats at the very bottom (hilariously long).

Argh!  I completely forget to build test this on non-x86, and missed that arm64
snuck in 75cd027cbcb1 ("KVM: arm64: selftests: Test ID_AA64PFR0.MPAM isn't completely 
ignored").  *sigh*

Given that I just sent out mail, I'm going to cross my fingers and hope that no
one has merged the above branch/tag.  I've deleted the branch and tags from the
remote, but kept the tag locally just in case.

Please holler if you managed to grab the broken branch/tag.  If no one screams,
I'll assume I got luckly and will push a fixed version (with different names) later
today.


From apopple at nvidia.com  Wed Dec 18 14:49:18 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Thu, 19 Dec 2024 09:49:18 +1100
Subject: [PATCH v4 10/25] mm/mm_init: Move p2pdma page refcount
 initialisation to p2pdma
In-Reply-To: <359a1cf2-c5b0-4682-ba3c-980d77c4cfdb@redhat.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <aaa23e6f315a2d9b30a422c3769100cdfa42e85a.1734407924.git-series.apopple@nvidia.com>
 <359a1cf2-c5b0-4682-ba3c-980d77c4cfdb@redhat.com>
Message-ID: <bk6cmiubwvor6gevit3wgl4k66xxpfcv6swmfrtvxnjnuojqkx@yow3pmyuxozw>

On Tue, Dec 17, 2024 at 11:14:42PM +0100, David Hildenbrand wrote:
> On 17.12.24 06:12, Alistair Popple wrote:
> > Currently ZONE_DEVICE page reference counts are initialised by core
> > memory management code in __init_zone_device_page() as part of the
> > memremap() call which driver modules make to obtain ZONE_DEVICE
> > pages. This initialises page refcounts to 1 before returning them to
> > the driver.
> > 
> > This was presumably done because it drivers had a reference of sorts
> > on the page. It also ensured the page could always be mapped with
> > vm_insert_page() for example and would never get freed (ie. have a
> > zero refcount), freeing drivers of manipulating page reference counts.
> 
> It probably dates back to copying that code from other zone-init code where
> we
> (a) Treat all available-at-boot memory as allocated before we release it to
> the buddy
> (b) Treat all hotplugged memory as allocated until we release it to the
> buddy
 
Argh, thanks for the background.

> As a side note, I'm working on converting (b) -- PageOffline pages -- to
> have a refcount of 0 ("frozen").

[...]

> > diff --git a/mm/mm_init.c b/mm/mm_init.c
> > index 24b68b4..f021e63 100644
> > --- a/mm/mm_init.c
> > +++ b/mm/mm_init.c
> > @@ -1017,12 +1017,26 @@ static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,
> >   	}
> >   	/*
> > -	 * ZONE_DEVICE pages are released directly to the driver page allocator
> > -	 * which will set the page count to 1 when allocating the page.
> > +	 * ZONE_DEVICE pages other than MEMORY_TYPE_GENERIC and
> > +	 * MEMORY_TYPE_FS_DAX pages are released directly to the driver page
> > +	 * allocator which will set the page count to 1 when allocating the
> > +	 * page.
> > +	 *
> > +	 * MEMORY_TYPE_GENERIC and MEMORY_TYPE_FS_DAX pages automatically have
> > +	 * their refcount reset to one whenever they are freed (ie. after
> > +	 * their refcount drops to 0).
> >   	 */
> > -	if (pgmap->type == MEMORY_DEVICE_PRIVATE ||
> > -	    pgmap->type == MEMORY_DEVICE_COHERENT)
> > +	switch (pgmap->type) {
> > +	case MEMORY_DEVICE_PRIVATE:
> > +	case MEMORY_DEVICE_COHERENT:
> > +	case MEMORY_DEVICE_PCI_P2PDMA:
> >   		set_page_count(page, 0);
> > +		break;
> > +
> > +	case MEMORY_DEVICE_FS_DAX:
> > +	case MEMORY_DEVICE_GENERIC:
> > +		break;
> > +	}
> >   }
> >   /*
> 
> 
> But that's a bit weird: we call __init_single_page()->init_page_count() to
> initialize it to 1, to then set it back to 0.
> 
> 
> Maybe we can just pass to __init_single_page() the refcount we want to have
> directly? Can be a patch on top of course.

Once the dust settles on this series we won't need the pgmap->type check at
all because all ZONE_DEVICE pages will get an initial count of 0. I have some
follow up clean-ups for after this series is applied (particularly with regards
to pgmap refcounts), so if it's ok I'd rather do this as a follow-up.

> Apart from that
> 
> Acked-by: David Hildenbrand <david at redhat.com>
> 
> -- 
> Cheers,
> 
> David / dhildenb
> 


From heiko at sntech.de  Wed Dec 18 14:49:19 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 18 Dec 2024 23:49:19 +0100
Subject: [PATCH v9 0/9] Drivers to support the MCU on QNAP NAS devices
In-Reply-To: <20241212171954.GI7139@google.com>
References: <20241107114712.538976-1-heiko@sntech.de>
 <173402387748.2234929.7484373598047473898.b4-ty@kernel.org>
 <20241212171954.GI7139@google.com>
Message-ID: <15355121.tv2OnDr8pf@diego>

Am Donnerstag, 12. Dezember 2024, 18:19:54 CET schrieb Lee Jones:
> On Thu, 12 Dec 2024, Lee Jones wrote:
> 
> > On Thu, 07 Nov 2024 12:47:03 +0100, Heiko Stuebner wrote:
> > > This implements a set of drivers for the MCU used on QNAP NAS devices.
> > > 
> > > Of course no documentation for the serial protocol is available, so
> > > thankfully QNAP has a tool on their rescue-inird to talk to the MCU and
> > > I found interceptty [0] to listen to what goes over the serial connection.
> > > 
> > > In general it looks like there are two different generations in general,
> > > an "EC" device and now this "MCU" - referenced in the strings of the
> > > userspace handlers for those devices.
> > > 
> > > [...]
> > 
> > Applied, thanks!
> > 
> > [1/9] HID: hid-sensor-hub: don't use stale platform-data on remove
> >       commit: e079a120f31e3f9c00180aa13c1df18cc138f7fe
> > [2/9] mfd: core: make platform_data pointer const in struct mfd_cell
> >       commit: 8f4009ad901c44f0428dbde654c4dd1fb29c863b
> > [3/9] dt-bindings: mfd: add binding for qnap,ts433-mcu devices
> >       commit: 8877bcff3e3b4f08a1fc0232dbfdaeda085cfdf3
> > [4/9] mfd: add base driver for qnap-mcu devices
> >       commit: 944ca826f69e4723853b3876875b03aeafe67b60
> > [5/9] leds: add driver for LEDs from qnap-mcu devices
> >       commit: fe6a21ee38f12e3e5f9adbd2f9a840be105b943f
> > [6/9] Input: add driver for the input part of qnap-mcu devices
> >       commit: 4b27e0da257371d3d141fae38fdbdc3c3a67bce6
> > [7/9] hwmon: add driver for the hwmon parts of qnap-mcu devices
> >       commit: 41755872a8a8ab8d1644459d9634c53b743fe2be
> 
> Once build testing is complete, I'll send out a PR.

thanks a lot for picking up the driver patches.

Heiko




From apopple at nvidia.com  Wed Dec 18 14:55:35 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Thu, 19 Dec 2024 09:55:35 +1100
Subject: [PATCH v4 14/25] rmap: Add support for PUD sized mappings to rmap
In-Reply-To: <4b5768b7-96e0-4864-9dbe-88fd1f0e87b8@redhat.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <7f739c9e9f0a25cafb76a482e31e632c8f72102e.1734407924.git-series.apopple@nvidia.com>
 <4b5768b7-96e0-4864-9dbe-88fd1f0e87b8@redhat.com>
Message-ID: <volhyxjxlbsflldgs36ghzartel2tu625ubz3kfed2gdwrsamt@cpfsfhdpc4rp>

On Tue, Dec 17, 2024 at 11:27:13PM +0100, David Hildenbrand wrote:
> On 17.12.24 06:12, Alistair Popple wrote:
> > The rmap doesn't currently support adding a PUD mapping of a
> > folio. This patch adds support for entire PUD mappings of folios,
> > primarily to allow for more standard refcounting of device DAX
> > folios. Currently DAX is the only user of this and it doesn't require
> > support for partially mapped PUD-sized folios so we don't support for
> > that for now.
> > 
> > Signed-off-by: Alistair Popple <apopple at nvidia.com>
> > 
> > ---
> > 
> > David - Thanks for your previous comments, I'm less familiar with the
> > rmap code so I would appreciate you taking another look. In particular
> > I haven't added a stat for PUD mapped folios as it seemed like
> > overkill for just the device DAX case but let me know if you think
> > otherwise.
> > 
> > Changes for v4:
> > 
> >   - New for v4, split out rmap changes as suggested by David.
> > ---
> >   include/linux/rmap.h | 15 ++++++++++++-
> >   mm/rmap.c            | 56 +++++++++++++++++++++++++++++++++++++++++++++-
> >   2 files changed, 71 insertions(+)
> > 
> > diff --git a/include/linux/rmap.h b/include/linux/rmap.h
> > index 683a040..7043914 100644
> > --- a/include/linux/rmap.h
> > +++ b/include/linux/rmap.h
> > @@ -192,6 +192,7 @@ typedef int __bitwise rmap_t;
> >   enum rmap_level {
> >   	RMAP_LEVEL_PTE = 0,
> >   	RMAP_LEVEL_PMD,
> > +	RMAP_LEVEL_PUD,
> >   };
> >   static inline void __folio_rmap_sanity_checks(const struct folio *folio,
> > @@ -228,6 +229,14 @@ static inline void __folio_rmap_sanity_checks(const struct folio *folio,
> >   		VM_WARN_ON_FOLIO(folio_nr_pages(folio) != HPAGE_PMD_NR, folio);
> >   		VM_WARN_ON_FOLIO(nr_pages != HPAGE_PMD_NR, folio);
> >   		break;
> > +	case RMAP_LEVEL_PUD:
> > +		/*
> > +		 * Assume that we are creating * a single "entire" mapping of the
> > +		 * folio.
> > +		 */
> > +		VM_WARN_ON_FOLIO(folio_nr_pages(folio) != HPAGE_PUD_NR, folio);
> > +		VM_WARN_ON_FOLIO(nr_pages != HPAGE_PUD_NR, folio);
> > +		break;
> >   	default:
> >   		VM_WARN_ON_ONCE(true);
> >   	}
> > @@ -251,12 +260,16 @@ void folio_add_file_rmap_ptes(struct folio *, struct page *, int nr_pages,
> >   	folio_add_file_rmap_ptes(folio, page, 1, vma)
> >   void folio_add_file_rmap_pmd(struct folio *, struct page *,
> >   		struct vm_area_struct *);
> > +void folio_add_file_rmap_pud(struct folio *, struct page *,
> > +		struct vm_area_struct *);
> >   void folio_remove_rmap_ptes(struct folio *, struct page *, int nr_pages,
> >   		struct vm_area_struct *);
> >   #define folio_remove_rmap_pte(folio, page, vma) \
> >   	folio_remove_rmap_ptes(folio, page, 1, vma)
> >   void folio_remove_rmap_pmd(struct folio *, struct page *,
> >   		struct vm_area_struct *);
> > +void folio_remove_rmap_pud(struct folio *, struct page *,
> > +		struct vm_area_struct *);
> >   void hugetlb_add_anon_rmap(struct folio *, struct vm_area_struct *,
> >   		unsigned long address, rmap_t flags);
> > @@ -341,6 +354,7 @@ static __always_inline void __folio_dup_file_rmap(struct folio *folio,
> >   		atomic_add(orig_nr_pages, &folio->_large_mapcount);
> >   		break;
> >   	case RMAP_LEVEL_PMD:
> > +	case RMAP_LEVEL_PUD:
> >   		atomic_inc(&folio->_entire_mapcount);
> >   		atomic_inc(&folio->_large_mapcount);
> >   		break;
> > @@ -437,6 +451,7 @@ static __always_inline int __folio_try_dup_anon_rmap(struct folio *folio,
> >   		atomic_add(orig_nr_pages, &folio->_large_mapcount);
> >   		break;
> >   	case RMAP_LEVEL_PMD:
> > +	case RMAP_LEVEL_PUD:
> >   		if (PageAnonExclusive(page)) {
> >   			if (unlikely(maybe_pinned))
> >   				return -EBUSY;
> > diff --git a/mm/rmap.c b/mm/rmap.c
> > index c6c4d4e..39d0439 100644
> > --- a/mm/rmap.c
> > +++ b/mm/rmap.c
> > @@ -1203,6 +1203,11 @@ static __always_inline unsigned int __folio_add_rmap(struct folio *folio,
> >   		}
> >   		atomic_inc(&folio->_large_mapcount);
> >   		break;
> > +	case RMAP_LEVEL_PUD:
> > +		/* We only support entire mappings of PUD sized folios in rmap */
> > +		atomic_inc(&folio->_entire_mapcount);
> > +		atomic_inc(&folio->_large_mapcount);
> > +		break;
> 
> 
> This way you don't account the pages at all as mapped, whereby PTE-mapping it
> would? And IIRC, these PUD-sized pages can be either mapped using PTEs or
> using a single PUD.

Oh good point. I was thinking that because we don't account PUD mappings today
that it would be fine to ignore them. But of course this series means we start
accounting them if mapped with PTEs so agree we should be consistent.
 
> I suspect what you want is to

Yes, I think so. Thanks for the hint. I will be out over the Christmas break but
will do a respin to incorporate this before then.

> diff --git a/mm/rmap.c b/mm/rmap.c
> index c6c4d4ea29a7e..1477028d3a176 100644
> --- a/mm/rmap.c
> +++ b/mm/rmap.c
> @@ -1187,12 +1187,19 @@ static __always_inline unsigned int __folio_add_rmap(struct folio *folio,
>                 atomic_add(orig_nr_pages, &folio->_large_mapcount);
>                 break;
>         case RMAP_LEVEL_PMD:
> +       case RMAP_LEVEL_PUD:
>                 first = atomic_inc_and_test(&folio->_entire_mapcount);
>                 if (first) {
>                         nr = atomic_add_return_relaxed(ENTIRELY_MAPPED, mapped);
>                         if (likely(nr < ENTIRELY_MAPPED + ENTIRELY_MAPPED)) {
> -                               *nr_pmdmapped = folio_nr_pages(folio);
> -                               nr = *nr_pmdmapped - (nr & FOLIO_PAGES_MAPPED);
> +                               nr_pages = folio_nr_pages(folio);
> +                               /*
> +                                * We only track PMD mappings of PMD-sized
> +                                * folios separately.
> +                                */
> +                               if (level == RMAP_LEVEL_PMD)
> +                                       *nr_pmdmapped = nr_pages;
> +                               nr = nr_pages - (nr & FOLIO_PAGES_MAPPED);
>                                 /* Raced ahead of a remove and another add? */
>                                 if (unlikely(nr < 0))
>                                         nr = 0;
> 
> Similar on the removal path.
> 
> 
> -- 
> Cheers,
> 
> David / dhildenb
> 


From mike.leach at linaro.org  Wed Dec 18 15:01:17 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Wed, 18 Dec 2024 23:01:17 +0000
Subject: [PATCH v3 2/3] coresight: tmc: Update error logging in tmc common functions
In-Reply-To: <20241218230118.999859-1-mike.leach@linaro.org>
References: <20241218230118.999859-1-mike.leach@linaro.org>
Message-ID: <20241218230118.999859-3-mike.leach@linaro.org>

Enhance the error logging in the tmc_wait_for_tmcready() and
tmc_flush_and_stop() to print key tmc  register values on error
conditions to improve hardware debug information.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
---
 .../hwtracing/coresight/coresight-tmc-core.c  | 44 +++++++++++++++----
 drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index e9876252a789..dff82facada3 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -34,25 +34,39 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
 DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
 DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
 
+#define TMC_WAIT_READY_FMT_STR "timeout while waiting for TMC to be Ready [STS=0x%04x]\n"
+
 int tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
 	struct csdev_access *csa = &csdev->access;
+	u32 tmc_sts = 0;
 
 	/* Ensure formatter, unformatter and hardware fifo are empty */
-	if (coresight_timeout(csa, TMC_STS, TMC_STS_TMCREADY_BIT, 1)) {
-		dev_err(&csdev->dev,
-			"timeout while waiting for TMC to be Ready\n");
+	if (coresight_timeout_retval(csa, TMC_STS, TMC_STS_TMCREADY_BIT, 1,
+				     &tmc_sts)) {
+		dev_err(&csdev->dev, TMC_WAIT_READY_FMT_STR, tmc_sts);
+		if (tmc_sts & TMC_STS_MEMERR)
+			dev_err(&csdev->dev,
+				"MemErr in STS reg waiting for TMC ready\n");
 		return -EBUSY;
 	}
 	return 0;
 }
 
-void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
+int tmc_flush_and_stop(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
 	struct csdev_access *csa = &csdev->access;
-	u32 ffcr;
+	u32 ffcr, ffsr, tmc_sts;
+	int rc = 0;
+
+	/* note any MemErr present when stopping TMC */
+	tmc_sts = readl_relaxed(drvdata->base + TMC_STS);
+	if (tmc_sts & TMC_STS_MEMERR)
+		dev_err(&csdev->dev,
+			"MemErr detected before Manual Flush; STS[0x%02x]\n",
+			tmc_sts);
 
 	ffcr = readl_relaxed(drvdata->base + TMC_FFCR);
 	ffcr |= TMC_FFCR_STOP_ON_FLUSH;
@@ -60,12 +74,26 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
 	ffcr |= BIT(TMC_FFCR_FLUSHMAN_BIT);
 	writel_relaxed(ffcr, drvdata->base + TMC_FFCR);
 	/* Ensure flush completes */
-	if (coresight_timeout(csa, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0)) {
+	if (coresight_timeout_retval(csa, TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0,
+				     &ffcr)) {
+		ffsr = readl_relaxed(drvdata->base + TMC_FFSR);
+		tmc_sts = readl_relaxed(drvdata->base + TMC_STS);
 		dev_err(&csdev->dev,
-		"timeout while waiting for completion of Manual Flush\n");
+			"timeout while waiting for completion of Manual Flush\n");
+		dev_err(&csdev->dev,
+			"regs: FFCR[0x%02x] FFSR[0x%02x] STS[0x%02x]\n",
+			ffcr, ffsr, tmc_sts);
+		if (tmc_sts & TMC_STS_MEMERR)
+			dev_err(&csdev->dev,
+				"MemErr in STS reg waiting for flush complete\n");
+		rc = -EBUSY;
 	}
 
-	tmc_wait_for_tmcready(drvdata);
+	if (tmc_wait_for_tmcready(drvdata)) {
+		dev_err(&csdev->dev, "TMC ready error after Manual flush\n");
+		rc = -EBUSY;
+	}
+	return rc;
 }
 
 void tmc_enable_hw(struct tmc_drvdata *drvdata)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 2671926be62a..34513f07c3aa 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -259,7 +259,7 @@ struct tmc_sg_table {
 
 /* Generic functions */
 int tmc_wait_for_tmcready(struct tmc_drvdata *drvdata);
-void tmc_flush_and_stop(struct tmc_drvdata *drvdata);
+int tmc_flush_and_stop(struct tmc_drvdata *drvdata);
 void tmc_enable_hw(struct tmc_drvdata *drvdata);
 void tmc_disable_hw(struct tmc_drvdata *drvdata);
 u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata);
-- 
2.25.1



From mike.leach at linaro.org  Wed Dec 18 15:01:15 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Wed, 18 Dec 2024 23:01:15 +0000
Subject: [PATCH v3 0/3] Extend logging on TMC start / stop errors
Message-ID: <20241218230118.999859-1-mike.leach@linaro.org>

Extend logging on TMC start / stop errors

Recent issues with trying to debug TMC timeouts and flush issues shows
a general lack of logging and context around the possible errors

Add logging to general wait for stop coresight routines and return values of
watched registers.

Update TMC to use this logging.

Changes since v2:
1) update coresight_timeout_retval() function to accept NULL for reg return
   pointer to simplify coresight_timeout()
2) Increase checks for MemErr bit in TMC status registers on error.

Changes since v1:
Rebase to coresight/next (kernel 6.13-rc2)

Mike Leach (3):
  coresight: Update timeout functions to allow return of test register
    value
  coresight: tmc: Update error logging in tmc common functions
  coresight: etf: etr: Update logging around flush_and_stop() errors

 drivers/hwtracing/coresight/coresight-core.c  | 50 +++++++++++++++----
 .../hwtracing/coresight/coresight-tmc-core.c  | 44 +++++++++++++---
 .../hwtracing/coresight/coresight-tmc-etf.c   | 12 +++--
 .../hwtracing/coresight/coresight-tmc-etr.c   |  8 ++-
 drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
 include/linux/coresight.h                     |  2 +
 6 files changed, 93 insertions(+), 25 deletions(-)

-- 
2.25.1



From mike.leach at linaro.org  Wed Dec 18 15:01:16 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Wed, 18 Dec 2024 23:01:16 +0000
Subject: [PATCH v3 1/3] coresight: Update timeout functions to allow return of test register value
In-Reply-To: <20241218230118.999859-1-mike.leach@linaro.org>
References: <20241218230118.999859-1-mike.leach@linaro.org>
Message-ID: <20241218230118.999859-2-mike.leach@linaro.org>

Current coresight_timeout function spins on a bit on a test register,
till bit value achieved or timeout hit.

Add another function to return the full value of the register being
tested.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
---
 drivers/hwtracing/coresight/coresight-core.c | 50 +++++++++++++++-----
 include/linux/coresight.h                    |  2 +
 2 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 0a9380350fb5..595f7ec0782f 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1092,32 +1092,37 @@ static void coresight_remove_conns(struct coresight_device *csdev)
 }
 
 /**
- * coresight_timeout - loop until a bit has changed to a specific register
- *			state.
+ * coresight_timeout_retval - loop until a bit has changed to a specific register
+ *			      state. Optionally return final register value
  * @csa: coresight device access for the device
  * @offset: Offset of the register from the base of the device.
  * @position: the position of the bit of interest.
  * @value: the value the bit should have.
+ * @rval: if not NULL, return the last read value of the register being tested.
  *
  * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
  * TIMEOUT_US has elapsed, which ever happens first.
  */
-int coresight_timeout(struct csdev_access *csa, u32 offset,
-		      int position, int value)
+int coresight_timeout_retval(struct csdev_access *csa, u32 offset,
+			     int position, int value, u32 *rval)
 {
-	int i;
-	u32 val;
+	int i, rc = -EAGAIN;
+	u32 val = 0;
 
 	for (i = TIMEOUT_US; i > 0; i--) {
 		val = csdev_access_read32(csa, offset);
 		/* waiting on the bit to go from 0 to 1 */
 		if (value) {
-			if (val & BIT(position))
-				return 0;
+			if (val & BIT(position)) {
+				rc = 0;
+				goto return_rval;
+			}
 		/* waiting on the bit to go from 1 to 0 */
 		} else {
-			if (!(val & BIT(position)))
-				return 0;
+			if (!(val & BIT(position))) {
+				rc = 0;
+				goto return_rval;
+			}
 		}
 
 		/*
@@ -1129,7 +1134,30 @@ int coresight_timeout(struct csdev_access *csa, u32 offset,
 			udelay(1);
 	}
 
-	return -EAGAIN;
+return_rval:
+	/* return the register value used when terminating the test */
+	if (rval)
+		*rval = val;
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(coresight_timeout_retval);
+
+/**
+ * coresight_timeout - loop until a bit has changed to a specific register
+ *		       state
+ * @csa: coresight device access for the device
+ * @offset: Offset of the register from the base of the device.
+ * @position: the position of the bit of interest.
+ * @value: the value the bit should have.
+ *
+ * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
+ * TIMEOUT_US has elapsed, which ever happens first.
+ */
+int coresight_timeout(struct csdev_access *csa, u32 offset,
+		      int position, int value)
+{
+	return coresight_timeout_retval(csa, offset, position, value, NULL);
 }
 EXPORT_SYMBOL_GPL(coresight_timeout);
 
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 17276965ff1d..cb3592d2803c 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -649,6 +649,8 @@ extern int coresight_enable_sysfs(struct coresight_device *csdev);
 extern void coresight_disable_sysfs(struct coresight_device *csdev);
 extern int coresight_timeout(struct csdev_access *csa, u32 offset,
 			     int position, int value);
+extern int coresight_timeout_retval(struct csdev_access *csa, u32 offset,
+				    int position, int value, u32 *rval);
 
 extern int coresight_claim_device(struct coresight_device *csdev);
 extern int coresight_claim_device_unlocked(struct coresight_device *csdev);
-- 
2.25.1



From mike.leach at linaro.org  Wed Dec 18 15:01:18 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Wed, 18 Dec 2024 23:01:18 +0000
Subject: [PATCH v3 3/3] coresight: etf: etr: Update logging around flush_and_stop() errors
In-Reply-To: <20241218230118.999859-1-mike.leach@linaro.org>
References: <20241218230118.999859-1-mike.leach@linaro.org>
Message-ID: <20241218230118.999859-4-mike.leach@linaro.org>

Insert additional context around tmc_flush_and_stop() errors.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
---
 drivers/hwtracing/coresight/coresight-tmc-etf.c | 12 +++++++++---
 drivers/hwtracing/coresight/coresight-tmc-etr.c |  8 ++++++--
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index d4f641cd9de6..62b4b685c1a1 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -84,7 +84,9 @@ static void __tmc_etb_disable_hw(struct tmc_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&drvdata->csdev->dev,
+			"Flush and stop error disabling ETB\n");
 	/*
 	 * When operating in sysFS mode the content of the buffer needs to be
 	 * read before the TMC is disabled.
@@ -146,7 +148,9 @@ static void tmc_etf_disable_hw(struct tmc_drvdata *drvdata)
 
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&drvdata->csdev->dev,
+			"Flush and stop error disabling ETF\n");
 	tmc_disable_hw(drvdata);
 	coresight_disclaim_device_unlocked(csdev);
 	CS_LOCK(drvdata->base);
@@ -496,7 +500,9 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
 
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&drvdata->csdev->dev,
+			"Flush and stop error updating perf buffer\n");
 
 	read_ptr = tmc_read_rrp(drvdata);
 	write_ptr = tmc_read_rwp(drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..122a067d1bb8 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1139,7 +1139,9 @@ static void __tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&drvdata->csdev->dev,
+			"Flush and stop error disabling ETR\n");
 	/*
 	 * When operating in sysFS mode the content of the buffer needs to be
 	 * read before the TMC is disabled.
@@ -1578,7 +1580,9 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
 
 	CS_UNLOCK(drvdata->base);
 
-	tmc_flush_and_stop(drvdata);
+	if (tmc_flush_and_stop(drvdata))
+		dev_err(&csdev->dev,
+			"Flush and Stop error updating perf buffer\n");
 	tmc_sync_etr_buf(drvdata);
 
 	CS_LOCK(drvdata->base);
-- 
2.25.1



From Frank.Li at nxp.com  Wed Dec 18 15:08:43 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:43 -0500
Subject: [PATCH v13 8/9] misc: pci_endpoint_test: Add doorbell test case
In-Reply-To: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
Message-ID: <20241218-ep-msi-v13-8-646e2192dc24@nxp.com>

Add three registers: PCIE_ENDPOINT_TEST_DB_BAR, PCIE_ENDPOINT_TEST_DB_ADDR,
and PCIE_ENDPOINT_TEST_DB_DATA.

Trigger the doorbell by writing data from PCI_ENDPOINT_TEST_DB_DATA to the
address provided by PCI_ENDPOINT_TEST_DB_OFFSET and wait for endpoint
feedback.

Add two command to COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL
to enable EP side's doorbell support and avoid compatible problem, which
host side driver miss-match with endpoint side function driver. See below
table:

		Host side new driver	Host side old driver
EP: new driver		S			F
EP: old driver		F			F

S: If EP side support MSI, 'pcitest -B' return success.
   If EP side doesn't support MSI, the same to 'F'.

F: 'pcitest -B' return failure, other case as usual.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v13
- none

Change from v8 to v9
- change PCITEST_DOORBELL to 0xa

Change form v6 to v8
- none

Change from v5 to v6
- %s/PCI_ENDPOINT_TEST_DB_ADDR/PCI_ENDPOINT_TEST_DB_OFFSET/g

Change from v4 to v5
- remove unused varible
- add irq_type at pci_endpoint_test_doorbell();

change from v3 to v4
- Add COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL.
- Remove new DID requirement.
---
 drivers/misc/pci_endpoint_test.c | 80 ++++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/pcitest.h     |  1 +
 2 files changed, 81 insertions(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 3aaaf47fa4ee2..b3f36b6ba8ba2 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -42,6 +42,8 @@
 #define COMMAND_READ				BIT(3)
 #define COMMAND_WRITE				BIT(4)
 #define COMMAND_COPY				BIT(5)
+#define COMMAND_ENABLE_DOORBELL			BIT(6)
+#define COMMAND_DISABLE_DOORBELL		BIT(7)
 
 #define PCI_ENDPOINT_TEST_STATUS		0x8
 #define STATUS_READ_SUCCESS			BIT(0)
@@ -53,6 +55,11 @@
 #define STATUS_IRQ_RAISED			BIT(6)
 #define STATUS_SRC_ADDR_INVALID			BIT(7)
 #define STATUS_DST_ADDR_INVALID			BIT(8)
+#define STATUS_DOORBELL_SUCCESS			BIT(9)
+#define STATUS_DOORBELL_ENABLE_SUCCESS		BIT(10)
+#define STATUS_DOORBELL_ENABLE_FAIL		BIT(11)
+#define STATUS_DOORBELL_DISABLE_SUCCESS		BIT(12)
+#define STATUS_DOORBELL_DISABLE_FAIL		BIT(13)
 
 #define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR	0x0c
 #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR	0x10
@@ -67,6 +74,10 @@
 #define PCI_ENDPOINT_TEST_IRQ_NUMBER		0x28
 
 #define PCI_ENDPOINT_TEST_FLAGS			0x2c
+#define PCI_ENDPOINT_TEST_DB_BAR		0x30
+#define PCI_ENDPOINT_TEST_DB_OFFSET		0x34
+#define PCI_ENDPOINT_TEST_DB_DATA		0x38
+
 #define FLAG_USE_DMA				BIT(0)
 
 #define PCI_DEVICE_ID_TI_AM654			0xb00c
@@ -108,6 +119,7 @@ enum pci_barno {
 	BAR_3,
 	BAR_4,
 	BAR_5,
+	NO_BAR = -1,
 };
 
 struct pci_endpoint_test {
@@ -746,6 +758,71 @@ static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
 	return false;
 }
 
+static bool pci_endpoint_test_doorbell(struct pci_endpoint_test *test)
+{
+	struct pci_dev *pdev = test->pdev;
+	struct device *dev = &pdev->dev;
+	int irq_type = test->irq_type;
+	enum pci_barno bar;
+	u32 data, status;
+	u32 addr;
+
+	if (irq_type < IRQ_TYPE_INTX || irq_type > IRQ_TYPE_MSIX) {
+		dev_err(dev, "Invalid IRQ type option\n");
+		return false;
+	}
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
+				 COMMAND_ENABLE_DOORBELL);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+	if (status & STATUS_DOORBELL_ENABLE_FAIL) {
+		dev_err(dev, "Failed to enable doorbell\n");
+		return false;
+	}
+
+	data = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_DATA);
+	addr = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_OFFSET);
+	bar = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_BAR);
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS, 0);
+
+	bar = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_BAR);
+
+	writel(data, test->bar[bar] + addr);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+
+	if (!(status & STATUS_DOORBELL_SUCCESS))
+		dev_err(dev, "Endpoint have not received Doorbell\n");
+
+	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
+				 COMMAND_DISABLE_DOORBELL);
+
+	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
+
+	status |= pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
+
+	if (status & STATUS_DOORBELL_DISABLE_FAIL) {
+		dev_err(dev, "Failed to disable doorbell\n");
+		return false;
+	}
+
+	if (!(status & STATUS_DOORBELL_SUCCESS))
+		return false;
+
+	return true;
+}
+
 static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 				    unsigned long arg)
 {
@@ -793,6 +870,9 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 	case PCITEST_CLEAR_IRQ:
 		ret = pci_endpoint_test_clear_irq(test);
 		break;
+	case PCITEST_DOORBELL:
+		ret = pci_endpoint_test_doorbell(test);
+		break;
 	}
 
 ret:
diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h
index 94b46b043b536..b82e7f2ed937d 100644
--- a/include/uapi/linux/pcitest.h
+++ b/include/uapi/linux/pcitest.h
@@ -20,6 +20,7 @@
 #define PCITEST_MSIX		_IOW('P', 0x7, int)
 #define PCITEST_SET_IRQTYPE	_IOW('P', 0x8, int)
 #define PCITEST_GET_IRQTYPE	_IO('P', 0x9)
+#define PCITEST_DOORBELL	_IO('P', 0xa)
 #define PCITEST_CLEAR_IRQ	_IO('P', 0x10)
 
 #define PCITEST_FLAGS_USE_DMA	0x00000001

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 18 15:08:35 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:35 -0500
Subject: [PATCH v13 0/9] PCI: EP: Add RC-to-EP doorbell with platform MSI
 controller
Message-ID: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>

??????????????   ?????????????????????????????????????   ??????????????????
?            ?   ?                                   ?   ?                ?
?            ?   ? PCI Endpoint                      ?   ? PCI Host       ?
?            ?   ?                                   ?   ?                ?
?            ????? 1.platform_msi_domain_alloc_irqs()?   ?                ?
?            ?   ?                                   ?   ?                ?
? MSI        ????? 2.write_msi_msg()                 ??????BAR<n>         ?
? Controller ?   ?   update doorbell register address?   ?                ?
?            ?   ?   for BAR                         ?   ?                ?
?            ?   ?                                   ?   ? 3. Write BAR<n>?
?            ?????????????????????????????????????????????                ?
?            ?   ?                                   ?   ?                ?
?            ????? 4.Irq Handle                      ?   ?                ?
?            ?   ?                                   ?   ?                ?
?            ?   ?                                   ?   ?                ?
??????????????   ?????????????????????????????????????   ??????????????????

This patches based on old https://lore.kernel.org/imx/20221124055036.1630573-1-Frank.Li at nxp.com/

Original patch only target to vntb driver. But actually it is common
method.

This patches add new API to pci-epf-core, so any EP driver can use it.

Previous v2 discussion here.
https://lore.kernel.org/imx/20230911220920.1817033-1-Frank.Li at nxp.com/

Changes in v13:
- Change to use DOMAIN_BUS_PCI_DEVICE_EP_MSI
- Change request id as  func | vfunc << 3
- Remove IRQ_DOMAIN_MSI_IMMUTABLE

Thomas Gleixner:

I hope capture all your points in review comments. If missed, let me know.

- Link to v12: https://lore.kernel.org/r/20241211-ep-msi-v12-0-33d4532fa520 at nxp.com

Changes in v12:
- Change to use IRQ_DOMAIN_MSI_IMMUTABLE and add help function
irq_domain_msi_is_immuatble().
- split PCI: endpoint: pci-ep-msi: Add MSI address/data pair mutable check to 3 patches
- Link to v11: https://lore.kernel.org/r/20241209-ep-msi-v11-0-7434fa8397bd at nxp.com

Changes in v11:
- Change to use MSI_FLAG_MSG_IMMUTABLE
- Link to v10: https://lore.kernel.org/r/20241204-ep-msi-v10-0-87c378dbcd6d at nxp.com

Changes in v10:

Thomas Gleixner:
	There are big change in pci-ep-msi.c. I am sure if go on the
corrent path. The key improvement is remove only 1 function devices's
limitation.

	I use new patch for imutable check, which relative additional
feature compared to base enablement patch.

- Remove patch Add msi_remove_device_irq_domain() in platform_device_msi_free_irqs_all()
- Add new patch irqchip/gic-v3-its: Avoid overwriting msi_prepare callback if provided by msi_domain_info
- Remove only support 1 endpoint function limiation.
- Create one MSI domain for each endpoint function devices.
- Use "msi-map" in pci ep controler node, instead of of msi-parent. first
argument is
	(func_no << 8 | vfunc_no)

- Link to v9: https://lore.kernel.org/r/20241203-ep-msi-v9-0-a60dbc3f15dd at nxp.com

Changes in v9
- Add patch platform-msi: Add msi_remove_device_irq_domain() in platform_device_msi_free_irqs_all()
- Remove patch PCI: endpoint: Add pci_epc_get_fn() API for customizable filtering
- Remove API pci_epf_align_inbound_addr_lo_hi
- Move doorbell_alloc in to doorbell_enable function.
- Link to v8: https://lore.kernel.org/r/20241116-ep-msi-v8-0-6f1f68ffd1bb at nxp.com

Changes in v8:
- update helper function name to pci_epf_align_inbound_addr()
- Link to v7: https://lore.kernel.org/r/20241114-ep-msi-v7-0-d4ac7aafbd2c at nxp.com

Changes in v7:
- Add helper function pci_epf_align_addr();
- Link to v6: https://lore.kernel.org/r/20241112-ep-msi-v6-0-45f9722e3c2a at nxp.com

Changes in v6:
- change doorbell_addr to doorbell_offset
- use round_down()
- add Niklas's test by tag
- rebase to pci/endpoint
- Link to v5: https://lore.kernel.org/r/20241108-ep-msi-v5-0-a14951c0d007 at nxp.com

Changes in v5:
- Move request_irq to epf test function driver for more flexiable user case
- Add fixed size bar handler
- Some minor improvememtn to see each patches's changelog.
- Link to v4: https://lore.kernel.org/r/20241031-ep-msi-v4-0-717da2d99b28 at nxp.com

Changes in v4:
- Remove patch genirq/msi: Add cleanup guard define for msi_lock_descs()/msi_unlock_descs()
- Use new method to avoid compatible problem.
  Add new command DOORBELL_ENABLE and DOORBELL_DISABLE.
  pcitest -B send DOORBELL_ENABLE first, EP test function driver try to
remap one of BAR_N (except test register bar) to ITS MSI MMIO space. Old
driver don't support new command, so failure return, not side effect.
  After test, DOORBELL_DISABLE command send out to recover original map, so
pcitest bar test can pass as normal.
- Other detail change see each patches's change log
- Link to v3: https://lore.kernel.org/r/20241015-ep-msi-v3-0-cedc89a16c1a at nxp.com

Change from v2 to v3
- Fixed manivannan's comments
- Move common part to pci-ep-msi.c and pci-ep-msi.h
- rebase to 6.12-rc1
- use RevID to distingiush old version

mkdir /sys/kernel/config/pci_ep/functions/pci_epf_test/func1
echo 16 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/msi_interrupts
echo 0x080c > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/deviceid
echo 0x1957 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/vendorid
echo 1 > /sys/kernel/config/pci_ep/functions/pci_epf_test/func1/revid
^^^^^^ to enable platform msi support.
ln -s /sys/kernel/config/pci_ep/functions/pci_epf_test/func1 /sys/kernel/config/pci_ep/controllers/4c380000.pcie-ep

- use new device ID, which identify support doorbell to avoid broken
compatility.

    Enable doorbell support only for PCI_DEVICE_ID_IMX8_DB, while other devices
    keep the same behavior as before.

           EP side             RC with old driver      RC with new driver
    PCI_DEVICE_ID_IMX8_DB          no probe              doorbell enabled
    Other device ID             doorbell disabled*       doorbell disabled*

    * Behavior remains unchanged.

Change from v1 to v2
- Add missed patch for endpont/pci-epf-test.c
- Move alloc and free to epc driver from epf.
- Provide general help function for EPC driver to alloc platform msi irq.
- Fixed manivannan's comments.

To: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
To: Krzysztof Wilczy?ski <kw at linux.com>
To: Kishon Vijay Abraham I <kishon at kernel.org>
To: Bjorn Helgaas <bhelgaas at google.com>
To: Arnd Bergmann <arnd at arndb.de>
To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: linux-kernel at vger.kernel.org
Cc: linux-pci at vger.kernel.org
Cc: imx at lists.linux.dev
Cc: Niklas Cassel <cassel at kernel.org>
Cc: dlemoal at kernel.org
Cc: jdmason at kudzu.us
To: Rafael J. Wysocki <rafael at kernel.org>
To: Thomas Gleixner <tglx at linutronix.de>
To: Anup Patel <apatel at ventanamicro.com>
To: Kishon Vijay Abraham I <kishon at kernel.org>
To: Marc Zyngier <maz at kernel.org>
To: Thomas Gleixner <tglx at linutronix.de>
Cc: linux-arm-kernel at lists.infradead.org

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Frank Li (9):
      genirq/msi: Provide DOMAIN_BUS_PLATFORM_PCI_EP_MSI
      PCI: EP: Add helper function pci_epf_msi_domain_get_msi_rid()
      irqchip/gic-v3-its: Add helper function its_pmsi_prepare_devid()
      irqchip/gic-v3-its: Add DOMAIN_BUS_DEVICE_PCI_EP_MSI support
      PCI: endpoint: Add RC-to-EP doorbell support using platform MSI controller
      PCI: endpoint: Add pci_epf_align_inbound_addr() helper for address alignment
      PCI: endpoint: pci-epf-test: Add doorbell test support
      misc: pci_endpoint_test: Add doorbell test case
      tools: PCI: Add 'B' option for test doorbell

 drivers/irqchip/irq-gic-v3-its-msi-parent.c   |  49 ++++++---
 drivers/irqchip/irq-msi-lib.c                 |   4 +
 drivers/irqchip/irq-msi-lib.h                 |   6 ++
 drivers/misc/pci_endpoint_test.c              |  80 +++++++++++++++
 drivers/pci/endpoint/Makefile                 |   2 +-
 drivers/pci/endpoint/functions/pci-epf-test.c | 132 ++++++++++++++++++++++++
 drivers/pci/endpoint/pci-ep-msi.c             | 140 ++++++++++++++++++++++++++
 drivers/pci/endpoint/pci-epf-core.c           |  44 ++++++++
 include/linux/irqdomain_defs.h                |   2 +
 include/linux/pci-ep-msi.h                    |  26 +++++
 include/linux/pci-epf.h                       |  19 ++++
 include/uapi/linux/pcitest.h                  |   1 +
 tools/pci/pcitest.c                           |  16 ++-
 13 files changed, 507 insertions(+), 14 deletions(-)
---
base-commit: fb32deaabac5c9ac8e555fad420113348cea8bc2
change-id: 20241010-ep-msi-8b4cab33b1be

Best regards,
---
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Wed Dec 18 15:08:36 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:36 -0500
Subject: [PATCH v13 1/9] genirq/msi: Provide DOMAIN_BUS_PLATFORM_PCI_EP_MSI
In-Reply-To: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
Message-ID: <20241218-ep-msi-v13-1-646e2192dc24@nxp.com>

           ??????????????????????????????????
           ?                                ?
           ?     PCI Endpoint Controller    ?
           ?                                ?
           ?   ???????  ???????     ??????? ?
PCI Bus    ?   ?     ?  ?     ?     ?     ? ?
?????????? ?   ?Func1?  ?Func2? ... ?Func ? ?
Doorbell   ?   ?     ?  ?     ?     ?<n>  ? ?
           ?   ?     ?  ?     ?     ?     ? ?
           ?   ???????  ???????     ??????? ?
           ?      ?        ?           ?    ?
           ??????????????????????????????????
                  ?        ?           ?
                  ?        ?           ?
               ??????????????????????????
               ?    MSI Controller      ?
               ??????????????????????????

Add domain BUS_PLATFORM_PCI_EP_MSI to allocate MSI domain for Endpoint
function in PCI Endpoint (EP) controller, So PCI Root Complex (RC) can
write MSI message to MSI controller to trigger doorbell IRQ for difference
EP functions.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
change from v12 to v13
- new patch
---
 drivers/irqchip/irq-msi-lib.c  | 4 ++++
 drivers/irqchip/irq-msi-lib.h  | 6 ++++++
 include/linux/irqdomain_defs.h | 2 ++
 3 files changed, 12 insertions(+)

diff --git a/drivers/irqchip/irq-msi-lib.c b/drivers/irqchip/irq-msi-lib.c
index d8e29fc0d4068..cf39f2e481477 100644
--- a/drivers/irqchip/irq-msi-lib.c
+++ b/drivers/irqchip/irq-msi-lib.c
@@ -57,6 +57,10 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 			return false;
 
 		break;
+	case DOMAIN_BUS_DEVICE_PCI_EP_MSI:
+		if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_PCI_ENDPOINT)))
+			return false;
+		fallthrough;
 	case DOMAIN_BUS_DEVICE_MSI:
 		/*
 		 * Per device MSI should never have any MSI feature bits
diff --git a/drivers/irqchip/irq-msi-lib.h b/drivers/irqchip/irq-msi-lib.h
index 681ceabb7bc74..5ccfdb14fce1d 100644
--- a/drivers/irqchip/irq-msi-lib.h
+++ b/drivers/irqchip/irq-msi-lib.h
@@ -17,6 +17,12 @@
 
 #define MATCH_PLATFORM_MSI	BIT(DOMAIN_BUS_PLATFORM_MSI)
 
+#ifdef CONFIG_PCI_ENDPOINT
+#define MATCH_PLATFORM_PCI_EP_MSI	BIT(DOMAIN_BUS_PLATFORM_PCI_EP_MSI)
+#else
+#define MATCH_PLATFORM_PCI_EP_MSI	(0)
+#endif
+
 int msi_lib_irq_domain_select(struct irq_domain *d, struct irq_fwspec *fwspec,
 			      enum irq_domain_bus_token bus_token);
 
diff --git a/include/linux/irqdomain_defs.h b/include/linux/irqdomain_defs.h
index 36653e2ee1c92..feecbc27c2575 100644
--- a/include/linux/irqdomain_defs.h
+++ b/include/linux/irqdomain_defs.h
@@ -15,6 +15,7 @@ enum irq_domain_bus_token {
 	DOMAIN_BUS_GENERIC_MSI,
 	DOMAIN_BUS_PCI_MSI,
 	DOMAIN_BUS_PLATFORM_MSI,
+	DOMAIN_BUS_PLATFORM_PCI_EP_MSI,
 	DOMAIN_BUS_NEXUS,
 	DOMAIN_BUS_IPI,
 	DOMAIN_BUS_FSL_MC_MSI,
@@ -27,6 +28,7 @@ enum irq_domain_bus_token {
 	DOMAIN_BUS_AMDVI,
 	DOMAIN_BUS_DEVICE_MSI,
 	DOMAIN_BUS_WIRED_TO_MSI,
+	DOMAIN_BUS_DEVICE_PCI_EP_MSI,
 };
 
 #endif /* _LINUX_IRQDOMAIN_DEFS_H */

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 18 15:08:37 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:37 -0500
Subject: [PATCH v13 2/9] PCI: EP: Add helper function
 pci_epf_msi_domain_get_msi_rid()
In-Reply-To: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
Message-ID: <20241218-ep-msi-v13-2-646e2192dc24@nxp.com>

Add helper function pci_epf_msi_domain_get_msi_rid() to convert EP device
id to msi domain's request ID to pave the road to support RC-to-EP doorbell
with platform MSI controller.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
change from v12 to v13
- new patch
---
 drivers/pci/endpoint/Makefile     |  2 +-
 drivers/pci/endpoint/pci-ep-msi.c | 36 ++++++++++++++++++++++++++++++++++++
 include/linux/pci-ep-msi.h        | 21 +++++++++++++++++++++
 3 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/endpoint/Makefile b/drivers/pci/endpoint/Makefile
index 95b2fe47e3b06..a1ccce440c2c5 100644
--- a/drivers/pci/endpoint/Makefile
+++ b/drivers/pci/endpoint/Makefile
@@ -5,4 +5,4 @@
 
 obj-$(CONFIG_PCI_ENDPOINT_CONFIGFS)	+= pci-ep-cfs.o
 obj-$(CONFIG_PCI_ENDPOINT)		+= pci-epc-core.o pci-epf-core.o\
-					   pci-epc-mem.o functions/
+					   pci-epc-mem.o pci-ep-msi.o functions/
diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
new file mode 100644
index 0000000000000..7aedc1cafbd14
--- /dev/null
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCI Endpoint *Controller* (EPC) MSI library
+ *
+ * Copyright (C) 2024 NXP
+ * Author: Frank Li <Frank.Li at nxp.com>
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/pci-epc.h>
+#include <linux/pci-epf.h>
+#include <linux/pci-ep-cfs.h>
+#include <linux/pci-ep-msi.h>
+#include <linux/slab.h>
+
+int pci_epf_msi_domain_get_msi_rid(struct device *dev, u32 *rid)
+{
+	struct pci_epf *epf = to_pci_epf(dev);
+	struct pci_epc *epc = epf->epc;
+
+	if (!rid)
+		return -EINVAL;
+
+	/*
+	 * PCI Endpoint device ID can't full reuse PCI's BDF, BUS number is
+	 * Root Complex Bus number, which is no means for EP side. Move func_no
+	 * as low 3 bits to partially match PCI's BDF.
+	 */
+	*rid = of_msi_map_id(epc->dev.parent, NULL, (epf->func_no & 0x7) | (epf->vfunc_no << 3));
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_msi_domain_get_msi_rid);
diff --git a/include/linux/pci-ep-msi.h b/include/linux/pci-ep-msi.h
new file mode 100644
index 0000000000000..75236867426a4
--- /dev/null
+++ b/include/linux/pci-ep-msi.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PCI Endpoint *Function* side MSI header file
+ *
+ * Copyright (C) 2024 NXP
+ * Author: Frank Li <Frank.Li at nxp.com>
+ */
+
+#ifndef __PCI_EP_MSI__
+#define __PCI_EP_MSI__
+
+#ifdef CONFIG_PCI_ENDPOINT
+int pci_epf_msi_domain_get_msi_rid(struct device *dev, u32 *rid);
+#else
+static inline int pci_epf_msi_domain_get_msi_rid(struct device *dev, u32 *rid)
+{
+	return -EINVAL;
+}
+#endif
+
+#endif /* __PCI_EP_MSI__ */

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 18 15:08:38 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:38 -0500
Subject: [PATCH v13 3/9] irqchip/gic-v3-its: Add helper function
 its_pmsi_prepare_devid()
In-Reply-To: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
Message-ID: <20241218-ep-msi-v13-3-646e2192dc24@nxp.com>

Add helper function its_pmsi_prepare_devid() to pave road to support new
DOMAIN_BUS_DEVICE_PCI_EP_MSI. No function change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
change from v12 to v13
- new patch
---
 drivers/irqchip/irq-gic-v3-its-msi-parent.c | 30 ++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
index 75aa0d4bd1346..b2a4b67545b82 100644
--- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
@@ -132,19 +132,10 @@ int __weak iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
 	return -1;
 }
 
-static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
-			    int nvec, msi_alloc_info_t *info)
+static int its_pmsi_prepare_devid(struct irq_domain *domain, struct device *dev,
+				  int nvec, msi_alloc_info_t *info, u32 dev_id)
 {
 	struct msi_domain_info *msi_info;
-	u32 dev_id;
-	int ret;
-
-	if (dev->of_node)
-		ret = of_pmsi_get_dev_id(domain->parent, dev, &dev_id);
-	else
-		ret = iort_pmsi_get_dev_id(dev, &dev_id);
-	if (ret)
-		return ret;
 
 	/* ITS specific DeviceID, as the core ITS ignores dev. */
 	info->scratchpad[0].ul = dev_id;
@@ -165,6 +156,23 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
 					  dev, nvec, info);
 }
 
+static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
+			    int nvec, msi_alloc_info_t *info)
+{
+	u32 dev_id;
+	int ret;
+
+	if (dev->of_node)
+		ret = of_pmsi_get_dev_id(domain->parent, dev, &dev_id);
+	else
+		ret = iort_pmsi_get_dev_id(dev, &dev_id);
+
+	if (ret)
+		return ret;
+
+	return its_pmsi_prepare_devid(domain, dev, nvec, info, dev_id);
+}
+
 static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 				  struct irq_domain *real_parent, struct msi_domain_info *info)
 {

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 18 15:08:39 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:39 -0500
Subject: [PATCH v13 4/9] irqchip/gic-v3-its: Add
 DOMAIN_BUS_DEVICE_PCI_EP_MSI support
In-Reply-To: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
Message-ID: <20241218-ep-msi-v13-4-646e2192dc24@nxp.com>

           ??????????????????????????????????
           ?                                ?
           ?     PCI Endpoint Controller    ?
           ?                                ?
           ?   ???????  ???????     ??????? ?
PCI Bus    ?   ?     ?  ?     ?     ?     ? ?
?????????? ?   ?Func1?  ?Func2? ... ?Func ? ?
Doorbell   ?   ?     ?  ?     ?     ?<n>  ? ?
           ?   ?     ?  ?     ?     ?     ? ?
           ?   ???????  ???????     ??????? ?
           ?      ?        ?           ?    ?
           ??????????????????????????????????
                  ?        ?           ?
                  ?        ?           ?
               ??????????????????????????
               ?    MSI Controller      ?
               ??????????????????????????

Add domain DOMAIN_BUS_DEVICE_PCI_EP_MSI to allocate MSI domain for Endpoint
function in PCI Endpoint (EP) controller, So PCI Root Complex (RC) can
write MSI message to MSI controller to trigger doorbell IRQ for difference
EP functions.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
change from v12 to v13
- new patch
---
 drivers/irqchip/irq-gic-v3-its-msi-parent.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
index b2a4b67545b82..16e7d53f0b133 100644
--- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
@@ -5,6 +5,7 @@
 // Copyright (C) 2022 Intel
 
 #include <linux/acpi_iort.h>
+#include <linux/pci-ep-msi.h>
 #include <linux/pci.h>
 
 #include "irq-gic-common.h"
@@ -173,6 +174,19 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
 	return its_pmsi_prepare_devid(domain, dev, nvec, info, dev_id);
 }
 
+static int its_pci_ep_msi_prepare(struct irq_domain *domain, struct device *dev,
+				  int nvec, msi_alloc_info_t *info)
+{
+	u32 dev_id;
+	int ret;
+
+	ret = pci_epf_msi_domain_get_msi_rid(dev, &dev_id);
+	if (ret)
+		return ret;
+
+	return its_pmsi_prepare_devid(domain, dev, nvec, info, dev_id);
+}
+
 static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 				  struct irq_domain *real_parent, struct msi_domain_info *info)
 {
@@ -205,6 +219,9 @@ static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 		 */
 		info->ops->msi_prepare = its_pmsi_prepare;
 		break;
+	case DOMAIN_BUS_DEVICE_PCI_EP_MSI:
+		info->ops->msi_prepare = its_pci_ep_msi_prepare;
+		break;
 	default:
 		/* Confused. How did the lib return true? */
 		WARN_ON_ONCE(1);
@@ -218,7 +235,7 @@ const struct msi_parent_ops gic_v3_its_msi_parent_ops = {
 	.supported_flags	= ITS_MSI_FLAGS_SUPPORTED,
 	.required_flags		= ITS_MSI_FLAGS_REQUIRED,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
-	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
+	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI | MATCH_PLATFORM_PCI_EP_MSI,
 	.prefix			= "ITS-",
 	.init_dev_msi_info	= its_init_dev_msi_info,
 };

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 18 15:08:40 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:40 -0500
Subject: [PATCH v13 5/9] PCI: endpoint: Add RC-to-EP doorbell support using
 platform MSI controller
In-Reply-To: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
Message-ID: <20241218-ep-msi-v13-5-646e2192dc24@nxp.com>

Doorbell feature is implemented by mapping the EP's MSI interrupt
controller message address to a dedicated BAR in the EPC core. It is the
responsibility of the EPF driver to pass the actual message data to be
written by the host to the doorbell BAR region through its own logic.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v12 to v13
- Use DOMAIN_BUS_DEVICE_PCI_EP_MSI

Change from v10 to v12
- none

Change from v9 to v10
- Create msi domain for each function device.
- Remove only function support limiation. My hardware only support one
function, so not test more than one case.
- use "msi-map" descript msi information

  msi-map = <func_no << 8  | vfunc_no, &its, start_stream_id,  size>;

Chagne from v8 to v9
- sort header file
- use pci_epc_get(dev_name(msi_desc_to_dev(desc)));
- check epf number at pci_epf_alloc_doorbell
- Add comments for miss msi-parent case

change from v5 to v8
-none

Change from v4 to v5
- Remove request_irq() in pci_epc_alloc_doorbell() and leave to EP function
driver, so ep function driver can register differece call back function for
difference doorbell events and set irq affinity to differece CPU core.
- Improve error message when MSI allocate failure.

Change from v3 to v4
- msi change to use msi_get_virq() avoid use msi_for_each_desc().
- add new struct for pci_epf_doorbell_msg to msi msg,virq and irq name.
- move mutex lock to epc function
- initialize variable at declear place.
- passdown epf to epc*() function to simplify code.
---
 drivers/pci/endpoint/pci-ep-msi.c | 104 ++++++++++++++++++++++++++++++++++++++
 include/linux/pci-ep-msi.h        |   5 ++
 include/linux/pci-epf.h           |  16 ++++++
 3 files changed, 125 insertions(+)

diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
index 7aedc1cafbd14..33503d86cf2bc 100644
--- a/drivers/pci/endpoint/pci-ep-msi.c
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -34,3 +34,107 @@ int pci_epf_msi_domain_get_msi_rid(struct device *dev, u32 *rid)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pci_epf_msi_domain_get_msi_rid);
+
+static void pci_epf_write_msi_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	struct msi_desc *desc = irq_data_get_msi_desc(d);
+	struct pci_epf *epf = to_pci_epf(desc->dev);
+
+	if (epf && epf->db_msg && desc->msi_index < epf->num_db)
+		memcpy(&epf->db_msg[desc->msi_index].msg, msg, sizeof(*msg));
+}
+
+static void pci_epf_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+	arg->desc = desc;
+	arg->hwirq = desc->msi_index;
+}
+
+static const struct msi_domain_template pci_epf_msi_template = {
+	.chip = {
+		.name			= "EP-MSI",
+		.irq_mask		= irq_chip_mask_parent,
+		.irq_unmask		= irq_chip_unmask_parent,
+		.irq_write_msi_msg	= pci_epf_write_msi_msg,
+		/* The rest is filled in by the MSI parent */
+	},
+
+	.ops = {
+		.set_desc		= pci_epf_msi_set_desc,
+	},
+
+	.info = {
+		.bus_token		= DOMAIN_BUS_DEVICE_PCI_EP_MSI,
+	},
+};
+
+static int pci_epf_device_msi_init_and_alloc_irqs(struct device *dev, unsigned int nvec)
+{
+	struct irq_domain *domain = dev->msi.domain;
+
+	if (!domain)
+		return -EINVAL;
+
+	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN,
+					  &pci_epf_msi_template, nvec, NULL, NULL))
+		return -ENODEV;
+
+	return msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, nvec - 1);
+}
+
+int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
+{
+	struct pci_epc *epc = epf->epc;
+	struct device *dev = &epf->dev;
+	struct irq_domain *dom;
+	void *msg;
+	u32 rid;
+	int ret;
+	int i;
+
+	rid = (epf->func_no & 0x7) | (epf->vfunc_no << 3);
+	dom = of_msi_map_get_device_domain(epc->dev.parent, rid, DOMAIN_BUS_PLATFORM_PCI_EP_MSI);
+	if (!dom) {
+		dev_err(dev, "Can't find msi domain\n");
+		return -EINVAL;
+	}
+
+	dev_set_msi_domain(dev, dom);
+
+	msg = kcalloc(num_db, sizeof(struct pci_epf_doorbell_msg), GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	epf->num_db = num_db;
+	epf->db_msg = msg;
+
+	ret = pci_epf_device_msi_init_and_alloc_irqs(dev, num_db);
+	if (ret) {
+		/*
+		 * The pcie_ep DT node has to specify 'msi-parent' for EP
+		 * doorbell support to work. Right now only GIC ITS is
+		 * supported. If you have GIC ITS and reached this print,
+		 * perhaps you are missing 'msi-map' in DT.
+		 */
+		dev_err(dev, "Failed to allocate MSI\n");
+		kfree(msg);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < num_db; i++)
+		epf->db_msg[i].virq = msi_get_virq(dev, i);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epf_alloc_doorbell);
+
+void pci_epf_free_doorbell(struct pci_epf *epf)
+{
+	msi_domain_free_irqs_all(&epf->dev, MSI_DEFAULT_DOMAIN);
+	msi_remove_device_irq_domain(&epf->dev, MSI_DEFAULT_DOMAIN);
+
+	kfree(epf->db_msg);
+	epf->db_msg = NULL;
+	epf->num_db = 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_free_doorbell);
diff --git a/include/linux/pci-ep-msi.h b/include/linux/pci-ep-msi.h
index 75236867426a4..26b1c86893ee4 100644
--- a/include/linux/pci-ep-msi.h
+++ b/include/linux/pci-ep-msi.h
@@ -18,4 +18,9 @@ static inline int pci_epf_msi_domain_get_msi_rid(struct device *dev, u32 *rid)
 }
 #endif
 
+struct pci_epf;
+
+int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 nums);
+void pci_epf_free_doorbell(struct pci_epf *epf);
+
 #endif /* __PCI_EP_MSI__ */
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 18a3aeb62ae4e..5374e6515ffa0 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -12,6 +12,7 @@
 #include <linux/configfs.h>
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <linux/msi.h>
 #include <linux/pci.h>
 
 struct pci_epf;
@@ -125,6 +126,17 @@ struct pci_epf_bar {
 	int		flags;
 };
 
+/**
+ * struct pci_epf_doorbell_msg - represents doorbell message
+ * @msi_msg: MSI message
+ * @virq: irq number of this doorbell MSI message
+ * @name: irq name for doorbell interrupt
+ */
+struct pci_epf_doorbell_msg {
+	struct msi_msg msg;
+	int virq;
+};
+
 /**
  * struct pci_epf - represents the PCI EPF device
  * @dev: the PCI EPF device
@@ -152,6 +164,8 @@ struct pci_epf_bar {
  * @vfunction_num_map: bitmap to manage virtual function number
  * @pci_vepf: list of virtual endpoint functions associated with this function
  * @event_ops: Callbacks for capturing the EPC events
+ * @db_msg: data for MSI from RC side
+ * @num_db: number of doorbells
  */
 struct pci_epf {
 	struct device		dev;
@@ -182,6 +196,8 @@ struct pci_epf {
 	unsigned long		vfunction_num_map;
 	struct list_head	pci_vepf;
 	const struct pci_epc_event_ops *event_ops;
+	struct pci_epf_doorbell_msg *db_msg;
+	u16 num_db;
 };
 
 /**

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 18 15:08:41 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:41 -0500
Subject: [PATCH v13 6/9] PCI: endpoint: Add pci_epf_align_inbound_addr()
 helper for address alignment
In-Reply-To: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
Message-ID: <20241218-ep-msi-v13-6-646e2192dc24@nxp.com>

Introduce the helper function pci_epf_align_inbound_addr() to adjust
addresses according to PCI BAR alignment requirements, converting addresses
into base and offset values.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change form v9 to v13
- none

change from v8 to v9
- pci_epf_align_inbound_addr(), base and off must be not NULL
- rm pci_epf_align_inbound_addr_lo_hi()

change from v7 to v8
- change name to pci_epf_align_inbound_addr()
- update comment said only need for memory, which not allocated by
pci_epf_alloc_space().

change from v6 to v7
- new patch
---
 drivers/pci/endpoint/pci-epf-core.c | 44 +++++++++++++++++++++++++++++++++++++
 include/linux/pci-epf.h             |  3 +++
 2 files changed, 47 insertions(+)

diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 8fa2797d4169a..d7a80f9c1e661 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -464,6 +464,50 @@ struct pci_epf *pci_epf_create(const char *name)
 }
 EXPORT_SYMBOL_GPL(pci_epf_create);
 
+/**
+ * pci_epf_align_inbound_addr() - Get base address and offset that match BAR's
+ *			  alignment requirement
+ * @epf: the EPF device
+ * @addr: the address of the memory
+ * @bar: the BAR number corresponding to map addr
+ * @base: return base address, which match BAR's alignment requirement.
+ * @off: return offset.
+ *
+ * Helper function to convert input 'addr' to base and offset, which match
+ * BAR's alignment requirement.
+ *
+ * The pci_epf_alloc_space() function already accounts for alignment. This is
+ * primarily intended for use with other memory regions not allocated by
+ * pci_epf_alloc_space(), such as peripheral register spaces or the trigger
+ * address for a platform MSI controller.
+ */
+int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
+			       u64 addr, u64 *base, size_t *off)
+{
+	const struct pci_epc_features *epc_features;
+	u64 align;
+
+	if (!base || !off)
+		return -EINVAL;
+
+	epc_features = pci_epc_get_features(epf->epc, epf->func_no, epf->vfunc_no);
+	if (!epc_features) {
+		dev_err(&epf->dev, "epc_features not implemented\n");
+		return -EOPNOTSUPP;
+	}
+
+	align = epc_features->align;
+	align = align ? align : 128;
+	if (epc_features->bar[bar].type == BAR_FIXED)
+		align = max(epc_features->bar[bar].fixed_size, align);
+
+	*base = round_down(addr, align);
+	*off = addr & (align - 1);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_align_inbound_addr);
+
 static void pci_epf_dev_release(struct device *dev)
 {
 	struct pci_epf *epf = to_pci_epf(dev);
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 5374e6515ffa0..2847d195433bf 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -238,6 +238,9 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
 			  enum pci_epc_interface_type type);
 void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
 			enum pci_epc_interface_type type);
+
+int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
+			       u64 addr, u64 *base, size_t *off);
 int pci_epf_bind(struct pci_epf *epf);
 void pci_epf_unbind(struct pci_epf *epf);
 int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 18 15:08:42 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:42 -0500
Subject: [PATCH v13 7/9] PCI: endpoint: pci-epf-test: Add doorbell test
 support
In-Reply-To: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
Message-ID: <20241218-ep-msi-v13-7-646e2192dc24@nxp.com>

Add three registers: doorbell_bar, doorbell_addr, and doorbell_data. Use
pci_epf_alloc_doorbell() to allocate a doorbell address space.

Enable the Root Complex (RC) side driver to trigger pci-epc-test's doorbell
callback handler by writing doorbell_data to the mapped doorbell_bar's
address space.

Set STATUS_DOORBELL_SUCCESS in the doorbell callback to indicate
completion.

Avoid breaking compatibility between host and endpoint, add new command
COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL. Host side need send
COMMAND_ENABLE_DOORBELL to map one bar's inbound address to MSI space.
the command COMMAND_DISABLE_DOORBELL to recovery original inbound address
mapping.

	 	Host side new driver	Host side old driver

EP: new driver      S				F
EP: old driver      F				F

S: If EP side support MSI, 'pcitest -B' return success.
   If EP side doesn't support MSI, the same to 'F'.

F: 'pcitest -B' return failure, other case as usual.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v9 to v13
- none

Change from v8 to v9
- move pci_epf_alloc_doorbell() into pci_epf_{enable/disable}_doorbell().
- remove doorbell_done in commit message.
- rename pci_epf_{enable/disable}_doorbell() to
pci_epf_test_{enable/disable}_doorbell() to align corrent code style.

Change from v7 to v8
- rename to pci_epf_align_inbound_addr_lo_hi()

Change from v6 to v7
- use help function pci_epf_align_addr_lo_hi()

Change from v5 to v6
- rename doorbell_addr to doorbell_offset

Chagne from v4 to v5
- Add doorbell free at unbind function.
- Move msi irq handler to here to more complex user case, such as differece
doorbell can use difference handler function.
- Add Niklas's code to handle fixed bar's case. If need add your signed-off
tag or co-developer tag, please let me know.

change from v3 to v4
- remove revid requirement
- Add command COMMAND_ENABLE_DOORBELL and COMMAND_DISABLE_DOORBELL.
- call pci_epc_set_bar() to map inbound address to MSI space only at
COMMAND_ENABLE_DOORBELL.
---
 drivers/pci/endpoint/functions/pci-epf-test.c | 132 ++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index ef6677f34116e..a0a0e86a081cb 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -11,12 +11,14 @@
 #include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/msi.h>
 #include <linux/slab.h>
 #include <linux/pci_ids.h>
 #include <linux/random.h>
 
 #include <linux/pci-epc.h>
 #include <linux/pci-epf.h>
+#include <linux/pci-ep-msi.h>
 #include <linux/pci_regs.h>
 
 #define IRQ_TYPE_INTX			0
@@ -29,6 +31,8 @@
 #define COMMAND_READ			BIT(3)
 #define COMMAND_WRITE			BIT(4)
 #define COMMAND_COPY			BIT(5)
+#define COMMAND_ENABLE_DOORBELL		BIT(6)
+#define COMMAND_DISABLE_DOORBELL	BIT(7)
 
 #define STATUS_READ_SUCCESS		BIT(0)
 #define STATUS_READ_FAIL		BIT(1)
@@ -39,6 +43,11 @@
 #define STATUS_IRQ_RAISED		BIT(6)
 #define STATUS_SRC_ADDR_INVALID		BIT(7)
 #define STATUS_DST_ADDR_INVALID		BIT(8)
+#define STATUS_DOORBELL_SUCCESS		BIT(9)
+#define STATUS_DOORBELL_ENABLE_SUCCESS	BIT(10)
+#define STATUS_DOORBELL_ENABLE_FAIL	BIT(11)
+#define STATUS_DOORBELL_DISABLE_SUCCESS BIT(12)
+#define STATUS_DOORBELL_DISABLE_FAIL	BIT(13)
 
 #define FLAG_USE_DMA			BIT(0)
 
@@ -74,6 +83,9 @@ struct pci_epf_test_reg {
 	u32	irq_type;
 	u32	irq_number;
 	u32	flags;
+	u32	doorbell_bar;
+	u32	doorbell_offset;
+	u32	doorbell_data;
 } __packed;
 
 static struct pci_epf_header test_header = {
@@ -642,6 +654,117 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test,
 	}
 }
 
+static irqreturn_t pci_epf_test_doorbell_handler(int irq, void *data)
+{
+	struct pci_epf_test *epf_test = data;
+	enum pci_barno test_reg_bar = epf_test->test_reg_bar;
+	struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
+
+	reg->status |= STATUS_DOORBELL_SUCCESS;
+	pci_epf_test_raise_irq(epf_test, reg);
+
+	return IRQ_HANDLED;
+}
+
+static void pci_epf_test_doorbell_cleanup(struct pci_epf_test *epf_test)
+{
+	struct pci_epf_test_reg *reg = epf_test->reg[epf_test->test_reg_bar];
+	struct pci_epf *epf = epf_test->epf;
+
+	if (reg->doorbell_bar > 0) {
+		free_irq(epf->db_msg[0].virq, epf_test);
+		reg->doorbell_bar = NO_BAR;
+	}
+
+	if (epf->db_msg)
+		pci_epf_free_doorbell(epf);
+}
+
+static void pci_epf_test_enable_doorbell(struct pci_epf_test *epf_test,
+					 struct pci_epf_test_reg *reg)
+{
+	struct pci_epf *epf = epf_test->epf;
+	struct pci_epf_bar db_bar = {};
+	struct pci_epc *epc = epf->epc;
+	struct msi_msg *msg;
+	enum pci_barno bar;
+	size_t offset;
+	int ret;
+
+	ret = pci_epf_alloc_doorbell(epf, 1);
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		return;
+	}
+
+	msg = &epf->db_msg[0].msg;
+	bar = pci_epc_get_next_free_bar(epf_test->epc_features, epf_test->test_reg_bar + 1);
+	if (bar < BAR_0 || bar == epf_test->test_reg_bar || !epf->db_msg) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		return;
+	}
+
+	ret = request_irq(epf->db_msg[0].virq, pci_epf_test_doorbell_handler, 0,
+			  "pci-test-doorbell", epf_test);
+	if (ret) {
+		dev_err(&epf->dev,
+			"Failed to request irq %d, doorbell feature is not supported\n",
+			epf->db_msg[0].virq);
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+		return;
+	}
+
+	reg->doorbell_data = msg->data;
+	reg->doorbell_bar = bar;
+
+	msg = &epf->db_msg[0].msg;
+	ret = pci_epf_align_inbound_addr(epf, bar, ((u64)msg->address_hi << 32) | msg->address_lo,
+					 &db_bar.phys_addr, &offset);
+
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+		return;
+	}
+
+	reg->doorbell_offset = offset;
+
+	db_bar.barno = bar;
+	db_bar.size = epf->bar[bar].size;
+	db_bar.flags = epf->bar[bar].flags;
+
+	ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &db_bar);
+	if (ret) {
+		reg->status |= STATUS_DOORBELL_ENABLE_FAIL;
+		pci_epf_test_doorbell_cleanup(epf_test);
+	} else {
+		reg->status |= STATUS_DOORBELL_ENABLE_SUCCESS;
+	}
+}
+
+static void pci_epf_test_disable_doorbell(struct pci_epf_test *epf_test,
+					  struct pci_epf_test_reg *reg)
+{
+	enum pci_barno bar = reg->doorbell_bar;
+	struct pci_epf *epf = epf_test->epf;
+	struct pci_epc *epc = epf->epc;
+	int ret;
+
+	if (bar < BAR_0 || bar == epf_test->test_reg_bar || !epf->db_msg) {
+		reg->status |= STATUS_DOORBELL_DISABLE_FAIL;
+		return;
+	}
+
+	ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &epf->bar[bar]);
+	if (ret)
+		reg->status |= STATUS_DOORBELL_DISABLE_FAIL;
+	else
+		reg->status |= STATUS_DOORBELL_DISABLE_SUCCESS;
+
+	pci_epf_test_doorbell_cleanup(epf_test);
+}
+
 static void pci_epf_test_cmd_handler(struct work_struct *work)
 {
 	u32 command;
@@ -688,6 +811,14 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 		pci_epf_test_copy(epf_test, reg);
 		pci_epf_test_raise_irq(epf_test, reg);
 		break;
+	case COMMAND_ENABLE_DOORBELL:
+		pci_epf_test_enable_doorbell(epf_test, reg);
+		pci_epf_test_raise_irq(epf_test, reg);
+		break;
+	case COMMAND_DISABLE_DOORBELL:
+		pci_epf_test_disable_doorbell(epf_test, reg);
+		pci_epf_test_raise_irq(epf_test, reg);
+		break;
 	default:
 		dev_err(dev, "Invalid command 0x%x\n", command);
 		break;
@@ -934,6 +1065,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
 		pci_epf_test_clean_dma_chan(epf_test);
 		pci_epf_test_clear_bar(epf);
 	}
+	pci_epf_test_doorbell_cleanup(epf_test);
 	pci_epf_test_free_space(epf);
 }
 

-- 
2.34.1



From Frank.Li at nxp.com  Wed Dec 18 15:08:44 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 18 Dec 2024 18:08:44 -0500
Subject: [PATCH v13 9/9] tools: PCI: Add 'B' option for test doorbell
In-Reply-To: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
Message-ID: <20241218-ep-msi-v13-9-646e2192dc24@nxp.com>

Add doorbell test support.

Tested-by: Niklas Cassel <cassel at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change from v3 to v13
- none
---
 tools/pci/pcitest.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 7b530d838d408..fcff0224a3381 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -34,6 +34,7 @@ struct pci_test {
 	bool		copy;
 	unsigned long	size;
 	bool		use_dma;
+	bool		doorbell;
 };
 
 static int run_test(struct pci_test *test)
@@ -147,6 +148,15 @@ static int run_test(struct pci_test *test)
 			fprintf(stdout, "%s\n", result[ret]);
 	}
 
+	if (test->doorbell) {
+		ret = ioctl(fd, PCITEST_DOORBELL, 0);
+		fprintf(stdout, "Ringing doorbell on the EP\t\t");
+		if (ret < 0)
+			fprintf(stdout, "TEST FAILED\n");
+		else
+			fprintf(stdout, "%s\n", result[ret]);
+	}
+
 	fflush(stdout);
 	close(fd);
 	return (ret < 0) ? ret : 1 - ret; /* return 0 if test succeeded */
@@ -172,7 +182,7 @@ int main(int argc, char **argv)
 	/* set default endpoint device */
 	test->device = "/dev/pci-endpoint-test.0";
 
-	while ((c = getopt(argc, argv, "D:b:m:x:i:deIlhrwcs:")) != EOF)
+	while ((c = getopt(argc, argv, "D:b:m:x:i:BdeIlhrwcs:")) != EOF)
 	switch (c) {
 	case 'D':
 		test->device = optarg;
@@ -222,6 +232,9 @@ int main(int argc, char **argv)
 	case 'd':
 		test->use_dma = true;
 		continue;
+	case 'B':
+		test->doorbell = true;
+		continue;
 	case 'h':
 	default:
 usage:
@@ -241,6 +254,7 @@ int main(int argc, char **argv)
 			"\t-w			Write buffer test\n"
 			"\t-c			Copy buffer test\n"
 			"\t-s <size>		Size of buffer {default: 100KB}\n"
+			"\t-B			Doorbell test\n"
 			"\t-h			Print this help message\n",
 			argv[0]);
 		return -EINVAL;

-- 
2.34.1



From apopple at nvidia.com  Wed Dec 18 15:11:32 2024
From: apopple at nvidia.com (Alistair Popple)
Date: Thu, 19 Dec 2024 10:11:32 +1100
Subject: [PATCH v4 19/25] proc/task_mmu: Ignore ZONE_DEVICE pages
In-Reply-To: <c7bd9b00-6920-4dc0-8e2e-36c16ef7ad5a@redhat.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <f3ebda542373feb70ed3e5d83b276a2e8347609f.1734407924.git-series.apopple@nvidia.com>
 <c7bd9b00-6920-4dc0-8e2e-36c16ef7ad5a@redhat.com>
Message-ID: <37rxl2bjda3psdknhboexhbg3hahf5ifmublp5fw7ltdoyqllc@udbz76jklmnu>

On Tue, Dec 17, 2024 at 11:31:25PM +0100, David Hildenbrand wrote:
> On 17.12.24 06:13, Alistair Popple wrote:
> > The procfs mmu files such as smaps currently ignore device dax and fs
> > dax pages because these pages are considered special. To maintain
> > existing behaviour once these pages are treated as normal pages and
> > returned from vm_normal_page() add tests to explicitly skip them.
> > 
> > Signed-off-by: Alistair Popple <apopple at nvidia.com>
> > ---
> >   fs/proc/task_mmu.c | 18 ++++++++++++++----
> >   1 file changed, 14 insertions(+), 4 deletions(-)
> > 
> > diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
> > index 38a5a3e..c9b227a 100644
> > --- a/fs/proc/task_mmu.c
> > +++ b/fs/proc/task_mmu.c
> > @@ -801,6 +801,8 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
> >   	if (pte_present(ptent)) {
> >   		page = vm_normal_page(vma, addr, ptent);
> > +		if (page && (is_device_dax_page(page) || is_fsdax_page(page)))
> 
> This "is_device_dax_page(page) || is_fsdax_page(page)" is a common theme
> here, likely we should have a special helper?

Sounds good, will add is_dax_page() if there are enough callers left after any
review comments.
 
> But, don't we actually want to include them in the smaps output now? I think
> we want.

I'm not an expert in what callers of vm_normal_page() think of as a "normal"
page. So my philosphy here was to ensure anything calling vm_normal_page()
didn't accidentally start seeing DAX pages, either by checking existing filters
(lots of callers already call vma_is_special_huge() or some equivalent) or
explicitly filtering them out in the hope someone smarter than me could tell me
it was unneccssary.

That stategy seems to have worked, and so I agree we likely do want them in
smaps. I just didn't want to silently do it without this kind of discussion
first.

> The rmap code will indicate these pages in /proc/meminfo, per-node info, in
> the memcg ... as "Mapped:" etc.
> 
> So likely we just want to also indicate them here, or is there any downsides
> we know of?

I don't know of any, and I think it makes sense to also indicate them so will
drop this check in the respin.

> -- 
> Cheers,
> 
> David / dhildenb
> 


From lkp at intel.com  Wed Dec 18 15:23:07 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 19 Dec 2024 07:23:07 +0800
Subject: [PATCH 09/18] KVM: arm64: Drop kvm_arm_pmu_available static key
In-Reply-To: <20241217212048.3709204-10-oliver.upton@linux.dev>
References: <20241217212048.3709204-10-oliver.upton@linux.dev>
Message-ID: <202412190743.1bLEb7Ps-lkp@intel.com>

Hi Oliver,

kernel test robot noticed the following build errors:

[auto build test ERROR on 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8]

url:    https://github.com/intel-lab-lkp/linux/commits/Oliver-Upton/drivers-perf-apple_m1-Refactor-event-select-filter-configuration/20241218-054416
base:   78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
patch link:    https://lore.kernel.org/r/20241217212048.3709204-10-oliver.upton%40linux.dev
patch subject: [PATCH 09/18] KVM: arm64: Drop kvm_arm_pmu_available static key
config: arm64-randconfig-001-20241219 (https://download.01.org/0day-ci/archive/20241219/202412190743.1bLEb7Ps-lkp at intel.com/config)
compiler: clang version 16.0.6 (https://github.com/llvm/llvm-project 7cbf1a2591520c2491aa35339f227775f4d3adf6)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241219/202412190743.1bLEb7Ps-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/202412190743.1bLEb7Ps-lkp at intel.com/

All errors (new ones prefixed by >>):

>> arch/arm64/kvm/arm.c:394:7: error: call to undeclared function 'kvm_supports_guest_pmuv3'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                   r = kvm_supports_guest_pmuv3();
                       ^
   arch/arm64/kvm/arm.c:1400:7: error: call to undeclared function 'kvm_supports_guest_pmuv3'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
           if (!kvm_supports_guest_pmuv3())
                ^
   2 errors generated.


vim +/kvm_supports_guest_pmuv3 +394 arch/arm64/kvm/arm.c

   309	
   310	int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
   311	{
   312		int r;
   313	
   314		if (kvm && kvm_vm_is_protected(kvm) && !pkvm_ext_allowed(kvm, ext))
   315			return 0;
   316	
   317		switch (ext) {
   318		case KVM_CAP_IRQCHIP:
   319			r = vgic_present;
   320			break;
   321		case KVM_CAP_IOEVENTFD:
   322		case KVM_CAP_USER_MEMORY:
   323		case KVM_CAP_SYNC_MMU:
   324		case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
   325		case KVM_CAP_ONE_REG:
   326		case KVM_CAP_ARM_PSCI:
   327		case KVM_CAP_ARM_PSCI_0_2:
   328		case KVM_CAP_READONLY_MEM:
   329		case KVM_CAP_MP_STATE:
   330		case KVM_CAP_IMMEDIATE_EXIT:
   331		case KVM_CAP_VCPU_EVENTS:
   332		case KVM_CAP_ARM_IRQ_LINE_LAYOUT_2:
   333		case KVM_CAP_ARM_NISV_TO_USER:
   334		case KVM_CAP_ARM_INJECT_EXT_DABT:
   335		case KVM_CAP_SET_GUEST_DEBUG:
   336		case KVM_CAP_VCPU_ATTRIBUTES:
   337		case KVM_CAP_PTP_KVM:
   338		case KVM_CAP_ARM_SYSTEM_SUSPEND:
   339		case KVM_CAP_IRQFD_RESAMPLE:
   340		case KVM_CAP_COUNTER_OFFSET:
   341			r = 1;
   342			break;
   343		case KVM_CAP_SET_GUEST_DEBUG2:
   344			return KVM_GUESTDBG_VALID_MASK;
   345		case KVM_CAP_ARM_SET_DEVICE_ADDR:
   346			r = 1;
   347			break;
   348		case KVM_CAP_NR_VCPUS:
   349			/*
   350			 * ARM64 treats KVM_CAP_NR_CPUS differently from all other
   351			 * architectures, as it does not always bound it to
   352			 * KVM_CAP_MAX_VCPUS. It should not matter much because
   353			 * this is just an advisory value.
   354			 */
   355			r = min_t(unsigned int, num_online_cpus(),
   356				  kvm_arm_default_max_vcpus());
   357			break;
   358		case KVM_CAP_MAX_VCPUS:
   359		case KVM_CAP_MAX_VCPU_ID:
   360			if (kvm)
   361				r = kvm->max_vcpus;
   362			else
   363				r = kvm_arm_default_max_vcpus();
   364			break;
   365		case KVM_CAP_MSI_DEVID:
   366			if (!kvm)
   367				r = -EINVAL;
   368			else
   369				r = kvm->arch.vgic.msis_require_devid;
   370			break;
   371		case KVM_CAP_ARM_USER_IRQ:
   372			/*
   373			 * 1: EL1_VTIMER, EL1_PTIMER, and PMU.
   374			 * (bump this number if adding more devices)
   375			 */
   376			r = 1;
   377			break;
   378		case KVM_CAP_ARM_MTE:
   379			r = system_supports_mte();
   380			break;
   381		case KVM_CAP_STEAL_TIME:
   382			r = kvm_arm_pvtime_supported();
   383			break;
   384		case KVM_CAP_ARM_EL1_32BIT:
   385			r = cpus_have_final_cap(ARM64_HAS_32BIT_EL1);
   386			break;
   387		case KVM_CAP_GUEST_DEBUG_HW_BPS:
   388			r = get_num_brps();
   389			break;
   390		case KVM_CAP_GUEST_DEBUG_HW_WPS:
   391			r = get_num_wrps();
   392			break;
   393		case KVM_CAP_ARM_PMU_V3:
 > 394			r = kvm_supports_guest_pmuv3();
   395			break;
   396		case KVM_CAP_ARM_INJECT_SERROR_ESR:
   397			r = cpus_have_final_cap(ARM64_HAS_RAS_EXTN);
   398			break;
   399		case KVM_CAP_ARM_VM_IPA_SIZE:
   400			r = get_kvm_ipa_limit();
   401			break;
   402		case KVM_CAP_ARM_SVE:
   403			r = system_supports_sve();
   404			break;
   405		case KVM_CAP_ARM_PTRAUTH_ADDRESS:
   406		case KVM_CAP_ARM_PTRAUTH_GENERIC:
   407			r = kvm_has_full_ptr_auth();
   408			break;
   409		case KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE:
   410			if (kvm)
   411				r = kvm->arch.mmu.split_page_chunk_size;
   412			else
   413				r = KVM_ARM_EAGER_SPLIT_CHUNK_SIZE_DEFAULT;
   414			break;
   415		case KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES:
   416			r = kvm_supported_block_sizes();
   417			break;
   418		case KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES:
   419			r = BIT(0);
   420			break;
   421		default:
   422			r = 0;
   423		}
   424	
   425		return r;
   426	}
   427	

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


From kw at linux.com  Wed Dec 18 16:04:00 2024
From: kw at linux.com (Krzysztof =?utf-8?Q?Wilczy=C5=84ski?=)
Date: Thu, 19 Dec 2024 09:04:00 +0900
Subject: [PATCH v3 0/2] Add support for CPM5 controller 1
In-Reply-To: <20240922061318.2653503-1-thippesw@amd.com>
References: <20240922061318.2653503-1-thippesw@amd.com>
Message-ID: <20241219000400.GF1444967@rocinante>

Hello,

> This patch series introduces support for the second Root Port controller in
> the Xilinx Versal Premium CPM5 block. The Versal Premium platform features
> two Type-A Root Port controllers operating at Gen5 speed. However, the
> error interrupt registers and their corresponding bits are located at
> different offsets for Controller 0 and Controller 1.
> 
> To handle these differences, the series includes:
> 
> A new compatible string for the second Root Port controller in the device
> tree bindings.
> 
> Driver updates to manage platform-specific interrupt registers and offsets
> for both controllers using the new compatible string.

Applied to controller/xilinx-cpm, thank you!

[01/02] dt-bindings: PCI: xilinx-cpm: Add compatible string for CPM5 host1
        https://git.kernel.org/pci/pci/c/5c911b4659d5

[02/02] PCI: xilinx-cpm: Add support for Versal CPM5 Root Port Controller 1
        https://git.kernel.org/pci/pci/c/

	Krzysztof


From kuba at kernel.org  Wed Dec 18 16:42:06 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Wed, 18 Dec 2024 16:42:06 -0800
Subject: [PATCH net-next v1] net: stmmac: Drop useless code related to
 ethtool rx-copybreak
In-Reply-To: <b2ae6b80-83e3-4b22-8301-c91569c89494@intel.com>
References: <20241218083407.390509-1-0x1207@gmail.com>
	<b2ae6b80-83e3-4b22-8301-c91569c89494@intel.com>
Message-ID: <20241218164206.437fcedc@kernel.org>

On Wed, 18 Dec 2024 16:48:38 +0100 Alexander Lobakin wrote:
> If sizeof(dma_addr_t) == 8, you're clearly introducing a 4-byte hole
> here. Perhaps you could reshuffle the struct a bit to avoid this.
> 
> It's always good to inspect the .kos with pahole after modifying
> structures to make sure there are no regressions.

Pretty off topic but I have a dumb question - how do you dump a struct
with pahole using debug info or BTF from a random .ko?
Ever since pahole got converted to BTF modules stopped working for me :S
I never cared enough to check as most interesting stuff is built-in
in Meta's kernels but it annoys me every now and then..


From jon.lin at rock-chips.com  Wed Dec 18 17:05:57 2024
From: jon.lin at rock-chips.com (Jon Lin)
Date: Thu, 19 Dec 2024 09:05:57 +0800
Subject: [PATCH] spi: rockchip-sfc: Using normal memory for dma
Message-ID: <20241219010557.333327-1-jon.lin@rock-chips.com>

Nornal memory CPU copy with cache invalidate is more efficient
than uncache memory copy.

Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

 drivers/spi/spi-rockchip-sfc.c | 47 ++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 22 deletions(-)

diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
index ca4f20283d23..36509bcccc27 100644
--- a/drivers/spi/spi-rockchip-sfc.c
+++ b/drivers/spi/spi-rockchip-sfc.c
@@ -156,10 +156,9 @@
 
 #define SFC_MAX_CHIPSELECT_NUM		2
 
-/* The SFC can transfer max 16KB - 1 at one time
- * we set it to 15.5KB here for alignment.
- */
 #define SFC_MAX_IOSIZE_VER3		(512 * 31)
+/* Although up to 4GB, 64KB is enough with less mem reserved */
+#define SFC_MAX_IOSIZE_VER4		(0x10000U)
 
 /* DMA is only enabled for large data transmission */
 #define SFC_DMA_TRANS_THRETHOLD		(0x40)
@@ -457,8 +456,10 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
 
 	dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
 
-	if (op->data.dir == SPI_MEM_DATA_OUT)
+	if (op->data.dir == SPI_MEM_DATA_OUT) {
 		memcpy(sfc->buffer, op->data.buf.out, len);
+		dma_sync_single_for_device(sfc->dev, sfc->dma_buffer, len, DMA_TO_DEVICE);
+	}
 
 	ret = rockchip_sfc_fifo_transfer_dma(sfc, sfc->dma_buffer, len);
 	if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) {
@@ -466,8 +467,11 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
 		ret = -ETIMEDOUT;
 	}
 	rockchip_sfc_irq_mask(sfc, SFC_IMR_DMA);
-	if (op->data.dir == SPI_MEM_DATA_IN)
+
+	if (op->data.dir == SPI_MEM_DATA_IN) {
+		dma_sync_single_for_cpu(sfc->dev, sfc->dma_buffer, len, DMA_FROM_DEVICE);
 		memcpy(op->data.buf.in, sfc->buffer, len);
+	}
 
 	return ret;
 }
@@ -633,19 +637,6 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
 
 	sfc->use_dma = !of_property_read_bool(sfc->dev->of_node, "rockchip,sfc-no-dma");
 
-	if (sfc->use_dma) {
-		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
-		if (ret) {
-			dev_warn(dev, "Unable to set dma mask\n");
-			return ret;
-		}
-
-		sfc->buffer = dmam_alloc_coherent(dev, SFC_MAX_IOSIZE_VER3,
-						  &sfc->dma_buffer, GFP_KERNEL);
-		if (!sfc->buffer)
-			return -ENOMEM;
-	}
-
 	ret = clk_prepare_enable(sfc->hclk);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to enable ahb clk\n");
@@ -676,8 +667,8 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_irq;
 
-	sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
 	sfc->version = rockchip_sfc_get_version(sfc);
+	sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
 
 	pm_runtime_set_autosuspend_delay(dev, ROCKCHIP_AUTOSUSPEND_DELAY);
 	pm_runtime_use_autosuspend(dev);
@@ -685,16 +676,27 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_noresume(dev);
 
+	if (sfc->use_dma) {
+		sfc->buffer = (u8 *)__get_free_pages(GFP_KERNEL | GFP_DMA32,
+						     get_order(sfc->max_iosize));
+		if (!sfc->buffer) {
+			ret = -ENOMEM;
+			goto err_dma;
+		}
+		sfc->dma_buffer = virt_to_phys(sfc->buffer);
+	}
+
 	ret = devm_spi_register_controller(dev, host);
 	if (ret)
-		goto err_pm_runtime_free;
+		goto err_register;
 
 	pm_runtime_mark_last_busy(dev);
 	pm_runtime_put_autosuspend(dev);
 
 	return 0;
-
-err_pm_runtime_free:
+err_register:
+	free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize));
+err_dma:
 	pm_runtime_get_sync(dev);
 	pm_runtime_put_noidle(dev);
 	pm_runtime_disable(dev);
@@ -714,6 +716,7 @@ static void rockchip_sfc_remove(struct platform_device *pdev)
 	struct spi_controller *host = sfc->host;
 
 	spi_unregister_controller(host);
+	free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize));
 
 	clk_disable_unprepare(sfc->clk);
 	clk_disable_unprepare(sfc->hclk);
-- 
2.34.1



From zhangqing at rock-chips.com  Wed Dec 18 17:11:59 2024
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Thu, 19 Dec 2024 09:11:59 +0800
Subject: [PATCH v2 2/2] arm64: dts: rockchip: rk3576: add can dts nodes
In-Reply-To: <20241219011159.3357530-1-zhangqing@rock-chips.com>
References: <20241219011159.3357530-1-zhangqing@rock-chips.com>
Message-ID: <20241219011159.3357530-3-zhangqing@rock-chips.com>

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 26 ++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index 436232ffe4d1..eefae2b5e6e4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1195,6 +1195,32 @@ dmac2: dma-controller at 2abd0000 {
 			#dma-cells = <1>;
 		};
 
+		can0: can at 2ac00000 {
+			compatible = "rockchip,rk3576-canfd";
+			reg = <0x0 0x2ac00000 0x0 0x1000>;
+			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru CLK_CAN0>, <&cru HCLK_CAN0>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&cru SRST_CAN0>, <&cru SRST_H_CAN0>;
+			reset-names = "can", "can-apb";
+			dmas = <&dmac0 20>;
+			dma-names = "rx";
+			status = "disabled";
+		};
+
+		can1: can at 2ac10000 {
+			compatible = "rockchip,rk3576-canfd";
+			reg = <0x0 0x2ac10000 0x0 0x1000>;
+			interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru CLK_CAN1>, <&cru HCLK_CAN1>;
+			clock-names = "baudclk", "apb_pclk";
+			resets = <&cru SRST_CAN1>, <&cru SRST_H_CAN1>;
+			reset-names = "can", "can-apb";
+			dmas = <&dmac1 21>;
+			dma-names = "rx";
+			status = "disabled";
+		};
+
 		i2c1: i2c at 2ac40000 {
 			compatible = "rockchip,rk3576-i2c", "rockchip,rk3399-i2c";
 			reg = <0x0 0x2ac40000 0x0 0x1000>;
-- 
2.34.1



From zhangqing at rock-chips.com  Wed Dec 18 17:11:57 2024
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Thu, 19 Dec 2024 09:11:57 +0800
Subject: [PATCH v2 0/2] rockchip: add can for RK3576 Soc
Message-ID: <20241219011159.3357530-1-zhangqing@rock-chips.com>

rk3576 can is a new controller:
Support CAN and CANFD protocol.

There are major differences from the previous rk3568. All errata on the
rk3568 have been fixed and redesigned.

Change in V2:
[PATCH v2 1/2]: remove rk3576_canfd.c, use the rockchip_canfd driver
[PATCH v2 2/2]: code style.

Elaine Zhang (2):
  net: can: rockchip: add can for RK3576 Soc
  arm64: dts: rockchip: rk3576: add can dts nodes

 arch/arm64/boot/dts/rockchip/rk3576.dtsi      |  26 +
 .../net/can/rockchip/rockchip_canfd-core.c    | 453 +++++++++++++++---
 drivers/net/can/rockchip/rockchip_canfd-rx.c  | 111 ++++-
 drivers/net/can/rockchip/rockchip_canfd-tx.c  |  29 ++
 drivers/net/can/rockchip/rockchip_canfd.h     | 285 +++++++++++
 5 files changed, 846 insertions(+), 58 deletions(-)

-- 
2.34.1



From zhangqing at rock-chips.com  Wed Dec 18 17:11:58 2024
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Thu, 19 Dec 2024 09:11:58 +0800
Subject: [PATCH v2 1/2] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20241219011159.3357530-1-zhangqing@rock-chips.com>
References: <20241219011159.3357530-1-zhangqing@rock-chips.com>
Message-ID: <20241219011159.3357530-2-zhangqing@rock-chips.com>

Is new controller:
Support CAN and CANFD protocol.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../net/can/rockchip/rockchip_canfd-core.c    | 453 +++++++++++++++---
 drivers/net/can/rockchip/rockchip_canfd-rx.c  | 111 ++++-
 drivers/net/can/rockchip/rockchip_canfd-tx.c  |  29 ++
 drivers/net/can/rockchip/rockchip_canfd.h     | 285 +++++++++++
 4 files changed, 820 insertions(+), 58 deletions(-)

diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index df18c85fc078..ceae691412d4 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -50,6 +50,11 @@ static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
 		RKCANFD_QUIRK_CANFD_BROKEN,
 };
 
+/* The rk3576 CAN-FD */
+static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3576 = {
+	.model = RKCANFD_MODEL_RK3576,
+};
+
 static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
 {
 	switch (model) {
@@ -57,6 +62,8 @@ static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
 		return "rk3568v2";
 	case RKCANFD_MODEL_RK3568V3:
 		return "rk3568v3";
+	case RKCANFD_MODEL_RK3576:
+		return "rk3576";
 	}
 
 	return "<unknown>";
@@ -163,10 +170,21 @@ static void rkcanfd_get_berr_counter_corrected(struct rkcanfd_priv *priv,
 					       struct can_berr_counter *bec)
 {
 	struct can_berr_counter bec_raw;
-	u32 reg_state;
+	u32 reg_state, rxerr, txerr, busoff_state, error_war_state;
 
-	bec->rxerr = rkcanfd_read(priv, RKCANFD_REG_RXERRORCNT);
-	bec->txerr = rkcanfd_read(priv, RKCANFD_REG_TXERRORCNT);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576) {
+		rxerr = RK3576CANFD_REG_RXERRORCNT;
+		txerr = RK3576CANFD_REG_TXERRORCNT;
+		busoff_state = RK3576CANFD_REG_STATE_BUS_OFF_STATE;
+		error_war_state = RK3576CANFD_REG_STATE_ERROR_WARNING_STATE;
+	} else {
+		rxerr = RKCANFD_REG_RXERRORCNT;
+		txerr = RKCANFD_REG_TXERRORCNT;
+		busoff_state = RKCANFD_REG_STATE_BUS_OFF_STATE;
+		error_war_state = RKCANFD_REG_STATE_ERROR_WARNING_STATE;
+	}
+	bec->rxerr = rkcanfd_read(priv, rxerr);
+	bec->txerr = rkcanfd_read(priv, txerr);
 	bec_raw = *bec;
 
 	/* Tests show that sometimes both CAN bus error counters read
@@ -198,8 +216,8 @@ static void rkcanfd_get_berr_counter_corrected(struct rkcanfd_priv *priv,
 		    "%s: Raw/Cor: txerr=%3u/%3u rxerr=%3u/%3u Bus Off=%u Warning=%u\n",
 		    __func__,
 		    bec_raw.txerr, bec->txerr, bec_raw.rxerr, bec->rxerr,
-		    !!(reg_state & RKCANFD_REG_STATE_BUS_OFF_STATE),
-		    !!(reg_state & RKCANFD_REG_STATE_ERROR_WARNING_STATE));
+		    !!(reg_state & busoff_state),
+		    !!(reg_state & error_war_state));
 }
 
 static int rkcanfd_get_berr_counter(const struct net_device *ndev,
@@ -229,28 +247,106 @@ static void rkcanfd_chip_interrupts_enable(const struct rkcanfd_priv *priv)
 
 static void rkcanfd_chip_interrupts_disable(const struct rkcanfd_priv *priv)
 {
-	rkcanfd_write(priv, RKCANFD_REG_INT_MASK, RKCANFD_REG_INT_ALL);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		rkcanfd_write(priv, RK3576CANFD_REG_INT_MASK, RK3576CANFD_REG_INT_ALL);
+	else
+		rkcanfd_write(priv, RKCANFD_REG_INT_MASK, RKCANFD_REG_INT_ALL);
 }
 
 static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
 {
-	u32 reg;
-
-	/* TXE FIFO */
-	reg = rkcanfd_read(priv, RKCANFD_REG_RX_FIFO_CTRL);
-	reg |= RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_ENABLE;
-	rkcanfd_write(priv, RKCANFD_REG_RX_FIFO_CTRL, reg);
-
-	/* RX FIFO */
-	reg = rkcanfd_read(priv, RKCANFD_REG_RX_FIFO_CTRL);
-	reg |= RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_ENABLE;
-	rkcanfd_write(priv, RKCANFD_REG_RX_FIFO_CTRL, reg);
+	u32 reg, ism = 0, water = 0;
+
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576) {
+		if (priv->rx_max_data > 4) {
+			ism = RK3576CANFD_DATA_CANFD_FIXED;
+			water = RK3576CANFD_ISM_WATERMASK_CANFD;
+		} else {
+			ism = RK3576CANFD_DATA_CAN_FIXED;
+			water = RK3576CANFD_ISM_WATERMASK_CAN;
+		}
 
+		/* internal sram mode */
+		rkcanfd_write(priv, RK3576CANFD_REG_STR_CTL,
+			      (ism << RK3576CANFD_ISM_SEL_SHIFT) |
+			      RK3576CANFD_STORAGE_TIMEOUT_MODE);
+		rkcanfd_write(priv, RK3576CANFD_REG_STR_WTM, water);
+	} else {
+		/* TXE FIFO */
+		reg = rkcanfd_read(priv, RKCANFD_REG_RX_FIFO_CTRL);
+		reg |= RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_ENABLE;
+		rkcanfd_write(priv, RKCANFD_REG_RX_FIFO_CTRL, reg);
+
+		/* RX FIFO */
+		reg = rkcanfd_read(priv, RKCANFD_REG_RX_FIFO_CTRL);
+		reg |= RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_ENABLE;
+		rkcanfd_write(priv, RKCANFD_REG_RX_FIFO_CTRL, reg);
+	}
 	WRITE_ONCE(priv->tx_head, 0);
 	WRITE_ONCE(priv->tx_tail, 0);
 	netdev_reset_queue(priv->ndev);
 }
 
+static int rk3576canfd_atf_config(struct rkcanfd_priv *priv, int mode)
+{
+	u32 id[10] = {0};
+	u32 dlc = 0, dlc_over = 0;
+
+	switch (mode) {
+	case RK3576CANFD_ATF_MASK_MODE:
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF0, id[0]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF1, id[1]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF2, id[2]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF3, id[3]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF4, id[4]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM0, 0x7fff);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM1, 0x7fff);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM2, 0x7fff);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM3, 0x7fff);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM4, 0x7fff);
+		break;
+	case RK3576CANFD_ATF_LIST_MODE:
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF0, id[0]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF1, id[1]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF2, id[2]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF3, id[3]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF4, id[4]);
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM0, id[5] | (1 << 31));
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM1, id[6] | (1 << 31));
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM2, id[7] | (1 << 31));
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM3, id[8] | (1 << 31));
+		rkcanfd_write(priv, RK3576CANFD_REG_ATFM4, id[9] | (1 << 31));
+		break;
+	default:
+		rkcanfd_write(priv, RK3576CANFD_REG_ATF_CTL, 0xffff);
+		return -EINVAL;
+	}
+
+	if (dlc) {
+		if (dlc_over)
+			rkcanfd_write(priv, RK3576CANFD_REG_ATF_DLC, dlc | (1 << 4));
+		else
+			rkcanfd_write(priv, RK3576CANFD_REG_ATF_DLC, dlc | (1 << 4) | (1 << 5));
+	}
+	rkcanfd_write(priv, RK3576CANFD_REG_ATF_CTL, 0);
+
+	return 0;
+}
+
+static void rk3576canfd_init(struct rkcanfd_priv *priv)
+{
+	rkcanfd_write(priv, RK3576CANFD_REG_AUTO_RETX_CFG,
+		      RK3576CANFD_AUTO_RETX_EN | RK3576CANFD_RETX_LIMIT_EN |
+		      (RK3576CANFD_RETX_TIME_LIMIT_CNT << RK3576CANFD_RETX_TIME_LIMIT_SHIFT));
+
+	rkcanfd_write(priv, RK3576CANFD_REG_BRS_CFG, 0x7);
+
+	rkcanfd_write(priv, RK3576CANFD_REG_BUSOFFRCY_CFG,
+		      RK3576CANFD_BUSOFF_RCY_MODE_EN |
+		      RK3576CANFD_BUSOFF_RCY_CNT_FAST);
+	rkcanfd_write(priv, RK3576CANFD_REG_BUSOFF_RCY_THR, RK3576CANFD_BUSOFF_RCY_TIME_FAST);
+}
+
 static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 {
 	u32 reg;
@@ -258,8 +354,12 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 	rkcanfd_chip_set_reset_mode(priv);
 
 	/* Receiving Filter: accept all */
-	rkcanfd_write(priv, RKCANFD_REG_IDCODE, 0x0);
-	rkcanfd_write(priv, RKCANFD_REG_IDMASK, RKCANFD_REG_IDCODE_EXTENDED_FRAME_ID);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576) {
+		rk3576canfd_atf_config(priv, RK3576CANFD_ATF_MASK_MODE);
+	} else {
+		rkcanfd_write(priv, RKCANFD_REG_IDCODE, 0x0);
+		rkcanfd_write(priv, RKCANFD_REG_IDMASK, RKCANFD_REG_IDCODE_EXTENDED_FRAME_ID);
+	}
 
 	/* enable:
 	 * - CAN_FD: enable CAN-FD
@@ -269,17 +369,26 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 	 * - WORK_MODE: transition from reset to working mode
 	 */
 	reg = rkcanfd_read(priv, RKCANFD_REG_MODE);
-	priv->reg_mode_default = reg |
-		RKCANFD_REG_MODE_CAN_FD_MODE_ENABLE |
-		RKCANFD_REG_MODE_AUTO_RETX_MODE |
-		RKCANFD_REG_MODE_COVER_MODE |
-		RKCANFD_REG_MODE_RXSTX_MODE |
-		RKCANFD_REG_MODE_WORK_MODE;
-
-	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
-		priv->reg_mode_default |= RKCANFD_REG_MODE_LBACK_MODE |
-			RKCANFD_REG_MODE_SILENT_MODE |
-			RKCANFD_REG_MODE_SELF_TEST;
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		priv->reg_mode_default = reg | RKCANFD_REG_MODE_WORK_MODE;
+	else
+		priv->reg_mode_default = reg |
+			RKCANFD_REG_MODE_CAN_FD_MODE_ENABLE |
+			RKCANFD_REG_MODE_AUTO_RETX_MODE |
+			RKCANFD_REG_MODE_COVER_MODE |
+			RKCANFD_REG_MODE_RXSTX_MODE |
+			RKCANFD_REG_MODE_WORK_MODE;
+
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+		if (priv->devtype_data.model == RKCANFD_MODEL_RK3576) {
+			priv->reg_mode_default |= RKCANFD_REG_MODE_LBACK_MODE;
+			rkcanfd_write(priv, RK3576CANFD_REG_ERROR_MASK, RK3576CANFD_ACK_ERROR_MASK);
+		} else {
+			priv->reg_mode_default |= RKCANFD_REG_MODE_LBACK_MODE |
+				RKCANFD_REG_MODE_SILENT_MODE |
+				RKCANFD_REG_MODE_SELF_TEST;
+		}
+	}
 
 	/* mask, i.e. ignore:
 	 * - TIMESTAMP_COUNTER_OVERFLOW_INT - timestamp counter overflow interrupt
@@ -287,11 +396,14 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 	 * - OVERLOAD_INT - CAN bus overload interrupt
 	 * - TX_FINISH_INT - Transmit finish interrupt
 	 */
-	priv->reg_int_mask_default =
-		RKCANFD_REG_INT_TIMESTAMP_COUNTER_OVERFLOW_INT |
-		RKCANFD_REG_INT_TX_ARBIT_FAIL_INT |
-		RKCANFD_REG_INT_OVERLOAD_INT |
-		RKCANFD_REG_INT_TX_FINISH_INT;
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		priv->reg_int_mask_default = RK3576CANFD_REG_INT_RX_FINISH_INT;
+	else
+		priv->reg_int_mask_default =
+			RKCANFD_REG_INT_TIMESTAMP_COUNTER_OVERFLOW_INT |
+			RKCANFD_REG_INT_TX_ARBIT_FAIL_INT |
+			RKCANFD_REG_INT_OVERLOAD_INT |
+			RKCANFD_REG_INT_TX_FINISH_INT;
 
 	/* Do not mask the bus error interrupt if the bus error
 	 * reporting is requested.
@@ -302,8 +414,13 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 	memset(&priv->bec, 0x0, sizeof(priv->bec));
 
 	rkcanfd_chip_fifo_setup(priv);
-	rkcanfd_timestamp_init(priv);
-	rkcanfd_timestamp_start(priv);
+	if (priv->devtype_data.model != RKCANFD_MODEL_RK3576) {
+		rkcanfd_timestamp_init(priv);
+		rkcanfd_timestamp_start(priv);
+	}
+
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		rk3576canfd_init(priv);
 
 	rkcanfd_set_bittiming(priv);
 
@@ -328,7 +445,8 @@ static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state st
 {
 	priv->can.state = state;
 
-	rkcanfd_timestamp_stop(priv);
+	if (priv->devtype_data.model != RKCANFD_MODEL_RK3576)
+		rkcanfd_timestamp_stop(priv);
 	__rkcanfd_chip_stop(priv, state);
 }
 
@@ -336,7 +454,8 @@ static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_sta
 {
 	priv->can.state = state;
 
-	rkcanfd_timestamp_stop_sync(priv);
+	if (priv->devtype_data.model != RKCANFD_MODEL_RK3576)
+		rkcanfd_timestamp_stop_sync(priv);
 	__rkcanfd_chip_stop(priv, state);
 }
 
@@ -395,6 +514,9 @@ static const char *rkcanfd_get_error_type_str(unsigned int type)
 #define RKCAN_ERROR_CODE(reg_ec, code) \
 	((reg_ec) & RKCANFD_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
 
+#define RK3576CAN_ERROR_CODE(reg_ec, code) \
+	((reg_ec) & RK3576CANFD_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
+
 static void
 rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
 				const u32 reg_ec)
@@ -524,6 +646,128 @@ rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
 	}
 }
 
+static void
+rk3576canfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
+				    const u32 reg_ec)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	unsigned int type;
+	u32 reg_state, reg_cmd;
+
+	type = FIELD_GET(RK3576CANFD_REG_ERROR_CODE_TYPE, reg_ec);
+	reg_cmd = rkcanfd_read(priv, RK3576CANFD_REG_CMD);
+	reg_state = rkcanfd_read(priv, RK3576CANFD_REG_STATE);
+
+	netdev_dbg(priv->ndev, "%s Error in %s %s Phase: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s(0x%08x) CMD=%u RX=%u TX=%u Error-Warning=%u Bus-Off=%u\n",
+		   rkcanfd_get_error_type_str(type),
+		   reg_ec & RK3576CANFD_REG_ERROR_CODE_DIRECTION_RX ? "RX" : "TX",
+		   reg_ec & RK3576CANFD_REG_ERROR_CODE_PHASE ? "Data" : "Arbitration",
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_ACK_EOF),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_CRC),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_STUFF_COUNT),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_DATA),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_SOF_DLC),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_IDLE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ERROR),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_OVERLOAD),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_SPACE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_EOF),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK_LIM),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC_LIM),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_STUFF_COUNT),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_DATA),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_DLC),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BRS_ESI),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_RES),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_FDF),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ID2_RTR),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_SOF_IDE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_IDLE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_INT),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_STOP),
+		   reg_ec, reg_cmd,
+		   !!(reg_state & RK3576CANFD_REG_STATE_RX_PERIOD),
+		   !!(reg_state & RK3576CANFD_REG_STATE_TX_PERIOD),
+		   !!(reg_state & RK3576CANFD_REG_STATE_ERROR_WARNING_STATE),
+		   !!(reg_state & RK3576CANFD_REG_STATE_BUS_OFF_STATE));
+
+	priv->can.can_stats.bus_error++;
+
+	if (reg_ec & RK3576CANFD_REG_ERROR_CODE_DIRECTION_RX)
+		stats->rx_errors++;
+	else
+		stats->tx_errors++;
+
+	if (!cf)
+		return;
+
+	if (reg_ec & RK3576CANFD_REG_ERROR_CODE_DIRECTION_RX) {
+		if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_SOF_IDE)
+			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_ID2_RTR)
+			cf->data[3] = CAN_ERR_PROT_LOC_RTR;
+		/* RKCANFD_REG_ERROR_CODE_RX_FDF */
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_RES)
+			cf->data[3] = CAN_ERR_PROT_LOC_RES0;
+		/* RKCANFD_REG_ERROR_CODE_RX_BRS_ESI */
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_DLC)
+			cf->data[3] = CAN_ERR_PROT_LOC_DLC;
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_DATA)
+			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
+		/* RKCANFD_REG_ERROR_CODE_RX_STUFF_COUNT */
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_CRC)
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_CRC_LIM)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_ACK)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_ACK_LIM)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_EOF)
+			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_RX_SPACE)
+			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
+	} else {
+		cf->data[2] |= CAN_ERR_PROT_TX;
+
+		if (reg_ec & RK3576CANFD_REG_ERROR_CODE_TX_SOF_DLC)
+			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_TX_DATA)
+			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
+		/* RKCANFD_REG_ERROR_CODE_TX_STUFF_COUNT */
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_TX_CRC)
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		else if (reg_ec & RK3576CANFD_REG_ERROR_CODE_TX_ACK_EOF)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+	}
+
+	switch (reg_ec & RK3576CANFD_REG_ERROR_CODE_TYPE) {
+	case FIELD_PREP_CONST(RK3576CANFD_REG_ERROR_CODE_TYPE,
+			      RK3576CANFD_REG_ERROR_CODE_TYPE_BIT):
+
+		cf->data[2] |= CAN_ERR_PROT_BIT;
+		break;
+	case FIELD_PREP_CONST(RK3576CANFD_REG_ERROR_CODE_TYPE,
+			      RK3576CANFD_REG_ERROR_CODE_TYPE_STUFF):
+		cf->data[2] |= CAN_ERR_PROT_STUFF;
+		break;
+	case FIELD_PREP_CONST(RK3576CANFD_REG_ERROR_CODE_TYPE,
+			      RK3576CANFD_REG_ERROR_CODE_TYPE_FORM):
+		cf->data[2] |= CAN_ERR_PROT_FORM;
+		break;
+	case FIELD_PREP_CONST(RK3576CANFD_REG_ERROR_CODE_TYPE,
+			      RK3576CANFD_REG_ERROR_CODE_TYPE_ACK):
+		cf->can_id |= CAN_ERR_ACK;
+		break;
+	case FIELD_PREP_CONST(RK3576CANFD_REG_ERROR_CODE_TYPE,
+			      RK3576CANFD_REG_ERROR_CODE_TYPE_CRC):
+		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		break;
+	}
+}
+
 static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -532,13 +776,19 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 	struct sk_buff *skb;
 	int err;
 
-	reg_ec = rkcanfd_read(priv, RKCANFD_REG_ERROR_CODE);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		reg_ec = rkcanfd_read(priv, RK3576CANFD_REG_ERROR_CODE);
+	else
+		reg_ec = rkcanfd_read(priv, RKCANFD_REG_ERROR_CODE);
 
 	if (!reg_ec)
 		return 0;
 
 	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
-		skb = rkcanfd_alloc_can_err_skb(priv, &cf, &timestamp);
+		if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+			skb = alloc_can_err_skb(priv->ndev, &cf);
+		else
+			skb = rkcanfd_alloc_can_err_skb(priv, &cf, &timestamp);
 		if (cf) {
 			struct can_berr_counter bec;
 
@@ -549,12 +799,18 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 		}
 	}
 
-	rkcanfd_handle_error_int_reg_ec(priv, cf, reg_ec);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		rk3576canfd_handle_error_int_reg_ec(priv, cf, reg_ec);
+	else
+		rkcanfd_handle_error_int_reg_ec(priv, cf, reg_ec);
 
 	if (!cf)
 		return 0;
 
-	err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		err = can_rx_offload_queue_tail(&priv->offload, skb);
+	else
+		err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
 	if (err)
 		stats->rx_fifo_errors++;
 
@@ -582,7 +838,10 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	/* The skb allocation might fail, but can_change_state()
 	 * handles cf == NULL.
 	 */
-	skb = rkcanfd_alloc_can_err_skb(priv, &cf, &timestamp);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		skb = alloc_can_err_skb(priv->ndev, &cf);
+	else
+		skb = rkcanfd_alloc_can_err_skb(priv, &cf, &timestamp);
 	can_change_state(ndev, cf, tx_state, rx_state);
 
 	if (new_state == CAN_STATE_BUS_OFF) {
@@ -599,7 +858,10 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 		cf->data[7] = bec.rxerr;
 	}
 
-	err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		err = can_rx_offload_queue_tail(&priv->offload, skb);
+	else
+		err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
 	if (err)
 		stats->rx_fifo_errors++;
 
@@ -621,7 +883,10 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 
 	netdev_dbg(priv->ndev, "RX-FIFO overflow\n");
 
-	skb = rkcanfd_alloc_can_err_skb(priv, &cf, &timestamp);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		skb = alloc_can_err_skb(priv->ndev, &cf);
+	else
+		skb = rkcanfd_alloc_can_err_skb(priv, &cf, &timestamp);
 	if (skb)
 		return 0;
 
@@ -632,7 +897,10 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 	cf->data[6] = bec.txerr;
 	cf->data[7] = bec.rxerr;
 
-	err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		err = can_rx_offload_queue_tail(&priv->offload, skb);
+	else
+		err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
 	if (err)
 		stats->rx_fifo_errors++;
 
@@ -652,11 +920,58 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 	err; \
 })
 
+static irqreturn_t rk3576canfd_irq(int irq, void *dev_id)
+{
+	struct rkcanfd_priv *priv = dev_id;
+	u32 reg_int_unmasked, reg_int;
+
+	reg_int_unmasked = rkcanfd_read(priv, RK3576CANFD_REG_INT);
+	reg_int = reg_int_unmasked & ~priv->reg_int_mask_default;
+
+	if (!reg_int)
+		return IRQ_NONE;
+
+	rkcanfd_write(priv, RK3576CANFD_REG_INT, reg_int);
+
+	if (reg_int & (RK3576CANFD_REG_INT_RXSTR_TIMEOUT_INT |
+		       RK3576CANFD_REG_INT_ISM_WTM_INT |
+		       RK3576CANFD_REG_INT_RX_FIFO_FULL_INT))
+		rkcanfd_handle(priv, rx_int);
+
+	if (reg_int & RK3576CANFD_REG_INT_TX_FINISH_INT)
+		rkcanfd_handle(priv, tx_int);
+
+	if (reg_int & RK3576CANFD_REG_INT_ERROR_INT)
+		rkcanfd_handle(priv, error_int);
+
+	if (reg_int & (RK3576CANFD_REG_INT_BUS_OFF_INT |
+		       RK3576CANFD_REG_INT_PASSIVE_ERROR_INT |
+		       RK3576CANFD_REG_INT_ERROR_WARNING_INT) ||
+	    priv->can.state > CAN_STATE_ERROR_ACTIVE)
+		rkcanfd_handle(priv, state_error_int);
+
+	if (reg_int & RK3576CANFD_REG_INT_WAKEUP_INT)
+		netdev_info(priv->ndev, "%s: WAKEUP_INT\n", __func__);
+
+	if (reg_int & RK3576CANFD_REG_INT_BUS_OFF_RECOVERY_INT)
+		netdev_info(priv->ndev, "%s: BUS_OFF_RECOVERY_INT\n", __func__);
+
+	if (reg_int & RK3576CANFD_REG_INT_OVERLOAD_INT)
+		netdev_info(priv->ndev, "%s: OVERLOAD_INT\n", __func__);
+
+	can_rx_offload_irq_finish(&priv->offload);
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t rkcanfd_irq(int irq, void *dev_id)
 {
 	struct rkcanfd_priv *priv = dev_id;
 	u32 reg_int_unmasked, reg_int;
 
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		return rk3576canfd_irq(irq, dev_id);
+
 	reg_int_unmasked = rkcanfd_read(priv, RKCANFD_REG_INT);
 	reg_int = reg_int_unmasked & ~priv->reg_int_mask_default;
 
@@ -789,14 +1104,21 @@ static void rkcanfd_register_done(const struct rkcanfd_priv *priv)
 {
 	u32 dev_id;
 
-	dev_id = rkcanfd_read(priv, RKCANFD_REG_RTL_VERSION);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576) {
+		dev_id = rkcanfd_read(priv, RK3576CANFD_REG_RTL_VERSION);
+		netdev_info(priv->ndev,
+			    "Rockchip-CANFD %s rev%u.\n",
+			    rkcanfd_get_model_str(priv), dev_id);
+	} else {
+		dev_id = rkcanfd_read(priv, RKCANFD_REG_RTL_VERSION);
 
-	netdev_info(priv->ndev,
-		    "Rockchip-CANFD %s rev%lu.%lu (errata 0x%04x) found\n",
-		    rkcanfd_get_model_str(priv),
-		    FIELD_GET(RKCANFD_REG_RTL_VERSION_MAJOR, dev_id),
-		    FIELD_GET(RKCANFD_REG_RTL_VERSION_MINOR, dev_id),
-		    priv->devtype_data.quirks);
+		netdev_info(priv->ndev,
+			    "Rockchip-CANFD %s rev%lu.%lu (errata 0x%04x) found\n",
+			    rkcanfd_get_model_str(priv),
+			    FIELD_GET(RKCANFD_REG_RTL_VERSION_MAJOR, dev_id),
+			    FIELD_GET(RKCANFD_REG_RTL_VERSION_MINOR, dev_id),
+			    priv->devtype_data.quirks);
+	}
 
 	if (priv->devtype_data.quirks & RKCANFD_QUIRK_RK3568_ERRATUM_5 &&
 	    priv->can.clock.freq < RKCANFD_ERRATUM_5_SYSCLOCK_HZ_MIN)
@@ -852,6 +1174,9 @@ static const struct of_device_id rkcanfd_of_match[] = {
 	}, {
 		.compatible = "rockchip,rk3568v3-canfd",
 		.data = &rkcanfd_devtype_data_rk3568v3,
+	},  {
+		.compatible = "rockchip,rk3576-canfd",
+		.data = &rkcanfd_devtype_data_rk3576,
 	}, {
 		/* sentinel */
 	},
@@ -863,7 +1188,7 @@ static int rkcanfd_probe(struct platform_device *pdev)
 	struct rkcanfd_priv *priv;
 	struct net_device *ndev;
 	const void *match;
-	int err;
+	int err, val;
 
 	ndev = alloc_candev(sizeof(struct rkcanfd_priv), RKCANFD_TXFIFO_DEPTH);
 	if (!ndev)
@@ -917,8 +1242,24 @@ static int rkcanfd_probe(struct platform_device *pdev)
 	if (match)
 		priv->devtype_data = *(struct rkcanfd_devtype_data *)match;
 
+	/* rx-max-data only 4 Words or 18 words are supported */
+	if (device_property_read_u32_array(&pdev->dev, "rockchip,rx-max-data", &val, 1))
+		priv->rx_max_data = 18;
+	else
+		priv->rx_max_data = val;
+
+	if (priv->rx_max_data != 4 && priv->rx_max_data != 18) {
+		priv->rx_max_data = 18;
+		dev_warn(&pdev->dev, "rx_max_data is invalid, set to 18 words!\n");
+	}
+	priv->rx_fifo_depth = RK3576CANFD_SRAM_MAX_DEPTH / priv->rx_max_data;
+
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		val = priv->rx_fifo_depth + 1;
+	else
+		val = RKCANFD_NAPI_WEIGHT;
 	err = can_rx_offload_add_manual(ndev, &priv->offload,
-					RKCANFD_NAPI_WEIGHT);
+					val);
 	if (err)
 		goto out_free_candev;
 
diff --git a/drivers/net/can/rockchip/rockchip_canfd-rx.c b/drivers/net/can/rockchip/rockchip_canfd-rx.c
index 475c0409e215..7dad674dc545 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-rx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-rx.c
@@ -91,6 +91,47 @@ rkcanfd_fifo_header_to_cfd_header(const struct rkcanfd_priv *priv,
 	return len + cfd->len;
 }
 
+static unsigned int
+rk3576canfd_fifo_header_to_cfd_header(const struct rkcanfd_priv *priv,
+				      const struct rk3576canfd_fifo_header *header,
+				      struct canfd_frame *cfd)
+{
+	unsigned int len = sizeof(*cfd) - sizeof(cfd->data);
+	u8 dlc;
+
+	if (header->frameinfo & RK3576CANFD_REG_RXFRD_FRAMEINFO_FRAME_FORMAT)
+		cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_EFF, header->id) |
+			CAN_EFF_FLAG;
+	else
+		cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_SFF, header->id);
+
+	dlc = FIELD_GET(RK3576CANFD_REG_RXFRD_FRAMEINFO_DATA_LENGTH,
+			header->frameinfo);
+
+	/* CAN-FD */
+	if (header->frameinfo & RK3576CANFD_REG_RXFRD_FRAMEINFO_FDF) {
+		cfd->len = can_fd_dlc2len(dlc);
+
+		/* The cfd is not allocated by alloc_canfd_skb(), so
+		 * set CANFD_FDF here.
+		 */
+		cfd->flags |= CANFD_FDF;
+
+		if (header->frameinfo & RK3576CANFD_REG_RXFRD_FRAMEINFO_BRS)
+			cfd->flags |= CANFD_BRS;
+	} else {
+		cfd->len = can_cc_dlc2len(dlc);
+
+		if (header->frameinfo & RK3576CANFD_REG_RXFRD_FRAMEINFO_RTR) {
+			cfd->can_id |= CAN_RTR_FLAG;
+
+			return len;
+		}
+	}
+
+	return len + cfd->len;
+}
+
 static int rkcanfd_rxstx_filter(struct rkcanfd_priv *priv,
 				const struct canfd_frame *cfd_rx, const u32 ts,
 				bool *tx_done)
@@ -198,6 +239,62 @@ rkcanfd_fifo_header_empty(const struct rkcanfd_fifo_header *header)
 		header->frameinfo == header->ts;
 }
 
+static int rk3576canfd_handle_rx_int_one(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	struct canfd_frame cfd[1] = { }, *skb_cfd;
+	struct rk3576canfd_fifo_header header[1] = { };
+	struct sk_buff *skb;
+	unsigned int len;
+	int err;
+
+	/* read header into separate struct and convert it later */
+	rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
+			 header, sizeof(*header));
+	/* read data directly into cfd */
+	rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
+			 cfd->data, (priv->rx_max_data - 2) * 4);
+
+	len = rk3576canfd_fifo_header_to_cfd_header(priv, header, cfd);
+
+	/* Drop any received CAN-FD frames if CAN-FD mode is not
+	 * requested.
+	 */
+	if (header->frameinfo & RKCANFD_REG_FD_FRAMEINFO_FDF &&
+	    !(priv->can.ctrlmode & CAN_CTRLMODE_FD)) {
+		stats->rx_dropped++;
+
+		return 0;
+	}
+
+	/* Manual handling of CAN Bus Error counters. See
+	 * rkcanfd_get_corrected_berr_counter() for detailed
+	 * explanation.
+	 */
+	if (priv->bec.rxerr)
+		priv->bec.rxerr = min(CAN_ERROR_PASSIVE_THRESHOLD,
+				      priv->bec.rxerr) - 1;
+
+	if (header->frameinfo & RKCANFD_REG_FD_FRAMEINFO_FDF)
+		skb = alloc_canfd_skb(priv->ndev, &skb_cfd);
+	else
+		skb = alloc_can_skb(priv->ndev, (struct can_frame **)&skb_cfd);
+
+	if (!skb) {
+		stats->rx_dropped++;
+
+		return 0;
+	}
+
+	memcpy(skb_cfd, cfd, len);
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int rkcanfd_handle_rx_int_one(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -207,6 +304,9 @@ static int rkcanfd_handle_rx_int_one(struct rkcanfd_priv *priv)
 	unsigned int len;
 	int err;
 
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576)
+		return rk3576canfd_handle_rx_int_one(priv);
+
 	/* read header into separate struct and convert it later */
 	rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
 			 header, sizeof(*header));
@@ -279,9 +379,16 @@ static int rkcanfd_handle_rx_int_one(struct rkcanfd_priv *priv)
 static inline unsigned int
 rkcanfd_rx_fifo_get_len(const struct rkcanfd_priv *priv)
 {
-	const u32 reg = rkcanfd_read(priv, RKCANFD_REG_RX_FIFO_CTRL);
+	u32 reg, len;
 
-	return FIELD_GET(RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_CNT, reg);
+	if (priv->devtype_data.model == RKCANFD_MODEL_RK3576) {
+		reg = rkcanfd_read(priv, RK3576CANFD_REG_STR_STATE);
+		len = FIELD_GET(RK3576CANFD_REG_INTM_FRAME_CNT, reg);
+	} else {
+		reg = rkcanfd_read(priv, RKCANFD_REG_RX_FIFO_CTRL);
+		len = FIELD_GET(RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_CNT, reg);
+	}
+	return len;
 }
 
 int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv)
diff --git a/drivers/net/can/rockchip/rockchip_canfd-tx.c b/drivers/net/can/rockchip/rockchip_canfd-tx.c
index 865a15e033a9..e00f3447928f 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-tx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-tx.c
@@ -165,3 +165,32 @@ void rkcanfd_handle_tx_done_one(struct rkcanfd_priv *priv, const u32 ts,
 							    frame_len_p);
 	stats->tx_packets++;
 }
+
+int rkcanfd_handle_tx_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	unsigned int tx_tail;
+	struct sk_buff *skb;
+	unsigned int frame_len = 0;
+
+	tx_tail = rkcanfd_get_tx_tail(priv);
+	skb = priv->can.echo_skb[tx_tail];
+
+	/* Manual handling of CAN Bus Error counters. See
+	 * rkcanfd_get_corrected_berr_counter() for detailed
+	 * explanation.
+	 */
+	if (priv->bec.txerr)
+		priv->bec.txerr--;
+
+	stats->tx_bytes +=
+		can_rx_offload_get_echo_skb_queue_tail(&priv->offload,
+						       tx_tail, &frame_len);
+	stats->tx_packets++;
+	WRITE_ONCE(priv->tx_tail, priv->tx_tail + 1);
+	netif_subqueue_completed_wake(priv->ndev, 0, 1, frame_len,
+				      rkcanfd_get_effective_tx_free(priv),
+				      RKCANFD_TX_START_THRESHOLD);
+	return 0;
+}
+
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index 93131c7d7f54..17f099ee08cf 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -287,6 +287,282 @@
 #define RKCANFD_REG_RX_FIFO_RDATA 0x400
 #define RKCANFD_REG_TXE_FIFO_RDATA 0x500
 
+#define RK3576CANFD_REG_MODE 0x000
+#define RK3576CANFD_REG_CMD 0x004
+
+#define RK3576CANFD_REG_STATE 0x008
+#define RK3576CANFD_REG_STATE_SLEEP_STATE BIT(5)
+#define RK3576CANFD_REG_STATE_BUS_OFF_STATE BIT(4)
+#define RK3576CANFD_REG_STATE_ERROR_WARNING_STATE BIT(3)
+#define RK3576CANFD_REG_STATE_TX_PERIOD BIT(2)
+#define RK3576CANFD_REG_STATE_RX_PERIOD BIT(1)
+#define RK3576CANFD_REG_STATE_TX_BUFFER_FULL BIT(0)
+
+#define RK3576CANFD_REG_INT 0x00c
+#define RK3576CANFD_REG_INT_BUSOFF_RCY_INT BIT(19)
+#define RK3576CANFD_REG_INT_ESM_WTM_INT BIT(18)
+#define RK3576CANFD_REG_INT_ISM_WTM_INT BIT(17)
+#define RK3576CANFD_REG_INT_BUSINT_INT BIT(16)
+#define RK3576CANFD_REG_INT_RXSTR_TIMEOUT_INT BIT(15)
+#define RK3576CANFD_REG_INT_MFI_TIMEOUT_INT BIT(14)
+#define RK3576CANFD_REG_INT_MFI_INT BIT(13)
+#define RK3576CANFD_REG_INT_AUTO_RETX_FAIL_INT BIT(12)
+#define RK3576CANFD_REG_INT_WAKEUP_INT BIT(11)
+#define RK3576CANFD_REG_INT_BUS_OFF_RECOVERY_INT BIT(10)
+#define RK3576CANFD_REG_INT_BUS_OFF_INT BIT(9)
+#define RK3576CANFD_REG_INT_RX_FIFO_OVERFLOW_INT BIT(8)
+#define RK3576CANFD_REG_INT_RX_FIFO_FULL_INT BIT(7)
+#define RK3576CANFD_REG_INT_ERROR_INT BIT(6)
+#define RK3576CANFD_REG_INT_TX_ARBIT_FAIL_INT BIT(5)
+#define RK3576CANFD_REG_INT_PASSIVE_ERROR_INT BIT(4)
+#define RK3576CANFD_REG_INT_OVERLOAD_INT BIT(3)
+#define RK3576CANFD_REG_INT_ERROR_WARNING_INT BIT(2)
+#define RK3576CANFD_REG_INT_TX_FINISH_INT BIT(1)
+#define RK3576CANFD_REG_INT_RX_FINISH_INT BIT(0)
+
+#define RK3576CANFD_REG_INT_ALL \
+	(RK3576CANFD_REG_INT_BUSOFF_RCY_INT | \
+	 RK3576CANFD_REG_INT_ESM_WTM_INT | \
+	 RK3576CANFD_REG_INT_ISM_WTM_INT | \
+	 RK3576CANFD_REG_INT_BUSINT_INT | \
+	 RK3576CANFD_REG_INT_RXSTR_TIMEOUT_INT | \
+	 RK3576CANFD_REG_INT_MFI_TIMEOUT_INT | \
+	 RK3576CANFD_REG_INT_MFI_INT | \
+	 RK3576CANFD_REG_INT_AUTO_RETX_FAIL_INT | \
+	 RK3576CANFD_REG_INT_WAKEUP_INT | \
+	 RK3576CANFD_REG_INT_BUS_OFF_RECOVERY_INT | \
+	 RK3576CANFD_REG_INT_BUS_OFF_INT | \
+	 RK3576CANFD_REG_INT_RX_FIFO_OVERFLOW_INT | \
+	 RK3576CANFD_REG_INT_RX_FIFO_FULL_INT | \
+	 RK3576CANFD_REG_INT_ERROR_INT | \
+	 RK3576CANFD_REG_INT_TX_ARBIT_FAIL_INT | \
+	 RK3576CANFD_REG_INT_PASSIVE_ERROR_INT | \
+	 RK3576CANFD_REG_INT_OVERLOAD_INT | \
+	 RK3576CANFD_REG_INT_ERROR_WARNING_INT | \
+	 RK3576CANFD_REG_INT_TX_FINISH_INT | \
+	 RK3576CANFD_REG_INT_RX_FINISH_INT)
+
+#define RK3576CANFD_REG_INT_ALL_ERROR \
+	(RK3576CANFD_REG_INT_BUS_OFF_INT | \
+	 RK3576CANFD_REG_INT_ERROR_INT | \
+	 RK3576CANFD_REG_INT_PASSIVE_ERROR_INT | \
+	 RK3576CANFD_REG_INT_ERROR_WARNING_INT)
+
+#define RK3576CANFD_REG_INT_MASK 0x010
+
+#define RK3576CANFD_REG_FD_NOMINAL_BITTIMING 0x100
+#define RK3576CANFD_REG_FD_NOMINAL_BITTIMING_SAMPLE_MODE BIT(31)
+#define RK3576CANFD_REG_FD_NOMINAL_BITTIMING_SJW GENMASK(30, 24)
+#define RK3576CANFD_REG_FD_NOMINAL_BITTIMING_BRP GENMASK(23, 16)
+#define RK3576CANFD_REG_FD_NOMINAL_BITTIMING_TSEG2 GENMASK(14, 8)
+#define RK3576CANFD_REG_FD_NOMINAL_BITTIMING_TSEG1 GENMASK(7, 0)
+
+#define RK3576CANFD_REG_FD_DATA_BITTIMING 0x104
+#define RK3576CANFD_REG_FD_DATA_BITTIMING_BRS_TSEG1 GENMASK(31, 24)
+#define RK3576CANFD_REG_FD_DATA_BITTIMING_BRS_MODE BIT(23)
+#define RK3576CANFD_REG_FD_DATA_BITTIMING_ACKSLOT_SYNC_DIS BIT(22)
+#define RK3576CANFD_REG_FD_DATA_BITTIMING_SJW GENMASK(20, 17)
+#define RK3576CANFD_REG_FD_DATA_BITTIMING_BRP GENMASK(16, 9)
+#define RK3576CANFD_REG_FD_DATA_BITTIMING_TSEG2 GENMASK(8, 5)
+#define RK3576CANFD_REG_FD_DATA_BITTIMING_TSEG1 GENMASK(4, 0)
+
+#define RK3576CANFD_REG_TRANSMIT_DELAY_COMPENSATION 0x108
+#define RK3576CANFD_REG_TRANSMIT_DELAY_COMPENSATION_TDC_OFFSET GENMASK(6, 1)
+#define RK3576CANFD_REG_TRANSMIT_DELAY_COMPENSATION_TDC_ENABLE BIT(0)
+
+#define RK3576CANFD_REG_BRS_CFG 0x10c
+#define RK3576CANFD_REG_BRS_CFG_TRIPLE_SYNC_MODE BIT(31)
+#define RK3576CANFD_REG_BRS_CFG_SP2_DTSEG1 GENMASK(30, 26)
+#define RK3576CANFD_REG_BRS_CFG_SP2_NTSEG1 GENMASK(25, 18)
+#define RK3576CANFD_REG_BRS_CFG_SP1_DTSEG1 GENMASK(17, 13)
+#define RK3576CANFD_REG_BRS_CFG_SP1_NTSEG1 GENMASK(12, 5)
+#define RK3576CANFD_REG_BRS_CFG_RESYNC_MODE BIT(3)
+#define RK3576CANFD_REG_BRS_CFG_BRS_POSSYNC_EN BIT(1)
+#define RK3576CANFD_REG_BRS_CFG_BRS_NEGSYNC_EN BIT(0)
+
+#define RK3576CANFD_REG_LOOP_CNT 0x110
+
+#define RK3576CANFD_REG_DMA_CTRL 0x11c
+#define RK3576CANFD_REG_DMA_CTRL_DMA_RX_EN BIT(9)
+#define RK3576CANFD_REG_DMA_CTRL_DMA_THR GENMASK(8, 0)
+
+#define RK3576CANFD_REG_FD_TXFRAMEINFO 0x200
+
+#define RK3576CANFD_REG_FD_TXID 0x204
+#define RK3576CANFD_REG_FD_ID_EFF GENMASK(28, 0)
+#define RK3576CANFD_REG_FD_ID_SFF GENMASK(11, 0)
+
+#define RK3576CANFD_REG_FD_TXDATA0 0x208
+#define RK3576CANFD_REG_FD_TXDATA1 0x20c
+#define RK3576CANFD_REG_FD_TXDATA2 0x210
+#define RK3576CANFD_REG_FD_TXDATA3 0x214
+#define RK3576CANFD_REG_FD_TXDATA4 0x218
+#define RK3576CANFD_REG_FD_TXDATA5 0x21c
+#define RK3576CANFD_REG_FD_TXDATA6 0x220
+#define RK3576CANFD_REG_FD_TXDATA7 0x224
+#define RK3576CANFD_REG_FD_TXDATA8 0x228
+#define RK3576CANFD_REG_FD_TXDATA9 0x22c
+#define RK3576CANFD_REG_FD_TXDATA10 0x230
+#define RK3576CANFD_REG_FD_TXDATA11 0x234
+#define RK3576CANFD_REG_FD_TXDATA12 0x238
+#define RK3576CANFD_REG_FD_TXDATA13 0x23c
+#define RK3576CANFD_REG_FD_TXDATA14 0x240
+#define RK3576CANFD_REG_FD_TXDATA15 0x244
+
+#define RK3576CANFD_REG_RXFRD 0x400
+#define RK3576CANFD_REG_RXFRD_FRAMEINFO_FRAME_FORMAT BIT(23)
+#define RK3576CANFD_REG_RXFRD_FRAMEINFO_RTR BIT(22)
+#define RK3576CANFD_REG_RXFRD_FRAMEINFO_FDF BIT(21)
+#define RK3576CANFD_REG_RXFRD_FRAMEINFO_BRS BIT(20)
+#define RK3576CANFD_REG_RXFRD_FRAMEINFO_DATA_LENGTH GENMASK(27, 24)
+
+#define RK3576CANFD_REG_STR_CTL 0x600
+#define RK3576CANFD_REG_STR_STATE 0x604
+#define RK3576CANFD_REG_INTM_FRAME_CNT GENMASK(25, 17)
+
+#define RK3576CANFD_REG_STR_TIMEOUT 0x608
+
+#define RK3576CANFD_BUFFER_MODE_ENABLE BIT(0)
+#define RK3576CANFD_EXT_STORAGE_MODE BIT(1)
+#define RK3576CANFD_ISM_SEL_SHIFT 2
+#define RK3576CANFD_ISM_SEL_MASK (0x3 << RK3576CANFD_ISM_SEL_SHIFT)
+#define RK3576CANFD_RX_STORAGE_RESET BIT(4)
+#define RK3576CANFD_ESM_SEL_SHIFT 6
+#define RK3576CANFD_ESM_SEL_MASK (0x3 << RK3576CANFD_ESM_SEL_SHIFT)
+#define RK3576CANFD_STORAGE_TIMEOUT_MODE BIT(8)
+
+#define RK3576CANFD_INTM_CNT_SHIFT 17
+#define RK3576CANFD_INTM_CNT_MASK (0x1ff << RK3576CANFD_INTM_CNT_SHIFT)
+#define RK3576CANFD_INTM_LEFT_CNT_SHIFT 8
+#define RK3576CANFD_INTM_LEFT_CNT_MASK (0x1ff << RK3576CANFD_INTM_LEFT_CNT_SHIFT)
+#define RK3576CANFD_EXTM_FULL BIT(3)
+#define RK3576CANFD_EXTM_EMPTY BIT(2)
+#define RK3576CANFD_INTM_FULL BIT(1)
+#define RK3576CANFD_INTM_EMPTY BIT(0)
+
+#define RK3576CANFD_REG_STR_WTM 0x60c
+#define RK3576CANFD_REG_ATF0 0x700
+#define RK3576CANFD_REG_ATF1 0x704
+#define RK3576CANFD_REG_ATF2 0x708
+#define RK3576CANFD_REG_ATF3 0x70c
+#define RK3576CANFD_REG_ATF4 0x710
+#define RK3576CANFD_REG_ATFM0 0x714
+#define RK3576CANFD_REG_ATFM1 0x718
+#define RK3576CANFD_REG_ATFM2 0x71c
+#define RK3576CANFD_REG_ATFM3 0x720
+#define RK3576CANFD_REG_ATFM4 0x724
+#define RK3576CANFD_REG_ATF_DLC 0x728
+#define RK3576CANFD_REG_ATF_CTL 0x72c
+#define RK3576CANFD_ATF_MASK BIT(31)
+#define RK3576CANFD_ATF_RTR_EN BIT(30)
+#define RK3576CANFD_ATF_RTR BIT(29)
+#define RK3576CANFD_ATF_DLC_MODE BIT(5)
+#define RK3576CANFD_ATF_DLC_EN BIT(4)
+#define RK3576CANFD_ATF_DLC_SHIFT 0
+#define RK3576CANFD_ATF_DLC_MASK (0xf << RK3576CANFD_ATF_DLC_SHIFT)
+#define RK3576CANFD_ATF_DIS(n) BIT(n)
+
+#define RK3576CANFD_REG_SPACE_CTRL 0x800
+
+#define RK3576CANFD_REG_AUTO_RETX_CFG 0x808
+#define RK3576CANFD_RETX_TIME_LIMIT_CNT 0x12c /* 300 */
+#define RK3576CANFD_RETX_TIME_LIMIT_SHIFT 3
+#define RK3576CANFD_RETX_LIMIT_EN BIT(1)
+#define RK3576CANFD_AUTO_RETX_EN BIT(0)
+
+#define RK3576CANFD_REG_AUTO_RETX_STATE0 0x80c
+#define RK3576CANFD_REG_AUTO_RETX_STATE1 0x810
+#define RK3576CANFD_REG_OLF_CFG 0x814
+#define RK3576CANFD_REG_RXINT_CTRL 0x818
+#define RK3576CANFD_REG_RXINT_TIMEOUT 0x81c
+#define RK3576CANFD_REG_OTHER_CFG 0x820
+#define RK3576CANFD_REG_WAVE_FILTER_CFG 0x824
+#define RK3576CANFD_REG_RBC_CFG 0x828
+#define RK3576CANFD_REG_TXCRC_CFG 0x82c
+
+#define RK3576CANFD_REG_BUSOFFRCY_CFG 0x830
+#define RK3576CANFD_REG_BUSOFF_RCY_THR 0x834
+#define RK3576CANFD_BUSOFF_RCY_MODE_EN BIT(8)
+#define RK3576CANFD_BUSOFF_RCY_TIME_CLR BIT(9)
+#define RK3576CANFD_BUSOFF_RCY_CNT_FAST 4
+#define RK3576CANFD_BUSOFF_RCY_CNT_SLOW 5
+#define RK3576CANFD_BUSOFF_RCY_TIME_FAST 0x3d0900 /* 40ms : cnt * (1 / can_clk) */
+#define RK3576CANFD_BUSOFF_RCY_TIME_SLOW 0x1312d00 /* 200ms : cnt * (1 / can_clk) */
+
+#define RK3576CANFD_REG_ERROR_CODE 0x900
+#define RK3576CANFD_REG_ERROR_MASK 0x904
+#define RK3576CANFD_ACK_ERROR_MASK BIT(4)
+#define RK3576CANFD_FORM_ERROR_MASK BIT(3)
+#define RK3576CANFD_CRC_ERROR_MASK BIT(2)
+#define RK3576CANFD_STUFF_ERROR_MASK BIT(1)
+#define RK3576CANFD_BIT_ERROR_MASK BIT(0)
+
+#define RK3576CANFD_REG_RXERRORCNT 0x910
+#define RK3576CANFD_REG_TXERRORCNT 0x914
+#define RK3576CANFD_REG_RX_RXSRAM_RDATA 0xc00
+#define RK3576CANFD_REG_RTL_VERSION 0xf0c
+
+#define RK3576CANFD_REG_ERROR_CODE_PHASE BIT(29)
+#define RK3576CANFD_REG_ERROR_CODE_TYPE GENMASK(28, 26)
+#define RK3576CANFD_REG_ERROR_CODE_TYPE_BIT 0x0
+#define RK3576CANFD_REG_ERROR_CODE_TYPE_STUFF 0x1
+#define RK3576CANFD_REG_ERROR_CODE_TYPE_FORM 0x2
+#define RK3576CANFD_REG_ERROR_CODE_TYPE_ACK 0x3
+#define RK3576CANFD_REG_ERROR_CODE_TYPE_CRC 0x4
+#define RK3576CANFD_REG_ERROR_CODE_DIRECTION_RX BIT(25)
+#define RK3576CANFD_REG_ERROR_CODE_TX GENMASK(24, 19)
+#define RK3576CANFD_REG_ERROR_CODE_TX_ACK_EOF BIT(24)
+#define RK3576CANFD_REG_ERROR_CODE_TX_CRC BIT(23)
+#define RK3576CANFD_REG_ERROR_CODE_TX_STUFF_COUNT BIT(22)
+#define RK3576CANFD_REG_ERROR_CODE_TX_DATA BIT(21)
+#define RK3576CANFD_REG_ERROR_CODE_TX_SOF_DLC BIT(20)
+#define RK3576CANFD_REG_ERROR_CODE_TX_IDLE BIT(19)
+#define RK3576CANFD_REG_ERROR_CODE_RX GENMASK(18, 0)
+#define RK3576CANFD_REG_ERROR_CODE_RX_ERROR BIT(18)
+#define RK3576CANFD_REG_ERROR_CODE_RX_OVERLOAD BIT(17)
+#define RK3576CANFD_REG_ERROR_CODE_RX_SPACE BIT(16)
+#define RK3576CANFD_REG_ERROR_CODE_RX_EOF BIT(15)
+#define RK3576CANFD_REG_ERROR_CODE_RX_ACK_LIM BIT(14)
+#define RK3576CANFD_REG_ERROR_CODE_RX_ACK BIT(13)
+#define RK3576CANFD_REG_ERROR_CODE_RX_CRC_LIM BIT(12)
+#define RK3576CANFD_REG_ERROR_CODE_RX_CRC BIT(11)
+#define RK3576CANFD_REG_ERROR_CODE_RX_STUFF_COUNT BIT(10)
+#define RK3576CANFD_REG_ERROR_CODE_RX_DATA BIT(9)
+#define RK3576CANFD_REG_ERROR_CODE_RX_DLC BIT(8)
+#define RK3576CANFD_REG_ERROR_CODE_RX_BRS_ESI BIT(7)
+#define RK3576CANFD_REG_ERROR_CODE_RX_RES BIT(6)
+#define RK3576CANFD_REG_ERROR_CODE_RX_FDF BIT(5)
+#define RK3576CANFD_REG_ERROR_CODE_RX_ID2_RTR BIT(4)
+#define RK3576CANFD_REG_ERROR_CODE_RX_SOF_IDE BIT(3)
+#define RK3576CANFD_REG_ERROR_CODE_RX_BUS_IDLE BIT(2)
+#define RK3576CANFD_REG_ERROR_CODE_RX_BUS_INT BIT(1)
+#define RK3576CANFD_REG_ERROR_CODE_RX_STOP BIT(0)
+
+#define RK3576CANFD_ISM_WATERMASK_CAN 0x6c /* word */
+#define RK3576CANFD_ISM_WATERMASK_CANFD 0x6c /* word */
+#define RK3576CANFD_ESM_WATERMASK (0x50 << 8) /* word */
+
+#define RK3576CANFD_SRAM_MAX_DEPTH 256 /* word */
+#define RK3576CANFD_EXT_MEM_SIZE 0x2000 /* 8KByte */
+
+#define RK3576CANFD_CANFD_FILTER_MASK 0x1fffffff
+
+#define RK3576CANFD_CANFD_FIFO_CNT_MASK 0xff
+
+#define RK3576CANFD_CANBUSOFF_RCY_SLOW 200 /* ms */
+#define RK3576CANFD_CANBUSOFF_RCY_FAST 30 /* ms */
+
+enum rk3576canfd_atf_mode {
+	RK3576CANFD_ATF_MASK_MODE = 0,
+	RK3576CANFD_ATF_LIST_MODE,
+};
+
+enum rk3576canfd_storage_mode {
+	RK3576CANFD_DATA_FLEXIBLE = 0,
+	RK3576CANFD_DATA_CAN_FIXED,
+	RK3576CANFD_DATA_CANFD_FIXED,
+};
+
 #define DEVICE_NAME "rockchip_canfd"
 #define RKCANFD_NAPI_WEIGHT 32
 #define RKCANFD_TXFIFO_DEPTH 2
@@ -434,6 +710,7 @@
 enum rkcanfd_model {
 	RKCANFD_MODEL_RK3568V2 = 0x35682,
 	RKCANFD_MODEL_RK3568V3 = 0x35683,
+	RKCANFD_MODEL_RK3576 = 0x3576,
 };
 
 struct rkcanfd_devtype_data {
@@ -447,6 +724,11 @@ struct rkcanfd_fifo_header {
 	u32 ts;
 };
 
+struct rk3576canfd_fifo_header {
+	u32 frameinfo;
+	u32 id;
+};
+
 struct rkcanfd_stats {
 	struct u64_stats_sync syncp;
 
@@ -482,6 +764,8 @@ struct rkcanfd_priv {
 	struct reset_control *reset;
 	struct clk_bulk_data *clks;
 	int clks_num;
+	int rx_fifo_depth;
+	int rx_max_data;
 };
 
 static inline u32
@@ -536,6 +820,7 @@ rkcanfd_get_tx_free(const struct rkcanfd_priv *priv)
 void rkcanfd_ethtool_init(struct rkcanfd_priv *priv);
 
 int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv);
+int rkcanfd_handle_tx_int(struct rkcanfd_priv *priv);
 
 void rkcanfd_skb_set_timestamp(const struct rkcanfd_priv *priv,
 			       struct sk_buff *skb, const u32 timestamp);
-- 
2.34.1



From kuba at kernel.org  Wed Dec 18 17:19:16 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Wed, 18 Dec 2024 17:19:16 -0800
Subject: [PATCH net-next v1] net: stmmac: TSO: Simplify the code flow of
 DMA descriptor allocations
In-Reply-To: <20241213030006.337695-1-0x1207@gmail.com>
References: <20241213030006.337695-1-0x1207@gmail.com>
Message-ID: <20241218171916.24a7e24f@kernel.org>

On Fri, 13 Dec 2024 11:00:06 +0800 Furong Xu wrote:
> -		if (priv->dma_cap.addr64 <= 32)
> -			desc->des0 = cpu_to_le32(curr_addr);
> -		else
> -			stmmac_set_desc_addr(priv, desc, curr_addr);
> -
> +		stmmac_set_desc_addr(priv, desc, curr_addr);

I can't figure out if this is correct or not in a reasonable amount of
time. dwmac4 and dwxgmac2 looks pretty obviously okay. But there are
also ndesc and enh, which don't seem to map to platform in an obvious
way to an outside reviewer.

Please provide more context/guidance in the commit message, otherwise
this looks like a high risk refactoring for a driver this poorly
designed.
-- 
pw-bot: cr


From damon.ding at rock-chips.com  Wed Dec 18 17:27:18 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 09:27:18 +0800
Subject: [PATCH v2 11/11] arm64: dts: rockchip: Add nodes related to eDP1
 for RK3588
In-Reply-To: <2173171.OBFZWjSADL@diego>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-12-damon.ding@rock-chips.com> <2173171.OBFZWjSADL@diego>
Message-ID: <5562ec11-c3f5-4068-8ad0-6e93924228ed@rock-chips.com>

Hi Heiko,

On 2024/12/18 20:45, Heiko St?bner wrote:
> Hi Damon,
> 
> Am Montag, 16. Dezember 2024, 04:12:25 CET schrieb Damon Ding:
>> The related nodes are hdptxphy1_grf, hdptxphy1 and edp1. And the
>> aliases edp0 and edp1 are added to separate two independent eDP
>> devices.
>>
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>> ---
>>   .../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 55 +++++++++++++++++++
>>   1 file changed, 55 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
>> index 0ce0934ec6b7..17cc0b619744 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
>> @@ -7,6 +7,11 @@
>>   #include "rk3588-extra-pinctrl.dtsi"
>>   
>>   / {
>> +	aliases {
>> +		edp0 = &edp0;
>> +		edp1 = &edp1;
>> +	};
>> +
> 
> drop aliases please

I will drop it and use the registers to separate edp0 and edp1 in the 
next version.

> 
> 
>> @@ -67,6 +72,11 @@ u2phy1_otg: otg-port {
>>   		};
>>   	};
>>   
>> +	hdptxphy1_grf: syscon at fd5e4000 {
>> +		compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
>> +		reg = <0x0 0xfd5e4000 0x0 0x100>;
>> +	};
>> +
>>   	i2s8_8ch: i2s at fddc8000 {
>>   		compatible = "rockchip,rk3588-i2s-tdm";
>>   		reg = <0x0 0xfddc8000 0x0 0x1000>;
> 
>> @@ -395,6 +434,22 @@ sata-port at 0 {
>>   		};
>>   	};
>>   
>> +	hdptxphy1: phy at fed70000 {
>> +		compatible = "rockchip,rk3588-hdptx-phy";
>> +		reg = <0x0 0xfed70000 0x0 0x2000>;
>> +		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>;
>> +		clock-names = "ref", "apb";
>> +		#phy-cells = <0>;
>> +		resets = <&cru SRST_HDPTX1>, <&cru SRST_P_HDPTX1>,
>> +			 <&cru SRST_HDPTX1_INIT>, <&cru SRST_HDPTX1_CMN>,
>> +			 <&cru SRST_HDPTX1_LANE>, <&cru SRST_HDPTX1_ROPLL>,
>> +			 <&cru SRST_HDPTX1_LCPLL>;
>> +		reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
>> +			      "lcpll";
>> +		rockchip,grf = <&hdptxphy1_grf>;
>> +		status = "disabled";
>> +	};
> 
> the hdptxphy nodes should be their own patch, also because most likely
> Cristian's patch for hdmi1 [0] will be slightly faster.

Indeed, it is good to add edp1 node only.

> 
> 
> [0] https://lore.kernel.org/r/20241211-rk3588-hdmi1-v2-2-02cdca22ff68 at collabora.com
> 
> 
> 
> 
> 
Best regards,
Damon



From damon.ding at rock-chips.com  Wed Dec 18 17:35:12 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 09:35:12 +0800
Subject: [PATCH v2 04/11] phy: phy-rockchip-samsung-hdptx: Add support for
 eDP mode
In-Reply-To: <867267676.0ifERbkFSE@diego>
References: <20241216031225.3746-1-damon.ding@rock-chips.com>
 <20241216031225.3746-5-damon.ding@rock-chips.com>
 <867267676.0ifERbkFSE@diego>
Message-ID: <7fa672bb-7263-468b-ad7d-f1585459dc67@rock-chips.com>

Hi Heiko,

On 2024/12/18 20:35, Heiko St?bner wrote:
> Hi Damon,
> 
> Am Montag, 16. Dezember 2024, 04:12:18 CET schrieb Damon Ding:
>> Add basic support for RBR/HBR/HBR2 link rates, and the voltage swing and
>> pre-emphasis configurations of each link rate have been verified according
>> to the eDP 1.3 requirements.
>>
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>>
>> ---
>>
>> Changes in v2:
>> - Add the module author
>> ---
> 
>> @@ -255,6 +364,19 @@ struct ropll_config {
>>   	u8 cd_tx_ser_rate_sel;
>>   };
>>   
>> +struct tx_drv_ctrl {
>> +	u8 tx_drv_lvl_ctrl;
>> +	u8 tx_drv_post_lvl_ctrl;
>> +	u8 ana_tx_drv_idrv_idn_ctrl;
>> +	u8 ana_tx_drv_idrv_iup_ctrl;
>> +	u8 ana_tx_drv_accdrv_en;
>> +	u8 ana_tx_drv_accdrv_ctrl;
>> +	u8 tx_drv_pre_lvl_ctrl;
>> +	u8 ana_tx_jeq_en;
>> +	u8 tx_jeq_even_ctrl;
>> +	u8 tx_jeq_odd_ctrl;
>> +};
>> +
>>   enum rk_hdptx_reset {
>>   	RST_PHY = 0,
>>   	RST_APB,
> 
> not a full review (yet), but this part conflicts with
> commit f2dbca169790 ("phy: phy-rockchip-samsung-hdptx: Don't request RST_PHY/RST_ROPLL/RST_LCPLL")
> 
> [0] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=f2dbca169790ea1e436ffdd9ef37d7c3a4401c46
> 
> 
> 
> 
I will update to the latest Kernel branch and fix this conflict in the 
next version.

Best regards,
Damon


From xueshuai at linux.alibaba.com  Wed Dec 18 17:43:59 2024
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Thu, 19 Dec 2024 09:43:59 +0800
Subject: [PATCH v17 3/3] ACPI: APEI: handle synchronous exceptions in task
 work
In-Reply-To: <20241218165331.GF1155365@yaz-khff2.amd.com>
References: <20241202030527.20586-1-xueshuai@linux.alibaba.com>
 <20241202030527.20586-4-xueshuai@linux.alibaba.com>
 <20241218165331.GF1155365@yaz-khff2.amd.com>
Message-ID: <a9c2ea4d-7199-4d1c-8f10-57761b50d27f@linux.alibaba.com>



? 2024/12/19 00:53, Yazen Ghannam ??:
> On Mon, Dec 02, 2024 at 11:05:27AM +0800, Shuai Xue wrote:
>> The memory uncorrected error could be signaled by asynchronous interrupt
>> (specifically, SPI in arm64 platform), e.g. when an error is detected by
>> a background scrubber, or signaled by synchronous exception
>> (specifically, data abort exception in arm64 platform), e.g. when a CPU
>> tries to access a poisoned cache line. Currently, both synchronous and
>> asynchronous error use memory_failure_queue() to schedule
>> memory_failure() to exectute in a kworker context.
>>
>> As a result, when a user-space process is accessing a poisoned data, a
>> data abort is taken and the memory_failure() is executed in the kworker
>> context, memory_failure():
>>
>>    - will send wrong si_code by SIGBUS signal in early_kill mode, and
>>    - can not kill the user-space in some cases resulting a synchronous
>>      error infinite loop
>>
>> Issue 1: send wrong si_code in early_kill mode
>>
>> Since commit a70297d22132 ("ACPI: APEI: set memory failure flags as
>> MF_ACTION_REQUIRED on synchronous events")', the flag MF_ACTION_REQUIRED
>> could be used to determine whether a synchronous exception occurs on
>> ARM64 platform.  When a synchronous exception is detected, the kernel is
>> expected to terminate the current process which has accessed poisoned
>> page. This is done by sending a SIGBUS signal with an error code
>> BUS_MCEERR_AR, indicating an action-required machine check error on
>> read.
>>
>> However, when kill_proc() is called to terminate the processes who have
>> the poisoned page mapped, it sends the incorrect SIGBUS error code
>> BUS_MCEERR_AO because the context in which it operates is not the one
>> where the error was triggered.
>>
>> To reproduce this problem:
>>
>>    #sysctl -w vm.memory_failure_early_kill=1
>>    vm.memory_failure_early_kill = 1
>>
>>    # STEP2: inject an UCE error and consume it to trigger a synchronous error
>>    #einj_mem_uc single
>>    0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>>    injecting ...
>>    triggering ...
>>    signal 7 code 5 addr 0xffffb0d75000
>>    page not present
>>    Test passed
>>
>> The si_code (code 5) from einj_mem_uc indicates that it is BUS_MCEERR_AO
>> error and it is not the fact.
>>
>> After this patch:
>>
>>    # STEP1: enable early kill mode
>>    #sysctl -w vm.memory_failure_early_kill=1
>>    vm.memory_failure_early_kill = 1
>>    # STEP2: inject an UCE error and consume it to trigger a synchronous error
>>    #einj_mem_uc single
>>    0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>>    injecting ...
>>    triggering ...
>>    signal 7 code 4 addr 0xffffb0d75000
>>    page not present
>>    Test passed
>>
>> The si_code (code 4) from einj_mem_uc indicates that it is a BUS_MCEERR_AR
>> error as we expected.
>>
>> Issue 2: a synchronous error infinite loop
>>
>> If a user-space process, e.g. devmem, accesses a poisoned page for which
>> the HWPoison flag is set, kill_accessing_process() is called to send
>> SIGBUS to current processs with error info. Because the memory_failure()
>> is executed in the kworker context, it will just do nothing but return
>> EFAULT. So, devmem will access the posioned page and trigger an
>> exception again, resulting in a synchronous error infinite loop. Such
>> exception loop may cause platform firmware to exceed some threshold and
>> reboot when Linux could have recovered from this error.
>>
>> To reproduce this problem:
>>
>>    # STEP 1: inject an UCE error, and kernel will set HWPosion flag for related page
>>    #einj_mem_uc single
>>    0: single   vaddr = 0xffffb0d75400 paddr = 4092d55b400
>>    injecting ...
>>    triggering ...
>>    signal 7 code 4 addr 0xffffb0d75000
>>    page not present
>>    Test passed
>>
>>    # STEP 2: access the same page and it will trigger a synchronous error infinite loop
>>    devmem 0x4092d55b400
>>
>> To fix above two issues, queue memory_failure() as a task_work so that
>> it runs in the context of the process that is actually consuming the
>> poisoned data.
>>
>> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
>> Tested-by: Ma Wupeng <mawupeng1 at huawei.com>
>> Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>> Reviewed-by: Xiaofei Tan <tanxiaofei at huawei.com>
>> Reviewed-by: Baolin Wang <baolin.wang at linux.alibaba.com>
>> Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>
>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
>> ---
>>   drivers/acpi/apei/ghes.c | 77 +++++++++++++++++++++++-----------------
>>   include/acpi/ghes.h      |  3 --
>>   include/linux/mm.h       |  1 -
>>   mm/memory-failure.c      | 13 -------
>>   4 files changed, 44 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 106486bdfefc..70f2ee3ad1a8 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -467,28 +467,41 @@ static void ghes_clear_estatus(struct ghes *ghes,
>>   }
>>   
>>   /*
> 
> The "kernel-doc" format needs an opening "/**".
> 
>> - * Called as task_work before returning to user-space.
>> - * Ensure any queued work has been done before we return to the context that
>> - * triggered the notification.
>> + * struct ghes_task_work - for synchronous RAS event
>> + *
>> + * @twork:                callback_head for task work
>> + * @pfn:                  page frame number of corrupted page
>> + * @flags:                work control flags
>> + *
>> + * Structure to pass task work to be handled before
>> + * returning to user-space via task_work_add().
>>    */
>> -static void ghes_kick_task_work(struct callback_head *head)
>> +struct ghes_task_work {
>> +	struct callback_head twork;
>> +	u64 pfn;
>> +	int flags;
>> +};
>> +
>> +static void memory_failure_cb(struct callback_head *twork)
>>   {
>> -	struct acpi_hest_generic_status *estatus;
>> -	struct ghes_estatus_node *estatus_node;
>> -	u32 node_len;
>> +	struct ghes_task_work *twcb = container_of(twork, struct ghes_task_work, twork);
>> +	int ret;
>>   
>> -	estatus_node = container_of(head, struct ghes_estatus_node, task_work);
>> -	if (IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
>> -		memory_failure_queue_kick(estatus_node->task_work_cpu);
>> +	ret = memory_failure(twcb->pfn, twcb->flags);
>> +	gen_pool_free(ghes_estatus_pool, (unsigned long)twcb, sizeof(*twcb));
>>   
>> -	estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
>> -	node_len = GHES_ESTATUS_NODE_LEN(cper_estatus_len(estatus));
>> -	gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len);
>> +	if (!ret || ret == -EHWPOISON || ret == -EOPNOTSUPP)
>> +		return;
>> +
>> +	pr_err("%#llx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",
>> +			twcb->pfn, current->comm, task_pid_nr(current));
> 
> This is basically the same as the message in kill_proc(). Was there any
> consideration to have a shared function? Maybe this could be a future
> patch.

Yep, I'd like to refactor in a future.
> 
>> +	force_sig(SIGBUS);
>>   }
>>   
>>   static bool ghes_do_memory_failure(u64 physical_addr, int flags)
>>   {
>>   	unsigned long pfn;
>> +	struct ghes_task_work *twcb;
> 
> Minor nit: A common preference I've seen is to order variable
> declarations from longest->shortest line length.

Will fix it if this patch set still misses the next merge window.

> 
> But overall, looks okay to me.
> 
> Reviewed-by: Yazen Ghannam <yazen.ghannam at amd.com>
> 
> Thanks,
> Yazen


Thanks for valuable comments.

Best Regards,
Shuai



From ming.qian at oss.nxp.com  Wed Dec 18 17:51:45 2024
From: ming.qian at oss.nxp.com (Ming Qian)
Date: Thu, 19 Dec 2024 10:51:45 +0900
Subject: [PATCH 1/2] media: amphion: Support display delay for Hevc format
Message-ID: <20241219015146.706482-1-ming.qian@oss.nxp.com>

The amphion decoder firmware v1.9.0 supports display delay 0 for
hevc format, then driver can enable this feature.

Signed-off-by: Ming Qian <ming.qian at oss.nxp.com>
---
 drivers/media/platform/amphion/vpu_malone.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
index 5c6b2a841b6f..8f4aa48b2d65 100644
--- a/drivers/media/platform/amphion/vpu_malone.c
+++ b/drivers/media/platform/amphion/vpu_malone.c
@@ -332,6 +332,8 @@ struct vpu_dec_ctrl {
 	u32 buf_addr[VID_API_NUM_STREAMS];
 };
 
+static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt);
+
 u32 vpu_malone_get_data_size(void)
 {
 	return sizeof(struct vpu_dec_ctrl);
@@ -654,8 +656,10 @@ static int vpu_malone_set_params(struct vpu_shared_addr *shared,
 		hc->jpg[instance].jpg_mjpeg_interlaced = 0;
 	}
 
-	hc->codec_param[instance].disp_imm = params->display_delay_enable ? 1 : 0;
-	if (malone_format != MALONE_FMT_AVC)
+	if (params->display_delay_enable &&
+	    get_padding_scode(SCODE_PADDING_BUFFLUSH, params->codec_format))
+		hc->codec_param[instance].disp_imm = 1;
+	else
 		hc->codec_param[instance].disp_imm = 0;
 	hc->codec_param[instance].dbglog_enable = 0;
 	iface->dbglog_desc.level = 0;
@@ -1024,6 +1028,7 @@ static const struct malone_padding_scode padding_scodes[] = {
 	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_JPEG,        {0x0, 0x0}},
 	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264,        {0x15010000, 0x0}},
 	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC,    {0x15010000, 0x0}},
+	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_HEVC,        {0x3e010000, 0x20}},
 };
 
 static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0};
@@ -1058,8 +1063,11 @@ static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer,
 	int ret;
 
 	ps = get_padding_scode(scode_type, pixelformat);
-	if (!ps)
+	if (!ps) {
+		if (scode_type == SCODE_PADDING_BUFFLUSH)
+			return 0;
 		return -EINVAL;
+	}
 
 	wptr = readl(&str_buf->wptr);
 	if (wptr < stream_buffer->phys || wptr > stream_buffer->phys + stream_buffer->length)
-- 
2.43.0-rc1



From ming.qian at oss.nxp.com  Wed Dec 18 17:51:46 2024
From: ming.qian at oss.nxp.com (Ming Qian)
Date: Thu, 19 Dec 2024 10:51:46 +0900
Subject: [PATCH 2/2] media: amphion: Add a frame flush mode for decoder
In-Reply-To: <20241219015146.706482-1-ming.qian@oss.nxp.com>
References: <20241219015146.706482-1-ming.qian@oss.nxp.com>
Message-ID: <20241219015146.706482-2-ming.qian@oss.nxp.com>

The amphion decoder will pre-parse 3 frames before decoding the first
frame. If we append a flush padding data after frame, the decoder
will finish parsing and start to decode when the flush data is parsed.
It can reduce the decoding latency.
In the past, we only enable this mode when the display delay is set to
0. But we still can enable this mode without changing the display order,
so we add a frame_flush_mode parameter to enable it.

Signed-off-by: Ming Qian <ming.qian at oss.nxp.com>
---
 drivers/media/platform/amphion/vpu_malone.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
index 8f4aa48b2d65..3750a2618b0e 100644
--- a/drivers/media/platform/amphion/vpu_malone.c
+++ b/drivers/media/platform/amphion/vpu_malone.c
@@ -25,6 +25,9 @@
 #include "vpu_imx8q.h"
 #include "vpu_malone.h"
 
+static bool frame_flush_mode;
+module_param(frame_flush_mode, bool, 0644);
+
 #define CMD_SIZE			25600
 #define MSG_SIZE			25600
 #define CODEC_SIZE			0x1000
@@ -1571,7 +1574,7 @@ static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer __iomem *str
 
 	vpu_malone_update_wptr(str_buf, wptr);
 
-	if (disp_imm && !vpu_vb_is_codecconfig(vbuf)) {
+	if ((disp_imm || frame_flush_mode) && !vpu_vb_is_codecconfig(vbuf)) {
 		ret = vpu_malone_add_scode(inst->core->iface,
 					   inst->id,
 					   &inst->stream_buffer,
-- 
2.43.0-rc1



From seanjc at google.com  Wed Dec 18 18:00:50 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 18 Dec 2024 18:00:50 -0800
Subject: [PATCH v4 00/16] KVM: selftests: "tree" wide overhauls
In-Reply-To: <Z2NIwmRDaZBc_V4o@google.com>
References: <20241128005547.4077116-1-seanjc@google.com> <173455833964.3185228.5614329030867008316.b4-ty@google.com>
 <Z2NIwmRDaZBc_V4o@google.com>
Message-ID: <Z2N-UlxgYlGT_1Or@google.com>

On Wed, Dec 18, 2024, Sean Christopherson wrote:
> On Wed, Dec 18, 2024, Sean Christopherson wrote:
> > On Wed, 27 Nov 2024 16:55:31 -0800, Sean Christopherson wrote:
> > > Two separate series (mmu_stress_test[1] and $ARCH[2]), posted as one to
> > > avoid unpleasant conflicts, and because I hope to land both in kvm/next
> > > shortly after 6.12-rc1 since they impact all of KVM selftests.
> > > 
> > > mmu_stress_test
> > > ---------------
> > > Convert the max_guest_memory_test into a more generic mmu_stress_test.
> > > The basic gist of the "conversion" is to have the test do mprotect() on
> > > guest memory while vCPUs are accessing said memory, e.g. to verify KVM
> > > and mmu_notifiers are working as intended.
> > > 
> > > [...]
> > 
> > As I am running out of time before I disappear for two weeks, applied to:
> > 
> >    https://github.com/kvm-x86/linux.git selftests_arch
> > 
> > Other KVM maintainers, that branch is officially immutable.  I also pushed a tag,
> > kvm-selftests-arch-6.14, just in case I pull a stupid and manage to clobber the
> > branch.  My apologies if this causes pain.  AFAICT, there aren't any queued or
> > in-flight patches that git's rename magic can't automatically handle, so hopefully
> > this ends up being pain-free.
> > 
> > Paolo, here's a pull request if you want to pull this into kvm/next long before
> > the 6.14 merge window.  Diff stats at the very bottom (hilariously long).
> 
> Argh!  I completely forget to build test this on non-x86, and missed that arm64
> snuck in 75cd027cbcb1 ("KVM: arm64: selftests: Test ID_AA64PFR0.MPAM isn't completely 
> ignored").  *sigh*
> 
> Given that I just sent out mail, I'm going to cross my fingers and hope that no
> one has merged the above branch/tag.  I've deleted the branch and tags from the
> remote, but kept the tag locally just in case.
> 
> Please holler if you managed to grab the broken branch/tag.  If no one screams,
> I'll assume I got luckly and will push a fixed version (with different names) later
> today.

Third time is the charm.  Compile tested on all architectures, and runtime tested
on x86 and arm64.

  https://github.com/kvm-x86/linux.git selftests_treewide_6.14

---
The following changes since commit 3522c419758ee8dca5a0e8753ee0070a22157bc1:

  Merge tag 'kvm-riscv-fixes-6.13-1' of https://github.com/kvm-riscv/linux into HEAD (2024-12-13 13:59:20 -0500)

are available in the Git repository at:

  https://github.com/kvm-x86/linux.git tags/kvm-selftests-treewide-6.14

for you to fetch changes up to 9af04539d474dda4984ff4909d4568e6123c8cba:

  KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR (2024-12-18 14:15:05 -0800)

----------------------------------------------------------------
KVM selftests "tree"-wide changes for 6.14:

 - Rework vcpu_get_reg() to return a value instead of using an out-param, and
   update all affected arch code accordingly.

 - Convert the max_guest_memory_test into a more generic mmu_stress_test.
   The basic gist of the "conversion" is to have the test do mprotect() on
   guest memory while vCPUs are accessing said memory, e.g. to verify KVM
   and mmu_notifiers are working as intended.

 - Play nice with treewrite builds of unsupported architectures, e.g. arm
   (32-bit), as KVM selftests' Makefile doesn't do anything to ensure the
   target architecture is actually one KVM selftests supports.

 - Use the kernel's $(ARCH) definition instead of the target triple for arch
   specific directories, e.g. arm64 instead of aarch64, mainly so as not to
   be different from the rest of the kernel.

----------------------------------------------------------------
Sean Christopherson (16):
      KVM: Move KVM_REG_SIZE() definition to common uAPI header
      KVM: selftests: Return a value from vcpu_get_reg() instead of using an out-param
      KVM: selftests: Assert that vcpu_{g,s}et_reg() won't truncate
      KVM: selftests: Check for a potential unhandled exception iff KVM_RUN succeeded
      KVM: selftests: Rename max_guest_memory_test to mmu_stress_test
      KVM: selftests: Only muck with SREGS on x86 in mmu_stress_test
      KVM: selftests: Compute number of extra pages needed in mmu_stress_test
      KVM: sefltests: Explicitly include ucall_common.h in mmu_stress_test.c
      KVM: selftests: Enable mmu_stress_test on arm64
      KVM: selftests: Use vcpu_arch_put_guest() in mmu_stress_test
      KVM: selftests: Precisely limit the number of guest loops in mmu_stress_test
      KVM: selftests: Add a read-only mprotect() phase to mmu_stress_test
      KVM: selftests: Verify KVM correctly handles mprotect(PROT_READ)
      KVM: selftests: Provide empty 'all' and 'clean' targets for unsupported ARCHs
      KVM: selftests: Use canonical $(ARCH) paths for KVM selftests directories
      KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR
--

[01/16] KVM: Move KVM_REG_SIZE() definition to common uAPI header
        https://github.com/kvm-x86/linux/commit/915d2f0718a4
[02/16] KVM: selftests: Return a value from vcpu_get_reg() instead of using an out-param
        https://github.com/kvm-x86/linux/commit/09bb926d2907
[03/16] KVM: selftests: Assert that vcpu_{g,s}et_reg() won't truncate
        https://github.com/kvm-x86/linux/commit/fe85ce31b289
[04/16] KVM: selftests: Check for a potential unhandled exception iff KVM_RUN succeeded
        https://github.com/kvm-x86/linux/commit/d6533c151338
[05/16] KVM: selftests: Rename max_guest_memory_test to mmu_stress_test
        https://github.com/kvm-x86/linux/commit/b12391498d1e
[06/16] KVM: selftests: Only muck with SREGS on x86 in mmu_stress_test
        https://github.com/kvm-x86/linux/commit/55e164df482a
[07/16] KVM: selftests: Compute number of extra pages needed in mmu_stress_test
        https://github.com/kvm-x86/linux/commit/1ddd3ea75ac3
[08/16] KVM: sefltests: Explicitly include ucall_common.h in mmu_stress_test.c
        https://github.com/kvm-x86/linux/commit/c35d8f579e50
[09/16] KVM: selftests: Enable mmu_stress_test on arm64
        https://github.com/kvm-x86/linux/commit/8abe7632a1ee
[10/16] KVM: selftests: Use vcpu_arch_put_guest() in mmu_stress_test
        https://github.com/kvm-x86/linux/commit/3a0422526404
[11/16] KVM: selftests: Precisely limit the number of guest loops in mmu_stress_test
        https://github.com/kvm-x86/linux/commit/82b542e11848
[12/16] KVM: selftests: Add a read-only mprotect() phase to mmu_stress_test
        https://github.com/kvm-x86/linux/commit/80b7859a3a43
[13/16] KVM: selftests: Verify KVM correctly handles mprotect(PROT_READ)
        https://github.com/kvm-x86/linux/commit/b6c304aec648
[14/16] KVM: selftests: Provide empty 'all' and 'clean' targets for unsupported ARCHs
        https://github.com/kvm-x86/linux/commit/43fbd8cd389f
[15/16] KVM: selftests: Use canonical $(ARCH) paths for KVM selftests directories
        https://github.com/kvm-x86/linux/commit/67730e6c53d7
[16/16] KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR
        https://github.com/kvm-x86/linux/commit/9af04539d474


 MAINTAINERS                                                                          |  12 +--
 arch/arm64/include/uapi/asm/kvm.h                                                    |   3 -
 arch/riscv/include/uapi/asm/kvm.h                                                    |   3 -
 include/uapi/linux/kvm.h                                                             |   4 +
 tools/testing/selftests/kvm/.gitignore                                               |   1 +
 tools/testing/selftests/kvm/Makefile                                                 | 345 ++------------------------------------------------------------------------------
 tools/testing/selftests/kvm/Makefile.kvm                                             | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/testing/selftests/kvm/{aarch64 => arm64}/aarch32_id_regs.c                     |  10 +--
 tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer.c                          |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer_edge_cases.c               |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/debug-exceptions.c                    |   4 +-
 tools/testing/selftests/kvm/{aarch64 => arm64}/get-reg-list.c                        |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/hypercalls.c                          |   6 +-
 tools/testing/selftests/kvm/{aarch64 => arm64}/mmio_abort.c                          |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/no-vgic-v3.c                          |   2 +-
 tools/testing/selftests/kvm/{aarch64 => arm64}/page_fault_test.c                     |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/psci_test.c                           |   8 +-
 tools/testing/selftests/kvm/{aarch64 => arm64}/set_id_regs.c                         |  22 +++---
 tools/testing/selftests/kvm/{aarch64 => arm64}/smccc_filter.c                        |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vcpu_width_config.c                   |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_init.c                           |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_irq.c                            |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_lpi_stress.c                     |   0
 tools/testing/selftests/kvm/{aarch64 => arm64}/vpmu_counter_access.c                 |  19 +++--
 tools/testing/selftests/kvm/dirty_log_perf_test.c                                    |   2 +-
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/arch_timer.h                  |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/delay.h                       |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic.h                         |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3.h                      |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3_its.h                  |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/kvm_util_arch.h               |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/processor.h                   |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/spinlock.h                    |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/ucall.h                       |   0
 tools/testing/selftests/kvm/include/{aarch64 => arm64}/vgic.h                        |   0
 tools/testing/selftests/kvm/include/kvm_util.h                                       |  10 ++-
 tools/testing/selftests/kvm/include/{s390x => s390}/debug_print.h                    |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/diag318_test_handler.h           |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/facility.h                       |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/kvm_util_arch.h                  |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/processor.h                      |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/sie.h                            |   0
 tools/testing/selftests/kvm/include/{s390x => s390}/ucall.h                          |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/apic.h                           |   2 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/evmcs.h                          |   3 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/hyperv.h                         |   3 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/kvm_util_arch.h                  |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/mce.h                            |   2 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/pmu.h                            |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/processor.h                      |   2 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/sev.h                            |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/svm.h                            |   6 --
 tools/testing/selftests/kvm/include/{x86_64 => x86}/svm_util.h                       |   3 -
 tools/testing/selftests/kvm/include/{x86_64 => x86}/ucall.h                          |   0
 tools/testing/selftests/kvm/include/{x86_64 => x86}/vmx.h                            |   2 -
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic.c                             |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_private.h                     |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3.c                          |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3_its.c                      |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/handlers.S                        |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/processor.c                       |   8 +-
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/spinlock.c                        |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/ucall.c                           |   0
 tools/testing/selftests/kvm/lib/{aarch64 => arm64}/vgic.c                            |   0
 tools/testing/selftests/kvm/lib/kvm_util.c                                           |   3 +-
 tools/testing/selftests/kvm/lib/riscv/processor.c                                    |  66 ++++++++--------
 tools/testing/selftests/kvm/lib/{s390x => s390}/diag318_test_handler.c               |   0
 tools/testing/selftests/kvm/lib/{s390x => s390}/facility.c                           |   0
 tools/testing/selftests/kvm/lib/{s390x => s390}/processor.c                          |   0
 tools/testing/selftests/kvm/lib/{s390x => s390}/ucall.c                              |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/apic.c                               |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/handlers.S                           |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/hyperv.c                             |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/memstress.c                          |   2 +-
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/pmu.c                                |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/processor.c                          |   2 -
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/sev.c                                |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/svm.c                                |   1 -
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/ucall.c                              |   0
 tools/testing/selftests/kvm/lib/{x86_64 => x86}/vmx.c                                |   2 -
 tools/testing/selftests/kvm/{max_guest_memory_test.c => mmu_stress_test.c}           | 162 ++++++++++++++++++++++++++++++++++----
 tools/testing/selftests/kvm/riscv/arch_timer.c                                       |   2 +-
 tools/testing/selftests/kvm/riscv/ebreak_test.c                                      |   2 +-
 tools/testing/selftests/kvm/riscv/sbi_pmu_test.c                                     |   2 +-
 tools/testing/selftests/kvm/{s390x => s390}/cmma_test.c                              |   0
 tools/testing/selftests/kvm/{s390x => s390}/config                                   |   0
 tools/testing/selftests/kvm/{s390x => s390}/cpumodel_subfuncs_test.c                 |   0
 tools/testing/selftests/kvm/{s390x => s390}/debug_test.c                             |   0
 tools/testing/selftests/kvm/{s390x => s390}/memop.c                                  |   0
 tools/testing/selftests/kvm/{s390x => s390}/resets.c                                 |   2 +-
 tools/testing/selftests/kvm/{s390x => s390}/shared_zeropage_test.c                   |   0
 tools/testing/selftests/kvm/{s390x => s390}/sync_regs_test.c                         |   0
 tools/testing/selftests/kvm/{s390x => s390}/tprot.c                                  |   0
 tools/testing/selftests/kvm/{s390x => s390}/ucontrol_test.c                          |   0
 tools/testing/selftests/kvm/set_memory_region_test.c                                 |   6 +-
 tools/testing/selftests/kvm/steal_time.c                                             |   3 +-
 tools/testing/selftests/kvm/{x86_64 => x86}/amx_test.c                               |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/apic_bus_clock_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/cpuid_test.c                             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/debug_regs.c                             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/dirty_log_page_splitting_test.c          |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/exit_on_emulation_failure_test.c         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/feature_msrs_test.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/fix_hypercall_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/flds_emulation.h                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hwcr_msr_test.c                          |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_clock.c                           |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_cpuid.c                           |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_evmcs.c                           |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_extended_hypercalls.c             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_features.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_ipi.c                             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_svm_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_tlb_flush.c                       |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/kvm_clock_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/kvm_pv_test.c                            |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/max_vcpuid_cap_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/monitor_mwait_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/nested_exceptions_test.c                 |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.sh                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/platform_info_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/pmu_counters_test.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/pmu_event_filter_test.c                  |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_conversions_test.c           |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_kvm_exits_test.c             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/recalc_apic_map_test.c                   |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/set_boot_cpu_id.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/set_sregs_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/sev_init2_tests.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/sev_migrate_tests.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/sev_smoke_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/smaller_maxphyaddr_emulation_test.c      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/smm_test.c                               |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/state_test.c                             |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/svm_int_ctl_test.c                       |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_shutdown_test.c               |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_soft_inject_test.c            |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/svm_vmcall_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/sync_regs_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/triple_fault_event_test.c                |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/tsc_msrs_test.c                          |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/tsc_scaling_sync.c                       |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/ucna_injection_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/userspace_io_test.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/userspace_msr_exit_test.c                |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_apic_access_test.c                   |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_close_while_nested_test.c            |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_dirty_log_test.c                     |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_exception_with_invalid_guest_state.c |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_invalid_nested_guest_state.c         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_msrs_test.c                          |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_nested_tsc_scaling_test.c            |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_pmu_caps_test.c                      |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_preemption_timer_test.c              |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_set_nested_state_test.c              |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c                    |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xapic_ipi_test.c                         |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xapic_state_test.c                       |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xcr0_cpuid_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xen_shinfo_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xen_vmcall_test.c                        |   0
 tools/testing/selftests/kvm/{x86_64 => x86}/xss_msr_test.c                           |   0
 164 files changed, 587 insertions(+), 480 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/Makefile.kvm
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/aarch32_id_regs.c (95%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer_edge_cases.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/debug-exceptions.c (99%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/get-reg-list.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/hypercalls.c (98%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/mmio_abort.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/no-vgic-v3.c (98%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/page_fault_test.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/psci_test.c (96%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/set_id_regs.c (97%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/smccc_filter.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vcpu_width_config.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_init.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_irq.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_lpi_stress.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vpmu_counter_access.c (97%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/arch_timer.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/delay.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3_its.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/processor.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/spinlock.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/vgic.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/debug_print.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/diag318_test_handler.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/facility.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/processor.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/sie.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/apic.h (98%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/evmcs.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/hyperv.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/mce.h (94%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/pmu.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/processor.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/sev.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm.h (98%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm_util.h (94%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/vmx.h (99%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_private.h (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3_its.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/handlers.S (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/processor.c (98%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/spinlock.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/vgic.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/diag318_test_handler.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/facility.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/processor.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/apic.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/handlers.S (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/hyperv.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/memstress.c (98%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/pmu.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/processor.c (99%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/sev.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/svm.c (99%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/vmx.c (99%)
 rename tools/testing/selftests/kvm/{max_guest_memory_test.c => mmu_stress_test.c} (60%)
 rename tools/testing/selftests/kvm/{s390x => s390}/cmma_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/config (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/cpumodel_subfuncs_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/debug_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/memop.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/resets.c (99%)
 rename tools/testing/selftests/kvm/{s390x => s390}/shared_zeropage_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/sync_regs_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/tprot.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/ucontrol_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/amx_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/apic_bus_clock_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/cpuid_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/debug_regs.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/dirty_log_page_splitting_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/exit_on_emulation_failure_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/feature_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/fix_hypercall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/flds_emulation.h (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hwcr_msr_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_clock.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_cpuid.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_evmcs.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_extended_hypercalls.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_features.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_ipi.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_svm_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_tlb_flush.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_clock_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_pv_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/max_vcpuid_cap_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/monitor_mwait_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nested_exceptions_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.sh (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/platform_info_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_counters_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_event_filter_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_conversions_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_kvm_exits_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/recalc_apic_map_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/set_boot_cpu_id.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/set_sregs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_init2_tests.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_migrate_tests.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_smoke_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/smaller_maxphyaddr_emulation_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/smm_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_int_ctl_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_shutdown_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_soft_inject_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_vmcall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sync_regs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/triple_fault_event_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_scaling_sync.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/ucna_injection_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_io_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_msr_exit_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_apic_access_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_close_while_nested_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_dirty_log_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_exception_with_invalid_guest_state.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_invalid_nested_guest_state.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_nested_tsc_scaling_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_pmu_caps_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_preemption_timer_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_set_nested_state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_ipi_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xcr0_cpuid_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_shinfo_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_vmcall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xss_msr_test.c (100%)


From baolu.lu at linux.intel.com  Wed Dec 18 18:05:53 2024
From: baolu.lu at linux.intel.com (Baolu Lu)
Date: Thu, 19 Dec 2024 10:05:53 +0800
Subject: [PATCH v3 07/14] iommufd/viommu: Add iommufd_viommu_get_vdev_id
 helper
In-Reply-To: <21d7e63b97d81d0acf9127418a67efe386787261.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
 <21d7e63b97d81d0acf9127418a67efe386787261.1734477608.git.nicolinc@nvidia.com>
Message-ID: <56c65e50-5890-42af-85b7-85f8a1bf5cf5@linux.intel.com>

On 12/18/24 13:00, Nicolin Chen wrote:
> This is a reverse search v.s. iommufd_viommu_find_dev, as drivers may want
> to convert a struct device pointer (physical) to its virtual device ID for
> an event injection to the user space VM.
> 
> Again, this avoids exposing more core structures to the drivers, than the
> iommufd_viommu alone.
> 
> Signed-off-by: Nicolin Chen<nicolinc at nvidia.com>
> ---
>   include/linux/iommufd.h        |  8 ++++++++
>   drivers/iommu/iommufd/driver.c | 20 ++++++++++++++++++++
>   2 files changed, 28 insertions(+)
> 
> diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
> index b082676c9e43..ac1f1897d290 100644
> --- a/include/linux/iommufd.h
> +++ b/include/linux/iommufd.h
> @@ -190,6 +190,8 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
>   					     enum iommufd_object_type type);
>   struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
>   				       unsigned long vdev_id);
> +unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
> +					 struct device *dev);

Hi Nicolin,

This series overall looks good to me. But I have a question that might
be irrelevant to this series itself.

The iommufd provides both IOMMUFD_OBJ_DEVICE and IOMMUFD_OBJ_VDEVICE
objects. What is the essential difference between these two from
userspace's perspective? And, which object ID should the IOMMU device
driver provide when reporting other events in the future?

Currently, the IOMMUFD uAPI reports IOMMUFD_OBJ_DEVICE in the page
fault message, and IOMMUFD_OBJ_VDEVICE (if I understand it correctly) in
the vIRQ message. It will be more future-proof if this could be defined
clearly.

Thanks,
baolu


From fj5100bi at fujitsu.com  Wed Dec 18 18:27:11 2024
From: fj5100bi at fujitsu.com (Yoshihiro Furudera (Fujitsu))
Date: Thu, 19 Dec 2024 02:27:11 +0000
Subject: [PATCH v2 1/2] perf: Fujitsu: Add the Uncore MAC PMU driver
In-Reply-To: <20241211113909.000039d0@huawei.com>
References: <20241122061753.2598688-1-fj5100bi@fujitsu.com>
	<20241122061753.2598688-2-fj5100bi@fujitsu.com>
 <20241211113909.000039d0@huawei.com>
Message-ID: <OS3PR01MB69035A6B5F695F039B5D77C3D4062@OS3PR01MB6903.jpnprd01.prod.outlook.com>

Hi, Jonathan
Thanks for you review/comments.

> On Fri, 22 Nov 2024 06:17:52 +0000
> Yoshihiro Furudera <fj5100bi at fujitsu.com> wrote:
> 
> > This adds a new dynamic PMU to the Perf Events framework to program
> > and control the Uncore MAC PMUs in Fujitsu chips.
> >
> > This driver was created with reference to drivers/perf/qcom_l3_pmu.c.
> >
> > This driver exports formatting and event information to sysfs so it
> > can be used by the perf user space tools with the syntaxes:
> >
> > perf stat -e mac_iod0_mac0_ch0/ea-mac/ ls perf stat -e
> > mac_iod0_mac0_ch0/event=0x80/ ls
> >
> > FUJITSU-MONAKA Specification URL:
> > https://github.com/fujitsu/FUJITSU-MONAKA
> >
> > Signed-off-by: Yoshihiro Furudera <fj5100bi at fujitsu.com>
> Hi,
> 
> A few comments inline.
> 
> Thanks,
> 
> Jonathan
> 
> > diff --git a/drivers/perf/fujitsu_mac_pmu.c
> > b/drivers/perf/fujitsu_mac_pmu.c new file mode 100644 index
> > 000000000000..810f51f798a0
> > --- /dev/null
> > +++ b/drivers/perf/fujitsu_mac_pmu.c
> 
> > +/* Number of counters on each PMU */
> > +#define MAC_NUM_COUNTERS  8
> > +/* Mask for the event type field within perf_event_attr.config and EVTYPE reg
> */
> > +#define MAC_EVTYPE_MASK   0xFF
> > +
> > +/* Perfmon registers */
> > +#define MAC_PM_EVCNTR(__cntr) (0x000 + ((__cntr) & 0x7) * 8) #define
> > +MAC_PM_CNTCTL(__cntr) (0x100 + ((__cntr) & 0x7) * 8) #define
> > +MAC_PM_EVTYPE(__cntr) (0x200 + ((__cntr) & 0x7) * 8)
> 
> Do you need the masking?  As far as I can tell the idx that goes into these calls is
> capped as below MAC_NUM_COUNTERS so that masking operation will never do
> anything.  I hope the only other value that occurs (-1) is never used with these.

Understood.
I'll remove mask operation.

> 
> 
> > +#define MAC_PM_CR         0x400
> > +#define MAC_PM_CNTENSET   0x410
> > +#define MAC_PM_CNTENCLR   0x418
> > +#define MAC_PM_INTENSET   0x420
> > +#define MAC_PM_INTENCLR   0x428
> > +#define MAC_PM_OVSR       0x440
> > +
> > +/* MAC_PM_CNTCTLx */
> > +#define PMCNT_RESET           0
> > +
> > +/* MAC_PM_EVTYPEx */
> > +#define EVSEL(__val)          ((__val) & MAC_EVTYPE_MASK)
> 
> FIELD_GET() and just use the mask inline.

Thanks, I'll try using FIELD_GET.

> 
> > +
> > +/* MAC_PM_CR */
> > +#define PM_RESET              (1UL << 1)
> 
> BIT(1)

I'll change it to use BIT.
I'll change any others like it.

> 
> > +#define PM_ENABLE             (1UL << 0)
> 
> BIT(0)
> 
> > +
> > +/* MAC_PM_CNTENSET */
> > +#define PMCNTENSET(__cntr)    (1UL << ((__cntr) & 0x7))
> > +
> > +/* MAC_PM_CNTENCLR */
> > +#define PMCNTENCLR(__cntr)    (1UL << ((__cntr) & 0x7))
> With above note on whether the mask is needed and the small size of that shift.
> BIT(__cntr) should work.
> 
> > +#define PM_CNTENCLR_RESET     0xFF
> > +
> > +/* MAC_PM_INTENSET */
> > +#define PMINTENSET(__cntr)    (1UL << ((__cntr) & 0x7))
> > +
> > +/* MAC_PM_INTENCLR */
> > +#define PMINTENCLR(__cntr)    (1UL << ((__cntr) & 0x7))
> > +#define PM_INTENCLR_RESET     0xFF
> > +
> > +/* MAC_PM_OVSR */
> > +#define PMOVSRCLR(__cntr)     (1UL << ((__cntr) & 0x7))
> > +#define PMOVSRCLR_RESET       0xFF
> 
> 
> > +static int fujitsu_mac__event_init(struct perf_event *event) {
> > +	struct mac_pmu *macpmu = to_mac_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +
> > +	/* Is the event for this PMU? */
> > +	if (event->attr.type != event->pmu->type)
> > +		return -ENOENT;
> > +
> > +	/*
> > +	 * Sampling not supported
> > +	 * since these events are not core-attributable.
> Strange line wrap.
> 	 * Sampling not supported since these events are not
> 	 * core-attributable.
> 
> would be more conventional.

Thanks, I'll fix it to wrap the lines correctly.

> 
> > +	 */
> > +	if (hwc->sample_period)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * Task mode not available, we run the counters as socket counters,
> > +	 * not attributable to any CPU and therefore cannot attribute per-task.
> > +	 */
> > +	if (event->cpu < 0)
> > +		return -EINVAL;
> > +
> > +	/* Validate the group */
> > +	if (!fujitsu_mac__validate_event_group(event))
> > +		return -EINVAL;
> > +
> > +	hwc->idx = -1;
> > +
> > +	/*
> > +	 * Many perf core operations (eg. events rotation) operate on a
> > +	 * single CPU context. This is obvious for CPU PMUs, where one
> > +	 * expects the same sets of events being observed on all CPUs,
> > +	 * but can lead to issues for off-core PMUs, like this one, where
> > +	 * each event could be theoretically assigned to a different CPU.
> > +	 * To mitigate this, we enforce CPU assignment to one designated
> > +	 * processor (the one described in the "cpumask" attribute exported
> > +	 * by the PMU device). perf user space tools honor this and avoid
> > +	 * opening more than one copy of the events.
> > +	 */
> > +	event->cpu = cpumask_first(&macpmu->cpumask);
> > +
> > +	return 0;
> > +}
> >
> > +
> > +static void fujitsu_mac__event_del(struct perf_event *event, int
> > +flags) {
> > +	struct mac_pmu *macpmu = to_mac_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +
> > +	/* Stop and clean up */
> > +	fujitsu_mac__event_stop(event,  flags | PERF_EF_UPDATE);
> 
> Drop the extra space before flags.

Remove extra spaces before the flag.

> 
> > +	macpmu->events[hwc->idx] = NULL;
> > +	bitmap_release_region(macpmu->used_mask, hwc->idx, 0);
> > +
> > +	/* Propagate changes to the userspace mapping. */
> > +	perf_event_update_userpage(event);
> > +}
> 
> 
> 
> ...
> 
> > +static ssize_t cpumask_show(struct device *dev,
> > +			    struct device_attribute *attr, char *buf) {
> > +	struct mac_pmu *macpmu = to_mac_pmu(dev_get_drvdata(dev));
> If as suggested below you used an index to store the cpu rather than a one hot
> mask, you'd need to create the mask here to print it.

I'll use the CPU index.
So I will create a mask and print it.

> > +
> > +	return cpumap_print_to_pagebuf(true, buf, &macpmu->cpumask); }
> 
> ...
> 
> > +static int fujitsu_mac_pmu_online_cpu(unsigned int cpu, struct
> > +hlist_node *node) {
> > +	struct mac_pmu *macpmu = hlist_entry_safe(node, struct mac_pmu,
> > +node);
> > +
> > +	/* If there is not a CPU/PMU association pick this CPU */
> > +	if (cpumask_empty(&macpmu->cpumask))
> > +		cpumask_set_cpu(cpu, &macpmu->cpumask);
> As below. Seems like just storing the CPU index (and using -1 for not yet
> set) would be simpler than
> > +
> > +	return 0;
> > +}
> > +
> > +static int fujitsu_mac_pmu_offline_cpu(unsigned int cpu, struct
> > +hlist_node *node) {
> > +	struct mac_pmu *macpmu = hlist_entry_safe(node, struct mac_pmu,
> node);
> > +	unsigned int target;
> > +
> > +	if (!cpumask_test_and_clear_cpu(cpu, &macpmu->cpumask))
> 
> If you are only ever going to set one bit in the mask, why not just store the CPU
> index instead?

I'll use the CPU index instead.

> 
> > +		return 0;
> > +
> > +	target = cpumask_any_but(cpu_online_mask, cpu);
> > +	if (target >= nr_cpu_ids)
> > +		return 0;
> > +
> > +	perf_pmu_migrate_context(&macpmu->pmu, cpu, target);
> > +	cpumask_set_cpu(target, &macpmu->cpumask);
> > +
> > +	return 0;
> > +}
> > +
> > +static int fujitsu_mac_pmu_probe(struct platform_device *pdev) {
> > +	struct device *dev = &pdev->dev;
> > +	struct acpi_device *acpi_dev;
> > +	struct mac_pmu *macpmu;
> > +	struct resource *memrc;
> > +	char *name;
> > +	int ret;
> > +	u64 uid;
> > +
> > +	acpi_dev = ACPI_COMPANION(dev);
> > +	if (!acpi_dev)
> > +		return -ENODEV;
> > +
> > +	ret = acpi_dev_uid_to_integer(acpi_dev, &uid);
> > +	if (ret)
> > +		return dev_err_probe(dev, ret, "unable to read ACPI uid\n");
> > +
> > +	macpmu = devm_kzalloc(dev, sizeof(*macpmu), GFP_KERNEL);
> > +	name = devm_kasprintf(dev, GFP_KERNEL,
> "mac_iod%llu_mac%llu_ch%llu",
> > +			  (uid >> 8) & 0xF, (uid >> 4) & 0xF, uid & 0xF);
> > +	if (!macpmu)
> > +		return -ENOMEM;
> 
> Why allocate two before checking either?  That's an unusual pattern.
> Check if macpmu is NULL before trying to allocate name.

I'll do as you suggested.

> 
> > +
> > +	if (!name)
> > +		return -ENOMEM;
> > +
> > +	macpmu->pmu = (struct pmu) {
> > +		.parent		= dev,
> > +		.task_ctx_nr	= perf_invalid_context,
> > +
> > +		.pmu_enable	= fujitsu_mac__pmu_enable,
> > +		.pmu_disable	= fujitsu_mac__pmu_disable,
> > +		.event_init	= fujitsu_mac__event_init,
> > +		.add		= fujitsu_mac__event_add,
> > +		.del		= fujitsu_mac__event_del,
> > +		.start		= fujitsu_mac__event_start,
> > +		.stop		= fujitsu_mac__event_stop,
> > +		.read		= fujitsu_mac__event_read,
> > +
> > +		.attr_groups	= fujitsu_mac_pmu_attr_grps,
> > +		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE
> > +	};
> > +
> > +	macpmu->regs = devm_platform_get_and_ioremap_resource(pdev, 0,
> &memrc);
> > +	if (IS_ERR(macpmu->regs))
> > +		return PTR_ERR(macpmu->regs);
> > +
> > +	fujitsu_mac__init(macpmu);
> > +
> > +	ret = platform_get_irq(pdev, 0);
> > +	if (ret <= 0)
> > +		return ret;
> > +
> > +	ret = devm_request_irq(dev, ret, fujitsu_mac__handle_irq, 0,
> > +			       name, macpmu);
> > +	if (ret)
> > +		return dev_err_probe(dev, ret, "Request for IRQ failed for slice
> @%pa\n",
> > +						&memrc->start);
> > +
> > +	/* Add this instance to the list used by the offline callback */
> > +	ret =
> cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_FUJITSU_MAC_ONLINE,
> &macpmu->node);
> > +	if (ret)
> > +		return dev_err_probe(dev, ret, "Error %d registering hotplug",
> > +ret);
> > +
> > +	ret = perf_pmu_register(&macpmu->pmu, name, -1);
> > +	if (ret < 0)
> > +		return dev_err_probe(dev, ret, "Failed to register MAC PMU
> (%d)\n",
> > +ret);
> 
> dev_err_probe() already pretty prints the return value.  No need to print the
> numeric value as well.

I'll do as you suggested.

> 
> > +
> > +	dev_dbg(dev, "Registered %s, type: %d\n", name, macpmu->pmu.type);
> > +
> > +	return 0;
> > +}
> 
> > diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> > index a04b73c40173..21006d1cda59 100644
> > --- a/include/linux/cpuhotplug.h
> > +++ b/include/linux/cpuhotplug.h
> > @@ -228,6 +228,7 @@ enum cpuhp_state {
> >  	CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE,
> >  	CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
> >  	CPUHP_AP_PERF_ARM_MRVL_PEM_ONLINE,
> > +	CPUHP_AP_PERF_ARM_FUJITSU_MAC_ONLINE,
> 
> If the DYN option works for you, I think we should go with that.
> Some more recent PMU drivers are already using it without problem.

I will try to do as you suggested, but I'll check it first.

> 
> >  	CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
> >  	CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
> >  	CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,

Best Regards,
Yoshihiro Furudera

From anshuman.khandual at arm.com  Wed Dec 18 18:48:41 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 19 Dec 2024 08:18:41 +0530
Subject: [PATCH V2 04/46] arm64/sysreg: Update register fields for
 TRBIDR_EL1
In-Reply-To: <36aba488-26d7-4dc9-9ca0-a14e3de028e9@redhat.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-5-anshuman.khandual@arm.com>
 <36aba488-26d7-4dc9-9ca0-a14e3de028e9@redhat.com>
Message-ID: <8ad1e830-9ac9-4776-a877-c8d37bb03a3c@arm.com>



On 12/18/24 20:10, Eric Auger wrote:
> Hi Anshuman
> 
> On 12/10/24 06:52, Anshuman Khandual wrote:
>> This adds register fields for TRBIDR_EL1 as per the definitions based
>> on DDI0601 2024-09.
>>
>> 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 | 15 +++++++++++++--
>>  1 file changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
>> index 59351931d907..10b1a0998d99 100644
>> --- a/arch/arm64/tools/sysreg
>> +++ b/arch/arm64/tools/sysreg
>> @@ -3295,13 +3295,24 @@ Field	31:0	TRG
>>  EndSysreg
>>  
>>  Sysreg	TRBIDR_EL1	3	0	9	11	7
>> -Res0	63:12
>> +Res0	63:48
>> +Field	47:32	MaxBuffSize
>> +Res0	31:16
>> +UnsignedEnum	15:12	MPAM
>> +	0b0000	NI
>> +	0b0001	PMG
> Out of curiosity how did you choose the PMG terminology?
> I see "MPAM implemented by the Trace Buffer Unit, using default PARTID
> and PMG values in External mode". Wouldn't be TBU more meaningful?

Right, TBU seems better. Unless Mark thinks otherwise, will change.


From anshuman.khandual at arm.com  Wed Dec 18 19:13:42 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 19 Dec 2024 08:43:42 +0530
Subject: [PATCH V2 15/46] arm64/sysreg: Add register fields for PFAR_EL1
In-Reply-To: <5203176c-2646-425b-b375-edb7931ef54f@redhat.com>
References: <20241210055311.780688-1-anshuman.khandual@arm.com>
 <20241210055311.780688-16-anshuman.khandual@arm.com>
 <5203176c-2646-425b-b375-edb7931ef54f@redhat.com>
Message-ID: <c707ecfd-6f1f-47d2-93ec-116f5dfd419e@arm.com>



On 12/18/24 21:12, Eric Auger wrote:
> Hi Anshuman,
> 
> On 12/10/24 06:52, Anshuman Khandual wrote:
>> This adds register fields for PFAR_EL1 as per the definitions based on
>> DDI0601 2024-09.
>>
>> 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 | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
>> index 18b814ff2c41..e33edb41721a 100644
>> --- a/arch/arm64/tools/sysreg
>> +++ b/arch/arm64/tools/sysreg
>> @@ -3533,3 +3533,10 @@ Field	5	F
>>  Field	4	P
>>  Field	3:0	Align
>>  EndSysreg
>> +
>> +Sysreg	PFAR_EL1	3	0	6	0	5
>> +Field	63	NS
>> +Field	62	NSE
>> +Res0	61:56
>> +Field	55:0	PA
> Just wondering: part of the PA definition depends on FEAT_D128 or
> FEAT_LPA and the reset field value is UNKNOWN if the feature is not
> available. Shouldn't introduce separate fields directly?
Generated PFAR_EL1_PA_MASK aka GENMASK_ULL(55, 0) should cover all the
cases for PA i.e 48 bits, LPA, D128 etc. Although individual use cases
will have to trim the mask subsequently as required.

Are you suggesting something like the following instead where the user
will have to concatenate these fields selectively to find the required
PA mask ?

Field	55:52	PA_D128
Field	51:48	PA_LPA
Field	47:0	PA


From quic_jiegan at quicinc.com  Wed Dec 18 19:24:12 2024
From: quic_jiegan at quicinc.com (Jie Gan)
Date: Thu, 19 Dec 2024 11:24:12 +0800
Subject: [PATCH v7 4/5] Coresight: Add Coresight TMC Control Unit driver
In-Reply-To: <d09097da-a07a-4dfa-9c0d-567b329b64ac@oss.qualcomm.com>
References: <20241210031545.3468561-1-quic_jiegan@quicinc.com>
 <20241210031545.3468561-5-quic_jiegan@quicinc.com>
 <d09097da-a07a-4dfa-9c0d-567b329b64ac@oss.qualcomm.com>
Message-ID: <a6de450f-792d-429e-925e-850d11163907@quicinc.com>



On 12/15/2024 6:21 AM, Konrad Dybcio wrote:
> On 10.12.2024 4:15 AM, Jie Gan wrote:
>> The Coresight TMC Control Unit hosts miscellaneous configuration registers
>> which control various features related to TMC ETR sink.
>>
>> Based on the trace ID, which is programmed in the related CTCU ATID
>> register of a specific ETR, trace data with that trace ID gets into
>> the ETR buffer, while other trace data gets dropped.
>>
>> Enabling source device sets one bit of the ATID register based on
>> source device's trace ID.
>> Disabling source device resets the bit according to the source
>> device's trace ID.
>>
>> Signed-off-by: Jie Gan <quic_jiegan at quicinc.com>
>> ---
> 
> [...]
> 
>> +static int __ctcu_set_etr_traceid(struct coresight_device *csdev,
>> +				  u8 traceid,
>> +				  int port_num,
>> +				  bool enable)
>> +{
>> +	uint32_t atid_offset;
>> +	struct ctcu_drvdata *drvdata;
>> +	unsigned long flags;
>> +	uint32_t reg_offset;
>> +	int bit;
>> +	uint32_t val;
>> +
>> +	if (!IS_VALID_CS_TRACE_ID(traceid) || port_num < 0)
>> +		return -EINVAL;
>> +
>> +	drvdata = dev_get_drvdata(csdev->dev.parent);
>> +	if (IS_ERR_OR_NULL(drvdata))
>> +		return -EINVAL;
>> +
>> +	atid_offset = drvdata->atid_offset[port_num];
>> +	if (atid_offset == 0)
>> +		return -EINVAL;
>> +
>> +	spin_lock_irqsave(&drvdata->spin_lock, flags);
> 
> guard(raw_spinlock_irqsave)(&drvdata->spin_lock);
> 
> and drop the unlocks
> 
Sure, will fix in next version.

>> +	CS_UNLOCK(drvdata->base);
>> +
>> +	reg_offset = CTCU_ATID_REG_OFFSET(traceid, atid_offset);
>> +	bit = CTCU_ATID_REG_BIT(traceid);
>> +	if (reg_offset - atid_offset >= CTCU_ATID_REG_SIZE ||
>> +	    bit >= CORESIGHT_TRACE_IDS_MAX) {
>> +		CS_LOCK(drvdata);
>> +		spin_unlock_irqrestore(&drvdata->spin_lock, flags);
>> +		return -EINVAL;
>> +	}
>> +
>> +	val = ctcu_readl(drvdata, reg_offset);
>> +	if (enable)
>> +		val = val | BIT(bit);
>> +	else
>> +		val = val & ~BIT(bit);
>> +	ctcu_writel(drvdata, val, reg_offset);
>> +
>> +	CS_LOCK(drvdata->base);
>> +	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
>> +
>> +	return 0;
>> +}
>> +
>> +static int ctcu_get_active_port(struct coresight_device *sink, struct coresight_device *helper)
>> +{
>> +	int port, i;
>> +
>> +	for (i = 0; i < sink->pdata->nr_outconns; ++i) {
>> +		if (sink->pdata->out_conns[i]->dest_dev) {
>> +			port = sink->pdata->out_conns[i]->dest_port;
>> +			return port;
> 
> Return sink->....
Sure, will fix in next version.

> 
>> +		}
>> +	}
>> +
>> +	return -EINVAL;
>> +}
>> +
>> +/*
>> + * ctcu_set_etr_traceid: Retrieve the ATID offset and trace ID.
>> + *
>> + * Returns 0 indicates success. None-zero result means failure.
>> + */
>> +static int ctcu_set_etr_traceid(struct coresight_device *csdev,
>> +				struct cs_sink_data *sink_data,
>> +				bool enable)
>> +{
>> +	int port_num;
>> +
>> +	if (!IS_VALID_CS_TRACE_ID(sink_data->traceid) ||
>> +	    (csdev == NULL) ||
> 
> I'm not sure this can be null by the time it reaches this function
Will check.

> 
>> +	    (sink_data->sink == NULL)) {
>> +		dev_dbg(&csdev->dev, "Invalid parameters\n");
> 
> dev_err?
It's better with dev_err, will fix.

> 
>> +		return -EINVAL;
>> +	}
>> +
>> +	port_num = ctcu_get_active_port(sink_data->sink, csdev);
>> +	if (port_num < 0)
>> +		return -EINVAL;
>> +
>> +	dev_dbg(&csdev->dev, "traceid is %d\n", sink_data->traceid);
>> +
>> +	return __ctcu_set_etr_traceid(csdev, sink_data->traceid, port_num, enable);
>> +}
>> +
>> +static int ctcu_enable(struct coresight_device *csdev, enum cs_mode mode,
>> +		       void *data)
>> +{
>> +	int ret = 0;
> 
> Unnecessary initialization (you instantly overwrite it), also below
> 
>> +	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
>> +
>> +	ret = ctcu_set_etr_traceid(csdev, sink_data, true);
>> +	if (ret)
>> +		dev_dbg(&csdev->dev, "enable data filter failed\n");
> 
> Since the this function returns an int, maybe return ctcu_set_etr_traceid()
> and let the upper layer throw an error (also for some other functions in this
> file)
> 
Sure, will check.

>> +
>> +	return 0;
>> +}
>> +
>> +static int ctcu_disable(struct coresight_device *csdev, void *data)
>> +{> +	int ret = 0;
>> +	struct cs_sink_data *sink_data = (struct cs_sink_data *)data;
>> +
>> +	ret = ctcu_set_etr_traceid(csdev, sink_data, false);
>> +	if (ret)
>> +		dev_dbg(&csdev->dev, "disable data filter failed\n");
>> +
>> +	return 0;
>> +}
> 
> [...]
> 
>>   enum coresight_dev_subtype_helper {
>>   	CORESIGHT_DEV_SUBTYPE_HELPER_CATU,
>> -	CORESIGHT_DEV_SUBTYPE_HELPER_ECT_CTI
>> +	CORESIGHT_DEV_SUBTYPE_HELPER_ECT_CTI,
>> +	CORESIGHT_DEV_SUBTYPE_HELPER_CTCU
> 
> Please add a comma here too, so that future additions will be
> less noisy
Sure, will add a comma after CORESIGHT_DEV_SUBTYPE_HELPER_CTCU.


Thanks,
Jie




From dharma.b at microchip.com  Wed Dec 18 20:10:41 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Thu, 19 Dec 2024 09:40:41 +0530
Subject: [PATCH] dt-bindings: mmc: move compatible property to its specific
 binding
Message-ID: <20241219-mmc-slot-v1-1-dfc747a3d3fb@microchip.com>

Move the `compatible` property into its specific binding to make the MMC
slot more generic and modular.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
 Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml | 4 ++++
 Documentation/devicetree/bindings/mmc/mmc-slot.yaml              | 7 +------
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml b/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml
index 022682a977c6..7600a4988eca 100644
--- a/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml
+++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml
@@ -54,6 +54,10 @@ patternProperties:
       A node for each slot provided by the MMC controller
 
     properties:
+      compatible:
+        items:
+          - const: mmc-slot
+
       reg:
         enum: [0, 1, 2]
 
diff --git a/Documentation/devicetree/bindings/mmc/mmc-slot.yaml b/Documentation/devicetree/bindings/mmc/mmc-slot.yaml
index 1f0667828063..84c4605658e0 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-slot.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-slot.yaml
@@ -20,19 +20,15 @@ properties:
   $nodename:
     pattern: "^slot(@.*)?$"
 
-  compatible:
-    const: mmc-slot
-
   reg:
     description:
       the slot (or "port") ID
     maxItems: 1
 
 required:
-  - compatible
   - reg
 
-unevaluatedProperties: false
+additionalProperties: true
 
 examples:
   - |
@@ -40,7 +36,6 @@ examples:
       #address-cells = <1>;
       #size-cells = <0>;
       slot at 0 {
-        compatible = "mmc-slot";
         reg = <0>;
         bus-width = <4>;
       };

---
base-commit: 7fa366f1b6e376c38966faa42da7f0f2e013fdab
change-id: 20241219-mmc-slot-0574889daea3

Best regards,
-- 
Dharma Balasubiramani <dharma.b at microchip.com>



From wbg at kernel.org  Wed Dec 18 20:35:35 2024
From: wbg at kernel.org (William Breathitt Gray)
Date: Thu, 19 Dec 2024 13:35:35 +0900
Subject: [PATCH 4/9] counter: stm32-timer-cnt: add support for stm32mp25
In-Reply-To: <20241218090153.742869-5-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
 <20241218090153.742869-5-fabrice.gasnier@foss.st.com>
Message-ID: <Z2Oilz0GECUbovtN@ishi>

On Wed, Dec 18, 2024 at 10:01:48AM +0100, Fabrice Gasnier wrote:
> Add support for STM32MP25 SoC. There are new counter modes that may be
> implemented in later. Still, use newly introduced compatible to handle
> this new HW variant and avoid being blocked with existing compatible
> in SoC dtsi file. Modes supported currently still remains compatible.
> New timer 20 has encoder capability, add it to the list.
> 
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>

Acked-by: William Breathitt Gray <wbg at kernel.org>
-------------- 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/20241219/2756ff6a/attachment.sig>

From nicolinc at nvidia.com  Wed Dec 18 21:06:18 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Wed, 18 Dec 2024 21:06:18 -0800
Subject: [PATCH v3 07/14] iommufd/viommu: Add iommufd_viommu_get_vdev_id
 helper
In-Reply-To: <56c65e50-5890-42af-85b7-85f8a1bf5cf5@linux.intel.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
 <21d7e63b97d81d0acf9127418a67efe386787261.1734477608.git.nicolinc@nvidia.com>
 <56c65e50-5890-42af-85b7-85f8a1bf5cf5@linux.intel.com>
Message-ID: <Z2OpylDlhLXoo3dt@Asurada-Nvidia>

On Thu, Dec 19, 2024 at 10:05:53AM +0800, Baolu Lu wrote:
> On 12/18/24 13:00, Nicolin Chen wrote:
> > This is a reverse search v.s. iommufd_viommu_find_dev, as drivers may want
> > to convert a struct device pointer (physical) to its virtual device ID for
> > an event injection to the user space VM.
> > 
> > Again, this avoids exposing more core structures to the drivers, than the
> > iommufd_viommu alone.
> > 
> > Signed-off-by: Nicolin Chen<nicolinc at nvidia.com>
> > ---
> >   include/linux/iommufd.h        |  8 ++++++++
> >   drivers/iommu/iommufd/driver.c | 20 ++++++++++++++++++++
> >   2 files changed, 28 insertions(+)
> > 
> > diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
> > index b082676c9e43..ac1f1897d290 100644
> > --- a/include/linux/iommufd.h
> > +++ b/include/linux/iommufd.h
> > @@ -190,6 +190,8 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
> >   					     enum iommufd_object_type type);
> >   struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
> >   				       unsigned long vdev_id);
> > +unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
> > +					 struct device *dev);
> 
> Hi Nicolin,
> 
> This series overall looks good to me. But I have a question that might
> be irrelevant to this series itself.
> 
> The iommufd provides both IOMMUFD_OBJ_DEVICE and IOMMUFD_OBJ_VDEVICE
> objects. What is the essential difference between these two from
> userspace's perspective?

A quick answer is an IOMMUFD_OBJ_DEVICE being a host physical
device and an IOMMUFD_OBJ_VDEVICE being an IOMMUFD_OBJ_DEVICE
related to IOMMUFD_OBJ_VIOMMU. Two of them can be seen in two
different layers. May refer to this graph:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/userspace-api/iommufd.rst?h=v6.13-rc3#n150

> And, which object ID should the IOMMU device
> driver provide when reporting other events in the future?
>
> Currently, the IOMMUFD uAPI reports IOMMUFD_OBJ_DEVICE in the page
> fault message, and IOMMUFD_OBJ_VDEVICE (if I understand it correctly) in
> the vIRQ message. It will be more future-proof if this could be defined
> clearly.

A vIRQ is actually reported per-vIOMMU in this design. Although
in the this series the SMMU driver seems to report a per-device
vIRQ, it internally converts the vDEVICE to a virtual device ID
and packs the virtual device ID into a per-vIOMMU event:

+/**
+ * struct iommu_virq_arm_smmuv3 - ARM SMMUv3 Virtual IRQ
+ *                                (IOMMU_VIRQ_TYPE_ARM_SMMUV3)
+ * @evt: 256-bit ARM SMMUv3 Event record, little-endian.
+ *       (Refer to "7.3 Event records" in SMMUv3 HW Spec)
+ *
+ * StreamID field reports a virtual device ID. To receive a virtual IRQ for a
+ * device, a vDEVICE must be allocated via IOMMU_VDEVICE_ALLOC.
+ */
+struct iommu_virq_arm_smmuv3 {
+	__aligned_le64 evt[4];
 };

Thanks
Nicolin


From danishanwar at ti.com  Wed Dec 18 21:06:57 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Thu, 19 Dec 2024 10:36:57 +0530
Subject: [PATCH net-next 1/4] net: ti: Kconfig: Select HSR for ICSSG
 Driver
In-Reply-To: <Z2L/hwH5pgBV9pSB@lzaremba-mobl.ger.corp.intel.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-2-danishanwar@ti.com>
 <Z2L/hwH5pgBV9pSB@lzaremba-mobl.ger.corp.intel.com>
Message-ID: <c6254178-6e2a-47e1-ac16-22af5affc8ca@ti.com>



On 18/12/24 10:29 pm, Larysa Zaremba wrote:
> On Mon, Dec 16, 2024 at 03:30:41PM +0530, MD Danish Anwar wrote:
>> HSR offloading is supported by ICSSG driver. Select the symbol HSR for
>> TI_ICSSG_PRUETH. Also select NET_SWITCHDEV instead of depending on it to
>> remove recursive dependency.
>>
> 
> 2 things:
> 1) The explanation from the cover should have been included in the commit 
>    message.

I wanted to keep the commit message brief so I provided the actual
errors in cover letter. I will add the logs here as well.

> 2) Why not `depends on HSR`?

Adding `depends on HSR` in `config TI_ICSSG_PRUETH` is not setting HSR.
I have tried below scenarios and only one of them work.

1) depends on NET_SWITCHDEV
   depends on HSR

	HSR doesn't get set in .config - `# CONFIG_HSR is not set`. Even the
CONFIG_TI_ICSSG_PRUETH also gets unset although this is set to =m in
defconfig. But keeping both as `depends on` makes CONFIG_TI_ICSSG_PRUETH
disabled.

2) select NET_SWITCHDEV
   depends on HSR

	HSR doesn't get set in .config - `# CONFIG_HSR is not set`. Even the
CONFIG_TI_ICSSG_PRUETH also gets unset although this is set to =m in
defconfig. But keeping both as `depends on` makes CONFIG_TI_ICSSG_PRUETH
disabled.

3) depends on NET_SWITCHDEV
   select HSR
	
	Results in recursive dependency

error: recursive dependency detected!
	symbol NET_DSA depends on HSR
	symbol HSR is selected by TI_ICSSG_PRUETH
	symbol TI_ICSSG_PRUETH depends on NET_SWITCHDEV
	symbol NET_SWITCHDEV is selected by NET_DSA
For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations"

make[2]: *** [scripts/kconfig/Makefile:95: defconfig] Error 1
make[1]: *** [/home/danish/workspace/net-next/Makefile:733: defconfig]
Error 2
make: *** [Makefile:251: __sub-make] Error 2

4) select NET_SWITCHDEV
   select HSR

	HSR is set as `m` along with `CONFIG_TI_ICSSG_PRUETH`

CONFIG_HSR=m
CONFIG_NET_SWITCHDEV=y
CONFIG_TI_ICSSG_PRUETH=m

#4 is the only secnario where HSR gets built. That's why I sent the
patch with `select NET_SWITCHDEV` and `select HSR`

>  
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> ---
>>  drivers/net/ethernet/ti/Kconfig | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
>> index 0d5a862cd78a..ad366abfa746 100644
>> --- a/drivers/net/ethernet/ti/Kconfig
>> +++ b/drivers/net/ethernet/ti/Kconfig
>> @@ -187,8 +187,9 @@ config TI_ICSSG_PRUETH
>>  	select PHYLIB
>>  	select TI_ICSS_IEP
>>  	select TI_K3_CPPI_DESC_POOL
>> +	select NET_SWITCHDEV
>> +	select HSR
>>  	depends on PRU_REMOTEPROC
>> -	depends on NET_SWITCHDEV
>>  	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
>>  	depends on PTP_1588_CLOCK_OPTIONAL
>>  	help
>> -- 
>> 2.34.1
>>
>>

-- 
Thanks and Regards,
Danish


From nicolinc at nvidia.com  Wed Dec 18 21:14:21 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Wed, 18 Dec 2024 21:14:21 -0800
Subject: [PATCH] iommu/tegra241-cmdqv: Read SMMU IDR1.CMDQS instead of hardcoding
Message-ID: <20241219051421.1850267-1-nicolinc@nvidia.com>

The hardware limitation "max=19" actually comes from SMMU Command Queue.
So, it'd be more natural for tegra241-cmdqv driver to read it out rather
than hardcoding it itself.

This is not an issue yet for a kernel on a baremetal system, but a guest
kernel setting the queue base/size in form of IPA/gPA might result in a
noncontiguous queue in the physical address space, if underlying physical
pages backing up the guest RAM aren't contiguous entirely: e.g. 2MB-page
backed guest RAM cannot guarantee a contiguous queue if it is 8MB (capped
to VCMDQ_LOG2SIZE_MAX=19). This might lead to command errors when HW does
linear-read from a noncontiguous queue memory.

Adding this extra IDR1.CMDQS cap (in the guest kernel) allows VMM to set
SMMU's IDR1.CMDQS=17 for the case mentioned above, so a guest-level queue
will be capped to maximum 2MB, ensuring a contiguous queue memory.

Fixes: a3799717b881 ("iommu/tegra241-cmdqv: Fix alignment failure at max_n_shift")
Reported-by: Ian Kalinowski <ikalinowski at nvidia.com>
Cc: <stable at vger.kernel.org>
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
index 6e41ddaa24d6..d525ab43a4ae 100644
--- a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
+++ b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
@@ -79,7 +79,6 @@
 #define TEGRA241_VCMDQ_PAGE1(q)		(TEGRA241_VCMDQ_PAGE1_BASE + 0x80*(q))
 #define  VCMDQ_ADDR			GENMASK(47, 5)
 #define  VCMDQ_LOG2SIZE			GENMASK(4, 0)
-#define  VCMDQ_LOG2SIZE_MAX		19
 
 #define TEGRA241_VCMDQ_BASE		0x00000
 #define TEGRA241_VCMDQ_CONS_INDX_BASE	0x00008
@@ -505,12 +504,15 @@ static int tegra241_vcmdq_alloc_smmu_cmdq(struct tegra241_vcmdq *vcmdq)
 	struct arm_smmu_cmdq *cmdq = &vcmdq->cmdq;
 	struct arm_smmu_queue *q = &cmdq->q;
 	char name[16];
+	u32 regval;
 	int ret;
 
 	snprintf(name, 16, "vcmdq%u", vcmdq->idx);
 
-	/* Queue size, capped to ensure natural alignment */
-	q->llq.max_n_shift = min_t(u32, CMDQ_MAX_SZ_SHIFT, VCMDQ_LOG2SIZE_MAX);
+	/* Cap queue size to SMMU's IDR1.CMDQS and ensure natural alignment */
+	regval = readl_relaxed(smmu->base + ARM_SMMU_IDR1);
+	q->llq.max_n_shift =
+		min_t(u32, CMDQ_MAX_SZ_SHIFT, FIELD_GET(IDR1_CMDQS, regval));
 
 	/* Use the common helper to init the VCMDQ, and then... */
 	ret = arm_smmu_init_one_queue(smmu, q, vcmdq->page0,
-- 
2.43.0



From ja at ssi.bg  Wed Dec 18 21:06:16 2024
From: ja at ssi.bg (Julian Anastasov)
Date: Thu, 19 Dec 2024 07:06:16 +0200 (EET)
Subject: [PATCH net-next] Fix clamp() of ip_vs_conn_tab on small memory
 systems.
In-Reply-To: <5e288aa5-5374-5542-b730-f3b923ba5a36@ssi.bg>
References: <24a6bfd0811b4931b6ef40098b33c9ee@AcuMS.aculab.com> <5e288aa5-5374-5542-b730-f3b923ba5a36@ssi.bg>
Message-ID: <a0ebe11c-4ca2-d2f3-8e53-0d9f44bfdda0@ssi.bg>


	Hello,

On Tue, 17 Dec 2024, Julian Anastasov wrote:

> On Sat, 14 Dec 2024, David Laight wrote:
> 
> > The 'max_avail' value is calculated from the system memory
> > size using order_base_2().
> > order_base_2(x) is defined as '(x) ? fn(x) : 0'.
> > The compiler generates two copies of the code that follows
> > and then expands clamp(max, min, PAGE_SHIFT - 12) (11 on 32bit).
> > This triggers a compile-time assert since min is 5.
> 
> 	8 ?
> 
> > 
> > In reality a system would have to have less than 512MB memory

	Also, note that this is 512KB (practically impossible),
not 512MB. So, it can fail only on build.

Regards

--
Julian Anastasov <ja at ssi.bg>



From aneesh.kumar at kernel.org  Wed Dec 18 21:37:22 2024
From: aneesh.kumar at kernel.org (Aneesh Kumar K.V)
Date: Thu, 19 Dec 2024 11:07:22 +0530
Subject: [PATCH v6 12/43] arm64: RME: Allocate/free RECs to match vCPUs
In-Reply-To: <20241212155610.76522-13-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
 <20241212155610.76522-13-steven.price@arm.com>
Message-ID: <yq5apllos06l.fsf@kernel.org>

Steven Price <steven.price at arm.com> writes:

> +static int alloc_rec_aux(struct page **aux_pages,
> +			 u64 *aux_phys_pages,
> +			 unsigned int num_aux)
> +{
> +	int ret;
> +	unsigned int i;
> +
> +	for (i = 0; i < num_aux; i++) {
> +		struct page *aux_page;
> +		phys_addr_t aux_page_phys;
> +
> +		aux_page = alloc_page(GFP_KERNEL);
> +		if (!aux_page) {
> +			ret = -ENOMEM;
> +			goto out_err;
> +		}
> +		aux_page_phys = page_to_phys(aux_page);
> +		if (rmi_granule_delegate(aux_page_phys)) {
> +			__free_page(aux_page);
> +			ret = -ENXIO;
> +			goto out_err;
> +		}
> +		aux_pages[i] = aux_page;
> +		aux_phys_pages[i] = aux_page_phys;
> +	}
> +
> +	return 0;
> +out_err:
> +	free_rec_aux(aux_pages, i);
> +	return ret;
> +}
>

We can possibly switch the above to the alloc/free helper so that all
granule allocation is done by alloc_delegated_granule() ?

static int alloc_rec_aux(struct realm *realm, u64 *aux_phys_pages, unsigned int num_aux)
{
	int ret;
	unsigned int i;

	for (i = 0; i < num_aux; i++) {
		phys_addr_t aux_page_phys;

		aux_page_phys = alloc_delegated_granule(realm, NULL, GFP_KERNEL);
		if (aux_page_phys == PHYS_ADDR_MAX) {
			ret = -ENOMEM;
			goto out_err;
		}
		aux_phys_pages[i] = aux_page_phys;
	}

	return 0;
out_err:
	free_rec_aux(realm, aux_phys_pages, i);
	return ret;
}






From charan.pedumuru at microchip.com  Wed Dec 18 21:42:50 2024
From: charan.pedumuru at microchip.com (Charan Pedumuru)
Date: Thu, 19 Dec 2024 11:12:50 +0530
Subject: [PATCH] dt-bindings: mfd: atmel: Convert to json schema
Message-ID: <20241219-gpbr-v1-1-e19a562ebf81@microchip.com>

Convert old text based binding to json schema.
Changes during conversion:
The text binding is misleading, add a fallback `atmel,at91sam9260-gpbr`
for both `microchip,sam9x60-gpbr` and `microchip,sam9x7-gpbr` which is
missing in old binding and `microchip,sam9x60-gpbr` is not a fallback
for `microchip,sam9x7-gpbr`.

Signed-off-by: Charan Pedumuru <charan.pedumuru at microchip.com>
---
 .../bindings/mfd/atmel,at91sam9260-gpbr.yaml       | 44 ++++++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-gpbr.txt         | 18 ---------
 2 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-gpbr.yaml b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-gpbr.yaml
new file mode 100644
index 000000000000..f805545aa62a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/atmel,at91sam9260-gpbr.yaml
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/atmel,at91sam9260-gpbr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip AT91 General Purpose Backup Registers
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+
+description:
+  The system controller embeds 256 bits of General Purpose Backup
+  registers organized as 8 32-bit registers.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - atmel,at91sam9260-gpbr
+          - const: syscon
+      - items:
+          - enum:
+              - microchip,sam9x60-gpbr
+              - microchip,sam9x7-gpbr
+          - const: atmel,at91sam9260-gpbr
+          - const: syscon
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    syscon at fffffd50 {
+        compatible = "atmel,at91sam9260-gpbr", "syscon";
+        reg = <0xfffffd50 0x10>;
+    };
diff --git a/Documentation/devicetree/bindings/mfd/atmel-gpbr.txt b/Documentation/devicetree/bindings/mfd/atmel-gpbr.txt
deleted file mode 100644
index 3c989d1760a2..000000000000
--- a/Documentation/devicetree/bindings/mfd/atmel-gpbr.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-* Device tree bindings for Atmel GPBR (General Purpose Backup Registers)
-
-The GPBR are a set of battery-backed registers.
-
-Required properties:
-- compatible:		Should be one of the following:
-			"atmel,at91sam9260-gpbr", "syscon"
-			"microchip,sam9x60-gpbr", "syscon"
-			"microchip,sam9x7-gpbr", "microchip,sam9x60-gpbr", "syscon"
-- reg:			contains offset/length value of the GPBR memory
-			region.
-
-Example:
-
-gpbr: gpbr at fffffd50 {
-	compatible = "atmel,at91sam9260-gpbr", "syscon";
-	reg = <0xfffffd50 0x10>;
-};

---
base-commit: 91e71d606356e50f238d7a87aacdee4abc427f07
change-id: 20241211-gpbr-24ac0823cde5

Best regards,
-- 
Charan Pedumuru <charan.pedumuru at microchip.com>



From aneesh.kumar at kernel.org  Wed Dec 18 21:44:09 2024
From: aneesh.kumar at kernel.org (Aneesh Kumar K.V)
Date: Thu, 19 Dec 2024 11:14:09 +0530
Subject: [PATCH v6 06/43] arm64: RME: Check for RME support at KVM init
In-Reply-To: <20241212155610.76522-7-steven.price@arm.com>
References: <20241212155610.76522-1-steven.price@arm.com>
 <20241212155610.76522-7-steven.price@arm.com>
Message-ID: <yq5amsgsrzva.fsf@kernel.org>

Steven Price <steven.price at arm.com> writes:

> +static int rmi_check_version(void)
> +{
> +	struct arm_smccc_res res;
> +	int version_major, version_minor;
> +	unsigned long host_version = RMI_ABI_VERSION(RMI_ABI_MAJOR_VERSION,
> +						     RMI_ABI_MINOR_VERSION);
> +
> +	arm_smccc_1_1_invoke(SMC_RMI_VERSION, host_version, &res);
> +
> +	if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
> +		return -ENXIO;
> +
> +	version_major = RMI_ABI_VERSION_GET_MAJOR(res.a1);
> +	version_minor = RMI_ABI_VERSION_GET_MINOR(res.a1);
> +
> +	if (res.a0 != RMI_SUCCESS) {
> +		kvm_err("Unsupported RMI ABI (v%d.%d) we want v%d.%d\n",
> +			version_major, version_minor,
> +			RMI_ABI_MAJOR_VERSION,
> +			RMI_ABI_MINOR_VERSION);
> +		return -ENXIO;
> +	}
> +
> +	kvm_info("RMI ABI version %d.%d\n", version_major, version_minor);
> +
> +	return 0;
> +}
> +

Should we include both high and low version numbers in the kvm_err
message on error? ie,

	high_version_major = RMI_ABI_VERSION_GET_MAJOR(res.a2);
	high_version_minor = RMI_ABI_VERSION_GET_MINOR(res.a2);

-aneesh


From o.rempel at pengutronix.de  Wed Dec 18 21:55:08 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Thu, 19 Dec 2024 06:55:08 +0100
Subject: [PATCH v3] i2c: imx: add imx7d compatible string for applying
 errata ERR007805
In-Reply-To: <20241218044238.143414-1-carlos.song@nxp.com>
References: <20241218044238.143414-1-carlos.song@nxp.com>
Message-ID: <Z2O1PFr4ZQHXTsrX@pengutronix.de>

On Wed, Dec 18, 2024 at 12:42:38PM +0800, Carlos Song wrote:
> Compatible string "fsl,imx7d-i2c" is not exited at i2c-imx driver
                                       do not exist?
> compatible string table, at the result, "fsl,imx21-i2c" will be
> matched, but it will cause errata ERR007805 not be applied in fact.
> 
> So Add "fsl,imx7d-i2c" compatible string in i2c-imx driver to apply
> the errata ERR007805(https://www.nxp.com/webapp/Download?colCode=
> IMX7DS_2N09P).

This link is not working, may be this one:
https://www.nxp.com/docs/en/errata/IMX7DS_3N09P.pdf

More practical is to include the erratum text with list of affected SoC
variants.

> "fsl,imx7d-i2c" already is documented in binding doc. This errata

s/errata/erratum

Errata is plural
Erratum is singular

> fix has been included in imx6_i2c_hwdata and it is the same in all
> I.MX6/7/8, so just reuse it.
> 

Please Fixes tag, this patch should go stable:
Fixes: 39c025721d70 ("i2c: imx: Implement errata ERR007805 or e7805 bus frequency limit")
Cc: stable at vger.kernel.org

> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>

With fixes in the commit message you can add my:
Acked-by: Oleksij Rempel <o.rempel at pengutronix.de>

> ---
> Change for V3:
> - No ACK, so resend this patch.
> Change for V2:
> - I have tried to fix this issue at imx7s.dtsi in V1, according to
>   the community suggestion, I make V2 patch for i2c-imx driver to
>   avoid updating the FDT to fix an errata. Discussion in V1:
>   Subject: [PATCH] ARM: dts: imx7s: change i2c compatible string for applying errata ERR007805
>   Message-ID: <20241021031148.2682015-1-carlos.song at nxp.com> (raw)
> ---
>  drivers/i2c/busses/i2c-imx.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index 350346a7892c..9d5caa032c5c 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -335,6 +335,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
>  	{ .compatible = "fsl,imx6sll-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx6sx-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx6ul-i2c", .data = &imx6_i2c_hwdata, },
> +	{ .compatible = "fsl,imx7d-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx7s-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx8mm-i2c", .data = &imx6_i2c_hwdata, },
>  	{ .compatible = "fsl,imx8mn-i2c", .data = &imx6_i2c_hwdata, },
> -- 
> 2.34.1
> 
> 

-- 
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 o.rempel at pengutronix.de  Wed Dec 18 22:02:18 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Thu, 19 Dec 2024 07:02:18 +0100
Subject: [PATCH v2] i2c: imx: switch different pinctrl state in different
 system power status
In-Reply-To: <20241218044114.143358-1-carlos.song@nxp.com>
References: <20241218044114.143358-1-carlos.song@nxp.com>
Message-ID: <Z2O26jWagFtsWJd8@pengutronix.de>

On Wed, Dec 18, 2024 at 12:41:14PM +0800, Carlos Song wrote:
> Switch different pinctrl state in different system power status.
> 
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Reviewed-by: Frank Li <Frank.Li at nxp.com>
> ---
> Change for V2:
> - Add Frank reviewed-by. No code change.
> ---
>  drivers/i2c/busses/i2c-imx.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index b6ed270dd04b..350346a7892c 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -1871,6 +1871,7 @@ static int i2c_imx_runtime_suspend(struct device *dev)
>  	struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
>  
>  	clk_disable(i2c_imx->clk);
> +	pinctrl_pm_select_sleep_state(dev);
>  
>  	return 0;
>  }
> @@ -1880,6 +1881,7 @@ static int i2c_imx_runtime_resume(struct device *dev)
>  	struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
>  	int ret;
>  
> +	pinctrl_pm_select_default_state(dev);

Both pinctrl_pm_select_sleep_state() and
pinctrl_pm_select_default_state() may fail. Please use return values.

-- 
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 o.rempel at pengutronix.de  Wed Dec 18 22:04:39 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Thu, 19 Dec 2024 07:04:39 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <20241218043541.143194-1-carlos.song@nxp.com>
References: <20241218043541.143194-1-carlos.song@nxp.com>
Message-ID: <Z2O3d5Kke7zIr4IW@pengutronix.de>

On Wed, Dec 18, 2024 at 12:35:41PM +0800, Carlos Song wrote:
> Return -EPROBE_DEFER when dma_request_slave_channel() because DMA driver
> have not ready yet.
> 
> Move i2c_imx_dma_request() before registering I2C adapter to avoid
> infinite loop of .probe() calls to the same driver, see "e8c220fac415
> Revert "i2c: imx: improve the error handling in i2c_imx_dma_request()""
> and "Documentation/driver-api/driver-model/driver.rst".
> 
> Use CPU mode to avoid stuck registering i2c adapter when DMA resources
> are unavailable.
> 
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Signed-off-by: Clark Wang <xiaoning.wang at nxp.com>
> Acked-by: Ahmad Fatoum <a.fatoum at pengutronix.de>

Acked-by: Oleksij Rempel <o.rempel at pengutronix.de>

Thank you!

-- 
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 wei.fang at nxp.com  Wed Dec 18 22:13:40 2024
From: wei.fang at nxp.com (Wei Fang)
Date: Thu, 19 Dec 2024 14:13:40 +0800
Subject: [PATCH v2 2/2] arm64: dts: imx95-19x19-evk: add ENETC 0 support
In-Reply-To: <20241219061340.1633173-1-wei.fang@nxp.com>
References: <20241219061340.1633173-1-wei.fang@nxp.com>
Message-ID: <20241219061340.1633173-3-wei.fang@nxp.com>

Add ENETC 0 (1G ethernet port) support for i.MX95-19x19-EVK board. In
addition, because all ENETC instances share MDIO bus, so enable EMDIO
at the same time.

Signed-off-by: Wei Fang <wei.fang at nxp.com>
---
 .../boot/dts/freescale/imx95-19x19-evk.dts    | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
index 6086cb7fa5a0..8bc066c3760c 100644
--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -22,6 +22,7 @@ / {
 	compatible = "fsl,imx95-19x19-evk", "fsl,imx95";
 
 	aliases {
+		ethernet0 = &enetc_port0;
 		gpio0 = &gpio1;
 		gpio1 = &gpio2;
 		gpio2 = &gpio3;
@@ -193,6 +194,14 @@ sound-wm8962 {
 	};
 };
 
+&enetc_port0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enetc0>;
+	phy-handle = <&ethphy0>;
+	phy-mode = "rgmii-id";
+	status = "okay";
+};
+
 &flexspi1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexspi1>;
@@ -338,6 +347,25 @@ &mu7 {
 	status = "okay";
 };
 
+&netcmix_blk_ctrl {
+	status = "okay";
+};
+
+&netc_blk_ctrl {
+	status = "okay";
+};
+
+&netc_emdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_emdio>;
+	status = "okay";
+
+	ethphy0: ethernet-phy at 1 {
+		reg = <1>;
+		realtek,clkout-disable;
+	};
+};
+
 &pcie0 {
 	pinctrl-0 = <&pinctrl_pcie0>;
 	pinctrl-names = "default";
@@ -429,6 +457,30 @@ &wdog3 {
 };
 
 &scmi_iomuxc {
+	pinctrl_emdio: emdiogrp{
+		fsl,pins = <
+			IMX95_PAD_ENET1_MDC__NETCMIX_TOP_NETC_MDC		0x57e
+			IMX95_PAD_ENET1_MDIO__NETCMIX_TOP_NETC_MDIO		0x97e
+		>;
+	};
+
+	pinctrl_enetc0: enetc0grp {
+		fsl,pins = <
+			IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3		0x57e
+			IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2		0x57e
+			IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1		0x57e
+			IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0		0x57e
+			IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL	0x57e
+			IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK	0x58e
+			IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL	0x57e
+			IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK	0x58e
+			IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0		0x57e
+			IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1		0x57e
+			IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2		0x57e
+			IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3		0x57e
+		>;
+	};
+
 	pinctrl_flexspi1: flexspi1grp {
 		fsl,pins = <
 			IMX95_PAD_XSPI1_SS0_B__FLEXSPI1_A_SS0_B			0x3fe
-- 
2.34.1



From wei.fang at nxp.com  Wed Dec 18 22:13:38 2024
From: wei.fang at nxp.com (Wei Fang)
Date: Thu, 19 Dec 2024 14:13:38 +0800
Subject: [PATCH v2 0/2] Add NETC support for i.MX95
Message-ID: <20241219061340.1633173-1-wei.fang@nxp.com>

We have added support for i.MX95 NETC related drivers, so it's time to
add NETC related nodes in DTS and enable the use of ENETC 0.

---
v1 link: https://lore.kernel.org/imx/20241218061725.1608466-1-wei.fang at nxp.com/
v2 changes:
1. Adjust the order of the nodes
2. Change the subject of patch 2
---

Wei Fang (2):
  arm64: dts: imx95: add NETC related nodes
  arm64: dts: imx95-19x19-evk: add ENETC 0 support

 .../boot/dts/freescale/imx95-19x19-evk.dts    | 52 ++++++++++
 arch/arm64/boot/dts/freescale/imx95.dtsi      | 94 +++++++++++++++++++
 2 files changed, 146 insertions(+)

-- 
2.34.1



From wei.fang at nxp.com  Wed Dec 18 22:13:39 2024
From: wei.fang at nxp.com (Wei Fang)
Date: Thu, 19 Dec 2024 14:13:39 +0800
Subject: [PATCH v2 1/2] arm64: dts: imx95: add NETC related nodes
In-Reply-To: <20241219061340.1633173-1-wei.fang@nxp.com>
References: <20241219061340.1633173-1-wei.fang@nxp.com>
Message-ID: <20241219061340.1633173-2-wei.fang@nxp.com>

Add NETC related nodes for i.MX95.

Signed-off-by: Wei Fang <wei.fang at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx95.dtsi | 94 ++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index e9c7a8265d71..8b0eb1d835e8 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -1697,10 +1697,104 @@ sai2: sai at 4c880000 {
 			status = "disabled";
 		};
 
+		netc_blk_ctrl: system-controller at 4cde0000 {
+			compatible = "nxp,imx95-netc-blk-ctrl";
+			reg = <0x0 0x4cde0000 0x0 0x10000>,
+			      <0x0 0x4cdf0000 0x0 0x10000>,
+			      <0x0 0x4c81000c 0x0 0x18>;
+			reg-names = "ierb", "prb", "netcmix";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			power-domains = <&scmi_devpd IMX95_PD_NETC>;
+			assigned-clocks = <&scmi_clk IMX95_CLK_ENET>,
+					  <&scmi_clk IMX95_CLK_ENETREF>;
+			assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD2>,
+						 <&scmi_clk IMX95_CLK_SYSPLL1_PFD0>;
+			assigned-clock-rates = <666666666>, <250000000>;
+			clocks = <&scmi_clk IMX95_CLK_ENET>;
+			clock-names = "ipg";
+			status = "disabled";
+
+			netc_bus0: pcie at 4ca00000 {
+				compatible = "pci-host-ecam-generic";
+				reg = <0x0 0x4ca00000 0x0 0x100000>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
+				bus-range = <0x0 0x0>;
+				msi-map = <0x0 &its 0x60 0x1>,	//ENETC0 PF
+					  <0x10 &its 0x61 0x1>, //ENETC0 VF0
+					  <0x20 &its 0x62 0x1>, //ENETC0 VF1
+					  <0x40 &its 0x63 0x1>, //ENETC1 PF
+					  <0x80 &its 0x64 0x1>, //ENETC2 PF
+					  <0x90 &its 0x65 0x1>, //ENETC2 VF0
+					  <0xa0 &its 0x66 0x1>, //ENETC2 VF1
+					  <0xc0 &its 0x67 0x1>; //NETC Timer
+					 /* ENETC0~2 and Timer BAR0 - non-prefetchable memory */
+				ranges = <0x82000000 0x0 0x4cc00000  0x0 0x4cc00000  0x0 0xe0000
+					 /* Timer BAR2 - prefetchable memory */
+					 0xc2000000 0x0 0x4cd00000  0x0 0x4cd00000  0x0 0x10000
+					 /* ENETC0~2: VF0-1 BAR0 - non-prefetchable memory */
+					 0x82000000 0x0 0x4cd20000  0x0 0x4cd20000  0x0 0x60000
+					 /* ENETC0~2: VF0-1 BAR2 - prefetchable memory */
+					 0xc2000000 0x0 0x4cd80000  0x0 0x4cd80000  0x0 0x60000>;
+
+				enetc_port0: ethernet at 0,0 {
+					compatible = "pci1131,e101";
+					reg = <0x000000 0 0 0 0>;
+					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
+					clock-names = "ref";
+					status = "disabled";
+				};
+
+				enetc_port1: ethernet at 8,0 {
+					compatible = "pci1131,e101";
+					reg = <0x004000 0 0 0 0>;
+					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
+					clock-names = "ref";
+					status = "disabled";
+				};
+
+				enetc_port2: ethernet at 10,0 {
+					compatible = "pci1131,e101";
+					reg = <0x008000 0 0 0 0>;
+					status = "disabled";
+				};
+
+				netc_timer: ethernet at 18,0 {
+					reg = <0x00c000 0 0 0 0>;
+					status = "disabled";
+				};
+			};
+
+			netc_bus1: pcie at 4cb00000 {
+				compatible = "pci-host-ecam-generic";
+				reg = <0x0 0x4cb00000 0x0 0x100000>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
+				bus-range = <0x1 0x1>;
+					 /* EMDIO BAR0 - non-prefetchable memory */
+				ranges = <0x82000000 0x0 0x4cce0000  0x0 0x4cce0000  0x0 0x20000
+					 /* EMDIO BAR2 - prefetchable memory */
+					 0xc2000000 0x0 0x4cd10000  0x0 0x4cd10000  0x0 0x10000>;
+
+				netc_emdio: mdio at 0,0 {
+					compatible = "pci1131,ee00";
+					reg = <0x010000 0 0 0 0>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+					status = "disabled";
+				};
+			};
+		};
+
 		ddr-pmu at 4e090dc0 {
 			compatible = "fsl,imx95-ddr-pmu", "fsl,imx93-ddr-pmu";
 			reg = <0x0 0x4e090dc0 0x0 0x200>;
 			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 		};
+
 	};
 };
-- 
2.34.1



From thomas.weissschuh at linutronix.de  Wed Dec 18 22:30:26 2024
From: thomas.weissschuh at linutronix.de (Thomas =?utf-8?Q?Wei=C3=9Fschuh?=)
Date: Thu, 19 Dec 2024 07:30:26 +0100
Subject: [PATCH 07/17] riscv: vdso: Switch to generic storage
 implementation
In-Reply-To: <137c0594-e178-4c91-bc8b-5f99b3ddb2f0@app.fastmail.com>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-7-f7aed1bdb3b2@linutronix.de>
 <20241218-action-matchbook-571b597b7f55@spud>
 <20241218162031-ee920684-db10-4f17-b1cb-50373d7ea954@linutronix.de>
 <137c0594-e178-4c91-bc8b-5f99b3ddb2f0@app.fastmail.com>
Message-ID: <20241219072552-7cd4512c-4f61-408a-9422-167a6f2810db@linutronix.de>

On Wed, Dec 18, 2024 at 05:35:31PM +0100, Arnd Bergmann wrote:
> On Wed, Dec 18, 2024, at 16:46, Thomas Wei?schuh wrote:
> > On Wed, Dec 18, 2024 at 03:08:28PM +0000, Conor Dooley wrote:
> >> On Mon, Dec 16, 2024 at 03:10:03PM +0100, Thomas Wei?schuh wrote:
> 
> >> Might be a clang thing, allmodconfig with clang doesn't build either.
> >
> > The proposed generic storage infrastructure currently expects that all
> > its users also use HAVE_GENERIC_VDSO.
> > I missed rv32 when checking this assumption.
> >
> > I can add a bunch of ifdefs into the storage code to handle this.
> >
> > Or we re-add the time vDSO functions which were removed in commit
> > d4c08b9776b3 ("riscv: Use latest system call ABI").
> > Today there are upstream ports of musl and glibc which can use them.
> > (currently musl even tries to use __vdso_clock_gettime() as 64-bit only
> > on rv32 due to a copy-and-paste error from its rv64 code)
> 
> Adding back __vdso_clock_gettime() wouldn't work on rv32 because there
> is no fallback syscall for it, and it wouldn't really help since
> there is no existing userspace that uses time32 structures.

My original paragraph was worded confusingly.
It was about re-adding time-related vDSO function *in general*, not the
specific 32-bit ones.
The new ones should be 64-bit only, indeed.

> > There is precedence in providing 64bit only vDSO functions, for example
> > __vdso_clock_gettime64() in arm.
> > I do have a small, so far untested, proof-of-concept patch for it.
> > This would even be less code than the ifdefs.
> >
> > What do you think about it?
> 
> Yes, simply exposing the normal time64 syscalls through vdso
> should be fine. I think this currently works on everything except
> rv32 and sparc32, probably because neither of them have actual
> users that are able to test.

Should it use the specific _vdso_clock_gettime64() naming or leave out
the 64 suffix?


General Note: I'll continue working on this next year.


Thanks,
Thomas


From ck.hu at mediatek.com  Wed Dec 18 22:52:00 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 19 Dec 2024 06:52:00 +0000
Subject: [PATCH v3 06/33] drm/mediatek: Add support for MT8195 Digital
 Parallel Interface
In-Reply-To: <20241217154345.276919-7-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-7-angelogioacchino.delregno@collabora.com>
Message-ID: <4256dda4b6aed2688b4aaa4affb2e039a8f960dd.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add support for the DPI block found in the MT8195 and MT8188 SoCs.
> Inside of the SoC, this block is directly connected to the HDMI IP.

Note: there is discussion in [1].

[1] https://patchwork.kernel.org/project/linux-mediatek/patch/20241120124420.133914-7-angelogioacchino.delregno at collabora.com/

Regards,
CK

> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c      | 55 ++++++++++++++++++++++---
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  6 +++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  2 +
>  3 files changed, 58 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index ed9849ad3e79..334ab9be2f31 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -144,6 +144,7 @@ struct mtk_dpi_factor {
>   * @csc_enable_bit: Enable bit of CSC.
>   * @pixels_per_iter: Quantity of transferred pixels per iteration.
>   * @edge_cfg_in_mmsys: If the edge configuration for DPI's output needs to be set in MMSYS.
> + * @is_internal_hdmi: Specifies whether the DPI is internally connected to the HDMI block
>   */
>  struct mtk_dpi_conf {
>         const struct mtk_dpi_factor *dpi_factor;
> @@ -164,6 +165,7 @@ struct mtk_dpi_conf {
>         u32 csc_enable_bit;
>         u32 pixels_per_iter;
>         bool edge_cfg_in_mmsys;
> +       bool is_internal_hdmi;
>  };
> 
>  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
> @@ -492,6 +494,7 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
> 
>         mtk_dpi_disable(dpi);
>         clk_disable_unprepare(dpi->pixel_clk);
> +       clk_disable_unprepare(dpi->tvd_clk);
>         clk_disable_unprepare(dpi->engine_clk);
>  }
> 
> @@ -508,6 +511,12 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>                 goto err_refcount;
>         }
> 
> +       ret = clk_prepare_enable(dpi->tvd_clk);
> +       if (ret) {
> +               dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +               goto err_engine;
> +       }
> +
>         ret = clk_prepare_enable(dpi->pixel_clk);
>         if (ret) {
>                 dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
> @@ -517,6 +526,8 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>         return 0;
> 
>  err_pixel:
> +       clk_disable_unprepare(dpi->tvd_clk);
> +err_engine:
>         clk_disable_unprepare(dpi->engine_clk);
>  err_refcount:
>         dpi->refcount--;
> @@ -584,7 +595,9 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>         struct videomode vm = { 0 };
> 
>         drm_display_mode_to_videomode(mode, &vm);
> -       mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
> +
> +       if (!dpi->conf->is_internal_hdmi)
> +               mtk_dpi_set_pixel_clk(dpi, &vm, mode->clock);
> 
>         dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
>         dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
> @@ -647,10 +660,18 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>         if (dpi->conf->support_direct_pin) {
>                 mtk_dpi_config_yc_map(dpi, dpi->yc_map);
>                 mtk_dpi_config_2n_h_fre(dpi);
> -               mtk_dpi_dual_edge(dpi);
> +               /* DPI can connect to either an external bridge or the internal HDMI encoder */
> +               if (dpi->conf->is_internal_hdmi) {
> +                       mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN, DPI_OUTPUT_1T1P_EN);
> +                       mtk_dpi_mask(dpi, DPI_CON,
> +                                    dpi->conf->input_2pixel ? DPI_INPUT_2P_EN : 0,
> +                                    DPI_INPUT_2P_EN);
> +               } else {
> +                       mtk_dpi_dual_edge(dpi);
> +               }
>                 mtk_dpi_config_disable_edge(dpi);
>         }
> -       if (dpi->conf->input_2pixel) {
> +       if (dpi->conf->input_2pixel && !dpi->conf->is_internal_hdmi) {
>                 mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
>                              DPINTF_INPUT_2P_EN);
>         }
> @@ -919,14 +940,16 @@ void mtk_dpi_start(struct device *dev)
>  {
>         struct mtk_dpi *dpi = dev_get_drvdata(dev);
> 
> -       mtk_dpi_power_on(dpi);
> +       if (!dpi->conf->is_internal_hdmi)
> +               mtk_dpi_power_on(dpi);
>  }
> 
>  void mtk_dpi_stop(struct device *dev)
>  {
>         struct mtk_dpi *dpi = dev_get_drvdata(dev);
> 
> -       mtk_dpi_power_off(dpi);
> +       if (!dpi->conf->is_internal_hdmi)
> +               mtk_dpi_power_off(dpi);
>  }
> 
>  unsigned int mtk_dpi_encoder_index(struct device *dev)
> @@ -1021,6 +1044,8 @@ static const struct mtk_dpi_factor dpi_factor_mt8195_dp_intf[] = {
>         { 70000 - 1, 4 }, { 200000 - 1, 2 }, { U32_MAX, 1 }
>  };
> 
> +static const struct mtk_dpi_factor dpi_factor_mt8195_dpi = { U32_MAX, 1 };
> +
>  static const struct mtk_dpi_conf mt8173_conf = {
>         .dpi_factor = dpi_factor_mt8173,
>         .num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8173),
> @@ -1113,6 +1138,25 @@ static const struct mtk_dpi_conf mt8192_conf = {
>         .csc_enable_bit = CSC_ENABLE,
>  };
> 
> +static const struct mtk_dpi_conf mt8195_conf = {
> +       .dpi_factor = &dpi_factor_mt8195_dpi,
> +       .num_dpi_factor = 1,
> +       .max_clock_khz = 594000,
> +       .output_fmts = mt8183_output_fmts,
> +       .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> +       .pixels_per_iter = 1,
> +       .is_ck_de_pol = true,
> +       .swap_input_support = true,
> +       .support_direct_pin = true,
> +       .dimension_mask = HPW_MASK,
> +       .hvsize_mask = HSIZE_MASK,
> +       .channel_swap_shift = CH_SWAP,
> +       .yuv422_en_bit = YUV422_EN,
> +       .csc_enable_bit = CSC_ENABLE,
> +       .is_internal_hdmi = true,
> +       .input_2pixel = true,
> +};
> +
>  static const struct mtk_dpi_conf mt8195_dpintf_conf = {
>         .dpi_factor = dpi_factor_mt8195_dp_intf,
>         .num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8195_dp_intf),
> @@ -1216,6 +1260,7 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>         { .compatible = "mediatek,mt8188-dp-intf", .data = &mt8195_dpintf_conf },
>         { .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf },
>         { .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf },
> +       { .compatible = "mediatek,mt8195-dpi", .data = &mt8195_conf },
>         { /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> index a0b1d18bbbf7..3c24d9e9f241 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -40,6 +40,12 @@
>  #define FAKE_DE_LEVEN                  BIT(21)
>  #define FAKE_DE_RODD                   BIT(22)
>  #define FAKE_DE_REVEN                  BIT(23)
> +
> +/* DPI_CON: DPI instances */
> +#define DPI_OUTPUT_1T1P_EN             BIT(24)
> +#define DPI_INPUT_2P_EN                        BIT(25)
> +
> +/* DPI_CON: DPINTF instances */
>  #define DPINTF_YUV422_EN               BIT(24)
>  #define DPINTF_CSC_ENABLE              BIT(26)
>  #define DPINTF_INPUT_2P_EN             BIT(29)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 49af2b19a85a..ad1eb91067c0 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -805,6 +805,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DPI },
>         { .compatible = "mediatek,mt8195-dp-intf",
>           .data = (void *)MTK_DP_INTF },
> +       { .compatible = "mediatek,mt8195-dpi",
> +         .data = (void *)MTK_DPI },
>         { .compatible = "mediatek,mt2701-dsi",
>           .data = (void *)MTK_DSI },
>         { .compatible = "mediatek,mt8173-dsi",
> --
> 2.47.0
> 


From tomi.valkeinen at ideasonboard.com  Wed Dec 18 22:58:36 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Thu, 19 Dec 2024 08:58:36 +0200
Subject: [PATCH v4 0/3] drm: xlnx: zynqmp: Add DP audio support
In-Reply-To: <20241023-xilinx-dp-audio-v4-0-5128881457be@ideasonboard.com>
References: <20241023-xilinx-dp-audio-v4-0-5128881457be@ideasonboard.com>
Message-ID: <008c6590-eeee-4721-85f8-1ccd861abaac@ideasonboard.com>

Hi,

On 23/10/2024 14:52, Tomi Valkeinen wrote:
> Add DisplayPort audio support for Xilinx ZynqMP platforms.
> 
> The current DT is, for some reason, missing the DMA channels for the
> audio. This series adds that to the bindings and the dts file, but to
> support older dtb files without the audio DMA, the driver will not fail
> if the audio DMA is missing, but will just mark the audio support as
> disabled.
> 
> To: Lars-Peter Clausen <lars at metafoo.de>
> To: Jaroslav Kysela <perex at perex.cz>
> To: Takashi Iwai <tiwai at suse.com>
> To: Liam Girdwood <lgirdwood at gmail.com>
> To: Mark Brown <broonie at kernel.org>
> To: Laurent Pinchart <laurent.pinchart at ideasonboard.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: 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: Michal Simek <michal.simek at amd.com>
> To: Krzysztof Kozlowski <krzk+dt at kernel.org>
> Cc: linux-sound at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: dri-devel at lists.freedesktop.org
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: Vishal Sagar <vishal.sagar at amd.com>
> Cc: Anatoliy Klymenko <anatoliy.klymenko at amd.com>
> Cc: P?ter Ujfalusi <peter.ujfalusi at gmail.com>
> Cc: Markus Elfring <Markus.Elfring at web.de>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> 
> Changes in v4:
> - Update copyright year
> - Use guard(mutex) in the zynqmp_dp_audio.c
> - Add Rb and Ab tags
> - Link to v3: https://lore.kernel.org/r/20240910-xilinx-dp-audio-v3-0-75560793f4d0 at ideasonboard.com
> 
> Changes in v3:
> - Expand the description in "dt-bindings: display/xlnx/zynqmp-dpsub: Add
>    audio DMAs" to be more clear about the DT binding change.
> - Rebased on top of current upstream
> - Link to v2: https://lore.kernel.org/r/20240319-xilinx-dp-audio-v2-0-92d6d3a7ca7e at ideasonboard.com
> 
> Changes in v2:
> - Fix a missing double-quote in the DT binding
> - Link to v1: https://lore.kernel.org/r/20240312-xilinx-dp-audio-v1-0-696c79facbb9 at ideasonboard.com
> 
> ---
> Tomi Valkeinen (3):
>        dt-bindings: display/xlnx/zynqmp-dpsub: Add audio DMAs
>        arm64: dts: zynqmp: Add DMA for DP audio
>        drm: xlnx: zynqmp_dpsub: Add DP audio support
> 
>   .../bindings/display/xlnx/xlnx,zynqmp-dpsub.yaml   |  10 +-
>   arch/arm64/boot/dts/xilinx/zynqmp.dtsi             |   7 +-
>   drivers/gpu/drm/xlnx/Kconfig                       |   9 +
>   drivers/gpu/drm/xlnx/Makefile                      |   1 +
>   drivers/gpu/drm/xlnx/zynqmp_disp.c                 |  48 ---
>   drivers/gpu/drm/xlnx/zynqmp_disp_regs.h            |   7 +-
>   drivers/gpu/drm/xlnx/zynqmp_dp.c                   |  54 ++-
>   drivers/gpu/drm/xlnx/zynqmp_dp.h                   |   7 +
>   drivers/gpu/drm/xlnx/zynqmp_dp_audio.c             | 447 +++++++++++++++++++++
>   drivers/gpu/drm/xlnx/zynqmp_dpsub.c                |  39 +-
>   drivers/gpu/drm/xlnx/zynqmp_dpsub.h                |  15 +-
>   11 files changed, 539 insertions(+), 105 deletions(-)
> ---
> base-commit: 42f7652d3eb527d03665b09edac47f85fb600924
> change-id: 20240312-xilinx-dp-audio-468ad12f9f64
> 
> Best regards,

Pushed to drm-misc-next.

  Tomi



From carlos.song at nxp.com  Wed Dec 18 23:02:28 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Thu, 19 Dec 2024 07:02:28 +0000
Subject: [PATCH v2] i2c: imx: switch different pinctrl state in different
 system power status
In-Reply-To: <Z2O26jWagFtsWJd8@pengutronix.de>
References: <20241218044114.143358-1-carlos.song@nxp.com>
 <Z2O26jWagFtsWJd8@pengutronix.de>
Message-ID: <AM0PR0402MB39376D08D11CA4CCF6F88F29E8062@AM0PR0402MB3937.eurprd04.prod.outlook.com>

Thank you! I will fix it at V3.

> -----Original Message-----
> From: Oleksij Rempel <o.rempel at pengutronix.de>
> Sent: Thursday, December 19, 2024 2:02 PM
> To: Carlos Song <carlos.song at nxp.com>
> Cc: andi.shyti at kernel.org; Frank Li <frank.li at nxp.com>;
> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> Subject: [EXT] Re: [PATCH v2] i2c: imx: switch different pinctrl state in different
> system power status
>
> 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 Wed, Dec 18, 2024 at 12:41:14PM +0800, Carlos Song wrote:
> > Switch different pinctrl state in different system power status.
> >
> > Signed-off-by: Carlos Song <carlos.song at nxp.com>
> > Reviewed-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > Change for V2:
> > - Add Frank reviewed-by. No code change.
> > ---
> >  drivers/i2c/busses/i2c-imx.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/i2c/busses/i2c-imx.c
> > b/drivers/i2c/busses/i2c-imx.c index b6ed270dd04b..350346a7892c 100644
> > --- a/drivers/i2c/busses/i2c-imx.c
> > +++ b/drivers/i2c/busses/i2c-imx.c
> > @@ -1871,6 +1871,7 @@ static int i2c_imx_runtime_suspend(struct device
> *dev)
> >       struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
> >
> >       clk_disable(i2c_imx->clk);
> > +     pinctrl_pm_select_sleep_state(dev);
> >
> >       return 0;
> >  }
> > @@ -1880,6 +1881,7 @@ static int i2c_imx_runtime_resume(struct device
> *dev)
> >       struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
> >       int ret;
> >
> > +     pinctrl_pm_select_default_state(dev);
>
> Both pinctrl_pm_select_sleep_state() and
> pinctrl_pm_select_default_state() may fail. Please use return values.
>
> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C556bac4a4d18
> 45fe9c6e08dd1ff2b262%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7
> C638701849411172324%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOn
> RydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3
> D%3D%7C0%7C%7C%7C&sdata=Gd6mIwBSMo6f03z3rVIInaPZXQXhCeyFEHYYl
> ctBPZQ%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |


From arnd at arndb.de  Wed Dec 18 23:03:24 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 19 Dec 2024 08:03:24 +0100
Subject: [PATCH 07/17] riscv: vdso: Switch to generic storage implementation
In-Reply-To: <20241219072552-7cd4512c-4f61-408a-9422-167a6f2810db@linutronix.de>
References: <20241216-vdso-store-rng-v1-0-f7aed1bdb3b2@linutronix.de>
 <20241216-vdso-store-rng-v1-7-f7aed1bdb3b2@linutronix.de>
 <20241218-action-matchbook-571b597b7f55@spud>
 <20241218162031-ee920684-db10-4f17-b1cb-50373d7ea954@linutronix.de>
 <137c0594-e178-4c91-bc8b-5f99b3ddb2f0@app.fastmail.com>
 <20241219072552-7cd4512c-4f61-408a-9422-167a6f2810db@linutronix.de>
Message-ID: <0bdeda72-73e6-4749-8d54-66c7614a6f83@app.fastmail.com>

On Thu, Dec 19, 2024, at 07:30, Thomas Wei?schuh wrote:
> On Wed, Dec 18, 2024 at 05:35:31PM +0100, Arnd Bergmann wrote:
>>
>> > There is precedence in providing 64bit only vDSO functions, for example
>> > __vdso_clock_gettime64() in arm.
>> > I do have a small, so far untested, proof-of-concept patch for it.
>> > This would even be less code than the ifdefs.
>> >
>> > What do you think about it?
>> 
>> Yes, simply exposing the normal time64 syscalls through vdso
>> should be fine. I think this currently works on everything except
>> rv32 and sparc32, probably because neither of them have actual
>> users that are able to test.
>
> Should it use the specific _vdso_clock_gettime64() naming or leave out
> the 64 suffix?

The VDSO function name should match the syscall name, with the '64'
suffix. Any syscall ending in _time64 uses the __kernel_time64_t
derived types, while the corresponding syscall names that don't end
in _time64 take a __kernel_old_time_t, which is defined as
__kernel_long_t and only 32 bits wide.

      Arnd


From cohuck at redhat.com  Wed Dec 18 23:05:06 2024
From: cohuck at redhat.com (Cornelia Huck)
Date: Thu, 19 Dec 2024 08:05:06 +0100
Subject: [PATCH v4 1/3] arm64: Modify _midr_range() functions to read
 MIDR/REVIDR internally
In-Reply-To: <20241218105345.73472-2-shameerali.kolothum.thodi@huawei.com>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
 <20241218105345.73472-2-shameerali.kolothum.thodi@huawei.com>
Message-ID: <87r064b1b1.fsf@redhat.com>

On Wed, Dec 18 2024, Shameer Kolothum <shameerali.kolothum.thodi at huawei.com> wrote:

> These changes lay the groundwork for adding support for guest kernels,
> allowing them to leverage target CPU implementations provided by the
> VMM.
>
> No functional changes intended.
>
> Suggested-by: Oliver Upton <oliver.upton at linux.dev>
> Reviewed-by: Sebastian Ott <sebott at redhat.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  arch/arm64/include/asm/cputype.h     | 28 ++++++++++++++--------------
>  arch/arm64/include/asm/mmu.h         |  3 +--
>  arch/arm64/kernel/cpu_errata.c       | 23 +++++++++++++----------
>  arch/arm64/kernel/cpufeature.c       |  6 +++---
>  arch/arm64/kernel/proton-pack.c      | 17 ++++++++---------
>  arch/arm64/kvm/vgic/vgic-v3.c        |  2 +-
>  drivers/clocksource/arm_arch_timer.c |  2 +-
>  7 files changed, 41 insertions(+), 40 deletions(-)

Reviewed-by: Cornelia Huck <cohuck at redhat.com>



From michal.swiatkowski at linux.intel.com  Wed Dec 18 23:02:10 2024
From: michal.swiatkowski at linux.intel.com (Michal Swiatkowski)
Date: Thu, 19 Dec 2024 08:02:10 +0100
Subject: [PATCH net-next 2/4] net: ti: icssg-prueth: Add VLAN support in
 EMAC mode
In-Reply-To: <20241216100044.577489-3-danishanwar@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-3-danishanwar@ti.com>
Message-ID: <Z2PE5m8R5lM4/YRT@mev-dev.igk.intel.com>

On Mon, Dec 16, 2024 at 03:30:42PM +0530, MD Danish Anwar wrote:
> Add support for vlan filtering in dual EMAC mode.
> 
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> ---
>  drivers/net/ethernet/ti/icssg/icssg_prueth.c | 29 +++++++++-----------
>  1 file changed, 13 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> index c568c84a032b..e031bccf31dc 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> @@ -822,19 +822,18 @@ static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev,
>  {
>  	struct prueth_emac *emac = netdev_priv(ndev);
>  	struct prueth *prueth = emac->prueth;
> +	int port_mask = BIT(emac->port_id);
>  	int untag_mask = 0;
> -	int port_mask;
>  
> -	if (prueth->is_hsr_offload_mode) {
> -		port_mask = BIT(PRUETH_PORT_HOST) | BIT(emac->port_id);
> -		untag_mask = 0;
> +	if (prueth->is_hsr_offload_mode)
> +		port_mask |= BIT(PRUETH_PORT_HOST);
>  
> -		netdev_dbg(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
> -			   vid, port_mask, untag_mask);
> +	netdev_err(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
> +		   vid, port_mask, untag_mask);
> +
> +	icssg_vtbl_modify(emac, vid, port_mask, untag_mask, true);
> +	icssg_set_pvid(emac->prueth, vid, emac->port_id);
>  
> -		icssg_vtbl_modify(emac, vid, port_mask, untag_mask, true);
> -		icssg_set_pvid(emac->prueth, vid, emac->port_id);
> -	}
>  	return 0;
>  }
>  
> @@ -843,18 +842,16 @@ static int emac_ndo_vlan_rx_del_vid(struct net_device *ndev,
>  {
>  	struct prueth_emac *emac = netdev_priv(ndev);
>  	struct prueth *prueth = emac->prueth;
> +	int port_mask = BIT(emac->port_id);
>  	int untag_mask = 0;
> -	int port_mask;
>  
> -	if (prueth->is_hsr_offload_mode) {
> +	if (prueth->is_hsr_offload_mode)
>  		port_mask = BIT(PRUETH_PORT_HOST);
> -		untag_mask = 0;
>  
> -		netdev_dbg(emac->ndev, "VID del vid:%u port_mask:%X untag_mask  %X\n",
> -			   vid, port_mask, untag_mask);
> +	netdev_err(emac->ndev, "VID del vid:%u port_mask:%X untag_mask  %X\n",
> +		   vid, port_mask, untag_mask);
Why error? It doesn't look like error path, previously there was
netdev_dbg (made more sense in my opinion)

> +	icssg_vtbl_modify(emac, vid, port_mask, untag_mask, false);
>  
> -		icssg_vtbl_modify(emac, vid, port_mask, untag_mask, false);
> -	}
>  	return 0;
>  }
>  
> -- 
> 2.34.1


From cohuck at redhat.com  Wed Dec 18 23:07:17 2024
From: cohuck at redhat.com (Cornelia Huck)
Date: Thu, 19 Dec 2024 08:07:17 +0100
Subject: [PATCH v4 2/3] KVM: arm64: Introduce hypercall support for
 retrieving target implementations
In-Reply-To: <20241218105345.73472-3-shameerali.kolothum.thodi@huawei.com>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
 <20241218105345.73472-3-shameerali.kolothum.thodi@huawei.com>
Message-ID: <87o718b17e.fsf@redhat.com>

On Wed, Dec 18 2024, Shameer Kolothum <shameerali.kolothum.thodi at huawei.com> wrote:

> If the Guest requires migration to multiple targets, this hypercall
> will provide a way to retrieve the target CPU implementations from
> the user space VMM.
>
> Subsequent patch will use this to enable the associated errata.
>
> Suggested-by: Oliver Upton <oliver.upton at linux.dev>
> Reviewed-by: Sebastian Ott <sebott at redhat.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  Documentation/virt/kvm/arm/hypercalls.rst | 30 +++++++++++++++++++++++
>  include/linux/arm-smccc.h                 |  7 ++++++
>  2 files changed, 37 insertions(+)

Reviewed-by: Cornelia Huck <cohuck at redhat.com>



From cohuck at redhat.com  Wed Dec 18 23:09:12 2024
From: cohuck at redhat.com (Cornelia Huck)
Date: Thu, 19 Dec 2024 08:09:12 +0100
Subject: [PATCH v4 3/3] arm64: paravirt: Enable errata based on
 implementation CPUs
In-Reply-To: <20241218105345.73472-4-shameerali.kolothum.thodi@huawei.com>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
 <20241218105345.73472-4-shameerali.kolothum.thodi@huawei.com>
Message-ID: <87ldwcb147.fsf@redhat.com>

On Wed, Dec 18 2024, Shameer Kolothum <shameerali.kolothum.thodi at huawei.com> wrote:

> Retrieve any migration target implementation CPUs using the hypercall
> and enable associated errata.
>
> Reviewed-by: Sebastian Ott <sebott at redhat.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  arch/arm64/include/asm/cputype.h  | 25 +++++++++++++++++++++++--
>  arch/arm64/include/asm/paravirt.h |  3 +++
>  arch/arm64/kernel/cpu_errata.c    | 20 +++++++++++++++++---
>  arch/arm64/kernel/cpufeature.c    |  2 ++
>  arch/arm64/kernel/image-vars.h    |  2 ++
>  arch/arm64/kernel/paravirt.c      | 31 +++++++++++++++++++++++++++++++
>  6 files changed, 78 insertions(+), 5 deletions(-)

Reviewed-by: Cornelia Huck <cohuck at redhat.com>



From carlos.song at nxp.com  Wed Dec 18 23:10:11 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Thu, 19 Dec 2024 07:10:11 +0000
Subject: [PATCH v3] i2c: imx: add imx7d compatible string for applying
 errata ERR007805
In-Reply-To: <Z2O1PFr4ZQHXTsrX@pengutronix.de>
References: <20241218044238.143414-1-carlos.song@nxp.com>
 <Z2O1PFr4ZQHXTsrX@pengutronix.de>
Message-ID: <AM0PR0402MB39379D10473292DA6533A757E8062@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Oleksij Rempel <o.rempel at pengutronix.de>
> Sent: Thursday, December 19, 2024 1:55 PM
> To: Carlos Song <carlos.song at nxp.com>
> Cc: andi.shyti at kernel.org; Frank Li <frank.li at nxp.com>;
> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Bough
> Chen <haibo.chen at nxp.com>
> Subject: [EXT] Re: [PATCH v3] i2c: imx: add imx7d compatible string for applying
> errata ERR007805
>
> 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 Wed, Dec 18, 2024 at 12:42:38PM +0800, Carlos Song wrote:
> > Compatible string "fsl,imx7d-i2c" is not exited at i2c-imx driver
>                                        do not exist?
> > compatible string table, at the result, "fsl,imx21-i2c" will be
> > matched, but it will cause errata ERR007805 not be applied in fact.
> >
> > So Add "fsl,imx7d-i2c" compatible string in i2c-imx driver to apply
> > the errata
> > ERR007805(https://eur01.safelinks.protection.outlook.com/?url=https%3A
> > %2F%2Fwww.nxp.com%2Fwebapp%2FDownload%3FcolCode%3D&data=05%
> 7C02%7Ccarl
> >
> os.song%40nxp.com%7C958101ea901c4404272f08dd1ff1bb7f%7C686ea1d3bc2
> b4c6
> >
> fa92cd99c5c301635%7C0%7C0%7C638701845332883650%7CUnknown%7CTW
> FpbGZsb3d
> >
> 8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoi
> T
> >
> WFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=gLJgTRfX8KgwxAIm7GHP
> TKgbQx3
> > 4f6p2lyaRna0BD%2BU%3D&reserved=0
> > IMX7DS_2N09P).
>
> This link is not working, may be this one:
> https://www.nxp/
> .com%2Fdocs%2Fen%2Ferrata%2FIMX7DS_3N09P.pdf&data=05%7C02%7Ccarl
> os.song%40nxp.com%7C958101ea901c4404272f08dd1ff1bb7f%7C686ea1d3bc2
> b4c6fa92cd99c5c301635%7C0%7C0%7C638701845332903180%7CUnknown%7
> CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXa
> W4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=xhrAk7
> %2FVbIWyXGr9ltpprMNimJjAX%2BfFrxQ%2BUvj7wZs%3D&reserved=0
>
> More practical is to include the erratum text with list of affected SoC variants.
>
> > "fsl,imx7d-i2c" already is documented in binding doc. This errata
>
> s/errata/erratum
>
> Errata is plural
> Erratum is singular
>
> > fix has been included in imx6_i2c_hwdata and it is the same in all
> > I.MX6/7/8, so just reuse it.
> >
>
> Please Fixes tag, this patch should go stable:
> Fixes: 39c025721d70 ("i2c: imx: Implement errata ERR007805 or e7805 bus
> frequency limit")
> Cc: stable at vger.kernel.org
>
> > Signed-off-by: Carlos Song <carlos.song at nxp.com>
> > Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
>
> With fixes in the commit message you can add my:
> Acked-by: Oleksij Rempel <o.rempel at pengutronix.de>
>

Hi, I have remake the commit log referring to your comment.
Is this what you expected? If yes, please let me know. I will apply it at V4 and add your
Acked-by.

It will be this in V4:

    i2c: imx: add imx7d compatible string for applying erratum ERR007805

    Compatible string "fsl,imx7d-i2c" is not exited at i2c-imx driver
    compatible string table, at the result, "fsl,imx21-i2c" will be
    matched, but it will cause erratum ERR007805 not be applied in fact.

    So Add "fsl,imx7d-i2c" compatible string in i2c-imx driver to apply
    the erratum ERR007805(https://www.nxp.com/docs/en/errata/IMX7DS_3N09P.pdf).

    "
    ERR007805 I2C: When the I2C clock speed is configured for 400 kHz,
    the SCL low period violates the I2C spec of 1.3 uS min

    Description: When the I2C module is programmed to operate at the
    maximum clock speed of 400 kHz (as defined by the I2C spec), the SCL
    clock low period violates the I2C spec of 1.3 uS min. The user must
    reduce the clock speed to obtain the SCL low time to meet the 1.3us
    I2C minimum required. This behavior means the SoC is not compliant
    to the I2C spec at 400kHz.

    Workaround: To meet the clock low period requirement in fast speed
    mode, SCL must be configured to 384KHz or less.
    "

    "fsl,imx7d-i2c" already is documented in binding doc. This erratum
    fix has been included in imx6_i2c_hwdata and it is the same in all
    I.MX6/7/8, so just reuse it.

    Fixes: 39c025721d70 ("i2c: imx: Implement errata ERR007805 or e7805 bus frequency limit")
    Cc: stable at vger.kernel.org
    Signed-off-by: Carlos Song <carlos.song at nxp.com>
    Signed-off-by: Haibo Chen <haibo.chen at nxp.com>

> > ---
> > Change for V3:
> > - No ACK, so resend this patch.
> > Change for V2:
> > - I have tried to fix this issue at imx7s.dtsi in V1, according to
> >   the community suggestion, I make V2 patch for i2c-imx driver to
> >   avoid updating the FDT to fix an errata. Discussion in V1:
> >   Subject: [PATCH] ARM: dts: imx7s: change i2c compatible string for
> applying errata ERR007805
> >   Message-ID: <20241021031148.2682015-1-carlos.song at nxp.com> (raw)
> > ---
> >  drivers/i2c/busses/i2c-imx.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/i2c/busses/i2c-imx.c
> > b/drivers/i2c/busses/i2c-imx.c index 350346a7892c..9d5caa032c5c 100644
> > --- a/drivers/i2c/busses/i2c-imx.c
> > +++ b/drivers/i2c/busses/i2c-imx.c
> > @@ -335,6 +335,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
> >       { .compatible = "fsl,imx6sll-i2c", .data = &imx6_i2c_hwdata, },
> >       { .compatible = "fsl,imx6sx-i2c", .data = &imx6_i2c_hwdata, },
> >       { .compatible = "fsl,imx6ul-i2c", .data = &imx6_i2c_hwdata, },
> > +     { .compatible = "fsl,imx7d-i2c", .data = &imx6_i2c_hwdata, },
> >       { .compatible = "fsl,imx7s-i2c", .data = &imx6_i2c_hwdata, },
> >       { .compatible = "fsl,imx8mm-i2c", .data = &imx6_i2c_hwdata, },
> >       { .compatible = "fsl,imx8mn-i2c", .data = &imx6_i2c_hwdata, },
> > --
> > 2.34.1
> >
> >
>
> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C958101ea901c
> 4404272f08dd1ff1bb7f%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7
> C638701845332917054%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOn
> RydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3
> D%3D%7C0%7C%7C%7C&sdata=Zc4%2BMIZBmbv7BsAELQk9jKNtmhMTGxcdT
> mytHTYdNag%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |


From ck.hu at mediatek.com  Wed Dec 18 23:22:27 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 19 Dec 2024 07:22:27 +0000
Subject: [PATCH v3 07/33] dt-bindings: display: mediatek: Add binding for
 MT8195 HDMI-TX v2
In-Reply-To: <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>
Message-ID: <745f02d04c4a7080cee094b91c5338d9d25fbdb7.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Add a binding for the HDMI TX v2 Encoder found in MediaTek MT8195
> and MT8188 SoCs.
> 
> This fully supports the HDMI Specification 2.0b, hence it provides
> support for 3D-HDMI, Polarity inversion, up to 16 bits Deep Color,
> color spaces including RGB444, YCBCR420/422/444 (ITU601/ITU709) and
> xvYCC, with output resolutions up to 3840x2160p at 60Hz.
> 
> Moreover, it also supports HDCP 1.4 and 2.3, Variable Refresh Rate
> (VRR) and Consumer Electronics Control (CEC).
> 
> This IP also includes support for HDMI Audio, including IEC60958
> and IEC61937 SPDIF, 8-channel PCM, DSD, and other lossless audio
> according to HDMI 2.0.

NOTE: There is discussion in [1].

[1] https://patchwork.kernel.org/project/linux-mediatek/patch/20241205114518.53527-8-angelogioacchino.delregno at collabora.com/

Regards,
CK

> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  .../mediatek/mediatek,mt8195-hdmi.yaml        | 154 ++++++++++++++++++
>  1 file changed, 154 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
> new file mode 100644
> index 000000000000..73b1dfaa1adb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml
> @@ -0,0 +1,154 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: https://urldefense.com/v3/__http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml*__;Iw!!CTRNKA9wMg0ARbw!iD_SefgVLlM0QdRazs33_spkjaIsc7gApEpGuJVf4jlsCGxK5FDtrYyCXsU1b3nyfXa7NNCClYTy3QmDmR61FjTWAi9G$
> +$schema: https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!iD_SefgVLlM0QdRazs33_spkjaIsc7gApEpGuJVf4jlsCGxK5FDtrYyCXsU1b3nyfXa7NNCClYTy3QmDmR61FqSQzM6e$
> +
> +title: MediaTek HDMI-TX v2 Encoder
> +
> +maintainers:
> +  - AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> +  - CK Hu <ck.hu at mediatek.com>
> +
> +description:
> +  The MediaTek HDMI-TX v2 encoder can generate HDMI format data based on
> +  the HDMI Specification 2.0b.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt8188-hdmi-tx
> +      - mediatek,mt8195-hdmi-tx
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: HDMI Peripheral Bus (APB) clock
> +      - description: HDCP and HDMI_TOP clock
> +      - description: HDCP and HDMI_TOP reference clock
> +      - description: VPP HDMI Split clock
> +
> +  clock-names:
> +    items:
> +      - const: bus
> +      - const: hdcp
> +      - const: hdcp24m
> +      - const: hdmi-split
> +
> +  i2c:
> +    type: object
> +    $ref: /schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
> +    unevaluatedProperties: false
> +    description: HDMI DDC I2C controller
> +
> +  phys:
> +    maxItems: 1
> +    description: PHY providing clocking TMDS and pixel to controller
> +
> +  phy-names:
> +    items:
> +      - const: hdmi
> +
> +  pinctrl-0: true
> +
> +  pinctrl-names:
> +    items:
> +      - const: default
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  '#sound-dai-cells':
> +    const: 1
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Input port, usually connected to the output port of a DPI
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Output port that must be connected either to the input port of
> +          a HDMI connector node containing a ddc-i2c-bus, or to the input
> +          port of an attached bridge chip, such as a SlimPort transmitter.
> +
> +    required:
> +      - port at 0
> +      - port at 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - interrupts
> +  - power-domains
> +  - phys
> +  - phy-names
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt8195-clk.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        hdmi-tx at 1c300000 {
> +            compatible = "mediatek,mt8195-hdmi-tx";
> +            reg = <0 0x1c300000 0 0x1000>;
> +            clocks = <&topckgen CLK_TOP_HDMI_APB>,
> +                     <&topckgen CLK_TOP_HDCP>,
> +                     <&topckgen CLK_TOP_HDCP_24M>,
> +                     <&vppsys1 CLK_VPP1_VPP_SPLIT_HDMI>;
> +            clock-names = "bus", "hdcp", "hdcp24m", "hdmi-split";
> +            interrupts = <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH 0>;
> +            phys = <&hdmi_phy>;
> +            phy-names = "hdmi";
> +            power-domains = <&spm MT8195_POWER_DOMAIN_HDMI_TX>;
> +            pinctrl-names = "default";
> +            pinctrl-0 = <&hdmi_pins>;
> +            #sound-dai-cells = <1>;
> +
> +            hdmitx_ddc: i2c {
> +                compatible = "mediatek,mt8195-hdmi-ddc";
> +                clocks = <&clk26m>;
> +            };
> +
> +            ports {
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +
> +                port at 0 {
> +                    reg = <0>;
> +
> +                    hdmi_in: endpoint {
> +                        remote-endpoint = <&dpi1_out>;
> +                    };
> +                };
> +
> +                port at 1 {
> +                    reg = <1>;
> +
> +                    hdmi_out: endpoint {
> +                        remote-endpoint = <&hdmi_connector_in>;
> +                    };
> +                };
> +            };
> +        };
> +    };
> --
> 2.47.0
> 


From michal.swiatkowski at linux.intel.com  Wed Dec 18 23:28:14 2024
From: michal.swiatkowski at linux.intel.com (Michal Swiatkowski)
Date: Thu, 19 Dec 2024 08:28:14 +0100
Subject: [PATCH net-next 3/4] net: ti: icssg-prueth: Add Multicast
 Filtering support for VLAN in MAC mode
In-Reply-To: <20241216100044.577489-4-danishanwar@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-4-danishanwar@ti.com>
Message-ID: <Z2PLDqqrLdXhLtAF@mev-dev.igk.intel.com>

On Mon, Dec 16, 2024 at 03:30:43PM +0530, MD Danish Anwar wrote:
> Add multicast filtering support for VLAN interfaces in dual EMAC mode
> for ICSSG driver.
> 
> The driver uses vlan_for_each() API to get the list of available
> vlans. The driver then sync mc addr of vlan interface with a locally
> mainatined list emac->vlan_mcast_list[vid] using __hw_addr_sync_multiple()
> API.
> 
> The driver then calls the sync / unsync callbacks and based on whether
> the ndev is vlan or not, driver passes appropriate vid to FDB helper
> functions.
> 
> This commit also exports __hw_addr_sync_multiple() in order to use it
> from the ICSSG driver.
> 
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> ---
>  drivers/net/ethernet/ti/icssg/icssg_prueth.c | 69 ++++++++++++++++----
>  drivers/net/ethernet/ti/icssg/icssg_prueth.h |  6 ++
>  include/linux/netdevice.h                    |  3 +
>  net/core/dev_addr_lists.c                    |  7 +-
>  4 files changed, 68 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> index e031bccf31dc..a18773ef6eab 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> @@ -472,30 +472,43 @@ const struct icss_iep_clockops prueth_iep_clockops = {
>  
>  static int icssg_prueth_add_mcast(struct net_device *ndev, const u8 *addr)
>  {
> -	struct prueth_emac *emac = netdev_priv(ndev);
> -	int port_mask = BIT(emac->port_id);
> +	struct net_device *real_dev;
> +	struct prueth_emac *emac;
> +	int port_mask;
> +	u8 vlan_id;
>  
> -	port_mask |= icssg_fdb_lookup(emac, addr, 0);
> -	icssg_fdb_add_del(emac, addr, 0, port_mask, true);
> -	icssg_vtbl_modify(emac, 0, port_mask, port_mask, true);
> +	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
> +	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
Looks like a helper for that can be nice to have.

> +	emac = netdev_priv(real_dev);
> +
> +	port_mask = BIT(emac->port_id) | icssg_fdb_lookup(emac, addr, vlan_id);
> +	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, true);
> +	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, true);
>  
>  	return 0;
>  }
>  
>  static int icssg_prueth_del_mcast(struct net_device *ndev, const u8 *addr)
>  {
> -	struct prueth_emac *emac = netdev_priv(ndev);
> -	int port_mask = BIT(emac->port_id);
> +	struct net_device *real_dev;
> +	struct prueth_emac *emac;
>  	int other_port_mask;
> +	int port_mask;
> +	u8 vlan_id;
> +
> +	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
> +	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
> +	emac = netdev_priv(real_dev);
>  
> -	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, 0);
> +	port_mask = BIT(emac->port_id);
> +	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, vlan_id);
>  
> -	icssg_fdb_add_del(emac, addr, 0, port_mask, false);
> -	icssg_vtbl_modify(emac, 0, port_mask, port_mask, false);
> +	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, false);
> +	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, false);
>  
>  	if (other_port_mask) {
> -		icssg_fdb_add_del(emac, addr, 0, other_port_mask, true);
> -		icssg_vtbl_modify(emac, 0, other_port_mask, other_port_mask, true);
> +		icssg_fdb_add_del(emac, addr, vlan_id, other_port_mask, true);
> +		icssg_vtbl_modify(emac, vlan_id, other_port_mask, other_port_mask, true);
>  	}
>  
>  	return 0;
> @@ -531,6 +544,28 @@ static int icssg_prueth_hsr_del_mcast(struct net_device *ndev, const u8 *addr)
>  	return 0;
>  }
>  
> +static int icssg_update_vlan_mcast(struct net_device *vdev, int vid,
> +				   void *args)
> +{
> +	struct net_device *vport_ndev;
> +	struct prueth_emac *emac;
> +
> +	if (!vdev || !vid)
> +		return 0;
> +
> +	vport_ndev = vlan_dev_real_dev(vdev);
> +	emac = netdev_priv(vport_ndev);
> +
> +	netif_addr_lock_bh(vdev);
> +	__hw_addr_sync_multiple(&emac->vlan_mcast_list[vid], &vdev->mc, vdev->addr_len);
Only question, why dev_mc_sync_multiple can't be used here?

> +	netif_addr_unlock_bh(vdev);
> +
> +	__hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
> +			   icssg_prueth_add_mcast, icssg_prueth_del_mcast);
> +
> +	return 0;
> +}
> +
>  /**
>   * emac_ndo_open - EMAC device open
>   * @ndev: network adapter device
> @@ -772,12 +807,17 @@ static void emac_ndo_set_rx_mode_work(struct work_struct *work)
>  		return;
>  	}
>  
> -	if (emac->prueth->is_hsr_offload_mode)
> +	if (emac->prueth->is_hsr_offload_mode) {
>  		__dev_mc_sync(ndev, icssg_prueth_hsr_add_mcast,
>  			      icssg_prueth_hsr_del_mcast);
> -	else
> +	} else {
>  		__dev_mc_sync(ndev, icssg_prueth_add_mcast,
>  			      icssg_prueth_del_mcast);
> +		if (rtnl_trylock()) {
> +			vlan_for_each(ndev, icssg_update_vlan_mcast, NULL);
> +			rtnl_unlock();
> +		}
> +	}
>  }
>  
>  /**
> @@ -828,6 +868,7 @@ static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev,
>  	if (prueth->is_hsr_offload_mode)
>  		port_mask |= BIT(PRUETH_PORT_HOST);
>  
> +	__hw_addr_init(&emac->vlan_mcast_list[vid]);
>  	netdev_err(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
>  		   vid, port_mask, untag_mask);
>  
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> index f5c1d473e9f9..4da8b87408b5 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> @@ -83,6 +83,10 @@
>  #define ICSS_CMD_ADD_FILTER 0x7
>  #define ICSS_CMD_ADD_MAC 0x8
>  
> +/* VLAN Filtering Related MACROs */
> +#define PRUETH_DFLT_VLAN_MAC	0
> +#define MAX_VLAN_ID		256
> +
>  /* In switch mode there are 3 real ports i.e. 3 mac addrs.
>   * however Linux sees only the host side port. The other 2 ports
>   * are the switch ports.
> @@ -201,6 +205,8 @@ struct prueth_emac {
>  	/* RX IRQ Coalescing Related */
>  	struct hrtimer rx_hrtimer;
>  	unsigned long rx_pace_timeout_ns;
> +
> +	struct netdev_hw_addr_list vlan_mcast_list[MAX_VLAN_ID];
>  };
>  
>  /**
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index d917949bba03..a5c169b19543 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -4685,6 +4685,9 @@ int devm_register_netdev(struct device *dev, struct net_device *ndev);
>  /* General hardware address lists handling functions */
>  int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
>  		   struct netdev_hw_addr_list *from_list, int addr_len);
> +int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> +			    struct netdev_hw_addr_list *from_list,
> +			    int addr_len);
>  void __hw_addr_unsync(struct netdev_hw_addr_list *to_list,
>  		      struct netdev_hw_addr_list *from_list, int addr_len);
>  int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
> diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
> index 166e404f7c03..90716bd736f3 100644
> --- a/net/core/dev_addr_lists.c
> +++ b/net/core/dev_addr_lists.c
> @@ -242,9 +242,9 @@ static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list,
>  	__hw_addr_del_entry(from_list, ha, false, false);
>  }
>  
> -static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> -				   struct netdev_hw_addr_list *from_list,
> -				   int addr_len)
> +int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> +			    struct netdev_hw_addr_list *from_list,
> +			    int addr_len)
>  {
>  	int err = 0;
>  	struct netdev_hw_addr *ha, *tmp;
> @@ -260,6 +260,7 @@ static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
>  	}
>  	return err;
>  }
> +EXPORT_SYMBOL(__hw_addr_sync_multiple);
>  
>  /* This function only works where there is a strict 1-1 relationship
>   * between source and destination of they synch. If you ever need to
> -- 
> 2.34.1


From andyshrk at 163.com  Wed Dec 18 23:39:09 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:09 +0800
Subject: [PATCH v7 1/9] drm/rockchip: vop2: Support 32x8 superblock afbc
In-Reply-To: <20241219073931.3997788-1-andyshrk@163.com>
References: <20241219073931.3997788-1-andyshrk@163.com>
Message-ID: <20241219073931.3997788-2-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

This is the only afbc format supported by the upcoming
VOP for rk3576.

Add support for it.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v2)

Changes in v2:
- split it from main patch add support for rk3576

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index b5f35839d5e8..efe7d0cbe155 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1454,16 +1454,18 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
 	if (afbc_en) {
-		u32 stride;
+		u32 stride, block_w;
+
+		/* the afbc superblock is 16 x 16 or 32 x 8 */
+		block_w = fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ? 32 : 16;
 
-		/* the afbc superblock is 16 x 16 */
 		afbc_format = vop2_convert_afbc_format(fb->format->format);
 
 		/* Enable color transform for YTR */
 		if (fb->modifier & AFBC_FORMAT_MOD_YTR)
 			afbc_format |= (1 << 4);
 
-		afbc_tile_num = ALIGN(actual_w, 16) >> 4;
+		afbc_tile_num = ALIGN(actual_w, block_w) / block_w;
 
 		/*
 		 * AFBC pic_vir_width is count by pixel, this is different
@@ -1474,6 +1476,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 			drm_dbg_kms(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n",
 				    vp->id, win->data->name, stride);
 
+		 /* It's for head stride, each head size is 16 byte */
+		stride = ALIGN(stride, block_w) / block_w * 16;
+
 		uv_swap = vop2_afbc_uv_swap(fb->format->format);
 		/*
 		 * This is a workaround for crazy IC design, Cluster
@@ -1504,7 +1509,11 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1);
 
-		vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
+		if (fb->modifier & AFBC_FORMAT_MOD_SPLIT)
+			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 1);
+		else
+			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
+
 		transform_offset = vop2_afbc_transform_offset(pstate, half_block_en);
 		vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
 		vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
-- 
2.34.1



From andyshrk at 163.com  Wed Dec 18 23:39:08 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:08 +0800
Subject: [PATCH v7 0/9] VOP Support for rk3576
Message-ID: <20241219073931.3997788-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>


Here is the V7, because I find that I missed sync with Heiko's
dp+dsi maxclk verification patch[0]:

Patches that have already been merged in V6 are dropped.

PATCH 1~7 are preparations for rk3576 support
PATCH 8~9 are real support for rk376

I test it with a 1080P/4K HDMI output with modetest and weston
output.

If there are some one want to have a try, I have a tree based on
Linux 6.13-rc2 here[1]

[0]https://lore.kernel.org/linux-rockchip/20241115151131.416830-1-heiko at sntech.de/
[1]https://github.com/andyshrk/linux/tree/rk3576-vop2-upstream-v6

Changes in v7:
- Fix rk3588 dp+dsi maxclk verification

Changes in v6:
- Add a blank line after hardware version check code
-  More specific explanation about the AXI_BUS_ID register bit of
   cluster window.

Changes in v5:
- Add axi id configuration
- Remove the non-existent CBCR scale register.

Changes in v4:
- Typo fix: selet->select

Changes in v3:
- Add comments for why we should treat rk3566 with special care.
- Add hardware version check
- Add comments for why we should treat rk3566 with special care.
- ordered by soc name
- Add description for newly added interrupt
- Share the alpha setup function with rk3568
- recoder the code block by soc

Changes in v2:
- split it from main patch add support for rk3576
- Add platform specific callback
- Introduce vop hardware version
- Add dt bindings
- Add platform specific callback

Andy Yan (9):
  drm/rockchip: vop2: Support 32x8 superblock afbc
  drm/rockchip: vop2: Add platform specific callback
  drm/rockchip: vop2: Support for different layer select configuration
    between VPs
  drm/rockchip: vop2: Introduce vop hardware version
  drm/rockchip: vop2: Register the primary plane and overlay plane
    separately
  drm/rockchip: vop2: Set plane possible crtcs by possible vp mask
  drm/rockchip: vop2: Add uv swap for cluster window
  dt-bindings: display: vop2: Add rk3576 support
  drm/rockchip: vop2: Add support for rk3576

 .../display/rockchip/rockchip-vop2.yaml       |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  | 1454 +++----------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h  |  271 ++-
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c  | 1797 ++++++++++++++++-
 4 files changed, 2307 insertions(+), 1228 deletions(-)

-- 
2.34.1



From andyshrk at 163.com  Wed Dec 18 23:39:14 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:14 +0800
Subject: [PATCH v7 6/9] drm/rockchip: vop2: Set plane possible crtcs by possible vp mask
In-Reply-To: <20241219073931.3997788-1-andyshrk@163.com>
References: <20241219073931.3997788-1-andyshrk@163.com>
Message-ID: <20241219073931.3997788-7-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP of rk3576, a window cannot attach to all Video
Ports, we introduce a possible_vp_mask for every window to indicate
which Video Ports this window can attach to.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 18 +++++++++++++++++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  1 +
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 14 ++++++++++++++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index e588d5d01e0a..0b79f2006836 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2311,6 +2311,10 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 			if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
 				continue;
 
+			/* If this win can not attached to this VP */
+			if (!(win->data->possible_vp_mask & BIT(vp->id)))
+				continue;
+
 			if (vop2_is_mirror_win(win))
 				continue;
 
@@ -2342,7 +2346,19 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 
 		win->type = DRM_PLANE_TYPE_OVERLAY;
 
-		possible_crtcs = (1 << nvps) - 1;
+		possible_crtcs = 0;
+		nvp = 0;
+		for (j = 0; j < vop2_data->nr_vps; j++) {
+			vp = &vop2->vps[j];
+
+			if (!vp->crtc.port)
+				continue;
+
+			if (win->data->possible_vp_mask & BIT(vp->id))
+				possible_crtcs |= BIT(nvp);
+			nvp++;
+		}
+
 		ret = vop2_plane_init(vop2, win, possible_crtcs);
 		if (ret) {
 			drm_err(vop2->drm, "failed to init overlay plane %s: %d\n",
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 21464d107bd3..3c9caf13749d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -167,6 +167,7 @@ struct vop2_win_data {
 	unsigned int phys_id;
 
 	u32 base;
+	u32 possible_vp_mask;
 	enum drm_plane_type type;
 
 	u32 nformats;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 48629353929d..f0b0608fe1be 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -347,6 +347,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.name = "Smart0-win0",
 		.phys_id = ROCKCHIP_VOP2_SMART0,
 		.base = 0x1c00,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
@@ -360,6 +361,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	}, {
 		.name = "Smart1-win0",
 		.phys_id = ROCKCHIP_VOP2_SMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
@@ -373,6 +375,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	}, {
 		.name = "Esmart1-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_rk356x_esmart,
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
@@ -386,6 +389,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 	}, {
 		.name = "Esmart0-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_rk356x_esmart,
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
@@ -400,6 +404,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.name = "Cluster0-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
 		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -415,6 +420,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.name = "Cluster1-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
 		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -580,6 +586,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster0-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
 		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -598,6 +605,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster1-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
 		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -616,6 +624,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster2-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER2,
 		.base = 0x1400,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -634,6 +643,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Cluster3-win0",
 		.phys_id = ROCKCHIP_VOP2_CLUSTER3,
 		.base = 0x1600,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
@@ -651,6 +661,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	}, {
 		.name = "Esmart0-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
@@ -667,6 +678,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	}, {
 		.name = "Esmart1-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
@@ -684,6 +696,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.name = "Esmart2-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART2,
 		.base = 0x1c00,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
@@ -699,6 +712,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 	}, {
 		.name = "Esmart3-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART3,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
-- 
2.34.1



From andyshrk at 163.com  Wed Dec 18 23:39:11 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:11 +0800
Subject: [PATCH v7 3/9] drm/rockchip: vop2: Support for different layer select configuration between VPs
In-Reply-To: <20241219073931.3997788-1-andyshrk@163.com>
References: <20241219073931.3997788-1-andyshrk@163.com>
Message-ID: <20241219073931.3997788-4-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP for rk3576, every VP has it's own LAYER_SEL
register, and the configuration value of each VP for the same
window maybe different, so extend the layer_sel_id to array,
let it can descption the layer select configuration value for
different VP.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v4)

Changes in v4:
- Typo fix: selet->select

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  4 +--
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 38 ++++++++++----------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 265bb5bfa27d..af3cd92e6815 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -166,9 +166,9 @@ struct vop2_win_data {
 	const unsigned int supported_rotations;
 
 	/**
-	 * @layer_sel_id: defined by register OVERLAY_LAYER_SEL of VOP2
+	 * @layer_sel_id: defined by register OVERLAY_LAYER_SEL or PORTn_LAYER_SEL
 	 */
-	unsigned int layer_sel_id;
+	unsigned int layer_sel_id[ROCKCHIP_MAX_CRTC];
 	uint64_t feature;
 
 	uint8_t axi_bus_id;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 32d2f240261f..747e3628ae96 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -350,7 +350,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_smart,
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
-		.layer_sel_id = 3,
+		/* 0xf means this layer can't attached to this VP */
+		.layer_sel_id = { 3, 3, 3, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -363,7 +364,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_smart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1e00,
-		.layer_sel_id = 7,
+		.layer_sel_id = { 7, 7, 7, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -376,7 +377,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = 6,
+		.layer_sel_id = { 6, 6, 6, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -389,7 +390,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1800,
-		.layer_sel_id = 2,
+		.layer_sel_id = { 2, 2, 2, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
 		.max_upscale_factor = 8,
@@ -402,7 +403,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 0,
+		.layer_sel_id = { 0, 0, 0, 0xf },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.max_upscale_factor = 4,
@@ -417,7 +418,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 1,
+		.layer_sel_id = { 1, 1, 1, 0xf },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
@@ -582,7 +583,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 0,
+		.layer_sel_id = { 0, 0, 0, 0 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.axi_bus_id = 0,
@@ -600,7 +601,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 1,
+		.layer_sel_id = { 1, 1, 1, 1 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -618,7 +619,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 4,
+		.layer_sel_id = { 4, 4, 4, 4 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -636,7 +637,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_cluster,
 		.nformats = ARRAY_SIZE(formats_cluster),
 		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = 5,
+		.layer_sel_id =  { 5, 5, 5, 5 },
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
@@ -654,7 +655,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1800,
-		.layer_sel_id = 2,
+		.layer_sel_id = { 2, 2, 2, 2 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 0,
@@ -670,7 +671,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = 3,
+		.layer_sel_id = { 3, 3, 3, 3 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 0,
@@ -686,7 +687,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.formats = formats_esmart,
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
-		.layer_sel_id = 6,
+		.layer_sel_id =  { 6, 6, 6, 6 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 1,
@@ -702,7 +703,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
 		.nformats = ARRAY_SIZE(formats_esmart),
 		.format_modifiers = format_modifiers,
 		.base = 0x1e00,
-		.layer_sel_id = 7,
+		.layer_sel_id =  { 7, 7, 7, 7 },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
 		.axi_bus_id = 1,
@@ -1454,7 +1455,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		 */
 		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
 			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
-			if (layer_sel_id == win->data->layer_sel_id)
+			if (layer_sel_id == win->data->layer_sel_id[vp->id])
 				break;
 		}
 
@@ -1464,7 +1465,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		for (i = 0; i < vop2->data->win_size; i++) {
 			old_win = &vop2->win[i];
 			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
-			if (layer_sel_id == old_win->data->layer_sel_id)
+			if (layer_sel_id == old_win->data->layer_sel_id[vp->id])
 				break;
 		}
 
@@ -1512,13 +1513,14 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
 		}
 
 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id[vp->id]);
 		/*
 		 * When we bind a window from layerM to layerN, we also need to move the old
 		 * window on layerN to layerM to avoid one window selected by two or more layers.
 		 */
 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id,
+			     old_win->data->layer_sel_id[vp->id]);
 	}
 
 	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-- 
2.34.1



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:31 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:31 +0100
Subject: [PATCH 07/10] arm64: dts: imx8mp-skov: configure uart1 for RS485
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-7-38bf80dc22df@pengutronix.de>

uart1 TX, RX and RTS signals go off the base board and to a RS485
transceiver. Describe this in the device tree.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
index 7ae686d37dda..bce23d62cd27 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
@@ -404,6 +404,13 @@ &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1>;
 	status = "okay";
+	/*
+	 * While there is no CTS line, the property "uart-has-rtscts" is still
+	 * the right thing to do to enable the UART to do RS485. In RS485-Mode
+	 * CTS isn't used anyhow and there is no dedicated property
+	 * "uart-has-rts-but-no-cts".
+	 */
+	uart-has-rtscts;
 };
 
 &uart2 {
@@ -618,6 +625,8 @@ pinctrl_uart1: uart1grp {
 			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX			0x140
 			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX			0x140
 			MX8MP_IOMUXC_UART3_RXD__UART1_DTE_RTS			0x140
+			/* CTS pin is not connected, but needed as workaround */
+			MX8MP_IOMUXC_UART3_TXD__UART1_DTE_CTS			0x140
 		>;
 	};
 

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:25 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:25 +0100
Subject: [PATCH 01/10] arm64: dts: imx8mp-skov: correct PMIC board limits
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-1-38bf80dc22df@pengutronix.de>

The PMIC voltage constraints in the device tree currently describe the
permissible range of the PMIC. This is unnecessary as this information
already exists in the driver and wrong as it doesn't account for
board-specific constraints, e.g. a 2.1V on VDD_SOC would fry the SoC and
a maximum voltage of 3.4V on the VDD_3V3 rail may be unexpected across
the board.

Fix this by adjusting constraints to reflect the board limits.

Fixes: 6d382d51d979 ("arm64: dts: freescale: Add SKOV IMX8MP CPU revB board")
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 .../arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 24 +++++++++++-----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
index 59813ef8e2bb..ae82166b5c26 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
@@ -247,8 +247,8 @@ reg_vdd_soc: BUCK1 {
 
 			reg_vdd_arm: BUCK2 {
 				regulator-name = "VDD_ARM";
-				regulator-min-microvolt = <600000>;
-				regulator-max-microvolt = <2187500>;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <1000000>;
 				vin-supply = <&reg_5v_p>;
 				regulator-boot-on;
 				regulator-always-on;
@@ -259,8 +259,8 @@ reg_vdd_arm: BUCK2 {
 
 			reg_vdd_3v3: BUCK4 {
 				regulator-name = "VDD_3V3";
-				regulator-min-microvolt = <600000>;
-				regulator-max-microvolt = <3400000>;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
 				vin-supply = <&reg_5v_p>;
 				regulator-boot-on;
 				regulator-always-on;
@@ -268,8 +268,8 @@ reg_vdd_3v3: BUCK4 {
 
 			reg_vdd_1v8: BUCK5 {
 				regulator-name = "VDD_1V8";
-				regulator-min-microvolt = <600000>;
-				regulator-max-microvolt = <3400000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
 				vin-supply = <&reg_5v_p>;
 				regulator-boot-on;
 				regulator-always-on;
@@ -277,8 +277,8 @@ reg_vdd_1v8: BUCK5 {
 
 			reg_nvcc_dram_1v1: BUCK6 {
 				regulator-name = "NVCC_DRAM_1V1";
-				regulator-min-microvolt = <600000>;
-				regulator-max-microvolt = <3400000>;
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
 				vin-supply = <&reg_5v_p>;
 				regulator-boot-on;
 				regulator-always-on;
@@ -286,8 +286,8 @@ reg_nvcc_dram_1v1: BUCK6 {
 
 			reg_nvcc_snvs_1v8: LDO1 {
 				regulator-name = "NVCC_SNVS_1V8";
-				regulator-min-microvolt = <1600000>;
-				regulator-max-microvolt = <3300000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
 				vin-supply = <&reg_5v_p>;
 				regulator-boot-on;
 				regulator-always-on;
@@ -295,8 +295,8 @@ reg_nvcc_snvs_1v8: LDO1 {
 
 			reg_vdda_1v8: LDO3 {
 				regulator-name = "VDDA_1V8";
-				regulator-min-microvolt = <800000>;
-				regulator-max-microvolt = <3300000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
 				vin-supply = <&reg_5v_p>;
 				regulator-boot-on;
 				regulator-always-on;

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:26 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:26 +0100
Subject: [PATCH 02/10] arm64: dts: imx8mp-skov: operate CPU at 850 mV by
 default
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-2-38bf80dc22df@pengutronix.de>

The Skov i.MX8MP boards are passively cooled and heatsink is specced for
continuous operation at 1.2 GHz only. Short bouts of 1.6 GHz are ok,
but these should be invoked intentionally, not as part of
suspend/resume cycles.

Therefore, configure RUN frequency as 850 mV and remove the higher
voltage operating points from those permissible for suspend.

Fixes: 6d382d51d979 ("arm64: dts: freescale: Add SKOV IMX8MP CPU revB board")
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
index ae82166b5c26..7ae686d37dda 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
@@ -163,6 +163,19 @@ reg_vsd_3v3: regulator-vsd-3v3 {
 	};
 };
 
+/*
+ * Board is passively cooled and heatsink is specced for continuous operation
+ * at 1.2 GHz only. Short bouts of 1.6 GHz are ok, but these should be done
+ * intentionally, not as part of suspend/resume cycles.
+ */
+&{/opp-table/opp-1600000000} {
+	/delete-property/ opp-suspend;
+};
+
+&{/opp-table/opp-1800000000} {
+	/delete-property/ opp-suspend;
+};
+
 &A53_0 {
 	cpu-supply = <&reg_vdd_arm>;
 };
@@ -253,7 +266,7 @@ reg_vdd_arm: BUCK2 {
 				regulator-boot-on;
 				regulator-always-on;
 				regulator-ramp-delay = <3125>;
-				nxp,dvs-run-voltage = <950000>;
+				nxp,dvs-run-voltage = <850000>;
 				nxp,dvs-standby-voltage = <850000>;
 			};
 

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:27 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:27 +0100
Subject: [PATCH 03/10] arm64: dts: imx8mp-skov: use I2C5 for DDC
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-3-38bf80dc22df@pengutronix.de>

The HDMI DDC pads can be muxed either to an i.MX I2C controller or
to a limited I2C controller within the Designware HDMI bridge.

So far we muxed the pads to the HDMI bridge, but the i.MX I2C controller
is the better choice:

  - We use DDC/CI commands for display brightness configuration, but the
    Linux driver refuses[1] transfers to/from address 0x37, because the
    controller doesn't support multi-byte requests.

  - The driver doesn't support I2C bus recovery, but we need that,
    because some HDMI panels used with the board can be flaky.

As the i.MX I2C controller doesn't have either of these limitations,
let's make use of it instead.

[1]: https://lore.kernel.org/all/20190722181945.244395-1-mka at chromium.org/

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 .../boot/dts/freescale/imx8mp-skov-revb-hdmi.dts   | 26 ++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
index c1ca69da3cb8..206116be8166 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
@@ -9,12 +9,34 @@ / {
 	compatible = "skov,imx8mp-skov-revb-hdmi", "fsl,imx8mp";
 };
 
+&i2c5 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c5>;
+	pinctrl-1 = <&pinctrl_i2c5_gpio>;
+	scl-gpios = <&gpio3 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio3 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl_hdmi: hdmigrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL		0x1c3
-			MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA		0x1c3
 			MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD			0x19
 		>;
 	};
+
+	pinctrl_i2c5: i2c5grp {
+		fsl,pins = <
+			MX8MP_IOMUXC_HDMI_DDC_SCL__I2C5_SCL			0x400001c2
+			MX8MP_IOMUXC_HDMI_DDC_SDA__I2C5_SDA			0x400001c2
+		>;
+	};
+
+	pinctrl_i2c5_gpio: i2c5gpiogrp {
+		fsl,pins = <
+			MX8MP_IOMUXC_HDMI_DDC_SCL__GPIO3_IO26			0x400001c2
+			MX8MP_IOMUXC_HDMI_DDC_SDA__GPIO3_IO27			0x400001c2
+		>;
+	};
 };

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:29 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:29 +0100
Subject: [PATCH 05/10] dt-bindings: display/lvds-codec: add ti,sn65lvds822
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-5-38bf80dc22df@pengutronix.de>

Add compatible strings for TI SN65LVDS822, a FlatLink LVDS receiver.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
To: Andrzej Hajda <andrzej.hajda at intel.com> (maintainer:DRM DRIVERS FOR BRIDGE CHIPS)
To: Neil Armstrong <neil.armstrong at linaro.org> (maintainer:DRM DRIVERS FOR BRIDGE CHIPS)
To: Robert Foss <rfoss at kernel.org> (maintainer:DRM DRIVERS FOR BRIDGE CHIPS)
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com> (reviewer:DRM DRIVERS FOR BRIDGE CHIPS,in file)
Cc: Jonas Karlman <jonas at kwiboo.se> (reviewer:DRM DRIVERS FOR BRIDGE CHIPS)
Cc: Jernej Skrabec <jernej.skrabec at gmail.com> (reviewer:DRM DRIVERS FOR BRIDGE CHIPS)
Cc: David Airlie <airlied at gmail.com> (maintainer:DRM DRIVERS)
Cc: Simona Vetter <simona at ffwll.ch> (maintainer:DRM DRIVERS)
Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com> (maintainer:DRM DRIVERS AND MISC GPU PATCHES)
Cc: Maxime Ripard <mripard at kernel.org> (maintainer:DRM DRIVERS AND MISC GPU PATCHES)
Cc: Thomas Zimmermann <tzimmermann at suse.de> (maintainer:DRM DRIVERS AND MISC GPU PATCHES)
Cc: dri-devel at lists.freedesktop.org (open list:DRM DRIVERS)
---
 Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
index 6ceeed76e88e..0487bbffd7f7 100644
--- a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
@@ -41,6 +41,7 @@ properties:
           - enum:
               - ti,ds90cf364a # For the DS90CF364A FPD-Link LVDS Receiver
               - ti,ds90cf384a # For the DS90CF384A FPD-Link LVDS Receiver
+              - ti,sn65lvds822  # For the SN65LVDS822 FlatLink LVDS Receiver
               - ti,sn65lvds94 # For the SN65DS94 LVDS serdes
           - const: lvds-decoder # Generic LVDS decoders compatible fallback
       - enum:

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:32 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:32 +0100
Subject: [PATCH 08/10] arm64: dts: imx8mp-skov: describe mains fail
 detection
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-8-38bf80dc22df@pengutronix.de>

From: Oleksij Rempel <o.rempel at pengutronix.de>

The main 24V regulator will toggle GPIO4_IO23 to signal imminent voltage
loss. Reflect this in the DT, so the OS can take appropriate action when
this happens.

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
index bce23d62cd27..80d212acc0c3 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
@@ -116,6 +116,11 @@ reg_24v: regulator-24v {
 		regulator-name = "24V";
 		regulator-min-microvolt = <24000000>;
 		regulator-max-microvolt = <24000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg24v>;
+		interrupts-extended = <&gpio4 23 IRQ_TYPE_EDGE_FALLING>;
+		system-critical-regulator;
+		regulator-uv-less-critical-window-ms = <50>;
 	};
 
 	reg_can2rs: regulator-can2rs {
@@ -591,6 +596,12 @@ MX8MP_IOMUXC_SAI3_MCLK__PWM4_OUT			0x116
 		>;
 	};
 
+	pinctrl_reg24v: reg24vgrp {
+		fsl,pins = <
+			MX8MP_IOMUXC_SAI2_RXD0__GPIO4_IO23			0x154
+		>;
+	};
+
 	pinctrl_reg_vsd_3v3: regvsd3v3grp {
 		fsl,pins = <
 			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:24 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:24 +0100
Subject: [PATCH 00/10] arm64: dts: imx8mp-skov: flesh out device trees
Message-ID: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>

When the Skov device trees were added a year ago, there were no
upstream bindings yet for many parts of the display pipeline.

This has changed now, so this series fleshes the display pipeline parts
out and adds some more fixes/enhancements that have accrued in the
meantime.

---
Ahmad Fatoum (5):
      arm64: dts: imx8mp-skov: correct PMIC board limits
      arm64: dts: imx8mp-skov: operate CPU at 850 mV by default
      arm64: dts: imx8mp-skov: use I2C5 for DDC
      dt-bindings: display/lvds-codec: add ti,sn65lvds822
      arm64: dts: imx8mp-skov: configure uart1 for RS485

Oleksij Rempel (5):
      arm64: dts: imx8mp-skov: describe HDMI display pipeline
      arm64: dts: imx8mp-skov: describe LVDS display pipeline
      arm64: dts: imx8mp-skov: describe mains fail detection
      arm64: dts: imx8mp-skov: fix phy-mode
      arm64: dts: imx8mp-skov: increase I2C clock frequency for RTC

 .../bindings/display/bridge/lvds-codec.yaml        |  1 +
 .../arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 63 ++++++++++++++++------
 .../boot/dts/freescale/imx8mp-skov-revb-hdmi.dts   | 45 +++++++++++++++-
 .../boot/dts/freescale/imx8mp-skov-revb-lt6.dts    | 60 +++++++++++++++++++++
 4 files changed, 152 insertions(+), 17 deletions(-)
---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241218-skov-dt-updates-eb8b73c693d1

Best regards,
-- 
Ahmad Fatoum <a.fatoum at pengutronix.de>



From a.fatoum at pengutronix.de  Wed Dec 18 23:27:33 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:27:33 +0100
Subject: [PATCH 2/6] arm64: dts: imx8mp: Add optional nominal drive mode
 DTSI
In-Reply-To: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
Message-ID: <20241219-imx8m-clk-v1-2-cfaffa087da6@pengutronix.de>

Unlike the i.MX8MM and i.MX8MN SoCs added earlier, the device tree for
the i.MX8MP configures some clocks at frequencies that are only validated
for overdrive mode, i.e. when VDD_SOC is 950 mV.

Boards may want to run their SoC at the lower voltage of 850 mV though
to reduce heat generation and power usage. For this to work, clock rates
need to adhere to the limits of the nominal drive mode.

Add an optional DTSI file which can be included by various boards to run
in this mode.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi | 63 +++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi
new file mode 100644
index 000000000000..f9a82a663033
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2024 Pengutronix, Ahmad Fatoum <kernel at pengutronix.de>
+ */
+
+&clk {
+	assigned-clocks = <&clk IMX8MP_CLK_A53_SRC>,
+			  <&clk IMX8MP_CLK_A53_CORE>,
+			  <&clk IMX8MP_SYS_PLL3>,
+			  <&clk IMX8MP_CLK_NOC>,
+			  <&clk IMX8MP_CLK_NOC_IO>,
+			  <&clk IMX8MP_CLK_GIC>;
+	assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
+				 <&clk IMX8MP_ARM_PLL_OUT>,
+				 <0>,
+				 <&clk IMX8MP_SYS_PLL1_800M>,
+				 <&clk IMX8MP_SYS_PLL3_OUT>,
+				 <&clk IMX8MP_SYS_PLL1_800M>;
+	assigned-clock-rates = <0>, <0>,
+			       <600000000>,
+			       <800000000>,
+			       <600000000>,
+			       <400000000>;
+};
+
+&pgc_hdmimix {
+	assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>,
+			  <&clk IMX8MP_CLK_HDMI_APB>;
+	assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
+				 <&clk IMX8MP_SYS_PLL1_133M>;
+	assigned-clock-rates = <400000000>, <133000000>;
+};
+
+&pgc_hsiomix {
+	assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
+	assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>;
+	assigned-clock-rates = <400000000>;
+};
+
+&pgc_gpumix {
+	assigned-clocks = <&clk IMX8MP_CLK_GPU_AXI>,
+			  <&clk IMX8MP_CLK_GPU_AHB>;
+	assigned-clock-parents = <&clk IMX8MP_SYS_PLL3_OUT>,
+				 <&clk IMX8MP_SYS_PLL3_OUT>;
+	assigned-clock-rates = <600000000>, <300000000>;
+};
+
+&media_blk_ctrl {
+	assigned-clocks = <&clk IMX8MP_CLK_MEDIA_AXI>,
+			  <&clk IMX8MP_CLK_MEDIA_APB>,
+			  <&clk IMX8MP_CLK_MEDIA_DISP1_PIX>,
+			  <&clk IMX8MP_CLK_MEDIA_DISP2_PIX>,
+			  <&clk IMX8MP_CLK_MEDIA_ISP>,
+			  <&clk IMX8MP_VIDEO_PLL1>;
+	assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
+				 <&clk IMX8MP_SYS_PLL1_800M>,
+				 <&clk IMX8MP_VIDEO_PLL1_OUT>,
+				 <&clk IMX8MP_VIDEO_PLL1_OUT>,
+				 <&clk IMX8MP_SYS_PLL1_800M>;
+	assigned-clock-rates = <400000000>, <200000000>,
+			       <0>, <0>, <400000000>,
+			       <1039500000>;
+};

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:27:35 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:27:35 +0100
Subject: [PATCH 4/6] arm64: dts: freescale: imx8mp-skov: fix LDB clock rate
 configuration
In-Reply-To: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
Message-ID: <20241219-imx8m-clk-v1-4-cfaffa087da6@pengutronix.de>

When the imx8mp-skov-revb-mi1010ait-1cp1 device tree was first added, it
configured the minimum clock rate supported by the panel instead of
the typical clock rate:

  fsl-ldb 32ec0000.blk-ctrl:bridge at 5c: Configured LDB clock
  (482300000 Hz) does not match requested LVDS clock: 490000000 Hz

Besides the warning, the display functioned normally though
This broke with commit ff06ea04e4cf ("clk: imx: clk-imx8mp: Allow
media_disp pixel clock reconfigure parent rate") as the reconfiguration
of the parent clocks removed setting the IMX8MP_VIDEO_PLL1 to 7 times
the display clock rate:

  fsl-ldb 32ec0000.blk-ctrl:bridge at 5c: Configured LDB clock
  (70000000 Hz) does not match requested LVDS clock: 490000000 Hz

Fix this by configuring the typical rate instead and benefit from
the new commit by dropping the now unneeded assigned-clock-rates
in &media_blk_ctrl.

Fixes: ff06ea04e4cf ("clk: imx: clk-imx8mp: Allow media_disp pixel clock reconfigure parent rate")
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 .../dts/freescale/imx8mp-skov-revb-mi1010ait-1cp1.dts | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-mi1010ait-1cp1.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-mi1010ait-1cp1.dts
index 30962922b361..a13f6d76a495 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-mi1010ait-1cp1.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-mi1010ait-1cp1.dts
@@ -51,8 +51,11 @@ &lcdif2 {
 };
 
 &lvds_bridge {
-	/* IMX8MP_CLK_MEDIA_LDB = IMX8MP_CLK_MEDIA_DISP2_PIX * 7 */
-	assigned-clock-rates = <482300000>;
+	assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>,
+				 <&clk IMX8MP_VIDEO_PLL1>;
+	assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
+	/* IMX8MP_VIDEO_PLL1 = IMX8MP_CLK_MEDIA_DISP2_PIX * 2 * 7 */
+	assigned-clock-rates = <0>, <980000000>;
 	status = "okay";
 
 	ports {
@@ -64,18 +67,6 @@ ldb_lvds_ch0: endpoint {
 	};
 };
 
-&media_blk_ctrl {
-	/* currently it is not possible to let display clocks confugure
-	 * automatically, so we need to set them manually
-	 */
-	assigned-clock-rates = <500000000>, <200000000>, <0>,
-		/* IMX8MP_CLK_MEDIA_DISP2_PIX = pixelclk of lvds panel */
-		<68900000>,
-		<500000000>,
-		/* IMX8MP_VIDEO_PLL1 = IMX8MP_CLK_MEDIA_LDB * 2 */
-		<964600000>;
-};
-
 &pwm4 {
 	status = "okay";
 };

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:27:34 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:27:34 +0100
Subject: [PATCH 3/6] arm64: dts: imx8mp: add fsl,nominal-mode property into
 nominal.dtsi
In-Reply-To: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
Message-ID: <20241219-imx8m-clk-v1-3-cfaffa087da6@pengutronix.de>

The imx8mp-nominal.dtsi is meant to be included into boards that want to
override the default overdrive clock settings with settings suitable for
running in nominal drive mode at its lower required voltage.

Specifying fsl,nominal-mode informs drivers of this fact, so they can
sanity check runtime clock reconfiguration to observe the limits imposed
by nominal mode.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi
index f9a82a663033..532eb049c7e8 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi
@@ -21,6 +21,7 @@ &clk {
 			       <800000000>,
 			       <600000000>,
 			       <400000000>;
+	fsl,nominal-mode;
 };
 
 &pgc_hdmimix {

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:27:37 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:27:37 +0100
Subject: [PATCH 6/6] clk: imx8mp: inform CCF of maximum frequency of clocks
In-Reply-To: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
Message-ID: <20241219-imx8m-clk-v1-6-cfaffa087da6@pengutronix.de>

The IMX8MPCEC datasheet lists maximum frequencies allowed for different
modules. Some of these limits are universal, but some depend on
whether the SoC is operating in nominal or in overdrive mode.

The imx8mp.dtsi currently assumes overdrive mode and configures some
clocks in accordance with this. Boards wishing to make use of nominal
mode will need to override some of the clock rates manually.

As operating the clocks outside of their allowed range can lead to
difficult to debug issues, it makes sense to register the maximum rates
allowed in the driver, so the CCF can take them into account.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 drivers/clk/imx/clk-imx8mp.c | 147 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 147 insertions(+)

diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 516dbd170c8a..3b06990b73ad 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -8,6 +8,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/units.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -405,6 +406,145 @@ static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_
 static struct clk_hw **hws;
 static struct clk_hw_onecell_data *clk_hw_data;
 
+struct imx8mp_clock_constraints {
+	int clkid;
+	u32 maxrate;
+};
+
+/*
+ * Below tables are taken from IMX8MPCEC Rev. 2.1, 07/2023
+ * Table 13. Maximum frequency of modules.
+ * Probable typos fixed are marked with a comment.
+ */
+static const struct imx8mp_clock_constraints imx8mp_clock_common_constraints[] = {
+	{ IMX8MP_CLK_A53_DIV,             1000 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ENET_AXI,             266666667 }, /* Datasheet claims 266MHz */
+	{ IMX8MP_CLK_NAND_USDHC_BUS,       266666667 }, /* Datasheet claims 266MHz */
+	{ IMX8MP_CLK_MEDIA_APB,            200 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_HDMI_APB,             133333333 }, /* Datasheet claims 133MHz */
+	{ IMX8MP_CLK_ML_AXI,               800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_AHB,                  133333333 },
+	{ IMX8MP_CLK_IPG_ROOT,              66666667 },
+	{ IMX8MP_CLK_AUDIO_AHB,            400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_DISP2_PIX,      170 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_DRAM_ALT,             666666667 },
+	{ IMX8MP_CLK_DRAM_APB,             200 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_CAN1,                  80 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_CAN2,                  80 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_PCIE_AUX,              10 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_I2C5,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_I2C6,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_SAI1,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_SAI2,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_SAI3,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_SAI5,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_SAI6,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_ENET_QOS,             125 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ENET_QOS_TIMER,       200 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ENET_REF,             125 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ENET_TIMER,           125 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ENET_PHY_REF,         125 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_NAND,                 500 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_QSPI,                 400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_USDHC1,               400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_USDHC2,               400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_I2C1,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_I2C2,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_I2C3,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_I2C4,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_UART1,                 80 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_UART2,                 80 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_UART3,                 80 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_UART4,                 80 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ECSPI1,                80 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ECSPI2,                80 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_PWM1,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_PWM2,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_PWM3,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_PWM4,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_GPT1,                 100 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPT2,                 100 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPT3,                 100 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPT4,                 100 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPT5,                 100 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPT6,                 100 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_WDOG,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_IPP_DO_CLKO1,         200 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_IPP_DO_CLKO2,         200 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_HDMI_REF_266M,        266 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_USDHC3,               400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_MIPI_PHY1_REF,  300 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_DISP1_PIX,      250 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_CAM2_PIX,       277 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_LDB,            595 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE, 200 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ECSPI3,                80 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_PDM,                  200 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_SAI7,                  66666667 }, /* Datasheet claims 66MHz */
+	{ IMX8MP_CLK_MAIN_AXI,             400 * HZ_PER_MHZ },
+	{ /* sentinel */ },
+};
+
+static const struct imx8mp_clock_constraints imx8mp_clock_nominal_constraints[] = {
+	{ IMX8MP_CLK_M7_CORE,           600 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ML_CORE,           800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU3D_CORE,        800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU3D_SHADER_CORE, 800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU2D_CORE,        800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_AUDIO_AXI_SRC,     600 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_HSIO_AXI,          400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_ISP,         400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_VPU_BUS,           600 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_AXI,         400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_HDMI_AXI,          400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU_AXI,           600 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU_AHB,           300 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_NOC,               800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_NOC_IO,            600 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ML_AHB,            300 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_VPU_G1,            600 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_VPU_G2,            500 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_CAM1_PIX,    400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_VPU_VC8000E,       400 * HZ_PER_MHZ }, /* Datasheet claims 500MHz */
+	{ IMX8MP_CLK_DRAM_CORE,         800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GIC,               400 * HZ_PER_MHZ },
+	{ /* sentinel */ },
+};
+
+static const struct imx8mp_clock_constraints imx8mp_clock_overdrive_constraints[] = {
+	{ IMX8MP_CLK_M7_CORE,            800 * HZ_PER_MHZ},
+	{ IMX8MP_CLK_ML_CORE,           1000 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU3D_CORE,        1000 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU3D_SHADER_CORE, 1000 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU2D_CORE,        1000 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_AUDIO_AXI_SRC,      800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_HSIO_AXI,           500 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_ISP,          500 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_VPU_BUS,            800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_AXI,          500 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_HDMI_AXI,           500 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU_AXI,            800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GPU_AHB,            400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_NOC,               1000 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_NOC_IO,             800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_ML_AHB,             400 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_VPU_G1,             800 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_VPU_G2,             700 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_MEDIA_CAM1_PIX,     500 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_VPU_VC8000E,        500 * HZ_PER_MHZ }, /* Datasheet claims 400MHz */
+	{ IMX8MP_CLK_DRAM_CORE,         1000 * HZ_PER_MHZ },
+	{ IMX8MP_CLK_GIC,                500 * HZ_PER_MHZ },
+	{ /* sentinel */ },
+};
+
+static void imx8mp_clocks_apply_constraints(const struct imx8mp_clock_constraints constraints[])
+{
+	const struct imx8mp_clock_constraints *constr;
+
+	for (constr = constraints; constr->clkid; constr++)
+		clk_hw_set_rate_range(hws[constr->clkid], 0, constr->maxrate);
+}
+
 static int imx8mp_clocks_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -714,6 +854,13 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	imx_check_clk_hws(hws, IMX8MP_CLK_END);
 
+	imx8mp_clocks_apply_constraints(imx8mp_clock_common_constraints);
+
+	if (of_property_read_bool(np, "fsl,nominal-mode"))
+		imx8mp_clocks_apply_constraints(imx8mp_clock_nominal_constraints);
+	else if (of_property_read_bool(np, "fsl,overdrive-mode"))
+		imx8mp_clocks_apply_constraints(imx8mp_clock_overdrive_constraints);
+
 	err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
 	if (err < 0) {
 		dev_err(dev, "failed to register hws for i.MX8MP\n");

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:27:32 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:27:32 +0100
Subject: [PATCH 1/6] dt-bindings: clock: imx8m: document nominal/overdrive
 properties
In-Reply-To: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
Message-ID: <20241219-imx8m-clk-v1-1-cfaffa087da6@pengutronix.de>

The imx8m-clock.yaml binding covers the clock controller inside all
of the i.MX8M Q/M/N/P SoCs. All of them have in common that they
support two operating modes: nominal and overdrive mode.

While the overdrive mode allows for higher frequencies for many IPs,
the nominal mode needs a lower SoC voltage, thereby reducing
heat generation and power usage.

In any case, software should respect the maximum clock rate limits
described in the datasheet for each of the two operating modes.

To allow device tree consumers to enforce these limits, document two new
optional properties that can be used to sanity check the clock tree.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 Documentation/devicetree/bindings/clock/imx8m-clock.yaml | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
index c643d4a81478..a6ae5257ef53 100644
--- a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
@@ -43,6 +43,14 @@ properties:
       ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8m-clock.h
       for the full list of i.MX8M clock IDs.
 
+  fsl,nominal-mode:
+    description: Set if SoC is operated in nominal mode
+    $ref: /schemas/types.yaml#/definitions/flag
+
+  fsl,overdrive-mode:
+    description: Set if SoC is operated in overdrive mode
+    $ref: /schemas/types.yaml#/definitions/flag
+
 required:
   - compatible
   - reg
@@ -95,6 +103,12 @@ allOf:
             - const: clk_ext2
             - const: clk_ext3
             - const: clk_ext4
+  - if:
+      required:
+        - fsl,overdrive-mode
+    then:
+      properties:
+        fsl,nominal-mode: false
 
 additionalProperties: false
 

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:27:36 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:27:36 +0100
Subject: [PATCH 5/6] arm64: dts: freescale: imx8mp-skov: operate SoC in
 nominal mode
In-Reply-To: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
Message-ID: <20241219-imx8m-clk-v1-5-cfaffa087da6@pengutronix.de>

To reduce heat generation, the Skov i.MX8MP boards should run in nominal
drive mode with a VDD_SOC voltage of 850 mV.

At this operating point, not all frequencies that are achievable with
overdrive mode are possible, so import imx8mp-nominal.dtsi to clock down
the clocks.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
index 59813ef8e2bb..9dc36517e90c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
 
 #include "imx8mp.dtsi"
+#include "imx8mp-nominal.dtsi"
 
 #include <dt-bindings/leds/common.h>
 
@@ -237,8 +238,8 @@ pmic at 25 {
 		regulators {
 			reg_vdd_soc: BUCK1 {
 				regulator-name = "VDD_SOC";
-				regulator-min-microvolt = <600000>;
-				regulator-max-microvolt = <2187500>;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
 				vin-supply = <&reg_5v_p>;
 				regulator-boot-on;
 				regulator-always-on;

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:27:31 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:27:31 +0100
Subject: [PATCH 0/6] arm64: dts: freescale: imx8mp-skov: switch to nominal
 drive mode
Message-ID: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>

Unlike the i.MX8MM and i.MX8MN SoCs added earlier, the imx8mp.dtsi
configures some clocks at frequencies that are only validated for
overdrive mode, i.e., when VDD_SOC is 950 mV.

For the Skov i.MX8MP board, we want to run the SoC at the lower voltage of
850 mV though to reduce heat generation and power usage. For this to work,
clock rates need to adhere to the limits of the nominal drive mode.

This is done by this series: A new imx8mp-nominal.dtsi reconfigures
the imx8mp.dtsi clock tree to be compatible with nominal mode, an adaptation
to the Linux clock driver makes it sanity check the actual clock rates against
the SoC operating mode's constraints and finally the Skov DT makes use
of it.

Actual configuration of the VDD_SOC rail continues to happen prior to Linux
as well as PLL configuration that needs to happen earlier than the kernel
running. See the corresponding barebox patch series[1] for details.
Note that the barebox series didn't yet include VDD_SOC reconfiguration
to 850mV, that would follow once the kernel changes have been merged.

[1]: https://lore.kernel.org/barebox/20240503103717.1370636-1-a.fatoum at pengutronix.de/

---
Ahmad Fatoum (6):
      dt-bindings: clock: imx8m: document nominal/overdrive properties
      arm64: dts: imx8mp: Add optional nominal drive mode DTSI
      arm64: dts: imx8mp: add fsl,nominal-mode property into nominal.dtsi
      arm64: dts: freescale: imx8mp-skov: fix LDB clock rate configuration
      arm64: dts: freescale: imx8mp-skov: operate SoC in nominal mode
      clk: imx8mp: inform CCF of maximum frequency of clocks

 .../devicetree/bindings/clock/imx8m-clock.yaml     |  14 ++
 arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi  |  64 +++++++++
 .../arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi |   5 +-
 .../freescale/imx8mp-skov-revb-mi1010ait-1cp1.dts  |  19 +--
 drivers/clk/imx/clk-imx8mp.c                       | 147 +++++++++++++++++++++
 5 files changed, 233 insertions(+), 16 deletions(-)
---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241217-imx8m-clk-9467763dfcd8

Best regards,
-- 
Ahmad Fatoum <a.fatoum at pengutronix.de>



From andyshrk at 163.com  Wed Dec 18 23:39:13 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:13 +0800
Subject: [PATCH v7 5/9] drm/rockchip: vop2: Register the primary plane and overlay plane separately
In-Reply-To: <20241219073931.3997788-1-andyshrk@163.com>
References: <20241219073931.3997788-1-andyshrk@163.com>
Message-ID: <20241219073931.3997788-6-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

In the upcoming VOP of rk3576, a Window cannot attach to all Video Ports,
so make sure all VP find it's suitable primary plane, then register the
remain windows as overlay plane will make code easier.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v3)

Changes in v3:
- Add comments for why we should treat rk3566 with special care.

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 100 +++++++++++--------
 1 file changed, 61 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index c87c98a8fb3a..e588d5d01e0a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2223,22 +2223,29 @@ static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win,
 	return 0;
 }
 
-static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2)
+/*
+ * On RK3566 these windows don't have an independent
+ * framebuffer. They can only share/mirror the framebuffer
+ * with smart0, esmart0 and cluster0 respectively.
+ * And RK3566 share the same vop version with Rk3568, so we
+ * need to use soc_id for identification here.
+ */
+static bool vop2_is_mirror_win(struct vop2_win *win)
 {
-	int i;
-
-	for (i = 0; i < vop2->data->nr_vps; i++) {
-		struct vop2_video_port *vp = &vop2->vps[i];
-
-		if (!vp->crtc.port)
-			continue;
-		if (vp->primary_plane)
-			continue;
+	struct vop2 *vop2 = win->vop2;
 
-		return vp;
+	if (vop2->data->soc_id == 3566) {
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART1:
+		case ROCKCHIP_VOP2_CLUSTER1:
+			return true;
+		default:
+			return false;
+		}
+	} else {
+		return false;
 	}
-
-	return NULL;
 }
 
 static int vop2_create_crtcs(struct vop2 *vop2)
@@ -2249,7 +2256,9 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 	struct drm_plane *plane;
 	struct device_node *port;
 	struct vop2_video_port *vp;
-	int i, nvp, nvps = 0;
+	struct vop2_win *win;
+	u32 possible_crtcs;
+	int i, j, nvp, nvps = 0;
 	int ret;
 
 	for (i = 0; i < vop2_data->nr_vps; i++) {
@@ -2288,42 +2297,55 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 	}
 
 	nvp = 0;
-	for (i = 0; i < vop2->registered_num_wins; i++) {
-		struct vop2_win *win = &vop2->win[i];
-		u32 possible_crtcs = 0;
-
-		if (vop2->data->soc_id == 3566) {
-			/*
-			 * On RK3566 these windows don't have an independent
-			 * framebuffer. They share the framebuffer with smart0,
-			 * esmart0 and cluster0 respectively.
-			 */
-			switch (win->data->phys_id) {
-			case ROCKCHIP_VOP2_SMART1:
-			case ROCKCHIP_VOP2_ESMART1:
-			case ROCKCHIP_VOP2_CLUSTER1:
+	/* Register a primary plane for every crtc */
+	for (i = 0; i < vop2_data->nr_vps; i++) {
+		vp = &vop2->vps[i];
+
+		if (!vp->crtc.port)
+			continue;
+
+		for (j = 0; j < vop2->registered_num_wins; j++) {
+			win = &vop2->win[j];
+
+			/* Aready registered as primary plane */
+			if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
+				continue;
+
+			if (vop2_is_mirror_win(win))
 				continue;
-			}
-		}
 
-		if (win->type == DRM_PLANE_TYPE_PRIMARY) {
-			vp = find_vp_without_primary(vop2);
-			if (vp) {
+			if (win->type == DRM_PLANE_TYPE_PRIMARY) {
 				possible_crtcs = BIT(nvp);
 				vp->primary_plane = win;
+				ret = vop2_plane_init(vop2, win, possible_crtcs);
+				if (ret) {
+					drm_err(vop2->drm, "failed to init primary plane %s: %d\n",
+						win->data->name, ret);
+					return ret;
+				}
 				nvp++;
-			} else {
-				/* change the unused primary window to overlay window */
-				win->type = DRM_PLANE_TYPE_OVERLAY;
+				break;
 			}
 		}
+	}
+
+	/* Register all unused window as overlay plane */
+	for (i = 0; i < vop2->registered_num_wins; i++) {
+		win = &vop2->win[i];
+
+		/* Aready registered as primary plane */
+		if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
+			continue;
+
+		if (vop2_is_mirror_win(win))
+			continue;
 
-		if (win->type == DRM_PLANE_TYPE_OVERLAY)
-			possible_crtcs = (1 << nvps) - 1;
+		win->type = DRM_PLANE_TYPE_OVERLAY;
 
+		possible_crtcs = (1 << nvps) - 1;
 		ret = vop2_plane_init(vop2, win, possible_crtcs);
 		if (ret) {
-			drm_err(vop2->drm, "failed to init plane %s: %d\n",
+			drm_err(vop2->drm, "failed to init overlay plane %s: %d\n",
 				win->data->name, ret);
 			return ret;
 		}
-- 
2.34.1



From andyshrk at 163.com  Wed Dec 18 23:39:10 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:10 +0800
Subject: [PATCH v7 2/9] drm/rockchip: vop2: Add platform specific callback
In-Reply-To: <20241219073931.3997788-1-andyshrk@163.com>
References: <20241219073931.3997788-1-andyshrk@163.com>
Message-ID: <20241219073931.3997788-3-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The VOP interface mux, overlay, background delay cycle configuration
of different SOC are much different. Add platform specific callback
ops to let the core driver look cleaner and more refined.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

Changes in v7:
- Fix rk3588 dp+dsi maxclk verification

Changes in v2:
- Add platform specific callback

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1145 +-----------------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  168 +++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c |  992 +++++++++++++++
 3 files changed, 1180 insertions(+), 1125 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index efe7d0cbe155..fded1e931c9a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -33,7 +33,6 @@
 #include <drm/drm_vblank.h>
 
 #include <uapi/linux/videodev2.h>
-#include <dt-bindings/soc/rockchip,vop2.h>
 
 #include "rockchip_drm_gem.h"
 #include "rockchip_drm_vop2.h"
@@ -102,143 +101,6 @@ enum vop2_afbc_format {
 	VOP2_AFBC_FMT_INVALID = -1,
 };
 
-union vop2_alpha_ctrl {
-	u32 val;
-	struct {
-		/* [0:1] */
-		u32 color_mode:1;
-		u32 alpha_mode:1;
-		/* [2:3] */
-		u32 blend_mode:2;
-		u32 alpha_cal_mode:1;
-		/* [5:7] */
-		u32 factor_mode:3;
-		/* [8:9] */
-		u32 alpha_en:1;
-		u32 src_dst_swap:1;
-		u32 reserved:6;
-		/* [16:23] */
-		u32 glb_alpha:8;
-	} bits;
-};
-
-struct vop2_alpha {
-	union vop2_alpha_ctrl src_color_ctrl;
-	union vop2_alpha_ctrl dst_color_ctrl;
-	union vop2_alpha_ctrl src_alpha_ctrl;
-	union vop2_alpha_ctrl dst_alpha_ctrl;
-};
-
-struct vop2_alpha_config {
-	bool src_premulti_en;
-	bool dst_premulti_en;
-	bool src_pixel_alpha_en;
-	bool dst_pixel_alpha_en;
-	u16 src_glb_alpha_value;
-	u16 dst_glb_alpha_value;
-};
-
-struct vop2_win {
-	struct vop2 *vop2;
-	struct drm_plane base;
-	const struct vop2_win_data *data;
-	struct regmap_field *reg[VOP2_WIN_MAX_REG];
-
-	/**
-	 * @win_id: graphic window id, a cluster may be split into two
-	 * graphics windows.
-	 */
-	u8 win_id;
-	u8 delay;
-	u32 offset;
-
-	enum drm_plane_type type;
-};
-
-struct vop2_video_port {
-	struct drm_crtc crtc;
-	struct vop2 *vop2;
-	struct clk *dclk;
-	unsigned int id;
-	const struct vop2_video_port_data *data;
-
-	struct completion dsp_hold_completion;
-
-	/**
-	 * @win_mask: Bitmask of windows attached to the video port;
-	 */
-	u32 win_mask;
-
-	struct vop2_win *primary_plane;
-	struct drm_pending_vblank_event *event;
-
-	unsigned int nlayers;
-};
-
-struct vop2 {
-	struct device *dev;
-	struct drm_device *drm;
-	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
-
-	const struct vop2_data *data;
-	/*
-	 * Number of windows that are registered as plane, may be less than the
-	 * total number of hardware windows.
-	 */
-	u32 registered_num_wins;
-
-	struct resource *res;
-	void __iomem *regs;
-	struct regmap *map;
-
-	struct regmap *sys_grf;
-	struct regmap *vop_grf;
-	struct regmap *vo1_grf;
-	struct regmap *sys_pmu;
-
-	/* physical map length of vop2 register */
-	u32 len;
-
-	void __iomem *lut_regs;
-
-	/* protects crtc enable/disable */
-	struct mutex vop2_lock;
-
-	int irq;
-
-	/*
-	 * Some global resources are shared between all video ports(crtcs), so
-	 * we need a ref counter here.
-	 */
-	unsigned int enable_count;
-	struct clk *hclk;
-	struct clk *aclk;
-	struct clk *pclk;
-
-	/* optional internal rgb encoder */
-	struct rockchip_rgb *rgb;
-
-	/* must be put at the end of the struct */
-	struct vop2_win win[];
-};
-
-#define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
-					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
-
-#define vop2_output_if_is_dp(x)		((x) == ROCKCHIP_VOP2_EP_DP0 || \
-					 (x) == ROCKCHIP_VOP2_EP_DP1)
-
-#define vop2_output_if_is_edp(x)	((x) == ROCKCHIP_VOP2_EP_EDP0 || \
-					 (x) == ROCKCHIP_VOP2_EP_EDP1)
-
-#define vop2_output_if_is_mipi(x)	((x) == ROCKCHIP_VOP2_EP_MIPI0 || \
-					 (x) == ROCKCHIP_VOP2_EP_MIPI1)
-
-#define vop2_output_if_is_lvds(x)	((x) == ROCKCHIP_VOP2_EP_LVDS0 || \
-					 (x) == ROCKCHIP_VOP2_EP_LVDS1)
-
-#define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
-
 
 /*
  * bus-format types.
@@ -272,15 +134,6 @@ static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
 
 static const struct regmap_config vop2_regmap_config;
 
-static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
-{
-	return container_of(crtc, struct vop2_video_port, crtc);
-}
-
-static struct vop2_win *to_vop2_win(struct drm_plane *p)
-{
-	return container_of(p, struct vop2_win, base);
-}
 
 static void vop2_lock(struct vop2 *vop2)
 {
@@ -292,44 +145,6 @@ static void vop2_unlock(struct vop2 *vop2)
 	mutex_unlock(&vop2->vop2_lock);
 }
 
-static void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
-{
-	regmap_write(vop2->map, offset, v);
-}
-
-static void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
-{
-	regmap_write(vp->vop2->map, vp->data->offset + offset, v);
-}
-
-static u32 vop2_readl(struct vop2 *vop2, u32 offset)
-{
-	u32 val;
-
-	regmap_read(vop2->map, offset, &val);
-
-	return val;
-}
-
-static u32 vop2_vp_read(struct vop2_video_port *vp, u32 offset)
-{
-	u32 val;
-
-	regmap_read(vp->vop2->map, vp->data->offset + offset, &val);
-
-	return val;
-}
-
-static void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
-{
-	regmap_field_write(win->reg[reg], v);
-}
-
-static bool vop2_cluster_window(const struct vop2_win *win)
-{
-	return win->data->feature & WIN_FEATURE_CLUSTER;
-}
-
 /*
  * Note:
  * The write mask function is documented but missing on rk3566/8, writes
@@ -1724,6 +1539,7 @@ static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
 static void vop2_post_config(struct drm_crtc *crtc)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	struct vop2 *vop2 = vp->vop2;
 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 	u16 vtotal = mode->crtc_vtotal;
 	u16 hdisplay = mode->crtc_hdisplay;
@@ -1734,18 +1550,10 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	u32 top_margin = 100, bottom_margin = 100;
 	u16 hsize = hdisplay * (left_margin + right_margin) / 200;
 	u16 vsize = vdisplay * (top_margin + bottom_margin) / 200;
-	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
 	u16 hact_end, vact_end;
 	u32 val;
-	u32 bg_dly;
-	u32 pre_scan_dly;
-
-	bg_dly = vp->data->pre_scan_max_dly[3];
-	vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
-		    FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
 
-	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
-	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+	vop2->ops->setup_bg_dly(vp);
 
 	vsize = rounddown(vsize, 2);
 	hsize = rounddown(hsize, 2);
@@ -1781,347 +1589,6 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
 }
 
-static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_crtc *crtc = &vp->crtc;
-	u32 die, dip;
-
-	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
-	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
-
-	switch (id) {
-	case ROCKCHIP_VOP2_EP_RGB0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_RGB |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		if (polflags & POLFLAG_DCLK_INV)
-			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
-		else
-			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
-		break;
-	case ROCKCHIP_VOP2_EP_HDMI0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_EDP0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_EDP |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI1:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_LVDS0:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_LVDS1:
-		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
-		die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
-			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
-		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
-		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
-		break;
-	default:
-		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
-		return 0;
-	}
-
-	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
-
-	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
-	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
-
-	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
-}
-
-/*
- * calc the dclk on rk3588
- * the available div of dclk is 1, 2, 4
- */
-static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
-{
-	if (child_clk * 4 <= max_dclk)
-		return child_clk * 4;
-	else if (child_clk * 2 <= max_dclk)
-		return child_clk * 2;
-	else if (child_clk <= max_dclk)
-		return child_clk;
-	else
-		return 0;
-}
-
-/*
- * 4 pixclk/cycle on rk3588
- * RGB/eDP/HDMI: if_pixclk >= dclk_core
- * DP: dp_pixclk = dclk_out <= dclk_core
- * DSI: mipi_pixclk <= dclk_out <= dclk_core
- */
-static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
-					 int *dclk_core_div, int *dclk_out_div,
-					 int *if_pixclk_div, int *if_dclk_div)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_crtc *crtc = &vp->crtc;
-	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
-	int output_mode = vcstate->output_mode;
-	unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
-	unsigned long dclk_core_rate = v_pixclk >> 2;
-	unsigned long dclk_rate = v_pixclk;
-	unsigned long dclk_out_rate;
-	unsigned long if_pixclk_rate;
-	int K = 1;
-
-	if (vop2_output_if_is_hdmi(id)) {
-		/*
-		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
-		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
-		 */
-		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
-			dclk_rate = dclk_rate >> 1;
-			K = 2;
-		}
-
-		if_pixclk_rate = (dclk_core_rate << 1) / K;
-		/*
-		 * if_dclk_rate = dclk_core_rate / K;
-		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
-		 * *if_dclk_div = dclk_rate / if_dclk_rate;
-		 */
-		*if_pixclk_div = 2;
-		*if_dclk_div = 4;
-	} else if (vop2_output_if_is_edp(id)) {
-		/*
-		 * edp_pixclk = edp_dclk > dclk_core
-		 */
-		if_pixclk_rate = v_pixclk / K;
-		dclk_rate = if_pixclk_rate * K;
-		/*
-		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
-		 * *if_dclk_div = *if_pixclk_div;
-		 */
-		*if_pixclk_div = K;
-		*if_dclk_div = K;
-	} else if (vop2_output_if_is_dp(id)) {
-		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
-			dclk_out_rate = v_pixclk >> 3;
-		else
-			dclk_out_rate = v_pixclk >> 2;
-
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
-		if (!dclk_rate) {
-			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n",
-				dclk_out_rate);
-			return 0;
-		}
-		*dclk_out_div = dclk_rate / dclk_out_rate;
-	} else if (vop2_output_if_is_mipi(id)) {
-		if_pixclk_rate = dclk_core_rate / K;
-		/*
-		 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
-		 */
-		dclk_out_rate = if_pixclk_rate;
-		/*
-		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
-		 * we get a little factor here
-		 */
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
-		if (!dclk_rate) {
-			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n",
-				dclk_out_rate);
-			return 0;
-		}
-		*dclk_out_div = dclk_rate / dclk_out_rate;
-		/*
-		 * mipi pixclk == dclk_out
-		 */
-		*if_pixclk_div = 1;
-	} else if (vop2_output_if_is_dpi(id)) {
-		dclk_rate = v_pixclk;
-	}
-
-	*dclk_core_div = dclk_rate / dclk_core_rate;
-	*if_pixclk_div = ilog2(*if_pixclk_div);
-	*if_dclk_div = ilog2(*if_dclk_div);
-	*dclk_core_div = ilog2(*dclk_core_div);
-	*dclk_out_div = ilog2(*dclk_out_div);
-
-	drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
-		dclk_rate, *if_pixclk_div, *if_dclk_div);
-
-	return dclk_rate;
-}
-
-/*
- * MIPI port mux on rk3588:
- * 0: Video Port2
- * 1: Video Port3
- * 3: Video Port 1(MIPI1 only)
- */
-static u32 rk3588_get_mipi_port_mux(int vp_id)
-{
-	if (vp_id == 1)
-		return 3;
-	else if (vp_id == 3)
-		return 1;
-	else
-		return 0;
-}
-
-static u32 rk3588_get_hdmi_pol(u32 flags)
-{
-	u32 val;
-
-	val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
-	val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
-
-	return val;
-}
-
-static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
-	unsigned long clock;
-	u32 die, dip, div, vp_clk_div, val;
-
-	clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
-				    &if_pixclk_div, &if_dclk_div);
-	if (!clock)
-		return 0;
-
-	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
-	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
-
-	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
-	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
-	div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
-
-	switch (id) {
-	case ROCKCHIP_VOP2_EP_HDMI0:
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
-			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
-		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
-		break;
-	case ROCKCHIP_VOP2_EP_HDMI1:
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
-			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
-		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
-		break;
-	case ROCKCHIP_VOP2_EP_EDP0:
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
-		break;
-	case ROCKCHIP_VOP2_EP_EDP1:
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
-		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
-		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI0:
-		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
-		val = rk3588_get_mipi_port_mux(vp->id);
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
-		break;
-	case ROCKCHIP_VOP2_EP_MIPI1:
-		div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
-		div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		val = rk3588_get_mipi_port_mux(vp->id);
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
-		break;
-	case ROCKCHIP_VOP2_EP_DP0:
-		die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
-		dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
-		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
-		break;
-	case ROCKCHIP_VOP2_EP_DP1:
-		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
-		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
-			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
-		dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
-		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
-		break;
-	default:
-		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
-		return 0;
-	}
-
-	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
-
-	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
-	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
-	vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
-	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
-
-	return clock;
-}
-
-static unsigned long vop2_set_intf_mux(struct vop2_video_port *vp, int ep_id, u32 polflags)
-{
-	struct vop2 *vop2 = vp->vop2;
-
-	if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568)
-		return rk3568_set_intf_mux(vp, ep_id, polflags);
-	else if (vop2->data->soc_id == 3588)
-		return rk3588_set_intf_mux(vp, ep_id, polflags);
-	else
-		return 0;
-}
-
 static int us_to_vertical_line(struct drm_display_mode *mode, int us)
 {
 	return us * mode->clock / mode->htotal / 1000;
@@ -2194,7 +1661,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
 		 * process multi(1/2/4/8) pixels per cycle, so the dclk feed by the
 		 * system cru may be the 1/2 or 1/4 of mode->clock.
 		 */
-		clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
+		clock = vop2->ops->setup_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
 	}
 
 	if (!clock) {
@@ -2323,454 +1790,13 @@ static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
 	return 0;
 }
 
-static bool is_opaque(u16 alpha)
-{
-	return (alpha >> 8) == 0xff;
-}
-
-static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
-			     struct vop2_alpha *alpha)
-{
-	int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
-	int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
-	int src_color_mode = alpha_config->src_premulti_en ?
-				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
-	int dst_color_mode = alpha_config->dst_premulti_en ?
-				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
-
-	alpha->src_color_ctrl.val = 0;
-	alpha->dst_color_ctrl.val = 0;
-	alpha->src_alpha_ctrl.val = 0;
-	alpha->dst_alpha_ctrl.val = 0;
-
-	if (!alpha_config->src_pixel_alpha_en)
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
-	else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
-	else
-		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
-
-	alpha->src_color_ctrl.bits.alpha_en = 1;
-
-	if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
-		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
-	} else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
-		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
-	} else {
-		alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
-		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
-	}
-	alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
-	alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-
-	alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-	alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
-	alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
-	alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
-	alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
-
-	alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
-	alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
-	alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
-
-	alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
-	if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
-		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
-	else
-		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
-	alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
-	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
-}
-
-static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
-{
-	struct vop2_video_port *vp;
-	int used_layer = 0;
-	int i;
-
-	for (i = 0; i < port_id; i++) {
-		vp = &vop2->vps[i];
-		used_layer += hweight32(vp->win_mask);
-	}
-
-	return used_layer;
-}
-
-static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
-{
-	struct vop2_alpha_config alpha_config;
-	struct vop2_alpha alpha;
-	struct drm_plane_state *bottom_win_pstate;
-	bool src_pixel_alpha_en = false;
-	u16 src_glb_alpha_val, dst_glb_alpha_val;
-	bool premulti_en = false;
-	bool swap = false;
-	u32 offset = 0;
-
-	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
-	bottom_win_pstate = main_win->base.state;
-	src_glb_alpha_val = 0;
-	dst_glb_alpha_val = main_win->base.state->alpha;
-
-	if (!bottom_win_pstate->fb)
-		return;
-
-	alpha_config.src_premulti_en = premulti_en;
-	alpha_config.dst_premulti_en = false;
-	alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
-	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
-	alpha_config.src_glb_alpha_value = src_glb_alpha_val;
-	alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
-	vop2_parse_alpha(&alpha_config, &alpha);
-
-	alpha.src_color_ctrl.bits.src_dst_swap = swap;
-
-	switch (main_win->data->phys_id) {
-	case ROCKCHIP_VOP2_CLUSTER0:
-		offset = 0x0;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER1:
-		offset = 0x10;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER2:
-		offset = 0x20;
-		break;
-	case ROCKCHIP_VOP2_CLUSTER3:
-		offset = 0x30;
-		break;
-	}
-
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
-		    alpha.src_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
-		    alpha.dst_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
-		    alpha.src_alpha_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
-		    alpha.dst_alpha_ctrl.val);
-}
-
-static void vop2_setup_alpha(struct vop2_video_port *vp)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_framebuffer *fb;
-	struct vop2_alpha_config alpha_config;
-	struct vop2_alpha alpha;
-	struct drm_plane *plane;
-	int pixel_alpha_en;
-	int premulti_en, gpremulti_en = 0;
-	int mixer_id;
-	u32 offset;
-	bool bottom_layer_alpha_en = false;
-	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
-
-	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
-	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-
-		if (plane->state->normalized_zpos == 0 &&
-		    !is_opaque(plane->state->alpha) &&
-		    !vop2_cluster_window(win)) {
-			/*
-			 * If bottom layer have global alpha effect [except cluster layer,
-			 * because cluster have deal with bottom layer global alpha value
-			 * at cluster mix], bottom layer mix need deal with global alpha.
-			 */
-			bottom_layer_alpha_en = true;
-			dst_global_alpha = plane->state->alpha;
-		}
-	}
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-		int zpos = plane->state->normalized_zpos;
-
-		/*
-		 * Need to configure alpha from second layer.
-		 */
-		if (zpos == 0)
-			continue;
-
-		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
-			premulti_en = 1;
-		else
-			premulti_en = 0;
-
-		plane = &win->base;
-		fb = plane->state->fb;
-
-		pixel_alpha_en = fb->format->has_alpha;
-
-		alpha_config.src_premulti_en = premulti_en;
-
-		if (bottom_layer_alpha_en && zpos == 1) {
-			gpremulti_en = premulti_en;
-			/* Cd = Cs + (1 - As) * Cd * Agd */
-			alpha_config.dst_premulti_en = false;
-			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
-			alpha_config.src_glb_alpha_value = plane->state->alpha;
-			alpha_config.dst_glb_alpha_value = dst_global_alpha;
-		} else if (vop2_cluster_window(win)) {
-			/* Mix output data only have pixel alpha */
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = true;
-			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-		} else {
-			/* Cd = Cs + (1 - As) * Cd */
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
-			alpha_config.src_glb_alpha_value = plane->state->alpha;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-		}
-
-		vop2_parse_alpha(&alpha_config, &alpha);
-
-		offset = (mixer_id + zpos - 1) * 0x10;
-		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
-			    alpha.src_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
-			    alpha.dst_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
-			    alpha.src_alpha_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
-			    alpha.dst_alpha_ctrl.val);
-	}
-
-	if (vp->id == 0) {
-		if (bottom_layer_alpha_en) {
-			/* Transfer pixel alpha to hdr mix */
-			alpha_config.src_premulti_en = gpremulti_en;
-			alpha_config.dst_premulti_en = true;
-			alpha_config.src_pixel_alpha_en = true;
-			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
-			vop2_parse_alpha(&alpha_config, &alpha);
-
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
-				    alpha.src_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
-				    alpha.dst_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
-				    alpha.src_alpha_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
-				    alpha.dst_alpha_ctrl.val);
-		} else {
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
-		}
-	}
-}
-
-static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
-{
-	struct vop2 *vop2 = vp->vop2;
-	struct drm_plane *plane;
-	u32 layer_sel = 0;
-	u32 port_sel;
-	u8 layer_id;
-	u8 old_layer_id;
-	u8 layer_sel_id;
-	unsigned int ofs;
-	u32 ovl_ctrl;
-	int i;
-	struct vop2_video_port *vp0 = &vop2->vps[0];
-	struct vop2_video_port *vp1 = &vop2->vps[1];
-	struct vop2_video_port *vp2 = &vop2->vps[2];
-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
-
-	ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
-	ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
-	if (vcstate->yuv_overlay)
-		ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
-	else
-		ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
-
-	vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
-
-	port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
-	port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
-
-	if (vp0->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
-				     vp0->nlayers - 1);
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
-
-	if (vp1->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
-				     (vp0->nlayers + vp1->nlayers - 1));
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
-
-	if (vp2->nlayers)
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
-			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
-	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
-
-	layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
-
-	ofs = 0;
-	for (i = 0; i < vp->id; i++)
-		ofs += vop2->vps[i].nlayers;
-
-	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-		struct vop2_win *old_win;
-
-		layer_id = (u8)(plane->state->normalized_zpos + ofs);
-
-		/*
-		 * Find the layer this win bind in old state.
-		 */
-		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
-			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
-			if (layer_sel_id == win->data->layer_sel_id)
-				break;
-		}
-
-		/*
-		 * Find the win bind to this layer in old state
-		 */
-		for (i = 0; i < vop2->data->win_size; i++) {
-			old_win = &vop2->win[i];
-			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
-			if (layer_sel_id == old_win->data->layer_sel_id)
-				break;
-		}
-
-		switch (win->data->phys_id) {
-		case ROCKCHIP_VOP2_CLUSTER0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER2:
-			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER3:
-			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART2:
-			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
-			break;
-		case ROCKCHIP_VOP2_ESMART3:
-			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
-			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
-			break;
-		case ROCKCHIP_VOP2_SMART0:
-			port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
-			break;
-		case ROCKCHIP_VOP2_SMART1:
-			port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
-			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
-			break;
-		}
-
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
-		/*
-		 * When we bind a window from layerM to layerN, we also need to move the old
-		 * window on layerN to layerM to avoid one window selected by two or more layers.
-		 */
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
-	}
-
-	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
-	vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
-}
-
-static void vop2_setup_dly_for_windows(struct vop2 *vop2)
-{
-	struct vop2_win *win;
-	int i = 0;
-	u32 cdly = 0, sdly = 0;
-
-	for (i = 0; i < vop2->data->win_size; i++) {
-		u32 dly;
-
-		win = &vop2->win[i];
-		dly = win->delay;
-
-		switch (win->data->phys_id) {
-		case ROCKCHIP_VOP2_CLUSTER0:
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
-			break;
-		case ROCKCHIP_VOP2_CLUSTER1:
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
-			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
-			break;
-		case ROCKCHIP_VOP2_ESMART0:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
-			break;
-		case ROCKCHIP_VOP2_ESMART1:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
-			break;
-		case ROCKCHIP_VOP2_SMART0:
-		case ROCKCHIP_VOP2_ESMART2:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
-			break;
-		case ROCKCHIP_VOP2_SMART1:
-		case ROCKCHIP_VOP2_ESMART3:
-			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
-			break;
-		}
-	}
-
-	vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
-	vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
-}
-
 static void vop2_crtc_atomic_begin(struct drm_crtc *crtc,
 				   struct drm_atomic_state *state)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
 	struct vop2 *vop2 = vp->vop2;
-	struct drm_plane *plane;
-
-	vp->win_mask = 0;
-
-	drm_atomic_crtc_for_each_plane(plane, crtc) {
-		struct vop2_win *win = to_vop2_win(plane);
-
-		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
-
-		vp->win_mask |= BIT(win->data->phys_id);
 
-		if (vop2_cluster_window(win))
-			vop2_setup_cluster_alpha(vop2, win);
-	}
-
-	if (!vp->win_mask)
-		return;
-
-	vop2_setup_layer_mixer(vp);
-	vop2_setup_alpha(vp);
-	vop2_setup_dly_for_windows(vop2);
+	vop2->ops->setup_overlay(vp);
 }
 
 static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
@@ -3373,182 +2399,50 @@ static int vop2_find_rgb_encoder(struct vop2 *vop2)
 	return -ENOENT;
 }
 
-static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
-	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
-	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
-	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
-	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
-	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
-	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
-	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
-	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
-	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
-	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
-	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
-	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
-	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
-	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
-	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
-	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
-	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
-	/* RK3588 only, reserved bit on rk3568*/
-	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
-
-	/* Scale */
-	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
-	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
-	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
-	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
-	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
-	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
-	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
-
-	/* cluster regs */
-	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
-	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
-	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
-
-	/* afbc regs */
-	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
-	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
-	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
-	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
-	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
-	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
-	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
-	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
-	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
-	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
-	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
-	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
-	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
-	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
-	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
-	[VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
-	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
-	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
-	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
-	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
-};
-
 static int vop2_cluster_init(struct vop2_win *win)
 {
 	struct vop2 *vop2 = win->vop2;
 	struct reg_field *cluster_regs;
 	int ret, i;
 
-	cluster_regs = kmemdup(vop2_cluster_regs, sizeof(vop2_cluster_regs),
+	cluster_regs = kmemdup(vop2->data->cluster_reg,
+			       sizeof(struct reg_field) * vop2->data->nr_cluster_regs,
 			       GFP_KERNEL);
 	if (!cluster_regs)
 		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(vop2_cluster_regs); i++)
+	for (i = 0; i < vop2->data->nr_cluster_regs; i++)
 		if (cluster_regs[i].reg != 0xffffffff)
 			cluster_regs[i].reg += win->offset;
 
 	ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
 					   cluster_regs,
-					   ARRAY_SIZE(vop2_cluster_regs));
-
+					   vop2->data->nr_cluster_regs);
 	kfree(cluster_regs);
 
 	return ret;
 };
 
-static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
-	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
-	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
-	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
-	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
-	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
-	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
-	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
-	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
-	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
-	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
-	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
-	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
-	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
-	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
-	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
-	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
-	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
-	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
-	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
-	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
-	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
-	/* RK3588 only, reserved register on rk3568 */
-	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
-
-	/* Scale */
-	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
-	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
-	[VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
-	[VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
-	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
-	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
-	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
-	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
-	[VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
-	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
-	[VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
-	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
-	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
-	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
-	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
-	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
-	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
-	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
-	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
-	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
-	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
-};
-
 static int vop2_esmart_init(struct vop2_win *win)
 {
 	struct vop2 *vop2 = win->vop2;
-	struct reg_field *esmart_regs;
+	struct reg_field *smart_regs;
 	int ret, i;
 
-	esmart_regs = kmemdup(vop2_esmart_regs, sizeof(vop2_esmart_regs),
-			      GFP_KERNEL);
-	if (!esmart_regs)
+	smart_regs = kmemdup(vop2->data->smart_reg,
+			     sizeof(struct reg_field) * vop2->data->nr_smart_regs,
+			     GFP_KERNEL);
+	if (!smart_regs)
 		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(vop2_esmart_regs); i++)
-		if (esmart_regs[i].reg != 0xffffffff)
-			esmart_regs[i].reg += win->offset;
+	for (i = 0; i < vop2->data->nr_smart_regs; i++)
+		if (smart_regs[i].reg != 0xffffffff)
+			smart_regs[i].reg += win->offset;
 
 	ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
-					   esmart_regs,
-					   ARRAY_SIZE(vop2_esmart_regs));
-
-	kfree(esmart_regs);
+					   smart_regs,
+					   vop2->data->nr_smart_regs);
+	kfree(smart_regs);
 
 	return ret;
 };
@@ -3628,6 +2522,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 
 	vop2->dev = dev;
 	vop2->data = vop2_data;
+	vop2->ops = vop2_data->ops;
 	vop2->drm = drm;
 
 	dev_set_drvdata(dev, vop2);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 29cc7fb8f6d8..265bb5bfa27d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -9,6 +9,7 @@
 
 #include <linux/regmap.h>
 #include <drm/drm_modes.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
@@ -58,6 +59,23 @@ enum vop2_scale_down_mode {
 #define VOP2_PD_DSC_4K		BIT(6)
 #define VOP2_PD_ESMART		BIT(7)
 
+#define vop2_output_if_is_hdmi(x)	((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
+					 (x) == ROCKCHIP_VOP2_EP_HDMI1)
+
+#define vop2_output_if_is_dp(x)		((x) == ROCKCHIP_VOP2_EP_DP0 || \
+					 (x) == ROCKCHIP_VOP2_EP_DP1)
+
+#define vop2_output_if_is_edp(x)	((x) == ROCKCHIP_VOP2_EP_EDP0 || \
+					 (x) == ROCKCHIP_VOP2_EP_EDP1)
+
+#define vop2_output_if_is_mipi(x)	((x) == ROCKCHIP_VOP2_EP_MIPI0 || \
+					 (x) == ROCKCHIP_VOP2_EP_MIPI1)
+
+#define vop2_output_if_is_lvds(x)	((x) == ROCKCHIP_VOP2_EP_LVDS0 || \
+					 (x) == ROCKCHIP_VOP2_EP_LVDS1)
+
+#define vop2_output_if_is_dpi(x)	((x) == ROCKCHIP_VOP2_EP_RGB0)
+
 enum vop2_win_regs {
 	VOP2_WIN_ENABLE,
 	VOP2_WIN_FORMAT,
@@ -162,6 +180,23 @@ struct vop2_win_data {
 	const u8 dly[VOP2_DLY_MODE_MAX];
 };
 
+struct vop2_win {
+	struct vop2 *vop2;
+	struct drm_plane base;
+	const struct vop2_win_data *data;
+	struct regmap_field *reg[VOP2_WIN_MAX_REG];
+
+	/**
+	 * @win_id: graphic window id, a cluster may be split into two
+	 * graphics windows.
+	 */
+	u8 win_id;
+	u8 delay;
+	u32 offset;
+
+	enum drm_plane_type type;
+};
+
 struct vop2_video_port_data {
 	unsigned int id;
 	u32 feature;
@@ -172,20 +207,105 @@ struct vop2_video_port_data {
 	unsigned int offset;
 };
 
+struct vop2_video_port {
+	struct drm_crtc crtc;
+	struct vop2 *vop2;
+	struct clk *dclk;
+	unsigned int id;
+	const struct vop2_video_port_data *data;
+
+	struct completion dsp_hold_completion;
+
+	/**
+	 * @win_mask: Bitmask of windows attached to the video port;
+	 */
+	u32 win_mask;
+
+	struct vop2_win *primary_plane;
+	struct drm_pending_vblank_event *event;
+
+	unsigned int nlayers;
+};
+
+/**
+ * struct vop2_ops - helper operations for vop2 hardware
+ *
+ * These hooks are used by the common part of the vop2 driver to
+ * implement the proper behaviour of different variants.
+ */
+struct vop2_ops {
+	unsigned long (*setup_intf_mux)(struct vop2_video_port *vp, int ep_id, u32 polflags);
+	void (*setup_bg_dly)(struct vop2_video_port *vp);
+	void (*setup_overlay)(struct vop2_video_port *vp);
+};
+
 struct vop2_data {
 	u8 nr_vps;
 	u64 feature;
+	const struct vop2_ops *ops;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
+	const struct reg_field *cluster_reg;
+	const struct reg_field *smart_reg;
 	const struct vop2_regs_dump *regs_dump;
 	struct vop_rect max_input;
 	struct vop_rect max_output;
 
+	unsigned int nr_cluster_regs;
+	unsigned int nr_smart_regs;
 	unsigned int win_size;
 	unsigned int regs_dump_size;
 	unsigned int soc_id;
 };
 
+struct vop2 {
+	struct device *dev;
+	struct drm_device *drm;
+	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
+
+	const struct vop2_data *data;
+	const struct vop2_ops *ops;
+	/*
+	 * Number of windows that are registered as plane, may be less than the
+	 * total number of hardware windows.
+	 */
+	u32 registered_num_wins;
+
+	struct resource *res;
+	void __iomem *regs;
+	struct regmap *map;
+
+	struct regmap *sys_grf;
+	struct regmap *vop_grf;
+	struct regmap *vo1_grf;
+	struct regmap *sys_pmu;
+
+	/* physical map length of vop2 register */
+	u32 len;
+
+	void __iomem *lut_regs;
+
+	/* protects crtc enable/disable */
+	struct mutex vop2_lock;
+
+	int irq;
+
+	/*
+	 * Some global resources are shared between all video ports(crtcs), so
+	 * we need a ref counter here.
+	 */
+	unsigned int enable_count;
+	struct clk *hclk;
+	struct clk *aclk;
+	struct clk *pclk;
+
+	/* optional internal rgb encoder */
+	struct rockchip_rgb *rgb;
+
+	/* must be put at the end of the struct */
+	struct vop2_win win[];
+};
+
 /* interrupt define */
 #define FS_NEW_INTR			BIT(4)
 #define ADDR_SAME_INTR			BIT(5)
@@ -560,4 +680,52 @@ enum vop2_layer_phy_id {
 
 extern const struct component_ops vop2_component_ops;
 
+static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
+{
+	regmap_write(vop2->map, offset, v);
+}
+
+static inline void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
+{
+	regmap_write(vp->vop2->map, vp->data->offset + offset, v);
+}
+
+static inline u32 vop2_readl(struct vop2 *vop2, u32 offset)
+{
+	u32 val;
+
+	regmap_read(vop2->map, offset, &val);
+
+	return val;
+}
+
+static inline u32 vop2_vp_read(struct vop2_video_port *vp, u32 offset)
+{
+	u32 val;
+
+	regmap_read(vp->vop2->map, vp->data->offset + offset, &val);
+
+	return val;
+}
+
+static inline void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
+{
+	regmap_field_write(win->reg[reg], v);
+}
+
+static inline bool vop2_cluster_window(const struct vop2_win *win)
+{
+	return win->data->feature & WIN_FEATURE_CLUSTER;
+}
+
+static inline struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct vop2_video_port, crtc);
+}
+
+static inline struct vop2_win *to_vop2_win(struct drm_plane *p)
+{
+	return container_of(p, struct vop2_win, base);
+}
+
 #endif /* _ROCKCHIP_DRM_VOP2_H */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 65a88f489693..32d2f240261f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -9,12 +9,50 @@
 #include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
+#include <drm/drm_blend.h>
 #include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
 #include <drm/drm_plane.h>
 #include <drm/drm_print.h>
 
 #include "rockchip_drm_vop2.h"
 
+union vop2_alpha_ctrl {
+	u32 val;
+	struct {
+		/* [0:1] */
+		u32 color_mode:1;
+		u32 alpha_mode:1;
+		/* [2:3] */
+		u32 blend_mode:2;
+		u32 alpha_cal_mode:1;
+		/* [5:7] */
+		u32 factor_mode:3;
+		/* [8:9] */
+		u32 alpha_en:1;
+		u32 src_dst_swap:1;
+		u32 reserved:6;
+		/* [16:23] */
+		u32 glb_alpha:8;
+	} bits;
+};
+
+struct vop2_alpha {
+	union vop2_alpha_ctrl src_color_ctrl;
+	union vop2_alpha_ctrl dst_color_ctrl;
+	union vop2_alpha_ctrl src_alpha_ctrl;
+	union vop2_alpha_ctrl dst_alpha_ctrl;
+};
+
+struct vop2_alpha_config {
+	bool src_premulti_en;
+	bool dst_premulti_en;
+	bool src_pixel_alpha_en;
+	bool dst_pixel_alpha_en;
+	u16 src_glb_alpha_value;
+	u16 dst_glb_alpha_value;
+};
+
 static const uint32_t formats_cluster[] = {
 	DRM_FORMAT_XRGB2101010,
 	DRM_FORMAT_XBGR2101010,
@@ -131,6 +169,138 @@ static const uint64_t format_modifiers_afbc[] = {
 	DRM_FORMAT_MOD_INVALID,
 };
 
+static const struct reg_field rk3568_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
+	/* RK3588 only, reserved bit on rk3568*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
+
+	/* cluster regs */
+	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
+	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
+	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
+
+	/* afbc regs */
+	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
+	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
+	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
+	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
+	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
+	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
+	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
+	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
+	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
+	[VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
+};
+
+static const struct reg_field rk3568_vop_smart_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
+	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
+	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	/* RK3588 only, reserved register on rk3568 */
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
+	[VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
+	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
+	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
+	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
+};
+
 static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -647,6 +817,813 @@ static const struct vop2_regs_dump rk3588_regs_dump[] = {
 	},
 };
 
+static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	u32 die, dip;
+
+	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
+	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_RGB0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_RGB |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		if (polflags & POLFLAG_DCLK_INV)
+			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
+		else
+			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
+		break;
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_EDP |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI1:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_LVDS0:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_LVDS1:
+		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
+		die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
+			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
+		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
+		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
+
+	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
+	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
+
+	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
+}
+
+/*
+ * calc the dclk on rk3588
+ * the available div of dclk is 1, 2, 4
+ */
+static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
+{
+	if (child_clk * 4 <= max_dclk)
+		return child_clk * 4;
+	else if (child_clk * 2 <= max_dclk)
+		return child_clk * 2;
+	else if (child_clk <= max_dclk)
+		return child_clk;
+	else
+		return 0;
+}
+
+/*
+ * 4 pixclk/cycle on rk3588
+ * RGB/eDP/HDMI: if_pixclk >= dclk_core
+ * DP: dp_pixclk = dclk_out <= dclk_core
+ * DSI: mipi_pixclk <= dclk_out <= dclk_core
+ */
+static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
+					 int *dclk_core_div, int *dclk_out_div,
+					 int *if_pixclk_div, int *if_dclk_div)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
+	int output_mode = vcstate->output_mode;
+	unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
+	unsigned long dclk_core_rate = v_pixclk >> 2;
+	unsigned long dclk_rate = v_pixclk;
+	unsigned long dclk_out_rate;
+	unsigned long if_pixclk_rate;
+	int K = 1;
+
+	if (vop2_output_if_is_hdmi(id)) {
+		/*
+		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
+		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
+		 */
+		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
+			dclk_rate = dclk_rate >> 1;
+			K = 2;
+		}
+
+		if_pixclk_rate = (dclk_core_rate << 1) / K;
+		/*
+		 * if_dclk_rate = dclk_core_rate / K;
+		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
+		 * *if_dclk_div = dclk_rate / if_dclk_rate;
+		 */
+		*if_pixclk_div = 2;
+		*if_dclk_div = 4;
+	} else if (vop2_output_if_is_edp(id)) {
+		/*
+		 * edp_pixclk = edp_dclk > dclk_core
+		 */
+		if_pixclk_rate = v_pixclk / K;
+		dclk_rate = if_pixclk_rate * K;
+		/*
+		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
+		 * *if_dclk_div = *if_pixclk_div;
+		 */
+		*if_pixclk_div = K;
+		*if_dclk_div = K;
+	} else if (vop2_output_if_is_dp(id)) {
+		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
+			dclk_out_rate = v_pixclk >> 3;
+		else
+			dclk_out_rate = v_pixclk >> 2;
+
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
+		if (!dclk_rate) {
+			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n",
+				dclk_out_rate);
+			return 0;
+		}
+		*dclk_out_div = dclk_rate / dclk_out_rate;
+	} else if (vop2_output_if_is_mipi(id)) {
+		if_pixclk_rate = dclk_core_rate / K;
+		/*
+		 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
+		 */
+		dclk_out_rate = if_pixclk_rate;
+		/*
+		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
+		 * we get a little factor here
+		 */
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
+		if (!dclk_rate) {
+			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n",
+				dclk_out_rate);
+			return 0;
+		}
+		*dclk_out_div = dclk_rate / dclk_out_rate;
+		/*
+		 * mipi pixclk == dclk_out
+		 */
+		*if_pixclk_div = 1;
+	} else if (vop2_output_if_is_dpi(id)) {
+		dclk_rate = v_pixclk;
+	}
+
+	*dclk_core_div = dclk_rate / dclk_core_rate;
+	*if_pixclk_div = ilog2(*if_pixclk_div);
+	*if_dclk_div = ilog2(*if_dclk_div);
+	*dclk_core_div = ilog2(*dclk_core_div);
+	*dclk_out_div = ilog2(*dclk_out_div);
+
+	drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
+		dclk_rate, *if_pixclk_div, *if_dclk_div);
+
+	return dclk_rate;
+}
+
+/*
+ * MIPI port mux on rk3588:
+ * 0: Video Port2
+ * 1: Video Port3
+ * 3: Video Port 1(MIPI1 only)
+ */
+static u32 rk3588_get_mipi_port_mux(int vp_id)
+{
+	if (vp_id == 1)
+		return 3;
+	else if (vp_id == 3)
+		return 1;
+	else
+		return 0;
+}
+
+static u32 rk3588_get_hdmi_pol(u32 flags)
+{
+	u32 val;
+
+	val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
+	val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
+
+	return val;
+}
+
+static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
+	unsigned long clock;
+	u32 die, dip, div, vp_clk_div, val;
+
+	clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
+				    &if_pixclk_div, &if_dclk_div);
+	if (!clock)
+		return 0;
+
+	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
+	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
+
+	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
+	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
+	div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
+			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
+		val = rk3588_get_hdmi_pol(polflags);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
+		break;
+	case ROCKCHIP_VOP2_EP_HDMI1:
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
+			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
+		val = rk3588_get_hdmi_pol(polflags);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
+		break;
+	case ROCKCHIP_VOP2_EP_EDP1:
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
+		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
+		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
+		val = rk3588_get_mipi_port_mux(vp->id);
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI1:
+		div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
+		div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		val = rk3588_get_mipi_port_mux(vp->id);
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
+		break;
+	case ROCKCHIP_VOP2_EP_DP0:
+		die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
+		dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
+		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
+		break;
+	case ROCKCHIP_VOP2_EP_DP1:
+		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
+		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
+			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
+		dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
+		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
+
+	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
+	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
+	vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
+	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
+
+	return clock;
+}
+
+static bool is_opaque(u16 alpha)
+{
+	return (alpha >> 8) == 0xff;
+}
+
+static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
+			     struct vop2_alpha *alpha)
+{
+	int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
+	int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
+	int src_color_mode = alpha_config->src_premulti_en ?
+				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
+	int dst_color_mode = alpha_config->dst_premulti_en ?
+				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
+
+	alpha->src_color_ctrl.val = 0;
+	alpha->dst_color_ctrl.val = 0;
+	alpha->src_alpha_ctrl.val = 0;
+	alpha->dst_alpha_ctrl.val = 0;
+
+	if (!alpha_config->src_pixel_alpha_en)
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
+	else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
+	else
+		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
+
+	alpha->src_color_ctrl.bits.alpha_en = 1;
+
+	if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
+		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
+	} else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
+		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
+	} else {
+		alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
+		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
+	}
+	alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
+	alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+
+	alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+	alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
+	alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
+	alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
+	alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
+
+	alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
+	alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
+	alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
+
+	alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
+	if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
+		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
+	else
+		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
+	alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
+	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
+}
+
+static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
+{
+	struct vop2_video_port *vp;
+	int used_layer = 0;
+	int i;
+
+	for (i = 0; i < port_id; i++) {
+		vp = &vop2->vps[i];
+		used_layer += hweight32(vp->win_mask);
+	}
+
+	return used_layer;
+}
+
+static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
+{
+	struct vop2_alpha_config alpha_config;
+	struct vop2_alpha alpha;
+	struct drm_plane_state *bottom_win_pstate;
+	bool src_pixel_alpha_en = false;
+	u16 src_glb_alpha_val, dst_glb_alpha_val;
+	u32 offset = 0;
+	bool premulti_en = false;
+	bool swap = false;
+
+	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
+	bottom_win_pstate = main_win->base.state;
+	src_glb_alpha_val = 0;
+	dst_glb_alpha_val = main_win->base.state->alpha;
+
+	if (!bottom_win_pstate->fb)
+		return;
+
+	alpha_config.src_premulti_en = premulti_en;
+	alpha_config.dst_premulti_en = false;
+	alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
+	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
+	alpha_config.src_glb_alpha_value = src_glb_alpha_val;
+	alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
+	vop2_parse_alpha(&alpha_config, &alpha);
+
+	alpha.src_color_ctrl.bits.src_dst_swap = swap;
+
+	switch (main_win->data->phys_id) {
+	case ROCKCHIP_VOP2_CLUSTER0:
+		offset = 0x0;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER1:
+		offset = 0x10;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER2:
+		offset = 0x20;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER3:
+		offset = 0x30;
+		break;
+	}
+
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
+		    alpha.src_color_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
+		    alpha.dst_color_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
+		    alpha.src_alpha_ctrl.val);
+	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
+		    alpha.dst_alpha_ctrl.val);
+}
+
+static void vop2_setup_alpha(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_framebuffer *fb;
+	struct vop2_alpha_config alpha_config;
+	struct vop2_alpha alpha;
+	struct drm_plane *plane;
+	int pixel_alpha_en;
+	int premulti_en, gpremulti_en = 0;
+	int mixer_id;
+	u32 offset;
+	bool bottom_layer_alpha_en = false;
+	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
+
+	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		if (plane->state->normalized_zpos == 0 &&
+		    !is_opaque(plane->state->alpha) &&
+		    !vop2_cluster_window(win)) {
+			/*
+			 * If bottom layer have global alpha effect [except cluster layer,
+			 * because cluster have deal with bottom layer global alpha value
+			 * at cluster mix], bottom layer mix need deal with global alpha.
+			 */
+			bottom_layer_alpha_en = true;
+			dst_global_alpha = plane->state->alpha;
+		}
+	}
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+		int zpos = plane->state->normalized_zpos;
+
+		/*
+		 * Need to configure alpha from second layer.
+		 */
+		if (zpos == 0)
+			continue;
+
+		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
+			premulti_en = 1;
+		else
+			premulti_en = 0;
+
+		plane = &win->base;
+		fb = plane->state->fb;
+
+		pixel_alpha_en = fb->format->has_alpha;
+
+		alpha_config.src_premulti_en = premulti_en;
+
+		if (bottom_layer_alpha_en && zpos == 1) {
+			gpremulti_en = premulti_en;
+			/* Cd = Cs + (1 - As) * Cd * Agd */
+			alpha_config.dst_premulti_en = false;
+			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
+			alpha_config.src_glb_alpha_value = plane->state->alpha;
+			alpha_config.dst_glb_alpha_value = dst_global_alpha;
+		} else if (vop2_cluster_window(win)) {
+			/* Mix output data only have pixel alpha */
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = true;
+			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+		} else {
+			/* Cd = Cs + (1 - As) * Cd */
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
+			alpha_config.src_glb_alpha_value = plane->state->alpha;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+		}
+
+		vop2_parse_alpha(&alpha_config, &alpha);
+
+		offset = (mixer_id + zpos - 1) * 0x10;
+		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
+			    alpha.src_color_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
+			    alpha.dst_color_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
+			    alpha.src_alpha_ctrl.val);
+		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
+			    alpha.dst_alpha_ctrl.val);
+	}
+
+	if (vp->id == 0) {
+		if (bottom_layer_alpha_en) {
+			/* Transfer pixel alpha to hdr mix */
+			alpha_config.src_premulti_en = gpremulti_en;
+			alpha_config.dst_premulti_en = true;
+			alpha_config.src_pixel_alpha_en = true;
+			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+			vop2_parse_alpha(&alpha_config, &alpha);
+
+			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
+				    alpha.src_color_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
+				    alpha.dst_color_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
+				    alpha.src_alpha_ctrl.val);
+			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
+				    alpha.dst_alpha_ctrl.val);
+		} else {
+			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
+		}
+	}
+}
+
+static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_plane *plane;
+	u32 layer_sel = 0;
+	u32 port_sel;
+	u8 layer_id;
+	u8 old_layer_id;
+	u8 layer_sel_id;
+	unsigned int ofs;
+	u32 ovl_ctrl;
+	int i;
+	struct vop2_video_port *vp0 = &vop2->vps[0];
+	struct vop2_video_port *vp1 = &vop2->vps[1];
+	struct vop2_video_port *vp2 = &vop2->vps[2];
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
+
+	ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
+	ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
+	if (vcstate->yuv_overlay)
+		ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
+	else
+		ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
+
+	vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
+
+	port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
+	port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
+
+	if (vp0->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
+				     vp0->nlayers - 1);
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
+
+	if (vp1->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
+				     (vp0->nlayers + vp1->nlayers - 1));
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
+
+	if (vp2->nlayers)
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
+			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
+	else
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
+
+	layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
+
+	ofs = 0;
+	for (i = 0; i < vp->id; i++)
+		ofs += vop2->vps[i].nlayers;
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+		struct vop2_win *old_win;
+
+		layer_id = (u8)(plane->state->normalized_zpos + ofs);
+		/*
+		 * Find the layer this win bind in old state.
+		 */
+		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
+			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
+			if (layer_sel_id == win->data->layer_sel_id)
+				break;
+		}
+
+		/*
+		 * Find the win bind to this layer in old state
+		 */
+		for (i = 0; i < vop2->data->win_size; i++) {
+			old_win = &vop2->win[i];
+			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
+			if (layer_sel_id == old_win->data->layer_sel_id)
+				break;
+		}
+
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_CLUSTER0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER2:
+			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER3:
+			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART2:
+			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
+			break;
+		case ROCKCHIP_VOP2_ESMART3:
+			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
+			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
+			break;
+		case ROCKCHIP_VOP2_SMART0:
+			port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
+			break;
+		case ROCKCHIP_VOP2_SMART1:
+			port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
+			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
+			break;
+		}
+
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
+		/*
+		 * When we bind a window from layerM to layerN, we also need to move the old
+		 * window on layerN to layerM to avoid one window selected by two or more layers.
+		 */
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
+	}
+
+	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
+	vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
+}
+
+static void rk3568_vop2_setup_dly_for_windows(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct vop2_win *win;
+	int i = 0;
+	u32 cdly = 0, sdly = 0;
+
+	for (i = 0; i < vop2->data->win_size; i++) {
+		u32 dly;
+
+		win = &vop2->win[i];
+		dly = win->delay;
+
+		switch (win->data->phys_id) {
+		case ROCKCHIP_VOP2_CLUSTER0:
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
+			break;
+		case ROCKCHIP_VOP2_CLUSTER1:
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
+			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
+			break;
+		case ROCKCHIP_VOP2_ESMART0:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
+			break;
+		case ROCKCHIP_VOP2_ESMART1:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
+			break;
+		case ROCKCHIP_VOP2_SMART0:
+		case ROCKCHIP_VOP2_ESMART2:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
+			break;
+		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART3:
+			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
+			break;
+		}
+	}
+
+	vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
+	vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
+}
+
+static void rk3568_vop2_setup_overlay(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_plane *plane;
+
+	vp->win_mask = 0;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
+
+		vp->win_mask |= BIT(win->data->phys_id);
+
+		if (vop2_cluster_window(win))
+			vop2_setup_cluster_alpha(vop2, win);
+	}
+
+	if (!vp->win_mask)
+		return;
+
+	rk3568_vop2_setup_layer_mixer(vp);
+	vop2_setup_alpha(vp);
+	rk3568_vop2_setup_dly_for_windows(vp);
+}
+
+static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
+{
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	u16 hdisplay = mode->crtc_hdisplay;
+	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+	u32 bg_dly;
+	u32 pre_scan_dly;
+
+	bg_dly = vp->data->pre_scan_max_dly[3];
+	vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
+		    FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
+
+	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
+	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+}
+
+static const struct vop2_ops rk3568_vop_ops = {
+	.setup_intf_mux = rk3568_set_intf_mux,
+	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
+	.setup_overlay = rk3568_vop2_setup_overlay,
+};
+
+static const struct vop2_ops rk3588_vop_ops = {
+	.setup_intf_mux = rk3588_set_intf_mux,
+	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
+	.setup_overlay = rk3568_vop2_setup_overlay,
+};
+
 static const struct vop2_data rk3566_vop = {
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
@@ -655,8 +1632,13 @@ static const struct vop2_data rk3566_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3568_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
+	.ops = &rk3568_vop_ops,
 	.soc_id = 3566,
 };
 
@@ -668,8 +1650,13 @@ static const struct vop2_data rk3568_vop = {
 	.vp = rk3568_vop_video_ports,
 	.win = rk3568_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3568_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
+	.ops = &rk3568_vop_ops,
 	.soc_id = 3568,
 };
 
@@ -682,8 +1669,13 @@ static const struct vop2_data rk3588_vop = {
 	.vp = rk3588_vop_video_ports,
 	.win = rk3588_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
+	.cluster_reg = rk3568_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
+	.smart_reg = rk3568_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
 	.regs_dump = rk3588_regs_dump,
 	.regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
+	.ops = &rk3588_vop_ops,
 	.soc_id = 3588,
 };
 
-- 
2.34.1



From andyshrk at 163.com  Wed Dec 18 23:39:17 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:17 +0800
Subject: [PATCH v7 9/9] drm/rockchip: vop2: Add support for rk3576
In-Reply-To: <20241219073931.3997788-1-andyshrk@163.com>
References: <20241219073931.3997788-1-andyshrk@163.com>
Message-ID: <20241219073931.3997788-10-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

VOP2 on rk3576:
Three video ports:
VP0 Max 4096x2160
VP1 Max 2560x1600
VP2 Max 1920x1080

2 4K Cluster windows with AFBC/RFBC, line RGB and YUV
4 Esmart windows with line RGB/YUV support:
Esmart0/1: 4K
Esmart2/3: 2k, or worked together as a single 4K plane at shared
line buffer mode.

Compared to the previous VOP, another difference is that each VP
has its own independent vsync interrupt number.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v6)

Changes in v6:
-  More specific explanation about the AXI_BUS_ID register bit of
   cluster window.

Changes in v5:
- Add axi id configuration
- Remove the non-existent CBCR scale register.

Changes in v3:
- Share the alpha setup function with rk3568
- recoder the code block by soc

Changes in v2:
- Add platform specific callback

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 144 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  87 ++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 950 +++++++++++++++++--
 3 files changed, 1056 insertions(+), 125 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0ddfafa3c208..e6327879b6b7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1276,6 +1276,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
 	}
 
+	if (vop2->version >= VOP_VERSION_RK3576)
+		vop2_win_write(win, VOP2_WIN_VP_SEL, vp->id);
+
 	if (vop2_cluster_window(win))
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
@@ -1340,6 +1343,11 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
 
+		if (vop2->version >= VOP_VERSION_RK3576) {
+			vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET_EN, 1);
+			vop2_win_write(win, VOP2_WIN_AFBC_PLD_OFFSET, yrgb_mst);
+		}
+
 		transform_offset = vop2_afbc_transform_offset(pstate, half_block_en);
 		vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
 		vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
@@ -2118,6 +2126,56 @@ static const struct drm_crtc_funcs vop2_crtc_funcs = {
 	.late_register = vop2_crtc_late_register,
 };
 
+static irqreturn_t rk3576_vp_isr(int irq, void *data)
+{
+	struct vop2_video_port *vp = data;
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	uint32_t irqs;
+	int ret = IRQ_NONE;
+
+	/*
+	 * The irq is shared with the iommu. If the runtime-pm state of the
+	 * vop2-device is disabled the irq has to be targeted at the iommu.
+	 */
+	if (!pm_runtime_get_if_in_use(vop2->dev))
+		return IRQ_NONE;
+
+	irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
+	vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
+
+	if (irqs & VP_INT_DSP_HOLD_VALID) {
+		complete(&vp->dsp_hold_completion);
+		ret = IRQ_HANDLED;
+	}
+
+	if (irqs & VP_INT_FS_FIELD) {
+		drm_crtc_handle_vblank(crtc);
+		spin_lock(&crtc->dev->event_lock);
+		if (vp->event) {
+			u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
+
+			if (!(val & BIT(vp->id))) {
+				drm_crtc_send_vblank_event(crtc, vp->event);
+				vp->event = NULL;
+				drm_crtc_vblank_put(crtc);
+			}
+		}
+		spin_unlock(&crtc->dev->event_lock);
+
+		ret = IRQ_HANDLED;
+	}
+
+	if (irqs & VP_INT_POST_BUF_EMPTY) {
+		drm_err_ratelimited(vop2->drm, "POST_BUF_EMPTY irq err at vp%d\n", vp->id);
+		ret = IRQ_HANDLED;
+	}
+
+	pm_runtime_put(vop2->dev);
+
+	return ret;
+}
+
 static irqreturn_t vop2_isr(int irq, void *data)
 {
 	struct vop2 *vop2 = data;
@@ -2133,41 +2191,43 @@ static irqreturn_t vop2_isr(int irq, void *data)
 	if (!pm_runtime_get_if_in_use(vop2->dev))
 		return IRQ_NONE;
 
-	for (i = 0; i < vop2_data->nr_vps; i++) {
-		struct vop2_video_port *vp = &vop2->vps[i];
-		struct drm_crtc *crtc = &vp->crtc;
-		u32 irqs;
+	if (vop2->version < VOP_VERSION_RK3576) {
+		for (i = 0; i < vop2_data->nr_vps; i++) {
+			struct vop2_video_port *vp = &vop2->vps[i];
+			struct drm_crtc *crtc = &vp->crtc;
+			u32 irqs;
 
-		irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
-		vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
+			irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
+			vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
 
-		if (irqs & VP_INT_DSP_HOLD_VALID) {
-			complete(&vp->dsp_hold_completion);
-			ret = IRQ_HANDLED;
-		}
-
-		if (irqs & VP_INT_FS_FIELD) {
-			drm_crtc_handle_vblank(crtc);
-			spin_lock(&crtc->dev->event_lock);
-			if (vp->event) {
-				u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
+			if (irqs & VP_INT_DSP_HOLD_VALID) {
+				complete(&vp->dsp_hold_completion);
+				ret = IRQ_HANDLED;
+			}
 
-				if (!(val & BIT(vp->id))) {
-					drm_crtc_send_vblank_event(crtc, vp->event);
-					vp->event = NULL;
-					drm_crtc_vblank_put(crtc);
+			if (irqs & VP_INT_FS_FIELD) {
+				drm_crtc_handle_vblank(crtc);
+				spin_lock(&crtc->dev->event_lock);
+				if (vp->event) {
+					u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
+
+					if (!(val & BIT(vp->id))) {
+						drm_crtc_send_vblank_event(crtc, vp->event);
+						vp->event = NULL;
+						drm_crtc_vblank_put(crtc);
+					}
 				}
-			}
-			spin_unlock(&crtc->dev->event_lock);
+				spin_unlock(&crtc->dev->event_lock);
 
-			ret = IRQ_HANDLED;
-		}
+				ret = IRQ_HANDLED;
+			}
 
-		if (irqs & VP_INT_POST_BUF_EMPTY) {
-			drm_err_ratelimited(vop2->drm,
-					    "POST_BUF_EMPTY irq err at vp%d\n",
-					    vp->id);
-			ret = IRQ_HANDLED;
+			if (irqs & VP_INT_POST_BUF_EMPTY) {
+				drm_err_ratelimited(vop2->drm,
+						    "POST_BUF_EMPTY irq err at vp%d\n",
+						    vp->id);
+				ret = IRQ_HANDLED;
+			}
 		}
 	}
 
@@ -2659,6 +2719,32 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 	if (ret)
 		return ret;
 
+	if (vop2->version >= VOP_VERSION_RK3576) {
+		struct drm_crtc *crtc;
+
+		drm_for_each_crtc(crtc, drm) {
+			struct vop2_video_port *vp = to_vop2_video_port(crtc);
+			int vp_irq;
+			const char *irq_name = devm_kasprintf(dev, GFP_KERNEL, "vop-vp%d", vp->id);
+
+			if (!irq_name)
+				return -ENOMEM;
+
+			vp_irq = platform_get_irq_byname(pdev, irq_name);
+			if (vp_irq < 0) {
+				DRM_DEV_ERROR(dev, "cannot find irq for vop2 vp%d\n", vp->id);
+				return vp_irq;
+			}
+
+			ret = devm_request_irq(dev, vp_irq, rk3576_vp_isr, IRQF_SHARED, irq_name,
+					       vp);
+			if (ret) {
+				DRM_DEV_ERROR(dev, "request irq for vop2 vp%d failed\n", vp->id);
+				return ret;
+			}
+		}
+	}
+
 	ret = vop2_find_rgb_encoder(vop2);
 	if (ret >= 0) {
 		vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 3c9caf13749d..ca3f1613d51c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -44,6 +44,13 @@ enum win_dly_mode {
 	VOP2_DLY_MODE_MAX,
 };
 
+enum vop2_dly_module {
+	VOP2_DLY_WIN,           /** Win delay cycle for this VP */
+	VOP2_DLY_LAYER_MIX,     /** Layer Mix delay cycle for this VP */
+	VOP2_DLY_HDR_MIX,       /** HDR delay cycle for this VP */
+	VOP2_DLY_MAX,
+};
+
 enum vop2_scale_up_mode {
 	VOP2_SCALE_UP_NRST_NBOR,
 	VOP2_SCALE_UP_BIL,
@@ -140,16 +147,22 @@ enum vop2_win_regs {
 	VOP2_WIN_AFBC_UV_SWAP,
 	VOP2_WIN_AFBC_AUTO_GATING_EN,
 	VOP2_WIN_AFBC_BLOCK_SPLIT_EN,
+	VOP2_WIN_AFBC_PLD_OFFSET_EN,
 	VOP2_WIN_AFBC_PIC_VIR_WIDTH,
 	VOP2_WIN_AFBC_TILE_NUM,
 	VOP2_WIN_AFBC_PIC_OFFSET,
 	VOP2_WIN_AFBC_PIC_SIZE,
 	VOP2_WIN_AFBC_DSP_OFFSET,
+	VOP2_WIN_AFBC_PLD_OFFSET,
 	VOP2_WIN_AFBC_TRANSFORM_OFFSET,
 	VOP2_WIN_AFBC_HDR_PTR,
 	VOP2_WIN_AFBC_HALF_BLOCK_EN,
 	VOP2_WIN_AFBC_ROTATE_270,
 	VOP2_WIN_AFBC_ROTATE_90,
+
+	VOP2_WIN_VP_SEL,
+	VOP2_WIN_DLY_NUM,
+
 	VOP2_WIN_MAX_REG,
 };
 
@@ -215,6 +228,10 @@ struct vop2_video_port_data {
 	struct vop_rect max_output;
 	const u8 pre_scan_max_dly[4];
 	unsigned int offset;
+	/**
+	 * @pixel_rate: pixel per cycle
+	 */
+	u8 pixel_rate;
 };
 
 struct vop2_video_port {
@@ -372,10 +389,13 @@ enum dst_factor_mode {
 #define RK3568_REG_CFG_DONE			0x000
 #define RK3568_VERSION_INFO			0x004
 #define RK3568_SYS_AUTO_GATING_CTRL		0x008
+#define RK3576_SYS_MMU_CTRL_IMD			0x020
 #define RK3568_SYS_AXI_LUT_CTRL			0x024
 #define RK3568_DSP_IF_EN			0x028
+#define RK3576_SYS_PORT_CTRL_IMD		0x028
 #define RK3568_DSP_IF_CTRL			0x02c
 #define RK3568_DSP_IF_POL			0x030
+#define RK3576_SYS_CLUSTER_PD_CTRL_IMD		0x030
 #define RK3588_SYS_PD_CTRL			0x034
 #define RK3568_WB_CTRL				0x40
 #define RK3568_WB_XSCAL_FACTOR			0x44
@@ -395,6 +415,55 @@ enum dst_factor_mode {
 #define RK3568_VP_INT_CLR(vp)			(0xA4 + (vp) * 0x10)
 #define RK3568_VP_INT_STATUS(vp)		(0xA8 + (vp) * 0x10)
 #define RK3568_VP_INT_RAW_STATUS(vp)		(0xAC + (vp) * 0x10)
+#define RK3576_WB_CTRL				0x100
+#define RK3576_WB_XSCAL_FACTOR			0x104
+#define RK3576_WB_YRGB_MST			0x108
+#define RK3576_WB_CBR_MST			0x10C
+#define RK3576_WB_VIR_STRIDE			0x110
+#define RK3576_WB_TIMEOUT_CTRL			0x114
+#define RK3576_MIPI0_IF_CTRL			0x180
+#define RK3576_HDMI0_IF_CTRL			0x184
+#define RK3576_EDP0_IF_CTRL			0x188
+#define RK3576_DP0_IF_CTRL			0x18C
+#define RK3576_RGB_IF_CTRL			0x194
+#define RK3576_DP1_IF_CTRL			0x1A4
+#define RK3576_DP2_IF_CTRL			0x1B0
+
+/* Extra OVL register definition */
+#define RK3576_SYS_EXTRA_ALPHA_CTRL		0x500
+#define RK3576_CLUSTER0_MIX_SRC_COLOR_CTRL	0x530
+#define RK3576_CLUSTER0_MIX_DST_COLOR_CTRL	0x534
+#define RK3576_CLUSTER0_MIX_SRC_ALPHA_CTRL	0x538
+#define RK3576_CLUSTER0_MIX_DST_ALPHA_CTRL	0x53c
+#define RK3576_CLUSTER1_MIX_SRC_COLOR_CTRL	0x540
+#define RK3576_CLUSTER1_MIX_DST_COLOR_CTRL	0x544
+#define RK3576_CLUSTER1_MIX_SRC_ALPHA_CTRL	0x548
+#define RK3576_CLUSTER1_MIX_DST_ALPHA_CTRL	0x54c
+
+/* OVL registers for Video Port definition */
+#define RK3576_OVL_CTRL(vp)			(0x600 + (vp) * 0x100)
+#define RK3576_OVL_LAYER_SEL(vp)		(0x604 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_SRC_COLOR_CTRL(vp)	(0x620 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_DST_COLOR_CTRL(vp)	(0x624 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_SRC_ALPHA_CTRL(vp)	(0x628 + (vp) * 0x100)
+#define RK3576_OVL_MIX0_DST_ALPHA_CTRL(vp)	(0x62C + (vp) * 0x100)
+#define RK3576_OVL_MIX1_SRC_COLOR_CTRL(vp)	(0x630 + (vp) * 0x100)
+#define RK3576_OVL_MIX1_DST_COLOR_CTRL(vp)	(0x634 + (vp) * 0x100)
+#define RK3576_OVL_MIX1_SRC_ALPHA_CTRL(vp)	(0x638 + (vp) * 0x100)
+#define RK3576_OVL_MIX1_DST_ALPHA_CTRL(vp)	(0x63C + (vp) * 0x100)
+#define RK3576_OVL_MIX2_SRC_COLOR_CTRL(vp)	(0x640 + (vp) * 0x100)
+#define RK3576_OVL_MIX2_DST_COLOR_CTRL(vp)	(0x644 + (vp) * 0x100)
+#define RK3576_OVL_MIX2_SRC_ALPHA_CTRL(vp)	(0x648 + (vp) * 0x100)
+#define RK3576_OVL_MIX2_DST_ALPHA_CTRL(vp)	(0x64C + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_SRC_COLOR_CTRL(vp)	(0x650 + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_DST_COLOR_CTRL(vp)	(0x654 + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_SRC_ALPHA_CTRL(vp)	(0x658 + (vp) * 0x100)
+#define RK3576_EXTRA_OVL_DST_ALPHA_CTRL(vp)	(0x65C + (vp) * 0x100)
+#define RK3576_OVL_HDR_SRC_COLOR_CTRL(vp)	(0x660 + (vp) * 0x100)
+#define RK3576_OVL_HDR_DST_COLOR_CTRL(vp)	(0x664 + (vp) * 0x100)
+#define RK3576_OVL_HDR_SRC_ALPHA_CTRL(vp)	(0x668 + (vp) * 0x100)
+#define RK3576_OVL_HDR_DST_ALPHA_CTRL(vp)	(0x66C + (vp) * 0x100)
+#define RK3576_OVL_BG_MIX_CTRL(vp)		(0x670 + (vp) * 0x100)
 
 /* Video Port registers definition */
 #define RK3568_VP0_CTRL_BASE			0x0C00
@@ -477,7 +546,11 @@ enum dst_factor_mode {
 #define RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET	0x68
 #define RK3568_CLUSTER_WIN_AFBCD_CTRL		0x6C
 
+#define RK3576_CLUSTER_WIN_AFBCD_PLD_PTR_OFFSET	0x78
+
 #define RK3568_CLUSTER_CTRL			0x100
+#define RK3576_CLUSTER_PORT_SEL_IMD		0x1F4
+#define RK3576_CLUSTER_DLY_NUM			0x1F8
 
 /* (E)smart register definition, offset relative to window base */
 #define RK3568_SMART_CTRL0			0x00
@@ -528,6 +601,9 @@ enum dst_factor_mode {
 #define RK3568_SMART_REGION3_SCL_FACTOR_CBR	0xC8
 #define RK3568_SMART_REGION3_SCL_OFFSET		0xCC
 #define RK3568_SMART_COLOR_KEY_CTRL		0xD0
+#define RK3576_SMART_ALPHA_MAP			0xD8
+#define RK3576_SMART_PORT_SEL_IMD		0xF4
+#define RK3576_SMART_DLY_NUM			0xF8
 
 /* HDR register definition */
 #define RK3568_HDR_LUT_CTRL			0x2000
@@ -676,6 +752,17 @@ enum dst_factor_mode {
 
 #define POLFLAG_DCLK_INV	BIT(3)
 
+#define RK3576_OVL_CTRL__YUV_MODE			BIT(0)
+#define RK3576_OVL_BG_MIX_CTRL__BG_DLY			GENMASK(31, 24)
+
+#define RK3576_DSP_IF_CFG_DONE_IMD			BIT(31)
+#define RK3576_DSP_IF_DCLK_SEL_OUT			BIT(21)
+#define RK3576_DSP_IF_PCLK_DIV				BIT(20)
+#define RK3576_DSP_IF_PIN_POL				GENMASK(5, 4)
+#define RK3576_DSP_IF_MUX				GENMASK(3, 2)
+#define RK3576_DSP_IF_CLK_OUT_EN			BIT(1)
+#define RK3576_DSP_IF_EN				BIT(0)
+
 enum vop2_layer_phy_id {
 	ROCKCHIP_VOP2_CLUSTER0 = 0,
 	ROCKCHIP_VOP2_CLUSTER1,
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index f0b0608fe1be..9c1fefdb9b5a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -70,6 +70,37 @@ static const uint32_t formats_cluster[] = {
 	DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */
 };
 
+/*
+ * The cluster windows on rk3576 support:
+ * RGB: linear mode and afbc
+ * YUV: linear mode and rfbc
+ * rfbc is a rockchip defined non-linear mode, produced by
+ * Video decoder
+ */
+static const uint32_t formats_rk3576_cluster[] = {
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_ABGR2101010,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
+};
+
 static const uint32_t formats_esmart[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -116,6 +147,41 @@ static const uint32_t formats_rk356x_esmart[] = {
 	DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
 };
 
+/*
+ * Add XRGB2101010/ARGB2101010ARGB1555/XRGB1555
+ */
+static const uint32_t formats_rk3576_esmart[] = {
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_ABGR2101010,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_ABGR1555,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_XBGR1555,
+	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
+	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
+	DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */
+	DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
+	DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */
+	DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */
+};
+
 static const uint32_t formats_smart[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -169,6 +235,48 @@ static const uint64_t format_modifiers_afbc[] = {
 	DRM_FORMAT_MOD_INVALID,
 };
 
+/* used from rk3576, afbc 32*8 half mode */
+static const uint64_t format_modifiers_rk3576_afbc[] = {
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_CBR |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+
+	/* SPLIT mandates SPARSE, RGB modes mandates YTR */
+	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+				AFBC_FORMAT_MOD_YTR |
+				AFBC_FORMAT_MOD_SPARSE |
+				AFBC_FORMAT_MOD_SPLIT),
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID,
+};
+
 static const struct reg_field rk3568_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
 	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
@@ -301,6 +409,146 @@ static const struct reg_field rk3568_vop_smart_regs[VOP2_WIN_MAX_REG] = {
 	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
 };
 
+static const struct reg_field rk3576_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 17, 17),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 4),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 9),
+	/* Read only bit on rk3576, writing on this bit have no effect.*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
+
+	[VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_CLUSTER_PORT_SEL_IMD, 0, 1),
+	[VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_CLUSTER_DLY_NUM, 0, 7),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 22, 23),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
+
+	/* cluster regs */
+	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
+	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
+	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
+
+	/* afbc regs */
+	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
+	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
+	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
+	[VOP2_WIN_AFBC_PLD_OFFSET_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 16, 16),
+	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
+	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
+	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
+	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_PLD_OFFSET] = REG_FIELD(RK3576_CLUSTER_WIN_AFBCD_PLD_PTR_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
+	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
+	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
+	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
+	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
+	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
+	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
+};
+
+static const struct reg_field rk3576_vop_smart_regs[VOP2_WIN_MAX_REG] = {
+	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
+	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
+	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
+	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
+	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
+	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
+	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
+	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
+	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
+	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
+	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
+	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
+	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
+	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
+	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
+	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
+	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
+	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
+	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_SMART_PORT_SEL_IMD, 0, 1),
+	[VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_SMART_DLY_NUM, 0, 7),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
+
+	/* Scale */
+	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
+	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
+	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
+	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
+	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
+	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
+	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
+	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
+	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
+	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
+	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
+	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
+
+	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff }, /* CBCR share the same scale factor as YRGB */
+	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff},
+	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff},
+	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff},
+
+	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
+	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
+	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
+};
+
 static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
 	{
 		.id = 0,
@@ -355,98 +603,385 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
 		.layer_sel_id = { 3, 3, 3, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
-		.max_upscale_factor = 8,
-		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Smart1-win0",
+		.phys_id = ROCKCHIP_VOP2_SMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_smart,
+		.nformats = ARRAY_SIZE(formats_smart),
+		.format_modifiers = format_modifiers,
+		.base = 0x1e00,
+		.layer_sel_id = { 7, 7, 7, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Esmart1-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART1,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_rk356x_esmart,
+		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
+		.format_modifiers = format_modifiers,
+		.base = 0x1a00,
+		.layer_sel_id = { 6, 6, 6, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Esmart0-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_rk356x_esmart,
+		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
+		.format_modifiers = format_modifiers,
+		.base = 0x1800,
+		.layer_sel_id = { 2, 2, 2, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
+		.dly = { 20, 47, 41 },
+	}, {
+		.name = "Cluster0-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
+		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_cluster,
+		.nformats = ARRAY_SIZE(formats_cluster),
+		.format_modifiers = format_modifiers_afbc,
+		.layer_sel_id = { 0, 0, 0, 0xf },
+		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
+					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.dly = { 0, 27, 21 },
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+	}, {
+		.name = "Cluster1-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
+		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
+		.formats = formats_cluster,
+		.nformats = ARRAY_SIZE(formats_cluster),
+		.format_modifiers = format_modifiers_afbc,
+		.layer_sel_id = { 1, 1, 1, 0xf },
+		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
+					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.dly = { 0, 27, 21 },
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+	},
+};
+
+static const struct vop2_regs_dump rk3568_regs_dump[] = {
+	{
+		.name = "SYS",
+		.base = RK3568_REG_CFG_DONE,
+		.size = 0x100,
+		.en_reg  = 0,
+		.en_val = 0,
+		.en_mask = 0
+	}, {
+		.name = "OVL",
+		.base = RK3568_OVL_CTRL,
+		.size = 0x100,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "VP0",
+		.base = RK3568_VP0_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP1",
+		.base = RK3568_VP1_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+	}, {
+		.name = "VP2",
+		.base = RK3568_VP2_CTRL_BASE,
+		.size = 0x100,
+		.en_reg = RK3568_VP_DSP_CTRL,
+		.en_val = 0,
+		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
+
+	}, {
+		.name = "Cluster0",
+		.base = RK3568_CLUSTER0_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Cluster1",
+		.base = RK3568_CLUSTER1_CTRL_BASE,
+		.size = 0x110,
+		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
+		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
+	}, {
+		.name = "Esmart0",
+		.base = RK3568_ESMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Esmart1",
+		.base = RK3568_ESMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart0",
+		.base = RK3568_SMART0_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	}, {
+		.name = "Smart1",
+		.base = RK3568_SMART1_CTRL_BASE,
+		.size = 0xf0,
+		.en_reg = RK3568_SMART_REGION0_CTRL,
+		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
+	},
+};
+
+static const struct vop2_video_port_data rk3576_vop_video_ports[] = {
+	{
+		.id = 0,
+		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
+		.gamma_lut_len = 1024,
+		.cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
+		.max_output = { 4096, 2304 },
+		/* win layer_mix hdr  */
+		.pre_scan_max_dly = { 10, 8, 2, 0 },
+		.offset = 0xc00,
+		.pixel_rate = 2,
+	}, {
+		.id = 1,
+		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
+		.gamma_lut_len = 1024,
+		.cubic_lut_len = 729, /* 9x9x9 */
+		.max_output = { 2560, 1600 },
+		/* win layer_mix hdr  */
+		.pre_scan_max_dly = { 10, 6, 0, 0 },
+		.offset = 0xd00,
+		.pixel_rate = 1,
+	}, {
+		.id = 2,
+		.gamma_lut_len = 1024,
+		.max_output = { 1920, 1080 },
+		/* win layer_mix hdr  */
+		.pre_scan_max_dly = { 10, 6, 0, 0 },
+		.offset = 0xe00,
+		.pixel_rate = 1,
+	},
+};
+
+/*
+ * rk3576 vop with 2 cluster, 4 esmart win.
+ * Every cluster can work as 4K win or split into two 2K win.
+ * All win in cluster support AFBCD.
+ *
+ * Every esmart win support 4 Multi-region.
+ *
+ * VP0 can use Cluster0/1 and Esmart0/2
+ * VP1 can use Cluster0/1 and Esmart1/3
+ * VP2 can use Esmart0/1/2/3
+ *
+ * Scale filter mode:
+ *
+ * * Cluster:
+ * * Support prescale down:
+ * * H/V: gt2/avg2 or gt4/avg4
+ * * After prescale down:
+ *	* nearest-neighbor/bilinear/multi-phase filter for scale up
+ *	* nearest-neighbor/bilinear/multi-phase filter for scale down
+ *
+ * * Esmart:
+ * * Support prescale down:
+ * * H: gt2/avg2 or gt4/avg4
+ * * V: gt2 or gt4
+ * * After prescale down:
+ *	* nearest-neighbor/bilinear/bicubic for scale up
+ *	* nearest-neighbor/bilinear for scale down
+ *
+ * AXI config::
+ *
+ * * Cluster0 win0: 0xa,  0xb       [AXI0]
+ * * Cluster0 win1: 0xc,  0xd       [AXI0]
+ * * Cluster1 win0: 0x6,  0x7       [AXI0]
+ * * Cluster1 win1: 0x8,  0x9       [AXI0]
+ * * Esmart0:       0x10, 0x11      [AXI0]
+ * * Esmart1:       0x12, 0x13      [AXI0]
+ * * Esmart2:       0xa,  0xb       [AXI1]
+ * * Esmart3:       0xc,  0xd       [AXI1]
+ * * Lut dma rid:   0x1,  0x2,  0x3 [AXI0]
+ * * DCI dma rid:   0x4             [AXI0]
+ * * Metadata rid:  0x5             [AXI0]
+ *
+ * * Limit:
+ * * (1) Cluster0/1 are fixed on AXI0 by IC design
+ * * (2) 0x0 and 0xf can't be used;
+ * * (3) 5 Bits ID for eache axi bus
+ * * (3) cluster and lut/dci/metadata rid must smaller than 0xf,
+ * *     if Cluster rid is bigger than 0xf, VOP will dead at the
+ * *     system bandwidth very terrible scene.
+ */
+static const struct vop2_win_data rk3576_vop_win_data[] = {
+	{
+		.name = "Cluster0-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
+		.base = 0x1000,
+		.possible_vp_mask = BIT(0) | BIT(1),
+		.formats = formats_rk3576_cluster,
+		.nformats = ARRAY_SIZE(formats_rk3576_cluster),
+		.format_modifiers = format_modifiers_rk3576_afbc,
+		.layer_sel_id = { 0, 0, 0xf, 0xf },
+		.supported_rotations =  DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0xa,
+		.axi_uv_r_id = 0xb,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
 	}, {
-		.name = "Smart1-win0",
-		.phys_id = ROCKCHIP_VOP2_SMART1,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_smart,
-		.nformats = ARRAY_SIZE(formats_smart),
+		.name = "Cluster1-win0",
+		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
+		.base = 0x1200,
+		.possible_vp_mask = BIT(0) | BIT(1),
+		.formats = formats_rk3576_cluster,
+		.nformats = ARRAY_SIZE(formats_rk3576_cluster),
+		.format_modifiers = format_modifiers_rk3576_afbc,
+		.layer_sel_id = { 1, 1, 0xf, 0xf },
+		.supported_rotations =  DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
+		.max_upscale_factor = 4,
+		.max_downscale_factor = 4,
+		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+	}, {
+		.name = "Esmart0-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART0,
+		.base = 0x1800,
+		.possible_vp_mask = BIT(0) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
 		.format_modifiers = format_modifiers,
-		.base = 0x1e00,
-		.layer_sel_id = { 7, 7, 7, 0xf },
+		.layer_sel_id = { 2, 0xf, 0, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
-		.type = DRM_PLANE_TYPE_PRIMARY,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x10,
+		.axi_uv_r_id = 0x11,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
 	}, {
 		.name = "Esmart1-win0",
 		.phys_id = ROCKCHIP_VOP2_ESMART1,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_rk356x_esmart,
-		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
-		.format_modifiers = format_modifiers,
 		.base = 0x1a00,
-		.layer_sel_id = { 6, 6, 6, 0xf },
+		.possible_vp_mask = BIT(1) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
+		.format_modifiers = format_modifiers,
+		.layer_sel_id = { 0xf, 2, 1, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
-		.type = DRM_PLANE_TYPE_PRIMARY,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x12,
+		.axi_uv_r_id = 0x13,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
 	}, {
-		.name = "Esmart0-win0",
-		.phys_id = ROCKCHIP_VOP2_ESMART0,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_rk356x_esmart,
-		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
+		.name = "Esmart2-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART2,
+		.base = 0x1c00,
+		.possible_vp_mask = BIT(0) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
 		.format_modifiers = format_modifiers,
-		.base = 0x1800,
-		.layer_sel_id = { 2, 2, 2, 0xf },
+		.layer_sel_id = { 3, 0xf, 2, 0xf },
 		.supported_rotations = DRM_MODE_REFLECT_Y,
-		.type = DRM_PLANE_TYPE_PRIMARY,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
-		.dly = { 20, 47, 41 },
-	}, {
-		.name = "Cluster0-win0",
-		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
-		.base = 0x1000,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_cluster,
-		.nformats = ARRAY_SIZE(formats_cluster),
-		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = { 0, 0, 0, 0xf },
-		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
-					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
-		.max_upscale_factor = 4,
-		.max_downscale_factor = 4,
-		.dly = { 0, 27, 21 },
-		.type = DRM_PLANE_TYPE_OVERLAY,
-		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
 	}, {
-		.name = "Cluster1-win0",
-		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
-		.base = 0x1200,
-		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
-		.formats = formats_cluster,
-		.nformats = ARRAY_SIZE(formats_cluster),
-		.format_modifiers = format_modifiers_afbc,
-		.layer_sel_id = { 1, 1, 1, 0xf },
-		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
-					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.name = "Esmart3-win0",
+		.phys_id = ROCKCHIP_VOP2_ESMART3,
+		.base = 0x1e00,
+		.possible_vp_mask = BIT(1) | BIT(2),
+		.formats = formats_rk3576_esmart,
+		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
+		.format_modifiers = format_modifiers,
+		.layer_sel_id = { 0xf, 3, 3, 0xf },
+		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
-		.max_upscale_factor = 4,
-		.max_downscale_factor = 4,
-		.dly = { 0, 27, 21 },
-		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x0d,
+		.max_upscale_factor = 8,
+		.max_downscale_factor = 8,
 	},
 };
 
-static const struct vop2_regs_dump rk3568_regs_dump[] = {
+static const struct vop2_regs_dump rk3576_regs_dump[] = {
 	{
 		.name = "SYS",
 		.base = RK3568_REG_CFG_DONE,
-		.size = 0x100,
+		.size = 0x200,
 		.en_reg  = 0,
 		.en_val = 0,
 		.en_mask = 0
 	}, {
-		.name = "OVL",
-		.base = RK3568_OVL_CTRL,
-		.size = 0x100,
+		.name = "OVL_SYS",
+		.base = RK3576_SYS_EXTRA_ALPHA_CTRL,
+		.size = 0x50,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "OVL_VP0",
+		.base = RK3576_OVL_CTRL(0),
+		.size = 0x80,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "OVL_VP1",
+		.base = RK3576_OVL_CTRL(1),
+		.size = 0x80,
+		.en_reg = 0,
+		.en_val = 0,
+		.en_mask = 0,
+	}, {
+		.name = "OVL_VP2",
+		.base = RK3576_OVL_CTRL(2),
+		.size = 0x80,
 		.en_reg = 0,
 		.en_val = 0,
 		.en_mask = 0,
@@ -471,18 +1006,17 @@ static const struct vop2_regs_dump rk3568_regs_dump[] = {
 		.en_reg = RK3568_VP_DSP_CTRL,
 		.en_val = 0,
 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
-
 	}, {
 		.name = "Cluster0",
 		.base = RK3568_CLUSTER0_CTRL_BASE,
-		.size = 0x110,
+		.size = 0x200,
 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
 	}, {
 		.name = "Cluster1",
 		.base = RK3568_CLUSTER1_CTRL_BASE,
-		.size = 0x110,
+		.size = 0x200,
 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
@@ -501,15 +1035,15 @@ static const struct vop2_regs_dump rk3568_regs_dump[] = {
 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 	}, {
-		.name = "Smart0",
-		.base = RK3568_SMART0_CTRL_BASE,
+		.name = "Esmart2",
+		.base = RK3588_ESMART2_CTRL_BASE,
 		.size = 0xf0,
 		.en_reg = RK3568_SMART_REGION0_CTRL,
 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
 	}, {
-		.name = "Smart1",
-		.base = RK3568_SMART1_CTRL_BASE,
+		.name = "Esmart3",
+		.base = RK3588_ESMART3_CTRL_BASE,
 		.size = 0xf0,
 		.en_reg = RK3568_SMART_REGION0_CTRL,
 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
@@ -908,6 +1442,84 @@ static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32
 	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
 }
 
+static unsigned long rk3576_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
+	u8 port_pix_rate = vp->data->pixel_rate;
+	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_sel;
+	u32 ctrl, vp_clk_div, reg, dclk_div;
+	unsigned long dclk_in_rate, dclk_core_rate;
+
+	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420 || adjusted_mode->crtc_clock > 600000)
+		dclk_div = 2;
+	else
+		dclk_div = 1;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
+		dclk_core_rate = adjusted_mode->crtc_clock / 2;
+	else
+		dclk_core_rate = adjusted_mode->crtc_clock / port_pix_rate;
+
+	dclk_in_rate = adjusted_mode->crtc_clock / dclk_div;
+
+	dclk_core_div = dclk_in_rate > dclk_core_rate ? 1 : 0;
+
+	if (vop2_output_if_is_edp(id))
+		if_pixclk_div = port_pix_rate == 2 ? RK3576_DSP_IF_PCLK_DIV : 0;
+	else
+		if_pixclk_div = port_pix_rate == 1 ? RK3576_DSP_IF_PCLK_DIV : 0;
+
+	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420) {
+		if_dclk_sel = RK3576_DSP_IF_DCLK_SEL_OUT;
+		dclk_out_div = 1;
+	} else {
+		if_dclk_sel = 0;
+		dclk_out_div = 0;
+	}
+
+	switch (id) {
+	case ROCKCHIP_VOP2_EP_HDMI0:
+		reg = RK3576_HDMI0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_EDP0:
+		reg = RK3576_EDP0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_MIPI0:
+		reg = RK3576_MIPI0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_DP0:
+		reg = RK3576_DP0_IF_CTRL;
+		break;
+	case ROCKCHIP_VOP2_EP_DP1:
+		reg = RK3576_DP1_IF_CTRL;
+		break;
+	default:
+		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
+		return 0;
+	}
+
+	ctrl = vop2_readl(vop2, reg);
+	ctrl &= ~RK3576_DSP_IF_DCLK_SEL_OUT;
+	ctrl &= ~RK3576_DSP_IF_PCLK_DIV;
+	ctrl &= ~RK3576_DSP_IF_MUX;
+	ctrl |= RK3576_DSP_IF_CFG_DONE_IMD;
+	ctrl |= if_dclk_sel | if_pixclk_div;
+	ctrl |= RK3576_DSP_IF_CLK_OUT_EN | RK3576_DSP_IF_EN;
+	ctrl |= FIELD_PREP(RK3576_DSP_IF_MUX, vp->id);
+	ctrl |= FIELD_PREP(RK3576_DSP_IF_PIN_POL, polflags);
+	vop2_writel(vop2, reg, ctrl);
+
+	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
+	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
+
+	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
+
+	return dclk_in_rate * 1000LL;
+}
+
 /*
  * calc the dclk on rk3588
  * the available div of dclk is 1, 2, 4
@@ -1246,6 +1858,7 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi
 	struct drm_plane_state *bottom_win_pstate;
 	bool src_pixel_alpha_en = false;
 	u16 src_glb_alpha_val, dst_glb_alpha_val;
+	u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg;
 	u32 offset = 0;
 	bool premulti_en = false;
 	bool swap = false;
@@ -1283,14 +1896,22 @@ static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_wi
 		break;
 	}
 
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
-		    alpha.src_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
-		    alpha.dst_color_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
-		    alpha.src_alpha_ctrl.val);
-	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
-		    alpha.dst_alpha_ctrl.val);
+	if (vop2->version <= VOP_VERSION_RK3588) {
+		src_color_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL;
+		dst_color_ctrl_reg = RK3568_CLUSTER0_MIX_DST_COLOR_CTRL;
+		src_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL;
+		dst_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL;
+	} else {
+		src_color_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_COLOR_CTRL;
+		dst_color_ctrl_reg = RK3576_CLUSTER0_MIX_DST_COLOR_CTRL;
+		src_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_ALPHA_CTRL;
+		dst_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_DST_ALPHA_CTRL;
+	}
+
+	vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val);
+	vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val);
+	vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val);
+	vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val);
 }
 
 static void vop2_setup_alpha(struct vop2_video_port *vp)
@@ -1303,11 +1924,16 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 	int pixel_alpha_en;
 	int premulti_en, gpremulti_en = 0;
 	int mixer_id;
+	u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg;
 	u32 offset;
 	bool bottom_layer_alpha_en = false;
 	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
 
-	mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	if (vop2->version <= VOP_VERSION_RK3588)
+		mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+	else
+		mixer_id = 0;
+
 	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
 
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
@@ -1326,6 +1952,18 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 		}
 	}
 
+	if (vop2->version <= VOP_VERSION_RK3588) {
+		src_color_ctrl_reg = RK3568_MIX0_SRC_COLOR_CTRL;
+		dst_color_ctrl_reg = RK3568_MIX0_DST_COLOR_CTRL;
+		src_alpha_ctrl_reg = RK3568_MIX0_SRC_ALPHA_CTRL;
+		dst_alpha_ctrl_reg = RK3568_MIX0_DST_ALPHA_CTRL;
+	} else {
+		src_color_ctrl_reg = RK3576_OVL_MIX0_SRC_COLOR_CTRL(vp->id);
+		dst_color_ctrl_reg = RK3576_OVL_MIX0_DST_COLOR_CTRL(vp->id);
+		src_alpha_ctrl_reg = RK3576_OVL_MIX0_SRC_ALPHA_CTRL(vp->id);
+		dst_alpha_ctrl_reg = RK3576_OVL_MIX0_DST_ALPHA_CTRL(vp->id);
+	}
+
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
 		struct vop2_win *win = to_vop2_win(plane);
 		int zpos = plane->state->normalized_zpos;
@@ -1372,17 +2010,26 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 		vop2_parse_alpha(&alpha_config, &alpha);
 
 		offset = (mixer_id + zpos - 1) * 0x10;
-		vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
-			    alpha.src_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
-			    alpha.dst_color_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
-			    alpha.src_alpha_ctrl.val);
-		vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
-			    alpha.dst_alpha_ctrl.val);
+
+		vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val);
+		vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val);
+		vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val);
+		vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val);
 	}
 
 	if (vp->id == 0) {
+		if (vop2->version <= VOP_VERSION_RK3588) {
+			src_color_ctrl_reg = RK3568_HDR0_SRC_COLOR_CTRL;
+			dst_color_ctrl_reg = RK3568_HDR0_DST_COLOR_CTRL;
+			src_alpha_ctrl_reg = RK3568_HDR0_SRC_ALPHA_CTRL;
+			dst_alpha_ctrl_reg = RK3568_HDR0_DST_ALPHA_CTRL;
+		} else {
+			src_color_ctrl_reg = RK3576_OVL_HDR_SRC_COLOR_CTRL(vp->id);
+			dst_color_ctrl_reg = RK3576_OVL_HDR_DST_COLOR_CTRL(vp->id);
+			src_alpha_ctrl_reg = RK3576_OVL_HDR_SRC_ALPHA_CTRL(vp->id);
+			dst_alpha_ctrl_reg = RK3576_OVL_HDR_DST_ALPHA_CTRL(vp->id);
+		}
+
 		if (bottom_layer_alpha_en) {
 			/* Transfer pixel alpha to hdr mix */
 			alpha_config.src_premulti_en = gpremulti_en;
@@ -1390,18 +2037,15 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 			alpha_config.src_pixel_alpha_en = true;
 			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
 			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
+
 			vop2_parse_alpha(&alpha_config, &alpha);
 
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
-				    alpha.src_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
-				    alpha.dst_color_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
-				    alpha.src_alpha_ctrl.val);
-			vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
-				    alpha.dst_alpha_ctrl.val);
+			vop2_writel(vop2, src_color_ctrl_reg, alpha.src_color_ctrl.val);
+			vop2_writel(vop2, dst_color_ctrl_reg, alpha.dst_color_ctrl.val);
+			vop2_writel(vop2, src_alpha_ctrl_reg, alpha.src_alpha_ctrl.val);
+			vop2_writel(vop2, dst_alpha_ctrl_reg, alpha.dst_alpha_ctrl.val);
 		} else {
-			vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
+			vop2_writel(vop2, src_color_ctrl_reg, 0);
 		}
 	}
 }
@@ -1611,6 +2255,72 @@ static void rk3568_vop2_setup_overlay(struct vop2_video_port *vp)
 	rk3568_vop2_setup_dly_for_windows(vp);
 }
 
+static void rk3576_vop2_setup_layer_mixer(struct vop2_video_port *vp)
+{
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_plane *plane;
+	u32 layer_sel = 0xffff; /* 0xf means this layer is disabled */
+	u32 ovl_ctrl;
+
+	ovl_ctrl = vop2_readl(vop2, RK3576_OVL_CTRL(vp->id));
+	if (vcstate->yuv_overlay)
+		ovl_ctrl |= RK3576_OVL_CTRL__YUV_MODE;
+	else
+		ovl_ctrl &= ~RK3576_OVL_CTRL__YUV_MODE;
+
+	vop2_writel(vop2, RK3576_OVL_CTRL(vp->id), ovl_ctrl);
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos,
+							  0xf);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos,
+							 win->data->layer_sel_id[vp->id]);
+	}
+
+	vop2_writel(vop2, RK3576_OVL_LAYER_SEL(vp->id), layer_sel);
+}
+
+static void rk3576_vop2_setup_dly_for_windows(struct vop2_video_port *vp)
+{
+	struct drm_plane *plane;
+	struct vop2_win *win;
+
+	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
+		win = to_vop2_win(plane);
+		vop2_win_write(win, VOP2_WIN_DLY_NUM, 0);
+	}
+}
+
+static void rk3576_vop2_setup_overlay(struct vop2_video_port *vp)
+{
+	struct vop2 *vop2 = vp->vop2;
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_plane *plane;
+
+	vp->win_mask = 0;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		struct vop2_win *win = to_vop2_win(plane);
+
+		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
+
+		vp->win_mask |= BIT(win->data->phys_id);
+
+		if (vop2_cluster_window(win))
+			vop2_setup_cluster_alpha(vop2, win);
+	}
+
+	if (!vp->win_mask)
+		return;
+
+	rk3576_vop2_setup_layer_mixer(vp);
+	vop2_setup_alpha(vp);
+	rk3576_vop2_setup_dly_for_windows(vp);
+}
+
 static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
 {
 	struct drm_crtc *crtc = &vp->crtc;
@@ -1628,12 +2338,38 @@ static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
 	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
 }
 
+static void rk3576_vop2_setup_bg_dly(struct vop2_video_port *vp)
+{
+	struct drm_crtc *crtc = &vp->crtc;
+	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	u16 hdisplay = mode->crtc_hdisplay;
+	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+	u32 bg_dly;
+	u32 pre_scan_dly;
+
+	bg_dly = vp->data->pre_scan_max_dly[VOP2_DLY_WIN] +
+		 vp->data->pre_scan_max_dly[VOP2_DLY_LAYER_MIX] +
+		 vp->data->pre_scan_max_dly[VOP2_DLY_HDR_MIX];
+
+	vop2_writel(vp->vop2, RK3576_OVL_BG_MIX_CTRL(vp->id),
+		    FIELD_PREP(RK3576_OVL_BG_MIX_CTRL__BG_DLY, bg_dly));
+
+	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
+	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
+}
+
 static const struct vop2_ops rk3568_vop_ops = {
 	.setup_intf_mux = rk3568_set_intf_mux,
 	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
 	.setup_overlay = rk3568_vop2_setup_overlay,
 };
 
+static const struct vop2_ops rk3576_vop_ops = {
+	.setup_intf_mux = rk3576_set_intf_mux,
+	.setup_bg_dly = rk3576_vop2_setup_bg_dly,
+	.setup_overlay = rk3576_vop2_setup_overlay,
+};
+
 static const struct vop2_ops rk3588_vop_ops = {
 	.setup_intf_mux = rk3588_set_intf_mux,
 	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
@@ -1678,6 +2414,25 @@ static const struct vop2_data rk3568_vop = {
 	.soc_id = 3568,
 };
 
+static const struct vop2_data rk3576_vop = {
+	.version = VOP_VERSION_RK3576,
+	.feature = VOP2_FEATURE_HAS_SYS_PMU,
+	.nr_vps = 3,
+	.max_input = { 4096, 4320 },
+	.max_output = { 4096, 4320 },
+	.vp = rk3576_vop_video_ports,
+	.win = rk3576_vop_win_data,
+	.win_size = ARRAY_SIZE(rk3576_vop_win_data),
+	.cluster_reg = rk3576_vop_cluster_regs,
+	.nr_cluster_regs = ARRAY_SIZE(rk3576_vop_cluster_regs),
+	.smart_reg = rk3576_vop_smart_regs,
+	.nr_smart_regs = ARRAY_SIZE(rk3576_vop_smart_regs),
+	.regs_dump = rk3576_regs_dump,
+	.regs_dump_size = ARRAY_SIZE(rk3576_regs_dump),
+	.ops = &rk3576_vop_ops,
+	.soc_id = 3576,
+};
+
 static const struct vop2_data rk3588_vop = {
 	.version = VOP_VERSION_RK3588,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
@@ -1705,6 +2460,9 @@ static const struct of_device_id vop2_dt_match[] = {
 	}, {
 		.compatible = "rockchip,rk3568-vop",
 		.data = &rk3568_vop,
+	}, {
+		.compatible = "rockchip,rk3576-vop",
+		.data = &rk3576_vop,
 	}, {
 		.compatible = "rockchip,rk3588-vop",
 		.data = &rk3588_vop
-- 
2.34.1



From andyshrk at 163.com  Wed Dec 18 23:39:12 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:12 +0800
Subject: [PATCH v7 4/9] drm/rockchip: vop2: Introduce vop hardware version
In-Reply-To: <20241219073931.3997788-1-andyshrk@163.com>
References: <20241219073931.3997788-1-andyshrk@163.com>
Message-ID: <20241219073931.3997788-5-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

There is a version number hardcoded in the VOP VERSION_INFO
register, and the version number increments sequentially based
on the production order of the SOC.

So using this version number to distinguish different VOP features
will simplify the code.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>

---

(no changes since v6)

Changes in v6:
- Add a blank line after hardware version check code

Changes in v3:
- Add comments for why we should treat rk3566 with special care.
- Add hardware version check

Changes in v2:
- Introduce vop hardware version

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 26 ++++++++++++++------
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 11 +++++++++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c |  3 +++
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index fded1e931c9a..c87c98a8fb3a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -354,7 +354,7 @@ static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode)
 
 static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format)
 {
-	if (vop2->data->soc_id == 3588) {
+	if (vop2->version == VOP_VERSION_RK3588) {
 		if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
 		    bus_format == MEDIA_BUS_FMT_YUV10_1X30)
 			return true;
@@ -407,7 +407,7 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
 	if (modifier == DRM_FORMAT_MOD_INVALID)
 		return false;
 
-	if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
+	if (vop2->version == VOP_VERSION_RK3568) {
 		if (vop2_cluster_window(win)) {
 			if (modifier == DRM_FORMAT_MOD_LINEAR) {
 				drm_dbg_kms(vop2->drm,
@@ -418,7 +418,7 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
 	}
 
 	if (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010) {
-		if (vop2->data->soc_id == 3588) {
+		if (vop2->version == VOP_VERSION_RK3588) {
 			if (!rockchip_afbc(plane, modifier)) {
 				drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n");
 				return false;
@@ -817,6 +817,7 @@ static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
 static void vop2_enable(struct vop2 *vop2)
 {
 	int ret;
+	u32 version;
 
 	ret = pm_runtime_resume_and_get(vop2->dev);
 	if (ret < 0) {
@@ -836,10 +837,20 @@ static void vop2_enable(struct vop2 *vop2)
 		return;
 	}
 
+	version = vop2_readl(vop2, RK3568_VERSION_INFO);
+	if (version != vop2->version) {
+		drm_err(vop2->drm, "Hardware version(0x%08x) mismatch\n", version);
+		return;
+	}
+
+	/*
+	 * rk3566 share the same vop version with rk3568, so
+	 * wen need to use soc_id for identification here.
+	 */
 	if (vop2->data->soc_id == 3566)
 		vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
 
-	if (vop2->data->soc_id == 3588)
+	if (vop2->version == VOP_VERSION_RK3588)
 		rk3588_vop2_power_domain_enable_all(vop2);
 
 	vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
@@ -920,7 +931,7 @@ static void vop2_vp_dsp_lut_update_enable(struct vop2_video_port *vp)
 
 static inline bool vop2_supports_seamless_gamma_lut_update(struct vop2 *vop2)
 {
-	return (vop2->data->soc_id != 3566 && vop2->data->soc_id != 3568);
+	return vop2->version != VOP_VERSION_RK3568;
 }
 
 static bool vop2_gamma_lut_in_use(struct vop2 *vop2, struct vop2_video_port *vp)
@@ -1259,7 +1270,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		&fb->format->format,
 		afbc_en ? "AFBC" : "", &yrgb_mst);
 
-	if (vop2->data->soc_id > 3568) {
+	if (vop2->version > VOP_VERSION_RK3568) {
 		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
 		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
 		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
@@ -1319,7 +1330,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		 * this bit is gating disable, we should write 1 to
 		 * disable gating when enable afbc.
 		 */
-		if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568)
+		if (vop2->version == VOP_VERSION_RK3568)
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0);
 		else
 			vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1);
@@ -2523,6 +2534,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 	vop2->dev = dev;
 	vop2->data = vop2_data;
 	vop2->ops = vop2_data->ops;
+	vop2->version = vop2_data->version;
 	vop2->drm = drm;
 
 	dev_set_drvdata(dev, vop2);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index af3cd92e6815..21464d107bd3 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -13,6 +13,15 @@
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
+#define VOP2_VERSION(major, minor, build)	((major) << 24 | (minor) << 16 | (build))
+
+/* The new SOC VOP version is bigger than the old */
+#define VOP_VERSION_RK3568	VOP2_VERSION(0x40, 0x15, 0x8023)
+#define VOP_VERSION_RK3588	VOP2_VERSION(0x40, 0x17, 0x6786)
+#define VOP_VERSION_RK3528	VOP2_VERSION(0x50, 0x17, 0x1263)
+#define VOP_VERSION_RK3562	VOP2_VERSION(0x50, 0x17, 0x4350)
+#define VOP_VERSION_RK3576	VOP2_VERSION(0x50, 0x19, 0x9765)
+
 #define VOP2_VP_FEATURE_OUTPUT_10BIT        BIT(0)
 
 #define VOP2_FEATURE_HAS_SYS_GRF	BIT(0)
@@ -242,6 +251,7 @@ struct vop2_ops {
 struct vop2_data {
 	u8 nr_vps;
 	u64 feature;
+	u32 version;
 	const struct vop2_ops *ops;
 	const struct vop2_win_data *win;
 	const struct vop2_video_port_data *vp;
@@ -259,6 +269,7 @@ struct vop2_data {
 };
 
 struct vop2 {
+	u32 version;
 	struct device *dev;
 	struct drm_device *drm;
 	struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 747e3628ae96..48629353929d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -1627,6 +1627,7 @@ static const struct vop2_ops rk3588_vop_ops = {
 };
 
 static const struct vop2_data rk3566_vop = {
+	.version = VOP_VERSION_RK3568,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
 	.max_input = { 4096, 2304 },
@@ -1645,6 +1646,7 @@ static const struct vop2_data rk3566_vop = {
 };
 
 static const struct vop2_data rk3568_vop = {
+	.version = VOP_VERSION_RK3568,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
 	.nr_vps = 3,
 	.max_input = { 4096, 2304 },
@@ -1663,6 +1665,7 @@ static const struct vop2_data rk3568_vop = {
 };
 
 static const struct vop2_data rk3588_vop = {
+	.version = VOP_VERSION_RK3588,
 	.feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
 		   VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU,
 	.nr_vps = 4,
-- 
2.34.1



From andyshrk at 163.com  Wed Dec 18 23:39:15 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:15 +0800
Subject: [PATCH v7 7/9] drm/rockchip: vop2: Add uv swap for cluster window
In-Reply-To: <20241219073931.3997788-1-andyshrk@163.com>
References: <20241219073931.3997788-1-andyshrk@163.com>
Message-ID: <20241219073931.3997788-8-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The Cluster windows of upcoming VOP on rk3576 also support
linear YUV support, we need to set uv swap bit for it.

As the VOP2_WIN_UV_SWA register defined on rk3568/rk3588 is
0xffffffff, so this register will not be touched on these
two platforms.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Tested-by: Michael Riesch <michael.riesch at wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova at collabora.com>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0b79f2006836..0ddfafa3c208 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1373,10 +1373,8 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 
 	rb_swap = vop2_win_rb_swap(fb->format->format);
 	vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap);
-	if (!vop2_cluster_window(win)) {
-		uv_swap = vop2_win_uv_swap(fb->format->format);
-		vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap);
-	}
+	uv_swap = vop2_win_uv_swap(fb->format->format);
+	vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap);
 
 	if (fb->format->is_yuv) {
 		vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4));
-- 
2.34.1



From andyshrk at 163.com  Wed Dec 18 23:39:16 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu, 19 Dec 2024 15:39:16 +0800
Subject: [PATCH v7 8/9] dt-bindings: display: vop2: Add rk3576 support
In-Reply-To: <20241219073931.3997788-1-andyshrk@163.com>
References: <20241219073931.3997788-1-andyshrk@163.com>
Message-ID: <20241219073931.3997788-9-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Add vop found on rk3576, the main difference between rk3576 and the
previous vop is that each VP has its own interrupt line.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>

---

(no changes since v3)

Changes in v3:
- ordered by soc name
- Add description for newly added interrupt

Changes in v2:
- Add dt bindings

 .../bindings/display/rockchip/rockchip-vop2.yaml    | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
index 2531726af306..a44964b6c36a 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -20,6 +20,7 @@ properties:
     enum:
       - rockchip,rk3566-vop
       - rockchip,rk3568-vop
+      - rockchip,rk3576-vop
       - rockchip,rk3588-vop
 
   reg:
@@ -37,10 +38,14 @@ properties:
       - const: gamma-lut
 
   interrupts:
-    maxItems: 1
-    description:
-      The VOP interrupt is shared by several interrupt sources, such as
-      frame start (VSYNC), line flag and other status interrupts.
+    minItems: 1
+    items:
+      - description:
+          vop system interrupt, such as bus error, and vsync for vop version under
+          rk3576.
+      - description:
+          independent interrupts for each video port, such as vsync and other video
+          port related error interrupts.
 
   # See compatible-specific constraints below.
   clocks:
-- 
2.34.1



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:30 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:30 +0100
Subject: [PATCH 06/10] arm64: dts: imx8mp-skov: describe LVDS display
 pipeline
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-6-38bf80dc22df@pengutronix.de>

From: Oleksij Rempel <o.rempel at pengutronix.de>

The Skov i.MX8MP LT6 device tree so far described the touch screen, but
didn't describe the screen itself. Fill out these missing pieces.

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 .../boot/dts/freescale/imx8mp-skov-revb-lt6.dts    | 60 ++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
index ccbd3abedd69..baecf768a2ee 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
@@ -8,6 +8,45 @@ / {
 	model = "SKOV IMX8MP CPU revB - LT6";
 	compatible = "skov,imx8mp-skov-revb-lt6", "fsl,imx8mp";
 
+	lvds-decoder {
+		compatible = "ti,sn65lvds822", "lvds-decoder";
+		power-supply = <&reg_3v3>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				in_lvds1: endpoint {
+					data-mapping = "vesa-24";
+					remote-endpoint = <&ldb_lvds_ch1>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				lvds_decoder_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+		};
+	};
+
+	panel {
+		compatible = "logictechno,lttd800480070-l6wh-rt";
+		backlight = <&backlight>;
+		power-supply = <&reg_tft_vcom>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&lvds_decoder_out>;
+			};
+		};
+	};
+
 	touchscreen {
 		compatible = "resistive-adc-touch";
 		io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>, <&adc_ts 5>;
@@ -78,6 +117,27 @@ channel at 5 {
 	};
 };
 
+&lcdif2 {
+	status = "okay";
+};
+
+&lvds_bridge {
+	assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>,
+				 <&clk IMX8MP_VIDEO_PLL1>;
+	assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
+	/* IMX8MP_VIDEO_PLL1 = IMX8MP_CLK_MEDIA_DISP2_PIX * 2 * 7 */
+	assigned-clock-rates = <0>, <462000000>;
+	status = "okay";
+
+	ports {
+		port at 2 {
+			ldb_lvds_ch1: endpoint {
+				remote-endpoint = <&in_lvds1>;
+			};
+		};
+	};
+};
+
 &pwm1 {
 	status = "okay";
 };

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:33 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:33 +0100
Subject: [PATCH 09/10] arm64: dts: imx8mp-skov: fix phy-mode
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-9-38bf80dc22df@pengutronix.de>

From: Oleksij Rempel <o.rempel at pengutronix.de>

Use rgmii-rxid instead of rgmii-txid. It should have no effect here,
but rxid is the correct value in our case.

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
index 80d212acc0c3..a683f46fcbab 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
@@ -215,7 +215,7 @@ adc: adc at 0 {
 &eqos {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_eqos>;
-	phy-mode = "rgmii-txid";
+	phy-mode = "rgmii-rxid";
 	status = "okay";
 
 	fixed-link {

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:28 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:28 +0100
Subject: [PATCH 04/10] arm64: dts: imx8mp-skov: describe HDMI display
 pipeline
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-4-38bf80dc22df@pengutronix.de>

From: Oleksij Rempel <o.rempel at pengutronix.de>

Back when this device tree was first added, there were no i.MX8MP
HDMI bindings upstream yet. This has changed now, so let's use them
to describe the HDMI on the imx8mp-skov-revb-hdmi board.

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 .../boot/dts/freescale/imx8mp-skov-revb-hdmi.dts      | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
index 206116be8166..32a429437cbd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
@@ -9,6 +9,21 @@ / {
 	compatible = "skov,imx8mp-skov-revb-hdmi", "fsl,imx8mp";
 };
 
+&hdmi_pvi {
+	status = "okay";
+};
+
+&hdmi_tx {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hdmi>;
+	ddc-i2c-bus = <&i2c5>;
+	status = "okay";
+};
+
+&hdmi_tx_phy {
+	status = "okay";
+};
+
 &i2c5 {
 	pinctrl-names = "default", "gpio";
 	pinctrl-0 = <&pinctrl_i2c5>;
@@ -19,6 +34,10 @@ &i2c5 {
 	status = "okay";
 };
 
+&lcdif3 {
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl_hdmi: hdmigrp {
 		fsl,pins = <

-- 
2.39.5



From a.fatoum at pengutronix.de  Wed Dec 18 23:25:34 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 08:25:34 +0100
Subject: [PATCH 10/10] arm64: dts: imx8mp-skov: increase I2C clock
 frequency for RTC
In-Reply-To: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
Message-ID: <20241219-skov-dt-updates-v1-10-38bf80dc22df@pengutronix.de>

From: Oleksij Rempel <o.rempel at pengutronix.de>

The NXP PCF85063TP RTC we use is capable of up to 400 kHz of SCL clock
frequency, so let's make use of this instead of the 100 kHz bus frequency
we are currently using.

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
index a683f46fcbab..ec7857db7bf0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
@@ -333,7 +333,7 @@ reg_nvcc_sd2: LDO5 {
 };
 
 &i2c3 {
-	clock-frequency = <100000>;
+	clock-frequency = <400000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c3>;
 	status = "okay";

-- 
2.39.5



From damon.ding at rock-chips.com  Thu Dec 19 00:05:50 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:50 +0800
Subject: [PATCH v3 01/15] drm/rockchip: analogix_dp: Use formalized struct definition for grf field
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-2-damon.ding@rock-chips.com>

The formalized struct definition will makes grf field operations more
concise and easier to extend.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Initialize struct rockchip_dp_chip_data rk3399_edp/rk3288_dp in order
  of its members
---
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 77 +++++++++++--------
 1 file changed, 45 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 546d13f19f9b..05699615b4fc 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -32,26 +32,29 @@
 
 #include "rockchip_drm_drv.h"
 
-#define RK3288_GRF_SOC_CON6		0x25c
-#define RK3288_EDP_LCDC_SEL		BIT(5)
-#define RK3399_GRF_SOC_CON20		0x6250
-#define RK3399_EDP_LCDC_SEL		BIT(5)
-
-#define HIWORD_UPDATE(val, mask)	(val | (mask) << 16)
-
 #define PSR_WAIT_LINE_FLAG_TIMEOUT_MS	100
 
+#define GRF_REG_FIELD(_reg, _lsb, _msb) {	\
+				.reg = _reg,	\
+				.lsb = _lsb,	\
+				.msb = _msb,	\
+				.valid = true,	\
+				}
+
+struct rockchip_grf_reg_field {
+	u32 reg;
+	u32 lsb;
+	u32 msb;
+	bool valid;
+};
+
 /**
  * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
- * @lcdsel_grf_reg: grf register offset of lcdc select
- * @lcdsel_big: reg value of selecting vop big for eDP
- * @lcdsel_lit: reg value of selecting vop little for eDP
+ * @lcdc_sel: grf register field of lcdc_sel
  * @chip_type: specific chip type
  */
 struct rockchip_dp_chip_data {
-	u32	lcdsel_grf_reg;
-	u32	lcdsel_big;
-	u32	lcdsel_lit;
+	const struct rockchip_grf_reg_field lcdc_sel;
 	u32	chip_type;
 };
 
@@ -84,6 +87,26 @@ static struct rockchip_dp_device *pdata_encoder_to_dp(struct analogix_dp_plat_da
 	return container_of(plat_data, struct rockchip_dp_device, plat_data);
 }
 
+static int rockchip_grf_write(struct regmap *grf, u32 reg, u32 mask, u32 val)
+{
+	return regmap_write(grf, reg, (mask << 16) | (val & mask));
+}
+
+static int rockchip_grf_field_write(struct regmap *grf,
+				    const struct rockchip_grf_reg_field *field,
+				    u32 val)
+{
+	u32 mask;
+
+	if (!field->valid)
+		return 0;
+
+	mask = GENMASK(field->msb, field->lsb);
+	val <<= field->lsb;
+
+	return rockchip_grf_write(grf, field->reg, mask, val);
+}
+
 static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
 {
 	reset_control_assert(dp->rst);
@@ -181,7 +204,6 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state;
 	int ret;
-	u32 val;
 
 	crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
 	if (!crtc)
@@ -192,24 +214,19 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
 	if (old_crtc_state && old_crtc_state->self_refresh_active)
 		return;
 
-	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
-	if (ret < 0)
-		return;
-
-	if (ret)
-		val = dp->data->lcdsel_lit;
-	else
-		val = dp->data->lcdsel_big;
-
-	DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
-
 	ret = clk_prepare_enable(dp->grfclk);
 	if (ret < 0) {
 		DRM_DEV_ERROR(dp->dev, "failed to enable grfclk %d\n", ret);
 		return;
 	}
 
-	ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
+	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
+	if (ret < 0)
+		return;
+
+	DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
+
+	ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, ret);
 	if (ret != 0)
 		DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
 
@@ -448,16 +465,12 @@ static DEFINE_RUNTIME_DEV_PM_OPS(rockchip_dp_pm_ops, rockchip_dp_suspend,
 		rockchip_dp_resume, NULL);
 
 static const struct rockchip_dp_chip_data rk3399_edp = {
-	.lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
-	.lcdsel_big = HIWORD_UPDATE(0, RK3399_EDP_LCDC_SEL),
-	.lcdsel_lit = HIWORD_UPDATE(RK3399_EDP_LCDC_SEL, RK3399_EDP_LCDC_SEL),
+	.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
 	.chip_type = RK3399_EDP,
 };
 
 static const struct rockchip_dp_chip_data rk3288_dp = {
-	.lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
-	.lcdsel_big = HIWORD_UPDATE(0, RK3288_EDP_LCDC_SEL),
-	.lcdsel_lit = HIWORD_UPDATE(RK3288_EDP_LCDC_SEL, RK3288_EDP_LCDC_SEL),
+	.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
 	.chip_type = RK3288_DP,
 };
 
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:49 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:49 +0800
Subject: [PATCH v3 00/15] Add eDP support for RK3588
Message-ID: <20241219080604.1423600-1-damon.ding@rock-chips.com>

These patchs have been tested with a 1536x2048p60 eDP panel on
RK3588S EVB1 board, and HDMI 1080P/4K display also has been verified
on RK3588 EVB1 board.

Patch 1~3   are the RK3588 eDP support of Rockchip analogix_dp driver.
Patch 4~5   are the eDP mode support of samsung hdptx phy driver.
Patch 6~7   are the RK3588 eDP support of Aanalogix DP driver. Add phy
            interfaces is to configure the HDMI/eDP TX Combo PHY.
Patch 8~10  are to support to get panel from the DP AUX bus.
Patch 11~12 are the renaming of hdptxphy node. It is not only used by
            HDMI display but also for the eDP display.
Patch 13    is the addition of RK3588 eDP0 node.
Patch 14    is to enable the eDP0 display on RK3588S EVB1 board.
Patch 15    is to add the eDP1 related nodes for RK3588 SoC.

Damon Ding (15):
  drm/rockchip: analogix_dp: Use formalized struct definition for grf
    field
  dt-bindings: display: rockchip: analogix-dp: Add support for RK3588
  drm/rockchip: analogix_dp: Add support for RK3588
  phy: phy-rockchip-samsung-hdptx: Rename some register names related to
    DP
  phy: phy-rockchip-samsung-hdptx: Add support for eDP mode
  drm/bridge: analogix_dp: Add support for RK3588
  drm/bridge: analogix_dp: Add support for phy configuration.
  drm/rockchip: analogix_dp: Add support to get panel from the DP AUX
    bus
  drm/bridge: analogix_dp: Add support to get panel from the DP AUX bus
  dt-bindings: display: rockchip: analogix-dp: Add support to get panel
    from the DP AUX bus
  dt-bindings: display: rockchip: Fix label name of hdptxphy for RK3588
    HDMI TX Controller
  arm64: dts: rockchip: Fix label name of hdptxphy for RK3588
  arm64: dts: rockchip: Add eDP0 node for RK3588
  arm64: dts: rockchip: Enable eDP0 display on RK3588S EVB1 board
  arm64: dts: rockchip: Add eDP1 node for RK3588

 .../rockchip/rockchip,analogix-dp.yaml        |  17 +-
 .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml  |   2 +-
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi |  32 +-
 .../dts/rockchip/rk3588-coolpi-cm5-evb.dts    |   2 +-
 .../rockchip/rk3588-coolpi-cm5-genbook.dts    |   2 +-
 .../boot/dts/rockchip/rk3588-evb1-v10.dts     |   2 +-
 .../arm64/boot/dts/rockchip/rk3588-extra.dtsi |  49 +
 .../rk3588-friendlyelec-cm3588-nas.dts        |   2 +-
 .../arm64/boot/dts/rockchip/rk3588-jaguar.dts |   2 +-
 .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi   |   2 +-
 .../dts/rockchip/rk3588-orangepi-5-plus.dts   |   2 +-
 .../boot/dts/rockchip/rk3588-rock-5b.dts      |   2 +-
 .../boot/dts/rockchip/rk3588-tiger-haikou.dts |   2 +-
 .../boot/dts/rockchip/rk3588s-coolpi-4b.dts   |   2 +-
 .../boot/dts/rockchip/rk3588s-evb1-v10.dts    |  52 +
 .../dts/rockchip/rk3588s-indiedroid-nova.dts  |   2 +-
 .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi  |   2 +-
 .../boot/dts/rockchip/rk3588s-odroid-m2.dts   |   2 +-
 .../boot/dts/rockchip/rk3588s-orangepi-5.dtsi |   2 +-
 .../boot/dts/rockchip/rk3588s-rock-5a.dts     |   2 +-
 .../boot/dts/rockchip/rk3588s-rock-5c.dts     |   2 +-
 .../drm/bridge/analogix/analogix_dp_core.c    |  24 +
 .../gpu/drm/bridge/analogix/analogix_dp_reg.c |  56 +
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 182 +++-
 .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 954 +++++++++++++++++-
 include/drm/bridge/analogix_dp.h              |   3 +-
 26 files changed, 1302 insertions(+), 101 deletions(-)

-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:51 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:51 +0800
Subject: [PATCH v3 02/15] dt-bindings: display: rockchip: analogix-dp: Add support for RK3588
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-3-damon.ding@rock-chips.com>

Compared with RK3288/RK3399, the HBR2 link rate support is the main
improvement of RK3588 eDP TX controller, and there are also two
independent eDP display interfaces on RK3588 Soc.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Add the main defferences of the RK3588 eDP and the previous versions
  in commit message

Changes in v3:
- expand the property clock-names, resets and reset-names
---
 .../display/rockchip/rockchip,analogix-dp.yaml     | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
index 60dedf9b2be7..4f84e8849876 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
@@ -15,6 +15,7 @@ properties:
     enum:
       - rockchip,rk3288-dp
       - rockchip,rk3399-edp
+      - rockchip,rk3588-edp
 
   clocks:
     minItems: 2
@@ -25,16 +26,23 @@ properties:
     items:
       - const: dp
       - const: pclk
-      - const: grf
+      - enum:
+          - grf
+          - spdif
 
   power-domains:
     maxItems: 1
 
   resets:
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
 
   reset-names:
-    const: dp
+    minItems: 1
+    items:
+      - const: dp
+      - enum:
+          - apb
 
   rockchip,grf:
     $ref: /schemas/types.yaml#/definitions/phandle
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:52 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:52 +0800
Subject: [PATCH v3 03/15] drm/rockchip: analogix_dp: Add support for RK3588
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-4-damon.ding@rock-chips.com>

RK3588 integrates the Analogix eDP 1.3 TX controller IP and the HDMI/eDP
TX Combo PHY based on a Samsung IP block. There are also two independent
eDP display interface on RK3588 Soc, so add 'u32 reg' to struct
rockchip_dp_chip_data in order to distinguish between two different eDP
devices. What's more, the reg configurations for RK3399 and RK3288 have
also been set.

The patch currently adds only the basic support, specifically RGB output
up to 4K at 60Hz, without the tests for audio, PSR and other eDP 1.3 specific
features.

In additon, the above Analogix IP has always been utilized as eDP on
Rockchip platform, despite its capability to also support the DP v1.2.
Therefore, the newly added logs will contain the term 'edp' rather than
'dp'.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Add support for the other eDP output edp1

Changes in v3:
- Fix the unexpected use of alias
- Add more details in commit message
---
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 91 +++++++++++++++++--
 include/drm/bridge/analogix_dp.h              |  3 +-
 2 files changed, 83 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 05699615b4fc..ba5263f85ee2 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -51,11 +51,14 @@ struct rockchip_grf_reg_field {
 /**
  * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
  * @lcdc_sel: grf register field of lcdc_sel
+ * @edp_mode: grf register field of edp_mode
  * @chip_type: specific chip type
  */
 struct rockchip_dp_chip_data {
 	const struct rockchip_grf_reg_field lcdc_sel;
+	const struct rockchip_grf_reg_field edp_mode;
 	u32	chip_type;
+	u32	reg;
 };
 
 struct rockchip_dp_device {
@@ -134,12 +137,21 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
 		return ret;
 	}
 
+	ret = rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 1);
+	if (ret != 0)
+		DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);
+
 	return ret;
 }
 
 static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
 {
 	struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
+	int ret;
+
+	ret = rockchip_grf_field_write(dp->grf, &dp->data->edp_mode, 0);
+	if (ret != 0)
+		DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);
 
 	clk_disable_unprepare(dp->pclk);
 
@@ -203,6 +215,10 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
 	struct rockchip_dp_device *dp = encoder_to_dp(encoder);
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state;
+	struct of_endpoint endpoint;
+	struct device_node *remote_port, *remote_port_parent;
+	char name[32];
+	u32 port_id;
 	int ret;
 
 	crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
@@ -220,13 +236,27 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
 		return;
 	}
 
-	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
+	ret = drm_of_encoder_active_endpoint(dp->dev->of_node, encoder, &endpoint);
 	if (ret < 0)
 		return;
 
-	DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
+	remote_port_parent = of_graph_get_remote_port_parent(endpoint.local_node);
+	if (remote_port_parent) {
+		if (of_get_child_by_name(remote_port_parent, "ports")) {
+			remote_port = of_graph_get_remote_port(endpoint.local_node);
+			of_property_read_u32(remote_port, "reg", &port_id);
+			of_node_put(remote_port);
+			sprintf(name, "%s vp%d", remote_port_parent->full_name, port_id);
+		} else {
+			sprintf(name, "%s %s",
+				remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
+		}
+		of_node_put(remote_port_parent);
+
+		DRM_DEV_DEBUG(dp->dev, "%s output to edp\n", name);
+	}
 
-	ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, ret);
+	ret = rockchip_grf_field_write(dp->grf, &dp->data->lcdc_sel, endpoint.id);
 	if (ret != 0)
 		DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
 
@@ -396,6 +426,8 @@ static int rockchip_dp_probe(struct platform_device *pdev)
 	const struct rockchip_dp_chip_data *dp_data;
 	struct drm_panel *panel = NULL;
 	struct rockchip_dp_device *dp;
+	struct resource *res;
+	int i;
 	int ret;
 
 	dp_data = of_device_get_match_data(dev);
@@ -410,9 +442,25 @@ static int rockchip_dp_probe(struct platform_device *pdev)
 	if (!dp)
 		return -ENOMEM;
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	i = 0;
+	while (dp_data[i].reg) {
+		if (dp_data[i].reg == res->start) {
+			dp->data = &dp_data[i];
+			break;
+		}
+
+		i++;
+	}
+
+	if (!dp->data) {
+		DRM_DEV_ERROR(dev, "no chip-data for %s node\n", dev->of_node->name);
+		return -ENODEV;
+	}
+
 	dp->dev = dev;
 	dp->adp = ERR_PTR(-ENODEV);
-	dp->data = dp_data;
 	dp->plat_data.panel = panel;
 	dp->plat_data.dev_type = dp->data->chip_type;
 	dp->plat_data.power_on = rockchip_dp_poweron;
@@ -464,19 +512,42 @@ static int rockchip_dp_resume(struct device *dev)
 static DEFINE_RUNTIME_DEV_PM_OPS(rockchip_dp_pm_ops, rockchip_dp_suspend,
 		rockchip_dp_resume, NULL);
 
-static const struct rockchip_dp_chip_data rk3399_edp = {
-	.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
-	.chip_type = RK3399_EDP,
+static const struct rockchip_dp_chip_data rk3399_edp[] = {
+	{
+		.lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
+		.chip_type = RK3399_EDP,
+		.reg = 0xff970000,
+	},
+	{ /* sentinel */ }
 };
 
-static const struct rockchip_dp_chip_data rk3288_dp = {
-	.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
-	.chip_type = RK3288_DP,
+static const struct rockchip_dp_chip_data rk3288_dp[] = {
+	{
+		.lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
+		.chip_type = RK3288_DP,
+		.reg = 0xff970000,
+	},
+	{ /* sentinel */ }
+};
+
+static const struct rockchip_dp_chip_data rk3588_edp[] = {
+	{
+		.edp_mode = GRF_REG_FIELD(0x0000, 0, 0),
+		.chip_type = RK3588_EDP,
+		.reg = 0xfdec0000,
+	},
+	{
+		.edp_mode = GRF_REG_FIELD(0x0004, 0, 0),
+		.chip_type = RK3588_EDP,
+		.reg = 0xfded0000,
+	},
+	{ /* sentinel */ }
 };
 
 static const struct of_device_id rockchip_dp_dt_ids[] = {
 	{.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp },
 	{.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp },
+	{.compatible = "rockchip,rk3588-edp", .data = &rk3588_edp },
 	{}
 };
 MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 6002c5666031..54086cb2d97d 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -15,11 +15,12 @@ enum analogix_dp_devtype {
 	EXYNOS_DP,
 	RK3288_DP,
 	RK3399_EDP,
+	RK3588_EDP,
 };
 
 static inline bool is_rockchip(enum analogix_dp_devtype type)
 {
-	return type == RK3288_DP || type == RK3399_EDP;
+	return type == RK3288_DP || type == RK3399_EDP || type == RK3588_EDP;
 }
 
 struct analogix_dp_plat_data {
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:53 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:53 +0800
Subject: [PATCH v3 04/15] phy: phy-rockchip-samsung-hdptx: Rename some register names related to DP
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-5-damon.ding@rock-chips.com>

The modifications of DP register names are as follows:
- Add the '_MASK' suffix to some registers to ensure consistency.
- Complete the names of some register to their full names.
- Swap the definitions of LCPLL_REF and ROPLL_REF.

Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver")
Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 64 +++++++++----------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index ceab9c71d3b5..c1b9c73f5f9f 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -69,41 +69,41 @@
 #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)
+#define ROPLL_SDC_FRAC_EN_RBR_MASK	BIT(3)
+#define ROPLL_SDC_FRAC_EN_HBR_MASK	BIT(2)
+#define ROPLL_SDC_FRAC_EN_HBR2_MASK	BIT(1)
+#define ROPLL_SDM_FRAC_EN_HBR3_MASK	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)
+#define ROPLL_SDC_NDIV_RSTN_MASK	BIT(2)
+#define ROPLL_SSC_EN_MASK		BIT(0)
 /* CMN_REG(0081) */
-#define OVRD_PLL_CD_CLK_EN		BIT(8)
-#define PLL_CD_HSCLK_EAST_EN		BIT(0)
+#define OVRD_PLL_CD_CLK_EN_MASK		BIT(8)
+#define ANA_PLL_CD_HSCLK_EAST_EN_MASK	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)
+#define ANA_PLL_FRL_MODE_EN_MASK	BIT(3)
+#define ANA_PLL_TX_HS_CLK_EN_MASK	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
+#define DIG_CLK_SEL_MASK		BIT(1)
+#define LCPLL_REF			BIT(1)
+#define ROPLL_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 HS_SPEED_SEL_MASK		BIT(0)
 #define DIV_10_CLOCK			BIT(0)
 /* CMN_REG(009b) */
-#define IS_SPEED_SEL			BIT(4)
+#define LS_SPEED_SEL_MASK		BIT(4)
 #define LINK_SYMBOL_CLOCK		BIT(4)
 #define LINK_SYMBOL_CLOCK1_2		0
 
@@ -165,32 +165,32 @@
 #define HDMI_MODE			BIT(2)
 #define HDMI_TMDS_FRL_SEL		BIT(1)
 /* LNTOP_REG(0206) */
-#define DATA_BUS_SEL			BIT(0)
+#define DATA_BUS_WIDTH_SEL_MASK		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)
+#define LN0_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
+#define LN0_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
+#define LN0_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
+#define LN0_TX_SER_RATE_SEL_HBR3_MASK	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)
+#define LN1_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
+#define LN1_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
+#define LN1_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
+#define LN1_TX_SER_RATE_SEL_HBR3_MASK	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)
+#define LN2_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
+#define LN2_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
+#define LN2_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
+#define LN2_TX_SER_RATE_SEL_HBR3_MASK	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)
+#define LN3_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
+#define LN3_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
+#define LN3_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
+#define LN3_TX_SER_RATE_SEL_HBR3_MASK	BIT(2)
 
 #define HDMI20_MAX_RATE			600000000
 
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:54 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:54 +0800
Subject: [PATCH v3 05/15] phy: phy-rockchip-samsung-hdptx: Add support for eDP mode
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-6-damon.ding@rock-chips.com>

Add basic support for RBR/HBR/HBR2 link rates, and the voltage swing and
pre-emphasis configurations of each link rate have been verified according
to the eDP 1.3 requirements.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Add the module author

Changes in v3:
- Split this patch into two, one for correction and the other for
  extension
---
 .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 890 +++++++++++++++++-
 1 file changed, 883 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index c1b9c73f5f9f..52fc121ff7de 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -25,6 +25,7 @@
 #define HDPTX_I_PLL_EN			BIT(7)
 #define HDPTX_I_BIAS_EN			BIT(6)
 #define HDPTX_I_BGR_EN			BIT(5)
+#define HDPTX_MODE_SEL			BIT(0)
 #define GRF_HDPTX_STATUS		0x80
 #define HDPTX_O_PLL_LOCK_DONE		BIT(3)
 #define HDPTX_O_PHY_CLK_RDY		BIT(2)
@@ -44,6 +45,7 @@
 #define LANE_REG(n)			HDTPX_REG(n, 0300, 062d)
 
 /* CMN_REG(0008) */
+#define OVRD_LCPLL_EN_MASK		BIT(7)
 #define LCPLL_EN_MASK			BIT(6)
 #define LCPLL_LCVCO_MODE_EN_MASK	BIT(4)
 /* CMN_REG(001e) */
@@ -61,28 +63,88 @@
 /* CMN_REG(002f) */
 #define LCPLL_SDC_DENOMINATOR_MASK	GENMASK(7, 2)
 #define LCPLL_SDC_NDIV_RSTN		BIT(0)
+/* CMN_REG(003c) */
+#define ANA_LCPLL_RESERVED7_MASK	BIT(7)
 /* CMN_REG(003d) */
+#define OVRD_ROPLL_EN_MASK		BIT(7)
+#define ROPLL_EN_MASK			BIT(6)
 #define ROPLL_LCVCO_EN			BIT(4)
+/* CMN_REG(0046) */
+#define ROPLL_ANA_CPP_CTRL_COARSE_MASK	GENMASK(7, 4)
+#define ROPLL_ANA_CPP_CTRL_FINE_MASK	GENMASK(3, 0)
+/* CMN_REG(0047) */
+#define ROPLL_ANA_LPF_C_SEL_COARSE_MASK	GENMASK(5, 3)
+#define ROPLL_ANA_LPF_C_SEL_FINE_MASK	GENMASK(2, 0)
 /* CMN_REG(004e) */
 #define ROPLL_PI_EN			BIT(5)
+/* CMN_REG(0051) */
+#define ROPLL_PMS_MDIV_MASK		GENMASK(7, 0)
+/* CMN_REG(0055) */
+#define ROPLL_PMS_MDIV_AFC_MASK		GENMASK(7, 0)
+/* CMN_REG(0059) */
+#define ANA_ROPLL_PMS_PDIV_MASK		GENMASK(7, 4)
+#define ANA_ROPLL_PMS_REFDIV_MASK	GENMASK(3, 0)
+/* CMN_REG(005a) */
+#define ROPLL_PMS_SDIV_RBR_MASK		GENMASK(7, 4)
+#define ROPLL_PMS_SDIV_HBR_MASK		GENMASK(3, 0)
+/* CMN_REG(005b) */
+#define ROPLL_PMS_SDIV_HBR2_MASK	GENMASK(7, 4)
 /* CMN_REG(005c) */
 #define ROPLL_PMS_IQDIV_RSTN		BIT(5)
 /* CMN_REG(005e) */
 #define ROPLL_SDM_EN_MASK		BIT(6)
+#define OVRD_ROPLL_SDM_RSTN_MASK	BIT(5)
+#define ROPLL_SDM_RSTN_MASK		BIT(4)
 #define ROPLL_SDC_FRAC_EN_RBR_MASK	BIT(3)
 #define ROPLL_SDC_FRAC_EN_HBR_MASK	BIT(2)
 #define ROPLL_SDC_FRAC_EN_HBR2_MASK	BIT(1)
 #define ROPLL_SDM_FRAC_EN_HBR3_MASK	BIT(0)
+/* CMN_REG(005f) */
+#define OVRD_ROPLL_SDC_RSTN_MASK	BIT(5)
+#define ROPLL_SDC_RSTN_MASK		BIT(4)
+/* CMN_REG(0060)  */
+#define ROPLL_SDM_DENOMINATOR_MASK	GENMASK(7, 0)
 /* CMN_REG(0064) */
 #define ROPLL_SDM_NUM_SIGN_RBR_MASK	BIT(3)
+#define ROPLL_SDM_NUM_SIGN_HBR_MASK	BIT(2)
+#define ROPLL_SDM_NUM_SIGN_HBR2_MASK	BIT(1)
+/* CMN_REG(0065) */
+#define ROPLL_SDM_NUM_MASK		GENMASK(7, 0)
 /* CMN_REG(0069) */
 #define ROPLL_SDC_N_RBR_MASK		GENMASK(2, 0)
+/* CMN_REG(006a) */
+#define ROPLL_SDC_N_HBR_MASK		GENMASK(5, 3)
+#define ROPLL_SDC_N_HBR2_MASK		GENMASK(2, 0)
+/* CMN_REG(006b) */
+#define ROPLL_SDC_N_HBR3_MASK		GENMASK(3, 1)
+/* CMN_REG(006c) */
+#define ROPLL_SDC_NUM_MASK		GENMASK(5, 0)
+/* cmn_reg0070 */
+#define ROPLL_SDC_DENO_MASK		GENMASK(5, 0)
 /* CMN_REG(0074) */
+#define OVRD_ROPLL_SDC_NDIV_RSTN_MASK	BIT(3)
 #define ROPLL_SDC_NDIV_RSTN_MASK	BIT(2)
+#define OVRD_ROPLL_SSC_EN_MASK		BIT(1)
 #define ROPLL_SSC_EN_MASK		BIT(0)
+/* CMN_REG(0075) */
+#define ANA_ROPLL_SSC_FM_DEVIATION_MASK	GENMASK(5, 0)
+/* CMN_REG(0076) */
+#define ANA_ROPLL_SSC_FM_FREQ_MASK	GENMASK(6, 2)
+/* CMN_REG(0077) */
+#define ANA_ROPLL_SSC_CLK_DIV_SEL_MASK	GENMASK(6, 3)
 /* CMN_REG(0081) */
 #define OVRD_PLL_CD_CLK_EN_MASK		BIT(8)
+#define ANA_PLL_CD_TX_SER_RATE_SEL_MASK	BIT(3)
+#define ANA_PLL_CD_HSCLK_WEST_EN_MASK	BIT(1)
 #define ANA_PLL_CD_HSCLK_EAST_EN_MASK	BIT(0)
+/* CMN_REG(0082) */
+#define ANA_PLL_CD_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
+/* CMN_REG(0083) */
+#define ANA_PLL_CD_VREG_ICTRL_MASK	GENMASK(6, 5)
+/* CMN_REG(0084) */
+#define PLL_LCRO_CLK_SEL_MASK		BIT(5)
+/* CMN_REG(0085) */
+#define ANA_PLL_SYNC_LOSS_DET_MODE_MASK	GENMASK(1, 0)
 /* CMN_REG(0086) */
 #define PLL_PCG_POSTDIV_SEL_MASK	GENMASK(7, 4)
 #define PLL_PCG_CLK_SEL_MASK		GENMASK(3, 1)
@@ -92,11 +154,14 @@
 #define ANA_PLL_TX_HS_CLK_EN_MASK	BIT(2)
 /* CMN_REG(0089) */
 #define LCPLL_ALONE_MODE		BIT(1)
+/* CMN_REG(0095) */
+#define DP_TX_LINK_BW_MASK		GENMASK(1, 0)
 /* CMN_REG(0097) */
 #define DIG_CLK_SEL_MASK		BIT(1)
 #define LCPLL_REF			BIT(1)
 #define ROPLL_REF			0
 /* CMN_REG(0099) */
+#define SSC_EN_MASK			GENMASK(7, 6)
 #define CMN_ROPLL_ALONE_MODE		BIT(2)
 #define ROPLL_ALONE_MODE		BIT(2)
 /* CMN_REG(009a) */
@@ -118,6 +183,8 @@
 /* SB_REG(0104) */
 #define OVRD_SB_EN_MASK			BIT(5)
 #define SB_EN_MASK			BIT(4)
+#define OVRD_SB_AUX_EN_MASK		BIT(1)
+#define SB_AUX_EN_MASK			BIT(0)
 /* SB_REG(0105) */
 #define OVRD_SB_EARC_CMDC_EN_MASK	BIT(6)
 #define SB_EARC_CMDC_EN_MASK		BIT(5)
@@ -126,6 +193,8 @@
 #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(010d) */
+#define ANA_SB_DMRX_LPBK_DATA_MASK	BIT(4)
 /* SB_REG(010f) */
 #define OVRD_SB_VREG_EN_MASK		BIT(7)
 #define SB_VREG_EN_MASK			BIT(6)
@@ -133,6 +202,7 @@
 #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_OUT_SEL_MASK	BIT(1)
 #define ANA_SB_VREG_REF_SEL_MASK	BIT(0)
 /* SB_REG(0113) */
 #define SB_RX_RCAL_OPT_CODE_MASK	GENMASK(5, 4)
@@ -147,13 +217,24 @@
 #define AFC_RSTN_DELAY_TIME_MASK	GENMASK(6, 4)
 /* SB_REG(0117) */
 #define FAST_PULSE_TIME_MASK		GENMASK(3, 0)
+/* SB_REG(0118) */
+#define SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK	GENMASK(7, 0)
+/* SB_REG(011a) */
+#define SB_TG_CNT_RUN_NO_7_0_MASK	GENMASK(7, 0)
 /* SB_REG(011b) */
 #define SB_EARC_SIG_DET_BYPASS_MASK	BIT(4)
 #define SB_AFC_TOL_MASK			GENMASK(3, 0)
+/* SB_REG(011c) */
+#define SB_AFC_STB_NUM_MASK		GENMASK(3, 0)
+/* SB_REG(011d) */
+#define SB_TG_OSC_CNT_MIN_MASK		GENMASK(7, 0)
+/* SB_REG(011e) */
+#define SB_TG_OSC_CNT_MAX_MASK		GENMASK(7, 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_AUX_EN_IN_MASK		BIT(7)
 #define SB_EARC_EN_MASK			BIT(1)
 #define SB_EARC_AFC_EN_MASK		BIT(2)
 /* SB_REG(0123) */
@@ -165,27 +246,74 @@
 #define HDMI_MODE			BIT(2)
 #define HDMI_TMDS_FRL_SEL		BIT(1)
 /* LNTOP_REG(0206) */
+#define DATA_BUS_WIDTH_MASK		GENMASK(2, 1)
 #define DATA_BUS_WIDTH_SEL_MASK		BIT(0)
 #define DATA_BUS_36_40			BIT(0)
 /* LNTOP_REG(0207) */
 #define LANE_EN				0xf
 #define ALL_LANE_EN			0xf
 
+/* LANE_REG(0301) */
+#define OVRD_LN_TX_DRV_EI_EN_MASK	BIT(7)
+#define LN_TX_DRV_EI_EN_MASK		BIT(6)
+/* LANE_REG(0303) */
+#define OVRD_LN_TX_DRV_LVL_CTRL_MASK	BIT(5)
+#define LN_TX_DRV_LVL_CTRL_MASK		GENMASK(4, 0)
+/* LANE_REG(0304)  */
+#define OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK	BIT(4)
+#define LN_TX_DRV_POST_LVL_CTRL_MASK	GENMASK(3, 0)
+/* LANE_REG(0305) */
+#define OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK	BIT(6)
+#define LN_TX_DRV_PRE_LVL_CTRL_MASK	GENMASK(5, 2)
+/* LANE_REG(0306) */
+#define LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK	GENMASK(7, 5)
+#define LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK	GENMASK(4, 2)
+#define LN_ANA_TX_DRV_ACCDRV_EN_MASK	BIT(0)
+/* LANE_REG(0307) */
+#define LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK	BIT(6)
+#define LN_ANA_TX_DRV_ACCDRV_CTRL_MASK	GENMASK(5, 3)
+/* LANE_REG(030a) */
+#define LN_ANA_TX_JEQ_EN_MASK		BIT(4)
+#define LN_TX_JEQ_EVEN_CTRL_RBR_MASK	GENMASK(3, 0)
+/* LANE_REG(030b) */
+#define LN_TX_JEQ_EVEN_CTRL_HBR_MASK	GENMASK(7, 4)
+#define LN_TX_JEQ_EVEN_CTRL_HBR2_MASK	GENMASK(3, 0)
+/* LANE_REG(030c) */
+#define LN_TX_JEQ_ODD_CTRL_RBR_MASK	GENMASK(3, 0)
+/* LANE_REG(030d) */
+#define LN_TX_JEQ_ODD_CTRL_HBR_MASK	GENMASK(7, 4)
+#define LN_TX_JEQ_ODD_CTRL_HBR2_MASK	GENMASK(3, 0)
+/* LANE_REG(0310) */
+#define LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK	GENMASK(1, 0)
+/* LANE_REG(0311) */
+#define LN_TX_SER_40BIT_EN_RBR_MASK	BIT(3)
+#define LN_TX_SER_40BIT_EN_HBR_MASK	BIT(2)
+#define LN_TX_SER_40BIT_EN_HBR2_MASK	BIT(1)
 /* LANE_REG(0312) */
 #define LN0_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
 #define LN0_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
 #define LN0_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
 #define LN0_TX_SER_RATE_SEL_HBR3_MASK	BIT(2)
+/* LANE_REG(0316) */
+#define LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
+/* LANE_REG(031B) */
+#define LN_ANA_TX_RESERVED_MASK		GENMASK(7, 0)
+/* LANE_REG(031e) */
+#define LN_POLARITY_INV_MASK		BIT(2)
+#define LN_LANE_MODE_MASK		BIT(1)
+
 /* LANE_REG(0412) */
 #define LN1_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
 #define LN1_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
 #define LN1_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
 #define LN1_TX_SER_RATE_SEL_HBR3_MASK	BIT(2)
+
 /* LANE_REG(0512) */
 #define LN2_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
 #define LN2_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
 #define LN2_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
 #define LN2_TX_SER_RATE_SEL_HBR3_MASK	BIT(2)
+
 /* LANE_REG(0612) */
 #define LN3_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
 #define LN3_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
@@ -194,6 +322,12 @@
 
 #define HDMI20_MAX_RATE			600000000
 
+enum dp_link_rate {
+	DP_BW_RBR,
+	DP_BW_HBR,
+	DP_BW_HBR2,
+};
+
 struct lcpll_config {
 	u32 bit_rate;
 	u8 lcvco_mode_en;
@@ -255,6 +389,19 @@ struct ropll_config {
 	u8 cd_tx_ser_rate_sel;
 };
 
+struct tx_drv_ctrl {
+	u8 tx_drv_lvl_ctrl;
+	u8 tx_drv_post_lvl_ctrl;
+	u8 ana_tx_drv_idrv_idn_ctrl;
+	u8 ana_tx_drv_idrv_iup_ctrl;
+	u8 ana_tx_drv_accdrv_en;
+	u8 ana_tx_drv_accdrv_ctrl;
+	u8 tx_drv_pre_lvl_ctrl;
+	u8 ana_tx_jeq_en;
+	u8 tx_jeq_even_ctrl;
+	u8 tx_jeq_odd_ctrl;
+};
+
 enum rk_hdptx_reset {
 	RST_APB = 0,
 	RST_INIT,
@@ -557,6 +704,90 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0606), 0x1c),
 };
 
+static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = {
+	/* voltage swing 0, pre-emphasis 0->3 */
+	{
+		{ 0x2, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0x4, 0x3, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0x7, 0x6, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 1, pre-emphasis 0->2 */
+	{
+		{ 0x4, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0x9, 0x5, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xc, 0x8, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 2, pre-emphasis 0->1 */
+	{
+		{ 0x8, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xc, 0x5, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 3, pre-emphasis 0 */
+	{
+		{ 0xb, 0x0, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
+	}
+};
+
+static struct tx_drv_ctrl tx_drv_ctrl_hbr[4][4] = {
+	/* voltage swing 0, pre-emphasis 0->3 */
+	{
+		{ 0x2, 0x0, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0x5, 0x4, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0x9, 0x8, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 1, pre-emphasis 0->2 */
+	{
+		{ 0x6, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xa, 0x6, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xc, 0x8, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 2, pre-emphasis 0->1 */
+	{
+		{ 0x9, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xd, 0x6, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 3, pre-emphasis 0 */
+	{
+		{ 0xc, 0x1, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
+	}
+};
+
+static struct tx_drv_ctrl tx_drv_ctrl_hbr2[4][4] = {
+	/* voltage swing 0, pre-emphasis 0->3 */
+	{
+		{ 0x2, 0x1, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0x5, 0x4, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0x9, 0x8, 0x4, 0x6, 0x1, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xd, 0xc, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 1, pre-emphasis 0->2 */
+	{
+		{ 0x6, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xb, 0x7, 0x4, 0x6, 0x0, 0x4, 0x0, 0x1, 0x7, 0x7 },
+		{ 0xd, 0x9, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 2, pre-emphasis 0->1 */
+	{
+		{ 0x8, 0x1, 0x4, 0x6, 0x0, 0x4, 0x1, 0x1, 0x7, 0x7 },
+		{ 0xc, 0x6, 0x7, 0x7, 0x1, 0x7, 0x0, 0x1, 0x7, 0x7 },
+	},
+
+	/* voltage swing 3, pre-emphasis 0 */
+	{
+		{ 0xb, 0x0, 0x7, 0x7, 0x1, 0x4, 0x1, 0x1, 0x7, 0x7 },
+	}
+};
+
 static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
@@ -899,11 +1130,297 @@ static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)
 	return ret;
 }
 
+static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx)
+{
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+	reset_control_assert(hdptx->rsts[RST_APB].rstc);
+	udelay(10);
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(0301),
+			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
+			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0401),
+			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
+			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0501),
+			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
+			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0601),
+			   OVRD_LN_TX_DRV_EI_EN_MASK | LN_TX_DRV_EI_EN_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_EI_EN_MASK, 1) |
+			   FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x0));
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x0));
+}
+
+static void rk_hdptx_dp_pll_init(struct rk_hdptx_phy *hdptx)
+{
+	regmap_update_bits(hdptx->regmap, CMN_REG(003c), ANA_LCPLL_RESERVED7_MASK,
+			   FIELD_PREP(ANA_LCPLL_RESERVED7_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0046),
+			   ROPLL_ANA_CPP_CTRL_COARSE_MASK | ROPLL_ANA_CPP_CTRL_FINE_MASK,
+			   FIELD_PREP(ROPLL_ANA_CPP_CTRL_COARSE_MASK, 0xe) |
+			   FIELD_PREP(ROPLL_ANA_CPP_CTRL_FINE_MASK, 0xe));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0047),
+			   ROPLL_ANA_LPF_C_SEL_COARSE_MASK |
+			   ROPLL_ANA_LPF_C_SEL_FINE_MASK,
+			   FIELD_PREP(ROPLL_ANA_LPF_C_SEL_COARSE_MASK, 0x4) |
+			   FIELD_PREP(ROPLL_ANA_LPF_C_SEL_FINE_MASK, 0x4));
+
+	regmap_write(hdptx->regmap, CMN_REG(0051), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x87));
+	regmap_write(hdptx->regmap, CMN_REG(0052), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x71));
+	regmap_write(hdptx->regmap, CMN_REG(0053), FIELD_PREP(ROPLL_PMS_MDIV_MASK, 0x71));
+
+	regmap_write(hdptx->regmap, CMN_REG(0055),
+		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x87));
+	regmap_write(hdptx->regmap, CMN_REG(0056),
+		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x71));
+	regmap_write(hdptx->regmap, CMN_REG(0057),
+		     FIELD_PREP(ROPLL_PMS_MDIV_AFC_MASK, 0x71));
+
+	regmap_write(hdptx->regmap, CMN_REG(0059),
+		     FIELD_PREP(ANA_ROPLL_PMS_PDIV_MASK, 0x1) |
+		     FIELD_PREP(ANA_ROPLL_PMS_REFDIV_MASK, 0x1));
+	regmap_write(hdptx->regmap, CMN_REG(005a),
+		     FIELD_PREP(ROPLL_PMS_SDIV_RBR_MASK, 0x3) |
+		     FIELD_PREP(ROPLL_PMS_SDIV_HBR_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005b), ROPLL_PMS_SDIV_HBR2_MASK,
+			   FIELD_PREP(ROPLL_PMS_SDIV_HBR2_MASK, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,
+			   FIELD_PREP(ROPLL_SDM_EN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e),
+			   OVRD_ROPLL_SDM_RSTN_MASK | ROPLL_SDM_RSTN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_SDM_RSTN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDM_RSTN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_RBR_MASK,
+			   FIELD_PREP(ROPLL_SDC_FRAC_EN_RBR_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_HBR_MASK,
+			   FIELD_PREP(ROPLL_SDC_FRAC_EN_HBR_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDC_FRAC_EN_HBR2_MASK,
+			   FIELD_PREP(ROPLL_SDC_FRAC_EN_HBR2_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(005f),
+			   OVRD_ROPLL_SDC_RSTN_MASK | ROPLL_SDC_RSTN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_SDC_RSTN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDC_RSTN_MASK, 0x1));
+	regmap_write(hdptx->regmap, CMN_REG(0060),
+		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x21));
+	regmap_write(hdptx->regmap, CMN_REG(0061),
+		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x27));
+	regmap_write(hdptx->regmap, CMN_REG(0062),
+		     FIELD_PREP(ROPLL_SDM_DENOMINATOR_MASK, 0x27));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0064),
+			   ROPLL_SDM_NUM_SIGN_RBR_MASK |
+			   ROPLL_SDM_NUM_SIGN_HBR_MASK |
+			   ROPLL_SDM_NUM_SIGN_HBR2_MASK,
+			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, 0x0) |
+			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_HBR_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_HBR2_MASK, 0x1));
+	regmap_write(hdptx->regmap, CMN_REG(0065),
+		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0x0));
+	regmap_write(hdptx->regmap, CMN_REG(0066),
+		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0xd));
+	regmap_write(hdptx->regmap, CMN_REG(0067),
+		     FIELD_PREP(ROPLL_SDM_NUM_MASK, 0xd));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
+			   FIELD_PREP(ROPLL_SDC_N_RBR_MASK, 0x2));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(006a),
+			   ROPLL_SDC_N_HBR_MASK | ROPLL_SDC_N_HBR2_MASK,
+			   FIELD_PREP(ROPLL_SDC_N_HBR_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDC_N_HBR2_MASK, 0x1));
+
+	regmap_write(hdptx->regmap, CMN_REG(006c),
+		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x3));
+	regmap_write(hdptx->regmap, CMN_REG(006d),
+		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x7));
+	regmap_write(hdptx->regmap, CMN_REG(006e),
+		     FIELD_PREP(ROPLL_SDC_NUM_MASK, 0x7));
+
+	regmap_write(hdptx->regmap, CMN_REG(0070),
+		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x8));
+	regmap_write(hdptx->regmap, CMN_REG(0071),
+		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x18));
+	regmap_write(hdptx->regmap, CMN_REG(0072),
+		     FIELD_PREP(ROPLL_SDC_DENO_MASK, 0x18));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0074),
+			   OVRD_ROPLL_SDC_NDIV_RSTN_MASK | ROPLL_SDC_NDIV_RSTN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_SDC_NDIV_RSTN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_SDC_NDIV_RSTN_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0077), ANA_ROPLL_SSC_CLK_DIV_SEL_MASK,
+			   FIELD_PREP(ANA_ROPLL_SSC_CLK_DIV_SEL_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0081), ANA_PLL_CD_TX_SER_RATE_SEL_MASK,
+			   FIELD_PREP(ANA_PLL_CD_TX_SER_RATE_SEL_MASK, 0x0));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0081),
+			   ANA_PLL_CD_HSCLK_EAST_EN_MASK | ANA_PLL_CD_HSCLK_WEST_EN_MASK,
+			   FIELD_PREP(ANA_PLL_CD_HSCLK_EAST_EN_MASK, 0x1) |
+			   FIELD_PREP(ANA_PLL_CD_HSCLK_WEST_EN_MASK, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0082), ANA_PLL_CD_VREG_GAIN_CTRL_MASK,
+			   FIELD_PREP(ANA_PLL_CD_VREG_GAIN_CTRL_MASK, 0x4));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0083), ANA_PLL_CD_VREG_ICTRL_MASK,
+			   FIELD_PREP(ANA_PLL_CD_VREG_ICTRL_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0084), PLL_LCRO_CLK_SEL_MASK,
+			   FIELD_PREP(PLL_LCRO_CLK_SEL_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0085), ANA_PLL_SYNC_LOSS_DET_MODE_MASK,
+			   FIELD_PREP(ANA_PLL_SYNC_LOSS_DET_MODE_MASK, 0x3));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0087), ANA_PLL_TX_HS_CLK_EN_MASK,
+			   FIELD_PREP(ANA_PLL_TX_HS_CLK_EN_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0097), DIG_CLK_SEL_MASK,
+			   FIELD_PREP(DIG_CLK_SEL_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0099), CMN_ROPLL_ALONE_MODE,
+			   FIELD_PREP(CMN_ROPLL_ALONE_MODE, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(009a), HS_SPEED_SEL_MASK,
+			   FIELD_PREP(HS_SPEED_SEL_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, CMN_REG(009b), LS_SPEED_SEL_MASK,
+			   FIELD_PREP(LS_SPEED_SEL_MASK, 0x1));
+}
+
+static int rk_hdptx_dp_aux_init(struct rk_hdptx_phy *hdptx)
+{
+	u32 status;
+	int ret;
+
+	regmap_update_bits(hdptx->regmap, SB_REG(0102), ANA_SB_RXTERM_OFFSP_MASK,
+			   FIELD_PREP(ANA_SB_RXTERM_OFFSP_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(0103), ANA_SB_RXTERM_OFFSN_MASK,
+			   FIELD_PREP(ANA_SB_RXTERM_OFFSN_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_AUX_EN_MASK,
+			   FIELD_PREP(SB_AUX_EN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0105), ANA_SB_TX_HLVL_PROG_MASK,
+			   FIELD_PREP(ANA_SB_TX_HLVL_PROG_MASK, 0x7));
+	regmap_update_bits(hdptx->regmap, SB_REG(0106), ANA_SB_TX_LLVL_PROG_MASK,
+			   FIELD_PREP(ANA_SB_TX_LLVL_PROG_MASK, 0x7));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(010d), ANA_SB_DMRX_LPBK_DATA_MASK,
+			   FIELD_PREP(ANA_SB_DMRX_LPBK_DATA_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(010f), ANA_SB_VREG_GAIN_CTRL_MASK,
+			   FIELD_PREP(ANA_SB_VREG_GAIN_CTRL_MASK, 0x0));
+	regmap_update_bits(hdptx->regmap, SB_REG(0110),
+			   ANA_SB_VREG_OUT_SEL_MASK | ANA_SB_VREG_REF_SEL_MASK,
+			   FIELD_PREP(ANA_SB_VREG_OUT_SEL_MASK, 0x1) |
+			   FIELD_PREP(ANA_SB_VREG_REF_SEL_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(0113),
+			   SB_RX_RCAL_OPT_CODE_MASK | SB_RX_RTERM_CTRL_MASK,
+			   FIELD_PREP(SB_RX_RCAL_OPT_CODE_MASK, 0x1) |
+			   FIELD_PREP(SB_RX_RTERM_CTRL_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(0114),
+			   SB_TG_SB_EN_DELAY_TIME_MASK | SB_TG_RXTERM_EN_DELAY_TIME_MASK,
+			   FIELD_PREP(SB_TG_SB_EN_DELAY_TIME_MASK, 0x2) |
+			   FIELD_PREP(SB_TG_RXTERM_EN_DELAY_TIME_MASK, 0x2));
+	regmap_update_bits(hdptx->regmap, SB_REG(0115),
+			   SB_READY_DELAY_TIME_MASK | SB_TG_OSC_EN_DELAY_TIME_MASK,
+			   FIELD_PREP(SB_READY_DELAY_TIME_MASK, 0x2) |
+			   FIELD_PREP(SB_TG_OSC_EN_DELAY_TIME_MASK, 0x2));
+	regmap_update_bits(hdptx->regmap, SB_REG(0116),
+			   AFC_RSTN_DELAY_TIME_MASK,
+			   FIELD_PREP(AFC_RSTN_DELAY_TIME_MASK, 0x2));
+	regmap_update_bits(hdptx->regmap, SB_REG(0117),
+			   FAST_PULSE_TIME_MASK,
+			   FIELD_PREP(FAST_PULSE_TIME_MASK, 0x4));
+	regmap_update_bits(hdptx->regmap, SB_REG(0118),
+			   SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK,
+			   FIELD_PREP(SB_TG_EARC_DMRX_RECVRD_CLK_CNT_MASK, 0xa));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(011a), SB_TG_CNT_RUN_NO_7_0_MASK,
+			   FIELD_PREP(SB_TG_CNT_RUN_NO_7_0_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(011b),
+			   SB_EARC_SIG_DET_BYPASS_MASK | SB_AFC_TOL_MASK,
+			   FIELD_PREP(SB_EARC_SIG_DET_BYPASS_MASK, 0x1) |
+			   FIELD_PREP(SB_AFC_TOL_MASK, 0x3));
+	regmap_update_bits(hdptx->regmap, SB_REG(011c), SB_AFC_STB_NUM_MASK,
+			   FIELD_PREP(SB_AFC_STB_NUM_MASK, 0x4));
+	regmap_update_bits(hdptx->regmap, SB_REG(011d), SB_TG_OSC_CNT_MIN_MASK,
+			   FIELD_PREP(SB_TG_OSC_CNT_MIN_MASK, 0x67));
+	regmap_update_bits(hdptx->regmap, SB_REG(011e), SB_TG_OSC_CNT_MAX_MASK,
+			   FIELD_PREP(SB_TG_OSC_CNT_MAX_MASK, 0x6a));
+	regmap_update_bits(hdptx->regmap, SB_REG(011f), SB_PWM_AFC_CTRL_MASK,
+			   FIELD_PREP(SB_PWM_AFC_CTRL_MASK, 0x5));
+	regmap_update_bits(hdptx->regmap, SB_REG(011f), SB_RCAL_RSTN_MASK,
+			   FIELD_PREP(SB_RCAL_RSTN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0120), SB_AUX_EN_IN_MASK,
+			   FIELD_PREP(SB_AUX_EN_IN_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(0102), OVRD_SB_RXTERM_EN_MASK,
+			   FIELD_PREP(OVRD_SB_RXTERM_EN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK,
+			   FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_EN_MASK,
+			   FIELD_PREP(OVRD_SB_EN_MASK, 0x1));
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), OVRD_SB_AUX_EN_MASK,
+			   FIELD_PREP(OVRD_SB_AUX_EN_MASK, 0x1));
+
+	regmap_update_bits(hdptx->regmap, SB_REG(010f), OVRD_SB_VREG_EN_MASK,
+			   FIELD_PREP(OVRD_SB_VREG_EN_MASK, 0x1));
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x1));
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x1));
+	usleep_range(20, 25);
+
+	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+	usleep_range(20, 25);
+	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+	usleep_range(20, 25);
+
+	regmap_update_bits(hdptx->regmap, SB_REG(0103), OVRD_SB_RX_RESCAL_DONE_MASK,
+			   FIELD_PREP(OVRD_SB_RX_RESCAL_DONE_MASK, 0x1));
+	usleep_range(100, 110);
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_EN_MASK,
+			   FIELD_PREP(SB_EN_MASK, 0x1));
+	usleep_range(100, 110);
+	regmap_update_bits(hdptx->regmap, SB_REG(0102), SB_RXTERM_EN_MASK,
+			   FIELD_PREP(SB_RXTERM_EN_MASK, 0x1));
+	usleep_range(20, 25);
+	regmap_update_bits(hdptx->regmap, SB_REG(010f), SB_VREG_EN_MASK,
+			   FIELD_PREP(SB_VREG_EN_MASK, 0x1));
+	usleep_range(20, 25);
+	regmap_update_bits(hdptx->regmap, SB_REG(0104), SB_AUX_EN_MASK,
+			   FIELD_PREP(SB_AUX_EN_MASK, 0x1));
+	usleep_range(100, 110);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
+				       status, FIELD_GET(HDPTX_O_SB_RDY, status),
+				       50, 1000);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get phy sb ready: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int rk_hdptx_phy_power_on(struct phy *phy)
 {
 	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
 	int bus_width = phy_get_bus_width(hdptx->phy);
-	int ret;
+	enum phy_mode mode = phy_get_mode(phy);
+	int ret, lane;
 
 	/*
 	 * FIXME: Temporary workaround to pass pixel_clk_rate
@@ -915,13 +1432,43 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
 		__func__, bus_width, rate);
 
-	ret = rk_hdptx_phy_consumer_get(hdptx, rate);
-	if (ret)
-		return ret;
+	if (mode == PHY_MODE_DP) {
+		rk_hdptx_dp_reset(hdptx);
 
-	ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
-	if (ret)
-		rk_hdptx_phy_consumer_put(hdptx, true);
+		for (lane = 0; lane < 4; lane++) {
+			regmap_update_bits(hdptx->regmap, LANE_REG(031e) + 0x400 * lane,
+					   LN_POLARITY_INV_MASK | LN_LANE_MODE_MASK,
+					   FIELD_PREP(LN_POLARITY_INV_MASK, 0) |
+					   FIELD_PREP(LN_LANE_MODE_MASK, 1));
+		}
+
+		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x1));
+
+		regmap_update_bits(hdptx->regmap, LNTOP_REG(0200), PROTOCOL_SEL,
+				   FIELD_PREP(PROTOCOL_SEL, 0x0));
+		regmap_update_bits(hdptx->regmap, LNTOP_REG(0206), DATA_BUS_WIDTH_MASK,
+				   FIELD_PREP(DATA_BUS_WIDTH_MASK, 0x1));
+		regmap_update_bits(hdptx->regmap, LNTOP_REG(0206), DATA_BUS_WIDTH_SEL_MASK,
+				   FIELD_PREP(DATA_BUS_WIDTH_SEL_MASK, 0x0));
+
+		rk_hdptx_dp_pll_init(hdptx);
+
+		ret = rk_hdptx_dp_aux_init(hdptx);
+		if (ret)
+			pm_runtime_put(hdptx->dev);
+	} else {
+		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
+
+		ret = rk_hdptx_phy_consumer_get(hdptx, rate);
+		if (ret)
+			return ret;
+
+		ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
+		if (ret)
+			rk_hdptx_phy_consumer_put(hdptx, true);
+	}
 
 	return ret;
 }
@@ -933,9 +1480,337 @@ static int rk_hdptx_phy_power_off(struct phy *phy)
 	return rk_hdptx_phy_consumer_put(hdptx, false);
 }
 
+static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode,
+				 int submode)
+{
+	return 0;
+}
+
+static int rk_hdptx_phy_verify_config(struct rk_hdptx_phy *hdptx,
+				      struct phy_configure_opts_dp *dp)
+{
+	int i;
+
+	if (dp->set_rate) {
+		switch (dp->link_rate) {
+		case 1620:
+		case 2700:
+		case 5400:
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	if (dp->set_lanes) {
+		switch (dp->lanes) {
+		case 0:
+		case 1:
+		case 2:
+		case 4:
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	if (dp->set_voltages) {
+		for (i = 0; i < dp->lanes; i++) {
+			if (dp->voltage[i] > 3 || dp->pre[i] > 3)
+				return -EINVAL;
+
+			if (dp->voltage[i] + dp->pre[i] > 3)
+				return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int rk_hdptx_phy_set_rate(struct rk_hdptx_phy *hdptx,
+				 struct phy_configure_opts_dp *dp)
+{
+	u32 bw, status;
+	int ret;
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
+
+	switch (dp->link_rate) {
+	case 1620:
+		bw = DP_BW_RBR;
+		break;
+	case 2700:
+		bw = DP_BW_HBR;
+		break;
+	case 5400:
+		bw = DP_BW_HBR2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0008), OVRD_LCPLL_EN_MASK | LCPLL_EN_MASK,
+			   FIELD_PREP(OVRD_LCPLL_EN_MASK, 0x1) |
+			   FIELD_PREP(LCPLL_EN_MASK, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(003d), OVRD_ROPLL_EN_MASK | ROPLL_EN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_EN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_EN_MASK, 0x1));
+
+	if (dp->ssc) {
+		regmap_update_bits(hdptx->regmap, CMN_REG(0074),
+				   OVRD_ROPLL_SSC_EN_MASK | ROPLL_SSC_EN_MASK,
+				   FIELD_PREP(OVRD_ROPLL_SSC_EN_MASK, 0x1) |
+				   FIELD_PREP(ROPLL_SSC_EN_MASK, 0x1));
+		regmap_write(hdptx->regmap, CMN_REG(0075),
+			     FIELD_PREP(ANA_ROPLL_SSC_FM_DEVIATION_MASK, 0xc));
+		regmap_update_bits(hdptx->regmap, CMN_REG(0076),
+				   ANA_ROPLL_SSC_FM_FREQ_MASK,
+				   FIELD_PREP(ANA_ROPLL_SSC_FM_FREQ_MASK, 0x1f));
+
+		regmap_update_bits(hdptx->regmap, CMN_REG(0099), SSC_EN_MASK,
+				   FIELD_PREP(SSC_EN_MASK, 0x2));
+	} else {
+		regmap_update_bits(hdptx->regmap, CMN_REG(0074),
+				   OVRD_ROPLL_SSC_EN_MASK | ROPLL_SSC_EN_MASK,
+				   FIELD_PREP(OVRD_ROPLL_SSC_EN_MASK, 0x1) |
+				   FIELD_PREP(ROPLL_SSC_EN_MASK, 0x0));
+		regmap_write(hdptx->regmap, CMN_REG(0075),
+			     FIELD_PREP(ANA_ROPLL_SSC_FM_DEVIATION_MASK, 0x20));
+		regmap_update_bits(hdptx->regmap, CMN_REG(0076),
+				   ANA_ROPLL_SSC_FM_FREQ_MASK,
+				   FIELD_PREP(ANA_ROPLL_SSC_FM_FREQ_MASK, 0xc));
+
+		regmap_update_bits(hdptx->regmap, CMN_REG(0099), SSC_EN_MASK,
+				   FIELD_PREP(SSC_EN_MASK, 0x0));
+	}
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0095), DP_TX_LINK_BW_MASK,
+			   FIELD_PREP(DP_TX_LINK_BW_MASK, bw));
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x1));
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
+				       status, FIELD_GET(HDPTX_O_PLL_LOCK_DONE, status),
+				       50, 1000);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get phy pll lock: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void rk_hdptx_phy_lane_disable(struct rk_hdptx_phy *hdptx)
+{
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+
+	regmap_update_bits(hdptx->regmap, LNTOP_REG(0207), LANE_EN,
+			   FIELD_PREP(LANE_EN, 0x0));
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0008), OVRD_LCPLL_EN_MASK | LCPLL_EN_MASK,
+			   FIELD_PREP(OVRD_LCPLL_EN_MASK, 0x1) |
+			   FIELD_PREP(LCPLL_EN_MASK, 0x0));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(003d), OVRD_ROPLL_EN_MASK | ROPLL_EN_MASK,
+			   FIELD_PREP(OVRD_ROPLL_EN_MASK, 0x1) |
+			   FIELD_PREP(ROPLL_EN_MASK, 0x0));
+}
+
+static int rk_hdptx_phy_set_lanes(struct rk_hdptx_phy *hdptx,
+				  struct phy_configure_opts_dp *dp)
+{
+	if (!dp->lanes) {
+		rk_hdptx_phy_lane_disable(hdptx);
+		return 0;
+	}
+
+	regmap_update_bits(hdptx->regmap, LNTOP_REG(0207), LANE_EN,
+			   FIELD_PREP(LANE_EN, GENMASK(dp->lanes - 1, 0)));
+
+	return 0;
+}
+
+static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
+				     struct phy_configure_opts_dp *dp,
+				     u8 lane)
+{
+	const struct tx_drv_ctrl *ctrl;
+	u32 offset = lane * 0x400;
+
+	switch (dp->link_rate) {
+	case 1620:
+		ctrl = &tx_drv_ctrl_rbr[dp->voltage[lane]][dp->pre[lane]];
+		regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
+				   LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
+				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
+				   ctrl->tx_jeq_even_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(030c) + offset,
+				   LN_TX_JEQ_ODD_CTRL_RBR_MASK,
+				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_RBR_MASK,
+				   ctrl->tx_jeq_odd_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
+				   LN_TX_SER_40BIT_EN_RBR_MASK,
+				   FIELD_PREP(LN_TX_SER_40BIT_EN_RBR_MASK, 0x1));
+		break;
+	case 2700:
+		ctrl = &tx_drv_ctrl_hbr[dp->voltage[lane]][dp->pre[lane]];
+		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
+				   LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
+				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
+				   ctrl->tx_jeq_even_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
+				   LN_TX_JEQ_ODD_CTRL_HBR_MASK,
+				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR_MASK,
+				   ctrl->tx_jeq_odd_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
+				   LN_TX_SER_40BIT_EN_HBR_MASK,
+				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR_MASK, 0x1));
+		break;
+	case 5400:
+	default:
+		ctrl = &tx_drv_ctrl_hbr2[dp->voltage[lane]][dp->pre[lane]];
+		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
+				   LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
+				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
+				   ctrl->tx_jeq_even_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
+				   LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
+				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
+				   ctrl->tx_jeq_odd_ctrl));
+		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
+				   LN_TX_SER_40BIT_EN_HBR2_MASK,
+				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1));
+		break;
+	}
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(0303) + offset,
+			   OVRD_LN_TX_DRV_LVL_CTRL_MASK | LN_TX_DRV_LVL_CTRL_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_LVL_CTRL_MASK, 0x1) |
+			   FIELD_PREP(LN_TX_DRV_LVL_CTRL_MASK,
+				      ctrl->tx_drv_lvl_ctrl));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0304) + offset,
+			   OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK |
+			   LN_TX_DRV_POST_LVL_CTRL_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_POST_LVL_CTRL_MASK, 0x1) |
+			   FIELD_PREP(LN_TX_DRV_POST_LVL_CTRL_MASK,
+				      ctrl->tx_drv_post_lvl_ctrl));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0305) + offset,
+			   OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK |
+			   LN_TX_DRV_PRE_LVL_CTRL_MASK,
+			   FIELD_PREP(OVRD_LN_TX_DRV_PRE_LVL_CTRL_MASK, 0x1) |
+			   FIELD_PREP(LN_TX_DRV_PRE_LVL_CTRL_MASK,
+				      ctrl->tx_drv_pre_lvl_ctrl));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0306) + offset,
+			   LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK |
+			   LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK |
+			   LN_ANA_TX_DRV_ACCDRV_EN_MASK,
+			   FIELD_PREP(LN_ANA_TX_DRV_IDRV_IDN_CTRL_MASK,
+				      ctrl->ana_tx_drv_idrv_idn_ctrl) |
+			   FIELD_PREP(LN_ANA_TX_DRV_IDRV_IUP_CTRL_MASK,
+				      ctrl->ana_tx_drv_idrv_iup_ctrl) |
+			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_EN_MASK,
+				      ctrl->ana_tx_drv_accdrv_en));
+	regmap_update_bits(hdptx->regmap, LANE_REG(0307) + offset,
+			   LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK |
+			   LN_ANA_TX_DRV_ACCDRV_CTRL_MASK,
+			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_POL_SEL_MASK, 0x1) |
+			   FIELD_PREP(LN_ANA_TX_DRV_ACCDRV_CTRL_MASK,
+				      ctrl->ana_tx_drv_accdrv_ctrl));
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
+			   LN_ANA_TX_JEQ_EN_MASK,
+			   FIELD_PREP(LN_ANA_TX_JEQ_EN_MASK, ctrl->ana_tx_jeq_en));
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(0310) + offset,
+			   LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK,
+			   FIELD_PREP(LN_ANA_TX_SYNC_LOSS_DET_MODE_MASK, 0x3));
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(0316) + offset,
+			   LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK,
+			   FIELD_PREP(LN_ANA_TX_SER_VREG_GAIN_CTRL_MASK, 0x2));
+
+	regmap_update_bits(hdptx->regmap, LANE_REG(031b) + offset,
+			   LN_ANA_TX_RESERVED_MASK,
+			   FIELD_PREP(LN_ANA_TX_RESERVED_MASK, 0x1));
+}
+
+static int rk_hdptx_phy_set_voltages(struct rk_hdptx_phy *hdptx,
+				     struct phy_configure_opts_dp *dp)
+{
+	u8 lane;
+	u32 status;
+	int ret;
+
+	for (lane = 0; lane < dp->lanes; lane++)
+		rk_hdptx_phy_set_voltage(hdptx, dp, lane);
+
+	reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
+				       status, FIELD_GET(HDPTX_O_PHY_RDY, status),
+				       50, 5000);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get phy ready: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
+	enum phy_mode mode = phy_get_mode(phy);
+	int ret;
+
+	if (mode != PHY_MODE_DP)
+		return -EINVAL;
+
+	ret = rk_hdptx_phy_verify_config(hdptx, &opts->dp);
+	if (ret) {
+		dev_err(hdptx->dev, "invalid params for phy configure\n");
+		return ret;
+	}
+
+	if (opts->dp.set_rate) {
+		ret = rk_hdptx_phy_set_rate(hdptx, &opts->dp);
+		if (ret) {
+			dev_err(hdptx->dev, "failed to set rate: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (opts->dp.set_lanes) {
+		ret = rk_hdptx_phy_set_lanes(hdptx, &opts->dp);
+		if (ret) {
+			dev_err(hdptx->dev, "failed to set lanes: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (opts->dp.set_voltages) {
+		ret = rk_hdptx_phy_set_voltages(hdptx, &opts->dp);
+		if (ret) {
+			dev_err(hdptx->dev, "failed to set voltages: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static const struct phy_ops rk_hdptx_phy_ops = {
 	.power_on  = rk_hdptx_phy_power_on,
 	.power_off = rk_hdptx_phy_power_off,
+	.set_mode  = rk_hdptx_phy_set_mode,
+	.configure = rk_hdptx_phy_configure,
 	.owner	   = THIS_MODULE,
 };
 
@@ -1149,5 +2024,6 @@ 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_AUTHOR("Damon Ding <damon.ding at rock-chips.com>");
 MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");
 MODULE_LICENSE("GPL");
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:55 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:55 +0800
Subject: [PATCH v3 06/15] drm/bridge: analogix_dp: Add support for RK3588
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-7-damon.ding@rock-chips.com>

Add max_link_rate and max_lane_count configs for RK3588.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index bfa88409a7ff..6f10d88a34c5 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1513,6 +1513,10 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
 		video_info->max_link_rate = 0x0A;
 		video_info->max_lane_count = 0x04;
 		break;
+	case RK3588_EDP:
+		video_info->max_link_rate = 0x14;
+		video_info->max_lane_count = 0x04;
+		break;
 	case EXYNOS_DP:
 		/*
 		 * NOTE: those property parseing code is used for
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:56 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:56 +0800
Subject: [PATCH v3 07/15] drm/bridge: analogix_dp: Add support for phy configuration.
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-8-damon.ding@rock-chips.com>

Add support to configurate link rate, lane count, voltage swing and
pre-emphasis with phy_configure(). It is helpful in application scenarios
where analogix controller is mixed with the phy of other vendors.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- remove needless assignments for phy_configure()
- remove unnecessary changes for phy_power_on()/phy_power_off()
---
 .../drm/bridge/analogix/analogix_dp_core.c    |  1 +
 .../gpu/drm/bridge/analogix/analogix_dp_reg.c | 56 +++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 6f10d88a34c5..9429c50cc1bc 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1696,6 +1696,7 @@ int analogix_dp_resume(struct analogix_dp_device *dp)
 	if (dp->plat_data->power_on)
 		dp->plat_data->power_on(dp->plat_data);
 
+	phy_set_mode(dp->phy, PHY_MODE_DP);
 	phy_power_on(dp->phy);
 
 	analogix_dp_init_dp(dp);
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 3afc73c858c4..613ce504bea6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -11,6 +11,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/phy/phy.h>
 
 #include <drm/bridge/analogix_dp.h>
 
@@ -513,10 +514,25 @@ void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
 void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
 {
 	u32 reg;
+	int ret;
 
 	reg = bwtype;
 	if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
 		writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
+
+	if (dp->phy) {
+		union phy_configure_opts phy_cfg = {0};
+
+		phy_cfg.dp.lanes = dp->link_train.lane_count;
+		phy_cfg.dp.link_rate =
+			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
+		phy_cfg.dp.set_rate = true;
+		ret = phy_configure(dp->phy, &phy_cfg);
+		if (ret && ret != -EOPNOTSUPP) {
+			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
+			return;
+		}
+	}
 }
 
 void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
@@ -530,9 +546,22 @@ void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
 void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
 {
 	u32 reg;
+	int ret;
 
 	reg = count;
 	writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
+
+	if (dp->phy) {
+		union phy_configure_opts phy_cfg = {0};
+
+		phy_cfg.dp.lanes = dp->link_train.lane_count;
+		phy_cfg.dp.set_lanes = true;
+		ret = phy_configure(dp->phy, &phy_cfg);
+		if (ret && ret != -EOPNOTSUPP) {
+			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
+			return;
+		}
+	}
 }
 
 void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
@@ -546,10 +575,37 @@ void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
 void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp)
 {
 	u8 lane;
+	int ret;
 
 	for (lane = 0; lane < dp->link_train.lane_count; lane++)
 		writel(dp->link_train.training_lane[lane],
 		       dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane);
+
+	if (dp->phy) {
+		union phy_configure_opts phy_cfg = {0};
+
+		for (lane = 0; lane < dp->link_train.lane_count; lane++) {
+			u8 training_lane = dp->link_train.training_lane[lane];
+			u8 vs, pe;
+
+			vs = (training_lane & DP_TRAIN_VOLTAGE_SWING_MASK) >>
+			     DP_TRAIN_VOLTAGE_SWING_SHIFT;
+			pe = (training_lane & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+			     DP_TRAIN_PRE_EMPHASIS_SHIFT;
+			phy_cfg.dp.voltage[lane] = vs;
+			phy_cfg.dp.pre[lane] = pe;
+		}
+
+		phy_cfg.dp.lanes = dp->link_train.lane_count;
+		phy_cfg.dp.link_rate =
+			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
+		phy_cfg.dp.set_voltages = true;
+		ret = phy_configure(dp->phy, &phy_cfg);
+		if (ret && ret != -EOPNOTSUPP) {
+			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
+			return;
+		}
+	}
 }
 
 u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane)
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:57 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:57 +0800
Subject: [PATCH v3 08/15] drm/rockchip: analogix_dp: Add support to get panel from the DP AUX bus
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-9-damon.ding@rock-chips.com>

The rockchip_dp_of_panel_on_aux_bus() helps to check whether the DT
configurations related to the DP AUX bus are correct or not.

If failed to get the panel from the platform bus, it is good to try
the DP AUX bus. Then, the probing process will continue until it enters
the analogix_dp_bind(), where devm_of_dp_aux_populate_bus() is called
after &analogix_dp_device.aux has been initialized.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 24 +++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index ba5263f85ee2..60c902abf40b 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -317,6 +317,24 @@ static const struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs =
 	.atomic_check = rockchip_dp_drm_encoder_atomic_check,
 };
 
+static bool rockchip_dp_of_panel_on_aux_bus(const struct device_node *np)
+{
+	struct device_node *bus_node, *panel_node;
+
+	bus_node = of_get_child_by_name(np, "aux-bus");
+	if (!bus_node)
+		return false;
+
+	panel_node = of_get_child_by_name(bus_node, "panel");
+	of_node_put(bus_node);
+	if (!panel_node)
+		return false;
+
+	of_node_put(panel_node);
+
+	return true;
+}
+
 static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
 {
 	struct device *dev = dp->dev;
@@ -435,8 +453,10 @@ static int rockchip_dp_probe(struct platform_device *pdev)
 		return -ENODEV;
 
 	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
-	if (ret < 0)
-		return ret;
+	if (ret < 0) {
+		if (!rockchip_dp_of_panel_on_aux_bus(dev->of_node))
+			return ret;
+	}
 
 	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
 	if (!dp)
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:58 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:58 +0800
Subject: [PATCH v3 09/15] drm/bridge: analogix_dp: Add support to get panel from the DP AUX bus
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-10-damon.ding@rock-chips.com>

If the panel can not be found in the beginning of rockchip_dp_probe()
using the platform bus, we can still try to find it in analogix_dp_bind()
through the DP AUX bus after the &analogix_dp_device.aux has been
initialized.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 .../drm/bridge/analogix/analogix_dp_core.c    | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 9429c50cc1bc..eae02819e3bb 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -19,12 +19,14 @@
 #include <linux/platform_device.h>
 
 #include <drm/bridge/analogix_dp.h>
+#include <drm/display/drm_dp_aux_bus.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_device.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>
@@ -1733,6 +1735,23 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
 		goto err_disable_pm_runtime;
 	}
 
+	if (!dp->plat_data->panel) {
+		/*
+		 * If the edp-panel module has not yet been initialized, the
+		 * devm_of_dp_aux_populate_bus() function will return 0 and
+		 * the done_probing() callback will not be called either.
+		 * Consequently, the panel will never be found.
+		 *
+		 * This is the reason why we do not use the done_probing()
+		 * callback and do not check the reture value here.
+		 */
+		devm_of_dp_aux_populate_bus(&dp->aux, NULL);
+		ret = drm_of_find_panel_or_bridge(dp->dev->of_node, 1, 0,
+						  &dp->plat_data->panel, NULL);
+		if (ret)
+			goto err_unregister_aux;
+	}
+
 	ret = analogix_dp_create_bridge(drm_dev, dp);
 	if (ret) {
 		DRM_ERROR("failed to create bridge (%d)\n", ret);
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:06:00 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:06:00 +0800
Subject: [PATCH v3 11/15] dt-bindings: display: rockchip: Fix label name of hdptxphy for RK3588 HDMI TX Controller
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-12-damon.ding@rock-chips.com>

The hdptxphy is a combo transmit-PHY for HDMI2.1 TMDS Link, FRL Link, DP
and eDP Link. Therefore, it is better to name it hdptxphy0 other than
hdptxphy_hdmi0, which will be referenced by both hdmi0 and edp0 nodes.

Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 .../bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
index d8e761865f27..7a1ae31cc535 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
@@ -156,7 +156,7 @@ examples:
                      <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>,
                      <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>;
         interrupt-names = "avp", "cec", "earc", "main", "hpd";
-        phys = <&hdptxphy_hdmi0>;
+        phys = <&hdptxphy0>;
         power-domains = <&power RK3588_PD_VO1>;
         resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>;
         reset-names = "ref", "hdp";
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:05:59 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:05:59 +0800
Subject: [PATCH v3 10/15] dt-bindings: display: rockchip: analogix-dp: Add support to get panel from the DP AUX bus
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-11-damon.ding@rock-chips.com>

According to Documentation/devicetree/bindings/display/dp-aux-bus.yaml,
it is a good way to get panel through the DP AUX bus.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 .../bindings/display/rockchip/rockchip,analogix-dp.yaml        | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
index 4f84e8849876..c45d92a2d901 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
@@ -49,6 +49,9 @@ properties:
     description:
       This SoC makes use of GRF regs.
 
+  aux-bus:
+    $ref: /schemas/display/dp-aux-bus.yaml#
+
 required:
   - compatible
   - clocks
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:06:01 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:06:01 +0800
Subject: [PATCH v3 12/15] arm64: dts: rockchip: Fix label name of hdptxphy for RK3588
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-13-damon.ding@rock-chips.com>

The hdptxphy is a combo transmit-PHY for HDMI2.1 TMDS Link, FRL Link, DP
and eDP Link. Therefore, it is better to name it hdptxphy0 other than
hdptxphy_hdmi0, which will be referenced by both hdmi0 and edp0 nodes.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi                 | 4 ++--
 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts        | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts    | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts              | 2 +-
 .../boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts      | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts                | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi            | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts       | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts               | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts          | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts            | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts      | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi           | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts            | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi          | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts              | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts              | 2 +-
 17 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index a337f3fb8377..7e125897b0cd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1386,7 +1386,7 @@ hdmi0: hdmi at fde80000 {
 			     <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>,
 			     <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>;
 		interrupt-names = "avp", "cec", "earc", "main", "hpd";
-		phys = <&hdptxphy_hdmi0>;
+		phys = <&hdptxphy0>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd
 			     &hdmim0_tx0_scl &hdmim0_tx0_sda>;
@@ -2806,7 +2806,7 @@ dmac2: dma-controller at fed10000 {
 		#dma-cells = <1>;
 	};
 
-	hdptxphy_hdmi0: phy at fed60000 {
+	hdptxphy0: phy at fed60000 {
 		compatible = "rockchip,rk3588-hdptx-phy";
 		reg = <0x0 0xfed60000 0x0 0x2000>;
 		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
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 9d525c8ff725..9eda69722665 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
@@ -129,7 +129,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
index 92f0ed83c990..d1be72eb63a4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-genbook.dts
@@ -166,7 +166,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
index d6e464cdc536..094235d22cd1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
@@ -328,7 +328,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
index b3a04ca370bb..8171fbfd819a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-friendlyelec-cm3588-nas.dts
@@ -335,7 +335,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
index 90f823b2c219..ef56380530f9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
@@ -303,7 +303,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
index cb350727d116..0d9b5020acc0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
@@ -360,7 +360,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
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 9f5a38b290bf..f14e96d96207 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
@@ -296,7 +296,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index c44d001da169..a047c579c93d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -220,7 +220,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
index 3187b4918a30..795d8175e654 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
@@ -189,7 +189,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
index 9c394f733bbf..f471baca6d31 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
@@ -236,7 +236,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index 4a3aa80f2226..74a4f03e05e3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -278,7 +278,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
index 76a6e8e517e9..482f5917043f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
@@ -251,7 +251,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
index 8f034c6d494c..1463bd36b1b2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
@@ -264,7 +264,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi
index d86aeacca238..9e16960b8705 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dtsi
@@ -197,7 +197,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 70a43432bdc5..676cc4fec269 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -334,7 +334,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 9b14d5383cdc..bf74789e3f51 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -278,7 +278,7 @@ hdmi0_out_con: endpoint {
 	};
 };
 
-&hdptxphy_hdmi0 {
+&hdptxphy0 {
 	status = "okay";
 };
 
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:06:02 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:06:02 +0800
Subject: [PATCH v3 13/15] arm64: dts: rockchip: Add eDP0 node for RK3588
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-14-damon.ding@rock-chips.com>

Add support for the eDP0 output on RK3588 SoC.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v3:
- Remove currently unsupported property '#sound-dai-cells'
---
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 7e125897b0cd..2a7b8e6074b8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1411,6 +1411,34 @@ hdmi0_out: port at 1 {
 		};
 	};
 
+	edp0: edp at fdec0000 {
+		compatible = "rockchip,rk3588-edp";
+		reg = <0x0 0xfdec0000 0x0 0x1000>;
+		clocks = <&cru CLK_EDP0_24M>, <&cru PCLK_EDP0>, <&cru CLK_EDP0_200M>;
+		clock-names = "dp", "pclk", "spdif";
+		interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>;
+		phys = <&hdptxphy0>;
+		phy-names = "dp";
+		power-domains = <&power RK3588_PD_VO1>;
+		resets = <&cru SRST_EDP0_24M>, <&cru SRST_P_EDP0>;
+		reset-names = "dp", "apb";
+		rockchip,grf = <&vo1_grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			edp0_in: port at 0 {
+				reg = <0>;
+			};
+
+			edp0_out: port at 1 {
+				reg = <1>;
+			};
+		};
+	};
+
 	qos_gpu_m0: qos at fdf35000 {
 		compatible = "rockchip,rk3588-qos", "syscon";
 		reg = <0x0 0xfdf35000 0x0 0x20>;
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:06:03 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:06:03 +0800
Subject: [PATCH v3 14/15] arm64: dts: rockchip: Enable eDP0 display on RK3588S EVB1 board
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-15-damon.ding@rock-chips.com>

Add the necessary DT changes to enable eDP0 on RK3588S EVB1 board:
- Add edp-panel node
- Set pinctrl of pwm12 for backlight
- Enable edp0/hdptxphy0/vp2

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v2:
- Remove brightness-levels and default-brightness-level properties in
  backlight node.
- Add the detail DT changes to commit message.

Changes in v3:
- Use aux-bus instead of platform bus for edp-panel.
---
 .../boot/dts/rockchip/rk3588s-evb1-v10.dts    | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
index bc4077575beb..9547ab18e596 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
@@ -9,6 +9,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include <dt-bindings/usb/pd.h>
 #include "rk3588s.dtsi"
 
@@ -238,6 +239,41 @@ &combphy2_psu {
 	status = "okay";
 };
 
+&edp0 {
+	force-hpd;
+	status = "okay";
+
+	aux-bus {
+		panel {
+			compatible = "lg,lp079qx1-sp0v";
+			backlight = <&backlight>;
+			power-supply = <&vcc3v3_lcd_edp>;
+
+			port {
+				panel_in_edp: endpoint {
+					remote-endpoint = <&edp_out_panel>;
+				};
+			};
+		};
+	};
+};
+
+&edp0_in {
+	edp0_in_vp2: endpoint {
+		remote-endpoint = <&vp2_out_edp0>;
+	};
+};
+
+&edp0_out {
+	edp_out_panel: endpoint {
+		remote-endpoint = <&panel_in_edp>;
+	};
+};
+
+&hdptxphy0 {
+	status = "okay";
+};
+
 &i2c3 {
 	status = "okay";
 
@@ -399,6 +435,7 @@ usbc0_int: usbc0-int {
 };
 
 &pwm12 {
+	pinctrl-0 = <&pwm12m1_pins>;
 	status = "okay";
 };
 
@@ -1168,3 +1205,18 @@ usbdp_phy0_dp_altmode_mux: endpoint at 1 {
 		};
 	};
 };
+
+&vop_mmu {
+	status = "okay";
+};
+
+&vop {
+	status = "okay";
+};
+
+&vp2 {
+	vp2_out_edp0: endpoint at ROCKCHIP_VOP2_EP_EDP0 {
+		reg = <ROCKCHIP_VOP2_EP_EDP0>;
+		remote-endpoint = <&edp0_in_vp2>;
+	};
+};
-- 
2.34.1



From damon.ding at rock-chips.com  Thu Dec 19 00:06:04 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Thu, 19 Dec 2024 16:06:04 +0800
Subject: [PATCH v3 15/15] arm64: dts: rockchip: Add eDP1 node for RK3588
In-Reply-To: <20241219080604.1423600-1-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
Message-ID: <20241219080604.1423600-16-damon.ding@rock-chips.com>

Add support for the eDP1 output on RK3588 SoC.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

Changes in v3:
- remove unexpected alias/hdptxphy1_grf/hdptxphy1 configurations
- remove currently unsupported property '#sound-dai-cells'
---
 .../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
index 0ce0934ec6b7..ad96fe25814e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -67,6 +67,11 @@ u2phy1_otg: otg-port {
 		};
 	};
 
+	hdptxphy1_grf: syscon at fd5e4000 {
+		compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
+		reg = <0x0 0xfd5e4000 0x0 0x100>;
+	};
+
 	i2s8_8ch: i2s at fddc8000 {
 		compatible = "rockchip,rk3588-i2s-tdm";
 		reg = <0x0 0xfddc8000 0x0 0x1000>;
@@ -135,6 +140,34 @@ i2s10_8ch: i2s at fde00000 {
 		status = "disabled";
 	};
 
+	edp1: edp at fded0000 {
+		compatible = "rockchip,rk3588-edp";
+		reg = <0x0 0xfded0000 0x0 0x1000>;
+		clocks = <&cru CLK_EDP1_24M>, <&cru PCLK_EDP1>, <&cru CLK_EDP1_200M>;
+		clock-names = "dp", "pclk", "spdif";
+		interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH 0>;
+		phys = <&hdptxphy1>;
+		phy-names = "dp";
+		power-domains = <&power RK3588_PD_VO1>;
+		resets = <&cru SRST_EDP1_24M>, <&cru SRST_P_EDP1>;
+		reset-names = "dp", "apb";
+		rockchip,grf = <&vo1_grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			edp1_in: port at 0 {
+				reg = <0>;
+			};
+
+			edp1_out: port at 1 {
+				reg = <1>;
+			};
+		};
+	};
+
 	pcie3x4: pcie at fe150000 {
 		compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
 		#address-cells = <3>;
@@ -395,6 +428,22 @@ sata-port at 0 {
 		};
 	};
 
+	hdptxphy1: phy at fed70000 {
+		compatible = "rockchip,rk3588-hdptx-phy";
+		reg = <0x0 0xfed70000 0x0 0x2000>;
+		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX1>;
+		clock-names = "ref", "apb";
+		#phy-cells = <0>;
+		resets = <&cru SRST_HDPTX1>, <&cru SRST_P_HDPTX1>,
+			 <&cru SRST_HDPTX1_INIT>, <&cru SRST_HDPTX1_CMN>,
+			 <&cru SRST_HDPTX1_LANE>, <&cru SRST_HDPTX1_ROPLL>,
+			 <&cru SRST_HDPTX1_LCPLL>;
+		reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
+			      "lcpll";
+		rockchip,grf = <&hdptxphy1_grf>;
+		status = "disabled";
+	};
+
 	usbdp_phy1: phy at fed90000 {
 		compatible = "rockchip,rk3588-usbdp-phy";
 		reg = <0x0 0xfed90000 0x0 0x10000>;
-- 
2.34.1



From ciprianmarian.costea at oss.nxp.com  Thu Dec 19 00:11:31 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Marian Costea)
Date: Thu, 19 Dec 2024 10:11:31 +0200
Subject: [PATCH v2] arm64: dts: s32g: add I2C support
In-Reply-To: <Z1yH7BFbYuJ++Vd1@lizhi-Precision-Tower-5810>
References: <20241213142250.2532559-1-ciprianmarian.costea@oss.nxp.com>
 <Z1yH7BFbYuJ++Vd1@lizhi-Precision-Tower-5810>
Message-ID: <a31ecf12-96f6-4e4b-854b-6b8ba40a3c38@oss.nxp.com>

On 12/13/2024 9:15 PM, Frank Li wrote:
> On Fri, Dec 13, 2024 at 04:22:50PM +0200, Ciprian Costea wrote:
>> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>>
>> Add the I2C Devicetree nodes and pinmux for S32G2 and S32G3 SoCs.
>>
>> With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
>> (rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
>> are quite similar. The common part for the EVB revisions will be
>> centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
>> be placed in 's32gxxa-rdb.dtsi' file.
>>
>> This refactor will also serve for other modules in the future, such as
>> FlexCAN, DSPI.
>>
>> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>> ---
> 
> Change log here!

Hello Frank,

Yes, I forgot to add it. I will add the changelog in V3.

> 
>>   arch/arm64/boot/dts/freescale/s32g2.dtsi      |  45 ++++++
>>   .../arm64/boot/dts/freescale/s32g274a-evb.dts |   1 +
> 
> Shawn require board dts should be seperate patch
> 

Sure. I can break the commit into two parts (common & board dts I2C 
support) in V3.

>>   .../boot/dts/freescale/s32g274a-rdb2.dts      |   1 +
>>   arch/arm64/boot/dts/freescale/s32g3.dtsi      |  50 ++++++
>>   .../boot/dts/freescale/s32g399a-rdb3.dts      |   9 ++
>>   .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
>>   .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 126 +++++++++++++++
>>   7 files changed, 382 insertions(+)
>>   create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>>   create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>>
>> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>> index 7be430b78c83..0e6c847ab0c3 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
>> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>> @@ -333,6 +333,33 @@ uart1: serial at 401cc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c0: i2c at 401e4000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x401e4000 0x1000>;
>> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c1: i2c at 401e8000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x401e8000 0x1000>;
>> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c2: i2c at 401ec000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x401ec000 0x1000>;
>> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		uart2: serial at 402bc000 {
>>   			compatible = "nxp,s32g2-linflexuart",
>>   				     "fsl,s32v234-linflexuart";
>> @@ -341,6 +368,24 @@ uart2: serial at 402bc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c3: i2c at 402d8000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x402d8000 0x1000>;
>> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c4: i2c at 402dc000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x402dc000 0x1000>;
>> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		usdhc0: mmc at 402f0000 {
>>   			compatible = "nxp,s32g2-usdhc";
>>   			reg = <0x402f0000 0x1000>;
>> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>> index b9a119eea2b7..c4a195dd67bf 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>> +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>> @@ -7,6 +7,7 @@
>>   /dts-v1/;
>>
>>   #include "s32g2.dtsi"
>> +#include "s32gxxxa-evb.dtsi"
>>
>>   / {
>>   	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
>> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
>> index aaa61a8ad0da..b5ba51696f43 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
>> +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
>> @@ -7,6 +7,7 @@
>>   /dts-v1/;
>>
>>   #include "s32g2.dtsi"
>> +#include "s32gxxxa-rdb.dtsi"
>>
>>   / {
>>   	model = "NXP S32G2 Reference Design Board 2 (S32G-VNP-RDB2)";
>> diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
>> index 6c572ffe37ca..666e4029e588 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
>> +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
>> @@ -390,6 +390,36 @@ uart1: serial at 401cc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c0: i2c at 401e4000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x401e4000 0x1000>;
>> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c1: i2c at 401e8000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x401e8000 0x1000>;
>> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c2: i2c at 401ec000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x401ec000 0x1000>;
>> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		uart2: serial at 402bc000 {
>>   			compatible = "nxp,s32g3-linflexuart",
>>   				     "fsl,s32v234-linflexuart";
>> @@ -398,6 +428,26 @@ uart2: serial at 402bc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c3: i2c at 402d8000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x402d8000 0x1000>;
>> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c4: i2c at 402dc000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x402dc000 0x1000>;
>> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		usdhc0: mmc at 402f0000 {
>>   			compatible = "nxp,s32g3-usdhc",
>>   				     "nxp,s32g2-usdhc";
>> diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
>> index 828e353455b5..5f8739c068c6 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
>> +++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
>> @@ -8,6 +8,7 @@
>>   /dts-v1/;
>>
>>   #include "s32g3.dtsi"
>> +#include "s32gxxxa-rdb.dtsi"
>>
>>   / {
>>   	model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
>> @@ -39,6 +40,14 @@ &uart1 {
>>   	status = "okay";
>>   };
>>
>> +&i2c4 {
>> +	ina231 at 40 {
>> +		compatible = "ti,ina231";
>> +		reg = <0x40>;
>> +		shunt-resistor = <1000>;
>> +	};
>> +};
>> +
>>   &usdhc0 {
>>   	pinctrl-names = "default", "state_100mhz", "state_200mhz";
>>   	pinctrl-0 = <&pinctrl_usdhc0>;
>> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>> new file mode 100644
>> index 000000000000..a44eff28073a
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>> @@ -0,0 +1,150 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
>> +/*
>> + * Copyright 2024 NXP
>> + *
>> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
>> + *          Larisa Grigore <larisa.grigore at nxp.com>
>> + */
>> +
>> +&pinctrl {
>> +	i2c0_pins: i2c0-pins {
>> +		i2c0-grp0 {
>> +			pinmux = <0x101>, <0x111>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c0-grp1 {
>> +			pinmux = <0x2352>, <0x2362>;
>> +		};
>> +	};
>> +
>> +	i2c0_gpio_pins: i2c0-gpio-pins {
>> +		i2c0-gpio-grp0 {
>> +			pinmux = <0x100>, <0x110>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c0-gpio-grp1 {
>> +			pinmux = <0x2350>, <0x2360>;
>> +		};
>> +	};
>> +
>> +	i2c1_pins: i2c1-pins {
>> +		i2c1-grp0 {
>> +			pinmux = <0x131>, <0x141>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c1-grp1 {
>> +			pinmux = <0x2cd2>, <0x2ce2>;
>> +		};
>> +	};
>> +
>> +	i2c1_gpio_pins: i2c1-gpio-pins {
>> +		i2c1-gpio-grp0 {
>> +			pinmux = <0x130>, <0x140>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c1-gpio-grp1 {
>> +			pinmux = <0x2cd0>, <0x2ce0>;
>> +		};
>> +	};
>> +
>> +	i2c2_pins: i2c2-pins {
>> +		i2c2-grp0 {
>> +			pinmux = <0x151>, <0x161>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c2-grp1 {
>> +			pinmux = <0x2cf2>, <0x2d02>;
>> +		};
>> +	};
>> +
>> +	i2c2_gpio_pins: i2c2-gpio-pins {
>> +		i2c2-gpio-grp0 {
>> +			pinmux = <0x150>, <0x160>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c2-gpio-grp1 {
>> +			pinmux = <0x2cf0>, <0x2d00>;
>> +		};
>> +	};
>> +
>> +	i2c4_pins: i2c4-pins {
>> +		i2c4-grp0 {
>> +			pinmux = <0x211>, <0x222>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c4-grp1 {
>> +			pinmux = <0x2d43>, <0x2d33>;
>> +		};
>> +	};
>> +
>> +	i2c4_gpio_pins: i2c4-gpio-pins {
>> +		i2c4-gpio-grp0 {
>> +			pinmux = <0x210>, <0x220>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c4-gpio-grp1 {
>> +			pinmux = <0x2d40>, <0x2d30>;
>> +		};
>> +	};
>> +};
>> +
>> +&i2c0 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c0_pins>;
>> +	pinctrl-1 = <&i2c0_gpio_pins>;
>> +	status = "okay";
>> +};
>> +
>> +&i2c1 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c1_pins>;
>> +	pinctrl-1 = <&i2c1_gpio_pins>;
>> +	status = "okay";
>> +};
>> +
>> +&i2c2 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c2_pins>;
>> +	pinctrl-1 = <&i2c2_gpio_pins>;
>> +	status = "okay";
>> +};
>> +
>> +&i2c4 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c4_pins>;
>> +	pinctrl-1 = <&i2c4_gpio_pins>;
>> +	status = "okay";
>> +};
>> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>> new file mode 100644
>> index 000000000000..50fe6aaa1605
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>> @@ -0,0 +1,126 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
>> +/*
>> + * Copyright 2024 NXP
>> + *
>> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
>> + *          Larisa Grigore <larisa.grigore at nxp.com>
>> + */
>> +
>> +&pinctrl {
>> +	i2c0_pins: i2c0-pins {
>> +		i2c0-grp0 {
>> +			pinmux = <0x1f2>, <0x201>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c0-grp1 {
>> +			pinmux = <0x2353>, <0x2363>;
>> +		};
>> +	};
>> +
>> +	i2c0_gpio_pins: i2c0-gpio-pins {
>> +		i2c0-gpio-grp0 {
>> +			pinmux = <0x1f0>, <0x200>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c0-gpio-grp1 {
>> +			pinmux = <0x2350>, <0x2360>;
>> +		};
>> +	};
>> +
>> +	i2c2_pins: i2c2-pins {
>> +		i2c2-grp0 {
>> +			pinmux = <0x151>, <0x161>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c2-grp1 {
>> +			pinmux = <0x2cf2>, <0x2d02>;
>> +		};
>> +	};
>> +
>> +	i2c2_gpio_pins: i2c2-gpio-pins {
>> +		i2c2-gpio-grp0 {
>> +			pinmux = <0x2cf0>, <0x2d00>;
>> +		};
>> +
>> +		i2c2-gpio-grp1 {
>> +			pinmux = <0x150>, <0x160>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +	};
>> +
>> +	i2c4_pins: i2c4-pins {
>> +		i2c4-grp0 {
>> +			pinmux = <0x211>, <0x222>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c4-grp1 {
>> +			pinmux = <0x2d43>, <0x2d33>;
>> +		};
>> +	};
>> +
>> +	i2c4_gpio_pins: i2c4-gpio-pins {
>> +		i2c4-gpio-grp0 {
>> +			pinmux = <0x210>, <0x220>;
>> +			drive-open-drain;
>> +			output-enable;
>> +			input-enable;
>> +			slew-rate = <133>;
>> +		};
>> +
>> +		i2c4-gpio-grp1 {
>> +			pinmux = <0x2d40>, <0x2d30>;
>> +		};
>> +	};
>> +};
>> +
>> +&i2c0 {
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
> 
> I remember I have said "#address-cells" and "#size-cells" should be in
> dtsi to avoid copy it at each board dts file.
> 
> Frank
> 

Yes, and I've moved them from board dts into a common board dtsi, which 
is the newly added 's32gxxxa-rdb.dtsi' as per commit description. This 
way I am not duplicating any such info in 's32g2.dtsi' and 's32g3.dtsi'.

Best Regards,
Ciprian

>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c0_pins>;
>> +	pinctrl-1 = <&i2c0_gpio_pins>;
>> +	status = "okay";
>> +
>> +	pcal6524: gpio-expander at 22 {
>> +		compatible = "nxp,pcal6524";
>> +		reg = <0x22>;
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +	};
>> +};
>> +
>> +&i2c2 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c2_pins>;
>> +	pinctrl-1 = <&i2c2_gpio_pins>;
>> +	status = "okay";
>> +};
>> +
>> +&i2c4 {
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c4_pins>;
>> +	pinctrl-1 = <&i2c4_gpio_pins>;
>> +	status = "okay";
>> +};
>> --
>> 2.45.2
>>



From krzysztof.kozlowski at linaro.org  Thu Dec 19 00:28:03 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 19 Dec 2024 09:28:03 +0100
Subject: [PATCH v3 02/15] dt-bindings: display: rockchip: analogix-dp:
 Add support for RK3588
In-Reply-To: <20241219080604.1423600-3-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-3-damon.ding@rock-chips.com>
Message-ID: <tdhs45ac2ivdke7idrzxrhlgsqlnswkb2maorau3guzrrwpce3@emdq7xx6cpwz>

On Thu, Dec 19, 2024 at 04:05:51PM +0800, Damon Ding wrote:
> Compared with RK3288/RK3399, the HBR2 link rate support is the main
> improvement of RK3588 eDP TX controller, and there are also two
> independent eDP display interfaces on RK3588 Soc.
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Drop, patch was very different.

> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> 
> ---
> 
> Changes in v2:
> - Add the main defferences of the RK3588 eDP and the previous versions
>   in commit message
> 
> Changes in v3:
> - expand the property clock-names, resets and reset-names

Adding new properties invalidates reviews. The patch is entirely, really
significantly different so keeping the review is not acceptable.

> ---
>  .../display/rockchip/rockchip,analogix-dp.yaml     | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> index 60dedf9b2be7..4f84e8849876 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> @@ -15,6 +15,7 @@ properties:
>      enum:
>        - rockchip,rk3288-dp
>        - rockchip,rk3399-edp
> +      - rockchip,rk3588-edp
>  
>    clocks:
>      minItems: 2
> @@ -25,16 +26,23 @@ properties:
>      items:
>        - const: dp
>        - const: pclk
> -      - const: grf
> +      - enum:
> +          - grf
> +          - spdif

No, this cannot be flexible for existing variants.

>  
>    power-domains:
>      maxItems: 1
>  
>    resets:
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 2

No, you must list the items.

>  
>    reset-names:
> -    const: dp
> +    minItems: 1
> +    items:
> +      - const: dp
> +      - enum:
> +          - apb

I don't understand what happened here but all this is NAK. Why suddenly
existing variants became different/changed? Nothing in commit msg
explains this.

Best regards,
Krzysztof



From krzk at kernel.org  Thu Dec 19 00:38:42 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 19 Dec 2024 09:38:42 +0100
Subject: [PATCH v4 1/3] dt-bindings: display: bcm2711-hdmi: Add interrupt
 details for BCM2712
In-Reply-To: <20241218-dt-bcm2712-fixes-v4-1-54cc88b6c229@raspberrypi.com>
References: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
 <20241218-dt-bcm2712-fixes-v4-1-54cc88b6c229@raspberrypi.com>
Message-ID: <7sgvdwyu2o7kli4eslg6o4mmzystoszrd6srw5pp6ikrmgq5ox@bvjz7j4d7v3l>

On Wed, Dec 18, 2024 at 02:48:32PM +0000, Dave Stevenson wrote:
> Commit 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
> added the compatible strings for BCM2712, but missed out that the
> number of interrupts changed.
> 
> Update the schema to include the interrupt requirements.
> 
> Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  .../bindings/display/brcm,bcm2711-hdmi.yaml        | 81 ++++++++++++++++++----
>  1 file changed, 67 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> index 6d11f5955b51..83c058728ef1 100644
> --- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
> @@ -56,22 +56,12 @@ properties:
>        - const: cec
>  
>    interrupts:
> -    items:
> -      - description: CEC TX interrupt
> -      - description: CEC RX interrupt
> -      - description: CEC stuck at low interrupt
> -      - description: Wake-up interrupt
> -      - description: Hotplug connected interrupt
> -      - description: Hotplug removed interrupt
> +    minItems: 5
> +    maxItems: 6
>  
>    interrupt-names:
> -    items:
> -      - const: cec-tx
> -      - const: cec-rx
> -      - const: cec-low
> -      - const: wakeup
> -      - const: hpd-connected
> -      - const: hpd-removed
> +    minItems: 5
> +    maxItems: 6
>  
>    ddc:
>      $ref: /schemas/types.yaml#/definitions/phandle
> @@ -112,6 +102,66 @@ required:
>  
>  additionalProperties: false
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - brcm,bcm2711-hdmi0
> +              - brcm,bcm2711-hdmi1
> +    then:
> +      properties:
> +        interrupts:
> +          items:
> +            - description: CEC TX interrupt
> +            - description: CEC RX interrupt
> +            - description: CEC stuck at low interrupt
> +            - description: Wake-up interrupt
> +            - description: Hotplug connected interrupt
> +            - description: Hotplug removed interrupt
> +        interrupt-names:
> +          items:
> +            - const: cec-tx
> +            - const: cec-rx
> +            - const: cec-low
> +            - const: wakeup
> +            - const: hpd-connected
> +            - const: hpd-removed
> +
> +

Only one blank line

> +      required:
> +        - interrupts
> +        - interrupt-names

But anyway this is unusual. Why this was added? Nothing in commit msg
explains this.

> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - brcm,bcm2712-hdmi0
> +              - brcm,bcm2712-hdmi1
> +    then:
> +      properties:
> +        interrupts:
> +          items:
> +            - description: CEC TX interrupt
> +            - description: CEC RX interrupt
> +            - description: CEC stuck at low interrupt
> +            - description: Hotplug connected interrupt
> +            - description: Hotplug removed interrupt
> +        interrupts-names:
> +          items:
> +            - const: cec-tx
> +            - const: cec-rx
> +            - const: cec-low
> +            - const: hpd-connected
> +            - const: hpd-removed
> +
> +      required:
> +        - interrupts
> +        - interrupt-names

Same question.

> +
>  examples:
>    - |
>      hdmi0: hdmi at 7ef00700 {
> @@ -136,6 +186,9 @@ examples:
>                      "hd";
>          clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
>          clock-names = "hdmi", "bvb", "audio", "cec";
> +        interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
> +        interrupt-names = "cec-tx", "cec-rx", "cec-low", "wakeup",
> +                "hpd-connected", "hpd-removed";

Fix alignment with opening " from earlier line (see DTS coding style).

Best regards,
Krzysztof



From krzk at kernel.org  Thu Dec 19 00:41:57 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 19 Dec 2024 09:41:57 +0100
Subject: [PATCH v4 2/3] dt-bindings: display: Fix BCM2835 HVS bindings
 for BCM2712
In-Reply-To: <20241218-dt-bcm2712-fixes-v4-2-54cc88b6c229@raspberrypi.com>
References: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
 <20241218-dt-bcm2712-fixes-v4-2-54cc88b6c229@raspberrypi.com>
Message-ID: <lzvcaspulvsulbulqinzftt3xtdyro64hi674u2bnkpvbrihri@e2o247mjom5s>

On Wed, Dec 18, 2024 at 02:48:33PM +0000, Dave Stevenson wrote:
> Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> added the compatible string for BCM2712, but missed out that
> the number of interrupts and clocks changed too, and both need to be
> named.
> 
> Update to validate clock, interrupts, and their names for the variants.
> 
> Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  .../bindings/display/brcm,bcm2835-hvs.yaml         | 84 ++++++++++++++++++----
>  1 file changed, 70 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> index f91c9dce2a44..fd25ee5ce301 100644
> --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> @@ -20,11 +20,20 @@ properties:
>      maxItems: 1
>  
>    interrupts:
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 3
> +
> +  interrupt-names:
> +    minItems: 1
> +    maxItems: 3
>  
>    clocks:
> -    maxItems: 1
> -    description: Core Clock
> +    minItems: 1
> +    maxItems: 2
> +
> +  clock-names:
> +    minItems: 1
> +    maxItems: 2
>  
>  required:
>    - compatible
> @@ -33,17 +42,64 @@ required:
>  
>  additionalProperties: false
>  
> -if:
> -  properties:
> -    compatible:
> -      contains:
> -        enum:
> -          - brcm,bcm2711-hvs
> -          - brcm,bcm2712-hvs
> -
> -then:
> -  required:
> -    - clocks
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: brcm,bcm2711-hvs
> +
> +    then:
> +      properties:
> +        clocks:
> +          items:
> +            - description: Core Clock
> +        interrupts:
> +          maxItems: 1


clock-names and interrupt-names: false, unless driver needs them but all
this should be explained in the commit msg because it would be a change
to the binding.

> +
> +      required:
> +        - clocks
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: brcm,bcm2712-hvs
> +
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 2
> +          maxItems: 2
> +        clock-names:
> +          items:
> +            - const: core
> +            - const: disp
> +        interrupts:
> +          items:
> +            - description: Channel 0 End of frame
> +            - description: Channel 1 End of frame
> +            - description: Channel 2 End of frame
> +        interrupt-names:
> +          items:
> +            - const: ch0-eof
> +            - const: ch1-eof
> +            - const: ch2-eof
> +      required:
> +        - clocks
> +        - clock-names
> +        - interrupt-names

My previous comment still stands. Reply to people's feedback instead of
ignoring it.

Best regards,
Krzysztof



From alexandre.torgue at foss.st.com  Thu Dec 19 00:53:58 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Thu, 19 Dec 2024 09:53:58 +0100
Subject: [PATCH 0/5] ARM: dts: stm32: add counter nodes on stm32mp13 and
 stm32mp15
In-Reply-To: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
References: <20241216153908.3069548-1-fabrice.gasnier@foss.st.com>
Message-ID: <11ea410e-a7df-4f1e-87df-8487b5532229@foss.st.com>

Hi Fabrice

On 12/16/24 16:39, Fabrice Gasnier wrote:
> Counter driver originally had support limited to quadrature interface
> and simple counter. It has been improved[1], so populate and enable
> stm32 timer counter nodes on stm32mp13 and stm32mp15.
> 
> [1] https://lore.kernel.org/linux-arm-kernel/20240307133306.383045-1-fabrice.gasnier at foss.st.com/
> 
> Fabrice Gasnier (5):
>    ARM: dts: stm32: populate all timer counter nodes on stm32mp13
>    ARM: dts: stm32: populate all timer counter nodes on stm32mp15
>    ARM: dts: stm32: add counter subnodes on stm32mp135f-dk
>    ARM: dts: stm32: add counter subnodes on stm32mp157c-ev1
>    ARM: dts: stm32: add counter subnodes on stm32mp157 dk boards
> 
>   arch/arm/boot/dts/st/stm32mp131.dtsi      | 40 ++++++++++++++++++++++
>   arch/arm/boot/dts/st/stm32mp135f-dk.dts   | 12 +++++++
>   arch/arm/boot/dts/st/stm32mp151.dtsi      | 41 +++++++++++++++++++++++
>   arch/arm/boot/dts/st/stm32mp157c-ev1.dts  |  9 +++++
>   arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi | 18 ++++++++++
>   5 files changed, 120 insertions(+)
> 

Series applied on stm32-next.

Thanks!
Alex


From krzk at kernel.org  Thu Dec 19 00:58:48 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 19 Dec 2024 09:58:48 +0100
Subject: [PATCH 1/2] dt-bindings: memory-controller: Document rev c.1.5
 compatible
In-Reply-To: <93a1333d-442f-4cec-b823-9b1a5ff6dc6b@broadcom.com>
References: <20241217194439.929040-1-florian.fainelli@broadcom.com>
 <20241217194439.929040-2-florian.fainelli@broadcom.com>
 <2e33t7ft5ermsfr7c4ympxrn6l5sqdef3wml4hlbnhdupoouwj@gfjpbmowjadi>
 <93a1333d-442f-4cec-b823-9b1a5ff6dc6b@broadcom.com>
Message-ID: <wxq5zzfh5jesucbbste2j6x2jtj45wjfc5xzjkqbqqta7cprda@oaf5arr3z6pt>

On Wed, Dec 18, 2024 at 09:15:08AM -0800, Florian Fainelli wrote:
> On 12/18/24 03:37, Krzysztof Kozlowski wrote:
> > On Tue, Dec 17, 2024 at 11:44:38AM -0800, Florian Fainelli wrote:
> > > Document the revision c.1.5 compatible string that is present on newer
> > > Broadcom STB memory controllers (74165 and onwards).
> > > 
> > > Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
> > > ---
> > >   .../bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml       | 1 +
> > >   1 file changed, 1 insertion(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
> > > index 4b072c879b02..99d79ccd1036 100644
> > > --- a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
> > > +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
> > > @@ -29,6 +29,7 @@ properties:
> > >             - brcm,brcmstb-memc-ddr-rev-c.1.2
> > >             - brcm,brcmstb-memc-ddr-rev-c.1.3
> > >             - brcm,brcmstb-memc-ddr-rev-c.1.4
> > > +          - brcm,brcmstb-memc-ddr-rev-c.1.5
> > 
> > You should use v2.1 fallback and drop driver patch. Or explain in
> > commit briefly why different approach is suitable.
> 
> Are you suggesting that we should have fallback compatible strings, such
> that we have something like this:
> 
> compatible = "brcm,brcmstb-memc-ddr-rev-c.1.5",
> "brcm,brcmstb-memc-ddr-rev-c", "brcm,brcmstb-memc-ddr"
> 
> and the driver only needs to match on "brcm,brcmstb-memc-ddr-rev-c" and
> apply the adequate register offset table?

Almost, fallback should be brcm,brcmstb-memc-ddr-rev-b.2.1 or whatever
was in the driver first or whatever is the oldest known common
interface.

brcm,brcmstb-memc-ddr-rev-c is not a specific compatible.

> If so, that is not how the current binding, and therefore DTBs are being
> deployed, so that will introduce a breakage until we update all DTBs in the
> field...

No. First, I thought about new comaptible so the one you add here. No
breakage, it's new compatible. This saves you these pointless updates of
driver everytime you add new compatible.

Second, you can introduce fallbacks to older compatibles as well - there
will be no breakage, because you add one more compatible. The old
compatibles (covered by fallback) of course stays in the driver, so
there is no breakage at all. We did it multiple times for several
different bindings in Qualcomm. People were doing exactly the same:
adding compatible for new device to binding and driver, without
considering the compatibility at all.

Except being logically correct choice - using fallbacks - this really
has huge benefits when later upstreaming complete, big SoCs, like we do
for latest Qualcomm SoCs: several changes will be only bindings updates.

Best regards,
Krzysztof



From alexandre.torgue at foss.st.com  Thu Dec 19 00:57:47 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Thu, 19 Dec 2024 09:57:47 +0100
Subject: [PATCH] ARM: dts: stm32: Swap USART3 and UART8 alias on
 STM32MP15xx DHCOM SoM
In-Reply-To: <20241213223658.99802-1-marex@denx.de>
References: <20241213223658.99802-1-marex@denx.de>
Message-ID: <a765a687-3d53-4ce8-aab3-e8a1d4adccf6@foss.st.com>

hi Marek

On 12/13/24 23:36, Marek Vasut wrote:
> Swap USART3 and UART8 aliases on STM32MP15xx DHCOM SoM,
> make sure UART8 is listed first, USART3 second, because
> the UART8 is labeled as UART2 on the SoM pinout, while
> USART3 is labeled as UART3 on the SoM pinout.
> 
> Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board")
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzk+dt at kernel.org>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Rob Herring <robh at kernel.org>
> Cc: devicetree at vger.kernel.org
> Cc: kernel at dh-electronics.com
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> ---
>   arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> index 086d3a60ccce2..142d4a8731f8d 100644
> --- a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> +++ b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
> @@ -15,8 +15,8 @@ aliases {
>   		rtc0 = &hwrtc;
>   		rtc1 = &rtc;
>   		serial0 = &uart4;
> -		serial1 = &usart3;
> -		serial2 = &uart8;
> +		serial1 = &uart8;
> +		serial2 = &usart3;
>   	};
>   
>   	chosen {


Applied on stm32-next.

Regards
Alex


From claudiu.beznea at tuxon.dev  Thu Dec 19 01:06:51 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Thu, 19 Dec 2024 11:06:51 +0200
Subject: [PATCH 0/2] Add address/size properties to spi-controller nodes
In-Reply-To: <20241218080333.2225-1-mihai.sain@microchip.com>
References: <20241218080333.2225-1-mihai.sain@microchip.com>
Message-ID: <347a8bb9-5a0c-405b-aa9b-01994aff8b53@tuxon.dev>



On 18.12.2024 10:03, Mihai Sain wrote:
> Mihai Sain (2):
>   ARM: dts: microchip: sam9x60: Add address/size to spi-controller nodes
>   ARM: dts: microchip: sam9x7: Add address/size to spi-controller nodes

Applied to at91-dt, thank you!


From claudiu.beznea at tuxon.dev  Thu Dec 19 01:07:10 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Thu, 19 Dec 2024 11:07:10 +0200
Subject: [PATCH 0/2] ARM: dts: microchip: Add no-1-8-v property to sdmmc0
 node
In-Reply-To: <20241119160107.598411-1-cristian.birsan@microchip.com>
References: <20241119160107.598411-1-cristian.birsan@microchip.com>
Message-ID: <1e2cb493-f645-4448-8df9-e6c19cb96a70@tuxon.dev>



On 19.11.2024 18:01, cristian.birsan at microchip.com wrote:
> Cristian Birsan (2):
>   ARM: dts: microchip: sama5d29_curiosity: Add no-1-8-v property to
>     sdmmc0 node
>   ARM: dts: microchip: sama5d27_wlsom1_ek: Add no-1-8-v property to
>     sdmmc0 node

Applied to at91-dt, thank you!


From csokas.bence at prolan.hu  Thu Dec 19 01:09:50 2024
From: csokas.bence at prolan.hu (=?UTF-8?B?Q3PDs2vDoXMgQmVuY2U=?=)
Date: Thu, 19 Dec 2024 10:09:50 +0100
Subject: [PATCH] spi: atmel-qspi: Memory barriers after memory-mapped I/O
In-Reply-To: <b1661e3f-cc62-489b-a4f8-9964ccf65fae@sirena.org.uk>
References: <20241218165850.378909-1-csokas.bence@prolan.hu>
 <b1661e3f-cc62-489b-a4f8-9964ccf65fae@sirena.org.uk>
Message-ID: <72874aa6-22c7-40a6-83bb-1ace0f3aec73@prolan.hu>

Right. I originally planned on splitting it into a cover letter and then 
the patch, but I guess everything can just go into the msg. Dropping the ---

Bence

On 2024. 12. 18. 18:01, Mark Brown wrote:
> On Wed, Dec 18, 2024 at 05:58:49PM +0100, Bence Cs?k?s wrote:
> 
>> However, the current documentation makes no mention to
>> synchronization requirements in the other direction, i.e.
>> after the last data written via AHB, and before the first
>> register access on APB.
>>
>> ---
>>
>> Fixes: d5433def3153 ("mtd: spi-nor: atmel-quadspi: Add spi-mem support to atmel-quadspi")
>> Cc: Hari.PrasathGE at microchip.com
>> Cc: Mahesh.Abotula at microchip.com
>> Cc: Marco.Cardellini at microchip.com
>> Cc: <stable at vger.kernel.org> # c0a0203cf579: ("spi: atmel-quadspi: Create `atmel_qspi_ops`"...)
>> Cc: <stable at vger.kernel.org> # 6.x.y
>> Signed-off-by: Bence Cs?k?s <csokas.bence at prolan.hu>
>> ---
> 
> Your signoffs and whatnot need to go before the --- so they don't get
> cut off by tools, any any ancilliary stuff should go after.



From csokas.bence at prolan.hu  Thu Dec 19 01:12:58 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?=)
Date: Thu, 19 Dec 2024 10:12:58 +0100
Subject: [PATCH v2] spi: atmel-qspi: Memory barriers after memory-mapped I/O
Message-ID: <20241219091258.395187-1-csokas.bence@prolan.hu>

The QSPI peripheral control and status registers are
accessible via the SoC's APB bus, whereas MMIO transactions'
data travels on the AHB bus.

Microchip documentation and even sample code from Atmel
emphasises the need for a memory barrier before the first
MMIO transaction to the AHB-connected QSPI, and before the
last write to its registers via APB. This is achieved by
the following lines in `atmel_qspi_transfer()`:

	/* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
	(void)atmel_qspi_read(aq, QSPI_IFR);

However, the current documentation makes no mention to
synchronization requirements in the other direction, i.e.
after the last data written via AHB, and before the first
register access on APB.

In our case, we were facing an issue where the QSPI peripheral
would cease to send any new CSR (nCS Rise) interrupts,
leading to a timeout in `atmel_qspi_wait_for_completion()`
and ultimately this panic in higher levels:

	ubi0 error: ubi_io_write: error -110 while writing 63108 bytes
 to PEB 491:128, written 63104 bytes

After months of extensive research of the codebase, fiddling
around the debugger with kgdb, and back-and-forth with
Microchip, we came to the conclusion that the issue is
probably that the peripheral is still busy receiving on AHB
when the LASTXFER bit is written to its Control Register
on APB, therefore this write gets lost, and the peripheral
still thinks there is more data to come in the MMIO transfer.
This was first formulated when we noticed that doubling the
write() of QSPI_CR_LASTXFER seemed to solve the problem.

Ultimately, the solution is to introduce memory barriers
after the AHB-mapped MMIO transfers, to ensure ordering.

Fixes: d5433def3153 ("mtd: spi-nor: atmel-quadspi: Add spi-mem support to atmel-quadspi")
Cc: Hari.PrasathGE at microchip.com
Cc: Mahesh.Abotula at microchip.com
Cc: Marco.Cardellini at microchip.com
Cc: <stable at vger.kernel.org> # c0a0203cf579: ("spi: atmel-quadspi: Create `atmel_qspi_ops`"...)
Cc: <stable at vger.kernel.org> # 6.x.y
Signed-off-by: Bence Cs?k?s <csokas.bence at prolan.hu>
---

Notes:
    Changes in v2:
    * dropping --- from commit msg

 drivers/spi/atmel-quadspi.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index 73cf0c3f1477..96fc1c56a221 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -625,13 +625,20 @@ static int atmel_qspi_transfer(struct spi_mem *mem,
 	(void)atmel_qspi_read(aq, QSPI_IFR);
 
 	/* Send/Receive data */
-	if (op->data.dir == SPI_MEM_DATA_IN)
+	if (op->data.dir == SPI_MEM_DATA_IN) {
 		memcpy_fromio(op->data.buf.in, aq->mem + offset,
 			      op->data.nbytes);
-	else
+
+		/* Synchronize AHB and APB accesses again */
+		rmb();
+	} else {
 		memcpy_toio(aq->mem + offset, op->data.buf.out,
 			    op->data.nbytes);
 
+		/* Synchronize AHB and APB accesses again */
+		wmb();
+	}
+
 	/* Release the chip-select */
 	atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
 
-- 
2.34.1




From eichest at gmail.com  Thu Dec 19 01:19:05 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Thu, 19 Dec 2024 10:19:05 +0100
Subject: [PATCH v1] i2c: imx: fix missing stop condition in single-master
 mode
In-Reply-To: <w3x46is2s463ektusvnyu5tt2rinz7eae2ekzyqw2urw5yh5ga@pfzrgzpxjc4y>
References: <20241216151829.74056-1-eichest@gmail.com>
 <w3x46is2s463ektusvnyu5tt2rinz7eae2ekzyqw2urw5yh5ga@pfzrgzpxjc4y>
Message-ID: <Z2PlCXSG8qt5_3ni@eichest-laptop>

Hi Andi,

On Wed, Dec 18, 2024 at 07:16:23PM +0100, Andi Shyti wrote:
> Hi Stefan,
> 
> On Mon, Dec 16, 2024 at 04:16:40PM +0100, Stefan Eichenberger wrote:
> > From: Stefan Eichenberger <stefan.eichenberger at toradex.com>
> > 
> > A regression was introduced with the implementation of single-master
> > mode, preventing proper stop conditions from being generated. Devices
> > that require a valid stop condition, such as EEPROMs, fail to function
> > correctly as a result.
> > 
> > The issue only affects devices with the single-master property enabled.
> > 
> > This commit resolves the issue by re-enabling I2C bus busy bit (IBB)
> > polling for single-master mode when generating a stop condition. The fix
> > further ensures that the i2c_imx->stopped flag is cleared at the start
> > of each transfer, allowing the stop condition to be correctly generated
> > in i2c_imx_stop().
> > 
> > According to the reference manual (IMX8MMRM, Rev. 2, 09/2019, page
> > 5270), polling the IBB bit to determine if the bus is free is only
> > necessary in multi-master mode. Consequently, the IBB bit is not polled
> > for the start condition in single-master mode.
> > 
> > Fixes: 6692694aca86 ("i2c: imx: do not poll for bus busy in single master mode")
> > Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>
> > ---
> >  drivers/i2c/busses/i2c-imx.c | 8 +++-----
> >  1 file changed, 3 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> > index f751d231ded8..cbf66a69e20b 100644
> > --- a/drivers/i2c/busses/i2c-imx.c
> > +++ b/drivers/i2c/busses/i2c-imx.c
> > @@ -534,20 +534,18 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a
> >  {
> >  	unsigned long orig_jiffies = jiffies;
> >  	unsigned int temp;
> > -
> > -	if (!i2c_imx->multi_master)
> > -		return 0;
> > +	bool multi_master = i2c_imx->multi_master;
> 
> with this small adjustment, I have applied your patch to 
> i2c/i2c-host-fixes.
> 
> The idea behind the change is that variables are sorted by 
> length, forming a kind of reversed Christmas tree shape. It's 
> not a strict rule?some communities enforce it, others don't, and 
> some follow entirely different conventions.
> 
> Since it feels somewhat arbitrary to me, I don't enforce it 
> strictly. However, I personally try to adhere to the reversed 
> Christmas tree rule whenever possible.

Thanks a lot for doing the change and for the explanation. I will keep
it in mind for future patches.

Best regards,
Stefan


From danishanwar at ti.com  Thu Dec 19 01:19:55 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Thu, 19 Dec 2024 14:49:55 +0530
Subject: [PATCH net-next 2/4] net: ti: icssg-prueth: Add VLAN support in
 EMAC mode
In-Reply-To: <Z2PE5m8R5lM4/YRT@mev-dev.igk.intel.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-3-danishanwar@ti.com>
 <Z2PE5m8R5lM4/YRT@mev-dev.igk.intel.com>
Message-ID: <06886be4-5f35-4785-bc63-a5c84887adfb@ti.com>



On 19/12/24 12:32 pm, Michal Swiatkowski wrote:
> On Mon, Dec 16, 2024 at 03:30:42PM +0530, MD Danish Anwar wrote:
>> Add support for vlan filtering in dual EMAC mode.
>>
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> ---
>>  drivers/net/ethernet/ti/icssg/icssg_prueth.c | 29 +++++++++-----------
>>  1 file changed, 13 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> index c568c84a032b..e031bccf31dc 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> @@ -822,19 +822,18 @@ static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev,
>>  {
>>  	struct prueth_emac *emac = netdev_priv(ndev);
>>  	struct prueth *prueth = emac->prueth;
>> +	int port_mask = BIT(emac->port_id);
>>  	int untag_mask = 0;
>> -	int port_mask;
>>  
>> -	if (prueth->is_hsr_offload_mode) {
>> -		port_mask = BIT(PRUETH_PORT_HOST) | BIT(emac->port_id);
>> -		untag_mask = 0;
>> +	if (prueth->is_hsr_offload_mode)
>> +		port_mask |= BIT(PRUETH_PORT_HOST);
>>  
>> -		netdev_dbg(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
>> -			   vid, port_mask, untag_mask);
>> +	netdev_err(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
>> +		   vid, port_mask, untag_mask);
>> +
>> +	icssg_vtbl_modify(emac, vid, port_mask, untag_mask, true);
>> +	icssg_set_pvid(emac->prueth, vid, emac->port_id);
>>  
>> -		icssg_vtbl_modify(emac, vid, port_mask, untag_mask, true);
>> -		icssg_set_pvid(emac->prueth, vid, emac->port_id);
>> -	}
>>  	return 0;
>>  }
>>  
>> @@ -843,18 +842,16 @@ static int emac_ndo_vlan_rx_del_vid(struct net_device *ndev,
>>  {
>>  	struct prueth_emac *emac = netdev_priv(ndev);
>>  	struct prueth *prueth = emac->prueth;
>> +	int port_mask = BIT(emac->port_id);
>>  	int untag_mask = 0;
>> -	int port_mask;
>>  
>> -	if (prueth->is_hsr_offload_mode) {
>> +	if (prueth->is_hsr_offload_mode)
>>  		port_mask = BIT(PRUETH_PORT_HOST);
>> -		untag_mask = 0;
>>  
>> -		netdev_dbg(emac->ndev, "VID del vid:%u port_mask:%X untag_mask  %X\n",
>> -			   vid, port_mask, untag_mask);
>> +	netdev_err(emac->ndev, "VID del vid:%u port_mask:%X untag_mask  %X\n",
>> +		   vid, port_mask, untag_mask);
> Why error? It doesn't look like error path, previously there was
> netdev_dbg (made more sense in my opinion)
> 

My bad. It should be netdev_dbg(). I'll change it in v2. Thanks

>> +	icssg_vtbl_modify(emac, vid, port_mask, untag_mask, false);
>>  
>> -		icssg_vtbl_modify(emac, vid, port_mask, untag_mask, false);
>> -	}
>>  	return 0;
>>  }
>>  
>> -- 
>> 2.34.1

-- 
Thanks and Regards,
Danish


From gankulkarni at os.amperecomputing.com  Thu Dec 19 01:30:11 2024
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Thu, 19 Dec 2024 15:00:11 +0530
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer
 expired
In-Reply-To: <4d443db1-85b1-4071-acd5-3187deb9cb17@redhat.com>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
 <867c89tc4q.wl-maz@kernel.org>
 <c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
 <865xntt2kv.wl-maz@kernel.org>
 <8be59ff3-6a68-48e1-8181-0ce4b2e7180f@os.amperecomputing.com>
 <bcb4289b-507c-4ea1-afc7-6febd34d88db@redhat.com>
 <86y10osr19.wl-maz@kernel.org>
 <4d443db1-85b1-4071-acd5-3187deb9cb17@redhat.com>
Message-ID: <2f6b2cb1-3d32-480a-9801-9b993ae74e2d@os.amperecomputing.com>



On 09-12-2024 11:04 pm, Eric Auger wrote:
> Hi Marc,
> 
> On 12/9/24 18:30, Marc Zyngier wrote:
>> On Mon, 09 Dec 2024 16:46:30 +0000,
>> Eric Auger <eauger at redhat.com> wrote:
>>>
>>> Hi,
>>>
>>> On 12/9/24 16:39, Ganapatrao Kulkarni wrote:
>>>>
>>>>
>>>> On 09-12-2024 06:50 pm, Marc Zyngier wrote:
>>>>> On Mon, 09 Dec 2024 12:25:34 +0000,
>>>>> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
>>>>>>>>
>>>>>>>> During automated testing of Nested Virtualization using avocado-vt,
>>>>>>>
>>>>>>> Which is not merged upstream. So what branch are you using? Based on
>>>>>>> what kernel version? On what HW? With which virtualisation features?
>>>>>>>
>>>>>>
>>>>>> Testing is done on Ampere's AmpereOne platform using 6.10 based kernel
>>>>>> with NV patches from your repo.
>>>>>
>>>>> Grmbl... *Which* patches? At least give me the SHA1 of the branch,
>>>>> because I have no idea what you are running. And 6.10 is definitely
>>>>> not something I care about. If you're using the NV patches, the
>>>>> *minimum* you should run is 6.13-rc1, because that's what the current
>>>>> code is based on.
>>>>>
>>>>
>>>> I tried 6.13-rc1 based nv-next branch today, which failed to boot
>>>> UEFI as L1. Yet to debug this.
>>>
>>> I confirm am stuck with the same issue with nv-next on AmpereOne.
>>
>> All I can say is that it Works For Me (TM) on M2 and Snapdragon, using
>> kvmtool, a fresh EDK2 built by Ard, and with the guest running purely
>> VHE (FEAT_E2H0 not implemented).
>>
>> I haven't tried QEMU, I don't have an AmpereOne. I have also spent way
>> too much time on this recently. So I'm afraid people interested in
>> making this particular combination work will have to debug it.
> 
> yes I do agree. I am currently setting up kvmtool to double check and I
> will debug the qemu issue.

I could boot Guest-hypervisor using QEMU with -bios and nv-next as L0 
with edk2 (QEMU_EFI.fd) built from upstream tree and fedora-41 as 
Guest-Hypervisor.

The issue was disappeared when upgraded from fc39 to fc41. Same was 
experienced with the kvmtool boot as well(KVMTOOL_EFI.fd).

-- 
Thanks,
Ganapat/GK



From alexandre.torgue at foss.st.com  Thu Dec 19 01:28:39 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Thu, 19 Dec 2024 10:28:39 +0100
Subject: [PATCH v4 00/15] media: stm32: introduction of CSI / DCMIPP for
 STM32MP25
In-Reply-To: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
References: <20241212-csi_dcmipp_mp25-v4-0-fbeb55a05ed7@foss.st.com>
Message-ID: <b6d92560-1bcc-4c9f-be1e-a5b7056f788a@foss.st.com>

Hi Alain

On 12/12/24 10:17, Alain Volmat wrote:
> This series introduces the camera pipeline support for the
> STM32MP25 SOC.  The STM32MP25 has 3 pipelines, fed from a
> single camera input which can be either parallel or csi.
> 
> This series adds the basic support for the 1st pipe (dump)
> which, in term of features is same as the one featured on
> the STM32MP13 SOC.  It focuses on introduction of the
> CSI input stage for the DCMIPP, and the CSI specific new
> control code for the DCMIPP.
> One of the subdev of the DCMIPP, dcmipp_parallel is now
> renamed as dcmipp_input since it allows to not only control
> the parallel but also the csi interface.
> 
> Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> ---
> Changes in v4:
> * stm32-dcmipp: correct patch 13/15 with clk error handling in
>    dcmipp_runtime_resume function
> - Link to v3: https://lore.kernel.org/r/20241118-csi_dcmipp_mp25-v3-0-c1914afb0a0f at foss.st.com
> 
> Changes in v3:
> * stm32-csi: use clk_bulk api
> * stm32-csiL perform reset control within the probe
> - Link to v2: https://lore.kernel.org/r/20241105-csi_dcmipp_mp25-v2-0-b9fc8a7273c2 at foss.st.com
> 
> ---
> Alain Volmat (15):
>        media: stm32: dcmipp: correct dma_set_mask_and_coherent mask value
>        dt-bindings: media: add description of stm32 csi
>        media: stm32: csi: addition of the STM32 CSI driver
>        media: stm32: dcmipp: use v4l2_subdev_is_streaming
>        media: stm32: dcmipp: replace s_stream with enable/disable_streams
>        media: stm32: dcmipp: rename dcmipp_parallel into dcmipp_input
>        media: stm32: dcmipp: add support for csi input into dcmipp-input
>        media: stm32: dcmipp: add bayer 10~14 bits formats
>        media: stm32: dcmipp: add 1X16 RGB / YUV formats support
>        media: stm32: dcmipp: avoid duplicated format on enum in bytecap
>        media: stm32: dcmipp: fill media ctl hw_revision field
>        dt-bindings: media: add the stm32mp25 compatible of DCMIPP
>        media: stm32: dcmipp: add core support for the stm32mp25
>        arm64: dts: st: add csi & dcmipp node in stm32mp25
>        arm64: dts: st: enable imx335/csi/dcmipp pipeline on stm32mp257f-ev1

DT patches applied on stm32-next (as drivers and dt-bindings patches are 
in linux-next branch).

Thanks
Alex


From danishanwar at ti.com  Thu Dec 19 01:36:18 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Thu, 19 Dec 2024 15:06:18 +0530
Subject: [PATCH net-next 3/4] net: ti: icssg-prueth: Add Multicast
 Filtering support for VLAN in MAC mode
In-Reply-To: <Z2PLDqqrLdXhLtAF@mev-dev.igk.intel.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-4-danishanwar@ti.com>
 <Z2PLDqqrLdXhLtAF@mev-dev.igk.intel.com>
Message-ID: <cb319ffd-ac67-42b3-9786-e8c9970086d2@ti.com>



On 19/12/24 12:58 pm, Michal Swiatkowski wrote:
> On Mon, Dec 16, 2024 at 03:30:43PM +0530, MD Danish Anwar wrote:
>> Add multicast filtering support for VLAN interfaces in dual EMAC mode
>> for ICSSG driver.
>>
>> The driver uses vlan_for_each() API to get the list of available
>> vlans. The driver then sync mc addr of vlan interface with a locally
>> mainatined list emac->vlan_mcast_list[vid] using __hw_addr_sync_multiple()
>> API.
>>
>> The driver then calls the sync / unsync callbacks and based on whether
>> the ndev is vlan or not, driver passes appropriate vid to FDB helper
>> functions.
>>
>> This commit also exports __hw_addr_sync_multiple() in order to use it
>> from the ICSSG driver.
>>
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> ---
>>  drivers/net/ethernet/ti/icssg/icssg_prueth.c | 69 ++++++++++++++++----
>>  drivers/net/ethernet/ti/icssg/icssg_prueth.h |  6 ++
>>  include/linux/netdevice.h                    |  3 +
>>  net/core/dev_addr_lists.c                    |  7 +-
>>  4 files changed, 68 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> index e031bccf31dc..a18773ef6eab 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
>> @@ -472,30 +472,43 @@ const struct icss_iep_clockops prueth_iep_clockops = {
>>  
>>  static int icssg_prueth_add_mcast(struct net_device *ndev, const u8 *addr)
>>  {
>> -	struct prueth_emac *emac = netdev_priv(ndev);
>> -	int port_mask = BIT(emac->port_id);
>> +	struct net_device *real_dev;
>> +	struct prueth_emac *emac;
>> +	int port_mask;
>> +	u8 vlan_id;
>>  
>> -	port_mask |= icssg_fdb_lookup(emac, addr, 0);
>> -	icssg_fdb_add_del(emac, addr, 0, port_mask, true);
>> -	icssg_vtbl_modify(emac, 0, port_mask, port_mask, true);
>> +	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
>> +	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
> Looks like a helper for that can be nice to have.
>

I don't think that's neccessary. vlan_dev_real_dev() itself is a helper
function to give the real dev, only down side is vlan_dev_real_dev()
assumes that the dev is vlan only.

In this function, we don't know if ndev is vlan or not, hence the check.
Most drivers are using vlan_dev_real_dev() the same way.


>> +	emac = netdev_priv(real_dev);
>> +
>> +	port_mask = BIT(emac->port_id) | icssg_fdb_lookup(emac, addr, vlan_id);
>> +	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, true);
>> +	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, true);
>>  
>>  	return 0;
>>  }
>>  
>>  static int icssg_prueth_del_mcast(struct net_device *ndev, const u8 *addr)
>>  {
>> -	struct prueth_emac *emac = netdev_priv(ndev);
>> -	int port_mask = BIT(emac->port_id);
>> +	struct net_device *real_dev;
>> +	struct prueth_emac *emac;
>>  	int other_port_mask;
>> +	int port_mask;
>> +	u8 vlan_id;
>> +
>> +	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
>> +	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
>> +	emac = netdev_priv(real_dev);
>>  
>> -	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, 0);
>> +	port_mask = BIT(emac->port_id);
>> +	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, vlan_id);
>>  
>> -	icssg_fdb_add_del(emac, addr, 0, port_mask, false);
>> -	icssg_vtbl_modify(emac, 0, port_mask, port_mask, false);
>> +	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, false);
>> +	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, false);
>>  
>>  	if (other_port_mask) {
>> -		icssg_fdb_add_del(emac, addr, 0, other_port_mask, true);
>> -		icssg_vtbl_modify(emac, 0, other_port_mask, other_port_mask, true);
>> +		icssg_fdb_add_del(emac, addr, vlan_id, other_port_mask, true);
>> +		icssg_vtbl_modify(emac, vlan_id, other_port_mask, other_port_mask, true);
>>  	}
>>  
>>  	return 0;
>> @@ -531,6 +544,28 @@ static int icssg_prueth_hsr_del_mcast(struct net_device *ndev, const u8 *addr)
>>  	return 0;
>>  }
>>  
>> +static int icssg_update_vlan_mcast(struct net_device *vdev, int vid,
>> +				   void *args)
>> +{
>> +	struct net_device *vport_ndev;
>> +	struct prueth_emac *emac;
>> +
>> +	if (!vdev || !vid)
>> +		return 0;
>> +
>> +	vport_ndev = vlan_dev_real_dev(vdev);
>> +	emac = netdev_priv(vport_ndev);
>> +
>> +	netif_addr_lock_bh(vdev);
>> +	__hw_addr_sync_multiple(&emac->vlan_mcast_list[vid], &vdev->mc, vdev->addr_len);
> Only question, why dev_mc_sync_multiple can't be used here?
> 

dev_mc_sync_multiple() doesn't work here.

Let's say we call dev_mc_sync_multiple() with emac->ndev (the netdevice
for current port say eth1) and vdev (the netdevice for the vlan
interface say eth1.x with x being the vid).

Now dev_mc_sync_multiple() will sync the mc list from vdev to ndev. And
ndev will have the address added to vdev. After this set_rx_mode() gets
called for ndev. Which eventually calls sync / unsync APIs
icssg_prueth_add/del_mcast.

Now in this API, we will have the address to add but we won't have the vid.

The sync/unsync API will be called for the emac->ndev (the *to* device)
and emac->ndev will have no information about vid. Since it is not a
vlan dev and is_vlan_dev() will be false for it as a result we will
fallback to default vid.

	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) :
PRUETH_DFLT_VLAN_HSR;

We don't want this. We want to capture the correct vid. Hence sync /
unsync needs to get called for the vlan device i.e. vdev.

Due to this dev_mc_sync_multiple() doesn't work and we need to call
__hw_addr_sync_multiple and __hw_addr_sync_dev on vdev so that our sync
/ unsync APIs are called for vdev.


>> +	netif_addr_unlock_bh(vdev);
>> +
>> +	__hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
>> +			   icssg_prueth_add_mcast, icssg_prueth_del_mcast);
>> +
>> +	return 0;
>> +}
>> +
>>  /**
>>   * emac_ndo_open - EMAC device open
>>   * @ndev: network adapter device
>> @@ -772,12 +807,17 @@ static void emac_ndo_set_rx_mode_work(struct work_struct *work)
>>  		return;
>>  	}
>>  
>> -	if (emac->prueth->is_hsr_offload_mode)
>> +	if (emac->prueth->is_hsr_offload_mode) {
>>  		__dev_mc_sync(ndev, icssg_prueth_hsr_add_mcast,
>>  			      icssg_prueth_hsr_del_mcast);
>> -	else
>> +	} else {
>>  		__dev_mc_sync(ndev, icssg_prueth_add_mcast,
>>  			      icssg_prueth_del_mcast);
>> +		if (rtnl_trylock()) {
>> +			vlan_for_each(ndev, icssg_update_vlan_mcast, NULL);
>> +			rtnl_unlock();
>> +		}
>> +	}
>>  }
>>  
>>  /**
>> @@ -828,6 +868,7 @@ static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev,
>>  	if (prueth->is_hsr_offload_mode)
>>  		port_mask |= BIT(PRUETH_PORT_HOST);
>>  
>> +	__hw_addr_init(&emac->vlan_mcast_list[vid]);
>>  	netdev_err(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
>>  		   vid, port_mask, untag_mask);
>>  
>> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> index f5c1d473e9f9..4da8b87408b5 100644
>> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
>> @@ -83,6 +83,10 @@
>>  #define ICSS_CMD_ADD_FILTER 0x7
>>  #define ICSS_CMD_ADD_MAC 0x8
>>  
>> +/* VLAN Filtering Related MACROs */
>> +#define PRUETH_DFLT_VLAN_MAC	0
>> +#define MAX_VLAN_ID		256
>> +
>>  /* In switch mode there are 3 real ports i.e. 3 mac addrs.
>>   * however Linux sees only the host side port. The other 2 ports
>>   * are the switch ports.
>> @@ -201,6 +205,8 @@ struct prueth_emac {
>>  	/* RX IRQ Coalescing Related */
>>  	struct hrtimer rx_hrtimer;
>>  	unsigned long rx_pace_timeout_ns;
>> +
>> +	struct netdev_hw_addr_list vlan_mcast_list[MAX_VLAN_ID];
>>  };
>>  
>>  /**
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index d917949bba03..a5c169b19543 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -4685,6 +4685,9 @@ int devm_register_netdev(struct device *dev, struct net_device *ndev);
>>  /* General hardware address lists handling functions */
>>  int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
>>  		   struct netdev_hw_addr_list *from_list, int addr_len);
>> +int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
>> +			    struct netdev_hw_addr_list *from_list,
>> +			    int addr_len);
>>  void __hw_addr_unsync(struct netdev_hw_addr_list *to_list,
>>  		      struct netdev_hw_addr_list *from_list, int addr_len);
>>  int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
>> diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
>> index 166e404f7c03..90716bd736f3 100644
>> --- a/net/core/dev_addr_lists.c
>> +++ b/net/core/dev_addr_lists.c
>> @@ -242,9 +242,9 @@ static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list,
>>  	__hw_addr_del_entry(from_list, ha, false, false);
>>  }
>>  
>> -static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
>> -				   struct netdev_hw_addr_list *from_list,
>> -				   int addr_len)
>> +int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
>> +			    struct netdev_hw_addr_list *from_list,
>> +			    int addr_len)
>>  {
>>  	int err = 0;
>>  	struct netdev_hw_addr *ha, *tmp;
>> @@ -260,6 +260,7 @@ static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
>>  	}
>>  	return err;
>>  }
>> +EXPORT_SYMBOL(__hw_addr_sync_multiple);
>>  
>>  /* This function only works where there is a strict 1-1 relationship
>>   * between source and destination of they synch. If you ever need to
>> -- 
>> 2.34.1

-- 
Thanks and Regards,
Danish


From krzk at kernel.org  Thu Dec 19 01:47:22 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 19 Dec 2024 10:47:22 +0100
Subject: [PATCH v5 15/20] dt-bindings: clock: imx8m-clock: support spread
 spectrum clocking
In-Reply-To: <CABGWkvoQzAhpVJ+QRfVZeps-Jn8REGF+21SPN=f24Tdf1d5DDQ@mail.gmail.com>
References: <20241205111939.1796244-1-dario.binacchi@amarulasolutions.com>
 <20241205111939.1796244-16-dario.binacchi@amarulasolutions.com>
 <gbymcmoya7dfmedq4nkopqpswh63d2ujxl2elc2x7x325b75bu@anp36sdya43v>
 <CABGWkvoQzAhpVJ+QRfVZeps-Jn8REGF+21SPN=f24Tdf1d5DDQ@mail.gmail.com>
Message-ID: <27f5b3a4-8e79-4648-8603-13cce068bfe6@kernel.org>

On 08/12/2024 17:47, Dario Binacchi wrote:
>>>    '#clock-cells':
>>>      const: 1
>>> @@ -43,6 +43,34 @@ properties:
>>>        ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8m-clock.h
>>>        for the full list of i.MX8M clock IDs.
>>>
>>> +  fsl,ssc-modfreq-hz:
>>> +    description:
>>> +      The values of modulation frequency (Hz unit) for each clock
>>> +      supporting spread spectrum.
>>> +    minItems: 7
>>> +    maxItems: 10
>>
>> Why all cloks receive now spread spectrum? I had impression - and all
>> your previous versions were doing this - that you have only three or
>> four clocks with SSC.
> 
> Exactly. Indeed, the first six values are not valid as SSC properties but are
> only used to reach the point where the first PLL with SSC (i.e., audio_pll1)
> can be indexed, which is in position 7 in the clocks list.
> This was the rationale I followed.
> And it is explicitly outlined in the example section.
> The "" for the fsl,ssc-method property is precisely aimed at specifying a
> "no SSC" method, which also fixes the warning:
> 
> fsl,ssc-method:0: '' is not one of ['down-spread', 'up-spread', 'center-spread']
> 
> raised by
> make dt_binding_check DT_SCHEMA_FILES=imx8m-clock.yaml
> 
> Or would it be acceptable to specify a list of SSC values that applies only to
> the last 4 PLLs in the clocks list?

Lists are strictly ordered, so their items are known. You take some
clocks, of which last clocks are "foo" and "bar". Then you have new
property for configuring SSC for clocks - again list - "foo" and "bar".

> 
> I feel like I might be missing something.
> 
> Could you kindly suggest what to do or provide a DTS example to show me
> what you expect?

Best regards,
Krzysztof


From tabba at google.com  Thu Dec 19 01:49:31 2024
From: tabba at google.com (Fuad Tabba)
Date: Thu, 19 Dec 2024 09:49:31 +0000
Subject: [PATCH v4 17/18] KVM: arm64: Introduce the EL1 pKVM MMU
In-Reply-To: <20241218194059.3670226-18-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com> <20241218194059.3670226-18-qperret@google.com>
Message-ID: <CA+EHjTymHPQGwLLpsWzYf1zHpnQKu4mV54Bz3U9HWf3Jb8TcqA@mail.gmail.com>

Hi Quentin

On Wed, 18 Dec 2024 at 19:41, Quentin Perret <qperret at google.com> wrote:
>
> Introduce a set of helper functions allowing to manipulate the pKVM
> guest stage-2 page-tables from EL1 using pKVM's HVC interface.
>
> Each helper has an exact one-to-one correspondance with the traditional
> kvm_pgtable_stage2_*() functions from pgtable.c, with a strictly
> matching prototype. This will ease plumbing later on in mmu.c.
>
> These callbacks track the gfn->pfn mappings in a simple rb_tree indexed
> by IPA in lieu of a page-table. This rb-tree is kept in sync with pKVM's
> state and is protected by the mmu_lock like a traditional stage-2
> page-table.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Minor nits (feel free to ignore). Apart from that, and despite that
for_each_mapping_in_range_safe macro:

Tested-by: Fuad Tabba <tabba at google.com>
Reviewed-by: Fuad Tabba <tabba at google.com>


> ---
>  arch/arm64/include/asm/kvm_host.h    |   1 +
>  arch/arm64/include/asm/kvm_pgtable.h |  23 +--
>  arch/arm64/include/asm/kvm_pkvm.h    |  26 ++++
>  arch/arm64/kvm/pkvm.c                | 201 +++++++++++++++++++++++++++
>  4 files changed, 242 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 1246f1d01dbf..f23f4ea9ec8b 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -85,6 +85,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
>  struct kvm_hyp_memcache {
>         phys_addr_t head;
>         unsigned long nr_pages;
> +       struct pkvm_mapping *mapping; /* only used from EL1 */
>  };
>
>  static inline void push_hyp_memcache(struct kvm_hyp_memcache *mc,
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 04418b5e3004..6b9d274052c7 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -412,15 +412,20 @@ static inline bool kvm_pgtable_walk_lock_held(void)
>   *                     be used instead of block mappings.
>   */
>  struct kvm_pgtable {
> -       u32                                     ia_bits;
> -       s8                                      start_level;
> -       kvm_pteref_t                            pgd;
> -       struct kvm_pgtable_mm_ops               *mm_ops;
> -
> -       /* Stage-2 only */
> -       struct kvm_s2_mmu                       *mmu;
> -       enum kvm_pgtable_stage2_flags           flags;
> -       kvm_pgtable_force_pte_cb_t              force_pte_cb;
> +       union {
> +               struct rb_root                                  pkvm_mappings;
> +               struct {
> +                       u32                                     ia_bits;
> +                       s8                                      start_level;
> +                       kvm_pteref_t                            pgd;
> +                       struct kvm_pgtable_mm_ops               *mm_ops;
> +
> +                       /* Stage-2 only */
> +                       enum kvm_pgtable_stage2_flags           flags;
> +                       kvm_pgtable_force_pte_cb_t              force_pte_cb;
> +               };
> +       };
> +       struct kvm_s2_mmu                                       *mmu;
>  };
>
>  /**
> diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> index cd56acd9a842..65f988b6fe0d 100644
> --- a/arch/arm64/include/asm/kvm_pkvm.h
> +++ b/arch/arm64/include/asm/kvm_pkvm.h
> @@ -137,4 +137,30 @@ static inline size_t pkvm_host_sve_state_size(void)
>                         SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_sve_max_vl)));
>  }
>
> +struct pkvm_mapping {
> +       struct rb_node node;
> +       u64 gfn;
> +       u64 pfn;
> +};
> +
> +int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
> +                            struct kvm_pgtable_mm_ops *mm_ops);
> +void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
> +int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
> +                           enum kvm_pgtable_prot prot, void *mc,
> +                           enum kvm_pgtable_walk_flags flags);
> +int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +int pkvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold);
> +int pkvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
> +                                   enum kvm_pgtable_walk_flags flags);
> +void pkvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
> +                                enum kvm_pgtable_walk_flags flags);
> +int pkvm_pgtable_stage2_split(struct kvm_pgtable *pgt, u64 addr, u64 size,
> +                             struct kvm_mmu_memory_cache *mc);
> +void pkvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level);
> +kvm_pte_t *pkvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
> +                                              enum kvm_pgtable_prot prot, void *mc,
> +                                              bool force_pte);
>  #endif /* __ARM64_KVM_PKVM_H__ */
> diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
> index 85117ea8f351..930b677eb9b0 100644
> --- a/arch/arm64/kvm/pkvm.c
> +++ b/arch/arm64/kvm/pkvm.c
> @@ -7,6 +7,7 @@
>  #include <linux/init.h>
>  #include <linux/kmemleak.h>
>  #include <linux/kvm_host.h>
> +#include <asm/kvm_mmu.h>
>  #include <linux/memblock.h>
>  #include <linux/mutex.h>
>  #include <linux/sort.h>
> @@ -268,3 +269,203 @@ static int __init finalize_pkvm(void)
>         return ret;
>  }
>  device_initcall_sync(finalize_pkvm);
> +
> +static int cmp_mappings(struct rb_node *node, const struct rb_node *parent)
> +{
> +       struct pkvm_mapping *a = rb_entry(node, struct pkvm_mapping, node);
> +       struct pkvm_mapping *b = rb_entry(parent, struct pkvm_mapping, node);
> +
> +       if (a->gfn < b->gfn)
> +               return -1;
> +       if (a->gfn > b->gfn)
> +               return 1;
> +       return 0;
> +}
> +
> +static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
> +{
> +       struct rb_node *node = root->rb_node, *prev = NULL;
> +       struct pkvm_mapping *mapping;
> +
> +       while (node) {
> +               mapping = rb_entry(node, struct pkvm_mapping, node);
> +               if (mapping->gfn == gfn)
> +                       return node;
> +               prev = node;
> +               node = (gfn < mapping->gfn) ? node->rb_left : node->rb_right;
> +       }
> +
> +       return prev;
> +}
> +
> +/*
> + * __tmp is updated to rb_next(__tmp) *before* entering the body of the loop to allow freeing
> + * of __map inline.
> + */
> +#define for_each_mapping_in_range_safe(__pgt, __start, __end, __map)                           \
> +       for (struct rb_node *__tmp = find_first_mapping_node(&(__pgt)->pkvm_mappings,           \
> +                                                            ((__start) >> PAGE_SHIFT));        \
> +            __tmp && ({                                                                        \
> +                               __map = rb_entry(__tmp, struct pkvm_mapping, node);             \
> +                               __tmp = rb_next(__tmp);                                         \
> +                               true;                                                           \
> +                      });                                                                      \
> +           )                                                                                   \
> +               if (__map->gfn < ((__start) >> PAGE_SHIFT))                                     \
> +                       continue;                                                               \
> +               else if (__map->gfn >= ((__end) >> PAGE_SHIFT))                                 \
> +                       break;                                                                  \
> +               else
> +
> +int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
> +                            struct kvm_pgtable_mm_ops *mm_ops)
> +{
> +       pgt->pkvm_mappings      = RB_ROOT;
> +       pgt->mmu                = mmu;
> +
> +       return 0;
> +}
> +
> +void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt)
> +{
> +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> +       pkvm_handle_t handle = kvm->arch.pkvm.handle;
> +       struct pkvm_mapping *mapping;
> +       struct rb_node *node;
> +
> +       if (!handle)
> +               return;
> +
> +       node = rb_first(&pgt->pkvm_mappings);
> +       while (node) {
> +               mapping = rb_entry(node, struct pkvm_mapping, node);
> +               kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
> +               node = rb_next(node);
> +               rb_erase(&mapping->node, &pgt->pkvm_mappings);
> +               kfree(mapping);
> +       }
> +}
> +
> +int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
> +                          u64 phys, enum kvm_pgtable_prot prot,
> +                          void *mc, enum kvm_pgtable_walk_flags flags)
> +{
> +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> +       struct pkvm_mapping *mapping = NULL;
> +       struct kvm_hyp_memcache *cache = mc;
> +       u64 gfn = addr >> PAGE_SHIFT;
> +       u64 pfn = phys >> PAGE_SHIFT;

Is it worth using the gpa_to_gfn and __phys_to_pfn helpers? Might
obscure rather than help, but something to think about.

> +       int ret;
> +
> +       if (size != PAGE_SIZE)
> +               return -EINVAL;
> +
> +       lockdep_assert_held_write(&kvm->mmu_lock);
> +       ret = kvm_call_hyp_nvhe(__pkvm_host_share_guest, pfn, gfn, prot);
> +       if (ret) {
> +               /* Is the gfn already mapped due to a racing vCPU? */
> +               if (ret == -EPERM)
> +                       return -EAGAIN;
> +       }
> +
> +       swap(mapping, cache->mapping);
> +       mapping->gfn = gfn;
> +       mapping->pfn = pfn;
> +       WARN_ON(rb_find_add(&mapping->node, &pgt->pkvm_mappings, cmp_mappings));

In addition to the warning, is it better to return an error as well?

Cheers,
/fuad


> +       return ret;
> +}
> +
> +int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> +       pkvm_handle_t handle = kvm->arch.pkvm.handle;
> +       struct pkvm_mapping *mapping;
> +       int ret = 0;
> +
> +       lockdep_assert_held_write(&kvm->mmu_lock);
> +       for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) {
> +               ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
> +               if (WARN_ON(ret))
> +                       break;
> +               rb_erase(&mapping->node, &pgt->pkvm_mappings);
> +               kfree(mapping);
> +       }
> +
> +       return ret;
> +}
> +
> +int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> +       pkvm_handle_t handle = kvm->arch.pkvm.handle;
> +       struct pkvm_mapping *mapping;
> +       int ret = 0;
> +
> +       lockdep_assert_held(&kvm->mmu_lock);
> +       for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) {
> +               ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn);
> +               if (WARN_ON(ret))
> +                       break;
> +       }
> +
> +       return ret;
> +}
> +
> +int pkvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> +       struct pkvm_mapping *mapping;
> +
> +       lockdep_assert_held(&kvm->mmu_lock);
> +       for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping)
> +               __clean_dcache_guest_page(pfn_to_kaddr(mapping->pfn), PAGE_SIZE);
> +
> +       return 0;
> +}
> +
> +bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold)
> +{
> +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> +       pkvm_handle_t handle = kvm->arch.pkvm.handle;
> +       struct pkvm_mapping *mapping;
> +       bool young = false;
> +
> +       lockdep_assert_held(&kvm->mmu_lock);
> +       for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping)
> +               young |= kvm_call_hyp_nvhe(__pkvm_host_test_clear_young_guest, handle, mapping->gfn,
> +                                          mkold);
> +
> +       return young;
> +}
> +
> +int pkvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
> +                                   enum kvm_pgtable_walk_flags flags)
> +{
> +       return kvm_call_hyp_nvhe(__pkvm_host_relax_perms_guest, addr >> PAGE_SHIFT, prot);
> +}
> +
> +void pkvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
> +                                enum kvm_pgtable_walk_flags flags)
> +{
> +       WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_mkyoung_guest, addr >> PAGE_SHIFT));
> +}
> +
> +void pkvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
> +{
> +       WARN_ON_ONCE(1);
> +}
> +
> +kvm_pte_t *pkvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
> +                                       enum kvm_pgtable_prot prot, void *mc, bool force_pte)
> +{
> +       WARN_ON_ONCE(1);
> +       return NULL;
> +}
> +
> +int pkvm_pgtable_stage2_split(struct kvm_pgtable *pgt, u64 addr, u64 size,
> +                             struct kvm_mmu_memory_cache *mc)
> +{
> +       WARN_ON_ONCE(1);
> +       return -EINVAL;
> +}
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From granquet at baylibre.com  Thu Dec 19 01:51:16 2024
From: granquet at baylibre.com (Guillaume Ranquet)
Date: Thu, 19 Dec 2024 03:51:16 -0600
Subject: [PATCH v3 1/1] drm/mediatek: Add return value check when reading DPCD
In-Reply-To: <20241218113448.2992-1-liankun.yang@mediatek.com>
References: <20241218113448.2992-1-liankun.yang@mediatek.com>
Message-ID: <CABnWg9uvQ4_vxYx-_8AKE_CvLgKd04LuvS1qvKwyMHvBck7_cw@mail.gmail.com>

On Wed, 18 Dec 2024 12:34, Liankun Yang <liankun.yang at mediatek.com> wrote:
>Returns the number of bytes transferred (1) on success.
Hi Liankun,

I'm not sure this statement above is true, you are not returning the
number of transferred bytes?


Aside of that little nitpick

Reviewed-by: Guillaume Ranquet <granquet at baylibre.com>

>Check the return value to confirm that AUX communication is successful.
>
>Fixes: f70ac097a2cf ("drm/mediatek: Add MT8195 Embedded DisplayPort driver")
>
>Signed-off-by: Liankun Yang <liankun.yang at mediatek.com>
>---
>Changes in V3:
>- Using drm_dp_read_sink_count() to improve patch.
>Per suggestion from the previous thread:
>https://patchwork.kernel.org/project/linux-mediatek/patch/20241128030940.25657-1-liankun.yang at mediatek.com/
>
>Changes in V2:
>- Modify Fixes in Commit Message.
>Per suggestion from the previous thread:
>https://patchwork.kernel.org/project/linux-mediatek/patch/20240930092000.5385-1-liankun.yang at mediatek.com/
>---
> drivers/gpu/drm/mediatek/mtk_dp.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
>diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
>index 36713c176cfc..b26dad8783be 100644
>--- a/drivers/gpu/drm/mediatek/mtk_dp.c
>+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
>@@ -2100,7 +2100,6 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
> 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
> 	enum drm_connector_status ret = connector_status_disconnected;
> 	bool enabled = mtk_dp->enabled;
>-	u8 sink_count = 0;
>
> 	if (!mtk_dp->train_info.cable_plugged_in)
> 		return ret;
>@@ -2115,8 +2114,8 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
> 	 * function, we just need to check the HPD connection to check
> 	 * whether we connect to a sink device.
> 	 */
>-	drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
>-	if (DP_GET_SINK_COUNT(sink_count))
>+
>+	if (drm_dp_read_sink_count(&mtk_dp->aux))
> 		ret = connector_status_connected;
>
> 	if (!enabled)
>--
>2.45.2


From maz at kernel.org  Thu Dec 19 01:51:23 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 09:51:23 +0000
Subject: [PATCH v4 2/3] KVM: arm64: Introduce hypercall support for retrieving target implementations
In-Reply-To: <20241218105345.73472-3-shameerali.kolothum.thodi@huawei.com>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
	<20241218105345.73472-3-shameerali.kolothum.thodi@huawei.com>
Message-ID: <86cyhoq9us.wl-maz@kernel.org>

Hi Shameer,

On Wed, 18 Dec 2024 10:53:44 +0000,
Shameer Kolothum <shameerali.kolothum.thodi at huawei.com> wrote:
> 
> If the Guest requires migration to multiple targets, this hypercall
> will provide a way to retrieve the target CPU implementations from
> the user space VMM.
> 
> Subsequent patch will use this to enable the associated errata.
> 
> Suggested-by: Oliver Upton <oliver.upton at linux.dev>
> Reviewed-by: Sebastian Ott <sebott at redhat.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  Documentation/virt/kvm/arm/hypercalls.rst | 30 +++++++++++++++++++++++
>  include/linux/arm-smccc.h                 |  7 ++++++
>  2 files changed, 37 insertions(+)
> 
> diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
> index af7bc2c2e0cb..16b4c02cf9d9 100644
> --- a/Documentation/virt/kvm/arm/hypercalls.rst
> +++ b/Documentation/virt/kvm/arm/hypercalls.rst
> @@ -142,3 +142,33 @@ region is equal to the memory protection granule advertised by
>  |                     |          |    +---------------------------------------------+
>  |                     |          |    | ``INVALID_PARAMETER (-3)``                  |
>  +---------------------+----------+----+---------------------------------------------+
> +
> +``ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID``
> +-------------------------------------------------------
> +
> +Request the target CPU implementation information for the Guest VM. This hypercall
> +must be handled by the userspace VMM. The Guest kernel will use this information to
> +enable the associated errata. A maximum of 64 implementations is supported.

In the interest of being able to support this long term, I really
think there should be a separate function returning:

- the version of the extension, modelled after the PSCI versioning

- how many different implementations the extension supports

This would avoid hardcoding this 'maximum of 64 implementations' in
the spec, and allow us to add new ID registers if they are added in
the future.

> +
> ++---------------------+-------------------------------------------------------------+
> +| Presence:           | Optional;  KVM/ARM64 Guests only                            |
> ++---------------------+-------------------------------------------------------------+
> +| Calling convention: | HVC64                                                       |
> ++---------------------+----------+--------------------------------------------------+
> +| Function ID:        | (uint32) | 0xC600007E                                       |
> ++---------------------+----------+----+---------------------------------------------+
> +| Arguments:          | (uint64) | R1 | selected implementation index               |
> +|                     +----------+----+---------------------------------------------+
> +|                     | (uint64) | R2 | Reserved / Must be zero                     |
> +|                     +----------+----+---------------------------------------------+
> +|                     | (uint64) | R3 | Reserved / Must be zero                     |
> ++---------------------+----------+----+---------------------------------------------+
> +| Return Values:      | (int64)  | R0 | -1 on error else the maximum required CPU   |
> +|                     |          |    | implementation index.                       |

With the above introduced, this can be simplified to always return
"SUCCESS (0)" or "INVALID_PARAMETERS (-3)". Please use the SMCCC names
to describe standard return values (see section 7.1 in the spec).

> +|                     +----------+----+---------------------------------------------+
> +|                     | (uint64) | R1 | MIDR_EL1 of the selected implementation     |
> +|                     +----------+----+---------------------------------------------+
> +|                     | (uint64) | R2 | REVIDR_EL1 of the selected implementation   |
> +|                     +----------+----+---------------------------------------------+
> +|                     | (uint64) | R3 | Reserved / Must be zero                     |
> ++---------------------+----------+----+---------------------------------------------+

This is missing AIDR_EL1. Although Linux never had to use it, its
purpose is to describe additional implementation details that we may
find relevant in the future.

> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
> index 67f6fdf2e7cd..6c080fa9d345 100644
> --- a/include/linux/arm-smccc.h
> +++ b/include/linux/arm-smccc.h
> @@ -179,6 +179,7 @@
>  #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62		62
>  #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63		63
>  /* End of pKVM hypercall range */
> +#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS	126

No need to stay at the back of the room, you can happily take slot 64!

>  #define ARM_SMCCC_KVM_FUNC_FEATURES_2		127
>  #define ARM_SMCCC_KVM_NUM_FUNCS			128
>  
> @@ -225,6 +226,12 @@
>  			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
>  			   ARM_SMCCC_KVM_FUNC_MMIO_GUARD)
>  
> +#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID		\
> +	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
> +			   ARM_SMCCC_SMC_64,				\
> +			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
> +			   ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS)
> +
>  /* ptp_kvm counter type ID */
>  #define KVM_PTP_VIRT_COUNTER			0
>  #define KVM_PTP_PHYS_COUNTER			1

Thanks,

	M.

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


From michal.swiatkowski at linux.intel.com  Thu Dec 19 01:57:30 2024
From: michal.swiatkowski at linux.intel.com (Michal Swiatkowski)
Date: Thu, 19 Dec 2024 10:57:30 +0100
Subject: [PATCH net-next 3/4] net: ti: icssg-prueth: Add Multicast
 Filtering support for VLAN in MAC mode
In-Reply-To: <cb319ffd-ac67-42b3-9786-e8c9970086d2@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-4-danishanwar@ti.com>
 <Z2PLDqqrLdXhLtAF@mev-dev.igk.intel.com>
 <cb319ffd-ac67-42b3-9786-e8c9970086d2@ti.com>
Message-ID: <Z2PuCmGDGpqvc0bp@mev-dev.igk.intel.com>

On Thu, Dec 19, 2024 at 03:06:18PM +0530, MD Danish Anwar wrote:
> 
> 
> On 19/12/24 12:58 pm, Michal Swiatkowski wrote:
> > On Mon, Dec 16, 2024 at 03:30:43PM +0530, MD Danish Anwar wrote:
> >> Add multicast filtering support for VLAN interfaces in dual EMAC mode
> >> for ICSSG driver.
> >>
> >> The driver uses vlan_for_each() API to get the list of available
> >> vlans. The driver then sync mc addr of vlan interface with a locally
> >> mainatined list emac->vlan_mcast_list[vid] using __hw_addr_sync_multiple()
> >> API.
> >>
> >> The driver then calls the sync / unsync callbacks and based on whether
> >> the ndev is vlan or not, driver passes appropriate vid to FDB helper
> >> functions.
> >>
> >> This commit also exports __hw_addr_sync_multiple() in order to use it
> >> from the ICSSG driver.
> >>
> >> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> >> ---
> >>  drivers/net/ethernet/ti/icssg/icssg_prueth.c | 69 ++++++++++++++++----
> >>  drivers/net/ethernet/ti/icssg/icssg_prueth.h |  6 ++
> >>  include/linux/netdevice.h                    |  3 +
> >>  net/core/dev_addr_lists.c                    |  7 +-
> >>  4 files changed, 68 insertions(+), 17 deletions(-)
> >>
> >> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> >> index e031bccf31dc..a18773ef6eab 100644
> >> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> >> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> >> @@ -472,30 +472,43 @@ const struct icss_iep_clockops prueth_iep_clockops = {
> >>  
> >>  static int icssg_prueth_add_mcast(struct net_device *ndev, const u8 *addr)
> >>  {
> >> -	struct prueth_emac *emac = netdev_priv(ndev);
> >> -	int port_mask = BIT(emac->port_id);
> >> +	struct net_device *real_dev;
> >> +	struct prueth_emac *emac;
> >> +	int port_mask;
> >> +	u8 vlan_id;
> >>  
> >> -	port_mask |= icssg_fdb_lookup(emac, addr, 0);
> >> -	icssg_fdb_add_del(emac, addr, 0, port_mask, true);
> >> -	icssg_vtbl_modify(emac, 0, port_mask, port_mask, true);
> >> +	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
> >> +	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
> > Looks like a helper for that can be nice to have.
> >
> 
> I don't think that's neccessary. vlan_dev_real_dev() itself is a helper
> function to give the real dev, only down side is vlan_dev_real_dev()
> assumes that the dev is vlan only.
> 
> In this function, we don't know if ndev is vlan or not, hence the check.
> Most drivers are using vlan_dev_real_dev() the same way.
> 

I meant to not repeat the
is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
(it is also used in next patch)

But as you think, I don't have strong opinion on that.

> 
> >> +	emac = netdev_priv(real_dev);
> >> +
> >> +	port_mask = BIT(emac->port_id) | icssg_fdb_lookup(emac, addr, vlan_id);
> >> +	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, true);
> >> +	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, true);
> >>  
> >>  	return 0;
> >>  }
> >>  
> >>  static int icssg_prueth_del_mcast(struct net_device *ndev, const u8 *addr)
> >>  {
> >> -	struct prueth_emac *emac = netdev_priv(ndev);
> >> -	int port_mask = BIT(emac->port_id);
> >> +	struct net_device *real_dev;
> >> +	struct prueth_emac *emac;
> >>  	int other_port_mask;
> >> +	int port_mask;
> >> +	u8 vlan_id;
> >> +
> >> +	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
> >> +	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
> >> +	emac = netdev_priv(real_dev);
> >>  
> >> -	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, 0);
> >> +	port_mask = BIT(emac->port_id);
> >> +	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, vlan_id);
> >>  
> >> -	icssg_fdb_add_del(emac, addr, 0, port_mask, false);
> >> -	icssg_vtbl_modify(emac, 0, port_mask, port_mask, false);
> >> +	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, false);
> >> +	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, false);
> >>  
> >>  	if (other_port_mask) {
> >> -		icssg_fdb_add_del(emac, addr, 0, other_port_mask, true);
> >> -		icssg_vtbl_modify(emac, 0, other_port_mask, other_port_mask, true);
> >> +		icssg_fdb_add_del(emac, addr, vlan_id, other_port_mask, true);
> >> +		icssg_vtbl_modify(emac, vlan_id, other_port_mask, other_port_mask, true);
> >>  	}
> >>  
> >>  	return 0;
> >> @@ -531,6 +544,28 @@ static int icssg_prueth_hsr_del_mcast(struct net_device *ndev, const u8 *addr)
> >>  	return 0;
> >>  }
> >>  
> >> +static int icssg_update_vlan_mcast(struct net_device *vdev, int vid,
> >> +				   void *args)
> >> +{
> >> +	struct net_device *vport_ndev;
> >> +	struct prueth_emac *emac;
> >> +
> >> +	if (!vdev || !vid)
> >> +		return 0;
> >> +
> >> +	vport_ndev = vlan_dev_real_dev(vdev);
> >> +	emac = netdev_priv(vport_ndev);
> >> +
> >> +	netif_addr_lock_bh(vdev);
> >> +	__hw_addr_sync_multiple(&emac->vlan_mcast_list[vid], &vdev->mc, vdev->addr_len);
> > Only question, why dev_mc_sync_multiple can't be used here?
> > 
> 
> dev_mc_sync_multiple() doesn't work here.
> 
> Let's say we call dev_mc_sync_multiple() with emac->ndev (the netdevice
> for current port say eth1) and vdev (the netdevice for the vlan
> interface say eth1.x with x being the vid).
> 
> Now dev_mc_sync_multiple() will sync the mc list from vdev to ndev. And
> ndev will have the address added to vdev. After this set_rx_mode() gets
> called for ndev. Which eventually calls sync / unsync APIs
> icssg_prueth_add/del_mcast.
> 
> Now in this API, we will have the address to add but we won't have the vid.
> 
> The sync/unsync API will be called for the emac->ndev (the *to* device)
> and emac->ndev will have no information about vid. Since it is not a
> vlan dev and is_vlan_dev() will be false for it as a result we will
> fallback to default vid.
> 
> 	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) :
> PRUETH_DFLT_VLAN_HSR;
> 
> We don't want this. We want to capture the correct vid. Hence sync /
> unsync needs to get called for the vlan device i.e. vdev.
> 
> Due to this dev_mc_sync_multiple() doesn't work and we need to call
> __hw_addr_sync_multiple and __hw_addr_sync_dev on vdev so that our sync
> / unsync APIs are called for vdev.
> 
>

Ok, I understand, thank for explanation.

> >> +	netif_addr_unlock_bh(vdev);
> >> +
> >> +	__hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
> >> +			   icssg_prueth_add_mcast, icssg_prueth_del_mcast);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >>  /**
> >>   * emac_ndo_open - EMAC device open
> >>   * @ndev: network adapter device
> >> @@ -772,12 +807,17 @@ static void emac_ndo_set_rx_mode_work(struct work_struct *work)
> >>  		return;
> >>  	}
> >>  
> >> -	if (emac->prueth->is_hsr_offload_mode)
> >> +	if (emac->prueth->is_hsr_offload_mode) {
> >>  		__dev_mc_sync(ndev, icssg_prueth_hsr_add_mcast,
> >>  			      icssg_prueth_hsr_del_mcast);
> >> -	else
> >> +	} else {
> >>  		__dev_mc_sync(ndev, icssg_prueth_add_mcast,
> >>  			      icssg_prueth_del_mcast);
> >> +		if (rtnl_trylock()) {
> >> +			vlan_for_each(ndev, icssg_update_vlan_mcast, NULL);
> >> +			rtnl_unlock();
> >> +		}
> >> +	}
> >>  }
> >>  
> >>  /**
> >> @@ -828,6 +868,7 @@ static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev,
> >>  	if (prueth->is_hsr_offload_mode)
> >>  		port_mask |= BIT(PRUETH_PORT_HOST);
> >>  
> >> +	__hw_addr_init(&emac->vlan_mcast_list[vid]);
> >>  	netdev_err(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
> >>  		   vid, port_mask, untag_mask);
> >>  
> >> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> >> index f5c1d473e9f9..4da8b87408b5 100644
> >> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> >> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
> >> @@ -83,6 +83,10 @@
> >>  #define ICSS_CMD_ADD_FILTER 0x7
> >>  #define ICSS_CMD_ADD_MAC 0x8
> >>  
> >> +/* VLAN Filtering Related MACROs */
> >> +#define PRUETH_DFLT_VLAN_MAC	0
> >> +#define MAX_VLAN_ID		256
> >> +
> >>  /* In switch mode there are 3 real ports i.e. 3 mac addrs.
> >>   * however Linux sees only the host side port. The other 2 ports
> >>   * are the switch ports.
> >> @@ -201,6 +205,8 @@ struct prueth_emac {
> >>  	/* RX IRQ Coalescing Related */
> >>  	struct hrtimer rx_hrtimer;
> >>  	unsigned long rx_pace_timeout_ns;
> >> +
> >> +	struct netdev_hw_addr_list vlan_mcast_list[MAX_VLAN_ID];
> >>  };
> >>  
> >>  /**
> >> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> >> index d917949bba03..a5c169b19543 100644
> >> --- a/include/linux/netdevice.h
> >> +++ b/include/linux/netdevice.h
> >> @@ -4685,6 +4685,9 @@ int devm_register_netdev(struct device *dev, struct net_device *ndev);
> >>  /* General hardware address lists handling functions */
> >>  int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
> >>  		   struct netdev_hw_addr_list *from_list, int addr_len);
> >> +int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> >> +			    struct netdev_hw_addr_list *from_list,
> >> +			    int addr_len);
> >>  void __hw_addr_unsync(struct netdev_hw_addr_list *to_list,
> >>  		      struct netdev_hw_addr_list *from_list, int addr_len);
> >>  int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
> >> diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
> >> index 166e404f7c03..90716bd736f3 100644
> >> --- a/net/core/dev_addr_lists.c
> >> +++ b/net/core/dev_addr_lists.c
> >> @@ -242,9 +242,9 @@ static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list,
> >>  	__hw_addr_del_entry(from_list, ha, false, false);
> >>  }
> >>  
> >> -static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> >> -				   struct netdev_hw_addr_list *from_list,
> >> -				   int addr_len)
> >> +int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> >> +			    struct netdev_hw_addr_list *from_list,
> >> +			    int addr_len)
> >>  {
> >>  	int err = 0;
> >>  	struct netdev_hw_addr *ha, *tmp;
> >> @@ -260,6 +260,7 @@ static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
> >>  	}
> >>  	return err;
> >>  }
> >> +EXPORT_SYMBOL(__hw_addr_sync_multiple);
> >>  
> >>  /* This function only works where there is a strict 1-1 relationship
> >>   * between source and destination of they synch. If you ever need to
> >> -- 
> >> 2.34.1
> 
> -- 
> Thanks and Regards,
> Danish


From maz at kernel.org  Thu Dec 19 02:04:22 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 10:04:22 +0000
Subject: [PATCH v4 3/3] arm64: paravirt: Enable errata based on implementation CPUs
In-Reply-To: <20241218105345.73472-4-shameerali.kolothum.thodi@huawei.com>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
	<20241218105345.73472-4-shameerali.kolothum.thodi@huawei.com>
Message-ID: <86bjx8q995.wl-maz@kernel.org>

On Wed, 18 Dec 2024 10:53:45 +0000,
Shameer Kolothum <shameerali.kolothum.thodi at huawei.com> wrote:
> 
> Retrieve any migration target implementation CPUs using the hypercall
> and enable associated errata.
> 
> Reviewed-by: Sebastian Ott <sebott at redhat.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  arch/arm64/include/asm/cputype.h  | 25 +++++++++++++++++++++++--
>  arch/arm64/include/asm/paravirt.h |  3 +++
>  arch/arm64/kernel/cpu_errata.c    | 20 +++++++++++++++++---
>  arch/arm64/kernel/cpufeature.c    |  2 ++
>  arch/arm64/kernel/image-vars.h    |  2 ++
>  arch/arm64/kernel/paravirt.c      | 31 +++++++++++++++++++++++++++++++
>  6 files changed, 78 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index dcf0e1ce892d..019d1b7dae80 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -265,6 +265,16 @@ struct midr_range {
>  #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r)
>  #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
>  
> +#define MAX_TARGET_IMPL_CPUS 64
> +
> +struct target_impl_cpu {
> +	u64 midr;
> +	u64 revidr;
> +};
> +
> +extern u32 target_impl_cpu_num;
> +extern struct target_impl_cpu target_impl_cpus[];
> +
>  static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
>  					   u32 rv_max)
>  {
> @@ -276,8 +286,19 @@ static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
>  
>  static inline bool is_midr_in_range(struct midr_range const *range)
>  {
> -	return midr_is_cpu_model_range(read_cpuid_id(), range->model,
> -				       range->rv_min, range->rv_max);
> +	int i;
> +
> +	if (!target_impl_cpu_num)
> +		return midr_is_cpu_model_range(read_cpuid_id(), range->model,
> +					       range->rv_min, range->rv_max);
> +
> +	for (i = 0; i < target_impl_cpu_num; i++) {
> +		if (midr_is_cpu_model_range(target_impl_cpus[i].midr,
> +					    range->model,
> +					    range->rv_min, range->rv_max))
> +			return true;
> +	}
> +	return false;
>  }
>  
>  static inline bool
> diff --git a/arch/arm64/include/asm/paravirt.h b/arch/arm64/include/asm/paravirt.h
> index 9aa193e0e8f2..95f1c15bbb7d 100644
> --- a/arch/arm64/include/asm/paravirt.h
> +++ b/arch/arm64/include/asm/paravirt.h
> @@ -19,11 +19,14 @@ static inline u64 paravirt_steal_clock(int cpu)
>  }
>  
>  int __init pv_time_init(void);
> +void __init pv_target_impl_cpu_init(void);
>  
>  #else
>  
>  #define pv_time_init() do {} while (0)
>  
> +#define pv_target_impl_cpu_init() do {} while (0)
> +
>  #endif // CONFIG_PARAVIRT
>  
>  #endif
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 929685c00263..4055082ce69b 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -14,6 +14,9 @@
>  #include <asm/kvm_asm.h>
>  #include <asm/smp_plat.h>
>  
> +u32 target_impl_cpu_num;
> +struct target_impl_cpu target_impl_cpus[MAX_TARGET_IMPL_CPUS];
> +
>  static bool __maybe_unused
>  __is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
>  			 u32 midr, u32 revidr)
> @@ -32,9 +35,20 @@ __is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
>  static bool __maybe_unused
>  is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
>  {
> -	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
> -	return __is_affected_midr_range(entry, read_cpuid_id(),
> -					read_cpuid(REVIDR_EL1));
> +	int i;
> +
> +	if (!target_impl_cpu_num) {
> +		WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
> +		return __is_affected_midr_range(entry, read_cpuid_id(),
> +						read_cpuid(REVIDR_EL1));
> +	}
> +
> +	for (i = 0; i < target_impl_cpu_num; i++) {
> +		if (__is_affected_midr_range(entry, target_impl_cpus[i].midr,
> +					     target_impl_cpus[i].midr))
> +			return true;
> +	}
> +	return false;
>  }
>  
>  static bool __maybe_unused
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 4cc4ae16b28d..d32c767bf189 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -85,6 +85,7 @@
>  #include <asm/kvm_host.h>
>  #include <asm/mmu_context.h>
>  #include <asm/mte.h>
> +#include <asm/paravirt.h>
>  #include <asm/processor.h>
>  #include <asm/smp.h>
>  #include <asm/sysreg.h>
> @@ -3642,6 +3643,7 @@ unsigned long cpu_get_elf_hwcap3(void)
>  
>  static void __init setup_boot_cpu_capabilities(void)
>  {
> +	pv_target_impl_cpu_init();
>  	/*
>  	 * The boot CPU's feature register values have been recorded. Detect
>  	 * boot cpucaps and local cpucaps for the boot CPU, then enable and
> diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
> index 8f5422ed1b75..694e19709c46 100644
> --- a/arch/arm64/kernel/image-vars.h
> +++ b/arch/arm64/kernel/image-vars.h
> @@ -49,6 +49,8 @@ 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);
> +PROVIDE(__pi_target_impl_cpu_num	= target_impl_cpu_num);
> +PROVIDE(__pi_target_impl_cpus		= target_impl_cpus);
>  #endif
>  PROVIDE(__pi__ctype			= _ctype);
>  PROVIDE(__pi_memstart_offset_seed	= memstart_offset_seed);
> diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c
> index aa718d6a9274..95fc3aae4a27 100644
> --- a/arch/arm64/kernel/paravirt.c
> +++ b/arch/arm64/kernel/paravirt.c
> @@ -153,6 +153,37 @@ static bool __init has_pv_steal_clock(void)
>  	return (res.a0 == SMCCC_RET_SUCCESS);
>  }
>  
> +void  __init pv_target_impl_cpu_init(void)
> +{
> +	struct arm_smccc_res res;
> +	int index = 0, max_idx = -1;
> +
> +	/* Check we have already set targets */
> +	if (target_impl_cpu_num)
> +		return;
> +
> +	do {
> +		arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID,
> +				     index, &res);
> +		if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
> +			return;

Can't you probe for this as part of the KVM guest services?

> +
> +		if (max_idx < 0) {
> +			/* res.a0 should have a valid maximum CPU implementation index */
> +			if (res.a0 >= MAX_TARGET_IMPL_CPUS)
> +				return;
> +			max_idx = res.a0;
> +		}
> +
> +		target_impl_cpus[index].midr = res.a1;
> +		target_impl_cpus[index].revidr = res.a2;
> +		index++;
> +	} while (index <= max_idx);
> +
> +	target_impl_cpu_num = index;
> +	pr_info("Number of target implementation CPUs is %d\n", target_impl_cpu_num);
> +}
> +
>  int __init pv_time_init(void)
>  {
>  	int ret;

Independent of this, I wonder what we should output in sysfs
(/sys/devices/system/cpu/cpu*/regs/identification/*).

Thanks,

	M.

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


From maz at kernel.org  Thu Dec 19 02:07:39 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 10:07:39 +0000
Subject: [PATCH v4 0/3] KVM: arm64: Errata management for VM Live migration
In-Reply-To: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <86a5csq93o.wl-maz@kernel.org>

Hi Shameer,

On Wed, 18 Dec 2024 10:53:42 +0000,
Shameer Kolothum <shameerali.kolothum.thodi at huawei.com> wrote:
> 
> Hi,
> 
> v3 --> v4(Minor updates)
> https://lore.kernel.org/kvmarm/20241209115311.40496-1-shameerali.kolothum.thodi at huawei.com/
> 
>  -Changed MIDR/REVIDR to 64 bits based on feedback from Connie
>   and Marc(Patch #3).
>  -Added R-by tags from Sebastian (Thanks!).

Thanks again for putting this together.

I think it would be really good to have a sample userspace
implementation of this extension so that we can play with it for real
before fully committing to it.

I am also wondering is we should make it mandatory that a guest is
presented with an MIDR_EL1.Implementer value set to 0, which denotes
SW use, and would make it plain to the guest (and crucially, guest
userspace) that we are going to play tricks.

Thoughts?

	M.

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


From james.clark at linaro.org  Thu Dec 19 02:10:59 2024
From: james.clark at linaro.org (James Clark)
Date: Thu, 19 Dec 2024 10:10:59 +0000
Subject: [PATCH 5/5] perf docs: arm_spe: Document new discard mode
In-Reply-To: <CAP-5=fXV6LXrUtvgRKuyurmu5SoSZLTf6MN=+BBXkqv7drvOjg@mail.gmail.com>
References: <20241217115610.371755-1-james.clark@linaro.org>
 <20241217115610.371755-6-james.clark@linaro.org>
 <CAP-5=fU7RNzvzxBcAQy3RT9Ge3YtqPhDonupNWS7Wgb8HGQkGg@mail.gmail.com>
 <8c15786c-47b6-47ff-b1dc-ecbf32d582fb@linaro.org>
 <CAP-5=fXV6LXrUtvgRKuyurmu5SoSZLTf6MN=+BBXkqv7drvOjg@mail.gmail.com>
Message-ID: <4f0bcc19-807c-40b0-a30c-309ba775693b@linaro.org>



On 18/12/2024 7:47 pm, Ian Rogers wrote:
> On Wed, Dec 18, 2024 at 2:07?AM James Clark <james.clark at linaro.org> wrote:
>>
>> On 18/12/2024 12:54 am, Ian Rogers wrote:
>>> On Tue, Dec 17, 2024 at 3:56?AM James Clark <james.clark at linaro.org> wrote:
>>>>
>>>> Document the flag, hint what it's used for and give an example with
>>>> other useful options to get minimal output.
>>>>
>>>> Signed-off-by: James Clark <james.clark at linaro.org>
>>>> ---
>>>>    tools/perf/Documentation/perf-arm-spe.txt | 11 +++++++++++
>>>>    1 file changed, 11 insertions(+)
>>>>
>>>> diff --git a/tools/perf/Documentation/perf-arm-spe.txt b/tools/perf/Documentation/perf-arm-spe.txt
>>>> index de2b0b479249..588eead438bc 100644
>>>> --- a/tools/perf/Documentation/perf-arm-spe.txt
>>>> +++ b/tools/perf/Documentation/perf-arm-spe.txt
>>>> @@ -150,6 +150,7 @@ arm_spe/load_filter=1,min_latency=10/'
>>>>      pct_enable=1        - collect physical timestamp instead of virtual timestamp (PMSCR.PCT) - requires privilege
>>>>      store_filter=1      - collect stores only (PMSFCR.ST)
>>>>      ts_enable=1         - enable timestamping with value of generic timer (PMSCR.TS)
>>>> +  discard=1           - enable SPE PMU events but don't collect sample data - see 'Discard mode' (PMBLIMITR.FM = DISCARD)
>>>>
>>>>    +++*+++ Latency is the total latency from the point at which sampling started on that instruction, rather
>>>>    than only the execution latency.
>>>> @@ -220,6 +221,16 @@ Common errors
>>>>
>>>>       Increase sampling interval (see above)
>>>>
>>>> +Discard mode
>>>> +~~~~~~~~~~~~
>>>> +
>>>> +SPE PMU events can be used without the overhead of collecting sample data if
>>>> +discard mode is supported (optional from Armv8.6). First run a system wide SPE
>>>> +session (or on the core of interest) using options to minimize output. Then run
>>>> +perf stat:
>>>> +
>>>> +  perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
>>>> +  perf stat -e SAMPLE_FEED_LD
>>>
>>> Perhaps clarify this should be an ARM SPE event? It seems strange to
>>> have one perf command affect a later one, the purpose of things like
>>> event multiplexing is to hide the hardware limits. I'd prefer if the
>>> last bit was like:
>>> ```
>>> Then run perf stat with an SPE event on the same PMU:
>>>
>>> perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
>>> perf stat -e arm_spe/SAMPLE_FEED_LD/
>>> ``
>>>
>>> Thanks,
>>> Ian
>>
>> Hi Ian,
>>
>> Confusingly this isn't an SPE event, it is a normal PMU event. The fact
>> that one Perf command affects the other is because these events only
>> count when SPE is enabled. When it's enabled it has an effect on a
>> per-core level which is why in the example I made it simpler by enabling
>> SPE system wide.
>>
>> SPE is an exclusive PMU like Coresight and some others so it can't be
>> affected by multiplexing or anything like that. The SAMPLE_FEED_LD PMU
>> would be, but as long as SPE stays enabled it will count the right thing
>> regardless of multiplexing.
> 
> Thanks James, sorry for my SPE ignorance. I'm smiling about the use of
> the word exclusive. When I was trying to make the tests run in
> parallel I used a file lock - so shared and exclusive. There were a
> lot of issues with that, hence switching to 2 phases in the test,
> parallel then sequential but I kept the "exclusive" tag for want of a
> better word. Perhaps the notion of an exclusive PMU existed previously

Yeah, see PERF_PMU_CAP_EXCLUSIVE. Hopefully it doesn't cause too much 
confusion, the context of test vs PMU should make it clear.

> but maybe I've accidentally invented the term by way of a failed file
> lock experiment :-)
> 
> Presumably the two PMUs side-effecting each other is a known thing. I
> wonder if we can capture this in the documentation. When you say
> "normal PMU event" you mean core PMU events?
> 
> Thanks,
> Ian

It should be a known thing yes, discard mode doesn't change this 
behavior anyway but just makes one use case of it better. I can add 
another section to this SPE manpage about it in a v2, that's probably 
the best place for it.

And yes, I meant core PMU event. I can clarify that the second example 
command is for a core PMU to avoid any doubt.

Thanks
James



From qperret at google.com  Thu Dec 19 02:12:48 2024
From: qperret at google.com (Quentin Perret)
Date: Thu, 19 Dec 2024 10:12:48 +0000
Subject: [PATCH v4 17/18] KVM: arm64: Introduce the EL1 pKVM MMU
In-Reply-To: <CA+EHjTymHPQGwLLpsWzYf1zHpnQKu4mV54Bz3U9HWf3Jb8TcqA@mail.gmail.com>
References: <20241218194059.3670226-1-qperret@google.com>
 <20241218194059.3670226-18-qperret@google.com>
 <CA+EHjTymHPQGwLLpsWzYf1zHpnQKu4mV54Bz3U9HWf3Jb8TcqA@mail.gmail.com>
Message-ID: <Z2PxoLcB3EMfk3_-@google.com>

On Thursday 19 Dec 2024 at 09:49:31 (+0000), Fuad Tabba wrote:
> Hi Quentin
> 
> On Wed, 18 Dec 2024 at 19:41, Quentin Perret <qperret at google.com> wrote:
> >
> > Introduce a set of helper functions allowing to manipulate the pKVM
> > guest stage-2 page-tables from EL1 using pKVM's HVC interface.
> >
> > Each helper has an exact one-to-one correspondance with the traditional
> > kvm_pgtable_stage2_*() functions from pgtable.c, with a strictly
> > matching prototype. This will ease plumbing later on in mmu.c.
> >
> > These callbacks track the gfn->pfn mappings in a simple rb_tree indexed
> > by IPA in lieu of a page-table. This rb-tree is kept in sync with pKVM's
> > state and is protected by the mmu_lock like a traditional stage-2
> > page-table.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> 
> Minor nits (feel free to ignore). Apart from that, and despite that
> for_each_mapping_in_range_safe macro:
> 
> Tested-by: Fuad Tabba <tabba at google.com>
> Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks!

> > ---
> >  arch/arm64/include/asm/kvm_host.h    |   1 +
> >  arch/arm64/include/asm/kvm_pgtable.h |  23 +--
> >  arch/arm64/include/asm/kvm_pkvm.h    |  26 ++++
> >  arch/arm64/kvm/pkvm.c                | 201 +++++++++++++++++++++++++++
> >  4 files changed, 242 insertions(+), 9 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 1246f1d01dbf..f23f4ea9ec8b 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -85,6 +85,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
> >  struct kvm_hyp_memcache {
> >         phys_addr_t head;
> >         unsigned long nr_pages;
> > +       struct pkvm_mapping *mapping; /* only used from EL1 */
> >  };
> >
> >  static inline void push_hyp_memcache(struct kvm_hyp_memcache *mc,
> > diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> > index 04418b5e3004..6b9d274052c7 100644
> > --- a/arch/arm64/include/asm/kvm_pgtable.h
> > +++ b/arch/arm64/include/asm/kvm_pgtable.h
> > @@ -412,15 +412,20 @@ static inline bool kvm_pgtable_walk_lock_held(void)
> >   *                     be used instead of block mappings.
> >   */
> >  struct kvm_pgtable {
> > -       u32                                     ia_bits;
> > -       s8                                      start_level;
> > -       kvm_pteref_t                            pgd;
> > -       struct kvm_pgtable_mm_ops               *mm_ops;
> > -
> > -       /* Stage-2 only */
> > -       struct kvm_s2_mmu                       *mmu;
> > -       enum kvm_pgtable_stage2_flags           flags;
> > -       kvm_pgtable_force_pte_cb_t              force_pte_cb;
> > +       union {
> > +               struct rb_root                                  pkvm_mappings;
> > +               struct {
> > +                       u32                                     ia_bits;
> > +                       s8                                      start_level;
> > +                       kvm_pteref_t                            pgd;
> > +                       struct kvm_pgtable_mm_ops               *mm_ops;
> > +
> > +                       /* Stage-2 only */
> > +                       enum kvm_pgtable_stage2_flags           flags;
> > +                       kvm_pgtable_force_pte_cb_t              force_pte_cb;
> > +               };
> > +       };
> > +       struct kvm_s2_mmu                                       *mmu;
> >  };
> >
> >  /**
> > diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> > index cd56acd9a842..65f988b6fe0d 100644
> > --- a/arch/arm64/include/asm/kvm_pkvm.h
> > +++ b/arch/arm64/include/asm/kvm_pkvm.h
> > @@ -137,4 +137,30 @@ static inline size_t pkvm_host_sve_state_size(void)
> >                         SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_sve_max_vl)));
> >  }
> >
> > +struct pkvm_mapping {
> > +       struct rb_node node;
> > +       u64 gfn;
> > +       u64 pfn;
> > +};
> > +
> > +int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
> > +                            struct kvm_pgtable_mm_ops *mm_ops);
> > +void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
> > +int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
> > +                           enum kvm_pgtable_prot prot, void *mc,
> > +                           enum kvm_pgtable_walk_flags flags);
> > +int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
> > +int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
> > +int pkvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
> > +bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold);
> > +int pkvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
> > +                                   enum kvm_pgtable_walk_flags flags);
> > +void pkvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
> > +                                enum kvm_pgtable_walk_flags flags);
> > +int pkvm_pgtable_stage2_split(struct kvm_pgtable *pgt, u64 addr, u64 size,
> > +                             struct kvm_mmu_memory_cache *mc);
> > +void pkvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level);
> > +kvm_pte_t *pkvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
> > +                                              enum kvm_pgtable_prot prot, void *mc,
> > +                                              bool force_pte);
> >  #endif /* __ARM64_KVM_PKVM_H__ */
> > diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
> > index 85117ea8f351..930b677eb9b0 100644
> > --- a/arch/arm64/kvm/pkvm.c
> > +++ b/arch/arm64/kvm/pkvm.c
> > @@ -7,6 +7,7 @@
> >  #include <linux/init.h>
> >  #include <linux/kmemleak.h>
> >  #include <linux/kvm_host.h>
> > +#include <asm/kvm_mmu.h>
> >  #include <linux/memblock.h>
> >  #include <linux/mutex.h>
> >  #include <linux/sort.h>
> > @@ -268,3 +269,203 @@ static int __init finalize_pkvm(void)
> >         return ret;
> >  }
> >  device_initcall_sync(finalize_pkvm);
> > +
> > +static int cmp_mappings(struct rb_node *node, const struct rb_node *parent)
> > +{
> > +       struct pkvm_mapping *a = rb_entry(node, struct pkvm_mapping, node);
> > +       struct pkvm_mapping *b = rb_entry(parent, struct pkvm_mapping, node);
> > +
> > +       if (a->gfn < b->gfn)
> > +               return -1;
> > +       if (a->gfn > b->gfn)
> > +               return 1;
> > +       return 0;
> > +}
> > +
> > +static struct rb_node *find_first_mapping_node(struct rb_root *root, u64 gfn)
> > +{
> > +       struct rb_node *node = root->rb_node, *prev = NULL;
> > +       struct pkvm_mapping *mapping;
> > +
> > +       while (node) {
> > +               mapping = rb_entry(node, struct pkvm_mapping, node);
> > +               if (mapping->gfn == gfn)
> > +                       return node;
> > +               prev = node;
> > +               node = (gfn < mapping->gfn) ? node->rb_left : node->rb_right;
> > +       }
> > +
> > +       return prev;
> > +}
> > +
> > +/*
> > + * __tmp is updated to rb_next(__tmp) *before* entering the body of the loop to allow freeing
> > + * of __map inline.
> > + */
> > +#define for_each_mapping_in_range_safe(__pgt, __start, __end, __map)                           \
> > +       for (struct rb_node *__tmp = find_first_mapping_node(&(__pgt)->pkvm_mappings,           \
> > +                                                            ((__start) >> PAGE_SHIFT));        \
> > +            __tmp && ({                                                                        \
> > +                               __map = rb_entry(__tmp, struct pkvm_mapping, node);             \
> > +                               __tmp = rb_next(__tmp);                                         \
> > +                               true;                                                           \
> > +                      });                                                                      \
> > +           )                                                                                   \
> > +               if (__map->gfn < ((__start) >> PAGE_SHIFT))                                     \
> > +                       continue;                                                               \
> > +               else if (__map->gfn >= ((__end) >> PAGE_SHIFT))                                 \
> > +                       break;                                                                  \
> > +               else
> > +
> > +int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
> > +                            struct kvm_pgtable_mm_ops *mm_ops)
> > +{
> > +       pgt->pkvm_mappings      = RB_ROOT;
> > +       pgt->mmu                = mmu;
> > +
> > +       return 0;
> > +}
> > +
> > +void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt)
> > +{
> > +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> > +       pkvm_handle_t handle = kvm->arch.pkvm.handle;
> > +       struct pkvm_mapping *mapping;
> > +       struct rb_node *node;
> > +
> > +       if (!handle)
> > +               return;
> > +
> > +       node = rb_first(&pgt->pkvm_mappings);
> > +       while (node) {
> > +               mapping = rb_entry(node, struct pkvm_mapping, node);
> > +               kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
> > +               node = rb_next(node);
> > +               rb_erase(&mapping->node, &pgt->pkvm_mappings);
> > +               kfree(mapping);
> > +       }
> > +}
> > +
> > +int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
> > +                          u64 phys, enum kvm_pgtable_prot prot,
> > +                          void *mc, enum kvm_pgtable_walk_flags flags)
> > +{
> > +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> > +       struct pkvm_mapping *mapping = NULL;
> > +       struct kvm_hyp_memcache *cache = mc;
> > +       u64 gfn = addr >> PAGE_SHIFT;
> > +       u64 pfn = phys >> PAGE_SHIFT;
> 
> Is it worth using the gpa_to_gfn and __phys_to_pfn helpers? Might
> obscure rather than help, but something to think about.

Apparently user_mem_abort() already uses an open coded variant of
gpa_to_gfn(), so I guess it makes sense to be consistent here? I
personally like the open coded variant better because it makes it clear
what this does, but no strong opinion really.

> > +       int ret;
> > +
> > +       if (size != PAGE_SIZE)
> > +               return -EINVAL;
> > +
> > +       lockdep_assert_held_write(&kvm->mmu_lock);
> > +       ret = kvm_call_hyp_nvhe(__pkvm_host_share_guest, pfn, gfn, prot);
> > +       if (ret) {
> > +               /* Is the gfn already mapped due to a racing vCPU? */
> > +               if (ret == -EPERM)
> > +                       return -EAGAIN;
> > +       }
> > +
> > +       swap(mapping, cache->mapping);
> > +       mapping->gfn = gfn;
> > +       mapping->pfn = pfn;
> > +       WARN_ON(rb_find_add(&mapping->node, &pgt->pkvm_mappings, cmp_mappings));
> 
> In addition to the warning, is it better to return an error as well?

Right, returning an error would be fatal for the guest I think, there's
nothing the VMM can do. The WARN alone keeps it limping along a bit
longer. In both case we're in deep trouble because the state is truly
borked.

I'm tempted to leave things as is (because the error path is really
going to be dead code in practice) unless anybody feels strongly about
it.

Cheers,
Quentin

> 
> > +       return ret;
> > +}
> > +
> > +int pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
> > +{
> > +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> > +       pkvm_handle_t handle = kvm->arch.pkvm.handle;
> > +       struct pkvm_mapping *mapping;
> > +       int ret = 0;
> > +
> > +       lockdep_assert_held_write(&kvm->mmu_lock);
> > +       for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) {
> > +               ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_guest, handle, mapping->gfn);
> > +               if (WARN_ON(ret))
> > +                       break;
> > +               rb_erase(&mapping->node, &pgt->pkvm_mappings);
> > +               kfree(mapping);
> > +       }
> > +
> > +       return ret;
> > +}
> > +
> > +int pkvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
> > +{
> > +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> > +       pkvm_handle_t handle = kvm->arch.pkvm.handle;
> > +       struct pkvm_mapping *mapping;
> > +       int ret = 0;
> > +
> > +       lockdep_assert_held(&kvm->mmu_lock);
> > +       for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) {
> > +               ret = kvm_call_hyp_nvhe(__pkvm_host_wrprotect_guest, handle, mapping->gfn);
> > +               if (WARN_ON(ret))
> > +                       break;
> > +       }
> > +
> > +       return ret;
> > +}
> > +
> > +int pkvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
> > +{
> > +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> > +       struct pkvm_mapping *mapping;
> > +
> > +       lockdep_assert_held(&kvm->mmu_lock);
> > +       for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping)
> > +               __clean_dcache_guest_page(pfn_to_kaddr(mapping->pfn), PAGE_SIZE);
> > +
> > +       return 0;
> > +}
> > +
> > +bool pkvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr, u64 size, bool mkold)
> > +{
> > +       struct kvm *kvm = kvm_s2_mmu_to_kvm(pgt->mmu);
> > +       pkvm_handle_t handle = kvm->arch.pkvm.handle;
> > +       struct pkvm_mapping *mapping;
> > +       bool young = false;
> > +
> > +       lockdep_assert_held(&kvm->mmu_lock);
> > +       for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping)
> > +               young |= kvm_call_hyp_nvhe(__pkvm_host_test_clear_young_guest, handle, mapping->gfn,
> > +                                          mkold);
> > +
> > +       return young;
> > +}
> > +
> > +int pkvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, enum kvm_pgtable_prot prot,
> > +                                   enum kvm_pgtable_walk_flags flags)
> > +{
> > +       return kvm_call_hyp_nvhe(__pkvm_host_relax_perms_guest, addr >> PAGE_SHIFT, prot);
> > +}
> > +
> > +void pkvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr,
> > +                                enum kvm_pgtable_walk_flags flags)
> > +{
> > +       WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_mkyoung_guest, addr >> PAGE_SHIFT));
> > +}
> > +
> > +void pkvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
> > +{
> > +       WARN_ON_ONCE(1);
> > +}
> > +
> > +kvm_pte_t *pkvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt, u64 phys, s8 level,
> > +                                       enum kvm_pgtable_prot prot, void *mc, bool force_pte)
> > +{
> > +       WARN_ON_ONCE(1);
> > +       return NULL;
> > +}
> > +
> > +int pkvm_pgtable_stage2_split(struct kvm_pgtable *pgt, u64 addr, u64 size,
> > +                             struct kvm_mmu_memory_cache *mc)
> > +{
> > +       WARN_ON_ONCE(1);
> > +       return -EINVAL;
> > +}
> > --
> > 2.47.1.613.gc27f4b7a9f-goog
> >


From lkp at intel.com  Thu Dec 19 02:12:36 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 19 Dec 2024 18:12:36 +0800
Subject: [arm-platforms:kvm-arm64/nv-next 7/20] arch/arm64/kvm/at.c:267:6:
 warning: variable 'as_el0' is uninitialized when used here
Message-ID: <202412191856.Qakq77aj-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/nv-next
head:   200e6aefbe57cd21d7ad678ec89f103388b20382
commit: eca7e4423a05f5cef4a1c84f8d69e4abed046a0d [7/20] KVM: arm64: nv: Extract translation helper from the AT code
config: arm64-randconfig-001-20241219 (https://download.01.org/0day-ci/archive/20241219/202412191856.Qakq77aj-lkp at intel.com/config)
compiler: clang version 16.0.6 (https://github.com/llvm/llvm-project 7cbf1a2591520c2491aa35339f227775f4d3adf6)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241219/202412191856.Qakq77aj-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/202412191856.Qakq77aj-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> arch/arm64/kvm/at.c:267:6: warning: variable 'as_el0' is uninitialized when used here [-Wuninitialized]
               as_el0 && (tcr & (va55 ? TCR_E0PD1 : TCR_E0PD0)))
               ^~~~~~
   arch/arm64/kvm/at.c:103:29: note: initialize the variable 'as_el0' to silence this warning
           bool va55, tbi, lva, as_el0;
                                      ^
                                       = 0
   1 warning generated.


vim +/as_el0 +267 arch/arm64/kvm/at.c

8a9b304d7e2276 Marc Zyngier 2024-10-23   97  
eca7e4423a05f5 Marc Zyngier 2024-09-24   98  static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
d6a01a2dc760c8 Marc Zyngier 2024-06-18   99  			 struct s1_walk_result *wr, u64 va)
d6a01a2dc760c8 Marc Zyngier 2024-06-18  100  {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  101  	u64 hcr, sctlr, tcr, tg, ps, ia_bits, ttbr;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  102  	unsigned int stride, x;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  103  	bool va55, tbi, lva, as_el0;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  104  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  105  	hcr = __vcpu_sys_reg(vcpu, HCR_EL2);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  106  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  107  	va55 = va & BIT(55);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  108  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  109  	if (wi->regime == TR_EL2 && va55)
d6a01a2dc760c8 Marc Zyngier 2024-06-18  110  		goto addrsz;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  111  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  112  	wi->s2 = wi->regime == TR_EL10 && (hcr & (HCR_VM | HCR_DC));
d6a01a2dc760c8 Marc Zyngier 2024-06-18  113  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  114  	switch (wi->regime) {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  115  	case TR_EL10:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  116  		sctlr	= vcpu_read_sys_reg(vcpu, SCTLR_EL1);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  117  		tcr	= vcpu_read_sys_reg(vcpu, TCR_EL1);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  118  		ttbr	= (va55 ?
d6a01a2dc760c8 Marc Zyngier 2024-06-18  119  			   vcpu_read_sys_reg(vcpu, TTBR1_EL1) :
d6a01a2dc760c8 Marc Zyngier 2024-06-18  120  			   vcpu_read_sys_reg(vcpu, TTBR0_EL1));
d6a01a2dc760c8 Marc Zyngier 2024-06-18  121  		break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  122  	case TR_EL2:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  123  	case TR_EL20:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  124  		sctlr	= vcpu_read_sys_reg(vcpu, SCTLR_EL2);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  125  		tcr	= vcpu_read_sys_reg(vcpu, TCR_EL2);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  126  		ttbr	= (va55 ?
d6a01a2dc760c8 Marc Zyngier 2024-06-18  127  			   vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
d6a01a2dc760c8 Marc Zyngier 2024-06-18  128  			   vcpu_read_sys_reg(vcpu, TTBR0_EL2));
d6a01a2dc760c8 Marc Zyngier 2024-06-18  129  		break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  130  	default:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  131  		BUG();
d6a01a2dc760c8 Marc Zyngier 2024-06-18  132  	}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  133  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  134  	tbi = (wi->regime == TR_EL2 ?
d6a01a2dc760c8 Marc Zyngier 2024-06-18  135  	       FIELD_GET(TCR_EL2_TBI, tcr) :
d6a01a2dc760c8 Marc Zyngier 2024-06-18  136  	       (va55 ?
d6a01a2dc760c8 Marc Zyngier 2024-06-18  137  		FIELD_GET(TCR_TBI1, tcr) :
d6a01a2dc760c8 Marc Zyngier 2024-06-18  138  		FIELD_GET(TCR_TBI0, tcr)));
d6a01a2dc760c8 Marc Zyngier 2024-06-18  139  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  140  	if (!tbi && (u64)sign_extend64(va, 55) != va)
d6a01a2dc760c8 Marc Zyngier 2024-06-18  141  		goto addrsz;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  142  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  143  	va = (u64)sign_extend64(va, 55);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  144  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  145  	/* Let's put the MMU disabled case aside immediately */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  146  	switch (wi->regime) {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  147  	case TR_EL10:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  148  		/*
d6a01a2dc760c8 Marc Zyngier 2024-06-18  149  		 * If dealing with the EL1&0 translation regime, 3 things
d6a01a2dc760c8 Marc Zyngier 2024-06-18  150  		 * can disable the S1 translation:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  151  		 *
d6a01a2dc760c8 Marc Zyngier 2024-06-18  152  		 * - HCR_EL2.DC = 1
d6a01a2dc760c8 Marc Zyngier 2024-06-18  153  		 * - HCR_EL2.{E2H,TGE} = {0,1}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  154  		 * - SCTLR_EL1.M = 0
d6a01a2dc760c8 Marc Zyngier 2024-06-18  155  		 *
d6a01a2dc760c8 Marc Zyngier 2024-06-18  156  		 * The TGE part is interesting. If we have decided that this
d6a01a2dc760c8 Marc Zyngier 2024-06-18  157  		 * is EL1&0, then it means that either {E2H,TGE} == {1,0} or
d6a01a2dc760c8 Marc Zyngier 2024-06-18  158  		 * {0,x}, and we only need to test for TGE == 1.
d6a01a2dc760c8 Marc Zyngier 2024-06-18  159  		 */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  160  		if (hcr & (HCR_DC | HCR_TGE)) {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  161  			wr->level = S1_MMU_DISABLED;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  162  			break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  163  		}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  164  		fallthrough;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  165  	case TR_EL2:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  166  	case TR_EL20:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  167  		if (!(sctlr & SCTLR_ELx_M))
d6a01a2dc760c8 Marc Zyngier 2024-06-18  168  			wr->level = S1_MMU_DISABLED;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  169  		break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  170  	}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  171  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  172  	if (wr->level == S1_MMU_DISABLED) {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  173  		if (va >= BIT(kvm_get_pa_bits(vcpu->kvm)))
d6a01a2dc760c8 Marc Zyngier 2024-06-18  174  			goto addrsz;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  175  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  176  		wr->pa = va;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  177  		return 0;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  178  	}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  179  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  180  	wi->be = sctlr & SCTLR_ELx_EE;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  181  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  182  	wi->hpd  = kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, HPDS, IMP);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  183  	wi->hpd &= (wi->regime == TR_EL2 ?
d6a01a2dc760c8 Marc Zyngier 2024-06-18  184  		    FIELD_GET(TCR_EL2_HPD, tcr) :
d6a01a2dc760c8 Marc Zyngier 2024-06-18  185  		    (va55 ?
d6a01a2dc760c8 Marc Zyngier 2024-06-18  186  		     FIELD_GET(TCR_HPD1, tcr) :
d6a01a2dc760c8 Marc Zyngier 2024-06-18  187  		     FIELD_GET(TCR_HPD0, tcr)));
5e21b297872237 Marc Zyngier 2024-10-23  188  	/* R_JHSVW */
5e21b297872237 Marc Zyngier 2024-10-23  189  	wi->hpd |= s1pie_enabled(vcpu, wi->regime);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  190  
8a9b304d7e2276 Marc Zyngier 2024-10-23  191  	/* Do we have POE? */
8a9b304d7e2276 Marc Zyngier 2024-10-23  192  	compute_s1poe(vcpu, wi);
8a9b304d7e2276 Marc Zyngier 2024-10-23  193  
8a9b304d7e2276 Marc Zyngier 2024-10-23  194  	/* R_BVXDG */
8a9b304d7e2276 Marc Zyngier 2024-10-23  195  	wi->hpd |= (wi->poe || wi->e0poe);
8a9b304d7e2276 Marc Zyngier 2024-10-23  196  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  197  	/* Someone was silly enough to encode TG0/TG1 differently */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  198  	if (va55) {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  199  		wi->txsz = FIELD_GET(TCR_T1SZ_MASK, tcr);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  200  		tg = FIELD_GET(TCR_TG1_MASK, tcr);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  201  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  202  		switch (tg << TCR_TG1_SHIFT) {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  203  		case TCR_TG1_4K:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  204  			wi->pgshift = 12;	 break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  205  		case TCR_TG1_16K:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  206  			wi->pgshift = 14;	 break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  207  		case TCR_TG1_64K:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  208  		default:	    /* IMPDEF: treat any other value as 64k */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  209  			wi->pgshift = 16;	 break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  210  		}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  211  	} else {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  212  		wi->txsz = FIELD_GET(TCR_T0SZ_MASK, tcr);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  213  		tg = FIELD_GET(TCR_TG0_MASK, tcr);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  214  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  215  		switch (tg << TCR_TG0_SHIFT) {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  216  		case TCR_TG0_4K:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  217  			wi->pgshift = 12;	 break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  218  		case TCR_TG0_16K:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  219  			wi->pgshift = 14;	 break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  220  		case TCR_TG0_64K:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  221  		default:	    /* IMPDEF: treat any other value as 64k */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  222  			wi->pgshift = 16;	 break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  223  		}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  224  	}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  225  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  226  	/* R_PLCGL, R_YXNYW */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  227  	if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR2_EL1, ST, 48_47)) {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  228  		if (wi->txsz > 39)
d6a01a2dc760c8 Marc Zyngier 2024-06-18  229  			goto transfault_l0;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  230  	} else {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  231  		if (wi->txsz > 48 || (BIT(wi->pgshift) == SZ_64K && wi->txsz > 47))
d6a01a2dc760c8 Marc Zyngier 2024-06-18  232  			goto transfault_l0;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  233  	}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  234  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  235  	/* R_GTJBY, R_SXWGM */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  236  	switch (BIT(wi->pgshift)) {
d6a01a2dc760c8 Marc Zyngier 2024-06-18  237  	case SZ_4K:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  238  		lva = kvm_has_feat(vcpu->kvm, ID_AA64MMFR0_EL1, TGRAN4, 52_BIT);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  239  		lva &= tcr & (wi->regime == TR_EL2 ? TCR_EL2_DS : TCR_DS);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  240  		break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  241  	case SZ_16K:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  242  		lva = kvm_has_feat(vcpu->kvm, ID_AA64MMFR0_EL1, TGRAN16, 52_BIT);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  243  		lva &= tcr & (wi->regime == TR_EL2 ? TCR_EL2_DS : TCR_DS);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  244  		break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  245  	case SZ_64K:
d6a01a2dc760c8 Marc Zyngier 2024-06-18  246  		lva = kvm_has_feat(vcpu->kvm, ID_AA64MMFR2_EL1, VARange, 52);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  247  		break;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  248  	}
d6a01a2dc760c8 Marc Zyngier 2024-06-18  249  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  250  	if ((lva && wi->txsz < 12) || (!lva && wi->txsz < 16))
d6a01a2dc760c8 Marc Zyngier 2024-06-18  251  		goto transfault_l0;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  252  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  253  	ia_bits = get_ia_size(wi);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  254  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  255  	/* R_YYVYV, I_THCZK */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  256  	if ((!va55 && va > GENMASK(ia_bits - 1, 0)) ||
d6a01a2dc760c8 Marc Zyngier 2024-06-18  257  	    (va55 && va < GENMASK(63, ia_bits)))
d6a01a2dc760c8 Marc Zyngier 2024-06-18  258  		goto transfault_l0;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  259  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  260  	/* I_ZFSYQ */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  261  	if (wi->regime != TR_EL2 &&
d6a01a2dc760c8 Marc Zyngier 2024-06-18  262  	    (tcr & (va55 ? TCR_EPD1_MASK : TCR_EPD0_MASK)))
d6a01a2dc760c8 Marc Zyngier 2024-06-18  263  		goto transfault_l0;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  264  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  265  	/* R_BNDVG and following statements */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  266  	if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR2_EL1, E0PD, IMP) &&
d6a01a2dc760c8 Marc Zyngier 2024-06-18 @267  	    as_el0 && (tcr & (va55 ? TCR_E0PD1 : TCR_E0PD0)))
d6a01a2dc760c8 Marc Zyngier 2024-06-18  268  		goto transfault_l0;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  269  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  270  	/* AArch64.S1StartLevel() */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  271  	stride = wi->pgshift - 3;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  272  	wi->sl = 3 - (((ia_bits - 1) - wi->pgshift) / stride);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  273  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  274  	ps = (wi->regime == TR_EL2 ?
d6a01a2dc760c8 Marc Zyngier 2024-06-18  275  	      FIELD_GET(TCR_EL2_PS_MASK, tcr) : FIELD_GET(TCR_IPS_MASK, tcr));
d6a01a2dc760c8 Marc Zyngier 2024-06-18  276  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  277  	wi->max_oa_bits = min(get_kvm_ipa_limit(), ps_to_output_size(ps));
d6a01a2dc760c8 Marc Zyngier 2024-06-18  278  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  279  	/* Compute minimal alignment */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  280  	x = 3 + ia_bits - ((3 - wi->sl) * stride + wi->pgshift);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  281  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  282  	wi->baddr = ttbr & TTBRx_EL1_BADDR;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  283  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  284  	/* R_VPBBF */
d6a01a2dc760c8 Marc Zyngier 2024-06-18  285  	if (check_output_size(wi->baddr, wi))
d6a01a2dc760c8 Marc Zyngier 2024-06-18  286  		goto addrsz;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  287  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  288  	wi->baddr &= GENMASK_ULL(wi->max_oa_bits - 1, x);
d6a01a2dc760c8 Marc Zyngier 2024-06-18  289  
d6a01a2dc760c8 Marc Zyngier 2024-06-18  290  	return 0;
d6a01a2dc760c8 Marc Zyngier 2024-06-18  291  

:::::: The code at line 267 was first introduced by commit
:::::: d6a01a2dc760c8350fa182a6afd69fabab131f73 KVM: arm64: nv: Add SW walker for AT S1 emulation

:::::: TO: Marc Zyngier <maz at kernel.org>
:::::: CC: Marc Zyngier <maz at kernel.org>

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


From andi.shyti at kernel.org  Thu Dec 19 02:25:36 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Thu, 19 Dec 2024 11:25:36 +0100
Subject: [PATCH v3] i2c: imx: add imx7d compatible string for applying
 errata ERR007805
In-Reply-To: <AM0PR0402MB39379D10473292DA6533A757E8062@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <20241218044238.143414-1-carlos.song@nxp.com>
 <Z2O1PFr4ZQHXTsrX@pengutronix.de>
 <AM0PR0402MB39379D10473292DA6533A757E8062@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <brzvlpspjm66awnkshxvw7xefxxjbjx5v5mhqd3jl7befx33fy@mfi3pbagfy7a>

Hi Carlos,

> It will be this in V4:

no need to send a v4.

Andi


From johan at kernel.org  Thu Dec 19 02:37:34 2024
From: johan at kernel.org (Johan Hovold)
Date: Thu, 19 Dec 2024 11:37:34 +0100
Subject: [PATCH V4 0/5] arm_scmi: vendors: Qualcomm Generic Vendor
 Extensions
In-Reply-To: <132d1404-9009-9fb5-1fb9-63eca03ce9fc@quicinc.com>
References: <20241007061023.1978380-1-quic_sibis@quicinc.com>
 <ZytnRc94iKUfMYH0@hovoldconsulting.com>
 <ZyvLktLUZOGP-LH5@pluto>
 <Zy4qvedrmkRdPR3x@hovoldconsulting.com>
 <8d42682b-0fa7-3962-da12-728cfe64903b@quicinc.com>
 <Z0BC203BhGEmXcJi@hovoldconsulting.com>
 <d61bb7bc-d824-883a-4edd-109ae74076c1@quicinc.com>
 <Z1HMWUa_QCsNA1-Q@hovoldconsulting.com>
 <132d1404-9009-9fb5-1fb9-63eca03ce9fc@quicinc.com>
Message-ID: <Z2P3bh04xXsreBF7@hovoldconsulting.com>

On Tue, Dec 17, 2024 at 05:19:25PM +0530, Sibi Sankar wrote:
> On 12/5/24 21:22, Johan Hovold wrote:
> > On Thu, Dec 05, 2024 at 04:26:55PM +0530, Sibi Sankar wrote:
> >> On 11/22/24 14:07, Johan Hovold wrote:
> > 
> >>> I have a Lenovo ThinkPad T14s set up now so I gave this series a spin
> >>> there too, and there I do *not* see the above mentioned -EOPNOSUPP error
> >>> and the memlat driver probes successfully.
> >>>
> >>> On the other hand, this series seems to have no effect on a kernel
> >>> compilation benchmark. Is that expected?
> >>
> >> I can have a look at your tree. But memlat in general
> >> depends on the cpu frequency when your benchmarks max
> >> the cpu's the ddr/llcc are scaled accordingly by it.
> > 
> > A kernel compilation should max out the CPU frequency on all cores.

Answering my own question here; bwmon should scale the buses for
benchmarks like kernel compilations so I guess the non-existing impact
of memlat is expected here.

Ettore helped me run some further benchmarks, including cachebench, but
also saw no positive (or negative) effect with this series running on an
X1E CRD (with recent firmware).

Do you have any suggestions of benchmarks to run where the effect of
memlat should show up? What have you been using for testing?

I did measure a possibly slightly higher (idle) power consumption with
memlat, but I guess that is also expected given the intended more
aggressive ramping of the bus clocks.

These are the branches (and configs; johan_defconfig) we've used for
testing:

	https://github.com/jhovold/linux/tree/wip/x1e80100-6.13-rc3
	https://github.com/jhovold/linux/tree/wip/x1e80100-6.13-rc3-memlat

> >>> And does this mean that you should stick with the uppercase "MEMLAT"
> >>> string after all? The firmware on my CRD is not the latest one, but I am
> >>> using the latest available firmware for the T14s.
> >>
> >> We should stick with "memlat" if we run into a device in the
> >> wild that doesn't support "MEMLAT"
> > 
> > Ok. So the updated firmware supports both strings?
> 
> Sry for the delay, was out sick. Yes the updated firmware supports both
> strings.

No worries, hope you're feeling better.

I noticed that the firmware on the T14s indeed accepts both strings.

Johan


From vt at altlinux.org  Thu Dec 19 02:49:22 2024
From: vt at altlinux.org (Vitaly Chikunov)
Date: Thu, 19 Dec 2024 13:49:22 +0300
Subject: [PATCH 6.6 v1] KVM: arm64: Disable MPAM visibility by default
 and ignore VMM writes
In-Reply-To: <20241217104058.GA2151333@e124191.cambridge.arm.com>
References: <20241212151406.1436382-1-joey.gouly@arm.com>
 <2024121528-refurbish-plausibly-31c7@gregkh>
 <20241217104058.GA2151333@e124191.cambridge.arm.com>
Message-ID: <fqmjpadvbc7hoakm5qsmaxbgr7jomuehxjm3axo3sbpl4nzqvg@innog6dkmwqd>

Marc, Joey,

On Tue, Dec 17, 2024 at 10:40:58AM GMT, Joey Gouly wrote:
> On Sun, Dec 15, 2024 at 10:22:53AM +0100, Greg KH wrote:
> > On Thu, Dec 12, 2024 at 03:14:06PM +0000, Joey Gouly wrote:
> > > From: James Morse <james.morse at arm.com>
> > > 
> > > commit 6685f5d572c22e1003e7c0d089afe1c64340ab1f upstream.
> > > 
> > > commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits in
> > > ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to guests,
> > > but didn't add trap handling. A previous patch supplied the missing trap
> > > handling.
> > > 
> > > Existing VMs that have the MPAM field of ID_AA64PFR0_EL1 set need to
> > > be migratable, but there is little point enabling the MPAM CPU
> > > interface on new VMs until there is something a guest can do with it.
> > > 
> > > Clear the MPAM field from the guest's ID_AA64PFR0_EL1 and on hardware
> > > that supports MPAM, politely ignore the VMMs attempts to set this bit.
> > > 
> > > Guests exposed to this bug have the sanitised value of the MPAM field,
> > > so only the correct value needs to be ignored. This means the field
> > > can continue to be used to block migration to incompatible hardware
> > > (between MPAM=1 and MPAM=5), and the VMM can't rely on the field
> > > being ignored.
> > > 
> > > Signed-off-by: James Morse <james.morse at arm.com>
> > > Co-developed-by: Joey Gouly <joey.gouly at arm.com>
> > > Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> > > Reviewed-by: Gavin Shan <gshan at redhat.com>
> > > Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> > > Reviewed-by: Marc Zyngier <maz at kernel.org>
> > > Link: https://lore.kernel.org/r/20241030160317.2528209-7-joey.gouly at arm.com
> > > Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> > > [ joey: fixed up merge conflict, no ID_FILTERED macro in 6.6 ]
> > > Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> > > Cc: stable at vger.kernel.org # 6.6.x
> > > Cc: Vitaly Chikunov <vt at altlinux.org>
> > > Link: https://lore.kernel.org/linux-arm-kernel/20241202045830.e4yy3nkvxtzaybxk at altlinux.org/
> > > ---
> > > 
> > > This fixes an issue seen when using KVM with a 6.6 host kernel, and
> > > newer (6.13+) kernels in the guest.
> > > 
> > > Tested with a stripped down version of set_id_regs from the original
> > > patch series.
> > 
> > What about 6.12.y?  You can't just skip a stable tree, otherwise you
> > will get a regression when you upgrade to 6.12.y, right?
> 
> I did have it ported/tested locally, but I wasn't sure of the stable process,
> so just sent out one!  Next time I will send all the backports at the same
> time.
> 
> Thanks Marc Z for sending it out!

Thank you for backporting this, and thanks to everyone involved in the fix.

Vitaly,

> 
> Joey


From angelogioacchino.delregno at collabora.com  Thu Dec 19 02:54:12 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 11:54:12 +0100
Subject: [PATCH v3 07/33] dt-bindings: display: mediatek: Add binding for
 MT8195 HDMI-TX v2
In-Reply-To: <rsnyljmkdf7i74bkrlf5nesp2sa3n6xcnzsqao4znmczjpfyq2@dsakz56s4ypt>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
 <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>
 <rsnyljmkdf7i74bkrlf5nesp2sa3n6xcnzsqao4znmczjpfyq2@dsakz56s4ypt>
Message-ID: <9a75e88c-d90d-4ea8-b5c3-6d056d4f0498@collabora.com>

Il 18/12/24 09:20, Krzysztof Kozlowski ha scritto:
> On Tue, Dec 17, 2024 at 04:43:19PM +0100, AngeloGioacchino Del Regno wrote:
>> +  i2c:
>> +    type: object
>> +    $ref: /schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
>> +    unevaluatedProperties: false
>> +    description: HDMI DDC I2C controller
>> +
>> +  phys:
>> +    maxItems: 1
>> +    description: PHY providing clocking TMDS and pixel to controller
>> +
>> +  phy-names:
>> +    items:
>> +      - const: hdmi
>> +
>> +  pinctrl-0: true
>> +
>> +  pinctrl-names:
>> +    items:
>> +      - const: default
> 
> Drop both pinctrl entries.
> 
>> +
>> +  power-domains:
>> +    maxItems: 1
>> +
>> +  '#sound-dai-cells':
>> +    const: 1
>> +
>> +  ports:
>> +    $ref: /schemas/graph.yaml#/properties/ports
>> +
>> +    properties:
>> +      port at 0:
>> +        $ref: /schemas/graph.yaml#/properties/port
>> +        description:
>> +          Input port, usually connected to the output port of a DPI
>> +
>> +      port at 1:
>> +        $ref: /schemas/graph.yaml#/properties/port
>> +        description:
>> +          Output port that must be connected either to the input port of
>> +          a HDMI connector node containing a ddc-i2c-bus, or to the input
>> +          port of an attached bridge chip, such as a SlimPort transmitter.
>> +
>> +    required:
>> +      - port at 0
>> +      - port at 1
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-names
> 
> Please keep the same order of things here and in main properties
> section.
> 
>> +  - interrupts
>> +  - power-domains
>> +  - phys
>> +  - phy-names
>> +  - ports
>> +
> 
> You need allOf: with ref to dai-common.yaml.
> 
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/mt8195-clk.h>
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +    #include <dt-bindings/power/mt8195-power.h>
>> +
>> +    soc {
>> +        #address-cells = <2>;
>> +        #size-cells = <2>;
>> +
>> +        hdmi-tx at 1c300000 {
> 
> hdmi@
> 
> Best regards,
> Krzysztof
> 

Thanks for the great review krzk.

I was wondering if it'd be more straightforward to just send the bindings in a
different series, instead of sending another batch of 33 (actually, 34, because
I forgot one commit adding the DDC binding, ugh!) patches...

CK, any objections?

Cheers,
Angelo


From andi.shyti at kernel.org  Thu Dec 19 02:50:51 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Thu, 19 Dec 2024 11:50:51 +0100
Subject: [PATCH v3] i2c: imx: add imx7d compatible string for applying
 errata ERR007805
In-Reply-To: <20241218044238.143414-1-carlos.song@nxp.com>
References: <20241218044238.143414-1-carlos.song@nxp.com>
Message-ID: <zhl7dmzfvoizotjb567psnvyu34vee3hlrbsgb6uchshrj7bti@touezue3vqwe>

Hi Carlos,

On Wed, Dec 18, 2024 at 12:42:38PM +0800, Carlos Song wrote:
> Compatible string "fsl,imx7d-i2c" is not exited at i2c-imx driver
> compatible string table, at the result, "fsl,imx21-i2c" will be
> matched, but it will cause errata ERR007805 not be applied in fact.
> 
> So Add "fsl,imx7d-i2c" compatible string in i2c-imx driver to apply
> the errata ERR007805(https://www.nxp.com/webapp/Download?colCode=
> IMX7DS_2N09P).
> 
> "fsl,imx7d-i2c" already is documented in binding doc. This errata
> fix has been included in imx6_i2c_hwdata and it is the same in all
> I.MX6/7/8, so just reuse it.
> 
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>

with the commit log changes, merged to i2c/i2c-host-fixes.

Thanks,
Andi


From tudor.ambarus at linaro.org  Thu Dec 19 02:50:58 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 19 Dec 2024 10:50:58 +0000
Subject: [PATCH v5 1/3] dt-bindings: mailbox: add google,gs101-mbox
In-Reply-To: <20241217-acpm-v4-upstream-mbox-v5-1-cd1d3951fe84@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
 <20241217-acpm-v4-upstream-mbox-v5-1-cd1d3951fe84@linaro.org>
Message-ID: <ec3cdfd1-df7a-466c-8581-c9546ca6b089@linaro.org>

Hi, Krzysztof, Jassi,

On 12/17/24 9:40 AM, Tudor Ambarus wrote:

> diff --git a/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml

cut

> +
> +  '#mbox-cells':
> +    description: |
> +      <&phandle type channel>
> +      phandle : label name of controller.
> +      type    : channel type, doorbell or data-transfer.
> +      channel : channel number.
> +
> +      Here is how a client can reference them:
> +      mboxes = <&ap2apm_mailbox DOORBELL 2>;
> +      mboxes = <&ap2apm_mailbox DATA 3>;
> +    const: 2
> +

Revisiting this, I think that for the ACPM interface mailbox client use
case, it would be better to introduce a mbox property where I reference
just the phandle to the controller:
	mbox = <&ap2apm_mailbox>;

The ACPM interface discovers the mailbox channel IDs at runtime by
parsing SRAM. And all ACPM's channels are of type DOORBELL, thus
specifying the type and channel in DT is redundant.

It would require to extend a bit the mailbox core to provide a
mbox_request_channel_by_args() method. I already wrote a draft and
tested it.

Do you find the idea fine?

Thanks,
ta


From maz at kernel.org  Thu Dec 19 02:52:30 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 10:52:30 +0000
Subject: [PATCH v13 4/9] irqchip/gic-v3-its: Add DOMAIN_BUS_DEVICE_PCI_EP_MSI support
In-Reply-To: <20241218-ep-msi-v13-4-646e2192dc24@nxp.com>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
	<20241218-ep-msi-v13-4-646e2192dc24@nxp.com>
Message-ID: <868qscq70x.wl-maz@kernel.org>

On Wed, 18 Dec 2024 23:08:39 +0000,
Frank Li <Frank.Li at nxp.com> wrote:
> 
>            ??????????????????????????????????
>            ?                                ?
>            ?     PCI Endpoint Controller    ?
>            ?                                ?
>            ?   ???????  ???????     ??????? ?
> PCI Bus    ?   ?     ?  ?     ?     ?     ? ?
> ?????????? ?   ?Func1?  ?Func2? ... ?Func ? ?
> Doorbell   ?   ?     ?  ?     ?     ?<n>  ? ?
>            ?   ?     ?  ?     ?     ?     ? ?
>            ?   ???????  ???????     ??????? ?
>            ?      ?        ?           ?    ?
>            ??????????????????????????????????
>                   ?        ?           ?
>                   ?        ?           ?
>                ??????????????????????????
>                ?    MSI Controller      ?
>                ??????????????????????????
> 
> Add domain DOMAIN_BUS_DEVICE_PCI_EP_MSI to allocate MSI domain for Endpoint
> function in PCI Endpoint (EP) controller, So PCI Root Complex (RC) can
> write MSI message to MSI controller to trigger doorbell IRQ for difference
> EP functions.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> change from v12 to v13
> - new patch

This might be v13, but after all this time, I have no idea what you
are trying to do. You keep pasting this non-ASCII drawing in commit
messages, but I still have no idea what this PCI Bus Doorbell
represents.

I appreciate the knowledge shortage is on my end, but it would
definitely help if someone would take the time to explain what this is
all about.

From what I gather, the ITS is actually on an end-point, and get
writes from the host, but that doesn't answer much.

> ---
>  drivers/irqchip/irq-gic-v3-its-msi-parent.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
> index b2a4b67545b82..16e7d53f0b133 100644
> --- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
> +++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
> @@ -5,6 +5,7 @@
>  // Copyright (C) 2022 Intel
>  
>  #include <linux/acpi_iort.h>
> +#include <linux/pci-ep-msi.h>
>  #include <linux/pci.h>
>  
>  #include "irq-gic-common.h"
> @@ -173,6 +174,19 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
>  	return its_pmsi_prepare_devid(domain, dev, nvec, info, dev_id);
>  }
>  
> +static int its_pci_ep_msi_prepare(struct irq_domain *domain, struct device *dev,
> +				  int nvec, msi_alloc_info_t *info)
> +{
> +	u32 dev_id;
> +	int ret;
> +
> +	ret = pci_epf_msi_domain_get_msi_rid(dev, &dev_id);

What this doesn't express is *how* are the writes conveyed to the ITS.
Specifically, the DevID is normally sampled as sideband information at
during the write transaction.

Obviously, you can't do that over PCI. So there is a lot of
undisclosed assumption about how the ITS is integrated, and how it
samples the DevID.

My conclusion is that this is not as generic as it seems to be. It is
definitely tied to implementation-specific behaviours, none of which
are explained.

Thanks,

	M.

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


From wenst at chromium.org  Thu Dec 19 02:53:02 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Thu, 19 Dec 2024 18:53:02 +0800
Subject: [PATCH] ASoC: mediatek: disable buffer pre-allocation
Message-ID: <20241219105303.548437-1-wenst@chromium.org>

On Chromebooks based on Mediatek MT8195 or MT8188, the audio frontend
(AFE) is limited to accessing a very small window (1 MiB) of memory,
which is described as a reserved memory region in the device tree.

On these two platforms, the maximum buffer size is given as 512 KiB.
The MediaTek common code uses the same value for preallocations. This
means that only the first two PCM substreams get preallocations, and
then the whole space is exhausted, barring any other substreams from
working. Since the substreams used are not always the first two, this
means audio won't work correctly.

This is observed on the MT8188 Geralt Chromebooks, on which the
"mediatek,dai-link" property was dropped when it was upstreamed. That
property causes the driver to only register the PCM substreams listed
in the property, and in the order given.

Instead of trying to compute an optimal value and figuring out which
streams are used, simply disable preallocation. The PCM buffers are
managed by the core and are allocated and released on the fly. There
should be no impact to any of the other MediaTek platforms.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 sound/soc/mediatek/common/mtk-afe-platform-driver.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
index 9b72b2a7ae91..6b6330583941 100644
--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c
+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
@@ -120,8 +120,8 @@ int mtk_afe_pcm_new(struct snd_soc_component *component,
 	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 
 	size = afe->mtk_afe_hardware->buffer_bytes_max;
-	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
-				       afe->dev, size, size);
+	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, afe->dev, 0, size);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_afe_pcm_new);
-- 
2.47.1.613.gc27f4b7a9f-goog



From nv at vosn.de  Thu Dec 19 02:54:11 2024
From: nv at vosn.de (Nikolaus Voss)
Date: Thur, 19 Dec 2024 11:54:11 +0100
Subject: [PATCH] clk: clk-imx8mp-audiomix: fix function signature
Message-ID: <20241219105447.889CB11FE@mail.steuer-voss.de>

clk_imx8mp_audiomix_reset_controller_register() in the
"if !CONFIG_RESET_CONTROLLER" branch had the first
argument missing. It is an empty function for this branch
so it wasn't immediately apparent.

Fixes: 6f0e817175c5 ("clk: imx: clk-audiomix: Add reset controller")
Cc: <stable at vger.kernel.org> # 6.12.x
Signed-off-by: Nikolaus Voss <nv at vosn.de>
---
 drivers/clk/imx/clk-imx8mp-audiomix.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx8mp-audiomix.c b/drivers/clk/imx/clk-imx8mp-audiomix.c
index b2cb157703c57..c409fc7e06186 100644
--- a/drivers/clk/imx/clk-imx8mp-audiomix.c
+++ b/drivers/clk/imx/clk-imx8mp-audiomix.c
@@ -278,7 +278,8 @@ static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev,
 
 #else /* !CONFIG_RESET_CONTROLLER */
 
-static int clk_imx8mp_audiomix_reset_controller_register(struct clk_imx8mp_audiomix_priv *priv)
+static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev,
+							 struct clk_imx8mp_audiomix_priv *priv)
 {
 	return 0;
 }
-- 
2.43.0



From code at stefan-gloor.ch  Thu Dec 19 02:56:23 2024
From: code at stefan-gloor.ch (Stefan Gloor)
Date: Thu, 19 Dec 2024 11:56:23 +0100
Subject: [PATCH] ARM: dts: sunxi: Add MMC alias for consistent enumeration
Message-ID: <20241219105622.13691-2-code@stefan-gloor.ch>

Add explicit alias for MMC devices, so that (e)MMC and micro SD cards
are enumerated consistently. This should fix spurious boot failures when
specifying a hard-coded root partition, e.g., mmcblk0p2.

Link: https://github.com/linux-sunxi/meta-sunxi/pull/431
Signed-off-by: Stefan Gloor <code at stefan-gloor.ch>
---
 arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-micro.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-micro.dts
index a1b89b2a2999..9cd1eb690134 100644
--- a/arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-micro.dts
@@ -60,6 +60,8 @@ aliases {
 		serial2 = &uart7;
 		spi0 = &spi1;
 		spi1 = &spi2;
+		mmc0 = &mmc0;
+		mmc1 = &mmc3;
 	};
 
 	chosen {
-- 
2.45.2



From neil.armstrong at linaro.org  Thu Dec 19 02:59:36 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 19 Dec 2024 11:59:36 +0100
Subject: (subset) [PATCH v7 0/3] SN65DSI83/4 lvds_vod_swing properties
In-Reply-To: <20241216085410.1968634-1-andrej.picej@norik.com>
References: <20241216085410.1968634-1-andrej.picej@norik.com>
Message-ID: <173460597657.883073.14115671156294694663.b4-ty@linaro.org>

Hi,

On Mon, 16 Dec 2024 09:54:07 +0100, Andrej Picej wrote:
> The LVDS differential voltage swing can be specified as arrays of min, max
> in microvolts. Two arrays, one for data-lanes and one for clock-lane can
> be specified. Additionally, because LVDS voltage swing depends on near-end
> termination this can now also be specified with separate property.
> 
> Driver goes through the tables, taken from datasheet [1] and selects the
> appropriate configuration. If appropriate configuration can not be found
> the probe fails. If these properties are not defined default values are
> used as before.
> 
> [...]

Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next)

[1/3] dt-bindings: drm/bridge: ti-sn65dsi83: Add properties for ti,lvds-vod-swing
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/63f4e7dfef8c1162e22cd25c9a23b125ba40dfc4
[2/3] drm/bridge: ti-sn65dsi83: Add ti,lvds-vod-swing optional properties
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/d2b8c6d5495706eee2347483ea89b5c13f256ff2

-- 
Neil



From angelogioacchino.delregno at collabora.com  Thu Dec 19 03:06:18 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 12:06:18 +0100
Subject: [PATCH] ASoC: mediatek: disable buffer pre-allocation
In-Reply-To: <20241219105303.548437-1-wenst@chromium.org>
References: <20241219105303.548437-1-wenst@chromium.org>
Message-ID: <e208a265-cd4a-4781-82a6-a7f4f2c47448@collabora.com>

Il 19/12/24 11:53, Chen-Yu Tsai ha scritto:
> On Chromebooks based on Mediatek MT8195 or MT8188, the audio frontend
> (AFE) is limited to accessing a very small window (1 MiB) of memory,
> which is described as a reserved memory region in the device tree.
> 
> On these two platforms, the maximum buffer size is given as 512 KiB.
> The MediaTek common code uses the same value for preallocations. This
> means that only the first two PCM substreams get preallocations, and
> then the whole space is exhausted, barring any other substreams from
> working. Since the substreams used are not always the first two, this
> means audio won't work correctly.
> 
> This is observed on the MT8188 Geralt Chromebooks, on which the
> "mediatek,dai-link" property was dropped when it was upstreamed. That
> property causes the driver to only register the PCM substreams listed
> in the property, and in the order given.
> 
> Instead of trying to compute an optimal value and figuring out which
> streams are used, simply disable preallocation. The PCM buffers are
> managed by the core and are allocated and released on the fly. There
> should be no impact to any of the other MediaTek platforms.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

No there's no impact on the older ones, it's fine and I agree.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   sound/soc/mediatek/common/mtk-afe-platform-driver.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
> index 9b72b2a7ae91..6b6330583941 100644
> --- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c
> +++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
> @@ -120,8 +120,8 @@ int mtk_afe_pcm_new(struct snd_soc_component *component,
>   	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
>   
>   	size = afe->mtk_afe_hardware->buffer_bytes_max;
> -	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
> -				       afe->dev, size, size);
> +	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, afe->dev, 0, size);
> +
>   	return 0;
>   }
>   EXPORT_SYMBOL_GPL(mtk_afe_pcm_new);




From angelogioacchino.delregno at collabora.com  Thu Dec 19 03:09:52 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 12:09:52 +0100
Subject: [PATCH v2 1/3] dt-bindings: display: mediatek: ovl: Modify rules
 for MT8195/MT8188
In-Reply-To: <20241213095044.23757-2-jason-jh.lin@mediatek.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
 <20241213095044.23757-2-jason-jh.lin@mediatek.com>
Message-ID: <6f92c81f-84d0-4306-96d2-1cfc2ddb72e0@collabora.com>

Il 13/12/24 10:50, Jason-JH.Lin ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.com>
> 
> Modify rules for both MT8195 and MT8188.
> Hardware capabilities include color formats and AFBC are
> changed since MT8195, stop using the settings of MT8183.
> 
> Acked-by: Rob Herring <robh at kernel.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Reviewed-by: CK Hu <ck.hu at mediatek.com>
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> ---
>   .../bindings/display/mediatek/mediatek,ovl.yaml          | 9 ++++-----
>   1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> index 9ea796a033b2..8ca8e5966b9a 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> @@ -26,6 +26,7 @@ properties:
>             - mediatek,mt8173-disp-ovl
>             - mediatek,mt8183-disp-ovl
>             - mediatek,mt8192-disp-ovl
> +          - mediatek,mt8195-disp-ovl
>             - mediatek,mt8195-mdp3-ovl
>         - items:
>             - enum:
> @@ -36,16 +37,14 @@ properties:
>             - enum:
>                 - mediatek,mt6795-disp-ovl
>             - const: mediatek,mt8173-disp-ovl
> -      - items:
> -          - enum:
> -              - mediatek,mt8188-disp-ovl
> -              - mediatek,mt8195-disp-ovl
> -          - const: mediatek,mt8183-disp-ovl
>         - items:
>             - enum:
>                 - mediatek,mt8186-disp-ovl
>                 - mediatek,mt8365-disp-ovl
>             - const: mediatek,mt8192-disp-ovl
> +      - items:
> +          - const: mediatek,mt8188-disp-ovl
> +          - const: mediatek,mt8195-disp-ovl
>   
>     reg:
>       maxItems: 1


Jason, while doing MDP3 bindings for MT8188, I noticed that the binding for OVL is
missing; can you please add a commit on top of this series adding the following
snippet?

       - items:
           - const: mediatek,mt8188-mdp3-ovl
           - const: mediatek,mt8195-mdp3-ovl

...with a suggested-by tag it's going to be fine :-)

P.S.: Please refer to 
https://lore.kernel.org/r/20241218105320.38980-1-angelogioacchino.delregno at collabora.com

Thanks,
Angelo


From qperret at google.com  Thu Dec 19 03:10:23 2024
From: qperret at google.com (Quentin Perret)
Date: Thu, 19 Dec 2024 11:10:23 +0000
Subject: [RFC PATCH v2 21/58] KVM: arm64: pkvm: Add
 __pkvm_host_add_remove_page()
In-Reply-To: <20241212180423.1578358-22-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-22-smostafa@google.com>
Message-ID: <Z2P_H4eahmrvhkIl@google.com>

On Thursday 12 Dec 2024 at 18:03:45 (+0000), Mostafa Saleh wrote:
> From: Jean-Philippe Brucker <jean-philippe at linaro.org>
> +/*
> + * Temporarily unmap a page from the host stage-2, if @remove is true, or put it
> + * back. After restoring the ownership to host, the page will be lazy-mapped.
> + */
> +int __pkvm_host_add_remove_page(u64 pfn, bool remove)
> +{
> +	int ret;
> +	u64 host_addr = hyp_pfn_to_phys(pfn);
> +	u8 owner = remove ? PKVM_ID_HYP : PKVM_ID_HOST;
> +
> +	host_lock_component();
> +	ret = host_stage2_set_owner_locked(host_addr, PAGE_SIZE, owner);

Any reason why this can't be expressed using __pkvm_host_donate_hyp()
and __pkvm_hyp_donate_host()?

This doesn't check any state, so it feels like a dangerous primitive to
have. Is the issue the overhead of mapping/unmapping into EL2 stage-1?


From qperret at google.com  Thu Dec 19 03:14:23 2024
From: qperret at google.com (Quentin Perret)
Date: Thu, 19 Dec 2024 11:14:23 +0000
Subject: [RFC PATCH v2 11/58] KVM: arm64: pkvm: Add pkvm_udelay()
In-Reply-To: <20241212180423.1578358-12-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-12-smostafa@google.com>
Message-ID: <Z2QADxbdoYi5q9iT@google.com>

On Thursday 12 Dec 2024 at 18:03:35 (+0000), Mostafa Saleh wrote:
> From: Jean-Philippe Brucker <jean-philippe at linaro.org>
> 
> Add a simple delay loop for drivers.
> 
> This could use more work. It should be possible to insert a wfe and save
> power, but I haven't studied whether it is safe to do so with the host
> in control of the event stream. The SMMU driver will use wfe anyway for
> frequent waits (provided the implementation can send command queue
> events).

Mooh, I'm thoroughly hating that we need this -- pKVM is non preemptible
so we better not wait for too long.

I can surely figure it out from the following patches, but could you
please expand on the use-case?

On a side note I'm not too worried about the power impact of not having
a wfe in there, again we better not be spinning for long enough that
power starts to be noticeable.


From mike.leach at linaro.org  Thu Dec 19 03:17:57 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 11:17:57 +0000
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <53354e84-73c0-403b-bbc0-af619196596d@arm.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-3-quic_jinlmao@quicinc.com> <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>
 <PAVPR08MB967401DC65384CBA26B6829C8C052@PAVPR08MB9674.eurprd08.prod.outlook.com>
 <53354e84-73c0-403b-bbc0-af619196596d@arm.com>
Message-ID: <CAJ9a7VhWZkNcYWUfUkU8+OuQK-Cnu6kp6x23M4s5jHLa3_TpJQ@mail.gmail.com>

Hi,

On Wed, 18 Dec 2024 at 18:16, Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>
> Hi Mike
>
> On 18/12/2024 09:56, Mike Leach wrote:
> > Hi
> >
> >> -----Original Message-----
> >> From: Suzuki K Poulose <suzuki.poulose at arm.com>
> >> Sent: Wednesday, December 18, 2024 9:38 AM
> >> To: Mao Jinlong <quic_jinlmao at quicinc.com>; Mike Leach
> >> <mike.leach at linaro.org>; James Clark <James.Clark at arm.com>; Rob Herring
> >> <robh at kernel.org>; Krzysztof Kozlowski <krzk+dt at kernel.org>; Conor Dooley
> >> <conor+dt at kernel.org>; Mathieu Poirier <mathieu.poirier at linaro.org>; Bjorn
> >> Andersson <andersson at kernel.org>; Konrad Dybcio
> >> <konradybcio at kernel.org>
> >> Cc: coresight at lists.linaro.org; linux-arm-kernel at lists.infradead.org;
> >> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> >> msm at vger.kernel.org
> >> Subject: Re: [PATCH v6 2/2] coresight: Add label sysfs node support
> >>
> >> On 17/12/2024 06:33, Mao Jinlong wrote:
> >>> For some coresight components like CTI and TPDM, there could be
> >>> numerous of them. From the node name, we can only get the type and
> >>> register address of the component. We can't identify the HW or the
> >>> system the component belongs to. Add label sysfs node support for
> >>> showing the intuitive name of the device.
> >>>
> >>> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
> >>> ---
> >>>    .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
> >>>    .../sysfs-bus-coresight-devices-funnel        |  6 ++++
> >>>    .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
> >>>    drivers/hwtracing/coresight/coresight-sysfs.c | 32
> >> +++++++++++++++++++
> >>>    4 files changed, 50 insertions(+)
> >>
> >> Do you think we need to name the devices using the label ?
> >>
> >
> > No - absolutely not. If we use label to name devices then we have to validate that the string is a correctly formed device name and that it has not been previously used.
>
> Anything that doesn't contain '/' can be a device name ? And it is very
> easy to find if the device name has been used in the coresight bus,
> after all these devices only appear there.
>
> It is as good as :
>
> bus_find_device_by_name(coresight_bus_type, NULL, name) == NULL
>
> Of course with coresight_mutex() held.
>
> Suzuki
>

DTS label property (DT spec 4.1.2) is a freeform string, specified to
be a human readable description of the device, e.g. :-

cti0 at 0x1000 {
reg = <0x1000>;
label = "main system CTI";
};

Arguably the label is completely unnecessary - as the @0x1000 tells
the knowledgeable user, with a hardware specification of the device
precisely what this CTI does and is related to.

The point of this patchset is to add context to the name at addr to make
the identification of the devices easier.

The DT compiler should ensure that the device tree is well formed.
Using driver selected names (cti_cpu0 ... etc) guarantees  that every
device found in the DT has a unique representation in sysfs.

Once a freeform string is used, then not only are duplicates possible,
illegal device names are possible, all of which can result in missing
nodes or worse. This requires handling / complications that are
unnecessary for the purpose.

Yes of course it is easy to look for duplicate names, reject bad ones,
emit errors - but that could end up with a partially working system
with missing components.

Why add potential for breakage when it is not necessary?

Regards

Mike

>
> >
> > Using the canonical driver selected names works best as we are guaranteed a unique name and the information label can be used to provide flexible context information that best matches the users requirements.
> >
> > Mike
> >
> >> Or is this enough ?
> >
> >> Suzuki
> >>
> >>
> >>>
> >>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> >>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> >>> index bf2869c413e7..909670e0451a 100644
> >>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> >>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
> >>> @@ -239,3 +239,9 @@ Date:           March 2020
> >>>    KernelVersion    5.7
> >>>    Contact: Mike Leach or Mathieu Poirier
> >>>    Description:     (Write) Clear all channel / trigger programming.
> >>> +
> >>> +What:           /sys/bus/coresight/devices/<cti-name>/label
> >>> +Date:           Dec 2024
> >>> +KernelVersion   6.14
> >>> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> >>> +Description:    (Read) Show hardware context information of device.
> >>> diff --git
> >>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> >>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> >>> index d75acda5e1b3..944aad879aeb 100644
> >>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> >>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
> >>> @@ -10,3 +10,9 @@ Date:             November 2014
> >>>    KernelVersion:   3.19
> >>>    Contact: Mathieu Poirier <mathieu.poirier at linaro.org>
> >>>    Description:     (RW) Defines input port priority order.
> >>> +
> >>> +What:           /sys/bus/coresight/devices/<memory_map>.funnel/label
> >>> +Date:           Dec 2024
> >>> +KernelVersion   6.14
> >>> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> >>> +Description:    (Read) Show hardware context information of device.
> >>> diff --git
> >>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> >>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> >>> index bf710ea6e0ef..309802246398 100644
> >>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> >>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> >>> @@ -257,3 +257,9 @@ 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 CMB
> >> subunit
> >>>             TPDM.
> >>> +
> >>> +What:           /sys/bus/coresight/devices/<tpdm-name>/label
> >>> +Date:           Dec 2024
> >>> +KernelVersion   6.14
> >>> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
> >>> +Description:    (Read) Show hardware context information of device.
> >>> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c
> >>> b/drivers/hwtracing/coresight/coresight-sysfs.c
> >>> index a01c9e54e2ed..4af40cd7d75a 100644
> >>> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
> >>> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
> >>> @@ -7,6 +7,7 @@
> >>>    #include <linux/device.h>
> >>>    #include <linux/idr.h>
> >>>    #include <linux/kernel.h>
> >>> +#include <linux/property.h>
> >>>
> >>>    #include "coresight-priv.h"
> >>>    #include "coresight-trace-id.h"
> >>> @@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device
> >> *dev,
> >>>    }
> >>>    static DEVICE_ATTR_RW(enable_source);
> >>>
> >>> +static ssize_t label_show(struct device *dev,
> >>> +           struct device_attribute *attr, char *buf) {
> >>> +
> >>> +   const char *str;
> >>> +   int ret = 0;
> >>> +
> >>> +   ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
> >>> +   if (ret == 0)
> >>> +           return scnprintf(buf, PAGE_SIZE, "%s\n", str);
> >>> +   else
> >>> +           return ret;
> >>> +}
> >>> +static DEVICE_ATTR_RO(label);
> >>> +
> >>>    static struct attribute *coresight_sink_attrs[] = {
> >>>     &dev_attr_enable_sink.attr,
> >>> +   &dev_attr_label.attr,
> >>>     NULL,
> >>>    };
> >>>    ATTRIBUTE_GROUPS(coresight_sink);
> >>>
> >>>    static struct attribute *coresight_source_attrs[] = {
> >>>     &dev_attr_enable_source.attr,
> >>> +   &dev_attr_label.attr,
> >>>     NULL,
> >>>    };
> >>>    ATTRIBUTE_GROUPS(coresight_source);
> >>>
> >>> +static struct attribute *coresight_link_attrs[] = {
> >>> +   &dev_attr_label.attr,
> >>> +   NULL,
> >>> +};
> >>> +ATTRIBUTE_GROUPS(coresight_link);
> >>> +
> >>> +static struct attribute *coresight_helper_attrs[] = {
> >>> +   &dev_attr_label.attr,
> >>> +   NULL,
> >>> +};
> >>> +ATTRIBUTE_GROUPS(coresight_helper);
> >>> +
> >>>    const struct device_type coresight_dev_type[] = {
> >>>     [CORESIGHT_DEV_TYPE_SINK] = {
> >>>             .name = "sink",
> >>> @@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
> >>>     },
> >>>     [CORESIGHT_DEV_TYPE_LINK] = {
> >>>             .name = "link",
> >>> +           .groups = coresight_link_groups,
> >>>     },
> >>>     [CORESIGHT_DEV_TYPE_LINKSINK] = {
> >>>             .name = "linksink",
> >>> @@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
> >>>     },
> >>>     [CORESIGHT_DEV_TYPE_HELPER] = {
> >>>             .name = "helper",
> >>> +           .groups = coresight_helper_groups,
> >>>     }
> >>>    };
> >>>    /* Ensure the enum matches the names and groups */
> >>
> >> _______________________________________________
> >> CoreSight mailing list -- coresight at lists.linaro.org To unsubscribe send an
> >> email to coresight-leave at lists.linaro.org
>


-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From smostafa at google.com  Thu Dec 19 03:19:26 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 19 Dec 2024 11:19:26 +0000
Subject: [RFC PATCH v2 21/58] KVM: arm64: pkvm: Add
 __pkvm_host_add_remove_page()
In-Reply-To: <Z2P_H4eahmrvhkIl@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-22-smostafa@google.com>
 <Z2P_H4eahmrvhkIl@google.com>
Message-ID: <Z2QBPtRvnB3PGvMG@google.com>

On Thu, Dec 19, 2024 at 11:10:23AM +0000, Quentin Perret wrote:
> On Thursday 12 Dec 2024 at 18:03:45 (+0000), Mostafa Saleh wrote:
> > From: Jean-Philippe Brucker <jean-philippe at linaro.org>
> > +/*
> > + * Temporarily unmap a page from the host stage-2, if @remove is true, or put it
> > + * back. After restoring the ownership to host, the page will be lazy-mapped.
> > + */
> > +int __pkvm_host_add_remove_page(u64 pfn, bool remove)
> > +{
> > +	int ret;
> > +	u64 host_addr = hyp_pfn_to_phys(pfn);
> > +	u8 owner = remove ? PKVM_ID_HYP : PKVM_ID_HOST;
> > +
> > +	host_lock_component();
> > +	ret = host_stage2_set_owner_locked(host_addr, PAGE_SIZE, owner);
> 
> Any reason why this can't be expressed using __pkvm_host_donate_hyp()
> and __pkvm_hyp_donate_host()?

That makes more sense, I will fix it.
> 
> This doesn't check any state, so it feels like a dangerous primitive to
> have. Is the issue the overhead of mapping/unmapping into EL2 stage-1?


From smostafa at google.com  Thu Dec 19 03:21:40 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 19 Dec 2024 11:21:40 +0000
Subject: [RFC PATCH v2 11/58] KVM: arm64: pkvm: Add pkvm_udelay()
In-Reply-To: <Z2QADxbdoYi5q9iT@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-12-smostafa@google.com>
 <Z2QADxbdoYi5q9iT@google.com>
Message-ID: <Z2QBxPyBsxGNSuzT@google.com>

On Thu, Dec 19, 2024 at 11:14:23AM +0000, Quentin Perret wrote:
> On Thursday 12 Dec 2024 at 18:03:35 (+0000), Mostafa Saleh wrote:
> > From: Jean-Philippe Brucker <jean-philippe at linaro.org>
> > 
> > Add a simple delay loop for drivers.
> > 
> > This could use more work. It should be possible to insert a wfe and save
> > power, but I haven't studied whether it is safe to do so with the host
> > in control of the event stream. The SMMU driver will use wfe anyway for
> > frequent waits (provided the implementation can send command queue
> > events).
> 
> Mooh, I'm thoroughly hating that we need this -- pKVM is non preemptible
> so we better not wait for too long.
> 
> I can surely figure it out from the following patches, but could you
> please expand on the use-case?

The driver needs to poll some SMMU MMIO, so it needs to measure time
in terms of udelay to timeout, at the moment its arbitrary set to 100ms.

Thanks,
Mostafa
> 
> On a side note I'm not too worried about the power impact of not having
> a wfe in there, again we better not be spinning for long enough that
> power starts to be noticeable.


From qperret at google.com  Thu Dec 19 03:23:04 2024
From: qperret at google.com (Quentin Perret)
Date: Thu, 19 Dec 2024 11:23:04 +0000
Subject: [RFC PATCH v2 12/58] KVM: arm64: Add __pkvm_{use, unuse}_dma()
In-Reply-To: <20241212180423.1578358-13-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-13-smostafa@google.com>
Message-ID: <Z2QCGFN5V41Vux6Z@google.com>

On Thursday 12 Dec 2024 at 18:03:36 (+0000), Mostafa Saleh wrote:
> +int __pkvm_host_unuse_dma(phys_addr_t phys_addr, size_t size)
> +{
> +	int i;
> +	size_t nr_pages = size >> PAGE_SHIFT;
> +
> +	if (WARN_ON(!PAGE_ALIGNED(phys_addr | size)))
> +		return -EINVAL;
> +
> +	host_lock_component();
> +	if (!range_is_memory(phys_addr, phys_addr + size))
> +		goto out_ret;

Nit: I think you can do this out of the critical section -- the memblock
list is guaranteed stable by construction.

> +	/*
> +	 * We end up here after the caller successfully unmapped the page from
> +	 * the IOMMU table. Which means that a ref is held, the page is shared
> +	 * in the host s2, there can be no failure.
> +	 */
> +	for (i = 0; i < nr_pages; i++)
> +		__pkvm_host_unuse_dma_page(phys_addr + i * PAGE_SIZE);
> +
> +out_ret:
> +	host_unlock_component();
> +	return 0;
> +}
> +
>  int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
>  			    enum kvm_pgtable_prot prot)
>  {
> -- 
> 2.47.0.338.g60cca15819-goog
> 


From anton.kirilov at arm.com  Thu Dec 19 03:25:32 2024
From: anton.kirilov at arm.com (anton.kirilov at arm.com)
Date: Thu, 19 Dec 2024 11:25:32 +0000
Subject: [PATCH] arm64: dts: rockchip: Enable the USB 3.0 port on NanoPi R6C/R6S
Message-ID: <20241219112532.482891-1-anton.kirilov@arm.com>

From: Anton Kirilov <anton.kirilov at arm.com>

Enable the USB 3.0 port on FriendlyElec NanoPi R6C/R6S boards.

Signed-off-by: Anton Kirilov <anton.kirilov at arm.com>
---
 .../boot/dts/rockchip/rk3588s-nanopi-r6.dtsi   | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
index 76a6e8e517e9..cbf09d0b4add 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
@@ -774,6 +774,15 @@ &tsadc {
 	status = "okay";
 };
 
+&u2phy0 {
+	status = "okay";
+};
+
+&u2phy0_otg {
+	phy-supply = <&vcc5v0_usb_otg0>;
+	status = "okay";
+};
+
 &u2phy2 {
 	status = "okay";
 };
@@ -796,6 +805,15 @@ &usb_host0_ohci {
 	status = "okay";
 };
 
+&usb_host0_xhci {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbdp_phy0 {
+	status = "okay";
+};
+
 &vop {
 	status = "okay";
 };
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Dec 19 03:27:33 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 12:27:33 +0100
Subject: [PATCH] drm/mediatek: mtk_dsi: Add registers to pdata to fix MT8186/MT8188
Message-ID: <20241219112733.47907-1-angelogioacchino.delregno@collabora.com>

Registers DSI_VM_CMD and DSI_SHADOW_DEBUG start at different
addresses in both MT8186 and MT8188 compared to the older IPs.

Add two members in struct mtk_dsi_driver_data to specify the
offsets for these two registers on a per-SoC basis, then do
specify those in all of the currently present SoC driver data.

This fixes writes to the Video Mode Command Packet Control
register, fixing enablement of command packet transmission
(VM_CMD_EN) and allowance of this transmission during the
VFP period (TS_VFP_EN) on both MT8186 and MT8188.

Fixes: 03d7adc41027 ("drm/mediatek: Add mt8186 dsi compatible to mtk_dsi.c")
Fixes: 814d5341f314 ("drm/mediatek: Add mt8188 dsi compatible to mtk_dsi.c")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index e61b9bc68e9a..978332cd52f5 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -139,11 +139,11 @@
 #define CLK_HS_POST			GENMASK(15, 8)
 #define CLK_HS_EXIT			GENMASK(23, 16)
 
-#define DSI_VM_CMD_CON		0x130
+/* DSI_VM_CMD_CON */
 #define VM_CMD_EN			BIT(0)
 #define TS_VFP_EN			BIT(5)
 
-#define DSI_SHADOW_DEBUG	0x190U
+/* DSI_SHADOW_DEBUG */
 #define FORCE_COMMIT			BIT(0)
 #define BYPASS_SHADOW			BIT(1)
 
@@ -187,6 +187,8 @@ struct phy;
 
 struct mtk_dsi_driver_data {
 	const u32 reg_cmdq_off;
+	const u32 reg_vm_cmd_off;
+	const u32 reg_shadow_dbg_off;
 	bool has_shadow_ctl;
 	bool has_size_ctl;
 	bool cmdq_long_packet_ctl;
@@ -367,8 +369,8 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
 
 static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 {
-	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
-	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
+	mtk_dsi_mask(dsi, dsi->driver_data->reg_vm_cmd_off, VM_CMD_EN, VM_CMD_EN);
+	mtk_dsi_mask(dsi, dsi->driver_data->reg_vm_cmd_off, TS_VFP_EN, TS_VFP_EN);
 }
 
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
@@ -714,7 +716,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 
 	if (dsi->driver_data->has_shadow_ctl)
 		writel(FORCE_COMMIT | BYPASS_SHADOW,
-		       dsi->regs + DSI_SHADOW_DEBUG);
+		       dsi->regs + dsi->driver_data->reg_shadow_dbg_off);
 
 	mtk_dsi_reset_engine(dsi);
 	mtk_dsi_phy_timconfig(dsi);
@@ -1263,26 +1265,36 @@ static void mtk_dsi_remove(struct platform_device *pdev)
 
 static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = {
 	.reg_cmdq_off = 0x200,
+	.reg_vm_cmd_off = 0x130,
+	.reg_shadow_dbg_off = 0x190
 };
 
 static const struct mtk_dsi_driver_data mt2701_dsi_driver_data = {
 	.reg_cmdq_off = 0x180,
+	.reg_vm_cmd_off = 0x130,
+	.reg_shadow_dbg_off = 0x190
 };
 
 static const struct mtk_dsi_driver_data mt8183_dsi_driver_data = {
 	.reg_cmdq_off = 0x200,
+	.reg_vm_cmd_off = 0x130,
+	.reg_shadow_dbg_off = 0x190,
 	.has_shadow_ctl = true,
 	.has_size_ctl = true,
 };
 
 static const struct mtk_dsi_driver_data mt8186_dsi_driver_data = {
 	.reg_cmdq_off = 0xd00,
+	.reg_vm_cmd_off = 0x200,
+	.reg_shadow_dbg_off = 0xc00,
 	.has_shadow_ctl = true,
 	.has_size_ctl = true,
 };
 
 static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
 	.reg_cmdq_off = 0xd00,
+	.reg_vm_cmd_off = 0x200,
+	.reg_shadow_dbg_off = 0xc00,
 	.has_shadow_ctl = true,
 	.has_size_ctl = true,
 	.cmdq_long_packet_ctl = true,
-- 
2.47.0



From qperret at google.com  Thu Dec 19 03:28:48 2024
From: qperret at google.com (Quentin Perret)
Date: Thu, 19 Dec 2024 11:28:48 +0000
Subject: [RFC PATCH v2 11/58] KVM: arm64: pkvm: Add pkvm_udelay()
In-Reply-To: <Z2QBxPyBsxGNSuzT@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-12-smostafa@google.com>
 <Z2QADxbdoYi5q9iT@google.com>
 <Z2QBxPyBsxGNSuzT@google.com>
Message-ID: <Z2QDcODuqcJojTpG@google.com>

On Thursday 19 Dec 2024 at 11:21:40 (+0000), Mostafa Saleh wrote:
> On Thu, Dec 19, 2024 at 11:14:23AM +0000, Quentin Perret wrote:
> > On Thursday 12 Dec 2024 at 18:03:35 (+0000), Mostafa Saleh wrote:
> > > From: Jean-Philippe Brucker <jean-philippe at linaro.org>
> > > 
> > > Add a simple delay loop for drivers.
> > > 
> > > This could use more work. It should be possible to insert a wfe and save
> > > power, but I haven't studied whether it is safe to do so with the host
> > > in control of the event stream. The SMMU driver will use wfe anyway for
> > > frequent waits (provided the implementation can send command queue
> > > events).
> > 
> > Mooh, I'm thoroughly hating that we need this -- pKVM is non preemptible
> > so we better not wait for too long.
> > 
> > I can surely figure it out from the following patches, but could you
> > please expand on the use-case?
> 
> The driver needs to poll some SMMU MMIO, so it needs to measure time
> in terms of udelay to timeout, at the moment its arbitrary set to 100ms.

OK, I'll look at the patches to see how hard it'd be to return to the
host for scheduling while this is happening. It's probably hard because
we're presumably in a funky state, but it's worth trying to figure it
out. Any EL2 section longer than 100us or so is problematic in my view,
so a 100*ms* timeout is scary!


From will at kernel.org  Thu Dec 19 03:30:20 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 11:30:20 +0000
Subject: [PATCH] iommu/arm-smmu-qcom: Only enable stall on smmu-v2
In-Reply-To: <20241216171017.4881-1-robdclark@gmail.com>
References: <20241216171017.4881-1-robdclark@gmail.com>
Message-ID: <20241219113019.GA23640@willie-the-truck>

On Mon, Dec 16, 2024 at 09:10:17AM -0800, Rob Clark wrote:
> From: Rob Clark <robdclark at chromium.org>
> 
> On mmu-500, stall-on-fault seems to stall all context banks, causing the
> GMU to misbehave.  So limit this feature to smmu-v2 for now.

MMU-500 has public documentation so please can you dig up what the
actual behaviour is rather than guess?

> This fixes an issue with an older mesa bug taking outo the system
> because of GMU going off into the year.

Sorry, but I don't understand this sentence.

Will


From anton.kirilov at arm.com  Thu Dec 19 03:31:45 2024
From: anton.kirilov at arm.com (anton.kirilov at arm.com)
Date: Thu, 19 Dec 2024 11:31:45 +0000
Subject: [PATCH] arm64: dts: rockchip: Fix the SD card detection on NanoPi R6C/R6S
Message-ID: <20241219113145.483205-1-anton.kirilov@arm.com>

From: Anton Kirilov <anton.kirilov at arm.com>

Fix the SD card detection on FriendlyElec NanoPi R6C/R6S boards.

Signed-off-by: Anton Kirilov <anton.kirilov at arm.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
index 76a6e8e517e9..c9749cb50076 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
@@ -434,6 +434,7 @@ &sdhci {
 &sdmmc {
 	bus-width = <4>;
 	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	max-frequency = <150000000>;
 	no-mmc;
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Dec 19 03:34:05 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 12:34:05 +0100
Subject: [PATCH v5 0/4] arm64: dts: mediatek: Add MT8186 Chinchou
In-Reply-To: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
References: <20241212062046.22509-1-xiazhengqiao@huaqin.corp-partner.google.com>
Message-ID: <173460804505.49444.13450128112085661822.b4-ty@collabora.com>

On Thu, 12 Dec 2024 14:20:42 +0800, Zhengqiao Xia wrote:
> This is v5 of the MT8186 Chromebook device tree series to support
> MT8186 chinchou platform. It is based on the "corsola" design.
> It includes chinchou and chinchou360, including LTE, stylus,
> touchscreen combinations.
> 
> Changes in v5:
> - move sku17 here to keep alphabetical order.
> - do not use the MTK_DRIVE_xxx definitions.
> - Modify exton to extcon
> - Link to v4: https://patchwork.kernel.org/project/linux-arm-kernel/cover/20241202032035.29045-1-xiazhengqiao at huaqin.corp-partner.google.com/
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/4] dt-bindings: arm: mediatek: Add MT8186 Chinchou Chromebook
      (no commit info)
[2/4] arm64: dts: mediatek: Add MT8186 Chinchou Chromebooks
      (no commit info)
[3/4] arm64: dts: mediatek: Add extcon node for DP bridge
      (no commit info)
[4/4] arm64: dts: mediatek: Modify audio codec name for pmic
      (no commit info)

Cheers,
Angelo




From fshao at chromium.org  Thu Dec 19 03:33:50 2024
From: fshao at chromium.org (Fei Shao)
Date: Thu, 19 Dec 2024 19:33:50 +0800
Subject: [PATCH] soc: mediatek: mtk-socinfo: Restructure SoC attribute information
Message-ID: <20241219113411.3999355-1-fshao@chromium.org>

So far, the MediaTek socinfo driver populates the SoC information as
follows:
  - family:  "MediaTek"
  - machine: "<marketing_name> (<soc_name>)"
      e.g.,  "Kompanio 1380 (MT8195)"
  - soc_id:  <null>

This approach has some drawbacks:
1.  "soc_id" can be used for showing the SoC name (e.g. "MT8195"), while
    it's currently unused.
2.  The newer socinfo API automatically populates the "machine"
    attribute with the model name from board DTS if unspecified, which
    we may want to preserve if possible.
3.  "machine" combines the marketing name and SoC name, making it
    trickier to parse. Ideally, the marketing name and SoC name should
    be in separate attributes so userspace to utilize them as needed.
4.  There's no guarantee that the marketing name will be announced along
    with the SoC name. If either is undetermined, the current design
    will result in a malformed "machine" output. This is observed on
    some newer MediaTek platforms, where the marketing name is still
    undetermined but the SoC information needs to be settled for device
    registration and validation before launch.

To address these points, this commit proposes a new theme to display the
SoC information:
  - family:  "MediaTek <marketing_name>"
      e.g.,  "MediaTek Kompanio 1380"
  - machine: "<dt_model_name>" (auto-populated)
      e.g.,  "Acer Tomato (rev1) board"
  - soc_id:  "<soc_name>"
      e.g.,  "MT8195"

Moreover, if the marketing name is not provided, the driver displays
"MediaTek" in the "family" attribute instead, consistent with the
previous behavior.

Restructure the way driver populates the SoC information as described
above.

Note that Mediatek-based Chromebooks are the primary consumers of this
socinfo driver, and Google has prepared corresponding userspace changes
to comply with this update, so the impact to userspace is controlled.

Signed-off-by: Fei Shao <fshao at chromium.org>
---

 drivers/soc/mediatek/mtk-socinfo.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c
index 123b12cd2543..b9dbc90d7814 100644
--- a/drivers/soc/mediatek/mtk-socinfo.c
+++ b/drivers/soc/mediatek/mtk-socinfo.c
@@ -62,17 +62,24 @@ static struct socinfo_data socinfo_data_table[] = {
 static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop)
 {
 	struct soc_device_attribute *attrs;
-	static char machine[30] = {0};
+	struct socinfo_data *data = mtk_socinfop->socinfo_data;
 	static const char *soc_manufacturer = "MediaTek";
 
 	attrs = devm_kzalloc(mtk_socinfop->dev, sizeof(*attrs), GFP_KERNEL);
 	if (!attrs)
 		return -ENOMEM;
 
-	snprintf(machine, sizeof(machine), "%s (%s)", mtk_socinfop->socinfo_data->marketing_name,
-		mtk_socinfop->socinfo_data->soc_name);
-	attrs->family = soc_manufacturer;
-	attrs->machine = machine;
+	if (data->marketing_name != NULL && data->marketing_name[0] != '\0')
+		attrs->family = devm_kasprintf(mtk_socinfop->dev, GFP_KERNEL, "MediaTek %s",
+					       data->marketing_name);
+	else
+		attrs->family = soc_manufacturer;
+
+	attrs->soc_id = data->soc_name;
+	/*
+	 * The "machine" field will be populated automatically with the model
+	 * name from board DTS (if available).
+	 **/
 
 	mtk_socinfop->soc_dev = soc_device_register(attrs);
 	if (IS_ERR(mtk_socinfop->soc_dev))
-- 
2.47.1.613.gc27f4b7a9f-goog



From krzk at kernel.org  Thu Dec 19 03:35:43 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 19 Dec 2024 12:35:43 +0100
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <f1c6da16-fbfd-40aa-a158-36ab713ce541@quicinc.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-3-quic_jinlmao@quicinc.com>
 <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>
 <f1c6da16-fbfd-40aa-a158-36ab713ce541@quicinc.com>
Message-ID: <15f4ebe2-a148-4927-8f01-2fcd414d480f@kernel.org>

On 18/12/2024 10:57, Jinlong Mao wrote:
> 
> 
> On 2024/12/18 17:38, Suzuki K Poulose wrote:
>> On 17/12/2024 06:33, Mao Jinlong wrote:
>>> For some coresight components like CTI and TPDM, there could be
>>> numerous of them. From the node name, we can only get the type and
>>> register address of the component. We can't identify the HW or the
>>> system the component belongs to. Add label sysfs node support for
>>> showing the intuitive name of the device.
>>>
>>> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
>>> ---
>>> ? .../testing/sysfs-bus-coresight-devices-cti?? |? 6 ++++
>>> ? .../sysfs-bus-coresight-devices-funnel??????? |? 6 ++++
>>> ? .../testing/sysfs-bus-coresight-devices-tpdm? |? 6 ++++
>>> ? drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++++++++++++++++++
>>> ? 4 files changed, 50 insertions(+)
>>
>> Do you think we need to name the devices using the label ? Or is this 
>> enough ?
>>
>> Suzuki
> Hi Suzuki,
> 
> In my opinion, we should use label as the device name.

As Linux device driver name?

No, that's not the point of label. We don't do such stuff, nowhere.


Best regards,
Krzysztof


From angelogioacchino.delregno at collabora.com  Thu Dec 19 03:45:49 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 12:45:49 +0100
Subject: [PATCH v2 1/3] dt-bindings: display: mediatek: ovl: Modify rules
 for MT8195/MT8188
In-Reply-To: <20241213095044.23757-2-jason-jh.lin@mediatek.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
 <20241213095044.23757-2-jason-jh.lin@mediatek.com>
Message-ID: <ba260dd3-a487-4b80-b52b-83cf8a45be79@collabora.com>

Il 13/12/24 10:50, Jason-JH.Lin ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.com>
> 
> Modify rules for both MT8195 and MT8188.
> Hardware capabilities include color formats and AFBC are
> changed since MT8195, stop using the settings of MT8183.
> 
> Acked-by: Rob Herring <robh at kernel.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Reviewed-by: CK Hu <ck.hu at mediatek.com>
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>

CK, can you please Ack this so that I can make it go through the mediatek tree
along with the devicetree changes?

Thanks,
Angelo

> ---
>   .../bindings/display/mediatek/mediatek,ovl.yaml          | 9 ++++-----
>   1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> index 9ea796a033b2..8ca8e5966b9a 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> @@ -26,6 +26,7 @@ properties:
>             - mediatek,mt8173-disp-ovl
>             - mediatek,mt8183-disp-ovl
>             - mediatek,mt8192-disp-ovl
> +          - mediatek,mt8195-disp-ovl
>             - mediatek,mt8195-mdp3-ovl
>         - items:
>             - enum:
> @@ -36,16 +37,14 @@ properties:
>             - enum:
>                 - mediatek,mt6795-disp-ovl
>             - const: mediatek,mt8173-disp-ovl
> -      - items:
> -          - enum:
> -              - mediatek,mt8188-disp-ovl
> -              - mediatek,mt8195-disp-ovl
> -          - const: mediatek,mt8183-disp-ovl
>         - items:
>             - enum:
>                 - mediatek,mt8186-disp-ovl
>                 - mediatek,mt8365-disp-ovl
>             - const: mediatek,mt8192-disp-ovl
> +      - items:
> +          - const: mediatek,mt8188-disp-ovl
> +          - const: mediatek,mt8195-disp-ovl
>   
>     reg:
>       maxItems: 1





From angelogioacchino.delregno at collabora.com  Thu Dec 19 03:49:22 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 12:49:22 +0100
Subject: [PATCH v3 0/2] Adding second source touchscreen used by some
 mt8183 devices
In-Reply-To: <20241213-touchscreen-v3-0-7c1f670913f9@chromium.org>
References: <20241213-touchscreen-v3-0-7c1f670913f9@chromium.org>
Message-ID: <173460896280.52937.15376299467879995072.b4-ty@collabora.com>

On Fri, 13 Dec 2024 05:27:46 +0000, Hsin-Te Yuan wrote:
> 
> 

Applied to v6.13-next/dts64, thanks!

[1/2] arm64: dts: mediatek: mt8183: kenzo: Support second source touchscreen
      commit: 5ec5dc73c5ac0c6e06803dc3b5aea4493e856568
[2/2] arm64: dts: mediatek: mt8183: willow: Support second source touchscreen
      commit: 9594935260d76bffe200bea6cfab6ba0752e70d9

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Thu Dec 19 03:51:20 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 12:51:20 +0100
Subject: [PATCH v4] arm64: dts: mt7986: add overlay for SATA power
 socket on BPI-R3
In-Reply-To: <20241206132401.70259-1-linux@fw-web.de>
References: <20241206132401.70259-1-linux@fw-web.de>
Message-ID: <173460908054.53645.11475281075607913939.b4-ty@collabora.com>

On Fri, 06 Dec 2024 14:23:59 +0100, Frank Wunderlich wrote:
> Bananapi R3 has a Power socket entended for using external SATA drives.
> This Socket is off by default but can be switched with gpio 8.
> 
> Add an overlay to activate it.
> 
> 

Applied to v6.13-next/dts64, thanks!

[1/1] arm64: dts: mt7986: add overlay for SATA power socket on BPI-R3
      commit: 312189ebb802a0242639a9c628cfdc6e532d8e11

Cheers,
Angelo




From dave.stevenson at raspberrypi.com  Thu Dec 19 03:54:31 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 19 Dec 2024 11:54:31 +0000
Subject: [PATCH v4 2/3] dt-bindings: display: Fix BCM2835 HVS bindings for BCM2712
In-Reply-To: <lzvcaspulvsulbulqinzftt3xtdyro64hi674u2bnkpvbrihri@e2o247mjom5s>
References: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
 <20241218-dt-bcm2712-fixes-v4-2-54cc88b6c229@raspberrypi.com> <lzvcaspulvsulbulqinzftt3xtdyro64hi674u2bnkpvbrihri@e2o247mjom5s>
Message-ID: <CAPY8ntCX8+yg1RFhAXu4ystGF_JivTh43RY=k2P0bUm5JxvzRA@mail.gmail.com>

Hi Krzysztof

On Thu, 19 Dec 2024 at 08:42, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On Wed, Dec 18, 2024 at 02:48:33PM +0000, Dave Stevenson wrote:
> > Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> > added the compatible string for BCM2712, but missed out that
> > the number of interrupts and clocks changed too, and both need to be
> > named.
> >
> > Update to validate clock, interrupts, and their names for the variants.
> >
> > Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> > Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> > ---
> >  .../bindings/display/brcm,bcm2835-hvs.yaml         | 84 ++++++++++++++++++----
> >  1 file changed, 70 insertions(+), 14 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> > index f91c9dce2a44..fd25ee5ce301 100644
> > --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> > +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> > @@ -20,11 +20,20 @@ properties:
> >      maxItems: 1
> >
> >    interrupts:
> > -    maxItems: 1
> > +    minItems: 1
> > +    maxItems: 3
> > +
> > +  interrupt-names:
> > +    minItems: 1
> > +    maxItems: 3
> >
> >    clocks:
> > -    maxItems: 1
> > -    description: Core Clock
> > +    minItems: 1
> > +    maxItems: 2
> > +
> > +  clock-names:
> > +    minItems: 1
> > +    maxItems: 2
> >
> >  required:
> >    - compatible
> > @@ -33,17 +42,64 @@ required:
> >
> >  additionalProperties: false
> >
> > -if:
> > -  properties:
> > -    compatible:
> > -      contains:
> > -        enum:
> > -          - brcm,bcm2711-hvs
> > -          - brcm,bcm2712-hvs
> > -
> > -then:
> > -  required:
> > -    - clocks
> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: brcm,bcm2711-hvs
> > +
> > +    then:
> > +      properties:
> > +        clocks:
> > +          items:
> > +            - description: Core Clock
> > +        interrupts:
> > +          maxItems: 1
>
>
> clock-names and interrupt-names: false, unless driver needs them but all
> this should be explained in the commit msg because it would be a change
> to the binding.

False it is then.

Is there actually a full guide to binding requirements?
https://www.kernel.org/doc/html/latest/devicetree/bindings/writing-schema.html
is the closest I've found, but it doesn't obviously cover these types
of things.

> > +
> > +      required:
> > +        - clocks
> > +
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: brcm,bcm2712-hvs
> > +
> > +    then:
> > +      properties:
> > +        clocks:
> > +          minItems: 2
> > +          maxItems: 2
> > +        clock-names:
> > +          items:
> > +            - const: core
> > +            - const: disp
> > +        interrupts:
> > +          items:
> > +            - description: Channel 0 End of frame
> > +            - description: Channel 1 End of frame
> > +            - description: Channel 2 End of frame
> > +        interrupt-names:
> > +          items:
> > +            - const: ch0-eof
> > +            - const: ch1-eof
> > +            - const: ch2-eof
> > +      required:
> > +        - clocks
> > +        - clock-names
> > +        - interrupt-names
>
> My previous comment still stands. Reply to people's feedback instead of
> ignoring it.

Your previous comment was
"Why requiring last two names? Commit msg does not explain that."

I didn't ignore it. The driver needs them, and the commit msg states
" but missed out that the number of interrupts and clocks changed too,
and *both need to be
named*.
Update to validate clock, interrupts, and *their names* for the variants."

Is that insufficient?

  Dave

> Best regards,
> Krzysztof
>


From angelogioacchino.delregno at collabora.com  Thu Dec 19 03:56:23 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 12:56:23 +0100
Subject: [PATCH v7 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241217085435.9586-4-linux@fw-web.de>
References: <20241217085435.9586-1-linux@fw-web.de>
 <20241217085435.9586-4-linux@fw-web.de>
Message-ID: <4ecfcdd3-3c81-4625-90cd-1d45f6d71a2f@collabora.com>

Il 17/12/24 09:54, Frank Wunderlich ha scritto:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> This adds bindings for MT7988 pinctrl driver.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

DT binding maintainers, can you please review this patch and eventually release
an Ack so that I can take it through the MediaTek tree along with the devicetree
changes?

Cheers,
Angelo

> ---
> changes in v6:
> changes suggested by rob
> - remove quotes around mux
> - use const instead of enum if only one value is possible
> 
> changes in v5 (so not adding RB from Rob given in v4):
> - do not use MTK_DRIVE_8mA in example
> - add _0 functions for pwm
> 
> changes in v4:
> - dt-binding: pinctrl: fix dt_binding_check fixed-string error
> 
> '^mux$' should not be valid under {'pattern': '^\\^[a-zA-Z0-9,\\-._#@]+\\$$'}
> 	hint: Fixed strings belong in 'properties', not 'patternProperties'
> 
> changes in v3:
> - limit conf subnode name with optional suffix like mmc on mt7986
> - match mux subnode without wildcards
> 
> changes in v2:
> - drop gpio-cells description
> - move ref in mux subnode up
> - order uart-functions alphanumeric and fix typo
> ---
>   .../pinctrl/mediatek,mt7988-pinctrl.yaml      | 575 ++++++++++++++++++
>   1 file changed, 575 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
> new file mode 100644
> index 000000000000..26dfe7e7735a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
> @@ -0,0 +1,575 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7988-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek MT7988 Pin Controller
> +
> +maintainers:
> +  - Sean Wang <sean.wang at kernel.org>
> +
> +description:
> +  The MediaTek's MT7988 Pin controller is used to control SoC pins.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt7988-pinctrl
> +
> +  reg:
> +    minItems: 7
> +    maxItems: 7
> +
> +  reg-names:
> +    items:
> +      - const: gpio
> +      - const: iocfg_tr
> +      - const: iocfg_br
> +      - const: iocfg_rb
> +      - const: iocfg_lb
> +      - const: iocfg_tl
> +      - const: eint
> +
> +  gpio-controller: true
> +
> +  "#gpio-cells":
> +    const: 2
> +
> +  gpio-ranges:
> +    minItems: 1
> +    maxItems: 5
> +    description:
> +      GPIO valid number range.
> +
> +  interrupt-controller: true
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  "#interrupt-cells":
> +    const: 2
> +
> +allOf:
> +  - $ref: pinctrl.yaml#
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - gpio-controller
> +  - "#gpio-cells"
> +
> +patternProperties:
> +  '-pins$':
> +    type: object
> +    additionalProperties: false
> +
> +    properties:
> +      mux:
> +        type: object
> +        additionalProperties: false
> +        $ref: /schemas/pinctrl/pinmux-node.yaml
> +        description: |
> +          pinmux configuration nodes.
> +
> +          The following table shows the effective values of "group", "function"
> +          properties and chip pinout pins
> +
> +          groups               function           pins (in pin#)
> +          ---------------------------------------------------------------------
> +          "tops_jtag0_0"       "jtag"             0, 1, 2, 3, 4
> +          "wo0_jtag"           "jtag"             50, 51, 52, 53, 54
> +          "wo1_jtag"           "jtag"             50, 51, 52, 53, 54
> +          "wo2_jtag"           "jtag"             50, 51, 52, 53, 54
> +          "jtag"               "jtag"             58, 59, 60, 61, 62
> +          "tops_jtag0_1"       "jtag"             58, 59, 60, 61, 62
> +          "int_usxgmii"        "int_usxgmii"      2, 3
> +          "pwm0"               "pwm"              57
> +          "pwm1"               "pwm"              21
> +          "pwm2"               "pwm"              80
> +          "pwm2_0"             "pwm"              58
> +          "pwm3"               "pwm"              81
> +          "pwm3_0"             "pwm"              59
> +          "pwm4"               "pwm"              82
> +          "pwm4_0"             "pwm"              60
> +          "pwm5"               "pwm"              83
> +          "pwm5_0"             "pwm"              61
> +          "pwm6"               "pwm"              69
> +          "pwm6_0"             "pwm"              62
> +          "pwm7"               "pwm"              70
> +          "pwm7_0"             "pwm"              4
> +          "dfd"                "dfd"              0, 1, 2, 3, 4
> +          "xfi_phy0_i2c0"      "i2c"              0, 1
> +          "xfi_phy1_i2c0"      "i2c"              0, 1
> +          "xfi_phy_pll_i2c0"   "i2c"              3, 4
> +          "xfi_phy_pll_i2c1"   "i2c"              3, 4
> +          "i2c0_0"             "i2c"              5, 6
> +          "i2c1_sfp"           "i2c"              5, 6
> +          "xfi_pextp_phy0_i2c" "i2c"              5, 6
> +          "xfi_pextp_phy1_i2c" "i2c"              5, 6
> +          "i2c0_1"             "i2c"              15, 16
> +          "u30_phy_i2c0"       "i2c"              15, 16
> +          "u32_phy_i2c0"       "i2c"              15, 16
> +          "xfi_phy0_i2c1"      "i2c"              15, 16
> +          "xfi_phy1_i2c1"      "i2c"              15, 16
> +          "xfi_phy_pll_i2c2"   "i2c"              15, 16
> +          "i2c1_0"             "i2c"              17, 18
> +          "u30_phy_i2c1"       "i2c"              17, 18
> +          "u32_phy_i2c1"       "i2c"              17, 18
> +          "xfi_phy_pll_i2c3"   "i2c"              17, 18
> +          "sgmii0_i2c"         "i2c"              17, 18
> +          "sgmii1_i2c"         "i2c"              17, 18
> +          "i2c1_2"             "i2c"              69, 70
> +          "i2c2_0"             "i2c"              69, 70
> +          "i2c2_1"             "i2c"              71, 72
> +          "mdc_mdio0"          "eth"              5, 6
> +          "2p5g_ext_mdio"      "eth"              28, 29
> +          "gbe_ext_mdio"       "eth"              30, 31
> +          "mdc_mdio1"          "eth"              69, 70
> +          "pcie_wake_n0_0"     "pcie"             7
> +          "pcie_clk_req_n0_0"  "pcie"             8
> +          "pcie_wake_n3_0"     "pcie"             9
> +          "pcie_clk_req_n3"    "pcie"             10
> +          "pcie_clk_req_n0_1"  "pcie"             10
> +          "pcie_p0_phy_i2c"    "pcie"             7, 8
> +          "pcie_p1_phy_i2c"    "pcie"             7, 8
> +          "pcie_p3_phy_i2c"    "pcie"             9, 10
> +          "pcie_p2_phy_i2c"    "pcie"             7, 8
> +          "ckm_phy_i2c"        "pcie"             9, 10
> +          "pcie_wake_n0_1"     "pcie"             13
> +          "pcie_wake_n3_1"     "pcie"             14
> +          "pcie_2l_0_pereset"  "pcie"             19
> +          "pcie_1l_1_pereset"  "pcie"             20
> +          "pcie_clk_req_n2_1"  "pcie"             63
> +          "pcie_2l_1_pereset"  "pcie"             73
> +          "pcie_1l_0_pereset"  "pcie"             74
> +          "pcie_wake_n1_0"     "pcie"             75
> +          "pcie_clk_req_n1"    "pcie"             76
> +          "pcie_wake_n2_0"     "pcie"             77
> +          "pcie_clk_req_n2_0"  "pcie"             78
> +          "pcie_wake_n2_1"     "pcie"             79
> +          "pmic"               "pmic"             11
> +          "watchdog"           "watchdog"         12
> +          "spi0_wp_hold"       "spi"              22, 23
> +          "spi0"               "spi"              24, 25, 26, 27
> +          "spi1"               "spi"              28, 29, 30, 31
> +          "spi2"               "spi"              32, 33, 34, 35
> +          "spi2_wp_hold"       "spi"              36, 37
> +          "snfi"               "flash"            22, 23, 24, 25, 26, 27
> +          "emmc_45"            "flash"            21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
> +          "sdcard"             "flash"            32, 33, 34, 35, 36, 37
> +          "emmc_51"            "flash"            38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49
> +          "uart2"              "uart"             0, 1, 2, 3
> +          "tops_uart0_0"       "uart"             22, 23
> +          "uart2_0"            "uart"             28, 29, 30, 31
> +          "uart1_0"            "uart"             32, 33, 34, 35
> +          "uart2_1"            "uart"             32, 33, 34, 35
> +          "net_wo0_uart_txd_0" "uart"             28
> +          "net_wo1_uart_txd_0" "uart"             29
> +          "net_wo2_uart_txd_0" "uart"             30
> +          "tops_uart1_0"       "uart"             28, 29
> +          "tops_uart0_1"       "uart"             30, 31
> +          "tops_uart1_1"       "uart"             36, 37
> +          "uart0"              "uart"             55, 56
> +          "tops_uart0_2"       "uart"             55, 56
> +          "uart2_2"            "uart"             50, 51, 52, 53
> +          "uart1_1"            "uart"             58, 59, 60, 61
> +          "uart2_3"            "uart"             58, 59, 60, 61
> +          "uart1_2"            "uart"             80, 81, 82, 83
> +          "uart1_2_lite"       "uart"             80, 81
> +          "tops_uart1_2"       "uart"             80, 81
> +          "net_wo0_uart_txd_1" "uart"             80
> +          "net_wo1_uart_txd_1" "uart"             81
> +          "net_wo2_uart_txd_1" "uart"             82
> +          "udi"                "udi"              32, 33, 34, 35, 36
> +          "i2s"                "audio"            50, 51, 52, 53, 54
> +          "pcm"                "audio"            50, 51, 52, 53
> +          "gbe0_led1"          "led"              58
> +          "gbe1_led1"          "led"              59
> +          "gbe2_led1"          "led"              60
> +          "gbe3_led1"          "led"              61
> +          "2p5gbe_led1"        "led"              62
> +          "gbe0_led0"          "led"              64
> +          "gbe1_led0"          "led"              65
> +          "gbe2_led0"          "led"              66
> +          "gbe3_led0"          "led"              67
> +          "2p5gbe_led0"        "led"              68
> +          "drv_vbus_p1"        "usb"              63
> +          "drv_vbus"           "usb"              79
> +
> +        properties:
> +          function:
> +            description:
> +              A string containing the name of the function to mux to the group.
> +            enum: [audio, dfd, eth, flash, i2c, int_usxgmii, jtag, led, pcie, pmic, pwm, spi,
> +                   uart, udi, usb, watchdog]
> +          groups:
> +            description:
> +              An array of strings. Each string contains the name of a group.
> +
> +        required:
> +          - function
> +          - groups
> +
> +        allOf:
> +          - if:
> +              properties:
> +                function:
> +                  const: audio
> +            then:
> +              properties:
> +                groups:
> +                  enum: [i2s, pcm]
> +          - if:
> +              properties:
> +                function:
> +                  const: jtag
> +            then:
> +              properties:
> +                groups:
> +                  enum: [jtag, tops_jtag0_0, tops_jtag0_1, wo0_jtag, wo1_jtag, wo2_jtag]
> +          - if:
> +              properties:
> +                function:
> +                  const: int_usxgmii
> +            then:
> +              properties:
> +                groups:
> +                  const: int_usxgmii
> +          - if:
> +              properties:
> +                function:
> +                  const: dfd
> +            then:
> +              properties:
> +                groups:
> +                  const: dfd
> +          - if:
> +              properties:
> +                function:
> +                  const: flash
> +            then:
> +              properties:
> +                groups:
> +                  enum: [emmc_45, emmc_51, sdcard, snfi]
> +          - if:
> +              properties:
> +                function:
> +                  const: eth
> +            then:
> +              properties:
> +                groups:
> +                  enum: [2p5g_ext_mdio, gbe_ext_mdio, mdc_mdio0, mdc_mdio1]
> +          - if:
> +              properties:
> +                function:
> +                  const: i2c
> +            then:
> +              properties:
> +                groups:
> +                  enum: [xfi_phy0_i2c0, xfi_phy1_i2c0, xfi_phy_pll_i2c0,
> +                         xfi_phy_pll_i2c1, i2c0_0, i2c1_sfp, xfi_pextp_phy0_i2c,
> +                         xfi_pextp_phy1_i2c, i2c0_1, u30_phy_i2c0, u32_phy_i2c0,
> +                         xfi_phy0_i2c1, xfi_phy1_i2c1, xfi_phy_pll_i2c2, i2c1_0,
> +                         u30_phy_i2c1, u32_phy_i2c1, xfi_phy_pll_i2c3, sgmii0_i2c,
> +                         sgmii1_i2c, i2c1_2, i2c2_0, i2c2_1]
> +          - if:
> +              properties:
> +                function:
> +                  const: led
> +            then:
> +              properties:
> +                groups:
> +                  enum: [2p5gbe_led0, 2p5gbe_led1, gbe0_led0, gbe0_led1, gbe1_led0, gbe1_led1,
> +                         gbe2_led0, gbe2_led1, gbe3_led0, gbe3_led1, wf5g_led0, wf5g_led1]
> +          - if:
> +              properties:
> +                function:
> +                  const: pcie
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [pcie_wake_n0_0, pcie_clk_req_n0_0, pcie_wake_n3_0,
> +                           pcie_clk_req_n3, pcie_p0_phy_i2c, pcie_p1_phy_i2c,
> +                           pcie_p3_phy_i2c, pcie_p2_phy_i2c, ckm_phy_i2c,
> +                           pcie_wake_n0_1, pcie_wake_n3_1, pcie_2l_0_pereset,
> +                           pcie_1l_1_pereset, pcie_clk_req_n2_1, pcie_2l_1_pereset,
> +                           pcie_1l_0_pereset, pcie_wake_n1_0, pcie_clk_req_n1,
> +                           pcie_wake_n2_0, pcie_clk_req_n2_0, pcie_wake_n2_1,
> +                           pcie_clk_req_n0_1]
> +                  maxItems: 3
> +          - if:
> +              properties:
> +                function:
> +                  const: pmic
> +            then:
> +              properties:
> +                groups:
> +                  const: pmic
> +          - if:
> +              properties:
> +                function:
> +                  const: pwm
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [pwm0, pwm1, pwm2, pwm2_0, pwm3, pwm3_0, pwm4, pwm4_0, pwm5, pwm5_0,
> +                           pwm6, pwm6_0, pwm7, pwm7_0]
> +                  maxItems: 2
> +          - if:
> +              properties:
> +                function:
> +                  const: spi
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [spi0, spi0_wp_hold, spi1, spi2, spi2_wp_hold]
> +                  maxItems: 2
> +          - if:
> +              properties:
> +                function:
> +                  const: uart
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [net_wo0_uart_txd_0, net_wo0_uart_txd_1, net_wo1_uart_txd_0,
> +                           net_wo1_uart_txd_1, net_wo2_uart_txd_0, net_wo2_uart_txd_1,
> +                           tops_uart0_0, tops_uart0_1, tops_uart0_2, tops_uart1_0,
> +                           tops_uart1_1, tops_uart1_2, uart0, uart1_0, uart1_1, uart1_2,
> +                           uart1_2_lite, uart2, uart2_0, uart2_1, uart2_3]
> +                  maxItems: 2
> +          - if:
> +              properties:
> +                function:
> +                  const: watchdog
> +            then:
> +              properties:
> +                groups:
> +                  const: watchdog
> +          - if:
> +              properties:
> +                function:
> +                  const: udi
> +            then:
> +              properties:
> +                groups:
> +                  const: udi
> +          - if:
> +              properties:
> +                function:
> +                  const: usb
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [drv_vbus, drv_vbus_p1]
> +                  maxItems: 1
> +
> +    patternProperties:
> +      '^conf(-[-a-z]*)?$':
> +        type: object
> +        additionalProperties: false
> +        description:
> +          pinconf configuration nodes.
> +        $ref: /schemas/pinctrl/pincfg-node.yaml
> +
> +        properties:
> +          pins:
> +            description:
> +              An array of strings. Each string contains the name of a pin.
> +            items:
> +              enum: [UART2_RXD, UART2_TXD, UART2_CTS, UART2_RTS, GPIO_A, SMI_0_MDC,
> +                     SMI_0_MDIO, PCIE30_2L_0_WAKE_N, PCIE30_2L_0_CLKREQ_N,
> +                     PCIE30_1L_1_WAKE_N, PCIE30_1L_1_CLKREQ_N, GPIO_P, WATCHDOG,
> +                     GPIO_RESET, GPIO_WPS, PMIC_I2C_SCL, PMIC_I2C_SDA, I2C_1_SCL,
> +                     I2C_1_SDA, PCIE30_2L_0_PRESET_N, PCIE30_1L_1_PRESET_N, PWMD1,
> +                     SPI0_WP, SPI0_HOLD, SPI0_CSB, SPI0_MISO, SPI0_MOSI, SPI0_CLK,
> +                     SPI1_CSB, SPI1_MISO, SPI1_MOSI, SPI1_CLK, SPI2_CLK, SPI2_MOSI,
> +                     SPI2_MISO, SPI2_CSB, SPI2_HOLD, SPI2_WP, EMMC_RSTB, EMMC_DSL,
> +                     EMMC_CK, EMMC_CMD, EMMC_DATA_7, EMMC_DATA_6, EMMC_DATA_5,
> +                     EMMC_DATA_4, EMMC_DATA_3, EMMC_DATA_2, EMMC_DATA_1,
> +                     EMMC_DATA_0, PCM_FS_I2S_LRCK, PCM_CLK_I2S_BCLK,
> +                     PCM_DRX_I2S_DIN, PCM_DTX_I2S_DOUT, PCM_MCK_I2S_MCLK,
> +                     UART0_RXD, UART0_TXD, PWMD0, JTAG_JTDI, JTAG_JTDO, JTAG_JTMS,
> +                     JTAG_JTCLK, JTAG_JTRST_N, USB_DRV_VBUS_P1, LED_A, LED_B, LED_C,
> +                     LED_D, LED_E, GPIO_B, GPIO_C, I2C_2_SCL, I2C_2_SDA,
> +                     PCIE30_2L_1_PRESET_N, PCIE30_1L_0_PRESET_N,
> +                     PCIE30_2L_1_WAKE_N, PCIE30_2L_1_CLKREQ_N,
> +                     PCIE30_1L_0_WAKE_N, PCIE30_1L_0_CLKREQ_N, USB_DRV_VBUS_P0,
> +                     UART1_RXD, UART1_TXD, UART1_CTS, UART1_RTS]
> +            maxItems: 84
> +
> +          bias-disable: true
> +
> +          bias-pull-up:
> +            oneOf:
> +              - type: boolean
> +                description: normal pull up.
> +              - enum: [100, 101, 102, 103]
> +                description:
> +                  PUPD/R1/R0 pull down type. See MTK_PUPD_SET_R1R0 defines in
> +                  dt-bindings/pinctrl/mt65xx.h.
> +
> +          bias-pull-down:
> +            oneOf:
> +              - type: boolean
> +                description: normal pull down.
> +              - enum: [100, 101, 102, 103]
> +                description:
> +                  PUPD/R1/R0 pull down type. See MTK_PUPD_SET_R1R0 defines in
> +                  dt-bindings/pinctrl/mt65xx.h.
> +
> +          input-enable: true
> +
> +          input-disable: true
> +
> +          output-enable: true
> +
> +          output-low: true
> +
> +          output-high: true
> +
> +          input-schmitt-enable: true
> +
> +          input-schmitt-disable: true
> +
> +          drive-strength:
> +            enum: [2, 4, 6, 8, 10, 12, 14, 16]
> +
> +          mediatek,pull-up-adv:
> +            description: |
> +              Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
> +              Pull up settings for 2 pull resistors, R0 and R1. Valid arguments
> +              are described as below:
> +              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
> +              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
> +              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
> +              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            enum: [0, 1, 2, 3]
> +
> +          mediatek,pull-down-adv:
> +            description: |
> +              Valid arguments for 'mediatek,pull-up-adv' are '0', '1', '2', '3'
> +              Pull down settings for 2 pull resistors, R0 and R1. Valid arguments
> +              are described as below:
> +              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
> +              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
> +              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
> +              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            enum: [0, 1, 2, 3]
> +
> +        required:
> +          - pins
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/pinctrl/mt65xx.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      pio: pinctrl at 1001f000 {
> +        compatible = "mediatek,mt7988-pinctrl";
> +        reg = <0 0x1001f000 0 0x1000>,
> +        <0 0x11c10000 0 0x1000>,
> +        <0 0x11d00000 0 0x1000>,
> +        <0 0x11d20000 0 0x1000>,
> +        <0 0x11e00000 0 0x1000>,
> +        <0 0x11f00000 0 0x1000>,
> +        <0 0x1000b000 0 0x1000>;
> +        reg-names = "gpio", "iocfg_tr",
> +          "iocfg_br", "iocfg_rb",
> +          "iocfg_lb", "iocfg_tl", "eint";
> +        gpio-controller;
> +        #gpio-cells = <2>;
> +        gpio-ranges = <&pio 0 0 84>;
> +        interrupt-controller;
> +        interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-parent = <&gic>;
> +        #interrupt-cells = <2>;
> +
> +        i2c0_pins: i2c0-g0-pins {
> +          mux {
> +            function = "i2c";
> +            groups = "i2c0_1";
> +          };
> +        };
> +
> +        mdio0_pins: mdio0-pins {
> +          mux {
> +            function = "eth";
> +            groups = "mdc_mdio0";
> +          };
> +
> +          conf {
> +            pins = "SMI_0_MDC", "SMI_0_MDIO";
> +            drive-strength = <8>;
> +          };
> +        };
> +
> +        mmc0_pins_emmc_51: mmc0-emmc-51-pins {
> +          mux {
> +            function = "flash";
> +            groups = "emmc_51";
> +          };
> +        };
> +
> +        mmc0_pins_sdcard: mmc0-sdcard-pins {
> +          mux {
> +            function = "flash";
> +            groups = "sdcard";
> +          };
> +        };
> +
> +        pcie0_pins: pcie0-pins {
> +          mux {
> +            function = "pcie";
> +            groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
> +                     "pcie_wake_n0_0";
> +          };
> +        };
> +
> +        pcie1_pins: pcie1-pins {
> +          mux {
> +            function = "pcie";
> +            groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
> +                     "pcie_wake_n1_0";
> +          };
> +        };
> +
> +        pcie2_pins: pcie2-pins {
> +          mux {
> +            function = "pcie";
> +            groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
> +                     "pcie_wake_n2_0";
> +          };
> +        };
> +
> +        pcie3_pins: pcie3-pins {
> +          mux {
> +            function = "pcie";
> +            groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
> +                     "pcie_wake_n3_0";
> +          };
> +        };
> +
> +        uart0_pins: uart0-pins {
> +          mux {
> +            function = "uart";
> +            groups =  "uart0";
> +          };
> +        };
> +      };
> +    };





From beata.michalska at arm.com  Thu Dec 19 03:57:07 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Thu, 19 Dec 2024 12:57:07 +0100
Subject: [PATCH v8 1/4] cpufreq: Introduce an optional cpuinfo_avg_freq
 sysfs entry
In-Reply-To: <20241218041127.khdwo3hzmywcwuh5@vireshk-i7>
References: <20241206135600.4083965-1-beata.michalska@arm.com>
 <20241206135600.4083965-2-beata.michalska@arm.com>
 <20241212065100.sjb7lrlmksbm2hdk@vireshk-i7>
 <Z2CmcelSy89NULtz@arm.com>
 <20241217042726.isllh5bulpnwql7i@vireshk-i7>
 <Z2Haw_o8gF-Ce1gx@arm.com>
 <20241218041127.khdwo3hzmywcwuh5@vireshk-i7>
Message-ID: <Z2QKE3uml7CRm0DD@arm.com>

On Wed, Dec 18, 2024 at 09:41:27AM +0530, Viresh Kumar wrote:
> On 17-12-24, 21:10, Beata Michalska wrote:
> > On Tue, Dec 17, 2024 at 09:57:26AM +0530, Viresh Kumar wrote:
> > > On 16-12-24, 23:15, Beata Michalska wrote:
> > > > My bad as I must have misinterpreted that message. Although I am not entirely
> > > > sure why this might be unacceptable as it is not such uncommon approach to use
> > > > signed int space to cover both: expected positive value as well as potential
> > > > error code case failure.
> > > 
> > > This part is fine. The problem is with handling frequency here. Signed int can
> > > capture up to 2 GHz of freq, where as unsigned int can capture up to 4 GHz and
> > > so we would really like to keep it at 4 GHz..
> > Right, though the arch_freq_get_on_cpu operates on kHz values.
> 
> Hmm.. Missed that.
> 
> If you still want to keep it, make that change in a separate patch and
> the new sysfs entry in a different one, so related people can easily
> review.
> 
Will do.
Thank you for your feedback. Much appreciated.

---
BR
Beata

> -- 
> viresh


From andi.shyti at kernel.org  Thu Dec 19 04:02:29 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Thu, 19 Dec 2024 13:02:29 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <20241218043541.143194-1-carlos.song@nxp.com>
References: <20241218043541.143194-1-carlos.song@nxp.com>
Message-ID: <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>

Hi Carlos,

> +	/*
> +	 * Init DMA config if supported, -ENODEV means DMA not enabled at
> +	 * this platform, that is not a real error, so just remind "only
> +	 * PIO mode is used". If DMA is enabled, but meet error when request
> +	 * DMA channel, error should be showed in probe error log. PIO mode
> +	 * should be available regardless of DMA.
> +	 */
> +	ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> +	if (ret) {
> +		if (ret == -EPROBE_DEFER)
> +			goto clk_notifier_unregister;
> +		else if (ret == -ENODEV)
> +			dev_dbg(&pdev->dev, "Only use PIO mode\n");
> +		else
> +			dev_err_probe(&pdev->dev, ret, "Failed to setup DMA, only use PIO mode\n");

Just for understanding, should we quit in this last case, as
well?

Before we were ignoring ENODEV and EPROBE_DEFER, but now you are
making it clear that other failures like ENOMEM might happen.

Thanks,
Andi


From robin.murphy at arm.com  Thu Dec 19 04:08:39 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 19 Dec 2024 12:08:39 +0000
Subject: [PATCH] iommu/arm-smmu-qcom: Only enable stall on smmu-v2
In-Reply-To: <20241219113019.GA23640@willie-the-truck>
References: <20241216171017.4881-1-robdclark@gmail.com>
 <20241219113019.GA23640@willie-the-truck>
Message-ID: <41d93dac-4ef1-4cc7-a7b2-24c8289f905f@arm.com>

On 2024-12-19 11:30 am, Will Deacon wrote:
> On Mon, Dec 16, 2024 at 09:10:17AM -0800, Rob Clark wrote:
>> From: Rob Clark <robdclark at chromium.org>
>>
>> On mmu-500, stall-on-fault seems to stall all context banks, causing the
>> GMU to misbehave.  So limit this feature to smmu-v2 for now.
> 
> MMU-500 has public documentation so please can you dig up what the
> actual behaviour is rather than guess?

Yeah, I'm pretty sure that's not true as stated, especially with 
SCTLR.HUPCF set as qcom_adreno_smmu_write_sctlr() does. However it is 
plausible that at the system interconnect level, a sufficient number of 
stalled transactions might backpressure other transactions from entering 
the same TBU, even if they are destined for a different context. That's 
more about the configuration and integration of individual SoCs than the 
SMMU IP used.

Robin.

>> This fixes an issue with an older mesa bug taking outo the system
>> because of GMU going off into the year.
> 
> Sorry, but I don't understand this sentence.
> 
> Will



From krzk at kernel.org  Thu Dec 19 04:14:21 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 19 Dec 2024 13:14:21 +0100
Subject: [PATCH v4 2/3] dt-bindings: display: Fix BCM2835 HVS bindings for
 BCM2712
In-Reply-To: <CAPY8ntCX8+yg1RFhAXu4ystGF_JivTh43RY=k2P0bUm5JxvzRA@mail.gmail.com>
References: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
 <20241218-dt-bcm2712-fixes-v4-2-54cc88b6c229@raspberrypi.com>
 <lzvcaspulvsulbulqinzftt3xtdyro64hi674u2bnkpvbrihri@e2o247mjom5s>
 <CAPY8ntCX8+yg1RFhAXu4ystGF_JivTh43RY=k2P0bUm5JxvzRA@mail.gmail.com>
Message-ID: <09bee93e-48bd-4a7c-b975-b10dce945d60@kernel.org>

On 19/12/2024 12:54, Dave Stevenson wrote:
> Hi Krzysztof
> 
> On Thu, 19 Dec 2024 at 08:42, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>>
>> On Wed, Dec 18, 2024 at 02:48:33PM +0000, Dave Stevenson wrote:
>>> Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
>>> added the compatible string for BCM2712, but missed out that
>>> the number of interrupts and clocks changed too, and both need to be
>>> named.
>>>
>>> Update to validate clock, interrupts, and their names for the variants.
>>>
>>> Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
>>> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
>>> ---
>>>  .../bindings/display/brcm,bcm2835-hvs.yaml         | 84 ++++++++++++++++++----
>>>  1 file changed, 70 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
>>> index f91c9dce2a44..fd25ee5ce301 100644
>>> --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
>>> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
>>> @@ -20,11 +20,20 @@ properties:
>>>      maxItems: 1
>>>
>>>    interrupts:
>>> -    maxItems: 1
>>> +    minItems: 1
>>> +    maxItems: 3
>>> +
>>> +  interrupt-names:
>>> +    minItems: 1
>>> +    maxItems: 3
>>>
>>>    clocks:
>>> -    maxItems: 1
>>> -    description: Core Clock
>>> +    minItems: 1
>>> +    maxItems: 2
>>> +
>>> +  clock-names:
>>> +    minItems: 1
>>> +    maxItems: 2
>>>
>>>  required:
>>>    - compatible
>>> @@ -33,17 +42,64 @@ required:
>>>
>>>  additionalProperties: false
>>>
>>> -if:
>>> -  properties:
>>> -    compatible:
>>> -      contains:
>>> -        enum:
>>> -          - brcm,bcm2711-hvs
>>> -          - brcm,bcm2712-hvs
>>> -
>>> -then:
>>> -  required:
>>> -    - clocks
>>> +allOf:
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          contains:
>>> +            const: brcm,bcm2711-hvs
>>> +
>>> +    then:
>>> +      properties:
>>> +        clocks:
>>> +          items:
>>> +            - description: Core Clock
>>> +        interrupts:
>>> +          maxItems: 1
>>
>>
>> clock-names and interrupt-names: false, unless driver needs them but all
>> this should be explained in the commit msg because it would be a change
>> to the binding.
> 
> False it is then.
> 
> Is there actually a full guide to binding requirements?
> https://www.kernel.org/doc/html/latest/devicetree/bindings/writing-schema.html
> is the closest I've found, but it doesn't obviously cover these types
> of things.
> 
>>> +
>>> +      required:
>>> +        - clocks
>>> +
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          contains:
>>> +            const: brcm,bcm2712-hvs
>>> +
>>> +    then:
>>> +      properties:
>>> +        clocks:
>>> +          minItems: 2
>>> +          maxItems: 2
>>> +        clock-names:
>>> +          items:
>>> +            - const: core
>>> +            - const: disp
>>> +        interrupts:
>>> +          items:
>>> +            - description: Channel 0 End of frame
>>> +            - description: Channel 1 End of frame
>>> +            - description: Channel 2 End of frame
>>> +        interrupt-names:
>>> +          items:
>>> +            - const: ch0-eof
>>> +            - const: ch1-eof
>>> +            - const: ch2-eof
>>> +      required:
>>> +        - clocks
>>> +        - clock-names
>>> +        - interrupt-names
>>
>> My previous comment still stands. Reply to people's feedback instead of
>> ignoring it.
> 
> Your previous comment was
> "Why requiring last two names? Commit msg does not explain that."
> 
> I didn't ignore it. The driver needs them, and the commit msg states

Uh, so someone added undocumented ABI. How this passed any checks? Or no
one cared to run validation?


> " but missed out that the number of interrupts and clocks changed too,
> and *both need to be
> named*.

Ah, I really did not get this.

> Update to validate clock, interrupts, and *their names* for the variants."

Please say explicitly that since some commit driver needs this. There
should be a clear reason in the commit msg why you are adding this ABI.


Best regards,
Krzysztof


From dave.stevenson at raspberrypi.com  Thu Dec 19 04:18:18 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 19 Dec 2024 12:18:18 +0000
Subject: [PATCH v4 2/3] dt-bindings: display: Fix BCM2835 HVS bindings for BCM2712
In-Reply-To: <09bee93e-48bd-4a7c-b975-b10dce945d60@kernel.org>
References: <20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229@raspberrypi.com>
 <20241218-dt-bcm2712-fixes-v4-2-54cc88b6c229@raspberrypi.com>
 <lzvcaspulvsulbulqinzftt3xtdyro64hi674u2bnkpvbrihri@e2o247mjom5s>
 <CAPY8ntCX8+yg1RFhAXu4ystGF_JivTh43RY=k2P0bUm5JxvzRA@mail.gmail.com> <09bee93e-48bd-4a7c-b975-b10dce945d60@kernel.org>
Message-ID: <CAPY8ntDWGaY9__BdR9Sfmom6YsZEhRZZsLghRNR1cvAZMxJyMA@mail.gmail.com>

On Thu, 19 Dec 2024 at 12:14, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On 19/12/2024 12:54, Dave Stevenson wrote:
> > Hi Krzysztof
> >
> > On Thu, 19 Dec 2024 at 08:42, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> >>
> >> On Wed, Dec 18, 2024 at 02:48:33PM +0000, Dave Stevenson wrote:
> >>> Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> >>> added the compatible string for BCM2712, but missed out that
> >>> the number of interrupts and clocks changed too, and both need to be
> >>> named.
> >>>
> >>> Update to validate clock, interrupts, and their names for the variants.
> >>>
> >>> Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> >>> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> >>> ---
> >>>  .../bindings/display/brcm,bcm2835-hvs.yaml         | 84 ++++++++++++++++++----
> >>>  1 file changed, 70 insertions(+), 14 deletions(-)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> >>> index f91c9dce2a44..fd25ee5ce301 100644
> >>> --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> >>> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
> >>> @@ -20,11 +20,20 @@ properties:
> >>>      maxItems: 1
> >>>
> >>>    interrupts:
> >>> -    maxItems: 1
> >>> +    minItems: 1
> >>> +    maxItems: 3
> >>> +
> >>> +  interrupt-names:
> >>> +    minItems: 1
> >>> +    maxItems: 3
> >>>
> >>>    clocks:
> >>> -    maxItems: 1
> >>> -    description: Core Clock
> >>> +    minItems: 1
> >>> +    maxItems: 2
> >>> +
> >>> +  clock-names:
> >>> +    minItems: 1
> >>> +    maxItems: 2
> >>>
> >>>  required:
> >>>    - compatible
> >>> @@ -33,17 +42,64 @@ required:
> >>>
> >>>  additionalProperties: false
> >>>
> >>> -if:
> >>> -  properties:
> >>> -    compatible:
> >>> -      contains:
> >>> -        enum:
> >>> -          - brcm,bcm2711-hvs
> >>> -          - brcm,bcm2712-hvs
> >>> -
> >>> -then:
> >>> -  required:
> >>> -    - clocks
> >>> +allOf:
> >>> +  - if:
> >>> +      properties:
> >>> +        compatible:
> >>> +          contains:
> >>> +            const: brcm,bcm2711-hvs
> >>> +
> >>> +    then:
> >>> +      properties:
> >>> +        clocks:
> >>> +          items:
> >>> +            - description: Core Clock
> >>> +        interrupts:
> >>> +          maxItems: 1
> >>
> >>
> >> clock-names and interrupt-names: false, unless driver needs them but all
> >> this should be explained in the commit msg because it would be a change
> >> to the binding.
> >
> > False it is then.
> >
> > Is there actually a full guide to binding requirements?
> > https://www.kernel.org/doc/html/latest/devicetree/bindings/writing-schema.html
> > is the closest I've found, but it doesn't obviously cover these types
> > of things.
> >
> >>> +
> >>> +      required:
> >>> +        - clocks
> >>> +
> >>> +  - if:
> >>> +      properties:
> >>> +        compatible:
> >>> +          contains:
> >>> +            const: brcm,bcm2712-hvs
> >>> +
> >>> +    then:
> >>> +      properties:
> >>> +        clocks:
> >>> +          minItems: 2
> >>> +          maxItems: 2
> >>> +        clock-names:
> >>> +          items:
> >>> +            - const: core
> >>> +            - const: disp
> >>> +        interrupts:
> >>> +          items:
> >>> +            - description: Channel 0 End of frame
> >>> +            - description: Channel 1 End of frame
> >>> +            - description: Channel 2 End of frame
> >>> +        interrupt-names:
> >>> +          items:
> >>> +            - const: ch0-eof
> >>> +            - const: ch1-eof
> >>> +            - const: ch2-eof
> >>> +      required:
> >>> +        - clocks
> >>> +        - clock-names
> >>> +        - interrupt-names
> >>
> >> My previous comment still stands. Reply to people's feedback instead of
> >> ignoring it.
> >
> > Your previous comment was
> > "Why requiring last two names? Commit msg does not explain that."
> >
> > I didn't ignore it. The driver needs them, and the commit msg states
>
> Uh, so someone added undocumented ABI. How this passed any checks? Or no
> one cared to run validation?

See the cover letter:
"I missed the DT errors from the recent patchset[1] (DT patches
in linux-next via Florian, DRM bindings patches on dri-misc-next)
as Rob's bot report got spam filtered, so this is a fixup set."

> > " but missed out that the number of interrupts and clocks changed too,
> > and *both need to be
> > named*.
>
> Ah, I really did not get this.
>
> > Update to validate clock, interrupts, and *their names* for the variants."
>
> Please say explicitly that since some commit driver needs this. There
> should be a clear reason in the commit msg why you are adding this ABI.

OK, will do.

  Dave

> Best regards,
> Krzysztof


From angelogioacchino.delregno at collabora.com  Thu Dec 19 04:20:34 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 13:20:34 +0100
Subject: [PATCH] arm64: dts: mediatek: mt8195: Remove suspend-breaking
 reset from pcie1
In-Reply-To: <20241218-mt8195-pcie1-reset-suspend-fix-v1-1-1c021dda42a6@collabora.com>
References: <20241218-mt8195-pcie1-reset-suspend-fix-v1-1-1c021dda42a6@collabora.com>
Message-ID: <173461083442.58336.13259484924514720817.b4-ty@collabora.com>

On Wed, 18 Dec 2024 19:01:08 -0300, N?colas F. R. A. Prado wrote:
> The MAC reset for PCIe port 1 on MT8195 when asserted during suspend
> causes the system to hang during resume with the following error (with
> no_console_suspend enabled):
> 
>   mtk-pcie-gen3 112f8000.pcie: PCIe link down, current LTSSM state: detect.quiet (0x0)
>   mtk-pcie-gen3 112f8000.pcie: PM: dpm_run_callback(): genpd_resume_noirq+0x0/0x24 returns -110
>   mtk-pcie-gen3 112f8000.pcie: PM: failed to resume noirq: error -110
> 
> [...]

Applied to v6.13-next/dts64, thanks!

[1/1] arm64: dts: mediatek: mt8195: Remove suspend-breaking reset from pcie1
      commit: 3d7fdd8e38aafd4858935df2392762c1ab8fb40f

Cheers,
Angelo




From mike.leach at linaro.org  Thu Dec 19 04:24:26 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:24:26 +0000
Subject: [PATCH v3 9/9] coresight/ultrasoc: change cti_drvdata spinlock's
 type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-10-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com> <20241216115006.415861-10-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7ViC+ZSzNYTo+mKK4UYw=GBO9TCyJ2WHN879=hO-tq8JvQ@mail.gmail.com>

Title of patch - this patch has nothing to do with cti_drvdata.

Mike


On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In ultrasoc-smb drivers, smb_drv_data->spinlock can be held
> during __schedule() by perf_event_task_sched_out()/in().
>
> Since smb__drv_data->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this, change type smb_drv_data->spinlock in ultrasoc-smb drivers,
> which can be called by perf_event_task_sched_out()/in(),
> from spinlock_t to raw_spinlock_t.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  drivers/hwtracing/coresight/ultrasoc-smb.c | 12 ++++++------
>  drivers/hwtracing/coresight/ultrasoc-smb.h |  2 +-
>  2 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
> index dc3c9504dd7c..26cfc939e5bd 100644
> --- a/drivers/hwtracing/coresight/ultrasoc-smb.c
> +++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
> @@ -98,7 +98,7 @@ static int smb_open(struct inode *inode, struct file *file)
>         struct smb_drv_data *drvdata = container_of(file->private_data,
>                                         struct smb_drv_data, miscdev);
>
> -       guard(spinlock)(&drvdata->spinlock);
> +       guard(raw_spinlock)(&drvdata->spinlock);
>
>         if (drvdata->reading)
>                 return -EBUSY;
> @@ -152,7 +152,7 @@ static int smb_release(struct inode *inode, struct file *file)
>         struct smb_drv_data *drvdata = container_of(file->private_data,
>                                         struct smb_drv_data, miscdev);
>
> -       guard(spinlock)(&drvdata->spinlock);
> +       guard(raw_spinlock)(&drvdata->spinlock);
>         drvdata->reading = false;
>
>         return 0;
> @@ -245,7 +245,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
>         struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
>         int ret = 0;
>
> -       guard(spinlock)(&drvdata->spinlock);
> +       guard(raw_spinlock)(&drvdata->spinlock);
>
>         /* Do nothing, the trace data is reading by other interface now */
>         if (drvdata->reading)
> @@ -280,7 +280,7 @@ static int smb_disable(struct coresight_device *csdev)
>  {
>         struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
>
> -       guard(spinlock)(&drvdata->spinlock);
> +       guard(raw_spinlock)(&drvdata->spinlock);
>
>         if (drvdata->reading)
>                 return -EBUSY;
> @@ -378,7 +378,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev,
>         if (!buf)
>                 return 0;
>
> -       guard(spinlock)(&drvdata->spinlock);
> +       guard(raw_spinlock)(&drvdata->spinlock);
>
>         /* Don't do anything if another tracer is using this sink. */
>         if (csdev->refcnt != 1)
> @@ -563,7 +563,7 @@ static int smb_probe(struct platform_device *pdev)
>
>         smb_reset_buffer(drvdata);
>         platform_set_drvdata(pdev, drvdata);
> -       spin_lock_init(&drvdata->spinlock);
> +       raw_spin_lock_init(&drvdata->spinlock);
>         drvdata->pid = -1;
>
>         ret = smb_register_sink(pdev, drvdata);
> diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing/coresight/ultrasoc-smb.h
> index a91d39cfccb8..c4c111275627 100644
> --- a/drivers/hwtracing/coresight/ultrasoc-smb.h
> +++ b/drivers/hwtracing/coresight/ultrasoc-smb.h
> @@ -115,7 +115,7 @@ struct smb_drv_data {
>         struct coresight_device *csdev;
>         struct smb_data_buffer sdb;
>         struct miscdevice miscdev;
> -       spinlock_t spinlock;
> +       raw_spinlock_t spinlock;
>         bool reading;
>         pid_t pid;
>  };
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Thu Dec 19 04:24:30 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:24:30 +0000
Subject: [PATCH v3 6/9] coresight-funnel: change funnel_drvdata spinlock's
 type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-7-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com> <20241216115006.415861-7-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7Vju8N=i5s=OUTXdCu8j2d95ZsqYT43jR54v6rui8o3DYw@mail.gmail.com>

On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In coresight-funnel drivers, cti_drvdata->spinlock can be held
> during __schedule() by perf_event_task_sched_out()/in().
>
> Since funnel_drvdata->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this, change type funnel_drvdata->spinlock in
> coresight-funnel drivers, which can be called by
> perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-funnel.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
> index 33efe1acbef7..a566c8854327 100644
> --- a/drivers/hwtracing/coresight/coresight-funnel.c
> +++ b/drivers/hwtracing/coresight/coresight-funnel.c
> @@ -47,7 +47,7 @@ struct funnel_drvdata {
>         struct clk              *pclk;
>         struct coresight_device *csdev;
>         unsigned long           priority;
> -       spinlock_t              spinlock;
> +       raw_spinlock_t          spinlock;
>  };
>
>  static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port)
> @@ -85,7 +85,7 @@ static int funnel_enable(struct coresight_device *csdev,
>         unsigned long flags;
>         bool first_enable = false;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         if (atomic_read(&in->dest_refcnt) == 0) {
>                 if (drvdata->base)
>                         rc = dynamic_funnel_enable_hw(drvdata, in->dest_port);
> @@ -94,7 +94,7 @@ static int funnel_enable(struct coresight_device *csdev,
>         }
>         if (!rc)
>                 atomic_inc(&in->dest_refcnt);
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         if (first_enable)
>                 dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n",
> @@ -129,13 +129,13 @@ static void funnel_disable(struct coresight_device *csdev,
>         unsigned long flags;
>         bool last_disable = false;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         if (atomic_dec_return(&in->dest_refcnt) == 0) {
>                 if (drvdata->base)
>                         dynamic_funnel_disable_hw(drvdata, in->dest_port);
>                 last_disable = true;
>         }
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         if (last_disable)
>                 dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n",
> @@ -266,7 +266,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
>         }
>         dev->platform_data = pdata;
>
> -       spin_lock_init(&drvdata->spinlock);
> +       raw_spin_lock_init(&drvdata->spinlock);
>         desc.type = CORESIGHT_DEV_TYPE_LINK;
>         desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG;
>         desc.ops = &funnel_cs_ops;
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Thu Dec 19 04:24:34 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:24:34 +0000
Subject: [PATCH v3 7/9] coresight-replicator: change replicator_drvdata
 spinlock's type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-8-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com> <20241216115006.415861-8-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7Vg_vyyG7A8N=+oUiE2MCPFR4+XGqZBe+Mq8c222Wq6Q8w@mail.gmail.com>

On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In coresight-replicator drivers, replicator_drvdata->spinlock can be held
> during __schedule() by perf_event_task_sched_out()/in().
>
> Since replicator_drvdata->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this, change type replicator_drvdata->spinlock in
> coresight-replicator drivers, which can be called
> by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-replicator.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
> index 0fba87de6d1a..7d36fe2176cc 100644
> --- a/drivers/hwtracing/coresight/coresight-replicator.c
> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
> @@ -41,7 +41,7 @@ struct replicator_drvdata {
>         struct clk              *atclk;
>         struct clk              *pclk;
>         struct coresight_device *csdev;
> -       spinlock_t              spinlock;
> +       raw_spinlock_t          spinlock;
>         bool                    check_idfilter_val;
>  };
>
> @@ -125,7 +125,7 @@ static int replicator_enable(struct coresight_device *csdev,
>         unsigned long flags;
>         bool first_enable = false;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         if (atomic_read(&out->src_refcnt) == 0) {
>                 if (drvdata->base)
>                         rc = dynamic_replicator_enable(drvdata, in->dest_port,
> @@ -135,7 +135,7 @@ static int replicator_enable(struct coresight_device *csdev,
>         }
>         if (!rc)
>                 atomic_inc(&out->src_refcnt);
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         if (first_enable)
>                 dev_dbg(&csdev->dev, "REPLICATOR enabled\n");
> @@ -179,14 +179,14 @@ static void replicator_disable(struct coresight_device *csdev,
>         unsigned long flags;
>         bool last_disable = false;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         if (atomic_dec_return(&out->src_refcnt) == 0) {
>                 if (drvdata->base)
>                         dynamic_replicator_disable(drvdata, in->dest_port,
>                                                    out->src_port);
>                 last_disable = true;
>         }
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         if (last_disable)
>                 dev_dbg(&csdev->dev, "REPLICATOR disabled\n");
> @@ -277,7 +277,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
>         }
>         dev->platform_data = pdata;
>
> -       spin_lock_init(&drvdata->spinlock);
> +       raw_spin_lock_init(&drvdata->spinlock);
>         desc.type = CORESIGHT_DEV_TYPE_LINK;
>         desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT;
>         desc.ops = &replicator_cs_ops;
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Thu Dec 19 04:27:47 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:27:47 +0000
Subject: [PATCH v3 0/9] coresight: change some driver' spinlock type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-1-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>

Hi,

On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In some coresight drivers, drvdata->spinlock can be held during __schedule()
> by perf_event_task_sched_out()/in().
>
> Since drvdata->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this,change type drvdata->spinlock in some coresight drivers,
> which can be called by perf_event_task_sched_out()/in(),
> from spinlock_t to raw_spinlock_t.
>
> Reviewed-by: James Clark <james.clark at linaro.org>
>
> v2 to v3:
>     - Fix build error
>
> v1 to v2:
>     - seperate patchsets to change locktype and apply gurad API.
>
> Yeoreum Yun (9):
>   coresight: change coresight_device lock type to  raw_spinlock_t
>   coresight-etm4x: change etmv4_drvdata spinlock type to  raw_spinlock_t
>   coresight: change coresight_trace_id_map's lock type to
>     raw_spinlock_t
>   coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
>   coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
>   coresight-funnel: change funnel_drvdata spinlock's type to
>     raw_spinlock_t
>   coresight-replicator: change replicator_drvdata spinlock's type to
>     raw_spinlock_t
>   coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
>   coresight/ultrasoc: change cti_drvdata spinlock's type to
>     raw_spinlock_t
>
>  .../hwtracing/coresight/coresight-config.c    |   8 +-
>  .../hwtracing/coresight/coresight-config.h    |   2 +-
>  drivers/hwtracing/coresight/coresight-core.c  |   2 +-
>  .../hwtracing/coresight/coresight-cti-core.c  |  44 +--
>  .../hwtracing/coresight/coresight-cti-sysfs.c |  76 +++---
>  drivers/hwtracing/coresight/coresight-cti.h   |   2 +-
>  drivers/hwtracing/coresight/coresight-etb10.c |  26 +-
>  .../coresight/coresight-etm4x-core.c          |  18 +-
>  .../coresight/coresight-etm4x-sysfs.c         | 250 +++++++++---------
>  drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
>  .../hwtracing/coresight/coresight-funnel.c    |  12 +-
>  .../coresight/coresight-replicator.c          |  12 +-
>  .../hwtracing/coresight/coresight-syscfg.c    |  26 +-
>  .../hwtracing/coresight/coresight-tmc-core.c  |   6 +-
>  .../hwtracing/coresight/coresight-tmc-etf.c   |  48 ++--
>  .../hwtracing/coresight/coresight-tmc-etr.c   |  40 +--
>  drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
>  .../hwtracing/coresight/coresight-trace-id.c  |  22 +-
>  drivers/hwtracing/coresight/ultrasoc-smb.c    |  12 +-
>  drivers/hwtracing/coresight/ultrasoc-smb.h    |   2 +-
>  include/linux/coresight.h                     |   4 +-
>  21 files changed, 308 insertions(+), 308 deletions(-)
>
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>

Notably missing is the same changes for the etm3x driver. The ETMv3.x
and PTM1.x are supported by this driver, and these trace source
variants are also supported in perf in the cs_etm.c code.

STM is also missing, though this is not directly enabled via perf -
but could perhaps run concurrently as it can be a target output for
ftrace.

Regards

Mike

-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From daniel.baluta at gmail.com  Thu Dec 19 04:33:40 2024
From: daniel.baluta at gmail.com (Daniel Baluta)
Date: Thu, 19 Dec 2024 14:33:40 +0200
Subject: [PATCH] clk: clk-imx8mp-audiomix: fix function signature
In-Reply-To: <20241219105447.889CB11FE@mail.steuer-voss.de>
References: <20241219105447.889CB11FE@mail.steuer-voss.de>
Message-ID: <CAEnQRZBpWQ936-yhV2WcxzvTP3m3CNXmopt6YcawzzdZjxh2zw@mail.gmail.com>

On Thu, Dec 19, 2024 at 12:55?PM Nikolaus Voss <nv at vosn.de> wrote:
>
> clk_imx8mp_audiomix_reset_controller_register() in the
> "if !CONFIG_RESET_CONTROLLER" branch had the first
> argument missing. It is an empty function for this branch
> so it wasn't immediately apparent.
>
> Fixes: 6f0e817175c5 ("clk: imx: clk-audiomix: Add reset controller")
> Cc: <stable at vger.kernel.org> # 6.12.x
> Signed-off-by: Nikolaus Voss <nv at vosn.de>

Good catch.

Reviewed-by: Daniel Baluta <daniel.baluta at nxp.com>


From robh at kernel.org  Thu Dec 19 04:34:41 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Dec 2024 06:34:41 -0600
Subject: [PATCH v7 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <4ecfcdd3-3c81-4625-90cd-1d45f6d71a2f@collabora.com>
References: <20241217085435.9586-1-linux@fw-web.de>
 <20241217085435.9586-4-linux@fw-web.de>
 <4ecfcdd3-3c81-4625-90cd-1d45f6d71a2f@collabora.com>
Message-ID: <20241219123441.GA4016373-robh@kernel.org>

On Thu, Dec 19, 2024 at 12:56:23PM +0100, AngeloGioacchino Del Regno wrote:
> Il 17/12/24 09:54, Frank Wunderlich ha scritto:
> > From: Frank Wunderlich <frank-w at public-files.de>
> > 
> > This adds bindings for MT7988 pinctrl driver.
> > 
> > Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> 
> DT binding maintainers, can you please review this patch and eventually release
> an Ack so that I can take it through the MediaTek tree along with the devicetree
> changes?

It's been 2 days... If you want to know the status and where you are in 
the queue, you can check patchwork[1]. But guess what, you're #1.

Rob

[1] https://patchwork.ozlabs.org/project/devicetree-bindings/list/


From jre at pengutronix.de  Thu Dec 19 04:34:55 2024
From: jre at pengutronix.de (Jonas Rebmann)
Date: Thu, 19 Dec 2024 13:34:55 +0100
Subject: [PATCH 0/2] Add FRAM to Protonic MECSBC device-tree
Message-ID: <20241219-mb85rs128ty-mecsbc-v1-0-77a0e851ef19@pengutronix.de>

The MECSBC single board computer is equipped with a Fujitsu MB85RS128TY
FRAM. This series adapts the devicetree accordingly.

Tested on current mtd/next which contains the required driver and
bindings update:
- 5b68d4d2db29 ("dt-bindings: mtd: mchp48l640 add mb85rs128ty compatible")
- 02ba194feacb ("mtd: mchp48l640: add support for Fujitsu MB85RS128TY FRAM")

Signed-off-by: Jonas Rebmann <jre at pengutronix.de>
---
David Jander (2):
      arm64: dts: rockchip: MECSBC: Remove i2c2 node
      arm64: dts: rockchip: MECSBC: Add FRAM MB85RS128TY

 arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
---
base-commit: 47f34eab58294d7bb2583f9519b4022e74d56437
change-id: 20241129-mb85rs128ty-mecsbc-adef26286564

Best regards,
-- 
Jonas Rebmann <jre at pengutronix.de>



From jre at pengutronix.de  Thu Dec 19 04:34:56 2024
From: jre at pengutronix.de (Jonas Rebmann)
Date: Thu, 19 Dec 2024 13:34:56 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: MECSBC: Remove i2c2 node
In-Reply-To: <20241219-mb85rs128ty-mecsbc-v1-0-77a0e851ef19@pengutronix.de>
References: <20241219-mb85rs128ty-mecsbc-v1-0-77a0e851ef19@pengutronix.de>
Message-ID: <20241219-mb85rs128ty-mecsbc-v1-1-77a0e851ef19@pengutronix.de>

From: David Jander <david at protonic.nl>

One of the pins of i2c2 is actually in use as chip select 0 for spi0.
The chip select 0 is used for an FRAM chip, which will be added in the
next patch.

Remove the i2c2 node from the rk3568-mecsbc device tree.

Signed-off-by: David Jander <david at protonic.nl>
Signed-off-by: Jonas Rebmann <jre at pengutronix.de>
---
 arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts b/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts
index c491dc4d4947dc460330847dede052b1b25ba86c..ca041b4d2d38a4e06cd0a54a806fed2ab723c94d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts
@@ -206,12 +206,6 @@ regulator-state-mem {
 	};
 };
 
-&i2c2 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c2m0_xfer>;
-};
-
 &i2c3 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c3m0_xfer>;

-- 
2.39.5



From jre at pengutronix.de  Thu Dec 19 04:34:57 2024
From: jre at pengutronix.de (Jonas Rebmann)
Date: Thu, 19 Dec 2024 13:34:57 +0100
Subject: [PATCH 2/2] arm64: dts: rockchip: MECSBC: Add FRAM MB85RS128TY
In-Reply-To: <20241219-mb85rs128ty-mecsbc-v1-0-77a0e851ef19@pengutronix.de>
References: <20241219-mb85rs128ty-mecsbc-v1-0-77a0e851ef19@pengutronix.de>
Message-ID: <20241219-mb85rs128ty-mecsbc-v1-2-77a0e851ef19@pengutronix.de>

From: David Jander <david at protonic.nl>

The board features a Fujitsu MB85RS128TY FRAM chip connected to spi0 CS
0. Add support for the MB85RS128TY to the device tree.

Signed-off-by: David Jander <david at protonic.nl>
Signed-off-by: Jonas Rebmann <jre at pengutronix.de>
---
 arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts b/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts
index ca041b4d2d38a4e06cd0a54a806fed2ab723c94d..c70f6df537596a85528e4e0b499e59d71f05b4a3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts
@@ -240,6 +240,18 @@ rtc at 51 {
 	};
 };
 
+&spi0 {
+	/* use hardware chipselect on cs0 (cs1 unconnected) */
+	pinctrl-0 = <&spi0m0_pins>, <&spi0m0_cs0>;
+	status = "okay";
+
+	fram at 0 {
+		compatible = "fujitsu,mb85rs128ty";
+		reg = <0>;
+		spi-max-frequency = <33000000>;
+	};
+};
+
 &i2s1_8ch {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>;

-- 
2.39.5



From angelogioacchino.delregno at collabora.com  Thu Dec 19 04:38:28 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 13:38:28 +0100
Subject: [PATCH] v1 pinctrl: mtk-eint: add eint new design for mt8196
In-Reply-To: <20241203131302.16022-1-ot_chhao.chang@mediatek.com>
References: <20241203131302.16022-1-ot_chhao.chang@mediatek.com>
Message-ID: <6695e77d-da46-45ed-9304-020f6da24582@collabora.com>

Il 03/12/24 14:12, chang hao ha scritto:
> From: Chhao Chang <ot_chhao.chang at mediatek.com>
> 
> Change 1: change EINT from 1 address to 5 addresses,
> Eint number is stored on each base.
> Change 2: Compatible with 1 address design
> 
> Signed-off-by: Chhao Chang <ot_chhao.chang at mediatek.com>

Have you tested this change on other MediaTek SoCs?

Which ones?

I know that you didn't, because you're breaking them. Next time, please do.

> ---
>   drivers/pinctrl/mediatek/mtk-eint.c           | 943 ++++++++++++++----
>   drivers/pinctrl/mediatek/mtk-eint.h           |  87 +-
>   .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  |  50 +-
>   3 files changed, 843 insertions(+), 237 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
> index 27f0a54e12bf..f7788166c335 100644
> --- a/drivers/pinctrl/mediatek/mtk-eint.c
> +++ b/drivers/pinctrl/mediatek/mtk-eint.c
> @@ -1,21 +1,24 @@
>   // SPDX-License-Identifier: GPL-2.0
> -// Copyright (c) 2014-2018 MediaTek Inc.
> -
> +// Copyright (c) 2014-2024 MediaTek Inc.
>   /*
>    * Library for MediaTek External Interrupt Support
>    *
>    * Author: Maoguang Meng <maoguang.meng at mediatek.com>
> - *	   Sean Wang <sean.wang at mediatek.com>
> - *
> + * Sean Wang <sean.wang at mediatek.com>
> + * Chhao Chang <ot_chhao.chang at mediatek.com>
>    */
>   
> +#include <linux/atomic.h>
>   #include <linux/delay.h>
>   #include <linux/err.h>
>   #include <linux/gpio/driver.h>
>   #include <linux/io.h>
>   #include <linux/irqchip/chained_irq.h>
>   #include <linux/irqdomain.h>
> +#include <linux/kernel.h>
>   #include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
>   #include <linux/of_irq.h>
>   #include <linux/platform_device.h>
>   

..snip..

> @@ -423,24 +599,42 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
>   	int virq, eint_offset;
>   	unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask,
>   		     dbnc;
> +	static const unsigned int debounce_time[] = { 156, 313, 625, 1250,
> +		20000, 40000, 80000, 160000, 320000, 640000 };

I told you already in an older review.

Every SoC has its own debounce time, and this will break all currently
supported MediaTek SoCs.

>   	struct irq_data *d;
> +	unsigned int instance, index;
> +	void __iomem *reg;
> +
> +	/*
> +	 * Due to different number of bit field, we only decode
> +	 * the coordinate here, instead of get the VA.
> +	 */
> +	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
> +				  &instance, &index);
>   
> -	if (!eint->hw->db_time)
> -		return -EOPNOTSUPP;
> +	if (!reg) {
> +		dev_err(eint->dev, "%s invalid eint_num %lu\n",
> +			__func__, eint_num);
> +		return 0;
> +	}
>   
>   	virq = irq_find_mapping(eint->domain, eint_num);
> -	eint_offset = (eint_num % 4) * 8;
> +	eint_offset = (index % 4) * 8;
>   	d = irq_get_irq_data(virq);
>   
> -	set_offset = (eint_num / 4) * 4 + eint->regs->dbnc_set;
> -	clr_offset = (eint_num / 4) * 4 + eint->regs->dbnc_clr;
> +	reg = eint->instances[instance].base;
> +	set_offset = (index / 4) * 4 + eint->comp->regs->dbnc_set;
> +	clr_offset = (index / 4) * 4 + eint->comp->regs->dbnc_clr;
>   
>   	if (!mtk_eint_can_en_debounce(eint, eint_num))
>   		return -EINVAL;
>   
> -	dbnc = eint->num_db_time;
> -	for (i = 0; i < eint->num_db_time; i++) {
> -		if (debounce <= eint->hw->db_time[i]) {
> +	/*
> +	 * Check eint number to avoid access out-of-range
> +	 */
> +	dbnc = ARRAY_SIZE(debounce_time) - 1;
> +	for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
> +		if (debounce <= debounce_time[i]) {
>   			dbnc = i;
>   			break;
>   		}
> @@ -454,18 +648,16 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
>   	}
>   
>   	clr_bit = 0xff << eint_offset;
> -	writel(clr_bit, eint->base + clr_offset);
> +	writel(clr_bit, reg + clr_offset);
>   
> -	bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS) | MTK_EINT_DBNC_SET_EN) <<
> -		eint_offset;
> +	bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS)
> +		| MTK_EINT_DBNC_SET_EN) << eint_offset;
>   	rst = MTK_EINT_DBNC_RST_BIT << eint_offset;
> -	writel(rst | bit, eint->base + set_offset);
> +	writel(rst | bit, reg + set_offset);
> +
> +	/* Delay should be (8T @ 32k) from dbc rst to work correctly. */
> +	udelay(250);
>   
> -	/*
> -	 * Delay a while (more than 2T) to wait for hw debounce counter reset
> -	 * work correctly.
> -	 */
> -	udelay(1);
>   	if (unmask == 1)
>   		mtk_eint_unmask(d);
>   
> @@ -473,6 +665,53 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
>   }
>   EXPORT_SYMBOL_GPL(mtk_eint_set_debounce);
>   
> +static unsigned int mtk_eint_get_debounce_en(struct mtk_eint *eint,
> +				      unsigned int eint_num)
> +{
> +	unsigned int instance, index, bit;
> +	void __iomem *reg;
> +
> +	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
> +				  &instance, &index);
> +
> +	if (!reg) {
> +		dev_err(eint->dev, "%s invalid eint_num %d\n",
> +			__func__, eint_num);
> +		return 0;
> +	}
> +
> +	reg = eint->instances[instance].base +
> +		(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
> +
> +	bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
> +
> +	return (readl(reg) & bit) ? 1 : 0;
> +}
> +
> +static unsigned int mtk_eint_get_debounce_value(struct mtk_eint *eint,
> +					 unsigned int eint_num)
> +{
> +	unsigned int instance, index, mask, offset;
> +	void __iomem *reg;
> +
> +	reg = mtk_eint_get_offset(eint, eint_num, MTK_EINT_NO_OFFSET,
> +				  &instance, &index);
> +
> +	if (!reg) {
> +		dev_err(eint->dev, "%s invalid eint_num %d\n",
> +			__func__, eint_num);
> +		return 0;
> +	}
> +
> +	reg = eint->instances[instance].base +
> +		(index / 4) * 4 + eint->comp->regs->dbnc_ctrl;
> +
> +	offset = MTK_EINT_DBNC_SET_DBNC_BITS + ((index % 4) * 8);
> +	mask = 0xf << offset;
> +
> +	return ((readl(reg) & mask) >> offset);
> +}
> +
>   int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
>   {
>   	int irq;
> @@ -485,44 +724,349 @@ int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
>   }
>   EXPORT_SYMBOL_GPL(mtk_eint_find_irq);
>   
> +/*
> + * Dump the properties/states of the specific EINT pin.
> + * @eint_num: the global EINT number.
> + * @buf: the pointer of a string buffer.
> + * @buf_size: the size of the buffer.
> + *
> + * If the return value < 0, it means that the @eint_num is invalid;
> + * Otherwise, return 0;
> + */
> +int dump_eint_pin_status(unsigned int eint_num, char *buf, unsigned int buf_size)
> +{
> +	unsigned int len = 0, enabled, stat, raw_stat, soft, mask, sens, pol,
> +		     deb_en, deb_val;
> +
> +	if (eint_num < 0 || eint_num >= global_eintc->total_pin_number)
> +		return -ENODEV;
> +
> +	enabled = global_eintc->pins[eint_num].enabled;
> +	stat = mtk_eint_get_stat(global_eintc, eint_num);
> +	raw_stat = mtk_eint_get_raw_stat(global_eintc, eint_num);
> +	soft = mtk_eint_get_soft(global_eintc, eint_num);
> +	mask = mtk_eint_get_mask(global_eintc, eint_num);
> +	sens = mtk_eint_get_sens(global_eintc, eint_num);
> +	pol = mtk_eint_get_pol(global_eintc, eint_num);
> +
> +	len += snprintf(buf + len, buf_size - len,
> +			"%s=%u(%s)\n%s=%s_%s\n%s=%u\n%s=%u\n%s=%u\n%s=%u\n",
> +			"Pin", eint_num, enabled ? "enabled" : "disabled",
> +			"Type", (sens == 1) ? "level" : "edge",
> +			(pol == 1) ? "high" : "low",
> +			"Pending", stat,
> +			"Raw", raw_stat,
> +			"Soft", soft,
> +			"Mask", mask);
> +
> +	if (mtk_eint_can_en_debounce(global_eintc, eint_num)) {
> +		deb_en	= mtk_eint_get_debounce_en(global_eintc, eint_num);
> +		deb_val = mtk_eint_get_debounce_value(global_eintc, eint_num);
> +
> +		len += snprintf(buf + len, buf_size - len,
> +				"Support debounce, %s=%u, %s=%u\n",
> +				"enable", deb_en,
> +				"setting", deb_val);
> +	} else {
> +		len += snprintf(buf + len, buf_size - len,
> +				"Not support debounce\n");
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(dump_eint_pin_status);

Why do you need to export this function?

> +
> +static ssize_t eintc_status_show(struct device_driver *driver, char *buf)
> +{
> +	struct mtk_eint *eint = global_eintc;
> +	unsigned int i, j, len = 0,
> +		     instance_num = eint->instance_number;
> +
> +	len += snprintf(buf + len, PAGE_SIZE - len, "=====EINTC Dump=====\n");
> +
> +	for (i = 0; i < instance_num; i++) {
> +		struct mtk_eint_instance inst = eint->instances[i];
> +
> +		len += snprintf(buf + len, PAGE_SIZE - len,
> +				"Instance %d name=%s with %u pins\n",
> +				i, inst.name, inst.number);
> +
> +		for (j = 0; j < inst.number; j++)
> +			len += snprintf(buf + len, PAGE_SIZE - len,
> +					"%d ", inst.pin_list[j]);
> +
> +		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
> +	}
> +
> +	return strlen(buf);
> +}
> +
> +static DRIVER_ATTR_RO(eintc_status);
> +
> +static ssize_t eint_pin_status_show(struct device_driver *driver, char *buf)
> +{
> +	struct mtk_eint *eint = global_eintc;
> +	unsigned int len = 0;
> +
> +	len += snprintf(buf + len, PAGE_SIZE - len,
> +			"=====EINT Pin Dump=====\n");
> +
> +	dump_eint_pin_status(eint->dump_target_eint,
> +			     buf + len, PAGE_SIZE - len);
> +
> +	return strlen(buf);
> +}
> +
> +static ssize_t eint_pin_status_store(struct device_driver *driver,
> +				     const char *buf, size_t count)
> +{
> +	int eint_num, ret;
> +
> +	ret = kstrtouint(buf, 10, &eint_num);
> +

Controlling pinctrl from userspace? Isn't there a generic facility to do this?

> +	if (ret || eint_num >= global_eintc->total_pin_number) {
> +		dev_err(global_eintc->dev,
> +			"%s invalid input: %s.\n", __func__, buf);
> +		goto err_out;
> +	}
> +
> +	global_eintc->dump_target_eint = (unsigned int)eint_num;
> +
> +err_out:
> +	return count;
> +}
> +
> +static DRIVER_ATTR_RW(eint_pin_status);
> +
> +static const struct mtk_eint_compatible default_compat = {
> +	.regs = &mtk_generic_eint_regs,
> +};
> +
>   int mtk_eint_do_init(struct mtk_eint *eint)
>   {
> -	int i;
> +	int i, virq;
> +	unsigned int ret, size, inst = 0;
>   
> -	/* If clients don't assign a specific regs, let's use generic one */
> -	if (!eint->regs)
> -		eint->regs = &mtk_generic_eint_regs;
> +	eint->instance_number = 1;
> +	eint->total_pin_number = eint->hw->ap_num;
>   
> -	eint->wake_mask = devm_kcalloc(eint->dev, eint->hw->ports,
> -				       sizeof(*eint->wake_mask), GFP_KERNEL);
> -	if (!eint->wake_mask)
> -		return -ENOMEM;
> +	dev_info(eint->dev, "%s read ap_num: %u\n", __func__, eint->hw->ap_num);
>   
> -	eint->cur_mask = devm_kcalloc(eint->dev, eint->hw->ports,
> -				      sizeof(*eint->cur_mask), GFP_KERNEL);
> -	if (!eint->cur_mask)
> +	size = eint->instance_number * sizeof(struct mtk_eint_instance);
> +	eint->instances = devm_kzalloc(eint->dev, size, GFP_KERNEL);
> +	if (!eint->instances)
>   		return -ENOMEM;
>   
> -	eint->dual_edge = devm_kcalloc(eint->dev, eint->hw->ap_num,
> -				       sizeof(int), GFP_KERNEL);
> -	if (!eint->dual_edge)
> +	size = eint->total_pin_number * sizeof(struct mtk_eint_pin);
> +	eint->pins = devm_kzalloc(eint->dev, size, GFP_KERNEL);
> +	if (!eint->pins)
>   		return -ENOMEM;
>   
> +	for (i = 0; i < eint->total_pin_number; i++) {
> +		eint->pins[i].enabled = true;
> +		eint->pins[i].instance = inst;
> +		eint->pins[i].index = i;
> +		eint->pins[i].debounce =  (i < eint->hw->db_cnt) ? 1 : 0;
> +
> +		eint->instances[inst].pin_list[i] = i;
> +		eint->instances[inst].number++;
> +	}
> +
> +	for (i = 0; i < eint->instance_number; i++) {
> +		size = (eint->instances[i].number / 32 + 1) * sizeof(unsigned int);
> +		eint->instances[i].wake_mask =
> +			devm_kzalloc(eint->dev, size, GFP_KERNEL);
> +		eint->instances[i].cur_mask =
> +			devm_kzalloc(eint->dev, size, GFP_KERNEL);
> +
> +		if (!eint->instances[i].wake_mask ||
> +		    !eint->instances[i].cur_mask)
> +			return -ENOMEM;
> +	}
> +
> +	eint->comp = &default_compat;
> +
>   	eint->domain = irq_domain_add_linear(eint->dev->of_node,
> -					     eint->hw->ap_num,
> +					     eint->total_pin_number,
>   					     &irq_domain_simple_ops, NULL);
>   	if (!eint->domain)
>   		return -ENOMEM;
>   
> -	if (eint->hw->db_time) {
> -		for (i = 0; i < MTK_EINT_DBNC_MAX; i++)
> -			if (eint->hw->db_time[i] == 0)
> -				break;
> -		eint->num_db_time = i;
> +	eint->instances[inst].base = eint->base;
> +
> +	mtk_eint_hw_init(eint);
> +
> +	for (i = 0; i < eint->total_pin_number; i++) {
> +		virq = irq_create_mapping(eint->domain, i);
> +
> +		irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
> +					 handle_level_irq);
> +		irq_set_chip_data(virq, eint);
> +	}
> +
> +	irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler,
> +					 eint);
> +
> +	ret = driver_create_file(eint->dev->driver,
> +				 &driver_attr_eintc_status);
> +
> +	ret |= driver_create_file(eint->dev->driver,
> +				  &driver_attr_eint_pin_status);
> +
> +	if (ret)
> +		dev_err(eint->dev, "%s create sysfs files failed.\n", __func__);
> +
> +	global_eintc = eint;

No global variables please. Makes no sense.

> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(mtk_eint_do_init);
> +
> +int mtk_eint_do_init_v2(struct mtk_eint *eint)
> +{
> +	int i, matrix_number = 0;
> +	struct device_node *node;
> +	unsigned int ret, size, offset;
> +	unsigned int id, inst, idx, support_deb;
> +
> +	const phandle *ph;
> +
> +#if defined(MTK_EINT_DEBUG)
> +	struct mtk_eint_pin pin;
> +#endif
> +
> +	ph = of_get_property(eint->dev->of_node, "mediatek,eint", NULL);

I'm not really sure that you really need this property, as the eint was declared
inside of the main pinctrl node for the SoC, and I'm mostly sure that you can keep
doing the same with eintv2.

> +	if (!ph) {
> +		dev_err(eint->dev, "Cannot find EINT phandle in PIO node.\n");
> +		return -ENODEV;
> +	}
> +
> +	node = of_find_node_by_phandle(be32_to_cpup(ph));
> +	if (!node) {
> +		dev_err(eint->dev, "Cannot find EINT node by phandle.\n");
> +		return -ENODEV;
> +	}
> +
> +	ret = of_property_read_u32(node, "mediatek,total-pin-number",
> +				   &eint->total_pin_number);

This is not for devicetree.
This is a SoC property and must be specified per-SoC as platform data.

> +	if (ret) {
> +		dev_err(eint->dev, "%s Get total pin Fail.\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	dev_info(eint->dev, "%s eint total pins:%u.\n",
> +		 __func__, eint->total_pin_number);
> +
> +	ret = of_property_read_u32(node, "mediatek,instance-num",
> +				   &eint->instance_number);
> +	if (ret)
> +		eint->instance_number = 1;

Can one SoC have variable instance numbers? I don't think so.

That goes to platform data.

> +
> +	size = eint->instance_number * sizeof(struct mtk_eint_instance);
> +	eint->instances = devm_kzalloc(eint->dev, size, GFP_KERNEL);
> +	if (!eint->instances)
> +		return -ENOMEM;
> +
> +	size = eint->total_pin_number * sizeof(struct mtk_eint_pin);
> +	eint->pins = devm_kzalloc(eint->dev, size, GFP_KERNEL);
> +	if (!eint->pins)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < eint->instance_number; i++) {
> +		ret = of_property_read_string_index(node, "reg-name", i,
> +						    &(eint->instances[i].name));

That reg-name is not a standard property; besides, you don't need to parse names,
as you can restrict the order in bindings you can just parse by knowing the
number of declared register spaces.

> +		if (ret) {
> +			dev_info(eint->dev,
> +				 "%s cannot read the name of instance %d.\n",
> +				 __func__, i);
> +		}
> +
> +		eint->instances[i].base = of_iomap(node, i);
> +		if (!eint->instances[i].base)
> +			return -ENOMEM;
>   	}
>   
> +	matrix_number = of_property_count_u32_elems(node, "mediatek,pins") / 4;

That's another thing for platform data instead.

> +	if (matrix_number < 0) {
> +		matrix_number = eint->total_pin_number;
> +		dev_info(eint->dev, "%s eint in legacy mode, matrix number is %u.\n",
> +			 __func__, matrix_number);
> +	} else {
> +		dev_info(eint->dev, "%s eint in new mode, matrix number is %u.\n",
> +			 __func__, matrix_number);
> +	}
> +
> +	for (i = 0; i < matrix_number ; i++) {
> +		offset = i * 4;
> +
> +		ret = of_property_read_u32_index(node, "mediatek,pins",
> +						 offset, &id);

Same, that's platform data!

> +		ret |= of_property_read_u32_index(node, "mediatek,pins",
> +						  offset + 1, &inst);
> +		ret |= of_property_read_u32_index(node, "mediatek,pins",
> +						  offset + 2, &idx);
> +		ret |= of_property_read_u32_index(node, "mediatek,pins",
> +						  offset + 3, &support_deb);
> +
> +		/* Legacy chip which no need to give coordinate list */
> +		if (ret) {
> +			id = i;
> +			inst = 0;
> +			idx = i;
> +			support_deb = (i < MTK_EINT_DBNC_MAX) ? 1 : 0;
> +		}
> +
> +		eint->pins[id].enabled = true;
> +		eint->pins[id].instance = inst;
> +		eint->pins[id].index = idx;
> +		eint->pins[id].debounce = support_deb;
> +
> +		eint->instances[inst].pin_list[idx] = id;
> +		eint->instances[inst].number++;
> +
> +#if defined(MTK_EINT_DEBUG)

No. You either use a dev_dbg() or you just avoid this print.

Please remove the MTK_EINT_DEBUG definition entirely.

> +		pin = eint->pins[id];
> +		dev_info(eint->dev,
> +			 "EINT%u in (%u-%u, %u), deb = %u. %u",
> +			 id,
> +			 pin.instance,
> +			 eint->instances[inst].number,
> +			 pin.index,
> +			 pin.debounce,
> +			 eint->instances[pin.instance].pin_list[pin.index]);
> +#endif
> +		BUG_ON(idx >= MAX_PIN);
> +	}
> +
> +	for (i = 0; i < eint->instance_number; i++) {
> +		size = (eint->instances[i].number / 32 + 1) * sizeof(unsigned int);
> +		eint->instances[i].wake_mask =
> +			devm_kzalloc(eint->dev, size, GFP_KERNEL);
> +		eint->instances[i].cur_mask =
> +			devm_kzalloc(eint->dev, size, GFP_KERNEL);
> +
> +		if (!eint->instances[i].wake_mask ||
> +		    !eint->instances[i].cur_mask)
> +			return -ENOMEM;
> +	}
> +
> +	eint->comp = &default_compat;
> +
> +	eint->irq = irq_of_parse_and_map(node, 0);
> +	if (!eint->irq) {
> +		dev_err(eint->dev,
> +			"%s IRQ parse fail.\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	eint->domain = irq_domain_add_linear(eint->dev->of_node,
> +					     eint->total_pin_number,
> +					     &irq_domain_simple_ops, NULL);
> +	if (!eint->domain)
> +		return -ENOMEM;
> +
>   	mtk_eint_hw_init(eint);
> -	for (i = 0; i < eint->hw->ap_num; i++) {
> +	for (i = 0; i < eint->total_pin_number; i++) {
>   		int virq = irq_create_mapping(eint->domain, i);
>   
>   		irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
> @@ -533,9 +1077,20 @@ int mtk_eint_do_init(struct mtk_eint *eint)
>   	irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler,
>   					 eint);
>   
> +	ret = driver_create_file(eint->dev->driver,
> +				 &driver_attr_eintc_status);
> +
> +	ret |= driver_create_file(eint->dev->driver,
> +				  &driver_attr_eint_pin_status);

ret = driver_create_file...
if (ret)
	return ret;

ret = driver_create_file...
if (ret)
	return ret;

OR'ing return values is never a good idea.

> +
> +	if (ret)
> +		dev_err(eint->dev, "%s create sysfs files failed.\n", __func__);
> +
> +	global_eintc = eint;
> +
>   	return 0;
>   }
> -EXPORT_SYMBOL_GPL(mtk_eint_do_init);
> +EXPORT_SYMBOL_GPL(mtk_eint_do_init_v2);
>   
>   MODULE_LICENSE("GPL v2");
>   MODULE_DESCRIPTION("MediaTek EINT Driver");
> diff --git a/drivers/pinctrl/mediatek/mtk-eint.h b/drivers/pinctrl/mediatek/mtk-eint.h
> index 6139b16cd225..30be50308b44 100644
> --- a/drivers/pinctrl/mediatek/mtk-eint.h
> +++ b/drivers/pinctrl/mediatek/mtk-eint.h
> @@ -1,16 +1,19 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> +/* SPDX-License-Identifier: GPL-2.0-only */
>   /*
> - * Copyright (C) 2014-2018 MediaTek Inc.
> + * Copyright (C) 2014-2024 MediaTek Inc.
>    *
>    * Author: Maoguang Meng <maoguang.meng at mediatek.com>
> - *	   Sean Wang <sean.wang at mediatek.com>
> - *
> + * Sean Wang <sean.wang at mediatek.com>
> + * Chhao Chang <ot_chhao.chang at mediatek.com>
>    */
>   #ifndef __MTK_EINT_H
>   #define __MTK_EINT_H
>   
>   #include <linux/irqdomain.h>
>   
> +#define MAX_PIN 256
> +//#define MTK_EINT_DEBUG
> +
>   struct mtk_eint_regs {
>   	unsigned int	stat;
>   	unsigned int	ack;
> @@ -30,19 +33,37 @@ struct mtk_eint_regs {
>   	unsigned int	dbnc_ctrl;
>   	unsigned int	dbnc_set;
>   	unsigned int	dbnc_clr;
> +	unsigned int	event;
> +	unsigned int	event_set;
> +	unsigned int	event_clr;
> +	unsigned int	raw_stat;
>   };
>   
> -struct mtk_eint_hw {
> -	u8		port_mask;
> -	u8		ports;
> -	unsigned int	ap_num;
> -	unsigned int	db_cnt;
> -	const unsigned int *db_time;
> +struct mtk_eint_ops {
> +	void (*ack)(struct irq_data *d);
>   };
>   
> -extern const unsigned int debounce_time_mt2701[];
> -extern const unsigned int debounce_time_mt6765[];
> -extern const unsigned int debounce_time_mt6795[];
> +struct mtk_eint_compatible {
> +	struct mtk_eint_ops ops;
> +	const struct mtk_eint_regs *regs;
> +};
> +
> +struct mtk_eint_pin {
> +	bool enabled;
> +	u8 instance;
> +	u8 index;
> +	bool debounce;
> +	bool dual_edge;
> +};
> +
> +struct mtk_eint_instance {
> +	const char *name;
> +	void __iomem *base;
> +	unsigned int number;
> +	u16 pin_list[MAX_PIN];
> +	unsigned int *wake_mask;
> +	unsigned int *cur_mask;
> +};
>   
>   struct mtk_eint;
>   
> @@ -54,33 +75,49 @@ struct mtk_eint_xt {
>   	int (*set_gpio_as_eint)(void *data, unsigned long eint_n);
>   };
>   
> +struct mtk_eint_hw {
> +	u8              port_mask;
> +	u8              ports;
> +	unsigned int    ap_num;
> +	unsigned int    db_cnt;
> +	const unsigned int *db_time;
> +};
> +
> +extern const unsigned int debounce_time_mt2701[];
> +extern const unsigned int debounce_time_mt6765[];
> +extern const unsigned int debounce_time_mt6795[];
> +
>   struct mtk_eint {
>   	struct device *dev;
>   	void __iomem *base;
>   	struct irq_domain *domain;
>   	int irq;
>   
> -	int *dual_edge;
> -	u32 *wake_mask;
> -	u32 *cur_mask;
> -
> -	/* Used to fit into various EINT device */
> +	/* An array to record the coordinate, index by global EINT ID */
> +	struct mtk_eint_pin *pins;
> +	/* An array to record the global EINT ID, index by coordinate */
> +	struct mtk_eint_instance *instances;
> +	unsigned int total_pin_number;
> +	unsigned int instance_number;
> +	unsigned int dump_target_eint;
> +	const struct mtk_eint_compatible *comp;
>   	const struct mtk_eint_hw *hw;
>   	const struct mtk_eint_regs *regs;
> -	u16 num_db_time;
>   
>   	/* Used to fit into various pinctrl device */
>   	void *pctl;
>   	const struct mtk_eint_xt *gpio_xlate;
>   };
>   
> -#if IS_ENABLED(CONFIG_EINT_MTK)
> +#if (IS_ENABLED(CONFIG_EINT_MTK) || IS_ENABLED(CONFIG_DEVICE_MODULES_EINT_MTK))
>   int mtk_eint_do_init(struct mtk_eint *eint);
> +int mtk_eint_do_init_v2(struct mtk_eint *eint);
>   int mtk_eint_do_suspend(struct mtk_eint *eint);
>   int mtk_eint_do_resume(struct mtk_eint *eint);
>   int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n,
>   			  unsigned int debounce);
>   int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n);
> +int dump_eint_pin_status(unsigned int eint_num, char *buf, unsigned int buf_size);
>   
>   #else
>   static inline int mtk_eint_do_init(struct mtk_eint *eint)
> @@ -88,6 +125,11 @@ static inline int mtk_eint_do_init(struct mtk_eint *eint)
>   	return -EOPNOTSUPP;
>   }
>   
> +static inline int mtk_eint_do_init_v2(struct mtk_eint *eint)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
>   static inline int mtk_eint_do_suspend(struct mtk_eint *eint)
>   {
>   	return -EOPNOTSUPP;
> @@ -108,5 +150,10 @@ static inline int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
>   {
>   	return -EOPNOTSUPP;
>   }
> +
> +static inline int dump_eint_pin_status(unsigned int eint_num)
> +{
> +	return -EOPNOTSUPP;
> +}
>   #endif
>   #endif /* __MTK_EINT_H */
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 54301fbba524..59d5ca2405f3 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -375,33 +375,37 @@ int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
>   	if (!of_property_read_bool(np, "interrupt-controller"))
>   		return -ENODEV;
>   
> -	hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
> -	if (!hw->eint)
> -		return -ENOMEM;
> -
> -	hw->eint->base = devm_platform_ioremap_resource_byname(pdev, "eint");
> -	if (IS_ERR(hw->eint->base)) {
> -		ret = PTR_ERR(hw->eint->base);
> -		goto err_free_eint;
> -	}
> +	if (hw->soc->eint_hw) {
> +		hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
> +		if (!hw->eint)
> +			return -ENOMEM;
> +
> +		hw->eint->base = devm_platform_ioremap_resource_byname(pdev, "eint");
> +		if (IS_ERR(hw->eint->base)) {
> +			ret = PTR_ERR(hw->eint->base);
> +			goto err_free_eint;
> +		}
>   
> -	hw->eint->irq = irq_of_parse_and_map(np, 0);
> -	if (!hw->eint->irq) {
> -		ret = -EINVAL;
> -		goto err_free_eint;
> -	}
> +		hw->eint->irq = irq_of_parse_and_map(np, 0);
> +		if (!hw->eint->irq) {
> +			ret = -EINVAL;
> +			goto err_free_eint;
> +		}
>   
> -	if (!hw->soc->eint_hw) {
> -		ret = -ENODEV;
> -		goto err_free_eint;
> -	}
> +		hw->eint->dev = &pdev->dev;
> +		hw->eint->hw = hw->soc->eint_hw;
> +		hw->eint->pctl = hw;
> +		hw->eint->gpio_xlate = &mtk_eint_xt;
> +
> +		return mtk_eint_do_init(hw->eint);
>   
> -	hw->eint->dev = &pdev->dev;
> -	hw->eint->hw = hw->soc->eint_hw;
> -	hw->eint->pctl = hw;
> -	hw->eint->gpio_xlate = &mtk_eint_xt;
> +	} else {
> +		hw->eint->dev = &pdev->dev;
> +		hw->eint->pctl = hw;
> +		hw->eint->gpio_xlate = &mtk_eint_xt;
>   
> -	return mtk_eint_do_init(hw->eint);
> +		return mtk_eint_do_init_v2(hw->eint);
> +	}
>   
>   err_free_eint:
>   	devm_kfree(hw->dev, hw->eint);




From o.rempel at pengutronix.de  Thu Dec 19 04:22:59 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Thu, 19 Dec 2024 13:22:59 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
References: <20241218043541.143194-1-carlos.song@nxp.com>
 <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
Message-ID: <Z2QQI2gJNLjI-fam@pengutronix.de>

On Thu, Dec 19, 2024 at 01:02:29PM +0100, Andi Shyti wrote:
> Hi Carlos,
> 
> > +	/*
> > +	 * Init DMA config if supported, -ENODEV means DMA not enabled at
> > +	 * this platform, that is not a real error, so just remind "only
> > +	 * PIO mode is used". If DMA is enabled, but meet error when request
> > +	 * DMA channel, error should be showed in probe error log. PIO mode
> > +	 * should be available regardless of DMA.
> > +	 */
> > +	ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> > +	if (ret) {
> > +		if (ret == -EPROBE_DEFER)
> > +			goto clk_notifier_unregister;
> > +		else if (ret == -ENODEV)
> > +			dev_dbg(&pdev->dev, "Only use PIO mode\n");
> > +		else
> > +			dev_err_probe(&pdev->dev, ret, "Failed to setup DMA, only use PIO mode\n");
> 
> Just for understanding, should we quit in this last case, as
> well?
> 
> Before we were ignoring ENODEV and EPROBE_DEFER, but now you are
> making it clear that other failures like ENOMEM might happen.

Good point, dev_err_probe() would not print an error in case of EPROBE_DEFER,
but in this case we should only print error and continue with PIO.

-- 
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 maz at kernel.org  Thu Dec 19 04:23:37 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 12:23:37 +0000
Subject: [PATCH] KVM: arm64: nv: Set ISTATUS for emulated timers, If timer expired
In-Reply-To: <2f6b2cb1-3d32-480a-9801-9b993ae74e2d@os.amperecomputing.com>
References: <20241209053201.339939-1-gankulkarni@os.amperecomputing.com>
	<867c89tc4q.wl-maz@kernel.org>
	<c5b1c3d7-56ca-4afc-a831-045dba4beffa@os.amperecomputing.com>
	<865xntt2kv.wl-maz@kernel.org>
	<8be59ff3-6a68-48e1-8181-0ce4b2e7180f@os.amperecomputing.com>
	<bcb4289b-507c-4ea1-afc7-6febd34d88db@redhat.com>
	<86y10osr19.wl-maz@kernel.org>
	<4d443db1-85b1-4071-acd5-3187deb9cb17@redhat.com>
	<2f6b2cb1-3d32-480a-9801-9b993ae74e2d@os.amperecomputing.com>
Message-ID: <864j2zrhdi.wl-maz@kernel.org>

On Thu, 19 Dec 2024 09:30:11 +0000,
Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> 
> 
> 
> On 09-12-2024 11:04 pm, Eric Auger wrote:
> > Hi Marc,
> > 
> > On 12/9/24 18:30, Marc Zyngier wrote:
> >> On Mon, 09 Dec 2024 16:46:30 +0000,
> >> Eric Auger <eauger at redhat.com> wrote:
> >>> 
> >>> Hi,
> >>> 
> >>> On 12/9/24 16:39, Ganapatrao Kulkarni wrote:
> >>>> 
> >>>> 
> >>>> On 09-12-2024 06:50 pm, Marc Zyngier wrote:
> >>>>> On Mon, 09 Dec 2024 12:25:34 +0000,
> >>>>> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> >>>>>>>> 
> >>>>>>>> During automated testing of Nested Virtualization using avocado-vt,
> >>>>>>> 
> >>>>>>> Which is not merged upstream. So what branch are you using? Based on
> >>>>>>> what kernel version? On what HW? With which virtualisation features?
> >>>>>>> 
> >>>>>> 
> >>>>>> Testing is done on Ampere's AmpereOne platform using 6.10 based kernel
> >>>>>> with NV patches from your repo.
> >>>>> 
> >>>>> Grmbl... *Which* patches? At least give me the SHA1 of the branch,
> >>>>> because I have no idea what you are running. And 6.10 is definitely
> >>>>> not something I care about. If you're using the NV patches, the
> >>>>> *minimum* you should run is 6.13-rc1, because that's what the current
> >>>>> code is based on.
> >>>>> 
> >>>> 
> >>>> I tried 6.13-rc1 based nv-next branch today, which failed to boot
> >>>> UEFI as L1. Yet to debug this.
> >>> 
> >>> I confirm am stuck with the same issue with nv-next on AmpereOne.
> >> 
> >> All I can say is that it Works For Me (TM) on M2 and Snapdragon, using
> >> kvmtool, a fresh EDK2 built by Ard, and with the guest running purely
> >> VHE (FEAT_E2H0 not implemented).
> >> 
> >> I haven't tried QEMU, I don't have an AmpereOne. I have also spent way
> >> too much time on this recently. So I'm afraid people interested in
> >> making this particular combination work will have to debug it.
> > 
> > yes I do agree. I am currently setting up kvmtool to double check and I
> > will debug the qemu issue.
> 
> I could boot Guest-hypervisor using QEMU with -bios and nv-next as L0
> with edk2 (QEMU_EFI.fd) built from upstream tree and fedora-41 as
> Guest-Hypervisor.

Cool. This shows that Ard's hard work on EDK2 is paying off.

> 
> The issue was disappeared when upgraded from fc39 to fc41. Same was
> experienced with the kvmtool boot as well(KVMTOOL_EFI.fd).

I guess the fc39 kernel is too old to understand the VHE-only ID
registers, which was introduced in 6.9.

Once you teach QEMU how to disable VHE, you should be able to boot
older kernels that predate this change.

	M.

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


From mike.leach at linaro.org  Thu Dec 19 04:23:37 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:23:37 +0000
Subject: [PATCH v3 8/9] coresight-tmc: change tmc_drvdata spinlock's type
 to raw_spinlock_t
In-Reply-To: <20241216115006.415861-9-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com> <20241216115006.415861-9-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7VgA9YsEyQHMPVXG_8H-Kp_wpnd9ro1dGNV9CFzX+EqvWA@mail.gmail.com>

On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In coresight-tmc drivers, tmc_drvdata->spinlock can be held
> during __schedule() by perf_event_task_sched_out()/in().
>
> Since tmc_drvdata->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this, change type tmc_drvdata->spinlock in coresight-tmc drivers,
> which can be called by perf_event_task_sched_out()/in(),
> from spinlock_t to raw_spinlock_t.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  .../hwtracing/coresight/coresight-tmc-core.c  |  6 +--
>  .../hwtracing/coresight/coresight-tmc-etf.c   | 48 +++++++++----------
>  .../hwtracing/coresight/coresight-tmc-etr.c   | 40 ++++++++--------
>  drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
>  4 files changed, 48 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index e9876252a789..4e9925300931 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -492,7 +492,7 @@ static int __tmc_probe(struct device *dev, struct resource *res)
>         drvdata->base = base;
>         desc.access = CSDEV_ACCESS_IOMEM(base);
>
> -       spin_lock_init(&drvdata->spinlock);
> +       raw_spin_lock_init(&drvdata->spinlock);
>
>         devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
>         drvdata->config_type = BMVAL(devid, 6, 7);
> @@ -596,7 +596,7 @@ static void tmc_shutdown(struct amba_device *adev)
>         unsigned long flags;
>         struct tmc_drvdata *drvdata = amba_get_drvdata(adev);
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         if (coresight_get_mode(drvdata->csdev) == CS_MODE_DISABLED)
>                 goto out;
> @@ -610,7 +610,7 @@ static void tmc_shutdown(struct amba_device *adev)
>          * the system is going down after this.
>          */
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>  }
>
>  static void __tmc_remove(struct device *dev)
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
> index d4f641cd9de6..fca8e9ffb3cf 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
> @@ -182,9 +182,9 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
>          * If we don't have a buffer release the lock and allocate memory.
>          * Otherwise keep the lock and move along.
>          */
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         if (!drvdata->buf) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>                 /* Allocating the memory here while outside of the spinlock */
>                 buf = kzalloc(drvdata->size, GFP_KERNEL);
> @@ -192,7 +192,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
>                         return -ENOMEM;
>
>                 /* Let's try again */
> -               spin_lock_irqsave(&drvdata->spinlock, flags);
> +               raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         }
>
>         if (drvdata->reading) {
> @@ -235,7 +235,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
>                 used = false;
>         }
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         /* Free memory outside the spinlock if need be */
>         if (!used)
> @@ -253,7 +253,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
>         struct perf_output_handle *handle = data;
>         struct cs_buffers *buf = etm_perf_sink_config(handle);
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         do {
>                 ret = -EINVAL;
>                 if (drvdata->reading)
> @@ -296,7 +296,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
>                         csdev->refcnt++;
>                 }
>         } while (0);
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         return ret;
>  }
> @@ -331,16 +331,16 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
>         unsigned long flags;
>         struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         if (drvdata->reading) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                 return -EBUSY;
>         }
>
>         csdev->refcnt--;
>         if (csdev->refcnt) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                 return -EBUSY;
>         }
>
> @@ -351,7 +351,7 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
>         drvdata->pid = -1;
>         coresight_set_mode(csdev, CS_MODE_DISABLED);
>
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n");
>         return 0;
> @@ -366,9 +366,9 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
>         struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>         bool first_enable = false;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         if (drvdata->reading) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                 return -EBUSY;
>         }
>
> @@ -381,7 +381,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
>         }
>         if (!ret)
>                 csdev->refcnt++;
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         if (first_enable)
>                 dev_dbg(&csdev->dev, "TMC-ETF enabled\n");
> @@ -396,9 +396,9 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
>         struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>         bool last_disable = false;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         if (drvdata->reading) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                 return;
>         }
>
> @@ -408,7 +408,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
>                 coresight_set_mode(csdev, CS_MODE_DISABLED);
>                 last_disable = true;
>         }
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         if (last_disable)
>                 dev_dbg(&csdev->dev, "TMC-ETF disabled\n");
> @@ -488,7 +488,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
>         if (WARN_ON_ONCE(coresight_get_mode(csdev) != CS_MODE_PERF))
>                 return 0;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         /* Don't do anything if another tracer is using this sink */
>         if (csdev->refcnt != 1)
> @@ -585,7 +585,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
>          */
>         CS_LOCK(drvdata->base);
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         return to_read;
>  }
> @@ -623,7 +623,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
>                          drvdata->config_type != TMC_CONFIG_TYPE_ETF))
>                 return -EINVAL;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         if (drvdata->reading) {
>                 ret = -EBUSY;
> @@ -655,7 +655,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
>
>         drvdata->reading = true;
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         return ret;
>  }
> @@ -672,14 +672,14 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
>                          drvdata->config_type != TMC_CONFIG_TYPE_ETF))
>                 return -EINVAL;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         /* Re-enable the TMC if need be */
>         if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
>                 /* There is no point in reading a TMC in HW FIFO mode */
>                 mode = readl_relaxed(drvdata->base + TMC_MODE);
>                 if (mode != TMC_MODE_CIRCULAR_BUFFER) {
> -                       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +                       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                         return -EINVAL;
>                 }
>                 /*
> @@ -693,7 +693,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
>                 memset(drvdata->buf, 0, drvdata->size);
>                 rc = __tmc_etb_enable_hw(drvdata);
>                 if (rc) {
> -                       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +                       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                         return rc;
>                 }
>         } else {
> @@ -706,7 +706,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
>         }
>
>         drvdata->reading = false;
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         /*
>          * Free allocated memory outside of the spinlock.  There is no need
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index a48bb85d0e7f..a0a90ce7333e 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -1176,10 +1176,10 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
>          * buffer, provided the size matches. Any allocation has to be done
>          * with the lock released.
>          */
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         sysfs_buf = READ_ONCE(drvdata->sysfs_buf);
>         if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>                 /* Allocate memory with the locks released */
>                 free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata);
> @@ -1187,7 +1187,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
>                         return new_buf;
>
>                 /* Let's try again */
> -               spin_lock_irqsave(&drvdata->spinlock, flags);
> +               raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         }
>
>         if (drvdata->reading || coresight_get_mode(csdev) == CS_MODE_PERF) {
> @@ -1206,7 +1206,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
>         }
>
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         /* Free memory outside the spinlock if need be */
>         if (free_buf)
> @@ -1224,7 +1224,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
>         if (IS_ERR(sysfs_buf))
>                 return PTR_ERR(sysfs_buf);
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         /*
>          * In sysFS mode we can have multiple writers per sink.  Since this
> @@ -1243,7 +1243,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
>         }
>
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         if (!ret)
>                 dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
> @@ -1562,17 +1562,17 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
>         struct etr_perf_buffer *etr_perf = config;
>         struct etr_buf *etr_buf = etr_perf->etr_buf;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         /* Don't do anything if another tracer is using this sink */
>         if (csdev->refcnt != 1) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                 goto out;
>         }
>
>         if (WARN_ON(drvdata->perf_buf != etr_buf)) {
>                 lost = true;
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                 goto out;
>         }
>
> @@ -1582,7 +1582,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
>         tmc_sync_etr_buf(drvdata);
>
>         CS_LOCK(drvdata->base);
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         lost = etr_buf->full;
>         offset = etr_buf->offset;
> @@ -1651,7 +1651,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
>         struct perf_output_handle *handle = data;
>         struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>          /* Don't use this sink if it is already claimed by sysFS */
>         if (coresight_get_mode(csdev) == CS_MODE_SYSFS) {
>                 rc = -EBUSY;
> @@ -1691,7 +1691,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
>         }
>
>  unlock_out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>         return rc;
>  }
>
> @@ -1713,16 +1713,16 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
>         unsigned long flags;
>         struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         if (drvdata->reading) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                 return -EBUSY;
>         }
>
>         csdev->refcnt--;
>         if (csdev->refcnt) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                 return -EBUSY;
>         }
>
> @@ -1735,7 +1735,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
>         /* Reset perf specific data */
>         drvdata->perf_buf = NULL;
>
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         dev_dbg(&csdev->dev, "TMC-ETR disabled\n");
>         return 0;
> @@ -1762,7 +1762,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
>         if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
>                 return -EINVAL;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         if (drvdata->reading) {
>                 ret = -EBUSY;
>                 goto out;
> @@ -1784,7 +1784,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
>
>         drvdata->reading = true;
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         return ret;
>  }
> @@ -1798,7 +1798,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
>         if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
>                 return -EINVAL;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         /* RE-enable the TMC if need be */
>         if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
> @@ -1818,7 +1818,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
>         }
>
>         drvdata->reading = false;
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         /* Free allocated memory out side of the spinlock */
>         if (sysfs_buf)
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index 2671926be62a..60b395025bc4 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -195,7 +195,7 @@ struct tmc_drvdata {
>         void __iomem            *base;
>         struct coresight_device *csdev;
>         struct miscdevice       miscdev;
> -       spinlock_t              spinlock;
> +       raw_spinlock_t          spinlock;
>         pid_t                   pid;
>         bool                    reading;
>         union {
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Thu Dec 19 04:23:55 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:23:55 +0000
Subject: [PATCH v3 1/9] coresight: change coresight_device lock type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-2-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com> <20241216115006.415861-2-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7VgJNLJK2oa9Us9bFAEiEmi8_u+NJ1zNrnd5WhhHgxhPxA@mail.gmail.com>

On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> coresight_device->cscfg_csdev_lock can be held during __schedule()
> by perf_event_task_sched_out()/in().
>
> Since coresight->cscfg_csdev_lock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this, change type of coresight_device->cscfg_csdev_lock
> from spinlock_t to raw_spinlock_t.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  .../hwtracing/coresight/coresight-syscfg.c    | 26 +++++++++----------
>  include/linux/coresight.h                     |  2 +-
>  2 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
> index 11138a9762b0..a70c1454b410 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
> @@ -89,9 +89,9 @@ static int cscfg_add_csdev_cfg(struct coresight_device *csdev,
>         }
>         /* if matched features, add config to device.*/
>         if (config_csdev) {
> -               spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
> +               raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
>                 list_add(&config_csdev->node, &csdev->config_csdev_list);
> -               spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
> +               raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
>         }
>
>         return 0;
> @@ -194,9 +194,9 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev,
>
>         /* add to internal csdev feature list & initialise using reset call */
>         cscfg_reset_feat(feat_csdev);
> -       spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
> +       raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
>         list_add(&feat_csdev->node, &csdev->feature_csdev_list);
> -       spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
> +       raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
>
>         return 0;
>  }
> @@ -765,7 +765,7 @@ static int cscfg_list_add_csdev(struct coresight_device *csdev,
>
>         INIT_LIST_HEAD(&csdev->feature_csdev_list);
>         INIT_LIST_HEAD(&csdev->config_csdev_list);
> -       spin_lock_init(&csdev->cscfg_csdev_lock);
> +       raw_spin_lock_init(&csdev->cscfg_csdev_lock);
>
>         return 0;
>  }
> @@ -855,7 +855,7 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
>         struct cscfg_feature_csdev *feat_csdev;
>         unsigned long flags;
>
> -       spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
> +       raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
>         if (list_empty(&csdev->feature_csdev_list))
>                 goto unlock_exit;
>
> @@ -863,7 +863,7 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
>                 cscfg_reset_feat(feat_csdev);
>
>  unlock_exit:
> -       spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
> +       raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
>  }
>  EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
>
> @@ -1059,7 +1059,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
>          * Look for matching configuration - set the active configuration
>          * context if found.
>          */
> -       spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
> +       raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
>         list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
>                 config_desc = config_csdev_item->config_desc;
>                 if ((atomic_read(&config_desc->active_cnt)) &&
> @@ -1069,7 +1069,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
>                         break;
>                 }
>         }
> -       spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
> +       raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
>
>         /*
>          * If found, attempt to enable
> @@ -1090,12 +1090,12 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
>                          *
>                          * Set enabled if OK, err if not.
>                          */
> -                       spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
> +                       raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
>                         if (csdev->active_cscfg_ctxt)
>                                 config_csdev_active->enabled = true;
>                         else
>                                 err = -EBUSY;
> -                       spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
> +                       raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
>                 }
>         }
>         return err;
> @@ -1124,7 +1124,7 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
>          * If it was not enabled, we have no work to do, otherwise mark as disabled.
>          * Clear the active config pointer.
>          */
> -       spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
> +       raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
>         config_csdev = (struct cscfg_config_csdev *)csdev->active_cscfg_ctxt;
>         if (config_csdev) {
>                 if (!config_csdev->enabled)
> @@ -1133,7 +1133,7 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
>                         config_csdev->enabled = false;
>         }
>         csdev->active_cscfg_ctxt = NULL;
> -       spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
> +       raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
>
>         /* true if there was an enabled active config */
>         if (config_csdev)
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index c13342594278..924b58c343b3 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -296,7 +296,7 @@ struct coresight_device {
>         /* system configuration and feature lists */
>         struct list_head feature_csdev_list;
>         struct list_head config_csdev_list;
> -       spinlock_t cscfg_csdev_lock;
> +       raw_spinlock_t cscfg_csdev_lock;
>         void *active_cscfg_ctxt;
>  };
>
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Thu Dec 19 04:24:02 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:24:02 +0000
Subject: [PATCH v3 2/9] coresight-etm4x: change etmv4_drvdata spinlock
 type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-3-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com> <20241216115006.415861-3-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7Vj6_ek9D-ZySt6dNAGWwWV=7yX36T=n7+n-Nak=UEhMdw@mail.gmail.com>

Hi,

On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In coresight-etm4x drivers, etmv4_drvdata->spinlock can be held during
> __schedule() by perf_event_task_sched_out()/in().
>
> Since etmv4_drvdata->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this, change type etmv4_drvdata->spinlock
> in coresight-etm4x drivers, which can be called
> by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  .../hwtracing/coresight/coresight-config.c    |   8 +-
>  .../hwtracing/coresight/coresight-config.h    |   2 +-
>  .../coresight/coresight-etm4x-core.c          |  18 +-
>  .../coresight/coresight-etm4x-sysfs.c         | 250 +++++++++---------
>  drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
>  5 files changed, 140 insertions(+), 140 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c
> index 4723bf7402a2..4f72ae71b696 100644
> --- a/drivers/hwtracing/coresight/coresight-config.c
> +++ b/drivers/hwtracing/coresight/coresight-config.c
> @@ -76,10 +76,10 @@ static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat_csdev)
>         unsigned long flags;
>         int i;
>
> -       spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
> +       raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
>         for (i = 0; i < feat_csdev->nr_regs; i++)
>                 cscfg_set_reg(&feat_csdev->regs_csdev[i]);
> -       spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
> +       raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
>         dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
>                 feat_csdev->feat_desc->name, "set on enable");
>         return 0;
> @@ -91,10 +91,10 @@ static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat_csdev)
>         unsigned long flags;
>         int i;
>
> -       spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
> +       raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
>         for (i = 0; i < feat_csdev->nr_regs; i++)
>                 cscfg_save_reg(&feat_csdev->regs_csdev[i]);
> -       spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
> +       raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
>         dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
>                 feat_csdev->feat_desc->name, "save on disable");
>  }
> diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
> index 6ba013975741..b9ebc9fcfb7f 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -206,7 +206,7 @@ struct cscfg_feature_csdev {
>         const struct cscfg_feature_desc *feat_desc;
>         struct coresight_device *csdev;
>         struct list_head node;
> -       spinlock_t *drv_spinlock;
> +       raw_spinlock_t *drv_spinlock;
>         int nr_params;
>         struct cscfg_parameter_csdev *params_csdev;
>         int nr_regs;

The above changes are not etm4x specific - should be in the previous patch.

> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index dd8c74f893db..86893115df17 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -807,7 +807,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
>                         return ret;
>         }
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>
>         /* sysfs needs to read and allocate a trace ID */
>         ret = etm4_read_alloc_trace_id(drvdata);
> @@ -830,7 +830,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
>                 etm4_release_trace_id(drvdata);
>
>  unlock_sysfs_enable:
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>
>         if (!ret)
>                 dev_dbg(&csdev->dev, "ETM tracing enabled\n");
> @@ -977,7 +977,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
>          * DYING hotplug callback is serviced by the ETM driver.
>          */
>         cpus_read_lock();
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>
>         /*
>          * Executing etm4_disable_hw on the cpu whose ETM is being disabled
> @@ -985,7 +985,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
>          */
>         smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
>
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         cpus_read_unlock();
>
>         /*
> @@ -1663,13 +1663,13 @@ static int etm4_starting_cpu(unsigned int cpu)
>         if (!etmdrvdata[cpu])
>                 return 0;
>
> -       spin_lock(&etmdrvdata[cpu]->spinlock);
> +       raw_spin_lock(&etmdrvdata[cpu]->spinlock);
>         if (!etmdrvdata[cpu]->os_unlock)
>                 etm4_os_unlock(etmdrvdata[cpu]);
>
>         if (coresight_get_mode(etmdrvdata[cpu]->csdev))
>                 etm4_enable_hw(etmdrvdata[cpu]);
> -       spin_unlock(&etmdrvdata[cpu]->spinlock);
> +       raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
>         return 0;
>  }
>
> @@ -1678,10 +1678,10 @@ static int etm4_dying_cpu(unsigned int cpu)
>         if (!etmdrvdata[cpu])
>                 return 0;
>
> -       spin_lock(&etmdrvdata[cpu]->spinlock);
> +       raw_spin_lock(&etmdrvdata[cpu]->spinlock);
>         if (coresight_get_mode(etmdrvdata[cpu]->csdev))
>                 etm4_disable_hw(etmdrvdata[cpu]);
> -       spin_unlock(&etmdrvdata[cpu]->spinlock);
> +       raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
>         return 0;
>  }
>
> @@ -2125,7 +2125,7 @@ static int etm4_probe(struct device *dev)
>                         return -ENOMEM;
>         }
>
> -       spin_lock_init(&drvdata->spinlock);
> +       raw_spin_lock_init(&drvdata->spinlock);
>
>         drvdata->cpu = coresight_get_cpu(dev);
>         if (drvdata->cpu < 0)
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> index a9f19629f3f8..11e865b8e824 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> @@ -174,7 +174,7 @@ static ssize_t reset_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         if (val)
>                 config->mode = 0x0;
>
> @@ -266,7 +266,7 @@ static ssize_t reset_store(struct device *dev,
>         config->vmid_mask0 = 0x0;
>         config->vmid_mask1 = 0x0;
>
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>
>         /* for sysfs - only release trace id when resetting */
>         etm4_release_trace_id(drvdata);
> @@ -300,7 +300,7 @@ static ssize_t mode_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->mode = val & ETMv4_MODE_ALL;
>
>         if (drvdata->instrp0 == true) {
> @@ -437,7 +437,7 @@ static ssize_t mode_store(struct device *dev,
>         if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
>                 etm4_config_trace_mode(config);
>
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>
>         return size;
>  }
> @@ -466,14 +466,14 @@ static ssize_t pe_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         if (val > drvdata->nr_pe) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EINVAL;
>         }
>
>         config->pe_sel = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(pe);
> @@ -501,7 +501,7 @@ static ssize_t event_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         switch (drvdata->nr_event) {
>         case 0x0:
>                 /* EVENT0, bits[7:0] */
> @@ -522,7 +522,7 @@ static ssize_t event_store(struct device *dev,
>         default:
>                 break;
>         }
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(event);
> @@ -550,7 +550,7 @@ static ssize_t event_instren_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         /* start by clearing all instruction event enable bits */
>         config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;
>         switch (drvdata->nr_event) {
> @@ -578,7 +578,7 @@ static ssize_t event_instren_store(struct device *dev,
>         default:
>                 break;
>         }
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(event_instren);
> @@ -739,11 +739,11 @@ static ssize_t event_vinst_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         val &= TRCVICTLR_EVENT_MASK >> __bf_shf(TRCVICTLR_EVENT_MASK);
>         config->vinst_ctrl &= ~TRCVICTLR_EVENT_MASK;
>         config->vinst_ctrl |= FIELD_PREP(TRCVICTLR_EVENT_MASK, val);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(event_vinst);
> @@ -771,13 +771,13 @@ static ssize_t s_exlevel_vinst_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         /* clear all EXLEVEL_S bits  */
>         config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;
>         /* enable instruction tracing for corresponding exception level */
>         val &= drvdata->s_ex_level;
>         config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_S_MASK);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(s_exlevel_vinst);
> @@ -806,13 +806,13 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         /* clear EXLEVEL_NS bits  */
>         config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;
>         /* enable instruction tracing for corresponding exception level */
>         val &= drvdata->ns_ex_level;
>         config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_NS_MASK);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(ns_exlevel_vinst);
> @@ -846,9 +846,9 @@ static ssize_t addr_idx_store(struct device *dev,
>          * Use spinlock to ensure index doesn't change while it gets
>          * dereferenced multiple times within a spinlock block elsewhere.
>          */
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->addr_idx = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(addr_idx);
> @@ -862,7 +862,7 @@ static ssize_t addr_instdatatype_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         val = FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]);
>         len = scnprintf(buf, PAGE_SIZE, "%s\n",
> @@ -870,7 +870,7 @@ static ssize_t addr_instdatatype_show(struct device *dev,
>                         (val == TRCACATRn_TYPE_DATA_LOAD_ADDR ? "data_load" :
>                         (val == TRCACATRn_TYPE_DATA_STORE_ADDR ? "data_store" :
>                         "data_load_store")));
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return len;
>  }
>
> @@ -888,13 +888,13 @@ static ssize_t addr_instdatatype_store(struct device *dev,
>         if (sscanf(buf, "%s", str) != 1)
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         if (!strcmp(str, "instr"))
>                 /* TYPE, bits[1:0] */
>                 config->addr_acc[idx] &= ~TRCACATRn_TYPE_MASK;
>
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(addr_instdatatype);
> @@ -909,14 +909,14 @@ static ssize_t addr_single_show(struct device *dev,
>         struct etmv4_config *config = &drvdata->config;
>
>         idx = config->addr_idx;
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
>               config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>         val = (unsigned long)config->addr_val[idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -932,17 +932,17 @@ static ssize_t addr_single_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
>               config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>
>         config->addr_val[idx] = (u64)val;
>         config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(addr_single);
> @@ -956,23 +956,23 @@ static ssize_t addr_range_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         if (idx % 2 != 0) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>         if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
>                config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
>               (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
>                config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>
>         val1 = (unsigned long)config->addr_val[idx];
>         val2 = (unsigned long)config->addr_val[idx + 1];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
>  }
>
> @@ -995,10 +995,10 @@ static ssize_t addr_range_store(struct device *dev,
>         if (val1 > val2)
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         if (idx % 2 != 0) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>
> @@ -1006,7 +1006,7 @@ static ssize_t addr_range_store(struct device *dev,
>                config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
>               (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
>                config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>
> @@ -1023,7 +1023,7 @@ static ssize_t addr_range_store(struct device *dev,
>                 exclude = config->mode & ETM_MODE_EXCLUDE;
>         etm4_set_mode_exclude(drvdata, exclude ? true : false);
>
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(addr_range);
> @@ -1037,17 +1037,17 @@ static ssize_t addr_start_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>
>         if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
>               config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>
>         val = (unsigned long)config->addr_val[idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1063,22 +1063,22 @@ static ssize_t addr_start_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         if (!drvdata->nr_addr_cmp) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EINVAL;
>         }
>         if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
>               config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>
>         config->addr_val[idx] = (u64)val;
>         config->addr_type[idx] = ETM_ADDR_TYPE_START;
>         config->vissctlr |= BIT(idx);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(addr_start);
> @@ -1092,17 +1092,17 @@ static ssize_t addr_stop_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>
>         if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
>               config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>
>         val = (unsigned long)config->addr_val[idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1118,22 +1118,22 @@ static ssize_t addr_stop_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         if (!drvdata->nr_addr_cmp) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EINVAL;
>         }
>         if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
>                config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
> -               spin_unlock(&drvdata->spinlock);
> +               raw_spin_unlock(&drvdata->spinlock);
>                 return -EPERM;
>         }
>
>         config->addr_val[idx] = (u64)val;
>         config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
>         config->vissctlr |= BIT(idx + 16);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(addr_stop);
> @@ -1147,14 +1147,14 @@ static ssize_t addr_ctxtype_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         /* CONTEXTTYPE, bits[3:2] */
>         val = FIELD_GET(TRCACATRn_CONTEXTTYPE_MASK, config->addr_acc[idx]);
>         len = scnprintf(buf, PAGE_SIZE, "%s\n", val == ETM_CTX_NONE ? "none" :
>                         (val == ETM_CTX_CTXID ? "ctxid" :
>                         (val == ETM_CTX_VMID ? "vmid" : "all")));
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return len;
>  }
>
> @@ -1172,7 +1172,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
>         if (sscanf(buf, "%s", str) != 1)
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         if (!strcmp(str, "none"))
>                 /* start by clearing context type bits */
> @@ -1199,7 +1199,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
>                 if (drvdata->numvmidc)
>                         config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
>         }
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(addr_ctxtype);
> @@ -1213,11 +1213,11 @@ static ssize_t addr_context_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         /* context ID comparator bits[6:4] */
>         val = FIELD_GET(TRCACATRn_CONTEXT_MASK, config->addr_acc[idx]);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1238,12 +1238,12 @@ static ssize_t addr_context_store(struct device *dev,
>                      drvdata->numcidc : drvdata->numvmidc))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         /* clear context ID comparator bits[6:4] */
>         config->addr_acc[idx] &= ~TRCACATRn_CONTEXT_MASK;
>         config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_CONTEXT_MASK);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(addr_context);
> @@ -1257,10 +1257,10 @@ static ssize_t addr_exlevel_s_ns_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         val = FIELD_GET(TRCACATRn_EXLEVEL_MASK, config->addr_acc[idx]);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1279,12 +1279,12 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
>         if (val & ~(TRCACATRn_EXLEVEL_MASK >> __bf_shf(TRCACATRn_EXLEVEL_MASK)))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         /* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8], bit[15] is res0 */
>         config->addr_acc[idx] &= ~TRCACATRn_EXLEVEL_MASK;
>         config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_EXLEVEL_MASK);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(addr_exlevel_s_ns);
> @@ -1307,7 +1307,7 @@ static ssize_t addr_cmp_view_show(struct device *dev,
>         int size = 0;
>         bool exclude = false;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->addr_idx;
>         addr_v = config->addr_val[idx];
>         addr_ctrl = config->addr_acc[idx];
> @@ -1322,7 +1322,7 @@ static ssize_t addr_cmp_view_show(struct device *dev,
>                 }
>                 exclude = config->viiectlr & BIT(idx / 2 + 16);
>         }
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         if (addr_type) {
>                 size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] %s %#lx", idx,
>                                  addr_type_names[addr_type], addr_v);
> @@ -1366,9 +1366,9 @@ static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
>         if (!drvdata->nr_pe_cmp)
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->vipcssctlr = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(vinst_pe_cmp_start_stop);
> @@ -1402,9 +1402,9 @@ static ssize_t seq_idx_store(struct device *dev,
>          * Use spinlock to ensure index doesn't change while it gets
>          * dereferenced multiple times within a spinlock block elsewhere.
>          */
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->seq_idx = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(seq_idx);
> @@ -1448,10 +1448,10 @@ static ssize_t seq_event_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->seq_idx;
>         val = config->seq_ctrl[idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1467,11 +1467,11 @@ static ssize_t seq_event_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->seq_idx;
>         /* Seq control has two masks B[15:8] F[7:0] */
>         config->seq_ctrl[idx] = val & 0xFFFF;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(seq_event);
> @@ -1535,9 +1535,9 @@ static ssize_t cntr_idx_store(struct device *dev,
>          * Use spinlock to ensure index doesn't change while it gets
>          * dereferenced multiple times within a spinlock block elsewhere.
>          */
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->cntr_idx = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(cntr_idx);
> @@ -1551,10 +1551,10 @@ static ssize_t cntrldvr_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->cntr_idx;
>         val = config->cntrldvr[idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1572,10 +1572,10 @@ static ssize_t cntrldvr_store(struct device *dev,
>         if (val > ETM_CNTR_MAX_VAL)
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->cntr_idx;
>         config->cntrldvr[idx] = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(cntrldvr);
> @@ -1589,10 +1589,10 @@ static ssize_t cntr_val_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->cntr_idx;
>         val = config->cntr_val[idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1610,10 +1610,10 @@ static ssize_t cntr_val_store(struct device *dev,
>         if (val > ETM_CNTR_MAX_VAL)
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->cntr_idx;
>         config->cntr_val[idx] = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(cntr_val);
> @@ -1627,10 +1627,10 @@ static ssize_t cntr_ctrl_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->cntr_idx;
>         val = config->cntr_ctrl[idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1646,10 +1646,10 @@ static ssize_t cntr_ctrl_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->cntr_idx;
>         config->cntr_ctrl[idx] = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(cntr_ctrl);
> @@ -1687,9 +1687,9 @@ static ssize_t res_idx_store(struct device *dev,
>          * Use spinlock to ensure index doesn't change while it gets
>          * dereferenced multiple times within a spinlock block elsewhere.
>          */
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->res_idx = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(res_idx);
> @@ -1703,10 +1703,10 @@ static ssize_t res_ctrl_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->res_idx;
>         val = config->res_ctrl[idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1722,7 +1722,7 @@ static ssize_t res_ctrl_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->res_idx;
>         /* For odd idx pair inversal bit is RES0 */
>         if (idx % 2 != 0)
> @@ -1732,7 +1732,7 @@ static ssize_t res_ctrl_store(struct device *dev,
>                                        TRCRSCTLRn_INV |
>                                        TRCRSCTLRn_GROUP_MASK |
>                                        TRCRSCTLRn_SELECT_MASK);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(res_ctrl);
> @@ -1761,9 +1761,9 @@ static ssize_t sshot_idx_store(struct device *dev,
>         if (val >= drvdata->nr_ss_cmp)
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->ss_idx = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(sshot_idx);
> @@ -1776,9 +1776,9 @@ static ssize_t sshot_ctrl_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         val = config->ss_ctrl[config->ss_idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1794,12 +1794,12 @@ static ssize_t sshot_ctrl_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->ss_idx;
>         config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
>         /* must clear bit 31 in related status register on programming */
>         config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(sshot_ctrl);
> @@ -1811,9 +1811,9 @@ static ssize_t sshot_status_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         val = config->ss_status[config->ss_idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>  static DEVICE_ATTR_RO(sshot_status);
> @@ -1826,9 +1826,9 @@ static ssize_t sshot_pe_ctrl_show(struct device *dev,
>         struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct etmv4_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         val = config->ss_pe_cmp[config->ss_idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1844,12 +1844,12 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->ss_idx;
>         config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
>         /* must clear bit 31 in related status register on programming */
>         config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(sshot_pe_ctrl);
> @@ -1883,9 +1883,9 @@ static ssize_t ctxid_idx_store(struct device *dev,
>          * Use spinlock to ensure index doesn't change while it gets
>          * dereferenced multiple times within a spinlock block elsewhere.
>          */
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->ctxid_idx = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(ctxid_idx);
> @@ -1906,10 +1906,10 @@ static ssize_t ctxid_pid_show(struct device *dev,
>         if (task_active_pid_ns(current) != &init_pid_ns)
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->ctxid_idx;
>         val = (unsigned long)config->ctxid_pid[idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -1944,10 +1944,10 @@ static ssize_t ctxid_pid_store(struct device *dev,
>         if (kstrtoul(buf, 16, &pid))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         idx = config->ctxid_idx;
>         config->ctxid_pid[idx] = (u64)pid;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(ctxid_pid);
> @@ -1967,10 +1967,10 @@ static ssize_t ctxid_masks_show(struct device *dev,
>         if (task_active_pid_ns(current) != &init_pid_ns)
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         val1 = config->ctxid_mask0;
>         val2 = config->ctxid_mask1;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
>  }
>
> @@ -2003,7 +2003,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
>         if ((drvdata->numcidc > 4) && (nr_inputs != 2))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         /*
>          * each byte[0..3] controls mask value applied to ctxid
>          * comparator[0..3]
> @@ -2075,7 +2075,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
>                         mask >>= 0x8;
>         }
>
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(ctxid_masks);
> @@ -2109,9 +2109,9 @@ static ssize_t vmid_idx_store(struct device *dev,
>          * Use spinlock to ensure index doesn't change while it gets
>          * dereferenced multiple times within a spinlock block elsewhere.
>          */
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->vmid_idx = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(vmid_idx);
> @@ -2131,9 +2131,9 @@ static ssize_t vmid_val_show(struct device *dev,
>         if (!task_is_in_init_pid_ns(current))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         val = (unsigned long)config->vmid_val[config->vmid_idx];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>
> @@ -2161,9 +2161,9 @@ static ssize_t vmid_val_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->vmid_val[config->vmid_idx] = (u64)val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(vmid_val);
> @@ -2182,10 +2182,10 @@ static ssize_t vmid_masks_show(struct device *dev,
>         if (!task_is_in_init_pid_ns(current))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         val1 = config->vmid_mask0;
>         val2 = config->vmid_mask1;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
>  }
>
> @@ -2217,7 +2217,7 @@ static ssize_t vmid_masks_store(struct device *dev,
>         if ((drvdata->numvmidc > 4) && (nr_inputs != 2))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>
>         /*
>          * each byte[0..3] controls mask value applied to vmid
> @@ -2290,7 +2290,7 @@ static ssize_t vmid_masks_store(struct device *dev,
>                 else
>                         mask >>= 0x8;
>         }
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(vmid_masks);
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index 9e9165f62e81..366f8f23a3e5 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -989,7 +989,7 @@ struct etmv4_drvdata {
>         struct clk                      *pclk;
>         void __iomem                    *base;
>         struct coresight_device         *csdev;
> -       spinlock_t                      spinlock;
> +       raw_spinlock_t                  spinlock;
>         int                             cpu;
>         u8                              arch;
>         u8                              nr_pe;
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>

with the above change:

Reviewed-by: Mike Leach <mike.leach at linaro.org>


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Thu Dec 19 04:24:08 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:24:08 +0000
Subject: [PATCH v3 3/9] coresight: change coresight_trace_id_map's lock
 type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-4-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com> <20241216115006.415861-4-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7VhBkrggH9y1jqZZoXfhqiqKTkqU+U0aEm=659kpNUMj7Q@mail.gmail.com>

On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> coresight_trace_id_map->lock can be acquired while coresight devices'
> drvdata_lock.
>
> But the drvdata_lock can be raw_spinlock_t (i.e) coresight-etm4x.
>
> To address this, change type of coresight_trace_id_map->lock to
> raw_spinlock_t
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-core.c  |  2 +-
>  .../hwtracing/coresight/coresight-trace-id.c  | 22 +++++++++----------
>  include/linux/coresight.h                     |  2 +-
>  3 files changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index ea38ecf26fcb..cc2d87b2f248 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -1164,7 +1164,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
>
>         if (csdev->type == CORESIGHT_DEV_TYPE_SINK ||
>             csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) {
> -               spin_lock_init(&csdev->perf_sink_id_map.lock);
> +               raw_spin_lock_init(&csdev->perf_sink_id_map.lock);
>                 csdev->perf_sink_id_map.cpu_map = alloc_percpu(atomic_t);
>                 if (!csdev->perf_sink_id_map.cpu_map) {
>                         kfree(csdev);
> diff --git a/drivers/hwtracing/coresight/coresight-trace-id.c b/drivers/hwtracing/coresight/coresight-trace-id.c
> index d98e12cb30ec..a6531869e9ec 100644
> --- a/drivers/hwtracing/coresight/coresight-trace-id.c
> +++ b/drivers/hwtracing/coresight/coresight-trace-id.c
> @@ -16,7 +16,7 @@
>  static DEFINE_PER_CPU(atomic_t, id_map_default_cpu_ids) = ATOMIC_INIT(0);
>  static struct coresight_trace_id_map id_map_default = {
>         .cpu_map = &id_map_default_cpu_ids,
> -       .lock = __SPIN_LOCK_UNLOCKED(id_map_default.lock)
> +       .lock = __RAW_SPIN_LOCK_UNLOCKED(id_map_default.lock)
>  };
>
>  /* #define TRACE_ID_DEBUG 1 */
> @@ -121,11 +121,11 @@ static void coresight_trace_id_release_all(struct coresight_trace_id_map *id_map
>         unsigned long flags;
>         int cpu;
>
> -       spin_lock_irqsave(&id_map->lock, flags);
> +       raw_spin_lock_irqsave(&id_map->lock, flags);
>         bitmap_zero(id_map->used_ids, CORESIGHT_TRACE_IDS_MAX);
>         for_each_possible_cpu(cpu)
>                 atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), 0);
> -       spin_unlock_irqrestore(&id_map->lock, flags);
> +       raw_spin_unlock_irqrestore(&id_map->lock, flags);
>         DUMP_ID_MAP(id_map);
>  }
>
> @@ -134,7 +134,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map
>         unsigned long flags;
>         int id;
>
> -       spin_lock_irqsave(&id_map->lock, flags);
> +       raw_spin_lock_irqsave(&id_map->lock, flags);
>
>         /* check for existing allocation for this CPU */
>         id = _coresight_trace_id_read_cpu_id(cpu, id_map);
> @@ -161,7 +161,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map
>         atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), id);
>
>  get_cpu_id_out_unlock:
> -       spin_unlock_irqrestore(&id_map->lock, flags);
> +       raw_spin_unlock_irqrestore(&id_map->lock, flags);
>
>         DUMP_ID_CPU(cpu, id);
>         DUMP_ID_MAP(id_map);
> @@ -178,12 +178,12 @@ static void _coresight_trace_id_put_cpu_id(int cpu, struct coresight_trace_id_ma
>         if (!id)
>                 return;
>
> -       spin_lock_irqsave(&id_map->lock, flags);
> +       raw_spin_lock_irqsave(&id_map->lock, flags);
>
>         coresight_trace_id_free(id, id_map);
>         atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), 0);
>
> -       spin_unlock_irqrestore(&id_map->lock, flags);
> +       raw_spin_unlock_irqrestore(&id_map->lock, flags);
>         DUMP_ID_CPU(cpu, id);
>         DUMP_ID_MAP(id_map);
>  }
> @@ -193,10 +193,10 @@ static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *i
>         unsigned long flags;
>         int id;
>
> -       spin_lock_irqsave(&id_map->lock, flags);
> +       raw_spin_lock_irqsave(&id_map->lock, flags);
>         /* prefer odd IDs for system components to avoid legacy CPU IDS */
>         id = coresight_trace_id_alloc_new_id(id_map, 0, true);
> -       spin_unlock_irqrestore(&id_map->lock, flags);
> +       raw_spin_unlock_irqrestore(&id_map->lock, flags);
>
>         DUMP_ID(id);
>         DUMP_ID_MAP(id_map);
> @@ -207,9 +207,9 @@ static void coresight_trace_id_map_put_system_id(struct coresight_trace_id_map *
>  {
>         unsigned long flags;
>
> -       spin_lock_irqsave(&id_map->lock, flags);
> +       raw_spin_lock_irqsave(&id_map->lock, flags);
>         coresight_trace_id_free(id, id_map);
> -       spin_unlock_irqrestore(&id_map->lock, flags);
> +       raw_spin_unlock_irqrestore(&id_map->lock, flags);
>
>         DUMP_ID(id);
>         DUMP_ID_MAP(id_map);
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 924b58c343b3..6446ca1f09d8 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -233,7 +233,7 @@ struct coresight_trace_id_map {
>         DECLARE_BITMAP(used_ids, CORESIGHT_TRACE_IDS_MAX);
>         atomic_t __percpu *cpu_map;
>         atomic_t perf_cs_etm_session_active;
> -       spinlock_t lock;
> +       raw_spinlock_t lock;
>  };
>
>  /**
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Thu Dec 19 04:24:13 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:24:13 +0000
Subject: [PATCH v3 4/9] coresight-cti: change cti_drvdata spinlock's type
 to raw_spinlock_t
In-Reply-To: <20241216115006.415861-5-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com> <20241216115006.415861-5-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7VgUMLR9cnY-QUqUcJj6ECfqxN0dD9QUqM8jmHj7t=Pd4g@mail.gmail.com>

On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In coresight-cti drivers, cti_drvdata->spinlock can be held during __schedule()
> by perf_event_task_sched_out()/in().
>
> Since cti_drvdata->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this, change type cti_drvdata->spinlock in coresight-cti drivers,
> which can be called by perf_event_task_sched_out()/in(),
> from spinlock_t to raw_spinlock_t.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  .../hwtracing/coresight/coresight-cti-core.c  | 44 +++++------
>  .../hwtracing/coresight/coresight-cti-sysfs.c | 76 +++++++++----------
>  drivers/hwtracing/coresight/coresight-cti.h   |  2 +-
>  3 files changed, 61 insertions(+), 61 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
> index d2b5a5718c29..80f6265e3740 100644
> --- a/drivers/hwtracing/coresight/coresight-cti-core.c
> +++ b/drivers/hwtracing/coresight/coresight-cti-core.c
> @@ -93,7 +93,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
>         unsigned long flags;
>         int rc = 0;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         /* no need to do anything if enabled or unpowered*/
>         if (config->hw_enabled || !config->hw_powered)
> @@ -108,7 +108,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
>
>         config->hw_enabled = true;
>         drvdata->config.enable_req_count++;
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>         return rc;
>
>  cti_state_unchanged:
> @@ -116,7 +116,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
>
>         /* cannot enable due to error */
>  cti_err_not_enabled:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>         return rc;
>  }
>
> @@ -125,7 +125,7 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata)
>  {
>         struct cti_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         config->hw_powered = true;
>
>         /* no need to do anything if no enable request */
> @@ -138,12 +138,12 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata)
>
>         cti_write_all_hw_regs(drvdata);
>         config->hw_enabled = true;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return;
>
>         /* did not re-enable due to no claim / no request */
>  cti_hp_not_enabled:
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>  }
>
>  /* disable hardware */
> @@ -153,7 +153,7 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
>         struct coresight_device *csdev = drvdata->csdev;
>         int ret = 0;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>
>         /* don't allow negative refcounts, return an error */
>         if (!drvdata->config.enable_req_count) {
> @@ -177,12 +177,12 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
>
>         coresight_disclaim_device_unlocked(csdev);
>         CS_LOCK(drvdata->base);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return ret;
>
>         /* not disabled this call */
>  cti_not_disabled:
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return ret;
>  }
>
> @@ -198,11 +198,11 @@ void cti_write_intack(struct device *dev, u32 ackval)
>         struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct cti_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         /* write if enabled */
>         if (cti_active(config))
>                 cti_write_single_reg(drvdata, CTIINTACK, ackval);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>  }
>
>  /*
> @@ -369,7 +369,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
>         reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) :
>                       CTIOUTEN(trigger_idx));
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>
>         /* read - modify write - the trigger / channel enable value */
>         reg_value = direction == CTI_TRIG_IN ? config->ctiinen[trigger_idx] :
> @@ -388,7 +388,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
>         /* write through if enabled */
>         if (cti_active(config))
>                 cti_write_single_reg(drvdata, reg_offset, reg_value);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return 0;
>  }
>
> @@ -406,7 +406,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
>
>         chan_bitmask = BIT(channel_idx);
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         reg_value = config->ctigate;
>         switch (op) {
>         case CTI_GATE_CHAN_ENABLE:
> @@ -426,7 +426,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
>                 if (cti_active(config))
>                         cti_write_single_reg(drvdata, CTIGATE, reg_value);
>         }
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return err;
>  }
>
> @@ -445,7 +445,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
>
>         chan_bitmask = BIT(channel_idx);
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         reg_value = config->ctiappset;
>         switch (op) {
>         case CTI_CHAN_SET:
> @@ -473,7 +473,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
>
>         if ((err == 0) && cti_active(config))
>                 cti_write_single_reg(drvdata, reg_offset, reg_value);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>
>         return err;
>  }
> @@ -676,7 +676,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
>         if (WARN_ON_ONCE(drvdata->ctidev.cpu != cpu))
>                 return NOTIFY_BAD;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>
>         switch (cmd) {
>         case CPU_PM_ENTER:
> @@ -716,7 +716,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
>         }
>
>  cti_notify_exit:
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return notify_res;
>  }
>
> @@ -743,11 +743,11 @@ static int cti_dying_cpu(unsigned int cpu)
>         if (!drvdata)
>                 return 0;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         drvdata->config.hw_powered = false;
>         if (drvdata->config.hw_enabled)
>                 coresight_disclaim_device(drvdata->csdev);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return 0;
>  }
>
> @@ -888,7 +888,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
>         drvdata->ctidev.ctm_id = 0;
>         INIT_LIST_HEAD(&drvdata->ctidev.trig_cons);
>
> -       spin_lock_init(&drvdata->spinlock);
> +       raw_spin_lock_init(&drvdata->spinlock);
>
>         /* initialise CTI driver config values */
>         cti_set_default_config(dev, drvdata);
> diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
> index d25dd2737b49..572b80ee96fb 100644
> --- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
> @@ -84,11 +84,11 @@ static ssize_t enable_show(struct device *dev,
>         bool enabled, powered;
>         struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         enable_req = drvdata->config.enable_req_count;
>         powered = drvdata->config.hw_powered;
>         enabled = drvdata->config.hw_enabled;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>
>         if (powered)
>                 return sprintf(buf, "%d\n", enabled);
> @@ -134,9 +134,9 @@ static ssize_t powered_show(struct device *dev,
>         bool powered;
>         struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         powered = drvdata->config.hw_powered;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>
>         return sprintf(buf, "%d\n", powered);
>  }
> @@ -181,10 +181,10 @@ static ssize_t coresight_cti_reg_show(struct device *dev,
>         u32 val = 0;
>
>         pm_runtime_get_sync(dev->parent);
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         if (drvdata->config.hw_powered)
>                 val = readl_relaxed(drvdata->base + cti_attr->off);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         pm_runtime_put_sync(dev->parent);
>         return sysfs_emit(buf, "0x%x\n", val);
>  }
> @@ -202,10 +202,10 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev,
>                 return -EINVAL;
>
>         pm_runtime_get_sync(dev->parent);
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         if (drvdata->config.hw_powered)
>                 cti_write_single_reg(drvdata, cti_attr->off, val);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         pm_runtime_put_sync(dev->parent);
>         return size;
>  }
> @@ -264,7 +264,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf,
>         struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct cti_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         if ((reg_offset >= 0) && cti_active(config)) {
>                 CS_UNLOCK(drvdata->base);
>                 val = readl_relaxed(drvdata->base + reg_offset);
> @@ -274,7 +274,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf,
>         } else if (pcached_val) {
>                 val = *pcached_val;
>         }
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return sprintf(buf, "%#x\n", val);
>  }
>
> @@ -293,7 +293,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf,
>         if (kstrtoul(buf, 0, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         /* local store */
>         if (pcached_val)
>                 *pcached_val = (u32)val;
> @@ -301,7 +301,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf,
>         /* write through if offset and enabled */
>         if ((reg_offset >= 0) && cti_active(config))
>                 cti_write_single_reg(drvdata, reg_offset, val);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>
> @@ -349,9 +349,9 @@ static ssize_t inout_sel_store(struct device *dev,
>         if (val > (CTIINOUTEN_MAX - 1))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         drvdata->config.ctiinout_sel = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(inout_sel);
> @@ -364,10 +364,10 @@ static ssize_t inen_show(struct device *dev,
>         int index;
>         struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         index = drvdata->config.ctiinout_sel;
>         val = drvdata->config.ctiinen[index];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return sprintf(buf, "%#lx\n", val);
>  }
>
> @@ -383,14 +383,14 @@ static ssize_t inen_store(struct device *dev,
>         if (kstrtoul(buf, 0, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         index = config->ctiinout_sel;
>         config->ctiinen[index] = val;
>
>         /* write through if enabled */
>         if (cti_active(config))
>                 cti_write_single_reg(drvdata, CTIINEN(index), val);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(inen);
> @@ -403,10 +403,10 @@ static ssize_t outen_show(struct device *dev,
>         int index;
>         struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         index = drvdata->config.ctiinout_sel;
>         val = drvdata->config.ctiouten[index];
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return sprintf(buf, "%#lx\n", val);
>  }
>
> @@ -422,14 +422,14 @@ static ssize_t outen_store(struct device *dev,
>         if (kstrtoul(buf, 0, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         index = config->ctiinout_sel;
>         config->ctiouten[index] = val;
>
>         /* write through if enabled */
>         if (cti_active(config))
>                 cti_write_single_reg(drvdata, CTIOUTEN(index), val);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(outen);
> @@ -463,7 +463,7 @@ static ssize_t appclear_store(struct device *dev,
>         if (kstrtoul(buf, 0, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>
>         /* a 1'b1 in appclr clears down the same bit in appset*/
>         config->ctiappset &= ~val;
> @@ -471,7 +471,7 @@ static ssize_t appclear_store(struct device *dev,
>         /* write through if enabled */
>         if (cti_active(config))
>                 cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_WO(appclear);
> @@ -487,12 +487,12 @@ static ssize_t apppulse_store(struct device *dev,
>         if (kstrtoul(buf, 0, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>
>         /* write through if enabled */
>         if (cti_active(config))
>                 cti_write_single_reg(drvdata, CTIAPPPULSE, val);
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_WO(apppulse);
> @@ -681,9 +681,9 @@ static ssize_t trig_filter_enable_show(struct device *dev,
>         u32 val;
>         struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         val = drvdata->config.trig_filter_enable;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return sprintf(buf, "%d\n", val);
>  }
>
> @@ -697,9 +697,9 @@ static ssize_t trig_filter_enable_store(struct device *dev,
>         if (kstrtoul(buf, 0, &val))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         drvdata->config.trig_filter_enable = !!val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_RW(trig_filter_enable);
> @@ -728,7 +728,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev,
>         struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
>         struct cti_config *config = &drvdata->config;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>
>         /* clear the CTI trigger / channel programming registers */
>         for (i = 0; i < config->nr_trig_max; i++) {
> @@ -747,7 +747,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev,
>         if (cti_active(config))
>                 cti_write_all_hw_regs(drvdata);
>
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>  static DEVICE_ATTR_WO(chan_xtrigs_reset);
> @@ -768,9 +768,9 @@ static ssize_t chan_xtrigs_sel_store(struct device *dev,
>         if (val > (drvdata->config.nr_ctm_channels - 1))
>                 return -EINVAL;
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         drvdata->config.xtrig_rchan_sel = val;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>         return size;
>  }
>
> @@ -781,9 +781,9 @@ static ssize_t chan_xtrigs_sel_show(struct device *dev,
>         unsigned long val;
>         struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
>
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         val = drvdata->config.xtrig_rchan_sel;
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>
>         return sprintf(buf, "%ld\n", val);
>  }
> @@ -838,12 +838,12 @@ static ssize_t print_chan_list(struct device *dev,
>         unsigned long inuse_bits = 0, chan_mask;
>
>         /* scan regs to get bitmap of channels in use. */
> -       spin_lock(&drvdata->spinlock);
> +       raw_spin_lock(&drvdata->spinlock);
>         for (i = 0; i < config->nr_trig_max; i++) {
>                 inuse_bits |= config->ctiinen[i];
>                 inuse_bits |= config->ctiouten[i];
>         }
> -       spin_unlock(&drvdata->spinlock);
> +       raw_spin_unlock(&drvdata->spinlock);
>
>         /* inverse bits if printing free channels */
>         if (!inuse)
> diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h
> index cb9ee616d01f..16e310e7e9d4 100644
> --- a/drivers/hwtracing/coresight/coresight-cti.h
> +++ b/drivers/hwtracing/coresight/coresight-cti.h
> @@ -175,7 +175,7 @@ struct cti_drvdata {
>         void __iomem *base;
>         struct coresight_device *csdev;
>         struct cti_device ctidev;
> -       spinlock_t spinlock;
> +       raw_spinlock_t spinlock;
>         struct cti_config config;
>         struct list_head node;
>         void (*csdev_release)(struct device *dev);
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Thu Dec 19 04:24:18 2024
From: mike.leach at linaro.org (Mike Leach)
Date: Thu, 19 Dec 2024 12:24:18 +0000
Subject: [PATCH v3 5/9] coresight-etb10: change etb_drvdata spinlock's
 type to raw_spinlock_t
In-Reply-To: <20241216115006.415861-6-yeoreum.yun@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com> <20241216115006.415861-6-yeoreum.yun@arm.com>
Message-ID: <CAJ9a7Vhzoynt69+O1zya8LM3dOPhar9YxQXqHygbeKQC8CfHtg@mail.gmail.com>

On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
>
> In coresight-etb10 drivers, etb_drvdata->spinlock can be held
> during __schedule() by perf_event_task_sched_out()/in().
>
> Since etb_drvdata->spinlock type is spinlock_t and
> perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> which is raw_spinlock_t (an unsleepable lock),
> this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
>
> To address this, change type etb_drvdata->spinlock in coresight-etb10 drivers,
> which can be called by perf_event_task_sched_out()/in(),
> from spinlock_t to raw_spinlock_t.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-etb10.c | 26 +++++++++----------
>  1 file changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
> index aea9ac9c4bd0..7948597d483d 100644
> --- a/drivers/hwtracing/coresight/coresight-etb10.c
> +++ b/drivers/hwtracing/coresight/coresight-etb10.c
> @@ -84,7 +84,7 @@ struct etb_drvdata {
>         struct clk              *atclk;
>         struct coresight_device *csdev;
>         struct miscdevice       miscdev;
> -       spinlock_t              spinlock;
> +       raw_spinlock_t          spinlock;
>         local_t                 reading;
>         pid_t                   pid;
>         u8                      *buf;
> @@ -145,7 +145,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
>         unsigned long flags;
>         struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         /* Don't messup with perf sessions. */
>         if (coresight_get_mode(csdev) == CS_MODE_PERF) {
> @@ -163,7 +163,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
>
>         csdev->refcnt++;
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>         return ret;
>  }
>
> @@ -176,7 +176,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
>         struct perf_output_handle *handle = data;
>         struct cs_buffers *buf = etm_perf_sink_config(handle);
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         /* No need to continue if the component is already in used by sysFS. */
>         if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
> @@ -219,7 +219,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
>         }
>
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>         return ret;
>  }
>
> @@ -352,11 +352,11 @@ static int etb_disable(struct coresight_device *csdev)
>         struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>         unsigned long flags;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         csdev->refcnt--;
>         if (csdev->refcnt) {
> -               spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +               raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>                 return -EBUSY;
>         }
>
> @@ -366,7 +366,7 @@ static int etb_disable(struct coresight_device *csdev)
>         /* Dissociate from monitored process. */
>         drvdata->pid = -1;
>         coresight_set_mode(csdev, CS_MODE_DISABLED);
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         dev_dbg(&csdev->dev, "ETB disabled\n");
>         return 0;
> @@ -443,7 +443,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
>
>         capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>
>         /* Don't do anything if another tracer is using this sink */
>         if (csdev->refcnt != 1)
> @@ -566,7 +566,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
>         __etb_enable_hw(drvdata);
>         CS_LOCK(drvdata->base);
>  out:
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         return to_read;
>  }
> @@ -587,13 +587,13 @@ static void etb_dump(struct etb_drvdata *drvdata)
>  {
>         unsigned long flags;
>
> -       spin_lock_irqsave(&drvdata->spinlock, flags);
> +       raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>         if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
>                 __etb_disable_hw(drvdata);
>                 etb_dump_hw(drvdata);
>                 __etb_enable_hw(drvdata);
>         }
> -       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +       raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>
>         dev_dbg(&drvdata->csdev->dev, "ETB dumped\n");
>  }
> @@ -746,7 +746,7 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
>         drvdata->base = base;
>         desc.access = CSDEV_ACCESS_IOMEM(base);
>
> -       spin_lock_init(&drvdata->spinlock);
> +       raw_spin_lock_init(&drvdata->spinlock);
>
>         drvdata->buffer_depth = etb_get_buffer_depth(drvdata);
>
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From angelogioacchino.delregno at collabora.com  Thu Dec 19 04:39:30 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 13:39:30 +0100
Subject: [PATCH] v1 pinctrl: mtk-eint: add eint new design for mt8196
In-Reply-To: <CACRpkdZy7HgkT-FFJh=ubXhdcBRa-vbaNmHC32E3djZdHnwdYg@mail.gmail.com>
References: <20241203131302.16022-1-ot_chhao.chang@mediatek.com>
 <CACRpkdZy7HgkT-FFJh=ubXhdcBRa-vbaNmHC32E3djZdHnwdYg@mail.gmail.com>
Message-ID: <47ca3129-245f-481f-9ca1-ed9d8db6e990@collabora.com>

Il 17/12/24 14:45, Linus Walleij ha scritto:
> Hi Chang,
> 
> thanks for your patch!
> 
> On Tue, Dec 3, 2024 at 2:13?PM chang hao <ot_chhao.chang at mediatek.com> wrote:
> 
>> From: Chhao Chang <ot_chhao.chang at mediatek.com>
>>
>> Change 1: change EINT from 1 address to 5 addresses,
>> Eint number is stored on each base.
>> Change 2: Compatible with 1 address design
>>
>> Signed-off-by: Chhao Chang <ot_chhao.chang at mediatek.com>
> 
> This patch looks good to me, as preparation for mt8196,
> but can one of the Mediatek experts please
> review it? If nothing happens I will just apply it I guess...
> 

Linus, that's something like the fourth time that he pushes variations of this
patch which do break all MediaTek SoCs in a way or another, leaving only MT8196
hopefully-functional.

NACK.

Cheers,
Angelo




From angelogioacchino.delregno at collabora.com  Thu Dec 19 04:41:56 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 19 Dec 2024 13:41:56 +0100
Subject: [PATCH v7 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241219123441.GA4016373-robh@kernel.org>
References: <20241217085435.9586-1-linux@fw-web.de>
 <20241217085435.9586-4-linux@fw-web.de>
 <4ecfcdd3-3c81-4625-90cd-1d45f6d71a2f@collabora.com>
 <20241219123441.GA4016373-robh@kernel.org>
Message-ID: <e9fb2634-5b47-4f68-ad7c-26a4f52d0df8@collabora.com>

Il 19/12/24 13:34, Rob Herring ha scritto:
> On Thu, Dec 19, 2024 at 12:56:23PM +0100, AngeloGioacchino Del Regno wrote:
>> Il 17/12/24 09:54, Frank Wunderlich ha scritto:
>>> From: Frank Wunderlich <frank-w at public-files.de>
>>>
>>> This adds bindings for MT7988 pinctrl driver.
>>>
>>> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
>>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>
>> DT binding maintainers, can you please review this patch and eventually release
>> an Ack so that I can take it through the MediaTek tree along with the devicetree
>> changes?
> 
> It's been 2 days... If you want to know the status and where you are in
> the queue, you can check patchwork[1]. But guess what, you're #1.
> 
> Rob
> 
> [1] https://patchwork.ozlabs.org/project/devicetree-bindings/list/


Rob, I was checking the patches to apply to the MTK trees and while in the
process I didn't notice that this one was sent that early.

Sending a ping after a short time wasn't intentional. Sorry for that.

Cheers,
Angelo




From robin.murphy at arm.com  Thu Dec 19 04:48:27 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 19 Dec 2024 12:48:27 +0000
Subject: [RFC PATCH v2 55/58] drivers/iommu: Add deferred map_sg
 operations
In-Reply-To: <20241212180423.1578358-56-smostafa@google.com>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-56-smostafa@google.com>
Message-ID: <ce4c8db4-4895-426b-8d9d-97dc5d74fbc4@arm.com>

On 2024-12-12 6:04 pm, Mostafa Saleh wrote:
> With pKVM SMMUv3 driver which para-virtualizes the IOMMU in the
> hypervisor, has an extra overhead with map_sg, as it loops over
> iommu_map, and for each map requires context switching, disabling
> interrupts...
> 
> Instead, add an new domain operations:
> - alloc_cookie_sg: Allocate a new sg deferred cookie
> - add_deferred_map_sg: Add a mapping to the cookie
> - consume_deferred_map_sg: Consume and release the cookie
> 
> Alternativly, we can pass the sg list as is. However, this would
> duplicate some of the logic and it would make more sense to
> conolidate all the sg list parsing for IOMMU drivers in one place.

But why bother with fiddly overly-specific machinery at all when you can 
already make ->map_pages asynchronous and consolidate the expensive part 
into ->iotlb_sync_map in general, like s390 does?

Thanks,
Robin.

> virtio-iommu is another IOMMU that can benfit from this, but it
> would need to have a new operation that standerdize passing
> an sglist based on these ops.
> 
> Signed-off-by: Mostafa Saleh <smostafa at google.com>
> ---
>   drivers/iommu/iommu.c | 53 +++++++++++++++++++++++++++++++++++++++++--
>   include/linux/iommu.h | 19 ++++++++++++++++
>   2 files changed, 70 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 83c8e617a2c5..3a3c48631dd6 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -2608,6 +2608,37 @@ size_t iommu_unmap_fast(struct iommu_domain *domain,
>   }
>   EXPORT_SYMBOL_GPL(iommu_unmap_fast);
>   
> +static int __iommu_add_sg(struct iommu_map_cookie_sg *cookie_sg,
> +			  unsigned long iova, phys_addr_t paddr, size_t size)
> +{
> +	struct iommu_domain *domain = cookie_sg->domain;
> +	const struct iommu_domain_ops *ops = domain->ops;
> +	unsigned int min_pagesz;
> +	size_t pgsize, count;
> +
> +	if (unlikely(!(domain->type & __IOMMU_DOMAIN_PAGING)))
> +		return -EINVAL;
> +
> +	if (WARN_ON(domain->pgsize_bitmap == 0UL))
> +		return -ENODEV;
> +
> +	/* find out the minimum page size supported */
> +	min_pagesz = 1 << __ffs(domain->pgsize_bitmap);
> +
> +	/*
> +	 * both the virtual address and the physical one, as well as
> +	 * the size of the mapping, must be aligned (at least) to the
> +	 * size of the smallest page supported by the hardware
> +	 */
> +	if (!IS_ALIGNED(iova | paddr | size, min_pagesz)) {
> +		pr_err("unaligned: iova 0x%lx pa %pa size 0x%zx min_pagesz 0x%x\n",
> +		       iova, &paddr, size, min_pagesz);
> +		return -EINVAL;
> +	}
> +	pgsize = iommu_pgsize(domain, iova, paddr, size, &count);
> +	return ops->add_deferred_map_sg(cookie_sg, paddr, pgsize, count);
> +}
> +
>   ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
>   		     struct scatterlist *sg, unsigned int nents, int prot,
>   		     gfp_t gfp)
> @@ -2617,6 +2648,9 @@ ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
>   	phys_addr_t start;
>   	unsigned int i = 0;
>   	int ret;
> +	bool deferred_sg = ops->alloc_cookie_sg && ops->add_deferred_map_sg &&
> +			   ops->consume_deferred_map_sg;
> +	struct iommu_map_cookie_sg *cookie_sg;
>   
>   	might_sleep_if(gfpflags_allow_blocking(gfp));
>   
> @@ -2625,12 +2659,24 @@ ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
>   				__GFP_HIGHMEM)))
>   		return -EINVAL;
>   
> +	if (deferred_sg) {
> +		cookie_sg = ops->alloc_cookie_sg(iova, prot, nents, gfp);
> +		if (!cookie_sg) {
> +			pr_err("iommu: failed alloc cookie\n");
> +			return -ENOMEM;
> +		}
> +		cookie_sg->domain = domain;
> +	}
> +
>   	while (i <= nents) {
>   		phys_addr_t s_phys = sg_phys(sg);
>   
>   		if (len && s_phys != start + len) {
> -			ret = __iommu_map(domain, iova + mapped, start,
> -					len, prot, gfp);
> +			if (deferred_sg)
> +				ret = __iommu_add_sg(cookie_sg, iova + mapped, start, len);
> +			else
> +				ret = __iommu_map(domain, iova + mapped, start,
> +						  len, prot, gfp);
>   
>   			if (ret)
>   				goto out_err;
> @@ -2654,6 +2700,9 @@ ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
>   			sg = sg_next(sg);
>   	}
>   
> +	if (deferred_sg)
> +		ops->consume_deferred_map_sg(cookie_sg);
> +
>   	if (ops->iotlb_sync_map) {
>   		ret = ops->iotlb_sync_map(domain, iova, mapped);
>   		if (ret)
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index c75877044185..5e60ac349228 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -601,6 +601,14 @@ struct iommu_ops {
>   	u8 user_pasid_table:1;
>   };
>   
> +/**
> + * struct iommu_map_cookie_sg - Cookie for a deferred map sg
> + * @domain: Domain for the sg lit
> + */
> +struct iommu_map_cookie_sg {
> +	struct iommu_domain *domain;
> +};
> +
>   /**
>    * struct iommu_domain_ops - domain specific operations
>    * @attach_dev: attach an iommu domain to a device
> @@ -638,6 +646,11 @@ struct iommu_ops {
>    * @enable_nesting: Enable nesting
>    * @set_pgtable_quirks: Set io page table quirks (IO_PGTABLE_QUIRK_*)
>    * @free: Release the domain after use.
> + * @alloc_cookie_sg: Allocate a cookie that would be used to create
> + *		     a sg list, filled from the next functions
> + * @add_deferred_map_sg: Add a mapping to a cookie of a sg list.
> + * @consume_deferred_map_sg: Consume the sg list as now all mappings are added,
> + *			     it should also release the cookie as it's not used.
>    */
>   struct iommu_domain_ops {
>   	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
> @@ -668,6 +681,12 @@ struct iommu_domain_ops {
>   				  unsigned long quirks);
>   
>   	void (*free)(struct iommu_domain *domain);
> +
> +	struct iommu_map_cookie_sg *(*alloc_cookie_sg)(unsigned long iova, int prot,
> +						       unsigned int nents, gfp_t gfp);
> +	int (*add_deferred_map_sg)(struct iommu_map_cookie_sg *cookie,
> +				   phys_addr_t paddr, size_t pgsize, size_t pgcount);
> +	int (*consume_deferred_map_sg)(struct iommu_map_cookie_sg *cookie);
>   };
>   
>   /**



From pbonzini at redhat.com  Thu Dec 19 04:51:39 2024
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Thu, 19 Dec 2024 13:51:39 +0100
Subject: [PATCH v4 00/16] KVM: selftests: "tree" wide overhauls
In-Reply-To: <Z2N-UlxgYlGT_1Or@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
 <173455833964.3185228.5614329030867008316.b4-ty@google.com>
 <Z2NIwmRDaZBc_V4o@google.com> <Z2N-UlxgYlGT_1Or@google.com>
Message-ID: <6887b48c-b1ef-418b-90e7-fa95fedc71f2@redhat.com>

On 12/19/24 03:00, Sean Christopherson wrote:
> On Wed, Dec 18, 2024, Sean Christopherson wrote:
>> On Wed, Dec 18, 2024, Sean Christopherson wrote:
>>> On Wed, 27 Nov 2024 16:55:31 -0800, Sean Christopherson wrote:
>>>> Two separate series (mmu_stress_test[1] and $ARCH[2]), posted as one to
>>>> avoid unpleasant conflicts, and because I hope to land both in kvm/next
>>>> shortly after 6.12-rc1 since they impact all of KVM selftests.
>>>>
>>>> mmu_stress_test
>>>> ---------------
>>>> Convert the max_guest_memory_test into a more generic mmu_stress_test.
>>>> The basic gist of the "conversion" is to have the test do mprotect() on
>>>> guest memory while vCPUs are accessing said memory, e.g. to verify KVM
>>>> and mmu_notifiers are working as intended.
>>>>
>>>> [...]
>>>
>>> As I am running out of time before I disappear for two weeks, applied to:
>>>
>>>     https://github.com/kvm-x86/linux.git selftests_arch
>>>
>>> Other KVM maintainers, that branch is officially immutable.  I also pushed a tag,
>>> kvm-selftests-arch-6.14, just in case I pull a stupid and manage to clobber the
>>> branch.  My apologies if this causes pain.  AFAICT, there aren't any queued or
>>> in-flight patches that git's rename magic can't automatically handle, so hopefully
>>> this ends up being pain-free.
>>>
>>> Paolo, here's a pull request if you want to pull this into kvm/next long before
>>> the 6.14 merge window.  Diff stats at the very bottom (hilariously long).
Pulled, thanks.

Paolo



From robh at kernel.org  Thu Dec 19 04:53:09 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 19 Dec 2024 06:53:09 -0600
Subject: [PATCH v7 3/5] dt-bindings: pinctrl: add binding for MT7988 SoC
In-Reply-To: <20241217085435.9586-4-linux@fw-web.de>
References: <20241217085435.9586-1-linux@fw-web.de>
 <20241217085435.9586-4-linux@fw-web.de>
Message-ID: <173461170218.4026495.15441109866406999660.robh@kernel.org>


On Tue, 17 Dec 2024 09:54:28 +0100, Frank Wunderlich wrote:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> This adds bindings for MT7988 pinctrl driver.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
> changes in v6:
> changes suggested by rob
> - remove quotes around mux
> - use const instead of enum if only one value is possible
> 
> changes in v5 (so not adding RB from Rob given in v4):
> - do not use MTK_DRIVE_8mA in example
> - add _0 functions for pwm
> 
> changes in v4:
> - dt-binding: pinctrl: fix dt_binding_check fixed-string error
> 
> '^mux$' should not be valid under {'pattern': '^\\^[a-zA-Z0-9,\\-._#@]+\\$$'}
> 	hint: Fixed strings belong in 'properties', not 'patternProperties'
> 
> changes in v3:
> - limit conf subnode name with optional suffix like mmc on mt7986
> - match mux subnode without wildcards
> 
> changes in v2:
> - drop gpio-cells description
> - move ref in mux subnode up
> - order uart-functions alphanumeric and fix typo
> ---
>  .../pinctrl/mediatek,mt7988-pinctrl.yaml      | 575 ++++++++++++++++++
>  1 file changed, 575 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7988-pinctrl.yaml
> 

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>



From ciprianmarian.costea at oss.nxp.com  Thu Dec 19 05:10:27 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Thu, 19 Dec 2024 15:10:27 +0200
Subject: [PATCH v3 2/4] arm64: dts: s32g: add common 'S32G-EVB' and 'S32G-RDB' board support
In-Reply-To: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
References: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241219131029.1139720-3-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
(rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
are quite similar. The common part for the EVB revisions will be
centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
be placed in 's32gxxa-rdb.dtsi' file.

This refactor will also serve for other modules in the future, such as
FlexCAN, DSPI.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
 .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 126 +++++++++++++++
 2 files changed, 276 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi

diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
new file mode 100644
index 000000000000..a44eff28073a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2024 NXP
+ *
+ * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
+ *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
+ *          Larisa Grigore <larisa.grigore at nxp.com>
+ */
+
+&pinctrl {
+	i2c0_pins: i2c0-pins {
+		i2c0-grp0 {
+			pinmux = <0x101>, <0x111>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-grp1 {
+			pinmux = <0x2352>, <0x2362>;
+		};
+	};
+
+	i2c0_gpio_pins: i2c0-gpio-pins {
+		i2c0-gpio-grp0 {
+			pinmux = <0x100>, <0x110>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-gpio-grp1 {
+			pinmux = <0x2350>, <0x2360>;
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		i2c1-grp0 {
+			pinmux = <0x131>, <0x141>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c1-grp1 {
+			pinmux = <0x2cd2>, <0x2ce2>;
+		};
+	};
+
+	i2c1_gpio_pins: i2c1-gpio-pins {
+		i2c1-gpio-grp0 {
+			pinmux = <0x130>, <0x140>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c1-gpio-grp1 {
+			pinmux = <0x2cd0>, <0x2ce0>;
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		i2c2-grp0 {
+			pinmux = <0x151>, <0x161>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-grp1 {
+			pinmux = <0x2cf2>, <0x2d02>;
+		};
+	};
+
+	i2c2_gpio_pins: i2c2-gpio-pins {
+		i2c2-gpio-grp0 {
+			pinmux = <0x150>, <0x160>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-gpio-grp1 {
+			pinmux = <0x2cf0>, <0x2d00>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		i2c4-grp0 {
+			pinmux = <0x211>, <0x222>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-grp1 {
+			pinmux = <0x2d43>, <0x2d33>;
+		};
+	};
+
+	i2c4_gpio_pins: i2c4-gpio-pins {
+		i2c4-gpio-grp0 {
+			pinmux = <0x210>, <0x220>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-gpio-grp1 {
+			pinmux = <0x2d40>, <0x2d30>;
+		};
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-1 = <&i2c0_gpio_pins>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c1_pins>;
+	pinctrl-1 = <&i2c1_gpio_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_gpio_pins>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-1 = <&i2c4_gpio_pins>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
new file mode 100644
index 000000000000..50fe6aaa1605
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2024 NXP
+ *
+ * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
+ *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
+ *          Larisa Grigore <larisa.grigore at nxp.com>
+ */
+
+&pinctrl {
+	i2c0_pins: i2c0-pins {
+		i2c0-grp0 {
+			pinmux = <0x1f2>, <0x201>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-grp1 {
+			pinmux = <0x2353>, <0x2363>;
+		};
+	};
+
+	i2c0_gpio_pins: i2c0-gpio-pins {
+		i2c0-gpio-grp0 {
+			pinmux = <0x1f0>, <0x200>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-gpio-grp1 {
+			pinmux = <0x2350>, <0x2360>;
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		i2c2-grp0 {
+			pinmux = <0x151>, <0x161>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-grp1 {
+			pinmux = <0x2cf2>, <0x2d02>;
+		};
+	};
+
+	i2c2_gpio_pins: i2c2-gpio-pins {
+		i2c2-gpio-grp0 {
+			pinmux = <0x2cf0>, <0x2d00>;
+		};
+
+		i2c2-gpio-grp1 {
+			pinmux = <0x150>, <0x160>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		i2c4-grp0 {
+			pinmux = <0x211>, <0x222>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-grp1 {
+			pinmux = <0x2d43>, <0x2d33>;
+		};
+	};
+
+	i2c4_gpio_pins: i2c4-gpio-pins {
+		i2c4-gpio-grp0 {
+			pinmux = <0x210>, <0x220>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-gpio-grp1 {
+			pinmux = <0x2d40>, <0x2d30>;
+		};
+	};
+};
+
+&i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-1 = <&i2c0_gpio_pins>;
+	status = "okay";
+
+	pcal6524: gpio-expander at 22 {
+		compatible = "nxp,pcal6524";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_gpio_pins>;
+	status = "okay";
+};
+
+&i2c4 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-1 = <&i2c4_gpio_pins>;
+	status = "okay";
+};
-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Thu Dec 19 05:10:28 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Thu, 19 Dec 2024 15:10:28 +0200
Subject: [PATCH v3 3/4] arm64: dts: s32g: include necessary 'EVB/RDB' common board dtsi
In-Reply-To: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
References: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241219131029.1139720-4-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

After the 'S32G2/S32G3' common 'EVB' and 'RDB' dtsi support addition,
include the necessary header depending on board flavour.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 arch/arm64/boot/dts/freescale/s32g274a-evb.dts  | 1 +
 arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts | 1 +
 arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
index b9a119eea2b7..c4a195dd67bf 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s32g2.dtsi"
+#include "s32gxxxa-evb.dtsi"
 
 / {
 	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
index aaa61a8ad0da..b5ba51696f43 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s32g2.dtsi"
+#include "s32gxxxa-rdb.dtsi"
 
 / {
 	model = "NXP S32G2 Reference Design Board 2 (S32G-VNP-RDB2)";
diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
index 828e353455b5..94f531be4017 100644
--- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
+++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
@@ -8,6 +8,7 @@
 /dts-v1/;
 
 #include "s32g3.dtsi"
+#include "s32gxxxa-rdb.dtsi"
 
 / {
 	model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
-- 
2.45.2



From tudor.ambarus at linaro.org  Thu Dec 19 05:07:45 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 19 Dec 2024 13:07:45 +0000
Subject: [PATCH 0/2] mailbox: add support for clients to request channels
 by arguments
Message-ID: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>

There are clients that can discover channel identifiers at runtime by
parsing a shared memory for example, as in the ACPM interface's case.
For such cases passing the channel identifiers via DT is redundant.

Supply a new framework API: mbox_request_channel_by_args().

It works by supplying the usual client pointer as the first argument and
a pointer to a ``const struct mbox_xlate_args`` as a second. The newly
introduced struct is modeled after ``struct of_phandle_args``. The API
will search the client's node for a ``mbox`` phandle, identify the
controller's device node, and then call that controller's xlate() method
that will return a pointer to a mbox_chan or a ERR_PTR. The binding
between the channel and the client is done in the typical way.

This allows clients to reference the controller node as following:
        firmware {
                acpm_ipc: power-management {
                        compatible = "google,gs101-acpm-ipc";
-                       mboxes = <&ap2apm_mailbox 0 0
-                                 &ap2apm_mailbox 0 1
-                                 &ap2apm_mailbox 0 2
-                                 &ap2apm_mailbox 0 3
-                                 &ap2apm_mailbox 0 4
-                                 &ap2apm_mailbox 0 5
-                                 &ap2apm_mailbox 0 6
-                                 &ap2apm_mailbox 0 7
-                                 &ap2apm_mailbox 0 8
-                                 &ap2apm_mailbox 0 9
-                                 &ap2apm_mailbox 0 10
-                                 &ap2apm_mailbox 0 11
-                                 &ap2apm_mailbox 0 12
-                                 &ap2apm_mailbox 0 13
-                                 &ap2apm_mailbox 0 14>;
+                       mbox = <&ap2apm_mailbox>;
                        shmem = <&apm_sram>;
                };
        };

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Tudor Ambarus (2):
      dt-bindings: mailbox: add support for referencing controllers solely by node
      mailbox: add support for clients to request channels by arguments

 .../devicetree/bindings/mailbox/mailbox.txt        | 19 ++++++--
 drivers/mailbox/mailbox.c                          | 57 ++++++++++++++++++++++
 include/linux/mailbox.h                            | 17 +++++++
 include/linux/mailbox_client.h                     |  3 ++
 include/linux/mailbox_controller.h                 |  4 ++
 5 files changed, 96 insertions(+), 4 deletions(-)
---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241219-mbox_request_channel_by_args-7115089ed492

Best regards,
-- 
Tudor Ambarus <tudor.ambarus at linaro.org>



From tudor.ambarus at linaro.org  Thu Dec 19 05:07:46 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 19 Dec 2024 13:07:46 +0000
Subject: [PATCH 1/2] dt-bindings: mailbox: add support for referencing
 controllers solely by node
In-Reply-To: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>
References: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>
Message-ID: <20241219-mbox_request_channel_by_args-v1-1-617a6910f842@linaro.org>

There are mailbox clients that can discover the mailbox channel ID at
run-time. For such cases passing the channel identifier via DT is
redundant. Add support for referencing controllers solely by node.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 Documentation/devicetree/bindings/mailbox/mailbox.txt | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mailbox/mailbox.txt b/Documentation/devicetree/bindings/mailbox/mailbox.txt
index af8ecee2ac68..0c4295a62f61 100644
--- a/Documentation/devicetree/bindings/mailbox/mailbox.txt
+++ b/Documentation/devicetree/bindings/mailbox/mailbox.txt
@@ -5,9 +5,10 @@ assign appropriate mailbox channel to client drivers.
 
 * Mailbox Controller
 
-Required property:
-- #mbox-cells: Must be at least 1. Number of cells in a mailbox
-		specifier.
+Optional property:
+- #mbox-cells: Must be at least 1. Number of cells in a mailbox specifier.
+               The property becomes mandatory for the cases where the clients
+               reference the controller via the mboxes property.
 
 Example:
 	mailbox: mailbox {
@@ -19,7 +20,11 @@ Example:
 * Mailbox Client
 
 Required property:
+Clients must reference the mailbox controller either via the mboxes or mbox
+properties.
 - mboxes: List of phandle and mailbox channel specifiers.
+- mbox: phandle pointing to the controller. Used by clients that can discover
+        the channel identifiers at runtime.
 
 Optional property:
 - mbox-names: List of identifier strings for each mailbox channel.
@@ -29,7 +34,13 @@ Optional property:
 	  communication between the mailbox client and the remote.
 
 
-Example:
+Example using mbox:
+	power-management {
+		...
+		mbox = <&mailbox>;
+	};
+
+Example using mboxes:
 	pwr_cntrl: power {
 		...
 		mbox-names = "pwr-ctrl", "rpc";

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Thu Dec 19 05:07:47 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 19 Dec 2024 13:07:47 +0000
Subject: [PATCH 2/2] mailbox: add support for clients to request channels
 by arguments
In-Reply-To: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>
References: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>
Message-ID: <20241219-mbox_request_channel_by_args-v1-2-617a6910f842@linaro.org>

There are clients that can discover channel identifiers at runtime by
parsing a shared memory for example, as in the ACPM interface's case.

Supply a new framework API: mbox_request_channel_by_args().

It works by supplying the usual client pointer as the first argument and
a pointer to a ``const struct mbox_xlate_args`` as a second. The newly
introduced struct is modeled after ``struct of_phandle_args``. The API
will search the client's node for a ``mbox`` phandle, identify the
controller's device node, and then call that controller's xlate() method
that will return a pointer to a mbox_chan or a ERR_PTR. The binding
between the channel and the client is done in the typical way.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/mailbox/mailbox.c          | 57 ++++++++++++++++++++++++++++++++++++++
 include/linux/mailbox.h            | 17 ++++++++++++
 include/linux/mailbox_client.h     |  3 ++
 include/linux/mailbox_controller.h |  4 +++
 4 files changed, 81 insertions(+)

diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index d3d26a2c9895..07ea32ebab80 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -467,6 +467,63 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
 }
 EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
 
+/**
+ * mbox_request_channel_by_args - request a mailbox channel using client's
+ * channel identifiers.
+ * @cl: identity of the client requesting the channel.
+ * @spec: arguments that describe the channel.
+ *
+ * Used by clients that can discover the channel identifiers at runtime (by
+ * parsing a shared memory for example). The description of
+ * mbox_request_channel() applies here as well.
+ *
+ * Return: Pointer to the channel assigned to the client if successful.
+ *         ERR_PTR for request failure.
+ */
+struct mbox_chan *mbox_request_channel_by_args(struct mbox_client *cl,
+					const struct mbox_xlate_args *spec)
+{
+	struct device *dev = cl->dev;
+	struct mbox_controller *mbox;
+	struct device_node *mbox_np;
+	struct mbox_chan *chan;
+	int ret;
+
+	if (!dev || !dev->of_node) {
+		pr_debug("%s: No owner device node\n", __func__);
+		return ERR_PTR(-ENODEV);
+	}
+
+	mbox_np = of_parse_phandle(dev_of_node(dev), "mbox", 0);
+	if (!mbox_np)
+		return ERR_PTR(-ENODEV);
+
+	mutex_lock(&con_mutex);
+
+	chan = ERR_PTR(-EPROBE_DEFER);
+	list_for_each_entry(mbox, &mbox_cons, node)
+		if (mbox->dev->of_node == mbox_np && mbox->xlate) {
+			chan = mbox->xlate(mbox, spec);
+			if (!IS_ERR(chan))
+				break;
+		}
+
+	of_node_put(mbox_np);
+
+	if (IS_ERR(chan)) {
+		mutex_unlock(&con_mutex);
+		return chan;
+	}
+
+	ret = __mbox_bind_client(chan, cl);
+	if (ret)
+		chan = ERR_PTR(ret);
+
+	mutex_unlock(&con_mutex);
+	return chan;
+}
+EXPORT_SYMBOL_GPL(mbox_request_channel_by_args);
+
 /**
  * mbox_free_channel - The client relinquishes control of a mailbox
  *			channel by this call.
diff --git a/include/linux/mailbox.h b/include/linux/mailbox.h
new file mode 100644
index 000000000000..cef88c5ae49d
--- /dev/null
+++ b/include/linux/mailbox.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#ifndef __LINUX_MAILBOX_H
+#define __LINUX_MAILBOX_H
+
+#include <linux/types.h>
+
+#define MBOX_XLATE_MAX_ARGS 16
+struct mbox_xlate_args {
+	int args_count;
+	u32 args[MBOX_XLATE_MAX_ARGS];
+};
+
+#endif /* __LINUX_MAILBOX_H */
diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h
index 734694912ef7..a9f4d108c48c 100644
--- a/include/linux/mailbox_client.h
+++ b/include/linux/mailbox_client.h
@@ -9,6 +9,7 @@
 
 #include <linux/of.h>
 #include <linux/device.h>
+#include <linux/mailbox.h>
 
 struct mbox_chan;
 
@@ -41,6 +42,8 @@ int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl);
 struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
 					      const char *name);
 struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index);
+struct mbox_chan *mbox_request_channel_by_args(struct mbox_client *cl,
+			     const struct mbox_xlate_args *spec);
 int mbox_send_message(struct mbox_chan *chan, void *mssg);
 int mbox_flush(struct mbox_chan *chan, unsigned long timeout);
 void mbox_client_txdone(struct mbox_chan *chan, int r); /* atomic */
diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h
index 6fee33cb52f5..dfddcf966f9f 100644
--- a/include/linux/mailbox_controller.h
+++ b/include/linux/mailbox_controller.h
@@ -8,6 +8,7 @@
 #include <linux/hrtimer.h>
 #include <linux/device.h>
 #include <linux/completion.h>
+#include <linux/mailbox.h>
 
 struct mbox_chan;
 
@@ -67,6 +68,7 @@ struct mbox_chan_ops {
  * @txpoll_period:	If 'txdone_poll' is in effect, the API polls for
  *			last TX's status after these many millisecs
  * @of_xlate:		Controller driver specific mapping of channel via DT
+ * @xlate:		Controller driver specific mapping of channel
  * @poll_hrt:		API private. hrtimer used to poll for TXDONE on all
  *			channels.
  * @node:		API private. To hook into list of controllers.
@@ -81,6 +83,8 @@ struct mbox_controller {
 	unsigned txpoll_period;
 	struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
 				      const struct of_phandle_args *sp);
+	struct mbox_chan *(*xlate)(struct mbox_controller *mbox,
+				   const struct mbox_xlate_args *sp);
 	/* Internal to API */
 	struct hrtimer poll_hrt;
 	spinlock_t poll_hrt_lock;

-- 
2.47.1.613.gc27f4b7a9f-goog



From ciprianmarian.costea at oss.nxp.com  Thu Dec 19 05:10:25 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Thu, 19 Dec 2024 15:10:25 +0200
Subject: [PATCH v3 0/4] add I2C DTS support for S32G2/S32G3 SoCs
Message-ID: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

This patchset aims to add two changes to the S32G2/S32G3 dtsi support:
- Adding I2C dts support for S32G SoC based boards
- Centralize the common part of 'S32G-EVB' and 'S32G-RDB' board revisions
into dtsi files. This refactor will serve I2C in this patchset, but in the
future it will also be used for other modules such as : FlexCAN and DSPI.

Changes in V3:
- Separated patchset into multiple stages: common 'I2C' dts entries, board
'I2C' dts entries and the introduction of common 'S32GXXXA-EVB/RDB' dtsi.
- Added missing changelog for V2 of this patchset

Changes in V2:
- Moved I2C end device '#address-size' and '#address-cells' entries from
board dts to common 's32gxxxa-evb/rdb' common dtsi.

Ciprian Marian Costea (4):
  arm64: dts: s32g: add 'I2C' common board support
  arm64: dts: s32g: add common 'S32G-EVB' and 'S32G-RDB' board support
  arm64: dts: s32g: include necessary 'EVB/RDB' common board dtsi
  arm64: dts: s32g399a-rdb3: Add INA231 sensor entry over I2C4

 arch/arm64/boot/dts/freescale/s32g2.dtsi      |  45 ++++++
 .../arm64/boot/dts/freescale/s32g274a-evb.dts |   1 +
 .../boot/dts/freescale/s32g274a-rdb2.dts      |   1 +
 arch/arm64/boot/dts/freescale/s32g3.dtsi      |  50 ++++++
 .../boot/dts/freescale/s32g399a-rdb3.dts      |   9 ++
 .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
 .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 126 +++++++++++++++
 7 files changed, 382 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi

-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Thu Dec 19 05:10:26 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Thu, 19 Dec 2024 15:10:26 +0200
Subject: [PATCH v3 1/4] arm64: dts: s32g: add 'I2C' common board support
In-Reply-To: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
References: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241219131029.1139720-2-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

On both 'S32G2' and 'S32G3' SoCs there are five i2c controllers available
(i2c0-i2c4). Specific S32G2/S32G3 based board 'i2c' dts device support
will be added in further commits.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 arch/arm64/boot/dts/freescale/s32g2.dtsi | 45 +++++++++++++++++++++
 arch/arm64/boot/dts/freescale/s32g3.dtsi | 50 ++++++++++++++++++++++++
 2 files changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
index 7be430b78c83..0e6c847ab0c3 100644
--- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -333,6 +333,33 @@ uart1: serial at 401cc000 {
 			status = "disabled";
 		};
 
+		i2c0: i2c at 401e4000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x401e4000 0x1000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c1: i2c at 401e8000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x401e8000 0x1000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c2: i2c at 401ec000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x401ec000 0x1000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		uart2: serial at 402bc000 {
 			compatible = "nxp,s32g2-linflexuart",
 				     "fsl,s32v234-linflexuart";
@@ -341,6 +368,24 @@ uart2: serial at 402bc000 {
 			status = "disabled";
 		};
 
+		i2c3: i2c at 402d8000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x402d8000 0x1000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c4: i2c at 402dc000 {
+			compatible = "nxp,s32g2-i2c";
+			reg = <0x402dc000 0x1000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		usdhc0: mmc at 402f0000 {
 			compatible = "nxp,s32g2-usdhc";
 			reg = <0x402f0000 0x1000>;
diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
index 6c572ffe37ca..666e4029e588 100644
--- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
@@ -390,6 +390,36 @@ uart1: serial at 401cc000 {
 			status = "disabled";
 		};
 
+		i2c0: i2c at 401e4000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x401e4000 0x1000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c1: i2c at 401e8000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x401e8000 0x1000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c2: i2c at 401ec000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x401ec000 0x1000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		uart2: serial at 402bc000 {
 			compatible = "nxp,s32g3-linflexuart",
 				     "fsl,s32v234-linflexuart";
@@ -398,6 +428,26 @@ uart2: serial at 402bc000 {
 			status = "disabled";
 		};
 
+		i2c3: i2c at 402d8000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x402d8000 0x1000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c4: i2c at 402dc000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			reg = <0x402dc000 0x1000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		usdhc0: mmc at 402f0000 {
 			compatible = "nxp,s32g3-usdhc",
 				     "nxp,s32g2-usdhc";
-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Thu Dec 19 05:10:29 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Thu, 19 Dec 2024 15:10:29 +0200
Subject: [PATCH v3 4/4] arm64: dts: s32g399a-rdb3: Add INA231 sensor entry over I2C4
In-Reply-To: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
References: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241219131029.1139720-5-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

On S32G399A-RDB3 boards, an INA231 current sensor is connected over
I2C4 bus.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
index 94f531be4017..5f8739c068c6 100644
--- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
+++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
@@ -40,6 +40,14 @@ &uart1 {
 	status = "okay";
 };
 
+&i2c4 {
+	ina231 at 40 {
+		compatible = "ti,ina231";
+		reg = <0x40>;
+		shunt-resistor = <1000>;
+	};
+};
+
 &usdhc0 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz";
 	pinctrl-0 = <&pinctrl_usdhc0>;
-- 
2.45.2



From pankaj.gupta at nxp.com  Thu Dec 19 10:57:25 2024
From: pankaj.gupta at nxp.com (Pankaj Gupta)
Date: Fri, 20 Dec 2024 00:27:25 +0530
Subject: [PATCH v11 4/5] firmware: imx: add driver for NXP EdgeLock Enclave
In-Reply-To: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
References: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
Message-ID: <20241220-imx-se-if-v11-4-0c7e65d7ae7b@nxp.com>

NXP hardware IP(s) for secure-enclaves like Edgelock Enclave(ELE),
are embedded in the SoC to support the features like HSM, SHE & V2X,
using message based communication interface.

The secure enclave FW communicates on a dedicated messaging unit(MU)
based interface(s) with application core, where kernel is running.
It exists on specific i.MX processors. e.g. i.MX8ULP, i.MX93.

This patch adds the driver for communication interface to secure-enclave,
for exchanging messages with NXP secure enclave HW IP(s) like EdgeLock
Enclave (ELE) from Kernel-space, used by kernel management layers like
- DM-Crypt.

Signed-off-by: Pankaj Gupta <pankaj.gupta at nxp.com>
---
 drivers/firmware/imx/Kconfig        |  13 +
 drivers/firmware/imx/Makefile       |   2 +
 drivers/firmware/imx/ele_base_msg.c | 273 ++++++++++++++++++
 drivers/firmware/imx/ele_base_msg.h |  94 +++++++
 drivers/firmware/imx/ele_common.c   | 323 ++++++++++++++++++++++
 drivers/firmware/imx/ele_common.h   |  51 ++++
 drivers/firmware/imx/se_ctrl.c      | 538 ++++++++++++++++++++++++++++++++++++
 drivers/firmware/imx/se_ctrl.h      |  94 +++++++
 include/linux/firmware/imx/se_api.h |  14 +
 9 files changed, 1402 insertions(+)

diff --git a/drivers/firmware/imx/Kconfig b/drivers/firmware/imx/Kconfig
index 477d3f32d99a..ccd9f9e0652e 100644
--- a/drivers/firmware/imx/Kconfig
+++ b/drivers/firmware/imx/Kconfig
@@ -33,3 +33,16 @@ config IMX_SCMI_MISC_DRV
 	  core that could provide misc functions such as board control.
 
 	  This driver can also be built as a module.
+
+config IMX_SEC_ENCLAVE
+	tristate "i.MX Embedded Secure Enclave - EdgeLock Enclave Firmware driver."
+	depends on IMX_MBOX && ARCH_MXC && ARM64
+	select FW_LOADER
+	default m if ARCH_MXC
+
+	help
+	  It is possible to use APIs exposed by the iMX Secure Enclave HW IP called:
+	  - EdgeLock Enclave Firmware (for i.MX8ULP, i.MX93),
+	    like base, HSM, V2X & SHE using the SAB protocol via the shared Messaging
+	    Unit. This driver exposes these interfaces via a set of file descriptors
+	    allowing to configure shared memory, send and receive messages.
diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
index 8d046c341be8..4e1d2706535d 100644
--- a/drivers/firmware/imx/Makefile
+++ b/drivers/firmware/imx/Makefile
@@ -2,3 +2,5 @@
 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_MISC_DRV}	+= sm-misc.o
+sec_enclave-objs		= se_ctrl.o ele_common.o ele_base_msg.o
+obj-${CONFIG_IMX_SEC_ENCLAVE}	+= sec_enclave.o
diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
new file mode 100644
index 000000000000..aa00e95d6aee
--- /dev/null
+++ b/drivers/firmware/imx/ele_base_msg.c
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/types.h>
+
+#include <linux/completion.h>
+#include <linux/dma-mapping.h>
+#include <linux/genalloc.h>
+
+#include "ele_base_msg.h"
+#include "ele_common.h"
+
+int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info)
+{
+	struct se_api_msg *tx_msg __free(kfree) = NULL;
+	struct se_api_msg *rx_msg __free(kfree) = NULL;
+	dma_addr_t get_info_addr = 0;
+	u32 *get_info_data = NULL;
+	int ret = 0;
+
+	if (!priv) {
+		ret = -EINVAL;
+		return ret;
+	}
+
+	memset(s_info, 0x0, sizeof(*s_info));
+
+	if (priv->mem_pool)
+		get_info_data = gen_pool_dma_alloc(priv->mem_pool,
+						   ELE_GET_INFO_BUFF_SZ,
+						   &get_info_addr);
+	else
+		get_info_data = dma_alloc_coherent(priv->dev,
+						   ELE_GET_INFO_BUFF_SZ,
+						   &get_info_addr,
+						   GFP_KERNEL);
+	if (!get_info_data) {
+		ret = -ENOMEM;
+		dev_dbg(priv->dev,
+			"%s: Failed to allocate get_info_addr.\n",
+			__func__);
+		return ret;
+	}
+
+	tx_msg = kzalloc(ELE_GET_INFO_REQ_MSG_SZ, GFP_KERNEL);
+	if (!tx_msg) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	rx_msg = kzalloc(ELE_GET_INFO_RSP_MSG_SZ, GFP_KERNEL);
+	if (!rx_msg) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ret = se_fill_cmd_msg_hdr(priv,
+				      (struct se_msg_hdr *)&tx_msg->header,
+				      ELE_GET_INFO_REQ,
+				      ELE_GET_INFO_REQ_MSG_SZ,
+				      true);
+	if (ret)
+		goto exit;
+
+	tx_msg->data[0] = upper_32_bits(get_info_addr);
+	tx_msg->data[1] = lower_32_bits(get_info_addr);
+	tx_msg->data[2] = sizeof(*s_info);
+	ret = ele_msg_send_rcv(priv,
+			       tx_msg,
+			       ELE_GET_INFO_REQ_MSG_SZ,
+			       rx_msg,
+			       ELE_GET_INFO_RSP_MSG_SZ);
+	if (ret < 0)
+		goto exit;
+
+	ret = se_val_rsp_hdr_n_status(priv,
+				      rx_msg,
+				      ELE_GET_INFO_REQ,
+				      ELE_GET_INFO_RSP_MSG_SZ,
+				      true);
+
+	memcpy(s_info, get_info_data, sizeof(*s_info));
+
+exit:
+	if (priv->mem_pool)
+		gen_pool_free(priv->mem_pool,
+			      (u64) get_info_data,
+			      ELE_GET_INFO_BUFF_SZ);
+	else
+		dma_free_coherent(priv->dev,
+				  ELE_GET_INFO_BUFF_SZ,
+				  get_info_data,
+				  get_info_addr);
+
+	return ret;
+}
+
+int ele_fetch_soc_info(struct se_if_priv *priv, void *data)
+{
+	int err;
+
+	err = ele_get_info(priv, data);
+	if (err < 0)
+		return err;
+
+	return err;
+}
+
+int ele_ping(struct se_if_priv *priv)
+{
+	struct se_api_msg *tx_msg __free(kfree) = NULL;
+	struct se_api_msg *rx_msg __free(kfree) = NULL;
+	int ret = 0;
+
+	if (!priv) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	tx_msg = kzalloc(ELE_PING_REQ_SZ, GFP_KERNEL);
+	if (!tx_msg) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	rx_msg = kzalloc(ELE_PING_RSP_SZ, GFP_KERNEL);
+	if (!rx_msg) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ret = se_fill_cmd_msg_hdr(priv,
+				      (struct se_msg_hdr *)&tx_msg->header,
+				      ELE_PING_REQ, ELE_PING_REQ_SZ, true);
+	if (ret) {
+		dev_err(priv->dev, "Error: se_fill_cmd_msg_hdr failed.\n");
+		goto exit;
+	}
+
+	ret = ele_msg_send_rcv(priv,
+			       tx_msg,
+			       ELE_PING_REQ_SZ,
+			       rx_msg,
+			       ELE_PING_RSP_SZ);
+	if (ret < 0)
+		goto exit;
+
+	ret = se_val_rsp_hdr_n_status(priv,
+				      rx_msg,
+				      ELE_PING_REQ,
+				      ELE_PING_RSP_SZ,
+				      true);
+exit:
+	return ret;
+}
+
+int ele_service_swap(struct se_if_priv *priv,
+		     phys_addr_t addr,
+		     u32 addr_size, u16 flag)
+{
+	struct se_api_msg *tx_msg __free(kfree) = NULL;
+	struct se_api_msg *rx_msg __free(kfree) = NULL;
+	int ret = 0;
+
+	if (!priv) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	tx_msg = kzalloc(ELE_SERVICE_SWAP_REQ_MSG_SZ, GFP_KERNEL);
+	if (!tx_msg) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	rx_msg = kzalloc(ELE_SERVICE_SWAP_RSP_MSG_SZ, GFP_KERNEL);
+	if (!rx_msg) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ret = se_fill_cmd_msg_hdr(priv,
+				      (struct se_msg_hdr *)&tx_msg->header,
+				      ELE_SERVICE_SWAP_REQ,
+				      ELE_SERVICE_SWAP_REQ_MSG_SZ, true);
+	if (ret)
+		goto exit;
+
+	tx_msg->data[0] = flag;
+	tx_msg->data[1] = addr_size;
+	tx_msg->data[2] = ELE_NONE_VAL;
+	tx_msg->data[3] = lower_32_bits(addr);
+	tx_msg->data[4] = se_add_msg_crc((uint32_t *)&tx_msg[0],
+						 ELE_SERVICE_SWAP_REQ_MSG_SZ);
+	ret = ele_msg_send_rcv(priv,
+			       tx_msg,
+			       ELE_SERVICE_SWAP_REQ_MSG_SZ,
+			       rx_msg,
+			       ELE_SERVICE_SWAP_RSP_MSG_SZ);
+	if (ret < 0)
+		goto exit;
+
+	ret = se_val_rsp_hdr_n_status(priv,
+				      rx_msg,
+				      ELE_SERVICE_SWAP_REQ,
+				      ELE_SERVICE_SWAP_RSP_MSG_SZ,
+				      true);
+	if (ret)
+		goto exit;
+
+	if (flag == ELE_IMEM_EXPORT)
+		ret = rx_msg->data[1];
+	else
+		ret = 0;
+
+exit:
+
+	return ret;
+}
+
+int ele_fw_authenticate(struct se_if_priv *priv, phys_addr_t addr)
+{
+	struct se_api_msg *tx_msg __free(kfree) = NULL;
+	struct se_api_msg *rx_msg __free(kfree) = NULL;
+	int ret = 0;
+
+	if (!priv) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	tx_msg = kzalloc(ELE_FW_AUTH_REQ_SZ, GFP_KERNEL);
+	if (!tx_msg) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	rx_msg = kzalloc(ELE_FW_AUTH_RSP_MSG_SZ, GFP_KERNEL);
+	if (!rx_msg) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ret = se_fill_cmd_msg_hdr(priv,
+				  (struct se_msg_hdr *)&tx_msg->header,
+				  ELE_FW_AUTH_REQ,
+				  ELE_FW_AUTH_REQ_SZ,
+				  true);
+	if (ret)
+		goto exit;
+
+	tx_msg->data[1] = upper_32_bits(addr);
+	tx_msg->data[0] = lower_32_bits(addr);
+	tx_msg->data[2] = addr;
+
+	ret = ele_msg_send_rcv(priv,
+			       tx_msg,
+			       ELE_FW_AUTH_REQ_SZ,
+			       rx_msg,
+			       ELE_FW_AUTH_RSP_MSG_SZ);
+	if (ret < 0)
+		goto exit;
+
+	ret = se_val_rsp_hdr_n_status(priv,
+				      rx_msg,
+				      ELE_FW_AUTH_REQ,
+				      ELE_FW_AUTH_RSP_MSG_SZ,
+				      true);
+exit:
+	return ret;
+}
diff --git a/drivers/firmware/imx/ele_base_msg.h b/drivers/firmware/imx/ele_base_msg.h
new file mode 100644
index 000000000000..ef9eb8155167
--- /dev/null
+++ b/drivers/firmware/imx/ele_base_msg.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ *
+ * Header file for the EdgeLock Enclave Base API(s).
+ */
+
+#ifndef ELE_BASE_MSG_H
+#define ELE_BASE_MSG_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+
+#include "se_ctrl.h"
+
+#define ELE_NONE_VAL			0x0
+
+#define ELE_GET_INFO_REQ		0xDA
+#define ELE_GET_INFO_REQ_MSG_SZ		0x10
+#define ELE_GET_INFO_RSP_MSG_SZ		0x08
+
+#define SOC_ID_MASK			0x0000FFFF
+
+#define MAX_UID_SIZE                     (16)
+#define DEV_GETINFO_ROM_PATCH_SHA_SZ     (32)
+#define DEV_GETINFO_FW_SHA_SZ            (32)
+#define DEV_GETINFO_OEM_SRKH_SZ          (64)
+#define DEV_GETINFO_MIN_VER_MASK	0xFF
+#define DEV_GETINFO_MAJ_VER_MASK	0xFF00
+#define ELE_DEV_INFO_EXTRA_SZ		0x60
+
+struct dev_info {
+	uint8_t  cmd;
+	uint8_t  ver;
+	uint16_t length;
+	uint16_t soc_id;
+	uint16_t soc_rev;
+	uint16_t lmda_val;
+	uint8_t  ssm_state;
+	uint8_t  dev_atts_api_ver;
+	uint8_t  uid[MAX_UID_SIZE];
+	uint8_t  sha_rom_patch[DEV_GETINFO_ROM_PATCH_SHA_SZ];
+	uint8_t  sha_fw[DEV_GETINFO_FW_SHA_SZ];
+};
+
+struct dev_addn_info {
+	uint8_t  oem_srkh[DEV_GETINFO_OEM_SRKH_SZ];
+	uint8_t  trng_state;
+	uint8_t  csal_state;
+	uint8_t  imem_state;
+	uint8_t  reserved2;
+};
+
+struct ele_dev_info {
+	struct dev_info d_info;
+	struct dev_addn_info d_addn_info;
+};
+
+#define ELE_GET_INFO_BUFF_SZ		(sizeof(struct ele_dev_info) \
+						+ ELE_DEV_INFO_EXTRA_SZ)
+
+#define GET_SERIAL_NUM_FROM_UID(x, uid_word_sz) \
+	(((u64)(((u32 *)(x))[(uid_word_sz) - 1]) << 32) | ((u32 *)(x))[0])
+
+#define ELE_DEBUG_DUMP_REQ		0x21
+#define ELE_DEBUG_DUMP_RSP_SZ		0x17
+
+#define ELE_PING_REQ			0x01
+#define ELE_PING_REQ_SZ			0x04
+#define ELE_PING_RSP_SZ			0x08
+
+#define ELE_SERVICE_SWAP_REQ		0xDF
+#define ELE_SERVICE_SWAP_REQ_MSG_SZ	0x18
+#define ELE_SERVICE_SWAP_RSP_MSG_SZ	0x0C
+#define ELE_IMEM_SIZE			0x10000
+#define ELE_IMEM_STATE_OK		0xCA
+#define ELE_IMEM_STATE_BAD		0xFE
+#define ELE_IMEM_STATE_WORD		0x27
+#define ELE_IMEM_STATE_MASK		0x00ff0000
+#define ELE_IMEM_EXPORT			0x1
+#define ELE_IMEM_IMPORT			0x2
+
+#define ELE_FW_AUTH_REQ			0x02
+#define ELE_FW_AUTH_REQ_SZ		0x10
+#define ELE_FW_AUTH_RSP_MSG_SZ		0x08
+
+int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info);
+int ele_fetch_soc_info(struct se_if_priv *priv, void *data);
+int ele_ping(struct se_if_priv *priv);
+int ele_service_swap(struct se_if_priv *priv,
+		     phys_addr_t addr,
+		     u32 addr_size, u16 flag);
+int ele_fw_authenticate(struct se_if_priv *priv, phys_addr_t addr);
+#endif
diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
new file mode 100644
index 000000000000..923eaa90cdd4
--- /dev/null
+++ b/drivers/firmware/imx/ele_common.c
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include "ele_base_msg.h"
+#include "ele_common.h"
+
+u32 se_add_msg_crc(u32 *msg, u32 msg_len)
+{
+	u32 nb_words = msg_len / (u32)sizeof(u32);
+	u32 crc = 0;
+	u32 i;
+
+	for (i = 0; i < nb_words - 1; i++)
+		crc ^= *(msg + i);
+
+	return crc;
+}
+
+int ele_msg_rcv(struct se_if_priv *priv,
+		struct se_clbk_handle *se_clbk_hdl)
+{
+	int err = 0;
+
+	do {
+		/* If callback is executed before entrying to wait state,
+		 * it will immediately come out after entering the wait state,
+		 * but completion_done(&se_clbk_hdl->done), will return false
+		 * after exiting the wait state, with err = 0.
+		 */
+		err = wait_for_completion_interruptible(&se_clbk_hdl->done);
+		if (err == -ERESTARTSYS) {
+			if (priv->waiting_rsp_clbk_hdl.rx_msg) {
+				priv->waiting_rsp_clbk_hdl.signal_rcvd = true;
+				continue;
+			}
+			dev_err(priv->dev,
+				"Err[0x%x]:Interrupted by signal.\n",
+				err);
+			err = -EINTR;
+			break;
+		}
+	} while (err != 0);
+
+	return err ? err : se_clbk_hdl->rx_msg_sz;
+}
+
+int ele_msg_send(struct se_if_priv *priv,
+		 void *tx_msg,
+		 int tx_msg_sz)
+{
+	struct se_msg_hdr *header;
+	int err;
+
+	header = tx_msg;
+
+	/*
+	 * Check that the size passed as argument matches the size
+	 * carried in the message.
+	 */
+	if (header->size << 2 != tx_msg_sz) {
+		err = -EINVAL;
+		dev_err(priv->dev,
+			"User buf hdr: 0x%x, sz mismatced with input-sz (%d != %d).",
+			*(u32 *)header,
+			header->size << 2, tx_msg_sz);
+		goto exit;
+	}
+
+	err = mbox_send_message(priv->tx_chan, tx_msg);
+	if (err < 0) {
+		dev_err(priv->dev, "Error: mbox_send_message failure.\n");
+		return err;
+	}
+	err = tx_msg_sz;
+
+exit:
+	return err;
+}
+
+/* API used for send/receive blocking call. */
+int ele_msg_send_rcv(struct se_if_priv *priv,
+		     void *tx_msg,
+		     int tx_msg_sz,
+		     void *rx_msg,
+		     int exp_rx_msg_sz)
+{
+	int err;
+
+	guard(mutex)(&priv->se_if_cmd_lock);
+
+	priv->waiting_rsp_clbk_hdl.rx_msg_sz = exp_rx_msg_sz;
+	priv->waiting_rsp_clbk_hdl.rx_msg = rx_msg;
+
+	err = ele_msg_send(priv, tx_msg, tx_msg_sz);
+	if (err < 0)
+		goto exit;
+
+	err = ele_msg_rcv(priv, &priv->waiting_rsp_clbk_hdl);
+
+	if (priv->waiting_rsp_clbk_hdl.signal_rcvd) {
+		err = -EINTR;
+		priv->waiting_rsp_clbk_hdl.signal_rcvd = false;
+		dev_err(priv->dev,
+			"Err[0x%x]:Interrupted by signal.\n",
+			err);
+	}
+
+exit:
+	return err;
+}
+
+static bool exception_for_size(struct se_if_priv *priv,
+				struct se_msg_hdr *header)
+{
+	/* List of API(s) that can be accepte variable length
+	 * response buffer.
+	 */
+	if (header->command == ELE_DEBUG_DUMP_REQ &&
+		header->ver == priv->if_defs->base_api_ver &&
+		header->size >= 0 &&
+		header->size <= ELE_DEBUG_DUMP_RSP_SZ)
+		return true;
+
+	return false;
+}
+
+/*
+ * Callback called by mailbox FW, when data is received.
+ */
+void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
+{
+	struct se_clbk_handle *se_clbk_hdl;
+	struct device *dev = mbox_cl->dev;
+	struct se_msg_hdr *header;
+	struct se_if_priv *priv;
+	u32 rx_msg_sz;
+
+	priv = dev_get_drvdata(dev);
+
+	/* The function can be called with NULL msg */
+	if (!msg) {
+		dev_err(dev, "Message is invalid\n");
+		return;
+	}
+
+	header = msg;
+	rx_msg_sz = header->size << 2;
+
+	/* Incoming command: wake up the receiver if any. */
+	if (header->tag == priv->if_defs->cmd_tag) {
+		se_clbk_hdl = &priv->cmd_receiver_clbk_hdl;
+		dev_dbg(dev,
+			"Selecting cmd receiver for mesg header:0x%x.",
+			*(u32 *) header);
+
+		/* Pre-allocated buffer of MAX_NVM_MSG_LEN
+		 * as the NVM command are initiated by FW.
+		 * Size is revealed as part of this call function.
+		 */
+		if (rx_msg_sz > MAX_NVM_MSG_LEN) {
+			dev_err(dev,
+				"CMD-RCVER NVM: hdr(0x%x) with different sz(%d != %d).\n",
+				*(u32 *) header,
+				rx_msg_sz, se_clbk_hdl->rx_msg_sz);
+
+			se_clbk_hdl->rx_msg_sz = MAX_NVM_MSG_LEN;
+		}
+		se_clbk_hdl->rx_msg_sz = rx_msg_sz;
+
+	} else if (header->tag == priv->if_defs->rsp_tag) {
+		se_clbk_hdl = &priv->waiting_rsp_clbk_hdl;
+		dev_dbg(dev,
+			"Selecting resp waiter for mesg header:0x%x.",
+			*(u32 *) header);
+
+		if (rx_msg_sz != se_clbk_hdl->rx_msg_sz
+				&& !exception_for_size(priv, header)) {
+			dev_err(dev,
+				"Rsp to CMD: hdr(0x%x) with different sz(%d != %d).\n",
+				*(u32 *) header,
+				rx_msg_sz, se_clbk_hdl->rx_msg_sz);
+
+			se_clbk_hdl->rx_msg_sz = min(rx_msg_sz, se_clbk_hdl->rx_msg_sz);
+		}
+	} else {
+		dev_err(dev, "Failed to select a device for message: %.8x\n",
+			*((u32 *) header));
+		return;
+	}
+
+	memcpy(se_clbk_hdl->rx_msg, msg, se_clbk_hdl->rx_msg_sz);
+
+	/* Allow user to read */
+	complete(&se_clbk_hdl->done);
+}
+
+int se_val_rsp_hdr_n_status(struct se_if_priv *priv,
+			    struct se_api_msg *msg,
+			    uint8_t msg_id,
+			    uint8_t sz,
+			    bool is_base_api)
+{
+	u32 status;
+	struct se_msg_hdr *header = &msg->header;
+
+	if (header->tag != priv->if_defs->rsp_tag) {
+		dev_err(priv->dev,
+			"MSG[0x%x] Hdr: Resp tag mismatch. (0x%x != 0x%x)",
+			msg_id, header->tag, priv->if_defs->rsp_tag);
+		return -EINVAL;
+	}
+
+	if (header->command != msg_id) {
+		dev_err(priv->dev,
+			"MSG Header: Cmd id mismatch. (0x%x != 0x%x)",
+			header->command, msg_id);
+		return -EINVAL;
+	}
+
+	if (header->size != (sz >> 2) && !exception_for_size(priv, header)) {
+		dev_err(priv->dev,
+			"MSG[0x%x] Hdr: Cmd size mismatch. (0x%x != 0x%x)",
+			msg_id, header->size, (sz >> 2));
+		return -EINVAL;
+	}
+
+	if (is_base_api && (header->ver != priv->if_defs->base_api_ver)) {
+		dev_err(priv->dev,
+			"MSG[0x%x] Hdr: Base API Vers mismatch. (0x%x != 0x%x)",
+			msg_id, header->ver, priv->if_defs->base_api_ver);
+		return -EINVAL;
+	} else if (!is_base_api && header->ver != priv->if_defs->fw_api_ver) {
+		dev_err(priv->dev,
+			"MSG[0x%x] Hdr: FW API Vers mismatch. (0x%x != 0x%x)",
+			msg_id, header->ver, priv->if_defs->fw_api_ver);
+		return -EINVAL;
+	}
+
+	status = RES_STATUS(msg->data[0]);
+	if (status != priv->if_defs->success_tag) {
+		dev_err(priv->dev, "Command Id[%x], Response Failure = 0x%x",
+			header->command, status);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+int se_save_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem)
+{
+	int ret;
+
+	/* EXPORT command will save encrypted IMEM to given address,
+	 * so later in resume, IMEM can be restored from the given
+	 * address.
+	 *
+	 * Size must be at least 64 kB.
+	 */
+	ret = ele_service_swap(priv,
+			       imem->phyaddr,
+			       ELE_IMEM_SIZE,
+			       ELE_IMEM_EXPORT);
+	if (ret < 0)
+		dev_err(priv->dev, "Failed to export IMEM\n");
+	else
+		dev_info(priv->dev,
+			 "Exported %d bytes of encrypted IMEM\n",
+			 ret);
+
+	return ret;
+}
+
+int se_restore_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem)
+{
+	struct ele_dev_info s_info;
+	int ret;
+
+	/* get info from ELE */
+	ret = ele_get_info(priv, &s_info);
+	if (ret) {
+		dev_err(priv->dev, "Failed to get info from ELE.\n");
+		return ret;
+	}
+	imem->state = s_info.d_addn_info.imem_state;
+
+	/* Get IMEM state, if 0xFE then import IMEM */
+	if (s_info.d_addn_info.imem_state == ELE_IMEM_STATE_BAD) {
+		/* IMPORT command will restore IMEM from the given
+		 * address, here size is the actual size returned by ELE
+		 * during the export operation
+		 */
+		ret = ele_service_swap(priv,
+				       imem->phyaddr,
+				       imem->size,
+				       ELE_IMEM_IMPORT);
+		if (ret) {
+			dev_err(priv->dev, "Failed to import IMEM\n");
+			goto exit;
+		}
+	} else
+		goto exit;
+
+	/* After importing IMEM, check if IMEM state is equal to 0xCA
+	 * to ensure IMEM is fully loaded and
+	 * ELE functionality can be used.
+	 */
+	ret = ele_get_info(priv, &s_info);
+	if (ret) {
+		dev_err(priv->dev, "Failed to get info from ELE.\n");
+		goto exit;
+	}
+	imem->state = s_info.d_addn_info.imem_state;
+
+	if (s_info.d_addn_info.imem_state == ELE_IMEM_STATE_OK)
+		dev_info(priv->dev, "Successfully restored IMEM\n");
+	else
+		dev_err(priv->dev, "Failed to restore IMEM\n");
+
+exit:
+	return ret;
+}
diff --git a/drivers/firmware/imx/ele_common.h b/drivers/firmware/imx/ele_common.h
new file mode 100644
index 000000000000..3d8b6f83fb9d
--- /dev/null
+++ b/drivers/firmware/imx/ele_common.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+
+#ifndef __ELE_COMMON_H__
+#define __ELE_COMMON_H__
+
+#include "se_ctrl.h"
+
+#define ELE_SUCCESS_IND			0xD6
+
+#define IMX_ELE_FW_DIR                 "imx/ele/"
+
+uint32_t se_add_msg_crc(uint32_t *msg, uint32_t msg_len);
+int ele_msg_rcv(struct se_if_priv *priv,
+		struct se_clbk_handle *se_clbk_hdl);
+int ele_msg_send(struct se_if_priv *priv,
+		 void *tx_msg,
+		 int tx_msg_sz);
+int ele_msg_send_rcv(struct se_if_priv *priv,
+		     void *tx_msg,
+		     int tx_msg_sz,
+		     void *rx_msg,
+		     int exp_rx_msg_sz);
+void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg);
+int se_val_rsp_hdr_n_status(struct se_if_priv *priv,
+			    struct se_api_msg *msg,
+			    uint8_t msg_id,
+			    uint8_t sz,
+			    bool is_base_api);
+
+/* Fill a command message header with a given command ID and length in bytes. */
+static inline int se_fill_cmd_msg_hdr(struct se_if_priv *priv,
+				      struct se_msg_hdr *hdr,
+				      u8 cmd, u32 len,
+				      bool is_base_api)
+{
+	hdr->tag = priv->if_defs->cmd_tag;
+	hdr->ver = (is_base_api) ? priv->if_defs->base_api_ver : priv->if_defs->fw_api_ver;
+	hdr->command = cmd;
+	hdr->size = len >> 2;
+
+	return 0;
+}
+
+int se_save_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem);
+int se_restore_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem);
+
+#endif /*__ELE_COMMON_H__ */
diff --git a/drivers/firmware/imx/se_ctrl.c b/drivers/firmware/imx/se_ctrl.c
new file mode 100644
index 000000000000..7260a9f93e06
--- /dev/null
+++ b/drivers/firmware/imx/se_ctrl.c
@@ -0,0 +1,538 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/dev_printk.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/firmware.h>
+#include <linux/firmware/imx/se_api.h>
+#include <linux/genalloc.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/miscdevice.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/sys_soc.h>
+
+#include "ele_base_msg.h"
+#include "ele_common.h"
+#include "se_ctrl.h"
+
+#define MAX_SOC_INFO_DATA_SZ		256
+#define MBOX_TX_NAME			"tx"
+#define MBOX_RX_NAME			"rx"
+#define SE_TYPE_STR_HSM			"hsm"
+#define SE_TYPE_ID_HSM			0x2
+
+struct se_fw_img_name {
+	const u8 *prim_fw_nm_in_rfs;
+	const u8 *seco_fw_nm_in_rfs;
+};
+
+struct se_fw_load_info {
+	const struct se_fw_img_name *se_fw_img_nm;
+	bool is_fw_loaded;
+	bool handle_susp_resm;
+	struct se_imem_buf imem;
+};
+
+struct se_if_node_info {
+	u8 se_if_id;
+	u8 se_if_did;
+	struct se_if_defines if_defs;
+	u8 *pool_name;
+	bool reserved_dma_ranges;
+};
+
+/* contains fixed information */
+struct se_if_node_info_list {
+	const u8 num_mu;
+	const u16 soc_id;
+	bool soc_register;
+	int (*se_fetch_soc_info)(struct se_if_priv *priv, void *data);
+	const struct se_fw_img_name se_fw_img_nm;
+	const struct se_if_node_info info[];
+};
+
+struct se_var_info {
+	u16 soc_rev;
+	struct se_fw_load_info load_fw;
+};
+
+static struct se_var_info var_se_info = {
+	.soc_rev = 0,
+	.load_fw = {
+		.is_fw_loaded = true,
+		.handle_susp_resm = false,
+	},
+};
+
+static struct se_if_node_info_list imx8ulp_info = {
+	.num_mu = 1,
+	.soc_id = SOC_ID_OF_IMX8ULP,
+	.soc_register = true,
+	.se_fetch_soc_info = ele_fetch_soc_info,
+	.se_fw_img_nm = {
+		.prim_fw_nm_in_rfs = IMX_ELE_FW_DIR
+			"mx8ulpa2-ahab-container.img",
+		.seco_fw_nm_in_rfs = IMX_ELE_FW_DIR
+			"mx8ulpa2ext-ahab-container.img",
+	},
+	.info = {
+			{
+			.se_if_id = 0,
+			.se_if_did = 7,
+			.if_defs = {
+				.se_if_type = SE_TYPE_ID_HSM,
+				.se_instance_id = 0,
+				.cmd_tag = 0x17,
+				.rsp_tag = 0xe1,
+				.success_tag = ELE_SUCCESS_IND,
+				.base_api_ver = MESSAGING_VERSION_6,
+				.fw_api_ver = MESSAGING_VERSION_7,
+			},
+			.pool_name = "sram",
+			.reserved_dma_ranges = true,
+			},
+	},
+};
+
+static struct se_if_node_info_list imx93_info = {
+	.num_mu = 1,
+	.soc_id = SOC_ID_OF_IMX93,
+	.soc_register = false,
+	.se_fetch_soc_info = ele_fetch_soc_info,
+	.se_fw_img_nm = {
+		.prim_fw_nm_in_rfs = NULL,
+		.seco_fw_nm_in_rfs = NULL,
+	},
+	.info = {
+			{
+			.se_if_id = 2,
+			.se_if_did = 3,
+			.if_defs = {
+				.se_if_type = SE_TYPE_ID_HSM,
+				.se_instance_id = 0,
+				.cmd_tag = 0x17,
+				.rsp_tag = 0xe1,
+				.success_tag = ELE_SUCCESS_IND,
+				.base_api_ver = MESSAGING_VERSION_6,
+				.fw_api_ver = MESSAGING_VERSION_7,
+			},
+			.reserved_dma_ranges = true,
+			},
+	},
+};
+
+static const struct of_device_id se_match[] = {
+	{ .compatible = "fsl,imx8ulp-se", .data = (void *)&imx8ulp_info},
+	{ .compatible = "fsl,imx93-se", .data = (void *)&imx93_info},
+	{},
+};
+
+static int se_soc_info(struct se_if_priv *priv)
+{
+	const struct se_if_node_info_list *info_list
+			= device_get_match_data(priv->dev);
+	struct soc_device_attribute *attr;
+	struct ele_dev_info *s_info;
+	struct soc_device *sdev;
+	u8 data[MAX_SOC_INFO_DATA_SZ];
+	int err = 0;
+
+	/* This function should be called once.
+	 * Check if the se_soc_rev is zero to continue.
+	 */
+	if (var_se_info.soc_rev)
+		return err;
+
+	if (info_list->se_fetch_soc_info) {
+		err = info_list->se_fetch_soc_info(priv, &data);
+		if (err < 0) {
+			dev_err(priv->dev, "Failed to fetch SoC Info.");
+			return err;
+		}
+		s_info = (void *)data;
+		var_se_info.soc_rev = s_info->d_info.soc_rev;
+	} else {
+		dev_err(priv->dev, "Failed to fetch SoC revision.");
+		if (info_list->soc_register)
+			dev_err(priv->dev, "Failed to do SoC registration.");
+		err = -EINVAL;
+		return err;
+	}
+
+	if (!info_list->soc_register)
+		return 0;
+
+	attr = devm_kzalloc(priv->dev, sizeof(*attr), GFP_KERNEL);
+	if (!attr)
+		return -ENOMEM;
+
+	if (FIELD_GET(DEV_GETINFO_MIN_VER_MASK, var_se_info.soc_rev))
+		attr->revision = devm_kasprintf(priv->dev, GFP_KERNEL, "%x.%x",
+						FIELD_GET(DEV_GETINFO_MIN_VER_MASK,
+							  var_se_info.soc_rev),
+						FIELD_GET(DEV_GETINFO_MAJ_VER_MASK,
+							  var_se_info.soc_rev));
+	else
+		attr->revision = devm_kasprintf(priv->dev, GFP_KERNEL, "%x",
+						FIELD_GET(DEV_GETINFO_MAJ_VER_MASK,
+							  var_se_info.soc_rev));
+
+	switch (info_list->soc_id) {
+	case SOC_ID_OF_IMX8ULP:
+		attr->soc_id = devm_kasprintf(priv->dev, GFP_KERNEL,
+					      "i.MX8ULP");
+		break;
+	case SOC_ID_OF_IMX93:
+		attr->soc_id = devm_kasprintf(priv->dev, GFP_KERNEL,
+					      "i.MX93");
+		break;
+	}
+
+	err = of_property_read_string(of_root, "model",
+				      &attr->machine);
+	if (err)
+		return -EINVAL;
+
+	attr->family = devm_kasprintf(priv->dev, GFP_KERNEL, "Freescale i.MX");
+
+	attr->serial_number
+		= devm_kasprintf(priv->dev, GFP_KERNEL, "%016llX",
+				 GET_SERIAL_NUM_FROM_UID(s_info->d_info.uid, MAX_UID_SIZE >> 2));
+
+	sdev = soc_device_register(attr);
+	if (IS_ERR(sdev))
+		return PTR_ERR(sdev);
+
+	return 0;
+}
+
+static struct se_fw_load_info *get_load_fw_instance(struct se_if_priv *priv)
+{
+	return &var_se_info.load_fw;
+}
+
+static int se_load_firmware(struct se_if_priv *priv)
+{
+	struct se_fw_load_info *load_fw = get_load_fw_instance(priv);
+	const struct firmware *fw;
+	phys_addr_t se_fw_phyaddr;
+	const u8 *se_img_file_to_load;
+	u8 *se_fw_buf;
+	int ret;
+
+	if (load_fw->is_fw_loaded)
+		return 0;
+
+	se_img_file_to_load = load_fw->se_fw_img_nm->seco_fw_nm_in_rfs;
+	if (load_fw->se_fw_img_nm->prim_fw_nm_in_rfs) {
+		/* allocate buffer where SE store encrypted IMEM */
+		load_fw->imem.buf = dmam_alloc_coherent(priv->dev, ELE_IMEM_SIZE,
+							&load_fw->imem.phyaddr,
+							GFP_KERNEL);
+		if (!load_fw->imem.buf) {
+			dev_err(priv->dev,
+				"dmam-alloc-failed: To store encr-IMEM.\n");
+			ret = -ENOMEM;
+			goto exit;
+		}
+		if (load_fw->imem.state == ELE_IMEM_STATE_BAD)
+			se_img_file_to_load
+					= load_fw->se_fw_img_nm->prim_fw_nm_in_rfs;
+	}
+
+	do {
+		ret = request_firmware(&fw, se_img_file_to_load, priv->dev);
+		if (ret)
+			goto exit;
+
+		dev_info(priv->dev, "loading firmware %s\n", se_img_file_to_load);
+
+		/* allocate buffer to store the SE FW */
+		se_fw_buf = dma_alloc_coherent(priv->dev, fw->size,
+				&se_fw_phyaddr, GFP_KERNEL);
+		if (!se_fw_buf) {
+			ret = -ENOMEM;
+			goto exit;
+		}
+
+		memcpy(se_fw_buf, fw->data, fw->size);
+		ret = ele_fw_authenticate(priv, se_fw_phyaddr);
+		if (ret < 0) {
+			dev_err(priv->dev,
+					"Error %pe: Authenticate & load SE firmware %s.\n",
+					ERR_PTR(ret),
+					se_img_file_to_load);
+			ret = -EPERM;
+		}
+
+		dma_free_coherent(priv->dev,
+				  fw->size,
+				  se_fw_buf,
+				  se_fw_phyaddr);
+
+		release_firmware(fw);
+
+		if (!ret && load_fw->imem.state == ELE_IMEM_STATE_BAD &&
+				se_img_file_to_load == load_fw->se_fw_img_nm->prim_fw_nm_in_rfs)
+			se_img_file_to_load = load_fw->se_fw_img_nm->seco_fw_nm_in_rfs;
+		else
+			se_img_file_to_load = NULL;
+
+	} while (se_img_file_to_load);
+
+	if (!ret)
+		load_fw->is_fw_loaded = true;
+
+exit:
+	return ret;
+}
+
+/* interface for managed res to free a mailbox channel */
+static void if_mbox_free_channel(void *mbox_chan)
+{
+	mbox_free_channel(mbox_chan);
+}
+
+static int se_if_request_channel(struct device *dev,
+				 struct mbox_chan **chan,
+				 struct mbox_client *cl,
+				 const char *name)
+{
+	struct mbox_chan *t_chan;
+	int ret = 0;
+
+	t_chan = mbox_request_channel_byname(cl, name);
+	if (IS_ERR(t_chan)) {
+		ret = PTR_ERR(t_chan);
+		return dev_err_probe(dev, ret,
+				     "Failed to request %s channel.", name);
+	}
+
+	ret = devm_add_action(dev, if_mbox_free_channel, t_chan);
+	if (ret) {
+		dev_err(dev, "failed to add devm removal of mbox %s\n", name);
+		goto exit;
+	}
+
+	*chan = t_chan;
+
+exit:
+	return ret;
+}
+
+static void se_if_probe_cleanup(void *plat_dev)
+{
+	struct platform_device *pdev = plat_dev;
+	struct device *dev = &pdev->dev;
+	struct se_fw_load_info *load_fw;
+	struct se_if_priv *priv;
+
+	priv = dev_get_drvdata(dev);
+	load_fw = get_load_fw_instance(priv);
+
+	/* In se_if_request_channel(), passed the clean-up functional
+	 * pointer reference as action to devm_add_action().
+	 * No need to free the mbox channels here.
+	 */
+
+	/* free the buffer in se remove, previously allocated
+	 * in se probe to store encrypted IMEM
+	 */
+	if (load_fw && load_fw->imem.buf) {
+		dmam_free_coherent(dev,
+				   ELE_IMEM_SIZE,
+				   load_fw->imem.buf,
+				   load_fw->imem.phyaddr);
+		load_fw->imem.buf = NULL;
+	}
+
+	/* No need to check, if reserved memory is allocated
+	 * before calling for its release. Or clearing the
+	 * un-set bit.
+	 */
+	of_reserved_mem_device_release(dev);
+}
+
+static int se_if_probe(struct platform_device *pdev)
+{
+	const struct se_if_node_info_list *info_list;
+	const struct se_if_node_info *info;
+	struct device *dev = &pdev->dev;
+	struct se_fw_load_info *load_fw;
+	struct se_if_priv *priv;
+	u32 idx;
+	int ret;
+
+	idx = GET_IDX_FROM_DEV_NODE_NAME(dev->of_node);
+	info_list = device_get_match_data(dev);
+	if (idx >= info_list->num_mu) {
+		dev_err(dev,
+			"Incorrect node name :%s\n",
+			dev->of_node->full_name);
+		dev_err(dev,
+			"%s-<index>, acceptable index range is 0..%d\n",
+			dev->of_node->name,
+			info_list->num_mu - 1);
+		ret = -EINVAL;
+		return ret;
+	}
+
+	info = &info_list->info[idx];
+	if (!info) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	priv->dev = dev;
+	priv->if_defs = &info->if_defs;
+	dev_set_drvdata(dev, priv);
+
+	ret = devm_add_action(dev, se_if_probe_cleanup, pdev);
+	if (ret)
+		goto exit;
+
+
+	/* Mailbox client configuration */
+	priv->se_mb_cl.dev		= dev;
+	priv->se_mb_cl.tx_block		= false;
+	priv->se_mb_cl.knows_txdone	= true;
+	priv->se_mb_cl.rx_callback	= se_if_rx_callback;
+
+	ret = se_if_request_channel(dev, &priv->tx_chan,
+			&priv->se_mb_cl, MBOX_TX_NAME);
+	if (ret)
+		goto exit;
+
+	ret = se_if_request_channel(dev, &priv->rx_chan,
+			&priv->se_mb_cl, MBOX_RX_NAME);
+	if (ret)
+		goto exit;
+
+	mutex_init(&priv->se_if_cmd_lock);
+
+	init_completion(&priv->waiting_rsp_clbk_hdl.done);
+	init_completion(&priv->cmd_receiver_clbk_hdl.done);
+
+	if (info->pool_name) {
+		priv->mem_pool = of_gen_pool_get(dev->of_node,
+							 info->pool_name, 0);
+		if (!priv->mem_pool) {
+			dev_err(dev,
+				"Unable to get sram pool = %s\n",
+				info->pool_name);
+			goto exit;
+		}
+	}
+
+	if (info->reserved_dma_ranges) {
+		ret = of_reserved_mem_device_init(dev);
+		if (ret) {
+			dev_err(dev,
+				"failed to init reserved memory region %d\n",
+				ret);
+			goto exit;
+		}
+	}
+
+	if (info->if_defs.se_if_type == SE_TYPE_ID_HSM) {
+		ret = se_soc_info(priv);
+		if (ret) {
+			dev_err(dev,
+				"failed[%pe] to fetch SoC Info\n", ERR_PTR(ret));
+			goto exit;
+		}
+	}
+
+	/* By default, there is no pending FW to be loaded.*/
+	if (info_list->se_fw_img_nm.prim_fw_nm_in_rfs ||
+			info_list->se_fw_img_nm.seco_fw_nm_in_rfs) {
+		load_fw = get_load_fw_instance(priv);
+		load_fw->se_fw_img_nm = &info_list->se_fw_img_nm;
+
+		load_fw->is_fw_loaded = false;
+	}
+	dev_info(dev, "i.MX secure-enclave: %s%d interface to firmware, configured.\n",
+			SE_TYPE_STR_HSM,
+			priv->if_defs->se_instance_id);
+	return ret;
+
+exit:
+	/* if execution control reaches here, if probe fails.
+	 */
+	return dev_err_probe(dev, ret, "%s: Probe failed.", __func__);
+}
+
+static void se_if_remove(struct platform_device *pdev)
+{
+	se_if_probe_cleanup(pdev);
+}
+
+static int se_suspend(struct device *dev)
+{
+	struct se_if_priv *priv = dev_get_drvdata(dev);
+	struct se_fw_load_info *load_fw;
+	int ret = 0;
+
+	load_fw = get_load_fw_instance(priv);
+
+	if (load_fw->handle_susp_resm) {
+		ret = se_save_imem_state(priv, &load_fw->imem);
+		if (ret < 0)
+			goto exit;
+		load_fw->imem.size = ret;
+	}
+exit:
+	return ret;
+}
+
+static int se_resume(struct device *dev)
+{
+	struct se_if_priv *priv = dev_get_drvdata(dev);
+	struct se_fw_load_info *load_fw;
+
+	load_fw = get_load_fw_instance(priv);
+
+	if (load_fw->handle_susp_resm)
+		se_restore_imem_state(priv, &load_fw->imem);
+
+	return 0;
+}
+
+static const struct dev_pm_ops se_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(se_suspend, se_resume)
+};
+
+static struct platform_driver se_driver = {
+	.driver = {
+		.name = "fsl-se",
+		.of_match_table = se_match,
+		.pm = &se_pm,
+	},
+	.probe = se_if_probe,
+	.remove = se_if_remove,
+};
+MODULE_DEVICE_TABLE(of, se_match);
+
+module_platform_driver(se_driver);
+MODULE_AUTHOR("Pankaj Gupta <pankaj.gupta at nxp.com>");
+MODULE_DESCRIPTION("iMX Secure Enclave Driver.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/imx/se_ctrl.h b/drivers/firmware/imx/se_ctrl.h
new file mode 100644
index 000000000000..12c201b503b1
--- /dev/null
+++ b/drivers/firmware/imx/se_ctrl.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef SE_MU_H
+#define SE_MU_H
+
+#include <linux/miscdevice.h>
+#include <linux/semaphore.h>
+#include <linux/mailbox_client.h>
+
+#define MAX_FW_LOAD_RETRIES		50
+
+#define RES_STATUS(x)			FIELD_GET(0x000000ff, x)
+#define MAX_NVM_MSG_LEN			(256)
+#define MESSAGING_VERSION_6		0x6
+#define MESSAGING_VERSION_7		0x7
+#define NODE_NAME			"secure-enclave"
+
+#define GET_ASCII_TO_U8(diff, tens_chr, ones_chr) \
+		((diff > 2) ? (((tens_chr - '0') * 10) + (ones_chr - '0')) :\
+		(tens_chr - '0'))
+
+#define GET_IDX_FROM_DEV_NODE_NAME(dev_of_node) \
+		((strlen(dev_of_node->full_name) > strlen(NODE_NAME)) ?\
+		GET_ASCII_TO_U8((strlen(dev_of_node->full_name) - strlen(NODE_NAME)),\
+				dev_of_node->full_name[strlen(NODE_NAME) + 1], \
+				dev_of_node->full_name[strlen(NODE_NAME) + 2]) : 0)
+
+struct se_clbk_handle {
+	struct completion done;
+	bool signal_rcvd;
+	u32 rx_msg_sz;
+	/* Assignment of the rx_msg buffer to held till the
+	 * received content as part callback function, is copied.
+	 */
+	struct se_api_msg *rx_msg;
+};
+
+struct se_imem_buf {
+	u8 *buf;
+	phys_addr_t phyaddr;
+	u32 size;
+	u32 state;
+};
+
+/* Header of the messages exchange with the EdgeLock Enclave */
+struct se_msg_hdr {
+	u8 ver;
+	u8 size;
+	u8 command;
+	u8 tag;
+}  __packed;
+
+#define SE_MU_HDR_SZ	4
+
+struct se_api_msg {
+	struct se_msg_hdr header;
+	u32 data[];
+};
+
+struct se_if_defines {
+	const u8 se_if_type;
+	const u8 se_instance_id;
+	u8 cmd_tag;
+	u8 rsp_tag;
+	u8 success_tag;
+	u8 base_api_ver;
+	u8 fw_api_ver;
+};
+
+struct se_if_priv {
+	struct device *dev;
+
+	struct se_clbk_handle cmd_receiver_clbk_hdl;
+	/* Update to the waiting_rsp_dev, to be protected
+	 * under se_if_cmd_lock.
+	 */
+	struct se_clbk_handle waiting_rsp_clbk_hdl;
+	/*
+	 * prevent new command to be sent on the se interface while previous
+	 * command is still processing. (response is awaited)
+	 */
+	struct mutex se_if_cmd_lock;
+
+	struct mbox_client se_mb_cl;
+	struct mbox_chan *tx_chan, *rx_chan;
+
+	struct gen_pool *mem_pool;
+	const struct se_if_defines *if_defs;
+};
+
+#endif
diff --git a/include/linux/firmware/imx/se_api.h b/include/linux/firmware/imx/se_api.h
new file mode 100644
index 000000000000..c47f84906837
--- /dev/null
+++ b/include/linux/firmware/imx/se_api.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __SE_API_H__
+#define __SE_API_H__
+
+#include <linux/types.h>
+
+#define SOC_ID_OF_IMX8ULP		0x084D
+#define SOC_ID_OF_IMX93			0x9300
+
+#endif /* __SE_API_H__ */

-- 
2.34.1



From pankaj.gupta at nxp.com  Thu Dec 19 10:57:21 2024
From: pankaj.gupta at nxp.com (Pankaj Gupta)
Date: Fri, 20 Dec 2024 00:27:21 +0530
Subject: [PATCH v11 0/5] v11: firmware: imx: driver for NXP secure-enclave
Message-ID: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>

Changes in v11:

5/5
- devname is constructed by concatinating get_se_if_name(se_if_id) & se_if_instance_id.
- ele_rcv_msg(), is updated to add the wait_interruptible_timeout for the non-NVM-Daemon message exchanges, such that in case of no response from FW,
  Linux donot hangs.
- added a new helper function get_se_if_name(), to return the secure-enclave interface owner's name string.
- added a new helper function get_se_soc_id(), to return the secure-enclave's SoC id.

4/5
- moved the se_if_node_info member "soc_register", to the struct "se_if_node_info_list"; as soc registration done once, not per interface.
- moved the se_if_node_info member "se_fetch_soc_info", to the struct "se_if_node_info_list"; as soc info fetching is done once, not per interface.
- Added two member variable se_if_id and se_if_instance_id to struct se_if_defines.
- removed the member "se_name" from struct "se_if_node_info". Rather, it will constructed by concatinating get_se_if_name(se_if_id) & se_if_instance_id.
- moved the static global variable "se_version", to the newly created structure "struct se_var_info".
- moved the member "struct se_fw_load_info load_fw" of "se_if_node_info_list", to the newly created structure "struct se_var_info".
- Replaced RUNTIME_PM_OPS with SET_SYSTEM_SLEEP_PM_OPS, in power-managment ops.

3/5
- No change

2/5
- No change

1/5
- No change

Reference:
- Link to v10: https://lore.kernel.org/r/20241104-imx-se-if-v10-0-bf06083cc97f at nxp.com

v10: firmware: imx: driver for NXP secure-enclave

Changes in v10:
5/5
- replaced the u8, u16, u32, u64, with __u8, __u16, __u32, __u64 in
  'include/uapi/linux/se_ioctl.h'.

4/5
- No change

3/5
- No change

2/5
- No change

1/5
- No change

Reference:
- Link to v9: https://lore.kernel.org/r/20241016-imx-se-if-v9-0-fd8fa0c04eab at nxp.com

Changes in v9:

4/5
- change se_if_remove function signature, required after rebase to v6.12-rc1.
- move the info->macros to a structure "struct se_if_defines if_defs".
- Removed "info" from "struct se_if_defines if_defs".
- Moved "mem_pool" from "struct se_if_defines if_defs" to "priv".
- Fetching "info" using container-of.

5/5
- Fetching "info" using container-of.
- Fixed issue reported by sparse.

Reference:
- Link to v8: https://lore.kernel.org/r/20241015-imx-se-if-v8-0-915438e267d3 at nxp.com

Changes in v8:

5/5
- Remove the check for SE_IF_CTX_OPENED.
- replaced dev_ctx->priv-dev, priv->dev, whereever possible.
- func "if_misc_deregister" moved before func "init_device_context".
- func "init_device_context" before func "se_ioctl_cmd_snd_rcv_rsp_handler".
- func "se_if_fops_write" and "se_if_fops_read", are moved after func "se_ioctl_get_mu_info".
- non static functions "se_dev_ctx_cpy_out_data, se_dev_ctx_shared_mem_cleanup & init_device_context" are moved static and local scope.
- Removed back & forth between the two structs "struct se_if_device_ctx *dev_ctx" and "struct se_shared_mem_mgmt_info *se_shared_mem_mgmt"
- removed the NULL check for bdesc.
- fops_open, is corrected for acquiring the fops_lock.
- Fops_close, mutex unlock is removed. Infact check for waiting_rsp_clbk_hdl.dev_ctx, is removed.
- sema_init(&dev_ctx->fops_lock, 1);, replaced with Mutex.
- structure member se_notify, is removed.

4/5
- removed initializing err to zero in func ele_fetch_soc_info(),
- replaced 'return 0', with 'goto exit', if the condition (!priv->mem_pool) is true.
- replaced "struct *dev" with "struct se_if_priv *priv", in base_message API(s) and others.
- Created a separate structure "struct se_if_defines" to maintain interface's fixed values like cmd_tag, rsp_tag, success_tag etc.
- removed the macros "WORD_SZ", "SOC_VER_MASK", "DEFAULT_IMX_SOC_VER", "RESERVED_DMA_POOL".
- Added handling for "ctrl+c", by postponing the interrupt, till the response to the "command in flight" is received.
- Removed the mutext lock "se_if_lock".
- furnction prototype for "se_save_imem_state" and "se_restore_imem_state", is changed to pass "imem" by reference.
- Added a new structure "struct se_fw_load_info", dedicated to contain FW loading relevant info. It is a member of struct info_list.
- split "imem_mgmt_file_in_rfs" into two "prim_fw_nm_in_rfs" and "seco_fw_nm_in_rfs", to be part of "struct se_fw_load_info".
- moved the function "se_load_firmware" prior to func "if_mbox_free_channel".
- function "se_load_firmware" is updated to use "request_firmware", instead of "request_firmware_no_wait".
- function "se_load_firmware" is updated to load "primary" fw image, if the imem_state is not BAD. Then load the "secondary FW" image.
- Added a new mutex_lock in the function "se_load_firmware", for ensuring FW loading done once, when there are multiple application are in play.
- instead of "wait_queue_head_t wq", used "sruct completion".
- add devm_add_action with action as se_if_probe_cleanup.

Reference:
- Link to v7: https://lore.kernel.org/r/20240904-imx-se-if-v7-0-5afd2ab74264 at nxp.com

Changes in v7:

5/5
- struct se_clbk_handle, is added with a member struct se_if_device_ctx *dev_ctx.
- func call to ele_miscdev_msg_rcv() & ele_miscdev_msg_send(), are removed.
- func se_ioctl_cmd_snd_rcv_rsp_handler(), is modified to remove the func call to ele_miscdev_msg_rcv() & ele_miscdev_msg_send()
- func se_ioctl_cmd_snd_rcv_rsp_handler is callig func ele_msg_send_rcv(), instead.
- Mutext "se_cmd_if_lock", handling is removed from this patch.
- func ele_miscdev_msg_send() is replaced with func ele_msg_send(), in fops_write.
- func ele_miscdev_msg_rcv() is replaced with func ele_msg_rcv(), in fops_read.
- fops_open is modified to create the new dev_ctx instance (using func init_device_context()), which is not registered as miscdev.
- Only one dev_ctx is registered as miscdev and its reference is stored in the struct se_if_priv, as priv_dev_ctx.
- Separate func cleanup_se_shared_mem() & func init_se_shared_mem(), for shared memory handling part of struct dev_ctx.
- Input param for func(s) ele_msg_rcv(), ele_msg_send() & ele_msg_send_rcv(), is replaced from struct se_if_priv to struct se_if_device_ctx.

4/5
- A new structure is defined name struct "se_clbk_handle", to contain members processed in mailbox call-back function.
- "struct se_if_priv" is modified to contain the two structures of "se_clbk_handle" - waiting_rsp_clbk_hdl & cmd_receiver_clbk_hdl.
- func ele_msg_rcv() is modified to take a new additional input reference param "struct se_clbk_handle *se_clbk_hdl".
- func ele_msg_send() is modified to take a new additional input tx_msg_sz.
- func ele_msg_send_rcv(), is modified to take 2 more inputs - tx_msg_sz & exp_rx_msg_sz.
- func se_val_rsp_hdr_n_status(), is modified to take input of rx_msg buffer, instead of header value, as input param.
- each caller of the func ele_msg_send_rcv(), is sending these two additional input params.
- func se_if_callback(), is modified to work on two structures of "se_clbk_handle" - waiting_rsp_clbk_hdl & cmd_receiver_clbk_hdl.
- Variable "max_dev_ctx", is removed from info & priv struture, as well its usage.
- New member variable "se_img_file_to_load", is added to structure "priv".
- Other member variables - rx_msg(ptr), rx_msg_sz, completion done & list of dev_ctxs, is removed from priv struture, along with their usage.
- func se_resume(), updated to wakeup the two "wq", part of "struct se_clbk_handle": priv->waiting_rsp_clbk_hdl & priv->cmd_receiver_clbk_hdl.

3/5
- Node name is changed from senclave-firmware at 0 to "secure-enclave"

2/5
- Node name is changed to "secure-enclave".

Reference:
- Link to v6: https://lore.kernel.org/r/20240722-imx-se-if-v6-0-ee26a87b824a at nxp.com

Changes in v6:

5/5
- replaced scope_gaurd with gaurd.

4/5
- replaced scope_gaurd with gaurd.
- remove reading the regs property from dtb.
- Added NULL check for priv data fetched from device, as a sanity check, for ele_base_msg apis)

3/5
- replace firmware with senclave-firmware.

2/5
- replace firmware with senclave-firmware.
- drop description for mbox
- Replaced "items:" with maxItems:1 for "memory-region"
- Replaced "items:" with maxItems:1 for "sram"
- remove regs property.
- remove "$nodename"

Reference:
- Link to v5: https://lore.kernel.org/r/20240712-imx-se-if-v5-0-66a79903a872 at nxp.com

Changes in v5:

2/5
- updated the description of mboxes
- updated the description & items for mbox-names.
- updated the description of memory-region
- move "additional properties: false" after allOf block.
- removed other example except one.

4/5
- Corrected the indentation in Kconfig.
- info members:mbox_tx_name & mbox_rx_name, are replaced with macros.

5/5
- Replaced "for  secure enclaves", with "for secure enclaves"
- Replaced "user space" with "userspace".
- End the line "[include]<linux/firmware/imx/ele_mu_ioctl.h>" with a period.

Reference:
- Link to v4: https://lore.kernel.org/r/20240705-imx-se-if-v4-0-52d000e18a1d at nxp.com

Changes in v4:

1/5
a. Removed - from EdgeLock Enclave.

b. Removed , after "Each of the above feature,"

c. replace "can exists" with "can exist".

d.
-messaging units(MU) per SE. Each co-existing 'se' can have one or multiple exclusive
-MU(s), dedicated to itself. None of the MU is shared between two SEs.
+messaging units(MU) per SE. Each co-existing SE can have one or multiple exclusive
+MUs, dedicated to itself. None of the MU is shared between two SEs.
 Communication of the MU is realized using the Linux mailbox driver.

e.
-All those SE interfaces 'se-if' that is/are dedicated to a particular SE, will be
-enumerated and provisioned under the very single 'SE' node.
+Although MU(s) is/are not shared between SE(s). But for SoC like i.MX95 which has
+multiple SE(s) like HSM, V2X-HSM, V2X-SHE; all the SE(s) and their interfaces 'se-if'
+that is/are dedicated to a particular SE will be enumerated and provisioned using the
+single compatible node("fsl,imx95-se").

f. Removed ",". Replaced for "Each 'se-if'," with "Each se-if'.

g. removed ","
-  This layer is responsible for ensuring the communication protocol, that is defined
+  This layer is responsible for ensuring the communication protocol that is defined

h. removed "-"
-  - FW can handle one command-message at a time.
+  - FW can handle one command message at a time.

i.
-  Using these multiple device contexts, that are getting multiplexed over a single MU,
-  user-space application(s) can call fops like write/read to send the command-message,
-  and read back the command-response-message to/from Firmware.
-  fops like read & write uses the above defined service layer API(s) to communicate with
+  Using these multiple device contexts that are getting multiplexed over a single MU,
+  userspace application(s) can call fops like write/read to send the command message,
+  and read back the command response message to/from Firmware.
+  fops like read & write use the above defined service layer API(s) to communicate with
   Firmware.

j. Uppercase for word "Linux".

2/5
a. Rephrased the description to remove list of phandles.

b. Moved required before allOf:
+required:
+  - compatible
+  - reg
+  - mboxes
+  - mbox-names
+
+additionalProperties: false
+
 allOf:

c. replaced not: required: with properties: <property-name>: false.
   # memory-region
-      not:
-        required:
-          - memory-region
+      properties:
+        memory-region: false

   # sram
-    else:
-      not:
-        required:
-          - sram

d. Reduced examples. keeping example of i.MX95.
e. node-name is changed to "firmware@<hex>"

3/5
- node name changed to "firmware@<hex>".

4/5
- used sizeof(*s_info)
- return early, rather than doing goto exit, in ele_get_info().
- Use upper_32_bits() and lower_32_bits()
- use rx_msg here instead of priv->rx_msg
- Moved the status check to validate_rsp_hdr. Rename the function to "se_val_rsp_hdr_n_status"
- typecasting removed header = (struct se_msg_hdr *) msg;
- Converted the API name with prefix imx_ele_* or imx_se_*, to ele_* and se_*, respectively.
- Removed the functions definition & declaration for: free_phybuf_mem_pool() & get_phybuf_mem_pool()
- removed the mbox_free_channel() calls from clean-up.
- Flag "priv->flags" is removed.
- Converted the int se_if_probe_cleanup() to void se_if_probe_cleanup().
- Replaced NULL initialization of structure members: priv->cmd_receiver_dev & priv->waiting_rsp_dev , with comments.
- Removed the function's declaration get_phy_buf_mem_pool1

5/5
Changes to Documentation/ABI/testing/se-cdev.
a. Removed "-" from "secure-enclave" and "file-descriptor".

b. Removed "-" from "shared-library"

c. Replaced "get" with "getting".

d. Added description for the new IOCTL "send command and receive command response"

e. Replaced "wakeup_intruptible" with "wait_event_interruptible"

f. Removed ";"

g. Removd "," from "mailbox_lock,"

h. Replaced "free" with "frees"

i. In mailbox callback function, checking the buffer size before
copying.

Reference:
- Link to v3: https://lore.kernel.org/r/20240617-imx-se-if-v3-0-a7d28dea5c4a at nxp.com

Changes in v3:
5/5:
- Initialize tx_msg with NULL.
- memdup_user() returns an error pointer, not NULL. correct it by adding check for err_ptr.
- new IOCTL is added to send & recieve the message.
- replaced the while loop till list is empty, with list_for_each_entry.
- replaced __list_del_entry, with list_del.
- Removed the dev_err message from copy to user.
- Removed the casting of void *.
- corrected the typcasting in copy to user.
- removed un-necessary goto statement.
- Removed dead code for clean-up of memory.
- Removed un-mapping of secured memory
- Passing se_if_priv structure to init_device_context.
- Updated the below check to replace io.length with round_up(io.length).
	if (shared_mem->size < shared_mem->pos|| io.length >= shared_mem->size - shared_mem->pos)
- Created a function to cleanup the list of shared memory buffers.
- Used list_for_each_entry_safe(). created a separate functions: se_dev_ctx_cpy_out_data() & se_dev_ctx_shared_mem_cleanup()

4/5
- Changed the compatible string to replace "-ele", to "-se".
- Declaration of imx_se_node_info, is done as const in the whole file
- Remove the unused macros from ele_base_msg.h
- Remove the function declaration get_phy_buf_mem_pool1, from the header file.
- Replace the use of dmam_alloc_coherent to dma_alloc_coherent
- Check for function pointer, before calling the fucntion pointer in imx_fetch_se_soc_info
- Removed the unused flag for SE_MU_IO_FLAGS_USE_SEC_MEM.
-  Removed the unused macros WORD_SZ
- instead of struct device *dev, struct se_if_priv *priv, is used as argument to the funtions:se_save_imem_state, se_restore_imem_state, imx_fetch_se_soc_info
- Removed ret from validate_rsp_hdr.
- changed the prefix of the funtion: plat_add_msg_crc and plat_fill_cmd_msg_hdr.
- indentation correction for info structures.
- remove the check for priv not null from se_if_probe_cleanup
- Removed the casting of void *.
- se_load_firmware function is corrected for not freeing the buffer when allocation fails.
- Checking if get_imx_se_node_info() can return NULL, in se_if_probe()
- imem.size has type u32. return value from se_save_imem_state() will be assigned to imem.size in case of success only.
- removed the flag un-setting in case of failure. priv->flags &= (~RESERVED_DMA_POOL);
- removed the function call for devm_of_platform_populate(dev);
- Checking for not-NULL,  before calling the funtion pointer se_fetch_soc_info.
- Removed the checking for reserved memory flag, before freeing up the reserved memory, in se_probe_if_cleanup.

3/5
- Changed the compatible string to replace "-ele", to "-se".

2/5
- to fix the warning error, replaced the "-ele" & "-v2x" in compatible string, to "-se".
- Added an example for ele at 0 for compatible string "fsl,imx95-se"

Reference
- Link to v2: https://lore.kernel.org/r/20240523-imx-se-if-v2-0-5a6fd189a539 at nxp.com

Changes in v2:

4/4
- Split this patch into two: 1. base driver & 2. Miscdev
- Initialize the return variable "err" as 0, before calling 'return err', in the file ele_common.c
- Fix the usage of un-iniitialized pointer variable, by initializing them with NULL, in ele_base_msg.c.
- Fix initializing the ret variable, to return the correct error code in case of issue.
- replaced dmam_alloc_coherent with dma_alloc_coherent.
- Replace the use of ELE_GET_INFO_READ_SZ, with sizeof(soc_info).
- Replaced -1 with -EPERM
- Removed the safety check on func-input param, in ele_get_info().
- fix the assigning data[1] with lower 32 address, rather than zero, for ele_fw_authenticate API.
- Correctly initializing the function's return error code, for file  ele_base_msg.c.
- replaced 'return' with 'goto'.
- Use length in bytes.
- Corrected the structure se_msg_hdr.
- Moved setting of rx_msg  to priv, into the function imx_ele_msg_send_rcv
- Will add lockdep_assert_held, to receive path, in v2.
- corrected the spacing at "ret  = validate_rsp_hdr"
- FIELD_GET() used for RES_STATUS
- Re-write the structure soc_info, matching the information provided in response to this api.
- The "|" goes to the end of the previous line.
- Moved the locking and unlocking of the command lock to the caller of the function.
- removed the safety check for device private data.
- Structure memory reference, used to read message header.
- In the interrupt call back function, remove assigning waiting_rsp_dev to NULL, in case of response message rcv from FW.
- do while removed.
- replaced BIT(1) for RESERVED_DMA_POOL, to BIT(0)
- The backslash is removed while assigning the file name with absolute path to structure variable.fw_name_in_rfs =.
- Update the 'if' condition by removing "idx < 0".
- mbox_request_channel_byname() uses a "char" for the name not a u8. Corrected.
- devm managed resources, are not cleaned now, in function se_probe_if_cleanup
- Used dev_err_probe().
- Used %pe to print error string.
- remove "__maybe_unused" for "struct platform_device *enum_plat_dev __maybe_unused;"
- used FIELD_GET(), for  RES_STATUS. Removed the use of MSG_TAG, MSG_COMMAND, MSG_SIZE, MSG_VER.
- Depricated the used of member of struct se_if_priv, bool no_dev_ctx_used;
- Moved the text explaing the synchronization logic via mutexes, from patch 1/4 to se_ctrl.h.
- removed the type casting of info_list = (struct imx_se_node_info_list *) device_get_match_data(dev->parent);
- Used static variable priv->soc_rev in the se_ctrl.c, replaced the following condition: if (info_list->soc_rev) to if (priv->soc_rev) for checking if this flow is already executed or not.
- imx_fetch_soc_info will return failure if the get_info function fails.
- Removed devm_free from imx_fetch_soc_info too.

3/3
- Made changes to move all the properties to parent node, without any child node.

2/4
- Use Hex pattern string.
- Move the properties to parent node, with no child node.
- Add i.MX95-ele to compatible nodes to fix the warning "/example-2/v2x: failed to match any schema with compatible: ['fsl,imx95-v2x']"

1/1
- Corrected the spelling from creats to creates.
- drop the braces around the plural 's' for interfaces
- written se in upper case SE.
- Replace "multiple message(s)" with messages.
- Removed too much details about locks.

Testing
- make CHECK_DTBS=y freescale/imx8ulp-evk.dtb;
- make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8  dt_binding_check DT_SCHEMA_FILES=fsl,imx-se.yaml
- make C=1 CHECK=scripts/coccicheck drivers/firmware/imx/*.* W=1 > r.txt
- ./scripts/checkpatch.pl --git <>..HEAD
- Tested the Image and .dtb, on the i.MX8ULP.

Reference
- Link to v1: https://lore.kernel.org/r/20240510-imx-se-if-v1-0-27c5a674916d at nxp.com

---
Pankaj Gupta (5):
      Documentation/firmware: add imx/se to other_interfaces
      dt-bindings: arm: fsl: add imx-se-fw binding doc
      arm64: dts: imx8ulp-evk: add nxp secure enclave firmware
      firmware: imx: add driver for NXP EdgeLock Enclave
      firmware: imx: adds miscdev

 Documentation/ABI/testing/se-cdev                  |   43 +
 .../devicetree/bindings/firmware/fsl,imx-se.yaml   |   91 ++
 .../driver-api/firmware/other_interfaces.rst       |  121 ++
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts      |   17 +-
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi         |   13 +-
 drivers/firmware/imx/Kconfig                       |   13 +
 drivers/firmware/imx/Makefile                      |    2 +
 drivers/firmware/imx/ele_base_msg.c                |  273 ++++
 drivers/firmware/imx/ele_base_msg.h                |   94 ++
 drivers/firmware/imx/ele_common.c                  |  358 ++++++
 drivers/firmware/imx/ele_common.h                  |   51 +
 drivers/firmware/imx/se_ctrl.c                     | 1323 ++++++++++++++++++++
 drivers/firmware/imx/se_ctrl.h                     |  136 ++
 include/linux/firmware/imx/se_api.h                |   14 +
 include/uapi/linux/se_ioctl.h                      |  101 ++
 15 files changed, 2647 insertions(+), 3 deletions(-)
---
base-commit: 607c67544a955d27a91698aaa00a5f7fd0d7d14c
change-id: 20240507-imx-se-if-a40055093dc6

Best regards,
-- 
Pankaj Gupta <pankaj.gupta at nxp.com>



From pankaj.gupta at nxp.com  Thu Dec 19 10:57:22 2024
From: pankaj.gupta at nxp.com (Pankaj Gupta)
Date: Fri, 20 Dec 2024 00:27:22 +0530
Subject: [PATCH v11 1/5] Documentation/firmware: add imx/se to
 other_interfaces
In-Reply-To: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
References: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
Message-ID: <20241220-imx-se-if-v11-1-0c7e65d7ae7b@nxp.com>

Documents i.MX SoC's Service layer and C_DEV driver for selected SoC(s)
that contains the NXP hardware IP(s) for Secure Enclaves(se) like:
- NXP EdgeLock Enclave on i.MX93 & i.MX8ULP

Signed-off-by: Pankaj Gupta <pankaj.gupta at nxp.com>
---
 .../driver-api/firmware/other_interfaces.rst       | 121 +++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/Documentation/driver-api/firmware/other_interfaces.rst b/Documentation/driver-api/firmware/other_interfaces.rst
index 06ac89adaafb..a3a95b54a174 100644
--- a/Documentation/driver-api/firmware/other_interfaces.rst
+++ b/Documentation/driver-api/firmware/other_interfaces.rst
@@ -49,3 +49,124 @@ of the requests on to a secure monitor (EL3).
 
 .. kernel-doc:: drivers/firmware/stratix10-svc.c
    :export:
+
+NXP Secure Enclave Firmware Interface
+=====================================
+
+Introduction
+------------
+The NXP's i.MX HW IP like EdgeLock Enclave, V2X etc., creates an embedded secure
+enclave within the SoC boundary to enable features like
+ - Hardware Security Module (HSM)
+ - Security Hardware Extension (SHE)
+ - Vehicular to Anything (V2X)
+
+Each of the above feature is enabled through dedicated NXP H/W IP on the SoC.
+On a single SoC, multiple hardware IP (or can say more than one secure enclave)
+can exist.
+
+NXP SoCs enabled with the such secure enclaves(SEs) IPs are:
+i.MX93, i.MX8ULP
+
+To communicate with one or more co-existing SE(s) on SoC, there is/are dedicated
+messaging units(MU) per SE. Each co-existing SE can have one or multiple exclusive
+MUs, dedicated to itself. None of the MU is shared between two SEs.
+Communication of the MU is realized using the Linux mailbox driver.
+
+NXP Secure Enclave(SE) Interface
+--------------------------------
+Although MU(s) is/are not shared between SE(s). But for SoC like i.MX95 which has
+multiple SE(s) like HSM, V2X-HSM, V2X-SHE; all the SE(s) and their interfaces 'se-if'
+that is/are dedicated to a particular SE will be enumerated and provisioned using the
+single compatible node("fsl,imx95-se").
+
+Each 'se-if' comprise of twp layers:
+- (C_DEV Layer) User-Space software-access interface.
+- (Service Layer) OS-level software-access interface.
+
+   +--------------------------------------------+
+   |            Character Device(C_DEV)         |
+   |                                            |
+   |   +---------+ +---------+     +---------+  |
+   |   | misc #1 | | misc #2 | ... | misc #n |  |
+   |   |  dev    | |  dev    |     | dev     |  |
+   |   +---------+ +---------+     +---------+  |
+   |        +-------------------------+         |
+   |        | Misc. Dev Synchr. Logic |         |
+   |        +-------------------------+         |
+   |                                            |
+   +--------------------------------------------+
+
+   +--------------------------------------------+
+   |               Service Layer                |
+   |                                            |
+   |      +-----------------------------+       |
+   |      | Message Serialization Logic |       |
+   |      +-----------------------------+       |
+   |          +---------------+                 |
+   |          |  imx-mailbox  |                 |
+   |          |   mailbox.c   |                 |
+   |          +---------------+                 |
+   |                                            |
+   +--------------------------------------------+
+
+- service layer:
+  This layer is responsible for ensuring the communication protocol that is defined
+  for communication with firmware.
+
+  FW Communication protocol ensures two things:
+  - Serializing the messages to be sent over an MU.
+
+  - FW can handle one command message at a time.
+
+- c_dev:
+  This layer offers character device contexts, created as '/dev/<se>_mux_chx'.
+  Using these multiple device contexts that are getting multiplexed over a single MU,
+  userspace application(s) can call fops like write/read to send the command message,
+  and read back the command response message to/from Firmware.
+  fops like read & write use the above defined service layer API(s) to communicate with
+  Firmware.
+
+  Misc-device(/dev/<se>_mux_chn) synchronization protocol:
+
+                                Non-Secure               +   Secure
+                                                         |
+                                                         |
+                  +---------+      +-------------+       |
+                  | se_fw.c +<---->+imx-mailbox.c|       |
+                  |         |      |  mailbox.c  +<-->+------+    +------+
+                  +---+-----+      +-------------+    | MU X +<-->+ ELE |
+                      |                               +------+    +------+
+                      +----------------+                 |
+                      |                |                 |
+                      v                v                 |
+                  logical           logical              |
+                  receiver          waiter               |
+                     +                 +                 |
+                     |                 |                 |
+                     |                 |                 |
+                     |            +----+------+          |
+                     |            |           |          |
+                     |            |           |          |
+              device_ctx     device_ctx     device_ctx   |
+                                                         |
+                User 0        User 1       User Y        |
+                +------+      +------+     +------+      |
+                |misc.c|      |misc.c|     |misc.c|      |
+ kernel space   +------+      +------+     +------+      |
+                                                         |
+ +------------------------------------------------------ |
+                    |             |           |          |
+ userspace     /dev/ele_muXch0    |           |          |
+                          /dev/ele_muXch1     |          |
+                                        /dev/ele_muXchY  |
+                                                         |
+
+When a user sends a command to the firmware, it registers its device_ctx
+as waiter of a response from firmware.
+
+Enclave's Firmware owns the storage management, over Linux filesystem.
+For this c_dev provisions a dedicated slave device called "receiver".
+
+.. kernel-doc:: drivers/firmware/imx/se_fw.c
+   :export:

-- 
2.34.1



From pankaj.gupta at nxp.com  Thu Dec 19 10:57:23 2024
From: pankaj.gupta at nxp.com (Pankaj Gupta)
Date: Fri, 20 Dec 2024 00:27:23 +0530
Subject: [PATCH v11 2/5] dt-bindings: arm: fsl: add imx-se-fw binding doc
In-Reply-To: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
References: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
Message-ID: <20241220-imx-se-if-v11-2-0c7e65d7ae7b@nxp.com>

The NXP security hardware IP(s) like: i.MX EdgeLock Enclave, V2X etc.,
creates an embedded secure enclave within the SoC boundary to enable
features like:
- HSM
- SHE
- V2X

Secure-Enclave(s) communication interface are typically via message
unit, i.e., based on mailbox linux kernel driver. This driver enables
communication ensuring well defined message sequence protocol between
Application Core and enclave's firmware.

Driver configures multiple misc-device on the MU, for multiple
user-space applications, to be able to communicate over single MU.

It exists on some i.MX processors. e.g. i.MX8ULP, i.MX93 etc.

Signed-off-by: Pankaj Gupta <pankaj.gupta at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Reviewed-by: Conor Dooley <conor at kernel.org>
---
 .../devicetree/bindings/firmware/fsl,imx-se.yaml   | 91 ++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/fsl,imx-se.yaml b/Documentation/devicetree/bindings/firmware/fsl,imx-se.yaml
new file mode 100644
index 000000000000..0b617f61640f
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/fsl,imx-se.yaml
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/fsl,imx-se.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX HW Secure Enclave(s) EdgeLock Enclave
+
+maintainers:
+  - Pankaj Gupta <pankaj.gupta at nxp.com>
+
+description: |
+  NXP's SoC may contain one or multiple embedded secure-enclave HW
+  IP(s) like i.MX EdgeLock Enclave, V2X etc. These NXP's HW IP(s)
+  enables features like
+    - Hardware Security Module (HSM),
+    - Security Hardware Extension (SHE), and
+    - Vehicular to Anything (V2X)
+
+  Communication interface to the secure-enclaves(se) is based on the
+  messaging unit(s).
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8ulp-se
+      - fsl,imx93-se
+      - fsl,imx95-se
+
+  mboxes:
+    items:
+      - description: mailbox phandle to send message to se firmware
+      - description: mailbox phandle to receive message from se firmware
+
+  mbox-names:
+    items:
+      - const: tx
+      - const: rx
+
+  memory-region:
+    maxItems: 1
+
+  sram:
+    maxItems: 1
+
+required:
+  - compatible
+  - mboxes
+  - mbox-names
+
+allOf:
+  # memory-region
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx8ulp-se
+              - fsl,imx93-se
+    then:
+      required:
+        - memory-region
+    else:
+      properties:
+        memory-region: false
+
+  # sram
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx8ulp-se
+    then:
+      required:
+        - sram
+
+    else:
+      properties:
+        sram: false
+
+additionalProperties: false
+
+examples:
+  - |
+    secure-enclave {
+      compatible = "fsl,imx95-se";
+      mboxes = <&ele_mu0 0 0>, <&ele_mu0 1 0>;
+      mbox-names = "tx", "rx";
+    };
+...

-- 
2.34.1



From pankaj.gupta at nxp.com  Thu Dec 19 10:57:24 2024
From: pankaj.gupta at nxp.com (Pankaj Gupta)
Date: Fri, 20 Dec 2024 00:27:24 +0530
Subject: [PATCH v11 3/5] arm64: dts: imx8ulp-evk: add nxp secure enclave
 firmware
In-Reply-To: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
References: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
Message-ID: <20241220-imx-se-if-v11-3-0c7e65d7ae7b@nxp.com>

Add support for NXP secure enclave called EdgeLock Enclave
firmware (se-fw) for imx8ulp-evk.

EdgeLock Enclave has a hardware limitation of restricted access to DDR
address: 0x80000000 to 0xAFFFFFFF, so reserve 1MB of DDR memory region
from 0x80000000.

Signed-off-by: Pankaj Gupta <pankaj.gupta at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts | 17 ++++++++++++++++-
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi    | 13 +++++++++++--
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index e937e5f8fa8b..f5963f4043c4 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
- * Copyright 2021 NXP
+ * Copyright 2021, 2024 NXP
  */
 
 /dts-v1/;
@@ -19,6 +19,17 @@ memory at 80000000 {
 		device_type = "memory";
 		reg = <0x0 0x80000000 0 0x80000000>;
 	};
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		ele_reserved: ele-reserved at 90000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x90000000 0 0x100000>;
+			no-map;
+		};
+	};
 
 	reserved-memory {
 		#address-cells = <2>;
@@ -204,6 +215,10 @@ &usdhc0 {
 	status = "okay";
 };
 
+&ele_if0 {
+	memory-region = <&ele_reserved>;
+};
+
 &fec {
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&pinctrl_enet>;
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index e32d5afcf4a9..f98629b7f4cc 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
- * Copyright 2021 NXP
+ * Copyright 2021, 2024 NXP
  */
 
 #include <dt-bindings/clock/imx8ulp-clock.h>
@@ -152,7 +152,7 @@ sosc: clock-sosc {
 		#clock-cells = <0>;
 	};
 
-	sram at 2201f000 {
+	sram0: sram at 2201f000 {
 		compatible = "mmio-sram";
 		reg = <0x0 0x2201f000 0x0 0x1000>;
 
@@ -167,6 +167,8 @@ scmi_buf: scmi-sram-section at 0 {
 	};
 
 	firmware {
+		#address-cells = <1>;
+		#size-cells = <0>;
 		scmi {
 			compatible = "arm,scmi-smc";
 			arm,smc-id = <0xc20000fe>;
@@ -184,6 +186,13 @@ scmi_sensor: protocol at 15 {
 				#thermal-sensor-cells = <1>;
 			};
 		};
+
+		ele_if0: secure-enclave {
+			 compatible = "fsl,imx8ulp-se";
+			 mbox-names = "tx", "rx";
+			 mboxes = <&s4muap 0 0>, <&s4muap 1 0>;
+			 sram = <&sram0>;
+		 };
 	};
 
 	cm33: remoteproc-cm33 {

-- 
2.34.1



From pankaj.gupta at nxp.com  Thu Dec 19 10:57:26 2024
From: pankaj.gupta at nxp.com (Pankaj Gupta)
Date: Fri, 20 Dec 2024 00:27:26 +0530
Subject: [PATCH v11 5/5] firmware: imx: adds miscdev
In-Reply-To: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
References: <20241220-imx-se-if-v11-0-0c7e65d7ae7b@nxp.com>
Message-ID: <20241220-imx-se-if-v11-5-0c7e65d7ae7b@nxp.com>

Adds the driver for communication interface to secure-enclave,
for exchanging messages with NXP secure enclave HW IP(s) like
EdgeLock Enclave from:
- User-Space Applications via character driver.

ABI documentation for the NXP secure-enclave driver.

User-space library using this driver:
- i.MX Secure Enclave library:
  -- URL: https://github.com/nxp-imx/imx-secure-enclave.git,
- i.MX Secure Middle-Ware:
  -- URL: https://github.com/nxp-imx/imx-smw.git

Signed-off-by: Pankaj Gupta <pankaj.gupta at nxp.com>
---
 Documentation/ABI/testing/se-cdev   |  43 ++
 drivers/firmware/imx/ele_base_msg.c |   8 +-
 drivers/firmware/imx/ele_common.c   |  85 ++--
 drivers/firmware/imx/ele_common.h   |   6 +-
 drivers/firmware/imx/se_ctrl.c      | 791 +++++++++++++++++++++++++++++++++++-
 drivers/firmware/imx/se_ctrl.h      |  42 ++
 include/uapi/linux/se_ioctl.h       | 101 +++++
 7 files changed, 1041 insertions(+), 35 deletions(-)

diff --git a/Documentation/ABI/testing/se-cdev b/Documentation/ABI/testing/se-cdev
new file mode 100644
index 000000000000..3451c909ccc4
--- /dev/null
+++ b/Documentation/ABI/testing/se-cdev
@@ -0,0 +1,43 @@
+What:		/dev/<se>_mu[0-9]+_ch[0-9]+
+Date:		May 2024
+KernelVersion:	6.8
+Contact:	linux-imx at nxp.com, pankaj.gupta at nxp.com
+Description:
+		NXP offers multiple hardware IP(s) for secure enclaves like EdgeLock-
+		Enclave(ELE), SECO. The character device file descriptors
+		/dev/<se>_mu*_ch* are the interface between userspace NXP's secure-
+		enclave shared library and the kernel driver.
+
+		The ioctl(2)-based ABI is defined and documented in
+		[include]<linux/firmware/imx/ele_mu_ioctl.h>.
+		ioctl(s) are used primarily for:
+			- shared memory management
+			- allocation of I/O buffers
+			- getting mu info
+			- setting a dev-ctx as receiver to receive all the commands from FW
+			- getting SoC info
+			- send command and receive command response
+
+		The following file operations are supported:
+
+		open(2)
+		  Currently the only useful flags are O_RDWR.
+
+		read(2)
+		  Every read() from the opened character device context is waiting on
+		  wait_event_interruptible, that gets set by the registered mailbox callback
+		  function, indicating a message received from the firmware on message-
+		  unit.
+
+		write(2)
+		  Every write() to the opened character device context needs to acquire
+		  mailbox_lock before sending message on to the message unit.
+
+		close(2)
+		  Stops and frees up the I/O contexts that were associated
+		  with the file descriptor.
+
+Users:		https://github.com/nxp-imx/imx-secure-enclave.git,
+		https://github.com/nxp-imx/imx-smw.git
+		crypto/skcipher,
+		drivers/nvmem/imx-ocotp-ele.c
diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
index aa00e95d6aee..ff9a39530fa9 100644
--- a/drivers/firmware/imx/ele_base_msg.c
+++ b/drivers/firmware/imx/ele_base_msg.c
@@ -67,7 +67,7 @@ int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info)
 	tx_msg->data[0] = upper_32_bits(get_info_addr);
 	tx_msg->data[1] = lower_32_bits(get_info_addr);
 	tx_msg->data[2] = sizeof(*s_info);
-	ret = ele_msg_send_rcv(priv,
+	ret = ele_msg_send_rcv(priv->priv_dev_ctx,
 			       tx_msg,
 			       ELE_GET_INFO_REQ_MSG_SZ,
 			       rx_msg,
@@ -139,7 +139,7 @@ int ele_ping(struct se_if_priv *priv)
 		goto exit;
 	}
 
-	ret = ele_msg_send_rcv(priv,
+	ret = ele_msg_send_rcv(priv->priv_dev_ctx,
 			       tx_msg,
 			       ELE_PING_REQ_SZ,
 			       rx_msg,
@@ -194,7 +194,7 @@ int ele_service_swap(struct se_if_priv *priv,
 	tx_msg->data[3] = lower_32_bits(addr);
 	tx_msg->data[4] = se_add_msg_crc((uint32_t *)&tx_msg[0],
 						 ELE_SERVICE_SWAP_REQ_MSG_SZ);
-	ret = ele_msg_send_rcv(priv,
+	ret = ele_msg_send_rcv(priv->priv_dev_ctx,
 			       tx_msg,
 			       ELE_SERVICE_SWAP_REQ_MSG_SZ,
 			       rx_msg,
@@ -255,7 +255,7 @@ int ele_fw_authenticate(struct se_if_priv *priv, phys_addr_t addr)
 	tx_msg->data[0] = lower_32_bits(addr);
 	tx_msg->data[2] = addr;
 
-	ret = ele_msg_send_rcv(priv,
+	ret = ele_msg_send_rcv(priv->priv_dev_ctx,
 			       tx_msg,
 			       ELE_FW_AUTH_REQ_SZ,
 			       rx_msg,
diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
index 923eaa90cdd4..acabbccf3e36 100644
--- a/drivers/firmware/imx/ele_common.c
+++ b/drivers/firmware/imx/ele_common.c
@@ -18,38 +18,62 @@ u32 se_add_msg_crc(u32 *msg, u32 msg_len)
 	return crc;
 }
 
-int ele_msg_rcv(struct se_if_priv *priv,
+int ele_msg_rcv(struct se_if_device_ctx *dev_ctx,
 		struct se_clbk_handle *se_clbk_hdl)
 {
-	int err = 0;
+	struct se_if_priv *priv = dev_ctx->priv;
+	bool wait_timeout_enabled = true;
+	unsigned int wait;
+	int err;
 
 	do {
-		/* If callback is executed before entrying to wait state,
-		 * it will immediately come out after entering the wait state,
-		 * but completion_done(&se_clbk_hdl->done), will return false
-		 * after exiting the wait state, with err = 0.
-		 */
-		err = wait_for_completion_interruptible(&se_clbk_hdl->done);
+		if (priv->cmd_receiver_clbk_hdl.dev_ctx == dev_ctx) {
+			/* For NVM-D that are slaves of SE-FW, are waiting indefinitly
+			 * to receive the command from SE-FW.
+			 */
+			wait_timeout_enabled = false;
+
+			/* If callback is executed before entrying to wait state,
+			 * it will immediately come out after entering the wait state,
+			 * but completion_done(&se_clbk_hdl->done), will return false
+			 * after exiting the wait state, with err = 0.
+			 */
+			err = wait_for_completion_interruptible(&se_clbk_hdl->done);
+		} else {
+			/* FW must send the message response to application in a finite
+			 * time.
+			 */
+			wait = msecs_to_jiffies(10000);
+			err = wait_for_completion_interruptible_timeout(&se_clbk_hdl->done, wait);
+		}
 		if (err == -ERESTARTSYS) {
-			if (priv->waiting_rsp_clbk_hdl.rx_msg) {
+			if (priv->waiting_rsp_clbk_hdl.dev_ctx) {
 				priv->waiting_rsp_clbk_hdl.signal_rcvd = true;
 				continue;
 			}
-			dev_err(priv->dev,
-				"Err[0x%x]:Interrupted by signal.\n",
-				err);
 			err = -EINTR;
 			break;
 		}
-	} while (err != 0);
+		if (err == 0) {
+			if (wait_timeout_enabled) {
+				err = -ETIMEDOUT;
+				dev_err(priv->dev,
+					"Fatal Error: SE interface: %s%d, hangs indefinitely.\n",
+					get_se_if_name(priv->if_defs->se_if_type),
+					priv->if_defs->se_instance_id);
+			}
+			break;
+		}
+	} while (err < 0);
 
-	return err ? err : se_clbk_hdl->rx_msg_sz;
+	return (err >= 0) ? se_clbk_hdl->rx_msg_sz : err;
 }
 
-int ele_msg_send(struct se_if_priv *priv,
+int ele_msg_send(struct se_if_device_ctx *dev_ctx,
 		 void *tx_msg,
 		 int tx_msg_sz)
 {
+	struct se_if_priv *priv = dev_ctx->priv;
 	struct se_msg_hdr *header;
 	int err;
 
@@ -62,7 +86,8 @@ int ele_msg_send(struct se_if_priv *priv,
 	if (header->size << 2 != tx_msg_sz) {
 		err = -EINVAL;
 		dev_err(priv->dev,
-			"User buf hdr: 0x%x, sz mismatced with input-sz (%d != %d).",
+			"%s: User buf hdr: 0x%x, sz mismatced with input-sz (%d != %d).",
+			dev_ctx->devname,
 			*(u32 *)header,
 			header->size << 2, tx_msg_sz);
 		goto exit;
@@ -70,7 +95,9 @@ int ele_msg_send(struct se_if_priv *priv,
 
 	err = mbox_send_message(priv->tx_chan, tx_msg);
 	if (err < 0) {
-		dev_err(priv->dev, "Error: mbox_send_message failure.\n");
+		dev_err(priv->dev,
+			"%s: Error: mbox_send_message failure.",
+			dev_ctx->devname);
 		return err;
 	}
 	err = tx_msg_sz;
@@ -80,32 +107,36 @@ int ele_msg_send(struct se_if_priv *priv,
 }
 
 /* API used for send/receive blocking call. */
-int ele_msg_send_rcv(struct se_if_priv *priv,
+int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx,
 		     void *tx_msg,
 		     int tx_msg_sz,
 		     void *rx_msg,
 		     int exp_rx_msg_sz)
 {
 	int err;
+	struct se_if_priv *priv = dev_ctx->priv;
 
 	guard(mutex)(&priv->se_if_cmd_lock);
 
+	priv->waiting_rsp_clbk_hdl.dev_ctx = dev_ctx;
 	priv->waiting_rsp_clbk_hdl.rx_msg_sz = exp_rx_msg_sz;
 	priv->waiting_rsp_clbk_hdl.rx_msg = rx_msg;
 
-	err = ele_msg_send(priv, tx_msg, tx_msg_sz);
+	err = ele_msg_send(dev_ctx, tx_msg, tx_msg_sz);
 	if (err < 0)
 		goto exit;
 
-	err = ele_msg_rcv(priv, &priv->waiting_rsp_clbk_hdl);
+	err = ele_msg_rcv(dev_ctx, &priv->waiting_rsp_clbk_hdl);
 
 	if (priv->waiting_rsp_clbk_hdl.signal_rcvd) {
 		err = -EINTR;
 		priv->waiting_rsp_clbk_hdl.signal_rcvd = false;
 		dev_err(priv->dev,
-			"Err[0x%x]:Interrupted by signal.\n",
+			"%s: Err[0x%x]:Interrupted by signal.\n",
+			dev_ctx->devname,
 			err);
 	}
+	priv->waiting_rsp_clbk_hdl.dev_ctx = NULL;
 
 exit:
 	return err;
@@ -152,7 +183,8 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
 	if (header->tag == priv->if_defs->cmd_tag) {
 		se_clbk_hdl = &priv->cmd_receiver_clbk_hdl;
 		dev_dbg(dev,
-			"Selecting cmd receiver for mesg header:0x%x.",
+			"Selecting cmd receiver:%s for mesg header:0x%x.",
+			se_clbk_hdl->dev_ctx->devname,
 			*(u32 *) header);
 
 		/* Pre-allocated buffer of MAX_NVM_MSG_LEN
@@ -161,7 +193,8 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
 		 */
 		if (rx_msg_sz > MAX_NVM_MSG_LEN) {
 			dev_err(dev,
-				"CMD-RCVER NVM: hdr(0x%x) with different sz(%d != %d).\n",
+				"%s: CMD-RCVER NVM: hdr(0x%x) with different sz(%d != %d).\n",
+				se_clbk_hdl->dev_ctx->devname,
 				*(u32 *) header,
 				rx_msg_sz, se_clbk_hdl->rx_msg_sz);
 
@@ -172,13 +205,15 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
 	} else if (header->tag == priv->if_defs->rsp_tag) {
 		se_clbk_hdl = &priv->waiting_rsp_clbk_hdl;
 		dev_dbg(dev,
-			"Selecting resp waiter for mesg header:0x%x.",
+			"Selecting resp waiter:%s for mesg header:0x%x.",
+			se_clbk_hdl->dev_ctx->devname,
 			*(u32 *) header);
 
 		if (rx_msg_sz != se_clbk_hdl->rx_msg_sz
 				&& !exception_for_size(priv, header)) {
 			dev_err(dev,
-				"Rsp to CMD: hdr(0x%x) with different sz(%d != %d).\n",
+				"%s: Rsp to CMD: hdr(0x%x) with different sz(%d != %d).\n",
+				se_clbk_hdl->dev_ctx->devname,
 				*(u32 *) header,
 				rx_msg_sz, se_clbk_hdl->rx_msg_sz);
 
diff --git a/drivers/firmware/imx/ele_common.h b/drivers/firmware/imx/ele_common.h
index 3d8b6f83fb9d..9bded800c103 100644
--- a/drivers/firmware/imx/ele_common.h
+++ b/drivers/firmware/imx/ele_common.h
@@ -14,12 +14,12 @@
 #define IMX_ELE_FW_DIR                 "imx/ele/"
 
 uint32_t se_add_msg_crc(uint32_t *msg, uint32_t msg_len);
-int ele_msg_rcv(struct se_if_priv *priv,
+int ele_msg_rcv(struct se_if_device_ctx *dev_ctx,
 		struct se_clbk_handle *se_clbk_hdl);
-int ele_msg_send(struct se_if_priv *priv,
+int ele_msg_send(struct se_if_device_ctx *dev_ctx,
 		 void *tx_msg,
 		 int tx_msg_sz);
-int ele_msg_send_rcv(struct se_if_priv *priv,
+int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx,
 		     void *tx_msg,
 		     int tx_msg_sz,
 		     void *rx_msg,
diff --git a/drivers/firmware/imx/se_ctrl.c b/drivers/firmware/imx/se_ctrl.c
index 7260a9f93e06..ae90538af390 100644
--- a/drivers/firmware/imx/se_ctrl.c
+++ b/drivers/firmware/imx/se_ctrl.c
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/sys_soc.h>
+#include <uapi/linux/se_ioctl.h>
 
 #include "ele_base_msg.h"
 #include "ele_common.h"
@@ -31,8 +32,6 @@
 #define MAX_SOC_INFO_DATA_SZ		256
 #define MBOX_TX_NAME			"tx"
 #define MBOX_RX_NAME			"rx"
-#define SE_TYPE_STR_HSM			"hsm"
-#define SE_TYPE_ID_HSM			0x2
 
 struct se_fw_img_name {
 	const u8 *prim_fw_nm_in_rfs;
@@ -140,6 +139,25 @@ static const struct of_device_id se_match[] = {
 	{},
 };
 
+char *get_se_if_name(u8 se_if_id)
+{
+	switch (se_if_id) {
+	case SE_TYPE_ID_DBG: return SE_TYPE_STR_DBG;
+	case SE_TYPE_ID_HSM: return SE_TYPE_STR_HSM;
+	}
+
+	return NULL;
+}
+
+static uint32_t get_se_soc_id(struct se_if_priv *priv)
+{
+        const struct se_if_node_info_list *info_list
+                        = device_get_match_data(priv->dev);
+
+        return info_list->soc_id;
+
+}
+
 static int se_soc_info(struct se_if_priv *priv)
 {
 	const struct se_if_node_info_list *info_list
@@ -300,6 +318,756 @@ static int se_load_firmware(struct se_if_priv *priv)
 	return ret;
 }
 
+static int init_se_shared_mem(struct se_if_device_ctx *dev_ctx)
+{
+	struct se_shared_mem_mgmt_info *se_shared_mem_mgmt = &dev_ctx->se_shared_mem_mgmt;
+	struct se_if_priv *priv = dev_ctx->priv;
+
+	INIT_LIST_HEAD(&se_shared_mem_mgmt->pending_out);
+	INIT_LIST_HEAD(&se_shared_mem_mgmt->pending_in);
+
+	/*
+	 * Allocate some memory for data exchanges with S40x.
+	 * This will be used for data not requiring secure memory.
+	 */
+	se_shared_mem_mgmt->non_secure_mem.ptr
+			= dma_alloc_coherent(priv->dev,
+					     MAX_DATA_SIZE_PER_USER,
+					     &se_shared_mem_mgmt->non_secure_mem.dma_addr,
+					     GFP_KERNEL);
+	if (!se_shared_mem_mgmt->non_secure_mem.ptr)
+		return -ENOMEM;
+
+	se_shared_mem_mgmt->non_secure_mem.size = MAX_DATA_SIZE_PER_USER;
+	se_shared_mem_mgmt->non_secure_mem.pos = 0;
+
+	return 0;
+}
+
+static void cleanup_se_shared_mem(struct se_if_device_ctx *dev_ctx)
+{
+	struct se_shared_mem_mgmt_info *se_shared_mem_mgmt = &dev_ctx->se_shared_mem_mgmt;
+	struct se_if_priv *priv = dev_ctx->priv;
+
+	/* Unmap secure memory shared buffer. */
+	if (se_shared_mem_mgmt->secure_mem.ptr)
+		devm_iounmap(priv->dev,
+				(void __iomem *)se_shared_mem_mgmt->secure_mem.ptr);
+
+	se_shared_mem_mgmt->secure_mem.ptr = NULL;
+	se_shared_mem_mgmt->secure_mem.dma_addr = 0;
+	se_shared_mem_mgmt->secure_mem.size = 0;
+	se_shared_mem_mgmt->secure_mem.pos = 0;
+
+	/* Free non-secure shared buffer. */
+	dma_free_coherent(priv->dev, MAX_DATA_SIZE_PER_USER,
+			  se_shared_mem_mgmt->non_secure_mem.ptr,
+			  se_shared_mem_mgmt->non_secure_mem.dma_addr);
+
+	se_shared_mem_mgmt->non_secure_mem.ptr = NULL;
+	se_shared_mem_mgmt->non_secure_mem.dma_addr = 0;
+	se_shared_mem_mgmt->non_secure_mem.size = 0;
+	se_shared_mem_mgmt->non_secure_mem.pos = 0;
+}
+
+/* Need to copy the output data to user-device context.
+ */
+static int se_dev_ctx_cpy_out_data(struct se_if_device_ctx *dev_ctx)
+{
+	struct se_shared_mem_mgmt_info *se_shared_mem_mgmt = &dev_ctx->se_shared_mem_mgmt;
+	struct se_if_priv *priv = dev_ctx->priv;
+	struct se_buf_desc *b_desc, *temp;
+	bool do_cpy = true;
+
+	list_for_each_entry_safe(b_desc, temp, &se_shared_mem_mgmt->pending_out, link) {
+		if (b_desc->usr_buf_ptr && b_desc->shared_buf_ptr && do_cpy) {
+
+			dev_dbg(priv->dev,
+				"Copying output data to user.");
+			if (do_cpy && copy_to_user(b_desc->usr_buf_ptr,
+					 b_desc->shared_buf_ptr,
+					 b_desc->size)) {
+				dev_err(priv->dev,
+					"Failure copying output data to user.");
+				do_cpy = false;
+			}
+		}
+
+		if (b_desc->shared_buf_ptr)
+			memset(b_desc->shared_buf_ptr, 0, b_desc->size);
+
+		list_del(&b_desc->link);
+		kfree(b_desc);
+	}
+
+	return do_cpy ? 0 : -EFAULT;
+}
+
+/*
+ * Clean the used Shared Memory space,
+ * whether its Input Data copied from user buffers, or
+ * Data received from FW.
+ */
+static void se_dev_ctx_shared_mem_cleanup(struct se_if_device_ctx *dev_ctx)
+{
+	struct se_shared_mem_mgmt_info *se_shared_mem_mgmt = &dev_ctx->se_shared_mem_mgmt;
+	struct list_head *pending_lists[] = {&se_shared_mem_mgmt->pending_in,
+						&se_shared_mem_mgmt->pending_out};
+	struct se_buf_desc *b_desc, *temp;
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		list_for_each_entry_safe(b_desc, temp,
+					 pending_lists[i], link) {
+
+			if (b_desc->shared_buf_ptr)
+				memset(b_desc->shared_buf_ptr, 0, b_desc->size);
+
+			list_del(&b_desc->link);
+			kfree(b_desc);
+		}
+	}
+	se_shared_mem_mgmt->secure_mem.pos = 0;
+	se_shared_mem_mgmt->non_secure_mem.pos = 0;
+}
+
+static int add_b_desc_to_pending_list(void *shared_ptr_with_pos,
+			       struct se_ioctl_setup_iobuf *io,
+			       struct se_if_device_ctx *dev_ctx)
+{
+	struct se_shared_mem_mgmt_info *se_shared_mem_mgmt = &dev_ctx->se_shared_mem_mgmt;
+	struct se_buf_desc *b_desc = NULL;
+
+	b_desc = kzalloc(sizeof(*b_desc), GFP_KERNEL);
+	if (!b_desc)
+		return -ENOMEM;
+
+	b_desc->shared_buf_ptr = shared_ptr_with_pos;
+	b_desc->usr_buf_ptr = io->user_buf;
+	b_desc->size = io->length;
+
+	if (io->flags & SE_IO_BUF_FLAGS_IS_INPUT) {
+		/*
+		 * buffer is input:
+		 * add an entry in the "pending input buffers" list so
+		 * that copied data can be cleaned from shared memory
+		 * later.
+		 */
+		list_add_tail(&b_desc->link, &se_shared_mem_mgmt->pending_in);
+	} else {
+		/*
+		 * buffer is output:
+		 * add an entry in the "pending out buffers" list so data
+		 * can be copied to user space when receiving Secure-Enclave
+		 * response.
+		 */
+		list_add_tail(&b_desc->link, &se_shared_mem_mgmt->pending_out);
+	}
+
+	return 0;
+}
+
+/* interface for managed res to unregister a character device */
+static void if_misc_deregister(void *miscdevice)
+{
+	misc_deregister(miscdevice);
+}
+
+static int init_device_context(struct se_if_priv *priv, int ch_id,
+			struct se_if_device_ctx **new_dev_ctx,
+			const struct file_operations *se_if_fops)
+{
+	struct se_if_device_ctx *dev_ctx;
+	int ret = 0;
+
+	if (ch_id)
+		dev_ctx = kzalloc(sizeof(*dev_ctx), GFP_KERNEL);
+	else
+		dev_ctx = devm_kzalloc(priv->dev, sizeof(*dev_ctx), GFP_KERNEL);
+
+	if (!dev_ctx) {
+		ret = -ENOMEM;
+		return ret;
+	}
+
+	dev_ctx->priv = priv;
+
+	if (ch_id)
+		dev_ctx->devname = kasprintf(GFP_KERNEL, "%s%d_ch%d",
+					     get_se_if_name(priv->if_defs->se_if_type),
+					     priv->if_defs->se_instance_id,
+					     ch_id);
+	else
+		dev_ctx->devname = devm_kasprintf(priv->dev, GFP_KERNEL, "%s%d_ch%d",
+					     get_se_if_name(priv->if_defs->se_if_type),
+					     priv->if_defs->se_instance_id,
+					     ch_id);
+	if (!dev_ctx->devname) {
+		ret = -ENOMEM;
+		if (ch_id)
+			kfree(dev_ctx);
+
+		return ret;
+	}
+
+	mutex_init(&dev_ctx->fops_lock);
+
+	*new_dev_ctx = dev_ctx;
+
+	if (ch_id) {
+		list_add_tail(&dev_ctx->link, &priv->dev_ctx_list);
+		priv->active_devctx_count++;
+
+		ret = init_se_shared_mem(dev_ctx);
+		if (ret < 0) {
+			kfree(dev_ctx->devname);
+			kfree(dev_ctx);
+			*new_dev_ctx = NULL;
+			return ret;
+		}
+
+		return ret;
+	}
+
+	/* Only for ch_id = 0:
+	 * - register the misc device.
+	 * - add action
+	 */
+	dev_ctx->miscdev = devm_kzalloc(priv->dev, sizeof(*dev_ctx->miscdev), GFP_KERNEL);
+	if (!dev_ctx->miscdev) {
+		ret = -ENOMEM;
+		*new_dev_ctx = NULL;
+		return ret;
+	}
+
+	dev_ctx->miscdev->name = dev_ctx->devname;
+	dev_ctx->miscdev->minor = MISC_DYNAMIC_MINOR;
+	dev_ctx->miscdev->fops = se_if_fops;
+	dev_ctx->miscdev->parent = priv->dev;
+	ret = misc_register(dev_ctx->miscdev);
+	if (ret) {
+		dev_err(priv->dev, "failed to register misc device %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = devm_add_action(priv->dev, if_misc_deregister,
+			      dev_ctx->miscdev);
+	if (ret) {
+		dev_err(priv->dev,
+			"failed[%d] to add action to the misc-dev\n",
+			ret);
+		misc_deregister(dev_ctx->miscdev);
+	}
+
+	return ret;
+}
+
+static int se_ioctl_cmd_snd_rcv_rsp_handler(struct se_if_device_ctx *dev_ctx,
+					    u64 arg)
+{
+	struct se_ioctl_cmd_snd_rcv_rsp_info cmd_snd_rcv_rsp_info;
+	struct se_if_priv *priv = dev_ctx->priv;
+	struct se_api_msg *tx_msg __free(kfree) = NULL;
+	struct se_api_msg *rx_msg __free(kfree) = NULL;
+	int err = 0;
+
+	if (copy_from_user(&cmd_snd_rcv_rsp_info, (u8 __user *)arg,
+			   sizeof(cmd_snd_rcv_rsp_info))) {
+		dev_err(priv->dev,
+			"%s: Failed to copy cmd_snd_rcv_rsp_info from user\n",
+			dev_ctx->devname);
+		err = -EFAULT;
+		goto exit;
+	}
+
+	if (cmd_snd_rcv_rsp_info.tx_buf_sz < SE_MU_HDR_SZ) {
+		dev_err(priv->dev,
+			"%s: User buffer too small(%d < %d)\n",
+			dev_ctx->devname,
+			cmd_snd_rcv_rsp_info.tx_buf_sz,
+			SE_MU_HDR_SZ);
+		err = -ENOSPC;
+		goto exit;
+	}
+
+	rx_msg = kzalloc(cmd_snd_rcv_rsp_info.rx_buf_sz, GFP_KERNEL);
+	if (!rx_msg) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	tx_msg = memdup_user(cmd_snd_rcv_rsp_info.tx_buf,
+			     cmd_snd_rcv_rsp_info.tx_buf_sz);
+	if (IS_ERR(tx_msg)) {
+		err = PTR_ERR(tx_msg);
+		goto exit;
+	}
+
+	if (tx_msg->header.tag != priv->if_defs->cmd_tag) {
+		err = -EINVAL;
+		goto exit;
+	}
+
+	if (tx_msg->header.ver == priv->if_defs->fw_api_ver &&
+		!get_load_fw_instance(priv)->is_fw_loaded) {
+		err = se_load_firmware(priv);
+		if (err) {
+			dev_err(priv->dev, "Could not send the message as FW is not loaded.");
+			err = -EPERM;
+			goto exit;
+		}
+	}
+	err = ele_msg_send_rcv(dev_ctx,
+			       tx_msg,
+			       cmd_snd_rcv_rsp_info.tx_buf_sz,
+			       rx_msg,
+			       cmd_snd_rcv_rsp_info.rx_buf_sz);
+	if (err < 0)
+		goto exit;
+
+	dev_dbg(priv->dev,
+		"%s: %s %s\n",
+		dev_ctx->devname,
+		__func__,
+		"message received, start transmit to user");
+
+	/* We may need to copy the output data to user before
+	 * delivering the completion message.
+	 */
+	err = se_dev_ctx_cpy_out_data(dev_ctx);
+	if (err < 0)
+		goto exit;
+
+	/* Copy data from the buffer */
+	print_hex_dump_debug("to user ", DUMP_PREFIX_OFFSET, 4, 4,
+			     rx_msg,
+			     cmd_snd_rcv_rsp_info.rx_buf_sz, false);
+
+	if (copy_to_user(cmd_snd_rcv_rsp_info.rx_buf, rx_msg,
+			 cmd_snd_rcv_rsp_info.rx_buf_sz)) {
+		dev_err(priv->dev,
+			"%s: Failed to copy to user\n",
+			dev_ctx->devname);
+		err = -EFAULT;
+	}
+
+exit:
+	se_dev_ctx_shared_mem_cleanup(dev_ctx);
+
+	if (copy_to_user((void __user *)arg, &cmd_snd_rcv_rsp_info,
+			 sizeof(cmd_snd_rcv_rsp_info))) {
+		dev_err(priv->dev,
+			"%s: Failed to copy cmd_snd_rcv_rsp_info from user\n",
+			dev_ctx->devname);
+		err = -EFAULT;
+	}
+
+	return err;
+}
+
+static int se_ioctl_get_mu_info(struct se_if_device_ctx *dev_ctx,
+				u64 arg)
+{
+	struct se_if_priv *priv = dev_ctx->priv;
+	struct se_if_node_info *info;
+	struct se_ioctl_get_if_info if_info;
+	int err = 0;
+
+	info = container_of(priv->if_defs, typeof(*info), if_defs);
+
+	if_info.se_if_id = 0;
+	if_info.interrupt_idx = 0;
+	if_info.tz = 0;
+	if_info.did = info->se_if_did;
+	if_info.cmd_tag = priv->if_defs->cmd_tag;
+	if_info.rsp_tag = priv->if_defs->rsp_tag;
+	if_info.success_tag = priv->if_defs->success_tag;
+	if_info.base_api_ver = priv->if_defs->base_api_ver;
+	if_info.fw_api_ver = priv->if_defs->fw_api_ver;
+
+	dev_dbg(priv->dev,
+		"%s: info [se_if_id: %d, irq_idx: %d, tz: 0x%x, did: 0x%x]\n",
+			dev_ctx->devname,
+			if_info.se_if_id, if_info.interrupt_idx,
+			if_info.tz, if_info.did);
+
+	if (copy_to_user((u8 __user *)arg, &if_info, sizeof(if_info))) {
+		dev_err(priv->dev,
+			"%s: Failed to copy mu info to user\n",
+			dev_ctx->devname);
+		err = -EFAULT;
+		goto exit;
+	}
+
+exit:
+	return err;
+}
+
+/*
+ * Copy a buffer of data to/from the user and return the address to use in
+ * messages
+ */
+static int se_ioctl_setup_iobuf_handler(struct se_if_device_ctx *dev_ctx,
+					u64 arg)
+{
+	struct se_shared_mem *shared_mem = NULL;
+	struct se_ioctl_setup_iobuf io = {0};
+	int err = 0;
+	u32 pos;
+
+	if (copy_from_user(&io, (u8 __user *)arg, sizeof(io))) {
+		dev_err(dev_ctx->priv->dev,
+			"%s: Failed copy iobuf config from user\n",
+			dev_ctx->devname);
+		err = -EFAULT;
+		goto exit;
+	}
+
+	dev_dbg(dev_ctx->priv->dev,
+		"%s: io [buf: %p(%d) flag: %x]\n",
+		dev_ctx->devname,
+		io.user_buf, io.length, io.flags);
+
+	if (io.length == 0 || !io.user_buf) {
+		/*
+		 * Accept NULL pointers since some buffers are optional
+		 * in FW commands. In this case we should return 0 as
+		 * pointer to be embedded into the message.
+		 * Skip all data copy part of code below.
+		 */
+		io.ele_addr = 0;
+		goto copy;
+	}
+
+	/* No specific requirement for this buffer. */
+	shared_mem = &dev_ctx->se_shared_mem_mgmt.non_secure_mem;
+
+	/* Check there is enough space in the shared memory. */
+	dev_dbg(dev_ctx->priv->dev,
+		"%s: req_size = %d, max_size= %d, curr_pos = %d",
+		dev_ctx->devname,
+		round_up(io.length, 8u),
+		shared_mem->size, shared_mem->pos);
+
+	if (shared_mem->size < shared_mem->pos ||
+		round_up(io.length, 8u) > (shared_mem->size - shared_mem->pos)) {
+		dev_err(dev_ctx->priv->dev,
+			"%s: Not enough space in shared memory\n",
+			dev_ctx->devname);
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	/* Allocate space in shared memory. 8 bytes aligned. */
+	pos = shared_mem->pos;
+	shared_mem->pos += round_up(io.length, 8u);
+	io.ele_addr = (u64)shared_mem->dma_addr + pos;
+
+	memset(shared_mem->ptr + pos, 0, io.length);
+	if ((io.flags & SE_IO_BUF_FLAGS_IS_INPUT) ||
+	    (io.flags & SE_IO_BUF_FLAGS_IS_IN_OUT)) {
+		/*
+		 * buffer is input:
+		 * copy data from user space to this allocated buffer.
+		 */
+		if (copy_from_user(shared_mem->ptr + pos, io.user_buf,
+				   io.length)) {
+			dev_err(dev_ctx->priv->dev,
+				"%s: Failed copy data to shared memory\n",
+				dev_ctx->devname);
+			err = -EFAULT;
+			goto exit;
+		}
+	}
+
+	err = add_b_desc_to_pending_list(shared_mem->ptr + pos,
+					 &io,
+					 dev_ctx);
+	if (err < 0)
+		dev_err(dev_ctx->priv->dev,
+			"%s: Failed to allocate/link b_desc.",
+			dev_ctx->devname);
+
+copy:
+	/* Provide the EdgeLock Enclave address to user space only if success.*/
+	if (copy_to_user((u8 __user *)arg, &io, sizeof(io))) {
+		dev_err(dev_ctx->priv->dev,
+			"%s: Failed to copy iobuff setup to user.",
+			dev_ctx->devname);
+		err = -EFAULT;
+		goto exit;
+	}
+exit:
+	return err;
+}
+
+/* IOCTL to provide SoC information */
+static int se_ioctl_get_se_soc_info_handler(struct se_if_device_ctx *dev_ctx,
+					     u64 arg)
+{
+	struct se_ioctl_get_soc_info soc_info;
+	int err = -EINVAL;
+
+	soc_info.soc_id = get_se_soc_id(dev_ctx->priv);
+	soc_info.soc_rev = var_se_info.soc_rev;
+
+	err = (int)copy_to_user((u8 __user *)arg, (u8 *)(&soc_info), sizeof(soc_info));
+	if (err) {
+		dev_err(dev_ctx->priv->dev,
+			"%s: Failed to copy soc info to user\n",
+			dev_ctx->devname);
+		err = -EFAULT;
+		goto exit;
+	}
+
+exit:
+	return err;
+}
+
+/*
+ * File operations for user-space
+ */
+
+/* Write a message to the MU. */
+static ssize_t se_if_fops_write(struct file *fp, const char __user *buf,
+				size_t size, loff_t *ppos)
+{
+	struct se_if_device_ctx *dev_ctx = fp->private_data;
+	struct se_api_msg *tx_msg __free(kfree) = NULL;
+	struct se_if_priv *priv = dev_ctx->priv;
+	int err;
+
+	dev_dbg(priv->dev,
+		"%s: write from buf (%p)%zu, ppos=%lld\n",
+		dev_ctx->devname,
+		buf, size, ((ppos) ? *ppos : 0));
+
+	if (mutex_lock_interruptible(&dev_ctx->fops_lock))
+		return -EBUSY;
+
+	if (dev_ctx != priv->cmd_receiver_clbk_hdl.dev_ctx) {
+		err = -EINVAL;
+		goto exit;
+	}
+
+	if (size < SE_MU_HDR_SZ) {
+		dev_err(priv->dev,
+			"%s: User buffer too small(%zu < %d)\n",
+			dev_ctx->devname,
+			size, SE_MU_HDR_SZ);
+		err = -ENOSPC;
+		goto exit;
+	}
+
+	tx_msg = memdup_user(buf, size);
+	if (IS_ERR(tx_msg)) {
+		err = PTR_ERR(tx_msg);
+		goto exit;
+	}
+
+	print_hex_dump_debug("from user ", DUMP_PREFIX_OFFSET, 4, 4,
+			     tx_msg, size, false);
+
+	err = ele_msg_send(dev_ctx, tx_msg, size);
+	if (err < 0)
+		goto exit;
+exit:
+	mutex_unlock(&dev_ctx->fops_lock);
+	return err;
+}
+
+/*
+ * Read a message from the MU.
+ * Blocking until a message is available.
+ */
+static ssize_t se_if_fops_read(struct file *fp, char __user *buf,
+			       size_t size, loff_t *ppos)
+{
+	struct se_if_device_ctx *dev_ctx = fp->private_data;
+	struct se_if_priv *priv = dev_ctx->priv;
+	int err;
+
+	dev_dbg(priv->dev,
+		"%s: read to buf %p(%zu), ppos=%lld\n",
+		dev_ctx->devname,
+		buf, size, ((ppos) ? *ppos : 0));
+
+	if (mutex_lock_interruptible(&dev_ctx->fops_lock))
+		return -EBUSY;
+
+	if (dev_ctx != priv->cmd_receiver_clbk_hdl.dev_ctx) {
+		err = -EINVAL;
+		goto exit;
+	}
+
+	err = ele_msg_rcv(dev_ctx, &priv->cmd_receiver_clbk_hdl);
+	if (err < 0) {
+		dev_err(priv->dev,
+			"%s: Err[0x%x]:Interrupted by signal.\n",
+			dev_ctx->devname, err);
+		dev_dbg(priv->dev,
+			"Current active dev-ctx count = %d.\n",
+			dev_ctx->priv->active_devctx_count);
+		goto exit;
+	}
+
+	/* We may need to copy the output data to user before
+	 * delivering the completion message.
+	 */
+	err = se_dev_ctx_cpy_out_data(dev_ctx);
+	if (err < 0)
+		goto exit;
+
+	/* Copy data from the buffer */
+	print_hex_dump_debug("to user ", DUMP_PREFIX_OFFSET, 4, 4,
+			     priv->cmd_receiver_clbk_hdl.rx_msg,
+			     priv->cmd_receiver_clbk_hdl.rx_msg_sz,
+			     false);
+
+	if (copy_to_user(buf, priv->cmd_receiver_clbk_hdl.rx_msg,
+			 priv->cmd_receiver_clbk_hdl.rx_msg_sz)) {
+		dev_err(priv->dev,
+			"%s: Failed to copy to user\n",
+			dev_ctx->devname);
+		err = -EFAULT;
+	}
+	err = priv->cmd_receiver_clbk_hdl.rx_msg_sz;
+exit:
+	priv->cmd_receiver_clbk_hdl.rx_msg_sz = 0;
+
+	se_dev_ctx_shared_mem_cleanup(dev_ctx);
+
+	mutex_unlock(&dev_ctx->fops_lock);
+	return err;
+}
+
+/* Open a character device. */
+static int se_if_fops_open(struct inode *nd, struct file *fp)
+{
+	struct miscdevice *miscdev = fp->private_data;
+	struct se_if_priv *priv = dev_get_drvdata(miscdev->parent);
+	struct se_if_device_ctx *misc_dev_ctx = priv->priv_dev_ctx;
+	struct se_if_device_ctx *dev_ctx;
+	int err = 0;
+
+	if (mutex_lock_interruptible(&misc_dev_ctx->fops_lock))
+		return -EBUSY;
+
+	priv->dev_ctx_mono_count++;
+	err = init_device_context(priv,
+				  priv->dev_ctx_mono_count ?
+					priv->dev_ctx_mono_count
+					: priv->dev_ctx_mono_count++,
+				  &dev_ctx, NULL);
+	if (err) {
+		dev_err(priv->dev,
+			"Failed[0x%x] to create device contexts.\n",
+			err);
+		goto exit;
+	}
+
+	fp->private_data = dev_ctx;
+
+exit:
+	mutex_unlock(&misc_dev_ctx->fops_lock);
+	return err;
+}
+
+/* Close a character device. */
+static int se_if_fops_close(struct inode *nd, struct file *fp)
+{
+	struct se_if_device_ctx *dev_ctx = fp->private_data;
+	struct se_if_priv *priv = dev_ctx->priv;
+
+	if (mutex_lock_interruptible(&dev_ctx->fops_lock))
+		return -EBUSY;
+
+	/* check if this device was registered as command receiver. */
+	if (priv->cmd_receiver_clbk_hdl.dev_ctx == dev_ctx) {
+		priv->cmd_receiver_clbk_hdl.dev_ctx = NULL;
+		kfree(priv->cmd_receiver_clbk_hdl.rx_msg);
+		priv->cmd_receiver_clbk_hdl.rx_msg = NULL;
+	}
+
+	se_dev_ctx_shared_mem_cleanup(dev_ctx);
+	cleanup_se_shared_mem(dev_ctx);
+
+	priv->active_devctx_count--;
+	list_del(&dev_ctx->link);
+
+	mutex_unlock(&dev_ctx->fops_lock);
+	kfree(dev_ctx->devname);
+	kfree(dev_ctx);
+
+	return 0;
+}
+
+/* IOCTL entry point of a character device */
+static long se_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+	struct se_if_device_ctx *dev_ctx = fp->private_data;
+	struct se_if_priv *priv = dev_ctx->priv;
+	int err;
+
+	/* Prevent race during change of device context */
+	if (mutex_lock_interruptible(&dev_ctx->fops_lock))
+		return -EBUSY;
+
+	switch (cmd) {
+	case SE_IOCTL_ENABLE_CMD_RCV:
+		if (!priv->cmd_receiver_clbk_hdl.dev_ctx) {
+			if (!priv->cmd_receiver_clbk_hdl.rx_msg) {
+				priv->cmd_receiver_clbk_hdl.rx_msg
+					= kzalloc(MAX_NVM_MSG_LEN,
+						  GFP_KERNEL);
+				if (!priv->cmd_receiver_clbk_hdl.rx_msg) {
+					err = -ENOMEM;
+					break;
+				}
+			}
+			priv->cmd_receiver_clbk_hdl.rx_msg_sz = MAX_NVM_MSG_LEN;
+			priv->cmd_receiver_clbk_hdl.dev_ctx = dev_ctx;
+			err = 0;
+		} else {
+			err = -EBUSY;
+		}
+		break;
+	case SE_IOCTL_GET_MU_INFO:
+		err = se_ioctl_get_mu_info(dev_ctx, arg);
+		break;
+	case SE_IOCTL_SETUP_IOBUF:
+		err = se_ioctl_setup_iobuf_handler(dev_ctx, arg);
+		break;
+	case SE_IOCTL_GET_SOC_INFO:
+		err = se_ioctl_get_se_soc_info_handler(dev_ctx, arg);
+		break;
+	case SE_IOCTL_CMD_SEND_RCV_RSP:
+		err = se_ioctl_cmd_snd_rcv_rsp_handler(dev_ctx, arg);
+		break;
+	default:
+		err = -EINVAL;
+		dev_dbg(priv->dev,
+			"%s: IOCTL %.8x not supported\n",
+			dev_ctx->devname,
+			cmd);
+	}
+
+	mutex_unlock(&dev_ctx->fops_lock);
+
+	return (long)err;
+}
+
+/* Char driver setup */
+static const struct file_operations se_if_fops = {
+	.open		= se_if_fops_open,
+	.owner		= THIS_MODULE,
+	.release	= se_if_fops_close,
+	.unlocked_ioctl = se_ioctl,
+	.read		= se_if_fops_read,
+	.write		= se_if_fops_write,
+};
+
 /* interface for managed res to free a mailbox channel */
 static void if_mbox_free_channel(void *mbox_chan)
 {
@@ -335,6 +1103,7 @@ static int se_if_request_channel(struct device *dev,
 
 static void se_if_probe_cleanup(void *plat_dev)
 {
+	struct se_if_device_ctx *dev_ctx, *t_dev_ctx;
 	struct platform_device *pdev = plat_dev;
 	struct device *dev = &pdev->dev;
 	struct se_fw_load_info *load_fw;
@@ -359,6 +1128,13 @@ static void se_if_probe_cleanup(void *plat_dev)
 		load_fw->imem.buf = NULL;
 	}
 
+	if (priv->dev_ctx_mono_count) {
+		list_for_each_entry_safe(dev_ctx, t_dev_ctx, &priv->dev_ctx_list, link) {
+			list_del(&dev_ctx->link);
+			priv->active_devctx_count--;
+		}
+	}
+
 	/* No need to check, if reserved memory is allocated
 	 * before calling for its release. Or clearing the
 	 * un-set bit.
@@ -442,6 +1218,7 @@ static int se_if_probe(struct platform_device *pdev)
 			goto exit;
 		}
 	}
+	INIT_LIST_HEAD(&priv->dev_ctx_list);
 
 	if (info->reserved_dma_ranges) {
 		ret = of_reserved_mem_device_init(dev);
@@ -453,6 +1230,14 @@ static int se_if_probe(struct platform_device *pdev)
 		}
 	}
 
+	ret = init_device_context(priv, 0, &priv->priv_dev_ctx, &se_if_fops);
+	if (ret) {
+		dev_err(dev,
+			"Failed[0x%x] to create device contexts.\n",
+			ret);
+		goto exit;
+	}
+
 	if (info->if_defs.se_if_type == SE_TYPE_ID_HSM) {
 		ret = se_soc_info(priv);
 		if (ret) {
@@ -471,7 +1256,7 @@ static int se_if_probe(struct platform_device *pdev)
 		load_fw->is_fw_loaded = false;
 	}
 	dev_info(dev, "i.MX secure-enclave: %s%d interface to firmware, configured.\n",
-			SE_TYPE_STR_HSM,
+			get_se_if_name(priv->if_defs->se_if_type),
 			priv->if_defs->se_instance_id);
 	return ret;
 
diff --git a/drivers/firmware/imx/se_ctrl.h b/drivers/firmware/imx/se_ctrl.h
index 12c201b503b1..91a2f084b1f4 100644
--- a/drivers/firmware/imx/se_ctrl.h
+++ b/drivers/firmware/imx/se_ctrl.h
@@ -13,6 +13,7 @@
 #define MAX_FW_LOAD_RETRIES		50
 
 #define RES_STATUS(x)			FIELD_GET(0x000000ff, x)
+#define MAX_DATA_SIZE_PER_USER		(65 * 1024)
 #define MAX_NVM_MSG_LEN			(256)
 #define MESSAGING_VERSION_6		0x6
 #define MESSAGING_VERSION_7		0x7
@@ -31,6 +32,7 @@
 struct se_clbk_handle {
 	struct completion done;
 	bool signal_rcvd;
+	struct se_if_device_ctx *dev_ctx;
 	u32 rx_msg_sz;
 	/* Assignment of the rx_msg buffer to held till the
 	 * received content as part callback function, is copied.
@@ -45,6 +47,40 @@ struct se_imem_buf {
 	u32 state;
 };
 
+struct se_buf_desc {
+	u8 *shared_buf_ptr;
+	void __user *usr_buf_ptr;
+	u32 size;
+	struct list_head link;
+};
+
+struct se_shared_mem {
+	dma_addr_t dma_addr;
+	u32 size;
+	u32 pos;
+	u8 *ptr;
+};
+
+struct se_shared_mem_mgmt_info {
+	struct list_head pending_in;
+	struct list_head pending_out;
+
+	struct se_shared_mem secure_mem;
+	struct se_shared_mem non_secure_mem;
+};
+
+/* Private struct for each char device instance. */
+struct se_if_device_ctx {
+	struct se_if_priv *priv;
+	struct miscdevice *miscdev;
+	const char *devname;
+
+	struct mutex fops_lock;
+
+	struct se_shared_mem_mgmt_info se_shared_mem_mgmt;
+	struct list_head link;
+};
+
 /* Header of the messages exchange with the EdgeLock Enclave */
 struct se_msg_hdr {
 	u8 ver;
@@ -89,6 +125,12 @@ struct se_if_priv {
 
 	struct gen_pool *mem_pool;
 	const struct se_if_defines *if_defs;
+
+	struct se_if_device_ctx *priv_dev_ctx;
+	struct list_head dev_ctx_list;
+	u32 active_devctx_count;
+	u32 dev_ctx_mono_count;
 };
 
+char *get_se_if_name(u8 se_if_id);
 #endif
diff --git a/include/uapi/linux/se_ioctl.h b/include/uapi/linux/se_ioctl.h
new file mode 100644
index 000000000000..5cf3d56734f4
--- /dev/null
+++ b/include/uapi/linux/se_ioctl.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause*/
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef SE_IOCTL_H
+#define SE_IOCTL_H
+
+#include <linux/types.h>
+
+#define SE_TYPE_STR_DBG			"dbg"
+#define SE_TYPE_STR_HSM			"hsm"
+#define SE_TYPE_ID_UNKWN		0x0
+#define SE_TYPE_ID_DBG			0x1
+#define SE_TYPE_ID_HSM			0x2
+/* IOCTL definitions. */
+
+struct se_ioctl_setup_iobuf {
+	void __user *user_buf;
+	__u32 length;
+	__u32 flags;
+	__u64 ele_addr;
+};
+
+struct se_ioctl_shared_mem_cfg {
+	__u32 base_offset;
+	__u32 size;
+};
+
+struct se_ioctl_get_if_info {
+	__u8 se_if_id;
+	__u8 interrupt_idx;
+	__u8 tz;
+	__u8 did;
+	__u8 cmd_tag;
+	__u8 rsp_tag;
+	__u8 success_tag;
+	__u8 base_api_ver;
+	__u8 fw_api_ver;
+};
+
+struct se_ioctl_cmd_snd_rcv_rsp_info {
+	__u32 __user *tx_buf;
+	int tx_buf_sz;
+	__u32 __user *rx_buf;
+	int rx_buf_sz;
+};
+
+struct se_ioctl_get_soc_info {
+	__u16 soc_id;
+	__u16 soc_rev;
+};
+
+/* IO Buffer Flags */
+#define SE_IO_BUF_FLAGS_IS_OUTPUT	(0x00u)
+#define SE_IO_BUF_FLAGS_IS_INPUT	(0x01u)
+#define SE_IO_BUF_FLAGS_USE_SEC_MEM	(0x02u)
+#define SE_IO_BUF_FLAGS_USE_SHORT_ADDR	(0x04u)
+#define SE_IO_BUF_FLAGS_IS_IN_OUT	(0x10u)
+
+/* IOCTLS */
+#define SE_IOCTL			0x0A /* like MISC_MAJOR. */
+
+/*
+ * ioctl to designated the current fd as logical-reciever.
+ * This is ioctl is send when the nvm-daemon, a slave to the
+ * firmware is started by the user.
+ */
+#define SE_IOCTL_ENABLE_CMD_RCV	_IO(SE_IOCTL, 0x01)
+
+/*
+ * ioctl to get the buffer allocated from the memory, which is shared
+ * between kernel and FW.
+ * Post allocation, the kernel tagged the allocated memory with:
+ *  Output
+ *  Input
+ *  Input-Output
+ *  Short address
+ *  Secure-memory
+ */
+#define SE_IOCTL_SETUP_IOBUF	_IOWR(SE_IOCTL, 0x03, \
+					struct se_ioctl_setup_iobuf)
+
+/*
+ * ioctl to get the mu information, that is used to exchange message
+ * with FW, from user-spaced.
+ */
+#define SE_IOCTL_GET_MU_INFO	_IOR(SE_IOCTL, 0x04, \
+					struct se_ioctl_get_if_info)
+/*
+ * ioctl to get SoC Info from user-space.
+ */
+#define SE_IOCTL_GET_SOC_INFO      _IOR(SE_IOCTL, 0x06, \
+					struct se_ioctl_get_soc_info)
+
+/*
+ * ioctl to send command and receive response from user-space.
+ */
+#define SE_IOCTL_CMD_SEND_RCV_RSP _IOWR(SE_IOCTL, 0x07, \
+					struct se_ioctl_cmd_snd_rcv_rsp_info)
+#endif

-- 
2.34.1



From zengheng4 at huawei.com  Thu Dec 19 05:39:50 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Thu, 19 Dec 2024 21:39:50 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 2/5] arm_mpam: Read
 monitor value with new closid/rmid pair
In-Reply-To: <Z1sMxKM9o6lAiZGr@e133380.arm.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
 <20241207092136.2488426-3-zengheng4@huawei.com>
 <Z1sMxKM9o6lAiZGr@e133380.arm.com>
Message-ID: <0a84f8ce-80a3-c49a-28a1-0d3c5e8839fa@huawei.com>



On 2024/12/13 0:18, Dave Martin wrote:
> Hi,
> 
> On Sat, Dec 07, 2024 at 05:21:33PM +0800, Zeng Heng wrote:
>> The MPAM driver statically assigns all reqPARTIDs to respective intPARTIDs.
>> For the new rmid allocation strategy, it will check if there is an
>> available rmid of any reqPARTID which belongs to the input closid, not just
>> the rmids belonging to the closid.
>>
>> For a mixture of MSCs system, for MSCs that do not support narrow-partid,
>> we use the PARTIDs exceeding the number of closids as reqPARTIDs for
>> expanding the monitoring groups.
>>
>> In order to keep the existing resctrl API interface, the rmid contains both
>> req_idx and PMG information instead of PMG only under the MPAM driver. The
>> req_idx represents the req_idx-th sub-monitoring group under the control
>> group. The new rmid would be like:
>>
>>      rmid = (req_idx << shift | pmg).
>>
>> The mapping relationships between each group's closid/rmid and the
>> respective MSCs' intPARTID/reqPARTID/PARTID are illustrated:
>>
>> n - Indicates the total number of intPARTIDs
>> m - Indicates the number of reqPARTIDs per intPARTID
>>
>> P - Partition group (control group)
>> M - Monitoring group
>>
>> Group closid rmid.req_idx (req)PARTID      MSCs with narrow-partid  MSCs without narrow-partid
>> P1    0      -            0                   intPARTID_1              PARTID_1
>> M1_1  0      0            0                       ??? reqPARTID_1_1       ??? PARTID_1_1
>> M1_2  0      1            0+n                     ??? reqPARTID_1_2       ??? PARTID_1_2
>> M1_3  0      2            0+n*2                   ??? reqPARTID_1_3       ??? PARTID_1_3
>>   ...                                              ??? ...                 ??? ...
>> M1_m  0      (m-1)        0+n*(m-1)               ??? reqPARTID_1_m       ??? PARTID_1_m
>>
>> P2    1      -            1                   intPARTID_2              PARTID_2
>> M2_1  1      0            1                       ??? reqPARTID_2_1       ??? PARTID_2_1
>> M2_2  1      1            1+n                     ??? reqPARTID_2_2       ??? PARTID_2_2
>> M2_3  1      2            1+n*2                   ??? reqPARTID_2_3       ??? PARTID_2_3
>>   ...                                              ??? ...                 ??? ...
>> M2_m  1      (m-1)        1+n*(m-1)               ??? reqPARTID_2_m       ??? PARTID_2_m
>>
>> Pn    (n-1)  -            (n-1)               intPARTID_n              PARTID_n
>> Mn_1  (n-1)  0            (n-1)                   ??? reqPARTID_n_1       ??? PARTID_n_1
>> Mn_2  (n-1)  1            (n-1)+n                 ??? reqPARTID_n_2       ??? PARTID_n_2
>> Mn_3  (n-1)  2            (n-1)+n*2               ??? reqPARTID_n_3       ??? PARTID_n_3
>>   ...                                              ??? ...                 ??? ...
>> Mn_m  (n-1)  (m-1)        (n-1)+n*(m-1) = n*m-1   ??? reqPARTID_n_m       ??? PARTID_n_m
>>
>> Based on the example provided, the conversion relationship between
>> closid/rmid and (req)PARTID/PMG is:
>>
>>      (req)PARTID = (rmid.req_idx * n) + closid,
>>      PMG = rmid.pmg.
> 
> It seemed more natural to me for the PARTIDs assigned to a particular
> CLOSID to be consecutively numbered (see [1]), though it works either
> way.
> 
> Otherwise, the approach makes sense.

Yes, I agree with your point and it would be included in the next 
version soon.


Best Regards,
Zeng Heng


From broonie at kernel.org  Thu Dec 19 05:42:23 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Dec 2024 13:42:23 +0000
Subject: [PATCH] spi: rockchip-sfc: Using normal memory for dma
In-Reply-To: <20241219010557.333327-1-jon.lin@rock-chips.com>
References: <20241219010557.333327-1-jon.lin@rock-chips.com>
Message-ID: <173461574310.119842.4743816830245681721.b4-ty@kernel.org>

On Thu, 19 Dec 2024 09:05:57 +0800, Jon Lin wrote:
> Nornal memory CPU copy with cache invalidate is more efficient
> than uncache memory copy.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: rockchip-sfc: Using normal memory for dma
      commit: b69386fcbc6066fb4885667743ab4d4967d561b8

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.dooley at microchip.com  Thu Dec 19 06:11:53 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Thu, 19 Dec 2024 14:11:53 +0000
Subject: [PATCH 1/2] dt-bindings: mailbox: add support for referencing
 controllers solely by node
In-Reply-To: <20241219-mbox_request_channel_by_args-v1-1-617a6910f842@linaro.org>
References: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>
 <20241219-mbox_request_channel_by_args-v1-1-617a6910f842@linaro.org>
Message-ID: <20241219-recent-everyone-865b19864693@wendy>

On Thu, Dec 19, 2024 at 01:07:46PM +0000, Tudor Ambarus wrote:
> There are mailbox clients that can discover the mailbox channel ID at
> run-time. For such cases passing the channel identifier via DT is
> redundant. Add support for referencing controllers solely by node.

I don't really get your implementation, why not just allow #mbox-cells = 0?
That's what's done for things like fixed frequency clocks that only have
a single output.

Cheers,
Conor.

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  Documentation/devicetree/bindings/mailbox/mailbox.txt | 19 +++++++++++++++----
>  1 file changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mailbox/mailbox.txt b/Documentation/devicetree/bindings/mailbox/mailbox.txt
> index af8ecee2ac68..0c4295a62f61 100644
> --- a/Documentation/devicetree/bindings/mailbox/mailbox.txt
> +++ b/Documentation/devicetree/bindings/mailbox/mailbox.txt
> @@ -5,9 +5,10 @@ assign appropriate mailbox channel to client drivers.
>  
>  * Mailbox Controller
>  
> -Required property:
> -- #mbox-cells: Must be at least 1. Number of cells in a mailbox
> -		specifier.
> +Optional property:
> +- #mbox-cells: Must be at least 1. Number of cells in a mailbox specifier.
> +               The property becomes mandatory for the cases where the clients
> +               reference the controller via the mboxes property.
>  
>  Example:
>  	mailbox: mailbox {
> @@ -19,7 +20,11 @@ Example:
>  * Mailbox Client
>  
>  Required property:
> +Clients must reference the mailbox controller either via the mboxes or mbox
> +properties.
>  - mboxes: List of phandle and mailbox channel specifiers.
> +- mbox: phandle pointing to the controller. Used by clients that can discover
> +        the channel identifiers at runtime.
>  
>  Optional property:
>  - mbox-names: List of identifier strings for each mailbox channel.
> @@ -29,7 +34,13 @@ Optional property:
>  	  communication between the mailbox client and the remote.
>  
>  
> -Example:
> +Example using mbox:
> +	power-management {
> +		...
> +		mbox = <&mailbox>;
> +	};
> +
> +Example using mboxes:
>  	pwr_cntrl: power {
>  		...
>  		mbox-names = "pwr-ctrl", "rpc";
> 
> -- 
> 2.47.1.613.gc27f4b7a9f-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/20241219/efe67b1b/attachment.sig>

From lcherian at marvell.com  Thu Dec 19 06:24:56 2024
From: lcherian at marvell.com (Linu Cherian)
Date: Thu, 19 Dec 2024 19:54:56 +0530
Subject: [PATCH v2] selftests: arm coresight: sysfsmode testing
Message-ID: <20241219142456.3474879-1-lcherian@marvell.com>

Add sysfs mode selftest for ARM Coresight hardware tracer.

The test will run below sequence for all possible sinks for every
trace source available on the system.
1. Enable source and sink device to start tracing in sysfs mode
3. Run a standard dd command to be traced
4. Stop tracing
5. Readback tracedata

- Test case is pass if the readback of tracedata is success else
failure.
- In case of ETR sink, the test is run with both default buffer mode and
reserved buffer mode(if available).

Sample output:

 selftests: drivers/hwtracing/coresight: sysfs_test_trace.sh
 Running sysfs trace with default settings
 64+0 records in
 64+0 records out
 67108864 bytes (67 MB, 64 MiB) copied, 0.196945 s, 341 MB/s
 32+0 records in
 32+0 records out
 16384 bytes (16 kB, 16 KiB) copied, 0.000805288 s, 20.3 MB/s
 CoreSight path testing (CPU0 -> tmc_etf0): PASS

Signed-off-by: Linu Cherian <lcherian at marvell.com>
---
Changelog from v1:
- Added test description in commit message suggested by Shuah
- Added config dependency file suggested by Shuah 
- Added TARGETS as suggested by James
- Skipped TPIU as suggested by James 
- Added Reviewed-by tag


 tools/testing/selftests/Makefile              |   1 +
 .../drivers/hwtracing/coresight/Makefile      |   5 +
 .../drivers/hwtracing/coresight/config        |   7 +
 .../hwtracing/coresight/sysfs_test_trace.sh   | 146 ++++++++++++++++++
 4 files changed, 159 insertions(+)
 create mode 100644 tools/testing/selftests/drivers/hwtracing/coresight/Makefile
 create mode 100644 tools/testing/selftests/drivers/hwtracing/coresight/config
 create mode 100755 tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 363d031a16f7..15788c32de6b 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -18,6 +18,7 @@ TARGETS += devices/error_logs
 TARGETS += devices/probe
 TARGETS += dmabuf-heaps
 TARGETS += drivers/dma-buf
+TARGETS += drivers/hwtracing/coresight
 TARGETS += drivers/s390x/uvdevice
 TARGETS += drivers/net
 TARGETS += drivers/net/bonding
diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/Makefile b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
new file mode 100644
index 000000000000..7dc68ae1c0a9
--- /dev/null
+++ b/tools/testing/selftests/drivers/hwtracing/coresight/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+TEST_PROGS = sysfs_test_trace.sh
+
+include ../../../lib.mk
diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/config b/tools/testing/selftests/drivers/hwtracing/coresight/config
new file mode 100644
index 000000000000..47e9256957d3
--- /dev/null
+++ b/tools/testing/selftests/drivers/hwtracing/coresight/config
@@ -0,0 +1,7 @@
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_LINKS_AND_SINKS=y
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_SINK_ETBV10
+CONFIG_CORESIGHT_SOURCE_ETM3X
+CONFIG_CORESIGHT_SOURCE_ETM4X=y
+CONFIG_CORESIGHT_TRBE=y
diff --git a/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
new file mode 100755
index 000000000000..1939bbede1af
--- /dev/null
+++ b/tools/testing/selftests/drivers/hwtracing/coresight/sysfs_test_trace.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2024 Marvell.
+
+# Test Arm CoreSight trace capture in sysfs mode
+# Based on tools/perf/tests/shell/test_arm_coresight.sh
+
+glb_err=0
+
+arm_cs_report() {
+	if [ $2 != 0 ]; then
+		echo "$1: FAIL"
+		glb_err=$2
+	else
+		echo "$1: PASS"
+	fi
+}
+
+is_device_sink() {
+	# If the node of "enable_sink" is existed under the device path, this
+	# means the device is a sink device. Need to exclude 'tpiu' since it
+	# doesn't have a readable file.
+	echo "$1" | grep -E -q -v "tpiu"
+
+	if [ $? -eq 0 ] && [ -e "$1/enable_sink" ]; then
+
+		return 0
+	else
+		return 1
+	fi
+}
+
+# Configure sink for buffer mode
+cfg_sink_buf_mode() {
+	sink_dev=$1
+	mode=$2
+	# Set buffer mode if supported
+	if [ -e "$sink_dev/buf_modes_available" ]; then
+		cat $sink_dev/buf_modes_available | grep -E -q $mode
+		if [ $? -eq 0 ]; then
+			echo $mode > $sink_dev/buf_mode_preferred
+			return 0
+		fi
+	fi
+
+	return 1
+}
+
+run_app() {
+
+	taskset -c $1 dd if=/dev/urandom  of=/dev/null bs=1M count=64
+}
+
+sysfs_trace() {
+	src_dev=$1
+	sink_dev=$2
+	cpu=$3
+
+	# Enable sink device
+	echo 1 > $sink_dev/enable_sink
+	# Enable source device
+	echo 1 > $src_dev/enable_source
+
+	# Run app to be traced
+	run_app $cpu
+
+	# Read back trace data
+	dd if=/dev/$sink_dev_name of=/tmp/tracedata
+
+	# Verify if read is successful
+	err=$?
+
+	# Disable source device
+	echo 0 > $src_dev/enable_source
+
+	# Diskable sink device
+	echo 0 > $sink_dev/enable_sink
+
+	arm_cs_report "CoreSight path testing (CPU$cpu -> $sink_dev_name)" $err
+}
+
+try_sysfs_trace_resrv_buf() {
+	src_dev=$1
+	sink_dev=$2
+	cpu=$3
+
+	# Configure the resrved buffer mode if available
+	cfg_sink_buf_mode $sink_dev "resrv"
+	if [ $? -eq 0 ]; then
+		echo "Running sysfs trace with resrv buf mode"
+		sysfs_trace $src_dev $sink_dev $cpu
+		# Restore buffer mode
+		cfg_sink_buf_mode $sink_dev "auto"
+		if [ $? -eq 1 ]; then
+			echo "Failed to restore default buf mode"
+		fi
+	fi
+}
+
+arm_cs_iterate_devices() {
+	src_dev=$1
+	cpu=$3
+	for cdev in $2/connections/out\:*; do
+
+		# Skip testing if it's not a directory
+		! [ -d $cdev ] && continue;
+
+		# Read out its symbol link file name
+		sink_dev=`readlink -f $cdev`
+
+		# Extract device name from path, e.g.
+		#   sink_dev = '/sys/devices/platform/20010000.etf/tmc_etf0'
+		#     `> sink_dev_name = 'tmc_etf0'
+		sink_dev_name=$(basename $sink_dev)
+
+		if is_device_sink $sink_dev; then
+			# Run trace with resrv buf mode (if available)
+			try_sysfs_trace_resrv_buf $src_dev $sink_dev $cpu
+
+			# Run the default mode
+			echo "Running sysfs trace with default settings"
+			sysfs_trace $src_dev $sink_dev $cpu
+		fi
+
+		arm_cs_iterate_devices $src_dev $cdev $cpu
+
+	done
+}
+
+arm_cs_etm_traverse_path_test() {
+	# Iterate for every ETM device
+	for dev in /sys/bus/event_source/devices/cs_etm/cpu*; do
+		# Canonicalize the path
+		dev=`readlink -f $dev`
+
+		# Find the ETM device belonging to which CPU
+		cpu=`cat $dev/cpu`
+
+		# Use depth-first search (DFS) to iterate outputs
+		arm_cs_iterate_devices $dev $dev $cpu
+	done
+}
+
+arm_cs_etm_traverse_path_test
+
+exit $glb_err
-- 
2.34.1



From peng.fan at oss.nxp.com  Thu Dec 19 06:25:16 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 19 Dec 2024 22:25:16 +0800
Subject: [PATCH v3 0/2] Make i.MX9 OCOTP work as accessing controller
Message-ID: <20241219-imx-ocotp-v3-0-b22371098071@nxp.com>

Previously there was discussion on using "feature-controller" or
adding a specific node to group the fuse information for U-Boot to
parse and update node. But rejected by DT maintainer(Rob).

Since the STM32 engineers added access controller concept and landed
the support in Linux Kernel, reuse the concept for i.MX.

i.MX OCOTP eFuse has some bits to indicate a specific periphral or
function is avaiable for current chip, for example i.MX93 has variants
that not have NPU. So introduce '#access-controller-cells' for OCOTP,
and add "#access-controllers = <&ocotp [gate_index]>" for periphrals
that needs accessing control checking.

In OCOTP driver, the nodes under "/" will be iterated, and checked
if property "#access-controllers" exsits. If not allow access, detach
the node.

In the end, cpu nodes should still be handled by bootloader.
And I may also update i.MX8M to use same method to support variants
if this patchset is good.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Changes in v3:
- Add A-b for patch 1
- Use scoped API when iterate nodes and address build warning in patch 2
- I am also thinking that to drop patch 2 to let
 bootloader to iterate the nodes that have access-controllers property and
 update the nodes before booting the kernel. Then just need patch 1 for
 the binding updates. Anyway, comments are welcomed.
- Link to v2: https://lore.kernel.org/r/20241217-imx-ocotp-v2-0-3faa6cbff41b at nxp.com

Changes in v2:
- Add R-b for patch 1
- Use '/' root node instead of '/soc' or '/soc at 0' for patch 2
- Link to v1: https://lore.kernel.org/r/20241212-imx-ocotp-v1-0-198bb0af86a0 at nxp.com

---
Peng Fan (2):
      dt-bindings: nvmem: imx-ocotp: Introduce #access-controller-cells
      nvmem: imx-ocotp-ele: Support accessing controller for i.MX9

 .../devicetree/bindings/nvmem/imx-ocotp.yaml       |   5 +
 drivers/nvmem/imx-ocotp-ele.c                      | 183 ++++++++++++++++++++-
 include/dt-bindings/nvmem/fsl,imx93-ocotp.h        |  24 +++
 include/dt-bindings/nvmem/fsl,imx95-ocotp.h        |  43 +++++
 4 files changed, 254 insertions(+), 1 deletion(-)
---
base-commit: 6d13015b67d58ddba56631c56e0a6f376ade0867
change-id: 20241212-imx-ocotp-cbef304140f5

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Thu Dec 19 06:25:17 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 19 Dec 2024 22:25:17 +0800
Subject: [PATCH v3 1/2] dt-bindings: nvmem: imx-ocotp: Introduce
 #access-controller-cells
In-Reply-To: <20241219-imx-ocotp-v3-0-b22371098071@nxp.com>
References: <20241219-imx-ocotp-v3-0-b22371098071@nxp.com>
Message-ID: <20241219-imx-ocotp-v3-1-b22371098071@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Introduce "#access-controller-cells" to make OCOTP be an accessing
controller, because i.MX Family OCOTP supports a specific peripheral
or function being fused which means being disabled.

Add the i.MX[95,93] OCOTP gate index.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/nvmem/imx-ocotp.yaml       |  5 +++
 include/dt-bindings/nvmem/fsl,imx93-ocotp.h        | 24 ++++++++++++
 include/dt-bindings/nvmem/fsl,imx95-ocotp.h        | 43 ++++++++++++++++++++++
 3 files changed, 72 insertions(+)

diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
index b2cb76cf9053a883a158acaf5eaa108895818afc..c78e202ced22f1c278f7be827b71ba434832d2a7 100644
--- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
+++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
@@ -54,6 +54,11 @@ properties:
   clocks:
     maxItems: 1
 
+  "#access-controller-cells":
+    const: 1
+    description:
+      Contains the gate ID associated to the peripheral.
+
 required:
   - "#address-cells"
   - "#size-cells"
diff --git a/include/dt-bindings/nvmem/fsl,imx93-ocotp.h b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ef525173845fd4ee0e847cf5a17e53a14f71362
--- /dev/null
+++ b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+#ifndef _DT_BINDINGS_NVMEM_IMX93_OTPC_H
+#define _DT_BINDINGS_NVMEM_IMX93_OTPC_H
+
+#define IMX93_OCOTP_NPU_GATE		0
+#define IMX93_OCOTP_A550_GATE		1
+#define IMX93_OCOTP_A551_GATE		2
+#define IMX93_OCOTP_M33_GATE		3
+#define IMX93_OCOTP_CAN1_FD_GATE	4
+#define IMX93_OCOTP_CAN2_FD_GATE	5
+#define IMX93_OCOTP_CAN1_GATE		6
+#define IMX93_OCOTP_CAN2_GATE		7
+#define IMX93_OCOTP_USB1_GATE		8
+#define IMX93_OCOTP_USB2_GATE		9
+#define IMX93_OCOTP_ENET1_GATE		10
+#define IMX93_OCOTP_ENET2_GATE		11
+#define IMX93_OCOTP_PXP_GATE		12
+#define IMX93_OCOTP_MIPI_CSI1_GATE	13
+#define IMX93_OCOTP_MIPI_DSI1_GATE	14
+#define IMX93_OCOTP_LVDS1_GATE		15
+#define IMX93_OCOTP_ADC1_GATE		16
+
+#endif
diff --git a/include/dt-bindings/nvmem/fsl,imx95-ocotp.h b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d21d1f690974d0215c71352168378a150f489af
--- /dev/null
+++ b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+#ifndef _DT_BINDINGS_NVMEM_IMX95_OTPC_H
+#define _DT_BINDINGS_NVMEM_IMX95_OTPC_H
+
+#define IMX95_OCOTP_CANFD1_GATE		0
+#define IMX95_OCOTP_CANFD2_GATE		1
+#define IMX95_OCOTP_CANFD3_GATE		2
+#define IMX95_OCOTP_CANFD4_GATE		3
+#define IMX95_OCOTP_CANFD5_GATE		4
+#define IMX95_OCOTP_CAN1_GATE		5
+#define IMX95_OCOTP_CAN2_GATE		6
+#define IMX95_OCOTP_CAN3_GATE		7
+#define IMX95_OCOTP_CAN4_GATE		8
+#define IMX95_OCOTP_CAN5_GATE		9
+#define IMX95_OCOTP_NPU_GATE		10
+#define IMX95_OCOTP_A550_GATE		11
+#define IMX95_OCOTP_A551_GATE		12
+#define IMX95_OCOTP_A552_GATE		13
+#define IMX95_OCOTP_A553_GATE		14
+#define IMX95_OCOTP_A554_GATE		15
+#define IMX95_OCOTP_A555_GATE		16
+#define IMX95_OCOTP_M7_GATE		17
+#define IMX95_OCOTP_DCSS_GATE		18
+#define IMX95_OCOTP_LVDS1_GATE		19
+#define IMX95_OCOTP_ISP_GATE		20
+#define IMX95_OCOTP_USB1_GATE		21
+#define IMX95_OCOTP_USB2_GATE		22
+#define IMX95_OCOTP_NETC_GATE		23
+#define IMX95_OCOTP_PCIE1_GATE		24
+#define IMX95_OCOTP_PCIE2_GATE		25
+#define IMX95_OCOTP_ADC1_GATE		26
+#define IMX95_OCOTP_EARC_RX_GATE	27
+#define IMX95_OCOTP_GPU3D_GATE		28
+#define IMX95_OCOTP_VPU_GATE		29
+#define IMX95_OCOTP_JPEG_ENC_GATE	30
+#define IMX95_OCOTP_JPEG_DEC_GATE	31
+#define IMX95_OCOTP_MIPI_CSI1_GATE	32
+#define IMX95_OCOTP_MIPI_CSI2_GATE	33
+#define IMX95_OCOTP_MIPI_DSI1_GATE	34
+#define IMX95_OCOTP_V2X_GATE		35
+
+#endif

-- 
2.37.1



From peng.fan at oss.nxp.com  Thu Dec 19 06:25:18 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 19 Dec 2024 22:25:18 +0800
Subject: [PATCH v3 2/2] nvmem: imx-ocotp-ele: Support accessing controller
 for i.MX9
In-Reply-To: <20241219-imx-ocotp-v3-0-b22371098071@nxp.com>
References: <20241219-imx-ocotp-v3-0-b22371098071@nxp.com>
Message-ID: <20241219-imx-ocotp-v3-2-b22371098071@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX9 OCOTP supports a specific peripheral or function being fused
which means disabled, so
 - Introduce ocotp_access_gates to be container of efuse gate info
 - Iterate each node under '/soc' to check accessing permission. If not
   allowed to be accessed, detach the node

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/nvmem/imx-ocotp-ele.c | 183 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index ca6dd71d8a2e29888c6e556aaea116c1a967cb5f..173863b1fd7de150576b78f03c256a151b174389 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -5,6 +5,8 @@
  * Copyright 2023 NXP
  */
 
+#include <dt-bindings/nvmem/fsl,imx93-ocotp.h>
+#include <dt-bindings/nvmem/fsl,imx95-ocotp.h>
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -27,6 +29,7 @@ struct ocotp_map_entry {
 };
 
 struct ocotp_devtype_data {
+	const struct ocotp_access_gates *access_gates;
 	u32 reg_off;
 	char *name;
 	u32 size;
@@ -36,11 +39,26 @@ struct ocotp_devtype_data {
 	struct ocotp_map_entry entry[];
 };
 
+#define OCOTP_MAX_NUM_GATE_WORDS 4
+#define IMX93_OCOTP_NUM_GATES 17
+#define IMX95_OCOTP_NUM_GATES 36
+
+struct ocotp_access_gates {
+	u32 num_words;
+	u32 words[OCOTP_MAX_NUM_GATE_WORDS];
+	u32 num_gates;
+	struct access_gate {
+		u32 word;
+		u32 mask;
+	} gates[];
+};
+
 struct imx_ocotp_priv {
 	struct device *dev;
 	void __iomem *base;
 	struct nvmem_config config;
 	struct mutex lock;
+	u32 value[OCOTP_MAX_NUM_GATE_WORDS];
 	const struct ocotp_devtype_data *data;
 };
 
@@ -131,6 +149,96 @@ static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
 	cell->read_post_process = imx_ocotp_cell_pp;
 }
 
+static int imx_ele_ocotp_check_access(struct platform_device *pdev, u32 id)
+{
+	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
+	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
+	u32 word, mask;
+
+	if (id >= access_gates->num_gates) {
+		dev_err(&pdev->dev, "Index %d too large\n", id);
+		return -EACCES;
+	}
+
+	word = access_gates->gates[id].word;
+	mask = access_gates->gates[id].mask;
+
+	dev_dbg(&pdev->dev, "id:%d word:%d mask:0x%08x\n", id, word, mask);
+	/* true means not allow access */
+	if (priv->value[word] & mask)
+		return -EACCES;
+
+	return 0;
+}
+
+static int imx_ele_ocotp_grant_access(struct platform_device *pdev, struct device_node *parent)
+{
+	struct device *dev = &pdev->dev;
+
+	for_each_available_child_of_node_scoped(parent, child) {
+		struct of_phandle_iterator it;
+		int err;
+		u32 id;
+
+		of_for_each_phandle(&it, err, child, "access-controllers",
+				    "#access-controller-cells", 0) {
+			struct of_phandle_args provider_args;
+			struct device_node *provider = it.node;
+
+			if (err) {
+				dev_err(dev, "Unable to get access-controllers property for node %s\n, err: %d",
+					child->full_name, err);
+				of_node_put(provider);
+				return err;
+			}
+
+			/* Only support one cell */
+			if (of_phandle_iterator_args(&it, provider_args.args, 1) != 1) {
+				dev_err(dev, "wrong args count\n");
+				return -EINVAL;
+			}
+
+			id = provider_args.args[0];
+
+			dev_dbg(dev, "Checking node: %s gate: %d\n", child->full_name, id);
+
+			if (imx_ele_ocotp_check_access(pdev, id)) {
+				of_detach_node(child);
+				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
+					child->full_name);
+			}
+		}
+
+		imx_ele_ocotp_grant_access(pdev, child);
+	}
+
+	return 0;
+}
+
+static int imx_ele_ocotp_access_control(struct platform_device *pdev)
+{
+	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
+	struct device_node *root __free(device_node) = of_find_node_by_path("/");
+	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
+	void __iomem *reg = priv->base + priv->data->reg_off;
+	u32 off;
+	int i;
+
+	if (!priv->data->access_gates)
+		return 0;
+
+	/* This should never happen */
+	WARN_ON(!root);
+
+	for (i = 0; i < access_gates->num_words; i++) {
+		off = access_gates->words[i] << 2;
+		priv->value[i] = readl(reg + off);
+		dev_dbg(&pdev->dev, "word:%d 0x%08x\n", access_gates->words[i], priv->value[i]);
+	}
+
+	return imx_ele_ocotp_grant_access(pdev, root);
+}
+
 static int imx_ele_ocotp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -161,14 +269,43 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
 	mutex_init(&priv->lock);
 
+	platform_set_drvdata(pdev, priv);
+
 	nvmem = devm_nvmem_register(dev, &priv->config);
 	if (IS_ERR(nvmem))
 		return PTR_ERR(nvmem);
 
-	return 0;
+
+	return imx_ele_ocotp_access_control(pdev);
 }
 
+static const struct ocotp_access_gates imx93_access_gates = {
+	.num_words = 3,
+	.words = {19, 20, 21},
+	.num_gates = IMX93_OCOTP_NUM_GATES,
+	.gates = {
+		[IMX93_OCOTP_NPU_GATE]		= { .word = 19, .mask = BIT(13) },
+		[IMX93_OCOTP_A550_GATE]		= { .word = 19, .mask = BIT(14) },
+		[IMX93_OCOTP_A551_GATE]		= { .word = 19, .mask = BIT(15) },
+		[IMX93_OCOTP_M33_GATE]		= { .word = 19, .mask = BIT(24) },
+		[IMX93_OCOTP_CAN1_FD_GATE]	= { .word = 19, .mask = BIT(28) },
+		[IMX93_OCOTP_CAN2_FD_GATE]	= { .word = 19, .mask = BIT(29) },
+		[IMX93_OCOTP_CAN1_GATE]		= { .word = 19, .mask = BIT(30) },
+		[IMX93_OCOTP_CAN2_GATE]		= { .word = 19, .mask = BIT(31) },
+		[IMX93_OCOTP_USB1_GATE]		= { .word = 20, .mask = BIT(3) },
+		[IMX93_OCOTP_USB2_GATE]		= { .word = 20, .mask = BIT(4) },
+		[IMX93_OCOTP_ENET1_GATE]	= { .word = 20, .mask = BIT(5) },
+		[IMX93_OCOTP_ENET2_GATE]	= { .word = 20, .mask = BIT(6) },
+		[IMX93_OCOTP_PXP_GATE]		= { .word = 20, .mask = BIT(10) },
+		[IMX93_OCOTP_MIPI_CSI1_GATE]	= { .word = 20, .mask = BIT(17) },
+		[IMX93_OCOTP_MIPI_DSI1_GATE]	= { .word = 20, .mask = BIT(19) },
+		[IMX93_OCOTP_LVDS1_GATE]	= { .word = 20, .mask = BIT(24) },
+		[IMX93_OCOTP_ADC1_GATE]		= { .word = 21, .mask = BIT(7) },
+	},
+};
+
 static const struct ocotp_devtype_data imx93_ocotp_data = {
+	.access_gates = &imx93_access_gates,
 	.reg_off = 0x8000,
 	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,
@@ -183,7 +320,51 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
 	},
 };
 
+static const struct ocotp_access_gates imx95_access_gates = {
+	.num_words = 3,
+	.words = {17, 18, 19},
+	.num_gates = IMX95_OCOTP_NUM_GATES,
+	.gates = {
+		[IMX95_OCOTP_CANFD1_GATE]	= { .word = 17, .mask = BIT(20) },
+		[IMX95_OCOTP_CANFD2_GATE]	= { .word = 17, .mask = BIT(21) },
+		[IMX95_OCOTP_CANFD3_GATE]	= { .word = 17, .mask = BIT(22) },
+		[IMX95_OCOTP_CANFD4_GATE]	= { .word = 17, .mask = BIT(23) },
+		[IMX95_OCOTP_CANFD5_GATE]	= { .word = 17, .mask = BIT(24) },
+		[IMX95_OCOTP_CAN1_GATE]		= { .word = 17, .mask = BIT(25) },
+		[IMX95_OCOTP_CAN2_GATE]		= { .word = 17, .mask = BIT(26) },
+		[IMX95_OCOTP_CAN3_GATE]		= { .word = 17, .mask = BIT(27) },
+		[IMX95_OCOTP_CAN4_GATE]		= { .word = 17, .mask = BIT(28) },
+		[IMX95_OCOTP_CAN5_GATE]		= { .word = 17, .mask = BIT(29) },
+		[IMX95_OCOTP_NPU_GATE]		= { .word = 18, .mask = BIT(0) },
+		[IMX95_OCOTP_A550_GATE]		= { .word = 18, .mask = BIT(1) },
+		[IMX95_OCOTP_A551_GATE]		= { .word = 18, .mask = BIT(2) },
+		[IMX95_OCOTP_A552_GATE]		= { .word = 18, .mask = BIT(3) },
+		[IMX95_OCOTP_A553_GATE]		= { .word = 18, .mask = BIT(4) },
+		[IMX95_OCOTP_A554_GATE]		= { .word = 18, .mask = BIT(5) },
+		[IMX95_OCOTP_A555_GATE]		= { .word = 18, .mask = BIT(6) },
+		[IMX95_OCOTP_M7_GATE]		= { .word = 18, .mask = BIT(9) },
+		[IMX95_OCOTP_DCSS_GATE]		= { .word = 18, .mask = BIT(22) },
+		[IMX95_OCOTP_LVDS1_GATE]	= { .word = 18, .mask = BIT(27) },
+		[IMX95_OCOTP_ISP_GATE]		= { .word = 18, .mask = BIT(29) },
+		[IMX95_OCOTP_USB1_GATE]		= { .word = 19, .mask = BIT(2) },
+		[IMX95_OCOTP_USB2_GATE]		= { .word = 19, .mask = BIT(3) },
+		[IMX95_OCOTP_NETC_GATE]		= { .word = 19, .mask = BIT(4) },
+		[IMX95_OCOTP_PCIE1_GATE]	= { .word = 19, .mask = BIT(6) },
+		[IMX95_OCOTP_PCIE2_GATE]	= { .word = 19, .mask = BIT(7) },
+		[IMX95_OCOTP_ADC1_GATE]		= { .word = 19, .mask = BIT(8) },
+		[IMX95_OCOTP_EARC_RX_GATE]	= { .word = 19, .mask = BIT(11) },
+		[IMX95_OCOTP_GPU3D_GATE]	= { .word = 19, .mask = BIT(16) },
+		[IMX95_OCOTP_VPU_GATE]		= { .word = 19, .mask = BIT(17) },
+		[IMX95_OCOTP_JPEG_ENC_GATE]	= { .word = 19, .mask = BIT(18) },
+		[IMX95_OCOTP_JPEG_DEC_GATE]	= { .word = 19, .mask = BIT(19) },
+		[IMX95_OCOTP_MIPI_CSI1_GATE]	= { .word = 19, .mask = BIT(21) },
+		[IMX95_OCOTP_MIPI_CSI2_GATE]	= { .word = 19, .mask = BIT(22) },
+		[IMX95_OCOTP_MIPI_DSI1_GATE]	= { .word = 19, .mask = BIT(23) },
+	}
+};
+
 static const struct ocotp_devtype_data imx95_ocotp_data = {
+	.access_gates = &imx95_access_gates,
 	.reg_off = 0x8000,
 	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,

-- 
2.37.1



From aleksander.lobakin at intel.com  Thu Dec 19 06:20:06 2024
From: aleksander.lobakin at intel.com (Alexander Lobakin)
Date: Thu, 19 Dec 2024 15:20:06 +0100
Subject: [PATCH net-next v1] net: stmmac: Drop useless code related to
 ethtool rx-copybreak
In-Reply-To: <20241218164206.437fcedc@kernel.org>
References: <20241218083407.390509-1-0x1207@gmail.com>
 <b2ae6b80-83e3-4b22-8301-c91569c89494@intel.com>
 <20241218164206.437fcedc@kernel.org>
Message-ID: <0c349cfa-909f-4c91-90df-8e56d93a7ce1@intel.com>

From: Jakub Kicinski <kuba at kernel.org>
Date: Wed, 18 Dec 2024 16:42:06 -0800

> On Wed, 18 Dec 2024 16:48:38 +0100 Alexander Lobakin wrote:
>> If sizeof(dma_addr_t) == 8, you're clearly introducing a 4-byte hole
>> here. Perhaps you could reshuffle the struct a bit to avoid this.
>>
>> It's always good to inspect the .kos with pahole after modifying
>> structures to make sure there are no regressions.
> 
> Pretty off topic but I have a dumb question - how do you dump a struct
> with pahole using debug info or BTF from a random .ko?
> Ever since pahole got converted to BTF modules stopped working for me :S

Hmm...

I have this

CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_NONE is not set
# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
# CONFIG_DEBUG_INFO_DWARF4 is not set
CONFIG_DEBUG_INFO_DWARF5=y
# CONFIG_DEBUG_INFO_REDUCED is not set
# CONFIG_DEBUG_INFO_COMPRESSED_NONE is not set
# CONFIG_DEBUG_INFO_COMPRESSED_ZLIB is not set
CONFIG_DEBUG_INFO_COMPRESSED_ZSTD=y
# CONFIG_DEBUG_INFO_SPLIT is not set
CONFIG_DEBUG_INFO_BTF=y
CONFIG_DEBUG_INFO_BTF_MODULES=y

CONFIG_PAHOLE_VERSION=127
CONFIG_PAHOLE_HAS_SPLIT_BTF=y
CONFIG_PAHOLE_HAS_BTF_TAG=y
CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y

enabled in .config, then I just do

$ pahole path/to/module.ko | less

and search for the struct :D

My pahole is korg Git HEAD.

> I never cared enough to check as most interesting stuff is built-in
> in Meta's kernels but it annoys me every now and then..

Thanks,
Olek


From cassel at kernel.org  Thu Dec 19 06:22:00 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Thu, 19 Dec 2024 15:22:00 +0100
Subject: [PATCH] PCI: dw-rockchip: Enumerate endpoints based on
 dll_link_up irq in the combined sys irq
In-Reply-To: <Z1qY_K57lamVxqRm@ryzen>
References: <20241127145041.3531400-2-cassel@kernel.org>
 <20241211053104.7sgo5bmmjnolwvhh@thinkpad>
 <Z1qY_K57lamVxqRm@ryzen>
Message-ID: <Z2QsCI60fK038OEv@ryzen>

On Thu, Dec 12, 2024 at 09:04:12AM +0100, Niklas Cassel wrote:
> > 
> > Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> 
> Thanks for the review!
> 
> Could this patch please be picked up?

Another week has past, hence another ping :)


Kind regards,
Niklas


From jon.lin at rock-chips.com  Thu Dec 19 06:22:16 2024
From: jon.lin at rock-chips.com (Jon Lin)
Date: Thu, 19 Dec 2024 22:22:16 +0800
Subject: [PATCH] spi: rockchip-sfc: Support sclk_x2 version
Message-ID: <20241219142216.2123065-1-jon.lin@rock-chips.com>

SFC after version 8 supports dtr mode, so the IO is the binary output of
the controller clock.

Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

 drivers/spi/spi-rockchip-sfc.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
index 36509bcccc27..59de351499a0 100644
--- a/drivers/spi/spi-rockchip-sfc.c
+++ b/drivers/spi/spi-rockchip-sfc.c
@@ -112,6 +112,7 @@
 #define  SFC_VER_3			0x3
 #define  SFC_VER_4			0x4
 #define  SFC_VER_5			0x5
+#define  SFC_VER_8			0x8
 
 /* Delay line controller register */
 #define SFC_DLL_CTRL0			0x3C
@@ -217,6 +218,22 @@ static u32 rockchip_sfc_get_max_iosize(struct rockchip_sfc *sfc)
 	return SFC_MAX_IOSIZE_VER3;
 }
 
+static int rockchip_sfc_clk_set_rate(struct rockchip_sfc *sfc, unsigned long  speed)
+{
+	if (sfc->version >= SFC_VER_8)
+		return clk_set_rate(sfc->clk, speed * 2);
+	else
+		return clk_set_rate(sfc->clk, speed);
+}
+
+static unsigned long rockchip_sfc_clk_get_rate(struct rockchip_sfc *sfc)
+{
+	if (sfc->version >= SFC_VER_8)
+		return clk_get_rate(sfc->clk) / 2;
+	else
+		return clk_get_rate(sfc->clk);
+}
+
 static void rockchip_sfc_irq_unmask(struct rockchip_sfc *sfc, u32 mask)
 {
 	u32 reg;
@@ -519,12 +536,12 @@ static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op
 
 	if (unlikely(mem->spi->max_speed_hz != sfc->speed[cs]) &&
 	    !has_acpi_companion(sfc->dev)) {
-		ret = clk_set_rate(sfc->clk, mem->spi->max_speed_hz);
+		ret = rockchip_sfc_clk_set_rate(sfc, mem->spi->max_speed_hz);
 		if (ret)
 			goto out;
 		sfc->speed[cs] = mem->spi->max_speed_hz;
 		dev_dbg(sfc->dev, "set_freq=%dHz real_freq=%ldHz\n",
-			sfc->speed[cs], clk_get_rate(sfc->clk));
+			sfc->speed[cs], rockchip_sfc_clk_get_rate(sfc));
 	}
 
 	rockchip_sfc_adjust_op_work((struct spi_mem_op *)op);
-- 
2.34.1



From smostafa at google.com  Thu Dec 19 06:24:05 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 19 Dec 2024 14:24:05 +0000
Subject: [RFC PATCH v2 55/58] drivers/iommu: Add deferred map_sg
 operations
In-Reply-To: <ce4c8db4-4895-426b-8d9d-97dc5d74fbc4@arm.com>
References: <20241212180423.1578358-1-smostafa@google.com>
 <20241212180423.1578358-56-smostafa@google.com>
 <ce4c8db4-4895-426b-8d9d-97dc5d74fbc4@arm.com>
Message-ID: <Z2Qshft8lQjI-x7c@google.com>

Hi Robin,

On Thu, Dec 19, 2024 at 12:48:27PM +0000, Robin Murphy wrote:
> On 2024-12-12 6:04 pm, Mostafa Saleh wrote:
> > With pKVM SMMUv3 driver which para-virtualizes the IOMMU in the
> > hypervisor, has an extra overhead with map_sg, as it loops over
> > iommu_map, and for each map requires context switching, disabling
> > interrupts...
> > 
> > Instead, add an new domain operations:
> > - alloc_cookie_sg: Allocate a new sg deferred cookie
> > - add_deferred_map_sg: Add a mapping to the cookie
> > - consume_deferred_map_sg: Consume and release the cookie
> > 
> > Alternativly, we can pass the sg list as is. However, this would
> > duplicate some of the logic and it would make more sense to
> > conolidate all the sg list parsing for IOMMU drivers in one place.
> 
> But why bother with fiddly overly-specific machinery at all when you can
> already make ->map_pages asynchronous and consolidate the expensive part
> into ->iotlb_sync_map in general, like s390 does?

This was my initial idea too. But I believe there is no enough context in
iotlb_sync_map, so we either have to create a per-domain deferred_map list
which is synced on any iotlb_sync_map, but that would require to lock the
map operation, hence impacting concurrency.

Or we have to use some complex logic to extract context from iotlb_sync_map,
(something like range iova tree in map and then on sync we can retrieve that)
That?s why I proposed this approach, where the IOMMU subsystem by design is
aware of the semantics and ?helps? by providing the right data structures/calls.

I had a quick look now at s390, and it seems a bit different as they only
notify the hypervisor about the iova range being changed, and don?t need
to provide iova->paddr mapping which pKVM does.

Thanks,
Mostafa
> 
> Thanks,
> Robin.
> 
> > virtio-iommu is another IOMMU that can benfit from this, but it
> > would need to have a new operation that standerdize passing
> > an sglist based on these ops.
> > 
> > Signed-off-by: Mostafa Saleh <smostafa at google.com>
> > ---
> >   drivers/iommu/iommu.c | 53 +++++++++++++++++++++++++++++++++++++++++--
> >   include/linux/iommu.h | 19 ++++++++++++++++
> >   2 files changed, 70 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 83c8e617a2c5..3a3c48631dd6 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -2608,6 +2608,37 @@ size_t iommu_unmap_fast(struct iommu_domain *domain,
> >   }
> >   EXPORT_SYMBOL_GPL(iommu_unmap_fast);
> > +static int __iommu_add_sg(struct iommu_map_cookie_sg *cookie_sg,
> > +			  unsigned long iova, phys_addr_t paddr, size_t size)
> > +{
> > +	struct iommu_domain *domain = cookie_sg->domain;
> > +	const struct iommu_domain_ops *ops = domain->ops;
> > +	unsigned int min_pagesz;
> > +	size_t pgsize, count;
> > +
> > +	if (unlikely(!(domain->type & __IOMMU_DOMAIN_PAGING)))
> > +		return -EINVAL;
> > +
> > +	if (WARN_ON(domain->pgsize_bitmap == 0UL))
> > +		return -ENODEV;
> > +
> > +	/* find out the minimum page size supported */
> > +	min_pagesz = 1 << __ffs(domain->pgsize_bitmap);
> > +
> > +	/*
> > +	 * both the virtual address and the physical one, as well as
> > +	 * the size of the mapping, must be aligned (at least) to the
> > +	 * size of the smallest page supported by the hardware
> > +	 */
> > +	if (!IS_ALIGNED(iova | paddr | size, min_pagesz)) {
> > +		pr_err("unaligned: iova 0x%lx pa %pa size 0x%zx min_pagesz 0x%x\n",
> > +		       iova, &paddr, size, min_pagesz);
> > +		return -EINVAL;
> > +	}
> > +	pgsize = iommu_pgsize(domain, iova, paddr, size, &count);
> > +	return ops->add_deferred_map_sg(cookie_sg, paddr, pgsize, count);
> > +}
> > +
> >   ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
> >   		     struct scatterlist *sg, unsigned int nents, int prot,
> >   		     gfp_t gfp)
> > @@ -2617,6 +2648,9 @@ ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
> >   	phys_addr_t start;
> >   	unsigned int i = 0;
> >   	int ret;
> > +	bool deferred_sg = ops->alloc_cookie_sg && ops->add_deferred_map_sg &&
> > +			   ops->consume_deferred_map_sg;
> > +	struct iommu_map_cookie_sg *cookie_sg;
> >   	might_sleep_if(gfpflags_allow_blocking(gfp));
> > @@ -2625,12 +2659,24 @@ ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
> >   				__GFP_HIGHMEM)))
> >   		return -EINVAL;
> > +	if (deferred_sg) {
> > +		cookie_sg = ops->alloc_cookie_sg(iova, prot, nents, gfp);
> > +		if (!cookie_sg) {
> > +			pr_err("iommu: failed alloc cookie\n");
> > +			return -ENOMEM;
> > +		}
> > +		cookie_sg->domain = domain;
> > +	}
> > +
> >   	while (i <= nents) {
> >   		phys_addr_t s_phys = sg_phys(sg);
> >   		if (len && s_phys != start + len) {
> > -			ret = __iommu_map(domain, iova + mapped, start,
> > -					len, prot, gfp);
> > +			if (deferred_sg)
> > +				ret = __iommu_add_sg(cookie_sg, iova + mapped, start, len);
> > +			else
> > +				ret = __iommu_map(domain, iova + mapped, start,
> > +						  len, prot, gfp);
> >   			if (ret)
> >   				goto out_err;
> > @@ -2654,6 +2700,9 @@ ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
> >   			sg = sg_next(sg);
> >   	}
> > +	if (deferred_sg)
> > +		ops->consume_deferred_map_sg(cookie_sg);
> > +
> >   	if (ops->iotlb_sync_map) {
> >   		ret = ops->iotlb_sync_map(domain, iova, mapped);
> >   		if (ret)
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index c75877044185..5e60ac349228 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -601,6 +601,14 @@ struct iommu_ops {
> >   	u8 user_pasid_table:1;
> >   };
> > +/**
> > + * struct iommu_map_cookie_sg - Cookie for a deferred map sg
> > + * @domain: Domain for the sg lit
> > + */
> > +struct iommu_map_cookie_sg {
> > +	struct iommu_domain *domain;
> > +};
> > +
> >   /**
> >    * struct iommu_domain_ops - domain specific operations
> >    * @attach_dev: attach an iommu domain to a device
> > @@ -638,6 +646,11 @@ struct iommu_ops {
> >    * @enable_nesting: Enable nesting
> >    * @set_pgtable_quirks: Set io page table quirks (IO_PGTABLE_QUIRK_*)
> >    * @free: Release the domain after use.
> > + * @alloc_cookie_sg: Allocate a cookie that would be used to create
> > + *		     a sg list, filled from the next functions
> > + * @add_deferred_map_sg: Add a mapping to a cookie of a sg list.
> > + * @consume_deferred_map_sg: Consume the sg list as now all mappings are added,
> > + *			     it should also release the cookie as it's not used.
> >    */
> >   struct iommu_domain_ops {
> >   	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
> > @@ -668,6 +681,12 @@ struct iommu_domain_ops {
> >   				  unsigned long quirks);
> >   	void (*free)(struct iommu_domain *domain);
> > +
> > +	struct iommu_map_cookie_sg *(*alloc_cookie_sg)(unsigned long iova, int prot,
> > +						       unsigned int nents, gfp_t gfp);
> > +	int (*add_deferred_map_sg)(struct iommu_map_cookie_sg *cookie,
> > +				   phys_addr_t paddr, size_t pgsize, size_t pgcount);
> > +	int (*consume_deferred_map_sg)(struct iommu_map_cookie_sg *cookie);
> >   };
> >   /**
> 


From csokas.bence at prolan.hu  Thu Dec 19 06:28:51 2024
From: csokas.bence at prolan.hu (=?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?=)
Date: Thu, 19 Dec 2024 15:28:51 +0100
Subject: [PATCH] spi: atmel-quadspi: Use devm_ clock management
Message-ID: <20241219142851.430959-1-csokas.bence@prolan.hu>

Clean up error handling by using the new devm_
clock handling functions. This should make it
easier to add new code, as we can eliminate the
"goto ladder" in probe().

Signed-off-by: Bence Cs?k?s <csokas.bence at prolan.hu>
---
 drivers/spi/atmel-quadspi.c | 42 ++++++++++---------------------------
 1 file changed, 11 insertions(+), 31 deletions(-)

diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index 73cf0c3f1477..0353f8e1384d 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -1381,50 +1381,37 @@ static int atmel_qspi_probe(struct platform_device *pdev)
 	aq->mmap_phys_base = (dma_addr_t)res->start;
 
 	/* Get the peripheral clock */
-	aq->pclk = devm_clk_get(&pdev->dev, "pclk");
+	aq->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
 	if (IS_ERR(aq->pclk))
-		aq->pclk = devm_clk_get(&pdev->dev, NULL);
+		aq->pclk = devm_clk_get_enabled(&pdev->dev, NULL);
 
 	if (IS_ERR(aq->pclk))
 		return dev_err_probe(&pdev->dev, PTR_ERR(aq->pclk),
 				     "missing peripheral clock\n");
 
-	/* Enable the peripheral clock */
-	err = clk_prepare_enable(aq->pclk);
-	if (err)
-		return dev_err_probe(&pdev->dev, err,
-				     "failed to enable the peripheral clock\n");
-
 	if (aq->caps->has_qspick) {
 		/* Get the QSPI system clock */
-		aq->qspick = devm_clk_get(&pdev->dev, "qspick");
+		aq->qspick = devm_clk_get_enabled(&pdev->dev, "qspick");
 		if (IS_ERR(aq->qspick)) {
 			dev_err(&pdev->dev, "missing system clock\n");
 			err = PTR_ERR(aq->qspick);
-			goto disable_pclk;
+			return err;
 		}
 
-		/* Enable the QSPI system clock */
-		err = clk_prepare_enable(aq->qspick);
-		if (err) {
-			dev_err(&pdev->dev,
-				"failed to enable the QSPI system clock\n");
-			goto disable_pclk;
-		}
 	} else if (aq->caps->has_gclk) {
 		/* Get the QSPI generic clock */
 		aq->gclk = devm_clk_get(&pdev->dev, "gclk");
 		if (IS_ERR(aq->gclk)) {
 			dev_err(&pdev->dev, "missing Generic clock\n");
 			err = PTR_ERR(aq->gclk);
-			goto disable_pclk;
+			return err;
 		}
 	}
 
 	if (aq->caps->has_dma) {
 		err = atmel_qspi_dma_init(ctrl);
 		if (err == -EPROBE_DEFER)
-			goto disable_qspick;
+			return err;
 	}
 
 	/* Request the IRQ */
@@ -1464,10 +1451,6 @@ static int atmel_qspi_probe(struct platform_device *pdev)
 dma_release:
 	if (aq->caps->has_dma)
 		atmel_qspi_dma_release(aq);
-disable_qspick:
-	clk_disable_unprepare(aq->qspick);
-disable_pclk:
-	clk_disable_unprepare(aq->pclk);
 
 	return err;
 }
@@ -1506,7 +1489,6 @@ static int atmel_qspi_sama7g5_suspend(struct atmel_qspi *aq)
 	if (ret)
 		return ret;
 
-	clk_disable_unprepare(aq->pclk);
 	return 0;
 }
 
@@ -1531,8 +1513,6 @@ static void atmel_qspi_remove(struct platform_device *pdev)
 		}
 
 		atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
-		clk_disable(aq->qspick);
-		clk_disable(aq->pclk);
 	} else {
 		/*
 		 * atmel_qspi_runtime_{suspend,resume} just disable and enable
@@ -1542,9 +1522,6 @@ static void atmel_qspi_remove(struct platform_device *pdev)
 		dev_warn(&pdev->dev, "Failed to resume device on remove\n");
 	}
 
-	clk_unprepare(aq->qspick);
-	clk_unprepare(aq->pclk);
-
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
 	pm_runtime_put_noidle(&pdev->dev);
@@ -1560,8 +1537,11 @@ static int __maybe_unused atmel_qspi_suspend(struct device *dev)
 	if (ret < 0)
 		return ret;
 
-	if (aq->caps->has_gclk)
-		return atmel_qspi_sama7g5_suspend(aq);
+	if (aq->caps->has_gclk) {
+		ret = atmel_qspi_sama7g5_suspend(aq);
+		clk_disable_unprepare(aq->pclk);
+		return ret;
+	}
 
 	atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
 
-- 
2.34.1




From peng.fan at oss.nxp.com  Thu Dec 19 06:50:29 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 19 Dec 2024 22:50:29 +0800
Subject: [PATCH V3] soc: imx8m: Unregister cpufreq and soc dev in cleanup path
Message-ID: <20241219145029.1776006-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Unregister the cpufreq device and soc device when resource unwinding,
otherwise there will be warning when do removing test:
sysfs: cannot create duplicate filename '/devices/platform/imx-cpufreq-dt'
CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.13.0-rc1-next-20241204
Hardware name: NXP i.MX8MPlus EVK board (DT)

Fixes: 9cc832d37799 ("soc: imx8m: Probe the SoC driver as platform driver")
Cc: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---

V3:
 Per Marco, drop remove function, use devm_add_action and update the patch
 title accordingly.

V2:
 Add err check when create the cpufreq platform device
 https://lore.kernel.org/all/20241217015826.1374497-1-peng.fan at oss.nxp.com/

 drivers/soc/imx/soc-imx8m.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
index 8ac7658e3d52..585631b7ae44 100644
--- a/drivers/soc/imx/soc-imx8m.c
+++ b/drivers/soc/imx/soc-imx8m.c
@@ -192,9 +192,20 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
 	devm_kasprintf((dev), GFP_KERNEL, "%d.%d", ((soc_rev) >> 4) & 0xf, (soc_rev) & 0xf) : \
 	"unknown"
 
+static void imx8m_unregister_soc(void *data)
+{
+	soc_device_unregister(data);
+}
+
+static void imx8m_unregister_cpufreq(void *data)
+{
+	platform_device_unregister(data);
+}
+
 static int imx8m_soc_probe(struct platform_device *pdev)
 {
 	struct soc_device_attribute *soc_dev_attr;
+	struct platform_device *cpufreq_dev;
 	const struct imx8_soc_data *data;
 	struct device *dev = &pdev->dev;
 	const struct of_device_id *id;
@@ -239,11 +250,19 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 	if (IS_ERR(soc_dev))
 		return PTR_ERR(soc_dev);
 
+	ret = devm_add_action(dev, imx8m_unregister_soc, soc_dev);
+	if (ret)
+		return ret;
+
 	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
 		soc_dev_attr->revision);
 
-	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
-		platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
+	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) {
+		cpufreq_dev = platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
+		ret = devm_add_action(dev, imx8m_unregister_cpufreq, cpufreq_dev);
+		if (ret)
+			return ret;
+	}
 
 	return 0;
 }
-- 
2.37.1



From robdclark at gmail.com  Thu Dec 19 07:00:48 2024
From: robdclark at gmail.com (Rob Clark)
Date: Thu, 19 Dec 2024 07:00:48 -0800
Subject: [PATCH] iommu/arm-smmu-qcom: Only enable stall on smmu-v2
In-Reply-To: <41d93dac-4ef1-4cc7-a7b2-24c8289f905f@arm.com>
References: <20241216171017.4881-1-robdclark@gmail.com> <20241219113019.GA23640@willie-the-truck>
 <41d93dac-4ef1-4cc7-a7b2-24c8289f905f@arm.com>
Message-ID: <CAF6AEGshSjOr1DE63WiXwAyH39-Tz9B3MEkKUo6sg1jpQPYZcA@mail.gmail.com>

On Thu, Dec 19, 2024 at 4:08?AM Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2024-12-19 11:30 am, Will Deacon wrote:
> > On Mon, Dec 16, 2024 at 09:10:17AM -0800, Rob Clark wrote:
> >> From: Rob Clark <robdclark at chromium.org>
> >>
> >> On mmu-500, stall-on-fault seems to stall all context banks, causing the
> >> GMU to misbehave.  So limit this feature to smmu-v2 for now.
> >
> > MMU-500 has public documentation so please can you dig up what the
> > actual behaviour is rather than guess?
>
> Yeah, I'm pretty sure that's not true as stated, especially with
> SCTLR.HUPCF set as qcom_adreno_smmu_write_sctlr() does. However it is
> plausible that at the system interconnect level, a sufficient number of
> stalled transactions might backpressure other transactions from entering
> the same TBU, even if they are destined for a different context. That's
> more about the configuration and integration of individual SoCs than the
> SMMU IP used.

I am aware of the docs and I've spent most of the last couple days
going thru them, as well as the errata, since it would be unfortunate
for debugging to disable this ;-)

The scenario where things lock up involves at least a few thousand
faults in rapid succession.  Disabling CFIE in the irq handler and
re-enabling when I resume translation does stop the flood of irq's but
not the lockup.  It might well be something about how the smmu is
integrated with the interconnect.

BR,
-R

> Robin.
>
> >> This fixes an issue with an older mesa bug taking outo the system
> >> because of GMU going off into the year.
> >
> > Sorry, but I don't understand this sentence.
> >
> > Will
>


From jic23 at kernel.org  Thu Dec 19 07:10:56 2024
From: jic23 at kernel.org (Jonathan Cameron)
Date: Thu, 19 Dec 2024 15:10:56 +0000
Subject: [PATCH 3/9] iio: trigger: stm32-timer: add support for
 stm32mp25
In-Reply-To: <20241218090153.742869-4-fabrice.gasnier@foss.st.com>
References: <20241218090153.742869-1-fabrice.gasnier@foss.st.com>
	<20241218090153.742869-4-fabrice.gasnier@foss.st.com>
Message-ID: <20241219151056.26e21aed@jic23-huawei>

On Wed, 18 Dec 2024 10:01:47 +0100
Fabrice Gasnier <fabrice.gasnier at foss.st.com> wrote:

> Add support for STM32MP25 SoC. Use newly introduced compatible to handle
> this new HW variant. Add TIM20 trigger definitions that can be used by
> the stm32 analog-to-digital converter. Use compatible data to identify
> it.
> As the counter framework is now superseding the deprecated IIO counter
> interface (IIO_COUNT), don't support it. Only register IIO trigger
> devices for ADC usage. So, make the valids_table a cfg option.
> 
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
Looks good to me.  Looks like I can just pick this up for IIO?

Or is thOre a dependency I'm missing?

Just in case it goes another route.
Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

Jonathan
> ---
>  drivers/iio/trigger/stm32-timer-trigger.c     | 21 +++++++++++++++++--
>  include/linux/iio/timer/stm32-timer-trigger.h |  6 ++++++
>  2 files changed, 25 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c
> index bb60b2d7b2ec..8aaf3abf044e 100644
> --- a/drivers/iio/trigger/stm32-timer-trigger.c
> +++ b/drivers/iio/trigger/stm32-timer-trigger.c
> @@ -38,6 +38,9 @@ static const void *triggers_table[][MAX_TRIGGERS] = {
>  	{ TIM15_TRGO,},
>  	{ TIM16_OC1,},
>  	{ TIM17_OC1,},
> +	{ }, /* timer 18 */
> +	{ }, /* timer 19 */
> +	{ TIM20_TRGO, TIM20_TRGO2, TIM20_OC1, TIM20_OC2, TIM20_OC3, },
>  };
>  
>  /* List the triggers accepted by each timer */
> @@ -781,7 +784,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
>  		return -EINVAL;
>  
>  	/* Create an IIO device only if we have triggers to be validated */
> -	if (*cfg->valids_table[index])
> +	if (cfg->valids_table && *cfg->valids_table[index])
>  		priv = stm32_setup_counter_device(dev);
>  	else
>  		priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> @@ -794,7 +797,8 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
>  	priv->clk = ddata->clk;
>  	priv->max_arr = ddata->max_arr;
>  	priv->triggers = triggers_table[index];
> -	priv->valids = cfg->valids_table[index];
> +	if (cfg->valids_table && *cfg->valids_table[index])
> +		priv->valids = cfg->valids_table[index];
>  	stm32_timer_detect_trgo2(priv);
>  	mutex_init(&priv->lock);
>  
> @@ -886,6 +890,16 @@ static const struct stm32_timer_trigger_cfg stm32h7_timer_trg_cfg = {
>  	.num_valids_table = ARRAY_SIZE(stm32h7_valids_table),
>  };
>  
> +static const struct stm32_timer_trigger_cfg stm32mp25_timer_trg_cfg = {
> +	/*
> +	 * valids_table not used: counter framework is now superseding the deprecated IIO
> +	 * counter interface (IIO_COUNT), so don't support it. num_valids_table is only
> +	 * kept here to register the IIO HW triggers. valids_table should be moved at some
> +	 * point to the stm32-timer-cnt driver instead.
> +	 */
> +	.num_valids_table = ARRAY_SIZE(triggers_table),
> +};
> +
>  static const struct of_device_id stm32_trig_of_match[] = {
>  	{
>  		.compatible = "st,stm32-timer-trigger",
> @@ -893,6 +907,9 @@ static const struct of_device_id stm32_trig_of_match[] = {
>  	}, {
>  		.compatible = "st,stm32h7-timer-trigger",
>  		.data = (void *)&stm32h7_timer_trg_cfg,
> +	}, {
> +		.compatible = "st,stm32mp25-timer-trigger",
> +		.data = (void *)&stm32mp25_timer_trg_cfg,
>  	},
>  	{ /* end node */ },
>  };
> diff --git a/include/linux/iio/timer/stm32-timer-trigger.h b/include/linux/iio/timer/stm32-timer-trigger.h
> index 37572e4dc73a..1ee237b56183 100644
> --- a/include/linux/iio/timer/stm32-timer-trigger.h
> +++ b/include/linux/iio/timer/stm32-timer-trigger.h
> @@ -72,6 +72,12 @@
>  
>  #define TIM17_OC1	"tim17_oc1"
>  
> +#define TIM20_OC1	"tim20_oc1"
> +#define TIM20_OC2	"tim20_oc2"
> +#define TIM20_OC3	"tim20_oc3"
> +#define TIM20_TRGO	"tim20_trgo"
> +#define TIM20_TRGO2	"tim20_trgo2"
> +
>  #if IS_REACHABLE(CONFIG_IIO_STM32_TIMER_TRIGGER)
>  bool is_stm32_timer_trigger(struct iio_trigger *trig);
>  #else



From john at quad.stoffel.home  Thu Dec 19 07:14:03 2024
From: john at quad.stoffel.home (John Stoffel)
Date: Thu, 19 Dec 2024 10:14:03 -0500
Subject: [PATCH v4 00/16] KVM: selftests: "tree" wide overhauls
In-Reply-To: <Z2N-UlxgYlGT_1Or@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
 <173455833964.3185228.5614329030867008316.b4-ty@google.com>
 <Z2NIwmRDaZBc_V4o@google.com>
 <Z2N-UlxgYlGT_1Or@google.com>
Message-ID: <Z2Q4O78gZZt-53DI@quad.stoffel.home>

On Wed, Dec 18, 2024 at 06:00:50PM -0800, Sean Christopherson wrote:
> On Wed, Dec 18, 2024, Sean Christopherson wrote:
> > On Wed, Dec 18, 2024, Sean Christopherson wrote:
> > > On Wed, 27 Nov 2024 16:55:31 -0800, Sean Christopherson wrote:
> > > > Two separate series (mmu_stress_test[1] and $ARCH[2]), posted as one to
> > > > avoid unpleasant conflicts, and because I hope to land both in kvm/next
> > > > shortly after 6.12-rc1 since they impact all of KVM selftests.
> > > > 
> > > > mmu_stress_test
> > > > ---------------
> > > > Convert the max_guest_memory_test into a more generic mmu_stress_test.
> > > > The basic gist of the "conversion" is to have the test do mprotect() on
> > > > guest memory while vCPUs are accessing said memory, e.g. to verify KVM
> > > > and mmu_notifiers are working as intended.
> > > > 
> > > > [...]
> > > 
> > > As I am running out of time before I disappear for two weeks, applied to:
> > > 
> > >    https://github.com/kvm-x86/linux.git selftests_arch
> > > 
> > > Other KVM maintainers, that branch is officially immutable.  I also pushed a tag,
> > > kvm-selftests-arch-6.14, just in case I pull a stupid and manage to clobber the
> > > branch.  My apologies if this causes pain.  AFAICT, there aren't any queued or
> > > in-flight patches that git's rename magic can't automatically handle, so hopefully
> > > this ends up being pain-free.
> > > 
> > > Paolo, here's a pull request if you want to pull this into kvm/next long before
> > > the 6.14 merge window.  Diff stats at the very bottom (hilariously long).
> > 
> > Argh!  I completely forget to build test this on non-x86, and missed that arm64
> > snuck in 75cd027cbcb1 ("KVM: arm64: selftests: Test ID_AA64PFR0.MPAM isn't completely 
> > ignored").  *sigh*
> > 
> > Given that I just sent out mail, I'm going to cross my fingers and hope that no
> > one has merged the above branch/tag.  I've deleted the branch and tags from the
> > remote, but kept the tag locally just in case.
> > 
> > Please holler if you managed to grab the broken branch/tag.  If no one screams,
> > I'll assume I got luckly and will push a fixed version (with different names) later
> > today.
> 
> Third time is the charm.  Compile tested on all architectures, and runtime tested
> on x86 and arm64.
> 
>   https://github.com/kvm-x86/linux.git selftests_treewide_6.14
> 
> ---
> The following changes since commit 3522c419758ee8dca5a0e8753ee0070a22157bc1:
> 
>   Merge tag 'kvm-riscv-fixes-6.13-1' of https://github.com/kvm-riscv/linux into HEAD (2024-12-13 13:59:20 -0500)
> 
> are available in the Git repository at:
> 
>   https://github.com/kvm-x86/linux.git tags/kvm-selftests-treewide-6.14
> 
> for you to fetch changes up to 9af04539d474dda4984ff4909d4568e6123c8cba:
> 
>   KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR (2024-12-18 14:15:05 -0800)
> 
> ----------------------------------------------------------------
> KVM selftests "tree"-wide changes for 6.14:
> 
>  - Rework vcpu_get_reg() to return a value instead of using an out-param, and
>    update all affected arch code accordingly.
> 
>  - Convert the max_guest_memory_test into a more generic mmu_stress_test.
>    The basic gist of the "conversion" is to have the test do mprotect() on
>    guest memory while vCPUs are accessing said memory, e.g. to verify KVM
>    and mmu_notifiers are working as intended.
> 
>  - Play nice with treewrite builds of unsupported architectures, e.g. arm

nit:  treewide, not treewrite

>    (32-bit), as KVM selftests' Makefile doesn't do anything to ensure the
>    target architecture is actually one KVM selftests supports.
> 
>  - Use the kernel's $(ARCH) definition instead of the target triple for arch
>    specific directories, e.g. arm64 instead of aarch64, mainly so as not to
>    be different from the rest of the kernel.
> 
> ----------------------------------------------------------------
> Sean Christopherson (16):
>       KVM: Move KVM_REG_SIZE() definition to common uAPI header
>       KVM: selftests: Return a value from vcpu_get_reg() instead of using an out-param
>       KVM: selftests: Assert that vcpu_{g,s}et_reg() won't truncate
>       KVM: selftests: Check for a potential unhandled exception iff KVM_RUN succeeded
>       KVM: selftests: Rename max_guest_memory_test to mmu_stress_test
>       KVM: selftests: Only muck with SREGS on x86 in mmu_stress_test
>       KVM: selftests: Compute number of extra pages needed in mmu_stress_test
>       KVM: sefltests: Explicitly include ucall_common.h in mmu_stress_test.c
>       KVM: selftests: Enable mmu_stress_test on arm64
>       KVM: selftests: Use vcpu_arch_put_guest() in mmu_stress_test
>       KVM: selftests: Precisely limit the number of guest loops in mmu_stress_test
>       KVM: selftests: Add a read-only mprotect() phase to mmu_stress_test
>       KVM: selftests: Verify KVM correctly handles mprotect(PROT_READ)
>       KVM: selftests: Provide empty 'all' and 'clean' targets for unsupported ARCHs
>       KVM: selftests: Use canonical $(ARCH) paths for KVM selftests directories
>       KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR
> --
> 
> [01/16] KVM: Move KVM_REG_SIZE() definition to common uAPI header
>         https://github.com/kvm-x86/linux/commit/915d2f0718a4
> [02/16] KVM: selftests: Return a value from vcpu_get_reg() instead of using an out-param
>         https://github.com/kvm-x86/linux/commit/09bb926d2907
> [03/16] KVM: selftests: Assert that vcpu_{g,s}et_reg() won't truncate
>         https://github.com/kvm-x86/linux/commit/fe85ce31b289
> [04/16] KVM: selftests: Check for a potential unhandled exception iff KVM_RUN succeeded
>         https://github.com/kvm-x86/linux/commit/d6533c151338
> [05/16] KVM: selftests: Rename max_guest_memory_test to mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/b12391498d1e
> [06/16] KVM: selftests: Only muck with SREGS on x86 in mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/55e164df482a
> [07/16] KVM: selftests: Compute number of extra pages needed in mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/1ddd3ea75ac3
> [08/16] KVM: sefltests: Explicitly include ucall_common.h in mmu_stress_test.c
>         https://github.com/kvm-x86/linux/commit/c35d8f579e50
> [09/16] KVM: selftests: Enable mmu_stress_test on arm64
>         https://github.com/kvm-x86/linux/commit/8abe7632a1ee
> [10/16] KVM: selftests: Use vcpu_arch_put_guest() in mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/3a0422526404
> [11/16] KVM: selftests: Precisely limit the number of guest loops in mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/82b542e11848
> [12/16] KVM: selftests: Add a read-only mprotect() phase to mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/80b7859a3a43
> [13/16] KVM: selftests: Verify KVM correctly handles mprotect(PROT_READ)
>         https://github.com/kvm-x86/linux/commit/b6c304aec648
> [14/16] KVM: selftests: Provide empty 'all' and 'clean' targets for unsupported ARCHs
>         https://github.com/kvm-x86/linux/commit/43fbd8cd389f
> [15/16] KVM: selftests: Use canonical $(ARCH) paths for KVM selftests directories
>         https://github.com/kvm-x86/linux/commit/67730e6c53d7
> [16/16] KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR
>         https://github.com/kvm-x86/linux/commit/9af04539d474
> 
> 
>  MAINTAINERS                                                                          |  12 +--
>  arch/arm64/include/uapi/asm/kvm.h                                                    |   3 -
>  arch/riscv/include/uapi/asm/kvm.h                                                    |   3 -
>  include/uapi/linux/kvm.h                                                             |   4 +
>  tools/testing/selftests/kvm/.gitignore                                               |   1 +
>  tools/testing/selftests/kvm/Makefile                                                 | 345 ++------------------------------------------------------------------------------
>  tools/testing/selftests/kvm/Makefile.kvm                                             | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tools/testing/selftests/kvm/{aarch64 => arm64}/aarch32_id_regs.c                     |  10 +--
>  tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer.c                          |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer_edge_cases.c               |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/debug-exceptions.c                    |   4 +-
>  tools/testing/selftests/kvm/{aarch64 => arm64}/get-reg-list.c                        |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/hypercalls.c                          |   6 +-
>  tools/testing/selftests/kvm/{aarch64 => arm64}/mmio_abort.c                          |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/no-vgic-v3.c                          |   2 +-
>  tools/testing/selftests/kvm/{aarch64 => arm64}/page_fault_test.c                     |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/psci_test.c                           |   8 +-
>  tools/testing/selftests/kvm/{aarch64 => arm64}/set_id_regs.c                         |  22 +++---
>  tools/testing/selftests/kvm/{aarch64 => arm64}/smccc_filter.c                        |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/vcpu_width_config.c                   |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_init.c                           |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_irq.c                            |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_lpi_stress.c                     |   0
>  tools/testing/selftests/kvm/{aarch64 => arm64}/vpmu_counter_access.c                 |  19 +++--
>  tools/testing/selftests/kvm/dirty_log_perf_test.c                                    |   2 +-
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/arch_timer.h                  |   0
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/delay.h                       |   0
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic.h                         |   0
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3.h                      |   0
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3_its.h                  |   0
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/kvm_util_arch.h               |   0
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/processor.h                   |   0
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/spinlock.h                    |   0
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/ucall.h                       |   0
>  tools/testing/selftests/kvm/include/{aarch64 => arm64}/vgic.h                        |   0
>  tools/testing/selftests/kvm/include/kvm_util.h                                       |  10 ++-
>  tools/testing/selftests/kvm/include/{s390x => s390}/debug_print.h                    |   0
>  tools/testing/selftests/kvm/include/{s390x => s390}/diag318_test_handler.h           |   0
>  tools/testing/selftests/kvm/include/{s390x => s390}/facility.h                       |   0
>  tools/testing/selftests/kvm/include/{s390x => s390}/kvm_util_arch.h                  |   0
>  tools/testing/selftests/kvm/include/{s390x => s390}/processor.h                      |   0
>  tools/testing/selftests/kvm/include/{s390x => s390}/sie.h                            |   0
>  tools/testing/selftests/kvm/include/{s390x => s390}/ucall.h                          |   0
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/apic.h                           |   2 -
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/evmcs.h                          |   3 -
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/hyperv.h                         |   3 -
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/kvm_util_arch.h                  |   0
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/mce.h                            |   2 -
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/pmu.h                            |   0
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/processor.h                      |   2 -
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/sev.h                            |   0
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/svm.h                            |   6 --
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/svm_util.h                       |   3 -
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/ucall.h                          |   0
>  tools/testing/selftests/kvm/include/{x86_64 => x86}/vmx.h                            |   2 -
>  tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic.c                             |   0
>  tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_private.h                     |   0
>  tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3.c                          |   0
>  tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3_its.c                      |   0
>  tools/testing/selftests/kvm/lib/{aarch64 => arm64}/handlers.S                        |   0
>  tools/testing/selftests/kvm/lib/{aarch64 => arm64}/processor.c                       |   8 +-
>  tools/testing/selftests/kvm/lib/{aarch64 => arm64}/spinlock.c                        |   0
>  tools/testing/selftests/kvm/lib/{aarch64 => arm64}/ucall.c                           |   0
>  tools/testing/selftests/kvm/lib/{aarch64 => arm64}/vgic.c                            |   0
>  tools/testing/selftests/kvm/lib/kvm_util.c                                           |   3 +-
>  tools/testing/selftests/kvm/lib/riscv/processor.c                                    |  66 ++++++++--------
>  tools/testing/selftests/kvm/lib/{s390x => s390}/diag318_test_handler.c               |   0
>  tools/testing/selftests/kvm/lib/{s390x => s390}/facility.c                           |   0
>  tools/testing/selftests/kvm/lib/{s390x => s390}/processor.c                          |   0
>  tools/testing/selftests/kvm/lib/{s390x => s390}/ucall.c                              |   0
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/apic.c                               |   0
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/handlers.S                           |   0
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/hyperv.c                             |   0
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/memstress.c                          |   2 +-
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/pmu.c                                |   0
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/processor.c                          |   2 -
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/sev.c                                |   0
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/svm.c                                |   1 -
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/ucall.c                              |   0
>  tools/testing/selftests/kvm/lib/{x86_64 => x86}/vmx.c                                |   2 -
>  tools/testing/selftests/kvm/{max_guest_memory_test.c => mmu_stress_test.c}           | 162 ++++++++++++++++++++++++++++++++++----
>  tools/testing/selftests/kvm/riscv/arch_timer.c                                       |   2 +-
>  tools/testing/selftests/kvm/riscv/ebreak_test.c                                      |   2 +-
>  tools/testing/selftests/kvm/riscv/sbi_pmu_test.c                                     |   2 +-
>  tools/testing/selftests/kvm/{s390x => s390}/cmma_test.c                              |   0
>  tools/testing/selftests/kvm/{s390x => s390}/config                                   |   0
>  tools/testing/selftests/kvm/{s390x => s390}/cpumodel_subfuncs_test.c                 |   0
>  tools/testing/selftests/kvm/{s390x => s390}/debug_test.c                             |   0
>  tools/testing/selftests/kvm/{s390x => s390}/memop.c                                  |   0
>  tools/testing/selftests/kvm/{s390x => s390}/resets.c                                 |   2 +-
>  tools/testing/selftests/kvm/{s390x => s390}/shared_zeropage_test.c                   |   0
>  tools/testing/selftests/kvm/{s390x => s390}/sync_regs_test.c                         |   0
>  tools/testing/selftests/kvm/{s390x => s390}/tprot.c                                  |   0
>  tools/testing/selftests/kvm/{s390x => s390}/ucontrol_test.c                          |   0
>  tools/testing/selftests/kvm/set_memory_region_test.c                                 |   6 +-
>  tools/testing/selftests/kvm/steal_time.c                                             |   3 +-
>  tools/testing/selftests/kvm/{x86_64 => x86}/amx_test.c                               |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/apic_bus_clock_test.c                    |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/cpuid_test.c                             |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c                    |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/debug_regs.c                             |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/dirty_log_page_splitting_test.c          |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/exit_on_emulation_failure_test.c         |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/feature_msrs_test.c                      |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/fix_hypercall_test.c                     |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/flds_emulation.h                         |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/hwcr_msr_test.c                          |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_clock.c                           |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_cpuid.c                           |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_evmcs.c                           |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_extended_hypercalls.c             |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_features.c                        |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_ipi.c                             |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_svm_test.c                        |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_tlb_flush.c                       |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/kvm_clock_test.c                         |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/kvm_pv_test.c                            |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/max_vcpuid_cap_test.c                    |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/monitor_mwait_test.c                     |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/nested_exceptions_test.c                 |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.c                     |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.sh                    |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/platform_info_test.c                     |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/pmu_counters_test.c                      |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/pmu_event_filter_test.c                  |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_conversions_test.c           |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_kvm_exits_test.c             |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/recalc_apic_map_test.c                   |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/set_boot_cpu_id.c                        |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/set_sregs_test.c                         |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/sev_init2_tests.c                        |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/sev_migrate_tests.c                      |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/sev_smoke_test.c                         |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/smaller_maxphyaddr_emulation_test.c      |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/smm_test.c                               |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/state_test.c                             |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/svm_int_ctl_test.c                       |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_shutdown_test.c               |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_soft_inject_test.c            |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/svm_vmcall_test.c                        |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/sync_regs_test.c                         |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/triple_fault_event_test.c                |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/tsc_msrs_test.c                          |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/tsc_scaling_sync.c                       |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/ucna_injection_test.c                    |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/userspace_io_test.c                      |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/userspace_msr_exit_test.c                |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_apic_access_test.c                   |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_close_while_nested_test.c            |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_dirty_log_test.c                     |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_exception_with_invalid_guest_state.c |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_invalid_nested_guest_state.c         |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_msrs_test.c                          |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_nested_tsc_scaling_test.c            |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_pmu_caps_test.c                      |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_preemption_timer_test.c              |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_set_nested_state_test.c              |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c                    |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/xapic_ipi_test.c                         |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/xapic_state_test.c                       |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/xcr0_cpuid_test.c                        |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/xen_shinfo_test.c                        |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/xen_vmcall_test.c                        |   0
>  tools/testing/selftests/kvm/{x86_64 => x86}/xss_msr_test.c                           |   0
>  164 files changed, 587 insertions(+), 480 deletions(-)
>  create mode 100644 tools/testing/selftests/kvm/Makefile.kvm
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/aarch32_id_regs.c (95%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer_edge_cases.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/debug-exceptions.c (99%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/get-reg-list.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/hypercalls.c (98%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/mmio_abort.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/no-vgic-v3.c (98%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/page_fault_test.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/psci_test.c (96%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/set_id_regs.c (97%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/smccc_filter.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vcpu_width_config.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_init.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_irq.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_lpi_stress.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vpmu_counter_access.c (97%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/arch_timer.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/delay.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3_its.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/kvm_util_arch.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/processor.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/spinlock.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/ucall.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/vgic.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/debug_print.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/diag318_test_handler.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/facility.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/kvm_util_arch.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/processor.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/sie.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/ucall.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/apic.h (98%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/evmcs.h (99%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/hyperv.h (99%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/kvm_util_arch.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/mce.h (94%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/pmu.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/processor.h (99%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/sev.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm.h (98%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm_util.h (94%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/ucall.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/vmx.h (99%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_private.h (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3_its.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/handlers.S (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/processor.c (98%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/spinlock.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/ucall.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/vgic.c (100%)
>  rename tools/testing/selftests/kvm/lib/{s390x => s390}/diag318_test_handler.c (100%)
>  rename tools/testing/selftests/kvm/lib/{s390x => s390}/facility.c (100%)
>  rename tools/testing/selftests/kvm/lib/{s390x => s390}/processor.c (100%)
>  rename tools/testing/selftests/kvm/lib/{s390x => s390}/ucall.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/apic.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/handlers.S (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/hyperv.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/memstress.c (98%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/pmu.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/processor.c (99%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/sev.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/svm.c (99%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/ucall.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/vmx.c (99%)
>  rename tools/testing/selftests/kvm/{max_guest_memory_test.c => mmu_stress_test.c} (60%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/cmma_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/config (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/cpumodel_subfuncs_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/debug_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/memop.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/resets.c (99%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/shared_zeropage_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/sync_regs_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/tprot.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/ucontrol_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/amx_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/apic_bus_clock_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/cpuid_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/debug_regs.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/dirty_log_page_splitting_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/exit_on_emulation_failure_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/feature_msrs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/fix_hypercall_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/flds_emulation.h (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hwcr_msr_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_clock.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_cpuid.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_evmcs.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_extended_hypercalls.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_features.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_ipi.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_svm_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_tlb_flush.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_clock_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_pv_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/max_vcpuid_cap_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/monitor_mwait_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/nested_exceptions_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.sh (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/platform_info_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_counters_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_event_filter_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_conversions_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_kvm_exits_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/recalc_apic_map_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/set_boot_cpu_id.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/set_sregs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_init2_tests.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_migrate_tests.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_smoke_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/smaller_maxphyaddr_emulation_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/smm_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/state_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_int_ctl_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_shutdown_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_soft_inject_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_vmcall_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/sync_regs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/triple_fault_event_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_msrs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_scaling_sync.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/ucna_injection_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_io_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_msr_exit_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_apic_access_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_close_while_nested_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_dirty_log_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_exception_with_invalid_guest_state.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_invalid_nested_guest_state.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_msrs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_nested_tsc_scaling_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_pmu_caps_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_preemption_timer_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_set_nested_state_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_ipi_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_state_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xcr0_cpuid_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_shinfo_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_vmcall_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xss_msr_test.c (100%)
> 

-- 


From tudor.ambarus at linaro.org  Thu Dec 19 07:42:11 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 19 Dec 2024 15:42:11 +0000
Subject: [PATCH 1/2] dt-bindings: mailbox: add support for referencing
 controllers solely by node
In-Reply-To: <20241219-recent-everyone-865b19864693@wendy>
References: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>
 <20241219-mbox_request_channel_by_args-v1-1-617a6910f842@linaro.org>
 <20241219-recent-everyone-865b19864693@wendy>
Message-ID: <d9e635c8-de05-4812-bf2b-11651f6da5c1@linaro.org>

Hi, Conor,

On 12/19/24 2:11 PM, Conor Dooley wrote:
>> There are mailbox clients that can discover the mailbox channel ID at
>> run-time. For such cases passing the channel identifier via DT is
>> redundant. Add support for referencing controllers solely by node.
> I don't really get your implementation, why not just allow #mbox-cells = 0?
> That's what's done for things like fixed frequency clocks that only have
> a single output.

Ah, indeed!

instead of:
	of_parse_phandle(dev->of_node, "mbox", 0);
I can do a:
	of_parse_phandle_with_args(dev->of_node, "mboxes",
                                   "#mbox-cells", 0, &of_args)
where #mbox-cells = 0;

Or ... can I pass NULL for cells_name and make the #mbox-cells property
optional and still keeping its requirement of being at least 1?

Thanks!
ta


From will at kernel.org  Thu Dec 19 07:49:06 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 15:49:06 +0000
Subject: [PATCH V2 5/7] arm64/cpufeature: Add field details for
 ID_AA64DFR1_EL1 register
In-Reply-To: <a382200e-00c4-405a-a417-f4c09bd91fb7@arm.com>
References: <20241028053426.2486633-1-anshuman.khandual@arm.com>
 <20241028053426.2486633-6-anshuman.khandual@arm.com>
 <20241210164144.GA16039@willie-the-truck>
 <a382200e-00c4-405a-a417-f4c09bd91fb7@arm.com>
Message-ID: <20241219154905.GA24724@willie-the-truck>

On Wed, Dec 11, 2024 at 10:02:42AM +0530, Anshuman Khandual wrote:
> 
> 
> On 12/10/24 22:11, Will Deacon wrote:
> > On Mon, Oct 28, 2024 at 11:04:24AM +0530, Anshuman Khandual wrote:
> >> This adds required field details for ID_AA64DFR1_EL1, and also drops dummy
> >> ftr_raz[] array which is now redundant. These register fields will be used
> >> to enable increased breakpoint and watchpoint registers via FEAT_Debugv8p9
> >> later.
> >>
> >> Cc: Catalin Marinas <catalin.marinas at arm.com>
> >> Cc: Will Deacon <will at kernel.org>
> >> cc: Mark Brown <broonie at kernel.org>
> >> Cc: Mark Rutland <mark.rutland at arm.com>
> >> Cc: Marc Zyngier <maz at kernel.org>
> >> Cc: linux-arm-kernel at lists.infradead.org
> >> Cc: linux-kernel at vger.kernel.org
> >> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> >> ---
> >>  arch/arm64/kernel/cpufeature.c | 21 ++++++++++++++++-----
> >>  1 file changed, 16 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> >> index 718728a85430..bd4d85f5dd92 100644
> >> --- a/arch/arm64/kernel/cpufeature.c
> >> +++ b/arch/arm64/kernel/cpufeature.c
> >> @@ -530,6 +530,21 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
> >>  	ARM64_FTR_END,
> >>  };
> >>  
> >> +static const struct arm64_ftr_bits ftr_id_aa64dfr1[] = {
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABL_CMPs_SHIFT, 8, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_DPFZS_SHIFT, 4, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_EBEP_SHIFT, 4, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ITE_SHIFT, 4, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_ABLE_SHIFT, 4, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_PMICNTR_SHIFT, 4, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SPMU_SHIFT, 4, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_CTX_CMPs_SHIFT, 8, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_WRPs_SHIFT, 8, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_BRPs_SHIFT, 8, 0),
> >> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR1_EL1_SYSPMUID_SHIFT, 8, 0),
> >> +	ARM64_FTR_END,
> >> +};
> > 
> > I think I mentioned this on an earlier series, but it would be useful to
> > see some justification in the commit message as to why some of these
> > features are considered STRICT vs NONSTRICT and why LOWER_SAFE is
> > preferred over EXACT.
> 
> I have updated the commit message regarding STRICT vs NONSTRICT as Mark had
> mentioned earlier (see below). But just wondering about FTR_LOWER_SAFE. All
> similar fields have been marked as FTR_LOWER_SAFE.
> 
> > 
> > For example, why is EBEP strict whereas other PMU-related fields aren't?
> 
> IIUC there are two types of fields here.
> 
> - Feature presence     (EBEP, ITE, ABLE etc)		---> FTR_STRICT
> - Debug resource count (WRPs, BRPs, CTX_CMPs etc)	---> FTR_NONSTRICT
> 
> > Why is the CTX_CMPs field treated differently to the same field in DFR0?
> 
> There is mismatch not only for CTX_CMPs but for WRPs and BRPs as well. As
> mentioned earlier, being resource count type, I believe these should be
> marked as FTR_NONSTRICT in existing DFR0 as well. I could send a patch
> fixing DFR0 first.
> 
> > 
> > I'm not saying the above table is wrong, it just looks arbitrary without
> > the justification.
> 
> Please find the updated version (v3) for this patch here for reference.

Please send new versions as new threads otherwise it's too easy to lose
track. Also, please give the rationale for the handling of each new field
in the commit message.

Will


From will at kernel.org  Thu Dec 19 07:55:48 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 15:55:48 +0000
Subject: [PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <248dea18-bfad-4ec9-9a7d-5c87c7f48c84@sirena.org.uk>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
 <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>
 <20241210170953.GB16075@willie-the-truck>
 <b859bdcd-7343-4d53-9f3a-f374deca725a@sirena.org.uk>
 <20241211224015.GB17836@willie-the-truck>
 <248dea18-bfad-4ec9-9a7d-5c87c7f48c84@sirena.org.uk>
Message-ID: <20241219155547.GC24724@willie-the-truck>

On Thu, Dec 12, 2024 at 11:33:05AM +0000, Mark Brown wrote:
> On Wed, Dec 11, 2024 at 10:40:15PM +0000, Will Deacon wrote:
> > On Tue, Dec 10, 2024 at 06:43:05PM +0000, Mark Brown wrote:
> 
> > > Yes, the issues here are not technical ones.  Though there are some
> > > complications -  eg, IIRC the XML doesn't encode the signedness of
> > > fields like we do and there's areas where we've deliberately diverged.
> > > Given the amount of review I end up having to do of sysreg changes your
> > > reasoning is especially apparent to me.  I've passed this feedback on
> > > (again).
> 
> > One thing we _could_ do is have a tool (in-tree) that takes two copies
> > of the sysreg file (i.e. before and after applying a diff) along with a
> > copy of the XML and, for the the new fields being added, shows how the
> > XML represents those compared to the diff. It should then be relatively
> > straightforward to flag the use of an unallocated encoding (like we had
> > here) and also things like assigning a field name to a RES0 region.
> 
> > So this wouldn't be generating the patches from the XML, but more like
> > using the XML as an oracle in a linter.
> 
> That'd be useful, yes - unfortunately I think that's still something I
> can't work on myself at the moment for the above mentioned non-technical
> reasons.

Is anybody able to work on it? Without insight into the "non-technical
reasons", I don't know what I'm supposed to do other than write the tool
myself (which means finding some spare cycles...) or refusing to take
wholesale sysreg definitions until it's been ironed out :/

Will


From dave.stevenson at raspberrypi.com  Thu Dec 19 08:16:37 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 19 Dec 2024 16:16:37 +0000
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <CAPY8ntDdcOXuWVgx6+cbgX5ct_-MXcE7CWDKgGP57EX6bvBLaw@mail.gmail.com>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-vivacious-chameleon-of-swiftness-f1edc4@houat> <CAA8EJprjCyWBNkRrc4W24uCwPtf_kxZLqNeNP8EJffbutYQ21w@mail.gmail.com>
 <20241218-wild-red-manatee-bb2a34@houat> <CAPY8ntDdcOXuWVgx6+cbgX5ct_-MXcE7CWDKgGP57EX6bvBLaw@mail.gmail.com>
Message-ID: <CAPY8ntAnJ1YDQee=pFSDY3+EXHj4_RZ-M1NMp2C3ZDdD5DsCKA@mail.gmail.com>

On Wed, 18 Dec 2024 at 14:52, Dave Stevenson
<dave.stevenson at raspberrypi.com> wrote:
>
> Hi Maxime & Dmitry
>
> On Wed, 18 Dec 2024 at 07:59, Maxime Ripard <mripard at kernel.org> wrote:
> >
> > On Wed, Dec 18, 2024 at 07:24:23AM +0200, Dmitry Baryshkov wrote:
> > > On Tue, 17 Dec 2024 at 19:21, Maxime Ripard <mripard at kernel.org> wrote:
> > > > On Tue, Dec 17, 2024 at 02:40:22AM +0200, Dmitry Baryshkov wrote:
> > > > > While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
> > > > > framework, I stumbled upon an issue while handling the Audio InfoFrames.
> > > > > The HDMI codec callbacks weren't receiving the drm_atomic_state, so
> > > > > there was no simple way to get the drm_connector that stayed at the end
> > > > > of the bridge chain. At the same point the drm_hdmi_connector functions
> > > > > expected to get drm_connector instance.
> > > > >
> > > > > While looking for a way to solve the issue, I stumbled upon several
> > > > > deficiencies in existing hdmi_codec_ops implementations. Only few of the
> > > > > implementations were able to handle codec's 'plugged' callback. One
> > > > > third of the drivers didn't implement the get_eld() callback.
> > > > >
> > > > > Most of the issues can be solved if drm_connector handles
> > > > > hdmi-audio-codec on its own, delegating functionality to the actual
> > > > > implementation, be it a driver that implements drm_connector or
> > > > > drm_bridge.
> > > > >
> > > > > Implement such high-level framework, adding proper support for Audio
> > > > > InfoFrame generation to the LT9611 driver.
> > > > >
> > > > > Several design decisions to be kept in mind:
> > > > >
> > > > > - drm_connector_hdmi_codec is kept as simple as possible. It implements
> > > > >   generic functionality (ELD, hotplug, registration).
> > > > >
> > > > > - drm_hdmi_connector sets up HDMI codec device if the connector
> > > > >   is setup correspondingly (either I2S or S/PDIF is marked as
> > > > >   supported).
> > > > >
> > > > > - drm_bridge_connector provides a way to link HDMI audio codec
> > > > >   funcionality in the drm_bridge with the drm_connector_hdmi_codec
> > > > >   framework.
> > > > >
> > > > > - It might be worth reverting the no_i2s_capture / no_spdif_capture
> > > > >   bits. Only TDA889x driver sets them, while it's safe to assume that
> > > > >   most of HDMI / DP devices do not support ARC / capture. I think the
> > > > >   drivers should opt-in capture support rather than having to opt-out of
> > > > >   it.
> > > >
> > > > Sorry if this isn't clear to me and I'm quite late to the party, but did
> > > > you test this on vc4 with both a pi3 and pi4, or was it just compile
> > > > tested?
> > >
> > > LT9611 is actually tested, VC4 is only compile-tested. Should I put an RFT tag?
> >
> > Yeah, we definitely need to test it on the pi3 (polling-based) and the
> > pi4 (irq-based) at least.
> >
> > Dave, Maira, could you give it a try?
>
> I'm on it.

Basic checks look OK.
Pi3 and Pi4 tested, including 4k60 on Pi4 (enables scrambling). Audio
works, and all the EDID parsing seems to be correct.

Ideally I would like to do a couple more tests though as I had a
couple of spontaneous reboots on Pi4 whilst hotplugging.
Most likely it was just grounding issues, as I can't think of an
obvious way for the kernel to be triggering an automatic reboot. They
seemed to go away when I had enabled drm.debug=0x14, but more likely
I'd connected the serial port and therefore provided another ground.
Please don't hold the patches waiting on me though - I don't know when
I'll have time to do them.


Also unrelated to this patch set, I have noted I'm getting
[   60.780897] WARNING: CPU: 3 PID: 501 at
drivers/gpu/drm/vc4/vc4_hvs.c:743 __vc4_hvs_stop_channel+0x148/0x164
[vc4]
...
[   60.781192]  __vc4_hvs_stop_channel+0x148/0x164 [vc4] (P)
[   60.781212]  __vc4_hvs_stop_channel+0x40/0x164 [vc4] (L)
[   60.781230]  vc4_hvs_stop_channel+0x30/0x3c [vc4]
[   60.781248]  vc4_crtc_disable+0x140/0x1e8 [vc4]
[   60.781266]  vc4_crtc_atomic_disable+0x98/0xb8 [vc4]
[   60.781284]  disable_outputs+0x22c/0x33c [drm_kms_helper]
[   60.781326]  drm_atomic_helper_commit_modeset_disables+0x1c/0x4c
[drm_kms_helper]
[   60.781347]  vc4_atomic_commit_tail+0x10c/0x8e4 [vc4]
[   60.781364]  commit_tail+0xa0/0x188 [drm_kms_helper]
[   60.781385]  drm_atomic_helper_commit+0x16c/0x180 [drm_kms_helper]
[   60.781406]  drm_atomic_commit+0x88/0xc4 [drm]
[   60.781500]  drm_client_modeset_commit_atomic+0x204/0x264 [drm]
[   60.781553]  drm_client_modeset_commit_locked+0x5c/0x198 [drm]
[   60.781603]  drm_client_modeset_commit+0x30/0x58 [drm]
[   60.781652]  __drm_fb_helper_restore_fbdev_mode_unlocked+0xb4/0xe8
[drm_kms_helper]
[   60.781674]  drm_fb_helper_hotplug_event+0x108/0x12c [drm_kms_helper]
[   60.781695]  drm_fbdev_client_hotplug+0x28/0xd4 [drm_client_lib]
[   60.781700]  drm_client_dev_hotplug+0xc8/0x12c [drm]
[   60.781750]  drm_connector_helper_hpd_irq_event+0x70/0xb0 [drm_kms_helper]
[   60.781771]  vc4_hdmi_hpd_irq_thread+0x2c/0x3c [vc4]
[   60.781790]  irq_thread_fn+0x2c/0xa8
[   60.781799]  irq_thread+0x16c/0x2f4
[   60.781805]  kthread+0x118/0x11c
[   60.781813]  ret_from_fork+0x10/0x20
On first plugging or unplugging a second monitor. I suspect that is
spurious though and I'll look into it, but probably not this side of
the Christmas break.

  Dave


From broonie at kernel.org  Thu Dec 19 08:19:06 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Dec 2024 16:19:06 +0000
Subject: [PATCH] ASoC: mediatek: disable buffer pre-allocation
In-Reply-To: <20241219105303.548437-1-wenst@chromium.org>
References: <20241219105303.548437-1-wenst@chromium.org>
Message-ID: <173462514608.189443.5339636221433842657.b4-ty@kernel.org>

On Thu, 19 Dec 2024 18:53:02 +0800, Chen-Yu Tsai wrote:
> On Chromebooks based on Mediatek MT8195 or MT8188, the audio frontend
> (AFE) is limited to accessing a very small window (1 MiB) of memory,
> which is described as a reserved memory region in the device tree.
> 
> On these two platforms, the maximum buffer size is given as 512 KiB.
> The MediaTek common code uses the same value for preallocations. This
> means that only the first two PCM substreams get preallocations, and
> then the whole space is exhausted, barring any other substreams from
> working. Since the substreams used are not always the first two, this
> means audio won't work correctly.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: mediatek: disable buffer pre-allocation
      commit: 32c9c06adb5b157ef259233775a063a43746d699

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 will at kernel.org  Thu Dec 19 08:25:35 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 16:25:35 +0000
Subject: [RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <21e72a5d-d488-4011-9abc-9f717e1c6643@os.amperecomputing.com>
References: <20241211154611.40395-1-miko.lenczewski@arm.com>
 <20241211154611.40395-3-miko.lenczewski@arm.com>
 <20241211210243.GA17155@willie-the-truck>
 <20241213161726.GA30314@mazurka.cambridge.arm.com>
 <21e72a5d-d488-4011-9abc-9f717e1c6643@os.amperecomputing.com>
Message-ID: <20241219162535.GD24724@willie-the-truck>

On Fri, Dec 13, 2024 at 02:34:57PM -0800, Yang Shi wrote:
> On 12/13/24 8:17 AM, Miko?aj Lenczewski wrote:
> > > > +static int do_conflict_abort(unsigned long far, unsigned long esr,
> > > > +			     struct pt_regs *regs)
> > > > +{
> > > > +	if (!system_supports_bbml2())
> > > > +		return do_bad(far, esr, regs);
> > > > +
> > > > +	/* if we receive a TLB conflict abort, we know that there are multiple
> > > > +	 * TLB entries that translate the same address range. the minimum set
> > > > +	 * of invalidations to clear these entries is implementation defined.
> > > > +	 * the maximum set is defined as either tlbi(vmalls12e1) or tlbi(alle1).
> > > > +	 *
> > > > +	 * if el2 is enabled and stage 2 translation enabled, this may be
> > > > +	 * raised as a stage 2 abort. if el2 is enabled but stage 2 translation
> > > > +	 * disabled, or if el2 is disabled, it will be raised as a stage 1
> > > > +	 * abort.
> > > > +	 *
> > > > +	 * local_flush_tlb_all() does a tlbi(vmalle1), which is enough to
> > > > +	 * handle a stage 1 abort.
> > > > +	 */
> > > > +
> > > > +	local_flush_tlb_all();
> > > > +
> > > > +	return 0;
> > > > +}
> > > Can we actually guarantee that we make it this far without taking another
> > > abort? Given that I'm yet to see one of these things in the wild, I'm
> > > fairly opposed to pretending that we can handle them. We'd be much better
> > > off only violating BBM on CPUs that are known to handle the conflict
> > > gracefully. Judging by your later patch, this is practically keyed off
> > > the MIDR _anyway_...
> > > 
> > > Will
> 
> Hi Miko?aj,
> 
> > Thanks for reviewing. Apologies for the delay in responding, and for
> > spam (replied instead of group-replied).
> > 
> > There should not be an option to take another fault while performing the
> > handler, as long as the mappings covering the fault handler table or any
> > code in this path are not screwed with. This is discussed further in the
> > resent patch series [1].
> 
> Will lead me to this thread when we discussed about my series
> (https://lore.kernel.org/lkml/20241211223034.GA17836 at willie-the-truck/#t).
> My series tried to use large mapping for kernel linear mapping when
> rodata=full. The common part of the both series is BBM lv2 support. My
> series depends on BBM lv2 to change page table block size when changing
> permission for kernel linear mapping.
> 
> Handling TLB conflict should be ok for your usecase since the conflict
> should just happen in user address space. But it may be not fine for my
> usecase. At least the TLB conflict handler needs to depend on
> CONFIG_VMAP_STACK otherwise the kernel stack pointer points to kernel linear
> address space. I'm not quite sure whether there is any other corner case
> which can trigger recursive abort in the path or not, maybe bad stack
> handler? So Will suggested MIDR based lookup. IIUC, he suggested just enable
> BBM lv2 support on the CPUs which can handle TLB conflict gracefully. This
> should make our lives easier. But the downside is maybe fewer CPUs can
> actually advertise BBM lv2 support.

Since most of them seem to be broken anyway, I still think this (having
an allowlist and not handling the conflict abort in the kernel) is the
right approach.

Will


From will at kernel.org  Thu Dec 19 08:36:02 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 16:36:02 +0000
Subject: [RESEND RFC PATCH v1 4/5] arm64/mm: Delay tlbi in
 contpte_convert() under BBML2
In-Reply-To: <20241211160218.41404-5-miko.lenczewski@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-5-miko.lenczewski@arm.com>
Message-ID: <20241219163602.GF24724@willie-the-truck>

On Wed, Dec 11, 2024 at 04:01:40PM +0000, Miko?aj Lenczewski wrote:
> When converting a region via contpte_convert() to use mTHP, we have two
> different goals. We have to mark each entry as contiguous, and we would
> like to smear the dirty and young (access) bits across all entries in
> the contiguous block. Currently, we do this by first accumulating the
> dirty and young bits in the block, using an atomic
> __ptep_get_and_clear() and the relevant pte_{dirty,young}() calls,
> performing a tlbi, and finally smearing the correct bits across the
> block using __set_ptes().
> 
> This approach works fine for BBM level 0, but with support for BBM level
> 2 we are allowed to reorder the tlbi to after setting the pagetable
> entries. This reordering means that other threads will not see an
> invalid pagetable entry, instead operating on stale data, until we have
> performed our smearing and issued the invalidation. Avoiding this
> invalid entry reduces faults in other threads, and thus improves
> performance marginally (more so when there are more threads).

Please provide the performance data.

Will


From will at kernel.org  Thu Dec 19 08:37:37 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 16:37:37 +0000
Subject: [RESEND RFC PATCH v1 5/5] arm64/mm: Elide tlbi in
 contpte_convert() under BBML2
In-Reply-To: <20241211160218.41404-6-miko.lenczewski@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-6-miko.lenczewski@arm.com>
Message-ID: <20241219163736.GG24724@willie-the-truck>

On Wed, Dec 11, 2024 at 04:01:41PM +0000, Miko?aj Lenczewski wrote:
> If we support BBM level 2, we can potentially avoid an intermediate
> TLB invalidation, as hardware is capable of managing the TLB itself
> in this situation. Hardware will either silently clear out the
> offending entry, or will take a TLB Conflict Abort Exception.
> 
> Note that such aborts should not occur on Arm hardware and indeed
> were not seen on any of the benchmarked systems.
> 
> Eliding the invalidation results in a 12% improvement on a
> microbenchmark which targeted the worst case of contpte_convert(), which
> represents an 80% reduction in the overhead of contpte_convert().

Can you run something more indicative of real world performance than a
targetted microbenchmark please?

Will


From broonie at kernel.org  Thu Dec 19 08:39:04 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Dec 2024 16:39:04 +0000
Subject: [PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <20241219155547.GC24724@willie-the-truck>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
 <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>
 <20241210170953.GB16075@willie-the-truck>
 <b859bdcd-7343-4d53-9f3a-f374deca725a@sirena.org.uk>
 <20241211224015.GB17836@willie-the-truck>
 <248dea18-bfad-4ec9-9a7d-5c87c7f48c84@sirena.org.uk>
 <20241219155547.GC24724@willie-the-truck>
Message-ID: <51632b4e-19a0-487f-878d-f03abeea2553@sirena.org.uk>

On Thu, Dec 19, 2024 at 03:55:48PM +0000, Will Deacon wrote:
> On Thu, Dec 12, 2024 at 11:33:05AM +0000, Mark Brown wrote:

> > That'd be useful, yes - unfortunately I think that's still something I
> > can't work on myself at the moment for the above mentioned non-technical
> > reasons.

> Is anybody able to work on it? Without insight into the "non-technical
> reasons", I don't know what I'm supposed to do other than write the tool
> myself (which means finding some spare cycles...) or refusing to take
> wholesale sysreg definitions until it's been ironed out :/

Similar issues will apply to anyone at Arm as things currently stand.
-------------- 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/20241219/46d9074c/attachment.sig>

From suzuki.poulose at arm.com  Thu Dec 19 08:40:46 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 19 Dec 2024 16:40:46 +0000
Subject: [PATCH v6 2/2] coresight: Add label sysfs node support
In-Reply-To: <CAJ9a7VhWZkNcYWUfUkU8+OuQK-Cnu6kp6x23M4s5jHLa3_TpJQ@mail.gmail.com>
References: <20241217063324.33781-1-quic_jinlmao@quicinc.com>
 <20241217063324.33781-3-quic_jinlmao@quicinc.com>
 <985d234c-e088-469d-b9dc-7904fcf5a91c@arm.com>
 <PAVPR08MB967401DC65384CBA26B6829C8C052@PAVPR08MB9674.eurprd08.prod.outlook.com>
 <53354e84-73c0-403b-bbc0-af619196596d@arm.com>
 <CAJ9a7VhWZkNcYWUfUkU8+OuQK-Cnu6kp6x23M4s5jHLa3_TpJQ@mail.gmail.com>
Message-ID: <df010fb9-44f7-44f4-b242-f7f06eb0adcb@arm.com>

On 19/12/2024 11:17, Mike Leach wrote:
> Hi,
> 
> On Wed, 18 Dec 2024 at 18:16, Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>>
>> Hi Mike
>>
>> On 18/12/2024 09:56, Mike Leach wrote:
>>> Hi
>>>
>>>> -----Original Message-----
>>>> From: Suzuki K Poulose <suzuki.poulose at arm.com>
>>>> Sent: Wednesday, December 18, 2024 9:38 AM
>>>> To: Mao Jinlong <quic_jinlmao at quicinc.com>; Mike Leach
>>>> <mike.leach at linaro.org>; James Clark <James.Clark at arm.com>; Rob Herring
>>>> <robh at kernel.org>; Krzysztof Kozlowski <krzk+dt at kernel.org>; Conor Dooley
>>>> <conor+dt at kernel.org>; Mathieu Poirier <mathieu.poirier at linaro.org>; Bjorn
>>>> Andersson <andersson at kernel.org>; Konrad Dybcio
>>>> <konradybcio at kernel.org>
>>>> Cc: coresight at lists.linaro.org; linux-arm-kernel at lists.infradead.org;
>>>> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
>>>> msm at vger.kernel.org
>>>> Subject: Re: [PATCH v6 2/2] coresight: Add label sysfs node support
>>>>
>>>> On 17/12/2024 06:33, Mao Jinlong wrote:
>>>>> For some coresight components like CTI and TPDM, there could be
>>>>> numerous of them. From the node name, we can only get the type and
>>>>> register address of the component. We can't identify the HW or the
>>>>> system the component belongs to. Add label sysfs node support for
>>>>> showing the intuitive name of the device.
>>>>>
>>>>> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
>>>>> ---
>>>>>     .../testing/sysfs-bus-coresight-devices-cti   |  6 ++++
>>>>>     .../sysfs-bus-coresight-devices-funnel        |  6 ++++
>>>>>     .../testing/sysfs-bus-coresight-devices-tpdm  |  6 ++++
>>>>>     drivers/hwtracing/coresight/coresight-sysfs.c | 32
>>>> +++++++++++++++++++
>>>>>     4 files changed, 50 insertions(+)
>>>>
>>>> Do you think we need to name the devices using the label ?
>>>>
>>>
>>> No - absolutely not. If we use label to name devices then we have to validate that the string is a correctly formed device name and that it has not been previously used.
>>
>> Anything that doesn't contain '/' can be a device name ? And it is very
>> easy to find if the device name has been used in the coresight bus,
>> after all these devices only appear there.
>>
>> It is as good as :
>>
>> bus_find_device_by_name(coresight_bus_type, NULL, name) == NULL
>>
>> Of course with coresight_mutex() held.
>>
>> Suzuki
>>
> 
> DTS label property (DT spec 4.1.2) is a freeform string, specified to
> be a human readable description of the device, e.g. :-
> 
> cti0 at 0x1000 {
> reg = <0x1000>;
> label = "main system CTI";
> };
> 
> Arguably the label is completely unnecessary - as the @0x1000 tells
> the knowledgeable user, with a hardware specification of the device
> precisely what this CTI does and is related to.
> 
> The point of this patchset is to add context to the name at addr to make
> the identification of the devices easier.
> 
> The DT compiler should ensure that the device tree is well formed.
> Using driver selected names (cti_cpu0 ... etc) guarantees  that every
> device found in the DT has a unique representation in sysfs.
> 
> Once a freeform string is used, then not only are duplicates possible,
> illegal device names are possible, all of which can result in missing
> nodes or worse. This requires handling / complications that are
> unnecessary for the purpose.
> 
> Yes of course it is easy to look for duplicate names, reject bad ones,
> emit errors - but that could end up with a partially working system
> with missing components.
> 
> Why add potential for breakage when it is not necessary?

Fair enough, we can do away with exporting the label.

Cheers
Suzuki


> 
> Regards
> 
> Mike
> 
>>
>>>
>>> Using the canonical driver selected names works best as we are guaranteed a unique name and the information label can be used to provide flexible context information that best matches the users requirements.
>>>
>>> Mike
>>>
>>>> Or is this enough ?
>>>
>>>> Suzuki
>>>>
>>>>
>>>>>
>>>>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>>>>> index bf2869c413e7..909670e0451a 100644
>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti
>>>>> @@ -239,3 +239,9 @@ Date:           March 2020
>>>>>     KernelVersion    5.7
>>>>>     Contact: Mike Leach or Mathieu Poirier
>>>>>     Description:     (Write) Clear all channel / trigger programming.
>>>>> +
>>>>> +What:           /sys/bus/coresight/devices/<cti-name>/label
>>>>> +Date:           Dec 2024
>>>>> +KernelVersion   6.14
>>>>> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
>>>>> +Description:    (Read) Show hardware context information of device.
>>>>> diff --git
>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>>>>> index d75acda5e1b3..944aad879aeb 100644
>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel
>>>>> @@ -10,3 +10,9 @@ Date:             November 2014
>>>>>     KernelVersion:   3.19
>>>>>     Contact: Mathieu Poirier <mathieu.poirier at linaro.org>
>>>>>     Description:     (RW) Defines input port priority order.
>>>>> +
>>>>> +What:           /sys/bus/coresight/devices/<memory_map>.funnel/label
>>>>> +Date:           Dec 2024
>>>>> +KernelVersion   6.14
>>>>> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
>>>>> +Description:    (Read) Show hardware context information of device.
>>>>> diff --git
>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> index bf710ea6e0ef..309802246398 100644
>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> @@ -257,3 +257,9 @@ 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 CMB
>>>> subunit
>>>>>              TPDM.
>>>>> +
>>>>> +What:           /sys/bus/coresight/devices/<tpdm-name>/label
>>>>> +Date:           Dec 2024
>>>>> +KernelVersion   6.14
>>>>> +Contact:        Mao Jinlong <quic_jinlmao at quicinc.com>
>>>>> +Description:    (Read) Show hardware context information of device.
>>>>> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c
>>>>> b/drivers/hwtracing/coresight/coresight-sysfs.c
>>>>> index a01c9e54e2ed..4af40cd7d75a 100644
>>>>> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
>>>>> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
>>>>> @@ -7,6 +7,7 @@
>>>>>     #include <linux/device.h>
>>>>>     #include <linux/idr.h>
>>>>>     #include <linux/kernel.h>
>>>>> +#include <linux/property.h>
>>>>>
>>>>>     #include "coresight-priv.h"
>>>>>     #include "coresight-trace-id.h"
>>>>> @@ -366,18 +367,47 @@ static ssize_t enable_source_store(struct device
>>>> *dev,
>>>>>     }
>>>>>     static DEVICE_ATTR_RW(enable_source);
>>>>>
>>>>> +static ssize_t label_show(struct device *dev,
>>>>> +           struct device_attribute *attr, char *buf) {
>>>>> +
>>>>> +   const char *str;
>>>>> +   int ret = 0;
>>>>> +
>>>>> +   ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str);
>>>>> +   if (ret == 0)
>>>>> +           return scnprintf(buf, PAGE_SIZE, "%s\n", str);
>>>>> +   else
>>>>> +           return ret;
>>>>> +}
>>>>> +static DEVICE_ATTR_RO(label);
>>>>> +
>>>>>     static struct attribute *coresight_sink_attrs[] = {
>>>>>      &dev_attr_enable_sink.attr,
>>>>> +   &dev_attr_label.attr,
>>>>>      NULL,
>>>>>     };
>>>>>     ATTRIBUTE_GROUPS(coresight_sink);
>>>>>
>>>>>     static struct attribute *coresight_source_attrs[] = {
>>>>>      &dev_attr_enable_source.attr,
>>>>> +   &dev_attr_label.attr,
>>>>>      NULL,
>>>>>     };
>>>>>     ATTRIBUTE_GROUPS(coresight_source);
>>>>>
>>>>> +static struct attribute *coresight_link_attrs[] = {
>>>>> +   &dev_attr_label.attr,
>>>>> +   NULL,
>>>>> +};
>>>>> +ATTRIBUTE_GROUPS(coresight_link);
>>>>> +
>>>>> +static struct attribute *coresight_helper_attrs[] = {
>>>>> +   &dev_attr_label.attr,
>>>>> +   NULL,
>>>>> +};
>>>>> +ATTRIBUTE_GROUPS(coresight_helper);
>>>>> +
>>>>>     const struct device_type coresight_dev_type[] = {
>>>>>      [CORESIGHT_DEV_TYPE_SINK] = {
>>>>>              .name = "sink",
>>>>> @@ -385,6 +415,7 @@ const struct device_type coresight_dev_type[] = {
>>>>>      },
>>>>>      [CORESIGHT_DEV_TYPE_LINK] = {
>>>>>              .name = "link",
>>>>> +           .groups = coresight_link_groups,
>>>>>      },
>>>>>      [CORESIGHT_DEV_TYPE_LINKSINK] = {
>>>>>              .name = "linksink",
>>>>> @@ -396,6 +427,7 @@ const struct device_type coresight_dev_type[] = {
>>>>>      },
>>>>>      [CORESIGHT_DEV_TYPE_HELPER] = {
>>>>>              .name = "helper",
>>>>> +           .groups = coresight_helper_groups,
>>>>>      }
>>>>>     };
>>>>>     /* Ensure the enum matches the names and groups */
>>>>
>>>> _______________________________________________
>>>> CoreSight mailing list -- coresight at lists.linaro.org To unsubscribe send an
>>>> email to coresight-leave at lists.linaro.org
>>
> 
> 



From kevin.brodsky at arm.com  Thu Dec 19 08:44:19 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:19 +0000
Subject: [PATCH 04/10] s390/mm: Add calls to pagetable_pud_[cd]tor
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-5-kevin.brodsky@arm.com>

Commit 55d2a0bd5ead ("mm: add statistics for PUD level pagetable")
introduced PUD-level ctor/dtor helpers to improve the accounting of
page table pages. s390 doesn't use the generic pgalloc
implementation and it seems that it got missed in the process. Add
the missing calls to the ctor/dtor helpers in pud_alloc_one/pud_free
to match the other architectures.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/s390/include/asm/pgalloc.h | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 7b84ef6dc4b6..97db66ae06b9 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -67,15 +67,20 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
 {
 	unsigned long *table = crst_table_alloc(mm);
-	if (table)
-		crst_table_init(table, _REGION3_ENTRY_EMPTY);
+
+	if (!table)
+		return NULL;
+	crst_table_init(table, _REGION3_ENTRY_EMPTY);
+	pagetable_pud_ctor(virt_to_ptdesc(table));
 	return (pud_t *) table;
 }
 
 static inline void pud_free(struct mm_struct *mm, pud_t *pud)
 {
-	if (!mm_pud_folded(mm))
-		crst_table_free(mm, (unsigned long *) pud);
+	if (mm_pud_folded(mm))
+		return;
+	pagetable_pud_dtor(virt_to_ptdesc(pud));
+	crst_table_free(mm, (unsigned long *) pud);
 }
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
-- 
2.47.0



From kevin.brodsky at arm.com  Thu Dec 19 08:44:20 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:20 +0000
Subject: [PATCH 05/10] riscv: mm: Skip pgtable level check in {pud,p4d}_alloc_one
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-6-kevin.brodsky@arm.com>

{pmd,pud,p4d}_alloc_one() is never called if the corresponding page
table level is folded, as {pmd,pud,p4d}_alloc() already does the
required check. We can therefore remove the runtime page table level
checks in {pud,p4d}_alloc_one. The PUD helper becomes equivalent to
the generic version, so we remove it altogether.

This is consistent with the way arm64 and x86 handle this situation
(runtime check in p4d_free() only).

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/riscv/include/asm/pgalloc.h | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
index f52264304f77..8ad0bbe838a2 100644
--- a/arch/riscv/include/asm/pgalloc.h
+++ b/arch/riscv/include/asm/pgalloc.h
@@ -12,7 +12,6 @@
 #include <asm/tlb.h>
 
 #ifdef CONFIG_MMU
-#define __HAVE_ARCH_PUD_ALLOC_ONE
 #define __HAVE_ARCH_PUD_FREE
 #include <asm-generic/pgalloc.h>
 
@@ -88,15 +87,6 @@ static inline void pgd_populate_safe(struct mm_struct *mm, pgd_t *pgd,
 	}
 }
 
-#define pud_alloc_one pud_alloc_one
-static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
-	if (pgtable_l4_enabled)
-		return __pud_alloc_one(mm, addr);
-
-	return NULL;
-}
-
 #define pud_free pud_free
 static inline void pud_free(struct mm_struct *mm, pud_t *pud)
 {
@@ -118,15 +108,11 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
 #define p4d_alloc_one p4d_alloc_one
 static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-	if (pgtable_l5_enabled) {
-		gfp_t gfp = GFP_PGTABLE_USER;
-
-		if (mm == &init_mm)
-			gfp = GFP_PGTABLE_KERNEL;
-		return (p4d_t *)get_zeroed_page(gfp);
-	}
+	gfp_t gfp = GFP_PGTABLE_USER;
 
-	return NULL;
+	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)
-- 
2.47.0



From kevin.brodsky at arm.com  Thu Dec 19 08:44:21 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:21 +0000
Subject: [PATCH 06/10] asm-generic: pgalloc: Provide generic p4d_{alloc_one,free}
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-7-kevin.brodsky@arm.com>

Four architectures currently implement 5-level pgtables: arm64,
riscv, x86 and s390. The first three have essentially the same
implementation for p4d_alloc_one() and p4d_free(), so we've got an
opportunity to reduce duplication like at the lower levels.

Provide a generic version of p4d_alloc_one() and p4d_free(), and
make use of it on those architectures.

Their implementation is the same as at PUD level, except that
p4d_free() performs a runtime check by calling mm_p4d_folded().
5-level pgtables depend on a runtime-detected hardware feature on
all supported architectures, so we might as well include this check
in the generic implementation. No runtime check is required in
p4d_alloc_one() as the top-level p4d_alloc() already does the
required check.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm64/include/asm/pgalloc.h | 17 ------------
 arch/riscv/include/asm/pgalloc.h | 23 ----------------
 arch/x86/include/asm/pgalloc.h   | 18 -------------
 include/asm-generic/pgalloc.h    | 45 ++++++++++++++++++++++++++++++++
 4 files changed, 45 insertions(+), 58 deletions(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index e75422864d1b..2965f5a7e39e 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -85,23 +85,6 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgdp, p4d_t *p4dp)
 	__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)
diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
index 8ad0bbe838a2..551d614d3369 100644
--- a/arch/riscv/include/asm/pgalloc.h
+++ b/arch/riscv/include/asm/pgalloc.h
@@ -105,29 +105,6 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
 	}
 }
 
-#define p4d_alloc_one p4d_alloc_one
-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)
-{
-	BUG_ON((unsigned long)p4d & (PAGE_SIZE-1));
-	free_page((unsigned long)p4d);
-}
-
-#define p4d_free p4d_free
-static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
-{
-	if (pgtable_l5_enabled)
-		__p4d_free(mm, p4d);
-}
-
 static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
 				  unsigned long addr)
 {
diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h
index dcd836b59beb..dd4841231bb9 100644
--- a/arch/x86/include/asm/pgalloc.h
+++ b/arch/x86/include/asm/pgalloc.h
@@ -147,24 +147,6 @@ static inline void pgd_populate_safe(struct mm_struct *mm, pgd_t *pgd, p4d_t *p4
 	set_pgd_safe(pgd, __pgd(_PAGE_TABLE | __pa(p4d)));
 }
 
-static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
-	gfp_t gfp = GFP_KERNEL_ACCOUNT;
-
-	if (mm == &init_mm)
-		gfp &= ~__GFP_ACCOUNT;
-	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);
-}
-
 extern void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d);
 
 static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index 7c48f5fbf8aa..59131629ac9c 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -215,6 +215,51 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud)
 
 #endif /* CONFIG_PGTABLE_LEVELS > 3 */
 
+#if CONFIG_PGTABLE_LEVELS > 4
+
+static inline p4d_t *__p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long addr)
+{
+	gfp_t gfp = GFP_PGTABLE_USER;
+	struct ptdesc *ptdesc;
+
+	if (mm == &init_mm)
+		gfp = GFP_PGTABLE_KERNEL;
+	gfp &= ~__GFP_HIGHMEM;
+
+	ptdesc = pagetable_alloc_noprof(gfp, 0);
+	if (!ptdesc)
+		return NULL;
+
+	return ptdesc_address(ptdesc);
+}
+#define __p4d_alloc_one(...)	alloc_hooks(__p4d_alloc_one_noprof(__VA_ARGS__))
+
+#ifndef __HAVE_ARCH_P4D_ALLOC_ONE
+static inline p4d_t *p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long addr)
+{
+	return __p4d_alloc_one_noprof(mm, addr);
+}
+#define p4d_alloc_one(...)	alloc_hooks(p4d_alloc_one_noprof(__VA_ARGS__))
+#endif
+
+static inline void __p4d_free(struct mm_struct *mm, p4d_t *p4d)
+{
+	struct ptdesc *ptdesc = virt_to_ptdesc(p4d);
+
+	BUG_ON((unsigned long)p4d & (PAGE_SIZE-1));
+	pagetable_free(ptdesc);
+}
+
+#ifndef __HAVE_ARCH_P4D_FREE
+static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
+{
+	if (!mm_p4d_folded(mm))
+		__p4d_free(mm, p4d);
+}
+#endif
+
+#endif /* CONFIG_PGTABLE_LEVELS > 4 */
+
 #ifndef __HAVE_ARCH_PGD_FREE
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
-- 
2.47.0



From will at kernel.org  Thu Dec 19 08:45:28 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 16:45:28 +0000
Subject: [RESEND RFC PATCH v1 2/5] arm64: Add BBM Level 2 cpu feature
In-Reply-To: <5c551e43-78e9-4336-ab16-b55c0d6c7f92@arm.com>
References: <20241211160218.41404-1-miko.lenczewski@arm.com>
 <20241211160218.41404-3-miko.lenczewski@arm.com>
 <87cyhxs3xq.wl-maz@kernel.org>
 <084c5ada-51af-4c1a-b50a-4401e62ddbd6@arm.com>
 <86ikrprn7w.wl-maz@kernel.org>
 <2b1cc228-a8d5-4383-ab25-abbbcccd2e2c@arm.com>
 <86h678sy00.wl-maz@kernel.org>
 <5c551e43-78e9-4336-ab16-b55c0d6c7f92@arm.com>
Message-ID: <20241219164528.GH24724@willie-the-truck>

On Thu, Dec 12, 2024 at 04:03:52PM +0000, Ryan Roberts wrote:
> >>> If anything, this should absolutely check for FAR_EL1 and assert that
> >>> this is indeed caused by such change.
> >>
> >> I'm not really sure how we would check this reliably? Without patch 5, the
> >> problem is somewhat constrained; we could have as many changes in flight as
> >> there are CPUs so we could keep a list of all the {mm_struct, VA-range} that are
> >> being modified. But if patch 5 is confirmed to be architecturally sound, then
> >> there is no "terminating tlbi" so there is no bound on the set of {mm_struct,
> >> VA-range}'s that could legitimately cause a conflict abort.
> > 
> > I didn't mean to imply that we should identify the exact cause of the
> > abort. I was hoping to simply check that FAR_EL1 reports a userspace
> > VA. Why wouldn't that work?
> 
> Ahh gottya! Yes agreed, this sounds like the right approach.

Please, can we just not bother handling conflict aborts at all outside of
KVM? This is all dead code, it's complicated and it doesn't scale to the
in-kernel use-cases that others want. There's also not been any attempt
to add the pKVM support for handling host-side conflict aborts from what
I can tell.

For now, I would suggest limiting this series just to the KVM support
for handling a broken/malicious guest. If the contpte performance
improvements are worthwhile (I've asked for data), then let's add support
for the CPUs that handle the conflict in hardware (I believe this is far
more common than reporting the abort) so that the in-kernel users can
benefit whilst keeping the code manageable at the same time.

Will


From kevin.brodsky at arm.com  Thu Dec 19 08:44:15 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:15 +0000
Subject: [PATCH 00/10] Account page tables at all levels
Message-ID: <20241219164425.2277022-1-kevin.brodsky@arm.com>

We currently have a pair of ctor/dtor calls for lower page table levels,
up to PUD. At PTE and PMD level, these handle split locks,
if supported. Additionally, the helpers ensure correct accounting of
page table pages to the corresponding process.

This series takes that principle to its logical conclusion: account all
page table pages, at all levels and on all architectures (see caveat
below), through suitable ctor/dtor calls. This means concretely:

* Ensuring that the existing pagetable_{pte,pmd,pud}_[cd]tor are called
  on all architectures.

* Introduce pagetable_{p4d,pgd}_[cd]tor and call them at P4D/PGD level.

The primary motivation for this series is not page accounting, though.
P4D/PGD-level pages represent a tiny proportion of the memory used by a
process. Rather, the appeal comes from the introduction of a single,
generic place where construction/destruction hooks can be called for all
page table pages at all levels. This will come in handy for protecting
page tables using kpkeys [1]. Peter Zijlstra suggested this approach [2]
to avoid handling this in arch code.

With this series, __pagetable_ctor() and __pagetable_dtor() (introduced
in patch 1) should be called when page tables are allocated/freed at any
level on any architecture. Note however that only P*D that consist of
one or more regular pages are handled. This excludes:

* All P*D allocated from a kmem_cache (or kmalloc).
* P*D that are not allocated via GFP (only an issue on sparc).

The table at the end of this email gives more details for each
architecture.

Patches in details:

* Patch 1 factors out the common implementation of all
  pagetable_*_[cd]tor.

* Patch 2-4: PMD/PUD; add missing calls to pagetable_{pmd,pud}_[cd]tor
  on various architectures.

* Patch 5-7: P4D; move most arch to using generic alloc/free functions
  at P4D level, and then have them call pagetable_p4d_[cd]tor.

* Patch 8-10: PGD; same principle at PGD level.

The patches were build-tested on all architectures (thanks Linus Walleij
for triggering the LKP CI for me!), and boot-tested on arm64 and x86_64.

- Kevin

[1] https://lore.kernel.org/linux-hardening/20241206101110.1646108-1-kevin.brodsky at arm.com/
[2] https://lore.kernel.org/linux-hardening/20241210122355.GN8562 at noisy.programming.kicks-ass.net/
---

Overview of the situation on all arch after this series is applied:

  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | arch          | #include                | Complete ctor/dtor    | ctor/dtor    | Notes                              |
  |               | <asm-generic/pgalloc.h> | calls up to p4d level | at pgd level |                                    |
  +===============+=========================+=======================+==============+====================================+
  | alpha         | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | arc           | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | arm           | Y                       | Y                     | Y/N          | kmalloc at pgd level if LPAE       |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | arm64         | Y                       | Y                     | Y/N          | kmem_cache if pgd not page-sized   |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | csky          | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | hexagon       | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | loongarch     | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | m68k (Sun3)   | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | m68k (others) | N                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | microblaze    | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | mips          | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | nios2         | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | openrisc      | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | parisc        | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | powerpc       | N                       | Y/N                   | N            | kmem_cache at:                     |
  |               |                         |                       |              | - pgd level                        |
  |               |                         |                       |              | - pud level in 64-bit              |
  |               |                         |                       |              | - pmd level in 64-bit on !book3s   |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | riscv         | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | s390          | N                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | sh            | Y                       | N                     | N            | kmem_cache at pmd/pgd level        |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | sparc         | N                       | N                     | N            | 32-bit: special memory             |
  |               |                         |                       |              | 64-bit: kmem_cache above pte level |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | um            | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | x86           | Y                       | Y                     | Y/N          | kmem_cache at pgd level if PAE     |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+
  | xtensa        | Y                       | Y                     | Y            |                                    |
  +---------------+-------------------------+-----------------------+--------------+------------------------------------+

Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Dave Hansen <dave.hansen at linux.intel.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Andy Lutomirski <luto at kernel.org>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: "Mike Rapoport (IBM)" <rppt at kernel.org>
Cc: Ryan Roberts <ryan.roberts at arm.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Will Deacon <will at kernel.org>
Cc: Matthew Wilcox <willy at infradead.org>
Cc: linux-alpha at vger.kernel.org
Cc: linux-arch at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-csky at vger.kernel.org
Cc: linux-hexagon at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-m68k at lists.linux-m68k.org
Cc: linux-mips at vger.kernel.org
Cc: linux-openrisc at vger.kernel.org
Cc: linux-parisc at vger.kernel.org
Cc: linux-riscv at lists.infradead.org
Cc: linux-s390 at vger.kernel.org
Cc: linux-snps-arc at lists.infradead.org
Cc: linux-um at lists.infradead.org
Cc: loongarch at lists.linux.dev
Cc: x86 at kernel.org
---
Kevin Brodsky (10):
  mm: Move common parts of pagetable_*_[cd]tor to helpers
  parisc: mm: Ensure pagetable_pmd_[cd]tor are called
  m68k: mm: Add calls to pagetable_pmd_[cd]tor
  s390/mm: Add calls to pagetable_pud_[cd]tor
  riscv: mm: Skip pgtable level check in {pud,p4d}_alloc_one
  asm-generic: pgalloc: Provide generic p4d_{alloc_one,free}
  mm: Introduce ctor/dtor at P4D level
  ARM: mm: Rename PGD helpers
  asm-generic: pgalloc: Provide generic __pgd_{alloc,free}
  mm: Introduce ctor/dtor at PGD level

 arch/alpha/mm/init.c                     |  2 +-
 arch/arc/include/asm/pgalloc.h           |  9 +--
 arch/arm/mm/pgd.c                        | 16 +++--
 arch/arm64/include/asm/pgalloc.h         | 17 ------
 arch/arm64/mm/pgd.c                      |  4 +-
 arch/csky/include/asm/pgalloc.h          |  2 +-
 arch/hexagon/include/asm/pgalloc.h       |  2 +-
 arch/loongarch/mm/pgtable.c              |  7 +--
 arch/m68k/include/asm/mcf_pgalloc.h      |  2 +
 arch/m68k/include/asm/motorola_pgalloc.h |  6 +-
 arch/m68k/include/asm/sun3_pgalloc.h     |  2 +-
 arch/m68k/mm/motorola.c                  | 31 ++++++++--
 arch/microblaze/include/asm/pgalloc.h    |  7 +--
 arch/mips/include/asm/pgalloc.h          |  6 --
 arch/mips/mm/pgtable.c                   |  8 +--
 arch/nios2/mm/pgtable.c                  |  3 +-
 arch/openrisc/include/asm/pgalloc.h      |  6 +-
 arch/parisc/include/asm/pgalloc.h        | 39 ++++--------
 arch/riscv/include/asm/pgalloc.h         | 46 ++------------
 arch/s390/include/asm/pgalloc.h          | 33 +++++++---
 arch/um/kernel/mem.c                     |  7 +--
 arch/x86/include/asm/pgalloc.h           | 18 ------
 arch/x86/mm/pgtable.c                    | 27 +++++----
 arch/xtensa/include/asm/pgalloc.h        |  2 +-
 include/asm-generic/pgalloc.h            | 76 +++++++++++++++++++++++-
 include/linux/mm.h                       | 64 +++++++++++++-------
 26 files changed, 234 insertions(+), 208 deletions(-)


base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
-- 
2.47.0



From kevin.brodsky at arm.com  Thu Dec 19 08:44:16 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:16 +0000
Subject: [PATCH 01/10] mm: Move common parts of pagetable_*_[cd]tor to helpers
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-2-kevin.brodsky@arm.com>

Besides the ptlock management at PTE/PMD level, all the
pagetable_*_[cd]tor have the same implementation. Introduce common
helpers for all levels to reduce the duplication.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 include/linux/mm.h | 46 ++++++++++++++++++++++------------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index c39c4945946c..a5b482362792 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2915,6 +2915,22 @@ static inline void pagetable_free(struct ptdesc *pt)
 	__free_pages(page, compound_order(page));
 }
 
+static inline void __pagetable_ctor(struct ptdesc *ptdesc)
+{
+	struct folio *folio = ptdesc_folio(ptdesc);
+
+	__folio_set_pgtable(folio);
+	lruvec_stat_add_folio(folio, NR_PAGETABLE);
+}
+
+static inline void __pagetable_dtor(struct ptdesc *ptdesc)
+{
+	struct folio *folio = ptdesc_folio(ptdesc);
+
+	__folio_clear_pgtable(folio);
+	lruvec_stat_sub_folio(folio, NR_PAGETABLE);
+}
+
 #if defined(CONFIG_SPLIT_PTE_PTLOCKS)
 #if ALLOC_SPLIT_PTLOCKS
 void __init ptlock_cache_init(void);
@@ -2992,22 +3008,16 @@ static inline void ptlock_free(struct ptdesc *ptdesc) {}
 
 static inline bool pagetable_pte_ctor(struct ptdesc *ptdesc)
 {
-	struct folio *folio = ptdesc_folio(ptdesc);
-
 	if (!ptlock_init(ptdesc))
 		return false;
-	__folio_set_pgtable(folio);
-	lruvec_stat_add_folio(folio, NR_PAGETABLE);
+	__pagetable_ctor(ptdesc);
 	return true;
 }
 
 static inline void pagetable_pte_dtor(struct ptdesc *ptdesc)
 {
-	struct folio *folio = ptdesc_folio(ptdesc);
-
 	ptlock_free(ptdesc);
-	__folio_clear_pgtable(folio);
-	lruvec_stat_sub_folio(folio, NR_PAGETABLE);
+	__pagetable_dtor(ptdesc);
 }
 
 pte_t *__pte_offset_map(pmd_t *pmd, unsigned long addr, pmd_t *pmdvalp);
@@ -3110,22 +3120,16 @@ static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd)
 
 static inline bool pagetable_pmd_ctor(struct ptdesc *ptdesc)
 {
-	struct folio *folio = ptdesc_folio(ptdesc);
-
 	if (!pmd_ptlock_init(ptdesc))
 		return false;
-	__folio_set_pgtable(folio);
-	lruvec_stat_add_folio(folio, NR_PAGETABLE);
+	__pagetable_ctor(ptdesc);
 	return true;
 }
 
 static inline void pagetable_pmd_dtor(struct ptdesc *ptdesc)
 {
-	struct folio *folio = ptdesc_folio(ptdesc);
-
 	pmd_ptlock_free(ptdesc);
-	__folio_clear_pgtable(folio);
-	lruvec_stat_sub_folio(folio, NR_PAGETABLE);
+	__pagetable_dtor(ptdesc);
 }
 
 /*
@@ -3149,18 +3153,12 @@ static inline spinlock_t *pud_lock(struct mm_struct *mm, pud_t *pud)
 
 static inline void pagetable_pud_ctor(struct ptdesc *ptdesc)
 {
-	struct folio *folio = ptdesc_folio(ptdesc);
-
-	__folio_set_pgtable(folio);
-	lruvec_stat_add_folio(folio, NR_PAGETABLE);
+	__pagetable_ctor(ptdesc);
 }
 
 static inline void pagetable_pud_dtor(struct ptdesc *ptdesc)
 {
-	struct folio *folio = ptdesc_folio(ptdesc);
-
-	__folio_clear_pgtable(folio);
-	lruvec_stat_sub_folio(folio, NR_PAGETABLE);
+	__pagetable_dtor(ptdesc);
 }
 
 extern void __init pagecache_init(void);
-- 
2.47.0



From kevin.brodsky at arm.com  Thu Dec 19 08:44:17 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:17 +0000
Subject: [PATCH 02/10] parisc: mm: Ensure pagetable_pmd_[cd]tor are called
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-3-kevin.brodsky@arm.com>

The implementation of pmd_{alloc_one,free} on parisc requires a
non-zero allocation order, but is completely standard aside from
that. Let's reuse the generic implementation of pmd_alloc_one().
Explicit zeroing is not needed as GFP_PGTABLE_KERNEL includes
__GFP_ZERO. The generic pmd_free() can handle higher allocation
orders so we don't need to define our own.

These changes ensure that pagetable_pmd_[cd]tor are called,
improving the accounting of page table pages.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/parisc/include/asm/pgalloc.h | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
index e3e142b1c5c5..3e8dbd79670b 100644
--- a/arch/parisc/include/asm/pgalloc.h
+++ b/arch/parisc/include/asm/pgalloc.h
@@ -11,7 +11,6 @@
 #include <asm/cache.h>
 
 #define __HAVE_ARCH_PMD_ALLOC_ONE
-#define __HAVE_ARCH_PMD_FREE
 #define __HAVE_ARCH_PGD_FREE
 #include <asm-generic/pgalloc.h>
 
@@ -46,17 +45,19 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	pmd_t *pmd;
+	struct ptdesc *ptdesc;
+	gfp_t gfp = GFP_PGTABLE_USER;
 
-	pmd = (pmd_t *)__get_free_pages(GFP_PGTABLE_KERNEL, PMD_TABLE_ORDER);
-	if (likely(pmd))
-		memset ((void *)pmd, 0, PAGE_SIZE << PMD_TABLE_ORDER);
-	return pmd;
-}
-
-static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
-{
-	free_pages((unsigned long)pmd, PMD_TABLE_ORDER);
+	if (mm == &init_mm)
+		gfp = GFP_PGTABLE_KERNEL;
+	ptdesc = pagetable_alloc(gfp, PMD_TABLE_ORDER);
+	if (!ptdesc)
+		return NULL;
+	if (!pagetable_pmd_ctor(ptdesc)) {
+		pagetable_free(ptdesc);
+		return NULL;
+	}
+	return ptdesc_address(ptdesc);
 }
 #endif
 
-- 
2.47.0



From kevin.brodsky at arm.com  Thu Dec 19 08:44:18 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:18 +0000
Subject: [PATCH 03/10] m68k: mm: Add calls to pagetable_pmd_[cd]tor
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-4-kevin.brodsky@arm.com>

get_pointer_table() and free_pointer_table() already special-case
TABLE_PTE to call pagetable_pte_[cd]tor. Let's do the same at PMD
level to improve accounting further. TABLE_PGD and TABLE_PMD are
currently defined to the same value, so we first need to separate
them. That also implies separating ptable_list for PMD/PGD levels.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/m68k/include/asm/motorola_pgalloc.h |  6 +++---
 arch/m68k/mm/motorola.c                  | 25 +++++++++++++++++++-----
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/arch/m68k/include/asm/motorola_pgalloc.h b/arch/m68k/include/asm/motorola_pgalloc.h
index 74a817d9387f..5abe7da8ac5a 100644
--- a/arch/m68k/include/asm/motorola_pgalloc.h
+++ b/arch/m68k/include/asm/motorola_pgalloc.h
@@ -9,9 +9,9 @@ extern void mmu_page_ctor(void *page);
 extern void mmu_page_dtor(void *page);
 
 enum m68k_table_types {
-	TABLE_PGD = 0,
-	TABLE_PMD = 0, /* same size as PGD */
-	TABLE_PTE = 1,
+	TABLE_PGD,
+	TABLE_PMD,
+	TABLE_PTE,
 };
 
 extern void init_pointer_table(void *table, int type);
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index c1761d309fc6..37010ee15928 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -97,17 +97,19 @@ void mmu_page_dtor(void *page)
 
 typedef struct list_head ptable_desc;
 
-static struct list_head ptable_list[2] = {
+static struct list_head ptable_list[3] = {
 	LIST_HEAD_INIT(ptable_list[0]),
 	LIST_HEAD_INIT(ptable_list[1]),
+	LIST_HEAD_INIT(ptable_list[2]),
 };
 
 #define PD_PTABLE(page) ((ptable_desc *)&(virt_to_page((void *)(page))->lru))
 #define PD_PAGE(ptable) (list_entry(ptable, struct page, lru))
 #define PD_MARKBITS(dp) (*(unsigned int *)&PD_PAGE(dp)->index)
 
-static const int ptable_shift[2] = {
-	7+2, /* PGD, PMD */
+static const int ptable_shift[3] = {
+	7+2, /* PGD */
+	7+2, /* PMD */
 	6+2, /* PTE */
 };
 
@@ -156,12 +158,17 @@ void *get_pointer_table(int type)
 		if (!(page = (void *)get_zeroed_page(GFP_KERNEL)))
 			return NULL;
 
-		if (type == TABLE_PTE) {
+		switch (type) {
+		case TABLE_PTE:
 			/*
 			 * m68k doesn't have SPLIT_PTE_PTLOCKS for not having
 			 * SMP.
 			 */
 			pagetable_pte_ctor(virt_to_ptdesc(page));
+			break;
+		case TABLE_PMD:
+			pagetable_pmd_ctor(virt_to_ptdesc(page));
+			break;
 		}
 
 		mmu_page_ctor(page);
@@ -200,8 +207,16 @@ int free_pointer_table(void *table, int type)
 		/* all tables in page are free, free page */
 		list_del(dp);
 		mmu_page_dtor((void *)page);
-		if (type == TABLE_PTE)
+
+		switch (type) {
+		case TABLE_PTE:
 			pagetable_pte_dtor(virt_to_ptdesc((void *)page));
+			break;
+		case TABLE_PMD:
+			pagetable_pmd_dtor(virt_to_ptdesc((void *)page));
+			break;
+		}
+
 		free_page (page);
 		return 1;
 	} else if (ptable_list[type].next != dp) {
-- 
2.47.0



From kevin.brodsky at arm.com  Thu Dec 19 08:44:22 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:22 +0000
Subject: [PATCH 07/10] mm: Introduce ctor/dtor at P4D level
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-8-kevin.brodsky@arm.com>

Commit 55d2a0bd5ead ("mm: add statistics for PUD level pagetable")
added accounting for PUD-level page tables. This patch does exactly
the same thing for P4D-level page tables, introducing
pagetable_p4d_[cd]tor with the same implementation as the PUD
ctor/dtor and calling them on all alloc/free paths.

Besides the small improvement in accounting accuracy, this also
enables adding construction/destruction hooks in just one generic
place for page tables at P4D level (like lower levels).

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/riscv/include/asm/pgalloc.h |  8 ++++++--
 arch/s390/include/asm/pgalloc.h  | 12 ++++++++----
 arch/x86/mm/pgtable.c            |  3 +++
 include/asm-generic/pgalloc.h    |  2 ++
 include/linux/mm.h               | 10 ++++++++++
 5 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
index 551d614d3369..3c364ecc3100 100644
--- a/arch/riscv/include/asm/pgalloc.h
+++ b/arch/riscv/include/asm/pgalloc.h
@@ -108,8 +108,12 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
 static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
 				  unsigned long addr)
 {
-	if (pgtable_l5_enabled)
-		riscv_tlb_remove_ptdesc(tlb, virt_to_ptdesc(p4d));
+	if (pgtable_l5_enabled) {
+		struct ptdesc *ptdesc = virt_to_ptdesc(p4d);
+
+		pagetable_p4d_dtor(ptdesc);
+		riscv_tlb_remove_ptdesc(tlb, ptdesc);
+	}
 }
 #endif /* __PAGETABLE_PMD_FOLDED */
 
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 97db66ae06b9..85a5d07365aa 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -53,15 +53,19 @@ static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long address)
 {
 	unsigned long *table = crst_table_alloc(mm);
 
-	if (table)
-		crst_table_init(table, _REGION2_ENTRY_EMPTY);
+	if (!table)
+		return NULL;
+	crst_table_init(table, _REGION2_ENTRY_EMPTY);
+	pagetable_p4d_ctor(virt_to_ptdesc(table));
 	return (p4d_t *) table;
 }
 
 static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
 {
-	if (!mm_p4d_folded(mm))
-		crst_table_free(mm, (unsigned long *) p4d);
+	if (mm_p4d_folded(mm))
+		return;
+	pagetable_p4d_dtor(virt_to_ptdesc(p4d));
+	crst_table_free(mm, (unsigned long *) p4d);
 }
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 5745a354a241..c1bfdf7b4767 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -86,6 +86,9 @@ void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
 #if CONFIG_PGTABLE_LEVELS > 4
 void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d)
 {
+	struct ptdesc *ptdesc = virt_to_ptdesc(p4d);
+
+	pagetable_p4d_dtor(ptdesc);
 	paravirt_release_p4d(__pa(p4d) >> PAGE_SHIFT);
 	paravirt_tlb_remove_table(tlb, virt_to_page(p4d));
 }
diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index 59131629ac9c..bb482eeca0c3 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -230,6 +230,7 @@ static inline p4d_t *__p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long
 	if (!ptdesc)
 		return NULL;
 
+	pagetable_p4d_ctor(ptdesc);
 	return ptdesc_address(ptdesc);
 }
 #define __p4d_alloc_one(...)	alloc_hooks(__p4d_alloc_one_noprof(__VA_ARGS__))
@@ -247,6 +248,7 @@ static inline void __p4d_free(struct mm_struct *mm, p4d_t *p4d)
 	struct ptdesc *ptdesc = virt_to_ptdesc(p4d);
 
 	BUG_ON((unsigned long)p4d & (PAGE_SIZE-1));
+	pagetable_p4d_dtor(ptdesc);
 	pagetable_free(ptdesc);
 }
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index a5b482362792..e8b92f4bf3f1 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3161,6 +3161,16 @@ static inline void pagetable_pud_dtor(struct ptdesc *ptdesc)
 	__pagetable_dtor(ptdesc);
 }
 
+static inline void pagetable_p4d_ctor(struct ptdesc *ptdesc)
+{
+	__pagetable_ctor(ptdesc);
+}
+
+static inline void pagetable_p4d_dtor(struct ptdesc *ptdesc)
+{
+	__pagetable_dtor(ptdesc);
+}
+
 extern void __init pagecache_init(void);
 extern void free_initmem(void);
 
-- 
2.47.0



From larysa.zaremba at intel.com  Thu Dec 19 08:59:27 2024
From: larysa.zaremba at intel.com (Larysa Zaremba)
Date: Thu, 19 Dec 2024 17:59:27 +0100
Subject: [PATCH net-next 1/4] net: ti: Kconfig: Select HSR for ICSSG
 Driver
In-Reply-To: <c6254178-6e2a-47e1-ac16-22af5affc8ca@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-2-danishanwar@ti.com>
 <Z2L/hwH5pgBV9pSB@lzaremba-mobl.ger.corp.intel.com>
 <c6254178-6e2a-47e1-ac16-22af5affc8ca@ti.com>
Message-ID: <Z2RQ7xj6IwPXsqHO@lzaremba-mobl.ger.corp.intel.com>

On Thu, Dec 19, 2024 at 10:36:57AM +0530, MD Danish Anwar wrote:
> 
> 
> On 18/12/24 10:29 pm, Larysa Zaremba wrote:
> > On Mon, Dec 16, 2024 at 03:30:41PM +0530, MD Danish Anwar wrote:
> >> HSR offloading is supported by ICSSG driver. Select the symbol HSR for
> >> TI_ICSSG_PRUETH. Also select NET_SWITCHDEV instead of depending on it to
> >> remove recursive dependency.
> >>
> > 
> > 2 things:
> > 1) The explanation from the cover should have been included in the commit 
> >    message.
> 
> I wanted to keep the commit message brief so I provided the actual
> errors in cover letter. I will add the logs here as well.
>

Commit message has to be as verbose as needed to provide enough context for 
whoever needs to explore the code history later.
 
> > 2) Why not `depends on HSR`?
> 
> Adding `depends on HSR` in `config TI_ICSSG_PRUETH` is not setting HSR.
> I have tried below scenarios and only one of them work.
> 
> 1) depends on NET_SWITCHDEV
>    depends on HSR
> 
> 	HSR doesn't get set in .config - `# CONFIG_HSR is not set`. Even the
> CONFIG_TI_ICSSG_PRUETH also gets unset although this is set to =m in
> defconfig. But keeping both as `depends on` makes CONFIG_TI_ICSSG_PRUETH
> disabled.

I do not understand your problem with this option, CONFIG_HSR is a visible 
option that you can enable manually only then you will be able to successfully 
set CONFIG_TI_ICSSG_PRUETH to m/y, this is how the relation with NET_SWITCHDEV 
currently works.

Just 'depends on' is still a preferred way for me, as there is not a single 
driver that does 'select NET_SWITCHDEV'

> 
> 2) select NET_SWITCHDEV
>    depends on HSR
> 
> 	HSR doesn't get set in .config - `# CONFIG_HSR is not set`. Even the
> CONFIG_TI_ICSSG_PRUETH also gets unset although this is set to =m in
> defconfig. But keeping both as `depends on` makes CONFIG_TI_ICSSG_PRUETH
> disabled.
> 
> 3) depends on NET_SWITCHDEV
>    select HSR
> 	
> 	Results in recursive dependency
> 
> error: recursive dependency detected!
> 	symbol NET_DSA depends on HSR
> 	symbol HSR is selected by TI_ICSSG_PRUETH
> 	symbol TI_ICSSG_PRUETH depends on NET_SWITCHDEV
> 	symbol NET_SWITCHDEV is selected by NET_DSA
> For a resolution refer to Documentation/kbuild/kconfig-language.rst
> subsection "Kconfig recursive dependency limitations"
> 
> make[2]: *** [scripts/kconfig/Makefile:95: defconfig] Error 1
> make[1]: *** [/home/danish/workspace/net-next/Makefile:733: defconfig]
> Error 2
> make: *** [Makefile:251: __sub-make] Error 2
> 
> 4) select NET_SWITCHDEV
>    select HSR
> 
> 	HSR is set as `m` along with `CONFIG_TI_ICSSG_PRUETH`
> 
> CONFIG_HSR=m
> CONFIG_NET_SWITCHDEV=y
> CONFIG_TI_ICSSG_PRUETH=m
> 
> #4 is the only secnario where HSR gets built. That's why I sent the
> patch with `select NET_SWITCHDEV` and `select HSR`
> 
> >  
> >> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> >> ---
> >>  drivers/net/ethernet/ti/Kconfig | 3 ++-
> >>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
> >> index 0d5a862cd78a..ad366abfa746 100644
> >> --- a/drivers/net/ethernet/ti/Kconfig
> >> +++ b/drivers/net/ethernet/ti/Kconfig
> >> @@ -187,8 +187,9 @@ config TI_ICSSG_PRUETH
> >>  	select PHYLIB
> >>  	select TI_ICSS_IEP
> >>  	select TI_K3_CPPI_DESC_POOL
> >> +	select NET_SWITCHDEV
> >> +	select HSR
> >>  	depends on PRU_REMOTEPROC
> >> -	depends on NET_SWITCHDEV
> >>  	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
> >>  	depends on PTP_1588_CLOCK_OPTIONAL
> >>  	help
> >> -- 
> >> 2.34.1
> >>
> >>
> 
> -- 
> Thanks and Regards,
> Danish


From kevin.brodsky at arm.com  Thu Dec 19 08:44:23 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:23 +0000
Subject: [PATCH 08/10] ARM: mm: Rename PGD helpers
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-9-kevin.brodsky@arm.com>

Generic implementations of __pgd_alloc and __pgd_free are about to
be introduced. Rename the macros in arch/arm/mm/pgd.c to avoid
clashes. While we're at it, also pass down the mm as argument to
those helpers, as it will be needed to call the generic
__pgd_{alloc,free}.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/arm/mm/pgd.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index f8e9bc58a84f..2a1077747758 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -17,11 +17,11 @@
 #include "mm.h"
 
 #ifdef CONFIG_ARM_LPAE
-#define __pgd_alloc()	kmalloc_array(PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL)
-#define __pgd_free(pgd)	kfree(pgd)
+#define _pgd_alloc(mm)		kmalloc_array(PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL)
+#define _pgd_free(mm, pgd)	kfree(pgd)
 #else
-#define __pgd_alloc()	(pgd_t *)__get_free_pages(GFP_KERNEL, 2)
-#define __pgd_free(pgd)	free_pages((unsigned long)pgd, 2)
+#define _pgd_alloc(mm)		(pgd_t *)__get_free_pages(GFP_KERNEL, 2)
+#define _pgd_free(mm, pgd)	free_pages((unsigned long)pgd, 2)
 #endif
 
 /*
@@ -35,7 +35,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 	pmd_t *new_pmd, *init_pmd;
 	pte_t *new_pte, *init_pte;
 
-	new_pgd = __pgd_alloc();
+	new_pgd = _pgd_alloc(mm);
 	if (!new_pgd)
 		goto no_pgd;
 
@@ -134,7 +134,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 no_pud:
 	p4d_free(mm, new_p4d);
 no_p4d:
-	__pgd_free(new_pgd);
+	_pgd_free(mm, new_pgd);
 no_pgd:
 	return NULL;
 }
@@ -207,5 +207,5 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
 		p4d_free(mm, p4d);
 	}
 #endif
-	__pgd_free(pgd_base);
+	_pgd_free(mm, pgd_base);
 }
-- 
2.47.0



From kevin.brodsky at arm.com  Thu Dec 19 08:44:24 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:24 +0000
Subject: [PATCH 09/10] asm-generic: pgalloc: Provide generic __pgd_{alloc,free}
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-10-kevin.brodsky@arm.com>

We already have a generic implementation of alloc/free up to P4D
level, as well as pgd_free(). Let's finish the work and add a
generic PGD-level alloc helper as well.

Unlike at lower levels, almost all architectures need some specific
magic at PGD level (typically initialising PGD entries), so
introducing a generic pgd_alloc() isn't worth it. Instead we
introduce two new helpers, __pgd_alloc() and __pgd_free(), and make
use of them in the arch-specific pgd_alloc() and pgd_free() wherever
possible. To accommodate as many arch as possible, __pgd_alloc()
takes a page alocation order.

Because pagetable_alloc() allocates zeroed pages, we are also able
to get rid of zeroing code in some implementations of pgd_alloc().
Some trivial implementations of pgd_free() also become unnecessary
once __pgd_alloc() is used; remove them.

Another small improvement is consistent accounting of PGD pages by
using GFP_PGTABLE_{USER,KERNEL} as appropriate.

Not all PGD allocations can be handled by the generic helpers. In
particular, multiple architectures allocate PGDs from a kmem_cache,
and those PGDs may not be page-sized.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/alpha/mm/init.c                  |  2 +-
 arch/arc/include/asm/pgalloc.h        |  9 ++-------
 arch/arm/mm/pgd.c                     |  8 +++-----
 arch/arm64/mm/pgd.c                   |  4 ++--
 arch/csky/include/asm/pgalloc.h       |  2 +-
 arch/hexagon/include/asm/pgalloc.h    |  2 +-
 arch/loongarch/mm/pgtable.c           |  7 +++----
 arch/m68k/include/asm/sun3_pgalloc.h  |  2 +-
 arch/microblaze/include/asm/pgalloc.h |  7 +------
 arch/mips/include/asm/pgalloc.h       |  6 ------
 arch/mips/mm/pgtable.c                |  8 +++-----
 arch/nios2/mm/pgtable.c               |  3 ++-
 arch/openrisc/include/asm/pgalloc.h   |  6 ++----
 arch/parisc/include/asm/pgalloc.h     | 16 +---------------
 arch/riscv/include/asm/pgalloc.h      |  3 +--
 arch/um/kernel/mem.c                  |  7 +++----
 arch/x86/mm/pgtable.c                 | 24 +++++++++++-------------
 arch/xtensa/include/asm/pgalloc.h     |  2 +-
 include/asm-generic/pgalloc.h         | 27 ++++++++++++++++++++++++++-
 19 files changed, 65 insertions(+), 80 deletions(-)

diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 4fe618446e4c..61c2198b1359 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -42,7 +42,7 @@ pgd_alloc(struct mm_struct *mm)
 {
 	pgd_t *ret, *init;
 
-	ret = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+	ret = __pgd_alloc(mm, 0);
 	init = pgd_offset(&init_mm, 0UL);
 	if (ret) {
 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index 096b8ef58edb..dfae070fe8d5 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -53,19 +53,14 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte_
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	pgd_t *ret = (pgd_t *) __get_free_page(GFP_KERNEL);
+	pgd_t *ret = __pgd_alloc(mm, 0);
 
 	if (ret) {
 		int num, num2;
-		num = USER_PTRS_PER_PGD + USER_KERNEL_GUTTER / PGDIR_SIZE;
-		memzero(ret, num * sizeof(pgd_t));
 
+		num = USER_PTRS_PER_PGD + USER_KERNEL_GUTTER / PGDIR_SIZE;
 		num2 = VMALLOC_SIZE / PGDIR_SIZE;
 		memcpy(ret + num, swapper_pg_dir + num, num2 * sizeof(pgd_t));
-
-		memzero(ret + num + num2,
-			       (PTRS_PER_PGD - num - num2) * sizeof(pgd_t));
-
 	}
 	return ret;
 }
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 2a1077747758..4eb81b7ed03a 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -17,11 +17,11 @@
 #include "mm.h"
 
 #ifdef CONFIG_ARM_LPAE
-#define _pgd_alloc(mm)		kmalloc_array(PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL)
+#define _pgd_alloc(mm)		kmalloc_array(PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL | __GFP_ZERO)
 #define _pgd_free(mm, pgd)	kfree(pgd)
 #else
-#define _pgd_alloc(mm)		(pgd_t *)__get_free_pages(GFP_KERNEL, 2)
-#define _pgd_free(mm, pgd)	free_pages((unsigned long)pgd, 2)
+#define _pgd_alloc(mm)		__pgd_alloc(mm, 2)
+#define _pgd_free(mm, pgd)	__pgd_free(mm, pgd)
 #endif
 
 /*
@@ -39,8 +39,6 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 	if (!new_pgd)
 		goto no_pgd;
 
-	memset(new_pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
-
 	/*
 	 * Copy over the kernel and IO PGD entries
 	 */
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 0c501cabc238..8160cff35089 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -33,7 +33,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 	gfp_t gfp = GFP_PGTABLE_USER;
 
 	if (pgdir_is_page_size())
-		return (pgd_t *)__get_free_page(gfp);
+		return __pgd_alloc(mm, 0);
 	else
 		return kmem_cache_alloc(pgd_cache, gfp);
 }
@@ -41,7 +41,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
 	if (pgdir_is_page_size())
-		free_page((unsigned long)pgd);
+		__pgd_free(mm, pgd);
 	else
 		kmem_cache_free(pgd_cache, pgd);
 }
diff --git a/arch/csky/include/asm/pgalloc.h b/arch/csky/include/asm/pgalloc.h
index 9c84c9012e53..9a3bbf16f03f 100644
--- a/arch/csky/include/asm/pgalloc.h
+++ b/arch/csky/include/asm/pgalloc.h
@@ -44,7 +44,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 	pgd_t *ret;
 	pgd_t *init;
 
-	ret = (pgd_t *) __get_free_page(GFP_KERNEL);
+	ret = __pgd_alloc(mm, 0);
 	if (ret) {
 		init = pgd_offset(&init_mm, 0UL);
 		pgd_init((unsigned long *)ret);
diff --git a/arch/hexagon/include/asm/pgalloc.h b/arch/hexagon/include/asm/pgalloc.h
index 55988625e6fb..289dace6d76d 100644
--- a/arch/hexagon/include/asm/pgalloc.h
+++ b/arch/hexagon/include/asm/pgalloc.h
@@ -22,7 +22,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
 	pgd_t *pgd;
 
-	pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+	pgd = __pgd_alloc(mm, 0);
 
 	/*
 	 * There may be better ways to do this, but to ensure
diff --git a/arch/loongarch/mm/pgtable.c b/arch/loongarch/mm/pgtable.c
index 3fa69b23ff84..22a94bb3e6e8 100644
--- a/arch/loongarch/mm/pgtable.c
+++ b/arch/loongarch/mm/pgtable.c
@@ -23,11 +23,10 @@ EXPORT_SYMBOL(tlb_virt_to_page);
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	pgd_t *init, *ret = NULL;
-	struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 0);
+	pgd_t *init, *ret;
 
-	if (ptdesc) {
-		ret = (pgd_t *)ptdesc_address(ptdesc);
+	ret = __pgd_alloc(mm, 0);
+	if (ret) {
 		init = pgd_offset(&init_mm, 0UL);
 		pgd_init(ret);
 		memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
diff --git a/arch/m68k/include/asm/sun3_pgalloc.h b/arch/m68k/include/asm/sun3_pgalloc.h
index 4a137eecb6fe..e91b0133df5d 100644
--- a/arch/m68k/include/asm/sun3_pgalloc.h
+++ b/arch/m68k/include/asm/sun3_pgalloc.h
@@ -43,7 +43,7 @@ static inline pgd_t * pgd_alloc(struct mm_struct *mm)
 {
 	pgd_t *new_pgd;
 
-	new_pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL);
+	new_pgd = __pgd_alloc(mm, 0);
 	memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
 	memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT));
 	return new_pgd;
diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h
index 6c33b05f730f..084a8a0dc239 100644
--- a/arch/microblaze/include/asm/pgalloc.h
+++ b/arch/microblaze/include/asm/pgalloc.h
@@ -21,12 +21,7 @@
 
 extern void __bad_pte(pmd_t *pmd);
 
-static inline pgd_t *get_pgd(void)
-{
-	return (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 0);
-}
-
-#define pgd_alloc(mm)		get_pgd()
+#define pgd_alloc(mm)		__pgd_alloc(mm, 0)
 
 extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
 
diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
index f4440edcd8fe..9ee8426b2e9d 100644
--- a/arch/mips/include/asm/pgalloc.h
+++ b/arch/mips/include/asm/pgalloc.h
@@ -15,7 +15,6 @@
 
 #define __HAVE_ARCH_PMD_ALLOC_ONE
 #define __HAVE_ARCH_PUD_ALLOC_ONE
-#define __HAVE_ARCH_PGD_FREE
 #include <asm-generic/pgalloc.h>
 
 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
@@ -49,11 +48,6 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 extern void pgd_init(void *addr);
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
 
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-	pagetable_free(virt_to_ptdesc(pgd));
-}
-
 #define __pte_free_tlb(tlb, pte, address)			\
 do {								\
 	pagetable_pte_dtor(page_ptdesc(pte));			\
diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c
index 1506e458040d..10835414819f 100644
--- a/arch/mips/mm/pgtable.c
+++ b/arch/mips/mm/pgtable.c
@@ -10,12 +10,10 @@
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	pgd_t *init, *ret = NULL;
-	struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM,
-			PGD_TABLE_ORDER);
+	pgd_t *init, *ret;
 
-	if (ptdesc) {
-		ret = ptdesc_address(ptdesc);
+	ret = __pgd_alloc(mm, PGD_TABLE_ORDER);
+	if (ret) {
 		init = pgd_offset(&init_mm, 0UL);
 		pgd_init(ret);
 		memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
diff --git a/arch/nios2/mm/pgtable.c b/arch/nios2/mm/pgtable.c
index 7c76e8a7447a..6470ed378782 100644
--- a/arch/nios2/mm/pgtable.c
+++ b/arch/nios2/mm/pgtable.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 
 #include <asm/cpuinfo.h>
+#include <asm/pgalloc.h>
 
 /* pteaddr:
  *   ptbase | vpn* | zero
@@ -54,7 +55,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 {
 	pgd_t *ret, *init;
 
-	ret = (pgd_t *) __get_free_page(GFP_KERNEL);
+	ret = __pgd_alloc(mm, 0);
 	if (ret) {
 		init = pgd_offset(&init_mm, 0UL);
 		pgd_init(ret);
diff --git a/arch/openrisc/include/asm/pgalloc.h b/arch/openrisc/include/asm/pgalloc.h
index c6a73772a546..c068c4942467 100644
--- a/arch/openrisc/include/asm/pgalloc.h
+++ b/arch/openrisc/include/asm/pgalloc.h
@@ -41,15 +41,13 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
  */
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL);
+	pgd_t *ret = __pgd_alloc(mm, 0);
 
-	if (ret) {
-		memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+	if (ret)
 		memcpy(ret + USER_PTRS_PER_PGD,
 		       swapper_pg_dir + USER_PTRS_PER_PGD,
 		       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
 
-	}
 	return ret;
 }
 
diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
index 3e8dbd79670b..2ca74a56415c 100644
--- a/arch/parisc/include/asm/pgalloc.h
+++ b/arch/parisc/include/asm/pgalloc.h
@@ -11,26 +11,12 @@
 #include <asm/cache.h>
 
 #define __HAVE_ARCH_PMD_ALLOC_ONE
-#define __HAVE_ARCH_PGD_FREE
 #include <asm-generic/pgalloc.h>
 
 /* Allocate the top level pgd (page directory) */
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	pgd_t *pgd;
-
-	pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_TABLE_ORDER);
-	if (unlikely(pgd == NULL))
-		return NULL;
-
-	memset(pgd, 0, PAGE_SIZE << PGD_TABLE_ORDER);
-
-	return pgd;
-}
-
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-	free_pages((unsigned long)pgd, PGD_TABLE_ORDER);
+	return __pgd_alloc(mm, PGD_TABLE_ORDER);
 }
 
 #if CONFIG_PGTABLE_LEVELS == 3
diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
index 3c364ecc3100..d527f141be1c 100644
--- a/arch/riscv/include/asm/pgalloc.h
+++ b/arch/riscv/include/asm/pgalloc.h
@@ -128,9 +128,8 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
 	pgd_t *pgd;
 
-	pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
+	pgd = __pgd_alloc(mm, 0);
 	if (likely(pgd != NULL)) {
-		memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
 		/* Copy kernel mappings */
 		sync_kernel_mappings(pgd);
 	}
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 53248ed04771..d98812907493 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -214,14 +214,13 @@ void free_initmem(void)
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
+	pgd_t *pgd = __pgd_alloc(mm, 0);
 
-	if (pgd) {
-		memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+	if (pgd)
 		memcpy(pgd + USER_PTRS_PER_PGD,
 		       swapper_pg_dir + USER_PTRS_PER_PGD,
 		       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
-	}
+
 	return pgd;
 }
 
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index c1bfdf7b4767..00917ef609b6 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -395,15 +395,14 @@ void __init pgtable_cache_init(void)
 				      SLAB_PANIC, NULL);
 }
 
-static inline pgd_t *_pgd_alloc(void)
+static inline pgd_t *_pgd_alloc(struct mm_struct *mm)
 {
 	/*
 	 * If no SHARED_KERNEL_PMD, PAE kernel is running as a Xen domain.
 	 * We allocate one page for pgd.
 	 */
 	if (!SHARED_KERNEL_PMD)
-		return (pgd_t *)__get_free_pages(GFP_PGTABLE_USER,
-						 PGD_ALLOCATION_ORDER);
+		return __pgd_alloc(mm, PGD_ALLOCATION_ORDER);
 
 	/*
 	 * Now PAE kernel is not running as a Xen domain. We can allocate
@@ -412,24 +411,23 @@ static inline pgd_t *_pgd_alloc(void)
 	return kmem_cache_alloc(pgd_cache, GFP_PGTABLE_USER);
 }
 
-static inline void _pgd_free(pgd_t *pgd)
+static inline void _pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
 	if (!SHARED_KERNEL_PMD)
-		free_pages((unsigned long)pgd, PGD_ALLOCATION_ORDER);
+		__pgd_free(mm, pgd);
 	else
 		kmem_cache_free(pgd_cache, pgd);
 }
 #else
 
-static inline pgd_t *_pgd_alloc(void)
+static inline pgd_t *_pgd_alloc(struct mm_struct *mm)
 {
-	return (pgd_t *)__get_free_pages(GFP_PGTABLE_USER,
-					 PGD_ALLOCATION_ORDER);
+	return __pgd_alloc(mm, PGD_ALLOCATION_ORDER);
 }
 
-static inline void _pgd_free(pgd_t *pgd)
+static inline void _pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
-	free_pages((unsigned long)pgd, PGD_ALLOCATION_ORDER);
+	__pgd_free(mm, pgd);
 }
 #endif /* CONFIG_X86_PAE */
 
@@ -439,7 +437,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 	pmd_t *u_pmds[MAX_PREALLOCATED_USER_PMDS];
 	pmd_t *pmds[MAX_PREALLOCATED_PMDS];
 
-	pgd = _pgd_alloc();
+	pgd = _pgd_alloc(mm);
 
 	if (pgd == NULL)
 		goto out;
@@ -482,7 +480,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 	if (sizeof(pmds) != 0)
 		free_pmds(mm, pmds, PREALLOCATED_PMDS);
 out_free_pgd:
-	_pgd_free(pgd);
+	_pgd_free(mm, pgd);
 out:
 	return NULL;
 }
@@ -492,7 +490,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 	pgd_mop_up_pmds(mm, pgd);
 	pgd_dtor(pgd);
 	paravirt_pgd_free(mm, pgd);
-	_pgd_free(pgd);
+	_pgd_free(mm, pgd);
 }
 
 /*
diff --git a/arch/xtensa/include/asm/pgalloc.h b/arch/xtensa/include/asm/pgalloc.h
index 7fc0f9126dd3..1919ee9c3dd6 100644
--- a/arch/xtensa/include/asm/pgalloc.h
+++ b/arch/xtensa/include/asm/pgalloc.h
@@ -29,7 +29,7 @@
 static inline pgd_t*
 pgd_alloc(struct mm_struct *mm)
 {
-	return (pgd_t*) __get_free_page(GFP_KERNEL | __GFP_ZERO);
+	return __pgd_alloc(mm, 0);
 }
 
 static inline void ptes_clear(pte_t *ptep)
diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index bb482eeca0c3..daa8bea36952 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -262,10 +262,35 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
 
 #endif /* CONFIG_PGTABLE_LEVELS > 4 */
 
+static inline pgd_t *__pgd_alloc_noprof(struct mm_struct *mm, unsigned int order)
+{
+	gfp_t gfp = GFP_PGTABLE_USER;
+	struct ptdesc *ptdesc;
+
+	if (mm == &init_mm)
+		gfp = GFP_PGTABLE_KERNEL;
+	gfp &= ~__GFP_HIGHMEM;
+
+	ptdesc = pagetable_alloc_noprof(gfp, order);
+	if (!ptdesc)
+		return NULL;
+
+	return ptdesc_address(ptdesc);
+}
+#define __pgd_alloc(...)	alloc_hooks(__pgd_alloc_noprof(__VA_ARGS__))
+
+static inline void __pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+	struct ptdesc *ptdesc = virt_to_ptdesc(pgd);
+
+	BUG_ON((unsigned long)pgd & (PAGE_SIZE-1));
+	pagetable_free(ptdesc);
+}
+
 #ifndef __HAVE_ARCH_PGD_FREE
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
-	pagetable_free(virt_to_ptdesc(pgd));
+	__pgd_free(mm, pgd);
 }
 #endif
 
-- 
2.47.0



From kevin.brodsky at arm.com  Thu Dec 19 08:44:25 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Thu, 19 Dec 2024 16:44:25 +0000
Subject: [PATCH 10/10] mm: Introduce ctor/dtor at PGD level
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <20241219164425.2277022-11-kevin.brodsky@arm.com>

Following on from the introduction of P4D-level ctor/dtor, let's
finish the job and introduce ctor/dtor at PGD level. The incurred
improvement in page accounting is minimal - the main motivation is
to create a single, generic place where construction/destruction
hooks can be added for all page table pages.

This patch should cover all architectures and all configurations
where PGDs are one or more regular pages. This excludes any
configuration where PGDs are allocated from a kmem_cache object.

Signed-off-by: Kevin Brodsky <kevin.brodsky at arm.com>
---
 arch/m68k/include/asm/mcf_pgalloc.h |  2 ++
 arch/m68k/mm/motorola.c             |  6 ++++++
 arch/s390/include/asm/pgalloc.h     |  8 +++++++-
 include/asm-generic/pgalloc.h       |  2 ++
 include/linux/mm.h                  | 10 ++++++++++
 5 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h
index 302c5bf67179..7bb9652e1d67 100644
--- a/arch/m68k/include/asm/mcf_pgalloc.h
+++ b/arch/m68k/include/asm/mcf_pgalloc.h
@@ -73,6 +73,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pgtable)
 
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
+	pagetable_pgd_dtor(virt_to_ptdesc(pgd));
 	pagetable_free(virt_to_ptdesc(pgd));
 }
 
@@ -84,6 +85,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 
 	if (!ptdesc)
 		return NULL;
+	pagetable_pgd_ctor(ptdesc);
 	new_pgd = ptdesc_address(ptdesc);
 
 	memcpy(new_pgd, swapper_pg_dir, PTRS_PER_PGD * sizeof(pgd_t));
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index 37010ee15928..b0fbb369589f 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -169,6 +169,9 @@ void *get_pointer_table(int type)
 		case TABLE_PMD:
 			pagetable_pmd_ctor(virt_to_ptdesc(page));
 			break;
+		case TABLE_PGD:
+			pagetable_pgd_ctor(virt_to_ptdesc(page));
+			break;
 		}
 
 		mmu_page_ctor(page);
@@ -215,6 +218,9 @@ int free_pointer_table(void *table, int type)
 		case TABLE_PMD:
 			pagetable_pmd_dtor(virt_to_ptdesc((void *)page));
 			break;
+		case TABLE_PGD:
+			pagetable_pgd_dtor(virt_to_ptdesc((void *)page));
+			break;
 		}
 
 		free_page (page);
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 85a5d07365aa..00b69f4ddf17 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -126,11 +126,17 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	return (pgd_t *) crst_table_alloc(mm);
+	unsigned long *table = crst_table_alloc(mm);
+
+	if (!table)
+		return NULL;
+	pagetable_pgd_ctor(virt_to_ptdesc(table));
+	return (pgd_t *) table;
 }
 
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
+	pagetable_pgd_dtor(virt_to_ptdesc(pgd));
 	crst_table_free(mm, (unsigned long *) pgd);
 }
 
diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index daa8bea36952..112b09dc992e 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -275,6 +275,7 @@ static inline pgd_t *__pgd_alloc_noprof(struct mm_struct *mm, unsigned int order
 	if (!ptdesc)
 		return NULL;
 
+	pagetable_pgd_ctor(ptdesc);
 	return ptdesc_address(ptdesc);
 }
 #define __pgd_alloc(...)	alloc_hooks(__pgd_alloc_noprof(__VA_ARGS__))
@@ -284,6 +285,7 @@ static inline void __pgd_free(struct mm_struct *mm, pgd_t *pgd)
 	struct ptdesc *ptdesc = virt_to_ptdesc(pgd);
 
 	BUG_ON((unsigned long)pgd & (PAGE_SIZE-1));
+	pagetable_pgd_dtor(ptdesc);
 	pagetable_free(ptdesc);
 }
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e8b92f4bf3f1..7347da3460c5 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3171,6 +3171,16 @@ static inline void pagetable_p4d_dtor(struct ptdesc *ptdesc)
 	__pagetable_dtor(ptdesc);
 }
 
+static inline void pagetable_pgd_ctor(struct ptdesc *ptdesc)
+{
+	__pagetable_ctor(ptdesc);
+}
+
+static inline void pagetable_pgd_dtor(struct ptdesc *ptdesc)
+{
+	__pagetable_dtor(ptdesc);
+}
+
 extern void __init pagecache_init(void);
 extern void free_initmem(void);
 
-- 
2.47.0



From broonie at kernel.org  Thu Dec 19 08:49:05 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Dec 2024 16:49:05 +0000
Subject: [PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <51632b4e-19a0-487f-878d-f03abeea2553@sirena.org.uk>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
 <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>
 <20241210170953.GB16075@willie-the-truck>
 <b859bdcd-7343-4d53-9f3a-f374deca725a@sirena.org.uk>
 <20241211224015.GB17836@willie-the-truck>
 <248dea18-bfad-4ec9-9a7d-5c87c7f48c84@sirena.org.uk>
 <20241219155547.GC24724@willie-the-truck>
 <51632b4e-19a0-487f-878d-f03abeea2553@sirena.org.uk>
Message-ID: <317e06e8-6e85-48cb-902b-4b3c7748bd8f@sirena.org.uk>

On Thu, Dec 19, 2024 at 04:39:11PM +0000, Mark Brown wrote:
> On Thu, Dec 19, 2024 at 03:55:48PM +0000, Will Deacon wrote:
> > On Thu, Dec 12, 2024 at 11:33:05AM +0000, Mark Brown wrote:

> > > That'd be useful, yes - unfortunately I think that's still something I
> > > can't work on myself at the moment for the above mentioned non-technical
> > > reasons.

> > Is anybody able to work on it? Without insight into the "non-technical
> > reasons", I don't know what I'm supposed to do other than write the tool
> > myself (which means finding some spare cycles...) or refusing to take
> > wholesale sysreg definitions until it's been ironed out :/

> Similar issues will apply to anyone at Arm as things currently stand.

Oh, actually - shortly after I sent this mail I got a notification that
there's now an "Open Source Machine Readable Data" package at:

  https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads

as part of the 2024-12 which should unblock this, just in time for
Christmas.  There's just the small matter of free time to resolve!
-------------- 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/20241219/1f438cd0/attachment.sig>

From will at kernel.org  Thu Dec 19 08:57:00 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 16:57:00 +0000
Subject: [PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601
 2024-09
In-Reply-To: <317e06e8-6e85-48cb-902b-4b3c7748bd8f@sirena.org.uk>
References: <20241203-arm64-2024-dpisa-v3-0-a6c78b1aa297@kernel.org>
 <20241203-arm64-2024-dpisa-v3-2-a6c78b1aa297@kernel.org>
 <20241210170953.GB16075@willie-the-truck>
 <b859bdcd-7343-4d53-9f3a-f374deca725a@sirena.org.uk>
 <20241211224015.GB17836@willie-the-truck>
 <248dea18-bfad-4ec9-9a7d-5c87c7f48c84@sirena.org.uk>
 <20241219155547.GC24724@willie-the-truck>
 <51632b4e-19a0-487f-878d-f03abeea2553@sirena.org.uk>
 <317e06e8-6e85-48cb-902b-4b3c7748bd8f@sirena.org.uk>
Message-ID: <20241219165659.GI24724@willie-the-truck>

On Thu, Dec 19, 2024 at 04:49:05PM +0000, Mark Brown wrote:
> On Thu, Dec 19, 2024 at 04:39:11PM +0000, Mark Brown wrote:
> > On Thu, Dec 19, 2024 at 03:55:48PM +0000, Will Deacon wrote:
> > > On Thu, Dec 12, 2024 at 11:33:05AM +0000, Mark Brown wrote:
> 
> > > > That'd be useful, yes - unfortunately I think that's still something I
> > > > can't work on myself at the moment for the above mentioned non-technical
> > > > reasons.
> 
> > > Is anybody able to work on it? Without insight into the "non-technical
> > > reasons", I don't know what I'm supposed to do other than write the tool
> > > myself (which means finding some spare cycles...) or refusing to take
> > > wholesale sysreg definitions until it's been ironed out :/
> 
> > Similar issues will apply to anyone at Arm as things currently stand.
> 
> Oh, actually - shortly after I sent this mail I got a notification that
> there's now an "Open Source Machine Readable Data" package at:
> 
>   https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads
> 
> as part of the 2024-12 which should unblock this, just in time for
> Christmas.  There's just the small matter of free time to resolve!

<party.gif>

That's great! Hopefully we can knock up some basic linter tools in the
new year.

Thanks,

Will


From Frank.li at nxp.com  Thu Dec 19 09:02:02 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:02:02 -0500
Subject: [PATCH v13 4/9] irqchip/gic-v3-its: Add
 DOMAIN_BUS_DEVICE_PCI_EP_MSI support
In-Reply-To: <868qscq70x.wl-maz@kernel.org>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
 <20241218-ep-msi-v13-4-646e2192dc24@nxp.com>
 <868qscq70x.wl-maz@kernel.org>
Message-ID: <Z2RRimPlT41Ru281@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 10:52:30AM +0000, Marc Zyngier wrote:
> On Wed, 18 Dec 2024 23:08:39 +0000,
> Frank Li <Frank.Li at nxp.com> wrote:
> >
> >            ??????????????????????????????????
> >            ?                                ?
> >            ?     PCI Endpoint Controller    ?
> >            ?                                ?
> >            ?   ???????  ???????     ??????? ?
> > PCI Bus    ?   ?     ?  ?     ?     ?     ? ?
> > ?????????? ?   ?Func1?  ?Func2? ... ?Func ? ?
> > Doorbell   ?   ?     ?  ?     ?     ?<n>  ? ?
> >            ?   ?     ?  ?     ?     ?     ? ?
> >            ?   ???????  ???????     ??????? ?
> >            ?      ?        ?           ?    ?
> >            ??????????????????????????????????
> >                   ?        ?           ?
> >                   ?        ?           ?
> >                ??????????????????????????
> >                ?    MSI Controller      ?
> >                ??????????????????????????
> >
> > Add domain DOMAIN_BUS_DEVICE_PCI_EP_MSI to allocate MSI domain for Endpoint
> > function in PCI Endpoint (EP) controller, So PCI Root Complex (RC) can
> > write MSI message to MSI controller to trigger doorbell IRQ for difference
> > EP functions.
> >
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > change from v12 to v13
> > - new patch
>
> This might be v13, but after all this time, I have no idea what you
> are trying to do. You keep pasting this non-ASCII drawing in commit
> messages, but I still have no idea what this PCI Bus Doorbell
> represents.

PCI Bus/Doorbell is two words. Basic over picture is a PCI EP devices (such
as imx95), which run linux and PCI Endpoint framework. i.MX95 connect to
PCI Host, such as PC (x86).

i.MX95 can use standard PCI MSI framework to issue a irq to X86. but there
are not reverse direction. X86 try write some MMIO register ( mapped PCI
bar0). But i.MX95 don't know it have been modified. So currently solution
is create a polling thread to check every 10ms.

So this patches try resolve this problem at the platform, which have MSI
controller such as ITS.

after this patches, i.MX95 can create a PCI Bar1, which map to MSI
controller register space,  when X86 write data to Bar1 (call as doorbell),
a irq will be triggered at i.MX95.

Doorbell in diagram means 'push doorbell' (write data to bar<n>).

>
> I appreciate the knowledge shortage is on my end, but it would
> definitely help if someone would take the time to explain what this is
> all about.

I am not sure if diagram in corver letter can help this, or above
descriptions is enough.


??????????????   ?????????????????????????????????????   ??????????????????
?            ?   ?                                   ?   ?                ?
?            ?   ? PCI Endpoint                      ?   ? PCI Host       ?
?            ?   ?                                   ?   ?                ?
?            ????? 1.platform_msi_domain_alloc_irqs()?   ?                ?
?            ?   ?                                   ?   ?                ?
? MSI        ????? 2.write_msi_msg()                 ??????BAR<n>         ?
? Controller ?   ?   update doorbell register address?   ?                ?
?            ?   ?   for BAR                         ?   ?                ?
?            ?   ?                                   ?   ? 3. Write BAR<n>?
?            ?????????????????????????????????????????????                ?
?            ?   ?                                   ?   ?                ?
?            ????? 4.Irq Handle                      ?   ?                ?
?            ?   ?                                   ?   ?                ?
?            ?   ?                                   ?   ?                ?
??????????????   ?????????????????????????????????????   ??????????????????
(* some detail have been changed and don't affect understand overall
picture)

>
> From what I gather, the ITS is actually on an end-point, and get
> writes from the host, but that doesn't answer much.

Yes, baisc it is correct. PCI RC -> PCIe Bus TLP -> PCI Endpoint Ctrl ->
AXI transaction -> ITS MMIO map register -> CPU IRQ.

The major problem how to distingiush from difference PCI Endpoint function
driver. There are have many EP functions as much as 8, which quite similar
standard PCI, one PCIe device can have 8 physical functions.

>
> > ---
> >  drivers/irqchip/irq-gic-v3-its-msi-parent.c | 19 ++++++++++++++++++-
> >  1 file changed, 18 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
> > index b2a4b67545b82..16e7d53f0b133 100644
> > --- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
> > +++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
> > @@ -5,6 +5,7 @@
> >  // Copyright (C) 2022 Intel
> >
> >  #include <linux/acpi_iort.h>
> > +#include <linux/pci-ep-msi.h>
> >  #include <linux/pci.h>
> >
> >  #include "irq-gic-common.h"
> > @@ -173,6 +174,19 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
> >  	return its_pmsi_prepare_devid(domain, dev, nvec, info, dev_id);
> >  }
> >
> > +static int its_pci_ep_msi_prepare(struct irq_domain *domain, struct device *dev,
> > +				  int nvec, msi_alloc_info_t *info)
> > +{
> > +	u32 dev_id;
> > +	int ret;
> > +
> > +	ret = pci_epf_msi_domain_get_msi_rid(dev, &dev_id);
>
> What this doesn't express is *how* are the writes conveyed to the ITS.
> Specifically, the DevID is normally sampled as sideband information at
> during the write transaction.

Like PCI host, there msi-map in dts file, which descript how map PCI RID
to DevID, such as
	msi-map = <0 $its 0x80 8>;

This informtion should be descripted in DTS or ACPI ...

>
> Obviously, you can't do that over PCI. So there is a lot of
> undisclosed assumption about how the ITS is integrated, and how it
> samples the DevID.

Yes, it should be platform PCI endpoint ctrl driver jobs.  Platform EP
driver should implement this type of covert. Such as i.MX95, there are
hardware call LUT in PCI ctrl,  which can convert PCI' request ID to DevID
here.

On going patch may help understand these
https://lore.kernel.org/linux-pci/20241210-imx95_lut-v8-0-2e730b2e5fde at nxp.com/

If use latest ITS MSI64 should be simple, only need descript it at DTS
(I have not hardware to test this case yet).
pci-ep {
	...
	msi-map = <0 &its, 0x<8_0000, 0xff>;
			      ^, ctrl ID.
	msi-mask = <0xff>;
	...
}

>
> My conclusion is that this is not as generic as it seems to be. It is
> definitely tied to implementation-specific behaviours, none of which
> are explained.

Compared to standard PCI MSI, which also have implementation-specific
behaviours, which convert PCI request ID to DevID Or stream ID.
https://lore.kernel.org/linux-pci/20241210-imx95_lut-v8-0-2e730b2e5fde at nxp.com/
(I have struggle this for almost one year for this implementation-specific
part)

Well defined and mature PCI standard, MSI still need two parts, common part
and "implementation-specific" part.

Common part of standard PCI is at several place, such its driver/msi
libary/ kernel msi code ...

"implementation-specific" part is in PCI host bridge driver, such as
drivers/pci/controller/dwc/pcie-qcom.c

This solution already test by Tested-by: Niklas Cassel <cassel at kernel.org>
who use another dwc controller, which they already implemented
"implementation-specific" by only update dts to provide hardware
information.(I guest he use ITS's MSI64)

Because it is new patches, I have not added Niklas's test-by tag. There
are not big functional change since Nikas test. The major change is make
msi part better align current MSI framework according to Thomas's
suggestion.

Frank
>
> Thanks,
>
> 	M.
>
> --
> Without deviation from the norm, progress is not possible.


From jason-jh.lin at mediatek.com  Thu Dec 19 09:07:53 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 01:07:53 +0800
Subject: [PATCH v3 0/7] Add GCE support for MT8196
Message-ID: <20241219170800.2957-1-jason-jh.lin@mediatek.com>

From: Jason-jh Lin <jason-jh.lin at mediatek.corp-partner.google.com>

This patch series adds support for the MediaTek MT8196 SoC in the CMDQ
driver and related subsystems. The changes include adding compatible
names and properties, updating driver data to accommodate hardware
changes, and modifying the usage of CMDQ APIs to support non-subsys ID
hardware.

---

Change in v3:
1. Merge 2 dt-bindings pathes together and add more detail commit message.
2. Change type u32 to phys_addr_t for pa_base of struct cmdq_client_reg.
3. Remove cmdq_subsys_is_valid() and subsys_num in CMDQ driver.
4. Add CMDQ_SUBSYS_INVALID to check subsys instead of using
   cmdq_subsys_is_invalid().
5. Make use of CMDQ_THR_SPR0 define to the parameter of CMDQ APIs.
6. Rebase on the new MACRO in mtk-mdp3-comp.h.

Change in v2:
1. Remove the constant and fix warning in dt-bindings.
2. Remove the pa_base parameter of CMDQ APIs and related modification.
3. Move subsys checking to client drivers and use 2 alternative
   CMDQ APIs to achieve the same functionality.

---

Jason-JH.Lin (7):
  dt-bindings: mailbox: mediatek: Add MT8196 support for gce-mailbox
  mailbox: mtk-cmdq: Add driver data to support for MT8196
  soc: mediatek: mtk-cmdq: Add pa_base parsing for unsupported subsys ID
    hardware
  soc: mediatek: mtk-cmdq: Add mminfra_offset compatibility for DRAM
    address
  soc: mediatek: Add programming flow for unsupported subsys ID hardware
  drm/mediatek: Add programming flow for unsupported subsys ID hardware
  media: mediatek: mdp3: Add programming flow for unsupported subsys ID
    hardware

 .../mailbox/mediatek,gce-mailbox.yaml         |    4 +
 drivers/gpu/drm/mediatek/mtk_ddp_comp.c       |   33 +-
 drivers/mailbox/mtk-cmdq-mailbox.c            |   90 +-
 .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c    |   18 +-
 .../platform/mediatek/mdp3/mtk-mdp3-comp.h    |   79 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c        |   53 +-
 drivers/soc/mediatek/mtk-mmsys.c              |   14 +-
 drivers/soc/mediatek/mtk-mutex.c              |   11 +-
 .../dt-bindings/mailbox/mediatek,mt8196-gce.h | 1415 +++++++++++++++++
 include/linux/mailbox/mtk-cmdq-mailbox.h      |    2 +
 include/linux/soc/mediatek/mtk-cmdq.h         |    3 +
 11 files changed, 1679 insertions(+), 43 deletions(-)
 create mode 100644 include/dt-bindings/mailbox/mediatek,mt8196-gce.h

-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 19 09:07:54 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 01:07:54 +0800
Subject: [PATCH v3 1/7] dt-bindings: mailbox: mediatek: Add MT8196 support for gce-mailbox
In-Reply-To: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
References: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219170800.2957-2-jason-jh.lin@mediatek.com>

1. Add compatible name and iommus property to mediatek,gce-mailbox.yaml
   for MT8196.

   - The compatible name "mediatek,mt8196-gce-mailbox" is added to
     ensure that the device tree can correctly identify and configure
     the GCE mailbox for the MT8196 SoC.

   - The iommus property is added to specify the IOMMU configuration
     for the GCE mailbox, ensuring proper memory management and access
     control.

2. Add the Global Command Engine (GCE) binding header to define the
   abstrct symbol binding to the GCE hardware settings of GCE Thread
   Priority, GCE Subsys ID and GCE Event for MT8196.

   - GCE Thread Priority: Defined to configure the priority level for
     each GCE hardware thread. This is necessary for proper scheduling
     and execution of commands in the GCE.

   - GCE Subsys ID: Defined to specify the subsystem ID for GCE clients.
     This is used to correctly address and access different subsystems
     within the GCE.

   - GCE Event: Defined to specify the events that the GCE can handle.
     These events are used by the driver to synchronize and manage
     hardware operations.

   Examples of the binding usage in the driver code:
   1) GCE Thread Priority:
   - Defined in the header file: `#define CMDQ_THR_PRIO_4 4`
   - Used in the Device Tree: `mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;`
   - Parsed and used in the driver to set thread priority:
     ```c
     static struct mbox_chan *cmdq_xlate(struct mbox_controller *mbox,i
     					 const struct of_phandle_args *sp)
     {
     	thread->priority = sp->args[1];
     }
     // set GCE thread priority to the priority level 4 for GCE thread 0
     writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
     ```

   2) GCE Subsys ID:
   - Defined in the header file: `#define SUBSYS_1c00XXXX 3`
   - Used in the Device Tree:
   	`mediatek,gce-client-reg = <&gce SUBSYS_1c00XXXX 0x0000 0x1000>;`
   - Parsed and used in the driver to configure subsys ID:
     ```c
     int cmdq_dev_get_client_reg(struct device *dev,
     				 struct cmdq_client_reg *client_reg,
     				 int idx)
     {
     	client_reg->subsys = (u8)spec.args[0];
     	client_reg->offset = (u16)spec.args[1];
     }
     // GCE write the value to the register 0x1c000000 + 0x0000 + offset
     cmdq_pkt_write(cmdq_handle, client_reg->subsys,
     		    client_reg->offset + offset, value);
     ```

   3) GCE Event:
   - Defined in the header file:
   	`#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0 574`
   - Used in the Device Tree:
   	`mediatek,gce-events = <CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0>;`
   - Parsed and used in the driver to handle events:
     ```c
     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)
     {
     	of_property_read_u32_index(priv->mutex_node,
     				   "mediatek,gce-events", i,
     				   &mtk_crtc->cmdq_event);
     }
     // GCE clear the STREAM_DONE event sent from DISP_MUTEX hardware
     cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
     ```

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 .../mailbox/mediatek,gce-mailbox.yaml         |    4 +
 .../dt-bindings/mailbox/mediatek,mt8196-gce.h | 1415 +++++++++++++++++
 2 files changed, 1419 insertions(+)
 create mode 100644 include/dt-bindings/mailbox/mediatek,mt8196-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml
index cef9d7601398..73d6db34d64a 100644
--- a/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml
+++ b/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml
@@ -25,6 +25,7 @@ properties:
           - mediatek,mt8188-gce
           - mediatek,mt8192-gce
           - mediatek,mt8195-gce
+          - mediatek,mt8196-gce
       - items:
           - const: mediatek,mt6795-gce
           - const: mediatek,mt8173-gce
@@ -49,6 +50,9 @@ properties:
     items:
       - const: gce
 
+  iommus:
+    maxItems: 1
+
 required:
   - compatible
   - "#mbox-cells"
diff --git a/include/dt-bindings/mailbox/mediatek,mt8196-gce.h b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h
new file mode 100644
index 000000000000..9e0700236033
--- /dev/null
+++ b/include/dt-bindings/mailbox/mediatek,mt8196-gce.h
@@ -0,0 +1,1415 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2024 MediaTek Inc.
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8196_H
+#define _DT_BINDINGS_GCE_MT8196_H
+
+/* GCE thread priority */
+#define CMDQ_THR_PRIO_LOWEST	0
+#define CMDQ_THR_PRIO_1		1
+#define CMDQ_THR_PRIO_2		2
+#define CMDQ_THR_PRIO_3		3
+#define CMDQ_THR_PRIO_4		4
+#define CMDQ_THR_PRIO_5		5
+#define CMDQ_THR_PRIO_6		6
+#define CMDQ_THR_PRIO_HIGHEST	7
+
+/* GCE subsys table */
+#define SUBSYS_1300XXXX		0
+#define SUBSYS_1400XXXX		1
+#define SUBSYS_1401XXXX		2
+#define SUBSYS_1402XXXX		3
+#define SUBSYS_1502XXXX		4
+#define SUBSYS_1880XXXX		5
+#define SUBSYS_1881XXXX		6
+#define SUBSYS_1882XXXX		7
+#define SUBSYS_1883XXXX		8
+#define SUBSYS_1884XXXX		9
+#define SUBSYS_1000XXXX		10
+#define SUBSYS_1001XXXX		11
+#define SUBSYS_1002XXXX		12
+#define SUBSYS_1003XXXX		13
+#define SUBSYS_1004XXXX		14
+#define SUBSYS_1005XXXX		15
+#define SUBSYS_1020XXXX		16
+#define SUBSYS_1028XXXX		17
+#define SUBSYS_1700XXXX		18
+#define SUBSYS_1701XXXX		19
+#define SUBSYS_1702XXXX		20
+#define SUBSYS_1703XXXX		21
+#define SUBSYS_1800XXXX		22
+#define SUBSYS_1801XXXX		23
+#define SUBSYS_1802XXXX		24
+#define SUBSYS_1804XXXX		25
+#define SUBSYS_1805XXXX		26
+#define SUBSYS_1808XXXX		27
+#define SUBSYS_180aXXXX		28
+#define SUBSYS_180bXXXX		29
+#define SUBSYS_NO_SUPPORT	99
+
+/* GCE-D hardware events */
+#define CMDQ_EVENT_DISP0_STREAM_SOF0						0
+#define CMDQ_EVENT_DISP0_STREAM_SOF1						1
+#define CMDQ_EVENT_DISP0_STREAM_SOF2						2
+#define CMDQ_EVENT_DISP0_STREAM_SOF3						3
+#define CMDQ_EVENT_DISP0_STREAM_SOF4						4
+#define CMDQ_EVENT_DISP0_STREAM_SOF5						5
+#define CMDQ_EVENT_DISP0_STREAM_SOF6						6
+#define CMDQ_EVENT_DISP0_STREAM_SOF7						7
+#define CMDQ_EVENT_DISP0_STREAM_SOF8						8
+#define CMDQ_EVENT_DISP0_STREAM_SOF9						9
+#define CMDQ_EVENT_DISP0_STREAM_SOF10						10
+#define CMDQ_EVENT_DISP0_STREAM_SOF11						11
+#define CMDQ_EVENT_DISP0_STREAM_SOF12						12
+#define CMDQ_EVENT_DISP0_STREAM_SOF13						13
+#define CMDQ_EVENT_DISP0_STREAM_SOF14						14
+#define CMDQ_EVENT_DISP0_STREAM_SOF15						15
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL0					16
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL1					17
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL2					18
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL3					19
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL4					20
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL5					21
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL6					22
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL7					23
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL8					24
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL9					25
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL10					26
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL11					27
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL12					28
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL13					29
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL14					30
+#define CMDQ_EVENT_DISP0_FRAME_DONE_SEL15					31
+#define CMDQ_EVENT_DISP0_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT			32
+#define CMDQ_EVENT_DISP0_DISP_WDMA0_SW_RST_DONE_ENG_EVENT			33
+#define CMDQ_EVENT_DISP0_DISP_POSTMASK1_RST_DONE_ENG_EVENT			34
+#define CMDQ_EVENT_DISP0_DISP_POSTMASK0_RST_DONE_ENG_EVENT			35
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_TIMEOUT_ENG_EVENT				36
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT0			37
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT1			38
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT2			39
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT3			40
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT4			41
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT5			42
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT6			43
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT7			44
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT8			45
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT9			46
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT10			47
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT11			48
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT12			49
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT13			50
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT14			51
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_REG_UPDATE_ENG_EVENT15			52
+#define CMDQ_EVENT_DISP0_DISP_MUTEX0_GET_RELEASE_ENG_EVENT			53
+#define CMDQ_EVENT_DISP0_DISP_MDP_RDMA0_SW_RST_DONE_ENG_EVENT			54
+
+#define CMDQ_EVENT_DISP1_STREAM_SOF0						55
+#define CMDQ_EVENT_DISP1_STREAM_SOF1						56
+#define CMDQ_EVENT_DISP1_STREAM_SOF2						57
+#define CMDQ_EVENT_DISP1_STREAM_SOF3						58
+#define CMDQ_EVENT_DISP1_STREAM_SOF4						59
+#define CMDQ_EVENT_DISP1_STREAM_SOF5						60
+#define CMDQ_EVENT_DISP1_STREAM_SOF6						61
+#define CMDQ_EVENT_DISP1_STREAM_SOF7						62
+#define CMDQ_EVENT_DISP1_STREAM_SOF8						63
+#define CMDQ_EVENT_DISP1_STREAM_SOF9						64
+#define CMDQ_EVENT_DISP1_STREAM_SOF10						65
+#define CMDQ_EVENT_DISP1_STREAM_SOF11						66
+#define CMDQ_EVENT_DISP1_STREAM_SOF12						67
+#define CMDQ_EVENT_DISP1_STREAM_SOF13						68
+#define CMDQ_EVENT_DISP1_STREAM_SOF14						69
+#define CMDQ_EVENT_DISP1_STREAM_SOF15						70
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL0					71
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL1					72
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL2					73
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL3					74
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL4					75
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL5					76
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL6					77
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL7					78
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL8					79
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL9					80
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL10					81
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL11					82
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL12					83
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL13					84
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL14					85
+#define CMDQ_EVENT_DISP1_FRAME_DONE_SEL15					86
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT0					87
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT1					88
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT2					89
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT3					90
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT4					91
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT5					92
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT6					93
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT7					94
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT8					95
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT9					96
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT10				97
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT11				98
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT12				99
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT13				100
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT14				101
+#define CMDQ_EVENT_DISP1_STREAM_DONE_ENG_EVENT15				102
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT0				103
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT1				104
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT2				105
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT3				106
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT4				107
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT5				108
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT6				109
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT7				110
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT8				111
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT9				112
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT10				113
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT11				114
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT12				115
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT13				116
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT14				117
+#define CMDQ_EVENT_DISP1_REG_UPDATE_DONE_ENG_EVENT15				118
+#define CMDQ_EVENT_DISP1_OCIP_SUBSYS_SRAM_ISOINT_ENG_EVENT			119
+#define CMDQ_EVENT_DISP1_DISP_WDMA4_TARGET_LINE_END_ENG_EVENT			120
+#define CMDQ_EVENT_DISP1_DISP_WDMA4_SW_RST_DONE_ENG_EVENT			121
+#define CMDQ_EVENT_DISP1_DISP_WDMA3_TARGET_LINE_END_ENG_EVENT			122
+#define CMDQ_EVENT_DISP1_DISP_WDMA3_SW_RST_DONE_ENG_EVENT			123
+#define CMDQ_EVENT_DISP1_DISP_WDMA2_TARGET_LINE_END_ENG_EVENT			124
+#define CMDQ_EVENT_DISP1_DISP_WDMA2_SW_RST_DONE_ENG_EVENT			125
+#define CMDQ_EVENT_DISP1_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT			126
+#define CMDQ_EVENT_DISP1_DISP_WDMA1_SW_RST_DONE_ENG_EVENT			127
+#define CMDQ_EVENT_DISP1_DISP_MUTEX0_TIMEOUT_ENG_EVENT				128
+#define CMDQ_EVENT_DISP1_DISP_MUTEX0_GET_RLZ_ENG_EVENT				129
+#define CMDQ_EVENT_DISP1_DISP_MDP_RDMA1_SW_RST_DONE_ENG_EVENT			130
+#define CMDQ_EVENT_DISP1_DISP_GDMA0_SW_RST_DONE_ENG_EVENT			131
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VSYNC_START_ENG_EVENT		132
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VSYNC_END_ENG_EVENT		133
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VRR_VFP_LAST_SAFE_BLANK_ENG_EVENT	134
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VFP_START_ENG_EVENT		135
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VFP_LAST_LINE_ENG_EVENT		136
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_VDE_END_ENG_EVENT			137
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TRIGGER_LOOP_CLR_ENG_EVENT	138
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TARGET_LINE1_ENG_EVENT		139
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_INT_TG_TARGET_LINE0_ENG_EVENT		140
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VSYNC_START_ENG_EVENT		141
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VSYNC_END_ENG_EVENT		142
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VDE_START_ENG_EVENT		143
+#define CMDQ_EVENT_DISP1_DISP_DVO0_DVO_EXT_TG_VDE_END_ENG_EVENT			144
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT0					145
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT1					146
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT2					147
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT3					148
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT4					149
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT5					150
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT6					151
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT7					152
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT8					153
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT9					154
+#define CMDQ_EVENT_DISP1_DISP_DSI2_ENG_EVENT10					155
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT0					156
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT1					157
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT2					158
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT3					159
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT4					160
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT5					161
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT6					162
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT7					163
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT8					164
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT9					165
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT10					166
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT11					167
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT12					168
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT13					169
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT14					170
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT15					171
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT16					172
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT17					173
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT18					174
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT19					175
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT20					176
+#define CMDQ_EVENT_DISP1_DISP_DSI1_ENG_EVENT21					177
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT0					178
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT1					179
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT2					180
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT3					181
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT4					182
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT5					183
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT6					184
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT7					185
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT8					186
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT9					187
+#define CMDQ_EVENT_DISP1_DISP_DSI0_ENG_EVENT10					188
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VSYNC_START_ENG_EVENT			189
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VSYNC_END_ENG_EVENT			190
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VDE_START_ENG_EVENT			191
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_VDE_END_ENG_EVENT			192
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF1_TARGET_LINE_ENG_EVENT			193
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VSYNC_START_ENG_EVENT			194
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VSYNC_END_ENG_EVENT			195
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VDE_START_ENG_EVENT			196
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_VDE_END_ENG_EVENT			197
+#define CMDQ_EVENT_DISP1_DISP_DP_INTF0_TARGET_LINE_ENG_EVENT			198
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT0				199
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT1				200
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT2				201
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT3				202
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT4				203
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT5				204
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT6				205
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT7				206
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT8				207
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT9				208
+#define CMDQ_EVENT_DISP1_BUF_UNDERRUN_ENG_EVENT10				209
+
+#define CMDQ_EVENT_MML0_STREAM_SOF0						210
+#define CMDQ_EVENT_MML0_STREAM_SOF1						211
+#define CMDQ_EVENT_MML0_STREAM_SOF2						212
+#define CMDQ_EVENT_MML0_STREAM_SOF3						213
+#define CMDQ_EVENT_MML0_STREAM_SOF4						214
+#define CMDQ_EVENT_MML0_STREAM_SOF5						215
+#define CMDQ_EVENT_MML0_STREAM_SOF6						216
+#define CMDQ_EVENT_MML0_STREAM_SOF7						217
+#define CMDQ_EVENT_MML0_STREAM_SOF8						218
+#define CMDQ_EVENT_MML0_STREAM_SOF9						219
+#define CMDQ_EVENT_MML0_STREAM_SOF10						220
+#define CMDQ_EVENT_MML0_STREAM_SOF11						221
+#define CMDQ_EVENT_MML0_STREAM_SOF12						222
+#define CMDQ_EVENT_MML0_STREAM_SOF13						223
+#define CMDQ_EVENT_MML0_STREAM_SOF14						224
+#define CMDQ_EVENT_MML0_STREAM_SOF15						225
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL0						226
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL1						227
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL2						228
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL3						229
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL4						230
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL5						231
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL6						232
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL7						233
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL8						234
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL9						235
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL10					236
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL11					237
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL12					238
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL13					239
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL14					240
+#define CMDQ_EVENT_MML0_FRAME_DONE_SEL15					241
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT0				242
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT1				243
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT2				244
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT3				245
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT4				246
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT5				247
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT6				248
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT7				249
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT8				250
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT9				251
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT10				252
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT11				253
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT12				254
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT13				255
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT14				256
+#define CMDQ_EVENT_MML0_REG_UPDATE_DONE_ENG_EVENT15				257
+#define CMDQ_EVENT_MML0_MDP_WROT2_SW_RST_DONE_ENG_EVENT				258
+#define CMDQ_EVENT_MML0_MDP_WROT1_SW_RST_DONE_ENG_EVENT				259
+#define CMDQ_EVENT_MML0_MDP_WROT0_SW_RST_DONE_ENG_EVENT				260
+#define CMDQ_EVENT_MML0_MDP_RROT0_SW_RST_DONE_ENG_EVENT				261
+#define CMDQ_EVENT_MML0_MDP_RDMA2_SW_RST_DONE_ENG_EVENT				262
+#define CMDQ_EVENT_MML0_MDP_RDMA1_SW_RST_DONE_ENG_EVENT				263
+#define CMDQ_EVENT_MML0_MDP_RDMA0_SW_RST_DONE_ENG_EVENT				264
+#define CMDQ_EVENT_MML0_MDP_MERGE0_SW_RST_DONE_ENG_EVENT			265
+#define CMDQ_EVENT_MML0_DISP_MUTEX0_TIMEOUT_ENG_EVENT				266
+#define CMDQ_EVENT_MML0_DISP_MUTEX0_GET_RLZ_ENG_EVENT				267
+
+#define CMDQ_EVENT_MML1_STREAM_SOF0						268
+#define CMDQ_EVENT_MML1_STREAM_SOF1						269
+#define CMDQ_EVENT_MML1_STREAM_SOF2						270
+#define CMDQ_EVENT_MML1_STREAM_SOF3						271
+#define CMDQ_EVENT_MML1_STREAM_SOF4						272
+#define CMDQ_EVENT_MML1_STREAM_SOF5						273
+#define CMDQ_EVENT_MML1_STREAM_SOF6						274
+#define CMDQ_EVENT_MML1_STREAM_SOF7						275
+#define CMDQ_EVENT_MML1_STREAM_SOF8						276
+#define CMDQ_EVENT_MML1_STREAM_SOF9						277
+#define CMDQ_EVENT_MML1_STREAM_SOF10						278
+#define CMDQ_EVENT_MML1_STREAM_SOF11						279
+#define CMDQ_EVENT_MML1_STREAM_SOF12						280
+#define CMDQ_EVENT_MML1_STREAM_SOF13						281
+#define CMDQ_EVENT_MML1_STREAM_SOF14						282
+#define CMDQ_EVENT_MML1_STREAM_SOF15						283
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL0						284
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL1						285
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL2						286
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL3						287
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL4						288
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL5						289
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL6						290
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL7						291
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL8						292
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL9						293
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL10					294
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL11					295
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL12					296
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL13					297
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL14					298
+#define CMDQ_EVENT_MML1_FRAME_DONE_SEL15					299
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT0				300
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT1				301
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT2				302
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT3				303
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT4				304
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT5				305
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT6				306
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT7				307
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT8				308
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT9				309
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT10				310
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT11				311
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT12				312
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT13				313
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT14				314
+#define CMDQ_EVENT_MML1_REG_UPDATE_DONE_ENG_EVENT15				315
+#define CMDQ_EVENT_MML1_MDP_WROT2_SW_RST_DONE_ENG_EVENT				316
+#define CMDQ_EVENT_MML1_MDP_WROT1_SW_RST_DONE_ENG_EVENT				317
+#define CMDQ_EVENT_MML1_MDP_WROT0_SW_RST_DONE_ENG_EVENT				318
+#define CMDQ_EVENT_MML1_MDP_RROT0_SW_RST_DONE_ENG_EVENT				319
+#define CMDQ_EVENT_MML1_MDP_RDMA2_SW_RST_DONE_ENG_EVENT				320
+#define CMDQ_EVENT_MML1_MDP_RDMA1_SW_RST_DONE_ENG_EVENT				321
+#define CMDQ_EVENT_MML1_MDP_RDMA0_SW_RST_DONE_ENG_EVENT				322
+#define CMDQ_EVENT_MML1_MDP_MERGE0_SW_RST_DONE_ENG_EVENT			323
+#define CMDQ_EVENT_MML1_DISP_MUTEX0_TIMEOUT_ENG_EVENT				324
+#define CMDQ_EVENT_MML1_DISP_MUTEX0_GET_RLZ_ENG_EVENT				325
+
+#define CMDQ_EVENT_OVL0_STREAM_SOF0						326
+#define CMDQ_EVENT_OVL0_STREAM_SOF1						327
+#define CMDQ_EVENT_OVL0_STREAM_SOF2						328
+#define CMDQ_EVENT_OVL0_STREAM_SOF3						329
+#define CMDQ_EVENT_OVL0_STREAM_SOF4						330
+#define CMDQ_EVENT_OVL0_STREAM_SOF5						331
+#define CMDQ_EVENT_OVL0_STREAM_SOF6						332
+#define CMDQ_EVENT_OVL0_STREAM_SOF7						333
+#define CMDQ_EVENT_OVL0_STREAM_SOF8						334
+#define CMDQ_EVENT_OVL0_STREAM_SOF9						335
+#define CMDQ_EVENT_OVL0_STREAM_SOF10						336
+#define CMDQ_EVENT_OVL0_STREAM_SOF11						337
+#define CMDQ_EVENT_OVL0_STREAM_SOF12						338
+#define CMDQ_EVENT_OVL0_STREAM_SOF13						339
+#define CMDQ_EVENT_OVL0_STREAM_SOF14						340
+#define CMDQ_EVENT_OVL0_STREAM_SOF15						341
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL0						342
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL1						343
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL2						344
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL3						345
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL4						346
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL5						347
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL6						348
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL7						349
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL8						350
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL9						351
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL10					352
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL11					353
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL12					354
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL13					355
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL14					356
+#define CMDQ_EVENT_OVL0_FRAME_DONE_SEL15					357
+#define CMDQ_EVENT_OVL0_OVL_UFBC_WDMA0_TARGET_LINE_END_ENG_EVENT		358
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_TIMEOUT_ENG_EVENT				359
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT0			360
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT1			361
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT2			362
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT3			363
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT4			364
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT5			365
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT6			366
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT7			367
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT8			368
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT9			369
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT10			370
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT11			371
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT12			372
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT13			373
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT14			374
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT15			375
+#define CMDQ_EVENT_OVL0_OVL_MUTEX0_GET_RELEASE_ENG_EVENT			376
+#define CMDQ_EVENT_OVL0_OVL_MDP_RDMA1_SW_RST_DONE_ENG_EVENT			377
+#define CMDQ_EVENT_OVL0_OVL_MDP_RDMA0_SW_RST_DONE_ENG_EVENT			378
+#define CMDQ_EVENT_OVL0_OVL_EXDMA9_FRAME_RESET_DONE_ENG_EVENT			379
+#define CMDQ_EVENT_OVL0_OVL_EXDMA8_FRAME_RESET_DONE_ENG_EVENT			380
+#define CMDQ_EVENT_OVL0_OVL_EXDMA7_FRAME_RESET_DONE_ENG_EVENT			381
+#define CMDQ_EVENT_OVL0_OVL_EXDMA6_FRAME_RESET_DONE_ENG_EVENT			382
+#define CMDQ_EVENT_OVL0_OVL_EXDMA5_FRAME_RESET_DONE_ENG_EVENT			383
+#define CMDQ_EVENT_OVL0_OVL_EXDMA4_FRAME_RESET_DONE_ENG_EVENT			384
+#define CMDQ_EVENT_OVL0_OVL_EXDMA3_FRAME_RESET_DONE_ENG_EVENT			385
+#define CMDQ_EVENT_OVL0_OVL_EXDMA2_FRAME_RESET_DONE_ENG_EVENT			386
+#define CMDQ_EVENT_OVL0_OVL_EXDMA1_FRAME_RESET_DONE_ENG_EVENT			387
+#define CMDQ_EVENT_OVL0_OVL_EXDMA0_FRAME_RESET_DONE_ENG_EVENT			388
+#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT		389
+#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA1_SW_RST_DONE_END_ENG_EVENT		390
+#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT		391
+#define CMDQ_EVENT_OVL0_OVL_DISP_WDMA0_SW_RST_DONE_END_ENG_EVENT		392
+#define CMDQ_EVENT_OVL0_OVL_BWM0_FRAME_RESET_DONE_ENG_EVENT			393
+#define CMDQ_EVENT_OVL1_STREAM_SOF0						394
+#define CMDQ_EVENT_OVL1_STREAM_SOF1						395
+#define CMDQ_EVENT_OVL1_STREAM_SOF2						396
+#define CMDQ_EVENT_OVL1_STREAM_SOF3						397
+#define CMDQ_EVENT_OVL1_STREAM_SOF4						398
+#define CMDQ_EVENT_OVL1_STREAM_SOF5						399
+#define CMDQ_EVENT_OVL1_STREAM_SOF6						400
+#define CMDQ_EVENT_OVL1_STREAM_SOF7						401
+#define CMDQ_EVENT_OVL1_STREAM_SOF8						402
+#define CMDQ_EVENT_OVL1_STREAM_SOF9						403
+#define CMDQ_EVENT_OVL1_STREAM_SOF10						404
+#define CMDQ_EVENT_OVL1_STREAM_SOF11						405
+#define CMDQ_EVENT_OVL1_STREAM_SOF12						406
+#define CMDQ_EVENT_OVL1_STREAM_SOF13						407
+#define CMDQ_EVENT_OVL1_STREAM_SOF14						408
+#define CMDQ_EVENT_OVL1_STREAM_SOF15						409
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL0						410
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL1						411
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL2						412
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL3						413
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL4						414
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL5						415
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL6						416
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL7						417
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL8						418
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL9						419
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL10					420
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL11					421
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL12					422
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL13					423
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL14					424
+#define CMDQ_EVENT_OVL1_FRAME_DONE_SEL15					425
+#define CMDQ_EVENT_OVL1_OVL_UFBC_WDMA0_TARGET_LINE_END_ENG_EVENT		426
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_TIMEOUT_ENG_EVENT				427
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT0			428
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT1			429
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT2			430
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT3			431
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT4			432
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT5			433
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT6			434
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT7			435
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT8			436
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT9			437
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT10			438
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT11			439
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT12			440
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT13			441
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT14			442
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_REG_UPDATE_DONE_ENG_EVENT15			443
+#define CMDQ_EVENT_OVL1_OVL_MUTEX0_GET_RELEASE_ENG_EVENT			444
+#define CMDQ_EVENT_OVL1_OVL_MDP_RDMA1_SW_RST_DONE_ENG_EVENT			445
+#define CMDQ_EVENT_OVL1_OVL_MDP_RDMA0_SW_RST_DONE_ENG_EVENT			446
+#define CMDQ_EVENT_OVL1_OVL_EXDMA9_FRAME_RESET_DONE_ENG_EVENT			447
+#define CMDQ_EVENT_OVL1_OVL_EXDMA8_FRAME_RESET_DONE_ENG_EVENT			448
+#define CMDQ_EVENT_OVL1_OVL_EXDMA7_FRAME_RESET_DONE_ENG_EVENT			449
+#define CMDQ_EVENT_OVL1_OVL_EXDMA6_FRAME_RESET_DONE_ENG_EVENT			450
+#define CMDQ_EVENT_OVL1_OVL_EXDMA5_FRAME_RESET_DONE_ENG_EVENT			451
+#define CMDQ_EVENT_OVL1_OVL_EXDMA4_FRAME_RESET_DONE_ENG_EVENT			452
+#define CMDQ_EVENT_OVL1_OVL_EXDMA3_FRAME_RESET_DONE_ENG_EVENT			453
+#define CMDQ_EVENT_OVL1_OVL_EXDMA2_FRAME_RESET_DONE_ENG_EVENT			454
+#define CMDQ_EVENT_OVL1_OVL_EXDMA1_FRAME_RESET_DONE_ENG_EVENT			455
+#define CMDQ_EVENT_OVL1_OVL_EXDMA0_FRAME_RESET_DONE_ENG_EVENT			456
+#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA1_TARGET_LINE_END_ENG_EVENT		457
+#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA1_SW_RST_DONE_END_ENG_EVENT		458
+#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA0_TARGET_LINE_END_ENG_EVENT		459
+#define CMDQ_EVENT_OVL1_OVL_DISP_WDMA0_SW_RST_DONE_END_ENG_EVENT		460
+#define CMDQ_EVENT_OVL1_OVL_BWM0_FRAME_RESET_DONE_ENG_EVENT			461
+
+#define CMDQ_EVENT_DPC_DT_DONE0							462
+#define CMDQ_EVENT_DPC_DT_DONE1							463
+#define CMDQ_EVENT_DPC_DT_DONE2_0_MERGE						464
+#define CMDQ_EVENT_DPC_DT_DONE2_1_MERGE						465
+#define CMDQ_EVENT_DPC_DT_DONE2_2_MERGE						466
+#define CMDQ_EVENT_DPC_DT_DONE2_3_MERGE						467
+#define CMDQ_EVENT_DPC_DT_DONE3							468
+#define CMDQ_EVENT_DPC_DT_DONE4_MERGE						469
+#define CMDQ_EVENT_DPC_DT_DONE5							470
+#define CMDQ_EVENT_DPC_DT_DONE6_0_MERGE						471
+#define CMDQ_EVENT_DPC_DT_DONE6_1_MERGE						472
+#define CMDQ_EVENT_DPC_DT_DONE6_2_MERGE						473
+#define CMDQ_EVENT_DPC_DT_DONE6_3_MERGE						474
+#define CMDQ_EVENT_DPC_DT_DONE7							475
+#define CMDQ_EVENT_DPC_DT_DONE32_MERGE						476
+#define CMDQ_EVENT_DPC_DT_DONE33						477
+#define CMDQ_EVENT_DPC_DT_DONE34_0						478
+#define CMDQ_EVENT_DPC_DT_DONE35						479
+#define CMDQ_EVENT_DPC_DISP_SSYS_DT_ERR_ON_BEFORE_OFF				480
+#define CMDQ_EVENT_DPC_DISP_SSYS_DT_ERR_PRETE_BEFORE_ON				481
+#define CMDQ_EVENT_DPC_DISP_DVFS_DT_ERR_ON_BEFORE_OFF				482
+#define CMDQ_EVENT_DPC_DISP_DVFS_DT_ERR_PRETE_BEFORE_ON				483
+#define CMDQ_EVENT_DPC_DISP_SB_DT_ERR_ON_BEFORE_OFF				484
+#define CMDQ_EVENT_DPC_DISP_SB_DT_ERR_PRETE_BEFORE_ON				485
+#define CMDQ_EVENT_DPC_DISP_SW_CONFIG_WHEN_MTCMOS_OFF				486
+#define CMDQ_EVENT_DPC_MML_SSYS_DT_ERR_ON_BEFORE_OFF				487
+#define CMDQ_EVENT_DPC_MML_SSYS_DT_ERR_PRETE_BEFORE_ON				488
+#define CMDQ_EVENT_DPC_MML_DVFS_DT_ERR_ON_BEFORE_OFF				489
+#define CMDQ_EVENT_DPC_MML_DVFS_DT_ERR_PRETE_BEFORE_ON				490
+#define CMDQ_EVENT_DPC_MML_SB_DT_ERR_ON_BEFORE_OFF				491
+#define CMDQ_EVENT_DPC_MML_SB_DT_ERR_PRETE_BEFORE_ON				492
+#define CMDQ_EVENT_DPC_MML_SW_CONFIG_WHEN_MTCMOS_OFF				493
+#define CMDQ_EVENT_DPTX_DPTX_EVENT0						494
+#define CMDQ_EVENT_DPTX_DPTX_EVENT1						495
+#define CMDQ_EVENT_DPTX_DPTX_EVENT2						496
+#define CMDQ_EVENT_DPTX_DPTX_EVENT3						497
+#define CMDQ_EVENT_EDPTX_EDPTX_EVENT0						498
+#define CMDQ_EVENT_EDPTX_EDPTX_EVENT1						499
+
+#define CMDQ_EVENT_DSI0_TE_I_DSI0_TE_I						898
+#define CMDQ_EVENT_DSI1_TE_I_DSI1_TE_I						899
+#define CMDQ_EVENT_DSI2_TE_I_DSI2_TE_I						900
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_0			901
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_1			902
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_2			903
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_3			904
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_4			905
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_5			906
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_6			907
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_7			908
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_8			909
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_9			910
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_10			911
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_11			912
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_12			913
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_13			914
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_14			915
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_15			916
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_16			917
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_17			918
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_18			919
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_19			920
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_20			921
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_21			922
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_22			923
+#define CMDQ_EVENT_POWEREVENT_GCE_EVENT_SUBSYS_PWR_ACK_23			924
+#define CMDQ_EVENT_GCE_EVENT_DPTX_GCE_EVENT_DPTX_0				925
+#define CMDQ_EVENT_GCE_EVENT_DPTX_GCE_EVENT_DPTX_1				926
+#define CMDQ_EVENT_GCE_EVENT_DPTX_P1_GCE_EVENT_DPTX_P1_0			927
+#define CMDQ_EVENT_GCE_EVENT_DPTX_P1_GCE_EVENT_DPTX_P1_1			928
+#define CMDQ_EVENT_GCE_EVENT_EDPTX_GCE_EVENT_EDPTX_0				929
+#define CMDQ_EVENT_GCE_EVENT_EDPTX_GCE_EVENT_EDPTX_1				930
+#define CMDQ_EVENT_DSI3_TE_I_DSI3_TE_I						931
+#define CMDQ_EVENT_SPI0_FINISH_EVENT_DSI4_TE_I					932
+#define CMDQ_EVENT_SPI0_EVENT_EVENT_DSI5_TE_I					933
+
+/* GCE-M hardware events */
+#define CMDQ_EVENT_VENC3_VENC_RESERVED						0
+#define CMDQ_EVENT_VENC3_VENC_FRAME_DONE					1
+#define CMDQ_EVENT_VENC3_VENC_PAUSE_DONE					2
+#define CMDQ_EVENT_VENC3_JPGENC_DONE						3
+#define CMDQ_EVENT_VENC3_VENC_MB_DONE						4
+#define CMDQ_EVENT_VENC3_VENC_128BYTE_DONE					5
+#define CMDQ_EVENT_VENC3_JPGDEC_DONE						6
+#define CMDQ_EVENT_VENC3_JPGDEC_C1_DONE						7
+#define CMDQ_EVENT_VENC3_JPGDEC_INSUFF_DONE					8
+#define CMDQ_EVENT_VENC3_JPGDEC_C1_INSUFF_DONE					9
+#define CMDQ_EVENT_VENC3_WP_2ND_STAGE_DONE					10
+#define CMDQ_EVENT_VENC3_WP_3RD_STAGE_DONE					11
+#define CMDQ_EVENT_VENC3_PPS_HEADER_DONE					12
+#define CMDQ_EVENT_VENC3_SPS_HEADER_DONE					13
+#define CMDQ_EVENT_VENC3_VPS_HEADER_DONE					14
+#define CMDQ_EVENT_VENC3_VENC_SLICE_DONE					15
+#define CMDQ_EVENT_VENC3_VENC_SOC_SLICE_DONE					16
+#define CMDQ_EVENT_VENC3_VENC_SOC_FRAME_DONE					17
+
+#define CMDQ_EVENT_VENC2_VENC_FRAME_DONE					33
+#define CMDQ_EVENT_VENC2_VENC_PAUSE_DONE					34
+#define CMDQ_EVENT_VENC2_JPGENC_DONE						35
+#define CMDQ_EVENT_VENC2_VENC_MB_DONE						36
+#define CMDQ_EVENT_VENC2_VENC_128BYTE_DONE					37
+#define CMDQ_EVENT_VENC2_JPGDEC_DONE						38
+#define CMDQ_EVENT_VENC2_JPGDEC_C1_DONE						39
+#define CMDQ_EVENT_VENC2_JPGDEC_INSUFF_DONE					40
+#define CMDQ_EVENT_VENC2_JPGDEC_C1_INSUFF_DONE					41
+#define CMDQ_EVENT_VENC2_WP_2ND_STAGE_DONE					42
+#define CMDQ_EVENT_VENC2_WP_3RD_STAGE_DONE					43
+#define CMDQ_EVENT_VENC2_PPS_HEADER_DONE					44
+#define CMDQ_EVENT_VENC2_SPS_HEADER_DONE					45
+#define CMDQ_EVENT_VENC2_VPS_HEADER_DONE					46
+#define CMDQ_EVENT_VENC2_VENC_SLICE_DONE					47
+#define CMDQ_EVENT_VENC2_VENC_SOC_SLICE_DONE					48
+#define CMDQ_EVENT_VENC2_VENC_SOC_FRAME_DONE					49
+
+#define CMDQ_EVENT_VENC1_VENC_FRAME_DONE					65
+#define CMDQ_EVENT_VENC1_VENC_PAUSE_DONE					66
+#define CMDQ_EVENT_VENC1_JPGENC_DONE						67
+#define CMDQ_EVENT_VENC1_VENC_MB_DONE						68
+#define CMDQ_EVENT_VENC1_VENC_128BYTE_DONE					69
+#define CMDQ_EVENT_VENC1_JPGDEC_DONE						70
+#define CMDQ_EVENT_VENC1_JPGDEC_C1_DONE						71
+#define CMDQ_EVENT_VENC1_JPGDEC_INSUFF_DONE					72
+#define CMDQ_EVENT_VENC1_JPGDEC_C1_INSUFF_DONE					73
+#define CMDQ_EVENT_VENC1_WP_2ND_STAGE_DONE					74
+#define CMDQ_EVENT_VENC1_WP_3RD_STAGE_DONE					75
+#define CMDQ_EVENT_VENC1_PPS_HEADER_DONE					76
+#define CMDQ_EVENT_VENC1_SPS_HEADER_DONE					77
+#define CMDQ_EVENT_VENC1_VPS_HEADER_DONE					78
+#define CMDQ_EVENT_VENC1_VENC_SLICE_DONE					79
+#define CMDQ_EVENT_VENC1_VENC_SOC_SLICE_DONE					80
+#define CMDQ_EVENT_VENC1_VENC_SOC_FRAME_DONE					81
+
+#define CMDQ_EVENT_VDEC1_VDEC_LINE_CNT_INT					192
+#define CMDQ_EVENT_VDEC1_VDEC_INT						193
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_2						194
+#define CMDQ_EVENT_VDEC1_VDEC_DEC_ERR						195
+#define CMDQ_EVENT_VDEC1_VDEC_BUSY_OVERFLOW					196
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_5						197
+#define CMDQ_EVENT_VDEC1_VDEC_INI_FETCH_RDY					198
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_7						199
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_8						200
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_9						201
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_10						202
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_11						203
+
+#define CMDQ_EVENT_VDEC1_VDEC_GCE_CNT_OP_THR					207
+
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_32						224
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_INT						225
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_34						226
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_DEC_ERR					227
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_BUSY_OVERFLOW					228
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_37						229
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_INI_FETCH_RDY					230
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_39						231
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_40						232
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_41						233
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_42						234
+#define CMDQ_EVENT_VDEC1_VDEC1_EVENT_43						235
+
+#define CMDQ_EVENT_VDEC1_VDEC_LAT_GCE_CNT_OP_THR				239
+
+#define CMDQ_EVENT_IMG_IMG_EVENT_0						256
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_0				257
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_1				258
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_2				259
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_3				260
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_4				261
+#define CMDQ_EVENT_IMG_TRAW0_CQ_THR_DONE_TRAW0_5				262
+#define CMDQ_EVENT_IMG_TRAW0_DMA_ERR_EVENT					263
+#define CMDQ_EVENT_IMG_TRAW0_DUMMY_0						264
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_0				265
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_1				266
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_2				267
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_3				268
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_4				269
+#define CMDQ_EVENT_IMG_TRAW1_CQ_THR_DONE_TRAW0_5				270
+#define CMDQ_EVENT_IMG_TRAW1_DMA_ERR_EVENT					271
+#define CMDQ_EVENT_IMG_ADL_TILE_DONE_EVENT					272
+#define CMDQ_EVENT_IMG_ADLWR0_TILE_DONE_EVENT					273
+#define CMDQ_EVENT_IMG_ADLWR1_TILE_DONE_EVENT					274
+#define CMDQ_EVENT_IMG_IMGSYS_IPE_ME_DONE					275
+#define CMDQ_EVENT_IMG_IMGSYS_IPE_MMG_DONE					276
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_0						277
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_1						278
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_2						279
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_3						280
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_4						281
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_5						282
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_6						283
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_7						284
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_8						285
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_9						286
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_10						287
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_11						288
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_12						289
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_13						290
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_14						291
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_15						292
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_16						293
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_17						294
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_18						295
+#define CMDQ_EVENT_IMG_QOF_ACK_EVENT_19						296
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_0						297
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_1						298
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_2						299
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_3						300
+#define CMDQ_EVENT_IMG_QOF_ON_EVENT_4						301
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_0						302
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_1						303
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_2						304
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_3						305
+#define CMDQ_EVENT_IMG_QOF_OFF_EVENT_4						306
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_0						307
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_1						308
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_2						309
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_3						310
+#define CMDQ_EVENT_IMG_QOF_SAVE_EVENT_4						311
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_0					312
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_1					313
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_2					314
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_3					315
+#define CMDQ_EVENT_IMG_QOF_RESTORE_EVENT_4					316
+
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_0					317
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_1					318
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_2					319
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_3					320
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_4					321
+#define CMDQ_EVENT_IMG_DIP_CQ_THR_DONE_P2_5					322
+#define CMDQ_EVENT_IMG_DIP_DMA_ERR_EVENT					323
+#define CMDQ_EVENT_IMG_DIP_NR_DMA_ERR_EVENT					324
+#define CMDQ_EVENT_IMG_DIP_DUMMY_0						325
+
+#define CMDQ_EVENT_IMG_WPE_EIS_GCE_FRAME_DONE					326
+#define CMDQ_EVENT_IMG_WPE_EIS_DONE_SYNC_OUT					327
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_0					328
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_1					329
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_2					330
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_3					331
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_4					332
+#define CMDQ_EVENT_IMG_WPE_EIS_CQ_THR_DONE_P2_5					333
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_0					334
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_1					335
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_2					336
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_3					337
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_4					338
+#define CMDQ_EVENT_IMG_PQDIP_A_CQ_THR_DONE_P2_5					339
+#define CMDQ_EVENT_IMG_PQA_DMA_ERR_EVENT					340
+#define CMDQ_EVENT_IMG_WPE0_DUMMY_0						341
+#define CMDQ_EVENT_IMG_WPE0_DUMMY_1						342
+#define CMDQ_EVENT_IMG_WPE0_DUMMY_2						343
+#define CMDQ_EVENT_IMG_OMC_TNR_GCE_FRAME_DONE					344
+#define CMDQ_EVENT_IMG_OMC_TNR_DONE_SYNC_OUT					345
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_0					346
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_1					347
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_2					348
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_3					349
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_4					350
+#define CMDQ_EVENT_IMG_OMC_TNR_CQ_THR_DONE_P2_5					351
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_0					352
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_1					353
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_2					354
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_3					355
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_4					356
+#define CMDQ_EVENT_IMG_PQDIP_B_CQ_THR_DONE_P2_5					357
+#define CMDQ_EVENT_IMG_PQB_DMA_ERR_EVENT					358
+#define CMDQ_EVENT_IMG_WPE1_DUMMY_0						359
+#define CMDQ_EVENT_IMG_WPE1_DUMMY_1						360
+#define CMDQ_EVENT_IMG_WPE1_DUMMY_2						361
+#define CMDQ_EVENT_IMG_WPE_LITE_GCE_FRAME_DONE					362
+#define CMDQ_EVENT_IMG_WPE_LITE_DONE_SYNC_OUT					363
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_0				364
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_1				365
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_2				366
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_3				367
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_4				368
+#define CMDQ_EVENT_IMG_WPE_LITE_CQ_THR_DONE_P2_5				369
+#define CMDQ_EVENT_IMG_OMC_LITE_GCE_FRAME_DONE					370
+#define CMDQ_EVENT_IMG_OMC_LITE_DONE_SYNC_OUT					371
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_0				372
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_1				373
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_2				374
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_3				375
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_4				376
+#define CMDQ_EVENT_IMG_OMC_LITE_CQ_THR_DONE_P2_5				377
+#define CMDQ_EVENT_IMG_WPE2_DUMMY_0						378
+#define CMDQ_EVENT_IMG_WPE2_DUMMY_1						379
+#define CMDQ_EVENT_IMG_WPE2_DUMMY_2						380
+#define CMDQ_EVENT_IMG_IMGSYS_IPE_FDVT0_DONE					381
+#define CMDQ_EVENT_IMG_IMG_EVENT_126						382
+#define CMDQ_EVENT_IMG_IMG_EVENT_127						383
+
+#define CMDQ_EVENT_CAM_CAM_EVENT_0						384
+#define CMDQ_EVENT_CAM_CAM_SUBA_SW_PASS1_DONE					385
+#define CMDQ_EVENT_CAM_CAM_SUBB_SW_PASS1_DONE					386
+#define CMDQ_EVENT_CAM_CAM_SUBC_SW_PASS1_DONE					387
+#define CMDQ_EVENT_CAM_CAM_SUBA_TFMR_PASS1_DONE					388
+#define CMDQ_EVENT_CAM_CAM_SUBB_TFMR_PASS1_DONE					389
+#define CMDQ_EVENT_CAM_CAM_SUBC_TFMR_PASS1_DONE					390
+#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_0					391
+#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_1					392
+#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_2					393
+#define CMDQ_EVENT_CAM_CAMSV_A_SW_PASS1_DONE_3					394
+#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_0					395
+#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_1					396
+#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_2					397
+#define CMDQ_EVENT_CAM_CAMSV_B_SW_PASS1_DONE_3					398
+#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_0					399
+#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_1					400
+#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_2					401
+#define CMDQ_EVENT_CAM_CAMSV_C_SW_PASS1_DONE_3					402
+#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_0					403
+#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_1					404
+#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_2					405
+#define CMDQ_EVENT_CAM_CAMSV_D_SW_PASS1_DONE_3					406
+#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_0					407
+#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_1					408
+#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_2					409
+#define CMDQ_EVENT_CAM_CAMSV_E_SW_PASS1_DONE_3					410
+#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_0					411
+#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_1					412
+#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_2					413
+#define CMDQ_EVENT_CAM_CAMSV_F_SW_PASS1_DONE_3					414
+#define CMDQ_EVENT_CAM_MRAW0_SW_PASS1_DONE					415
+#define CMDQ_EVENT_CAM_MRAW1_SW_PASS1_DONE					416
+#define CMDQ_EVENT_CAM_MRAW2_SW_PASS1_DONE					417
+#define CMDQ_EVENT_CAM_MRAW3_SW_PASS1_DONE					418
+#define CMDQ_EVENT_CAM_UISP_SW_PASS1_DONE					419
+#define CMDQ_EVENT_CAM_TG_MRAW0_OUT_SOF						420
+#define CMDQ_EVENT_CAM_TG_MRAW1_OUT_SOF						421
+#define CMDQ_EVENT_CAM_TG_MRAW2_OUT_SOF						422
+#define CMDQ_EVENT_CAM_TG_MRAW3_OUT_SOF						423
+#define CMDQ_EVENT_CAM_PDA0_IRQO_EVENT_DONE_D1					424
+#define CMDQ_EVENT_CAM_PDA1_IRQO_EVENT_DONE_D1					425
+
+#define CMDQ_EVENT_CAM_DPE_DVP_CMQ_EVENT					426
+#define CMDQ_EVENT_CAM_DPE_DVS_CMQ_EVENT					427
+#define CMDQ_EVENT_CAM_DPE_DVFG_CMQ_EVENT					428
+#define CMDQ_EVENT_CAM_CAM_EVENT_45						429
+#define CMDQ_EVENT_CAM_CAM_EVENT_46						430
+#define CMDQ_EVENT_CAM_CAM_EVENT_47						431
+#define CMDQ_EVENT_CAM_CAM_EVENT_48						432
+#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT1						433
+#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT2						434
+#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT3						435
+#define CMDQ_EVENT_CAM_CAM_SUBA_TG_INT4						436
+#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT1						437
+#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT2						438
+#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT3						439
+#define CMDQ_EVENT_CAM_CAM_SUBB_TG_INT4						440
+#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT1						441
+#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT2						442
+#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT3						443
+#define CMDQ_EVENT_CAM_CAM_SUBC_TG_INT4						444
+#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBA						445
+#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBB						446
+#define CMDQ_EVENT_CAM_RAW_O_SOF_SUBC						447
+#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBA					448
+#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBB					449
+#define CMDQ_EVENT_CAM_TFMR_RAW_O_SOF_SUBC					450
+#define CMDQ_EVENT_CAM_RAW_SEL_SOF_UISP						451
+#define CMDQ_EVENT_CAM_CAM_SUBA_RING_BUFFER_OVERFLOW_INT_IN			452
+#define CMDQ_EVENT_CAM_CAM_SUBB_RING_BUFFER_OVERFLOW_INT_IN			453
+#define CMDQ_EVENT_CAM_CAM_SUBC_RING_BUFFER_OVERFLOW_INT_IN			454
+#define CMDQ_EVENT_CAM_CAM_EVENT_71						455
+#define CMDQ_EVENT_CAM_ADL_WR_FRAME_DONE					456
+#define CMDQ_EVENT_CAM_ADL_RD_FRAME_DONE					457
+#define CMDQ_EVENT_CAM_QOF_RAWA_POWER_ON_EVENT					458
+#define CMDQ_EVENT_CAM_QOF_RAWB_POWER_ON_EVENT					459
+#define CMDQ_EVENT_CAM_QOF_RAWC_POWER_ON_EVENT					460
+#define CMDQ_EVENT_CAM_QOF_RAWA_POWER_OFF_EVENT					461
+#define CMDQ_EVENT_CAM_QOF_RAWB_POWER_OFF_EVENT					462
+#define CMDQ_EVENT_CAM_QOF_RAWC_POWER_OFF_EVENT					463
+#define CMDQ_EVENT_CAM_QOF_RAWA_SAVE_EVENT					464
+#define CMDQ_EVENT_CAM_QOF_RAWB_SAVE_EVENT					465
+#define CMDQ_EVENT_CAM_QOF_RAWC_SAVE_EVENT					466
+#define CMDQ_EVENT_CAM_QOF_RAWA_RESTORE_EVENT					467
+#define CMDQ_EVENT_CAM_QOF_RAWB_RESTORE_EVENT					468
+#define CMDQ_EVENT_CAM_QOF_RAWC_RESTORE_EVENT					469
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_0						470
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_1						471
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_2						472
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_3						473
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_4						474
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_5						475
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_6						476
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_7						477
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_8						478
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_9						479
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_10						480
+#define CMDQ_EVENT_CAM_QOF_CAM_EVENT_11						481
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_0					482
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_1					483
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_2					484
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_3					485
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_4					486
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_5					487
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_6					488
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_7					489
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_8					490
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_9					491
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_10					492
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_11					493
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_12					494
+#define CMDQ_EVENT_CAM_SENINF_CFG_DONE_EVENT_13					495
+#define CMDQ_EVENT_CAM_CCU0_TO_GCE_NON_SEC_IRQ					496
+#define CMDQ_EVENT_CAM_CCU0_TO_GCE_SEC_IRQ					497
+#define CMDQ_EVENT_CAM_CCU0_TO_GCE_VM_IRQ					498
+#define CMDQ_EVENT_CAM_CCU0_TO_GCE_EXCH_VM_IRQ					499
+#define CMDQ_EVENT_CAM_CCU1_TO_GCE_NON_SEC_IRQ					500
+#define CMDQ_EVENT_CAM_CCU1_TO_GCE_SEC_IRQ					501
+#define CMDQ_EVENT_CAM_CCU1_TO_GCE_VM_IRQ					502
+#define CMDQ_EVENT_CAM_CCU1_TO_GCE_EXCH_VM_IRQ					503
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_0						504
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_1						505
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_2						506
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_3						507
+#define CMDQ_EVENT_CAM_I2C_CH2_EVENT_4						508
+#define CMDQ_EVENT_CAM_CAM_EVENT_125						509
+#define CMDQ_EVENT_CAM_CAM_EVENT_126						510
+#define CMDQ_EVENT_CAM_CAM_EVENT_127						511
+
+#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_MMSRAM_COMM_SMIASSER			898
+#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_MDP_COMM_SMIASSER			899
+#define CMDQ_EVENT_SMI_EVENT_MMINFRA_SMI_DISP_COMM_SMIASSER			900
+
+#define CMDQ_MAX_HW_EVENT							512
+/* End of hardware event and begin of software token */
+
+/*
+ * CMDQ software tokens:
+ * The following are GCE software tokens, which can be used by clients
+ * event to operate API.
+ */
+
+/* Begin of GCE-D software token */
+/* MML software tokens */
+#define CMDQ_SYNC_TOKEN_MML_BUFA			630
+#define CMDQ_SYNC_TOKEN_MML_BUFB			631
+#define CMDQ_SYNC_TOKEN_MML_BUF_NEXT			632
+#define CMDQ_SYNC_TOKEN_MML_IR_MML_READY		633
+#define CMDQ_SYNC_TOKEN_MML_IR_DISP_READY		634
+#define CMDQ_SYNC_TOKEN_MML_MML_STOP			635
+#define CMDQ_SYNC_TOKEN_MML_PIPE0			636
+#define CMDQ_SYNC_TOKEN_MML_PIPE1			637
+#define CMDQ_SYNC_TOKEN_MML_PIPE1_NEXT			638
+#define CMDQ_SYNC_TOKEN_MML_APU_START			639
+
+/* Config thread notify trigger thread */
+#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY			640
+/* Trigger thread notify config thread */
+#define CMDQ_SYNC_TOKEN_STREAM_EOF			641
+/* Block Trigger thread until the ESD check finishes */
+#define CMDQ_SYNC_TOKEN_ESD_EOF				642
+#define CMDQ_SYNC_TOKEN_STREAM_BLOCK			643
+/* Check CABC setup finish */
+#define CMDQ_SYNC_TOKEN_CABC_EOF			644
+
+/* VFP period token for Msync */
+#define CMDQ_SYNC_TOKEN_VFP_PERIOD			645
+/* Software sync token for dual display */
+#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY_1			694
+#define CMDQ_SYNC_TOKEN_STREAM_EOF_1			695
+#define CMDQ_SYNC_TOKEN_ESD_EOF_1			696
+#define CMDQ_SYNC_TOKEN_STREAM_BLOCK_1			697
+#define CMDQ_SYNC_TOKEN_CABC_EOF_1			698
+
+/*
+ * GPR access tokens (for HW register backup)
+ * There are 15 32-bit GPR, form 3 GPR as a set
+ * (64-bit for address, 32-bit for value)
+ */
+#define CMDQ_SYNC_TOKEN_GPR_SET_0			700
+#define CMDQ_SYNC_TOKEN_GPR_SET_1			701
+#define CMDQ_SYNC_TOKEN_GPR_SET_2			702
+#define CMDQ_SYNC_TOKEN_GPR_SET_3			703
+#define CMDQ_SYNC_TOKEN_GPR_SET_4			704
+
+#define CMDQ_SYNC_TOKEN_TE_0				705
+#define CMDQ_SYNC_TOKEN_PREFETCH_TE_0			706
+#define CMDQ_SYNC_TOKEN_VIDLE_POWER_ON			707
+#define CMDQ_SYNC_TOKEN_CHECK_TRIGGER_MERGE		708
+
+/* Resource lock event to control resource in GCE thread */
+#define CMDQ_SYNC_RESOURCE_WROT0			710
+#define CMDQ_SYNC_RESOURCE_WROT1			711
+
+/* Hardware TRACE software token */
+#define CMDQ_SYNC_TOKEN_HW_TRACE_WAIT			712
+#define CMDQ_SYNC_TOKEN_HW_TRACE_LOCK			713
+
+/* Software sync token for dual display */
+#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY_3			714
+#define CMDQ_SYNC_TOKEN_STREAM_EOF_3			715
+#define CMDQ_SYNC_TOKEN_ESD_EOF_3			716
+#define CMDQ_SYNC_TOKEN_STREAM_BLOCK_3			717
+#define CMDQ_SYNC_TOKEN_CABC_EOF_3			718
+/* End of GCE-D software token */
+
+/* Begin of GCE-M software token */
+/* IMGSYS_POOL */
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_1			514
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_2			515
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_3			516
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_4			517
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_5			518
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_6			519
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_7			520
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_8			521
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_9			522
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_10			523
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_11			524
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_12			525
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_13			526
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_14			527
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_15			528
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_16			529
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_17			530
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_18			531
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_19			532
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_20			533
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_21			534
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_22			535
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_23			536
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_24			537
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_25			538
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_26			539
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_27			540
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_28			541
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_29			542
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_30			543
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_31			544
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_32			545
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_33			546
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_34			547
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_35			548
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_36			549
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_37			550
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_38			551
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_39			552
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_40			553
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_41			554
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_42			555
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_43			556
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_44			557
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_45			558
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_46			559
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_47			560
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_48			561
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_49			562
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_50			563
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_51			564
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_52			565
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_53			566
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_54			567
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_55			568
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_56			569
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_57			570
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_58			571
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_59			572
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_60			573
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_61			574
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_62			575
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_63			576
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_64			577
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_65			578
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_66			579
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_67			580
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_68			581
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_69			582
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_70			583
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_71			584
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_72			585
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_73			586
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_74			587
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_75			588
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_76			589
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_77			590
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_78			591
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_79			592
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_80			593
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_81			594
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_82			595
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_83			596
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_84			597
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_85			598
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_86			599
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_87			600
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_88			601
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_89			602
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_90			603
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_91			604
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_92			605
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_93			606
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_94			607
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_95			608
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_96			609
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_97			610
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_98			611
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_99			612
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_100			613
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_101			614
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_102			615
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_103			616
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_104			617
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_105			618
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_106			619
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_107			620
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_108			621
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_109			622
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_110			623
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_111			624
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_112			625
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_113			626
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_114			627
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_115			628
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_116			629
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_117			630
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_118			631
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_119			632
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_120			633
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_121			634
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_122			635
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_123			636
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_124			637
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_125			638
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_126			639
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_127			640
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_128			641
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_129			642
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_130			643
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_131			644
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_132			645
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_133			646
+
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_134			694
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_135			695
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_136			696
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_137			697
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_138			698
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_139			699
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_140			700
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_141			701
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_142			702
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_143			703
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_144			704
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_145			705
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_146			706
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_147			707
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_148			708
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_149			709
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_150			710
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_151			711
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_152			714
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_153			715
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_154			716
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_155			717
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_156			718
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_157			719
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_158			720
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_159			721
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_160			722
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_161			723
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_162			724
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_163			725
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_164			726
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_165			727
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_166			728
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_167			729
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_168			730
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_169			731
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_170			732
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_171			733
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_172			734
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_173			735
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_174			736
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_175			737
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_176			738
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_177			739
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_178			740
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_179			741
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_180			742
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_181			743
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_182			744
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_183			745
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_184			746
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_185			747
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_186			748
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_187			749
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_188			750
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_189			751
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_190			752
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_191			753
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_192			754
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_193			755
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_194			756
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_195			757
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_196			758
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_197			759
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_198			760
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_199			761
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_200			762
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_201			763
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_202			764
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_203			765
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_204			766
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_205			767
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_206			784
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_207			785
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_208			786
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_209			787
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_210			788
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_211			789
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_212			790
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_213			791
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_214			792
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_215			793
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_216			794
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_217			795
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_218			796
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_219			797
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_220			798
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_221			799
+
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_222			833
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_223			834
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_224			835
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_225			836
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_226			837
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_227			838
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_228			839
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_229			840
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_230			841
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_231			842
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_232			843
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_233			844
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_234			845
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_235			846
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_236			847
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_237			848
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_238			849
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_239			850
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_240			851
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_241			852
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_242			853
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_243			854
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_244			855
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_245			856
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_246			857
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_247			858
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_248			859
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_249			860
+#define	CMDQ_SYNC_TOKEN_IMGSYS_POOL_250			861
+
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_251			901
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_252			902
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_253			903
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_254			904
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_255			905
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_256			906
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_257			907
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_258			908
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_259			909
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_260			910
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_261			911
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_262			912
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_263			913
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_264			914
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_265			915
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_266			916
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_267			917
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_268			918
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_269			919
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_270			920
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_271			921
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_272			922
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_273			923
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_274			924
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_275			925
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_276			926
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_277			927
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_278			928
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_279			929
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_280			930
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_281			931
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_282			932
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_283			933
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_284			934
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_285			935
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_286			936
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_287			937
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_288			938
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_289			939
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_290			940
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_291			941
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_292			942
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_293			943
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_294			944
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_295			945
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_296			946
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_297			947
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_298			948
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_299			949
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_300			950
+
+/* ISP software token */
+#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_EIS			665
+#define CMDQ_SYNC_TOKEN_IMGSYS_OMC_TNR			666
+#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_LITE			667
+#define CMDQ_SYNC_TOKEN_IMGSYS_TRAW			668
+#define CMDQ_SYNC_TOKEN_IMGSYS_LTRAW			669
+#define CMDQ_SYNC_TOKEN_IMGSYS_XTRAW			670
+#define CMDQ_SYNC_TOKEN_IMGSYS_DIP			671
+#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_A			672
+#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_B			673
+#define CMDQ_SYNC_TOKEN_IPESYS_ME			674
+#define CMDQ_SYNC_TOKEN_APUSYS_APU			675
+#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_TRAW			676
+#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_LTRAW		677
+#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_XTRAW		678
+#define CMDQ_SYNC_TOKEN_IMGSYS_VSS_DIP			679
+#define CMDQ_SYNC_TOKEN_IMGSYS_OMC_LITE			680
+
+/* IMG software token for QoS */
+#define CMDQ_SYNC_TOKEN_IMGSYS_QOS_LOCK			800
+/* IMG software token for Qof */
+#define CMDQ_SYNC_TOKEN_DIP_POWER_CTRL			862
+#define CMDQ_SYNC_TOKEN_DIP_TRIG_PWR_ON			863
+#define CMDQ_SYNC_TOKEN_DIP_PWR_ON			864
+#define CMDQ_SYNC_TOKEN_DIP_TRIG_PWR_OFF		865
+#define CMDQ_SYNC_TOKEN_DIP_PWR_OFF			866
+#define CMDQ_SYNC_TOKEN_DIP_PWR_HAND_SHAKE		867
+
+#define CMDQ_SYNC_TOKEN_TRAW_POWER_CTRL			868
+#define CMDQ_SYNC_TOKEN_TRAW_TRIG_PWR_ON		869
+#define CMDQ_SYNC_TOKEN_TRAW_PWR_ON			870
+#define CMDQ_SYNC_TOKEN_TRAW_TRIG_PWR_OFF		871
+#define CMDQ_SYNC_TOKEN_TRAW_PWR_OFF			872
+#define CMDQ_SYNC_TOKEN_TRAW_PWR_HAND_SHAKE		873
+/* End of GCE-M software token */
+
+/* Begin of common software token */
+
+/*
+ * Notify normal CMDQ there are some secure task done
+ * MUST NOT CHANGE, this token sync with secure world
+ */
+#define CMDQ_SYNC_SECURE_THR_EOF			647
+
+/* CMDQ use software token */
+#define CMDQ_SYNC_TOKEN_USER_0				649
+#define CMDQ_SYNC_TOKEN_USER_1				650
+#define CMDQ_SYNC_TOKEN_POLL_MONITOR			651
+#define CMDQ_SYNC_TOKEN_TPR_LOCK			652
+
+/* TZMP software token */
+#define CMDQ_SYNC_TOKEN_TZMP_DISP_WAIT			653
+#define CMDQ_SYNC_TOKEN_TZMP_DISP_SET			654
+#define CMDQ_SYNC_TOKEN_TZMP_ISP_WAIT			655
+#define CMDQ_SYNC_TOKEN_TZMP_ISP_SET			656
+#define CMDQ_SYNC_TOKEN_TZMP_AIE_WAIT			657
+#define CMDQ_SYNC_TOKEN_TZMP_AIE_SET			658
+#define CMDQ_SYNC_TOKEN_TZMP_ADL_WAIT			659
+#define CMDQ_SYNC_TOKEN_TZMP_ADL_SET			660
+
+/* PREBUILT software token */
+#define CMDQ_SYNC_TOKEN_PREBUILT_MDP_LOCK		682
+#define CMDQ_SYNC_TOKEN_PREBUILT_MML_LOCK		685
+#define CMDQ_SYNC_TOKEN_PREBUILT_VFMT_LOCK		688
+#define CMDQ_SYNC_TOKEN_PREBUILT_DISP_LOCK		691
+#define CMDQ_SYNC_TOKEN_DISP_VA_START			692
+#define CMDQ_SYNC_TOKEN_DISP_VA_END			693
+
+/* Event for GPR timer, used in sleep and poll with timeout */
+#define CMDQ_TOKEN_GPR_TIMER_R0				994
+#define CMDQ_TOKEN_GPR_TIMER_R1				995
+#define CMDQ_TOKEN_GPR_TIMER_R2				996
+#define CMDQ_TOKEN_GPR_TIMER_R3				997
+#define CMDQ_TOKEN_GPR_TIMER_R4				998
+#define CMDQ_TOKEN_GPR_TIMER_R5				999
+#define CMDQ_TOKEN_GPR_TIMER_R6				1000
+#define CMDQ_TOKEN_GPR_TIMER_R7				1001
+#define CMDQ_TOKEN_GPR_TIMER_R8				1002
+#define CMDQ_TOKEN_GPR_TIMER_R9				1003
+#define CMDQ_TOKEN_GPR_TIMER_R10			1004
+#define CMDQ_TOKEN_GPR_TIMER_R11			1005
+#define CMDQ_TOKEN_GPR_TIMER_R12			1006
+#define CMDQ_TOKEN_GPR_TIMER_R13			1007
+#define CMDQ_TOKEN_GPR_TIMER_R14			1008
+#define CMDQ_TOKEN_GPR_TIMER_R15			1009
+/* End of common software token */
+/* CMDQ software tokens END */
+
+#endif
-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 19 09:07:57 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 01:07:57 +0800
Subject: [PATCH v3 4/7] soc: mediatek: mtk-cmdq: Add mminfra_offset compatibility for DRAM address
In-Reply-To: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
References: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219170800.2957-5-jason-jh.lin@mediatek.com>

Since GCE has been moved to mminfra in MT8196, all transactions from
mminfra to DRAM will have their addresses adjusted by subtracting a
mminfra offset.
This information should be handled inside the CMDQ driver, allowing
CMDQ users to call CMDQ APIs as usual.

Therefore, CMDQ driver needs to use the mbox API to get the
mminfra_offset value of the SoC, and then add it to the DRAM address
when generating instructions to ensure GCE accesses the correct DRAM
address.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 35 ++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index aa9853100d78..f2853a74af01 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -314,10 +314,22 @@ EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
 int cmdq_pkt_mem_move(struct cmdq_pkt *pkt, dma_addr_t src_addr, dma_addr_t dst_addr)
 {
+	struct cmdq_client *cl = (struct cmdq_client *)pkt->cl;
 	const u16 high_addr_reg_idx  = CMDQ_THR_SPR_IDX0;
 	const u16 value_reg_idx = CMDQ_THR_SPR_IDX1;
 	int ret;
 
+	if (!cl) {
+		pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	if (cmdq_addr_need_offset(cl->chan, src_addr))
+		src_addr += cmdq_get_offset_pa(cl->chan);
+
+	if (cmdq_addr_need_offset(cl->chan, dst_addr))
+		dst_addr += cmdq_get_offset_pa(cl->chan);
+
 	/* read the value of src_addr into high_addr_reg_idx */
 	ret = cmdq_pkt_assign(pkt, high_addr_reg_idx, CMDQ_ADDR_HIGH(src_addr));
 	if (ret < 0)
@@ -428,10 +440,19 @@ EXPORT_SYMBOL(cmdq_pkt_poll_mask);
 
 int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask)
 {
+	struct cmdq_client *cl = (struct cmdq_client *)pkt->cl;
 	struct cmdq_instruction inst = { {0} };
 	u8 use_mask = 0;
 	int ret;
 
+	if (!cl) {
+		pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	if (cmdq_addr_need_offset(cl->chan, addr))
+		addr += cmdq_get_offset_pa(cl->chan);
+
 	/*
 	 * Append an MASK instruction to set the mask for following POLL instruction
 	 * which enables use_mask bit.
@@ -509,11 +530,21 @@ EXPORT_SYMBOL(cmdq_pkt_assign);
 
 int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 {
+	struct cmdq_client *cl = (struct cmdq_client *)pkt->cl;
 	struct cmdq_instruction inst = {
 		.op = CMDQ_CODE_JUMP,
-		.offset = CMDQ_JUMP_ABSOLUTE,
-		.value = addr >> shift_pa
+		.offset = CMDQ_JUMP_ABSOLUTE
 	};
+
+	if (!cl) {
+		pr_err("%s %d: pkt->cl is NULL!\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	if (cmdq_addr_need_offset(cl->chan, addr))
+		addr += cmdq_get_offset_pa(cl->chan);
+
+	inst.value = addr >> shift_pa;
 	return cmdq_pkt_append_command(pkt, inst);
 }
 EXPORT_SYMBOL(cmdq_pkt_jump_abs);
-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 19 09:07:55 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 01:07:55 +0800
Subject: [PATCH v3 2/7] mailbox: mtk-cmdq: Add driver data to support for MT8196
In-Reply-To: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
References: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219170800.2957-3-jason-jh.lin@mediatek.com>

MT8196 has 3 new hardware configuration compared with the previous SoC,
which correspond to the 3 new driver data:

1. mminfra_offset: For GCE data plane control
   Since GCE has been moved into mminfra, GCE needs to append the
   mminfra offset to the DRAM address when accessing the DRAM.

2. gce_vm: For GCE hardware virtualization
   Currently, the first version of the mt8196 mailbox controller only
   requires setting the VM-related registers to enable the permissions
   of a host VM.

3. dma_mask_bit: For dma address bit control
   In order to avoid the hardware limitations of MT8196 accessing DRAM,
   GCE needs to configure the DMA address to be less than 35 bits.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c       | 90 +++++++++++++++++++++---
 include/linux/mailbox/mtk-cmdq-mailbox.h |  2 +
 2 files changed, 84 insertions(+), 8 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index d186865b8dce..442ccd332d5f 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -43,6 +43,17 @@
 #define GCE_CTRL_BY_SW				GENMASK(2, 0)
 #define GCE_DDR_EN				GENMASK(18, 16)
 
+#define GCE_VM_ID_MAP0			0x5018
+#define GCE_VM_MAP0_ALL_HOST			GENMASK(29, 0)
+#define GCE_VM_ID_MAP1			0x501c
+#define GCE_VM_MAP1_ALL_HOST			GENMASK(29, 0)
+#define GCE_VM_ID_MAP2			0x5020
+#define GCE_VM_MAP2_ALL_HOST			GENMASK(29, 0)
+#define GCE_VM_ID_MAP3			0x5024
+#define GCE_VM_MAP3_ALL_HOST			GENMASK(5, 0)
+#define GCE_VM_CPR_GSIZE		0x50c4
+#define GCE_VM_CPR_GSIZE_HSOT			GENMASK(3, 0)
+
 #define CMDQ_THR_ACTIVE_SLOT_CYCLES	0x3200
 #define CMDQ_THR_ENABLED		0x1
 #define CMDQ_THR_DISABLED		0x0
@@ -87,11 +98,24 @@ struct cmdq {
 struct gce_plat {
 	u32 thread_nr;
 	u8 shift;
+	dma_addr_t mminfra_offset;
 	bool control_by_sw;
 	bool sw_ddr_en;
+	bool gce_vm;
+	u32 dma_mask_bit;
 	u32 gce_num;
 };
 
+static inline u32 cmdq_reg_shift_addr(u32 addr, const struct gce_plat *pdata)
+{
+	return ((addr + pdata->mminfra_offset) >> pdata->shift);
+}
+
+static inline u32 cmdq_reg_revert_addr(u32 addr, const struct gce_plat *pdata)
+{
+	return ((addr << pdata->shift) - pdata->mminfra_offset);
+}
+
 static void cmdq_sw_ddr_enable(struct cmdq *cmdq, bool enable)
 {
 	WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
@@ -112,6 +136,30 @@ u8 cmdq_get_shift_pa(struct mbox_chan *chan)
 }
 EXPORT_SYMBOL(cmdq_get_shift_pa);
 
+dma_addr_t cmdq_get_offset_pa(struct mbox_chan *chan)
+{
+	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+	return cmdq->pdata->mminfra_offset;
+}
+EXPORT_SYMBOL(cmdq_get_offset_pa);
+
+bool cmdq_addr_need_offset(struct mbox_chan *chan, dma_addr_t addr)
+{
+	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+	if (cmdq->pdata->mminfra_offset == 0)
+		return false;
+
+	/*
+	 * mminfra will recognize the addr that greater than the mminfra_offset
+	 * as a transaction to DRAM.
+	 * So the caller needs to append mminfra_offset for the true case.
+	 */
+	return (addr >= cmdq->pdata->mminfra_offset);
+}
+EXPORT_SYMBOL(cmdq_addr_need_offset);
+
 static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
 {
 	u32 status;
@@ -143,6 +191,17 @@ static void cmdq_init(struct cmdq *cmdq)
 	u32 gctl_regval = 0;
 
 	WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
+
+	if (cmdq->pdata->gce_vm) {
+		/* config cpr size for host vm */
+		writel(GCE_VM_CPR_GSIZE_HSOT, cmdq->base + GCE_VM_CPR_GSIZE);
+		/* config CPR_GSIZE before setting VM_ID_MAP to avoid data leakage */
+		writel(GCE_VM_MAP0_ALL_HOST, cmdq->base + GCE_VM_ID_MAP0);
+		writel(GCE_VM_MAP1_ALL_HOST, cmdq->base + GCE_VM_ID_MAP1);
+		writel(GCE_VM_MAP2_ALL_HOST, cmdq->base + GCE_VM_ID_MAP2);
+		writel(GCE_VM_MAP3_ALL_HOST, cmdq->base + GCE_VM_ID_MAP3);
+	}
+
 	if (cmdq->pdata->control_by_sw)
 		gctl_regval = GCE_CTRL_BY_SW;
 	if (cmdq->pdata->sw_ddr_en)
@@ -199,7 +258,7 @@ static void cmdq_task_insert_into_thread(struct cmdq_task *task)
 				prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
 	prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] =
 		(u64)CMDQ_JUMP_BY_PA << 32 |
-		(task->pa_base >> task->cmdq->pdata->shift);
+		cmdq_reg_shift_addr(task->pa_base, task->cmdq->pdata);
 	dma_sync_single_for_device(dev, prev_task->pa_base,
 				   prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
 
@@ -264,7 +323,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
 	else
 		return;
 
-	curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->pdata->shift;
+	curr_pa = cmdq_reg_shift_addr(readl(thread->base + CMDQ_THR_CURR_ADDR), cmdq->pdata);
 
 	list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
 				 list_entry) {
@@ -416,9 +475,9 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
 		 */
 		WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
 
-		writel(task->pa_base >> cmdq->pdata->shift,
+		writel(cmdq_reg_shift_addr(task->pa_base, cmdq->pdata),
 		       thread->base + CMDQ_THR_CURR_ADDR);
-		writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->pdata->shift,
+		writel(cmdq_reg_shift_addr(task->pa_base + pkt->cmd_buf_size, cmdq->pdata),
 		       thread->base + CMDQ_THR_END_ADDR);
 
 		writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
@@ -426,10 +485,10 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
 		writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
 	} else {
 		WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
-		curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
-			cmdq->pdata->shift;
-		end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
-			cmdq->pdata->shift;
+		curr_pa = cmdq_reg_revert_addr(readl(thread->base + CMDQ_THR_CURR_ADDR),
+					       cmdq->pdata);
+		end_pa = cmdq_reg_revert_addr(readl(thread->base + CMDQ_THR_END_ADDR),
+					      cmdq->pdata);
 		/* check boundary */
 		if (curr_pa == end_pa - CMDQ_INST_SIZE ||
 		    curr_pa == end_pa) {
@@ -663,6 +722,9 @@ static int cmdq_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
+	if (cmdq->pdata->dma_mask_bit)
+		dma_set_coherent_mask(dev, DMA_BIT_MASK(cmdq->pdata->dma_mask_bit));
+
 	cmdq->mbox.dev = dev;
 	cmdq->mbox.chans = devm_kcalloc(dev, cmdq->pdata->thread_nr,
 					sizeof(*cmdq->mbox.chans), GFP_KERNEL);
@@ -782,6 +844,17 @@ static const struct gce_plat gce_plat_mt8195 = {
 	.gce_num = 2
 };
 
+static const struct gce_plat gce_plat_mt8196 = {
+	.thread_nr = 32,
+	.shift = 3,
+	.mminfra_offset = 0x80000000, /* 2GB */
+	.control_by_sw = true,
+	.sw_ddr_en = true,
+	.gce_vm = true,
+	.dma_mask_bit = 35,
+	.gce_num = 2
+};
+
 static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_mt6779},
 	{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_mt8173},
@@ -790,6 +863,7 @@ static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt8188-gce", .data = (void *)&gce_plat_mt8188},
 	{.compatible = "mediatek,mt8192-gce", .data = (void *)&gce_plat_mt8192},
 	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_mt8195},
+	{.compatible = "mediatek,mt8196-gce", .data = (void *)&gce_plat_mt8196},
 	{}
 };
 MODULE_DEVICE_TABLE(of, cmdq_of_ids);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
index a8f0070c7aa9..79398bf95f8d 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -79,5 +79,7 @@ struct cmdq_pkt {
 };
 
 u8 cmdq_get_shift_pa(struct mbox_chan *chan);
+dma_addr_t cmdq_get_offset_pa(struct mbox_chan *chan);
+bool cmdq_addr_need_offset(struct mbox_chan *chan, dma_addr_t addr);
 
 #endif /* __MTK_CMDQ_MAILBOX_H__ */
-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 19 09:07:59 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 01:07:59 +0800
Subject: [PATCH v3 6/7] drm/mediatek: Add programming flow for unsupported subsys ID hardware
In-Reply-To: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
References: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219170800.2957-7-jason-jh.lin@mediatek.com>

To support hardware without subsys IDs on new SoCs, add a programming
flow that checks whether the subsys ID is valid. If the subsys ID is
invalid, the flow will call 2 alternative CMDQ APIs:
cmdq_pkt_assign() and cmdq_pkt_write_s_value() to achieve the same
functionality.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 33 ++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
index edc6417639e6..219d67735a54 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
@@ -66,14 +66,37 @@ struct mtk_ddp_comp_dev {
 	struct cmdq_client_reg cmdq_reg;
 };
 
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+static void mtk_ddp_write_cmdq_pkt(struct cmdq_pkt *cmdq_pkt, struct cmdq_client_reg *cmdq_reg,
+				   unsigned int offset, unsigned int value, unsigned int mask)
+{
+	offset += cmdq_reg->offset;
+
+	if (cmdq_reg->subsys != CMDQ_SUBSYS_INVALID) {
+		if (mask == GENMASK(31, 0))
+			cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys, offset, value);
+		else
+			cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys, offset, value, mask);
+	} else {
+		/* only MMIO access, no need to check mminfro_offset */
+		cmdq_pkt_assign(cmdq_pkt, 0, CMDQ_ADDR_HIGH(cmdq_reg->pa_base));
+		if (mask == GENMASK(31, 0))
+			cmdq_pkt_write_s_value(cmdq_pkt, CMDQ_THR_SPR_IDX0,
+					       CMDQ_ADDR_LOW(offset), value);
+		else
+			cmdq_pkt_write_s_mask_value(cmdq_pkt, CMDQ_THR_SPR_IDX0,
+						    CMDQ_ADDR_LOW(offset), value, mask);
+	}
+}
+#endif
+
 void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 		   struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
 		   unsigned int offset)
 {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (cmdq_pkt)
-		cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
-			       cmdq_reg->offset + offset, value);
+		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0));
 	else
 #endif
 		writel(value, regs + offset);
@@ -85,8 +108,7 @@ void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (cmdq_pkt)
-		cmdq_pkt_write(cmdq_pkt, cmdq_reg->subsys,
-			       cmdq_reg->offset + offset, value);
+		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, GENMASK(31, 0));
 	else
 #endif
 		writel_relaxed(value, regs + offset);
@@ -98,8 +120,7 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (cmdq_pkt) {
-		cmdq_pkt_write_mask(cmdq_pkt, cmdq_reg->subsys,
-				    cmdq_reg->offset + offset, value, mask);
+		mtk_ddp_write_cmdq_pkt(cmdq_pkt, cmdq_reg, offset, value, mask);
 	} else {
 #endif
 		u32 tmp = readl(regs + offset);
-- 
2.43.0



From Frank.li at nxp.com  Thu Dec 19 09:17:24 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:17:24 -0500
Subject: [PATCH v3 1/4] arm64: dts: s32g: add 'I2C' common board support
In-Reply-To: <20241219131029.1139720-2-ciprianmarian.costea@oss.nxp.com>
References: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
 <20241219131029.1139720-2-ciprianmarian.costea@oss.nxp.com>
Message-ID: <Z2RVJLKqimn+jDYY@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 03:10:26PM +0200, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>
> On both 'S32G2' and 'S32G3' SoCs there are five i2c controllers available
> (i2c0-i2c4). Specific S32G2/S32G3 based board 'i2c' dts device support
> will be added in further commits.
>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/s32g2.dtsi | 45 +++++++++++++++++++++
>  arch/arm64/boot/dts/freescale/s32g3.dtsi | 50 ++++++++++++++++++++++++
>  2 files changed, 95 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> index 7be430b78c83..0e6c847ab0c3 100644
> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> @@ -333,6 +333,33 @@ uart1: serial at 401cc000 {
>  			status = "disabled";
>  		};
>
> +		i2c0: i2c at 401e4000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x401e4000 0x1000>;

Need add common part #address-cell and #size-cell, which all are the same
for all I2C.

Frank

> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c1: i2c at 401e8000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x401e8000 0x1000>;
> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c2: i2c at 401ec000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x401ec000 0x1000>;
> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		uart2: serial at 402bc000 {
>  			compatible = "nxp,s32g2-linflexuart",
>  				     "fsl,s32v234-linflexuart";
> @@ -341,6 +368,24 @@ uart2: serial at 402bc000 {
>  			status = "disabled";
>  		};
>
> +		i2c3: i2c at 402d8000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x402d8000 0x1000>;
> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c4: i2c at 402dc000 {
> +			compatible = "nxp,s32g2-i2c";
> +			reg = <0x402dc000 0x1000>;
> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		usdhc0: mmc at 402f0000 {
>  			compatible = "nxp,s32g2-usdhc";
>  			reg = <0x402f0000 0x1000>;
> diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> index 6c572ffe37ca..666e4029e588 100644
> --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> @@ -390,6 +390,36 @@ uart1: serial at 401cc000 {
>  			status = "disabled";
>  		};
>
> +		i2c0: i2c at 401e4000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x401e4000 0x1000>;
> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c1: i2c at 401e8000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x401e8000 0x1000>;
> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c2: i2c at 401ec000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x401ec000 0x1000>;
> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		uart2: serial at 402bc000 {
>  			compatible = "nxp,s32g3-linflexuart",
>  				     "fsl,s32v234-linflexuart";
> @@ -398,6 +428,26 @@ uart2: serial at 402bc000 {
>  			status = "disabled";
>  		};
>
> +		i2c3: i2c at 402d8000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x402d8000 0x1000>;
> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c4: i2c at 402dc000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			reg = <0x402dc000 0x1000>;
> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		usdhc0: mmc at 402f0000 {
>  			compatible = "nxp,s32g3-usdhc",
>  				     "nxp,s32g2-usdhc";
> --
> 2.45.2
>


From jason-jh.lin at mediatek.com  Thu Dec 19 09:07:56 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 01:07:56 +0800
Subject: [PATCH v3 3/7] soc: mediatek: mtk-cmdq: Add pa_base parsing for unsupported subsys ID hardware
In-Reply-To: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
References: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219170800.2957-4-jason-jh.lin@mediatek.com>

When GCE executes instructions, the corresponding hardware register
can be found through the subsys ID. For hardware that does not support
subsys ID, its subsys ID will be set to invalid value and its physical
address needs to be used to generate GCE instructions.

This commit adds a pa_base parsing flow to the cmdq_client_reg structure
for these unsupported subsys ID hardware.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 18 ++++++++++++++++--
 include/linux/soc/mediatek/mtk-cmdq.h  |  3 +++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 455221e8de24..aa9853100d78 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/mailbox_controller.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #define CMDQ_WRITE_ENABLE_MASK	BIT(0)
@@ -60,20 +61,30 @@ int cmdq_dev_get_client_reg(struct device *dev,
 			    struct cmdq_client_reg *client_reg, int idx)
 {
 	struct of_phandle_args spec;
+	struct resource res;
 	int err;
 
 	if (!client_reg)
 		return -ENOENT;
 
+	if (of_address_to_resource(dev->of_node, 0, &res) != 0) {
+		dev_err(dev, "Missing reg in %s node\n", dev->of_node->full_name);
+		return -EINVAL;
+	}
+	client_reg->pa_base = res.start;
+
 	err = of_parse_phandle_with_fixed_args(dev->of_node,
 					       "mediatek,gce-client-reg",
 					       3, idx, &spec);
 	if (err < 0) {
-		dev_warn(dev,
+		dev_dbg(dev,
 			"error %d can't parse gce-client-reg property (%d)",
 			err, idx);
 
-		return err;
+		/* make subsys invalid */
+		client_reg->subsys = CMDQ_SUBSYS_INVALID;
+
+		return 0;
 	}
 
 	client_reg->subsys = (u8)spec.args[0];
@@ -130,6 +141,9 @@ int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t siz
 
 	pkt->buf_size = size;
 
+	/* need to use pkt->cl->chan later to call mbox APIs when generating instruction */
+	pkt->cl = (void *)client;
+
 	dev = client->chan->mbox->dev;
 	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
 				  DMA_TO_DEVICE);
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 0c3906e8ad19..3578cc9200e9 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -23,6 +23,8 @@
 #define CMDQ_THR_SPR_IDX2	(2)
 #define CMDQ_THR_SPR_IDX3	(3)
 
+#define CMDQ_SUBSYS_INVALID	(U8_MAX)
+
 struct cmdq_pkt;
 
 enum cmdq_logic_op {
@@ -52,6 +54,7 @@ struct cmdq_operand {
 
 struct cmdq_client_reg {
 	u8 subsys;
+	phys_addr_t pa_base;
 	u16 offset;
 	u16 size;
 };
-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 19 09:07:58 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 01:07:58 +0800
Subject: [PATCH v3 5/7] soc: mediatek: Add programming flow for unsupported subsys ID hardware
In-Reply-To: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
References: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219170800.2957-6-jason-jh.lin@mediatek.com>

To support hardware without subsys IDs on new SoCs, add a programming
flow that checks whether the subsys ID is valid. If the subsys ID is
invalid, the flow will call 2 alternative CMDQ APIs:
cmdq_pkt_assign() and cmdq_pkt_write_s_value() to achieve the same
functionality.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mmsys.c | 14 +++++++++++---
 drivers/soc/mediatek/mtk-mutex.c | 11 +++++++++--
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index bb4639ca0b8c..ce949b863b05 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -167,9 +167,17 @@ static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask,
 	u32 tmp;
 
 	if (mmsys->cmdq_base.size && cmdq_pkt) {
-		ret = cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
-					  mmsys->cmdq_base.offset + offset, val,
-					  mask);
+		offset += mmsys->cmdq_base.offset;
+		if (mmsys->cmdq_base.subsys != CMDQ_SUBSYS_INVALID) {
+			ret = cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
+						  offset, val, mask);
+		} else {
+			/* only MMIO access, no need to check mminfro_offset */
+			ret = cmdq_pkt_assign(cmdq_pkt, CMDQ_THR_SPR_IDX0,
+					      CMDQ_ADDR_HIGH(mmsys->cmdq_base.pa_base));
+			ret |= cmdq_pkt_write_s_mask_value(cmdq_pkt, CMDQ_THR_SPR_IDX0,
+							   CMDQ_ADDR_LOW(offset), val, mask);
+		}
 		if (ret)
 			pr_debug("CMDQ unavailable: using CPU write\n");
 		else
diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 5250c1d702eb..3788b16efbf4 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -963,6 +963,7 @@ int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, void *pkt)
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
 						 mutex[mutex->id]);
 	struct cmdq_pkt *cmdq_pkt = (struct cmdq_pkt *)pkt;
+	dma_addr_t en_addr = mtx->addr + DISP_REG_MUTEX_EN(mutex->id);
 
 	WARN_ON(&mtx->mutex[mutex->id] != mutex);
 
@@ -971,8 +972,14 @@ int mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex, void *pkt)
 		return -ENODEV;
 	}
 
-	cmdq_pkt_write(cmdq_pkt, mtx->cmdq_reg.subsys,
-		       mtx->addr + DISP_REG_MUTEX_EN(mutex->id), 1);
+	if (mtx->cmdq_reg.subsys != CMDQ_SUBSYS_INVALID) {
+		cmdq_pkt_write(cmdq_pkt, mtx->cmdq_reg.subsys, en_addr, 1);
+	} else {
+		/* only MMIO access, no need to check mminfro_offset */
+		cmdq_pkt_assign(cmdq_pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(en_addr));
+		cmdq_pkt_write_s_value(cmdq_pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_LOW(en_addr), 1);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq);
-- 
2.43.0



From maz at kernel.org  Thu Dec 19 09:11:31 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 17:11:31 +0000
Subject: [PATCH v3 0/6] arm64: Clean up and simplify PA space size handling
In-Reply-To: <20241212081841.2168124-8-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
Message-ID: <86y10bpph8.wl-maz@kernel.org>

On Thu, 12 Dec 2024 08:18:42 +0000,
Ard Biesheuvel <ardb+git at google.com> wrote:
> 
> From: Ard Biesheuvel <ardb at kernel.org>
> 
> This series addresses a number of buglets related to how we handle the
> size of the physical address space when building LPA2 capable kernels:
> 
> - reject 52-bit physical addressess in the mapping routines when LPA2 is
>   configured but not available at runtime
> - ensure that TCR.IPS is not set to 52-bits if LPA2 is not supported
> - ensure that TCR_EL2.PS and DS match the host, regardless of whether
>   LPA2 is available at stage 2
> - don't rely on kvm_get_parange() and invalid physical addresses as
>   control flags in the pKVM page donation APIs
> 
> Finally, the configurable 48-bit physical address space limit is dropped
> entirely, as it doesn't buy us a lot now that all the PARange and {I}PS
> handling is done at runtime.

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

	M.

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


From dave.hansen at intel.com  Thu Dec 19 09:13:57 2024
From: dave.hansen at intel.com (Dave Hansen)
Date: Thu, 19 Dec 2024 09:13:57 -0800
Subject: [PATCH 00/10] Account page tables at all levels
In-Reply-To: <20241219164425.2277022-1-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
Message-ID: <a7398426-56d1-40b4-a1c9-40ae8c8a4b4b@intel.com>

On 12/19/24 08:44, Kevin Brodsky wrote:
>   +---------------+-------------------------+-----------------------+--------------+------------------------------------+
>   | x86           | Y                       | Y                     | Y/N          | kmem_cache at pgd level if PAE     |
>   +---------------+-------------------------+-----------------------+--------------+------------------------------------+

This is a really rare series that adds functionality _and_ removes code
overall. It looks really good to me. The x86 implementation seems to be
captured just fine in the generic one:

Acked-by: Dave Hansen <dave.hansen at linux.intel.com>

One super tiny nit is that the PAE pgd _can_ be allocated using
__get_free_pages(). It was originally there for Xen, but I think it's
being used for PTI only at this point and the comments are wrong-ish.

I kinda think we should just get rid of the 32-bit kmem_cache entirely.


From Frank.li at nxp.com  Thu Dec 19 09:13:56 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:13:56 -0500
Subject: [PATCH v3 2/2] nvmem: imx-ocotp-ele: Support accessing
 controller for i.MX9
In-Reply-To: <20241219-imx-ocotp-v3-2-b22371098071@nxp.com>
References: <20241219-imx-ocotp-v3-0-b22371098071@nxp.com>
 <20241219-imx-ocotp-v3-2-b22371098071@nxp.com>
Message-ID: <Z2RUVK/nj5Mf8hVr@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 10:25:18PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
>
> i.MX9 OCOTP supports a specific peripheral or function being fused
> which means disabled, so
>  - Introduce ocotp_access_gates to be container of efuse gate info
>  - Iterate each node under '/soc' to check accessing permission. If not

Nit: Iterate all nodes to ....

>    allowed to be accessed, detach the node
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/nvmem/imx-ocotp-ele.c | 183 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 182 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
> index ca6dd71d8a2e29888c6e556aaea116c1a967cb5f..173863b1fd7de150576b78f03c256a151b174389 100644
> --- a/drivers/nvmem/imx-ocotp-ele.c
> +++ b/drivers/nvmem/imx-ocotp-ele.c
> @@ -5,6 +5,8 @@
>   * Copyright 2023 NXP
>   */
>
[...]
> +
> +	for_each_available_child_of_node_scoped(parent, child) {
> +		struct of_phandle_iterator it;
> +		int err;
> +		u32 id;
> +
> +		of_for_each_phandle(&it, err, child, "access-controllers",
> +				    "#access-controller-cells", 0) {
> +			struct of_phandle_args provider_args;
> +			struct device_node *provider = it.node;
> +
> +			if (err) {
> +				dev_err(dev, "Unable to get access-controllers property for node %s\n, err: %d",
> +					child->full_name, err);
> +				of_node_put(provider);
> +				return err;
> +			}
> +
> +			/* Only support one cell */
> +			if (of_phandle_iterator_args(&it, provider_args.args, 1) != 1) {
> +				dev_err(dev, "wrong args count\n");

you call of_node_put(provider) in above err branch.
why not call it here?

Frank
> +				return -EINVAL;
> +			}
> +
> +			id = provider_args.args[0];
> +
> +			dev_dbg(dev, "Checking node: %s gate: %d\n", child->full_name, id);
> +
> +			if (imx_ele_ocotp_check_access(pdev, id)) {
> +				of_detach_node(child);
> +				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
> +					child->full_name);
> +			}
> +		}
> +
> +		imx_ele_ocotp_grant_access(pdev, child);
> +	}
> +
> +	return 0;
> +}
> +

[...]

>
> --
> 2.37.1
>


From peterz at infradead.org  Thu Dec 19 09:19:20 2024
From: peterz at infradead.org (Peter Zijlstra)
Date: Thu, 19 Dec 2024 18:19:20 +0100
Subject: [PATCH 01/10] mm: Move common parts of pagetable_*_[cd]tor to
 helpers
In-Reply-To: <20241219164425.2277022-2-kevin.brodsky@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <20241219164425.2277022-2-kevin.brodsky@arm.com>
Message-ID: <20241219171920.GB26279@noisy.programming.kicks-ass.net>

On Thu, Dec 19, 2024 at 04:44:16PM +0000, Kevin Brodsky wrote:
> Besides the ptlock management at PTE/PMD level, all the
> pagetable_*_[cd]tor have the same implementation. Introduce common
> helpers for all levels to reduce the duplication.

Uff, I forgot to Cc you on the discussion here, sorry!:

  https://lkml.kernel.org/r/cover.1734526570.git.zhengqi.arch at bytedance.com

we now have two series doing more or less overlapping things :/

You can in fact trivially merge the all the implementations -- the
apparent non-common bit (ptlock_free) is a no-op for all those other
levels because they'll be having ptdesc->lock == NULL.


From Frank.li at nxp.com  Thu Dec 19 09:20:08 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:20:08 -0500
Subject: [PATCH v3 2/4] arm64: dts: s32g: add common 'S32G-EVB' and
 'S32G-RDB' board support
In-Reply-To: <20241219131029.1139720-3-ciprianmarian.costea@oss.nxp.com>
References: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
 <20241219131029.1139720-3-ciprianmarian.costea@oss.nxp.com>
Message-ID: <Z2RVyO05WvIQUmX4@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 03:10:27PM +0200, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>
> With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
> (rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
> are quite similar. The common part for the EVB revisions will be
> centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
> be placed in 's32gxxa-rdb.dtsi' file.
>
> This refactor will also serve for other modules in the future, such as
> FlexCAN, DSPI.
>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> ---
>  .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
>  .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 126 +++++++++++++++
>  2 files changed, 276 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>
> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
> new file mode 100644
> index 000000000000..a44eff28073a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
> @@ -0,0 +1,150 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> +/*
> + * Copyright 2024 NXP
> + *
> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
> + *          Larisa Grigore <larisa.grigore at nxp.com>
> + */
> +
[...]

> +
> +&i2c2 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c2_pins>;
> +	pinctrl-1 = <&i2c2_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c4 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;


I have said many times, these should be in common part.

Frank

> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c4_pins>;
> +	pinctrl-1 = <&i2c4_gpio_pins>;
> +	status = "okay";
> +};
> --
> 2.45.2
>


From jason-jh.lin at mediatek.com  Thu Dec 19 09:08:00 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 01:08:00 +0800
Subject: [PATCH v3 7/7] media: mediatek: mdp3: Add programming flow for unsupported subsys ID hardware
In-Reply-To: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
References: <20241219170800.2957-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219170800.2957-8-jason-jh.lin@mediatek.com>

To support hardware without subsys IDs on new SoCs, add a programming
flow that checks whether the subsys ID is valid. If the subsys ID is
invalid, the flow will call 2 alternative CMDQ APIs:
cmdq_pkt_assign() and cmdq_pkt_write_s_mask_value() to achieve the
same functionality.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c    | 18 ++++-
 .../platform/mediatek/mdp3/mtk-mdp3-comp.h    | 79 ++++++++++++++-----
 2 files changed, 77 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
index e5ccf673e152..0ee3354963db 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
@@ -321,7 +321,14 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
 	/* Enable mux settings */
 	for (index = 0; index < ctrl->num_sets; index++) {
 		set = &ctrl->sets[index];
-		cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, set->value);
+		if (set->subsys_id != CMDQ_SUBSYS_INVALID) {
+			cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, set->value);
+		} else {
+			/* only MMIO access, no need to check mminfro_offset */
+			cmdq_pkt_assign(&cmd->pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(set->reg));
+			cmdq_pkt_write_s_value(&cmd->pkt, CMDQ_THR_SPR_IDX0,
+					       CMDQ_ADDR_LOW(set->reg), set->value);
+		}
 	}
 	/* Config sub-frame information */
 	for (index = (num_comp - 1); index >= 0; index--) {
@@ -376,7 +383,14 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
 	/* Disable mux settings */
 	for (index = 0; index < ctrl->num_sets; index++) {
 		set = &ctrl->sets[index];
-		cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, 0);
+		if (set->subsys_id != CMDQ_SUBSYS_INVALID) {
+			cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, 0);
+		} else {
+			/* only MMIO access, no need to check mminfro_offset */
+			cmdq_pkt_assign(&cmd->pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(set->reg));
+			cmdq_pkt_write_s_value(&cmd->pkt, CMDQ_THR_SPR_IDX0,
+					       CMDQ_ADDR_LOW(set->reg), 0);
+		}
 	}
 
 	return 0;
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
index 681906c16419..e20f9d080db9 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
@@ -9,17 +9,44 @@
 
 #include "mtk-mdp3-cmdq.h"
 
-#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask)	\
-do {								\
-	typeof(mask) (m) = (mask);				\
-	cmdq_pkt_write_mask(&((cmd)->pkt), id, (base) + (ofst),	\
-			    (val),				\
-		(((m) & (ofst##_MASK)) == (ofst##_MASK)) ?	\
-			(0xffffffff) : (m));			\
+#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask)		\
+do {									\
+	typeof(cmd) (_c) = (cmd);					\
+	typeof(id) (_i) = (id);						\
+	typeof(base) (_b) = (base);					\
+	typeof(ofst) (_o) = (ofst);					\
+	typeof(val) (_v) = (val);					\
+	typeof(mask) (_m) = (mask);					\
+	_m = ((_m & (ofst##_MASK)) == (ofst##_MASK)) ? 0xffffffff : _m;	\
+	if (_i != CMDQ_SUBSYS_INVALID) {				\
+		cmdq_pkt_write_mask(&_c->pkt, _i, _b + _o, _v, _m);	\
+	} else {							\
+		/* only MMIO access, no need to check mminfro_offset */	\
+		cmdq_pkt_assign(&_c->pkt, CMDQ_THR_SPR_IDX0,		\
+				CMDQ_ADDR_HIGH(_b));			\
+		cmdq_pkt_write_s_mask_value(&_c->pkt, CMDQ_THR_SPR_IDX0,\
+					    CMDQ_ADDR_LOW(_b + _o),	\
+					    _v, _m);			\
+	}								\
 } while (0)
 
-#define MM_REG_WRITE(cmd, id, base, ofst, val)			\
-	cmdq_pkt_write(&((cmd)->pkt), id, (base) + (ofst), (val))
+#define MM_REG_WRITE(cmd, id, base, ofst, val)				\
+do {									\
+	typeof(cmd) (_c) = (cmd);					\
+	typeof(id) (_i) = (id);						\
+	typeof(base) (_b) = (base);					\
+	typeof(ofst) (_o) = (ofst);					\
+	typeof(val) (_v) = (val);					\
+	if (_i != CMDQ_SUBSYS_INVALID) {				\
+		cmdq_pkt_write(&_c->pkt, _i, _b + _o, _v);		\
+	} else {							\
+		/* only MMIO access, no need to check mminfro_offset */	\
+		cmdq_pkt_assign(&_c->pkt, CMDQ_THR_SPR_IDX0,		\
+				CMDQ_ADDR_HIGH(_b));			\
+		cmdq_pkt_write_s_value(&_c->pkt, CMDQ_THR_SPR_IDX0,	\
+				       CMDQ_ADDR_LOW(_b + _o), _v);	\
+	}								\
+} while (0)
 
 #define MM_REG_WAIT(cmd, evt)					\
 do {								\
@@ -49,17 +76,33 @@ do {								\
 	cmdq_pkt_set_event(&((c)->pkt), (e));			\
 } while (0)
 
-#define MM_REG_POLL_MASK(cmd, id, base, ofst, val, _mask)	\
-do {								\
-	typeof(_mask) (_m) = (_mask);				\
-	cmdq_pkt_poll_mask(&((cmd)->pkt), id,			\
-		(base) + (ofst), (val),				\
-		(((_m) & (ofst##_MASK)) == (ofst##_MASK)) ?	\
-			(0xffffffff) : (_m));			\
+#define MM_REG_POLL_MASK(cmd, id, base, ofst, val, mask)		\
+do {									\
+	typeof(cmd) (_c) = (cmd);					\
+	typeof(id) (_i) = (id);						\
+	typeof(base) (_b) = (base);					\
+	typeof(ofst) (_o) = (ofst);					\
+	typeof(val) (_v) = (val);					\
+	typeof(mask) (_m) = (mask);					\
+	_m = ((_m & (ofst##_MASK)) == (ofst##_MASK)) ? 0xffffffff : _m;	\
+	if (_i != CMDQ_SUBSYS_INVALID)					\
+		cmdq_pkt_poll_mask(&_c->pkt, _i, _b + _o, _v, _m);	\
+	else /* POLL not support SPR, so use cmdq_pkt_poll_addr() */	\
+		cmdq_pkt_poll_addr(&_c->pkt, _b + _o, _v, _m);		\
 } while (0)
 
-#define MM_REG_POLL(cmd, id, base, ofst, val)			\
-	cmdq_pkt_poll(&((cmd)->pkt), id, (base) + (ofst), (val))
+#define MM_REG_POLL(cmd, id, base, ofst, val)				\
+do {									\
+	typeof(cmd) (_c) = (cmd);					\
+	typeof(id) (_i) = (id);						\
+	typeof(base) (_b) = (base);					\
+	typeof(ofst) (_o) = (ofst);					\
+	typeof(val) (_v) = (val);					\
+	if (_i != CMDQ_SUBSYS_INVALID)					\
+		cmdq_pkt_poll(&_c->pkt, _i, _b + _o, _v);		\
+	else /* POLL not support SPR, so use cmdq_pkt_poll_addr() */	\
+		cmdq_pkt_poll_addr(&_c->pkt, _b + _o, _v, 0xffffffff);	\
+} while (0)
 
 enum mtk_mdp_comp_id {
 	MDP_COMP_NONE = -1,	/* Invalid engine */
-- 
2.43.0



From Jason-JH.Lin at mediatek.com  Thu Dec 19 09:26:51 2024
From: Jason-JH.Lin at mediatek.com (=?utf-8?B?SmFzb24tSkggTGluICjmnpfnnb/npaUp?=)
Date: Thu, 19 Dec 2024 17:26:51 +0000
Subject: [PATCH v2 1/3] dt-bindings: display: mediatek: ovl: Modify rules
 for MT8195/MT8188
In-Reply-To: <6f92c81f-84d0-4306-96d2-1cfc2ddb72e0@collabora.com>
References: <20241213095044.23757-1-jason-jh.lin@mediatek.com>
	 <20241213095044.23757-2-jason-jh.lin@mediatek.com>
	 <6f92c81f-84d0-4306-96d2-1cfc2ddb72e0@collabora.com>
Message-ID: <8599c12c853cdbe19c39c12ee3391cde5a29a2ac.camel@mediatek.com>

On Thu, 2024-12-19 at 12:09 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> Il 13/12/24 10:50, Jason-JH.Lin ha scritto:
> > From: Hsiao Chien Sung <shawn.sung at mediatek.com>
> > 
> > Modify rules for both MT8195 and MT8188.
> > Hardware capabilities include color formats and AFBC are
> > changed since MT8195, stop using the settings of MT8183.
> > 
> > Acked-by: Rob Herring <robh at kernel.org>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno at collabora.com>
> > Reviewed-by: CK Hu <ck.hu at mediatek.com>
> > Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
> > ---
> >   .../bindings/display/mediatek/mediatek,ovl.yaml          | 9
> > ++++-----
> >   1 file changed, 4 insertions(+), 5 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.y
> > aml
> > index 9ea796a033b2..8ca8e5966b9a 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.y
> > aml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.y
> > aml
> > @@ -26,6 +26,7 @@ properties:
> >             - mediatek,mt8173-disp-ovl
> >             - mediatek,mt8183-disp-ovl
> >             - mediatek,mt8192-disp-ovl
> > +          - mediatek,mt8195-disp-ovl
> >             - mediatek,mt8195-mdp3-ovl
> >         - items:
> >             - enum:
> > @@ -36,16 +37,14 @@ properties:
> >             - enum:
> >                 - mediatek,mt6795-disp-ovl
> >             - const: mediatek,mt8173-disp-ovl
> > -      - items:
> > -          - enum:
> > -              - mediatek,mt8188-disp-ovl
> > -              - mediatek,mt8195-disp-ovl
> > -          - const: mediatek,mt8183-disp-ovl
> >         - items:
> >             - enum:
> >                 - mediatek,mt8186-disp-ovl
> >                 - mediatek,mt8365-disp-ovl
> >             - const: mediatek,mt8192-disp-ovl
> > +      - items:
> > +          - const: mediatek,mt8188-disp-ovl
> > +          - const: mediatek,mt8195-disp-ovl
> > 
> >     reg:
> >       maxItems: 1
> 
> 
> Jason, while doing MDP3 bindings for MT8188, I noticed that the
> binding for OVL is
> missing; can you please add a commit on top of this series adding the
> following
> snippet?
> 
>        - items:
>            - const: mediatek,mt8188-mdp3-ovl
>            - const: mediatek,mt8195-mdp3-ovl
> 
> ...with a suggested-by tag it's going to be fine :-)
> 

Sure, I'll add one more patch for this in the top of v3.

Regards,
Jason-JH.Lin

> P.S.: Please refer to
> 
https://lore.kernel.org/r/20241218105320.38980-1-angelogioacchino.delregno at collabora.com
> 
> Thanks,
> Angelo

From Frank.li at nxp.com  Thu Dec 19 09:45:36 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:45:36 -0500
Subject: [PATCH 09/10] arm64: dts: imx8mp-skov: fix phy-mode
In-Reply-To: <20241219-skov-dt-updates-v1-9-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-9-38bf80dc22df@pengutronix.de>
Message-ID: <Z2RbwCt2zX2GyK8O@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 08:25:33AM +0100, Ahmad Fatoum wrote:
> From: Oleksij Rempel <o.rempel at pengutronix.de>
>
> Use rgmii-rxid instead of rgmii-txid. It should have no effect here,
> but rxid is the correct value in our case.

Use rgmii-rxid instead of rgmii-txid because ...

Frank

>
> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
>  arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> index 80d212acc0c3..a683f46fcbab 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> @@ -215,7 +215,7 @@ adc: adc at 0 {
>  &eqos {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_eqos>;
> -	phy-mode = "rgmii-txid";
> +	phy-mode = "rgmii-rxid";
>  	status = "okay";
>
>  	fixed-link {
>
> --
> 2.39.5
>


From Frank.li at nxp.com  Thu Dec 19 09:47:16 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:47:16 -0500
Subject: [PATCH 10/10] arm64: dts: imx8mp-skov: increase I2C clock
 frequency for RTC
In-Reply-To: <20241219-skov-dt-updates-v1-10-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-10-38bf80dc22df@pengutronix.de>
Message-ID: <Z2RcJCaYC2FW3Ks6@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 08:25:34AM +0100, Ahmad Fatoum wrote:
> From: Oleksij Rempel <o.rempel at pengutronix.de>
>
> The NXP PCF85063TP RTC we use is capable of up to 400 kHz of SCL clock
> frequency, so let's make use of this instead of the 100 kHz bus frequency
> we are currently using.

Increase I2C frequency to 400khz from 100kHz because NXP PCF85063TP RTC
support it.

Frank

>
> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
>  arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> index a683f46fcbab..ec7857db7bf0 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> @@ -333,7 +333,7 @@ reg_nvcc_sd2: LDO5 {
>  };
>
>  &i2c3 {
> -	clock-frequency = <100000>;
> +	clock-frequency = <400000>;
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_i2c3>;
>  	status = "okay";
>
> --
> 2.39.5
>


From a.fatoum at pengutronix.de  Thu Dec 19 09:47:35 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 18:47:35 +0100
Subject: [PATCH 07/10] arm64: dts: imx8mp-skov: configure uart1 for RS485
In-Reply-To: <Z2RbINlmO9UL+MPH@lizhi-Precision-Tower-5810>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-7-38bf80dc22df@pengutronix.de>
 <Z2RbINlmO9UL+MPH@lizhi-Precision-Tower-5810>
Message-ID: <1ced1da5-ae70-4dba-a5cc-e1e05d67b2f3@pengutronix.de>

On 19.12.24 18:42, Frank Li wrote:
> On Thu, Dec 19, 2024 at 08:25:31AM +0100, Ahmad Fatoum wrote:
>> uart1 TX, RX and RTS signals go off the base board and to a RS485
>> transceiver. Describe this in the device tree.
> 
> Look like it is not related what your did in this patch.
> 
> Add uart-has-rtscts in uart1 to ... (because ....)

because they go off to the base board to a RS485 transceiver?

>> +	/*
>> +	 * While there is no CTS line, the property "uart-has-rtscts" is still
>> +	 * the right thing to do to enable the UART to do RS485. In RS485-Mode
>> +	 * CTS isn't used anyhow and there is no dedicated property
>> +	 * "uart-has-rts-but-no-cts".
>> +	 */
>> +	uart-has-rtscts;
>>  };
>>
>>  &uart2 {
>> @@ -618,6 +625,8 @@ pinctrl_uart1: uart1grp {
>>  			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX			0x140
>>  			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX			0x140
>>  			MX8MP_IOMUXC_UART3_RXD__UART1_DTE_RTS			0x140
>> +			/* CTS pin is not connected, but needed as workaround */
> 
> what' means here! what's problem to be workaround?

See the more descriptive comment above. We don't actually have CTS connected in hardware,
but we mux it anyway, so the i.MX UART is cleared to send always.

Thanks,
Ahmad

> 
>> +			MX8MP_IOMUXC_UART3_TXD__UART1_DTE_CTS			0x140
>>  		>;
>>  	};
>>
>>
>> --
>> 2.39.5
>>
> 


-- 
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 a.fatoum at pengutronix.de  Thu Dec 19 09:49:12 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 18:49:12 +0100
Subject: [PATCH 09/10] arm64: dts: imx8mp-skov: fix phy-mode
In-Reply-To: <Z2RbwCt2zX2GyK8O@lizhi-Precision-Tower-5810>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-9-38bf80dc22df@pengutronix.de>
 <Z2RbwCt2zX2GyK8O@lizhi-Precision-Tower-5810>
Message-ID: <ab896c6a-49a2-4eda-bee3-c429fe8cef1b@pengutronix.de>

On 19.12.24 18:45, Frank Li wrote:
> On Thu, Dec 19, 2024 at 08:25:33AM +0100, Ahmad Fatoum wrote:
>> From: Oleksij Rempel <o.rempel at pengutronix.de>
>>
>> Use rgmii-rxid instead of rgmii-txid. It should have no effect here,
>> but rxid is the correct value in our case.
> 
> Use rgmii-rxid instead of rgmii-txid because ...

I consider it useful information to note that it should introduce no
functional change.

Thanks,
Ahmad

> 
> Frank
> 
>>
>> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
>> ---
>>  arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
>> index 80d212acc0c3..a683f46fcbab 100644
>> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
>> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
>> @@ -215,7 +215,7 @@ adc: adc at 0 {
>>  &eqos {
>>  	pinctrl-names = "default";
>>  	pinctrl-0 = <&pinctrl_eqos>;
>> -	phy-mode = "rgmii-txid";
>> +	phy-mode = "rgmii-rxid";
>>  	status = "okay";
>>
>>  	fixed-link {
>>
>> --
>> 2.39.5
>>
> 


-- 
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 patrice.chotard at foss.st.com  Thu Dec 19 09:29:27 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Thu, 19 Dec 2024 18:29:27 +0100
Subject: [PATCH 0/7] ARM: config: stm32: Disable useless flags
Message-ID: <20241219172934.3010875-1-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

*** BLURB HERE ***

Patrice Chotard (7):
  ARM: configs: stm32: run savedefconfig for STM32 defconfig
  ARM: configs: stm32: Disable CONFIG_COMMON_CLK_STM32MP in STM32
    defconfig
  ARM: configs: stm32: Disable CONFIG_SUSPEND in STM32 defconfig
  ARM: configs: stm32: Disable CONFIG_ADVISE_SYSCALLS in STM32 defconfig
  ARM: configs: stm32: Disable CONFIG_IO_URING in STM32 defconfig
  ARM: configs: stm32: Disable CONFIG_POSIX_TIMERS in STM32 defconfig
  ARM: configs: stm32: Disable CONFIG_GCC_PLUGINS in STM32 defconfig

 arch/arm/configs/stm32_defconfig | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

-- 
2.25.1



From patrice.chotard at foss.st.com  Thu Dec 19 09:29:34 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Thu, 19 Dec 2024 18:29:34 +0100
Subject: [PATCH 7/7] ARM: configs: stm32: Disable CONFIG_GCC_PLUGINS in STM32 defconfig
In-Reply-To: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
References: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
Message-ID: <20241219172934.3010875-8-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Disable CONFIG_GCC_PLUGINS in stm32_defconfig.
It will reduce the kernel image size for these platform which
embeds a low amount of memory.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index dbe36a59a796..77048b5e1ec4 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -24,6 +24,7 @@ CONFIG_DRAM_BASE=0x90000000
 CONFIG_XIP_KERNEL=y
 CONFIG_XIP_PHYS_ADDR=0x08008000
 # CONFIG_SUSPEND is not set
+# CONFIG_GCC_PLUGINS is not set
 CONFIG_BINFMT_FLAT=y
 # CONFIG_COREDUMP is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
-- 
2.25.1



From patrice.chotard at foss.st.com  Thu Dec 19 09:29:29 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Thu, 19 Dec 2024 18:29:29 +0100
Subject: [PATCH 2/7] ARM: configs: stm32: Disable CONFIG_COMMON_CLK_STM32MP in STM32 defconfig
In-Reply-To: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
References: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
Message-ID: <20241219172934.3010875-3-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

As stm32_defconfig is dedicated to STM32 MCUs, disable
CONFIG_COMMON_CLK_STM32MP flag which is only used by STM32 MPUs.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index d62a0c0b7ce5..9262be1e7cf6 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -60,6 +60,7 @@ CONFIG_DMADEVICES=y
 CONFIG_STM32_DMA=y
 CONFIG_STM32_DMAMUX=y
 CONFIG_STM32_MDMA=y
+# CONFIG_COMMON_CLK_STM32MP is not set
 CONFIG_IIO=y
 CONFIG_STM32_ADC_CORE=y
 CONFIG_STM32_ADC=y
-- 
2.25.1



From patrice.chotard at foss.st.com  Thu Dec 19 09:29:30 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Thu, 19 Dec 2024 18:29:30 +0100
Subject: [PATCH 3/7] ARM: configs: stm32: Disable CONFIG_SUSPEND in STM32 defconfig
In-Reply-To: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
References: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
Message-ID: <20241219172934.3010875-4-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Disable CONFIG_SUSPEND in stm32_defconfig as there is no power
management on these platforms.
It will reduce the kernel image size for these platform which
embeds a low amount of memory.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 9262be1e7cf6..0fc411e7d87c 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -20,6 +20,7 @@ CONFIG_DRAM_BASE=0x90000000
 # CONFIG_ATAGS is not set
 CONFIG_XIP_KERNEL=y
 CONFIG_XIP_PHYS_ADDR=0x08008000
+# CONFIG_SUSPEND is not set
 CONFIG_BINFMT_FLAT=y
 # CONFIG_COREDUMP is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
-- 
2.25.1



From patrice.chotard at foss.st.com  Thu Dec 19 09:29:33 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Thu, 19 Dec 2024 18:29:33 +0100
Subject: [PATCH 6/7] ARM: configs: stm32: Disable CONFIG_POSIX_TIMERS in STM32 defconfig
In-Reply-To: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
References: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
Message-ID: <20241219172934.3010875-7-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Disable CONFIG_POSIX_TIMERS in stm32_defconfig.
It will reduce the kernel image size for these platform which
embeds a low amount of memory.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 3a9bffa06d6d..dbe36a59a796 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -6,6 +6,7 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_EXPERT=y
 # CONFIG_UID16 is not set
+# CONFIG_POSIX_TIMERS is not set
 CONFIG_BASE_SMALL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
-- 
2.25.1



From patrice.chotard at foss.st.com  Thu Dec 19 09:29:32 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Thu, 19 Dec 2024 18:29:32 +0100
Subject: [PATCH 5/7] ARM: configs: stm32: Disable CONFIG_IO_URING in STM32 defconfig
In-Reply-To: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
References: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
Message-ID: <20241219172934.3010875-6-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Disable CONFIG_IO_URING in stm32_defconfig.
It will reduce the kernel image size for these platform which
embeds a low amount of memory.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 20fa929e2f9b..3a9bffa06d6d 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -12,6 +12,7 @@ CONFIG_BASE_SMALL=y
 # CONFIG_SIGNALFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+# CONFIG_IO_URING is not set
 # CONFIG_ADVISE_SYSCALLS is not set
 # CONFIG_MMU is not set
 CONFIG_ARCH_STM32=y
-- 
2.25.1



From patrice.chotard at foss.st.com  Thu Dec 19 09:29:31 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Thu, 19 Dec 2024 18:29:31 +0100
Subject: [PATCH 4/7] ARM: configs: stm32: Disable CONFIG_ADVISE_SYSCALLS in STM32 defconfig
In-Reply-To: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
References: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
Message-ID: <20241219172934.3010875-5-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Disable CONFIG_ADVISE_SYSCALLS in stm32_defconfig.
It will reduce the kernel image size for these platform which
embeds a low amount of memory.

Signed-off-by: Patrice Chotard <patrice.chotard at st.com>
---
 arch/arm/configs/stm32_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 0fc411e7d87c..20fa929e2f9b 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -12,6 +12,7 @@ CONFIG_BASE_SMALL=y
 # CONFIG_SIGNALFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+# CONFIG_ADVISE_SYSCALLS is not set
 # CONFIG_MMU is not set
 CONFIG_ARCH_STM32=y
 CONFIG_CPU_V7M_NUM_IRQ=240
-- 
2.25.1



From patrice.chotard at foss.st.com  Thu Dec 19 09:29:28 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Thu, 19 Dec 2024 18:29:28 +0100
Subject: [PATCH 1/7] ARM: configs: stm32: run savedefconfig for STM32 defconfig
In-Reply-To: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
References: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
Message-ID: <20241219172934.3010875-2-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Run 'make savedefconfig' in order to clean stm32_defconfig.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 3baec075d1ef..d62a0c0b7ce5 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -12,14 +12,11 @@ CONFIG_BASE_SMALL=y
 # CONFIG_SIGNALFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
-# CONFIG_BLK_DEV_BSG is not set
 # CONFIG_MMU is not set
 CONFIG_ARCH_STM32=y
 CONFIG_CPU_V7M_NUM_IRQ=240
 CONFIG_SET_MEM_PARAM=y
 CONFIG_DRAM_BASE=0x90000000
-CONFIG_FLASH_MEM_BASE=0x08000000
-CONFIG_FLASH_SIZE=0x00200000
 # CONFIG_ATAGS is not set
 CONFIG_XIP_KERNEL=y
 CONFIG_XIP_PHYS_ADDR=0x08008000
@@ -74,10 +71,7 @@ CONFIG_NLS=y
 CONFIG_CRC_ITU_T=y
 CONFIG_CRC7=y
 CONFIG_PRINTK_TIME=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SLUB_DEBUG is not set
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_CRYPTO=y
-- 
2.25.1



From maz at kernel.org  Thu Dec 19 09:33:46 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 17:33:46 +0000
Subject: [PATCH v2 0/4] arm64/sysreg: Get rid of *_ELx as fields for EL12 accessors
Message-ID: <20241219173351.1123087-1-maz@kernel.org>

We keep adding *_ELx definition to the sysreg as an abstraction for
the mapping between an EL1 register and its EL12 counterpart.

But nothing in the architecture has these ELx suffixes to describe
such abstraction. When they are mentioned, it always is as a shortcut
for EL1, EL2 or EL3, and never for EL12. That's because *_EL12 are
*not* registers. They are accessors, nothing else. So what we
currently have is not only bizarre, it is actively wrong.

This small series aims are injecting some sanity, by explicitly
describing EL12 registers as mappings to EL1 registers, and keeping
the ELx description as fields for the EL{1,2} registers.

* From v1:

  - Fixed the description in the first patch following Mark's proposal

  - Couple of spelling funnies being fixed

  - Collected Acks and RBs.

Marc Zyngier (4):
  arm64/sysreg: Allow a 'Mapping' descriptor for system registers
  arm64/sysreg: Get rid of the TCR2_EL1x SysregFields
  arm64/sysreg: Convert *_EL12 accessors to Mapping
  arm64/sysreg: Get rid of CPACR_ELx SysregFields

 arch/arm64/include/asm/el2_setup.h      |  6 ++--
 arch/arm64/include/asm/kvm_arm.h        |  2 --
 arch/arm64/include/asm/kvm_emulate.h    | 40 +++++++++++-----------
 arch/arm64/include/asm/kvm_nested.h     |  8 ++---
 arch/arm64/kernel/cpufeature.c          |  4 +--
 arch/arm64/kvm/at.c                     |  6 ++--
 arch/arm64/kvm/emulate-nested.c         |  2 +-
 arch/arm64/kvm/fpsimd.c                 |  2 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 +--
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  4 +--
 arch/arm64/kvm/hyp/nvhe/pkvm.c          |  2 +-
 arch/arm64/kvm/hyp/nvhe/switch.c        |  6 ++--
 arch/arm64/kvm/hyp/vhe/switch.c         | 16 ++++-----
 arch/arm64/mm/proc.S                    |  5 +--
 arch/arm64/tools/gen-sysreg.awk         |  2 +-
 arch/arm64/tools/sysreg                 | 44 ++++++++++++-------------
 16 files changed, 76 insertions(+), 77 deletions(-)

-- 
2.39.2



From maz at kernel.org  Thu Dec 19 09:33:47 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 17:33:47 +0000
Subject: [PATCH v2 1/4] arm64/sysreg: Allow a 'Mapping' descriptor for system registers
In-Reply-To: <20241219173351.1123087-1-maz@kernel.org>
References: <20241219173351.1123087-1-maz@kernel.org>
Message-ID: <20241219173351.1123087-2-maz@kernel.org>

*EL02 and *_EL12 system registers are actually only accessors for
EL0 and EL1 registers accessed from EL2 when HCR_EL2.E2H==1. They
do not have fields of their own.

To that effect, introduce a 'Mapping' entry, describing which
system register an _EL12 register maps to.

Implementation wise, this is handled the same was as Fields,
which ls only a comment.

Acked-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: Mark Brown <broonie at kernel.org
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/tools/gen-sysreg.awk |  2 +-
 arch/arm64/tools/sysreg         | 12 ++++++++++--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/tools/gen-sysreg.awk b/arch/arm64/tools/gen-sysreg.awk
index d1254a056114e..1a2afc9fdd42e 100755
--- a/arch/arm64/tools/gen-sysreg.awk
+++ b/arch/arm64/tools/gen-sysreg.awk
@@ -206,7 +206,7 @@ END {
 
 # Currently this is effectivey a comment, in future we may want to emit
 # defines for the fields.
-/^Fields/ && block_current() == "Sysreg" {
+(/^Fields/ || /^Mapping/) && block_current() == "Sysreg" {
 	expect_fields(2)
 
 	if (next_bit != 63)
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index b081b54d6d227..da3f02cdf1052 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -24,8 +24,16 @@
 #	...
 # EndEnum
 
-# Alternatively if multiple registers share the same layout then
-# a SysregFields block can be used to describe the shared layout
+# For VHE aliases (*_EL12, *_EL02) of system registers, a Mapping
+# entry describes the register the alias actually accesses:
+
+# Sysreg 	<name_EL12>	<op0> 	<op1>	<crn>	<crm>	<op2>
+# Mapping	<name_EL1>
+# EndSysreg
+
+# Where multiple system regsiters are not VHE aliases but share a
+# common layout, a SysregFields block can be used to describe the
+# shared layout:
 
 # SysregFields	<fieldsname>
 # <field>
-- 
2.39.2



From maz at kernel.org  Thu Dec 19 09:33:49 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 17:33:49 +0000
Subject: [PATCH v2 3/4] arm64/sysreg: Convert *_EL12 accessors to Mapping
In-Reply-To: <20241219173351.1123087-1-maz@kernel.org>
References: <20241219173351.1123087-1-maz@kernel.org>
Message-ID: <20241219173351.1123087-4-maz@kernel.org>

Perform a bulk convert of the remaining EL12 accessors to use the
Mapping qualifier, which makes things a bit clearer.

Reviewed-by: Mark Brown <broonie at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/tools/sysreg | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 64712e00787f9..899526e16a4cd 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2955,23 +2955,23 @@ Field	63:0	PhysicalOffset
 EndSysreg
 
 Sysreg	CPACR_EL12	3	5	1	0	2
-Fields	CPACR_ELx
+Mapping	CPACR_EL1
 EndSysreg
 
 Sysreg	ZCR_EL12	3	5	1	2	0
-Fields	ZCR_ELx
+Mapping	ZCR_EL1
 EndSysreg
 
 Sysreg	SMCR_EL12	3	5	1	2	6
-Fields	SMCR_ELx
+Mapping	SMCR_EL1
 EndSysreg
 
 Sysreg	GCSCR_EL12	3	5	2	5	0
-Fields	GCSCR_ELx
+Mapping	GCSCR_EL1
 EndSysreg
 
 Sysreg	GCSPR_EL12	3	5	2	5	1
-Fields	GCSPR_ELx
+Mapping	GCSPR_EL1
 EndSysreg
 
 Sysreg	FAR_EL12	3	5	6	0	0
@@ -2983,7 +2983,7 @@ Fields	MPAM1_ELx
 EndSysreg
 
 Sysreg	CONTEXTIDR_EL12	3	5	13	0	1
-Fields	CONTEXTIDR_ELx
+Mapping	CONTEXTIDR_EL1
 EndSysreg
 
 SysregFields TTBRx_EL1
@@ -3088,7 +3088,7 @@ Fields	PIRx_ELx
 EndSysreg
 
 Sysreg	PIRE0_EL12	3	5	10	2	2
-Fields	PIRx_ELx
+Mapping	PIRE0_EL1
 EndSysreg
 
 Sysreg	PIRE0_EL2	3	4	10	2	2
@@ -3100,7 +3100,7 @@ Fields	PIRx_ELx
 EndSysreg
 
 Sysreg	PIR_EL12	3	5	10	2	3
-Fields	PIRx_ELx
+Mapping	PIR_EL1
 EndSysreg
 
 Sysreg	PIR_EL2		3	4	10	2	3
@@ -3120,7 +3120,7 @@ Fields	PIRx_ELx
 EndSysreg
 
 Sysreg	POR_EL12	3	5	10	2	4
-Fields	PIRx_ELx
+Mapping	POR_EL1
 EndSysreg
 
 Sysreg	S2POR_EL1	3	0	10	2	5
-- 
2.39.2



From maz at kernel.org  Thu Dec 19 09:33:48 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 17:33:48 +0000
Subject: [PATCH v2 2/4] arm64/sysreg: Get rid of the TCR2_EL1x SysregFields
In-Reply-To: <20241219173351.1123087-1-maz@kernel.org>
References: <20241219173351.1123087-1-maz@kernel.org>
Message-ID: <20241219173351.1123087-3-maz@kernel.org>

TCR2_EL1x is a pretty bizarre construct, as it is shared between
TCR2_EL1 and TCR2_EL12. But the latter is obviously only an
accessor to the former.

In order to make things more consistent, upgrade TCR2_EL1x to
a full-blown sysreg definition for TCR2_EL1, and describe TCR2_EL12
as a mapping to TCR2_EL1.

This results in a couple of minor changes to the actual code.

Acked-by: Mark Rutland <mark.rutland at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 2 +-
 arch/arm64/kvm/at.c            | 6 +++---
 arch/arm64/mm/proc.S           | 5 +++--
 arch/arm64/tools/sysreg        | 8 ++------
 4 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed84..7712df48758e9 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2376,7 +2376,7 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused)
 #ifdef CONFIG_ARM64_POE
 static void cpu_enable_poe(const struct arm64_cpu_capabilities *__unused)
 {
-	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1x_E0POE);
+	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1_E0POE);
 	sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_E0POE);
 }
 #endif
diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
index 3d7eb395e33dd..3a96c96816e93 100644
--- a/arch/arm64/kvm/at.c
+++ b/arch/arm64/kvm/at.c
@@ -111,7 +111,7 @@ static bool s1pie_enabled(struct kvm_vcpu *vcpu, enum trans_regime regime)
 		return vcpu_read_sys_reg(vcpu, TCR2_EL2) & TCR2_EL2_PIE;
 	case TR_EL10:
 		return  (__vcpu_sys_reg(vcpu, HCRX_EL2) & HCRX_EL2_TCR2En) &&
-			(__vcpu_sys_reg(vcpu, TCR2_EL1) & TCR2_EL1x_PIE);
+			(__vcpu_sys_reg(vcpu, TCR2_EL1) & TCR2_EL1_PIE);
 	default:
 		BUG();
 	}
@@ -140,8 +140,8 @@ static void compute_s1poe(struct kvm_vcpu *vcpu, struct s1_walk_info *wi)
 		}
 
 		val = __vcpu_sys_reg(vcpu, TCR2_EL1);
-		wi->poe = val & TCR2_EL1x_POE;
-		wi->e0poe = val & TCR2_EL1x_E0POE;
+		wi->poe = val & TCR2_EL1_POE;
+		wi->e0poe = val & TCR2_EL1_E0POE;
 	}
 }
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index b8edc5765441e..fb30c8804f87b 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -501,7 +501,7 @@ alternative_else_nop_endif
 #ifdef CONFIG_ARM64_HAFT
 	cmp	x9, ID_AA64MMFR1_EL1_HAFDBS_HAFT
 	b.lt	1f
-	orr	tcr2, tcr2, TCR2_EL1x_HAFT
+	orr	tcr2, tcr2, TCR2_EL1_HAFT
 #endif /* CONFIG_ARM64_HAFT */
 1:
 #endif	/* CONFIG_ARM64_HW_AFDBM */
@@ -532,7 +532,8 @@ alternative_else_nop_endif
 #undef PTE_MAYBE_NG
 #undef PTE_MAYBE_SHARED
 
-	orr	tcr2, tcr2, TCR2_EL1x_PIE
+	orr	tcr2, tcr2, TCR2_EL1_PIE
+	msr	REG_TCR2_EL1, x0
 
 .Lskip_indirection:
 
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index da3f02cdf1052..64712e00787f9 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -3000,7 +3000,7 @@ Sysreg	TTBR1_EL1	3	0	2	0	1
 Fields	TTBRx_EL1
 EndSysreg
 
-SysregFields	TCR2_EL1x
+Sysreg	TCR2_EL1	3	0	2	0	3
 Res0	63:16
 Field	15	DisCH1
 Field	14	DisCH0
@@ -3014,14 +3014,10 @@ Field	3	POE
 Field	2	E0POE
 Field	1	PIE
 Field	0	PnCH
-EndSysregFields
-
-Sysreg	TCR2_EL1	3	0	2	0	3
-Fields	TCR2_EL1x
 EndSysreg
 
 Sysreg	TCR2_EL12	3	5	2	0	3
-Fields	TCR2_EL1x
+Mapping	TCR2_EL1
 EndSysreg
 
 Sysreg	TCR2_EL2	3	4	2	0	3
-- 
2.39.2



From maz at kernel.org  Thu Dec 19 09:33:50 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Dec 2024 17:33:50 +0000
Subject: [PATCH v2 4/4] arm64/sysreg: Get rid of CPACR_ELx SysregFields
In-Reply-To: <20241219173351.1123087-1-maz@kernel.org>
References: <20241219173351.1123087-1-maz@kernel.org>
Message-ID: <20241219173351.1123087-5-maz@kernel.org>

There is no such thing as CPACR_ELx in the architecture.
What we have is CPACR_EL1, for which CPTR_EL12 is an accessor.

Rename CPACR_ELx_* to CPACR_EL1_*, and fix the bit of code using
these names.

Reviewed-by: Mark Brown <broonie at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/el2_setup.h      |  6 ++--
 arch/arm64/include/asm/kvm_arm.h        |  2 --
 arch/arm64/include/asm/kvm_emulate.h    | 40 ++++++++++++-------------
 arch/arm64/include/asm/kvm_nested.h     |  8 ++---
 arch/arm64/kernel/cpufeature.c          |  2 +-
 arch/arm64/kvm/emulate-nested.c         |  2 +-
 arch/arm64/kvm/fpsimd.c                 |  2 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 +--
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  4 +--
 arch/arm64/kvm/hyp/nvhe/pkvm.c          |  2 +-
 arch/arm64/kvm/hyp/nvhe/switch.c        |  6 ++--
 arch/arm64/kvm/hyp/vhe/switch.c         | 16 +++++-----
 arch/arm64/tools/sysreg                 |  6 +---
 13 files changed, 47 insertions(+), 53 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 4ef52d7245bbb..25e1626517500 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -154,7 +154,7 @@
 /* Coprocessor traps */
 .macro __init_el2_cptr
 	__check_hvhe .LnVHE_\@, x1
-	mov	x0, #CPACR_ELx_FPEN
+	mov	x0, #CPACR_EL1_FPEN
 	msr	cpacr_el1, x0
 	b	.Lskip_set_cptr_\@
 .LnVHE_\@:
@@ -332,7 +332,7 @@
 
 	// (h)VHE case
 	mrs	x0, cpacr_el1			// Disable SVE traps
-	orr	x0, x0, #CPACR_ELx_ZEN
+	orr	x0, x0, #CPACR_EL1_ZEN
 	msr	cpacr_el1, x0
 	b	.Lskip_set_cptr_\@
 
@@ -353,7 +353,7 @@
 
 	// (h)VHE case
 	mrs	x0, cpacr_el1			// Disable SME traps
-	orr	x0, x0, #CPACR_ELx_SMEN
+	orr	x0, x0, #CPACR_EL1_SMEN
 	msr	cpacr_el1, x0
 	b	.Lskip_set_cptr_sme_\@
 
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3e0f0de1d2da8..43e365fbff0b2 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -391,8 +391,6 @@
 	ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
 	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64), ECN(ERET)
 
-#define CPACR_EL1_TTA		(1 << 28)
-
 #define kvm_mode_names				\
 	{ PSR_MODE_EL0t,	"EL0t" },	\
 	{ PSR_MODE_EL1t,	"EL1t" },	\
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index cf811009a33c9..4f1d99725f6b3 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -556,13 +556,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
 	({								\
 		u64 cptr = 0;						\
 									\
-		if ((set) & CPACR_ELx_FPEN)				\
+		if ((set) & CPACR_EL1_FPEN)				\
 			cptr |= CPTR_EL2_TFP;				\
-		if ((set) & CPACR_ELx_ZEN)				\
+		if ((set) & CPACR_EL1_ZEN)				\
 			cptr |= CPTR_EL2_TZ;				\
-		if ((set) & CPACR_ELx_SMEN)				\
+		if ((set) & CPACR_EL1_SMEN)				\
 			cptr |= CPTR_EL2_TSM;				\
-		if ((clr) & CPACR_ELx_TTA)				\
+		if ((clr) & CPACR_EL1_TTA)				\
 			cptr |= CPTR_EL2_TTA;				\
 		if ((clr) & CPTR_EL2_TAM)				\
 			cptr |= CPTR_EL2_TAM;				\
@@ -576,13 +576,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
 	({								\
 		u64 cptr = 0;						\
 									\
-		if ((clr) & CPACR_ELx_FPEN)				\
+		if ((clr) & CPACR_EL1_FPEN)				\
 			cptr |= CPTR_EL2_TFP;				\
-		if ((clr) & CPACR_ELx_ZEN)				\
+		if ((clr) & CPACR_EL1_ZEN)				\
 			cptr |= CPTR_EL2_TZ;				\
-		if ((clr) & CPACR_ELx_SMEN)				\
+		if ((clr) & CPACR_EL1_SMEN)				\
 			cptr |= CPTR_EL2_TSM;				\
-		if ((set) & CPACR_ELx_TTA)				\
+		if ((set) & CPACR_EL1_TTA)				\
 			cptr |= CPTR_EL2_TTA;				\
 		if ((set) & CPTR_EL2_TAM)				\
 			cptr |= CPTR_EL2_TAM;				\
@@ -595,13 +595,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
 #define cpacr_clear_set(clr, set)					\
 	do {								\
 		BUILD_BUG_ON((set) & CPTR_VHE_EL2_RES0);		\
-		BUILD_BUG_ON((clr) & CPACR_ELx_E0POE);			\
-		__build_check_all_or_none((clr), CPACR_ELx_FPEN);	\
-		__build_check_all_or_none((set), CPACR_ELx_FPEN);	\
-		__build_check_all_or_none((clr), CPACR_ELx_ZEN);	\
-		__build_check_all_or_none((set), CPACR_ELx_ZEN);	\
-		__build_check_all_or_none((clr), CPACR_ELx_SMEN);	\
-		__build_check_all_or_none((set), CPACR_ELx_SMEN);	\
+		BUILD_BUG_ON((clr) & CPACR_EL1_E0POE);			\
+		__build_check_all_or_none((clr), CPACR_EL1_FPEN);	\
+		__build_check_all_or_none((set), CPACR_EL1_FPEN);	\
+		__build_check_all_or_none((clr), CPACR_EL1_ZEN);	\
+		__build_check_all_or_none((set), CPACR_EL1_ZEN);	\
+		__build_check_all_or_none((clr), CPACR_EL1_SMEN);	\
+		__build_check_all_or_none((set), CPACR_EL1_SMEN);	\
 									\
 		if (has_vhe() || has_hvhe())				\
 			sysreg_clear_set(cpacr_el1, clr, set);		\
@@ -624,16 +624,16 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
 	u64 val;
 
 	if (has_vhe()) {
-		val = (CPACR_ELx_FPEN | CPACR_EL1_ZEN_EL1EN);
+		val = (CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN);
 		if (cpus_have_final_cap(ARM64_SME))
 			val |= CPACR_EL1_SMEN_EL1EN;
 	} else if (has_hvhe()) {
-		val = CPACR_ELx_FPEN;
+		val = CPACR_EL1_FPEN;
 
 		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
-			val |= CPACR_ELx_ZEN;
+			val |= CPACR_EL1_ZEN;
 		if (cpus_have_final_cap(ARM64_SME))
-			val |= CPACR_ELx_SMEN;
+			val |= CPACR_EL1_SMEN;
 	} else {
 		val = CPTR_NVHE_EL2_RES1;
 
@@ -685,7 +685,7 @@ static inline bool ____cptr_xen_trap_enabled(const struct kvm_vcpu *vcpu,
 #define __guest_hyp_cptr_xen_trap_enabled(vcpu, xen)				\
 	(!vcpu_has_nv(vcpu) ? false :						\
 	 ____cptr_xen_trap_enabled(vcpu,					\
-				   SYS_FIELD_GET(CPACR_ELx, xen,		\
+				   SYS_FIELD_GET(CPACR_EL1, xen,		\
 						 vcpu_sanitised_cptr_el2(vcpu))))
 
 static inline bool guest_hyp_fpsimd_traps_enabled(const struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 233e655227164..6cd08198bf195 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -33,14 +33,14 @@ static inline u64 translate_tcr_el2_to_tcr_el1(u64 tcr)
 
 static inline u64 translate_cptr_el2_to_cpacr_el1(u64 cptr_el2)
 {
-	u64 cpacr_el1 = CPACR_ELx_RES1;
+	u64 cpacr_el1 = CPACR_EL1_RES1;
 
 	if (cptr_el2 & CPTR_EL2_TTA)
-		cpacr_el1 |= CPACR_ELx_TTA;
+		cpacr_el1 |= CPACR_EL1_TTA;
 	if (!(cptr_el2 & CPTR_EL2_TFP))
-		cpacr_el1 |= CPACR_ELx_FPEN;
+		cpacr_el1 |= CPACR_EL1_FPEN;
 	if (!(cptr_el2 & CPTR_EL2_TZ))
-		cpacr_el1 |= CPACR_ELx_ZEN;
+		cpacr_el1 |= CPACR_EL1_ZEN;
 
 	cpacr_el1 |= cptr_el2 & (CPTR_EL2_TCPAC | CPTR_EL2_TAM);
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 7712df48758e9..6e220da3a495b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2377,7 +2377,7 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused)
 static void cpu_enable_poe(const struct arm64_cpu_capabilities *__unused)
 {
 	sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1_E0POE);
-	sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_E0POE);
+	sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_E0POE);
 }
 #endif
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 1ffbfd1c3cf2e..f1b7287e1f3c3 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -494,7 +494,7 @@ static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
 	if (!vcpu_el2_e2h_is_set(vcpu))
 		val = translate_cptr_el2_to_cpacr_el1(val);
 
-	if (val & CPACR_ELx_TTA)
+	if (val & CPACR_EL1_TTA)
 		return BEHAVE_FORWARD_RW;
 
 	return BEHAVE_HANDLE_LOCALLY;
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index ea5484ce1f3ba..98718bd65bf15 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -169,7 +169,7 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 	if (has_vhe() && system_supports_sme()) {
 		/* Also restore EL0 state seen on entry */
 		if (vcpu_get_flag(vcpu, HOST_SME_ENABLED))
-			sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_SMEN);
+			sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_SMEN);
 		else
 			sysreg_clear_set(CPACR_EL1,
 					 CPACR_EL1_SMEN_EL0EN,
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 34f53707892df..abfa6ad92e91e 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -419,9 +419,9 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 
 	/* First disable enough traps to allow us to update the registers */
 	if (sve_guest || (is_protected_kvm_enabled() && system_supports_sve()))
-		cpacr_clear_set(0, CPACR_ELx_FPEN | CPACR_ELx_ZEN);
+		cpacr_clear_set(0, CPACR_EL1_FPEN | CPACR_EL1_ZEN);
 	else
-		cpacr_clear_set(0, CPACR_ELx_FPEN);
+		cpacr_clear_set(0, CPACR_EL1_FPEN);
 	isb();
 
 	/* Write out the host state if it's in the registers */
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 6aa0b13d86e58..6c90ef6736d63 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -68,7 +68,7 @@ static void fpsimd_sve_sync(struct kvm_vcpu *vcpu)
 	if (!guest_owns_fp_regs())
 		return;
 
-	cpacr_clear_set(0, CPACR_ELx_FPEN | CPACR_ELx_ZEN);
+	cpacr_clear_set(0, CPACR_EL1_FPEN | CPACR_EL1_ZEN);
 	isb();
 
 	if (vcpu_has_sve(vcpu))
@@ -481,7 +481,7 @@ void handle_trap(struct kvm_cpu_context *host_ctxt)
 		handle_host_smc(host_ctxt);
 		break;
 	case ESR_ELx_EC_SVE:
-		cpacr_clear_set(0, CPACR_ELx_ZEN);
+		cpacr_clear_set(0, CPACR_EL1_ZEN);
 		isb();
 		sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1,
 				       SYS_ZCR_EL2);
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 071993c16de81..73e3198913272 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -68,7 +68,7 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
 	/* Trap SVE */
 	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), feature_ids)) {
 		if (has_hvhe())
-			cptr_clear |= CPACR_ELx_ZEN;
+			cptr_clear |= CPACR_EL1_ZEN;
 		else
 			cptr_set |= CPTR_EL2_TZ;
 	}
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index cc69106734ca7..0f6b01b3da5cf 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -48,14 +48,14 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 	val |= has_hvhe() ? CPACR_EL1_TTA : CPTR_EL2_TTA;
 	if (cpus_have_final_cap(ARM64_SME)) {
 		if (has_hvhe())
-			val &= ~CPACR_ELx_SMEN;
+			val &= ~CPACR_EL1_SMEN;
 		else
 			val |= CPTR_EL2_TSM;
 	}
 
 	if (!guest_owns_fp_regs()) {
 		if (has_hvhe())
-			val &= ~(CPACR_ELx_FPEN | CPACR_ELx_ZEN);
+			val &= ~(CPACR_EL1_FPEN | CPACR_EL1_ZEN);
 		else
 			val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
 
@@ -192,7 +192,7 @@ static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
 
 		/* Re-enable SVE traps if not supported for the guest vcpu. */
 		if (!vcpu_has_sve(vcpu))
-			cpacr_clear_set(CPACR_ELx_ZEN, 0);
+			cpacr_clear_set(CPACR_EL1_ZEN, 0);
 
 	} else {
 		__fpsimd_save_state(*host_data_ptr(fpsimd_state));
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 80581b1c39959..59d992455793d 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -77,12 +77,12 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
 	 * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
 	 * shift value for trapping the AMU accesses.
 	 */
-	u64 val = CPACR_ELx_TTA | CPTR_EL2_TAM;
+	u64 val = CPACR_EL1_TTA | CPTR_EL2_TAM;
 
 	if (guest_owns_fp_regs()) {
-		val |= CPACR_ELx_FPEN;
+		val |= CPACR_EL1_FPEN;
 		if (vcpu_has_sve(vcpu))
-			val |= CPACR_ELx_ZEN;
+			val |= CPACR_EL1_ZEN;
 	} else {
 		__activate_traps_fpsimd32(vcpu);
 	}
@@ -122,13 +122,13 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
 	 * hypervisor has traps enabled to dispel any illusion of something more
 	 * complicated taking place.
 	 */
-	if (!(SYS_FIELD_GET(CPACR_ELx, FPEN, cptr) & BIT(0)))
-		val &= ~CPACR_ELx_FPEN;
-	if (!(SYS_FIELD_GET(CPACR_ELx, ZEN, cptr) & BIT(0)))
-		val &= ~CPACR_ELx_ZEN;
+	if (!(SYS_FIELD_GET(CPACR_EL1, FPEN, cptr) & BIT(0)))
+		val &= ~CPACR_EL1_FPEN;
+	if (!(SYS_FIELD_GET(CPACR_EL1, ZEN, cptr) & BIT(0)))
+		val &= ~CPACR_EL1_ZEN;
 
 	if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
-		val |= cptr & CPACR_ELx_E0POE;
+		val |= cptr & CPACR_EL1_E0POE;
 
 	val |= cptr & CPTR_EL2_TCPAC;
 
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 899526e16a4cd..40a9e4e2cae69 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1986,7 +1986,7 @@ Field	1	A
 Field	0	M
 EndSysreg
 
-SysregFields	CPACR_ELx
+Sysreg	CPACR_EL1	3	0	1	0	2
 Res0	63:30
 Field	29	E0POE
 Field	28	TTA
@@ -1997,10 +1997,6 @@ Field	21:20	FPEN
 Res0	19:18
 Field	17:16	ZEN
 Res0	15:0
-EndSysregFields
-
-Sysreg	CPACR_EL1	3	0	1	0	2
-Fields	CPACR_ELx
 EndSysreg
 
 Sysreg	SMPRI_EL1	3	0	1	2	4
-- 
2.39.2



From Frank.li at nxp.com  Thu Dec 19 09:34:19 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:34:19 -0500
Subject: [PATCH 03/10] arm64: dts: imx8mp-skov: use I2C5 for DDC
In-Reply-To: <20241219-skov-dt-updates-v1-3-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-3-38bf80dc22df@pengutronix.de>
Message-ID: <Z2RZG7pAElG3TGLx@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 08:25:27AM +0100, Ahmad Fatoum wrote:
> The HDMI DDC pads can be muxed either to an i.MX I2C controller or
> to a limited I2C controller within the Designware HDMI bridge.
>
> So far we muxed the pads to the HDMI bridge, but the i.MX I2C controller
> is the better choice:

Switch to the i.MX I2C controller because

>
>   - We use DDC/CI commands for display brightness configuration, but the
>     Linux driver refuses[1] transfers to/from address 0x37, because the
>     controller doesn't support multi-byte requests.

      Designware HDMI Limited I2C controller doesn't support multi-byte
requests and display brightness configuration by DDC/CI command need it.

>
>   - The driver doesn't support I2C bus recovery, but we need that,
>     because some HDMI panels used with the board can be flaky.

      Designware HDMI Limited I2C controller doesn't support I2C bus
recovery.

>
> As the i.MX I2C controller doesn't have either of these limitations,
> let's make use of it instead.

Reduntant. can be removed.

Frank
>
> [1]: https://lore.kernel.org/all/20190722181945.244395-1-mka at chromium.org/
>
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
>  .../boot/dts/freescale/imx8mp-skov-revb-hdmi.dts   | 26 ++++++++++++++++++++--
>  1 file changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
> index c1ca69da3cb8..206116be8166 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
> @@ -9,12 +9,34 @@ / {
>  	compatible = "skov,imx8mp-skov-revb-hdmi", "fsl,imx8mp";
>  };
>
> +&i2c5 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&pinctrl_i2c5>;
> +	pinctrl-1 = <&pinctrl_i2c5_gpio>;
> +	scl-gpios = <&gpio3 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> +	sda-gpios = <&gpio3 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> +	clock-frequency = <100000>;
> +	status = "okay";
> +};
> +
>  &iomuxc {
>  	pinctrl_hdmi: hdmigrp {
>  		fsl,pins = <
> -			MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL		0x1c3
> -			MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA		0x1c3
>  			MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD			0x19
>  		>;
>  	};
> +
> +	pinctrl_i2c5: i2c5grp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_HDMI_DDC_SCL__I2C5_SCL			0x400001c2
> +			MX8MP_IOMUXC_HDMI_DDC_SDA__I2C5_SDA			0x400001c2
> +		>;
> +	};
> +
> +	pinctrl_i2c5_gpio: i2c5gpiogrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_HDMI_DDC_SCL__GPIO3_IO26			0x400001c2
> +			MX8MP_IOMUXC_HDMI_DDC_SDA__GPIO3_IO27			0x400001c2
> +		>;
> +	};
>  };
>
> --
> 2.39.5
>


From Frank.li at nxp.com  Thu Dec 19 09:35:31 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:35:31 -0500
Subject: [PATCH 04/10] arm64: dts: imx8mp-skov: describe HDMI display
 pipeline
In-Reply-To: <20241219-skov-dt-updates-v1-4-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-4-38bf80dc22df@pengutronix.de>
Message-ID: <Z2RZY/gvQ0qqDjqv@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 08:25:28AM +0100, Ahmad Fatoum wrote:
> From: Oleksij Rempel <o.rempel at pengutronix.de>
>
> Back when this device tree was first added, there were no i.MX8MP
> HDMI bindings upstream yet. This has changed now, so let's use them
> to describe the HDMI on the imx8mp-skov-revb-hdmi board.

Skip your story.
Just said

Add HDMI display pipeline for imx8mp-skov-revb-hdmi board.

Frank
>
> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
>  .../boot/dts/freescale/imx8mp-skov-revb-hdmi.dts      | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
> index 206116be8166..32a429437cbd 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
> @@ -9,6 +9,21 @@ / {
>  	compatible = "skov,imx8mp-skov-revb-hdmi", "fsl,imx8mp";
>  };
>
> +&hdmi_pvi {
> +	status = "okay";
> +};
> +
> +&hdmi_tx {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_hdmi>;
> +	ddc-i2c-bus = <&i2c5>;
> +	status = "okay";
> +};
> +
> +&hdmi_tx_phy {
> +	status = "okay";
> +};
> +
>  &i2c5 {
>  	pinctrl-names = "default", "gpio";
>  	pinctrl-0 = <&pinctrl_i2c5>;
> @@ -19,6 +34,10 @@ &i2c5 {
>  	status = "okay";
>  };
>
> +&lcdif3 {
> +	status = "okay";
> +};
> +
>  &iomuxc {
>  	pinctrl_hdmi: hdmigrp {
>  		fsl,pins = <
>
> --
> 2.39.5
>


From arnd at arndb.de  Thu Dec 19 09:35:42 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 19 Dec 2024 18:35:42 +0100
Subject: [PATCH 0/7] ARM: config: stm32: Disable useless flags
In-Reply-To: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
References: <20241219172934.3010875-1-patrice.chotard@foss.st.com>
Message-ID: <7c6dc57c-f33b-4a4b-9423-01ee2933f759@app.fastmail.com>

On Thu, Dec 19, 2024, at 18:29, patrice.chotard at foss.st.com wrote:
> From: Patrice Chotard <patrice.chotard at foss.st.com>
>
> *** BLURB HERE ***
>
> Patrice Chotard (7):
>   ARM: configs: stm32: run savedefconfig for STM32 defconfig
>   ARM: configs: stm32: Disable CONFIG_COMMON_CLK_STM32MP in STM32
>     defconfig
>   ARM: configs: stm32: Disable CONFIG_SUSPEND in STM32 defconfig
>   ARM: configs: stm32: Disable CONFIG_ADVISE_SYSCALLS in STM32 defconfig

I would structure these the other way round: you can combine patches
2-7 and just explain why you do those changes in one commit. 


For the things that have changed by themselves, you do need a lot
more explanation, so we can see that you have checked that these
don't accidentally break stuff. You can probably still do them
in a single patch, but it would be nicer to have one patch
per option that has become unavailable, changing all defconfig
files that need the same change.

     Arnd


From oliver.upton at linux.dev  Thu Dec 19 09:36:16 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 19 Dec 2024 09:36:16 -0800
Subject: [PATCH v4 0/3] KVM: arm64: Errata management for VM Live
 migration
In-Reply-To: <86a5csq93o.wl-maz@kernel.org>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
 <86a5csq93o.wl-maz@kernel.org>
Message-ID: <Z2RZkP-v2nbmmzLV@linux.dev>

On Thu, Dec 19, 2024 at 10:07:39AM +0000, Marc Zyngier wrote:
> Hi Shameer,
> 
> On Wed, 18 Dec 2024 10:53:42 +0000,
> Shameer Kolothum <shameerali.kolothum.thodi at huawei.com> wrote:
> > 
> > Hi,
> > 
> > v3 --> v4(Minor updates)
> > https://lore.kernel.org/kvmarm/20241209115311.40496-1-shameerali.kolothum.thodi at huawei.com/
> > 
> >  -Changed MIDR/REVIDR to 64 bits based on feedback from Connie
> >   and Marc(Patch #3).
> >  -Added R-by tags from Sebastian (Thanks!).
> 
> Thanks again for putting this together.
> 
> I think it would be really good to have a sample userspace
> implementation of this extension so that we can play with it for real
> before fully committing to it.
> 
> I am also wondering is we should make it mandatory that a guest is
> presented with an MIDR_EL1.Implementer value set to 0, which denotes
> SW use, and would make it plain to the guest (and crucially, guest
> userspace) that we are going to play tricks.
> 
> Thoughts?

I see no issues with giving userspace the option of doing this, but I'd
rather not enforce this to use the PV interface.

At least in a cloud setting it seems highly likely that you'd be running
a mix of guests on the same VM definition, some aware of the PV
interface and others not. If we use a software MIDR, all old VMs will
lose errata mitigations and whatever else userspace might key off of MIDR.

Userspace can make the call whether or not a VM can be migrated onto a
different implementation based on whether or not the guest used the
hypercall interface. And maybe just terminate the VM if it didn't.

-- 
Thanks,
Oliver


From Frank.li at nxp.com  Thu Dec 19 09:37:26 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:37:26 -0500
Subject: [PATCH 06/10] arm64: dts: imx8mp-skov: describe LVDS display
 pipeline
In-Reply-To: <20241219-skov-dt-updates-v1-6-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-6-38bf80dc22df@pengutronix.de>
Message-ID: <Z2RZ1o6AWGRe0ww9@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 08:25:30AM +0100, Ahmad Fatoum wrote:
> From: Oleksij Rempel <o.rempel at pengutronix.de>
>
> The Skov i.MX8MP LT6 device tree so far described the touch screen, but
> didn't describe the screen itself. Fill out these missing pieces.

Add "ti,sn65lvds822" touch screen description for i.MX8MP LT6 board.

Frank

> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
>  .../boot/dts/freescale/imx8mp-skov-revb-lt6.dts    | 60 ++++++++++++++++++++++
>  1 file changed, 60 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
> index ccbd3abedd69..baecf768a2ee 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
> @@ -8,6 +8,45 @@ / {
>  	model = "SKOV IMX8MP CPU revB - LT6";
>  	compatible = "skov,imx8mp-skov-revb-lt6", "fsl,imx8mp";
>
> +	lvds-decoder {
> +		compatible = "ti,sn65lvds822", "lvds-decoder";
> +		power-supply = <&reg_3v3>;
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port at 0 {
> +				reg = <0>;
> +
> +				in_lvds1: endpoint {
> +					data-mapping = "vesa-24";
> +					remote-endpoint = <&ldb_lvds_ch1>;
> +				};
> +			};
> +
> +			port at 1 {
> +				reg = <1>;
> +
> +				lvds_decoder_out: endpoint {
> +					remote-endpoint = <&panel_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	panel {
> +		compatible = "logictechno,lttd800480070-l6wh-rt";
> +		backlight = <&backlight>;
> +		power-supply = <&reg_tft_vcom>;
> +
> +		port {
> +			panel_in: endpoint {
> +				remote-endpoint = <&lvds_decoder_out>;
> +			};
> +		};
> +	};
> +
>  	touchscreen {
>  		compatible = "resistive-adc-touch";
>  		io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>, <&adc_ts 5>;
> @@ -78,6 +117,27 @@ channel at 5 {
>  	};
>  };
>
> +&lcdif2 {
> +	status = "okay";
> +};
> +
> +&lvds_bridge {
> +	assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>,
> +				 <&clk IMX8MP_VIDEO_PLL1>;
> +	assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
> +	/* IMX8MP_VIDEO_PLL1 = IMX8MP_CLK_MEDIA_DISP2_PIX * 2 * 7 */
> +	assigned-clock-rates = <0>, <462000000>;
> +	status = "okay";
> +
> +	ports {
> +		port at 2 {
> +			ldb_lvds_ch1: endpoint {
> +				remote-endpoint = <&in_lvds1>;
> +			};
> +		};
> +	};
> +};
> +
>  &pwm1 {
>  	status = "okay";
>  };
>
> --
> 2.39.5
>


From a.fatoum at pengutronix.de  Thu Dec 19 09:40:28 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 18:40:28 +0100
Subject: [PATCH 04/10] arm64: dts: imx8mp-skov: describe HDMI display
 pipeline
In-Reply-To: <Z2RZY/gvQ0qqDjqv@lizhi-Precision-Tower-5810>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-4-38bf80dc22df@pengutronix.de>
 <Z2RZY/gvQ0qqDjqv@lizhi-Precision-Tower-5810>
Message-ID: <f085aa33-f0b7-49e7-bbfc-d3728d3e3e8c@pengutronix.de>

Hello Frank,

On 19.12.24 18:35, Frank Li wrote:
> On Thu, Dec 19, 2024 at 08:25:28AM +0100, Ahmad Fatoum wrote:
>> From: Oleksij Rempel <o.rempel at pengutronix.de>
>>
>> Back when this device tree was first added, there were no i.MX8MP
>> HDMI bindings upstream yet. This has changed now, so let's use them
>> to describe the HDMI on the imx8mp-skov-revb-hdmi board.
> 
> Skip your story.

I am sure you don't mean it this way, but the way you phrase it
sounds a bit rude.

> Just said
> 
> Add HDMI display pipeline for imx8mp-skov-revb-hdmi board.

That's already what my commit message title says.
I am not a fan of just repeating the commit message title
in the commit message body.

Unless you have a concrete problem with my commit message,
I'd prefer to keep it the way it is.

Thanks,
Ahmad

> 
> Frank
>>
>> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
>> ---
>>  .../boot/dts/freescale/imx8mp-skov-revb-hdmi.dts      | 19 +++++++++++++++++++
>>  1 file changed, 19 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
>> index 206116be8166..32a429437cbd 100644
>> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
>> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
>> @@ -9,6 +9,21 @@ / {
>>  	compatible = "skov,imx8mp-skov-revb-hdmi", "fsl,imx8mp";
>>  };
>>
>> +&hdmi_pvi {
>> +	status = "okay";
>> +};
>> +
>> +&hdmi_tx {
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&pinctrl_hdmi>;
>> +	ddc-i2c-bus = <&i2c5>;
>> +	status = "okay";
>> +};
>> +
>> +&hdmi_tx_phy {
>> +	status = "okay";
>> +};
>> +
>>  &i2c5 {
>>  	pinctrl-names = "default", "gpio";
>>  	pinctrl-0 = <&pinctrl_i2c5>;
>> @@ -19,6 +34,10 @@ &i2c5 {
>>  	status = "okay";
>>  };
>>
>> +&lcdif3 {
>> +	status = "okay";
>> +};
>> +
>>  &iomuxc {
>>  	pinctrl_hdmi: hdmigrp {
>>  		fsl,pins = <
>>
>> --
>> 2.39.5
>>
> 


-- 
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 oliver.upton at linux.dev  Thu Dec 19 09:40:55 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 19 Dec 2024 09:40:55 -0800
Subject: [PATCH v4 3/3] arm64: paravirt: Enable errata based on
 implementation CPUs
In-Reply-To: <86bjx8q995.wl-maz@kernel.org>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
 <20241218105345.73472-4-shameerali.kolothum.thodi@huawei.com>
 <86bjx8q995.wl-maz@kernel.org>
Message-ID: <Z2RapzikZQGgeE_6@linux.dev>

On Thu, Dec 19, 2024 at 10:04:22AM +0000, Marc Zyngier wrote:
> > +void  __init pv_target_impl_cpu_init(void)
> > +{
> > +	struct arm_smccc_res res;
> > +	int index = 0, max_idx = -1;
> > +
> > +	/* Check we have already set targets */
> > +	if (target_impl_cpu_num)
> > +		return;
> > +
> > +	do {
> > +		arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID,
> > +				     index, &res);
> > +		if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
> > +			return;
> 
> Can't you probe for this as part of the KVM guest services?

+1, this needs to be predicated on actually detecting the hypervisor as
KVM.

> > +
> > +		if (max_idx < 0) {
> > +			/* res.a0 should have a valid maximum CPU implementation index */
> > +			if (res.a0 >= MAX_TARGET_IMPL_CPUS)
> > +				return;
> > +			max_idx = res.a0;
> > +		}
> > +
> > +		target_impl_cpus[index].midr = res.a1;
> > +		target_impl_cpus[index].revidr = res.a2;
> > +		index++;
> > +	} while (index <= max_idx);
> > +
> > +	target_impl_cpu_num = index;
> > +	pr_info("Number of target implementation CPUs is %d\n", target_impl_cpu_num);
> > +}
> > +
> >  int __init pv_time_init(void)
> >  {
> >  	int ret;
> 
> Independent of this, I wonder what we should output in sysfs
> (/sys/devices/system/cpu/cpu*/regs/identification/*).

It's a bit crap, but maybe implementation index 0 gets reported through
the 'main' midr/revidr files, otherwise have a directory per
implementation index of midr/revidr.

-- 
Thanks,
Oliver


From Frank.li at nxp.com  Thu Dec 19 09:42:56 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:42:56 -0500
Subject: [PATCH 07/10] arm64: dts: imx8mp-skov: configure uart1 for RS485
In-Reply-To: <20241219-skov-dt-updates-v1-7-38bf80dc22df@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-7-38bf80dc22df@pengutronix.de>
Message-ID: <Z2RbINlmO9UL+MPH@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 08:25:31AM +0100, Ahmad Fatoum wrote:
> uart1 TX, RX and RTS signals go off the base board and to a RS485
> transceiver. Describe this in the device tree.

Look like it is not related what your did in this patch.

Add uart-has-rtscts in uart1 to ... (because ....)

Frank
>
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
>  arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> index 7ae686d37dda..bce23d62cd27 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> @@ -404,6 +404,13 @@ &uart1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_uart1>;
>  	status = "okay";
> +	/*
> +	 * While there is no CTS line, the property "uart-has-rtscts" is still
> +	 * the right thing to do to enable the UART to do RS485. In RS485-Mode
> +	 * CTS isn't used anyhow and there is no dedicated property
> +	 * "uart-has-rts-but-no-cts".
> +	 */
> +	uart-has-rtscts;
>  };
>
>  &uart2 {
> @@ -618,6 +625,8 @@ pinctrl_uart1: uart1grp {
>  			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX			0x140
>  			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX			0x140
>  			MX8MP_IOMUXC_UART3_RXD__UART1_DTE_RTS			0x140
> +			/* CTS pin is not connected, but needed as workaround */

what' means here! what's problem to be workaround?

> +			MX8MP_IOMUXC_UART3_TXD__UART1_DTE_CTS			0x140
>  		>;
>  	};
>
>
> --
> 2.39.5
>


From a.fatoum at pengutronix.de  Thu Dec 19 09:43:56 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 18:43:56 +0100
Subject: [PATCH 03/10] arm64: dts: imx8mp-skov: use I2C5 for DDC
In-Reply-To: <Z2RZG7pAElG3TGLx@lizhi-Precision-Tower-5810>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-3-38bf80dc22df@pengutronix.de>
 <Z2RZG7pAElG3TGLx@lizhi-Precision-Tower-5810>
Message-ID: <a30baba6-6252-4c69-b6a7-e4099e823920@pengutronix.de>

Hello Frank,

On 19.12.24 18:34, Frank Li wrote:
> On Thu, Dec 19, 2024 at 08:25:27AM +0100, Ahmad Fatoum wrote:
>> The HDMI DDC pads can be muxed either to an i.MX I2C controller or
>> to a limited I2C controller within the Designware HDMI bridge.
>>
>> So far we muxed the pads to the HDMI bridge, but the i.MX I2C controller
>> is the better choice:
> 
> Switch to the i.MX I2C controller because
> 
>>
>>   - We use DDC/CI commands for display brightness configuration, but the
>>     Linux driver refuses[1] transfers to/from address 0x37, because the
>>     controller doesn't support multi-byte requests.
> 
>       Designware HDMI Limited I2C controller doesn't support multi-byte
> requests and display brightness configuration by DDC/CI command need it.
> 
>>
>>   - The driver doesn't support I2C bus recovery, but we need that,
>>     because some HDMI panels used with the board can be flaky.
> 
>       Designware HDMI Limited I2C controller doesn't support I2C bus
> recovery.
> 
>>
>> As the i.MX I2C controller doesn't have either of these limitations,
>> let's make use of it instead.
> 
> Reduntant. can be removed.

Sorry, I am very much open to review feedback, but I fail to see how
your subjective take improves things.

Thanks,
Ahmad




> 
> Frank
>>
>> [1]: https://lore.kernel.org/all/20190722181945.244395-1-mka at chromium.org/
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
>> ---
>>  .../boot/dts/freescale/imx8mp-skov-revb-hdmi.dts   | 26 ++++++++++++++++++++--
>>  1 file changed, 24 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
>> index c1ca69da3cb8..206116be8166 100644
>> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
>> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
>> @@ -9,12 +9,34 @@ / {
>>  	compatible = "skov,imx8mp-skov-revb-hdmi", "fsl,imx8mp";
>>  };
>>
>> +&i2c5 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&pinctrl_i2c5>;
>> +	pinctrl-1 = <&pinctrl_i2c5_gpio>;
>> +	scl-gpios = <&gpio3 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
>> +	sda-gpios = <&gpio3 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
>> +	clock-frequency = <100000>;
>> +	status = "okay";
>> +};
>> +
>>  &iomuxc {
>>  	pinctrl_hdmi: hdmigrp {
>>  		fsl,pins = <
>> -			MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL		0x1c3
>> -			MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA		0x1c3
>>  			MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD			0x19
>>  		>;
>>  	};
>> +
>> +	pinctrl_i2c5: i2c5grp {
>> +		fsl,pins = <
>> +			MX8MP_IOMUXC_HDMI_DDC_SCL__I2C5_SCL			0x400001c2
>> +			MX8MP_IOMUXC_HDMI_DDC_SDA__I2C5_SDA			0x400001c2
>> +		>;
>> +	};
>> +
>> +	pinctrl_i2c5_gpio: i2c5gpiogrp {
>> +		fsl,pins = <
>> +			MX8MP_IOMUXC_HDMI_DDC_SCL__GPIO3_IO26			0x400001c2
>> +			MX8MP_IOMUXC_HDMI_DDC_SDA__GPIO3_IO27			0x400001c2
>> +		>;
>> +	};
>>  };
>>
>> --
>> 2.39.5
>>
> 


-- 
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 a.fatoum at pengutronix.de  Thu Dec 19 09:45:24 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 18:45:24 +0100
Subject: [PATCH 06/10] arm64: dts: imx8mp-skov: describe LVDS display
 pipeline
In-Reply-To: <Z2RZ1o6AWGRe0ww9@lizhi-Precision-Tower-5810>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-6-38bf80dc22df@pengutronix.de>
 <Z2RZ1o6AWGRe0ww9@lizhi-Precision-Tower-5810>
Message-ID: <1b5236db-9a2c-475c-825c-3feae22ea32e@pengutronix.de>

On 19.12.24 18:37, Frank Li wrote:
> On Thu, Dec 19, 2024 at 08:25:30AM +0100, Ahmad Fatoum wrote:
>> From: Oleksij Rempel <o.rempel at pengutronix.de>
>>
>> The Skov i.MX8MP LT6 device tree so far described the touch screen, but
>> didn't describe the screen itself. Fill out these missing pieces.
> 
> Add "ti,sn65lvds822" touch screen description for i.MX8MP LT6 board.

This is not what this patch does. Touch screen was already described
and now the remainder is being added, just like what my message said.

Thanks,
Ahmad

> 
> Frank
> 
>> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
>> ---
>>  .../boot/dts/freescale/imx8mp-skov-revb-lt6.dts    | 60 ++++++++++++++++++++++
>>  1 file changed, 60 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
>> index ccbd3abedd69..baecf768a2ee 100644
>> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
>> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
>> @@ -8,6 +8,45 @@ / {
>>  	model = "SKOV IMX8MP CPU revB - LT6";
>>  	compatible = "skov,imx8mp-skov-revb-lt6", "fsl,imx8mp";
>>
>> +	lvds-decoder {
>> +		compatible = "ti,sn65lvds822", "lvds-decoder";
>> +		power-supply = <&reg_3v3>;
>> +
>> +		ports {
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +
>> +			port at 0 {
>> +				reg = <0>;
>> +
>> +				in_lvds1: endpoint {
>> +					data-mapping = "vesa-24";
>> +					remote-endpoint = <&ldb_lvds_ch1>;
>> +				};
>> +			};
>> +
>> +			port at 1 {
>> +				reg = <1>;
>> +
>> +				lvds_decoder_out: endpoint {
>> +					remote-endpoint = <&panel_in>;
>> +				};
>> +			};
>> +		};
>> +	};
>> +
>> +	panel {
>> +		compatible = "logictechno,lttd800480070-l6wh-rt";
>> +		backlight = <&backlight>;
>> +		power-supply = <&reg_tft_vcom>;
>> +
>> +		port {
>> +			panel_in: endpoint {
>> +				remote-endpoint = <&lvds_decoder_out>;
>> +			};
>> +		};
>> +	};
>> +
>>  	touchscreen {
>>  		compatible = "resistive-adc-touch";
>>  		io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>, <&adc_ts 5>;
>> @@ -78,6 +117,27 @@ channel at 5 {
>>  	};
>>  };
>>
>> +&lcdif2 {
>> +	status = "okay";
>> +};
>> +
>> +&lvds_bridge {
>> +	assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>,
>> +				 <&clk IMX8MP_VIDEO_PLL1>;
>> +	assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
>> +	/* IMX8MP_VIDEO_PLL1 = IMX8MP_CLK_MEDIA_DISP2_PIX * 2 * 7 */
>> +	assigned-clock-rates = <0>, <462000000>;
>> +	status = "okay";
>> +
>> +	ports {
>> +		port at 2 {
>> +			ldb_lvds_ch1: endpoint {
>> +				remote-endpoint = <&in_lvds1>;
>> +			};
>> +		};
>> +	};
>> +};
>> +
>>  &pwm1 {
>>  	status = "okay";
>>  };
>>
>> --
>> 2.39.5
>>
> 


-- 
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 Frank.li at nxp.com  Thu Dec 19 09:50:07 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:50:07 -0500
Subject: [PATCH v2 2/2] arm64: dts: imx95-19x19-evk: add ENETC 0 support
In-Reply-To: <20241219061340.1633173-3-wei.fang@nxp.com>
References: <20241219061340.1633173-1-wei.fang@nxp.com>
 <20241219061340.1633173-3-wei.fang@nxp.com>
Message-ID: <Z2Rcz9CtXuzQUMko@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 02:13:40PM +0800, Wei Fang wrote:
> Add ENETC 0 (1G ethernet port) support for i.MX95-19x19-EVK board. In
> addition, because all ENETC instances share MDIO bus, so enable EMDIO
> at the same time.
>
> Signed-off-by: Wei Fang <wei.fang at nxp.com>
> ---

Reviewed-by: Frank Li <Frank.Li at nxp.com>

>  .../boot/dts/freescale/imx95-19x19-evk.dts    | 52 +++++++++++++++++++
>  1 file changed, 52 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> index 6086cb7fa5a0..8bc066c3760c 100644
> --- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> @@ -22,6 +22,7 @@ / {
>  	compatible = "fsl,imx95-19x19-evk", "fsl,imx95";
>
>  	aliases {
> +		ethernet0 = &enetc_port0;
>  		gpio0 = &gpio1;
>  		gpio1 = &gpio2;
>  		gpio2 = &gpio3;
> @@ -193,6 +194,14 @@ sound-wm8962 {
>  	};
>  };
>
> +&enetc_port0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_enetc0>;
> +	phy-handle = <&ethphy0>;
> +	phy-mode = "rgmii-id";
> +	status = "okay";
> +};
> +
>  &flexspi1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_flexspi1>;
> @@ -338,6 +347,25 @@ &mu7 {
>  	status = "okay";
>  };
>
> +&netcmix_blk_ctrl {
> +	status = "okay";
> +};
> +
> +&netc_blk_ctrl {
> +	status = "okay";
> +};
> +
> +&netc_emdio {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_emdio>;
> +	status = "okay";
> +
> +	ethphy0: ethernet-phy at 1 {
> +		reg = <1>;
> +		realtek,clkout-disable;
> +	};
> +};
> +
>  &pcie0 {
>  	pinctrl-0 = <&pinctrl_pcie0>;
>  	pinctrl-names = "default";
> @@ -429,6 +457,30 @@ &wdog3 {
>  };
>
>  &scmi_iomuxc {
> +	pinctrl_emdio: emdiogrp{
> +		fsl,pins = <
> +			IMX95_PAD_ENET1_MDC__NETCMIX_TOP_NETC_MDC		0x57e
> +			IMX95_PAD_ENET1_MDIO__NETCMIX_TOP_NETC_MDIO		0x97e
> +		>;
> +	};
> +
> +	pinctrl_enetc0: enetc0grp {
> +		fsl,pins = <
> +			IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3		0x57e
> +			IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2		0x57e
> +			IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1		0x57e
> +			IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0		0x57e
> +			IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL	0x57e
> +			IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK	0x58e
> +			IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL	0x57e
> +			IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK	0x58e
> +			IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0		0x57e
> +			IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1		0x57e
> +			IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2		0x57e
> +			IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3		0x57e
> +		>;
> +	};
> +
>  	pinctrl_flexspi1: flexspi1grp {
>  		fsl,pins = <
>  			IMX95_PAD_XSPI1_SS0_B__FLEXSPI1_A_SS0_B			0x3fe
> --
> 2.34.1
>


From Frank.li at nxp.com  Thu Dec 19 09:50:32 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 12:50:32 -0500
Subject: [PATCH v2 1/2] arm64: dts: imx95: add NETC related nodes
In-Reply-To: <20241219061340.1633173-2-wei.fang@nxp.com>
References: <20241219061340.1633173-1-wei.fang@nxp.com>
 <20241219061340.1633173-2-wei.fang@nxp.com>
Message-ID: <Z2Rc6EOSpuY0FMty@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 02:13:39PM +0800, Wei Fang wrote:
> Add NETC related nodes for i.MX95.
>
> Signed-off-by: Wei Fang <wei.fang at nxp.com>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>  arch/arm64/boot/dts/freescale/imx95.dtsi | 94 ++++++++++++++++++++++++
>  1 file changed, 94 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
> index e9c7a8265d71..8b0eb1d835e8 100644
> --- a/arch/arm64/boot/dts/freescale/imx95.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
> @@ -1697,10 +1697,104 @@ sai2: sai at 4c880000 {
>  			status = "disabled";
>  		};
>
> +		netc_blk_ctrl: system-controller at 4cde0000 {
> +			compatible = "nxp,imx95-netc-blk-ctrl";
> +			reg = <0x0 0x4cde0000 0x0 0x10000>,
> +			      <0x0 0x4cdf0000 0x0 0x10000>,
> +			      <0x0 0x4c81000c 0x0 0x18>;
> +			reg-names = "ierb", "prb", "netcmix";
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			ranges;
> +			power-domains = <&scmi_devpd IMX95_PD_NETC>;
> +			assigned-clocks = <&scmi_clk IMX95_CLK_ENET>,
> +					  <&scmi_clk IMX95_CLK_ENETREF>;
> +			assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD2>,
> +						 <&scmi_clk IMX95_CLK_SYSPLL1_PFD0>;
> +			assigned-clock-rates = <666666666>, <250000000>;
> +			clocks = <&scmi_clk IMX95_CLK_ENET>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +
> +			netc_bus0: pcie at 4ca00000 {
> +				compatible = "pci-host-ecam-generic";
> +				reg = <0x0 0x4ca00000 0x0 0x100000>;
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				device_type = "pci";
> +				bus-range = <0x0 0x0>;
> +				msi-map = <0x0 &its 0x60 0x1>,	//ENETC0 PF
> +					  <0x10 &its 0x61 0x1>, //ENETC0 VF0
> +					  <0x20 &its 0x62 0x1>, //ENETC0 VF1
> +					  <0x40 &its 0x63 0x1>, //ENETC1 PF
> +					  <0x80 &its 0x64 0x1>, //ENETC2 PF
> +					  <0x90 &its 0x65 0x1>, //ENETC2 VF0
> +					  <0xa0 &its 0x66 0x1>, //ENETC2 VF1
> +					  <0xc0 &its 0x67 0x1>; //NETC Timer
> +					 /* ENETC0~2 and Timer BAR0 - non-prefetchable memory */
> +				ranges = <0x82000000 0x0 0x4cc00000  0x0 0x4cc00000  0x0 0xe0000
> +					 /* Timer BAR2 - prefetchable memory */
> +					 0xc2000000 0x0 0x4cd00000  0x0 0x4cd00000  0x0 0x10000
> +					 /* ENETC0~2: VF0-1 BAR0 - non-prefetchable memory */
> +					 0x82000000 0x0 0x4cd20000  0x0 0x4cd20000  0x0 0x60000
> +					 /* ENETC0~2: VF0-1 BAR2 - prefetchable memory */
> +					 0xc2000000 0x0 0x4cd80000  0x0 0x4cd80000  0x0 0x60000>;
> +
> +				enetc_port0: ethernet at 0,0 {
> +					compatible = "pci1131,e101";
> +					reg = <0x000000 0 0 0 0>;
> +					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
> +					clock-names = "ref";
> +					status = "disabled";
> +				};
> +
> +				enetc_port1: ethernet at 8,0 {
> +					compatible = "pci1131,e101";
> +					reg = <0x004000 0 0 0 0>;
> +					clocks = <&scmi_clk IMX95_CLK_ENETREF>;
> +					clock-names = "ref";
> +					status = "disabled";
> +				};
> +
> +				enetc_port2: ethernet at 10,0 {
> +					compatible = "pci1131,e101";
> +					reg = <0x008000 0 0 0 0>;
> +					status = "disabled";
> +				};
> +
> +				netc_timer: ethernet at 18,0 {
> +					reg = <0x00c000 0 0 0 0>;
> +					status = "disabled";
> +				};
> +			};
> +
> +			netc_bus1: pcie at 4cb00000 {
> +				compatible = "pci-host-ecam-generic";
> +				reg = <0x0 0x4cb00000 0x0 0x100000>;
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				device_type = "pci";
> +				bus-range = <0x1 0x1>;
> +					 /* EMDIO BAR0 - non-prefetchable memory */
> +				ranges = <0x82000000 0x0 0x4cce0000  0x0 0x4cce0000  0x0 0x20000
> +					 /* EMDIO BAR2 - prefetchable memory */
> +					 0xc2000000 0x0 0x4cd10000  0x0 0x4cd10000  0x0 0x10000>;
> +
> +				netc_emdio: mdio at 0,0 {
> +					compatible = "pci1131,ee00";
> +					reg = <0x010000 0 0 0 0>;
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +					status = "disabled";
> +				};
> +			};
> +		};
> +
>  		ddr-pmu at 4e090dc0 {
>  			compatible = "fsl,imx95-ddr-pmu", "fsl,imx93-ddr-pmu";
>  			reg = <0x0 0x4e090dc0 0x0 0x200>;
>  			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
>  		};
> +
>  	};
>  };
> --
> 2.34.1
>


From will at kernel.org  Thu Dec 19 09:51:28 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 17:51:28 +0000
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
References: <20241214005248.198803-1-dianders@chromium.org>
 <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
Message-ID: <20241219175128.GA25477@willie-the-truck>

On Fri, Dec 13, 2024 at 04:52:02PM -0800, Douglas Anderson wrote:
> The code for detecting CPUs that are vulnerable to Spectre BHB was
> based on a hardcoded list of CPU IDs that were known to be affected.
> Unfortunately, the list mostly only contained the IDs of standard ARM
> cores. The IDs for many cores that are minor variants of the standard
> ARM cores (like many Qualcomm Kyro CPUs) weren't listed. This led the
> code to assume that those variants were not affected.
> 
> Flip the code on its head and instead list CPU IDs for cores that are
> known to be _not_ affected. Now CPUs will be assumed vulnerable until
> added to the list saying that they're safe.
> 
> As of right now, the only CPU IDs added to the "unaffected" list are
> ARM Cortex A35, A53, and A55. This list was created by looking at
> older cores listed in cputype.h that weren't listed in the "affected"
> list previously.

There's a list of affected CPUs from Arm here:

https://developer.arm.com/Arm%20Security%20Center/Spectre-BHB

(obviously only covers their own designs).

So it looks like A510 and A520 should be unaffected too, although I
didn't check exhaustively. It also looks like A715 is affected but the
whitepaper doesn't tell you what version of 'k' to use...

> Unfortunately, while this solution is better than what we had before,
> it's still an imperfect solution. Specifically there are two ways to
> mitigate Spectre BHB and one of those ways is parameterized with a "k"
> value indicating how many loops are needed to mitigate. If we have an
> unknown CPU ID then we've got to guess about how to mitigate it. Since
> more cores seem to be mitigated by looping (and because it's unlikely
> that the needed FW code will be in place for FW mitigation for unknown
> cores), we'll choose looping for unknown CPUs and choose the highest
> "k" value of 32.

I don't think we should guess. Just say vulnerable.

> The downside of our guessing is that some CPUs may now report as
> "mitigated" when in reality they should need a firmware mitigation.
> We'll choose to put a WARN_ON splat in the logs in this case any time
> we had to make a guess since guessing the right mitigation is pretty
> awful. Hopefully this will encourage CPU vendors to add their CPU IDs
> to the list.

Hmm. We shouldn't have to guess here as the firmware mitigation is
discoverable. So if it's unavailable and we're running an a CPU which
needs it, then we're vulnerable.

Will


From a.fatoum at pengutronix.de  Thu Dec 19 09:51:35 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 18:51:35 +0100
Subject: [PATCH 10/10] arm64: dts: imx8mp-skov: increase I2C clock
 frequency for RTC
In-Reply-To: <Z2RcJCaYC2FW3Ks6@lizhi-Precision-Tower-5810>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-10-38bf80dc22df@pengutronix.de>
 <Z2RcJCaYC2FW3Ks6@lizhi-Precision-Tower-5810>
Message-ID: <30dbe486-7e36-426d-8fa4-3ecd83193a10@pengutronix.de>

On 19.12.24 18:47, Frank Li wrote:
> On Thu, Dec 19, 2024 at 08:25:34AM +0100, Ahmad Fatoum wrote:
>> From: Oleksij Rempel <o.rempel at pengutronix.de>
>>
>> The NXP PCF85063TP RTC we use is capable of up to 400 kHz of SCL clock
>> frequency, so let's make use of this instead of the 100 kHz bus frequency
>> we are currently using.
> 
> Increase I2C frequency to 400khz from 100kHz because NXP PCF85063TP RTC
> support it.

Unlike your other suggestions, these is no information lost by rewriting
the commit message as you suggest. I don't mind, but must admit it feels
like bikeshedding. What is your concrete objection to my commit message?

Thanks,
Ahmad


> 
> Frank
> 
>>
>> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
>> ---
>>  arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
>> index a683f46fcbab..ec7857db7bf0 100644
>> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
>> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
>> @@ -333,7 +333,7 @@ reg_nvcc_sd2: LDO5 {
>>  };
>>
>>  &i2c3 {
>> -	clock-frequency = <100000>;
>> +	clock-frequency = <400000>;
>>  	pinctrl-names = "default";
>>  	pinctrl-0 = <&pinctrl_i2c3>;
>>  	status = "okay";
>>
>> --
>> 2.39.5
>>
> 


-- 
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 jason-jh.lin at mediatek.com  Thu Dec 19 10:15:29 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 02:15:29 +0800
Subject: [PATCH v3 2/4] dt-bindings: display: mediatek: ovl: Modify rules for MT8195/MT8188
In-Reply-To: <20241219181531.4282-1-jason-jh.lin@mediatek.com>
References: <20241219181531.4282-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219181531.4282-3-jason-jh.lin@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.com>

Modify rules for both MT8195 and MT8188.
Hardware capabilities include color formats and AFBC are
changed since MT8195, stop using the settings of MT8183.

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 .../bindings/display/mediatek/mediatek,ovl.yaml          | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index 33542211507f..4f110635afb6 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -26,6 +26,7 @@ properties:
           - mediatek,mt8173-disp-ovl
           - mediatek,mt8183-disp-ovl
           - mediatek,mt8192-disp-ovl
+          - mediatek,mt8195-disp-ovl
           - mediatek,mt8195-mdp3-ovl
       - items:
           - enum:
@@ -36,16 +37,14 @@ properties:
           - enum:
               - mediatek,mt6795-disp-ovl
           - const: mediatek,mt8173-disp-ovl
-      - items:
-          - enum:
-              - mediatek,mt8188-disp-ovl
-              - mediatek,mt8195-disp-ovl
-          - const: mediatek,mt8183-disp-ovl
       - items:
           - enum:
               - mediatek,mt8186-disp-ovl
               - mediatek,mt8365-disp-ovl
           - const: mediatek,mt8192-disp-ovl
+      - items:
+          - const: mediatek,mt8188-disp-ovl
+          - const: mediatek,mt8195-disp-ovl
       - items:
           - const: mediatek,mt8188-mdp3-ovl
           - const: mediatek,mt8195-mdp3-ovl
-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 19 10:15:28 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 02:15:28 +0800
Subject: [PATCH v3 1/4] dt-bindings: display: mediatek: ovl: Add compatible strings for MT8188 MDP3
In-Reply-To: <20241219181531.4282-1-jason-jh.lin@mediatek.com>
References: <20241219181531.4282-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219181531.4282-2-jason-jh.lin@mediatek.com>

Add compatible strings for the MDP3 OVL hardware components in
MediaTek's MT8188 SoC and it is compatible with the existing
MT8195 MDP OVL components.

Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
Suggested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../devicetree/bindings/display/mediatek/mediatek,ovl.yaml     | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index 9ea796a033b2..33542211507f 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -46,6 +46,9 @@ properties:
               - mediatek,mt8186-disp-ovl
               - mediatek,mt8365-disp-ovl
           - const: mediatek,mt8192-disp-ovl
+      - items:
+          - const: mediatek,mt8188-mdp3-ovl
+          - const: mediatek,mt8195-mdp3-ovl
 
   reg:
     maxItems: 1
-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 19 10:15:30 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 02:15:30 +0800
Subject: [PATCH v3 3/4] dts: arm64: mediatek: mt8188: Update OVL compatible from MT8183 to MT8195
In-Reply-To: <20241219181531.4282-1-jason-jh.lin@mediatek.com>
References: <20241219181531.4282-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219181531.4282-4-jason-jh.lin@mediatek.com>

The OVL hardware capabilities have changed starting from MT8195,
making the MT8183 compatible no longer applicable.
Therefore, it is necessary to update the OVL compatible from MT8183 to
MT8195.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8188.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index faccc7f16259..23ec3ff6cad9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -2488,7 +2488,7 @@ jpeg_decoder: jpeg-decoder at 1a040000 {
 		};
 
 		ovl0: ovl at 1c000000 {
-			compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8183-disp-ovl";
+			compatible = "mediatek,mt8188-disp-ovl", "mediatek,mt8195-disp-ovl";
 			reg = <0 0x1c000000 0 0x1000>;
 			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
 			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 19 10:15:27 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 02:15:27 +0800
Subject: [PATCH v3 0/4] Update MT8188 OVL compatible from MT8183 to MT8195
Message-ID: <20241219181531.4282-1-jason-jh.lin@mediatek.com>

This patch series updates the compatible strings for the MediaTek OVL
in the MT8188 dts and the corresponding dt-binding.
The changes ensure that the MT8188 OVL device is correctly identified
and managed by the appropriate drivers.

The first patch is adding the MT8188 compatible strings, refer to:
- https://lore.kernel.org/all/20241218105320.38980-2-angelogioacchino.delregno at collabora.com/

The 2nd patch is resending the reviewed and acked patch from:
- https://lore.kernel.org/all/5d9e6f6c-604d-4e2d-a448-fc5b8bd24a75 at collabora.com/
and rebase it to the latest linux-next-20241212.

The 3rd and the 4th patches are updating the mt8188.dtsi and mt8195.dtsi
according to the 1st patch.

---

Change in v3:
1. Add a dt-bindings ptach for MT8188 MDP3 OVL.

Change in v2:
1. Add missing mt8195 compatible in the beginning of compatible property.
2. Add fix patch to mt8195.

---

Hsiao Chien Sung (1):
  dt-bindings: display: mediatek: ovl: Modify rules for MT8195/MT8188

Jason-JH.Lin (3):
  dt-bindings: display: mediatek: ovl: Add compatible strings for MT8188
    MDP3
  dts: arm64: mediatek: mt8188: Update OVL compatible from MT8183 to
    MT8195
  dts: arm64: mediatek: mt8195: Remove MT8183 compatible for OVL

 .../bindings/display/mediatek/mediatek,ovl.yaml      | 12 +++++++-----
 arch/arm64/boot/dts/mediatek/mt8188.dtsi             |  2 +-
 arch/arm64/boot/dts/mediatek/mt8195.dtsi             |  2 +-
 3 files changed, 9 insertions(+), 7 deletions(-)

-- 
2.43.0



From jason-jh.lin at mediatek.com  Thu Dec 19 10:15:31 2024
From: jason-jh.lin at mediatek.com (Jason-JH.Lin)
Date: Fri, 20 Dec 2024 02:15:31 +0800
Subject: [PATCH v3 4/4] dts: arm64: mediatek: mt8195: Remove MT8183 compatible for OVL
In-Reply-To: <20241219181531.4282-1-jason-jh.lin@mediatek.com>
References: <20241219181531.4282-1-jason-jh.lin@mediatek.com>
Message-ID: <20241219181531.4282-5-jason-jh.lin@mediatek.com>

The OVL hardware capabilities have changed starting from MT8195,
making the MT8183 compatible no longer applicable.
Therefore, it is necessary to remove the MT8183 compatible for OVL.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index ade685ed2190..137ee8929e01 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -3138,7 +3138,7 @@ larb20: larb at 1b010000 {
 		};
 
 		ovl0: ovl at 1c000000 {
-			compatible = "mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-ovl";
+			compatible = "mediatek,mt8195-disp-ovl";
 			reg = <0 0x1c000000 0 0x1000>;
 			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
 			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
-- 
2.43.0



From dianders at chromium.org  Thu Dec 19 10:36:16 2024
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 19 Dec 2024 10:36:16 -0800
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <20241219175128.GA25477@willie-the-truck>
References: <20241214005248.198803-1-dianders@chromium.org>
 <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid> <20241219175128.GA25477@willie-the-truck>
Message-ID: <CAD=FV=WnbMegiKDuV1HeWrGyQx42+bPZjwKQ09Q++b-fFBm7gg@mail.gmail.com>

Hi,

On Thu, Dec 19, 2024 at 9:51?AM Will Deacon <will at kernel.org> wrote:
>
> On Fri, Dec 13, 2024 at 04:52:02PM -0800, Douglas Anderson wrote:
> > The code for detecting CPUs that are vulnerable to Spectre BHB was
> > based on a hardcoded list of CPU IDs that were known to be affected.
> > Unfortunately, the list mostly only contained the IDs of standard ARM
> > cores. The IDs for many cores that are minor variants of the standard
> > ARM cores (like many Qualcomm Kyro CPUs) weren't listed. This led the
> > code to assume that those variants were not affected.
> >
> > Flip the code on its head and instead list CPU IDs for cores that are
> > known to be _not_ affected. Now CPUs will be assumed vulnerable until
> > added to the list saying that they're safe.
> >
> > As of right now, the only CPU IDs added to the "unaffected" list are
> > ARM Cortex A35, A53, and A55. This list was created by looking at
> > older cores listed in cputype.h that weren't listed in the "affected"
> > list previously.
>
> There's a list of affected CPUs from Arm here:
>
> https://developer.arm.com/Arm%20Security%20Center/Spectre-BHB
>
> (obviously only covers their own designs).
>
> So it looks like A510 and A520 should be unaffected too, although I
> didn't check exhaustively. It also looks like A715 is affected but the
> whitepaper doesn't tell you what version of 'k' to use...
>
> > Unfortunately, while this solution is better than what we had before,
> > it's still an imperfect solution. Specifically there are two ways to
> > mitigate Spectre BHB and one of those ways is parameterized with a "k"
> > value indicating how many loops are needed to mitigate. If we have an
> > unknown CPU ID then we've got to guess about how to mitigate it. Since
> > more cores seem to be mitigated by looping (and because it's unlikely
> > that the needed FW code will be in place for FW mitigation for unknown
> > cores), we'll choose looping for unknown CPUs and choose the highest
> > "k" value of 32.
>
> I don't think we should guess. Just say vulnerable.

Ah, I see. So the series won't actually _fix_ anyone, it will just
properly report that we're vulnerable. I guess that works.


> > The downside of our guessing is that some CPUs may now report as
> > "mitigated" when in reality they should need a firmware mitigation.
> > We'll choose to put a WARN_ON splat in the logs in this case any time
> > we had to make a guess since guessing the right mitigation is pretty
> > awful. Hopefully this will encourage CPU vendors to add their CPU IDs
> > to the list.
>
> Hmm. We shouldn't have to guess here as the firmware mitigation is
> discoverable. So if it's unavailable and we're running an a CPU which
> needs it, then we're vulnerable.

Sure.

-Doug


From broonie at kernel.org  Thu Dec 19 10:49:28 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Dec 2024 18:49:28 +0000
Subject: [PATCH v2 2/4] arm64/sysreg: Get rid of the TCR2_EL1x
 SysregFields
In-Reply-To: <20241219173351.1123087-3-maz@kernel.org>
References: <20241219173351.1123087-1-maz@kernel.org>
 <20241219173351.1123087-3-maz@kernel.org>
Message-ID: <53a95b37-0b46-4ec8-bad6-a431f81cdc44@sirena.org.uk>

On Thu, Dec 19, 2024 at 05:33:48PM +0000, Marc Zyngier wrote:
> TCR2_EL1x is a pretty bizarre construct, as it is shared between
> TCR2_EL1 and TCR2_EL12. But the latter is obviously only an
> accessor to the former.

Reviewed-by: Mark Brown <broonie at kernel.org>

Sorry, I thought I'd sent this on v1.
-------------- 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/20241219/f4e5762a/attachment.sig>

From conor at kernel.org  Thu Dec 19 10:58:28 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 19 Dec 2024 18:58:28 +0000
Subject: [PATCH 1/2] dt-bindings: mailbox: add support for referencing
 controllers solely by node
In-Reply-To: <d9e635c8-de05-4812-bf2b-11651f6da5c1@linaro.org>
References: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>
 <20241219-mbox_request_channel_by_args-v1-1-617a6910f842@linaro.org>
 <20241219-recent-everyone-865b19864693@wendy>
 <d9e635c8-de05-4812-bf2b-11651f6da5c1@linaro.org>
Message-ID: <20241219-strum-cheese-89e5e60d22c3@spud>

On Thu, Dec 19, 2024 at 03:42:11PM +0000, Tudor Ambarus wrote:
> Hi, Conor,
> 
> On 12/19/24 2:11 PM, Conor Dooley wrote:
> >> There are mailbox clients that can discover the mailbox channel ID at
> >> run-time. For such cases passing the channel identifier via DT is
> >> redundant. Add support for referencing controllers solely by node.
> > I don't really get your implementation, why not just allow #mbox-cells = 0?
> > That's what's done for things like fixed frequency clocks that only have
> > a single output.
> 
> Ah, indeed!
> 
> instead of:
> 	of_parse_phandle(dev->of_node, "mbox", 0);
> I can do a:
> 	of_parse_phandle_with_args(dev->of_node, "mboxes",
>                                    "#mbox-cells", 0, &of_args)
> where #mbox-cells = 0;
> 
> Or ... can I pass NULL for cells_name and make the #mbox-cells property
> optional and still keeping its requirement of being at least 1?

I think the mbox-cells = 0 approach is preferred, that property is what
marks it as a mailbox controller after all. Perhaps Rob or Krzysztof can
comment?
-------------- 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/20241219/d8dc4171/attachment.sig>

From konrad.dybcio at oss.qualcomm.com  Thu Dec 19 11:06:34 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 19 Dec 2024 20:06:34 +0100
Subject: [PATCH v10 4/4] arm64: dts: qcom:
 qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <22479c27-9265-4994-8974-9739ecbae5ee@linaro.org>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-5-quic_vikramsa@quicinc.com>
 <22479c27-9265-4994-8974-9739ecbae5ee@linaro.org>
Message-ID: <99cf5f7e-43f6-4ac4-a4a2-dc731b695572@oss.qualcomm.com>

On 17.12.2024 3:40 PM, Vladimir Zapolskiy wrote:
> On 12/17/24 16:06, Vikram Sharma wrote:
>> The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
>> Enable the IMX577 on the vision mezzanine.
>>
>> An example media-ctl pipeline for the imx577 is:
>>
>> media-ctl --reset
>> media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
>> media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
>> media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
>> media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
>> media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
>> media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
>>
>> yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0
>>
>> Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
>> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
>> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
>> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
>> Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>> ---

[...]

>> +??????? rst-pins {
>> +??????????? pins = "gpio78";
>> +??????????? function = "gpio";
>> +??????????? drive-strength = <2>;
>> +??????????? bias-pull-down;
>> +??????????? output-low;
>> +??????? };
> 
> I have doubts that it's proper to embed a reset gpio into driver's
> pinctrl suspend/resume power management.
> 
> Konrad, can you please confirm that it's really accepted?
> 
> I'd rather ask to remove this reset pin control.

There's certainly some appearances of this in the tree.

You could make the argument that it makes sense to prevent misconfiguration
(i.e. the bootloader may set the pin in input mode), but then the counter
argument is that the (Linux) gpiod APIs request OUT_LOW/HIGH, and we would
expect that the driver uses that if the GPIO is requested through
e.g. reset-gpios.

I'm not particularly sure what to recommend here. Krzysztof?

Konrad


From konrad.dybcio at oss.qualcomm.com  Thu Dec 19 11:07:19 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 19 Dec 2024 20:07:19 +0100
Subject: [PATCH v10 3/4] arm64: dts: qcom: sc7280: Add support for camss
In-Reply-To: <20241217140656.965235-4-quic_vikramsa@quicinc.com>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-4-quic_vikramsa@quicinc.com>
Message-ID: <5c4c4ee0-9e2f-4ed4-9fe4-ca41d18321bf@oss.qualcomm.com>

On 17.12.2024 3:06 PM, Vikram Sharma wrote:
> Add changes to support the camera subsystem on the SC7280.
> 
> Signed-off-by: Suresh Vankadara <quic_svankada at quicinc.com>
> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

Konrad


From dianders at chromium.org  Thu Dec 19 11:12:49 2024
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 19 Dec 2024 11:12:49 -0800
Subject: [PATCH v2 1/6] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <20241219175128.GA25477@willie-the-truck>
References: <20241214005248.198803-1-dianders@chromium.org>
 <20241213165201.v2.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid> <20241219175128.GA25477@willie-the-truck>
Message-ID: <CAD=FV=WhzZ_v1+WPpG9839JwN=fKyiY_T1M37RAU_e9cHy4XGw@mail.gmail.com>

Hi,

On Thu, Dec 19, 2024 at 9:51?AM Will Deacon <will at kernel.org> wrote:
>
> > As of right now, the only CPU IDs added to the "unaffected" list are
> > ARM Cortex A35, A53, and A55. This list was created by looking at
> > older cores listed in cputype.h that weren't listed in the "affected"
> > list previously.
>
> There's a list of affected CPUs from Arm here:
>
> https://developer.arm.com/Arm%20Security%20Center/Spectre-BHB
>
> (obviously only covers their own designs).
>
> So it looks like A510 and A520 should be unaffected too, although I
> didn't check exhaustively.

I was hoping that newer cores would hit the supports_csv2p3() check
and be considered safe, but I guess the white paper explicitly says
that A510 doesn't implement it and is still considered safe. I looked
up the TRM of A520 and it looks like it also doesn't set CSV2P3, so I
guess I'll add that one too.


> It also looks like A715 is affected but the
> whitepaper doesn't tell you what version of 'k' to use...

It doesn't? I see a "k" of 38 there. Wow, and Neoverse N2 needs 132!!!

...though I guess on newer steppings of those chips they'll just use
"clear BHB", which seems available and is the preferred mitigation?


From Frank.li at nxp.com  Thu Dec 19 11:16:02 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 14:16:02 -0500
Subject: [PATCH 10/10] arm64: dts: imx8mp-skov: increase I2C clock
 frequency for RTC
In-Reply-To: <30dbe486-7e36-426d-8fa4-3ecd83193a10@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-10-38bf80dc22df@pengutronix.de>
 <Z2RcJCaYC2FW3Ks6@lizhi-Precision-Tower-5810>
 <30dbe486-7e36-426d-8fa4-3ecd83193a10@pengutronix.de>
Message-ID: <Z2Rw8qnn9hULyh8l@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 06:51:35PM +0100, Ahmad Fatoum wrote:
> On 19.12.24 18:47, Frank Li wrote:
> > On Thu, Dec 19, 2024 at 08:25:34AM +0100, Ahmad Fatoum wrote:
> >> From: Oleksij Rempel <o.rempel at pengutronix.de>
> >>
> >> The NXP PCF85063TP RTC we use is capable of up to 400 kHz of SCL clock
> >> frequency, so let's make use of this instead of the 100 kHz bus frequency
> >> we are currently using.
> >
> > Increase I2C frequency to 400khz from 100kHz because NXP PCF85063TP RTC
> > support it.
>
> Unlike your other suggestions, these is no information lost by rewriting
> the commit message as you suggest. I don't mind, but must admit it feels
> like bikeshedding. What is your concrete objection to my commit message?

According to
https://docs.kernel.org/process/submitting-patches.html

Describe your changes in imperative mood, e.g. ?make xyzzy do frotz?
instead of ?[This patch] makes xyzzy do frotz? or
?[I] changed xyzzy to do frotz?, as if you are giving orders to the
codebase to change its behaviour.

Generally, avoid use

"this patch ..."
"let's ...."
"we do ... for ... "

Just simple said

Do ... to ...
Do ... because ...

Frank

>
> Thanks,
> Ahmad
>
>
> >
> > Frank
> >
> >>
> >> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> >> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> >> ---
> >>  arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> >> index a683f46fcbab..ec7857db7bf0 100644
> >> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> >> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> >> @@ -333,7 +333,7 @@ reg_nvcc_sd2: LDO5 {
> >>  };
> >>
> >>  &i2c3 {
> >> -	clock-frequency = <100000>;
> >> +	clock-frequency = <400000>;
> >>  	pinctrl-names = "default";
> >>  	pinctrl-0 = <&pinctrl_i2c3>;
> >>  	status = "okay";
> >>
> >> --
> >> 2.39.5
> >>
> >
>
>
> --
> 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 kees at ijzerbout.nl  Thu Dec 19 11:18:38 2024
From: kees at ijzerbout.nl (Kees Bakker)
Date: Thu, 19 Dec 2024 20:18:38 +0100
Subject: [PATCH v9 4/9] mfd: add base driver for qnap-mcu devices
In-Reply-To: <20241107114712.538976-5-heiko@sntech.de>
References: <20241107114712.538976-1-heiko@sntech.de>
 <20241107114712.538976-5-heiko@sntech.de>
Message-ID: <5d1ddf7e-2df5-4563-81e5-e0cfa7ef58da@ijzerbout.nl>

Op 07-11-2024 om 12:47 schreef Heiko Stuebner:
> These microcontroller units are used in network-attached-storage devices
> made by QNAP and provide additional functionality to the system.
>
> This adds the base driver that implements the serial protocol via
> serdev and additionally hooks into the poweroff handlers to turn
> off the parts of the system not supplied by the general PMIC.
>
> Turning off (at least the TSx33 devices using Rockchip SoCs) consists of
> two separate actions. Turning off the MCU alone does not turn off the main
> SoC and turning off only the SoC/PMIC does not turn off the hard-drives.
> Also if the MCU is not turned off, the system also won't start again until
> it is unplugged from power.
>
> So on shutdown the MCU needs to be turned off separately before the
> main PMIC.
>
> The protocol spoken by the MCU is sadly not documented, but was
> obtained by listening to the chatter on the serial port, as thankfully
> the "hal_app" program from QNAPs firmware allows triggering all/most
> MCU actions from the command line.
>
> The implementation of how to talk to the serial device got some
> inspiration from the rave-sp servdev driver.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>   MAINTAINERS                  |   6 +
>   drivers/mfd/Kconfig          |  13 ++
>   drivers/mfd/Makefile         |   2 +
>   drivers/mfd/qnap-mcu.c       | 338 +++++++++++++++++++++++++++++++++++
>   include/linux/mfd/qnap-mcu.h |  26 +++
>   5 files changed, 385 insertions(+)
>   create mode 100644 drivers/mfd/qnap-mcu.c
>   create mode 100644 include/linux/mfd/qnap-mcu.h
>
> [...]
> diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c
> new file mode 100644
> index 000000000000..4be39d8b2905
> --- /dev/null
> +++ b/drivers/mfd/qnap-mcu.c
> [...]
> +int qnap_mcu_exec(struct qnap_mcu *mcu,
> +		  const u8 *cmd_data, size_t cmd_data_size,
> +		  u8 *reply_data, size_t reply_data_size)
> +{
> +	unsigned char rx[QNAP_MCU_RX_BUFFER_SIZE];
> +	size_t length = reply_data_size + QNAP_MCU_CHECKSUM_SIZE;
> +	struct qnap_mcu_reply *reply = &mcu->reply;
> +	int ret = 0;
> +
> +	if (length > sizeof(rx)) {
> +		dev_err(&mcu->serdev->dev, "expected data too big for receive buffer");
> +		return -EINVAL;
> +	}
> +
> +	mutex_lock(&mcu->bus_lock);
> +
> +	reply->data = rx,
> +	reply->length = length,
> +	reply->received = 0,
> +	reinit_completion(&reply->done);
> +
> +	qnap_mcu_write(mcu, cmd_data, cmd_data_size);
> +
> +	serdev_device_wait_until_sent(mcu->serdev, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS));
> +
> +	if (!wait_for_completion_timeout(&reply->done, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS))) {
> +		dev_err(&mcu->serdev->dev, "Command timeout\n");
> +		ret = -ETIMEDOUT;
> +	} else {
> +		u8 crc = qnap_mcu_csum(rx, reply_data_size);
Here `rx` is still not initialized.
> +
> +		if (crc != rx[reply_data_size]) {
> +			dev_err(&mcu->serdev->dev,
> +				"Invalid Checksum received\n");
> +			ret = -EIO;
> +		} else {
> +			memcpy(reply_data, rx, reply_data_size);
> +		}
> +	}
> +
> +	mutex_unlock(&mcu->bus_lock);
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(qnap_mcu_exec);
>


From konrad.dybcio at oss.qualcomm.com  Thu Dec 19 11:20:41 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 19 Dec 2024 20:20:41 +0100
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on pre-SYSTEM_SUSPEND
 PSCI impls
In-Reply-To: <20241113080540.mtm7nu7nqrfz27yj@thinkpad>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241112180118.pcn7sf6r3mswwwxf@thinkpad>
 <ce1d2196-cf09-4d27-8b41-372948a59e89@gmail.com>
 <20241112184301.6mlwpfzzowut36pn@thinkpad>
 <eeec6eea-edb4-414e-9c11-88054e3624e4@gmail.com>
 <20241113080540.mtm7nu7nqrfz27yj@thinkpad>
Message-ID: <476c1d1f-08d4-4413-ad24-a22cca569d7f@oss.qualcomm.com>

On 13.11.2024 9:05 AM, Manivannan Sadhasivam wrote:
> On Tue, Nov 12, 2024 at 08:04:34PM +0100, Konrad Dybcio wrote:
>>
>>
>> On 11/12/24 19:43, Manivannan Sadhasivam wrote:
>>> On Tue, Nov 12, 2024 at 07:32:36PM +0100, Konrad Dybcio wrote:
>>>>
>>>>
>>>> On 11/12/24 19:01, Manivannan Sadhasivam wrote:
>>>>> On Mon, Oct 28, 2024 at 03:22:56PM +0100, Konrad Dybcio wrote:
>>>>>> Certain firmwares expose exactly what PSCI_SYSTEM_SUSPEND does through
>>>>>> CPU_SUSPEND instead. Inform Linux about that.
>>>>>> Please see the commit messages for a more detailed explanation.
>>>>>>
>>>>>
>>>>> It is still not PSCI_SYSTEM_SUSPEND though...
>>>>
>>>> It *literally* does the same thing on devices where it's exposed.
>>>>
>>>
>>> But still...
>>
>> Still-what? We can't replace the signed firmware on (unironically) tens
>> of millions of devices in the wild and this is how it exposes that sleep
>> state. This is how arm platforms did it before the PSCI spec was
>> updated and SYSTEM_SUSPEND is *still optional today*.
>>
> 
> I never asked you to replace the firmware in first place, so don't quote the
> fact I never said.

Never implied you did. I'm putting pressure on the fact that we can't
update the firmware on such devices to expose PSCI_SYSTEM_SUSPEND.

> I see this approach as a way of abusing/faking PSCI system
> suspend.

And I disagree. I can't stress this enough, calling PSCI_SYSTEM_SUSPEND
is literally internally equivalent to calling PSCI_CPU_SUSPEND(magicval).

> 
> Moreover, I heard from Bjorn that Qcom doesn't want to put the PCIe devices into
> D3Cold during system suspend for future platforms (based on their
> experimentation). So if drivers rely on this static information, then even Qcom
> cannot achieve what they want.
> 
>>
>>>>>> This is effectively a more educated follow-up to [1].
>>>>>>
>>>>>> The ultimate goal is to stop making Linux think that certain states
>>>>>> only concern cores/clusters, and consequently setting
>>>>>> pm_set_suspend/resume_via_firmware(), so that client drivers (such as
>>>>>> NVMe, see related discussion over at [2]) can make informed decisions
>>>>>> about assuming the power state of the device they govern.
>>>>>>
>>>>>> If this series gets green light, I'll push a follow-up one that wires
>>>>>> up said sleep state on Qualcomm SoCs across the board.
>>>>>>
>>>>>
>>>>> Sorry. I don't think PSCI is the right place for this. Qcom SoCs have a common
>>>>> firmware across all segments (mostly),
>>>>
>>>> This ^
>>>>
>>>>> so there is no S2R involved and only S2Idle.
>>>>
>>>> is not at all related to this ^, the "so" makes no sense.
>>>>
>>>> (also you're wrong, this *is* S2RAM)
>>>>
>>>
>>> What? Qcom SoCs supporting S2R? I'm unheard of.
>>
>> Maybe you're thinking of hibernation, which is not widely (if at all)
>> supported.
>>
> 
> Not hibernation. The Qcom platforms I've aware of all support only S2Idle. I
> don't work for Qcom, so I may be missing some insider information.

I think this is the main source of misunderstanding in this entire thread.

CXPC is S2RAM. Not S2idle.

Shallower sleep states on QC platforms are S2idle.

>>>>> If you use PSCI to implement suspend_via_firmware(), then all the SoCs
>>>>> making use of the PSCI implementation will have the same behavior. I don't think
>>>>> we would want that.
>>>>
>>>> This is an issue with the NVMe framework that is totally unrelated to this
>>>> change, see below. Also, the code only sets that on targets where such state
>>>> exists and is described.
>>>>
>>>
>>> Well, you are doing it just because you want the NVMe device to learn about the
>>> platform requirement.
>>
>> And I can't see why you're having a problem with this. It's exactly how it
>> works on x86 too. Modern Standby also shuts down storage on Windows,
>> regardless of the CPU architecture.
> 
> It is not just my problem. I'm expressing the concern that NVMe folks have and
> already expressed over the similar solutions I proposed. And I cannot just
> overrule them.

Sure, but if PSCI_SYSTEM_SUSPEND implies S2ram, why should the behavior be
different purely based on the architectural idle implementation?

Moreover, if the same platform can be booted with ACPI or DT, why should
power state switching work differently, considering both would describe
the hardware accurately?

>>>>> For instance, if a Qcom SoC is used in an android tablet with the same firmware,
>>>>> then this would allow the NVMe device to be turned off during system suspend all
>>>>> the time when user presses the lock button. And this will cause NVMe device to
>>>>> wear out faster. The said approach will work fine for non-android usecases
>>>>> though.
>>>>
>>>> The NVMe framework doesn't make a distinction between "phone screen off" and
>>>> "laptop lid closed & thrown in a bag" on *any* platform. The usecase you're
>>>> describing is not supported as of today since nobody *actually* has NVMe on a
>>>> phone that also happens to run upstream Linux.
>>>> I'm not going to solve imaginary problems.
>>>>
>>>
>>> Not just phone, NVMe device could be running on an android tablet.
>>
>> 'Could' very much makes it imaginary. There are no supported devices that
>> fall into this category.
>>
> 
> Agree that there are no products in the market (yet). But having NMVe on
> handheld devices is not something I would quote as 'imaginary'.
> 
>>> I'm not
>>> talking about an imaginary problem, but a real problem that is in a forseeable
>>> future
>>
>> Keyword: future. This issue has been on hold for years because of 'issues'
>> that are pinky promised to happen eventually, without anyone suggesting any
>> actually acceptable solutions. This just undermines progress.
>>
> 
> Not true. There are solutions suggested, but then it always takes time to reach
> consensus. One of the approach that I'm about to propose is to have a userspace
> knob that specifies whether the device can be powered down or not (leaving the
> default behavior to put them in low power state). Because, the decision to put
> the devices into power down or low power state sounds more like an userspace
> policy. It was discussed at LPC 2023.

Sure, however I believe it is perfectly reasonable to change the
default setting there based on platform capabilities.

Konrad

> 
>>> (that is also the reason why NVMe developers doesn't want to put the
>>> device into power down mode always during system suspend).
>>
>> This is the current behavior on any new x86 laptop, and has been for a
>> couple of years.
>>
>>> And with this change, you are just going to make the NVMe lifetime miserable on
>>> those platforms.
>>
>> Fearmongering and hearsay. See above.
>>
> 
> I can only wish you best of luck with this approach!
> 
> - Mani
> 


From konrad.dybcio at oss.qualcomm.com  Thu Dec 19 11:23:46 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 19 Dec 2024 20:23:46 +0100
Subject: [PATCH 3/3] firmware/psci: Allow specifying an S2RAM state
 through CPU_SUSPEND
In-Reply-To: <ZzSiM6Pn6A9e1QUD@lpieralisi>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-3-9fdd9a04b75c@oss.qualcomm.com>
 <ZzSiM6Pn6A9e1QUD@lpieralisi>
Message-ID: <761f93a0-5894-402c-b39a-ce9a65707a55@oss.qualcomm.com>

On 13.11.2024 1:57 PM, Lorenzo Pieralisi wrote:
> On Mon, Oct 28, 2024 at 03:22:59PM +0100, Konrad Dybcio wrote:
>> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>
>> Certain firmware implementations (such as the ones found on Qualcomm
>> SoCs between roughly 2015 and 2023) expose an S3-like S2RAM state
>> through the CPU_SUSPEND call.
>>
>> This works exactly like SYSTEM_SUSPEND. The PSCI spec describes that
>> call as optional (and only introduced in PSCIv1.0), so not all
>> platforms expose it.
>>
>> Marking a DT-described "domain-idle-state" as such isn't currently
>> well accounted for in the PSCI idle topology infrastructure: the
>> cpuidle and genpd framework are deeply intertwined, and trying to
>> separate them would cause more havoc than good.
> 
> I don't understand what you mean here please elaborate.
> 
> The part of the story I understand is that you have a system (well,
> firmware for an extended set of systems) that does not implement
> SYSTEM_SUSPEND but can reach a S2R like system state through the
> CPU_SUSPEND call. Firmware works in OS-initiated mode, idle-states
> should allow you to define idle states that allow the system to
> enter the S2R state through CPUidle.
> 
> Please explain to me what's missing.
> 
>> Instead, allow the specifying of a single CPU_SUSPEND sleep param
>> under the /psci node that shall be treated exactly like SYSTEM_SUSPEND
>> from Linux's POV. As a bonus, this way we also don't have to fight
>> with the genpd idle governor to avoid taking the S3-like state into
>> consideration.
> 
> That's not acceptable. I want to understand what's preventing this
> system to enter that state through suspend2idle and the mainline code.

The answer to both is:

Linux doesn't get to know we're entering a S2RAM state and can't make
different decisions based on that, if said low power state is exposed
though cpuidle.

We e.g. can't expect all hardware to come back up functional after
entering such state.

Konrad


From Frank.li at nxp.com  Thu Dec 19 11:24:51 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 14:24:51 -0500
Subject: [PATCH 06/10] arm64: dts: imx8mp-skov: describe LVDS display
 pipeline
In-Reply-To: <1b5236db-9a2c-475c-825c-3feae22ea32e@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-6-38bf80dc22df@pengutronix.de>
 <Z2RZ1o6AWGRe0ww9@lizhi-Precision-Tower-5810>
 <1b5236db-9a2c-475c-825c-3feae22ea32e@pengutronix.de>
Message-ID: <Z2RzA5S/ch1YDdUD@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 06:45:24PM +0100, Ahmad Fatoum wrote:
> On 19.12.24 18:37, Frank Li wrote:
> > On Thu, Dec 19, 2024 at 08:25:30AM +0100, Ahmad Fatoum wrote:
> >> From: Oleksij Rempel <o.rempel at pengutronix.de>
> >>
> >> The Skov i.MX8MP LT6 device tree so far described the touch screen, but
> >> didn't describe the screen itself. Fill out these missing pieces.
> >
> > Add "ti,sn65lvds822" touch screen description for i.MX8MP LT6 board.
>
> This is not what this patch does. Touch screen was already described
> and now the remainder is being added, just like what my message said.

My main means, use below order to descript commit message

Add ... for ...

Frank

>
> Thanks,
> Ahmad
>
> >
> > Frank
> >
> >> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> >> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> >> ---
> >>  .../boot/dts/freescale/imx8mp-skov-revb-lt6.dts    | 60 ++++++++++++++++++++++
> >>  1 file changed, 60 insertions(+)
> >>
> >> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
> >> index ccbd3abedd69..baecf768a2ee 100644
> >> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
> >> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-lt6.dts
> >> @@ -8,6 +8,45 @@ / {
> >>  	model = "SKOV IMX8MP CPU revB - LT6";
> >>  	compatible = "skov,imx8mp-skov-revb-lt6", "fsl,imx8mp";
> >>
> >> +	lvds-decoder {
> >> +		compatible = "ti,sn65lvds822", "lvds-decoder";
> >> +		power-supply = <&reg_3v3>;
> >> +
> >> +		ports {
> >> +			#address-cells = <1>;
> >> +			#size-cells = <0>;
> >> +
> >> +			port at 0 {
> >> +				reg = <0>;
> >> +
> >> +				in_lvds1: endpoint {
> >> +					data-mapping = "vesa-24";
> >> +					remote-endpoint = <&ldb_lvds_ch1>;
> >> +				};
> >> +			};
> >> +
> >> +			port at 1 {
> >> +				reg = <1>;
> >> +
> >> +				lvds_decoder_out: endpoint {
> >> +					remote-endpoint = <&panel_in>;
> >> +				};
> >> +			};
> >> +		};
> >> +	};
> >> +
> >> +	panel {
> >> +		compatible = "logictechno,lttd800480070-l6wh-rt";
> >> +		backlight = <&backlight>;
> >> +		power-supply = <&reg_tft_vcom>;
> >> +
> >> +		port {
> >> +			panel_in: endpoint {
> >> +				remote-endpoint = <&lvds_decoder_out>;
> >> +			};
> >> +		};
> >> +	};
> >> +
> >>  	touchscreen {
> >>  		compatible = "resistive-adc-touch";
> >>  		io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>, <&adc_ts 5>;
> >> @@ -78,6 +117,27 @@ channel at 5 {
> >>  	};
> >>  };
> >>
> >> +&lcdif2 {
> >> +	status = "okay";
> >> +};
> >> +
> >> +&lvds_bridge {
> >> +	assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>,
> >> +				 <&clk IMX8MP_VIDEO_PLL1>;
> >> +	assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
> >> +	/* IMX8MP_VIDEO_PLL1 = IMX8MP_CLK_MEDIA_DISP2_PIX * 2 * 7 */
> >> +	assigned-clock-rates = <0>, <462000000>;
> >> +	status = "okay";
> >> +
> >> +	ports {
> >> +		port at 2 {
> >> +			ldb_lvds_ch1: endpoint {
> >> +				remote-endpoint = <&in_lvds1>;
> >> +			};
> >> +		};
> >> +	};
> >> +};
> >> +
> >>  &pwm1 {
> >>  	status = "okay";
> >>  };
> >>
> >> --
> >> 2.39.5
> >>
> >
>
>
> --
> 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 konrad.dybcio at oss.qualcomm.com  Thu Dec 19 11:26:51 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 19 Dec 2024 20:26:51 +0100
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on pre-SYSTEM_SUSPEND
 PSCI impls
In-Reply-To: <20241113165329590-0800.eberman@hu-eberman-lv.qualcomm.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241113165329590-0800.eberman@hu-eberman-lv.qualcomm.com>
Message-ID: <e4509104-c809-4d45-bdbb-a2d754a816db@oss.qualcomm.com>

On 14.11.2024 2:10 AM, Elliot Berman wrote:
> On Mon, Oct 28, 2024 at 03:22:56PM +0100, Konrad Dybcio wrote:
>> Certain firmwares expose exactly what PSCI_SYSTEM_SUSPEND does through
>> CPU_SUSPEND instead. Inform Linux about that.
>> Please see the commit messages for a more detailed explanation.
>>
>> This is effectively a more educated follow-up to [1].
>>
>> The ultimate goal is to stop making Linux think that certain states
>> only concern cores/clusters, and consequently setting
>> pm_set_suspend/resume_via_firmware(), so that client drivers (such as
>> NVMe, see related discussion over at [2]) can make informed decisions
>> about assuming the power state of the device they govern.
>>
>> If this series gets green light, I'll push a follow-up one that wires
>> up said sleep state on Qualcomm SoCs across the board.
>>
>> [1] https://lore.kernel.org/linux-arm-kernel/20231227-topic-psci_fw_sus-v1-0-6910add70bf3 at linaro.org/
>> [2] https://lore.kernel.org/linux-nvme/20241024-topic-nvmequirk-v1-1-51249999d409 at oss.qualcomm.com/
>>
> 
> I got a bit confused, but I think I might've pieced it together. Konrad
> wants to support s2ram (not clear why) on Qualcomm SoCs from 2015-2023.
> On these SoCs, PSCI_SYSTEM_SUSPEND (s2ram) isn't supported but doing
> s2idle gets you the same effect. You'd like s2ram to work, so you
> provide a way to replace the PSCI_SYSTEM_SUSPEND param with
> (effectively) the CPU_SUSPEND command. If this is the wrong
> understanding, please correct me.
> 
> Could patch 2 be sent separately? I think it seems fine without the
> rest of the series.
> 
> I'm not sure why you'd like to support s2ram. Is it *only* that you'd
> like to be able to set pm_set_supend/resume_via_firmware()? I hope this
> doesn't sound silly: what if you register a platform_s2idle_ops for the
> relevant SoCs which calls pm_set_suspend/resume_via_firwmare()?

S2RAM is what you get after entering a certain state, but currently
it's presented as just another (s2idle) idle state.

That means some hardware that may need to be reinitialized, isn't as
Linux has no clue it might have lost power.

One of such cases is the PCIe block, with storage drivers specifically
looking for pm_suspend_via_firmware, but that's unfortunately not the
whole list.

Konrad


From Frank.li at nxp.com  Thu Dec 19 11:27:28 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 14:27:28 -0500
Subject: [PATCH 03/10] arm64: dts: imx8mp-skov: use I2C5 for DDC
In-Reply-To: <a30baba6-6252-4c69-b6a7-e4099e823920@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-3-38bf80dc22df@pengutronix.de>
 <Z2RZG7pAElG3TGLx@lizhi-Precision-Tower-5810>
 <a30baba6-6252-4c69-b6a7-e4099e823920@pengutronix.de>
Message-ID: <Z2RzoITPUmZFoX09@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 06:43:56PM +0100, Ahmad Fatoum wrote:
> Hello Frank,
>
> On 19.12.24 18:34, Frank Li wrote:
> > On Thu, Dec 19, 2024 at 08:25:27AM +0100, Ahmad Fatoum wrote:
> >> The HDMI DDC pads can be muxed either to an i.MX I2C controller or
> >> to a limited I2C controller within the Designware HDMI bridge.
> >>
> >> So far we muxed the pads to the HDMI bridge, but the i.MX I2C controller
> >> is the better choice:
> >
> > Switch to the i.MX I2C controller because
> >
> >>
> >>   - We use DDC/CI commands for display brightness configuration, but the
> >>     Linux driver refuses[1] transfers to/from address 0x37, because the
> >>     controller doesn't support multi-byte requests.
> >
> >       Designware HDMI Limited I2C controller doesn't support multi-byte
> > requests and display brightness configuration by DDC/CI command need it.
> >
> >>
> >>   - The driver doesn't support I2C bus recovery, but we need that,
> >>     because some HDMI panels used with the board can be flaky.
> >
> >       Designware HDMI Limited I2C controller doesn't support I2C bus
> > recovery.
> >
> >>
> >> As the i.MX I2C controller doesn't have either of these limitations,
> >> let's make use of it instead.
> >
> > Reduntant. can be removed.
>
> Sorry, I am very much open to review feedback, but I fail to see how
> your subjective take improves things.

Ref https://docs.kernel.org/process/submitting-patches.html

"Describe your changes in imperative mood, e.g. ?make xyzzy do frotz?
instead of ?[This patch] makes xyzzy do frotz? or ?[I] changed xyzzy to do
frotz?, as if you are giving orders to the codebase to change its behaviour."

Avoid use "we(same as "I" in above example) ..."

Frank

>
> Thanks,
> Ahmad
>
>
>
>
> >
> > Frank
> >>
> >> [1]: https://lore.kernel.org/all/20190722181945.244395-1-mka at chromium.org/
> >>
> >> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> >> ---
> >>  .../boot/dts/freescale/imx8mp-skov-revb-hdmi.dts   | 26 ++++++++++++++++++++--
> >>  1 file changed, 24 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
> >> index c1ca69da3cb8..206116be8166 100644
> >> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
> >> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revb-hdmi.dts
> >> @@ -9,12 +9,34 @@ / {
> >>  	compatible = "skov,imx8mp-skov-revb-hdmi", "fsl,imx8mp";
> >>  };
> >>
> >> +&i2c5 {
> >> +	pinctrl-names = "default", "gpio";
> >> +	pinctrl-0 = <&pinctrl_i2c5>;
> >> +	pinctrl-1 = <&pinctrl_i2c5_gpio>;
> >> +	scl-gpios = <&gpio3 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> >> +	sda-gpios = <&gpio3 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> >> +	clock-frequency = <100000>;
> >> +	status = "okay";
> >> +};
> >> +
> >>  &iomuxc {
> >>  	pinctrl_hdmi: hdmigrp {
> >>  		fsl,pins = <
> >> -			MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL		0x1c3
> >> -			MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA		0x1c3
> >>  			MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD			0x19
> >>  		>;
> >>  	};
> >> +
> >> +	pinctrl_i2c5: i2c5grp {
> >> +		fsl,pins = <
> >> +			MX8MP_IOMUXC_HDMI_DDC_SCL__I2C5_SCL			0x400001c2
> >> +			MX8MP_IOMUXC_HDMI_DDC_SDA__I2C5_SDA			0x400001c2
> >> +		>;
> >> +	};
> >> +
> >> +	pinctrl_i2c5_gpio: i2c5gpiogrp {
> >> +		fsl,pins = <
> >> +			MX8MP_IOMUXC_HDMI_DDC_SCL__GPIO3_IO26			0x400001c2
> >> +			MX8MP_IOMUXC_HDMI_DDC_SDA__GPIO3_IO27			0x400001c2
> >> +		>;
> >> +	};
> >>  };
> >>
> >> --
> >> 2.39.5
> >>
> >
>
>
> --
> 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 vladimir.zapolskiy at linaro.org  Thu Dec 19 11:32:21 2024
From: vladimir.zapolskiy at linaro.org (Vladimir Zapolskiy)
Date: Thu, 19 Dec 2024 21:32:21 +0200
Subject: [PATCH v10 4/4] arm64: dts: qcom:
 qcs6490-rb3gen2-vision-mezzanine: Add vision mezzanine
In-Reply-To: <99cf5f7e-43f6-4ac4-a4a2-dc731b695572@oss.qualcomm.com>
References: <20241217140656.965235-1-quic_vikramsa@quicinc.com>
 <20241217140656.965235-5-quic_vikramsa@quicinc.com>
 <22479c27-9265-4994-8974-9739ecbae5ee@linaro.org>
 <99cf5f7e-43f6-4ac4-a4a2-dc731b695572@oss.qualcomm.com>
Message-ID: <c7253f5f-eb4a-4636-b0f9-7d284a2f5a8d@linaro.org>

On 12/19/24 21:06, Konrad Dybcio wrote:
> On 17.12.2024 3:40 PM, Vladimir Zapolskiy wrote:
>> On 12/17/24 16:06, Vikram Sharma wrote:
>>> The Vision Mezzanine for the RB3 ships with an imx577 camera sensor.
>>> Enable the IMX577 on the vision mezzanine.
>>>
>>> An example media-ctl pipeline for the imx577 is:
>>>
>>> media-ctl --reset
>>> media-ctl -v -V '"imx577 '19-001a'":0[fmt:SRGGB10/4056x3040 field:none]'
>>> media-ctl -V '"msm_csiphy3":0[fmt:SRGGB10/4056x3040]'
>>> media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4056x3040]'
>>> media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4056x3040]'
>>> media-ctl -l '"msm_csiphy3":1->"msm_csid0":0[1]'
>>> media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
>>>
>>> yavta -B capture-mplane -c -I -n 5 -f SRGGB10P -s 4056x3040 -F /dev/video0
>>>
>>> Signed-off-by: Hariram Purushothaman <quic_hariramp at quicinc.com>
>>> Signed-off-by: Vikram Sharma <quic_vikramsa at quicinc.com>
>>> Signed-off-by: Trishansh Bhardwaj <quic_tbhardwa at quicinc.com>
>>> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
>>> Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>> ---
> 
> [...]
> 
>>> +        rst-pins {
>>> +            pins = "gpio78";
>>> +            function = "gpio";
>>> +            drive-strength = <2>;
>>> +            bias-pull-down;
>>> +            output-low;
>>> +        };
>>
>> I have doubts that it's proper to embed a reset gpio into driver's
>> pinctrl suspend/resume power management.
>>
>> Konrad, can you please confirm that it's really accepted?
>>
>> I'd rather ask to remove this reset pin control.
> 
> There's certainly some appearances of this in the tree.
> 
> You could make the argument that it makes sense to prevent misconfiguration
> (i.e. the bootloader may set the pin in input mode), but then the counter
> argument is that the (Linux) gpiod APIs request OUT_LOW/HIGH, and we would
> expect that the driver uses that if the GPIO is requested through
> e.g. reset-gpios.
> 
> I'm not particularly sure what to recommend here. Krzysztof?
> 

I'm worried by a possibility that a device reset/shutdown control GPIO could
be turned off by entering the "sleep" pinctrl setup. If a particular GPIO/pin
is off, is it still continuously functional as a control GPIO of some device?
I believe it is not anymore in general, this is my concern here.

--
Best wishes,
Vladimir


From konrad.dybcio at oss.qualcomm.com  Thu Dec 19 11:37:54 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 19 Dec 2024 20:37:54 +0100
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on pre-SYSTEM_SUSPEND
 PSCI impls
In-Reply-To: <CAPDyKFq5+HWmHK4E4ERx1rb8O4mubHGqRHP8AAiq2KyZyX1GSQ@mail.gmail.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <CAPDyKFpGrw+vOs=-TxfChBeORjzkpaL_iVB08MtmaC4sFNKzcg@mail.gmail.com>
 <72add0ff-db2a-44f8-b4af-0b5fe5f65f20@oss.qualcomm.com>
 <CAPDyKFq5+HWmHK4E4ERx1rb8O4mubHGqRHP8AAiq2KyZyX1GSQ@mail.gmail.com>
Message-ID: <c970cf8d-a174-4c10-85ca-00f66056a621@oss.qualcomm.com>

On 6.12.2024 10:53 AM, Ulf Hansson wrote:
> + Maulik, Vincent
> 
> On Thu, 5 Dec 2024 at 21:34, Konrad Dybcio
> <konrad.dybcio at oss.qualcomm.com> wrote:
>>
>> On 14.11.2024 4:30 PM, Ulf Hansson wrote:
>>> On Mon, 28 Oct 2024 at 15:24, Konrad Dybcio <konradybcio at kernel.org> wrote:
>>>>
>>>> Certain firmwares expose exactly what PSCI_SYSTEM_SUSPEND does through
>>>> CPU_SUSPEND instead. Inform Linux about that.
>>>> Please see the commit messages for a more detailed explanation.
>>>>
>>>> This is effectively a more educated follow-up to [1].
>>>>
>>>> The ultimate goal is to stop making Linux think that certain states
>>>> only concern cores/clusters, and consequently setting
>>>> pm_set_suspend/resume_via_firmware(), so that client drivers (such as
>>>> NVMe, see related discussion over at [2]) can make informed decisions
>>>> about assuming the power state of the device they govern.
>>>
>>> In my opinion, this is not really the correct way to do it. Using
>>> pm_set_suspend/resume_via_firmware() works fine for x86/ACPI, but not
>>> for PSCI like this. Let me elaborate. If the NVMe storage device is
>>> sharing the same power-rail as the CPU cluster, then yes we should use
>>> PSCI to control it. But is that really the case? If so, there are in
>>> principle two ways forward to deal with this correctly.
>>>
>>> 1) If PSCI OSI mode is being used, the corresponding NVMe storage
>>> device should be hooked up to the CPU PM cluster domain via genpd and
>>> controlled as any other devices sharing the cluster-rail. In this way,
>>> genpd together with the cpuidle-psci-domain can decide whether it's
>>> okay to turn off the cluster. I believe this is the preferred way, but
>>> 2) would work fine too.
>>>
>>> 2) If PSCI PC mode is being used, a separate channel/interface to the
>>> FW (like SCMI or rpmh in the QC case), should inform the FW whether
>>> NVMe needs the power to it. This information should then be taken into
>>> account by the PSCI FW when it decides what low-power-state to enter,
>>> which ultimately means whether the cluster-rail can be turned off or
>>> not.
>>
>> This assumes PSCI only governs the CPU power rail. But what I'd
>> guesstimate is that in most implementations if system-level suspend is
>> there at all (no matter through which call), as per the spec, it at
>> least also projects onto the DDR power state (like in this i.mx
>> impl here [1]), or some uncore peripherals (like in Tegra's case with
>> some secure element being toggled at [2])
> 
> Right, I certainly understand the above. There are different parts of
> an SoC that may be sharing the same power-island as the CPUs.
> 
> The question here is whether the NVMe storage device is part of that
> power-island too on some QC SoCs?

Yes, but not exclusively (i.e. there can also be other voltage rails or
similar that may or may not be manged by Linux, depending on the SoC)

>>> Assuming PSCI OSI mode is used here. Then if 1) doesn't work for you,
>>> please elaborate on why, so we can help to make it work, as it should.
>>
>> On Qualcomm platforms, RPMh is the central authority when it comes
>> to power governance, but by design, the CPUs must be off (and with a
>> specific magic cookie) for the RPMh hardware to consider powering off
>> very power hungry parts of the system, such as general i/o rails.
> 
> Right, that is why the "qcom,rpmh-rsc" device in many cases belongs to
> the cluster-power-domain (for PSCI). This allows "qcom,rpmh-rsc" to
> control the "last-man" activities and prevent deeper PSCI states
> if/when necessary.

Problem is, today we only describe the RSC connected to the CPU cluster.
Newer SoCs have multiple RSCs, which long story short allow for certain
IP blocks to operate and have their power managed without the CPU block
being involved, or even online.

The CPU RSC can only reliably probe the CPU online status, as all other
IPs can be requested to stay powered from an external entity (e.g. a DSP,
secure world and similar), so the driver can only do its best to try and
prevent obviously-going-to-fail idle entries when CPUs are online.

>> So again, PSCI must be fed a specific value for the rest of the hw
>> to react. The "S2RAM state" isn't really a cpuidle state, because
>> it doesn't differ from many shallower states as far as the cpu/cluster
>> are concerned. If that all isn't in place, the platform never actually
>> enters any "real" sleep state, other than "CPU and some controllable
>> IP blocks are runtime-suspended".
> 
> We recently discussed this, offlist, with Maulik - and I think we need
> some more clarity around what is actually going on here.
> 
> In principle, it looks to me that using S2I with just another deeper
> idlestate specified (with another psci-suspend-parameter, representing
> a deeper state) should work fine, at least theoretically. Of course,
> we may not be able to use that idlestate during regular
> cpuidle/runtime but only during S2I, which we need to control in a
> smooth way and that is not currently supported (but can be fixed
> easily, I think).
> 
> In the end, it's the psci-suspend-parameter that is given to the PSCI
> FW that informs about what state we can enter.
> 
> That said, using S2I may not work without updating the PSCI FW, of
> course. For example, there may be FW limitations that require the
> boot-CPU( CPU0) to be the last one for these deeper low-power-states.
> Whether that is just a FW limitation or whether there are some
> additional HW constraints that enforce this, needs to be clarified.

Yeah, not being able to runtime-idle into that state is one issue,
and another one being successfully entering the S2RAM state may
require us to reinitialize some hardware. Currently, Linux has no
way of knowing that state is any different from the rest, but
marking it as S2RAM would allow to check for PM_SUSPEND_MEM vs
PM_SUSPEND_TO_IDLE

>> This effectively is very close to what ACPI+x86 do - there's a
>> co-processor/firmware that does a lot of things behind your back and
>> all you can do is *ask* it to change some handwavily-defined P/Cstate
>> that affects a huge chunk of silicon.
> 
> Yep, there are similarities.
> 
> However, ACPI is for generic device power management. PSCI requires
> something additional, such as ARM SCMI or QC's rpm/rsc interface.

Right, we're not yet fully there with "for_each_device(fw_shut_down())"

Konrad

> 
>>
>> Konrad
>>
>> [1] https://github.com/nxp-imx/imx-atf/blob/lf_v2.6/plat/imx/imx8m/imx8mp/imx8mp_lpa_psci.c#L474
>> [2] https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c#L214
>>
> 
> Kind regards
> Uffe


From konrad.dybcio at oss.qualcomm.com  Thu Dec 19 11:43:27 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 19 Dec 2024 20:43:27 +0100
Subject: [PATCH 1/3] dt-bindings: arm,psci: Allow S2RAM power_state
 parameter description
In-Reply-To: <Z1LQOmEfFy640PjG@bogus>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
 <Z1LQOmEfFy640PjG@bogus>
Message-ID: <54cc4221-ba5f-4741-9033-20874265ca01@oss.qualcomm.com>

On 6.12.2024 11:21 AM, Sudeep Holla wrote:
> On Mon, Oct 28, 2024 at 03:22:57PM +0100, Konrad Dybcio wrote:
>> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>
>> Certain firmware implementations (such as the ones found on Qualcomm
>> SoCs between roughly 2015 and 2023) expose an S3-like S2RAM state
>> through the CPU_SUSPEND call, as opposed to exposing PSCIv1.0's
>> optional PSCI_SYSTEM_SUSPEND.
>>
> 
> If so, can you elaborate why s2idle doesn't work as an alternative to what
> you are hacking up here.

Please see other branches of this thread

> 
>> This really doesn't work well with the model where we associate all
>> calls to CPU_SUSPEND with cpuidle. Allow specifying a single special
>> CPU_SUSPEND suspend parameter value that is to be treated just like
>> SYSTEM_SUSPEND from the OS's point of view.
>>
>> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>> ---
>>  Documentation/devicetree/bindings/arm/psci.yaml | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml
>> index cbb012e217ab80c1ca88e611e7acc06c6d56fad0..a6901878697c8e1ec1cbfed62298ae3bc58f2501 100644
>> --- a/Documentation/devicetree/bindings/arm/psci.yaml
>> +++ b/Documentation/devicetree/bindings/arm/psci.yaml
>> @@ -98,6 +98,12 @@ properties:
>>        [1] Kernel documentation - ARM idle states bindings
>>          Documentation/devicetree/bindings/cpu/idle-states.yaml
>>  
>> +  arm,psci-s2ram-param:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description:
>> +      power_state parameter denoting the S2RAM/S3-like system suspend state
> 
> Yet another NACK as this corresponds to PSCI SYSTEM_SUSPEND and as per
> specification it takes no such parameter. This is just misleading.
> 

Yeah PSCI_SYSTEM_SUSPEND takes care of this on platforms that expose it.

DEN0022F.b Section 6.5. recommends that CPU_SUSPEND StateID includes
a field for system-level power down states. This binding change only
adds a way for DT-based platforms to associate such state with S2RAM
suspend.

That may be a bit Linux-specific whereas bindings are supposed to be
OS-agnostic, but since we effectively want one PSCI state for deep
suspend regardless of the OS, I would think this kind of hint is fine.

Konrad 



From heiko at sntech.de  Thu Dec 19 11:43:08 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 19 Dec 2024 20:43:08 +0100
Subject: [PATCH v9 4/9] mfd: add base driver for qnap-mcu devices
In-Reply-To: <5d1ddf7e-2df5-4563-81e5-e0cfa7ef58da@ijzerbout.nl>
References: <20241107114712.538976-1-heiko@sntech.de>
 <20241107114712.538976-5-heiko@sntech.de>
 <5d1ddf7e-2df5-4563-81e5-e0cfa7ef58da@ijzerbout.nl>
Message-ID: <3130486.CbtlEUcBR6@diego>

Hi Kees,

Am Donnerstag, 19. Dezember 2024, 20:18:38 CET schrieb Kees Bakker:
> Op 07-11-2024 om 12:47 schreef Heiko Stuebner:
> > These microcontroller units are used in network-attached-storage devices
> > made by QNAP and provide additional functionality to the system.
> >
> > This adds the base driver that implements the serial protocol via
> > serdev and additionally hooks into the poweroff handlers to turn
> > off the parts of the system not supplied by the general PMIC.
> >
> > Turning off (at least the TSx33 devices using Rockchip SoCs) consists of
> > two separate actions. Turning off the MCU alone does not turn off the main
> > SoC and turning off only the SoC/PMIC does not turn off the hard-drives.
> > Also if the MCU is not turned off, the system also won't start again until
> > it is unplugged from power.
> >
> > So on shutdown the MCU needs to be turned off separately before the
> > main PMIC.
> >
> > The protocol spoken by the MCU is sadly not documented, but was
> > obtained by listening to the chatter on the serial port, as thankfully
> > the "hal_app" program from QNAPs firmware allows triggering all/most
> > MCU actions from the command line.
> >
> > The implementation of how to talk to the serial device got some
> > inspiration from the rave-sp servdev driver.
> >
> > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > ---
> >   MAINTAINERS                  |   6 +
> >   drivers/mfd/Kconfig          |  13 ++
> >   drivers/mfd/Makefile         |   2 +
> >   drivers/mfd/qnap-mcu.c       | 338 +++++++++++++++++++++++++++++++++++
> >   include/linux/mfd/qnap-mcu.h |  26 +++
> >   5 files changed, 385 insertions(+)
> >   create mode 100644 drivers/mfd/qnap-mcu.c
> >   create mode 100644 include/linux/mfd/qnap-mcu.h
> >
> > [...]
> > diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c
> > new file mode 100644
> > index 000000000000..4be39d8b2905
> > --- /dev/null
> > +++ b/drivers/mfd/qnap-mcu.c
> > [...]
> > +int qnap_mcu_exec(struct qnap_mcu *mcu,
> > +		  const u8 *cmd_data, size_t cmd_data_size,
> > +		  u8 *reply_data, size_t reply_data_size)
> > +{
> > +	unsigned char rx[QNAP_MCU_RX_BUFFER_SIZE];
> > +	size_t length = reply_data_size + QNAP_MCU_CHECKSUM_SIZE;
> > +	struct qnap_mcu_reply *reply = &mcu->reply;
> > +	int ret = 0;
> > +
> > +	if (length > sizeof(rx)) {
> > +		dev_err(&mcu->serdev->dev, "expected data too big for receive buffer");
> > +		return -EINVAL;
> > +	}
> > +
> > +	mutex_lock(&mcu->bus_lock);
> > +
> > +	reply->data = rx,
> > +	reply->length = length,
> > +	reply->received = 0,
> > +	reinit_completion(&reply->done);
> > +
> > +	qnap_mcu_write(mcu, cmd_data, cmd_data_size);
> > +
> > +	serdev_device_wait_until_sent(mcu->serdev, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS));
> > +
> > +	if (!wait_for_completion_timeout(&reply->done, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS))) {
> > +		dev_err(&mcu->serdev->dev, "Command timeout\n");
> > +		ret = -ETIMEDOUT;
> > +	} else {
> > +		u8 crc = qnap_mcu_csum(rx, reply_data_size);
> Here `rx` is still not initialized.

The MCU works in a way that a sent command always causes "reply_data_size"
bytes to be returned.

So for each qnap_mcu_write() above we know that this amount of bytes has
been returned (and thus written into rx) if the completion above finishes
sucessfully.

"rx" is assigned to reply->data above (same as the expected received size).
When characters are received on the serial line, this will trigger
qnap_mcu_receive_buf() from the serdev and thus fill those elements in rx.

So if we land at the qnap_mcu_csum() call, we do have received the expected
amount of bytes from the serdev and thus rx is filled accordingly.

If we don't receive the needed amount of bytes, we end up in the timeout
above that.

What did I miss?


Heiko

> > +
> > +		if (crc != rx[reply_data_size]) {
> > +			dev_err(&mcu->serdev->dev,
> > +				"Invalid Checksum received\n");
> > +			ret = -EIO;
> > +		} else {
> > +			memcpy(reply_data, rx, reply_data_size);
> > +		}
> > +	}
> > +
> > +	mutex_unlock(&mcu->bus_lock);
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(qnap_mcu_exec);
> >
> 






From will at kernel.org  Thu Dec 19 11:47:11 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 19:47:11 +0000
Subject: [PATCH] iommu/tegra241-cmdqv: Read SMMU IDR1.CMDQS instead of hardcoding
In-Reply-To: <20241219051421.1850267-1-nicolinc@nvidia.com>
References: <20241219051421.1850267-1-nicolinc@nvidia.com>
Message-ID: <173462305169.3912600.1369814969067145717.b4-ty@kernel.org>

On Wed, 18 Dec 2024 21:14:21 -0800, Nicolin Chen wrote:
> The hardware limitation "max=19" actually comes from SMMU Command Queue.
> So, it'd be more natural for tegra241-cmdqv driver to read it out rather
> than hardcoding it itself.
> 
> This is not an issue yet for a kernel on a baremetal system, but a guest
> kernel setting the queue base/size in form of IPA/gPA might result in a
> noncontiguous queue in the physical address space, if underlying physical
> pages backing up the guest RAM aren't contiguous entirely: e.g. 2MB-page
> backed guest RAM cannot guarantee a contiguous queue if it is 8MB (capped
> to VCMDQ_LOG2SIZE_MAX=19). This might lead to command errors when HW does
> linear-read from a noncontiguous queue memory.
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/1] iommu/tegra241-cmdqv: Read SMMU IDR1.CMDQS instead of hardcoding
      https://git.kernel.org/will/c/e94dc6ddda8d

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Thu Dec 19 11:47:12 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 19:47:12 +0000
Subject: [PATCH] perf/arm-cmn: Permit more exhaustive groups
In-Reply-To: <bdfd1e58dac449e407c5cacfd6bf8577dc0a5899.1733943898.git.robin.murphy@arm.com>
References: <bdfd1e58dac449e407c5cacfd6bf8577dc0a5899.1733943898.git.robin.murphy@arm.com>
Message-ID: <173462242272.3910338.7654467298369824108.b4-ty@kernel.org>

On Wed, 11 Dec 2024 19:04:58 +0000, Robin Murphy wrote:
> The group validation logic still somewhat assumes the original CMN-600
> case of events counting globally, such that if one tries to group 9
> events where the first 8 target a single DTC domain, the 9th will be
> rejected because *a* DTC domain is full, even though it might only
> target other non-overlapping domains and thus still be schedulable.
> Improve matters by only counting the DTCs that the new event actually
> needs (as arm_cmn_val_add_event() was already clever enough to do).
> 
> [...]

Applied to will (for-next/perf), thanks!

[1/1] perf/arm-cmn: Permit more exhaustive groups
      https://git.kernel.org/will/c/e49ecdf79a60

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Thu Dec 19 11:47:13 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 19:47:13 +0000
Subject: [PATCH] iommu/io-pgtable-arm: Fix cfg reading in arm_lpae_concat_mandatory()
In-Reply-To: <20241215200412.561400-1-smostafa@google.com>
References: <20241215200412.561400-1-smostafa@google.com>
Message-ID: <173462288874.3912129.4288094387004225028.b4-ty@kernel.org>

On Sun, 15 Dec 2024 20:04:11 +0000, Mostafa Saleh wrote:
> I messed up the newly introduced function arm_lpae_concat_mandatory()
> where ias/oas are read from the io_pgtable_cfg copy in arm_lpae_io_pgtable.
> 
> However, this copy is set later in alloc_io_pgtable_ops() after alloc()
> function was called.
> 
> I didn?t catch that with my selftesting as arm_lpae_io_pgtable is
> allocated from kmalloc, which was caching old configs.
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/1] iommu/io-pgtable-arm: Fix cfg reading in arm_lpae_concat_mandatory()
      https://git.kernel.org/will/c/b7b8a6305557

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Thu Dec 19 11:47:14 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 19:47:14 +0000
Subject: [PATCH RESEND v3] perf: imx9_perf: Introduce AXI filter version to refactor the driver and better extension
In-Reply-To: <20241212065708.1353513-1-xu.yang_2@nxp.com>
References: <20241212065708.1353513-1-xu.yang_2@nxp.com>
Message-ID: <173462343305.3913401.15165333302624535869.b4-ty@kernel.org>

On Thu, 12 Dec 2024 14:57:08 +0800, Xu Yang wrote:
> The imx93 is the first supported DDR PMU that supports read transaction,
> write transaction and read beats events which corresponding respecitively
> to counter 2, 3 and 4.
> 
> However, transaction-based AXI match has low accuracy when get total bits
> compared to beats-based. And imx93 doesn't assign AXI_ID to each master.
> So axi filter is not used widely on imx93. This could be regards as AXI
> filter version 1.
> 
> [...]

Applied to will (for-next/perf), thanks!

[1/1] perf: imx9_perf: Introduce AXI filter version to refactor the driver and better extension
      https://git.kernel.org/will/c/f3edf03a4c59

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From conor at kernel.org  Thu Dec 19 11:49:46 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 19 Dec 2024 19:49:46 +0000
Subject: [PATCH 1/6] dt-bindings: clock: imx8m: document
 nominal/overdrive properties
In-Reply-To: <20241219-imx8m-clk-v1-1-cfaffa087da6@pengutronix.de>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
 <20241219-imx8m-clk-v1-1-cfaffa087da6@pengutronix.de>
Message-ID: <20241219-lash-lather-31443ced0e0c@spud>

On Thu, Dec 19, 2024 at 08:27:32AM +0100, Ahmad Fatoum wrote:
> The imx8m-clock.yaml binding covers the clock controller inside all
> of the i.MX8M Q/M/N/P SoCs. All of them have in common that they
> support two operating modes: nominal and overdrive mode.

This implies that only the two modes you mention are possible, but you
leave the option open to a dts author to use either. How come?

Makes it seem like we only need one of these, for whatever the
non-default option is?

> 
> While the overdrive mode allows for higher frequencies for many IPs,
> the nominal mode needs a lower SoC voltage, thereby reducing
> heat generation and power usage.
> 
> In any case, software should respect the maximum clock rate limits
> described in the datasheet for each of the two operating modes.
> 
> To allow device tree consumers to enforce these limits, document two new
> optional properties that can be used to sanity check the clock tree.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
>  Documentation/devicetree/bindings/clock/imx8m-clock.yaml | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
> index c643d4a81478..a6ae5257ef53 100644
> --- a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
> +++ b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
> @@ -43,6 +43,14 @@ properties:
>        ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8m-clock.h
>        for the full list of i.MX8M clock IDs.
>  
> +  fsl,nominal-mode:
> +    description: Set if SoC is operated in nominal mode
> +    $ref: /schemas/types.yaml#/definitions/flag
> +
> +  fsl,overdrive-mode:
> +    description: Set if SoC is operated in overdrive mode
> +    $ref: /schemas/types.yaml#/definitions/flag
> +
>  required:
>    - compatible
>    - reg
> @@ -95,6 +103,12 @@ allOf:
>              - const: clk_ext2
>              - const: clk_ext3
>              - const: clk_ext4
> +  - if:
> +      required:
> +        - fsl,overdrive-mode
> +    then:
> +      properties:
> +        fsl,nominal-mode: false
>  
>  additionalProperties: false
>  
> 
> -- 
> 2.39.5
> 
-------------- 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/20241219/9d2f8c52/attachment.sig>

From kees at ijzerbout.nl  Thu Dec 19 11:51:41 2024
From: kees at ijzerbout.nl (Kees Bakker)
Date: Thu, 19 Dec 2024 20:51:41 +0100
Subject: [PATCH v9 4/9] mfd: add base driver for qnap-mcu devices
In-Reply-To: <3130486.CbtlEUcBR6@diego>
References: <20241107114712.538976-1-heiko@sntech.de>
 <20241107114712.538976-5-heiko@sntech.de>
 <5d1ddf7e-2df5-4563-81e5-e0cfa7ef58da@ijzerbout.nl>
 <3130486.CbtlEUcBR6@diego>
Message-ID: <4cecc705-84ab-44d5-8725-eb973254f257@ijzerbout.nl>

Op 19-12-2024 om 20:43 schreef Heiko St?bner:
> Hi Kees,
>
> Am Donnerstag, 19. Dezember 2024, 20:18:38 CET schrieb Kees Bakker:
>> Op 07-11-2024 om 12:47 schreef Heiko Stuebner:
>>> These microcontroller units are used in network-attached-storage devices
>>> made by QNAP and provide additional functionality to the system.
>>>
>>> This adds the base driver that implements the serial protocol via
>>> serdev and additionally hooks into the poweroff handlers to turn
>>> off the parts of the system not supplied by the general PMIC.
>>>
>>> Turning off (at least the TSx33 devices using Rockchip SoCs) consists of
>>> two separate actions. Turning off the MCU alone does not turn off the main
>>> SoC and turning off only the SoC/PMIC does not turn off the hard-drives.
>>> Also if the MCU is not turned off, the system also won't start again until
>>> it is unplugged from power.
>>>
>>> So on shutdown the MCU needs to be turned off separately before the
>>> main PMIC.
>>>
>>> The protocol spoken by the MCU is sadly not documented, but was
>>> obtained by listening to the chatter on the serial port, as thankfully
>>> the "hal_app" program from QNAPs firmware allows triggering all/most
>>> MCU actions from the command line.
>>>
>>> The implementation of how to talk to the serial device got some
>>> inspiration from the rave-sp servdev driver.
>>>
>>> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
>>> ---
>>>    MAINTAINERS                  |   6 +
>>>    drivers/mfd/Kconfig          |  13 ++
>>>    drivers/mfd/Makefile         |   2 +
>>>    drivers/mfd/qnap-mcu.c       | 338 +++++++++++++++++++++++++++++++++++
>>>    include/linux/mfd/qnap-mcu.h |  26 +++
>>>    5 files changed, 385 insertions(+)
>>>    create mode 100644 drivers/mfd/qnap-mcu.c
>>>    create mode 100644 include/linux/mfd/qnap-mcu.h
>>>
>>> [...]
>>> diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c
>>> new file mode 100644
>>> index 000000000000..4be39d8b2905
>>> --- /dev/null
>>> +++ b/drivers/mfd/qnap-mcu.c
>>> [...]
>>> +int qnap_mcu_exec(struct qnap_mcu *mcu,
>>> +		  const u8 *cmd_data, size_t cmd_data_size,
>>> +		  u8 *reply_data, size_t reply_data_size)
>>> +{
>>> +	unsigned char rx[QNAP_MCU_RX_BUFFER_SIZE];
>>> +	size_t length = reply_data_size + QNAP_MCU_CHECKSUM_SIZE;
>>> +	struct qnap_mcu_reply *reply = &mcu->reply;
>>> +	int ret = 0;
>>> +
>>> +	if (length > sizeof(rx)) {
>>> +		dev_err(&mcu->serdev->dev, "expected data too big for receive buffer");
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	mutex_lock(&mcu->bus_lock);
>>> +
>>> +	reply->data = rx,
>>> +	reply->length = length,
>>> +	reply->received = 0,
>>> +	reinit_completion(&reply->done);
>>> +
>>> +	qnap_mcu_write(mcu, cmd_data, cmd_data_size);
>>> +
>>> +	serdev_device_wait_until_sent(mcu->serdev, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS));
>>> +
>>> +	if (!wait_for_completion_timeout(&reply->done, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS))) {
>>> +		dev_err(&mcu->serdev->dev, "Command timeout\n");
>>> +		ret = -ETIMEDOUT;
>>> +	} else {
>>> +		u8 crc = qnap_mcu_csum(rx, reply_data_size);
>> Here `rx` is still not initialized.
> The MCU works in a way that a sent command always causes "reply_data_size"
> bytes to be returned.
>
> So for each qnap_mcu_write() above we know that this amount of bytes has
> been returned (and thus written into rx) if the completion above finishes
> sucessfully.
>
> "rx" is assigned to reply->data above (same as the expected received size).
> When characters are received on the serial line, this will trigger
> qnap_mcu_receive_buf() from the serdev and thus fill those elements in rx.
>
> So if we land at the qnap_mcu_csum() call, we do have received the expected
> amount of bytes from the serdev and thus rx is filled accordingly.
>
> If we don't receive the needed amount of bytes, we end up in the timeout
> above that.
>
> What did I miss?
Sorry, my fault. I missed the essential part of the external event (external
for this function that is).
Thanks for explaining.
>
>
> Heiko
>
>>> +
>>> +		if (crc != rx[reply_data_size]) {
>>> +			dev_err(&mcu->serdev->dev,
>>> +				"Invalid Checksum received\n");
>>> +			ret = -EIO;
>>> +		} else {
>>> +			memcpy(reply_data, rx, reply_data_size);
>>> +		}
>>> +	}
>>> +
>>> +	mutex_unlock(&mcu->bus_lock);
>>> +	return ret;
>>> +}
>>> +EXPORT_SYMBOL_GPL(qnap_mcu_exec);
>>>
>
>
>



From will at kernel.org  Thu Dec 19 11:47:07 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 19:47:07 +0000
Subject: [PATCH 0/2] docs: arm64: Document MDCR_EL3 boot requirements
In-Reply-To: <20241211065425.1106683-1-anshuman.khandual@arm.com>
References: <20241211065425.1106683-1-anshuman.khandual@arm.com>
Message-ID: <173462766799.3925724.13780644464677755383.b4-ty@kernel.org>

On Wed, 11 Dec 2024 12:24:23 +0530, Anshuman Khandual wrote:
> This series adds missing MDCR_EL3 boot requirements for debug and pmu
> registers that are currently being accessed in the kernel. Please refer
> the following link for some earlier discussions on this.
> 
> https://lore.kernel.org/all/ZxfOeqyb3RvsdYbU at J2N7QTR9R3/
> 
> This series applies on v6.13-rc1
> 
> [...]

Applied to arm64 (for-next/docs), thanks!

[1/2] docs: arm64: Document EL3 requirements for cpu debug architecture
      https://git.kernel.org/arm64/c/3e5be4e11aac
[2/2] docs: arm64: Document EL3 requirements for FEAT_PMUv3
      https://git.kernel.org/arm64/c/1e4a5e3679cc

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Thu Dec 19 11:47:08 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 19:47:08 +0000
Subject: [PATCH v3 0/6] arm64: Clean up and simplify PA space size handling
In-Reply-To: <20241212081841.2168124-8-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
Message-ID: <173462903479.3930132.9019084013797129885.b4-ty@kernel.org>

On Thu, 12 Dec 2024 09:18:42 +0100, Ard Biesheuvel wrote:
> This series addresses a number of buglets related to how we handle the
> size of the physical address space when building LPA2 capable kernels:
> 
> - reject 52-bit physical addressess in the mapping routines when LPA2 is
>   configured but not available at runtime
> - ensure that TCR.IPS is not set to 52-bits if LPA2 is not supported
> - ensure that TCR_EL2.PS and DS match the host, regardless of whether
>   LPA2 is available at stage 2
> - don't rely on kvm_get_parange() and invalid physical addresses as
>   control flags in the pKVM page donation APIs
> 
> [...]

Applied to arm64 (for-next/mm), thanks!

[1/6] arm64/mm: Reduce PA space to 48 bits when LPA2 is not enabled
      https://git.kernel.org/arm64/c/bf74bb73cd87
[2/6] arm64/mm: Override PARange for !LPA2 and use it consistently
      https://git.kernel.org/arm64/c/62cffa496aac
[3/6] arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
      https://git.kernel.org/arm64/c/f0da16992aef
[4/6] arm64/kvm: Avoid invalid physical addresses to signal owner updates
      https://git.kernel.org/arm64/c/9d86c3c97434
[5/6] arm64: Kconfig: force ARM64_PAN=y when enabling TTBR0 sw PAN
      https://git.kernel.org/arm64/c/92b6919d7fb2
[6/6] arm64/mm: Drop configurable 48-bit physical address space limit
      https://git.kernel.org/arm64/c/32d053d6f5e9

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Thu Dec 19 11:47:10 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Dec 2024 19:47:10 +0000
Subject: [PATCH v2 0/4] arm64/sysreg: Get rid of *_ELx as fields for EL12 accessors
In-Reply-To: <20241219173351.1123087-1-maz@kernel.org>
References: <20241219173351.1123087-1-maz@kernel.org>
Message-ID: <173463125944.3934348.13870436616394837034.b4-ty@kernel.org>

On Thu, 19 Dec 2024 17:33:46 +0000, Marc Zyngier wrote:
> We keep adding *_ELx definition to the sysreg as an abstraction for
> the mapping between an EL1 register and its EL12 counterpart.
> 
> But nothing in the architecture has these ELx suffixes to describe
> such abstraction. When they are mentioned, it always is as a shortcut
> for EL1, EL2 or EL3, and never for EL12. That's because *_EL12 are
> *not* registers. They are accessors, nothing else. So what we
> currently have is not only bizarre, it is actively wrong.
> 
> [...]

Applied to arm64 (for-next/cpufeature), thanks!

[1/4] arm64/sysreg: Allow a 'Mapping' descriptor for system registers
      https://git.kernel.org/arm64/c/078bc96539c3
[2/4] arm64/sysreg: Get rid of the TCR2_EL1x SysregFields
      https://git.kernel.org/arm64/c/7052e808c446
[3/4] arm64/sysreg: Convert *_EL12 accessors to Mapping
      https://git.kernel.org/arm64/c/233fc36bb5a2
[4/4] arm64/sysreg: Get rid of CPACR_ELx SysregFields
      https://git.kernel.org/arm64/c/e5ecedcd7cc2

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From Frank.li at nxp.com  Thu Dec 19 11:55:08 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 14:55:08 -0500
Subject: [PATCH v8 0/7] PCI: dwc: opitimaze RC Host/EP pci_fixup_addr()
In-Reply-To: <Z1i9uEGvsVACsF2r@lizhi-Precision-Tower-5810>
References: <20241119-pci_fixup_addr-v8-0-c4bfa5193288@nxp.com>
 <20241124143839.hg2yj462h22rftqa@thinkpad>
 <Z1i9uEGvsVACsF2r@lizhi-Precision-Tower-5810>
Message-ID: <Z2R6HET6FZEO+uwi@lizhi-Precision-Tower-5810>

On Tue, Dec 10, 2024 at 05:16:24PM -0500, Frank Li wrote:
> On Sun, Nov 24, 2024 at 08:08:39PM +0530, Manivannan Sadhasivam wrote:
> > On Tue, Nov 19, 2024 at 02:44:18PM -0500, Frank Li wrote:
[...]
> > > Previously, `cpu_addr_fixup()` was used to handle address conversion. Now,
> > > the device tree provides this information.
> > >
> > > The both pave the road to eliminate ugle cpu_fixup_addr() callback function.
> > >
> >
> > Series looks good to me. Thanks a lot for your persistence! But it missed 6.13
> > cycle. So let's get it merged early once 6.13-rc1 is out.
>
> Krzysztof Wilczy?ski:
>
> 	Could you please pick these? all reviewed by mani? It pave the
> road to clean up ugle cpu_fixup_addr().

Krzysztof Wilczy?ski and Bjorn Helgaas

	Any update for this? All already reviewed by mani.

Frank

>
> Frank
>
> >
> > - Mani
> >
[...]
> >
> > --
> > ????????? ????????


From msp at baylibre.com  Thu Dec 19 11:57:54 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 20:57:54 +0100
Subject: [PATCH v6 3/7] can: m_can: Return ERR_PTR on error in allocation
In-Reply-To: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
References: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
Message-ID: <20241219-topic-mcan-wakeup-source-v6-12-v6-3-1356c7f7cfda@baylibre.com>

We have more detailed error values available, return them in the core
driver and the calling drivers to return proper errors to callers.

Reviewed-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/net/can/m_can/m_can.c          | 6 +++---
 drivers/net/can/m_can/m_can_pci.c      | 4 ++--
 drivers/net/can/m_can/m_can_platform.c | 4 ++--
 drivers/net/can/m_can/tcan4x5x-core.c  | 4 ++--
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 0dcdcde3449c7647e4bc9a92f918160a336f94c0..e69e9799710b3e4cb267324e8e9db40ca02328e2 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -2356,7 +2356,7 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
 					     sizeof(mram_config_vals) / 4);
 	if (ret) {
 		dev_err(dev, "Could not get Message RAM configuration.");
-		goto out;
+		return ERR_PTR(ret);
 	}
 
 	if (dev->of_node && of_property_read_bool(dev->of_node, "wakeup-source"))
@@ -2371,7 +2371,7 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
 	net_dev = alloc_candev(sizeof_priv, tx_fifo_size);
 	if (!net_dev) {
 		dev_err(dev, "Failed to allocate CAN device");
-		goto out;
+		return ERR_PTR(-ENOMEM);
 	}
 
 	class_dev = netdev_priv(net_dev);
@@ -2380,7 +2380,7 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
 	SET_NETDEV_DEV(net_dev, dev);
 
 	m_can_of_parse_mram(class_dev, mram_config_vals);
-out:
+
 	return class_dev;
 }
 EXPORT_SYMBOL_GPL(m_can_class_allocate_dev);
diff --git a/drivers/net/can/m_can/m_can_pci.c b/drivers/net/can/m_can/m_can_pci.c
index d72fe771dfc7aa768c728f817e67a87b49fd9974..05a01dfdbfbf18b74f796d2efc75e2be5cbb75ed 100644
--- a/drivers/net/can/m_can/m_can_pci.c
+++ b/drivers/net/can/m_can/m_can_pci.c
@@ -111,8 +111,8 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
 
 	mcan_class = m_can_class_allocate_dev(&pci->dev,
 					      sizeof(struct m_can_pci_priv));
-	if (!mcan_class)
-		return -ENOMEM;
+	if (IS_ERR(mcan_class))
+		return PTR_ERR(mcan_class);
 
 	priv = cdev_to_priv(mcan_class);
 
diff --git a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c
index b832566efda042929486578fad1879c7ad4a0cff..40bd10f71f0e2fab847c40c5bd5f7d85d3d46712 100644
--- a/drivers/net/can/m_can/m_can_platform.c
+++ b/drivers/net/can/m_can/m_can_platform.c
@@ -87,8 +87,8 @@ static int m_can_plat_probe(struct platform_device *pdev)
 
 	mcan_class = m_can_class_allocate_dev(&pdev->dev,
 					      sizeof(struct m_can_plat_priv));
-	if (!mcan_class)
-		return -ENOMEM;
+	if (IS_ERR(mcan_class))
+		return PTR_ERR(mcan_class);
 
 	priv = cdev_to_priv(mcan_class);
 
diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c
index 2f73bf3abad889c222f15c39a3d43de1a1cf5fbb..4c40b444727585b30df33a897c398e35e7592fb2 100644
--- a/drivers/net/can/m_can/tcan4x5x-core.c
+++ b/drivers/net/can/m_can/tcan4x5x-core.c
@@ -375,8 +375,8 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
 
 	mcan_class = m_can_class_allocate_dev(&spi->dev,
 					      sizeof(struct tcan4x5x_priv));
-	if (!mcan_class)
-		return -ENOMEM;
+	if (IS_ERR(mcan_class))
+		return PTR_ERR(mcan_class);
 
 	ret = m_can_check_mram_cfg(mcan_class, TCAN4X5X_MRAM_SIZE);
 	if (ret)

-- 
2.45.2



From msp at baylibre.com  Thu Dec 19 11:57:55 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 20:57:55 +0100
Subject: [PATCH v6 4/7] can: m_can: Support pinctrl wakeup state
In-Reply-To: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
References: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
Message-ID: <20241219-topic-mcan-wakeup-source-v6-12-v6-4-1356c7f7cfda@baylibre.com>

am62 requires a wakeup flag being set in pinctrl when mcan pins acts as
a wakeup source. Add support to select the wakeup state if WOL is
enabled.

Reviewed-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/net/can/m_can/m_can.c | 68 +++++++++++++++++++++++++++++++++++++++++++
 drivers/net/can/m_can/m_can.h |  4 +++
 2 files changed, 72 insertions(+)

diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index e69e9799710b3e4cb267324e8e9db40ca02328e2..ce39685a7c42a2238ad8afd6cf53aa53c9bbb3bb 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -2197,6 +2197,7 @@ static void m_can_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 static int m_can_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct m_can_classdev *cdev = netdev_priv(dev);
+	struct pinctrl_state *new_pinctrl_state = NULL;
 	bool wol_enable = !!(wol->wolopts & WAKE_PHY);
 	int ret;
 
@@ -2213,7 +2214,28 @@ static int m_can_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 		return ret;
 	}
 
+	if (wol_enable)
+		new_pinctrl_state = cdev->pinctrl_state_wakeup;
+	else
+		new_pinctrl_state = cdev->pinctrl_state_default;
+
+	if (IS_ERR_OR_NULL(new_pinctrl_state))
+		return 0;
+
+	ret = pinctrl_select_state(cdev->pinctrl, new_pinctrl_state);
+	if (ret) {
+		netdev_err(cdev->net, "Failed to select pinctrl state %pE\n",
+			   ERR_PTR(ret));
+		goto err_wakeup_enable;
+	}
+
 	return 0;
+
+err_wakeup_enable:
+	/* Revert wakeup enable */
+	device_set_wakeup_enable(cdev->dev, !wol_enable);
+
+	return ret;
 }
 
 static const struct ethtool_ops m_can_ethtool_ops_coalescing = {
@@ -2341,6 +2363,44 @@ int m_can_class_get_clocks(struct m_can_classdev *cdev)
 }
 EXPORT_SYMBOL_GPL(m_can_class_get_clocks);
 
+static int m_can_class_setup_optional_pinctrl(struct m_can_classdev *class_dev)
+{
+	struct device *dev = class_dev->dev;
+	int ret;
+
+	class_dev->pinctrl = devm_pinctrl_get(dev);
+	if (IS_ERR(class_dev->pinctrl)) {
+		ret = PTR_ERR(class_dev->pinctrl);
+		class_dev->pinctrl = NULL;
+
+		if (ret == -ENODEV)
+			return 0;
+
+		return dev_err_probe(dev, ret, "Failed to get pinctrl\n");
+	}
+
+	class_dev->pinctrl_state_wakeup =
+		pinctrl_lookup_state(class_dev->pinctrl, "wakeup");
+	if (IS_ERR(class_dev->pinctrl_state_wakeup)) {
+		ret = PTR_ERR(class_dev->pinctrl_state_wakeup);
+		class_dev->pinctrl_state_wakeup = NULL;
+
+		if (ret == -ENODEV)
+			return 0;
+
+		return dev_err_probe(dev, ret, "Failed to lookup pinctrl wakeup state\n");
+	}
+
+	class_dev->pinctrl_state_default =
+		pinctrl_lookup_state(class_dev->pinctrl, "default");
+	if (IS_ERR(class_dev->pinctrl_state_default)) {
+		ret = PTR_ERR(class_dev->pinctrl_state_default);
+		return dev_err_probe(dev, ret, "Failed to lookup pinctrl default state\n");
+	}
+
+	return 0;
+}
+
 struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
 						int sizeof_priv)
 {
@@ -2381,7 +2441,15 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
 
 	m_can_of_parse_mram(class_dev, mram_config_vals);
 
+	ret = m_can_class_setup_optional_pinctrl(class_dev);
+	if (ret)
+		goto err_free_candev;
+
 	return class_dev;
+
+err_free_candev:
+	free_candev(net_dev);
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(m_can_class_allocate_dev);
 
diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h
index 92b2bd8628e6b31370f4accbc2e28f3b2257a71d..b75b0dd6ccc93973d0891daac07c92b61f81dc2a 100644
--- a/drivers/net/can/m_can/m_can.h
+++ b/drivers/net/can/m_can/m_can.h
@@ -126,6 +126,10 @@ struct m_can_classdev {
 	struct mram_cfg mcfg[MRAM_CFG_NUM];
 
 	struct hrtimer hrtimer;
+
+	struct pinctrl *pinctrl;
+	struct pinctrl_state *pinctrl_state_default;
+	struct pinctrl_state *pinctrl_state_wakeup;
 };
 
 struct m_can_classdev *m_can_class_allocate_dev(struct device *dev, int sizeof_priv);

-- 
2.45.2



From msp at baylibre.com  Thu Dec 19 11:57:56 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 20:57:56 +0100
Subject: [PATCH v6 5/7] arm64: dts: ti: k3-am62: Mark mcu_mcan0/1 as
 wakeup-source
In-Reply-To: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
References: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
Message-ID: <20241219-topic-mcan-wakeup-source-v6-12-v6-5-1356c7f7cfda@baylibre.com>

mcu_mcan0 and mcu_mcan1 can be wakeup sources for the SoC. Mark them
accordingly in the devicetree.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
index 68e906796aefebc5eaaa5a231e56105a9cdd13e5..cc693be47df080e8b8dba9f1aca2cd725f4ea85f 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
@@ -160,6 +160,7 @@ mcu_mcan0: can at 4e08000 {
 		clocks = <&k3_clks 188 6>, <&k3_clks 188 1>;
 		clock-names = "hclk", "cclk";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 
@@ -172,6 +173,7 @@ mcu_mcan1: can at 4e18000 {
 		clocks = <&k3_clks 189 6>, <&k3_clks 189 1>;
 		clock-names = "hclk", "cclk";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 

-- 
2.45.2



From msp at baylibre.com  Thu Dec 19 11:57:58 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 20:57:58 +0100
Subject: [PATCH v6 7/7] arm64: dts: ti: k3-am62p-mcu: Mark mcu_mcan0/1 as
 wakeup-source
In-Reply-To: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
References: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
Message-ID: <20241219-topic-mcan-wakeup-source-v6-12-v6-7-1356c7f7cfda@baylibre.com>

From: Vibhore Vardhan <vibhore at ti.com>

mcu_mcan0 and mcu_mcan1 can be wakeup sources for the SoC. Mark them
accordingly in the devicetree. Based on the patch for AM62a.

Signed-off-by: Vibhore Vardhan <vibhore at ti.com>
Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
index b33aff0d65c9def755f8dda9eb9feda7bc74e5c8..cf57f954dd3e31a8747c833bcc583dbc6ba21d03 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
@@ -173,6 +173,7 @@ mcu_mcan0: can at 4e08000 {
 		interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "int0", "int1";
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 
@@ -188,6 +189,7 @@ mcu_mcan1: can at 4e18000 {
 		interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "int0", "int1";
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 

-- 
2.45.2



From conor at kernel.org  Thu Dec 19 12:01:07 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 19 Dec 2024 20:01:07 +0000
Subject: [PATCH] dt-bindings: mfd: atmel: Convert to json schema
In-Reply-To: <20241219-gpbr-v1-1-e19a562ebf81@microchip.com>
References: <20241219-gpbr-v1-1-e19a562ebf81@microchip.com>
Message-ID: <20241219-catcher-genre-5ea63d8e6587@spud>

On Thu, Dec 19, 2024 at 11:12:50AM +0530, Charan Pedumuru wrote:
> Convert old text based binding to json schema.
> Changes during conversion:
> The text binding is misleading, add a fallback `atmel,at91sam9260-gpbr`
> for both `microchip,sam9x60-gpbr` and `microchip,sam9x7-gpbr` which is
> missing in old binding and `microchip,sam9x60-gpbr` is not a fallback
> for `microchip,sam9x7-gpbr`.
> 
> Signed-off-by: Charan Pedumuru <charan.pedumuru at microchip.com>

Reviewed-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/20241219/a003321c/attachment.sig>

From heiko at sntech.de  Thu Dec 19 12:01:57 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 19 Dec 2024 21:01:57 +0100
Subject: [PATCH v9 4/9] mfd: add base driver for qnap-mcu devices
In-Reply-To: <4cecc705-84ab-44d5-8725-eb973254f257@ijzerbout.nl>
References: <20241107114712.538976-1-heiko@sntech.de> <3130486.CbtlEUcBR6@diego>
 <4cecc705-84ab-44d5-8725-eb973254f257@ijzerbout.nl>
Message-ID: <5047567.0VBMTVartN@diego>

Am Donnerstag, 19. Dezember 2024, 20:51:41 CET schrieb Kees Bakker:
> Op 19-12-2024 om 20:43 schreef Heiko St?bner:
> > Hi Kees,
> >
> > Am Donnerstag, 19. Dezember 2024, 20:18:38 CET schrieb Kees Bakker:
> >> Op 07-11-2024 om 12:47 schreef Heiko Stuebner:
> >>> These microcontroller units are used in network-attached-storage devices
> >>> made by QNAP and provide additional functionality to the system.
> >>>
> >>> This adds the base driver that implements the serial protocol via
> >>> serdev and additionally hooks into the poweroff handlers to turn
> >>> off the parts of the system not supplied by the general PMIC.
> >>>
> >>> Turning off (at least the TSx33 devices using Rockchip SoCs) consists of
> >>> two separate actions. Turning off the MCU alone does not turn off the main
> >>> SoC and turning off only the SoC/PMIC does not turn off the hard-drives.
> >>> Also if the MCU is not turned off, the system also won't start again until
> >>> it is unplugged from power.
> >>>
> >>> So on shutdown the MCU needs to be turned off separately before the
> >>> main PMIC.
> >>>
> >>> The protocol spoken by the MCU is sadly not documented, but was
> >>> obtained by listening to the chatter on the serial port, as thankfully
> >>> the "hal_app" program from QNAPs firmware allows triggering all/most
> >>> MCU actions from the command line.
> >>>
> >>> The implementation of how to talk to the serial device got some
> >>> inspiration from the rave-sp servdev driver.
> >>>
> >>> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> >>> ---
> >>>    MAINTAINERS                  |   6 +
> >>>    drivers/mfd/Kconfig          |  13 ++
> >>>    drivers/mfd/Makefile         |   2 +
> >>>    drivers/mfd/qnap-mcu.c       | 338 +++++++++++++++++++++++++++++++++++
> >>>    include/linux/mfd/qnap-mcu.h |  26 +++
> >>>    5 files changed, 385 insertions(+)
> >>>    create mode 100644 drivers/mfd/qnap-mcu.c
> >>>    create mode 100644 include/linux/mfd/qnap-mcu.h
> >>>
> >>> [...]
> >>> diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c
> >>> new file mode 100644
> >>> index 000000000000..4be39d8b2905
> >>> --- /dev/null
> >>> +++ b/drivers/mfd/qnap-mcu.c
> >>> [...]
> >>> +int qnap_mcu_exec(struct qnap_mcu *mcu,
> >>> +		  const u8 *cmd_data, size_t cmd_data_size,
> >>> +		  u8 *reply_data, size_t reply_data_size)
> >>> +{
> >>> +	unsigned char rx[QNAP_MCU_RX_BUFFER_SIZE];
> >>> +	size_t length = reply_data_size + QNAP_MCU_CHECKSUM_SIZE;
> >>> +	struct qnap_mcu_reply *reply = &mcu->reply;
> >>> +	int ret = 0;
> >>> +
> >>> +	if (length > sizeof(rx)) {
> >>> +		dev_err(&mcu->serdev->dev, "expected data too big for receive buffer");
> >>> +		return -EINVAL;
> >>> +	}
> >>> +
> >>> +	mutex_lock(&mcu->bus_lock);
> >>> +
> >>> +	reply->data = rx,
> >>> +	reply->length = length,
> >>> +	reply->received = 0,
> >>> +	reinit_completion(&reply->done);
> >>> +
> >>> +	qnap_mcu_write(mcu, cmd_data, cmd_data_size);
> >>> +
> >>> +	serdev_device_wait_until_sent(mcu->serdev, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS));
> >>> +
> >>> +	if (!wait_for_completion_timeout(&reply->done, msecs_to_jiffies(QNAP_MCU_TIMEOUT_MS))) {
> >>> +		dev_err(&mcu->serdev->dev, "Command timeout\n");
> >>> +		ret = -ETIMEDOUT;
> >>> +	} else {
> >>> +		u8 crc = qnap_mcu_csum(rx, reply_data_size);
> >> Here `rx` is still not initialized.
> > The MCU works in a way that a sent command always causes "reply_data_size"
> > bytes to be returned.
> >
> > So for each qnap_mcu_write() above we know that this amount of bytes has
> > been returned (and thus written into rx) if the completion above finishes
> > sucessfully.
> >
> > "rx" is assigned to reply->data above (same as the expected received size).
> > When characters are received on the serial line, this will trigger
> > qnap_mcu_receive_buf() from the serdev and thus fill those elements in rx.
> >
> > So if we land at the qnap_mcu_csum() call, we do have received the expected
> > amount of bytes from the serdev and thus rx is filled accordingly.
> >
> > If we don't receive the needed amount of bytes, we end up in the timeout
> > above that.
> >
> > What did I miss?
> Sorry, my fault. I missed the essential part of the external event (external
> for this function that is).
> Thanks for explaining.

no worries :-) .

The more eyes, the better.

Heiko




From msp at baylibre.com  Thu Dec 19 12:02:11 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 21:02:11 +0100
Subject: [PATCH v4 0/4] firmware: ti_sci: Partial-IO support
Message-ID: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>

Hi,

Series
------
Partial-IO is a poweroff SoC state with a few pingroups active for
wakeup. This state can be entered by sending a TI_SCI PREPARE_SLEEP
message.

The message is sent on poweroff if one of the potential wakeup sources
for this power state are wakeup enabled. The potential wakeup sources
are found by looking for devices that list "poweroff" in the
wakeup-source property in the devicetree. The wakeup sources can be
individually enabled/disabled by the user in the running system.

The series is based on v6.13-rc1.

Partial-IO
----------
This series is part of a bigger topic to support Partial-IO on am62,
am62a and am62p. Partial-IO is a poweroff state in which some pins are
able to wakeup the SoC. In detail MCU m_can and two serial port pins can
trigger the wakeup.
A documentation can also be found in section 6.2.4 in the TRM:
  https://www.ti.com/lit/pdf/spruiv7

This other series is relevant for the support of Partial-IO:

 - can: m_can: Add am62 wakeup support
   https://lore.kernel.org/r/20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda at baylibre.com
   https://gitlab.baylibre.com/msp8/linux/-/tree/topic/mcan-wakeup-source/v6.13?ref_type=heads

Testing
-------

A test branch is available here that includes all patches required to
test Partial-IO:

https://gitlab.baylibre.com/msp8/linux/-/tree/integration/am62-partialio/v6.13?ref_type=heads

After enabling Wake-on-LAN the system can be powered off and will enter
the Partial-IO state in which it can be woken up by activity on the
specific pins:
    ethtool -s can0 wol p
    ethtool -s can1 wol p
    poweroff

I tested these patches on am62-lp-sk.

Best,
Markus

Previous versions:
 v1: https://lore.kernel.org/lkml/20240523080225.1288617-1-msp at baylibre.com/
 v2: https://lore.kernel.org/lkml/20240729080101.3859701-1-msp at baylibre.com/
 v3: https://lore.kernel.org/r/20241012-topic-am62-partialio-v6-13-b4-v3-0-f7c6c2739681 at baylibre.com

Changes in v4:
 - Rebased to v6.13-rc1
 - Removed all regulator related structures from patches and implemented
   the wakeup-source property use instead.

Changes in v3:
 - Remove other modes declared for PREPARE_SLEEP as they probably won't
   ever be used in upstream.
 - Replace the wait loop after sending PREPARE_SLEEP with msleep and do
   an emergency_restart if it exits
 - Remove uarts from DT wakeup sources
 - Split no response handling in ti_sci_do_xfer() into a separate patch
   and use goto instead of if ()
 - Remove DT binding parital-io-wakeup-sources. Instead I am modeling
   the devices that are in the relevant group that are powered during
   Partial-IO with the power supplies that are externally provided to
   the SoC. In this case they are provided through 'vddshv_canuart'. All
   devices using this regulator can be considered a potential wakeup
   source if they are wakeup capable and wakeup enabled.
 - Added devicetree patches adding vcc_3v3_sys regulator and
   vddshv_canuart for am62-lp-sk
 - Add pinctrl entries for am62-lp-sk to add WKUP_EN for mcu_mcan0 and
   mcu_mcan1

Changes in v2:
 - Rebase to v6.11-rc1
 - dt-binding:
    - Update commit message
    - Add more verbose description of the new binding for a better
      explanation.
 - ti_sci driver:
    - Combine ti_sci_do_send() into ti_sci_do_xfer and only wait on a
      response if a flag is set.
    - On failure to enter Partial-IO, do emergency_restart()
    - Add comments
    - Fix small things

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
Markus Schneider-Pargmann (4):
      firmware: ti_sci: Support transfers without response
      firmware: ti_sci: Partial-IO support
      arm64: dts: ti: k3-pinctrl: Add WKUP_EN flag
      arm64: dts: ti: am62-lp-sk: Add wakeup mcu_mcan0/1 pinctrl

 arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts |  52 +++++++++++++
 arch/arm64/boot/dts/ti/k3-pinctrl.h      |   3 +
 drivers/firmware/ti_sci.c                | 122 ++++++++++++++++++++++++++++++-
 drivers/firmware/ti_sci.h                |   5 ++
 4 files changed, 181 insertions(+), 1 deletion(-)
---
base-commit: cbc4912199deab59fdbd830b115d81941d0add46
change-id: 20241008-topic-am62-partialio-v6-12-b4-c273fbac4447
prerequisite-change-id: 20241009-topic-mcan-wakeup-source-v6-12-8c1d69931bd8:6
prerequisite-patch-id: eba4f2096c69d9c734a4a4491e062bd8b01d26fd
prerequisite-patch-id: 830b339ea452edd750b04f719da91e721be630cb
prerequisite-patch-id: 56fd0aae20e82eb2dfb48f1b7088d62311a11f05
prerequisite-patch-id: 41f55b96c0428240d74d488e3c788c09842a1753
prerequisite-patch-id: 4ab7269193dbcfd449349ccd41b23914bbbdaa6b
prerequisite-patch-id: 24a735db927cbe2b1e0c6c5f3985b6676ce5528c
prerequisite-patch-id: 52dbbf390d3f7e4a3859e60e4f660bfe39b92cd9

Best regards,
-- 
Markus Schneider-Pargmann <msp at baylibre.com>



From msp at baylibre.com  Thu Dec 19 12:02:12 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 21:02:12 +0100
Subject: [PATCH v4 1/4] firmware: ti_sci: Support transfers without
 response
In-Reply-To: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
References: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
Message-ID: <20241219-topic-am62-partialio-v6-12-b4-v4-1-1cb8eabd407e@baylibre.com>

Check the header flags if an response is expected or not. If it is not
expected skip the receive part of ti_sci_do_xfer(). This prepares the
driver for one-way messages as prepare_sleep for Partial-IO.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/firmware/ti_sci.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 806a975fff22ae00ecb88587b2c47ba172120bc2..ec0c54935ac0d667323d98b86ac9d288b73be6aa 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -398,10 +398,13 @@ static void ti_sci_put_one_xfer(struct ti_sci_xfers_info *minfo,
 static inline int ti_sci_do_xfer(struct ti_sci_info *info,
 				 struct ti_sci_xfer *xfer)
 {
+	struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
 	int ret;
 	int timeout;
 	struct device *dev = info->dev;
 	bool done_state = true;
+	bool response_expected = !!(hdr->flags & (TI_SCI_FLAG_REQ_ACK_ON_PROCESSED |
+						  TI_SCI_FLAG_REQ_ACK_ON_RECEIVED));
 
 	ret = mbox_send_message(info->chan_tx, &xfer->tx_message);
 	if (ret < 0)
@@ -409,6 +412,9 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
 
 	ret = 0;
 
+	if (!response_expected)
+		goto no_response;
+
 	if (system_state <= SYSTEM_RUNNING) {
 		/* And we wait for the response. */
 		timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
@@ -429,6 +435,7 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
 		dev_err(dev, "Mbox timedout in resp(caller: %pS)\n",
 			(void *)_RET_IP_);
 
+no_response:
 	/*
 	 * NOTE: we might prefer not to need the mailbox ticker to manage the
 	 * transfer queueing since the protocol layer queues things by itself.

-- 
2.45.2



From msp at baylibre.com  Thu Dec 19 12:02:13 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 21:02:13 +0100
Subject: [PATCH v4 2/4] firmware: ti_sci: Partial-IO support
In-Reply-To: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
References: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
Message-ID: <20241219-topic-am62-partialio-v6-12-b4-v4-2-1cb8eabd407e@baylibre.com>

Add support for Partial-IO poweroff. In Partial-IO pins of a few
hardware units can generate system wakeups while DDR memory is not
powered resulting in a fresh boot of the system. These hardware units in
the SoC are always powered so that some logic can detect pin activity.

If the system supports Partial-IO as described in the fw capabilities, a
sys_off handler is added. This sys_off handler decides if the poweroff
is executed by entering normal poweroff or Partial-IO instead. The
decision is made by checking if wakeup is enabled on all devices that
may wake up the SoC from Partial-IO.

The possible wakeup devices are found by checking which devices have the
"poweroff" in the list of wakeup-source power states. Only devices that
are actually enabled by the user will be considered as an active wakeup
source. If none of the wakeup sources is enabled the system will do a
normal poweroff. If at least one wakeup source is enabled it will
instead send a TI_SCI_MSG_PREPARE_SLEEP message from the sys_off
handler. Sending this message will result in an immediate shutdown of
the system. No execution is expected after this point. The code will
wait for 5s and do an emergency_restart afterwards if Partial-IO wasn't
entered at that point.

A short documentation about Partial-IO can be found in section 6.2.4.5
of the TRM at
  https://www.ti.com/lit/pdf/spruiv7

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/firmware/ti_sci.c | 115 +++++++++++++++++++++++++++++++++++++++++++++-
 drivers/firmware/ti_sci.h |   5 ++
 2 files changed, 119 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index ec0c54935ac0d667323d98b86ac9d288b73be6aa..693ac816f8ba3941a9156bd39524099ca476d712 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -3746,6 +3746,100 @@ static const struct dev_pm_ops ti_sci_pm_ops = {
 #endif
 };
 
+/*
+ * Enter Partial-IO, which disables everything including DDR with only a small
+ * logic being active for wakeup.
+ */
+static int tisci_enter_partial_io(struct ti_sci_info *info)
+{
+	struct ti_sci_msg_req_prepare_sleep *req;
+	struct ti_sci_xfer *xfer;
+	struct device *dev = info->dev;
+	int ret = 0;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PREPARE_SLEEP,
+				   TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
+				   sizeof(*req), sizeof(struct ti_sci_msg_hdr));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+
+	req = (struct ti_sci_msg_req_prepare_sleep *)xfer->xfer_buf;
+	req->mode = TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO;
+	req->ctx_lo = 0;
+	req->ctx_hi = 0;
+	req->debug_flags = 0;
+
+	dev_info(dev, "Entering Partial-IO because a powered wakeup-enabled device was found.\n");
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+static bool tisci_canuart_wakeup_enabled(struct ti_sci_info *info)
+{
+	struct device_node *wakeup_node = NULL;
+
+	for (wakeup_node = of_find_node_with_property(NULL, "wakeup-source");
+	     wakeup_node;
+	     wakeup_node = of_find_node_with_property(wakeup_node, "wakeup-source")) {
+		struct platform_device *pdev;
+		int index;
+
+		index = of_property_match_string(wakeup_node, "wakeup-source", "poweroff");
+		if (index < 0)
+			continue;
+
+		pdev = of_find_device_by_node(wakeup_node);
+		if (!pdev)
+			break;
+
+		if (device_may_wakeup(&pdev->dev)) {
+			dev_dbg(info->dev, "%pOF identified as wakeup source for Partial-IO\n",
+				wakeup_node);
+			put_device(&pdev->dev);
+			of_node_put(wakeup_node);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int tisci_sys_off_handler(struct sys_off_data *data)
+{
+	struct ti_sci_info *info = data->cb_data;
+	bool enter_partial_io = tisci_canuart_wakeup_enabled(info);
+	int ret;
+
+	if (!enter_partial_io)
+		return NOTIFY_DONE;
+
+	ret = tisci_enter_partial_io(info);
+
+	if (ret) {
+		dev_err(info->dev,
+			"Failed to enter Partial-IO %pe, trying to do an emergency restart\n",
+			ERR_PTR(ret));
+		emergency_restart();
+	}
+
+	mdelay(5000);
+	emergency_restart();
+
+	return NOTIFY_DONE;
+}
+
 /* Description for K2G */
 static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
 	.default_host_id = 2,
@@ -3889,6 +3983,19 @@ static int ti_sci_probe(struct platform_device *pdev)
 		goto out;
 	}
 
+	if (info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO) {
+		ret = devm_register_sys_off_handler(dev,
+						    SYS_OFF_MODE_POWER_OFF,
+						    SYS_OFF_PRIO_FIRMWARE,
+						    tisci_sys_off_handler,
+						    info);
+		if (ret) {
+			dev_err(dev, "Failed to register sys_off_handler %pe\n",
+				ERR_PTR(ret));
+			goto out;
+		}
+	}
+
 	dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
 		 info->handle.version.abi_major, info->handle.version.abi_minor,
 		 info->handle.version.firmware_revision,
@@ -3898,7 +4005,13 @@ static int ti_sci_probe(struct platform_device *pdev)
 	list_add_tail(&info->node, &ti_sci_list);
 	mutex_unlock(&ti_sci_list_mutex);
 
-	return of_platform_populate(dev->of_node, NULL, NULL, dev);
+	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+	if (ret) {
+		dev_err(dev, "platform_populate failed %pe\n", ERR_PTR(ret));
+		goto out;
+	}
+	return 0;
+
 out:
 	if (!IS_ERR(info->chan_tx))
 		mbox_free_channel(info->chan_tx);
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index 053387d7baa064498e6a208daa7f70040ef87281..dec9e20cbe5da8f6d9393d56bb9a1e73cb083a42 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -592,6 +592,11 @@ struct ti_sci_msg_resp_get_clock_freq {
 struct ti_sci_msg_req_prepare_sleep {
 	struct ti_sci_msg_hdr	hdr;
 
+/*
+ * When sending perpare_sleep with MODE_PARTIAL_IO no response will be sent,
+ * no further steps are required.
+ */
+#define TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO				0x03
 #define TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED				0xfd
 	u8			mode;
 	u32			ctx_lo;

-- 
2.45.2



From msp at baylibre.com  Thu Dec 19 12:02:14 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 21:02:14 +0100
Subject: [PATCH v4 3/4] arm64: dts: ti: k3-pinctrl: Add WKUP_EN flag
In-Reply-To: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
References: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
Message-ID: <20241219-topic-am62-partialio-v6-12-b4-v4-3-1cb8eabd407e@baylibre.com>

WKUP_EN is a flag to enable pin wakeup. Any activity will wakeup the SoC
in that case.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-pinctrl.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-pinctrl.h b/arch/arm64/boot/dts/ti/k3-pinctrl.h
index 22b8d73cfd3264735ddf91874e60a0c5fc7ade5b..dd4d53e8420a1d671e04a70d4af8b0ea1b75b2b2 100644
--- a/arch/arm64/boot/dts/ti/k3-pinctrl.h
+++ b/arch/arm64/boot/dts/ti/k3-pinctrl.h
@@ -12,6 +12,7 @@
 #define PULLTYPESEL_SHIFT	(17)
 #define RXACTIVE_SHIFT		(18)
 #define DEBOUNCE_SHIFT		(11)
+#define WKUP_EN_SHIFT		(29)
 
 #define PULL_DISABLE		(1 << PULLUDEN_SHIFT)
 #define PULL_ENABLE		(0 << PULLUDEN_SHIFT)
@@ -38,6 +39,8 @@
 #define PIN_DEBOUNCE_CONF5	(5 << DEBOUNCE_SHIFT)
 #define PIN_DEBOUNCE_CONF6	(6 << DEBOUNCE_SHIFT)
 
+#define WKUP_EN			(1 << WKUP_EN_SHIFT)
+
 /* Default mux configuration for gpio-ranges to use with pinctrl */
 #define PIN_GPIO_RANGE_IOPAD	(PIN_INPUT | 7)
 

-- 
2.45.2



From msp at baylibre.com  Thu Dec 19 12:02:15 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 21:02:15 +0100
Subject: [PATCH v4 4/4] arm64: dts: ti: am62-lp-sk: Add wakeup mcu_mcan0/1
 pinctrl
In-Reply-To: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
References: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
Message-ID: <20241219-topic-am62-partialio-v6-12-b4-v4-4-1cb8eabd407e@baylibre.com>

Add pincontrol definitions for mcu_mcan0 and mcu_mcan1 for wakeup from
Partial-IO. Add these as wakeup pinctrl entries for both devices.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts | 52 ++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
index 8e9fc00a6b3c7459a360f9e1d6bbb60e68c460ab..22695715239644b1bfe209ba4f1c42fae4c59f70 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
@@ -232,3 +232,55 @@ &tlv320aic3106 {
 &gpmc0 {
 	ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */
 };
+
+&mcu_mcan0 {
+	pinctrl-names = "default", "wakeup";
+	pinctrl-0 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_default>;
+	pinctrl-1 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_wakeup>;
+	status = "okay";
+};
+
+&mcu_mcan1 {
+	pinctrl-names = "default", "wakeup";
+	pinctrl-0 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_default>;
+	pinctrl-1 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_wakeup>;
+	status = "okay";
+};
+
+&mcu_pmx0 {
+	mcu_mcan0_tx_pins_default: mcu-mcan0-tx-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */
+		>;
+	};
+
+	mcu_mcan0_rx_pins_default: mcu-mcan0-rx-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */
+		>;
+	};
+
+	mcu_mcan0_rx_pins_wakeup: mcu-mcan0-rx-wakeup-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x038, PIN_INPUT | WKUP_EN, 0) /* (B3) MCU_MCAN0_RX */
+		>;
+	};
+
+	mcu_mcan1_tx_pins_default: mcu-mcan1-tx-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x03c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */
+		>;
+	};
+
+	mcu_mcan1_rx_pins_default: mcu-mcan1-rx-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */
+		>;
+	};
+
+	mcu_mcan1_rx_pins_wakeup: mcu-mcan1-rx-wakeup-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x040, PIN_INPUT | WKUP_EN, 0) /* (D4) MCU_MCAN1_RX */
+		>;
+	};
+};

-- 
2.45.2



From msp at baylibre.com  Thu Dec 19 11:57:57 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 20:57:57 +0100
Subject: [PATCH v6 6/7] arm64: dts: ti: k3-am62a-mcu: Mark mcu_mcan0/1 as
 wakeup-source
In-Reply-To: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
References: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
Message-ID: <20241219-topic-mcan-wakeup-source-v6-12-v6-6-1356c7f7cfda@baylibre.com>

mcu_mcan0 and mcu_mcan1 can be wakeup sources for the SoC. Mark them
accordingly in the devicetree.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi
index 0469c766b769e46068f23e0073f951aa094c456f..7f88f284ea5daeba189976d03dbd048626104b77 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi
@@ -161,6 +161,7 @@ mcu_mcan0: can at 4e08000 {
 		clocks = <&k3_clks 188 6>, <&k3_clks 188 1>;
 		clock-names = "hclk", "cclk";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 
@@ -173,6 +174,7 @@ mcu_mcan1: can at 4e18000 {
 		clocks = <&k3_clks 189 6>, <&k3_clks 189 1>;
 		clock-names = "hclk", "cclk";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 };

-- 
2.45.2



From Frank.li at nxp.com  Thu Dec 19 12:08:41 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 15:08:41 -0500
Subject: [PATCH v2] i3c: master: Improve initialization of numbered I2C
 adapters
In-Reply-To: <20241212091818.8591-1-defa.li@mediatek.com>
References: <20241212091818.8591-1-defa.li@mediatek.com>
Message-ID: <Z2R9SUJYJlUJSmtL@lizhi-Precision-Tower-5810>

On Thu, Dec 12, 2024 at 05:17:53PM +0800, Defa Li wrote:
> Add logic to initialize I2C adapters with a specific ID if available,
> improving device identification and configuration.
>
> For mixed buses, in addition to the i3c alias, an i2c alias can be added to
> assign a fixed bus number to the i2c adapter.
>
> This allows an alias node such as:
>     aliases {
>         i2c2 = &mixed_bus_a,
>         i3c2 = &mixed_bus_a,
>         i3c4 = &mixed_bus_b,
>     };
>
>     /* assigned "i3c-2" and "i2c-2" */
>     mixed_bus_a: i3c-master {
>     };
>
> If there is no i2c alias for a mixed bus, the i2c adapter numbers will
> remain as is and will be assigned starting after the highest fixed bus
> number.
>
>     /* assigned "i3c-4" and likely assigned "i2c-3" */
>     mixed_bus_b: i3c-master {
>     };
>
> v2:
>   - Modify commit message and code format issues

v2: ...
 should be after "---"

>
> Signed-off-by: Defa Li <defa.li at mediatek.com>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>  drivers/i3c/master.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 42310c9a00c2..92223e0b6e59 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -2486,7 +2486,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
>  	struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master);
>  	struct i2c_dev_desc *i2cdev;
>  	struct i2c_dev_boardinfo *i2cboardinfo;
> -	int ret;
> +	int ret, id = -ENODEV;
>
>  	adap->dev.parent = master->dev.parent;
>  	adap->owner = master->dev.parent->driver->owner;
> @@ -2497,7 +2497,15 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
>  	adap->timeout = 1000;
>  	adap->retries = 3;
>
> -	ret = i2c_add_adapter(adap);
> +	if (master->dev.of_node)
> +		id = of_alias_get_id(master->dev.of_node, "i2c");
> +
> +	if (id >= 0) {
> +		adap->nr = id;
> +		ret = i2c_add_numbered_adapter(adap);
> +	} else {
> +		ret = i2c_add_adapter(adap);
> +	}
>  	if (ret)
>  		return ret;
>
> --
> 2.46.0
>
>
> --
> linux-i3c mailing list
> linux-i3c at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-i3c


From cassel at kernel.org  Thu Dec 19 12:10:16 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Thu, 19 Dec 2024 21:10:16 +0100
Subject: [PATCH v13 4/9] irqchip/gic-v3-its: Add
 DOMAIN_BUS_DEVICE_PCI_EP_MSI support
In-Reply-To: <Z2RRimPlT41Ru281@lizhi-Precision-Tower-5810>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
 <20241218-ep-msi-v13-4-646e2192dc24@nxp.com>
 <868qscq70x.wl-maz@kernel.org>
 <Z2RRimPlT41Ru281@lizhi-Precision-Tower-5810>
Message-ID: <Z2R9qPmAyTcc5mtg@ryzen>

On Thu, Dec 19, 2024 at 12:02:02PM -0500, Frank Li wrote:
> On Thu, Dec 19, 2024 at 10:52:30AM +0000, Marc Zyngier wrote:
> > On Wed, 18 Dec 2024 23:08:39 +0000,

[...]

> If use latest ITS MSI64 should be simple, only need descript it at DTS
> (I have not hardware to test this case yet).
> pci-ep {
> 	...
> 	msi-map = <0 &its, 0x<8_0000, 0xff>;
> 			      ^, ctrl ID.
> 	msi-mask = <0xff>;
> 	...
> }

[...]

> This solution already test by Tested-by: Niklas Cassel <cassel at kernel.org>
> who use another dwc controller, which they already implemented
> "implementation-specific" by only update dts to provide hardware
> information.(I guest he use ITS's MSI64)
> 
> Because it is new patches, I have not added Niklas's test-by tag. There
> are not big functional change since Nikas test. The major change is make
> msi part better align current MSI framework according to Thomas's
> suggestion.

Frank, I tested this series (a few revisions back) on the rockchip rk3588,
which just like imx95, uses a DWC based PCIe EP controller, and ARM GIC ITS,
but unlike imx95, it does not require any additional look up table registers
to be configured.


While the rk3588 PCIe host controller node has:
msi-map = <0x0000 &its1 0x0000 0x1000>;
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi?h=v6.13-rc3#n164

The rk3588 PCIe endpoint controller node, which is the only one relevant
in this case, only has:
msi-parent = <&its1 0x0000>;
no msi-map.
https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/commit/?h=v6.14-armsoc/dts64&id=b6f09f497b07008aa65c31341138cecafa78222c


Kind regards,
Niklas


From conor at kernel.org  Thu Dec 19 12:11:05 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 19 Dec 2024 20:11:05 +0000
Subject: [PATCH] dt-bindings: mmc: move compatible property to its
 specific binding
In-Reply-To: <20241219-mmc-slot-v1-1-dfc747a3d3fb@microchip.com>
References: <20241219-mmc-slot-v1-1-dfc747a3d3fb@microchip.com>
Message-ID: <20241219-scenic-revision-17da9231d61a@spud>

On Thu, Dec 19, 2024 at 09:40:41AM +0530, Dharma Balasubiramani wrote:
> Move the `compatible` property into its specific binding to make the MMC
> slot more generic and modular.

This makes no sense, as presented. What's the real reason for this
change? You want to ref mmc-slot.yaml but the compatible is causing a
driver to probe?
Otherwise, if this is just to avoid having to fix up some devicetree
source files, I don't think we should do this.

Thanks,
Conor.

> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> ---
>  Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml | 4 ++++
>  Documentation/devicetree/bindings/mmc/mmc-slot.yaml              | 7 +------
>  2 files changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml b/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml
> index 022682a977c6..7600a4988eca 100644
> --- a/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml
> +++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml
> @@ -54,6 +54,10 @@ patternProperties:
>        A node for each slot provided by the MMC controller
>  
>      properties:
> +      compatible:
> +        items:
> +          - const: mmc-slot
> +
>        reg:
>          enum: [0, 1, 2]
>  
> diff --git a/Documentation/devicetree/bindings/mmc/mmc-slot.yaml b/Documentation/devicetree/bindings/mmc/mmc-slot.yaml
> index 1f0667828063..84c4605658e0 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc-slot.yaml
> +++ b/Documentation/devicetree/bindings/mmc/mmc-slot.yaml
> @@ -20,19 +20,15 @@ properties:
>    $nodename:
>      pattern: "^slot(@.*)?$"
>  
> -  compatible:
> -    const: mmc-slot
> -
>    reg:
>      description:
>        the slot (or "port") ID
>      maxItems: 1
>  
>  required:
> -  - compatible
>    - reg
>  
> -unevaluatedProperties: false
> +additionalProperties: true
>  
>  examples:
>    - |
> @@ -40,7 +36,6 @@ examples:
>        #address-cells = <1>;
>        #size-cells = <0>;
>        slot at 0 {
> -        compatible = "mmc-slot";
>          reg = <0>;
>          bus-width = <4>;
>        };
> 
> ---
> base-commit: 7fa366f1b6e376c38966faa42da7f0f2e013fdab
> change-id: 20241219-mmc-slot-0574889daea3
> 
> Best regards,
> -- 
> Dharma Balasubiramani <dharma.b 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/20241219/c3f1c766/attachment.sig>

From quic_philber at quicinc.com  Thu Dec 19 12:11:06 2024
From: quic_philber at quicinc.com (Peter Hilber)
Date: Thu, 19 Dec 2024 21:11:06 +0100
Subject: [RFC PATCH v4 0/4] Add virtio_rtc module
Message-ID: <20241219201118.2233-1-quic_philber@quicinc.com>

This series implements a driver for a virtio-rtc device conforming to spec
RFC v6 [1]. It includes a PTP clock driver and an RTC class driver with
alarm.

RFC v4 updates
==============

Important changes compared to the previous driver series [3] are:

- Update to spec RFC v6 [1].

- Distinguish UTC-like clocks by their handling of leap seconds.

- Update RTC class device according to feedback.

A dependent series will expose virtio-rtc's leap second and clock
performance related information to userspace through a novel PTP clock
ioctl.

Overview
========

This patch series adds the virtio_rtc module, and related bugfixes. The
virtio_rtc module implements a driver compatible with the proposed Virtio
RTC device specification [1]. The Virtio RTC (Real Time Clock) device
provides information about current time. The device can provide different
clocks, e.g. for the UTC or TAI time standards, or for physical time
elapsed since some past epoch. The driver can read the clocks with simple
or more accurate methods. Optionally, the driver can set an alarm.

For the Virtio RTC device, there is currently a proprietary implementation,
which has been used for provisional testing.

PTP clock interface
===================

virtio_rtc exposes clocks as PTP clocks to userspace, similar to ptp_kvm.
If both the Virtio RTC device and this driver have special support for the
current clocksource, time synchronization programs can use
cross-timestamping using ioctl PTP_SYS_OFFSET_PRECISE2 aka
PTP_SYS_OFFSET_PRECISE. Similar to ptp_kvm, system time synchronization
with single-digit ns precision is possible with a quiescent reference clock
(from the Virtio RTC device). This works even when the Virtio device
response is slow compared to ptp_kvm hypercalls.

The following illustrates a test using PTP_SYS_OFFSET_PRECISE, with
interspersed strace log and chrony [2] refclocks log, on arm64. In the
example, chrony tracks a virtio_rtc PTP clock ("PHCV", /dev/ptp0). The raw
offset between the virtio_rtc clock and CLOCK_REALTIME is 0 to 1 ns. At the
device side, the Virtio RTC device artificially delays both the clock read
request, and the response, by 50 ms. Cross-timestamp interpolation still
works with this delay. chrony also monitors a ptp_kvm clock ("PHCK",
/dev/ptp3) for comparison, which yields a similar offset.

	ioctl(5</dev/ptp3>, PTP_SYS_OFFSET_PRECISE, 0xffffe86691c8) = 0 <0.000329>
	===============================================================================
	   Date (UTC) Time         Refid  DP L P  Raw offset   Cooked offset      Disp.
	===============================================================================
	2023-06-29 18:49:55.595742 PHCK    0 N 0  1.000000e-09  8.717931e-10  5.500e-08
	2023-06-29 18:49:55.595742 PHCK    - N -       -        8.717931e-10  5.500e-08
	ioctl(6</dev/ptp0>, PTP_SYS_OFFSET_PRECISE, 0xffffe86691c8) = 0 <0.101545>
	2023-06-29 18:49:56.147766 PHCV    0 N 0  1.000000e-09  8.801870e-10  5.500e-08
	2023-06-29 18:49:56.147766 PHCV    - N -       -        8.801870e-10  5.500e-08
	ioctl(5</dev/ptp3>, PTP_SYS_OFFSET_PRECISE, 0xffffe86691c8) = 0 <0.000195>
	2023-06-29 18:49:56.202446 PHCK    0 N 0  1.000000e-09  7.364180e-10  5.500e-08
	2023-06-29 18:49:56.202446 PHCK    - N -       -        7.364180e-10  5.500e-08
	ioctl(6</dev/ptp0>, PTP_SYS_OFFSET_PRECISE, 0xffffe86691c8) = 0 <0.101484>
	2023-06-29 18:49:56.754641 PHCV    0 N 0  0.000000e+00 -2.617368e-10  5.500e-08
	2023-06-29 18:49:56.754641 PHCV    - N -       -       -2.617368e-10  5.500e-08
	ioctl(5</dev/ptp3>, PTP_SYS_OFFSET_PRECISE, 0xffffe86691c8) = 0 <0.000270>
	2023-06-29 18:49:56.809282 PHCK    0 N 0  1.000000e-09  7.779321e-10  5.500e-08
	2023-06-29 18:49:56.809282 PHCK    - N -       -        7.779321e-10  5.500e-08
	ioctl(6</dev/ptp0>, PTP_SYS_OFFSET_PRECISE, 0xffffe86691c8) = 0 <0.101510>
	2023-06-29 18:49:57.361376 PHCV    0 N 0  0.000000e+00 -2.198794e-10  5.500e-08
	2023-06-29 18:49:57.361376 PHCV    - N -       -       -2.198794e-10  5.500e-08

This patch series only adds special support for the Arm Generic Timer
clocksource. At the driver side, it should be easy to support more
clocksources.

Fallback PTP clock interface
----------------------------

Without special support for the current clocksource, time synchronization
programs can still use ioctl PTP_SYS_OFFSET_EXTENDED2 aka
PTP_SYS_OFFSET_EXTENDED. In this case, precision will generally be worse
and will depend on the Virtio device response characteristics.

The following illustrates a test using PTP_SYS_OFFSET_EXTENDED, with
interspersed strace log and chrony refclocks log, on x86-64 (with `ts'
values omitted):

	ioctl(5, PTP_SYS_OFFSET_EXTENDED, {n_samples=10, ts=OMITTED}) = 0
	===============================================================================
	   Date (UTC) Time         Refid  DP L P  Raw offset   Cooked offset      Disp.
	===============================================================================
	2023-06-28 14:11:26.697782 PHCV    0 N 0  3.318200e-05  3.450891e-05  4.611e-06
	2023-06-28 14:11:26.697782 PHCV    - N -       -        3.450891e-05  4.611e-06
	ioctl(5, PTP_SYS_OFFSET_EXTENDED, {n_samples=10, ts=OMITTED}) = 0
	2023-06-28 14:11:27.208763 PHCV    0 N 0 -3.792800e-05 -4.023965e-05  4.611e-06
	2023-06-28 14:11:27.208763 PHCV    - N -       -       -4.023965e-05  4.611e-06
	ioctl(5, PTP_SYS_OFFSET_EXTENDED, {n_samples=10, ts=OMITTED}) = 0
	2023-06-28 14:11:27.722818 PHCV    0 N 0 -3.328600e-05 -3.134404e-05  4.611e-06
	2023-06-28 14:11:27.722818 PHCV    - N -       -       -3.134404e-05  4.611e-06
	ioctl(5, PTP_SYS_OFFSET_EXTENDED, {n_samples=10, ts=OMITTED}) = 0
	2023-06-28 14:11:28.233572 PHCV    0 N 0 -4.966900e-05 -4.584331e-05  4.611e-06
	2023-06-28 14:11:28.233572 PHCV    - N -       -       -4.584331e-05  4.611e-06
	ioctl(5, PTP_SYS_OFFSET_EXTENDED, {n_samples=10, ts=OMITTED}) = 0
	2023-06-28 14:11:28.742737 PHCV    0 N 0  4.902700e-05  5.361388e-05  4.611e-06
	2023-06-28 14:11:28.742737 PHCV    - N -       -        5.361388e-05  4.611e-06

PTP clock setup
---------------

The following udev rule can be used to get a symlink /dev/ptp_virtio to the
UTC clock:

	SUBSYSTEM=="ptp", ATTR{clock_name}=="Virtio PTP type 0, variant 0", SYMLINK += "ptp_virtio"

The following chrony configuration directive can then be added in
/etc/chrony/chrony.conf to synchronize to the Virtio UTC clock:

	refclock PHC /dev/ptp_virtio refid PHCV poll -1 dpoll -1

RTC interface
=============

This patch series adds virtio_rtc as a generic Virtio driver, including
both a PTP clock driver and an RTC class driver.

Feedback is greatly appreciated.

[1] https://lore.kernel.org/virtio-comment/20241206094819.858-1-quic_philber at quicinc.com/T/#t
[2] https://chrony.tuxfamily.org/
[3] https://lore.kernel.org/lkml/20231218073849.35294-1-peter.hilber at opensynergy.com/T/#t

Changelog
=========

v4:

- Update Virtio interface to spec v6.

- Distinguish UTC-like clocks by handling of leap seconds (spec v6).

- Do not create RTC class device for clocks which may step on leap seconds
  (Alexandre Belloni).

- Clear RTC class feature bit instead of defining reduced ops
  (Alexandre Belloni).

- For PTP clock name, always use numeric clock type, and numeric variant.

- Use macros for 64-bit divisions.

- Remove unnecessary memory barriers.

- Cosmetic improvements.

- Drop upstreamed timekeeping bugfixes from series.

v3:

- Update to conform to virtio spec RFC v3 (no significant behavioral
  changes).

- Add RTC class driver with alarm according to virtio spec RFC v3.

- For cross-timestamp corner case fix, switch back to v1 style closed
  interval test (Thomas Gleixner).

v2:

- Depend on patch series "treewide: Use clocksource id for
  get_device_system_crosststamp()" to avoid requiring a clocksource pointer
  with get_device_system_crosststamp().

- Assume Arm Generic Timer will use CP15 virtual counter. Drop
  arm_arch_timer helper functions (Marc Zyngier).

- Improve cross-timestamp fixes problem description and implementation
  (John Stultz).


Peter Hilber (4):
  virtio_rtc: Add module and driver core
  virtio_rtc: Add PTP clocks
  virtio_rtc: Add Arm Generic Timer cross-timestamping
  virtio_rtc: Add RTC class driver

 MAINTAINERS                          |    7 +
 drivers/virtio/Kconfig               |   64 ++
 drivers/virtio/Makefile              |    5 +
 drivers/virtio/virtio_rtc_arm.c      |   23 +
 drivers/virtio/virtio_rtc_class.c    |  268 +++++
 drivers/virtio/virtio_rtc_driver.c   | 1361 ++++++++++++++++++++++++++
 drivers/virtio/virtio_rtc_internal.h |  122 +++
 drivers/virtio/virtio_rtc_ptp.c      |  348 +++++++
 include/uapi/linux/virtio_rtc.h      |  286 ++++++
 9 files changed, 2484 insertions(+)
 create mode 100644 drivers/virtio/virtio_rtc_arm.c
 create mode 100644 drivers/virtio/virtio_rtc_class.c
 create mode 100644 drivers/virtio/virtio_rtc_driver.c
 create mode 100644 drivers/virtio/virtio_rtc_internal.h
 create mode 100644 drivers/virtio/virtio_rtc_ptp.c
 create mode 100644 include/uapi/linux/virtio_rtc.h


base-commit: 8503810115fbff903f626adc0788daa048302bc0
-- 
2.43.0



From quic_philber at quicinc.com  Thu Dec 19 12:11:07 2024
From: quic_philber at quicinc.com (Peter Hilber)
Date: Thu, 19 Dec 2024 21:11:07 +0100
Subject: [RFC PATCH v4 1/4] virtio_rtc: Add module and driver core
In-Reply-To: <20241219201118.2233-1-quic_philber@quicinc.com>
References: <20241219201118.2233-1-quic_philber@quicinc.com>
Message-ID: <20241219201118.2233-2-quic_philber@quicinc.com>

Add the virtio_rtc module and driver core. The virtio_rtc module implements
a driver compatible with the proposed Virtio RTC device specification.
The Virtio RTC (Real Time Clock) device provides information about current
time. The device can provide different clocks, e.g. for the UTC or TAI time
standards, or for physical time elapsed since some past epoch. The driver
can read the clocks with simple or more accurate methods.

Implement the core, which interacts with the Virtio RTC device. Apart from
this, the core does not expose functionality outside of the virtio_rtc
module. A follow-up patch will expose PTP clocks.

Provide synchronous messaging, which is enough for the expected time
synchronization use cases through PTP clocks (similar to ptp_kvm) or RTC
Class driver.

Signed-off-by: Peter Hilber <quic_philber at quicinc.com>
---

Notes:
    v4:
    
    - Update Virtio interface to spec v6.
    
    - Distinguish UTC-like clocks by handling of leap seconds (spec v6).
    
    - Remove unnecessary memory barriers.
    
    - Cosmetic improvements.
    
    v3:
    
    - merge readq and controlq into a single requestq (spec v3)
    
    - don't guard cross-timestamping with feature bit (spec v3)
    
    - pad message headers to 64 bits (spec v3)
    
    - reduce clock id to 16 bits (spec v3)
    
    - change Virtio status codes (spec v3)
    
    - use 'VIRTIO_RTC_REQ_' prefix for request messages (spec v3)

 MAINTAINERS                          |   7 +
 drivers/virtio/Kconfig               |  13 +
 drivers/virtio/Makefile              |   2 +
 drivers/virtio/virtio_rtc_driver.c   | 767 +++++++++++++++++++++++++++
 drivers/virtio/virtio_rtc_internal.h |  24 +
 include/uapi/linux/virtio_rtc.h      | 201 +++++++
 6 files changed, 1014 insertions(+)
 create mode 100644 drivers/virtio/virtio_rtc_driver.c
 create mode 100644 drivers/virtio/virtio_rtc_internal.h
 create mode 100644 include/uapi/linux/virtio_rtc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index c67f868ea1c9..71bb2661a7bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -25040,6 +25040,13 @@ S:	Maintained
 F:	drivers/nvdimm/nd_virtio.c
 F:	drivers/nvdimm/virtio_pmem.c
 
+VIRTIO RTC DRIVER
+M:	Peter Hilber <quic_philber at quicinc.com>
+L:	virtualization at lists.linux.dev
+S:	Maintained
+F:	drivers/virtio/virtio_rtc_*
+F:	include/uapi/linux/virtio_rtc.h
+
 VIRTIO SOUND DRIVER
 M:	Anton Yakovlev <anton.yakovlev at opensynergy.com>
 M:	"Michael S. Tsirkin" <mst at redhat.com>
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 2eb747311bfd..83bcb06acb6c 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -188,4 +188,17 @@ config VIRTIO_DEBUG
 
 	  If unsure, say N.
 
+config VIRTIO_RTC
+	tristate "Virtio RTC driver"
+	depends on VIRTIO
+	depends on PTP_1588_CLOCK_OPTIONAL
+	help
+	 This driver provides current time from a Virtio RTC device. The driver
+	 provides the time through one or more clocks.
+
+	 To compile this code as a module, choose M here: the module will be
+	 called virtio_rtc.
+
+	 If unsure, say M.
+
 endif # VIRTIO_MENU
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 58b2b0489fc9..c41c4c0f9264 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -14,3 +14,5 @@ obj-$(CONFIG_VIRTIO_VDPA) += virtio_vdpa.o
 obj-$(CONFIG_VIRTIO_MEM) += virtio_mem.o
 obj-$(CONFIG_VIRTIO_DMA_SHARED_BUFFER) += virtio_dma_buf.o
 obj-$(CONFIG_VIRTIO_DEBUG) += virtio_debug.o
+obj-$(CONFIG_VIRTIO_RTC) += virtio_rtc.o
+virtio_rtc-y := virtio_rtc_driver.o
diff --git a/drivers/virtio/virtio_rtc_driver.c b/drivers/virtio/virtio_rtc_driver.c
new file mode 100644
index 000000000000..b2abf01d1534
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_driver.c
@@ -0,0 +1,767 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * virtio_rtc driver core
+ *
+ * Copyright (C) 2022-2024 OpenSynergy GmbH
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/completion.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/module.h>
+
+#include <uapi/linux/virtio_rtc.h>
+
+#include "virtio_rtc_internal.h"
+
+/* virtqueue order */
+enum {
+	VIORTC_REQUESTQ,
+	VIORTC_MAX_NR_QUEUES,
+};
+
+/**
+ * struct viortc_vq - virtqueue abstraction
+ * @vq: virtqueue
+ * @lock: protects access to vq
+ */
+struct viortc_vq {
+	struct virtqueue *vq;
+	spinlock_t lock;
+};
+
+/**
+ * struct viortc_dev - virtio_rtc device data
+ * @vdev: virtio device
+ * @vqs: virtqueues
+ * @num_clocks: # of virtio_rtc clocks
+ */
+struct viortc_dev {
+	struct virtio_device *vdev;
+	struct viortc_vq vqs[VIORTC_MAX_NR_QUEUES];
+	u16 num_clocks;
+};
+
+/**
+ * struct viortc_msg - Message requested by driver, responded by device.
+ * @viortc: device data
+ * @req: request buffer
+ * @resp: response buffer
+ * @responded: vqueue callback signals response reception
+ * @refcnt: Message reference count, message and buffers will be deallocated
+ *	    once 0. refcnt is decremented in the vqueue callback and in the
+ *	    thread waiting on the responded completion.
+ *          If a message response wait function times out, the message will be
+ *          freed upon late reception (refcnt will reach 0 in the callback), or
+ *          device removal.
+ * @req_size: size of request in bytes
+ * @resp_cap: maximum size of response in bytes
+ * @resp_actual_size: actual size of response
+ */
+struct viortc_msg {
+	struct viortc_dev *viortc;
+	void *req;
+	void *resp;
+	struct completion responded;
+	refcount_t refcnt;
+	unsigned int req_size;
+	unsigned int resp_cap;
+	unsigned int resp_actual_size;
+};
+
+/**
+ * viortc_msg_init() - Allocate and initialize requestq message.
+ * @viortc: device data
+ * @msg_type: virtio_rtc message type
+ * @req_size: size of request buffer to be allocated
+ * @resp_cap: size of response buffer to be allocated
+ *
+ * Initializes the message refcnt to 2. The refcnt will be decremented once in
+ * the virtqueue callback, and once in the thread waiting on the message (on
+ * completion or timeout).
+ *
+ * Context: Process context.
+ * Return: non-NULL on success.
+ */
+static struct viortc_msg *viortc_msg_init(struct viortc_dev *viortc,
+					  u16 msg_type, unsigned int req_size,
+					  unsigned int resp_cap)
+{
+	struct viortc_msg *msg;
+	struct device *dev = &viortc->vdev->dev;
+	struct virtio_rtc_req_head *req_head;
+
+	msg = devm_kzalloc(dev, sizeof(*msg), GFP_KERNEL);
+	if (!msg)
+		return NULL;
+
+	init_completion(&msg->responded);
+
+	msg->req = devm_kzalloc(dev, req_size, GFP_KERNEL);
+	if (!msg->req)
+		goto err_free_msg;
+
+	req_head = msg->req;
+
+	msg->resp = devm_kzalloc(dev, resp_cap, GFP_KERNEL);
+	if (!msg->resp)
+		goto err_free_msg_req;
+
+	msg->viortc = viortc;
+	msg->req_size = req_size;
+	msg->resp_cap = resp_cap;
+
+	refcount_set(&msg->refcnt, 2);
+
+	req_head->msg_type = virtio_cpu_to_le(msg_type, req_head->msg_type);
+
+	return msg;
+
+err_free_msg_req:
+	devm_kfree(dev, msg->req);
+
+err_free_msg:
+	devm_kfree(dev, msg);
+
+	return NULL;
+}
+
+/**
+ * viortc_msg_release() - Decrement message refcnt, potentially free message.
+ * @msg: message requested by driver
+ *
+ * Context: Any context.
+ */
+static void viortc_msg_release(struct viortc_msg *msg)
+{
+	if (refcount_dec_and_test(&msg->refcnt)) {
+		struct device *dev = &msg->viortc->vdev->dev;
+
+		devm_kfree(dev, msg->req);
+		devm_kfree(dev, msg->resp);
+		devm_kfree(dev, msg);
+	}
+}
+
+/**
+ * viortc_do_cb() - generic virtqueue callback logic
+ * @vq: virtqueue
+ * @handle_buf: function to process a used buffer
+ *
+ * Context: virtqueue callback, typically interrupt. Takes and releases vq lock.
+ */
+static void viortc_do_cb(struct virtqueue *vq,
+			 void (*handle_buf)(void *token, unsigned int len,
+					    struct virtqueue *vq,
+					    struct viortc_vq *viortc_vq,
+					    struct viortc_dev *viortc))
+{
+	struct viortc_dev *viortc = vq->vdev->priv;
+	struct viortc_vq *viortc_vq;
+	bool cb_enabled = true;
+	unsigned long flags;
+	unsigned int len;
+	void *token;
+
+	viortc_vq = &viortc->vqs[vq->index];
+
+	for (;;) {
+		spin_lock_irqsave(&viortc_vq->lock, flags);
+
+		if (cb_enabled) {
+			virtqueue_disable_cb(vq);
+			cb_enabled = false;
+		}
+
+		token = virtqueue_get_buf(vq, &len);
+		if (!token) {
+			if (virtqueue_enable_cb(vq)) {
+				spin_unlock_irqrestore(&viortc_vq->lock, flags);
+				return;
+			}
+			cb_enabled = true;
+		}
+
+		spin_unlock_irqrestore(&viortc_vq->lock, flags);
+
+		if (token)
+			handle_buf(token, len, vq, viortc_vq, viortc);
+	}
+}
+
+/**
+ * viortc_requestq_hdlr() - process a requestq used buffer
+ * @token: token identifying the buffer
+ * @len: bytes written by device
+ * @vq: virtqueue
+ * @viortc_vq: device specific data for virtqueue
+ * @viortc: device data
+ *
+ * Signals completion for each received message.
+ *
+ * Context: virtqueue callback
+ */
+static void viortc_requestq_hdlr(void *token, unsigned int len,
+				 struct virtqueue *vq,
+				 struct viortc_vq *viortc_vq,
+				 struct viortc_dev *viortc)
+{
+	struct viortc_msg *msg = token;
+
+	msg->resp_actual_size = len;
+
+	/*
+	 * completion waiter must see our msg metadata, but complete() does not
+	 * guarantee a memory barrier
+	 */
+	smp_wmb();
+
+	complete(&msg->responded);
+	viortc_msg_release(msg);
+}
+
+/**
+ * viortc_cb_requestq() - callback for requestq
+ * @vq: virtqueue
+ *
+ * Context: virtqueue callback
+ */
+static void viortc_cb_requestq(struct virtqueue *vq)
+{
+	viortc_do_cb(vq, viortc_requestq_hdlr);
+}
+
+/**
+ * viortc_get_resp_errno() - converts virtio_rtc errnos to system errnos
+ * @resp_head: message response header
+ *
+ * Return: negative system errno, or 0
+ */
+static int viortc_get_resp_errno(struct virtio_rtc_resp_head *resp_head)
+{
+	switch (virtio_le_to_cpu(resp_head->status)) {
+	case VIRTIO_RTC_S_OK:
+		return 0;
+	case VIRTIO_RTC_S_EOPNOTSUPP:
+		return -EOPNOTSUPP;
+	case VIRTIO_RTC_S_EINVAL:
+		return -EINVAL;
+	case VIRTIO_RTC_S_ENODEV:
+		return -ENODEV;
+	case VIRTIO_RTC_S_EIO:
+	default:
+		return -EIO;
+	}
+}
+
+/**
+ * viortc_msg_xfer() - send message request, wait until message response
+ * @vq: virtqueue
+ * @msg: message with driver request
+ * @timeout_jiffies: message response timeout, 0 for no timeout
+ *
+ * Context: Process context. Takes and releases vq.lock. May sleep.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_msg_xfer(struct viortc_vq *vq, struct viortc_msg *msg,
+			   unsigned long timeout_jiffies)
+{
+	int ret;
+	unsigned long flags;
+	struct scatterlist out_sg[1];
+	struct scatterlist in_sg[1];
+	struct scatterlist *sgs[2] = { out_sg, in_sg };
+	bool notify;
+
+	sg_init_one(out_sg, msg->req, msg->req_size);
+	sg_init_one(in_sg, msg->resp, msg->resp_cap);
+
+	spin_lock_irqsave(&vq->lock, flags);
+
+	ret = virtqueue_add_sgs(vq->vq, sgs, 1, 1, msg, GFP_ATOMIC);
+	if (ret) {
+		spin_unlock_irqrestore(&vq->lock, flags);
+		/*
+		 * Release in place of the response callback, which will never
+		 * come.
+		 */
+		viortc_msg_release(msg);
+		return ret;
+	}
+
+	notify = virtqueue_kick_prepare(vq->vq);
+
+	spin_unlock_irqrestore(&vq->lock, flags);
+
+	if (notify)
+		virtqueue_notify(vq->vq);
+
+	if (timeout_jiffies) {
+		long timeout_ret;
+
+		timeout_ret = wait_for_completion_interruptible_timeout(
+			&msg->responded, timeout_jiffies);
+
+		if (!timeout_ret)
+			return -ETIMEDOUT;
+		else if (timeout_ret < 0)
+			return (int)timeout_ret;
+	} else {
+		ret = wait_for_completion_interruptible(&msg->responded);
+		if (ret)
+			return ret;
+	}
+
+	/*
+	 * Ensure we can read message metadata written in the virtqueue
+	 * callback.
+	 */
+	smp_rmb();
+
+	/*
+	 * There is not yet a case where returning a short message would make
+	 * sense, so consider any deviation an error.
+	 */
+	if (msg->resp_actual_size != msg->resp_cap)
+		return -EINVAL;
+
+	return viortc_get_resp_errno(msg->resp);
+}
+
+/*
+ * common message handle macros for messages of different types
+ */
+
+/**
+ * VIORTC_DECLARE_MSG_HDL_ONSTACK() - declare message handle on stack
+ * @hdl: message handle name
+ * @msg_id: message type id
+ * @msg_req: message request type
+ * @msg_resp: message response type
+ */
+#define VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, msg_id, msg_req, msg_resp)       \
+	struct {                                                             \
+		struct viortc_msg *msg;                                      \
+		msg_req *req;                                                \
+		msg_resp *resp;                                              \
+		unsigned int req_size;                                       \
+		unsigned int resp_cap;                                       \
+		u16 msg_type;                                                \
+	} hdl = {                                                            \
+		NULL, NULL, NULL, sizeof(msg_req), sizeof(msg_resp), msg_id, \
+	}
+
+/**
+ * VIORTC_MSG() - extract message from message handle
+ * @hdl: message handle
+ *
+ * Return: struct viortc_msg
+ */
+#define VIORTC_MSG(hdl) ((hdl).msg)
+
+/**
+ * VIORTC_MSG_INIT() - initialize message handle
+ * @hdl: message handle
+ * @viortc: device data (struct viortc_dev *)
+ *
+ * Context: Process context.
+ * Return: 0 on success, -ENOMEM otherwise.
+ */
+#define VIORTC_MSG_INIT(hdl, viortc)                                         \
+	({                                                                   \
+		typeof(hdl) *_hdl = &(hdl);                                  \
+									     \
+		_hdl->msg = viortc_msg_init((viortc), _hdl->msg_type,        \
+					    _hdl->req_size, _hdl->resp_cap); \
+		if (_hdl->msg) {                                             \
+			_hdl->req = _hdl->msg->req;                          \
+			_hdl->resp = _hdl->msg->resp;                        \
+		}                                                            \
+		_hdl->msg ? 0 : -ENOMEM;                                     \
+	})
+
+/**
+ * VIORTC_MSG_WRITE() - write a request message field
+ * @hdl: message handle
+ * @dest_member: request message field name
+ * @src_ptr: pointer to data of compatible type
+ *
+ * Writes the field in little-endian format.
+ */
+#define VIORTC_MSG_WRITE(hdl, dest_member, src_ptr)                         \
+	do {                                                                \
+		typeof(hdl) _hdl = (hdl);                                   \
+		typeof(src_ptr) _src_ptr = (src_ptr);                       \
+									    \
+		/* Sanity check: must match the member's type */            \
+		typecheck(typeof(_hdl.req->dest_member), *_src_ptr);        \
+									    \
+		_hdl.req->dest_member =                                     \
+			virtio_cpu_to_le(*_src_ptr, _hdl.req->dest_member); \
+	} while (0)
+
+/**
+ * VIORTC_MSG_READ() - read from a response message field
+ * @hdl: message handle
+ * @src_member: response message field name
+ * @dest_ptr: pointer to data of compatible type
+ *
+ * Converts from little-endian format and writes to dest_ptr.
+ */
+#define VIORTC_MSG_READ(hdl, src_member, dest_ptr)                     \
+	do {                                                           \
+		typeof(dest_ptr) _dest_ptr = (dest_ptr);               \
+								       \
+		/* Sanity check: must match the member's type */       \
+		typecheck(typeof((hdl).resp->src_member), *_dest_ptr); \
+								       \
+		*_dest_ptr = virtio_le_to_cpu((hdl).resp->src_member); \
+	} while (0)
+
+/*
+ * read requests
+ */
+
+/** timeout for clock readings, where timeouts are considered non-fatal */
+#define VIORTC_MSG_READ_TIMEOUT (msecs_to_jiffies(60 * 1000))
+
+/**
+ * viortc_read() - VIRTIO_RTC_REQ_READ wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @reading: clock reading [ns]
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_read(struct viortc_dev *viortc, u16 vio_clk_id, u64 *reading)
+{
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, VIRTIO_RTC_REQ_READ,
+				       struct virtio_rtc_req_read,
+				       struct virtio_rtc_resp_read);
+	int ret;
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      VIORTC_MSG_READ_TIMEOUT);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, clock_reading, reading);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_read_cross() - VIRTIO_RTC_REQ_READ_CROSS wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @hw_counter: virtio_rtc HW counter type
+ * @reading: clock reading [ns]
+ * @cycles: HW counter cycles during clock reading
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_read_cross(struct viortc_dev *viortc, u16 vio_clk_id, u8 hw_counter,
+		      u64 *reading, u64 *cycles)
+{
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, VIRTIO_RTC_REQ_READ_CROSS,
+				       struct virtio_rtc_req_read_cross,
+				       struct virtio_rtc_resp_read_cross);
+	int ret;
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+	VIORTC_MSG_WRITE(hdl, hw_counter, &hw_counter);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      VIORTC_MSG_READ_TIMEOUT);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, clock_reading, reading);
+	VIORTC_MSG_READ(hdl, counter_cycles, cycles);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/*
+ * control requests
+ */
+
+/**
+ * viortc_cfg() - VIRTIO_RTC_REQ_CFG wrapper
+ * @viortc: device data
+ * @num_clocks: # of virtio_rtc clocks
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_cfg(struct viortc_dev *viortc, u16 *num_clocks)
+{
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, VIRTIO_RTC_REQ_CFG,
+				       struct virtio_rtc_req_cfg,
+				       struct virtio_rtc_resp_cfg);
+	int ret;
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, num_clocks, num_clocks);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_clock_cap() - VIRTIO_RTC_REQ_CLOCK_CAP wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @type: virtio_rtc clock type
+ * @leap_second_smearing: virtio_rtc smearing variant
+ * @flags: struct virtio_rtc_resp_clock_cap.flags
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_clock_cap(struct viortc_dev *viortc, u16 vio_clk_id, u8 *type,
+			    u8 *leap_second_smearing, u8 *flags)
+{
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, VIRTIO_RTC_REQ_CLOCK_CAP,
+				       struct virtio_rtc_req_clock_cap,
+				       struct virtio_rtc_resp_clock_cap);
+	int ret;
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, type, type);
+	VIORTC_MSG_READ(hdl, leap_second_smearing, leap_second_smearing);
+	VIORTC_MSG_READ(hdl, flags, flags);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/**
+ * viortc_cross_cap() - VIRTIO_RTC_REQ_CROSS_CAP wrapper
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @hw_counter: virtio_rtc HW counter type
+ * @supported: xtstamping is supported for the vio_clk_id/hw_counter pair
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u8 hw_counter,
+		     bool *supported)
+{
+	VIORTC_DECLARE_MSG_HDL_ONSTACK(hdl, VIRTIO_RTC_REQ_CROSS_CAP,
+				       struct virtio_rtc_req_cross_cap,
+				       struct virtio_rtc_resp_cross_cap);
+	u8 flags;
+	int ret;
+
+	ret = VIORTC_MSG_INIT(hdl, viortc);
+	if (ret)
+		return ret;
+
+	VIORTC_MSG_WRITE(hdl, clock_id, &vio_clk_id);
+	VIORTC_MSG_WRITE(hdl, hw_counter, &hw_counter);
+
+	ret = viortc_msg_xfer(&viortc->vqs[VIORTC_REQUESTQ], VIORTC_MSG(hdl),
+			      0);
+	if (ret) {
+		dev_dbg(&viortc->vdev->dev, "%s: xfer returned %d\n", __func__,
+			ret);
+		goto out_release;
+	}
+
+	VIORTC_MSG_READ(hdl, flags, &flags);
+	*supported = !!(flags & VIRTIO_RTC_FLAG_CROSS_CAP);
+
+out_release:
+	viortc_msg_release(VIORTC_MSG(hdl));
+
+	return ret;
+}
+
+/*
+ * init, deinit
+ */
+
+/**
+ * viortc_clocks_init() - init local representations of virtio_rtc clocks
+ * @viortc: device data
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_clocks_init(struct viortc_dev *viortc)
+{
+	int ret;
+	u16 num_clocks;
+
+	ret = viortc_cfg(viortc, &num_clocks);
+	if (ret)
+		return ret;
+
+	if (num_clocks < 1) {
+		dev_err(&viortc->vdev->dev, "device reported 0 clocks\n");
+		return -ENODEV;
+	}
+
+	viortc->num_clocks = num_clocks;
+
+	/* In the future, PTP clocks will be initialized here. */
+	(void)viortc_clock_cap;
+
+	return ret;
+}
+
+/**
+ * viortc_init_vqs() - init virtqueues
+ * @viortc: device data
+ *
+ * Inits virtqueues and associated data.
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_init_vqs(struct viortc_dev *viortc)
+{
+	int ret;
+	struct virtio_device *vdev = viortc->vdev;
+	struct virtqueue_info vqs_info[] = {
+		{ "requestq", viortc_cb_requestq },
+	};
+	struct virtqueue *vqs[VIORTC_MAX_NR_QUEUES];
+	int nr_queues;
+
+	nr_queues = VIORTC_REQUESTQ + 1;
+
+	ret = virtio_find_vqs(vdev, nr_queues, vqs, vqs_info, NULL);
+	if (ret)
+		return ret;
+
+	viortc->vqs[VIORTC_REQUESTQ].vq = vqs[VIORTC_REQUESTQ];
+	spin_lock_init(&viortc->vqs[VIORTC_REQUESTQ].lock);
+
+	return 0;
+}
+
+/**
+ * viortc_probe() - probe a virtio_rtc virtio device
+ * @vdev: virtio device
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_probe(struct virtio_device *vdev)
+{
+	struct viortc_dev *viortc;
+	int ret;
+
+	viortc = devm_kzalloc(&vdev->dev, sizeof(*viortc), GFP_KERNEL);
+	if (!viortc)
+		return -ENOMEM;
+
+	vdev->priv = viortc;
+	viortc->vdev = vdev;
+
+	ret = viortc_init_vqs(viortc);
+	if (ret)
+		return ret;
+
+	virtio_device_ready(vdev);
+
+	ret = viortc_clocks_init(viortc);
+	if (ret)
+		goto err_reset_vdev;
+
+	return 0;
+
+err_reset_vdev:
+	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
+
+	return ret;
+}
+
+/**
+ * viortc_remove() - remove a virtio_rtc virtio device
+ * @vdev: virtio device
+ */
+static void viortc_remove(struct virtio_device *vdev)
+{
+	/* In the future, PTP clocks will be deinitialized here. */
+
+	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
+}
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_CLOCK, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+MODULE_DEVICE_TABLE(virtio, id_table);
+
+static struct virtio_driver virtio_rtc_drv = {
+	.driver.name = KBUILD_MODNAME,
+	.id_table = id_table,
+	.probe = viortc_probe,
+	.remove = viortc_remove,
+};
+
+module_virtio_driver(virtio_rtc_drv);
+
+MODULE_DESCRIPTION("Virtio RTC driver");
+MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/virtio/virtio_rtc_internal.h b/drivers/virtio/virtio_rtc_internal.h
new file mode 100644
index 000000000000..9c249c15b68f
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_internal.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * virtio_rtc internal interfaces
+ *
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _VIRTIO_RTC_INTERNAL_H_
+#define _VIRTIO_RTC_INTERNAL_H_
+
+#include <linux/types.h>
+
+/* driver core IFs */
+
+struct viortc_dev;
+
+int viortc_read(struct viortc_dev *viortc, u16 vio_clk_id, u64 *reading);
+int viortc_read_cross(struct viortc_dev *viortc, u16 vio_clk_id, u8 hw_counter,
+		      u64 *reading, u64 *cycles);
+int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u8 hw_counter,
+		     bool *supported);
+
+#endif /* _VIRTIO_RTC_INTERNAL_H_ */
diff --git a/include/uapi/linux/virtio_rtc.h b/include/uapi/linux/virtio_rtc.h
new file mode 100644
index 000000000000..8fb04846b397
--- /dev/null
+++ b/include/uapi/linux/virtio_rtc.h
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2022-2024 OpenSynergy GmbH
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _LINUX_VIRTIO_RTC_H
+#define _LINUX_VIRTIO_RTC_H
+
+#include <linux/types.h>
+
+/* read request message types */
+
+#define VIRTIO_RTC_REQ_READ			0x0001
+#define VIRTIO_RTC_REQ_READ_CROSS		0x0002
+
+/* control request message types */
+
+#define VIRTIO_RTC_REQ_CFG			0x1000
+#define VIRTIO_RTC_REQ_CLOCK_CAP		0x1001
+#define VIRTIO_RTC_REQ_CROSS_CAP		0x1002
+
+/* Message headers */
+
+/** common request header */
+struct virtio_rtc_req_head {
+	__le16 msg_type;
+	__u8 reserved[6];
+};
+
+/** common response header */
+struct virtio_rtc_resp_head {
+#define VIRTIO_RTC_S_OK			0
+#define VIRTIO_RTC_S_EOPNOTSUPP		2
+#define VIRTIO_RTC_S_ENODEV		3
+#define VIRTIO_RTC_S_EINVAL		4
+#define VIRTIO_RTC_S_EIO		5
+	__u8 status;
+	__u8 reserved[7];
+};
+
+/* read requests */
+
+/* VIRTIO_RTC_REQ_READ message */
+
+struct virtio_rtc_req_read {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__u8 reserved[6];
+};
+
+struct virtio_rtc_resp_read {
+	struct virtio_rtc_resp_head head;
+	__le64 clock_reading;
+};
+
+/* VIRTIO_RTC_REQ_READ_CROSS message */
+
+struct virtio_rtc_leap_info {
+	__le32 smear_offset_nsec;
+	__le16 tai_offset_sec;
+#define VIRTIO_RTC_LEAP_NONE		0x00
+#define VIRTIO_RTC_LEAP_PRE_POS		0x01
+#define VIRTIO_RTC_LEAP_PRE_NEG		0x02
+#define VIRTIO_RTC_LEAP_POS		0x03
+#define VIRTIO_RTC_LEAP_POST_POS	0x04
+#define VIRTIO_RTC_LEAP_POST_NEG	0x05
+#define VIRTIO_RTC_LEAP_SMEAR_PRE_POS	0x16
+#define VIRTIO_RTC_LEAP_SMEAR_PRE_NEG	0x17
+#define VIRTIO_RTC_LEAP_SMEAR_POS	0x38
+#define VIRTIO_RTC_LEAP_SMEAR_NEG	0x39
+#define VIRTIO_RTC_LEAP_SMEAR_POST_POS	0x1A
+#define VIRTIO_RTC_LEAP_SMEAR_POST_NEG	0x1B
+/* common bits in above */
+#define VIRTIO_RTC_LEAP_SMEAR_NEAR	0x10
+#define VIRTIO_RTC_LEAP_SMEAR_NOW	0x20
+	__u8 leap;
+#define VIRTIO_RTC_FLAG_LEAP_VALID		(1 << 0)
+#define VIRTIO_RTC_FLAG_TAI_OFFSET_VALID	(1 << 1)
+#define VIRTIO_RTC_FLAG_SMEAR_OFFSET_VALID	(1 << 2)
+	__u8 flags;
+};
+
+struct virtio_rtc_perf {
+	__le64 freq_esterror;
+	__le64 freq_maxerror;
+	__le64 time_esterror;
+	__le64 time_maxerror;
+#define VIRTIO_RTC_FLAG_FREQ_ESTERROR_VALID	(1 << 3)
+#define VIRTIO_RTC_FLAG_FREQ_MAXERROR_VALID	(1 << 4)
+#define VIRTIO_RTC_FLAG_TIME_ESTERROR_VALID	(1 << 5)
+#define VIRTIO_RTC_FLAG_TIME_MAXERROR_VALID	(1 << 6)
+	__u8 flags;
+#define VIRTIO_RTC_STATUS_UNKNOWN		0
+#define VIRTIO_RTC_STATUS_INITIALIZING		1
+#define VIRTIO_RTC_STATUS_SYNCHRONIZED		2
+#define VIRTIO_RTC_STATUS_FREERUNNING		3
+#define VIRTIO_RTC_STATUS_UNRELIABLE		4
+	__u8 clock_status;
+	__u8 reserved[6];
+};
+
+struct virtio_rtc_req_read_cross {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+/* Arm Generic Timer Counter-timer Virtual Count Register (CNTVCT_EL0) */
+#define VIRTIO_RTC_COUNTER_ARM_VCT	0
+/* x86 Time-Stamp Counter */
+#define VIRTIO_RTC_COUNTER_X86_TSC	1
+/* Invalid */
+#define VIRTIO_RTC_COUNTER_INVALID	0xFF
+	__u8 hw_counter;
+	__u8 reserved[5];
+};
+
+struct virtio_rtc_resp_read_cross {
+	struct virtio_rtc_resp_head head;
+	__le64 clock_reading;
+	__le64 counter_cycles;
+	struct virtio_rtc_leap_info leap_info;
+	struct virtio_rtc_perf perf;
+};
+
+/* control requests */
+
+/* VIRTIO_RTC_REQ_CFG message */
+
+struct virtio_rtc_req_cfg {
+	struct virtio_rtc_req_head head;
+	/* no request params */
+};
+
+struct virtio_rtc_resp_cfg {
+	struct virtio_rtc_resp_head head;
+	/** # of clocks -> clock ids < num_clocks are valid */
+	__le16 num_clocks;
+	__u8 reserved[6];
+};
+
+/* VIRTIO_RTC_REQ_CLOCK_CAP message */
+
+struct virtio_rtc_req_clock_cap {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__u8 reserved[6];
+};
+
+struct virtio_rtc_resp_clock_cap {
+	struct virtio_rtc_resp_head head;
+#define VIRTIO_RTC_CLOCK_UTC			0
+#define VIRTIO_RTC_CLOCK_TAI			1
+#define VIRTIO_RTC_CLOCK_MONOTONIC		2
+#define VIRTIO_RTC_CLOCK_UTC_SMEARED		3
+#define VIRTIO_RTC_CLOCK_UTC_MAYBE_SMEARED	4
+	__u8 type;
+#define VIRTIO_RTC_SMEAR_UNSPECIFIED	0
+#define VIRTIO_RTC_SMEAR_NOON_LINEAR	1
+#define VIRTIO_RTC_SMEAR_UTC_SLS	2
+	__u8 leap_second_smearing;
+#define VIRTIO_RTC_FLAG_LEAP_CAP		(1 << 0)
+#define VIRTIO_RTC_FLAG_TAI_OFFSET_CAP		(1 << 1)
+#define VIRTIO_RTC_FLAG_SMEAR_OFFSET_CAP	(1 << 2)
+	__u8 flags;
+	__u8 reserved[5];
+};
+
+/* VIRTIO_RTC_REQ_CROSS_CAP message */
+
+struct virtio_rtc_req_cross_cap {
+	struct virtio_rtc_req_head head;
+	__le16 clock_id;
+	__u8 hw_counter;
+	__u8 reserved[5];
+};
+
+struct virtio_rtc_resp_cross_cap {
+	struct virtio_rtc_resp_head head;
+#define VIRTIO_RTC_FLAG_CROSS_CAP	(1 << 0)
+	__u8 flags;
+	__u8 reserved[7];
+};
+
+/** Union of request types for requestq */
+union virtio_rtc_req_requestq {
+	struct virtio_rtc_req_read read;
+	struct virtio_rtc_req_read_cross read_cross;
+	struct virtio_rtc_req_cfg cfg;
+	struct virtio_rtc_req_clock_cap clock_cap;
+	struct virtio_rtc_req_cross_cap cross_cap;
+};
+
+/** Union of response types for requestq */
+union virtio_rtc_resp_requestq {
+	struct virtio_rtc_resp_read read;
+	struct virtio_rtc_resp_read_cross read_cross;
+	struct virtio_rtc_resp_cfg cfg;
+	struct virtio_rtc_resp_clock_cap clock_cap;
+	struct virtio_rtc_resp_cross_cap cross_cap;
+};
+
+#endif /* _LINUX_VIRTIO_RTC_H */
-- 
2.43.0



From quic_philber at quicinc.com  Thu Dec 19 12:11:09 2024
From: quic_philber at quicinc.com (Peter Hilber)
Date: Thu, 19 Dec 2024 21:11:09 +0100
Subject: [RFC PATCH v4 3/4] virtio_rtc: Add Arm Generic Timer cross-timestamping
In-Reply-To: <20241219201118.2233-1-quic_philber@quicinc.com>
References: <20241219201118.2233-1-quic_philber@quicinc.com>
Message-ID: <20241219201118.2233-4-quic_philber@quicinc.com>

Add PTP_SYS_OFFSET_PRECISE2 support on platforms using the Arm Generic
Timer.

Always report the CP15 virtual counter as the HW counter in use by
arm_arch_timer, since the Linux kernel's usage of the Arm Generic Timer
should always be compatible with this.

Signed-off-by: Peter Hilber <quic_philber at quicinc.com>
---

Notes:
    v4:
    
    - Update names and types to spec v6.
    
    v2:
    
    - Depend on prerequisite patch series "treewide: Use clocksource id for
      get_device_system_crosststamp()".
    
    - Return clocksource id instead of calling dropped arm_arch_timer helpers.
    
    - Always report the CP15 virtual counter to be in use by arm_arch_timer,
      since distinction of Arm physical and virtual counter appears unneeded
      after discussion with Marc Zyngier.

 drivers/virtio/Kconfig          | 13 +++++++++++++
 drivers/virtio/Makefile         |  1 +
 drivers/virtio/virtio_rtc_arm.c | 23 +++++++++++++++++++++++
 3 files changed, 37 insertions(+)
 create mode 100644 drivers/virtio/virtio_rtc_arm.c

diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index a14a2b77e142..3d8b366c0625 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -221,6 +221,19 @@ config VIRTIO_RTC_PTP
 
 	 If unsure, say Y.
 
+config VIRTIO_RTC_ARM
+	bool "Virtio RTC cross-timestamping using Arm Generic Timer"
+	default y
+	depends on VIRTIO_RTC_PTP && ARM_ARCH_TIMER
+	help
+	 This enables Virtio RTC cross-timestamping using the Arm Generic Timer.
+	 It only has an effect if the Virtio RTC device also supports this. The
+	 cross-timestamp is available through the PTP clock driver precise
+	 cross-timestamp ioctl (PTP_SYS_OFFSET_PRECISE2 aka
+	 PTP_SYS_OFFSET_PRECISE).
+
+	 If unsure, say Y.
+
 endif # VIRTIO_RTC
 
 endif # VIRTIO_MENU
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 88d6fb8d4731..dbd77f124ba9 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_VIRTIO_DEBUG) += virtio_debug.o
 obj-$(CONFIG_VIRTIO_RTC) += virtio_rtc.o
 virtio_rtc-y := virtio_rtc_driver.o
 virtio_rtc-$(CONFIG_VIRTIO_RTC_PTP) += virtio_rtc_ptp.o
+virtio_rtc-$(CONFIG_VIRTIO_RTC_ARM) += virtio_rtc_arm.o
diff --git a/drivers/virtio/virtio_rtc_arm.c b/drivers/virtio/virtio_rtc_arm.c
new file mode 100644
index 000000000000..211299d72870
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_arm.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Provides cross-timestamp params for Arm.
+ *
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clocksource_ids.h>
+
+#include <uapi/linux/virtio_rtc.h>
+
+#include "virtio_rtc_internal.h"
+
+/* see header for doc */
+
+int viortc_hw_xtstamp_params(u8 *hw_counter, enum clocksource_ids *cs_id)
+{
+	*hw_counter = VIRTIO_RTC_COUNTER_ARM_VCT;
+	*cs_id = CSID_ARM_ARCH_COUNTER;
+
+	return 0;
+}
-- 
2.43.0



From quic_philber at quicinc.com  Thu Dec 19 12:11:08 2024
From: quic_philber at quicinc.com (Peter Hilber)
Date: Thu, 19 Dec 2024 21:11:08 +0100
Subject: [RFC PATCH v4 2/4] virtio_rtc: Add PTP clocks
In-Reply-To: <20241219201118.2233-1-quic_philber@quicinc.com>
References: <20241219201118.2233-1-quic_philber@quicinc.com>
Message-ID: <20241219201118.2233-3-quic_philber@quicinc.com>

Expose the virtio_rtc clocks as PTP clocks to userspace, similar to
ptp_kvm. virtio_rtc can expose multiple clocks, e.g. a UTC clock and a
monotonic clock.

Userspace should distinguish different clocks through the name assigned by
the driver. In particular, UTC-like clocks can also be distinguished by if
and how leap seconds are smeared. udev rules such as the following can be
used to get different symlinks for different clock types:

	SUBSYSTEM=="ptp", ATTR{clock_name}=="Virtio PTP type 0, variant 0", SYMLINK += "ptp_virtio"
	SUBSYSTEM=="ptp", ATTR{clock_name}=="Virtio PTP type 1, variant 0", SYMLINK += "ptp_virtio_tai"
	SUBSYSTEM=="ptp", ATTR{clock_name}=="Virtio PTP type 2, variant 0", SYMLINK += "ptp_virtio_mono"
	SUBSYSTEM=="ptp", ATTR{clock_name}=="Virtio PTP type 3, variant 0", SYMLINK += "ptp_virtio_smear_unspecified"
	SUBSYSTEM=="ptp", ATTR{clock_name}=="Virtio PTP type 3, variant 1", SYMLINK += "ptp_virtio_smear_noon_linear"

The preferred PTP clock reading method is ioctl PTP_SYS_OFFSET_PRECISE2,
through the ptp_clock_info.getcrosststamp() op. For now,
PTP_SYS_OFFSET_PRECISE2 will return -EOPNOTSUPP through a weak function.
PTP_SYS_OFFSET_PRECISE2 requires cross-timestamping support for specific
clocksources, which will be added in the following. If the clocksource
specific code is enabled, check that the Virtio RTC device supports the
respective HW counter before obtaining an actual cross-timestamp from the
Virtio device.

The Virtio RTC device response time may be higher than the timekeeper
seqcount increment interval. Therefore, obtain the cross-timestamp before
calling get_device_system_crosststamp().

As a fallback, support the ioctl PTP_SYS_OFFSET_EXTENDED2 for all
platforms.

Assume that concurrency issues during PTP clock removal are avoided by the
posix_clock framework.

Kconfig recursive dependencies prevent virtio_rtc from implicitly enabling
PTP_1588_CLOCK, therefore just warn the user if PTP_1588_CLOCK is not
available. Since virtio_rtc should in the future also expose clocks as RTC
class devices, do not depend VIRTIO_RTC on PTP_1588_CLOCK.

Signed-off-by: Peter Hilber <quic_philber at quicinc.com>
---

Notes:
    v4:
    
    - Distinguish UTC-like clocks by handling of leap seconds (spec v6).
    
    - For PTP clock name, always use numeric clock type, and numeric variant.
    
    - Update types to spec v6.
    
    - Cosmetic improvements.
    
    v3:
    
    - don't guard cross-timestamping with feature bit (spec v3)
    
    - reduce clock id to 16 bits (spec v3)
    
    v2:
    
    - Depend on prerequisite patch series "treewide: Use clocksource id for
      get_device_system_crosststamp()".
    
    - Check clocksource id before sending crosststamp message to device.
    
    - Do not support multiple hardware counters at runtime any more, since
      distinction of Arm physical and virtual counter appears unneeded after
      discussion with Marc Zyngier.

 drivers/virtio/Kconfig               |  24 +-
 drivers/virtio/Makefile              |   1 +
 drivers/virtio/virtio_rtc_driver.c   | 122 +++++++++-
 drivers/virtio/virtio_rtc_internal.h |  46 ++++
 drivers/virtio/virtio_rtc_ptp.c      | 348 +++++++++++++++++++++++++++
 5 files changed, 537 insertions(+), 4 deletions(-)
 create mode 100644 drivers/virtio/virtio_rtc_ptp.c

diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 83bcb06acb6c..a14a2b77e142 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -194,11 +194,33 @@ config VIRTIO_RTC
 	depends on PTP_1588_CLOCK_OPTIONAL
 	help
 	 This driver provides current time from a Virtio RTC device. The driver
-	 provides the time through one or more clocks.
+	 provides the time through one or more clocks. The Virtio RTC PTP
+	 clocks must be enabled to expose the clocks to userspace.
 
 	 To compile this code as a module, choose M here: the module will be
 	 called virtio_rtc.
 
 	 If unsure, say M.
 
+if VIRTIO_RTC
+
+comment "WARNING: Consider enabling VIRTIO_RTC_PTP."
+	depends on !VIRTIO_RTC_PTP
+
+comment "Enable PTP_1588_CLOCK in order to enable VIRTIO_RTC_PTP."
+	depends on PTP_1588_CLOCK=n
+
+config VIRTIO_RTC_PTP
+	bool "Virtio RTC PTP clocks"
+	default y
+	depends on PTP_1588_CLOCK
+	help
+	 This exposes any Virtio RTC clocks as PTP Hardware Clocks (PHCs) to
+	 userspace. The PHC sysfs attribute "clock_name" describes the clock
+	 type.
+
+	 If unsure, say Y.
+
+endif # VIRTIO_RTC
+
 endif # VIRTIO_MENU
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index c41c4c0f9264..88d6fb8d4731 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_VIRTIO_DMA_SHARED_BUFFER) += virtio_dma_buf.o
 obj-$(CONFIG_VIRTIO_DEBUG) += virtio_debug.o
 obj-$(CONFIG_VIRTIO_RTC) += virtio_rtc.o
 virtio_rtc-y := virtio_rtc_driver.o
+virtio_rtc-$(CONFIG_VIRTIO_RTC_PTP) += virtio_rtc_ptp.o
diff --git a/drivers/virtio/virtio_rtc_driver.c b/drivers/virtio/virtio_rtc_driver.c
index b2abf01d1534..83f975d9a6ae 100644
--- a/drivers/virtio/virtio_rtc_driver.c
+++ b/drivers/virtio/virtio_rtc_driver.c
@@ -36,11 +36,16 @@ struct viortc_vq {
  * struct viortc_dev - virtio_rtc device data
  * @vdev: virtio device
  * @vqs: virtqueues
+ * @clocks_to_unregister: Clock references, which are only used during device
+ *                        removal.
+ *			  For other uses, there would be a race between device
+ *			  creation and setting the pointers here.
  * @num_clocks: # of virtio_rtc clocks
  */
 struct viortc_dev {
 	struct virtio_device *vdev;
 	struct viortc_vq vqs[VIORTC_MAX_NR_QUEUES];
+	struct viortc_ptp_clock **clocks_to_unregister;
 	u16 num_clocks;
 };
 
@@ -637,6 +642,100 @@ int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u8 hw_counter,
  * init, deinit
  */
 
+/**
+ * viortc_init_ptp_clock() - init and register PTP clock
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ * @clock_type: virtio_rtc clock type
+ * @leap_second_smearing: virtio_rtc leap second smearing
+ *
+ * Context: Process context.
+ * Return: Positive if registered, zero if not supported by configuration,
+ *         negative error code otherwise.
+ */
+static int viortc_init_ptp_clock(struct viortc_dev *viortc, u16 vio_clk_id,
+				 u8 clock_type, u8 leap_second_smearing)
+{
+	struct device *dev = &viortc->vdev->dev;
+	char ptp_clock_name[PTP_CLOCK_NAME_LEN];
+	struct viortc_ptp_clock *vio_ptp;
+
+	snprintf(ptp_clock_name, PTP_CLOCK_NAME_LEN,
+		 "Virtio PTP type %d, variant %d", clock_type,
+		 leap_second_smearing);
+
+	vio_ptp = viortc_ptp_register(viortc, dev, vio_clk_id, ptp_clock_name);
+	if (IS_ERR(vio_ptp)) {
+		dev_err(dev, "failed to register PTP clock '%s'\n",
+			ptp_clock_name);
+		return PTR_ERR(vio_ptp);
+	}
+
+	viortc->clocks_to_unregister[vio_clk_id] = vio_ptp;
+
+	return !!vio_ptp;
+}
+
+/**
+ * viortc_init_clock() - init local representation of virtio_rtc clock
+ * @viortc: device data
+ * @vio_clk_id: virtio_rtc clock id
+ *
+ * Initializes PHC and/or RTC class device to represent virtio_rtc clock.
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_init_clock(struct viortc_dev *viortc, u16 vio_clk_id)
+{
+	u8 clock_type, leap_second_smearing, flags;
+	bool is_exposed = false;
+	int ret;
+
+	ret = viortc_clock_cap(viortc, vio_clk_id, &clock_type,
+			       &leap_second_smearing, &flags);
+	if (ret)
+		return ret;
+
+	if (IS_ENABLED(CONFIG_VIRTIO_RTC_PTP)) {
+		ret = viortc_init_ptp_clock(viortc, vio_clk_id, clock_type,
+					    leap_second_smearing);
+		if (ret < 0)
+			return ret;
+		if (ret > 0)
+			is_exposed = true;
+	}
+
+	if (!is_exposed)
+		dev_warn(
+			&viortc->vdev->dev,
+			"cannot expose clock %d (type %d, variant %d) to userspace\n",
+			vio_clk_id, clock_type, leap_second_smearing);
+
+	return 0;
+}
+
+/**
+ * viortc_clocks_exit() - unregister PHCs
+ * @viortc: device data
+ */
+static void viortc_clocks_exit(struct viortc_dev *viortc)
+{
+	unsigned int i;
+	struct viortc_ptp_clock *vio_ptp;
+
+	for (i = 0; i < viortc->num_clocks; i++) {
+		vio_ptp = viortc->clocks_to_unregister[i];
+
+		if (!vio_ptp)
+			continue;
+
+		viortc->clocks_to_unregister[i] = NULL;
+
+		WARN_ON(viortc_ptp_unregister(vio_ptp, &viortc->vdev->dev));
+	}
+}
+
 /**
  * viortc_clocks_init() - init local representations of virtio_rtc clocks
  * @viortc: device data
@@ -648,6 +747,7 @@ static int viortc_clocks_init(struct viortc_dev *viortc)
 {
 	int ret;
 	u16 num_clocks;
+	unsigned int i;
 
 	ret = viortc_cfg(viortc, &num_clocks);
 	if (ret)
@@ -660,8 +760,22 @@ static int viortc_clocks_init(struct viortc_dev *viortc)
 
 	viortc->num_clocks = num_clocks;
 
-	/* In the future, PTP clocks will be initialized here. */
-	(void)viortc_clock_cap;
+	viortc->clocks_to_unregister =
+		devm_kcalloc(&viortc->vdev->dev, num_clocks,
+			     sizeof(*viortc->clocks_to_unregister), GFP_KERNEL);
+	if (!viortc->clocks_to_unregister)
+		return -ENOMEM;
+
+	for (i = 0; i < num_clocks; i++) {
+		ret = viortc_init_clock(viortc, i);
+		if (ret)
+			goto err_free_clocks;
+	}
+
+	return 0;
+
+err_free_clocks:
+	viortc_clocks_exit(viortc);
 
 	return ret;
 }
@@ -741,7 +855,9 @@ static int viortc_probe(struct virtio_device *vdev)
  */
 static void viortc_remove(struct virtio_device *vdev)
 {
-	/* In the future, PTP clocks will be deinitialized here. */
+	struct viortc_dev *viortc = vdev->priv;
+
+	viortc_clocks_exit(viortc);
 
 	virtio_reset_device(vdev);
 	vdev->config->del_vqs(vdev);
diff --git a/drivers/virtio/virtio_rtc_internal.h b/drivers/virtio/virtio_rtc_internal.h
index 9c249c15b68f..785356e488a8 100644
--- a/drivers/virtio/virtio_rtc_internal.h
+++ b/drivers/virtio/virtio_rtc_internal.h
@@ -10,6 +10,7 @@
 #define _VIRTIO_RTC_INTERNAL_H_
 
 #include <linux/types.h>
+#include <linux/ptp_clock_kernel.h>
 
 /* driver core IFs */
 
@@ -21,4 +22,49 @@ int viortc_read_cross(struct viortc_dev *viortc, u16 vio_clk_id, u8 hw_counter,
 int viortc_cross_cap(struct viortc_dev *viortc, u16 vio_clk_id, u8 hw_counter,
 		     bool *supported);
 
+/* PTP IFs */
+
+struct viortc_ptp_clock;
+
+#if IS_ENABLED(CONFIG_VIRTIO_RTC_PTP)
+
+struct viortc_ptp_clock *viortc_ptp_register(struct viortc_dev *viortc,
+					     struct device *parent_dev,
+					     u16 vio_clk_id,
+					     const char *ptp_clock_name);
+int viortc_ptp_unregister(struct viortc_ptp_clock *vio_ptp,
+			  struct device *parent_dev);
+
+#else
+
+static inline struct viortc_ptp_clock *
+viortc_ptp_register(struct viortc_dev *viortc, struct device *parent_dev,
+		    u16 vio_clk_id, const char *ptp_clock_name)
+{
+	return NULL;
+}
+
+static inline int viortc_ptp_unregister(struct viortc_ptp_clock *vio_ptp,
+					struct device *parent_dev)
+{
+	return -ENODEV;
+}
+
+#endif
+
+/* HW counter IFs */
+
+/**
+ * viortc_hw_xtstamp_params() - get HW-specific xtstamp params
+ * @hw_counter: virtio_rtc HW counter type
+ * @cs_id: clocksource id corresponding to hw_counter
+ *
+ * Gets the HW-specific xtstamp params. Returns an error if the driver cannot
+ * support xtstamp.
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_hw_xtstamp_params(u8 *hw_counter, enum clocksource_ids *cs_id);
+
 #endif /* _VIRTIO_RTC_INTERNAL_H_ */
diff --git a/drivers/virtio/virtio_rtc_ptp.c b/drivers/virtio/virtio_rtc_ptp.c
new file mode 100644
index 000000000000..09f5a9adf2e4
--- /dev/null
+++ b/drivers/virtio/virtio_rtc_ptp.c
@@ -0,0 +1,348 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Expose virtio_rtc clocks as PTP clocks.
+ *
+ * Copyright (C) 2022-2023 OpenSynergy GmbH
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Derived from ptp_kvm_common.c, virtual PTP 1588 clock for use with KVM
+ * guests.
+ *
+ * Copyright (C) 2017 Red Hat Inc.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/ptp_clock_kernel.h>
+
+#include <uapi/linux/virtio_rtc.h>
+
+#include "virtio_rtc_internal.h"
+
+/**
+ * struct viortc_ptp_clock - PTP clock abstraction
+ * @ptp_clock: PTP clock handle for unregistering
+ * @viortc: virtio_rtc device data
+ * @ptp_info: PTP clock description
+ * @vio_clk_id: virtio_rtc clock id
+ * @have_cross: device supports crosststamp with available HW counter
+ */
+struct viortc_ptp_clock {
+	struct ptp_clock *ptp_clock;
+	struct viortc_dev *viortc;
+	struct ptp_clock_info ptp_info;
+	u16 vio_clk_id;
+	bool have_cross;
+};
+
+/**
+ * struct viortc_ptp_cross_ctx - context for get_device_system_crosststamp()
+ * @device_time: device clock reading
+ * @system_counterval: HW counter value at device_time
+ *
+ * Provides the already obtained crosststamp to get_device_system_crosststamp().
+ */
+struct viortc_ptp_cross_ctx {
+	ktime_t device_time;
+	struct system_counterval_t system_counterval;
+};
+
+/* Weak function in case get_device_system_crosststamp() is not supported */
+int __weak viortc_hw_xtstamp_params(u8 *hw_counter, enum clocksource_ids *cs_id)
+{
+	return -EOPNOTSUPP;
+}
+
+/**
+ * viortc_ptp_get_time_fn() - callback for get_device_system_crosststamp()
+ * @device_time: device clock reading
+ * @system_counterval: HW counter value at device_time
+ * @ctx: context with already obtained crosststamp
+ *
+ * Return: zero (success).
+ */
+static int viortc_ptp_get_time_fn(ktime_t *device_time,
+				  struct system_counterval_t *system_counterval,
+				  void *ctx)
+{
+	struct viortc_ptp_cross_ctx *vio_ctx = ctx;
+
+	*device_time = vio_ctx->device_time;
+	*system_counterval = vio_ctx->system_counterval;
+
+	return 0;
+}
+
+/**
+ * viortc_ptp_do_xtstamp() - get crosststamp from device
+ * @vio_ptp: virtio_rtc PTP clock
+ * @hw_counter: virtio_rtc HW counter type
+ * @cs_id: clocksource id corresponding to hw_counter
+ * @ctx: context for get_device_system_crosststamp()
+ *
+ * Reads HW-specific crosststamp from device.
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_ptp_do_xtstamp(struct viortc_ptp_clock *vio_ptp,
+				 u8 hw_counter, enum clocksource_ids cs_id,
+				 struct viortc_ptp_cross_ctx *ctx)
+{
+	u64 ns;
+	u64 max_ns;
+	int ret;
+
+	ctx->system_counterval.cs_id = cs_id;
+
+	ret = viortc_read_cross(vio_ptp->viortc, vio_ptp->vio_clk_id,
+				hw_counter, &ns,
+				&ctx->system_counterval.cycles);
+	if (ret)
+		return ret;
+
+	max_ns = (u64)ktime_to_ns(KTIME_MAX);
+	if (ns > max_ns)
+		return -EINVAL;
+
+	ctx->device_time = ns_to_ktime(ns);
+
+	return 0;
+}
+
+/*
+ * PTP clock operations
+ */
+
+/**
+ * viortc_ptp_getcrosststamp() - PTP clock getcrosststamp op
+ * @ptp: PTP clock info
+ * @xtstamp: crosststamp
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_ptp_getcrosststamp(struct ptp_clock_info *ptp,
+				     struct system_device_crosststamp *xtstamp)
+{
+	struct viortc_ptp_clock *vio_ptp =
+		container_of(ptp, struct viortc_ptp_clock, ptp_info);
+	struct system_time_snapshot history_begin;
+	struct viortc_ptp_cross_ctx ctx;
+	enum clocksource_ids cs_id;
+	u8 hw_counter;
+	int ret;
+
+	if (!vio_ptp->have_cross)
+		return -EOPNOTSUPP;
+
+	ret = viortc_hw_xtstamp_params(&hw_counter, &cs_id);
+	if (ret)
+		return ret;
+
+	ktime_get_snapshot(&history_begin);
+	if (history_begin.cs_id != cs_id)
+		return -EOPNOTSUPP;
+
+	/*
+	 * Getting the timestamp can take many milliseconds with a slow Virtio
+	 * device. This is too long for viortc_ptp_get_time_fn() passed to
+	 * get_device_system_crosststamp(), which has to usually return before
+	 * the timekeeper seqcount increases (every tick or so).
+	 *
+	 * So, get the actual cross-timestamp first.
+	 */
+	ret = viortc_ptp_do_xtstamp(vio_ptp, hw_counter, cs_id, &ctx);
+	if (ret)
+		return ret;
+
+	ret = get_device_system_crosststamp(viortc_ptp_get_time_fn, &ctx,
+					    &history_begin, xtstamp);
+	if (ret)
+		pr_debug("%s: get_device_system_crosststamp() returned %d\n",
+			 __func__, ret);
+
+	return ret;
+}
+
+/** viortc_ptp_adjfine() - unsupported PTP clock adjfine op */
+static int viortc_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+{
+	return -EOPNOTSUPP;
+}
+
+/** viortc_ptp_adjtime() - unsupported PTP clock adjtime op */
+static int viortc_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	return -EOPNOTSUPP;
+}
+
+/** viortc_ptp_settime64() - unsupported PTP clock settime64 op */
+static int viortc_ptp_settime64(struct ptp_clock_info *ptp,
+				const struct timespec64 *ts)
+{
+	return -EOPNOTSUPP;
+}
+
+/**
+ * viortc_ptp_gettimex64() - PTP clock gettimex64 op
+ *
+ * Context: Process context.
+ */
+static int viortc_ptp_gettimex64(struct ptp_clock_info *ptp,
+				 struct timespec64 *ts,
+				 struct ptp_system_timestamp *sts)
+{
+	struct viortc_ptp_clock *vio_ptp =
+		container_of(ptp, struct viortc_ptp_clock, ptp_info);
+	u64 ns;
+	int ret;
+
+	ptp_read_system_prets(sts);
+	ret = viortc_read(vio_ptp->viortc, vio_ptp->vio_clk_id, &ns);
+	ptp_read_system_postts(sts);
+
+	if (ret)
+		return ret;
+
+	if (ns > (u64)S64_MAX)
+		return -EINVAL;
+
+	*ts = ns_to_timespec64((s64)ns);
+
+	return 0;
+}
+
+/** viortc_ptp_enable() - unsupported PTP clock enable op */
+static int viortc_ptp_enable(struct ptp_clock_info *ptp,
+			     struct ptp_clock_request *rq, int on)
+{
+	return -EOPNOTSUPP;
+}
+
+/**
+ * viortc_ptp_info_template - ptp_clock_info template
+ *
+ * The .name member will be set for individual virtio_rtc PTP clocks.
+ *
+ * The .getcrosststamp member will be cleared for PTP clocks not supporting
+ * crosststamp.
+ */
+static const struct ptp_clock_info viortc_ptp_info_template = {
+	.owner = THIS_MODULE,
+	/* .name is set according to clock type */
+	.adjfine = viortc_ptp_adjfine,
+	.adjtime = viortc_ptp_adjtime,
+	.gettimex64 = viortc_ptp_gettimex64,
+	.settime64 = viortc_ptp_settime64,
+	.enable = viortc_ptp_enable,
+	.getcrosststamp = viortc_ptp_getcrosststamp,
+};
+
+/**
+ * viortc_ptp_unregister() - PTP clock unregistering wrapper
+ * @vio_ptp: virtio_rtc PTP clock
+ * @parent_dev: parent device of PTP clock
+ *
+ * Return: Zero on success, negative error code otherwise.
+ */
+int viortc_ptp_unregister(struct viortc_ptp_clock *vio_ptp,
+			  struct device *parent_dev)
+{
+	int ret = ptp_clock_unregister(vio_ptp->ptp_clock);
+
+	if (!ret)
+		devm_kfree(parent_dev, vio_ptp);
+
+	return ret;
+}
+
+/**
+ * viortc_ptp_get_cross_cap() - get xtstamp support info from device
+ * @viortc: virtio_rtc device data
+ * @vio_ptp: virtio_rtc PTP clock abstraction
+ *
+ * Context: Process context.
+ * Return: Zero on success, negative error code otherwise.
+ */
+static int viortc_ptp_get_cross_cap(struct viortc_dev *viortc,
+				    struct viortc_ptp_clock *vio_ptp)
+{
+	int ret;
+	enum clocksource_ids cs_id;
+	u8 hw_counter;
+	bool xtstamp_supported;
+
+	ret = viortc_hw_xtstamp_params(&hw_counter, &cs_id);
+	if (ret) {
+		vio_ptp->have_cross = false;
+		return 0;
+	}
+
+	ret = viortc_cross_cap(viortc, vio_ptp->vio_clk_id, hw_counter,
+			       &xtstamp_supported);
+	if (ret)
+		return ret;
+
+	vio_ptp->have_cross = xtstamp_supported;
+
+	return 0;
+}
+
+/**
+ * viortc_ptp_register() - prepare and register PTP clock
+ * @viortc: virtio_rtc device data
+ * @parent_dev: parent device for PTP clock
+ * @vio_clk_id: id of virtio_rtc clock which backs PTP clock
+ * @ptp_clock_name: PTP clock name
+ *
+ * Context: Process context.
+ * Return: Pointer on success, ERR_PTR() otherwise; NULL if PTP clock support
+ *         not available.
+ */
+struct viortc_ptp_clock *viortc_ptp_register(struct viortc_dev *viortc,
+					     struct device *parent_dev,
+					     u16 vio_clk_id,
+					     const char *ptp_clock_name)
+{
+	struct viortc_ptp_clock *vio_ptp;
+	struct ptp_clock *ptp_clock;
+	ssize_t len;
+	int ret;
+
+	vio_ptp = devm_kzalloc(parent_dev, sizeof(*vio_ptp), GFP_KERNEL);
+	if (!vio_ptp)
+		return ERR_PTR(-ENOMEM);
+
+	vio_ptp->viortc = viortc;
+	vio_ptp->vio_clk_id = vio_clk_id;
+	vio_ptp->ptp_info = viortc_ptp_info_template;
+	len = strscpy(vio_ptp->ptp_info.name, ptp_clock_name,
+		      sizeof(vio_ptp->ptp_info.name));
+	if (len < 0) {
+		ret = len;
+		goto err_free_dev;
+	}
+
+	ret = viortc_ptp_get_cross_cap(viortc, vio_ptp);
+	if (ret)
+		goto err_free_dev;
+
+	if (!vio_ptp->have_cross)
+		vio_ptp->ptp_info.getcrosststamp = NULL;
+
+	ptp_clock = ptp_clock_register(&vio_ptp->ptp_info, parent_dev);
+	if (IS_ERR(ptp_clock))
+		goto err_on_register;
+
+	vio_ptp->ptp_clock = ptp_clock;
+
+	return vio_ptp;
+
+err_on_register:
+	ret = PTR_ERR(ptp_clock);
+
+err_free_dev:
+	devm_kfree(parent_dev, vio_ptp);
+	return ERR_PTR(ret);
+}
-- 
2.43.0



From a.fatoum at pengutronix.de  Thu Dec 19 12:14:10 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 19 Dec 2024 21:14:10 +0100
Subject: [PATCH 1/6] dt-bindings: clock: imx8m: document nominal/overdrive
 properties
In-Reply-To: <20241219-lash-lather-31443ced0e0c@spud>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
 <20241219-imx8m-clk-v1-1-cfaffa087da6@pengutronix.de>
 <20241219-lash-lather-31443ced0e0c@spud>
Message-ID: <4e2250b3-5170-4e88-aa0a-dd796b81e78b@pengutronix.de>

Hello Conor,

On 19.12.24 20:49, Conor Dooley wrote:
> On Thu, Dec 19, 2024 at 08:27:32AM +0100, Ahmad Fatoum wrote:
>> The imx8m-clock.yaml binding covers the clock controller inside all
>> of the i.MX8M Q/M/N/P SoCs. All of them have in common that they
>> support two operating modes: nominal and overdrive mode.
> 
> This implies that only the two modes you mention are possible, but you
> leave the option open to a dts author to use either. How come?
> 
> Makes it seem like we only need one of these, for whatever the
> non-default option is?

There is no real default. The mode is configured implicitly by the
bootloader setting VDD_SOC and then kernel needs to adhere to the
limits that imposes.

For i.MX8M Mini and Nano, the kernel SoC DTSIs has assigned-clock-rates
that are all achievable in nominal mode. For i.MX8MP, there are some
rates only validated for overdrive mode.

But even for the i.MX8M Mini/Nano boards, we don't know what rates they
may configure at runtime, so it's not possible to infer from just the
device tree what the mode is, which is why I need to allow for absence
of either property. I can make it a single property with two possible
values though if that's preferable.

Theoretically, we could infer mode at runtime from VDD_SOC voltage,
but we need to set up clocks to read out the PMIC and I want to
apply the constraints as early as possible as I don't want the SoC
to run outside of spec even for a short while.

Thanks,
Ahmad

> 
>>
>> While the overdrive mode allows for higher frequencies for many IPs,
>> the nominal mode needs a lower SoC voltage, thereby reducing
>> heat generation and power usage.
>>
>> In any case, software should respect the maximum clock rate limits
>> described in the datasheet for each of the two operating modes.
>>
>> To allow device tree consumers to enforce these limits, document two new
>> optional properties that can be used to sanity check the clock tree.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
>> ---
>>  Documentation/devicetree/bindings/clock/imx8m-clock.yaml | 14 ++++++++++++++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
>> index c643d4a81478..a6ae5257ef53 100644
>> --- a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
>> +++ b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
>> @@ -43,6 +43,14 @@ properties:
>>        ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8m-clock.h
>>        for the full list of i.MX8M clock IDs.
>>  
>> +  fsl,nominal-mode:
>> +    description: Set if SoC is operated in nominal mode
>> +    $ref: /schemas/types.yaml#/definitions/flag
>> +
>> +  fsl,overdrive-mode:
>> +    description: Set if SoC is operated in overdrive mode
>> +    $ref: /schemas/types.yaml#/definitions/flag
>> +
>>  required:
>>    - compatible
>>    - reg
>> @@ -95,6 +103,12 @@ allOf:
>>              - const: clk_ext2
>>              - const: clk_ext3
>>              - const: clk_ext4
>> +  - if:
>> +      required:
>> +        - fsl,overdrive-mode
>> +    then:
>> +      properties:
>> +        fsl,nominal-mode: false
>>  
>>  additionalProperties: false
>>  
>>
>> -- 
>> 2.39.5
>>


-- 
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 msp at baylibre.com  Thu Dec 19 11:57:52 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 20:57:52 +0100
Subject: [PATCH v6 1/7] dt-bindings: can: m_can: Add wakeup properties
In-Reply-To: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
References: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
Message-ID: <20241219-topic-mcan-wakeup-source-v6-12-v6-1-1356c7f7cfda@baylibre.com>

m_can can be a wakeup source on some devices. Especially on some of the
am62* SoCs pins, connected to m_can in the mcu, can be used to wakeup
the SoC.

The wakeup-source property defines on which devices m_can can be used
for wakeup and in which power states.

The pins associated with m_can have to have a special configuration to
be able to wakeup the SoC. This configuration is described in the wakeup
pinctrl state while the default state describes the default
configuration.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 .../devicetree/bindings/net/can/bosch,m_can.yaml   | 27 ++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
index c4887522e8fe97c3947357b4dbd4ecf20ee8100a..75963b11d31964c47679370664824ea111e70ca7 100644
--- a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
+++ b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
@@ -106,6 +106,22 @@ properties:
         maximum: 32
     minItems: 1
 
+  pinctrl-0:
+    description: Default pinctrl state
+
+  pinctrl-1:
+    description: Wakeup pinctrl state
+
+  pinctrl-names:
+    description:
+      When present should contain at least "default" describing the default pin
+      states. The second state called "wakeup" describes the pins in their
+      wakeup configuration required to exit sleep states.
+    minItems: 1
+    items:
+      - const: default
+      - const: wakeup
+
   power-domains:
     description:
       Power domain provider node and an args specifier containing
@@ -122,6 +138,17 @@ properties:
     minItems: 1
     maxItems: 2
 
+  wakeup-source:
+    oneOf:
+      - description: This device is capable of wakeup.
+        type: boolean
+      - description: This device is capable of wakeup from the defined power
+          states.
+        $ref: /schemas/types.yaml#/definitions/string-array
+        enum:
+          - suspend
+          - poweroff
+
 required:
   - compatible
   - reg

-- 
2.45.2



From msp at baylibre.com  Thu Dec 19 11:57:51 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 20:57:51 +0100
Subject: [PATCH v6 0/7] can: m_can: Add am62 wakeup support
Message-ID: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>

Hi,

Series
------
am62, am62a and am62p support Partial-IO, a poweroff SoC state with a
few pin groups being active for wakeup.

To support mcu_mcan0 and mcu_mcan1 wakeup for the mentioned SoCs, the
series introduces a notion of wake-on-lan for m_can. If the user decides
to enable wake-on-lan for a m_can device, the device is set to wakeup
enabled. A 'wakeup' pinctrl state is selected to enable wakeup flags for
the relevant pins. If wake-on-lan is disabled the default pinctrl is
selected.

After feedback from Nishanth and Krzysztof, I moved to a wakeup-source
property that can be a list of powerstates in which the device is wakeup
capable. This describes special cases like Partial-IO where the device
is powered off but pins can be sensible to changes and trigger a wakeup.

It is based on v6.13-rc1.

Partial-IO
----------
This series is part of a bigger topic to support Partial-IO on am62,
am62a and am62p. Partial-IO is a poweroff state in which some pins are
able to wakeup the SoC. In detail MCU m_can and two serial port pins can
trigger the wakeup.
A documentation can also be found in section 6.2.4 in the TRM:
  https://www.ti.com/lit/pdf/spruiv7

This other series is relevant for the support of Partial-IO:

 - firmware: ti_sci: Partial-IO support
   https://gitlab.baylibre.com/msp8/linux/-/tree/topic/am62-partialio/v6.13?ref_type=heads

Testing
-------
A test branch is available here that includes all patches required to
test Partial-IO:

https://gitlab.baylibre.com/msp8/linux/-/tree/integration/am62-partialio/v6.13?ref_type=heads

After enabling Wake-on-LAN the system can be powered off and will enter
the Partial-IO state in which it can be woken up by activity on the
specific pins:
    ethtool -s can0 wol p
    ethtool -s can1 wol p
    poweroff

I tested these patches on am62-lp-sk.

Best,
Markus

Previous versions:
 v1: https://lore.kernel.org/lkml/20240523075347.1282395-1-msp at baylibre.com/
 v2: https://lore.kernel.org/lkml/20240729074135.3850634-1-msp at baylibre.com/
 v3: https://lore.kernel.org/lkml/20241011-topic-mcan-wakeup-source-v6-12-v3-0-9752c714ad12 at baylibre.com
 v4: https://lore.kernel.org/r/20241015-topic-mcan-wakeup-source-v6-12-v4-0-fdac1d1e7aa6 at baylibre.com
 v5: https://lore.kernel.org/r/20241028-topic-mcan-wakeup-source-v6-12-v5-0-33edc0aba629 at baylibre.com

Changes in v6:
 - Rebased to v6.13-rc1
 - After feedback of the other Partial-IO series, I updated this series
   and removed all use of regulator-related patches.
 - wakeup-source is now not only a boolean property but can also be a
   list of power states in which the device is wakeup capable.

Changes in v5:
 - Make the check of wol options nicer to read

Changes in v4:
 - Remove leftover testing code that always returned -EIO in a specific
 - Redesign pincontrol setup to be easier understandable and less nested
 - Fix missing parantheses around wol_enable expression
 - Remove | from binding description

Changes in v3:
 - Rebase to v6.12-rc1
 - Change 'wakeup-source' to only 'true'
 - Simplify m_can_set_wol by returning early on error
 - Add vio-suuply binding and handling of this optional property.
   vio-supply is used to reflect the SoC architecture and which power
   line powers the m_can unit. This is important as some units are
   powered in special low power modes.

Changes in v2:
 - Rebase to v6.11-rc1
 - Squash these two patches for the binding into one:
   dt-bindings: can: m_can: Add wakeup-source property
   dt-bindings: can: m_can: Add wakeup pinctrl state
 - Add error handling to multiple patches of the m_can driver
 - Add error handling in m_can_class_allocate_dev(). This also required
   to add a new patch to return error pointers from
   m_can_class_allocate_dev().

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
Markus Schneider-Pargmann (6):
      dt-bindings: can: m_can: Add wakeup properties
      can: m_can: Map WoL to device_set_wakeup_enable
      can: m_can: Return ERR_PTR on error in allocation
      can: m_can: Support pinctrl wakeup state
      arm64: dts: ti: k3-am62: Mark mcu_mcan0/1 as wakeup-source
      arm64: dts: ti: k3-am62a-mcu: Mark mcu_mcan0/1 as wakeup-source

Vibhore Vardhan (1):
      arm64: dts: ti: k3-am62p-mcu: Mark mcu_mcan0/1 as wakeup-source

 .../devicetree/bindings/net/can/bosch,m_can.yaml   |  27 +++++
 arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi            |   2 +
 arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi           |   2 +
 .../boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi     |   2 +
 drivers/net/can/m_can/m_can.c                      | 111 ++++++++++++++++++++-
 drivers/net/can/m_can/m_can.h                      |   4 +
 drivers/net/can/m_can/m_can_pci.c                  |   4 +-
 drivers/net/can/m_can/m_can_platform.c             |   4 +-
 drivers/net/can/m_can/tcan4x5x-core.c              |   4 +-
 9 files changed, 151 insertions(+), 9 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241009-topic-mcan-wakeup-source-v6-12-8c1d69931bd8

Best regards,
-- 
Markus Schneider-Pargmann <msp at baylibre.com>



From msp at baylibre.com  Thu Dec 19 11:57:53 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Thu, 19 Dec 2024 20:57:53 +0100
Subject: [PATCH v6 2/7] can: m_can: Map WoL to device_set_wakeup_enable
In-Reply-To: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
References: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
Message-ID: <20241219-topic-mcan-wakeup-source-v6-12-v6-2-1356c7f7cfda@baylibre.com>

In some devices the pins of the m_can module can act as a wakeup source.
This patch helps do that by connecting the PHY_WAKE WoL option to
device_set_wakeup_enable. By marking this device as being wakeup
enabled, this setting can be used by platform code to decide which
sleep or poweroff mode to use.

Also this prepares the driver for the next patch in which the pinctrl
settings are changed depending on the desired wakeup source.

Reviewed-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/net/can/m_can/m_can.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 16e9e7d7527d9762d73a7ec47940c73c0976e05d..0dcdcde3449c7647e4bc9a92f918160a336f94c0 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -2186,6 +2186,36 @@ static int m_can_set_coalesce(struct net_device *dev,
 	return 0;
 }
 
+static void m_can_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct m_can_classdev *cdev = netdev_priv(dev);
+
+	wol->supported = device_can_wakeup(cdev->dev) ? WAKE_PHY : 0;
+	wol->wolopts = device_may_wakeup(cdev->dev) ? WAKE_PHY : 0;
+}
+
+static int m_can_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct m_can_classdev *cdev = netdev_priv(dev);
+	bool wol_enable = !!(wol->wolopts & WAKE_PHY);
+	int ret;
+
+	if (wol->wolopts & ~WAKE_PHY)
+		return -EINVAL;
+
+	if (wol_enable == device_may_wakeup(cdev->dev))
+		return 0;
+
+	ret = device_set_wakeup_enable(cdev->dev, wol_enable);
+	if (ret) {
+		netdev_err(cdev->net, "Failed to set wakeup enable %pE\n",
+			   ERR_PTR(ret));
+		return ret;
+	}
+
+	return 0;
+}
+
 static const struct ethtool_ops m_can_ethtool_ops_coalescing = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS_IRQ |
 		ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ |
@@ -2195,10 +2225,14 @@ static const struct ethtool_ops m_can_ethtool_ops_coalescing = {
 	.get_ts_info = ethtool_op_get_ts_info,
 	.get_coalesce = m_can_get_coalesce,
 	.set_coalesce = m_can_set_coalesce,
+	.get_wol = m_can_get_wol,
+	.set_wol = m_can_set_wol,
 };
 
 static const struct ethtool_ops m_can_ethtool_ops = {
 	.get_ts_info = ethtool_op_get_ts_info,
+	.get_wol = m_can_get_wol,
+	.set_wol = m_can_set_wol,
 };
 
 static int register_m_can_dev(struct m_can_classdev *cdev)
@@ -2325,6 +2359,9 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
 		goto out;
 	}
 
+	if (dev->of_node && of_property_read_bool(dev->of_node, "wakeup-source"))
+		device_set_wakeup_capable(dev, true);
+
 	/* Get TX FIFO size
 	 * Defines the total amount of echo buffers for loopback
 	 */

-- 
2.45.2



From Frank.li at nxp.com  Thu Dec 19 12:17:15 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 15:17:15 -0500
Subject: [PATCH v13 4/9] irqchip/gic-v3-its: Add
 DOMAIN_BUS_DEVICE_PCI_EP_MSI support
In-Reply-To: <Z2R9qPmAyTcc5mtg@ryzen>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
 <20241218-ep-msi-v13-4-646e2192dc24@nxp.com>
 <868qscq70x.wl-maz@kernel.org>
 <Z2RRimPlT41Ru281@lizhi-Precision-Tower-5810>
 <Z2R9qPmAyTcc5mtg@ryzen>
Message-ID: <Z2R/S4y3fF2Dw4Ye@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 09:10:16PM +0100, Niklas Cassel wrote:
> On Thu, Dec 19, 2024 at 12:02:02PM -0500, Frank Li wrote:
> > On Thu, Dec 19, 2024 at 10:52:30AM +0000, Marc Zyngier wrote:
> > > On Wed, 18 Dec 2024 23:08:39 +0000,
>
> [...]
>
> > If use latest ITS MSI64 should be simple, only need descript it at DTS
> > (I have not hardware to test this case yet).
> > pci-ep {
> > 	...
> > 	msi-map = <0 &its, 0x<8_0000, 0xff>;
> > 			      ^, ctrl ID.
> > 	msi-mask = <0xff>;
> > 	...
> > }
>
> [...]
>
> > This solution already test by Tested-by: Niklas Cassel <cassel at kernel.org>
> > who use another dwc controller, which they already implemented
> > "implementation-specific" by only update dts to provide hardware
> > information.(I guest he use ITS's MSI64)
> >
> > Because it is new patches, I have not added Niklas's test-by tag. There
> > are not big functional change since Nikas test. The major change is make
> > msi part better align current MSI framework according to Thomas's
> > suggestion.
>
> Frank, I tested this series (a few revisions back) on the rockchip rk3588,
> which just like imx95, uses a DWC based PCIe EP controller, and ARM GIC ITS,
> but unlike imx95, it does not require any additional look up table registers
> to be configured.
>
>
> While the rk3588 PCIe host controller node has:
> msi-map = <0x0000 &its1 0x0000 0x1000>;
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi?h=v6.13-rc3#n164
>
> The rk3588 PCIe endpoint controller node, which is the only one relevant
> in this case, only has:
> msi-parent = <&its1 0x0000>;
> no msi-map.
> https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/commit/?h=v6.14-armsoc/dts64&id=b6f09f497b07008aa65c31341138cecafa78222c

Thank you very much. I update msi part, so endpoint controller node align
host controller node.

It should be
msi-map = <0x0000 &its1 0x0000 0x1000>;

So if your hardware support multi physical function, your can create more
than one pci_test func. Previous version only support one EP func.

Frank

>
>
> Kind regards,
> Niklas


From cassel at kernel.org  Thu Dec 19 12:43:15 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Thu, 19 Dec 2024 21:43:15 +0100
Subject: [PATCH v13 4/9] irqchip/gic-v3-its: Add
 DOMAIN_BUS_DEVICE_PCI_EP_MSI support
In-Reply-To: <Z2R/S4y3fF2Dw4Ye@lizhi-Precision-Tower-5810>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
 <20241218-ep-msi-v13-4-646e2192dc24@nxp.com>
 <868qscq70x.wl-maz@kernel.org>
 <Z2RRimPlT41Ru281@lizhi-Precision-Tower-5810>
 <Z2R9qPmAyTcc5mtg@ryzen>
 <Z2R/S4y3fF2Dw4Ye@lizhi-Precision-Tower-5810>
Message-ID: <Z2SFYwC7KC-qiZD2@ryzen>

On Thu, Dec 19, 2024 at 03:17:15PM -0500, Frank Li wrote:
> 
> Thank you very much. I update msi part, so endpoint controller node align
> host controller node.
> 
> It should be
> msi-map = <0x0000 &its1 0x0000 0x1000>;
> 
> So if your hardware support multi physical function, your can create more
> than one pci_test func. Previous version only support one EP func.

I see. That seems like an improvement.
I will need to ask Rockchip maintainer to drop my msi-parent patch for PCIe
EP node then. (Which is currently queued up in for-6.14)

However, for the PCIe host node, rk3588 has:
iommu-map = <0x0000 &mmu600_pcie 0x0000 0x1000>;

For the PCIe endpoint node, rk3588 has:
iommus = <&mmu600_pcie 0x0000>;

https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/commit/?h=v6.14-armsoc/dts64&id=da92d3dfc871e821a1bface3ba5afcf8cda19805

Is it fine that for the PCIe EP node, we specify iommu mapping using:
iommus = <&mmu600_pcie 0x0000>;
but the ITS/MSI map will be:
msi-map = <0x0000 &its1 0x0000 0x1000>;

isn't this a bit inconsistent?

The physical function is the "F" in the BDF.
Does this mean that:
iommus = <&mmu600_pcie 0x0000>;
the IOMMU will not be able to distinguish different PCI physical functions
from the same PCI device? So two different physical functions on the same
PCI device share the same IOMMU mappings?


Kind regards,
Niklas


From dianders at chromium.org  Thu Dec 19 12:53:20 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Thu, 19 Dec 2024 12:53:20 -0800
Subject: [PATCH v3 0/3] arm64: errata: Rework Spectre BHB mitigations to not assume "safe"
Message-ID: <20241219205426.2275508-1-dianders@chromium.org>


Recently I realized that a device with some Qualcomm Kryo 4xx cores
reported in `lscpu` that it was _not_ vulnerable to Spectre BHB. This
seemed unlikely to me.

I wrote up a patch series to attempt (with a lot of guesswork) to add
Qualcomm cores to the tables governing how the Spectre BHB mitigation
worked.

In response to that patch, Will suggested that I flip the mitigation
on its head and assume things are vulnerable until we find that
they're not [1]. This patch series _attempts_ to accomplish that.

In case it's not obvious, v2 of this patch series was pretty different
than v1 because it flips the logic on its head. Some of the patches
carried over, though.

v3 is yet more different, avoiding the guesses (and thus dropping
some patches) and also incorporating feedback from Julius in response
to v2.

As a last caveat, I'll note that I am certainly no expert on
Spectre. Mostly I ended up here running `lscpu` on a device and
noticing that it thought that it wasn't affected by Spectre v2 when I
thought it was.

Link to prev versions:
v1: https://lore.kernel.org/r/20241209174430.2904353-1-dianders at chromium.org/
v2: https://lore.kernel.org/r/20241214005248.198803-1-dianders at chromium.org

[1] https://lore.kernel.org/r/20241211213410.GB17486 at willie-the-truck

Changes in v3:
- Don't guess the mitigation; just report unknown cores as vulnerable.
- Restructure the code since is_spectre_bhb_affected() defaults to true
- arm64: cputype: Add MIDR_CORTEX_A76AE
- arm64: errata: Add newer ARM cores to the spectre_bhb_loop_affected() lists

Changes in v2:
- arm64: errata: Assume that unknown CPUs _are_ vulnerable to Spectre BHB

Douglas Anderson (3):
  arm64: errata: Assume that unknown CPUs _are_ vulnerable to Spectre
    BHB
  arm64: cputype: Add MIDR_CORTEX_A76AE
  arm64: errata: Add newer ARM cores to the spectre_bhb_loop_affected()
    lists

 arch/arm64/include/asm/cputype.h |   2 +
 arch/arm64/include/asm/spectre.h |   1 -
 arch/arm64/kernel/proton-pack.c  | 157 ++++++++++++++++++-------------
 3 files changed, 92 insertions(+), 68 deletions(-)

-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Thu Dec 19 12:53:21 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Thu, 19 Dec 2024 12:53:21 -0800
Subject: [PATCH v3 1/3] arm64: errata: Assume that unknown CPUs _are_ vulnerable to Spectre BHB
In-Reply-To: <20241219205426.2275508-1-dianders@chromium.org>
References: <20241219205426.2275508-1-dianders@chromium.org>
Message-ID: <20241219125317.v3.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>

The code for detecting CPUs that are vulnerable to Spectre BHB was
based on a hardcoded list of CPU IDs that were known to be affected.
Unfortunately, the list mostly only contained the IDs of standard ARM
cores. The IDs for many cores that are minor variants of the standard
ARM cores (like many Qualcomm Kyro CPUs) weren't listed. This led the
code to assume that those variants were not affected.

Flip the code on its head and instead assume that a core is vulnerable
if it doesn't have CSV2_3 but is unrecognized as being safe. This
involves creating a "Spectre BHB safe" list.

As of right now, the only CPU IDs added to the "Spectre BHB safe" list
are ARM Cortex A35, A53, A55, A510, and A520. This list was created by
looking for cores that weren't listed in ARM's list [1] as per review
feedback on v2 of this patch [2].

NOTE: this patch will not actually _mitigate_ anyone, it will simply
cause them to report themselves as vulnerable. If any cores in the
system are reported as vulnerable but not mitigated then the whole
system will be reported as vulnerable though the system will attempt
to mitigate with the information it has about the known cores.

[1] https://developer.arm.com/Arm%20Security%20Center/Spectre-BHB
[2] https://lore.kernel.org/r/20241219175128.GA25477 at willie-the-truck


Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels")
Cc: stable at vger.kernel.org
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

Changes in v3:
- Don't guess the mitigation; just report unknown cores as vulnerable.
- Restructure the code since is_spectre_bhb_affected() defaults to true

Changes in v2:
- New

 arch/arm64/include/asm/spectre.h |   1 -
 arch/arm64/kernel/proton-pack.c  | 144 +++++++++++++++++--------------
 2 files changed, 77 insertions(+), 68 deletions(-)

diff --git a/arch/arm64/include/asm/spectre.h b/arch/arm64/include/asm/spectre.h
index 0c4d9045c31f..f1524cdeacf1 100644
--- a/arch/arm64/include/asm/spectre.h
+++ b/arch/arm64/include/asm/spectre.h
@@ -97,7 +97,6 @@ enum mitigation_state arm64_get_meltdown_state(void);
 
 enum mitigation_state arm64_get_spectre_bhb_state(void);
 bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
-u8 spectre_bhb_loop_affected(int scope);
 void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
 bool try_emulate_el1_ssbs(struct pt_regs *regs, u32 instr);
 
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index da53722f95d4..06e04c9e6480 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -845,52 +845,68 @@ static unsigned long system_bhb_mitigations;
  * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
  * SCOPE_SYSTEM call will give the right answer.
  */
-u8 spectre_bhb_loop_affected(int scope)
+static bool is_spectre_bhb_safe(int scope)
+{
+	static const struct midr_range spectre_bhb_safe_list[] = {
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A35),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A53),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A510),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A520),
+		{},
+	};
+	static bool all_safe = true;
+
+	if (scope != SCOPE_LOCAL_CPU)
+		return all_safe;
+
+	if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_safe_list))
+		return true;
+
+	all_safe = false;
+
+	return false;
+}
+
+static u8 spectre_bhb_loop_affected(void)
 {
 	u8 k = 0;
-	static u8 max_bhb_k;
-
-	if (scope == SCOPE_LOCAL_CPU) {
-		static const struct midr_range spectre_bhb_k32_list[] = {
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
-			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
-			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
-			{},
-		};
-		static const struct midr_range spectre_bhb_k24_list[] = {
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
-			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
-			{},
-		};
-		static const struct midr_range spectre_bhb_k11_list[] = {
-			MIDR_ALL_VERSIONS(MIDR_AMPERE1),
-			{},
-		};
-		static const struct midr_range spectre_bhb_k8_list[] = {
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
-			MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
-			{},
-		};
-
-		if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
-			k = 32;
-		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
-			k = 24;
-		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
-			k = 11;
-		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
-			k =  8;
-
-		max_bhb_k = max(max_bhb_k, k);
-	} else {
-		k = max_bhb_k;
-	}
+
+	static const struct midr_range spectre_bhb_k32_list[] = {
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
+		MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+		MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
+		{},
+	};
+	static const struct midr_range spectre_bhb_k24_list[] = {
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
+		MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+		{},
+	};
+	static const struct midr_range spectre_bhb_k11_list[] = {
+		MIDR_ALL_VERSIONS(MIDR_AMPERE1),
+		{},
+	};
+	static const struct midr_range spectre_bhb_k8_list[] = {
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
+		{},
+	};
+
+	if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
+		k = 32;
+	else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
+		k = 24;
+	else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
+		k = 11;
+	else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
+		k =  8;
 
 	return k;
 }
@@ -916,9 +932,8 @@ static enum mitigation_state spectre_bhb_get_cpu_fw_mitigation_state(void)
 	}
 }
 
-static bool is_spectre_bhb_fw_affected(int scope)
+static bool is_spectre_bhb_fw_affected(void)
 {
-	static bool system_affected;
 	enum mitigation_state fw_state;
 	bool has_smccc = arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_NONE;
 	static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
@@ -929,16 +944,8 @@ static bool is_spectre_bhb_fw_affected(int scope)
 	bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
 					 spectre_bhb_firmware_mitigated_list);
 
-	if (scope != SCOPE_LOCAL_CPU)
-		return system_affected;
-
 	fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
-	if (cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) {
-		system_affected = true;
-		return true;
-	}
-
-	return false;
+	return cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED);
 }
 
 static bool supports_ecbhb(int scope)
@@ -954,6 +961,8 @@ static bool supports_ecbhb(int scope)
 						    ID_AA64MMFR1_EL1_ECBHB_SHIFT);
 }
 
+static u8 max_bhb_k;
+
 bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
 			     int scope)
 {
@@ -962,16 +971,18 @@ bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
 	if (supports_csv2p3(scope))
 		return false;
 
-	if (supports_clearbhb(scope))
-		return true;
-
-	if (spectre_bhb_loop_affected(scope))
-		return true;
+	if (is_spectre_bhb_safe(scope))
+		return false;
 
-	if (is_spectre_bhb_fw_affected(scope))
-		return true;
+	/*
+	 * At this point the core isn't known to be "safe" so we're going to
+	 * assume it's vulnerable. We still need to update `max_bhb_k` though,
+	 * but only if we aren't mitigating with clearbhb though.
+	 */
+	if (scope == SCOPE_LOCAL_CPU && !supports_clearbhb(SCOPE_LOCAL_CPU))
+		max_bhb_k = max(max_bhb_k, spectre_bhb_loop_affected());
 
-	return false;
+	return true;
 }
 
 static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
@@ -1028,7 +1039,7 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
 		this_cpu_set_vectors(EL1_VECTOR_BHB_CLEAR_INSN);
 		state = SPECTRE_MITIGATED;
 		set_bit(BHB_INSN, &system_bhb_mitigations);
-	} else if (spectre_bhb_loop_affected(SCOPE_LOCAL_CPU)) {
+	} else if (spectre_bhb_loop_affected()) {
 		/*
 		 * Ensure KVM uses the indirect vector which will have the
 		 * branchy-loop added. A57/A72-r0 will already have selected
@@ -1041,7 +1052,7 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
 		this_cpu_set_vectors(EL1_VECTOR_BHB_LOOP);
 		state = SPECTRE_MITIGATED;
 		set_bit(BHB_LOOP, &system_bhb_mitigations);
-	} else if (is_spectre_bhb_fw_affected(SCOPE_LOCAL_CPU)) {
+	} else if (is_spectre_bhb_fw_affected()) {
 		fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
 		if (fw_state == SPECTRE_MITIGATED) {
 			/*
@@ -1100,7 +1111,6 @@ void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt,
 {
 	u8 rd;
 	u32 insn;
-	u16 loop_count = spectre_bhb_loop_affected(SCOPE_SYSTEM);
 
 	BUG_ON(nr_inst != 1); /* MOV -> MOV */
 
@@ -1109,7 +1119,7 @@ void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt,
 
 	insn = le32_to_cpu(*origptr);
 	rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn);
-	insn = aarch64_insn_gen_movewide(rd, loop_count, 0,
+	insn = aarch64_insn_gen_movewide(rd, max_bhb_k, 0,
 					 AARCH64_INSN_VARIANT_64BIT,
 					 AARCH64_INSN_MOVEWIDE_ZERO);
 	*updptr++ = cpu_to_le32(insn);
-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Thu Dec 19 12:53:22 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Thu, 19 Dec 2024 12:53:22 -0800
Subject: [PATCH v3 2/3] arm64: cputype: Add MIDR_CORTEX_A76AE
In-Reply-To: <20241219205426.2275508-1-dianders@chromium.org>
References: <20241219205426.2275508-1-dianders@chromium.org>
Message-ID: <20241219125317.v3.2.I151f3b7ee323bcc3082179b8c60c3cd03308aa94@changeid>

>From the TRM, MIDR_CORTEX_A76AE has a partnum of 0xDOE and an
implementor of 0x41 (ARM). Add the values.


Cc: stable at vger.kernel.org
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

Changes in v3:
- New

 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 488f8e751349..a345628fce51 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -75,6 +75,7 @@
 #define ARM_CPU_PART_CORTEX_A76		0xD0B
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
+#define ARM_CPU_PART_CORTEX_A76AE	0xD0E
 #define ARM_CPU_PART_NEOVERSE_V1	0xD40
 #define ARM_CPU_PART_CORTEX_A78		0xD41
 #define ARM_CPU_PART_CORTEX_A78AE	0xD42
@@ -158,6 +159,7 @@
 #define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_CORTEX_A76AE	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76AE)
 #define MIDR_NEOVERSE_V1	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
 #define MIDR_CORTEX_A78	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
 #define MIDR_CORTEX_A78AE	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE)
-- 
2.47.1.613.gc27f4b7a9f-goog



From Frank.li at nxp.com  Thu Dec 19 12:53:56 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 19 Dec 2024 15:53:56 -0500
Subject: [PATCH v13 4/9] irqchip/gic-v3-its: Add
 DOMAIN_BUS_DEVICE_PCI_EP_MSI support
In-Reply-To: <Z2SFYwC7KC-qiZD2@ryzen>
References: <20241218-ep-msi-v13-0-646e2192dc24@nxp.com>
 <20241218-ep-msi-v13-4-646e2192dc24@nxp.com>
 <868qscq70x.wl-maz@kernel.org>
 <Z2RRimPlT41Ru281@lizhi-Precision-Tower-5810>
 <Z2R9qPmAyTcc5mtg@ryzen>
 <Z2R/S4y3fF2Dw4Ye@lizhi-Precision-Tower-5810>
 <Z2SFYwC7KC-qiZD2@ryzen>
Message-ID: <Z2SH5I/5oAHkNxS3@lizhi-Precision-Tower-5810>

On Thu, Dec 19, 2024 at 09:43:15PM +0100, Niklas Cassel wrote:
> On Thu, Dec 19, 2024 at 03:17:15PM -0500, Frank Li wrote:
> >
> > Thank you very much. I update msi part, so endpoint controller node align
> > host controller node.
> >
> > It should be
> > msi-map = <0x0000 &its1 0x0000 0x1000>;
> >
> > So if your hardware support multi physical function, your can create more
> > than one pci_test func. Previous version only support one EP func.
>
> I see. That seems like an improvement.
> I will need to ask Rockchip maintainer to drop my msi-parent patch for PCIe
> EP node then. (Which is currently queued up in for-6.14)
>
> However, for the PCIe host node, rk3588 has:
> iommu-map = <0x0000 &mmu600_pcie 0x0000 0x1000>;
>
> For the PCIe endpoint node, rk3588 has:
> iommus = <&mmu600_pcie 0x0000>;
>
> https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/commit/?h=v6.14-armsoc/dts64&id=da92d3dfc871e821a1bface3ba5afcf8cda19805
>
> Is it fine that for the PCIe EP node, we specify iommu mapping using:
> iommus = <&mmu600_pcie 0x0000>;
> but the ITS/MSI map will be:
> msi-map = <0x0000 &its1 0x0000 0x1000>;

For doorbell feature, it should be fine.

>
> isn't this a bit inconsistent?

Ideally, iommus need do similar map.

>
> The physical function is the "F" in the BDF.
> Does this mean that:
> iommus = <&mmu600_pcie 0x0000>;
> the IOMMU will not be able to distinguish different PCI physical functions
> from the same PCI device?

You are right. All physical functions will share one IOMMU space.

> So two different physical functions on the same
> PCI device share the same IOMMU mappings?

Yes,
Function should be okay. Only miss isolation protection. func1 and access
func2's dma memory address. At most system it should be fine.

Frank

>
>
> Kind regards,
> Niklas


From dianders at chromium.org  Thu Dec 19 12:53:23 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Thu, 19 Dec 2024 12:53:23 -0800
Subject: [PATCH v3 3/3] arm64: errata: Add newer ARM cores to the spectre_bhb_loop_affected() lists
In-Reply-To: <20241219205426.2275508-1-dianders@chromium.org>
References: <20241219205426.2275508-1-dianders@chromium.org>
Message-ID: <20241219125317.v3.3.I4a9a527e03f663040721c5401c41de587d015c82@changeid>

When comparing to the ARM list [1], it appears that several ARM cores
were missing from the lists in spectre_bhb_loop_affected(). Add them.

NOTE: for some of these cores it may not matter since other ways of
clearing the BHB may be used (like the CLRBHB instruction or ECBHB),
but it still seems good to have all the info from ARM's whitepaper
included.

[1] https://developer.arm.com/Arm%20Security%20Center/Spectre-BHB


Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels")
Cc: stable at vger.kernel.org
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

Changes in v3:
- New

 arch/arm64/kernel/proton-pack.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 06e04c9e6480..86d67f5a5a72 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -872,6 +872,14 @@ static u8 spectre_bhb_loop_affected(void)
 {
 	u8 k = 0;
 
+	static const struct midr_range spectre_bhb_k132_list[] = {
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
+		MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
+	};
+	static const struct midr_range spectre_bhb_k38_list[] = {
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
+	};
 	static const struct midr_range spectre_bhb_k32_list[] = {
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
@@ -885,6 +893,7 @@ static u8 spectre_bhb_loop_affected(void)
 	};
 	static const struct midr_range spectre_bhb_k24_list[] = {
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A76AE),
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
 		MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
 		{},
@@ -899,7 +908,11 @@ static u8 spectre_bhb_loop_affected(void)
 		{},
 	};
 
-	if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
+	if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k132_list))
+		k = 132;
+	else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k38_list))
+		k = 38;
+	else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
 		k = 32;
 	else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
 		k = 24;
-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Thu Dec 19 13:11:09 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Thu, 19 Dec 2024 13:11:09 -0800
Subject: [PATCH v3 1/2] arm64: cputype: Add QCOM_CPU_PART_KRYO_3XX_GOLD
In-Reply-To: <20241219211131.2389091-1-dianders@chromium.org>
References: <20241219211131.2389091-1-dianders@chromium.org>
Message-ID: <20241219131107.v3.1.I18e0288742871393228249a768e5d56ea65d93dc@changeid>

Add a definition for the Qualcomm Kryo 300-series Gold cores.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

(no changes since v1)

 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 488f8e751349..c8058f91a5bd 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -119,6 +119,7 @@
 #define QCOM_CPU_PART_KRYO		0x200
 #define QCOM_CPU_PART_KRYO_2XX_GOLD	0x800
 #define QCOM_CPU_PART_KRYO_2XX_SILVER	0x801
+#define QCOM_CPU_PART_KRYO_3XX_GOLD	0x802
 #define QCOM_CPU_PART_KRYO_3XX_SILVER	0x803
 #define QCOM_CPU_PART_KRYO_4XX_GOLD	0x804
 #define QCOM_CPU_PART_KRYO_4XX_SILVER	0x805
@@ -195,6 +196,7 @@
 #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO)
 #define MIDR_QCOM_KRYO_2XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_GOLD)
 #define MIDR_QCOM_KRYO_2XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_SILVER)
+#define MIDR_QCOM_KRYO_3XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_GOLD)
 #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER)
 #define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD)
 #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Thu Dec 19 13:11:08 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Thu, 19 Dec 2024 13:11:08 -0800
Subject: [PATCH v3 0/2] arm64: cputype: Add info about some Qualcomm Kryo cores
Message-ID: <20241219211131.2389091-1-dianders@chromium.org>


This series breaks off of my series that reworked Spectre BHB
mitigations. Originally I needed Qualcomm Kryo IDs because I was
adding "guesses" about their Spectre BHB mitigations. Now that the
Spectre BHB series no longer has guesses I don't need them there, but
these two patches still seem worth it to land on their own.

I've still called this series "v3" because the first patch was part of
the v1 and v2 of the previous series.

Link to prev versions:
v1: https://lore.kernel.org/r/20241209174430.2904353-1-dianders at chromium.org/
v2: https://lore.kernel.org/r/20241214005248.198803-1-dianders at chromium.org

Changes in v3:
- arm64: cputype: Add comments about Qualcomm Kryo 5XX and 6XX cores

Douglas Anderson (2):
  arm64: cputype: Add QCOM_CPU_PART_KRYO_3XX_GOLD
  arm64: cputype: Add comments about Qualcomm Kryo 5XX and 6XX cores

 arch/arm64/include/asm/cputype.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

-- 
2.47.1.613.gc27f4b7a9f-goog



From dianders at chromium.org  Thu Dec 19 13:11:10 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Thu, 19 Dec 2024 13:11:10 -0800
Subject: [PATCH v3 2/2] arm64: cputype: Add comments about Qualcomm Kryo 5XX and 6XX cores
In-Reply-To: <20241219211131.2389091-1-dianders@chromium.org>
References: <20241219211131.2389091-1-dianders@chromium.org>
Message-ID: <20241219131107.v3.2.I520dfa10ad9f598581c2591d631aa6e9e26f7603@changeid>

As tested on one example of a Qualcomm Kryo 5XX CPU [1] and one
example of a Qualcomm Kryo 6XX CPU [2], we don't need any extra MIDR
definitions for the cores in those processors. Add comments to make it
clear that these IDs weren't forgotten and just aren't needed.

[1] https://lore.kernel.org/r/l5rqbbxn6hktlcxooolkvi5n3arkht6zzhrvdjf6kis322nsup at 5hsrak4cgteq/
[2] https://lore.kernel.org/r/tx7vtur7yea6ruefrkpkccqptahgmxnsrudwdz5uzcfxnng25b at afrr5bmdk2xa/


Suggested-by: Julius Werner <jwerner at chromium.org>
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

Changes in v3:
- New

 arch/arm64/include/asm/cputype.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index c8058f91a5bd..8782d4721f81 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -200,6 +200,16 @@
 #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER)
 #define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD)
 #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
+
+/*
+ * NOTES:
+ * - Qualcomm Kryo 5XX Prime / Gold ID themselves as MIDR_CORTEX_A77
+ * - Qualcomm Kryo 5XX Silver IDs itself as MIDR_QCOM_KRYO_4XX_SILVER
+ * - Qualcomm Kryo 6XX Prime IDs itself as MIDR_CORTEX_X1
+ * - Qualcomm Kryo 6XX Gold IDs itself as ARM_CPU_PART_CORTEX_A78
+ * - Qualcomm Kryo 6XX Silver IDs itself as MIDR_CORTEX_A55
+ */
+
 #define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER)
 #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL)
 #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)
-- 
2.47.1.613.gc27f4b7a9f-goog



From konrad.dybcio at oss.qualcomm.com  Thu Dec 19 13:28:17 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 19 Dec 2024 22:28:17 +0100
Subject: [PATCH v6 5/5] arm64: dts: qcom: Update IPQ9574 xo_board_clk to
 use fixed factor clock
In-Reply-To: <2456ab36-f48e-4aa3-88e1-aeb7895c9816@quicinc.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-5-a5cfe09de485@quicinc.com>
 <0776a26e-56cd-4838-9b52-210ae9a1f281@oss.qualcomm.com>
 <8063460d-18ad-4e54-8232-716bad9d37c3@quicinc.com>
 <2456ab36-f48e-4aa3-88e1-aeb7895c9816@quicinc.com>
Message-ID: <fb9d117e-77bd-4a01-a738-f72d07f6b84c@oss.qualcomm.com>

On 18.12.2024 12:17 PM, Jie Luo wrote:
> 
> 
> On 12/13/2024 6:30 PM, Jie Luo wrote:
>>
>>
>> On 12/13/2024 2:33 AM, Konrad Dybcio wrote:
>>> On 7.11.2024 10:50 AM, Luo Jie wrote:
>>>> xo_board_clk is fixed to 24 MHZ, which is routed from WiFi output clock
>>>> 48 MHZ (also being the reference clock of CMN PLL) divided 2 by analog
>>>> block routing channel.
>>>>
>>>> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
>>>> ---
>>>> ? arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 7 ++++++-
>>>> ? arch/arm64/boot/dts/qcom/ipq9574.dtsi??????????? | 3 ++-
>>>> ? 2 files changed, 8 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/ arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>>> index 78f6a2e053d5..9a8692377176 100644
>>>> --- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>>> +++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>>> @@ -174,8 +174,13 @@ &ref_48mhz_clk {
>>>> ????? clock-mult = <1>;
>>>> ? };
>>>> +/*
>>>> + * The frequency of xo_board_clk is fixed to 24 MHZ, which is routed
>>>> + * from WiFi output clock 48 MHZ divided by 2.
>>>> + */
>>>> ? &xo_board_clk {
>>>> -??? clock-frequency = <24000000>;
>>>> +??? clock-div = <2>;
>>>> +??? clock-mult = <1>;
>>>> ? };
>>>> ? &xo_clk {
>>>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/ dts/qcom/ipq9574.dtsi
>>>> index 8246a00a3e3e..25aed33e9358 100644
>>>> --- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>>>> +++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>>>> @@ -32,7 +32,8 @@ sleep_clk: sleep-clk {
>>>> ????????? };
>>>> ????????? xo_board_clk: xo-board-clk {
>>>> -??????????? compatible = "fixed-clock";
>>>> +??????????? compatible = "fixed-factor-clock";
>>>> +??????????? clocks = <&ref_48mhz_clk>;
>>>
>>> This must be squashed with the previous patch, you can't introduce
>>> code and replace it immediately afterwards.
>>>
>>> Konrad
> 
> Hi Konrad,
> 
> Looking at this comment again, there may have been some
> misunderstanding. We are not introducing xo_board_clk in patch 4 of this
> series. xo_board_clk is a pre-existing node.
> 
> As part of this additional patch 5, we wanted to address Dmitry's
> comment earlier in v5 (reference to comment below), by converting the
> xo_board_clk as well to a fixed-factor clock. So it is better to keep
> this change as a separate patch in my view. Hope this is OK.

Oh okay..

What's the difference between xo_board_clk and xo_clk then, if the
divider is accounted for in xo_board_clk?

Konrad


From dmitry.baryshkov at linaro.org  Thu Dec 19 14:00:23 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 00:00:23 +0200
Subject: [PATCH v3 2/2] arm64: cputype: Add comments about Qualcomm Kryo
 5XX and 6XX cores
In-Reply-To: <20241219131107.v3.2.I520dfa10ad9f598581c2591d631aa6e9e26f7603@changeid>
References: <20241219211131.2389091-1-dianders@chromium.org>
 <20241219131107.v3.2.I520dfa10ad9f598581c2591d631aa6e9e26f7603@changeid>
Message-ID: <6xubvdnyo4otwanapxersipmae4uuwkvple2jaxyuu5ucepjju@kl6lhbde4ney>

On Thu, Dec 19, 2024 at 01:11:10PM -0800, Douglas Anderson wrote:
> As tested on one example of a Qualcomm Kryo 5XX CPU [1] and one
> example of a Qualcomm Kryo 6XX CPU [2], we don't need any extra MIDR
> definitions for the cores in those processors. Add comments to make it
> clear that these IDs weren't forgotten and just aren't needed.
> 
> [1] https://lore.kernel.org/r/l5rqbbxn6hktlcxooolkvi5n3arkht6zzhrvdjf6kis322nsup at 5hsrak4cgteq/
> [2] https://lore.kernel.org/r/tx7vtur7yea6ruefrkpkccqptahgmxnsrudwdz5uzcfxnng25b at afrr5bmdk2xa/
> 
> 
> Suggested-by: Julius Werner <jwerner at chromium.org>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---


Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From nicolinc at nvidia.com  Thu Dec 19 14:30:19 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 19 Dec 2024 14:30:19 -0800
Subject: [PATCH v3 01/14] iommufd: Keep IOCTL list in an alphabetical
 order
In-Reply-To: <0bdb04c6dc32f428a7f181471a0d78642e80d3b8.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
 <0bdb04c6dc32f428a7f181471a0d78642e80d3b8.1734477608.git.nicolinc@nvidia.com>
Message-ID: <Z2See1oS+Ogr4LQI@Asurada-Nvidia>

On Tue, Dec 17, 2024 at 09:00:14PM -0800, Nicolin Chen wrote:
> Move VDEVICE upward to keep the order. Also run clang-format keep the same
> coding style at line wrappings. No functional change.

It should fix the order in ucmd_buffer too. Will include in v4.

Nicolin


From nicolinc at nvidia.com  Thu Dec 19 14:31:55 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Thu, 19 Dec 2024 14:31:55 -0800
Subject: [PATCH v3 06/14] iommufd: Add IOMMUFD_OBJ_VIRQ and
 IOMMUFD_CMD_VIRQ_ALLOC
In-Reply-To: <dc1252de7ff06c944cb7d91c91b4f61c25182f91.1734477608.git.nicolinc@nvidia.com>
References: <cover.1734477608.git.nicolinc@nvidia.com>
 <dc1252de7ff06c944cb7d91c91b4f61c25182f91.1734477608.git.nicolinc@nvidia.com>
Message-ID: <Z2Se2/IVKgXSXH5M@Asurada-Nvidia>

On Tue, Dec 17, 2024 at 09:00:19PM -0800, Nicolin Chen wrote:
> diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
> index cfbdf7b0e3c1..9d15978ef882 100644
> --- a/drivers/iommu/iommufd/main.c
> +++ b/drivers/iommu/iommufd/main.c
> @@ -367,6 +367,8 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = {
>  		 __reserved),
>  	IOCTL_OP(IOMMU_VIOMMU_ALLOC, iommufd_viommu_alloc_ioctl,
>  		 struct iommu_viommu_alloc, out_viommu_id),
> +	IOCTL_OP(IOMMU_VIRQ_ALLOC, iommufd_virq_alloc, struct iommu_virq_alloc,
> +		 out_virq_fd),

This is missing the "struct iommu_virq_alloc" in union ucmd_buffer.
Will include in v4.

Nicolin


From cki-project at redhat.com  Thu Dec 19 15:12:08 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Thu, 19 Dec 2024 23:12:08 -0000
Subject: =?utf-8?b?4p2M?= FAIL: Test report for for-kernelci (6.13.0-rc3,
 upstream-arm-next, 06a57361)
Message-ID: <64955.124121918121002524@us-mta-554.us.mimecast.lan>

Hi, we tested your kernel and here are the results:

    Overall result: FAILED
             Merge: OK
           Compile: OK
              Test: FAILED (Did not boot)


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/redhat:1596629923

One or more kernel builds failed:
    Builds that are failing to boot:
         aarch64 - https://datawarehouse.cki-project.org/kcidb/builds/redhat:1596629923-aarch64-kernel


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 florian.fainelli at broadcom.com  Thu Dec 19 15:43:17 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 19 Dec 2024 15:43:17 -0800
Subject: [PATCH 1/2] dt-bindings: memory-controller: Document rev c.1.5
 compatible
In-Reply-To: <wxq5zzfh5jesucbbste2j6x2jtj45wjfc5xzjkqbqqta7cprda@oaf5arr3z6pt>
References: <20241217194439.929040-1-florian.fainelli@broadcom.com>
 <20241217194439.929040-2-florian.fainelli@broadcom.com>
 <2e33t7ft5ermsfr7c4ympxrn6l5sqdef3wml4hlbnhdupoouwj@gfjpbmowjadi>
 <93a1333d-442f-4cec-b823-9b1a5ff6dc6b@broadcom.com>
 <wxq5zzfh5jesucbbste2j6x2jtj45wjfc5xzjkqbqqta7cprda@oaf5arr3z6pt>
Message-ID: <f906a056-3c6b-4115-9fd0-e50da8fc049b@broadcom.com>

On 12/19/24 00:58, Krzysztof Kozlowski wrote:
> On Wed, Dec 18, 2024 at 09:15:08AM -0800, Florian Fainelli wrote:
>> On 12/18/24 03:37, Krzysztof Kozlowski wrote:
>>> On Tue, Dec 17, 2024 at 11:44:38AM -0800, Florian Fainelli wrote:
>>>> Document the revision c.1.5 compatible string that is present on newer
>>>> Broadcom STB memory controllers (74165 and onwards).
>>>>
>>>> Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
>>>> ---
>>>>    .../bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml       | 1 +
>>>>    1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
>>>> index 4b072c879b02..99d79ccd1036 100644
>>>> --- a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
>>>> +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
>>>> @@ -29,6 +29,7 @@ properties:
>>>>              - brcm,brcmstb-memc-ddr-rev-c.1.2
>>>>              - brcm,brcmstb-memc-ddr-rev-c.1.3
>>>>              - brcm,brcmstb-memc-ddr-rev-c.1.4
>>>> +          - brcm,brcmstb-memc-ddr-rev-c.1.5
>>>
>>> You should use v2.1 fallback and drop driver patch. Or explain in
>>> commit briefly why different approach is suitable.
>>
>> Are you suggesting that we should have fallback compatible strings, such
>> that we have something like this:
>>
>> compatible = "brcm,brcmstb-memc-ddr-rev-c.1.5",
>> "brcm,brcmstb-memc-ddr-rev-c", "brcm,brcmstb-memc-ddr"
>>
>> and the driver only needs to match on "brcm,brcmstb-memc-ddr-rev-c" and
>> apply the adequate register offset table?
> 
> Almost, fallback should be brcm,brcmstb-memc-ddr-rev-b.2.1 or whatever
> was in the driver first or whatever is the oldest known common
> interface.
> 
> brcm,brcmstb-memc-ddr-rev-c is not a specific compatible.
> 
>> If so, that is not how the current binding, and therefore DTBs are being
>> deployed, so that will introduce a breakage until we update all DTBs in the
>> field...
> 
> No. First, I thought about new comaptible so the one you add here. No
> breakage, it's new compatible. This saves you these pointless updates of
> driver everytime you add new compatible.

Yes, but that is not how the binding has been defined until now, so all 
of the DTBs out there have:

compatible = "brcm,brcmstb-memc-ddr-rev-b.2.x", "brcm,brcmstb-memc-ddr"

(where X is in range [1..5])

and there is no fallback defined to "brcm,brcmstb-memc-ddr-rev-b.2.1", 
so it is not like we can retrofit that easily by adding one now.

 > > Second, you can introduce fallbacks to older compatibles as well - 
there
> will be no breakage, because you add one more compatible. The old
> compatibles (covered by fallback) of course stays in the driver, so
> there is no breakage at all. We did it multiple times for several
> different bindings in Qualcomm. People were doing exactly the same:
> adding compatible for new device to binding and driver, without
> considering the compatibility at all.
> 
> Except being logically correct choice - using fallbacks - this really
> has huge benefits when later upstreaming complete, big SoCs, like we do
> for latest Qualcomm SoCs: several changes will be only bindings updates.

Yes, there are advantages to using fallbacks and we (ab)use that 
whenever practical.

The driver only uses a very limited subset of registers (for now), the 
registers change between minor revisions as well in a way that using a 
fallback like "brcm,brcmstb-memc-ddr-rev-b.2.1" is not accurate enough 
not practical. In particular for some of the changes that I am thinking 
of adding later on, we would need the precise minor version because the 
behavior and/or register interface is subtly different that this matters.

Thanks
-- 
Florian


From peng.fan at nxp.com  Thu Dec 19 16:11:05 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 20 Dec 2024 00:11:05 +0000
Subject: [PATCH v3 2/2] nvmem: imx-ocotp-ele: Support accessing controller
 for i.MX9
In-Reply-To: <Z2RUVK/nj5Mf8hVr@lizhi-Precision-Tower-5810>
References: <20241219-imx-ocotp-v3-0-b22371098071@nxp.com>
 <20241219-imx-ocotp-v3-2-b22371098071@nxp.com>
 <Z2RUVK/nj5Mf8hVr@lizhi-Precision-Tower-5810>
Message-ID: <PAXPR04MB8459E92CDCE9AE6EE7BDA95188072@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH v3 2/2] nvmem: imx-ocotp-ele: Support accessing
> controller for i.MX9
> 
> On Thu, Dec 19, 2024 at 10:25:18PM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > i.MX9 OCOTP supports a specific peripheral or function being fused
> > which means disabled, so
> >  - Introduce ocotp_access_gates to be container of efuse gate info
> >  - Iterate each node under '/soc' to check accessing permission. If
> > not
> 
> Nit: Iterate all nodes to ....
> 
> >    allowed to be accessed, detach the node
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/nvmem/imx-ocotp-ele.c | 183
> > +++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 182 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/nvmem/imx-ocotp-ele.c
> > b/drivers/nvmem/imx-ocotp-ele.c index
> >
> ca6dd71d8a2e29888c6e556aaea116c1a967cb5f..173863b1fd7de1505
> 76b78f03c25
> > 6a151b174389 100644
> > --- a/drivers/nvmem/imx-ocotp-ele.c
> > +++ b/drivers/nvmem/imx-ocotp-ele.c
> > @@ -5,6 +5,8 @@
> >   * Copyright 2023 NXP
> >   */
> >
> [...]
> > +
> > +	for_each_available_child_of_node_scoped(parent, child) {
> > +		struct of_phandle_iterator it;
> > +		int err;
> > +		u32 id;
> > +
> > +		of_for_each_phandle(&it, err, child, "access-
> controllers",
> > +				    "#access-controller-cells", 0) {
> > +			struct of_phandle_args provider_args;
> > +			struct device_node *provider = it.node;
> > +
> > +			if (err) {
> > +				dev_err(dev, "Unable to get access-
> controllers property for node %s\n, err: %d",
> > +					child->full_name, err);
> > +				of_node_put(provider);
> > +				return err;
> > +			}
> > +
> > +			/* Only support one cell */
> > +			if (of_phandle_iterator_args(&it,
> provider_args.args, 1) != 1) {
> > +				dev_err(dev, "wrong args count\n");
> 
> you call of_node_put(provider) in above err branch.
> why not call it here?

Good catch. I will fix in v4.

Thanks,
Peng.

> 
> Frank
> > +				return -EINVAL;
> > +			}
> > +
> > +			id = provider_args.args[0];
> > +
> > +			dev_dbg(dev, "Checking node: %s gate: %d\n",
> child->full_name,
> > +id);
> > +
> > +			if (imx_ele_ocotp_check_access(pdev, id)) {
> > +				of_detach_node(child);
> > +				dev_err(dev, "%s: Not granted,
> device driver will not be probed\n",
> > +					child->full_name);
> > +			}
> > +		}
> > +
> > +		imx_ele_ocotp_grant_access(pdev, child);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> [...]
> 
> >
> > --
> > 2.37.1
> >


From dmitry.baryshkov at linaro.org  Thu Dec 19 16:13:53 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 02:13:53 +0200
Subject: [PATCH v3 07/15] drm/bridge: analogix_dp: Add support for phy
 configuration.
In-Reply-To: <20241219080604.1423600-8-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-8-damon.ding@rock-chips.com>
Message-ID: <a6vvydjbx3hbckoy74iiyzguyyacwvdh6iirqydjfvhwgocw3a@knecggjcbcid>

On Thu, Dec 19, 2024 at 04:05:56PM +0800, Damon Ding wrote:
> Add support to configurate link rate, lane count, voltage swing and
> pre-emphasis with phy_configure(). It is helpful in application scenarios
> where analogix controller is mixed with the phy of other vendors.
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> 
> ---
> 
> Changes in v2:
> - remove needless assignments for phy_configure()
> - remove unnecessary changes for phy_power_on()/phy_power_off()
> ---
>  .../drm/bridge/analogix/analogix_dp_core.c    |  1 +
>  .../gpu/drm/bridge/analogix/analogix_dp_reg.c | 56 +++++++++++++++++++
>  2 files changed, 57 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> index 6f10d88a34c5..9429c50cc1bc 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> @@ -1696,6 +1696,7 @@ int analogix_dp_resume(struct analogix_dp_device *dp)
>  	if (dp->plat_data->power_on)
>  		dp->plat_data->power_on(dp->plat_data);
>  
> +	phy_set_mode(dp->phy, PHY_MODE_DP);
>  	phy_power_on(dp->phy);
>  
>  	analogix_dp_init_dp(dp);
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
> index 3afc73c858c4..613ce504bea6 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
> @@ -11,6 +11,7 @@
>  #include <linux/gpio/consumer.h>
>  #include <linux/io.h>
>  #include <linux/iopoll.h>
> +#include <linux/phy/phy.h>
>  
>  #include <drm/bridge/analogix_dp.h>
>  
> @@ -513,10 +514,25 @@ void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
>  void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
>  {
>  	u32 reg;
> +	int ret;
>  
>  	reg = bwtype;
>  	if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
>  		writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
> +
> +	if (dp->phy) {
> +		union phy_configure_opts phy_cfg = {0};
> +
> +		phy_cfg.dp.lanes = dp->link_train.lane_count;

Should not be necessary, you are only setting the .set_rate.

> +		phy_cfg.dp.link_rate =
> +			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
> +		phy_cfg.dp.set_rate = true;
> +		ret = phy_configure(dp->phy, &phy_cfg);
> +		if (ret && ret != -EOPNOTSUPP) {
> +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
> +			return;
> +		}
> +	}
>  }
>  
>  void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
> @@ -530,9 +546,22 @@ void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
>  void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
>  {
>  	u32 reg;
> +	int ret;
>  
>  	reg = count;
>  	writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
> +
> +	if (dp->phy) {
> +		union phy_configure_opts phy_cfg = {0};
> +
> +		phy_cfg.dp.lanes = dp->link_train.lane_count;
> +		phy_cfg.dp.set_lanes = true;
> +		ret = phy_configure(dp->phy, &phy_cfg);
> +		if (ret && ret != -EOPNOTSUPP) {
> +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
> +			return;
> +		}
> +	}
>  }
>  
>  void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
> @@ -546,10 +575,37 @@ void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
>  void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp)
>  {
>  	u8 lane;
> +	int ret;
>  
>  	for (lane = 0; lane < dp->link_train.lane_count; lane++)
>  		writel(dp->link_train.training_lane[lane],
>  		       dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane);
> +
> +	if (dp->phy) {
> +		union phy_configure_opts phy_cfg = {0};
> +
> +		for (lane = 0; lane < dp->link_train.lane_count; lane++) {
> +			u8 training_lane = dp->link_train.training_lane[lane];
> +			u8 vs, pe;
> +
> +			vs = (training_lane & DP_TRAIN_VOLTAGE_SWING_MASK) >>
> +			     DP_TRAIN_VOLTAGE_SWING_SHIFT;
> +			pe = (training_lane & DP_TRAIN_PRE_EMPHASIS_MASK) >>
> +			     DP_TRAIN_PRE_EMPHASIS_SHIFT;
> +			phy_cfg.dp.voltage[lane] = vs;
> +			phy_cfg.dp.pre[lane] = pe;
> +		}
> +
> +		phy_cfg.dp.lanes = dp->link_train.lane_count;
> +		phy_cfg.dp.link_rate =
> +			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;

This two should not be necessary, please drop them.

> +		phy_cfg.dp.set_voltages = true;
> +		ret = phy_configure(dp->phy, &phy_cfg);
> +		if (ret && ret != -EOPNOTSUPP) {
> +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
> +			return;
> +		}
> +	}
>  }
>  
>  u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane)
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Thu Dec 19 16:16:41 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 02:16:41 +0200
Subject: [PATCH v3 08/15] drm/rockchip: analogix_dp: Add support to get
 panel from the DP AUX bus
In-Reply-To: <20241219080604.1423600-9-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-9-damon.ding@rock-chips.com>
Message-ID: <aiggslcdbdmnc2amlvmzycyxmu3f5zp6kt4ifgzq5gkuugmnem@oqnwf4o7hbss>

On Thu, Dec 19, 2024 at 04:05:57PM +0800, Damon Ding wrote:
> The rockchip_dp_of_panel_on_aux_bus() helps to check whether the DT
> configurations related to the DP AUX bus are correct or not.
> 
> If failed to get the panel from the platform bus, it is good to try
> the DP AUX bus. Then, the probing process will continue until it enters
> the analogix_dp_bind(), where devm_of_dp_aux_populate_bus() is called
> after &analogix_dp_device.aux has been initialized.

No. devm_of_dp_aux_populate_bus() should be called before bind(). And
bind should only be called from the done_probing() callback. The reason
is very simple: the panel driver might be built as a module and might be
not available when the analogix driver is being probed.

Also, please invert the logic of the commit message (and the driver).
The platform bus should be a fallback if there is no AUX bus panel, not
other way around.

> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> ---
>  .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 24 +++++++++++++++++--
>  1 file changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index ba5263f85ee2..60c902abf40b 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -317,6 +317,24 @@ static const struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs =
>  	.atomic_check = rockchip_dp_drm_encoder_atomic_check,
>  };
>  
> +static bool rockchip_dp_of_panel_on_aux_bus(const struct device_node *np)
> +{
> +	struct device_node *bus_node, *panel_node;
> +
> +	bus_node = of_get_child_by_name(np, "aux-bus");
> +	if (!bus_node)
> +		return false;
> +
> +	panel_node = of_get_child_by_name(bus_node, "panel");
> +	of_node_put(bus_node);
> +	if (!panel_node)
> +		return false;
> +
> +	of_node_put(panel_node);
> +
> +	return true;
> +}
> +
>  static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
>  {
>  	struct device *dev = dp->dev;
> @@ -435,8 +453,10 @@ static int rockchip_dp_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  
>  	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
> -	if (ret < 0)
> -		return ret;
> +	if (ret < 0) {
> +		if (!rockchip_dp_of_panel_on_aux_bus(dev->of_node))
> +			return ret;
> +	}
>  
>  	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
>  	if (!dp)
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Thu Dec 19 16:18:24 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 02:18:24 +0200
Subject: [PATCH v3 10/15] dt-bindings: display: rockchip: analogix-dp:
 Add support to get panel from the DP AUX bus
In-Reply-To: <20241219080604.1423600-11-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-11-damon.ding@rock-chips.com>
Message-ID: <bjkcue3dfgaf5i66cqbiczifo7r3xngupghklxgevwqpwfeeix@i2jfd477igri>

On Thu, Dec 19, 2024 at 04:05:59PM +0800, Damon Ding wrote:
> According to Documentation/devicetree/bindings/display/dp-aux-bus.yaml,
> it is a good way to get panel through the DP AUX bus.
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> ---
>  .../bindings/display/rockchip/rockchip,analogix-dp.yaml        | 3 +++
>  1 file changed, 3 insertions(+)

Business before pleasure.^W^W^W Bindings before the driver.

> 
> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> index 4f84e8849876..c45d92a2d901 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> @@ -49,6 +49,9 @@ properties:
>      description:
>        This SoC makes use of GRF regs.
>  
> +  aux-bus:
> +    $ref: /schemas/display/dp-aux-bus.yaml#
> +
>  required:
>    - compatible
>    - clocks
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Thu Dec 19 16:17:50 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 02:17:50 +0200
Subject: [PATCH v3 09/15] drm/bridge: analogix_dp: Add support to get
 panel from the DP AUX bus
In-Reply-To: <20241219080604.1423600-10-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-10-damon.ding@rock-chips.com>
Message-ID: <irh3rei7to7gevrr5dqwa3qr3nl2lunenyvvvlqnpiyplbk2vj@ooedydnvl4df>

On Thu, Dec 19, 2024 at 04:05:58PM +0800, Damon Ding wrote:
> If the panel can not be found in the beginning of rockchip_dp_probe()
> using the platform bus, we can still try to find it in analogix_dp_bind()
> through the DP AUX bus after the &analogix_dp_device.aux has been
> initialized.
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> ---
>  .../drm/bridge/analogix/analogix_dp_core.c    | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> index 9429c50cc1bc..eae02819e3bb 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> @@ -19,12 +19,14 @@
>  #include <linux/platform_device.h>
>  
>  #include <drm/bridge/analogix_dp.h>
> +#include <drm/display/drm_dp_aux_bus.h>
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_bridge.h>
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_device.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>
> @@ -1733,6 +1735,23 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
>  		goto err_disable_pm_runtime;
>  	}
>  
> +	if (!dp->plat_data->panel) {
> +		/*
> +		 * If the edp-panel module has not yet been initialized, the
> +		 * devm_of_dp_aux_populate_bus() function will return 0 and
> +		 * the done_probing() callback will not be called either.
> +		 * Consequently, the panel will never be found.
> +		 *
> +		 * This is the reason why we do not use the done_probing()
> +		 * callback and do not check the reture value here.

NAK. It is there for exactly this reason, to account for the panel
driver being not present yet. Please make a use of the done_probing()
callback.

> +		 */
> +		devm_of_dp_aux_populate_bus(&dp->aux, NULL);
> +		ret = drm_of_find_panel_or_bridge(dp->dev->of_node, 1, 0,
> +						  &dp->plat_data->panel, NULL);
> +		if (ret)
> +			goto err_unregister_aux;
> +	}
> +
>  	ret = analogix_dp_create_bridge(drm_dev, dp);
>  	if (ret) {
>  		DRM_ERROR("failed to create bridge (%d)\n", ret);
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From didi.debian at cknow.org  Thu Dec 19 16:17:42 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Fri, 20 Dec 2024 01:17:42 +0100
Subject: [PATCH v3 07/15] drm/bridge: analogix_dp: Add support for phy
 configuration.
In-Reply-To: <a6vvydjbx3hbckoy74iiyzguyyacwvdh6iirqydjfvhwgocw3a@knecggjcbcid>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-8-damon.ding@rock-chips.com>
 <a6vvydjbx3hbckoy74iiyzguyyacwvdh6iirqydjfvhwgocw3a@knecggjcbcid>
Message-ID: <D6G3H3AXXVAJ.3F1WMBTWLX2KV@cknow.org>

On Fri Dec 20, 2024 at 1:13 AM CET, Dmitry Baryshkov wrote:
> On Thu, Dec 19, 2024 at 04:05:56PM +0800, Damon Ding wrote:
> >  void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
> > @@ -546,10 +575,37 @@ void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
> >  void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp)
> >  {
> >  	u8 lane;
> > +	int ret;
> >  
> >  	for (lane = 0; lane < dp->link_train.lane_count; lane++)
> >  		writel(dp->link_train.training_lane[lane],
> >  		       dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane);
> > +
> > +	if (dp->phy) {
> > +		union phy_configure_opts phy_cfg = {0};
> > +
> > +		for (lane = 0; lane < dp->link_train.lane_count; lane++) {
> > +			u8 training_lane = dp->link_train.training_lane[lane];
> > +			u8 vs, pe;
> > +
> > +			vs = (training_lane & DP_TRAIN_VOLTAGE_SWING_MASK) >>
> > +			     DP_TRAIN_VOLTAGE_SWING_SHIFT;
> > +			pe = (training_lane & DP_TRAIN_PRE_EMPHASIS_MASK) >>
> > +			     DP_TRAIN_PRE_EMPHASIS_SHIFT;
> > +			phy_cfg.dp.voltage[lane] = vs;
> > +			phy_cfg.dp.pre[lane] = pe;
> > +		}
> > +
> > +		phy_cfg.dp.lanes = dp->link_train.lane_count;
> > +		phy_cfg.dp.link_rate =
> > +			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
>
> This two should not be necessary, please drop them.

This too or These two (statements)?

> > +		phy_cfg.dp.set_voltages = true;
> > +		ret = phy_configure(dp->phy, &phy_cfg);
> > +		if (ret && ret != -EOPNOTSUPP) {
> > +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
> > +			return;
> > +		}
> > +	}
> >  }
> >  
> >  u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane)
> > -- 
> > 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/20241220/408c112d/attachment.sig>

From dmitry.baryshkov at linaro.org  Thu Dec 19 16:20:15 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 02:20:15 +0200
Subject: [PATCH v3 14/15] arm64: dts: rockchip: Enable eDP0 display on
 RK3588S EVB1 board
In-Reply-To: <20241219080604.1423600-15-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-15-damon.ding@rock-chips.com>
Message-ID: <cg7bnhol4gvzji7agxazas7nkxy7zammzy67rjvhp35yqyraju@73daepsbmuae>

On Thu, Dec 19, 2024 at 04:06:03PM +0800, Damon Ding wrote:
> Add the necessary DT changes to enable eDP0 on RK3588S EVB1 board:
> - Add edp-panel node
> - Set pinctrl of pwm12 for backlight
> - Enable edp0/hdptxphy0/vp2
> 
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> 
> ---
> 
> Changes in v2:
> - Remove brightness-levels and default-brightness-level properties in
>   backlight node.
> - Add the detail DT changes to commit message.
> 
> Changes in v3:
> - Use aux-bus instead of platform bus for edp-panel.
> ---
>  .../boot/dts/rockchip/rk3588s-evb1-v10.dts    | 52 +++++++++++++++++++
>  1 file changed, 52 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
> index bc4077575beb..9547ab18e596 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
> @@ -9,6 +9,7 @@
>  #include <dt-bindings/gpio/gpio.h>
>  #include <dt-bindings/input/input.h>
>  #include <dt-bindings/pinctrl/rockchip.h>
> +#include <dt-bindings/soc/rockchip,vop2.h>
>  #include <dt-bindings/usb/pd.h>
>  #include "rk3588s.dtsi"
>  
> @@ -238,6 +239,41 @@ &combphy2_psu {
>  	status = "okay";
>  };
>  
> +&edp0 {
> +	force-hpd;
> +	status = "okay";
> +
> +	aux-bus {
> +		panel {
> +			compatible = "lg,lp079qx1-sp0v";

Why do you need the particular compat string here? Can you use the
generic "edp-panel" instead? What if the user swaps the panel?

> +			backlight = <&backlight>;
> +			power-supply = <&vcc3v3_lcd_edp>;
> +
> +			port {
> +				panel_in_edp: endpoint {
> +					remote-endpoint = <&edp_out_panel>;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&edp0_in {
> +	edp0_in_vp2: endpoint {
> +		remote-endpoint = <&vp2_out_edp0>;
> +	};
> +};
> +
> +&edp0_out {
> +	edp_out_panel: endpoint {
> +		remote-endpoint = <&panel_in_edp>;
> +	};
> +};
> +
> +&hdptxphy0 {
> +	status = "okay";
> +};
> +
>  &i2c3 {
>  	status = "okay";
>  
> @@ -399,6 +435,7 @@ usbc0_int: usbc0-int {
>  };
>  
>  &pwm12 {
> +	pinctrl-0 = <&pwm12m1_pins>;
>  	status = "okay";
>  };
>  
> @@ -1168,3 +1205,18 @@ usbdp_phy0_dp_altmode_mux: endpoint at 1 {
>  		};
>  	};
>  };
> +
> +&vop_mmu {
> +	status = "okay";
> +};
> +
> +&vop {
> +	status = "okay";
> +};
> +
> +&vp2 {
> +	vp2_out_edp0: endpoint at ROCKCHIP_VOP2_EP_EDP0 {
> +		reg = <ROCKCHIP_VOP2_EP_EDP0>;
> +		remote-endpoint = <&edp0_in_vp2>;
> +	};
> +};
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Thu Dec 19 16:22:33 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 02:22:33 +0200
Subject: [PATCH v3 04/15] phy: phy-rockchip-samsung-hdptx: Rename some
 register names related to DP
In-Reply-To: <20241219080604.1423600-5-damon.ding@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-5-damon.ding@rock-chips.com>
Message-ID: <rkdp44csph6stq2e7emhgjziiwypcas7uqsvcdo7i6ypvg64uz@gnqikl5fzxqd>

On Thu, Dec 19, 2024 at 04:05:53PM +0800, Damon Ding wrote:
> The modifications of DP register names are as follows:
> - Add the '_MASK' suffix to some registers to ensure consistency.
> - Complete the names of some register to their full names.
> - Swap the definitions of LCPLL_REF and ROPLL_REF.

Three unrelated changes, ideally means three commits (I won't insist on
that though). Also please mention that LCPLL_REF and ROPLL_REF were not
used by the existing driver, so it's not a bug and there is no need to
backport it.

> 
> Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver")
> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> ---
>  .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 64 +++++++++----------
>  1 file changed, 32 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index ceab9c71d3b5..c1b9c73f5f9f 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -69,41 +69,41 @@
>  #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)
> +#define ROPLL_SDC_FRAC_EN_RBR_MASK	BIT(3)
> +#define ROPLL_SDC_FRAC_EN_HBR_MASK	BIT(2)
> +#define ROPLL_SDC_FRAC_EN_HBR2_MASK	BIT(1)
> +#define ROPLL_SDM_FRAC_EN_HBR3_MASK	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)
> +#define ROPLL_SDC_NDIV_RSTN_MASK	BIT(2)
> +#define ROPLL_SSC_EN_MASK		BIT(0)
>  /* CMN_REG(0081) */
> -#define OVRD_PLL_CD_CLK_EN		BIT(8)
> -#define PLL_CD_HSCLK_EAST_EN		BIT(0)
> +#define OVRD_PLL_CD_CLK_EN_MASK		BIT(8)
> +#define ANA_PLL_CD_HSCLK_EAST_EN_MASK	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)
> +#define ANA_PLL_FRL_MODE_EN_MASK	BIT(3)
> +#define ANA_PLL_TX_HS_CLK_EN_MASK	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
> +#define DIG_CLK_SEL_MASK		BIT(1)
> +#define LCPLL_REF			BIT(1)
> +#define ROPLL_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 HS_SPEED_SEL_MASK		BIT(0)
>  #define DIV_10_CLOCK			BIT(0)
>  /* CMN_REG(009b) */
> -#define IS_SPEED_SEL			BIT(4)
> +#define LS_SPEED_SEL_MASK		BIT(4)
>  #define LINK_SYMBOL_CLOCK		BIT(4)
>  #define LINK_SYMBOL_CLOCK1_2		0
>  
> @@ -165,32 +165,32 @@
>  #define HDMI_MODE			BIT(2)
>  #define HDMI_TMDS_FRL_SEL		BIT(1)
>  /* LNTOP_REG(0206) */
> -#define DATA_BUS_SEL			BIT(0)
> +#define DATA_BUS_WIDTH_SEL_MASK		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)
> +#define LN0_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
> +#define LN0_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
> +#define LN0_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
> +#define LN0_TX_SER_RATE_SEL_HBR3_MASK	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)
> +#define LN1_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
> +#define LN1_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
> +#define LN1_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
> +#define LN1_TX_SER_RATE_SEL_HBR3_MASK	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)
> +#define LN2_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
> +#define LN2_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
> +#define LN2_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
> +#define LN2_TX_SER_RATE_SEL_HBR3_MASK	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)
> +#define LN3_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
> +#define LN3_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
> +#define LN3_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
> +#define LN3_TX_SER_RATE_SEL_HBR3_MASK	BIT(2)
>  
>  #define HDMI20_MAX_RATE			600000000
>  
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Thu Dec 19 16:45:09 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 02:45:09 +0200
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <CAPY8ntAnJ1YDQee=pFSDY3+EXHj4_RZ-M1NMp2C3ZDdD5DsCKA@mail.gmail.com>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-vivacious-chameleon-of-swiftness-f1edc4@houat>
 <CAA8EJprjCyWBNkRrc4W24uCwPtf_kxZLqNeNP8EJffbutYQ21w@mail.gmail.com>
 <20241218-wild-red-manatee-bb2a34@houat>
 <CAPY8ntDdcOXuWVgx6+cbgX5ct_-MXcE7CWDKgGP57EX6bvBLaw@mail.gmail.com>
 <CAPY8ntAnJ1YDQee=pFSDY3+EXHj4_RZ-M1NMp2C3ZDdD5DsCKA@mail.gmail.com>
Message-ID: <c7qyka3hsrggqevdwdlfcanzps3z63s4joryskijlbuztacmly@tadqjm2vkj24>

On Thu, Dec 19, 2024 at 04:16:37PM +0000, Dave Stevenson wrote:
> On Wed, 18 Dec 2024 at 14:52, Dave Stevenson
> <dave.stevenson at raspberrypi.com> wrote:
> >
> > Hi Maxime & Dmitry
> >
> > On Wed, 18 Dec 2024 at 07:59, Maxime Ripard <mripard at kernel.org> wrote:
> > >
> > > On Wed, Dec 18, 2024 at 07:24:23AM +0200, Dmitry Baryshkov wrote:
> > > > On Tue, 17 Dec 2024 at 19:21, Maxime Ripard <mripard at kernel.org> wrote:
> > > > > On Tue, Dec 17, 2024 at 02:40:22AM +0200, Dmitry Baryshkov wrote:
> > > > > > While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
> > > > > > framework, I stumbled upon an issue while handling the Audio InfoFrames.
> > > > > > The HDMI codec callbacks weren't receiving the drm_atomic_state, so
> > > > > > there was no simple way to get the drm_connector that stayed at the end
> > > > > > of the bridge chain. At the same point the drm_hdmi_connector functions
> > > > > > expected to get drm_connector instance.
> > > > > >
> > > > > > While looking for a way to solve the issue, I stumbled upon several
> > > > > > deficiencies in existing hdmi_codec_ops implementations. Only few of the
> > > > > > implementations were able to handle codec's 'plugged' callback. One
> > > > > > third of the drivers didn't implement the get_eld() callback.
> > > > > >
> > > > > > Most of the issues can be solved if drm_connector handles
> > > > > > hdmi-audio-codec on its own, delegating functionality to the actual
> > > > > > implementation, be it a driver that implements drm_connector or
> > > > > > drm_bridge.
> > > > > >
> > > > > > Implement such high-level framework, adding proper support for Audio
> > > > > > InfoFrame generation to the LT9611 driver.
> > > > > >
> > > > > > Several design decisions to be kept in mind:
> > > > > >
> > > > > > - drm_connector_hdmi_codec is kept as simple as possible. It implements
> > > > > >   generic functionality (ELD, hotplug, registration).
> > > > > >
> > > > > > - drm_hdmi_connector sets up HDMI codec device if the connector
> > > > > >   is setup correspondingly (either I2S or S/PDIF is marked as
> > > > > >   supported).
> > > > > >
> > > > > > - drm_bridge_connector provides a way to link HDMI audio codec
> > > > > >   funcionality in the drm_bridge with the drm_connector_hdmi_codec
> > > > > >   framework.
> > > > > >
> > > > > > - It might be worth reverting the no_i2s_capture / no_spdif_capture
> > > > > >   bits. Only TDA889x driver sets them, while it's safe to assume that
> > > > > >   most of HDMI / DP devices do not support ARC / capture. I think the
> > > > > >   drivers should opt-in capture support rather than having to opt-out of
> > > > > >   it.
> > > > >
> > > > > Sorry if this isn't clear to me and I'm quite late to the party, but did
> > > > > you test this on vc4 with both a pi3 and pi4, or was it just compile
> > > > > tested?
> > > >
> > > > LT9611 is actually tested, VC4 is only compile-tested. Should I put an RFT tag?
> > >
> > > Yeah, we definitely need to test it on the pi3 (polling-based) and the
> > > pi4 (irq-based) at least.
> > >
> > > Dave, Maira, could you give it a try?
> >
> > I'm on it.
> 
> Basic checks look OK.
> Pi3 and Pi4 tested, including 4k60 on Pi4 (enables scrambling). Audio
> works, and all the EDID parsing seems to be correct.
> 
> Ideally I would like to do a couple more tests though as I had a
> couple of spontaneous reboots on Pi4 whilst hotplugging.
> Most likely it was just grounding issues, as I can't think of an
> obvious way for the kernel to be triggering an automatic reboot. They
> seemed to go away when I had enabled drm.debug=0x14, but more likely
> I'd connected the serial port and therefore provided another ground.
> Please don't hold the patches waiting on me though - I don't know when
> I'll have time to do them.

Tested-by?

> 
> 
> Also unrelated to this patch set, I have noted I'm getting
> [   60.780897] WARNING: CPU: 3 PID: 501 at
> drivers/gpu/drm/vc4/vc4_hvs.c:743 __vc4_hvs_stop_channel+0x148/0x164
> [vc4]
> ...
> [   60.781192]  __vc4_hvs_stop_channel+0x148/0x164 [vc4] (P)
> [   60.781212]  __vc4_hvs_stop_channel+0x40/0x164 [vc4] (L)
> [   60.781230]  vc4_hvs_stop_channel+0x30/0x3c [vc4]
> [   60.781248]  vc4_crtc_disable+0x140/0x1e8 [vc4]
> [   60.781266]  vc4_crtc_atomic_disable+0x98/0xb8 [vc4]
> [   60.781284]  disable_outputs+0x22c/0x33c [drm_kms_helper]
> [   60.781326]  drm_atomic_helper_commit_modeset_disables+0x1c/0x4c
> [drm_kms_helper]
> [   60.781347]  vc4_atomic_commit_tail+0x10c/0x8e4 [vc4]
> [   60.781364]  commit_tail+0xa0/0x188 [drm_kms_helper]
> [   60.781385]  drm_atomic_helper_commit+0x16c/0x180 [drm_kms_helper]
> [   60.781406]  drm_atomic_commit+0x88/0xc4 [drm]
> [   60.781500]  drm_client_modeset_commit_atomic+0x204/0x264 [drm]
> [   60.781553]  drm_client_modeset_commit_locked+0x5c/0x198 [drm]
> [   60.781603]  drm_client_modeset_commit+0x30/0x58 [drm]
> [   60.781652]  __drm_fb_helper_restore_fbdev_mode_unlocked+0xb4/0xe8
> [drm_kms_helper]
> [   60.781674]  drm_fb_helper_hotplug_event+0x108/0x12c [drm_kms_helper]
> [   60.781695]  drm_fbdev_client_hotplug+0x28/0xd4 [drm_client_lib]
> [   60.781700]  drm_client_dev_hotplug+0xc8/0x12c [drm]
> [   60.781750]  drm_connector_helper_hpd_irq_event+0x70/0xb0 [drm_kms_helper]
> [   60.781771]  vc4_hdmi_hpd_irq_thread+0x2c/0x3c [vc4]
> [   60.781790]  irq_thread_fn+0x2c/0xa8
> [   60.781799]  irq_thread+0x16c/0x2f4
> [   60.781805]  kthread+0x118/0x11c
> [   60.781813]  ret_from_fork+0x10/0x20
> On first plugging or unplugging a second monitor. I suspect that is
> spurious though and I'll look into it, but probably not this side of
> the Christmas break.
> 
>   Dave

-- 
With best wishes
Dmitry


From seanjc at google.com  Thu Dec 19 17:39:01 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Dec 2024 17:39:01 -0800
Subject: [PATCH 3/8] KVM: selftests: Assert that __vm_get_stat() actually
 finds a stat
In-Reply-To: <20241220013906.3518334-1-seanjc@google.com>
References: <20241220013906.3518334-1-seanjc@google.com>
Message-ID: <20241220013906.3518334-4-seanjc@google.com>

Fail the test if it attempts to read a stat that doesn't exist, e.g. due
to a typo, or because the test tried to get a stat for the wrong scope.
As is, there's no indiciation of failure and @data is left untouched,
e.g. holds '0' or random stack data in most cases.

Fixes: 8448ec5993be ("KVM: selftests: Add NX huge pages test")
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/lib/kvm_util.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 9138801ecb60..21b5a6261106 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -2238,9 +2238,10 @@ void __vm_get_stat(struct kvm_vm *vm, const char *stat_name, uint64_t *data,
 
 		read_stat_data(vm->stats_fd, &vm->stats_header, desc,
 			       data, max_elements);
-
-		break;
+		return;
 	}
+
+	TEST_FAIL("Unabled to find stat '%s'", stat_name);
 }
 
 __weak void kvm_arch_vm_post_create(struct kvm_vm *vm)
-- 
2.47.1.613.gc27f4b7a9f-goog



From seanjc at google.com  Thu Dec 19 17:39:02 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Dec 2024 17:39:02 -0800
Subject: [PATCH 4/8] KVM: selftests: Macrofy vm_get_stat() to auto-generate
 stat name string
In-Reply-To: <20241220013906.3518334-1-seanjc@google.com>
References: <20241220013906.3518334-1-seanjc@google.com>
Message-ID: <20241220013906.3518334-5-seanjc@google.com>

Turn vm_get_stat() into a macro that generates a string for the stat name,
as opposed to taking a string.  This will allow hardening stat usage in
the future to generate errors on unknown stats at compile time.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/include/kvm_util.h     | 14 +++++++-------
 .../kvm/x86/dirty_log_page_splitting_test.c        |  6 +++---
 .../testing/selftests/kvm/x86/nx_huge_pages_test.c |  4 ++--
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 4c4e5a847f67..044c2231431e 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -534,13 +534,13 @@ void read_stat_data(int stats_fd, struct kvm_stats_header *header,
 void __vm_get_stat(struct kvm_vm *vm, const char *stat_name, uint64_t *data,
 		   size_t max_elements);
 
-static inline uint64_t vm_get_stat(struct kvm_vm *vm, const char *stat_name)
-{
-	uint64_t data;
-
-	__vm_get_stat(vm, stat_name, &data, 1);
-	return data;
-}
+#define vm_get_stat(vm, stat)				\
+({							\
+	uint64_t data;					\
+							\
+	__vm_get_stat(vm, #stat, &data, 1);		\
+	data;						\
+})
 
 void vm_create_irqchip(struct kvm_vm *vm);
 
diff --git a/tools/testing/selftests/kvm/x86/dirty_log_page_splitting_test.c b/tools/testing/selftests/kvm/x86/dirty_log_page_splitting_test.c
index 2929c067c207..b0d2b04a7ff2 100644
--- a/tools/testing/selftests/kvm/x86/dirty_log_page_splitting_test.c
+++ b/tools/testing/selftests/kvm/x86/dirty_log_page_splitting_test.c
@@ -41,9 +41,9 @@ struct kvm_page_stats {
 
 static void get_page_stats(struct kvm_vm *vm, struct kvm_page_stats *stats, const char *stage)
 {
-	stats->pages_4k = vm_get_stat(vm, "pages_4k");
-	stats->pages_2m = vm_get_stat(vm, "pages_2m");
-	stats->pages_1g = vm_get_stat(vm, "pages_1g");
+	stats->pages_4k = vm_get_stat(vm, pages_4k);
+	stats->pages_2m = vm_get_stat(vm, pages_2m);
+	stats->pages_1g = vm_get_stat(vm, pages_1g);
 	stats->hugepages = stats->pages_2m + stats->pages_1g;
 
 	pr_debug("\nPage stats after %s: 4K: %ld 2M: %ld 1G: %ld huge: %ld\n",
diff --git a/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
index e7efb2b35f8b..c0d84827f736 100644
--- a/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
+++ b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
@@ -73,7 +73,7 @@ static void check_2m_page_count(struct kvm_vm *vm, int expected_pages_2m)
 {
 	int actual_pages_2m;
 
-	actual_pages_2m = vm_get_stat(vm, "pages_2m");
+	actual_pages_2m = vm_get_stat(vm, pages_2m);
 
 	TEST_ASSERT(actual_pages_2m == expected_pages_2m,
 		    "Unexpected 2m page count. Expected %d, got %d",
@@ -84,7 +84,7 @@ static void check_split_count(struct kvm_vm *vm, int expected_splits)
 {
 	int actual_splits;
 
-	actual_splits = vm_get_stat(vm, "nx_lpage_splits");
+	actual_splits = vm_get_stat(vm, nx_lpage_splits);
 
 	TEST_ASSERT(actual_splits == expected_splits,
 		    "Unexpected NX huge page split count. Expected %d, got %d",
-- 
2.47.1.613.gc27f4b7a9f-goog



From seanjc at google.com  Thu Dec 19 17:39:03 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Dec 2024 17:39:03 -0800
Subject: [PATCH 5/8] KVM: selftests: Add struct and helpers to wrap binary
 stats cache
In-Reply-To: <20241220013906.3518334-1-seanjc@google.com>
References: <20241220013906.3518334-1-seanjc@google.com>
Message-ID: <20241220013906.3518334-6-seanjc@google.com>

Add a struct and helpers to manage the binary stats cache, which is
currently used only for VM-scoped stats.  This will allow expanding the
selftests infrastructure to provide support for vCPU-scoped binary stats,
which, except for the ioctl to get the stats FD are identical to VM-scoped
stats.

Defer converting __vm_get_stat() to a scope-agnostic helper to a future
patch, as getting the stats FD from KVM needs to be moved elsewhere
before it can be made completely scope-agnostic.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../testing/selftests/kvm/include/kvm_util.h  | 11 +++--
 tools/testing/selftests/kvm/lib/kvm_util.c    | 47 +++++++++++--------
 2 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 044c2231431e..9a64bab42f89 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -46,6 +46,12 @@ struct userspace_mem_region {
 	struct hlist_node slot_node;
 };
 
+struct kvm_binary_stats {
+	int fd;
+	struct kvm_stats_header header;
+	struct kvm_stats_desc *desc;
+};
+
 struct kvm_vcpu {
 	struct list_head list;
 	uint32_t id;
@@ -99,10 +105,7 @@ struct kvm_vm {
 
 	struct kvm_vm_arch arch;
 
-	/* Cache of information for binary stats interface */
-	int stats_fd;
-	struct kvm_stats_header stats_header;
-	struct kvm_stats_desc *stats_desc;
+	struct kvm_binary_stats stats;
 
 	/*
 	 * KVM region slots. These are the default memslots used by page
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 21b5a6261106..c88f5e7871f7 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -657,6 +657,20 @@ userspace_mem_region_find(struct kvm_vm *vm, uint64_t start, uint64_t end)
 	return NULL;
 }
 
+static void kvm_stats_release(struct kvm_binary_stats *stats)
+{
+	int ret;
+
+	if (!stats->desc)
+		return;
+
+	free(stats->desc);
+	stats->desc = NULL;
+
+	ret = close(stats->fd);
+	TEST_ASSERT(!ret,  __KVM_SYSCALL_ERROR("close()", ret));
+}
+
 __weak void vcpu_arch_free(struct kvm_vcpu *vcpu)
 {
 
@@ -711,13 +725,7 @@ void kvm_vm_release(struct kvm_vm *vmp)
 	TEST_ASSERT(!ret,  __KVM_SYSCALL_ERROR("close()", ret));
 
 	/* Free cached stats metadata and close FD */
-	if (vmp->stats_desc) {
-		free(vmp->stats_desc);
-		vmp->stats_desc = NULL;
-
-		ret = close(vmp->stats_fd);
-		TEST_ASSERT(!ret,  __KVM_SYSCALL_ERROR("close()", ret));
-	}
+	kvm_stats_release(&vmp->stats);
 }
 
 static void __vm_mem_region_delete(struct kvm_vm *vm,
@@ -2214,34 +2222,33 @@ void read_stat_data(int stats_fd, struct kvm_stats_header *header,
  *
  * Read the data values of a specified stat from the binary stats interface.
  */
-void __vm_get_stat(struct kvm_vm *vm, const char *stat_name, uint64_t *data,
+void __vm_get_stat(struct kvm_vm *vm, const char *name, uint64_t *data,
 		   size_t max_elements)
 {
+	struct kvm_binary_stats *stats = &vm->stats;
 	struct kvm_stats_desc *desc;
 	size_t size_desc;
 	int i;
 
-	if (!vm->stats_desc) {
-		vm->stats_fd = vm_get_stats_fd(vm);
-		read_stats_header(vm->stats_fd, &vm->stats_header);
-		vm->stats_desc = read_stats_descriptors(vm->stats_fd,
-							&vm->stats_header);
+	if (!stats->desc) {
+		stats->fd = vm_get_stats_fd(vm);
+		read_stats_header(stats->fd, &stats->header);
+		stats->desc = read_stats_descriptors(stats->fd, &stats->header);
 	}
 
-	size_desc = get_stats_descriptor_size(&vm->stats_header);
+	size_desc = get_stats_descriptor_size(&stats->header);
 
-	for (i = 0; i < vm->stats_header.num_desc; ++i) {
-		desc = (void *)vm->stats_desc + (i * size_desc);
+	for (i = 0; i < stats->header.num_desc; ++i) {
+		desc = (void *)stats->desc + (i * size_desc);
 
-		if (strcmp(desc->name, stat_name))
+		if (strcmp(desc->name, name))
 			continue;
 
-		read_stat_data(vm->stats_fd, &vm->stats_header, desc,
-			       data, max_elements);
+		read_stat_data(stats->fd, &stats->header, desc, data, max_elements);
 		return;
 	}
 
-	TEST_FAIL("Unabled to find stat '%s'", stat_name);
+	TEST_FAIL("Unabled to find stat '%s'", name);
 }
 
 __weak void kvm_arch_vm_post_create(struct kvm_vm *vm)
-- 
2.47.1.613.gc27f4b7a9f-goog



From seanjc at google.com  Thu Dec 19 17:39:04 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Dec 2024 17:39:04 -0800
Subject: [PATCH 6/8] KVM: selftests: Get VM's binary stats FD when opening VM
In-Reply-To: <20241220013906.3518334-1-seanjc@google.com>
References: <20241220013906.3518334-1-seanjc@google.com>
Message-ID: <20241220013906.3518334-7-seanjc@google.com>

Get and cache a VM's binary stats FD when the VM is opened, as opposed to
waiting until the stats are first used.  Opening the stats FD outside of
__vm_get_stat() will allow converting it to a scope-agnostic helper.

Note, this doesn't interfere with kvm_binary_stats_test's testcase that
verifies a stats FD can be used after its own VM's FD is closed, as the
cached FD is also closed during kvm_vm_free().

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/lib/kvm_util.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index c88f5e7871f7..16ee03e76d66 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -196,6 +196,11 @@ static void vm_open(struct kvm_vm *vm)
 
 	vm->fd = __kvm_ioctl(vm->kvm_fd, KVM_CREATE_VM, (void *)vm->type);
 	TEST_ASSERT(vm->fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm->fd));
+
+	if (kvm_has_cap(KVM_CAP_BINARY_STATS_FD))
+		vm->stats.fd = vm_get_stats_fd(vm);
+	else
+		vm->stats.fd = -1;
 }
 
 const char *vm_guest_mode_string(uint32_t i)
@@ -661,14 +666,17 @@ static void kvm_stats_release(struct kvm_binary_stats *stats)
 {
 	int ret;
 
-	if (!stats->desc)
+	if (stats->fd < 0)
 		return;
 
-	free(stats->desc);
-	stats->desc = NULL;
+	if (stats->desc) {
+		free(stats->desc);
+		stats->desc = NULL;
+	}
 
 	ret = close(stats->fd);
 	TEST_ASSERT(!ret,  __KVM_SYSCALL_ERROR("close()", ret));
+	stats->fd = -1;
 }
 
 __weak void vcpu_arch_free(struct kvm_vcpu *vcpu)
@@ -2231,7 +2239,6 @@ void __vm_get_stat(struct kvm_vm *vm, const char *name, uint64_t *data,
 	int i;
 
 	if (!stats->desc) {
-		stats->fd = vm_get_stats_fd(vm);
 		read_stats_header(stats->fd, &stats->header);
 		stats->desc = read_stats_descriptors(stats->fd, &stats->header);
 	}
-- 
2.47.1.613.gc27f4b7a9f-goog



From seanjc at google.com  Thu Dec 19 17:39:05 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Dec 2024 17:39:05 -0800
Subject: [PATCH 7/8] KVM: selftests: Add infrastructure for getting vCPU
 binary stats
In-Reply-To: <20241220013906.3518334-1-seanjc@google.com>
References: <20241220013906.3518334-1-seanjc@google.com>
Message-ID: <20241220013906.3518334-8-seanjc@google.com>

Now that the binary stats cache infrastructure is largely scope agnostic,
add support for vCPU-scoped stats.  Like VM stats, open and cache the
stats FD when the vCPU is created so that it's guaranteed to be valid when
vcpu_get_stats() is invoked.

To sanity check that the infrastructure actually works, and to get a bit
of bonus coverage, add an assert in x86's xapic_ipi_test to verify that
the number of HLTs executed by the test matches the number of HLT exits
observed by KVM.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../testing/selftests/kvm/include/kvm_util.h  | 20 +++++++++------
 tools/testing/selftests/kvm/lib/kvm_util.c    | 25 +++++++------------
 .../selftests/kvm/x86/xapic_ipi_test.c        |  2 ++
 3 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 9a64bab42f89..e0d23873158e 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -61,6 +61,7 @@ struct kvm_vcpu {
 #ifdef __x86_64__
 	struct kvm_cpuid2 *cpuid;
 #endif
+	struct kvm_binary_stats stats;
 	struct kvm_dirty_gfn *dirty_gfns;
 	uint32_t fetch_index;
 	uint32_t dirty_gfns_count;
@@ -534,17 +535,20 @@ void read_stat_data(int stats_fd, struct kvm_stats_header *header,
 		    struct kvm_stats_desc *desc, uint64_t *data,
 		    size_t max_elements);
 
-void __vm_get_stat(struct kvm_vm *vm, const char *stat_name, uint64_t *data,
-		   size_t max_elements);
+void kvm_get_stat(struct kvm_binary_stats *stats, const char *name,
+		  uint64_t *data, size_t max_elements);
 
-#define vm_get_stat(vm, stat)				\
-({							\
-	uint64_t data;					\
-							\
-	__vm_get_stat(vm, #stat, &data, 1);		\
-	data;						\
+#define __get_stat(stats, stat)							\
+({										\
+	uint64_t data;								\
+										\
+	kvm_get_stat(stats, #stat, &data, 1);					\
+	data;									\
 })
 
+#define vm_get_stat(vm, stat) __get_stat(&(vm)->stats, stat)
+#define vcpu_get_stat(vcpu, stat) __get_stat(&(vcpu)->stats, stat)
+
 void vm_create_irqchip(struct kvm_vm *vm);
 
 static inline int __vm_create_guest_memfd(struct kvm_vm *vm, uint64_t size,
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 16ee03e76d66..99fe8bcd2346 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -712,6 +712,8 @@ static void vm_vcpu_rm(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
 	ret = close(vcpu->fd);
 	TEST_ASSERT(!ret,  __KVM_SYSCALL_ERROR("close()", ret));
 
+	kvm_stats_release(&vcpu->stats);
+
 	list_del(&vcpu->list);
 
 	vcpu_arch_free(vcpu);
@@ -1305,6 +1307,11 @@ struct kvm_vcpu *__vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id)
 	TEST_ASSERT(vcpu->run != MAP_FAILED,
 		    __KVM_SYSCALL_ERROR("mmap()", (int)(unsigned long)MAP_FAILED));
 
+	if (kvm_has_cap(KVM_CAP_BINARY_STATS_FD))
+		vcpu->stats.fd = vcpu_get_stats_fd(vcpu);
+	else
+		vcpu->stats.fd = -1;
+
 	/* Add to linked-list of VCPUs. */
 	list_add(&vcpu->list, &vm->vcpus);
 
@@ -2217,23 +2224,9 @@ void read_stat_data(int stats_fd, struct kvm_stats_header *header,
 		    desc->name, size, ret);
 }
 
-/*
- * Read the data of the named stat
- *
- * Input Args:
- *   vm - the VM for which the stat should be read
- *   stat_name - the name of the stat to read
- *   max_elements - the maximum number of 8-byte values to read into data
- *
- * Output Args:
- *   data - the buffer into which stat data should be read
- *
- * Read the data values of a specified stat from the binary stats interface.
- */
-void __vm_get_stat(struct kvm_vm *vm, const char *name, uint64_t *data,
-		   size_t max_elements)
+void kvm_get_stat(struct kvm_binary_stats *stats, const char *name,
+		  uint64_t *data, size_t max_elements)
 {
-	struct kvm_binary_stats *stats = &vm->stats;
 	struct kvm_stats_desc *desc;
 	size_t size_desc;
 	int i;
diff --git a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
index a76078a08ff8..574a944763b7 100644
--- a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
+++ b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
@@ -465,6 +465,8 @@ int main(int argc, char *argv[])
 	cancel_join_vcpu_thread(threads[0], params[0].vcpu);
 	cancel_join_vcpu_thread(threads[1], params[1].vcpu);
 
+	TEST_ASSERT_EQ(data->hlt_count, vcpu_get_stat(params[0].vcpu, halt_exits));
+
 	fprintf(stderr,
 		"Test successful after running for %d seconds.\n"
 		"Sending vCPU sent %lu IPIs to halting vCPU\n"
-- 
2.47.1.613.gc27f4b7a9f-goog



From seanjc at google.com  Thu Dec 19 17:39:06 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Dec 2024 17:39:06 -0800
Subject: [PATCH 8/8] KVM: selftests: Add compile-time assertions to guard
 against stats typos
In-Reply-To: <20241220013906.3518334-1-seanjc@google.com>
References: <20241220013906.3518334-1-seanjc@google.com>
Message-ID: <20241220013906.3518334-9-seanjc@google.com>

Add compile-time assertions to the main binary stats accessor to verify
the stat is a known KVM stat of the appropriate scope, and "add" all
known stats for all architectures.

To build the set of known stats, define enums for each stat, with a
completely arbitrary magic value to specify the scope of the stat.  With
the assert in place, misuse of stat (or usage of a new stat) generates
error like so:

  In file included from include/x86/kvm_util_arch.h:8,
                   from include/kvm_util.h:23,
                   from x86/dirty_log_page_splitting_test.c:16:
   x86/dirty_log_page_splitting_test.c: In function ?get_page_stats?:
  include/kvm_util.h:563:42: error: ?VM_STAT_pages_4m? undeclared
    (first use in this function); did you mean ?VM_STAT_pages_2m??
    563 | #define vm_get_stat(vm, stat) __get_stat(VM, &(vm)->stats, stat)
        |                                          ^~

  ...
  x86/dirty_log_page_splitting_test.c:45:27: note: in expansion of macro ?vm_get_stat?
     45 |         stats->pages_2m = vm_get_stat(vm, pages_4m);
        |                           ^~~~~~~~~~~

Using pre-defined lists of stats doesn't completely eliminate human error,
e.g. it's obviously possible to make a typo when adding a state.  And
while there is also a non-zero cost to maintaining the set of stats,
adding stats in KVM is relatively uncommon, and removing stats is extremely
rare.  On the flip side, providing a list of known stats should make it
easier to use stats in test, at which point detecting goofs at compile-time
will also be more valuable.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../kvm/include/arm64/kvm_util_arch.h         |  12 ++
 .../testing/selftests/kvm/include/kvm_util.h  |  24 +++-
 .../selftests/kvm/include/kvm_util_types.h    |   6 +
 .../kvm/include/riscv/kvm_util_arch.h         |  14 +++
 .../kvm/include/s390/kvm_util_arch.h          | 113 ++++++++++++++++++
 .../selftests/kvm/include/x86/kvm_util_arch.h |  52 ++++++++
 6 files changed, 218 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/arm64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/arm64/kvm_util_arch.h
index e43a57d99b56..12097262f585 100644
--- a/tools/testing/selftests/kvm/include/arm64/kvm_util_arch.h
+++ b/tools/testing/selftests/kvm/include/arm64/kvm_util_arch.h
@@ -2,6 +2,18 @@
 #ifndef SELFTEST_KVM_UTIL_ARCH_H
 #define SELFTEST_KVM_UTIL_ARCH_H
 
+#include "kvm_util_types.h"
+
 struct kvm_vm_arch {};
 
+enum kvm_arm64_stats {
+	VCPU_STAT(hvc_exit_stat),
+	VCPU_STAT(wfe_exit_stat),
+	VCPU_STAT(wfi_exit_stat),
+	VCPU_STAT(mmio_exit_user),
+	VCPU_STAT(mmio_exit_kernel),
+	VCPU_STAT(signal_exits),
+	VCPU_STAT(exits),
+};
+
 #endif  // SELFTEST_KVM_UTIL_ARCH_H
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index e0d23873158e..f4f0e27cea27 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -535,19 +535,37 @@ void read_stat_data(int stats_fd, struct kvm_stats_header *header,
 		    struct kvm_stats_desc *desc, uint64_t *data,
 		    size_t max_elements);
 
+enum kvm_common_stats {
+	VM_STAT(remote_tlb_flush),
+	VM_STAT(remote_tlb_flush_requests),
+
+	VCPU_STAT(halt_successfull_poll),
+	VCPU_STAT(halt_attempted_poll),
+	VCPU_STAT(halt_poll_invalid),
+	VCPU_STAT(halt_wakeup),
+	VCPU_STAT(halt_poll_success_ns),
+	VCPU_STAT(halt_poll_fail_ns),
+	VCPU_STAT(halt_wait_ns),
+	VCPU_STAT(halt_poll_success_hist),
+	VCPU_STAT(halt_poll_fail_hist),
+	VCPU_STAT(halt_wait_hist),
+	VCPU_STAT(blocking),
+};
+
 void kvm_get_stat(struct kvm_binary_stats *stats, const char *name,
 		  uint64_t *data, size_t max_elements);
 
-#define __get_stat(stats, stat)							\
+#define __get_stat(type, stats, stat)						\
 ({										\
 	uint64_t data;								\
 										\
+	kvm_static_assert(type##_STAT_##stat == type##_STAT_MAGIC_NUMBER);	\
 	kvm_get_stat(stats, #stat, &data, 1);					\
 	data;									\
 })
 
-#define vm_get_stat(vm, stat) __get_stat(&(vm)->stats, stat)
-#define vcpu_get_stat(vcpu, stat) __get_stat(&(vcpu)->stats, stat)
+#define vm_get_stat(vm, stat) __get_stat(VM, &(vm)->stats, stat)
+#define vcpu_get_stat(vcpu, stat) __get_stat(VCPU, &(vcpu)->stats, stat)
 
 void vm_create_irqchip(struct kvm_vm *vm);
 
diff --git a/tools/testing/selftests/kvm/include/kvm_util_types.h b/tools/testing/selftests/kvm/include/kvm_util_types.h
index ec787b97cf18..20e6717a0d24 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_types.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_types.h
@@ -17,4 +17,10 @@
 typedef uint64_t vm_paddr_t; /* Virtual Machine (Guest) physical address */
 typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
 
+#define VM_STAT_MAGIC_NUMBER   1
+#define VM_STAT(stat)  VM_STAT_##stat = VM_STAT_MAGIC_NUMBER
+
+#define VCPU_STAT_MAGIC_NUMBER   2
+#define VCPU_STAT(stat) VCPU_STAT_##stat = VCPU_STAT_MAGIC_NUMBER
+
 #endif /* SELFTEST_KVM_UTIL_TYPES_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
index e43a57d99b56..ea53d6aeb693 100644
--- a/tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
+++ b/tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
@@ -2,6 +2,20 @@
 #ifndef SELFTEST_KVM_UTIL_ARCH_H
 #define SELFTEST_KVM_UTIL_ARCH_H
 
+#include "kvm_util_types.h"
+
 struct kvm_vm_arch {};
 
+enum kvm_riscv_stats {
+	VCPU_STAT(ecall_exit_stat),
+	VCPU_STAT(wfi_exit_stat),
+	VCPU_STAT(wrs_exit_stat),
+	VCPU_STAT(mmio_exit_user),
+	VCPU_STAT(mmio_exit_kernel),
+	VCPU_STAT(csr_exit_user),
+	VCPU_STAT(csr_exit_kernel),
+	VCPU_STAT(signal_exits),
+	VCPU_STAT(exits),
+};
+
 #endif  // SELFTEST_KVM_UTIL_ARCH_H
diff --git a/tools/testing/selftests/kvm/include/s390/kvm_util_arch.h b/tools/testing/selftests/kvm/include/s390/kvm_util_arch.h
index e43a57d99b56..64d4de333e09 100644
--- a/tools/testing/selftests/kvm/include/s390/kvm_util_arch.h
+++ b/tools/testing/selftests/kvm/include/s390/kvm_util_arch.h
@@ -2,6 +2,119 @@
 #ifndef SELFTEST_KVM_UTIL_ARCH_H
 #define SELFTEST_KVM_UTIL_ARCH_H
 
+#include "kvm_util_types.h"
+
 struct kvm_vm_arch {};
 
+enum kvm_s390_stats {
+	VM_STAT(inject_io),
+	VM_STAT(inject_float_mchk),
+	VM_STAT(inject_pfault_done),
+	VM_STAT(inject_service_signal),
+	VM_STAT(inject_virtio),
+	VM_STAT(aen_forward),
+	VM_STAT(gmap_shadow_reuse),
+	VM_STAT(gmap_shadow_create),
+	VM_STAT(gmap_shadow_r1_entry),
+	VM_STAT(gmap_shadow_r2_entry),
+	VM_STAT(gmap_shadow_r3_entry),
+	VM_STAT(gmap_shadow_sg_entry),
+	VM_STAT(gmap_shadow_pg_entry),
+
+	VCPU_STAT(exit_userspace),
+	VCPU_STAT(exit_null),
+	VCPU_STAT(exit_external_request),
+	VCPU_STAT(exit_io_request),
+	VCPU_STAT(exit_external_interrupt),
+	VCPU_STAT(exit_stop_request),
+	VCPU_STAT(exit_validity),
+	VCPU_STAT(exit_instruction),
+	VCPU_STAT(exit_pei),
+	VCPU_STAT(halt_no_poll_steal),
+	VCPU_STAT(instruction_lctl),
+	VCPU_STAT(instruction_lctlg),
+	VCPU_STAT(instruction_stctl),
+	VCPU_STAT(instruction_stctg),
+	VCPU_STAT(exit_program_interruption),
+	VCPU_STAT(exit_instr_and_program),
+	VCPU_STAT(exit_operation_exception),
+	VCPU_STAT(deliver_ckc),
+	VCPU_STAT(deliver_cputm),
+	VCPU_STAT(deliver_external_call),
+	VCPU_STAT(deliver_emergency_signal),
+	VCPU_STAT(deliver_service_signal),
+	VCPU_STAT(deliver_virtio),
+	VCPU_STAT(deliver_stop_signal),
+	VCPU_STAT(deliver_prefix_signal),
+	VCPU_STAT(deliver_restart_signal),
+	VCPU_STAT(deliver_program),
+	VCPU_STAT(deliver_io),
+	VCPU_STAT(deliver_machine_check),
+	VCPU_STAT(exit_wait_state),
+	VCPU_STAT(inject_ckc),
+	VCPU_STAT(inject_cputm),
+	VCPU_STAT(inject_external_call),
+	VCPU_STAT(inject_emergency_signal),
+	VCPU_STAT(inject_mchk),
+	VCPU_STAT(inject_pfault_init),
+	VCPU_STAT(inject_program),
+	VCPU_STAT(inject_restart),
+	VCPU_STAT(inject_set_prefix),
+	VCPU_STAT(inject_stop_signal),
+	VCPU_STAT(instruction_epsw),
+	VCPU_STAT(instruction_gs),
+	VCPU_STAT(instruction_io_other),
+	VCPU_STAT(instruction_lpsw),
+	VCPU_STAT(instruction_lpswe),
+	VCPU_STAT(instruction_lpswey),
+	VCPU_STAT(instruction_pfmf),
+	VCPU_STAT(instruction_ptff),
+	VCPU_STAT(instruction_sck),
+	VCPU_STAT(instruction_sckpf),
+	VCPU_STAT(instruction_stidp),
+	VCPU_STAT(instruction_spx),
+	VCPU_STAT(instruction_stpx),
+	VCPU_STAT(instruction_stap),
+	VCPU_STAT(instruction_iske),
+	VCPU_STAT(instruction_ri),
+	VCPU_STAT(instruction_rrbe),
+	VCPU_STAT(instruction_sske),
+	VCPU_STAT(instruction_ipte_interlock),
+	VCPU_STAT(instruction_stsi),
+	VCPU_STAT(instruction_stfl),
+	VCPU_STAT(instruction_tb),
+	VCPU_STAT(instruction_tpi),
+	VCPU_STAT(instruction_tprot),
+	VCPU_STAT(instruction_tsch),
+	VCPU_STAT(instruction_sie),
+	VCPU_STAT(instruction_essa),
+	VCPU_STAT(instruction_sthyi),
+	VCPU_STAT(instruction_sigp_sense),
+	VCPU_STAT(instruction_sigp_sense_running),
+	VCPU_STAT(instruction_sigp_external_call),
+	VCPU_STAT(instruction_sigp_emergency),
+	VCPU_STAT(instruction_sigp_cond_emergency),
+	VCPU_STAT(instruction_sigp_start),
+	VCPU_STAT(instruction_sigp_stop),
+	VCPU_STAT(instruction_sigp_stop_store_status),
+	VCPU_STAT(instruction_sigp_store_status),
+	VCPU_STAT(instruction_sigp_store_adtl_status),
+	VCPU_STAT(instruction_sigp_arch),
+	VCPU_STAT(instruction_sigp_prefix),
+	VCPU_STAT(instruction_sigp_restart),
+	VCPU_STAT(instruction_sigp_init_cpu_reset),
+	VCPU_STAT(instruction_sigp_cpu_reset),
+	VCPU_STAT(instruction_sigp_unknown),
+	VCPU_STAT(instruction_diagnose_10),
+	VCPU_STAT(instruction_diagnose_44),
+	VCPU_STAT(instruction_diagnose_9c),
+	VCPU_STAT(diag_9c_ignored),
+	VCPU_STAT(diag_9c_forward),
+	VCPU_STAT(instruction_diagnose_258),
+	VCPU_STAT(instruction_diagnose_308),
+	VCPU_STAT(instruction_diagnose_500),
+	VCPU_STAT(instruction_diagnose_other),
+	VCPU_STAT(pfault_sync),
+};
+
 #endif  // SELFTEST_KVM_UTIL_ARCH_H
diff --git a/tools/testing/selftests/kvm/include/x86/kvm_util_arch.h b/tools/testing/selftests/kvm/include/x86/kvm_util_arch.h
index 972bb1c4ab4c..f9c4aedddbd0 100644
--- a/tools/testing/selftests/kvm/include/x86/kvm_util_arch.h
+++ b/tools/testing/selftests/kvm/include/x86/kvm_util_arch.h
@@ -48,4 +48,56 @@ do {											\
 	}										\
 } while (0)
 
+enum kvm_x86_stats {
+	VM_STAT(mmu_shadow_zapped),
+	VM_STAT(mmu_pte_write),
+	VM_STAT(mmu_pde_zapped),
+	VM_STAT(mmu_flooded),
+	VM_STAT(mmu_recycled),
+	VM_STAT(mmu_cache_miss),
+	VM_STAT(mmu_unsync),
+	VM_STAT(pages_4k),
+	VM_STAT(pages_2m),
+	VM_STAT(pages_1g),
+	VM_STAT(pages),
+	VM_STAT(nx_lpage_splits),
+	VM_STAT(max_mmu_page_hash_collisions),
+	VM_STAT(max_mmu_rmap_size),
+
+	VCPU_STAT(pf_taken),
+	VCPU_STAT(pf_fixed),
+	VCPU_STAT(pf_emulate),
+	VCPU_STAT(pf_spurious),
+	VCPU_STAT(pf_fast),
+	VCPU_STAT(pf_mmio_spte_created),
+	VCPU_STAT(pf_guest),
+	VCPU_STAT(tlb_flush),
+	VCPU_STAT(invlpg),
+	VCPU_STAT(exits),
+	VCPU_STAT(io_exits),
+	VCPU_STAT(mmio_exits),
+	VCPU_STAT(signal_exits),
+	VCPU_STAT(irq_window_exits),
+	VCPU_STAT(nmi_window_exits),
+	VCPU_STAT(l1d_flush),
+	VCPU_STAT(halt_exits),
+	VCPU_STAT(request_irq_exits),
+	VCPU_STAT(irq_exits),
+	VCPU_STAT(host_state_reload),
+	VCPU_STAT(fpu_reload),
+	VCPU_STAT(insn_emulation),
+	VCPU_STAT(insn_emulation_fail),
+	VCPU_STAT(hypercalls),
+	VCPU_STAT(irq_injections),
+	VCPU_STAT(nmi_injections),
+	VCPU_STAT(req_event),
+	VCPU_STAT(nested_run),
+	VCPU_STAT(directed_yield_attempted),
+	VCPU_STAT(directed_yield_successful),
+	VCPU_STAT(preemption_reported),
+	VCPU_STAT(preemption_other),
+	VCPU_STAT(guest_mode),
+	VCPU_STAT(notify_window_exits),
+};
+
 #endif  // SELFTEST_KVM_UTIL_ARCH_H
-- 
2.47.1.613.gc27f4b7a9f-goog



From seanjc at google.com  Thu Dec 19 17:38:58 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Dec 2024 17:38:58 -0800
Subject: [PATCH 0/8] KVM: selftests: Binary stats fixes and infra updates
Message-ID: <20241220013906.3518334-1-seanjc@google.com>

Fix a handful of bugs in the binary stats infrastructure, expand support
to vCPU-scoped stats, enumerate all KVM stats in selftests, and use the
enumerated stats to assert at compile-time that {vm,vcpu}_get_stat() is
getting a stat that actually exists.

Most of the bugs are benign, and AFAICT, none actually cause problems in
the current code base.  The worst of the bugs is lack of validation that
the requested stat actually exists, which is quite annoying if someone
fat fingers a stat name, tries to get a vCPU stat on a VM FD, etc.

FWIW, I'm not entirely convinced enumerating all stats is worth doing in
selftests.  It seems nice to have?  But I don't know that it'll be worth
the maintenance cost.  It was easy enough to implement, so here it is...

Sean Christopherson (8):
  KVM: selftests: Fix mostly theoretical leak of VM's binary stats FD
  KVM: selftests: Close VM's binary stats FD when releasing VM
  KVM: selftests: Assert that __vm_get_stat() actually finds a stat
  KVM: selftests: Macrofy vm_get_stat() to auto-generate stat name
    string
  KVM: selftests: Add struct and helpers to wrap binary stats cache
  KVM: selftests: Get VM's binary stats FD when opening VM
  KVM: selftests: Add infrastructure for getting vCPU binary stats
  KVM: selftests: Add compile-time assertions to guard against stats
    typos

Sean Christopherson (8):
  KVM: selftests: Fix mostly theoretical leak of VM's binary stats FD
  KVM: selftests: Close VM's binary stats FD when releasing VM
  KVM: selftests: Assert that __vm_get_stat() actually finds a stat
  KVM: selftests: Macrofy vm_get_stat() to auto-generate stat name
    string
  KVM: selftests: Add struct and helpers to wrap binary stats cache
  KVM: selftests: Get VM's binary stats FD when opening VM
  KVM: selftests: Add infrastructure for getting vCPU binary stats
  KVM: selftests: Add compile-time assertions to guard against stats
    typos

 .../kvm/include/arm64/kvm_util_arch.h         |  12 ++
 .../testing/selftests/kvm/include/kvm_util.h  |  49 ++++++--
 .../selftests/kvm/include/kvm_util_types.h    |   6 +
 .../kvm/include/riscv/kvm_util_arch.h         |  14 +++
 .../kvm/include/s390/kvm_util_arch.h          | 113 ++++++++++++++++++
 .../selftests/kvm/include/x86/kvm_util_arch.h |  52 ++++++++
 tools/testing/selftests/kvm/lib/kvm_util.c    |  79 ++++++------
 .../kvm/x86/dirty_log_page_splitting_test.c   |   6 +-
 .../selftests/kvm/x86/nx_huge_pages_test.c    |   4 +-
 .../selftests/kvm/x86/xapic_ipi_test.c        |   2 +
 10 files changed, 286 insertions(+), 51 deletions(-)


base-commit: dcab55cef6f247a71a75a239d4063018dc83a671
-- 
2.47.1.613.gc27f4b7a9f-goog



From seanjc at google.com  Thu Dec 19 17:38:59 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Dec 2024 17:38:59 -0800
Subject: [PATCH 1/8] KVM: selftests: Fix mostly theoretical leak of VM's
 binary stats FD
In-Reply-To: <20241220013906.3518334-1-seanjc@google.com>
References: <20241220013906.3518334-1-seanjc@google.com>
Message-ID: <20241220013906.3518334-2-seanjc@google.com>

When allocating and freeing a VM's cached binary stats info, check for a
NULL descriptor, not a '0' file descriptor, as '0' is a legal FD.  E.g. in
the unlikely scenario the kernel installs the stats FD at entry '0',
selftests would reallocate on the next __vm_get_stat() and/or fail to free
the stats in kvm_vm_free().

Fixes: 83f6e109f562 ("KVM: selftests: Cache binary stats metadata for duration of test")
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/lib/kvm_util.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 33fefeb3ca44..91d295ef5d02 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -749,7 +749,7 @@ void kvm_vm_free(struct kvm_vm *vmp)
 		return;
 
 	/* Free cached stats metadata and close FD */
-	if (vmp->stats_fd) {
+	if (vmp->stats_desc) {
 		free(vmp->stats_desc);
 		close(vmp->stats_fd);
 	}
@@ -2218,7 +2218,7 @@ void __vm_get_stat(struct kvm_vm *vm, const char *stat_name, uint64_t *data,
 	size_t size_desc;
 	int i;
 
-	if (!vm->stats_fd) {
+	if (!vm->stats_desc) {
 		vm->stats_fd = vm_get_stats_fd(vm);
 		read_stats_header(vm->stats_fd, &vm->stats_header);
 		vm->stats_desc = read_stats_descriptors(vm->stats_fd,
-- 
2.47.1.613.gc27f4b7a9f-goog



From seanjc at google.com  Thu Dec 19 17:39:00 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Dec 2024 17:39:00 -0800
Subject: [PATCH 2/8] KVM: selftests: Close VM's binary stats FD when releasing VM
In-Reply-To: <20241220013906.3518334-1-seanjc@google.com>
References: <20241220013906.3518334-1-seanjc@google.com>
Message-ID: <20241220013906.3518334-3-seanjc@google.com>

Close/free a VM's binary stats cache when the VM is released, not when the
VM is fully freed.  When a VM is re-created, e.g. for state save/restore
tests, the stats FD and descriptor points at the old, defunct VM.  The FD
is still valid, in that the underlying stats file won't be freed until the
FD is closed, but reading stats will always pull information from the old
VM.

Note, this is a benign bug in the current code base as none of the tests
that recreate VMs use binary stats.

Fixes: 83f6e109f562 ("KVM: selftests: Cache binary stats metadata for duration of test")
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/lib/kvm_util.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 91d295ef5d02..9138801ecb60 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -709,6 +709,15 @@ void kvm_vm_release(struct kvm_vm *vmp)
 
 	ret = close(vmp->kvm_fd);
 	TEST_ASSERT(!ret,  __KVM_SYSCALL_ERROR("close()", ret));
+
+	/* Free cached stats metadata and close FD */
+	if (vmp->stats_desc) {
+		free(vmp->stats_desc);
+		vmp->stats_desc = NULL;
+
+		ret = close(vmp->stats_fd);
+		TEST_ASSERT(!ret,  __KVM_SYSCALL_ERROR("close()", ret));
+	}
 }
 
 static void __vm_mem_region_delete(struct kvm_vm *vm,
@@ -748,12 +757,6 @@ void kvm_vm_free(struct kvm_vm *vmp)
 	if (vmp == NULL)
 		return;
 
-	/* Free cached stats metadata and close FD */
-	if (vmp->stats_desc) {
-		free(vmp->stats_desc);
-		close(vmp->stats_fd);
-	}
-
 	/* Free userspace_mem_regions. */
 	hash_for_each_safe(vmp->regions.slot_hash, ctr, node, region, slot_node)
 		__vm_mem_region_delete(vmp, region);
-- 
2.47.1.613.gc27f4b7a9f-goog



From damon.ding at rock-chips.com  Thu Dec 19 17:46:24 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Fri, 20 Dec 2024 09:46:24 +0800
Subject: [PATCH v3 04/15] phy: phy-rockchip-samsung-hdptx: Rename some
 register names related to DP
In-Reply-To: <rkdp44csph6stq2e7emhgjziiwypcas7uqsvcdo7i6ypvg64uz@gnqikl5fzxqd>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-5-damon.ding@rock-chips.com>
 <rkdp44csph6stq2e7emhgjziiwypcas7uqsvcdo7i6ypvg64uz@gnqikl5fzxqd>
Message-ID: <20d95d18-ddbc-423e-ab15-d246dc605527@rock-chips.com>

Hi Dmitry,

On 2024/12/20 8:22, Dmitry Baryshkov wrote:
> On Thu, Dec 19, 2024 at 04:05:53PM +0800, Damon Ding wrote:
>> The modifications of DP register names are as follows:
>> - Add the '_MASK' suffix to some registers to ensure consistency.
>> - Complete the names of some register to their full names.
>> - Swap the definitions of LCPLL_REF and ROPLL_REF.
> 
> Three unrelated changes, ideally means three commits (I won't insist on
> that though). Also please mention that LCPLL_REF and ROPLL_REF were not
> used by the existing driver, so it's not a bug and there is no need to
> backport it.
> 

Indeed, it would be better to split this patch into three different 
commits. However, I still want to keep the fixes for LCPLL_REF and 
ROPLL_REF because, according to the datasheet, they are indeed 
incorrect. And I will describe the suggestions you mentioned in the 
commit message.

>>
>> Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver")
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>> ---
>>   .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 64 +++++++++----------
>>   1 file changed, 32 insertions(+), 32 deletions(-)
>>
>> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> index ceab9c71d3b5..c1b9c73f5f9f 100644
>> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> @@ -69,41 +69,41 @@
>>   #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)
>> +#define ROPLL_SDC_FRAC_EN_RBR_MASK	BIT(3)
>> +#define ROPLL_SDC_FRAC_EN_HBR_MASK	BIT(2)
>> +#define ROPLL_SDC_FRAC_EN_HBR2_MASK	BIT(1)
>> +#define ROPLL_SDM_FRAC_EN_HBR3_MASK	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)
>> +#define ROPLL_SDC_NDIV_RSTN_MASK	BIT(2)
>> +#define ROPLL_SSC_EN_MASK		BIT(0)
>>   /* CMN_REG(0081) */
>> -#define OVRD_PLL_CD_CLK_EN		BIT(8)
>> -#define PLL_CD_HSCLK_EAST_EN		BIT(0)
>> +#define OVRD_PLL_CD_CLK_EN_MASK		BIT(8)
>> +#define ANA_PLL_CD_HSCLK_EAST_EN_MASK	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)
>> +#define ANA_PLL_FRL_MODE_EN_MASK	BIT(3)
>> +#define ANA_PLL_TX_HS_CLK_EN_MASK	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
>> +#define DIG_CLK_SEL_MASK		BIT(1)
>> +#define LCPLL_REF			BIT(1)
>> +#define ROPLL_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 HS_SPEED_SEL_MASK		BIT(0)
>>   #define DIV_10_CLOCK			BIT(0)
>>   /* CMN_REG(009b) */
>> -#define IS_SPEED_SEL			BIT(4)
>> +#define LS_SPEED_SEL_MASK		BIT(4)
>>   #define LINK_SYMBOL_CLOCK		BIT(4)
>>   #define LINK_SYMBOL_CLOCK1_2		0
>>   
>> @@ -165,32 +165,32 @@
>>   #define HDMI_MODE			BIT(2)
>>   #define HDMI_TMDS_FRL_SEL		BIT(1)
>>   /* LNTOP_REG(0206) */
>> -#define DATA_BUS_SEL			BIT(0)
>> +#define DATA_BUS_WIDTH_SEL_MASK		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)
>> +#define LN0_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
>> +#define LN0_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
>> +#define LN0_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
>> +#define LN0_TX_SER_RATE_SEL_HBR3_MASK	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)
>> +#define LN1_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
>> +#define LN1_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
>> +#define LN1_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
>> +#define LN1_TX_SER_RATE_SEL_HBR3_MASK	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)
>> +#define LN2_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
>> +#define LN2_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
>> +#define LN2_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
>> +#define LN2_TX_SER_RATE_SEL_HBR3_MASK	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)
>> +#define LN3_TX_SER_RATE_SEL_RBR_MASK	BIT(5)
>> +#define LN3_TX_SER_RATE_SEL_HBR_MASK	BIT(4)
>> +#define LN3_TX_SER_RATE_SEL_HBR2_MASK	BIT(3)
>> +#define LN3_TX_SER_RATE_SEL_HBR3_MASK	BIT(2)
>>   
>>   #define HDMI20_MAX_RATE			600000000
>>   
>> -- 
>> 2.34.1
>>
> 

Best regards,
Damon


From shengjiu.wang at gmail.com  Thu Dec 19 17:59:44 2024
From: shengjiu.wang at gmail.com (Shengjiu Wang)
Date: Fri, 20 Dec 2024 09:59:44 +0800
Subject: [PATCH] clk: clk-imx8mp-audiomix: fix function signature
In-Reply-To: <20241219105447.889CB11FE@mail.steuer-voss.de>
References: <20241219105447.889CB11FE@mail.steuer-voss.de>
Message-ID: <CAA+D8AMO+ia5ztD8Z97TOn-NBbXKHfd+T65zBc6vJuNkeVdVhQ@mail.gmail.com>

On Thu, Dec 19, 2024 at 6:55?PM Nikolaus Voss <nv at vosn.de> wrote:
>
> clk_imx8mp_audiomix_reset_controller_register() in the
> "if !CONFIG_RESET_CONTROLLER" branch had the first
> argument missing. It is an empty function for this branch
> so it wasn't immediately apparent.
>
> Fixes: 6f0e817175c5 ("clk: imx: clk-audiomix: Add reset controller")
> Cc: <stable at vger.kernel.org> # 6.12.x
> Signed-off-by: Nikolaus Voss <nv at vosn.de>

Acked-by: Shengjiu Wang <shengjiu.wang at gmail.com>

Best regards
Shengjiu Wang
> ---
>  drivers/clk/imx/clk-imx8mp-audiomix.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/imx/clk-imx8mp-audiomix.c b/drivers/clk/imx/clk-imx8mp-audiomix.c
> index b2cb157703c57..c409fc7e06186 100644
> --- a/drivers/clk/imx/clk-imx8mp-audiomix.c
> +++ b/drivers/clk/imx/clk-imx8mp-audiomix.c
> @@ -278,7 +278,8 @@ static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev,
>
>  #else /* !CONFIG_RESET_CONTROLLER */
>
> -static int clk_imx8mp_audiomix_reset_controller_register(struct clk_imx8mp_audiomix_priv *priv)
> +static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev,
> +                                                        struct clk_imx8mp_audiomix_priv *priv)
>  {
>         return 0;
>  }
> --
> 2.43.0
>
>


From dmitry.baryshkov at linaro.org  Thu Dec 19 18:01:14 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 04:01:14 +0200
Subject: [PATCH v3 04/15] phy: phy-rockchip-samsung-hdptx: Rename some
 register names related to DP
In-Reply-To: <20d95d18-ddbc-423e-ab15-d246dc605527@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-5-damon.ding@rock-chips.com>
 <rkdp44csph6stq2e7emhgjziiwypcas7uqsvcdo7i6ypvg64uz@gnqikl5fzxqd>
 <20d95d18-ddbc-423e-ab15-d246dc605527@rock-chips.com>
Message-ID: <pb5ds6pyugndyfttqeyy2czumaltagbuns5zfclvqpwcp5gdez@tfsgukr6irzh>

On Fri, Dec 20, 2024 at 09:46:24AM +0800, Damon Ding wrote:
> Hi Dmitry,
> 
> On 2024/12/20 8:22, Dmitry Baryshkov wrote:
> > On Thu, Dec 19, 2024 at 04:05:53PM +0800, Damon Ding wrote:
> > > The modifications of DP register names are as follows:
> > > - Add the '_MASK' suffix to some registers to ensure consistency.
> > > - Complete the names of some register to their full names.
> > > - Swap the definitions of LCPLL_REF and ROPLL_REF.
> > 
> > Three unrelated changes, ideally means three commits (I won't insist on
> > that though). Also please mention that LCPLL_REF and ROPLL_REF were not
> > used by the existing driver, so it's not a bug and there is no need to
> > backport it.
> > 
> 
> Indeed, it would be better to split this patch into three different commits.
> However, I still want to keep the fixes for LCPLL_REF and ROPLL_REF because,
> according to the datasheet, they are indeed incorrect. And I will describe
> the suggestions you mentioned in the commit message.

I meant that the issue with those defines doesn't affect existing code,
so there is no need for Fixes:, etc.


-- 
With best wishes
Dmitry


From fj5100bi at fujitsu.com  Thu Dec 19 18:26:57 2024
From: fj5100bi at fujitsu.com (Yoshihiro Furudera (Fujitsu))
Date: Fri, 20 Dec 2024 02:26:57 +0000
Subject: [PATCH v2 1/2] perf: Fujitsu: Add the Uncore MAC PMU driver
In-Reply-To: <OS3PR01MB69035A6B5F695F039B5D77C3D4062@OS3PR01MB6903.jpnprd01.prod.outlook.com>
References: <20241122061753.2598688-1-fj5100bi@fujitsu.com>
	<20241122061753.2598688-2-fj5100bi@fujitsu.com>
 <20241211113909.000039d0@huawei.com>
 <OS3PR01MB69035A6B5F695F039B5D77C3D4062@OS3PR01MB6903.jpnprd01.prod.outlook.com>
Message-ID: <OS3PR01MB690361C2E315CF9D1E6C7CBDD4072@OS3PR01MB6903.jpnprd01.prod.outlook.com>

Hi, Jonathan

> > > diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> > > index a04b73c40173..21006d1cda59 100644
> > > --- a/include/linux/cpuhotplug.h
> > > +++ b/include/linux/cpuhotplug.h
> > > @@ -228,6 +228,7 @@ enum cpuhp_state {
> > >  	CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE,
> > >  	CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
> > >  	CPUHP_AP_PERF_ARM_MRVL_PEM_ONLINE,
> > > +	CPUHP_AP_PERF_ARM_FUJITSU_MAC_ONLINE,
> >
> > If the DYN option works for you, I think we should go with that.
> > Some more recent PMU drivers are already using it without problem.
> 
> I will try to do as you suggested, but I'll check it first.

After checking, we found that the Uncore MAC/PCI PMU driver's
CPU hotplug callback function has no dependency on other callback functions,
so we changed it to the DYN option.

Best Regards,
Yoshihiro Furudera

From damon.ding at rock-chips.com  Thu Dec 19 18:38:48 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Fri, 20 Dec 2024 10:38:48 +0800
Subject: [PATCH v3 14/15] arm64: dts: rockchip: Enable eDP0 display on
 RK3588S EVB1 board
In-Reply-To: <cg7bnhol4gvzji7agxazas7nkxy7zammzy67rjvhp35yqyraju@73daepsbmuae>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-15-damon.ding@rock-chips.com>
 <cg7bnhol4gvzji7agxazas7nkxy7zammzy67rjvhp35yqyraju@73daepsbmuae>
Message-ID: <d2b47813-45fa-4148-8a4a-6cf4a18ee7ca@rock-chips.com>

Hi Dmitry,

On 2024/12/20 8:20, Dmitry Baryshkov wrote:
> On Thu, Dec 19, 2024 at 04:06:03PM +0800, Damon Ding wrote:
>> Add the necessary DT changes to enable eDP0 on RK3588S EVB1 board:
>> - Add edp-panel node
>> - Set pinctrl of pwm12 for backlight
>> - Enable edp0/hdptxphy0/vp2
>>
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>>
>> ---
>>
>> Changes in v2:
>> - Remove brightness-levels and default-brightness-level properties in
>>    backlight node.
>> - Add the detail DT changes to commit message.
>>
>> Changes in v3:
>> - Use aux-bus instead of platform bus for edp-panel.
>> ---
>>   .../boot/dts/rockchip/rk3588s-evb1-v10.dts    | 52 +++++++++++++++++++
>>   1 file changed, 52 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
>> index bc4077575beb..9547ab18e596 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
>> @@ -9,6 +9,7 @@
>>   #include <dt-bindings/gpio/gpio.h>
>>   #include <dt-bindings/input/input.h>
>>   #include <dt-bindings/pinctrl/rockchip.h>
>> +#include <dt-bindings/soc/rockchip,vop2.h>
>>   #include <dt-bindings/usb/pd.h>
>>   #include "rk3588s.dtsi"
>>   
>> @@ -238,6 +239,41 @@ &combphy2_psu {
>>   	status = "okay";
>>   };
>>   
>> +&edp0 {
>> +	force-hpd;
>> +	status = "okay";
>> +
>> +	aux-bus {
>> +		panel {
>> +			compatible = "lg,lp079qx1-sp0v";
> 
> Why do you need the particular compat string here? Can you use the
> generic "edp-panel" instead? What if the user swaps the panel?
> 

The eDP panels used in conjunction with the RK3588S EVB1 have broken 
identification, which is one of the valid reasons for using a particular 
compat string. So the generic_edp_panel_probe() can not return success 
when using the "edp-panel".

>> +			backlight = <&backlight>;
>> +			power-supply = <&vcc3v3_lcd_edp>;
>> +
>> +			port {
>> +				panel_in_edp: endpoint {
>> +					remote-endpoint = <&edp_out_panel>;
>> +				};
>> +			};
>> +		};
>> +	};
>> +};
>> +
>> +&edp0_in {
>> +	edp0_in_vp2: endpoint {
>> +		remote-endpoint = <&vp2_out_edp0>;
>> +	};
>> +};
>> +
>> +&edp0_out {
>> +	edp_out_panel: endpoint {
>> +		remote-endpoint = <&panel_in_edp>;
>> +	};
>> +};
>> +
>> +&hdptxphy0 {
>> +	status = "okay";
>> +};
>> +
>>   &i2c3 {
>>   	status = "okay";
>>   
>> @@ -399,6 +435,7 @@ usbc0_int: usbc0-int {
>>   };
>>   
>>   &pwm12 {
>> +	pinctrl-0 = <&pwm12m1_pins>;
>>   	status = "okay";
>>   };
>>   
>> @@ -1168,3 +1205,18 @@ usbdp_phy0_dp_altmode_mux: endpoint at 1 {
>>   		};
>>   	};
>>   };
>> +
>> +&vop_mmu {
>> +	status = "okay";
>> +};
>> +
>> +&vop {
>> +	status = "okay";
>> +};
>> +
>> +&vp2 {
>> +	vp2_out_edp0: endpoint at ROCKCHIP_VOP2_EP_EDP0 {
>> +		reg = <ROCKCHIP_VOP2_EP_EDP0>;
>> +		remote-endpoint = <&edp0_in_vp2>;
>> +	};
>> +};
>> -- 
>> 2.34.1
>>
> 
Best regards,
Damon


From carlos.song at nxp.com  Thu Dec 19 18:45:09 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Fri, 20 Dec 2024 02:45:09 +0000
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <Z2QQI2gJNLjI-fam@pengutronix.de>
References: <20241218043541.143194-1-carlos.song@nxp.com>
 <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
Message-ID: <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Oleksij Rempel <o.rempel at pengutronix.de>
> Sent: Thursday, December 19, 2024 8:23 PM
> To: Andi Shyti <andi.shyti at kernel.org>
> Cc: Carlos Song <carlos.song at nxp.com>; Frank Li <frank.li at nxp.com>;
> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Clark Wang
> <xiaoning.wang at nxp.com>; Ahmad Fatoum <a.fatoum at pengutronix.de>
> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
>
> 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, Dec 19, 2024 at 01:02:29PM +0100, Andi Shyti wrote:
> > Hi Carlos,
> >
> > > +   /*
> > > +    * Init DMA config if supported, -ENODEV means DMA not enabled at
> > > +    * this platform, that is not a real error, so just remind "only
> > > +    * PIO mode is used". If DMA is enabled, but meet error when request
> > > +    * DMA channel, error should be showed in probe error log. PIO mode
> > > +    * should be available regardless of DMA.
> > > +    */
> > > +   ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> > > +   if (ret) {
> > > +           if (ret == -EPROBE_DEFER)
> > > +                   goto clk_notifier_unregister;
> > > +           else if (ret == -ENODEV)
> > > +                   dev_dbg(&pdev->dev, "Only use PIO mode\n");
> > > +           else
> > > +                   dev_err_probe(&pdev->dev, ret, "Failed to setup
> > > + DMA, only use PIO mode\n");
> >
> > Just for understanding, should we quit in this last case, as well?
> >
> > Before we were ignoring ENODEV and EPROBE_DEFER, but now you are
> > making it clear that other failures like ENOMEM might happen.
>
> Good point, dev_err_probe() would not print an error in case of EPROBE_DEFER,
> but in this case we should only print error and continue with PIO.
>
Hi,

Thank you all very much! As I comment at previous mail:
DMA mode should be optional for i2c-imx, because i2c-imx can accept DMA mode not enabled, because it still can work in CPU mode.[1]
[1]https://lore.kernel.org/imx/AM0PR0402MB39374E34FD6133B5E3D414D7E82F2 at AM0PR0402MB3937.eurprd04.prod.outlook.com/

Also we don't want to annoy current user without DMA[2]
[2] https://lore.kernel.org/imx/20241127-analytic-azure-hamster-727fd8-mkl at pengutronix.de/

So we make this logic. Anyway we let the I2C controller registered whether DMA is available or not(except defer probe).
Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing happened if DMA is defer probed or not enabled(This is an expected).
However we still need i2c DMA status is known when meet an unexpected error, so we use dev_err_probe() to print error.

> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7Cf0f2b14d05e4
> 4bb9581408dd2027ef82%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%
> 7C638702078063818207%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiO
> nRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%
> 3D%3D%7C0%7C%7C%7C&sdata=q355QWfiCHuoREtM4pkuovpn%2F6MeXynD
> hrpSEpWeCXk%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |



From damon.ding at rock-chips.com  Thu Dec 19 18:48:58 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Fri, 20 Dec 2024 10:48:58 +0800
Subject: [PATCH v3 10/15] dt-bindings: display: rockchip: analogix-dp: Add
 support to get panel from the DP AUX bus
In-Reply-To: <bjkcue3dfgaf5i66cqbiczifo7r3xngupghklxgevwqpwfeeix@i2jfd477igri>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-11-damon.ding@rock-chips.com>
 <bjkcue3dfgaf5i66cqbiczifo7r3xngupghklxgevwqpwfeeix@i2jfd477igri>
Message-ID: <c06381b7-1e38-4af4-9873-15862e91937d@rock-chips.com>

Hi Dmitry,

On 2024/12/20 8:18, Dmitry Baryshkov wrote:
> On Thu, Dec 19, 2024 at 04:05:59PM +0800, Damon Ding wrote:
>> According to Documentation/devicetree/bindings/display/dp-aux-bus.yaml,
>> it is a good way to get panel through the DP AUX bus.
>>
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>> ---
>>   .../bindings/display/rockchip/rockchip,analogix-dp.yaml        | 3 +++
>>   1 file changed, 3 insertions(+)
> 
> Business before pleasure.^W^W^W Bindings before the driver.

I couldn't agree more. ;-)

> 
>>
>> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> index 4f84e8849876..c45d92a2d901 100644
>> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> @@ -49,6 +49,9 @@ properties:
>>       description:
>>         This SoC makes use of GRF regs.
>>   
>> +  aux-bus:
>> +    $ref: /schemas/display/dp-aux-bus.yaml#
>> +
>>   required:
>>     - compatible
>>     - clocks
>> -- 
>> 2.34.1
>>
> 

Best regards,
Damon


From ck.hu at mediatek.com  Thu Dec 19 18:49:37 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 02:49:37 +0000
Subject: [PATCH v3 12/33] drm/mediatek: hdmi: Use regmap instead of iomem
 for main registers
In-Reply-To: <20241217154345.276919-13-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-13-angelogioacchino.delregno@collabora.com>
Message-ID: <292899cc3420242629305be95225a28713849e00.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> From: Guillaume Ranquet <granquet at baylibre.com>
> 
> In preparation for the addition of a new version of the HDMI IP
> which will need to share its iospace between multiple subdrivers,
> and in preparation for moving out the common bits between the two,
> migrate this driver to fully use regmap.

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

> 
> Signed-off-by: Guillaume Ranquet <granquet at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---


From ck.hu at mediatek.com  Thu Dec 19 18:51:41 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 02:51:41 +0000
Subject: [PATCH v3 13/33] drm/mediatek: mtk_hdmi: Fix typo for
 aud_sampe_size member
In-Reply-To: <20241217154345.276919-14-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-14-angelogioacchino.delregno@collabora.com>
Message-ID: <37b5aac8e889ced47af3388e1439050c53149de9.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Rename member aud_sampe_size of struct hdmi_audio_param to
> aud_sample_size to fix a typo and enhance readability.
> 
> This commit brings no functional changes.

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

> 
> Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---


From patchwork-bot+netdevbpf at kernel.org  Thu Dec 19 19:30:35 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 20 Dec 2024 03:30:35 +0000
Subject: [PATCH net-next v1] net: stmmac: Drop useless code related to ethtool
 rx-copybreak
In-Reply-To: <20241218083407.390509-1-0x1207@gmail.com>
References: <20241218083407.390509-1-0x1207@gmail.com>
Message-ID: <173466543521.2462446.17820764757552771854.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Wed, 18 Dec 2024 16:34:07 +0800 you wrote:
> After commit 2af6106ae949 ("net: stmmac: Introducing support for Page
> Pool"), the driver always copies frames to get a better performance,
> zero-copy for RX frames is no more, then these code turned to be
> useless and users of ethtool may get confused about the unhandled
> rx-copybreak parameter.
> 
> This patch mostly reverts
> commit 22ad38381547 ("stmmac: do not perform zero-copy for rx frames")
> 
> [...]

Here is the summary with links:
  - [net-next,v1] net: stmmac: Drop useless code related to ethtool rx-copybreak
    https://git.kernel.org/netdev/net-next/c/5c98e89d96ec

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+netdevbpf at kernel.org  Thu Dec 19 19:30:39 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 20 Dec 2024 03:30:39 +0000
Subject: [PATCH net-next v2] net: airoha: Fix error path in airoha_probe()
In-Reply-To: <20241216-airoha_probe-error-path-fix-v2-1-6b10e04e9a5c@kernel.org>
References: <20241216-airoha_probe-error-path-fix-v2-1-6b10e04e9a5c@kernel.org>
Message-ID: <173466543949.2462446.3986917315473515090.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Mon, 16 Dec 2024 18:47:33 +0100 you wrote:
> Do not run napi_disable() if airoha_hw_init() fails since Tx/Rx napi
> has not been started yet. In order to fix the issue, introduce
> airoha_qdma_stop_napi routine and remove napi_disable in
> airoha_hw_cleanup().
> 
> Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
> Reviewed-by: Michal Swiatkowski <michal.swiatkowski at linux.intel.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
> 
> [...]

Here is the summary with links:
  - [net-next,v2] net: airoha: Fix error path in airoha_probe()
    https://git.kernel.org/netdev/net-next/c/0c7469ee718e

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From damon.ding at rock-chips.com  Thu Dec 19 19:37:43 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Fri, 20 Dec 2024 11:37:43 +0800
Subject: [PATCH v3 07/15] drm/bridge: analogix_dp: Add support for phy
 configuration.
In-Reply-To: <a6vvydjbx3hbckoy74iiyzguyyacwvdh6iirqydjfvhwgocw3a@knecggjcbcid>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-8-damon.ding@rock-chips.com>
 <a6vvydjbx3hbckoy74iiyzguyyacwvdh6iirqydjfvhwgocw3a@knecggjcbcid>
Message-ID: <654c30ec-7d7e-4956-9a48-15bfcea34acc@rock-chips.com>

Hi Dmitry,

On 2024/12/20 8:13, Dmitry Baryshkov wrote:
> On Thu, Dec 19, 2024 at 04:05:56PM +0800, Damon Ding wrote:
>> Add support to configurate link rate, lane count, voltage swing and
>> pre-emphasis with phy_configure(). It is helpful in application scenarios
>> where analogix controller is mixed with the phy of other vendors.
>>
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>>
>> ---
>>
>> Changes in v2:
>> - remove needless assignments for phy_configure()
>> - remove unnecessary changes for phy_power_on()/phy_power_off()
>> ---
>>   .../drm/bridge/analogix/analogix_dp_core.c    |  1 +
>>   .../gpu/drm/bridge/analogix/analogix_dp_reg.c | 56 +++++++++++++++++++
>>   2 files changed, 57 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> index 6f10d88a34c5..9429c50cc1bc 100644
>> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> @@ -1696,6 +1696,7 @@ int analogix_dp_resume(struct analogix_dp_device *dp)
>>   	if (dp->plat_data->power_on)
>>   		dp->plat_data->power_on(dp->plat_data);
>>   
>> +	phy_set_mode(dp->phy, PHY_MODE_DP);
>>   	phy_power_on(dp->phy);
>>   
>>   	analogix_dp_init_dp(dp);
>> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
>> index 3afc73c858c4..613ce504bea6 100644
>> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
>> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
>> @@ -11,6 +11,7 @@
>>   #include <linux/gpio/consumer.h>
>>   #include <linux/io.h>
>>   #include <linux/iopoll.h>
>> +#include <linux/phy/phy.h>
>>   
>>   #include <drm/bridge/analogix_dp.h>
>>   
>> @@ -513,10 +514,25 @@ void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
>>   void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
>>   {
>>   	u32 reg;
>> +	int ret;
>>   
>>   	reg = bwtype;
>>   	if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
>>   		writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
>> +
>> +	if (dp->phy) {
>> +		union phy_configure_opts phy_cfg = {0};
>> +
>> +		phy_cfg.dp.lanes = dp->link_train.lane_count;
> 
> Should not be necessary, you are only setting the .set_rate.

Indeed, this can be dropped.

> 
>> +		phy_cfg.dp.link_rate =
>> +			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
>> +		phy_cfg.dp.set_rate = true;
>> +		ret = phy_configure(dp->phy, &phy_cfg);
>> +		if (ret && ret != -EOPNOTSUPP) {
>> +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
>> +			return;
>> +		}
>> +	}
>>   }
>>   
>>   void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
>> @@ -530,9 +546,22 @@ void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
>>   void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
>>   {
>>   	u32 reg;
>> +	int ret;
>>   
>>   	reg = count;
>>   	writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
>> +
>> +	if (dp->phy) {
>> +		union phy_configure_opts phy_cfg = {0};
>> +
>> +		phy_cfg.dp.lanes = dp->link_train.lane_count;
>> +		phy_cfg.dp.set_lanes = true;
>> +		ret = phy_configure(dp->phy, &phy_cfg);
>> +		if (ret && ret != -EOPNOTSUPP) {
>> +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
>> +			return;
>> +		}
>> +	}
>>   }
>>   
>>   void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
>> @@ -546,10 +575,37 @@ void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
>>   void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp)
>>   {
>>   	u8 lane;
>> +	int ret;
>>   
>>   	for (lane = 0; lane < dp->link_train.lane_count; lane++)
>>   		writel(dp->link_train.training_lane[lane],
>>   		       dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane);
>> +
>> +	if (dp->phy) {
>> +		union phy_configure_opts phy_cfg = {0};
>> +
>> +		for (lane = 0; lane < dp->link_train.lane_count; lane++) {
>> +			u8 training_lane = dp->link_train.training_lane[lane];
>> +			u8 vs, pe;
>> +
>> +			vs = (training_lane & DP_TRAIN_VOLTAGE_SWING_MASK) >>
>> +			     DP_TRAIN_VOLTAGE_SWING_SHIFT;
>> +			pe = (training_lane & DP_TRAIN_PRE_EMPHASIS_MASK) >>
>> +			     DP_TRAIN_PRE_EMPHASIS_SHIFT;
>> +			phy_cfg.dp.voltage[lane] = vs;
>> +			phy_cfg.dp.pre[lane] = pe;
>> +		}
>> +
>> +		phy_cfg.dp.lanes = dp->link_train.lane_count;
>> +		phy_cfg.dp.link_rate =
>> +			drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
> 
> This two should not be necessary, please drop them.

These two are necessary for rk_hdptx_phy_set_voltage(), so they cannot 
be dropped.

> 
>> +		phy_cfg.dp.set_voltages = true;
>> +		ret = phy_configure(dp->phy, &phy_cfg);
>> +		if (ret && ret != -EOPNOTSUPP) {
>> +			dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
>> +			return;
>> +		}
>> +	}
>>   }
>>   
>>   u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane)
>> -- 
>> 2.34.1
>>
> 

Best regards,
Damon



From ck.hu at mediatek.com  Thu Dec 19 19:47:07 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 03:47:07 +0000
Subject: [PATCH v3 14/33] drm/mediatek: mtk_hdmi: Move audio params
 selection to new function
In-Reply-To: <20241217154345.276919-15-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-15-angelogioacchino.delregno@collabora.com>
Message-ID: <03d20d6d77b54c25b9d7e65899a67359fae6130a.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for splitting common bits of this driver, move the
> audio params (codec, sample rate/size, input type, i2s format, etc)
> selection to a new function called mtk_hdmi_audio_params().
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_hdmi.c | 46 +++++++++++++++++------------
>  1 file changed, 27 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index d2f1d6286fbc..8f5ab97a0261 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -1479,12 +1479,11 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
>   * HDMI audio codec callbacks
>   */
> 
> -static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
> -                                   struct hdmi_codec_daifmt *daifmt,
> -                                   struct hdmi_codec_params *params)
> +static int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi,
> +                                struct hdmi_codec_daifmt *daifmt,
> +                                struct hdmi_codec_params *params)
>  {
> -       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> -       struct hdmi_audio_param hdmi_params;
> +       struct hdmi_audio_param aud_params = { 0 };
>         unsigned int chan = params->cea.channels;
> 
>         dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
> @@ -1495,16 +1494,16 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
> 
>         switch (chan) {
>         case 2:
> -               hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
>                 break;
>         case 4:
> -               hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;
>                 break;
>         case 6:
> -               hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;
>                 break;
>         case 8:
> -               hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
> +               aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;
>                 break;
>         default:
>                 dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
> @@ -1528,26 +1527,35 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
> 
>         switch (daifmt->fmt) {
>         case HDMI_I2S:
> -               hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -               hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> -               hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
> -               hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> -               hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
> +               aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +               aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +               aud_params.aud_input_type = HDMI_AUD_INPUT_I2S;
> +               aud_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> +               aud_params.aud_mclk = HDMI_AUD_MCLK_128FS;
>                 break;
>         case HDMI_SPDIF:
> -               hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -               hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> -               hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
> +               aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +               aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +               aud_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
>                 break;
>         default:
>                 dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,
>                         daifmt->fmt);
>                 return -EINVAL;
>         }
> +       memcpy(&aud_params.codec_params, params, sizeof(aud_params.codec_params));

You copy to local variable, so this function does nothing.

> +
> +       return 0;
> +}
> 
> -       memcpy(&hdmi_params.codec_params, params,
> -              sizeof(hdmi_params.codec_params));
> +static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
> +                                   struct hdmi_codec_daifmt *daifmt,
> +                                   struct hdmi_codec_params *params)
> +{
> +       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +       struct hdmi_audio_param hdmi_params;
> 
> +       mtk_hdmi_audio_params(hdmi, daifmt, params);
>         mtk_hdmi_audio_set_param(hdmi, &hdmi_params);

hdmi_params has not been initialized.

Regards,
CK

> 
>         return 0;
> --
> 2.47.0
> 


From delphine_cc_chiu at wiwynn.com  Thu Dec 19 20:38:51 2024
From: delphine_cc_chiu at wiwynn.com (Delphine CC Chiu)
Date: Fri, 20 Dec 2024 12:38:51 +0800
Subject: [PATCH v1] ARM: dts: aspeed: yosemite4: add fan led config
Message-ID: <20241220043852.1096074-1-delphine_cc_chiu@wiwynn.com>

From: Marshall Zhan <marshall.zhan.wiwynn at gmail.com>

Set fan led config in yosemite4 DTS.

Signed-off-by: Marshall Zhan <marshall.zhan.wiwynn at gmail.com>
Signed-off-by: Delphine CC Chiu <delphine_cc_chiu at wiwynn.com>
---
 .../aspeed/aspeed-bmc-facebook-yosemite4.dts  | 166 +++++++++++++++++-
 1 file changed, 163 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
index ab4904cf2c0e..b5865efcc80c 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
@@ -73,6 +73,160 @@ tpm at 0 {
 			spi-max-frequency = <33000000>;
 		};
 	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_identify {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&identify_gpio 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan0_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio0 4 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan0_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio0 5 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan1_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio0 10 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan1_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio0 11 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan2_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio1 4 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan2_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio1 5 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan3_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio1 10 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan3_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio1 11 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan4_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio0 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan4_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio0 3 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan5_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan5_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan6_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio1 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan6_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio1 3 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan7_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio1 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan7_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio1 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan8_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio0 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan8_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio0 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan9_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio0 6 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan9_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan10_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio1 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan10_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio1 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan11_blue {
+			retain-state-shutdown;
+			default-state = "on";
+			gpios = <&led_gpio1 6 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_fan11_amber {
+			retain-state-shutdown;
+			default-state = "off";
+			gpios = <&led_gpio1 7 GPIO_ACTIVE_HIGH>;
+		};
+	};
 };
 
 &uart1 {
@@ -995,11 +1149,17 @@ gpio at 20 {
 				#gpio-cells = <2>;
 			};
 
-			gpio at 21 {
+			identify_gpio: gpio at 21 {
 				compatible = "nxp,pca9506";
 				reg = <0x21>;
 				gpio-controller;
 				#gpio-cells = <2>;
+				gpio-line-names = "","","","",
+						  "","","","",
+						  "LED_IDENTIFY",
+						  "","","","","","","",
+						  "","","","","","","","",
+						  "","","","","","","","";
 			};
 
 			gpio at 22 {
@@ -1173,7 +1333,7 @@ eeprom at 52 {
 				reg = <0x52>;
 			};
 
-			gpio at 61 {
+			led_gpio0: gpio at 61 {
 				compatible = "nxp,pca9552";
 				reg = <0x61>;
 				#address-cells = <1>;
@@ -1221,7 +1381,7 @@ eeprom at 52 {
 				reg = <0x52>;
 			};
 
-			gpio at 61 {
+			led_gpio1: gpio at 61 {
 				compatible = "nxp,pca9552";
 				reg = <0x61>;
 				#address-cells = <1>;
-- 
2.25.1



From tan.shaopeng at fujitsu.com  Thu Dec 19 21:01:30 2024
From: tan.shaopeng at fujitsu.com (Shaopeng Tan (Fujitsu))
Date: Fri, 20 Dec 2024 05:01:30 +0000
Subject: [RFC PATCH 4/6] arm_mpam: Introduce flexible CLOSID/RMID
 translation
In-Reply-To: <20241212154000.330467-5-Dave.Martin@arm.com>
References: <20241212154000.330467-1-Dave.Martin@arm.com>
 <20241212154000.330467-5-Dave.Martin@arm.com>
Message-ID: <OSZPR01MB8798833576F5FD4868E804FE8B072@OSZPR01MB8798.jpnprd01.prod.outlook.com>

Hello Dave,

> Currently, the MPAM driver uses the resctrl CLOSID directly as the MPAM
> Partition Identifier (PARTID; possibly modified to give different PARTIDs to
> code and data when Code/Data Partitioning / CDP is enabled), and uses the
> resctrl RMID directly as the MPAM Performance Monitoring Group identifier
> (PMG).
> 
> In preparation for using the MPAM PARTID Narrowing feature to allow more
> resctrl monitoring groups to be provided than the number of PMG values
> supported by the hardware, a more flexible remapping scheme is needed.
> 
> Factor out ID translation operations in the MPAM resctrl glue code into a couple
> of self-contained helpers, and call them as appropriate.
> 
> The translation scheme has a single parameter, partid_per_closid, which is
> currently hard-wired to 1.
> 
> As a result, this patch should have no effect on functionality.
> 
> Logic to determine / control the mapping parameters can be introduced later.
> 
> The ID transformation may be visualised as follows:
> 
> without CDP:
>   +---------------------------------------------------+-----------+
>   |                       CLOSID                      |    RMID   |
>   +---------------------------------------------------+-------+---+
>   |                           PARTID                  :       |PMG|
>   +-----------------------------------------------------------+---+
> 
> and with CDP, where the "CDP" field is 0 for the data sub- partition and 1 for
> the code sub-partition:
>   +-----------------------------------------------+---+-----------+
>   |                     CLOSID                    |CDP|    RMID   |
>   +-----------------------------------------------+---+-------+---+
>   |                           PARTID                  :       |PMG|
>   +-----------------------------------------------------------+---+
> 
> where each box represents a non-negative integer spanning some fixed range
> starting from zero, and horizontal concatenation denotes multiplying the value
> denoted by the left-hand box by the span of the right-hand box, and adding the
> result to the value denoted by the right-hand box; thus, most-significant fields
> are on the left.
> 
> (Except for the span of each field not necessarily being a power of two, this is
> conceptually identical to concatenation and cutting of
> bitfields.)
> 
> The dotted segment indicates the least significant part of PARTID, which spans
> partid_per_closid PARTIDs and discriminates monitoring groups that use the
> same MPAM PMG value.
> 
> Signed-off-by: Dave Martin <Dave.Martin at arm.com>
> ---
>  drivers/platform/arm64/mpam/mpam_resctrl.c | 200
> +++++++++++----------
>  1 file changed, 110 insertions(+), 90 deletions(-)
> 
> diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c
> b/drivers/platform/arm64/mpam/mpam_resctrl.c
> index 30f2caec11d7..0473286ec65a 100644
> --- a/drivers/platform/arm64/mpam/mpam_resctrl.c
> +++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
> @@ -156,6 +156,18 @@ static bool mpam_resctrl_hide_cdp(enum
> resctrl_res_level rid)
>  	return cdp_enabled && !resctrl_arch_get_cdp_enabled(rid);
>  }
> 
> +static unsigned int partid_per_closid = 1;
> +
> +static unsigned int mpam_num_pmg(void)
> +{
> +	return mpam_pmg_max + 1;
> +}
> +
> +static unsigned int mpam_num_rmid(void) {
> +	return mpam_num_pmg() * partid_per_closid; }
> +
>  /*
>   * MSC may raise an error interrupt if it sees an out or range partid/pmg,
>   * and go on to truncate the value. Regardless of what the hardware supports,
> @@ -163,35 +175,71 @@ static bool mpam_resctrl_hide_cdp(enum
> resctrl_res_level rid)
>   */
>  u32 resctrl_arch_get_num_closid(struct rdt_resource *ignored)  {
> -	return mpam_partid_max + 1;
> +	u32 res = (mpam_partid_max + 1) / partid_per_closid;

If there is a remainder, are you going to ignore the remainder PARTIDs?
It might be better to notify the user with a warning message.

> +	WARN_ON(res < 1);
> +	return res;
>  }

I think it is better to check whether PARTID narrowing feature is supported or not before using this function.?
If it is checked here, since this function is called multiple times, the message should be printed only once by WARN_ON_ONCE().?

Also, if the partid_per_closid is greater than (mpam_partid_max + 1), returning "0" will not work properly. 
To switch to default behavior (PARTID narrowing disabled), should it return mapm_patid_max+ 1)?

> -u32 resctrl_arch_system_num_rmid_idx(void)
> +static void mpam_resctrl_partid_range(u32 closid, enum resctrl_conf_type
> type,
> +				      const struct rdt_resource *r,
> +				      u16 *min_partid, u16 *max_partid)
>  {
> -	u8 closid_shift = fls(mpam_pmg_max);
> -	u32 num_partid = resctrl_arch_get_num_closid(NULL);
> +	u16 base_partid = closid;
> +	u16 span = 1;
> +
> +	if (cdp_enabled) {
> +		base_partid *= 2;
> +		if (mpam_resctrl_hide_cdp(r->rid) ||
> +		    type == CDP_NONE)
> +			span *= 2;
> +	}
> 
> -	return num_partid << closid_shift;
> +	*min_partid = base_partid * partid_per_closid;
> +	if (max_partid)
> +		*max_partid = *min_partid + (span * partid_per_closid - 1);
>  }

I think the min_partid/max_partid is different depending on the type (CDP_DATA or CDP_CODE).

> -u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
> +static void mpam_resctrl_hwid(u32 closid, u32 rmid,
> +			      u16 *partid_d, u16 *partid_i, u8 *pmg)
>  {
> -	u8 closid_shift = fls(mpam_pmg_max);
> +	const u16 pmg_hi = rmid / mpam_num_pmg();
> +	const u16 pmg_lo = rmid % mpam_num_pmg();
> +	u16 base_partid = closid;
> +	u16 partid_stride = 0;
> +
> +	if (cdp_enabled) {
> +		base_partid *= 2;
> +		partid_stride = 1;
> +	}
> 
> -	BUG_ON(closid_shift > 8);
> +	partid_stride *= partid_per_closid;
> +	base_partid *= partid_per_closid;
> +	base_partid += pmg_hi;
> 
> -	return (closid << closid_shift) | rmid;
> +	*partid_d = base_partid;
> +	if (partid_i)
> +		*partid_i = base_partid + partid_stride;
> +
> +	*pmg = pmg_lo;
>  }
> 
> -void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
> +u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
>  {
> -	u8 closid_shift = fls(mpam_pmg_max);
> -	u32 pmg_mask = ~(~0 << closid_shift);
> +	return closid * mpam_num_rmid() + rmid; }
> 
> -	BUG_ON(closid_shift > 8);
> +u32 resctrl_arch_system_num_rmid_idx(void)
> +{
> +	u32 num_closid = resctrl_arch_get_num_closid(NULL);
> 
> -	*closid = idx >> closid_shift;
> -	*rmid = idx & pmg_mask;
> +	return resctrl_arch_rmid_idx_encode(num_closid, 0); }
> +
> +void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid) {
> +	*closid = idx / mpam_num_rmid();
> +	*rmid = idx % mpam_num_rmid();
>  }
> 
>  void resctrl_arch_sched_in(struct task_struct *tsk) @@ -203,21 +251,14 @@
> void resctrl_arch_sched_in(struct task_struct *tsk)
> 
>  void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid, u32 rmid)
> {
> +	u16 partid_d, partid_i;
> +	u8 pmg;
> +
>  	BUG_ON(closid > U16_MAX);
>  	BUG_ON(rmid > U8_MAX);
> 
> -	if (!cdp_enabled) {
> -		mpam_set_cpu_defaults(cpu, closid, closid, rmid, rmid);
> -	} else {
> -		/*
> -		 * When CDP is enabled, resctrl halves the closid range and
> we
> -		 * use odd/even partid for one closid.
> -		 */
> -		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
> -		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
> -
> -		mpam_set_cpu_defaults(cpu, partid_d, partid_i, rmid, rmid);
> -	}
> +	mpam_resctrl_hwid(closid, rmid, &partid_d, &partid_i, &pmg);
> +	mpam_set_cpu_defaults(cpu, partid_d, partid_i, pmg, pmg);
>  }
> 
>  void resctrl_arch_sync_cpu_closid_rmid(void *info) @@ -236,41 +277,38 @@
> void resctrl_arch_sync_cpu_closid_rmid(void *info)
> 
>  void resctrl_arch_set_closid_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
> {
> +	u16 partid_d, partid_i;
> +	u8 pmg;
> +
>  	BUG_ON(closid > U16_MAX);
>  	BUG_ON(rmid > U8_MAX);
> 
> -	if (!cdp_enabled) {
> -		mpam_set_task_partid_pmg(tsk, closid, closid, rmid, rmid);
> -	} else {
> -		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
> -		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
> -
> -		mpam_set_task_partid_pmg(tsk, partid_d, partid_i, rmid,
> rmid);
> -	}
> +	mpam_resctrl_hwid(closid, rmid, &partid_d, &partid_i, &pmg);
> +	mpam_set_task_partid_pmg(tsk, partid_d, partid_i, pmg, pmg);
>  }
> 
>  bool resctrl_arch_match_closid(struct task_struct *tsk, u32 closid)  {
> +	u16 min_partid, max_partid;
>  	u64 regval = mpam_get_regval(tsk);
>  	u32 tsk_closid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
> 
> -	if (cdp_enabled)
> -		tsk_closid >>= 1;
> -
> -	return tsk_closid == closid;
> +	mpam_resctrl_partid_range(closid, CDP_NONE, NULL,
> +				  &min_partid, &max_partid);
> +	return tsk_closid >= min_partid && tsk_closid <= max_partid;
>  }
> 
>  /* The task's pmg is not unique, the partid must be considered too */  bool
> resctrl_arch_match_rmid(struct task_struct *tsk, u32 closid, u32 rmid)  {
> +	u16 partid_d;
> +	u8 pmg;
>  	u64 regval = mpam_get_regval(tsk);
> -	u32 tsk_closid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
> -	u32 tsk_rmid = FIELD_GET(MPAM1_EL1_PMG_D, regval);
> -
> -	if (cdp_enabled)
> -		tsk_closid >>= 1;
> +	u16 tsk_partid_d = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
> +	u8 tsk_pmg = FIELD_GET(MPAM1_EL1_PMG_D, regval);
> 
> -	return (tsk_closid == closid) && (tsk_rmid == rmid);
> +	mpam_resctrl_hwid(closid, rmid, &partid_d, NULL, &pmg);
> +	return (tsk_partid_d == partid_d) && (tsk_pmg == pmg);
>  }
> 
>  struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
> @@ -370,6 +408,7 @@ int resctrl_arch_rmid_read(struct rdt_resource	*r,
> struct rdt_mon_domain *d,
>  	struct mpam_resctrl_dom *dom;
>  	u32 mon = *(u32 *)arch_mon_ctx;
>  	enum mpam_device_features type;
> +	u16 partid_d, partid_i, pmg;
> 
>  	resctrl_arch_rmid_read_context_check();
> 
> @@ -391,27 +430,23 @@ int resctrl_arch_rmid_read(struct rdt_resource	*r,
> struct rdt_mon_domain *d,
>  	if (cfg.mon == USE_RMID_IDX)
>  		cfg.mon = resctrl_arch_rmid_idx_encode(closid, rmid);
> 
> +	mpam_resctrl_hwid(closid, rmid, &partid_d, &partid_i, &cfg.pmg);
>  	cfg.match_pmg = true;
> -	cfg.pmg = rmid;
> +	cfg.pmg = pmg;
>  	cfg.opts = resctrl_evt_config_to_mpam(dom->mbm_local_evt_cfg);
> 
>  	if (irqs_disabled()) {
>  		/* Check if we can access this domain without an IPI */
>  		err = -EIO;
>  	} else {
> -		if (cdp_enabled) {
> -			cfg.partid = closid << 1;
> -			err = mpam_msmon_read(dom->comp, &cfg, type,
> val);
> -			if (err)
> -				return err;
> +		cfg.partid = partid_d;
> +		err = mpam_msmon_read(dom->comp, &cfg, type, val);
> 
> -			cfg.partid += 1;
> +		if (partid_i != partid_d) {
> +			cfg.partid = partid_i;
>  			err = mpam_msmon_read(dom->comp, &cfg, type,
> &cdp_val);
>  			if (!err)
>  				*val += cdp_val;
> -		} else {
> -			cfg.partid = closid;
> -			err = mpam_msmon_read(dom->comp, &cfg, type,
> val);
>  		}
>  	}
> 
> @@ -423,6 +458,7 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r,
> struct rdt_mon_domain *d,  {
>  	struct mon_cfg cfg;
>  	struct mpam_resctrl_dom *dom;
> +	u16 partid_d, partid_i;
> 
>  	if (eventid != QOS_L3_MBM_LOCAL_EVENT_ID)
>  		return;
> @@ -433,14 +469,13 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r,
> struct rdt_mon_domain *d,
> 
>  	dom = container_of(d, struct mpam_resctrl_dom, resctrl_mon_dom);
> 
> -	if (cdp_enabled) {
> -		cfg.partid = closid << 1;
> -		mpam_msmon_reset_mbwu(dom->comp, &cfg);
> +	mpam_resctrl_hwid(closid, rmid, &partid_d, &partid_i, &cfg.pmg);
> 
> -		cfg.partid += 1;
> -		mpam_msmon_reset_mbwu(dom->comp, &cfg);
> -	} else {
> -		cfg.partid = closid;
> +	cfg.partid = partid_d;
> +	mpam_msmon_reset_mbwu(dom->comp, &cfg);
> +
> +	if (partid_i != partid_d) {
> +		cfg.partid = partid_i;
>  		mpam_msmon_reset_mbwu(dom->comp, &cfg);
>  	}
>  }
> @@ -1081,7 +1116,7 @@ static void mpam_resctrl_exit(void)
>  u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_ctrl_domain *d,
>  			    u32 closid, enum resctrl_conf_type type)  {
> -	u32 partid;
> +	u16 partid;
>  	struct mpam_config *cfg;
>  	struct mpam_props *cprops;
>  	struct mpam_resctrl_res *res;
> @@ -1097,15 +1132,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r,
> struct rdt_ctrl_domain *d,
>  	dom = container_of(d, struct mpam_resctrl_dom, resctrl_ctrl_dom);
>  	cprops = &res->class->props;
> 
> -	/*
> -	 * When CDP is enabled, but the resource doesn't support it,
> -	 * the control is cloned across both partids.
> -	 * Pick one at random to read:
> -	 */
> -	if (mpam_resctrl_hide_cdp(r->rid))
> -		type = CDP_DATA;
> -
> -	partid = resctrl_get_config_index(closid, type);
> +	mpam_resctrl_partid_range(closid, type, r, &partid, NULL);
>  	cfg = &dom->comp->cfg[partid];
> 
>  	switch (r->rid) {
> @@ -1126,7 +1153,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r,
> struct rdt_ctrl_domain *d,
>  		return -EINVAL;
>  	}
> 
> -	if (!r->alloc_capable || partid >= resctrl_arch_get_num_closid(r) ||
> +	if (!r->alloc_capable || partid > mpam_partid_max ||
>  	    !mpam_has_feature(configured_by, cfg))
>  		return resctrl_get_default_ctrl(r);
> 
> @@ -1147,8 +1174,8 @@ u32 resctrl_arch_get_config(struct rdt_resource *r,
> struct rdt_ctrl_domain *d,  int resctrl_arch_update_one(struct rdt_resource *r,
> struct rdt_ctrl_domain *d,
>  			    u32 closid, enum resctrl_conf_type t, u32 cfg_val)
> {
> -	int err;
> -	u32 partid;
> +	int err = 0;
> +	u16 partid, min_partid, max_partid;
>  	struct mpam_config cfg;
>  	struct mpam_props *cprops;
>  	struct mpam_resctrl_res *res;
> @@ -1163,8 +1190,10 @@ int resctrl_arch_update_one(struct rdt_resource *r,
> struct rdt_ctrl_domain *d,
>  	dom = container_of(d, struct mpam_resctrl_dom, resctrl_ctrl_dom);
>  	cprops = &res->class->props;
> 
> -	partid = resctrl_get_config_index(closid, t);
> -	if (!r->alloc_capable || partid >= resctrl_arch_get_num_closid(r))
> +	mpam_resctrl_partid_range(closid, t, r, &min_partid, &max_partid);
> +	if (!r->alloc_capable ||
> +	    min_partid > mpam_partid_max ||
> +	    max_partid > mpam_partid_max)
>  		return -EINVAL;
> 
>  	cfg.features = 0;
> @@ -1190,22 +1219,13 @@ int resctrl_arch_update_one(struct rdt_resource *r,
> struct rdt_ctrl_domain *d,
>  		return -EINVAL;
>  	}
> 
> -	/*
> -	 * When CDP is enabled, but the resource doesn't support it, we need
> to
> -	 * apply the same configuration to the other partid.
> -	 */
> -	if (mpam_resctrl_hide_cdp(r->rid)) {
> -		partid = resctrl_get_config_index(closid, CDP_CODE);
> +	for (partid = min_partid; partid <= max_partid; partid++) {
>  		err = mpam_apply_config(dom->comp, partid, &cfg);
>  		if (err)
> -			return err;
> -
> -		partid = resctrl_get_config_index(closid, CDP_DATA);
> -		return mpam_apply_config(dom->comp, partid, &cfg);
> -
> -	} else {
> -		return mpam_apply_config(dom->comp, partid, &cfg);
> +			break;
>  	}
> +
> +	return err;
>  }

For a mixture of MSCs system, MSCs that do not support PARTID narrowing and support Maximum Partition feature may not work properly.

>  /* TODO: this is IPI heavy */
> --
> 2.34.1

I know this is not a complete implementation.
Mapping relationship between intPARTIDs and reqPARTIDs need to be written to register MPAMCFG_INTPARTID/MPAMCFG_PART_SEL.

Best regards,
Shaopeng TAN

From peng.fan at oss.nxp.com  Thu Dec 19 22:12:42 2024
From: peng.fan at oss.nxp.com (Peng Fan)
Date: Fri, 20 Dec 2024 14:12:42 +0800
Subject: [PATCH] clk: clk-imx8mp-audiomix: fix function signature
In-Reply-To: <20241219105447.889CB11FE@mail.steuer-voss.de>
References: <20241219105447.889CB11FE@mail.steuer-voss.de>
Message-ID: <20241220061242.GA8295@localhost.localdomain>

On Thu, Dec 19, 2024 at 11:54:11AM +0100, Nikolaus Voss wrote:
>clk_imx8mp_audiomix_reset_controller_register() in the
>"if !CONFIG_RESET_CONTROLLER" branch had the first
>argument missing. It is an empty function for this branch
>so it wasn't immediately apparent.
>
>Fixes: 6f0e817175c5 ("clk: imx: clk-audiomix: Add reset controller")
>Cc: <stable at vger.kernel.org> # 6.12.x
>Signed-off-by: Nikolaus Voss <nv at vosn.de>

Reviewed-by: Peng Fan <peng.fan at nxp.com>


From peng.fan at oss.nxp.com  Thu Dec 19 22:16:13 2024
From: peng.fan at oss.nxp.com (Peng Fan)
Date: Fri, 20 Dec 2024 14:16:13 +0800
Subject: [PATCH 0/6] arm64: dts: freescale: imx8mp-skov: switch to
 nominal drive mode
In-Reply-To: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
Message-ID: <20241220061613.GB8295@localhost.localdomain>

On Thu, Dec 19, 2024 at 08:27:31AM +0100, Ahmad Fatoum wrote:
>Unlike the i.MX8MM and i.MX8MN SoCs added earlier, the imx8mp.dtsi
>configures some clocks at frequencies that are only validated for
>overdrive mode, i.e., when VDD_SOC is 950 mV.
>
>For the Skov i.MX8MP board, we want to run the SoC at the lower voltage of
>850 mV though to reduce heat generation and power usage. For this to work,
>clock rates need to adhere to the limits of the nominal drive mode.
>
>This is done by this series: A new imx8mp-nominal.dtsi reconfigures
>the imx8mp.dtsi clock tree to be compatible with nominal mode, an adaptation
>to the Linux clock driver makes it sanity check the actual clock rates against
>the SoC operating mode's constraints and finally the Skov DT makes use
>of it.
>
>Actual configuration of the VDD_SOC rail continues to happen prior to Linux
>as well as PLL configuration that needs to happen earlier than the kernel
>running. See the corresponding barebox patch series[1] for details.
>Note that the barebox series didn't yet include VDD_SOC reconfiguration
>to 850mV, that would follow once the kernel changes have been merged.

Good to see this. I had same plan to support i.MX9.

I see you introduce a new property, how about using a boot pararmeter,
saying "mode=nominal" or "mode=overdrive". Then drivers could
act accordingly.

Regards,
Peng

>
>[1]: https://lore.kernel.org/barebox/20240503103717.1370636-1-a.fatoum at pengutronix.de/
>
>---
>Ahmad Fatoum (6):
>      dt-bindings: clock: imx8m: document nominal/overdrive properties
>      arm64: dts: imx8mp: Add optional nominal drive mode DTSI
>      arm64: dts: imx8mp: add fsl,nominal-mode property into nominal.dtsi
>      arm64: dts: freescale: imx8mp-skov: fix LDB clock rate configuration
>      arm64: dts: freescale: imx8mp-skov: operate SoC in nominal mode
>      clk: imx8mp: inform CCF of maximum frequency of clocks
>
> .../devicetree/bindings/clock/imx8m-clock.yaml     |  14 ++
> arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi  |  64 +++++++++
> .../arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi |   5 +-
> .../freescale/imx8mp-skov-revb-mi1010ait-1cp1.dts  |  19 +--
> drivers/clk/imx/clk-imx8mp.c                       | 147 +++++++++++++++++++++
> 5 files changed, 233 insertions(+), 16 deletions(-)
>---
>base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
>change-id: 20241217-imx8m-clk-9467763dfcd8
>
>Best regards,
>-- 
>Ahmad Fatoum <a.fatoum at pengutronix.de>
>


From peng.fan at oss.nxp.com  Thu Dec 19 22:18:05 2024
From: peng.fan at oss.nxp.com (Peng Fan)
Date: Fri, 20 Dec 2024 14:18:05 +0800
Subject: [PATCH 6/6] clk: imx8mp: inform CCF of maximum frequency of
 clocks
In-Reply-To: <20241219-imx8m-clk-v1-6-cfaffa087da6@pengutronix.de>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
 <20241219-imx8m-clk-v1-6-cfaffa087da6@pengutronix.de>
Message-ID: <20241220061805.GC8295@localhost.localdomain>

On Thu, Dec 19, 2024 at 08:27:37AM +0100, Ahmad Fatoum wrote:
>The IMX8MPCEC datasheet lists maximum frequencies allowed for different
>modules. Some of these limits are universal, but some depend on
>whether the SoC is operating in nominal or in overdrive mode.
>
>The imx8mp.dtsi currently assumes overdrive mode and configures some
>clocks in accordance with this. Boards wishing to make use of nominal
>mode will need to override some of the clock rates manually.
>
>As operating the clocks outside of their allowed range can lead to
>difficult to debug issues, it makes sense to register the maximum rates
>allowed in the driver, so the CCF can take them into account.
>
>Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
>---
> drivers/clk/imx/clk-imx8mp.c | 147 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 147 insertions(+)
>
>diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
>index 516dbd170c8a..3b06990b73ad 100644
>--- a/drivers/clk/imx/clk-imx8mp.c
>+++ b/drivers/clk/imx/clk-imx8mp.c
>@@ -8,6 +8,7 @@
> #include <linux/err.h>
> #include <linux/io.h>
> #include <linux/module.h>
>+#include <linux/units.h>
> #include <linux/of_address.h>
> #include <linux/platform_device.h>
> #include <linux/slab.h>
>@@ -405,6 +406,145 @@ static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_
> static struct clk_hw **hws;
> static struct clk_hw_onecell_data *clk_hw_data;
> 
>+struct imx8mp_clock_constraints {
>+	int clkid;
>+	u32 maxrate;
>+};
>+
>+/*
>+ * Below tables are taken from IMX8MPCEC Rev. 2.1, 07/2023
>+ * Table 13. Maximum frequency of modules.
>+ * Probable typos fixed are marked with a comment.
>+ */
>+static const struct imx8mp_clock_constraints imx8mp_clock_common_constraints[] = {
>+	{ IMX8MP_CLK_A53_DIV,             1000 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ENET_AXI,             266666667 }, /* Datasheet claims 266MHz */
>+	{ IMX8MP_CLK_NAND_USDHC_BUS,       266666667 }, /* Datasheet claims 266MHz */
>+	{ IMX8MP_CLK_MEDIA_APB,            200 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_HDMI_APB,             133333333 }, /* Datasheet claims 133MHz */
>+	{ IMX8MP_CLK_ML_AXI,               800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_AHB,                  133333333 },
>+	{ IMX8MP_CLK_IPG_ROOT,              66666667 },
>+	{ IMX8MP_CLK_AUDIO_AHB,            400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_DISP2_PIX,      170 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_DRAM_ALT,             666666667 },
>+	{ IMX8MP_CLK_DRAM_APB,             200 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_CAN1,                  80 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_CAN2,                  80 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_PCIE_AUX,              10 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_I2C5,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_I2C6,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_SAI1,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_SAI2,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_SAI3,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_SAI5,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_SAI6,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_ENET_QOS,             125 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ENET_QOS_TIMER,       200 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ENET_REF,             125 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ENET_TIMER,           125 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ENET_PHY_REF,         125 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_NAND,                 500 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_QSPI,                 400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_USDHC1,               400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_USDHC2,               400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_I2C1,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_I2C2,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_I2C3,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_I2C4,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_UART1,                 80 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_UART2,                 80 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_UART3,                 80 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_UART4,                 80 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ECSPI1,                80 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ECSPI2,                80 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_PWM1,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_PWM2,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_PWM3,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_PWM4,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_GPT1,                 100 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPT2,                 100 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPT3,                 100 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPT4,                 100 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPT5,                 100 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPT6,                 100 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_WDOG,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_IPP_DO_CLKO1,         200 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_IPP_DO_CLKO2,         200 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_HDMI_REF_266M,        266 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_USDHC3,               400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_MIPI_PHY1_REF,  300 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_DISP1_PIX,      250 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_CAM2_PIX,       277 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_LDB,            595 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE, 200 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ECSPI3,                80 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_PDM,                  200 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_SAI7,                  66666667 }, /* Datasheet claims 66MHz */
>+	{ IMX8MP_CLK_MAIN_AXI,             400 * HZ_PER_MHZ },
>+	{ /* sentinel */ },
>+};
>+
>+static const struct imx8mp_clock_constraints imx8mp_clock_nominal_constraints[] = {
>+	{ IMX8MP_CLK_M7_CORE,           600 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ML_CORE,           800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU3D_CORE,        800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU3D_SHADER_CORE, 800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU2D_CORE,        800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_AUDIO_AXI_SRC,     600 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_HSIO_AXI,          400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_ISP,         400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_VPU_BUS,           600 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_AXI,         400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_HDMI_AXI,          400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU_AXI,           600 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU_AHB,           300 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_NOC,               800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_NOC_IO,            600 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ML_AHB,            300 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_VPU_G1,            600 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_VPU_G2,            500 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_CAM1_PIX,    400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_VPU_VC8000E,       400 * HZ_PER_MHZ }, /* Datasheet claims 500MHz */
>+	{ IMX8MP_CLK_DRAM_CORE,         800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GIC,               400 * HZ_PER_MHZ },
>+	{ /* sentinel */ },
>+};
>+
>+static const struct imx8mp_clock_constraints imx8mp_clock_overdrive_constraints[] = {
>+	{ IMX8MP_CLK_M7_CORE,            800 * HZ_PER_MHZ},
>+	{ IMX8MP_CLK_ML_CORE,           1000 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU3D_CORE,        1000 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU3D_SHADER_CORE, 1000 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU2D_CORE,        1000 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_AUDIO_AXI_SRC,      800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_HSIO_AXI,           500 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_ISP,          500 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_VPU_BUS,            800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_AXI,          500 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_HDMI_AXI,           500 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU_AXI,            800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GPU_AHB,            400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_NOC,               1000 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_NOC_IO,             800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_ML_AHB,             400 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_VPU_G1,             800 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_VPU_G2,             700 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_MEDIA_CAM1_PIX,     500 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_VPU_VC8000E,        500 * HZ_PER_MHZ }, /* Datasheet claims 400MHz */
>+	{ IMX8MP_CLK_DRAM_CORE,         1000 * HZ_PER_MHZ },
>+	{ IMX8MP_CLK_GIC,                500 * HZ_PER_MHZ },
>+	{ /* sentinel */ },
>+};
>+
>+static void imx8mp_clocks_apply_constraints(const struct imx8mp_clock_constraints constraints[])
>+{
>+	const struct imx8mp_clock_constraints *constr;
>+
>+	for (constr = constraints; constr->clkid; constr++)
>+		clk_hw_set_rate_range(hws[constr->clkid], 0, constr->maxrate);
>+}
>+
> static int imx8mp_clocks_probe(struct platform_device *pdev)
> {
> 	struct device *dev = &pdev->dev;
>@@ -714,6 +854,13 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
> 
> 	imx_check_clk_hws(hws, IMX8MP_CLK_END);
> 
>+	imx8mp_clocks_apply_constraints(imx8mp_clock_common_constraints);
>+
>+	if (of_property_read_bool(np, "fsl,nominal-mode"))
>+		imx8mp_clocks_apply_constraints(imx8mp_clock_nominal_constraints);
>+	else if (of_property_read_bool(np, "fsl,overdrive-mode"))
>+		imx8mp_clocks_apply_constraints(imx8mp_clock_overdrive_constraints);

As I replied, a boot parameter should be better? the mode is a soc level mode,
not just clock controller.

Thanks,
Peng

>+
> 	err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
> 	if (err < 0) {
> 		dev_err(dev, "failed to register hws for i.MX8MP\n");
>
>-- 
>2.39.5
>


From a0501179 at ti.com  Thu Dec 19 21:31:20 2024
From: a0501179 at ti.com (Anwar, Md Danish)
Date: Fri, 20 Dec 2024 11:01:20 +0530
Subject: [PATCH net-next 1/4] net: ti: Kconfig: Select HSR for ICSSG
 Driver
In-Reply-To: <Z2RQ7xj6IwPXsqHO@lzaremba-mobl.ger.corp.intel.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-2-danishanwar@ti.com>
 <Z2L/hwH5pgBV9pSB@lzaremba-mobl.ger.corp.intel.com>
 <c6254178-6e2a-47e1-ac16-22af5affc8ca@ti.com>
 <Z2RQ7xj6IwPXsqHO@lzaremba-mobl.ger.corp.intel.com>
Message-ID: <73bc878e-a323-44ef-b90f-11723ce129e3@ti.com>

Hi,

On 12/19/2024 10:29 PM, Larysa Zaremba wrote:
> On Thu, Dec 19, 2024 at 10:36:57AM +0530, MD Danish Anwar wrote:
>>
>>
>> On 18/12/24 10:29 pm, Larysa Zaremba wrote:
>>> On Mon, Dec 16, 2024 at 03:30:41PM +0530, MD Danish Anwar wrote:
>>>> HSR offloading is supported by ICSSG driver. Select the symbol HSR for
>>>> TI_ICSSG_PRUETH. Also select NET_SWITCHDEV instead of depending on it to
>>>> remove recursive dependency.
>>>>
>>>
>>> 2 things:
>>> 1) The explanation from the cover should have been included in the commit 
>>>    message.
>>
>> I wanted to keep the commit message brief so I provided the actual
>> errors in cover letter. I will add the logs here as well.
>>
> 
> Commit message has to be as verbose as needed to provide enough context for 
> whoever needs to explore the code history later.
>  

Sure I will update the commit message.

>>> 2) Why not `depends on HSR`?
>>
>> Adding `depends on HSR` in `config TI_ICSSG_PRUETH` is not setting HSR.
>> I have tried below scenarios and only one of them work.
>>
>> 1) depends on NET_SWITCHDEV
>>    depends on HSR
>>
>> 	HSR doesn't get set in .config - `# CONFIG_HSR is not set`. Even the
>> CONFIG_TI_ICSSG_PRUETH also gets unset although this is set to =m in
>> defconfig. But keeping both as `depends on` makes CONFIG_TI_ICSSG_PRUETH
>> disabled.
> 
> I do not understand your problem with this option, CONFIG_HSR is a visible 
> option that you can enable manually only then you will be able to successfully 
> set CONFIG_TI_ICSSG_PRUETH to m/y, this is how the relation with NET_SWITCHDEV 
> currently works.
> 

The only problem with this option is that when I do `make defconfig`, it
will unset CONFIG_TI_ICSSG_PRUETH.

I will have to manually change the arch/arm64/configs/defconfig to set
HSR=m and then only `make defconfig` will enable CONFIG_TI_ICSSG_PRUETH

Currently HSR is not enabled in defconfig. I will have to send out a
patch to set HSR=m in defconfig

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..ff3e5d960e2a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -129,6 +129,7 @@ CONFIG_MEMORY_FAILURE=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_HSR=m
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y


Since I am the only one needing HSR, I thought it would be better if I
select HSR and it only gets built if CONFIG_TI_ICSSG_PRUETH is enabled
instead of always getting built.

For this reason I thought selecting HSR would be good choice, since just
selecting HSR wasn't enough and resulted in recursive dependency,  I had
to change NET_SWITCHDEV also to select.

BTW `NET_DSA` selects `NET_SWITCHDEV` (net/dsa/Kconfig:9)

> Just 'depends on' is still a preferred way for me, as there is not a single 
> driver that does 'select NET_SWITCHDEV'
> 
>>
>> 2) select NET_SWITCHDEV
>>    depends on HSR
>>
>> 	HSR doesn't get set in .config - `# CONFIG_HSR is not set`. Even the
>> CONFIG_TI_ICSSG_PRUETH also gets unset although this is set to =m in
>> defconfig. But keeping both as `depends on` makes CONFIG_TI_ICSSG_PRUETH
>> disabled.
>>
>> 3) depends on NET_SWITCHDEV
>>    select HSR
>> 	
>> 	Results in recursive dependency
>>
>> error: recursive dependency detected!
>> 	symbol NET_DSA depends on HSR
>> 	symbol HSR is selected by TI_ICSSG_PRUETH
>> 	symbol TI_ICSSG_PRUETH depends on NET_SWITCHDEV
>> 	symbol NET_SWITCHDEV is selected by NET_DSA
>> For a resolution refer to Documentation/kbuild/kconfig-language.rst
>> subsection "Kconfig recursive dependency limitations"
>>
>> make[2]: *** [scripts/kconfig/Makefile:95: defconfig] Error 1
>> make[1]: *** [/home/danish/workspace/net-next/Makefile:733: defconfig]
>> Error 2
>> make: *** [Makefile:251: __sub-make] Error 2
>>
>> 4) select NET_SWITCHDEV
>>    select HSR
>>
>> 	HSR is set as `m` along with `CONFIG_TI_ICSSG_PRUETH`
>>
>> CONFIG_HSR=m
>> CONFIG_NET_SWITCHDEV=y
>> CONFIG_TI_ICSSG_PRUETH=m
>>
>> #4 is the only secnario where HSR gets built. That's why I sent the
>> patch with `select NET_SWITCHDEV` and `select HSR`
>>

I still think 4 is the best option. Only difference here is that we have
to `select NET_SWITCHDEV` as well.

>>>  
>>>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>>>> ---
>>>>  drivers/net/ethernet/ti/Kconfig | 3 ++-
>>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
>>>> index 0d5a862cd78a..ad366abfa746 100644
>>>> --- a/drivers/net/ethernet/ti/Kconfig
>>>> +++ b/drivers/net/ethernet/ti/Kconfig
>>>> @@ -187,8 +187,9 @@ config TI_ICSSG_PRUETH
>>>>  	select PHYLIB
>>>>  	select TI_ICSS_IEP
>>>>  	select TI_K3_CPPI_DESC_POOL
>>>> +	select NET_SWITCHDEV
>>>> +	select HSR
>>>>  	depends on PRU_REMOTEPROC
>>>> -	depends on NET_SWITCHDEV
>>>>  	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
>>>>  	depends on PTP_1588_CLOCK_OPTIONAL
>>>>  	help
>>>> -- 
>>>> 2.34.1
>>>>
>>>>
>>
>> -- 
>> Thanks and Regards,
>> Danish

-- 
Thanks and Regards,
Md Danish Anwar


From o.rempel at pengutronix.de  Thu Dec 19 21:32:45 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Fri, 20 Dec 2024 06:32:45 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <20241218043541.143194-1-carlos.song@nxp.com>
 <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <Z2UBfcq6pE-JMUrb@pengutronix.de>

On Fri, Dec 20, 2024 at 02:45:09AM +0000, Carlos Song wrote:
> 
> 
> > -----Original Message-----
> > From: Oleksij Rempel <o.rempel at pengutronix.de>
> > Sent: Thursday, December 19, 2024 8:23 PM
> > To: Andi Shyti <andi.shyti at kernel.org>
> > Cc: Carlos Song <carlos.song at nxp.com>; Frank Li <frank.li at nxp.com>;
> > kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> > festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> > linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Clark Wang
> > <xiaoning.wang at nxp.com>; Ahmad Fatoum <a.fatoum at pengutronix.de>
> > Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
> >
> > 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, Dec 19, 2024 at 01:02:29PM +0100, Andi Shyti wrote:
> > > Hi Carlos,
> > >
> > > > +   /*
> > > > +    * Init DMA config if supported, -ENODEV means DMA not enabled at
> > > > +    * this platform, that is not a real error, so just remind "only
> > > > +    * PIO mode is used". If DMA is enabled, but meet error when request
> > > > +    * DMA channel, error should be showed in probe error log. PIO mode
> > > > +    * should be available regardless of DMA.
> > > > +    */
> > > > +   ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> > > > +   if (ret) {
> > > > +           if (ret == -EPROBE_DEFER)
> > > > +                   goto clk_notifier_unregister;
> > > > +           else if (ret == -ENODEV)
> > > > +                   dev_dbg(&pdev->dev, "Only use PIO mode\n");
> > > > +           else
> > > > +                   dev_err_probe(&pdev->dev, ret, "Failed to setup
> > > > + DMA, only use PIO mode\n");
> > >
> > > Just for understanding, should we quit in this last case, as well?
> > >
> > > Before we were ignoring ENODEV and EPROBE_DEFER, but now you are
> > > making it clear that other failures like ENOMEM might happen.
> >
> > Good point, dev_err_probe() would not print an error in case of EPROBE_DEFER,
> > but in this case we should only print error and continue with PIO.
> >
> Hi,
> 
> Thank you all very much! As I comment at previous mail:
> DMA mode should be optional for i2c-imx, because i2c-imx can accept DMA mode not enabled, because it still can work in CPU mode.[1]
> [1]https://lore.kernel.org/imx/AM0PR0402MB39374E34FD6133B5E3D414D7E82F2 at AM0PR0402MB3937.eurprd04.prod.outlook.com/
> 
> Also we don't want to annoy current user without DMA[2]
> [2] https://lore.kernel.org/imx/20241127-analytic-azure-hamster-727fd8-mkl at pengutronix.de/
> 
> So we make this logic. Anyway we let the I2C controller registered whether DMA is available or not(except defer probe).
> Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing happened if DMA is defer probed or not enabled(This is an expected).
> However we still need i2c DMA status is known when meet an unexpected error, so we use dev_err_probe() to print error.

Why dev_err_probe() instead of dev_err()?

-- 
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 dmitry.baryshkov at linaro.org  Thu Dec 19 21:37:11 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 07:37:11 +0200
Subject: [PATCH v3 07/15] drm/bridge: analogix_dp: Add support for phy configuration.
In-Reply-To: <654c30ec-7d7e-4956-9a48-15bfcea34acc@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-8-damon.ding@rock-chips.com> <a6vvydjbx3hbckoy74iiyzguyyacwvdh6iirqydjfvhwgocw3a@knecggjcbcid>
 <654c30ec-7d7e-4956-9a48-15bfcea34acc@rock-chips.com>
Message-ID: <CAA8EJpqk-iim668ZTzQaROJmkTr2COBwA5G9Eg73uLE28XHYpg@mail.gmail.com>

On Fri, 20 Dec 2024 at 05:37, Damon Ding <damon.ding at rock-chips.com> wrote:
>
> Hi Dmitry,
>
> On 2024/12/20 8:13, Dmitry Baryshkov wrote:
> > On Thu, Dec 19, 2024 at 04:05:56PM +0800, Damon Ding wrote:
> >> Add support to configurate link rate, lane count, voltage swing and
> >> pre-emphasis with phy_configure(). It is helpful in application scenarios
> >> where analogix controller is mixed with the phy of other vendors.
> >>
> >> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> >>
> >> ---
> >>
> >> Changes in v2:
> >> - remove needless assignments for phy_configure()
> >> - remove unnecessary changes for phy_power_on()/phy_power_off()
> >> ---
> >>   .../drm/bridge/analogix/analogix_dp_core.c    |  1 +
> >>   .../gpu/drm/bridge/analogix/analogix_dp_reg.c | 56 +++++++++++++++++++
> >>   2 files changed, 57 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> >> index 6f10d88a34c5..9429c50cc1bc 100644
> >> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> >> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> >> @@ -1696,6 +1696,7 @@ int analogix_dp_resume(struct analogix_dp_device *dp)
> >>      if (dp->plat_data->power_on)
> >>              dp->plat_data->power_on(dp->plat_data);
> >>
> >> +    phy_set_mode(dp->phy, PHY_MODE_DP);
> >>      phy_power_on(dp->phy);
> >>
> >>      analogix_dp_init_dp(dp);
> >> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
> >> index 3afc73c858c4..613ce504bea6 100644
> >> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
> >> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
> >> @@ -11,6 +11,7 @@
> >>   #include <linux/gpio/consumer.h>
> >>   #include <linux/io.h>
> >>   #include <linux/iopoll.h>
> >> +#include <linux/phy/phy.h>
> >>
> >>   #include <drm/bridge/analogix_dp.h>
> >>
> >> @@ -513,10 +514,25 @@ void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
> >>   void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
> >>   {
> >>      u32 reg;
> >> +    int ret;
> >>
> >>      reg = bwtype;
> >>      if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
> >>              writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
> >> +
> >> +    if (dp->phy) {
> >> +            union phy_configure_opts phy_cfg = {0};
> >> +
> >> +            phy_cfg.dp.lanes = dp->link_train.lane_count;
> >
> > Should not be necessary, you are only setting the .set_rate.
>
> Indeed, this can be dropped.
>
> >
> >> +            phy_cfg.dp.link_rate =
> >> +                    drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
> >> +            phy_cfg.dp.set_rate = true;
> >> +            ret = phy_configure(dp->phy, &phy_cfg);
> >> +            if (ret && ret != -EOPNOTSUPP) {
> >> +                    dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
> >> +                    return;
> >> +            }
> >> +    }
> >>   }
> >>
> >>   void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
> >> @@ -530,9 +546,22 @@ void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
> >>   void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
> >>   {
> >>      u32 reg;
> >> +    int ret;
> >>
> >>      reg = count;
> >>      writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
> >> +
> >> +    if (dp->phy) {
> >> +            union phy_configure_opts phy_cfg = {0};
> >> +
> >> +            phy_cfg.dp.lanes = dp->link_train.lane_count;
> >> +            phy_cfg.dp.set_lanes = true;
> >> +            ret = phy_configure(dp->phy, &phy_cfg);
> >> +            if (ret && ret != -EOPNOTSUPP) {
> >> +                    dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
> >> +                    return;
> >> +            }
> >> +    }
> >>   }
> >>
> >>   void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
> >> @@ -546,10 +575,37 @@ void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
> >>   void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp)
> >>   {
> >>      u8 lane;
> >> +    int ret;
> >>
> >>      for (lane = 0; lane < dp->link_train.lane_count; lane++)
> >>              writel(dp->link_train.training_lane[lane],
> >>                     dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane);
> >> +
> >> +    if (dp->phy) {
> >> +            union phy_configure_opts phy_cfg = {0};
> >> +
> >> +            for (lane = 0; lane < dp->link_train.lane_count; lane++) {
> >> +                    u8 training_lane = dp->link_train.training_lane[lane];
> >> +                    u8 vs, pe;
> >> +
> >> +                    vs = (training_lane & DP_TRAIN_VOLTAGE_SWING_MASK) >>
> >> +                         DP_TRAIN_VOLTAGE_SWING_SHIFT;
> >> +                    pe = (training_lane & DP_TRAIN_PRE_EMPHASIS_MASK) >>
> >> +                         DP_TRAIN_PRE_EMPHASIS_SHIFT;
> >> +                    phy_cfg.dp.voltage[lane] = vs;
> >> +                    phy_cfg.dp.pre[lane] = pe;
> >> +            }
> >> +
> >> +            phy_cfg.dp.lanes = dp->link_train.lane_count;
> >> +            phy_cfg.dp.link_rate =
> >> +                    drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100;
> >
> > This two should not be necessary, please drop them.
>
> These two are necessary for rk_hdptx_phy_set_voltage(), so they cannot
> be dropped.

Please review the documentation for struct phy_configure_opts_dp and
fix your PHY driver to skip the values for which the .set_foo isn't
set. Then you might have to change this part.
You are setting just .set_voltages. It means that the rate and .lanes
shouldn't be changed and can be used as they were set by the previous
calls to phy_configure().

>
> >
> >> +            phy_cfg.dp.set_voltages = true;
> >> +            ret = phy_configure(dp->phy, &phy_cfg);
> >> +            if (ret && ret != -EOPNOTSUPP) {
> >> +                    dev_err(dp->dev, "%s: phy_configure() failed: %d\n", __func__, ret);
> >> +                    return;
> >> +            }
> >> +    }
> >>   }
> >>
> >>   u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane)
> >> --
> >> 2.34.1
> >>
> >
>
> Best regards,
> Damon
>


-- 
With best wishes
Dmitry


From ck.hu at mediatek.com  Thu Dec 19 21:36:11 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 05:36:11 +0000
Subject: [PATCH v3 16/33] drm/mediatek: mtk_hdmi: Move
 plugged_cb/codec_dev setting to new function
In-Reply-To: <20241217154345.276919-17-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-17-angelogioacchino.delregno@collabora.com>
Message-ID: <4d00d1e771f75e151481bb9a010a22faa5552a0a.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for splitting common bits of this driver, move the
> mutex-protected cable plugged callback and codec device setting
> to a new function called mtk_hdmi_audio_set_plugged_cb().

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_hdmi.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index a927d9889818..f60c4effe905 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -1597,17 +1597,22 @@ static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
>         return 0;
>  }
> 
> -static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,
> -                                         hdmi_codec_plugged_cb fn,
> +static void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn,
>                                           struct device *codec_dev)
>  {
> -       struct mtk_hdmi *hdmi = data;
> -
>         mutex_lock(&hdmi->update_plugged_status_lock);
>         hdmi->plugged_cb = fn;
>         hdmi->codec_dev = codec_dev;
>         mutex_unlock(&hdmi->update_plugged_status_lock);
> +}
> +
> +static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,
> +                                         hdmi_codec_plugged_cb fn,
> +                                         struct device *codec_dev)
> +{
> +       struct mtk_hdmi *hdmi = data;
> 
> +       mtk_hdmi_audio_set_plugged_cb(hdmi, fn, codec_dev);
>         mtk_hdmi_update_plugged_status(hdmi);
> 
>         return 0;
> --
> 2.47.0
> 


From dmitry.baryshkov at linaro.org  Thu Dec 19 21:38:12 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 07:38:12 +0200
Subject: [PATCH v3 14/15] arm64: dts: rockchip: Enable eDP0 display on
 RK3588S EVB1 board
In-Reply-To: <d2b47813-45fa-4148-8a4a-6cf4a18ee7ca@rock-chips.com>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-15-damon.ding@rock-chips.com> <cg7bnhol4gvzji7agxazas7nkxy7zammzy67rjvhp35yqyraju@73daepsbmuae>
 <d2b47813-45fa-4148-8a4a-6cf4a18ee7ca@rock-chips.com>
Message-ID: <CAA8EJpp0Smtqx7VQ5zdg9x3EhuLpk4u4vGv=rv8DHJ0rhei18w@mail.gmail.com>

On Fri, 20 Dec 2024 at 04:38, Damon Ding <damon.ding at rock-chips.com> wrote:
>
> Hi Dmitry,
>
> On 2024/12/20 8:20, Dmitry Baryshkov wrote:
> > On Thu, Dec 19, 2024 at 04:06:03PM +0800, Damon Ding wrote:
> >> Add the necessary DT changes to enable eDP0 on RK3588S EVB1 board:
> >> - Add edp-panel node
> >> - Set pinctrl of pwm12 for backlight
> >> - Enable edp0/hdptxphy0/vp2
> >>
> >> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
> >>
> >> ---
> >>
> >> Changes in v2:
> >> - Remove brightness-levels and default-brightness-level properties in
> >>    backlight node.
> >> - Add the detail DT changes to commit message.
> >>
> >> Changes in v3:
> >> - Use aux-bus instead of platform bus for edp-panel.
> >> ---
> >>   .../boot/dts/rockchip/rk3588s-evb1-v10.dts    | 52 +++++++++++++++++++
> >>   1 file changed, 52 insertions(+)
> >>
> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
> >> index bc4077575beb..9547ab18e596 100644
> >> --- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
> >> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
> >> @@ -9,6 +9,7 @@
> >>   #include <dt-bindings/gpio/gpio.h>
> >>   #include <dt-bindings/input/input.h>
> >>   #include <dt-bindings/pinctrl/rockchip.h>
> >> +#include <dt-bindings/soc/rockchip,vop2.h>
> >>   #include <dt-bindings/usb/pd.h>
> >>   #include "rk3588s.dtsi"
> >>
> >> @@ -238,6 +239,41 @@ &combphy2_psu {
> >>      status = "okay";
> >>   };
> >>
> >> +&edp0 {
> >> +    force-hpd;
> >> +    status = "okay";
> >> +
> >> +    aux-bus {
> >> +            panel {
> >> +                    compatible = "lg,lp079qx1-sp0v";
> >
> > Why do you need the particular compat string here? Can you use the
> > generic "edp-panel" instead? What if the user swaps the panel?
> >
>
> The eDP panels used in conjunction with the RK3588S EVB1 have broken
> identification, which is one of the valid reasons for using a particular
> compat string. So the generic_edp_panel_probe() can not return success
> when using the "edp-panel".

Broken how? I don't see such info in the commit message.

>
> >> +                    backlight = <&backlight>;
> >> +                    power-supply = <&vcc3v3_lcd_edp>;
> >> +
> >> +                    port {
> >> +                            panel_in_edp: endpoint {
> >> +                                    remote-endpoint = <&edp_out_panel>;
> >> +                            };
> >> +                    };
> >> +            };
> >> +    };
> >> +};
> >> +
> >> +&edp0_in {
> >> +    edp0_in_vp2: endpoint {
> >> +            remote-endpoint = <&vp2_out_edp0>;
> >> +    };
> >> +};
> >> +
> >> +&edp0_out {
> >> +    edp_out_panel: endpoint {
> >> +            remote-endpoint = <&panel_in_edp>;
> >> +    };
> >> +};
> >> +
> >> +&hdptxphy0 {
> >> +    status = "okay";
> >> +};
> >> +
> >>   &i2c3 {
> >>      status = "okay";
> >>
> >> @@ -399,6 +435,7 @@ usbc0_int: usbc0-int {
> >>   };
> >>
> >>   &pwm12 {
> >> +    pinctrl-0 = <&pwm12m1_pins>;
> >>      status = "okay";
> >>   };
> >>
> >> @@ -1168,3 +1205,18 @@ usbdp_phy0_dp_altmode_mux: endpoint at 1 {
> >>              };
> >>      };
> >>   };
> >> +
> >> +&vop_mmu {
> >> +    status = "okay";
> >> +};
> >> +
> >> +&vop {
> >> +    status = "okay";
> >> +};
> >> +
> >> +&vp2 {
> >> +    vp2_out_edp0: endpoint at ROCKCHIP_VOP2_EP_EDP0 {
> >> +            reg = <ROCKCHIP_VOP2_EP_EDP0>;
> >> +            remote-endpoint = <&edp0_in_vp2>;
> >> +    };
> >> +};
> >> --
> >> 2.34.1
> >>
> >
> Best regards,
> Damon



-- 
With best wishes
Dmitry


From ck.hu at mediatek.com  Thu Dec 19 21:44:58 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 05:44:58 +0000
Subject: [PATCH v3 17/33] drm/mediatek: mtk_hdmi: Move N/CTS setting to
 new function
In-Reply-To: <20241217154345.276919-18-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-18-angelogioacchino.delregno@collabora.com>
Message-ID: <cdbb4c9e1d4c69fad7f716db48f207e454a081ef.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for splitting common bits of this driver, moving
> the hdmi_rec_n_table struct array, and the hdmi_recommended_n(),
> hdmi_mode_clock_to_hz(), hdmi_expected_cts() functions, add one
> function called mtk_hdmi_get_ncts() that sets both N and CTS in
> a single call.

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_hdmi.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index f60c4effe905..ef8dfcb77318 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -682,6 +682,13 @@ static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate,
>                                      128 * audio_sample_rate);
>  }
> 
> +static void mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock,
> +                             unsigned int *n, unsigned int *cts)
> +{
> +       *n = hdmi_recommended_n(sample_rate, clock);
> +       *cts = hdmi_expected_cts(sample_rate, clock, *n);
> +}
> +
>  static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,
>                                     unsigned int cts)
>  {
> @@ -712,8 +719,7 @@ static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
>  {
>         unsigned int n, cts;
> 
> -       n = hdmi_recommended_n(sample_rate, clock);
> -       cts = hdmi_expected_cts(sample_rate, clock, n);
> +       mtk_hdmi_get_ncts(sample_rate, clock, &n, &cts);
> 
>         dev_dbg(hdmi->dev, "%s: sample_rate=%u, clock=%d, cts=%u, n=%u\n",
>                 __func__, sample_rate, clock, n, cts);
> --
> 2.47.0
> 


From s-vadapalli at ti.com  Thu Dec 19 21:45:16 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 20 Dec 2024 11:15:16 +0530
Subject: [PATCH] arm64: dts: ti: k3-am62p-j722s-common-main: enable USB0 for DFU boot
Message-ID: <20241220054550.153360-1-s-vadapalli@ti.com>

Add the "bootph-all" property to the "usb0" device-tree node. This is
required for the USB0 instance of USB to be functional at all stages of
USB DFU boot.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

Hello,

This patch is based on linux-next tagged next-20241219.

Enabling USB DFU Boot for AM62P5-SK requires the "bootph-all" property as
indicated at:
https://lore.kernel.org/r/20241218124542.3519447-5-s-vadapalli at ti.com/
This patch is being posted to have the "bootph-all" property present in
the Linux device-tree in order to have the same property in the U-Boot
device-tree in the future via DT sync.

Regards,
Siddharth.

 arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
index 41e1c24b1144..4516a95b7504 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
@@ -651,6 +651,7 @@ usb0: usb at 31000000 {
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			bootph-all;
 			snps,usb2-gadget-lpm-disable;
 			snps,usb2-lpm-disable;
 		};
-- 
2.43.0



From carlos.song at nxp.com  Thu Dec 19 21:59:38 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Fri, 20 Dec 2024 05:59:38 +0000
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <Z2UBfcq6pE-JMUrb@pengutronix.de>
References: <20241218043541.143194-1-carlos.song@nxp.com>
 <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
Message-ID: <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Oleksij Rempel <o.rempel at pengutronix.de>
> Sent: Friday, December 20, 2024 1:33 PM
> To: Carlos Song <carlos.song at nxp.com>
> Cc: Andi Shyti <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>;
> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Clark Wang
> <xiaoning.wang at nxp.com>; Ahmad Fatoum <a.fatoum at pengutronix.de>
> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
>
> 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 Fri, Dec 20, 2024 at 02:45:09AM +0000, Carlos Song wrote:
> >
> >
> > > -----Original Message-----
> > > From: Oleksij Rempel <o.rempel at pengutronix.de>
> > > Sent: Thursday, December 19, 2024 8:23 PM
> > > To: Andi Shyti <andi.shyti at kernel.org>
> > > Cc: Carlos Song <carlos.song at nxp.com>; Frank Li <frank.li at nxp.com>;
> > > kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> > > festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> > > linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> > > Clark Wang <xiaoning.wang at nxp.com>; Ahmad Fatoum
> > > <a.fatoum at pengutronix.de>
> > > Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
> > >
> > > 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, Dec 19, 2024 at 01:02:29PM +0100, Andi Shyti wrote:
> > > > Hi Carlos,
> > > >
> > > > > +   /*
> > > > > +    * Init DMA config if supported, -ENODEV means DMA not enabled
> at
> > > > > +    * this platform, that is not a real error, so just remind "only
> > > > > +    * PIO mode is used". If DMA is enabled, but meet error when
> request
> > > > > +    * DMA channel, error should be showed in probe error log. PIO
> mode
> > > > > +    * should be available regardless of DMA.
> > > > > +    */
> > > > > +   ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> > > > > +   if (ret) {
> > > > > +           if (ret == -EPROBE_DEFER)
> > > > > +                   goto clk_notifier_unregister;
> > > > > +           else if (ret == -ENODEV)
> > > > > +                   dev_dbg(&pdev->dev, "Only use PIO mode\n");
> > > > > +           else
> > > > > +                   dev_err_probe(&pdev->dev, ret, "Failed to
> > > > > + setup DMA, only use PIO mode\n");
> > > >
> > > > Just for understanding, should we quit in this last case, as well?
> > > >
> > > > Before we were ignoring ENODEV and EPROBE_DEFER, but now you are
> > > > making it clear that other failures like ENOMEM might happen.
> > >
> > > Good point, dev_err_probe() would not print an error in case of
> > > EPROBE_DEFER, but in this case we should only print error and continue with
> PIO.
> > >
> > Hi,
> >
> > Thank you all very much! As I comment at previous mail:
> > DMA mode should be optional for i2c-imx, because i2c-imx can accept
> > DMA mode not enabled, because it still can work in CPU mode.[1]
> > [1]https://l/
> >
> ore.kernel.org%2Fimx%2FAM0PR0402MB39374E34FD6133B5E3D414D7E82F2
> %40AM0P
> >
> R0402MB3937.eurprd04.prod.outlook.com%2F&data=05%7C02%7Ccarlos.song
> %40
> >
> nxp.com%7C5bfbfc0a74184fa1620808dd20b7c4db%7C686ea1d3bc2b4c6fa92c
> d99c5
> >
> c301635%7C0%7C0%7C638702695851431182%7CUnknown%7CTWFpbGZsb3d
> 8eyJFbXB0e
> >
> U1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIl
> d
> >
> UIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=F28DC7RUwlqd5OIyh5QMVyqa1%2
> F%2BcX2p%2
> > FsFWftgDaliA%3D&reserved=0
> >
> > Also we don't want to annoy current user without DMA[2] [2]
> > https://lore/
> > .kernel.org%2Fimx%2F20241127-analytic-azure-hamster-727fd8-mkl%40peng
> u
> >
> tronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C5bfbfc0a74184fa
> 162
> >
> 0808dd20b7c4db%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638
> 7026958
> >
> 51449521%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiI
> wLjAuM
> >
> DAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%
> 7C&s
> >
> data=y6pkewfVx7Mb0ZrPfRwDdAo69TV1eHOkRMnRq91Ec9Q%3D&reserved=0
> >
> > So we make this logic. Anyway we let the I2C controller registered whether
> DMA is available or not(except defer probe).
> > Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing happened if
> DMA is defer probed or not enabled(This is an expected).
> > However we still need i2c DMA status is known when meet an unexpected
> error, so we use dev_err_probe() to print error.
>
> Why dev_err_probe() instead of dev_err()?
>
Hi,
In patch V2 discussion, Marc suggested just return dev_err_probe(), but I don't accept it so I choose to use dev_err_probe() to print error in V3.[1]
In this case, the two APIs have the same function, do you mean dev_err() is more suitable?

[1]https://lore.kernel.org/imx/AM0PR0402MB39374E34FD6133B5E3D414D7E82F2 at AM0PR0402MB3937.eurprd04.prod.outlook.com/#t
> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C5bfbfc0a7418
> 4fa1620808dd20b7c4db%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%
> 7C638702695851464654%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiO
> nRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%
> 3D%3D%7C0%7C%7C%7C&sdata=X2AuLskzqYH9g34wfb4%2B%2Bs2OdZEW3q5
> i49V8OwKmgtw%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |


From ck.hu at mediatek.com  Thu Dec 19 22:09:43 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 06:09:43 +0000
Subject: [PATCH v3 18/33] drm/mediatek: mtk_hdmi: Move vendor/product
 strings to drm_bridge
In-Reply-To: <20241217154345.276919-19-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-19-angelogioacchino.delregno@collabora.com>
Message-ID: <c93c81878ca5f45e2b7cf16863f1e4ab85f957e5.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Move the vendor and product strings to the appropriate entries
> of struct drm_bridge and use that in mtk_hdmi_setup_spd_infoframe
> instead of having the same as function parameters.
> 
> While at it, also beautify the strings, setting them to read
> "MediaTek On-Chip HDMI".

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_hdmi.c | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index ef8dfcb77318..eb38f4b7674e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -952,15 +952,14 @@ static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi,
>         return 0;
>  }
> 
> -static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi,
> -                                       const char *vendor,
> -                                       const char *product)
> +static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi)
>  {
> +       struct drm_bridge *bridge = &hdmi->bridge;
>         struct hdmi_spd_infoframe frame;
>         u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE];
>         ssize_t err;
> 
> -       err = hdmi_spd_infoframe_init(&frame, vendor, product);
> +       err = hdmi_spd_infoframe_init(&frame, bridge->vendor, bridge->product);
>         if (err < 0) {
>                 dev_err(hdmi->dev, "Failed to initialize SPD infoframe: %zd\n",
>                         err);
> @@ -1328,7 +1327,7 @@ static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi,
>  {
>         mtk_hdmi_setup_audio_infoframe(hdmi);
>         mtk_hdmi_setup_avi_infoframe(hdmi, mode);
> -       mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI");
> +       mtk_hdmi_setup_spd_infoframe(hdmi);
>         if (mode->flags & DRM_MODE_FLAG_3D_MASK)
>                 mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode);
>  }
> @@ -1709,6 +1708,8 @@ static int mtk_hdmi_probe(struct platform_device *pdev)
>         hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
>                          | DRM_BRIDGE_OP_HPD;
>         hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
> +       hdmi->bridge.vendor = "MediaTek";
> +       hdmi->bridge.product = "On-Chip HDMI";
>         drm_bridge_add(&hdmi->bridge);
> 
>         ret = mtk_hdmi_clk_enable_audio(hdmi);
> --
> 2.47.0
> 


From o.rempel at pengutronix.de  Thu Dec 19 22:12:50 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Fri, 20 Dec 2024 07:12:50 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <20241218043541.143194-1-carlos.song@nxp.com>
 <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <Z2UK4rMxrtNsPw5V@pengutronix.de>

On Fri, Dec 20, 2024 at 05:59:38AM +0000, Carlos Song wrote:
> > > So we make this logic. Anyway we let the I2C controller registered whether
> > DMA is available or not(except defer probe).
> > > Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing happened if
> > DMA is defer probed or not enabled(This is an expected).
> > > However we still need i2c DMA status is known when meet an unexpected
> > error, so we use dev_err_probe() to print error.
> >
> > Why dev_err_probe() instead of dev_err()?
> >
> Hi,
> In patch V2 discussion, Marc suggested just return dev_err_probe(), but I don't accept it so I choose to use dev_err_probe() to print error in V3.[1]
> In this case, the two APIs have the same function, do you mean dev_err() is more suitable?

Yes, dev_err_probe() should be used in combination with return. For
example:
  return dev_err_probe(...);

It will pass the return value on exit of the function and optionally
print of the error message if it is not EPROBE_DEFER. Practically it
replace commonly used coding pattern:
  if (ret == -EPROBE_DEFER) {
    return ret;
  } else if (ret) {
    dev_err(..);
    return ret;
  }

-- 
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 a.fatoum at pengutronix.de  Thu Dec 19 22:21:36 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Fri, 20 Dec 2024 07:21:36 +0100
Subject: [PATCH 0/6] arm64: dts: freescale: imx8mp-skov: switch to nominal
 drive mode
In-Reply-To: <20241220061613.GB8295@localhost.localdomain>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
 <20241220061613.GB8295@localhost.localdomain>
Message-ID: <44278a64-7578-4109-aef3-4888627166d1@pengutronix.de>

Hello Peng,

On 20.12.24 07:16, Peng Fan wrote:
> On Thu, Dec 19, 2024 at 08:27:31AM +0100, Ahmad Fatoum wrote:
>> Unlike the i.MX8MM and i.MX8MN SoCs added earlier, the imx8mp.dtsi
>> configures some clocks at frequencies that are only validated for
>> overdrive mode, i.e., when VDD_SOC is 950 mV.
>>
>> For the Skov i.MX8MP board, we want to run the SoC at the lower voltage of
>> 850 mV though to reduce heat generation and power usage. For this to work,
>> clock rates need to adhere to the limits of the nominal drive mode.
>>
>> This is done by this series: A new imx8mp-nominal.dtsi reconfigures
>> the imx8mp.dtsi clock tree to be compatible with nominal mode, an adaptation
>> to the Linux clock driver makes it sanity check the actual clock rates against
>> the SoC operating mode's constraints and finally the Skov DT makes use
>> of it.
>>
>> Actual configuration of the VDD_SOC rail continues to happen prior to Linux
>> as well as PLL configuration that needs to happen earlier than the kernel
>> running. See the corresponding barebox patch series[1] for details.
>> Note that the barebox series didn't yet include VDD_SOC reconfiguration
>> to 850mV, that would follow once the kernel changes have been merged.
> 
> Good to see this. I had same plan to support i.MX9.
> 
> I see you introduce a new property, how about using a boot pararmeter,
> saying "mode=nominal" or "mode=overdrive". Then drivers could
> act accordingly.

I assume you would place that parameter in drivers/soc/imx/soc-imx8m.c?

That's certainly possible as well, but I think for such a hardware property,
the device tree is the natural place.

Thanks,
Ahmad

> 
> Regards,
> Peng
> 
>>
>> [1]: https://lore.kernel.org/barebox/20240503103717.1370636-1-a.fatoum at pengutronix.de/
>>
>> ---
>> Ahmad Fatoum (6):
>>      dt-bindings: clock: imx8m: document nominal/overdrive properties
>>      arm64: dts: imx8mp: Add optional nominal drive mode DTSI
>>      arm64: dts: imx8mp: add fsl,nominal-mode property into nominal.dtsi
>>      arm64: dts: freescale: imx8mp-skov: fix LDB clock rate configuration
>>      arm64: dts: freescale: imx8mp-skov: operate SoC in nominal mode
>>      clk: imx8mp: inform CCF of maximum frequency of clocks
>>
>> .../devicetree/bindings/clock/imx8m-clock.yaml     |  14 ++
>> arch/arm64/boot/dts/freescale/imx8mp-nominal.dtsi  |  64 +++++++++
>> .../arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi |   5 +-
>> .../freescale/imx8mp-skov-revb-mi1010ait-1cp1.dts  |  19 +--
>> drivers/clk/imx/clk-imx8mp.c                       | 147 +++++++++++++++++++++
>> 5 files changed, 233 insertions(+), 16 deletions(-)
>> ---
>> base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
>> change-id: 20241217-imx8m-clk-9467763dfcd8
>>
>> Best regards,
>> -- 
>> Ahmad Fatoum <a.fatoum at pengutronix.de>
>>
> 


-- 
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 a.fatoum at pengutronix.de  Thu Dec 19 22:30:28 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Fri, 20 Dec 2024 07:30:28 +0100
Subject: [PATCH 6/6] clk: imx8mp: inform CCF of maximum frequency of
 clocks
In-Reply-To: <20241220061805.GC8295@localhost.localdomain>
References: <20241219-imx8m-clk-v1-0-cfaffa087da6@pengutronix.de>
 <20241219-imx8m-clk-v1-6-cfaffa087da6@pengutronix.de>
 <20241220061805.GC8295@localhost.localdomain>
Message-ID: <22faf38d-3e64-40b8-9896-dcccefcc181a@pengutronix.de>

Hi Peng,

On 20.12.24 07:18, Peng Fan wrote:
> On Thu, Dec 19, 2024 at 08:27:37AM +0100, Ahmad Fatoum wrote:
>> The IMX8MPCEC datasheet lists maximum frequencies allowed for different
>> modules. Some of these limits are universal, but some depend on
>> whether the SoC is operating in nominal or in overdrive mode.
>>
>> The imx8mp.dtsi currently assumes overdrive mode and configures some
>> clocks in accordance with this. Boards wishing to make use of nominal
>> mode will need to override some of the clock rates manually.
>>
>> As operating the clocks outside of their allowed range can lead to
>> difficult to debug issues, it makes sense to register the maximum rates
>> allowed in the driver, so the CCF can take them into account.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>

>> +	imx8mp_clocks_apply_constraints(imx8mp_clock_common_constraints);
>> +
>> +	if (of_property_read_bool(np, "fsl,nominal-mode"))
>> +		imx8mp_clocks_apply_constraints(imx8mp_clock_nominal_constraints);
>> +	else if (of_property_read_bool(np, "fsl,overdrive-mode"))
>> +		imx8mp_clocks_apply_constraints(imx8mp_clock_overdrive_constraints);
> 
> As I replied, a boot parameter should be better? the mode is a soc level mode,
> not just clock controller.

I think it's counterproductive for a sanity check to be enforced via kernel
command-line.

The Skov board shouldn't run with overdrive frequencies and I prefer to encode
that in the same device tree, where I define the permissible VDD_SOC range
and configure the initial clock rates.

The mode is selected by the VDD_SOC voltage, but affects AFAICS only the clock
tree. IMO, the clock controller module is thus a natural place for the property.

Cheers,
Ahmad

> 
> Thanks,
> Peng
> 
>> +
>> 	err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
>> 	if (err < 0) {
>> 		dev_err(dev, "failed to register hws for i.MX8MP\n");
>>
>> -- 
>> 2.39.5
>>
> 


-- 
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 viresh.kumar at linaro.org  Thu Dec 19 22:39:09 2024
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 20 Dec 2024 12:09:09 +0530
Subject: [PATCH v3 0/7] Apple A7-A11, T2 SoC cpufreq support
In-Reply-To: <20241218182834.22334-1-towinchenmi@gmail.com>
References: <20241218182834.22334-1-towinchenmi@gmail.com>
Message-ID: <20241220063909.hrqrch5fy44nywl2@vireshk-i7>

On 19-12-24, 02:25, Nick Chan wrote:
> This series add driver support for cpufreq Apple A7-A11, T2 SoCs.
> Device Tree nodes will be included in another series.
> 
> Changes since v2:
> - Use NSEC_PER_USEC instead of 1000 as multplier.
> 
> v2: https://lore.kernel.org/asahi/20241212070344.3858-1-towinchenmi at gmail.com/T

Applied. Thanks.

-- 
viresh


From quic_luoj at quicinc.com  Thu Dec 19 22:43:51 2024
From: quic_luoj at quicinc.com (Jie Luo)
Date: Fri, 20 Dec 2024 14:43:51 +0800
Subject: [PATCH v6 5/5] arm64: dts: qcom: Update IPQ9574 xo_board_clk to
 use fixed factor clock
In-Reply-To: <fb9d117e-77bd-4a01-a738-f72d07f6b84c@oss.qualcomm.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-5-a5cfe09de485@quicinc.com>
 <0776a26e-56cd-4838-9b52-210ae9a1f281@oss.qualcomm.com>
 <8063460d-18ad-4e54-8232-716bad9d37c3@quicinc.com>
 <2456ab36-f48e-4aa3-88e1-aeb7895c9816@quicinc.com>
 <fb9d117e-77bd-4a01-a738-f72d07f6b84c@oss.qualcomm.com>
Message-ID: <f6930a4c-6d31-4cd9-a9ba-d6ff50e274e2@quicinc.com>



On 12/20/2024 5:28 AM, Konrad Dybcio wrote:
> On 18.12.2024 12:17 PM, Jie Luo wrote:
>>
>>
>> On 12/13/2024 6:30 PM, Jie Luo wrote:
>>>
>>>
>>> On 12/13/2024 2:33 AM, Konrad Dybcio wrote:
>>>> On 7.11.2024 10:50 AM, Luo Jie wrote:
>>>>> xo_board_clk is fixed to 24 MHZ, which is routed from WiFi output clock
>>>>> 48 MHZ (also being the reference clock of CMN PLL) divided 2 by analog
>>>>> block routing channel.
>>>>>
>>>>> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
>>>>> ---
>>>>>  ? arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 7 ++++++-
>>>>>  ? arch/arm64/boot/dts/qcom/ipq9574.dtsi??????????? | 3 ++-
>>>>>  ? 2 files changed, 8 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/ arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>>>> index 78f6a2e053d5..9a8692377176 100644
>>>>> --- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>>>> +++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>>>> @@ -174,8 +174,13 @@ &ref_48mhz_clk {
>>>>>  ????? clock-mult = <1>;
>>>>>  ? };
>>>>> +/*
>>>>> + * The frequency of xo_board_clk is fixed to 24 MHZ, which is routed
>>>>> + * from WiFi output clock 48 MHZ divided by 2.
>>>>> + */
>>>>>  ? &xo_board_clk {
>>>>> -??? clock-frequency = <24000000>;
>>>>> +??? clock-div = <2>;
>>>>> +??? clock-mult = <1>;
>>>>>  ? };
>>>>>  ? &xo_clk {
>>>>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/ dts/qcom/ipq9574.dtsi
>>>>> index 8246a00a3e3e..25aed33e9358 100644
>>>>> --- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>>>>> +++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>>>>> @@ -32,7 +32,8 @@ sleep_clk: sleep-clk {
>>>>>  ????????? };
>>>>>  ????????? xo_board_clk: xo-board-clk {
>>>>> -??????????? compatible = "fixed-clock";
>>>>> +??????????? compatible = "fixed-factor-clock";
>>>>> +??????????? clocks = <&ref_48mhz_clk>;
>>>>
>>>> This must be squashed with the previous patch, you can't introduce
>>>> code and replace it immediately afterwards.
>>>>
>>>> Konrad
>>
>> Hi Konrad,
>>
>> Looking at this comment again, there may have been some
>> misunderstanding. We are not introducing xo_board_clk in patch 4 of this
>> series. xo_board_clk is a pre-existing node.
>>
>> As part of this additional patch 5, we wanted to address Dmitry's
>> comment earlier in v5 (reference to comment below), by converting the
>> xo_board_clk as well to a fixed-factor clock. So it is better to keep
>> this change as a separate patch in my view. Hope this is OK.
> 
> Oh okay..
> 
> What's the difference between xo_board_clk and xo_clk then, if the
> divider is accounted for in xo_board_clk?
> 
> Konrad

Here is the clock chain for the relationship between the clocks:
xo_clk (48 MHZ or 96 MHZ)-->WiFi (mul/div)--> 48 MHZ-->CMN PLL
				               |
					       +-->fixed factor(div by 2) --> xo_board_clk (24 MHZ)

So there are two dividers (fixed factor clocks): first for generating
the 48 MHZ clock (ref-48mhz-clk) from the fixed clock source 'xo_clk',
and a second for generating the 24 MHZ 'xo_board_clk' from the 48 MHZ
ref clock.


From carlos.song at nxp.com  Thu Dec 19 22:58:16 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Fri, 20 Dec 2024 06:58:16 +0000
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <Z2UK4rMxrtNsPw5V@pengutronix.de>
References: <20241218043541.143194-1-carlos.song@nxp.com>
 <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
Message-ID: <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Oleksij Rempel <o.rempel at pengutronix.de>
> Sent: Friday, December 20, 2024 2:13 PM
> To: Carlos Song <carlos.song at nxp.com>
> Cc: Andi Shyti <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>;
> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Clark Wang
> <xiaoning.wang at nxp.com>; Ahmad Fatoum <a.fatoum at pengutronix.de>
> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
>
> 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 Fri, Dec 20, 2024 at 05:59:38AM +0000, Carlos Song wrote:
> > > > So we make this logic. Anyway we let the I2C controller registered
> > > > whether
> > > DMA is available or not(except defer probe).
> > > > Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing
> > > > happened if
> > > DMA is defer probed or not enabled(This is an expected).
> > > > However we still need i2c DMA status is known when meet an
> > > > unexpected
> > > error, so we use dev_err_probe() to print error.
> > >
> > > Why dev_err_probe() instead of dev_err()?
> > >
> > Hi,
> > In patch V2 discussion, Marc suggested just return dev_err_probe(),
> > but I don't accept it so I choose to use dev_err_probe() to print error in V3.[1]
> In this case, the two APIs have the same function, do you mean dev_err() is more
> suitable?
>
> Yes, dev_err_probe() should be used in combination with return. For
> example:
>   return dev_err_probe(...);
>
> It will pass the return value on exit of the function and optionally print of the
> error message if it is not EPROBE_DEFER. Practically it replace commonly used
> coding pattern:
>   if (ret == -EPROBE_DEFER) {
>     return ret;
>   } else if (ret) {
>     dev_err(..);
>     return ret;
>   }
>
Hi,

Get your good point. I will change my code in V6:
+       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
+       if (ret) {
+               if (ret == -EPROBE_DEFER)
+                       goto clk_notifier_unregister;
+               else if (ret == -ENODEV)
+                       dev_dbg(&pdev->dev, "Only use PIO mode\n");
+               else
+                       dev_err(&pdev->dev, "Failed to setup DMA, only use PIO mode\n");
+       }

I think this is what you want to see, right?

> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C2950266755a
> 241c00a9208dd20bd5cf2%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> %7C638702719862691439%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGki
> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ
> %3D%3D%7C0%7C%7C%7C&sdata=aIuzJP0v5C6HzOCGnCHobK9Llml3thHclTwu
> CjD13IM%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |


From a.fatoum at pengutronix.de  Thu Dec 19 23:06:25 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Fri, 20 Dec 2024 08:06:25 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <20241218043541.143194-1-carlos.song@nxp.com>
 <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>

Hello Carlos,

On 20.12.24 07:58, Carlos Song wrote:
> 
> 
>> -----Original Message-----
>> From: Oleksij Rempel <o.rempel at pengutronix.de>
>> Sent: Friday, December 20, 2024 2:13 PM
>> To: Carlos Song <carlos.song at nxp.com>
>> Cc: Andi Shyti <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>;
>> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
>> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
>> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Clark Wang
>> <xiaoning.wang at nxp.com>; Ahmad Fatoum <a.fatoum at pengutronix.de>
>> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
>>
>> 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 Fri, Dec 20, 2024 at 05:59:38AM +0000, Carlos Song wrote:
>>>>> So we make this logic. Anyway we let the I2C controller registered
>>>>> whether
>>>> DMA is available or not(except defer probe).
>>>>> Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing
>>>>> happened if
>>>> DMA is defer probed or not enabled(This is an expected).
>>>>> However we still need i2c DMA status is known when meet an
>>>>> unexpected
>>>> error, so we use dev_err_probe() to print error.
>>>>
>>>> Why dev_err_probe() instead of dev_err()?
>>>>
>>> Hi,
>>> In patch V2 discussion, Marc suggested just return dev_err_probe(),
>>> but I don't accept it so I choose to use dev_err_probe() to print error in V3.[1]
>> In this case, the two APIs have the same function, do you mean dev_err() is more
>> suitable?
>>
>> Yes, dev_err_probe() should be used in combination with return. For
>> example:
>>   return dev_err_probe(...);
>>
>> It will pass the return value on exit of the function and optionally print of the
>> error message if it is not EPROBE_DEFER. Practically it replace commonly used
>> coding pattern:
>>   if (ret == -EPROBE_DEFER) {
>>     return ret;
>>   } else if (ret) {
>>     dev_err(..);
>>     return ret;
>>   }
>>
> Hi,
> 
> Get your good point. I will change my code in V6:
> +       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> +       if (ret) {
> +               if (ret == -EPROBE_DEFER)
> +                       goto clk_notifier_unregister;
> +               else if (ret == -ENODEV)
> +                       dev_dbg(&pdev->dev, "Only use PIO mode\n");
> +               else
> +                       dev_err(&pdev->dev, "Failed to setup DMA, only use PIO mode\n");
> +       }
> 
> I think this is what you want to see, right?

This loses the information why the error happens (ret). Using dev_err_probe
even if no probe deferral is expected in that branch is perfectly fine
and the kernel-doc even points it out:

  Using this helper in your probe function is totally fine even if @err
  is known to never be -EPROBE_DEFER.

Cheers,
Ahmad

> 
>> --
>> Pengutronix e.K.                           |
>> |
>> Steuerwalder Str. 21                       |
>> http://www.pen/
>> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C2950266755a
>> 241c00a9208dd20bd5cf2%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
>> %7C638702719862691439%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGki
>> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ
>> %3D%3D%7C0%7C%7C%7C&sdata=aIuzJP0v5C6HzOCGnCHobK9Llml3thHclTwu
>> CjD13IM%3D&reserved=0  |
>> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
>> |
>> Amtsgericht Hildesheim, HRA 2686           | Fax:
>> +49-5121-206917-5555 |
> 


-- 
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 anshuman.khandual at arm.com  Thu Dec 19 23:22:33 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Dec 2024 12:52:33 +0530
Subject: [PATCH 0/7] arm64/boot: Enable EL2 requirements for FEAT_PMUv3p9
Message-ID: <20241220072240.1003352-1-anshuman.khandual@arm.com>

This series adds fine grained trap control in EL2 required for FEAT_PMUv3p9
registers like PMICNTR_EL0, PMICFILTR_EL0, and PMUACR_EL1 which are already
being used in the kernel. This is required to prevent their EL1 access trap
into EL2.

PMZR_EL0 register trap control i.e HDFGWTR2_EL2.nPMZR_EL0 remains unchanged
for now as it does not get accessed in the kernel, and there is no plan for
its access from user space.

I have taken the liberty to pick up all the review tags for patches related
to tools sysreg update from the KVM FGT2 V2 patch series posted earlier.

https://lore.kernel.org/all/20241210055311.780688-1-anshuman.khandual at arm.com/

Rob had earler mentioned about FEAT_FGT2 based trap control requirement for
FEAT_PMUv3p9 registers that are currently being used in kernel. The context
can be found here.

https://lore.kernel.org/all/20241216234251.GA629562-robh at kernel.org/

This series is based on v6.13-rc3

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Ryan Roberts <ryan.roberts at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Mark Brown <robh at kernel.org>
Cc: Rob Herring <robh at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
Cc: Jonathan Corbet <corbet at lwn.net>
Cc: Eric Auger <eric.auger at redhat.com>
Cc: kvmarm at lists.linux.dev
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org

Anshuman Khandual (7):
  arm64/sysreg: Update register fields for ID_AA64MMFR0_EL1
  arm64/sysreg: Add register fields for HDFGRTR2_EL2
  arm64/sysreg: Add register fields for HDFGWTR2_EL2
  arm64/sysreg: Add register fields for HFGITR2_EL2
  arm64/sysreg: Add register fields for HFGRTR2_EL2
  arm64/sysreg: Add register fields for HFGWTR2_EL2
  arm64/boot: Enable EL2 requirements for FEAT_PMUv3p9

 Documentation/arch/arm64/booting.rst |  18 +++++
 arch/arm64/include/asm/el2_setup.h   |  25 +++++++
 arch/arm64/tools/sysreg              | 103 +++++++++++++++++++++++++++
 3 files changed, 146 insertions(+)

-- 
2.25.1



From anshuman.khandual at arm.com  Thu Dec 19 23:22:34 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Dec 2024 12:52:34 +0530
Subject: [PATCH 1/7] arm64/sysreg: Update register fields for ID_AA64MMFR0_EL1
In-Reply-To: <20241220072240.1003352-1-anshuman.khandual@arm.com>
References: <20241220072240.1003352-1-anshuman.khandual@arm.com>
Message-ID: <20241220072240.1003352-2-anshuman.khandual@arm.com>

This updates ID_AA64MMFR0_EL1 register fields as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Eric Auger <eric.auger at redhat.com>
Reviewed-by: Mark Brown <broonie at 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 b081b54d6d22..a6cbe0dcd63b 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1591,6 +1591,7 @@ EndEnum
 UnsignedEnum	59:56	FGT
 	0b0000	NI
 	0b0001	IMP
+	0b0010	FGT2
 EndEnum
 Res0	55:48
 UnsignedEnum	47:44	EXS
@@ -1652,6 +1653,7 @@ Enum	3:0	PARANGE
 	0b0100	44
 	0b0101	48
 	0b0110	52
+	0b0111	56
 EndEnum
 EndSysreg
 
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Dec 19 23:22:35 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Dec 2024 12:52:35 +0530
Subject: [PATCH 2/7] arm64/sysreg: Add register fields for HDFGRTR2_EL2
In-Reply-To: <20241220072240.1003352-1-anshuman.khandual@arm.com>
References: <20241220072240.1003352-1-anshuman.khandual@arm.com>
Message-ID: <20241220072240.1003352-3-anshuman.khandual@arm.com>

This adds register fields for HDFGRTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Eric Auger <eric.auger at redhat.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a6cbe0dcd63b..9ce8602dd40f 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2546,6 +2546,35 @@ Field	1	ICIALLU
 Field	0	ICIALLUIS
 EndSysreg
 
+Sysreg HDFGRTR2_EL2	3	4	3	1	0
+Res0	63:25
+Field	24	nPMBMAR_EL1
+Field	23	nMDSTEPOP_EL1
+Field	22	nTRBMPAM_EL1
+Res0	21
+Field	20	nTRCITECR_EL1
+Field	19	nPMSDSFR_EL1
+Field	18	nSPMDEVAFF_EL1
+Field	17	nSPMID
+Field	16	nSPMSCR_EL1
+Field	15	nSPMACCESSR_EL1
+Field	14	nSPMCR_EL0
+Field	13	nSPMOVS
+Field	12	nSPMINTEN
+Field	11	nSPMCNTEN
+Field	10	nSPMSELR_EL0
+Field	9	nSPMEVTYPERn_EL0
+Field	8	nSPMEVCNTRn_EL0
+Field	7	nPMSSCR_EL1
+Field	6	nPMSSDATA
+Field	5	nMDSELR_EL1
+Field	4	nPMUACR_EL1
+Field	3	nPMICFILTR_EL0
+Field	2	nPMICNTR_EL0
+Field	1	nPMIAR_EL1
+Field	0	nPMECR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Dec 19 23:22:36 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Dec 2024 12:52:36 +0530
Subject: [PATCH 3/7] arm64/sysreg: Add register fields for HDFGWTR2_EL2
In-Reply-To: <20241220072240.1003352-1-anshuman.khandual@arm.com>
References: <20241220072240.1003352-1-anshuman.khandual@arm.com>
Message-ID: <20241220072240.1003352-4-anshuman.khandual@arm.com>

This adds register fields for HDFGWTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Eric Auger <eric.auger at redhat.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 9ce8602dd40f..f5a1fa75ec72 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2575,6 +2575,34 @@ Field	1	nPMIAR_EL1
 Field	0	nPMECR_EL1
 EndSysreg
 
+Sysreg HDFGWTR2_EL2	3	4	3	1	1
+Res0	63:25
+Field	24	nPMBMAR_EL1
+Field	23	nMDSTEPOP_EL1
+Field	22	nTRBMPAM_EL1
+Field	21	nPMZR_EL0
+Field	20	nTRCITECR_EL1
+Field	19	nPMSDSFR_EL1
+Res0	18:17
+Field	16	nSPMSCR_EL1
+Field	15	nSPMACCESSR_EL1
+Field	14	nSPMCR_EL0
+Field	13	nSPMOVS
+Field	12	nSPMINTEN
+Field	11	nSPMCNTEN
+Field	10	nSPMSELR_EL0
+Field	9	nSPMEVTYPERn_EL0
+Field	8	nSPMEVCNTRn_EL0
+Field	7	nPMSSCR_EL1
+Res0	6
+Field	5	nMDSELR_EL1
+Field	4	nPMUACR_EL1
+Field	3	nPMICFILTR_EL0
+Field	2	nPMICNTR_EL0
+Field	1	nPMIAR_EL1
+Field	0	nPMECR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Dec 19 23:22:37 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Dec 2024 12:52:37 +0530
Subject: [PATCH 4/7] arm64/sysreg: Add register fields for HFGITR2_EL2
In-Reply-To: <20241220072240.1003352-1-anshuman.khandual@arm.com>
References: <20241220072240.1003352-1-anshuman.khandual@arm.com>
Message-ID: <20241220072240.1003352-5-anshuman.khandual@arm.com>

This adds register fields for HFGITR2_EL2 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Eric Auger <eric.auger at redhat.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index f5a1fa75ec72..088e3be8f884 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2775,6 +2775,12 @@ Field	1	AMEVCNTR00_EL0
 Field	0	AMCNTEN0
 EndSysreg
 
+Sysreg	HFGITR2_EL2	3	4	3	1	7
+Res0	63:2
+Field	1	nDCCIVAPS
+Field	0	TSBCSYNC
+EndSysreg
+
 Sysreg	ZCR_EL2	3	4	1	2	0
 Fields	ZCR_ELx
 EndSysreg
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Dec 19 23:22:38 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Dec 2024 12:52:38 +0530
Subject: [PATCH 5/7] arm64/sysreg: Add register fields for HFGRTR2_EL2
In-Reply-To: <20241220072240.1003352-1-anshuman.khandual@arm.com>
References: <20241220072240.1003352-1-anshuman.khandual@arm.com>
Message-ID: <20241220072240.1003352-6-anshuman.khandual@arm.com>

This adds register fields for HFGRTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Eric Auger <eric.auger at redhat.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 088e3be8f884..0875e0057706 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2603,6 +2603,25 @@ Field	1	nPMIAR_EL1
 Field	0	nPMECR_EL1
 EndSysreg
 
+Sysreg	HFGRTR2_EL2	3	4	3	1	2
+Res0	63:15
+Field	14	nACTLRALIAS_EL1
+Field	13	nACTLRMASK_EL1
+Field	12	nTCR2ALIAS_EL1
+Field	11	nTCRALIAS_EL1
+Field	10	nSCTLRALIAS2_EL1
+Field	9	nSCTLRALIAS_EL1
+Field	8	nCPACRALIAS_EL1
+Field	7	nTCR2MASK_EL1
+Field	6	nTCRMASK_EL1
+Field	5	nSCTLR2MASK_EL1
+Field	4	nSCTLRMASK_EL1
+Field	3	nCPACRMASK_EL1
+Field	2	nRCWSMASK_EL1
+Field	1	nERXGSR_EL1
+Field	0	nPFAR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Dec 19 23:22:39 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Dec 2024 12:52:39 +0530
Subject: [PATCH 6/7] arm64/sysreg: Add register fields for HFGWTR2_EL2
In-Reply-To: <20241220072240.1003352-1-anshuman.khandual@arm.com>
References: <20241220072240.1003352-1-anshuman.khandual@arm.com>
Message-ID: <20241220072240.1003352-7-anshuman.khandual@arm.com>

This adds register fields for HFGWTR2_EL2 as per the definitions based
on DDI0601 2024-09.

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
Reviewed-by: Eric Auger <eric.auger at redhat.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/tools/sysreg | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 0875e0057706..268f1b808e3f 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2622,6 +2622,25 @@ Field	1	nERXGSR_EL1
 Field	0	nPFAR_EL1
 EndSysreg
 
+Sysreg	HFGWTR2_EL2	3	4	3	1	3
+Res0	63:15
+Field	14	nACTLRALIAS_EL1
+Field	13	nACTLRMASK_EL1
+Field	12	nTCR2ALIAS_EL1
+Field	11	nTCRALIAS_EL1
+Field	10	nSCTLRALIAS2_EL1
+Field	9	nSCTLRALIAS_EL1
+Field	8	nCPACRALIAS_EL1
+Field	7	nTCR2MASK_EL1
+Field	6	nTCRMASK_EL1
+Field	5	nSCTLR2MASK_EL1
+Field	4	nSCTLRMASK_EL1
+Field	3	nCPACRMASK_EL1
+Field	2	nRCWSMASK_EL1
+Res0	1
+Field	0	nPFAR_EL1
+EndSysreg
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Dec 19 23:22:40 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Dec 2024 12:52:40 +0530
Subject: [PATCH 7/7] arm64/boot: Enable EL2 requirements for FEAT_PMUv3p9
In-Reply-To: <20241220072240.1003352-1-anshuman.khandual@arm.com>
References: <20241220072240.1003352-1-anshuman.khandual@arm.com>
Message-ID: <20241220072240.1003352-8-anshuman.khandual@arm.com>

FEAT_PMUv3p9 registers such as PMICNTR_EL0, PMICFILTR_EL0, and PMUACR_EL1
access from EL1 requires appropriate EL2 fine grained trap configuration
via FEAT_FGT2 based trap control registers HDFGRTR2_EL2 and HDFGWTR2_EL2.
Otherwise such register accesses will result in traps into EL2.

Add a new helper __init_el2_fgt2() which initializes FEAT_FGT2 based fine
grained trap control registers HDFGRTR2_EL2 and HDFGWTR2_EL2 (setting the
bits nPMICNTR_EL0, nPMICFILTR_EL0 and nPMUACR_EL1) to enable access into
PMICNTR_EL0, PMICFILTR_EL0, and PMUACR_EL1 registers.

Also update booting.rst with SCR_EL3.FGTEn2 requirement for all FEAT_FGT2
based registers to be accessible in EL2.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Rob Herring <robh at kernel.org>
Cc: Jonathan Corbet <corbet at lwn.net>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: kvmarm at lists.linux.dev
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arch/arm64/booting.rst | 18 ++++++++++++++++++
 arch/arm64/include/asm/el2_setup.h   | 25 +++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
index 3278fb4bf219..57ca46577084 100644
--- a/Documentation/arch/arm64/booting.rst
+++ b/Documentation/arch/arm64/booting.rst
@@ -288,6 +288,12 @@ Before jumping into the kernel, the following conditions must be met:
 
     - SCR_EL3.FGTEn (bit 27) must be initialised to 0b1.
 
+  For CPUs with the Fine Grained Traps 2 (FEAT_FGT2) extension present:
+
+  - If EL3 is present and the kernel is entered at EL2:
+
+    - SCR_EL3.FGTEn2 (bit 59) must be initialised to 0b1.
+
   For CPUs with support for HCRX_EL2 (FEAT_HCX) present:
 
   - If EL3 is present and the kernel is entered at EL2:
@@ -382,6 +388,18 @@ Before jumping into the kernel, the following conditions must be met:
 
     - SMCR_EL2.EZT0 (bit 30) must be initialised to 0b1.
 
+  For CPUs with the Performance Monitors Extension (FEAT_PMUv3p9):
+
+ - If the kernel is entered at EL1 and EL2 is present:
+
+    - HDFGRTR2_EL2.nPMICNTR_EL0 (bit 2) must be initialised to 0b1.
+    - HDFGRTR2_EL2.nPMICFILTR_EL0 (bit 3) must be initialised to 0b1.
+    - HDFGRTR2_EL2.nPMUACR_EL1 (bit 4) must be initialised to 0b1.
+
+    - HDFGWTR2_EL2.nPMICNTR_EL0 (bit 2) must be initialised to 0b1.
+    - HDFGWTR2_EL2.nPMICFILTR_EL0 (bit 3) must be initialised to 0b1.
+    - HDFGWTR2_EL2.nPMUACR_EL1 (bit 4) must be initialised to 0b1.
+
   For CPUs with Memory Copy and Memory Set instructions (FEAT_MOPS):
 
   - If the kernel is entered at EL1 and EL2 is present:
diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 4ef52d7245bb..9e44c13711e5 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -233,6 +233,30 @@
 .Lskip_fgt_\@:
 .endm
 
+.macro __init_el2_fgt2
+	mrs	x1, id_aa64mmfr0_el1
+	ubfx	x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
+	cmp	x1, #ID_AA64MMFR0_EL1_FGT_FGT2
+	b.lt	.Lskip_fgt2_\@
+
+	mov	x0, xzr
+	mrs	x1, id_aa64dfr0_el1
+	ubfx	x1, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
+	cmp	x1, #ID_AA64DFR0_EL1_PMUVer_V3P9
+	b.lt	.Lskip_pmuv3p9_\@
+
+	orr	x0, x0, #HDFGRTR2_EL2_nPMICNTR_EL0
+	orr	x0, x0, #HDFGRTR2_EL2_nPMICFILTR_EL0
+	orr	x0, x0, #HDFGRTR2_EL2_nPMUACR_EL1
+.Lskip_pmuv3p9_\@:
+	msr_s   SYS_HDFGRTR2_EL2, x0
+	msr_s   SYS_HDFGWTR2_EL2, x0
+	msr_s   SYS_HFGRTR2_EL2, xzr
+	msr_s   SYS_HFGWTR2_EL2, xzr
+	msr_s   SYS_HFGITR2_EL2, xzr
+.Lskip_fgt2_\@:
+.endm
+
 .macro __init_el2_gcs
 	mrs_s	x1, SYS_ID_AA64PFR1_EL1
 	ubfx	x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
@@ -283,6 +307,7 @@
 	__init_el2_nvhe_idregs
 	__init_el2_cptr
 	__init_el2_fgt
+	__init_el2_fgt2
         __init_el2_gcs
 .endm
 
-- 
2.25.1



From ck.hu at mediatek.com  Thu Dec 19 23:25:41 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 07:25:41 +0000
Subject: [PATCH v3 21/33] drm/mediatek: mtk_hdmi: Remove unused members of
 struct mtk_hdmi
In-Reply-To: <20241217154345.276919-22-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-22-angelogioacchino.delregno@collabora.com>
Message-ID: <8531b18b1e98156e315e3a20506c3e9f274712fe.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> The hdmi_colorspace csp member of struct mtk_hdmi is initialized
> once but then it's never used at all.
> Remove said member and the only assignment to it as a cleanup.
> 
> Also remove the ibias, ibias_up, min_clock, max_clock, min_hdisplay
> and max_vdisplay members, as those were really completely unused.
> 
> This commit brings no functional changes.

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_hdmi.c | 8 --------
>  1 file changed, 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index c95c7b55998c..3ecd0ed59851 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -162,16 +162,9 @@ struct mtk_hdmi {
>         struct clk *clk[MTK_HDMI_CLK_COUNT];
>         struct drm_display_mode mode;
>         bool dvi_mode;
> -       u32 min_clock;
> -       u32 max_clock;
> -       u32 max_hdisplay;
> -       u32 max_vdisplay;
> -       u32 ibias;
> -       u32 ibias_up;
>         struct regmap *sys_regmap;
>         unsigned int sys_offset;
>         struct regmap *regs;
> -       enum hdmi_colorspace csp;
>         struct platform_device *audio_pdev;
>         struct hdmi_audio_param aud_param;
>         bool audio_enable;
> @@ -1036,7 +1029,6 @@ static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
>  {
>         struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> 
> -       hdmi->csp = HDMI_COLORSPACE_RGB;
>         aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
>         aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
>         aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> --
> 2.47.0
> 


From tomi.valkeinen at ideasonboard.com  Thu Dec 19 23:29:40 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Fri, 20 Dec 2024 09:29:40 +0200
Subject: [PATCH] drm: xlnx: zynqmp_dpsub: Fix kernel doc
Message-ID: <20241220-xilinx-dp-audio-doc-fix-v1-1-cc488996e463@ideasonboard.com>

Fix two kernel doc warnings introduced by the recent DP audio patch:

- Add a doc line for the new "audio" field
- Remove a reference to zynqmp_dpsub.c from zynqmp.rst, as the .c file
  no longer has structured comments

Fixes: 3ec5c1579305 ("drm: xlnx: zynqmp_dpsub: Add DP audio support")
Closes: https://lore.kernel.org/all/20241220154208.720d990b at canb.auug.org.au/
Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 Documentation/gpu/zynqmp.rst        | 2 --
 drivers/gpu/drm/xlnx/zynqmp_dpsub.h | 1 +
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/Documentation/gpu/zynqmp.rst b/Documentation/gpu/zynqmp.rst
index f57bfa0ad6ec..1a6f9193de22 100644
--- a/Documentation/gpu/zynqmp.rst
+++ b/Documentation/gpu/zynqmp.rst
@@ -144,6 +144,4 @@ Internals
 
 .. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_dp.c
 
-.. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_dpsub.c
-
 .. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_kms.c
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
index 49875529c2a4..d771b8b199e0 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
@@ -60,6 +60,7 @@ struct zynqmp_dpsub_audio;
  * @layers: Video and graphics layers
  * @dp: The DisplayPort controller
  * @dma_align: DMA alignment constraint (must be a power of 2)
+ * @audio: DP audio data
  */
 struct zynqmp_dpsub {
 	struct device *dev;

---
base-commit: 74ef9527bd87ead62deabe749a6d867af748d448
change-id: 20241220-xilinx-dp-audio-doc-fix-0651029616e7

Best regards,
-- 
Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>



From o.rempel at pengutronix.de  Thu Dec 19 23:35:05 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Fri, 20 Dec 2024 08:35:05 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
References: <20241218043541.143194-1-carlos.song@nxp.com>
 <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
Message-ID: <Z2UeKZcpeRUt2OQ4@pengutronix.de>

On Fri, Dec 20, 2024 at 08:06:25AM +0100, Ahmad Fatoum wrote:
> Hello Carlos,
> 
> On 20.12.24 07:58, Carlos Song wrote:
> > 
> > 
> >> -----Original Message-----
> >> From: Oleksij Rempel <o.rempel at pengutronix.de>
> >> Sent: Friday, December 20, 2024 2:13 PM
> >> To: Carlos Song <carlos.song at nxp.com>
> >> Cc: Andi Shyti <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>;
> >> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> >> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> >> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Clark Wang
> >> <xiaoning.wang at nxp.com>; Ahmad Fatoum <a.fatoum at pengutronix.de>
> >> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
> >>
> >> 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 Fri, Dec 20, 2024 at 05:59:38AM +0000, Carlos Song wrote:
> >>>>> So we make this logic. Anyway we let the I2C controller registered
> >>>>> whether
> >>>> DMA is available or not(except defer probe).
> >>>>> Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing
> >>>>> happened if
> >>>> DMA is defer probed or not enabled(This is an expected).
> >>>>> However we still need i2c DMA status is known when meet an
> >>>>> unexpected
> >>>> error, so we use dev_err_probe() to print error.
> >>>>
> >>>> Why dev_err_probe() instead of dev_err()?
> >>>>
> >>> Hi,
> >>> In patch V2 discussion, Marc suggested just return dev_err_probe(),
> >>> but I don't accept it so I choose to use dev_err_probe() to print error in V3.[1]
> >> In this case, the two APIs have the same function, do you mean dev_err() is more
> >> suitable?
> >>
> >> Yes, dev_err_probe() should be used in combination with return. For
> >> example:
> >>   return dev_err_probe(...);
> >>
> >> It will pass the return value on exit of the function and optionally print of the
> >> error message if it is not EPROBE_DEFER. Practically it replace commonly used
> >> coding pattern:
> >>   if (ret == -EPROBE_DEFER) {
> >>     return ret;
> >>   } else if (ret) {
> >>     dev_err(..);
> >>     return ret;
> >>   }
> >>
> > Hi,
> > 
> > Get your good point. I will change my code in V6:
> > +       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> > +       if (ret) {
> > +               if (ret == -EPROBE_DEFER)
> > +                       goto clk_notifier_unregister;
> > +               else if (ret == -ENODEV)
> > +                       dev_dbg(&pdev->dev, "Only use PIO mode\n");
> > +               else
> > +                       dev_err(&pdev->dev, "Failed to setup DMA, only use PIO mode\n");
> > +       }
> > 
> > I think this is what you want to see, right?
> 
> This loses the information why the error happens (ret). Using dev_err_probe
> even if no probe deferral is expected in that branch is perfectly fine
> and the kernel-doc even points it out:
> 
>   Using this helper in your probe function is totally fine even if @err
>   is known to never be -EPROBE_DEFER.

Thank you for the feedback. While I recognize the benefits of
dev_err_probe() for compact and standardized error handling, using it
without returning its result raises a red flag.

The function's primary purpose is to combine error logging with
returning the error code. If the return value is not used, it can create
confusion and suggests potential oversight or unintended behavior. This
misuse might mislead readers into thinking that the function always
returns at that point, which is not the case here.

In this scenario, using dev_err() directly is more explicit and avoids
any ambiguity about the control flow or error handling intent. It keeps
the code clear and aligned with its actual behavior.

-- 
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 carlos.song at nxp.com  Thu Dec 19 23:38:47 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Fri, 20 Dec 2024 07:38:47 +0000
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <Z2UeKZcpeRUt2OQ4@pengutronix.de>
References: <20241218043541.143194-1-carlos.song@nxp.com>
 <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
 <Z2UeKZcpeRUt2OQ4@pengutronix.de>
Message-ID: <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Oleksij Rempel <o.rempel at pengutronix.de>
> Sent: Friday, December 20, 2024 3:35 PM
> To: Ahmad Fatoum <a.fatoum at pengutronix.de>
> Cc: Carlos Song <carlos.song at nxp.com>; Andi Shyti <andi.shyti at kernel.org>;
> Frank Li <frank.li at nxp.com>; kernel at pengutronix.de; shawnguo at kernel.org;
> s.hauer at pengutronix.de; festevam at gmail.com; linux-i2c at vger.kernel.org;
> imx at lists.linux.dev; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org; Clark Wang <xiaoning.wang at nxp.com>
> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
>
> 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 Fri, Dec 20, 2024 at 08:06:25AM +0100, Ahmad Fatoum wrote:
> > Hello Carlos,
> >
> > On 20.12.24 07:58, Carlos Song wrote:
> > >
> > >
> > >> -----Original Message-----
> > >> From: Oleksij Rempel <o.rempel at pengutronix.de>
> > >> Sent: Friday, December 20, 2024 2:13 PM
> > >> To: Carlos Song <carlos.song at nxp.com>
> > >> Cc: Andi Shyti <andi.shyti at kernel.org>; Frank Li
> > >> <frank.li at nxp.com>; kernel at pengutronix.de; shawnguo at kernel.org;
> > >> s.hauer at pengutronix.de; festevam at gmail.com;
> > >> linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> > >> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> > >> Clark Wang <xiaoning.wang at nxp.com>; Ahmad Fatoum
> > >> <a.fatoum at pengutronix.de>
> > >> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
> > >>
> > >> 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 Fri, Dec 20, 2024 at 05:59:38AM +0000, Carlos Song wrote:
> > >>>>> So we make this logic. Anyway we let the I2C controller
> > >>>>> registered whether
> > >>>> DMA is available or not(except defer probe).
> > >>>>> Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing
> > >>>>> happened if
> > >>>> DMA is defer probed or not enabled(This is an expected).
> > >>>>> However we still need i2c DMA status is known when meet an
> > >>>>> unexpected
> > >>>> error, so we use dev_err_probe() to print error.
> > >>>>
> > >>>> Why dev_err_probe() instead of dev_err()?
> > >>>>
> > >>> Hi,
> > >>> In patch V2 discussion, Marc suggested just return
> > >>> dev_err_probe(), but I don't accept it so I choose to use
> > >>> dev_err_probe() to print error in V3.[1]
> > >> In this case, the two APIs have the same function, do you mean
> > >> dev_err() is more suitable?
> > >>
> > >> Yes, dev_err_probe() should be used in combination with return. For
> > >> example:
> > >>   return dev_err_probe(...);
> > >>
> > >> It will pass the return value on exit of the function and
> > >> optionally print of the error message if it is not EPROBE_DEFER.
> > >> Practically it replace commonly used coding pattern:
> > >>   if (ret == -EPROBE_DEFER) {
> > >>     return ret;
> > >>   } else if (ret) {
> > >>     dev_err(..);
> > >>     return ret;
> > >>   }
> > >>
> > > Hi,
> > >
> > > Get your good point. I will change my code in V6:
> > > +       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> > > +       if (ret) {
> > > +               if (ret == -EPROBE_DEFER)
> > > +                       goto clk_notifier_unregister;
> > > +               else if (ret == -ENODEV)
> > > +                       dev_dbg(&pdev->dev, "Only use PIO
> mode\n");
> > > +               else
> > > +                       dev_err(&pdev->dev, "Failed to setup DMA,
> only use PIO mode\n");
> > > +       }
> > >
> > > I think this is what you want to see, right?
> >
> > This loses the information why the error happens (ret). Using
> > dev_err_probe even if no probe deferral is expected in that branch is
> > perfectly fine and the kernel-doc even points it out:
> >
> >   Using this helper in your probe function is totally fine even if @err
> >   is known to never be -EPROBE_DEFER.
>
> Thank you for the feedback. While I recognize the benefits of
> dev_err_probe() for compact and standardized error handling, using it without
> returning its result raises a red flag.
>
> The function's primary purpose is to combine error logging with returning the
> error code. If the return value is not used, it can create confusion and suggests
> potential oversight or unintended behavior. This misuse might mislead readers
> into thinking that the function always returns at that point, which is not the case
> here.
>
> In this scenario, using dev_err() directly is more explicit and avoids any ambiguity
> about the control flow or error handling intent. It keeps the code clear and
> aligned with its actual behavior.
>

how about this?

+       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
+       if (ret) {
+               if (ret == -EPROBE_DEFER)
+                       goto clk_notifier_unregister;
+               else if (ret == -ENODEV)
+                       dev_dbg(&pdev->dev, "Only use PIO mode\n");
+               else
+                       dev_err(&pdev->dev, "Failed to setup DMA (%d), only use PIO mode\n", ret);
+       }

We can both know the error and also use dev_err() directly.
> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7Cae12fdac9f63
> 4b7d7d9408dd20c8d8b6%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> %7C638702769209008171%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGki
> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ
> %3D%3D%7C0%7C%7C%7C&sdata=DKjI9z82LWvymmNmnTRo33F9F%2FBOBb
> Wc7In0RS1xAPs%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |


From zengheng4 at huawei.com  Thu Dec 19 23:45:36 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Fri, 20 Dec 2024 15:45:36 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 5/5] arm_mpam:
 Adapting the closid/rmid matching determination functions
In-Reply-To: <Z1sNHFhpYlPvVANC@e133380.arm.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
 <20241207092136.2488426-6-zengheng4@huawei.com>
 <Z1sNHFhpYlPvVANC@e133380.arm.com>
Message-ID: <b6fe1fdb-5c28-9a2e-c000-12b26a6222b7@huawei.com>



On 2024/12/13 0:19, Dave Martin wrote:
> Hi,
> 
> On Sat, Dec 07, 2024 at 05:21:36PM +0800, Zeng Heng wrote:
>> According to the previous patches, add the inverse functions for the
>> closid/rmid conversion functions to serve as the conversion functions for
>> reqpartid/pmg. And adapt the matching determination functions
>> resctrl_arch_match_closid() and resctrl_arch_match_rmid() by the inverse
>> functions.
>>
>> For the same reason, when updating the (req)PARTID/PMG pair for a task,
>> the new conversion functions also are used for adaptation.
>>
>> Signed-off-by: Zeng Heng <zengheng4 at huawei.com>
>> ---
>>   arch/arm64/include/asm/mpam.h              |  6 ++-
>>   drivers/platform/arm64/mpam/mpam_resctrl.c | 63 +++++++++++++++-------
>>   2 files changed, 47 insertions(+), 22 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h
>> index e5f385767174..9fc095530671 100644
>> --- a/arch/arm64/include/asm/mpam.h
>> +++ b/arch/arm64/include/asm/mpam.h
>> @@ -93,6 +93,8 @@ static inline u64 mpam_get_regval(struct task_struct *tsk)
>>   #endif
>>   }
>>   
>> +u32 rmid2pmg(u32 rmid);
>> +
>>   static inline void resctrl_arch_set_rmid(struct task_struct *tsk, u32 rmid)
>>   {
>>   #ifdef CONFIG_ARM64_MPAM
>> @@ -100,8 +102,8 @@ static inline void resctrl_arch_set_rmid(struct task_struct *tsk, u32 rmid)
>>   
>>   	regval &= ~MPAM1_EL1_PMG_D;
>>   	regval &= ~MPAM1_EL1_PMG_I;
>> -	regval |= FIELD_PREP(MPAM1_EL1_PMG_D, rmid);
>> -	regval |= FIELD_PREP(MPAM1_EL1_PMG_I, rmid);
>> +	regval |= FIELD_PREP(MPAM1_EL1_PMG_D, rmid2pmg(rmid));
>> +	regval |= FIELD_PREP(MPAM1_EL1_PMG_I, rmid2pmg(rmid));
> 
> Note, this function does not seem to be used; I added a patch in my
> series [1] to get rid of it instead of converting it.
> 

At that time, I was still hesitating whether to directly delete that 
function. Yes, I will skip the adaptation of this function.

>>   
>>   	WRITE_ONCE(task_thread_info(tsk)->mpam_partid_pmg, regval);
>>   #endif
>> diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
> 
> [...]
> 
>>   void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid, u32 rmid)
>>   {
>> -	BUG_ON(closid > U16_MAX);
>> -	BUG_ON(rmid > U8_MAX);
>> +	u32 reqpartid = closid_rmid2reqpartid(closid, rmid);
>> +	u32 pmg = rmid2pmg(rmid);
>> +	u32 partid_d, partid_i;
>> +
>> +	BUG_ON(reqpartid > U16_MAX);
>> +	BUG_ON(pmg > U8_MAX);
>>   
>>   	if (!cdp_enabled) {
>> -		mpam_set_cpu_defaults(cpu, closid, closid, rmid, rmid);
>> +		mpam_set_cpu_defaults(cpu, reqpartid, reqpartid, pmg, pmg);
>>   	} else {
>>   		/*
>>   		 * When CDP is enabled, resctrl halves the closid range and we
>>   		 * use odd/even partid for one closid.
>>   		 */
>> -		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
>> -		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
>> +		partid_d = resctrl_get_config_index(reqpartid, CDP_DATA);
>> +		partid_i = resctrl_get_config_index(reqpartid, CDP_CODE);
>>   
>> -		mpam_set_cpu_defaults(cpu, partid_d, partid_i, rmid, rmid);
>> +		mpam_set_cpu_defaults(cpu, partid_d, partid_i, pmg, pmg);
> 
> Prior to this patch, will the PARTID and/or PMG programmed for a
> control group be different from the PARTID and/or PMG used to program
> the MSCs?
> 
> If so, those changes probably need to be in the same patch.
> 

Thanks to point it out. It's reasonable to put setting PARTID/PMG 
operations together with the closid/rmid pair remapping.

> 
>> @@ -289,41 +307,46 @@ void resctrl_arch_sync_cpu_closid_rmid(void *info)
> 
> [...]
> 
>>   /* The task's pmg is not unique, the partid must be considered too */
>>   bool resctrl_arch_match_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
>>   {
>>   	u64 regval = mpam_get_regval(tsk);
>> -	u32 tsk_closid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
>> -	u32 tsk_rmid = FIELD_GET(MPAM1_EL1_PMG_D, regval);
>> +	u32 tsk_pmg = FIELD_GET(MPAM1_EL1_PMG_D, regval);
>> +	u32 tsk_partid = FIELD_GET(MPAM1_EL1_PARTID_D, regval);
>>   
>>   	if (cdp_enabled)
>> -		tsk_closid >>= 1;
>> +		tsk_partid >>= 1;
>>   
>> -	return (tsk_closid == closid) && (tsk_rmid == rmid);
>> +	return (reqpartid2closid(tsk_partid) == closid) &&
>> +	       (reqpartid_pmg2rmid(tsk_partid, tsk_pmg) == rmid);
> 
> Do we actually need the reverse mappings here?
> 
> It doesn't really matter which ID namespace is used for the
> comparison, so in my version of this I converted the passed-in closid
> and rmid to PARTID / PMG form and then compared those with tsk's
> values.
> 
> (But if I've missed some subtlety here, please let me know!)
> 

Yes, we actually don't need the reverse mappings, and reuse the
closid_rmid2reqpartid() and rmid2pmg() to finish the comparison.

Best regards,
Zeng Heng


From o.rempel at pengutronix.de  Thu Dec 19 23:45:59 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Fri, 20 Dec 2024 08:45:59 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
 <Z2UeKZcpeRUt2OQ4@pengutronix.de>
 <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <Z2Ugt8NVued0_4c4@pengutronix.de>

On Fri, Dec 20, 2024 at 07:38:47AM +0000, Carlos Song wrote:
> 
> 
> > -----Original Message-----
> > From: Oleksij Rempel <o.rempel at pengutronix.de>
> > Sent: Friday, December 20, 2024 3:35 PM
> > To: Ahmad Fatoum <a.fatoum at pengutronix.de>
> > Cc: Carlos Song <carlos.song at nxp.com>; Andi Shyti <andi.shyti at kernel.org>;
> > Frank Li <frank.li at nxp.com>; kernel at pengutronix.de; shawnguo at kernel.org;
> > s.hauer at pengutronix.de; festevam at gmail.com; linux-i2c at vger.kernel.org;
> > imx at lists.linux.dev; linux-arm-kernel at lists.infradead.org;
> > linux-kernel at vger.kernel.org; Clark Wang <xiaoning.wang at nxp.com>
> > Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
> >
> > 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 Fri, Dec 20, 2024 at 08:06:25AM +0100, Ahmad Fatoum wrote:
> > > Hello Carlos,
> > >
> > > On 20.12.24 07:58, Carlos Song wrote:
> > > >
> > > >
> > > >> -----Original Message-----
> > > >> From: Oleksij Rempel <o.rempel at pengutronix.de>
> > > >> Sent: Friday, December 20, 2024 2:13 PM
> > > >> To: Carlos Song <carlos.song at nxp.com>
> > > >> Cc: Andi Shyti <andi.shyti at kernel.org>; Frank Li
> > > >> <frank.li at nxp.com>; kernel at pengutronix.de; shawnguo at kernel.org;
> > > >> s.hauer at pengutronix.de; festevam at gmail.com;
> > > >> linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> > > >> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> > > >> Clark Wang <xiaoning.wang at nxp.com>; Ahmad Fatoum
> > > >> <a.fatoum at pengutronix.de>
> > > >> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
> > > >>
> > > >> 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 Fri, Dec 20, 2024 at 05:59:38AM +0000, Carlos Song wrote:
> > > >>>>> So we make this logic. Anyway we let the I2C controller
> > > >>>>> registered whether
> > > >>>> DMA is available or not(except defer probe).
> > > >>>>> Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing
> > > >>>>> happened if
> > > >>>> DMA is defer probed or not enabled(This is an expected).
> > > >>>>> However we still need i2c DMA status is known when meet an
> > > >>>>> unexpected
> > > >>>> error, so we use dev_err_probe() to print error.
> > > >>>>
> > > >>>> Why dev_err_probe() instead of dev_err()?
> > > >>>>
> > > >>> Hi,
> > > >>> In patch V2 discussion, Marc suggested just return
> > > >>> dev_err_probe(), but I don't accept it so I choose to use
> > > >>> dev_err_probe() to print error in V3.[1]
> > > >> In this case, the two APIs have the same function, do you mean
> > > >> dev_err() is more suitable?
> > > >>
> > > >> Yes, dev_err_probe() should be used in combination with return. For
> > > >> example:
> > > >>   return dev_err_probe(...);
> > > >>
> > > >> It will pass the return value on exit of the function and
> > > >> optionally print of the error message if it is not EPROBE_DEFER.
> > > >> Practically it replace commonly used coding pattern:
> > > >>   if (ret == -EPROBE_DEFER) {
> > > >>     return ret;
> > > >>   } else if (ret) {
> > > >>     dev_err(..);
> > > >>     return ret;
> > > >>   }
> > > >>
> > > > Hi,
> > > >
> > > > Get your good point. I will change my code in V6:
> > > > +       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> > > > +       if (ret) {
> > > > +               if (ret == -EPROBE_DEFER)
> > > > +                       goto clk_notifier_unregister;
> > > > +               else if (ret == -ENODEV)
> > > > +                       dev_dbg(&pdev->dev, "Only use PIO
> > mode\n");
> > > > +               else
> > > > +                       dev_err(&pdev->dev, "Failed to setup DMA,
> > only use PIO mode\n");
> > > > +       }
> > > >
> > > > I think this is what you want to see, right?
> > >
> > > This loses the information why the error happens (ret). Using
> > > dev_err_probe even if no probe deferral is expected in that branch is
> > > perfectly fine and the kernel-doc even points it out:
> > >
> > >   Using this helper in your probe function is totally fine even if @err
> > >   is known to never be -EPROBE_DEFER.
> >
> > Thank you for the feedback. While I recognize the benefits of
> > dev_err_probe() for compact and standardized error handling, using it without
> > returning its result raises a red flag.
> >
> > The function's primary purpose is to combine error logging with returning the
> > error code. If the return value is not used, it can create confusion and suggests
> > potential oversight or unintended behavior. This misuse might mislead readers
> > into thinking that the function always returns at that point, which is not the case
> > here.
> >
> > In this scenario, using dev_err() directly is more explicit and avoids any ambiguity
> > about the control flow or error handling intent. It keeps the code clear and
> > aligned with its actual behavior.
> >
> 
> how about this?
> 
> +       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> +       if (ret) {
> +               if (ret == -EPROBE_DEFER)
> +                       goto clk_notifier_unregister;
> +               else if (ret == -ENODEV)
> +                       dev_dbg(&pdev->dev, "Only use PIO mode\n");
> +               else
> +                       dev_err(&pdev->dev, "Failed to setup DMA (%d), only use PIO mode\n", ret);
> +       }

Please use human readable version of error value. In this case it will
be:
  dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n", ERR_PTR(ret));


-- 
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 tudor.ambarus at linaro.org  Thu Dec 19 23:51:32 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 07:51:32 +0000
Subject: [PATCH 1/2] dt-bindings: mailbox: add support for referencing
 controllers solely by node
In-Reply-To: <20241219-strum-cheese-89e5e60d22c3@spud>
References: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>
 <20241219-mbox_request_channel_by_args-v1-1-617a6910f842@linaro.org>
 <20241219-recent-everyone-865b19864693@wendy>
 <d9e635c8-de05-4812-bf2b-11651f6da5c1@linaro.org>
 <20241219-strum-cheese-89e5e60d22c3@spud>
Message-ID: <463d5955-a056-40e1-a46e-f89ac0dadccf@linaro.org>



On 12/19/24 6:58 PM, Conor Dooley wrote:
> On Thu, Dec 19, 2024 at 03:42:11PM +0000, Tudor Ambarus wrote:
>> Hi, Conor,
>>
>> On 12/19/24 2:11 PM, Conor Dooley wrote:
>>>> There are mailbox clients that can discover the mailbox channel ID at
>>>> run-time. For such cases passing the channel identifier via DT is
>>>> redundant. Add support for referencing controllers solely by node.
>>> I don't really get your implementation, why not just allow #mbox-cells = 0?
>>> That's what's done for things like fixed frequency clocks that only have
>>> a single output.
>>
>> Ah, indeed!
>>
>> instead of:
>> 	of_parse_phandle(dev->of_node, "mbox", 0);
>> I can do a:
>> 	of_parse_phandle_with_args(dev->of_node, "mboxes",
>>                                    "#mbox-cells", 0, &of_args)
>> where #mbox-cells = 0;
>>
>> Or ... can I pass NULL for cells_name and make the #mbox-cells property
>> optional and still keeping its requirement of being at least 1?
> 
> I think the mbox-cells = 0 approach is preferred, that property is what
> marks it as a mailbox controller after all. Perhaps Rob or Krzysztof can
> comment?

I think using mbox-cells = 0 is better indeed. In my proposal I
considered the list to always have a single phandle, thus a reference to
a single mailbox controller, whereas it may be possible that clients to
reference multiple mailbox controllers. If so, #mbox-cells needs to be
defined in all the controllers, for consistency reasons, similar to what
happens with fixed clocks, as you already mentioned.

Thus I'll change the method to:
struct mbox_chan *mbox_request_channel_by_args(struct mbox_client *cl,
                       int index, const struct mbox_xlate_args *spec);
and use of_parse_phandle_with_args() in it.

Thanks, Conor!
ta


From yangyicong at huawei.com  Thu Dec 19 23:53:10 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 20 Dec 2024 15:53:10 +0800
Subject: [PATCH v10 1/4] cpu/SMT: Provide a default topology_is_primary_thread()
In-Reply-To: <20241220075313.51502-1-yangyicong@huawei.com>
References: <20241220075313.51502-1-yangyicong@huawei.com>
Message-ID: <20241220075313.51502-2-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Currently if architectures want to support HOTPLUG_SMT they need to
provide a topology_is_primary_thread() telling the framework which
thread in the SMT cannot offline. However arm64 doesn't have a
restriction on which thread in the SMT cannot offline, a simplest
choice is that just make 1st thread as the "primary" thread. So
just make this as the default implementation in the framework and
let architectures like x86 that have special primary thread to
override this function (which they've already done).

There's no need to provide a stub function if !CONFIG_SMP or
!CONFIG_HOTPLUG_SMP. In such case the testing CPU is already
the 1st CPU in the SMT so it's always the primary thread.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
As questioned in v9 [1] whether this works on architectures not using
CONFIG_GENERIC_ARCH_TOPOLOGY, hacked on LoongArch VM and this also works.
Architectures should use this on their own situation.
[1] https://lore.kernel.org/linux-arm-kernel/427bd639-33c3-47e4-9e83-68c428eb1a7d at arm.com/

[root at localhost smt]# uname -m
loongarch64
[root at localhost smt]# pwd
/sys/devices/system/cpu/smt
[root at localhost smt]# cat ../possible 
0-3
[root at localhost smt]# cat ../online 
0-3
[root at localhost smt]# cat control 
on
[root at localhost smt]# echo off > control 
[root at localhost smt]# cat control 
off
[root at localhost smt]# cat ../online 
0,2
[root at localhost smt]# echo on > control 
[root at localhost smt]# cat control 
on
[root at localhost smt]# cat ../online 
0-3

 arch/powerpc/include/asm/topology.h |  1 +
 arch/x86/include/asm/topology.h     |  2 +-
 include/linux/topology.h            | 22 ++++++++++++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index 16bacfe8c7a2..da15b5efe807 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -152,6 +152,7 @@ static inline bool topology_is_primary_thread(unsigned int cpu)
 {
 	return cpu == cpu_first_thread_sibling(cpu);
 }
+#define topology_is_primary_thread topology_is_primary_thread
 
 static inline bool topology_smt_thread_allowed(unsigned int cpu)
 {
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index fd41103ad342..faa0d6334ea4 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -228,11 +228,11 @@ static inline bool topology_is_primary_thread(unsigned int cpu)
 {
 	return cpumask_test_cpu(cpu, cpu_primary_thread_mask);
 }
+#define topology_is_primary_thread topology_is_primary_thread
 
 #else /* CONFIG_SMP */
 static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
 static inline int topology_max_smt_threads(void) { return 1; }
-static inline bool topology_is_primary_thread(unsigned int cpu) { return true; }
 static inline unsigned int topology_amd_nodes_per_pkg(void) { return 1; }
 #endif /* !CONFIG_SMP */
 
diff --git a/include/linux/topology.h b/include/linux/topology.h
index 52f5850730b3..b3aba443c4eb 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -240,6 +240,28 @@ static inline const struct cpumask *cpu_smt_mask(int cpu)
 }
 #endif
 
+#ifndef topology_is_primary_thread
+
+#define topology_is_primary_thread topology_is_primary_thread
+
+static inline bool topology_is_primary_thread(unsigned int cpu)
+{
+	/*
+	 * On SMT hotplug the primary thread of the SMT won't be disabled.
+	 * Architectures do have a special primary thread (e.g. x86) need
+	 * to override this function. Otherwise just make the first thread
+	 * in the SMT as the primary thread.
+	 *
+	 * The sibling cpumask of an offline CPU contains always the CPU
+	 * itself for architectures using CONFIG_GENERIC_ARCH_TOPOLOGY.
+	 * Other architectures should use this depend on their own
+	 * situation.
+	 */
+	return cpu == cpumask_first(topology_sibling_cpumask(cpu));
+}
+
+#endif
+
 static inline const struct cpumask *cpu_cpu_mask(int cpu)
 {
 	return cpumask_of_node(cpu_to_node(cpu));
-- 
2.24.0



From yangyicong at huawei.com  Thu Dec 19 23:53:11 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 20 Dec 2024 15:53:11 +0800
Subject: [PATCH v10 2/4] arch_topology: Support SMT control for OF based system
In-Reply-To: <20241220075313.51502-1-yangyicong@huawei.com>
References: <20241220075313.51502-1-yangyicong@huawei.com>
Message-ID: <20241220075313.51502-3-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

On building the topology from the devicetree, we've already
gotten the SMT thread number of each core. Update the largest
SMT thread number and enable the SMT control by the end of
topology parsing.

The core's SMT control provides two interface to the users [1]:
1) enable/disable SMT by writing on/off
2) enable/disable SMT by writing thread number 1/max_thread_number

If a system have more than one SMT thread number the 2) may
not handle it well, since there're multiple thread numbers in the
system and 2) only accept 1/max_thread_number. So issue a warning
to notify the users if such system detected.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/ABI/testing/sysfs-devices-system-cpu#n542
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/base/arch_topology.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 3ebe77566788..9e81060144c7 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -11,6 +11,7 @@
 #include <linux/cleanup.h>
 #include <linux/cpu.h>
 #include <linux/cpufreq.h>
+#include <linux/cpu_smt.h>
 #include <linux/device.h>
 #include <linux/of.h>
 #include <linux/slab.h>
@@ -506,6 +507,10 @@ core_initcall(free_raw_capacity);
 #endif
 
 #if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
+
+/* Maximum SMT thread number detected used to enable the SMT control */
+static unsigned int max_smt_thread_num;
+
 /*
  * This function returns the logic cpu number of the node.
  * There are basically three kinds of return values:
@@ -565,6 +570,17 @@ static int __init parse_core(struct device_node *core, int package_id,
 		i++;
 	} while (1);
 
+	/*
+	 * If max_smt_thread_num has been initialized and doesn't match
+	 * the thread number of this entry, then the system has
+	 * heterogeneous SMT topology.
+	 */
+	if (max_smt_thread_num && max_smt_thread_num != i)
+		pr_warn_once("Heterogeneous SMT topology is partly supported by SMT control\n");
+
+	if (max_smt_thread_num < i)
+		max_smt_thread_num = i;
+
 	cpu = get_cpu_for_node(core);
 	if (cpu >= 0) {
 		if (!leaf) {
@@ -677,6 +693,16 @@ static int __init parse_socket(struct device_node *socket)
 	if (!has_socket)
 		ret = parse_cluster(socket, 0, -1, 0);
 
+	/*
+	 * Notify the CPU framework of the SMT support. Initialize the
+	 * max_smt_thread_num to 1 if no SMT support detected. A thread
+	 * number of 1 can be handled by the framework so we don't need
+	 * to check max_smt_thread_num to see we support SMT or not.
+	 */
+	if (!max_smt_thread_num)
+		max_smt_thread_num = 1;
+
+	cpu_smt_set_num_threads(max_smt_thread_num, max_smt_thread_num);
 	return ret;
 }
 
-- 
2.24.0



From yangyicong at huawei.com  Thu Dec 19 23:53:13 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 20 Dec 2024 15:53:13 +0800
Subject: [PATCH v10 4/4] arm64: Kconfig: Enable HOTPLUG_SMT
In-Reply-To: <20241220075313.51502-1-yangyicong@huawei.com>
References: <20241220075313.51502-1-yangyicong@huawei.com>
Message-ID: <20241220075313.51502-5-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Enable HOTPLUG_SMT for SMT control.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 100570a048c5..1ee926e2252e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -246,6 +246,7 @@ config ARM64
 	select HAVE_KRETPROBES
 	select HAVE_GENERIC_VDSO
 	select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
+	select HOTPLUG_SMT if HOTPLUG_CPU
 	select IRQ_DOMAIN
 	select IRQ_FORCED_THREADING
 	select KASAN_VMALLOC if KASAN
-- 
2.24.0



From s-vadapalli at ti.com  Thu Dec 19 23:56:14 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 20 Dec 2024 13:26:14 +0530
Subject: [PATCH net] net: ethernet: ti: am65-cpsw: default to round-robin for host port receive
Message-ID: <20241220075618.228202-1-s-vadapalli@ti.com>

The Host Port (i.e. CPU facing port) of CPSW receives traffic from Linux
via TX DMA Channels which are Hardware Queues consisting of traffic
categorized according to their priority. The Host Port is configured to
dequeue traffic from these Hardware Queues on the basis of priority i.e.
as long as traffic exists on a Hardware Queue of a higher priority, the
traffic on Hardware Queues of lower priority isn't dequeued. An alternate
operation is also supported wherein traffic can be dequeued by the Host
Port in a Round-Robin manner.

Until [0], the am65-cpsw driver enabled a single TX DMA Channel, due to
which, unless modified by user via "ethtool", all traffic from Linux is
transmitted on DMA Channel 0. Therefore, configuring the Host Port for
priority based dequeuing or Round-Robin operation is identical since
there is a single DMA Channel.

Since [0], all 8 TX DMA Channels are enabled by default. Additionally,
the default "tc mapping" doesn't take into account the possibility of
different traffic profiles which various users might have. This results
in traffic starvation at the Host Port due to the priority based dequeuing
which has been enabled by default since the inception of the driver. The
traffic starvation triggers NETDEV WATCHDOG timeout for all TX DMA Channels
that haven't been serviced due to the presence of traffic on the higher
priority TX DMA Channels.

Fix this by defaulting to Round-Robin dequeuing at the Host Port, which
shall ensure that traffic is dequeued from all TX DMA Channels irrespective
of the traffic profile. This will address the NETDEV WATCHDOG timeouts.
At the same time, users can still switch from Round-Robin to Priority
based dequeuing at the Host Port with the help of the "p0-rx-ptype-rrobin"
private flag of "ethtool". Users are expected to setup an appropriate
"tc mapping" that suits their traffic profile when switching to priority
based dequeuing at the Host Port.

[0] commit be397ea3473d ("net: ethernet: am65-cpsw: Set default TX channels to maximum")
Fixes: be397ea3473d ("net: ethernet: am65-cpsw: Set default TX channels to maximum")
Cc: <stable at vger.kernel.org>
Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

Hello,

This patch is based on commit
8faabc041a00 Merge tag 'net-6.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
of Mainline Linux.

Regards,
Siddharth.

 drivers/net/ethernet/ti/am65-cpsw-nuss.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index 14e1df721f2e..5465bf872734 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -3551,7 +3551,7 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
 	init_completion(&common->tdown_complete);
 	common->tx_ch_num = AM65_CPSW_DEFAULT_TX_CHNS;
 	common->rx_ch_num_flows = AM65_CPSW_DEFAULT_RX_CHN_FLOWS;
-	common->pf_p0_rx_ptype_rrobin = false;
+	common->pf_p0_rx_ptype_rrobin = true;
 	common->default_vlan = 1;
 
 	common->ports = devm_kcalloc(dev, common->port_num,
-- 
2.43.0



From yangyicong at huawei.com  Thu Dec 19 23:53:09 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 20 Dec 2024 15:53:09 +0800
Subject: [PATCH v10 0/4] Support SMT control on arm64
Message-ID: <20241220075313.51502-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

The core CPU control framework supports runtime SMT control which
is not yet supported on arm64. Besides the general vulnerabilities
concerns we want this runtime control on our arm64 server for:

- better single CPU performance in some cases
- saving overall power consumption

This patchset implements it in the following aspects:

- Provides a default topology_is_primary_thread()
- support retrieve SMT thread number on OF based system
- support retrieve SMT thread number on ACPI based system
- select HOTPLUG_SMT for arm64

Tests has been done on our ACPI based arm64 server and on ACPI/OF\
based QEMU VMs.

Change since v9:
- Refine the comment of topology_is_primary_thread(). Tested with LoongArch
  to prove it also works on architecture's not using CONFIG_GENERIC_ARCH_TOPOLOGY
- always call cpu_smt_set_num_threads() to make the smt/control shows correct
  status on non-SMT system
Link: https://lore.kernel.org/linux-arm-kernel/20241114141127.23232-1-yangyicong at huawei.com/

Change since v8:
- Fix WARN on ACPI based non-SMT platform noticed in v7, per Pierre.
Link: https://lore.kernel.org/all/20241105093237.63565-1-yangyicong at huawei.com/

Change since v7:
Address the comments from Thomas:
- Add a newline between the glue define and function of topology_is_primary_thread
- Explicitly mention the sibling mask won't be empty in the comment
Link: https://lore.kernel.org/lkml/20241030125415.18994-1-yangyicong at huawei.com/

Change since v6:
- Fix unused variable if !CONFIG_ARM64 || !CONFIG_RISV found by lkp-test
- Fix max_smt_thread_num updating in OF path pointed by Pierre
- Drop unused variable and refine the comments/commit per Pierre
Link: https://lore.kernel.org/linux-arm-kernel/20241015021841.35713-1-yangyicong at huawei.com/

Change since v5:
- Drop the dependency on CONFIG_SMP since it's always on on arm64, per Pierre
- Avoid potential multiple calls of cpu_smt_set_num_threads() on asymmetric system, per Dietmar
- Detect heterogenous SMT topology and issue a warning for partly support, per Pierre
- Thanks Dietmar for testing, didn't pickup the tag due to code changes. Thanks testing by Pierre
Link: https://lore.kernel.org/linux-arm-kernel/20240806085320.63514-1-yangyicong at huawei.com/

Change since v4:
- Provide a default topology_is_primary_thread() in the framework, Per Will
Link: https://lore.kernel.org/linux-arm-kernel/20231121092602.47792-1-yangyicong at huawei.com/

Change since v3:
- Fix some build and kconfig error reported by kernel test robot <lkp at intel.com>
Link: https://lore.kernel.org/linux-arm-kernel/20231114040110.54590-1-yangyicong at huawei.com/

Change since v2:
- Detect SMT thread number at topology build from ACPI/DT, avoid looping CPUs
- Split patches into ACPI/OF/arch_topology path and enable the kconfig for arm64
Link: https://lore.kernel.org/linux-arm-kernel/20231010115335.13862-1-yangyicong at huawei.com/

Yicong Yang (4):
  cpu/SMT: Provide a default topology_is_primary_thread()
  arch_topology: Support SMT control for OF based system
  arm64: topology: Support SMT control on ACPI based system
  arm64: Kconfig: Enable HOTPLUG_SMT

 arch/arm64/Kconfig                  |  1 +
 arch/arm64/kernel/topology.c        | 66 +++++++++++++++++++++++++++++
 arch/powerpc/include/asm/topology.h |  1 +
 arch/x86/include/asm/topology.h     |  2 +-
 drivers/base/arch_topology.c        | 26 ++++++++++++
 include/linux/topology.h            | 22 ++++++++++
 6 files changed, 117 insertions(+), 1 deletion(-)

-- 
2.24.0



From yangyicong at huawei.com  Thu Dec 19 23:53:12 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 20 Dec 2024 15:53:12 +0800
Subject: [PATCH v10 3/4] arm64: topology: Support SMT control on ACPI based system
In-Reply-To: <20241220075313.51502-1-yangyicong@huawei.com>
References: <20241220075313.51502-1-yangyicong@huawei.com>
Message-ID: <20241220075313.51502-4-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

For ACPI we'll build the topology from PPTT and we cannot directly
get the SMT number of each core. Instead using a temporary xarray
to record the heterogeneous information (from ACPI_PPTT_ACPI_IDENTICAL)
and SMT information of the first core in its heterogeneous CPU cluster
when building the topology. Then we can know the largest SMT number
in the system. If a homogeneous system's using ACPI 6.2 or later,
all the CPUs should be under the root node of PPTT. There'll be
only one entry in the xarray and all the CPUs in the system will
be assumed identical.

The core's SMT control provides two interface to the users [1]:
1) enable/disable SMT by writing on/off
2) enable/disable SMT by writing thread number 1/max_thread_number

If a system have more than one SMT thread number the 2) may
not handle it well, since there're multiple thread numbers in the
system and 2) only accept 1/max_thread_number. So issue a warning
to notify the users if such system detected.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/ABI/testing/sysfs-devices-system-cpu#n542
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 arch/arm64/kernel/topology.c | 66 ++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 1a2c72f3e7f8..85cb18d72a29 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -15,8 +15,10 @@
 #include <linux/arch_topology.h>
 #include <linux/cacheinfo.h>
 #include <linux/cpufreq.h>
+#include <linux/cpu_smt.h>
 #include <linux/init.h>
 #include <linux/percpu.h>
+#include <linux/xarray.h>
 
 #include <asm/cpu.h>
 #include <asm/cputype.h>
@@ -37,17 +39,28 @@ static bool __init acpi_cpu_is_threaded(int cpu)
 	return !!is_threaded;
 }
 
+struct cpu_smt_info {
+	int thread_num;
+	int core_id;
+};
+
 /*
  * Propagate the topology information of the processor_topology_node tree to the
  * cpu_topology array.
  */
 int __init parse_acpi_topology(void)
 {
+	int max_smt_thread_num = 0;
+	struct cpu_smt_info *entry;
+	struct xarray hetero_cpu;
+	unsigned long hetero_id;
 	int cpu, topology_id;
 
 	if (acpi_disabled)
 		return 0;
 
+	xa_init(&hetero_cpu);
+
 	for_each_possible_cpu(cpu) {
 		topology_id = find_acpi_cpu_topology(cpu, 0);
 		if (topology_id < 0)
@@ -57,6 +70,32 @@ int __init parse_acpi_topology(void)
 			cpu_topology[cpu].thread_id = topology_id;
 			topology_id = find_acpi_cpu_topology(cpu, 1);
 			cpu_topology[cpu].core_id   = topology_id;
+
+			/*
+			 * In the PPTT, CPUs below a node with the 'identical
+			 * implementation' flag have the same number of threads.
+			 * Count the number of threads for only one CPU (i.e.
+			 * one core_id) among those with the same hetero_id.
+			 * See the comment of find_acpi_cpu_topology_hetero_id()
+			 * for more details.
+			 *
+			 * One entry is created for each node having:
+			 * - the 'identical implementation' flag
+			 * - its parent not having the flag
+			 */
+			hetero_id = find_acpi_cpu_topology_hetero_id(cpu);
+			entry = (struct cpu_smt_info *)xa_load(&hetero_cpu, hetero_id);
+			if (!entry) {
+				entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+				WARN_ON(!entry);
+
+				entry->core_id = topology_id;
+				entry->thread_num = 1;
+				xa_store(&hetero_cpu, hetero_id,
+					 entry, GFP_KERNEL);
+			} else if (entry->core_id == topology_id) {
+				entry->thread_num++;
+			}
 		} else {
 			cpu_topology[cpu].thread_id  = -1;
 			cpu_topology[cpu].core_id    = topology_id;
@@ -67,6 +106,33 @@ int __init parse_acpi_topology(void)
 		cpu_topology[cpu].package_id = topology_id;
 	}
 
+	/*
+	 * This should be a short loop depending on the number of heterogeneous
+	 * CPU clusters. Typically on a homogeneous system there's only one
+	 * entry in the XArray.
+	 */
+	xa_for_each(&hetero_cpu, hetero_id, entry) {
+		if (entry->thread_num != max_smt_thread_num && max_smt_thread_num)
+			pr_warn_once("Heterogeneous SMT topology is partly supported by SMT control\n");
+
+		if (entry->thread_num > max_smt_thread_num)
+			max_smt_thread_num = entry->thread_num;
+
+		xa_erase(&hetero_cpu, hetero_id);
+		kfree(entry);
+	}
+
+	/*
+	 * Notify the CPU framework of the SMT support. Initialize the
+	 * max_smt_thread_num to 1 if no SMT support detected. A thread
+	 * number of 1 can be handled by the framework so we don't need
+	 * to check max_smt_thread_num to see we support SMT or not.
+	 */
+	if (!max_smt_thread_num)
+		max_smt_thread_num = 1;
+
+	cpu_smt_set_num_threads(max_smt_thread_num, max_smt_thread_num);
+	xa_destroy(&hetero_cpu);
 	return 0;
 }
 #endif
-- 
2.24.0



From yangyicong at huawei.com  Thu Dec 19 23:59:27 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 20 Dec 2024 15:59:27 +0800
Subject: [PATCH v10 1/4] cpu/SMT: Provide a default
 topology_is_primary_thread()
In-Reply-To: <20241220075313.51502-2-yangyicong@huawei.com>
References: <20241220075313.51502-1-yangyicong@huawei.com>
 <20241220075313.51502-2-yangyicong@huawei.com>
Message-ID: <a5690fee-3019-f26c-8bad-1d95e388e877@huawei.com>

On 2024/12/20 15:53, Yicong Yang wrote:
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> Currently if architectures want to support HOTPLUG_SMT they need to
> provide a topology_is_primary_thread() telling the framework which
> thread in the SMT cannot offline. However arm64 doesn't have a
> restriction on which thread in the SMT cannot offline, a simplest
> choice is that just make 1st thread as the "primary" thread. So
> just make this as the default implementation in the framework and
> let architectures like x86 that have special primary thread to
> override this function (which they've already done).
> 
> There's no need to provide a stub function if !CONFIG_SMP or
> !CONFIG_HOTPLUG_SMP. In such case the testing CPU is already
> the 1st CPU in the SMT so it's always the primary thread.
> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
> As questioned in v9 [1] whether this works on architectures not using
> CONFIG_GENERIC_ARCH_TOPOLOGY, hacked on LoongArch VM and this also works.
> Architectures should use this on their own situation.
> [1] https://lore.kernel.org/linux-arm-kernel/427bd639-33c3-47e4-9e83-68c428eb1a7d at arm.com/
> 
> [root at localhost smt]# uname -m
> loongarch64
> [root at localhost smt]# pwd
> /sys/devices/system/cpu/smt
> [root at localhost smt]# cat ../possible 
> 0-3
> [root at localhost smt]# cat ../online 
> 0-3
> [root at localhost smt]# cat control 
> on
> [root at localhost smt]# echo off > control 
> [root at localhost smt]# cat control 
> off
> [root at localhost smt]# cat ../online 
> 0,2
> [root at localhost smt]# echo on > control 
> [root at localhost smt]# cat control 
> on
> [root at localhost smt]# cat ../online 
> 0-3

Tested with below code using the topology_is_primary_thread() introduced
in this patch. Tested on an ACPI-based QEMU VM emulating SMT2.

Subject: [PATCH] LoongArch: Support HOTPLUG_SMT on ACPI-based system

Support HOTPLUG_SMT on ACPI-based system using generic
topology_is_primary_thread().

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 arch/loongarch/Kconfig       |  1 +
 arch/loongarch/kernel/acpi.c | 26 ++++++++++++++++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index dae3a9104ca6..bed1b0640b97 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -172,6 +172,7 @@ config LOONGARCH
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_TIF_NOHZ
 	select HAVE_VIRT_CPU_ACCOUNTING_GEN if !SMP
+	select HOTPLUG_SMT if HOTPLUG_CPU
 	select IRQ_FORCED_THREADING
 	select IRQ_LOONGARCH_CPU
 	select LOCK_MM_AND_FIND_VMA
diff --git a/arch/loongarch/kernel/acpi.c b/arch/loongarch/kernel/acpi.c
index 382a09a7152c..e642b0de57e7 100644
--- a/arch/loongarch/kernel/acpi.c
+++ b/arch/loongarch/kernel/acpi.c
@@ -15,9 +15,11 @@
 #include <linux/memblock.h>
 #include <linux/of_fdt.h>
 #include <linux/serial_core.h>
+#include <linux/xarray.h>
 #include <asm/io.h>
 #include <asm/numa.h>
 #include <asm/loongson.h>
+#include <linux/cpu_smt.h>

 int acpi_disabled;
 EXPORT_SYMBOL(acpi_disabled);
@@ -175,8 +177,12 @@ int pptt_enabled;

 int __init parse_acpi_topology(void)
 {
+	int thread_num, max_smt_thread_num = 1;
+	struct xarray core_threads;
 	int cpu, topology_id;
+	void *entry;

+	xa_init(&core_threads);
 	for_each_possible_cpu(cpu) {
 		topology_id = find_acpi_cpu_topology(cpu, 0);
 		if (topology_id < 0) {
@@ -184,19 +190,35 @@ int __init parse_acpi_topology(void)
 			return -ENOENT;
 		}

-		if (acpi_pptt_cpu_is_thread(cpu) <= 0)
+		if (acpi_pptt_cpu_is_thread(cpu) <= 0) {
 			cpu_data[cpu].core = topology_id;
-		else {
+		} else {
 			topology_id = find_acpi_cpu_topology(cpu, 1);
 			if (topology_id < 0)
 				return -ENOENT;

 			cpu_data[cpu].core = topology_id;
+
+			entry = xa_load(&core_threads, topology_id);
+			if (!entry) {
+				xa_store(&core_threads, topology_id,
+					 xa_mk_value(1), GFP_KERNEL);
+			} else {
+				thread_num = xa_to_value(entry);
+				thread_num++;
+				xa_store(&core_threads, topology_id,
+					 xa_mk_value(thread_num), GFP_KERNEL);
+
+				if (thread_num > max_smt_thread_num)
+					max_smt_thread_num = thread_num;
+			}
 		}
 	}

 	pptt_enabled = 1;

+	cpu_smt_set_num_threads(max_smt_thread_num, max_smt_thread_num);
+	xa_destroy(&core_threads);
 	return 0;
 }

-- 
2.24.0

> 
>  arch/powerpc/include/asm/topology.h |  1 +
>  arch/x86/include/asm/topology.h     |  2 +-
>  include/linux/topology.h            | 22 ++++++++++++++++++++++
>  3 files changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
> index 16bacfe8c7a2..da15b5efe807 100644
> --- a/arch/powerpc/include/asm/topology.h
> +++ b/arch/powerpc/include/asm/topology.h
> @@ -152,6 +152,7 @@ static inline bool topology_is_primary_thread(unsigned int cpu)
>  {
>  	return cpu == cpu_first_thread_sibling(cpu);
>  }
> +#define topology_is_primary_thread topology_is_primary_thread
>  
>  static inline bool topology_smt_thread_allowed(unsigned int cpu)
>  {
> diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
> index fd41103ad342..faa0d6334ea4 100644
> --- a/arch/x86/include/asm/topology.h
> +++ b/arch/x86/include/asm/topology.h
> @@ -228,11 +228,11 @@ static inline bool topology_is_primary_thread(unsigned int cpu)
>  {
>  	return cpumask_test_cpu(cpu, cpu_primary_thread_mask);
>  }
> +#define topology_is_primary_thread topology_is_primary_thread
>  
>  #else /* CONFIG_SMP */
>  static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
>  static inline int topology_max_smt_threads(void) { return 1; }
> -static inline bool topology_is_primary_thread(unsigned int cpu) { return true; }
>  static inline unsigned int topology_amd_nodes_per_pkg(void) { return 1; }
>  #endif /* !CONFIG_SMP */
>  
> diff --git a/include/linux/topology.h b/include/linux/topology.h
> index 52f5850730b3..b3aba443c4eb 100644
> --- a/include/linux/topology.h
> +++ b/include/linux/topology.h
> @@ -240,6 +240,28 @@ static inline const struct cpumask *cpu_smt_mask(int cpu)
>  }
>  #endif
>  
> +#ifndef topology_is_primary_thread
> +
> +#define topology_is_primary_thread topology_is_primary_thread
> +
> +static inline bool topology_is_primary_thread(unsigned int cpu)
> +{
> +	/*
> +	 * On SMT hotplug the primary thread of the SMT won't be disabled.
> +	 * Architectures do have a special primary thread (e.g. x86) need
> +	 * to override this function. Otherwise just make the first thread
> +	 * in the SMT as the primary thread.
> +	 *
> +	 * The sibling cpumask of an offline CPU contains always the CPU
> +	 * itself for architectures using CONFIG_GENERIC_ARCH_TOPOLOGY.
> +	 * Other architectures should use this depend on their own
> +	 * situation.
> +	 */
> +	return cpu == cpumask_first(topology_sibling_cpumask(cpu));
> +}
> +
> +#endif
> +
>  static inline const struct cpumask *cpu_cpu_mask(int cpu)
>  {
>  	return cpumask_of_node(cpu_to_node(cpu));
> 


From cassel at kernel.org  Fri Dec 20 00:03:36 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Fri, 20 Dec 2024 09:03:36 +0100
Subject: [PATCH] arm64: dts: rockchip: rk3588: add msi-parent for
 pcie3x4_ep
In-Reply-To: <173318214613.1403925.10026428339576666444.b4-ty@sntech.de>
References: <20241120171048.2839621-2-cassel@kernel.org>
 <173318214613.1403925.10026428339576666444.b4-ty@sntech.de>
Message-ID: <Z2Uk2A7-YwkSfAOh@ryzen>

On Tue, Dec 03, 2024 at 12:29:16AM +0100, Heiko Stuebner wrote:
> 
> On Wed, 20 Nov 2024 18:10:49 +0100, Niklas Cassel wrote:
> > Add msi-parent for the pcie3x4_ep PCI endpoint node.
> > 
> > The pcie3x4_ep node should use the same msi-parent as the pcie3x4 node
> > (which represents the PCIe controller running in Root Complex mode).
> > 
> > The GIC ITS can be used to trigger an IRQ on the endpoint when any of
> > the endpoint's PCI BARs are written to by the host[1].
> > 
> > [...]
> 
> Applied, thanks!
> 
> [1/1] arm64: dts: rockchip: rk3588: add msi-parent for pcie3x4_ep
>       commit: b6f09f497b07008aa65c31341138cecafa78222c
> 

Hello Heiko,

When I sent this patch, I had tested it against Frank's v8 series which adds
support for a PCIe endpoint triggering an interrupt (using GIC ITS) when the
host side writes to the PCI BAR that the endpoint has configured as doorbell:
https://lore.kernel.org/linux-pci/20241116-ep-msi-v8-0-6f1f68ffd1bb at nxp.com/


However, it seems that in v10 of his series, he has changed it so that the
PCIe endpoint node now requires 'msi-map' instead of 'msi-parent'
(just like how it is done in the PCIe root complex node):

See:
https://lore.kernel.org/linux-pci/20241204-ep-msi-v10-0-87c378dbcd6d at nxp.com/

"""
Changes in v10:

[...]

- Use "msi-map" in pci ep controler node, instead of of msi-parent. first
argument is
	(func_no << 8 | vfunc_no)
"""


I didn't realize that DT property required for this feature could change so
drastically, since DT is supposed to describe hardware, and msi-parent made
perfect sense, since this property is usually the one used for devices
connected to a bus.
(msi-map is usually only used on the host bus adapter / root complex.)

Knowing what I now know, I should have waited until this feature had landed
before submitting this patch. I apologize for this.

Could you please drop this patch from your v6.14-armsoc/dts64 branch?

Or should I send a revert?

Once Frank's series has landed, I can resubmit a patch that adds whichever
DT property he finally ends up using.


Kind regards,
Niklas


From carlos.song at nxp.com  Fri Dec 20 00:06:33 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Fri, 20 Dec 2024 08:06:33 +0000
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <Z2Ugt8NVued0_4c4@pengutronix.de>
References: <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
 <Z2UeKZcpeRUt2OQ4@pengutronix.de>
 <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2Ugt8NVued0_4c4@pengutronix.de>
Message-ID: <AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Oleksij Rempel <o.rempel at pengutronix.de>
> Sent: Friday, December 20, 2024 3:46 PM
> To: Carlos Song <carlos.song at nxp.com>
> Cc: Ahmad Fatoum <a.fatoum at pengutronix.de>; Andi Shyti
> <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>; kernel at pengutronix.de;
> shawnguo at kernel.org; s.hauer at pengutronix.de; festevam at gmail.com;
> linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Clark Wang
> <xiaoning.wang at nxp.com>
> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
>
> 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 Fri, Dec 20, 2024 at 07:38:47AM +0000, Carlos Song wrote:
> >
> >
> > > -----Original Message-----
> > > From: Oleksij Rempel <o.rempel at pengutronix.de>
> > > Sent: Friday, December 20, 2024 3:35 PM
> > > To: Ahmad Fatoum <a.fatoum at pengutronix.de>
> > > Cc: Carlos Song <carlos.song at nxp.com>; Andi Shyti
> > > <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>;
> > > kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> > > festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> > > linux-arm-kernel at lists.infradead.org;
> > > linux-kernel at vger.kernel.org; Clark Wang <xiaoning.wang at nxp.com>
> > > Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
> > >
> > > 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 Fri, Dec 20, 2024 at 08:06:25AM +0100, Ahmad Fatoum wrote:
> > > > Hello Carlos,
> > > >
> > > > On 20.12.24 07:58, Carlos Song wrote:
> > > > >
> > > > >
> > > > >> -----Original Message-----
> > > > >> From: Oleksij Rempel <o.rempel at pengutronix.de>
> > > > >> Sent: Friday, December 20, 2024 2:13 PM
> > > > >> To: Carlos Song <carlos.song at nxp.com>
> > > > >> Cc: Andi Shyti <andi.shyti at kernel.org>; Frank Li
> > > > >> <frank.li at nxp.com>; kernel at pengutronix.de; shawnguo at kernel.org;
> > > > >> s.hauer at pengutronix.de; festevam at gmail.com;
> > > > >> linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> > > > >> linux-arm-kernel at lists.infradead.org;
> > > > >> linux-kernel at vger.kernel.org; Clark Wang
> > > > >> <xiaoning.wang at nxp.com>; Ahmad Fatoum
> <a.fatoum at pengutronix.de>
> > > > >> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer
> > > > >> probing
> > > > >>
> > > > >> 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 Fri, Dec 20, 2024 at 05:59:38AM +0000, Carlos Song wrote:
> > > > >>>>> So we make this logic. Anyway we let the I2C controller
> > > > >>>>> registered whether
> > > > >>>> DMA is available or not(except defer probe).
> > > > >>>>> Ignoring ENODEV and EPROBE_DEFER makes it looks like nothing
> > > > >>>>> happened if
> > > > >>>> DMA is defer probed or not enabled(This is an expected).
> > > > >>>>> However we still need i2c DMA status is known when meet an
> > > > >>>>> unexpected
> > > > >>>> error, so we use dev_err_probe() to print error.
> > > > >>>>
> > > > >>>> Why dev_err_probe() instead of dev_err()?
> > > > >>>>
> > > > >>> Hi,
> > > > >>> In patch V2 discussion, Marc suggested just return
> > > > >>> dev_err_probe(), but I don't accept it so I choose to use
> > > > >>> dev_err_probe() to print error in V3.[1]
> > > > >> In this case, the two APIs have the same function, do you mean
> > > > >> dev_err() is more suitable?
> > > > >>
> > > > >> Yes, dev_err_probe() should be used in combination with return.
> > > > >> For
> > > > >> example:
> > > > >>   return dev_err_probe(...);
> > > > >>
> > > > >> It will pass the return value on exit of the function and
> > > > >> optionally print of the error message if it is not EPROBE_DEFER.
> > > > >> Practically it replace commonly used coding pattern:
> > > > >>   if (ret == -EPROBE_DEFER) {
> > > > >>     return ret;
> > > > >>   } else if (ret) {
> > > > >>     dev_err(..);
> > > > >>     return ret;
> > > > >>   }
> > > > >>
> > > > > Hi,
> > > > >
> > > > > Get your good point. I will change my code in V6:
> > > > > +       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> > > > > +       if (ret) {
> > > > > +               if (ret == -EPROBE_DEFER)
> > > > > +                       goto clk_notifier_unregister;
> > > > > +               else if (ret == -ENODEV)
> > > > > +                       dev_dbg(&pdev->dev, "Only use PIO
> > > mode\n");
> > > > > +               else
> > > > > +                       dev_err(&pdev->dev, "Failed to setup
> > > > > + DMA,
> > > only use PIO mode\n");
> > > > > +       }
> > > > >
> > > > > I think this is what you want to see, right?
> > > >
> > > > This loses the information why the error happens (ret). Using
> > > > dev_err_probe even if no probe deferral is expected in that branch
> > > > is perfectly fine and the kernel-doc even points it out:
> > > >
> > > >   Using this helper in your probe function is totally fine even if @err
> > > >   is known to never be -EPROBE_DEFER.
> > >
> > > Thank you for the feedback. While I recognize the benefits of
> > > dev_err_probe() for compact and standardized error handling, using
> > > it without returning its result raises a red flag.
> > >
> > > The function's primary purpose is to combine error logging with
> > > returning the error code. If the return value is not used, it can
> > > create confusion and suggests potential oversight or unintended
> > > behavior. This misuse might mislead readers into thinking that the
> > > function always returns at that point, which is not the case here.
> > >
> > > In this scenario, using dev_err() directly is more explicit and
> > > avoids any ambiguity about the control flow or error handling
> > > intent. It keeps the code clear and aligned with its actual behavior.
> > >
> >
> > how about this?
> >
> > +       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> > +       if (ret) {
> > +               if (ret == -EPROBE_DEFER)
> > +                       goto clk_notifier_unregister;
> > +               else if (ret == -ENODEV)
> > +                       dev_dbg(&pdev->dev, "Only use PIO mode\n");
> > +               else
> > +                       dev_err(&pdev->dev, "Failed to setup DMA (%d),
> only use PIO mode\n", ret);
> > +       }
>
> Please use human readable version of error value. In this case it will
> be:
>   dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n",
> ERR_PTR(ret));
>

Hi, the ret is from i2c_imx_dma_request() and look like that ret has been converted by PTR_ERR,
So the ret error has been human readable version?

static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx, dma_addr_t phy_addr)
{
...
        dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
        if (!dma)
---->           return -ENOMEM;

        dma->chan_tx = dma_request_chan(dev, "tx");
        if (IS_ERR(dma->chan_tx)) {
---->           ret = PTR_ERR(dma->chan_tx);
                if (ret != -ENODEV && ret != -EPROBE_DEFER)
                        dev_err(dev, "can't request DMA tx channel (%d)\n", ret);
                goto fail_al;
        }

        dma_sconfig.dst_addr = phy_addr +
                                (IMX_I2C_I2DR << i2c_imx->hwdata->regshift);
        dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
        dma_sconfig.dst_maxburst = 1;
        dma_sconfig.direction = DMA_MEM_TO_DEV;
---->   ret = dmaengine_slave_config(dma->chan_tx, &dma_sconfig);
        if (ret < 0) {
                dev_err(dev, "can't configure tx channel (%d)\n", ret);
                goto fail_tx;
        }

        dma->chan_rx = dma_request_chan(dev, "rx");
        if (IS_ERR(dma->chan_rx)) {
---->           ret = PTR_ERR(dma->chan_rx);
                if (ret != -ENODEV && ret != -EPROBE_DEFER)
                        dev_err(dev, "can't request DMA rx channel (%d)\n", ret);
                goto fail_tx;
        }

        dma_sconfig.src_addr = phy_addr +
                                (IMX_I2C_I2DR << i2c_imx->hwdata->regshift);
        dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
        dma_sconfig.src_maxburst = 1;
        dma_sconfig.direction = DMA_DEV_TO_MEM;
        ret = dmaengine_slave_config(dma->chan_rx, &dma_sconfig);
        if (ret < 0) {
                dev_err(dev, "can't configure rx channel (%d)\n", ret);
                goto fail_rx;
        }

        i2c_imx->dma = dma;
        init_completion(&dma->cmd_complete);
        dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n",
                dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx));

        return 0;

fail_rx:
        dma_release_channel(dma->chan_rx);
fail_tx:
        dma_release_channel(dma->chan_tx);
fail_al:
        devm_kfree(dev, dma);

        return ret;
}
>
> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7Cd77fb08d389a
> 46773df008dd20ca5fdc%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%
> 7C638702775737161676%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiO
> nRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%
> 3D%3D%7C0%7C%7C%7C&sdata=B%2BR4YbexNiAlDpf5xTf%2BWp2GbmwtfG4
> yKaW8FBvaTRI%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |



From 0x1207 at gmail.com  Fri Dec 20 00:07:26 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Fri, 20 Dec 2024 16:07:26 +0800
Subject: [PATCH net-next v2] net: stmmac: TSO: Simplify the code flow of DMA descriptor allocations
Message-ID: <20241220080726.1733837-1-0x1207@gmail.com>

The TCP Segmentation Offload (TSO) engine is an optional function in
DWMAC cores, it is implemented for dwmac4 and dwxgmac2 only, ancient
dwmac100 and dwmac1000 are not supported by hardware. Current driver
code checks priv->dma_cap.tsoen which is read from MAC_HW_Feature1
register to determine if TSO is enabled in hardware configurations,
if (!priv->dma_cap.tsoen) driver never sets NETIF_F_TSO for net_device.

This patch never affects dwmac100/dwmac1000 and their stmmac_desc_ops:
ndesc_ops/enh_desc_ops, since TSO is never supported by them two.

The DMA AXI address width of DWMAC cores can be configured to
32-bit/40-bit/48-bit, then the format of DMA transmit descriptors
get a little different between 32-bit and 40-bit/48-bit.
Current driver code checks priv->dma_cap.addr64 to use certain format
with certain configuration.

This patch converts the format of DMA transmit descriptors on dwmac4
and dwxgmac2 that the DMA AXI address width is configured to 32-bit (as
described by function comments of stmmac_tso_xmit() in current code) to
a more generic format (see updated function comments after this patch)
which is actually already used on 40-bit/48-bit platforms to provide
better compatibility and make code flow cleaner in TSO TX routine.

Another interesting finding, struct stmmac_desc_ops is a common abstract
interface to maintain descriptors, we should avoid the direct assignment
of descriptor members (e.g. desc->des0), stmmac_set_desc_addr() is the
proper method yet. This patch tries to improve this by the way.

Tested and verified on:
DWMAC CORE 5.00a with 32-bit DMA AXI address width
DWMAC CORE 5.10a with 32-bit DMA AXI address width
DWXGMAC CORE 3.20a with 40-bit DMA AXI address width

Signed-off-by: Furong Xu <0x1207 at gmail.com>
---
V1 -> V2: Update commit message
V1: https://lore.kernel.org/r/20241213030006.337695-1-0x1207 at gmail.com
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 60 ++++++++-----------
 1 file changed, 24 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6bc10ffe7a2b..99eaec8bac4a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4116,11 +4116,7 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, dma_addr_t des,
 			desc = &tx_q->dma_tx[tx_q->cur_tx];
 
 		curr_addr = des + (total_len - tmp_len);
-		if (priv->dma_cap.addr64 <= 32)
-			desc->des0 = cpu_to_le32(curr_addr);
-		else
-			stmmac_set_desc_addr(priv, desc, curr_addr);
-
+		stmmac_set_desc_addr(priv, desc, curr_addr);
 		buff_size = tmp_len >= TSO_MAX_BUFF_SIZE ?
 			    TSO_MAX_BUFF_SIZE : tmp_len;
 
@@ -4166,17 +4162,27 @@ static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue)
  *  First Descriptor
  *   --------
  *   | DES0 |---> buffer1 = L2/L3/L4 header
- *   | DES1 |---> TCP Payload (can continue on next descr...)
- *   | DES2 |---> buffer 1 and 2 len
+ *   | DES1 |---> can be used as buffer2 for TCP Payload if the DMA AXI address
+ *   |      |     width is 32-bit, but we never use it.
+ *   |      |     Also can be used as the most-significant 8-bits or 16-bits of
+ *   |      |     buffer1 address pointer if the DMA AXI address width is 40-bit
+ *   |      |     or 48-bit, and we always use it.
+ *   | DES2 |---> buffer1 len
  *   | DES3 |---> must set TSE, TCP hdr len-> [22:19]. TCP payload len [17:0]
  *   --------
+ *   --------
+ *   | DES0 |---> buffer1 = TCP Payload (can continue on next descr...)
+ *   | DES1 |---> same as the First Descriptor
+ *   | DES2 |---> buffer1 len
+ *   | DES3 |
+ *   --------
  *	|
  *     ...
  *	|
  *   --------
- *   | DES0 | --| Split TCP Payload on Buffers 1 and 2
- *   | DES1 | --|
- *   | DES2 | --> buffer 1 and 2 len
+ *   | DES0 |---> buffer1 = Split TCP Payload
+ *   | DES1 |---> same as the First Descriptor
+ *   | DES2 |---> buffer1 len
  *   | DES3 |
  *   --------
  *
@@ -4186,15 +4192,14 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct dma_desc *desc, *first, *mss_desc = NULL;
 	struct stmmac_priv *priv = netdev_priv(dev);
-	int tmp_pay_len = 0, first_tx, nfrags;
 	unsigned int first_entry, tx_packets;
 	struct stmmac_txq_stats *txq_stats;
 	struct stmmac_tx_queue *tx_q;
 	u32 pay_len, mss, queue;
-	dma_addr_t tso_des, des;
+	int i, first_tx, nfrags;
 	u8 proto_hdr_len, hdr;
+	dma_addr_t des;
 	bool set_ic;
-	int i;
 
 	/* Always insert VLAN tag to SKB payload for TSO frames.
 	 *
@@ -4279,24 +4284,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (dma_mapping_error(priv->device, des))
 		goto dma_map_err;
 
-	if (priv->dma_cap.addr64 <= 32) {
-		first->des0 = cpu_to_le32(des);
-
-		/* Fill start of payload in buff2 of first descriptor */
-		if (pay_len)
-			first->des1 = cpu_to_le32(des + proto_hdr_len);
-
-		/* If needed take extra descriptors to fill the remaining payload */
-		tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
-		tso_des = des;
-	} else {
-		stmmac_set_desc_addr(priv, first, des);
-		tmp_pay_len = pay_len;
-		tso_des = des + proto_hdr_len;
-		pay_len = 0;
-	}
-
-	stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
+	stmmac_set_desc_addr(priv, first, des);
+	stmmac_tso_allocator(priv, des + proto_hdr_len, pay_len,
+			     (nfrags == 0), queue);
 
 	/* In case two or more DMA transmit descriptors are allocated for this
 	 * non-paged SKB data, the DMA buffer address should be saved to
@@ -4400,11 +4390,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	/* Complete the first descriptor before granting the DMA */
-	stmmac_prepare_tso_tx_desc(priv, first, 1,
-			proto_hdr_len,
-			pay_len,
-			1, tx_q->tx_skbuff_dma[first_entry].last_segment,
-			hdr / 4, (skb->len - proto_hdr_len));
+	stmmac_prepare_tso_tx_desc(priv, first, 1, proto_hdr_len, 0, 1,
+				   tx_q->tx_skbuff_dma[first_entry].last_segment,
+				   hdr / 4, (skb->len - proto_hdr_len));
 
 	/* If context desc is used to change MSS */
 	if (mss_desc) {
-- 
2.34.1



From ciprianmarian.costea at oss.nxp.com  Fri Dec 20 00:20:08 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Marian Costea)
Date: Fri, 20 Dec 2024 10:20:08 +0200
Subject: [PATCH v3 2/4] arm64: dts: s32g: add common 'S32G-EVB' and
 'S32G-RDB' board support
In-Reply-To: <Z2RVyO05WvIQUmX4@lizhi-Precision-Tower-5810>
References: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
 <20241219131029.1139720-3-ciprianmarian.costea@oss.nxp.com>
 <Z2RVyO05WvIQUmX4@lizhi-Precision-Tower-5810>
Message-ID: <eef5aeea-6106-4ea0-8d02-8f10df1f39db@oss.nxp.com>

On 12/19/2024 7:20 PM, Frank Li wrote:
> On Thu, Dec 19, 2024 at 03:10:27PM +0200, Ciprian Costea wrote:
>> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>>
>> With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
>> (rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
>> are quite similar. The common part for the EVB revisions will be
>> centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
>> be placed in 's32gxxa-rdb.dtsi' file.
>>
>> This refactor will also serve for other modules in the future, such as
>> FlexCAN, DSPI.
>>
>> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>> ---
>>   .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
>>   .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 126 +++++++++++++++
>>   2 files changed, 276 insertions(+)
>>   create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>>   create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
>>
>> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>> new file mode 100644
>> index 000000000000..a44eff28073a
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>> @@ -0,0 +1,150 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
>> +/*
>> + * Copyright 2024 NXP
>> + *
>> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
>> + *          Larisa Grigore <larisa.grigore at nxp.com>
>> + */
>> +
> [...]
> 
>> +
>> +&i2c2 {
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c2_pins>;
>> +	pinctrl-1 = <&i2c2_gpio_pins>;
>> +	status = "okay";
>> +};
>> +
>> +&i2c4 {
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
> 
> 
> I have said many times, these should be in common part.
> 
> Frank
> 

Hello Frank,

Ok, I'll move the 'address/size cells' from board common part into SoC 
common part.

Best Regards,
Ciprian

>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&i2c4_pins>;
>> +	pinctrl-1 = <&i2c4_gpio_pins>;
>> +	status = "okay";
>> +};
>> --
>> 2.45.2
>>



From ciprianmarian.costea at oss.nxp.com  Fri Dec 20 00:21:07 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Marian Costea)
Date: Fri, 20 Dec 2024 10:21:07 +0200
Subject: [PATCH v3 1/4] arm64: dts: s32g: add 'I2C' common board support
In-Reply-To: <Z2RVJLKqimn+jDYY@lizhi-Precision-Tower-5810>
References: <20241219131029.1139720-1-ciprianmarian.costea@oss.nxp.com>
 <20241219131029.1139720-2-ciprianmarian.costea@oss.nxp.com>
 <Z2RVJLKqimn+jDYY@lizhi-Precision-Tower-5810>
Message-ID: <4f7a25de-f1b5-44e8-b858-be4fac122c58@oss.nxp.com>

On 12/19/2024 7:17 PM, Frank Li wrote:
> On Thu, Dec 19, 2024 at 03:10:26PM +0200, Ciprian Costea wrote:
>> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>>
>> On both 'S32G2' and 'S32G3' SoCs there are five i2c controllers available
>> (i2c0-i2c4). Specific S32G2/S32G3 based board 'i2c' dts device support
>> will be added in further commits.
>>
>> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>> ---
>>   arch/arm64/boot/dts/freescale/s32g2.dtsi | 45 +++++++++++++++++++++
>>   arch/arm64/boot/dts/freescale/s32g3.dtsi | 50 ++++++++++++++++++++++++
>>   2 files changed, 95 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>> index 7be430b78c83..0e6c847ab0c3 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
>> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>> @@ -333,6 +333,33 @@ uart1: serial at 401cc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c0: i2c at 401e4000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x401e4000 0x1000>;
> 
> Need add common part #address-cell and #size-cell, which all are the same
> for all I2C.
> 
> Frank
> 

Hello Frank,

Ok, I will update accordingly in V4.

Best Regards,
Ciprian

>> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c1: i2c at 401e8000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x401e8000 0x1000>;
>> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c2: i2c at 401ec000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x401ec000 0x1000>;
>> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		uart2: serial at 402bc000 {
>>   			compatible = "nxp,s32g2-linflexuart",
>>   				     "fsl,s32v234-linflexuart";
>> @@ -341,6 +368,24 @@ uart2: serial at 402bc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c3: i2c at 402d8000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x402d8000 0x1000>;
>> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c4: i2c at 402dc000 {
>> +			compatible = "nxp,s32g2-i2c";
>> +			reg = <0x402dc000 0x1000>;
>> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		usdhc0: mmc at 402f0000 {
>>   			compatible = "nxp,s32g2-usdhc";
>>   			reg = <0x402f0000 0x1000>;
>> diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
>> index 6c572ffe37ca..666e4029e588 100644
>> --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
>> +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
>> @@ -390,6 +390,36 @@ uart1: serial at 401cc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c0: i2c at 401e4000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x401e4000 0x1000>;
>> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c1: i2c at 401e8000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x401e8000 0x1000>;
>> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c2: i2c at 401ec000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x401ec000 0x1000>;
>> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		uart2: serial at 402bc000 {
>>   			compatible = "nxp,s32g3-linflexuart",
>>   				     "fsl,s32v234-linflexuart";
>> @@ -398,6 +428,26 @@ uart2: serial at 402bc000 {
>>   			status = "disabled";
>>   		};
>>
>> +		i2c3: i2c at 402d8000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x402d8000 0x1000>;
>> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>> +		i2c4: i2c at 402dc000 {
>> +			compatible = "nxp,s32g3-i2c",
>> +				     "nxp,s32g2-i2c";
>> +			reg = <0x402dc000 0x1000>;
>> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&clks 40>;
>> +			clock-names = "ipg";
>> +			status = "disabled";
>> +		};
>> +
>>   		usdhc0: mmc at 402f0000 {
>>   			compatible = "nxp,s32g3-usdhc",
>>   				     "nxp,s32g2-usdhc";
>> --
>> 2.45.2
>>



From ck.hu at mediatek.com  Fri Dec 20 00:24:15 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 08:24:15 +0000
Subject: [PATCH v3 22/33] drm/mediatek: mtk_hdmi: Move output init to
 mtk_hdmi_register_audio_driver()
In-Reply-To: <20241217154345.276919-23-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-23-angelogioacchino.delregno@collabora.com>
Message-ID: <2c65e6fbe42fb4d7491413b44daefd2af74c1579.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> In preparation for moving the common bits of this driver, merge the
> contents of mtk_hdmi_output_init in mtk_hdmi_register_audio_driver
> function.
> 
> While at it, also remove the "%s driver bound to HDMI" debugging
> print disguised as informative.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_hdmi.c | 28 ++++++++--------------------
>  1 file changed, 8 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index 3ecd0ed59851..2d5cf7352ed2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -1025,20 +1025,6 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi,
>         return 0;
>  }
> 
> -static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
> -{
> -       struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> -
> -       aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> -       aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> -       aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> -       aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> -       aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> -       aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> -
> -       return 0;
> -}
> -
>  static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)
>  {
>         mtk_hdmi_hw_send_aud_packet(hdmi, true);
> @@ -1617,6 +1603,7 @@ static void mtk_hdmi_unregister_audio_driver(void *data)
>  static int mtk_hdmi_register_audio_driver(struct device *dev)
>  {
>         struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +       struct hdmi_audio_param *aud_param = &hdmi->aud_param;
>         struct hdmi_codec_pdata codec_data = {
>                 .ops = &mtk_hdmi_audio_codec_ops,
>                 .max_i2s_channels = 2,
> @@ -1625,6 +1612,13 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
>         };
>         int ret;
> 
> +       aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +       aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +       aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> +       aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> +       aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> +       aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> +
>         hdmi->audio_pdev = platform_device_register_data(dev,
>                                                          HDMI_CODEC_DRV_NAME,
>                                                          PLATFORM_DEVID_AUTO,
> @@ -1640,7 +1634,6 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
>                 return ret;
>         }
> 
> -       DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
>         return 0;
>  }
> 
> @@ -1669,11 +1662,6 @@ static int mtk_hdmi_probe(struct platform_device *pdev)
>         mutex_init(&hdmi->update_plugged_status_lock);
>         platform_set_drvdata(pdev, hdmi);
> 
> -       ret = mtk_hdmi_output_init(hdmi);
> -       if (ret)
> -               return dev_err_probe(dev, ret,
> -                                    "Failed to initialize hdmi output\n");
> -

I think without this merge, mtk_hdmi_output_init() could still be common code.
So the reason is weird. This merge look not necessary.

Regards,
CK

>         ret = mtk_hdmi_register_audio_driver(dev);
>         if (ret)
>                 return dev_err_probe(dev, ret,
> --
> 2.47.0
> 


From damon.ding at rock-chips.com  Fri Dec 20 00:29:27 2024
From: damon.ding at rock-chips.com (Damon Ding)
Date: Fri, 20 Dec 2024 16:29:27 +0800
Subject: [PATCH v3 08/15] drm/rockchip: analogix_dp: Add support to get
 panel from the DP AUX bus
In-Reply-To: <aiggslcdbdmnc2amlvmzycyxmu3f5zp6kt4ifgzq5gkuugmnem@oqnwf4o7hbss>
References: <20241219080604.1423600-1-damon.ding@rock-chips.com>
 <20241219080604.1423600-9-damon.ding@rock-chips.com>
 <aiggslcdbdmnc2amlvmzycyxmu3f5zp6kt4ifgzq5gkuugmnem@oqnwf4o7hbss>
Message-ID: <3663bbec-fcb2-4f93-aae6-3c2082491069@rock-chips.com>

Hi Dmitry,

On 2024/12/20 8:16, Dmitry Baryshkov wrote:
> On Thu, Dec 19, 2024 at 04:05:57PM +0800, Damon Ding wrote:
>> The rockchip_dp_of_panel_on_aux_bus() helps to check whether the DT
>> configurations related to the DP AUX bus are correct or not.
>>
>> If failed to get the panel from the platform bus, it is good to try
>> the DP AUX bus. Then, the probing process will continue until it enters
>> the analogix_dp_bind(), where devm_of_dp_aux_populate_bus() is called
>> after &analogix_dp_device.aux has been initialized.
> 
> No. devm_of_dp_aux_populate_bus() should be called before bind(). And
> bind should only be called from the done_probing() callback. The reason
> is very simple: the panel driver might be built as a module and might be
> not available when the analogix driver is being probed.
> 
> Also, please invert the logic of the commit message (and the driver).
> The platform bus should be a fallback if there is no AUX bus panel, not
> other way around.
> 

I have tried the logic as you recommanded, and it is really a good way. 
I will fix this in the next version.

>>
>> Signed-off-by: Damon Ding <damon.ding at rock-chips.com>
>> ---
>>   .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 24 +++++++++++++++++--
>>   1 file changed, 22 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>> index ba5263f85ee2..60c902abf40b 100644
>> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>> @@ -317,6 +317,24 @@ static const struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs =
>>   	.atomic_check = rockchip_dp_drm_encoder_atomic_check,
>>   };
>>   
>> +static bool rockchip_dp_of_panel_on_aux_bus(const struct device_node *np)
>> +{
>> +	struct device_node *bus_node, *panel_node;
>> +
>> +	bus_node = of_get_child_by_name(np, "aux-bus");
>> +	if (!bus_node)
>> +		return false;
>> +
>> +	panel_node = of_get_child_by_name(bus_node, "panel");
>> +	of_node_put(bus_node);
>> +	if (!panel_node)
>> +		return false;
>> +
>> +	of_node_put(panel_node);
>> +
>> +	return true;
>> +}
>> +
>>   static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
>>   {
>>   	struct device *dev = dp->dev;
>> @@ -435,8 +453,10 @@ static int rockchip_dp_probe(struct platform_device *pdev)
>>   		return -ENODEV;
>>   
>>   	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
>> -	if (ret < 0)
>> -		return ret;
>> +	if (ret < 0) {
>> +		if (!rockchip_dp_of_panel_on_aux_bus(dev->of_node))
>> +			return ret;
>> +	}
>>   
>>   	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
>>   	if (!dp)
>> -- 
>> 2.34.1
>>
> 

Best regards,
Damon



From ck.hu at mediatek.com  Fri Dec 20 00:31:35 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 08:31:35 +0000
Subject: [PATCH v3 23/33] drm/mediatek: mtk_hdmi: Use devm managed version
 of drm_bridge_add
In-Reply-To: <20241217154345.276919-24-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-24-angelogioacchino.delregno@collabora.com>
Message-ID: <bb26fb95bc38087ebc1b915fead920fc3a01a077.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Simplify the probe/remove functions by using devm_drm_bridge_add()
> as now there is no more need to manually remove the bridge.

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_hdmi.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index 2d5cf7352ed2..5d46d486c68f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -1674,14 +1674,15 @@ static int mtk_hdmi_probe(struct platform_device *pdev)
>         hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
>         hdmi->bridge.vendor = "MediaTek";
>         hdmi->bridge.product = "On-Chip HDMI";
> -       drm_bridge_add(&hdmi->bridge);
> +
> +       ret = devm_drm_bridge_add(dev, &hdmi->bridge);
> +       if (ret)
> +               return dev_err_probe(dev, ret, "Failed to add bridge\n");
> 
>         ret = mtk_hdmi_clk_enable_audio(hdmi);
> -       if (ret) {
> -               drm_bridge_remove(&hdmi->bridge);
> +       if (ret)
>                 return dev_err_probe(dev, ret,
>                                      "Failed to enable audio clocks\n");
> -       }
> 
>         return 0;
>  }
> @@ -1690,7 +1691,6 @@ static void mtk_hdmi_remove(struct platform_device *pdev)
>  {
>         struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
> 
> -       drm_bridge_remove(&hdmi->bridge);
>         mtk_hdmi_clk_disable_audio(hdmi);
>  }
> 
> --
> 2.47.0
> 


From vishal.sagar at amd.com  Fri Dec 20 00:31:42 2024
From: vishal.sagar at amd.com (Sagar, Vishal)
Date: Fri, 20 Dec 2024 08:31:42 +0000
Subject: [PATCH] drm: xlnx: zynqmp_dpsub: Fix kernel doc
In-Reply-To: <20241220-xilinx-dp-audio-doc-fix-v1-1-cc488996e463@ideasonboard.com>
References: <20241220-xilinx-dp-audio-doc-fix-v1-1-cc488996e463@ideasonboard.com>
Message-ID: <BL1PR12MB596939BC3BB3E228DAB8415A9C072@BL1PR12MB5969.namprd12.prod.outlook.com>

[AMD Official Use Only - AMD Internal Distribution Only]

Hi Tomi,

Thanks for the patch.

> -----Original Message-----
> From: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> Sent: Friday, December 20, 2024 8:30 AM
> To: Laurent Pinchart <laurent.pinchart at ideasonboard.com>; Maarten Lankhorst
> <maarten.lankhorst at linux.intel.com>; Maxime Ripard <mripard at kernel.org>;
> Thomas Zimmermann <tzimmermann at suse.de>; David Airlie
> <airlied at gmail.com>; Simona Vetter <simona at ffwll.ch>; Jonathan Corbet
> <corbet at lwn.net>; Simek, Michal <michal.simek at amd.com>; Sagar, Vishal
> <vishal.sagar at amd.com>
> Cc: dri-devel at lists.freedesktop.org; linux-doc at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Tomi Valkeinen
> <tomi.valkeinen at ideasonboard.com>
> Subject: [PATCH] drm: xlnx: zynqmp_dpsub: Fix kernel doc
>
> Fix two kernel doc warnings introduced by the recent DP audio patch:
>
> - Add a doc line for the new "audio" field
> - Remove a reference to zynqmp_dpsub.c from zynqmp.rst, as the .c file
>   no longer has structured comments
>
> Fixes: 3ec5c1579305 ("drm: xlnx: zynqmp_dpsub: Add DP audio support")
> Closes: https://lore.kernel.org/all/20241220154208.720d990b at canb.auug.org.au/
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
>  Documentation/gpu/zynqmp.rst        | 2 --
>  drivers/gpu/drm/xlnx/zynqmp_dpsub.h | 1 +
>  2 files changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/Documentation/gpu/zynqmp.rst b/Documentation/gpu/zynqmp.rst
> index f57bfa0ad6ec..1a6f9193de22 100644
> --- a/Documentation/gpu/zynqmp.rst
> +++ b/Documentation/gpu/zynqmp.rst
> @@ -144,6 +144,4 @@ Internals
>
>  .. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_dp.c
>
> -.. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_dpsub.c
> -
>  .. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_kms.c
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
> b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
> index 49875529c2a4..d771b8b199e0 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
> @@ -60,6 +60,7 @@ struct zynqmp_dpsub_audio;
>   * @layers: Video and graphics layers
>   * @dp: The DisplayPort controller
>   * @dma_align: DMA alignment constraint (must be a power of 2)
> + * @audio: DP audio data
>   */
>  struct zynqmp_dpsub {
>       struct device *dev;
>
> ---
> base-commit: 74ef9527bd87ead62deabe749a6d867af748d448
> change-id: 20241220-xilinx-dp-audio-doc-fix-0651029616e7
>
> Best regards,
> --
> Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>

This looks good to me. Apologies for missing this in my earlier review.

I tested this patch with
./scripts/kernel-doc -none drivers/gpu/drm/xlnx/zynqmp_dpsub.c
make htmldocs

Please feel free to add

Reviewed-by: Vishal Sagar <vishal.sagar at amd.com>

Regards
Vishal Sagar

From a.fatoum at pengutronix.de  Fri Dec 20 00:40:06 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Fri, 20 Dec 2024 09:40:06 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
 <Z2UeKZcpeRUt2OQ4@pengutronix.de>
 <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2Ugt8NVued0_4c4@pengutronix.de>
 <AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b@pengutronix.de>

Hi,

On 20.12.24 09:06, Carlos Song wrote:
>> -----Original Message-----
>> On Fri, Dec 20, 2024 at 07:38:47AM +0000, Carlos Song wrote:
>>>> -----Original Message-----
>>>> From: Oleksij Rempel <o.rempel at pengutronix.de>
>>>> Sent: Friday, December 20, 2024 3:35 PM
>>>> To: Ahmad Fatoum <a.fatoum at pengutronix.de>
>>>> Cc: Carlos Song <carlos.song at nxp.com>; Andi Shyti
>>>> <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>;
>>>> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
>>>> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
>>>> linux-arm-kernel at lists.infradead.org;
>>>> linux-kernel at vger.kernel.org; Clark Wang <xiaoning.wang at nxp.com>
>>>> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing

>>>>>> I think this is what you want to see, right?
>>>>>
>>>>> This loses the information why the error happens (ret). Using
>>>>> dev_err_probe even if no probe deferral is expected in that branch
>>>>> is perfectly fine and the kernel-doc even points it out:
>>>>>
>>>>>   Using this helper in your probe function is totally fine even if @err
>>>>>   is known to never be -EPROBE_DEFER.
>>>>
>>>> Thank you for the feedback. While I recognize the benefits of
>>>> dev_err_probe() for compact and standardized error handling, using
>>>> it without returning its result raises a red flag.

Agreed, which is what spawned this thread in the first place.

If we want to ignore errors intentionally, I think a comment
like the following would make this clearer:

  /*
   * As we can always fall back to PIO, let's ignore the error setting up
   * DMA and see if we run into errors while setting up PIO mode.
   */


>>>> The function's primary purpose is to combine error logging with
>>>> returning the error code. If the return value is not used, it can
>>>> create confusion and suggests potential oversight or unintended
>>>> behavior. This misuse might mislead readers into thinking that the
>>>> function always returns at that point, which is not the case here.
>>>>
>>>> In this scenario, using dev_err() directly is more explicit and
>>>> avoids any ambiguity about the control flow or error handling
>>>> intent. It keeps the code clear and aligned with its actual behavior.

This is a fair point. I don't mind whether we use dev_err_probe or
dev_err with a return code, it's up to you ultimately. I just wanted
the error code to be included and I think a comment would be a good
idea to avoid confusion (provided we keep behavior as-is).

>>> how about this?
>>>
>>> +       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
>>> +       if (ret) {
>>> +               if (ret == -EPROBE_DEFER)
>>> +                       goto clk_notifier_unregister;
>>> +               else if (ret == -ENODEV)
>>> +                       dev_dbg(&pdev->dev, "Only use PIO mode\n");
>>> +               else
>>> +                       dev_err(&pdev->dev, "Failed to setup DMA (%d),
>> only use PIO mode\n", ret);
>>> +       }
>>
>> Please use human readable version of error value. In this case it will
>> be:
>>   dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n",
>> ERR_PTR(ret));

Sounds good to me.

> Hi, the ret is from i2c_imx_dma_request() and look like that ret has been converted by PTR_ERR,
> So the ret error has been human readable version?

I am not sure I understand the question. ERR_PTR() makes an error pointer and %pe
formats that pointer as error message. So you don't need to change any function
return types unless needed, just at the end print it with %pe instead of %d
(and after error pointer conversion if needed).

Cheers,
Ahmad


-- 
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 jinjian.song at fibocom.com  Fri Dec 20 00:50:27 2024
From: jinjian.song at fibocom.com (Jinjian Song)
Date: Fri, 20 Dec 2024 16:50:27 +0800
Subject: [net v2] net: wwan: t7xx: Fix FSM command timeout issue
In-Reply-To: <da90f64c-260a-4329-87bf-1f9ff20a5951@gmail.com>
References: <20241213064720.122615-1-jinjian.song@fibocom.com>
Message-ID: <20241220085027.7692-1-jinjian.song@fibocom.com>

From: Sergey Ryazanov <ryazanov.s.a at gmail.com>

>> Fixes: d785ed945de6 ("net: wwan: t7xx: PCIe reset rescan")
>
>The completion waiting was introduced in a different commit. I believe, 
>the fix tag should be 13e920d93e37 ("net: wwan: t7xx: Add core components")
>

Got it.

[...]
>>   	if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
>>   		*cmd->ret = result;
>
>The memory for the result storage is allocated on the stack as well. And 
>writing it unconditionally can cause unexpected consequences.
>

Got it.

[...]
>>   		wait_ret = wait_for_completion_timeout(&done,
>>   						       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
>> -		if (!wait_ret)
>> +		if (!wait_ret) {
>> +			cmd->done = NULL;
>
>We cannot access the command memory here, since fsm_finish_command() 
>could release it already.
>

Got it.

[...]
>Here we have an ownership transfer problem and a driver author has tried 
>to solve it, but as noticed, we are still experiencing issues in case of 
>timeout.
>
>The command completion routine should not release the command memory 
>unconditionally. Looks like the references counting approach should help 
>us here. E.g.
>1. grab a reference before we put a command into the queue
>1.1. grab an extra reference if we are going to wait the completion
>2. release the reference as soon as we are done with the command execution
>3. in case of completion waiting release the reference as soon as we are 
>done with waiting due to completion or timeout
>
>Could you try the following patch? Please note, besides the reference 
>counter introduction it also moves completion and result storage inside 
>the command structure as advised by the completion documentation.
>

Hi Sergey,

Yes, the patch works fine, needs some minor modifications, could we 
feedback to the driver author to merge these changes.

diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
index 3931c7a13f5a..265c40b29f56 100644
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c
@@ -104,14 +104,20 @@ void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl *ctl, enum md_state state)
 	fsm_state_notify(ctl->md, state);
 }
 
+static void fsm_release_command(struct kref *ref)
+{
+	struct t7xx_fsm_command *cmd = container_of(ref, typeof(*cmd), refcnt);
+	kfree(cmd);
+}
+
 static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd, int result)
 {
 	if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
-		*cmd->ret = result;
-		complete_all(cmd->done);
+		cmd->result = result;
+		complete_all(&cmd->done);
 	}
 
-	kfree(cmd);
+	kref_put(&cmd->refcnt, fsm_release_command);
 }
 
 static void fsm_del_kf_event(struct t7xx_fsm_event *event)
@@ -475,7 +481,6 @@ static int fsm_main_thread(void *data)
 
 int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id, unsigned int flag)
 {
-	DECLARE_COMPLETION_ONSTACK(done);
 	struct t7xx_fsm_command *cmd;
 	unsigned long flags;
 	int ret;
@@ -487,11 +492,13 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id
 	INIT_LIST_HEAD(&cmd->entry);
 	cmd->cmd_id = cmd_id;
 	cmd->flag = flag;
+	kref_init(&cmd->refcnt);
 	if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
-		cmd->done = &done;
-		cmd->ret = &ret;
+		init_completion(&cmd->done);
+		kref_get(&cmd->refcnt);
 	}
 
+	kref_get(&cmd->refcnt);
 	spin_lock_irqsave(&ctl->command_lock, flags);
 	list_add_tail(&cmd->entry, &ctl->command_queue);
 	spin_unlock_irqrestore(&ctl->command_lock, flags);
@@ -501,11 +508,11 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id
 	if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
 		unsigned long wait_ret;
 
-		wait_ret = wait_for_completion_timeout(&done,
+		wait_ret = wait_for_completion_timeout(&cmd->done,
 						       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
-		if (!wait_ret)
-			return -ETIMEDOUT;
 
+		ret = wait_ret ? cmd->result : -ETIMEDOUT;
+		kref_put(&cmd->refcnt, fsm_release_command);
 		return ret;
 	}
 
diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
index 7b0a9baf488c..6e0601bb752e 100644
--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h
+++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h
@@ -110,8 +110,9 @@ struct t7xx_fsm_command {
 	struct list_head	entry;
 	enum t7xx_fsm_cmd_state	cmd_id;
 	unsigned int		flag;
-	struct completion	*done;
-	int			*ret;
+	struct completion	done;
+	int			result;
+	struct kref		refcnt;
 };
 
 struct t7xx_fsm_notifier {

Thanks.

Jinjian,
Best Regards.


From ck.hu at mediatek.com  Fri Dec 20 01:11:57 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 20 Dec 2024 09:11:57 +0000
Subject: [PATCH v3 25/33] drm/mediatek: mtk_hdmi: Remove goto in
 mtk_hdmi_clk_enable_audio()
In-Reply-To: <20241217154345.276919-26-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-26-angelogioacchino.delregno@collabora.com>
Message-ID: <02ff0113fa1d6c0215b64ec3d353ec61efd34733.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> If the clk_prepare_enable() call for the SPDIF clock fails, just
> disable and unprepare the clock in the error check branch and
> return immediately instead of jumping to the end with a goto,
> slightly reducing code size.
> 
> This commit brings no functional changes.

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_hdmi.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index 7e4536391cfb..dbcb9fb09edd 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -1095,13 +1095,12 @@ static int mtk_hdmi_clk_enable_audio(struct mtk_hdmi *hdmi)
>                 return ret;
> 
>         ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]);
> -       if (ret)
> -               goto err;
> +       if (ret) {
> +               clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);
> +               return ret;
> +       }
> 
>         return 0;
> -err:
> -       clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);
> -       return ret;
>  }
> 
>  static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi)
> --
> 2.47.0
> 


From a.fatoum at pengutronix.de  Fri Dec 20 01:12:49 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Fri, 20 Dec 2024 10:12:49 +0100
Subject: [PATCH 10/10] arm64: dts: imx8mp-skov: increase I2C clock
 frequency for RTC
In-Reply-To: <Z2Rw8qnn9hULyh8l@lizhi-Precision-Tower-5810>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-10-38bf80dc22df@pengutronix.de>
 <Z2RcJCaYC2FW3Ks6@lizhi-Precision-Tower-5810>
 <30dbe486-7e36-426d-8fa4-3ecd83193a10@pengutronix.de>
 <Z2Rw8qnn9hULyh8l@lizhi-Precision-Tower-5810>
Message-ID: <2ae085fa-6f13-4eb7-88c1-e625309fc35e@pengutronix.de>

Hello Frank,

On 19.12.24 20:16, Frank Li wrote:
> On Thu, Dec 19, 2024 at 06:51:35PM +0100, Ahmad Fatoum wrote:
>> On 19.12.24 18:47, Frank Li wrote:
>>> On Thu, Dec 19, 2024 at 08:25:34AM +0100, Ahmad Fatoum wrote:
>>>> From: Oleksij Rempel <o.rempel at pengutronix.de>
>>>>
>>>> The NXP PCF85063TP RTC we use is capable of up to 400 kHz of SCL clock
>>>> frequency, so let's make use of this instead of the 100 kHz bus frequency
>>>> we are currently using.
>>>
>>> Increase I2C frequency to 400khz from 100kHz because NXP PCF85063TP RTC
>>> support it.
>>
>> Unlike your other suggestions, these is no information lost by rewriting
>> the commit message as you suggest. I don't mind, but must admit it feels
>> like bikeshedding. What is your concrete objection to my commit message?
> 
> According to
> https://docs.kernel.org/process/submitting-patches.html
> 
> Describe your changes in imperative mood, e.g. ?make xyzzy do frotz?
> instead of ?[This patch] makes xyzzy do frotz? or
> ?[I] changed xyzzy to do frotz?, as if you are giving orders to the
> codebase to change its behaviour.

I have to disagree with your interpretation. The imperative mood is primarily
expected for commit message titles, but if you take a look at normal commit
message _bodies_ that make it into the kernel, you'll find that a whole lot
of them start off like I do: Describe the situation and then what's done about
it.

I personally find that this is often easier to follow than just having two
imperatives back-to-back.

I have just Cc'd you on an RFC patch to amend the documentation you linked
to reflect this. I am happy to continue the discussion over there:

https://lore.kernel.org/workflows/20241220-submitting-patches-imperative-v1-0-ee874c1859b3 at pengutronix.de/T/#t

Thanks,
Ahmad

> 
> Generally, avoid use
> 
> "this patch ..."
> "let's ...."
> "we do ... for ... "
> 
> Just simple said
> 
> Do ... to ...
> Do ... because ...
> 
> Frank
> 
>>
>> Thanks,
>> Ahmad
>>
>>
>>>
>>> Frank
>>>
>>>>
>>>> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
>>>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
>>>> ---
>>>>  arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 2 +-
>>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
>>>> index a683f46fcbab..ec7857db7bf0 100644
>>>> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
>>>> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
>>>> @@ -333,7 +333,7 @@ reg_nvcc_sd2: LDO5 {
>>>>  };
>>>>
>>>>  &i2c3 {
>>>> -	clock-frequency = <100000>;
>>>> +	clock-frequency = <400000>;
>>>>  	pinctrl-names = "default";
>>>>  	pinctrl-0 = <&pinctrl_i2c3>;
>>>>  	status = "okay";
>>>>
>>>> --
>>>> 2.39.5
>>>>
>>>
>>
>>
>> --
>> 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 |
> 


-- 
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 carlos.song at nxp.com  Fri Dec 20 01:23:23 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Fri, 20 Dec 2024 09:23:23 +0000
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b@pengutronix.de>
References: <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
 <Z2UeKZcpeRUt2OQ4@pengutronix.de>
 <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2Ugt8NVued0_4c4@pengutronix.de>
 <AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b@pengutronix.de>
Message-ID: <AM0PR0402MB39374CFFA66D8121DB218334E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Ahmad Fatoum <a.fatoum at pengutronix.de>
> Sent: Friday, December 20, 2024 4:40 PM
> To: Carlos Song <carlos.song at nxp.com>; Oleksij Rempel
> <o.rempel at pengutronix.de>
> Cc: Andi Shyti <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>;
> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Clark Wang
> <xiaoning.wang at nxp.com>
> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
>
> 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,
>
> On 20.12.24 09:06, Carlos Song wrote:
> >> -----Original Message-----
> >> On Fri, Dec 20, 2024 at 07:38:47AM +0000, Carlos Song wrote:
> >>>> -----Original Message-----
> >>>> From: Oleksij Rempel <o.rempel at pengutronix.de>
> >>>> Sent: Friday, December 20, 2024 3:35 PM
> >>>> To: Ahmad Fatoum <a.fatoum at pengutronix.de>
> >>>> Cc: Carlos Song <carlos.song at nxp.com>; Andi Shyti
> >>>> <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>;
> >>>> kernel at pengutronix.de; shawnguo at kernel.org;
> s.hauer at pengutronix.de;
> >>>> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> >>>> linux-arm-kernel at lists.infradead.org;
> >>>> linux-kernel at vger.kernel.org; Clark Wang <xiaoning.wang at nxp.com>
> >>>> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
>
> >>>>>> I think this is what you want to see, right?
> >>>>>
> >>>>> This loses the information why the error happens (ret). Using
> >>>>> dev_err_probe even if no probe deferral is expected in that branch
> >>>>> is perfectly fine and the kernel-doc even points it out:
> >>>>>
> >>>>>   Using this helper in your probe function is totally fine even if @err
> >>>>>   is known to never be -EPROBE_DEFER.
> >>>>
> >>>> Thank you for the feedback. While I recognize the benefits of
> >>>> dev_err_probe() for compact and standardized error handling, using
> >>>> it without returning its result raises a red flag.
>
> Agreed, which is what spawned this thread in the first place.
>
> If we want to ignore errors intentionally, I think a comment like the following
> would make this clearer:
>
>   /*
>    * As we can always fall back to PIO, let's ignore the error setting up
>    * DMA and see if we run into errors while setting up PIO mode.
>    */
>
>
> >>>> The function's primary purpose is to combine error logging with
> >>>> returning the error code. If the return value is not used, it can
> >>>> create confusion and suggests potential oversight or unintended
> >>>> behavior. This misuse might mislead readers into thinking that the
> >>>> function always returns at that point, which is not the case here.
> >>>>
> >>>> In this scenario, using dev_err() directly is more explicit and
> >>>> avoids any ambiguity about the control flow or error handling
> >>>> intent. It keeps the code clear and aligned with its actual behavior.
>
> This is a fair point. I don't mind whether we use dev_err_probe or dev_err with
> a return code, it's up to you ultimately. I just wanted the error code to be
> included and I think a comment would be a good idea to avoid confusion
> (provided we keep behavior as-is).
>
> >>> how about this?
> >>>
> >>> +       ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> >>> +       if (ret) {
> >>> +               if (ret == -EPROBE_DEFER)
> >>> +                       goto clk_notifier_unregister;
> >>> +               else if (ret == -ENODEV)
> >>> +                       dev_dbg(&pdev->dev, "Only use PIO
> mode\n");
> >>> +               else
> >>> +                       dev_err(&pdev->dev, "Failed to setup DMA
> >>> + (%d),
> >> only use PIO mode\n", ret);
> >>> +       }
> >>
> >> Please use human readable version of error value. In this case it
> >> will
> >> be:
> >>   dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO
> >> mode\n", ERR_PTR(ret));
>
> Sounds good to me.
>
> > Hi, the ret is from i2c_imx_dma_request() and look like that ret has
> > been converted by PTR_ERR, So the ret error has been human readable
> version?
>
> I am not sure I understand the question. ERR_PTR() makes an error pointer
> and %pe formats that pointer as error message. So you don't need to change
> any function return types unless needed, just at the end print it with %pe
> instead of %d (and after error pointer conversion if needed).
>
> Cheers,
> Ahmad
>

Sorry, I don't know if I understand it incorrectly.
I review other driver code, most choose to return error value but not an error pointer.
Shouldn't error value ?be more readable than error pointers?
When we see -110 we know TIMEOUT and we see -12 we know NO MEM.

i2c_imx_dma_request is using PTR_ERR to convert pointer to error value[1].
I don't know why need to use ERR_PTR to reconvert the value to pointer:

dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n", ERR_PTR(ret));

Is there some strong reason?

[1] https://lore.kernel.org/imx/AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072 at AM0PR0402MB3937.eurprd04.prod.outlook.com/
>
> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C594497db1b5
> 44e479a8f08dd20d1e88e%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> %7C638702808104903131%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGki
> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ
> %3D%3D%7C0%7C%7C%7C&sdata=EnhsIFlBooqjB%2FSRWF7uAqRHE3yN6rbdD
> 1yQueTrRus%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |

From jbrunet at baylibre.com  Fri Dec 20 01:23:37 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 10:23:37 +0100
Subject: [PATCH] clk: amlogic: g12a: fix mmc A peripheral clock
In-Reply-To: <20241213-amlogic-clk-g12a-mmca-fix-v1-1-5af421f58b64@baylibre.com>
References: <20241213-amlogic-clk-g12a-mmca-fix-v1-1-5af421f58b64@baylibre.com>
Message-ID: <173468657763.2759236.17472540885807657211.b4-ty@baylibre.com>

Applied to clk-meson (clk-meson-next), thanks!

[1/1] clk: amlogic: g12a: fix mmc A peripheral clock
      https://github.com/BayLibre/clk-meson/commit/799ce46951dc

Best regards,
--
Jerome


From jbrunet at baylibre.com  Fri Dec 20 01:23:38 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 10:23:38 +0100
Subject: [PATCH] clk: amlogic: g12b: fix cluster A parent data
In-Reply-To: <20241213-amlogic-clk-g12a-cpua-parent-fix-v1-1-d8c0f41865fe@baylibre.com>
References: <20241213-amlogic-clk-g12a-cpua-parent-fix-v1-1-d8c0f41865fe@baylibre.com>
Message-ID: <173468657763.2759236.18371740322790756565.b4-ty@baylibre.com>

Applied to clk-meson (clk-meson-next), thanks!

[1/1] clk: amlogic: g12b: fix cluster A parent data
      https://github.com/BayLibre/clk-meson/commit/1909d0d351ed

Best regards,
--
Jerome


From a.fatoum at pengutronix.de  Fri Dec 20 01:31:59 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Fri, 20 Dec 2024 10:31:59 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <AM0PR0402MB39374CFFA66D8121DB218334E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
 <Z2UeKZcpeRUt2OQ4@pengutronix.de>
 <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2Ugt8NVued0_4c4@pengutronix.de>
 <AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b@pengutronix.de>
 <AM0PR0402MB39374CFFA66D8121DB218334E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <451e8c12-7b45-4b12-af10-63f60ba6e92e@pengutronix.de>

Hi Carlos,

On 20.12.24 10:23, Carlos Song wrote:
>>> Hi, the ret is from i2c_imx_dma_request() and look like that ret has
>>> been converted by PTR_ERR, So the ret error has been human readable
>> version?
>>
>> I am not sure I understand the question. ERR_PTR() makes an error pointer
>> and %pe formats that pointer as error message. So you don't need to change
>> any function return types unless needed, just at the end print it with %pe
>> instead of %d (and after error pointer conversion if needed).
> 
> Sorry, I don't know if I understand it incorrectly.
> I review other driver code, most choose to return error value but not an error pointer.
> Shouldn't error value ?be more readable than error pointers?
> When we see -110 we know TIMEOUT and we see -12 we know NO MEM.

I know -110, but -12 I need to look up :)
Both are cryptic to end users, which is why %pe was added
on top of the existing %p:

If CONFIG_SYMBOLIC_ERRNAME is enabled %pe expands to an error string,
e.g. "ENOMEM" or "ETIMEDOUT". If it's disabled, you get the same
error number that was printed raw before.

Cheers,
Ahmad

> 
> i2c_imx_dma_request is using PTR_ERR to convert pointer to error value[1].
> I don't know why need to use ERR_PTR to reconvert the value to pointer:
> 
> dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n", ERR_PTR(ret));
> 
> Is there some strong reason?
> 
> [1] https://lore.kernel.org/imx/AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072 at AM0PR0402MB3937.eurprd04.prod.outlook.com/
>>
>> --
>> Pengutronix e.K.                           |
>> |
>> Steuerwalder Str. 21                       |
>> http://www.pen/
>> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C594497db1b5
>> 44e479a8f08dd20d1e88e%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
>> %7C638702808104903131%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGki
>> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ
>> %3D%3D%7C0%7C%7C%7C&sdata=EnhsIFlBooqjB%2FSRWF7uAqRHE3yN6rbdD
>> 1yQueTrRus%3D&reserved=0  |
>> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
>> |
>> Amtsgericht Hildesheim, HRA 2686           | Fax:
>> +49-5121-206917-5555 |


-- 
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 zengheng4 at huawei.com  Fri Dec 20 01:36:23 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Fri, 20 Dec 2024 17:36:23 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 4/5] arm_mpam:
 Automatically synchronize the configuration of all sub-monitoring groups
In-Reply-To: <Z1sM7TMK+BHQEwgI@e133380.arm.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
 <20241207092136.2488426-5-zengheng4@huawei.com>
 <Z1sM7TMK+BHQEwgI@e133380.arm.com>
Message-ID: <65e556b6-61e1-7d84-ab8a-becaf55dbb18@huawei.com>



On 2024/12/13 0:18, Dave Martin wrote:
> Hi,
> 
>> @@ -3072,9 +3080,20 @@ struct mpam_write_config_arg {
>>   
>>   static int __write_config(void *arg)
>>   {
>> +	int closid_num = resctrl_arch_get_num_closid(NULL);
>>   	struct mpam_write_config_arg *c = arg;
>> +	u32 reqpartid, req_idx;
>> +
>> +	WARN_ON(c->partid >= closid_num);
>>   
>> -	mpam_reprogram_ris_partid(c->ris, c->partid, &c->comp->cfg[c->partid]);
>> +	/* Synchronize the configuration to each sub-monitoring group. */
>> +	for (req_idx = 0; req_idx < get_num_reqpartid_per_closid();
>> +	     req_idx++) {
>> +		reqpartid = req_idx * closid_num + c->partid;
>> +
>> +		mpam_reprogram_ris_partid(c->ris, reqpartid,
>> +					 &c->comp->cfg[c->partid]);
>> +	}
>>   
>>   	return 0;
>>   }
> 
> I haven't decided whether this iteration belongs here or in
> mpam_resctrl.c.
> 
> Your approach looks like it should work; I do it in
> resctrl_arch_update_one() instead [1], but I think the approaches are
> pretty much equivalent -- but let me know if you have any thoughts on
> it.
> 

Yes, the actual functions of these two locations are essentially the
same. However, at the __write_config position, we can reduce the
repeated judgments of cfg[partid] in mpam_update_config() and also
decrease the times of smp_call remote invocations.

What about your option towards it?

Best regards,
Zeng Heng


From quic_ylal at quicinc.com  Fri Dec 20 01:39:07 2024
From: quic_ylal at quicinc.com (Yogesh Lal)
Date: Fri, 20 Dec 2024 15:09:07 +0530
Subject: [PATCH v2] irqchip: gic-v3: Handle failure case of CPU enters low power state
Message-ID: <20241220093907.2747601-1-quic_ylal@quicinc.com>

Adding a new condition in gic_cpu_pm_notifier to address instances
where the CPU fails to enter low power mode (CPU_PM_ENTER_FAILED).
The CPU_PM framework signals CPU_PM_ENTER_FAILED upon such failures.

When the CPU attempts to enter low power mode, it disables the
redistributor and Group 1 interrupts and reinitializes the system
registers upon wakeup.

In case of failure while entering low power mode, it is necessary
to re-enable the redistributor and Group 1 interrupts to restore
normal operation.

Signed-off-by: Yogesh Lal <quic_ylal at quicinc.com>
---
 drivers/irqchip/irq-gic-v3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

---
Changes in V2:

* Updating the commit message
* Link to V1: https://lore.kernel.org/all/1671734140-15935-1-git-send-email-quic_ylal at quicinc.com/
---

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c19083bfb943..2a99ca5c3f1d 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1495,7 +1495,7 @@ static int gic_retrigger(struct irq_data *data)
 static int gic_cpu_pm_notifier(struct notifier_block *self,
 			       unsigned long cmd, void *v)
 {
-	if (cmd == CPU_PM_EXIT) {
+	if (cmd == CPU_PM_EXIT || cmd == CPU_PM_ENTER_FAILED) {
 		if (gic_dist_security_disabled())
 			gic_enable_redist(true);
 		gic_cpu_sys_reg_init();
-- 
2.34.1



From sjoerd at collabora.com  Fri Dec 20 01:55:06 2024
From: sjoerd at collabora.com (Sjoerd Simons)
Date: Fri, 20 Dec 2024 10:55:06 +0100
Subject: [PATCH] arm64: dts: mediatek: Set ethernet alias for mt8365-evk
Message-ID: <20241220095522.2026002-1-sjoerd@collabora.com>

Configure an the ethernet alias to match the ethernet controller (even
if it's off by default). This allows e.g. u-boot to configure the mac
address on boot properly

Signed-off-by: Sjoerd Simons <sjoerd at collabora.com>
---

 arch/arm64/boot/dts/mediatek/mt8365-evk.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8365-evk.dts b/arch/arm64/boot/dts/mediatek/mt8365-evk.dts
index 7d90112a7e27..44c61094c4d5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8365-evk.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8365-evk.dts
@@ -21,6 +21,7 @@ / {
 
 	aliases {
 		serial0 = &uart0;
+		ethernet = &ethernet;
 	};
 
 	chosen {
-- 
2.45.2



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:27 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:27 +0100
Subject: [PATCH v2 9/9] arm64: dts: st: add timer nodes on stm32mp257f-ev1
In-Reply-To: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241220095927.1122782-10-fabrice.gasnier@foss.st.com>

Configure timer nodes on stm32mp257f-ev1:
- Timer3 CH2 is available on mikroBUS connector for PWM
- timer8 CH1, timer8 CH4, timer10 CH1 and timer12 CH2 are available
  on EXPANSION connector.
Timers are kept disabled by default, so the pins can be used for any
other purpose (and the timers can be assigned to any of the processors).
Arbitrary choice is to use all these timers as PWM (or counter on
internal clock signal), except for timer10 that is configured with
CH1 as an input (for capture).

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 58 ++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index 6f393b082789..6601ca411006 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -156,6 +156,64 @@ &spi8 {
 	status = "disabled";
 };
 
+&timers3 {
+	status = "disabled";
+	counter {
+		status = "okay";
+	};
+	pwm {
+		pinctrl-0 = <&pwm3_pins_a>;
+		pinctrl-1 = <&pwm3_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer at 2 {
+		status = "okay";
+	};
+};
+
+&timers8 {
+	status = "disabled";
+	counter {
+		status = "okay";
+	};
+	pwm {
+		pinctrl-0 = <&pwm8_pins_a>;
+		pinctrl-1 = <&pwm8_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer at 7 {
+		status = "okay";
+	};
+};
+
+&timers10 {
+	status = "disabled";
+	counter {
+		pinctrl-0 = <&tim10_counter_pins_a>;
+		pinctrl-1 = <&tim10_counter_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+};
+
+&timers12 {
+	status = "disabled";
+	counter {
+		status = "okay";
+	};
+	pwm {
+		pinctrl-0 = <&pwm12_pins_a>;
+		pinctrl-1 = <&pwm12_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer at 11 {
+		status = "okay";
+	};
+};
+
 &usart2 {
 	pinctrl-names = "default", "idle", "sleep";
 	pinctrl-0 = <&usart2_pins_a>;
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:19 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:19 +0100
Subject: [PATCH v2 1/9] dt-bindings: mfd: stm32-timers: add support for stm32mp25
In-Reply-To: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241220095927.1122782-2-fabrice.gasnier@foss.st.com>

Add a new stm32mp25 compatible to stm32-timer dt-bindings in order to
support the STM32MP25 SoC. Some features has been added or updated in
the stm32-timer timer such as:
- hardware configuration and identification registers to read the timer
  version and capabilities (counter width, number of channels...)
- dithering mode (can be used to extend PWM resolution)
- input triggers list
- new counter modes
- various bit-field updates
- power-domains property
Timer trigger identifier can be up to 19 (from timer 20)

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 .../bindings/mfd/st,stm32-timers.yaml          | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml b/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
index b0e438ff4950..66aa1550a4e5 100644
--- a/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
+++ b/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
@@ -21,7 +21,9 @@ maintainers:
 
 properties:
   compatible:
-    const: st,stm32-timers
+    enum:
+      - st,stm32-timers
+      - st,stm32mp25-timers
 
   reg:
     maxItems: 1
@@ -36,6 +38,9 @@ properties:
   resets:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
   dmas:
     minItems: 1
     maxItems: 7
@@ -77,7 +82,9 @@ properties:
 
     properties:
       compatible:
-        const: st,stm32-pwm
+        enum:
+          - st,stm32-pwm
+          - st,stm32mp25-pwm
 
       "#pwm-cells":
         const: 3
@@ -113,7 +120,9 @@ properties:
 
     properties:
       compatible:
-        const: st,stm32-timer-counter
+        enum:
+          - st,stm32-timer-counter
+          - st,stm32mp25-timer-counter
 
     required:
       - compatible
@@ -128,12 +137,13 @@ patternProperties:
         enum:
           - st,stm32-timer-trigger
           - st,stm32h7-timer-trigger
+          - st,stm32mp25-timer-trigger
 
       reg:
         description: Identify trigger hardware block.
         items:
           minimum: 0
-          maximum: 16
+          maximum: 19
 
     required:
       - compatible
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:25 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:25 +0100
Subject: [PATCH v2 7/9] arm64: dts: st: add timer nodes on stm32mp251
In-Reply-To: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241220095927.1122782-8-fabrice.gasnier@foss.st.com>

Add timers support on STM32MP25 SoC. Use dedicated compatible to handle
new features and instances introduced with this SoC. STM32MP25 SoC has
various timer flavours, each group has its own specific feature list:
- Advanced-control timers (TIM1/TIM8/TIM20)
- General-purpose timers (TIM2/TIM3/TIM4/TIM5)
- Basic timers (TIM6/TIM7)
- General-purpose timers (TIM10/TIM11/TIM12/TIM13/TIM14)
- General purpose timers (TIM15/TIM16/TIM17)

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 524 +++++++++++++++++++++++++
 1 file changed, 524 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 6fe12e3bd7dd..220fb1a3da71 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -237,6 +237,273 @@ rifsc: bus at 42080000 {
 			#access-controller-cells = <1>;
 			ranges;
 
+			timers2: timer at 40000000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40000000 0x400>;
+				interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM2>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 1>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 1 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <1>;
+					status = "disabled";
+				};
+			};
+
+			timers3: timer at 40010000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40010000 0x400>;
+				interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM3>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 2>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 2 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <2>;
+					status = "disabled";
+				};
+			};
+
+			timers4: timer at 40020000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40020000 0x400>;
+				interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM4>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 3>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 3 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <3>;
+					status = "disabled";
+				};
+			};
+
+			timers5: timer at 40030000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40030000 0x400>;
+				interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM5>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 4>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 4 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+
+			timers6: timer at 40040000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40040000 0x400>;
+				interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM6>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 5>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				timer at 5 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <5>;
+					status = "disabled";
+				};
+			};
+
+			timers7: timer at 40050000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40050000 0x400>;
+				interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM7>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 6>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				timer at 6 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <6>;
+					status = "disabled";
+				};
+			};
+
+			timers12: timer at 40060000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40060000 0x400>;
+				interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM12>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 10>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 11 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <11>;
+					status = "disabled";
+				};
+			};
+
+			timers13: timer at 40070000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40070000 0x400>;
+				interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM13>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 11>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 12 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <12>;
+					status = "disabled";
+				};
+			};
+
+			timers14: timer at 40080000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40080000 0x400>;
+				interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM14>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 12>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 13 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <13>;
+					status = "disabled";
+				};
+			};
+
 			spi2: spi at 400b0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -427,6 +694,136 @@ i2c7: i2c at 40180000 {
 				status = "disabled";
 			};
 
+			timers10: timer at 401c0000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x401c0000 0x400>;
+				interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM10>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 8>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 9 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <9>;
+					status = "disabled";
+				};
+			};
+
+			timers11: timer at 401d0000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x401d0000 0x400>;
+				interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM11>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 9>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 10 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <10>;
+					status = "disabled";
+				};
+			};
+
+			timers1: timer at 40200000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40200000 0x400>;
+				interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "brk", "up", "trg-com", "cc";
+				clocks = <&rcc CK_KER_TIM1>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 0>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 0 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <0>;
+					status = "disabled";
+				};
+			};
+
+			timers8: timer at 40210000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40210000 0x400>;
+				interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "brk", "up", "trg-com", "cc";
+				clocks = <&rcc CK_KER_TIM8>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 7>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 7 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <7>;
+					status = "disabled";
+				};
+			};
+
 			usart6: serial at 40220000 {
 				compatible = "st,stm32h7-uart";
 				reg = <0x40220000 0x400>;
@@ -469,6 +866,99 @@ spi4: spi at 40240000 {
 				status = "disabled";
 			};
 
+			timers15: timer at 40250000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40250000 0x400>;
+				interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM15>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 13>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 14 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <14>;
+					status = "disabled";
+				};
+			};
+
+			timers16: timer at 40260000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40260000 0x400>;
+				interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM16>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 14>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 15 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <15>;
+					status = "disabled";
+				};
+			};
+
+			timers17: timer at 40270000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40270000 0x400>;
+				interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "global";
+				clocks = <&rcc CK_KER_TIM17>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 15>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 16 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <16>;
+					status = "disabled";
+				};
+			};
+
 			spi5: spi at 40280000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -496,6 +986,40 @@ uart9: serial at 402c0000 {
 				status = "disabled";
 			};
 
+			timers20: timer at 40320000 {
+				compatible = "st,stm32mp25-timers";
+				reg = <0x40320000 0x400>;
+				interrupts = <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>;
+				interrupt-names = "brk", "up", "trg-com", "cc";
+				clocks = <&rcc CK_KER_TIM20>;
+				clock-names = "int";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				access-controllers = <&rifsc 16>;
+				power-domains = <&CLUSTER_PD>;
+				status = "disabled";
+
+				counter {
+					compatible = "st,stm32mp25-timer-counter";
+					status = "disabled";
+				};
+
+				pwm {
+					compatible = "st,stm32mp25-pwm";
+					#pwm-cells = <3>;
+					status = "disabled";
+				};
+
+				timer at 19 {
+					compatible = "st,stm32mp25-timer-trigger";
+					reg = <19>;
+					status = "disabled";
+				};
+			};
+
 			usart1: serial at 40330000 {
 				compatible = "st,stm32h7-uart";
 				reg = <0x40330000 0x400>;
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:23 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:23 +0100
Subject: [PATCH v2 5/9] pwm: stm32: add support for stm32mp25
In-Reply-To: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241220095927.1122782-6-fabrice.gasnier@foss.st.com>

Add support for STM32MP25 SoC. Use newly introduced compatible to handle
new features along with registers and bits diversity.
The MFD part of the driver fills in ipidr, so it is used to check the
hardware configuration register, when available to gather the number
of PWM channels and complementary outputs.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
Changes in v2:
Address Uwe review comments:
- Make MAX_PWM_OUTPUT definition less generic: STM32_PWM_MAX_OUTPUT
- No need to initialize 'npwm'
- refactor code, for *num_enabled to use same code path
---
 drivers/pwm/pwm-stm32.c | 42 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index 17e591f61efb..b9aadc473280 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -19,6 +19,7 @@
 #define CCMR_CHANNEL_SHIFT 8
 #define CCMR_CHANNEL_MASK  0xFF
 #define MAX_BREAKINPUT 2
+#define STM32_MAX_PWM_OUTPUT 4
 
 struct stm32_breakinput {
 	u32 index;
@@ -775,10 +776,19 @@ static int stm32_pwm_probe_breakinputs(struct stm32_pwm *priv,
 	return stm32_pwm_apply_breakinputs(priv);
 }
 
-static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
+static void stm32_pwm_detect_complementary(struct stm32_pwm *priv, struct stm32_timers *ddata)
 {
 	u32 ccer;
 
+	if (ddata->ipidr) {
+		u32 val;
+
+		/* Simply read from HWCFGR the number of complementary outputs (MP25). */
+		regmap_read(priv->regmap, TIM_HWCFGR1, &val);
+		priv->have_complementary_output = !!FIELD_GET(TIM_HWCFGR1_NB_OF_DT, val);
+		return;
+	}
+
 	/*
 	 * If complementary bit doesn't exist writing 1 will have no
 	 * effect so we can detect it.
@@ -790,22 +800,39 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
 	priv->have_complementary_output = (ccer != 0);
 }
 
-static unsigned int stm32_pwm_detect_channels(struct regmap *regmap,
+static unsigned int stm32_pwm_detect_channels(struct stm32_timers *ddata,
 					      unsigned int *num_enabled)
 {
+	struct regmap *regmap = ddata->regmap;
 	u32 ccer, ccer_backup;
 
+	regmap_read(regmap, TIM_CCER, &ccer_backup);
+	*num_enabled = hweight32(ccer_backup & TIM_CCER_CCXE);
+
+	if (ddata->ipidr) {
+		u32 hwcfgr;
+		unsigned int npwm;
+
+		/* Deduce from HWCFGR the number of outputs (MP25). */
+		regmap_read(regmap, TIM_HWCFGR1, &hwcfgr);
+
+		/*
+		 * Timers may have more capture/compare channels than the
+		 * actual number of PWM channel outputs (e.g. TIM_CH[1..4]).
+		 */
+		npwm = FIELD_GET(TIM_HWCFGR1_NB_OF_CC, hwcfgr);
+
+		return npwm < STM32_MAX_PWM_OUTPUT ? npwm : STM32_MAX_PWM_OUTPUT;
+	}
+
 	/*
 	 * If channels enable bits don't exist writing 1 will have no
 	 * effect so we can detect and count them.
 	 */
-	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);
-
 	return hweight32(ccer & TIM_CCER_CCXE);
 }
 
@@ -820,7 +847,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 	unsigned int i;
 	int ret;
 
-	npwm = stm32_pwm_detect_channels(ddata->regmap, &num_enabled);
+	npwm = stm32_pwm_detect_channels(ddata, &num_enabled);
 
 	chip = devm_pwmchip_alloc(dev, npwm, sizeof(*priv));
 	if (IS_ERR(chip))
@@ -841,7 +868,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, ret,
 				     "Failed to configure breakinputs\n");
 
-	stm32_pwm_detect_complementary(priv);
+	stm32_pwm_detect_complementary(priv, ddata);
 
 	ret = devm_clk_rate_exclusive_get(dev, priv->clk);
 	if (ret)
@@ -911,6 +938,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stm32_pwm_pm_ops, stm32_pwm_suspend, stm32_pwm_r
 
 static const struct of_device_id stm32_pwm_of_match[] = {
 	{ .compatible = "st,stm32-pwm",	},
+	{ .compatible = "st,stm32mp25-pwm", },
 	{ /* end node */ },
 };
 MODULE_DEVICE_TABLE(of, stm32_pwm_of_match);
-- 
2.25.1



From danishanwar at ti.com  Fri Dec 20 02:05:07 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Fri, 20 Dec 2024 15:35:07 +0530
Subject: [PATCH v2 1/2] soc: ti: pruss: Fix pruss APIs
In-Reply-To: <20241220100508.1554309-1-danishanwar@ti.com>
References: <20241220100508.1554309-1-danishanwar@ti.com>
Message-ID: <20241220100508.1554309-2-danishanwar@ti.com>

PRUSS APIs in pruss_driver.h produce lots of compilation errors when
CONFIG_TI_PRUSS is not set.

The errors and warnings,
warning: returning 'void *' from a function with return type 'int' makes
	integer from pointer without a cast [-Wint-conversion]
error: expected identifier or '(' before '{' token

Fix these warnings and errors by fixing the return type of pruss APIs as
well as removing the misplaced semicolon from pruss_cfg_xfr_enable()

Fixes: 0211cc1e4fbb ("soc: ti: pruss: Add helper functions to set GPI mode, MII_RT_event and XFR")
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Reviewed-by: Roger Quadros <rogerq at kernel.org>
---
 include/linux/pruss_driver.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h
index c9a31c567e85..2e18fef1a2e1 100644
--- a/include/linux/pruss_driver.h
+++ b/include/linux/pruss_driver.h
@@ -144,32 +144,32 @@ static inline int pruss_release_mem_region(struct pruss *pruss,
 static inline int pruss_cfg_get_gpmux(struct pruss *pruss,
 				      enum pruss_pru_id pru_id, u8 *mux)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 static inline int pruss_cfg_set_gpmux(struct pruss *pruss,
 				      enum pruss_pru_id pru_id, u8 mux)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 static inline int pruss_cfg_gpimode(struct pruss *pruss,
 				    enum pruss_pru_id pru_id,
 				    enum pruss_gpi_mode mode)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 static inline int pruss_cfg_xfr_enable(struct pruss *pruss,
 				       enum pru_type pru_type,
-				       bool enable);
+				       bool enable)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return -EOPNOTSUPP;
 }
 
 #endif /* CONFIG_TI_PRUSS */
-- 
2.34.1



From danishanwar at ti.com  Fri Dec 20 02:05:06 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Fri, 20 Dec 2024 15:35:06 +0530
Subject: [PATCH v2 0/2] Fix compilation errors with pruss APIs
Message-ID: <20241220100508.1554309-1-danishanwar@ti.com>

The APIs in 'include/linux/pruss_driver.h' produce compilation errors and
warnings when config symbol CONFIG_TI_PRUSS is not enabled.

This series fixes those errors / warnings.

Also the header file 'include/linux/pruss_driver.h' is orphan and has no
entry in MAINTAINERS file.

v2 - v1:
*) Collected RB tag from Roger for PATCH 1/2
*) Fixed typo in PATCH 2/2 as suggested by Roger.

v1 https://lore.kernel.org/all/20241218104424.1257880-1-danishanwar at ti.com/

MD Danish Anwar (2):
  soc: ti: pruss: Fix pruss APIs
  MAINTAINERS: Add entry for linux/pruss_driver.h

 MAINTAINERS                  |  1 +
 include/linux/pruss_driver.h | 12 ++++++------
 2 files changed, 7 insertions(+), 6 deletions(-)


base-commit: 8503810115fbff903f626adc0788daa048302bc0
-- 
2.34.1



From danishanwar at ti.com  Fri Dec 20 02:05:08 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Fri, 20 Dec 2024 15:35:08 +0530
Subject: [PATCH v2 2/2] MAINTAINERS: Add entry for linux/pruss_driver.h
In-Reply-To: <20241220100508.1554309-1-danishanwar@ti.com>
References: <20241220100508.1554309-1-danishanwar@ti.com>
Message-ID: <20241220100508.1554309-3-danishanwar@ti.com>

include/linux/pruss_driver.h is an orphan file. Add entry for this in
the MAINTAINERS file.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c67f868ea1c9..2d4c883cb06a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23644,6 +23644,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
 F:	Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
 F:	drivers/pmdomain/ti/omap_prm.c
 F:	drivers/soc/ti/*
+F:	include/linux/pruss_driver.h
 
 TI LM49xxx FAMILY ASoC CODEC DRIVERS
 M:	M R Swami Reddy <mr.swami.reddy at ti.com>
-- 
2.34.1



From yeoreum.yun at arm.com  Fri Dec 20 02:06:27 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:06:27 +0000
Subject: [PATCH v3 0/9] coresight: change some driver' spinlock type to
 raw_spinlock_t
In-Reply-To: <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
 <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>
Message-ID: <Z2VBoxu/pAnkiWMh@e129823.arm.com>

Hi Mike,

> Hi,
>
> On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
> >
> > In some coresight drivers, drvdata->spinlock can be held during __schedule()
> > by perf_event_task_sched_out()/in().
> >
> > Since drvdata->spinlock type is spinlock_t and
> > perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> > which is raw_spinlock_t (an unsleepable lock),
> > this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
> >
> > To address this,change type drvdata->spinlock in some coresight drivers,
> > which can be called by perf_event_task_sched_out()/in(),
> > from spinlock_t to raw_spinlock_t.
> >
> > Reviewed-by: James Clark <james.clark at linaro.org>
> >
> > v2 to v3:
> >     - Fix build error
> >
> > v1 to v2:
> >     - seperate patchsets to change locktype and apply gurad API.
> >
> > Yeoreum Yun (9):
> >   coresight: change coresight_device lock type to  raw_spinlock_t
> >   coresight-etm4x: change etmv4_drvdata spinlock type to  raw_spinlock_t
> >   coresight: change coresight_trace_id_map's lock type to
> >     raw_spinlock_t
> >   coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
> >   coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
> >   coresight-funnel: change funnel_drvdata spinlock's type to
> >     raw_spinlock_t
> >   coresight-replicator: change replicator_drvdata spinlock's type to
> >     raw_spinlock_t
> >   coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
> >   coresight/ultrasoc: change cti_drvdata spinlock's type to
> >     raw_spinlock_t
> >
> >  .../hwtracing/coresight/coresight-config.c    |   8 +-
> >  .../hwtracing/coresight/coresight-config.h    |   2 +-
> >  drivers/hwtracing/coresight/coresight-core.c  |   2 +-
> >  .../hwtracing/coresight/coresight-cti-core.c  |  44 +--
> >  .../hwtracing/coresight/coresight-cti-sysfs.c |  76 +++---
> >  drivers/hwtracing/coresight/coresight-cti.h   |   2 +-
> >  drivers/hwtracing/coresight/coresight-etb10.c |  26 +-
> >  .../coresight/coresight-etm4x-core.c          |  18 +-
> >  .../coresight/coresight-etm4x-sysfs.c         | 250 +++++++++---------
> >  drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
> >  .../hwtracing/coresight/coresight-funnel.c    |  12 +-
> >  .../coresight/coresight-replicator.c          |  12 +-
> >  .../hwtracing/coresight/coresight-syscfg.c    |  26 +-
> >  .../hwtracing/coresight/coresight-tmc-core.c  |   6 +-
> >  .../hwtracing/coresight/coresight-tmc-etf.c   |  48 ++--
> >  .../hwtracing/coresight/coresight-tmc-etr.c   |  40 +--
> >  drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
> >  .../hwtracing/coresight/coresight-trace-id.c  |  22 +-
> >  drivers/hwtracing/coresight/ultrasoc-smb.c    |  12 +-
> >  drivers/hwtracing/coresight/ultrasoc-smb.h    |   2 +-
> >  include/linux/coresight.h                     |   4 +-
> >  21 files changed, 308 insertions(+), 308 deletions(-)
> >
> > --
> > LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
> >
>
> Notably missing is the same changes for the etm3x driver. The ETMv3.x
> and PTM1.x are supported by this driver, and these trace source
> variants are also supported in perf in the cs_etm.c code.
>
> STM is also missing, though this is not directly enabled via perf -
> but could perhaps run concurrently as it can be a target output for
> ftrace.
>
> Regards

Thanks for review. okay I'll back with new patch set including etm3 /
stm.

Thanks!

> --
> Mike Leach
> Principal Engineer, ARM Ltd.
> Manchester Design Centre. UK


From konrad.dybcio at oss.qualcomm.com  Fri Dec 20 02:07:03 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 20 Dec 2024 11:07:03 +0100
Subject: [PATCH v6 5/5] arm64: dts: qcom: Update IPQ9574 xo_board_clk to
 use fixed factor clock
In-Reply-To: <f6930a4c-6d31-4cd9-a9ba-d6ff50e274e2@quicinc.com>
References: <20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485@quicinc.com>
 <20241107-qcom_ipq_cmnpll-v6-5-a5cfe09de485@quicinc.com>
 <0776a26e-56cd-4838-9b52-210ae9a1f281@oss.qualcomm.com>
 <8063460d-18ad-4e54-8232-716bad9d37c3@quicinc.com>
 <2456ab36-f48e-4aa3-88e1-aeb7895c9816@quicinc.com>
 <fb9d117e-77bd-4a01-a738-f72d07f6b84c@oss.qualcomm.com>
 <f6930a4c-6d31-4cd9-a9ba-d6ff50e274e2@quicinc.com>
Message-ID: <fb81ecb7-1ae8-4ace-9d6a-5954136d9142@oss.qualcomm.com>

On 20.12.2024 7:43 AM, Jie Luo wrote:
> 
> 
> On 12/20/2024 5:28 AM, Konrad Dybcio wrote:
>> On 18.12.2024 12:17 PM, Jie Luo wrote:
>>>
>>>
>>> On 12/13/2024 6:30 PM, Jie Luo wrote:
>>>>
>>>>
>>>> On 12/13/2024 2:33 AM, Konrad Dybcio wrote:
>>>>> On 7.11.2024 10:50 AM, Luo Jie wrote:
>>>>>> xo_board_clk is fixed to 24 MHZ, which is routed from WiFi output clock
>>>>>> 48 MHZ (also being the reference clock of CMN PLL) divided 2 by analog
>>>>>> block routing channel.
>>>>>>
>>>>>> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
>>>>>> ---
>>>>>> ?? arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 7 ++++++-
>>>>>> ?? arch/arm64/boot/dts/qcom/ipq9574.dtsi??????????? | 3 ++-
>>>>>> ?? 2 files changed, 8 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/ arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>>>>> index 78f6a2e053d5..9a8692377176 100644
>>>>>> --- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>>>>> +++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
>>>>>> @@ -174,8 +174,13 @@ &ref_48mhz_clk {
>>>>>> ?????? clock-mult = <1>;
>>>>>> ?? };
>>>>>> +/*
>>>>>> + * The frequency of xo_board_clk is fixed to 24 MHZ, which is routed
>>>>>> + * from WiFi output clock 48 MHZ divided by 2.
>>>>>> + */
>>>>>> ?? &xo_board_clk {
>>>>>> -??? clock-frequency = <24000000>;
>>>>>> +??? clock-div = <2>;
>>>>>> +??? clock-mult = <1>;
>>>>>> ?? };
>>>>>> ?? &xo_clk {
>>>>>> diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/ dts/qcom/ipq9574.dtsi
>>>>>> index 8246a00a3e3e..25aed33e9358 100644
>>>>>> --- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>>>>>> +++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
>>>>>> @@ -32,7 +32,8 @@ sleep_clk: sleep-clk {
>>>>>> ?????????? };
>>>>>> ?????????? xo_board_clk: xo-board-clk {
>>>>>> -??????????? compatible = "fixed-clock";
>>>>>> +??????????? compatible = "fixed-factor-clock";
>>>>>> +??????????? clocks = <&ref_48mhz_clk>;
>>>>>
>>>>> This must be squashed with the previous patch, you can't introduce
>>>>> code and replace it immediately afterwards.
>>>>>
>>>>> Konrad
>>>
>>> Hi Konrad,
>>>
>>> Looking at this comment again, there may have been some
>>> misunderstanding. We are not introducing xo_board_clk in patch 4 of this
>>> series. xo_board_clk is a pre-existing node.
>>>
>>> As part of this additional patch 5, we wanted to address Dmitry's
>>> comment earlier in v5 (reference to comment below), by converting the
>>> xo_board_clk as well to a fixed-factor clock. So it is better to keep
>>> this change as a separate patch in my view. Hope this is OK.
>>
>> Oh okay..
>>
>> What's the difference between xo_board_clk and xo_clk then, if the
>> divider is accounted for in xo_board_clk?
>>
>> Konrad
> 
> Here is the clock chain for the relationship between the clocks:
> xo_clk (48 MHZ or 96 MHZ)-->WiFi (mul/div)--> 48 MHZ-->CMN PLL
> ?????????????????????????????? |
> ?????????????????????????? +-->fixed factor(div by 2) --> xo_board_clk (24 MHZ)
> 
> So there are two dividers (fixed factor clocks): first for generating
> the 48 MHZ clock (ref-48mhz-clk) from the fixed clock source 'xo_clk',
> and a second for generating the 24 MHZ 'xo_board_clk' from the 48 MHZ
> ref clock.

Ok, thanks for the explanation

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

Konrad


From yeoreum.yun at arm.com  Fri Dec 20 02:07:42 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:07:42 +0000
Subject: [PATCH v3 9/9] coresight/ultrasoc: change cti_drvdata spinlock's
 type to raw_spinlock_t
In-Reply-To: <CAJ9a7ViC+ZSzNYTo+mKK4UYw=GBO9TCyJ2WHN879=hO-tq8JvQ@mail.gmail.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
 <20241216115006.415861-10-yeoreum.yun@arm.com>
 <CAJ9a7ViC+ZSzNYTo+mKK4UYw=GBO9TCyJ2WHN879=hO-tq8JvQ@mail.gmail.com>
Message-ID: <Z2VB7uGgTpOoRQqj@e129823.arm.com>

Hi Mike.

> Title of patch - this patch has nothing to do with cti_drvdata.

Sorry. I'll fix this. Thanks
>
>
> On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun at arm.com> wrote:
> >
> > In ultrasoc-smb drivers, smb_drv_data->spinlock can be held
> > during __schedule() by perf_event_task_sched_out()/in().
> >
> > Since smb__drv_data->spinlock type is spinlock_t and
> > perf_event_task_sched_out()/in() is called after acquiring rq_lock,
> > which is raw_spinlock_t (an unsleepable lock),
> > this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.
> >
> > To address this, change type smb_drv_data->spinlock in ultrasoc-smb drivers,
> > which can be called by perf_event_task_sched_out()/in(),
> > from spinlock_t to raw_spinlock_t.
> >
> > Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
> > ---
> >  drivers/hwtracing/coresight/ultrasoc-smb.c | 12 ++++++------
> >  drivers/hwtracing/coresight/ultrasoc-smb.h |  2 +-
> >  2 files changed, 7 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
> > index dc3c9504dd7c..26cfc939e5bd 100644
> > --- a/drivers/hwtracing/coresight/ultrasoc-smb.c
> > +++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
> > @@ -98,7 +98,7 @@ static int smb_open(struct inode *inode, struct file *file)
> >         struct smb_drv_data *drvdata = container_of(file->private_data,
> >                                         struct smb_drv_data, miscdev);
> >
> > -       guard(spinlock)(&drvdata->spinlock);
> > +       guard(raw_spinlock)(&drvdata->spinlock);
> >
> >         if (drvdata->reading)
> >                 return -EBUSY;
> > @@ -152,7 +152,7 @@ static int smb_release(struct inode *inode, struct file *file)
> >         struct smb_drv_data *drvdata = container_of(file->private_data,
> >                                         struct smb_drv_data, miscdev);
> >
> > -       guard(spinlock)(&drvdata->spinlock);
> > +       guard(raw_spinlock)(&drvdata->spinlock);
> >         drvdata->reading = false;
> >
> >         return 0;
> > @@ -245,7 +245,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
> >         struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
> >         int ret = 0;
> >
> > -       guard(spinlock)(&drvdata->spinlock);
> > +       guard(raw_spinlock)(&drvdata->spinlock);
> >
> >         /* Do nothing, the trace data is reading by other interface now */
> >         if (drvdata->reading)
> > @@ -280,7 +280,7 @@ static int smb_disable(struct coresight_device *csdev)
> >  {
> >         struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
> >
> > -       guard(spinlock)(&drvdata->spinlock);
> > +       guard(raw_spinlock)(&drvdata->spinlock);
> >
> >         if (drvdata->reading)
> >                 return -EBUSY;
> > @@ -378,7 +378,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev,
> >         if (!buf)
> >                 return 0;
> >
> > -       guard(spinlock)(&drvdata->spinlock);
> > +       guard(raw_spinlock)(&drvdata->spinlock);
> >
> >         /* Don't do anything if another tracer is using this sink. */
> >         if (csdev->refcnt != 1)
> > @@ -563,7 +563,7 @@ static int smb_probe(struct platform_device *pdev)
> >
> >         smb_reset_buffer(drvdata);
> >         platform_set_drvdata(pdev, drvdata);
> > -       spin_lock_init(&drvdata->spinlock);
> > +       raw_spin_lock_init(&drvdata->spinlock);
> >         drvdata->pid = -1;
> >
> >         ret = smb_register_sink(pdev, drvdata);
> > diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing/coresight/ultrasoc-smb.h
> > index a91d39cfccb8..c4c111275627 100644
> > --- a/drivers/hwtracing/coresight/ultrasoc-smb.h
> > +++ b/drivers/hwtracing/coresight/ultrasoc-smb.h
> > @@ -115,7 +115,7 @@ struct smb_drv_data {
> >         struct coresight_device *csdev;
> >         struct smb_data_buffer sdb;
> >         struct miscdevice miscdev;
> > -       spinlock_t spinlock;
> > +       raw_spinlock_t spinlock;
> >         bool reading;
> >         pid_t pid;
> >  };
> > --
> > LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
> >
>
>
> --
> Mike Leach
> Principal Engineer, ARM Ltd.
> Manchester Design Centre. UK


From yeoreum.yun at arm.com  Fri Dec 20 02:13:17 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:13:17 +0000
Subject: [PATCH v3 2/9] coresight-etm4x: change etmv4_drvdata spinlock
 type to raw_spinlock_t
In-Reply-To: <CAJ9a7Vj6_ek9D-ZySt6dNAGWwWV=7yX36T=n7+n-Nak=UEhMdw@mail.gmail.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
 <20241216115006.415861-3-yeoreum.yun@arm.com>
 <CAJ9a7Vj6_ek9D-ZySt6dNAGWwWV=7yX36T=n7+n-Nak=UEhMdw@mail.gmail.com>
Message-ID: <Z2VDPQMUH61THA8r@e129823.arm.com>

Hi Mike.
> > diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
> > index 6ba013975741..b9ebc9fcfb7f 100644
> > --- a/drivers/hwtracing/coresight/coresight-config.h
> > +++ b/drivers/hwtracing/coresight/coresight-config.h
> > @@ -206,7 +206,7 @@ struct cscfg_feature_csdev {
> >         const struct cscfg_feature_desc *feat_desc;
> >         struct coresight_device *csdev;
> >         struct list_head node;
> > -       spinlock_t *drv_spinlock;
> > +       raw_spinlock_t *drv_spinlock;
> >         int nr_params;
> >         struct cscfg_parameter_csdev *params_csdev;
> >         int nr_regs;
>
> The above changes are not etm4x specific - should be in the previous patch.

Yes, However when this changes, etm4x should be changed at the same time
because of build failures.

That's why I modified this with etm4x where currenly cscfg is used only.

Thanks


From kever.yang at rock-chips.com  Fri Dec 20 02:15:45 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:15:45 +0800
Subject: [PATCH v2 1/7] dts: arm64: rockchip: Add rk3576 naneng combphy nodes
In-Reply-To: <20241220101551.3505917-1-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
Message-ID: <20241220101551.3505917-2-kever.yang@rock-chips.com>

rk3576 has two naneng combo phy,
- combophy0 is used for one of pcie and sata;
- combophy1 is used for one of pcie, sata and usb3;

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

Changes in v2:
- update the clock and reset names to pass the DTB CHECK

 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 36 ++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index 436232ffe4d1..a147879da501 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1587,6 +1587,42 @@ uart11: serial at 2afd0000 {
 			status = "disabled";
 		};
 
+		combphy0_ps: phy at 2b050000 {
+			compatible = "rockchip,rk3576-naneng-combphy";
+			reg = <0x0 0x2b050000 0x0 0x100>;
+			#phy-cells = <1>;
+			clocks = <&cru CLK_REF_PCIE0_PHY>,
+				 <&cru PCLK_PCIE2_COMBOPHY0>,
+				 <&cru PCLK_PCIE0>;
+			clock-names = "ref", "apb", "pipe";
+			assigned-clocks = <&cru CLK_REF_PCIE0_PHY>;
+			assigned-clock-rates = <100000000>;
+			resets = <&cru SRST_PCIE0_PIPE_PHY>,
+				 <&cru SRST_P_PCIE2_COMBOPHY0>;
+			reset-names = "phy", "apb";
+			rockchip,pipe-grf = <&php_grf>;
+			rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
+			status = "disabled";
+		};
+
+		combphy1_psu: phy at 2b060000 {
+			compatible = "rockchip,rk3576-naneng-combphy";
+			reg = <0x0 0x2b060000 0x0 0x100>;
+			#phy-cells = <1>;
+			clocks = <&cru CLK_REF_PCIE1_PHY>,
+				 <&cru PCLK_PCIE2_COMBOPHY1>,
+				 <&cru PCLK_PCIE1>;
+			clock-names = "ref", "apb", "pipe";
+			assigned-clocks = <&cru CLK_REF_PCIE1_PHY>;
+			assigned-clock-rates = <100000000>;
+			resets = <&cru SRST_PCIE1_PIPE_PHY>,
+				 <&cru SRST_P_PCIE2_COMBOPHY1>;
+			reset-names = "phy", "apb";
+			rockchip,pipe-grf = <&php_grf>;
+			rockchip,pipe-phy-grf = <&pipe_phy1_grf>;
+			status = "disabled";
+		};
+
 		sram: sram at 3ff88000 {
 			compatible = "mmio-sram";
 			reg = <0x0 0x3ff88000 0x0 0x78000>;
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:22 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:22 +0100
Subject: [PATCH v2 4/9] counter: stm32-timer-cnt: add support for stm32mp25
In-Reply-To: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241220095927.1122782-5-fabrice.gasnier@foss.st.com>

Add support for STM32MP25 SoC. There are new counter modes that may be
implemented in later. Still, use newly introduced compatible to handle
this new HW variant and avoid being blocked with existing compatible
in SoC dtsi file. Modes supported currently still remains compatible.
New timer 20 has encoder capability, add it to the list.

Acked-by: William Breathitt Gray <wbg at kernel.org>
Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 drivers/counter/stm32-timer-cnt.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
index e75b69476a00..3d3384cbea87 100644
--- a/drivers/counter/stm32-timer-cnt.c
+++ b/drivers/counter/stm32-timer-cnt.c
@@ -669,12 +669,14 @@ static void stm32_timer_cnt_detect_channels(struct device *dev,
 	dev_dbg(dev, "has %d cc channels\n", priv->nchannels);
 }
 
-/* encoder supported on TIM1 TIM2 TIM3 TIM4 TIM5 TIM8 */
-#define STM32_TIM_ENCODER_SUPPORTED	(BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(7))
+/* encoder supported on TIM1 TIM2 TIM3 TIM4 TIM5 TIM8 TIM20 */
+#define STM32_TIM_ENCODER_SUPPORTED	(BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(7) | \
+					 BIT(19))
 
 static const char * const stm32_timer_trigger_compat[] = {
 	"st,stm32-timer-trigger",
 	"st,stm32h7-timer-trigger",
+	"st,stm32mp25-timer-trigger",
 };
 
 static int stm32_timer_cnt_probe_encoder(struct device *dev,
@@ -846,6 +848,7 @@ static SIMPLE_DEV_PM_OPS(stm32_timer_cnt_pm_ops, stm32_timer_cnt_suspend,
 
 static const struct of_device_id stm32_timer_cnt_of_match[] = {
 	{ .compatible = "st,stm32-timer-counter", },
+	{ .compatible = "st,stm32mp25-timer-counter", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, stm32_timer_cnt_of_match);
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:20 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:20 +0100
Subject: [PATCH v2 2/9] mfd: stm32-timers: add support for stm32mp25
In-Reply-To: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241220095927.1122782-3-fabrice.gasnier@foss.st.com>

Add support for STM32MP25 SoC. Use newly introduced compatible, to handle
new features.
Identification and hardware configuration registers allow to read the
timer version and capabilities (counter width, number of channels...).
So, rework the probe to avoid touching ARR register by simply read the
counter width when available. This may avoid messing with a possibly
running timer.
Also add useful bit fields to stm32-timers header file.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 drivers/mfd/stm32-timers.c       | 32 +++++++++++++++++++++++++++++++-
 include/linux/mfd/stm32-timers.h |  9 +++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/stm32-timers.c b/drivers/mfd/stm32-timers.c
index 650724e19b88..6f217c32482c 100644
--- a/drivers/mfd/stm32-timers.c
+++ b/drivers/mfd/stm32-timers.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/reset.h>
 
 #define STM32_TIMERS_MAX_REGISTERS	0x3fc
@@ -173,6 +174,32 @@ static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
 	regmap_write(ddata->regmap, TIM_ARR, arr);
 }
 
+static int stm32_timers_probe_hwcfgr(struct device *dev, struct stm32_timers *ddata)
+{
+	u32 val;
+
+	ddata->ipidr = (uintptr_t)device_get_match_data(dev);
+	if (!ddata->ipidr) {
+		/* fallback to legacy method for probing counter width */
+		stm32_timers_get_arr_size(ddata);
+		return 0;
+	}
+
+	regmap_read(ddata->regmap, TIM_IPIDR, &val);
+	/* Sanity check on IP identification register */
+	if (val != ddata->ipidr) {
+		dev_err(dev, "Unexpected identification: %u\n", val);
+		return -EINVAL;
+	}
+
+	regmap_read(ddata->regmap, TIM_HWCFGR2, &val);
+	/* Counter width in bits, max reload value is BIT(width) - 1 */
+	ddata->max_arr = BIT(FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val)) - 1;
+	dev_dbg(dev, "TIM width: %ld\n", FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val));
+
+	return 0;
+}
+
 static int stm32_timers_dma_probe(struct device *dev,
 				   struct stm32_timers *ddata)
 {
@@ -285,7 +312,9 @@ static int stm32_timers_probe(struct platform_device *pdev)
 	if (IS_ERR(ddata->clk))
 		return PTR_ERR(ddata->clk);
 
-	stm32_timers_get_arr_size(ddata);
+	ret = stm32_timers_probe_hwcfgr(dev, ddata);
+	if (ret)
+		return ret;
 
 	ret = stm32_timers_irq_probe(pdev, ddata);
 	if (ret)
@@ -320,6 +349,7 @@ static void stm32_timers_remove(struct platform_device *pdev)
 
 static const struct of_device_id stm32_timers_of_match[] = {
 	{ .compatible = "st,stm32-timers", },
+	{ .compatible = "st,stm32mp25-timers", .data = (void *)STM32MP25_TIM_IPIDR },
 	{ /* end node */ },
 };
 MODULE_DEVICE_TABLE(of, stm32_timers_of_match);
diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h
index f09ba598c97a..23b0cae4a9f8 100644
--- a/include/linux/mfd/stm32-timers.h
+++ b/include/linux/mfd/stm32-timers.h
@@ -33,6 +33,9 @@
 #define TIM_DCR		0x48			/* DMA control register			*/
 #define TIM_DMAR	0x4C			/* DMA register for transfer		*/
 #define TIM_TISEL	0x68			/* Input Selection			*/
+#define TIM_HWCFGR2	0x3EC			/* hardware configuration 2 Reg (MP25)	*/
+#define TIM_HWCFGR1	0x3F0			/* hardware configuration 1 Reg (MP25)	*/
+#define TIM_IPIDR	0x3F8			/* IP identification Reg (MP25)		*/
 
 #define TIM_CR1_CEN		BIT(0)					/* Counter Enable				*/
 #define TIM_CR1_DIR		BIT(4)					/* Counter Direction				*/
@@ -100,6 +103,9 @@
 #define TIM_BDTR_BKF(x)		(0xf << (16 + (x) * 4))
 #define TIM_DCR_DBA		GENMASK(4, 0)				/* DMA base addr				*/
 #define TIM_DCR_DBL		GENMASK(12, 8)				/* DMA burst len				*/
+#define TIM_HWCFGR1_NB_OF_CC	GENMASK(3, 0)				/* Capture/compare channels			*/
+#define TIM_HWCFGR1_NB_OF_DT	GENMASK(7, 4)				/* Complementary outputs & dead-time generators */
+#define TIM_HWCFGR2_CNT_WIDTH	GENMASK(15, 8)				/* Counter width				*/
 
 #define MAX_TIM_PSC				0xFFFF
 #define MAX_TIM_ICPSC				0x3
@@ -113,6 +119,8 @@
 #define TIM_BDTR_BKF_MASK			0xF
 #define TIM_BDTR_BKF_SHIFT(x)			(16 + (x) * 4)
 
+#define STM32MP25_TIM_IPIDR	0x00120002
+
 enum stm32_timers_dmas {
 	STM32_TIMERS_DMA_CH1,
 	STM32_TIMERS_DMA_CH2,
@@ -151,6 +159,7 @@ struct stm32_timers_dma {
 
 struct stm32_timers {
 	struct clk *clk;
+	u32 ipidr;
 	struct regmap *regmap;
 	u32 max_arr;
 	struct stm32_timers_dma dma; /* Only to be used by the parent */
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:18 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:18 +0100
Subject: [PATCH v2 0/9] Add STM32MP25 timers support: MFD, PWM, IIO and counter drivers
Message-ID: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>

This series adds STM32MP25 support on MFD PWM, IIO, counter timer drivers.
This new timer variant is managed by using a new DT compatible string.
It comes with a slightly updated register set, some new features and new
interconnect signals inside the SoC. There is also a new instance (TIM20).
Same feature list as on STM32MP1x is supported currently, except for PWM
capture (not enabled, by DT).
The device tree files add all instances in stm32mp251 dtsi. PWM, counter
and trigger examples are provided for stm32mp257f-ev1 board.

Changes in V2
---
- PMW driver updated to address Uwe's review comments
- Collected Acked-by

Fabrice Gasnier (9):
  dt-bindings: mfd: stm32-timers: add support for stm32mp25
  mfd: stm32-timers: add support for stm32mp25
  iio: trigger: stm32-timer: add support for stm32mp25
  counter: stm32-timer-cnt: add support for stm32mp25
  pwm: stm32: add support for stm32mp25
  arm64: defconfig: enable STM32 timers drivers
  arm64: dts: st: add timer nodes on stm32mp251
  arm64: dts: st: add timer pins for stm32mp257f-ev1
  arm64: dts: st: add timer nodes on stm32mp257f-ev1

 .../bindings/mfd/st,stm32-timers.yaml         |  18 +-
 arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi |  61 ++
 arch/arm64/boot/dts/st/stm32mp251.dtsi        | 524 ++++++++++++++++++
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts    |  58 ++
 arch/arm64/configs/defconfig                  |   4 +
 drivers/counter/stm32-timer-cnt.c             |   7 +-
 drivers/iio/trigger/stm32-timer-trigger.c     |  21 +-
 drivers/mfd/stm32-timers.c                    |  32 +-
 drivers/pwm/pwm-stm32.c                       |  42 +-
 include/linux/iio/timer/stm32-timer-trigger.h |   6 +
 include/linux/mfd/stm32-timers.h              |   9 +
 11 files changed, 766 insertions(+), 16 deletions(-)

-- 
2.25.1



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:21 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:21 +0100
Subject: [PATCH v2 3/9] iio: trigger: stm32-timer: add support for stm32mp25
In-Reply-To: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241220095927.1122782-4-fabrice.gasnier@foss.st.com>

Add support for STM32MP25 SoC. Use newly introduced compatible to handle
this new HW variant. Add TIM20 trigger definitions that can be used by
the stm32 analog-to-digital converter. Use compatible data to identify
it.
As the counter framework is now superseding the deprecated IIO counter
interface (IIO_COUNT), don't support it. Only register IIO trigger
devices for ADC usage. So, make the valids_table a cfg option.

Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 drivers/iio/trigger/stm32-timer-trigger.c     | 21 +++++++++++++++++--
 include/linux/iio/timer/stm32-timer-trigger.h |  6 ++++++
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c
index bb60b2d7b2ec..8aaf3abf044e 100644
--- a/drivers/iio/trigger/stm32-timer-trigger.c
+++ b/drivers/iio/trigger/stm32-timer-trigger.c
@@ -38,6 +38,9 @@ static const void *triggers_table[][MAX_TRIGGERS] = {
 	{ TIM15_TRGO,},
 	{ TIM16_OC1,},
 	{ TIM17_OC1,},
+	{ }, /* timer 18 */
+	{ }, /* timer 19 */
+	{ TIM20_TRGO, TIM20_TRGO2, TIM20_OC1, TIM20_OC2, TIM20_OC3, },
 };
 
 /* List the triggers accepted by each timer */
@@ -781,7 +784,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	/* Create an IIO device only if we have triggers to be validated */
-	if (*cfg->valids_table[index])
+	if (cfg->valids_table && *cfg->valids_table[index])
 		priv = stm32_setup_counter_device(dev);
 	else
 		priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -794,7 +797,8 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
 	priv->clk = ddata->clk;
 	priv->max_arr = ddata->max_arr;
 	priv->triggers = triggers_table[index];
-	priv->valids = cfg->valids_table[index];
+	if (cfg->valids_table && *cfg->valids_table[index])
+		priv->valids = cfg->valids_table[index];
 	stm32_timer_detect_trgo2(priv);
 	mutex_init(&priv->lock);
 
@@ -886,6 +890,16 @@ static const struct stm32_timer_trigger_cfg stm32h7_timer_trg_cfg = {
 	.num_valids_table = ARRAY_SIZE(stm32h7_valids_table),
 };
 
+static const struct stm32_timer_trigger_cfg stm32mp25_timer_trg_cfg = {
+	/*
+	 * valids_table not used: counter framework is now superseding the deprecated IIO
+	 * counter interface (IIO_COUNT), so don't support it. num_valids_table is only
+	 * kept here to register the IIO HW triggers. valids_table should be moved at some
+	 * point to the stm32-timer-cnt driver instead.
+	 */
+	.num_valids_table = ARRAY_SIZE(triggers_table),
+};
+
 static const struct of_device_id stm32_trig_of_match[] = {
 	{
 		.compatible = "st,stm32-timer-trigger",
@@ -893,6 +907,9 @@ static const struct of_device_id stm32_trig_of_match[] = {
 	}, {
 		.compatible = "st,stm32h7-timer-trigger",
 		.data = (void *)&stm32h7_timer_trg_cfg,
+	}, {
+		.compatible = "st,stm32mp25-timer-trigger",
+		.data = (void *)&stm32mp25_timer_trg_cfg,
 	},
 	{ /* end node */ },
 };
diff --git a/include/linux/iio/timer/stm32-timer-trigger.h b/include/linux/iio/timer/stm32-timer-trigger.h
index 37572e4dc73a..1ee237b56183 100644
--- a/include/linux/iio/timer/stm32-timer-trigger.h
+++ b/include/linux/iio/timer/stm32-timer-trigger.h
@@ -72,6 +72,12 @@
 
 #define TIM17_OC1	"tim17_oc1"
 
+#define TIM20_OC1	"tim20_oc1"
+#define TIM20_OC2	"tim20_oc2"
+#define TIM20_OC3	"tim20_oc3"
+#define TIM20_TRGO	"tim20_trgo"
+#define TIM20_TRGO2	"tim20_trgo2"
+
 #if IS_REACHABLE(CONFIG_IIO_STM32_TIMER_TRIGGER)
 bool is_stm32_timer_trigger(struct iio_trigger *trig);
 #else
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:24 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:24 +0100
Subject: [PATCH v2 6/9] arm64: defconfig: enable STM32 timers drivers
In-Reply-To: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241220095927.1122782-7-fabrice.gasnier@foss.st.com>

Enable the STM32 timer drivers: MFD, counter, PWM and trigger as module.
These drivers can be used on STM32MP25.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm64/configs/defconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..d6aabdc103d7 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -764,6 +764,7 @@ CONFIG_MFD_TI_LP873X=m
 CONFIG_MFD_TPS65219=y
 CONFIG_MFD_TPS6594_I2C=m
 CONFIG_MFD_ROHM_BD718XX=y
+CONFIG_MFD_STM32_TIMERS=m
 CONFIG_MFD_WCD934X=m
 CONFIG_MFD_KHADAS_MCU=m
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -1499,6 +1500,7 @@ CONFIG_IIO_CROS_EC_LIGHT_PROX=m
 CONFIG_SENSORS_ISL29018=m
 CONFIG_VCNL4000=m
 CONFIG_IIO_ST_MAGN_3AXIS=m
+CONFIG_IIO_STM32_TIMER_TRIGGER=m
 CONFIG_IIO_CROS_EC_BARO=m
 CONFIG_MPL3115=m
 CONFIG_PWM=y
@@ -1516,6 +1518,7 @@ CONFIG_PWM_ROCKCHIP=y
 CONFIG_PWM_RZ_MTU3=m
 CONFIG_PWM_SAMSUNG=y
 CONFIG_PWM_SL28CPLD=m
+CONFIG_PWM_STM32=m
 CONFIG_PWM_SUN4I=m
 CONFIG_PWM_TEGRA=m
 CONFIG_PWM_TIECAP=m
@@ -1650,6 +1653,7 @@ CONFIG_INTERCONNECT_QCOM_SM8650=y
 CONFIG_INTERCONNECT_QCOM_X1E80100=y
 CONFIG_COUNTER=m
 CONFIG_RZ_MTU3_CNT=m
+CONFIG_STM32_TIMER_CNT=m
 CONFIG_HTE=y
 CONFIG_HTE_TEGRA194=y
 CONFIG_HTE_TEGRA194_TEST=m
-- 
2.25.1



From fabrice.gasnier at foss.st.com  Fri Dec 20 01:59:26 2024
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Fri, 20 Dec 2024 10:59:26 +0100
Subject: [PATCH v2 8/9] arm64: dts: st: add timer pins for stm32mp257f-ev1
In-Reply-To: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
Message-ID: <20241220095927.1122782-9-fabrice.gasnier@foss.st.com>

Add timer pins available on stm32mp257f-ev1, configured for PWM:
- timer3 CH2 is available on mikroBUS connector
- timer8 CH1, timer8 CH4, timer10 CH1 and timer12 CH2 are available
  on EXPANSION connector
Arbitrary define all these pins to be used as PWM (output) channels,
except for timer10 CH1, to be used as counter input.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
index 8fdd5f020425..bb9dc82d3dd5 100644
--- a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
@@ -82,6 +82,53 @@ pins {
 		};
 	};
 
+	pwm3_pins_a: pwm3-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 15, AF7)>; /* TIM3_CH2 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm3_sleep_pins_a: pwm3-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 15, ANALOG)>; /* TIM3_CH2 */
+		};
+	};
+
+	pwm8_pins_a: pwm8-0 {
+		pins {
+			pinmux = <STM32_PINMUX('J', 5, AF8)>, /* TIM8_CH1 */
+				 <STM32_PINMUX('J', 4, AF8)>; /* TIM8_CH4 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm8_sleep_pins_a: pwm8-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('J', 5, ANALOG)>, /* TIM8_CH1 */
+				 <STM32_PINMUX('J', 4, ANALOG)>; /* TIM8_CH4 */
+		};
+	};
+
+	pwm12_pins_a: pwm12-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 11, AF9)>; /* TIM12_CH2 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm12_sleep_pins_a: pwm12-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 11, ANALOG)>; /* TIM12_CH2 */
+		};
+	};
+
 	sdmmc1_b4_pins_a: sdmmc1-b4-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
@@ -158,6 +205,20 @@ pins1 {
 		};
 	};
 
+	tim10_counter_pins_a: tim10-counter-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 9, AF9)>; /* TIM10_CH1 */
+			bias-disable;
+		};
+	};
+
+	tim10_counter_sleep_pins_a: tim10-counter-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 9, ANALOG)>; /* TIM10_CH1 */
+			bias-disable;
+		};
+	};
+
 	usart2_pins_a: usart2-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('A', 4, AF6)>; /* USART2_TX */
-- 
2.25.1



From kever.yang at rock-chips.com  Fri Dec 20 02:15:46 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:15:46 +0800
Subject: [PATCH v2 2/7] dt-bindings: PCI: dwc: rockchip: Add rk3576 support
In-Reply-To: <20241220101551.3505917-1-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
Message-ID: <20241220101551.3505917-3-kever.yang@rock-chips.com>

rk3576 is using dwc controller, but use msi interrupt instead of its,
so the msi-map is not required, and need to add a new 'msi' interrupt name.

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

Changes in v2:
- remove required 'msi-map'
- add interrupt name 'msi'

 .../devicetree/bindings/pci/rockchip-dw-pcie-common.yaml      | 1 +
 Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml   | 4 +---
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-common.yaml b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-common.yaml
index cc9adfc7611c..e5e1a2c7ae05 100644
--- a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-common.yaml
@@ -81,6 +81,7 @@ properties:
       - const: msg
       - const: legacy
       - const: err
+      - const: msi
       - const: dma0
       - const: dma1
       - const: dma2
diff --git a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml
index 550d8a684af3..9a464731fa4a 100644
--- a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml
@@ -26,6 +26,7 @@ properties:
       - const: rockchip,rk3568-pcie
       - items:
           - enum:
+              - rockchip,rk3576-pcie
               - rockchip,rk3588-pcie
           - const: rockchip,rk3568-pcie
 
@@ -71,9 +72,6 @@ properties:
 
   vpcie3v3-supply: true
 
-required:
-  - msi-map
-
 unevaluatedProperties: false
 
 examples:
-- 
2.25.1



From jbrunet at baylibre.com  Fri Dec 20 02:25:37 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 11:25:37 +0100
Subject: [PATCH 2/2] clk: amlogic: gxbb: drop non existing 32k clock parent
In-Reply-To: <20241220-amlogic-clk-gxbb-32k-fixes-v1-0-baca56ecf2db@baylibre.com>
References: <20241220-amlogic-clk-gxbb-32k-fixes-v1-0-baca56ecf2db@baylibre.com>
Message-ID: <20241220-amlogic-clk-gxbb-32k-fixes-v1-2-baca56ecf2db@baylibre.com>

The 32k clock reference a parent 'cts_slow_oscin' with a fixme note saying
that this clock should be provided by AO controller.

The HW probably has this clock but it does not exist at the moment in
any controller implementation. Furthermore, referencing clock by the global
name should be avoided whenever possible.

There is no reason to keep this hack around, at least for now.

Fixes: 14c735c8e308 ("clk: meson-gxbb: Add EE 32K Clock for CEC")
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/clk/meson/gxbb.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 62494cf06e7d775bdb18b2242c3d45bf246bdd0e..66f299f6fef1442ead5e978c1d3750b55b800c2e 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -1266,14 +1266,13 @@ static struct clk_regmap gxbb_cts_i958 = {
 	},
 };
 
+/*
+ * This table skips a clock named 'cts_slow_oscin' in the documentation
+ * This clock does not exist yet in this controller or the AO one
+ */
+static u32 gxbb_32k_clk_parents_val_table[] = { 0, 2, 3 };
 static const struct clk_parent_data gxbb_32k_clk_parent_data[] = {
 	{ .fw_name = "xtal", },
-	/*
-	 * FIXME: This clock is provided by the ao clock controller but the
-	 * clock is not yet part of the binding of this controller, so string
-	 * name must be use to set this parent.
-	 */
-	{ .name = "cts_slow_oscin", .index = -1 },
 	{ .hw = &gxbb_fclk_div3.hw },
 	{ .hw = &gxbb_fclk_div5.hw },
 };
@@ -1283,6 +1282,7 @@ static struct clk_regmap gxbb_32k_clk_sel = {
 		.offset = HHI_32K_CLK_CNTL,
 		.mask = 0x3,
 		.shift = 16,
+		.table = gxbb_32k_clk_parents_val_table,
 		},
 	.hw.init = &(struct clk_init_data){
 		.name = "32k_clk_sel",

-- 
2.45.2



From jbrunet at baylibre.com  Fri Dec 20 02:25:36 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 11:25:36 +0100
Subject: [PATCH 1/2] clk: amlogic: gxbb: drop incorrect flag on 32k clock
In-Reply-To: <20241220-amlogic-clk-gxbb-32k-fixes-v1-0-baca56ecf2db@baylibre.com>
References: <20241220-amlogic-clk-gxbb-32k-fixes-v1-0-baca56ecf2db@baylibre.com>
Message-ID: <20241220-amlogic-clk-gxbb-32k-fixes-v1-1-baca56ecf2db@baylibre.com>

gxbb_32k_clk_div sets CLK_DIVIDER_ROUND_CLOSEST in the init_data flag which
is incorrect. This is field is not where the divider flags belong.

Thankfully, CLK_DIVIDER_ROUND_CLOSEST maps to bit 4 which is an unused
clock flag, so there is no unintended consequence to this error.

Effectively, the clock has been used without CLK_DIVIDER_ROUND_CLOSEST
so far, so just drop it.

Fixes: 14c735c8e308 ("clk: meson-gxbb: Add EE 32K Clock for CEC")
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/clk/meson/gxbb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 262c318edbd512239b79e5ad26643ae6c7b0173b..62494cf06e7d775bdb18b2242c3d45bf246bdd0e 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -1306,7 +1306,7 @@ static struct clk_regmap gxbb_32k_clk_div = {
 			&gxbb_32k_clk_sel.hw
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 

-- 
2.45.2



From neil.armstrong at linaro.org  Fri Dec 20 02:28:22 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 20 Dec 2024 11:28:22 +0100
Subject: [PATCH 1/2] clk: amlogic: gxbb: drop incorrect flag on 32k clock
In-Reply-To: <20241220-amlogic-clk-gxbb-32k-fixes-v1-1-baca56ecf2db@baylibre.com>
References: <20241220-amlogic-clk-gxbb-32k-fixes-v1-0-baca56ecf2db@baylibre.com>
 <20241220-amlogic-clk-gxbb-32k-fixes-v1-1-baca56ecf2db@baylibre.com>
Message-ID: <e74da1e8-d1fe-4937-9f41-63347beb40a2@linaro.org>

On 20/12/2024 11:25, Jerome Brunet wrote:
> gxbb_32k_clk_div sets CLK_DIVIDER_ROUND_CLOSEST in the init_data flag which
> is incorrect. This is field is not where the divider flags belong.
> 
> Thankfully, CLK_DIVIDER_ROUND_CLOSEST maps to bit 4 which is an unused
> clock flag, so there is no unintended consequence to this error.
> 
> Effectively, the clock has been used without CLK_DIVIDER_ROUND_CLOSEST
> so far, so just drop it.
> 
> Fixes: 14c735c8e308 ("clk: meson-gxbb: Add EE 32K Clock for CEC")
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
>   drivers/clk/meson/gxbb.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
> index 262c318edbd512239b79e5ad26643ae6c7b0173b..62494cf06e7d775bdb18b2242c3d45bf246bdd0e 100644
> --- a/drivers/clk/meson/gxbb.c
> +++ b/drivers/clk/meson/gxbb.c
> @@ -1306,7 +1306,7 @@ static struct clk_regmap gxbb_32k_clk_div = {
>   			&gxbb_32k_clk_sel.hw
>   		},
>   		.num_parents = 1,
> -		.flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
> +		.flags = CLK_SET_RATE_PARENT,
>   	},
>   };
>   
> 

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From lukma at denx.de  Fri Dec 20 02:29:50 2024
From: lukma at denx.de (Lukasz Majewski)
Date: Fri, 20 Dec 2024 11:29:50 +0100
Subject: [PATCH v11 1/3] dt-bindings: display: Add
 powertip,{st7272|hx8238a} as DT Schema description
In-Reply-To: <20241209105240.72d8d84a@wsk>
References: <20241107085705.490940-1-lukma@denx.de>
	<20241209105240.72d8d84a@wsk>
Message-ID: <20241220112950.4673bb3f@wsk>

Dear Community,

> Dear Community,
> 
> > This patch provides the DT Schema description of:
> > - powertip,st7272  320 x 240 LCD display
> > - powertip,hx8238a 320 x 240 LCD display
> > 
> > Used with the different HW revisions of btt3 devices.
> > 
> > Signed-off-by: Lukasz Majewski <lukma at denx.de>
> > Reviewed-by: Rob Herring <robh at kernel.org>  
> 
> Are there any more comments for this particular patch?
> 
> If not - can it be applied as it prevents dts patchs to be pull by
> Shawn.

Gentle ping on this patch ...

> 
> > ---
> > 
> > Changes for v9:
> > - New patch
> > 
> > Changes for v10:
> > - None
> > 
> > Changes for v11:
> > - Combine both separate dt-bindings patches for powertip,st7272 and
> >   powertip,hx8238a into one
> > - Drop the quotes for in "title" entry of powertip*.yaml files
> > ---
> >  .../display/panel/powertip,hx8238a.yaml       | 29
> > +++++++++++++++++++ .../display/panel/powertip,st7272.yaml        |
> > 29 +++++++++++++++++++ 2 files changed, 58 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/panel/powertip,hx8238a.yaml
> > create mode 100644
> > Documentation/devicetree/bindings/display/panel/powertip,st7272.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/panel/powertip,hx8238a.yaml
> > b/Documentation/devicetree/bindings/display/panel/powertip,hx8238a.yaml
> > new file mode 100644 index 000000000000..b7d74faeb5d5 --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/panel/powertip,hx8238a.yaml
> > @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-only OR
> > BSD-2-Clause +%YAML 1.2
> > +---
> > +$id:
> > http://devicetree.org/schemas/display/panel/powertip,hx8238a.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml# +
> > +title: Powertip Electronic Technology Co. 320 x 240 LCD panel
> > +
> > +maintainers:
> > +  - Lukasz Majewski <lukma at denx.de>
> > +
> > +allOf:
> > +  - $ref: panel-dpi.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - const: powertip,hx8238a
> > +      - {} # panel-dpi, but not listed here to avoid false select
> > +
> > +  height-mm: true
> > +  panel-timing: true
> > +  port: true
> > +  power-supply: true
> > +  width-mm: true
> > +
> > +additionalProperties: false
> > +
> > +...
> > diff --git
> > a/Documentation/devicetree/bindings/display/panel/powertip,st7272.yaml
> > b/Documentation/devicetree/bindings/display/panel/powertip,st7272.yaml
> > new file mode 100644 index 000000000000..f3622800f13f --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/panel/powertip,st7272.yaml
> > @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-only OR
> > BSD-2-Clause +%YAML 1.2
> > +---
> > +$id:
> > http://devicetree.org/schemas/display/panel/powertip,st7272.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml# +
> > +title: Powertip Electronic Technology Co. 320 x 240 LCD panel
> > +
> > +maintainers:
> > +  - Lukasz Majewski <lukma at denx.de>
> > +
> > +allOf:
> > +  - $ref: panel-dpi.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - const: powertip,st7272
> > +      - {} # panel-dpi, but not listed here to avoid false select
> > +
> > +  height-mm: true
> > +  panel-timing: true
> > +  port: true
> > +  power-supply: true
> > +  width-mm: true
> > +
> > +additionalProperties: false
> > +
> > +...  
> 
> 
> 
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Erika Unter
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
> lukma at denx.de




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- 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/20241220/583f8f7f/attachment.sig>

From geert+renesas at glider.be  Fri Dec 20 02:28:46 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 20 Dec 2024 11:28:46 +0100
Subject: [GIT PULL 2/3] Renesas driver updates for v6.14
In-Reply-To: <cover.1734689797.git.geert+renesas@glider.be>
References: <cover.1734689797.git.geert+renesas@glider.be>
Message-ID: <cover.1734689801.git.geert+renesas@glider.be>

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -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.14-tag1

for you to fetch changes up to 12e0bd600e3c2f33f9db0e3b91f6b8d8d95b7dbe:

  soc: renesas: Add RZ/G3E (R9A09G047) config option (2024-12-13 11:09:01 +0100)

----------------------------------------------------------------
Renesas driver updates for v6.14

  - Initial support for the Renesas RZ/G3E (R9A09G047) SoC.

----------------------------------------------------------------
Biju Das (1):
      soc: renesas: Add RZ/G3E (R9A09G047) config option

 drivers/soc/renesas/Kconfig | 5 +++++
 1 file changed, 5 insertions(+)


From geert+renesas at glider.be  Fri Dec 20 02:28:45 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 20 Dec 2024 11:28:45 +0100
Subject: [GIT PULL 1/3] Renesas ARM defconfig updates for v6.14
In-Reply-To: <cover.1734689797.git.geert+renesas@glider.be>
References: <cover.1734689797.git.geert+renesas@glider.be>
Message-ID: <cover.1734689799.git.geert+renesas@glider.be>

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -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.14-tag1

for you to fetch changes up to a40f02b2923b6d58e76cfef760b8ed61a00f1d53:

  arm64: defconfig: Enable R9A09G047 SoC (2024-12-13 11:09:59 +0100)

----------------------------------------------------------------
Renesas ARM defconfig updates for v6.14

  - Enable Watchdog support for the RZ/V2H(P) SoC and the RZ/V2H EVK
    board in the ARM64 defconfig,
  - Refresh shmobile_defconfig for v6.13-rc1,
  - Enable support for the Renesas RZ/G3E (R9A09G047) SoC in the ARM64
    defconfig.

----------------------------------------------------------------
Biju Das (1):
      arm64: defconfig: Enable R9A09G047 SoC

Geert Uytterhoeven (1):
      ARM: shmobile: defconfig: Refresh for v6.13-rc1

Lad Prabhakar (1):
      arm64: defconfig: Enable Renesas RZ/V2H(P) Watchdog driver

 arch/arm/configs/shmobile_defconfig | 1 +
 arch/arm64/configs/defconfig        | 2 ++
 2 files changed, 3 insertions(+)


From geert+renesas at glider.be  Fri Dec 20 02:28:47 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 20 Dec 2024 11:28:47 +0100
Subject: [GIT PULL 3/3] Renesas DTS updates for v6.14
In-Reply-To: <cover.1734689797.git.geert+renesas@glider.be>
References: <cover.1734689797.git.geert+renesas@glider.be>
Message-ID: <cover.1734689803.git.geert+renesas@glider.be>

The following changes since commit 40384c840ea1944d7c5a392e8975ed088ecf0b37:

  Linux 6.13-rc1 (2024-12-01 14:28:56 -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.14-tag1

for you to fetch changes up to acb247afab5bc2b4462f4dfc17a9d930e1153e52:

  arm64: dts: renesas: r9a09g047: Add I2C nodes (2024-12-17 09:42:52 +0100)

----------------------------------------------------------------
Renesas DTS updates for v6.14

  - Add more serial (SCIF), power monitor, ADC, and sound support for
    the RZ/G3S SoC and the RZ/G3S SMARC SoM and development board,
  - Add support for the R-Car V4H ES3.0 (R8A779G3) SoC on the White Hawk
    Single development board,
  - Add display support for the R-Car V4M SoC and the Gray Hawk Single
    development board,
  - Add video capture support for the Gray Hawk Single development
    board,
  - Add initial support for the RZ/G3E (R9A09G047) SoC and the RZ/G3E
    SMARC SoM and Carrier-II EVK development board,
  - Add support for 5-port MATEnet on the Falcon Ethernet sub-board,
  - Miscellaneous fixes and improvements.

----------------------------------------------------------------
Biju Das (8):
      dt-bindings: soc: renesas: Document Renesas RZ/G3E SoC variants
      dt-bindings: soc: renesas: Document RZ/G3E SMARC SoM and Carrier-II EVK
      dt-bindings: clock: renesas: Document RZ/G3E SoC CPG
      arm64: dts: renesas: Add initial DTSI for RZ/G3E SoC
      arm64: dts: renesas: r9a09g047: Add OPP table
      arm64: dts: renesas: Add initial support for RZ/G3E SMARC SoM
      arm64: dts: renesas: Add initial device tree for RZ/G3E SMARC EVK board
      arm64: dts: renesas: r9a09g047: Add I2C nodes

Claudiu Beznea (9):
      arm64: dts: renesas: r9a08g045: Add the remaining SCIF interfaces
      arm64: dts: renesas: rzg3s-smarc: Fix the debug serial alias
      arm64: dts: renesas: r9a08g045: Add ADC node
      arm64: dts: renesas: rzg3s-smarc-som: Enable ADC
      arm64: dts: renesas: r9a08g045: Add SSI nodes
      arm64: dts: renesas: rzg3s-smarc-som: Add versa3 clock generator node
      arm64: dts: renesas: Add da7212 audio codec node
      arm64: dts: renesas: rzg3s-smarc: Enable SSI3
      arm64: dts: renesas: rzg3s-smarc: Add sound card

Geert Uytterhoeven (9):
      dt-bindings: soc: renesas: Move R8A779G0 White Hawk up
      dt-bindings: soc: renesas: Document R8A779G3 White Hawk Single
      arm64: dts: renesas: Factor out White Hawk Single board support
      arm64: dts: renesas: Add R8A779G3 SoC support
      arm64: dts: renesas: r8a779g3: Add White Hawk Single support
      arm64: dts: renesas: white-hawk-ard-audio: Drop SoC part
      arm64: dts: renesas: white-hawk-single: Add R-Car Sound support
      ARM: dts: renesas: r7s72100: Add DMA support to RSPI
      Merge tag 'renesas-r9a09g047-dt-binding-defs-tag1' into renesas-dts-for-v6.14

Kuninori Morimoto (1):
      arm64: dts: renesas: ulcb: Add sample Audio Codec settings

Niklas S?derlund (3):
      arm64: dts: renesas: gray-hawk-single: Add video capture support
      arm64: dts: renesas: r8a779a0: Remove address- and size-cells from AVB[1-5]
      arm64: dts: renesas: falcon-ethernet: Describe PHYs connected on the breakout board

Tomi Valkeinen (3):
      arm64: dts: renesas: gray-hawk-single: Fix indentation
      arm64: dts: renesas: r8a779h0: Add display support
      arm64: dts: renesas: gray-hawk-single: Add DisplayPort support

Wolfram Sang (1):
      arm64: dts: renesas: rzg3s-smarc: Enable I2C1 and connected power monitor

 .../bindings/clock/renesas,rzv2h-cpg.yaml          |  15 +-
 .../devicetree/bindings/soc/renesas/renesas.yaml   |  33 +-
 arch/arm/boot/dts/renesas/r7s72100.dtsi            |  10 +
 arch/arm64/boot/dts/renesas/Makefile               |  12 +-
 .../boot/dts/renesas/r8a779a0-falcon-ethernet.dtsi | 242 +++++++++++++
 arch/arm64/boot/dts/renesas/r8a779a0.dtsi          |  10 -
 .../dts/renesas/r8a779g2-white-hawk-single.dts     |  62 +---
 .../dts/renesas/r8a779g3-white-hawk-single.dts     |  16 +
 arch/arm64/boot/dts/renesas/r8a779g3.dtsi          |  12 +
 .../boot/dts/renesas/r8a779h0-gray-hawk-single.dts | 298 +++++++++++++++-
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi          |  73 ++++
 arch/arm64/boot/dts/renesas/r9a08g045.dtsi         | 237 +++++++++++++
 arch/arm64/boot/dts/renesas/r9a09g047.dtsi         | 374 +++++++++++++++++++++
 arch/arm64/boot/dts/renesas/r9a09g047e37.dtsi      |  18 +
 arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts |  18 +
 arch/arm64/boot/dts/renesas/r9a09g047e57.dtsi      |  13 +
 arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi    |  24 ++
 arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi   |  28 ++
 arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi   |  56 ++-
 arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi       |  83 ++++-
 arch/arm64/boot/dts/renesas/ulcb-kf.dtsi           |  18 +-
 arch/arm64/boot/dts/renesas/ulcb.dtsi              |   5 +
 ...a7212.dtso => white-hawk-ard-audio-da7212.dtso} |   6 +-
 arch/arm64/boot/dts/renesas/white-hawk-single.dtsi |  73 ++++
 include/dt-bindings/clock/renesas,r9a09g047-cpg.h  |  21 ++
 25 files changed, 1644 insertions(+), 113 deletions(-)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779g3-white-hawk-single.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779g3.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g047.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g047e37.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g047e57.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/rzg3e-smarc-som.dtsi
 rename arch/arm64/boot/dts/renesas/{r8a779g0-white-hawk-ard-audio-da7212.dtso => white-hawk-ard-audio-da7212.dtso} (96%)
 create mode 100644 arch/arm64/boot/dts/renesas/white-hawk-single.dtsi
 create mode 100644 include/dt-bindings/clock/renesas,r9a09g047-cpg.h


From geert+renesas at glider.be  Fri Dec 20 02:28:44 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 20 Dec 2024 11:28:44 +0100
Subject: [GIT PULL 0/3] Renesas SoC updates for v6.14
Message-ID: <cover.1734689797.git.geert+renesas@glider.be>

	Hi SoC folks,

This is my first pull request for the inclusion of Renesas SoC updates
for v6.14.

It consists of 3 parts:

  [GIT PULL 1/3] Renesas ARM defconfig updates for v6.14

    - Enable Watchdog support for the RZ/V2H(P) SoC and the RZ/V2H EVK
      board in the ARM64 defconfig,
    - Refresh shmobile_defconfig for v6.13-rc1,
    - Enable support for the Renesas RZ/G3E (R9A09G047) SoC in the ARM64
      defconfig.

  [GIT PULL 2/3] Renesas driver updates for v6.14

    - Initial support for the Renesas RZ/G3E (R9A09G047) SoC.

  [GIT PULL 3/3] Renesas DTS updates for v6.14

    - Add more serial (SCIF), power monitor, ADC, and sound support for
      the RZ/G3S SoC and the RZ/G3S SMARC SoM and development board,
    - Add support for the R-Car V4H ES3.0 (R8A779G3) SoC on the White Hawk
      Single development board,
    - Add display support for the R-Car V4M SoC and the Gray Hawk Single
      development board,
    - Add video capture support for the Gray Hawk Single development
      board,
    - Add initial support for the RZ/G3E (R9A09G047) SoC and the RZ/G3E
      SMARC SoM and Carrier-II EVK development board,
    - Add support for 5-port MATEnet on the Falcon Ethernet sub-board,
    - Miscellaneous fixes and improvements.

Note that the third part includes DT bindings and binding definitions
for the RZ/G3E SoC, which are shared by DT source files and the clock
driver.

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 andre.draszik at linaro.org  Fri Dec 20 02:32:50 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 20 Dec 2024 10:32:50 +0000
Subject: [PATCH v2] arm64: dts: exynos: gs101-oriole: configure
 simple-framebuffer
Message-ID: <20241220-gs101-simplefb-oriole-v2-1-df60e566932a@linaro.org>

The bootloader configures the display hardware for a framebuffer at the
given address, let's add a simple-framebuffer node here until we get a
proper DRM driver.

This has several benefits since it's an OLED display:
* energy consumption goes down significantly, as it changes from white
  (as left by bootloader) to black (linux console), and we generally
  don't run out of battery anymore when plugged into a USB port
* less of a burn-in effect I assume
* phone stays cooler due to reduced energy consumption by display

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Tested-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
This is marked as v2, because it has been split out from my original
series in [1] to make it independent, for two reasons:
* drop the dependency on other patches touching the same file
* no need to mingle this one with adding Pixel 6 Pro support

Other than that, there are no changes and I kept the existing trailers.

For those who want to try this out:
The stock bootloader disables the decon hardware trigger before jumping
to Linux, preventing framebuffer updates from reaching the display. We
have added a work-around in our Yocto BSP layer for the time being
(until a proper display exists upstream). An alternative might be to
port and use uniLoader from https://github.com/ivoszbg/uniLoader, as
seems to be done for some other Exynos platforms.
---
Changes in v2:
- split out of original series
- Link to v1 series: https://lore.kernel.org/r/20241216-gs101-simplefb-v1-0-8ccad1830281 at linaro.org
---
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
index 387fb779bd29..a00cb27e167e 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
@@ -22,9 +22,23 @@ aliases {
 	};
 
 	chosen {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
 		/* Bootloader expects bootargs specified otherwise it crashes */
 		bootargs = "";
 		stdout-path = &serial_0;
+
+		/* Use display framebuffer as setup by bootloader */
+		framebuffer0: framebuffer at fac00000 {
+			compatible = "simple-framebuffer";
+			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
+			width = <1080>;
+			height = <2400>;
+			stride = <(1080 * 4)>;
+			format = "a8r8g8b8";
+		};
 	};
 
 	gpio-keys {
@@ -68,6 +82,13 @@ ufs_0_fixed_vcc_reg: regulator-1 {
 		regulator-boot-on;
 		enable-active-high;
 	};
+
+	reserved-memory {
+		cont_splash_mem: splash at fac00000 {
+			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
+			no-map;
+		};
+	};
 };
 
 &ext_24_5m {

---
base-commit: 8503810115fbff903f626adc0788daa048302bc0
change-id: 20241219-gs101-simplefb-oriole-d3fad1f5b498

Best regards,
-- 
Andr? Draszik <andre.draszik at linaro.org>



From neil.armstrong at linaro.org  Fri Dec 20 02:35:25 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 20 Dec 2024 11:35:25 +0100
Subject: [PATCH 2/2] clk: amlogic: gxbb: drop non existing 32k clock
 parent
In-Reply-To: <20241220-amlogic-clk-gxbb-32k-fixes-v1-2-baca56ecf2db@baylibre.com>
References: <20241220-amlogic-clk-gxbb-32k-fixes-v1-0-baca56ecf2db@baylibre.com>
 <20241220-amlogic-clk-gxbb-32k-fixes-v1-2-baca56ecf2db@baylibre.com>
Message-ID: <72f222a9-32b4-479a-8307-4653bc99686d@linaro.org>

On 20/12/2024 11:25, Jerome Brunet wrote:
> The 32k clock reference a parent 'cts_slow_oscin' with a fixme note saying
> that this clock should be provided by AO controller.
> 
> The HW probably has this clock but it does not exist at the moment in
> any controller implementation. Furthermore, referencing clock by the global
> name should be avoided whenever possible.
> 
> There is no reason to keep this hack around, at least for now.
> 
> Fixes: 14c735c8e308 ("clk: meson-gxbb: Add EE 32K Clock for CEC")
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
>   drivers/clk/meson/gxbb.c | 12 ++++++------
>   1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
> index 62494cf06e7d775bdb18b2242c3d45bf246bdd0e..66f299f6fef1442ead5e978c1d3750b55b800c2e 100644
> --- a/drivers/clk/meson/gxbb.c
> +++ b/drivers/clk/meson/gxbb.c
> @@ -1266,14 +1266,13 @@ static struct clk_regmap gxbb_cts_i958 = {
>   	},
>   };
>   
> +/*
> + * This table skips a clock named 'cts_slow_oscin' in the documentation
> + * This clock does not exist yet in this controller or the AO one
> + */
> +static u32 gxbb_32k_clk_parents_val_table[] = { 0, 2, 3 };
>   static const struct clk_parent_data gxbb_32k_clk_parent_data[] = {
>   	{ .fw_name = "xtal", },
> -	/*
> -	 * FIXME: This clock is provided by the ao clock controller but the
> -	 * clock is not yet part of the binding of this controller, so string
> -	 * name must be use to set this parent.
> -	 */
> -	{ .name = "cts_slow_oscin", .index = -1 },
>   	{ .hw = &gxbb_fclk_div3.hw },
>   	{ .hw = &gxbb_fclk_div5.hw },
>   };
> @@ -1283,6 +1282,7 @@ static struct clk_regmap gxbb_32k_clk_sel = {
>   		.offset = HHI_32K_CLK_CNTL,
>   		.mask = 0x3,
>   		.shift = 16,
> +		.table = gxbb_32k_clk_parents_val_table,
>   		},
>   	.hw.init = &(struct clk_init_data){
>   		.name = "32k_clk_sel",
> 

I guess it's for using alternate 32k clk source from the GPIOAO_6/CLK_32K_IN,
but AFAIK no boards never used that so we can't even test it...

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From kever.yang at rock-chips.com  Fri Dec 20 02:37:47 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:37:47 +0800
Subject: [PATCH 01/38] dt-bindings: clock: add rk3562 cru bindings
In-Reply-To: <20241220103825.3509421-1-kever.yang@rock-chips.com>
References: <20241220103825.3509421-1-kever.yang@rock-chips.com>
Message-ID: <20241220103825.3509421-2-kever.yang@rock-chips.com>

Document the device tree bindings of the rockchip rk3562 SoC
clock and reset unit.

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

 .../bindings/clock/rockchip,rk3562-cru.yaml   | 62 +++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3562-cru.yaml

diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3562-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3562-cru.yaml
new file mode 100644
index 000000000000..aa8dedf2bfce
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3562-cru.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rk3562-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip rk3562 Clock and Reset Control Module
+
+maintainers:
+  - Elaine Zhang <zhangqing at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+description:
+  The RK3562 clock controller generates the clock and also implements a reset
+  controller for SoC peripherals. For example it provides SCLK_UART2 and
+  PCLK_UART2, as well as SRST_P_UART2 and SRST_S_UART2 for the second UART
+  module.
+
+properties:
+  compatible:
+    const: rockchip,rk3562-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: xin24m
+      - const: xin32k
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon managing the "general register files" (GRF),
+      if missing pll rates are not changeable, due to the missing pll
+      lock status.
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at ff100000 {
+      compatible = "rockchip,rk3562-cru";
+      reg = <0xff100000 0x40000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
-- 
2.25.1



From kever.yang at rock-chips.com  Fri Dec 20 02:37:49 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:37:49 +0800
Subject: [PATCH 03/38] clk: rockchip: Add clock controller for the RK3562
In-Reply-To: <20241220103825.3509421-1-kever.yang@rock-chips.com>
References: <20241220103825.3509421-1-kever.yang@rock-chips.com>
Message-ID: <20241220103825.3509421-4-kever.yang@rock-chips.com>

From: Finley Xiao <finley.xiao at rock-chips.com>

Add the clock tree definition for the new RK3562 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Tao Huang <huangtao at rock-chips.com>
Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

 drivers/clk/rockchip/Kconfig      |    7 +
 drivers/clk/rockchip/Makefile     |    1 +
 drivers/clk/rockchip/clk-rk3562.c | 1111 +++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h        |   39 +
 4 files changed, 1158 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rk3562.c

diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
index 570ad90835d3..178cfc19d6ee 100644
--- a/drivers/clk/rockchip/Kconfig
+++ b/drivers/clk/rockchip/Kconfig
@@ -100,6 +100,13 @@ config CLK_RK3568
 	help
 	  Build the driver for RK3568 Clock Driver.
 
+config CLK_RK3562
+	tristate "Rockchip RK3562 clock controller support"
+	depends on ARM64 || COMPILE_TEST
+	default y
+	help
+	  Build the driver for RK3562 Clock Driver.
+
 config CLK_RK3576
 	bool "Rockchip RK3576 clock controller support"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index af2ade54a7ef..41909bdd8558 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CLK_RK3308)        += clk-rk3308.o
 obj-$(CONFIG_CLK_RK3328)        += clk-rk3328.o
 obj-$(CONFIG_CLK_RK3368)        += clk-rk3368.o
 obj-$(CONFIG_CLK_RK3399)        += clk-rk3399.o
+obj-$(CONFIG_CLK_RK3562)        += clk-rk3562.o
 obj-$(CONFIG_CLK_RK3568)	+= clk-rk3568.o
 obj-$(CONFIG_CLK_RK3576)	+= clk-rk3576.o rst-rk3576.o
 obj-$(CONFIG_CLK_RK3588)	+= clk-rk3588.o rst-rk3588.o
diff --git a/drivers/clk/rockchip/clk-rk3562.c b/drivers/clk/rockchip/clk-rk3562.c
new file mode 100644
index 000000000000..af9aaf382145
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3562.c
@@ -0,0 +1,1111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ * Author: Elaine Zhang <zhangqing at rock-chips.com>
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rk3562-cru.h>
+#include "clk.h"
+
+#define RK3562_GRF_SOC_STATUS0		0x430
+#define ROCKCHIP_PLL_ALLOW_POWER_DOWN	BIT(2)
+
+enum rk3562_plls {
+	apll, gpll, vpll, hpll, cpll, dpll,
+};
+
+static struct rockchip_pll_rate_table rk3562_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(2208000000, 1, 92, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2184000000, 1, 91, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2160000000, 1, 90, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2088000000, 1, 87, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2064000000, 1, 86, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2040000000, 1, 85, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1992000000, 1, 83, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1920000000, 1, 80, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1584000000, 1, 132, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1560000000, 1, 130, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1536000000, 1, 128, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1512000000, 1, 126, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1488000000, 1, 124, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1464000000, 1, 122, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1440000000, 1, 120, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1392000000, 1, 116, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1368000000, 1, 114, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1344000000, 1, 112, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1320000000, 1, 110, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1272000000, 1, 106, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1248000000, 1, 104, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
+	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+	RK3036_PLL_RATE(700000000, 3, 350, 4, 1, 1, 0),
+	RK3036_PLL_RATE(696000000, 1, 116, 4, 1, 1, 0),
+	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
+	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
+	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
+	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+	RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0),
+	RK3036_PLL_RATE(148500000, 1, 99, 4, 4, 1, 0),
+	RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
+	RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
+	RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0),
+	{ /* sentinel */ },
+};
+
+PNAME(mux_pll_p)			= { "xin24m" };
+PNAME(gpll_cpll_p)			= { "gpll", "cpll" };
+PNAME(gpll_cpll_hpll_p)			= { "gpll", "cpll", "hpll" };
+PNAME(gpll_cpll_pvtpll_dmyapll_p)	= { "gpll", "cpll", "log_pvtpll", "dummy_apll" };
+PNAME(gpll_cpll_hpll_xin24m_p)		= { "gpll", "cpll", "hpll", "xin24m" };
+PNAME(gpll_cpll_vpll_dmyhpll_p)		= { "gpll", "cpll", "vpll", "dummy_hpll" };
+PNAME(gpll_dmyhpll_vpll_apll_p)		= { "gpll", "dummy_hpll", "vpll", "apll" };
+PNAME(gpll_cpll_xin24m_p)		= { "gpll", "cpll", "xin24m" };
+PNAME(gpll_cpll_xin24m_dmyapll_p)	= { "gpll", "cpll", "xin24m", "dummy_apll" };
+PNAME(gpll_cpll_xin24m_dmyhpll_p)	= { "gpll", "cpll", "xin24m", "dummy_hpll" };
+PNAME(vpll_dmyhpll_gpll_cpll_p)		= { "vpll", "dummy_hpll", "gpll", "cpll" };
+PNAME(mux_xin24m_32k_p)			= { "xin24m", "clk_rtc_32k" };
+PNAME(mux_50m_xin24m_p)			= { "clk_matrix_50m_src", "xin24m" };
+PNAME(mux_100m_50m_xin24m_p)		= { "clk_matrix_100m_src", "clk_matrix_50m_src", "xin24m" };
+PNAME(mux_125m_xin24m_p)		= { "clk_matrix_125m_src", "xin24m" };
+PNAME(mux_200m_xin24m_32k_p)		= { "clk_200m_pmu", "xin24m", "clk_rtc_32k" };
+PNAME(mux_200m_100m_p)			= { "clk_matrix_200m_src", "clk_matrix_100m_src" };
+PNAME(mux_200m_100m_50m_xin24m_p)	= { "clk_matrix_200m_src", "clk_matrix_100m_src", "clk_matrix_50m_src", "xin24m" };
+PNAME(clk_sai0_p)			= { "clk_sai0_src", "clk_sai0_frac", "xin_osc0_half", "mclk_sai0_from_io" };
+PNAME(mclk_sai0_out2io_p)		= { "mclk_sai0", "xin_osc0_half" };
+PNAME(clk_sai1_p)			= { "clk_sai1_src", "clk_sai1_frac", "xin_osc0_half", "mclk_sai1_from_io" };
+PNAME(mclk_sai1_out2io_p)		= { "mclk_sai1", "xin_osc0_half" };
+PNAME(clk_sai2_p)			= { "clk_sai2_src", "clk_sai2_frac", "xin_osc0_half", "mclk_sai2_from_io" };
+PNAME(mclk_sai2_out2io_p)		= { "mclk_sai2", "xin_osc0_half" };
+PNAME(clk_spdif_p)			= { "clk_spdif_src", "clk_spdif_frac", "xin_osc0_half" };
+PNAME(clk_uart1_p)			= { "clk_uart1_src", "clk_uart1_frac", "xin24m" };
+PNAME(clk_uart2_p)			= { "clk_uart2_src", "clk_uart2_frac", "xin24m" };
+PNAME(clk_uart3_p)			= { "clk_uart3_src", "clk_uart3_frac", "xin24m" };
+PNAME(clk_uart4_p)			= { "clk_uart4_src", "clk_uart4_frac", "xin24m" };
+PNAME(clk_uart5_p)			= { "clk_uart5_src", "clk_uart5_frac", "xin24m" };
+PNAME(clk_uart6_p)			= { "clk_uart6_src", "clk_uart6_frac", "xin24m" };
+PNAME(clk_uart7_p)			= { "clk_uart7_src", "clk_uart7_frac", "xin24m" };
+PNAME(clk_uart8_p)			= { "clk_uart8_src", "clk_uart8_frac", "xin24m" };
+PNAME(clk_uart9_p)			= { "clk_uart9_src", "clk_uart9_frac", "xin24m" };
+PNAME(clk_rtc32k_pmu_p)			= { "clk_rtc32k_frac", "xin32k", "clk_32k_pvtm" };
+PNAME(clk_pmu1_uart0_p)			= { "clk_pmu1_uart0_src", "clk_pmu1_uart0_frac", "xin24m" };
+PNAME(clk_pipephy_ref_p)		= { "clk_pipephy_div", "clk_pipephy_xin24m" };
+PNAME(clk_usbphy_ref_p)			= { "clk_usb2phy_xin24m", "clk_24m_sscsrc" };
+PNAME(clk_mipidsi_ref_p)		= { "clk_mipidsiphy_xin24m", "clk_24m_sscsrc" };
+
+static struct rockchip_pll_clock rk3562_pll_clks[] __initdata = {
+	[apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p,
+		     0, RK3562_PLL_CON(0),
+		     RK3562_MODE_CON, 0, 0,
+		     ROCKCHIP_PLL_ALLOW_POWER_DOWN, rk3562_pll_rates),
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+		     0, RK3562_PLL_CON(24),
+		     RK3562_MODE_CON, 2, 3, 0, rk3562_pll_rates),
+	[vpll] = PLL(pll_rk3328, PLL_VPLL, "vpll", mux_pll_p,
+		     0, RK3562_PLL_CON(32),
+		     RK3562_MODE_CON, 6, 4,
+		     ROCKCHIP_PLL_ALLOW_POWER_DOWN, rk3562_pll_rates),
+	[hpll] = PLL(pll_rk3328, PLL_HPLL, "hpll", mux_pll_p,
+		     0, RK3562_PLL_CON(40),
+		     RK3562_MODE_CON, 8, 5,
+		     ROCKCHIP_PLL_ALLOW_POWER_DOWN, rk3562_pll_rates),
+	[cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p,
+		     0, RK3562_PMU1_PLL_CON(0),
+		     RK3562_PMU1_MODE_CON, 0, 2, 0, rk3562_pll_rates),
+	[dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3562_SUBDDR_PLL_CON(0),
+		     RK3562_SUBDDR_MODE_CON, 0, 1, 0, NULL),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_clk_branch rk3562_clk_sai0_fracmux __initdata =
+	MUX(CLK_SAI0, "clk_sai0", clk_sai0_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(3), 6, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_sai1_fracmux __initdata =
+	MUX(CLK_SAI1, "clk_sai1", clk_sai1_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(5), 6, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_sai2_fracmux __initdata =
+	MUX(CLK_SAI2, "clk_sai2", clk_sai2_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(8), 6, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_spdif_fracmux __initdata =
+	MUX(CLK_SPDIF, "clk_spdif", clk_spdif_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(15), 6, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_uart1_fracmux __initdata =
+	MUX(CLK_UART1, "clk_uart1", clk_uart1_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(21), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_uart2_fracmux __initdata =
+	MUX(CLK_UART2, "clk_uart2", clk_uart2_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(23), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_uart3_fracmux __initdata =
+	MUX(CLK_UART3, "clk_uart3", clk_uart3_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(25), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_uart4_fracmux __initdata =
+	MUX(CLK_UART4, "clk_uart4", clk_uart4_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(27), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_uart5_fracmux __initdata =
+	MUX(CLK_UART5, "clk_uart5", clk_uart5_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(29), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_uart6_fracmux __initdata =
+	MUX(CLK_UART6, "clk_uart6", clk_uart6_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(31), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_uart7_fracmux __initdata =
+	MUX(CLK_UART7, "clk_uart7", clk_uart7_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(33), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_uart8_fracmux __initdata =
+	MUX(CLK_UART8, "clk_uart8", clk_uart8_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(35), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_uart9_fracmux __initdata =
+	MUX(CLK_UART9, "clk_uart9", clk_uart9_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(37), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_rtc32k_pmu_fracmux __initdata =
+	MUX(CLK_RTC_32K, "clk_rtc_32k", clk_rtc32k_pmu_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+			RK3562_PMU0_CLKSEL_CON(1), 0, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_pmu1_uart0_fracmux __initdata =
+	MUX(CLK_PMU1_UART0, "clk_pmu1_uart0", clk_pmu1_uart0_p, CLK_SET_RATE_PARENT,
+			RK3562_PMU1_CLKSEL_CON(2), 6, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3562_clk_branches[] __initdata = {
+	/*
+	 * CRU Clock-Architecture
+	 */
+	/* PD_TOP */
+	COMPOSITE(CLK_MATRIX_50M_SRC, "clk_matrix_50m_src", gpll_cpll_p, 0,
+			RK3562_CLKSEL_CON(0), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3562_CLKGATE_CON(0), 0, GFLAGS),
+	COMPOSITE(CLK_MATRIX_100M_SRC, "clk_matrix_100m_src", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_CLKSEL_CON(0), 15, 1, MFLAGS, 8, 4, DFLAGS,
+			RK3562_CLKGATE_CON(0), 1, GFLAGS),
+	COMPOSITE(CLK_MATRIX_125M_SRC, "clk_matrix_125m_src", gpll_cpll_p, 0,
+			RK3562_CLKSEL_CON(1), 7, 1, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(0), 2, GFLAGS),
+	COMPOSITE(CLK_MATRIX_200M_SRC, "clk_matrix_200m_src", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_CLKSEL_CON(2), 7, 1, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(0), 4, GFLAGS),
+	COMPOSITE(CLK_MATRIX_300M_SRC, "clk_matrix_300m_src", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_CLKSEL_CON(3), 7, 1, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(0), 6, GFLAGS),
+	COMPOSITE(ACLK_TOP, "aclk_top", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_CLKSEL_CON(5), 7, 1, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE(ACLK_TOP_VIO, "aclk_top_vio", gpll_cpll_p, 0,
+			RK3562_CLKSEL_CON(5), 15, 1, MFLAGS, 8, 4, DFLAGS,
+			RK3562_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE(CLK_24M_SSCSRC, "clk_24m_sscsrc", vpll_dmyhpll_gpll_cpll_p, 0,
+			RK3562_CLKSEL_CON(6), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			RK3562_CLKGATE_CON(1), 9, GFLAGS),
+	COMPOSITE(CLK_CAM0_OUT2IO, "clk_cam0_out2io", gpll_cpll_xin24m_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(8), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			RK3562_CLKGATE_CON(1), 12, GFLAGS),
+	COMPOSITE(CLK_CAM1_OUT2IO, "clk_cam1_out2io", gpll_cpll_xin24m_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(8), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3562_CLKGATE_CON(1), 13, GFLAGS),
+	COMPOSITE(CLK_CAM2_OUT2IO, "clk_cam2_out2io", gpll_cpll_xin24m_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			RK3562_CLKGATE_CON(1), 14, GFLAGS),
+	COMPOSITE(CLK_CAM3_OUT2IO, "clk_cam3_out2io", gpll_cpll_xin24m_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(9), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3562_CLKGATE_CON(1), 15, GFLAGS),
+	FACTOR(0, "xin_osc0_half", "xin24m", 0, 1, 2),
+
+	/* PD_BUS */
+	COMPOSITE(ACLK_BUS, "aclk_bus", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_CLKSEL_CON(40), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3562_CLKGATE_CON(18), 0, GFLAGS),
+	COMPOSITE(HCLK_BUS, "hclk_bus", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_CLKSEL_CON(40), 15, 1, MFLAGS, 8, 6, DFLAGS,
+			RK3562_CLKGATE_CON(18), 1, GFLAGS),
+	COMPOSITE(PCLK_BUS, "pclk_bus", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_CLKSEL_CON(41), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3562_CLKGATE_CON(18), 2, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(19), 0, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(19), 1, GFLAGS),
+	GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(19), 2, GFLAGS),
+	GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(19), 3, GFLAGS),
+	GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(19), 4, GFLAGS),
+	COMPOSITE_NODIV(CLK_I2C, "clk_i2c", mux_200m_100m_50m_xin24m_p, 0,
+			RK3562_CLKSEL_CON(41), 8, 2, MFLAGS,
+			RK3562_CLKGATE_CON(19), 5, GFLAGS),
+	GATE(CLK_I2C1, "clk_i2c1", "clk_i2c", 0,
+			RK3562_CLKGATE_CON(19), 6, GFLAGS),
+	GATE(CLK_I2C2, "clk_i2c2", "clk_i2c", 0,
+			RK3562_CLKGATE_CON(19), 7, GFLAGS),
+	GATE(CLK_I2C3, "clk_i2c3", "clk_i2c", 0,
+			RK3562_CLKGATE_CON(19), 8, GFLAGS),
+	GATE(CLK_I2C4, "clk_i2c4", "clk_i2c", 0,
+			RK3562_CLKGATE_CON(19), 9, GFLAGS),
+	GATE(CLK_I2C5, "clk_i2c5", "clk_i2c", 0,
+			RK3562_CLKGATE_CON(19), 10, GFLAGS),
+	COMPOSITE_NODIV(DCLK_BUS_GPIO, "dclk_bus_gpio", mux_xin24m_32k_p, 0,
+			RK3562_CLKSEL_CON(41), 15, 1, MFLAGS,
+			RK3562_CLKGATE_CON(20), 4, GFLAGS),
+	GATE(DCLK_BUS_GPIO3, "dclk_bus_gpio3", "dclk_bus_gpio", 0,
+			RK3562_CLKGATE_CON(20), 5, GFLAGS),
+	GATE(DCLK_BUS_GPIO4, "dclk_bus_gpio4", "dclk_bus_gpio", 0,
+			RK3562_CLKGATE_CON(20), 6, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(21), 0, GFLAGS),
+	GATE(CLK_TIMER0, "clk_timer0", "xin24m", 0,
+			RK3562_CLKGATE_CON(21), 1, GFLAGS),
+	GATE(CLK_TIMER1, "clk_timer1", "xin24m", 0,
+			RK3562_CLKGATE_CON(21), 2, GFLAGS),
+	GATE(CLK_TIMER2, "clk_timer2", "xin24m", 0,
+			RK3562_CLKGATE_CON(21), 3, GFLAGS),
+	GATE(CLK_TIMER3, "clk_timer3", "xin24m", 0,
+			RK3562_CLKGATE_CON(21), 4, GFLAGS),
+	GATE(CLK_TIMER4, "clk_timer4", "xin24m", 0,
+			RK3562_CLKGATE_CON(21), 5, GFLAGS),
+	GATE(CLK_TIMER5, "clk_timer5", "xin24m", 0,
+			RK3562_CLKGATE_CON(21), 6, GFLAGS),
+	GATE(PCLK_STIMER, "pclk_stimer", "pclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(21), 7, GFLAGS),
+	GATE(CLK_STIMER0, "clk_stimer0", "xin24m", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(21), 8, GFLAGS),
+	GATE(CLK_STIMER1, "clk_stimer1", "xin24m", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(21), 9, GFLAGS),
+	GATE(PCLK_WDTNS, "pclk_wdtns", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(22), 0, GFLAGS),
+	GATE(CLK_WDTNS, "clk_wdtns", "xin24m", 0,
+			RK3562_CLKGATE_CON(22), 1, GFLAGS),
+	GATE(PCLK_GRF, "pclk_grf", "pclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(22), 2, GFLAGS),
+	GATE(PCLK_SGRF, "pclk_sgrf", "pclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(22), 3, GFLAGS),
+	GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(22), 4, GFLAGS),
+	GATE(PCLK_INTC, "pclk_intc", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(22), 5, GFLAGS),
+	GATE(ACLK_BUS_GIC400, "aclk_bus_gic400", "aclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(22), 6, GFLAGS),
+	GATE(ACLK_BUS_SPINLOCK, "aclk_bus_spinlock", "aclk_bus", 0,
+			RK3562_CLKGATE_CON(23), 0, GFLAGS),
+	GATE(ACLK_DCF, "aclk_dcf", "aclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(23), 1, GFLAGS),
+	GATE(PCLK_DCF, "pclk_dcf", "pclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(23), 2, GFLAGS),
+	GATE(FCLK_BUS_CM0_CORE, "fclk_bus_cm0_core", "hclk_bus", 0,
+			RK3562_CLKGATE_CON(23), 3, GFLAGS),
+	GATE(CLK_BUS_CM0_RTC, "clk_bus_cm0_rtc", "clk_rtc_32k", 0,
+			RK3562_CLKGATE_CON(23), 4, GFLAGS),
+	GATE(HCLK_ICACHE, "hclk_icache", "hclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(23), 8, GFLAGS),
+	GATE(HCLK_DCACHE, "hclk_dcache", "hclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(23), 9, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(24), 0, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m", 0,
+			RK3562_CLKSEL_CON(43), 0, 11, DFLAGS,
+			RK3562_CLKGATE_CON(24), 1, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m", 0,
+			RK3562_CLKSEL_CON(43), 11, 5, DFLAGS,
+			RK3562_CLKGATE_CON(24), 3, GFLAGS),
+	GATE(PCLK_DFT2APB, "pclk_dft2apb", "pclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(24), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_SARADC_VCCIO156, "clk_saradc_vccio156", "xin24m", 0,
+			RK3562_CLKSEL_CON(44), 0, 12, DFLAGS,
+			RK3562_CLKGATE_CON(24), 9, GFLAGS),
+	GATE(PCLK_GMAC, "pclk_gmac", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(25), 0, GFLAGS),
+	GATE(ACLK_GMAC, "aclk_gmac", "aclk_bus", 0,
+			RK3562_CLKGATE_CON(25), 1, GFLAGS),
+	COMPOSITE_NODIV(CLK_GMAC_125M_CRU_I, "clk_gmac_125m_cru_i", mux_125m_xin24m_p, 0,
+			RK3562_CLKSEL_CON(45), 8, 1, MFLAGS,
+			RK3562_CLKGATE_CON(25), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_GMAC_50M_CRU_I, "clk_gmac_50m_cru_i", mux_50m_xin24m_p, 0,
+			RK3562_CLKSEL_CON(45), 7, 1, MFLAGS,
+			RK3562_CLKGATE_CON(25), 3, GFLAGS),
+	COMPOSITE(CLK_GMAC_ETH_OUT2IO, "clk_gmac_eth_out2io", gpll_cpll_p, 0,
+			RK3562_CLKSEL_CON(46), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_CLKGATE_CON(25), 4, GFLAGS),
+	GATE(PCLK_APB2ASB_VCCIO156, "pclk_apb2asb_vccio156", "pclk_bus", CLK_IS_CRITICAL,
+			RK3562_CLKGATE_CON(25), 5, GFLAGS),
+	GATE(PCLK_TO_VCCIO156, "pclk_to_vccio156", "pclk_bus", CLK_IS_CRITICAL,
+			RK3562_CLKGATE_CON(25), 6, GFLAGS),
+	GATE(PCLK_DSIPHY, "pclk_dsiphy", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(25), 8, GFLAGS),
+	GATE(PCLK_DSITX, "pclk_dsitx", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(25), 9, GFLAGS),
+	GATE(PCLK_CPU_EMA_DET, "pclk_cpu_ema_det", "pclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(25), 10, GFLAGS),
+	GATE(PCLK_HASH, "pclk_hash", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(25), 11, GFLAGS),
+	GATE(PCLK_TOPCRU, "pclk_topcru", "pclk_bus", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(25), 15, GFLAGS),
+	GATE(PCLK_ASB2APB_VCCIO156, "pclk_asb2apb_vccio156", "pclk_to_vccio156", CLK_IS_CRITICAL,
+			RK3562_CLKGATE_CON(26), 0, GFLAGS),
+	GATE(PCLK_IOC_VCCIO156, "pclk_ioc_vccio156", "pclk_to_vccio156", CLK_IS_CRITICAL,
+			RK3562_CLKGATE_CON(26), 1, GFLAGS),
+	GATE(PCLK_GPIO3_VCCIO156, "pclk_gpio3_vccio156", "pclk_to_vccio156", 0,
+			RK3562_CLKGATE_CON(26), 2, GFLAGS),
+	GATE(PCLK_GPIO4_VCCIO156, "pclk_gpio4_vccio156", "pclk_to_vccio156", 0,
+			RK3562_CLKGATE_CON(26), 3, GFLAGS),
+	GATE(PCLK_SARADC_VCCIO156, "pclk_saradc_vccio156", "pclk_to_vccio156", 0,
+			RK3562_CLKGATE_CON(26), 4, GFLAGS),
+	GATE(PCLK_MAC100, "pclk_mac100", "pclk_bus", 0,
+			RK3562_CLKGATE_CON(27), 0, GFLAGS),
+	GATE(ACLK_MAC100, "aclk_mac100", "aclk_bus", 0,
+			RK3562_CLKGATE_CON(27), 1, GFLAGS),
+	COMPOSITE_NODIV(CLK_MAC100_50M_MATRIX, "clk_mac100_50m_matrix", mux_50m_xin24m_p, 0,
+			RK3562_CLKSEL_CON(47), 7, 1, MFLAGS,
+			RK3562_CLKGATE_CON(27), 2, GFLAGS),
+
+	/* PD_CORE */
+	COMPOSITE_NOMUX(0, "aclk_core_pre", "scmi_clk_cpu", CLK_IGNORE_UNUSED,
+			RK3562_CLKSEL_CON(11), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3562_CLKGATE_CON(4), 3, GFLAGS),
+	COMPOSITE_NOMUX(0, "pclk_dbg_pre", "scmi_clk_cpu", CLK_IGNORE_UNUSED,
+			RK3562_CLKSEL_CON(12), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3562_CLKGATE_CON(4), 5, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_CORE, "hclk_core", "gpll", CLK_IS_CRITICAL,
+			RK3562_CLKSEL_CON(13), 0, 6, DFLAGS,
+			RK3562_CLKGATE_CON(5), 2, GFLAGS),
+	GATE(0, "pclk_dbg_daplite", "pclk_dbg_pre", CLK_IGNORE_UNUSED,
+			RK3562_CLKGATE_CON(4), 10, GFLAGS),
+
+	/* PD_DDR */
+	FACTOR_GATE(0, "clk_gpll_mux_to_ddr", "gpll", 0, 1, 4,
+			RK3328_CLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_DDR, "pclk_ddr", "clk_gpll_mux_to_ddr", CLK_IS_CRITICAL,
+			RK3562_DDR_CLKSEL_CON(1), 8, 5, DFLAGS,
+			RK3562_DDR_CLKGATE_CON(0), 3, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MSCH_BRG_BIU, "clk_msch_brg_biu", "clk_gpll_mux_to_ddr", CLK_IS_CRITICAL,
+			RK3562_DDR_CLKSEL_CON(1), 0, 4, DFLAGS,
+			RK3562_DDR_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_DDR_HWLP, "pclk_ddr_hwlp", "pclk_ddr", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(0), 6, GFLAGS),
+	GATE(PCLK_DDR_UPCTL, "pclk_ddr_upctl", "pclk_ddr", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(PCLK_DDR_PHY, "pclk_ddr_phy", "pclk_ddr", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_DDR_DFICTL, "pclk_ddr_dfictl", "pclk_ddr", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(0), 9, GFLAGS),
+	GATE(PCLK_DDR_DMA2DDR, "pclk_ddr_dma2ddr", "pclk_ddr", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(0), 10, GFLAGS),
+	GATE(PCLK_DDR_MON, "pclk_ddr_mon", "pclk_ddr", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(1), 0, GFLAGS),
+	GATE(TMCLK_DDR_MON, "tmclk_ddr_mon", "xin24m", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(PCLK_DDR_GRF, "pclk_ddr_grf", "pclk_ddr", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(1), 2, GFLAGS),
+	GATE(PCLK_DDR_CRU, "pclk_ddr_cru", "pclk_ddr", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(1), 3, GFLAGS),
+	GATE(PCLK_SUBDDR_CRU, "pclk_subddr_cru", "pclk_ddr", CLK_IGNORE_UNUSED,
+			RK3562_DDR_CLKGATE_CON(1), 4, GFLAGS),
+
+	/* PD_GPU */
+	COMPOSITE(CLK_GPU_PRE, "clk_gpu_pre", gpll_cpll_p, 0,
+			RK3562_CLKSEL_CON(18), 7, 1, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(8), 0, GFLAGS),
+	COMPOSITE_NOMUX(ACLK_GPU_PRE, "aclk_gpu_pre", "clk_gpu_pre", 0,
+			RK3562_CLKSEL_CON(19), 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(8), 2, GFLAGS),
+	GATE(CLK_GPU, "clk_gpu", "clk_gpu_pre", 0,
+			RK3562_CLKGATE_CON(8), 4, GFLAGS),
+	COMPOSITE_NODIV(CLK_GPU_BRG, "clk_gpu_brg", mux_200m_100m_p, 0,
+			RK3562_CLKSEL_CON(19), 15, 1, MFLAGS,
+			RK3562_CLKGATE_CON(8), 8, GFLAGS),
+
+	/* PD_NPU */
+	COMPOSITE(CLK_NPU_PRE, "clk_npu_pre", gpll_cpll_p, 0,
+			RK3562_CLKSEL_CON(15), 7, 1, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(6), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_NPU_PRE, "hclk_npu_pre", "clk_npu_pre", 0,
+			RK3562_CLKSEL_CON(16), 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(6), 1, GFLAGS),
+	GATE(ACLK_RKNN, "aclk_rknn", "clk_npu_pre", 0,
+			RK3562_CLKGATE_CON(6), 4, GFLAGS),
+	GATE(HCLK_RKNN, "hclk_rknn", "hclk_npu_pre", 0,
+			RK3562_CLKGATE_CON(6), 5, GFLAGS),
+
+	/* PD_PERI */
+	COMPOSITE(ACLK_PERI, "aclk_peri", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_PERI_CLKSEL_CON(0), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE(HCLK_PERI, "hclk_peri", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_PERI_CLKSEL_CON(0), 15, 1, MFLAGS, 8, 6, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE(PCLK_PERI, "pclk_peri", gpll_cpll_p, CLK_IS_CRITICAL,
+			RK3562_PERI_CLKSEL_CON(1), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(1), 2, GFLAGS),
+	GATE(PCLK_PERICRU, "pclk_pericru", "pclk_peri", CLK_IGNORE_UNUSED,
+			RK3562_PERI_CLKGATE_CON(1), 6, GFLAGS),
+	GATE(HCLK_SAI0, "hclk_sai0", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(2), 0, GFLAGS),
+	COMPOSITE(CLK_SAI0_SRC, "clk_sai0_src", gpll_cpll_hpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(1), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(2), 1, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_SAI0_FRAC, "clk_sai0_frac", "clk_sai0_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(2), 0,
+			RK3562_PERI_CLKGATE_CON(2), 2, GFLAGS,
+			&rk3562_clk_sai0_fracmux),
+	GATE(MCLK_SAI0, "mclk_sai0", "clk_sai0", 0,
+			RK3562_PERI_CLKGATE_CON(2), 3, GFLAGS),
+	COMPOSITE_NODIV(MCLK_SAI0_OUT2IO, "mclk_sai0_out2io", mclk_sai0_out2io_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(3), 5, 1, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(2), 4, GFLAGS),
+	GATE(HCLK_SAI1, "hclk_sai1", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(2), 5, GFLAGS),
+	COMPOSITE(CLK_SAI1_SRC, "clk_sai1_src", gpll_cpll_hpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(3), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(2), 6, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_SAI1_FRAC, "clk_sai1_frac", "clk_sai1_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(4), 0,
+			RK3562_PERI_CLKGATE_CON(2), 7, GFLAGS,
+			&rk3562_clk_sai1_fracmux),
+	GATE(MCLK_SAI1, "mclk_sai1", "clk_sai1", 0,
+			RK3562_PERI_CLKGATE_CON(2), 8, GFLAGS),
+	COMPOSITE_NODIV(MCLK_SAI1_OUT2IO, "mclk_sai1_out2io", mclk_sai1_out2io_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(5), 5, 1, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(2), 9, GFLAGS),
+	GATE(HCLK_SAI2, "hclk_sai2", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(2), 10, GFLAGS),
+	COMPOSITE(CLK_SAI2_SRC, "clk_sai2_src", gpll_cpll_hpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(6), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(2), 11, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_SAI2_FRAC, "clk_sai2_frac", "clk_sai2_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(7), 0,
+			RK3562_PERI_CLKGATE_CON(2), 12, GFLAGS,
+			&rk3562_clk_sai2_fracmux),
+	GATE(MCLK_SAI2, "mclk_sai2", "clk_sai2", 0,
+			RK3562_PERI_CLKGATE_CON(2), 13, GFLAGS),
+	COMPOSITE_NODIV(MCLK_SAI2_OUT2IO, "mclk_sai2_out2io", mclk_sai2_out2io_p, CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(8), 5, 1, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(2), 14, GFLAGS),
+	GATE(HCLK_DSM, "hclk_dsm", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(3), 1, GFLAGS),
+	GATE(CLK_DSM, "clk_dsm", "mclk_sai1", 0,
+			RK3562_PERI_CLKGATE_CON(3), 2, GFLAGS),
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(3), 4, GFLAGS),
+	COMPOSITE(MCLK_PDM, "mclk_pdm", gpll_cpll_hpll_xin24m_p, 0,
+			RK3562_PERI_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(3), 5, GFLAGS),
+	GATE(HCLK_SPDIF, "hclk_spdif", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(3), 8, GFLAGS),
+	COMPOSITE(CLK_SPDIF_SRC, "clk_spdif_src", gpll_cpll_hpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(13), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(3), 9, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_SPDIF_FRAC, "clk_spdif_frac", "clk_spdif_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(14), 0,
+			RK3562_PERI_CLKGATE_CON(3), 10, GFLAGS,
+			&rk3562_clk_spdif_fracmux),
+	GATE(MCLK_SPDIF, "mclk_spdif", "clk_spdif", 0,
+			RK3562_PERI_CLKGATE_CON(3), 11, GFLAGS),
+	GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(4), 0, GFLAGS),
+	COMPOSITE(CCLK_SDMMC0, "cclk_sdmmc0", gpll_cpll_xin24m_dmyhpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(16), 14, 2, MFLAGS, 0, 8, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(4), 1, GFLAGS),
+	MMC(SCLK_SDMMC0_DRV, "sdmmc0_drv", "cclk_sdmmc0", RK3562_SDMMC0_CON0, 1),
+	MMC(SCLK_SDMMC0_SAMPLE, "sdmmc0_sample", "cclk_sdmmc0", RK3562_SDMMC0_CON1, 1),
+	GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(4), 2, GFLAGS),
+	COMPOSITE(CCLK_SDMMC1, "cclk_sdmmc1", gpll_cpll_xin24m_dmyhpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(17), 14, 2, MFLAGS, 0, 8, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(4), 3, GFLAGS),
+	MMC(SCLK_SDMMC1_DRV, "sdmmc1_drv", "cclk_sdmmc1", RK3562_SDMMC1_CON0, 1),
+	MMC(SCLK_SDMMC1_SAMPLE, "sdmmc1_sample", "cclk_sdmmc1", RK3562_SDMMC1_CON1, 1),
+	GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(4), 8, GFLAGS),
+	GATE(ACLK_EMMC, "aclk_emmc", "aclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(4), 9, GFLAGS),
+	COMPOSITE(CCLK_EMMC, "cclk_emmc", gpll_cpll_xin24m_dmyhpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(18), 14, 2, MFLAGS, 0, 8, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(4), 10, GFLAGS),
+	COMPOSITE(BCLK_EMMC, "bclk_emmc", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(19), 15, 1, MFLAGS, 8, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(4), 11, GFLAGS),
+	GATE(TMCLK_EMMC, "tmclk_emmc", "xin24m", 0,
+			RK3562_PERI_CLKGATE_CON(4), 12, GFLAGS),
+	COMPOSITE(SCLK_SFC, "sclk_sfc", gpll_cpll_xin24m_p, 0,
+			RK3562_PERI_CLKSEL_CON(20), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(4), 13, GFLAGS),
+	GATE(HCLK_SFC, "hclk_sfc", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(4), 14, GFLAGS),
+	GATE(HCLK_USB2HOST, "hclk_usb2host", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(5), 0, GFLAGS),
+	GATE(HCLK_USB2HOST_ARB, "hclk_usb2host_arb", "hclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(5), 1, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(6), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_xin24m_p, 0,
+			RK3562_PERI_CLKSEL_CON(20), 12, 2, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(6), 1, GFLAGS),
+	GATE(SCLK_IN_SPI1, "sclk_in_spi1", "sclk_in_spi1_io", 0,
+			RK3562_PERI_CLKGATE_CON(6), 2, GFLAGS),
+	GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(6), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", mux_200m_100m_50m_xin24m_p, 0,
+			RK3562_PERI_CLKSEL_CON(20), 14, 2, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(6), 4, GFLAGS),
+	GATE(SCLK_IN_SPI2, "sclk_in_spi2", "sclk_in_spi2_io", 0,
+			RK3562_PERI_CLKGATE_CON(6), 5, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(7), 0, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(7), 1, GFLAGS),
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(7), 2, GFLAGS),
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(7), 3, GFLAGS),
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(7), 4, GFLAGS),
+	GATE(PCLK_UART6, "pclk_uart6", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(7), 5, GFLAGS),
+	GATE(PCLK_UART7, "pclk_uart7", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(7), 6, GFLAGS),
+	GATE(PCLK_UART8, "pclk_uart8", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(7), 7, GFLAGS),
+	GATE(PCLK_UART9, "pclk_uart9", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(7), 8, GFLAGS),
+	COMPOSITE(CLK_UART1_SRC, "clk_uart1_src", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(21), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(7), 9, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(22), 0,
+			RK3562_PERI_CLKGATE_CON(7), 10, GFLAGS,
+			&rk3562_clk_uart1_fracmux),
+	GATE(SCLK_UART1, "sclk_uart1", "clk_uart1", 0,
+			RK3562_PERI_CLKGATE_CON(7), 11, GFLAGS),
+	COMPOSITE(CLK_UART2_SRC, "clk_uart2_src", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(23), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(7), 12, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(24), 0,
+			RK3562_PERI_CLKGATE_CON(7), 13, GFLAGS,
+			&rk3562_clk_uart2_fracmux),
+	GATE(SCLK_UART2, "sclk_uart2", "clk_uart2", 0,
+			RK3562_PERI_CLKGATE_CON(7), 14, GFLAGS),
+	COMPOSITE(CLK_UART3_SRC, "clk_uart3_src", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(25), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(7), 15, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(26), 0,
+			RK3562_PERI_CLKGATE_CON(8), 0, GFLAGS,
+			&rk3562_clk_uart3_fracmux),
+	GATE(SCLK_UART3, "sclk_uart3", "clk_uart3", 0,
+			RK3562_PERI_CLKGATE_CON(8), 1, GFLAGS),
+	COMPOSITE(CLK_UART4_SRC, "clk_uart4_src", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(27), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(8), 2, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(28), 0,
+			RK3562_PERI_CLKGATE_CON(8), 3, GFLAGS,
+			&rk3562_clk_uart4_fracmux),
+	GATE(SCLK_UART4, "sclk_uart4", "clk_uart4", 0,
+			RK3562_PERI_CLKGATE_CON(8), 4, GFLAGS),
+	COMPOSITE(CLK_UART5_SRC, "clk_uart5_src", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(29), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(8), 5, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(30), 0,
+			RK3562_PERI_CLKGATE_CON(8), 6, GFLAGS,
+			&rk3562_clk_uart5_fracmux),
+	GATE(SCLK_UART5, "sclk_uart5", "clk_uart5", 0,
+			RK3562_PERI_CLKGATE_CON(8), 7, GFLAGS),
+	COMPOSITE(CLK_UART6_SRC, "clk_uart6_src", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(31), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(8), 8, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(32), 0,
+			RK3562_PERI_CLKGATE_CON(8), 9, GFLAGS,
+			&rk3562_clk_uart6_fracmux),
+	GATE(SCLK_UART6, "sclk_uart6", "clk_uart6", 0,
+			RK3562_PERI_CLKGATE_CON(8), 10, GFLAGS),
+	COMPOSITE(CLK_UART7_SRC, "clk_uart7_src", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(33), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(8), 11, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(34), 0,
+			RK3562_PERI_CLKGATE_CON(8), 12, GFLAGS,
+			&rk3562_clk_uart7_fracmux),
+	GATE(SCLK_UART7, "sclk_uart7", "clk_uart7", 0,
+			RK3562_PERI_CLKGATE_CON(8), 13, GFLAGS),
+	COMPOSITE(CLK_UART8_SRC, "clk_uart8_src", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(35), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(8), 14, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART8_FRAC, "clk_uart8_frac", "clk_uart8_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(36), 0,
+			RK3562_PERI_CLKGATE_CON(8), 15, GFLAGS,
+			&rk3562_clk_uart8_fracmux),
+	GATE(SCLK_UART8, "sclk_uart8", "clk_uart8", 0,
+			RK3562_PERI_CLKGATE_CON(9), 0, GFLAGS),
+	COMPOSITE(CLK_UART9_SRC, "clk_uart9_src", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(37), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(9), 1, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART9_FRAC, "clk_uart9_frac", "clk_uart9_src", CLK_SET_RATE_PARENT,
+			RK3562_PERI_CLKSEL_CON(38), 0,
+			RK3562_PERI_CLKGATE_CON(9), 2, GFLAGS,
+			&rk3562_clk_uart9_fracmux),
+	GATE(SCLK_UART9, "sclk_uart9", "clk_uart9", 0,
+			RK3562_PERI_CLKGATE_CON(9), 3, GFLAGS),
+	GATE(PCLK_PWM1_PERI, "pclk_pwm1_peri", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(10), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM1_PERI, "clk_pwm1_peri", mux_100m_50m_xin24m_p, 0,
+			RK3562_PERI_CLKSEL_CON(40), 0, 2, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(10), 1, GFLAGS),
+	GATE(CLK_CAPTURE_PWM1_PERI, "clk_capture_pwm1_peri", "xin24m", 0,
+			RK3562_PERI_CLKGATE_CON(10), 2, GFLAGS),
+	GATE(PCLK_PWM2_PERI, "pclk_pwm2_peri", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(10), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM2_PERI, "clk_pwm2_peri", mux_100m_50m_xin24m_p, 0,
+			RK3562_PERI_CLKSEL_CON(40), 6, 2, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(10), 4, GFLAGS),
+	GATE(CLK_CAPTURE_PWM2_PERI, "clk_capture_pwm2_peri", "xin24m", 0,
+			RK3562_PERI_CLKGATE_CON(10), 5, GFLAGS),
+	GATE(PCLK_PWM3_PERI, "pclk_pwm3_peri", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(10), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM3_PERI, "clk_pwm3_peri", mux_100m_50m_xin24m_p, 0,
+			RK3562_PERI_CLKSEL_CON(40), 8, 2, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(10), 7, GFLAGS),
+	GATE(CLK_CAPTURE_PWM3_PERI, "clk_capture_pwm3_peri", "xin24m", 0,
+			RK3562_PERI_CLKGATE_CON(10), 8, GFLAGS),
+	GATE(PCLK_CAN0, "pclk_can0", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(11), 0, GFLAGS),
+	COMPOSITE(CLK_CAN0, "clk_can0", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(41), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(11), 1, GFLAGS),
+	GATE(PCLK_CAN1, "pclk_can1", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(11), 2, GFLAGS),
+	COMPOSITE(CLK_CAN1, "clk_can1", gpll_cpll_p, 0,
+			RK3562_PERI_CLKSEL_CON(41), 15, 1, MFLAGS, 8, 5, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(11), 3, GFLAGS),
+	GATE(PCLK_PERI_WDT, "pclk_peri_wdt", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(13), 0, GFLAGS),
+	COMPOSITE_NODIV(TCLK_PERI_WDT, "tclk_peri_wdt", mux_xin24m_32k_p, 0,
+			RK3562_PERI_CLKSEL_CON(43), 15, 1, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(ACLK_SYSMEM, "aclk_sysmem", "aclk_peri", CLK_IGNORE_UNUSED,
+			RK3562_PERI_CLKGATE_CON(13), 2, GFLAGS),
+	GATE(HCLK_BOOTROM, "hclk_bootrom", "hclk_peri", CLK_IGNORE_UNUSED,
+			RK3562_PERI_CLKGATE_CON(13), 3, GFLAGS),
+	GATE(PCLK_PERI_GRF, "pclk_peri_grf", "pclk_peri", CLK_IGNORE_UNUSED,
+			RK3562_PERI_CLKGATE_CON(13), 4, GFLAGS),
+	GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(13), 5, GFLAGS),
+	GATE(ACLK_RKDMAC, "aclk_rkdmac", "aclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(13), 6, GFLAGS),
+	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(14), 0, GFLAGS),
+	GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m", 0,
+			RK3562_PERI_CLKGATE_CON(14), 1, GFLAGS),
+	COMPOSITE_NOMUX(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "xin24m", 0,
+			RK3562_PERI_CLKSEL_CON(44), 0, 8, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(14), 2, GFLAGS),
+	GATE(PCLK_OTPC_S, "pclk_otpc_s", "pclk_peri", CLK_IGNORE_UNUSED,
+			RK3562_PERI_CLKGATE_CON(14), 3, GFLAGS),
+	GATE(CLK_SBPI_OTPC_S, "clk_sbpi_otpc_s", "xin24m", CLK_IGNORE_UNUSED,
+			RK3562_PERI_CLKGATE_CON(14), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_USER_OTPC_S, "clk_user_otpc_s", "xin24m", CLK_IGNORE_UNUSED,
+			RK3562_PERI_CLKSEL_CON(44), 8, 8, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(14), 5, GFLAGS),
+	GATE(CLK_OTPC_ARB, "clk_otpc_arb", "xin24m", 0,
+			RK3562_PERI_CLKGATE_CON(14), 6, GFLAGS),
+	GATE(PCLK_OTPPHY, "pclk_otpphy", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(14), 7, GFLAGS),
+	GATE(PCLK_USB2PHY, "pclk_usb2phy", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(15), 0, GFLAGS),
+	GATE(PCLK_PIPEPHY, "pclk_pipephy", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(15), 7, GFLAGS),
+	GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(16), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_SARADC, "clk_saradc", "xin24m", 0,
+			RK3562_PERI_CLKSEL_CON(46), 0, 12, DFLAGS,
+			RK3562_PERI_CLKGATE_CON(16), 5, GFLAGS),
+	GATE(PCLK_IOC_VCCIO234, "pclk_ioc_vccio234", "pclk_peri", CLK_IS_CRITICAL,
+			RK3562_PERI_CLKGATE_CON(16), 12, GFLAGS),
+	GATE(PCLK_PERI_GPIO1, "pclk_peri_gpio1", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(17), 0, GFLAGS),
+	GATE(PCLK_PERI_GPIO2, "pclk_peri_gpio2", "pclk_peri", 0,
+			RK3562_PERI_CLKGATE_CON(17), 1, GFLAGS),
+	COMPOSITE_NODIV(DCLK_PERI_GPIO, "dclk_peri_gpio", mux_xin24m_32k_p, 0,
+			RK3562_PERI_CLKSEL_CON(47), 8, 1, MFLAGS,
+			RK3562_PERI_CLKGATE_CON(17), 4, GFLAGS),
+	GATE(DCLK_PERI_GPIO1, "dclk_peri_gpio1", "dclk_peri_gpio", 0,
+			RK3562_PERI_CLKGATE_CON(17), 2, GFLAGS),
+	GATE(DCLK_PERI_GPIO2, "dclk_peri_gpio2", "dclk_peri_gpio", 0,
+			RK3562_PERI_CLKGATE_CON(17), 3, GFLAGS),
+
+	/* PD_PHP */
+	COMPOSITE(ACLK_PHP, "aclk_php", gpll_cpll_p, 0,
+			RK3562_CLKSEL_CON(36), 7, 1, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(16), 0, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_PHP, "pclk_php", "aclk_php", 0,
+			RK3562_CLKSEL_CON(36), 8, 4, DFLAGS,
+			RK3562_CLKGATE_CON(16), 1, GFLAGS),
+	GATE(ACLK_PCIE20_MST, "aclk_pcie20_mst", "aclk_php", 0,
+			RK3562_CLKGATE_CON(16), 4, GFLAGS),
+	GATE(ACLK_PCIE20_SLV, "aclk_pcie20_slv", "aclk_php", 0,
+			RK3562_CLKGATE_CON(16), 5, GFLAGS),
+	GATE(ACLK_PCIE20_DBI, "aclk_pcie20_dbi", "aclk_php", 0,
+			RK3562_CLKGATE_CON(16), 6, GFLAGS),
+	GATE(PCLK_PCIE20, "pclk_pcie20", "pclk_php", 0,
+			RK3562_CLKGATE_CON(16), 7, GFLAGS),
+	GATE(CLK_PCIE20_AUX, "clk_pcie20_aux", "xin24m", 0,
+			RK3562_CLKGATE_CON(16), 8, GFLAGS),
+	GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_php", 0,
+			RK3562_CLKGATE_CON(16), 10, GFLAGS),
+	COMPOSITE_NODIV(CLK_USB3OTG_SUSPEND, "clk_usb3otg_suspend", mux_xin24m_32k_p, 0,
+			RK3562_CLKSEL_CON(36), 15, 1, MFLAGS,
+			RK3562_CLKGATE_CON(16), 11, GFLAGS),
+	GATE(CLK_USB3OTG_REF, "clk_usb3otg_ref", "xin24m", 0,
+			RK3562_CLKGATE_CON(16), 12, GFLAGS),
+	GATE(CLK_PIPEPHY_REF_FUNC, "clk_pipephy_ref_func", "pclk_pcie20", 0,
+			RK3562_CLKGATE_CON(17), 3, GFLAGS),
+
+	/* PD_PMU1 */
+	COMPOSITE_NOMUX(CLK_200M_PMU, "clk_200m_pmu", "cpll", CLK_IS_CRITICAL,
+			RK3562_PMU1_CLKSEL_CON(0), 0, 5, DFLAGS,
+			RK3562_PMU1_CLKGATE_CON(0), 1, GFLAGS),
+	/* PD_PMU0 */
+	COMPOSITE_FRACMUX(CLK_RTC32K_FRAC, "clk_rtc32k_frac", "xin24m", CLK_IS_CRITICAL,
+			RK3562_PMU0_CLKSEL_CON(0), 0,
+			RK3562_PMU0_CLKGATE_CON(0), 15, GFLAGS,
+			&rk3562_rtc32k_pmu_fracmux),
+	COMPOSITE_NOMUX(BUSCLK_PDPMU0, "busclk_pdpmu0", "clk_200m_pmu", CLK_IS_CRITICAL,
+			RK3562_PMU0_CLKSEL_CON(1), 3, 2, DFLAGS,
+			RK3562_PMU0_CLKGATE_CON(0), 14, GFLAGS),
+	GATE(PCLK_PMU0_CRU, "pclk_pmu0_cru", "busclk_pdpmu0", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(0), 0, GFLAGS),
+	GATE(PCLK_PMU0_PMU, "pclk_pmu0_pmu", "busclk_pdpmu0", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(CLK_PMU0_PMU, "clk_pmu0_pmu", "xin24m", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_PMU0_HP_TIMER, "pclk_pmu0_hp_timer", "busclk_pdpmu0", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_PMU0_HP_TIMER, "clk_pmu0_hp_timer", "xin24m", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(CLK_PMU0_32K_HP_TIMER, "clk_pmu0_32k_hp_timer", "clk_rtc_32k", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_PMU0_PVTM, "pclk_pmu0_pvtm", "busclk_pdpmu0", 0,
+			RK3562_PMU0_CLKGATE_CON(0), 6, GFLAGS),
+	GATE(CLK_PMU0_PVTM, "clk_pmu0_pvtm", "xin24m", 0,
+			RK3562_PMU0_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(PCLK_IOC_PMUIO, "pclk_ioc_pmuio", "busclk_pdpmu0", CLK_IS_CRITICAL,
+			RK3562_PMU0_CLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_PMU0_GPIO0, "pclk_pmu0_gpio0", "busclk_pdpmu0", 0,
+			RK3562_PMU0_CLKGATE_CON(0), 9, GFLAGS),
+	GATE(DBCLK_PMU0_GPIO0, "dbclk_pmu0_gpio0", "xin24m", 0,
+			RK3562_PMU0_CLKGATE_CON(0), 10, GFLAGS),
+	GATE(PCLK_PMU0_GRF, "pclk_pmu0_grf", "busclk_pdpmu0", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_PMU0_SGRF, "pclk_pmu0_sgrf", "busclk_pdpmu0", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(0), 12, GFLAGS),
+	GATE(CLK_DDR_FAIL_SAFE, "clk_ddr_fail_safe", "xin24m", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(1), 0, GFLAGS),
+	GATE(PCLK_PMU0_SCRKEYGEN, "pclk_pmu0_scrkeygen", "busclk_pdpmu0", CLK_IGNORE_UNUSED,
+			RK3562_PMU0_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_NOMUX(CLK_PIPEPHY_DIV, "clk_pipephy_div", "cpll", 0,
+			RK3562_PMU0_CLKSEL_CON(2), 0, 6, DFLAGS,
+			RK3562_PMU0_CLKGATE_CON(2), 0, GFLAGS),
+	GATE(CLK_PIPEPHY_XIN24M, "clk_pipephy_xin24m", "xin24m", 0,
+			RK3562_PMU0_CLKGATE_CON(2), 1, GFLAGS),
+	COMPOSITE_NODIV(CLK_PIPEPHY_REF, "clk_pipephy_ref", clk_pipephy_ref_p, 0,
+			RK3562_PMU0_CLKSEL_CON(2), 7, 1, MFLAGS,
+			RK3562_PMU0_CLKGATE_CON(2), 2, GFLAGS),
+	GATE(CLK_USB2PHY_XIN24M, "clk_usb2phy_xin24m", "xin24m", 0,
+			RK3562_PMU0_CLKGATE_CON(2), 4, GFLAGS),
+	COMPOSITE_NODIV(CLK_USB2PHY_REF, "clk_usb2phy_ref", clk_usbphy_ref_p, 0,
+			RK3562_PMU0_CLKSEL_CON(2), 8, 1, MFLAGS,
+			RK3562_PMU0_CLKGATE_CON(2), 5, GFLAGS),
+	GATE(CLK_MIPIDSIPHY_XIN24M, "clk_mipidsiphy_xin24m", "xin24m", 0,
+			RK3562_PMU0_CLKGATE_CON(2), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_MIPIDSIPHY_REF, "clk_mipidsiphy_ref", clk_mipidsi_ref_p, 0,
+			RK3562_PMU0_CLKSEL_CON(2), 15, 1, MFLAGS,
+			RK3562_PMU0_CLKGATE_CON(2), 7, GFLAGS),
+	GATE(PCLK_PMU0_I2C0, "pclk_pmu0_i2c0", "busclk_pdpmu0", 0,
+			RK3562_PMU0_CLKGATE_CON(2), 8, GFLAGS),
+	COMPOSITE(CLK_PMU0_I2C0, "clk_pmu0_i2c0", mux_200m_xin24m_32k_p, 0,
+			RK3562_PMU0_CLKSEL_CON(3), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RK3562_PMU0_CLKGATE_CON(2), 9, GFLAGS),
+	/* PD_PMU1 */
+	GATE(PCLK_PMU1_CRU, "pclk_pmu1_cru", "busclk_pdpmu0", CLK_IGNORE_UNUSED,
+			RK3562_PMU1_CLKGATE_CON(0), 0, GFLAGS),
+	GATE(HCLK_PMU1_MEM, "hclk_pmu1_mem", "busclk_pdpmu0", CLK_IGNORE_UNUSED,
+			RK3562_PMU1_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_PMU1_UART0, "pclk_pmu1_uart0", "busclk_pdpmu0", 0,
+			RK3562_PMU1_CLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NOMUX(CLK_PMU1_UART0_SRC, "clk_pmu1_uart0_src", "cpll", 0,
+			RK3562_PMU1_CLKSEL_CON(2), 0, 4, DFLAGS,
+			RK3562_PMU1_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_PMU1_UART0_FRAC, "clk_pmu1_uart0_frac", "clk_pmu1_uart0_src", CLK_SET_RATE_PARENT,
+			RK3562_PMU1_CLKSEL_CON(3), 0,
+			RK3562_PMU1_CLKGATE_CON(0), 9, GFLAGS,
+			&rk3562_clk_pmu1_uart0_fracmux),
+	GATE(SCLK_PMU1_UART0, "sclk_pmu1_uart0", "clk_pmu1_uart0", 0,
+			RK3562_PMU1_CLKGATE_CON(0), 10, GFLAGS),
+	GATE(PCLK_PMU1_SPI0, "pclk_pmu1_spi0", "busclk_pdpmu0", 0,
+			RK3562_PMU1_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE(CLK_PMU1_SPI0, "clk_pmu1_spi0", mux_200m_xin24m_32k_p, 0,
+			RK3562_PMU1_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 2, DFLAGS,
+			RK3562_PMU1_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(SCLK_IN_PMU1_SPI0, "sclk_in_pmu1_spi0", "sclk_in_pmu1_spi0_io", 0,
+			RK3562_PMU1_CLKGATE_CON(1), 2, GFLAGS),
+	GATE(PCLK_PMU1_PWM0, "pclk_pmu1_pwm0", "busclk_pdpmu0", 0,
+			RK3562_PMU1_CLKGATE_CON(1), 3, GFLAGS),
+	COMPOSITE(CLK_PMU1_PWM0, "clk_pmu1_pwm0", mux_200m_xin24m_32k_p, 0,
+			RK3562_PMU1_CLKSEL_CON(4), 14, 2, MFLAGS, 8, 2, DFLAGS,
+			RK3562_PMU1_CLKGATE_CON(1), 4, GFLAGS),
+	GATE(CLK_CAPTURE_PMU1_PWM0, "clk_capture_pmu1_pwm0", "xin24m", 0,
+			RK3562_PMU1_CLKGATE_CON(1), 5, GFLAGS),
+	GATE(CLK_PMU1_WIFI, "clk_pmu1_wifi", "xin24m", 0,
+			RK3562_PMU1_CLKGATE_CON(1), 6, GFLAGS),
+	GATE(FCLK_PMU1_CM0_CORE, "fclk_pmu1_cm0_core", "busclk_pdpmu0", 0,
+			RK3562_PMU1_CLKGATE_CON(2), 0, GFLAGS),
+	GATE(CLK_PMU1_CM0_RTC, "clk_pmu1_cm0_rtc", "clk_rtc_32k", 0,
+			RK3562_PMU1_CLKGATE_CON(2), 1, GFLAGS),
+	GATE(PCLK_PMU1_WDTNS, "pclk_pmu1_wdtns", "busclk_pdpmu0", 0,
+			RK3562_PMU1_CLKGATE_CON(2), 3, GFLAGS),
+	GATE(CLK_PMU1_WDTNS, "clk_pmu1_wdtns", "xin24m", 0,
+			RK3562_PMU1_CLKGATE_CON(2), 4, GFLAGS),
+	GATE(PCLK_PMU1_MAILBOX, "pclk_pmu1_mailbox", "busclk_pdpmu0", 0,
+			RK3562_PMU1_CLKGATE_CON(3), 8, GFLAGS),
+
+	/* PD_RGA */
+	COMPOSITE(ACLK_RGA_PRE, "aclk_rga_pre", gpll_cpll_pvtpll_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(32), 6, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(14), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_RGA_PRE, "hclk_rga_pre", "aclk_rga_jdec", 0,
+			RK3562_CLKSEL_CON(32), 8, 3, DFLAGS,
+			RK3562_CLKGATE_CON(14), 1, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_rga_jdec", 0,
+			RK3562_CLKGATE_CON(14), 6, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", 0,
+			RK3562_CLKGATE_CON(14), 7, GFLAGS),
+	COMPOSITE(CLK_RGA_CORE, "clk_rga_core", gpll_cpll_pvtpll_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(33), 6, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(14), 8, GFLAGS),
+	GATE(ACLK_JDEC, "aclk_jdec", "aclk_rga_jdec", 0,
+			RK3562_CLKGATE_CON(14), 9, GFLAGS),
+	GATE(HCLK_JDEC, "hclk_jdec", "hclk_rga_pre", 0,
+			RK3562_CLKGATE_CON(14), 10, GFLAGS),
+
+	/* PD_VDPU */
+	COMPOSITE(ACLK_VDPU_PRE, "aclk_vdpu_pre", gpll_cpll_pvtpll_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(22), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3562_CLKGATE_CON(10), 0, GFLAGS),
+	COMPOSITE(CLK_RKVDEC_HEVC_CA, "clk_rkvdec_hevc_ca", gpll_cpll_pvtpll_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(23), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RK3562_CLKGATE_CON(10), 3, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_VDPU_PRE, "hclk_vdpu_pre", "aclk_vdpu", 0,
+			RK3562_CLKSEL_CON(24), 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(10), 4, GFLAGS),
+	GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_vdpu", 0,
+			RK3562_CLKGATE_CON(10), 7, GFLAGS),
+	GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_vdpu_pre", 0,
+			RK3562_CLKGATE_CON(10), 8, GFLAGS),
+
+	/* PD_VEPU */
+	COMPOSITE(CLK_RKVENC_CORE, "clk_rkvenc_core", gpll_cpll_pvtpll_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(20), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3562_CLKGATE_CON(9), 0, GFLAGS),
+	COMPOSITE(ACLK_VEPU_PRE, "aclk_vepu_pre", gpll_cpll_pvtpll_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(20), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RK3562_CLKGATE_CON(9), 1, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_VEPU_PRE, "hclk_vepu_pre", "aclk_vepu", 0,
+			RK3562_CLKSEL_CON(21), 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(9), 2, GFLAGS),
+	GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_vepu", 0,
+			RK3562_CLKGATE_CON(9), 5, GFLAGS),
+	GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_vepu", 0,
+			RK3562_CLKGATE_CON(9), 6, GFLAGS),
+
+	/* PD_VI */
+	COMPOSITE(ACLK_VI, "aclk_vi", gpll_cpll_pvtpll_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(25), 6, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(11), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_VI, "hclk_vi", "aclk_vi_isp", 0,
+			RK3562_CLKSEL_CON(26), 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(11), 1, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_VI, "pclk_vi", "aclk_vi_isp", 0,
+			RK3562_CLKSEL_CON(26), 8, 4, DFLAGS,
+			RK3562_CLKGATE_CON(11), 2, GFLAGS),
+	GATE(ACLK_ISP, "aclk_isp", "aclk_vi_isp", 0,
+			RK3562_CLKGATE_CON(11), 6, GFLAGS),
+	GATE(HCLK_ISP, "hclk_isp", "hclk_vi", 0,
+			RK3562_CLKGATE_CON(11), 7, GFLAGS),
+	COMPOSITE(CLK_ISP, "clk_isp", gpll_cpll_pvtpll_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(27), 6, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3562_CLKGATE_CON(11), 8, GFLAGS),
+	GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_isp", 0,
+			RK3562_CLKGATE_CON(11), 9, GFLAGS),
+	GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi", 0,
+			RK3562_CLKGATE_CON(11), 10, GFLAGS),
+	COMPOSITE(DCLK_VICAP, "dclk_vicap", gpll_cpll_pvtpll_dmyapll_p, 0,
+			RK3562_CLKSEL_CON(27), 14, 2, MFLAGS, 8, 4, DFLAGS,
+			RK3562_CLKGATE_CON(11), 11, GFLAGS),
+	GATE(CSIRX0_CLK_DATA, "csirx0_clk_data", "csirx0_clk_data_io", 0,
+			RK3562_CLKGATE_CON(11), 12, GFLAGS),
+	GATE(CSIRX1_CLK_DATA, "csirx1_clk_data", "csirx1_clk_data_io", 0,
+			RK3562_CLKGATE_CON(11), 13, GFLAGS),
+	GATE(CSIRX2_CLK_DATA, "csirx2_clk_data", "csirx2_clk_data_io", 0,
+			RK3562_CLKGATE_CON(11), 14, GFLAGS),
+	GATE(CSIRX3_CLK_DATA, "csirx3_clk_data", "csirx3_clk_data_io", 0,
+			RK3562_CLKGATE_CON(11), 15, GFLAGS),
+	GATE(PCLK_CSIHOST0, "pclk_csihost0", "pclk_vi", 0,
+			RK3562_CLKGATE_CON(12), 0, GFLAGS),
+	GATE(PCLK_CSIHOST1, "pclk_csihost1", "pclk_vi", 0,
+			RK3562_CLKGATE_CON(12), 1, GFLAGS),
+	GATE(PCLK_CSIHOST2, "pclk_csihost2", "pclk_vi", 0,
+			RK3562_CLKGATE_CON(12), 2, GFLAGS),
+	GATE(PCLK_CSIHOST3, "pclk_csihost3", "pclk_vi", 0,
+			RK3562_CLKGATE_CON(12), 3, GFLAGS),
+	GATE(PCLK_CSIPHY0, "pclk_csiphy0", "pclk_vi", 0,
+			RK3562_CLKGATE_CON(12), 4, GFLAGS),
+	GATE(PCLK_CSIPHY1, "pclk_csiphy1", "pclk_vi", 0,
+			RK3562_CLKGATE_CON(12), 5, GFLAGS),
+
+	/* PD_VO */
+	COMPOSITE(ACLK_VO_PRE, "aclk_vo_pre", gpll_cpll_vpll_dmyhpll_p, 0,
+			RK3562_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3562_CLKGATE_CON(13), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_VO_PRE, "hclk_vo_pre", "aclk_vo", 0,
+			RK3562_CLKSEL_CON(29), 0, 5, DFLAGS,
+			RK3562_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(ACLK_VOP, "aclk_vop", "aclk_vo", 0,
+			RK3562_CLKGATE_CON(13), 6, GFLAGS),
+	GATE(HCLK_VOP, "hclk_vop", "hclk_vo_pre", 0,
+			RK3562_CLKGATE_CON(13), 7, GFLAGS),
+	COMPOSITE(DCLK_VOP, "dclk_vop", gpll_dmyhpll_vpll_apll_p, CLK_SET_RATE_NO_REPARENT,
+			RK3562_CLKSEL_CON(30), 14, 2, MFLAGS, 0, 8, DFLAGS,
+			RK3562_CLKGATE_CON(13), 8, GFLAGS),
+	COMPOSITE(DCLK_VOP1, "dclk_vop1", gpll_dmyhpll_vpll_apll_p, CLK_SET_RATE_NO_REPARENT,
+			RK3562_CLKSEL_CON(31), 14, 2, MFLAGS, 0, 8, DFLAGS,
+			RK3562_CLKGATE_CON(13), 9, GFLAGS),
+};
+
+static void __iomem *rk3562_cru_base;
+
+static void __init rk3562_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	void __iomem *reg_base;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	rk3562_cru_base = reg_base;
+
+	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rk3562_pll_clks,
+				   ARRAY_SIZE(rk3562_pll_clks),
+				   RK3562_GRF_SOC_STATUS0);
+
+	rockchip_clk_register_branches(ctx, rk3562_clk_branches,
+				       ARRAY_SIZE(rk3562_clk_branches));
+
+	/* (0x30444 - 0x400) / 4 + 1 = 49170 */
+	rockchip_register_softrst(np, 49170, reg_base + RK3562_SOFTRST_CON(0),
+				  ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+	rockchip_register_restart_notifier(ctx, RK3562_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+}
+
+CLK_OF_DECLARE(rk3562_cru, "rockchip,rk3562-cru", rk3562_clk_init);
+
+#ifdef MODULE
+struct clk_rk3562_inits {
+	void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rk3562_inits clk_3562_cru_init = {
+	.inits = rk3562_clk_init,
+};
+
+static const struct of_device_id clk_rk3562_match_table[] = {
+	{
+		.compatible = "rockchip,rk3562-cru",
+		.data = &clk_3562_cru_init,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, clk_rk3562_match_table);
+
+static int clk_rk3562_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const struct of_device_id *match;
+	const struct clk_rk3562_inits *init_data;
+
+	match = of_match_device(clk_rk3562_match_table, &pdev->dev);
+	if (!match || !match->data)
+		return -EINVAL;
+
+	init_data = match->data;
+	if (init_data->inits)
+		init_data->inits(np);
+
+	return 0;
+}
+
+static struct platform_driver clk_rk3562_driver = {
+	.probe		= clk_rk3562_probe,
+	.driver		= {
+		.name	= "clk-rk3562",
+		.of_match_table = clk_rk3562_match_table,
+		.suppress_bind_attrs = true,
+	},
+};
+module_platform_driver(clk_rk3562_driver);
+
+MODULE_DESCRIPTION("Rockchip RK3562 Clock Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:clk-rk3562");
+#endif /* MODULE */
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index f1957e1c1178..ed7546b365e4 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -207,6 +207,45 @@ struct clk;
 #define RK3399_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x100)
 #define RK3399_PMU_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
 
+#define RK3562_PMU0_CRU_BASE		0x10000
+#define RK3562_PMU1_CRU_BASE		0x18000
+#define RK3562_DDR_CRU_BASE		0x20000
+#define RK3562_SUBDDR_CRU_BASE		0x28000
+#define RK3562_PERI_CRU_BASE		0x30000
+
+#define RK3562_PLL_CON(x)		RK2928_PLL_CON(x)
+#define RK3562_PMU1_PLL_CON(x)		((x) * 0x4 + RK3562_PMU1_CRU_BASE + 0x40)
+#define RK3562_SUBDDR_PLL_CON(x)	((x) * 0x4 + RK3562_SUBDDR_CRU_BASE + 0x20)
+#define RK3562_MODE_CON			0x600
+#define RK3562_PMU1_MODE_CON		(RK3562_PMU1_CRU_BASE + 0x380)
+#define RK3562_SUBDDR_MODE_CON		(RK3562_SUBDDR_CRU_BASE + 0x380)
+#define RK3562_CLKSEL_CON(x)		((x) * 0x4 + 0x100)
+#define RK3562_CLKGATE_CON(x)		((x) * 0x4 + 0x300)
+#define RK3562_SOFTRST_CON(x)		((x) * 0x4 + 0x400)
+#define RK3562_DDR_CLKSEL_CON(x)	((x) * 0x4 + RK3562_DDR_CRU_BASE + 0x100)
+#define RK3562_DDR_CLKGATE_CON(x)	((x) * 0x4 + RK3562_DDR_CRU_BASE + 0x180)
+#define RK3562_DDR_SOFTRST_CON(x)	((x) * 0x4 + RK3562_DDR_CRU_BASE + 0x200)
+#define RK3562_SUBDDR_CLKSEL_CON(x)	((x) * 0x4 + RK3562_SUBDDR_CRU_BASE + 0x100)
+#define RK3562_SUBDDR_CLKGATE_CON(x)	((x) * 0x4 + RK3562_SUBDDR_CRU_BASE + 0x180)
+#define RK3562_SUBDDR_SOFTRST_CON(x)	((x) * 0x4 + RK3562_SUBDDR_CRU_BASE + 0x200)
+#define RK3562_PERI_CLKSEL_CON(x)	((x) * 0x4 + RK3562_PERI_CRU_BASE + 0x100)
+#define RK3562_PERI_CLKGATE_CON(x)	((x) * 0x4 + RK3562_PERI_CRU_BASE + 0x300)
+#define RK3562_PERI_SOFTRST_CON(x)	((x) * 0x4 + RK3562_PERI_CRU_BASE + 0x400)
+#define RK3562_PMU0_CLKSEL_CON(x)	((x) * 0x4 + RK3562_PMU0_CRU_BASE + 0x100)
+#define RK3562_PMU0_CLKGATE_CON(x)	((x) * 0x4 + RK3562_PMU0_CRU_BASE + 0x180)
+#define RK3562_PMU0_SOFTRST_CON(x)	((x) * 0x4 + RK3562_PMU0_CRU_BASE + 0x200)
+#define RK3562_PMU1_CLKSEL_CON(x)	((x) * 0x4 + RK3562_PMU1_CRU_BASE + 0x100)
+#define RK3562_PMU1_CLKGATE_CON(x)	((x) * 0x4 + RK3562_PMU1_CRU_BASE + 0x180)
+#define RK3562_PMU1_SOFTRST_CON(x)	((x) * 0x4 + RK3562_PMU1_CRU_BASE + 0x200)
+#define RK3562_GLB_SRST_FST		0x614
+#define RK3562_GLB_SRST_SND		0x618
+#define RK3562_GLB_RST_CON		0x61c
+#define RK3562_GLB_RST_ST		0x620
+#define RK3562_SDMMC0_CON0		0x624
+#define RK3562_SDMMC0_CON1		0x628
+#define RK3562_SDMMC1_CON0		0x62c
+#define RK3562_SDMMC1_CON1		0x630
+
 #define RK3568_PLL_CON(x)		RK2928_PLL_CON(x)
 #define RK3568_MODE_CON0		0xc0
 #define RK3568_MISC_CON0		0xc4
-- 
2.25.1



From kever.yang at rock-chips.com  Fri Dec 20 02:37:50 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:37:50 +0800
Subject: [PATCH 04/38] dt-bindings: pinctrl: Add rk3562 pinctrl support
In-Reply-To: <20241220103825.3509421-1-kever.yang@rock-chips.com>
References: <20241220103825.3509421-1-kever.yang@rock-chips.com>
Message-ID: <20241220103825.3509421-5-kever.yang@rock-chips.com>

Add the compatible string for the rk3562 SoC.

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

 Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
index 6a23d845f1f2..80a2b1934849 100644
--- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
@@ -44,6 +44,7 @@ properties:
       - rockchip,rk3328-pinctrl
       - rockchip,rk3368-pinctrl
       - rockchip,rk3399-pinctrl
+      - rockchip,rk3562-pinctrl
       - rockchip,rk3568-pinctrl
       - rockchip,rk3576-pinctrl
       - rockchip,rk3588-pinctrl
-- 
2.25.1



From yeoreum.yun at arm.com  Fri Dec 20 02:38:26 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:38:26 +0000
Subject: [PATCH v3 0/9] coresight: change some driver' spinlock type to
 raw_spinlock_t
In-Reply-To: <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
 <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>
Message-ID: <Z2VJIh2+Z40bZi1e@e129823.arm.com>

Hi Mike.

> Notably missing is the same changes for the etm3x driver. The ETMv3.x
> and PTM1.x are supported by this driver, and these trace source
> variants are also supported in perf in the cs_etm.c code.

But I wonder etmv3 needs to change. Because its spinlock is used only
via sysfs enable/disable path.
So, I think it doesn't need to change the lock type.

> STM is also missing, though this is not directly enabled via perf -
> but could perhaps run concurrently as it can be a target output for
> ftrace.

Actually, I couldn't find out the path where
the STM's lock could be grabbed under other raw_spin_lock (including csdev)
If you don't mind would you let me the code path please?

Thanks
> --
> Mike Leach
> Principal Engineer, ARM Ltd.
> Manchester Design Centre. UK


From przemyslaw.kitszel at intel.com  Fri Dec 20 02:41:26 2024
From: przemyslaw.kitszel at intel.com (Przemek Kitszel)
Date: Fri, 20 Dec 2024 11:41:26 +0100
Subject: [PATCH net] net: ethernet: ti: am65-cpsw: default to round-robin
 for host port receive
In-Reply-To: <20241220075618.228202-1-s-vadapalli@ti.com>
References: <20241220075618.228202-1-s-vadapalli@ti.com>
Message-ID: <eb573f51-4363-4cd7-ab1b-0d7304820d85@intel.com>

On 12/20/24 08:56, Siddharth Vadapalli wrote:
> The Host Port (i.e. CPU facing port) of CPSW receives traffic from Linux
> via TX DMA Channels which are Hardware Queues consisting of traffic
> categorized according to their priority. The Host Port is configured to
> dequeue traffic from these Hardware Queues on the basis of priority i.e.
> as long as traffic exists on a Hardware Queue of a higher priority, the
> traffic on Hardware Queues of lower priority isn't dequeued. An alternate
> operation is also supported wherein traffic can be dequeued by the Host
> Port in a Round-Robin manner.
> 
> Until [0], the am65-cpsw driver enabled a single TX DMA Channel, due to
> which, unless modified by user via "ethtool", all traffic from Linux is
> transmitted on DMA Channel 0. Therefore, configuring the Host Port for
> priority based dequeuing or Round-Robin operation is identical since
> there is a single DMA Channel.
> 
> Since [0], all 8 TX DMA Channels are enabled by default. Additionally,
> the default "tc mapping" doesn't take into account the possibility of
> different traffic profiles which various users might have. This results
> in traffic starvation at the Host Port due to the priority based dequeuing
> which has been enabled by default since the inception of the driver. The
> traffic starvation triggers NETDEV WATCHDOG timeout for all TX DMA Channels
> that haven't been serviced due to the presence of traffic on the higher
> priority TX DMA Channels.

I get it right that the starving is caused by HW/DMA (not SW)

> 
> Fix this by defaulting to Round-Robin dequeuing at the Host Port, which
> shall ensure that traffic is dequeued from all TX DMA Channels irrespective
> of the traffic profile. This will address the NETDEV WATCHDOG timeouts.
> At the same time, users can still switch from Round-Robin to Priority
> based dequeuing at the Host Port with the help of the "p0-rx-ptype-rrobin"

why the flag has rx in the name?

> private flag of "ethtool". Users are expected to setup an appropriate
> "tc mapping" that suits their traffic profile when switching to priority
> based dequeuing at the Host Port.
> 
> [0] commit be397ea3473d ("net: ethernet: am65-cpsw: Set default TX channels to maximum")
> Fixes: be397ea3473d ("net: ethernet: am65-cpsw: Set default TX channels to maximum")
> Cc: <stable at vger.kernel.org>
> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
> ---
> 
> Hello,
> 
> This patch is based on commit
> 8faabc041a00 Merge tag 'net-6.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
> of Mainline Linux.
> 
> Regards,
> Siddharth.
> 
>   drivers/net/ethernet/ti/am65-cpsw-nuss.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
> index 14e1df721f2e..5465bf872734 100644
> --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
> +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
> @@ -3551,7 +3551,7 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
>   	init_completion(&common->tdown_complete);
>   	common->tx_ch_num = AM65_CPSW_DEFAULT_TX_CHNS;
>   	common->rx_ch_num_flows = AM65_CPSW_DEFAULT_RX_CHN_FLOWS;
> -	common->pf_p0_rx_ptype_rrobin = false;
> +	common->pf_p0_rx_ptype_rrobin = true;
>   	common->default_vlan = 1;
>   
>   	common->ports = devm_kcalloc(dev, common->port_num,



From yeoreum.yun at arm.com  Fri Dec 20 02:45:11 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:11 +0000
Subject: [PATCH v4 0/9] coresight: change some driver' spinlock type to raw_spinlock_t
Message-ID: <20241220104521.809071-1-yeoreum.yun@arm.com>

In some coresight drivers, drvdata->spinlock can be held during __schedule()
by perf_event_task_sched_out()/in().

Since drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this,change type drvdata->spinlock in some coresight drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>

Yeoreum Yun (9):
  coresight: change coresight_device lock type to  raw_spinlock_t
  coresight-etm4x: change etmv4_drvdata spinlock type to  raw_spinlock_t
  coresight: change coresight_trace_id_map's lock type to
    raw_spinlock_t
  coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
  coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
  coresight-funnel: change funnel_drvdata spinlock's type to
    raw_spinlock_t
  coresight-replicator: change replicator_drvdata spinlock's type to
    raw_spinlock_t
  coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
  coresight/ultrasoc: change smb_drv_data spinlock's type to
    raw_spinlock_t

 .../hwtracing/coresight/coresight-config.c    |   8 +-
 .../hwtracing/coresight/coresight-config.h    |   2 +-
 drivers/hwtracing/coresight/coresight-core.c  |   2 +-
 .../hwtracing/coresight/coresight-cti-core.c  |  44 +--
 .../hwtracing/coresight/coresight-cti-sysfs.c |  76 +++---
 drivers/hwtracing/coresight/coresight-cti.h   |   2 +-
 drivers/hwtracing/coresight/coresight-etb10.c |  26 +-
 .../coresight/coresight-etm4x-core.c          |  18 +-
 .../coresight/coresight-etm4x-sysfs.c         | 250 +++++++++---------
 drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
 .../hwtracing/coresight/coresight-funnel.c    |  12 +-
 .../coresight/coresight-replicator.c          |  12 +-
 .../hwtracing/coresight/coresight-syscfg.c    |  26 +-
 .../hwtracing/coresight/coresight-tmc-core.c  |   6 +-
 .../hwtracing/coresight/coresight-tmc-etf.c   |  48 ++--
 .../hwtracing/coresight/coresight-tmc-etr.c   |  40 +--
 drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
 .../hwtracing/coresight/coresight-trace-id.c  |  22 +-
 drivers/hwtracing/coresight/ultrasoc-smb.c    |  12 +-
 drivers/hwtracing/coresight/ultrasoc-smb.h    |   2 +-
 include/linux/coresight.h                     |   4 +-
 21 files changed, 308 insertions(+), 308 deletions(-)

--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:12 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:12 +0000
Subject: [PATCH v4 1/9] coresight: change coresight_device lock type to  raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-2-yeoreum.yun@arm.com>

coresight_device->cscfg_csdev_lock can be held during __schedule()
by perf_event_task_sched_out()/in().

Since coresight->cscfg_csdev_lock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type of coresight_device->cscfg_csdev_lock
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>
Reviewed-by: Mike Leach <mike.leach at linaro.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-syscfg.c    | 26 +++++++++----------
 include/linux/coresight.h                     |  2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 11138a9762b0..a70c1454b410 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -89,9 +89,9 @@ static int cscfg_add_csdev_cfg(struct coresight_device *csdev,
 	}
 	/* if matched features, add config to device.*/
 	if (config_csdev) {
-		spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+		raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 		list_add(&config_csdev->node, &csdev->config_csdev_list);
-		spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+		raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 	}
 
 	return 0;
@@ -194,9 +194,9 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev,
 
 	/* add to internal csdev feature list & initialise using reset call */
 	cscfg_reset_feat(feat_csdev);
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	list_add(&feat_csdev->node, &csdev->feature_csdev_list);
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	return 0;
 }
@@ -765,7 +765,7 @@ static int cscfg_list_add_csdev(struct coresight_device *csdev,
 
 	INIT_LIST_HEAD(&csdev->feature_csdev_list);
 	INIT_LIST_HEAD(&csdev->config_csdev_list);
-	spin_lock_init(&csdev->cscfg_csdev_lock);
+	raw_spin_lock_init(&csdev->cscfg_csdev_lock);
 
 	return 0;
 }
@@ -855,7 +855,7 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
 	struct cscfg_feature_csdev *feat_csdev;
 	unsigned long flags;
 
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	if (list_empty(&csdev->feature_csdev_list))
 		goto unlock_exit;
 
@@ -863,7 +863,7 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
 		cscfg_reset_feat(feat_csdev);
 
 unlock_exit:
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 }
 EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
 
@@ -1059,7 +1059,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 	 * Look for matching configuration - set the active configuration
 	 * context if found.
 	 */
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
 		config_desc = config_csdev_item->config_desc;
 		if ((atomic_read(&config_desc->active_cnt)) &&
@@ -1069,7 +1069,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 			break;
 		}
 	}
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	/*
 	 * If found, attempt to enable
@@ -1090,12 +1090,12 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 			 *
 			 * Set enabled if OK, err if not.
 			 */
-			spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+			raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 			if (csdev->active_cscfg_ctxt)
 				config_csdev_active->enabled = true;
 			else
 				err = -EBUSY;
-			spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+			raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 		}
 	}
 	return err;
@@ -1124,7 +1124,7 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
 	 * If it was not enabled, we have no work to do, otherwise mark as disabled.
 	 * Clear the active config pointer.
 	 */
-	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	config_csdev = (struct cscfg_config_csdev *)csdev->active_cscfg_ctxt;
 	if (config_csdev) {
 		if (!config_csdev->enabled)
@@ -1133,7 +1133,7 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
 			config_csdev->enabled = false;
 	}
 	csdev->active_cscfg_ctxt = NULL;
-	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	/* true if there was an enabled active config */
 	if (config_csdev)
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index c13342594278..924b58c343b3 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -296,7 +296,7 @@ struct coresight_device {
 	/* system configuration and feature lists */
 	struct list_head feature_csdev_list;
 	struct list_head config_csdev_list;
-	spinlock_t cscfg_csdev_lock;
+	raw_spinlock_t cscfg_csdev_lock;
 	void *active_cscfg_ctxt;
 };
 
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:13 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:13 +0000
Subject: [PATCH v4 1/1] coresight/ultrasoc: change smb_drv_data spinlock's type to raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-3-yeoreum.yun@arm.com>

In ultrasoc-smb drivers, smb_drv_data->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since smb__drv_data->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type smb_drv_data->spinlock in ultrasoc-smb drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/ultrasoc-smb.c | 12 ++++++------
 drivers/hwtracing/coresight/ultrasoc-smb.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index dc3c9504dd7c..26cfc939e5bd 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -98,7 +98,7 @@ static int smb_open(struct inode *inode, struct file *file)
 	struct smb_drv_data *drvdata = container_of(file->private_data,
 					struct smb_drv_data, miscdev);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	if (drvdata->reading)
 		return -EBUSY;
@@ -152,7 +152,7 @@ static int smb_release(struct inode *inode, struct file *file)
 	struct smb_drv_data *drvdata = container_of(file->private_data,
 					struct smb_drv_data, miscdev);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 	drvdata->reading = false;
 
 	return 0;
@@ -245,7 +245,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 	int ret = 0;
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	/* Do nothing, the trace data is reading by other interface now */
 	if (drvdata->reading)
@@ -280,7 +280,7 @@ static int smb_disable(struct coresight_device *csdev)
 {
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	if (drvdata->reading)
 		return -EBUSY;
@@ -378,7 +378,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev,
 	if (!buf)
 		return 0;
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	/* Don't do anything if another tracer is using this sink. */
 	if (csdev->refcnt != 1)
@@ -563,7 +563,7 @@ static int smb_probe(struct platform_device *pdev)
 
 	smb_reset_buffer(drvdata);
 	platform_set_drvdata(pdev, drvdata);
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	drvdata->pid = -1;
 
 	ret = smb_register_sink(pdev, drvdata);
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing/coresight/ultrasoc-smb.h
index a91d39cfccb8..c4c111275627 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.h
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.h
@@ -115,7 +115,7 @@ struct smb_drv_data {
 	struct coresight_device	*csdev;
 	struct smb_data_buffer sdb;
 	struct miscdevice miscdev;
-	spinlock_t spinlock;
+	raw_spinlock_t spinlock;
 	bool reading;
 	pid_t pid;
 };
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:14 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:14 +0000
Subject: [PATCH v4 2/9] coresight-etm4x: change etmv4_drvdata spinlock type to raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-4-yeoreum.yun@arm.com>

In coresight-etm4x drivers, etmv4_drvdata->spinlock can be held during
__schedule() by perf_event_task_sched_out()/in().

Since etmv4_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type etmv4_drvdata->spinlock
in coresight-etm4x drivers, which can be called
by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
Reviewed-by: James Clark <james.clark at linaro.org>
---
 .../hwtracing/coresight/coresight-config.c    |   8 +-
 .../hwtracing/coresight/coresight-config.h    |   2 +-
 .../coresight/coresight-etm4x-core.c          |  18 +-
 .../coresight/coresight-etm4x-sysfs.c         | 250 +++++++++---------
 drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
 5 files changed, 140 insertions(+), 140 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c
index 4723bf7402a2..4f72ae71b696 100644
--- a/drivers/hwtracing/coresight/coresight-config.c
+++ b/drivers/hwtracing/coresight/coresight-config.c
@@ -76,10 +76,10 @@ static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat_csdev)
 	unsigned long flags;
 	int i;
 
-	spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
+	raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
 	for (i = 0; i < feat_csdev->nr_regs; i++)
 		cscfg_set_reg(&feat_csdev->regs_csdev[i]);
-	spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+	raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
 	dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
 		feat_csdev->feat_desc->name, "set on enable");
 	return 0;
@@ -91,10 +91,10 @@ static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat_csdev)
 	unsigned long flags;
 	int i;
 
-	spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
+	raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
 	for (i = 0; i < feat_csdev->nr_regs; i++)
 		cscfg_save_reg(&feat_csdev->regs_csdev[i]);
-	spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+	raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
 	dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
 		feat_csdev->feat_desc->name, "save on disable");
 }
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 6ba013975741..b9ebc9fcfb7f 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -206,7 +206,7 @@ struct cscfg_feature_csdev {
 	const struct cscfg_feature_desc *feat_desc;
 	struct coresight_device *csdev;
 	struct list_head node;
-	spinlock_t *drv_spinlock;
+	raw_spinlock_t *drv_spinlock;
 	int nr_params;
 	struct cscfg_parameter_csdev *params_csdev;
 	int nr_regs;
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index dd8c74f893db..86893115df17 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -807,7 +807,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 			return ret;
 	}
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* sysfs needs to read and allocate a trace ID */
 	ret = etm4_read_alloc_trace_id(drvdata);
@@ -830,7 +830,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 		etm4_release_trace_id(drvdata);
 
 unlock_sysfs_enable:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	if (!ret)
 		dev_dbg(&csdev->dev, "ETM tracing enabled\n");
@@ -977,7 +977,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	 * DYING hotplug callback is serviced by the ETM driver.
 	 */
 	cpus_read_lock();
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/*
 	 * Executing etm4_disable_hw on the cpu whose ETM is being disabled
@@ -985,7 +985,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	 */
 	smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	cpus_read_unlock();
 
 	/*
@@ -1663,13 +1663,13 @@ static int etm4_starting_cpu(unsigned int cpu)
 	if (!etmdrvdata[cpu])
 		return 0;
 
-	spin_lock(&etmdrvdata[cpu]->spinlock);
+	raw_spin_lock(&etmdrvdata[cpu]->spinlock);
 	if (!etmdrvdata[cpu]->os_unlock)
 		etm4_os_unlock(etmdrvdata[cpu]);
 
 	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
 		etm4_enable_hw(etmdrvdata[cpu]);
-	spin_unlock(&etmdrvdata[cpu]->spinlock);
+	raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
 	return 0;
 }
 
@@ -1678,10 +1678,10 @@ static int etm4_dying_cpu(unsigned int cpu)
 	if (!etmdrvdata[cpu])
 		return 0;
 
-	spin_lock(&etmdrvdata[cpu]->spinlock);
+	raw_spin_lock(&etmdrvdata[cpu]->spinlock);
 	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
 		etm4_disable_hw(etmdrvdata[cpu]);
-	spin_unlock(&etmdrvdata[cpu]->spinlock);
+	raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
 	return 0;
 }
 
@@ -2125,7 +2125,7 @@ static int etm4_probe(struct device *dev)
 			return -ENOMEM;
 	}
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	drvdata->cpu = coresight_get_cpu(dev);
 	if (drvdata->cpu < 0)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a9f19629f3f8..11e865b8e824 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -174,7 +174,7 @@ static ssize_t reset_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (val)
 		config->mode = 0x0;
 
@@ -266,7 +266,7 @@ static ssize_t reset_store(struct device *dev,
 	config->vmid_mask0 = 0x0;
 	config->vmid_mask1 = 0x0;
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	/* for sysfs - only release trace id when resetting */
 	etm4_release_trace_id(drvdata);
@@ -300,7 +300,7 @@ static ssize_t mode_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->mode = val & ETMv4_MODE_ALL;
 
 	if (drvdata->instrp0 == true) {
@@ -437,7 +437,7 @@ static ssize_t mode_store(struct device *dev,
 	if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
 		etm4_config_trace_mode(config);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -466,14 +466,14 @@ static ssize_t pe_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (val > drvdata->nr_pe) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EINVAL;
 	}
 
 	config->pe_sel = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(pe);
@@ -501,7 +501,7 @@ static ssize_t event_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	switch (drvdata->nr_event) {
 	case 0x0:
 		/* EVENT0, bits[7:0] */
@@ -522,7 +522,7 @@ static ssize_t event_store(struct device *dev,
 	default:
 		break;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(event);
@@ -550,7 +550,7 @@ static ssize_t event_instren_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* start by clearing all instruction event enable bits */
 	config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;
 	switch (drvdata->nr_event) {
@@ -578,7 +578,7 @@ static ssize_t event_instren_store(struct device *dev,
 	default:
 		break;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(event_instren);
@@ -739,11 +739,11 @@ static ssize_t event_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val &= TRCVICTLR_EVENT_MASK >> __bf_shf(TRCVICTLR_EVENT_MASK);
 	config->vinst_ctrl &= ~TRCVICTLR_EVENT_MASK;
 	config->vinst_ctrl |= FIELD_PREP(TRCVICTLR_EVENT_MASK, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(event_vinst);
@@ -771,13 +771,13 @@ static ssize_t s_exlevel_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* clear all EXLEVEL_S bits  */
 	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;
 	/* enable instruction tracing for corresponding exception level */
 	val &= drvdata->s_ex_level;
 	config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_S_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(s_exlevel_vinst);
@@ -806,13 +806,13 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* clear EXLEVEL_NS bits  */
 	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;
 	/* enable instruction tracing for corresponding exception level */
 	val &= drvdata->ns_ex_level;
 	config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_NS_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ns_exlevel_vinst);
@@ -846,9 +846,9 @@ static ssize_t addr_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->addr_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_idx);
@@ -862,7 +862,7 @@ static ssize_t addr_instdatatype_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	val = FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]);
 	len = scnprintf(buf, PAGE_SIZE, "%s\n",
@@ -870,7 +870,7 @@ static ssize_t addr_instdatatype_show(struct device *dev,
 			(val == TRCACATRn_TYPE_DATA_LOAD_ADDR ? "data_load" :
 			(val == TRCACATRn_TYPE_DATA_STORE_ADDR ? "data_store" :
 			"data_load_store")));
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return len;
 }
 
@@ -888,13 +888,13 @@ static ssize_t addr_instdatatype_store(struct device *dev,
 	if (sscanf(buf, "%s", str) != 1)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!strcmp(str, "instr"))
 		/* TYPE, bits[1:0] */
 		config->addr_acc[idx] &= ~TRCACATRn_TYPE_MASK;
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_instdatatype);
@@ -909,14 +909,14 @@ static ssize_t addr_single_show(struct device *dev,
 	struct etmv4_config *config = &drvdata->config;
 
 	idx = config->addr_idx;
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 	val = (unsigned long)config->addr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -932,17 +932,17 @@ static ssize_t addr_single_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	config->addr_val[idx] = (u64)val;
 	config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_single);
@@ -956,23 +956,23 @@ static ssize_t addr_range_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 	if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
 	      (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	val1 = (unsigned long)config->addr_val[idx];
 	val2 = (unsigned long)config->addr_val[idx + 1];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
 }
 
@@ -995,10 +995,10 @@ static ssize_t addr_range_store(struct device *dev,
 	if (val1 > val2)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
@@ -1006,7 +1006,7 @@ static ssize_t addr_range_store(struct device *dev,
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
 	      (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
@@ -1023,7 +1023,7 @@ static ssize_t addr_range_store(struct device *dev,
 		exclude = config->mode & ETM_MODE_EXCLUDE;
 	etm4_set_mode_exclude(drvdata, exclude ? true : false);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_range);
@@ -1037,17 +1037,17 @@ static ssize_t addr_start_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	val = (unsigned long)config->addr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1063,22 +1063,22 @@ static ssize_t addr_start_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!drvdata->nr_addr_cmp) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EINVAL;
 	}
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	config->addr_val[idx] = (u64)val;
 	config->addr_type[idx] = ETM_ADDR_TYPE_START;
 	config->vissctlr |= BIT(idx);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_start);
@@ -1092,17 +1092,17 @@ static ssize_t addr_stop_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	val = (unsigned long)config->addr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1118,22 +1118,22 @@ static ssize_t addr_stop_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!drvdata->nr_addr_cmp) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EINVAL;
 	}
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	       config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
-		spin_unlock(&drvdata->spinlock);
+		raw_spin_unlock(&drvdata->spinlock);
 		return -EPERM;
 	}
 
 	config->addr_val[idx] = (u64)val;
 	config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
 	config->vissctlr |= BIT(idx + 16);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_stop);
@@ -1147,14 +1147,14 @@ static ssize_t addr_ctxtype_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* CONTEXTTYPE, bits[3:2] */
 	val = FIELD_GET(TRCACATRn_CONTEXTTYPE_MASK, config->addr_acc[idx]);
 	len = scnprintf(buf, PAGE_SIZE, "%s\n", val == ETM_CTX_NONE ? "none" :
 			(val == ETM_CTX_CTXID ? "ctxid" :
 			(val == ETM_CTX_VMID ? "vmid" : "all")));
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return len;
 }
 
@@ -1172,7 +1172,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
 	if (sscanf(buf, "%s", str) != 1)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!strcmp(str, "none"))
 		/* start by clearing context type bits */
@@ -1199,7 +1199,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
 		if (drvdata->numvmidc)
 			config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_ctxtype);
@@ -1213,11 +1213,11 @@ static ssize_t addr_context_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* context ID comparator bits[6:4] */
 	val = FIELD_GET(TRCACATRn_CONTEXT_MASK, config->addr_acc[idx]);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1238,12 +1238,12 @@ static ssize_t addr_context_store(struct device *dev,
 		     drvdata->numcidc : drvdata->numvmidc))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* clear context ID comparator bits[6:4] */
 	config->addr_acc[idx] &= ~TRCACATRn_CONTEXT_MASK;
 	config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_CONTEXT_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_context);
@@ -1257,10 +1257,10 @@ static ssize_t addr_exlevel_s_ns_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	val = FIELD_GET(TRCACATRn_EXLEVEL_MASK, config->addr_acc[idx]);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1279,12 +1279,12 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
 	if (val & ~(TRCACATRn_EXLEVEL_MASK >> __bf_shf(TRCACATRn_EXLEVEL_MASK)))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8], bit[15] is res0 */
 	config->addr_acc[idx] &= ~TRCACATRn_EXLEVEL_MASK;
 	config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_EXLEVEL_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(addr_exlevel_s_ns);
@@ -1307,7 +1307,7 @@ static ssize_t addr_cmp_view_show(struct device *dev,
 	int size = 0;
 	bool exclude = false;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	addr_v = config->addr_val[idx];
 	addr_ctrl = config->addr_acc[idx];
@@ -1322,7 +1322,7 @@ static ssize_t addr_cmp_view_show(struct device *dev,
 		}
 		exclude = config->viiectlr & BIT(idx / 2 + 16);
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	if (addr_type) {
 		size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] %s %#lx", idx,
 				 addr_type_names[addr_type], addr_v);
@@ -1366,9 +1366,9 @@ static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
 	if (!drvdata->nr_pe_cmp)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->vipcssctlr = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vinst_pe_cmp_start_stop);
@@ -1402,9 +1402,9 @@ static ssize_t seq_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->seq_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(seq_idx);
@@ -1448,10 +1448,10 @@ static ssize_t seq_event_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->seq_idx;
 	val = config->seq_ctrl[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1467,11 +1467,11 @@ static ssize_t seq_event_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->seq_idx;
 	/* Seq control has two masks B[15:8] F[7:0] */
 	config->seq_ctrl[idx] = val & 0xFFFF;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(seq_event);
@@ -1535,9 +1535,9 @@ static ssize_t cntr_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->cntr_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntr_idx);
@@ -1551,10 +1551,10 @@ static ssize_t cntrldvr_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	val = config->cntrldvr[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1572,10 +1572,10 @@ static ssize_t cntrldvr_store(struct device *dev,
 	if (val > ETM_CNTR_MAX_VAL)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntrldvr[idx] = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntrldvr);
@@ -1589,10 +1589,10 @@ static ssize_t cntr_val_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	val = config->cntr_val[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1610,10 +1610,10 @@ static ssize_t cntr_val_store(struct device *dev,
 	if (val > ETM_CNTR_MAX_VAL)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntr_val[idx] = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntr_val);
@@ -1627,10 +1627,10 @@ static ssize_t cntr_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	val = config->cntr_ctrl[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1646,10 +1646,10 @@ static ssize_t cntr_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntr_ctrl[idx] = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(cntr_ctrl);
@@ -1687,9 +1687,9 @@ static ssize_t res_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->res_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(res_idx);
@@ -1703,10 +1703,10 @@ static ssize_t res_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->res_idx;
 	val = config->res_ctrl[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1722,7 +1722,7 @@ static ssize_t res_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->res_idx;
 	/* For odd idx pair inversal bit is RES0 */
 	if (idx % 2 != 0)
@@ -1732,7 +1732,7 @@ static ssize_t res_ctrl_store(struct device *dev,
 				       TRCRSCTLRn_INV |
 				       TRCRSCTLRn_GROUP_MASK |
 				       TRCRSCTLRn_SELECT_MASK);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(res_ctrl);
@@ -1761,9 +1761,9 @@ static ssize_t sshot_idx_store(struct device *dev,
 	if (val >= drvdata->nr_ss_cmp)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->ss_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(sshot_idx);
@@ -1776,9 +1776,9 @@ static ssize_t sshot_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = config->ss_ctrl[config->ss_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1794,12 +1794,12 @@ static ssize_t sshot_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ss_idx;
 	config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
 	/* must clear bit 31 in related status register on programming */
 	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(sshot_ctrl);
@@ -1811,9 +1811,9 @@ static ssize_t sshot_status_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = config->ss_status[config->ss_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 static DEVICE_ATTR_RO(sshot_status);
@@ -1826,9 +1826,9 @@ static ssize_t sshot_pe_ctrl_show(struct device *dev,
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct etmv4_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = config->ss_pe_cmp[config->ss_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1844,12 +1844,12 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ss_idx;
 	config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
 	/* must clear bit 31 in related status register on programming */
 	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(sshot_pe_ctrl);
@@ -1883,9 +1883,9 @@ static ssize_t ctxid_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->ctxid_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_idx);
@@ -1906,10 +1906,10 @@ static ssize_t ctxid_pid_show(struct device *dev,
 	if (task_active_pid_ns(current) != &init_pid_ns)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ctxid_idx;
 	val = (unsigned long)config->ctxid_pid[idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1944,10 +1944,10 @@ static ssize_t ctxid_pid_store(struct device *dev,
 	if (kstrtoul(buf, 16, &pid))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ctxid_idx;
 	config->ctxid_pid[idx] = (u64)pid;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_pid);
@@ -1967,10 +1967,10 @@ static ssize_t ctxid_masks_show(struct device *dev,
 	if (task_active_pid_ns(current) != &init_pid_ns)
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val1 = config->ctxid_mask0;
 	val2 = config->ctxid_mask1;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
 }
 
@@ -2003,7 +2003,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
 	if ((drvdata->numcidc > 4) && (nr_inputs != 2))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/*
 	 * each byte[0..3] controls mask value applied to ctxid
 	 * comparator[0..3]
@@ -2075,7 +2075,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
 			mask >>= 0x8;
 	}
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_masks);
@@ -2109,9 +2109,9 @@ static ssize_t vmid_idx_store(struct device *dev,
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
 	 */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->vmid_idx = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vmid_idx);
@@ -2131,9 +2131,9 @@ static ssize_t vmid_val_show(struct device *dev,
 	if (!task_is_in_init_pid_ns(current))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = (unsigned long)config->vmid_val[config->vmid_idx];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -2161,9 +2161,9 @@ static ssize_t vmid_val_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->vmid_val[config->vmid_idx] = (u64)val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vmid_val);
@@ -2182,10 +2182,10 @@ static ssize_t vmid_masks_show(struct device *dev,
 	if (!task_is_in_init_pid_ns(current))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val1 = config->vmid_mask0;
 	val2 = config->vmid_mask1;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
 }
 
@@ -2217,7 +2217,7 @@ static ssize_t vmid_masks_store(struct device *dev,
 	if ((drvdata->numvmidc > 4) && (nr_inputs != 2))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/*
 	 * each byte[0..3] controls mask value applied to vmid
@@ -2290,7 +2290,7 @@ static ssize_t vmid_masks_store(struct device *dev,
 		else
 			mask >>= 0x8;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(vmid_masks);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 9e9165f62e81..366f8f23a3e5 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -989,7 +989,7 @@ struct etmv4_drvdata {
 	struct clk			*pclk;
 	void __iomem			*base;
 	struct coresight_device		*csdev;
-	spinlock_t			spinlock;
+	raw_spinlock_t			spinlock;
 	int				cpu;
 	u8				arch;
 	u8				nr_pe;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:15 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:15 +0000
Subject: [PATCH v4 3/9] coresight: change coresight_trace_id_map's lock type to  raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-5-yeoreum.yun@arm.com>

coresight_trace_id_map->lock can be acquired while coresight devices'
drvdata_lock.

But the drvdata_lock can be raw_spinlock_t (i.e) coresight-etm4x.

To address this, change type of coresight_trace_id_map->lock to
raw_spinlock_t

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
Reviewed-by: James Clark <james.clark at linaro.org>
Reviewed-by: Mike Leach <mike.leach at linaro.org>
---
 drivers/hwtracing/coresight/coresight-core.c  |  2 +-
 .../hwtracing/coresight/coresight-trace-id.c  | 22 +++++++++----------
 include/linux/coresight.h                     |  2 +-
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index ea38ecf26fcb..cc2d87b2f248 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1164,7 +1164,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
 
 	if (csdev->type == CORESIGHT_DEV_TYPE_SINK ||
 	    csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) {
-		spin_lock_init(&csdev->perf_sink_id_map.lock);
+		raw_spin_lock_init(&csdev->perf_sink_id_map.lock);
 		csdev->perf_sink_id_map.cpu_map = alloc_percpu(atomic_t);
 		if (!csdev->perf_sink_id_map.cpu_map) {
 			kfree(csdev);
diff --git a/drivers/hwtracing/coresight/coresight-trace-id.c b/drivers/hwtracing/coresight/coresight-trace-id.c
index d98e12cb30ec..a6531869e9ec 100644
--- a/drivers/hwtracing/coresight/coresight-trace-id.c
+++ b/drivers/hwtracing/coresight/coresight-trace-id.c
@@ -16,7 +16,7 @@
 static DEFINE_PER_CPU(atomic_t, id_map_default_cpu_ids) = ATOMIC_INIT(0);
 static struct coresight_trace_id_map id_map_default = {
 	.cpu_map = &id_map_default_cpu_ids,
-	.lock = __SPIN_LOCK_UNLOCKED(id_map_default.lock)
+	.lock = __RAW_SPIN_LOCK_UNLOCKED(id_map_default.lock)
 };
 
 /* #define TRACE_ID_DEBUG 1 */
@@ -121,11 +121,11 @@ static void coresight_trace_id_release_all(struct coresight_trace_id_map *id_map
 	unsigned long flags;
 	int cpu;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 	bitmap_zero(id_map->used_ids, CORESIGHT_TRACE_IDS_MAX);
 	for_each_possible_cpu(cpu)
 		atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), 0);
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 	DUMP_ID_MAP(id_map);
 }
 
@@ -134,7 +134,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map
 	unsigned long flags;
 	int id;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 
 	/* check for existing allocation for this CPU */
 	id = _coresight_trace_id_read_cpu_id(cpu, id_map);
@@ -161,7 +161,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map
 	atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), id);
 
 get_cpu_id_out_unlock:
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 
 	DUMP_ID_CPU(cpu, id);
 	DUMP_ID_MAP(id_map);
@@ -178,12 +178,12 @@ static void _coresight_trace_id_put_cpu_id(int cpu, struct coresight_trace_id_ma
 	if (!id)
 		return;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 
 	coresight_trace_id_free(id, id_map);
 	atomic_set(per_cpu_ptr(id_map->cpu_map, cpu), 0);
 
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 	DUMP_ID_CPU(cpu, id);
 	DUMP_ID_MAP(id_map);
 }
@@ -193,10 +193,10 @@ static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *i
 	unsigned long flags;
 	int id;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 	/* prefer odd IDs for system components to avoid legacy CPU IDS */
 	id = coresight_trace_id_alloc_new_id(id_map, 0, true);
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 
 	DUMP_ID(id);
 	DUMP_ID_MAP(id_map);
@@ -207,9 +207,9 @@ static void coresight_trace_id_map_put_system_id(struct coresight_trace_id_map *
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&id_map->lock, flags);
+	raw_spin_lock_irqsave(&id_map->lock, flags);
 	coresight_trace_id_free(id, id_map);
-	spin_unlock_irqrestore(&id_map->lock, flags);
+	raw_spin_unlock_irqrestore(&id_map->lock, flags);
 
 	DUMP_ID(id);
 	DUMP_ID_MAP(id_map);
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 924b58c343b3..6446ca1f09d8 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -233,7 +233,7 @@ struct coresight_trace_id_map {
 	DECLARE_BITMAP(used_ids, CORESIGHT_TRACE_IDS_MAX);
 	atomic_t __percpu *cpu_map;
 	atomic_t perf_cs_etm_session_active;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 };
 
 /**
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:16 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:16 +0000
Subject: [PATCH v4 4/9] coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-6-yeoreum.yun@arm.com>

In coresight-cti drivers, cti_drvdata->spinlock can be held during __schedule()
by perf_event_task_sched_out()/in().

Since cti_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type cti_drvdata->spinlock in coresight-cti drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>
Reviewed-by: Mike Leach <mike.leach at linaro.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-cti-core.c  | 44 +++++------
 .../hwtracing/coresight/coresight-cti-sysfs.c | 76 +++++++++----------
 drivers/hwtracing/coresight/coresight-cti.h   |  2 +-
 3 files changed, 61 insertions(+), 61 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
index d2b5a5718c29..80f6265e3740 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -93,7 +93,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
 	unsigned long flags;
 	int rc = 0;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* no need to do anything if enabled or unpowered*/
 	if (config->hw_enabled || !config->hw_powered)
@@ -108,7 +108,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
 
 	config->hw_enabled = true;
 	drvdata->config.enable_req_count++;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return rc;
 
 cti_state_unchanged:
@@ -116,7 +116,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata)
 
 	/* cannot enable due to error */
 cti_err_not_enabled:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return rc;
 }
 
@@ -125,7 +125,7 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata)
 {
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	config->hw_powered = true;
 
 	/* no need to do anything if no enable request */
@@ -138,12 +138,12 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata)
 
 	cti_write_all_hw_regs(drvdata);
 	config->hw_enabled = true;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return;
 
 	/* did not re-enable due to no claim / no request */
 cti_hp_not_enabled:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 }
 
 /* disable hardware */
@@ -153,7 +153,7 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
 	struct coresight_device *csdev = drvdata->csdev;
 	int ret = 0;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* don't allow negative refcounts, return an error */
 	if (!drvdata->config.enable_req_count) {
@@ -177,12 +177,12 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
 
 	coresight_disclaim_device_unlocked(csdev);
 	CS_LOCK(drvdata->base);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return ret;
 
 	/* not disabled this call */
 cti_not_disabled:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return ret;
 }
 
@@ -198,11 +198,11 @@ void cti_write_intack(struct device *dev, u32 ackval)
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* write if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIINTACK, ackval);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 }
 
 /*
@@ -369,7 +369,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 	reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) :
 		      CTIOUTEN(trigger_idx));
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* read - modify write - the trigger / channel enable value */
 	reg_value = direction == CTI_TRIG_IN ? config->ctiinen[trigger_idx] :
@@ -388,7 +388,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, reg_offset, reg_value);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return 0;
 }
 
@@ -406,7 +406,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
 
 	chan_bitmask = BIT(channel_idx);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	reg_value = config->ctigate;
 	switch (op) {
 	case CTI_GATE_CHAN_ENABLE:
@@ -426,7 +426,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
 		if (cti_active(config))
 			cti_write_single_reg(drvdata, CTIGATE, reg_value);
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return err;
 }
 
@@ -445,7 +445,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
 
 	chan_bitmask = BIT(channel_idx);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	reg_value = config->ctiappset;
 	switch (op) {
 	case CTI_CHAN_SET:
@@ -473,7 +473,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
 
 	if ((err == 0) && cti_active(config))
 		cti_write_single_reg(drvdata, reg_offset, reg_value);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return err;
 }
@@ -676,7 +676,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
 	if (WARN_ON_ONCE(drvdata->ctidev.cpu != cpu))
 		return NOTIFY_BAD;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	switch (cmd) {
 	case CPU_PM_ENTER:
@@ -716,7 +716,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
 	}
 
 cti_notify_exit:
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return notify_res;
 }
 
@@ -743,11 +743,11 @@ static int cti_dying_cpu(unsigned int cpu)
 	if (!drvdata)
 		return 0;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.hw_powered = false;
 	if (drvdata->config.hw_enabled)
 		coresight_disclaim_device(drvdata->csdev);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return 0;
 }
 
@@ -888,7 +888,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 	drvdata->ctidev.ctm_id = 0;
 	INIT_LIST_HEAD(&drvdata->ctidev.trig_cons);
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	/* initialise CTI driver config values */
 	cti_set_default_config(dev, drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
index d25dd2737b49..572b80ee96fb 100644
--- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c
@@ -84,11 +84,11 @@ static ssize_t enable_show(struct device *dev,
 	bool enabled, powered;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	enable_req = drvdata->config.enable_req_count;
 	powered = drvdata->config.hw_powered;
 	enabled = drvdata->config.hw_enabled;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	if (powered)
 		return sprintf(buf, "%d\n", enabled);
@@ -134,9 +134,9 @@ static ssize_t powered_show(struct device *dev,
 	bool powered;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	powered = drvdata->config.hw_powered;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return sprintf(buf, "%d\n", powered);
 }
@@ -181,10 +181,10 @@ static ssize_t coresight_cti_reg_show(struct device *dev,
 	u32 val = 0;
 
 	pm_runtime_get_sync(dev->parent);
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (drvdata->config.hw_powered)
 		val = readl_relaxed(drvdata->base + cti_attr->off);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	pm_runtime_put_sync(dev->parent);
 	return sysfs_emit(buf, "0x%x\n", val);
 }
@@ -202,10 +202,10 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev,
 		return -EINVAL;
 
 	pm_runtime_get_sync(dev->parent);
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if (drvdata->config.hw_powered)
 		cti_write_single_reg(drvdata, cti_attr->off, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	pm_runtime_put_sync(dev->parent);
 	return size;
 }
@@ -264,7 +264,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf,
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	if ((reg_offset >= 0) && cti_active(config)) {
 		CS_UNLOCK(drvdata->base);
 		val = readl_relaxed(drvdata->base + reg_offset);
@@ -274,7 +274,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf,
 	} else if (pcached_val) {
 		val = *pcached_val;
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%#x\n", val);
 }
 
@@ -293,7 +293,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	/* local store */
 	if (pcached_val)
 		*pcached_val = (u32)val;
@@ -301,7 +301,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf,
 	/* write through if offset and enabled */
 	if ((reg_offset >= 0) && cti_active(config))
 		cti_write_single_reg(drvdata, reg_offset, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 
@@ -349,9 +349,9 @@ static ssize_t inout_sel_store(struct device *dev,
 	if (val > (CTIINOUTEN_MAX - 1))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.ctiinout_sel = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(inout_sel);
@@ -364,10 +364,10 @@ static ssize_t inen_show(struct device *dev,
 	int index;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = drvdata->config.ctiinout_sel;
 	val = drvdata->config.ctiinen[index];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%#lx\n", val);
 }
 
@@ -383,14 +383,14 @@ static ssize_t inen_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = config->ctiinout_sel;
 	config->ctiinen[index] = val;
 
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIINEN(index), val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(inen);
@@ -403,10 +403,10 @@ static ssize_t outen_show(struct device *dev,
 	int index;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = drvdata->config.ctiinout_sel;
 	val = drvdata->config.ctiouten[index];
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%#lx\n", val);
 }
 
@@ -422,14 +422,14 @@ static ssize_t outen_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	index = config->ctiinout_sel;
 	config->ctiouten[index] = val;
 
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIOUTEN(index), val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(outen);
@@ -463,7 +463,7 @@ static ssize_t appclear_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* a 1'b1 in appclr clears down the same bit in appset*/
 	config->ctiappset &= ~val;
@@ -471,7 +471,7 @@ static ssize_t appclear_store(struct device *dev,
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(appclear);
@@ -487,12 +487,12 @@ static ssize_t apppulse_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* write through if enabled */
 	if (cti_active(config))
 		cti_write_single_reg(drvdata, CTIAPPPULSE, val);
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(apppulse);
@@ -681,9 +681,9 @@ static ssize_t trig_filter_enable_show(struct device *dev,
 	u32 val;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = drvdata->config.trig_filter_enable;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return sprintf(buf, "%d\n", val);
 }
 
@@ -697,9 +697,9 @@ static ssize_t trig_filter_enable_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.trig_filter_enable = !!val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_RW(trig_filter_enable);
@@ -728,7 +728,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev,
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 
 	/* clear the CTI trigger / channel programming registers */
 	for (i = 0; i < config->nr_trig_max; i++) {
@@ -747,7 +747,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev,
 	if (cti_active(config))
 		cti_write_all_hw_regs(drvdata);
 
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(chan_xtrigs_reset);
@@ -768,9 +768,9 @@ static ssize_t chan_xtrigs_sel_store(struct device *dev,
 	if (val > (drvdata->config.nr_ctm_channels - 1))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	drvdata->config.xtrig_rchan_sel = val;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 	return size;
 }
 
@@ -781,9 +781,9 @@ static ssize_t chan_xtrigs_sel_show(struct device *dev,
 	unsigned long val;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	val = drvdata->config.xtrig_rchan_sel;
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	return sprintf(buf, "%ld\n", val);
 }
@@ -838,12 +838,12 @@ static ssize_t print_chan_list(struct device *dev,
 	unsigned long inuse_bits = 0, chan_mask;
 
 	/* scan regs to get bitmap of channels in use. */
-	spin_lock(&drvdata->spinlock);
+	raw_spin_lock(&drvdata->spinlock);
 	for (i = 0; i < config->nr_trig_max; i++) {
 		inuse_bits |= config->ctiinen[i];
 		inuse_bits |= config->ctiouten[i];
 	}
-	spin_unlock(&drvdata->spinlock);
+	raw_spin_unlock(&drvdata->spinlock);
 
 	/* inverse bits if printing free channels */
 	if (!inuse)
diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h
index cb9ee616d01f..16e310e7e9d4 100644
--- a/drivers/hwtracing/coresight/coresight-cti.h
+++ b/drivers/hwtracing/coresight/coresight-cti.h
@@ -175,7 +175,7 @@ struct cti_drvdata {
 	void __iomem *base;
 	struct coresight_device	*csdev;
 	struct cti_device ctidev;
-	spinlock_t spinlock;
+	raw_spinlock_t spinlock;
 	struct cti_config config;
 	struct list_head node;
 	void (*csdev_release)(struct device *dev);
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:17 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:17 +0000
Subject: [PATCH v4 5/9] coresight-etb10: change etb_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-7-yeoreum.yun@arm.com>

In coresight-etb10 drivers, etb_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since etb_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type etb_drvdata->spinlock in coresight-etb10 drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>
Reviewed-by: Mike Leach <mike.leach at linaro.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-etb10.c | 26 +++++++++----------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index aea9ac9c4bd0..7948597d483d 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -84,7 +84,7 @@ struct etb_drvdata {
 	struct clk		*atclk;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 	local_t			reading;
 	pid_t			pid;
 	u8			*buf;
@@ -145,7 +145,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
 	unsigned long flags;
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't messup with perf sessions. */
 	if (coresight_get_mode(csdev) == CS_MODE_PERF) {
@@ -163,7 +163,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
 
 	csdev->refcnt++;
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return ret;
 }
 
@@ -176,7 +176,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
 	struct perf_output_handle *handle = data;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* No need to continue if the component is already in used by sysFS. */
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
@@ -219,7 +219,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
 	}
 
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return ret;
 }
 
@@ -352,11 +352,11 @@ static int etb_disable(struct coresight_device *csdev)
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	unsigned long flags;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	csdev->refcnt--;
 	if (csdev->refcnt) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -366,7 +366,7 @@ static int etb_disable(struct coresight_device *csdev)
 	/* Dissociate from monitored process. */
 	drvdata->pid = -1;
 	coresight_set_mode(csdev, CS_MODE_DISABLED);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&csdev->dev, "ETB disabled\n");
 	return 0;
@@ -443,7 +443,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
 
 	capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't do anything if another tracer is using this sink */
 	if (csdev->refcnt != 1)
@@ -566,7 +566,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
 	__etb_enable_hw(drvdata);
 	CS_LOCK(drvdata->base);
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return to_read;
 }
@@ -587,13 +587,13 @@ static void etb_dump(struct etb_drvdata *drvdata)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
 		__etb_disable_hw(drvdata);
 		etb_dump_hw(drvdata);
 		__etb_enable_hw(drvdata);
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&drvdata->csdev->dev, "ETB dumped\n");
 }
@@ -746,7 +746,7 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
 	drvdata->base = base;
 	desc.access = CSDEV_ACCESS_IOMEM(base);
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	drvdata->buffer_depth = etb_get_buffer_depth(drvdata);
 
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:18 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:18 +0000
Subject: [PATCH v4 6/9] coresight-funnel: change funnel_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-8-yeoreum.yun@arm.com>

In coresight-funnel drivers, cti_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since funnel_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type funnel_drvdata->spinlock in
coresight-funnel drivers, which can be called by
perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>
Reviewed-by: Mike Leach <mike.leach at linaro.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-funnel.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 33efe1acbef7..a566c8854327 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -47,7 +47,7 @@ struct funnel_drvdata {
 	struct clk		*pclk;
 	struct coresight_device	*csdev;
 	unsigned long		priority;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 };
 
 static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port)
@@ -85,7 +85,7 @@ static int funnel_enable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool first_enable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_read(&in->dest_refcnt) == 0) {
 		if (drvdata->base)
 			rc = dynamic_funnel_enable_hw(drvdata, in->dest_port);
@@ -94,7 +94,7 @@ static int funnel_enable(struct coresight_device *csdev,
 	}
 	if (!rc)
 		atomic_inc(&in->dest_refcnt);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (first_enable)
 		dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n",
@@ -129,13 +129,13 @@ static void funnel_disable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool last_disable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_dec_return(&in->dest_refcnt) == 0) {
 		if (drvdata->base)
 			dynamic_funnel_disable_hw(drvdata, in->dest_port);
 		last_disable = true;
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (last_disable)
 		dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n",
@@ -266,7 +266,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
 	}
 	dev->platform_data = pdata;
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	desc.type = CORESIGHT_DEV_TYPE_LINK;
 	desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG;
 	desc.ops = &funnel_cs_ops;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:19 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:19 +0000
Subject: [PATCH v4 7/9] coresight-replicator: change replicator_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-9-yeoreum.yun@arm.com>

In coresight-replicator drivers, replicator_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since replicator_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type replicator_drvdata->spinlock in
coresight-replicator drivers, which can be called
by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>
Reviewed-by: Mike Leach <mike.leach at linaro.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/coresight-replicator.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 0fba87de6d1a..7d36fe2176cc 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -41,7 +41,7 @@ struct replicator_drvdata {
 	struct clk		*atclk;
 	struct clk		*pclk;
 	struct coresight_device	*csdev;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 	bool			check_idfilter_val;
 };
 
@@ -125,7 +125,7 @@ static int replicator_enable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool first_enable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_read(&out->src_refcnt) == 0) {
 		if (drvdata->base)
 			rc = dynamic_replicator_enable(drvdata, in->dest_port,
@@ -135,7 +135,7 @@ static int replicator_enable(struct coresight_device *csdev,
 	}
 	if (!rc)
 		atomic_inc(&out->src_refcnt);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (first_enable)
 		dev_dbg(&csdev->dev, "REPLICATOR enabled\n");
@@ -179,14 +179,14 @@ static void replicator_disable(struct coresight_device *csdev,
 	unsigned long flags;
 	bool last_disable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (atomic_dec_return(&out->src_refcnt) == 0) {
 		if (drvdata->base)
 			dynamic_replicator_disable(drvdata, in->dest_port,
 						   out->src_port);
 		last_disable = true;
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (last_disable)
 		dev_dbg(&csdev->dev, "REPLICATOR disabled\n");
@@ -277,7 +277,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
 	}
 	dev->platform_data = pdata;
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	desc.type = CORESIGHT_DEV_TYPE_LINK;
 	desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT;
 	desc.ops = &replicator_cs_ops;
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:20 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:20 +0000
Subject: [PATCH v4 8/9] coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-10-yeoreum.yun@arm.com>

In coresight-tmc drivers, tmc_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since tmc_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type tmc_drvdata->spinlock in coresight-tmc drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>
Reviewed-by: Mike Leach <mike.leach at linaro.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../hwtracing/coresight/coresight-tmc-core.c  |  6 +--
 .../hwtracing/coresight/coresight-tmc-etf.c   | 48 +++++++++----------
 .../hwtracing/coresight/coresight-tmc-etr.c   | 40 ++++++++--------
 drivers/hwtracing/coresight/coresight-tmc.h   |  2 +-
 4 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index e9876252a789..4e9925300931 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -492,7 +492,7 @@ static int __tmc_probe(struct device *dev, struct resource *res)
 	drvdata->base = base;
 	desc.access = CSDEV_ACCESS_IOMEM(base);
 
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 
 	devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
 	drvdata->config_type = BMVAL(devid, 6, 7);
@@ -596,7 +596,7 @@ static void tmc_shutdown(struct amba_device *adev)
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = amba_get_drvdata(adev);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_DISABLED)
 		goto out;
@@ -610,7 +610,7 @@ static void tmc_shutdown(struct amba_device *adev)
 	 * the system is going down after this.
 	 */
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 }
 
 static void __tmc_remove(struct device *dev)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index d4f641cd9de6..fca8e9ffb3cf 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -182,9 +182,9 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 	 * If we don't have a buffer release the lock and allocate memory.
 	 * Otherwise keep the lock and move along.
 	 */
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (!drvdata->buf) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 		/* Allocating the memory here while outside of the spinlock */
 		buf = kzalloc(drvdata->size, GFP_KERNEL);
@@ -192,7 +192,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 			return -ENOMEM;
 
 		/* Let's try again */
-		spin_lock_irqsave(&drvdata->spinlock, flags);
+		raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	}
 
 	if (drvdata->reading) {
@@ -235,7 +235,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 		used = false;
 	}
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/* Free memory outside the spinlock if need be */
 	if (!used)
@@ -253,7 +253,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
 	struct perf_output_handle *handle = data;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	do {
 		ret = -EINVAL;
 		if (drvdata->reading)
@@ -296,7 +296,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
 			csdev->refcnt++;
 		}
 	} while (0);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -331,16 +331,16 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
 	csdev->refcnt--;
 	if (csdev->refcnt) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -351,7 +351,7 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
 	drvdata->pid = -1;
 	coresight_set_mode(csdev, CS_MODE_DISABLED);
 
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n");
 	return 0;
@@ -366,9 +366,9 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	bool first_enable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -381,7 +381,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
 	}
 	if (!ret)
 		csdev->refcnt++;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (first_enable)
 		dev_dbg(&csdev->dev, "TMC-ETF enabled\n");
@@ -396,9 +396,9 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	bool last_disable = false;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return;
 	}
 
@@ -408,7 +408,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
 		coresight_set_mode(csdev, CS_MODE_DISABLED);
 		last_disable = true;
 	}
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (last_disable)
 		dev_dbg(&csdev->dev, "TMC-ETF disabled\n");
@@ -488,7 +488,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
 	if (WARN_ON_ONCE(coresight_get_mode(csdev) != CS_MODE_PERF))
 		return 0;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't do anything if another tracer is using this sink */
 	if (csdev->refcnt != 1)
@@ -585,7 +585,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
 	 */
 	CS_LOCK(drvdata->base);
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return to_read;
 }
@@ -623,7 +623,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
 			 drvdata->config_type != TMC_CONFIG_TYPE_ETF))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (drvdata->reading) {
 		ret = -EBUSY;
@@ -655,7 +655,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
 
 	drvdata->reading = true;
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -672,14 +672,14 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
 			 drvdata->config_type != TMC_CONFIG_TYPE_ETF))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Re-enable the TMC if need be */
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
 		/* There is no point in reading a TMC in HW FIFO mode */
 		mode = readl_relaxed(drvdata->base + TMC_MODE);
 		if (mode != TMC_MODE_CIRCULAR_BUFFER) {
-			spin_unlock_irqrestore(&drvdata->spinlock, flags);
+			raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 			return -EINVAL;
 		}
 		/*
@@ -693,7 +693,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
 		memset(drvdata->buf, 0, drvdata->size);
 		rc = __tmc_etb_enable_hw(drvdata);
 		if (rc) {
-			spin_unlock_irqrestore(&drvdata->spinlock, flags);
+			raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 			return rc;
 		}
 	} else {
@@ -706,7 +706,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
 	}
 
 	drvdata->reading = false;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/*
 	 * Free allocated memory outside of the spinlock.  There is no need
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..a0a90ce7333e 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1176,10 +1176,10 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 	 * buffer, provided the size matches. Any allocation has to be done
 	 * with the lock released.
 	 */
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	sysfs_buf = READ_ONCE(drvdata->sysfs_buf);
 	if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 		/* Allocate memory with the locks released */
 		free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata);
@@ -1187,7 +1187,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 			return new_buf;
 
 		/* Let's try again */
-		spin_lock_irqsave(&drvdata->spinlock, flags);
+		raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	}
 
 	if (drvdata->reading || coresight_get_mode(csdev) == CS_MODE_PERF) {
@@ -1206,7 +1206,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
 	}
 
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/* Free memory outside the spinlock if need be */
 	if (free_buf)
@@ -1224,7 +1224,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 	if (IS_ERR(sysfs_buf))
 		return PTR_ERR(sysfs_buf);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/*
 	 * In sysFS mode we can have multiple writers per sink.  Since this
@@ -1243,7 +1243,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 	}
 
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	if (!ret)
 		dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
@@ -1562,17 +1562,17 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
 	struct etr_perf_buffer *etr_perf = config;
 	struct etr_buf *etr_buf = etr_perf->etr_buf;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* Don't do anything if another tracer is using this sink */
 	if (csdev->refcnt != 1) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		goto out;
 	}
 
 	if (WARN_ON(drvdata->perf_buf != etr_buf)) {
 		lost = true;
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		goto out;
 	}
 
@@ -1582,7 +1582,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
 	tmc_sync_etr_buf(drvdata);
 
 	CS_LOCK(drvdata->base);
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	lost = etr_buf->full;
 	offset = etr_buf->offset;
@@ -1651,7 +1651,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 	struct perf_output_handle *handle = data;
 	struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	 /* Don't use this sink if it is already claimed by sysFS */
 	if (coresight_get_mode(csdev) == CS_MODE_SYSFS) {
 		rc = -EBUSY;
@@ -1691,7 +1691,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 	}
 
 unlock_out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 	return rc;
 }
 
@@ -1713,16 +1713,16 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	if (drvdata->reading) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
 	csdev->refcnt--;
 	if (csdev->refcnt) {
-		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
@@ -1735,7 +1735,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
 	/* Reset perf specific data */
 	drvdata->perf_buf = NULL;
 
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	dev_dbg(&csdev->dev, "TMC-ETR disabled\n");
 	return 0;
@@ -1762,7 +1762,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
 		ret = -EBUSY;
 		goto out;
@@ -1784,7 +1784,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
 
 	drvdata->reading = true;
 out:
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -1798,7 +1798,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
 		return -EINVAL;
 
-	spin_lock_irqsave(&drvdata->spinlock, flags);
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* RE-enable the TMC if need be */
 	if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
@@ -1818,7 +1818,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
 	}
 
 	drvdata->reading = false;
-	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	/* Free allocated memory out side of the spinlock */
 	if (sysfs_buf)
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 2671926be62a..60b395025bc4 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -195,7 +195,7 @@ struct tmc_drvdata {
 	void __iomem		*base;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
-	spinlock_t		spinlock;
+	raw_spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
 	union {
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Fri Dec 20 02:45:21 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 10:45:21 +0000
Subject: [PATCH v4 9/9] coresight/ultrasoc: change smb_drv_data spinlock's type to raw_spinlock_t
In-Reply-To: <20241220104521.809071-1-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
Message-ID: <20241220104521.809071-11-yeoreum.yun@arm.com>

In ultrasoc-smb drivers, smb_drv_data->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since smb__drv_data->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type smb_drv_data->spinlock in ultrasoc-smb drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/ultrasoc-smb.c | 12 ++++++------
 drivers/hwtracing/coresight/ultrasoc-smb.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index dc3c9504dd7c..26cfc939e5bd 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -98,7 +98,7 @@ static int smb_open(struct inode *inode, struct file *file)
 	struct smb_drv_data *drvdata = container_of(file->private_data,
 					struct smb_drv_data, miscdev);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	if (drvdata->reading)
 		return -EBUSY;
@@ -152,7 +152,7 @@ static int smb_release(struct inode *inode, struct file *file)
 	struct smb_drv_data *drvdata = container_of(file->private_data,
 					struct smb_drv_data, miscdev);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 	drvdata->reading = false;
 
 	return 0;
@@ -245,7 +245,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 	int ret = 0;
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	/* Do nothing, the trace data is reading by other interface now */
 	if (drvdata->reading)
@@ -280,7 +280,7 @@ static int smb_disable(struct coresight_device *csdev)
 {
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	if (drvdata->reading)
 		return -EBUSY;
@@ -378,7 +378,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev,
 	if (!buf)
 		return 0;
 
-	guard(spinlock)(&drvdata->spinlock);
+	guard(raw_spinlock)(&drvdata->spinlock);
 
 	/* Don't do anything if another tracer is using this sink. */
 	if (csdev->refcnt != 1)
@@ -563,7 +563,7 @@ static int smb_probe(struct platform_device *pdev)
 
 	smb_reset_buffer(drvdata);
 	platform_set_drvdata(pdev, drvdata);
-	spin_lock_init(&drvdata->spinlock);
+	raw_spin_lock_init(&drvdata->spinlock);
 	drvdata->pid = -1;
 
 	ret = smb_register_sink(pdev, drvdata);
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing/coresight/ultrasoc-smb.h
index a91d39cfccb8..c4c111275627 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.h
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.h
@@ -115,7 +115,7 @@ struct smb_drv_data {
 	struct coresight_device	*csdev;
 	struct smb_data_buffer sdb;
 	struct miscdevice miscdev;
-	spinlock_t spinlock;
+	raw_spinlock_t spinlock;
 	bool reading;
 	pid_t pid;
 };
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From carlos.song at nxp.com  Fri Dec 20 02:46:17 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Fri, 20 Dec 2024 10:46:17 +0000
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <451e8c12-7b45-4b12-af10-63f60ba6e92e@pengutronix.de>
References: <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <Z2QQI2gJNLjI-fam@pengutronix.de>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
 <Z2UeKZcpeRUt2OQ4@pengutronix.de>
 <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2Ugt8NVued0_4c4@pengutronix.de>
 <AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b@pengutronix.de>
 <AM0PR0402MB39374CFFA66D8121DB218334E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <451e8c12-7b45-4b12-af10-63f60ba6e92e@pengutronix.de>
Message-ID: <AM0PR0402MB3937E87BBDC5CEA1C51E4E3AE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Ahmad Fatoum <a.fatoum at pengutronix.de>
> Sent: Friday, December 20, 2024 5:32 PM
> To: Carlos Song <carlos.song at nxp.com>; Oleksij Rempel
> <o.rempel at pengutronix.de>
> Cc: Andi Shyti <andi.shyti at kernel.org>; Frank Li <frank.li at nxp.com>;
> kernel at pengutronix.de; shawnguo at kernel.org; s.hauer at pengutronix.de;
> festevam at gmail.com; linux-i2c at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Clark Wang
> <xiaoning.wang at nxp.com>
> Subject: [EXT] Re: [PATCH v5] i2c: imx: support DMA defer probing
>
> 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 Carlos,
>
> On 20.12.24 10:23, Carlos Song wrote:
> >>> Hi, the ret is from i2c_imx_dma_request() and look like that ret has
> >>> been converted by PTR_ERR, So the ret error has been human readable
> >> version?
> >>
> >> I am not sure I understand the question. ERR_PTR() makes an error
> >> pointer and %pe formats that pointer as error message. So you don't
> >> need to change any function return types unless needed, just at the
> >> end print it with %pe instead of %d (and after error pointer conversion if
> needed).
> >
> > Sorry, I don't know if I understand it incorrectly.
> > I review other driver code, most choose to return error value but not an error
> pointer.
> > Shouldn't error value ?be more readable than error pointers?
> > When we see -110 we know TIMEOUT and we see -12 we know NO MEM.
>
> I know -110, but -12 I need to look up :) Both are cryptic to end users, which is
> why %pe was added on top of the existing %p:
>
> If CONFIG_SYMBOLIC_ERRNAME is enabled %pe expands to an error string, e.g.
> "ENOMEM" or "ETIMEDOUT". If it's disabled, you get the same error number
> that was printed raw before.
>
> Cheers,
> Ahmad
>

Wow! Looks so cool.
Thank you very much for your patient explanation! I agree it.

Also I will change the comment from your suggestion[1]:

"
  /*
   * As we can always fall back to PIO, let's ignore the error setting up
   * DMA and see if we run into errors while setting up PIO mode.
   */
"
In fact, other errors are also from DMA setting not from setting PIO mode.
So can I comment simply like this?

        /* As we can always fall back to PIO, let's ignore the error setting up DMA. */
        ret = i2c_imx_dma_request(i2c_imx, phy_addr);
        if (ret) {
                if (ret == -EPROBE_DEFER)
                        goto clk_notifier_unregister;
                else if (ret == -ENODEV)
                        dev_dbg(&pdev->dev, "Only use PIO mode\n");
                else
                        dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n", ERR_PTR(ret));
        }

[1]https://lore.kernel.org/imx/89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b at pengutronix.de/

BR
Carlos
> >
> > i2c_imx_dma_request is using PTR_ERR to convert pointer to error value[1].
> > I don't know why need to use ERR_PTR to reconvert the value to pointer:
> >
> > dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n",
> > ERR_PTR(ret));
> >
> > Is there some strong reason?
> >
> > [1]
> > https://lore/
> > .kernel.org%2Fimx%2FAM0PR0402MB3937419BBB58B75FB8F8DE2DE8072%
> 40AM0PR04
> >
> 02MB3937.eurprd04.prod.outlook.com%2F&data=05%7C02%7Ccarlos.song%4
> 0nxp
> > .com%7C13a8e6532dd7435c302008dd20d92819%7C686ea1d3bc2b4c6fa92c
> d99c5c30
> >
> 1635%7C0%7C0%7C638702839227618754%7CUnknown%7CTWFpbGZsb3d8eyJ
> FbXB0eU1h
> >
> cGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIj
> >
> oyfQ%3D%3D%7C0%7C%7C%7C&sdata=2A6qPlFEuW1SmlvOZ7OhtfO7VwqysM
> cGhFL2G%2F
> > ECNek%3D&reserved=0
> >>
> >> --
> >> Pengutronix e.K.                           |
> >> |
> >> Steuerwalder Str. 21                       |
> >> http://www/.
> >>
> pen%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C13a8e6532dd7435c30
> 2008d
> >>
> d20d92819%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63870283
> 922763
> >>
> 8077%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjA
> uMDAw
> >>
> MCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&s
> da
> >>
> ta=LasLtpe7GjsG5qVUKG%2FOmVro2JueGLfwUPALw7%2FB2fg%3D&reserved=
> 0
> >>
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C594497db1b5
> >>
> 44e479a8f08dd20d1e88e%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> >> %7C638702808104903131%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hc
> Gki
> >>
> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyf
> >>
> Q %3D%3D%7C0%7C%7C%7C&sdata=EnhsIFlBooqjB%2FSRWF7uAqRHE3yN6rbd
> D
> >> 1yQueTrRus%3D&reserved=0  |
> >> 31137 Hildesheim, Germany                  | Phone:
> +49-5121-206917-0
> >> |
> >> Amtsgericht Hildesheim, HRA 2686           | Fax:
> >> +49-5121-206917-5555 |
>
>
> --
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> http://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C13a8e6532dd
> 7435c302008dd20d92819%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> %7C638702839227652725%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGki
> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ
> %3D%3D%7C0%7C%7C%7C&sdata=Hm60QL5dJ2h3OCesOXK871ASnK7s0L4SPiY
> bK0jtSOo%3D&reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:
> +49-5121-206917-5555 |

From YeoReum.Yun at arm.com  Fri Dec 20 02:46:11 2024
From: YeoReum.Yun at arm.com (Yeo Reum Yun)
Date: Fri, 20 Dec 2024 10:46:11 +0000
Subject: [PATCH v4 1/1] coresight/ultrasoc: change smb_drv_data spinlock's
 type to raw_spinlock_t
In-Reply-To: <20241220104521.809071-3-yeoreum.yun@arm.com>
References: <20241220104521.809071-1-yeoreum.yun@arm.com>
 <20241220104521.809071-3-yeoreum.yun@arm.com>
Message-ID: <GV1PR08MB105219ACE97D596BA78FCEE8EFB072@GV1PR08MB10521.eurprd08.prod.outlook.com>

Sorry this patch is sent duplicate.

________________________________________
From: Yeoreum Yun <yeoreum.yun at arm.com>
Sent: 20 December 2024 10:45
To: Suzuki Poulose; james.clark at linaro.org; alexander.shishkin at linux.intel.com; bigeasy at linutronix.de; clrkwllms at kernel.org; rostedt at goodmis.org; mike.leach at linaro.org
Cc: coresight at lists.linaro.org; linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; linux-rt-devel at lists.linux.dev; Yeo Reum Yun
Subject: [PATCH v4 1/1] coresight/ultrasoc: change smb_drv_data spinlock's type to raw_spinlock_t

In ultrasoc-smb drivers, smb_drv_data->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since smb__drv_data->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type smb_drv_data->spinlock in ultrasoc-smb drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: James Clark <james.clark at linaro.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 drivers/hwtracing/coresight/ultrasoc-smb.c | 12 ++++++------
 drivers/hwtracing/coresight/ultrasoc-smb.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index dc3c9504dd7c..26cfc939e5bd 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -98,7 +98,7 @@ static int smb_open(struct inode *inode, struct file *file)
        struct smb_drv_data *drvdata = container_of(file->private_data,
                                        struct smb_drv_data, miscdev);

-       guard(spinlock)(&drvdata->spinlock);
+       guard(raw_spinlock)(&drvdata->spinlock);

        if (drvdata->reading)
                return -EBUSY;
@@ -152,7 +152,7 @@ static int smb_release(struct inode *inode, struct file *file)
        struct smb_drv_data *drvdata = container_of(file->private_data,
                                        struct smb_drv_data, miscdev);

-       guard(spinlock)(&drvdata->spinlock);
+       guard(raw_spinlock)(&drvdata->spinlock);
        drvdata->reading = false;

        return 0;
@@ -245,7 +245,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
        struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
        int ret = 0;

-       guard(spinlock)(&drvdata->spinlock);
+       guard(raw_spinlock)(&drvdata->spinlock);

        /* Do nothing, the trace data is reading by other interface now */
        if (drvdata->reading)
@@ -280,7 +280,7 @@ static int smb_disable(struct coresight_device *csdev)
 {
        struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);

-       guard(spinlock)(&drvdata->spinlock);
+       guard(raw_spinlock)(&drvdata->spinlock);

        if (drvdata->reading)
                return -EBUSY;
@@ -378,7 +378,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev,
        if (!buf)
                return 0;

-       guard(spinlock)(&drvdata->spinlock);
+       guard(raw_spinlock)(&drvdata->spinlock);

        /* Don't do anything if another tracer is using this sink. */
        if (csdev->refcnt != 1)
@@ -563,7 +563,7 @@ static int smb_probe(struct platform_device *pdev)

        smb_reset_buffer(drvdata);
        platform_set_drvdata(pdev, drvdata);
-       spin_lock_init(&drvdata->spinlock);
+       raw_spin_lock_init(&drvdata->spinlock);
        drvdata->pid = -1;

        ret = smb_register_sink(pdev, drvdata);
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing/coresight/ultrasoc-smb.h
index a91d39cfccb8..c4c111275627 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.h
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.h
@@ -115,7 +115,7 @@ struct smb_drv_data {
        struct coresight_device *csdev;
        struct smb_data_buffer sdb;
        struct miscdevice miscdev;
-       spinlock_t spinlock;
+       raw_spinlock_t spinlock;
        bool reading;
        pid_t pid;
 };
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From kevin.brodsky at arm.com  Fri Dec 20 02:49:38 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri, 20 Dec 2024 11:49:38 +0100
Subject: [PATCH 01/10] mm: Move common parts of pagetable_*_[cd]tor to
 helpers
In-Reply-To: <20241219171920.GB26279@noisy.programming.kicks-ass.net>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <20241219164425.2277022-2-kevin.brodsky@arm.com>
 <20241219171920.GB26279@noisy.programming.kicks-ass.net>
Message-ID: <75cb4ff8-eb0c-4519-a30a-f8be717ba278@arm.com>

Hi Peter, Qi,

On 19/12/2024 18:19, Peter Zijlstra wrote:
> On Thu, Dec 19, 2024 at 04:44:16PM +0000, Kevin Brodsky wrote:
>> Besides the ptlock management at PTE/PMD level, all the
>> pagetable_*_[cd]tor have the same implementation. Introduce common
>> helpers for all levels to reduce the duplication.
> Uff, I forgot to Cc you on the discussion here, sorry!:
>
>   https://lkml.kernel.org/r/cover.1734526570.git.zhengqi.arch at bytedance.com
>
> we now have two series doing more or less overlapping things :/
>
> You can in fact trivially merge the all the implementations -- the
> apparent non-common bit (ptlock_free) is a no-op for all those other
> levels because they'll be having ptdesc->lock == NULL.

Ah that is good to know, thanks for letting me know about that and Qi's
series! Fortunately there isn't that much overlap between our series - I
think we can easily sort this out.

Qi, shall we collaborate to make our series complementary? I believe my
series covers patch 2 and 4 of your series, but it goes further by
covering all levels and all architectures, and patches introducing
ctor/dtor are already split as Alexander suggested on your series. So my
suggestion would be:

* Remove patch 1 in my series - I'd just introduce
pagetable_{p4d,pgd}_[cd]tor with the same implementation as
pagetable_pud_[cd]tor.
* Remove patch 2 and 4 from your series and rebase it on mine.

Let me know if that makes sense, if so I'll post a v2.

Cheers,
- Kevin


From a.fatoum at pengutronix.de  Fri Dec 20 02:51:27 2024
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Fri, 20 Dec 2024 11:51:27 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <AM0PR0402MB3937E87BBDC5CEA1C51E4E3AE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
References: <dhn3f2xpdpu757pizdhcksqiqo53szeh65gtmddfxfhotimh2z@dfxfpl3int53>
 <AM0PR0402MB3937C9A79C55BF4C279F8099E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UBfcq6pE-JMUrb@pengutronix.de>
 <AM0PR0402MB3937347200BF1967EB677123E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2UK4rMxrtNsPw5V@pengutronix.de>
 <AM0PR0402MB393781D3109B1B3FF3C2529FE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
 <Z2UeKZcpeRUt2OQ4@pengutronix.de>
 <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2Ugt8NVued0_4c4@pengutronix.de>
 <AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b@pengutronix.de>
 <AM0PR0402MB39374CFFA66D8121DB218334E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <451e8c12-7b45-4b12-af10-63f60ba6e92e@pengutronix.de>
 <AM0PR0402MB3937E87BBDC5CEA1C51E4E3AE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
Message-ID: <f2690b83-b907-4ade-bb9d-daa0636c6786@pengutronix.de>

Hi Carlos,

On 20.12.24 11:46, Carlos Song wrote:
> 
> 
>> -----Original Message-----
>> From: Ahmad Fatoum <a.fatoum at pengutronix.de>
>> Sent: Friday, December 20, 2024 5:32 PM
>> To: Carlos Song <carlos.song at nxp.com>; Oleksij Rempel

>> I know -110, but -12 I need to look up :) Both are cryptic to end users, which is
>> why %pe was added on top of the existing %p:
>>
>> If CONFIG_SYMBOLIC_ERRNAME is enabled %pe expands to an error string, e.g.
>> "ENOMEM" or "ETIMEDOUT". If it's disabled, you get the same error number
>> that was printed raw before.
>>
>> Cheers,
>> Ahmad
>>
> 
> Wow! Looks so cool.
> Thank you very much for your patient explanation! I agree it.
> 
> Also I will change the comment from your suggestion[1]:
> 
> "
>   /*
>    * As we can always fall back to PIO, let's ignore the error setting up
>    * DMA and see if we run into errors while setting up PIO mode.
>    */
> "
> In fact, other errors are also from DMA setting not from setting PIO mode.
> So can I comment simply like this?
> 
>         /* As we can always fall back to PIO, let's ignore the error setting up DMA. */
>         ret = i2c_imx_dma_request(i2c_imx, phy_addr);
>         if (ret) {
>                 if (ret == -EPROBE_DEFER)
>                         goto clk_notifier_unregister;
>                 else if (ret == -ENODEV)
>                         dev_dbg(&pdev->dev, "Only use PIO mode\n");
>                 else
>                         dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n", ERR_PTR(ret));
>         }
> 
> [1]https://lore.kernel.org/imx/89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b at pengutronix.de/

Sure, looks good to me. @Oleksij?

Cheers,
Ahmad

> 
> BR
> Carlos
>>>
>>> i2c_imx_dma_request is using PTR_ERR to convert pointer to error value[1].
>>> I don't know why need to use ERR_PTR to reconvert the value to pointer:
>>>
>>> dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n",
>>> ERR_PTR(ret));
>>>
>>> Is there some strong reason?
>>>
>>> [1]
>>> https://lore/
>>> .kernel.org%2Fimx%2FAM0PR0402MB3937419BBB58B75FB8F8DE2DE8072%
>> 40AM0PR04
>>>
>> 02MB3937.eurprd04.prod.outlook.com%2F&data=05%7C02%7Ccarlos.song%4
>> 0nxp
>>> .com%7C13a8e6532dd7435c302008dd20d92819%7C686ea1d3bc2b4c6fa92c
>> d99c5c30
>>>
>> 1635%7C0%7C0%7C638702839227618754%7CUnknown%7CTWFpbGZsb3d8eyJ
>> FbXB0eU1h
>>>
>> cGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIj
>>>
>> oyfQ%3D%3D%7C0%7C%7C%7C&sdata=2A6qPlFEuW1SmlvOZ7OhtfO7VwqysM
>> cGhFL2G%2F
>>> ECNek%3D&reserved=0
>>>>
>>>> --
>>>> Pengutronix e.K.                           |
>>>> |
>>>> Steuerwalder Str. 21                       |
>>>> http://www/.
>>>>
>> pen%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C13a8e6532dd7435c30
>> 2008d
>>>>
>> d20d92819%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63870283
>> 922763
>>>>
>> 8077%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjA
>> uMDAw
>>>>
>> MCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&s
>> da
>>>>
>> ta=LasLtpe7GjsG5qVUKG%2FOmVro2JueGLfwUPALw7%2FB2fg%3D&reserved=
>> 0
>>>>
>> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C594497db1b5
>>>>
>> 44e479a8f08dd20d1e88e%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
>>>> %7C638702808104903131%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hc
>> Gki
>>>>
>> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyf
>>>>
>> Q %3D%3D%7C0%7C%7C%7C&sdata=EnhsIFlBooqjB%2FSRWF7uAqRHE3yN6rbd
>> D
>>>> 1yQueTrRus%3D&reserved=0  |
>>>> 31137 Hildesheim, Germany                  | Phone:
>> +49-5121-206917-0
>>>> |
>>>> Amtsgericht Hildesheim, HRA 2686           | Fax:
>>>> +49-5121-206917-5555 |
>>
>>
>> --
>> Pengutronix e.K.                           |
>> |
>> Steuerwalder Str. 21                       |
>> http://www.pen/
>> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C13a8e6532dd
>> 7435c302008dd20d92819%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
>> %7C638702839227652725%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGki
>> OnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ
>> %3D%3D%7C0%7C%7C%7C&sdata=Hm60QL5dJ2h3OCesOXK871ASnK7s0L4SPiY
>> bK0jtSOo%3D&reserved=0  |
>> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0
>> |
>> Amtsgericht Hildesheim, HRA 2686           | Fax:
>> +49-5121-206917-5555 |


-- 
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 andyshrk at 163.com  Fri Dec 20 02:51:11 2024
From: andyshrk at 163.com (Andy Yan)
Date: Fri, 20 Dec 2024 18:51:11 +0800 (CST)
Subject: [PATCH] dt-bindings: iommu: rockchip: Add Rockchip RK3576
In-Reply-To: <172721001667.289647.10163147936752673484.robh@kernel.org>
References: <20240920094947.7566-1-andyshrk@163.com>
 <172721001667.289647.10163147936752673484.robh@kernel.org>
Message-ID: <662c9716.a714.193e3b15aac.Coremail.andyshrk@163.com>


ping

At 2024-09-25 04:33:37, "Rob Herring (Arm)" <robh at kernel.org> wrote:
>
>On Fri, 20 Sep 2024 17:49:40 +0800, Andy Yan wrote:
>> From: Andy Yan <andy.yan at rock-chips.com>
>> 
>> Just like RK3588, RK3576 is compatible to the existing rk3568
>> binding.
>> 
>> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>> ---
>> 
>>  Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml | 1 +
>>  1 file changed, 1 insertion(+)
>> 
>
>Acked-by: Rob Herring (Arm) <robh at kernel.org>
>

From kevin.brodsky at arm.com  Fri Dec 20 02:58:08 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri, 20 Dec 2024 11:58:08 +0100
Subject: [PATCH 00/10] Account page tables at all levels
In-Reply-To: <a7398426-56d1-40b4-a1c9-40ae8c8a4b4b@intel.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <a7398426-56d1-40b4-a1c9-40ae8c8a4b4b@intel.com>
Message-ID: <765aec36-55a4-4161-bb30-4ff838bc2d98@arm.com>

On 19/12/2024 18:13, Dave Hansen wrote:
> On 12/19/24 08:44, Kevin Brodsky wrote:
>>   +---------------+-------------------------+-----------------------+--------------+------------------------------------+
>>   | x86           | Y                       | Y                     | Y/N          | kmem_cache at pgd level if PAE     |
>>   +---------------+-------------------------+-----------------------+--------------+------------------------------------+
> This is a really rare series that adds functionality _and_ removes code
> overall. It looks really good to me. The x86 implementation seems to be
> captured just fine in the generic one:

Thank you for the review, very appreciated!

> Acked-by: Dave Hansen <dave.hansen at linux.intel.com>

Just to double-check, are your ack'ing the x86 changes specifically? If
so I'll add your Acked-by on patch 6, 7 and 9.

> One super tiny nit is that the PAE pgd _can_ be allocated using
> __get_free_pages(). It was originally there for Xen, but I think it's
> being used for PTI only at this point and the comments are wrong-ish.
>
> I kinda think we should just get rid of the 32-bit kmem_cache entirely.

That would certainly simplify things on the x86 side! I'm not at all
familiar with that code though, would you be happy with providing a
patch? I could add it to this series if that's convenient.

- Kevin


From zengheng4 at huawei.com  Fri Dec 20 02:59:31 2024
From: zengheng4 at huawei.com (Zeng Heng)
Date: Fri, 20 Dec 2024 18:59:31 +0800
Subject: [RFC PATCH mpam mpam/snapshot/v6.12-rc1 v3 0/5] arm_mpam:
 Introduce the Narrow-PARTID feature for MPAM driver
In-Reply-To: <Z1sMtF9bvw5NZOC6@e133380.arm.com>
References: <20241207092136.2488426-1-zengheng4@huawei.com>
 <Z1sMtF9bvw5NZOC6@e133380.arm.com>
Message-ID: <acf5c82f-1d33-4cd4-ff50-5f7c37f49a1e@huawei.com>



On 2024/12/13 0:17, Dave Martin wrote:
> Hi,
> 
> On Sat, Dec 07, 2024 at 05:21:31PM +0800, Zeng Heng wrote:
>> The patch set is applied for mpam/snapshot/v6.12-rc1 branch of
>> https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git
>> repository.
>>
>> The narrow-partid feature in MPAM allows for a more efficient use of
>> PARTIDs by enabling a many-to-one mapping of reqpartids (requested PARTIDs)
>> to intpartids (internal PARTIDs). This mapping reduces the number of unique
>> PARTIDs needed, thus allowing more tasks or processes to be monitored and
>> managed with the available resources.
>>
>> For a mixture of MSCs system, for MSCs that do not support narrow-partid,
>> we use the PARTIDs exceeding the number of closids as reqPARTIDs for
>> expanding the monitoring groups.
> 
> Mixed systems still seem not to be handled completely by this series?
> 
> You do cope with the scenario where some MSCs support Narrowing and
> some do not, but there is still the problem of incompatible controls.
> 
> If a non-Narrowing MSC has controls that are not of the "partition
> bitmap" type, then splitting a resctrl control group across multiple
> PARTIDs is going to change the hardware regulation behaviour.  There
> does not seem to be any way to work around this be programming
> different control values (for example).  So, there may be over- or
> under-allocation of resources compared with what the user requests in
> resctrlfs.
> 
> So, I think there is still a need to check which controls are present,
> and either disable the use of non-identity intPARTID<->reqPARTID
> mappings if incompatible controls are present (or don't expose those
> controls to resctrl).
> 
> (If you were not trying to address this issue yet then that is not a
> problem for an RFC, but it is best to be clear about the
> limitations...)
> 

In the v3, the limitation you mentioned has not yet been handled.
V3 has not yet determined how to define this limitation well. 
Additionally, for v3, I was still uncertain whether a large-scale
refactoring was still necessary at that time.

In fact, I take this limitation very seriously, and I will try to define
the limitation in next version, explaining it separately as a distinct
patch.


>> In order to keep the existing resctrl API interface, the rmid contains both
>> req_idx and PMG information instead of PMG only under the MPAM driver. The
>> req_idx represents the req_idx-th sub-monitoring group under the control
>> group. The new rmid would be like:
>>
>>      rmid = (req_idx << shift | pmg).
>>
>> The new conversion relationship between closid/rmid and (req)PARTID/PMG is:
>>
>>      (req)PARTID = (rmid.req_idx * n) + closid,
>>      PMG = rmid.pmg.
>>
>> Each intPARTID has m reqPARTIDs, which are used to expand the number of
>> monitoring groups under the control group. Therefore, the number of
>> monitoring groups is no longer limited by the range of MPAM PMG, which
>> enhances the extensibility of the system's monitoring capabilities.
>>
>> ---
>> Compared with v1:
>>    - Rebase this patch set on latest MPAM driver of the v6.12-rc1 branch.
>>
>> Compared with v2:
>>    - Refactor closid/rmid pair translation
>>    - Simplify the logic of synchronize configuration
>>    - Remove reqPARTID pool
>> ---
> 
> This approach looks reasonable overall, and in this version the changes
> do seem to be better localised in the mpam_resctrl.c glue code now.
> 
> I had also been working on a similar approach, so I have posted it for
> comparison [1] -- though the two approaches are doing pretty much the
> same thing, some details differ.
> 
> (Note, I have not addressed PARTID Narrowing at all yet; however,
> I think more thought is needed for that.)
> 

Yes, localize the narrow-partid feature within mpam_resctrl.c file is
the biggest restructuring improvement in this version. Of course, thanks
for your meticulous review and insightful comments.

In the meanwhile, I have roughly read through the patch set you sent
out, especially patch 4 (arm_mpam: Introduce flexible CLOSID/RMID
translation). If I have any comments worth discussing, I will try to
share them.

> 
> Note: Are there bisection issues with some of the patches in the
> series?  It looks like not all of the ID conversions are applied in the
> same patch, so I'm wondering whether strange behaviour may be seen at
> the intermediate commits.
> 

The original intention of splitting the patch set was to facilitate 
review. I will merge the part of patch 5 into patch 2 and consider
making the patch set be friendly for bisection issues.


Best regards,
Zeng Heng



From przemyslaw.kitszel at intel.com  Fri Dec 20 02:59:54 2024
From: przemyslaw.kitszel at intel.com (Przemek Kitszel)
Date: Fri, 20 Dec 2024 11:59:54 +0100
Subject: [PATCH v5 3/3] net: stmmac: dwmac-nuvoton: Add dwmac glue for
 Nuvoton MA35 family
In-Reply-To: <216e7c97-e0b1-4833-b344-a71834020b15@gmail.com>
References: <20241218114442.137884-1-a0987203069@gmail.com>
 <20241218114442.137884-4-a0987203069@gmail.com>
 <7a4f5769-0010-40fd-8bb7-a20f2725114f@intel.com>
 <216e7c97-e0b1-4833-b344-a71834020b15@gmail.com>
Message-ID: <c800e544-82af-43d3-b07a-e7b1a4028330@intel.com>

On 12/20/24 08:07, Joey Lu wrote:
> Dear Przemek,
> 
> Thank you for your reply.

sure :)
please also configure your email to write replies as plain-text, instead
of HTML

I also forgot to say, that you should have target this series for the
net-next (--subject-prefix for git-send-email)

Please also note that your v2 should wait to be send in the new year,
as we will begin the Winter Break for netdev ML in a moment.

>>> +/* 2000ps is mapped to 0 ~ 0xF */
>>> +#define PATH_DELAY_DEC????? 134
>>
>> would be great to previx your macros by NVT_
> Got it.
>>
>> why 134 and not 125?
> 
> The interval is confirmed to be 134. The mapping is as follows:
> 
> |0000| = 0.00 ns
> |0001| = 0.13 ns
> |0010| = 0.27 ns
> ...
> |1111| = 2.00 ns

thanks, that's correct, sorry for confusion




From kever.yang at rock-chips.com  Fri Dec 20 02:15:44 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:15:44 +0800
Subject: [PATCH v2 0/7] Rockchip: add Rockchip rk3576 EVB1 board
Message-ID: <20241220101551.3505917-1-kever.yang@rock-chips.com>

This patch set is for rockchip rk3576 evb1.
Based on the naneng combphy patch from Frank Wang.

This version including the patch adding usb nodes from Frank Wang.

Changes in v2:
- update the clock and reset names to pass the DTB CHECK
- remove required 'msi-map'
- add interrupt name 'msi'
- Update clock and reset names and sequence to pass DTB check
- collect acked-by tag
- Enable USB nodes

Frank Wang (1):
  arm64: dts: rockchip: add usb related nodes for rk3576

Kever Yang (6):
  dts: arm64: rockchip: Add rk3576 naneng combphy nodes
  dt-bindings: PCI: dwc: rockchip: Add rk3576 support
  dts: arm64: rockchip: Add rk3576 pcie nodes
  dt-bindings: arm: rockchip: Sort for rk3568 evb
  dt-bindings: arm: rockchip: Add rk3576 evb1 board
  arm64: dts: rockchip: Add rk3576 evb1 board

 .../devicetree/bindings/arm/rockchip.yaml     |  25 +-
 .../bindings/pci/rockchip-dw-pcie-common.yaml |   1 +
 .../bindings/pci/rockchip-dw-pcie.yaml        |   4 +-
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3576-evb1-v10.dts     | 727 ++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3576.dtsi      | 278 +++++++
 6 files changed, 1023 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts

-- 
2.25.1



From kever.yang at rock-chips.com  Fri Dec 20 02:15:47 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:15:47 +0800
Subject: [PATCH v2 3/7] dts: arm64: rockchip: Add rk3576 pcie nodes
In-Reply-To: <20241220101551.3505917-1-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
Message-ID: <20241220101551.3505917-4-kever.yang@rock-chips.com>

rk3576 has two pcie controller, both are pcie2x1 used with
naneng-combphy.

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

Changes in v2:
- Update clock and reset names and sequence to pass DTB check

 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 109 +++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index a147879da501..df7dfe702221 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1016,6 +1016,115 @@ qos_npu_m1ro: qos at 27f22100 {
 			reg = <0x0 0x27f22100 0x0 0x20>;
 		};
 
+		pcie0: pcie at 2a200000 {
+			compatible = "rockchip,rk3576-pcie", "rockchip,rk3568-pcie";
+			bus-range = <0x0 0xf>;
+			clocks = <&cru ACLK_PCIE0_MST>, <&cru ACLK_PCIE0_SLV>,
+				 <&cru ACLK_PCIE0_DBI>, <&cru PCLK_PCIE0>,
+				 <&cru CLK_PCIE0_AUX>;
+
+			clock-names = "aclk_mst", "aclk_slv",
+				      "aclk_dbi", "pclk",
+				      "aux";
+			device_type = "pci";
+			interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "sys", "pmc", "msg", "legacy", "err", "msi";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie0_intc 0>,
+					<0 0 0 2 &pcie0_intc 1>,
+					<0 0 0 3 &pcie0_intc 2>,
+					<0 0 0 4 &pcie0_intc 3>;
+			linux,pci-domain = <0>;
+			num-ib-windows = <8>;
+			num-viewport = <8>;
+			num-ob-windows = <2>;
+			max-link-speed = <2>;
+			num-lanes = <1>;
+			phys = <&combphy0_ps PHY_TYPE_PCIE>;
+			phy-names = "pcie-phy";
+			power-domains = <&power RK3576_PD_PHP>;
+			ranges = <0x01000000 0x0 0x20100000 0x0 0x20100000 0x0 0x00100000
+				  0x02000000 0x0 0x20200000 0x0 0x20200000 0x0 0x00e00000
+				  0x03000000 0x9 0x00000000 0x9 0x00000000 0x0 0x80000000>;
+			reg = <0x0 0x22000000 0x0 0x00400000>,
+			      <0x0 0x2a200000 0x0 0x00010000>,
+			      <0x0 0x20000000 0x0 0x00100000>;
+			reg-names = "dbi", "apb", "config";
+			resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
+			reset-names = "pwr", "pipe";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			status = "disabled";
+
+			pcie0_intc: legacy-interrupt-controller {
+				interrupt-controller;
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 280 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
+
+		pcie1: pcie at 2a210000 {
+			compatible = "rockchip,rk3576-pcie", "rockchip,rk3568-pcie";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x20 0x2f>;
+			clocks = <&cru ACLK_PCIE1_MST>, <&cru ACLK_PCIE1_SLV>,
+				 <&cru ACLK_PCIE1_DBI>, <&cru PCLK_PCIE1>,
+				 <&cru CLK_PCIE1_AUX>;
+			clock-names = "aclk_mst", "aclk_slv",
+				      "aclk_dbi", "pclk",
+				      "aux";
+			device_type = "pci";
+			interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "sys", "pmc", "msg", "legacy", "err", "msi";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie1_intc 0>,
+					<0 0 0 2 &pcie1_intc 1>,
+					<0 0 0 3 &pcie1_intc 2>,
+					<0 0 0 4 &pcie1_intc 3>;
+			linux,pci-domain = <0>;
+			num-ib-windows = <8>;
+			num-viewport = <8>;
+			num-ob-windows = <2>;
+			max-link-speed = <2>;
+			num-lanes = <1>;
+			phys = <&combphy1_psu PHY_TYPE_PCIE>;
+			phy-names = "pcie-phy";
+			power-domains = <&power RK3576_PD_SUBPHP>;
+			ranges = <0x01000000 0x0 0x21100000 0x0 0x21100000 0x0 0x00100000
+				  0x02000000 0x0 0x21200000 0x0 0x21200000 0x0 0x00e00000
+				  0x03000000 0x9 0x80000000 0x9 0x80000000 0x0 0x80000000>;
+			reg = <0x0 0x22400000 0x0 0x00400000>,
+			      <0x0 0x2a210000 0x0 0x00010000>,
+			      <0x0 0x21000000 0x0 0x00100000>;
+			reg-names = "dbi", "apb", "config";
+			resets = <&cru SRST_PCIE1_POWER_UP>, <&cru SRST_P_PCIE1>;
+			reset-names = "pwr", "pipe";
+			status = "disabled";
+
+			pcie1_intc: legacy-interrupt-controller {
+				interrupt-controller;
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 266 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
+
 		gmac0: ethernet at 2a220000 {
 			compatible = "rockchip,rk3576-gmac", "snps,dwmac-4.20a";
 			reg = <0x0 0x2a220000 0x0 0x10000>;
-- 
2.25.1



From kever.yang at rock-chips.com  Fri Dec 20 02:15:49 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:15:49 +0800
Subject: [PATCH v2 5/7] dt-bindings: arm: rockchip: Sort for rk3568 evb
In-Reply-To: <20241220101551.3505917-1-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
Message-ID: <20241220101551.3505917-6-kever.yang@rock-chips.com>

The info for rk3568 should before rk3588.

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---

Changes in v2:
- collect acked-by tag

 .../devicetree/bindings/arm/rockchip.yaml     | 20 +++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 753199a12923..45ee4bf7c80c 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -1006,6 +1006,16 @@ properties:
           - const: rockchip,rk3399-sapphire-excavator
           - const: rockchip,rk3399
 
+      - description: Rockchip RK3566 BOX Evaluation Demo board
+        items:
+          - const: rockchip,rk3566-box-demo
+          - const: rockchip,rk3566
+
+      - description: Rockchip RK3568 Evaluation board
+        items:
+          - const: rockchip,rk3568-evb1-v10
+          - const: rockchip,rk3568
+
       - description: Rockchip RK3588 Evaluation board
         items:
           - const: rockchip,rk3588-evb1-v10
@@ -1099,16 +1109,6 @@ properties:
           - const: zkmagic,a95x-z2
           - const: rockchip,rk3318
 
-      - description: Rockchip RK3566 BOX Evaluation Demo board
-        items:
-          - const: rockchip,rk3566-box-demo
-          - const: rockchip,rk3566
-
-      - description: Rockchip RK3568 Evaluation board
-        items:
-          - const: rockchip,rk3568-evb1-v10
-          - const: rockchip,rk3568
-
       - description: Sinovoip RK3308 Banana Pi P2 Pro
         items:
           - const: sinovoip,rk3308-bpi-p2pro
-- 
2.25.1



From kever.yang at rock-chips.com  Fri Dec 20 02:15:48 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:15:48 +0800
Subject: [PATCH v2 4/7] arm64: dts: rockchip: add usb related nodes for rk3576
In-Reply-To: <20241220101551.3505917-1-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
Message-ID: <20241220101551.3505917-5-kever.yang@rock-chips.com>

From: Frank Wang <frank.wang at rock-chips.com>

This adds USB and USB-PHY related nodes for RK3576 SoC.

Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

Changes in v2: None

 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 133 +++++++++++++++++++++++
 1 file changed, 133 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index df7dfe702221..5be316684be4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -445,6 +445,58 @@ soc {
 		#size-cells = <2>;
 		ranges;
 
+		usb_drd0_dwc3: usb at 23000000 {
+			compatible = "rockchip,rk3576-dwc3", "snps,dwc3";
+			reg = <0x0 0x23000000 0x0 0x400000>;
+			clocks = <&cru CLK_REF_USB3OTG0>,
+				 <&cru CLK_SUSPEND_USB3OTG0>,
+				 <&cru ACLK_USB3OTG0>;
+			clock-names = "ref_clk", "suspend_clk", "bus_clk";
+			interrupts = <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&power RK3576_PD_USB>;
+			resets = <&cru SRST_A_USB3OTG0>;
+			dr_mode = "otg";
+			phys = <&u2phy0_otg>, <&usbdp_phy PHY_TYPE_USB3>;
+			phy-names = "usb2-phy", "usb3-phy";
+			phy_type = "utmi_wide";
+			snps,dis_enblslpm_quirk;
+			snps,dis-u1-entry-quirk;
+			snps,dis-u2-entry-quirk;
+			snps,dis-u2-freeclk-exists-quirk;
+			snps,dis-del-phy-power-chg-quirk;
+			snps,dis-tx-ipgap-linecheck-quirk;
+			snps,parkmode-disable-hs-quirk;
+			snps,parkmode-disable-ss-quirk;
+			status = "disabled";
+		};
+
+		usb_drd1_dwc3: usb at 23400000 {
+			compatible = "rockchip,rk3576-dwc3", "snps,dwc3";
+			reg = <0x0 0x23400000 0x0 0x400000>;
+			clocks = <&cru CLK_REF_USB3OTG1>,
+				 <&cru CLK_SUSPEND_USB3OTG1>,
+				 <&cru ACLK_USB3OTG1>;
+			clock-names = "ref_clk", "suspend_clk", "bus_clk";
+			interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&power RK3576_PD_PHP>;
+			resets = <&cru SRST_A_USB3OTG1>;
+			dr_mode = "otg";
+			phys = <&u2phy1_otg>, <&combphy1_psu PHY_TYPE_USB3>;
+			phy-names = "usb2-phy", "usb3-phy";
+			phy_type = "utmi_wide";
+			snps,dis_enblslpm_quirk;
+			snps,dis-u1-entry-quirk;
+			snps,dis-u2-entry-quirk;
+			snps,dis-u2-freeclk-exists-quirk;
+			snps,dis-del-phy-power-chg-quirk;
+			snps,dis-tx-ipgap-linecheck-quirk;
+			snps,dis_rxdet_inp3_quirk;
+			snps,parkmode-disable-hs-quirk;
+			snps,parkmode-disable-ss-quirk;
+			dma-coherent;
+			status = "disabled";
+		};
+
 		sys_grf: syscon at 2600a000 {
 			compatible = "rockchip,rk3576-sys-grf", "syscon";
 			reg = <0x0 0x2600a000 0x0 0x2000>;
@@ -515,6 +567,65 @@ usbdpphy_grf: syscon at 2602c000 {
 			reg = <0x0 0x2602c000 0x0 0x2000>;
 		};
 
+		usb2phy_grf: syscon at 2602e000 {
+			compatible = "rockchip,rk3576-usb2phy-grf", "syscon", "simple-mfd";
+			reg = <0x0 0x2602e000 0x0 0x4000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			u2phy0: usb2-phy at 0 {
+				compatible = "rockchip,rk3576-usb2phy";
+				reg = <0x0 0x10>;
+				resets = <&cru SRST_OTGPHY_0>, <&cru SRST_P_USBPHY_GRF_0>;
+				reset-names = "phy", "apb";
+				clocks = <&cru CLK_PHY_REF_SRC>,
+					 <&cru ACLK_MMU2>,
+					 <&cru ACLK_SLV_MMU2>;
+				clock-names = "phyclk", "aclk", "aclk_slv";
+				clock-output-names = "usb480m_phy0";
+				#clock-cells = <0>;
+				status = "disabled";
+
+				u2phy0_otg: otg-port {
+					#phy-cells = <0>;
+					interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH>,
+						     <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
+						     <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+					interrupt-names = "otg-bvalid", "otg-id", "linestate";
+					status = "disabled";
+				};
+			};
+
+			u2phy1: usb2-phy at 2000 {
+				compatible = "rockchip,rk3576-usb2phy";
+				reg = <0x2000 0x10>;
+				resets = <&cru SRST_OTGPHY_1>, <&cru SRST_P_USBPHY_GRF_1>;
+				reset-names = "phy", "apb";
+				clocks = <&cru CLK_PHY_REF_SRC>,
+					 <&cru ACLK_MMU1>,
+					 <&cru ACLK_SLV_MMU1>;
+				clock-names = "phyclk", "aclk", "aclk_slv";
+				clock-output-names = "usb480m_phy1";
+				#clock-cells = <0>;
+				status = "disabled";
+
+				u2phy1_otg: otg-port {
+					#phy-cells = <0>;
+					interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>,
+						     <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>,
+						     <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+					interrupt-names = "otg-bvalid", "otg-id", "linestate";
+					status = "disabled";
+				};
+			};
+		};
+
+		vo1_grf: syscon at 26036000 {
+			compatible = "rockchip,rk3576-vo1-grf", "syscon";
+			reg = <0x0 0x26036000 0x0 0x100>;
+			clocks = <&cru PCLK_VO1_ROOT>;
+		};
+
 		sdgmac_grf: syscon at 26038000 {
 			compatible = "rockchip,rk3576-sdgmac-grf", "syscon";
 			reg = <0x0 0x26038000 0x0 0x1000>;
@@ -1732,6 +1843,28 @@ combphy1_psu: phy at 2b060000 {
 			status = "disabled";
 		};
 
+		usbdp_phy: phy at 2b010000 {
+			compatible = "rockchip,rk3576-usbdp-phy";
+			reg = <0x0 0x2b010000 0x0 0x10000>;
+			#phy-cells = <1>;
+			clocks = <&cru CLK_PHY_REF_SRC >,
+				 <&cru CLK_USBDP_COMBO_PHY_IMMORTAL>,
+				 <&cru PCLK_USBDPPHY>,
+				 <&u2phy0>;
+			clock-names = "refclk", "immortal", "pclk", "utmi";
+			resets = <&cru SRST_USBDP_COMBO_PHY_INIT>,
+				 <&cru SRST_USBDP_COMBO_PHY_CMN>,
+				 <&cru SRST_USBDP_COMBO_PHY_LANE>,
+				 <&cru SRST_USBDP_COMBO_PHY_PCS>,
+				 <&cru SRST_P_USBDPPHY>;
+			reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+			rockchip,u2phy-grf = <&usb2phy_grf>;
+			rockchip,usb-grf = <&usb_grf>;
+			rockchip,usbdpphy-grf = <&usbdpphy_grf>;
+			rockchip,vo-grf = <&vo1_grf>;
+			status = "disabled";
+		};
+
 		sram: sram at 3ff88000 {
 			compatible = "mmio-sram";
 			reg = <0x0 0x3ff88000 0x0 0x78000>;
-- 
2.25.1



From kever.yang at rock-chips.com  Fri Dec 20 02:15:50 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:15:50 +0800
Subject: [PATCH v2 6/7] dt-bindings: arm: rockchip: Add rk3576 evb1 board
In-Reply-To: <20241220101551.3505917-1-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
Message-ID: <20241220101551.3505917-7-kever.yang@rock-chips.com>

Add device tree documentation for rk3576-evb1-v10.

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---

Changes in v2:
- collect acked-by tag

 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 45ee4bf7c80c..b2681a45867b 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -1016,6 +1016,11 @@ properties:
           - const: rockchip,rk3568-evb1-v10
           - const: rockchip,rk3568
 
+      - description: Rockchip RK3576 Evaluation board
+        items:
+          - const: rockchip,rk3576-evb1-v10
+          - const: rockchip,rk3576
+
       - description: Rockchip RK3588 Evaluation board
         items:
           - const: rockchip,rk3588-evb1-v10
-- 
2.25.1



From kever.yang at rock-chips.com  Fri Dec 20 02:15:51 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Fri, 20 Dec 2024 18:15:51 +0800
Subject: [PATCH v2 7/7] arm64: dts: rockchip: Add rk3576 evb1 board
In-Reply-To: <20241220101551.3505917-1-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
Message-ID: <20241220101551.3505917-8-kever.yang@rock-chips.com>

RK3576 EVB1 board features:
- Rockchip RK3576
- PMIC: RK806-2x2pcs+DiscretePower
- RAM: LPDDR4/4x 2pcsx 32bit
- ROM: eMMC5.1 + UFS
- LAN x 2
- HDMI TX
- SD card slot
- PCIe2 slot

Add support for pmic, eMMC, SD-card, ADC-KEY, PCIE and GMAC.

NOTE: The board has a hardware mux design for
- PCIe slot(pcie1)
- USB3 host(usb_drd1_dwc3)
and default state is switch to USB3. To enable PCIe slot:
- hardware: Switch the mux to PCIe side;
- dts: disable usb_drd1_dwc3 and enable pcie1;

Signed-off-by: Liang Chen <cl at rock-chips.com>
Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

Changes in v2:
- Enable USB nodes

 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3576-evb1-v10.dts     | 727 ++++++++++++++++++
 2 files changed, 728 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 86cc418a2255..2e683d7eab58 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -129,6 +129,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-display-vz.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-io-expander.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-sige7.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-w3.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-coolpi-cm5-evb.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts
new file mode 100644
index 000000000000..edbc46e6cf12
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts
@@ -0,0 +1,727 @@
+// 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/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3576.dtsi"
+
+/ {
+	model = "Rockchip RK3576 EVB V10 Board";
+	compatible = "rockchip,rk3576-evb1-v10", "rockchip,rk3576";
+
+	aliases {
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
+	};
+
+	chosen: chosen {
+		stdout-path = "serial0:1500000n8";
+	};
+
+	adc_keys: 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-back {
+			label = "back";
+			linux,code = <KEY_BACK>;
+			press-threshold-microvolt = <1235000>;
+		};
+	};
+
+	leds: leds {
+		compatible = "gpio-leds";
+		work_led: led-0 {
+			gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	vcc12v_dcin: regulator-vcc12v-dcin {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc_sys: regulator-vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_device: regulator-vcc5v0-device {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_device";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc_2v0_pldo_s3: regulator-vcc-2v0-pldo-s3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_2v0_pldo_s3";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <2000000>;
+		regulator-max-microvolt = <2000000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v1_nldo_s3";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc3v3_rtc_s5: regulator-vcc3v3-rtc-s5 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_rtc_s5";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc_1v8_s0: regulator-vcc-1v8-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_1v8_s3>;
+	};
+
+	vcc_3v3_s0: regulator-vcc-3v3-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	vcc_ufs_s0: regulator-vcc-ufs-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_ufs_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc1v8_ufs_vccq2_s0: regulator-vcc1v8-ufs-vccq2-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc1v8_ufs_vccq2_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_1v8_s3>;
+	};
+
+	vcc1v2_ufs_vccq_s0: regulator-vcc1v2-ufs-vccq-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc1v2_ufs_vccq_s0";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc3v3_lcd_n: regulator-vcc3v3-lcd0-n {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_lcd0_n";
+		regulator-boot-on;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc_3v3_s0>;
+	};
+
+	vcc3v3_pcie0: regulator-vcc3v3-pcie0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_pcie1";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <5000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_host: regulator-vcc5v0-host {
+		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 = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc5v0_device>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_host_pwren>;
+	};
+
+	vbus5v0_typec: regulator-vbus5v0-typec {
+		compatible = "regulator-fixed";
+		regulator-name = "vbus5v0_typec";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc5v0_device>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_otg0_pwren>;
+	};
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu_big_s0>;
+};
+
+&combphy1_psu {
+	status = "okay";
+};
+
+&gmac0 {
+	phy-mode = "rgmii-rxid";
+	clock_in_out = "output";
+
+	snps,reset-gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 20000 100000>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&eth0m0_miim
+		     &eth0m0_tx_bus2
+		     &eth0m0_rx_bus2
+		     &eth0m0_rgmii_clk
+		     &eth0m0_rgmii_bus
+		     &ethm0_clk0_25m_out>;
+
+	tx_delay = <0x21>;
+
+	phy-handle = <&rgmii_phy0>;
+	status = "okay";
+};
+
+&gmac1 {
+	phy-mode = "rgmii-rxid";
+	clock_in_out = "output";
+
+	snps,reset-gpio = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 20000 100000>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&eth1m0_miim
+		     &eth1m0_tx_bus2
+		     &eth1m0_rx_bus2
+		     &eth1m0_rgmii_clk
+		     &eth1m0_rgmii_bus
+		     &ethm0_clk1_25m_out>;
+
+	tx_delay = <0x20>;
+
+	phy-handle = <&rgmii_phy1>;
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+
+	rk806: pmic at 23 {
+		compatible = "rockchip,rk806";
+		reg = <0x23>;
+
+		interrupt-parent = <&gpio0>;
+		interrupts = <6 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 = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc5-supply = <&vcc_sys>;
+		vcc6-supply = <&vcc_sys>;
+		vcc7-supply = <&vcc_sys>;
+		vcc8-supply = <&vcc_sys>;
+		vcc9-supply = <&vcc_sys>;
+		vcc10-supply = <&vcc_sys>;
+		vcc11-supply = <&vcc_2v0_pldo_s3>;
+		vcc12-supply = <&vcc_sys>;
+		vcc13-supply = <&vcc_1v1_nldo_s3>;
+		vcc14-supply = <&vcc_1v1_nldo_s3>;
+		vcca-supply = <&vcc_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";
+		};
+
+		rk806_dvs1_slp: dvs1-slp-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun1";
+		};
+
+		rk806_dvs1_pwrdn: dvs1-pwrdn-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun2";
+		};
+
+		rk806_dvs1_rst: dvs1-rst-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun3";
+		};
+
+		rk806_dvs2_slp: dvs2-slp-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun1";
+		};
+
+		rk806_dvs2_pwrdn: dvs2-pwrdn-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun2";
+		};
+
+		rk806_dvs2_rst: dvs2-rst-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun3";
+		};
+
+		rk806_dvs2_dvs: dvs2-dvs-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun4";
+		};
+
+		rk806_dvs2_gpio: dvs2-gpio-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun5";
+		};
+
+		rk806_dvs3_slp: dvs3-slp-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun1";
+		};
+
+		rk806_dvs3_pwrdn: dvs3-pwrdn-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun2";
+		};
+
+		rk806_dvs3_rst: dvs3-rst-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun3";
+		};
+
+		rk806_dvs3_dvs: dvs3-dvs-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun4";
+		};
+
+		rk806_dvs3_gpio: dvs3-gpio-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun5";
+		};
+
+		regulators {
+			vdd_cpu_big_s0: dcdc-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_cpu_big_s0";
+				regulator-enable-ramp-delay = <400>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_npu_s0: dcdc-reg2 {
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_npu_s0";
+				regulator-enable-ramp-delay = <400>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_lit_s0: dcdc-reg3 {
+				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;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vcc_3v3_s3: dcdc-reg4 {
+				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>;
+				};
+			};
+
+			vdd_gpu_s0: dcdc-reg5 {
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <900000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_gpu_s0";
+				regulator-enable-ramp-delay = <400>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vddq_ddr_s0: dcdc-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vddq_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_logic_s0: dcdc-reg7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <800000>;
+				regulator-name = "vdd_logic_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s3: dcdc-reg8 {
+				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>;
+				};
+			};
+
+			vdd2_ddr_s3: dcdc-reg9 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vdd2_ddr_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_ddr_s0: dcdc-reg10 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-name = "vdd_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca_1v8_s0: pldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca_1v8_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pldo2_s0: pldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca1v8_pldo2_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_1v2_s0: pldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-name = "vdda_1v2_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca_3v3_s0: pldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcca_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;
+				};
+			};
+
+			vcca1v8_pldo6_s3: pldo-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca1v8_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 = <550000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdda_ddr_pll_s0: nldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdda_ddr_pll_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v75_hdmi_s0: nldo-reg3 {
+				regulator-boot-on;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
+				regulator-name = "vdda0v75_hdmi_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v85_s0: nldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdda_0v85_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v75_s0: nldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdda_0v75_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&mdio0 {
+	rgmii_phy0: phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+		clocks = <&cru REFCLKO25M_GMAC0_OUT>;
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x1>;
+		clocks = <&cru REFCLKO25M_GMAC1_OUT>;
+	};
+};
+
+&pinctrl {
+	usb {
+		usb_host_pwren: usb-host-pwren {
+			rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usb_otg0_pwren: usb-otg0-pwren {
+			rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usbc0_int: usbc0-int {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&sdmmc {
+	max-frequency = <200000000>;
+	no-sdio;
+	no-mmc;
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	disable-wp;
+	sd-uhs-sdr104;
+	vqmmc-supply = <&vccio_sd_s0>;
+	status = "okay";
+};
+
+&pcie1 {
+	reset-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_pcie0>;
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vcca_1v8_s0>;
+};
+
+&u2phy0 {
+	status = "okay";
+};
+
+&u2phy0_otg {
+	phy-supply = <&vbus5v0_typec>;
+	status = "okay";
+};
+
+&u2phy1 {
+	status = "okay";
+};
+
+&u2phy1_otg {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&usbdp_phy {
+	rockchip,dp-lane-mux = <2 3>;
+	status = "okay";
+};
+
+&usb_drd0_dwc3 {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usb_drd1_dwc3 {
+	dr_mode = "host";
+	status = "okay";
+};
-- 
2.25.1



From jbrunet at baylibre.com  Fri Dec 20 02:25:35 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 11:25:35 +0100
Subject: [PATCH 0/2] clk: amlogic: gxbb: 32k clock fixes
Message-ID: <20241220-amlogic-clk-gxbb-32k-fixes-v1-0-baca56ecf2db@baylibre.com>

This patchset provides 2 fixes for 32k clock of the gxbb SoC family.
The problems were minor enough to have no real world consequences but still
need fixing.

Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
Jerome Brunet (2):
      clk: amlogic: gxbb: drop incorrect flag on 32k clock
      clk: amlogic: gxbb: drop non existing 32k clock parent

 drivers/clk/meson/gxbb.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
---
base-commit: 1909d0d351ed98fdb9f5cbe377213ba0154bf2e0
change-id: 20241220-amlogic-clk-gxbb-32k-fixes-9483bb55f849

Best regards,
-- 
Jerome



From maz at kernel.org  Fri Dec 20 03:10:20 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Dec 2024 11:10:20 +0000
Subject: [PATCH v4 00/18] KVM: arm64: Non-protected guest stage-2 support for pKVM
In-Reply-To: <20241218194059.3670226-1-qperret@google.com>
References: <20241218194059.3670226-1-qperret@google.com>
Message-ID: <173469300935.1371312.1616528930981043115.b4-ty@kernel.org>

On Wed, 18 Dec 2024 19:40:41 +0000, Quentin Perret wrote:
> This is the v4 of the series adding support for non-protected guests
> stage-2 to pKVM. Please refer to v1 for all the context:
> 
>   https://lore.kernel.org/kvmarm/20241104133204.85208-1-qperret at google.com/
> 
> Please note that in its current form, this series has two main
> limitations that will be addressed separately:
> 
> [...]

Applied to next, thanks!

[01/18] KVM: arm64: Change the layout of enum pkvm_page_state
        commit: a1a1f1ff1f28d52deb39aa29b89663de2afefd67
[02/18] KVM: arm64: Move enum pkvm_page_state to memory.h
        commit: d4fc42a479c8e913fd61dbb432e67f35587c336a
[03/18] KVM: arm64: Make hyp_page::order a u8
        commit: b35875d466ad3cb08866eac067cca0581d4293d7
[04/18] KVM: arm64: Move host page ownership tracking to the hyp vmemmap
        commit: e94a7dea2972bd9a5ee3ed4312f7198370969407
[05/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_mkyoung
        commit: 5398ddc5c90bd418b90d859e9267aa39399021af
[06/18] KVM: arm64: Pass walk flags to kvm_pgtable_stage2_relax_perms
        commit: e279c25d78d6729e39a0221c98185bd0e7aa0c99
[07/18] KVM: arm64: Make kvm_pgtable_stage2_init() a static inline function
        commit: c77e5181fed54b25d489eb7d2ccb5c1c72a1063c
[08/18] KVM: arm64: Add {get,put}_pkvm_hyp_vm() helpers
        commit: 99996d575ee69d4327bad98a0148729b73dde23a
[09/18] KVM: arm64: Introduce __pkvm_vcpu_{load,put}()
        commit: f7d03fcbf1f482069e9afac55b17de3bd323b8f6
[10/18] KVM: arm64: Introduce __pkvm_host_share_guest()
        commit: d0bd3e6570aee42766e7bd884734ae078667ea1e
[11/18] KVM: arm64: Introduce __pkvm_host_unshare_guest()
        commit: 72db3d3fbaa77ba649201c9e9f9d1a54fa76b217
[12/18] KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
        commit: 34884a0a4a53f9544f78e7e9556cb4d202e170d5
[13/18] KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
        commit: 26117e4c636c813be4fa31e9ec9410b7d02ced5c
[14/18] KVM: arm64: Introduce __pkvm_host_test_clear_young_guest()
        commit: 56ab4de37f4e13231e964cf7fa304818f791fea7
[15/18] KVM: arm64: Introduce __pkvm_host_mkyoung_guest()
        commit: 76f0b18b3db57868fb0cabe691201aad3085b712
[16/18] KVM: arm64: Introduce __pkvm_tlb_flush_vmid()
        commit: 0adce4d42f249b1701c136907055d9b12f8f6e1c
[17/18] KVM: arm64: Introduce the EL1 pKVM MMU
        commit: e912efed485a4c50bdc3934ae647e257ef568ef6
[18/18] KVM: arm64: Plumb the pKVM MMU in KVM
        commit: fce886a6020734d6253c2c5a3bc285e385cc5496

Cheers,

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




From maz at kernel.org  Fri Dec 20 03:17:00 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Dec 2024 11:17:00 +0000
Subject: [PATCH v4 3/3] arm64: paravirt: Enable errata based on implementation CPUs
In-Reply-To: <Z2RapzikZQGgeE_6@linux.dev>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
	<20241218105345.73472-4-shameerali.kolothum.thodi@huawei.com>
	<86bjx8q995.wl-maz@kernel.org>
	<Z2RapzikZQGgeE_6@linux.dev>
Message-ID: <86v7veppsj.wl-maz@kernel.org>

On Thu, 19 Dec 2024 17:40:55 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> > Independent of this, I wonder what we should output in sysfs
> > (/sys/devices/system/cpu/cpu*/regs/identification/*).
> 
> It's a bit crap, but maybe implementation index 0 gets reported through
> the 'main' midr/revidr files, otherwise have a directory per
> implementation index of midr/revidr.

Having slept on that one, I'm starting to think that we should keep
the status-quo of reporting what the kernel snapshot at boot time.
There is no good reason to force the VMM to report the potential
implementations in any specific order.

The "alternative-implementations" is interesting, but we don't keep it
per-CPU, so I don't  think it fits the current scheme. But maybe
something in /sys/devices/system/cpu, outside of the cpu* hierarchy?

Either way, this isn't something we should worry too much right now.

Thanks,

	M.

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


From sudeep.holla at arm.com  Fri Dec 20 03:27:04 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 20 Dec 2024 11:27:04 +0000
Subject: [PATCH 1/3] dt-bindings: arm,psci: Allow S2RAM power_state
 parameter description
In-Reply-To: <54cc4221-ba5f-4741-9033-20874265ca01@oss.qualcomm.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
 <Z1LQOmEfFy640PjG@bogus>
 <54cc4221-ba5f-4741-9033-20874265ca01@oss.qualcomm.com>
Message-ID: <Z2VUiHWHgbWowdal@bogus>

On Thu, Dec 19, 2024 at 08:43:27PM +0100, Konrad Dybcio wrote:
> On 6.12.2024 11:21 AM, Sudeep Holla wrote:
> > On Mon, Oct 28, 2024 at 03:22:57PM +0100, Konrad Dybcio wrote:
> >> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> >>
> >> Certain firmware implementations (such as the ones found on Qualcomm
> >> SoCs between roughly 2015 and 2023) expose an S3-like S2RAM state
> >> through the CPU_SUSPEND call, as opposed to exposing PSCIv1.0's
> >> optional PSCI_SYSTEM_SUSPEND.
> >>
> > 
> > If so, can you elaborate why s2idle doesn't work as an alternative to what
> > you are hacking up here.
> 
> Please see other branches of this thread
> 
> > 
> >> This really doesn't work well with the model where we associate all
> >> calls to CPU_SUSPEND with cpuidle. Allow specifying a single special
> >> CPU_SUSPEND suspend parameter value that is to be treated just like
> >> SYSTEM_SUSPEND from the OS's point of view.
> >>
> >> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> >> ---
> >>  Documentation/devicetree/bindings/arm/psci.yaml | 6 ++++++
> >>  1 file changed, 6 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml
> >> index cbb012e217ab80c1ca88e611e7acc06c6d56fad0..a6901878697c8e1ec1cbfed62298ae3bc58f2501 100644
> >> --- a/Documentation/devicetree/bindings/arm/psci.yaml
> >> +++ b/Documentation/devicetree/bindings/arm/psci.yaml
> >> @@ -98,6 +98,12 @@ properties:
> >>        [1] Kernel documentation - ARM idle states bindings
> >>          Documentation/devicetree/bindings/cpu/idle-states.yaml
> >>  
> >> +  arm,psci-s2ram-param:
> >> +    $ref: /schemas/types.yaml#/definitions/uint32
> >> +    description:
> >> +      power_state parameter denoting the S2RAM/S3-like system suspend state
> > 
> > Yet another NACK as this corresponds to PSCI SYSTEM_SUSPEND and as per
> > specification it takes no such parameter. This is just misleading.
> > 
> 
> Yeah PSCI_SYSTEM_SUSPEND takes care of this on platforms that expose it.
>

And those that don't advertise/expose don't get to use, simple.

> DEN0022F.b Section 6.5. recommends that CPU_SUSPEND StateID includes
> a field for system-level power down states. This binding change only
> adds a way for DT-based platforms to associate such state with S2RAM
> suspend.
>

Sure, just use the CPU_SUSPEND bindings that already exist. No need to
define this as some special case if it is exposed as CPU_SUSPEND idle
state. Not sure why you want to do it differently. I understand the
need to handle it different in the kernel, but I don't understand to
define the new bindings for that. Just use the existing bindings for the
idle states. Again I see no exception for this case.

> That may be a bit Linux-specific whereas bindings are supposed to be
> OS-agnostic, but since we effectively want one PSCI state for deep
> suspend regardless of the OS, I would think this kind of hint is fine.
>

Exactly, that's the reason for not changing this into special case and
special binding for that special case created.

--
Regards,
Sudeep


From andre.draszik at linaro.org  Fri Dec 20 03:27:23 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 20 Dec 2024 11:27:23 +0000
Subject: [PATCH v2 0/3] Google Pixel 6 Pro support
Message-ID: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>

Hi,

This series enables support for Google Pixel 6 Pro.

Since Pixel 6 and Pixel 6 Pro use a different resolution display, we
now need to add explicit support for it, we can not piggyback on the
non-Pro version anymore. This means having to separate them into their
respective DTs, and provide one for each of them.
There are other differences between the two of course, like battery
design capacity, etc., but they don't matter at this stage due to
incomplete upstream support.

* dependency note *

Due to the renaming of the gs101-oriole.dts, this series will conflict
with any pending patches touching the same file. I have therefore based
this series on top of my USB series from
https://lore.kernel.org/r/20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01 at linaro.org
and the patch enabling framebuffer support for Pixel 6 from
https://lore.kernel.org/r/20241220-gs101-simplefb-oriole-v2-1-df60e566932a at linaro.org

* dependency note end *

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
Changes in v2:
- We now have a generic gs101-based Pixel board DT, which can work on
  any Pixel 6 / 6 Pro / 6a
- Pixel 6 (Pro) are overlays onto that one.
  This has the advantage that all boards can be supported without
  having to have a full copy of the DT for each of them. We still
  instruct kbuild to create merged DTBs (in addition to the DTBOs) so
  that existing scripts can keep working while giving the option to
  just apply the overlay before boot (e.g. by the bootloader).
- The binding has been updated according to the above points
- I've changed the simple-framebuffer node to specify the memory via
  memory-region instead of reg, as that avoids unnecessary duplication
  (of the size), and it avoids having to specify #address-cells
  and #size-cells in the chosen node (and duplicating this in the
  DTSO), which is otherwise necessary to keep dt_binding_check happy
  and DT validation working in general.
- sort overriding/extending nodes ordered by label name (Krzysztof)
- format patches with diff.renames=copies (Krzysztof)
- dependencies have been updated, see below
- Link to v1: https://lore.kernel.org/r/20241216-gs101-simplefb-v1-0-8ccad1830281 at linaro.org

---
Andr? Draszik (3):
      dt-bindings: arm: google: add gs101-raven and generic gs101-pixel
      arm64: dts: exynos: gs101-pixel: add generic gs101-based Pixel support
      arm64: dts: exynos: gs101-raven: add new board file

 Documentation/devicetree/bindings/arm/google.yaml  | 18 +++++++++---
 arch/arm64/boot/dts/exynos/google/Makefile         |  9 ++++--
 .../arm64/boot/dts/exynos/google/gs101-oriole.dtso | 33 ++++++++++++++++++++++
 .../{gs101-oriole.dts => gs101-pixel-generic.dts}  | 24 +++++++---------
 arch/arm64/boot/dts/exynos/google/gs101-raven.dtso | 33 ++++++++++++++++++++++
 5 files changed, 97 insertions(+), 20 deletions(-)
---
base-commit: f70ddfc479f2fac1d0b744148743c25ce1778f01
change-id: 20241216-gs101-simplefb-8aae80278ed7

Best regards,
-- 
Andr? Draszik <andre.draszik at linaro.org>



From andre.draszik at linaro.org  Fri Dec 20 03:27:24 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 20 Dec 2024 11:27:24 +0000
Subject: [PATCH v2 1/3] dt-bindings: arm: google: add gs101-raven and
 generic gs101-pixel
In-Reply-To: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
References: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
Message-ID: <20241220-gs101-simplefb-v2-1-c10a8f9e490b@linaro.org>

Raven is Google's code name for Pixel 6 Pro. Since there are
differences compared to Pixel 6 (Oriole), we need to add a separate
compatible for it.

We also want to support a generic DT, which can work on any type of
gs101-based Pixel device, e.g. Pixel 6, or Pixel 6 Pro, or Pixel 6a (as
a future addition). Such a DT will have certain nodes disabled / not
added. To facilitate such a generic gs101-based Pixel device, also add
a more generic gs101-pixel compatible. We can not just use the existing
google,gs101 for that, as it refers to the SoC, not a board.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
 Documentation/devicetree/bindings/arm/google.yaml | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/google.yaml b/Documentation/devicetree/bindings/arm/google.yaml
index e20b5c9b16bc..a8faf2256242 100644
--- a/Documentation/devicetree/bindings/arm/google.yaml
+++ b/Documentation/devicetree/bindings/arm/google.yaml
@@ -34,11 +34,21 @@ properties:
     const: '/'
   compatible:
     oneOf:
-      - description: Google Pixel 6 / Oriole
+      - description: Google GS101 Pixel devices, as generic Pixel, or Pixel 6
+          (Oriole), or 6 Pro (Raven)
+        minItems: 2
+        maxItems: 3
         items:
-          - enum:
-              - google,gs101-oriole
-          - const: google,gs101
+          enum:
+            - google,gs101-oriole
+            - google,gs101-raven
+            - google,gs101-pixel
+            - google,gs101
+        allOf:
+          - contains:
+              const: google,gs101-pixel
+          - contains:
+              const: google,gs101
 
   # Bootloader requires empty ect node to be present
   ect:

-- 
2.47.1.613.gc27f4b7a9f-goog



From andre.draszik at linaro.org  Fri Dec 20 03:27:25 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 20 Dec 2024 11:27:25 +0000
Subject: [PATCH v2 2/3] arm64: dts: exynos: gs101-pixel: add generic
 gs101-based Pixel support
In-Reply-To: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
References: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
Message-ID: <20241220-gs101-simplefb-v2-2-c10a8f9e490b@linaro.org>

In order to support Pixel 6 (Oriole), Pixel 6 Pro (Raven), and Pixel 6a
(Bluejay) correctly, we have to be able to distinguish them properly as
we add support for more features.

For example, Raven has a larger display. There are other differences,
like battery design capacity, etc.

To facilitate this, we create a generic gs101-based Pixel DT that can
work on any such gs101-based device. At the same time, we move the
Oriole specific parts that we have at the moment (display) into an
overlay, making it easy to add support for Raven and Bluejay in a
similar way.

Note1:
Despite being an overlay, we instruct kbuild to create a merged
gs101-oriole.dtb and a gs101-oriole.dtbo. This way existing scripts can
keep working, but it also gives the option to just apply the overlay
before boot (e.g. by the bootloader).

Note2:
I've changed the simple-framebuffer node to specify the memory via
memory-region instead of reg, as that avoids unnecessary duplication
(of the size), and it avoids having to specify #address-cells
and #size-cells in the chosen node (and duplicating this in the DTSO),
which is otherwise necessary to keep dt_binding_check happy and DT
validation working in general.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
---
Note: MAINTAINERS doesn't need updating, it covers this whole directory
---
 arch/arm64/boot/dts/exynos/google/Makefile         |  6 ++--
 .../arm64/boot/dts/exynos/google/gs101-oriole.dtso | 33 ++++++++++++++++++++++
 .../{gs101-oriole.dts => gs101-pixel-generic.dts}  | 24 +++++++---------
 3 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/google/Makefile b/arch/arm64/boot/dts/exynos/google/Makefile
index 0a6d5e1fe4ee..6e6b5319212a 100644
--- a/arch/arm64/boot/dts/exynos/google/Makefile
+++ b/arch/arm64/boot/dts/exynos/google/Makefile
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-dtb-$(CONFIG_ARCH_EXYNOS) += \
-	gs101-oriole.dtb \
+dtb-$(CONFIG_ARCH_EXYNOS) += gs101-pixel-generic.dtb
+
+gs101-oriole-dtbs := gs101-pixel-generic.dtb gs101-oriole.dtbo
+dtb-$(CONFIG_ARCH_EXYNOS) += gs101-oriole.dtb
diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dtso b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dtso
new file mode 100644
index 000000000000..43572039cd07
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dtso
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Oriole Device Tree
+ *
+ * Copyright 2021-2023 Google LLC
+ * Copyright 2023-2024 Linaro Ltd
+ */
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	model = "Oriole";
+	compatible = "google,gs101-oriole", "google,gs101-pixel", "google,gs101";
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <1>;
+
+		splash at fac00000 {
+			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
+			status = "okay";
+		};
+	};
+};
+
+&framebuffer0 {
+	width = <1080>;
+	height = <2400>;
+	stride = <(1080 * 4)>;
+	format = "a8r8g8b8";
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-pixel-generic.dts
similarity index 93%
rename from arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
rename to arch/arm64/boot/dts/exynos/google/gs101-pixel-generic.dts
index 4e1625e3fbb4..48dc37afcb86 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-pixel-generic.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Oriole Device Tree
+ * generic gs101-based Pixel Device Tree
  *
  * Copyright 2021-2023 Google LLC
  * Copyright 2023 Linaro Ltd - <peter.griffin at linaro.org>
@@ -15,30 +15,24 @@
 #include "gs101.dtsi"
 
 / {
-	model = "Oriole";
-	compatible = "google,gs101-oriole", "google,gs101";
+	model = "GS101-based Pixel or derivative";
+	compatible = "google,gs101-pixel", "google,gs101";
 
 	aliases {
 		serial0 = &serial_0;
 	};
 
 	chosen {
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges;
-
 		/* Bootloader expects bootargs specified otherwise it crashes */
 		bootargs = "";
 		stdout-path = &serial_0;
 
 		/* Use display framebuffer as setup by bootloader */
-		framebuffer0: framebuffer at fac00000 {
+		framebuffer0: framebuffer-0 {
 			compatible = "simple-framebuffer";
-			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
-			width = <1080>;
-			height = <2400>;
-			stride = <(1080 * 4)>;
-			format = "a8r8g8b8";
+			memory-region = <&cont_splash_mem>;
+			/* format properties to be added by board overlay */
+			status = "disabled";
 		};
 	};
 
@@ -86,8 +80,10 @@ ufs_0_fixed_vcc_reg: regulator-1 {
 
 	reserved-memory {
 		cont_splash_mem: splash at fac00000 {
-			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
+			/* size to be updated by board overlay */
+			reg = <0x0 0xfac00000 0x0>;
 			no-map;
+			status = "disabled";
 		};
 	};
 };

-- 
2.47.1.613.gc27f4b7a9f-goog



From andre.draszik at linaro.org  Fri Dec 20 03:27:26 2024
From: andre.draszik at linaro.org (=?utf-8?q?Andr=C3=A9_Draszik?=)
Date: Fri, 20 Dec 2024 11:27:26 +0000
Subject: [PATCH v2 3/3] arm64: dts: exynos: gs101-raven: add new board file
In-Reply-To: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
References: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
Message-ID: <20241220-gs101-simplefb-v2-3-c10a8f9e490b@linaro.org>

Raven is Google's code name for Pixel 6 Pro. Similar to Pixel 6
(Oriole), this is also based around its Tensor gs101 SoC.

For now, the relevant difference here is the display resolution:
1440 x 3120 instead of 1080 x 2400.

Create a new board file to reflect this difference.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>

---
Note: MAINTAINERS doesn't need updating, it covers this whole directory
---
 arch/arm64/boot/dts/exynos/google/Makefile         |  3 ++
 arch/arm64/boot/dts/exynos/google/gs101-raven.dtso | 33 ++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/Makefile b/arch/arm64/boot/dts/exynos/google/Makefile
index 6e6b5319212a..bc6d600fda84 100644
--- a/arch/arm64/boot/dts/exynos/google/Makefile
+++ b/arch/arm64/boot/dts/exynos/google/Makefile
@@ -4,3 +4,6 @@ dtb-$(CONFIG_ARCH_EXYNOS) += gs101-pixel-generic.dtb
 
 gs101-oriole-dtbs := gs101-pixel-generic.dtb gs101-oriole.dtbo
 dtb-$(CONFIG_ARCH_EXYNOS) += gs101-oriole.dtb
+
+gs101-raven-dtbs := gs101-pixel-generic.dtb gs101-raven.dtbo
+dtb-$(CONFIG_ARCH_EXYNOS) += gs101-raven.dtb
diff --git a/arch/arm64/boot/dts/exynos/google/gs101-raven.dtso b/arch/arm64/boot/dts/exynos/google/gs101-raven.dtso
new file mode 100644
index 000000000000..577f52a4fdad
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/google/gs101-raven.dtso
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Raven Device Tree
+ *
+ * Copyright 2021-2023 Google LLC
+ * Copyright 2023-2024 Linaro Ltd
+ */
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	model = "Raven";
+	compatible = "google,gs101-raven", "google,gs101-pixel", "google,gs101";
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <1>;
+
+		splash at fac00000 {
+			reg = <0x0 0xfac00000 (1440 * 3120 * 4)>;
+			status = "okay";
+		};
+	};
+};
+
+&framebuffer0 {
+	width = <1440>;
+	height = <3120>;
+	stride = <(1440 * 4)>;
+	format = "a8r8g8b8";
+	status = "okay";
+};

-- 
2.47.1.613.gc27f4b7a9f-goog



From suzuki.poulose at arm.com  Fri Dec 20 03:35:36 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 20 Dec 2024 11:35:36 +0000
Subject: [PATCH v3 0/9] coresight: change some driver' spinlock type to
 raw_spinlock_t
In-Reply-To: <Z2VJIh2+Z40bZi1e@e129823.arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
 <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>
 <Z2VJIh2+Z40bZi1e@e129823.arm.com>
Message-ID: <ac537889-dc0a-4d2e-870b-c5a33279633e@arm.com>

On 20/12/2024 10:38, Yeoreum Yun wrote:
> Hi Mike.
> 
>> Notably missing is the same changes for the etm3x driver. The ETMv3.x
>> and PTM1.x are supported by this driver, and these trace source
>> variants are also supported in perf in the cs_etm.c code.
> 
> But I wonder etmv3 needs to change. Because its spinlock is used only
> via sysfs enable/disable path.
> So, I think it doesn't need to change the lock type.

ETM3 can be used in perf mode, similar to the ETM4x.

So, you need to fix it as well.


> 
>> STM is also missing, though this is not directly enabled via perf -
>> but could perhaps run concurrently as it can be a target output for
>> ftrace.
> 
> Actually, I couldn't find out the path where
> the STM's lock could be grabbed under other raw_spin_lock (including csdev)
> If you don't mind would you let me the code path please?

STM can't be used in perf mode, and as such you may skip it.

Suzuki


> 
> Thanks
>> --
>> Mike Leach
>> Principal Engineer, ARM Ltd.
>> Manchester Design Centre. UK



From quic_manafm at quicinc.com  Fri Dec 20 03:38:38 2024
From: quic_manafm at quicinc.com (Manaf Meethalavalappu Pallikunhi)
Date: Fri, 20 Dec 2024 17:08:38 +0530
Subject: [PATCH v4 6/7] arm64: defconfig: enable cpu idle injection and
 cpu idle cooling device
In-Reply-To: <59e96784-9efc-4958-baf0-a51e766e47e8@kernel.org>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
 <20241217064856.2772305-7-quic_wasimn@quicinc.com>
 <59e96784-9efc-4958-baf0-a51e766e47e8@kernel.org>
Message-ID: <b98cc6ea-d215-2200-1537-1a53c2587c81@quicinc.com>


Hi Krzysztof,

Thank you for reviewing this patch.

On 12/18/2024 1:32 PM, Krzysztof Kozlowski wrote:
> On 17/12/2024 07:48, Wasim Nazir wrote:
>> From: Manaf Meethalavalappu Pallikunhi <quic_manafm at quicinc.com>
>>
>> Enable cpu idle injection framework and thermal cpu idle cooling device
>> to throttle the cpu by injecting idle cycle during high thermal condition.
> I know what they do, but why do we need it in the defconfig? This is not
> a product defconfig, just in case you mirrored downstream patches.

We believe these defconfigs serve as a generic framework rather than 
being tied to specific product features. Therefore, we have enabled them 
in the defconfig to ensure the end-to-end feature is available in the 
pristine upstream build. However, if you think this would introduce 
overhead for other products, we will exclude this patch in the next 
revision.

Best regards,

Manaf

> Best regards,
> Krzysztofthe


From sudeep.holla at arm.com  Fri Dec 20 03:39:46 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 20 Dec 2024 11:39:46 +0000
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on
 pre-SYSTEM_SUSPEND PSCI impls
In-Reply-To: <e4509104-c809-4d45-bdbb-a2d754a816db@oss.qualcomm.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241113165329590-0800.eberman@hu-eberman-lv.qualcomm.com>
 <e4509104-c809-4d45-bdbb-a2d754a816db@oss.qualcomm.com>
Message-ID: <Z2VXgkJ4x5TJTKJ_@bogus>

On Thu, Dec 19, 2024 at 08:26:51PM +0100, Konrad Dybcio wrote:
> On 14.11.2024 2:10 AM, Elliot Berman wrote:
>
> > I'm not sure why you'd like to support s2ram. Is it *only* that you'd
> > like to be able to set pm_set_supend/resume_via_firmware()? I hope this
> > doesn't sound silly: what if you register a platform_s2idle_ops for the
> > relevant SoCs which calls pm_set_suspend/resume_via_firwmare()?
>
> S2RAM is what you get after entering a certain state, but currently
> it's presented as just another (s2idle) idle state.
>

Just to be clear, I assume you mean CPU_SUSPEND idle state. There is
no special or different s2idle idle states IIUC.

> That means some hardware that may need to be reinitialized, isn't as
> Linux has no clue it might have lost power.
>

Interesting, so this means firmware doesn't automatically save and restore
states yet exposes it as CPU_SUSPEND idle state.

> One of such cases is the PCIe block, with storage drivers specifically
> looking for pm_suspend_via_firmware, but that's unfortunately not the
> whole list.
>

Well I can now imagine and I understand what's wrong here. An idle state
is exposed to OS with an expectation that OS saves and restores certain
state. Unless you tie it some other power domains that theses devices
share, it is hard for OS to know the state is being lost and it needs
to save and restore them. It is simple wrong to assume that OS needs
to take care of them even though the power domain hierarchy doesn't
represent this dependency to enter such a state. cpuidle-psci-domain.c
takes care of this IIUC. Ulf can provide details if you are interested.

--
Regards,
Sudeep


From yeoreum.yun at arm.com  Fri Dec 20 03:39:31 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 11:39:31 +0000
Subject: [PATCH v3 0/9] coresight: change some driver' spinlock type to
 raw_spinlock_t
In-Reply-To: <ac537889-dc0a-4d2e-870b-c5a33279633e@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
 <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>
 <Z2VJIh2+Z40bZi1e@e129823.arm.com>
 <ac537889-dc0a-4d2e-870b-c5a33279633e@arm.com>
Message-ID: <Z2VXc/R/nOLGz+Cg@e129823.arm.com>

Hi Suzuki,
> On 20/12/2024 10:38, Yeoreum Yun wrote:
> > Hi Mike.
> >
> > > Notably missing is the same changes for the etm3x driver. The ETMv3.x
> > > and PTM1.x are supported by this driver, and these trace source
> > > variants are also supported in perf in the cs_etm.c code.
> >
> > But I wonder etmv3 needs to change. Because its spinlock is used only
> > via sysfs enable/disable path.
> > So, I think it doesn't need to change the lock type.
>
> ETM3 can be used in perf mode, similar to the ETM4x.
>
> So, you need to fix it as well.

Yes. But etmv3's etmdata->spinlock doesn't used in perf path
its usage is only in sysfs interface path.
That's why I think it could skip too.

Thanks.


From d-gole at ti.com  Fri Dec 20 03:41:18 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Fri, 20 Dec 2024 17:11:18 +0530
Subject: [PATCH v4 1/4] firmware: ti_sci: Support transfers without
 response
In-Reply-To: <20241219-topic-am62-partialio-v6-12-b4-v4-1-1cb8eabd407e@baylibre.com>
References: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
 <20241219-topic-am62-partialio-v6-12-b4-v4-1-1cb8eabd407e@baylibre.com>
Message-ID: <20241220114118.uwi5bsefxnue46re@lcpd911>

On Dec 19, 2024 at 21:02:12 +0100, Markus Schneider-Pargmann wrote:
> Check the header flags if an response is expected or not. If it is not
> expected skip the receive part of ti_sci_do_xfer(). This prepares the
> driver for one-way messages as prepare_sleep for Partial-IO.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---
>  drivers/firmware/ti_sci.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> index 806a975fff22ae00ecb88587b2c47ba172120bc2..ec0c54935ac0d667323d98b86ac9d288b73be6aa 100644
> --- a/drivers/firmware/ti_sci.c
> +++ b/drivers/firmware/ti_sci.c
> @@ -398,10 +398,13 @@ static void ti_sci_put_one_xfer(struct ti_sci_xfers_info *minfo,
>  static inline int ti_sci_do_xfer(struct ti_sci_info *info,
>  				 struct ti_sci_xfer *xfer)
>  {
> +	struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;

I think it's best to sort this in order? so it will come below struct
device?

>  	int ret;
>  	int timeout;
>  	struct device *dev = info->dev;
>  	bool done_state = true;
> +	bool response_expected = !!(hdr->flags & (TI_SCI_FLAG_REQ_ACK_ON_PROCESSED |
> +						  TI_SCI_FLAG_REQ_ACK_ON_RECEIVED));
>  
>  	ret = mbox_send_message(info->chan_tx, &xfer->tx_message);
>  	if (ret < 0)
> @@ -409,6 +412,9 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
>  
>  	ret = 0;
>  
> +	if (!response_expected)
> +		goto no_response;
> +

I am not a very big fan of using goto here, it feels like we should be
more clear in our implementation and make the else part below more
specific by using `else if` and checking for more specific SYSTEM_XX
states. Then based on POWEROFF, skip any polling or whatever wait for
response.
Infact, with that we may not even need the response_expected part, but I
am okay keeping both checks in place just for the clarity in design.

>  	if (system_state <= SYSTEM_RUNNING) {
>  		/* And we wait for the response. */
>  		timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
> @@ -429,6 +435,7 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
>  		dev_err(dev, "Mbox timedout in resp(caller: %pS)\n",
>  			(void *)_RET_IP_);
>  

-- 
Best regards,
Dhruva Gole
Texas Instruments Incorporated


From robh at kernel.org  Fri Dec 20 03:43:57 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 20 Dec 2024 05:43:57 -0600
Subject: [PATCH v2 2/7] dt-bindings: PCI: dwc: rockchip: Add rk3576
 support
In-Reply-To: <20241220101551.3505917-3-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
 <20241220101551.3505917-3-kever.yang@rock-chips.com>
Message-ID: <173469503748.2890446.9450914997693920466.robh@kernel.org>


On Fri, 20 Dec 2024 18:15:46 +0800, Kever Yang wrote:
> rk3576 is using dwc controller, but use msi interrupt instead of its,
> so the msi-map is not required, and need to add a new 'msi' interrupt name.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
> ---
> 
> Changes in v2:
> - remove required 'msi-map'
> - add interrupt name 'msi'
> 
>  .../devicetree/bindings/pci/rockchip-dw-pcie-common.yaml      | 1 +
>  Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml   | 4 +---
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-ep.example.dtb: pcie-ep at fe150000: interrupt-names:5: 'msi' was expected
	from schema $id: http://devicetree.org/schemas/pci/rockchip-dw-pcie-ep.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-ep.example.dtb: pcie-ep at fe150000: interrupt-names:6: 'dma0' was expected
	from schema $id: http://devicetree.org/schemas/pci/rockchip-dw-pcie-ep.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-ep.example.dtb: pcie-ep at fe150000: interrupt-names:7: 'dma1' was expected
	from schema $id: http://devicetree.org/schemas/pci/rockchip-dw-pcie-ep.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-ep.example.dtb: pcie-ep at fe150000: interrupt-names:8: 'dma2' was expected
	from schema $id: http://devicetree.org/schemas/pci/rockchip-dw-pcie-ep.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-ep.example.dtb: pcie-ep at fe150000: Unevaluated properties are not allowed ('power-domains' was unexpected)
	from schema $id: http://devicetree.org/schemas/pci/rockchip-dw-pcie-ep.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241220101551.3505917-3-kever.yang at rock-chips.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 o.rempel at pengutronix.de  Fri Dec 20 03:46:55 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Fri, 20 Dec 2024 12:46:55 +0100
Subject: [PATCH v5] i2c: imx: support DMA defer probing
In-Reply-To: <f2690b83-b907-4ade-bb9d-daa0636c6786@pengutronix.de>
References: <b919e252-6ff4-4e55-9bd6-4d610dda5348@pengutronix.de>
 <Z2UeKZcpeRUt2OQ4@pengutronix.de>
 <AM0PR0402MB393739E1D91ED2A539B5A2C7E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <Z2Ugt8NVued0_4c4@pengutronix.de>
 <AM0PR0402MB3937419BBB58B75FB8F8DE2DE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b@pengutronix.de>
 <AM0PR0402MB39374CFFA66D8121DB218334E8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <451e8c12-7b45-4b12-af10-63f60ba6e92e@pengutronix.de>
 <AM0PR0402MB3937E87BBDC5CEA1C51E4E3AE8072@AM0PR0402MB3937.eurprd04.prod.outlook.com>
 <f2690b83-b907-4ade-bb9d-daa0636c6786@pengutronix.de>
Message-ID: <Z2VZLw0RGiEA68Nd@pengutronix.de>

On Fri, Dec 20, 2024 at 11:51:27AM +0100, Ahmad Fatoum wrote:
> Hi Carlos,
> 
> On 20.12.24 11:46, Carlos Song wrote:
> > 
> > 
> >> -----Original Message-----
> >> From: Ahmad Fatoum <a.fatoum at pengutronix.de>
> >> Sent: Friday, December 20, 2024 5:32 PM
> >> To: Carlos Song <carlos.song at nxp.com>; Oleksij Rempel
> 
> >> I know -110, but -12 I need to look up :) Both are cryptic to end users, which is
> >> why %pe was added on top of the existing %p:
> >>
> >> If CONFIG_SYMBOLIC_ERRNAME is enabled %pe expands to an error string, e.g.
> >> "ENOMEM" or "ETIMEDOUT". If it's disabled, you get the same error number
> >> that was printed raw before.
> >>
> >> Cheers,
> >> Ahmad
> >>
> > 
> > Wow! Looks so cool.
> > Thank you very much for your patient explanation! I agree it.
> > 
> > Also I will change the comment from your suggestion[1]:
> > 
> > "
> >   /*
> >    * As we can always fall back to PIO, let's ignore the error setting up
> >    * DMA and see if we run into errors while setting up PIO mode.
> >    */
> > "
> > In fact, other errors are also from DMA setting not from setting PIO mode.
> > So can I comment simply like this?
> > 
> >         /* As we can always fall back to PIO, let's ignore the error setting up DMA. */
> >         ret = i2c_imx_dma_request(i2c_imx, phy_addr);
> >         if (ret) {
> >                 if (ret == -EPROBE_DEFER)
> >                         goto clk_notifier_unregister;
> >                 else if (ret == -ENODEV)
> >                         dev_dbg(&pdev->dev, "Only use PIO mode\n");
> >                 else
> >                         dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n", ERR_PTR(ret));
> >         }
> > 
> > [1]https://lore.kernel.org/imx/89a3b1c9-2be2-4e7f-a0c6-abbf8b88957b at pengutronix.de/
> 
> Sure, looks good to me. @Oleksij?

Ack, looks good. Thank you!

-- 
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 zhengqi.arch at bytedance.com  Fri Dec 20 03:46:04 2024
From: zhengqi.arch at bytedance.com (Qi Zheng)
Date: Fri, 20 Dec 2024 19:46:04 +0800
Subject: [PATCH 01/10] mm: Move common parts of pagetable_*_[cd]tor to
 helpers
In-Reply-To: <75cb4ff8-eb0c-4519-a30a-f8be717ba278@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <20241219164425.2277022-2-kevin.brodsky@arm.com>
 <20241219171920.GB26279@noisy.programming.kicks-ass.net>
 <75cb4ff8-eb0c-4519-a30a-f8be717ba278@arm.com>
Message-ID: <0daabd32-cba4-4345-baa8-e8c66bc899ff@bytedance.com>

Hi Kevin,

On 2024/12/20 18:49, Kevin Brodsky wrote:
> Hi Peter, Qi,
> 
> On 19/12/2024 18:19, Peter Zijlstra wrote:
>> On Thu, Dec 19, 2024 at 04:44:16PM +0000, Kevin Brodsky wrote:
>>> Besides the ptlock management at PTE/PMD level, all the
>>> pagetable_*_[cd]tor have the same implementation. Introduce common
>>> helpers for all levels to reduce the duplication.
>> Uff, I forgot to Cc you on the discussion here, sorry!:
>>
>>    https://lkml.kernel.org/r/cover.1734526570.git.zhengqi.arch at bytedance.com
>>
>> we now have two series doing more or less overlapping things :/
>>
>> You can in fact trivially merge the all the implementations -- the
>> apparent non-common bit (ptlock_free) is a no-op for all those other
>> levels because they'll be having ptdesc->lock == NULL.
> 
> Ah that is good to know, thanks for letting me know about that and Qi's
> series! Fortunately there isn't that much overlap between our series - I
> think we can easily sort this out.
> 
> Qi, shall we collaborate to make our series complementary? I believe my
> series covers patch 2 and 4 of your series, but it goes further by
> covering all levels and all architectures, and patches introducing
> ctor/dtor are already split as Alexander suggested on your series. So my
> suggestion would be:
> 
> * Remove patch 1 in my series - I'd just introduce
> pagetable_{p4d,pgd}_[cd]tor with the same implementation as
> pagetable_pud_[cd]tor.
> * Remove patch 2 and 4 from your series and rebase it on mine.

I quickly went through your patch series. It looks like my patch 2 and
your patch 6 are duplicated, so you want me to remove my patch 2.

But I think you may not be able to simple let arm64, riscv and x86 to
use generic p4d_{alloc_one,free}(). Because even if
CONFIG_PGTABLE_LEVELS > 4, the pgtable_l5_enabled() may not be true.

For example, in arm64:

#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);
}

Did I miss something?

My patch series is not only for cleanup, but also for fixes of
UAF issue [1], so is it possible to rebase your patch series onto
mine? I can post v3 ASAP.

[1]. 
https://lore.kernel.org/all/67548279.050a0220.a30f1.015b.GAE at google.com/

Thanks!

> 
> Let me know if that makes sense, if so I'll post a v2.
> 
> Cheers,
> - Kevin


From suzuki.poulose at arm.com  Fri Dec 20 03:48:06 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 20 Dec 2024 11:48:06 +0000
Subject: [PATCH v3 0/9] coresight: change some driver' spinlock type to
 raw_spinlock_t
In-Reply-To: <Z2VXc/R/nOLGz+Cg@e129823.arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
 <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>
 <Z2VJIh2+Z40bZi1e@e129823.arm.com>
 <ac537889-dc0a-4d2e-870b-c5a33279633e@arm.com>
 <Z2VXc/R/nOLGz+Cg@e129823.arm.com>
Message-ID: <f0c15466-a27f-4cc2-90a1-476ec278d870@arm.com>

On 20/12/2024 11:39, Yeoreum Yun wrote:
> Hi Suzuki,
>> On 20/12/2024 10:38, Yeoreum Yun wrote:
>>> Hi Mike.
>>>
>>>> Notably missing is the same changes for the etm3x driver. The ETMv3.x
>>>> and PTM1.x are supported by this driver, and these trace source
>>>> variants are also supported in perf in the cs_etm.c code.
>>>
>>> But I wonder etmv3 needs to change. Because its spinlock is used only
>>> via sysfs enable/disable path.
>>> So, I think it doesn't need to change the lock type.
>>
>> ETM3 can be used in perf mode, similar to the ETM4x.
>>
>> So, you need to fix it as well.
> 
> Yes. But etmv3's etmdata->spinlock doesn't used in perf path
> its usage is only in sysfs interface path.
> That's why I think it could skip too.

Ok, which I think is a problem, since the sysfs mode could overwrite the 
"config" while perf is preparing the config from the event parsing.
And we would need it there. So, for the time being, we can accept this
series, pending other review comments and address this issue separately

Suzuki


> 
> Thanks.



From d-gole at ti.com  Fri Dec 20 03:50:43 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Fri, 20 Dec 2024 17:20:43 +0530
Subject: [PATCH v4 2/4] firmware: ti_sci: Partial-IO support
In-Reply-To: <20241219-topic-am62-partialio-v6-12-b4-v4-2-1cb8eabd407e@baylibre.com>
References: <20241219-topic-am62-partialio-v6-12-b4-v4-0-1cb8eabd407e@baylibre.com>
 <20241219-topic-am62-partialio-v6-12-b4-v4-2-1cb8eabd407e@baylibre.com>
Message-ID: <20241220115043.qhjroeqc4gl3pwtz@lcpd911>

Hi Markus,

On Dec 19, 2024 at 21:02:13 +0100, Markus Schneider-Pargmann wrote:
> Add support for Partial-IO poweroff. In Partial-IO pins of a few

Maybe add a comma after the In partial-IO, a few pins in this SOC can generate....

> hardware units can generate system wakeups while DDR memory is not
> powered resulting in a fresh boot of the system. These hardware units in
> the SoC are always powered so that some logic can detect pin activity.
> 
> If the system supports Partial-IO as described in the fw capabilities, a
> sys_off handler is added. This sys_off handler decides if the poweroff
> is executed by entering normal poweroff or Partial-IO instead. The
> decision is made by checking if wakeup is enabled on all devices that
> may wake up the SoC from Partial-IO.
> 
> The possible wakeup devices are found by checking which devices have the
> "poweroff" in the list of wakeup-source power states. Only devices that
> are actually enabled by the user will be considered as an active wakeup
> source. If none of the wakeup sources is enabled the system will do a
> normal poweroff. If at least one wakeup source is enabled it will
> instead send a TI_SCI_MSG_PREPARE_SLEEP message from the sys_off
> handler. Sending this message will result in an immediate shutdown of
> the system. No execution is expected after this point. The code will
> wait for 5s and do an emergency_restart afterwards if Partial-IO wasn't
> entered at that point.
> 
> A short documentation about Partial-IO can be found in section 6.2.4.5
> of the TRM at
>   https://www.ti.com/lit/pdf/spruiv7
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---
>  drivers/firmware/ti_sci.c | 115 +++++++++++++++++++++++++++++++++++++++++++++-
>  drivers/firmware/ti_sci.h |   5 ++
>  2 files changed, 119 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> index ec0c54935ac0d667323d98b86ac9d288b73be6aa..693ac816f8ba3941a9156bd39524099ca476d712 100644
> --- a/drivers/firmware/ti_sci.c
> +++ b/drivers/firmware/ti_sci.c
> @@ -3746,6 +3746,100 @@ static const struct dev_pm_ops ti_sci_pm_ops = {
>  #endif
>  };
>  
> +/*
> + * Enter Partial-IO, which disables everything including DDR with only a small
> + * logic being active for wakeup.
> + */
> +static int tisci_enter_partial_io(struct ti_sci_info *info)

Isn't the function naming style in the driver ti_sci_XXX ? You're
missing one `_` I guess

> +{
> +	struct ti_sci_msg_req_prepare_sleep *req;
> +	struct ti_sci_xfer *xfer;
> +	struct device *dev = info->dev;
> +	int ret = 0;
> +
> +	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PREPARE_SLEEP,
> +				   TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
> +				   sizeof(*req), sizeof(struct ti_sci_msg_hdr));
> +	if (IS_ERR(xfer)) {
> +		ret = PTR_ERR(xfer);
> +		dev_err(dev, "Message alloc failed(%d)\n", ret);
> +		return ret;
> +	}
> +
> +	req = (struct ti_sci_msg_req_prepare_sleep *)xfer->xfer_buf;
> +	req->mode = TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO;
> +	req->ctx_lo = 0;
> +	req->ctx_hi = 0;
> +	req->debug_flags = 0;
> +
> +	dev_info(dev, "Entering Partial-IO because a powered wakeup-enabled device was found.\n");
> +
> +	ret = ti_sci_do_xfer(info, xfer);
> +	if (ret) {
> +		dev_err(dev, "Mbox send fail %d\n", ret);
> +		goto fail;
> +	}
> +
> +fail:
> +	ti_sci_put_one_xfer(&info->minfo, xfer);
> +
> +	return ret;
> +}
> +
> +static bool tisci_canuart_wakeup_enabled(struct ti_sci_info *info)

Add some documentation around this please.

> +{
> +	struct device_node *wakeup_node = NULL;
> +
> +	for (wakeup_node = of_find_node_with_property(NULL, "wakeup-source");
> +	     wakeup_node;
> +	     wakeup_node = of_find_node_with_property(wakeup_node, "wakeup-source")) {
> +		struct platform_device *pdev;
> +		int index;
> +
> +		index = of_property_match_string(wakeup_node, "wakeup-source", "poweroff");
> +		if (index < 0)
> +			continue;

Doesn't the fact that we're inside the for loop already ensure this is > 0?

> +
> +		pdev = of_find_device_by_node(wakeup_node);
> +		if (!pdev)
> +			break;

Same here? Would we otherwise be in the loop?
Just having a quick look here, I could be wrong, please just check once.



-- 
Best regards,
Dhruva Gole
Texas Instruments Incorporated


From yeoreum.yun at arm.com  Fri Dec 20 03:50:39 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Fri, 20 Dec 2024 11:50:39 +0000
Subject: [PATCH v3 0/9] coresight: change some driver' spinlock type to
 raw_spinlock_t
In-Reply-To: <f0c15466-a27f-4cc2-90a1-476ec278d870@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
 <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>
 <Z2VJIh2+Z40bZi1e@e129823.arm.com>
 <ac537889-dc0a-4d2e-870b-c5a33279633e@arm.com>
 <Z2VXc/R/nOLGz+Cg@e129823.arm.com>
 <f0c15466-a27f-4cc2-90a1-476ec278d870@arm.com>
Message-ID: <Z2VaD0K+jNaFYmbn@e129823.arm.com>

Hi Suzuki,

> > > >
> > > > > Notably missing is the same changes for the etm3x driver. The ETMv3.x
> > > > > and PTM1.x are supported by this driver, and these trace source
> > > > > variants are also supported in perf in the cs_etm.c code.
> > > >
> > > > But I wonder etmv3 needs to change. Because its spinlock is used only
> > > > via sysfs enable/disable path.
> > > > So, I think it doesn't need to change the lock type.
> > >
> > > ETM3 can be used in perf mode, similar to the ETM4x.
> > >
> > > So, you need to fix it as well.
> >
> > Yes. But etmv3's etmdata->spinlock doesn't used in perf path
> > its usage is only in sysfs interface path.
> > That's why I think it could skip too.
>
> Ok, which I think is a problem, since the sysfs mode could overwrite the
> "config" while perf is preparing the config from the event parsing.
> And we would need it there. So, for the time being, we can accept this
> series, pending other review comments and address this issue separately

Agree. also it has the same problem in etm4.
I have a patchset for etm3/etm4 for this. but it's based on this series.
So, after this patch is mereged. I'll send related patch.
Thanks.


From pbrobinson at gmail.com  Fri Dec 20 04:00:29 2024
From: pbrobinson at gmail.com (Peter Robinson)
Date: Fri, 20 Dec 2024 12:00:29 +0000
Subject: [PATCH v2 0/2] Add support for WiFi/BT header on Pine64 A64
Message-ID: <20241220120038.3137248-1-pbrobinson@gmail.com>

Add the BT and WiFi pins on the WiFi/BT header on the Pine64/Sopine
boards.

Changes in v2:
- drop patch that enables the WiFi module, it'll move to a overlay later

Peter Robinson (2):
  arm64: dts: allwinner: a64: Add WiFi/BT header on Pine64
  arm64: dts: allwinner: a64: Add WiFi/BT header on SoPine

 .../boot/dts/allwinner/sun50i-a64-pine64.dts  | 17 +++++++++++++
 .../allwinner/sun50i-a64-sopine-baseboard.dts | 24 +++++++++++++++++++
 2 files changed, 41 insertions(+)

-- 
2.47.1



From pbrobinson at gmail.com  Fri Dec 20 04:00:30 2024
From: pbrobinson at gmail.com (Peter Robinson)
Date: Fri, 20 Dec 2024 12:00:30 +0000
Subject: [PATCH v2 1/2] arm64: dts: allwinner: a64: Add WiFi/BT header on Pine64
In-Reply-To: <20241220120038.3137248-1-pbrobinson@gmail.com>
References: <20241220120038.3137248-1-pbrobinson@gmail.com>
Message-ID: <20241220120038.3137248-2-pbrobinson@gmail.com>

This adds all the pin mappings on the WiFi/BT header on
the original Pine64. They're disabled by default as the
modules don't ship by default. This includes, where they
haven't been already, UART1 for BT and mmc1 for WiFi.

Signed-off-by: Peter Robinson <pbrobinson at gmail.com>
---
 .../boot/dts/allwinner/sun50i-a64-pine64.dts    | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 09e71fd60785..f04f0f1badc4 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -35,6 +35,11 @@ hdmi_con_in: endpoint {
 			};
 		};
 	};
+
+	wifi_pwrseq: pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
+	};
 };
 
 &codec {
@@ -124,6 +129,17 @@ &mmc0 {
 	status = "okay";
 };
 
+/* On Wifi/BT connector */
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	vmmc-supply = <&reg_dldo4>;
+	vqmmc-supply = <&reg_eldo1>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+};
+
 &ohci0 {
 	status = "okay";
 };
@@ -286,6 +302,7 @@ &uart0 {
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+	uart-has-rtscts;
 	status = "disabled";
 };
 
-- 
2.47.1



From pbrobinson at gmail.com  Fri Dec 20 04:00:31 2024
From: pbrobinson at gmail.com (Peter Robinson)
Date: Fri, 20 Dec 2024 12:00:31 +0000
Subject: [PATCH v2 2/2] arm64: dts: allwinner: a64: Add WiFi/BT header on SoPine
In-Reply-To: <20241220120038.3137248-1-pbrobinson@gmail.com>
References: <20241220120038.3137248-1-pbrobinson@gmail.com>
Message-ID: <20241220120038.3137248-3-pbrobinson@gmail.com>

This adds all the pin mappings on the WiFi/BT header on
the SoPine baseboard/A64-LTS. They're disabled by default
as the modules don't ship by default. This includes, where
they haven't been already, UART1 for BT and mmc1 for WiFi.

Signed-off-by: Peter Robinson <pbrobinson at gmail.com>
---
 .../allwinner/sun50i-a64-sopine-baseboard.dts | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
index be2347c8f267..752d2aae8465 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -42,6 +42,11 @@ reg_vcc1v8: vcc1v8 {
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
+
+	wifi_pwrseq: pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
+	};
 };
 
 &ac_power_supply {
@@ -103,6 +108,17 @@ ext_rgmii_phy: ethernet-phy at 1 {
 	};
 };
 
+/* On Wifi/BT connector */
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	vmmc-supply = <&reg_dldo4>;
+	vqmmc-supply = <&reg_eldo1>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+};
+
 &mmc2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc2_pins>;
@@ -175,6 +191,14 @@ &uart0 {
 	status = "okay";
 };
 
+/* On Wifi/BT connector, with RTS/CTS */
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+	uart-has-rtscts;
+	status = "disabled";
+};
+
 /* On Pi-2 connector */
 &uart2 {
 	pinctrl-names = "default";
-- 
2.47.1



From mkl at pengutronix.de  Fri Dec 20 04:06:01 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 20 Dec 2024 13:06:01 +0100
Subject: [PATCH v2 1/2] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20241219011159.3357530-2-zhangqing@rock-chips.com>
References: <20241219011159.3357530-1-zhangqing@rock-chips.com>
 <20241219011159.3357530-2-zhangqing@rock-chips.com>
Message-ID: <20241219-sapphire-vicugna-of-opposition-be748f-mkl@pengutronix.de>

On 19.12.2024 09:11:58, Elaine Zhang wrote:
> Is new controller:
> Support CAN and CANFD protocol.
> 
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>

Thanks for porting the rk3576 to the mainline driver. Looking at subtle
differences between the IP cores I'm not sure if you want to add it to
the existing driver or have a dedicated driver. But we can decide on
this later. At least the mainline driver has a better structure than
your original downstream driver.

Why was the timestamp register removed from the registers? Previously
the driver supported hardware timestamping. :(

Some general comments here, a more detailed review will follow.

Why have bits been removed from several registers and the remaining ones
moved? That doesn't make it easier for driver developers to cover new IP
cores. :(

Please use FIELD_GET(), FIELD_PREP() macros instead of open coding shift
and mask operations. See rest of the driver.

Have you actually tested this code in both RX and TX direction? I don't
see rkcanfd_handle_tx_int() being called?

What's the purpose of "rockchip,rx-max-data"?

Why do you add "rx_fifo_depth" to "struct rkcanfd_priv"? It's not used
outside of rkcanfd_probe().

Can you configure the IP core for CAN-2.0 only mode, so that it only
receives CAN-2.0 frames only?

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/20241220/c745d024/attachment.sig>

From ilias.apalodimas at linaro.org  Fri Dec 20 04:29:19 2024
From: ilias.apalodimas at linaro.org (Ilias Apalodimas)
Date: Fri, 20 Dec 2024 14:29:19 +0200
Subject: [PATCH RFCv5 1/8] page_pool: introduce page_pool_to_pp() API
In-Reply-To: <20241213122739.4050137-2-linyunsheng@huawei.com>
References: <20241213122739.4050137-1-linyunsheng@huawei.com> <20241213122739.4050137-2-linyunsheng@huawei.com>
Message-ID: <CAC_iWj+3Q7CAS3xH9+zWA7nXdFNSJ-XMKQB3ZT0YvUQ-Q2gMCQ@mail.gmail.com>

Hi Yunsheng,

On Fri, 13 Dec 2024 at 14:35, Yunsheng Lin <linyunsheng at huawei.com> wrote:
>
> introduce page_pool_to_pp() API to avoid caller accessing
> page->pp directly.
>

I think we already have way too many abstractions, I'd say we need
less not more. I don't know what others think, but I don't see what we
gain from this

Thanks
/Ilias
> Signed-off-by: Yunsheng Lin <linyunsheng at huawei.com>
> ---
>  drivers/net/ethernet/freescale/fec_main.c          |  8 +++++---
>  .../net/ethernet/google/gve/gve_buffer_mgmt_dqo.c  |  2 +-
>  drivers/net/ethernet/intel/iavf/iavf_txrx.c        |  6 ++++--
>  drivers/net/ethernet/intel/idpf/idpf_txrx.c        | 14 +++++++++-----
>  drivers/net/ethernet/intel/libeth/rx.c             |  2 +-
>  drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c   |  3 ++-
>  drivers/net/netdevsim/netdev.c                     |  6 ++++--
>  drivers/net/wireless/mediatek/mt76/mt76.h          |  2 +-
>  include/net/libeth/rx.h                            |  3 ++-
>  include/net/page_pool/helpers.h                    |  5 +++++
>  net/core/skbuff.c                                  |  3 ++-
>  net/core/xdp.c                                     |  3 ++-
>  12 files changed, 38 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
> index 1b55047c0237..98fce41d088c 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -1009,7 +1009,8 @@ static void fec_enet_bd_init(struct net_device *dev)
>                                 struct page *page = txq->tx_buf[i].buf_p;
>
>                                 if (page)
> -                                       page_pool_put_page(page->pp, page, 0, false);
> +                                       page_pool_put_page(page_pool_to_pp(page),
> +                                                          page, 0, false);
>                         }
>
>                         txq->tx_buf[i].buf_p = NULL;
> @@ -1549,7 +1550,7 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
>                         xdp_return_frame_rx_napi(xdpf);
>                 } else { /* recycle pages of XDP_TX frames */
>                         /* The dma_sync_size = 0 as XDP_TX has already synced DMA for_device */
> -                       page_pool_put_page(page->pp, page, 0, true);
> +                       page_pool_put_page(page_pool_to_pp(page), page, 0, true);
>                 }
>
>                 txq->tx_buf[index].buf_p = NULL;
> @@ -3311,7 +3312,8 @@ static void fec_enet_free_buffers(struct net_device *ndev)
>                         } else {
>                                 struct page *page = txq->tx_buf[i].buf_p;
>
> -                               page_pool_put_page(page->pp, page, 0, false);
> +                               page_pool_put_page(page_pool_to_pp(page),
> +                                                  page, 0, false);
>                         }
>
>                         txq->tx_buf[i].buf_p = NULL;
> diff --git a/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c b/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c
> index 403f0f335ba6..db5926152c72 100644
> --- a/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c
> +++ b/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c
> @@ -210,7 +210,7 @@ void gve_free_to_page_pool(struct gve_rx_ring *rx,
>         if (!page)
>                 return;
>
> -       page_pool_put_full_page(page->pp, page, allow_direct);
> +       page_pool_put_full_page(page_pool_to_pp(page), page, allow_direct);
>         buf_state->page_info.page = NULL;
>  }
>
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
> index 26b424fd6718..658d8f9a6abb 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
> @@ -1050,7 +1050,8 @@ static void iavf_add_rx_frag(struct sk_buff *skb,
>                              const struct libeth_fqe *rx_buffer,
>                              unsigned int size)
>  {
> -       u32 hr = rx_buffer->page->pp->p.offset;
> +       struct page_pool *pool = page_pool_to_pp(rx_buffer->page);
> +       u32 hr = pool->p.offset;
>
>         skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page,
>                         rx_buffer->offset + hr, size, rx_buffer->truesize);
> @@ -1067,7 +1068,8 @@ static void iavf_add_rx_frag(struct sk_buff *skb,
>  static struct sk_buff *iavf_build_skb(const struct libeth_fqe *rx_buffer,
>                                       unsigned int size)
>  {
> -       u32 hr = rx_buffer->page->pp->p.offset;
> +       struct page_pool *pool = page_pool_to_pp(rx_buffer->page);
> +       u32 hr = pool->p.offset;
>         struct sk_buff *skb;
>         void *va;
>
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> index da2a5becf62f..38ad32678bcc 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> @@ -385,7 +385,8 @@ static void idpf_rx_page_rel(struct libeth_fqe *rx_buf)
>         if (unlikely(!rx_buf->page))
>                 return;
>
> -       page_pool_put_full_page(rx_buf->page->pp, rx_buf->page, false);
> +       page_pool_put_full_page(page_pool_to_pp(rx_buf->page), rx_buf->page,
> +                               false);
>
>         rx_buf->page = NULL;
>         rx_buf->offset = 0;
> @@ -3097,7 +3098,8 @@ idpf_rx_process_skb_fields(struct idpf_rx_queue *rxq, struct sk_buff *skb,
>  void idpf_rx_add_frag(struct idpf_rx_buf *rx_buf, struct sk_buff *skb,
>                       unsigned int size)
>  {
> -       u32 hr = rx_buf->page->pp->p.offset;
> +       struct page_pool *pool = page_pool_to_pp(rx_buf->page);
> +       u32 hr = pool->p.offset;
>
>         skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buf->page,
>                         rx_buf->offset + hr, size, rx_buf->truesize);
> @@ -3129,8 +3131,10 @@ static u32 idpf_rx_hsplit_wa(const struct libeth_fqe *hdr,
>         if (!libeth_rx_sync_for_cpu(buf, copy))
>                 return 0;
>
> -       dst = page_address(hdr->page) + hdr->offset + hdr->page->pp->p.offset;
> -       src = page_address(buf->page) + buf->offset + buf->page->pp->p.offset;
> +       dst = page_address(hdr->page) + hdr->offset +
> +               page_pool_to_pp(hdr->page)->p.offset;
> +       src = page_address(buf->page) + buf->offset +
> +               page_pool_to_pp(buf->page)->p.offset;
>         memcpy(dst, src, LARGEST_ALIGN(copy));
>
>         buf->offset += copy;
> @@ -3148,7 +3152,7 @@ static u32 idpf_rx_hsplit_wa(const struct libeth_fqe *hdr,
>   */
>  struct sk_buff *idpf_rx_build_skb(const struct libeth_fqe *buf, u32 size)
>  {
> -       u32 hr = buf->page->pp->p.offset;
> +       u32 hr = page_pool_to_pp(buf->page)->p.offset;
>         struct sk_buff *skb;
>         void *va;
>
> diff --git a/drivers/net/ethernet/intel/libeth/rx.c b/drivers/net/ethernet/intel/libeth/rx.c
> index f20926669318..385afca0e61d 100644
> --- a/drivers/net/ethernet/intel/libeth/rx.c
> +++ b/drivers/net/ethernet/intel/libeth/rx.c
> @@ -207,7 +207,7 @@ EXPORT_SYMBOL_NS_GPL(libeth_rx_fq_destroy, LIBETH);
>   */
>  void libeth_rx_recycle_slow(struct page *page)
>  {
> -       page_pool_recycle_direct(page->pp, page);
> +       page_pool_recycle_direct(page_pool_to_pp(page), page);
>  }
>  EXPORT_SYMBOL_NS_GPL(libeth_rx_recycle_slow, LIBETH);
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
> index 94b291662087..78866b5473da 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
> @@ -716,7 +716,8 @@ static void mlx5e_free_xdpsq_desc(struct mlx5e_xdpsq *sq,
>                                 /* No need to check ((page->pp_magic & ~0x3UL) == PP_SIGNATURE)
>                                  * as we know this is a page_pool page.
>                                  */
> -                               page_pool_recycle_direct(page->pp, page);
> +                               page_pool_recycle_direct(page_pool_to_pp(page),
> +                                                        page);
>                         } while (++n < num);
>
>                         break;
> diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
> index 0be47fed4efc..088f4836a0e2 100644
> --- a/drivers/net/netdevsim/netdev.c
> +++ b/drivers/net/netdevsim/netdev.c
> @@ -632,7 +632,8 @@ nsim_pp_hold_write(struct file *file, const char __user *data,
>                 if (!ns->page)
>                         ret = -ENOMEM;
>         } else {
> -               page_pool_put_full_page(ns->page->pp, ns->page, false);
> +               page_pool_put_full_page(page_pool_to_pp(ns->page), ns->page,
> +                                       false);
>                 ns->page = NULL;
>         }
>         rtnl_unlock();
> @@ -831,7 +832,8 @@ void nsim_destroy(struct netdevsim *ns)
>
>         /* Put this intentionally late to exercise the orphaning path */
>         if (ns->page) {
> -               page_pool_put_full_page(ns->page->pp, ns->page, false);
> +               page_pool_put_full_page(page_pool_to_pp(ns->page), ns->page,
> +                                       false);
>                 ns->page = NULL;
>         }
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> index 0b75a45ad2e8..94a277290909 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -1688,7 +1688,7 @@ static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
>  {
>         struct page *page = virt_to_head_page(buf);
>
> -       page_pool_put_full_page(page->pp, page, allow_direct);
> +       page_pool_put_full_page(page_pool_to_pp(page), page, allow_direct);
>  }
>
>  static inline void *
> diff --git a/include/net/libeth/rx.h b/include/net/libeth/rx.h
> index 43574bd6612f..beee7ddd77a5 100644
> --- a/include/net/libeth/rx.h
> +++ b/include/net/libeth/rx.h
> @@ -137,7 +137,8 @@ static inline bool libeth_rx_sync_for_cpu(const struct libeth_fqe *fqe,
>                 return false;
>         }
>
> -       page_pool_dma_sync_for_cpu(page->pp, page, fqe->offset, len);
> +       page_pool_dma_sync_for_cpu(page_pool_to_pp(page), page, fqe->offset,
> +                                  len);
>
>         return true;
>  }
> diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
> index 793e6fd78bc5..1659f1995985 100644
> --- a/include/net/page_pool/helpers.h
> +++ b/include/net/page_pool/helpers.h
> @@ -83,6 +83,11 @@ static inline u64 *page_pool_ethtool_stats_get(u64 *data, const void *stats)
>  }
>  #endif
>
> +static inline struct page_pool *page_pool_to_pp(struct page *page)
> +{
> +       return page->pp;
> +}
> +
>  /**
>   * page_pool_dev_alloc_pages() - allocate a page.
>   * @pool:      pool from which to allocate
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 6841e61a6bd0..54e8e7cf2bc9 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -1033,7 +1033,8 @@ bool napi_pp_put_page(netmem_ref netmem)
>         if (unlikely(!is_pp_netmem(netmem)))
>                 return false;
>
> -       page_pool_put_full_netmem(netmem_get_pp(netmem), netmem, false);
> +       page_pool_put_full_netmem(page_pool_to_pp(netmem_to_page(netmem)),
> +                                 netmem, false);
>
>         return true;
>  }
> diff --git a/net/core/xdp.c b/net/core/xdp.c
> index bcc5551c6424..e8582036b411 100644
> --- a/net/core/xdp.c
> +++ b/net/core/xdp.c
> @@ -384,7 +384,8 @@ void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct,
>                 /* No need to check ((page->pp_magic & ~0x3UL) == PP_SIGNATURE)
>                  * as mem->type knows this a page_pool page
>                  */
> -               page_pool_put_full_page(page->pp, page, napi_direct);
> +               page_pool_put_full_page(page_pool_to_pp(page), page,
> +                                       napi_direct);
>                 break;
>         case MEM_TYPE_PAGE_SHARED:
>                 page_frag_free(data);
> --
> 2.33.0
>


From will at kernel.org  Fri Dec 20 04:35:27 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 20 Dec 2024 12:35:27 +0000
Subject: =?utf-8?Q?=E2=9D=8C_FAIL=3A_Test_repor?= =?utf-8?Q?t?= for
 for-kernelci (6.13.0-rc3, upstream-arm-next, 06a57361)
In-Reply-To: <64955.124121918121002524@us-mta-554.us.mimecast.lan>
References: <64955.124121918121002524@us-mta-554.us.mimecast.lan>
Message-ID: <20241220123526.GA26697@willie-the-truck>

On Thu, Dec 19, 2024 at 11:12:08PM -0000, cki-project at redhat.com wrote:
> Hi, we tested your kernel and here are the results:
> 
>     Overall result: FAILED
>              Merge: OK
>            Compile: OK
>               Test: FAILED (Did not boot)
> 
> 
> 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/redhat:1596629923
> 
> One or more kernel builds failed:
>     Builds that are failing to boot:
>          aarch64 - https://datawarehouse.cki-project.org/kcidb/builds/redhat:1596629923-aarch64-kernel

Hmm, I can't find any console logs here. Did the machines really fail that
early?

Will


From ciprianmarian.costea at oss.nxp.com  Fri Dec 20 04:39:15 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri, 20 Dec 2024 14:39:15 +0200
Subject: [PATCH v4 3/4] arm64: dts: s32g: include necessary 'EVB/RDB' common board dtsi
In-Reply-To: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
References: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241220123916.1452582-4-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

After the 'S32G2/S32G3' common 'EVB' and 'RDB' dtsi support addition,
include the necessary header depending on board flavour.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 arch/arm64/boot/dts/freescale/s32g274a-evb.dts  | 1 +
 arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts | 1 +
 arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
index b9a119eea2b7..c4a195dd67bf 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s32g2.dtsi"
+#include "s32gxxxa-evb.dtsi"
 
 / {
 	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
index aaa61a8ad0da..b5ba51696f43 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s32g2.dtsi"
+#include "s32gxxxa-rdb.dtsi"
 
 / {
 	model = "NXP S32G2 Reference Design Board 2 (S32G-VNP-RDB2)";
diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
index 828e353455b5..94f531be4017 100644
--- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
+++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
@@ -8,6 +8,7 @@
 /dts-v1/;
 
 #include "s32g3.dtsi"
+#include "s32gxxxa-rdb.dtsi"
 
 / {
 	model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Fri Dec 20 04:39:16 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri, 20 Dec 2024 14:39:16 +0200
Subject: [PATCH v4 4/4] arm64: dts: s32g399a-rdb3: Add INA231 sensor entry over I2C4
In-Reply-To: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
References: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241220123916.1452582-5-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

On S32G399A-RDB3 boards, an INA231 current sensor is connected over
I2C4 bus.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
index 94f531be4017..5f8739c068c6 100644
--- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
+++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
@@ -40,6 +40,14 @@ &uart1 {
 	status = "okay";
 };
 
+&i2c4 {
+	ina231 at 40 {
+		compatible = "ti,ina231";
+		reg = <0x40>;
+		shunt-resistor = <1000>;
+	};
+};
+
 &usdhc0 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz";
 	pinctrl-0 = <&pinctrl_usdhc0>;
-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Fri Dec 20 04:39:12 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri, 20 Dec 2024 14:39:12 +0200
Subject: [PATCH v4 0/4] add I2C DTS support for S32G2/S32G3 SoCs
Message-ID: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

This patchset aims to add two changes to the S32G2/S32G3 dtsi support:
- Adding I2C dts support for S32G SoC based boards
- Centralize the common part of 'S32G-EVB' and 'S32G-RDB' board revisions
into dtsi files. This refactor will serve I2C in this patchset, but in the
future it will also be used for other modules such as : FlexCAN and DSPI.

Changes in V4:
- Moved I2C nodes '#address-size' and '#address-cells' entries from board
common level to S32G2/S32G3 SoC level.

Changes in V3:
- Separated patchset into multiple stages: common 'I2C' dts entries, board
'I2C' dts entries and the introduction of common 'S32GXXXA-EVB/RDB' dtsi.
- Added missing changelog for V2 of this patchset

Changes in V2:
- Moved I2C end device '#address-size' and '#address-cells' entries from
board dts to common 's32gxxxa-evb/rdb' common dtsi.

Ciprian Marian Costea (4):
  arm64: dts: s32g: add 'I2C' common board support
  arm64: dts: s32g: add common 'S32G-EVB' and 'S32G-RDB' board support
  arm64: dts: s32g: include necessary 'EVB/RDB' common board dtsi
  arm64: dts: s32g399a-rdb3: Add INA231 sensor entry over I2C4

 arch/arm64/boot/dts/freescale/s32g2.dtsi      |  55 +++++++
 .../arm64/boot/dts/freescale/s32g274a-evb.dts |   1 +
 .../boot/dts/freescale/s32g274a-rdb2.dts      |   1 +
 arch/arm64/boot/dts/freescale/s32g3.dtsi      |  60 +++++++
 .../boot/dts/freescale/s32g399a-rdb3.dts      |   9 ++
 .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
 .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 122 ++++++++++++++
 7 files changed, 398 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi

-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Fri Dec 20 04:39:13 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri, 20 Dec 2024 14:39:13 +0200
Subject: [PATCH v4 1/4] arm64: dts: s32g: add 'I2C' common board support
In-Reply-To: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
References: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241220123916.1452582-2-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

On both 'S32G2' and 'S32G3' SoCs there are five i2c controllers available
(i2c0-i2c4). Specific S32G2/S32G3 based board 'i2c' dts device support
will be added in further commits.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 arch/arm64/boot/dts/freescale/s32g2.dtsi | 55 ++++++++++++++++++++++
 arch/arm64/boot/dts/freescale/s32g3.dtsi | 60 ++++++++++++++++++++++++
 2 files changed, 115 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
index 7be430b78c83..1a9683c234b7 100644
--- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -333,6 +333,39 @@ uart1: serial at 401cc000 {
 			status = "disabled";
 		};
 
+		i2c0: i2c at 401e4000 {
+			compatible = "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x401e4000 0x1000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c1: i2c at 401e8000 {
+			compatible = "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x401e8000 0x1000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c2: i2c at 401ec000 {
+			compatible = "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x401ec000 0x1000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		uart2: serial at 402bc000 {
 			compatible = "nxp,s32g2-linflexuart",
 				     "fsl,s32v234-linflexuart";
@@ -341,6 +374,28 @@ uart2: serial at 402bc000 {
 			status = "disabled";
 		};
 
+		i2c3: i2c at 402d8000 {
+			compatible = "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x402d8000 0x1000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c4: i2c at 402dc000 {
+			compatible = "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x402dc000 0x1000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		usdhc0: mmc at 402f0000 {
 			compatible = "nxp,s32g2-usdhc";
 			reg = <0x402f0000 0x1000>;
diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
index 6c572ffe37ca..5d28b439906d 100644
--- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
@@ -390,6 +390,42 @@ uart1: serial at 401cc000 {
 			status = "disabled";
 		};
 
+		i2c0: i2c at 401e4000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x401e4000 0x1000>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c1: i2c at 401e8000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x401e8000 0x1000>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c2: i2c at 401ec000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x401ec000 0x1000>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		uart2: serial at 402bc000 {
 			compatible = "nxp,s32g3-linflexuart",
 				     "fsl,s32v234-linflexuart";
@@ -398,6 +434,30 @@ uart2: serial at 402bc000 {
 			status = "disabled";
 		};
 
+		i2c3: i2c at 402d8000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x402d8000 0x1000>;
+			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		i2c4: i2c at 402dc000 {
+			compatible = "nxp,s32g3-i2c",
+				     "nxp,s32g2-i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x402dc000 0x1000>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clks 40>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
 		usdhc0: mmc at 402f0000 {
 			compatible = "nxp,s32g3-usdhc",
 				     "nxp,s32g2-usdhc";
-- 
2.45.2



From ciprianmarian.costea at oss.nxp.com  Fri Dec 20 04:39:14 2024
From: ciprianmarian.costea at oss.nxp.com (Ciprian Costea)
Date: Fri, 20 Dec 2024 14:39:14 +0200
Subject: [PATCH v4 2/4] arm64: dts: s32g: add common 'S32G-EVB' and 'S32G-RDB' board support
In-Reply-To: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
References: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
Message-ID: <20241220123916.1452582-3-ciprianmarian.costea@oss.nxp.com>

From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>

With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
(rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
are quite similar. The common part for the EVB revisions will be
centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
be placed in 's32gxxa-rdb.dtsi' file.

This refactor will also serve for other modules in the future, such as
FlexCAN, DSPI.

Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
---
 .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
 .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 122 ++++++++++++++
 2 files changed, 272 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi

diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
new file mode 100644
index 000000000000..a44eff28073a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2024 NXP
+ *
+ * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
+ *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
+ *          Larisa Grigore <larisa.grigore at nxp.com>
+ */
+
+&pinctrl {
+	i2c0_pins: i2c0-pins {
+		i2c0-grp0 {
+			pinmux = <0x101>, <0x111>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-grp1 {
+			pinmux = <0x2352>, <0x2362>;
+		};
+	};
+
+	i2c0_gpio_pins: i2c0-gpio-pins {
+		i2c0-gpio-grp0 {
+			pinmux = <0x100>, <0x110>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-gpio-grp1 {
+			pinmux = <0x2350>, <0x2360>;
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		i2c1-grp0 {
+			pinmux = <0x131>, <0x141>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c1-grp1 {
+			pinmux = <0x2cd2>, <0x2ce2>;
+		};
+	};
+
+	i2c1_gpio_pins: i2c1-gpio-pins {
+		i2c1-gpio-grp0 {
+			pinmux = <0x130>, <0x140>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c1-gpio-grp1 {
+			pinmux = <0x2cd0>, <0x2ce0>;
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		i2c2-grp0 {
+			pinmux = <0x151>, <0x161>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-grp1 {
+			pinmux = <0x2cf2>, <0x2d02>;
+		};
+	};
+
+	i2c2_gpio_pins: i2c2-gpio-pins {
+		i2c2-gpio-grp0 {
+			pinmux = <0x150>, <0x160>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-gpio-grp1 {
+			pinmux = <0x2cf0>, <0x2d00>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		i2c4-grp0 {
+			pinmux = <0x211>, <0x222>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-grp1 {
+			pinmux = <0x2d43>, <0x2d33>;
+		};
+	};
+
+	i2c4_gpio_pins: i2c4-gpio-pins {
+		i2c4-gpio-grp0 {
+			pinmux = <0x210>, <0x220>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-gpio-grp1 {
+			pinmux = <0x2d40>, <0x2d30>;
+		};
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-1 = <&i2c0_gpio_pins>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c1_pins>;
+	pinctrl-1 = <&i2c1_gpio_pins>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_gpio_pins>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-1 = <&i2c4_gpio_pins>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
new file mode 100644
index 000000000000..91fd8dbf2224
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2024 NXP
+ *
+ * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
+ *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
+ *          Larisa Grigore <larisa.grigore at nxp.com>
+ */
+
+&pinctrl {
+	i2c0_pins: i2c0-pins {
+		i2c0-grp0 {
+			pinmux = <0x1f2>, <0x201>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-grp1 {
+			pinmux = <0x2353>, <0x2363>;
+		};
+	};
+
+	i2c0_gpio_pins: i2c0-gpio-pins {
+		i2c0-gpio-grp0 {
+			pinmux = <0x1f0>, <0x200>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c0-gpio-grp1 {
+			pinmux = <0x2350>, <0x2360>;
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		i2c2-grp0 {
+			pinmux = <0x151>, <0x161>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c2-grp1 {
+			pinmux = <0x2cf2>, <0x2d02>;
+		};
+	};
+
+	i2c2_gpio_pins: i2c2-gpio-pins {
+		i2c2-gpio-grp0 {
+			pinmux = <0x2cf0>, <0x2d00>;
+		};
+
+		i2c2-gpio-grp1 {
+			pinmux = <0x150>, <0x160>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		i2c4-grp0 {
+			pinmux = <0x211>, <0x222>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-grp1 {
+			pinmux = <0x2d43>, <0x2d33>;
+		};
+	};
+
+	i2c4_gpio_pins: i2c4-gpio-pins {
+		i2c4-gpio-grp0 {
+			pinmux = <0x210>, <0x220>;
+			drive-open-drain;
+			output-enable;
+			input-enable;
+			slew-rate = <133>;
+		};
+
+		i2c4-gpio-grp1 {
+			pinmux = <0x2d40>, <0x2d30>;
+		};
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-1 = <&i2c0_gpio_pins>;
+	status = "okay";
+
+	pcal6524: gpio-expander at 22 {
+		compatible = "nxp,pcal6524";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_gpio_pins>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-1 = <&i2c4_gpio_pins>;
+	status = "okay";
+};
-- 
2.45.2



From konrad.dybcio at oss.qualcomm.com  Fri Dec 20 04:42:04 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 20 Dec 2024 13:42:04 +0100
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on pre-SYSTEM_SUSPEND
 PSCI impls
In-Reply-To: <Z2VXgkJ4x5TJTKJ_@bogus>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241113165329590-0800.eberman@hu-eberman-lv.qualcomm.com>
 <e4509104-c809-4d45-bdbb-a2d754a816db@oss.qualcomm.com>
 <Z2VXgkJ4x5TJTKJ_@bogus>
Message-ID: <765bb1c8-31de-4aec-b8ef-f141a3e25c56@oss.qualcomm.com>

On 20.12.2024 12:39 PM, Sudeep Holla wrote:
> On Thu, Dec 19, 2024 at 08:26:51PM +0100, Konrad Dybcio wrote:
>> On 14.11.2024 2:10 AM, Elliot Berman wrote:
>>
>>> I'm not sure why you'd like to support s2ram. Is it *only* that you'd
>>> like to be able to set pm_set_supend/resume_via_firmware()? I hope this
>>> doesn't sound silly: what if you register a platform_s2idle_ops for the
>>> relevant SoCs which calls pm_set_suspend/resume_via_firwmare()?
>>
>> S2RAM is what you get after entering a certain state, but currently
>> it's presented as just another (s2idle) idle state.
>>
> 
> Just to be clear, I assume you mean CPU_SUSPEND idle state. There is
> no special or different s2idle idle states IIUC.

Yeah, right.

>> That means some hardware that may need to be reinitialized, isn't as
>> Linux has no clue it might have lost power.
>>
> 
> Interesting, so this means firmware doesn't automatically save and restore
> states yet exposes it as CPU_SUSPEND idle state.

Reading the spec, I'm pretty sure PSCI calls should only mess with the
power state of the cores, core-adjacent peripherals and GIC.

Reading section 5.20.1 (SYSTEM_SUSPEND / Intended use) I think it says
mostly what I'm trying to convey:


"In a typical implementation, the semantics are equivalent to a
CPU_SUSPEND to the deepest low-power state. However, it is possible that
an implementation might reserve a deeper state for SYSTEM_SUSPEND than
those used with CPU_SUSPEND."

- this is the situation on QC platforms, with the case of not reserving a
deeper state for SYSTEM_SUSPEND

>> One of such cases is the PCIe block, with storage drivers specifically
>> looking for pm_suspend_via_firmware, but that's unfortunately not the
>> whole list.
>>
> 
> Well I can now imagine and I understand what's wrong here. An idle state
> is exposed to OS with an expectation that OS saves and restores certain
> state. Unless you tie it some other power domains that theses devices
> share, it is hard for OS to know the state is being lost and it needs
> to save and restore them. It is simple wrong to assume that OS needs
> to take care of them even though the power domain hierarchy doesn't
> represent this dependency to enter such a state. cpuidle-psci-domain.c
> takes care of this IIUC. Ulf can provide details if you are interested.

The spec disagrees:

"Note that entering the system into S2 or S3 carries with it several
preconditions. For example, all devices in the system must be in a state
that is compatible with entry into the system state"

- this also happens to be relevant here, given PSCI is not supposed to
power-govern the entire SoC, but only the CPU block. We have specialty
hardware that does power management for non-CPU IPs, but to request
a system power rail disablement, it must be done in conjunction with the
CPU requesting such CPU_SUSPEND state. And only after the required hardware
is de-initialized.

Konrad


From linus.walleij at linaro.org  Fri Dec 20 04:50:14 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 20 Dec 2024 13:50:14 +0100
Subject: [PATCH v3 3/7] dt-bindings: gpio: brcmstb: permit gpio-line-names property
In-Reply-To: <20241212-dt-bcm2712-fixes-v3-3-44a7f3390331@raspberrypi.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com> <20241212-dt-bcm2712-fixes-v3-3-44a7f3390331@raspberrypi.com>
Message-ID: <CACRpkdaB9kqcjmhaXd5RxpYvqdSVMZkj0wHAtEgdqDs03+wzJg@mail.gmail.com>

On Thu, Dec 12, 2024 at 7:36?PM Dave Stevenson
<dave.stevenson at raspberrypi.com> wrote:

> gpio-line-names is a generic property that can be supported by any
> GPIO controller, so permit it through the binding.
>
> It is permitted to have a variable number of GPIOs per node based
> on brcm,gpio-bank-widths, so define an arbitrary maximum number of
> items based on current users.
>
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Perhaps Bartosz can just apply this one patch separately?

Yours,
Linus Walleij


From konrad.dybcio at oss.qualcomm.com  Fri Dec 20 04:54:45 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 20 Dec 2024 13:54:45 +0100
Subject: [PATCH 1/3] dt-bindings: arm,psci: Allow S2RAM power_state
 parameter description
In-Reply-To: <Z2VUiHWHgbWowdal@bogus>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
 <Z1LQOmEfFy640PjG@bogus>
 <54cc4221-ba5f-4741-9033-20874265ca01@oss.qualcomm.com>
 <Z2VUiHWHgbWowdal@bogus>
Message-ID: <349bac70-87e0-4870-a3f0-9f6a3b3e6824@oss.qualcomm.com>

On 20.12.2024 12:27 PM, Sudeep Holla wrote:
> On Thu, Dec 19, 2024 at 08:43:27PM +0100, Konrad Dybcio wrote:
>> On 6.12.2024 11:21 AM, Sudeep Holla wrote:
>>> On Mon, Oct 28, 2024 at 03:22:57PM +0100, Konrad Dybcio wrote:
>>>> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>>>
>>>> Certain firmware implementations (such as the ones found on Qualcomm
>>>> SoCs between roughly 2015 and 2023) expose an S3-like S2RAM state
>>>> through the CPU_SUSPEND call, as opposed to exposing PSCIv1.0's
>>>> optional PSCI_SYSTEM_SUSPEND.
>>>>
>>>
>>> If so, can you elaborate why s2idle doesn't work as an alternative to what
>>> you are hacking up here.
>>
>> Please see other branches of this thread
>>
>>>
>>>> This really doesn't work well with the model where we associate all
>>>> calls to CPU_SUSPEND with cpuidle. Allow specifying a single special
>>>> CPU_SUSPEND suspend parameter value that is to be treated just like
>>>> SYSTEM_SUSPEND from the OS's point of view.
>>>>
>>>> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>>> ---
>>>>  Documentation/devicetree/bindings/arm/psci.yaml | 6 ++++++
>>>>  1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml
>>>> index cbb012e217ab80c1ca88e611e7acc06c6d56fad0..a6901878697c8e1ec1cbfed62298ae3bc58f2501 100644
>>>> --- a/Documentation/devicetree/bindings/arm/psci.yaml
>>>> +++ b/Documentation/devicetree/bindings/arm/psci.yaml
>>>> @@ -98,6 +98,12 @@ properties:
>>>>        [1] Kernel documentation - ARM idle states bindings
>>>>          Documentation/devicetree/bindings/cpu/idle-states.yaml
>>>>  
>>>> +  arm,psci-s2ram-param:
>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>> +    description:
>>>> +      power_state parameter denoting the S2RAM/S3-like system suspend state
>>>
>>> Yet another NACK as this corresponds to PSCI SYSTEM_SUSPEND and as per
>>> specification it takes no such parameter. This is just misleading.
>>>
>>
>> Yeah PSCI_SYSTEM_SUSPEND takes care of this on platforms that expose it.
>>
> 
> And those that don't advertise/expose don't get to use, simple.

The spec says:

"The call is equivalent to using the CPU_SUSPEND call for the
deepest possible platform powerdown state."

so by that logic, I'd rather call implementing PSCI_SYSTEM_SUSPEND in
Linux unnecessary bloat..

>> DEN0022F.b Section 6.5. recommends that CPU_SUSPEND StateID includes
>> a field for system-level power down states. This binding change only
>> adds a way for DT-based platforms to associate such state with S2RAM
>> suspend.
>>
> 
> Sure, just use the CPU_SUSPEND bindings that already exist. No need to
> define this as some special case if it is exposed as CPU_SUSPEND idle
> state. Not sure why you want to do it differently. I understand the
> need to handle it different in the kernel, but I don't understand to
> define the new bindings for that. Just use the existing bindings for the
> idle states. Again I see no exception for this case.

The bindings exist for core/cluster idle states. This whole series tries
to include a system-wide suspend state that has no business being
described as a cpuidle one and depends on more than just the CPUs being
powered down.

>> That may be a bit Linux-specific whereas bindings are supposed to be
>> OS-agnostic, but since we effectively want one PSCI state for deep
>> suspend regardless of the OS, I would think this kind of hint is fine.
>>
> 
> Exactly, that's the reason for not changing this into special case and
> special binding for that special case created.

I simply don't think it's fitting to lie about system suspend states being
just CPU idle states, see above.

Konrad


From patrice.chotard at foss.st.com  Fri Dec 20 04:55:06 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Fri, 20 Dec 2024 13:55:06 +0100
Subject: [PATCH v2 4/4] ARM: configs: stm32: Remove useless flags in STM32 defconfig
In-Reply-To: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
References: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
Message-ID: <20241220125506.3157268-5-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

As stm32_defconfig is dedicated to STM32 MCUs, disable
CONFIG_COMMON_CLK_STM32MP flag which is only used by STM32 MPUs.

Disable CONFIG_SUSPEND, CONFIG_ADVISE_SYSCALLS, CONFIG_IO_URING
CONFIG_POSIX_TIMERS, CONFIG_GCC_PLUGINS, it will reduce the kernel
image size for these platforms which embed a low amount of memory.

Tested on STM32F746-DISCO board which embeds 8MB of memory.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index d62a0c0b7ce5..77048b5e1ec4 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -6,12 +6,15 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_EXPERT=y
 # CONFIG_UID16 is not set
+# CONFIG_POSIX_TIMERS is not set
 CONFIG_BASE_SMALL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_SIGNALFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+# CONFIG_IO_URING is not set
+# CONFIG_ADVISE_SYSCALLS is not set
 # CONFIG_MMU is not set
 CONFIG_ARCH_STM32=y
 CONFIG_CPU_V7M_NUM_IRQ=240
@@ -20,6 +23,8 @@ CONFIG_DRAM_BASE=0x90000000
 # CONFIG_ATAGS is not set
 CONFIG_XIP_KERNEL=y
 CONFIG_XIP_PHYS_ADDR=0x08008000
+# CONFIG_SUSPEND is not set
+# CONFIG_GCC_PLUGINS is not set
 CONFIG_BINFMT_FLAT=y
 # CONFIG_COREDUMP is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
@@ -60,6 +65,7 @@ CONFIG_DMADEVICES=y
 CONFIG_STM32_DMA=y
 CONFIG_STM32_DMAMUX=y
 CONFIG_STM32_MDMA=y
+# CONFIG_COMMON_CLK_STM32MP is not set
 CONFIG_IIO=y
 CONFIG_STM32_ADC_CORE=y
 CONFIG_STM32_ADC=y
-- 
2.25.1



From patrice.chotard at foss.st.com  Fri Dec 20 04:55:03 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Fri, 20 Dec 2024 13:55:03 +0100
Subject: [PATCH v2 1/4] ARM: configs: stm32: Remove FLASH_MEM_BASE and FLASH_SIZE in STM32 defconfig
In-Reply-To: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
References: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
Message-ID: <20241220125506.3157268-2-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Running make savedefconfig highlights some useless flags.

Remove FLASH_MEM_BASE and FLASH_SIZE as these 2 flags are only
used by CPU_ARM740T,CPU_ARM940T and CPU_ARM946E which is not the
case here for CPU_V7M.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 3baec075d1ef..973bf7c8236b 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -18,8 +18,6 @@ CONFIG_ARCH_STM32=y
 CONFIG_CPU_V7M_NUM_IRQ=240
 CONFIG_SET_MEM_PARAM=y
 CONFIG_DRAM_BASE=0x90000000
-CONFIG_FLASH_MEM_BASE=0x08000000
-CONFIG_FLASH_SIZE=0x00200000
 # CONFIG_ATAGS is not set
 CONFIG_XIP_KERNEL=y
 CONFIG_XIP_PHYS_ADDR=0x08008000
-- 
2.25.1



From patrice.chotard at foss.st.com  Fri Dec 20 04:55:04 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Fri, 20 Dec 2024 13:55:04 +0100
Subject: [PATCH v2 2/4] ARM: configs: stm32: Clean STM32 defconfig
In-Reply-To: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
References: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
Message-ID: <20241220125506.3157268-3-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Running make savedefconfig highlights some useless flags.

Since 54a48aa3d558 ("Compiler Attributes: remove CONFIG_ENABLE_MUST_CHECK")
flag ENABLE_MUST_CHECK has been removed.

Since 35260cf54522 ("Kconfig.debug: fix SCHED_DEBUG dependency")
SCHED_DEBUG depends on DEBUG_KERNEL and PROC_FS.
As PROC_FS is not set, SCHED_DEBUG reference can be removed.

Since 78011042684d ("scsi: bsg: Move bsg_scsi_ops to drivers/scsi/")
BLK_DEV_BSG depends on SCSI. As SCSI is not set, BLK_DEV_BSG reference
can be removed.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 973bf7c8236b..be7b63036730 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -12,7 +12,6 @@ CONFIG_BASE_SMALL=y
 # CONFIG_SIGNALFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
-# CONFIG_BLK_DEV_BSG is not set
 # CONFIG_MMU is not set
 CONFIG_ARCH_STM32=y
 CONFIG_CPU_V7M_NUM_IRQ=240
@@ -72,10 +71,8 @@ CONFIG_NLS=y
 CONFIG_CRC_ITU_T=y
 CONFIG_CRC7=y
 CONFIG_PRINTK_TIME=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SLUB_DEBUG is not set
-# CONFIG_SCHED_DEBUG is not set
 CONFIG_CRYPTO=y
-- 
2.25.1



From patrice.chotard at foss.st.com  Fri Dec 20 04:55:05 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Fri, 20 Dec 2024 13:55:05 +0100
Subject: [PATCH v2 3/4] ARM: configs: stm32: Remove CRYPTO in STM32 defconfig
In-Reply-To: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
References: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
Message-ID: <20241220125506.3157268-4-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Running make savedefconfig highlights some useless flags.

Since 1c92d4a0edcf ("ARM: configs: stm32: Enable MMC_ARMMMCI and EXT3_FS support")
CRYPTO is selected by EXT3_FS, so CRYPTO can be removed in stm32_defconfig.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/configs/stm32_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index be7b63036730..d62a0c0b7ce5 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -75,4 +75,3 @@ CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SLUB_DEBUG is not set
-CONFIG_CRYPTO=y
-- 
2.25.1



From patrice.chotard at foss.st.com  Fri Dec 20 04:55:02 2024
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Fri, 20 Dec 2024 13:55:02 +0100
Subject: [PATCH v2 0/4] ARM: config: stm32: Remove useless flags
Message-ID: <20241220125506.3157268-1-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Running "make savedefconfig" highlights that some flags are no more used,
remove them.
Remove some flags to reduce the kernel image size as STM32 MCU's board
embeds low amount of RAM.

Changes in V2:
  _ squash patches 2-7
  _ split patch 1 in three parts and add epxlanations about flags removal.

Patrice Chotard (4):
  ARM: configs: stm32: Remove FLASH_MEM_BASE and FLASH_SIZE in STM32
    defconfig
  ARM: configs: stm32: Clean STM32 defconfig
  ARM: configs: stm32: Remove CRYPTO in STM32 defconfig
  ARM: configs: stm32: Remove useless flags in STM32 defconfig

 arch/arm/configs/stm32_defconfig | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

-- 
2.25.1



From dave.stevenson at raspberrypi.com  Fri Dec 20 05:01:51 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 13:01:51 +0000
Subject: [PATCH v3 3/7] dt-bindings: gpio: brcmstb: permit gpio-line-names property
In-Reply-To: <CACRpkdaB9kqcjmhaXd5RxpYvqdSVMZkj0wHAtEgdqDs03+wzJg@mail.gmail.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
 <20241212-dt-bcm2712-fixes-v3-3-44a7f3390331@raspberrypi.com> <CACRpkdaB9kqcjmhaXd5RxpYvqdSVMZkj0wHAtEgdqDs03+wzJg@mail.gmail.com>
Message-ID: <CAPY8ntBJqukSJs7VUXvUFAsiKqNWknL8VjgtQG_VAEmw576EPQ@mail.gmail.com>

Hi Linus

On Fri, 20 Dec 2024 at 12:50, Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Thu, Dec 12, 2024 at 7:36?PM Dave Stevenson
> <dave.stevenson at raspberrypi.com> wrote:
>
> > gpio-line-names is a generic property that can be supported by any
> > GPIO controller, so permit it through the binding.
> >
> > It is permitted to have a variable number of GPIOs per node based
> > on brcm,gpio-bank-widths, so define an arbitrary maximum number of
> > items based on current users.
> >
> > Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Thank you.

> Perhaps Bartosz can just apply this one patch separately?

I believe he already has, but commented against the cover letter
rather than this patch -
https://lore.kernel.org/linux-arm-kernel/173434013318.38429.808413721248542013.b4-ty at linaro.org/

  Dave

> Yours,
> Linus Walleij


From linus.walleij at linaro.org  Fri Dec 20 05:10:18 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 20 Dec 2024 14:10:18 +0100
Subject: [PATCH 3/4] ARM: drop CONFIG_HIGHPTE support
In-Reply-To: <d54e11cf3f4d4216b5cecf29b761cd45@AcuMS.aculab.com>
References: <20241210160556.2341497-1-arnd@kernel.org> <20241210160556.2341497-4-arnd@kernel.org>
 <d54e11cf3f4d4216b5cecf29b761cd45@AcuMS.aculab.com>
Message-ID: <CACRpkdYihj15SRp5t_8Aq4i4jtgP1-VLOSbbKG+ozLgiAuLgmQ@mail.gmail.com>

On Sat, Dec 14, 2024 at 7:41?PM David Laight <David.Laight at aculab.com> wrote:

> From: Arnd Bergmann
> > Sent: 10 December 2024 16:06
> ...
> > Since Arm is the last architecture remaining that uses this, and almost
> > no 32-bit machines support more than 4GB of RAM, the cost of continuing
> > to maintain HIGHPTE seems unjustified, so remove it here to allow
> > simplifying the generic page table handling.
>
> 'Picking at nits' 'highmem' support was needed for systems with 4GB of RAM
> in order to use more than 3GB or 3.5GB (depending on the bios) because
> of the physical addresses that are reserved for PCI (and other MMIO).

Wow I didn't know that, there are so many reasons why highmem is used
by different architectures.

On ARM it was originally added for a certain Marvell system with
a mere 2GB of RAM:
commit 053a96ca11a9785a7e63fc89eed4514a6446ec58

The reason was that since the virtual address space is just 4GB and
we have reserved virtual kernel memory from (typically) 0xc0000000
only ~1GB can be linearly accessed by the kernel (actually less than
that).

This wasn't a problem since no ARM system was using more than
1GB until Nico ran into it.

So the ARM "high memory" is something to do with virtual memory
size rather than physical memory reservations as in the x86 case.

Yours,
Linus Walleij


From andrei.stefanescu at oss.nxp.com  Fri Dec 20 05:16:07 2024
From: andrei.stefanescu at oss.nxp.com (Andrei Stefanescu)
Date: Fri, 20 Dec 2024 15:16:07 +0200
Subject: [PATCH v6 2/7] mfd: nxp-siul2: add support for NXP SIUL2
In-Reply-To: <20241213171529.GF2418536@google.com>
References: <20241113101124.1279648-1-andrei.stefanescu@oss.nxp.com>
 <20241113101124.1279648-3-andrei.stefanescu@oss.nxp.com>
 <20241211124454.GE7139@google.com>
 <3b090335-20b4-4d73-aabc-ddac98311e33@sirena.org.uk>
 <20241213171529.GF2418536@google.com>
Message-ID: <5970e8a0-8c28-4201-ac87-b1152a236c5b@oss.nxp.com>

Hi Mark, Lee,

Thank you for your review!

On 13/12/2024 19:15, Lee Jones wrote:
> On Wed, 11 Dec 2024, Mark Brown wrote:
> 
>> On Wed, Dec 11, 2024 at 12:45:56PM +0000, Lee Jones wrote:
>>
>>> Seeing as the vast majority of this 400 line driver pertains to Regmap
>>> handling (!), would you be kind enough to cast your expert eye over it
>>> please?
>>
>> Is there something specific you're concerned about there?  It looks like
>> it's just data which should be fine.
> 
> Just the mass of complex hoop-jumping to get all of these Regmaps
> registered.  But if nothing stands out to you, then it's probably okay.
> 
> Still, I can't review / take this until it's a proper MFD.
> 

I will add the SIUL2 NVMEM driver to this series in v7 then.

Best regards,
Andrei


From quic_luoj at quicinc.com  Fri Dec 20 05:22:46 2024
From: quic_luoj at quicinc.com (Luo Jie)
Date: Fri, 20 Dec 2024 21:22:46 +0800
Subject: [PATCH v7 5/5] arm64: dts: qcom: Update IPQ9574 xo_board_clk to
 use fixed factor clock
In-Reply-To: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
References: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
Message-ID: <20241220-qcom_ipq_cmnpll-v7-5-438a1b5cb98e@quicinc.com>

xo_board_clk is fixed to 24 MHZ, which is routed from WiFi output clock
48 MHZ (also being the reference clock of CMN PLL) divided 2 by analog
block routing channel.

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
---
 arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 7 ++++++-
 arch/arm64/boot/dts/qcom/ipq9574.dtsi            | 3 ++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
index bb1ff79360d3..ae12f069f26f 100644
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
@@ -175,8 +175,13 @@ &ref_48mhz_clk {
 	clock-mult = <1>;
 };
 
+/*
+ * The frequency of xo_board_clk is fixed to 24 MHZ, which is routed
+ * from WiFi output clock 48 MHZ divided by 2.
+ */
 &xo_board_clk {
-	clock-frequency = <24000000>;
+	clock-div = <2>;
+	clock-mult = <1>;
 };
 
 &xo_clk {
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
index 475868a241cc..b5c8d2ab2ab5 100644
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -32,7 +32,8 @@ sleep_clk: sleep-clk {
 		};
 
 		xo_board_clk: xo-board-clk {
-			compatible = "fixed-clock";
+			compatible = "fixed-factor-clock";
+			clocks = <&ref_48mhz_clk>;
 			#clock-cells = <0>;
 		};
 

-- 
2.34.1



From quic_luoj at quicinc.com  Fri Dec 20 05:22:41 2024
From: quic_luoj at quicinc.com (Luo Jie)
Date: Fri, 20 Dec 2024 21:22:41 +0800
Subject: [PATCH v7 0/5] Add CMN PLL clock controller driver for IPQ9574
Message-ID: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>

The CMN PLL clock controller in Qualcomm IPQ chipsets provides
the clocks to the networking hardware blocks that are internal
or external to the SoC, and to the GCC. This driver configures
the CMN PLL clock controller to enable the output clocks. The
networking blocks include the internal blocks such as PPE
(Packet Process Engine) and PCS blocks, and external hardware
such as Ethernet PHY or switch. The CMN PLL block also outputs
fixed rate clocks to GCC, such as 24 MHZ as XO clock and 32 KHZ
as sleep clock supplied to GCC.

The controller expects the input reference clock from the internal
Wi-Fi block acting as the clock source. The output clocks supplied
by the controller are fixed rate clocks.

The CMN PLL hardware block does not include any other function
other than enabling the clocks to the networking hardware blocks
and GCC.

The driver is being enabled to support IPQ9574 SoC initially, and
will be extended for other SoCs.

Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
---
Changes in v7:
- Update to use API regmap_set and clear_bits.
- Update comment of CMN PLL reference clock to mention .xo could be
  48 MHZ or 96 MHZ on different IPQ9574 RDP board.
- Link to v6: https://lore.kernel.org/r/20241107-qcom_ipq_cmnpll-v6-0-a5cfe09de485 at quicinc.com

Changes in v6:
- Rename the reference clock of CMN PLL to ref_48mhz_clk.
- Add the patch to update xo_board_clk to use fixed factor clock.
- Link to v5: https://lore.kernel.org/r/20241028-qcom_ipq_cmnpll-v5-0-339994b0388d at quicinc.com

Changes in v5:
- Move the hardware configurations into set_rate() from determine_rate().
- Remove the dependency on IPQ_GCC_9574.
- Correct the header files included.
- Update reference clock of CMN PLL to use fixed factor clock.
- Link to v4: https://lore.kernel.org/r/20241015-qcom_ipq_cmnpll-v4-0-27817fbe3505 at quicinc.com

Changes in v4:
- Rename driver file to ipq-cmn-pll.c
- Register CMN PLL as a 12 GHZ clock.
- Configure CMN PLL input ref clock using clk_ops::determine_rate().
  Add the additional output clocks to GCC and PCS.
- Update the same information in dtbindings.
- Use PM clock APIs for input clock enablement.
- Link to v3: https://lore.kernel.org/r/20240827-qcom_ipq_cmnpll-v3-0-8e009cece8b2 at quicinc.com

Changes in v3:
- Update description of dt-binding to explain scope of 'CMN' in CMN PLL.
- Collect Reviewed-by tags for dtbindings and defconfig patches.
- Enable PLL_LOCKED check for the stability of output clocks.
- Link to v2: https://lore.kernel.org/r/20240820-qcom_ipq_cmnpll-v2-0-b000dd335280 at quicinc.com

Changes in v2:
- Rename the dt-binding file with the compatible.
- Remove property 'clock-output-names' from dt-bindings and define
  names in the driver. Add qcom,ipq-cmn-pll.h to export the output
  clock specifier.
- Alphanumeric ordering of 'cmn_pll_ref_clk' node in DTS.
- Fix allmodconfig error reported by test robot.
- Replace usage of "common" to "CMN" to match the name with the
  hardware specification.
- Clarify in commit message on scope of CMN PLL function.
- Link to v1: https://lore.kernel.org/r/20240808-qcom_ipq_cmnpll-v1-0-b0631dcbf785 at quicinc.com

---
Luo Jie (5):
      dt-bindings: clock: qcom: Add CMN PLL clock controller for IPQ SoC
      clk: qcom: Add CMN PLL clock controller driver for IPQ SoC
      arm64: defconfig: Enable Qualcomm IPQ CMN PLL clock controller
      arm64: dts: qcom: Add CMN PLL node for IPQ9574 SoC
      arm64: dts: qcom: Update IPQ9574 xo_board_clk to use fixed factor clock

 .../bindings/clock/qcom,ipq9574-cmn-pll.yaml       |  85 ++++
 arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi   |  24 +-
 arch/arm64/boot/dts/qcom/ipq9574.dtsi              |  27 +-
 arch/arm64/configs/defconfig                       |   1 +
 drivers/clk/qcom/Kconfig                           |   9 +
 drivers/clk/qcom/Makefile                          |   1 +
 drivers/clk/qcom/ipq-cmn-pll.c                     | 435 +++++++++++++++++++++
 include/dt-bindings/clock/qcom,ipq-cmn-pll.h       |  22 ++
 8 files changed, 601 insertions(+), 3 deletions(-)
---
base-commit: e25c8d66f6786300b680866c0e0139981273feba
change-id: 20241216-qcom_ipq_cmnpll-f5c84724db9d

Best regards,
-- 
Luo Jie <quic_luoj at quicinc.com>



From quic_luoj at quicinc.com  Fri Dec 20 05:22:42 2024
From: quic_luoj at quicinc.com (Luo Jie)
Date: Fri, 20 Dec 2024 21:22:42 +0800
Subject: [PATCH v7 1/5] dt-bindings: clock: qcom: Add CMN PLL clock
 controller for IPQ SoC
In-Reply-To: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
References: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
Message-ID: <20241220-qcom_ipq_cmnpll-v7-1-438a1b5cb98e@quicinc.com>

The CMN PLL controller provides clocks to networking hardware blocks
and to GCC on Qualcomm IPQ9574 SoC. It receives input clock from the
on-chip Wi-Fi, and produces output clocks at fixed rates. These output
rates are predetermined, and are unrelated to the input clock rate.
The primary purpose of CMN PLL is to supply clocks to the networking
hardware such as PPE (packet process engine), PCS and the externally
connected switch or PHY device. The CMN PLL block also outputs fixed
rate clocks to GCC, such as 24 MHZ as XO clock and 32 KHZ as sleep
clock supplied to GCC.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
---
 .../bindings/clock/qcom,ipq9574-cmn-pll.yaml       | 85 ++++++++++++++++++++++
 include/dt-bindings/clock/qcom,ipq-cmn-pll.h       | 22 ++++++
 2 files changed, 107 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
new file mode 100644
index 000000000000..db8a3ee56067
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,ipq9574-cmn-pll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm CMN PLL Clock Controller on IPQ SoC
+
+maintainers:
+  - Bjorn Andersson <andersson at kernel.org>
+  - Luo Jie <quic_luoj at quicinc.com>
+
+description:
+  The CMN (or common) PLL clock controller expects a reference
+  input clock. This reference clock is from the on-board Wi-Fi.
+  The CMN PLL supplies a number of fixed rate output clocks to
+  the devices providing networking functions and to GCC. These
+  networking hardware include PPE (packet process engine), PCS
+  and the externally connected switch or PHY devices. The CMN
+  PLL block also outputs fixed rate clocks to GCC. The PLL's
+  primary function is to enable fixed rate output clocks for
+  networking hardware functions used with the IPQ SoC.
+
+properties:
+  compatible:
+    enum:
+      - qcom,ipq9574-cmn-pll
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: The reference clock. The supported clock rates include
+          25000000, 31250000, 40000000, 48000000, 50000000 and 96000000 HZ.
+      - description: The AHB clock
+      - description: The SYS clock
+    description:
+      The reference clock is the source clock of CMN PLL, which is from the
+      Wi-Fi. The AHB and SYS clocks must be enabled to access CMN PLL
+      clock registers.
+
+  clock-names:
+    items:
+      - const: ref
+      - const: ahb
+      - const: sys
+
+  "#clock-cells":
+    const: 1
+
+  assigned-clocks:
+    maxItems: 1
+
+  assigned-clock-rates-u64:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - assigned-clocks
+  - assigned-clock-rates-u64
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
+    #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
+
+    cmn_pll: clock-controller at 9b000 {
+        compatible = "qcom,ipq9574-cmn-pll";
+        reg = <0x0009b000 0x800>;
+        clocks = <&cmn_pll_ref_clk>,
+                 <&gcc GCC_CMN_12GPLL_AHB_CLK>,
+                 <&gcc GCC_CMN_12GPLL_SYS_CLK>;
+        clock-names = "ref", "ahb", "sys";
+        #clock-cells = <1>;
+        assigned-clocks = <&cmn_pll CMN_PLL_CLK>;
+        assigned-clock-rates-u64 = /bits/ 64 <12000000000>;
+    };
+...
diff --git a/include/dt-bindings/clock/qcom,ipq-cmn-pll.h b/include/dt-bindings/clock/qcom,ipq-cmn-pll.h
new file mode 100644
index 000000000000..936e92b3b62c
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,ipq-cmn-pll.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_IPQ_CMN_PLL_H
+#define _DT_BINDINGS_CLK_QCOM_IPQ_CMN_PLL_H
+
+/* CMN PLL core clock. */
+#define CMN_PLL_CLK			0
+
+/* The output clocks from CMN PLL of IPQ9574. */
+#define XO_24MHZ_CLK			1
+#define SLEEP_32KHZ_CLK			2
+#define PCS_31P25MHZ_CLK		3
+#define NSS_1200MHZ_CLK			4
+#define PPE_353MHZ_CLK			5
+#define ETH0_50MHZ_CLK			6
+#define ETH1_50MHZ_CLK			7
+#define ETH2_50MHZ_CLK			8
+#define ETH_25MHZ_CLK			9
+#endif

-- 
2.34.1



From quic_luoj at quicinc.com  Fri Dec 20 05:22:43 2024
From: quic_luoj at quicinc.com (Luo Jie)
Date: Fri, 20 Dec 2024 21:22:43 +0800
Subject: [PATCH v7 2/5] clk: qcom: Add CMN PLL clock controller driver for
 IPQ SoC
In-Reply-To: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
References: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
Message-ID: <20241220-qcom_ipq_cmnpll-v7-2-438a1b5cb98e@quicinc.com>

The CMN PLL clock controller supplies clocks to the hardware
blocks that together make up the Ethernet function on Qualcomm
IPQ SoCs and to GCC. The driver is initially supported for
IPQ9574 SoC.

The CMN PLL clock controller expects a reference input clock
from the on-board Wi-Fi block acting as clock source. The input
reference clock needs to be configured to one of the supported
clock rates.

The controller supplies a number of fixed-rate output clocks.
For the IPQ9574, there is one output clock of 353 MHZ to PPE
(Packet Process Engine) hardware block, three 50 MHZ output
clocks and an additional 25 MHZ output clock supplied to the
connected Ethernet devices. The PLL also supplies a 24 MHZ
clock as XO and a 32 KHZ sleep clock to GCC, and one 31.25
MHZ clock to PCS.

Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
---
 drivers/clk/qcom/Kconfig       |   9 +
 drivers/clk/qcom/Makefile      |   1 +
 drivers/clk/qcom/ipq-cmn-pll.c | 435 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 445 insertions(+)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index ef89d686cbc4..9d05887cfc6f 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -190,6 +190,15 @@ config IPQ_APSS_6018
 	  Say Y if you want to support CPU frequency scaling on
 	  ipq based devices.
 
+config IPQ_CMN_PLL
+	tristate "IPQ CMN PLL Clock Controller"
+	help
+	  Support for CMN PLL clock controller on IPQ platform. The
+	  CMN PLL consumes the AHB/SYS clocks from GCC and supplies
+	  the output clocks to the networking hardware and GCC blocks.
+	  Say Y or M if you want to support CMN PLL clock on the IPQ
+	  based devices.
+
 config IPQ_GCC_4019
 	tristate "IPQ4019 Global Clock Controller"
 	help
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index b09dbdc210eb..e0ac75b79f84 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -29,6 +29,7 @@ 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_CMN_PLL) += ipq-cmn-pll.o
 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
 obj-$(CONFIG_IPQ_GCC_5018) += gcc-ipq5018.o
 obj-$(CONFIG_IPQ_GCC_5332) += gcc-ipq5332.o
diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c
new file mode 100644
index 000000000000..432d4c4b7aa6
--- /dev/null
+++ b/drivers/clk/qcom/ipq-cmn-pll.c
@@ -0,0 +1,435 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/*
+ * CMN PLL block expects the reference clock from on-board Wi-Fi block,
+ * and supplies fixed rate clocks as output to the networking hardware
+ * blocks and to GCC. The networking related blocks include PPE (packet
+ * process engine), the externally connected PHY or switch devices, and
+ * the PCS.
+ *
+ * On the IPQ9574 SoC, there are three clocks with 50 MHZ and one clock
+ * with 25 MHZ which are output from the CMN PLL to Ethernet PHY (or switch),
+ * and one clock with 353 MHZ to PPE. The other fixed rate output clocks
+ * are supplied to GCC (24 MHZ as XO and 32 KHZ as sleep clock), and to PCS
+ * with 31.25 MHZ.
+ *
+ *               +---------+
+ *               |   GCC   |
+ *               +--+---+--+
+ *           AHB CLK|   |SYS CLK
+ *                  V   V
+ *          +-------+---+------+
+ *          |                  +-------------> eth0-50mhz
+ * REF CLK  |     IPQ9574      |
+ * -------->+                  +-------------> eth1-50mhz
+ *          |  CMN PLL block   |
+ *          |                  +-------------> eth2-50mhz
+ *          |                  |
+ *          +----+----+----+---+-------------> eth-25mhz
+ *               |    |    |
+ *               V    V    V
+ *              GCC  PCS  NSS/PPE
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.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,ipq-cmn-pll.h>
+
+#define CMN_PLL_REFCLK_SRC_SELECTION		0x28
+#define CMN_PLL_REFCLK_SRC_DIV			GENMASK(9, 8)
+
+#define CMN_PLL_LOCKED				0x64
+#define CMN_PLL_CLKS_LOCKED			BIT(8)
+
+#define CMN_PLL_POWER_ON_AND_RESET		0x780
+#define CMN_ANA_EN_SW_RSTN			BIT(6)
+
+#define CMN_PLL_REFCLK_CONFIG			0x784
+#define CMN_PLL_REFCLK_EXTERNAL			BIT(9)
+#define CMN_PLL_REFCLK_DIV			GENMASK(8, 4)
+#define CMN_PLL_REFCLK_INDEX			GENMASK(3, 0)
+
+#define CMN_PLL_CTRL				0x78c
+#define CMN_PLL_CTRL_LOCK_DETECT_EN		BIT(15)
+
+#define CMN_PLL_DIVIDER_CTRL			0x794
+#define CMN_PLL_DIVIDER_CTRL_FACTOR		GENMASK(9, 0)
+
+/**
+ * struct cmn_pll_fixed_output_clk - CMN PLL output clocks information
+ * @id:	Clock specifier to be supplied
+ * @name: Clock name to be registered
+ * @rate: Clock rate
+ */
+struct cmn_pll_fixed_output_clk {
+	unsigned int id;
+	const char *name;
+	unsigned long rate;
+};
+
+/**
+ * struct clk_cmn_pll - CMN PLL hardware specific data
+ * @regmap: hardware regmap.
+ * @hw: handle between common and hardware-specific interfaces
+ */
+struct clk_cmn_pll {
+	struct regmap *regmap;
+	struct clk_hw hw;
+};
+
+#define CLK_PLL_OUTPUT(_id, _name, _rate) {		\
+	.id =		_id,				\
+	.name =		_name,				\
+	.rate =		_rate,				\
+}
+
+#define to_clk_cmn_pll(_hw) container_of(_hw, struct clk_cmn_pll, hw)
+
+static const struct regmap_config ipq_cmn_pll_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x7fc,
+	.fast_io = true,
+};
+
+static const struct cmn_pll_fixed_output_clk ipq9574_output_clks[] = {
+	CLK_PLL_OUTPUT(XO_24MHZ_CLK, "xo-24mhz", 24000000UL),
+	CLK_PLL_OUTPUT(SLEEP_32KHZ_CLK, "sleep-32khz", 32000UL),
+	CLK_PLL_OUTPUT(PCS_31P25MHZ_CLK, "pcs-31p25mhz", 31250000UL),
+	CLK_PLL_OUTPUT(NSS_1200MHZ_CLK, "nss-1200mhz", 1200000000UL),
+	CLK_PLL_OUTPUT(PPE_353MHZ_CLK, "ppe-353mhz", 353000000UL),
+	CLK_PLL_OUTPUT(ETH0_50MHZ_CLK, "eth0-50mhz", 50000000UL),
+	CLK_PLL_OUTPUT(ETH1_50MHZ_CLK, "eth1-50mhz", 50000000UL),
+	CLK_PLL_OUTPUT(ETH2_50MHZ_CLK, "eth2-50mhz", 50000000UL),
+	CLK_PLL_OUTPUT(ETH_25MHZ_CLK, "eth-25mhz", 25000000UL),
+};
+
+/*
+ * CMN PLL has the single parent clock, which supports the several
+ * possible parent clock rates, each parent clock rate is reflected
+ * by the specific reference index value in the hardware.
+ */
+static int ipq_cmn_pll_find_freq_index(unsigned long parent_rate)
+{
+	int index = -EINVAL;
+
+	switch (parent_rate) {
+	case 25000000:
+		index = 3;
+		break;
+	case 31250000:
+		index = 4;
+		break;
+	case 40000000:
+		index = 6;
+		break;
+	case 48000000:
+	case 96000000:
+		/*
+		 * Parent clock rate 48 MHZ and 96 MHZ take the same value
+		 * of reference clock index. 96 MHZ needs the source clock
+		 * divider to be programmed as 2.
+		 */
+		index = 7;
+		break;
+	case 50000000:
+		index = 8;
+		break;
+	default:
+		break;
+	}
+
+	return index;
+}
+
+static unsigned long clk_cmn_pll_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
+	u32 val, factor;
+
+	/*
+	 * The value of CMN_PLL_DIVIDER_CTRL_FACTOR is automatically adjusted
+	 * by HW according to the parent clock rate.
+	 */
+	regmap_read(cmn_pll->regmap, CMN_PLL_DIVIDER_CTRL, &val);
+	factor = FIELD_GET(CMN_PLL_DIVIDER_CTRL_FACTOR, val);
+
+	return parent_rate * 2 * factor;
+}
+
+static int clk_cmn_pll_determine_rate(struct clk_hw *hw,
+				      struct clk_rate_request *req)
+{
+	int ret;
+
+	/* Validate the rate of the single parent clock. */
+	ret = ipq_cmn_pll_find_freq_index(req->best_parent_rate);
+
+	return ret < 0 ? ret : 0;
+}
+
+/*
+ * This function is used to initialize the CMN PLL to enable the fixed
+ * rate output clocks. It is expected to be configured once.
+ */
+static int clk_cmn_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
+	int ret, index;
+	u32 val;
+
+	/*
+	 * Configure the reference input clock selection as per the given
+	 * parent clock. The output clock rates are always of fixed value.
+	 */
+	index = ipq_cmn_pll_find_freq_index(parent_rate);
+	if (index < 0)
+		return index;
+
+	ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
+				 CMN_PLL_REFCLK_INDEX,
+				 FIELD_PREP(CMN_PLL_REFCLK_INDEX, index));
+	if (ret)
+		return ret;
+
+	/*
+	 * Update the source clock rate selection and source clock
+	 * divider as 2 when the parent clock rate is 96 MHZ.
+	 */
+	if (parent_rate == 96000000) {
+		ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
+					 CMN_PLL_REFCLK_DIV,
+					 FIELD_PREP(CMN_PLL_REFCLK_DIV, 2));
+		if (ret)
+			return ret;
+
+		ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_SRC_SELECTION,
+					 CMN_PLL_REFCLK_SRC_DIV,
+					 FIELD_PREP(CMN_PLL_REFCLK_SRC_DIV, 0));
+		if (ret)
+			return ret;
+	}
+
+	/* Enable PLL locked detect. */
+	ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_CTRL,
+			      CMN_PLL_CTRL_LOCK_DETECT_EN);
+	if (ret)
+		return ret;
+
+	/*
+	 * Reset the CMN PLL block to ensure the updated configurations
+	 * take effect.
+	 */
+	ret = regmap_clear_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
+				CMN_ANA_EN_SW_RSTN);
+	if (ret)
+		return ret;
+
+	usleep_range(1000, 1200);
+	ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
+			      CMN_ANA_EN_SW_RSTN);
+	if (ret)
+		return ret;
+
+	/* Stability check of CMN PLL output clocks. */
+	return regmap_read_poll_timeout(cmn_pll->regmap, CMN_PLL_LOCKED, val,
+					(val & CMN_PLL_CLKS_LOCKED),
+					100, 100 * USEC_PER_MSEC);
+}
+
+static const struct clk_ops clk_cmn_pll_ops = {
+	.recalc_rate = clk_cmn_pll_recalc_rate,
+	.determine_rate = clk_cmn_pll_determine_rate,
+	.set_rate = clk_cmn_pll_set_rate,
+};
+
+static struct clk_hw *ipq_cmn_pll_clk_hw_register(struct platform_device *pdev)
+{
+	struct clk_parent_data pdata = { .index = 0 };
+	struct device *dev = &pdev->dev;
+	struct clk_init_data init = {};
+	struct clk_cmn_pll *cmn_pll;
+	struct regmap *regmap;
+	void __iomem *base;
+	int ret;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return ERR_CAST(base);
+
+	regmap = devm_regmap_init_mmio(dev, base, &ipq_cmn_pll_regmap_config);
+	if (IS_ERR(regmap))
+		return ERR_CAST(regmap);
+
+	cmn_pll = devm_kzalloc(dev, sizeof(*cmn_pll), GFP_KERNEL);
+	if (!cmn_pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = "cmn_pll";
+	init.parent_data = &pdata;
+	init.num_parents = 1;
+	init.ops = &clk_cmn_pll_ops;
+
+	cmn_pll->hw.init = &init;
+	cmn_pll->regmap = regmap;
+
+	ret = devm_clk_hw_register(dev, &cmn_pll->hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &cmn_pll->hw;
+}
+
+static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
+{
+	const struct cmn_pll_fixed_output_clk *fixed_clk;
+	struct clk_hw_onecell_data *hw_data;
+	struct device *dev = &pdev->dev;
+	struct clk_hw *cmn_pll_hw;
+	unsigned int num_clks;
+	struct clk_hw *hw;
+	int ret, i;
+
+	fixed_clk = ipq9574_output_clks;
+	num_clks = ARRAY_SIZE(ipq9574_output_clks);
+
+	hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks + 1),
+			       GFP_KERNEL);
+	if (!hw_data)
+		return -ENOMEM;
+
+	/*
+	 * Register the CMN PLL clock, which is the parent clock of
+	 * the fixed rate output clocks.
+	 */
+	cmn_pll_hw = ipq_cmn_pll_clk_hw_register(pdev);
+	if (IS_ERR(cmn_pll_hw))
+		return PTR_ERR(cmn_pll_hw);
+
+	/* Register the fixed rate output clocks. */
+	for (i = 0; i < num_clks; i++) {
+		hw = clk_hw_register_fixed_rate_parent_hw(dev, fixed_clk[i].name,
+							  cmn_pll_hw, 0,
+							  fixed_clk[i].rate);
+		if (IS_ERR(hw)) {
+			ret = PTR_ERR(hw);
+			goto unregister_fixed_clk;
+		}
+
+		hw_data->hws[fixed_clk[i].id] = hw;
+	}
+
+	/*
+	 * Provide the CMN PLL clock. The clock rate of CMN PLL
+	 * is configured to 12 GHZ by DT property assigned-clock-rates-u64.
+	 */
+	hw_data->hws[CMN_PLL_CLK] = cmn_pll_hw;
+	hw_data->num = num_clks + 1;
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data);
+	if (ret)
+		goto unregister_fixed_clk;
+
+	platform_set_drvdata(pdev, hw_data);
+
+	return 0;
+
+unregister_fixed_clk:
+	while (i > 0)
+		clk_hw_unregister(hw_data->hws[fixed_clk[--i].id]);
+
+	return ret;
+}
+
+static int ipq_cmn_pll_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	ret = devm_pm_clk_create(dev);
+	if (ret)
+		return ret;
+
+	/*
+	 * To access the CMN PLL registers, the GCC AHB & SYS clocks
+	 * of CMN PLL block need to be enabled.
+	 */
+	ret = pm_clk_add(dev, "ahb");
+	if (ret)
+		return dev_err_probe(dev, ret, "Fail to add AHB clock\n");
+
+	ret = pm_clk_add(dev, "sys");
+	if (ret)
+		return dev_err_probe(dev, ret, "Fail to add SYS clock\n");
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret)
+		return ret;
+
+	/* Register CMN PLL clock and fixed rate output clocks. */
+	ret = ipq_cmn_pll_register_clks(pdev);
+	pm_runtime_put(dev);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Fail to register CMN PLL clocks\n");
+
+	return 0;
+}
+
+static void ipq_cmn_pll_clk_remove(struct platform_device *pdev)
+{
+	struct clk_hw_onecell_data *hw_data = platform_get_drvdata(pdev);
+	int i;
+
+	/*
+	 * The clock with index CMN_PLL_CLK is unregistered by
+	 * device management.
+	 */
+	for (i = 0; i < hw_data->num; i++) {
+		if (i != CMN_PLL_CLK)
+			clk_hw_unregister(hw_data->hws[i]);
+	}
+}
+
+static const struct dev_pm_ops ipq_cmn_pll_pm_ops = {
+	SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
+};
+
+static const struct of_device_id ipq_cmn_pll_clk_ids[] = {
+	{ .compatible = "qcom,ipq9574-cmn-pll", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ipq_cmn_pll_clk_ids);
+
+static struct platform_driver ipq_cmn_pll_clk_driver = {
+	.probe = ipq_cmn_pll_clk_probe,
+	.remove = ipq_cmn_pll_clk_remove,
+	.driver = {
+		.name = "ipq_cmn_pll",
+		.of_match_table = ipq_cmn_pll_clk_ids,
+		.pm = &ipq_cmn_pll_pm_ops,
+	},
+};
+module_platform_driver(ipq_cmn_pll_clk_driver);
+
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ CMN PLL Driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From quic_luoj at quicinc.com  Fri Dec 20 05:22:44 2024
From: quic_luoj at quicinc.com (Luo Jie)
Date: Fri, 20 Dec 2024 21:22:44 +0800
Subject: [PATCH v7 3/5] arm64: defconfig: Enable Qualcomm IPQ CMN PLL clock
 controller
In-Reply-To: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
References: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
Message-ID: <20241220-qcom_ipq_cmnpll-v7-3-438a1b5cb98e@quicinc.com>

The CMN PLL hardware block is available in the Qualcomm IPQ SoC such
as IPQ9574 and IPQ5332. It provides fixed rate output clocks to Ethernet
related hardware blocks such as external Ethernet PHY or switch. This
driver is initially being enabled for IPQ9574. All boards based on
IPQ9574 SoC will require to include this driver in the build.

This CMN PLL hardware block does not provide any other specific function
on the IPQ SoC other than enabling output clocks to Ethernet related
devices.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Luo Jie <quic_luoj 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 dfa5c8d5b658..92f60b04cbba 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1316,6 +1316,7 @@ CONFIG_QCOM_CLK_SMD_RPM=y
 CONFIG_QCOM_CLK_RPMH=y
 CONFIG_IPQ_APSS_6018=y
 CONFIG_IPQ_APSS_5018=y
+CONFIG_IPQ_CMN_PLL=m
 CONFIG_IPQ_GCC_5018=y
 CONFIG_IPQ_GCC_5332=y
 CONFIG_IPQ_GCC_6018=y

-- 
2.34.1



From quic_luoj at quicinc.com  Fri Dec 20 05:22:45 2024
From: quic_luoj at quicinc.com (Luo Jie)
Date: Fri, 20 Dec 2024 21:22:45 +0800
Subject: [PATCH v7 4/5] arm64: dts: qcom: Add CMN PLL node for IPQ9574 SoC
In-Reply-To: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
References: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
Message-ID: <20241220-qcom_ipq_cmnpll-v7-4-438a1b5cb98e@quicinc.com>

The CMN PLL clock controller allows selection of an input clock rate
from a defined set of input clock rates. It in-turn supplies fixed
rate output clocks to the hardware blocks that provide the ethernet
functions such as PPE (Packet Process Engine) and connected switch or
PHY, and to GCC.

The reference clock of CMN PLL is routed from XO to the CMN PLL through
the internal WiFi block.
.XO (48 MHZ or 96 MHZ)-->WiFi (multiplier/divider)-->48 MHZ to CMN PLL.

The reference input clock from WiFi to CMN PLL is fully controlled by
the bootstrap pins which select the XO frequency (48 MHZ or 96 MHZ).
Based on this frequency, the divider in the internal Wi-Fi block is
automatically configured by hardware (1 for 48 MHZ, 2 for 96 MHZ), to
ensure output clock to CMN PLL is 48 MHZ.

Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
---
 arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 17 +++++++++++++++-
 arch/arm64/boot/dts/qcom/ipq9574.dtsi            | 26 +++++++++++++++++++++++-
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
index 91e104b0f865..bb1ff79360d3 100644
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
@@ -3,7 +3,7 @@
  * IPQ9574 RDP board common device tree source
  *
  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 /dts-v1/;
@@ -164,6 +164,21 @@ &usb3 {
 	status = "okay";
 };
 
+/*
+ * The bootstrap pins for the board select the XO clock frequency
+ * (48 MHZ or 96 MHZ used for different RDP type board). This setting
+ * automatically enables the right dividers, to ensure the reference
+ * clock output from WiFi to the CMN PLL is 48 MHZ.
+ */
+&ref_48mhz_clk {
+	clock-div = <1>;
+	clock-mult = <1>;
+};
+
 &xo_board_clk {
 	clock-frequency = <24000000>;
 };
+
+&xo_clk {
+	clock-frequency = <48000000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
index d1fd35ebc4a2..475868a241cc 100644
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -3,10 +3,11 @@
  * IPQ9574 SoC device tree source
  *
  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <dt-bindings/clock/qcom,apss-ipq.h>
+#include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
 #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
 #include <dt-bindings/interconnect/qcom,ipq9574.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -19,6 +20,12 @@ / {
 	#size-cells = <2>;
 
 	clocks {
+		ref_48mhz_clk: ref-48mhz-clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&xo_clk>;
+			#clock-cells = <0>;
+		};
+
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
@@ -28,6 +35,11 @@ xo_board_clk: xo-board-clk {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
 		};
+
+		xo_clk: xo-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
 	};
 
 	cpus {
@@ -243,6 +255,18 @@ mdio: mdio at 90000 {
 			status = "disabled";
 		};
 
+		cmn_pll: clock-controller at 9b000 {
+			compatible = "qcom,ipq9574-cmn-pll";
+			reg = <0x0009b000 0x800>;
+			clocks = <&ref_48mhz_clk>,
+				 <&gcc GCC_CMN_12GPLL_AHB_CLK>,
+				 <&gcc GCC_CMN_12GPLL_SYS_CLK>;
+			clock-names = "ref", "ahb", "sys";
+			#clock-cells = <1>;
+			assigned-clocks = <&cmn_pll CMN_PLL_CLK>;
+			assigned-clock-rates-u64 = /bits/ 64 <12000000000>;
+		};
+
 		qfprom: efuse at a4000 {
 			compatible = "qcom,ipq9574-qfprom", "qcom,qfprom";
 			reg = <0x000a4000 0x5a1>;

-- 
2.34.1



From will at kernel.org  Fri Dec 20 05:25:50 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 20 Dec 2024 13:25:50 +0000
Subject: =?utf-8?Q?=E2=9D=8C_FAIL=3A_Test_repor?= =?utf-8?Q?t?= for
 for-kernelci (6.13.0-rc3, upstream-arm-next, 06a57361)
In-Reply-To: <CAMj1kXGx+Li4qwh_05Uf-aTtEOLSThv8o3JjKgWrPp9t8rqQyg@mail.gmail.com>
References: <64955.124121918121002524@us-mta-554.us.mimecast.lan>
 <20241220123526.GA26697@willie-the-truck>
 <CAMj1kXENrzsF6JzvbGSwiJT5nupfJbij86zp0k2+YbqUCqvqNA@mail.gmail.com>
 <CAMj1kXGx+Li4qwh_05Uf-aTtEOLSThv8o3JjKgWrPp9t8rqQyg@mail.gmail.com>
Message-ID: <20241220132549.GA26731@willie-the-truck>

On Fri, Dec 20, 2024 at 02:06:21PM +0100, Ard Biesheuvel wrote:
> On Fri, 20 Dec 2024 at 13:49, Ard Biesheuvel <ardb at kernel.org> wrote:
> >
> > On Fri, 20 Dec 2024 at 13:35, Will Deacon <will at kernel.org> wrote:
> > >
> > > On Thu, Dec 19, 2024 at 11:12:08PM -0000, cki-project at redhat.com wrote:
> > > > Hi, we tested your kernel and here are the results:
> > > >
> > > >     Overall result: FAILED
> > > >              Merge: OK
> > > >            Compile: OK
> > > >               Test: FAILED (Did not boot)
> > > >
> > > >
> > > > 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/redhat:1596629923
> > > >
> > > > One or more kernel builds failed:
> > > >     Builds that are failing to boot:
> > > >          aarch64 - https://datawarehouse.cki-project.org/kcidb/builds/redhat:1596629923-aarch64-kernel
> > >
> > > Hmm, I can't find any console logs here. Did the machines really fail that
> > > early?
> > >
> >
> > This appears to be my fault: commit 32d053d6f5e92efd
> >
> >   arm64/mm: Drop configurable 48-bit physical address space limit
> >
> > inadvertently sets CONFIG_ARM64_LPA2 for all VA space sizes. The
> > following hunk needs to be applied to address this
> >
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -1418,7 +1418,7 @@ config ARM64_VA_BITS
> >
> >  config ARM64_LPA2
> >         def_bool y
> > -       depends on !ARM64_64K_PAGES
> > +       depends on ARM64_VA_BITS_52 && !ARM64_64K_PAGES
> >
> >  choice
> >         prompt "Endianness"
> 
> On second thought, let's just omit commit 32d053d6f5e92efd  for now -
> it's at the tip of the for-next/mm branch so it can just be dropped.
> 
> I'll revisit this later - I have to double check that non-LPA2 configs
> (such as the one this report is about) work correctly on LPA2 capable
> hardware, and don't deviate from LPA2 configs booting with arm64.nolva

Sure thing, I'll drop it for now. I've managed to repro the failure
under qemu using the CKI .config, so I'll check that things are happy
again before I pushed the updated branch.

Will


From brgl at bgdev.pl  Fri Dec 20 05:40:44 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 20 Dec 2024 14:40:44 +0100
Subject: [PATCH v3 3/7] dt-bindings: gpio: brcmstb: permit gpio-line-names property
In-Reply-To: <CAPY8ntBJqukSJs7VUXvUFAsiKqNWknL8VjgtQG_VAEmw576EPQ@mail.gmail.com>
References: <20241212-dt-bcm2712-fixes-v3-0-44a7f3390331@raspberrypi.com>
 <20241212-dt-bcm2712-fixes-v3-3-44a7f3390331@raspberrypi.com>
 <CACRpkdaB9kqcjmhaXd5RxpYvqdSVMZkj0wHAtEgdqDs03+wzJg@mail.gmail.com> <CAPY8ntBJqukSJs7VUXvUFAsiKqNWknL8VjgtQG_VAEmw576EPQ@mail.gmail.com>
Message-ID: <CAMRc=McmtEuc06YdEOXho8hkW30hYEYOtbOR3+mttmg4yrzrxg@mail.gmail.com>

On Fri, Dec 20, 2024 at 2:02?PM Dave Stevenson
<dave.stevenson at raspberrypi.com> wrote:
>
> Hi Linus
>
> On Fri, 20 Dec 2024 at 12:50, Linus Walleij <linus.walleij at linaro.org> wrote:
> >
> > On Thu, Dec 12, 2024 at 7:36?PM Dave Stevenson
> > <dave.stevenson at raspberrypi.com> wrote:
> >
> > > gpio-line-names is a generic property that can be supported by any
> > > GPIO controller, so permit it through the binding.
> > >
> > > It is permitted to have a variable number of GPIOs per node based
> > > on brcm,gpio-bank-widths, so define an arbitrary maximum number of
> > > items based on current users.
> > >
> > > Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> >
> > Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>
> Thank you.
>
> > Perhaps Bartosz can just apply this one patch separately?
>
> I believe he already has, but commented against the cover letter
> rather than this patch -
> https://lore.kernel.org/linux-arm-kernel/173434013318.38429.808413721248542013.b4-ty at linaro.org/
>

Ah, this is how b4 works. Even if you apply a single patch, it
responds to the cover letter (or the first patch in the series if
there's no cover letter).

Bart


From will at kernel.org  Fri Dec 20 05:43:24 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 20 Dec 2024 13:43:24 +0000
Subject: =?utf-8?Q?=E2=9D=8C_FAIL=3A_Test_repor?= =?utf-8?Q?t?= for
 for-kernelci (6.13.0-rc3, upstream-arm-next, 06a57361)
In-Reply-To: <20241220132549.GA26731@willie-the-truck>
References: <64955.124121918121002524@us-mta-554.us.mimecast.lan>
 <20241220123526.GA26697@willie-the-truck>
 <CAMj1kXENrzsF6JzvbGSwiJT5nupfJbij86zp0k2+YbqUCqvqNA@mail.gmail.com>
 <CAMj1kXGx+Li4qwh_05Uf-aTtEOLSThv8o3JjKgWrPp9t8rqQyg@mail.gmail.com>
 <20241220132549.GA26731@willie-the-truck>
Message-ID: <20241220134324.GB26731@willie-the-truck>

On Fri, Dec 20, 2024 at 01:25:50PM +0000, Will Deacon wrote:
> On Fri, Dec 20, 2024 at 02:06:21PM +0100, Ard Biesheuvel wrote:
> > On Fri, 20 Dec 2024 at 13:49, Ard Biesheuvel <ardb at kernel.org> wrote:
> > >
> > > On Fri, 20 Dec 2024 at 13:35, Will Deacon <will at kernel.org> wrote:
> > > >
> > > > On Thu, Dec 19, 2024 at 11:12:08PM -0000, cki-project at redhat.com wrote:
> > > > > Hi, we tested your kernel and here are the results:
> > > > >
> > > > >     Overall result: FAILED
> > > > >              Merge: OK
> > > > >            Compile: OK
> > > > >               Test: FAILED (Did not boot)
> > > > >
> > > > >
> > > > > 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/redhat:1596629923
> > > > >
> > > > > One or more kernel builds failed:
> > > > >     Builds that are failing to boot:
> > > > >          aarch64 - https://datawarehouse.cki-project.org/kcidb/builds/redhat:1596629923-aarch64-kernel
> > > >
> > > > Hmm, I can't find any console logs here. Did the machines really fail that
> > > > early?
> > > >
> > >
> > > This appears to be my fault: commit 32d053d6f5e92efd
> > >
> > >   arm64/mm: Drop configurable 48-bit physical address space limit
> > >
> > > inadvertently sets CONFIG_ARM64_LPA2 for all VA space sizes. The
> > > following hunk needs to be applied to address this
> > >
> > > --- a/arch/arm64/Kconfig
> > > +++ b/arch/arm64/Kconfig
> > > @@ -1418,7 +1418,7 @@ config ARM64_VA_BITS
> > >
> > >  config ARM64_LPA2
> > >         def_bool y
> > > -       depends on !ARM64_64K_PAGES
> > > +       depends on ARM64_VA_BITS_52 && !ARM64_64K_PAGES
> > >
> > >  choice
> > >         prompt "Endianness"
> > 
> > On second thought, let's just omit commit 32d053d6f5e92efd  for now -
> > it's at the tip of the for-next/mm branch so it can just be dropped.
> > 
> > I'll revisit this later - I have to double check that non-LPA2 configs
> > (such as the one this report is about) work correctly on LPA2 capable
> > hardware, and don't deviate from LPA2 configs booting with arm64.nolva
> 
> Sure thing, I'll drop it for now. I've managed to repro the failure
> under qemu using the CKI .config, so I'll check that things are happy
> again before I pushed the updated branch.

Ok, now pushed!

Will


From daniel.machon at microchip.com  Fri Dec 20 05:48:48 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:48 +0100
Subject: [PATCH net-next v5 9/9] dt-bindings: net: sparx5: document RGMII
 delays
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-9-fa8ba5dff732@microchip.com>

The lan969x switch device supports two RGMII port interfaces that can be
configured for MAC level rx and tx delays. Document two new properties
{rx,tx}-internal-delay-ps in the bindings, used to select these delays.

Tested-by: Robert Marko <robert.marko at sartura.hr>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 .../bindings/net/microchip,sparx5-switch.yaml          | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml b/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
index dedfad526666..a73fc5036905 100644
--- a/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
+++ b/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
@@ -129,6 +129,24 @@ properties:
             minimum: 0
             maximum: 383
 
+          rx-internal-delay-ps:
+            description:
+              RGMII Receive Clock Delay defined in pico seconds, used to select
+              the DLL phase shift between 1000 ps (45 degree shift at 1Gbps) and
+              3300 ps (147 degree shift at 1Gbps). A value of 0 ps will disable
+              any delay. The Default is no delay.
+            enum: [0, 1000, 1700, 2000, 2500, 3000, 3300]
+            default: 0
+
+          tx-internal-delay-ps:
+            description:
+              RGMII Transmit Clock Delay defined in pico seconds, used to select
+              the DLL phase shift between 1000 ps (45 degree shift at 1Gbps) and
+              3300 ps (147 degree shift at 1Gbps). A value of 0 ps will disable
+              any delay. The Default is no delay.
+            enum: [0, 1000, 1700, 2000, 2500, 3000, 3300]
+            default: 0
+
         required:
           - reg
           - phys

-- 
2.34.1



From tudor.ambarus at linaro.org  Fri Dec 20 05:49:56 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 13:49:56 +0000
Subject: [PATCH v6 1/5] dt-bindings: mailbox: allow #mbox-cells = <0>;
In-Reply-To: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
References: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
Message-ID: <20241220-acpm-v4-upstream-mbox-v6-1-a6942806e52a@linaro.org>

There are mailbox clients that can discover the mailbox channel
identifiers at runtime. For such cases passing the channel
identifiers via DT is redundant.

The framework API will be supplied with mbox_request_channel_by_args().
It will allow clients to request a mailbox channel using the runtime
discovered channel identifiers.

Add support for referencing controllers solely by phandle.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 Documentation/devicetree/bindings/mailbox/mailbox.txt | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/mailbox/mailbox.txt b/Documentation/devicetree/bindings/mailbox/mailbox.txt
index af8ecee2ac68..fc31a4a3b637 100644
--- a/Documentation/devicetree/bindings/mailbox/mailbox.txt
+++ b/Documentation/devicetree/bindings/mailbox/mailbox.txt
@@ -6,8 +6,7 @@ assign appropriate mailbox channel to client drivers.
 * Mailbox Controller
 
 Required property:
-- #mbox-cells: Must be at least 1. Number of cells in a mailbox
-		specifier.
+- #mbox-cells: Must be at least 0. Number of cells in a mailbox specifier.
 
 Example:
 	mailbox: mailbox {

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Fri Dec 20 05:49:55 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 13:49:55 +0000
Subject: [PATCH v6 0/5] mailbox: add Samsung Exynos driver
Message-ID: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>

The Samsung Exynos mailbox controller, used on Google GS101 SoC, has 16 flag
bits for hardware interrupt generation and a shared register for passing
mailbox messages. When the controller is used by the ACPM protocol the shared
register is ignored and the mailbox controller acts as a doorbell.
The controller just raises the interrupt to APM after the ACPM protocol has
written the message to SRAM.

Changes in v6:
- mailbox: add support for clients to request channels by arguments.
  Used by the ACPM interface where the channel identifiers are
  discovered at runtime. Passing them via DT would be redundant.
  Initial version sent on its own to gather feedback:
  - Link: https://lore.kernel.org/all/20241219-mbox_request_channel_by_args-v1-0-617a6910f842 at linaro.org/
  - the patches differ from the initial version as they allow #mbox-cells = 0
- bindings: google,gs101-mbox: update description, make #mbox-cells
  const 0.
- mailbox: exynos-mailbox:
  - replace exynos_mbox_of_xlate with exynos_mbox_xlate, the channel
    identifiers are discovered at runtime and passed as
    'const struct mbox_xlate_args *sp'
  - in the xlate method, the first argument is the channel and the
    second the type, as channels can be configured either in DOORBELL or
    DATA modes. This becomes an example for when an exynos_mbox_of_xlate()
    method will be introduced.
  - make exynos_mbox_chan_index() inline and directly
    return chan - chan->mbox->chans;
- drop Krzysztof's and Peter's R-b tags from the google,gs101-mbox
  bindings and the Samsung Exynos mailbox driver as they were updated.
- add Krzysztof's and Peter's R-b tags to the MAINTAINERS patch
- Link to v5: https://lore.kernel.org/r/20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84 at linaro.org

Changes in v5:
- fix dt-bindings by using the correct compatible name in the example
- drop redundand "bindings" from the dt-bindings patch subject
- rebase on top of v6.13-rc3
- Link to v4: https://lore.kernel.org/r/20241212-acpm-v4-upstream-mbox-v4-0-02f8de92cfaf at linaro.org

Changes in v4:
- rename bindings file to be based on compatible: google,gs101-acpm-mbox
- specify doorbell or data mode via '#mbox-cells' dt property. Update
  driver and introduce exynos_mbox_of_xlate() to parse the mode.
- s/samsung/Samsung/, s/exynos/Exynos/
- use writel instead of writel_relaxed
- remove stray of_match_ptr()
- Link to v3: https://lore.kernel.org/linux-arm-kernel/20241205174137.190545-1-tudor.ambarus at linaro.org/

Changes in v3:
- decouple the mailbox controller driver from the ACPM protocol driver
- address Krzysztof's review comments

v2:
https://lore.kernel.org/linux-arm-kernel/20241017163649.3007062-1-tudor.ambarus at linaro.org/

v1:
https://lore.kernel.org/linux-arm-kernel/20241004165301.1979527-1-tudor.ambarus at linaro.org/

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Tudor Ambarus (5):
      dt-bindings: mailbox: allow #mbox-cells = <0>;
      dt-bindings: mailbox: add google,gs101-mbox
      mailbox: add support for clients to request channels by args
      mailbox: add Samsung Exynos driver
      MAINTAINERS: add entry for Samsung Exynos mailbox driver

 .../bindings/mailbox/google,gs101-mbox.yaml        |  70 +++++++++
 .../devicetree/bindings/mailbox/mailbox.txt        |   3 +-
 MAINTAINERS                                        |  10 ++
 drivers/mailbox/Kconfig                            |  11 ++
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/exynos-mailbox.c                   | 174 +++++++++++++++++++++
 drivers/mailbox/mailbox.c                          |  60 +++++++
 include/dt-bindings/mailbox/google,gs101.h         |  14 ++
 include/linux/mailbox.h                            |  17 ++
 include/linux/mailbox_client.h                     |   3 +
 include/linux/mailbox_controller.h                 |   4 +
 11 files changed, 366 insertions(+), 2 deletions(-)
---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241212-acpm-v4-upstream-mbox-948714004b05

Best regards,
-- 
Tudor Ambarus <tudor.ambarus at linaro.org>



From tudor.ambarus at linaro.org  Fri Dec 20 05:49:57 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 13:49:57 +0000
Subject: [PATCH v6 2/5] dt-bindings: mailbox: add google,gs101-mbox
In-Reply-To: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
References: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
Message-ID: <20241220-acpm-v4-upstream-mbox-v6-2-a6942806e52a@linaro.org>

Add bindings for the Samsung Exynos Mailbox Controller.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 .../bindings/mailbox/google,gs101-mbox.yaml        | 70 ++++++++++++++++++++++
 include/dt-bindings/mailbox/google,gs101.h         | 14 +++++
 2 files changed, 84 insertions(+)

diff --git a/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
new file mode 100644
index 000000000000..a1fbc3b2b9de
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright 2024 Linaro Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/google,gs101-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos Mailbox Controller
+
+maintainers:
+  - Tudor Ambarus <tudor.ambarus at linaro.org>
+
+description: |
+  The Samsung Exynos mailbox controller, used on Google GS101 SoC, has 16 flag
+  bits for hardware interrupt generation and a shared register for passing
+  mailbox messages. When the controller is used by the ACPM protocol the shared
+  register is ignored and the mailbox controller acts as a doorbell.
+  The controller just raises the interrupt to the firmware after the
+  ACPM protocol has written the message to SRAM.
+
+properties:
+  compatible:
+    const: google,gs101-mbox
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: pclk
+
+  interrupts:
+    description: IRQ line for the RX mailbox.
+    maxItems: 1
+
+  '#mbox-cells':
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - '#mbox-cells'
+
+additionalProperties: false
+
+examples:
+  # Doorbell mode.
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/google,gs101.h>
+
+    soc {
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        ap2apm_mailbox: mailbox at 17610000 {
+            compatible = "google,gs101-mbox";
+            reg = <0x17610000 0x1000>;
+            clocks = <&cmu_apm CLK_GOUT_APM_MAILBOX_APM_AP_PCLK>;
+            clock-names = "pclk";
+            interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 0>;
+            #mbox-cells = <0>;
+        };
+    };
diff --git a/include/dt-bindings/mailbox/google,gs101.h b/include/dt-bindings/mailbox/google,gs101.h
new file mode 100644
index 000000000000..7ff4fe669f9e
--- /dev/null
+++ b/include/dt-bindings/mailbox/google,gs101.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright 2024 Linaro Ltd.
+ *
+ * This header provides constants for the defined mailbox channel types.
+ */
+
+#ifndef _DT_BINDINGS_MAILBOX_GOOGLE_GS101_H
+#define _DT_BINDINGS_MAILBOX_GOOGLE_GS101_H
+
+#define DOORBELL	0
+#define DATA		1
+
+#endif /* _DT_BINDINGS_MAILBOX_GOOGLE_GS101_H */

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Fri Dec 20 05:49:58 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 13:49:58 +0000
Subject: [PATCH v6 3/5] mailbox: add support for clients to request
 channels by args
In-Reply-To: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
References: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
Message-ID: <20241220-acpm-v4-upstream-mbox-v6-3-a6942806e52a@linaro.org>

There are clients that can discover channel identifiers at runtime by
parsing a shared memory for example, as in the ACPM interface's case.

Supply a new framework API: mbox_request_channel_by_args().

It works by supplying the usual client pointer as the first argument,
the usual index of the mailbox specifier in the 'mboxes' property as
a second argument, and a pointer to a 'const struct mbox_xlate_args'
as a third. The newly introduced struct is modeled after
'struct of_phandle_args'. The API identifies the controller's device
node, and then calls that controller's xlate() method that will return
a pointer to a mbox_chan or a ERR_PTR. The binding between the channel
and the client is done in the typical way.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/mailbox/mailbox.c          | 60 ++++++++++++++++++++++++++++++++++++++
 include/linux/mailbox.h            | 17 +++++++++++
 include/linux/mailbox_client.h     |  3 ++
 include/linux/mailbox_controller.h |  4 +++
 4 files changed, 84 insertions(+)

diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index d3d26a2c9895..0eecffd5a2ad 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -467,6 +467,66 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
 }
 EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
 
+/**
+ * mbox_request_channel_by_args - request a mailbox channel using client's
+ * channel identifiers.
+ * @cl: identity of the client requesting the channel.
+ * @index: index of mailbox specifier in 'mboxes' property.
+ * @spec: arguments that describe the channel.
+ *
+ * Used by clients that can discover the channel identifiers at runtime (by
+ * parsing a shared memory for example). The description of
+ * mbox_request_channel() applies here as well.
+ *
+ * Return: Pointer to the channel assigned to the client if successful.
+ *         ERR_PTR for request failure.
+ */
+struct mbox_chan *mbox_request_channel_by_args(struct mbox_client *cl,
+			int index, const struct mbox_xlate_args *mbox_spec)
+{
+	struct of_phandle_args of_args;
+	struct device *dev = cl->dev;
+	struct mbox_controller *mbox;
+	struct mbox_chan *chan;
+	int ret;
+
+	if (!dev || !dev->of_node) {
+		pr_debug("%s: No owner device node\n", __func__);
+		return ERR_PTR(-ENODEV);
+	}
+
+	if (of_parse_phandle_with_args(dev->of_node, "mboxes",
+				       "#mbox-cells", index, &of_args)) {
+		dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__);
+		return ERR_PTR(-ENODEV);
+	}
+
+	mutex_lock(&con_mutex);
+
+	chan = ERR_PTR(-EPROBE_DEFER);
+	list_for_each_entry(mbox, &mbox_cons, node)
+		if (mbox->dev->of_node == of_args.np && mbox->xlate) {
+			chan = mbox->xlate(mbox, mbox_spec);
+			if (!IS_ERR(chan))
+				break;
+		}
+
+	of_node_put(of_args.np);
+
+	if (IS_ERR(chan)) {
+		mutex_unlock(&con_mutex);
+		return chan;
+	}
+
+	ret = __mbox_bind_client(chan, cl);
+	if (ret)
+		chan = ERR_PTR(ret);
+
+	mutex_unlock(&con_mutex);
+	return chan;
+}
+EXPORT_SYMBOL_GPL(mbox_request_channel_by_args);
+
 /**
  * mbox_free_channel - The client relinquishes control of a mailbox
  *			channel by this call.
diff --git a/include/linux/mailbox.h b/include/linux/mailbox.h
new file mode 100644
index 000000000000..cef88c5ae49d
--- /dev/null
+++ b/include/linux/mailbox.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#ifndef __LINUX_MAILBOX_H
+#define __LINUX_MAILBOX_H
+
+#include <linux/types.h>
+
+#define MBOX_XLATE_MAX_ARGS 16
+struct mbox_xlate_args {
+	int args_count;
+	u32 args[MBOX_XLATE_MAX_ARGS];
+};
+
+#endif /* __LINUX_MAILBOX_H */
diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h
index 734694912ef7..06e2721313ca 100644
--- a/include/linux/mailbox_client.h
+++ b/include/linux/mailbox_client.h
@@ -9,6 +9,7 @@
 
 #include <linux/of.h>
 #include <linux/device.h>
+#include <linux/mailbox.h>
 
 struct mbox_chan;
 
@@ -41,6 +42,8 @@ int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl);
 struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
 					      const char *name);
 struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index);
+struct mbox_chan *mbox_request_channel_by_args(struct mbox_client *cl,
+			int index, const struct mbox_xlate_args *mbox_spec);
 int mbox_send_message(struct mbox_chan *chan, void *mssg);
 int mbox_flush(struct mbox_chan *chan, unsigned long timeout);
 void mbox_client_txdone(struct mbox_chan *chan, int r); /* atomic */
diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h
index 6fee33cb52f5..dfddcf966f9f 100644
--- a/include/linux/mailbox_controller.h
+++ b/include/linux/mailbox_controller.h
@@ -8,6 +8,7 @@
 #include <linux/hrtimer.h>
 #include <linux/device.h>
 #include <linux/completion.h>
+#include <linux/mailbox.h>
 
 struct mbox_chan;
 
@@ -67,6 +68,7 @@ struct mbox_chan_ops {
  * @txpoll_period:	If 'txdone_poll' is in effect, the API polls for
  *			last TX's status after these many millisecs
  * @of_xlate:		Controller driver specific mapping of channel via DT
+ * @xlate:		Controller driver specific mapping of channel
  * @poll_hrt:		API private. hrtimer used to poll for TXDONE on all
  *			channels.
  * @node:		API private. To hook into list of controllers.
@@ -81,6 +83,8 @@ struct mbox_controller {
 	unsigned txpoll_period;
 	struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
 				      const struct of_phandle_args *sp);
+	struct mbox_chan *(*xlate)(struct mbox_controller *mbox,
+				   const struct mbox_xlate_args *sp);
 	/* Internal to API */
 	struct hrtimer poll_hrt;
 	spinlock_t poll_hrt_lock;

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Fri Dec 20 05:49:59 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 13:49:59 +0000
Subject: [PATCH v6 4/5] mailbox: add Samsung Exynos driver
In-Reply-To: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
References: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
Message-ID: <20241220-acpm-v4-upstream-mbox-v6-4-a6942806e52a@linaro.org>

The Samsung Exynos mailbox controller, used on Google GS101 SoC, has 16
flag bits for hardware interrupt generation and a shared register for
passing mailbox messages. When the controller is used by the
ACPM protocol the shared register is ignored and the mailbox controller
acts as a doorbell. The controller just raises the interrupt to APM
after the ACPM protocol has written the message to SRAM.

Add support for the Samsung Exynos mailbox controller.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/mailbox/Kconfig          |  11 +++
 drivers/mailbox/Makefile         |   2 +
 drivers/mailbox/exynos-mailbox.c | 174 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 187 insertions(+)

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 8ecba7fb999e..44b808c4d97f 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -36,6 +36,17 @@ config ARM_MHU_V3
 	  that provides different means of transports: supported extensions
 	  will be discovered and possibly managed at probe-time.
 
+config EXYNOS_MBOX
+	tristate "Exynos Mailbox"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	help
+	  Say Y here if you want to build the Samsung Exynos Mailbox controller
+	  driver. The controller has 16 flag bits for hardware interrupt
+	  generation and a shared register for passing mailbox messages.
+	  When the controller is used by the ACPM protocol the shared register
+	  is ignored and the mailbox controller acts as a doorbell that raises
+	  the interrupt to the ACPM firmware.
+
 config IMX_MBOX
 	tristate "i.MX Mailbox"
 	depends on ARCH_MXC || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 5f4f5b0ce2cc..86192b5c7c32 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -11,6 +11,8 @@ obj-$(CONFIG_ARM_MHU_V2)	+= arm_mhuv2.o
 
 obj-$(CONFIG_ARM_MHU_V3)	+= arm_mhuv3.o
 
+obj-$(CONFIG_EXYNOS_MBOX)	+= exynos-mailbox.o
+
 obj-$(CONFIG_IMX_MBOX)	+= imx-mailbox.o
 
 obj-$(CONFIG_ARMADA_37XX_RWTM_MBOX)	+= armada-37xx-rwtm-mailbox.o
diff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c
new file mode 100644
index 000000000000..07bbc6b442ef
--- /dev/null
+++ b/drivers/mailbox/exynos-mailbox.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#include <dt-bindings/mailbox/google,gs101.h>
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define EXYNOS_MBOX_MCUCTRL		0x0	/* Mailbox Control Register */
+#define EXYNOS_MBOX_INTCR0		0x24	/* Interrupt Clear Register 0 */
+#define EXYNOS_MBOX_INTMR0		0x28	/* Interrupt Mask Register 0 */
+#define EXYNOS_MBOX_INTSR0		0x2c	/* Interrupt Status Register 0 */
+#define EXYNOS_MBOX_INTMSR0		0x30	/* Interrupt Mask Status Register 0 */
+#define EXYNOS_MBOX_INTGR1		0x40	/* Interrupt Generation Register 1 */
+#define EXYNOS_MBOX_INTMR1		0x48	/* Interrupt Mask Register 1 */
+#define EXYNOS_MBOX_INTSR1		0x4c	/* Interrupt Status Register 1 */
+#define EXYNOS_MBOX_INTMSR1		0x50	/* Interrupt Mask Status Register 1 */
+
+#define EXYNOS_MBOX_INTMR0_MASK		GENMASK(15, 0)
+#define EXYNOS_MBOX_INTGR1_MASK		GENMASK(15, 0)
+
+#define EXYNOS_MBOX_CHAN_COUNT		HWEIGHT32(EXYNOS_MBOX_INTGR1_MASK)
+
+enum {
+	EXYNOS_MBOX_CELL_ID,
+	EXYNOS_MBOX_CELL_TYPE,
+	EXYNOS_MBOX_CELLS
+};
+
+#define EXYNOS_MBOX_CELL_TYPE_COUNT	2
+
+/**
+ * struct exynos_mbox - driver's private data.
+ * @regs:	mailbox registers base address.
+ * @mbox:	pointer to the mailbox controller.
+ * @dev:	pointer to the mailbox device.
+ * @pclk:	pointer to the mailbox peripheral clock.
+ */
+struct exynos_mbox {
+	void __iomem *regs;
+	struct mbox_controller *mbox;
+	struct device *dev;
+	struct clk *pclk;
+};
+
+static inline int exynos_mbox_chan_index(struct mbox_chan *chan)
+{
+	return chan - chan->mbox->chans;
+}
+
+static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct exynos_mbox *exynos_mbox = dev_get_drvdata(chan->mbox->dev);
+	int index = exynos_mbox_chan_index(chan);
+
+	writel(BIT(index), exynos_mbox->regs + EXYNOS_MBOX_INTGR1);
+
+	return 0;
+}
+
+static const struct mbox_chan_ops exynos_mbox_chan_ops = {
+	.send_data = exynos_mbox_send_data,
+};
+
+static struct mbox_chan *exynos_mbox_xlate(struct mbox_controller *mbox,
+					   const struct mbox_xlate_args *sp)
+{
+	u32 id, type;
+
+	if (sp->args_count != EXYNOS_MBOX_CELLS) {
+		dev_err(mbox->dev, "Invalid argument count %d\n",
+			sp->args_count);
+		return ERR_PTR(-EINVAL);
+	}
+
+	id = sp->args[EXYNOS_MBOX_CELL_ID];
+	if (id >= mbox->num_chans) {
+		dev_err(mbox->dev, "Invalid channel ID %d\n", id);
+		return ERR_PTR(-EINVAL);
+	}
+
+	type = sp->args[EXYNOS_MBOX_CELL_TYPE];
+	if (type >= EXYNOS_MBOX_CELL_TYPE_COUNT) {
+		dev_err(mbox->dev, "Invalid channel type %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (type == DATA) {
+		dev_err(mbox->dev, "DATA channel type [%d] not supported\n",
+			type);
+		return ERR_PTR(-EINVAL);
+	};
+
+	return &mbox->chans[id];
+}
+
+static const struct of_device_id exynos_mbox_match[] = {
+	{ .compatible = "google,gs101-mbox" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos_mbox_match);
+
+static int exynos_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct exynos_mbox *exynos_mbox;
+	struct mbox_controller *mbox;
+	struct mbox_chan *chans;
+	int i;
+
+	exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL);
+	if (!exynos_mbox)
+		return -ENOMEM;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	chans = devm_kcalloc(dev, EXYNOS_MBOX_CHAN_COUNT, sizeof(*chans),
+			     GFP_KERNEL);
+	if (!chans)
+		return -ENOMEM;
+
+	exynos_mbox->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(exynos_mbox->regs))
+		return PTR_ERR(exynos_mbox->regs);
+
+	exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk");
+	if (IS_ERR(exynos_mbox->pclk))
+		return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk),
+				     "Failed to enable clock.\n");
+
+	mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT;
+	mbox->chans = chans;
+	mbox->dev = dev;
+	mbox->ops = &exynos_mbox_chan_ops;
+	mbox->xlate = exynos_mbox_xlate;
+
+	for (i = 0; i < EXYNOS_MBOX_CHAN_COUNT; i++)
+		chans[i].mbox = mbox;
+
+	exynos_mbox->dev = dev;
+	exynos_mbox->mbox = mbox;
+
+	platform_set_drvdata(pdev, exynos_mbox);
+
+	/* Mask out all interrupts. We support just polling channels for now. */
+	writel(EXYNOS_MBOX_INTMR0_MASK, exynos_mbox->regs + EXYNOS_MBOX_INTMR0);
+
+	return devm_mbox_controller_register(dev, mbox);
+}
+
+static struct platform_driver exynos_mbox_driver = {
+	.probe	= exynos_mbox_probe,
+	.driver	= {
+		.name = "exynos-acpm-mbox",
+		.of_match_table	= exynos_mbox_match,
+	},
+};
+module_platform_driver(exynos_mbox_driver);
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos mailbox driver");
+MODULE_LICENSE("GPL");

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Fri Dec 20 05:50:00 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 13:50:00 +0000
Subject: [PATCH v6 5/5] MAINTAINERS: add entry for Samsung Exynos mailbox
 driver
In-Reply-To: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
References: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
Message-ID: <20241220-acpm-v4-upstream-mbox-v6-5-a6942806e52a@linaro.org>

Add entry for the Samsung Exynos mailbox driver.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index baf0eeb9a355..6bef5fc5e4ee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3023,6 +3023,7 @@ F:	drivers/*/*s3c24*
 F:	drivers/*/*s3c64xx*
 F:	drivers/*/*s5pv210*
 F:	drivers/clocksource/samsung_pwm_timer.c
+F:	drivers/mailbox/exynos-mailbox.c
 F:	drivers/memory/samsung/
 F:	drivers/pwm/pwm-samsung.c
 F:	drivers/soc/samsung/
@@ -20717,6 +20718,15 @@ F:	arch/arm64/boot/dts/exynos/exynos850*
 F:	drivers/clk/samsung/clk-exynos850.c
 F:	include/dt-bindings/clock/exynos850.h
 
+SAMSUNG EXYNOS MAILBOX DRIVER
+M:	Tudor Ambarus <tudor.ambarus at linaro.org>
+L:	linux-kernel at vger.kernel.org
+L:	linux-samsung-soc at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
+F:	drivers/mailbox/exynos-mailbox.c
+F:	include/dt-bindings/mailbox/google,gs101.h
+
 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 M:	Krzysztof Kozlowski <krzk at kernel.org>
 L:	linux-crypto at vger.kernel.org

-- 
2.47.1.613.gc27f4b7a9f-goog



From kevin.brodsky at arm.com  Fri Dec 20 05:50:17 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri, 20 Dec 2024 14:50:17 +0100
Subject: [PATCH 01/10] mm: Move common parts of pagetable_*_[cd]tor to
 helpers
In-Reply-To: <0daabd32-cba4-4345-baa8-e8c66bc899ff@bytedance.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <20241219164425.2277022-2-kevin.brodsky@arm.com>
 <20241219171920.GB26279@noisy.programming.kicks-ass.net>
 <75cb4ff8-eb0c-4519-a30a-f8be717ba278@arm.com>
 <0daabd32-cba4-4345-baa8-e8c66bc899ff@bytedance.com>
Message-ID: <2f65f93e-9d44-4acc-b63c-8f5a35f59699@arm.com>

On 20/12/2024 12:46, Qi Zheng wrote:
> Hi Kevin,
>
> On 2024/12/20 18:49, Kevin Brodsky wrote:
>> [...]
>>
>> Qi, shall we collaborate to make our series complementary? I believe my
>> series covers patch 2 and 4 of your series, but it goes further by
>> covering all levels and all architectures, and patches introducing
>> ctor/dtor are already split as Alexander suggested on your series. So my
>> suggestion would be:
>>
>> * Remove patch 1 in my series - I'd just introduce
>> pagetable_{p4d,pgd}_[cd]tor with the same implementation as
>> pagetable_pud_[cd]tor.
>> * Remove patch 2 and 4 from your series and rebase it on mine.
>
> I quickly went through your patch series. It looks like my patch 2 and
> your patch 6 are duplicated, so you want me to remove my patch 2.
>
> But I think you may not be able to simple let arm64, riscv and x86 to
> use generic p4d_{alloc_one,free}(). Because even if
> CONFIG_PGTABLE_LEVELS > 4, the pgtable_l5_enabled() may not be true.
>
> For example, in arm64:
>
> #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);
> }

Correct. That's why the implementation of p4d_free() I introduce in
patch 6 checks mm_p4d_folded(), which is implemented as
!pgtable_l5_enabled() on those architectures (see last paragraph in
commit message). In fact it turns out Alexander suggested exactly this
approach [2].

>
> Did I miss something?
>
> My patch series is not only for cleanup, but also for fixes of
> UAF issue [1], so is it possible to rebase your patch series onto
> mine? I can post v3 ASAP.

I see, yours should be merged first then. The issue is that yours would
depend on some of the patches in mine, not the other way round.

My suggestion would then be for you to take patch 5, 6 and 7 from my
series, as they match Alexander's suggestions (and patch 5 is I think a
useful simplification), and replace patch 2 in your series with those. I
would then rebase my series on top and adapt it accordingly. Does that
sound reasonable?

- Kevin

[2]
https://lore.kernel.org/all/Z2RKpdv7pL34MIEt at tuxmaker.boeblingen.de.ibm.com/



From sudeep.holla at arm.com  Fri Dec 20 05:55:54 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 20 Dec 2024 13:55:54 +0000
Subject: [PATCH 1/3] dt-bindings: arm,psci: Allow S2RAM power_state
 parameter description
In-Reply-To: <349bac70-87e0-4870-a3f0-9f6a3b3e6824@oss.qualcomm.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
 <Z1LQOmEfFy640PjG@bogus>
 <54cc4221-ba5f-4741-9033-20874265ca01@oss.qualcomm.com>
 <Z2VUiHWHgbWowdal@bogus>
 <349bac70-87e0-4870-a3f0-9f6a3b3e6824@oss.qualcomm.com>
Message-ID: <Z2V3amqWYDUWA2uM@bogus>

On Fri, Dec 20, 2024 at 01:54:45PM +0100, Konrad Dybcio wrote:
> On 20.12.2024 12:27 PM, Sudeep Holla wrote:
> > On Thu, Dec 19, 2024 at 08:43:27PM +0100, Konrad Dybcio wrote:
> >> On 6.12.2024 11:21 AM, Sudeep Holla wrote:
> >>> On Mon, Oct 28, 2024 at 03:22:57PM +0100, Konrad Dybcio wrote:
> >>>> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> >>>>
> >>>> Certain firmware implementations (such as the ones found on Qualcomm
> >>>> SoCs between roughly 2015 and 2023) expose an S3-like S2RAM state
> >>>> through the CPU_SUSPEND call, as opposed to exposing PSCIv1.0's
> >>>> optional PSCI_SYSTEM_SUSPEND.
> >>>>
> >>>
> >>> If so, can you elaborate why s2idle doesn't work as an alternative to what
> >>> you are hacking up here.
> >>
> >> Please see other branches of this thread
> >>
> >>>
> >>>> This really doesn't work well with the model where we associate all
> >>>> calls to CPU_SUSPEND with cpuidle. Allow specifying a single special
> >>>> CPU_SUSPEND suspend parameter value that is to be treated just like
> >>>> SYSTEM_SUSPEND from the OS's point of view.
> >>>>
> >>>> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> >>>> ---
> >>>>  Documentation/devicetree/bindings/arm/psci.yaml | 6 ++++++
> >>>>  1 file changed, 6 insertions(+)
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml
> >>>> index cbb012e217ab80c1ca88e611e7acc06c6d56fad0..a6901878697c8e1ec1cbfed62298ae3bc58f2501 100644
> >>>> --- a/Documentation/devicetree/bindings/arm/psci.yaml
> >>>> +++ b/Documentation/devicetree/bindings/arm/psci.yaml
> >>>> @@ -98,6 +98,12 @@ properties:
> >>>>        [1] Kernel documentation - ARM idle states bindings
> >>>>          Documentation/devicetree/bindings/cpu/idle-states.yaml
> >>>>
> >>>> +  arm,psci-s2ram-param:
> >>>> +    $ref: /schemas/types.yaml#/definitions/uint32
> >>>> +    description:
> >>>> +      power_state parameter denoting the S2RAM/S3-like system suspend state
> >>>
> >>> Yet another NACK as this corresponds to PSCI SYSTEM_SUSPEND and as per
> >>> specification it takes no such parameter. This is just misleading.
> >>>
> >>
> >> Yeah PSCI_SYSTEM_SUSPEND takes care of this on platforms that expose it.
> >>
> >
> > And those that don't advertise/expose don't get to use, simple.
>
> The spec says:
>
> "The call is equivalent to using the CPU_SUSPEND call for the
> deepest possible platform powerdown state."
>

Please take a look at the preconditions for both the calls. They are
different.

--
Regards,
Sudeep


From konrad.dybcio at oss.qualcomm.com  Fri Dec 20 05:57:34 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 20 Dec 2024 14:57:34 +0100
Subject: [PATCH 1/3] dt-bindings: arm,psci: Allow S2RAM power_state
 parameter description
In-Reply-To: <Z2V3amqWYDUWA2uM@bogus>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
 <Z1LQOmEfFy640PjG@bogus>
 <54cc4221-ba5f-4741-9033-20874265ca01@oss.qualcomm.com>
 <Z2VUiHWHgbWowdal@bogus>
 <349bac70-87e0-4870-a3f0-9f6a3b3e6824@oss.qualcomm.com>
 <Z2V3amqWYDUWA2uM@bogus>
Message-ID: <c80c4cdb-48e1-4b6f-8ab8-fad6e100af00@oss.qualcomm.com>

On 20.12.2024 2:55 PM, Sudeep Holla wrote:
> On Fri, Dec 20, 2024 at 01:54:45PM +0100, Konrad Dybcio wrote:
>> On 20.12.2024 12:27 PM, Sudeep Holla wrote:
>>> On Thu, Dec 19, 2024 at 08:43:27PM +0100, Konrad Dybcio wrote:
>>>> On 6.12.2024 11:21 AM, Sudeep Holla wrote:
>>>>> On Mon, Oct 28, 2024 at 03:22:57PM +0100, Konrad Dybcio wrote:
>>>>>> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>>>>>
>>>>>> Certain firmware implementations (such as the ones found on Qualcomm
>>>>>> SoCs between roughly 2015 and 2023) expose an S3-like S2RAM state
>>>>>> through the CPU_SUSPEND call, as opposed to exposing PSCIv1.0's
>>>>>> optional PSCI_SYSTEM_SUSPEND.
>>>>>>
>>>>>
>>>>> If so, can you elaborate why s2idle doesn't work as an alternative to what
>>>>> you are hacking up here.
>>>>
>>>> Please see other branches of this thread
>>>>
>>>>>
>>>>>> This really doesn't work well with the model where we associate all
>>>>>> calls to CPU_SUSPEND with cpuidle. Allow specifying a single special
>>>>>> CPU_SUSPEND suspend parameter value that is to be treated just like
>>>>>> SYSTEM_SUSPEND from the OS's point of view.
>>>>>>
>>>>>> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>>>>> ---
>>>>>>  Documentation/devicetree/bindings/arm/psci.yaml | 6 ++++++
>>>>>>  1 file changed, 6 insertions(+)
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml
>>>>>> index cbb012e217ab80c1ca88e611e7acc06c6d56fad0..a6901878697c8e1ec1cbfed62298ae3bc58f2501 100644
>>>>>> --- a/Documentation/devicetree/bindings/arm/psci.yaml
>>>>>> +++ b/Documentation/devicetree/bindings/arm/psci.yaml
>>>>>> @@ -98,6 +98,12 @@ properties:
>>>>>>        [1] Kernel documentation - ARM idle states bindings
>>>>>>          Documentation/devicetree/bindings/cpu/idle-states.yaml
>>>>>>
>>>>>> +  arm,psci-s2ram-param:
>>>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>>>> +    description:
>>>>>> +      power_state parameter denoting the S2RAM/S3-like system suspend state
>>>>>
>>>>> Yet another NACK as this corresponds to PSCI SYSTEM_SUSPEND and as per
>>>>> specification it takes no such parameter. This is just misleading.
>>>>>
>>>>
>>>> Yeah PSCI_SYSTEM_SUSPEND takes care of this on platforms that expose it.
>>>>
>>>
>>> And those that don't advertise/expose don't get to use, simple.
>>
>> The spec says:
>>
>> "The call is equivalent to using the CPU_SUSPEND call for the
>> deepest possible platform powerdown state."
>>
> 
> Please take a look at the preconditions for both the calls. They are
> different.

Which is *precisely* why I want to tell the OS that it's a S2RAM state,
so that different actions can be taken in peripheral device drivers.

Konrad


From sudeep.holla at arm.com  Fri Dec 20 05:58:57 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 20 Dec 2024 13:58:57 +0000
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on
 pre-SYSTEM_SUSPEND PSCI impls
In-Reply-To: <765bb1c8-31de-4aec-b8ef-f141a3e25c56@oss.qualcomm.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241113165329590-0800.eberman@hu-eberman-lv.qualcomm.com>
 <e4509104-c809-4d45-bdbb-a2d754a816db@oss.qualcomm.com>
 <Z2VXgkJ4x5TJTKJ_@bogus>
 <765bb1c8-31de-4aec-b8ef-f141a3e25c56@oss.qualcomm.com>
Message-ID: <Z2V4IblZNgnS4T2Z@bogus>

On Fri, Dec 20, 2024 at 01:42:04PM +0100, Konrad Dybcio wrote:
> On 20.12.2024 12:39 PM, Sudeep Holla wrote:
> > On Thu, Dec 19, 2024 at 08:26:51PM +0100, Konrad Dybcio wrote:
> >> On 14.11.2024 2:10 AM, Elliot Berman wrote:
> >>
> >>> I'm not sure why you'd like to support s2ram. Is it *only* that you'd
> >>> like to be able to set pm_set_supend/resume_via_firmware()? I hope this
> >>> doesn't sound silly: what if you register a platform_s2idle_ops for the
> >>> relevant SoCs which calls pm_set_suspend/resume_via_firwmare()?
> >>
> >> S2RAM is what you get after entering a certain state, but currently
> >> it's presented as just another (s2idle) idle state.
> >>
> >
> > Just to be clear, I assume you mean CPU_SUSPEND idle state. There is
> > no special or different s2idle idle states IIUC.
>
> Yeah, right.
>
> >> That means some hardware that may need to be reinitialized, isn't as
> >> Linux has no clue it might have lost power.
> >>
> >
> > Interesting, so this means firmware doesn't automatically save and restore
> > states yet exposes it as CPU_SUSPEND idle state.
>
> Reading the spec, I'm pretty sure PSCI calls should only mess with the
> power state of the cores, core-adjacent peripherals and GIC.
>
> Reading section 5.20.1 (SYSTEM_SUSPEND / Intended use) I think it says
> mostly what I'm trying to convey:
>
>
> "In a typical implementation, the semantics are equivalent to a
> CPU_SUSPEND to the deepest low-power state. However, it is possible that
> an implementation might reserve a deeper state for SYSTEM_SUSPEND than
> those used with CPU_SUSPEND."
>

Yes these text help to understand the interface easily. If they were same,
do you think we would have defined 2 different interfaces.

--
Regards,
Sudeep


From sudeep.holla at arm.com  Fri Dec 20 06:04:08 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 20 Dec 2024 14:04:08 +0000
Subject: [PATCH 1/3] dt-bindings: arm,psci: Allow S2RAM power_state
 parameter description
In-Reply-To: <c80c4cdb-48e1-4b6f-8ab8-fad6e100af00@oss.qualcomm.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
 <Z1LQOmEfFy640PjG@bogus>
 <54cc4221-ba5f-4741-9033-20874265ca01@oss.qualcomm.com>
 <Z2VUiHWHgbWowdal@bogus>
 <349bac70-87e0-4870-a3f0-9f6a3b3e6824@oss.qualcomm.com>
 <Z2V3amqWYDUWA2uM@bogus>
 <c80c4cdb-48e1-4b6f-8ab8-fad6e100af00@oss.qualcomm.com>
Message-ID: <Z2V5WMN5aHQwQlNH@bogus>

On Fri, Dec 20, 2024 at 02:57:34PM +0100, Konrad Dybcio wrote:
> On 20.12.2024 2:55 PM, Sudeep Holla wrote:
> > 
> > Please take a look at the preconditions for both the calls. They are
> > different.
> 
> Which is *precisely* why I want to tell the OS that it's a S2RAM state,
> so that different actions can be taken in peripheral device drivers.

Yes we do that for SYSTEM_SUSPEND. And CPU_SUSPEND is not SYSTEM_SUSPEND
hence 2 different APIs. My NACK still stands.

--
Regards,
Sudeep


From daniel.machon at microchip.com  Fri Dec 20 05:48:42 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:42 +0100
Subject: [PATCH net-next v5 3/9] net: sparx5: use is_port_rgmii()
 throughout
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-3-fa8ba5dff732@microchip.com>

Now that we can check if a given port is an RGMII port, use it in the
following cases:

 - To set RGMII PHY modes for RGMII port devices.

 - To avoid checking for a SerDes node in the devicetree, when the port
   is an RGMII port.

 - To bail out of sparx5_port_init() when the common configuration is
   done.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Tested-by: Robert Marko <robert.marko at sartura.hr>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 .../net/ethernet/microchip/sparx5/sparx5_main.c    | 28 +++++++++++++++-------
 .../net/ethernet/microchip/sparx5/sparx5_port.c    |  3 +++
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 4be717ba7d37..e68277c38adc 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -313,10 +313,13 @@ static int sparx5_create_port(struct sparx5 *sparx5,
 			      struct initial_port_config *config)
 {
 	struct sparx5_port *spx5_port;
+	const struct sparx5_ops *ops;
 	struct net_device *ndev;
 	struct phylink *phylink;
 	int err;
 
+	ops = sparx5->data->ops;
+
 	ndev = sparx5_create_netdev(sparx5, config->portno);
 	if (IS_ERR(ndev)) {
 		dev_err(sparx5->dev, "Could not create net device: %02u\n",
@@ -357,6 +360,9 @@ static int sparx5_create_port(struct sparx5 *sparx5,
 		MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD |
 		MAC_2500FD | MAC_5000FD | MAC_10000FD | MAC_25000FD;
 
+	if (ops->is_port_rgmii(spx5_port->portno))
+		phy_interface_set_rgmii(spx5_port->phylink_config.supported_interfaces);
+
 	__set_bit(PHY_INTERFACE_MODE_SGMII,
 		  spx5_port->phylink_config.supported_interfaces);
 	__set_bit(PHY_INTERFACE_MODE_QSGMII,
@@ -830,6 +836,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 	struct initial_port_config *configs, *config;
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *ports, *portnp;
+	const struct sparx5_ops *ops;
 	struct reset_control *reset;
 	struct sparx5 *sparx5;
 	int idx = 0, err = 0;
@@ -851,6 +858,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	regs = sparx5->data->regs;
+	ops = sparx5->data->ops;
 
 	/* Do switch core reset if available */
 	reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
@@ -880,7 +888,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 
 	for_each_available_child_of_node(ports, portnp) {
 		struct sparx5_port_config *conf;
-		struct phy *serdes;
+		struct phy *serdes = NULL;
 		u32 portno;
 
 		err = of_property_read_u32(portnp, "reg", &portno);
@@ -910,13 +918,17 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 			conf->sd_sgpio = ~0;
 		else
 			sparx5->sd_sgpio_remapping = true;
-		serdes = devm_of_phy_get(sparx5->dev, portnp, NULL);
-		if (IS_ERR(serdes)) {
-			err = dev_err_probe(sparx5->dev, PTR_ERR(serdes),
-					    "port %u: missing serdes\n",
-					    portno);
-			of_node_put(portnp);
-			goto cleanup_config;
+		/* There is no SerDes node for RGMII ports. */
+		if (!ops->is_port_rgmii(portno)) {
+			serdes = devm_of_phy_get(sparx5->dev, portnp, NULL);
+			if (IS_ERR(serdes)) {
+				err = dev_err_probe(sparx5->dev,
+						    PTR_ERR(serdes),
+						    "port %u: missing serdes\n",
+						    portno);
+				of_node_put(portnp);
+				goto cleanup_config;
+			}
 		}
 		config->portno = portno;
 		config->node = portnp;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index f39bf4878e11..996dc4343019 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1090,6 +1090,9 @@ int sparx5_port_init(struct sparx5 *sparx5,
 		 ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
 		 sparx5, ANA_CL_FILTER_CTRL(port->portno));
 
+	if (ops->is_port_rgmii(port->portno))
+		return 0; /* RGMII device - nothing more to configure */
+
 	/* Configure MAC vlan awareness */
 	err = sparx5_port_max_tags_set(sparx5, port);
 	if (err)

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 20 05:48:39 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:39 +0100
Subject: [PATCH net-next v5 0/9] net: lan969x: add RGMII support
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>

== Description:

This series is the fourth of a multi-part series, that prepares and adds
support for the new lan969x switch driver.

The upstreaming efforts is split into multiple series (might change a
bit as we go along):

        1) Prepare the Sparx5 driver for lan969x (merged)

        2) Add support for lan969x (same basic features as Sparx5
           provides excl. FDMA and VCAP, merged).

        3) Add lan969x VCAP functionality (merged).

    --> 4) Add RGMII support.

        5) Add FDMA support.

== RGMII support:

The lan969x switch device includes two RGMII port interfaces (port 28
and 29) supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps.

== Patch breakdown:

Patch #1 does some preparation work.

Patch #2 adds new function: is_port_rgmii() to the match data ops.

Patch #3 uses the is_port_rgmii() in a number of places.

Patch #4 makes sure that we do not configure an RGMII device as a
         low-speed device, when doing a port config.

Patch #5 makes sure we only return the PCS if the port mode requires
         it.

Patch #6 adds checks for RGMII PHY modes in sparx5_verify_speeds().

Patch #7 adds registers required to configure RGMII.

Patch #8 adds RGMII implementation.

Patch #9 documents RGMII delays in the dt-bindings.

Details are in the commit description of the individual patches

To: UNGLinuxDriver at microchip.com
To: Andrew Lunn <andrew+netdev at lunn.ch>
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>
To: Lars Povlsen <lars.povlsen at microchip.com>
To: Steen Hegelund <Steen.Hegelund at microchip.com>
To: Horatiu Vultur <horatiu.vultur at microchip.com>
To: Russell King <linux at armlinux.org.uk>
To: jacob.e.keller at intel.com
To: robh at kernel.org
To: krzk+dt at kernel.org
To: conor+dt at kernel.org
Cc: devicetree at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: robert.marko at sartura.hr

Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
Changes in v5:

- Updated tags received on the list. No other changes to commits. Patch
  6/9 from v4 is kept, since it is required in order for RGMII port
  config to not fail. The cleanup of the sparx5_port_verify_speed()
  function will be deferred to another series (see comments on patch 6/9
  from previous version).

- Link to v4:
  https://lore.kernel.org/r/20241213-sparx5-lan969x-switch-driver-4-v4-0-d1a72c9c4714 at microchip.com

Changes in v4:

- Split patch #4 in v3 into two patches, where the new patch #5 handles
  PCS selection, by returning the PCS only for ports that require it.

- Got rid of the '|' symbol for {rx,tx}-internal-delay-ps property
  description in the dt-bindings (patch #9).

- Link to v3: https://lore.kernel.org/r/20241118-sparx5-lan969x-switch-driver-4-v3-0-3cefee5e7e3a at microchip.com

Changes in v3:

v2 was kindly tested by Robert Marko. Not carrying the tag to v3 since
we have changes to the handling of the delays.

- Modified lan969x_rgmii_delay_config() to not apply any MAC delay when
  the {rx,tx}-internal-delay-ps properties are missing or set to 0
  (patch #7).

- Removed 'required' constraint from {rx-tx}-internal-delay-ps
  properties. Also added description and default value (Patch #8).

- Link to v2: https://lore.kernel.org/r/20241113-sparx5-lan969x-switch-driver-4-v2-0-0db98ac096d1 at microchip.com

Changes in v2:

  Most changes are in patch #7. RGMII implementation has been moved to
  it's own file lan969x_rgmii.c.

  Details:

    - Use ETH_P_8021Q and ETH_P_8021AD instead of the Sparx5 provided
      equivalents (patch #7).
    - Configure MAC delays through "{rx,tx}-internal-delay-ps"
      properties (patch #7).
    - Add selectors for all the phase shifts that the hardware supports
      (instead of only 2.0 ns, patch #7).
    - Add selectors for all the port speeds (instead of only 1000 mbps.)
    - Document RGMII delays in dt-bindings.

  - Link to v1: https://lore.kernel.org/r/20241106-sparx5-lan969x-switch-driver-4-v1-0-f7f7316436bd at microchip.com

---
Daniel Machon (9):
      net: sparx5: do some preparation work
      net: sparx5: add function for RGMII port check
      net: sparx5: use is_port_rgmii() throughout
      net: sparx5: skip low-speed configuration when port is RGMII
      net: sparx5: only return PCS for modes that require it
      net: sparx5: verify RGMII speeds
      net: lan969x: add RGMII registers
      net: lan969x: add RGMII implementation
      dt-bindings: net: sparx5: document RGMII delays

 .../bindings/net/microchip,sparx5-switch.yaml      |  18 ++
 drivers/net/ethernet/microchip/sparx5/Makefile     |   3 +-
 .../ethernet/microchip/sparx5/lan969x/lan969x.c    |   5 +
 .../ethernet/microchip/sparx5/lan969x/lan969x.h    |  10 +
 .../microchip/sparx5/lan969x/lan969x_rgmii.c       | 224 +++++++++++++++++++++
 .../net/ethernet/microchip/sparx5/sparx5_main.c    |  29 ++-
 .../net/ethernet/microchip/sparx5/sparx5_main.h    |   3 +
 .../ethernet/microchip/sparx5/sparx5_main_regs.h   | 145 +++++++++++++
 .../net/ethernet/microchip/sparx5/sparx5_phylink.c |  14 +-
 .../net/ethernet/microchip/sparx5/sparx5_port.c    |  57 ++++--
 .../net/ethernet/microchip/sparx5/sparx5_port.h    |   5 +
 11 files changed, 484 insertions(+), 29 deletions(-)
---
base-commit: b73e56f16250c6124f8975636f1844472f6fd450
change-id: 20241104-sparx5-lan969x-switch-driver-4-d59b7820485a

Best regards,
-- 
Daniel Machon <daniel.machon at microchip.com>



From daniel.machon at microchip.com  Fri Dec 20 05:48:40 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:40 +0100
Subject: [PATCH net-next v5 1/9] net: sparx5: do some preparation work
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-1-fa8ba5dff732@microchip.com>

The sparx5_port_init() does initial configuration of a variety of
different features and options for each port. Some are shared for all
types of devices, some are not. As it is now, common configuration is
done after configuration of low-speed devices. This will not work when
adding RGMII support in a subsequent patch.

In preparation for lan969x RGMII support, move a block of code, that
configures 2g5 devices, down. This ensures that the configuration common
to all devices is done before configuration of 2g5, 5g, 10g and 25g
devices.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Tested-by: Robert Marko <robert.marko at sartura.hr>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 .../net/ethernet/microchip/sparx5/sparx5_port.c    | 36 +++++++++++-----------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index f9d1a6bb9bff..f39bf4878e11 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1067,24 +1067,6 @@ int sparx5_port_init(struct sparx5 *sparx5,
 	if (err)
 		return err;
 
-	/* Configure MAC vlan awareness */
-	err = sparx5_port_max_tags_set(sparx5, port);
-	if (err)
-		return err;
-
-	/* Set Max Length */
-	spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
-		 DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
-		 sparx5,
-		 DEV2G5_MAC_MAXLEN_CFG(port->portno));
-
-	/* 1G/2G5: Signal Detect configuration */
-	spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
-		DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
-		DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
-		sparx5,
-		DEV2G5_PCS1G_SD_CFG(port->portno));
-
 	/* Set Pause WM hysteresis */
 	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_START_SET(pause_start) |
 		 QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop) |
@@ -1108,6 +1090,24 @@ int sparx5_port_init(struct sparx5 *sparx5,
 		 ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
 		 sparx5, ANA_CL_FILTER_CTRL(port->portno));
 
+	/* Configure MAC vlan awareness */
+	err = sparx5_port_max_tags_set(sparx5, port);
+	if (err)
+		return err;
+
+	/* Set Max Length */
+	spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
+		 DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
+		 sparx5,
+		 DEV2G5_MAC_MAXLEN_CFG(port->portno));
+
+	/* 1G/2G5: Signal Detect configuration */
+	spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
+		DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
+		DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
+		sparx5,
+		DEV2G5_PCS1G_SD_CFG(port->portno));
+
 	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII ||
 	    conf->portmode == PHY_INTERFACE_MODE_SGMII) {
 		err = sparx5_serdes_set(sparx5, port, conf);

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 20 05:48:41 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:41 +0100
Subject: [PATCH net-next v5 2/9] net: sparx5: add function for RGMII port
 check
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-2-fa8ba5dff732@microchip.com>

The lan969x device contains two RGMII port interfaces, sitting at port
28 and 29. Add function: is_port_rgmii() to the match data ops, that
checks if a given port is an RGMII port or not. For Sparx5, this
function always returns false.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Tested-by: Robert Marko <robert.marko at sartura.hr>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c | 1 +
 drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h | 5 +++++
 drivers/net/ethernet/microchip/sparx5/sparx5_main.c     | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_main.h     | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_port.h     | 5 +++++
 5 files changed, 13 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
index c2afa2176b08..76f0c8635eb9 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
@@ -329,6 +329,7 @@ static const struct sparx5_ops lan969x_ops = {
 	.is_port_5g              = &lan969x_port_is_5g,
 	.is_port_10g             = &lan969x_port_is_10g,
 	.is_port_25g             = &lan969x_port_is_25g,
+	.is_port_rgmii           = &lan969x_port_is_rgmii,
 	.get_port_dev_index      = &lan969x_port_dev_mapping,
 	.get_port_dev_bit        = &lan969x_get_dev_mode_bit,
 	.get_hsch_max_group_rate = &lan969x_get_hsch_max_group_rate,
diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
index 2489d0d32dfd..4b91c47d6d21 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
@@ -59,6 +59,11 @@ static inline bool lan969x_port_is_25g(int portno)
 	return false;
 }
 
+static inline bool lan969x_port_is_rgmii(int portno)
+{
+	return portno == 28 || portno == 29;
+}
+
 /* lan969x_calendar.c */
 int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
 			      struct sparx5_calendar_data *data);
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index f61aa15beab7..4be717ba7d37 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -1072,6 +1072,7 @@ static const struct sparx5_ops sparx5_ops = {
 	.is_port_5g              = &sparx5_port_is_5g,
 	.is_port_10g             = &sparx5_port_is_10g,
 	.is_port_25g             = &sparx5_port_is_25g,
+	.is_port_rgmii           = &sparx5_port_is_rgmii,
 	.get_port_dev_index      = &sparx5_port_dev_mapping,
 	.get_port_dev_bit        = &sparx5_port_dev_mapping,
 	.get_hsch_max_group_rate = &sparx5_get_hsch_max_group_rate,
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index d5dd953b0a71..c58d7841638e 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -313,6 +313,7 @@ struct sparx5_ops {
 	bool (*is_port_5g)(int portno);
 	bool (*is_port_10g)(int portno);
 	bool (*is_port_25g)(int portno);
+	bool (*is_port_rgmii)(int portno);
 	u32  (*get_port_dev_index)(struct sparx5 *sparx5, int port);
 	u32  (*get_port_dev_bit)(struct sparx5 *sparx5, int port);
 	u32  (*get_hsch_max_group_rate)(int grp);
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
index 9b9bcc6834bc..c8a37468a3d1 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
@@ -40,6 +40,11 @@ static inline bool sparx5_port_is_25g(int portno)
 	return portno >= 56 && portno <= 63;
 }
 
+static inline bool sparx5_port_is_rgmii(int portno)
+{
+	return false;
+}
+
 static inline u32 sparx5_to_high_dev(struct sparx5 *sparx5, int port)
 {
 	const struct sparx5_ops *ops = sparx5->data->ops;

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 20 05:48:44 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:44 +0100
Subject: [PATCH net-next v5 5/9] net: sparx5: only return PCS for modes
 that require it
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-5-fa8ba5dff732@microchip.com>

The RGMII ports have no PCS to configure. Make sure we only return the
PCS for port modes that require it.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Tested-by: Robert Marko <robert.marko at sartura.hr>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
index f8562c1a894d..035d2f1bea0d 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
@@ -32,7 +32,19 @@ sparx5_phylink_mac_select_pcs(struct phylink_config *config,
 {
 	struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));
 
-	return &port->phylink_pcs;
+	/* Return the PCS for all the modes that require it. */
+	switch (interface) {
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_QSGMII:
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_25GBASER:
+		return &port->phylink_pcs;
+	default:
+		return NULL;
+	}
 }
 
 static void sparx5_phylink_mac_config(struct phylink_config *config,

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 20 05:48:45 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:45 +0100
Subject: [PATCH net-next v5 6/9] net: sparx5: verify RGMII speeds
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-6-fa8ba5dff732@microchip.com>

When doing a port config, we verify the port speed against the PHY mode
and supported speeds of that PHY mode. Add checks for the four RGMII phy
modes: RGMII, RGMII_ID, RGMII_TXID and RGMII_RXID.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Tested-by: Robert Marko <robert.marko at sartura.hr>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 0a1374422ccb..86d6c9e9ec7c 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -257,6 +257,15 @@ static int sparx5_port_verify_speed(struct sparx5 *sparx5,
 		     conf->speed != SPEED_25000))
 			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
 		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		if (conf->speed != SPEED_1000 &&
+		    conf->speed != SPEED_100 &&
+		    conf->speed != SPEED_10)
+			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
+		break;
 	default:
 		return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
 	}

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 20 05:48:43 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:43 +0100
Subject: [PATCH net-next v5 4/9] net: sparx5: skip low-speed configuration
 when port is RGMII
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-4-fa8ba5dff732@microchip.com>

When doing a port config, we configure low-speed port devices, among
other things. We have a check to ensure, that the device is indeed a
low-speed device, an not a high-speed device. Add an additional check,
to ensure that the device is not an RGMII device.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Tested-by: Robert Marko <robert.marko at sartura.hr>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 996dc4343019..0a1374422ccb 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -994,6 +994,7 @@ int sparx5_port_config(struct sparx5 *sparx5,
 		       struct sparx5_port *port,
 		       struct sparx5_port_config *conf)
 {
+	bool rgmii = phy_interface_mode_is_rgmii(conf->phy_mode);
 	bool high_speed_dev = sparx5_is_baser(conf->portmode);
 	const struct sparx5_ops *ops = sparx5->data->ops;
 	int err, urgency, stop_wm;
@@ -1003,7 +1004,7 @@ int sparx5_port_config(struct sparx5 *sparx5,
 		return err;
 
 	/* high speed device is already configured */
-	if (!high_speed_dev)
+	if (!rgmii && !high_speed_dev)
 		sparx5_port_config_low_set(sparx5, port, conf);
 
 	/* Configure flow control */

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 20 05:48:46 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:46 +0100
Subject: [PATCH net-next v5 7/9] net: lan969x: add RGMII registers
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-7-fa8ba5dff732@microchip.com>

Configuration of RGMII is done by configuring the GPIO and clock
settings in the HSIOWRAP target, and configuring the RGMII port devices
in the DEVRGMII target. Both targets contain registers replicated for
the number of RGMII port devices, which is two.

Add said targets and register macros required to configure RGMII.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Tested-by: Robert Marko <robert.marko at sartura.hr>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 .../ethernet/microchip/sparx5/lan969x/lan969x.c    |   3 +
 .../ethernet/microchip/sparx5/sparx5_main_regs.h   | 145 +++++++++++++++++++++
 2 files changed, 148 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
index 76f0c8635eb9..be49a99556fe 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
@@ -90,9 +90,12 @@ static const struct sparx5_main_io_resource lan969x_main_iomap[] =  {
 	{ TARGET_DEV2G5 + 27,         0x30d8000, 1 }, /* 0xe30d8000 */
 	{ TARGET_DEV10G +  9,         0x30dc000, 1 }, /* 0xe30dc000 */
 	{ TARGET_PCS10G_BR +  9,      0x30e0000, 1 }, /* 0xe30e0000 */
+	{ TARGET_DEVRGMII,            0x30e4000, 1 }, /* 0xe30e4000 */
+	{ TARGET_DEVRGMII +  1,       0x30e8000, 1 }, /* 0xe30e8000 */
 	{ TARGET_DSM,                 0x30ec000, 1 }, /* 0xe30ec000 */
 	{ TARGET_PORT_CONF,           0x30f0000, 1 }, /* 0xe30f0000 */
 	{ TARGET_ASM,                 0x3200000, 1 }, /* 0xe3200000 */
+	{ TARGET_HSIO_WRAP,           0x3408000, 1 }, /* 0xe3408000 */
 };
 
 static struct sparx5_sdlb_group lan969x_sdlb_groups[LAN969X_SDLB_GRP_CNT] = {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
index 561344f19062..d9ef4ef137b8 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
@@ -37,6 +37,7 @@ enum sparx5_target {
 	TARGET_FDMA = 117,
 	TARGET_GCB = 118,
 	TARGET_HSCH = 119,
+	TARGET_HSIO_WRAP = 120,
 	TARGET_LRN = 122,
 	TARGET_PCEP = 129,
 	TARGET_PCS10G_BR = 132,
@@ -54,6 +55,7 @@ enum sparx5_target {
 	TARGET_VCAP_SUPER = 326,
 	TARGET_VOP = 327,
 	TARGET_XQS = 331,
+	TARGET_DEVRGMII = 392,
 	NUM_TARGETS = 517
 };
 
@@ -5367,6 +5369,69 @@ extern const struct sparx5_regs *regs;
 #define HSCH_TAS_STATEMACHINE_CFG_REVISIT_DLY_GET(x)\
 	FIELD_GET(HSCH_TAS_STATEMACHINE_CFG_REVISIT_DLY, x)
 
+/* LAN969X ONLY */
+/* HSIOWRAP:XMII_CFG:XMII_CFG */
+#define HSIO_WRAP_XMII_CFG(g)                                                  \
+	__REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 0, 0, 1, 4)
+
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG         GENMASK(2, 1)
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_SET(x)\
+	FIELD_PREP(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG, x)
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_GET(x)\
+	FIELD_GET(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG, x)
+
+/* LAN969X ONLY */
+/* HSIOWRAP:XMII_CFG:RGMII_CFG */
+#define HSIO_WRAP_RGMII_CFG(g)                                                 \
+	__REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 4, 0, 1, 4)
+
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG           GENMASK(4, 2)
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_SET(x)\
+	FIELD_PREP(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG, x)
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_GET(x)\
+	FIELD_GET(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG, x)
+
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST         BIT(1)
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_SET(x)\
+	FIELD_PREP(HSIO_WRAP_RGMII_CFG_RGMII_TX_RST, x)
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_GET(x)\
+	FIELD_GET(HSIO_WRAP_RGMII_CFG_RGMII_TX_RST, x)
+
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST         BIT(0)
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_SET(x)\
+	FIELD_PREP(HSIO_WRAP_RGMII_CFG_RGMII_RX_RST, x)
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_GET(x)\
+	FIELD_GET(HSIO_WRAP_RGMII_CFG_RGMII_RX_RST, x)
+
+/* LAN969X ONLY */
+/* HSIOWRAP:XMII_CFG:DLL_CFG */
+#define HSIO_WRAP_DLL_CFG(g, r)                                                \
+	__REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 12, r, 2, 4)
+
+#define HSIO_WRAP_DLL_CFG_DLL_ENA                BIT(19)
+#define HSIO_WRAP_DLL_CFG_DLL_ENA_SET(x)\
+	FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_ENA, x)
+#define HSIO_WRAP_DLL_CFG_DLL_ENA_GET(x)\
+	FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_ENA, x)
+
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA            BIT(18)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(x)\
+	FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_CLK_ENA, x)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_GET(x)\
+	FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_CLK_ENA, x)
+
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL            GENMASK(17, 15)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(x)\
+	FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_CLK_SEL, x)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_GET(x)\
+	FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_CLK_SEL, x)
+
+#define HSIO_WRAP_DLL_CFG_DLL_RST                BIT(0)
+#define HSIO_WRAP_DLL_CFG_DLL_RST_SET(x)\
+	FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_RST, x)
+#define HSIO_WRAP_DLL_CFG_DLL_RST_GET(x)\
+	FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_RST, x)
+
 /* LRN:COMMON:COMMON_ACCESS_CTRL */
 #define LRN_COMMON_ACCESS_CTRL                                                 \
 	__REG(TARGET_LRN, 0, 1, 0, 0, 1, 72, 0, 0, 1, 4)
@@ -8110,4 +8175,84 @@ extern const struct sparx5_regs *regs;
 #define XQS_CNT(g)                                                             \
 	__REG(TARGET_XQS, 0, 1, 0, g, 1024, 4, 0, 0, 1, 4)
 
+/* LAN969X ONLY */
+/* DEV1G:DEV_CFG_STATUS:DEV_RST_CTRL */
+#define DEVRGMII_DEV_RST_CTRL(t)                                               \
+	__REG(TARGET_DEVRGMII, t, 2, 0, 0, 1, 36, 0, 0, 1, 4)
+
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL          GENMASK(22, 20)
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL_SET(x)\
+	FIELD_PREP(DEVRGMII_DEV_RST_CTRL_SPEED_SEL, x)
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL_GET(x)\
+	FIELD_GET(DEVRGMII_DEV_RST_CTRL_SPEED_SEL, x)
+
+/* LAN969X ONLY */
+/* DEV1G:MAC_CFG_STATUS:MAC_ENA_CFG */
+#define DEVRGMII_MAC_ENA_CFG(t)                                                \
+	__REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 0, 0, 1, 4)
+
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA              BIT(4)
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_ENA_CFG_RX_ENA, x)
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_ENA_CFG_RX_ENA, x)
+
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA              BIT(0)
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_ENA_CFG_TX_ENA, x)
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_ENA_CFG_TX_ENA, x)
+
+/* LAN969X ONLY */
+/* DEV1G:MAC_CFG_STATUS:MAC_TAGS_CFG */
+#define DEVRGMII_MAC_TAGS_CFG(t)                                               \
+	__REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 12, 0, 1, 4)
+
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID             GENMASK(31, 16)
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_TAG_ID, x)
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_TAGS_CFG_TAG_ID, x)
+
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA   BIT(3)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, x)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, x)
+
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA             GENMASK(2, 1)
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_PB_ENA, x)
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_TAGS_CFG_PB_ENA, x)
+
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA       BIT(0)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
+
+/* LAN969X ONLY */
+/* DEV1G:MAC_CFG_STATUS:MAC_IFG_CFG */
+#define DEVRGMII_MAC_IFG_CFG(t)                                                \
+	__REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 24, 0, 1, 4)
+
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG              GENMASK(12, 8)
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_IFG_CFG_TX_IFG, x)
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_IFG_CFG_TX_IFG, x)
+
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2             GENMASK(7, 4)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_IFG_CFG_RX_IFG2, x)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_IFG_CFG_RX_IFG2, x)
+
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1             GENMASK(3, 0)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1_SET(x)\
+	FIELD_PREP(DEVRGMII_MAC_IFG_CFG_RX_IFG1, x)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1_GET(x)\
+	FIELD_GET(DEVRGMII_MAC_IFG_CFG_RX_IFG1, x)
+
 #endif /* _SPARX5_MAIN_REGS_H_ */

-- 
2.34.1



From daniel.machon at microchip.com  Fri Dec 20 05:48:47 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Fri, 20 Dec 2024 14:48:47 +0100
Subject: [PATCH net-next v5 8/9] net: lan969x: add RGMII implementation
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
Message-ID: <20241220-sparx5-lan969x-switch-driver-4-v5-8-fa8ba5dff732@microchip.com>

The lan969x switch device includes two RGMII port interfaces (port 28
and 29) supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps. MAC
level delays are configurable through the HSIO_WRAP target, by choosing
a phase shift selector, corresponding to a certain time delay in nano
seconds.

Add new file: lan969x_rgmii.c that contains the implementation for
configuring the RGMII port devices. MAC level delays are configured
using the "{rx,tx}-internal-delay-ps" properties. These properties must
be specified independently of the phy-mode. If missing, or set to zero,
the MAC will not apply any delay.

Reviewed-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Tested-by: Robert Marko <robert.marko at sartura.hr>
Signed-off-by: Daniel Machon <daniel.machon at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/Makefile     |   3 +-
 .../ethernet/microchip/sparx5/lan969x/lan969x.c    |   1 +
 .../ethernet/microchip/sparx5/lan969x/lan969x.h    |   5 +
 .../microchip/sparx5/lan969x/lan969x_rgmii.c       | 224 +++++++++++++++++++++
 .../net/ethernet/microchip/sparx5/sparx5_main.h    |   2 +
 .../net/ethernet/microchip/sparx5/sparx5_port.c    |   6 +
 6 files changed, 240 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/Makefile b/drivers/net/ethernet/microchip/sparx5/Makefile
index 4bf2a885a9da..3f34e83246a0 100644
--- a/drivers/net/ethernet/microchip/sparx5/Makefile
+++ b/drivers/net/ethernet/microchip/sparx5/Makefile
@@ -20,7 +20,8 @@ sparx5-switch-$(CONFIG_LAN969X_SWITCH) += lan969x/lan969x_regs.o \
 					  lan969x/lan969x.o \
 					  lan969x/lan969x_calendar.o \
 					  lan969x/lan969x_vcap_ag_api.o \
-					  lan969x/lan969x_vcap_impl.o
+					  lan969x/lan969x_vcap_impl.o \
+					  lan969x/lan969x_rgmii.o
 
 # Provide include files
 ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
index be49a99556fe..396f76b6eea5 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.c
@@ -340,6 +340,7 @@ static const struct sparx5_ops lan969x_ops = {
 	.set_port_mux            = &lan969x_port_mux_set,
 	.ptp_irq_handler         = &lan969x_ptp_irq_handler,
 	.dsm_calendar_calc       = &lan969x_dsm_calendar_calc,
+	.port_config_rgmii       = &lan969x_port_config_rgmii,
 };
 
 const struct sparx5_match_data lan969x_desc = {
diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
index 4b91c47d6d21..9a7ddebecf1e 100644
--- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x.h
@@ -67,4 +67,9 @@ static inline bool lan969x_port_is_rgmii(int portno)
 /* lan969x_calendar.c */
 int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
 			      struct sparx5_calendar_data *data);
+
+/* lan969x_rgmii.c */
+int lan969x_port_config_rgmii(struct sparx5_port *port,
+			      struct sparx5_port_config *conf);
+
 #endif
diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_rgmii.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_rgmii.c
new file mode 100644
index 000000000000..4e422ca50828
--- /dev/null
+++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_rgmii.c
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Microchip lan969x Switch driver
+ *
+ * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries.
+ */
+
+#include "lan969x.h"
+
+/* Tx clock selectors */
+#define LAN969X_RGMII_TX_CLK_SEL_125MHZ 1  /* 1000Mbps */
+#define LAN969X_RGMII_TX_CLK_SEL_25MHZ  2  /* 100Mbps */
+#define LAN969X_RGMII_TX_CLK_SEL_2M5MHZ 3  /* 10Mbps */
+
+/* Port speed selectors */
+#define LAN969X_RGMII_SPEED_SEL_10 0   /* Select 10Mbps speed */
+#define LAN969X_RGMII_SPEED_SEL_100 1  /* Select 100Mbps speed */
+#define LAN969X_RGMII_SPEED_SEL_1000 2 /* Select 1000Mbps speed */
+
+/* Clock delay selectors */
+#define LAN969X_RGMII_CLK_DELAY_SEL_1_0_NS 2  /* Phase shift 45deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_1_7_NS 3  /* Phase shift 77deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_2_0_NS 4  /* Phase shift 90deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_2_5_NS 5  /* Phase shift 112deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_3_0_NS 6  /* Phase shift 135deg */
+#define LAN969X_RGMII_CLK_DELAY_SEL_3_3_NS 7  /* Phase shift 147deg */
+
+#define LAN969X_RGMII_PORT_START_IDX 28 /* Index of the first RGMII port */
+#define LAN969X_RGMII_IFG_TX 4          /* TX Inter Frame Gap value */
+#define LAN969X_RGMII_IFG_RX1 5         /* RX1 Inter Frame Gap value */
+#define LAN969X_RGMII_IFG_RX2 1         /* RX2 Inter Frame Gap value */
+
+#define RGMII_PORT_IDX(port) ((port)->portno - LAN969X_RGMII_PORT_START_IDX)
+
+/* Get the tx clock selector based on the port speed. */
+static int lan969x_rgmii_get_clk_sel(int speed)
+{
+	return (speed == SPEED_10  ? LAN969X_RGMII_TX_CLK_SEL_2M5MHZ :
+		speed == SPEED_100 ? LAN969X_RGMII_TX_CLK_SEL_25MHZ :
+				     LAN969X_RGMII_TX_CLK_SEL_125MHZ);
+}
+
+/* Get the port speed selector based on the port speed. */
+static int lan969x_rgmii_get_speed_sel(int speed)
+{
+	return (speed == SPEED_10  ? LAN969X_RGMII_SPEED_SEL_10 :
+		speed == SPEED_100 ? LAN969X_RGMII_SPEED_SEL_100 :
+				     LAN969X_RGMII_SPEED_SEL_1000);
+}
+
+/* Get the clock delay selector based on the clock delay in picoseconds. */
+static int lan969x_rgmii_get_clk_delay_sel(struct sparx5_port *port,
+					   u32 delay_ps, u32 *clk_delay_sel)
+{
+	switch (delay_ps) {
+	case 0:
+		/* Hardware default selector. */
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_2_5_NS;
+		break;
+	case 1000:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_1_0_NS;
+		break;
+	case 1700:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_1_7_NS;
+		break;
+	case 2000:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_2_0_NS;
+		break;
+	case 2500:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_2_5_NS;
+		break;
+	case 3000:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_3_0_NS;
+		break;
+	case 3300:
+		*clk_delay_sel = LAN969X_RGMII_CLK_DELAY_SEL_3_3_NS;
+		break;
+	default:
+		dev_err(port->sparx5->dev, "Invalid RGMII delay: %u", delay_ps);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Configure the RGMII tx clock frequency. */
+static void lan969x_rgmii_tx_clk_config(struct sparx5_port *port,
+					struct sparx5_port_config *conf)
+{
+	u32 clk_sel = lan969x_rgmii_get_clk_sel(conf->speed);
+	u32 idx = RGMII_PORT_IDX(port);
+
+	/* Take the RGMII clock domain out of reset and set tx clock
+	 * frequency.
+	 */
+	spx5_rmw(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_SET(clk_sel) |
+		 HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_SET(0) |
+		 HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_SET(0),
+		 HSIO_WRAP_RGMII_CFG_TX_CLK_CFG |
+		 HSIO_WRAP_RGMII_CFG_RGMII_TX_RST |
+		 HSIO_WRAP_RGMII_CFG_RGMII_RX_RST,
+		 port->sparx5, HSIO_WRAP_RGMII_CFG(idx));
+}
+
+/* Configure the RGMII port device. */
+static void lan969x_rgmii_port_device_config(struct sparx5_port *port,
+					     struct sparx5_port_config *conf)
+{
+	u32 dtag, dotag, etype, speed_sel, idx = RGMII_PORT_IDX(port);
+
+	speed_sel = lan969x_rgmii_get_speed_sel(conf->speed);
+
+	etype = (port->vlan_type == SPX5_VLAN_PORT_TYPE_S_CUSTOM ?
+		 port->custom_etype :
+		 port->vlan_type == SPX5_VLAN_PORT_TYPE_C ?
+		 ETH_P_8021Q : ETH_P_8021AD);
+
+	dtag = port->max_vlan_tags == SPX5_PORT_MAX_TAGS_TWO;
+	dotag = port->max_vlan_tags != SPX5_PORT_MAX_TAGS_NONE;
+
+	/* Enable the MAC. */
+	spx5_wr(DEVRGMII_MAC_ENA_CFG_RX_ENA_SET(1) |
+		DEVRGMII_MAC_ENA_CFG_TX_ENA_SET(1),
+		port->sparx5, DEVRGMII_MAC_ENA_CFG(idx));
+
+	/* Configure the Inter Frame Gap. */
+	spx5_wr(DEVRGMII_MAC_IFG_CFG_TX_IFG_SET(LAN969X_RGMII_IFG_TX) |
+		DEVRGMII_MAC_IFG_CFG_RX_IFG1_SET(LAN969X_RGMII_IFG_RX1) |
+		DEVRGMII_MAC_IFG_CFG_RX_IFG2_SET(LAN969X_RGMII_IFG_RX2),
+		port->sparx5, DEVRGMII_MAC_IFG_CFG(idx));
+
+	/* Configure port data rate. */
+	spx5_wr(DEVRGMII_DEV_RST_CTRL_SPEED_SEL_SET(speed_sel),
+		port->sparx5, DEVRGMII_DEV_RST_CTRL(idx));
+
+	/* Configure VLAN awareness. */
+	spx5_wr(DEVRGMII_MAC_TAGS_CFG_TAG_ID_SET(etype) |
+		DEVRGMII_MAC_TAGS_CFG_PB_ENA_SET(dtag) |
+		DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(dotag) |
+		DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(dotag),
+		port->sparx5,
+		DEVRGMII_MAC_TAGS_CFG(idx));
+}
+
+/* Configure the RGMII delay lines in the MAC.
+ *
+ * We use the rx-internal-delay-ps" and "tx-internal-delay-ps" properties to
+ * configure the rx and tx delays for the MAC. If these properties are missing
+ * or set to zero, the MAC will not apply any delay.
+ *
+ * The PHY side delays are determined by the PHY mode
+ * (e.g. PHY_INTERFACE_MODE_RGMII_{ID, RXID, TXID}), and ignored by the MAC side
+ * entirely.
+ */
+static int lan969x_rgmii_delay_config(struct sparx5_port *port,
+				      struct sparx5_port_config *conf)
+{
+	u32 tx_clk_sel, rx_clk_sel, tx_delay_ps = 0, rx_delay_ps = 0;
+	u32 idx = RGMII_PORT_IDX(port);
+	int err;
+
+	of_property_read_u32(port->of_node, "rx-internal-delay-ps",
+			     &rx_delay_ps);
+
+	of_property_read_u32(port->of_node, "tx-internal-delay-ps",
+			     &tx_delay_ps);
+
+	err = lan969x_rgmii_get_clk_delay_sel(port, rx_delay_ps, &rx_clk_sel);
+	if (err)
+		return err;
+
+	err = lan969x_rgmii_get_clk_delay_sel(port, tx_delay_ps, &tx_clk_sel);
+	if (err)
+		return err;
+
+	/* Configure rx delay. */
+	spx5_rmw(HSIO_WRAP_DLL_CFG_DLL_RST_SET(0) |
+		 HSIO_WRAP_DLL_CFG_DLL_ENA_SET(1) |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(!!rx_delay_ps) |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(rx_clk_sel),
+		 HSIO_WRAP_DLL_CFG_DLL_RST |
+		 HSIO_WRAP_DLL_CFG_DLL_ENA |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_ENA |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_SEL,
+		 port->sparx5, HSIO_WRAP_DLL_CFG(idx, 0));
+
+	/* Configure tx delay. */
+	spx5_rmw(HSIO_WRAP_DLL_CFG_DLL_RST_SET(0) |
+		 HSIO_WRAP_DLL_CFG_DLL_ENA_SET(1) |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(!!tx_delay_ps) |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(tx_clk_sel),
+		 HSIO_WRAP_DLL_CFG_DLL_RST |
+		 HSIO_WRAP_DLL_CFG_DLL_ENA |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_ENA |
+		 HSIO_WRAP_DLL_CFG_DLL_CLK_SEL,
+		 port->sparx5, HSIO_WRAP_DLL_CFG(idx, 1));
+
+	return 0;
+}
+
+/* Configure GPIO's to be used as RGMII interface. */
+static void lan969x_rgmii_gpio_config(struct sparx5_port *port)
+{
+	u32 idx = RGMII_PORT_IDX(port);
+
+	/* Enable the RGMII on the GPIOs. */
+	spx5_wr(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_SET(1), port->sparx5,
+		HSIO_WRAP_XMII_CFG(!idx));
+}
+
+int lan969x_port_config_rgmii(struct sparx5_port *port,
+			      struct sparx5_port_config *conf)
+{
+	int err;
+
+	err = lan969x_rgmii_delay_config(port, conf);
+	if (err)
+		return err;
+
+	lan969x_rgmii_tx_clk_config(port, conf);
+	lan969x_rgmii_gpio_config(port);
+	lan969x_rgmii_port_device_config(port, conf);
+
+	return 0;
+}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index c58d7841638e..3ae760da17e2 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -324,6 +324,8 @@ struct sparx5_ops {
 	irqreturn_t (*ptp_irq_handler)(int irq, void *args);
 	int (*dsm_calendar_calc)(struct sparx5 *sparx5, u32 taxi,
 				 struct sparx5_calendar_data *data);
+	int (*port_config_rgmii)(struct sparx5_port *port,
+				 struct sparx5_port_config *conf);
 };
 
 struct sparx5_main_io_resource {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 86d6c9e9ec7c..04bc8fffaf96 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1012,6 +1012,12 @@ int sparx5_port_config(struct sparx5 *sparx5,
 	if (err)
 		return err;
 
+	if (rgmii) {
+		err = ops->port_config_rgmii(port, conf);
+		if (err)
+			return err;
+	}
+
 	/* high speed device is already configured */
 	if (!rgmii && !high_speed_dev)
 		sparx5_port_config_low_set(sparx5, port, conf);

-- 
2.34.1



From jbrunet at baylibre.com  Fri Dec 20 06:08:24 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 15:08:24 +0100
Subject: [PATCH 0/2] clk: amlogic: gxbb: 32k clock fixes
In-Reply-To: <20241220-amlogic-clk-gxbb-32k-fixes-v1-0-baca56ecf2db@baylibre.com>
References: <20241220-amlogic-clk-gxbb-32k-fixes-v1-0-baca56ecf2db@baylibre.com>
Message-ID: <173470370410.3067219.1883604095856278984.b4-ty@baylibre.com>

Applied to clk-meson (clk-meson-next), thanks!

[1/2] clk: amlogic: gxbb: drop incorrect flag on 32k clock
      https://github.com/BayLibre/clk-meson/commit/66eff51d972c
[2/2] clk: amlogic: gxbb: drop non existing 32k clock parent
      https://github.com/BayLibre/clk-meson/commit/1e1fd26ed4ca

Best regards,
--
Jerome



From will at kernel.org  Fri Dec 20 06:13:22 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 20 Dec 2024 14:13:22 +0000
Subject: [PATCH] KVM: arm64: Selftest for pKVM transitions
In-Reply-To: <20241129125800.992468-1-qperret@google.com>
References: <20241129125800.992468-1-qperret@google.com>
Message-ID: <20241220141321.GA26794@willie-the-truck>

On Fri, Nov 29, 2024 at 12:58:00PM +0000, Quentin Perret wrote:
> We have recently found a bug [1] in the pKVM memory ownership
> transitions by code inspection, but it could have been caught with a
> test.
> 
> Introduce a boot-time selftest exercising all the known pKVM memory
> transitions and importantly checks the rejection of illegal transitions.

Thanks for doing this!

> 
> The new test is hidden behind a new Kconfig option separate from
> CONFIG_EL2_NVHE_DEBUG on purpose as that has side effects on the
> transition checks ([1] doesn't reproduce with EL2 debug enabled).

Hmm. What does a test failure look like without CONFIG_EL2_NVHE_DEBUG
enabled? Do we still get file:line information?

[...]

> +void pkvm_ownership_selftest(void)
> +{
> +	void *virt = hyp_alloc_pages(&host_s2_pool, 0);
> +	u64 phys, size, pfn;
> +
> +	WARN_ON(!virt);
> +	selftest_page = hyp_virt_to_page(virt);
> +	selftest_page->refcount = 0;
> +
> +	size = PAGE_SIZE << selftest_page->order;
> +	phys = hyp_virt_to_phys(virt);
> +	pfn = hyp_phys_to_pfn(phys);
> +
> +	selftest_state.host = PKVM_NOPAGE;
> +	selftest_state.hyp = PKVM_PAGE_OWNED;
> +	assert_page_state();
> +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> +	assert_transition_res(-EPERM,	__pkvm_host_unshare_hyp, pfn);
> +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_host_unshare_ffa, pfn, 1);
> +	assert_transition_res(-EPERM,	hyp_pin_shared_mem, virt, virt + size);
> +
> +	selftest_state.host = PKVM_PAGE_OWNED;
> +	selftest_state.hyp = PKVM_NOPAGE;
> +	assert_transition_res(0,	__pkvm_hyp_donate_host, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);
> +	assert_transition_res(-EPERM,	hyp_pin_shared_mem, virt, virt + size);

Should we recheck the unshare transitions here?

> +	selftest_state.host = PKVM_PAGE_SHARED_OWNED;
> +	selftest_state.hyp = PKVM_PAGE_SHARED_BORROWED;
> +	assert_transition_res(0,	__pkvm_host_share_hyp, pfn);
> +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);

We could check unshare_ffa here.

> +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);
> +
> +	assert_transition_res(0,	hyp_pin_shared_mem, virt, virt + size);

Is it worth trying an extra pin + unpin?

> +	WARN_ON(!hyp_page_count(virt));

Can we assert an exact value (e.g. count == 1)?

> +	assert_transition_res(-EBUSY,	__pkvm_host_unshare_hyp, pfn);
> +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);

unshare_ffa again here.

> +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);
> +
> +	hyp_unpin_shared_mem(virt, virt + size);
> +	assert_page_state();
> +	WARN_ON(hyp_page_count(virt));
> +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);

Is this block actually testing anything new? Once we've asserted the page
state and checked the refcount, the transitions seem redundant to me.

> +	selftest_state.host = PKVM_PAGE_OWNED;
> +	selftest_state.hyp = PKVM_NOPAGE;
> +	assert_transition_res(0,	__pkvm_host_unshare_hyp, pfn);
> +
> +	selftest_state.host = PKVM_PAGE_SHARED_OWNED;
> +	selftest_state.hyp = PKVM_NOPAGE;
> +	assert_transition_res(0,	__pkvm_host_share_ffa, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> +	assert_transition_res(-EPERM,	__pkvm_host_unshare_hyp, pfn);
> +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);
> +	assert_transition_res(-EPERM,	hyp_pin_shared_mem, virt, virt + size);
> +
> +	selftest_state.host = PKVM_PAGE_OWNED;
> +	selftest_state.hyp = PKVM_NOPAGE;
> +	assert_transition_res(0,	__pkvm_host_unshare_ffa, pfn, 1);

Try it twice?

Will


From zhengqi.arch at bytedance.com  Fri Dec 20 06:16:22 2024
From: zhengqi.arch at bytedance.com (Qi Zheng)
Date: Fri, 20 Dec 2024 22:16:22 +0800
Subject: [PATCH 01/10] mm: Move common parts of pagetable_*_[cd]tor to
 helpers
In-Reply-To: <2f65f93e-9d44-4acc-b63c-8f5a35f59699@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <20241219164425.2277022-2-kevin.brodsky@arm.com>
 <20241219171920.GB26279@noisy.programming.kicks-ass.net>
 <75cb4ff8-eb0c-4519-a30a-f8be717ba278@arm.com>
 <0daabd32-cba4-4345-baa8-e8c66bc899ff@bytedance.com>
 <2f65f93e-9d44-4acc-b63c-8f5a35f59699@arm.com>
Message-ID: <33ce9b58-4787-49cd-a7f2-34272cb3ecf7@bytedance.com>



On 2024/12/20 21:50, Kevin Brodsky wrote:
> On 20/12/2024 12:46, Qi Zheng wrote:
>> Hi Kevin,
>>
>> On 2024/12/20 18:49, Kevin Brodsky wrote:
>>> [...]
>>>
>>> Qi, shall we collaborate to make our series complementary? I believe my
>>> series covers patch 2 and 4 of your series, but it goes further by
>>> covering all levels and all architectures, and patches introducing
>>> ctor/dtor are already split as Alexander suggested on your series. So my
>>> suggestion would be:
>>>
>>> * Remove patch 1 in my series - I'd just introduce
>>> pagetable_{p4d,pgd}_[cd]tor with the same implementation as
>>> pagetable_pud_[cd]tor.
>>> * Remove patch 2 and 4 from your series and rebase it on mine.
>>
>> I quickly went through your patch series. It looks like my patch 2 and
>> your patch 6 are duplicated, so you want me to remove my patch 2.
>>
>> But I think you may not be able to simple let arm64, riscv and x86 to
>> use generic p4d_{alloc_one,free}(). Because even if
>> CONFIG_PGTABLE_LEVELS > 4, the pgtable_l5_enabled() may not be true.
>>
>> For example, in arm64:
>>
>> #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);
>> }
> 
> Correct. That's why the implementation of p4d_free() I introduce in
> patch 6 checks mm_p4d_folded(), which is implemented as
> !pgtable_l5_enabled() on those architectures (see last paragraph in
> commit message). In fact it turns out Alexander suggested exactly this
> approach [2].

OK, I see.

> 
>>
>> Did I miss something?
>>
>> My patch series is not only for cleanup, but also for fixes of
>> UAF issue [1], so is it possible to rebase your patch series onto
>> mine? I can post v3 ASAP.
> 
> I see, yours should be merged first then. The issue is that yours would
> depend on some of the patches in mine, not the other way round.
> 
> My suggestion would then be for you to take patch 5, 6 and 7 from my
> series, as they match Alexander's suggestions (and patch 5 is I think a
> useful simplification), and replace patch 2 in your series with those. I
> would then rebase my series on top and adapt it accordingly. Does that
> sound reasonable?

Sounds good. But maybe just patch 5 and 6. Because I actually did
the work of your patch 7 in my patch 2 and 4.

So, is it okay to do something like the following?

1. I separate the ctor()/dtor() part from my patch 2, and then replace
    the rest with your patch 6.
2. take your patch 5 form your series

If it's ok, I will post the v3 next Monday. ;)

Thanks!

> 
> - Kevin
> 
> [2]
> https://lore.kernel.org/all/Z2RKpdv7pL34MIEt at tuxmaker.boeblingen.de.ibm.com/
> 


From konrad.dybcio at oss.qualcomm.com  Fri Dec 20 06:20:37 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 20 Dec 2024 15:20:37 +0100
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on pre-SYSTEM_SUSPEND
 PSCI impls
In-Reply-To: <Z2V4IblZNgnS4T2Z@bogus>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241113165329590-0800.eberman@hu-eberman-lv.qualcomm.com>
 <e4509104-c809-4d45-bdbb-a2d754a816db@oss.qualcomm.com>
 <Z2VXgkJ4x5TJTKJ_@bogus>
 <765bb1c8-31de-4aec-b8ef-f141a3e25c56@oss.qualcomm.com>
 <Z2V4IblZNgnS4T2Z@bogus>
Message-ID: <875342b7-3825-47bf-810a-effdbeacab46@oss.qualcomm.com>

On 20.12.2024 2:58 PM, Sudeep Holla wrote:
> On Fri, Dec 20, 2024 at 01:42:04PM +0100, Konrad Dybcio wrote:
>> On 20.12.2024 12:39 PM, Sudeep Holla wrote:
>>> On Thu, Dec 19, 2024 at 08:26:51PM +0100, Konrad Dybcio wrote:
>>>> On 14.11.2024 2:10 AM, Elliot Berman wrote:
>>>>
>>>>> I'm not sure why you'd like to support s2ram. Is it *only* that you'd
>>>>> like to be able to set pm_set_supend/resume_via_firmware()? I hope this
>>>>> doesn't sound silly: what if you register a platform_s2idle_ops for the
>>>>> relevant SoCs which calls pm_set_suspend/resume_via_firwmare()?
>>>>
>>>> S2RAM is what you get after entering a certain state, but currently
>>>> it's presented as just another (s2idle) idle state.
>>>>
>>>
>>> Just to be clear, I assume you mean CPU_SUSPEND idle state. There is
>>> no special or different s2idle idle states IIUC.
>>
>> Yeah, right.
>>
>>>> That means some hardware that may need to be reinitialized, isn't as
>>>> Linux has no clue it might have lost power.
>>>>
>>>
>>> Interesting, so this means firmware doesn't automatically save and restore
>>> states yet exposes it as CPU_SUSPEND idle state.
>>
>> Reading the spec, I'm pretty sure PSCI calls should only mess with the
>> power state of the cores, core-adjacent peripherals and GIC.
>>
>> Reading section 5.20.1 (SYSTEM_SUSPEND / Intended use) I think it says
>> mostly what I'm trying to convey:
>>
>>
>> "In a typical implementation, the semantics are equivalent to a
>> CPU_SUSPEND to the deepest low-power state. However, it is possible that
>> an implementation might reserve a deeper state for SYSTEM_SUSPEND than
>> those used with CPU_SUSPEND."
>>
> 
> Yes these text help to understand the interface easily. If they were same,
> do you think we would have defined 2 different interfaces.

I would happen to think that, yes. Especially since the reference firmware
implementation does *exactly this*:

https://github.com/ARM-software/arm-trusted-firmware/blob/master/lib/psci/psci_main.c#L179-L221

PSCI_SYSTEM_SUSPEND seems to be simply meant as a wrapper around a specific
CPU_SUSPEND state (which may or may not be only callable from inside the
firmware when SYSTEM_SUSPEND specifically is requested, for reasons),
in a platform-agnostic way, so that the OS can enter suspend without
providing that magic StateID on all supported platforms.
But since it already requires more elbow grease on the peripheral IP side,
I'm not really convinced it's that much useful.

Plus, the optional bit of doing more work behind the scenes doesn't seem
to be very wildly used across TF-A supported platforms.

So please, stop making the argument that it's any different. The firmware
I'm dealing with simply didn't expose the same thing twice, in perfect
accordance with the spec.

Konrad


From konrad.dybcio at oss.qualcomm.com  Fri Dec 20 06:21:46 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 20 Dec 2024 15:21:46 +0100
Subject: [PATCH 1/3] dt-bindings: arm,psci: Allow S2RAM power_state
 parameter description
In-Reply-To: <Z2V5WMN5aHQwQlNH@bogus>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241028-topic-cpu_suspend_s2ram-v1-1-9fdd9a04b75c@oss.qualcomm.com>
 <Z1LQOmEfFy640PjG@bogus>
 <54cc4221-ba5f-4741-9033-20874265ca01@oss.qualcomm.com>
 <Z2VUiHWHgbWowdal@bogus>
 <349bac70-87e0-4870-a3f0-9f6a3b3e6824@oss.qualcomm.com>
 <Z2V3amqWYDUWA2uM@bogus>
 <c80c4cdb-48e1-4b6f-8ab8-fad6e100af00@oss.qualcomm.com>
 <Z2V5WMN5aHQwQlNH@bogus>
Message-ID: <b533ab3e-41e8-4078-99c9-1a9d80470279@oss.qualcomm.com>

On 20.12.2024 3:04 PM, Sudeep Holla wrote:
> On Fri, Dec 20, 2024 at 02:57:34PM +0100, Konrad Dybcio wrote:
>> On 20.12.2024 2:55 PM, Sudeep Holla wrote:
>>>
>>> Please take a look at the preconditions for both the calls. They are
>>> different.
>>
>> Which is *precisely* why I want to tell the OS that it's a S2RAM state,
>> so that different actions can be taken in peripheral device drivers.
> 
> Yes we do that for SYSTEM_SUSPEND. And CPU_SUSPEND is not SYSTEM_SUSPEND
> hence 2 different APIs. My NACK still stands.

I'll just paste it here one more time to reassure you they are indeed
the same under the hood

https://github.com/ARM-software/arm-trusted-firmware/blob/master/lib/psci/psci_main.c#L179-L221

Konrad


From kevin.brodsky at arm.com  Fri Dec 20 06:28:36 2024
From: kevin.brodsky at arm.com (Kevin Brodsky)
Date: Fri, 20 Dec 2024 15:28:36 +0100
Subject: [PATCH 01/10] mm: Move common parts of pagetable_*_[cd]tor to
 helpers
In-Reply-To: <33ce9b58-4787-49cd-a7f2-34272cb3ecf7@bytedance.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <20241219164425.2277022-2-kevin.brodsky@arm.com>
 <20241219171920.GB26279@noisy.programming.kicks-ass.net>
 <75cb4ff8-eb0c-4519-a30a-f8be717ba278@arm.com>
 <0daabd32-cba4-4345-baa8-e8c66bc899ff@bytedance.com>
 <2f65f93e-9d44-4acc-b63c-8f5a35f59699@arm.com>
 <33ce9b58-4787-49cd-a7f2-34272cb3ecf7@bytedance.com>
Message-ID: <7f5e6ac7-01ef-46c8-bc85-7f8399dadb19@arm.com>

On 20/12/2024 15:16, Qi Zheng wrote:
>>>
>>> Did I miss something?
>>>
>>> My patch series is not only for cleanup, but also for fixes of
>>> UAF issue [1], so is it possible to rebase your patch series onto
>>> mine? I can post v3 ASAP.
>>
>> I see, yours should be merged first then. The issue is that yours would
>> depend on some of the patches in mine, not the other way round.
>>
>> My suggestion would then be for you to take patch 5, 6 and 7 from my
>> series, as they match Alexander's suggestions (and patch 5 is I think a
>> useful simplification), and replace patch 2 in your series with those. I
>> would then rebase my series on top and adapt it accordingly. Does that
>> sound reasonable?
>
> Sounds good. But maybe just patch 5 and 6. Because I actually did
> the work of your patch 7 in my patch 2 and 4.

Yes that's fair! You'd have to do adapt my patch 7 to make it fit in
your series so I agree it makes more sense this way.

>
> So, is it okay to do something like the following?
>
> 1. I separate the ctor()/dtor() part from my patch 2, and then replace
> ?? the rest with your patch 6.
> 2. take your patch 5 form your series

Sounds good to me!

IIUC Dave Hansen gave his Acked-by for the x86 part of patch 6 [1],
would make sense to add it when you post your v3.

>
> If it's ok, I will post the v3 next Monday. ;)

Perfect. I'm going offline tonight, when I come back in the new year
I'll review your v3 series and post a new version of this one.

Cheers,
- Kevin

[1]
https://lore.kernel.org/linux-mm/a7398426-56d1-40b4-a1c9-40ae8c8a4b4b at intel.com/


From arnd at arndb.de  Fri Dec 20 06:30:41 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 20 Dec 2024 15:30:41 +0100
Subject: [PATCH 3/4] ARM: drop CONFIG_HIGHPTE support
In-Reply-To: <CACRpkdYihj15SRp5t_8Aq4i4jtgP1-VLOSbbKG+ozLgiAuLgmQ@mail.gmail.com>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-4-arnd@kernel.org>
 <d54e11cf3f4d4216b5cecf29b761cd45@AcuMS.aculab.com>
 <CACRpkdYihj15SRp5t_8Aq4i4jtgP1-VLOSbbKG+ozLgiAuLgmQ@mail.gmail.com>
Message-ID: <4d8ee82a-b767-4c3f-9735-2a1e0f6bbc8b@app.fastmail.com>

On Fri, Dec 20, 2024, at 14:10, Linus Walleij wrote:
> On Sat, Dec 14, 2024 at 7:41?PM David Laight <David.Laight at aculab.com> wrote:
>
>> From: Arnd Bergmann
>> > Sent: 10 December 2024 16:06
>> ...
>> > Since Arm is the last architecture remaining that uses this, and almost
>> > no 32-bit machines support more than 4GB of RAM, the cost of continuing
>> > to maintain HIGHPTE seems unjustified, so remove it here to allow
>> > simplifying the generic page table handling.
>>
>> 'Picking at nits' 'highmem' support was needed for systems with 4GB of RAM
>> in order to use more than 3GB or 3.5GB (depending on the bios) because
>> of the physical addresses that are reserved for PCI (and other MMIO).

What you mean here is CONFIG_HIGHMEM64G on x86, not CONFIG_HIGHMEM
or CONFIG_HIGHPTE.

> Wow I didn't know that, there are so many reasons why highmem is used
> by different architectures.
>
> On ARM it was originally added for a certain Marvell system with
> a mere 2GB of RAM:
> commit 053a96ca11a9785a7e63fc89eed4514a6446ec58
>
> The reason was that since the virtual address space is just 4GB and
> we have reserved virtual kernel memory from (typically) 0xc0000000
> only ~1GB can be linearly accessed by the kernel (actually less than
> that).
>
> This wasn't a problem since no ARM system was using more than
> 1GB until Nico ran into it.
>
> So the ARM "high memory" is something to do with virtual memory
> size rather than physical memory reservations as in the x86 case.

HIGHMEM works the exact same way on the major 32-bit architectures
(x86, arm, powerpc): With the default TASK_SIZE and PAGE_OFFSET
of set to 3GB (0xc0000000) you have 1GB left that is use for
the linear lowmem and the vmalloc area,  leaving between 786MB
and 900MB for lowmem, unless you shrink TASK_SIZE (CONFIG_VMSPLIT_*).

The most common systems (Intel Pentium M, PowerPC 74xx, Arm
Cortex-A9) have a 4GB address limit and have to fit both RAM and
MMIO or PCI into that, which is where the 3GB (Pentium M) through
3.9GB (i.MX6, Calxeda Highbank) total-RAM limit comes from.

The 4GB physical address limit is broken by CONFIG_PHYS_ADDR_T_64BIT
on some x86 server chipsets (Serverworks GC, HP F8, IBM Summit,
Intel 450GX, ...), Arm Cortex-A15 and PowerPC e500/e600 cores,
which gets you to the point where you fill up all your lowmem
before using all of highmem.

HIGHPTE was added when x86 servers to to 32GB, at which point
the lowmem is mostly filled with page tables for typical
workloads.

Other architectures (mips, sparc, arc, ...) have some but not
all of the above, HIGHPTE was only ever a thing on x86,
arm and frv.

     Arnd


From sudeep.holla at arm.com  Fri Dec 20 06:36:02 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 20 Dec 2024 14:36:02 +0000
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on
 pre-SYSTEM_SUSPEND PSCI impls
In-Reply-To: <875342b7-3825-47bf-810a-effdbeacab46@oss.qualcomm.com>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241113165329590-0800.eberman@hu-eberman-lv.qualcomm.com>
 <e4509104-c809-4d45-bdbb-a2d754a816db@oss.qualcomm.com>
 <Z2VXgkJ4x5TJTKJ_@bogus>
 <765bb1c8-31de-4aec-b8ef-f141a3e25c56@oss.qualcomm.com>
 <Z2V4IblZNgnS4T2Z@bogus>
 <875342b7-3825-47bf-810a-effdbeacab46@oss.qualcomm.com>
Message-ID: <Z2WA0o0QJS64ftVh@bogus>

On Fri, Dec 20, 2024 at 03:20:37PM +0100, Konrad Dybcio wrote:
>
> I would happen to think that, yes. Especially since the reference firmware
> implementation does *exactly this*:
>
> https://github.com/ARM-software/arm-trusted-firmware/blob/master/lib/psci/psci_main.c#L179-L221
>
> PSCI_SYSTEM_SUSPEND seems to be simply meant as a wrapper around a specific
> CPU_SUSPEND state (which may or may not be only callable from inside the
> firmware when SYSTEM_SUSPEND specifically is requested, for reasons),
> in a platform-agnostic way, so that the OS can enter suspend without
> providing that magic StateID on all supported platforms.

Exactly, that's how it can be OS and platform agnostic. Yet this platform
considered to optimise by not just providing it as a wrapper(if it was
that simple on your platform too) without running any tests and leaving
it to interested parties like you to mess around to get it working.
That practice needs to be fixed and this change won't help and once we
fix this, more such special treatment fixes are needed on newer platforms.
So lets stop and ensure things are fixed properly.

> But since it already requires more elbow grease on the peripheral IP side,
> I'm not really convinced it's that much useful.
>
> Plus, the optional bit of doing more work behind the scenes doesn't seem
> to be very wildly used across TF-A supported platforms.
>
> So please, stop making the argument that it's any different. The firmware
> I'm dealing with simply didn't expose the same thing twice, in perfect
> accordance with the spec.
>

So that it can continue to do so in the future ?
Thanks but no thanks. NACK with no arguments as requested.

--
Regards,
Sudeep


From arnd at arndb.de  Fri Dec 20 06:37:30 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 20 Dec 2024 15:37:30 +0100
Subject: [PATCH 2/4] ARM: Disable HIGHPTE on PREEMPT_RT kernels
In-Reply-To: <Z1m18yn67dsJRVWA@shell.armlinux.org.uk>
References: <20241210160556.2341497-1-arnd@kernel.org>
 <20241210160556.2341497-3-arnd@kernel.org>
 <20241211134811.wM_UADhQ@linutronix.de>
 <20241211140402.yf7gMExr@linutronix.de>
 <Z1m18yn67dsJRVWA@shell.armlinux.org.uk>
Message-ID: <41427a05-f032-4713-812d-7f8a021067d8@app.fastmail.com>

TL;DR: I would still like to merge patch 3 and 4, but let's
keep that separate from the RT patches.

(just realized I had never sent my reply here)

On Wed, Dec 11, 2024, at 16:55, Russell King (Oracle) wrote:
> On Wed, Dec 11, 2024 at 03:04:02PM +0100, Sebastian Andrzej Siewior wrote:
>
> However, what is quite different is the L1 page tables. On x86,
> everything is nice and easy, and each page table is one 4k page.
> On 32-bit Arm, this is not the case - we need to grab a 16k page for
> the L1, and the more immovable allocations we have in lowmem, the
> harder it will be to satisfy this. Failing to grab a 16k page
> leads to fork() failing and an unusable system.
>
> So, we want to keep as many immovable allocations out of lowmem as
> possible - which is an additional constraint x86 doesn't have, and
> shouldn't be overlooked without ensuring that the probability of it
> happening remains acceptably low.

Right, non-LPAE systems indeed have a bigger problem with
fragmentation here, I hadn't thought of that.  Most of the
systems with 4GB RAM (and all of those with more) support
LPAE though, which means they can use the same page table
layout as x86 when when using CONFIG_LPAE=y.

Almost all SoCs prior to ARMv7VE are limited to 2GB of RAM
or less, the only exceptions I can think of are three SoCs
that can use close to 4GB (a small physical address range 
is used for MMIO):

- Calxeda highbank
- Hisilicon hip01
- NXP i.MX6D/DP/Q/QP

We can throw the first two under the bus, I'm sure nobody
cares enough, but the i.MX6Q was actually shipped in a
handful of products with 4GB that some users still have:

- Bunnie's Novena Laptop (856 original backers on crowdsupply)
- Solidrun CuBox i4x4 (not the more common i4P)
- Solidrun Hummingboard (early revisions only, later 2GB)

A couple of other i.MX6Q boards were advertised as supporting
"up to 4GB", but if you tried to buy those, the only ones in
stock anywhere seemed to be limited to 1 or 2 GB. Examples:

- armstone A9r4 (dts not upstream)
- DFI FS053 (dts not  upstream)
- VAR-SOM-MX6

[Part of the problem here apparently was availability
and cost of qualified 8Gbit DDR3 chips.]

Do you know of any other SoCs or boards in that category?

My feeling so far is that none of these are show-stoppers:

- The 4GB/8GB boards with LPAE don't have the added problem
  of fragmentation with order-2 page table allocations.
  They can run low on lowmem with CONFIG_VMSPLIT_3G, but
  as Sebastian cited, HIGHPTE is not likely to be the
  breaking point for them. These were mainly built around
  2012-2013 (before 64-bit became available) as high-end
  SoCs and are reaching the end of their commercial life.
- The 4GB boards without LPAE are also 10+ years old by now
  and were fairly rare even then. These would suffer the
  most from the fragmentation though.
- The 2GB boards with or without LPAE can theoretically
  avoid HIGHMEM entirely by using CONFIG_VMSPLIT_2G_OPT.
  These are still very common today, but at least a third
  of the total memory is going to be available as lowmem
  even with VMSPLIT_3G.

The case that is less clear to me is the one where memory
is sparse enough to lead to exhausting lowmem without
having a lot of total RAM. These are a little harder
to find, but I think e.g. Renesas has some chips that
need this, and Realview PBX had a custom __phys_to_virt
in earlier versions to work around this. This should
be solved when we get the "densemem" support that Linus
mentioned.

     Arnd


From tudor.ambarus at linaro.org  Fri Dec 20 06:32:51 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 14:32:51 +0000
Subject: [PATCH v5 1/3] dt-bindings: firmware: add google,gs101-acpm-ipc
In-Reply-To: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>
References: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>
Message-ID: <20241220-gs101-acpm-v5-1-4f26b7fb3f5f@linaro.org>

Add bindings for the Samsung Exynos ACPM mailbox protocol.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 .../bindings/firmware/google,gs101-acpm-ipc.yaml   | 50 ++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
new file mode 100644
index 000000000000..982cb8d62011
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2024 Linaro Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/google,gs101-acpm-ipc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos ACPM mailbox protocol
+
+maintainers:
+  - Tudor Ambarus <tudor.ambarus at linaro.org>
+
+description: |
+  ACPM (Alive Clock and Power Manager) is a firmware that operates on the
+  APM (Active Power Management) module that handles overall power management
+  activities. ACPM and masters regard each other as independent hardware
+  component and communicate with each other using mailbox messages and
+  shared memory.
+
+  This binding is intended to define the interface the firmware implementing
+  ACPM provides for OSPM in the device tree.
+
+properties:
+  compatible:
+    const: google,gs101-acpm-ipc
+
+  mboxes:
+    maxItems: 1
+
+  shmem:
+    description:
+      List of phandle pointing to the shared memory (SHM) area. The memory
+      contains channels configuration data and the TX/RX ring buffers that
+      are used for passing messages to/from the ACPM firmware.
+    maxItems: 1
+
+required:
+  - compatible
+  - mboxes
+  - shmem
+
+additionalProperties: false
+
+examples:
+  - |
+    power-management {
+        compatible = "google,gs101-acpm-ipc";
+        mboxes = <&ap2apm_mailbox>;
+        shmem = <&apm_sram>;
+    };

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Fri Dec 20 06:32:50 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 14:32:50 +0000
Subject: [PATCH v5 0/3] firmware: add Exynos ACPM protocol driver
Message-ID: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>

Alive Clock and Power Manager (ACPM) Message Protocol is defined for
the purpose of communication between the ACPM firmware and masters
(AP, AOC, ...). ACPM firmware operates on the Active Power Management
(APM) module that handles overall power activities.

This protocol driver provides the interface for all the client drivers
making use of the features offered by the APM. Add ACPM protocol support.

Changes in v5:
- depends on:
  - Link: https://lore.kernel.org/all/20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a at linaro.org/
  - it uses the newly introduced mbox_request_channel_by_args() API
- dt-bindings:
  - drop redundant binding word from the commit subject
  - remove extra blank line and update example with by complying to
    #mbox-cells = <0>;
  - drop Krzysztof's R-b tag as the example was updated.
- driver:
  - channel identifiers are discovered at runtime, use
    mbox_request_channel_by_args() instead of specifying them in DT.
  - don't call mbox_free_channel() for PTR_ERR or NULL channels.
  - introduce common method to init xfer
  - rename guard name from __EXYNOS_ACPM_MFD_H__ to __EXYNOS_ACPM_PMIC_H__
  - stop exporting devm_acpm_get_by_phandle(). We'll export the symbol
    once a client is introduced.
- rebase on top of v6.13-rc3
- Link to v4: https://lore.kernel.org/r/20241212-b4-acpm-v4-upstream-firmware-v4-0-3f18ca64f1b9 at linaro.org

Changes in v4:
- rename bindings filename based on compatible
- bindings: drop nodename
- bindings: drop mboxes description
- bindings: remove initdata-base prop, and define it based on compatible
- bindings: move additionalProperties after the required block
- bindings: drop firmware node from examples
- bindings: drop unused label in examples
- bindings: rename node to power-management
- driver: switch 2 macros to inline functions for readability
- driver: add checl to avoid shift overflow on these inline functions
- driver: use ktime_to_ms(ktime_get()) to record ktime
- driver: use the default non-relaxed IO accessors
- driver: remove atomic handling
- driver: remove stray of_match_ptr()
- driver: move header in include/linux/firmware
- driver: make sure to, from are 32-bit aligned and count is a 32bit
  quantity before calling __{ioread, write}32_copy
- driver: reject IRQ channels (not supported yet_ at the top of do_xfer,
  instead of when waiting for response.

Changes in v3:
- decouple the mailbox controller driver from the ACPM protocol driver
- address Krzysztof's eview comments
- add ACPM PMIC protocol helpers

v2:
https://lore.kernel.org/linux-arm-kernel/20241017163649.3007062-1-tudor.ambarus at linaro.org/

v1:
https://lore.kernel.org/linux-arm-kernel/20241004165301.1979527-1-tudor.ambarus at linaro.org/

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Tudor Ambarus (3):
      dt-bindings: firmware: add google,gs101-acpm-ipc
      firmware: add Exynos ACPM protocol driver
      MAINTAINERS: add entry for the Samsung Exynos ACPM mailbox protocol

 .../bindings/firmware/google,gs101-acpm-ipc.yaml   |  50 ++
 MAINTAINERS                                        |  10 +
 drivers/firmware/Kconfig                           |   1 +
 drivers/firmware/Makefile                          |   1 +
 drivers/firmware/samsung/Kconfig                   |  14 +
 drivers/firmware/samsung/Makefile                  |   4 +
 drivers/firmware/samsung/exynos-acpm-pmic.c        | 224 ++++++
 drivers/firmware/samsung/exynos-acpm-pmic.h        |  24 +
 drivers/firmware/samsung/exynos-acpm.c             | 805 +++++++++++++++++++++
 drivers/firmware/samsung/exynos-acpm.h             |  15 +
 .../linux/firmware/samsung/exynos-acpm-protocol.h  |  55 ++
 11 files changed, 1203 insertions(+)
---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241220-gs101-acpm-047922ab4654

Best regards,
-- 
Tudor Ambarus <tudor.ambarus at linaro.org>



From tudor.ambarus at linaro.org  Fri Dec 20 06:32:53 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 14:32:53 +0000
Subject: [PATCH v5 3/3] MAINTAINERS: add entry for the Samsung Exynos ACPM
 mailbox protocol
In-Reply-To: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>
References: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>
Message-ID: <20241220-gs101-acpm-v5-3-4f26b7fb3f5f@linaro.org>

Add entry for the Samsung Exynos ACPM mailbox protocol.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index baf0eeb9a355..5cfec7cac9eb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3023,6 +3023,7 @@ F:	drivers/*/*s3c24*
 F:	drivers/*/*s3c64xx*
 F:	drivers/*/*s5pv210*
 F:	drivers/clocksource/samsung_pwm_timer.c
+F:	drivers/firmware/samsung/
 F:	drivers/memory/samsung/
 F:	drivers/pwm/pwm-samsung.c
 F:	drivers/soc/samsung/
@@ -20717,6 +20718,15 @@ F:	arch/arm64/boot/dts/exynos/exynos850*
 F:	drivers/clk/samsung/clk-exynos850.c
 F:	include/dt-bindings/clock/exynos850.h
 
+SAMSUNG EXYNOS ACPM MAILBOX PROTOCOL
+M:	Tudor Ambarus <tudor.ambarus at linaro.org>
+L:	linux-kernel at vger.kernel.org
+L:	linux-samsung-soc at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
+F:	drivers/firmware/samsung/exynos-acpm*
+F:	include/linux/firmware/samsung/exynos-acpm-protocol.h
+
 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 M:	Krzysztof Kozlowski <krzk at kernel.org>
 L:	linux-crypto at vger.kernel.org

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Fri Dec 20 06:32:52 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 14:32:52 +0000
Subject: [PATCH v5 2/3] firmware: add Exynos ACPM protocol driver
In-Reply-To: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>
References: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>
Message-ID: <20241220-gs101-acpm-v5-2-4f26b7fb3f5f@linaro.org>

Alive Clock and Power Manager (ACPM) Message Protocol is defined for
the purpose of communication between the ACPM firmware and masters
(AP, AOC, ...). ACPM firmware operates on the Active Power Management
(APM) module that handles overall power activities.

ACPM and masters regard each other as independent hardware component and
communicate with each other using mailbox messages and shared memory.

This protocol driver provides the interface for all the client drivers
making use of the features offered by the APM. Add ACPM protocol support.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/firmware/Kconfig                           |   1 +
 drivers/firmware/Makefile                          |   1 +
 drivers/firmware/samsung/Kconfig                   |  14 +
 drivers/firmware/samsung/Makefile                  |   4 +
 drivers/firmware/samsung/exynos-acpm-pmic.c        | 224 ++++++
 drivers/firmware/samsung/exynos-acpm-pmic.h        |  24 +
 drivers/firmware/samsung/exynos-acpm.c             | 805 +++++++++++++++++++++
 drivers/firmware/samsung/exynos-acpm.h             |  15 +
 .../linux/firmware/samsung/exynos-acpm-protocol.h  |  55 ++
 9 files changed, 1143 insertions(+)

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 71d8b26c4103..24edb956831b 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -267,6 +267,7 @@ source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/microchip/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/qcom/Kconfig"
+source "drivers/firmware/samsung/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
 source "drivers/firmware/tegra/Kconfig"
 source "drivers/firmware/xilinx/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 7a8d486e718f..91efcc868a05 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -33,6 +33,7 @@ obj-y				+= efi/
 obj-y				+= imx/
 obj-y				+= psci/
 obj-y				+= qcom/
+obj-y				+= samsung/
 obj-y				+= smccc/
 obj-y				+= tegra/
 obj-y				+= xilinx/
diff --git a/drivers/firmware/samsung/Kconfig b/drivers/firmware/samsung/Kconfig
new file mode 100644
index 000000000000..750b41342174
--- /dev/null
+++ b/drivers/firmware/samsung/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config EXYNOS_ACPM_PROTOCOL
+	tristate "Exynos Alive Clock and Power Manager (ACPM) Message Protocol"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	depends on EXYNOS_MBOX
+	help
+	  Alive Clock and Power Manager (ACPM) Message Protocol is defined for
+	  the purpose of communication between the ACPM firmware and masters
+	  (AP, AOC, ...). ACPM firmware operates on the Active Power Management
+	  (APM) module that handles overall power activities.
+
+	  This protocol driver provides interface for all the client drivers
+	  making use of the features offered by the APM.
diff --git a/drivers/firmware/samsung/Makefile b/drivers/firmware/samsung/Makefile
new file mode 100644
index 000000000000..7b4c9f6f34f5
--- /dev/null
+++ b/drivers/firmware/samsung/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+acpm-protocol-objs			:= exynos-acpm.o exynos-acpm-pmic.o
+obj-$(CONFIG_EXYNOS_ACPM_PROTOCOL)	+= acpm-protocol.o
diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.c b/drivers/firmware/samsung/exynos-acpm-pmic.c
new file mode 100644
index 000000000000..d698e5a03630
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm-pmic.c
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+#include <linux/bitfield.h>
+#include <linux/firmware/samsung/exynos-acpm-protocol.h>
+#include <linux/ktime.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include "exynos-acpm.h"
+#include "exynos-acpm-pmic.h"
+
+#define ACPM_PMIC_CHANNEL		GENMASK(15, 12)
+#define ACPM_PMIC_TYPE			GENMASK(11, 8)
+#define ACPM_PMIC_REG			GENMASK(7, 0)
+
+#define ACPM_PMIC_RETURN		GENMASK(31, 24)
+#define ACPM_PMIC_MASK			GENMASK(23, 16)
+#define ACPM_PMIC_VALUE			GENMASK(15, 8)
+#define ACPM_PMIC_FUNC			GENMASK(7, 0)
+
+#define ACPM_PMIC_BULK_SHIFT		8
+#define ACPM_PMIC_BULK_MASK		GENMASK(7, 0)
+#define ACPM_PMIC_BULK_MAX_COUNT	8
+
+enum exynos_acpm_pmic_func {
+	ACPM_PMIC_READ,
+	ACPM_PMIC_WRITE,
+	ACPM_PMIC_UPDATE,
+	ACPM_PMIC_BULK_READ,
+	ACPM_PMIC_BULK_WRITE,
+};
+
+static inline u32 acpm_pmic_set_bulk(u32 data, unsigned int i)
+{
+	return (data & ACPM_PMIC_BULK_MASK) << (ACPM_PMIC_BULK_SHIFT * i);
+}
+
+static inline u32 acpm_pmic_get_bulk(u32 data, unsigned int i)
+{
+	return (data >> (ACPM_PMIC_BULK_SHIFT * i)) & ACPM_PMIC_BULK_MASK;
+}
+
+static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd,
+			       int acpm_chan_id)
+{
+	xfer->tx.cmd = cmd;
+	xfer->tx.len = sizeof(cmd);
+	xfer->rx.cmd = cmd;
+	xfer->rx.len = sizeof(cmd);
+	xfer->acpm_chan_id = acpm_chan_id;
+}
+
+static void acpm_pmic_init_read_cmd(u32 *cmd, u8 type, u8 reg, u8 chan)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_READ);
+	cmd[3] = ktime_to_ms(ktime_get());
+}
+
+int acpm_pmic_read_reg(const struct acpm_handle *handle, int acpm_chan_id,
+		       u8 type, u8 reg, u8 chan, u8 *dest)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_read_cmd(cmd, type, reg, chan);
+	acpm_dvfs_set_xfer(&xfer, cmd, acpm_chan_id);
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	*dest = FIELD_GET(ACPM_PMIC_VALUE, xfer.rx.cmd[1]);
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+static void acpm_pmic_init_bulk_read_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+					 u8 count)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_BULK_READ) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, count);
+}
+
+int acpm_pmic_bulk_read(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 count, u8 *buf)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int i, ret;
+
+	if (count > ACPM_PMIC_BULK_MAX_COUNT)
+		return -EINVAL;
+
+	acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count);
+	acpm_dvfs_set_xfer(&xfer, cmd, acpm_chan_id);
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	ret = FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < count; i++) {
+		if (i < 4)
+			buf[i] = acpm_pmic_get_bulk(xfer.rx.cmd[2], i);
+		else
+			buf[i] = acpm_pmic_get_bulk(xfer.rx.cmd[3], i - 4);
+	}
+
+	return 0;
+}
+
+static void acpm_pmic_init_write_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+				     u8 value)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_WRITE) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, value);
+	cmd[3] = ktime_to_ms(ktime_get());
+}
+
+int acpm_pmic_write_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 value)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_write_cmd(cmd, type, reg, chan, value);
+	acpm_dvfs_set_xfer(&xfer, cmd, acpm_chan_id);
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+static void acpm_pmic_init_bulk_write_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+					  u8 count, u8 *buf)
+{
+	int i;
+
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_BULK_WRITE) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, count);
+
+	for (i = 0; i < count; i++) {
+		if (i < 4)
+			cmd[2] |= acpm_pmic_set_bulk(buf[i], i);
+		else
+			cmd[3] |= acpm_pmic_set_bulk(buf[i], i - 4);
+	}
+}
+
+int acpm_pmic_bulk_write(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 count, u8 *buf)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	if (count > ACPM_PMIC_BULK_MAX_COUNT)
+		return -EINVAL;
+
+	acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf);
+	acpm_dvfs_set_xfer(&xfer, cmd, acpm_chan_id);
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+static void acpm_pmic_init_update_cmd(u32 *cmd, u8 type, u8 reg, u8 chan,
+				      u8 value, u8 mask)
+{
+	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
+		 FIELD_PREP(ACPM_PMIC_REG, reg) |
+		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
+	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_UPDATE) |
+		 FIELD_PREP(ACPM_PMIC_VALUE, value) |
+		 FIELD_PREP(ACPM_PMIC_MASK, mask);
+	cmd[3] = ktime_to_ms(ktime_get());
+}
+
+int acpm_pmic_update_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 value, u8 mask)
+{
+	struct acpm_xfer xfer;
+	u32 cmd[4] = {0};
+	int ret;
+
+	acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask);
+	acpm_dvfs_set_xfer(&xfer, cmd, acpm_chan_id);
+
+	ret = acpm_do_xfer(handle, &xfer);
+	if (ret)
+		return ret;
+
+	return FIELD_GET(ACPM_PMIC_RETURN, xfer.rx.cmd[1]);
+}
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos ACPM mailbox PMIC protocol driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.h b/drivers/firmware/samsung/exynos-acpm-pmic.h
new file mode 100644
index 000000000000..92b1997d9933
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm-pmic.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+#ifndef __EXYNOS_ACPM_PMIC_H__
+#define __EXYNOS_ACPM_PMIC_H__
+
+#include <linux/types.h>
+
+struct acpm_handle;
+
+int acpm_pmic_read_reg(const struct acpm_handle *handle, int acpm_chan_id,
+		       u8 type, u8 reg, u8 chan, u8 *dest);
+int acpm_pmic_bulk_read(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+int acpm_pmic_write_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 value);
+int acpm_pmic_bulk_write(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+int acpm_pmic_update_reg(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 value, u8 mask);
+#endif /* __EXYNOS_ACPM_PMIC_H__ */
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
new file mode 100644
index 000000000000..2f98306f8325
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -0,0 +1,805 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitmap.h>
+#include <linux/bits.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/firmware/samsung/exynos-acpm-protocol.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/math.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "exynos-acpm.h"
+#include "exynos-acpm-pmic.h"
+
+#define ACPM_PROTOCOL_SEQNUM		GENMASK(21, 16)
+
+/* The unit of counter is 20 us. 5000 * 20 = 100 ms */
+#define ACPM_POLL_TIMEOUT		5000
+#define ACPM_TX_TIMEOUT_US		500000
+
+#define ACPM_GS101_INITDATA_BASE	0xa000
+
+/**
+ * struct acpm_shmem - shared memory configuration information.
+ * @reserved:	unused fields.
+ * @chans:	offset to array of struct acpm_chan_shmem.
+ * @reserved1:	unused fields.
+ * @num_chans:	number of channels.
+ */
+struct acpm_shmem {
+	u32 reserved[2];
+	u32 chans;
+	u32 reserved1[3];
+	u32 num_chans;
+};
+
+/**
+ * struct acpm_chan_shmem - descriptor of a shared memory channel.
+ *
+ * @id:			channel ID.
+ * @reserved:		unused fields.
+ * @rx_rear:		rear pointer of APM RX queue (TX for AP).
+ * @rx_front:		front pointer of APM RX queue (TX for AP).
+ * @rx_base:		base address of APM RX queue (TX for AP).
+ * @reserved1:		unused fields.
+ * @tx_rear:		rear pointer of APM TX queue (RX for AP).
+ * @tx_front:		front pointer of APM TX queue (RX for AP).
+ * @tx_base:		base address of APM TX queue (RX for AP).
+ * @qlen:		queue length. Applies to both TX/RX queues.
+ * @mlen:		message length. Applies to both TX/RX queues.
+ * @reserved2:		unused fields.
+ * @poll_completion:	true when the channel works on polling.
+ */
+struct acpm_chan_shmem {
+	u32 id;
+	u32 reserved[3];
+	u32 rx_rear;
+	u32 rx_front;
+	u32 rx_base;
+	u32 reserved1[3];
+	u32 tx_rear;
+	u32 tx_front;
+	u32 tx_base;
+	u32 qlen;
+	u32 mlen;
+	u32 reserved2[2];
+	u32 poll_completion;
+};
+
+/**
+ * struct acpm_queue - exynos acpm queue.
+ *
+ * @rear:	rear address of the queue.
+ * @front:	front address of the queue.
+ * @base:	base address of the queue.
+ */
+struct acpm_queue {
+	void __iomem *rear;
+	void __iomem *front;
+	void __iomem *base;
+};
+
+/**
+ * struct acpm_rx_data - RX queue data.
+ *
+ * @cmd:	pointer to where the data shall be saved.
+ * @n_cmd:	number of 32-bit commands.
+ * @response:	true if the client expects the RX data.
+ */
+struct acpm_rx_data {
+	u32 *cmd;
+	size_t n_cmd;
+	bool response;
+};
+
+#define ACPM_SEQNUM_MAX    64
+
+/**
+ * struct acpm_chan - driver internal representation of a channel.
+ * @cl:		mailbox client.
+ * @chan:	mailbox channel.
+ * @acpm:	pointer to driver private data.
+ * @tx:		TX queue. The enqueue is done by the host.
+ *			- front index is written by the host.
+ *			- rear index is written by the firmware.
+ *
+ * @rx:		RX queue. The enqueue is done by the firmware.
+ *			- front index is written by the firmware.
+ *			- rear index is written by the host.
+ * @tx_lock:	protects TX queue.
+ * @rx_lock:	protects RX queue.
+ * @qlen:	queue length. Applies to both TX/RX queues.
+ * @mlen:	message length. Applies to both TX/RX queues.
+ * @seqnum:	sequence number of the last message enqueued on TX queue.
+ * @id:		channel ID.
+ * @poll_completion:	indicates if the transfer needs to be polled for
+ *			completion or interrupt mode is used.
+ * @bitmap_seqnum: bitmap that tracks the messages on the TX/RX queues.
+ * @rx_data:	internal buffer used to drain the RX queue.
+ */
+struct acpm_chan {
+	struct mbox_client cl;
+	struct mbox_chan *chan;
+	struct acpm_info *acpm;
+	struct acpm_queue tx;
+	struct acpm_queue rx;
+	struct mutex tx_lock;
+	struct mutex rx_lock;
+
+	unsigned int qlen;
+	unsigned int mlen;
+	u8 seqnum;
+	u8 id;
+	bool poll_completion;
+
+	DECLARE_BITMAP(bitmap_seqnum, ACPM_SEQNUM_MAX - 1);
+	struct acpm_rx_data rx_data[ACPM_SEQNUM_MAX];
+};
+
+/**
+ * struct acpm_info - driver's private data.
+ * @shmem:	pointer to the SRAM configuration data.
+ * @sram_base:	base address of SRAM.
+ * @chans:	pointer to the ACPM channel parameters retrieved from SRAM.
+ * @dev:	pointer to the exynos-acpm device.
+ * @handle:	instance of acpm_handle to send to clients.
+ * @node:	list head
+ * @num_chans:	number of channels available for this controller.
+ * @users:	number of users of this instance.
+ */
+struct acpm_info {
+	struct acpm_shmem __iomem *shmem;
+	void __iomem *sram_base;
+	struct acpm_chan *chans;
+	struct device *dev;
+	struct acpm_handle handle;
+	struct list_head node;
+	u32 num_chans;
+	/* protected by acpm_list_mutex */
+	int users;
+};
+
+/**
+ * struct acpm_match_data - of_device_id data.
+ * @initdata_base:	offset in SRAM where the channels configuration resides.
+ */
+struct acpm_match_data {
+	loff_t initdata_base;
+};
+
+#define client_to_acpm_chan(c) container_of(c, struct acpm_chan, cl)
+#define handle_to_acpm_info(h) container_of(h, struct acpm_info, handle)
+
+/* List of all ACPM devices active in system */
+static LIST_HEAD(acpm_list);
+/* Protection for the entire list */
+static DEFINE_MUTEX(acpm_list_mutex);
+
+static inline void acpm_memcpy_fromio32(void *to, const void __iomem *from,
+					size_t count)
+{
+	WARN_ON(!IS_ALIGNED((unsigned long)from, 4) ||
+		!IS_ALIGNED((unsigned long)to, 4) ||
+		count % 4);
+
+	__ioread32_copy(to, from, count / 4);
+}
+
+static inline void acpm_memcpy_toio32(void __iomem *to, const void *from,
+				      size_t count)
+{
+	WARN_ON(!IS_ALIGNED((unsigned long)to, 4) ||
+		!IS_ALIGNED((unsigned long)from, 4) ||
+		count % 4);
+
+	__iowrite32_copy(to, from, count / 4);
+}
+
+/**
+ * acpm_get_rx() - get response from RX queue.
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer to get response for.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_get_rx(struct acpm_chan *achan, struct acpm_xfer *xfer)
+{
+	struct acpm_msg *tx = &xfer->tx;
+	struct acpm_msg *rx = &xfer->rx;
+	struct acpm_rx_data *rx_data;
+	const void __iomem *base, *addr;
+	u32 rx_front, rx_seqnum, tx_seqnum, seqnum;
+	u32 i, val, mlen;
+	bool rx_set = false;
+
+	rx_front = readl(achan->rx.front);
+	i = readl(achan->rx.rear);
+
+	/* Bail out if RX is empty. */
+	if (i == rx_front)
+		return 0;
+
+	base = achan->rx.base;
+	mlen = achan->mlen;
+
+	tx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, tx->cmd[0]);
+
+	/* Drain RX queue. */
+	do {
+		/* Read RX seqnum. */
+		addr = base + mlen * i;
+		val = readl(addr);
+
+		rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, val);
+		if (!rx_seqnum)
+			return -EIO;
+		/*
+		 * mssg seqnum starts with value 1, whereas the driver considers
+		 * the first mssg at index 0.
+		 */
+		seqnum = rx_seqnum - 1;
+		rx_data = &achan->rx_data[seqnum];
+
+		if (rx_data->response) {
+			if (rx_seqnum == tx_seqnum) {
+				acpm_memcpy_fromio32(rx->cmd, addr, rx->len);
+				rx_set = true;
+				clear_bit(seqnum, achan->bitmap_seqnum);
+			} else {
+				/*
+				 * The RX data corresponds to another request.
+				 * Save the data to drain the queue, but don't
+				 * clear yet the bitmap. It will be cleared
+				 * after the response is copied to the request.
+				 */
+				acpm_memcpy_fromio32(rx_data->cmd, addr,
+						     rx->len);
+			}
+		} else {
+			clear_bit(seqnum, achan->bitmap_seqnum);
+		}
+
+		i = (i + 1) % achan->qlen;
+	} while (i != rx_front);
+
+	/* We saved all responses, mark RX empty. */
+	writel(rx_front, achan->rx.rear);
+
+	/*
+	 * If the response was not in this iteration of the queue, check if the
+	 * RX data was previously saved.
+	 */
+	rx_data = &achan->rx_data[tx_seqnum - 1];
+	if (!rx_set && rx_data->response) {
+		rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM,
+				      rx_data->cmd[0]);
+
+		if (rx_seqnum == tx_seqnum) {
+			memcpy(rx->cmd, rx_data->cmd, rx->len);
+			clear_bit(rx_seqnum - 1, achan->bitmap_seqnum);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * acpm_dequeue_by_polling() - RX dequeue by polling.
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer being waited for.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_dequeue_by_polling(struct acpm_chan *achan,
+				   struct acpm_xfer *xfer)
+{
+	struct device *dev = achan->acpm->dev;
+	struct acpm_msg *tx = &xfer->tx;
+	unsigned int cnt_20us = 0;
+	u32 seqnum;
+	int ret;
+
+	seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, tx->cmd[0]);
+
+	do {
+		mutex_lock(&achan->rx_lock);
+		ret = acpm_get_rx(achan, xfer);
+		mutex_unlock(&achan->rx_lock);
+		if (ret)
+			return ret;
+
+		if (!test_bit(seqnum - 1, achan->bitmap_seqnum))
+			return 0;
+
+		/* Determined experimentally. */
+		usleep_range(20, 30);
+		cnt_20us++;
+	} while (cnt_20us < ACPM_POLL_TIMEOUT);
+
+	dev_err(dev, "Timeout! ch:%u s:%u bitmap:%lx, cnt_20us = %d.\n",
+		achan->id, seqnum, achan->bitmap_seqnum[0], cnt_20us);
+
+	return -ETIME;
+}
+
+/**
+ * acpm_wait_for_queue_slots() - wait for queue slots.
+ *
+ * @achan:		ACPM channel info.
+ * @next_tx_front:	next front index of the TX queue.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_wait_for_queue_slots(struct acpm_chan *achan, u32 next_tx_front)
+{
+	u32 val, ret;
+
+	/*
+	 * Wait for RX front to keep up with TX front. Make sure there's at
+	 * least one element between them.
+	 */
+	ret = readl_poll_timeout(achan->rx.front, val, next_tx_front != val, 0,
+				 ACPM_TX_TIMEOUT_US);
+	if (ret) {
+		dev_err(achan->acpm->dev, "RX front can not keep up with TX front.\n");
+		return ret;
+	}
+
+	ret = readl_poll_timeout(achan->tx.rear, val, next_tx_front != val, 0,
+				 ACPM_TX_TIMEOUT_US);
+	if (ret)
+		dev_err(achan->acpm->dev, "TX queue is full.\n");
+
+	return ret;
+}
+
+/**
+ * acpm_prepare_xfer() - prepare a transfer before writing the message to the
+ * TX queue.
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer being prepared.
+ */
+static void acpm_prepare_xfer(struct acpm_chan *achan, struct acpm_xfer *xfer)
+{
+	struct acpm_msg *tx = &xfer->tx;
+	struct acpm_rx_data *rx_data;
+
+	/* Prevent chan->seqnum from being re-used */
+	do {
+		if (++achan->seqnum == ACPM_SEQNUM_MAX)
+			achan->seqnum = 1;
+	} while (test_bit(achan->seqnum - 1, achan->bitmap_seqnum));
+
+	tx->cmd[0] |= FIELD_PREP(ACPM_PROTOCOL_SEQNUM, achan->seqnum);
+
+	/* Clear data for upcoming responses */
+	rx_data = &achan->rx_data[achan->seqnum - 1];
+	memset(rx_data->cmd, 0, sizeof(*rx_data->cmd) * rx_data->n_cmd);
+	if (xfer->rx.cmd)
+		rx_data->response = true;
+
+	/* Flag the index based on seqnum. (seqnum: 1~63, bitmap: 0~62) */
+	set_bit(achan->seqnum - 1, achan->bitmap_seqnum);
+}
+
+/**
+ * acpm_wait_for_message_response - an helper to group all possible ways of
+ * waiting for a synchronous message response.
+ *
+ * @achan:	ACPM channel info.
+ * @xfer:	reference to the transfer being waited for.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_wait_for_message_response(struct acpm_chan *achan,
+					  struct acpm_xfer *xfer)
+{
+	/* Just polling mode supported for now. */
+	return acpm_dequeue_by_polling(achan, xfer);
+}
+
+/**
+ * acpm_do_xfer() - do one transfer.
+ * @handle:	pointer to the acpm handle.
+ * @xfer:	transfer to initiate and wait for response.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int acpm_do_xfer(const struct acpm_handle *handle, struct acpm_xfer *xfer)
+{
+	struct acpm_info *acpm = handle_to_acpm_info(handle);
+	struct acpm_chan *achan = &acpm->chans[xfer->acpm_chan_id];
+	struct acpm_msg *tx = &xfer->tx;
+	u32 idx, tx_front;
+	int ret;
+
+	if (!tx->cmd || tx->len > achan->mlen || xfer->rx.len > achan->mlen)
+		return -EINVAL;
+
+	if (!achan->poll_completion) {
+		dev_err(achan->acpm->dev, "Interrupt mode not supported\n");
+		return -EOPNOTSUPP;
+	}
+
+	mutex_lock(&achan->tx_lock);
+
+	tx_front = readl(achan->tx.front);
+	idx = (tx_front + 1) % achan->qlen;
+
+	ret = acpm_wait_for_queue_slots(achan, idx);
+	if (ret) {
+		mutex_unlock(&achan->tx_lock);
+		return ret;
+	}
+
+	acpm_prepare_xfer(achan, xfer);
+
+	/* Write TX command. */
+	acpm_memcpy_toio32(achan->tx.base + achan->mlen * tx_front, tx->cmd,
+			   tx->len);
+
+	/* Advance TX front. */
+	writel(idx, achan->tx.front);
+
+	mutex_unlock(&achan->tx_lock);
+
+	ret = mbox_send_message(achan->chan, xfer);
+	if (ret < 0)
+		return ret;
+
+	ret = acpm_wait_for_message_response(achan, xfer);
+
+	/*
+	 * NOTE: we might prefer not to need the mailbox ticker to manage the
+	 * transfer queueing since the protocol layer queues things by itself.
+	 * Unfortunately, we have to kick the mailbox framework after we have
+	 * received our message.
+	 */
+	mbox_client_txdone(achan->chan, ret);
+
+	return ret;
+}
+
+/**
+ * acpm_put_handle() - release the handle acquired by acpm_get_by_phandle.
+ * @handle:	Handle acquired by acpm_get_by_phandle.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_put_handle(const struct acpm_handle *handle)
+{
+	struct acpm_info *acpm;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	acpm = handle_to_acpm_info(handle);
+	mutex_lock(&acpm_list_mutex);
+	if (!WARN_ON(!acpm->users))
+		acpm->users--;
+	mutex_unlock(&acpm_list_mutex);
+
+	return 0;
+}
+
+/**
+ * devm_acpm_release() - devres release method.
+ * @dev: pointer to device.
+ * @res: pointer to resource.
+ */
+static void devm_acpm_release(struct device *dev, void *res)
+{
+	const struct acpm_handle **ptr = res;
+	const struct acpm_handle *handle = *ptr;
+	int ret;
+
+	ret = acpm_put_handle(handle);
+	if (ret)
+		dev_err(dev, "failed to put handle %d\n", ret);
+}
+
+/**
+ * acpm_get_by_phandle() - get the ACPM handle using DT phandle.
+ * @np:		device node.
+ * @property:	property name containing phandle on ACPM node.
+ *
+ * Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
+ */
+static const struct acpm_handle *acpm_get_by_phandle(struct device_node *np,
+						     const char *property)
+{
+	struct acpm_handle *handle = NULL;
+	struct device_node *acpm_np;
+	struct acpm_info *info;
+
+	if (!np) {
+		pr_err("I need a device pointer\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	acpm_np = of_parse_phandle(np, property, 0);
+	if (!acpm_np)
+		return ERR_PTR(-ENODEV);
+
+	mutex_lock(&acpm_list_mutex);
+	list_for_each_entry(info, &acpm_list, node) {
+		if (acpm_np == info->dev->of_node) {
+			handle = &info->handle;
+			info->users++;
+			break;
+		}
+	}
+	mutex_unlock(&acpm_list_mutex);
+	of_node_put(acpm_np);
+
+	if (!handle)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return handle;
+}
+
+/**
+ * devm_acpm_get_by_phandle() - managed get handle using phandle.
+ * @dev:	device pointer requesting ACPM handle.
+ * @property:	property name containing phandle on ACPM node.
+ *
+ * Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
+ */
+const struct acpm_handle *devm_acpm_get_by_phandle(struct device *dev,
+						   const char *property)
+{
+	const struct acpm_handle *handle;
+	const struct acpm_handle **ptr;
+
+	ptr = devres_alloc(devm_acpm_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+	handle = acpm_get_by_phandle(dev_of_node(dev), property);
+
+	if (!IS_ERR(handle)) {
+		*ptr = handle;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return handle;
+}
+
+/**
+ * acpm_chan_shmem_get_params() - get channel parameters and addresses of the
+ * TX/RX queues.
+ * @achan:	ACPM channel info.
+ * @chan_shmem:	__iomem pointer to a channel described in shared memory.
+ */
+static void acpm_chan_shmem_get_params(struct acpm_chan *achan,
+				struct acpm_chan_shmem __iomem *chan_shmem)
+{
+	void __iomem *base = achan->acpm->sram_base;
+	struct acpm_queue *rx = &achan->rx;
+	struct acpm_queue *tx = &achan->tx;
+
+	achan->mlen = readl(&chan_shmem->mlen);
+	achan->poll_completion = readl(&chan_shmem->poll_completion);
+	achan->id = readl(&chan_shmem->id);
+	achan->qlen = readl(&chan_shmem->qlen);
+
+	tx->base = base + readl(&chan_shmem->rx_base);
+	tx->rear = base + readl(&chan_shmem->rx_rear);
+	tx->front = base + readl(&chan_shmem->rx_front);
+
+	rx->base = base + readl(&chan_shmem->tx_base);
+	rx->rear = base + readl(&chan_shmem->tx_rear);
+	rx->front = base + readl(&chan_shmem->tx_front);
+
+	dev_vdbg(achan->acpm->dev, "ID = %d poll = %d, mlen = %d, qlen = %d\n",
+		 achan->id, achan->poll_completion, achan->mlen, achan->qlen);
+}
+
+/**
+ * acpm_achan_alloc_cmds() - allocate buffers for retrieving data from the ACPM
+ * firmware.
+ * @achan:	ACPM channel info.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_achan_alloc_cmds(struct acpm_chan *achan)
+{
+	struct device *dev = achan->acpm->dev;
+	struct acpm_rx_data *rx_data;
+	size_t cmd_size, n_cmd;
+	int i;
+
+	if (achan->mlen == 0)
+		return 0;
+
+	cmd_size = sizeof(*(achan->rx_data[0].cmd));
+	n_cmd = DIV_ROUND_UP_ULL(achan->mlen, cmd_size);
+
+	for (i = 0; i < ACPM_SEQNUM_MAX; i++) {
+		rx_data = &achan->rx_data[i];
+		rx_data->n_cmd = n_cmd;
+		rx_data->cmd = devm_kcalloc(dev, n_cmd, cmd_size, GFP_KERNEL);
+		if (!rx_data->cmd)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * acpm_free_mbox_chans() - free mailbox channels.
+ * @acpm:	pointer to driver data.
+ */
+static void acpm_free_mbox_chans(struct acpm_info *acpm)
+{
+	int i;
+
+	for (i = 0; i < acpm->num_chans; i++)
+		if (!IS_ERR_OR_NULL(acpm->chans[i].chan))
+			mbox_free_channel(acpm->chans[i].chan);
+}
+
+/**
+ * acpm_channels_init() - initialize channels based on the configuration data in
+ * the shared memory.
+ * @acpm:	pointer to driver data.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int acpm_channels_init(struct acpm_info *acpm)
+{
+	struct acpm_shmem __iomem *shmem = acpm->shmem;
+	struct acpm_chan_shmem __iomem *chans_shmem;
+	struct device *dev = acpm->dev;
+	int i, ret;
+
+	acpm->num_chans = readl(&shmem->num_chans);
+	acpm->chans = devm_kcalloc(dev, acpm->num_chans, sizeof(*acpm->chans),
+				   GFP_KERNEL);
+	if (!acpm->chans)
+		return -ENOMEM;
+
+	chans_shmem = acpm->sram_base + readl(&shmem->chans);
+
+	for (i = 0; i < acpm->num_chans; i++) {
+		struct acpm_chan_shmem __iomem *chan_shmem = &chans_shmem[i];
+		struct acpm_chan *achan = &acpm->chans[i];
+		struct mbox_client *cl = &achan->cl;
+		struct mbox_xlate_args spec;
+
+		achan->acpm = acpm;
+
+		acpm_chan_shmem_get_params(achan, chan_shmem);
+
+		ret = acpm_achan_alloc_cmds(achan);
+		if (ret)
+			return ret;
+
+		mutex_init(&achan->rx_lock);
+		mutex_init(&achan->tx_lock);
+
+		cl->dev = dev;
+
+		spec.args[0] = achan->id;
+		spec.args[1] = 0; /* DOORBELL */
+		spec.args_count = 2;
+
+		achan->chan = mbox_request_channel_by_args(cl, 0, &spec);
+		if (IS_ERR(achan->chan)) {
+			acpm_free_mbox_chans(acpm);
+			return PTR_ERR(achan->chan);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * acpm_setup_ops() - setup the operations structures.
+ * @acpm:	pointer to the driver data.
+ */
+static void acpm_setup_ops(struct acpm_info *acpm)
+{
+	struct acpm_pmic_ops *pmic_ops = &acpm->handle.ops.pmic_ops;
+
+	pmic_ops->read_reg = acpm_pmic_read_reg;
+	pmic_ops->bulk_read = acpm_pmic_bulk_read;
+	pmic_ops->write_reg = acpm_pmic_write_reg;
+	pmic_ops->bulk_write = acpm_pmic_bulk_write;
+	pmic_ops->update_reg = acpm_pmic_update_reg;
+}
+
+static int acpm_probe(struct platform_device *pdev)
+{
+	const struct acpm_match_data *match_data;
+	struct device *dev = &pdev->dev;
+	struct device_node *shmem;
+	struct acpm_info *acpm;
+	resource_size_t size;
+	struct resource res;
+	int ret;
+
+	acpm = devm_kzalloc(dev, sizeof(*acpm), GFP_KERNEL);
+	if (!acpm)
+		return -ENOMEM;
+
+	shmem = of_parse_phandle(dev->of_node, "shmem", 0);
+	ret = of_address_to_resource(shmem, 0, &res);
+	of_node_put(shmem);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get shared memory.\n");
+
+	size = resource_size(&res);
+	acpm->sram_base = devm_ioremap(dev, res.start, size);
+	if (!acpm->sram_base)
+		return dev_err_probe(dev, -ENOMEM,
+				     "Failed to ioremap shared memory.\n");
+
+	match_data = of_device_get_match_data(dev);
+	if (!match_data)
+		return dev_err_probe(dev, -EINVAL,
+				     "Faile to get match data.\n");
+
+	acpm->shmem = acpm->sram_base + match_data->initdata_base;
+	acpm->dev = dev;
+
+	ret = acpm_channels_init(acpm);
+	if (ret)
+		return ret;
+
+	acpm_setup_ops(acpm);
+
+	INIT_LIST_HEAD(&acpm->node);
+	mutex_lock(&acpm_list_mutex);
+	list_add_tail(&acpm->node, &acpm_list);
+	mutex_unlock(&acpm_list_mutex);
+
+	platform_set_drvdata(pdev, acpm);
+
+	return 0;
+}
+
+static const struct acpm_match_data acpm_gs101 = {
+	.initdata_base = ACPM_GS101_INITDATA_BASE,
+};
+
+static const struct of_device_id acpm_match[] = {
+	{
+		.compatible = "google,gs101-acpm-ipc",
+		.data = &acpm_gs101,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, acpm_match);
+
+static struct platform_driver acpm_driver = {
+	.probe	= acpm_probe,
+	.driver	= {
+		.name = "exynos-acpm-protocol",
+		.of_match_table	= acpm_match,
+	},
+};
+module_platform_driver(acpm_driver);
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus at linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos ACPM mailbox protocol driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h
new file mode 100644
index 000000000000..a03adcd260f5
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+#ifndef __EXYNOS_ACPM_H__
+#define __EXYNOS_ACPM_H__
+
+struct acpm_handle;
+struct acpm_xfer;
+
+int acpm_do_xfer(const struct acpm_handle *handle, struct acpm_xfer *xfer);
+
+#endif /* __EXYNOS_ACPM_H__ */
diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h
new file mode 100644
index 000000000000..f834af20cef8
--- /dev/null
+++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2024 Linaro Ltd.
+ */
+
+#ifndef __EXYNOS_ACPM_PROTOCOL_H
+#define __EXYNOS_ACPM_PROTOCOL_H
+
+#include <linux/types.h>
+
+struct acpm_msg {
+	u32 *cmd;
+	size_t len;
+};
+
+struct acpm_xfer {
+	struct acpm_msg tx;
+	struct acpm_msg rx;
+	int acpm_chan_id;
+};
+
+struct acpm_handle;
+
+struct acpm_pmic_ops {
+	int (*read_reg)(const struct acpm_handle *handle, int acpm_chan_id,
+			u8 type, u8 reg, u8 chan, u8 *dest);
+	int (*bulk_read)(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+	int (*write_reg)(const struct acpm_handle *handle, int acpm_chan_id,
+			 u8 type, u8 reg, u8 chan, u8 value);
+	int (*bulk_write)(const struct acpm_handle *handle, int acpm_chan_id,
+			  u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+	int (*update_reg)(const struct acpm_handle *handle, int acpm_chan_id,
+			  u8 type, u8 reg, u8 chan, u8 value, u8 mask);
+};
+
+struct acpm_ops {
+	struct acpm_pmic_ops pmic_ops;
+};
+
+/**
+ * struct acpm_handle - Reference to an initialized protocol instance
+ * @ops:
+ */
+struct acpm_handle {
+	struct acpm_ops ops;
+};
+
+struct device;
+
+const struct acpm_handle *devm_acpm_get_by_phandle(struct device *dev,
+						   const char *property);
+#endif /* __EXYNOS_ACPM_PROTOCOL_H */

-- 
2.47.1.613.gc27f4b7a9f-goog



From zhengqi.arch at bytedance.com  Fri Dec 20 06:35:23 2024
From: zhengqi.arch at bytedance.com (Qi Zheng)
Date: Fri, 20 Dec 2024 22:35:23 +0800
Subject: [PATCH 01/10] mm: Move common parts of pagetable_*_[cd]tor to
 helpers
In-Reply-To: <7f5e6ac7-01ef-46c8-bc85-7f8399dadb19@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <20241219164425.2277022-2-kevin.brodsky@arm.com>
 <20241219171920.GB26279@noisy.programming.kicks-ass.net>
 <75cb4ff8-eb0c-4519-a30a-f8be717ba278@arm.com>
 <0daabd32-cba4-4345-baa8-e8c66bc899ff@bytedance.com>
 <2f65f93e-9d44-4acc-b63c-8f5a35f59699@arm.com>
 <33ce9b58-4787-49cd-a7f2-34272cb3ecf7@bytedance.com>
 <7f5e6ac7-01ef-46c8-bc85-7f8399dadb19@arm.com>
Message-ID: <0725252d-1339-4841-bc1d-6cf9e82b2170@bytedance.com>



On 2024/12/20 22:28, Kevin Brodsky wrote:
> On 20/12/2024 15:16, Qi Zheng wrote:
>>>>
>>>> Did I miss something?
>>>>
>>>> My patch series is not only for cleanup, but also for fixes of
>>>> UAF issue [1], so is it possible to rebase your patch series onto
>>>> mine? I can post v3 ASAP.
>>>
>>> I see, yours should be merged first then. The issue is that yours would
>>> depend on some of the patches in mine, not the other way round.
>>>
>>> My suggestion would then be for you to take patch 5, 6 and 7 from my
>>> series, as they match Alexander's suggestions (and patch 5 is I think a
>>> useful simplification), and replace patch 2 in your series with those. I
>>> would then rebase my series on top and adapt it accordingly. Does that
>>> sound reasonable?
>>
>> Sounds good. But maybe just patch 5 and 6. Because I actually did
>> the work of your patch 7 in my patch 2 and 4.
> 
> Yes that's fair! You'd have to do adapt my patch 7 to make it fit in
> your series so I agree it makes more sense this way.

Thanks!

> 
>>
>> So, is it okay to do something like the following?
>>
>> 1. I separate the ctor()/dtor() part from my patch 2, and then replace
>>  ?? the rest with your patch 6.
>> 2. take your patch 5 form your series
> 
> Sounds good to me!
> 
> IIUC Dave Hansen gave his Acked-by for the x86 part of patch 6 [1],
> would make sense to add it when you post your v3.

OK, will add it!

> 
>>
>> If it's ok, I will post the v3 next Monday. ;)
> 
> Perfect. I'm going offline tonight, when I come back in the new year
> I'll review your v3 series and post a new version of this one.

Thank you very much! And Happy New Year!

> 
> Cheers,
> - Kevin
> 
> [1]
> https://lore.kernel.org/linux-mm/a7398426-56d1-40b4-a1c9-40ae8c8a4b4b at intel.com/


From lkp at intel.com  Fri Dec 20 06:38:53 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 20 Dec 2024 22:38:53 +0800
Subject: [PATCH v4 5/6] optee: FF-A: dynamic restricted memory allocation
In-Reply-To: <20241217100809.3962439-6-jens.wiklander@linaro.org>
References: <20241217100809.3962439-6-jens.wiklander@linaro.org>
Message-ID: <202412202214.OdgzpOke-lkp@intel.com>

Hi Jens,

kernel test robot noticed the following build errors:

[auto build test ERROR on fac04efc5c793dccbd07e2d59af9f90b7fc0dca4]

url:    https://github.com/intel-lab-lkp/linux/commits/Jens-Wiklander/tee-add-restricted-memory-allocation/20241217-181101
base:   fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
patch link:    https://lore.kernel.org/r/20241217100809.3962439-6-jens.wiklander%40linaro.org
patch subject: [PATCH v4 5/6] optee: FF-A: dynamic restricted memory allocation
config: arm64-randconfig-002-20241220 (https://download.01.org/0day-ci/archive/20241220/202412202214.OdgzpOke-lkp at intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241220/202412202214.OdgzpOke-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/202412202214.OdgzpOke-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/tee/optee/rstmem.c:8:
   In file included from include/linux/dma-map-ops.h:9:
   In file included from include/linux/dma-mapping.h:8:
   In file included from include/linux/scatterlist.h:8:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
>> drivers/tee/optee/rstmem.c:311:67: error: expected ')'
     311 | static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee __unused,
         |                                                                   ^
   drivers/tee/optee/rstmem.c:311:46: note: to match this '('
     311 | static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee __unused,
         |                                              ^
>> drivers/tee/optee/rstmem.c:332:35: error: too many arguments to function call, expected single argument 'optee', have 2 arguments
     332 |                 pool = alloc_rstmem_pool(optee, use_case);
         |                        ~~~~~~~~~~~~~~~~~        ^~~~~~~~
   drivers/tee/optee/rstmem.c:311:29: note: 'alloc_rstmem_pool' declared here
     311 | static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee __unused,
         |                             ^                 ~~~~~~~~~~~~~~~~~~~
   1 warning and 2 errors generated.


vim +311 drivers/tee/optee/rstmem.c

   268	
   269	static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee, u32 use_case)
   270	{
   271		struct optee_rstmem_cma_pool *rp;
   272		size_t min_size;
   273		int rc;
   274	
   275		rp = kzalloc(sizeof(*rp), GFP_KERNEL);
   276		if (!rp)
   277			return ERR_PTR(-ENOMEM);
   278		rp->rstmem.use_case = use_case;
   279	
   280		rc = get_rstmem_config(optee, use_case, &min_size, &rp->align, NULL,
   281				       &rp->end_point_count);
   282		if (rc) {
   283			if (rc != -ENOSPC)
   284				goto err;
   285			rp->end_points = kcalloc(rp->end_point_count,
   286						 sizeof(*rp->end_points), GFP_KERNEL);
   287			if (!rp->end_points) {
   288				rc = -ENOMEM;
   289				goto err;
   290			}
   291			rc = get_rstmem_config(optee, use_case, &min_size, &rp->align,
   292					       rp->end_points, &rp->end_point_count);
   293			if (rc)
   294				goto err_kfree_eps;
   295		}
   296	
   297		rp->pool.ops = &rstmem_pool_ops_cma;
   298		rp->optee = optee;
   299		rp->page_count = min_size / PAGE_SIZE;
   300		mutex_init(&rp->mutex);
   301	
   302		return &rp->pool;
   303	
   304	err_kfree_eps:
   305		kfree(rp->end_points);
   306	err:
   307		kfree(rp);
   308		return ERR_PTR(rc);
   309	}
   310	#else /*CONFIG_CMA*/
 > 311	static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee __unused,
   312						      u32 use_case __unused)
   313	{
   314		return ERR_PTR(-EINVAL);
   315	}
   316	#endif /*CONFIG_CMA*/
   317	
   318	int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
   319			       u32 flags, u32 use_case, size_t size)
   320	{
   321		struct optee *optee = tee_get_drvdata(ctx->teedev);
   322		struct tee_shm_pool *pool;
   323		int rc;
   324	
   325		if (!optee->rstmem_pools)
   326			return -EINVAL;
   327		if (flags)
   328			return -EINVAL;
   329	
   330		pool = xa_load(&optee->rstmem_pools->xa, use_case);
   331		if (!pool) {
 > 332			pool = alloc_rstmem_pool(optee, use_case);
   333			if (IS_ERR(pool))
   334				return PTR_ERR(pool);
   335			rc = xa_insert(&optee->rstmem_pools->xa, use_case, pool,
   336				       GFP_KERNEL);
   337			if (rc) {
   338				pool->ops->destroy_pool(pool);
   339				return rc;
   340			}
   341		}
   342	
   343		return pool->ops->alloc(pool, shm, size, 0);
   344	}
   345	

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


From andre.draszik at linaro.org  Fri Dec 20 06:42:49 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Fri, 20 Dec 2024 14:42:49 +0000
Subject: [PATCH v2 0/3] Google Pixel 6 Pro support
In-Reply-To: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
References: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
Message-ID: <21d1605c49d7d6a0f7f0f532d99cd7d285bd2958.camel@linaro.org>

On Fri, 2024-12-20 at 11:27 +0000, Andr? Draszik wrote:
> Hi,
> 
> This series enables support for Google Pixel 6 Pro.
> 
> Since Pixel 6 and Pixel 6 Pro use a different resolution display, we
> now need to add explicit support for it, we can not piggyback on the
> non-Pro version anymore. This means having to separate them into their
> respective DTs, and provide one for each of them.
> There are other differences between the two of course, like battery
> design capacity, etc., but they don't matter at this stage due to
> incomplete upstream support.
> 
> * dependency note *
> 
> Due to the renaming of the gs101-oriole.dts, this series will conflict
> with any pending patches touching the same file. I have therefore based
> this series on top of my USB series from
> https://lore.kernel.org/r/20241203-gs101-phy-lanes-orientation-dts-v2-0-1412783a6b01 at linaro.org
> and the patch enabling framebuffer support for Pixel 6 from
> https://lore.kernel.org/r/20241220-gs101-simplefb-oriole-v2-1-df60e566932a at linaro.org

Actually, since this series was regenerated with git's
diff.renames=copies, it doesn't depend on my USB series
anymore, just on the framebuffer enablement for Pixel 6.

Cheers,
Andre'



From tudor.ambarus at linaro.org  Fri Dec 20 06:45:46 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 14:45:46 +0000
Subject: [PATCH v3 3/4] arm64: dts: exynos: gs101: add ACPM protocol node
In-Reply-To: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>
References: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>
Message-ID: <20241220-gs101-acpm-dt-v3-3-642d64daa5d1@linaro.org>

Add the ACPM protocol node. ACPM protocol provides interface for all
the client drivers making use of the features offered by the
Active Power Management (APM) module.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 6947dd081a0e..681ea775ba54 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -277,6 +277,14 @@ apm_sram: sram at 2039000 {
 		ranges = <0x0 0x0 0x2039000 0x40000>;
 	};
 
+	firmware {
+		acpm_ipc: power-management {
+			compatible = "google,gs101-acpm-ipc";
+			mboxes = <&ap2apm_mailbox>;
+			shmem = <&apm_sram>;
+		};
+	};
+
 	soc: soc at 0 {
 		compatible = "simple-bus";
 		#address-cells = <1>;

-- 
2.47.1.613.gc27f4b7a9f-goog



From dave.hansen at intel.com  Fri Dec 20 06:45:55 2024
From: dave.hansen at intel.com (Dave Hansen)
Date: Fri, 20 Dec 2024 06:45:55 -0800
Subject: [PATCH 00/10] Account page tables at all levels
In-Reply-To: <765aec36-55a4-4161-bb30-4ff838bc2d98@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <a7398426-56d1-40b4-a1c9-40ae8c8a4b4b@intel.com>
 <765aec36-55a4-4161-bb30-4ff838bc2d98@arm.com>
Message-ID: <719c5aa7-63ad-43f1-a2e8-644ef220db4f@intel.com>

On 12/20/24 02:58, Kevin Brodsky wrote:
>> Acked-by: Dave Hansen <dave.hansen at linux.intel.com>
> Just to double-check, are your ack'ing the x86 changes specifically? If
> so I'll add your Acked-by on patch 6, 7 and 9.

Feel free to add it to each patch in the series.


From tudor.ambarus at linaro.org  Fri Dec 20 06:45:43 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 14:45:43 +0000
Subject: [PATCH v3 0/4] arm64: exynos: gs101: add ACPM related nodes
Message-ID: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>

Define SRAM, mailbox and ACPM protocol in device tree.
Enable the mailbox and ACPM protocol in defconfig.

Changes in v3:
- ACPM: don't specify the channel ID and type in DT: the channel ID is
  discovered at runtime and the channel type is always DOORBELL for the
  ACPM interface.
- mbox: update #mbox-cells = <0>;
- rebase on top of v6.13-rc3
- Link to v2: https://lore.kernel.org/r/20241212-b4-acpm-v4-upstream-dts-v2-0-91b7a6f6d0b0 at linaro.org

Changes in v2:
- update nodes based on the bindings updates
- update mailbox and power-management (mailbox client) nodes to specify
  channel type (doorbell or data) and channel ID.

v1:
Link: https://lore.kernel.org/linux-arm-kernel/20241205180200.203146-1-tudor.ambarus at linaro.org/

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Tudor Ambarus (4):
      arm64: dts: exynos: gs101: add SRAM node
      arm64: dts: exynos: gs101: add AP to APM mailbox node
      arm64: dts: exynos: gs101: add ACPM protocol node
      arm64: defconfig: enable ACPM protocol and Exynos mailbox

 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 25 +++++++++++++++++++++++++
 arch/arm64/configs/defconfig                 |  2 ++
 2 files changed, 27 insertions(+)
---
base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
change-id: 20241220-gs101-acpm-dt-6dcde166530a

Best regards,
-- 
Tudor Ambarus <tudor.ambarus at linaro.org>



From tudor.ambarus at linaro.org  Fri Dec 20 06:45:44 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 14:45:44 +0000
Subject: [PATCH v3 1/4] arm64: dts: exynos: gs101: add SRAM node
In-Reply-To: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>
References: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>
Message-ID: <20241220-gs101-acpm-dt-v3-1-642d64daa5d1@linaro.org>

SRAM is used by the ACPM protocol to retrieve the ACPM channels
information, which includes the TX/RX rings among other channel
configuration data. Add the SRAM node.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 302c5beb224a..1441e9a252c2 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -269,6 +269,14 @@ bldr_log_hist_reserved: bldr-log-hist-reserved at fd900000 {
 		};
 	};
 
+	apm_sram: sram at 2039000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0x2039000 0x40000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x2039000 0x40000>;
+	};
+
 	soc: soc at 0 {
 		compatible = "simple-bus";
 		#address-cells = <1>;

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Fri Dec 20 06:45:45 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 14:45:45 +0000
Subject: [PATCH v3 2/4] arm64: dts: exynos: gs101: add AP to APM mailbox
 node
In-Reply-To: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>
References: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>
Message-ID: <20241220-gs101-acpm-dt-v3-2-642d64daa5d1@linaro.org>

GS101 has 14 mailbox controllers. Add the AP to APM mailbox node.

Mailbox controllers have a shared register that can be used for passing
the mailbox messages. The AP to APM mailbox controller is used just as a
doorbell mechanism. It raises interrupt to the firmware after the mailbox
message has been written to SRAM where the TX/RX rings are defined.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index 1441e9a252c2..6947dd081a0e 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -1445,6 +1445,15 @@ wakeup-interrupt-controller {
 			};
 		};
 
+		ap2apm_mailbox: mailbox at 17610000 {
+			compatible = "google,gs101-mbox";
+			reg = <0x17610000 0x1000>;
+			clocks = <&cmu_apm CLK_GOUT_APM_MAILBOX_APM_AP_PCLK>;
+			clock-names = "pclk";
+			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <0>;
+		};
+
 		pinctrl_gsactrl: pinctrl at 17940000 {
 			compatible = "google,gs101-pinctrl";
 			reg = <0x17940000 0x00001000>;

-- 
2.47.1.613.gc27f4b7a9f-goog



From tudor.ambarus at linaro.org  Fri Dec 20 06:45:47 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 20 Dec 2024 14:45:47 +0000
Subject: [PATCH v3 4/4] arm64: defconfig: enable ACPM protocol and Exynos
 mailbox
In-Reply-To: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>
References: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>
Message-ID: <20241220-gs101-acpm-dt-v3-4-642d64daa5d1@linaro.org>

Enable the Samsung Exynos ACPM protocol and its transport layer, the
Exynos mailbox driver. Samsung Exynos platforms implement ACPM to
provide support for PMIC, clock frequency scaling, clock configuration
and temperature sensors.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c62831e61586..91139b1cf813 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -262,6 +262,7 @@ CONFIG_IMX_SCU=y
 CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
 CONFIG_QCOM_QSEECOM=y
 CONFIG_QCOM_QSEECOM_UEFISECAPP=y
+CONFIG_EXYNOS_ACPM_PROTOCOL=m
 CONFIG_GNSS=m
 CONFIG_GNSS_MTK_SERIAL=m
 CONFIG_MTD=y
@@ -1378,6 +1379,7 @@ CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_TEGRA186_TIMER=y
 CONFIG_RENESAS_OSTM=y
 CONFIG_ARM_MHU=y
+CONFIG_EXYNOS_MBOX=m
 CONFIG_IMX_MBOX=y
 CONFIG_OMAP2PLUS_MBOX=m
 CONFIG_PLATFORM_MHU=y

-- 
2.47.1.613.gc27f4b7a9f-goog



From konrad.dybcio at oss.qualcomm.com  Fri Dec 20 06:57:48 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 20 Dec 2024 15:57:48 +0100
Subject: [PATCH 0/3] Allow specifying an S2RAM sleep on pre-SYSTEM_SUSPEND
 PSCI impls
In-Reply-To: <Z2WA0o0QJS64ftVh@bogus>
References: <20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com>
 <20241113165329590-0800.eberman@hu-eberman-lv.qualcomm.com>
 <e4509104-c809-4d45-bdbb-a2d754a816db@oss.qualcomm.com>
 <Z2VXgkJ4x5TJTKJ_@bogus>
 <765bb1c8-31de-4aec-b8ef-f141a3e25c56@oss.qualcomm.com>
 <Z2V4IblZNgnS4T2Z@bogus>
 <875342b7-3825-47bf-810a-effdbeacab46@oss.qualcomm.com>
 <Z2WA0o0QJS64ftVh@bogus>
Message-ID: <db755bda-8464-4882-a72b-1d860abcb2fe@oss.qualcomm.com>

On 20.12.2024 3:36 PM, Sudeep Holla wrote:
> On Fri, Dec 20, 2024 at 03:20:37PM +0100, Konrad Dybcio wrote:
>>
>> I would happen to think that, yes. Especially since the reference firmware
>> implementation does *exactly this*:
>>
>> https://github.com/ARM-software/arm-trusted-firmware/blob/master/lib/psci/psci_main.c#L179-L221
>>
>> PSCI_SYSTEM_SUSPEND seems to be simply meant as a wrapper around a specific
>> CPU_SUSPEND state (which may or may not be only callable from inside the
>> firmware when SYSTEM_SUSPEND specifically is requested, for reasons),
>> in a platform-agnostic way, so that the OS can enter suspend without
>> providing that magic StateID on all supported platforms.
> 
> Exactly, that's how it can be OS and platform agnostic. Yet this platform
> considered to optimise by not just providing it as a wrapper(if it was
> that simple on your platform too) without running any tests and leaving
> it to interested parties like you to mess around to get it working.
> That practice needs to be fixed and this change won't help and once we
> fix this, more such special treatment fixes are needed on newer platforms.
> So lets stop and ensure things are fixed properly.

And then remove CPU_SUSPEND support if CPU_SUSPEND2 comes in a spec update
because it's not generic enough? Sorry, this is not acceptable.

If you enforce PSCI as the only way of doing SMP/cpuidle/platform suspend
upstream on arm64, you should not gatekeep existing implementations that are
actually in line with the written spec, just because you don't happen to
like them.

If you want to start the process of getting rid of those, amend the spec
to deprecate and/or forbid system-level suspend in CPU_SUSPEND in future
PSCI versions. But you can't retroactively change your decisions like that.

>> But since it already requires more elbow grease on the peripheral IP side,
>> I'm not really convinced it's that much useful.
>>
>> Plus, the optional bit of doing more work behind the scenes doesn't seem
>> to be very wildly used across TF-A supported platforms.
>>
>> So please, stop making the argument that it's any different. The firmware
>> I'm dealing with simply didn't expose the same thing twice, in perfect
>> accordance with the spec.
>>
> 
> So that it can continue to do so in the future ?
> Thanks but no thanks. NACK with no arguments as requested.

That's already been "fixed" on QC platforms starting around 2022, as
mentioned in this series.

Konrad


From niharchaithanya at gmail.com  Fri Dec 20 06:57:02 2024
From: niharchaithanya at gmail.com (Nihar Chaithanya)
Date: Fri, 20 Dec 2024 20:27:02 +0530
Subject: [PATCH] perf: arm-spe: Fix null-ptr-deref in arm_spe__alloc_metadata()
Message-ID: <20241220145659.66066-1-niharchaithanya@gmail.com>

When metadata is allocated using arm_spe__alloc_metadata(), if the
metadata version is 1, metadata is returned as NULL. This value
is dereferenced later in arm_spe__free_metadata() and it can cause
null-ptr-deref.

Modify the NULL check for metadata to return -EINVAL even when
metadata_ver == 1.

This issue was reported by Coverity scan [1].
[1] https://scan5.scan.coverity.com/#/project-view/63616/10063?selectedIssue=1636359

Closes: https://scan5.scan.coverity.com/#/project-view/63616/10063?selectedIssue=1636359
Signed-off-by: Nihar Chaithanya <niharchaithanya at gmail.com>
---
 tools/perf/util/arm-spe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index dbf13f47879c..55827d8ce133 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -1497,7 +1497,7 @@ int arm_spe_process_auxtrace_info(union perf_event *event,
 
 	metadata = arm_spe__alloc_metadata(auxtrace_info, &metadata_ver,
 					   &nr_cpu);
-	if (!metadata && metadata_ver != 1) {
+	if (!metadata) {
 		pr_err("Failed to parse Arm SPE metadata.\n");
 		return -EINVAL;
 	}
-- 
2.34.1



From dave.stevenson at raspberrypi.com  Fri Dec 20 07:00:47 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 15:00:47 +0000
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <c7qyka3hsrggqevdwdlfcanzps3z63s4joryskijlbuztacmly@tadqjm2vkj24>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-vivacious-chameleon-of-swiftness-f1edc4@houat> <CAA8EJprjCyWBNkRrc4W24uCwPtf_kxZLqNeNP8EJffbutYQ21w@mail.gmail.com>
 <20241218-wild-red-manatee-bb2a34@houat> <CAPY8ntDdcOXuWVgx6+cbgX5ct_-MXcE7CWDKgGP57EX6bvBLaw@mail.gmail.com>
 <CAPY8ntAnJ1YDQee=pFSDY3+EXHj4_RZ-M1NMp2C3ZDdD5DsCKA@mail.gmail.com> <c7qyka3hsrggqevdwdlfcanzps3z63s4joryskijlbuztacmly@tadqjm2vkj24>
Message-ID: <CAPY8ntDUaFnvkjkqES4AkrzZ2z659h3w5MFSd8vW04Eh-iJ1FA@mail.gmail.com>

On Fri, 20 Dec 2024 at 00:45, Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Thu, Dec 19, 2024 at 04:16:37PM +0000, Dave Stevenson wrote:
> > On Wed, 18 Dec 2024 at 14:52, Dave Stevenson
> > <dave.stevenson at raspberrypi.com> wrote:
> > >
> > > Hi Maxime & Dmitry
> > >
> > > On Wed, 18 Dec 2024 at 07:59, Maxime Ripard <mripard at kernel.org> wrote:
> > > >
> > > > On Wed, Dec 18, 2024 at 07:24:23AM +0200, Dmitry Baryshkov wrote:
> > > > > On Tue, 17 Dec 2024 at 19:21, Maxime Ripard <mripard at kernel.org> wrote:
> > > > > > On Tue, Dec 17, 2024 at 02:40:22AM +0200, Dmitry Baryshkov wrote:
> > > > > > > While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
> > > > > > > framework, I stumbled upon an issue while handling the Audio InfoFrames.
> > > > > > > The HDMI codec callbacks weren't receiving the drm_atomic_state, so
> > > > > > > there was no simple way to get the drm_connector that stayed at the end
> > > > > > > of the bridge chain. At the same point the drm_hdmi_connector functions
> > > > > > > expected to get drm_connector instance.
> > > > > > >
> > > > > > > While looking for a way to solve the issue, I stumbled upon several
> > > > > > > deficiencies in existing hdmi_codec_ops implementations. Only few of the
> > > > > > > implementations were able to handle codec's 'plugged' callback. One
> > > > > > > third of the drivers didn't implement the get_eld() callback.
> > > > > > >
> > > > > > > Most of the issues can be solved if drm_connector handles
> > > > > > > hdmi-audio-codec on its own, delegating functionality to the actual
> > > > > > > implementation, be it a driver that implements drm_connector or
> > > > > > > drm_bridge.
> > > > > > >
> > > > > > > Implement such high-level framework, adding proper support for Audio
> > > > > > > InfoFrame generation to the LT9611 driver.
> > > > > > >
> > > > > > > Several design decisions to be kept in mind:
> > > > > > >
> > > > > > > - drm_connector_hdmi_codec is kept as simple as possible. It implements
> > > > > > >   generic functionality (ELD, hotplug, registration).
> > > > > > >
> > > > > > > - drm_hdmi_connector sets up HDMI codec device if the connector
> > > > > > >   is setup correspondingly (either I2S or S/PDIF is marked as
> > > > > > >   supported).
> > > > > > >
> > > > > > > - drm_bridge_connector provides a way to link HDMI audio codec
> > > > > > >   funcionality in the drm_bridge with the drm_connector_hdmi_codec
> > > > > > >   framework.
> > > > > > >
> > > > > > > - It might be worth reverting the no_i2s_capture / no_spdif_capture
> > > > > > >   bits. Only TDA889x driver sets them, while it's safe to assume that
> > > > > > >   most of HDMI / DP devices do not support ARC / capture. I think the
> > > > > > >   drivers should opt-in capture support rather than having to opt-out of
> > > > > > >   it.
> > > > > >
> > > > > > Sorry if this isn't clear to me and I'm quite late to the party, but did
> > > > > > you test this on vc4 with both a pi3 and pi4, or was it just compile
> > > > > > tested?
> > > > >
> > > > > LT9611 is actually tested, VC4 is only compile-tested. Should I put an RFT tag?
> > > >
> > > > Yeah, we definitely need to test it on the pi3 (polling-based) and the
> > > > pi4 (irq-based) at least.
> > > >
> > > > Dave, Maira, could you give it a try?
> > >
> > > I'm on it.
> >
> > Basic checks look OK.
> > Pi3 and Pi4 tested, including 4k60 on Pi4 (enables scrambling). Audio
> > works, and all the EDID parsing seems to be correct.
> >
> > Ideally I would like to do a couple more tests though as I had a
> > couple of spontaneous reboots on Pi4 whilst hotplugging.
> > Most likely it was just grounding issues, as I can't think of an
> > obvious way for the kernel to be triggering an automatic reboot. They
> > seemed to go away when I had enabled drm.debug=0x14, but more likely
> > I'd connected the serial port and therefore provided another ground.
> > Please don't hold the patches waiting on me though - I don't know when
> > I'll have time to do them.
>
> Tested-by?

I'd held off hoping to get the extra testing done today, but that
hasn't happened, and today is my last day before the Christmas break.
So based on what I've done so far:

Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>

> >
> >
> > Also unrelated to this patch set, I have noted I'm getting
> > [   60.780897] WARNING: CPU: 3 PID: 501 at
> > drivers/gpu/drm/vc4/vc4_hvs.c:743 __vc4_hvs_stop_channel+0x148/0x164
> > [vc4]
> > ...
> > [   60.781192]  __vc4_hvs_stop_channel+0x148/0x164 [vc4] (P)
> > [   60.781212]  __vc4_hvs_stop_channel+0x40/0x164 [vc4] (L)
> > [   60.781230]  vc4_hvs_stop_channel+0x30/0x3c [vc4]
> > [   60.781248]  vc4_crtc_disable+0x140/0x1e8 [vc4]
> > [   60.781266]  vc4_crtc_atomic_disable+0x98/0xb8 [vc4]
> > [   60.781284]  disable_outputs+0x22c/0x33c [drm_kms_helper]
> > [   60.781326]  drm_atomic_helper_commit_modeset_disables+0x1c/0x4c
> > [drm_kms_helper]
> > [   60.781347]  vc4_atomic_commit_tail+0x10c/0x8e4 [vc4]
> > [   60.781364]  commit_tail+0xa0/0x188 [drm_kms_helper]
> > [   60.781385]  drm_atomic_helper_commit+0x16c/0x180 [drm_kms_helper]
> > [   60.781406]  drm_atomic_commit+0x88/0xc4 [drm]
> > [   60.781500]  drm_client_modeset_commit_atomic+0x204/0x264 [drm]
> > [   60.781553]  drm_client_modeset_commit_locked+0x5c/0x198 [drm]
> > [   60.781603]  drm_client_modeset_commit+0x30/0x58 [drm]
> > [   60.781652]  __drm_fb_helper_restore_fbdev_mode_unlocked+0xb4/0xe8
> > [drm_kms_helper]
> > [   60.781674]  drm_fb_helper_hotplug_event+0x108/0x12c [drm_kms_helper]
> > [   60.781695]  drm_fbdev_client_hotplug+0x28/0xd4 [drm_client_lib]
> > [   60.781700]  drm_client_dev_hotplug+0xc8/0x12c [drm]
> > [   60.781750]  drm_connector_helper_hpd_irq_event+0x70/0xb0 [drm_kms_helper]
> > [   60.781771]  vc4_hdmi_hpd_irq_thread+0x2c/0x3c [vc4]
> > [   60.781790]  irq_thread_fn+0x2c/0xa8
> > [   60.781799]  irq_thread+0x16c/0x2f4
> > [   60.781805]  kthread+0x118/0x11c
> > [   60.781813]  ret_from_fork+0x10/0x20
> > On first plugging or unplugging a second monitor. I suspect that is
> > spurious though and I'll look into it, but probably not this side of
> > the Christmas break.
> >
> >   Dave
>
> --
> With best wishes
> Dmitry


From cohuck at redhat.com  Fri Dec 20 07:00:57 2024
From: cohuck at redhat.com (Cornelia Huck)
Date: Fri, 20 Dec 2024 16:00:57 +0100
Subject: [PATCH v4 3/3] arm64: paravirt: Enable errata based on
 implementation CPUs
In-Reply-To: <86v7veppsj.wl-maz@kernel.org>
References: <20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com>
 <20241218105345.73472-4-shameerali.kolothum.thodi@huawei.com>
 <86bjx8q995.wl-maz@kernel.org> <Z2RapzikZQGgeE_6@linux.dev>
 <86v7veppsj.wl-maz@kernel.org>
Message-ID: <87ikrebdqu.fsf@redhat.com>

On Fri, Dec 20 2024, Marc Zyngier <maz at kernel.org> wrote:

> On Thu, 19 Dec 2024 17:40:55 +0000,
> Oliver Upton <oliver.upton at linux.dev> wrote:
>> 
>> > Independent of this, I wonder what we should output in sysfs
>> > (/sys/devices/system/cpu/cpu*/regs/identification/*).
>> 
>> It's a bit crap, but maybe implementation index 0 gets reported through
>> the 'main' midr/revidr files, otherwise have a directory per
>> implementation index of midr/revidr.
>
> Having slept on that one, I'm starting to think that we should keep
> the status-quo of reporting what the kernel snapshot at boot time.
> There is no good reason to force the VMM to report the potential
> implementations in any specific order.
>
> The "alternative-implementations" is interesting, but we don't keep it
> per-CPU, so I don't  think it fits the current scheme. But maybe
> something in /sys/devices/system/cpu, outside of the cpu* hierarchy?

I agree that this should be reported outside of the cpu* hierarchy,
maybe smth like

/sys/devices/system/cpu/alternatives/
   identification/
     regs0/
       aidr_el1
       midr_el1
       revidr_el1
     regs1/
       aidr_el1
       midr_el1
       revidr_el1

(with no guarantee as to _which_ triplet will show up under regs<n>)

Also depends on the intended consumers, I guess.

>
> Either way, this isn't something we should worry too much right now.

I agree as well.



From didi.debian at cknow.org  Fri Dec 20 07:08:54 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Fri, 20 Dec 2024 16:08:54 +0100
Subject: [PATCH v2 5/7] dt-bindings: arm: rockchip: Sort for rk3568 evb
In-Reply-To: <20241220101551.3505917-6-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
 <20241220101551.3505917-6-kever.yang@rock-chips.com>
Message-ID: <D6GMFFSALGMQ.3GQ1PUD6L2TV8@cknow.org>

Hi Kever,

On Fri Dec 20, 2024 at 11:15 AM CET, Kever Yang wrote:
> The info for rk3568 should before rk3588.

Indeed, so thanks for this patch.

> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> ---
>
> Changes in v2:
> - collect acked-by tag
>
>  .../devicetree/bindings/arm/rockchip.yaml     | 20 +++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
> index 753199a12923..45ee4bf7c80c 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> @@ -1006,6 +1006,16 @@ properties:
>            - const: rockchip,rk3399-sapphire-excavator
>            - const: rockchip,rk3399
>  
> +      - description: Rockchip RK3566 BOX Evaluation Demo board
> +        items:
> +          - const: rockchip,rk3566-box-demo
> +          - const: rockchip,rk3566
> +
> +      - description: Rockchip RK3568 Evaluation board
> +        items:
> +          - const: rockchip,rk3568-evb1-v10
> +          - const: rockchip,rk3568
> +
>        - description: Rockchip RK3588 Evaluation board
>          items:
>            - const: rockchip,rk3588-evb1-v10
> @@ -1099,16 +1109,6 @@ properties:
>            - const: zkmagic,a95x-z2
>            - const: rockchip,rk3318
>  
> -      - description: Rockchip RK3566 BOX Evaluation Demo board
> -        items:
> -          - const: rockchip,rk3566-box-demo
> -          - const: rockchip,rk3566
> -
> -      - description: Rockchip RK3568 Evaluation board
> -        items:
> -          - const: rockchip,rk3568-evb1-v10
> -          - const: rockchip,rk3568
> -

While you're fixing the sorting order of these 2 Rockchip items, it
would be great if "Sinovoip RK3308 Banana Pi P2 Pro", "Sinovoip RK3568
Banana Pi R2 Pro" and "Sonoff iHost Smart Home Hub" could also be moved
into their correctly sorted position. A quick scan seems to indicate
that all the other items are properly sorted.

Cheers,
  Diederik

>        - description: Sinovoip RK3308 Banana Pi P2 Pro
>          items:
>            - const: sinovoip,rk3308-bpi-p2pro

-------------- 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/20241220/06901c48/attachment.sig>

From qperret at google.com  Fri Dec 20 07:14:36 2024
From: qperret at google.com (Quentin Perret)
Date: Fri, 20 Dec 2024 15:14:36 +0000
Subject: [PATCH] KVM: arm64: Selftest for pKVM transitions
In-Reply-To: <20241220141321.GA26794@willie-the-truck>
References: <20241129125800.992468-1-qperret@google.com>
 <20241220141321.GA26794@willie-the-truck>
Message-ID: <Z2WJ3F0qiqvV3qTw@google.com>

On Friday 20 Dec 2024 at 14:13:22 (+0000), Will Deacon wrote:
> On Fri, Nov 29, 2024 at 12:58:00PM +0000, Quentin Perret wrote:
> > We have recently found a bug [1] in the pKVM memory ownership
> > transitions by code inspection, but it could have been caught with a
> > test.
> > 
> > Introduce a boot-time selftest exercising all the known pKVM memory
> > transitions and importantly checks the rejection of illegal transitions.
> 
> Thanks for doing this!
> 
> > 
> > The new test is hidden behind a new Kconfig option separate from
> > CONFIG_EL2_NVHE_DEBUG on purpose as that has side effects on the
> > transition checks ([1] doesn't reproduce with EL2 debug enabled).
> 
> Hmm. What does a test failure look like without CONFIG_EL2_NVHE_DEBUG
> enabled? Do we still get file:line information?

Nope, sadly we don't, but if you get a failure after turning on that
config then you can at least be confident there is a problem with your
code :-)

As discussed in the other thread, once we get the hyp state into the
vmemmap (I've got patches that do exactly that, happy to send them out)
we could just plain remove the 'skip_pgtable_check()' logic, and then
I'm not opposed to merging CONFIG_PKVM_SELFTESTS and CONFIG_EL2_NVHE_DEBUG
together as the latter won't have the same side effects.

> > +void pkvm_ownership_selftest(void)
> > +{
> > +	void *virt = hyp_alloc_pages(&host_s2_pool, 0);
> > +	u64 phys, size, pfn;
> > +
> > +	WARN_ON(!virt);
> > +	selftest_page = hyp_virt_to_page(virt);
> > +	selftest_page->refcount = 0;
> > +
> > +	size = PAGE_SIZE << selftest_page->order;
> > +	phys = hyp_virt_to_phys(virt);
> > +	pfn = hyp_phys_to_pfn(phys);
> > +
> > +	selftest_state.host = PKVM_NOPAGE;
> > +	selftest_state.hyp = PKVM_PAGE_OWNED;
> > +	assert_page_state();
> > +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> > +	assert_transition_res(-EPERM,	__pkvm_host_unshare_hyp, pfn);
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_host_unshare_ffa, pfn, 1);
> > +	assert_transition_res(-EPERM,	hyp_pin_shared_mem, virt, virt + size);
> > +
> > +	selftest_state.host = PKVM_PAGE_OWNED;
> > +	selftest_state.hyp = PKVM_NOPAGE;
> > +	assert_transition_res(0,	__pkvm_hyp_donate_host, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);
> > +	assert_transition_res(-EPERM,	hyp_pin_shared_mem, virt, virt + size);
> 
> Should we recheck the unshare transitions here?

Yep, sounds like a good idea.

> > +	selftest_state.host = PKVM_PAGE_SHARED_OWNED;
> > +	selftest_state.hyp = PKVM_PAGE_SHARED_BORROWED;
> > +	assert_transition_res(0,	__pkvm_host_share_hyp, pfn);
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> > +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);
> 
> We could check unshare_ffa here.

Sadly no, unshare_ffa() isn't super smart, it'll only check that a
page is SHARED_OWNED from the host's PoV and turn it to PAGE_OWNED. So
we'd break the state in this case :/

> > +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);
> > +
> > +	assert_transition_res(0,	hyp_pin_shared_mem, virt, virt + size);
> 
> Is it worth trying an extra pin + unpin?

You mean doing pin > pin > unpin > sanity checks > unpin ?

I guess that would test that we can indeed stack the pins, so sounds
like a good idea too.

> > +	WARN_ON(!hyp_page_count(virt));
> 
> Can we assert an exact value (e.g. count == 1)?

Sure.

> > +	assert_transition_res(-EBUSY,	__pkvm_host_unshare_hyp, pfn);
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> > +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);
> 
> unshare_ffa again here.

Same as above.

> > +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);
> > +
> > +	hyp_unpin_shared_mem(virt, virt + size);
> > +	assert_page_state();
> > +	WARN_ON(hyp_page_count(virt));
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> > +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);
> 
> Is this block actually testing anything new? Once we've asserted the page
> state and checked the refcount, the transitions seem redundant to me.

The idea was to check if the previous transitions had other sad effects
not visible through the <state, refcount> pair that would cause
problems. But I guess that is a bit far fetched so happy to remove that
part.

> > +	selftest_state.host = PKVM_PAGE_OWNED;
> > +	selftest_state.hyp = PKVM_NOPAGE;
> > +	assert_transition_res(0,	__pkvm_host_unshare_hyp, pfn);
> > +
> > +	selftest_state.host = PKVM_PAGE_SHARED_OWNED;
> > +	selftest_state.hyp = PKVM_NOPAGE;
> > +	assert_transition_res(0,	__pkvm_host_share_ffa, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_ffa, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_host_donate_hyp, pfn, 1);
> > +	assert_transition_res(-EPERM,	__pkvm_host_share_hyp, pfn);
> > +	assert_transition_res(-EPERM,	__pkvm_host_unshare_hyp, pfn);
> > +	assert_transition_res(-EPERM,	__pkvm_hyp_donate_host, pfn, 1);
> > +	assert_transition_res(-EPERM,	hyp_pin_shared_mem, virt, virt + size);
> > +
> > +	selftest_state.host = PKVM_PAGE_OWNED;
> > +	selftest_state.hyp = PKVM_NOPAGE;
> > +	assert_transition_res(0,	__pkvm_host_unshare_ffa, pfn, 1);
> 
> Try it twice?

Sg.

Thanks!
Quentin


From maz at kernel.org  Fri Dec 20 07:22:30 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Dec 2024 15:22:30 +0000
Subject: [PATCH v5 00/17] KVM: arm64: Rework guest VM fixed feature handling and trapping in pKVM
In-Reply-To: <20241216105057.579031-1-tabba@google.com>
References: <20241216105057.579031-1-tabba@google.com>
Message-ID: <173470804652.1394795.5150120931608048707.b4-ty@kernel.org>

On Mon, 16 Dec 2024 10:50:40 +0000, Fuad Tabba wrote:
> Changes from v4:
> - (Oliver) Add assertion in kvm_init_pvm_id_regs() that vm_table
>   lock is held.
> - (Quentin) Carve out patches that fix RAS and that remove the
>   feature KVM_ARM_VCPU_POWER_OFF from original patches, for clarity.
> - (Quentin) Add a patch that refactors existing code to use
>   kvm_vcpu_has_feature() instead of __vcpu_has_feature().
> - (Quentin) Fixes to commit messages.
> 
> [...]

Applied to next, thanks!

There was a number of conflicts applying this to -rc3, and then
some more with Quentin's series. Please check kvmarm/next to make
sure that I did the right thing.

[01/17] KVM: arm64: Consolidate allowed and restricted VM feature checks
        commit: 2589dbd72797a4163dd998b05c4663ff98bd0771
[02/17] KVM: arm64: Group setting traps for protected VMs by control register
        commit: f50758260bfff393f2a800469b37c45a7ef50376
[03/17] KVM: arm64: Move checking protected vcpu features to a separate function
        commit: 1fea164ccf19750c5bea688afd9122eb84eb3a72
[04/17] KVM: arm64: Remove KVM_ARM_VCPU_POWER_OFF from protected VMs allowed features in pKVM
        commit: 27f5cf8ad5224033a711aef3fde90b60c9a8d7d5
[05/17] KVM: arm64: Use KVM extension checks for allowed protected VM capabilities
        commit: a3163dca4817e9a30b154a14c793641e39a00592
[06/17] KVM: arm64: Initialize feature id registers for protected VMs
        commit: 7ba5b8f80475e48b486f095ee9fb67dc9f9d02df
[07/17] KVM: arm64: Fix RAS trapping in pKVM for protected VMs
        commit: 9df9186f8df513dc9bf9f95f68525c7ebc941bcd
[08/17] KVM: arm64: Set protected VM traps based on its view of feature registers
        commit: 0401f7e76d707741d2562f4988743cc5daf445e4
[09/17] KVM: arm64: Rework specifying restricted features for protected VMs
        commit: 3d7ff00700d1a4d0c8f092f2c1bf67553a8c7c4c
[10/17] KVM: arm64: Remove fixed_config.h header
        commit: 81403c8d04e1d85209cdb0e0ce32aa0019620c65
[11/17] KVM: arm64: Remove redundant setting of HCR_EL2 trap bit
        commit: 092e7b2c3b1a5591bbabc358f3b709dfa2289b91
[12/17] KVM: arm64: Calculate cptr_el2 traps on activating traps
        commit: 2fd5b4b0e7b440602455b79977bfa64dea101e6c
[13/17] KVM: arm64: Refactor kvm_reset_cptr_el2()
        commit: 8f7df795b2da0564b22a03c4aceec90bfc5e1b1b
[14/17] KVM: arm64: Fix the value of the CPTR_EL2 RES1 bitmask for nVHE
        commit: 1eccad35c9268f1ad4be3d72d37167a58c0ac2db
[15/17] KVM: arm64: Remove PtrAuth guest vcpu flag
        commit: c5c1763596660fcd77a1190b3bd78bbe24bcfd6a
[16/17] KVM: arm64: Convert the SVE guest vcpu flag to a vm flag
        commit: 41d6028e28bd474298ff10409c292ec46cf43a90
[17/17] KVM: arm64: Use kvm_vcpu_has_feature() directly for struct kvm
        commit: aac64ad36955268d65375c32415d5bcf1bd1dd47

Cheers,

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




From Frank.li at nxp.com  Fri Dec 20 07:38:20 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 20 Dec 2024 10:38:20 -0500
Subject: [PATCH 10/10] arm64: dts: imx8mp-skov: increase I2C clock
 frequency for RTC
In-Reply-To: <2ae085fa-6f13-4eb7-88c1-e625309fc35e@pengutronix.de>
References: <20241219-skov-dt-updates-v1-0-38bf80dc22df@pengutronix.de>
 <20241219-skov-dt-updates-v1-10-38bf80dc22df@pengutronix.de>
 <Z2RcJCaYC2FW3Ks6@lizhi-Precision-Tower-5810>
 <30dbe486-7e36-426d-8fa4-3ecd83193a10@pengutronix.de>
 <Z2Rw8qnn9hULyh8l@lizhi-Precision-Tower-5810>
 <2ae085fa-6f13-4eb7-88c1-e625309fc35e@pengutronix.de>
Message-ID: <Z2WPbB9cV0hcP2UB@lizhi-Precision-Tower-5810>

On Fri, Dec 20, 2024 at 10:12:49AM +0100, Ahmad Fatoum wrote:
> Hello Frank,
>
> On 19.12.24 20:16, Frank Li wrote:
> > On Thu, Dec 19, 2024 at 06:51:35PM +0100, Ahmad Fatoum wrote:
> >> On 19.12.24 18:47, Frank Li wrote:
> >>> On Thu, Dec 19, 2024 at 08:25:34AM +0100, Ahmad Fatoum wrote:
> >>>> From: Oleksij Rempel <o.rempel at pengutronix.de>
> >>>>
> >>>> The NXP PCF85063TP RTC we use is capable of up to 400 kHz of SCL clock
> >>>> frequency, so let's make use of this instead of the 100 kHz bus frequency
> >>>> we are currently using.
> >>>
> >>> Increase I2C frequency to 400khz from 100kHz because NXP PCF85063TP RTC
> >>> support it.
> >>
> >> Unlike your other suggestions, these is no information lost by rewriting
> >> the commit message as you suggest. I don't mind, but must admit it feels
> >> like bikeshedding. What is your concrete objection to my commit message?
> >
> > According to
> > https://docs.kernel.org/process/submitting-patches.html
> >
> > Describe your changes in imperative mood, e.g. ?make xyzzy do frotz?
> > instead of ?[This patch] makes xyzzy do frotz? or
> > ?[I] changed xyzzy to do frotz?, as if you are giving orders to the
> > codebase to change its behaviour.
>
> I have to disagree with your interpretation. The imperative mood is primarily
> expected for commit message titles, but if you take a look at normal commit
> message _bodies_ that make it into the kernel, you'll find that a whole lot
> of them start off like I do: Describe the situation and then what's done about
> it.

I was got many similar feedback from difference maintainer to be required
change my commit message _bodies_ in past years.

https://lore.kernel.org/imx/3c9fe85a-5f86-4df6-92fb-e4ceb033f161 at kernel.org/
https://lore.kernel.org/imx/117dd6f3-8829-4000-a05b-6cb421ca7de6 at kernel.org/
https://lore.kernel.org/linux-pci/20240807025423.GF3412 at thinkpad/
https://lore.kernel.org/linux-pci/YnvyrSTAxJmGxful at lpieralisi/

At beginning, I can't understand this. But after follow these expertor
suggestion, I found some beanfit.
- sentense will be shorter and easy to capture most important part. for
example:

  "The NXP PCF85063TP RTC we use is capable of up to 400 kHz of SCL clock
  frequency, so let's make use of this instead of the 100 kHz bus frequency
  we are currently using."

  34 words

  "Increase I2C frequency to 400khz from 100kHz because NXP PCF85063TP RTC
   support it"

  13 words

  Linux is big community, even reduce 1 minutes to read it, multi by
totall reviewer/reader will be very big numbers.

- empahse the important change first to help understand whole patch
quickly.

You can choose what you want if maintainer don't reject it. Generally I
just send such kind comments for v1 patch, because it is less possible to
be accepted by by maintainer to accept (except some critial fixes).

>
> I personally find that this is often easier to follow than just having two
> imperatives back-to-back.

Basic principle is clear, simple, and straightforward.

Frank

>
> I have just Cc'd you on an RFC patch to amend the documentation you linked
> to reflect this. I am happy to continue the discussion over there:
>
> https://lore.kernel.org/workflows/20241220-submitting-patches-imperative-v1-0-ee874c1859b3 at pengutronix.de/T/#t
>
> Thanks,
> Ahmad
>
> >
> > Generally, avoid use
> >
> > "this patch ..."
> > "let's ...."
> > "we do ... for ... "
> >
> > Just simple said
> >
> > Do ... to ...
> > Do ... because ...
> >
> > Frank
> >
> >>
> >> Thanks,
> >> Ahmad
> >>
> >>
> >>>
> >>> Frank
> >>>
> >>>>
> >>>> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> >>>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> >>>> ---
> >>>>  arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi | 2 +-
> >>>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> >>>> index a683f46fcbab..ec7857db7bf0 100644
> >>>> --- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> >>>> +++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
> >>>> @@ -333,7 +333,7 @@ reg_nvcc_sd2: LDO5 {
> >>>>  };
> >>>>
> >>>>  &i2c3 {
> >>>> -	clock-frequency = <100000>;
> >>>> +	clock-frequency = <400000>;
> >>>>  	pinctrl-names = "default";
> >>>>  	pinctrl-0 = <&pinctrl_i2c3>;
> >>>>  	status = "okay";
> >>>>
> >>>> --
> >>>> 2.39.5
> >>>>
> >>>
> >>
> >>
> >> --
> >> 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 |
> >
>
>
> --
> 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 david at redhat.com  Fri Dec 20 07:42:35 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 20 Dec 2024 16:42:35 +0100
Subject: [PATCH v2 1/1] KVM: arm64: Allow cacheable stage 2 mapping using
 VMA flags
In-Reply-To: <20241118131958.4609-2-ankita@nvidia.com>
References: <20241118131958.4609-1-ankita@nvidia.com>
 <20241118131958.4609-2-ankita@nvidia.com>
Message-ID: <a2d95399-62ad-46d3-9e48-6fa90fd2c2f3@redhat.com>

On 18.11.24 14:19, ankita at nvidia.com wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> Currently KVM determines if a VMA is pointing at IO memory by checking
> pfn_is_map_memory(). However, the MM already gives us a way to tell what
> kind of memory it is by inspecting the VMA.

Do you primarily care about VM_PFNMAP/VM_MIXEDMAP VMAs, or also other 
VMA types?

> 
> This patch solves the problems where it is possible for the kernel to
> have VMAs pointing at cachable memory without causing
> pfn_is_map_memory() to be true, eg DAX memremap cases and CXL/pre-CXL
> devices. This memory is now properly marked as cachable in KVM.

Does this only imply in worse performance, or does this also affect 
correctness? I suspect performance is the problem, correct?

> 
> The pfn_is_map_memory() is restrictive and allows only for the memory
> that is added to the kernel to be marked as cacheable. In most cases
> the code needs to know if there is a struct page, or if the memory is
> in the kernel map and pfn_valid() is an appropriate API for this.
 > Extend the umbrella with pfn_valid() to include memory with no 
struct> pages for consideration to be mapped cacheable in stage 2. A 
!pfn_valid()
> implies that the memory is unsafe to be mapped as cacheable.


I do wonder, are there ways we could have a !(VM_PFNMAP/VM_MIXEDMAP) 
where kvm_is_device_pfn() == true? Are these the "DAX memremap cases and 
CXL/pre-CXL" things you describe above, or are they VM_PFNMAP/VM_MIXEDMAP?


It's worth nothing that COW VM_PFNMAP/VM_MIXEDMAP mappings are possible 
right now, where we could have anon pages mixed with PFN mappings. Of 
course, VMA pgrpot only partially apply to the anon pages (esp. caching 
attributes).

Likely you assume to never end up with COW VM_PFNMAP -- I think it's 
possible when doing a MAP_PRIVATE /dev/mem mapping on systems that allow 
for mapping /dev/mem. Maybe one could just reject such cases (if KVM PFN 
lookup code not already rejects them, which might just be that case IIRC).

> 
> Moreover take account of the mapping type in the VMA to make a decision
> on the mapping. The VMA's pgprot is tested to determine the memory type
> with the following mapping:
>   pgprot_noncached    MT_DEVICE_nGnRnE   device (or Normal_NC)
>   pgprot_writecombine MT_NORMAL_NC       device (or Normal_NC)
>   pgprot_device       MT_DEVICE_nGnRE    device (or Normal_NC)
>   pgprot_tagged       MT_NORMAL_TAGGED   RAM / Normal
>   -                   MT_NORMAL          RAM / Normal
> 
> Also take care of the following two cases that prevents the memory to
> be safely mapped as cacheable:
> 1. The VMA pgprot have VM_IO set alongwith MT_NORMAL or
>     MT_NORMAL_TAGGED. Although unexpected and wrong, presence of such
>     configuration cannot be ruled out.
> 2. Configurations where VM_MTE_ALLOWED is not set and KVM_CAP_ARM_MTE
>     is enabled. Otherwise a malicious guest can enable MTE at stage 1
>     without the hypervisor being able to tell. This could cause external
>     aborts.
> 
> Introduce a new variable noncacheable to represent whether the memory
> should not be mapped as cacheable. The noncacheable as false implies
> the memory is safe to be mapped cacheable.

Why not use ... "cacheable" ? This sentence would then read as:

"Introduce a new variable "cachable" to represent whether the memory
should be mapped as cacheable."

and maybe even could be dropped completely. :)

But maybe there is a reason for that in the code.

> Use this to handle the
> aforementioned potentially unsafe cases for cacheable mapping.
> 
> Note when FWB is not enabled, the kernel expects to trivially do
> cache management by flushing the memory by linearly converting a
> kvm_pte to phys_addr to a KVA, see kvm_flush_dcache_to_poc(). This is
> only possibile for struct page backed memory. Do not allow non-struct
> page memory to be cachable without FWB.
> 
> The device memory such as on the Grace Hopper systems is interchangeable
> with DDR memory and retains its properties. Allow executable faults
> on the memory determined as Normal cacheable.
> 
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
-- 
Cheers,

David / dhildenb



From Frank.li at nxp.com  Fri Dec 20 07:44:50 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 20 Dec 2024 10:44:50 -0500
Subject: [PATCH v4 1/4] arm64: dts: s32g: add 'I2C' common board support
In-Reply-To: <20241220123916.1452582-2-ciprianmarian.costea@oss.nxp.com>
References: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
 <20241220123916.1452582-2-ciprianmarian.costea@oss.nxp.com>
Message-ID: <Z2WQ8j2kIQ462dxX@lizhi-Precision-Tower-5810>

On Fri, Dec 20, 2024 at 02:39:13PM +0200, Ciprian Costea wrote:

Subject is wrong, this patch is not for common board

Simple said:  "Add I2C[0..2] support for s32g2 and s32g3"

> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>
> On both 'S32G2' and 'S32G3' SoCs there are five i2c controllers available
> (i2c0-i2c4). Specific S32G2/S32G3 based board 'i2c' dts device support
> will be added in further commits.

This commit have not touch "based board".

So"Add I2C[0..2] for S32G and S32G3 SoCs commit dts."

Allow only copy subject here for such simple add some nodes.

>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/s32g2.dtsi | 55 ++++++++++++++++++++++
>  arch/arm64/boot/dts/freescale/s32g3.dtsi | 60 ++++++++++++++++++++++++
>  2 files changed, 115 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> index 7be430b78c83..1a9683c234b7 100644
> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> @@ -333,6 +333,39 @@ uart1: serial at 401cc000 {
>  			status = "disabled";
>  		};
>
> +		i2c0: i2c at 401e4000 {
> +			compatible = "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x401e4000 0x1000>;

reg should just after compatible.

Frank

> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c1: i2c at 401e8000 {
> +			compatible = "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x401e8000 0x1000>;
> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c2: i2c at 401ec000 {
> +			compatible = "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x401ec000 0x1000>;
> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		uart2: serial at 402bc000 {
>  			compatible = "nxp,s32g2-linflexuart",
>  				     "fsl,s32v234-linflexuart";
> @@ -341,6 +374,28 @@ uart2: serial at 402bc000 {
>  			status = "disabled";
>  		};
>
> +		i2c3: i2c at 402d8000 {
> +			compatible = "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x402d8000 0x1000>;
> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c4: i2c at 402dc000 {
> +			compatible = "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x402dc000 0x1000>;
> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		usdhc0: mmc at 402f0000 {
>  			compatible = "nxp,s32g2-usdhc";
>  			reg = <0x402f0000 0x1000>;
> diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> index 6c572ffe37ca..5d28b439906d 100644
> --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> @@ -390,6 +390,42 @@ uart1: serial at 401cc000 {
>  			status = "disabled";
>  		};
>
> +		i2c0: i2c at 401e4000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x401e4000 0x1000>;
> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c1: i2c at 401e8000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x401e8000 0x1000>;
> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c2: i2c at 401ec000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x401ec000 0x1000>;
> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		uart2: serial at 402bc000 {
>  			compatible = "nxp,s32g3-linflexuart",
>  				     "fsl,s32v234-linflexuart";
> @@ -398,6 +434,30 @@ uart2: serial at 402bc000 {
>  			status = "disabled";
>  		};
>
> +		i2c3: i2c at 402d8000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x402d8000 0x1000>;
> +			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		i2c4: i2c at 402dc000 {
> +			compatible = "nxp,s32g3-i2c",
> +				     "nxp,s32g2-i2c";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x402dc000 0x1000>;
> +			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 40>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
>  		usdhc0: mmc at 402f0000 {
>  			compatible = "nxp,s32g3-usdhc",
>  				     "nxp,s32g2-usdhc";
> --
> 2.45.2
>


From Frank.li at nxp.com  Fri Dec 20 07:55:56 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 20 Dec 2024 10:55:56 -0500
Subject: [PATCH v4 4/4] arm64: dts: s32g399a-rdb3: Add INA231 sensor
 entry over I2C4
In-Reply-To: <20241220123916.1452582-5-ciprianmarian.costea@oss.nxp.com>
References: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
 <20241220123916.1452582-5-ciprianmarian.costea@oss.nxp.com>
Message-ID: <Z2WTjETLunBr83AN@lizhi-Precision-Tower-5810>

On Fri, Dec 20, 2024 at 02:39:16PM +0200, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>
> On S32G399A-RDB3 boards, an INA231 current sensor is connected over
> I2C4 bus.

Add INA231 current sensor for S32G399A-RDB3 boards.

>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> index 94f531be4017..5f8739c068c6 100644
> --- a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
> @@ -40,6 +40,14 @@ &uart1 {
>  	status = "okay";
>  };
>
> +&i2c4 {
> +	ina231 at 40 {

Need use general node name:
https://devicetree-specification.readthedocs.io/en/v0.3/devicetree-basics.html#node-names

look like should be current-sensor

Frank

> +		compatible = "ti,ina231";
> +		reg = <0x40>;
> +		shunt-resistor = <1000>;
> +	};
> +};
> +
>  &usdhc0 {
>  	pinctrl-names = "default", "state_100mhz", "state_200mhz";
>  	pinctrl-0 = <&pinctrl_usdhc0>;
> --
> 2.45.2
>


From Frank.li at nxp.com  Fri Dec 20 08:02:19 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 20 Dec 2024 11:02:19 -0500
Subject: [PATCH v4 2/4] arm64: dts: s32g: add common 'S32G-EVB' and
 'S32G-RDB' board support
In-Reply-To: <20241220123916.1452582-3-ciprianmarian.costea@oss.nxp.com>
References: <20241220123916.1452582-1-ciprianmarian.costea@oss.nxp.com>
 <20241220123916.1452582-3-ciprianmarian.costea@oss.nxp.com>
Message-ID: <Z2WVCyJbJTpU/FrY@lizhi-Precision-Tower-5810>

On Fri, Dec 20, 2024 at 02:39:14PM +0200, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
>
> With respect to S32G2/S32G3 SoC based boards, there are multiple RDB
> (rdb2 vs rdb3) and EVB (for G2 vs for G3) board revisions. These versions
> are quite similar. The common part for the EVB revisions will be
> centralized in 's32gxxa-evb.dtsi' file, while the RDB commonalities will
> be placed in 's32gxxa-rdb.dtsi' file.
>
> This refactor will also serve for other modules in the future, such as
> FlexCAN, DSPI.


https://docs.kernel.org/process/submitting-patches.html
"Describe your changes in imperative mood, e.g. ?make xyzzy do frotz?
instead of ?[This patch] makes xyzzy do frotz? or ?[I] changed xyzzy to do
frotz?, as if you are giving orders to the codebase to change its
behaviour."

So suggest..

Create common part, s32gxxa-evb.dtsi and s32gxxa-rdb.dtsi, for S32G2/S32G3
RDB2\3 and EVB G2/G3 boards to avoid copy duplicate part in boards dts
file. Prepare to add other modules easily in the future.

>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> ---
>  .../boot/dts/freescale/s32gxxxa-evb.dtsi      | 150 ++++++++++++++++++
>  .../boot/dts/freescale/s32gxxxa-rdb.dtsi      | 122 ++++++++++++++
>  2 files changed, 272 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi

I think you should squash patch 3/4 to this one. All is for the boards dts.

Frank
>
> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
> new file mode 100644
> index 000000000000..a44eff28073a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
> @@ -0,0 +1,150 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> +/*
> + * Copyright 2024 NXP
> + *
> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
> + *          Larisa Grigore <larisa.grigore at nxp.com>
> + */
> +
> +&pinctrl {
> +	i2c0_pins: i2c0-pins {
> +		i2c0-grp0 {
> +			pinmux = <0x101>, <0x111>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-grp1 {
> +			pinmux = <0x2352>, <0x2362>;
> +		};
> +	};
> +
> +	i2c0_gpio_pins: i2c0-gpio-pins {
> +		i2c0-gpio-grp0 {
> +			pinmux = <0x100>, <0x110>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-gpio-grp1 {
> +			pinmux = <0x2350>, <0x2360>;
> +		};
> +	};
> +
> +	i2c1_pins: i2c1-pins {
> +		i2c1-grp0 {
> +			pinmux = <0x131>, <0x141>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c1-grp1 {
> +			pinmux = <0x2cd2>, <0x2ce2>;
> +		};
> +	};
> +
> +	i2c1_gpio_pins: i2c1-gpio-pins {
> +		i2c1-gpio-grp0 {
> +			pinmux = <0x130>, <0x140>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c1-gpio-grp1 {
> +			pinmux = <0x2cd0>, <0x2ce0>;
> +		};
> +	};
> +
> +	i2c2_pins: i2c2-pins {
> +		i2c2-grp0 {
> +			pinmux = <0x151>, <0x161>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c2-grp1 {
> +			pinmux = <0x2cf2>, <0x2d02>;
> +		};
> +	};
> +
> +	i2c2_gpio_pins: i2c2-gpio-pins {
> +		i2c2-gpio-grp0 {
> +			pinmux = <0x150>, <0x160>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c2-gpio-grp1 {
> +			pinmux = <0x2cf0>, <0x2d00>;
> +		};
> +	};
> +
> +	i2c4_pins: i2c4-pins {
> +		i2c4-grp0 {
> +			pinmux = <0x211>, <0x222>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-grp1 {
> +			pinmux = <0x2d43>, <0x2d33>;
> +		};
> +	};
> +
> +	i2c4_gpio_pins: i2c4-gpio-pins {
> +		i2c4-gpio-grp0 {
> +			pinmux = <0x210>, <0x220>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-gpio-grp1 {
> +			pinmux = <0x2d40>, <0x2d30>;
> +		};
> +	};
> +};
> +
> +&i2c0 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c0_pins>;
> +	pinctrl-1 = <&i2c0_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c1 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c1_pins>;
> +	pinctrl-1 = <&i2c1_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c2_pins>;
> +	pinctrl-1 = <&i2c2_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c4 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c4_pins>;
> +	pinctrl-1 = <&i2c4_gpio_pins>;
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
> new file mode 100644
> index 000000000000..91fd8dbf2224
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
> @@ -0,0 +1,122 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> +/*
> + * Copyright 2024 NXP
> + *
> + * Authors: Ciprian Marian Costea <ciprianmarian.costea at oss.nxp.com>
> + *          Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
> + *          Larisa Grigore <larisa.grigore at nxp.com>
> + */
> +
> +&pinctrl {
> +	i2c0_pins: i2c0-pins {
> +		i2c0-grp0 {
> +			pinmux = <0x1f2>, <0x201>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-grp1 {
> +			pinmux = <0x2353>, <0x2363>;
> +		};
> +	};
> +
> +	i2c0_gpio_pins: i2c0-gpio-pins {
> +		i2c0-gpio-grp0 {
> +			pinmux = <0x1f0>, <0x200>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c0-gpio-grp1 {
> +			pinmux = <0x2350>, <0x2360>;
> +		};
> +	};
> +
> +	i2c2_pins: i2c2-pins {
> +		i2c2-grp0 {
> +			pinmux = <0x151>, <0x161>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c2-grp1 {
> +			pinmux = <0x2cf2>, <0x2d02>;
> +		};
> +	};
> +
> +	i2c2_gpio_pins: i2c2-gpio-pins {
> +		i2c2-gpio-grp0 {
> +			pinmux = <0x2cf0>, <0x2d00>;
> +		};
> +
> +		i2c2-gpio-grp1 {
> +			pinmux = <0x150>, <0x160>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +	};
> +
> +	i2c4_pins: i2c4-pins {
> +		i2c4-grp0 {
> +			pinmux = <0x211>, <0x222>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-grp1 {
> +			pinmux = <0x2d43>, <0x2d33>;
> +		};
> +	};
> +
> +	i2c4_gpio_pins: i2c4-gpio-pins {
> +		i2c4-gpio-grp0 {
> +			pinmux = <0x210>, <0x220>;
> +			drive-open-drain;
> +			output-enable;
> +			input-enable;
> +			slew-rate = <133>;
> +		};
> +
> +		i2c4-gpio-grp1 {
> +			pinmux = <0x2d40>, <0x2d30>;
> +		};
> +	};
> +};
> +
> +&i2c0 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c0_pins>;
> +	pinctrl-1 = <&i2c0_gpio_pins>;
> +	status = "okay";
> +
> +	pcal6524: gpio-expander at 22 {
> +		compatible = "nxp,pcal6524";
> +		reg = <0x22>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c2_pins>;
> +	pinctrl-1 = <&i2c2_gpio_pins>;
> +	status = "okay";
> +};
> +
> +&i2c4 {
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&i2c4_pins>;
> +	pinctrl-1 = <&i2c4_gpio_pins>;
> +	status = "okay";
> +};
> --
> 2.45.2
>


From nfraprado at collabora.com  Fri Dec 20 08:09:45 2024
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Fri, 20 Dec 2024 13:09:45 -0300
Subject: [PATCH v2 0/2] net: stmmac: dwmac-mediatek: Fix inverted logic
 for mediatek,mac-wol
In-Reply-To: <173155682775.1476954.16636894744432122406.git-patchwork-notify@kernel.org>
References: <20241109-mediatek-mac-wol-noninverted-v2-0-0e264e213878@collabora.com>
 <173155682775.1476954.16636894744432122406.git-patchwork-notify@kernel.org>
Message-ID: <876cf020-e2ba-46a7-b9b2-82dcd47f7a04@notapiano>

On Thu, Nov 14, 2024 at 04:00:27AM +0000, patchwork-bot+netdevbpf at kernel.org wrote:
> Hello:
> 
> This series was applied to netdev/net.git (main)
> by Jakub Kicinski <kuba at kernel.org>:
> 
> On Sat, 09 Nov 2024 10:16:31 -0500 you wrote:
> > This series fixes the inverted handling of the mediatek,mac-wol DT
> > property. This was done with backwards compatibility in v1, but based on
> > the feedback received, all boards should be using MAC WOL, so many of
> > them were incorrectly described and didn't have working WOL tested
> > anyway. So for v2, the approach is simpler: just fix the driver handling
> > and update the DTs to enable MAC WOL everywhere.
> > 
> > [...]
> 
> Here is the summary with links:
>   - [v2,1/2] net: stmmac: dwmac-mediatek: Fix inverted handling of mediatek,mac-wol
>     https://git.kernel.org/netdev/net/c/a03b18a71c12
>   - [v2,2/2] arm64: dts: mediatek: Set mediatek,mac-wol on DWMAC node for all boards
>     (no matching commit)

Hi Jakub,

This message implies patch 2 was also applied, but I only see patch 1, not patch
2 there:
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/log/?qt=grep&q=mac-wol

So I just wanted to confirm whether it was applied or not. It would be fine for
patch 2 to be merged through the mediatek tree as is usual if you haven't
already taken it.

(Also, FYI, I was not CC'ed in this message from the patchwork bot)

Thanks,
N?colas


From wens at kernel.org  Fri Dec 20 08:12:40 2024
From: wens at kernel.org (Chen-Yu Tsai)
Date: Sat, 21 Dec 2024 00:12:40 +0800
Subject: [PATCH v2] arm64: dts: rockchip: orangepi-5-plus: Enable USB 3.0 ports
Message-ID: <20241220161240.109253-1-wens@kernel.org>

From: Chen-Yu Tsai <wens at csie.org>

The Orange Pi 5 Plus has its first USB 3.0 interface on the SoC wired
directly to the USB type C port next to the MASKROM button, and the
second interface wired to a USB 3.0 hub which in turn is connected to
the USB 3.0 host ports on the board, as well as the USB 2.0 connection
on the M.2 E-key slot.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>

---
Changes since v1:
- Dropped source current to 1.4A
- Dropped sink current to 10mA, since it doesn't actually sink current
- Added try-power-role
- Added newline before endpoint device nodes in USB connector node
---
 .../dts/rockchip/rk3588-orangepi-5-plus.dts   | 133 ++++++++++++++++++
 1 file changed, 133 insertions(+)

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 9f5a38b290bf..000d353645a9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
@@ -218,6 +218,18 @@ vcc5v0_sys: regulator-vcc5v0-sys {
 		regulator-max-microvolt = <5000000>;
 	};
 
+	vbus5v0_typec: vbus-typec-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&typec5v_pwren>;
+		regulator-name = "vbus5v0_typec";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
 	vcc5v0_usb20: regulator-vcc5v0-usb20 {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -344,6 +356,57 @@ &i2c6 {
 	clock-frequency = <400000>;
 	status = "okay";
 
+	usbc0: usb-typec at 22 {
+		compatible = "fcs,fusb302";
+		reg = <0x22>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbc0_int>;
+		vbus-supply = <&vbus5v0_typec>;
+		status = "okay";
+
+		usb_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "dual";
+			source-pdos = <PDO_FIXED(5000, 1400, PDO_FIXED_USB_COMM)>;
+			sink-pdos = <PDO_FIXED(5000, 10, PDO_FIXED_USB_COMM)>;
+			op-sink-microwatt = <10>;
+			try-power-role = "source";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_hs: endpoint {
+						remote-endpoint = <&usb_host0_xhci_drd_sw>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_ss: endpoint {
+						remote-endpoint = <&usbdp_phy0_typec_ss>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+
+					usbc0_sbu: endpoint {
+						remote-endpoint = <&usbdp_phy0_typec_sbu>;
+					};
+				};
+			};
+		};
+	};
+
 	hym8563: rtc at 51 {
 		compatible = "haoyu,hym8563";
 		reg = <0x51>;
@@ -485,6 +548,16 @@ vcc5v0_usb20_en: vcc5v0-usb20-en {
 			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
+
+	usb-typec {
+		usbc0_int: usbc0-int {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		typec5v_pwren: typec5v-pwren {
+			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
 };
 
 &pwm2 {
@@ -876,6 +949,23 @@ &tsadc {
 	status = "okay";
 };
 
+&u2phy0 {
+	status = "okay";
+};
+
+&u2phy0_otg {
+	status = "okay";
+};
+
+&u2phy1 {
+	status = "okay";
+};
+
+&u2phy1_otg {
+	phy-supply = <&vcc5v0_sys>;
+	status = "okay";
+};
+
 &u2phy2 {
 	status = "okay";
 };
@@ -904,6 +994,33 @@ &uart9 {
 	status = "okay";
 };
 
+&usbdp_phy0 {
+	mode-switch;
+	orientation-switch;
+	sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
+	sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usbdp_phy0_typec_ss: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&usbc0_ss>;
+		};
+
+		usbdp_phy0_typec_sbu: endpoint at 1 {
+			reg = <1>;
+			remote-endpoint = <&usbc0_sbu>;
+		};
+	};
+};
+
+&usbdp_phy1 {
+	status = "okay";
+};
+
 &usb_host0_ehci {
 	status = "okay";
 };
@@ -912,6 +1029,17 @@ &usb_host0_ohci {
 	status = "okay";
 };
 
+&usb_host0_xhci {
+	usb-role-switch;
+	status = "okay";
+
+	port {
+		usb_host0_xhci_drd_sw: endpoint {
+			remote-endpoint = <&usbc0_hs>;
+		};
+	};
+};
+
 &usb_host1_ehci {
 	status = "okay";
 };
@@ -920,6 +1048,11 @@ &usb_host1_ohci {
 	status = "okay";
 };
 
+&usb_host1_xhci {
+	dr_mode = "host";
+	status = "okay";
+};
+
 &vop_mmu {
 	status = "okay";
 };
-- 
2.39.5



From s-vadapalli at ti.com  Fri Dec 20 08:17:05 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 20 Dec 2024 21:47:05 +0530
Subject: [PATCH net] net: ethernet: ti: am65-cpsw: default to round-robin
 for host port receive
In-Reply-To: <eb573f51-4363-4cd7-ab1b-0d7304820d85@intel.com>
References: <20241220075618.228202-1-s-vadapalli@ti.com>
 <eb573f51-4363-4cd7-ab1b-0d7304820d85@intel.com>
Message-ID: <6whu7jzxigyqmnk5424ltu3tpdnlgetpqv6nvfbaxvlw2nseq4@y2vi3c56o3dd>

On Fri, Dec 20, 2024 at 11:41:26AM +0100, Przemek Kitszel wrote:
> On 12/20/24 08:56, Siddharth Vadapalli wrote:
> > The Host Port (i.e. CPU facing port) of CPSW receives traffic from Linux
> > via TX DMA Channels which are Hardware Queues consisting of traffic
> > categorized according to their priority. The Host Port is configured to
> > dequeue traffic from these Hardware Queues on the basis of priority i.e.
> > as long as traffic exists on a Hardware Queue of a higher priority, the
> > traffic on Hardware Queues of lower priority isn't dequeued. An alternate
> > operation is also supported wherein traffic can be dequeued by the Host
> > Port in a Round-Robin manner.
> > 
> > Until [0], the am65-cpsw driver enabled a single TX DMA Channel, due to
> > which, unless modified by user via "ethtool", all traffic from Linux is
> > transmitted on DMA Channel 0. Therefore, configuring the Host Port for
> > priority based dequeuing or Round-Robin operation is identical since
> > there is a single DMA Channel.
> > 
> > Since [0], all 8 TX DMA Channels are enabled by default. Additionally,
> > the default "tc mapping" doesn't take into account the possibility of
> > different traffic profiles which various users might have. This results
> > in traffic starvation at the Host Port due to the priority based dequeuing
> > which has been enabled by default since the inception of the driver. The
> > traffic starvation triggers NETDEV WATCHDOG timeout for all TX DMA Channels
> > that haven't been serviced due to the presence of traffic on the higher
> > priority TX DMA Channels.
> 
> I get it right that the starving is caused by HW/DMA (not SW)

Yes. The CPSW Host Port in Hardware can be configured to dequeue packets
queued onto the DMA Channels by Linux in either a Priority-based manner
or Round-Robin manner. Linux is submitting the packets onto the TX DMA
Channels to be received by CPSW, with CPSW's Host Port dequeuing them
in one of the two modes (fixed priority or round-robin) that has been
programmed.

> 
> > 
> > Fix this by defaulting to Round-Robin dequeuing at the Host Port, which
> > shall ensure that traffic is dequeued from all TX DMA Channels irrespective
> > of the traffic profile. This will address the NETDEV WATCHDOG timeouts.
> > At the same time, users can still switch from Round-Robin to Priority
> > based dequeuing at the Host Port with the help of the "p0-rx-ptype-rrobin"
> 
> why the flag has rx in the name?

The "rx" corresponds to "receive" w.r.t. the Host Port (P0). As indicated
in the $subject of this patch, we are defaulting to "Round-Robin" (rrobin)
mode of operation of Host Port dequeuing i.e. packets received by the Host
Port from Linux are to be dequeued in a Round-Robin manner from each of the
TX DMA Channels (TX from Linux's perspective). As for the naming convention
being followed, it is based on the Techincal Reference Manual.

[...]

Regards,
Siddharth.


From dave.stevenson at raspberrypi.com  Fri Dec 20 08:21:13 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 16:21:13 +0000
Subject: [PATCH 2/7] docs: uapi: media: Document Raspberry Pi NV12 column
 format
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
Message-ID: <20241220-media-rpi-hevc-dec-v1-2-0ebcc04ed42e@raspberrypi.com>

The Raspberry Pi HEVC decoder uses a tiled format based on
columns for 8 and 10 bit YUV images, so document them as
NV12MT_COL128 and NV12MT_10_COL128.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../userspace-api/media/v4l/pixfmt-yuv-planar.rst  | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
index b788f6933855..90414491d7b5 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
@@ -827,6 +827,48 @@ Data in the 12 high bits, zeros in the 4 low bits, arranged in little endian ord
       - Cb\ :sub:`11`
       - Cr\ :sub:`11`
 
+NV12MT_COL128 and NV12MT_10_COL128
+----------------------------------
+
+``V4L2_PIX_FMT_NV12MT_COL128`` is a tiled version of
+``V4L2_PIX_FMT_NV12M`` where the two planes are split into 128 byte wide columns
+of Y or interleaved CbCr.
+
+NV12MT_10_COL128 expands that as a 10 bit format where 3 10 bit values are
+packed into a 32bit word. A 128 byte wide column therefore holds 96 samples
+(either Y or interleaved CrCb). That effectively makes it 6 values in a 64 bit
+word for the CbCr plane, as the values always go in pairs.
+
+Bit-packed representation.
+
+.. tabularcolumns:: |p{1.2cm}||p{1.2cm}||p{1.2cm}||p{1.2cm}|p{3.2cm}|p{3.2cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 8 8 8 8
+
+    * - Y'\ :sub:`00[7:0]`
+      - Y'\ :sub:`01[5:0] (bits 7--2)` Y'\ :sub:`00[9:8]`\ (bits 1--0)
+      - Y'\ :sub:`02[3:0] (bits 7--4)` Y'\ :sub:`01[9:6]`\ (bits 3--0)
+      - unused (bits 7--6)` Y'\ :sub:`02[9:4]`\ (bits 5--0)
+
+.. tabularcolumns:: |p{1.2cm}||p{1.2cm}||p{1.2cm}||p{1.2cm}|p{3.2cm}|p{3.2cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 12 12 12 12 12 12 12 12
+
+    * - Cb\ :sub:`00[7:0]`
+      - Cr\ :sub:`00[5:0]`\ (bits 7--2) Cb\ :sub:`00[9:8]`\ (bits 1--0)
+      - Cb\ :sub:`01[3:0]`\ (bits 7--4) Cr\ :sub:`00[9:6]`\ (bits 3--0)
+      - unused (bits 7--6) Cb\ :sub:`02[9:4]`\ (bits 5--0)
+      - Cr\ :sub:`01[7:0]`
+      - Cb\ :sub:`02[5:0]`\ (bits 7--2) Cr\ :sub:`01[9:8]`\ (bits 1--0)
+      - Cr\ :sub:`02[3:0]`\ (bits 7--4) Cb\ :sub:`02[9:6]`\ (bits 3--0)
+      - unused (bits 7--6) Cr\ :sub:`02[9:4]`\ (bits 5--0)
+
 
 Fully Planar YUV Formats
 ========================

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Fri Dec 20 08:21:14 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 16:21:14 +0000
Subject: [PATCH 3/7] media: ioctl: Add pixel formats NV12MT_COL128 and
 NV12MT_10_COL128
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
Message-ID: <20241220-media-rpi-hevc-dec-v1-3-0ebcc04ed42e@raspberrypi.com>

Add V4L2_PIXFMT_NV12MT_COL128 and V4L2_PIXFMT_NV12MT_10_COL128
to describe the Raspberry Pi HEVC decoder NV12 multiplanar formats.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 drivers/media/v4l2-core/v4l2-ioctl.c | 2 ++
 include/uapi/linux/videodev2.h       | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 0304daa8471d..e510e375a871 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1377,7 +1377,9 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
 	case V4L2_PIX_FMT_NV16M:	descr = "Y/UV 4:2:2 (N-C)"; break;
 	case V4L2_PIX_FMT_NV61M:	descr = "Y/VU 4:2:2 (N-C)"; break;
 	case V4L2_PIX_FMT_NV12MT:	descr = "Y/UV 4:2:0 (64x32 MB, N-C)"; break;
+	case V4L2_PIX_FMT_NV12MT_COL128: descr = "Y/CbCr 4:2:0 (128b cols)"; break;
 	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/UV 4:2:0 (16x16 MB, N-C)"; break;
+	case V4L2_PIX_FMT_NV12MT_10_COL128: descr = "10-bit Y/CbCr 4:2:0 (128b cols)"; break;
 	case V4L2_PIX_FMT_P012M:	descr = "12-bit Y/UV 4:2:0 (N-C)"; break;
 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index e7c4dce39007..f8f97aa6a616 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -687,6 +687,11 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12  Y/CbCr 4:2:0 16x16 tiles */
 #define V4L2_PIX_FMT_NV12M_8L128      v4l2_fourcc('N', 'A', '1', '2') /* Y/CbCr 4:2:0 8x128 tiles */
 #define V4L2_PIX_FMT_NV12M_10BE_8L128 v4l2_fourcc_be('N', 'T', '1', '2') /* Y/CbCr 4:2:0 10-bit 8x128 tiles */
+#define V4L2_PIX_FMT_NV12MT_COL128 v4l2_fourcc('N', 'c', '1', '2') /* 12  Y/CbCr 4:2:0 128 pixel wide column */
+#define V4L2_PIX_FMT_NV12MT_10_COL128 v4l2_fourcc('N', 'c', '3', '0')
+								/* Y/CbCr 4:2:0 10bpc, 3x10 packed as 4 bytes in
+								 * a 128 bytes / 96 pixel wide column */
+
 
 /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Fri Dec 20 08:21:12 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 16:21:12 +0000
Subject: [PATCH 1/7] RFC: media: Add media_request_{pin,unpin} API
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
Message-ID: <20241220-media-rpi-hevc-dec-v1-1-0ebcc04ed42e@raspberrypi.com>

From: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

This is probably not the API we will want to add, but it
should show what semantics are needed by drivers.

The goal is to allow the OUTPUT (aka source) buffer and the
controls associated to a request to be released from the request,
and in particular return the OUTPUT buffer back to userspace,
without signalling the media request fd.

This is useful for devices that are able to pre-process
the OUTPUT buffer, therefore able to release it before
the decoding is finished. These drivers should signal
the media request fd only after the CAPTURE buffer is done.

Tested-by: John Cox <john.cox at raspberypi.com>
Signed-off-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 drivers/media/mc/mc-request.c | 35 +++++++++++++++++++++++++++++++++++
 include/media/media-request.h | 12 ++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/drivers/media/mc/mc-request.c b/drivers/media/mc/mc-request.c
index 5edfc2791ce7..b5334389d846 100644
--- a/drivers/media/mc/mc-request.c
+++ b/drivers/media/mc/mc-request.c
@@ -499,3 +499,38 @@ void media_request_object_complete(struct media_request_object *obj)
 		media_request_put(req);
 }
 EXPORT_SYMBOL_GPL(media_request_object_complete);
+
+void media_request_pin(struct media_request *req)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&req->lock, flags);
+	if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED))
+		goto unlock;
+	req->num_incomplete_objects++;
+unlock:
+	spin_unlock_irqrestore(&req->lock, flags);
+}
+EXPORT_SYMBOL_GPL(media_request_pin);
+
+void media_request_unpin(struct media_request *req)
+{
+	unsigned long flags;
+	bool completed = false;
+
+	spin_lock_irqsave(&req->lock, flags);
+	if (WARN_ON(!req->num_incomplete_objects) ||
+	    WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED))
+		goto unlock;
+
+	if (!--req->num_incomplete_objects) {
+		req->state = MEDIA_REQUEST_STATE_COMPLETE;
+		wake_up_interruptible_all(&req->poll_wait);
+		completed = true;
+	}
+unlock:
+	spin_unlock_irqrestore(&req->lock, flags);
+	if (completed)
+		media_request_put(req);
+}
+EXPORT_SYMBOL_GPL(media_request_unpin);
diff --git a/include/media/media-request.h b/include/media/media-request.h
index d4ac557678a7..c48cfb710959 100644
--- a/include/media/media-request.h
+++ b/include/media/media-request.h
@@ -189,6 +189,10 @@ static inline void media_request_get(struct media_request *req)
  */
 void media_request_put(struct media_request *req);
 
+void media_request_pin(struct media_request *req);
+
+void media_request_unpin(struct media_request *req);
+
 /**
  * media_request_get_by_fd - Get a media request by fd
  *
@@ -228,6 +232,14 @@ static inline void media_request_put(struct media_request *req)
 {
 }
 
+static inline void media_request_pin(struct media_request *req)
+{
+}
+
+static inline void media_request_unpin(struct media_request *req)
+{
+}
+
 static inline struct media_request *
 media_request_get_by_fd(struct media_device *mdev, int request_fd)
 {

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Fri Dec 20 08:21:11 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 16:21:11 +0000
Subject: [PATCH 0/7] Raspberry Pi HEVC decoder driver
Message-ID: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>

Hi All

This has been in the pipeline for a while, but I've finally cleaned
up our HEVC decoder driver to be in a shape to at least get a first
review.
John Cox has done almost all of the work under contract to Raspberry
Pi, and I'm largely just doing the process of patch curation and
sending.

There are a couple of questions raised in frameworks.
The main one is that the codec has 2 independent phases to the decode,
CABAC and reconstruction. To keep the decoder operating optimally
means that two requests need to be in process at once, whilst the
current frameworks don't want to allow as there is an implicit
assumption of only a single job being active at once, and
completition returns both buffers and releases the media request.

The OUTPUT queue buffer is finished with and can be returned at the
end of phase 1, but the media request is still required for phase 2.
The frameworks currently force the driver to be returning both
together via v4l2_m2m_buf_done_and_job_finish. v4l2_m2m_job_finish
would complete the job without returning the buffer as we need,
however if the driver has set VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF
then we have a WARN in v4l2_m2m_job_finish.
Dropping the WARN as this series is currently doing isn't going to be
the right answer, but it isn't obvious what the right answer is.
Discussion required.

We also have a need to hold on to the media request for phase 2. John
had discussed this with Ezequiel (and others) a couple of years back,
and hence suggested a patch that adds media_request_{pin,unpin} to
grab references on the media request. Discussion required on that
or a better way of handling it.

I will apologise in advance for sending this V1 just before I head off
on the Christmas break, but will respond to things as soon as possible.

Thanks
  Dave

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
Dave Stevenson (4):
      docs: uapi: media: Document Raspberry Pi NV12 column format
      media: ioctl: Add pixel formats NV12MT_COL128 and NV12MT_10_COL128
      media: dt-bindings: media: Add binding for the Raspberry Pi HEVC decoder
      arm: dts: bcm2711-rpi: Add HEVC decoder node

Ezequiel Garcia (1):
      RFC: media: Add media_request_{pin,unpin} API

John Cox (2):
      media: platform: Add Raspberry Pi HEVC decoder driver
      RFC: v4l2-mem2mem: Remove warning from v4l2_m2m_job_finish

 .../bindings/media/raspberrypi,hevc-dec.yaml       |   72 +
 .../userspace-api/media/v4l/pixfmt-yuv-planar.rst  |   42 +
 MAINTAINERS                                        |   10 +
 arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi        |    5 +
 arch/arm/boot/dts/broadcom/bcm2711.dtsi            |    9 +
 drivers/media/mc/mc-request.c                      |   35 +
 drivers/media/platform/raspberrypi/Kconfig         |    1 +
 drivers/media/platform/raspberrypi/Makefile        |    1 +
 .../media/platform/raspberrypi/hevc_dec/Kconfig    |   17 +
 .../media/platform/raspberrypi/hevc_dec/Makefile   |    5 +
 .../media/platform/raspberrypi/hevc_dec/hevc_d.c   |  443 ++++
 .../media/platform/raspberrypi/hevc_dec/hevc_d.h   |  190 ++
 .../platform/raspberrypi/hevc_dec/hevc_d_h265.c    | 2629 ++++++++++++++++++++
 .../platform/raspberrypi/hevc_dec/hevc_d_hw.c      |  376 +++
 .../platform/raspberrypi/hevc_dec/hevc_d_hw.h      |  303 +++
 .../platform/raspberrypi/hevc_dec/hevc_d_video.c   |  685 +++++
 .../platform/raspberrypi/hevc_dec/hevc_d_video.h   |   38 +
 drivers/media/v4l2-core/v4l2-ioctl.c               |    2 +
 drivers/media/v4l2-core/v4l2-mem2mem.c             |    7 -
 include/media/media-request.h                      |   12 +
 include/uapi/linux/videodev2.h                     |    5 +
 21 files changed, 4880 insertions(+), 7 deletions(-)
---
base-commit: e90c9612ac3969cb8206029a26bcd2b6f5d4a942
change-id: 20241212-media-rpi-hevc-dec-3b5be739f3bd

Best regards,
-- 
Dave Stevenson <dave.stevenson at raspberrypi.com>



From dave.stevenson at raspberrypi.com  Fri Dec 20 08:21:15 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 16:21:15 +0000
Subject: [PATCH 4/7] media: dt-bindings: media: Add binding for the
 Raspberry Pi HEVC decoder
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
Message-ID: <20241220-media-rpi-hevc-dec-v1-4-0ebcc04ed42e@raspberrypi.com>

Adds a binding for the HEVC decoder found on the BCM2711 / Raspberry Pi 4,
and BCM2712 / Raspberry Pi 5.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/media/raspberrypi,hevc-dec.yaml       | 72 ++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/raspberrypi,hevc-dec.yaml b/Documentation/devicetree/bindings/media/raspberrypi,hevc-dec.yaml
new file mode 100644
index 000000000000..d9e804300297
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/raspberrypi,hevc-dec.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/raspberrypi,hevc-dec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Raspberry Pi HEVC Decoder
+
+maintainers:
+  - John Cox <john.cox at raspberrypi.com>
+  - Dom Cobley <dom at raspberrypi.com>
+  - Dave Stevenson <dave.stevenson at raspberrypi.com>
+  - Raspberry Pi internal review list <kernel-list at raspberrypi.com>
+
+description: |-
+  The Raspberry Pi HEVC decoder is a hardware video decode accelerator block
+  found in the BCM2711 and BCM2712 processors used on Raspberry Pi 4 and 5
+  boards respectively.
+
+properties:
+  compatible:
+    enum:
+      - raspberrypi,hevc-dec
+
+  reg:
+    items:
+      - description: The HEVC main register region
+      - description: The Interrupt control register region
+
+  reg-names:
+    items:
+      - const: intc
+      - const: hevc
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: The HEVC block clock
+
+  clock-names:
+    items:
+      - const: hevc
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    video-codec at 7eb10000 {
+        compatible = "raspberrypi,hevc-dec";
+        reg = <0x7eb10000 0x1000>,	/* INTC */
+              <0x7eb00000 0x10000>; /* HEVC */
+        reg-names = "intc",
+                    "hevc";
+
+        interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
+        clocks = <&clk 0>;
+        clock-names = "hevc";
+    };
+
+...

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Fri Dec 20 08:21:17 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 16:21:17 +0000
Subject: [PATCH 6/7] RFC: v4l2-mem2mem: Remove warning from
 v4l2_m2m_job_finish
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
Message-ID: <20241220-media-rpi-hevc-dec-v1-6-0ebcc04ed42e@raspberrypi.com>

From: John Cox <john.cox at raspberrypi.com>

The Raspberry Pi HEVC decoder has a 2 stage pipeline
where the OUTPUT buffer is finished with before the
CAPTURE buffer is ready.

v4l2_m2m_job_finish allows us to do this, however as
the driver handles VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
this warn fires on every buffer as drivers that hold capture
buffers are expected to use v4l2_m2m_buf_done_and_job_finish
(introduced with [1]).
That doesn't allow us to handle not returning the destination
buffer.

[1] Commit f8cca8c97a63 ("media: v4l2-mem2mem: support held
capture buffers")

Signed-off-by: John Cox <john.cox at raspberrypi.com>
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index eb22d6172462..325a518beff7 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -490,13 +490,6 @@ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
 	unsigned long flags;
 	bool schedule_next;
 
-	/*
-	 * This function should not be used for drivers that support
-	 * holding capture buffers. Those should use
-	 * v4l2_m2m_buf_done_and_job_finish() instead.
-	 */
-	WARN_ON(m2m_ctx->out_q_ctx.q.subsystem_flags &
-		VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF);
 	spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
 	schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx);
 	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Fri Dec 20 08:21:18 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 16:21:18 +0000
Subject: [PATCH 7/7] arm: dts: bcm2711-rpi: Add HEVC decoder node
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com>
Message-ID: <20241220-media-rpi-hevc-dec-v1-7-0ebcc04ed42e@raspberrypi.com>

Add the configuration information for the HEVC decoder.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi | 5 +++++
 arch/arm/boot/dts/broadcom/bcm2711.dtsi     | 9 +++++++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi
index 6bf4241fe3b7..43fa2d82cedc 100644
--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi
@@ -105,3 +105,8 @@ &vchiq {
 &xhci {
 	power-domains = <&power RPI_POWER_DOMAIN_USB>;
 };
+
+&hevc_dec {
+	clocks = <&firmware_clocks 11>;
+	clock-names = "hevc";
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm2711.dtsi b/arch/arm/boot/dts/broadcom/bcm2711.dtsi
index e4e42af21ef3..0a1f05a26a6a 100644
--- a/arch/arm/boot/dts/broadcom/bcm2711.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm2711.dtsi
@@ -628,6 +628,15 @@ v3d: gpu at 7ec00000 {
 			resets = <&pm BCM2835_RESET_V3D>;
 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
 		};
+
+		hevc_dec: codec at 7eb10000 {
+			compatible = "raspberrypi,hevc-dec";
+			reg = <0x0 0x7eb10000  0x1000>,  /* INTC */
+			      <0x0 0x7eb00000  0x10000>; /* HEVC */
+			reg-names = "intc",
+				    "hevc";
+			interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 };
 

-- 
2.34.1



From lkp at intel.com  Fri Dec 20 08:26:50 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 00:26:50 +0800
Subject: [PATCH] pinctrl: mediatek: Add support for MT8196
In-Reply-To: <20241211055454.17120-3-ot_cathy.xu@mediatek.com>
References: <20241211055454.17120-3-ot_cathy.xu@mediatek.com>
Message-ID: <202412210007.sMeJEMYf-lkp@intel.com>

Hi ot907280,

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 linus/master v6.13-rc3 next-20241220]
[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/ot907280/pinctrl-mediatek-Add-support-for-MT8196/20241211-140107
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
patch link:    https://lore.kernel.org/r/20241211055454.17120-3-ot_cathy.xu%40mediatek.com
patch subject: [PATCH] pinctrl: mediatek: Add support for MT8196
config: sparc64-randconfig-r071-20241219 (https://download.01.org/0day-ci/archive/20241221/202412210007.sMeJEMYf-lkp at intel.com/config)
compiler: sparc64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241221/202412210007.sMeJEMYf-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/202412210007.sMeJEMYf-lkp at intel.com/

All errors (new ones prefixed by >>):

>> sparc64-linux-ld: drivers/pinctrl/mediatek/pinctrl-mt8196.o:(.data+0xa0): undefined reference to `mtk_paris_pinctrl_pm_ops'

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


From alicja.michalska at 9elements.com  Fri Dec 20 08:32:27 2024
From: alicja.michalska at 9elements.com (Alicja Michalska)
Date: Fri, 20 Dec 2024 17:32:27 +0100
Subject: [PATCH] arm64: dts: rockchip: ROCK3B: Correct clock rates for Ethernet PHYs
Message-ID: <20241220163227.1501912-1-alicja.michalska@9elements.com>

Built-in ethernet PHYs did not work on mainline kernel:

fe010000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
fe010000.ethernet eth0: __stmmac_open: Cannot attach to PHY

According to the board design, they need to be configured as output with
static TX/RX delay. This patch sets it accordingly.

Signed-off-by: Alicja Michalska <alicja.michalska at 9elements.com>
---
 .../boot/dts/rockchip/rk3568-rock-3b.dts      | 68 +++++++++++--------
 1 file changed, 38 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
index 3d0c1ccfaa79..5350158302e4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
@@ -183,37 +183,65 @@ &cpu3 {
 &gmac0 {
 	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
 	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
-	clock_in_out = "input";
-	phy-handle = <&rgmii_phy0>;
-	phy-mode = "rgmii-id";
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "output";
 	phy-supply = <&vcc_3v3>;
+	phy-mode = "rgmii";
+	phy-handle = <&rgmii_phy0>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&gmac0_miim
 		     &gmac0_tx_bus2
 		     &gmac0_rx_bus2
 		     &gmac0_rgmii_clk
-		     &gmac0_rgmii_bus
-		     &gmac0_clkinout>;
+		     &gmac0_rgmii_bus>;
+	snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 20000 100000>;
+
+	tx_delay = <0x36>;
+	rx_delay = <0x2d>;
+
 	status = "okay";
 };
 
 &gmac1 {
 	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
 	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
-	clock_in_out = "input";
-	phy-handle = <&rgmii_phy1>;
-	phy-mode = "rgmii-id";
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "output";
 	phy-supply = <&vcc_3v3>;
+	phy-mode = "rgmii";
+	phy-handle = <&rgmii_phy1>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&gmac1m1_miim
 		     &gmac1m1_tx_bus2
 		     &gmac1m1_rx_bus2
 		     &gmac1m1_rgmii_clk
-		     &gmac1m1_rgmii_bus
-		     &gmac1m1_clkinout>;
+		     &gmac1m1_rgmii_bus>;
+	snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 50000 150000>;
+
+	tx_delay = <0x47>;
+	rx_delay = <0x28>;
+
 	status = "okay";
 };
 
+&mdio0 {
+	rgmii_phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0>;
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0>;
+	};
+};
+
 &gpu {
 	mali-supply = <&vdd_gpu>;
 	status = "okay";
@@ -512,26 +540,6 @@ &i2s1m0_sdi0
 	status = "okay";
 };
 
-&mdio0 {
-	rgmii_phy0: ethernet-phy at 1 {
-		compatible = "ethernet-phy-ieee802.3-c22";
-		reg = <1>;
-		reset-assert-us = <20000>;
-		reset-deassert-us = <50000>;
-		reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
-	};
-};
-
-&mdio1 {
-	rgmii_phy1: ethernet-phy at 1 {
-		compatible = "ethernet-phy-ieee802.3-c22";
-		reg = <1>;
-		reset-assert-us = <20000>;
-		reset-deassert-us = <50000>;
-		reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
-	};
-};
-
 &pcie2x1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie20m1_pins>;
-- 
2.47.1



From jwerner at chromium.org  Fri Dec 20 08:33:53 2024
From: jwerner at chromium.org (Julius Werner)
Date: Fri, 20 Dec 2024 17:33:53 +0100
Subject: [PATCH v3 1/3] arm64: errata: Assume that unknown CPUs _are_
 vulnerable to Spectre BHB
In-Reply-To: <20241219125317.v3.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
References: <20241219205426.2275508-1-dianders@chromium.org> <20241219125317.v3.1.I2040fa004dafe196243f67ebcc647cbedbb516e6@changeid>
Message-ID: <CAODwPW8bq8ev7gb4T=p7GeKsW8Q_7MNY1MpauZ9LOcmH3qVw1A@mail.gmail.com>

Reviewed-by: Julius Werner <jwerner at chromium.org>

On Thu, Dec 19, 2024 at 9:54?PM Douglas Anderson <dianders at chromium.org> wrote:
>
> The code for detecting CPUs that are vulnerable to Spectre BHB was
> based on a hardcoded list of CPU IDs that were known to be affected.
> Unfortunately, the list mostly only contained the IDs of standard ARM
> cores. The IDs for many cores that are minor variants of the standard
> ARM cores (like many Qualcomm Kyro CPUs) weren't listed. This led the
> code to assume that those variants were not affected.
>
> Flip the code on its head and instead assume that a core is vulnerable
> if it doesn't have CSV2_3 but is unrecognized as being safe. This
> involves creating a "Spectre BHB safe" list.
>
> As of right now, the only CPU IDs added to the "Spectre BHB safe" list
> are ARM Cortex A35, A53, A55, A510, and A520. This list was created by
> looking for cores that weren't listed in ARM's list [1] as per review
> feedback on v2 of this patch [2].
>
> NOTE: this patch will not actually _mitigate_ anyone, it will simply
> cause them to report themselves as vulnerable. If any cores in the
> system are reported as vulnerable but not mitigated then the whole
> system will be reported as vulnerable though the system will attempt
> to mitigate with the information it has about the known cores.
>
> [1] https://developer.arm.com/Arm%20Security%20Center/Spectre-BHB
> [2] https://lore.kernel.org/r/20241219175128.GA25477 at willie-the-truck
>
>
> Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels")
> Cc: stable at vger.kernel.org
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---
>
> Changes in v3:
> - Don't guess the mitigation; just report unknown cores as vulnerable.
> - Restructure the code since is_spectre_bhb_affected() defaults to true
>
> Changes in v2:
> - New
>
>  arch/arm64/include/asm/spectre.h |   1 -
>  arch/arm64/kernel/proton-pack.c  | 144 +++++++++++++++++--------------
>  2 files changed, 77 insertions(+), 68 deletions(-)
>
> diff --git a/arch/arm64/include/asm/spectre.h b/arch/arm64/include/asm/spectre.h
> index 0c4d9045c31f..f1524cdeacf1 100644
> --- a/arch/arm64/include/asm/spectre.h
> +++ b/arch/arm64/include/asm/spectre.h
> @@ -97,7 +97,6 @@ enum mitigation_state arm64_get_meltdown_state(void);
>
>  enum mitigation_state arm64_get_spectre_bhb_state(void);
>  bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
> -u8 spectre_bhb_loop_affected(int scope);
>  void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
>  bool try_emulate_el1_ssbs(struct pt_regs *regs, u32 instr);
>
> diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
> index da53722f95d4..06e04c9e6480 100644
> --- a/arch/arm64/kernel/proton-pack.c
> +++ b/arch/arm64/kernel/proton-pack.c
> @@ -845,52 +845,68 @@ static unsigned long system_bhb_mitigations;
>   * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
>   * SCOPE_SYSTEM call will give the right answer.
>   */
> -u8 spectre_bhb_loop_affected(int scope)
> +static bool is_spectre_bhb_safe(int scope)
> +{
> +       static const struct midr_range spectre_bhb_safe_list[] = {
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A35),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A53),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A510),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A520),
> +               {},
> +       };
> +       static bool all_safe = true;
> +
> +       if (scope != SCOPE_LOCAL_CPU)
> +               return all_safe;
> +
> +       if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_safe_list))
> +               return true;
> +
> +       all_safe = false;
> +
> +       return false;
> +}
> +
> +static u8 spectre_bhb_loop_affected(void)
>  {
>         u8 k = 0;
> -       static u8 max_bhb_k;
> -
> -       if (scope == SCOPE_LOCAL_CPU) {
> -               static const struct midr_range spectre_bhb_k32_list[] = {
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
> -                       MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> -                       MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
> -                       {},
> -               };
> -               static const struct midr_range spectre_bhb_k24_list[] = {
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
> -                       MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
> -                       {},
> -               };
> -               static const struct midr_range spectre_bhb_k11_list[] = {
> -                       MIDR_ALL_VERSIONS(MIDR_AMPERE1),
> -                       {},
> -               };
> -               static const struct midr_range spectre_bhb_k8_list[] = {
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
> -                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
> -                       {},
> -               };
> -
> -               if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
> -                       k = 32;
> -               else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
> -                       k = 24;
> -               else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
> -                       k = 11;
> -               else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
> -                       k =  8;
> -
> -               max_bhb_k = max(max_bhb_k, k);
> -       } else {
> -               k = max_bhb_k;
> -       }
> +
> +       static const struct midr_range spectre_bhb_k32_list[] = {
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
> +               MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +               MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
> +               {},
> +       };
> +       static const struct midr_range spectre_bhb_k24_list[] = {
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
> +               MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
> +               {},
> +       };
> +       static const struct midr_range spectre_bhb_k11_list[] = {
> +               MIDR_ALL_VERSIONS(MIDR_AMPERE1),
> +               {},
> +       };
> +       static const struct midr_range spectre_bhb_k8_list[] = {
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
> +               MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
> +               {},
> +       };
> +
> +       if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
> +               k = 32;
> +       else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
> +               k = 24;
> +       else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
> +               k = 11;
> +       else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
> +               k =  8;
>
>         return k;
>  }
> @@ -916,9 +932,8 @@ static enum mitigation_state spectre_bhb_get_cpu_fw_mitigation_state(void)
>         }
>  }
>
> -static bool is_spectre_bhb_fw_affected(int scope)
> +static bool is_spectre_bhb_fw_affected(void)
>  {
> -       static bool system_affected;
>         enum mitigation_state fw_state;
>         bool has_smccc = arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_NONE;
>         static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
> @@ -929,16 +944,8 @@ static bool is_spectre_bhb_fw_affected(int scope)
>         bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
>                                          spectre_bhb_firmware_mitigated_list);
>
> -       if (scope != SCOPE_LOCAL_CPU)
> -               return system_affected;
> -
>         fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
> -       if (cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) {
> -               system_affected = true;
> -               return true;
> -       }
> -
> -       return false;
> +       return cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED);
>  }
>
>  static bool supports_ecbhb(int scope)
> @@ -954,6 +961,8 @@ static bool supports_ecbhb(int scope)
>                                                     ID_AA64MMFR1_EL1_ECBHB_SHIFT);
>  }
>
> +static u8 max_bhb_k;
> +
>  bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
>                              int scope)
>  {
> @@ -962,16 +971,18 @@ bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
>         if (supports_csv2p3(scope))
>                 return false;
>
> -       if (supports_clearbhb(scope))
> -               return true;
> -
> -       if (spectre_bhb_loop_affected(scope))
> -               return true;
> +       if (is_spectre_bhb_safe(scope))
> +               return false;
>
> -       if (is_spectre_bhb_fw_affected(scope))
> -               return true;
> +       /*
> +        * At this point the core isn't known to be "safe" so we're going to
> +        * assume it's vulnerable. We still need to update `max_bhb_k` though,
> +        * but only if we aren't mitigating with clearbhb though.
> +        */
> +       if (scope == SCOPE_LOCAL_CPU && !supports_clearbhb(SCOPE_LOCAL_CPU))
> +               max_bhb_k = max(max_bhb_k, spectre_bhb_loop_affected());
>
> -       return false;
> +       return true;
>  }
>
>  static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
> @@ -1028,7 +1039,7 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
>                 this_cpu_set_vectors(EL1_VECTOR_BHB_CLEAR_INSN);
>                 state = SPECTRE_MITIGATED;
>                 set_bit(BHB_INSN, &system_bhb_mitigations);
> -       } else if (spectre_bhb_loop_affected(SCOPE_LOCAL_CPU)) {
> +       } else if (spectre_bhb_loop_affected()) {
>                 /*
>                  * Ensure KVM uses the indirect vector which will have the
>                  * branchy-loop added. A57/A72-r0 will already have selected
> @@ -1041,7 +1052,7 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
>                 this_cpu_set_vectors(EL1_VECTOR_BHB_LOOP);
>                 state = SPECTRE_MITIGATED;
>                 set_bit(BHB_LOOP, &system_bhb_mitigations);
> -       } else if (is_spectre_bhb_fw_affected(SCOPE_LOCAL_CPU)) {
> +       } else if (is_spectre_bhb_fw_affected()) {
>                 fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
>                 if (fw_state == SPECTRE_MITIGATED) {
>                         /*
> @@ -1100,7 +1111,6 @@ void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt,
>  {
>         u8 rd;
>         u32 insn;
> -       u16 loop_count = spectre_bhb_loop_affected(SCOPE_SYSTEM);
>
>         BUG_ON(nr_inst != 1); /* MOV -> MOV */
>
> @@ -1109,7 +1119,7 @@ void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt,
>
>         insn = le32_to_cpu(*origptr);
>         rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn);
> -       insn = aarch64_insn_gen_movewide(rd, loop_count, 0,
> +       insn = aarch64_insn_gen_movewide(rd, max_bhb_k, 0,
>                                          AARCH64_INSN_VARIANT_64BIT,
>                                          AARCH64_INSN_MOVEWIDE_ZERO);
>         *updptr++ = cpu_to_le32(insn);
> --
> 2.47.1.613.gc27f4b7a9f-goog
>


From linux at fw-web.de  Fri Dec 20 08:38:34 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Fri, 20 Dec 2024 17:38:34 +0100
Subject: [PATCH v8 0/2] Add Pmic to Bpi-R4
Message-ID: <20241220163838.114786-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

After these 2 Patches are dropped from my dts-series [1] i verified these
with mtk and changed based on this.

The problem was that voltages from BUCK4 and LDO were not matching the
voltages from schematic.

These 2 are not software-controlled, but should show the right voltage
in regulator overview.

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=918585

Frank Wunderlich (2):
  arm64: dts: mediatek: mt7988a-bpi-r4: Add MediaTek MT6682A/RT5190A
    PMIC
  arm64: dts: mediatek: mt7988a-bpi-r4: Add proc-supply for cpus

 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 66 +++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi     |  8 +--
 2 files changed, 70 insertions(+), 4 deletions(-)

-- 
2.43.0



From linux at fw-web.de  Fri Dec 20 08:38:35 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Fri, 20 Dec 2024 17:38:35 +0100
Subject: [PATCH v8 1/2] arm64: dts: mediatek: mt7988a-bpi-r4: Add MediaTek MT6682A/RT5190A PMIC
In-Reply-To: <20241220163838.114786-1-linux@fw-web.de>
References: <20241220163838.114786-1-linux@fw-web.de>
Message-ID: <20241220163838.114786-2-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Bananapi R4 Board contains a MT6682A pmic which is compatible to rt5190a.
Add its node to the i2 controller.

The BananaPi R4 board has a MediaTek MT6682A PMIC, a rebrand of the
Richtek RT5190A chip, connected to the I2C0 bus.

Add the relevant node and, while at it, also configure the regulators
from this PMIC that are used on this board.

Only Buck2/Buck3 voltage can be controlled by software.

BUCK4 input is 5V from BUCK1 output, and the resistor (mapped to RP30/RP31
on BPI-R4) configures BUCK4 output to 1.8V.
LDO input is 3.3V from 3.3VD, and the resistor (mapped to RP38/RP40 on
BPI-R4) configures LDO output to 1.8V.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v8:
- fixed buck4 and ldo voltage and extended commit-Message
- readded (send separately) after verifying with mtk
- left RB from angelo as this is imho only minor change
v7:
- dropped this patch due to voltage mismatch compared to schematic
v4:
- change regulator-allowed-modes of pmic as 2 items
v3:
- change commit title and text
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 50 +++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index d6f1fca3323c..27edc6b84f80 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -3,6 +3,7 @@
 /dts-v1/;
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
 
 #include "mt7988a.dtsi"
 
@@ -66,6 +67,55 @@ &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins>;
 	status = "okay";
+
+	rt5190a_64: rt5190a at 64 {
+		compatible = "richtek,rt5190a";
+		reg = <0x64>;
+		vin2-supply = <&rt5190_buck1>;
+		vin3-supply = <&rt5190_buck1>;
+		vin4-supply = <&rt5190_buck1>;
+
+		regulators {
+			rt5190_buck1: buck1 {
+				regulator-name = "rt5190a-buck1";
+				regulator-min-microvolt = <5090000>;
+				regulator-max-microvolt = <5090000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO>, <RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+			buck2 {
+				regulator-name = "vcore";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+			rt5190_buck3: buck3 {
+				regulator-name = "vproc";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-boot-on;
+			};
+			buck4 {
+				regulator-name = "rt5190a-buck4";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-allowed-modes =
+				<RT5190A_OPMODE_AUTO>, <RT5190A_OPMODE_FPWM>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+			ldo {
+				regulator-name = "rt5190a-ldo";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
 };
 
 &i2c2 {
-- 
2.43.0



From linux at fw-web.de  Fri Dec 20 08:38:36 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Fri, 20 Dec 2024 17:38:36 +0100
Subject: [PATCH v8 2/2] arm64: dts: mediatek: mt7988a-bpi-r4: Add proc-supply for cpus
In-Reply-To: <20241220163838.114786-1-linux@fw-web.de>
References: <20241220163838.114786-1-linux@fw-web.de>
Message-ID: <20241220163838.114786-3-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add proc-supply property to cpus on Bananapi R4 board.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
changes:
v3:
- change commit title to have prefix for r4
---
 .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts     | 16 ++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi        |  8 ++++----
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
index 27edc6b84f80..6623112c24c7 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -35,6 +35,22 @@ reg_3p3v: regulator-3p3v {
 	};
 };
 
+&cpu0 {
+	proc-supply = <&rt5190_buck3>;
+};
+
+&cpu1 {
+	proc-supply = <&rt5190_buck3>;
+};
+
+&cpu2 {
+	proc-supply = <&rt5190_buck3>;
+};
+
+&cpu3 {
+	proc-supply = <&rt5190_buck3>;
+};
+
 &cpu_thermal {
 	trips {
 		cpu_trip_hot: hot {
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index 7a5e16a97476..88b56a24efca 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -16,7 +16,7 @@ cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		cpu at 0 {
+		cpu0: cpu at 0 {
 			compatible = "arm,cortex-a73";
 			reg = <0x0>;
 			device_type = "cpu";
@@ -27,7 +27,7 @@ cpu at 0 {
 			operating-points-v2 = <&cluster0_opp>;
 		};
 
-		cpu at 1 {
+		cpu1: cpu at 1 {
 			compatible = "arm,cortex-a73";
 			reg = <0x1>;
 			device_type = "cpu";
@@ -38,7 +38,7 @@ cpu at 1 {
 			operating-points-v2 = <&cluster0_opp>;
 		};
 
-		cpu at 2 {
+		cpu2: cpu at 2 {
 			compatible = "arm,cortex-a73";
 			reg = <0x2>;
 			device_type = "cpu";
@@ -49,7 +49,7 @@ cpu at 2 {
 			operating-points-v2 = <&cluster0_opp>;
 		};
 
-		cpu at 3 {
+		cpu3: cpu at 3 {
 			compatible = "arm,cortex-a73";
 			reg = <0x3>;
 			device_type = "cpu";
-- 
2.43.0



From frank-w at public-files.de  Fri Dec 20 08:44:22 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Fri, 20 Dec 2024 16:44:22 +0000
Subject: Aw: [PATCH v8 0/2] Add Pmic to Bpi-R4
In-Reply-To: <20241220163838.114786-1-linux@fw-web.de>
References: <20241220163838.114786-1-linux@fw-web.de>
Message-ID: <trinity-bbda816d-6467-433a-a516-19da45abe816-1734713062840@trinity-msg-rest-gmx-gmx-live-548599f845-5xz2p>

Sorry, seems i made mistake with version-number...

these 2 patches were dropped from the linked v3.

there is no v4-v7

not sure why i had increased my changelog in first patch to v7 before...
maybe mixed with the pinctrl series

regards Frank


From arnd at arndb.de  Fri Dec 20 08:47:01 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 20 Dec 2024 17:47:01 +0100
Subject: [PATCH v2 0/4] ARM: config: stm32: Remove useless flags
In-Reply-To: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
References: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
Message-ID: <c720715b-cde3-4ab4-991d-37e9ae91b16f@app.fastmail.com>

On Fri, Dec 20, 2024, at 13:55, patrice.chotard at foss.st.com wrote:
> From: Patrice Chotard <patrice.chotard at foss.st.com>
>
> Running "make savedefconfig" highlights that some flags are no more used,
> remove them.
> Remove some flags to reduce the kernel image size as STM32 MCU's board
> embeds low amount of RAM.
>
> Changes in V2:
>   _ squash patches 2-7
>   _ split patch 1 in three parts and add epxlanations about flags removal.

Looks good to me, thanks for the update. I assume the plan is to
have this in another pull request rather than me picking up the
patches directly, right?


Acked-by: Arnd Bergmann <arnd at arndb.de>


From broonie at kernel.org  Fri Dec 20 08:46:45 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:45 +0000
Subject: [PATCH RFC v3 20/27] KVM: arm64: Provide assembly for SME state
 restore
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-20-05b018c1ffeb@kernel.org>

Provide a __sme_restore_state() for the hypervisor to allow it to restore
ZA and ZT for guests.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_hyp.h |  2 ++
 arch/arm64/kvm/hyp/fpsimd.S      | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 21943cb98542750a1b626a8de6bbc095d7770ccf..5a1f8e4be18624efa6b887f09c36f0e8ad318c40 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -113,6 +113,8 @@ void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
 void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
 void __sve_save_state(void *sve_pffr, u32 *fpsr, int save_ffr);
 void __sve_restore_state(void *sve_pffr, u32 *fpsr, int restore_ffr);
+int __sve_get_vl(void);
+void __sme_restore_state(void const *state, bool restore_zt);
 
 u64 __guest_enter(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/kvm/hyp/fpsimd.S b/arch/arm64/kvm/hyp/fpsimd.S
index e950875e31cee4df58d041519b7584356463c91b..9e4bce86ef2e632a6071480c06a0b7d69bf48f3d 100644
--- a/arch/arm64/kvm/hyp/fpsimd.S
+++ b/arch/arm64/kvm/hyp/fpsimd.S
@@ -31,3 +31,19 @@ SYM_FUNC_START(__sve_save_state)
 	sve_save 0, x1, x2, 3
 	ret
 SYM_FUNC_END(__sve_save_state)
+
+SYM_FUNC_START(__sve_get_vl)
+	_sve_rdvl	0, 1
+	ret
+SYM_FUNC_END(__sve_get_vl)
+
+SYM_FUNC_START(__sme_restore_state)
+	_sme_rdsvl	2, 1		// x2 = VL/8
+	sme_load_za	0, x2, 12	// Leaves x0 pointing to end of ZA
+
+	cbz	x1, 1f
+	_ldr_zt 0
+
+1:
+	ret
+SYM_FUNC_END(__sme_restore_state)

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:46 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:46 +0000
Subject: [PATCH RFC v3 21/27] KVM: arm64: Support Z and P registers in
 streaming mode
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-21-05b018c1ffeb@kernel.org>

SME introduces a mode called streaming mode where the Z, P and optionally
FFR registers can be accessed using the SVE instructions but with the SME
vector length. Reflect this in the ABI for accessing the guest registers by
making the vector length for the vcpu reflect the vector length that would
be seen by the guest were it running, using the SME vector length when the
guest is configured for streaming mode.

Since SME may be present without SVE we also update the existing checks for
access to the Z, P and V registers to check for either SVE or streaming
mode. When not in streaming mode the guest floating point state may be
accessed via the V registers.

Any VMM that supports SME must be aware of the need to configure streaming
mode prior to writing the floating point registers that this creates.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  9 +++++++--
 arch/arm64/kvm/guest.c            | 38 ++++++++++++++++++++++++++++++++++----
 2 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f72024ffc89d955b3a0a20b6503ceb451abe824f..7393672fa0ee9c4ac13adb48a973f94929f767ea 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1017,16 +1017,18 @@ struct kvm_vcpu_arch {
 	size_t __size_ret;						\
 	unsigned int __vcpu_vq;						\
 									\
-	if (WARN_ON(!sve_vl_valid((vcpu)->arch.max_vl[ARM64_VEC_SVE]))) { \
+	if (WARN_ON(!sve_vl_valid(vcpu_max_vl(vcpu)))) {		\
 		__size_ret = 0;						\
 	} else {							\
-		__vcpu_vq = vcpu_sve_max_vq(vcpu);			\
+		__vcpu_vq = sve_vl_from_vq(vcpu_max_vl(vcpu));		\
 		__size_ret = SVE_SIG_REGS_SIZE(__vcpu_vq);		\
 	}								\
 									\
 	__size_ret;							\
 })
 
+#define vcpu_sme_state(vcpu) (kern_hyp_va((vcpu)->arch.sme_state))
+
 /*
  * Only use __vcpu_sys_reg/ctxt_sys_reg if you know you want the
  * memory backed version of a register, and not the one most recently
@@ -1583,4 +1585,7 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
 	(system_supports_sme() &&			\
 	 kvm_has_feat((k), ID_AA64PFR1_EL1, SME, SME2))
 
+#define vcpu_in_streaming_mode(vcpu) \
+	(__vcpu_sys_reg(vcpu, SVCR) & SVCR_SM_MASK)
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 8820cd42a27ac05874ed52c572c1dd9b29a77a1b..cf468ac93c9e75d642d7293e020d04c4267ffff4 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -73,6 +73,11 @@ static u64 core_reg_offset_from_id(u64 id)
 	return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE);
 }
 
+static bool vcpu_has_sve_regs(const struct kvm_vcpu *vcpu)
+{
+	return vcpu_has_sve(vcpu) || vcpu_in_streaming_mode(vcpu);
+}
+
 static int core_reg_size_from_offset(const struct kvm_vcpu *vcpu, u64 off)
 {
 	int size;
@@ -110,9 +115,10 @@ static int core_reg_size_from_offset(const struct kvm_vcpu *vcpu, u64 off)
 	/*
 	 * The KVM_REG_ARM64_SVE regs must be used instead of
 	 * KVM_REG_ARM_CORE for accessing the FPSIMD V-registers on
-	 * SVE-enabled vcpus:
+	 * SVE-enabled vcpus or when a SME enabled vcpu is in
+	 * streaming mode:
 	 */
-	if (vcpu_has_sve(vcpu) && core_reg_offset_is_vreg(off))
+	if (vcpu_has_sve_regs(vcpu) && core_reg_offset_is_vreg(off))
 		return -EINVAL;
 
 	return size;
@@ -426,6 +432,24 @@ struct vec_state_reg_region {
 	unsigned int upad;	/* extra trailing padding in user memory */
 };
 
+/*
+ * We represent the Z and P registers to userspace using either the
+ * SVE or SME vector length, depending on which features the guest has
+ * and if the guest is in streaming mode.
+ */
+static unsigned int vcpu_sve_cur_vq(struct kvm_vcpu *vcpu)
+{
+	unsigned int vq = 0;
+
+	if (vcpu_has_sve(vcpu))
+		vq = vcpu_sve_max_vq(vcpu);
+
+	if (vcpu_in_streaming_mode(vcpu))
+		vq = vcpu_sme_max_vq(vcpu);
+
+	return vq;
+}
+
 /*
  * Validate SVE register ID and get sanitised bounds for user/kernel SVE
  * register copy
@@ -466,7 +490,7 @@ static int sve_reg_to_region(struct vec_state_reg_region *region,
 		if (!vcpu_has_sve(vcpu) || (reg->id & SVE_REG_SLICE_MASK) > 0)
 			return -ENOENT;
 
-		vq = vcpu_sve_max_vq(vcpu);
+		vq = vcpu_sve_cur_vq(vcpu);
 
 		reqoffset = SVE_SIG_ZREG_OFFSET(vq, reg_num) -
 				SVE_SIG_REGS_OFFSET;
@@ -476,7 +500,7 @@ static int sve_reg_to_region(struct vec_state_reg_region *region,
 		if (!vcpu_has_sve(vcpu) || (reg->id & SVE_REG_SLICE_MASK) > 0)
 			return -ENOENT;
 
-		vq = vcpu_sve_max_vq(vcpu);
+		vq = vcpu_sve_cur_vq(vcpu);
 
 		reqoffset = SVE_SIG_PREG_OFFSET(vq, reg_num) -
 				SVE_SIG_REGS_OFFSET;
@@ -515,6 +539,9 @@ static int get_sve_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	if (!kvm_arm_vcpu_vec_finalized(vcpu))
 		return -EPERM;
 
+	if (!vcpu_has_sve_regs(vcpu))
+		return -EBUSY;
+
 	if (copy_to_user(uptr, vcpu->arch.sve_state + region.koffset,
 			 region.klen) ||
 	    clear_user(uptr + region.klen, region.upad))
@@ -541,6 +568,9 @@ static int set_sve_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	if (!kvm_arm_vcpu_vec_finalized(vcpu))
 		return -EPERM;
 
+	if (!vcpu_has_sve_regs(vcpu))
+		return -EBUSY;
+
 	if (copy_from_user(vcpu->arch.sve_state + region.koffset, uptr,
 			   region.klen))
 		return -EFAULT;

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:47 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:47 +0000
Subject: [PATCH RFC v3 22/27] KVM: arm64: Expose SME specific state to
 userspace
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-22-05b018c1ffeb@kernel.org>

SME introduces two new registers, the ZA matrix register and the ZT0 LUT
register.  Both of these registers are only accessible when PSTATE.ZA is
set and ZT0 is only present if SME2 is enabled for the guest. Provide
support for configuring these from VMMs.

The ZA matrix is a single SVL*SVL register which is available when
PSTATE.ZA is set. We follow the pattern established by the architecture
itself and expose this to userspace as a series of horizontal SVE vectors
with the streaming mode vector length, using the format already established
for the SVE vectors themselves.

ZT0 is a single register with a refreshingly fixed size 512 bit register
which is like ZA accessible only when PSTATE.ZA is set. Add support for it
to the userspace API, as with ZA we allow the register to be read or written
regardless of the state of PSTATE.ZA in order to simplify userspace usage.
The value will be reset to 0 whenever PSTATE.ZA changes from 0 to 1,
userspace can read stale values but these are not observable by the guest
without manipulation of PSTATE.ZA by userspace.

While there is currently only one ZT register the naming as ZT0 and the
instruction encoding clearly leave room for future extensions adding more
ZT registers. This encoding can readily support such an extension if one is
introduced.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  19 +++++++
 arch/arm64/include/uapi/asm/kvm.h |  17 ++++++
 arch/arm64/kvm/guest.c            | 114 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 148 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7393672fa0ee9c4ac13adb48a973f94929f767ea..3e064520a86f25fb7b1185b3aca342f593f04994 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1029,6 +1029,22 @@ struct kvm_vcpu_arch {
 
 #define vcpu_sme_state(vcpu) (kern_hyp_va((vcpu)->arch.sme_state))
 
+#define vcpu_sme_state_size(vcpu) ({					\
+	size_t __size_ret;						\
+	unsigned int __vcpu_vq;						\
+									\
+	if (WARN_ON(!sve_vl_valid((vcpu)->arch.max_vl[ARM64_VEC_SME]))) { \
+		__size_ret = 0;						\
+	} else {							\
+		__vcpu_vq = vcpu_sme_max_vq(vcpu);			\
+		__size_ret = ZA_SIG_REGS_SIZE(__vcpu_vq);		\
+		if (system_supports_sme2())				\
+			__size_ret += ZT_SIG_REG_SIZE;			\
+	}								\
+									\
+	__size_ret;							\
+})
+
 /*
  * Only use __vcpu_sys_reg/ctxt_sys_reg if you know you want the
  * memory backed version of a register, and not the one most recently
@@ -1588,4 +1604,7 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
 #define vcpu_in_streaming_mode(vcpu) \
 	(__vcpu_sys_reg(vcpu, SVCR) & SVCR_SM_MASK)
 
+#define vcpu_za_enabled(vcpu) \
+	(__vcpu_sys_reg(vcpu, SVCR) & SVCR_ZA_MASK)
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index efb384cf9d503007f68aad9233ba949128c94b8b..5092f39138cbf17d9e89191de23ab2ee9f3fa77d 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -359,6 +359,23 @@ struct kvm_arm_counter_offset {
 /* SME registers */
 #define KVM_REG_ARM64_SME		(0x17 << KVM_REG_ARM_COPROC_SHIFT)
 
+#define KVM_ARM64_SME_VQ_MIN __SVE_VQ_MIN
+#define KVM_ARM64_SME_VQ_MAX __SVE_VQ_MAX
+
+/* ZA and ZTn occupy blocks at the following offsets within this range: */
+#define KVM_REG_ARM64_SME_ZA_BASE	0
+#define KVM_REG_ARM64_SME_ZT_BASE	0x600
+
+#define KVM_ARM64_SME_MAX_ZAHREG	(__SVE_VQ_BYTES * KVM_ARM64_SME_VQ_MAX)
+
+#define KVM_REG_ARM64_SME_ZAHREG(n, i)					\
+	(KVM_REG_ARM64 | KVM_REG_ARM64_SME | KVM_REG_ARM64_SME_ZA_BASE | \
+	 KVM_REG_SIZE_U2048 |						\
+	 (((n) & (KVM_ARM64_SME_MAX_ZAHREG - 1)) << 5) |		\
+	 ((i) & (KVM_ARM64_SVE_MAX_SLICES - 1)))
+
+#define KVM_REG_ARM64_SME_ZTREG_SIZE	(512 / 8)
+
 /* Vector lengths pseudo-register: */
 #define KVM_REG_ARM64_SME_VLS		(KVM_REG_ARM64 | KVM_REG_ARM64_SME | \
 					 KVM_REG_SIZE_U512 | 0xffff)
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index cf468ac93c9e75d642d7293e020d04c4267ffff4..ad32f0f539be9acd5ff78412b369d4134b30559f 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -600,23 +600,133 @@ static int set_sme_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	return set_vec_vls(ARM64_VEC_SME, vcpu, reg);
 }
 
+/*
+ * Validate SVE register ID and get sanitised bounds for user/kernel SVE
+ * register copy
+ */
+static int sme_reg_to_region(struct vec_state_reg_region *region,
+			     struct kvm_vcpu *vcpu,
+			     const struct kvm_one_reg *reg)
+{
+	/* reg ID ranges for ZA.H[n] registers */
+	unsigned int vq = vcpu_sme_max_vq(vcpu) - 1;
+	const u64 za_h_max = vq * __SVE_VQ_BYTES;
+	const u64 zah_id_min = KVM_REG_ARM64_SME_ZAHREG(0, 0);
+	const u64 zah_id_max = KVM_REG_ARM64_SME_ZAHREG(za_h_max - 1,
+						       SVE_NUM_SLICES - 1);
+	unsigned int reg_num;
+
+	unsigned int reqoffset, reqlen; /* User-requested offset and length */
+	unsigned int maxlen; /* Maximum permitted length */
+
+	size_t sme_state_size;
+
+	reg_num = (reg->id & SVE_REG_ID_MASK) >> SVE_REG_ID_SHIFT;
+
+	if (reg->id >= zah_id_min && reg->id <= zah_id_max) {
+		if (!vcpu_has_sme(vcpu) || (reg->id & SVE_REG_SLICE_MASK) > 0)
+			return -ENOENT;
+
+		/* ZA is exposed as SVE vectors ZA.H[n] */
+		reqoffset = ZA_SIG_ZAV_OFFSET(vq, reg_num) -
+			ZA_SIG_REGS_OFFSET;
+		reqlen = KVM_SVE_ZREG_SIZE;
+		maxlen = SVE_SIG_ZREG_SIZE(vq);
+	} else if (reg->id == KVM_REG_ARM64_SME_ZT_BASE) {
+		/* ZA is exposed as SVE vectors ZA.H[n] */
+		if (!kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SME, SME2) ||
+		    (reg->id & SVE_REG_SLICE_MASK) > 0 ||
+		    reg_num > 0)
+			return -ENOENT;
+
+		/* ZT0 is stored after ZA */
+		reqlen = KVM_REG_ARM64_SME_ZTREG_SIZE;
+		maxlen = KVM_REG_ARM64_SME_ZTREG_SIZE;
+	} else {
+		return -EINVAL;
+	}
+
+	sme_state_size = vcpu_sme_state_size(vcpu);
+	if (WARN_ON(!sme_state_size))
+		return -EINVAL;
+
+	region->koffset = array_index_nospec(reqoffset, sme_state_size);
+	region->klen = min(maxlen, reqlen);
+	region->upad = reqlen - region->klen;
+
+	return 0;
+}
+
+/*
+ * ZA is exposed as an array of horizontal vectors with the same
+ * format as SVE, mirroring the architecture's LDR ZA[Wv, offs], [Xn]
+ * instruction.
+ */
+
 static int get_sme_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 {
+	int ret;
+	struct vec_state_reg_region region;
+	char __user *uptr = (char __user *)reg->addr;
+
 	/* Handle the KVM_REG_ARM64_SME_VLS pseudo-reg as a special case: */
 	if (reg->id == KVM_REG_ARM64_SME_VLS)
 		return get_sme_vls(vcpu, reg);
 
-	return -EINVAL;
+	/* Try to interpret reg ID as an architectural SME register... */
+	ret = sme_reg_to_region(&region, vcpu, reg);
+	if (ret)
+		return ret;
+
+	if (!kvm_arm_vcpu_vec_finalized(vcpu))
+		return -EPERM;
+
+	/*
+	 * None of the SME specific registers are accessible unless
+	 * PSTATE.ZA is set.
+	 */
+	if (!vcpu_za_enabled(vcpu))
+		return -EINVAL;
+
+	if (copy_from_user(vcpu->arch.sme_state + region.koffset, uptr,
+			   region.klen))
+		return -EFAULT;
+
+	return 0;
 }
 
 static int set_sme_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 {
+	int ret;
+	struct vec_state_reg_region region;
+	char __user *uptr = (char __user *)reg->addr;
+
 	/* Handle the KVM_REG_ARM64_SME_VLS pseudo-reg as a special case: */
 	if (reg->id == KVM_REG_ARM64_SME_VLS)
 		return set_sme_vls(vcpu, reg);
 
-	return -EINVAL;
+	/* Try to interpret reg ID as an architectural SME register... */
+	ret = sme_reg_to_region(&region, vcpu, reg);
+	if (ret)
+		return ret;
+
+	if (!kvm_arm_vcpu_vec_finalized(vcpu))
+		return -EPERM;
+
+	/*
+	 * None of the SME specific registers are accessible unless
+	 * PSTATE.ZA is set.
+	 */
+	if (!vcpu_za_enabled(vcpu))
+		return -EINVAL;
+
+	if (copy_from_user(vcpu->arch.sme_state + region.koffset, uptr,
+			   region.klen))
+		return -EFAULT;
+
+	return 0;
 }
+
 int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
 	return -EINVAL;

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:25 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:25 +0000
Subject: [PATCH RFC v3 00/27] KVM: arm64: Implement support for SME in
 non-protected guests
Message-ID: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>

Given the time of year and point in the release cycle this is an RFC
series, there's a few areas where I'm particularly expecting that people
might have feedback:

 - The userspace ABI, in particular:
  - The vector length used for the SVE registers, access to the SVE
    registers and access to ZA and (if available) ZT0 depending on
    the current state of PSTATE.{SM,ZA}.
  - The use of a single finalisation for both SVE and SME.

 - The addition of control for enabling fine grained traps in a similar
   manner to FGU but without the UNDEF, I'm not clear if this is desired
   at all and at present this requires symmetric read and write traps like
   FGU. That seemed like it might be desired from an implementation
   point of view but we already have one case where we enable an
   asymmetric trap (for ARM64_WORKAROUND_AMPERE_AC03_CPU_38) and it
   seems generally useful to enable asymmetrically.

There is some nested virtualisation support in the code but it is not
enabled or complete, this will be completed before the RFC tag is
removed. I am anticipating having a vastly better test environment soon
which will make this much easier to complete and there is no SME
specific ABI for nested virtualisation.

This series implements support for SME use in non-protected KVM guests.
Much of this is very similar to SVE, the main additional challenge that
SME presents is that it introduces a new vector length similar to the
SVE vector length and two new controls which change the registers seen
by guests:

 - PSTATE.ZA enables the ZA matrix register and, if SME2 is supported,
   the ZT0 LUT register.
 - PSTATE.SM enables streaming mode, a new floating point mode which
   uses the SVE register set with the separately configured SME vector
   length.  In streaming mode implementation of the FFR register is
   optional.

It is also permitted to build systems which support SME without SVE, in
this case when not in streaming mode no SVE registers or instructions
are available.  Further, there is no requirement that there be any
overlap in the set of vector lengths supported by SVE and SME in a
system, this is expected to be a common situation in practical systems.

Since there is a new vector length to configure we introduce a new
feature parallel to the existing SVE one with a new pseudo register for
the streaming mode vector length.  Due to the overlap with SVE caused by
streaming mode rather than finalising SME as a separate feature we use
the existing SVE finalisation to also finalise SME, a new define
KVM_ARM_VCPU_VEC is provided to help make user code clearer.  Finalising
SVE and SME separately would introduce complication with register access
since finalising SVE makes the SVE regsiters writeable by userspace and
doing multiple finalisations results in an error being reported.
Dealing with a state where the SVE registers are writeable due to one of
SVE or SME being finalised but may have their VL changed by the other
being finalised seems like needless complexity with minimal practical
utility, it seems clearer to just express directly that only one
finalisation can be done in the ABI.

Access to the floating point registers follows the architecture:

 - When both SVE and SME are present:
   - If PSTATE.SM == 0 the vector length used for the Z and P registers
     is the SVE vector length.
   - If PSTATE.SM == 1 the vector length used for the Z and P registers
     is the SME vector length.
 - If only SME is present:
   - If PSTATE.SM == 0 the Z and P registers are inaccessible and the
     floating point state accessed via the encodings for the V registers. 
   - If PSTATE.SM == 1 the vector length used for the Z and P registers
 - The SME specific ZA and ZT0 registers are only accessible if SVCR.ZA is 1.

The VMM must understand this, in particular when loading state SVCR
should be configured before other state.

There are a large number of subfeatures for SME, most of which only
offer additional instructions but some of which (SME2 and FA64) add
architectural state. These are configured via the ID registers as per
usual.

The new KVM_ARM_VCPU_VEC feature and ZA and ZT0 registers have not been
added to the get-reg-list selftest, the idea of supporting additional
features there without restructuring the program to generate all
possible feature combinations has been rejected.  I will post a separate
series which does that restructuring.

No support is present for protected guests, this is expected to be added
separately.

The series is based on Fuad's series:

  https://lore.kernel.org/r/20241216105057.579031-1-tabba at google.com/

It will need a rebase on:

  https://lore.kernel.org/r/20241219173351.1123087-1-maz at kernel.org

(as will Fuad's.)

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v3:
- Rebase onto v6.12-rc2.
- Link to v2: https://lore.kernel.org/r/20231222-kvm-arm64-sme-v2-0-da226cb180bb at kernel.org

Changes in v2:
- Rebase onto v6.7-rc3.
- Configure subfeatures based on host system only.
- Complete nVHE support.
- There was some snafu with sending v1 out, it didn't make it to the
  lists but in case it hit people's inboxes I'm sending as v2.

---
Mark Brown (27):
      arm64/fpsimd: Update FA64 and ZT0 enables when loading SME state
      arm64/fpsimd: Decide to save ZT0 and streaming mode FFR at bind time
      arm64/fpsimd: Check enable bit for FA64 when saving EFI state
      arm64/fpsimd: Determine maximum virtualisable SME vector length
      KVM: arm64: Introduce non-UNDEF FGT control
      KVM: arm64: Pull ctxt_has_ helpers to start of sysreg-sr.h
      KVM: arm64: Convert cpacr_clear_set() to a static inline
      KVM: arm64: Move SVE state access macros after feature test macros
      KVM: arm64: Factor SVE guest exit handling out into a function
      KVM: arm64: Rename SVE finalization constants to be more general
      KVM: arm64: Document the KVM ABI for SME
      KVM: arm64: Define internal features for SME
      KVM: arm64: Rename sve_state_reg_region
      KVM: arm64: Store vector lengths in an array
      KVM: arm64: Implement SME vector length configuration
      KVM: arm64: Add definitions for SME control register
      KVM: arm64: Support TPIDR2_EL0
      KVM: arm64: Support SMIDR_EL1 for guests
      KVM: arm64: Support SME priority registers
      KVM: arm64: Provide assembly for SME state restore
      KVM: arm64: Support Z and P registers in streaming mode
      KVM: arm64: Expose SME specific state to userspace
      KVM: arm64: Context switch SME state for normal guests
      KVM: arm64: Handle SME exceptions
      KVM: arm64: Provide interface for configuring and enabling SME for guests
      KVM: arm64: selftests: Add SME system registers to get-reg-list
      KVM: arm64: selftests: Add SME to set_id_regs test

 Documentation/virt/kvm/api.rst                     | 117 ++++++---
 arch/arm64/include/asm/fpsimd.h                    |  22 ++
 arch/arm64/include/asm/kvm_emulate.h               |  37 ++-
 arch/arm64/include/asm/kvm_host.h                  | 135 ++++++++---
 arch/arm64/include/asm/kvm_hyp.h                   |   4 +-
 arch/arm64/include/asm/kvm_pkvm.h                  |   2 +-
 arch/arm64/include/asm/vncr_mapping.h              |   2 +
 arch/arm64/include/uapi/asm/kvm.h                  |  33 +++
 arch/arm64/kernel/cpufeature.c                     |   2 -
 arch/arm64/kernel/fpsimd.c                         |  86 ++++---
 arch/arm64/kvm/arm.c                               |  10 +
 arch/arm64/kvm/fpsimd.c                            | 156 +++++++-----
 arch/arm64/kvm/guest.c                             | 262 ++++++++++++++++++---
 arch/arm64/kvm/handle_exit.c                       |  14 ++
 arch/arm64/kvm/hyp/fpsimd.S                        |  16 ++
 arch/arm64/kvm/hyp/include/hyp/switch.h            | 104 ++++++--
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h         |  47 ++--
 arch/arm64/kvm/hyp/nvhe/hyp-main.c                 |  17 +-
 arch/arm64/kvm/hyp/nvhe/pkvm.c                     |   4 +-
 arch/arm64/kvm/hyp/nvhe/switch.c                   |  11 +-
 arch/arm64/kvm/hyp/vhe/switch.c                    |  21 +-
 arch/arm64/kvm/reset.c                             | 154 +++++++++---
 arch/arm64/kvm/sys_regs.c                          | 118 +++++++++-
 include/uapi/linux/kvm.h                           |   1 +
 tools/testing/selftests/kvm/aarch64/get-reg-list.c |  32 ++-
 tools/testing/selftests/kvm/aarch64/set_id_regs.c  |  29 ++-
 26 files changed, 1117 insertions(+), 319 deletions(-)
---
base-commit: e32a80927434907f973f38a88cd19d7e51991d24
change-id: 20230301-kvm-arm64-sme-06a1246d3636
prerequisite-message-id: 20241216105057.579031-1-tabba at google.com
prerequisite-patch-id: 10a23279fc1aa942c363d66df0e95414342b614b
prerequisite-patch-id: 670db72b1987d2591e23db072fd27db7f65ffb0f
prerequisite-patch-id: c6bc6f799cebe5010bf3d734eb06e39d5dfab0d6
prerequisite-patch-id: 5555cde0b025483c2318d006a0324fd95bd06268
prerequisite-patch-id: a73738d5bbc5e694c92b7a5654f78eb79ed23c09
prerequisite-patch-id: 6194857db22ccaefe13e88b3155b6e761c9b7692
prerequisite-patch-id: 5dca3992c2ffa5bf2edb45f68be45edfae9b41b3
prerequisite-patch-id: b048e799d816c9c6750ed4f264fd38cb6e31f968
prerequisite-patch-id: 07fea6c2207f8cd2d35d4c171a97d28397db9a79
prerequisite-patch-id: f330e82665af9f223e838511bd4a95faad56e3ac
prerequisite-patch-id: 060a6061eaedb7fd02c18e898bfd9652c991b9af
prerequisite-patch-id: fc31d9f0e7812a8f962876fdb311414122895389
prerequisite-patch-id: ae675f63215a211c42a497789ee5e092fd461279
prerequisite-patch-id: ff3c533043a1fa3a13827ea5c70459b228aa95ee
prerequisite-patch-id: de489d2d73f49d74b75c628828a6b56dbac751e2
prerequisite-patch-id: 92f4a1249e3a1ff32eb16c25af56930762c5697d
prerequisite-patch-id: ac1248b4e10dce15672e02b366a359d634297877

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From nfraprado at collabora.com  Fri Dec 20 08:50:44 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Fri, 20 Dec 2024 13:50:44 -0300
Subject: [PATCH] arm64: defconfig: Enable MediaTek STAR Ethernet MAC
Message-ID: <20241220-mt8365-eth-config-v1-1-7f3ffae35fd6@collabora.com>

Enable CONFIG_NET_VENDOR_MEDIATEK and CONFIG_NET_MEDIATEK_STAR_EMAC in
the defconfig to allow usage of the Ethernet controller on the MT8365
SoC.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index dfa5c8d5b65863741be7d7d3c6f6f05567d336da..0de2dcb5799f4b405fbfdfd9f2d0afdd053d0c07 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -360,6 +360,8 @@ CONFIG_IGBVF=y
 CONFIG_MVNETA=y
 CONFIG_MVPP2=y
 CONFIG_SKY2=y
+CONFIG_NET_VENDOR_MEDIATEK=y
+CONFIG_NET_MEDIATEK_STAR_EMAC=m
 CONFIG_MLX4_EN=m
 CONFIG_MLX5_CORE=m
 CONFIG_MLX5_CORE_EN=y

---
base-commit: e25c8d66f6786300b680866c0e0139981273feba
change-id: 20241220-mt8365-eth-config-23ef81e5d938

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From broonie at kernel.org  Fri Dec 20 08:46:26 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:26 +0000
Subject: [PATCH RFC v3 01/27] arm64/fpsimd: Update FA64 and ZT0 enables
 when loading SME state
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-1-05b018c1ffeb@kernel.org>

Currently we enable EL0 and EL1 access to FA64 and ZT0 at boot and leave
them enabled throughout the runtime of the system. When we add KVM support
we will need to make this configuration dynamic, these features may be
disabled for some KVM guests. Since the host kernel saves the floating
point state for non-protected guests and we wish to avoid KVM having to
reload the floating point state needlessly on guest reentry let's move the
configuration of these enables to the floating point state reload.

We provide a helper which does the configuration as part of a
read/modify/write operation along with the configuration of the task VL,
then update the floating point state load and SME access trap to use it.
We also remove the setting of the enable bits from the CPU feature
identification and resume paths.  There will be a small overhead from
setting the enables one at a time but this should be negligable in the
context of the state load or access trap.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h | 12 +++++++++++
 arch/arm64/kernel/cpufeature.c  |  2 --
 arch/arm64/kernel/fpsimd.c      | 44 ++++++++++++-----------------------------
 3 files changed, 25 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index f2a84efc361858d4deda99faf1967cc7cac386c1..95355892d47b3ec1c77a3ab19ccad0d7f9a8d621 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -429,6 +429,18 @@ static inline size_t sme_state_size(struct task_struct const *task)
 
 #endif /* ! CONFIG_ARM64_SME */
 
+#define sme_cond_update_smcr(vl, fa64, zt0, reg)		\
+	do {							\
+		u64 __old = read_sysreg_s((reg));		\
+		u64 __new = vl;					\
+		if (fa64)			\
+			__new |= SMCR_ELx_FA64;			\
+		if (zt0)					\
+			__new |= SMCR_ELx_EZT0;			\
+		if (__old != __new)				\
+			write_sysreg_s(__new, (reg));		\
+	} while (0)
+
 /* For use by EFI runtime services calls only */
 extern void __efi_fpsimd_begin(void);
 extern void __efi_fpsimd_end(void);
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6ce71f444ed84f9056196bb21bbfac61c9687e30..ab669ef8244eea70d9e20024d5584d2e960389dc 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2848,7 +2848,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
 		.capability = ARM64_SME_FA64,
 		.matches = has_cpuid_feature,
-		.cpu_enable = cpu_enable_fa64,
 		ARM64_CPUID_FIELDS(ID_AA64SMFR0_EL1, FA64, IMP)
 	},
 	{
@@ -2856,7 +2855,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
 		.capability = ARM64_SME2,
 		.matches = has_cpuid_feature,
-		.cpu_enable = cpu_enable_sme2,
 		ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, SME, SME2)
 	},
 #endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 8c4c1a2186cc510a7826d15ec36225857c07ed71..92c085288ed2cbc4f51f49546c6abbde6ba891a3 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -399,9 +399,15 @@ static void task_fpsimd_load(void)
 	if (system_supports_sme()) {
 		unsigned long sme_vl = task_get_sme_vl(current);
 
-		/* Ensure VL is set up for restoring data */
+		/*
+		 * Ensure VL is set up for restoring data.  KVM might
+		 * disable subfeatures so we reset them each time.
+		 */
 		if (test_thread_flag(TIF_SME))
-			sme_set_vq(sve_vq_from_vl(sme_vl) - 1);
+			sme_cond_update_smcr(sve_vq_from_vl(sme_vl) - 1,
+					     system_supports_fa64(),
+					     system_supports_sme2(),
+					     SYS_SMCR_EL1);
 
 		write_sysreg_s(current->thread.svcr, SYS_SVCR);
 
@@ -1267,26 +1273,6 @@ void cpu_enable_sme(const struct arm64_cpu_capabilities *__always_unused p)
 	isb();
 }
 
-void cpu_enable_sme2(const struct arm64_cpu_capabilities *__always_unused p)
-{
-	/* This must be enabled after SME */
-	BUILD_BUG_ON(ARM64_SME2 <= ARM64_SME);
-
-	/* Allow use of ZT0 */
-	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_EZT0_MASK,
-		       SYS_SMCR_EL1);
-}
-
-void cpu_enable_fa64(const struct arm64_cpu_capabilities *__always_unused p)
-{
-	/* This must be enabled after SME */
-	BUILD_BUG_ON(ARM64_SME_FA64 <= ARM64_SME);
-
-	/* Allow use of FA64 */
-	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_FA64_MASK,
-		       SYS_SMCR_EL1);
-}
-
 void __init sme_setup(void)
 {
 	struct vl_info *info = &vl_info[ARM64_VEC_SME];
@@ -1330,17 +1316,9 @@ void __init sme_setup(void)
 
 void sme_suspend_exit(void)
 {
-	u64 smcr = 0;
-
 	if (!system_supports_sme())
 		return;
 
-	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);
 }
 
@@ -1457,7 +1435,11 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
 	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
 		unsigned long vq_minus_one =
 			sve_vq_from_vl(task_get_sme_vl(current)) - 1;
-		sme_set_vq(vq_minus_one);
+
+		sme_cond_update_smcr(vq_minus_one,
+				     system_supports_fa64(),
+				     system_supports_sme2(),
+				     SYS_SMCR_EL1);
 
 		fpsimd_bind_task_to_cpu();
 	}

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:27 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:27 +0000
Subject: [PATCH RFC v3 02/27] arm64/fpsimd: Decide to save ZT0 and
 streaming mode FFR at bind time
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-2-05b018c1ffeb@kernel.org>

Some parts of the SME state are optional, enabled by additional features
on top of the base FEAT_SME and controlled with enable bits in SMCR_ELx. We
unconditionally enable these for the host but for KVM we will allow the
feature set exposed to guests to be restricted by the VMM. These are the
FFR register (FEAT_SME_FA64) and ZT0 (FEAT_SME2).

We defer saving of guest floating point state for non-protected guests to
the host kernel. We also want to avoid having to reconfigure the guest
floating point state if nothing used the floating point state while running
the host. If the guest was running with the optional features disabled then
traps will be enabled for them so the host kernel will need to skip
accessing that state when saving state for the guest.

Support this by moving the decision about saving this state to the point
where we bind floating point state to the CPU, adding a new variable to
the cpu_fp_state which uses the enable bits in SMCR_ELx to flag which
features are enabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h |  1 +
 arch/arm64/kernel/fpsimd.c      | 10 ++++++++--
 arch/arm64/kvm/fpsimd.c         |  1 +
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 95355892d47b3ec1c77a3ab19ccad0d7f9a8d621..144cc805bfea112341b89c9c6028cf4b2a201c6c 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -88,6 +88,7 @@ struct cpu_fp_state {
 	void *sme_state;
 	u64 *svcr;
 	u64 *fpmr;
+	u64 sme_features;
 	unsigned int sve_vl;
 	unsigned int sme_vl;
 	enum fp_type *fp_type;
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 92c085288ed2cbc4f51f49546c6abbde6ba891a3..7c66ed6e43c34d1b5e1cc00595c12244d13d3d0d 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -478,12 +478,12 @@ static void fpsimd_save_user_state(void)
 
 		if (*svcr & SVCR_ZA_MASK)
 			sme_save_state(last->sme_state,
-				       system_supports_sme2());
+				       last->sme_features & SMCR_ELx_EZT0);
 
 		/* If we are in streaming mode override regular SVE. */
 		if (*svcr & SVCR_SM_MASK) {
 			save_sve_regs = true;
-			save_ffr = system_supports_fa64();
+			save_ffr = last->sme_features & SMCR_ELx_FA64;
 			vl = last->sme_vl;
 		}
 	}
@@ -1722,6 +1722,12 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->to_save = FP_STATE_CURRENT;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
+	last->sme_features = 0;
+	if (system_supports_fa64())
+		last->sme_features |= SMCR_ELx_FA64;
+	if (system_supports_sme2())
+		last->sme_features |= SMCR_ELx_EZT0;
+
 	/*
 	 * Toggle SVE and SME trapping for userspace if needed, these
 	 * are serialsied by ret_to_user().
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index ea5484ce1f3ba3121b6938bda15f7a8057d49051..09b65abaf9db60cc57dbc554ad2108a80c2dc46b 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -138,6 +138,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 		fp_state.svcr = &__vcpu_sys_reg(vcpu, SVCR);
 		fp_state.fpmr = &__vcpu_sys_reg(vcpu, FPMR);
 		fp_state.fp_type = &vcpu->arch.fp_type;
+		fp_state.sme_features = 0;
 
 		if (vcpu_has_sve(vcpu))
 			fp_state.to_save = FP_STATE_SVE;

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:28 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:28 +0000
Subject: [PATCH RFC v3 03/27] arm64/fpsimd: Check enable bit for FA64 when
 saving EFI state
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-3-05b018c1ffeb@kernel.org>

Currently when deciding if we need to save FFR when in streaming mode prior
to EFI calls we check if FA64 is supported by the system. Since KVM guest
support will mean that FA64 might be enabled and disabled at runtime switch
to checking if traps for FA64 are enabled in SMCR_EL1 instead.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 7c66ed6e43c34d1b5e1cc00595c12244d13d3d0d..a6f9a102fadb0547b4988cb5b0c239ca90a262a0 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1980,6 +1980,11 @@ static DEFINE_PER_CPU(bool, efi_sm_state);
  * either doing something wrong or you need to propose some refactoring.
  */
 
+static bool fa64_enabled(void)
+{
+	return read_sysreg_s(SYS_SMCR_EL1) & SMCR_ELx_FA64;
+}
+
 /*
  * __efi_fpsimd_begin(): prepare FPSIMD for making an EFI runtime services call
  */
@@ -2014,7 +2019,7 @@ void __efi_fpsimd_begin(void)
 				 * Unless we have FA64 FFR does not
 				 * exist in streaming mode.
 				 */
-				if (!system_supports_fa64())
+				if (!fa64_enabled())
 					ffr = !(svcr & SVCR_SM_MASK);
 			}
 
@@ -2065,7 +2070,7 @@ void __efi_fpsimd_end(void)
 					 * Unless we have FA64 FFR does not
 					 * exist in streaming mode.
 					 */
-					if (!system_supports_fa64())
+					if (!fa64_enabled())
 						ffr = false;
 				}
 			}

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:29 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:29 +0000
Subject: [PATCH RFC v3 04/27] arm64/fpsimd: Determine maximum virtualisable
 SME vector length
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-4-05b018c1ffeb@kernel.org>

As with SVE we can only virtualise SME vector lengths that are supported by
all CPUs in the system, implement similar checks to those for SVE. Since
unlike SVE there are no specific vector lengths that are architecturally
required the handling is subtly different, we report a system where this
happens with a maximum vector length of -1.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a6f9a102fadb0547b4988cb5b0c239ca90a262a0..d976708d84854846fe38a35a19c60ff36f44030a 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1276,7 +1276,8 @@ void cpu_enable_sme(const struct arm64_cpu_capabilities *__always_unused p)
 void __init sme_setup(void)
 {
 	struct vl_info *info = &vl_info[ARM64_VEC_SME];
-	int min_bit, max_bit;
+	DECLARE_BITMAP(tmp_map, SVE_VQ_MAX);
+	int min_bit, max_bit, b;
 
 	if (!system_supports_sme())
 		return;
@@ -1306,12 +1307,32 @@ void __init sme_setup(void)
 	 */
 	set_sme_default_vl(find_supported_vector_length(ARM64_VEC_SME, 32));
 
+	bitmap_andnot(tmp_map, info->vq_partial_map, info->vq_map,
+		      SVE_VQ_MAX);
+
+	b = find_last_bit(tmp_map, SVE_VQ_MAX);
+	if (b >= SVE_VQ_MAX)
+		/* All VLs virtualisable */
+		info->max_virtualisable_vl = SVE_VQ_MAX;
+	else if (b == SVE_VQ_MAX - 1)
+		/* No virtualisable VLs */
+		info->max_virtualisable_vl = -1;
+	else
+		info->max_virtualisable_vl = sve_vl_from_vq(__bit_to_vq(b +  1));
+
+	if (info->max_virtualisable_vl > info->max_vl)
+		info->max_virtualisable_vl = info->max_vl;
+
 	pr_info("SME: minimum available vector length %u bytes per vector\n",
 		info->min_vl);
 	pr_info("SME: maximum available vector length %u bytes per vector\n",
 		info->max_vl);
 	pr_info("SME: default vector length %u bytes per vector\n",
 		get_sme_default_vl());
+
+	/* KVM decides whether to support mismatched systems. Just warn here: */
+	if (info->max_virtualisable_vl < info->max_vl)
+		pr_warn("SME: unvirtualisable vector lengths present\n");
 }
 
 void sme_suspend_exit(void)

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:30 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:30 +0000
Subject: [PATCH RFC v3 05/27] KVM: arm64: Introduce non-UNDEF FGT control
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-5-05b018c1ffeb@kernel.org>

We have support for determining a set of fine grained traps to enable for
the guest which is tied to the support for injecting UNDEFs for undefined
features. This means that we can't use the mechanism for system registers
which should be present but need emulation, such as SMPRI_EL1 which should
be accessible when SME is present but if SME priority support is absent
SMPRI_EL1.Priority should be RAZ.

Add an additional set of fine grained traps fgt, mirroring the existing fgu
array. We use the same format where we always set the bit for the trap in
the array as for FGU. This makes it clear what is being explicitly managed
and keeps the code consistent.

We do not convert the handling of ARM_WORKAROUND_AMPERE_ACO3_CPU_38 to this
mechanism since this only enables a write trap and when implementing the
existing UNDEF that we would share the read and write trap enablement (this
being the overwhelmingly common case).

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h       | 6 ++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h | 7 ++++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7ba742b9067e0216a156eebb3e5ea6bb69239a44..fca81ede6140c0ee7d03cb6ca8f5eead45b87033 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -288,6 +288,12 @@ struct kvm_arch {
 	 */
 	u64 fgu[__NR_FGT_GROUP_IDS__];
 
+	/*
+	 * Additional FGTs to enable for the guests, eg. for emulated
+	 * registers,
+	 */
+	u64 fgt[__NR_FGT_GROUP_IDS__];
+
 	/*
 	 * Stage 2 paging state for VMs with nested S2 using a virtual
 	 * VMID.
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 34f53707892dfe7bba41620e7adb65f1f8376018..247dfadcdb22e1ef96f92a9d86e66c9eefb44600 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -98,9 +98,9 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
 		id;							\
 	})
 
-#define compute_undef_clr_set(vcpu, kvm, reg, clr, set)			\
+#define compute_trap_clr_set(vcpu, kvm, trap, reg, clr, set)		\
 	do {								\
-		u64 hfg = kvm->arch.fgu[reg_to_fgt_group_id(reg)];	\
+		u64 hfg = kvm->arch.trap[reg_to_fgt_group_id(reg)];	\
 		set |= hfg & __ ## reg ## _MASK;			\
 		clr |= hfg & __ ## reg ## _nMASK; 			\
 	} while(0)
@@ -113,7 +113,8 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
 		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);		\
+		compute_trap_clr_set(vcpu, kvm, fgu, reg, c, s);	\
+		compute_trap_clr_set(vcpu, kvm, fgt, reg, c, s);	\
 									\
 		s |= set;						\
 		c |= clr;						\

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:31 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:31 +0000
Subject: [PATCH RFC v3 06/27] KVM: arm64: Pull ctxt_has_ helpers to start
 of sysreg-sr.h
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-6-05b018c1ffeb@kernel.org>

Rather than add earlier prototypes of specific ctxt_has_ helpers let's just
pull all their definitions to the top of sysreg-sr.h so they're all
available to all the individual save/restore functions.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 32 ++++++++++++++----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index a651c43ad679fcc5a13ab7a619e252d96fd46281..8c234d53acb2753c59aa37d7a66f856f2eb87882 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -16,23 +16,6 @@
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
 
-static inline bool ctxt_has_s1poe(struct kvm_cpu_context *ctxt);
-
-static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
-{
-	ctxt_sys_reg(ctxt, MDSCR_EL1)	= read_sysreg(mdscr_el1);
-
-	// POR_EL0 can affect uaccess, so must be saved/restored early.
-	if (ctxt_has_s1poe(ctxt))
-		ctxt_sys_reg(ctxt, POR_EL0)	= read_sysreg_s(SYS_POR_EL0);
-}
-
-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);
-}
-
 static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt)
 {
 	struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu;
@@ -83,6 +66,21 @@ static inline bool ctxt_has_s1poe(struct kvm_cpu_context *ctxt)
 	return kvm_has_s1poe(kern_hyp_va(vcpu->kvm));
 }
 
+static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
+{
+	ctxt_sys_reg(ctxt, MDSCR_EL1)	= read_sysreg(mdscr_el1);
+
+	// POR_EL0 can affect uaccess, so must be saved/restored early.
+	if (ctxt_has_s1poe(ctxt))
+		ctxt_sys_reg(ctxt, POR_EL0)	= read_sysreg_s(SYS_POR_EL0);
+}
+
+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);
+}
+
 static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
 {
 	ctxt_sys_reg(ctxt, SCTLR_EL1)	= read_sysreg_el1(SYS_SCTLR);

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:32 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:32 +0000
Subject: [PATCH RFC v3 07/27] KVM: arm64: Convert cpacr_clear_set() to a
 static inline
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-7-05b018c1ffeb@kernel.org>

Currently cpacr_clear_set() is defined as a macro in order to allow it to
include a number of build time asserts that the bits being set and cleared
are appropriate. While this check is welcome it only works when the
arguments are constant which starts to scale poorly as we add SME unless we
do multiple updates of the system register.

Convert the function to a static inline so that it can accept runtime
variable arguments.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h | 27 +++++++++------------------
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 2d91fb88298a263dcd73a4269318f8edf1379650..5f05da7f538d29d321c424233f21b8448d8b4628 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -592,24 +592,15 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
 		cptr;							\
 	})
 
-#define cpacr_clear_set(clr, set)					\
-	do {								\
-		BUILD_BUG_ON((set) & CPTR_VHE_EL2_RES0);		\
-		BUILD_BUG_ON((clr) & CPACR_ELx_E0POE);			\
-		__build_check_all_or_none((clr), CPACR_ELx_FPEN);	\
-		__build_check_all_or_none((set), CPACR_ELx_FPEN);	\
-		__build_check_all_or_none((clr), CPACR_ELx_ZEN);	\
-		__build_check_all_or_none((set), CPACR_ELx_ZEN);	\
-		__build_check_all_or_none((clr), CPACR_ELx_SMEN);	\
-		__build_check_all_or_none((set), CPACR_ELx_SMEN);	\
-									\
-		if (has_vhe() || has_hvhe())				\
-			sysreg_clear_set(cpacr_el1, clr, set);		\
-		else							\
-			sysreg_clear_set(cptr_el2,			\
-					 __cpacr_to_cptr_clr(clr, set),	\
-					 __cpacr_to_cptr_set(clr, set));\
-	} while (0)
+static __always_inline void cpacr_clear_set(u64 clr, u64 set)
+{
+	if (has_vhe() || has_hvhe())
+		sysreg_clear_set(cpacr_el1, clr, set);
+	else
+		sysreg_clear_set(cptr_el2,
+				 __cpacr_to_cptr_clr(clr, set),
+				 __cpacr_to_cptr_set(clr, set));
+}
 
 static __always_inline void kvm_write_cptr_el2(u64 val)
 {

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:33 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:33 +0000
Subject: [PATCH RFC v3 08/27] KVM: arm64: Move SVE state access macros
 after feature test macros
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-8-05b018c1ffeb@kernel.org>

In preparation for SME support move the macros used to access SVE state
after the feature test macros, we will need to test for SME subfeatures to
determine the size of the SME state.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 46 +++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index fca81ede6140c0ee7d03cb6ca8f5eead45b87033..97b617606221e8c11fd2b55d9636848d8453209f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -934,29 +934,6 @@ struct kvm_vcpu_arch {
 #define IN_WFI			__vcpu_single_flag(sflags, BIT(7))
 
 
-/* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
-#define vcpu_sve_pffr(vcpu) (kern_hyp_va((vcpu)->arch.sve_state) +	\
-			     sve_ffr_offset((vcpu)->arch.sve_max_vl))
-
-#define vcpu_sve_max_vq(vcpu)	sve_vq_from_vl((vcpu)->arch.sve_max_vl)
-
-#define vcpu_sve_zcr_elx(vcpu)						\
-	(unlikely(is_hyp_ctxt(vcpu)) ? ZCR_EL2 : ZCR_EL1)
-
-#define vcpu_sve_state_size(vcpu) ({					\
-	size_t __size_ret;						\
-	unsigned int __vcpu_vq;						\
-									\
-	if (WARN_ON(!sve_vl_valid((vcpu)->arch.sve_max_vl))) {		\
-		__size_ret = 0;						\
-	} else {							\
-		__vcpu_vq = vcpu_sve_max_vq(vcpu);			\
-		__size_ret = SVE_SIG_REGS_SIZE(__vcpu_vq);		\
-	}								\
-									\
-	__size_ret;							\
-})
-
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
 				 KVM_GUESTDBG_USE_SW_BP | \
 				 KVM_GUESTDBG_USE_HW | \
@@ -992,6 +969,29 @@ struct kvm_vcpu_arch {
 
 #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.regs)
 
+/* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
+#define vcpu_sve_pffr(vcpu) (kern_hyp_va((vcpu)->arch.sve_state) +	\
+			     sve_ffr_offset((vcpu)->arch.sve_max_vl))
+
+#define vcpu_sve_max_vq(vcpu)	sve_vq_from_vl((vcpu)->arch.sve_max_vl)
+
+#define vcpu_sve_zcr_elx(vcpu)						\
+	(unlikely(is_hyp_ctxt(vcpu)) ? ZCR_EL2 : ZCR_EL1)
+
+#define vcpu_sve_state_size(vcpu) ({					\
+	size_t __size_ret;						\
+	unsigned int __vcpu_vq;						\
+									\
+	if (WARN_ON(!sve_vl_valid((vcpu)->arch.sve_max_vl))) {		\
+		__size_ret = 0;						\
+	} else {							\
+		__vcpu_vq = vcpu_sve_max_vq(vcpu);			\
+		__size_ret = SVE_SIG_REGS_SIZE(__vcpu_vq);		\
+	}								\
+									\
+	__size_ret;							\
+})
+
 /*
  * Only use __vcpu_sys_reg/ctxt_sys_reg if you know you want the
  * memory backed version of a register, and not the one most recently

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:34 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:34 +0000
Subject: [PATCH RFC v3 09/27] KVM: arm64: Factor SVE guest exit handling
 out into a function
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-9-05b018c1ffeb@kernel.org>

The SVE portion of kvm_vcpu_put() is quite large, especially given the
comments required.  When we add similar handling for SME the function
will get even larger, in order to keep things managable factor the SVE
portion out of the main kvm_vcpu_put().

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/fpsimd.c | 67 +++++++++++++++++++++++++++----------------------
 1 file changed, 37 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 09b65abaf9db60cc57dbc554ad2108a80c2dc46b..3c2e0b96877ac5b4f3b9d8dfa38975f11b74b60d 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -151,6 +151,41 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 	}
 }
 
+static void kvm_vcpu_put_sve(struct kvm_vcpu *vcpu)
+{
+	u64 zcr;
+
+	if (!vcpu_has_sve(vcpu))
+		return;
+
+	zcr = read_sysreg_el1(SYS_ZCR);
+
+	/*
+	 * If the vCPU is in the hyp context then ZCR_EL1 is loaded
+	 * with its vEL2 counterpart.
+	 */
+	__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)) = zcr;
+
+	/*
+	 * Restore the VL that was saved when bound to the CPU, which
+	 * is the maximum VL for the guest. Because the layout of the
+	 * data when saving the sve state depends on the VL, we need
+	 * to use a consistent (i.e., the maximum) VL.  Note that this
+	 * means that at guest exit ZCR_EL1 is not necessarily the
+	 * same as on guest entry.
+	 *
+	 * ZCR_EL2 holds the guest hypervisor's VL when running a
+	 * nested guest, which could be smaller than the max for the
+	 * vCPU. Similar to above, we first need to switch to a VL
+	 * consistent with the layout of the vCPU's SVE state. KVM
+	 * support for NV implies VHE, so using the ZCR_EL1 alias is
+	 * safe.
+	 */
+	if (!has_vhe() || (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)))
+		sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1,
+				       SYS_ZCR_EL1);
+}
+
 /*
  * Write back the vcpu FPSIMD regs if they are dirty, and invalidate the
  * cpu FPSIMD regs so that they can't be spuriously reused if this vcpu
@@ -179,38 +214,10 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 	}
 
 	if (guest_owns_fp_regs()) {
-		if (vcpu_has_sve(vcpu)) {
-			u64 zcr = read_sysreg_el1(SYS_ZCR);
-
-			/*
-			 * If the vCPU is in the hyp context then ZCR_EL1 is
-			 * loaded with its vEL2 counterpart.
-			 */
-			__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)) = zcr;
-
-			/*
-			 * Restore the VL that was saved when bound to the CPU,
-			 * which is the maximum VL for the guest. Because the
-			 * layout of the data when saving the sve state depends
-			 * on the VL, we need to use a consistent (i.e., the
-			 * maximum) VL.
-			 * Note that this means that at guest exit ZCR_EL1 is
-			 * not necessarily the same as on guest entry.
-			 *
-			 * ZCR_EL2 holds the guest hypervisor's VL when running
-			 * a nested guest, which could be smaller than the
-			 * max for the vCPU. Similar to above, we first need to
-			 * switch to a VL consistent with the layout of the
-			 * vCPU's SVE state. KVM support for NV implies VHE, so
-			 * using the ZCR_EL1 alias is safe.
-			 */
-			if (!has_vhe() || (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)))
-				sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1,
-						       SYS_ZCR_EL1);
-		}
+		kvm_vcpu_put_sve(vcpu);
 
 		/*
-		 * Flush (save and invalidate) the fpsimd/sve state so that if
+		 * Flush (save and invalidate) the FP state so that if
 		 * the host tries to use fpsimd/sve, it's not using stale data
 		 * from the guest.
 		 *

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:35 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:35 +0000
Subject: [PATCH RFC v3 10/27] KVM: arm64: Rename SVE finalization constants
 to be more general
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-10-05b018c1ffeb@kernel.org>

Due to the overlap between SVE and SME vector length configuration
created by streaming mode SVE we will finalize both at once.  Rename the
existing finalization to use _VEC (vector) for the naming to avoid
confusion.

Since this includes the userspace API we create an alias
KVM_ARM_VCPU_VEC for the existing KVM_ARM_VCPU_SVE capability, existing
code which does not enable SME will be unaffected and any SME only code
will not need to use SVE constants.

No functional change.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  6 ++++--
 arch/arm64/include/uapi/asm/kvm.h |  6 ++++++
 arch/arm64/kvm/guest.c            | 10 +++++-----
 arch/arm64/kvm/hyp/nvhe/pkvm.c    |  2 +-
 arch/arm64/kvm/reset.c            | 20 ++++++++++----------
 5 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 97b617606221e8c11fd2b55d9636848d8453209f..f64ad573573cf000c4644f12f9e072a2fdfc3824 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -873,7 +873,7 @@ struct kvm_vcpu_arch {
 /* KVM_ARM_VCPU_INIT completed */
 #define VCPU_INITIALIZED	__vcpu_single_flag(cflags, BIT(0))
 /* SVE config completed */
-#define VCPU_SVE_FINALIZED	__vcpu_single_flag(cflags, BIT(1))
+#define VCPU_VEC_FINALIZED	__vcpu_single_flag(cflags, BIT(1))
 
 /* Exception pending */
 #define PENDING_EXCEPTION	__vcpu_single_flag(iflags, BIT(0))
@@ -948,6 +948,8 @@ struct kvm_vcpu_arch {
 #define vcpu_has_sve(vcpu)	kvm_has_sve((vcpu)->kvm)
 #endif
 
+#define vcpu_has_vec(vcpu) vcpu_has_sve(vcpu)
+
 #ifdef CONFIG_ARM64_PTR_AUTH
 #define vcpu_has_ptrauth(vcpu)						\
 	((cpus_have_final_cap(ARM64_HAS_ADDRESS_AUTH) ||		\
@@ -1414,7 +1416,7 @@ struct kvm *kvm_arch_alloc_vm(void);
 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
 bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
 
-#define kvm_arm_vcpu_sve_finalized(vcpu) vcpu_get_flag(vcpu, VCPU_SVE_FINALIZED)
+#define kvm_arm_vcpu_vec_finalized(vcpu) vcpu_get_flag(vcpu, VCPU_VEC_FINALIZED)
 
 #define kvm_has_mte(kvm)					\
 	(system_supports_mte() &&				\
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 66736ff04011e0fa9fcfb74154d5613bf4ee89f7..9d80d22af9d4e00204f5096fb7c8c2ee8c3646c1 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -109,6 +109,12 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_PTRAUTH_GENERIC	6 /* VCPU uses generic authentication */
 #define KVM_ARM_VCPU_HAS_EL2		7 /* Support nested virtualization */
 
+/*
+ * An alias for _SVE since we finalize VL configuration for both SVE and SME
+ * simultaneously.
+ */
+#define KVM_ARM_VCPU_VEC		KVM_ARM_VCPU_SVE
+
 struct kvm_vcpu_init {
 	__u32 target;
 	__u32 features[7];
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 12dad841f2a51276eee4d4da7400c1b2a5732ff8..62ff51d6e4584acc71205f5d4b1d2f3d2e2d2f88 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -342,7 +342,7 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	if (!vcpu_has_sve(vcpu))
 		return -ENOENT;
 
-	if (kvm_arm_vcpu_sve_finalized(vcpu))
+	if (kvm_arm_vcpu_vec_finalized(vcpu))
 		return -EPERM; /* too late! */
 
 	if (WARN_ON(vcpu->arch.sve_state))
@@ -497,7 +497,7 @@ static int get_sve_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	if (ret)
 		return ret;
 
-	if (!kvm_arm_vcpu_sve_finalized(vcpu))
+	if (!kvm_arm_vcpu_vec_finalized(vcpu))
 		return -EPERM;
 
 	if (copy_to_user(uptr, vcpu->arch.sve_state + region.koffset,
@@ -523,7 +523,7 @@ static int set_sve_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	if (ret)
 		return ret;
 
-	if (!kvm_arm_vcpu_sve_finalized(vcpu))
+	if (!kvm_arm_vcpu_vec_finalized(vcpu))
 		return -EPERM;
 
 	if (copy_from_user(vcpu->arch.sve_state + region.koffset, uptr,
@@ -657,7 +657,7 @@ static unsigned long num_sve_regs(const struct kvm_vcpu *vcpu)
 		return 0;
 
 	/* Policed by KVM_GET_REG_LIST: */
-	WARN_ON(!kvm_arm_vcpu_sve_finalized(vcpu));
+	WARN_ON(!kvm_arm_vcpu_vec_finalized(vcpu));
 
 	return slices * (SVE_NUM_PREGS + SVE_NUM_ZREGS + 1 /* FFR */)
 		+ 1; /* KVM_REG_ARM64_SVE_VLS */
@@ -675,7 +675,7 @@ static int copy_sve_reg_indices(const struct kvm_vcpu *vcpu,
 		return 0;
 
 	/* Policed by KVM_GET_REG_LIST: */
-	WARN_ON(!kvm_arm_vcpu_sve_finalized(vcpu));
+	WARN_ON(!kvm_arm_vcpu_vec_finalized(vcpu));
 
 	/*
 	 * Enumerate this first, so that userspace can save/restore in
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 446a9114b0d3ee4323a9cd8d618d36035e85e4d0..0a4e1f5105592b23a0505bf7680c66e76b5c2a65 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -314,7 +314,7 @@ static void pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *
 	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
 
 	if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE))
-		vcpu_clear_flag(vcpu, VCPU_SVE_FINALIZED);
+		vcpu_clear_flag(vcpu, VCPU_VEC_FINALIZED);
 }
 
 static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 803e11b0dc8f5eb74b07b0ad745b0c4f666713d5..ce726b1d4e8e90cfd4459a6cb9c67b8805424e22 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -92,7 +92,7 @@ static void kvm_vcpu_enable_sve(struct kvm_vcpu *vcpu)
  * Finalize vcpu's maximum SVE vector length, allocating
  * vcpu->arch.sve_state as necessary.
  */
-static int kvm_vcpu_finalize_sve(struct kvm_vcpu *vcpu)
+static int kvm_vcpu_finalize_vec(struct kvm_vcpu *vcpu)
 {
 	void *buf;
 	unsigned int vl;
@@ -122,21 +122,21 @@ static int kvm_vcpu_finalize_sve(struct kvm_vcpu *vcpu)
 	}
 	
 	vcpu->arch.sve_state = buf;
-	vcpu_set_flag(vcpu, VCPU_SVE_FINALIZED);
+	vcpu_set_flag(vcpu, VCPU_VEC_FINALIZED);
 	return 0;
 }
 
 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature)
 {
 	switch (feature) {
-	case KVM_ARM_VCPU_SVE:
-		if (!vcpu_has_sve(vcpu))
+	case KVM_ARM_VCPU_VEC:
+		if (!vcpu_has_vec(vcpu))
 			return -EINVAL;
 
-		if (kvm_arm_vcpu_sve_finalized(vcpu))
+		if (kvm_arm_vcpu_vec_finalized(vcpu))
 			return -EPERM;
 
-		return kvm_vcpu_finalize_sve(vcpu);
+		return kvm_vcpu_finalize_vec(vcpu);
 	}
 
 	return -EINVAL;
@@ -144,7 +144,7 @@ int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature)
 
 bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu)
 {
-	if (vcpu_has_sve(vcpu) && !kvm_arm_vcpu_sve_finalized(vcpu))
+	if (vcpu_has_vec(vcpu) && !kvm_arm_vcpu_vec_finalized(vcpu))
 		return false;
 
 	return true;
@@ -161,7 +161,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu)
 	kfree(vcpu->arch.ccsidr);
 }
 
-static void kvm_vcpu_reset_sve(struct kvm_vcpu *vcpu)
+static void kvm_vcpu_reset_vec(struct kvm_vcpu *vcpu)
 {
 	if (vcpu_has_sve(vcpu))
 		memset(vcpu->arch.sve_state, 0, vcpu_sve_state_size(vcpu));
@@ -204,11 +204,11 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 	if (loaded)
 		kvm_arch_vcpu_put(vcpu);
 
-	if (!kvm_arm_vcpu_sve_finalized(vcpu)) {
+	if (!kvm_arm_vcpu_vec_finalized(vcpu)) {
 		if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE))
 			kvm_vcpu_enable_sve(vcpu);
 	} else {
-		kvm_vcpu_reset_sve(vcpu);
+		kvm_vcpu_reset_vec(vcpu);
 	}
 
 	if (vcpu_el1_is_32bit(vcpu))

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:36 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:36 +0000
Subject: [PATCH RFC v3 11/27] KVM: arm64: Document the KVM ABI for SME
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-11-05b018c1ffeb@kernel.org>

SME, the Scalable Matrix Extension, is an arm64 extension which adds
support for matrix operations, with core concepts patterned after SVE.

SVE introduced some complication in the ABI since it adds new vector
floating point registers with runtime configurable size, the size being
controlled by a prameter called the vector length (VL). To provide control
of this to VMMs we offer two phase configuration of SVE, SVE must first be
enabled for the vCPU with KVM_ARM_VCPU_INIT(KVM_ARM_VCPU_SVE), after which
vector length may then be configured but the configurably sized floating
point registers are inaccessible until finalized with a call to
KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE) after which the configurably sized
registers can be accessed.

SME introduces an additional independent configurable vector length
which as well as controlling the size of the new ZA register also
provides an alternative view of the configurably sized SVE registers
(known as streaming mode) with the guest able to switch between the two
modes as it pleases.  There is also a fixed sized register ZT0
introduced in SME2. As well as streaming mode the guest may enable and
disable ZA and (where SME2 is available) ZT0 dynamically independently
of streaming mode. These modes are controlled via the system register
SVCR.

We handle the configuration of the vector length for SME in a similar
manner to SVE, requiring initialization and finalization of the feature
with a pseudo register controlling the available SME vector lengths as for
SVE. Further, if the guest has both SVE and SME then finalizing one
prevents further configuration of the vector length for the other.

Where both SVE and SME are configured for the guest we always present
the SVE registers to userspace as having the larger of the configured
maximum SVE and SME vector lengths, discarding extra data at load time
and zero padding on read as required if the active vector length is
lower. Note that this means that enabling or disabling streaming mode
while the guest is stopped will not zero Zn or Pn as it will when the
guest is running, but it does allow SVCR, Zn and Pn to be read and
written in any order.

Userspace access to ZA and (if configured) ZT0 is always available, they
will be zeroed when the guest runs if disabled in SVCR and the value
read will be zero if the guest stops with them disabled. This mirrors
the behaviour of the architecture, enabling access causes ZA and ZT0 to
be zeroed, while allowing access to SVCR, ZA and ZT0 to be performed in
any order.

If SME is enabled for a guest without SVE then the FPSIMD Vn registers
must be accessed via the low 128 bits of the SVE Zn registers as is the
case when SVE is enabled. This is not ideal but allows access to SVCR and
the registers in any order without duplication or ambiguity about which
values should take effect. This may be an issue for VMMs that are
unaware of SME on systems that implement it without SVE if they let SME
be enabled, the lack of access to Vn may surprise them, but it seems
like an unusual implementation choice.

For SME unware VMMs on systems with both SVE and SME support the SVE
registers may be larger than expected, this should be less disruptive
than on a system without SVE as they will simply ignore the high bits of
the registers.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/virt/kvm/api.rst | 117 +++++++++++++++++++++++++++++------------
 1 file changed, 82 insertions(+), 35 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 454c2aaa155e5b994ee1f68502d8fdf55cf6700a..1d9270f8492392d9142cc38abe5a25cf5ab5f7d6 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -406,7 +406,7 @@ Errors:
              instructions from device memory (arm64)
   ENOSYS     data abort outside memslots with no syndrome info and
              KVM_CAP_ARM_NISV_TO_USER not enabled (arm64)
-  EPERM      SVE feature set but not finalized (arm64)
+  EPERM      SVE or SME feature set but not finalized (arm64)
   =======    ==============================================================
 
 This ioctl is used to run a guest virtual cpu.  While there are no
@@ -2580,12 +2580,12 @@ Specifically:
   0x6020 0000 0010 00d5 FPCR        32  fp_regs.fpcr
 ======================= ========= ===== =======================================
 
-.. [1] These encodings are not accepted for SVE-enabled vcpus.  See
-       :ref:`KVM_ARM_VCPU_INIT`.
+.. [1] These encodings are not accepted for SVE enabled vcpus.  See
+       :ref:`KVM_ARM_VCPU_INIT`.  They are also not accepted when SME is
+       enabled without SVE and the vcpu is in streaming mode.
 
        The equivalent register content can be accessed via bits [127:0] of
-       the corresponding SVE Zn registers instead for vcpus that have SVE
-       enabled (see below).
+       the corresponding SVE Zn registers in these cases (see below).
 
 arm64 CCSIDR registers are demultiplexed by CSSELR value::
 
@@ -2616,24 +2616,34 @@ arm64 SVE registers have the following bit patterns::
   0x6050 0000 0015 060 <slice:5>        FFR bits[256*slice + 255 : 256*slice]
   0x6060 0000 0015 ffff                 KVM_REG_ARM64_SVE_VLS pseudo-register
 
-Access to register IDs where 2048 * slice >= 128 * max_vq will fail with
-ENOENT.  max_vq is the vcpu's maximum supported vector length in 128-bit
-quadwords: see [2]_ below.
+arm64 SME registers have the following bit patterns:
+
+  0x6080 0000 0017 00 <n:5> <slice:5>   ZA.H[n] bits[2048*slice + 2047 : 2048*slice]
+  0x60XX 0000 0017 0100                 ZT0
+  0x6060 0000 0017 fffe                 KVM_REG_ARM64_SME_VLS pseudo-register
+
+Access to Z, P or ZA register IDs where 2048 * slice >= 128 * max_vq
+will fail with ENOENT.  max_vq is the vcpu's maximum supported vector
+length in 128-bit quadwords: see [2]_ below.
+
+Access to the ZA and ZT0 registers is only available if SVCR.ZA is set
+to 1.
 
 These registers are only accessible on vcpus for which SVE is enabled.
 See KVM_ARM_VCPU_INIT for details.
 
-In addition, except for KVM_REG_ARM64_SVE_VLS, these registers are not
-accessible until the vcpu's SVE configuration has been finalized
-using KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE).  See KVM_ARM_VCPU_INIT
-and KVM_ARM_VCPU_FINALIZE for more information about this procedure.
+In addition, except for KVM_REG_ARM64_SVE_VLS and
+KVM_REG_ARM64_SME_VLS, these registers are not accessible until the
+vcpu's SVE and SME configuration has been finalized using
+KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC).  See KVM_ARM_VCPU_INIT and
+KVM_ARM_VCPU_FINALIZE for more information about this procedure.
 
-KVM_REG_ARM64_SVE_VLS is a pseudo-register that allows the set of vector
-lengths supported by the vcpu to be discovered and configured by
-userspace.  When transferred to or from user memory via KVM_GET_ONE_REG
-or KVM_SET_ONE_REG, the value of this register is of type
-__u64[KVM_ARM64_SVE_VLS_WORDS], and encodes the set of vector lengths as
-follows::
+KVM_REG_ARM64_SVE_VLS and KVM_ARM64_VCPU_SME_VLS are pseudo-registers
+that allows the set of vector lengths supported by the vcpu to be
+discovered and configured by userspace.  When transferred to or from
+user memory via KVM_GET_ONE_REG or KVM_SET_ONE_REG, the value of this
+register is of type __u64[KVM_ARM64_SVE_VLS_WORDS], and encodes the
+set of vector lengths as follows::
 
   __u64 vector_lengths[KVM_ARM64_SVE_VLS_WORDS];
 
@@ -2645,19 +2655,25 @@ follows::
 	/* Vector length vq * 16 bytes not supported */
 
 .. [2] The maximum value vq for which the above condition is true is
-       max_vq.  This is the maximum vector length available to the guest on
-       this vcpu, and determines which register slices are visible through
-       this ioctl interface.
+       max_vq.  This is the maximum vector length currently available to
+       the guest on this vcpu, and determines which register slices are
+       visible through this ioctl interface.
+
+       If SME is supported then the max_vq used for the Z and P registers
+       then while SVCR.SM is 1 this vector length will be the maximum SME
+       vector length available for the guest, otherwise it will be the
+       maximum SVE vector length available.
 
 (See Documentation/arch/arm64/sve.rst for an explanation of the "vq"
 nomenclature.)
 
-KVM_REG_ARM64_SVE_VLS is only accessible after KVM_ARM_VCPU_INIT.
-KVM_ARM_VCPU_INIT initialises it to the best set of vector lengths that
-the host supports.
+KVM_REG_ARM64_SVE_VLS and KVM_REG_ARM_SME_VLS are only accessible
+after KVM_ARM_VCPU_INIT.  KVM_ARM_VCPU_INIT initialises them to the
+best set of vector lengths that the host supports.
 
-Userspace may subsequently modify it if desired until the vcpu's SVE
-configuration is finalized using KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE).
+Userspace may subsequently modify these registers if desired until the
+vcpu's SVE and SME configuration is finalized using
+KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC).
 
 Apart from simply removing all vector lengths from the host set that
 exceed some value, support for arbitrarily chosen sets of vector lengths
@@ -2665,8 +2681,8 @@ is hardware-dependent and may not be available.  Attempting to configure
 an invalid set of vector lengths via KVM_SET_ONE_REG will fail with
 EINVAL.
 
-After the vcpu's SVE configuration is finalized, further attempts to
-write this register will fail with EPERM.
+After the vcpu's SVE or SME configuration is finalized, further
+attempts to write these registers will fail with EPERM.
 
 arm64 bitmap feature firmware pseudo-registers have the following bit pattern::
 
@@ -3449,6 +3465,7 @@ The initial values are defined as:
 	- General Purpose registers, including PC and SP: set to 0
 	- FPSIMD/NEON registers: set to 0
 	- SVE registers: set to 0
+	- SME registers: set to 0
 	- System registers: Reset to their architecturally defined
 	  values as for a warm reset to EL1 (resp. SVC)
 
@@ -3491,7 +3508,7 @@ Possible features:
 
 	- KVM_ARM_VCPU_SVE: Enables SVE for the CPU (arm64 only).
 	  Depends on KVM_CAP_ARM_SVE.
-	  Requires KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE):
+	  Requires KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC):
 
 	   * After KVM_ARM_VCPU_INIT:
 
@@ -3499,7 +3516,7 @@ Possible features:
 	        initial value of this pseudo-register indicates the best set of
 	        vector lengths possible for a vcpu on this host.
 
-	   * Before KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE):
+	   * Before KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC}):
 
 	      - KVM_RUN and KVM_GET_REG_LIST are not available;
 
@@ -3512,11 +3529,40 @@ Possible features:
 	        KVM_SET_ONE_REG, to modify the set of vector lengths available
 	        for the vcpu.
 
-	   * After KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE):
+	   * After KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC):
 
 	      - the KVM_REG_ARM64_SVE_VLS pseudo-register is immutable, and can
 	        no longer be written using KVM_SET_ONE_REG.
 
+	- KVM_ARM_VCPU_SME: Enables SME for the CPU (arm64 only).
+	  Depends on KVM_CAP_ARM_SME.
+	  Requires KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC):
+
+	   * After KVM_ARM_VCPU_INIT:
+
+	      - KVM_REG_ARM64_SME_VLS may be read using KVM_GET_ONE_REG: the
+	        initial value of this pseudo-register indicates the best set of
+	        vector lengths possible for a vcpu on this host.
+
+	   * Before KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC}):
+
+	      - KVM_RUN and KVM_GET_REG_LIST are not available;
+
+	      - KVM_GET_ONE_REG and KVM_SET_ONE_REG cannot be used to access
+	        the scalable architectural SVE registers
+	        KVM_REG_ARM64_SVE_ZREG(), KVM_REG_ARM64_SVE_PREG() or
+	        KVM_REG_ARM64_SVE_FFR, the matrix register
+		KVM_REG_ARM64_SME_ZA() or the LUT register KVM_REG_ARM64_ZT();
+
+	      - KVM_REG_ARM64_SME_VLS may optionally be written using
+	        KVM_SET_ONE_REG, to modify the set of vector lengths available
+	        for the vcpu.
+
+	   * After KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC):
+
+	      - the KVM_REG_ARM64_SME_VLS pseudo-register is immutable, and can
+	        no longer be written using KVM_SET_ONE_REG.
+
 4.83 KVM_ARM_PREFERRED_TARGET
 -----------------------------
 
@@ -5086,11 +5132,12 @@ Errors:
 
 Recognised values for feature:
 
-  =====      ===========================================
-  arm64      KVM_ARM_VCPU_SVE (requires KVM_CAP_ARM_SVE)
-  =====      ===========================================
+  =====      ==============================================================
+  arm64      KVM_ARM_VCPU_VEC (requires KVM_CAP_ARM_SVE or KVM_CAP_ARM_SME)
+  arm64      KVM_ARM_VCPU_SVE (alias for KVM_ARM_VCPU_VEC)
+  =====      ==============================================================
 
-Finalizes the configuration of the specified vcpu feature.
+Finalizes the configuration of the specified vcpu features.
 
 The vcpu must already have been initialised, enabling the affected feature, by
 means of a successful :ref:`KVM_ARM_VCPU_INIT <KVM_ARM_VCPU_INIT>` call with the

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:37 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:37 +0000
Subject: [PATCH RFC v3 12/27] KVM: arm64: Define internal features for SME
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-12-05b018c1ffeb@kernel.org>

In order to simplify interdependencies in the rest of the series define
the feature detection for SME and it's subfeatures.  Due to the need for
vector length configuration we define a flag for SME like for SVE.  We
also have two subfeatures which add architectural state, FA64 and SME2,
which are configured via the normal ID register scheme.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 23 +++++++++++++++++++++--
 arch/arm64/kvm/sys_regs.c         |  2 +-
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f64ad573573cf000c4644f12f9e072a2fdfc3824..022214e57e74404e8d590a5820a9e77160869b1b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -39,7 +39,7 @@
 
 #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
 
-#define KVM_VCPU_MAX_FEATURES 7
+#define KVM_VCPU_MAX_FEATURES 9
 #define KVM_VCPU_VALID_FEATURES	(BIT(KVM_VCPU_MAX_FEATURES) - 1)
 
 #define KVM_REQ_SLEEP \
@@ -339,6 +339,8 @@ struct kvm_arch {
 #define KVM_ARCH_FLAG_FGU_INITIALIZED			8
 	/* SVE exposed to guest */
 #define KVM_ARCH_FLAG_GUEST_HAS_SVE			9
+	/* SME exposed to guest */
+#define KVM_ARCH_FLAG_GUEST_HAS_SME			10
 	unsigned long flags;
 
 	/* VM-wide vCPU feature set */
@@ -948,7 +950,16 @@ struct kvm_vcpu_arch {
 #define vcpu_has_sve(vcpu)	kvm_has_sve((vcpu)->kvm)
 #endif
 
-#define vcpu_has_vec(vcpu) vcpu_has_sve(vcpu)
+#define kvm_has_sme(kvm)	\
+	test_bit(KVM_ARCH_FLAG_GUEST_HAS_SME, &(kvm)->arch.flags)
+
+#ifdef __KVM_NVHE_HYPERVISOR__
+#define vcpu_has_sme(vcpu)	kvm_has_sme(kern_hyp_va((vcpu)->kvm))
+#else
+#define vcpu_has_sme(vcpu)	kvm_has_sme((vcpu)->kvm)
+#endif
+
+#define vcpu_has_vec(vcpu) (vcpu_has_sve(vcpu) || vcpu_has_sme(vcpu))
 
 #ifdef CONFIG_ARM64_PTR_AUTH
 #define vcpu_has_ptrauth(vcpu)						\
@@ -1542,4 +1553,12 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
 #define kvm_has_s1poe(k)				\
 	(kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP))
 
+#define kvm_has_fa64(k)					\
+	(system_supports_sme() &&			\
+	 kvm_has_feat((k), ID_AA64SMFR0_EL1, FA64, IMP))
+
+#define kvm_has_sme2(k)					\
+	(system_supports_sme() &&			\
+	 kvm_has_feat((k), ID_AA64PFR1_EL1, SME, SME2))
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 83c6b4a07ef56cf0ed9c8751ec80686f45dca6b2..1b16716a6d53525fbe694cc8d5d009d72b6ce416 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1727,7 +1727,7 @@ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu,
 static unsigned int sme_visibility(const struct kvm_vcpu *vcpu,
 				   const struct sys_reg_desc *rd)
 {
-	if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SME, IMP))
+	if (vcpu_has_sme(vcpu))
 		return 0;
 
 	return REG_HIDDEN;

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:38 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:38 +0000
Subject: [PATCH RFC v3 13/27] KVM: arm64: Rename sve_state_reg_region
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-13-05b018c1ffeb@kernel.org>

As for SVE we will need to pull parts of dynamically sized registers out of
a block of memory for SME so we will use a similar code pattern for this.
Rename the current struct sve_state_reg_region in preparation for this.

No functional change.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/guest.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 62ff51d6e4584acc71205f5d4b1d2f3d2e2d2f88..cde733417f25b5af4f5e996f91c2b962a4d361fd 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -404,9 +404,9 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
  */
 #define vcpu_sve_slices(vcpu) 1
 
-/* Bounds of a single SVE register slice within vcpu->arch.sve_state */
-struct sve_state_reg_region {
-	unsigned int koffset;	/* offset into sve_state in kernel memory */
+/* Bounds of a single register slice within vcpu->arch.s[mv]e_state */
+struct vec_state_reg_region {
+	unsigned int koffset;	/* offset into s[mv]e_state in kernel memory */
 	unsigned int klen;	/* length in kernel memory */
 	unsigned int upad;	/* extra trailing padding in user memory */
 };
@@ -415,7 +415,7 @@ struct sve_state_reg_region {
  * Validate SVE register ID and get sanitised bounds for user/kernel SVE
  * register copy
  */
-static int sve_reg_to_region(struct sve_state_reg_region *region,
+static int sve_reg_to_region(struct vec_state_reg_region *region,
 			     struct kvm_vcpu *vcpu,
 			     const struct kvm_one_reg *reg)
 {
@@ -485,7 +485,7 @@ static int sve_reg_to_region(struct sve_state_reg_region *region,
 static int get_sve_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 {
 	int ret;
-	struct sve_state_reg_region region;
+	struct vec_state_reg_region region;
 	char __user *uptr = (char __user *)reg->addr;
 
 	/* Handle the KVM_REG_ARM64_SVE_VLS pseudo-reg as a special case: */
@@ -511,7 +511,7 @@ static int get_sve_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 static int set_sve_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 {
 	int ret;
-	struct sve_state_reg_region region;
+	struct vec_state_reg_region region;
 	const char __user *uptr = (const char __user *)reg->addr;
 
 	/* Handle the KVM_REG_ARM64_SVE_VLS pseudo-reg as a special case: */

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:39 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:39 +0000
Subject: [PATCH RFC v3 14/27] KVM: arm64: Store vector lengths in an array
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-14-05b018c1ffeb@kernel.org>

SME adds a second vector length configured in a very similar way to the
SVE vector length, in order to facilitate future code sharing for SME
refactor our storage of vector lengths to use an array like the host does.
We do not yet take much advantage of this so the intermediate code is not
as clean as might be.

No functional change.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h       | 17 +++++++++++------
 arch/arm64/include/asm/kvm_hyp.h        |  2 +-
 arch/arm64/include/asm/kvm_pkvm.h       |  2 +-
 arch/arm64/kvm/fpsimd.c                 |  2 +-
 arch/arm64/kvm/guest.c                  |  6 +++---
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 ++--
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      | 11 ++++++-----
 arch/arm64/kvm/hyp/nvhe/pkvm.c          |  2 +-
 arch/arm64/kvm/reset.c                  | 22 +++++++++++-----------
 9 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 022214e57e74404e8d590a5820a9e77160869b1b..63e1410146f76fd584374765c04b3ba14090afdc 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -74,8 +74,10 @@ enum kvm_mode kvm_get_mode(void);
 static inline enum kvm_mode kvm_get_mode(void) { return KVM_MODE_NONE; };
 #endif
 
-extern unsigned int __ro_after_init kvm_sve_max_vl;
-extern unsigned int __ro_after_init kvm_host_sve_max_vl;
+extern unsigned int __ro_after_init kvm_max_vl[ARM64_VEC_MAX];
+extern unsigned int __ro_after_init kvm_host_max_vl[ARM64_VEC_MAX];
+DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
+
 int __init kvm_arm_init_sve(void);
 
 u32 __attribute_const__ kvm_target_cpu(void);
@@ -709,7 +711,7 @@ struct kvm_vcpu_arch {
 	 */
 	void *sve_state;
 	enum fp_type fp_type;
-	unsigned int sve_max_vl;
+	unsigned int max_vl[ARM64_VEC_MAX];
 
 	/* Stage 2 paging state used by the hardware on next switch */
 	struct kvm_s2_mmu *hw_mmu;
@@ -984,9 +986,12 @@ struct kvm_vcpu_arch {
 
 /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
 #define vcpu_sve_pffr(vcpu) (kern_hyp_va((vcpu)->arch.sve_state) +	\
-			     sve_ffr_offset((vcpu)->arch.sve_max_vl))
+			     sve_ffr_offset((vcpu)->arch.max_vl[ARM64_VEC_SVE]))
+
+#define vcpu_vec_max_vq(vcpu, type) sve_vq_from_vl((vcpu)->arch.max_vl[type])
+
+#define vcpu_sve_max_vq(vcpu)	vcpu_vec_max_vq(vcpu, ARM64_VEC_SVE)
 
-#define vcpu_sve_max_vq(vcpu)	sve_vq_from_vl((vcpu)->arch.sve_max_vl)
 
 #define vcpu_sve_zcr_elx(vcpu)						\
 	(unlikely(is_hyp_ctxt(vcpu)) ? ZCR_EL2 : ZCR_EL1)
@@ -995,7 +1000,7 @@ struct kvm_vcpu_arch {
 	size_t __size_ret;						\
 	unsigned int __vcpu_vq;						\
 									\
-	if (WARN_ON(!sve_vl_valid((vcpu)->arch.sve_max_vl))) {		\
+	if (WARN_ON(!sve_vl_valid((vcpu)->arch.max_vl[ARM64_VEC_SVE]))) { \
 		__size_ret = 0;						\
 	} else {							\
 		__vcpu_vq = vcpu_sve_max_vq(vcpu);			\
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index c838309e4ec47e395d78127a8ee6bad8390c4411..21943cb98542750a1b626a8de6bbc095d7770ccf 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -143,6 +143,6 @@ extern u64 kvm_nvhe_sym(id_aa64smfr0_el1_sys_val);
 
 extern unsigned long kvm_nvhe_sym(__icache_flags);
 extern unsigned int kvm_nvhe_sym(kvm_arm_vmid_bits);
-extern unsigned int kvm_nvhe_sym(kvm_host_sve_max_vl);
+extern unsigned int kvm_nvhe_sym(kvm_host_max_vl[ARM64_VEC_MAX]);
 
 #endif /* __ARM64_KVM_HYP_H__ */
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 400f7cef1e81b29925ed00593d8198f8d2700025..e6021a2418529064dcd31b4a5301e4d6f6ac8acd 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -159,7 +159,7 @@ static inline size_t pkvm_host_sve_state_size(void)
 		return 0;
 
 	return size_add(sizeof(struct cpu_sve_state),
-			SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_sve_max_vl)));
+			SVE_SIG_REGS_SIZE(sve_vq_from_vl(kvm_host_max_vl[ARM64_VEC_SVE])));
 }
 
 #endif	/* __ARM64_KVM_PKVM_H__ */
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 3c2e0b96877ac5b4f3b9d8dfa38975f11b74b60d..51c844e25dfa460ecab5bb0dfc50c7680318aa20 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -133,7 +133,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 		 */
 		fp_state.st = &vcpu->arch.ctxt.fp_regs;
 		fp_state.sve_state = vcpu->arch.sve_state;
-		fp_state.sve_vl = vcpu->arch.sve_max_vl;
+		fp_state.sve_vl = vcpu->arch.max_vl[ARM64_VEC_SVE];
 		fp_state.sme_state = NULL;
 		fp_state.svcr = &__vcpu_sys_reg(vcpu, SVCR);
 		fp_state.fpmr = &__vcpu_sys_reg(vcpu, FPMR);
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index cde733417f25b5af4f5e996f91c2b962a4d361fd..5fda5dbc0c3c0ce3a20a732a68421376e54f23ca 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -318,7 +318,7 @@ static int get_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	if (!vcpu_has_sve(vcpu))
 		return -ENOENT;
 
-	if (WARN_ON(!sve_vl_valid(vcpu->arch.sve_max_vl)))
+	if (WARN_ON(!sve_vl_valid(vcpu->arch.max_vl[ARM64_VEC_SVE])))
 		return -EINVAL;
 
 	memset(vqs, 0, sizeof(vqs));
@@ -356,7 +356,7 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 		if (vq_present(vqs, vq))
 			max_vq = vq;
 
-	if (max_vq > sve_vq_from_vl(kvm_sve_max_vl))
+	if (max_vq > sve_vq_from_vl(kvm_max_vl[ARM64_VEC_SVE]))
 		return -EINVAL;
 
 	/*
@@ -375,7 +375,7 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 		return -EINVAL;
 
 	/* vcpu->arch.sve_state will be alloc'd by kvm_vcpu_finalize_sve() */
-	vcpu->arch.sve_max_vl = sve_vl_from_vq(max_vq);
+	vcpu->arch.max_vl[ARM64_VEC_SVE] = sve_vl_from_vq(max_vq);
 
 	return 0;
 }
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 247dfadcdb22e1ef96f92a9d86e66c9eefb44600..09a9a237d6dd22d4bb941714363675abdab1baa7 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -370,8 +370,8 @@ static inline void __hyp_sve_save_host(void)
 	struct cpu_sve_state *sve_state = *host_data_ptr(sve_state);
 
 	sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR);
-	write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2);
-	__sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl),
+	write_sysreg_s(sve_vq_from_vl(kvm_host_max_vl[ARM64_VEC_SVE]) - 1, SYS_ZCR_EL2);
+	__sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_max_vl[ARM64_VEC_SVE]),
 			 &sve_state->fpsr,
 			 true);
 }
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 6aa0b13d86e581a36ed529bcd932498045d2d6df..7468d8516ecaa1370861e51ad4f65adbc01a5d97 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -33,7 +33,7 @@ static void __hyp_sve_save_guest(struct kvm_vcpu *vcpu)
 	 */
 	sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
 	__sve_save_state(vcpu_sve_pffr(vcpu), &vcpu->arch.ctxt.fp_regs.fpsr, true);
-	write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2);
+	write_sysreg_s(sve_vq_from_vl(kvm_host_max_vl[ARM64_VEC_SVE]) - 1, SYS_ZCR_EL2);
 }
 
 static void __hyp_sve_restore_host(void)
@@ -49,8 +49,8 @@ static void __hyp_sve_restore_host(void)
 	 * that was discovered, if we wish to use larger VLs this will
 	 * need to be revisited.
 	 */
-	write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2);
-	__sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl),
+	write_sysreg_s(sve_vq_from_vl(kvm_host_max_vl[ARM64_VEC_SVE]) - 1, SYS_ZCR_EL2);
+	__sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_max_vl[ARM64_VEC_SVE]),
 			    &sve_state->fpsr,
 			    true);
 	write_sysreg_el1(sve_state->zcr_el1, SYS_ZCR);
@@ -101,7 +101,8 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
 
 	hyp_vcpu->vcpu.arch.sve_state	= kern_hyp_va(host_vcpu->arch.sve_state);
 	/* Limit guest vector length to the maximum supported by the host.  */
-	hyp_vcpu->vcpu.arch.sve_max_vl	= min(host_vcpu->arch.sve_max_vl, kvm_host_sve_max_vl);
+	hyp_vcpu->vcpu.arch.max_vl[ARM64_VEC_SVE] = min(host_vcpu->arch.max_vl[ARM64_VEC_SVE],
+							kvm_host_max_vl[ARM64_VEC_SVE]);
 
 	hyp_vcpu->vcpu.arch.hw_mmu	= host_vcpu->arch.hw_mmu;
 
@@ -483,7 +484,7 @@ void handle_trap(struct kvm_cpu_context *host_ctxt)
 	case ESR_ELx_EC_SVE:
 		cpacr_clear_set(0, CPACR_ELx_ZEN);
 		isb();
-		sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1,
+		sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_max_vl[ARM64_VEC_SVE]) - 1,
 				       SYS_ZCR_EL2);
 		break;
 	case ESR_ELx_EC_IABT_LOW:
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 0a4e1f5105592b23a0505bf7680c66e76b5c2a65..fea01612ac47a8a2f42edb9f17490edbaa89d04c 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -20,7 +20,7 @@ unsigned long __icache_flags;
 /* Used by kvm_get_vttbr(). */
 unsigned int kvm_arm_vmid_bits;
 
-unsigned int kvm_host_sve_max_vl;
+unsigned int kvm_host_max_vl[ARM64_VEC_MAX];
 
 static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 {
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index ce726b1d4e8e90cfd4459a6cb9c67b8805424e22..3cb91dc6dc3dc5cc484900dbd9f4cdfedb3e2b4a 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -32,7 +32,7 @@
 
 /* Maximum phys_shift supported for any VM on this host */
 static u32 __ro_after_init kvm_ipa_limit;
-unsigned int __ro_after_init kvm_host_sve_max_vl;
+unsigned int __ro_after_init kvm_host_max_vl[ARM64_VEC_MAX];
 
 /*
  * ARMv8 Reset Values
@@ -46,14 +46,14 @@ unsigned int __ro_after_init kvm_host_sve_max_vl;
 #define VCPU_RESET_PSTATE_SVC	(PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
 				 PSR_AA32_I_BIT | PSR_AA32_F_BIT)
 
-unsigned int __ro_after_init kvm_sve_max_vl;
+unsigned int __ro_after_init kvm_max_vl[ARM64_VEC_MAX];
 
 int __init kvm_arm_init_sve(void)
 {
 	if (system_supports_sve()) {
-		kvm_sve_max_vl = sve_max_virtualisable_vl();
-		kvm_host_sve_max_vl = sve_max_vl();
-		kvm_nvhe_sym(kvm_host_sve_max_vl) = kvm_host_sve_max_vl;
+		kvm_max_vl[ARM64_VEC_SVE] = sve_max_virtualisable_vl();
+		kvm_host_max_vl[ARM64_VEC_SVE] = sve_max_vl();
+		kvm_nvhe_sym(kvm_host_max_vl[ARM64_VEC_SVE]) = kvm_host_max_vl[ARM64_VEC_SVE];
 
 		/*
 		 * The get_sve_reg()/set_sve_reg() ioctl interface will need
@@ -61,16 +61,16 @@ int __init kvm_arm_init_sve(void)
 		 * order to support vector lengths greater than
 		 * VL_ARCH_MAX:
 		 */
-		if (WARN_ON(kvm_sve_max_vl > VL_ARCH_MAX))
-			kvm_sve_max_vl = VL_ARCH_MAX;
+		if (WARN_ON(kvm_max_vl[ARM64_VEC_SVE] > VL_ARCH_MAX))
+			kvm_max_vl[ARM64_VEC_SVE] = VL_ARCH_MAX;
 
 		/*
 		 * Don't even try to make use of vector lengths that
 		 * aren't available on all CPUs, for now:
 		 */
-		if (kvm_sve_max_vl < sve_max_vl())
+		if (kvm_max_vl[ARM64_VEC_SVE] < sve_max_vl())
 			pr_warn("KVM: SVE vector length for guests limited to %u bytes\n",
-				kvm_sve_max_vl);
+				kvm_max_vl[ARM64_VEC_SVE]);
 	}
 
 	return 0;
@@ -78,7 +78,7 @@ int __init kvm_arm_init_sve(void)
 
 static void kvm_vcpu_enable_sve(struct kvm_vcpu *vcpu)
 {
-	vcpu->arch.sve_max_vl = kvm_sve_max_vl;
+	vcpu->arch.max_vl[ARM64_VEC_SVE] = kvm_max_vl[ARM64_VEC_SVE];
 
 	/*
 	 * Userspace can still customize the vector lengths by writing
@@ -99,7 +99,7 @@ static int kvm_vcpu_finalize_vec(struct kvm_vcpu *vcpu)
 	size_t reg_sz;
 	int ret;
 
-	vl = vcpu->arch.sve_max_vl;
+	vl = vcpu->arch.max_vl[ARM64_VEC_SVE];
 
 	/*
 	 * Responsibility for these properties is shared between

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:40 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:40 +0000
Subject: [PATCH RFC v3 15/27] KVM: arm64: Implement SME vector length
 configuration
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-15-05b018c1ffeb@kernel.org>

SME implements a vector length which architecturally looks very similar
to that for SVE, configured in a very similar manner.  This controls the
vector length used for the ZA matrix register, and for the SVE vector
and predicate registers when in streaming mode.  The only substantial
difference is that unlike SVE the architecture does not guarantee that
any particular vector length will be implemented.

Configuration for SME vector lengths is done using a virtual register as
for SVE, hook up the implementation for the virtual register.  Since we
do not yet have support for any of the new SME registers stub register
access functions are provided that only allow VL configuration.  These
will be extended as the SME specific registers, as for SVE.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  7 +++
 arch/arm64/include/uapi/asm/kvm.h |  9 ++++
 arch/arm64/kvm/guest.c            | 94 +++++++++++++++++++++++++++++++--------
 3 files changed, 91 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 63e1410146f76fd584374765c04b3ba14090afdc..02f620d95f7dd2cb2b29cc25e78e7ef404cfad4c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -708,8 +708,15 @@ struct kvm_vcpu_arch {
 	 * low 128 bits of the SVE Z registers.  When the core
 	 * floating point code saves the register state of a task it
 	 * records which view it saved in fp_type.
+	 *
+	 * If SME support is also present then it provides an
+	 * alternative view of the SVE registers accessed as for the Z
+	 * registers when PSTATE.SM is 1, plus an additional set of
+	 * SME specific state in the matrix register ZA and LUT
+	 * register ZT0.
 	 */
 	void *sve_state;
+	void *sme_state;
 	enum fp_type fp_type;
 	unsigned int max_vl[ARM64_VEC_MAX];
 
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 9d80d22af9d4e00204f5096fb7c8c2ee8c3646c1..efb384cf9d503007f68aad9233ba949128c94b8b 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -356,6 +356,15 @@ struct kvm_arm_counter_offset {
 #define KVM_ARM64_SVE_VLS_WORDS	\
 	((KVM_ARM64_SVE_VQ_MAX - KVM_ARM64_SVE_VQ_MIN) / 64 + 1)
 
+/* SME registers */
+#define KVM_REG_ARM64_SME		(0x17 << KVM_REG_ARM_COPROC_SHIFT)
+
+/* Vector lengths pseudo-register: */
+#define KVM_REG_ARM64_SME_VLS		(KVM_REG_ARM64 | KVM_REG_ARM64_SME | \
+					 KVM_REG_SIZE_U512 | 0xffff)
+#define KVM_ARM64_SME_VLS_WORDS	\
+	((KVM_ARM64_SVE_VQ_MAX - KVM_ARM64_SVE_VQ_MIN) / 64 + 1)
+
 /* Bitmap feature firmware registers */
 #define KVM_REG_ARM_FW_FEAT_BMAP		(0x0016 << KVM_REG_ARM_COPROC_SHIFT)
 #define KVM_REG_ARM_FW_FEAT_BMAP_REG(r)		(KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 5fda5dbc0c3c0ce3a20a732a68421376e54f23ca..8820cd42a27ac05874ed52c572c1dd9b29a77a1b 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -310,22 +310,20 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 #define vq_mask(vq) ((u64)1 << ((vq) - SVE_VQ_MIN) % 64)
 #define vq_present(vqs, vq) (!!((vqs)[vq_word(vq)] & vq_mask(vq)))
 
-static int get_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+static int get_vec_vls(enum vec_type vec_type, struct kvm_vcpu *vcpu,
+		      const struct kvm_one_reg *reg)
 {
 	unsigned int max_vq, vq;
 	u64 vqs[KVM_ARM64_SVE_VLS_WORDS];
 
-	if (!vcpu_has_sve(vcpu))
-		return -ENOENT;
-
-	if (WARN_ON(!sve_vl_valid(vcpu->arch.max_vl[ARM64_VEC_SVE])))
+	if (WARN_ON(!sve_vl_valid(vcpu->arch.max_vl[vec_type])))
 		return -EINVAL;
 
 	memset(vqs, 0, sizeof(vqs));
 
-	max_vq = vcpu_sve_max_vq(vcpu);
+	max_vq = vcpu_vec_max_vq(vcpu, vec_type);
 	for (vq = SVE_VQ_MIN; vq <= max_vq; ++vq)
-		if (sve_vq_available(vq))
+		if (vq_available(vec_type, vq))
 			vqs[vq_word(vq)] |= vq_mask(vq);
 
 	if (copy_to_user((void __user *)reg->addr, vqs, sizeof(vqs)))
@@ -334,18 +332,13 @@ static int get_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	return 0;
 }
 
-static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+static int set_vec_vls(enum vec_type vec_type, struct kvm_vcpu *vcpu,
+		       const struct kvm_one_reg *reg)
 {
 	unsigned int max_vq, vq;
 	u64 vqs[KVM_ARM64_SVE_VLS_WORDS];
 
-	if (!vcpu_has_sve(vcpu))
-		return -ENOENT;
-
-	if (kvm_arm_vcpu_vec_finalized(vcpu))
-		return -EPERM; /* too late! */
-
-	if (WARN_ON(vcpu->arch.sve_state))
+	if (WARN_ON(!sve_vl_valid(vcpu->arch.max_vl[vec_type])))
 		return -EINVAL;
 
 	if (copy_from_user(vqs, (const void __user *)reg->addr, sizeof(vqs)))
@@ -356,18 +349,18 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 		if (vq_present(vqs, vq))
 			max_vq = vq;
 
-	if (max_vq > sve_vq_from_vl(kvm_max_vl[ARM64_VEC_SVE]))
+	if (max_vq > sve_vq_from_vl(kvm_max_vl[vec_type]))
 		return -EINVAL;
 
 	/*
 	 * Vector lengths supported by the host can't currently be
 	 * hidden from the guest individually: instead we can only set a
-	 * maximum via ZCR_EL2.LEN.  So, make sure the available vector
+	 * maximum via xCR_EL2.LEN.  So, make sure the available vector
 	 * lengths match the set requested exactly up to the requested
 	 * maximum:
 	 */
 	for (vq = SVE_VQ_MIN; vq <= max_vq; ++vq)
-		if (vq_present(vqs, vq) != sve_vq_available(vq))
+		if (vq_present(vqs, vq) != vq_available(vec_type, vq))
 			return -EINVAL;
 
 	/* Can't run with no vector lengths at all: */
@@ -375,11 +368,33 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 		return -EINVAL;
 
 	/* vcpu->arch.sve_state will be alloc'd by kvm_vcpu_finalize_sve() */
-	vcpu->arch.max_vl[ARM64_VEC_SVE] = sve_vl_from_vq(max_vq);
+	vcpu->arch.max_vl[vec_type] = sve_vl_from_vq(max_vq);
 
 	return 0;
 }
 
+static int get_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	if (!vcpu_has_sve(vcpu))
+		return -ENOENT;
+
+	return get_vec_vls(ARM64_VEC_SVE, vcpu, reg);
+}
+
+static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	if (!vcpu_has_sve(vcpu))
+		return -ENOENT;
+
+	if (kvm_arm_vcpu_vec_finalized(vcpu))
+		return -EPERM; /* too late! */
+
+	if (WARN_ON(vcpu->arch.sve_state))
+		return -EINVAL;
+
+	return set_vec_vls(ARM64_VEC_SVE, vcpu, reg);
+}
+
 #define SVE_REG_SLICE_SHIFT	0
 #define SVE_REG_SLICE_BITS	5
 #define SVE_REG_ID_SHIFT	(SVE_REG_SLICE_SHIFT + SVE_REG_SLICE_BITS)
@@ -533,6 +548,45 @@ static int set_sve_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	return 0;
 }
 
+static int get_sme_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	if (!vcpu_has_sme(vcpu))
+		return -ENOENT;
+
+	return get_vec_vls(ARM64_VEC_SME, vcpu, reg);
+}
+
+static int set_sme_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	if (!vcpu_has_sme(vcpu))
+		return -ENOENT;
+
+	if (kvm_arm_vcpu_vec_finalized(vcpu))
+		return -EPERM; /* too late! */
+
+	if (WARN_ON(vcpu->arch.sme_state))
+		return -EINVAL;
+
+	return set_vec_vls(ARM64_VEC_SME, vcpu, reg);
+}
+
+static int get_sme_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	/* Handle the KVM_REG_ARM64_SME_VLS pseudo-reg as a special case: */
+	if (reg->id == KVM_REG_ARM64_SME_VLS)
+		return get_sme_vls(vcpu, reg);
+
+	return -EINVAL;
+}
+
+static int set_sme_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	/* Handle the KVM_REG_ARM64_SME_VLS pseudo-reg as a special case: */
+	if (reg->id == KVM_REG_ARM64_SME_VLS)
+		return set_sme_vls(vcpu, reg);
+
+	return -EINVAL;
+}
 int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
 	return -EINVAL;
@@ -775,6 +829,7 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	case KVM_REG_ARM_FW_FEAT_BMAP:
 		return kvm_arm_get_fw_reg(vcpu, reg);
 	case KVM_REG_ARM64_SVE:	return get_sve_reg(vcpu, reg);
+	case KVM_REG_ARM64_SME:	return get_sme_reg(vcpu, reg);
 	}
 
 	if (is_timer_reg(reg->id))
@@ -795,6 +850,7 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	case KVM_REG_ARM_FW_FEAT_BMAP:
 		return kvm_arm_set_fw_reg(vcpu, reg);
 	case KVM_REG_ARM64_SVE:	return set_sve_reg(vcpu, reg);
+	case KVM_REG_ARM64_SME:	return set_sme_reg(vcpu, reg);
 	}
 
 	if (is_timer_reg(reg->id))

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:41 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:41 +0000
Subject: [PATCH RFC v3 16/27] KVM: arm64: Add definitions for SME control
 register
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-16-05b018c1ffeb@kernel.org>

SME is configured by the system registers SMCR_EL1 and SMCR_EL2, add
definitions and userspace access for them.  They will be context
switched together with the rest of SME state.

In systems with SME priority support there are additional registers
SMPRI_EL1 and SMPRIMAP_EL2 managing the priorities however we do not
currently have any support for SME priorities and mask that support out
from guests.  The intention is to revist this once we have physical
implementations and can properly evaluate the practical impacts that
they have.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h     |  6 ++++++
 arch/arm64/include/asm/vncr_mapping.h |  1 +
 arch/arm64/kvm/sys_regs.c             | 37 ++++++++++++++++++++++++++++++++++-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 02f620d95f7dd2cb2b29cc25e78e7ef404cfad4c..8d6342dde02fd99cfd7d2bedeccf0581ad3504ee 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -484,6 +484,7 @@ enum vcpu_sysreg {
 	CPTR_EL2,	/* Architectural Feature Trap Register (EL2) */
 	HACR_EL2,	/* Hypervisor Auxiliary Control Register */
 	ZCR_EL2,	/* SVE Control Register (EL2) */
+	SMCR_EL2,	/* SME Control Register (EL2) */
 	TTBR0_EL2,	/* Translation Table Base Register 0 (EL2) */
 	TTBR1_EL2,	/* Translation Table Base Register 1 (EL2) */
 	TCR_EL2,	/* Translation Control Register (EL2) */
@@ -521,6 +522,7 @@ enum vcpu_sysreg {
 	VNCR(ACTLR_EL1),/* Auxiliary Control Register */
 	VNCR(CPACR_EL1),/* Coprocessor Access Control */
 	VNCR(ZCR_EL1),	/* SVE Control */
+	VNCR(SMCR_EL1),	/* SME Control */
 	VNCR(TTBR0_EL1),/* Translation Table Base Register 0 */
 	VNCR(TTBR1_EL1),/* Translation Table Base Register 1 */
 	VNCR(TCR_EL1),	/* Translation Control Register */
@@ -998,7 +1000,11 @@ struct kvm_vcpu_arch {
 #define vcpu_vec_max_vq(vcpu, type) sve_vq_from_vl((vcpu)->arch.max_vl[type])
 
 #define vcpu_sve_max_vq(vcpu)	vcpu_vec_max_vq(vcpu, ARM64_VEC_SVE)
+#define vcpu_sme_max_vq(vcpu)	vcpu_vec_max_vq(vcpu, ARM64_VEC_SME)
 
+#define vcpu_max_vl(vcpu) max((vcpu)->arch.max_vl[ARM64_VEC_SVE], \
+			      (vcpu)->arch.max_vl[ARM64_VEC_SME])
+#define vcpu_max_vq(vcpu) sve_vq_from_vl(vcpu_max_vl(vcpu))
 
 #define vcpu_sve_zcr_elx(vcpu)						\
 	(unlikely(is_hyp_ctxt(vcpu)) ? ZCR_EL2 : ZCR_EL1)
diff --git a/arch/arm64/include/asm/vncr_mapping.h b/arch/arm64/include/asm/vncr_mapping.h
index 4f9bbd4d6c2671753124599475e5138bf6b9c749..74fc7400efbc7de6b8dd81a485f1e9d545baf7a9 100644
--- a/arch/arm64/include/asm/vncr_mapping.h
+++ b/arch/arm64/include/asm/vncr_mapping.h
@@ -42,6 +42,7 @@
 #define VNCR_HDFGWTR_EL2	0x1D8
 #define VNCR_ZCR_EL1            0x1E0
 #define VNCR_HAFGRTR_EL2	0x1E8
+#define VNCR_SMCR_EL1		0x1F0
 #define VNCR_TTBR0_EL1          0x200
 #define VNCR_TTBR1_EL1          0x210
 #define VNCR_FAR_EL1            0x220
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 1b16716a6d53525fbe694cc8d5d009d72b6ce416..a9429d9d63b54b5b4d4fe365aa6af4d84a256539 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -142,6 +142,7 @@ static bool get_el2_to_el1_mapping(unsigned int reg,
 		MAPPED_EL2_SYSREG(ELR_EL2,     ELR_EL1,	    NULL	     );
 		MAPPED_EL2_SYSREG(SPSR_EL2,    SPSR_EL1,    NULL	     );
 		MAPPED_EL2_SYSREG(ZCR_EL2,     ZCR_EL1,     NULL	     );
+		MAPPED_EL2_SYSREG(SMCR_EL2,    SMCR_EL1,    NULL	     );
 		MAPPED_EL2_SYSREG(CONTEXTIDR_EL2, CONTEXTIDR_EL1, NULL	     );
 	default:
 		return false;
@@ -2405,6 +2406,37 @@ static bool access_zcr_el2(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static unsigned int sme_el2_visibility(const struct kvm_vcpu *vcpu,
+				       const struct sys_reg_desc *rd)
+{
+	return __el2_visibility(vcpu, rd, sme_visibility);
+}
+
+static bool access_smcr_el2(struct kvm_vcpu *vcpu,
+			    struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	unsigned int vq;
+	u64 smcr;
+
+	if (guest_hyp_sve_traps_enabled(vcpu)) {
+		kvm_inject_nested_sve_trap(vcpu);
+		return true;
+	}
+
+	if (!p->is_write) {
+		p->regval = vcpu_read_sys_reg(vcpu, SMCR_EL2);
+		return true;
+	}
+
+	smcr = p->regval;
+	vq = SYS_FIELD_GET(SMCR_ELx, LEN, smcr) + 1;
+	vq = min(vq, vcpu_sme_max_vq(vcpu));
+	vcpu_write_sys_reg(vcpu, SYS_FIELD_PREP(SMCR_ELx, LEN, vq - 1),
+			   SMCR_EL2);
+	return true;
+}
+
 static unsigned int s1poe_visibility(const struct kvm_vcpu *vcpu,
 				     const struct sys_reg_desc *rd)
 {
@@ -2649,7 +2681,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility },
 	{ SYS_DESC(SYS_TRFCR_EL1), undef_access },
 	{ SYS_DESC(SYS_SMPRI_EL1), undef_access },
-	{ SYS_DESC(SYS_SMCR_EL1), undef_access },
+	{ SYS_DESC(SYS_SMCR_EL1), NULL, reset_val, SMCR_EL1, 0, .visibility = sme_visibility },
 	{ SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },
 	{ SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 },
 	{ SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 },
@@ -2995,6 +3027,9 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	EL2_REG_VNCR(HCRX_EL2, reset_val, 0),
 
+	EL2_REG_FILTERED(SMCR_EL2, access_smcr_el2, reset_val, 0,
+			 sme_el2_visibility),
+
 	EL2_REG(TTBR0_EL2, access_rw, reset_val, 0),
 	EL2_REG(TTBR1_EL2, access_rw, reset_val, 0),
 	EL2_REG(TCR_EL2, access_rw, reset_val, TCR_EL2_RES1),

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:42 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:42 +0000
Subject: [PATCH RFC v3 17/27] KVM: arm64: Support TPIDR2_EL0
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-17-05b018c1ffeb@kernel.org>

SME adds a new thread ID register, TPIDR2_EL0. This is used in userspace
for delayed saving of the ZA state but in terms of the architecture is
not really connected to SME other than being part of FEAT_SME. It has an
independent fine grained trap and the runtime connection with the rest
of SME is purely software defined.

Expose the register as a system register if the guest supports SME,
context switching it along with the other EL0 TPIDRs.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h          |  1 +
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 15 +++++++++++++++
 arch/arm64/kvm/sys_regs.c                  |  9 ++++++---
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 8d6342dde02fd99cfd7d2bedeccf0581ad3504ee..063b75eb4f3bc4fb425d2abc8118a950bccc2317 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -428,6 +428,7 @@ enum vcpu_sysreg {
 	CSSELR_EL1,	/* Cache Size Selection Register */
 	TPIDR_EL0,	/* Thread ID, User R/W */
 	TPIDRRO_EL0,	/* Thread ID, User R/O */
+	TPIDR2_EL0,	/* Thread ID, Register 2 */
 	TPIDR_EL1,	/* Thread ID, Privileged */
 	CNTKCTL_EL1,	/* Timer Control Register (EL1) */
 	PAR_EL1,	/* Physical Address Register */
diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index 8c234d53acb2753c59aa37d7a66f856f2eb87882..93d2b81e8d0678a16c88bda3549ee790db7f5bc2 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -66,6 +66,17 @@ static inline bool ctxt_has_s1poe(struct kvm_cpu_context *ctxt)
 	return kvm_has_s1poe(kern_hyp_va(vcpu->kvm));
 }
 
+static inline bool ctxt_has_sme(struct kvm_cpu_context *ctxt)
+{
+	struct kvm_vcpu *vcpu;
+
+	if (!system_supports_sme())
+		return false;
+
+	vcpu = ctxt_to_vcpu(ctxt);
+	return kvm_has_sme(kern_hyp_va(vcpu->kvm));
+}
+
 static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
 {
 	ctxt_sys_reg(ctxt, MDSCR_EL1)	= read_sysreg(mdscr_el1);
@@ -79,6 +90,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 (ctxt_has_sme(ctxt))
+		ctxt_sys_reg(ctxt, TPIDR2_EL0)	= read_sysreg_s(SYS_TPIDR2_EL0);
 }
 
 static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
@@ -148,6 +161,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 (ctxt_has_sme(ctxt))
+		write_sysreg_s(ctxt_sys_reg(ctxt, TPIDR2_EL0), SYS_TPIDR2_EL0);
 }
 
 static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt,
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index a9429d9d63b54b5b4d4fe365aa6af4d84a256539..b5a38fc7a4a9ed4fce053018eb6ff353ae5c0d09 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2855,7 +2855,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	  .visibility = s1poe_visibility },
 	{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
 	{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
-	{ SYS_DESC(SYS_TPIDR2_EL0), undef_access },
+	{ SYS_DESC(SYS_TPIDR2_EL0), NULL, reset_unknown, TPIDR2_EL0,
+	  .visibility = sme_visibility},
 
 	{ SYS_DESC(SYS_SCXTNUM_EL0), undef_access },
 
@@ -4959,8 +4960,7 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
 				       HFGxTR_EL2_nMAIR2_EL1		|
 				       HFGxTR_EL2_nS2POR_EL1		|
 				       HFGxTR_EL2_nACCDATA_EL1		|
-				       HFGxTR_EL2_nSMPRI_EL1_MASK	|
-				       HFGxTR_EL2_nTPIDR2_EL0_MASK);
+				       HFGxTR_EL2_nSMPRI_EL1_MASK);
 
 	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
 		kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1OS|
@@ -5007,6 +5007,9 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
 		kvm->arch.fgu[HAFGRTR_GROUP] |= ~(HAFGRTR_EL2_RES0 |
 						  HAFGRTR_EL2_RES1);
 
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
+		kvm->arch.fgu[HFGxTR_GROUP] |= HFGxTR_EL2_nTPIDR2_EL0;
+
 	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
 out:
 	mutex_unlock(&kvm->arch.config_lock);

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:43 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:43 +0000
Subject: [PATCH RFC v3 18/27] KVM: arm64: Support SMIDR_EL1 for guests
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-18-05b018c1ffeb@kernel.org>

SME adds an identification register SMIDR_EL1 which provides a basic
description of the SME implementation, describing the implementation
in a manner similar to MIDR_EL1 for the PE as well as indicating support
for priority management.

Since we do not currently support SME priority control we mask out SMPS,
indicating that priority management is not supported.  We do the same
for Affinity, indicating that there is no physical sharing, and unknown
fields.

As for MIDR_EL1 and REVIDR_EL1 we expose the implementer and revision
information to guests with the raw value from the CPU we are running on,
this may present issues for asymmetric systems or for migration as it
does for the existing registers.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/sys_regs.c         | 46 ++++++++++++++++++++++++++++++++++++---
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 063b75eb4f3bc4fb425d2abc8118a950bccc2317..a304b02efcadba5371edffe97e911bba0634ed62 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -472,6 +472,7 @@ enum vcpu_sysreg {
 	/* FP/SIMD/SVE */
 	SVCR,
 	FPMR,
+	SMIDR_EL1,	/* Streaming Mode Identification Register */
 
 	/* 32bit specific registers. */
 	DACR32_EL2,	/* Domain Access Control Register */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index b5a38fc7a4a9ed4fce053018eb6ff353ae5c0d09..416c855153ca532e4c6557d78599e9af0f913071 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -882,6 +882,39 @@ static u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 	return mpidr;
 }
 
+static u64 reset_smidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	u64 smidr = 0;
+
+	if (!system_supports_sme())
+		return smidr;
+
+	smidr = read_sysreg_s(SYS_SMIDR_EL1);
+
+	/*
+	 * Mask out any priority or affinity information, or fields we
+	 * don't know about.
+	 */
+	smidr &= ~(SMIDR_EL1_SMPS_MASK | SMIDR_EL1_AFFINITY_MASK |
+		   SMIDR_EL1_RES0);
+
+	vcpu_write_sys_reg(vcpu, smidr, SMIDR_EL1);
+
+	return smidr;
+}
+
+static bool access_smidr(struct kvm_vcpu *vcpu,
+			 struct sys_reg_params *p,
+			 const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	p->regval = vcpu_read_sys_reg(vcpu, r->reg);
+
+	return true;
+}
+
 static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu,
 				   const struct sys_reg_desc *r)
 {
@@ -1576,7 +1609,9 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
 		if (!kvm_has_mte(vcpu->kvm))
 			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
 
-		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
+		if (!vcpu_has_sme(vcpu))
+			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
+
 		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_RNDR_trap);
 		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_NMI);
 		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE_frac);
@@ -1676,6 +1711,10 @@ static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
 		if (!vcpu_has_sve(vcpu))
 			return REG_RAZ;
 		break;
+	case SYS_ID_AA64SMFR0_EL1:
+		if (!vcpu_has_sme(vcpu))
+			return REG_RAZ;
+		break;
 	}
 
 	return 0;
@@ -2601,7 +2640,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR),
 	ID_UNALLOCATED(4,3),
 	ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0),
-	ID_HIDDEN(ID_AA64SMFR0_EL1),
+	ID_WRITABLE(ID_AA64SMFR0_EL1, ~ID_AA64SMFR0_EL1_RES0),
 	ID_UNALLOCATED(4,6),
 	ID_WRITABLE(ID_AA64FPFR0_EL1, ~ID_AA64FPFR0_EL1_RES0),
 
@@ -2799,7 +2838,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_CLIDR_EL1), access_clidr, reset_clidr, CLIDR_EL1,
 	  .set_user = set_clidr, .val = ~CLIDR_EL1_RES0 },
 	{ SYS_DESC(SYS_CCSIDR2_EL1), undef_access },
-	{ SYS_DESC(SYS_SMIDR_EL1), undef_access },
+	{ SYS_DESC(SYS_SMIDR_EL1), .access = access_smidr, .reset = reset_smidr,
+	  .reg = SMIDR_EL1, .visibility = sme_visibility },
 	{ SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
 	ID_FILTERED(CTR_EL0, ctr_el0,
 		    CTR_EL0_DIC_MASK |

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:44 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:44 +0000
Subject: [PATCH RFC v3 19/27] KVM: arm64: Support SME priority registers
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-19-05b018c1ffeb@kernel.org>

SME has optional support for configuring the relative priorities of PEs
in systems where they share a single SME hardware block, known as a
SMCU. Currently we do not have any support for this in Linux and will
also hide it from KVM guests, pending experience with practical
implementations. The interface for configuring priority support is via
two new system registers, these registers are always available if SME is
supported.

The register SMPRI_EL1 allows control of SME execution priorities. Since
we disable SME priority support for guests this register is RAZ, define
it as such and enable fine grained traps for SMPRI_EL1 to ensure that
guests can't write to it even if the hardware supports priorites.  We
could with some adjustment to the generic FGT code allow untrapped reads
but since we don't currently advertise priority support to guests there
should be no reason for frequent accesses.

There is also an EL2 register SMPRIMAP_EL2 for virtualisation of
priorities, this is also RAZ when priority configuration is not
supported but has no specific traps available.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h     |  2 ++
 arch/arm64/include/asm/vncr_mapping.h |  1 +
 arch/arm64/kvm/sys_regs.c             | 30 +++++++++++++++++++++++++-----
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a304b02efcadba5371edffe97e911bba0634ed62..f72024ffc89d955b3a0a20b6503ceb451abe824f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -473,6 +473,7 @@ enum vcpu_sysreg {
 	SVCR,
 	FPMR,
 	SMIDR_EL1,	/* Streaming Mode Identification Register */
+	SMPRI_EL1,	/* Streaming Mode Priority Register */
 
 	/* 32bit specific registers. */
 	DACR32_EL2,	/* Domain Access Control Register */
@@ -525,6 +526,7 @@ enum vcpu_sysreg {
 	VNCR(CPACR_EL1),/* Coprocessor Access Control */
 	VNCR(ZCR_EL1),	/* SVE Control */
 	VNCR(SMCR_EL1),	/* SME Control */
+	VNCR(SMPRIMAP_EL2),	/* Streaming Mode Priority Mapping Register */
 	VNCR(TTBR0_EL1),/* Translation Table Base Register 0 */
 	VNCR(TTBR1_EL1),/* Translation Table Base Register 1 */
 	VNCR(TCR_EL1),	/* Translation Control Register */
diff --git a/arch/arm64/include/asm/vncr_mapping.h b/arch/arm64/include/asm/vncr_mapping.h
index 74fc7400efbc7de6b8dd81a485f1e9d545baf7a9..1685df741294b68e5ae4a4503258c3ee2667dda9 100644
--- a/arch/arm64/include/asm/vncr_mapping.h
+++ b/arch/arm64/include/asm/vncr_mapping.h
@@ -43,6 +43,7 @@
 #define VNCR_ZCR_EL1            0x1E0
 #define VNCR_HAFGRTR_EL2	0x1E8
 #define VNCR_SMCR_EL1		0x1F0
+#define VNCR_SMPRIMAP_EL2	0x1F0
 #define VNCR_TTBR0_EL1          0x200
 #define VNCR_TTBR1_EL1          0x210
 #define VNCR_FAR_EL1            0x220
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 416c855153ca532e4c6557d78599e9af0f913071..c327b5544ad95c965a3d24cea059997eb57135f2 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1782,6 +1782,15 @@ static unsigned int fp8_visibility(const struct kvm_vcpu *vcpu,
 	return REG_HIDDEN;
 }
 
+static unsigned int sme_raz_visibility(const struct kvm_vcpu *vcpu,
+				       const struct sys_reg_desc *rd)
+{
+	if (vcpu_has_sme(vcpu))
+		return REG_RAZ;
+
+	return REG_HIDDEN;
+}
+
 static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
 {
 	if (!vcpu_has_sve(vcpu))
@@ -2719,7 +2728,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility },
 	{ SYS_DESC(SYS_TRFCR_EL1), undef_access },
-	{ SYS_DESC(SYS_SMPRI_EL1), undef_access },
+
+	/*
+	 * SMPRI_EL1 is UNDEF when SME is disabled, the UNDEF is
+	 * handled via FGU which is handled without consulting this
+	 * table.
+	 */
+	{ SYS_DESC(SYS_SMPRI_EL1), trap_raz_wi, .visibility = sme_raz_visibility },
+
 	{ SYS_DESC(SYS_SMCR_EL1), NULL, reset_val, SMCR_EL1, 0, .visibility = sme_visibility },
 	{ SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },
 	{ SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 },
@@ -3068,6 +3084,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	EL2_REG_VNCR(HCRX_EL2, reset_val, 0),
 
+	EL2_REG_FILTERED(SMPRIMAP_EL2, trap_raz_wi, reset_val, 0,
+			 sme_el2_visibility),
 	EL2_REG_FILTERED(SMCR_EL2, access_smcr_el2, reset_val, 0,
 			 sme_el2_visibility),
 
@@ -4999,8 +5017,7 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
 	kvm->arch.fgu[HFGxTR_GROUP] = (HFGxTR_EL2_nAMAIR2_EL1		|
 				       HFGxTR_EL2_nMAIR2_EL1		|
 				       HFGxTR_EL2_nS2POR_EL1		|
-				       HFGxTR_EL2_nACCDATA_EL1		|
-				       HFGxTR_EL2_nSMPRI_EL1_MASK);
+				       HFGxTR_EL2_nACCDATA_EL1);
 
 	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
 		kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1OS|
@@ -5047,8 +5064,11 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
 		kvm->arch.fgu[HAFGRTR_GROUP] |= ~(HAFGRTR_EL2_RES0 |
 						  HAFGRTR_EL2_RES1);
 
-	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
-		kvm->arch.fgu[HFGxTR_GROUP] |= HFGxTR_EL2_nTPIDR2_EL0;
+	if (kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
+		kvm->arch.fgt[HFGxTR_GROUP] |= HFGxTR_EL2_nSMPRI_EL1_MASK;
+	else
+		kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nTPIDR2_EL0 |
+						HFGxTR_EL2_nSMPRI_EL1_MASK);
 
 	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
 out:

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:48 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:48 +0000
Subject: [PATCH RFC v3 23/27] KVM: arm64: Context switch SME state for
 normal guests
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-23-05b018c1ffeb@kernel.org>

If the guest has SME state we need to context switch that state, provide
support for that for normal guests.

SME has three sets of registers, ZA, ZT (only present for SME2) and also
streaming SVE which replaces the standard floating point registers when
active. The first two are fairly straightforward, they are accessible only
when PSTATE.ZA is set and we can reuse the assembly from the host to save
and load them from a single contiguous buffer. When PSTATE.ZA is not set
then these registers are inaccessible, if the guest enables PSTATE.ZA then
all bits will be set to 0 and nothing is required on restore.

Streaming mode is slightly more complicated, when enabled via PSTATE.SM it
provides a version of the SVE registers using the SME vector length and may
optionally omit the FFR register. SME may also be present without SVE. The
register state is stored in sve_state as for non-streaming SVE mode, we
make an initial selection of registers to update based on the guest SVE
support and then override this when loading SVCR if streaming mode is
enabled.

Since in order to avoid duplication with SME we now restore the register
state outside of the SVE specific restore function we need to move the
restore of the effective VL for nested guests to a separate restore
function run after loading the floating point register state, along with
the similar handling required for SME.

The selection of which vector length to use is handled by vcpu_sve_pffr().

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h         |  9 ++++
 arch/arm64/include/asm/kvm_emulate.h    |  6 +++
 arch/arm64/include/asm/kvm_host.h       |  3 ++
 arch/arm64/kvm/fpsimd.c                 | 86 ++++++++++++++++++++----------
 arch/arm64/kvm/hyp/include/hyp/switch.h | 93 ++++++++++++++++++++++++++++-----
 5 files changed, 156 insertions(+), 41 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 144cc805bfea112341b89c9c6028cf4b2a201c6c..f517b371e0132271a9bd693349a828e2b824ff07 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -442,6 +442,15 @@ static inline size_t sme_state_size(struct task_struct const *task)
 			write_sysreg_s(__new, (reg));		\
 	} while (0)
 
+#define sme_cond_update_smcr_vq(val, reg)			\
+	do {							\
+		u64 __smcr = read_sysreg_s((reg));		\
+		u64 __new = __smcr & ~SMCR_ELx_LEN_MASK;	\
+		__new |= (val) & SMCR_ELx_LEN_MASK;		\
+		if (__smcr != __new)				\
+			write_sysreg_s(__new, (reg));		\
+	} while (0)
+
 /* For use by EFI runtime services calls only */
 extern void __efi_fpsimd_begin(void);
 extern void __efi_fpsimd_end(void);
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 5f05da7f538d29d321c424233f21b8448d8b4628..c7f3d14c1d69d9b3f7c1c22ad0919c278d2140c1 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -688,4 +688,10 @@ static inline bool guest_hyp_sve_traps_enabled(const struct kvm_vcpu *vcpu)
 {
 	return __guest_hyp_cptr_xen_trap_enabled(vcpu, ZEN);
 }
+
+static inline bool guest_hyp_sme_traps_enabled(const struct kvm_vcpu *vcpu)
+{
+	return __guest_hyp_cptr_xen_trap_enabled(vcpu, SMEN);
+}
+
 #endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 3e064520a86f25fb7b1185b3aca342f593f04994..4fcb2c2603ae2bc51d6993f1f6a3f81f2689717c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1013,6 +1013,9 @@ struct kvm_vcpu_arch {
 #define vcpu_sve_zcr_elx(vcpu)						\
 	(unlikely(is_hyp_ctxt(vcpu)) ? ZCR_EL2 : ZCR_EL1)
 
+#define vcpu_sme_smcr_elx(vcpu)						\
+	(unlikely(is_hyp_ctxt(vcpu)) ? SMCR_EL2 : SMCR_EL1)
+
 #define vcpu_sve_state_size(vcpu) ({					\
 	size_t __size_ret;						\
 	unsigned int __vcpu_vq;						\
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 51c844e25dfa460ecab5bb0dfc50c7680318aa20..d2a47d7163374ea51157c4817dd13fa43bd2146a 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -127,19 +127,25 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 	WARN_ON_ONCE(!irqs_disabled());
 
 	if (guest_owns_fp_regs()) {
-		/*
-		 * Currently we do not support SME guests so SVCR is
-		 * always 0 and we just need a variable to point to.
-		 */
 		fp_state.st = &vcpu->arch.ctxt.fp_regs;
 		fp_state.sve_state = vcpu->arch.sve_state;
 		fp_state.sve_vl = vcpu->arch.max_vl[ARM64_VEC_SVE];
-		fp_state.sme_state = NULL;
+		fp_state.sme_vl = vcpu->arch.max_vl[ARM64_VEC_SME];
+		fp_state.sme_state = vcpu->arch.sme_state;
 		fp_state.svcr = &__vcpu_sys_reg(vcpu, SVCR);
 		fp_state.fpmr = &__vcpu_sys_reg(vcpu, FPMR);
 		fp_state.fp_type = &vcpu->arch.fp_type;
+
 		fp_state.sme_features = 0;
+		if (kvm_has_fa64(vcpu->kvm))
+			fp_state.sme_features |= SMCR_ELx_FA64;
+		if (kvm_has_sme2(vcpu->kvm))
+			fp_state.sme_features |= SMCR_ELx_EZT0;
 
+		/*
+		 * For SME only hosts fpsimd_save() will override the
+		 * state selection if we are in streaming mode.
+		 */
 		if (vcpu_has_sve(vcpu))
 			fp_state.to_save = FP_STATE_SVE;
 		else
@@ -186,6 +192,32 @@ static void kvm_vcpu_put_sve(struct kvm_vcpu *vcpu)
 				       SYS_ZCR_EL1);
 }
 
+static void kvm_vcpu_put_sme(struct kvm_vcpu *vcpu)
+{
+	u64 smcr;
+
+	if (!vcpu_has_sme(vcpu))
+		return;
+
+	smcr = read_sysreg_el1(SYS_SMCR);
+
+	/*
+	 * If the vCPU is in the hyp context then SMCR_EL1 is loaded
+	 * with its vEL2 counterpart.
+	 */
+	__vcpu_sys_reg(vcpu, vcpu_sme_smcr_elx(vcpu)) = smcr;
+
+	/*
+	 * As for SVE we always save the SME state for the guest using
+	 * the maximum VL supported by the guest so if we are using
+	 * nVHE or were in a nested guest we need to set the VL for
+	 * the host to match.
+	 */
+	if (!has_vhe() || (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)))
+		sme_cond_update_smcr_vq(vcpu_sme_max_vq(vcpu) - 1,
+					SYS_SMCR_EL1);
+}
+
 /*
  * Write back the vcpu FPSIMD regs if they are dirty, and invalidate the
  * cpu FPSIMD regs so that they can't be spuriously reused if this vcpu
@@ -198,23 +230,9 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 
 	local_irq_save(flags);
 
-	/*
-	 * If we have VHE then the Hyp code will reset CPACR_EL1 to
-	 * the default value and we need to reenable SME.
-	 */
-	if (has_vhe() && system_supports_sme()) {
-		/* Also restore EL0 state seen on entry */
-		if (vcpu_get_flag(vcpu, HOST_SME_ENABLED))
-			sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_SMEN);
-		else
-			sysreg_clear_set(CPACR_EL1,
-					 CPACR_EL1_SMEN_EL0EN,
-					 CPACR_EL1_SMEN_EL1EN);
-		isb();
-	}
-
 	if (guest_owns_fp_regs()) {
 		kvm_vcpu_put_sve(vcpu);
+		kvm_vcpu_put_sme(vcpu);
 
 		/*
 		 * Flush (save and invalidate) the FP state so that if
@@ -227,18 +245,30 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 		 * when needed.
 		 */
 		fpsimd_save_and_flush_cpu_state();
-	} else if (has_vhe() && system_supports_sve()) {
+	} else if (has_vhe() && (system_supports_sve() ||
+				 system_supports_sme())) {
 		/*
-		 * The FPSIMD/SVE state in the CPU has not been touched, and we
-		 * have SVE (and VHE): CPACR_EL1 (alias CPTR_EL2) has been
-		 * reset by kvm_reset_cptr_el2() in the Hyp code, disabling SVE
-		 * for EL0.  To avoid spurious traps, restore the trap state
-		 * seen by kvm_arch_vcpu_load_fp():
+		 * The FP state in the CPU has not been touched, and
+		 * we have a vector extension (and VHE): CPACR_EL1
+		 * (alias CPTR_EL2) has been reset by
+		 * kvm_reset_cptr_el2() in the Hyp code, disabling SVE
+		 * for EL0.  To avoid spurious traps, restore the trap
+		 * state seen by kvm_arch_vcpu_load_fp():
 		 */
+		u64 clear = 0;
+		u64 set = 0;
+
 		if (vcpu_get_flag(vcpu, HOST_SVE_ENABLED))
-			sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_ZEN_EL0EN);
+			set |= CPACR_EL1_ZEN_EL0EN;
 		else
-			sysreg_clear_set(CPACR_EL1, CPACR_EL1_ZEN_EL0EN, 0);
+			clear |= CPACR_EL1_ZEN_EL0EN;
+
+		if (vcpu_get_flag(vcpu, HOST_SME_ENABLED))
+			set |= CPACR_EL1_SMEN_EL0EN;
+		else
+			clear |= CPACR_EL1_SMEN_EL0EN;
+
+		sysreg_clear_set(CPACR_EL1, clear, set);
 	}
 
 	local_irq_restore(flags);
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 09a9a237d6dd22d4bb941714363675abdab1baa7..3aed023ccaf336320b5ca5acab82e30fb52fb63d 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -343,6 +343,37 @@ static bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return true;
 }
 
+static inline void __hyp_sme_restore_guest(struct kvm_vcpu *vcpu,
+					   bool *restore_sve,
+					   bool *restore_ffr)
+{
+	u64 old_smcr, new_smcr;
+	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
+	bool has_fa64 = kvm_has_fa64(kvm);
+	bool has_sme2 = kvm_has_sme2(kvm);
+
+	old_smcr = read_sysreg_s(SYS_SMCR_EL2);
+	new_smcr = vcpu_sme_max_vq(vcpu) - 1;
+	if (has_fa64)
+		new_smcr |= SMCR_ELx_FA64_MASK;
+	if (has_sme2)
+		new_smcr |= SMCR_ELx_EZT0_MASK;
+	if (old_smcr != new_smcr)
+		write_sysreg_s(new_smcr, SYS_SMCR_EL2);
+
+	write_sysreg_el1(__vcpu_sys_reg(vcpu, SMCR_EL1), SYS_SMCR);
+
+	write_sysreg_s(__vcpu_sys_reg(vcpu, SVCR), SYS_SVCR);
+
+	if (vcpu_in_streaming_mode(vcpu)) {
+		*restore_sve = true;
+		*restore_ffr = has_fa64;
+	}
+
+	if (vcpu_za_enabled(vcpu))
+		__sme_restore_state(vcpu_sme_state(vcpu), has_sme2);
+}
+
 static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
 {
 	/*
@@ -350,19 +381,26 @@ static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
 	 * vCPU. Start off with the max VL so we can load the SVE state.
 	 */
 	sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
-	__sve_restore_state(vcpu_sve_pffr(vcpu),
-			    &vcpu->arch.ctxt.fp_regs.fpsr,
-			    true);
 
+	write_sysreg_el1(__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)), SYS_ZCR);
+}
+
+static inline void __hyp_nv_restore_guest_vls(struct kvm_vcpu *vcpu)
+{
 	/*
-	 * The effective VL for a VM could differ from the max VL when running a
-	 * nested guest, as the guest hypervisor could select a smaller VL. Slap
-	 * that into hardware before wrapping up.
+	 * The effective VL for a VM could differ from the max VL when
+	 * running a nested guest, as the guest hypervisor could
+	 * select a smaller VL. Slap that into hardware before
+	 * wrapping up.
 	 */
-	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu))
+	if (!(vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)))
+		return;
+
+	if (vcpu_has_sve(vcpu))
 		sve_cond_update_zcr_vq(__vcpu_sys_reg(vcpu, ZCR_EL2), SYS_ZCR_EL2);
 
-	write_sysreg_el1(__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)), SYS_ZCR);
+	if (vcpu_has_sme(vcpu))
+		sme_cond_update_smcr_vq(__vcpu_sys_reg(vcpu, SMCR_EL2), SYS_SMCR_EL2);
 }
 
 static inline void __hyp_sve_save_host(void)
@@ -386,14 +424,18 @@ static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu);
  */
 static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
-	bool sve_guest;
-	u8 esr_ec;
+	u64 cpacr;
+	bool restore_sve, restore_ffr;
+	bool sve_guest, sme_guest;
+	u8 esr_ec, esr_iss;
 
 	if (!system_supports_fpsimd())
 		return false;
 
 	sve_guest = vcpu_has_sve(vcpu);
+	sme_guest = vcpu_has_sme(vcpu);
 	esr_ec = kvm_vcpu_trap_get_class(vcpu);
+	esr_iss = ESR_ELx_ISS(kvm_vcpu_get_esr(vcpu));
 
 	/* Only handle traps the vCPU can support here: */
 	switch (esr_ec) {
@@ -412,6 +454,15 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 		if (guest_hyp_sve_traps_enabled(vcpu))
 			return false;
 		break;
+	case ESR_ELx_EC_SME:
+		if (!sme_guest)
+			return false;
+		if (guest_hyp_sme_traps_enabled(vcpu))
+			return false;
+		if (!kvm_has_sme2(vcpu->kvm) &&
+		    (esr_iss == ESR_ELx_SME_ISS_ZT_DISABLED))
+			return false;
+		break;
 	default:
 		return false;
 	}
@@ -419,10 +470,12 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 	/* Valid trap.  Switch the context: */
 
 	/* First disable enough traps to allow us to update the registers */
+	cpacr = CPACR_ELx_FPEN;
 	if (sve_guest || (is_protected_kvm_enabled() && system_supports_sve()))
-		cpacr_clear_set(0, CPACR_ELx_FPEN | CPACR_ELx_ZEN);
-	else
-		cpacr_clear_set(0, CPACR_ELx_FPEN);
+		cpacr |= CPACR_ELx_ZEN;
+	if (sme_guest)
+		cpacr |= CPACR_ELx_SMEN;
+	cpacr_clear_set(0, cpacr);
 	isb();
 
 	/* Write out the host state if it's in the registers */
@@ -430,8 +483,20 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 		kvm_hyp_save_fpsimd_host(vcpu);
 
 	/* Restore the guest state */
+
+	/* These may be overridden for a SME guest */
+	restore_sve = sve_guest;
+	restore_ffr = sve_guest;
+
 	if (sve_guest)
 		__hyp_sve_restore_guest(vcpu);
+	if (sme_guest)
+		__hyp_sme_restore_guest(vcpu, &restore_sve, &restore_ffr);
+
+	if (restore_sve)
+		__sve_restore_state(vcpu_sve_pffr(vcpu),
+				    &vcpu->arch.ctxt.fp_regs.fpsr,
+				    restore_ffr);
 	else
 		__fpsimd_restore_state(&vcpu->arch.ctxt.fp_regs);
 
@@ -442,6 +507,8 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 	if (!(read_sysreg(hcr_el2) & HCR_RW))
 		write_sysreg(__vcpu_sys_reg(vcpu, FPEXC32_EL2), fpexc32_el2);
 
+	__hyp_nv_restore_guest_vls(vcpu);
+
 	*host_data_ptr(fp_owner) = FP_STATE_GUEST_OWNED;
 
 	return true;

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:49 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:49 +0000
Subject: [PATCH RFC v3 24/27] KVM: arm64: Handle SME exceptions
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-24-05b018c1ffeb@kernel.org>

The access control for SME follows the same structure as for the base FP
and SVE extensions, with control being via CPACR_ELx.SMEN and CPTR_EL2.TSM
mirroring the equivalent FPSIMD and SVE controls in those registers.Add
handling for these controls and exceptions mirroring the existing handling
for FPSIMD and SVE.

When the hardware is in streaming mode guest operations that are invalid in
in streaming mode will generate SME exceptions. Since these exceptions may
be routed to EL1 with no opportunity for the hypervisor to intercept them
we already have code in kvm_arch_vcpu_load_fp() which ensures that we exit
streaming mode before running the guest. This ensures that guests do not
receive unexpected SME exceptions.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h |  4 ++--
 arch/arm64/kvm/handle_exit.c         | 14 ++++++++++++++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c   |  6 ++++++
 arch/arm64/kvm/hyp/nvhe/switch.c     | 11 ++++++-----
 arch/arm64/kvm/hyp/vhe/switch.c      | 21 ++++++++++++++++-----
 5 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index c7f3d14c1d69d9b3f7c1c22ad0919c278d2140c1..4c52945779a20604e18d96c78ff920abec9c4dfe 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -624,14 +624,14 @@ static __always_inline void __kvm_reset_cptr_el2(struct kvm *kvm)
 
 		if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
 			val |= CPACR_ELx_ZEN;
-		if (cpus_have_final_cap(ARM64_SME))
+		if (!kvm_has_sme(kvm) || !guest_owns_fp_regs())
 			val |= CPACR_ELx_SMEN;
 	} else {
 		val = CPTR_NVHE_EL2_RES1;
 
 		if (kvm_has_sve(kvm) && guest_owns_fp_regs())
 			val |= CPTR_EL2_TZ;
-		if (!cpus_have_final_cap(ARM64_SME))
+		if (kvm_has_sme(kvm) && guest_owns_fp_regs())
 			val |= CPTR_EL2_TSM;
 	}
 
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index d7c2990e7c9ed671833d1011638adeb2c15efd06..48076d0e34038808a36caf2310e11519fd04dd82 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -224,6 +224,19 @@ static int handle_sve(struct kvm_vcpu *vcpu)
 	return 1;
 }
 
+/*
+ * Guest access to SME registers should be routed to this handler only
+ * when the system doesn't support SME.
+ */
+static int handle_sme(struct kvm_vcpu *vcpu)
+{
+	if (guest_hyp_sme_traps_enabled(vcpu))
+		return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+
+	kvm_inject_undefined(vcpu);
+	return 1;
+}
+
 /*
  * Two possibilities to handle a trapping ptrauth instruction:
  *
@@ -307,6 +320,7 @@ static exit_handle_fn arm_exit_handlers[] = {
 	[ESR_ELx_EC_SVC64]	= handle_svc,
 	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
 	[ESR_ELx_EC_SVE]	= handle_sve,
+	[ESR_ELx_EC_SME]	= handle_sme,
 	[ESR_ELx_EC_ERET]	= kvm_handle_eret,
 	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
 	[ESR_ELx_EC_DABT_LOW]	= kvm_handle_guest_abort,
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 7468d8516ecaa1370861e51ad4f65adbc01a5d97..481ecd757e0eba021dad6f3b268bb5235f803553 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -487,6 +487,12 @@ void handle_trap(struct kvm_cpu_context *host_ctxt)
 		sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_max_vl[ARM64_VEC_SVE]) - 1,
 				       SYS_ZCR_EL2);
 		break;
+	case ESR_ELx_EC_SME:
+		cpacr_clear_set(0, CPACR_ELx_SMEN);
+		isb();
+		sme_cond_update_smcr_vq(sve_vq_from_vl(kvm_host_max_vl[ARM64_VEC_SME]) - 1,
+					SYS_SMCR_EL2);
+		break;
 	case ESR_ELx_EC_IABT_LOW:
 	case ESR_ELx_EC_DABT_LOW:
 		handle_host_mem_abort(host_ctxt);
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 0ebf84a9f9e2715793bcd08c494539be25b6870e..7d29585f1fa03ad6b0063a82dcfba4c5c0b1e4a5 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -46,15 +46,14 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
 			val |= CPACR_ELx_FPEN;
 			if (vcpu_has_sve(vcpu))
 				val |= CPACR_ELx_ZEN;
+			if (vcpu_has_sme(vcpu))
+				val |= CPACR_ELx_SMEN;
 		}
 	} else {
 		val |= CPTR_EL2_TTA | CPTR_NVHE_EL2_RES1;
 
-		/*
-		 * Always trap SME since it's not supported in KVM.
-		 * TSM is RES1 if SME isn't implemented.
-		 */
-		val |= CPTR_EL2_TSM;
+		if (!vcpu_has_sme(vcpu) || !guest_owns_fp_regs())
+			val |= CPTR_EL2_TSM;
 
 		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
 			val |= CPTR_EL2_TZ;
@@ -225,6 +224,7 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[ESR_ELx_EC_CP15_32]		= kvm_hyp_handle_cp15_32,
 	[ESR_ELx_EC_SYS64]		= kvm_hyp_handle_sysreg,
 	[ESR_ELx_EC_SVE]		= kvm_hyp_handle_fpsimd,
+	[ESR_ELx_EC_SME]		= kvm_hyp_handle_fpsimd,
 	[ESR_ELx_EC_FP_ASIMD]		= kvm_hyp_handle_fpsimd,
 	[ESR_ELx_EC_IABT_LOW]		= kvm_hyp_handle_iabt_low,
 	[ESR_ELx_EC_DABT_LOW]		= kvm_hyp_handle_dabt_low,
@@ -236,6 +236,7 @@ static const exit_handler_fn pvm_exit_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= NULL,
 	[ESR_ELx_EC_SYS64]		= kvm_handle_pvm_sys64,
 	[ESR_ELx_EC_SVE]		= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_SME]		= kvm_handle_pvm_restricted,
 	[ESR_ELx_EC_FP_ASIMD]		= kvm_hyp_handle_fpsimd,
 	[ESR_ELx_EC_IABT_LOW]		= kvm_hyp_handle_iabt_low,
 	[ESR_ELx_EC_DABT_LOW]		= kvm_hyp_handle_dabt_low,
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 80581b1c399595fd64d0ccada498edac322480a6..b2ce97d47b2715d8d7c7f4f365dc9b39f93b0673 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -83,6 +83,8 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
 		val |= CPACR_ELx_FPEN;
 		if (vcpu_has_sve(vcpu))
 			val |= CPACR_ELx_ZEN;
+		if (vcpu_has_sme(vcpu))
+			val |= CPACR_ELx_SMEN;
 	} else {
 		__activate_traps_fpsimd32(vcpu);
 	}
@@ -126,6 +128,8 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
 		val &= ~CPACR_ELx_FPEN;
 	if (!(SYS_FIELD_GET(CPACR_ELx, ZEN, cptr) & BIT(0)))
 		val &= ~CPACR_ELx_ZEN;
+	if (!(SYS_FIELD_GET(CPACR_ELx, SMEN, cptr) & BIT(0)))
+		val &= ~CPACR_ELx_SMEN;
 
 	if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
 		val |= cptr & CPACR_ELx_E0POE;
@@ -380,22 +384,28 @@ static bool kvm_hyp_handle_cpacr_el1(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return true;
 }
 
-static bool kvm_hyp_handle_zcr_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
+static bool kvm_hyp_handle_vec_cr_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	u32 sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
 
 	if (!vcpu_has_nv(vcpu))
 		return false;
 
-	if (sysreg != SYS_ZCR_EL2)
+	switch (sysreg) {
+	case SYS_ZCR_EL2:
+	case SYS_SMCR_EL2:
+		break;
+	default:
 		return false;
+	}
 
 	if (guest_owns_fp_regs())
 		return false;
 
 	/*
-	 * ZCR_EL2 traps are handled in the slow path, with the expectation
-	 * that the guest's FP context has already been loaded onto the CPU.
+	 * ZCR_EL2 and SMCR_EL2 traps are handled in the slow path,
+	 * with the expectation that the guest's FP context has
+	 * already been loaded onto the CPU.
 	 *
 	 * Load the guest's FP context and unconditionally forward to the
 	 * slow path for handling (i.e. return false).
@@ -412,7 +422,7 @@ static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
 	if (kvm_hyp_handle_cpacr_el1(vcpu, exit_code))
 		return true;
 
-	if (kvm_hyp_handle_zcr_el2(vcpu, exit_code))
+	if (kvm_hyp_handle_vec_cr_el2(vcpu, exit_code))
 		return true;
 
 	return kvm_hyp_handle_sysreg(vcpu, exit_code);
@@ -422,6 +432,7 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= NULL,
 	[ESR_ELx_EC_CP15_32]		= kvm_hyp_handle_cp15_32,
 	[ESR_ELx_EC_SYS64]		= kvm_hyp_handle_sysreg_vhe,
+	[ESR_ELx_EC_SME]		= kvm_hyp_handle_fpsimd,
 	[ESR_ELx_EC_SVE]		= kvm_hyp_handle_fpsimd,
 	[ESR_ELx_EC_FP_ASIMD]		= kvm_hyp_handle_fpsimd,
 	[ESR_ELx_EC_IABT_LOW]		= kvm_hyp_handle_iabt_low,

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:50 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:50 +0000
Subject: [PATCH RFC v3 25/27] KVM: arm64: Provide interface for configuring
 and enabling SME for guests
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-25-05b018c1ffeb@kernel.org>

Since SME requires configuration of a vector length in order to know the
size of both the streaming mode SVE state and ZA array we implement a
capability for it and require that it be enabled and finalized before
the SME specific state can be accessed, similarly to SVE.

Due to the overlap with sizing the SVE state we finalise both SVE and
SME with a single finalization, preventing any further changes to the
SVE and SME configuration once KVM_ARM_VCPU_VEC (an alias for _VCPU_SVE)
has been finalised. This is not a thing of great elegance but it ensures
that we never have a state where one of SVE or SME is finalised and the
other not, avoiding complexity.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |   1 +
 arch/arm64/include/uapi/asm/kvm.h |   1 +
 arch/arm64/kvm/arm.c              |  10 ++++
 arch/arm64/kvm/reset.c            | 114 ++++++++++++++++++++++++++++++++------
 include/uapi/linux/kvm.h          |   1 +
 5 files changed, 109 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 4fcb2c2603ae2bc51d6993f1f6a3f81f2689717c..838f7ad8ec14b7549ebdfe11e991f664894cc4e7 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -79,6 +79,7 @@ extern unsigned int __ro_after_init kvm_host_max_vl[ARM64_VEC_MAX];
 DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
 
 int __init kvm_arm_init_sve(void);
+int __init kvm_arm_init_sme(void);
 
 u32 __attribute_const__ kvm_target_cpu(void);
 void kvm_reset_vcpu(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 5092f39138cbf17d9e89191de23ab2ee9f3fa77d..4110ff85623b6fe354038b2dffd59a27d0d6d75b 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -108,6 +108,7 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_PTRAUTH_ADDRESS	5 /* VCPU uses address authentication */
 #define KVM_ARM_VCPU_PTRAUTH_GENERIC	6 /* VCPU uses generic authentication */
 #define KVM_ARM_VCPU_HAS_EL2		7 /* Support nested virtualization */
+#define KVM_ARM_VCPU_SME		8 /* enable SME for this CPU */
 
 /*
  * An alias for _SVE since we finalize VL configuration for both SVE and SME
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 8a3d02cf0a7a28e6d2a2fe2b6d63a9dbbe2d4916..c8f44e2c54b613b53087c581176315bc3f4bb2c8 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -377,6 +377,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_SVE:
 		r = system_supports_sve();
 		break;
+	case KVM_CAP_ARM_SME:
+		r = system_supports_sme();
+		break;
 	case KVM_CAP_ARM_PTRAUTH_ADDRESS:
 	case KVM_CAP_ARM_PTRAUTH_GENERIC:
 		r = kvm_has_full_ptr_auth();
@@ -1378,6 +1381,9 @@ static unsigned long system_supported_vcpu_features(void)
 	if (!system_supports_sve())
 		clear_bit(KVM_ARM_VCPU_SVE, &features);
 
+	if (!system_supports_sme())
+		clear_bit(KVM_ARM_VCPU_SME, &features);
+
 	if (!kvm_has_full_ptr_auth()) {
 		clear_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, &features);
 		clear_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, &features);
@@ -2756,6 +2762,10 @@ static __init int kvm_arm_init(void)
 	if (err)
 		return err;
 
+	err = kvm_arm_init_sme();
+	if (err)
+		return err;
+
 	err = kvm_arm_vmid_alloc_init();
 	if (err) {
 		kvm_err("Failed to initialize VMID allocator.\n");
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 3cb91dc6dc3dc5cc484900dbd9f4cdfedb3e2b4a..78b5aa7976dbbfec35d83f5e373ef87636c2e3e4 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -76,6 +76,34 @@ int __init kvm_arm_init_sve(void)
 	return 0;
 }
 
+int __init kvm_arm_init_sme(void)
+{
+	if (system_supports_sme()) {
+		kvm_max_vl[ARM64_VEC_SME] = sme_max_virtualisable_vl();
+		kvm_host_max_vl[ARM64_VEC_SME] = sme_max_vl();
+		kvm_nvhe_sym(kvm_host_max_vl[ARM64_VEC_SME]) = kvm_host_max_vl[ARM64_VEC_SME];
+
+		/*
+		 * The get_sve_reg()/set_sve_reg() ioctl interface will need
+		 * to be extended with multiple register slice support in
+		 * order to support vector lengths greater than
+		 * VL_ARCH_MAX:
+		 */
+		if (WARN_ON(kvm_max_vl[ARM64_VEC_SME] > VL_ARCH_MAX))
+			kvm_max_vl[ARM64_VEC_SME] = VL_ARCH_MAX;
+
+		/*
+		 * Don't even try to make use of vector lengths that
+		 * aren't available on all CPUs, for now:
+		 */
+		if (kvm_max_vl[ARM64_VEC_SME] < sme_max_vl())
+			pr_warn("KVM: SME vector length for guests limited to %u bytes\n",
+				kvm_max_vl[ARM64_VEC_SME]);
+	}
+
+	return 0;
+}
+
 static void kvm_vcpu_enable_sve(struct kvm_vcpu *vcpu)
 {
 	vcpu->arch.max_vl[ARM64_VEC_SVE] = kvm_max_vl[ARM64_VEC_SVE];
@@ -88,42 +116,84 @@ static void kvm_vcpu_enable_sve(struct kvm_vcpu *vcpu)
 	set_bit(KVM_ARCH_FLAG_GUEST_HAS_SVE, &vcpu->kvm->arch.flags);
 }
 
+static void kvm_vcpu_enable_sme(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.max_vl[ARM64_VEC_SME] = kvm_max_vl[ARM64_VEC_SME];
+
+	/*
+	 * Userspace can still customize the vector lengths by writing
+	 * KVM_REG_ARM64_SME_VLS.  Allocation is deferred until
+	 * kvm_arm_vcpu_finalize(), which freezes the configuration.
+	 */
+	set_bit(KVM_ARCH_FLAG_GUEST_HAS_SME, &vcpu->kvm->arch.flags);
+}
+
 /*
- * Finalize vcpu's maximum SVE vector length, allocating
- * vcpu->arch.sve_state as necessary.
+ * Finalize vcpu's maximum vector lengths, allocating
+ * vcpu->arch.sve_state and vcpu->arch.sme_state as necessary.
  */
 static int kvm_vcpu_finalize_vec(struct kvm_vcpu *vcpu)
 {
-	void *buf;
+	void *sve_state, *sme_state;
 	unsigned int vl;
-	size_t reg_sz;
 	int ret;
 
-	vl = vcpu->arch.max_vl[ARM64_VEC_SVE];
-
 	/*
 	 * Responsibility for these properties is shared between
 	 * kvm_arm_init_sve(), kvm_vcpu_enable_sve() and
 	 * set_sve_vls().  Double-check here just to be sure:
 	 */
-	if (WARN_ON(!sve_vl_valid(vl) || vl > sve_max_virtualisable_vl() ||
-		    vl > VL_ARCH_MAX))
-		return -EIO;
+	if (vcpu_has_sve(vcpu)) {
+		vl = vcpu->arch.max_vl[ARM64_VEC_SVE];
+		if (WARN_ON(!sve_vl_valid(vl) ||
+			    vl > sve_max_virtualisable_vl() ||
+			    vl > VL_ARCH_MAX))
+			return -EIO;
+	}
 
-	reg_sz = vcpu_sve_state_size(vcpu);
-	buf = kzalloc(reg_sz, GFP_KERNEL_ACCOUNT);
-	if (!buf)
+	/* Similarly for SME */
+	if (vcpu_has_sme(vcpu)) {
+		vl = vcpu->arch.max_vl[ARM64_VEC_SME];
+		if (WARN_ON(!sve_vl_valid(vl) ||
+			    vl > sme_max_virtualisable_vl() ||
+			    vl > VL_ARCH_MAX))
+			return -EIO;
+	}
+
+	sve_state = kzalloc(vcpu_sve_state_size(vcpu), GFP_KERNEL_ACCOUNT);
+	if (!sve_state)
 		return -ENOMEM;
 
-	ret = kvm_share_hyp(buf, buf + reg_sz);
-	if (ret) {
-		kfree(buf);
-		return ret;
+	ret = kvm_share_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
+	if (ret)
+		goto err_sve_alloc;
+
+	if (vcpu_has_sme(vcpu)) {
+		sme_state = kzalloc(vcpu_sme_state_size(vcpu),
+				    GFP_KERNEL_ACCOUNT);
+		if (!sme_state) {
+			ret = -ENOMEM;
+			goto err_sve_map;
+		}
+
+		ret = kvm_share_hyp(sme_state,
+				    sme_state + vcpu_sme_state_size(vcpu));
+		if (ret)
+			goto err_sve_map;
+	} else {
+		sme_state = NULL;
 	}
-	
-	vcpu->arch.sve_state = buf;
+
+	vcpu->arch.sve_state = sve_state;
+	vcpu->arch.sme_state = sme_state;
 	vcpu_set_flag(vcpu, VCPU_VEC_FINALIZED);
 	return 0;
+
+err_sve_map:
+	kvm_unshare_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
+err_sve_alloc:
+	kfree(sve_state);
+	return ret;
 }
 
 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature)
@@ -153,11 +223,15 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu)
 void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
 	void *sve_state = vcpu->arch.sve_state;
+	void *sme_state = vcpu->arch.sme_state;
 
 	kvm_unshare_hyp(vcpu, vcpu + 1);
 	if (sve_state)
 		kvm_unshare_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
 	kfree(sve_state);
+	if (sme_state)
+		kvm_unshare_hyp(sme_state, sme_state + vcpu_sme_state_size(vcpu));
+	kfree(sme_state);
 	kfree(vcpu->arch.ccsidr);
 }
 
@@ -165,6 +239,8 @@ static void kvm_vcpu_reset_vec(struct kvm_vcpu *vcpu)
 {
 	if (vcpu_has_sve(vcpu))
 		memset(vcpu->arch.sve_state, 0, vcpu_sve_state_size(vcpu));
+	if (vcpu_has_sme(vcpu))
+		memset(vcpu->arch.sme_state, 0, vcpu_sme_state_size(vcpu));
 }
 
 /**
@@ -207,6 +283,8 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 	if (!kvm_arm_vcpu_vec_finalized(vcpu)) {
 		if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE))
 			kvm_vcpu_enable_sve(vcpu);
+		if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SME))
+			kvm_vcpu_enable_sme(vcpu);
 	} else {
 		kvm_vcpu_reset_vec(vcpu);
 	}
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 502ea63b5d2e7371f3f0d8cb5b9757ff693ee363..e478d9e5e8bff3beeddd39043a62337e0b9d688d 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -933,6 +933,7 @@ struct kvm_enable_cap {
 #define KVM_CAP_PRE_FAULT_MEMORY 236
 #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237
 #define KVM_CAP_X86_GUEST_MODE 238
+#define KVM_CAP_ARM_SME 239
 
 struct kvm_irq_routing_irqchip {
 	__u32 irqchip;

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:51 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:51 +0000
Subject: [PATCH RFC v3 26/27] KVM: arm64: selftests: Add SME system
 registers to get-reg-list
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-26-05b018c1ffeb@kernel.org>

SME adds a number of new system registers, update get-reg-list to check for
them based on the visibility of SME.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/kvm/aarch64/get-reg-list.c | 32 +++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/aarch64/get-reg-list.c b/tools/testing/selftests/kvm/aarch64/get-reg-list.c
index d43fb3f49050ba3de950d19d56b45beefec9dbeb..3e9c19c4a0d658f349a7d476a90b877882815709 100644
--- a/tools/testing/selftests/kvm/aarch64/get-reg-list.c
+++ b/tools/testing/selftests/kvm/aarch64/get-reg-list.c
@@ -23,6 +23,18 @@ struct feature_id_reg {
 };
 
 static struct feature_id_reg feat_id_regs[] = {
+	{
+		ARM64_SYS_REG(3, 0, 1, 2, 4),	/* SMPRI_EL1 */
+		ARM64_SYS_REG(3, 0, 0, 4, 1),	/* ID_AA64PFR1_EL1 */
+		24,
+		1
+	},
+	{
+		ARM64_SYS_REG(3, 0, 1, 2, 6),	/* SMCR_EL1 */
+		ARM64_SYS_REG(3, 0, 0, 4, 1),	/* ID_AA64PFR1_EL1 */
+		24,
+		1
+	},
 	{
 		ARM64_SYS_REG(3, 0, 2, 0, 3),	/* TCR2_EL1 */
 		ARM64_SYS_REG(3, 0, 0, 7, 3),	/* ID_AA64MMFR3_EL1 */
@@ -52,7 +64,25 @@ static struct feature_id_reg feat_id_regs[] = {
 		ARM64_SYS_REG(3, 0, 0, 7, 3),	/* ID_AA64MMFR3_EL1 */
 		16,
 		1
-	}
+	},
+	{
+		ARM64_SYS_REG(3, 1, 0, 0, 6),	/* SMIDR_EL1 */
+		ARM64_SYS_REG(3, 0, 0, 4, 1),	/* ID_AA64PFR1_EL1 */
+		24,
+		1
+	},
+	{
+		ARM64_SYS_REG(3, 3, 4, 2, 2),	/* SVCR */
+		ARM64_SYS_REG(3, 0, 0, 4, 1),	/* ID_AA64PFR1_EL1 */
+		24,
+		1
+	},
+	{
+		ARM64_SYS_REG(3, 3, 13, 0, 5),	/* TPIDR2_EL0 */
+		ARM64_SYS_REG(3, 0, 0, 4, 1),	/* ID_AA64PFR1_EL1 */
+		24,
+		1
+	},
 };
 
 bool filter_reg(__u64 reg)

-- 
2.39.5



From broonie at kernel.org  Fri Dec 20 08:46:52 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Dec 2024 16:46:52 +0000
Subject: [PATCH RFC v3 27/27] KVM: arm64: selftests: Add SME to set_id_regs
 test
In-Reply-To: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
References: <20241220-kvm-arm64-sme-v3-0-05b018c1ffeb@kernel.org>
Message-ID: <20241220-kvm-arm64-sme-v3-27-05b018c1ffeb@kernel.org>

Add coverage of the SME ID registers to set_id_regs, ID_AA64PFR1_EL1.SME
becomes writable and we add ID_AA64SMFR_EL1 and it's subfields.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/kvm/aarch64/set_id_regs.c | 29 +++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/aarch64/set_id_regs.c b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
index a79b7f18452d2ec336ae623b8aa5c9cf329b6b4e..ce20ca3bd2733002465ff690e3b99d23d1284de4 100644
--- a/tools/testing/selftests/kvm/aarch64/set_id_regs.c
+++ b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
@@ -138,6 +138,7 @@ static const struct reg_ftr_bits ftr_id_aa64pfr0_el1[] = {
 
 static const struct reg_ftr_bits ftr_id_aa64pfr1_el1[] = {
 	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, CSV2_frac, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, SME, 0),
 	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, SSBS, ID_AA64PFR1_EL1_SSBS_NI),
 	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, BT, 0),
 	REG_FTR_END,
@@ -183,6 +184,28 @@ static const struct reg_ftr_bits ftr_id_aa64mmfr2_el1[] = {
 	REG_FTR_END,
 };
 
+static const struct reg_ftr_bits ftr_id_aa64smfr0_el1[] = {
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, FA64, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, LUTv2, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, SMEver, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, I16I64, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, F64F64, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, I16I32, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, B16B16, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, F16F16, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, F8F16, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, F8F32, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, I8I32, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, F16F32, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, B16F32, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, BI32I32, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, F32F32, 0)
+,	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, SF8FMA, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, SF8DP4, 0),
+	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64SMFR0_EL1, SF8DP2, 0),
+	REG_FTR_END,
+};
+
 static const struct reg_ftr_bits ftr_id_aa64zfr0_el1[] = {
 	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64ZFR0_EL1, F64MM, 0),
 	REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64ZFR0_EL1, F32MM, 0),
@@ -213,6 +236,7 @@ static struct test_feature_reg test_regs[] = {
 	TEST_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0_el1),
 	TEST_REG(SYS_ID_AA64MMFR1_EL1, ftr_id_aa64mmfr1_el1),
 	TEST_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2_el1),
+	TEST_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64smfr0_el1),
 	TEST_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0_el1),
 };
 
@@ -229,6 +253,7 @@ static void guest_code(void)
 	GUEST_REG_SYNC(SYS_ID_AA64MMFR0_EL1);
 	GUEST_REG_SYNC(SYS_ID_AA64MMFR1_EL1);
 	GUEST_REG_SYNC(SYS_ID_AA64MMFR2_EL1);
+	GUEST_REG_SYNC(SYS_ID_AA64SMFR0_EL1);
 	GUEST_REG_SYNC(SYS_ID_AA64ZFR0_EL1);
 	GUEST_REG_SYNC(SYS_CTR_EL0);
 
@@ -676,8 +701,8 @@ int main(void)
 		   ARRAY_SIZE(ftr_id_aa64isar2_el1) + ARRAY_SIZE(ftr_id_aa64pfr0_el1) +
 		   ARRAY_SIZE(ftr_id_aa64pfr1_el1) + ARRAY_SIZE(ftr_id_aa64mmfr0_el1) +
 		   ARRAY_SIZE(ftr_id_aa64mmfr1_el1) + ARRAY_SIZE(ftr_id_aa64mmfr2_el1) +
-		   ARRAY_SIZE(ftr_id_aa64zfr0_el1) - ARRAY_SIZE(test_regs) + 2 +
-		   MPAM_IDREG_TEST;
+		   ARRAY_SIZE(ftr_id_aa64zfr0_el1) + ARRAY_SIZE(ftr_id_aa64smfr0_el1) - ARRAY_SIZE(test_regs) +
+		   2 + MPAM_IDREG_TEST;
 
 	ksft_set_plan(test_cnt);
 

-- 
2.39.5



From maz at kernel.org  Fri Dec 20 09:05:46 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Dec 2024 17:05:46 +0000
Subject: [PATCH v8 6/8] KVM: arm64: coresight: Give TRBE enabled state to KVM
In-Reply-To: <20241127100130.1162639-7-james.clark@linaro.org>
References: <20241127100130.1162639-1-james.clark@linaro.org>
	<20241127100130.1162639-7-james.clark@linaro.org>
Message-ID: <86ttayp9n9.wl-maz@kernel.org>

On Wed, 27 Nov 2024 10:01:23 +0000,
James Clark <james.clark at linaro.org> wrote:
> 
> Currently in nVHE, KVM has to check if TRBE is enabled on every guest
> switch even if it was never used. Because it's a debug feature and is
> more likely to not be used than used, give KVM the TRBE buffer status to
> allow a much simpler and faster do-nothing path in the hyp.
> 
> This is always called with preemption disabled except for probe/hotplug
> which gets wrapped with preempt_disable().
> 
> Protected mode disables trace regardless of TRBE (because
> guest_trfcr_el1 is always 0), which was not previously done. HAS_TRBE
> becomes redundant, but HAS_TRF is now required for this.
> 
> Signed-off-by: James Clark <james.clark at linaro.org>
> ---
>  arch/arm64/include/asm/kvm_host.h            | 10 +++-
>  arch/arm64/kvm/debug.c                       | 25 ++++++++--
>  arch/arm64/kvm/hyp/nvhe/debug-sr.c           | 51 +++++++++++---------
>  drivers/hwtracing/coresight/coresight-trbe.c |  5 ++
>  4 files changed, 65 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 7e3478386351..ba251caa593b 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -611,7 +611,8 @@ struct cpu_sve_state {
>   */
>  struct kvm_host_data {
>  #define KVM_HOST_DATA_FLAG_HAS_SPE	0
> -#define KVM_HOST_DATA_FLAG_HAS_TRBE	1
> +#define KVM_HOST_DATA_FLAG_HAS_TRF	1
> +#define KVM_HOST_DATA_FLAG_TRBE_ENABLED	2
>  	unsigned long flags;
>  
>  	struct kvm_cpu_context host_ctxt;
> @@ -657,6 +658,9 @@ struct kvm_host_data {
>  		u64 mdcr_el2;
>  	} host_debug_state;
>  
> +	/* Guest trace filter value */
> +	u64 guest_trfcr_el1;

Guest value? Or host state while running the guest? If the former,
then this has nothing to do here. If the latter, this should be
spelled out (trfcr_in_guest?), and the comment amended.

> +
>  	/* Number of programmable event counters (PMCR_EL0.N) for this CPU */
>  	unsigned int nr_event_counters;
>  };
> @@ -1381,6 +1385,8 @@ static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr)
>  void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
>  void kvm_clr_pmu_events(u64 clr);
>  bool kvm_set_pmuserenr(u64 val);
> +void kvm_enable_trbe(void);
> +void kvm_disable_trbe(void);
>  #else
>  static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {}
>  static inline void kvm_clr_pmu_events(u64 clr) {}
> @@ -1388,6 +1394,8 @@ static inline bool kvm_set_pmuserenr(u64 val)
>  {
>  	return false;
>  }
> +static inline void kvm_enable_trbe(void) {}
> +static inline void kvm_disable_trbe(void) {}
>  #endif
>  
>  void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index dd9e139dfd13..0c340ae7b5d1 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -314,7 +314,26 @@ void kvm_init_host_debug_data(void)
>  	    !(read_sysreg_s(SYS_PMBIDR_EL1) & PMBIDR_EL1_P))
>  		host_data_set_flag(HAS_SPE);
>  
> -	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
> -	    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
> -		host_data_set_flag(HAS_TRBE);
> +	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceFilt_SHIFT))
> +		host_data_set_flag(HAS_TRF);
>  }
> +
> +void kvm_enable_trbe(void)
> +{
> +	if (has_vhe() || is_protected_kvm_enabled() ||
> +	    WARN_ON_ONCE(preemptible()))
> +		return;
> +
> +	host_data_set_flag(TRBE_ENABLED);
> +}
> +EXPORT_SYMBOL_GPL(kvm_enable_trbe);
> +
> +void kvm_disable_trbe(void)
> +{
> +	if (has_vhe() || is_protected_kvm_enabled() ||
> +	    WARN_ON_ONCE(preemptible()))
> +		return;
> +
> +	host_data_clear_flag(TRBE_ENABLED);
> +}
> +EXPORT_SYMBOL_GPL(kvm_disable_trbe);
> diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> index 858bb38e273f..9479bee41801 100644
> --- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> +++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> @@ -51,32 +51,39 @@ static void __debug_restore_spe(u64 pmscr_el1)
>  	write_sysreg_el1(pmscr_el1, SYS_PMSCR);
>  }
>  
> -static void __debug_save_trace(u64 *trfcr_el1)
> +static void __trace_do_switch(u64 *saved_trfcr, u64 new_trfcr)
>  {
> -	*trfcr_el1 = 0;
> +	*saved_trfcr = read_sysreg_el1(SYS_TRFCR);
> +	write_sysreg_el1(new_trfcr, SYS_TRFCR);
>  
> -	/* Check if the TRBE is enabled */
> -	if (!(read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E))
> +	/* No need to drain if going to an enabled state or from disabled state */
> +	if (new_trfcr || !*saved_trfcr)

What if TRFCR_EL1.TS is set to something non-zero? I'd rather you
check for the E*TRE bits instead of assuming things.

>  		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_el1(SYS_TRFCR);
> -	write_sysreg_el1(0, SYS_TRFCR);
> +
>  	isb();
> -	/* Drain the trace buffer to memory */
>  	tsb_csync();
>  }
>  
> -static void __debug_restore_trace(u64 trfcr_el1)
> +static bool __trace_needs_switch(void)
>  {
> -	if (!trfcr_el1)
> -		return;
> +	return host_data_test_flag(TRBE_ENABLED) ||
> +	       (is_protected_kvm_enabled() && host_data_test_flag(HAS_TRF));
> +}
>  
> -	/* Restore trace filter controls */
> -	write_sysreg_el1(trfcr_el1, SYS_TRFCR);
> +static void __trace_switch_to_guest(void)
> +{
> +	/* Unsupported with TRBE so disable */
> +	if (host_data_test_flag(TRBE_ENABLED))
> +		*host_data_ptr(guest_trfcr_el1) = 0;
> +
> +	__trace_do_switch(host_data_ptr(host_debug_state.trfcr_el1),
> +			  *host_data_ptr(guest_trfcr_el1));
> +}
> +
> +static void __trace_switch_to_host(void)
> +{
> +	__trace_do_switch(host_data_ptr(guest_trfcr_el1),
> +			  *host_data_ptr(host_debug_state.trfcr_el1));
>  }
>  
>  void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
> @@ -84,9 +91,9 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
>  	/* Disable and flush SPE data generation */
>  	if (host_data_test_flag(HAS_SPE))
>  		__debug_save_spe(host_data_ptr(host_debug_state.pmscr_el1));
> -	/* Disable and flush Self-Hosted Trace generation */
> -	if (host_data_test_flag(HAS_TRBE))
> -		__debug_save_trace(host_data_ptr(host_debug_state.trfcr_el1));
> +
> +	if (__trace_needs_switch())
> +		__trace_switch_to_guest();
>  }
>  
>  void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
> @@ -98,8 +105,8 @@ void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
>  {
>  	if (host_data_test_flag(HAS_SPE))
>  		__debug_restore_spe(*host_data_ptr(host_debug_state.pmscr_el1));
> -	if (host_data_test_flag(HAS_TRBE))
> -		__debug_restore_trace(*host_data_ptr(host_debug_state.trfcr_el1));
> +	if (__trace_needs_switch())
> +		__trace_switch_to_host();
>  }
>  
>  void __debug_switch_to_host(struct kvm_vcpu *vcpu)
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 96a32b213669..9c0f8c43e6fe 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -18,6 +18,7 @@
>  #include <asm/barrier.h>
>  #include <asm/cpufeature.h>
>  #include <linux/vmalloc.h>
> +#include <linux/kvm_host.h>

Ordering of include files.

>  
>  #include "coresight-self-hosted-trace.h"
>  #include "coresight-trbe.h"
> @@ -221,6 +222,7 @@ static inline void set_trbe_enabled(struct trbe_cpudata *cpudata, u64 trblimitr)
>  	 */
>  	trblimitr |= TRBLIMITR_EL1_E;
>  	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
> +	kvm_enable_trbe();
>  
>  	/* Synchronize the TRBE enable event */
>  	isb();
> @@ -239,6 +241,7 @@ static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
>  	 */
>  	trblimitr &= ~TRBLIMITR_EL1_E;
>  	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
> +	kvm_disable_trbe();
>  
>  	if (trbe_needs_drain_after_disable(cpudata))
>  		trbe_drain_buffer();
> @@ -253,8 +256,10 @@ static void trbe_drain_and_disable_local(struct trbe_cpudata *cpudata)
>  
>  static void trbe_reset_local(struct trbe_cpudata *cpudata)
>  {
> +	preempt_disable();
>  	trbe_drain_and_disable_local(cpudata);
>  	write_sysreg_s(0, SYS_TRBLIMITR_EL1);
> +	preempt_enable();

This looks terribly wrong. If you need to disable preemption here, why
doesn't the critical section cover all register accesses? Surely you
don't want to nuke another CPU's context?

But looking at the calling sites, this makes even less sense. The two
callers of this thing mess with *per-CPU* interrupts. Dealing with
per-CPU interrupts in preemptible context is a big no-no (hint: they
start with a call to smp_processor_id()).

So what is this supposed to ensure?

	M.

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


From arnd at arndb.de  Fri Dec 20 09:06:44 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 20 Dec 2024 18:06:44 +0100
Subject: [PATCH v2 4/4] ARM: configs: stm32: Remove useless flags in STM32
 defconfig
In-Reply-To: <20241220125506.3157268-5-patrice.chotard@foss.st.com>
References: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
 <20241220125506.3157268-5-patrice.chotard@foss.st.com>
Message-ID: <c48b7e84-5287-4da0-84a0-7747581f49d0@app.fastmail.com>

On Fri, Dec 20, 2024, at 13:55, patrice.chotard at foss.st.com wrote:
> From: Patrice Chotard <patrice.chotard at foss.st.com>
>
> As stm32_defconfig is dedicated to STM32 MCUs, disable
> CONFIG_COMMON_CLK_STM32MP flag which is only used by STM32 MPUs.
>
> Disable CONFIG_SUSPEND, CONFIG_ADVISE_SYSCALLS, CONFIG_IO_URING
> CONFIG_POSIX_TIMERS, CONFIG_GCC_PLUGINS, it will reduce the kernel
> image size for these platforms which embed a low amount of memory.
>
> Tested on STM32F746-DISCO board which embeds 8MB of memory.

Out of curiosity, what is the smallest memory configuration that
you see people using on stm32f7/h7 these days? I know we had
configs that kind-of worked on 2MB in the past, but I assume there
has been a lot of bloat since.

       Arnd


From jonas at kwiboo.se  Fri Dec 20 09:09:01 2024
From: jonas at kwiboo.se (Jonas Karlman)
Date: Fri, 20 Dec 2024 18:09:01 +0100
Subject: [PATCH] arm64: dts: rockchip: ROCK3B: Correct clock rates for
 Ethernet PHYs
In-Reply-To: <20241220163227.1501912-1-alicja.michalska@9elements.com>
References: <20241220163227.1501912-1-alicja.michalska@9elements.com>
Message-ID: <17251add-40b7-4d18-8626-2d74b29532fc@kwiboo.se>

Hi Alicja,

On 2024-12-20 17:32, Alicja Michalska wrote:
> Built-in ethernet PHYs did not work on mainline kernel:
> 
> fe010000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
> fe010000.ethernet eth0: __stmmac_open: Cannot attach to PHY

Have you used mainline or vendor u-boot when testing?

There is an existing issue with RTL8211F PHYs that they must be reset
before Linux can identify them, see [1] for more details on the issue.

Mainline U-Boot will reset the Ethernet PHYs on this board and that
should allow for Linux to identify and use the Ethernet PHYs.

[1] https://lore.kernel.org/r/47d55aca-bee6-810f-379f-9431649fefa6 at kwiboo.se/

> 
> According to the board design, they need to be configured as output with
> static TX/RX delay. This patch sets it accordingly.
> 
> Signed-off-by: Alicja Michalska <alicja.michalska at 9elements.com>
> ---
>  .../boot/dts/rockchip/rk3568-rock-3b.dts      | 68 +++++++++++--------
>  1 file changed, 38 insertions(+), 30 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
> index 3d0c1ccfaa79..5350158302e4 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
> @@ -183,37 +183,65 @@ &cpu3 {
>  &gmac0 {
>  	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
>  	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
> -	clock_in_out = "input";
> -	phy-handle = <&rgmii_phy0>;
> -	phy-mode = "rgmii-id";
> +	assigned-clock-rates = <0>, <125000000>;
> +	clock_in_out = "output";
>  	phy-supply = <&vcc_3v3>;
> +	phy-mode = "rgmii";
> +	phy-handle = <&rgmii_phy0>;
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&gmac0_miim
>  		     &gmac0_tx_bus2
>  		     &gmac0_rx_bus2
>  		     &gmac0_rgmii_clk
> -		     &gmac0_rgmii_bus
> -		     &gmac0_clkinout>;
> +		     &gmac0_rgmii_bus>;
> +	snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
> +	snps,reset-active-low;
> +	snps,reset-delays-us = <0 20000 100000>;

The snps,reset props is deprecated and reset- props should be used in
the PHY node.

This also changes to use 20/100 ms delay instead of current 20/50ms
delay. If anything it could be changed to 20/80ms, I have only seen
datasheets for rtl8211f mention minimum 10 ms and minimum 30-76 ms.

> +
> +	tx_delay = <0x36>;
> +	rx_delay = <0x2d>;

Are you having issue with use of rgmii-id on your board?

> +
>  	status = "okay";
>  };
>  
>  &gmac1 {
>  	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
>  	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
> -	clock_in_out = "input";
> -	phy-handle = <&rgmii_phy1>;
> -	phy-mode = "rgmii-id";
> +	assigned-clock-rates = <0>, <125000000>;
> +	clock_in_out = "output";
>  	phy-supply = <&vcc_3v3>;
> +	phy-mode = "rgmii";
> +	phy-handle = <&rgmii_phy1>;
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&gmac1m1_miim
>  		     &gmac1m1_tx_bus2
>  		     &gmac1m1_rx_bus2
>  		     &gmac1m1_rgmii_clk
> -		     &gmac1m1_rgmii_bus
> -		     &gmac1m1_clkinout>;
> +		     &gmac1m1_rgmii_bus>;
> +	snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
> +	snps,reset-active-low;
> +	snps,reset-delays-us = <0 50000 150000>;

Same here, but now this is 50/150 ms?

> +
> +	tx_delay = <0x47>;
> +	rx_delay = <0x28>;

Same here, is use of rgmii-id causing issues on your boards?

> +
>  	status = "okay";
>  };
>  
> +&mdio0 {
> +	rgmii_phy0: ethernet-phy at 0 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <0>;

The phy addr used for these boards is 0x1.

> +	};
> +};
> +
> +&mdio1 {
> +	rgmii_phy1: ethernet-phy at 0 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <0>;

Same here.

> +	};
> +};

There should be no need to move these nodes, they should already be in
alphabetical order?

> +
>  &gpu {
>  	mali-supply = <&vdd_gpu>;
>  	status = "okay";
> @@ -512,26 +540,6 @@ &i2s1m0_sdi0
>  	status = "okay";
>  };
>  
> -&mdio0 {
> -	rgmii_phy0: ethernet-phy at 1 {
> -		compatible = "ethernet-phy-ieee802.3-c22";

If you want to use vendor u-boot you can probably change this to
"ethernet-phy-id001c.c916".

> -		reg = <1>;
> -		reset-assert-us = <20000>;
> -		reset-deassert-us = <50000>;
> -		reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
> -	};
> -};
> -
> -&mdio1 {
> -	rgmii_phy1: ethernet-phy at 1 {
> -		compatible = "ethernet-phy-ieee802.3-c22";

Same here.

Regards,
Jonas

> -		reg = <1>;
> -		reset-assert-us = <20000>;
> -		reset-deassert-us = <50000>;
> -		reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
> -	};
> -};
> -
>  &pcie2x1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pcie20m1_pins>;



From sashal at kernel.org  Fri Dec 20 09:11:27 2024
From: sashal at kernel.org (Sasha Levin)
Date: Fri, 20 Dec 2024 12:11:27 -0500
Subject: [PATCH AUTOSEL 6.12 26/29] irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
In-Reply-To: <20241220171130.511389-1-sashal@kernel.org>
References: <20241220171130.511389-1-sashal@kernel.org>
Message-ID: <20241220171130.511389-26-sashal@kernel.org>

From: Uros Bizjak <ubizjak at gmail.com>

[ Upstream commit a1855f1b7c33642c9f7a01991fb763342a312e9b ]

percpu_base is used in various percpu functions that expect variable in
__percpu address space. Correct the declaration of percpu_base to

void __iomem * __percpu *percpu_base;

to declare the variable as __percpu pointer.

The patch fixes several sparse warnings:

irq-gic.c:1172:44: warning: incorrect type in assignment (different address spaces)
irq-gic.c:1172:44:    expected void [noderef] __percpu *[noderef] __iomem *percpu_base
irq-gic.c:1172:44:    got void [noderef] __iomem *[noderef] __percpu *
...
irq-gic.c:1231:43: warning: incorrect type in argument 1 (different address spaces)
irq-gic.c:1231:43:    expected void [noderef] __percpu *__pdata
irq-gic.c:1231:43:    got void [noderef] __percpu *[noderef] __iomem *percpu_base

There were no changes in the resulting object files.

Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Acked-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/all/20241213145809.2918-2-ubizjak at gmail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/irqchip/irq-gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 3be7bd8cd8cd..32abc2916b40 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -64,7 +64,7 @@ static void gic_check_cpu_features(void)
 
 union gic_base {
 	void __iomem *common_base;
-	void __percpu * __iomem *percpu_base;
+	void __iomem * __percpu *percpu_base;
 };
 
 struct gic_chip_data {
-- 
2.39.5



From sashal at kernel.org  Fri Dec 20 09:12:39 2024
From: sashal at kernel.org (Sasha Levin)
Date: Fri, 20 Dec 2024 12:12:39 -0500
Subject: [PATCH AUTOSEL 6.6 15/16] irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
In-Reply-To: <20241220171240.511904-1-sashal@kernel.org>
References: <20241220171240.511904-1-sashal@kernel.org>
Message-ID: <20241220171240.511904-15-sashal@kernel.org>

From: Uros Bizjak <ubizjak at gmail.com>

[ Upstream commit a1855f1b7c33642c9f7a01991fb763342a312e9b ]

percpu_base is used in various percpu functions that expect variable in
__percpu address space. Correct the declaration of percpu_base to

void __iomem * __percpu *percpu_base;

to declare the variable as __percpu pointer.

The patch fixes several sparse warnings:

irq-gic.c:1172:44: warning: incorrect type in assignment (different address spaces)
irq-gic.c:1172:44:    expected void [noderef] __percpu *[noderef] __iomem *percpu_base
irq-gic.c:1172:44:    got void [noderef] __iomem *[noderef] __percpu *
...
irq-gic.c:1231:43: warning: incorrect type in argument 1 (different address spaces)
irq-gic.c:1231:43:    expected void [noderef] __percpu *__pdata
irq-gic.c:1231:43:    got void [noderef] __percpu *[noderef] __iomem *percpu_base

There were no changes in the resulting object files.

Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Acked-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/all/20241213145809.2918-2-ubizjak at gmail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/irqchip/irq-gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 412196a7dad5..2c6c50348afd 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -64,7 +64,7 @@ static void gic_check_cpu_features(void)
 
 union gic_base {
 	void __iomem *common_base;
-	void __percpu * __iomem *percpu_base;
+	void __iomem * __percpu *percpu_base;
 };
 
 struct gic_chip_data {
-- 
2.39.5



From sashal at kernel.org  Fri Dec 20 09:13:16 2024
From: sashal at kernel.org (Sasha Levin)
Date: Fri, 20 Dec 2024 12:13:16 -0500
Subject: [PATCH AUTOSEL 6.1 11/12] irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
In-Reply-To: <20241220171317.512120-1-sashal@kernel.org>
References: <20241220171317.512120-1-sashal@kernel.org>
Message-ID: <20241220171317.512120-11-sashal@kernel.org>

From: Uros Bizjak <ubizjak at gmail.com>

[ Upstream commit a1855f1b7c33642c9f7a01991fb763342a312e9b ]

percpu_base is used in various percpu functions that expect variable in
__percpu address space. Correct the declaration of percpu_base to

void __iomem * __percpu *percpu_base;

to declare the variable as __percpu pointer.

The patch fixes several sparse warnings:

irq-gic.c:1172:44: warning: incorrect type in assignment (different address spaces)
irq-gic.c:1172:44:    expected void [noderef] __percpu *[noderef] __iomem *percpu_base
irq-gic.c:1172:44:    got void [noderef] __iomem *[noderef] __percpu *
...
irq-gic.c:1231:43: warning: incorrect type in argument 1 (different address spaces)
irq-gic.c:1231:43:    expected void [noderef] __percpu *__pdata
irq-gic.c:1231:43:    got void [noderef] __percpu *[noderef] __iomem *percpu_base

There were no changes in the resulting object files.

Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Acked-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/all/20241213145809.2918-2-ubizjak at gmail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/irqchip/irq-gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 4c7bae0ec8f9..867b282fa95d 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -63,7 +63,7 @@ static void gic_check_cpu_features(void)
 
 union gic_base {
 	void __iomem *common_base;
-	void __percpu * __iomem *percpu_base;
+	void __iomem * __percpu *percpu_base;
 };
 
 struct gic_chip_data {
-- 
2.39.5



From sashal at kernel.org  Fri Dec 20 09:13:46 2024
From: sashal at kernel.org (Sasha Levin)
Date: Fri, 20 Dec 2024 12:13:46 -0500
Subject: [PATCH AUTOSEL 5.15 8/9] irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
In-Reply-To: <20241220171347.512287-1-sashal@kernel.org>
References: <20241220171347.512287-1-sashal@kernel.org>
Message-ID: <20241220171347.512287-8-sashal@kernel.org>

From: Uros Bizjak <ubizjak at gmail.com>

[ Upstream commit a1855f1b7c33642c9f7a01991fb763342a312e9b ]

percpu_base is used in various percpu functions that expect variable in
__percpu address space. Correct the declaration of percpu_base to

void __iomem * __percpu *percpu_base;

to declare the variable as __percpu pointer.

The patch fixes several sparse warnings:

irq-gic.c:1172:44: warning: incorrect type in assignment (different address spaces)
irq-gic.c:1172:44:    expected void [noderef] __percpu *[noderef] __iomem *percpu_base
irq-gic.c:1172:44:    got void [noderef] __iomem *[noderef] __percpu *
...
irq-gic.c:1231:43: warning: incorrect type in argument 1 (different address spaces)
irq-gic.c:1231:43:    expected void [noderef] __percpu *__pdata
irq-gic.c:1231:43:    got void [noderef] __percpu *[noderef] __iomem *percpu_base

There were no changes in the resulting object files.

Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Acked-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/all/20241213145809.2918-2-ubizjak at gmail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/irqchip/irq-gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 99077f30f699..c941037199c8 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -62,7 +62,7 @@ static void gic_check_cpu_features(void)
 
 union gic_base {
 	void __iomem *common_base;
-	void __percpu * __iomem *percpu_base;
+	void __iomem * __percpu *percpu_base;
 };
 
 struct gic_chip_data {
-- 
2.39.5



From sashal at kernel.org  Fri Dec 20 09:14:05 2024
From: sashal at kernel.org (Sasha Levin)
Date: Fri, 20 Dec 2024 12:14:05 -0500
Subject: [PATCH AUTOSEL 5.10 6/7] irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
In-Reply-To: <20241220171406.512413-1-sashal@kernel.org>
References: <20241220171406.512413-1-sashal@kernel.org>
Message-ID: <20241220171406.512413-6-sashal@kernel.org>

From: Uros Bizjak <ubizjak at gmail.com>

[ Upstream commit a1855f1b7c33642c9f7a01991fb763342a312e9b ]

percpu_base is used in various percpu functions that expect variable in
__percpu address space. Correct the declaration of percpu_base to

void __iomem * __percpu *percpu_base;

to declare the variable as __percpu pointer.

The patch fixes several sparse warnings:

irq-gic.c:1172:44: warning: incorrect type in assignment (different address spaces)
irq-gic.c:1172:44:    expected void [noderef] __percpu *[noderef] __iomem *percpu_base
irq-gic.c:1172:44:    got void [noderef] __iomem *[noderef] __percpu *
...
irq-gic.c:1231:43: warning: incorrect type in argument 1 (different address spaces)
irq-gic.c:1231:43:    expected void [noderef] __percpu *__pdata
irq-gic.c:1231:43:    got void [noderef] __percpu *[noderef] __iomem *percpu_base

There were no changes in the resulting object files.

Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Acked-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/all/20241213145809.2918-2-ubizjak at gmail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/irqchip/irq-gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 205cbd24ff20..8030bdcd008c 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -62,7 +62,7 @@ static void gic_check_cpu_features(void)
 
 union gic_base {
 	void __iomem *common_base;
-	void __percpu * __iomem *percpu_base;
+	void __iomem * __percpu *percpu_base;
 };
 
 struct gic_chip_data {
-- 
2.39.5



From sashal at kernel.org  Fri Dec 20 09:14:19 2024
From: sashal at kernel.org (Sasha Levin)
Date: Fri, 20 Dec 2024 12:14:19 -0500
Subject: [PATCH AUTOSEL 5.4 5/6] irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
In-Reply-To: <20241220171420.512513-1-sashal@kernel.org>
References: <20241220171420.512513-1-sashal@kernel.org>
Message-ID: <20241220171420.512513-5-sashal@kernel.org>

From: Uros Bizjak <ubizjak at gmail.com>

[ Upstream commit a1855f1b7c33642c9f7a01991fb763342a312e9b ]

percpu_base is used in various percpu functions that expect variable in
__percpu address space. Correct the declaration of percpu_base to

void __iomem * __percpu *percpu_base;

to declare the variable as __percpu pointer.

The patch fixes several sparse warnings:

irq-gic.c:1172:44: warning: incorrect type in assignment (different address spaces)
irq-gic.c:1172:44:    expected void [noderef] __percpu *[noderef] __iomem *percpu_base
irq-gic.c:1172:44:    got void [noderef] __iomem *[noderef] __percpu *
...
irq-gic.c:1231:43: warning: incorrect type in argument 1 (different address spaces)
irq-gic.c:1231:43:    expected void [noderef] __percpu *__pdata
irq-gic.c:1231:43:    got void [noderef] __percpu *[noderef] __iomem *percpu_base

There were no changes in the resulting object files.

Signed-off-by: Uros Bizjak <ubizjak at gmail.com>
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Acked-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/all/20241213145809.2918-2-ubizjak at gmail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/irqchip/irq-gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 882204d1ef4f..5937f3cd288b 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -62,7 +62,7 @@ static void gic_check_cpu_features(void)
 
 union gic_base {
 	void __iomem *common_base;
-	void __percpu * __iomem *percpu_base;
+	void __iomem * __percpu *percpu_base;
 };
 
 struct gic_chip_data {
-- 
2.39.5



From james.clark at linaro.org  Fri Dec 20 09:16:21 2024
From: james.clark at linaro.org (James Clark)
Date: Fri, 20 Dec 2024 17:16:21 +0000
Subject: [PATCH] perf: arm-spe: Fix null-ptr-deref in
 arm_spe__alloc_metadata()
In-Reply-To: <20241220145659.66066-1-niharchaithanya@gmail.com>
References: <20241220145659.66066-1-niharchaithanya@gmail.com>
Message-ID: <c98e8399-1471-4d38-b314-4fbcb8dcb27d@linaro.org>



On 20/12/2024 2:57 pm, Nihar Chaithanya wrote:
> When metadata is allocated using arm_spe__alloc_metadata(), if the
> metadata version is 1, metadata is returned as NULL. This value
> is dereferenced later in arm_spe__free_metadata() and it can cause
> null-ptr-deref.
> 
> Modify the NULL check for metadata to return -EINVAL even when
> metadata_ver == 1.
> 

Hi Nihar,

I don't think this is the right fix. Doesn't that mean we can't open 
files with V1 anymore? Did you test opening an old SPE file on a new 
version of Perf? I actually thought I tested this before but maybe not 
if there's a NULL deref.

Seems like the correct fix is to not dereference anything if metadata is 
NULL, or make a fake placeholder one.


> This issue was reported by Coverity scan [1].
> [1] https://scan5.scan.coverity.com/#/project-view/63616/10063?selectedIssue=1636359
> 

Is this supposed to be publicly accessible? It goes to a login page for me.

> Closes: https://scan5.scan.coverity.com/#/project-view/63616/10063?selectedIssue=1636359
> Signed-off-by: Nihar Chaithanya <niharchaithanya at gmail.com>

Probably needs a fixes: tag too for the commit that introduced the issue.

Thanks
James

> ---
>   tools/perf/util/arm-spe.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
> index dbf13f47879c..55827d8ce133 100644
> --- a/tools/perf/util/arm-spe.c
> +++ b/tools/perf/util/arm-spe.c
> @@ -1497,7 +1497,7 @@ int arm_spe_process_auxtrace_info(union perf_event *event,
>   
>   	metadata = arm_spe__alloc_metadata(auxtrace_info, &metadata_ver,
>   					   &nr_cpu);
> -	if (!metadata && metadata_ver != 1) {
> +	if (!metadata) {
>   		pr_err("Failed to parse Arm SPE metadata.\n");
>   		return -EINVAL;
>   	}



From jbrunet at baylibre.com  Fri Dec 20 09:17:41 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 18:17:41 +0100
Subject: [PATCH 0/3] clk: amlogic: drop clk_regmap tables
Message-ID: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com>

This patchset removes the needs for clk_regmap tables in each clock
controller driver. Those were used to populate regmap with in the regmap
based clocks.

This saves a some memory and ease maintenance a bit.

This is the 1st step in a series of rework of Amlogic clocks, to clean-up,
increase code re-use and ease future maintenance.

Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
Jerome Brunet (3):
      clk: add a clk_hw helper to get the associate device structure
      clk: amlogic: drop clk_regmap tables
      clk: amlogic: s4: remove unused data

 drivers/clk/clk.c                  |   6 +
 drivers/clk/meson/a1-peripherals.c | 165 +-------------
 drivers/clk/meson/a1-pll.c         |  18 +-
 drivers/clk/meson/axg-aoclk.c      |  22 --
 drivers/clk/meson/axg-audio.c      | 435 +------------------------------------
 drivers/clk/meson/axg.c            | 131 -----------
 drivers/clk/meson/c3-peripherals.c | 212 +-----------------
 drivers/clk/meson/c3-pll.c         |  34 +--
 drivers/clk/meson/clk-cpu-dyndiv.c |   1 +
 drivers/clk/meson/clk-dualdiv.c    |   2 +
 drivers/clk/meson/clk-mpll.c       |   6 +
 drivers/clk/meson/clk-phase.c      |  11 +
 drivers/clk/meson/clk-pll.c        |   7 +
 drivers/clk/meson/clk-regmap.c     |  88 ++++++++
 drivers/clk/meson/clk-regmap.h     |   7 +
 drivers/clk/meson/g12a-aoclk.c     |  34 ---
 drivers/clk/meson/g12a.c           | 261 ----------------------
 drivers/clk/meson/gxbb-aoclk.c     |  19 --
 drivers/clk/meson/gxbb.c           | 393 ---------------------------------
 drivers/clk/meson/meson-aoclk.c    |   7 +-
 drivers/clk/meson/meson-aoclk.h    |   2 -
 drivers/clk/meson/meson-eeclk.c    |   6 +-
 drivers/clk/meson/meson-eeclk.h    |   2 -
 drivers/clk/meson/meson8-ddr.c     |  11 +-
 drivers/clk/meson/s4-peripherals.c | 343 +----------------------------
 drivers/clk/meson/s4-pll.c         |  33 +--
 drivers/clk/meson/sclk-div.c       |   5 +
 drivers/clk/meson/vclk.c           |   2 +
 drivers/clk/meson/vid-pll-div.c    |   1 +
 include/linux/clk-provider.h       |   1 +
 30 files changed, 172 insertions(+), 2093 deletions(-)
---
base-commit: 1909d0d351ed98fdb9f5cbe377213ba0154bf2e0
change-id: 20241220-amlogic-clk-drop-clk-regmap-tables-18e5cf572356

Best regards,
-- 
Jerome



From jbrunet at baylibre.com  Fri Dec 20 09:17:42 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 18:17:42 +0100
Subject: [PATCH 1/3] clk: add a clk_hw helper to get the associate device
 structure
In-Reply-To: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com>
References: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com>
Message-ID: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-1-96dd657cbfbd@baylibre.com>

Add an helper function to get the 'struct device' associated with
an a 'clk_hw'. This can be used by clock drivers to access various
device related functionnalities such as devres, dev_ prints, etc ...

Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/clk/clk.c            | 6 ++++++
 include/linux/clk-provider.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 9b45fa005030f56e1478b9742715ebcde898133f..7e734d2955978cafd77d911562a26f1646684ec2 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -365,6 +365,12 @@ const char *clk_hw_get_name(const struct clk_hw *hw)
 }
 EXPORT_SYMBOL_GPL(clk_hw_get_name);
 
+struct device *clk_hw_get_dev(const struct clk_hw *hw)
+{
+	return hw->core->dev;
+}
+EXPORT_SYMBOL_GPL(clk_hw_get_dev);
+
 struct clk_hw *__clk_get_hw(struct clk *clk)
 {
 	return !clk ? NULL : clk->core->hw;
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 2e6e603b749342931c0d0693c3e72b62c000791b..e5f111dce6ae26c1103f5ff60bebbdb2fa230060 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -1360,6 +1360,7 @@ void clk_hw_unregister(struct clk_hw *hw);
 /* helper functions */
 const char *__clk_get_name(const struct clk *clk);
 const char *clk_hw_get_name(const struct clk_hw *hw);
+struct device *clk_hw_get_dev(const struct clk_hw *hw);
 #ifdef CONFIG_COMMON_CLK
 struct clk_hw *__clk_get_hw(struct clk *clk);
 #else

-- 
2.45.2



From jbrunet at baylibre.com  Fri Dec 20 09:17:44 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 18:17:44 +0100
Subject: [PATCH 3/3] clk: amlogic: s4: remove unused data
In-Reply-To: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com>
References: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com>
Message-ID: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-3-96dd657cbfbd@baylibre.com>

Following the removal of the big clk_regmap clock table from the
s4-peripherals clock controller driver, it appears some clocks are unused,
which means these are not exported or even registered.

In all likelihood, these clocks have not been tested. Remove the unused
clocks for now. These can added back later when they have been properly
tested.

Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/clk/meson/s4-peripherals.c | 112 -------------------------------------
 1 file changed, 112 deletions(-)

diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c
index 91c7b10c2b68c626dd1d6164ea855370aae71485..72b990fc0de8e4e2c83d0fc3b4c6e3fc1fc96367 100644
--- a/drivers/clk/meson/s4-peripherals.c
+++ b/drivers/clk/meson/s4-peripherals.c
@@ -3129,118 +3129,6 @@ static struct clk_regmap s4_gen_clk = {
 	},
 };
 
-static const struct clk_parent_data s4_adc_extclk_in_parent_data[]  = {
-	{ .fw_name = "xtal", },
-	{ .fw_name = "fclk_div4", },
-	{ .fw_name = "fclk_div3", },
-	{ .fw_name = "fclk_div5", },
-	{ .fw_name = "fclk_div7", },
-	{ .fw_name = "mpll2", },
-	{ .fw_name = "gp0_pll", },
-	{ .fw_name = "hifi_pll", },
-};
-
-static struct clk_regmap s4_adc_extclk_in_mux = {
-	.data = &(struct clk_regmap_mux_data) {
-		.offset = CLKCTRL_DEMOD_CLK_CTRL,
-		.mask = 0x7,
-		.shift = 25,
-	},
-	.hw.init = &(struct clk_init_data){
-		.name = "adc_extclk_in_mux",
-		.ops = &clk_regmap_mux_ops,
-		.parent_data = s4_adc_extclk_in_parent_data,
-		.num_parents = ARRAY_SIZE(s4_adc_extclk_in_parent_data),
-		.flags = 0,
-	},
-};
-
-static struct clk_regmap s4_adc_extclk_in_div = {
-	.data = &(struct clk_regmap_div_data) {
-		.offset = CLKCTRL_DEMOD_CLK_CTRL,
-		.shift = 16,
-		.width = 7,
-	},
-	.hw.init = &(struct clk_init_data){
-		.name = "adc_extclk_in_div",
-		.ops = &clk_regmap_divider_ops,
-		.parent_hws = (const struct clk_hw *[]) {
-			&s4_adc_extclk_in_mux.hw
-		},
-		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
-	},
-};
-
-static struct clk_regmap s4_adc_extclk_in_gate = {
-	.data = &(struct clk_regmap_gate_data) {
-		.offset = CLKCTRL_DEMOD_CLK_CTRL,
-		.bit_idx = 24,
-	},
-	.hw.init = &(struct clk_init_data){
-		.name = "adc_extclk_in",
-		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) {
-			&s4_adc_extclk_in_div.hw
-		},
-		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
-	},
-};
-
-static struct clk_regmap s4_demod_core_clk_mux = {
-	.data = &(struct clk_regmap_mux_data) {
-		.offset = CLKCTRL_DEMOD_CLK_CTRL,
-		.mask = 0x3,
-		.shift = 9,
-	},
-	.hw.init = &(struct clk_init_data){
-		.name = "demod_core_clk_mux",
-		.ops = &clk_regmap_mux_ops,
-		.parent_data = (const struct clk_parent_data []) {
-			{ .fw_name = "xtal", },
-			{ .fw_name = "fclk_div7", },
-			{ .fw_name = "fclk_div4", },
-			{ .hw = &s4_adc_extclk_in_gate.hw }
-		},
-		.num_parents = 4,
-		.flags = CLK_SET_RATE_PARENT,
-	},
-};
-
-static struct clk_regmap s4_demod_core_clk_div = {
-	.data = &(struct clk_regmap_div_data) {
-		.offset = CLKCTRL_DEMOD_CLK_CTRL,
-		.shift = 0,
-		.width = 7,
-	},
-	.hw.init = &(struct clk_init_data){
-		.name = "demod_core_clk_div",
-		.ops = &clk_regmap_divider_ops,
-		.parent_hws = (const struct clk_hw *[]) {
-			&s4_demod_core_clk_mux.hw
-		},
-		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
-	},
-};
-
-static struct clk_regmap s4_demod_core_clk_gate = {
-	.data = &(struct clk_regmap_gate_data) {
-		.offset = CLKCTRL_DEMOD_CLK_CTRL,
-		.bit_idx = 8,
-	},
-	.hw.init = &(struct clk_init_data){
-		.name = "demod_core_clk",
-		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) {
-			&s4_demod_core_clk_div.hw
-		},
-		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
-	},
-};
-
 #define MESON_GATE(_name, _reg, _bit) \
 	MESON_PCLK(_name, _reg, _bit, &s4_sys_clk.hw)
 

-- 
2.45.2



From jbrunet at baylibre.com  Fri Dec 20 09:17:43 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 20 Dec 2024 18:17:43 +0100
Subject: [PATCH 2/3] clk: amlogic: drop clk_regmap tables
In-Reply-To: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com>
References: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com>
Message-ID: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-2-96dd657cbfbd@baylibre.com>

Remove the big clk_regmap tables that are used to populate the regmap
field of clk_regmap clocks at runtime. Instead of using tables, use devres
to allow the clocks to get the necessary regmap.

A simpler solution would have been to use dev_get_regmap() but this would
not work with syscon based controllers.

This rework save a bit memory and the result is less of a maintenance
burden.

Unfortunately meson8b is left out for now since it is an early clock
driver that does not have proper device support for now.

Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/clk/meson/a1-peripherals.c | 165 +-------------
 drivers/clk/meson/a1-pll.c         |  18 +-
 drivers/clk/meson/axg-aoclk.c      |  22 --
 drivers/clk/meson/axg-audio.c      | 435 +------------------------------------
 drivers/clk/meson/axg.c            | 131 -----------
 drivers/clk/meson/c3-peripherals.c | 212 +-----------------
 drivers/clk/meson/c3-pll.c         |  34 +--
 drivers/clk/meson/clk-cpu-dyndiv.c |   1 +
 drivers/clk/meson/clk-dualdiv.c    |   2 +
 drivers/clk/meson/clk-mpll.c       |   6 +
 drivers/clk/meson/clk-phase.c      |  11 +
 drivers/clk/meson/clk-pll.c        |   7 +
 drivers/clk/meson/clk-regmap.c     |  88 ++++++++
 drivers/clk/meson/clk-regmap.h     |   7 +
 drivers/clk/meson/g12a-aoclk.c     |  34 ---
 drivers/clk/meson/g12a.c           | 261 ----------------------
 drivers/clk/meson/gxbb-aoclk.c     |  19 --
 drivers/clk/meson/gxbb.c           | 393 ---------------------------------
 drivers/clk/meson/meson-aoclk.c    |   7 +-
 drivers/clk/meson/meson-aoclk.h    |   2 -
 drivers/clk/meson/meson-eeclk.c    |   6 +-
 drivers/clk/meson/meson-eeclk.h    |   2 -
 drivers/clk/meson/meson8-ddr.c     |  11 +-
 drivers/clk/meson/s4-peripherals.c | 231 +-------------------
 drivers/clk/meson/s4-pll.c         |  33 +--
 drivers/clk/meson/sclk-div.c       |   5 +
 drivers/clk/meson/vclk.c           |   2 +
 drivers/clk/meson/vid-pll-div.c    |   1 +
 28 files changed, 165 insertions(+), 1981 deletions(-)

diff --git a/drivers/clk/meson/a1-peripherals.c b/drivers/clk/meson/a1-peripherals.c
index 7aa6abb2eb1f2b804916d5c2515eefc15149433d..020779e4042d5e1e7ec555bf543604e2bc137477 100644
--- a/drivers/clk/meson/a1-peripherals.c
+++ b/drivers/clk/meson/a1-peripherals.c
@@ -2026,163 +2026,6 @@ static struct clk_hw *a1_periphs_hw_clks[] = {
 	[CLKID_DMC_SEL2]		= &dmc_sel2.hw,
 };
 
-/* Convenience table to populate regmap in .probe */
-static struct clk_regmap *const a1_periphs_regmaps[] = {
-	&xtal_in,
-	&fixpll_in,
-	&usb_phy_in,
-	&usb_ctrl_in,
-	&hifipll_in,
-	&syspll_in,
-	&dds_in,
-	&sys,
-	&clktree,
-	&reset_ctrl,
-	&analog_ctrl,
-	&pwr_ctrl,
-	&pad_ctrl,
-	&sys_ctrl,
-	&temp_sensor,
-	&am2axi_dev,
-	&spicc_b,
-	&spicc_a,
-	&msr,
-	&audio,
-	&jtag_ctrl,
-	&saradc_en,
-	&pwm_ef,
-	&pwm_cd,
-	&pwm_ab,
-	&cec,
-	&i2c_s,
-	&ir_ctrl,
-	&i2c_m_d,
-	&i2c_m_c,
-	&i2c_m_b,
-	&i2c_m_a,
-	&acodec,
-	&otp,
-	&sd_emmc_a,
-	&usb_phy,
-	&usb_ctrl,
-	&sys_dspb,
-	&sys_dspa,
-	&dma,
-	&irq_ctrl,
-	&nic,
-	&gic,
-	&uart_c,
-	&uart_b,
-	&uart_a,
-	&sys_psram,
-	&rsa,
-	&coresight,
-	&am2axi_vad,
-	&audio_vad,
-	&axi_dmc,
-	&axi_psram,
-	&ramb,
-	&rama,
-	&axi_spifc,
-	&axi_nic,
-	&axi_dma,
-	&cpu_ctrl,
-	&rom,
-	&prod_i2c,
-	&dspa_sel,
-	&dspb_sel,
-	&dspa_en,
-	&dspa_en_nic,
-	&dspb_en,
-	&dspb_en_nic,
-	&rtc,
-	&ceca_32k_out,
-	&cecb_32k_out,
-	&clk_24m,
-	&clk_12m,
-	&fclk_div2_divn,
-	&gen,
-	&saradc_sel,
-	&saradc,
-	&pwm_a,
-	&pwm_b,
-	&pwm_c,
-	&pwm_d,
-	&pwm_e,
-	&pwm_f,
-	&spicc,
-	&ts,
-	&spifc,
-	&usb_bus,
-	&sd_emmc,
-	&psram,
-	&dmc,
-	&sys_a_sel,
-	&sys_a_div,
-	&sys_a,
-	&sys_b_sel,
-	&sys_b_div,
-	&sys_b,
-	&dspa_a_sel,
-	&dspa_a_div,
-	&dspa_a,
-	&dspa_b_sel,
-	&dspa_b_div,
-	&dspa_b,
-	&dspb_a_sel,
-	&dspb_a_div,
-	&dspb_a,
-	&dspb_b_sel,
-	&dspb_b_div,
-	&dspb_b,
-	&rtc_32k_in,
-	&rtc_32k_div,
-	&rtc_32k_xtal,
-	&rtc_32k_sel,
-	&cecb_32k_in,
-	&cecb_32k_div,
-	&cecb_32k_sel_pre,
-	&cecb_32k_sel,
-	&ceca_32k_in,
-	&ceca_32k_div,
-	&ceca_32k_sel_pre,
-	&ceca_32k_sel,
-	&fclk_div2_divn_pre,
-	&gen_sel,
-	&gen_div,
-	&saradc_div,
-	&pwm_a_sel,
-	&pwm_a_div,
-	&pwm_b_sel,
-	&pwm_b_div,
-	&pwm_c_sel,
-	&pwm_c_div,
-	&pwm_d_sel,
-	&pwm_d_div,
-	&pwm_e_sel,
-	&pwm_e_div,
-	&pwm_f_sel,
-	&pwm_f_div,
-	&spicc_sel,
-	&spicc_div,
-	&spicc_sel2,
-	&ts_div,
-	&spifc_sel,
-	&spifc_div,
-	&spifc_sel2,
-	&usb_bus_sel,
-	&usb_bus_div,
-	&sd_emmc_sel,
-	&sd_emmc_div,
-	&sd_emmc_sel2,
-	&psram_sel,
-	&psram_div,
-	&psram_sel2,
-	&dmc_sel,
-	&dmc_div,
-	&dmc_sel2,
-};
-
 static const struct regmap_config a1_periphs_regmap_cfg = {
 	.reg_bits   = 32,
 	.val_bits   = 32,
@@ -2200,7 +2043,7 @@ static int meson_a1_periphs_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	void __iomem *base;
 	struct regmap *map;
-	int clkid, i, err;
+	int clkid, err;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
@@ -2212,9 +2055,9 @@ static int meson_a1_periphs_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(map),
 				     "can't init regmap mmio region\n");
 
-	/* Populate regmap for the regmap backed clocks */
-	for (i = 0; i < ARRAY_SIZE(a1_periphs_regmaps); i++)
-		a1_periphs_regmaps[i]->map = map;
+	err = clk_regmap_init_regmap(dev, map);
+	if (err)
+		return err;
 
 	for (clkid = 0; clkid < a1_periphs_clks.num; clkid++) {
 		err = devm_clk_hw_register(dev, a1_periphs_clks.hws[clkid]);
diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c
index 8e5a42d1afbbcd82341a5dcdd19b9f352e725e91..58d63936bd6bf3109bdd76712ce445ba2f35be46 100644
--- a/drivers/clk/meson/a1-pll.c
+++ b/drivers/clk/meson/a1-pll.c
@@ -285,16 +285,6 @@ static struct clk_hw *a1_pll_hw_clks[] = {
 	[CLKID_HIFI_PLL]	= &hifi_pll.hw,
 };
 
-static struct clk_regmap *const a1_pll_regmaps[] = {
-	&fixed_pll_dco,
-	&fixed_pll,
-	&fclk_div2,
-	&fclk_div3,
-	&fclk_div5,
-	&fclk_div7,
-	&hifi_pll,
-};
-
 static const struct regmap_config a1_pll_regmap_cfg = {
 	.reg_bits   = 32,
 	.val_bits   = 32,
@@ -312,7 +302,7 @@ static int meson_a1_pll_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	void __iomem *base;
 	struct regmap *map;
-	int clkid, i, err;
+	int clkid, err;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
@@ -324,9 +314,9 @@ static int meson_a1_pll_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(map),
 				     "can't init regmap mmio region\n");
 
-	/* Populate regmap for the regmap backed clocks */
-	for (i = 0; i < ARRAY_SIZE(a1_pll_regmaps); i++)
-		a1_pll_regmaps[i]->map = map;
+	err = clk_regmap_init_regmap(dev, map);
+	if (err)
+		return err;
 
 	/* Register clocks */
 	for (clkid = 0; clkid < a1_pll_clks.num; clkid++) {
diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c
index 1dabc81535a6f77a6420f075f1bbef8ab8b31fd2..84cf0fac86b4482e8966f12a49c09c820aa19987 100644
--- a/drivers/clk/meson/axg-aoclk.c
+++ b/drivers/clk/meson/axg-aoclk.c
@@ -270,26 +270,6 @@ static const unsigned int axg_aoclk_reset[] = {
 	[RESET_AO_IR_BLASTER]	= 23,
 };
 
-static struct clk_regmap *axg_aoclk_regmap[] = {
-	&axg_aoclk_remote,
-	&axg_aoclk_i2c_master,
-	&axg_aoclk_i2c_slave,
-	&axg_aoclk_uart1,
-	&axg_aoclk_uart2,
-	&axg_aoclk_ir_blaster,
-	&axg_aoclk_saradc,
-	&axg_aoclk_cts_oscin,
-	&axg_aoclk_32k_pre,
-	&axg_aoclk_32k_div,
-	&axg_aoclk_32k_sel,
-	&axg_aoclk_32k,
-	&axg_aoclk_cts_rtc_oscin,
-	&axg_aoclk_clk81,
-	&axg_aoclk_saradc_mux,
-	&axg_aoclk_saradc_div,
-	&axg_aoclk_saradc_gate,
-};
-
 static struct clk_hw *axg_aoclk_hw_clks[] = {
 	[CLKID_AO_REMOTE]	= &axg_aoclk_remote.hw,
 	[CLKID_AO_I2C_MASTER]	= &axg_aoclk_i2c_master.hw,
@@ -314,8 +294,6 @@ static const struct meson_aoclk_data axg_aoclkc_data = {
 	.reset_reg	= AO_RTI_GEN_CNTL_REG0,
 	.num_reset	= ARRAY_SIZE(axg_aoclk_reset),
 	.reset		= axg_aoclk_reset,
-	.num_clks	= ARRAY_SIZE(axg_aoclk_regmap),
-	.clks		= axg_aoclk_regmap,
 	.hw_clks	= {
 		.hws	= axg_aoclk_hw_clks,
 		.num	= ARRAY_SIZE(axg_aoclk_hw_clks),
diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c
index beda86349389990065954300369e5daa360856c9..803bb7a3ac716f1d16b779949e2d5ebc2dd95478 100644
--- a/drivers/clk/meson/axg-audio.c
+++ b/drivers/clk/meson/axg-audio.c
@@ -1257,427 +1257,6 @@ static struct clk_hw *sm1_audio_hw_clks[] = {
 	[AUD_CLKID_EARCRX_DMAC]		= &sm1_earcrx_dmac_clk.hw,
 };
 
-
-/* Convenience table to populate regmap in .probe(). */
-static struct clk_regmap *const axg_clk_regmaps[] = {
-	&ddr_arb,
-	&pdm,
-	&tdmin_a,
-	&tdmin_b,
-	&tdmin_c,
-	&tdmin_lb,
-	&tdmout_a,
-	&tdmout_b,
-	&tdmout_c,
-	&frddr_a,
-	&frddr_b,
-	&frddr_c,
-	&toddr_a,
-	&toddr_b,
-	&toddr_c,
-	&loopback,
-	&spdifin,
-	&spdifout,
-	&resample,
-	&power_detect,
-	&mst_a_mclk_sel,
-	&mst_b_mclk_sel,
-	&mst_c_mclk_sel,
-	&mst_d_mclk_sel,
-	&mst_e_mclk_sel,
-	&mst_f_mclk_sel,
-	&mst_a_mclk_div,
-	&mst_b_mclk_div,
-	&mst_c_mclk_div,
-	&mst_d_mclk_div,
-	&mst_e_mclk_div,
-	&mst_f_mclk_div,
-	&mst_a_mclk,
-	&mst_b_mclk,
-	&mst_c_mclk,
-	&mst_d_mclk,
-	&mst_e_mclk,
-	&mst_f_mclk,
-	&spdifout_clk_sel,
-	&spdifout_clk_div,
-	&spdifout_clk,
-	&spdifin_clk_sel,
-	&spdifin_clk_div,
-	&spdifin_clk,
-	&pdm_dclk_sel,
-	&pdm_dclk_div,
-	&pdm_dclk,
-	&pdm_sysclk_sel,
-	&pdm_sysclk_div,
-	&pdm_sysclk,
-	&mst_a_sclk_pre_en,
-	&mst_b_sclk_pre_en,
-	&mst_c_sclk_pre_en,
-	&mst_d_sclk_pre_en,
-	&mst_e_sclk_pre_en,
-	&mst_f_sclk_pre_en,
-	&mst_a_sclk_div,
-	&mst_b_sclk_div,
-	&mst_c_sclk_div,
-	&mst_d_sclk_div,
-	&mst_e_sclk_div,
-	&mst_f_sclk_div,
-	&mst_a_sclk_post_en,
-	&mst_b_sclk_post_en,
-	&mst_c_sclk_post_en,
-	&mst_d_sclk_post_en,
-	&mst_e_sclk_post_en,
-	&mst_f_sclk_post_en,
-	&mst_a_sclk,
-	&mst_b_sclk,
-	&mst_c_sclk,
-	&mst_d_sclk,
-	&mst_e_sclk,
-	&mst_f_sclk,
-	&mst_a_lrclk_div,
-	&mst_b_lrclk_div,
-	&mst_c_lrclk_div,
-	&mst_d_lrclk_div,
-	&mst_e_lrclk_div,
-	&mst_f_lrclk_div,
-	&mst_a_lrclk,
-	&mst_b_lrclk,
-	&mst_c_lrclk,
-	&mst_d_lrclk,
-	&mst_e_lrclk,
-	&mst_f_lrclk,
-	&tdmin_a_sclk_sel,
-	&tdmin_b_sclk_sel,
-	&tdmin_c_sclk_sel,
-	&tdmin_lb_sclk_sel,
-	&tdmout_a_sclk_sel,
-	&tdmout_b_sclk_sel,
-	&tdmout_c_sclk_sel,
-	&tdmin_a_sclk_pre_en,
-	&tdmin_b_sclk_pre_en,
-	&tdmin_c_sclk_pre_en,
-	&tdmin_lb_sclk_pre_en,
-	&tdmout_a_sclk_pre_en,
-	&tdmout_b_sclk_pre_en,
-	&tdmout_c_sclk_pre_en,
-	&tdmin_a_sclk_post_en,
-	&tdmin_b_sclk_post_en,
-	&tdmin_c_sclk_post_en,
-	&tdmin_lb_sclk_post_en,
-	&tdmout_a_sclk_post_en,
-	&tdmout_b_sclk_post_en,
-	&tdmout_c_sclk_post_en,
-	&tdmin_a_sclk,
-	&tdmin_b_sclk,
-	&tdmin_c_sclk,
-	&tdmin_lb_sclk,
-	&axg_tdmout_a_sclk,
-	&axg_tdmout_b_sclk,
-	&axg_tdmout_c_sclk,
-	&tdmin_a_lrclk,
-	&tdmin_b_lrclk,
-	&tdmin_c_lrclk,
-	&tdmin_lb_lrclk,
-	&tdmout_a_lrclk,
-	&tdmout_b_lrclk,
-	&tdmout_c_lrclk,
-};
-
-static struct clk_regmap *const g12a_clk_regmaps[] = {
-	&ddr_arb,
-	&pdm,
-	&tdmin_a,
-	&tdmin_b,
-	&tdmin_c,
-	&tdmin_lb,
-	&tdmout_a,
-	&tdmout_b,
-	&tdmout_c,
-	&frddr_a,
-	&frddr_b,
-	&frddr_c,
-	&toddr_a,
-	&toddr_b,
-	&toddr_c,
-	&loopback,
-	&spdifin,
-	&spdifout,
-	&resample,
-	&power_detect,
-	&spdifout_b,
-	&mst_a_mclk_sel,
-	&mst_b_mclk_sel,
-	&mst_c_mclk_sel,
-	&mst_d_mclk_sel,
-	&mst_e_mclk_sel,
-	&mst_f_mclk_sel,
-	&mst_a_mclk_div,
-	&mst_b_mclk_div,
-	&mst_c_mclk_div,
-	&mst_d_mclk_div,
-	&mst_e_mclk_div,
-	&mst_f_mclk_div,
-	&mst_a_mclk,
-	&mst_b_mclk,
-	&mst_c_mclk,
-	&mst_d_mclk,
-	&mst_e_mclk,
-	&mst_f_mclk,
-	&spdifout_clk_sel,
-	&spdifout_clk_div,
-	&spdifout_clk,
-	&spdifin_clk_sel,
-	&spdifin_clk_div,
-	&spdifin_clk,
-	&pdm_dclk_sel,
-	&pdm_dclk_div,
-	&pdm_dclk,
-	&pdm_sysclk_sel,
-	&pdm_sysclk_div,
-	&pdm_sysclk,
-	&mst_a_sclk_pre_en,
-	&mst_b_sclk_pre_en,
-	&mst_c_sclk_pre_en,
-	&mst_d_sclk_pre_en,
-	&mst_e_sclk_pre_en,
-	&mst_f_sclk_pre_en,
-	&mst_a_sclk_div,
-	&mst_b_sclk_div,
-	&mst_c_sclk_div,
-	&mst_d_sclk_div,
-	&mst_e_sclk_div,
-	&mst_f_sclk_div,
-	&mst_a_sclk_post_en,
-	&mst_b_sclk_post_en,
-	&mst_c_sclk_post_en,
-	&mst_d_sclk_post_en,
-	&mst_e_sclk_post_en,
-	&mst_f_sclk_post_en,
-	&mst_a_sclk,
-	&mst_b_sclk,
-	&mst_c_sclk,
-	&mst_d_sclk,
-	&mst_e_sclk,
-	&mst_f_sclk,
-	&mst_a_lrclk_div,
-	&mst_b_lrclk_div,
-	&mst_c_lrclk_div,
-	&mst_d_lrclk_div,
-	&mst_e_lrclk_div,
-	&mst_f_lrclk_div,
-	&mst_a_lrclk,
-	&mst_b_lrclk,
-	&mst_c_lrclk,
-	&mst_d_lrclk,
-	&mst_e_lrclk,
-	&mst_f_lrclk,
-	&tdmin_a_sclk_sel,
-	&tdmin_b_sclk_sel,
-	&tdmin_c_sclk_sel,
-	&tdmin_lb_sclk_sel,
-	&tdmout_a_sclk_sel,
-	&tdmout_b_sclk_sel,
-	&tdmout_c_sclk_sel,
-	&tdmin_a_sclk_pre_en,
-	&tdmin_b_sclk_pre_en,
-	&tdmin_c_sclk_pre_en,
-	&tdmin_lb_sclk_pre_en,
-	&tdmout_a_sclk_pre_en,
-	&tdmout_b_sclk_pre_en,
-	&tdmout_c_sclk_pre_en,
-	&tdmin_a_sclk_post_en,
-	&tdmin_b_sclk_post_en,
-	&tdmin_c_sclk_post_en,
-	&tdmin_lb_sclk_post_en,
-	&tdmout_a_sclk_post_en,
-	&tdmout_b_sclk_post_en,
-	&tdmout_c_sclk_post_en,
-	&tdmin_a_sclk,
-	&tdmin_b_sclk,
-	&tdmin_c_sclk,
-	&tdmin_lb_sclk,
-	&g12a_tdmout_a_sclk,
-	&g12a_tdmout_b_sclk,
-	&g12a_tdmout_c_sclk,
-	&tdmin_a_lrclk,
-	&tdmin_b_lrclk,
-	&tdmin_c_lrclk,
-	&tdmin_lb_lrclk,
-	&tdmout_a_lrclk,
-	&tdmout_b_lrclk,
-	&tdmout_c_lrclk,
-	&spdifout_b_clk_sel,
-	&spdifout_b_clk_div,
-	&spdifout_b_clk,
-	&g12a_tdm_mclk_pad_0,
-	&g12a_tdm_mclk_pad_1,
-	&g12a_tdm_lrclk_pad_0,
-	&g12a_tdm_lrclk_pad_1,
-	&g12a_tdm_lrclk_pad_2,
-	&g12a_tdm_sclk_pad_0,
-	&g12a_tdm_sclk_pad_1,
-	&g12a_tdm_sclk_pad_2,
-	&toram,
-	&eqdrc,
-};
-
-static struct clk_regmap *const sm1_clk_regmaps[] = {
-	&ddr_arb,
-	&pdm,
-	&tdmin_a,
-	&tdmin_b,
-	&tdmin_c,
-	&tdmin_lb,
-	&tdmout_a,
-	&tdmout_b,
-	&tdmout_c,
-	&frddr_a,
-	&frddr_b,
-	&frddr_c,
-	&toddr_a,
-	&toddr_b,
-	&toddr_c,
-	&loopback,
-	&spdifin,
-	&spdifout,
-	&resample,
-	&spdifout_b,
-	&sm1_mst_a_mclk_sel,
-	&sm1_mst_b_mclk_sel,
-	&sm1_mst_c_mclk_sel,
-	&sm1_mst_d_mclk_sel,
-	&sm1_mst_e_mclk_sel,
-	&sm1_mst_f_mclk_sel,
-	&sm1_mst_a_mclk_div,
-	&sm1_mst_b_mclk_div,
-	&sm1_mst_c_mclk_div,
-	&sm1_mst_d_mclk_div,
-	&sm1_mst_e_mclk_div,
-	&sm1_mst_f_mclk_div,
-	&sm1_mst_a_mclk,
-	&sm1_mst_b_mclk,
-	&sm1_mst_c_mclk,
-	&sm1_mst_d_mclk,
-	&sm1_mst_e_mclk,
-	&sm1_mst_f_mclk,
-	&spdifout_clk_sel,
-	&spdifout_clk_div,
-	&spdifout_clk,
-	&spdifin_clk_sel,
-	&spdifin_clk_div,
-	&spdifin_clk,
-	&pdm_dclk_sel,
-	&pdm_dclk_div,
-	&pdm_dclk,
-	&pdm_sysclk_sel,
-	&pdm_sysclk_div,
-	&pdm_sysclk,
-	&mst_a_sclk_pre_en,
-	&mst_b_sclk_pre_en,
-	&mst_c_sclk_pre_en,
-	&mst_d_sclk_pre_en,
-	&mst_e_sclk_pre_en,
-	&mst_f_sclk_pre_en,
-	&mst_a_sclk_div,
-	&mst_b_sclk_div,
-	&mst_c_sclk_div,
-	&mst_d_sclk_div,
-	&mst_e_sclk_div,
-	&mst_f_sclk_div,
-	&mst_a_sclk_post_en,
-	&mst_b_sclk_post_en,
-	&mst_c_sclk_post_en,
-	&mst_d_sclk_post_en,
-	&mst_e_sclk_post_en,
-	&mst_f_sclk_post_en,
-	&mst_a_sclk,
-	&mst_b_sclk,
-	&mst_c_sclk,
-	&mst_d_sclk,
-	&mst_e_sclk,
-	&mst_f_sclk,
-	&mst_a_lrclk_div,
-	&mst_b_lrclk_div,
-	&mst_c_lrclk_div,
-	&mst_d_lrclk_div,
-	&mst_e_lrclk_div,
-	&mst_f_lrclk_div,
-	&mst_a_lrclk,
-	&mst_b_lrclk,
-	&mst_c_lrclk,
-	&mst_d_lrclk,
-	&mst_e_lrclk,
-	&mst_f_lrclk,
-	&tdmin_a_sclk_sel,
-	&tdmin_b_sclk_sel,
-	&tdmin_c_sclk_sel,
-	&tdmin_lb_sclk_sel,
-	&tdmout_a_sclk_sel,
-	&tdmout_b_sclk_sel,
-	&tdmout_c_sclk_sel,
-	&tdmin_a_sclk_pre_en,
-	&tdmin_b_sclk_pre_en,
-	&tdmin_c_sclk_pre_en,
-	&tdmin_lb_sclk_pre_en,
-	&tdmout_a_sclk_pre_en,
-	&tdmout_b_sclk_pre_en,
-	&tdmout_c_sclk_pre_en,
-	&tdmin_a_sclk_post_en,
-	&tdmin_b_sclk_post_en,
-	&tdmin_c_sclk_post_en,
-	&tdmin_lb_sclk_post_en,
-	&tdmout_a_sclk_post_en,
-	&tdmout_b_sclk_post_en,
-	&tdmout_c_sclk_post_en,
-	&tdmin_a_sclk,
-	&tdmin_b_sclk,
-	&tdmin_c_sclk,
-	&tdmin_lb_sclk,
-	&g12a_tdmout_a_sclk,
-	&g12a_tdmout_b_sclk,
-	&g12a_tdmout_c_sclk,
-	&tdmin_a_lrclk,
-	&tdmin_b_lrclk,
-	&tdmin_c_lrclk,
-	&tdmin_lb_lrclk,
-	&tdmout_a_lrclk,
-	&tdmout_b_lrclk,
-	&tdmout_c_lrclk,
-	&spdifout_b_clk_sel,
-	&spdifout_b_clk_div,
-	&spdifout_b_clk,
-	&sm1_tdm_mclk_pad_0,
-	&sm1_tdm_mclk_pad_1,
-	&sm1_tdm_lrclk_pad_0,
-	&sm1_tdm_lrclk_pad_1,
-	&sm1_tdm_lrclk_pad_2,
-	&sm1_tdm_sclk_pad_0,
-	&sm1_tdm_sclk_pad_1,
-	&sm1_tdm_sclk_pad_2,
-	&sm1_aud_top,
-	&toram,
-	&eqdrc,
-	&resample_b,
-	&tovad,
-	&locker,
-	&spdifin_lb,
-	&frddr_d,
-	&toddr_d,
-	&loopback_b,
-	&sm1_clk81_en,
-	&sm1_sysclk_a_div,
-	&sm1_sysclk_a_en,
-	&sm1_sysclk_b_div,
-	&sm1_sysclk_b_en,
-	&earcrx,
-	&sm1_earcrx_cmdc_clk_sel,
-	&sm1_earcrx_cmdc_clk_div,
-	&sm1_earcrx_cmdc_clk,
-	&sm1_earcrx_dmac_clk_sel,
-	&sm1_earcrx_dmac_clk_div,
-	&sm1_earcrx_dmac_clk,
-};
-
 struct axg_audio_reset_data {
 	struct reset_controller_dev rstc;
 	struct regmap *map;
@@ -1763,8 +1342,6 @@ static struct regmap_config axg_audio_regmap_cfg = {
 };
 
 struct audioclk_data {
-	struct clk_regmap *const *regmap_clks;
-	unsigned int regmap_clk_num;
 	struct meson_clk_hw_data hw_clks;
 	unsigned int reset_offset;
 	unsigned int reset_num;
@@ -1808,9 +1385,9 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	/* Populate regmap for the regmap backed clocks */
-	for (i = 0; i < data->regmap_clk_num; i++)
-		data->regmap_clks[i]->map = map;
+	ret = clk_regmap_init_regmap(dev, map);
+	if (ret)
+		return ret;
 
 	/* Take care to skip the registered input clocks */
 	for (i = AUD_CLKID_DDR_ARB; i < data->hw_clks.num; i++) {
@@ -1853,8 +1430,6 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
 }
 
 static const struct audioclk_data axg_audioclk_data = {
-	.regmap_clks = axg_clk_regmaps,
-	.regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps),
 	.hw_clks = {
 		.hws = axg_audio_hw_clks,
 		.num = ARRAY_SIZE(axg_audio_hw_clks),
@@ -1863,8 +1438,6 @@ static const struct audioclk_data axg_audioclk_data = {
 };
 
 static const struct audioclk_data g12a_audioclk_data = {
-	.regmap_clks = g12a_clk_regmaps,
-	.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
 	.hw_clks = {
 		.hws = g12a_audio_hw_clks,
 		.num = ARRAY_SIZE(g12a_audio_hw_clks),
@@ -1875,8 +1448,6 @@ static const struct audioclk_data g12a_audioclk_data = {
 };
 
 static const struct audioclk_data sm1_audioclk_data = {
-	.regmap_clks = sm1_clk_regmaps,
-	.regmap_clk_num = ARRAY_SIZE(sm1_clk_regmaps),
 	.hw_clks = {
 		.hws = sm1_audio_hw_clks,
 		.num = ARRAY_SIZE(sm1_audio_hw_clks),
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 1b08daf579b2e57c4f618ce13d10206330fdce3e..c1c53ba1449f0dde5f70012b213a58d2ec8628c8 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -2025,138 +2025,7 @@ static struct clk_hw *axg_hw_clks[] = {
 	[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
 };
 
-/* Convenience table to populate regmap in .probe */
-static struct clk_regmap *const axg_clk_regmaps[] = {
-	&axg_clk81,
-	&axg_ddr,
-	&axg_audio_locker,
-	&axg_mipi_dsi_host,
-	&axg_isa,
-	&axg_pl301,
-	&axg_periphs,
-	&axg_spicc_0,
-	&axg_i2c,
-	&axg_rng0,
-	&axg_uart0,
-	&axg_mipi_dsi_phy,
-	&axg_spicc_1,
-	&axg_pcie_a,
-	&axg_pcie_b,
-	&axg_hiu_reg,
-	&axg_assist_misc,
-	&axg_emmc_b,
-	&axg_emmc_c,
-	&axg_dma,
-	&axg_spi,
-	&axg_audio,
-	&axg_eth_core,
-	&axg_uart1,
-	&axg_g2d,
-	&axg_usb0,
-	&axg_usb1,
-	&axg_reset,
-	&axg_usb_general,
-	&axg_ahb_arb0,
-	&axg_efuse,
-	&axg_boot_rom,
-	&axg_ahb_data_bus,
-	&axg_ahb_ctrl_bus,
-	&axg_usb1_to_ddr,
-	&axg_usb0_to_ddr,
-	&axg_mmc_pclk,
-	&axg_vpu_intr,
-	&axg_sec_ahb_ahb3_bridge,
-	&axg_gic,
-	&axg_ao_media_cpu,
-	&axg_ao_ahb_sram,
-	&axg_ao_ahb_bus,
-	&axg_ao_iface,
-	&axg_ao_i2c,
-	&axg_sd_emmc_b_clk0,
-	&axg_sd_emmc_c_clk0,
-	&axg_mpeg_clk_div,
-	&axg_sd_emmc_b_clk0_div,
-	&axg_sd_emmc_c_clk0_div,
-	&axg_mpeg_clk_sel,
-	&axg_sd_emmc_b_clk0_sel,
-	&axg_sd_emmc_c_clk0_sel,
-	&axg_mpll0,
-	&axg_mpll1,
-	&axg_mpll2,
-	&axg_mpll3,
-	&axg_mpll0_div,
-	&axg_mpll1_div,
-	&axg_mpll2_div,
-	&axg_mpll3_div,
-	&axg_fixed_pll,
-	&axg_sys_pll,
-	&axg_gp0_pll,
-	&axg_hifi_pll,
-	&axg_mpll_prediv,
-	&axg_fclk_div2,
-	&axg_fclk_div3,
-	&axg_fclk_div4,
-	&axg_fclk_div5,
-	&axg_fclk_div7,
-	&axg_pcie_pll_dco,
-	&axg_pcie_pll_od,
-	&axg_pcie_pll,
-	&axg_pcie_mux,
-	&axg_pcie_ref,
-	&axg_pcie_cml_en0,
-	&axg_pcie_cml_en1,
-	&axg_gen_clk_sel,
-	&axg_gen_clk_div,
-	&axg_gen_clk,
-	&axg_fixed_pll_dco,
-	&axg_sys_pll_dco,
-	&axg_gp0_pll_dco,
-	&axg_hifi_pll_dco,
-	&axg_pcie_pll_dco,
-	&axg_pcie_pll_od,
-	&axg_vpu_0_div,
-	&axg_vpu_0_sel,
-	&axg_vpu_0,
-	&axg_vpu_1_div,
-	&axg_vpu_1_sel,
-	&axg_vpu_1,
-	&axg_vpu,
-	&axg_vapb_0_div,
-	&axg_vapb_0_sel,
-	&axg_vapb_0,
-	&axg_vapb_1_div,
-	&axg_vapb_1_sel,
-	&axg_vapb_1,
-	&axg_vapb_sel,
-	&axg_vapb,
-	&axg_vclk,
-	&axg_vclk2,
-	&axg_vclk_sel,
-	&axg_vclk2_sel,
-	&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,
-	&axg_vclk_div12_en,
-	&axg_vclk2_div2_en,
-	&axg_vclk2_div4_en,
-	&axg_vclk2_div6_en,
-	&axg_vclk2_div12_en,
-	&axg_cts_encl_sel,
-	&axg_cts_encl,
-	&axg_vdin_meas_sel,
-	&axg_vdin_meas_div,
-	&axg_vdin_meas,
-};
-
 static const struct meson_eeclkc_data axg_clkc_data = {
-	.regmap_clks = axg_clk_regmaps,
-	.regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps),
 	.hw_clks = {
 		.hws = axg_hw_clks,
 		.num = ARRAY_SIZE(axg_hw_clks),
diff --git a/drivers/clk/meson/c3-peripherals.c b/drivers/clk/meson/c3-peripherals.c
index 7dcbf4ebee078abaebc28c666c6ffe8160d8d7e5..fd6ac1cd6c3d24b749f09c2170f360850f19432d 100644
--- a/drivers/clk/meson/c3-peripherals.c
+++ b/drivers/clk/meson/c3-peripherals.c
@@ -2092,210 +2092,6 @@ static struct clk_hw *c3_periphs_hw_clks[] = {
 	[CLKID_VAPB]			= &vapb.hw,
 };
 
-/* Convenience table to populate regmap in .probe */
-static struct clk_regmap *const c3_periphs_clk_regmaps[] = {
-	&rtc_xtal_clkin,
-	&rtc_32k_div,
-	&rtc_32k_mux,
-	&rtc_32k,
-	&rtc_clk,
-	&sys_reset_ctrl,
-	&sys_pwr_ctrl,
-	&sys_pad_ctrl,
-	&sys_ctrl,
-	&sys_ts_pll,
-	&sys_dev_arb,
-	&sys_mmc_pclk,
-	&sys_cpu_ctrl,
-	&sys_jtag_ctrl,
-	&sys_ir_ctrl,
-	&sys_irq_ctrl,
-	&sys_msr_clk,
-	&sys_rom,
-	&sys_uart_f,
-	&sys_cpu_apb,
-	&sys_rsa,
-	&sys_sar_adc,
-	&sys_startup,
-	&sys_secure,
-	&sys_spifc,
-	&sys_nna,
-	&sys_eth_mac,
-	&sys_gic,
-	&sys_rama,
-	&sys_big_nic,
-	&sys_ramb,
-	&sys_audio_pclk,
-	&sys_pwm_kl,
-	&sys_pwm_ij,
-	&sys_usb,
-	&sys_sd_emmc_a,
-	&sys_sd_emmc_c,
-	&sys_pwm_ab,
-	&sys_pwm_cd,
-	&sys_pwm_ef,
-	&sys_pwm_gh,
-	&sys_spicc_1,
-	&sys_spicc_0,
-	&sys_uart_a,
-	&sys_uart_b,
-	&sys_uart_c,
-	&sys_uart_d,
-	&sys_uart_e,
-	&sys_i2c_m_a,
-	&sys_i2c_m_b,
-	&sys_i2c_m_c,
-	&sys_i2c_m_d,
-	&sys_i2c_s_a,
-	&sys_rtc,
-	&sys_ge2d,
-	&sys_isp,
-	&sys_gpv_isp_nic,
-	&sys_gpv_cve_nic,
-	&sys_mipi_dsi_host,
-	&sys_mipi_dsi_phy,
-	&sys_eth_phy,
-	&sys_acodec,
-	&sys_dwap,
-	&sys_dos,
-	&sys_cve,
-	&sys_vout,
-	&sys_vc9000e,
-	&sys_pwm_mn,
-	&sys_sd_emmc_b,
-	&axi_sys_nic,
-	&axi_isp_nic,
-	&axi_cve_nic,
-	&axi_ramb,
-	&axi_rama,
-	&axi_cpu_dmc,
-	&axi_nic,
-	&axi_dma,
-	&axi_mux_nic,
-	&axi_cve,
-	&axi_dev1_dmc,
-	&axi_dev0_dmc,
-	&axi_dsp_dmc,
-	&clk_12_24m_in,
-	&clk_12_24m,
-	&fclk_25m_div,
-	&fclk_25m,
-	&gen_sel,
-	&gen_div,
-	&gen,
-	&saradc_sel,
-	&saradc_div,
-	&saradc,
-	&pwm_a_sel,
-	&pwm_a_div,
-	&pwm_a,
-	&pwm_b_sel,
-	&pwm_b_div,
-	&pwm_b,
-	&pwm_c_sel,
-	&pwm_c_div,
-	&pwm_c,
-	&pwm_d_sel,
-	&pwm_d_div,
-	&pwm_d,
-	&pwm_e_sel,
-	&pwm_e_div,
-	&pwm_e,
-	&pwm_f_sel,
-	&pwm_f_div,
-	&pwm_f,
-	&pwm_g_sel,
-	&pwm_g_div,
-	&pwm_g,
-	&pwm_h_sel,
-	&pwm_h_div,
-	&pwm_h,
-	&pwm_i_sel,
-	&pwm_i_div,
-	&pwm_i,
-	&pwm_j_sel,
-	&pwm_j_div,
-	&pwm_j,
-	&pwm_k_sel,
-	&pwm_k_div,
-	&pwm_k,
-	&pwm_l_sel,
-	&pwm_l_div,
-	&pwm_l,
-	&pwm_m_sel,
-	&pwm_m_div,
-	&pwm_m,
-	&pwm_n_sel,
-	&pwm_n_div,
-	&pwm_n,
-	&spicc_a_sel,
-	&spicc_a_div,
-	&spicc_a,
-	&spicc_b_sel,
-	&spicc_b_div,
-	&spicc_b,
-	&spifc_sel,
-	&spifc_div,
-	&spifc,
-	&sd_emmc_a_sel,
-	&sd_emmc_a_div,
-	&sd_emmc_a,
-	&sd_emmc_b_sel,
-	&sd_emmc_b_div,
-	&sd_emmc_b,
-	&sd_emmc_c_sel,
-	&sd_emmc_c_div,
-	&sd_emmc_c,
-	&ts_div,
-	&ts,
-	&eth_125m,
-	&eth_rmii_div,
-	&eth_rmii,
-	&mipi_dsi_meas_sel,
-	&mipi_dsi_meas_div,
-	&mipi_dsi_meas,
-	&dsi_phy_sel,
-	&dsi_phy_div,
-	&dsi_phy,
-	&vout_mclk_sel,
-	&vout_mclk_div,
-	&vout_mclk,
-	&vout_enc_sel,
-	&vout_enc_div,
-	&vout_enc,
-	&hcodec_0_sel,
-	&hcodec_0_div,
-	&hcodec_0,
-	&hcodec_1_sel,
-	&hcodec_1_div,
-	&hcodec_1,
-	&hcodec,
-	&vc9000e_aclk_sel,
-	&vc9000e_aclk_div,
-	&vc9000e_aclk,
-	&vc9000e_core_sel,
-	&vc9000e_core_div,
-	&vc9000e_core,
-	&csi_phy0_sel,
-	&csi_phy0_div,
-	&csi_phy0,
-	&dewarpa_sel,
-	&dewarpa_div,
-	&dewarpa,
-	&isp0_sel,
-	&isp0_div,
-	&isp0,
-	&nna_core_sel,
-	&nna_core_div,
-	&nna_core,
-	&ge2d_sel,
-	&ge2d_div,
-	&ge2d,
-	&vapb_sel,
-	&vapb_div,
-	&vapb,
-};
-
 static const struct regmap_config clkc_regmap_config = {
 	.reg_bits       = 32,
 	.val_bits       = 32,
@@ -2313,7 +2109,7 @@ static int c3_peripherals_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct regmap *regmap;
 	void __iomem *base;
-	int clkid, ret, i;
+	int clkid, ret;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
@@ -2323,9 +2119,9 @@ static int c3_peripherals_probe(struct platform_device *pdev)
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	/* Populate regmap for the regmap backed clocks */
-	for (i = 0; i < ARRAY_SIZE(c3_periphs_clk_regmaps); i++)
-		c3_periphs_clk_regmaps[i]->map = regmap;
+	ret = clk_regmap_init_regmap(dev, regmap);
+	if (ret)
+		return ret;
 
 	for (clkid = 0; clkid < c3_periphs_clks.num; clkid++) {
 		/* array might be sparse */
diff --git a/drivers/clk/meson/c3-pll.c b/drivers/clk/meson/c3-pll.c
index 35fda31a19e218bb6db71346a264ec20e832382c..cbfc9d0b189edecbd0cee87044c245283776a74d 100644
--- a/drivers/clk/meson/c3-pll.c
+++ b/drivers/clk/meson/c3-pll.c
@@ -653,32 +653,6 @@ static struct clk_hw *c3_pll_hw_clks[] = {
 	[CLKID_MCLK1]		= &mclk1.hw
 };
 
-/* Convenience table to populate regmap in .probe */
-static struct clk_regmap *const c3_pll_clk_regmaps[] = {
-	&fclk_50m_en,
-	&fclk_div2,
-	&fclk_div2p5,
-	&fclk_div3,
-	&fclk_div4,
-	&fclk_div5,
-	&fclk_div7,
-	&gp0_pll_dco,
-	&gp0_pll,
-	&hifi_pll_dco,
-	&hifi_pll,
-	&mclk_pll_dco,
-	&mclk_pll_od,
-	&mclk_pll,
-	&mclk0_sel,
-	&mclk0_div_en,
-	&mclk0_div,
-	&mclk0,
-	&mclk1_sel,
-	&mclk1_div_en,
-	&mclk1_div,
-	&mclk1,
-};
-
 static const struct regmap_config clkc_regmap_config = {
 	.reg_bits       = 32,
 	.val_bits       = 32,
@@ -696,7 +670,7 @@ static int c3_pll_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct regmap *regmap;
 	void __iomem *base;
-	int clkid, ret, i;
+	int clkid, ret;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
@@ -706,9 +680,9 @@ static int c3_pll_probe(struct platform_device *pdev)
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	/* Populate regmap for the regmap backed clocks */
-	for (i = 0; i < ARRAY_SIZE(c3_pll_clk_regmaps); i++)
-		c3_pll_clk_regmaps[i]->map = regmap;
+	ret = clk_regmap_init_regmap(dev, regmap);
+	if (ret)
+		return ret;
 
 	for (clkid = 0; clkid < c3_pll_clks.num; clkid++) {
 		/* array might be sparse */
diff --git a/drivers/clk/meson/clk-cpu-dyndiv.c b/drivers/clk/meson/clk-cpu-dyndiv.c
index 6c1f58826e24a2bf7706f0fc98cdcdb44fd60b64..0498fd3af7de7b9a4e72930ac4de11368d686393 100644
--- a/drivers/clk/meson/clk-cpu-dyndiv.c
+++ b/drivers/clk/meson/clk-cpu-dyndiv.c
@@ -61,6 +61,7 @@ static int meson_clk_cpu_dyndiv_set_rate(struct clk_hw *hw, unsigned long rate,
 };
 
 const struct clk_ops meson_clk_cpu_dyndiv_ops = {
+	.init = clk_regmap_init,
 	.recalc_rate = meson_clk_cpu_dyndiv_recalc_rate,
 	.determine_rate = meson_clk_cpu_dyndiv_determine_rate,
 	.set_rate = meson_clk_cpu_dyndiv_set_rate,
diff --git a/drivers/clk/meson/clk-dualdiv.c b/drivers/clk/meson/clk-dualdiv.c
index 913bf25d3771bdffa8db28e9b08dc566d1aac1ff..7c668df1a29f6eb20bde3f23d8701443602d774c 100644
--- a/drivers/clk/meson/clk-dualdiv.c
+++ b/drivers/clk/meson/clk-dualdiv.c
@@ -126,6 +126,7 @@ static int meson_clk_dualdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 }
 
 const struct clk_ops meson_clk_dualdiv_ops = {
+	.init		= clk_regmap_init,
 	.recalc_rate	= meson_clk_dualdiv_recalc_rate,
 	.determine_rate	= meson_clk_dualdiv_determine_rate,
 	.set_rate	= meson_clk_dualdiv_set_rate,
@@ -133,6 +134,7 @@ const struct clk_ops meson_clk_dualdiv_ops = {
 EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ops, CLK_MESON);
 
 const struct clk_ops meson_clk_dualdiv_ro_ops = {
+	.init		= clk_regmap_init,
 	.recalc_rate	= meson_clk_dualdiv_recalc_rate,
 };
 EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ro_ops, CLK_MESON);
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index aa9abd06ae653585f68043bb1ddc2b0b96feeb6d..166fbcb053cc573ec92489c2bb03f81caffdf64b 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -128,6 +128,11 @@ static int mpll_init(struct clk_hw *hw)
 {
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
+	int ret;
+
+	ret = clk_regmap_init(hw);
+	if (ret)
+		return ret;
 
 	if (mpll->init_count)
 		regmap_multi_reg_write(clk->map, mpll->init_regs,
@@ -151,6 +156,7 @@ static int mpll_init(struct clk_hw *hw)
 }
 
 const struct clk_ops meson_clk_mpll_ro_ops = {
+	.init		= clk_regmap_init,
 	.recalc_rate	= mpll_recalc_rate,
 	.determine_rate	= mpll_determine_rate,
 };
diff --git a/drivers/clk/meson/clk-phase.c b/drivers/clk/meson/clk-phase.c
index c1526fbfb6c4ccdd4034df465f70a56e0f9214ac..d05065e56483a218e0eaf402807c8734271d0cf5 100644
--- a/drivers/clk/meson/clk-phase.c
+++ b/drivers/clk/meson/clk-phase.c
@@ -58,6 +58,7 @@ static int meson_clk_phase_set_phase(struct clk_hw *hw, int degrees)
 }
 
 const struct clk_ops meson_clk_phase_ops = {
+	.init		= clk_regmap_init,
 	.get_phase	= meson_clk_phase_get_phase,
 	.set_phase	= meson_clk_phase_set_phase,
 };
@@ -83,6 +84,11 @@ static int meson_clk_triphase_sync(struct clk_hw *hw)
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
 	unsigned int val;
+	int ret;
+
+	ret = clk_regmap_init(hw);
+	if (ret)
+		return ret;
 
 	/* Get phase 0 and sync it to phase 1 and 2 */
 	val = meson_parm_read(clk->map, &tph->ph0);
@@ -142,6 +148,11 @@ static int meson_sclk_ws_inv_sync(struct clk_hw *hw)
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
 	unsigned int val;
+	int ret;
+
+	ret = clk_regmap_init(hw);
+	if (ret)
+		return ret;
 
 	/* Get phase and sync the inverted value to ws */
 	val = meson_parm_read(clk->map, &tph->ph);
diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 89f0f04a16abad99748e1ff3784e7ed91abd0f88..eaaf021d2f6911a99a722c8b9d8b4e1f1f77d0e6 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -311,6 +311,11 @@ static int meson_clk_pll_init(struct clk_hw *hw)
 {
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
+	int ret;
+
+	ret = clk_regmap_init(hw);
+	if (ret)
+		return ret;
 
 	/*
 	 * Keep the clock running, which was already initialized and enabled
@@ -468,6 +473,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
  * the other ops except set_rate since the rate is fixed.
  */
 const struct clk_ops meson_clk_pcie_pll_ops = {
+	.init		= clk_regmap_init,
 	.recalc_rate	= meson_clk_pll_recalc_rate,
 	.determine_rate	= meson_clk_pll_determine_rate,
 	.is_enabled	= meson_clk_pll_is_enabled,
@@ -488,6 +494,7 @@ const struct clk_ops meson_clk_pll_ops = {
 EXPORT_SYMBOL_NS_GPL(meson_clk_pll_ops, CLK_MESON);
 
 const struct clk_ops meson_clk_pll_ro_ops = {
+	.init		= clk_regmap_init,
 	.recalc_rate	= meson_clk_pll_recalc_rate,
 	.is_enabled	= meson_clk_pll_is_enabled,
 };
diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c
index 07f7e441b9161c47fdb38ec61ed162a2f9d4fe41..a69c83215571051b88f4b33e342d34c0065f29fc 100644
--- a/drivers/clk/meson/clk-regmap.c
+++ b/drivers/clk/meson/clk-regmap.c
@@ -4,9 +4,91 @@
  * Author: Jerome Brunet <jbrunet at baylibre.com>
  */
 
+#include <linux/device.h>
 #include <linux/module.h>
 #include "clk-regmap.h"
 
+static void clk_regmap_devres_release(struct device *dev, void *res)
+{
+	/*
+	 * Nothing to be done here
+	 * This is meant as an id for devres related functions
+	 */
+}
+
+static int clk_regmap_devres_match(struct device *dev, void *res, void *data)
+{
+	struct regmap **r = res;
+
+	if (!r || !*r) {
+		WARN_ON(!r || !*r);
+		return 0;
+	}
+
+	/*
+	 * NOTE:
+	 * At the moment, only one regmap is needed so only one is expected
+	 * to be registered. Should more be needed in the future,
+	 * struct clk_regmap should evolve to carry the name of regmap it
+	 * needs
+	 */
+	return 1;
+}
+
+int clk_regmap_init_regmap(struct device *dev, struct regmap *map)
+{
+	struct regmap **m;
+
+	m = devres_alloc(clk_regmap_devres_release, sizeof(*m), GFP_KERNEL);
+	if (!m)
+		return -ENOMEM;
+
+	*m = map;
+	devres_add(dev, m);
+
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(clk_regmap_init_regmap, CLK_MESON);
+
+static struct regmap *clk_regmap_init_get_regmap(struct device *dev)
+{
+	struct regmap **r = devres_find(dev, clk_regmap_devres_release,
+					clk_regmap_devres_match, NULL);
+
+	if (!r)
+		return NULL;
+
+	return *r;
+}
+
+int clk_regmap_init(struct clk_hw *hw)
+{
+	struct device *dev = clk_hw_get_dev(hw);
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct regmap *map;
+
+	/*
+	 * Do not try to go through devres if there is not device associated
+	 * with the clock. It may happen with early controller that have no
+	 * device support. In this case, regmap should already be set.
+	 */
+	if (!dev)
+		return clk->map ? 0 : -EINVAL;
+
+	map = clk_regmap_init_get_regmap(dev);
+	if (!map)
+		return -EINVAL;
+
+	/*
+	 * Cache the regmap here so it not necessary to through devres
+	 * for each clock action
+	 */
+	clk->map = map;
+
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(clk_regmap_init, CLK_MESON);
+
 static int clk_regmap_gate_endisable(struct clk_hw *hw, int enable)
 {
 	struct clk_regmap *clk = to_clk_regmap(hw);
@@ -45,6 +127,7 @@ static int clk_regmap_gate_is_enabled(struct clk_hw *hw)
 }
 
 const struct clk_ops clk_regmap_gate_ops = {
+	.init		= clk_regmap_init,
 	.enable = clk_regmap_gate_enable,
 	.disable = clk_regmap_gate_disable,
 	.is_enabled = clk_regmap_gate_is_enabled,
@@ -52,6 +135,7 @@ const struct clk_ops clk_regmap_gate_ops = {
 EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ops, CLK_MESON);
 
 const struct clk_ops clk_regmap_gate_ro_ops = {
+	.init		= clk_regmap_init,
 	.is_enabled = clk_regmap_gate_is_enabled,
 };
 EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ro_ops, CLK_MESON);
@@ -121,6 +205,7 @@ static int clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long rate,
 /* Would prefer clk_regmap_div_ro_ops but clashes with qcom */
 
 const struct clk_ops clk_regmap_divider_ops = {
+	.init = clk_regmap_init,
 	.recalc_rate = clk_regmap_div_recalc_rate,
 	.determine_rate = clk_regmap_div_determine_rate,
 	.set_rate = clk_regmap_div_set_rate,
@@ -128,6 +213,7 @@ const struct clk_ops clk_regmap_divider_ops = {
 EXPORT_SYMBOL_NS_GPL(clk_regmap_divider_ops, CLK_MESON);
 
 const struct clk_ops clk_regmap_divider_ro_ops = {
+	.init = clk_regmap_init,
 	.recalc_rate = clk_regmap_div_recalc_rate,
 	.determine_rate = clk_regmap_div_determine_rate,
 };
@@ -170,6 +256,7 @@ static int clk_regmap_mux_determine_rate(struct clk_hw *hw,
 }
 
 const struct clk_ops clk_regmap_mux_ops = {
+	.init		= clk_regmap_init,
 	.get_parent = clk_regmap_mux_get_parent,
 	.set_parent = clk_regmap_mux_set_parent,
 	.determine_rate = clk_regmap_mux_determine_rate,
@@ -177,6 +264,7 @@ const struct clk_ops clk_regmap_mux_ops = {
 EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ops, CLK_MESON);
 
 const struct clk_ops clk_regmap_mux_ro_ops = {
+	.init		= clk_regmap_init,
 	.get_parent = clk_regmap_mux_get_parent,
 };
 EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ro_ops, CLK_MESON);
diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h
index e365312da54ece08098293b1a831c803415db814..0945aab6d99e537eb66cc7a72643e0a293cea74d 100644
--- a/drivers/clk/meson/clk-regmap.h
+++ b/drivers/clk/meson/clk-regmap.h
@@ -7,6 +7,7 @@
 #ifndef __CLK_REGMAP_H
 #define __CLK_REGMAP_H
 
+#include <linux/device.h>
 #include <linux/clk-provider.h>
 #include <linux/regmap.h>
 
@@ -31,6 +32,12 @@ static inline struct clk_regmap *to_clk_regmap(struct clk_hw *hw)
 	return container_of(hw, struct clk_regmap, hw);
 }
 
+/* Controllers should call this to provide regmap to clk_regmap clocks */
+int clk_regmap_init_regmap(struct device *dev, struct regmap *map);
+
+/* clk_regmap init op to get and cache regmap from the controllers */
+int clk_regmap_init(struct clk_hw *hw);
+
 /**
  * struct clk_regmap_gate_data - regmap backed gate specific data
  *
diff --git a/drivers/clk/meson/g12a-aoclk.c b/drivers/clk/meson/g12a-aoclk.c
index f0a18d8c9fc2318d04dde0e63b4a53d0e1f88db5..ff468f43eb0185ed84e667650ee9b9f94384c687 100644
--- a/drivers/clk/meson/g12a-aoclk.c
+++ b/drivers/clk/meson/g12a-aoclk.c
@@ -381,38 +381,6 @@ static const unsigned int g12a_aoclk_reset[] = {
 	[RESET_AO_IR_OUT]	= 23,
 };
 
-static struct clk_regmap *g12a_aoclk_regmap[] = {
-	&g12a_aoclk_ahb,
-	&g12a_aoclk_ir_in,
-	&g12a_aoclk_i2c_m0,
-	&g12a_aoclk_i2c_s0,
-	&g12a_aoclk_uart,
-	&g12a_aoclk_prod_i2c,
-	&g12a_aoclk_uart2,
-	&g12a_aoclk_ir_out,
-	&g12a_aoclk_saradc,
-	&g12a_aoclk_mailbox,
-	&g12a_aoclk_m3,
-	&g12a_aoclk_ahb_sram,
-	&g12a_aoclk_rti,
-	&g12a_aoclk_m4_fclk,
-	&g12a_aoclk_m4_hclk,
-	&g12a_aoclk_cts_oscin,
-	&g12a_aoclk_32k_by_oscin_pre,
-	&g12a_aoclk_32k_by_oscin_div,
-	&g12a_aoclk_32k_by_oscin_sel,
-	&g12a_aoclk_32k_by_oscin,
-	&g12a_aoclk_cec_pre,
-	&g12a_aoclk_cec_div,
-	&g12a_aoclk_cec_sel,
-	&g12a_aoclk_cec,
-	&g12a_aoclk_cts_rtc_oscin,
-	&g12a_aoclk_clk81,
-	&g12a_aoclk_saradc_mux,
-	&g12a_aoclk_saradc_div,
-	&g12a_aoclk_saradc_gate,
-};
-
 static struct clk_hw *g12a_aoclk_hw_clks[] = {
 	[CLKID_AO_AHB]		= &g12a_aoclk_ahb.hw,
 	[CLKID_AO_IR_IN]	= &g12a_aoclk_ir_in.hw,
@@ -449,8 +417,6 @@ static const struct meson_aoclk_data g12a_aoclkc_data = {
 	.reset_reg	= AO_RTI_GEN_CNTL_REG0,
 	.num_reset	= ARRAY_SIZE(g12a_aoclk_reset),
 	.reset		= g12a_aoclk_reset,
-	.num_clks	= ARRAY_SIZE(g12a_aoclk_regmap),
-	.clks		= g12a_aoclk_regmap,
 	.hw_clks	= {
 		.hws	= g12a_aoclk_hw_clks,
 		.num	= ARRAY_SIZE(g12a_aoclk_hw_clks),
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index 4e6584377e43fa7c9956017ddfcd3f295fafd686..34d8398b06c3bdd2571b963339843c0b53843a95 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -5125,261 +5125,6 @@ static struct clk_hw *sm1_hw_clks[] = {
 	[CLKID_MIPI_DSI_PXCLK]		= &g12a_mipi_dsi_pxclk.hw,
 };
 
-/* Convenience table to populate regmap in .probe */
-static struct clk_regmap *const g12a_clk_regmaps[] = {
-	&g12a_clk81,
-	&g12a_dos,
-	&g12a_ddr,
-	&g12a_audio_locker,
-	&g12a_mipi_dsi_host,
-	&g12a_eth_phy,
-	&g12a_isa,
-	&g12a_pl301,
-	&g12a_periphs,
-	&g12a_spicc_0,
-	&g12a_i2c,
-	&g12a_sana,
-	&g12a_sd,
-	&g12a_rng0,
-	&g12a_uart0,
-	&g12a_spicc_1,
-	&g12a_hiu_reg,
-	&g12a_mipi_dsi_phy,
-	&g12a_assist_misc,
-	&g12a_emmc_a,
-	&g12a_emmc_b,
-	&g12a_emmc_c,
-	&g12a_audio_codec,
-	&g12a_audio,
-	&g12a_eth_core,
-	&g12a_demux,
-	&g12a_audio_ififo,
-	&g12a_adc,
-	&g12a_uart1,
-	&g12a_g2d,
-	&g12a_reset,
-	&g12a_pcie_comb,
-	&g12a_parser,
-	&g12a_usb_general,
-	&g12a_pcie_phy,
-	&g12a_ahb_arb0,
-	&g12a_ahb_data_bus,
-	&g12a_ahb_ctrl_bus,
-	&g12a_htx_hdcp22,
-	&g12a_htx_pclk,
-	&g12a_bt656,
-	&g12a_usb1_to_ddr,
-	&g12a_mmc_pclk,
-	&g12a_uart2,
-	&g12a_vpu_intr,
-	&g12a_gic,
-	&g12a_sd_emmc_a_clk0,
-	&g12a_sd_emmc_b_clk0,
-	&g12a_sd_emmc_c_clk0,
-	&g12a_mpeg_clk_div,
-	&g12a_sd_emmc_a_clk0_div,
-	&g12a_sd_emmc_b_clk0_div,
-	&g12a_sd_emmc_c_clk0_div,
-	&g12a_mpeg_clk_sel,
-	&g12a_sd_emmc_a_clk0_sel,
-	&g12a_sd_emmc_b_clk0_sel,
-	&g12a_sd_emmc_c_clk0_sel,
-	&g12a_mpll0,
-	&g12a_mpll1,
-	&g12a_mpll2,
-	&g12a_mpll3,
-	&g12a_mpll0_div,
-	&g12a_mpll1_div,
-	&g12a_mpll2_div,
-	&g12a_mpll3_div,
-	&g12a_fixed_pll,
-	&g12a_sys_pll,
-	&g12a_gp0_pll,
-	&g12a_hifi_pll,
-	&g12a_vclk2_venci0,
-	&g12a_vclk2_venci1,
-	&g12a_vclk2_vencp0,
-	&g12a_vclk2_vencp1,
-	&g12a_vclk2_venct0,
-	&g12a_vclk2_venct1,
-	&g12a_vclk2_other,
-	&g12a_vclk2_enci,
-	&g12a_vclk2_encp,
-	&g12a_dac_clk,
-	&g12a_aoclk_gate,
-	&g12a_iec958_gate,
-	&g12a_enc480p,
-	&g12a_rng1,
-	&g12a_vclk2_enct,
-	&g12a_vclk2_encl,
-	&g12a_vclk2_venclmmc,
-	&g12a_vclk2_vencl,
-	&g12a_vclk2_other1,
-	&g12a_fixed_pll_dco,
-	&g12a_sys_pll_dco,
-	&g12a_gp0_pll_dco,
-	&g12a_hifi_pll_dco,
-	&g12a_fclk_div2,
-	&g12a_fclk_div3,
-	&g12a_fclk_div4,
-	&g12a_fclk_div5,
-	&g12a_fclk_div7,
-	&g12a_fclk_div2p5,
-	&g12a_dma,
-	&g12a_efuse,
-	&g12a_rom_boot,
-	&g12a_reset_sec,
-	&g12a_sec_ahb_apb3,
-	&g12a_vpu_0_sel,
-	&g12a_vpu_0_div,
-	&g12a_vpu_0,
-	&g12a_vpu_1_sel,
-	&g12a_vpu_1_div,
-	&g12a_vpu_1,
-	&g12a_vpu,
-	&g12a_vapb_0_sel,
-	&g12a_vapb_0_div,
-	&g12a_vapb_0,
-	&g12a_vapb_1_sel,
-	&g12a_vapb_1_div,
-	&g12a_vapb_1,
-	&g12a_vapb_sel,
-	&g12a_vapb,
-	&g12a_hdmi_pll_dco,
-	&g12a_hdmi_pll_od,
-	&g12a_hdmi_pll_od2,
-	&g12a_hdmi_pll,
-	&g12a_vid_pll_div,
-	&g12a_vid_pll_sel,
-	&g12a_vid_pll,
-	&g12a_vclk_sel,
-	&g12a_vclk2_sel,
-	&g12a_vclk_input,
-	&g12a_vclk2_input,
-	&g12a_vclk_div,
-	&g12a_vclk2_div,
-	&g12a_vclk,
-	&g12a_vclk2,
-	&g12a_vclk_div1,
-	&g12a_vclk_div2_en,
-	&g12a_vclk_div4_en,
-	&g12a_vclk_div6_en,
-	&g12a_vclk_div12_en,
-	&g12a_vclk2_div1,
-	&g12a_vclk2_div2_en,
-	&g12a_vclk2_div4_en,
-	&g12a_vclk2_div6_en,
-	&g12a_vclk2_div12_en,
-	&g12a_cts_enci_sel,
-	&g12a_cts_encp_sel,
-	&g12a_cts_encl_sel,
-	&g12a_cts_vdac_sel,
-	&g12a_hdmi_tx_sel,
-	&g12a_cts_enci,
-	&g12a_cts_encp,
-	&g12a_cts_encl,
-	&g12a_cts_vdac,
-	&g12a_hdmi_tx,
-	&g12a_hdmi_sel,
-	&g12a_hdmi_div,
-	&g12a_hdmi,
-	&g12a_mali_0_sel,
-	&g12a_mali_0_div,
-	&g12a_mali_0,
-	&g12a_mali_1_sel,
-	&g12a_mali_1_div,
-	&g12a_mali_1,
-	&g12a_mali,
-	&g12a_mpll_50m,
-	&g12a_sys_pll_div16_en,
-	&g12a_cpu_clk_premux0,
-	&g12a_cpu_clk_mux0_div,
-	&g12a_cpu_clk_postmux0,
-	&g12a_cpu_clk_premux1,
-	&g12a_cpu_clk_mux1_div,
-	&g12a_cpu_clk_postmux1,
-	&g12a_cpu_clk_dyn,
-	&g12a_cpu_clk,
-	&g12a_cpu_clk_div16_en,
-	&g12a_cpu_clk_apb_div,
-	&g12a_cpu_clk_apb,
-	&g12a_cpu_clk_atb_div,
-	&g12a_cpu_clk_atb,
-	&g12a_cpu_clk_axi_div,
-	&g12a_cpu_clk_axi,
-	&g12a_cpu_clk_trace_div,
-	&g12a_cpu_clk_trace,
-	&g12a_pcie_pll_od,
-	&g12a_pcie_pll_dco,
-	&g12a_vdec_1_sel,
-	&g12a_vdec_1_div,
-	&g12a_vdec_1,
-	&g12a_vdec_hevc_sel,
-	&g12a_vdec_hevc_div,
-	&g12a_vdec_hevc,
-	&g12a_vdec_hevcf_sel,
-	&g12a_vdec_hevcf_div,
-	&g12a_vdec_hevcf,
-	&g12a_ts_div,
-	&g12a_ts,
-	&g12b_cpu_clk,
-	&g12b_sys1_pll_dco,
-	&g12b_sys1_pll,
-	&g12b_sys1_pll_div16_en,
-	&g12b_cpub_clk_premux0,
-	&g12b_cpub_clk_mux0_div,
-	&g12b_cpub_clk_postmux0,
-	&g12b_cpub_clk_premux1,
-	&g12b_cpub_clk_mux1_div,
-	&g12b_cpub_clk_postmux1,
-	&g12b_cpub_clk_dyn,
-	&g12b_cpub_clk,
-	&g12b_cpub_clk_div16_en,
-	&g12b_cpub_clk_apb_sel,
-	&g12b_cpub_clk_apb,
-	&g12b_cpub_clk_atb_sel,
-	&g12b_cpub_clk_atb,
-	&g12b_cpub_clk_axi_sel,
-	&g12b_cpub_clk_axi,
-	&g12b_cpub_clk_trace_sel,
-	&g12b_cpub_clk_trace,
-	&sm1_gp1_pll_dco,
-	&sm1_gp1_pll,
-	&sm1_dsu_clk_premux0,
-	&sm1_dsu_clk_premux1,
-	&sm1_dsu_clk_mux0_div,
-	&sm1_dsu_clk_postmux0,
-	&sm1_dsu_clk_mux1_div,
-	&sm1_dsu_clk_postmux1,
-	&sm1_dsu_clk_dyn,
-	&sm1_dsu_final_clk,
-	&sm1_dsu_clk,
-	&sm1_cpu1_clk,
-	&sm1_cpu2_clk,
-	&sm1_cpu3_clk,
-	&g12a_spicc0_sclk_sel,
-	&g12a_spicc0_sclk_div,
-	&g12a_spicc0_sclk,
-	&g12a_spicc1_sclk_sel,
-	&g12a_spicc1_sclk_div,
-	&g12a_spicc1_sclk,
-	&sm1_nna_axi_clk_sel,
-	&sm1_nna_axi_clk_div,
-	&sm1_nna_axi_clk,
-	&sm1_nna_core_clk_sel,
-	&sm1_nna_core_clk_div,
-	&sm1_nna_core_clk,
-	&g12a_mipi_dsi_pxclk_sel,
-	&g12a_mipi_dsi_pxclk_div,
-	&g12a_mipi_dsi_pxclk,
-	&g12b_mipi_isp_sel,
-	&g12b_mipi_isp_div,
-	&g12b_mipi_isp,
-	&g12b_mipi_isp_gate,
-	&g12b_csi_phy1,
-	&g12b_csi_phy0,
-};
-
 static const struct reg_sequence g12a_init_regs[] = {
 	{ .reg = HHI_MPLL_CNTL0,	.def = 0x00000543 },
 };
@@ -5558,8 +5303,6 @@ static int meson_g12a_probe(struct platform_device *pdev)
 
 static const struct meson_g12a_data g12a_clkc_data = {
 	.eeclkc_data = {
-		.regmap_clks = g12a_clk_regmaps,
-		.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
 		.hw_clks = {
 			.hws = g12a_hw_clks,
 			.num = ARRAY_SIZE(g12a_hw_clks),
@@ -5572,8 +5315,6 @@ static const struct meson_g12a_data g12a_clkc_data = {
 
 static const struct meson_g12a_data g12b_clkc_data = {
 	.eeclkc_data = {
-		.regmap_clks = g12a_clk_regmaps,
-		.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
 		.hw_clks = {
 			.hws = g12b_hw_clks,
 			.num = ARRAY_SIZE(g12b_hw_clks),
@@ -5584,8 +5325,6 @@ static const struct meson_g12a_data g12b_clkc_data = {
 
 static const struct meson_g12a_data sm1_clkc_data = {
 	.eeclkc_data = {
-		.regmap_clks = g12a_clk_regmaps,
-		.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
 		.hw_clks = {
 			.hws = sm1_hw_clks,
 			.num = ARRAY_SIZE(sm1_hw_clks),
diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c
index 83b034157b3534dd157c6cc2b0ae5ba320197400..30fb57c2d849fdf4958ec444932539c7166b83c1 100644
--- a/drivers/clk/meson/gxbb-aoclk.c
+++ b/drivers/clk/meson/gxbb-aoclk.c
@@ -237,23 +237,6 @@ static const unsigned int gxbb_aoclk_reset[] = {
 	[RESET_AO_IR_BLASTER] = 23,
 };
 
-static struct clk_regmap *gxbb_aoclk[] = {
-	&remote_ao,
-	&i2c_master_ao,
-	&i2c_slave_ao,
-	&uart1_ao,
-	&uart2_ao,
-	&ir_blaster_ao,
-	&ao_cts_oscin,
-	&ao_32k_pre,
-	&ao_32k_div,
-	&ao_32k_sel,
-	&ao_32k,
-	&ao_cts_rtc_oscin,
-	&ao_clk81,
-	&ao_cts_cec,
-};
-
 static struct clk_hw *gxbb_aoclk_hw_clks[] = {
 		[CLKID_AO_REMOTE] = &remote_ao.hw,
 		[CLKID_AO_I2C_MASTER] = &i2c_master_ao.hw,
@@ -275,8 +258,6 @@ static const struct meson_aoclk_data gxbb_aoclkc_data = {
 	.reset_reg	= AO_RTI_GEN_CNTL_REG0,
 	.num_reset	= ARRAY_SIZE(gxbb_aoclk_reset),
 	.reset		= gxbb_aoclk_reset,
-	.num_clks	= ARRAY_SIZE(gxbb_aoclk),
-	.clks		= gxbb_aoclk,
 	.hw_clks	= {
 		.hws	= gxbb_aoclk_hw_clks,
 		.num	= ARRAY_SIZE(gxbb_aoclk_hw_clks),
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 262c318edbd512239b79e5ad26643ae6c7b0173b..79b6cda95df773747140aefa3565bf6603298308 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -3140,398 +3140,7 @@ static struct clk_hw *gxl_hw_clks[] = {
 	[CLKID_ACODEC]		    = &gxl_acodec.hw,
 };
 
-static struct clk_regmap *const gxbb_clk_regmaps[] = {
-	&gxbb_clk81,
-	&gxbb_ddr,
-	&gxbb_dos,
-	&gxbb_isa,
-	&gxbb_pl301,
-	&gxbb_periphs,
-	&gxbb_spicc,
-	&gxbb_i2c,
-	&gxbb_sar_adc,
-	&gxbb_smart_card,
-	&gxbb_rng0,
-	&gxbb_uart0,
-	&gxbb_sdhc,
-	&gxbb_stream,
-	&gxbb_async_fifo,
-	&gxbb_sdio,
-	&gxbb_abuf,
-	&gxbb_hiu_iface,
-	&gxbb_assist_misc,
-	&gxbb_spi,
-	&gxbb_i2s_spdif,
-	&gxbb_eth,
-	&gxbb_demux,
-	&gxbb_aiu_glue,
-	&gxbb_iec958,
-	&gxbb_i2s_out,
-	&gxbb_amclk,
-	&gxbb_aififo2,
-	&gxbb_mixer,
-	&gxbb_mixer_iface,
-	&gxbb_adc,
-	&gxbb_blkmv,
-	&gxbb_aiu,
-	&gxbb_uart1,
-	&gxbb_g2d,
-	&gxbb_usb0,
-	&gxbb_usb1,
-	&gxbb_reset,
-	&gxbb_nand,
-	&gxbb_dos_parser,
-	&gxbb_usb,
-	&gxbb_vdin1,
-	&gxbb_ahb_arb0,
-	&gxbb_efuse,
-	&gxbb_boot_rom,
-	&gxbb_ahb_data_bus,
-	&gxbb_ahb_ctrl_bus,
-	&gxbb_hdmi_intr_sync,
-	&gxbb_hdmi_pclk,
-	&gxbb_usb1_ddr_bridge,
-	&gxbb_usb0_ddr_bridge,
-	&gxbb_mmc_pclk,
-	&gxbb_dvin,
-	&gxbb_uart2,
-	&gxbb_sana,
-	&gxbb_vpu_intr,
-	&gxbb_sec_ahb_ahb3_bridge,
-	&gxbb_clk81_a53,
-	&gxbb_vclk2_venci0,
-	&gxbb_vclk2_venci1,
-	&gxbb_vclk2_vencp0,
-	&gxbb_vclk2_vencp1,
-	&gxbb_gclk_venci_int0,
-	&gxbb_gclk_vencp_int,
-	&gxbb_dac_clk,
-	&gxbb_aoclk_gate,
-	&gxbb_iec958_gate,
-	&gxbb_enc480p,
-	&gxbb_rng1,
-	&gxbb_gclk_venci_int1,
-	&gxbb_vclk2_venclmcc,
-	&gxbb_vclk2_vencl,
-	&gxbb_vclk_other,
-	&gxbb_edp,
-	&gxbb_ao_media_cpu,
-	&gxbb_ao_ahb_sram,
-	&gxbb_ao_ahb_bus,
-	&gxbb_ao_iface,
-	&gxbb_ao_i2c,
-	&gxbb_emmc_a,
-	&gxbb_emmc_b,
-	&gxbb_emmc_c,
-	&gxbb_sar_adc_clk,
-	&gxbb_mali_0,
-	&gxbb_mali_1,
-	&gxbb_cts_amclk,
-	&gxbb_cts_mclk_i958,
-	&gxbb_32k_clk,
-	&gxbb_sd_emmc_a_clk0,
-	&gxbb_sd_emmc_b_clk0,
-	&gxbb_sd_emmc_c_clk0,
-	&gxbb_vpu_0,
-	&gxbb_vpu_1,
-	&gxbb_vapb_0,
-	&gxbb_vapb_1,
-	&gxbb_vapb,
-	&gxbb_mpeg_clk_div,
-	&gxbb_sar_adc_clk_div,
-	&gxbb_mali_0_div,
-	&gxbb_mali_1_div,
-	&gxbb_cts_mclk_i958_div,
-	&gxbb_32k_clk_div,
-	&gxbb_sd_emmc_a_clk0_div,
-	&gxbb_sd_emmc_b_clk0_div,
-	&gxbb_sd_emmc_c_clk0_div,
-	&gxbb_vpu_0_div,
-	&gxbb_vpu_1_div,
-	&gxbb_vapb_0_div,
-	&gxbb_vapb_1_div,
-	&gxbb_mpeg_clk_sel,
-	&gxbb_sar_adc_clk_sel,
-	&gxbb_mali_0_sel,
-	&gxbb_mali_1_sel,
-	&gxbb_mali,
-	&gxbb_cts_amclk_sel,
-	&gxbb_cts_mclk_i958_sel,
-	&gxbb_cts_i958,
-	&gxbb_32k_clk_sel,
-	&gxbb_sd_emmc_a_clk0_sel,
-	&gxbb_sd_emmc_b_clk0_sel,
-	&gxbb_sd_emmc_c_clk0_sel,
-	&gxbb_vpu_0_sel,
-	&gxbb_vpu_1_sel,
-	&gxbb_vpu,
-	&gxbb_vapb_0_sel,
-	&gxbb_vapb_1_sel,
-	&gxbb_vapb_sel,
-	&gxbb_mpll0,
-	&gxbb_mpll1,
-	&gxbb_mpll2,
-	&gxbb_mpll0_div,
-	&gxbb_mpll1_div,
-	&gxbb_mpll2_div,
-	&gxbb_cts_amclk_div,
-	&gxbb_fixed_pll,
-	&gxbb_sys_pll,
-	&gxbb_mpll_prediv,
-	&gxbb_fclk_div2,
-	&gxbb_fclk_div3,
-	&gxbb_fclk_div4,
-	&gxbb_fclk_div5,
-	&gxbb_fclk_div7,
-	&gxbb_vdec_1_sel,
-	&gxbb_vdec_1_div,
-	&gxbb_vdec_1,
-	&gxbb_vdec_hevc_sel,
-	&gxbb_vdec_hevc_div,
-	&gxbb_vdec_hevc,
-	&gxbb_gen_clk_sel,
-	&gxbb_gen_clk_div,
-	&gxbb_gen_clk,
-	&gxbb_fixed_pll_dco,
-	&gxbb_sys_pll_dco,
-	&gxbb_gp0_pll,
-	&gxbb_vid_pll,
-	&gxbb_vid_pll_sel,
-	&gxbb_vid_pll_div,
-	&gxbb_vclk,
-	&gxbb_vclk_sel,
-	&gxbb_vclk_div,
-	&gxbb_vclk_input,
-	&gxbb_vclk_div1,
-	&gxbb_vclk_div2_en,
-	&gxbb_vclk_div4_en,
-	&gxbb_vclk_div6_en,
-	&gxbb_vclk_div12_en,
-	&gxbb_vclk2,
-	&gxbb_vclk2_sel,
-	&gxbb_vclk2_div,
-	&gxbb_vclk2_input,
-	&gxbb_vclk2_div1,
-	&gxbb_vclk2_div2_en,
-	&gxbb_vclk2_div4_en,
-	&gxbb_vclk2_div6_en,
-	&gxbb_vclk2_div12_en,
-	&gxbb_cts_enci,
-	&gxbb_cts_enci_sel,
-	&gxbb_cts_encp,
-	&gxbb_cts_encp_sel,
-	&gxbb_cts_vdac,
-	&gxbb_cts_vdac_sel,
-	&gxbb_hdmi_tx,
-	&gxbb_hdmi_tx_sel,
-	&gxbb_hdmi_sel,
-	&gxbb_hdmi_div,
-	&gxbb_hdmi,
-	&gxbb_gp0_pll_dco,
-	&gxbb_hdmi_pll,
-	&gxbb_hdmi_pll_od,
-	&gxbb_hdmi_pll_od2,
-	&gxbb_hdmi_pll_dco,
-};
-
-static struct clk_regmap *const gxl_clk_regmaps[] = {
-	&gxbb_clk81,
-	&gxbb_ddr,
-	&gxbb_dos,
-	&gxbb_isa,
-	&gxbb_pl301,
-	&gxbb_periphs,
-	&gxbb_spicc,
-	&gxbb_i2c,
-	&gxbb_sar_adc,
-	&gxbb_smart_card,
-	&gxbb_rng0,
-	&gxbb_uart0,
-	&gxbb_sdhc,
-	&gxbb_stream,
-	&gxbb_async_fifo,
-	&gxbb_sdio,
-	&gxbb_abuf,
-	&gxbb_hiu_iface,
-	&gxbb_assist_misc,
-	&gxbb_spi,
-	&gxbb_i2s_spdif,
-	&gxbb_eth,
-	&gxbb_demux,
-	&gxbb_aiu_glue,
-	&gxbb_iec958,
-	&gxbb_i2s_out,
-	&gxbb_amclk,
-	&gxbb_aififo2,
-	&gxbb_mixer,
-	&gxbb_mixer_iface,
-	&gxbb_adc,
-	&gxbb_blkmv,
-	&gxbb_aiu,
-	&gxbb_uart1,
-	&gxbb_g2d,
-	&gxbb_usb0,
-	&gxbb_usb1,
-	&gxbb_reset,
-	&gxbb_nand,
-	&gxbb_dos_parser,
-	&gxbb_usb,
-	&gxbb_vdin1,
-	&gxbb_ahb_arb0,
-	&gxbb_efuse,
-	&gxbb_boot_rom,
-	&gxbb_ahb_data_bus,
-	&gxbb_ahb_ctrl_bus,
-	&gxbb_hdmi_intr_sync,
-	&gxbb_hdmi_pclk,
-	&gxbb_usb1_ddr_bridge,
-	&gxbb_usb0_ddr_bridge,
-	&gxbb_mmc_pclk,
-	&gxbb_dvin,
-	&gxbb_uart2,
-	&gxbb_sana,
-	&gxbb_vpu_intr,
-	&gxbb_sec_ahb_ahb3_bridge,
-	&gxbb_clk81_a53,
-	&gxbb_vclk2_venci0,
-	&gxbb_vclk2_venci1,
-	&gxbb_vclk2_vencp0,
-	&gxbb_vclk2_vencp1,
-	&gxbb_gclk_venci_int0,
-	&gxbb_gclk_vencp_int,
-	&gxbb_dac_clk,
-	&gxbb_aoclk_gate,
-	&gxbb_iec958_gate,
-	&gxbb_enc480p,
-	&gxbb_rng1,
-	&gxbb_gclk_venci_int1,
-	&gxbb_vclk2_venclmcc,
-	&gxbb_vclk2_vencl,
-	&gxbb_vclk_other,
-	&gxbb_edp,
-	&gxbb_ao_media_cpu,
-	&gxbb_ao_ahb_sram,
-	&gxbb_ao_ahb_bus,
-	&gxbb_ao_iface,
-	&gxbb_ao_i2c,
-	&gxbb_emmc_a,
-	&gxbb_emmc_b,
-	&gxbb_emmc_c,
-	&gxbb_sar_adc_clk,
-	&gxbb_mali_0,
-	&gxbb_mali_1,
-	&gxbb_cts_amclk,
-	&gxbb_cts_mclk_i958,
-	&gxbb_32k_clk,
-	&gxbb_sd_emmc_a_clk0,
-	&gxbb_sd_emmc_b_clk0,
-	&gxbb_sd_emmc_c_clk0,
-	&gxbb_vpu_0,
-	&gxbb_vpu_1,
-	&gxbb_vapb_0,
-	&gxbb_vapb_1,
-	&gxbb_vapb,
-	&gxbb_mpeg_clk_div,
-	&gxbb_sar_adc_clk_div,
-	&gxbb_mali_0_div,
-	&gxbb_mali_1_div,
-	&gxbb_cts_mclk_i958_div,
-	&gxbb_32k_clk_div,
-	&gxbb_sd_emmc_a_clk0_div,
-	&gxbb_sd_emmc_b_clk0_div,
-	&gxbb_sd_emmc_c_clk0_div,
-	&gxbb_vpu_0_div,
-	&gxbb_vpu_1_div,
-	&gxbb_vapb_0_div,
-	&gxbb_vapb_1_div,
-	&gxbb_mpeg_clk_sel,
-	&gxbb_sar_adc_clk_sel,
-	&gxbb_mali_0_sel,
-	&gxbb_mali_1_sel,
-	&gxbb_mali,
-	&gxbb_cts_amclk_sel,
-	&gxbb_cts_mclk_i958_sel,
-	&gxbb_cts_i958,
-	&gxbb_32k_clk_sel,
-	&gxbb_sd_emmc_a_clk0_sel,
-	&gxbb_sd_emmc_b_clk0_sel,
-	&gxbb_sd_emmc_c_clk0_sel,
-	&gxbb_vpu_0_sel,
-	&gxbb_vpu_1_sel,
-	&gxbb_vpu,
-	&gxbb_vapb_0_sel,
-	&gxbb_vapb_1_sel,
-	&gxbb_vapb_sel,
-	&gxbb_mpll0,
-	&gxbb_mpll1,
-	&gxbb_mpll2,
-	&gxl_mpll0_div,
-	&gxbb_mpll1_div,
-	&gxbb_mpll2_div,
-	&gxbb_cts_amclk_div,
-	&gxbb_fixed_pll,
-	&gxbb_sys_pll,
-	&gxbb_mpll_prediv,
-	&gxbb_fclk_div2,
-	&gxbb_fclk_div3,
-	&gxbb_fclk_div4,
-	&gxbb_fclk_div5,
-	&gxbb_fclk_div7,
-	&gxbb_vdec_1_sel,
-	&gxbb_vdec_1_div,
-	&gxbb_vdec_1,
-	&gxbb_vdec_hevc_sel,
-	&gxbb_vdec_hevc_div,
-	&gxbb_vdec_hevc,
-	&gxbb_gen_clk_sel,
-	&gxbb_gen_clk_div,
-	&gxbb_gen_clk,
-	&gxbb_fixed_pll_dco,
-	&gxbb_sys_pll_dco,
-	&gxbb_gp0_pll,
-	&gxbb_vid_pll,
-	&gxbb_vid_pll_sel,
-	&gxbb_vid_pll_div,
-	&gxbb_vclk,
-	&gxbb_vclk_sel,
-	&gxbb_vclk_div,
-	&gxbb_vclk_input,
-	&gxbb_vclk_div1,
-	&gxbb_vclk_div2_en,
-	&gxbb_vclk_div4_en,
-	&gxbb_vclk_div6_en,
-	&gxbb_vclk_div12_en,
-	&gxbb_vclk2,
-	&gxbb_vclk2_sel,
-	&gxbb_vclk2_div,
-	&gxbb_vclk2_input,
-	&gxbb_vclk2_div1,
-	&gxbb_vclk2_div2_en,
-	&gxbb_vclk2_div4_en,
-	&gxbb_vclk2_div6_en,
-	&gxbb_vclk2_div12_en,
-	&gxbb_cts_enci,
-	&gxbb_cts_enci_sel,
-	&gxbb_cts_encp,
-	&gxbb_cts_encp_sel,
-	&gxbb_cts_vdac,
-	&gxbb_cts_vdac_sel,
-	&gxbb_hdmi_tx,
-	&gxbb_hdmi_tx_sel,
-	&gxbb_hdmi_sel,
-	&gxbb_hdmi_div,
-	&gxbb_hdmi,
-	&gxl_gp0_pll_dco,
-	&gxl_hdmi_pll,
-	&gxl_hdmi_pll_od,
-	&gxl_hdmi_pll_od2,
-	&gxl_hdmi_pll_dco,
-	&gxl_acodec,
-};
-
 static const struct meson_eeclkc_data gxbb_clkc_data = {
-	.regmap_clks = gxbb_clk_regmaps,
-	.regmap_clk_num = ARRAY_SIZE(gxbb_clk_regmaps),
 	.hw_clks = {
 		.hws = gxbb_hw_clks,
 		.num = ARRAY_SIZE(gxbb_hw_clks),
@@ -3539,8 +3148,6 @@ static const struct meson_eeclkc_data gxbb_clkc_data = {
 };
 
 static const struct meson_eeclkc_data gxl_clkc_data = {
-	.regmap_clks = gxl_clk_regmaps,
-	.regmap_clk_num = ARRAY_SIZE(gxl_clk_regmaps),
 	.hw_clks = {
 		.hws = gxl_hw_clks,
 		.num = ARRAY_SIZE(gxl_hw_clks),
diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c
index 053940ee8940d7ca785ad89f026071244e247d7f..64ae2aff8736ac71fef1b6eb804f84d687f0b4f3 100644
--- a/drivers/clk/meson/meson-aoclk.c
+++ b/drivers/clk/meson/meson-aoclk.c
@@ -18,6 +18,7 @@
 
 #include <linux/slab.h>
 #include "meson-aoclk.h"
+#include "clk-regmap.h"
 
 static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev,
 			       unsigned long id)
@@ -70,9 +71,9 @@ int meson_aoclkc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	/* Populate regmap */
-	for (clkid = 0; clkid < data->num_clks; clkid++)
-		data->clks[clkid]->map = regmap;
+	ret = clk_regmap_init_regmap(dev, regmap);
+	if (ret)
+		return ret;
 
 	/* Register all clks */
 	for (clkid = 0; clkid < data->hw_clks.num; clkid++) {
diff --git a/drivers/clk/meson/meson-aoclk.h b/drivers/clk/meson/meson-aoclk.h
index 308be3e4814a9477287c5d1df5138142e3fa38f1..ea5fc61308af14c63489b7c72410d9d981d8745b 100644
--- a/drivers/clk/meson/meson-aoclk.h
+++ b/drivers/clk/meson/meson-aoclk.h
@@ -23,8 +23,6 @@ struct meson_aoclk_data {
 	const unsigned int			reset_reg;
 	const int				num_reset;
 	const unsigned int			*reset;
-	const int				num_clks;
-	struct clk_regmap			**clks;
 	struct meson_clk_hw_data		hw_clks;
 };
 
diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c
index 66f79e384fe5118dcbf6b29daf2b20e01fee9934..0475d7def15121e18f6d9f970c244dd0e810ec8d 100644
--- a/drivers/clk/meson/meson-eeclk.c
+++ b/drivers/clk/meson/meson-eeclk.c
@@ -39,9 +39,9 @@ int meson_eeclkc_probe(struct platform_device *pdev)
 	if (data->init_count)
 		regmap_multi_reg_write(map, data->init_regs, data->init_count);
 
-	/* Populate regmap for the regmap backed clocks */
-	for (i = 0; i < data->regmap_clk_num; i++)
-		data->regmap_clks[i]->map = map;
+	ret = clk_regmap_init_regmap(dev, map);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < data->hw_clks.num; i++) {
 		/* array might be sparse */
diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h
index 37a48b75c66051b68730f808f7c01e6397c34231..6a81d67b46b2270315e24eb58042de8c09b37763 100644
--- a/drivers/clk/meson/meson-eeclk.h
+++ b/drivers/clk/meson/meson-eeclk.h
@@ -14,8 +14,6 @@
 struct platform_device;
 
 struct meson_eeclkc_data {
-	struct clk_regmap *const	*regmap_clks;
-	unsigned int			regmap_clk_num;
 	const struct reg_sequence	*init_regs;
 	unsigned int			init_count;
 	struct meson_clk_hw_data	hw_clks;
diff --git a/drivers/clk/meson/meson8-ddr.c b/drivers/clk/meson/meson8-ddr.c
index 4b73ea244b630fb4cfb6525a8cb4848c987a8107..64fe6dcf7d12317ae7e1b190a88bdf4c697b41d7 100644
--- a/drivers/clk/meson/meson8-ddr.c
+++ b/drivers/clk/meson/meson8-ddr.c
@@ -85,11 +85,6 @@ static struct clk_hw_onecell_data meson8_ddr_clk_hw_onecell_data = {
 	.num = 2,
 };
 
-static struct clk_regmap *const meson8_ddr_clk_regmaps[] = {
-	&meson8_ddr_pll_dco,
-	&meson8_ddr_pll,
-};
-
 static const struct regmap_config meson8_ddr_clkc_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 32,
@@ -113,9 +108,9 @@ static int meson8_ddr_clkc_probe(struct platform_device *pdev)
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	/* Populate regmap */
-	for (i = 0; i < ARRAY_SIZE(meson8_ddr_clk_regmaps); i++)
-		meson8_ddr_clk_regmaps[i]->map = regmap;
+	ret = clk_regmap_init_regmap(&pdev->dev, regmap);
+	if (ret)
+		return ret;
 
 	/* Register all clks */
 	for (i = 0; i < meson8_ddr_clk_hw_onecell_data.num; i++) {
diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c
index c930cf0614a0f4250a712dc20ce8e8a0ed812e6d..91c7b10c2b68c626dd1d6164ea855370aae71485 100644
--- a/drivers/clk/meson/s4-peripherals.c
+++ b/drivers/clk/meson/s4-peripherals.c
@@ -3522,231 +3522,6 @@ static struct clk_hw *s4_periphs_hw_clks[] = {
 	[CLKID_HDCP22_SKPCLK]		= &s4_hdcp22_skpclk_gate.hw,
 };
 
-/* Convenience table to populate regmap in .probe */
-static struct clk_regmap *const s4_periphs_clk_regmaps[] = {
-	&s4_rtc_32k_by_oscin_clkin,
-	&s4_rtc_32k_by_oscin_div,
-	&s4_rtc_32k_by_oscin_sel,
-	&s4_rtc_32k_by_oscin,
-	&s4_rtc_clk,
-	&s4_sysclk_b_sel,
-	&s4_sysclk_b_div,
-	&s4_sysclk_b,
-	&s4_sysclk_a_sel,
-	&s4_sysclk_a_div,
-	&s4_sysclk_a,
-	&s4_sys_clk,
-	&s4_ceca_32k_clkin,
-	&s4_ceca_32k_div,
-	&s4_ceca_32k_sel_pre,
-	&s4_ceca_32k_sel,
-	&s4_ceca_32k_clkout,
-	&s4_cecb_32k_clkin,
-	&s4_cecb_32k_div,
-	&s4_cecb_32k_sel_pre,
-	&s4_cecb_32k_sel,
-	&s4_cecb_32k_clkout,
-	&s4_sc_clk_mux,
-	&s4_sc_clk_div,
-	&s4_sc_clk_gate,
-	&s4_12_24M_clk_gate,
-	&s4_12_24M_clk,
-	&s4_vid_pll_div,
-	&s4_vid_pll_sel,
-	&s4_vid_pll,
-	&s4_vclk_sel,
-	&s4_vclk2_sel,
-	&s4_vclk_input,
-	&s4_vclk2_input,
-	&s4_vclk_div,
-	&s4_vclk2_div,
-	&s4_vclk,
-	&s4_vclk2,
-	&s4_vclk_div1,
-	&s4_vclk_div2_en,
-	&s4_vclk_div4_en,
-	&s4_vclk_div6_en,
-	&s4_vclk_div12_en,
-	&s4_vclk2_div1,
-	&s4_vclk2_div2_en,
-	&s4_vclk2_div4_en,
-	&s4_vclk2_div6_en,
-	&s4_vclk2_div12_en,
-	&s4_cts_enci_sel,
-	&s4_cts_encp_sel,
-	&s4_cts_vdac_sel,
-	&s4_hdmi_tx_sel,
-	&s4_cts_enci,
-	&s4_cts_encp,
-	&s4_cts_vdac,
-	&s4_hdmi_tx,
-	&s4_hdmi_sel,
-	&s4_hdmi_div,
-	&s4_hdmi,
-	&s4_ts_clk_div,
-	&s4_ts_clk_gate,
-	&s4_mali_0_sel,
-	&s4_mali_0_div,
-	&s4_mali_0,
-	&s4_mali_1_sel,
-	&s4_mali_1_div,
-	&s4_mali_1,
-	&s4_mali_mux,
-	&s4_vdec_p0_mux,
-	&s4_vdec_p0_div,
-	&s4_vdec_p0,
-	&s4_vdec_p1_mux,
-	&s4_vdec_p1_div,
-	&s4_vdec_p1,
-	&s4_vdec_mux,
-	&s4_hevcf_p0_mux,
-	&s4_hevcf_p0_div,
-	&s4_hevcf_p0,
-	&s4_hevcf_p1_mux,
-	&s4_hevcf_p1_div,
-	&s4_hevcf_p1,
-	&s4_hevcf_mux,
-	&s4_vpu_0_sel,
-	&s4_vpu_0_div,
-	&s4_vpu_0,
-	&s4_vpu_1_sel,
-	&s4_vpu_1_div,
-	&s4_vpu_1,
-	&s4_vpu,
-	&s4_vpu_clkb_tmp_mux,
-	&s4_vpu_clkb_tmp_div,
-	&s4_vpu_clkb_tmp,
-	&s4_vpu_clkb_div,
-	&s4_vpu_clkb,
-	&s4_vpu_clkc_p0_mux,
-	&s4_vpu_clkc_p0_div,
-	&s4_vpu_clkc_p0,
-	&s4_vpu_clkc_p1_mux,
-	&s4_vpu_clkc_p1_div,
-	&s4_vpu_clkc_p1,
-	&s4_vpu_clkc_mux,
-	&s4_vapb_0_sel,
-	&s4_vapb_0_div,
-	&s4_vapb_0,
-	&s4_vapb_1_sel,
-	&s4_vapb_1_div,
-	&s4_vapb_1,
-	&s4_vapb,
-	&s4_ge2d_gate,
-	&s4_hdcp22_esmclk_mux,
-	&s4_hdcp22_esmclk_div,
-	&s4_hdcp22_esmclk_gate,
-	&s4_hdcp22_skpclk_mux,
-	&s4_hdcp22_skpclk_div,
-	&s4_hdcp22_skpclk_gate,
-	&s4_vdin_meas_mux,
-	&s4_vdin_meas_div,
-	&s4_vdin_meas_gate,
-	&s4_sd_emmc_c_clk0_sel,
-	&s4_sd_emmc_c_clk0_div,
-	&s4_sd_emmc_c_clk0,
-	&s4_sd_emmc_a_clk0_sel,
-	&s4_sd_emmc_a_clk0_div,
-	&s4_sd_emmc_a_clk0,
-	&s4_sd_emmc_b_clk0_sel,
-	&s4_sd_emmc_b_clk0_div,
-	&s4_sd_emmc_b_clk0,
-	&s4_spicc0_mux,
-	&s4_spicc0_div,
-	&s4_spicc0_gate,
-	&s4_pwm_a_mux,
-	&s4_pwm_a_div,
-	&s4_pwm_a_gate,
-	&s4_pwm_b_mux,
-	&s4_pwm_b_div,
-	&s4_pwm_b_gate,
-	&s4_pwm_c_mux,
-	&s4_pwm_c_div,
-	&s4_pwm_c_gate,
-	&s4_pwm_d_mux,
-	&s4_pwm_d_div,
-	&s4_pwm_d_gate,
-	&s4_pwm_e_mux,
-	&s4_pwm_e_div,
-	&s4_pwm_e_gate,
-	&s4_pwm_f_mux,
-	&s4_pwm_f_div,
-	&s4_pwm_f_gate,
-	&s4_pwm_g_mux,
-	&s4_pwm_g_div,
-	&s4_pwm_g_gate,
-	&s4_pwm_h_mux,
-	&s4_pwm_h_div,
-	&s4_pwm_h_gate,
-	&s4_pwm_i_mux,
-	&s4_pwm_i_div,
-	&s4_pwm_i_gate,
-	&s4_pwm_j_mux,
-	&s4_pwm_j_div,
-	&s4_pwm_j_gate,
-	&s4_saradc_mux,
-	&s4_saradc_div,
-	&s4_saradc_gate,
-	&s4_gen_clk_sel,
-	&s4_gen_clk_div,
-	&s4_gen_clk,
-	&s4_ddr,
-	&s4_dos,
-	&s4_ethphy,
-	&s4_mali,
-	&s4_aocpu,
-	&s4_aucpu,
-	&s4_cec,
-	&s4_sdemmca,
-	&s4_sdemmcb,
-	&s4_nand,
-	&s4_smartcard,
-	&s4_acodec,
-	&s4_spifc,
-	&s4_msr_clk,
-	&s4_ir_ctrl,
-	&s4_audio,
-	&s4_eth,
-	&s4_uart_a,
-	&s4_uart_b,
-	&s4_uart_c,
-	&s4_uart_d,
-	&s4_uart_e,
-	&s4_aififo,
-	&s4_ts_ddr,
-	&s4_ts_pll,
-	&s4_g2d,
-	&s4_spicc0,
-	&s4_usb,
-	&s4_i2c_m_a,
-	&s4_i2c_m_b,
-	&s4_i2c_m_c,
-	&s4_i2c_m_d,
-	&s4_i2c_m_e,
-	&s4_hdmitx_apb,
-	&s4_i2c_s_a,
-	&s4_usb1_to_ddr,
-	&s4_hdcp22,
-	&s4_mmc_apb,
-	&s4_rsa,
-	&s4_cpu_debug,
-	&s4_vpu_intr,
-	&s4_demod,
-	&s4_sar_adc,
-	&s4_gic,
-	&s4_pwm_ab,
-	&s4_pwm_cd,
-	&s4_pwm_ef,
-	&s4_pwm_gh,
-	&s4_pwm_ij,
-	&s4_demod_core_clk_mux,
-	&s4_demod_core_clk_div,
-	&s4_demod_core_clk_gate,
-	&s4_adc_extclk_in_mux,
-	&s4_adc_extclk_in_div,
-	&s4_adc_extclk_in_gate,
-};
-
 static const struct regmap_config clkc_regmap_config = {
 	.reg_bits       = 32,
 	.val_bits       = 32,
@@ -3776,9 +3551,9 @@ static int meson_s4_periphs_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(regmap),
 				     "can't init regmap mmio region\n");
 
-	/* Populate regmap for the regmap backed clocks */
-	for (i = 0; i < ARRAY_SIZE(s4_periphs_clk_regmaps); i++)
-		s4_periphs_clk_regmaps[i]->map = regmap;
+	ret = clk_regmap_init_regmap(dev, regmap);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < s4_periphs_clks.num; i++) {
 		/* array might be sparse */
diff --git a/drivers/clk/meson/s4-pll.c b/drivers/clk/meson/s4-pll.c
index d8e621e794281a14cdbc90e1990f677a087771ef..69581d7f154785321c6bd9abf8064d45332e6cea 100644
--- a/drivers/clk/meson/s4-pll.c
+++ b/drivers/clk/meson/s4-pll.c
@@ -767,33 +767,6 @@ static struct clk_hw *s4_pll_hw_clks[] = {
 	[CLKID_MPLL3]			= &s4_mpll3.hw,
 };
 
-static struct clk_regmap *const s4_pll_clk_regmaps[] = {
-	&s4_fixed_pll_dco,
-	&s4_fixed_pll,
-	&s4_fclk_div2,
-	&s4_fclk_div3,
-	&s4_fclk_div4,
-	&s4_fclk_div5,
-	&s4_fclk_div7,
-	&s4_fclk_div2p5,
-	&s4_gp0_pll_dco,
-	&s4_gp0_pll,
-	&s4_hifi_pll_dco,
-	&s4_hifi_pll,
-	&s4_hdmi_pll_dco,
-	&s4_hdmi_pll_od,
-	&s4_hdmi_pll,
-	&s4_mpll_50m,
-	&s4_mpll0_div,
-	&s4_mpll0,
-	&s4_mpll1_div,
-	&s4_mpll1,
-	&s4_mpll2_div,
-	&s4_mpll2,
-	&s4_mpll3_div,
-	&s4_mpll3,
-};
-
 static const struct reg_sequence s4_init_regs[] = {
 	{ .reg = ANACTRL_MPLL_CTRL0,	.def = 0x00000543 },
 };
@@ -832,9 +805,9 @@ static int meson_s4_pll_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, ret,
 				     "Failed to init registers\n");
 
-	/* Populate regmap for the regmap backed clocks */
-	for (i = 0; i < ARRAY_SIZE(s4_pll_clk_regmaps); i++)
-		s4_pll_clk_regmaps[i]->map = regmap;
+	ret = clk_regmap_init_regmap(dev, regmap);
+	if (ret)
+		return ret;
 
 	/* Register clocks */
 	for (i = 0; i < s4_pll_clks.num; i++) {
diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
index ae03b048182f3bbaf4a7e86b605fb4fb37b9cfd5..13536df1760d135cc2d62062e2699ed6842e1e5f 100644
--- a/drivers/clk/meson/sclk-div.c
+++ b/drivers/clk/meson/sclk-div.c
@@ -222,6 +222,11 @@ static int sclk_div_init(struct clk_hw *hw)
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
 	unsigned int val;
+	int ret;
+
+	ret = clk_regmap_init(hw);
+	if (ret)
+		return ret;
 
 	val = meson_parm_read(clk->map, &sclk->div);
 
diff --git a/drivers/clk/meson/vclk.c b/drivers/clk/meson/vclk.c
index 36f637d2d01b5d86bf5d85196643ad9d66c6f19b..bcdec8a444f60838c84eb27c4cdf2b8f8574ce71 100644
--- a/drivers/clk/meson/vclk.c
+++ b/drivers/clk/meson/vclk.c
@@ -45,6 +45,7 @@ static int meson_vclk_gate_is_enabled(struct clk_hw *hw)
 }
 
 const struct clk_ops meson_vclk_gate_ops = {
+	.init = clk_regmap_init,
 	.enable = meson_vclk_gate_enable,
 	.disable = meson_vclk_gate_disable,
 	.is_enabled = meson_vclk_gate_is_enabled,
@@ -127,6 +128,7 @@ static int meson_vclk_div_is_enabled(struct clk_hw *hw)
 }
 
 const struct clk_ops meson_vclk_div_ops = {
+	.init = clk_regmap_init,
 	.recalc_rate = meson_vclk_div_recalc_rate,
 	.determine_rate = meson_vclk_div_determine_rate,
 	.set_rate = meson_vclk_div_set_rate,
diff --git a/drivers/clk/meson/vid-pll-div.c b/drivers/clk/meson/vid-pll-div.c
index 486cf68fc97a0205ee5139056b1eabc6e743ff35..c28d8b150400308df050e500c2aedc14157c1bcf 100644
--- a/drivers/clk/meson/vid-pll-div.c
+++ b/drivers/clk/meson/vid-pll-div.c
@@ -90,6 +90,7 @@ static unsigned long meson_vid_pll_div_recalc_rate(struct clk_hw *hw,
 }
 
 const struct clk_ops meson_vid_pll_div_ro_ops = {
+	.init		= clk_regmap_init,
 	.recalc_rate	= meson_vid_pll_div_recalc_rate,
 };
 EXPORT_SYMBOL_NS_GPL(meson_vid_pll_div_ro_ops, CLK_MESON);

-- 
2.45.2



From andrew at lunn.ch  Fri Dec 20 09:21:23 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 20 Dec 2024 18:21:23 +0100
Subject: [PATCH] arm64: dts: rockchip: ROCK3B: Correct clock rates for
 Ethernet PHYs
In-Reply-To: <20241220163227.1501912-1-alicja.michalska@9elements.com>
References: <20241220163227.1501912-1-alicja.michalska@9elements.com>
Message-ID: <f3c6fd86-1fd8-4540-a4f4-0c6e3a0e2583@lunn.ch>

On Fri, Dec 20, 2024 at 05:32:27PM +0100, Alicja Michalska wrote:
> Built-in ethernet PHYs did not work on mainline kernel:

Builtin, as within the SoC?
> 
> fe010000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
> fe010000.ethernet eth0: __stmmac_open: Cannot attach to PHY

Not being able to find the PHY has nothing to do with RGMII delays.
If the RGMII delays are wrong, packets will not be
received/transmitted, or they will be corrupt and thrown away with
checksum errors. But the PHY will be found and you can attach to it.

So please leave everything to do with RGMII delays alone, at least
until you have a patch which causes the PHY to be found and attached.
It is likely not broken.

> According to the board design, they need to be configured as output with
> static TX/RX delay. This patch sets it accordingly.
> 
> Signed-off-by: Alicja Michalska <alicja.michalska at 9elements.com>
> ---
>  .../boot/dts/rockchip/rk3568-rock-3b.dts      | 68 +++++++++++--------
>  1 file changed, 38 insertions(+), 30 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
> index 3d0c1ccfaa79..5350158302e4 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
> @@ -183,37 +183,65 @@ &cpu3 {
>  &gmac0 {
>  	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
>  	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
> -	clock_in_out = "input";
> -	phy-handle = <&rgmii_phy0>;
> -	phy-mode = "rgmii-id";
> +	assigned-clock-rates = <0>, <125000000>;
> +	clock_in_out = "output";
>  	phy-supply = <&vcc_3v3>;
> +	phy-mode = "rgmii";

This is wrong. RGMII requires a 2ns delay between the data and clock
lines. One way you can achieve this is by having extra long clock
lines on the PCB. If you have that, you use phy-mode rgmii. If there
are not extra long clock lines, you use rgmii-id, which indicates the
MAC/PHY pair need to insert the delays.

Now vendors very frequently get this wrong, monkeys typing Shakespeare
until something works, with no idea why it works, or if it is correct.
Using the wrong phy-mode, combined with wrong tx_delay and rx_delay
settings cancel each other out and it works. But its just "Two wrongs
make a right". We don't want mainline kernel code working like this.

> +	phy-handle = <&rgmii_phy0>;
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&gmac0_miim
>  		     &gmac0_tx_bus2
>  		     &gmac0_rx_bus2
>  		     &gmac0_rgmii_clk
> -		     &gmac0_rgmii_bus
> -		     &gmac0_clkinout>;
> +		     &gmac0_rgmii_bus>;
> +	snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
> +	snps,reset-active-low;
> +	snps,reset-delays-us = <0 20000 100000>;

You are adding this here and removing the equivalent from the PHY
node. Using the PHY node properties is the recommended way to do this,
since it is the same for all PHYs, where as the vendor snps,
properties only work for this device.

So, now you have something that works, slowly undo all the changes,
and find what actually made it work. But you need to undo stuff in
pairs. Remove all the RGMII delay related changes and test. Remove the
reset GPIO changes and test, etc.

	Andrew


From Hermann.Lauer at iwr.uni-heidelberg.de  Fri Dec 20 09:21:34 2024
From: Hermann.Lauer at iwr.uni-heidelberg.de (Hermann Lauer)
Date: Fri, 20 Dec 2024 18:21:34 +0100
Subject: [PATCH v2] ARM: dts: sun8i-r40: remove unused GPIO regulator
In-Reply-To: <e61c927a4dfe909f4ede4a07dffd9dcd762875be.camel@icenowy.me>
References: <20241213195433.GA1568@lemon.iwr.uni-heidelberg.de>
 <20241214011612.4fd9e4bf@minigeek.lan>
 <e61c927a4dfe909f4ede4a07dffd9dcd762875be.camel@icenowy.me>
Message-ID: <20241220172134.GA9899@lemon.iwr.uni-heidelberg.de>

Hi,

On Sat, Dec 14, 2024 at 03:13:23PM +0800, Icenowy Zheng wrote:
> > CC:ing Icenowy, who added the regulator originally, with commit
> > 0ca12c1ee43c ("ARM: sun8i: r40: add 5V regulator for Banana Pi M2
> > Ultra").
...
> > Icenowy: can you clarify what "newer" version this was referring to
> > in
> > that commit message? That commit in itself doesn't seem to do
> > anything,
> > as the regulator isn't referenced, and it's not always-on. It's only
> > later when the USB nodes were added that it got used?
> > So was PH23 really necessary? As Hermann reports, setting PH23 on a
> > v1.1
> > makes it reboot.

diagnosed that futher now: PH23 is indeed powering the USB-Ports. Whats
happens ist that I powered the board through the micro USB port which turned
out to be limited to 900mA in axp221s. So the setting of reg 0x30 is
the real culprit: Setting the two lowest bits in this register allows
unlimited power over micro usb.

In U-Boot:
 i2c dev 0
 i2c mw 34 30 63

Or power the board through the barrel connector.

In all cases the kernel turns on USB-A power and boots.

> I am not sure, the schematics I have here (which says V1.0) have PH23
> as NC... Well, the M2 Berry schematics have PH23 as 5V EN, maybe I
> messed up M2U and M2B when developing?

While V1.0 didn't need the PH23 setup due to nc, V1.1 needs it. Maybe V1.1
was already on the horizon...

Thanks for the insights and your support, guys.

With seasons greetings
  Hermann


From catalin.marinas at arm.com  Fri Dec 20 09:22:17 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 20 Dec 2024 17:22:17 +0000
Subject: [PATCH v3] arm64/signal: Silence sparse warning storing GCSPR_EL0
In-Reply-To: <20241214-arm64-gcs-signal-sparse-v3-1-5e8d18fffc0c@kernel.org>
References: <20241214-arm64-gcs-signal-sparse-v3-1-5e8d18fffc0c@kernel.org>
Message-ID: <173471533453.2414588.7044123053780464753.b4-ty@arm.com>

On Sat, 14 Dec 2024 02:12:06 +0000, Mark Brown wrote:
> We are seeing a sparse warning in gcs_restore_signal():
> 
>   arch/arm64/kernel/signal.c:1054:9: sparse: sparse: cast removes address space '__user' of expression
> 
> when storing the final GCSPR_EL0 value back into the register, caused by
> the fact that write_sysreg_s() casts the value it writes to a u64 which
> sparse sees as discarding the __userness of the pointer.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64/signal: Silence sparse warning storing GCSPR_EL0
      https://git.kernel.org/arm64/c/926e86205897

-- 
Catalin



From andrew at lunn.ch  Fri Dec 20 09:23:27 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 20 Dec 2024 18:23:27 +0100
Subject: [PATCH net-next v5 9/9] dt-bindings: net: sparx5: document RGMII
 delays
In-Reply-To: <20241220-sparx5-lan969x-switch-driver-4-v5-9-fa8ba5dff732@microchip.com>
References: <20241220-sparx5-lan969x-switch-driver-4-v5-0-fa8ba5dff732@microchip.com>
 <20241220-sparx5-lan969x-switch-driver-4-v5-9-fa8ba5dff732@microchip.com>
Message-ID: <cb42f0d7-d2fd-460b-9f38-3b9ebfec7607@lunn.ch>

On Fri, Dec 20, 2024 at 02:48:48PM +0100, Daniel Machon wrote:
> The lan969x switch device supports two RGMII port interfaces that can be
> configured for MAC level rx and tx delays. Document two new properties
> {rx,tx}-internal-delay-ps in the bindings, used to select these delays.
> 
> Tested-by: Robert Marko <robert.marko at sartura.hr>
> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> Signed-off-by: Daniel Machon <daniel.machon at microchip.com>

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

    Andrew


From srinivas.kandagatla at linaro.org  Fri Dec 20 09:27:36 2024
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Fri, 20 Dec 2024 17:27:36 +0000
Subject: (subset) [PATCH 00/35] Reorganize kerneldoc parameter names
In-Reply-To: <20240930112121.95324-1-Julia.Lawall@inria.fr>
References: <20240930112121.95324-1-Julia.Lawall@inria.fr>
Message-ID: <173471565665.227782.7244101246430956449.b4-ty@linaro.org>


On Mon, 30 Sep 2024 13:20:46 +0200, Julia Lawall wrote:
> Reorganize kerneldoc parameter names to match the parameter
> order in the function header.
> 
> The misordered cases were identified using the following
> Coccinelle semantic patch:
> 
> // <smpl>
> @initialize:ocaml@
> @@
> 
> [...]

Applied, thanks!

[31/35] slimbus: messaging: Reorganize kerneldoc parameter names
        commit: 52d3d7f7a77ee9afc6a846b415790e13e1434847

Best regards,
-- 
Srinivas Kandagatla <srinivas.kandagatla at linaro.org>



From alicja.michalska at 9elements.com  Fri Dec 20 09:29:42 2024
From: alicja.michalska at 9elements.com (Alicja Michalska)
Date: Fri, 20 Dec 2024 18:29:42 +0100
Subject: [PATCH] arm64: dts: rockchip: ROCK3B: Correct clock rates for
 Ethernet PHYs
In-Reply-To: <17251add-40b7-4d18-8626-2d74b29532fc@kwiboo.se>
References: <20241220163227.1501912-1-alicja.michalska@9elements.com>
 <17251add-40b7-4d18-8626-2d74b29532fc@kwiboo.se>
Message-ID: <9a210e3d-90eb-42d4-83fd-7bbad7b00e86@9elements.com>

Hello Jonas,


On 20/12/2024 18:09, Jonas Karlman wrote:
> Have you used mainline or vendor u-boot when testing?
>
> There is an existing issue with RTL8211F PHYs that they must be reset
> before Linux can identify them, see [1] for more details on the issue.
>
> Mainline U-Boot will reset the Ethernet PHYs on this board and that
> should allow for Linux to identify and use the Ethernet PHYs.
>
> [1] https://lore.kernel.org/r/47d55aca-bee6-810f-379f-9431649fefa6 at kwiboo.se/

Thank you for the link. I've tested with vendor-provided U-Boot build:

U-Boot latest-2023.10-11-cc60ff40-gcc60ff40 (Aug 14 2024 - 03:56:35 +0000)

I can test with upstream in upcoming days.

> The snps,reset props is deprecated and reset- props should be used in
> the PHY node.
>
> This also changes to use 20/100 ms delay instead of current 20/50ms
> delay. If anything it could be changed to 20/80ms, I have only seen
> datasheets for rtl8211f mention minimum 10 ms and minimum 30-76 ms.
>
>> +
>> +	tx_delay = <0x36>;
>> +	rx_delay = <0x2d>;
> Are you having issue with use of rgmii-id on your board?

Interesting insight, thank you!

I have to admit that I haven't read the current documentation, just seen that other RK356X boards in the tree used it. My apologies.

I've ran into issues with rgmii-id, but that's with vendor U-Boot (as mentioned above), will try with upstream next and see a follow-up if I will still experience issues.

>> +
>>  	status = "okay";
>>  };
>>  
>>  &gmac1 {
>>  	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
>>  	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
>> -	clock_in_out = "input";
>> -	phy-handle = <&rgmii_phy1>;
>> -	phy-mode = "rgmii-id";
>> +	assigned-clock-rates = <0>, <125000000>;
>> +	clock_in_out = "output";
>>  	phy-supply = <&vcc_3v3>;
>> +	phy-mode = "rgmii";
>> +	phy-handle = <&rgmii_phy1>;
>>  	pinctrl-names = "default";
>>  	pinctrl-0 = <&gmac1m1_miim
>>  		     &gmac1m1_tx_bus2
>>  		     &gmac1m1_rx_bus2
>>  		     &gmac1m1_rgmii_clk
>> -		     &gmac1m1_rgmii_bus
>> -		     &gmac1m1_clkinout>;
>> +		     &gmac1m1_rgmii_bus>;
>> +	snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
>> +	snps,reset-active-low;
>> +	snps,reset-delays-us = <0 50000 150000>;
> Same here, but now this is 50/150 ms?
I wasn't sure about those delays, as I've taken them from vendor's sources. They did seem awfully high, though.
>> +
>> +	tx_delay = <0x47>;
>> +	rx_delay = <0x28>;
> Same here, is use of rgmii-id causing issues on your boards?
Answer above :)
>> +
>>  	status = "okay";
>>  };
>>  
>> +&mdio0 {
>> +	rgmii_phy0: ethernet-phy at 0 {
>> +		compatible = "ethernet-phy-ieee802.3-c22";
>> +		reg = <0>;
> The phy addr used for these boards is 0x1.
>
>> +	};
>> +};
>> +
>> +&mdio1 {
>> +	rgmii_phy1: ethernet-phy at 0 {
>> +		compatible = "ethernet-phy-ieee802.3-c22";
>> +		reg = <0>;
> Same here.
Makes sense, other boards in the tree had it configured the same way.
>> +	};
>> +};
> There should be no need to move these nodes, they should already be in
> alphabetical order?
There's no reason to, just thought moving them closer to PHYs would look cleaner and make a bit more sense. It's just a nitpick though.
>> +
>>  &gpu {
>>  	mali-supply = <&vdd_gpu>;
>>  	status = "okay";
>> @@ -512,26 +540,6 @@ &i2s1m0_sdi0
>>  	status = "okay";
>>  };
>>  
>> -&mdio0 {
>> -	rgmii_phy0: ethernet-phy at 1 {
>> -		compatible = "ethernet-phy-ieee802.3-c22";
> If you want to use vendor u-boot you can probably change this to
> "ethernet-phy-id001c.c916".
>
>> -		reg = <1>;
>> -		reset-assert-us = <20000>;
>> -		reset-deassert-us = <50000>;
>> -		reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
>> -	};
>> -};
>> -
>> -&mdio1 {
>> -	rgmii_phy1: ethernet-phy at 1 {
>> -		compatible = "ethernet-phy-ieee802.3-c22";
> Same here.

True, but in this case it likely wouldn't be accepted in upstream, right?

I really would prefer devicetrees to be passed to the OS by bootloader, just like ACPI does on x86 and some (i.e Ampere) platforms.

This way we wouldn't need to maintain per-board DTs in the tree, and would keep functionality between kernel versions/BSDs... but one can dream, huh? :)

Thank you,

Alicja



From james.clark at linaro.org  Fri Dec 20 09:32:17 2024
From: james.clark at linaro.org (James Clark)
Date: Fri, 20 Dec 2024 17:32:17 +0000
Subject: [PATCH v8 6/8] KVM: arm64: coresight: Give TRBE enabled state to
 KVM
In-Reply-To: <86ttayp9n9.wl-maz@kernel.org>
References: <20241127100130.1162639-1-james.clark@linaro.org>
 <20241127100130.1162639-7-james.clark@linaro.org>
 <86ttayp9n9.wl-maz@kernel.org>
Message-ID: <e6b46080-b9ae-4aad-b06d-81407c195e28@linaro.org>



On 20/12/2024 5:05 pm, Marc Zyngier wrote:
> On Wed, 27 Nov 2024 10:01:23 +0000,
> James Clark <james.clark at linaro.org> wrote:
>>
>> Currently in nVHE, KVM has to check if TRBE is enabled on every guest
>> switch even if it was never used. Because it's a debug feature and is
>> more likely to not be used than used, give KVM the TRBE buffer status to
>> allow a much simpler and faster do-nothing path in the hyp.
>>
>> This is always called with preemption disabled except for probe/hotplug
>> which gets wrapped with preempt_disable().
>>
>> Protected mode disables trace regardless of TRBE (because
>> guest_trfcr_el1 is always 0), which was not previously done. HAS_TRBE
>> becomes redundant, but HAS_TRF is now required for this.
>>
>> Signed-off-by: James Clark <james.clark at linaro.org>
>> ---
>>   arch/arm64/include/asm/kvm_host.h            | 10 +++-
>>   arch/arm64/kvm/debug.c                       | 25 ++++++++--
>>   arch/arm64/kvm/hyp/nvhe/debug-sr.c           | 51 +++++++++++---------
>>   drivers/hwtracing/coresight/coresight-trbe.c |  5 ++
>>   4 files changed, 65 insertions(+), 26 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index 7e3478386351..ba251caa593b 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -611,7 +611,8 @@ struct cpu_sve_state {
>>    */
>>   struct kvm_host_data {
>>   #define KVM_HOST_DATA_FLAG_HAS_SPE	0
>> -#define KVM_HOST_DATA_FLAG_HAS_TRBE	1
>> +#define KVM_HOST_DATA_FLAG_HAS_TRF	1
>> +#define KVM_HOST_DATA_FLAG_TRBE_ENABLED	2
>>   	unsigned long flags;
>>   
>>   	struct kvm_cpu_context host_ctxt;
>> @@ -657,6 +658,9 @@ struct kvm_host_data {
>>   		u64 mdcr_el2;
>>   	} host_debug_state;
>>   
>> +	/* Guest trace filter value */
>> +	u64 guest_trfcr_el1;
> 
> Guest value? Or host state while running the guest? If the former,
> then this has nothing to do here. If the latter, this should be
> spelled out (trfcr_in_guest?), and the comment amended.
> 
>> +
>>   	/* Number of programmable event counters (PMCR_EL0.N) for this CPU */
>>   	unsigned int nr_event_counters;
>>   };
>> @@ -1381,6 +1385,8 @@ static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr)
>>   void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
>>   void kvm_clr_pmu_events(u64 clr);
>>   bool kvm_set_pmuserenr(u64 val);
>> +void kvm_enable_trbe(void);
>> +void kvm_disable_trbe(void);
>>   #else
>>   static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {}
>>   static inline void kvm_clr_pmu_events(u64 clr) {}
>> @@ -1388,6 +1394,8 @@ static inline bool kvm_set_pmuserenr(u64 val)
>>   {
>>   	return false;
>>   }
>> +static inline void kvm_enable_trbe(void) {}
>> +static inline void kvm_disable_trbe(void) {}
>>   #endif
>>   
>>   void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
>> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
>> index dd9e139dfd13..0c340ae7b5d1 100644
>> --- a/arch/arm64/kvm/debug.c
>> +++ b/arch/arm64/kvm/debug.c
>> @@ -314,7 +314,26 @@ void kvm_init_host_debug_data(void)
>>   	    !(read_sysreg_s(SYS_PMBIDR_EL1) & PMBIDR_EL1_P))
>>   		host_data_set_flag(HAS_SPE);
>>   
>> -	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
>> -	    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
>> -		host_data_set_flag(HAS_TRBE);
>> +	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceFilt_SHIFT))
>> +		host_data_set_flag(HAS_TRF);
>>   }
>> +
>> +void kvm_enable_trbe(void)
>> +{
>> +	if (has_vhe() || is_protected_kvm_enabled() ||
>> +	    WARN_ON_ONCE(preemptible()))
>> +		return;
>> +
>> +	host_data_set_flag(TRBE_ENABLED);
>> +}
>> +EXPORT_SYMBOL_GPL(kvm_enable_trbe);
>> +
>> +void kvm_disable_trbe(void)
>> +{
>> +	if (has_vhe() || is_protected_kvm_enabled() ||
>> +	    WARN_ON_ONCE(preemptible()))
>> +		return;
>> +
>> +	host_data_clear_flag(TRBE_ENABLED);
>> +}
>> +EXPORT_SYMBOL_GPL(kvm_disable_trbe);
>> diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
>> index 858bb38e273f..9479bee41801 100644
>> --- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
>> +++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
>> @@ -51,32 +51,39 @@ static void __debug_restore_spe(u64 pmscr_el1)
>>   	write_sysreg_el1(pmscr_el1, SYS_PMSCR);
>>   }
>>   
>> -static void __debug_save_trace(u64 *trfcr_el1)
>> +static void __trace_do_switch(u64 *saved_trfcr, u64 new_trfcr)
>>   {
>> -	*trfcr_el1 = 0;
>> +	*saved_trfcr = read_sysreg_el1(SYS_TRFCR);
>> +	write_sysreg_el1(new_trfcr, SYS_TRFCR);
>>   
>> -	/* Check if the TRBE is enabled */
>> -	if (!(read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E))
>> +	/* No need to drain if going to an enabled state or from disabled state */
>> +	if (new_trfcr || !*saved_trfcr)
> 
> What if TRFCR_EL1.TS is set to something non-zero? I'd rather you
> check for the E*TRE bits instead of assuming things.
> 

Yeah it's probably better that way. TS is actually always set when any 
tracing session starts and then never cleared, so doing it the simpler 
way made it always flush even after tracing finished, which probably 
wasn't great.

>>   		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_el1(SYS_TRFCR);
>> -	write_sysreg_el1(0, SYS_TRFCR);
>> +
>>   	isb();
>> -	/* Drain the trace buffer to memory */
>>   	tsb_csync();
>>   }
>>   
>> -static void __debug_restore_trace(u64 trfcr_el1)
>> +static bool __trace_needs_switch(void)
>>   {
>> -	if (!trfcr_el1)
>> -		return;
>> +	return host_data_test_flag(TRBE_ENABLED) ||
>> +	       (is_protected_kvm_enabled() && host_data_test_flag(HAS_TRF));
>> +}
>>   
>> -	/* Restore trace filter controls */
>> -	write_sysreg_el1(trfcr_el1, SYS_TRFCR);
>> +static void __trace_switch_to_guest(void)
>> +{
>> +	/* Unsupported with TRBE so disable */
>> +	if (host_data_test_flag(TRBE_ENABLED))
>> +		*host_data_ptr(guest_trfcr_el1) = 0;
>> +
>> +	__trace_do_switch(host_data_ptr(host_debug_state.trfcr_el1),
>> +			  *host_data_ptr(guest_trfcr_el1));
>> +}
>> +
>> +static void __trace_switch_to_host(void)
>> +{
>> +	__trace_do_switch(host_data_ptr(guest_trfcr_el1),
>> +			  *host_data_ptr(host_debug_state.trfcr_el1));
>>   }
>>   
>>   void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
>> @@ -84,9 +91,9 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
>>   	/* Disable and flush SPE data generation */
>>   	if (host_data_test_flag(HAS_SPE))
>>   		__debug_save_spe(host_data_ptr(host_debug_state.pmscr_el1));
>> -	/* Disable and flush Self-Hosted Trace generation */
>> -	if (host_data_test_flag(HAS_TRBE))
>> -		__debug_save_trace(host_data_ptr(host_debug_state.trfcr_el1));
>> +
>> +	if (__trace_needs_switch())
>> +		__trace_switch_to_guest();
>>   }
>>   
>>   void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
>> @@ -98,8 +105,8 @@ void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
>>   {
>>   	if (host_data_test_flag(HAS_SPE))
>>   		__debug_restore_spe(*host_data_ptr(host_debug_state.pmscr_el1));
>> -	if (host_data_test_flag(HAS_TRBE))
>> -		__debug_restore_trace(*host_data_ptr(host_debug_state.trfcr_el1));
>> +	if (__trace_needs_switch())
>> +		__trace_switch_to_host();
>>   }
>>   
>>   void __debug_switch_to_host(struct kvm_vcpu *vcpu)
>> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
>> index 96a32b213669..9c0f8c43e6fe 100644
>> --- a/drivers/hwtracing/coresight/coresight-trbe.c
>> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
>> @@ -18,6 +18,7 @@
>>   #include <asm/barrier.h>
>>   #include <asm/cpufeature.h>
>>   #include <linux/vmalloc.h>
>> +#include <linux/kvm_host.h>
> 
> Ordering of include files.
> 
>>   
>>   #include "coresight-self-hosted-trace.h"
>>   #include "coresight-trbe.h"
>> @@ -221,6 +222,7 @@ static inline void set_trbe_enabled(struct trbe_cpudata *cpudata, u64 trblimitr)
>>   	 */
>>   	trblimitr |= TRBLIMITR_EL1_E;
>>   	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
>> +	kvm_enable_trbe();
>>   
>>   	/* Synchronize the TRBE enable event */
>>   	isb();
>> @@ -239,6 +241,7 @@ static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
>>   	 */
>>   	trblimitr &= ~TRBLIMITR_EL1_E;
>>   	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
>> +	kvm_disable_trbe();
>>   
>>   	if (trbe_needs_drain_after_disable(cpudata))
>>   		trbe_drain_buffer();
>> @@ -253,8 +256,10 @@ static void trbe_drain_and_disable_local(struct trbe_cpudata *cpudata)
>>   
>>   static void trbe_reset_local(struct trbe_cpudata *cpudata)
>>   {
>> +	preempt_disable();
>>   	trbe_drain_and_disable_local(cpudata);
>>   	write_sysreg_s(0, SYS_TRBLIMITR_EL1);
>> +	preempt_enable();
> 
> This looks terribly wrong. If you need to disable preemption here, why
> doesn't the critical section cover all register accesses? Surely you
> don't want to nuke another CPU's context?
> 
> But looking at the calling sites, this makes even less sense. The two
> callers of this thing mess with *per-CPU* interrupts. Dealing with
> per-CPU interrupts in preemptible context is a big no-no (hint: they
> start with a call to smp_processor_id()).
> 
> So what is this supposed to ensure?
> 
> 	M.
> 

These ones are only intended to silence the WARN_ON_ONCE(preemptible()) 
in kvm_enable_trbe() when this is called from boot/hotplug 
(arm_trbe_enable_cpu()). Preemption isn't disabled, but a guest can't 
run at that point either.

The "real" calls to kvm_enable_trbe() _are_ called from an atomic 
context. I think there was a previous review comment about when it was 
safe to call the KVM parts of this change, which is why I added the 
warning making sure it was always called with preemption disabled. But 
actually I could remove the warning and these preempt_disables() and 
replace them with a comment.

Thanks
James



From bigeasy at linutronix.de  Fri Dec 20 09:41:30 2024
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Fri, 20 Dec 2024 18:41:30 +0100
Subject: [PATCH v2 16/28] ARM: module: Use RCU in all users of __module_text_address().
In-Reply-To: <20241220174731.514432-1-bigeasy@linutronix.de>
References: <20241220174731.514432-1-bigeasy@linutronix.de>
Message-ID: <20241220174731.514432-17-bigeasy@linutronix.de>

__module_text_address() can be invoked within a RCU section, there is no
requirement to have preemption disabled.

Replace the preempt_disable() section around __module_text_address()
with RCU.

Cc: Russell King <linux at armlinux.org.uk>
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
---
 arch/arm/kernel/module-plts.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c
index da2ee8d6ef1a7..354ce16d83cb5 100644
--- a/arch/arm/kernel/module-plts.c
+++ b/arch/arm/kernel/module-plts.c
@@ -285,11 +285,9 @@ bool in_module_plt(unsigned long loc)
 	struct module *mod;
 	bool ret;
 
-	preempt_disable();
+	guard(rcu)();
 	mod = __module_text_address(loc);
 	ret = mod && (loc - (u32)mod->arch.core.plt_ent < mod->arch.core.plt_count * PLT_ENT_SIZE ||
 		      loc - (u32)mod->arch.init.plt_ent < mod->arch.init.plt_count * PLT_ENT_SIZE);
-	preempt_enable();
-
 	return ret;
 }
-- 
2.45.2



From bigeasy at linutronix.de  Fri Dec 20 09:41:31 2024
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Fri, 20 Dec 2024 18:41:31 +0100
Subject: [PATCH v2 17/28] arm64: module: Use RCU in all users of __module_text_address().
In-Reply-To: <20241220174731.514432-1-bigeasy@linutronix.de>
References: <20241220174731.514432-1-bigeasy@linutronix.de>
Message-ID: <20241220174731.514432-18-bigeasy@linutronix.de>

__module_text_address() can be invoked within a RCU section, there is no
requirement to have preemption disabled.

Replace the preempt_disable() section around __module_text_address()
with RCU.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Masami Hiramatsu <mhiramat at kernel.org>
Cc: Steven Rostedt <rostedt at goodmis.org>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-trace-kernel at vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
---
 arch/arm64/kernel/ftrace.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
index 245cb419ca24d..2b76939b6304f 100644
--- a/arch/arm64/kernel/ftrace.c
+++ b/arch/arm64/kernel/ftrace.c
@@ -257,14 +257,13 @@ static bool ftrace_find_callable_addr(struct dyn_ftrace *rec,
 	 * dealing with an out-of-range condition, we can assume it
 	 * is due to a module being loaded far away from the kernel.
 	 *
-	 * NOTE: __module_text_address() must be called with preemption
-	 * disabled, but we can rely on ftrace_lock to ensure that 'mod'
+	 * NOTE: __module_text_address() must be called within a RCU read
+	 * section, but we can rely on ftrace_lock to ensure that 'mod'
 	 * retains its validity throughout the remainder of this code.
 	 */
 	if (!mod) {
-		preempt_disable();
+		guard(rcu)();
 		mod = __module_text_address(pc);
-		preempt_enable();
 	}
 
 	if (WARN_ON(!mod))
-- 
2.45.2



From james.morse at arm.com  Fri Dec 20 09:51:21 2024
From: james.morse at arm.com (James Morse)
Date: Fri, 20 Dec 2024 17:51:21 +0000
Subject: [PATCH mpam/v6.10-rc1 RFC 0/4] arm_mpam: Fix several minor issues
In-Reply-To: <20240722040140.515173-1-zengheng4@huawei.com>
References: <20240722040140.515173-1-zengheng4@huawei.com>
Message-ID: <ee78c9e9-ff47-416c-8bb2-55b0a903e13a@arm.com>

Hello!

On 22/07/2024 05:01, Zeng Heng wrote:
> After completing the necessary software adaptation for the local chipset,
> the MPAM function is successfully enabled. After related tests are
> completed, some issues were discovered and here attempt to fix them.
> 
> Hope to get some suggestions for modifications, if I miss any rules should
> be followed, please let me know.

Sorry for the delay following these up - they should all be fixed in the newer
versions of the tree. I've added 'CC' tags to the patches you fixed here.


Thanks,

James


From dave.stevenson at raspberrypi.com  Fri Dec 20 10:11:10 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 18:11:10 +0000
Subject: [PATCH v5 0/3] drm/vc4: Fixup DT and DT binding issues from recent
 patchset
Message-ID: <20241220-dt-bcm2712-fixes-v5-0-cbbf13d2e97a@raspberrypi.com>

I missed the DT errors from the recent patchset[1] (DT patches
in linux-next via Florian, DRM bindings patches on dri-misc-next)
as Rob's bot report got spam filtered, so this is a fixup set.

Largely it was changes to number of interrupts or clocks in the
bindings, so those are now covered.

I've fixed up the missing "interrupt-controller" flags for 2711
and 2712 whilst here.

I can't get my head around what is meant to happen with ranges:
"soc at 107c000000: firmware: 'ranges' is a required property"
The meaning seems obvious.

However if I add it then I get:
"firmware: '#address-cells', '#size-cells', 'dma-ranges', 'ranges' do
not match any of the regexes: 'pinctrl-[0-9]+'
from schema $id: http://devicetree.org/schemas/arm/bcm/raspberrypi,bcm2835-firmware.yaml#

There's obviously some other flag I need to set in the bindings,
but I can't work it out. We have similar errors for all the Pi
platforms for one or more nodes.
Please advise and I'll happily fix them all.

Thanks
  Dave

[1] https://lore.kernel.org/linux-arm-kernel/20241025-drm-vc4-2712-support-v2-0-35efa83c8fc0 at raspberrypi.com/

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
Changes in v5:
- Removed all changes to HDMI bindings for earlier hardware revisions.
- Updated commit text to make it explicit that clock and interrupt names
  are required by the driver for 2712.
- Added clock-names and interrupt-names: false for 2711 and 2835 (the
  existing variants).
- Updated commit text to state clock and interrupt names are required
  by the driver for 2712.
- Link to v4: https://lore.kernel.org/r/20241218-dt-bcm2712-fixes-v4-0-54cc88b6c229 at raspberrypi.com

Changes in v4:
- 1/7 Removed the duplication
- 2/7 Added "minItems: 2" and added to the commit text that the clock
  and interrupt names are required for bcm2712
- 3/7 Already applied by Bartosz, and 5-7/7 applied by Florian
- 4/7 added Krzysztof Acked-by
- Link to v3: https://lore.kernel.org/r/20241212-dt-bcm2712-fixes-v3-0-44a7f3390331 at raspberrypi.com

Thanks Krzysztof for your comments. Terms such as "widest constraints"
may be obvious to those regularly doing dtschemas, but not to me who
does them once in a blue-moon.

Changes in v3:
- Fixed up indentation on 1/7. (I fixed it once, but obviously reworked
  things and lost it).
- Link to v2: https://lore.kernel.org/r/20241212-dt-bcm2712-fixes-v2-0-35986e04d0f4 at raspberrypi.com

Thanks to Stefan and Krzysztof for their reviews.
Hopefully I've addressed all points raised in the correct manner.

Changes in v2:
- Commits have now be merged from drm-misc-next to linux-next, so all
  commit hashes are valid on linux-next.
- 1/7 Removed references to "previous commit". Fixed up indentation.
  Added maxItems
- 2/7 Defined widest constraints
- 3/7 Added maxItems and removed reference to Linux
- 4/7 Described the errors. Split into two for fix of node name vs addr
  being wrong.
- Added new patch removing "required" for interrupt-controller and
  interrupt-cells for bcm2836-l1-intc
- 5/7 (now 7/7) Removed the intc node for 2712 - it's irrelevant on 64bit systems
- 6/7 dropped as updating the binding is the correct answer
- 7/7 dropped. simple-bus claims ranges is required, but adding it
  creates other errors. I'm unclear as to the right solution.

- Link to v1: https://lore.kernel.org/r/20241202-dt-bcm2712-fixes-v1-0-fac67cc2f98a at raspberrypi.com

---
Dave Stevenson (3):
      dt-bindings: display: bcm2711-hdmi: Add interrupt details for BCM2712
      dt-bindings: display: Fix brcm,bcm2835-hvs bindings for BCM2712
      dt-bindings: interrupt-controller: brcm,bcm2836-l1-intc: Drop interrupt-controller requirement

 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 76 +++++++++++++++----
 .../bindings/display/brcm,bcm2835-hvs.yaml         | 88 ++++++++++++++++++----
 .../interrupt-controller/brcm,bcm2836-l1-intc.yaml |  2 -
 3 files changed, 136 insertions(+), 30 deletions(-)
---
base-commit: 29978a81e62128d2cee56f066ec92de584f4ab5f
change-id: 20241128-dt-bcm2712-fixes-afb0e8a0a476

Best regards,
-- 
Dave Stevenson <dave.stevenson at raspberrypi.com>



From dave.stevenson at raspberrypi.com  Fri Dec 20 10:11:11 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 18:11:11 +0000
Subject: [PATCH v5 1/3] dt-bindings: display: bcm2711-hdmi: Add interrupt
 details for BCM2712
In-Reply-To: <20241220-dt-bcm2712-fixes-v5-0-cbbf13d2e97a@raspberrypi.com>
References: <20241220-dt-bcm2712-fixes-v5-0-cbbf13d2e97a@raspberrypi.com>
Message-ID: <20241220-dt-bcm2712-fixes-v5-1-cbbf13d2e97a@raspberrypi.com>

Commit 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
added the compatible strings for BCM2712, but missed out that the
number of interrupts changed, and for BCM2712 the driver changes[1]
required that the interrupts are named.

Update the schema to correct the interrupt requirements for BCM2712.
(Requirements for BCM2711 should be unchanged).

[1] Commit 0b1dbe82e051 ("drm/vc4: hdmi: Add support for BCM2712 HDMI
controllers")

Fixes: 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2711-hdmi.yaml        | 76 ++++++++++++++++++----
 1 file changed, 62 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
index 6d11f5955b51..c1cefd547391 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml
@@ -56,22 +56,12 @@ properties:
       - const: cec
 
   interrupts:
-    items:
-      - description: CEC TX interrupt
-      - description: CEC RX interrupt
-      - description: CEC stuck at low interrupt
-      - description: Wake-up interrupt
-      - description: Hotplug connected interrupt
-      - description: Hotplug removed interrupt
+    minItems: 5
+    maxItems: 6
 
   interrupt-names:
-    items:
-      - const: cec-tx
-      - const: cec-rx
-      - const: cec-low
-      - const: wakeup
-      - const: hpd-connected
-      - const: hpd-removed
+    minItems: 5
+    maxItems: 6
 
   ddc:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -112,6 +102,61 @@ required:
 
 additionalProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - brcm,bcm2711-hdmi0
+              - brcm,bcm2711-hdmi1
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: CEC TX interrupt
+            - description: CEC RX interrupt
+            - description: CEC stuck at low interrupt
+            - description: Wake-up interrupt
+            - description: Hotplug connected interrupt
+            - description: Hotplug removed interrupt
+        interrupt-names:
+          items:
+            - const: cec-tx
+            - const: cec-rx
+            - const: cec-low
+            - const: wakeup
+            - const: hpd-connected
+            - const: hpd-removed
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - brcm,bcm2712-hdmi0
+              - brcm,bcm2712-hdmi1
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: CEC TX interrupt
+            - description: CEC RX interrupt
+            - description: CEC stuck at low interrupt
+            - description: Hotplug connected interrupt
+            - description: Hotplug removed interrupt
+        interrupts-names:
+          items:
+            - const: cec-tx
+            - const: cec-rx
+            - const: cec-low
+            - const: hpd-connected
+            - const: hpd-removed
+
+      required:
+        - interrupts
+        - interrupt-names
+
 examples:
   - |
     hdmi0: hdmi at 7ef00700 {
@@ -136,6 +181,9 @@ examples:
                     "hd";
         clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
         clock-names = "hdmi", "bvb", "audio", "cec";
+        interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
+        interrupt-names = "cec-tx", "cec-rx", "cec-low", "wakeup",
+                          "hpd-connected", "hpd-removed";
         resets = <&dvp 0>;
         ddc = <&ddc0>;
     };

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Fri Dec 20 10:11:12 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 18:11:12 +0000
Subject: [PATCH v5 2/3] dt-bindings: display: Fix brcm,bcm2835-hvs bindings
 for BCM2712
In-Reply-To: <20241220-dt-bcm2712-fixes-v5-0-cbbf13d2e97a@raspberrypi.com>
References: <20241220-dt-bcm2712-fixes-v5-0-cbbf13d2e97a@raspberrypi.com>
Message-ID: <20241220-dt-bcm2712-fixes-v5-2-cbbf13d2e97a@raspberrypi.com>

Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
added the compatible string for BCM2712, but missed out that
the number of interrupts and clocks changed too.

The driver commit adding support for BCM2712 [1] also requires that
both interrupts and clocks are named, so the relevant -names
properties are also added to "required" for BCM2712.

Update to validate clock, interrupts, and their names for the BCM2712
variant. (There should be no change in the binding requirements for
the other variants).

[1] Commit 7687a12153d3 ("drm/vc4: hvs: Add support for BCM2712 HVS")

Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
---
 .../bindings/display/brcm,bcm2835-hvs.yaml         | 88 ++++++++++++++++++----
 1 file changed, 74 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
index f91c9dce2a44..9aca38a58a16 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
@@ -20,11 +20,20 @@ properties:
     maxItems: 1
 
   interrupts:
-    maxItems: 1
+    minItems: 1
+    maxItems: 3
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 3
 
   clocks:
-    maxItems: 1
-    description: Core Clock
+    minItems: 1
+    maxItems: 2
+
+  clock-names:
+    minItems: 1
+    maxItems: 2
 
 required:
   - compatible
@@ -33,17 +42,68 @@ required:
 
 additionalProperties: false
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - brcm,bcm2711-hvs
-          - brcm,bcm2712-hvs
-
-then:
-  required:
-    - clocks
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2711-hvs
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Core Clock
+        interrupts:
+          maxItems: 1
+        clock-names: false
+        interrupt-names: false
+
+      required:
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2712-hvs
+
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: core
+            - const: disp
+        interrupts:
+          items:
+            - description: Channel 0 End of frame
+            - description: Channel 1 End of frame
+            - description: Channel 2 End of frame
+        interrupt-names:
+          items:
+            - const: ch0-eof
+            - const: ch1-eof
+            - const: ch2-eof
+      required:
+        - clocks
+        - clock-names
+        - interrupt-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm2835-hvs
+
+    then:
+      properties:
+        interrupts:
+          maxItems: 1
+        clock-names: false
+        interrupt-names: false
 
 examples:
   - |

-- 
2.34.1



From dave.stevenson at raspberrypi.com  Fri Dec 20 10:11:13 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 18:11:13 +0000
Subject: [PATCH v5 3/3] dt-bindings: interrupt-controller:
 brcm,bcm2836-l1-intc: Drop interrupt-controller requirement
In-Reply-To: <20241220-dt-bcm2712-fixes-v5-0-cbbf13d2e97a@raspberrypi.com>
References: <20241220-dt-bcm2712-fixes-v5-0-cbbf13d2e97a@raspberrypi.com>
Message-ID: <20241220-dt-bcm2712-fixes-v5-3-cbbf13d2e97a@raspberrypi.com>

Since commit 88bbe85dcd37 ("irqchip: bcm2836: Move SMP startup code to
arch/arm (v2)") the bcm2836-l1-intc block on bcm2711 is only used as a
base address for the smp_boot_secondary hook on 32 bit kernels. It is
not used as an interrupt controller.

Drop the binding requirement for interrupt-controller and interrupt-cells
to satisfy validation on this platform.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml  | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
index 5fda626c80ce..2ff390c1705b 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.yaml
@@ -34,8 +34,6 @@ properties:
 required:
   - compatible
   - reg
-  - interrupt-controller
-  - '#interrupt-cells'
 
 additionalProperties: false
 

-- 
2.34.1



From jeremy.linton at arm.com  Fri Dec 20 10:12:35 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri, 20 Dec 2024 12:12:35 -0600
Subject: [PATCH v4 0/1] arm64: CCA TSM module autoloading
Message-ID: <20241220181236.172060-1-jeremy.linton@arm.com>

Provide module tables and a platform device so that the
CCA TSM module will autoload when needed.

v3->v4:
	More comment/function name tweaking

v2->v3:
	Fix __maybe_used placement, it does fix CLANG builds now.
	Add reviewed-by tag, Thanks Gavin!
	Ugly commit message cleanup.
v1->v2:
	Various comment updates/variable renames
	Add missing __maybe_unused to the platform_device_id

Jeremy Linton (1):
  arm64: rsi: Add automatic arm-cca-guest module loading

 arch/arm64/include/asm/rsi.h                    |  2 ++
 arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
 3 files changed, 25 insertions(+)

-- 
2.46.0



From jeremy.linton at arm.com  Fri Dec 20 10:12:36 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri, 20 Dec 2024 12:12:36 -0600
Subject: [PATCH v4 1/1] arm64: rsi: Add automatic arm-cca-guest module loading
In-Reply-To: <20241220181236.172060-1-jeremy.linton@arm.com>
References: <20241220181236.172060-1-jeremy.linton@arm.com>
Message-ID: <20241220181236.172060-2-jeremy.linton@arm.com>

The TSM module provides guest identification and attestation when a
guest runs in CCA realm mode. By creating a dummy platform device,
let's ensure the module is automatically loaded. The udev daemon loads
the TSM module after it receives a device addition event. Once that
happens, it can be used earlier in the boot process to decrypt the
rootfs.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
Reviewed-by: Gavin Shan <gshan at redhat.com>
---
 arch/arm64/include/asm/rsi.h                    |  2 ++
 arch/arm64/kernel/rsi.c                         | 15 +++++++++++++++
 drivers/virt/coco/arm-cca-guest/arm-cca-guest.c |  8 ++++++++
 3 files changed, 25 insertions(+)

diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
index 188cbb9b23f5..b42aeac05340 100644
--- a/arch/arm64/include/asm/rsi.h
+++ b/arch/arm64/include/asm/rsi.h
@@ -10,6 +10,8 @@
 #include <linux/jump_label.h>
 #include <asm/rsi_cmds.h>
 
+#define RSI_PDEV_NAME "arm-cca-dev"
+
 DECLARE_STATIC_KEY_FALSE(rsi_present);
 
 void __init arm64_rsi_init(void);
diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
index 3031f25c32ef..ce4778141ec7 100644
--- a/arch/arm64/kernel/rsi.c
+++ b/arch/arm64/kernel/rsi.c
@@ -8,6 +8,7 @@
 #include <linux/psci.h>
 #include <linux/swiotlb.h>
 #include <linux/cc_platform.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/mem_encrypt.h>
@@ -140,3 +141,17 @@ void __init arm64_rsi_init(void)
 	static_branch_enable(&rsi_present);
 }
 
+static struct platform_device rsi_dev = {
+	.name = RSI_PDEV_NAME,
+	.id = PLATFORM_DEVID_NONE
+};
+
+static int __init arm64_create_dummy_rsi_dev(void)
+{
+	if (is_realm_world() &&
+	    platform_device_register(&rsi_dev))
+		pr_err("failed to register rsi platform device\n");
+	return 0;
+}
+
+arch_initcall(arm64_create_dummy_rsi_dev)
diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
index 488153879ec9..87f162736b2e 100644
--- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
+++ b/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c
@@ -6,6 +6,7 @@
 #include <linux/arm-smccc.h>
 #include <linux/cc_platform.h>
 #include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/tsm.h>
@@ -219,6 +220,13 @@ static void __exit arm_cca_guest_exit(void)
 }
 module_exit(arm_cca_guest_exit);
 
+/* modalias, so userspace can autoload this module when RSI is available */
+static const struct platform_device_id arm_cca_match[] __maybe_unused = {
+	{ RSI_PDEV_NAME, 0},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(platform, arm_cca_match);
 MODULE_AUTHOR("Sami Mujawar <sami.mujawar at arm.com>");
 MODULE_DESCRIPTION("Arm CCA Guest TSM Driver");
 MODULE_LICENSE("GPL");
-- 
2.46.0



From dave.stevenson at raspberrypi.com  Fri Dec 20 10:20:00 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Fri, 20 Dec 2024 18:20:00 +0000
Subject: [PATCH 5/7] media: platform: Add Raspberry Pi HEVC decoder driver
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-0-0ebcc04ed42e@raspberrypi.com> <20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e@raspberrypi.com>
Message-ID: <CAPY8ntD=+FmSRN7k-kr6Vya0huEVKbFLP84w5O7ww3KSHoDACQ@mail.gmail.com>

On Fri, 20 Dec 2024 at 16:21, Dave Stevenson
<dave.stevenson at raspberrypi.com> wrote:
>
> From: John Cox <john.cox at raspberrypi.com>
>
> The BCM2711 and BCM2712 SoCs used on Rapsberry Pi 4 and Raspberry
> Pi 5 boards include an HEVC decoder block. Add a driver for it.
>
> Signed-off-by: John Cox <john.cox at raspberrypi.com>
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  MAINTAINERS                                        |   10 +
>  drivers/media/platform/raspberrypi/Kconfig         |    1 +
>  drivers/media/platform/raspberrypi/Makefile        |    1 +
>  .../media/platform/raspberrypi/hevc_dec/Kconfig    |   17 +
>  .../media/platform/raspberrypi/hevc_dec/Makefile   |    5 +
>  .../media/platform/raspberrypi/hevc_dec/hevc_d.c   |  443 ++++
>  .../media/platform/raspberrypi/hevc_dec/hevc_d.h   |  190 ++
>  .../platform/raspberrypi/hevc_dec/hevc_d_h265.c    | 2629 ++++++++++++++++++++
>  .../platform/raspberrypi/hevc_dec/hevc_d_hw.c      |  376 +++
>  .../platform/raspberrypi/hevc_dec/hevc_d_hw.h      |  303 +++
>  .../platform/raspberrypi/hevc_dec/hevc_d_video.c   |  685 +++++
>  .../platform/raspberrypi/hevc_dec/hevc_d_video.h   |   38 +
>  12 files changed, 4698 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a33a97d5ffff..569b478c44fe 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19567,6 +19567,16 @@ L:     linux-edac at vger.kernel.org
>  S:     Maintained
>  F:     drivers/ras/amd/fmpm.c
>
<snip>

Typical. You read a patch multiple times over, and still miss a "git
add" of a new file

I won't send a new version now as there are bound to be multiple other
things in review, but hevc_d_h265.h should read

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Raspberry Pi HEVC driver
 *
 * Copyright (C) 2024 Raspberry Pi Ltd
 *
 */

#ifndef _HEVC_D_H265_H_
#define _HEVC_D_H265_H_
#include "hevc_d.h"

extern const struct v4l2_ctrl_ops hevc_d_hevc_sps_ctrl_ops;
extern const struct v4l2_ctrl_ops hevc_d_hevc_pps_ctrl_ops;

void hevc_d_h265_setup(struct hevc_d_ctx *ctx, struct hevc_d_run *run);
int hevc_d_h265_start(struct hevc_d_ctx *ctx);
void hevc_d_h265_stop(struct hevc_d_ctx *ctx);
void hevc_d_h265_trigger(struct hevc_d_ctx *ctx);

void hevc_d_device_run(void *priv);

#endif

Thanks
  Dave


From lkp at intel.com  Fri Dec 20 10:26:45 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 02:26:45 +0800
Subject: [PATCH] [v1] spi: spi-mtk-nor: Modify the clock architecture of
 nor controller
In-Reply-To: <20241212092206.14071-1-Cloud.Zhang@mediatek.com>
References: <20241212092206.14071-1-Cloud.Zhang@mediatek.com>
Message-ID: <202412210247.Brq06CHb-lkp@intel.com>

Hi mtk22730,

kernel test robot noticed the following build warnings:

[auto build test WARNING on broonie-spi/for-next]
[also build test WARNING on linus/master v6.13-rc3 next-20241220]
[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/mtk22730/spi-spi-mtk-nor-Modify-the-clock-architecture-of-nor-controller/20241212-172704
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
patch link:    https://lore.kernel.org/r/20241212092206.14071-1-Cloud.Zhang%40mediatek.com
patch subject: [PATCH] [v1] spi: spi-mtk-nor: Modify the clock architecture of nor controller
config: um-randconfig-002-20241220 (https://download.01.org/0day-ci/archive/20241221/202412210247.Brq06CHb-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 9daf10ff8f29ba3a88a105aaa9d2379c21b77d35)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241221/202412210247.Brq06CHb-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/202412210247.Brq06CHb-lkp at intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/spi/spi-mtk-nor.c:10:
   In file included from include/linux/dma-mapping.h:8:
   In file included from include/linux/scatterlist.h:8:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   In file included from drivers/spi/spi-mtk-nor.c:10:
   In file included from include/linux/dma-mapping.h:8:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/um/include/asm/io.h:24:
   include/asm-generic/io.h:549:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     549 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:567:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     567 |         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/spi/spi-mtk-nor.c:10:
   In file included from include/linux/dma-mapping.h:8:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/um/include/asm/io.h:24:
   include/asm-generic/io.h:585:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     585 |         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/spi/spi-mtk-nor.c:10:
   In file included from include/linux/dma-mapping.h:8:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/um/include/asm/io.h:24:
   include/asm-generic/io.h:601:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     601 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:616:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     616 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:631:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     631 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:724:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     724 |         readsb(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:737:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     737 |         readsw(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:750:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     750 |         readsl(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:764:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     764 |         writesb(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:778:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     778 |         writesw(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:792:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     792 |         writesl(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
>> drivers/spi/spi-mtk-nor.c:746:19: warning: result of comparison of constant -22 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
     746 |         if (!cnt || (cnt == -EINVAL)) {
         |                      ~~~ ^  ~~~~~~~
   14 warnings generated.


vim +746 drivers/spi/spi-mtk-nor.c

   737	
   738	static int mtk_nor_parse_clk(struct device *dev, struct mtk_nor *sp)
   739	{
   740		struct device_node *np = dev->of_node;
   741		int ret;
   742		const char *name;
   743		u8 cnt, i;
   744	
   745		cnt = of_property_count_strings(np, "clock-names");
 > 746		if (!cnt || (cnt == -EINVAL)) {
   747			dev_err(dev, "Unable to find clocks\n");
   748			ret = -EINVAL;
   749			goto out;
   750		} else if (cnt < 0) {
   751			dev_err(dev, "Count clock strings failed, err %d\n", cnt);
   752			ret = cnt;
   753			goto out;
   754		} else if (cnt > MAX_CLOCK_CNT) {
   755			ret = -EINVAL;
   756			goto out;
   757		}
   758	
   759		sp->clock_cnt = cnt;
   760	
   761		for (i = 0; i < cnt; i++) {
   762			ret = of_property_read_string_index(np, "clock-names", i,
   763					       &name);
   764			if (ret) {
   765				dev_err(dev, "failed to get clock string\n");
   766				return ret;
   767			}
   768	
   769			sp->clocks[i].name = name;
   770			sp->clocks[i].clki = devm_clk_get(dev, sp->clocks[i].name);
   771			if (IS_ERR(sp->clocks[i].clki)) {
   772				dev_err(dev, "get clock %s fail\n", sp->clocks[i].name);
   773				return PTR_ERR(sp->clocks[i].clki);
   774			}
   775		}
   776	
   777	out:
   778		return ret;
   779	}
   780	

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


From david at redhat.com  Fri Dec 20 10:29:18 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 20 Dec 2024 19:29:18 +0100
Subject: [PATCH v4 10/25] mm/mm_init: Move p2pdma page refcount
 initialisation to p2pdma
In-Reply-To: <bk6cmiubwvor6gevit3wgl4k66xxpfcv6swmfrtvxnjnuojqkx@yow3pmyuxozw>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <aaa23e6f315a2d9b30a422c3769100cdfa42e85a.1734407924.git-series.apopple@nvidia.com>
 <359a1cf2-c5b0-4682-ba3c-980d77c4cfdb@redhat.com>
 <bk6cmiubwvor6gevit3wgl4k66xxpfcv6swmfrtvxnjnuojqkx@yow3pmyuxozw>
Message-ID: <4446a9c9-613b-4303-9a06-686fb10af363@redhat.com>


>>
>>
>> But that's a bit weird: we call __init_single_page()->init_page_count() to
>> initialize it to 1, to then set it back to 0.
>>
>>
>> Maybe we can just pass to __init_single_page() the refcount we want to have
>> directly? Can be a patch on top of course.
> 
> Once the dust settles on this series we won't need the pgmap->type check at
> all because all ZONE_DEVICE pages will get an initial count of 0. I have some
> follow up clean-ups for after this series is applied (particularly with regards
> to pgmap refcounts), so if it's ok I'd rather do this as a follow-up.

Sure. For ordinary memory hotplug I'll also convert it to start with 
refcount=0 soonish, so there we're also simply pass 0 to __init_single_page.

-- 
Cheers,

David / dhildenb



From catalin.marinas at arm.com  Fri Dec 20 10:30:00 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 20 Dec 2024 18:30:00 +0000
Subject: [PATCH v2 1/2] arm64: mm: vmemmap populate to page level if not
 section aligned
In-Reply-To: <20241209094227.1529977-2-quic_zhenhuah@quicinc.com>
References: <20241209094227.1529977-1-quic_zhenhuah@quicinc.com>
 <20241209094227.1529977-2-quic_zhenhuah@quicinc.com>
Message-ID: <Z2W3qA7wbBTaq6DQ@arm.com>

On Mon, Dec 09, 2024 at 05:42:26PM +0800, Zhenhua Huang wrote:
> Commit c1cc1552616d ("arm64: MMU initialisation")
> optimizes the vmemmap to populate at the PMD section level. However, if
> start or end is not aligned to a section boundary, such as when a
> subsection is hot added, populating the entire section is wasteful. For
> instance, if only one subsection hot-added, the entire section's struct
> page metadata will still be populated.In such cases, it is more effective
> to populate at page granularity.

OK, so from the vmemmap perspective, we waste up to 2MB memory that has
been allocated even if a 2MB hot-plugged subsection required only 32KB
of struct page. I don't mind this much really. I hope all those
subsections are not scattered around to amplify this waste.

> This change also addresses mismatch issues during vmemmap_free(): When
> pmd_sect() is true, the entire PMD section is cleared, even if there is
> other effective subsection. For example, pagemap1 and pagemap2 are part
> of a single PMD entry and they are hot-added sequentially. Then pagemap1
> is removed, vmemmap_free() will clear the entire PMD entry, freeing the
> struct page metadata for the whole section, even though pagemap2 is still
> active.

I think that's the bigger issue. We can't unplug a subsection only.
Looking at unmap_hotplug_pmd_range(), it frees a 2MB vmemmap section but
that may hold struct page for the equivalent of 128MB of memory. So any
struct page accesses for the other subsections will fault.

> Fixes: c1cc1552616d ("arm64: MMU initialisation")

I wouldn't add a fix for the first commit adding arm64 support, we did
not even have memory hotplug at the time (added later in 5.7 by commit
bbd6ec605c0f ("arm64/mm: Enable memory hot remove")). IIUC, this hasn't
been a problem until commit ba72b4c8cf60 ("mm/sparsemem: support
sub-section hotplug"). That commit broke some arm64 assumptions.

> Signed-off-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
> ---
>  arch/arm64/mm/mmu.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index e2739b69e11b..fd59ee44960e 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -1177,7 +1177,9 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
>  {
>  	WARN_ON((start < VMEMMAP_START) || (end > VMEMMAP_END));
>  
> -	if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES))
> +	if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) ||
> +	!IS_ALIGNED(page_to_pfn((struct page *)start), PAGES_PER_SECTION) ||
> +	!IS_ALIGNED(page_to_pfn((struct page *)end), PAGES_PER_SECTION))
>  		return vmemmap_populate_basepages(start, end, node, altmap);
>  	else
>  		return vmemmap_populate_hugepages(start, end, node, altmap);

An alternative would be to fix unmap_hotplug_pmd_range() etc. to avoid
nuking the whole vmemmap pmd section if it's not empty. Not sure how
easy that is, whether we have the necessary information (I haven't
looked in detail).

A potential issue - can we hotplug 128MB of RAM and only unplug 2MB? If
that's possible, the problem isn't solved by this patch.

-- 
Catalin


From david at redhat.com  Fri Dec 20 10:31:03 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 20 Dec 2024 19:31:03 +0100
Subject: [PATCH v4 14/25] rmap: Add support for PUD sized mappings to rmap
In-Reply-To: <volhyxjxlbsflldgs36ghzartel2tu625ubz3kfed2gdwrsamt@cpfsfhdpc4rp>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <7f739c9e9f0a25cafb76a482e31e632c8f72102e.1734407924.git-series.apopple@nvidia.com>
 <4b5768b7-96e0-4864-9dbe-88fd1f0e87b8@redhat.com>
 <volhyxjxlbsflldgs36ghzartel2tu625ubz3kfed2gdwrsamt@cpfsfhdpc4rp>
Message-ID: <107dacce-87dc-457b-a2e1-e5a4699d66af@redhat.com>

>>>    				return -EBUSY;
>>> diff --git a/mm/rmap.c b/mm/rmap.c
>>> index c6c4d4e..39d0439 100644
>>> --- a/mm/rmap.c
>>> +++ b/mm/rmap.c
>>> @@ -1203,6 +1203,11 @@ static __always_inline unsigned int __folio_add_rmap(struct folio *folio,
>>>    		}
>>>    		atomic_inc(&folio->_large_mapcount);
>>>    		break;
>>> +	case RMAP_LEVEL_PUD:
>>> +		/* We only support entire mappings of PUD sized folios in rmap */
>>> +		atomic_inc(&folio->_entire_mapcount);
>>> +		atomic_inc(&folio->_large_mapcount);
>>> +		break;
>>
>>
>> This way you don't account the pages at all as mapped, whereby PTE-mapping it
>> would? And IIRC, these PUD-sized pages can be either mapped using PTEs or
>> using a single PUD.
> 
> Oh good point. I was thinking that because we don't account PUD mappings today
> that it would be fine to ignore them. But of course this series means we start
> accounting them if mapped with PTEs so agree we should be consistent.
>   
>> I suspect what you want is to
> 
> Yes, I think so. Thanks for the hint. I will be out over the Christmas break but
> will do a respin to incorporate this before then.

I'll be on PTO starting ... well now. But I'll try to give the other 
parts a quick peek if anything urgent jumps at me. (bad habit of reading 
mails while on PTO ...)

In any case, happy holidays to you!

-- 
Cheers,

David / dhildenb



From david at redhat.com  Fri Dec 20 10:32:52 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 20 Dec 2024 19:32:52 +0100
Subject: [PATCH v4 19/25] proc/task_mmu: Ignore ZONE_DEVICE pages
In-Reply-To: <37rxl2bjda3psdknhboexhbg3hahf5ifmublp5fw7ltdoyqllc@udbz76jklmnu>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <f3ebda542373feb70ed3e5d83b276a2e8347609f.1734407924.git-series.apopple@nvidia.com>
 <c7bd9b00-6920-4dc0-8e2e-36c16ef7ad5a@redhat.com>
 <37rxl2bjda3psdknhboexhbg3hahf5ifmublp5fw7ltdoyqllc@udbz76jklmnu>
Message-ID: <36334f20-2b9e-4529-89c4-120678bc5985@redhat.com>

On 19.12.24 00:11, Alistair Popple wrote:
> On Tue, Dec 17, 2024 at 11:31:25PM +0100, David Hildenbrand wrote:
>> On 17.12.24 06:13, Alistair Popple wrote:
>>> The procfs mmu files such as smaps currently ignore device dax and fs
>>> dax pages because these pages are considered special. To maintain
>>> existing behaviour once these pages are treated as normal pages and
>>> returned from vm_normal_page() add tests to explicitly skip them.
>>>
>>> Signed-off-by: Alistair Popple <apopple at nvidia.com>
>>> ---
>>>    fs/proc/task_mmu.c | 18 ++++++++++++++----
>>>    1 file changed, 14 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
>>> index 38a5a3e..c9b227a 100644
>>> --- a/fs/proc/task_mmu.c
>>> +++ b/fs/proc/task_mmu.c
>>> @@ -801,6 +801,8 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
>>>    	if (pte_present(ptent)) {
>>>    		page = vm_normal_page(vma, addr, ptent);
>>> +		if (page && (is_device_dax_page(page) || is_fsdax_page(page)))
>>
>> This "is_device_dax_page(page) || is_fsdax_page(page)" is a common theme
>> here, likely we should have a special helper?
> 
> Sounds good, will add is_dax_page() if there are enough callers left after any
> review comments.

:)

>   
>> But, don't we actually want to include them in the smaps output now? I think
>> we want.
> 
> I'm not an expert in what callers of vm_normal_page() think of as a "normal"
> page. 

Yeah, it's tricky. It means "this is abnormal, don't look at the struct 
page". We're moving away from that, such that these folios/pages will be 
... mostly normal :)

> So my philosphy here was to ensure anything calling vm_normal_page()
> didn't accidentally start seeing DAX pages, either by checking existing filters
> (lots of callers already call vma_is_special_huge() or some equivalent) or
> explicitly filtering them out in the hope someone smarter than me could tell me
> it was unneccssary.
> 
> That stategy seems to have worked, and so I agree we likely do want them in
> smaps. I just didn't want to silently do it without this kind of discussion
> first.

Yes, absolutely.

> 
>> The rmap code will indicate these pages in /proc/meminfo, per-node info, in
>> the memcg ... as "Mapped:" etc.
>>
>> So likely we just want to also indicate them here, or is there any downsides
>> we know of?
> 
> I don't know of any, and I think it makes sense to also indicate them so will
> drop this check in the respin.

It will be easy to hide them later, at least we talked about it. Thanks 
for doing all this!

-- 
Cheers,

David / dhildenb



From catalin.marinas at arm.com  Fri Dec 20 10:35:50 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 20 Dec 2024 18:35:50 +0000
Subject: [PATCH v2 2/2] arm64: mm: implement vmemmap_check_pmd for arm64
In-Reply-To: <20241209094227.1529977-3-quic_zhenhuah@quicinc.com>
References: <20241209094227.1529977-1-quic_zhenhuah@quicinc.com>
 <20241209094227.1529977-3-quic_zhenhuah@quicinc.com>
Message-ID: <Z2W5Bs0bZANI6NKv@arm.com>

On Mon, Dec 09, 2024 at 05:42:27PM +0800, Zhenhua Huang wrote:
> vmemmap_check_pmd() is used to determine if needs to populate to base
> pages. Implement it for arm64 arch.
> 
> Fixes: 2045a3b8911b ("mm/sparse-vmemmap: generalise vmemmap_populate_hugepages()")
> Signed-off-by: Zhenhua Huang <quic_zhenhuah at quicinc.com>
> ---
>  arch/arm64/mm/mmu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index fd59ee44960e..41c7978a92be 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -1169,7 +1169,8 @@ int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node,
>  				unsigned long addr, unsigned long next)
>  {
>  	vmemmap_verify((pte_t *)pmdp, node, addr, next);
> -	return 1;
> +
> +	return pmd_sect(*pmdp);
>  }
>  
>  int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,

Don't we need this patch only if we implement the first one? Please fold
it into the other patch.

-- 
Catalin


From david at redhat.com  Fri Dec 20 10:39:32 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 20 Dec 2024 19:39:32 +0100
Subject: [PATCH v4 17/25] memremap: Add is_device_dax_page() and
 is_fsdax_page() helpers
In-Reply-To: <58ea909bd178d97bcc73997d6499880137d5e4ed.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <58ea909bd178d97bcc73997d6499880137d5e4ed.1734407924.git-series.apopple@nvidia.com>
Message-ID: <65af8809-af14-46d1-a479-d82b9973e278@redhat.com>

On 17.12.24 06:13, Alistair Popple wrote:
> Add helpers to determine if a page or folio is a device dax or fs dax
> page or folio.

... why is it "device_dax" but "fsdax" ? In particular because you wrote 
"fs dax" above.

I see "fsdax" getting used in some functions. But then, people usually 
say "devdax".

I'm fine either way (could be cleaned up later), just wondering about 
that slight "inconsistency".

So whatever you think is best, feel free to add

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From catalin.marinas at arm.com  Fri Dec 20 10:42:46 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 20 Dec 2024 18:42:46 +0000
Subject: [GIT PULL] arm64 fix for 6.13-rc4
Message-ID: <Z2W6puapTlYMGeyx@arm.com>

Hi Linus,

That's hopefully the last pull request of the year - a minor sparse
warning fix for the recently merged GCS support (arm's shadow stack).
Thanks.

Merry Christmas!

The following changes since commit ce03573a1917532da06057da9f8e74a2ee9e2ac9:

  kselftest/arm64: abi: fix SVCR detection (2024-12-13 14:59:37 +0000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

for you to fetch changes up to 926e862058978a8f81872845715d67ad21c30f65:

  arm64/signal: Silence sparse warning storing GCSPR_EL0 (2024-12-20 14:12:04 +0000)

----------------------------------------------------------------
Fix a sparse warning in the arm64 signal code dealing with the user
shadow stack register, GCSPR_EL0.

----------------------------------------------------------------
Mark Brown (1):
      arm64/signal: Silence sparse warning storing GCSPR_EL0

 arch/arm64/kernel/signal.c | 35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

-- 
Catalin


From wens at csie.org  Fri Dec 20 10:43:03 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Sat, 21 Dec 2024 02:43:03 +0800
Subject: [PATCH] arm64: dts: allwinner: h313: enable DVFS for Tanix TX1
In-Reply-To: <20241215212533.12707-1-andre.przywara@arm.com>
References: <20241215212533.12707-1-andre.przywara@arm.com>
Message-ID: <173472018373.189342.9184547368106297153.b4-ty@csie.org>

On Sun, 15 Dec 2024 21:25:33 +0000, Andre Przywara wrote:
> The merging of the Tanix TX1 .dts file overlapped with the introduction
> of the CPU OPP .dtsi file, so the TX1 wasn't covered by the patch
> enabling DVFS for all boards.
> 
> Add the missing include of that OPP .dtsi file, to allow the box to run
> at up to 1.3GHz, and enable power saving by using lower OPPs.
> 
> [...]

Applied to dt-for-6.14 in git at github.com:linux-sunxi/linux-sunxi.git, thanks!

[1/1] arm64: dts: allwinner: h313: enable DVFS for Tanix TX1
      commit: 300d7208ed783df828d26196f0105853811f4af1

Best regards,
-- 
Chen-Yu Tsai <wens at csie.org>



From wens at csie.org  Fri Dec 20 10:43:03 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Sat, 21 Dec 2024 02:43:03 +0800
Subject: [PATCH v2 0/2] sunxi: Add A100 syscon nodes
In-Reply-To: <20241218-a100-syscon-v2-0-dae60b9ce192@epochal.quest>
References: <20241218-a100-syscon-v2-0-dae60b9ce192@epochal.quest>
Message-ID: <173472018359.189342.4338686387095816178.b4-ty@csie.org>

On Wed, 18 Dec 2024 09:01:17 -0400, Cody Eksal wrote:
> https://msgid.link/20241202-a100-syscon-v1-0-86c6524f24d7 at epochal.quest.
> Only changes here are fixing missing newlines between child nodes and
> rebasing on 6.13-rc3.
> 
> ***
> 
> Here are some very small patches to add syscon nodes to the A100's
> device tree. These had not been added yet, as they hadn't been needed up
> to this point. However, Parthiban and I have been working on patch
> series in parallel that require either the syscon or the SRAM nodes it
> is responsible for; specifically my patches add support for the A100's
> ethernet controller, while Parthiban has been working hard on bringing
> up the Display Engine.
> 
> [...]

Applied to dt-for-6.14 in git at github.com:linux-sunxi/linux-sunxi.git, thanks!

[1/2] dt-bindings: sram: sunxi-sram: Add A100 compatible
      commit: 168b2b355f886db4230f10d24bc109b0b34c4708
[2/2] arm64: dts: allwinner: a100: Add syscon nodes
      commit: 53c54d9b9379e2a3eaec015556a51e47957a8d92

Best regards,
-- 
Chen-Yu Tsai <wens at csie.org>



From david at redhat.com  Fri Dec 20 10:52:43 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 20 Dec 2024 19:52:43 +0100
Subject: [PATCH v4 15/25] huge_memory: Add vmf_insert_folio_pud()
In-Reply-To: <03cb3c24f10818c0780a08509628893ab460e5d1.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <03cb3c24f10818c0780a08509628893ab460e5d1.1734407924.git-series.apopple@nvidia.com>
Message-ID: <ee19854f-fa1f-4207-9176-3c7b79bccd07@redhat.com>

On 17.12.24 06:12, Alistair Popple wrote:
> Currently DAX folio/page reference counts are managed differently to
> normal pages. To allow these to be managed the same as normal pages
> introduce vmf_insert_folio_pud. This will map the entire PUD-sized folio
> and take references as it would for a normally mapped page.
> 
> This is distinct from the current mechanism, vmf_insert_pfn_pud, which
> simply inserts a special devmap PUD entry into the page table without
> holding a reference to the page for the mapping.
> 
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> ---
>   include/linux/huge_mm.h | 11 +++++-
>   mm/huge_memory.c        | 96 ++++++++++++++++++++++++++++++++++++------
>   2 files changed, 95 insertions(+), 12 deletions(-)
> 
> diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
> index 93e509b..012137b 100644
> --- a/include/linux/huge_mm.h
> +++ b/include/linux/huge_mm.h
> @@ -39,6 +39,7 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
>   
>   vm_fault_t vmf_insert_pfn_pmd(struct vm_fault *vmf, pfn_t pfn, bool write);
>   vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write);
> +vm_fault_t vmf_insert_folio_pud(struct vm_fault *vmf, struct folio *folio, bool write);
>   
>   enum transparent_hugepage_flag {
>   	TRANSPARENT_HUGEPAGE_UNSUPPORTED,
> @@ -458,6 +459,11 @@ static inline bool is_huge_zero_pmd(pmd_t pmd)
>   	return pmd_present(pmd) && READ_ONCE(huge_zero_pfn) == pmd_pfn(pmd);
>   }
>   
> +static inline bool is_huge_zero_pud(pud_t pud)
> +{
> +	return false;
> +}
> +
>   struct folio *mm_get_huge_zero_folio(struct mm_struct *mm);
>   void mm_put_huge_zero_folio(struct mm_struct *mm);
>   
> @@ -604,6 +610,11 @@ static inline bool is_huge_zero_pmd(pmd_t pmd)
>   	return false;
>   }
>   
> +static inline bool is_huge_zero_pud(pud_t pud)
> +{
> +	return false;
> +}
> +

I'm really not a fan of these, because I assume we will never ever 
implement these any time soon. (who will waste 1 GiG or more on faster 
reading of 0s?)


>   static inline void mm_put_huge_zero_folio(struct mm_struct *mm)
>   {
>   	return;
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 120cd2c..5081808 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -1482,19 +1482,17 @@ static void insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
>   	struct mm_struct *mm = vma->vm_mm;
>   	pgprot_t prot = vma->vm_page_prot;
>   	pud_t entry;
> -	spinlock_t *ptl;
>   
> -	ptl = pud_lock(mm, pud);
>   	if (!pud_none(*pud)) {
>   		if (write) {
>   			if (WARN_ON_ONCE(pud_pfn(*pud) != pfn_t_to_pfn(pfn)))
> -				goto out_unlock;
> +				return;
>   			entry = pud_mkyoung(*pud);
>   			entry = maybe_pud_mkwrite(pud_mkdirty(entry), vma);
>   			if (pudp_set_access_flags(vma, addr, pud, entry, 1))
>   				update_mmu_cache_pud(vma, addr, pud);
>   		}
> -		goto out_unlock;
> +		return;
>   	}
>   
>   	entry = pud_mkhuge(pfn_t_pud(pfn, prot));
> @@ -1508,9 +1506,6 @@ static void insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
>   	}
>   	set_pud_at(mm, addr, pud, entry);
>   	update_mmu_cache_pud(vma, addr, pud);
> -
> -out_unlock:
> -	spin_unlock(ptl);
>   }
>   
>   /**
> @@ -1528,6 +1523,7 @@ vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write)
>   	unsigned long addr = vmf->address & PUD_MASK;
>   	struct vm_area_struct *vma = vmf->vma;
>   	pgprot_t pgprot = vma->vm_page_prot;
> +	spinlock_t *ptl;
>   
>   	/*
>   	 * If we had pud_special, we could avoid all these restrictions,
> @@ -1545,10 +1541,55 @@ vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write)
>   
>   	track_pfn_insert(vma, &pgprot, pfn);
>   
> +	ptl = pud_lock(vma->vm_mm, vmf->pud);
>   	insert_pfn_pud(vma, addr, vmf->pud, pfn, write);
> +	spin_unlock(ptl);
> +
>   	return VM_FAULT_NOPAGE;
>   }
>   EXPORT_SYMBOL_GPL(vmf_insert_pfn_pud);
> +
> +/**
> + * vmf_insert_folio_pud - insert a pud size folio mapped by a pud entry
> + * @vmf: Structure describing the fault
> + * @pfn: pfn of the page to insert
> + * @write: whether it's a write fault
> + *
> + * Return: vm_fault_t value.
> + */
> +vm_fault_t vmf_insert_folio_pud(struct vm_fault *vmf, struct folio *folio, bool write)
> +{
> +	struct vm_area_struct *vma = vmf->vma;
> +	unsigned long addr = vmf->address & PUD_MASK;
> +	pfn_t pfn = pfn_to_pfn_t(folio_pfn(folio));
> +	pud_t *pud = vmf->pud;
> +	pgprot_t prot = vma->vm_page_prot;

See below, pfn, prot and page can likely go.

> +	struct mm_struct *mm = vma->vm_mm;
> +	spinlock_t *ptl;
> +	struct page *page;
> +
> +	if (addr < vma->vm_start || addr >= vma->vm_end)
> +		return VM_FAULT_SIGBUS;
> +
> +	if (WARN_ON_ONCE(folio_order(folio) != PUD_ORDER))
> +		return VM_FAULT_SIGBUS;
> +
> +	track_pfn_insert(vma, &prot, pfn);

Oh, why is that required? We are inserting a folio and start messing 
with VM_PAT on x86 that only applies to VM_PFNMAP mappings? :)

> +
> +	ptl = pud_lock(mm, pud);
> +	if (pud_none(*vmf->pud)) {
> +		page = pfn_t_to_page(pfn);

Why are we suddenly working with that pfn_t whichcraft? :)


> +		folio = page_folio(page);

Ehm, you got the folio ... passed into this function?

Why can't that simply be

folio_get(folio);
folio_add_file_rmap_pud(folio, folio_page(folio, 0), vma);

> +		folio_get(folio);
> +		folio_add_file_rmap_pud(folio, page, vma);
> +		add_mm_counter(mm, mm_counter_file(folio), HPAGE_PUD_NR);
> +	}
> +	insert_pfn_pud(vma, addr, vmf->pud, pfn, write);
> +	spin_unlock(ptl);
> +
> +	return VM_FAULT_NOPAGE;
> +}
> +EXPORT_SYMBOL_GPL(vmf_insert_folio_pud);
>   #endif /* CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
>   
>   void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
> @@ -2146,7 +2187,8 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
>   			zap_deposited_table(tlb->mm, pmd);
>   		spin_unlock(ptl);
>   	} else if (is_huge_zero_pmd(orig_pmd)) {
> -		zap_deposited_table(tlb->mm, pmd);
> +		if (!vma_is_dax(vma) || arch_needs_pgtable_deposit())
> +			zap_deposited_table(tlb->mm, pmd);
>   		spin_unlock(ptl);
>   	} else {
>   		struct folio *folio = NULL;
> @@ -2634,12 +2676,24 @@ int zap_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma,
>   	orig_pud = pudp_huge_get_and_clear_full(vma, addr, pud, tlb->fullmm);
>   	arch_check_zapped_pud(vma, orig_pud);
>   	tlb_remove_pud_tlb_entry(tlb, pud, addr);
> -	if (vma_is_special_huge(vma)) {
> +	if (!vma_is_dax(vma) && vma_is_special_huge(vma)) {
>   		spin_unlock(ptl);
>   		/* No zero page support yet */
>   	} else {
> -		/* No support for anonymous PUD pages yet */
> -		BUG();
> +		struct page *page = NULL;
> +		struct folio *folio;
> +
> +		/* No support for anonymous PUD pages or migration yet */
> +		BUG_ON(vma_is_anonymous(vma) || !pud_present(orig_pud));

VM_WARN_ON_ONCE().

> +
> +		page = pud_page(orig_pud);
> +		folio = page_folio(page);
> +		folio_remove_rmap_pud(folio, page, vma);
> +		VM_BUG_ON_PAGE(!PageHead(page), page);

Please drop that or so something like

VM_WARN_ON_ONCE(page != folio_page(folio, 0));

> +		add_mm_counter(tlb->mm, mm_counter_file(folio), -HPAGE_PUD_NR);
> +
> +		spin_unlock(ptl);
> +		tlb_remove_page_size(tlb, page, HPAGE_PUD_SIZE);
>   	}
>   	return 1;
>   }
> @@ -2647,6 +2701,8 @@ int zap_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma,
>   static void __split_huge_pud_locked(struct vm_area_struct *vma, pud_t *pud,
>   		unsigned long haddr)
>   {
> +	pud_t old_pud;
> +
>   	VM_BUG_ON(haddr & ~HPAGE_PUD_MASK);
>   	VM_BUG_ON_VMA(vma->vm_start > haddr, vma);
>   	VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PUD_SIZE, vma);
> @@ -2654,7 +2710,23 @@ static void __split_huge_pud_locked(struct vm_area_struct *vma, pud_t *pud,
>   
>   	count_vm_event(THP_SPLIT_PUD);
>   
> -	pudp_huge_clear_flush(vma, haddr, pud);
> +	old_pud = pudp_huge_clear_flush(vma, haddr, pud);
> +	if (is_huge_zero_pud(old_pud))
> +		return;
> +
> +	if (vma_is_dax(vma)) {

Maybe you want

if (!vma_is_dax(vma))
	return;

To then reduce alignment. I suspect all other splitting code (besides 
anon memory) will want to do the same thing here in the future.

-- 
Cheers,

David / dhildenb



From david at redhat.com  Fri Dec 20 10:54:03 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 20 Dec 2024 19:54:03 +0100
Subject: [PATCH v4 16/25] huge_memory: Add vmf_insert_folio_pmd()
In-Reply-To: <b1c1e92f29094d6d5b78c6f87dc8ac81a9cbd7aa.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <b1c1e92f29094d6d5b78c6f87dc8ac81a9cbd7aa.1734407924.git-series.apopple@nvidia.com>
Message-ID: <d20b0078-afda-4a20-ad9e-b3694a43ba33@redhat.com>


> +vm_fault_t vmf_insert_folio_pmd(struct vm_fault *vmf, struct folio *folio, bool write)
> +{
> +	struct vm_area_struct *vma = vmf->vma;
> +	unsigned long addr = vmf->address & PMD_MASK;
> +	pfn_t pfn = pfn_to_pfn_t(folio_pfn(folio));
> +	struct mm_struct *mm = vma->vm_mm;
> +	spinlock_t *ptl;
> +	pgtable_t pgtable = NULL;
> +	struct page *page;
> +
> +	if (addr < vma->vm_start || addr >= vma->vm_end)
> +		return VM_FAULT_SIGBUS;
> +
> +	if (WARN_ON_ONCE(folio_order(folio) != PMD_ORDER))
> +		return VM_FAULT_SIGBUS;
> +
> +	if (arch_needs_pgtable_deposit()) {
> +		pgtable = pte_alloc_one(vma->vm_mm);
> +		if (!pgtable)
> +			return VM_FAULT_OOM;
> +	}
> +
> +	track_pfn_insert(vma, &vma->vm_page_prot, pfn);
> +
> +	ptl = pmd_lock(mm, vmf->pmd);
> +	if (pmd_none(*vmf->pmd)) {
> +		page = pfn_t_to_page(pfn);
> +		folio = page_folio(page);
> +		folio_get(folio);
> +		folio_add_file_rmap_pmd(folio, page, vma);
> +		add_mm_counter(mm, mm_counter_file(folio), HPAGE_PMD_NR);
> +	}

Same comments as for the PUD variant, apart from that nothing jumped at me.

-- 
Cheers,

David / dhildenb



From lkp at intel.com  Fri Dec 20 10:58:40 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 02:58:40 +0800
Subject: [PATCH 5/7] media: platform: Add Raspberry Pi HEVC decoder driver
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e@raspberrypi.com>
Message-ID: <202412210220.jZ2hzj8t-lkp@intel.com>

Hi Dave,

kernel test robot noticed the following build warnings:

[auto build test WARNING on e90c9612ac3969cb8206029a26bcd2b6f5d4a942]

url:    https://github.com/intel-lab-lkp/linux/commits/Dave-Stevenson/RFC-media-Add-media_request_-pin-unpin-API/20241221-002633
base:   e90c9612ac3969cb8206029a26bcd2b6f5d4a942
patch link:    https://lore.kernel.org/r/20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e%40raspberrypi.com
patch subject: [PATCH 5/7] media: platform: Add Raspberry Pi HEVC decoder driver
reproduce: (https://download.01.org/0day-ci/archive/20241221/202412210220.jZ2hzj8t-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/202412210220.jZ2hzj8t-lkp at intel.com/

All warnings (new ones prefixed by >>):

   Warning: Documentation/devicetree/bindings/regulator/siliconmitus,sm5703-regulator.yaml references a file that doesn't exist: Documentation/devicetree/bindings/mfd/siliconmitus,sm5703.yaml
   Warning: Documentation/hwmon/g762.rst references a file that doesn't exist: Documentation/devicetree/bindings/hwmon/g762.txt
   Warning: Documentation/hwmon/isl28022.rst references a file that doesn't exist: Documentation/devicetree/bindings/hwmon/isl,isl28022.yaml
   Warning: Documentation/translations/ja_JP/SubmittingPatches references a file that doesn't exist: linux-2.6.12-vanilla/Documentation/dontdiff
   Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>> Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/media/raspberrypi,rpi_hevc_dec.yaml
   Warning: lib/Kconfig.debug references a file that doesn't exist: Documentation/dev-tools/fault-injection/fault-injection.rst
   Using alabaster theme

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


From david at redhat.com  Fri Dec 20 11:01:02 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 20 Dec 2024 20:01:02 +0100
Subject: [PATCH v4 12/25] mm/memory: Enhance insert_page_into_pte_locked()
 to create writable mappings
In-Reply-To: <25a23433cb70f0fe6af92042eb71e962fcbf092b.1734407924.git-series.apopple@nvidia.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <25a23433cb70f0fe6af92042eb71e962fcbf092b.1734407924.git-series.apopple@nvidia.com>
Message-ID: <d4d32e17-d8e2-4447-bd33-af41e89a528f@redhat.com>

On 17.12.24 06:12, Alistair Popple wrote:
> In preparation for using insert_page() for DAX, enhance
> insert_page_into_pte_locked() to handle establishing writable
> mappings.  Recall that DAX returns VM_FAULT_NOPAGE after installing a
> PTE which bypasses the typical set_pte_range() in finish_fault.
> 
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> Suggested-by: Dan Williams <dan.j.williams at intel.com>
> 
> ---
> 
> Changes since v2:
> 
>   - New patch split out from "mm/memory: Add dax_insert_pfn"
> ---
>   mm/memory.c | 45 +++++++++++++++++++++++++++++++++++++--------
>   1 file changed, 37 insertions(+), 8 deletions(-)
> 
> diff --git a/mm/memory.c b/mm/memory.c
> index 06bb29e..cd82952 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2126,19 +2126,47 @@ static int validate_page_before_insert(struct vm_area_struct *vma,
>   }
>   
>   static int insert_page_into_pte_locked(struct vm_area_struct *vma, pte_t *pte,
> -			unsigned long addr, struct page *page, pgprot_t prot)
> +				unsigned long addr, struct page *page,
> +				pgprot_t prot, bool mkwrite)
>   {
>   	struct folio *folio = page_folio(page);
> +	pte_t entry = ptep_get(pte);
>   	pte_t pteval;
>   
> -	if (!pte_none(ptep_get(pte)))
> -		return -EBUSY;
> +	if (!pte_none(entry)) {
> +		if (!mkwrite)
> +			return -EBUSY;
> +
> +		/*
> +		 * For read faults on private mappings the PFN passed in may not
> +		 * match the PFN we have mapped if the mapped PFN is a writeable
> +		 * COW page.  In the mkwrite case we are creating a writable PTE
> +		 * for a shared mapping and we expect the PFNs to match. If they
> +		 * don't match, we are likely racing with block allocation and
> +		 * mapping invalidation so just skip the update.
> +		 */

Would it make sense to instead have here

/* See insert_pfn(). */

But ...

> +		if (pte_pfn(entry) != page_to_pfn(page)) {
> +			WARN_ON_ONCE(!is_zero_pfn(pte_pfn(entry)));
> +			return -EFAULT;
> +		}
> +		entry = maybe_mkwrite(entry, vma);
> +		entry = pte_mkyoung(entry);
> +		if (ptep_set_access_flags(vma, addr, pte, entry, 1))
> +			update_mmu_cache(vma, addr, pte);

... I am not sure if we want the above at all. Someone inserted a page, 
which is refcounted + mapcounted already.

Now you ignore that and do like the second insertion "worked" ?

No, that feels wrong, I suspect you will run into refcount+mapcount issues.

If there is already something, inserting must fail IMHO. If you want to 
change something to upgrade write permissions, then a different 
interface should be used.

> +		return 0;
> +	}
> +
>   	/* Ok, finally just insert the thing.. */
>   	pteval = mk_pte(page, prot);
>   	if (unlikely(is_zero_folio(folio))) {
>   		pteval = pte_mkspecial(pteval);
>   	} else {
>   		folio_get(folio);
> +		entry = mk_pte(page, prot);
> +		if (mkwrite) {
> +			entry = pte_mkyoung(entry);
 > +			entry = maybe_mkwrite(pte_mkdirty(entry), vma);> +		}
>   		inc_mm_counter(vma->vm_mm, mm_counter_file(folio));
>   		folio_add_file_rmap_pte(folio, page, vma);
>   	}
> @@ -2147,7 +2175,7 @@ static int insert_page_into_pte_locked(struct vm_area_struct *vma, pte_t *pte,
>   }
>   
>   static int insert_page(struct vm_area_struct *vma, unsigned long addr,
> -			struct page *page, pgprot_t prot)
> +			struct page *page, pgprot_t prot, bool mkwrite)
>   {
>   	int retval;
>   	pte_t *pte;
> @@ -2160,7 +2188,8 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,
>   	pte = get_locked_pte(vma->vm_mm, addr, &ptl);
>   	if (!pte)
>   		goto out;
> -	retval = insert_page_into_pte_locked(vma, pte, addr, page, prot);
> +	retval = insert_page_into_pte_locked(vma, pte, addr, page, prot,
> +					mkwrite);

Alignment looks odd. Likely you can also just put it into a single line.



-- 
Cheers,

David / dhildenb



From david at redhat.com  Fri Dec 20 11:06:48 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 20 Dec 2024 20:06:48 +0100
Subject: [PATCH v4 12/25] mm/memory: Enhance insert_page_into_pte_locked()
 to create writable mappings
In-Reply-To: <d4d32e17-d8e2-4447-bd33-af41e89a528f@redhat.com>
References: <cover.18cbcff3638c6aacc051c44533ebc6c002bf2bd9.1734407924.git-series.apopple@nvidia.com>
 <25a23433cb70f0fe6af92042eb71e962fcbf092b.1734407924.git-series.apopple@nvidia.com>
 <d4d32e17-d8e2-4447-bd33-af41e89a528f@redhat.com>
Message-ID: <6254ce2c-4a47-4501-b518-dedaddcbf91a@redhat.com>

On 20.12.24 20:01, David Hildenbrand wrote:
> On 17.12.24 06:12, Alistair Popple wrote:
>> In preparation for using insert_page() for DAX, enhance
>> insert_page_into_pte_locked() to handle establishing writable
>> mappings.  Recall that DAX returns VM_FAULT_NOPAGE after installing a
>> PTE which bypasses the typical set_pte_range() in finish_fault.
>>
>> Signed-off-by: Alistair Popple <apopple at nvidia.com>
>> Suggested-by: Dan Williams <dan.j.williams at intel.com>
>>
>> ---
>>
>> Changes since v2:
>>
>>    - New patch split out from "mm/memory: Add dax_insert_pfn"
>> ---
>>    mm/memory.c | 45 +++++++++++++++++++++++++++++++++++++--------
>>    1 file changed, 37 insertions(+), 8 deletions(-)
>>
>> diff --git a/mm/memory.c b/mm/memory.c
>> index 06bb29e..cd82952 100644
>> --- a/mm/memory.c
>> +++ b/mm/memory.c
>> @@ -2126,19 +2126,47 @@ static int validate_page_before_insert(struct vm_area_struct *vma,
>>    }
>>    
>>    static int insert_page_into_pte_locked(struct vm_area_struct *vma, pte_t *pte,
>> -			unsigned long addr, struct page *page, pgprot_t prot)
>> +				unsigned long addr, struct page *page,
>> +				pgprot_t prot, bool mkwrite)
>>    {
>>    	struct folio *folio = page_folio(page);
>> +	pte_t entry = ptep_get(pte);
>>    	pte_t pteval;
>>    
>> -	if (!pte_none(ptep_get(pte)))
>> -		return -EBUSY;
>> +	if (!pte_none(entry)) {
>> +		if (!mkwrite)
>> +			return -EBUSY;
>> +
>> +		/*
>> +		 * For read faults on private mappings the PFN passed in may not
>> +		 * match the PFN we have mapped if the mapped PFN is a writeable
>> +		 * COW page.  In the mkwrite case we are creating a writable PTE
>> +		 * for a shared mapping and we expect the PFNs to match. If they
>> +		 * don't match, we are likely racing with block allocation and
>> +		 * mapping invalidation so just skip the update.
>> +		 */
> 
> Would it make sense to instead have here
> 
> /* See insert_pfn(). */
> 
> But ...
> 
>> +		if (pte_pfn(entry) != page_to_pfn(page)) {
>> +			WARN_ON_ONCE(!is_zero_pfn(pte_pfn(entry)));
>> +			return -EFAULT;
>> +		}
>> +		entry = maybe_mkwrite(entry, vma);
>> +		entry = pte_mkyoung(entry);
>> +		if (ptep_set_access_flags(vma, addr, pte, entry, 1))
>> +			update_mmu_cache(vma, addr, pte);
> 
> ... I am not sure if we want the above at all. Someone inserted a page,
> which is refcounted + mapcounted already.
> 
> Now you ignore that and do like the second insertion "worked" ?
> 
> No, that feels wrong, I suspect you will run into refcount+mapcount issues.
> 
> If there is already something, inserting must fail IMHO. If you want to
> change something to upgrade write permissions, then a different
> interface should be used.

Ah, now I realize that the early exit saves you because we won't adjust 
the refcount +mapcount.

I still wonder if that really belongs in here, I would prefer to not 
play such tricks to upgrade write permissions if possible.

-- 
Cheers,

David / dhildenb



From jic23 at kernel.org  Fri Dec 20 11:23:17 2024
From: jic23 at kernel.org (Jonathan Cameron)
Date: Fri, 20 Dec 2024 19:23:17 +0000
Subject: [PATCH v2 3/9] iio: trigger: stm32-timer: add support for
 stm32mp25
In-Reply-To: <20241220095927.1122782-4-fabrice.gasnier@foss.st.com>
References: <20241220095927.1122782-1-fabrice.gasnier@foss.st.com>
	<20241220095927.1122782-4-fabrice.gasnier@foss.st.com>
Message-ID: <20241220192317.1266a34e@jic23-huawei>

On Fri, 20 Dec 2024 10:59:21 +0100
Fabrice Gasnier <fabrice.gasnier at foss.st.com> wrote:

> Add support for STM32MP25 SoC. Use newly introduced compatible to handle
> this new HW variant. Add TIM20 trigger definitions that can be used by
> the stm32 analog-to-digital converter. Use compatible data to identify
> it.
> As the counter framework is now superseding the deprecated IIO counter
> interface (IIO_COUNT), don't support it. Only register IIO trigger
> devices for ADC usage. So, make the valids_table a cfg option.
> 
> Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
I'm not seeing any compile time dependencies, so I've picked this one up.
Applied to the togreg branch of iio.git and pushed out initially as testing
to let 0-day see if I missed anything.

Thanks,

Jonathan


From olof at lixom.net  Fri Dec 20 11:27:33 2024
From: olof at lixom.net (Olof Johansson)
Date: Fri, 20 Dec 2024 11:27:33 -0800
Subject: [PATCH v2 0/4] ARM: config: stm32: Remove useless flags
In-Reply-To: <c720715b-cde3-4ab4-991d-37e9ae91b16f@app.fastmail.com>
References: <20241220125506.3157268-1-patrice.chotard@foss.st.com>
 <c720715b-cde3-4ab4-991d-37e9ae91b16f@app.fastmail.com>
Message-ID: <Z2XFJeMgUdaeAqHS@chonkvm.lixom.net>

On Fri, Dec 20, 2024 at 05:47:01PM +0100, Arnd Bergmann wrote:
> On Fri, Dec 20, 2024, at 13:55, patrice.chotard at foss.st.com wrote:
> > From: Patrice Chotard <patrice.chotard at foss.st.com>
> >
> > Running "make savedefconfig" highlights that some flags are no more used,
> > remove them.
> > Remove some flags to reduce the kernel image size as STM32 MCU's board
> > embeds low amount of RAM.
> >
> > Changes in V2:
> >   _ squash patches 2-7
> >   _ split patch 1 in three parts and add epxlanations about flags removal.
> 
> Looks good to me, thanks for the update. I assume the plan is to
> have this in another pull request rather than me picking up the
> patches directly, right?

On that note, I would *love* to no longer get patches into my inbox,
and I'll start to kindly request the senders of said patches to take
me off the recipients in the future. I'm not actively part of the soc
maintainer group any more, but I'm guessing that the others would benefit
from the same.

STM32 already has a maintainer, so there's no need to send these directly
to the soc-level maintainers, as far as I can tell. And certainly not
in the to: line (vs cc), at that.

If there's reason to send them directly, such as the platform maintainer
being unavailable or the patch being urgent as a fix, a justification
to make sure they're not missed would be useful.


-Olof


From dmitry.baryshkov at linaro.org  Fri Dec 20 11:15:55 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:15:55 +0200
Subject: [PATCH v7 00/10] drm: add DRM HDMI Codec framework
In-Reply-To: <CAPY8ntDUaFnvkjkqES4AkrzZ2z659h3w5MFSd8vW04Eh-iJ1FA@mail.gmail.com>
References: <20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515@linaro.org>
 <20241217-vivacious-chameleon-of-swiftness-f1edc4@houat>
 <CAA8EJprjCyWBNkRrc4W24uCwPtf_kxZLqNeNP8EJffbutYQ21w@mail.gmail.com>
 <20241218-wild-red-manatee-bb2a34@houat>
 <CAPY8ntDdcOXuWVgx6+cbgX5ct_-MXcE7CWDKgGP57EX6bvBLaw@mail.gmail.com>
 <CAPY8ntAnJ1YDQee=pFSDY3+EXHj4_RZ-M1NMp2C3ZDdD5DsCKA@mail.gmail.com>
 <c7qyka3hsrggqevdwdlfcanzps3z63s4joryskijlbuztacmly@tadqjm2vkj24>
 <CAPY8ntDUaFnvkjkqES4AkrzZ2z659h3w5MFSd8vW04Eh-iJ1FA@mail.gmail.com>
Message-ID: <2ut2qwy2geh7f2f75wq2ttlh4xbniwow24rtnzaikit7sd5smt@nrm5wiigrrha>

On Fri, Dec 20, 2024 at 03:00:47PM +0000, Dave Stevenson wrote:
> On Fri, 20 Dec 2024 at 00:45, Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
> >
> > On Thu, Dec 19, 2024 at 04:16:37PM +0000, Dave Stevenson wrote:
> > > On Wed, 18 Dec 2024 at 14:52, Dave Stevenson
> > > <dave.stevenson at raspberrypi.com> wrote:
> > > >
> > > > Hi Maxime & Dmitry
> > > >
> > > > On Wed, 18 Dec 2024 at 07:59, Maxime Ripard <mripard at kernel.org> wrote:
> > > > >
> > > > > On Wed, Dec 18, 2024 at 07:24:23AM +0200, Dmitry Baryshkov wrote:
> > > > > > On Tue, 17 Dec 2024 at 19:21, Maxime Ripard <mripard at kernel.org> wrote:
> > > > > > > On Tue, Dec 17, 2024 at 02:40:22AM +0200, Dmitry Baryshkov wrote:
> > > > > > > > While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
> > > > > > > > framework, I stumbled upon an issue while handling the Audio InfoFrames.
> > > > > > > > The HDMI codec callbacks weren't receiving the drm_atomic_state, so
> > > > > > > > there was no simple way to get the drm_connector that stayed at the end
> > > > > > > > of the bridge chain. At the same point the drm_hdmi_connector functions
> > > > > > > > expected to get drm_connector instance.
> > > > > > > >
> > > > > > > > While looking for a way to solve the issue, I stumbled upon several
> > > > > > > > deficiencies in existing hdmi_codec_ops implementations. Only few of the
> > > > > > > > implementations were able to handle codec's 'plugged' callback. One
> > > > > > > > third of the drivers didn't implement the get_eld() callback.
> > > > > > > >
> > > > > > > > Most of the issues can be solved if drm_connector handles
> > > > > > > > hdmi-audio-codec on its own, delegating functionality to the actual
> > > > > > > > implementation, be it a driver that implements drm_connector or
> > > > > > > > drm_bridge.
> > > > > > > >
> > > > > > > > Implement such high-level framework, adding proper support for Audio
> > > > > > > > InfoFrame generation to the LT9611 driver.
> > > > > > > >
> > > > > > > > Several design decisions to be kept in mind:
> > > > > > > >
> > > > > > > > - drm_connector_hdmi_codec is kept as simple as possible. It implements
> > > > > > > >   generic functionality (ELD, hotplug, registration).
> > > > > > > >
> > > > > > > > - drm_hdmi_connector sets up HDMI codec device if the connector
> > > > > > > >   is setup correspondingly (either I2S or S/PDIF is marked as
> > > > > > > >   supported).
> > > > > > > >
> > > > > > > > - drm_bridge_connector provides a way to link HDMI audio codec
> > > > > > > >   funcionality in the drm_bridge with the drm_connector_hdmi_codec
> > > > > > > >   framework.
> > > > > > > >
> > > > > > > > - It might be worth reverting the no_i2s_capture / no_spdif_capture
> > > > > > > >   bits. Only TDA889x driver sets them, while it's safe to assume that
> > > > > > > >   most of HDMI / DP devices do not support ARC / capture. I think the
> > > > > > > >   drivers should opt-in capture support rather than having to opt-out of
> > > > > > > >   it.
> > > > > > >
> > > > > > > Sorry if this isn't clear to me and I'm quite late to the party, but did
> > > > > > > you test this on vc4 with both a pi3 and pi4, or was it just compile
> > > > > > > tested?
> > > > > >
> > > > > > LT9611 is actually tested, VC4 is only compile-tested. Should I put an RFT tag?
> > > > >
> > > > > Yeah, we definitely need to test it on the pi3 (polling-based) and the
> > > > > pi4 (irq-based) at least.
> > > > >
> > > > > Dave, Maira, could you give it a try?
> > > >
> > > > I'm on it.
> > >
> > > Basic checks look OK.
> > > Pi3 and Pi4 tested, including 4k60 on Pi4 (enables scrambling). Audio
> > > works, and all the EDID parsing seems to be correct.
> > >
> > > Ideally I would like to do a couple more tests though as I had a
> > > couple of spontaneous reboots on Pi4 whilst hotplugging.
> > > Most likely it was just grounding issues, as I can't think of an
> > > obvious way for the kernel to be triggering an automatic reboot. They
> > > seemed to go away when I had enabled drm.debug=0x14, but more likely
> > > I'd connected the serial port and therefore provided another ground.
> > > Please don't hold the patches waiting on me though - I don't know when
> > > I'll have time to do them.
> >
> > Tested-by?
> 
> I'd held off hoping to get the extra testing done today, but that
> hasn't happened, and today is my last day before the Christmas break.
> So based on what I've done so far:
> 
> Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>

Thank you!

> 
> > >
> > >
> > > Also unrelated to this patch set, I have noted I'm getting
> > > [   60.780897] WARNING: CPU: 3 PID: 501 at
> > > drivers/gpu/drm/vc4/vc4_hvs.c:743 __vc4_hvs_stop_channel+0x148/0x164
> > > [vc4]
> > > ...
> > > [   60.781192]  __vc4_hvs_stop_channel+0x148/0x164 [vc4] (P)
> > > [   60.781212]  __vc4_hvs_stop_channel+0x40/0x164 [vc4] (L)
> > > [   60.781230]  vc4_hvs_stop_channel+0x30/0x3c [vc4]
> > > [   60.781248]  vc4_crtc_disable+0x140/0x1e8 [vc4]
> > > [   60.781266]  vc4_crtc_atomic_disable+0x98/0xb8 [vc4]
> > > [   60.781284]  disable_outputs+0x22c/0x33c [drm_kms_helper]
> > > [   60.781326]  drm_atomic_helper_commit_modeset_disables+0x1c/0x4c
> > > [drm_kms_helper]
> > > [   60.781347]  vc4_atomic_commit_tail+0x10c/0x8e4 [vc4]
> > > [   60.781364]  commit_tail+0xa0/0x188 [drm_kms_helper]
> > > [   60.781385]  drm_atomic_helper_commit+0x16c/0x180 [drm_kms_helper]
> > > [   60.781406]  drm_atomic_commit+0x88/0xc4 [drm]
> > > [   60.781500]  drm_client_modeset_commit_atomic+0x204/0x264 [drm]
> > > [   60.781553]  drm_client_modeset_commit_locked+0x5c/0x198 [drm]
> > > [   60.781603]  drm_client_modeset_commit+0x30/0x58 [drm]
> > > [   60.781652]  __drm_fb_helper_restore_fbdev_mode_unlocked+0xb4/0xe8
> > > [drm_kms_helper]
> > > [   60.781674]  drm_fb_helper_hotplug_event+0x108/0x12c [drm_kms_helper]
> > > [   60.781695]  drm_fbdev_client_hotplug+0x28/0xd4 [drm_client_lib]
> > > [   60.781700]  drm_client_dev_hotplug+0xc8/0x12c [drm]
> > > [   60.781750]  drm_connector_helper_hpd_irq_event+0x70/0xb0 [drm_kms_helper]
> > > [   60.781771]  vc4_hdmi_hpd_irq_thread+0x2c/0x3c [vc4]
> > > [   60.781790]  irq_thread_fn+0x2c/0xa8
> > > [   60.781799]  irq_thread+0x16c/0x2f4
> > > [   60.781805]  kthread+0x118/0x11c
> > > [   60.781813]  ret_from_fork+0x10/0x20
> > > On first plugging or unplugging a second monitor. I suspect that is
> > > spurious though and I'll look into it, but probably not this side of
> > > the Christmas break.
> > >
> > >   Dave
> >
> > --
> > With best wishes
> > Dmitry

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Fri Dec 20 11:16:57 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:16:57 +0200
Subject: [PATCH v8 00/10] drm: add DRM HDMI Codec framework
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>

While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
framework, I stumbled upon an issue while handling the Audio InfoFrames.
The HDMI codec callbacks weren't receiving the drm_atomic_state, so
there was no simple way to get the drm_connector that stayed at the end
of the bridge chain. At the same point the drm_hdmi_connector functions
expected to get drm_connector instance.

While looking for a way to solve the issue, I stumbled upon several
deficiencies in existing hdmi_codec_ops implementations. Only few of the
implementations were able to handle codec's 'plugged' callback. One
third of the drivers didn't implement the get_eld() callback.

Most of the issues can be solved if drm_connector handles
hdmi-audio-codec on its own, delegating functionality to the actual
implementation, be it a driver that implements drm_connector or
drm_bridge.

Implement such high-level framework, adding proper support for Audio
InfoFrame generation to the LT9611 driver.

Several design decisions to be kept in mind:

- drm_connector_hdmi_codec is kept as simple as possible. It implements
  generic functionality (ELD, hotplug, registration).

- drm_hdmi_connector sets up HDMI codec device if the connector
  is setup correspondingly (either I2S or S/PDIF is marked as
  supported).

- drm_bridge_connector provides a way to link HDMI audio codec
  funcionality in the drm_bridge with the drm_connector_hdmi_codec
  framework.

- It might be worth reverting the no_i2s_capture / no_spdif_capture
  bits. Only TDA889x driver sets them, while it's safe to assume that
  most of HDMI / DP devices do not support ARC / capture. I think the
  drivers should opt-in capture support rather than having to opt-out of
  it.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
Changes in v8:
- Mass rename hdmi_codec -> hdmi_audio, drop redundant audio_ prefixes
  from several callbacks (Maxime)
- Fix the commit message to stop mentioning
  drm_atomic_helper_connector_hdmi_update_edid() (Maxime)
- Link to v7: https://lore.kernel.org/r/20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515 at linaro.org

Changes in v7:
- Renamed drm_connector_hdmi_codec_init() to
  drm_connector_hdmi_audio_init() (Maxime)
- Added extra empty line in struct drm_connector_hdmi_codec_funcs
  (Maxime)
- Dropped if/else from drm_bridge_connector_audio_startup() (Maxime)
- Added optional .read_edid() callback and reworked
  drm_atomic_helper_connector_hdmi_hotplug() to use that callback
  instead of having an internal function which accepts EDID (Maxime)
- Made VC4 and drm_bridge_connector use .force() in addition to
  .detect() and .detect_ctx().
- Moved HDMI codec functions out of struct drm_connector_hdmi_funcs.
  Assign them from drm_connector_hdmi_audio_init().
- Documented struct drm_connector_hdmi_codec and its fields.
- Link to v6: https://lore.kernel.org/r/20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06 at linaro.org

Changes in v6:
- Dropped extra checks on the EDID (Jani)
- Reworked drmm_connector_hdmi_init(), splitting the codec init to a
  separate optional function rather than passing arguments through
  drm_connector (Maxime)
- Reworked EDID update functions (Maxime, Jani)
- No longer refresh the EDID in vc4_hdmi_connector_get_modes(), it is
  redundant as vc4_hdmi_connector_detect_cxtx() already does that.
- Link to v5: https://lore.kernel.org/r/20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a at linaro.org

Changes in v5:
- Moved prototypes from drm_internal.h to
  drm_connector_hdmi_codec_internal.h (Jani)
- Rebased on top of ELD mutex series, resolving the long-standing FIXME
- Converted the VC4 driver (compile-tested only)
- Link to v4: https://lore.kernel.org/r/20241122-drm-bridge-hdmi-connector-v4-0-b4d69d6e3bd9 at linaro.org

Changes in v4:
- Added forward declaration of struct drm_edid (LKP)
- Fixed kerneldoc for drm_atomic_helper_connector_hdmi_update_edid().
- Link to v3: https://lore.kernel.org/r/20241109-drm-bridge-hdmi-connector-v3-0-c15afdca5884 at linaro.org

Changes in v3:
- Dropped RFC status
- Fixed drm_connector_hdmi_codec_init() kerneldoc (LKP)
- Dropped double underscore prefix from
  __drm_atomic_helper_connector_hdmi_update_edid() (Jani)
- Moved drm_edid_free() from
  drm_atomic_helper_connector_hdmi_update_edid() to the caller's side
  (Jani)
- Link to v2: https://lore.kernel.org/r/20241101-drm-bridge-hdmi-connector-v2-0-739ef9addf9e at linaro.org

Changes in v2:
- Use drm_atomic_get_old_connector_for_encoder in atomic_disable() to
  prevent it from crashing
- Reworked HDMI codec init/exit, removing drmm_ calls (Maxime)
- Drafted the helper to be called from .detect_ctx() that performs HDMI
  Connector maintenance duties (Maxime)
- Moved no_capture_mute to struct hdmi_codec_pdata
- Link to v1: https://lore.kernel.org/r/20240615-drm-bridge-hdmi-connector-v1-0-d59fc7865ab2 at linaro.org

---
Dmitry Baryshkov (10):
      ASoC: hdmi-codec: pass data to get_dai_id too
      ASoC: hdmi-codec: move no_capture_mute to struct hdmi_codec_pdata
      drm/connector: implement generic HDMI audio helpers
      drm/bridge: connector: add support for HDMI codec framework
      drm/bridge: lt9611: switch to using the DRM HDMI codec framework
      drm/display/hdmi: implement hotplug functions
      drm/bridge_connector: hook drm_atomic_helper_connector_hdmi_hotplug()
      drm/vc4: hdmi: switch to using generic HDMI Codec infrastructure
      drm/vc4: hdmi: stop rereading EDID in get_modes()
      drm/vc4: hdmi: use drm_atomic_helper_connector_hdmi_hotplug()

 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c     |   3 +-
 drivers/gpu/drm/bridge/analogix/anx7625.c          |   3 +-
 drivers/gpu/drm/bridge/ite-it66121.c               |   2 +-
 drivers/gpu/drm/bridge/lontium-lt9611.c            | 169 ++++++++----------
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c         |   3 +-
 drivers/gpu/drm/bridge/sii902x.c                   |   5 +-
 .../gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c    |   3 +-
 drivers/gpu/drm/display/drm_bridge_connector.c     | 137 ++++++++++++++-
 drivers/gpu/drm/display/drm_hdmi_state_helper.c    |  56 ++++++
 drivers/gpu/drm/drm_connector.c                    |   5 +
 drivers/gpu/drm/drm_connector_hdmi_audio.c         | 189 +++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_hdmi.c               |   2 +-
 drivers/gpu/drm/i2c/tda998x_drv.c                  |   2 +-
 drivers/gpu/drm/mediatek/mtk_dp.c                  |   2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c                |   2 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c             |   2 +-
 drivers/gpu/drm/sti/sti_hdmi.c                     |   2 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c                     | 103 +++--------
 drivers/gpu/drm/vc4/vc4_hdmi.h                     |   2 -
 include/drm/display/drm_hdmi_state_helper.h        |   5 +
 include/drm/drm_bridge.h                           |  74 ++++++++
 include/drm/drm_connector.h                        | 141 +++++++++++++++
 include/sound/hdmi-codec.h                         |   7 +-
 sound/soc/codecs/hdmi-codec.c                      |   4 +-
 25 files changed, 716 insertions(+), 208 deletions(-)
---
base-commit: 74ef9527bd87ead62deabe749a6d867af748d448
change-id: 20240530-drm-bridge-hdmi-connector-9b0f6725973e

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:16:58 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:16:58 +0200
Subject: [PATCH v8 01/10] ASoC: hdmi-codec: pass data to get_dai_id too
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-1-2399dbae2990@linaro.org>

The upcoming DRM connector HDMI codec implementation is going to use
codec-specific data in the .get_dai_id to get drm_connector. Pass data
to the callback, as it is done with other hdmi_codec_ops callbacks.

Acked-by: Mark Brown <broonie at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c      | 3 ++-
 drivers/gpu/drm/bridge/analogix/anx7625.c           | 3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611.c             | 3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c          | 3 ++-
 drivers/gpu/drm/bridge/sii902x.c                    | 3 ++-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 3 ++-
 include/sound/hdmi-codec.h                          | 3 ++-
 sound/soc/codecs/hdmi-codec.c                       | 2 +-
 8 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
index 61f4a38e7d2bf6905683cbc9e762b28ecc999d05..51fb9a574b4e28450b2598a92e2930ace5128b71 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -204,7 +204,8 @@ static void audio_shutdown(struct device *dev, void *data)
 }
 
 static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-					struct device_node *endpoint)
+					struct device_node *endpoint,
+					void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 6238eabd23282d5f7e59a05d267737f40211aaf3..d65680d1bc8f2f27927b8a9d6926b72531791614 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1952,7 +1952,8 @@ static void anx7625_audio_shutdown(struct device *dev, void *data)
 }
 
 static int anx7625_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				       struct device_node *endpoint)
+				       struct device_node *endpoint,
+				       void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 74f726efc74613460a6eb9c41f0bbad2ab06208f..698a9a01783d28edc734b6932a7768978de65ffc 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -1057,7 +1057,8 @@ static void lt9611_audio_shutdown(struct device *dev, void *data)
 }
 
 static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				      struct device_node *endpoint)
+				      struct device_node *endpoint,
+				      void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index db9a5466060b663e88d58e85f24bf2d58d74a81c..f4c3ff1fdc6923eb7a8c0d8f7f92e7649c797d77 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -522,7 +522,8 @@ static void lt9611uxc_audio_shutdown(struct device *dev, void *data)
 }
 
 static int lt9611uxc_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-					 struct device_node *endpoint)
+					 struct device_node *endpoint,
+					 void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 127da22011b3235b049c38413e56d50414cf36fb..a02d30c0ba4221d7fee0eb50892ab4d8e8436004 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -815,7 +815,8 @@ static int sii902x_audio_get_eld(struct device *dev, void *data,
 }
 
 static int sii902x_audio_get_dai_id(struct snd_soc_component *component,
-				    struct device_node *endpoint)
+				    struct device_node *endpoint,
+				    void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index f1c5a8d0fa90e2eb2ee488b6a5871b005f797ea1..2c903c9fe8052ab721445188fd2b75270a55f2b0 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -148,7 +148,8 @@ static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, uint8_t *buf,
 }
 
 static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				  struct device_node *endpoint)
+				  struct device_node *endpoint,
+				  void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index 5e1a9eafd10f5d4f831abbb6f4c0fff661909584..b3407b47b4a7878532ecf3b08eeecd443d6fdb07 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -105,7 +105,8 @@ struct hdmi_codec_ops {
 	 * Optional
 	 */
 	int (*get_dai_id)(struct snd_soc_component *comment,
-			  struct device_node *endpoint);
+			  struct device_node *endpoint,
+			  void *data);
 
 	/*
 	 * Hook callback function to handle connector plug event.
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index d9df29a26f4f213a30a2ebcdb63a593f9cf4b901..f536ca60e162dca6b50b37854ca6de2c114bc2a1 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -995,7 +995,7 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
 	int ret = -ENOTSUPP; /* see snd_soc_get_dai_id() */
 
 	if (hcp->hcd.ops->get_dai_id)
-		ret = hcp->hcd.ops->get_dai_id(component, endpoint);
+		ret = hcp->hcd.ops->get_dai_id(component, endpoint, hcp->hcd.data);
 
 	return ret;
 }

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:16:59 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:16:59 +0200
Subject: [PATCH v8 02/10] ASoC: hdmi-codec: move no_capture_mute to struct
 hdmi_codec_pdata
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-2-2399dbae2990@linaro.org>

The no_capture_mute flag might differ from platform to platform,
especially in the case of the wrapping implementations, like the
upcoming DRM HDMI Codec framework. Move the flag next to all other flags
in struct hdmi_codec_pdata.

Acked-by: Mark Brown <broonie at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/ite-it66121.c   | 2 +-
 drivers/gpu/drm/bridge/sii902x.c       | 2 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c   | 2 +-
 drivers/gpu/drm/i2c/tda998x_drv.c      | 2 +-
 drivers/gpu/drm/mediatek/mtk_dp.c      | 2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c    | 2 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +-
 drivers/gpu/drm/sti/sti_hdmi.c         | 2 +-
 include/sound/hdmi-codec.h             | 4 +---
 sound/soc/codecs/hdmi-codec.c          | 2 +-
 10 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c
index 940083e5d2ddbfc56f14e2bdc6ddd0b9dd50b1f8..7734e389ca7692f7880aa9b8650e45aab228c7fd 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -1466,7 +1466,6 @@ static const struct hdmi_codec_ops it66121_audio_codec_ops = {
 	.audio_shutdown = it66121_audio_shutdown,
 	.mute_stream = it66121_audio_mute,
 	.get_eld = it66121_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev)
@@ -1476,6 +1475,7 @@ static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev)
 		.i2s = 1, /* Only i2s support for now */
 		.spdif = 0,
 		.max_i2s_channels = 8,
+		.no_capture_mute = 1,
 	};
 
 	dev_dbg(dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index a02d30c0ba4221d7fee0eb50892ab4d8e8436004..2a0af0f09defa2994ddece755ecf9742b418473b 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -841,7 +841,6 @@ static const struct hdmi_codec_ops sii902x_audio_codec_ops = {
 	.mute_stream = sii902x_audio_mute,
 	.get_eld = sii902x_audio_get_eld,
 	.get_dai_id = sii902x_audio_get_dai_id,
-	.no_capture_mute = 1,
 };
 
 static int sii902x_audio_codec_init(struct sii902x *sii902x,
@@ -864,6 +863,7 @@ static int sii902x_audio_codec_init(struct sii902x *sii902x,
 		.i2s = 1, /* Only i2s support for now. */
 		.spdif = 0,
 		.max_i2s_channels = 0,
+		.no_capture_mute = 1,
 	};
 	u8 lanes[4];
 	int num_lanes, i;
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 7a57d4a23e410db1d4d3a11bb9285d34c784f2d5..176fd88717597c37824fbf825ca6b893b083e0ca 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1660,7 +1660,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = hdmi_audio_shutdown,
 	.mute_stream = hdmi_audio_mute,
 	.get_eld = hdmi_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int hdmi_register_audio_device(struct hdmi_context *hdata)
@@ -1669,6 +1668,7 @@ static int hdmi_register_audio_device(struct hdmi_context *hdata)
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 6,
 		.i2s = 1,
+		.no_capture_mute = 1,
 	};
 
 	hdata->audio.pdev = platform_device_register_data(
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 57ce77c2be2458fff5b752332ae51e016582ddca..82d4a4e206a584e045a8fcd593fc12b7c1257bfe 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1165,7 +1165,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = tda998x_audio_shutdown,
 	.mute_stream = tda998x_audio_mute_stream,
 	.get_eld = tda998x_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int tda998x_audio_codec_init(struct tda998x_priv *priv,
@@ -1176,6 +1175,7 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
 		.max_i2s_channels = 2,
 		.no_i2s_capture = 1,
 		.no_spdif_capture = 1,
+		.no_capture_mute = 1,
 	};
 
 	if (priv->audio_port_enable[AUDIO_ROUTE_I2S])
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 36713c176cfcf1af2d365280700d06f4c1239e09..5c805094daf6d4678355fec43648552b34508bec 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -2615,7 +2615,6 @@ static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = {
 	.audio_shutdown = mtk_dp_audio_shutdown,
 	.get_eld = mtk_dp_audio_get_eld,
 	.hook_plugged_cb = mtk_dp_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int mtk_dp_register_audio_driver(struct device *dev)
@@ -2626,6 +2625,7 @@ static int mtk_dp_register_audio_driver(struct device *dev)
 		.max_i2s_channels = 8,
 		.i2s = 1,
 		.data = mtk_dp,
+		.no_capture_mute = 1,
 	};
 
 	mtk_dp->audio_pdev = platform_device_register_data(dev,
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 70dc1d4460adfc04b5c40263d11184aae826c658..ca82bc829cb96446d4d34eeef45848df03bd716b 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1660,7 +1660,6 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
 	.mute_stream = mtk_hdmi_audio_mute,
 	.get_eld = mtk_hdmi_audio_get_eld,
 	.hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int mtk_hdmi_register_audio_driver(struct device *dev)
@@ -1671,6 +1670,7 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
 		.max_i2s_channels = 2,
 		.i2s = 1,
 		.data = hdmi,
+		.no_capture_mute = 1,
 	};
 	struct platform_device *pdev;
 
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b76337f690ec2fdfbf4dac08a04aa4de4eff257f..b17de83b988b1f1afb2f6d12b1d155761ff9ca50 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -885,7 +885,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.mute_stream = cdn_dp_audio_mute_stream,
 	.get_eld = cdn_dp_audio_get_eld,
 	.hook_plugged_cb = cdn_dp_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
@@ -896,6 +895,7 @@ static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
 		.spdif = 1,
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 8,
+		.no_capture_mute = 1,
 	};
 
 	dp->audio_pdev = platform_device_register_data(
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index f8bbae6393ef8c0bd1deb75d1e131c1d83c1ebfe..ca2fe17de4a5d1e0199e59a97e6c7601e139ed9e 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -1237,7 +1237,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = hdmi_audio_shutdown,
 	.mute_stream = hdmi_audio_mute,
 	.get_eld = hdmi_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int sti_hdmi_register_audio_driver(struct device *dev,
@@ -1247,6 +1246,7 @@ static int sti_hdmi_register_audio_driver(struct device *dev,
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 8,
 		.i2s = 1,
+		.no_capture_mute = 1,
 	};
 
 	DRM_DEBUG_DRIVER("\n");
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index b3407b47b4a7878532ecf3b08eeecd443d6fdb07..b220072cfa1baf503efbe2d530d7e8392dc16603 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -115,9 +115,6 @@ struct hdmi_codec_ops {
 	int (*hook_plugged_cb)(struct device *dev, void *data,
 			       hdmi_codec_plugged_cb fn,
 			       struct device *codec_dev);
-
-	/* bit field */
-	unsigned int no_capture_mute:1;
 };
 
 /* HDMI codec initalization data */
@@ -129,6 +126,7 @@ struct hdmi_codec_pdata {
 	uint spdif:1;
 	uint no_spdif_playback:1;
 	uint no_spdif_capture:1;
+	uint no_capture_mute:1;
 	int max_i2s_channels;
 	void *data;
 };
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index f536ca60e162dca6b50b37854ca6de2c114bc2a1..69f98975e14ae367f482862724a358eb138ebf6a 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -714,7 +714,7 @@ static int hdmi_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
 	 */
 	if (hcp->hcd.ops->mute_stream &&
 	    (direction == SNDRV_PCM_STREAM_PLAYBACK ||
-	     !hcp->hcd.ops->no_capture_mute))
+	     !hcp->hcd.no_capture_mute))
 		return hcp->hcd.ops->mute_stream(dai->dev->parent,
 						 hcp->hcd.data,
 						 mute, direction);

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:17:00 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:17:00 +0200
Subject: [PATCH v8 03/10] drm/connector: implement generic HDMI audio
 helpers
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-3-2399dbae2990@linaro.org>

Several DRM drivers implement HDMI codec support (despite its name it
applies to both HDMI and DisplayPort drivers). Implement generic
framework to be used by these drivers. This removes a requirement to
implement get_eld() callback and provides default implementation for
codec's plug handling.

Acked-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/Makefile                   |   1 +
 drivers/gpu/drm/drm_connector.c            |   5 +
 drivers/gpu/drm/drm_connector_hdmi_audio.c | 189 +++++++++++++++++++++++++++++
 include/drm/drm_connector.h                | 125 +++++++++++++++++++
 4 files changed, 320 insertions(+)

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 19fb370fbc56772077973c864df71e4b8e0bf99b..4f7f8bde021f9713ab425fcfc9b687f3c7507d73 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -42,6 +42,7 @@ drm-y := \
 	drm_cache.o \
 	drm_color_mgmt.o \
 	drm_connector.o \
+	drm_connector_hdmi_audio.o \
 	drm_crtc.o \
 	drm_displayid.o \
 	drm_drv.o \
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index ae6e71305f3000aff1cfe96b050061a300b9478e..0669e0d9521c9d80efef1296180f23d6b38835b7 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -33,6 +33,7 @@
 #include <drm/drm_sysfs.h>
 #include <drm/drm_utils.h>
 
+#include <linux/platform_device.h>
 #include <linux/property.h>
 #include <linux/uaccess.h>
 
@@ -281,6 +282,7 @@ static int drm_connector_init_only(struct drm_device *dev,
 	mutex_init(&connector->eld_mutex);
 	mutex_init(&connector->edid_override_mutex);
 	mutex_init(&connector->hdmi.infoframes.lock);
+	mutex_init(&connector->hdmi_codec.lock);
 	connector->edid_blob_ptr = NULL;
 	connector->epoch_counter = 0;
 	connector->tile_blob_ptr = NULL;
@@ -714,6 +716,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		    DRM_CONNECTOR_REGISTERED))
 		drm_connector_unregister(connector);
 
+	platform_device_unregister(connector->hdmi_codec.codec_pdev);
+
 	if (connector->privacy_screen) {
 		drm_privacy_screen_put(connector->privacy_screen);
 		connector->privacy_screen = NULL;
@@ -750,6 +754,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		connector->funcs->atomic_destroy_state(connector,
 						       connector->state);
 
+	mutex_destroy(&connector->hdmi_codec.lock);
 	mutex_destroy(&connector->hdmi.infoframes.lock);
 	mutex_destroy(&connector->mutex);
 
diff --git a/drivers/gpu/drm/drm_connector_hdmi_audio.c b/drivers/gpu/drm/drm_connector_hdmi_audio.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd7aab2fdfd3530d1f812ea058f5f6fd9d1c3b27
--- /dev/null
+++ b/drivers/gpu/drm/drm_connector_hdmi_audio.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2024 Linaro Ltd
+ */
+
+#include <linux/mutex.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+
+#include <drm/drm_connector.h>
+#include <drm/drm_device.h>
+
+#include <sound/hdmi-codec.h>
+
+static int drm_connector_hdmi_audio_startup(struct device *dev, void *data)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_audio_funcs *funcs =
+		connector->hdmi_codec.funcs;
+
+	if (funcs->startup)
+		return funcs->startup(connector);
+
+	return 0;
+}
+
+static int drm_connector_hdmi_audio_prepare(struct device *dev, void *data,
+					    struct hdmi_codec_daifmt *fmt,
+					    struct hdmi_codec_params *hparms)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_audio_funcs *funcs =
+		connector->hdmi_codec.funcs;
+
+	return funcs->prepare(connector, fmt, hparms);
+}
+
+static void drm_connector_hdmi_audio_shutdown(struct device *dev, void *data)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_audio_funcs *funcs =
+		connector->hdmi_codec.funcs;
+
+	return funcs->shutdown(connector);
+}
+
+static int drm_connector_hdmi_audio_mute_stream(struct device *dev, void *data,
+						bool enable, int direction)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_audio_funcs *funcs =
+		connector->hdmi_codec.funcs;
+
+	if (funcs->mute_stream)
+		return funcs->mute_stream(connector, enable, direction);
+
+	return -ENOTSUPP;
+}
+
+static int drm_connector_hdmi_audio_get_dai_id(struct snd_soc_component *comment,
+					       struct device_node *endpoint,
+					       void *data)
+{
+	struct drm_connector *connector = data;
+	struct of_endpoint of_ep;
+	int ret;
+
+	if (connector->hdmi_codec.dai_port < 0)
+		return -ENOTSUPP;
+
+	ret = of_graph_parse_endpoint(endpoint, &of_ep);
+	if (ret < 0)
+		return ret;
+
+	if (of_ep.port == connector->hdmi_codec.dai_port)
+		return 0;
+
+	return -EINVAL;
+}
+
+static int drm_connector_hdmi_audio_get_eld(struct device *dev, void *data,
+					    uint8_t *buf, size_t len)
+{
+	struct drm_connector *connector = data;
+
+	mutex_lock(&connector->eld_mutex);
+	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
+	mutex_unlock(&connector->eld_mutex);
+
+	return 0;
+}
+
+static int drm_connector_hdmi_audio_hook_plugged_cb(struct device *dev,
+						    void *data,
+						    hdmi_codec_plugged_cb fn,
+						    struct device *codec_dev)
+{
+	struct drm_connector *connector = data;
+
+	mutex_lock(&connector->hdmi_codec.lock);
+
+	connector->hdmi_codec.plugged_cb = fn;
+	connector->hdmi_codec.plugged_cb_dev = codec_dev;
+
+	fn(codec_dev, connector->hdmi_codec.last_state);
+
+	mutex_unlock(&connector->hdmi_codec.lock);
+
+	return 0;
+}
+
+void drm_connector_hdmi_audio_plugged_notify(struct drm_connector *connector,
+					     bool plugged)
+{
+	mutex_lock(&connector->hdmi_codec.lock);
+
+	connector->hdmi_codec.last_state = plugged;
+
+	if (connector->hdmi_codec.plugged_cb &&
+	    connector->hdmi_codec.plugged_cb_dev)
+		connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev,
+						 connector->hdmi_codec.last_state);
+
+	mutex_unlock(&connector->hdmi_codec.lock);
+}
+EXPORT_SYMBOL(drm_connector_hdmi_audio_plugged_notify);
+
+static const struct hdmi_codec_ops drm_connector_hdmi_audio_ops = {
+	.audio_startup = drm_connector_hdmi_audio_startup,
+	.prepare = drm_connector_hdmi_audio_prepare,
+	.audio_shutdown = drm_connector_hdmi_audio_shutdown,
+	.mute_stream = drm_connector_hdmi_audio_mute_stream,
+	.get_eld = drm_connector_hdmi_audio_get_eld,
+	.get_dai_id = drm_connector_hdmi_audio_get_dai_id,
+	.hook_plugged_cb = drm_connector_hdmi_audio_hook_plugged_cb,
+};
+
+/**
+ * drm_connector_hdmi_audio_init - Initialize HDMI Codec device for the DRM connector
+ * @connector: A pointer to the connector to allocate codec for
+ * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
+ * @funcs: callbacks for this HDMI Codec
+ * @max_i2s_playback_channels: maximum number of playback I2S channels
+ * @spdif_playback: set if HDMI codec has S/PDIF playback port
+ * @dai_port: sound DAI port, -1 if it is not enabled
+ *
+ * Create a HDMI codec device to be used with the specified connector.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_connector_hdmi_audio_init(struct drm_connector *connector,
+				  struct device *hdmi_codec_dev,
+				  const struct drm_connector_hdmi_audio_funcs *funcs,
+				  unsigned int max_i2s_playback_channels,
+				  bool spdif_playback,
+				  int dai_port)
+{
+	struct hdmi_codec_pdata codec_pdata = {
+		.ops = &drm_connector_hdmi_audio_ops,
+		.max_i2s_channels = max_i2s_playback_channels,
+		.i2s = !!max_i2s_playback_channels,
+		.spdif = spdif_playback,
+		.no_i2s_capture = true,
+		.no_spdif_capture = true,
+		.data = connector,
+	};
+	struct platform_device *pdev;
+
+	if (!funcs ||
+	    !funcs->prepare ||
+	    !funcs->shutdown)
+		return -EINVAL;
+
+	connector->hdmi_codec.funcs = funcs;
+	connector->hdmi_codec.dai_port = dai_port;
+
+	pdev = platform_device_register_data(hdmi_codec_dev,
+					     HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO,
+					     &codec_pdata, sizeof(codec_pdata));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	connector->hdmi_codec.codec_pdev = pdev;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_hdmi_audio_init);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index d1be19242a5c5d7ab6b38cced1da336830b3848d..bdd8637196a608319e81fb3aee286ce0fd22cd9c 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -46,6 +46,8 @@ struct drm_property_blob;
 struct drm_printer;
 struct drm_privacy_screen;
 struct edid;
+struct hdmi_codec_daifmt;
+struct hdmi_codec_params;
 struct i2c_adapter;
 
 enum drm_connector_force {
@@ -1141,6 +1143,53 @@ struct drm_connector_state {
 	struct drm_connector_hdmi_state hdmi;
 };
 
+struct drm_connector_hdmi_audio_funcs {
+	/**
+	 * @startup:
+	 *
+	 * Called when ASoC starts an audio stream setup. The
+	 * @startup() is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*startup)(struct drm_connector *connector);
+
+	/**
+	 * @prepare:
+	 * Configures HDMI-encoder for audio stream. Can be called
+	 * multiple times for each setup. Mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*prepare)(struct drm_connector *connector,
+		       struct hdmi_codec_daifmt *fmt,
+		       struct hdmi_codec_params *hparms);
+
+	/**
+	 * @shutdown:
+	 *
+	 * Shut down the audio stream. Mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	void (*shutdown)(struct drm_connector *connector);
+
+	/**
+	 * @mute_stream:
+	 *
+	 * Mute/unmute HDMI audio stream. The @mute_stream callback is
+	 * optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*mute_stream)(struct drm_connector *connector,
+			   bool enable, int direction);
+};
+
 /**
  * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
  */
@@ -1660,6 +1709,68 @@ struct drm_cmdline_mode {
 	bool tv_mode_specified;
 };
 
+/**
+ * struct drm_connector_hdmi_audio - DRM gemeric HDMI Codec-related structure
+ *
+ * HDMI drivers usually incorporate a HDMI Codec. This structure expresses the
+ * generic HDMI Codec as used by the DRM HDMI Codec framework.
+ */
+struct drm_connector_hdmi_audio {
+	/**
+	 * @funcs:
+	 *
+	 * Implementation of the HDMI codec functionality to be used by the DRM
+	 * HDMI Codec framework.
+	 */
+	const struct drm_connector_hdmi_audio_funcs *funcs;
+
+	/**
+	 * @codec_pdev:
+	 *
+	 * Platform device created to hold the HDMI Codec. It will be
+	 * automatically unregistered during drm_connector_cleanup().
+	 */
+	struct platform_device *codec_pdev;
+
+	/**
+	 * @lock:
+	 *
+	 * Mutex to protect @last_state, @plugged_cb and @plugged_cb_dev.
+	 */
+	struct mutex lock;
+
+	/**
+	 * @plugged_cb:
+	 *
+	 * Callback to be called when the HDMI sink get plugged to or unplugged
+	 * from this connector. This is assigned by the framework when
+	 * requested by the ASoC code.
+	 */
+	void (*plugged_cb)(struct device *dev, bool plugged);
+
+	/**
+	 * @plugged_cb_dev:
+	 *
+	 * The data for @plugged_cb(). It is being provided by the ASoC.
+	 */
+	struct device *plugged_cb_dev;
+
+	/**
+	 * @last_state:
+	 *
+	 * Last plugged state recored by the framework. It is used to correctly
+	 * report the state to @plugged_cb().
+	 */
+	bool last_state;
+
+	/**
+	 * @dai_port:
+	 *
+	 * The port in DT that is used for the Codec DAI.
+	 */
+	int dai_port;
+};
+
 /*
  * struct drm_connector_hdmi - DRM Connector HDMI-related structure
  */
@@ -2121,6 +2232,11 @@ struct drm_connector {
 	 * @hdmi: HDMI-related variable and properties.
 	 */
 	struct drm_connector_hdmi hdmi;
+
+	/**
+	 * @hdmi_codec: HDMI codec properties and non-DRM state.
+	 */
+	struct drm_connector_hdmi_audio hdmi_codec;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -2153,6 +2269,12 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct i2c_adapter *ddc,
 			     unsigned long supported_formats,
 			     unsigned int max_bpc);
+int drm_connector_hdmi_audio_init(struct drm_connector *connector,
+				  struct device *hdmi_codec_dev,
+				  const struct drm_connector_hdmi_audio_funcs *funcs,
+				  unsigned int max_i2s_playback_channels,
+				  bool spdif_playback,
+				  int sound_dai_port);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);
 int drm_connector_dynamic_register(struct drm_connector *connector);
@@ -2160,6 +2282,9 @@ void drm_connector_unregister(struct drm_connector *connector);
 int drm_connector_attach_encoder(struct drm_connector *connector,
 				      struct drm_encoder *encoder);
 
+void drm_connector_hdmi_audio_plugged_notify(struct drm_connector *connector,
+					     bool plugged);
+
 void drm_connector_cleanup(struct drm_connector *connector);
 
 static inline unsigned int drm_connector_index(const struct drm_connector *connector)

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:17:01 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:17:01 +0200
Subject: [PATCH v8 04/10] drm/bridge: connector: add support for HDMI codec
 framework
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-4-2399dbae2990@linaro.org>

Add necessary glue code to be able to use new HDMI codec framework from
the DRM bridge drivers. The drm_bridge implements a limited set of the
hdmi_codec_ops interface, with the functions accepting both
drm_connector and drm_bridge instead of just a generic void pointer.

This framework is integrated with the DRM HDMI Connector framework, but
can also be used for DisplayPort connectors.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 98 ++++++++++++++++++++++++--
 drivers/gpu/drm/drm_connector.c                |  6 +-
 drivers/gpu/drm/drm_connector_hdmi_audio.c     | 42 +++++------
 include/drm/drm_bridge.h                       | 74 +++++++++++++++++++
 include/drm/drm_connector.h                    |  2 +-
 5 files changed, 193 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 512ced87ea18c74e182a558a686ddd83de891814..cc955ee008d843d73fedb891e97143a4168fd311 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -374,6 +374,75 @@ static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
 	.write_infoframe = drm_bridge_connector_write_infoframe,
 };
 
+static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	if (!bridge->funcs->hdmi_audio_startup)
+		return 0;
+
+	return bridge->funcs->hdmi_audio_startup(connector, bridge);
+}
+
+static int drm_bridge_connector_audio_prepare(struct drm_connector *connector,
+					      struct hdmi_codec_daifmt *fmt,
+					      struct hdmi_codec_params *hparms)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	return bridge->funcs->hdmi_audio_prepare(connector, bridge, fmt, hparms);
+}
+
+static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return;
+
+	bridge->funcs->hdmi_audio_shutdown(connector, bridge);
+}
+
+static int drm_bridge_connector_audio_mute_stream(struct drm_connector *connector,
+					    bool enable, int direction)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	if (bridge->funcs->hdmi_audio_mute_stream)
+		return bridge->funcs->hdmi_audio_mute_stream(connector, bridge,
+							     enable, direction);
+	else
+		return -ENOTSUPP;
+}
+
+static const struct drm_connector_hdmi_audio_funcs drm_bridge_connector_hdmi_audio_funcs = {
+	.startup = drm_bridge_connector_audio_startup,
+	.prepare = drm_bridge_connector_audio_prepare,
+	.shutdown = drm_bridge_connector_audio_shutdown,
+	.mute_stream = drm_bridge_connector_audio_mute_stream,
+};
+
 /* -----------------------------------------------------------------------------
  * Bridge Connector Initialisation
  */
@@ -473,7 +542,9 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
 		return ERR_PTR(-EINVAL);
 
-	if (bridge_connector->bridge_hdmi)
+	if (bridge_connector->bridge_hdmi) {
+		bridge = bridge_connector->bridge_hdmi;
+
 		ret = drmm_connector_hdmi_init(drm, connector,
 					       bridge_connector->bridge_hdmi->vendor,
 					       bridge_connector->bridge_hdmi->product,
@@ -482,12 +553,31 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 					       connector_type, ddc,
 					       supported_formats,
 					       max_bpc);
-	else
+		if (ret)
+			return ERR_PTR(ret);
+
+		if (bridge->hdmi_audio_max_i2s_playback_channels ||
+		    bridge->hdmi_audio_spdif_playback) {
+			if (!bridge->funcs->hdmi_audio_prepare ||
+			    !bridge->funcs->hdmi_audio_shutdown)
+				return ERR_PTR(-EINVAL);
+
+			ret = drm_connector_hdmi_audio_init(connector,
+							    bridge->hdmi_audio_dev,
+							    &drm_bridge_connector_hdmi_audio_funcs,
+							    bridge->hdmi_audio_max_i2s_playback_channels,
+							    bridge->hdmi_audio_spdif_playback,
+							    bridge->hdmi_audio_dai_port);
+			if (ret)
+				return ERR_PTR(ret);
+		}
+	} else {
 		ret = drmm_connector_init(drm, connector,
 					  &drm_bridge_connector_funcs,
 					  connector_type, ddc);
-	if (ret)
-		return ERR_PTR(ret);
+		if (ret)
+			return ERR_PTR(ret);
+	}
 
 	drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs);
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 0669e0d9521c9d80efef1296180f23d6b38835b7..1383fa9fff9bcf31488453e209a36c6fe97be2f1 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -282,7 +282,7 @@ static int drm_connector_init_only(struct drm_device *dev,
 	mutex_init(&connector->eld_mutex);
 	mutex_init(&connector->edid_override_mutex);
 	mutex_init(&connector->hdmi.infoframes.lock);
-	mutex_init(&connector->hdmi_codec.lock);
+	mutex_init(&connector->hdmi_audio.lock);
 	connector->edid_blob_ptr = NULL;
 	connector->epoch_counter = 0;
 	connector->tile_blob_ptr = NULL;
@@ -716,7 +716,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		    DRM_CONNECTOR_REGISTERED))
 		drm_connector_unregister(connector);
 
-	platform_device_unregister(connector->hdmi_codec.codec_pdev);
+	platform_device_unregister(connector->hdmi_audio.codec_pdev);
 
 	if (connector->privacy_screen) {
 		drm_privacy_screen_put(connector->privacy_screen);
@@ -754,7 +754,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		connector->funcs->atomic_destroy_state(connector,
 						       connector->state);
 
-	mutex_destroy(&connector->hdmi_codec.lock);
+	mutex_destroy(&connector->hdmi_audio.lock);
 	mutex_destroy(&connector->hdmi.infoframes.lock);
 	mutex_destroy(&connector->mutex);
 
diff --git a/drivers/gpu/drm/drm_connector_hdmi_audio.c b/drivers/gpu/drm/drm_connector_hdmi_audio.c
index bd7aab2fdfd3530d1f812ea058f5f6fd9d1c3b27..cda9403e49ec35e9d9c118705934908b3ca925b0 100644
--- a/drivers/gpu/drm/drm_connector_hdmi_audio.c
+++ b/drivers/gpu/drm/drm_connector_hdmi_audio.c
@@ -16,7 +16,7 @@ static int drm_connector_hdmi_audio_startup(struct device *dev, void *data)
 {
 	struct drm_connector *connector = data;
 	const struct drm_connector_hdmi_audio_funcs *funcs =
-		connector->hdmi_codec.funcs;
+		connector->hdmi_audio.funcs;
 
 	if (funcs->startup)
 		return funcs->startup(connector);
@@ -30,7 +30,7 @@ static int drm_connector_hdmi_audio_prepare(struct device *dev, void *data,
 {
 	struct drm_connector *connector = data;
 	const struct drm_connector_hdmi_audio_funcs *funcs =
-		connector->hdmi_codec.funcs;
+		connector->hdmi_audio.funcs;
 
 	return funcs->prepare(connector, fmt, hparms);
 }
@@ -39,7 +39,7 @@ static void drm_connector_hdmi_audio_shutdown(struct device *dev, void *data)
 {
 	struct drm_connector *connector = data;
 	const struct drm_connector_hdmi_audio_funcs *funcs =
-		connector->hdmi_codec.funcs;
+		connector->hdmi_audio.funcs;
 
 	return funcs->shutdown(connector);
 }
@@ -49,7 +49,7 @@ static int drm_connector_hdmi_audio_mute_stream(struct device *dev, void *data,
 {
 	struct drm_connector *connector = data;
 	const struct drm_connector_hdmi_audio_funcs *funcs =
-		connector->hdmi_codec.funcs;
+		connector->hdmi_audio.funcs;
 
 	if (funcs->mute_stream)
 		return funcs->mute_stream(connector, enable, direction);
@@ -65,14 +65,14 @@ static int drm_connector_hdmi_audio_get_dai_id(struct snd_soc_component *comment
 	struct of_endpoint of_ep;
 	int ret;
 
-	if (connector->hdmi_codec.dai_port < 0)
+	if (connector->hdmi_audio.dai_port < 0)
 		return -ENOTSUPP;
 
 	ret = of_graph_parse_endpoint(endpoint, &of_ep);
 	if (ret < 0)
 		return ret;
 
-	if (of_ep.port == connector->hdmi_codec.dai_port)
+	if (of_ep.port == connector->hdmi_audio.dai_port)
 		return 0;
 
 	return -EINVAL;
@@ -97,14 +97,14 @@ static int drm_connector_hdmi_audio_hook_plugged_cb(struct device *dev,
 {
 	struct drm_connector *connector = data;
 
-	mutex_lock(&connector->hdmi_codec.lock);
+	mutex_lock(&connector->hdmi_audio.lock);
 
-	connector->hdmi_codec.plugged_cb = fn;
-	connector->hdmi_codec.plugged_cb_dev = codec_dev;
+	connector->hdmi_audio.plugged_cb = fn;
+	connector->hdmi_audio.plugged_cb_dev = codec_dev;
 
-	fn(codec_dev, connector->hdmi_codec.last_state);
+	fn(codec_dev, connector->hdmi_audio.last_state);
 
-	mutex_unlock(&connector->hdmi_codec.lock);
+	mutex_unlock(&connector->hdmi_audio.lock);
 
 	return 0;
 }
@@ -112,16 +112,16 @@ static int drm_connector_hdmi_audio_hook_plugged_cb(struct device *dev,
 void drm_connector_hdmi_audio_plugged_notify(struct drm_connector *connector,
 					     bool plugged)
 {
-	mutex_lock(&connector->hdmi_codec.lock);
+	mutex_lock(&connector->hdmi_audio.lock);
 
-	connector->hdmi_codec.last_state = plugged;
+	connector->hdmi_audio.last_state = plugged;
 
-	if (connector->hdmi_codec.plugged_cb &&
-	    connector->hdmi_codec.plugged_cb_dev)
-		connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev,
-						 connector->hdmi_codec.last_state);
+	if (connector->hdmi_audio.plugged_cb &&
+	    connector->hdmi_audio.plugged_cb_dev)
+		connector->hdmi_audio.plugged_cb(connector->hdmi_audio.plugged_cb_dev,
+						 connector->hdmi_audio.last_state);
 
-	mutex_unlock(&connector->hdmi_codec.lock);
+	mutex_unlock(&connector->hdmi_audio.lock);
 }
 EXPORT_SYMBOL(drm_connector_hdmi_audio_plugged_notify);
 
@@ -172,8 +172,8 @@ int drm_connector_hdmi_audio_init(struct drm_connector *connector,
 	    !funcs->shutdown)
 		return -EINVAL;
 
-	connector->hdmi_codec.funcs = funcs;
-	connector->hdmi_codec.dai_port = dai_port;
+	connector->hdmi_audio.funcs = funcs;
+	connector->hdmi_audio.dai_port = dai_port;
 
 	pdev = platform_device_register_data(hdmi_codec_dev,
 					     HDMI_CODEC_DRV_NAME,
@@ -182,7 +182,7 @@ int drm_connector_hdmi_audio_init(struct drm_connector *connector,
 	if (IS_ERR(pdev))
 		return PTR_ERR(pdev);
 
-	connector->hdmi_codec.codec_pdev = pdev;
+	connector->hdmi_audio.codec_pdev = pdev;
 
 	return 0;
 }
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index e8d735b7f6a480468c88287e2517b387ceec0f22..4b84faf14e368310dd20aa964e8178ec80aa6fa7 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -41,6 +41,8 @@ struct drm_display_info;
 struct drm_minor;
 struct drm_panel;
 struct edid;
+struct hdmi_codec_daifmt;
+struct hdmi_codec_params;
 struct i2c_adapter;
 
 /**
@@ -676,6 +678,57 @@ struct drm_bridge_funcs {
 				    enum hdmi_infoframe_type type,
 				    const u8 *buffer, size_t len);
 
+	/**
+	 * @hdmi_audio_startup:
+	 *
+	 * Called when ASoC starts an audio stream setup. The
+	 * @hdmi_audio_startup() is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*hdmi_audio_startup)(struct drm_connector *connector,
+				  struct drm_bridge *bridge);
+
+	/**
+	 * @prepare:
+	 * Configures HDMI-encoder for audio stream. Can be called multiple
+	 * times for each setup. Mandatory if HDMI audio is enabled in the
+	 * bridge's configuration.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*hdmi_audio_prepare)(struct drm_connector *connector,
+				  struct drm_bridge *bridge,
+				  struct hdmi_codec_daifmt *fmt,
+				  struct hdmi_codec_params *hparms);
+
+	/**
+	 * @hdmi_audio_shutdown:
+	 *
+	 * Shut down the audio stream. Mandatory if HDMI audio is enabled in
+	 * the bridge's configuration.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	void (*hdmi_audio_shutdown)(struct drm_connector *connector,
+				    struct drm_bridge *bridge);
+
+	/**
+	 * @hdmi_audio_mute_stream:
+	 *
+	 * Mute/unmute HDMI audio stream. The @hdmi_audio_mute_stream callback
+	 * is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*hdmi_audio_mute_stream)(struct drm_connector *connector,
+				      struct drm_bridge *bridge,
+				      bool enable, int direction);
+
 	/**
 	 * @debugfs_init:
 	 *
@@ -859,6 +912,27 @@ struct drm_bridge {
 	 * @DRM_BRIDGE_OP_HDMI is set.
 	 */
 	unsigned int max_bpc;
+
+	/**
+	 * @hdmi_audio_dev: device to be used as a parent for the HDMI Codec
+	 */
+	struct device *hdmi_audio_dev;
+
+	/**
+	 * @hdmi_audio_max_i2s_playback_channels: maximum number of playback
+	 * I2S channels for the HDMI codec
+	 */
+	int hdmi_audio_max_i2s_playback_channels;
+
+	/**
+	 * @hdmi_audio_spdif_playback: set if HDMI codec has S/PDIF playback port
+	 */
+	unsigned int hdmi_audio_spdif_playback : 1;
+
+	/**
+	 * @hdmi_audio_dai_port: sound DAI port, -1 if it is not enabled
+	 */
+	int hdmi_audio_dai_port;
 };
 
 static inline struct drm_bridge *
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index bdd8637196a608319e81fb3aee286ce0fd22cd9c..ecd3dce94ffcfefacdb554efdc00ea19d6c18f24 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -2236,7 +2236,7 @@ struct drm_connector {
 	/**
 	 * @hdmi_codec: HDMI codec properties and non-DRM state.
 	 */
-	struct drm_connector_hdmi_audio hdmi_codec;
+	struct drm_connector_hdmi_audio hdmi_audio;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:17:02 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:17:02 +0200
Subject: [PATCH v8 05/10] drm/bridge: lt9611: switch to using the DRM HDMI
 codec framework
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-5-2399dbae2990@linaro.org>

Make the Lontium LT9611 DSI-to-HDMI bridge driver use the DRM HDMI Codec
framework. This enables programming of Audio InfoFrames using the HDMI
Connector interface and also enables support for the missing features,
including the ELD retrieval and better hotplug support.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 170 +++++++++++++-------------------
 1 file changed, 68 insertions(+), 102 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 698a9a01783d28edc734b6932a7768978de65ffc..11331e1d48a87c9acb048db5130bf635ec834fe0 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -45,7 +45,6 @@ struct lt9611 {
 	struct device_node *dsi1_node;
 	struct mipi_dsi_device *dsi0;
 	struct mipi_dsi_device *dsi1;
-	struct platform_device *audio_pdev;
 
 	bool ac_mode;
 
@@ -864,6 +863,10 @@ static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge,
 	unsigned int mask;
 
 	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mask = LT9611_INFOFRAME_AUDIO;
+		break;
+
 	case HDMI_INFOFRAME_TYPE_AVI:
 		mask = LT9611_INFOFRAME_AVI;
 		break;
@@ -897,6 +900,11 @@ static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge,
 	int i;
 
 	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mask = LT9611_INFOFRAME_AUDIO;
+		addr = 0x84b2;
+		break;
+
 	case HDMI_INFOFRAME_TYPE_AVI:
 		mask = LT9611_INFOFRAME_AVI;
 		addr = 0x8440;
@@ -940,6 +948,55 @@ lt9611_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
 	return MODE_OK;
 }
 
+static int lt9611_hdmi_audio_startup(struct drm_connector *connector,
+				     struct drm_bridge *bridge)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	regmap_write(lt9611->regmap, 0x82d6, 0x8c);
+	regmap_write(lt9611->regmap, 0x82d7, 0x04);
+
+	regmap_write(lt9611->regmap, 0x8406, 0x08);
+	regmap_write(lt9611->regmap, 0x8407, 0x10);
+
+	regmap_write(lt9611->regmap, 0x8434, 0xd5);
+
+	return 0;
+}
+
+static int lt9611_hdmi_audio_prepare(struct drm_connector *connector,
+				     struct drm_bridge *bridge,
+				     struct hdmi_codec_daifmt *fmt,
+				     struct hdmi_codec_params *hparms)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	if (hparms->sample_rate == 48000)
+		regmap_write(lt9611->regmap, 0x840f, 0x2b);
+	else if (hparms->sample_rate == 96000)
+		regmap_write(lt9611->regmap, 0x840f, 0xab);
+	else
+		return -EINVAL;
+
+	regmap_write(lt9611->regmap, 0x8435, 0x00);
+	regmap_write(lt9611->regmap, 0x8436, 0x18);
+	regmap_write(lt9611->regmap, 0x8437, 0x00);
+
+	return drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
+								       &hparms->cea);
+}
+
+static void lt9611_hdmi_audio_shutdown(struct drm_connector *connector,
+				       struct drm_bridge *bridge)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector);
+
+	regmap_write(lt9611->regmap, 0x8406, 0x00);
+	regmap_write(lt9611->regmap, 0x8407, 0x00);
+}
+
 static const struct drm_bridge_funcs lt9611_bridge_funcs = {
 	.attach = lt9611_bridge_attach,
 	.mode_valid = lt9611_bridge_mode_valid,
@@ -960,6 +1017,10 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = {
 	.hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid,
 	.hdmi_write_infoframe = lt9611_hdmi_write_infoframe,
 	.hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe,
+
+	.hdmi_audio_startup = lt9611_hdmi_audio_startup,
+	.hdmi_audio_prepare = lt9611_hdmi_audio_prepare,
+	.hdmi_audio_shutdown = lt9611_hdmi_audio_shutdown,
 };
 
 static int lt9611_parse_dt(struct device *dev,
@@ -1013,102 +1074,6 @@ static int lt9611_read_device_rev(struct lt9611 *lt9611)
 	return ret;
 }
 
-static int lt9611_hdmi_hw_params(struct device *dev, void *data,
-				 struct hdmi_codec_daifmt *fmt,
-				 struct hdmi_codec_params *hparms)
-{
-	struct lt9611 *lt9611 = data;
-
-	if (hparms->sample_rate == 48000)
-		regmap_write(lt9611->regmap, 0x840f, 0x2b);
-	else if (hparms->sample_rate == 96000)
-		regmap_write(lt9611->regmap, 0x840f, 0xab);
-	else
-		return -EINVAL;
-
-	regmap_write(lt9611->regmap, 0x8435, 0x00);
-	regmap_write(lt9611->regmap, 0x8436, 0x18);
-	regmap_write(lt9611->regmap, 0x8437, 0x00);
-
-	return 0;
-}
-
-static int lt9611_audio_startup(struct device *dev, void *data)
-{
-	struct lt9611 *lt9611 = data;
-
-	regmap_write(lt9611->regmap, 0x82d6, 0x8c);
-	regmap_write(lt9611->regmap, 0x82d7, 0x04);
-
-	regmap_write(lt9611->regmap, 0x8406, 0x08);
-	regmap_write(lt9611->regmap, 0x8407, 0x10);
-
-	regmap_write(lt9611->regmap, 0x8434, 0xd5);
-
-	return 0;
-}
-
-static void lt9611_audio_shutdown(struct device *dev, void *data)
-{
-	struct lt9611 *lt9611 = data;
-
-	regmap_write(lt9611->regmap, 0x8406, 0x00);
-	regmap_write(lt9611->regmap, 0x8407, 0x00);
-}
-
-static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				      struct device_node *endpoint,
-				      void *data)
-{
-	struct of_endpoint of_ep;
-	int ret;
-
-	ret = of_graph_parse_endpoint(endpoint, &of_ep);
-	if (ret < 0)
-		return ret;
-
-	/*
-	 * HDMI sound should be located as reg = <2>
-	 * Then, it is sound port 0
-	 */
-	if (of_ep.port == 2)
-		return 0;
-
-	return -EINVAL;
-}
-
-static const struct hdmi_codec_ops lt9611_codec_ops = {
-	.hw_params	= lt9611_hdmi_hw_params,
-	.audio_shutdown = lt9611_audio_shutdown,
-	.audio_startup	= lt9611_audio_startup,
-	.get_dai_id	= lt9611_hdmi_i2s_get_dai_id,
-};
-
-static struct hdmi_codec_pdata codec_data = {
-	.ops = &lt9611_codec_ops,
-	.max_i2s_channels = 8,
-	.i2s = 1,
-};
-
-static int lt9611_audio_init(struct device *dev, struct lt9611 *lt9611)
-{
-	codec_data.data = lt9611;
-	lt9611->audio_pdev =
-		platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-					      PLATFORM_DEVID_AUTO,
-					      &codec_data, sizeof(codec_data));
-
-	return PTR_ERR_OR_ZERO(lt9611->audio_pdev);
-}
-
-static void lt9611_audio_exit(struct lt9611 *lt9611)
-{
-	if (lt9611->audio_pdev) {
-		platform_device_unregister(lt9611->audio_pdev);
-		lt9611->audio_pdev = NULL;
-	}
-}
-
 static int lt9611_probe(struct i2c_client *client)
 {
 	struct lt9611 *lt9611;
@@ -1172,6 +1137,9 @@ static int lt9611_probe(struct i2c_client *client)
 
 	i2c_set_clientdata(client, lt9611);
 
+	/* Disable Audio InfoFrame, enabled by default */
+	regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, 0);
+
 	lt9611->bridge.funcs = &lt9611_bridge_funcs;
 	lt9611->bridge.of_node = client->dev.of_node;
 	lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
@@ -1180,6 +1148,9 @@ static int lt9611_probe(struct i2c_client *client)
 	lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	lt9611->bridge.vendor = "Lontium";
 	lt9611->bridge.product = "LT9611";
+	lt9611->bridge.hdmi_audio_dev = dev;
+	lt9611->bridge.hdmi_audio_max_i2s_playback_channels = 8;
+	lt9611->bridge.hdmi_audio_dai_port = 2;
 
 	drm_bridge_add(&lt9611->bridge);
 
@@ -1201,10 +1172,6 @@ static int lt9611_probe(struct i2c_client *client)
 
 	lt9611_enable_hpd_interrupts(lt9611);
 
-	ret = lt9611_audio_init(dev, lt9611);
-	if (ret)
-		goto err_remove_bridge;
-
 	return 0;
 
 err_remove_bridge:
@@ -1225,7 +1192,6 @@ static void lt9611_remove(struct i2c_client *client)
 	struct lt9611 *lt9611 = i2c_get_clientdata(client);
 
 	disable_irq(client->irq);
-	lt9611_audio_exit(lt9611);
 	drm_bridge_remove(&lt9611->bridge);
 
 	regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:17:03 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:17:03 +0200
Subject: [PATCH v8 06/10] drm/display/hdmi: implement hotplug functions
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-6-2399dbae2990@linaro.org>

The HDMI Connectors need to perform a variety of tasks when the HDMI
connector state changes. Such tasks include setting or invalidating CEC
address, notifying HDMI codec driver, updating scrambler data, etc.

Implementing such tasks in a driver-specific callbacks is error prone.
Start implementing the generic helper function (currently handling only
the HDMI Codec framework) to be used by drivers utilizing HDMI Connector
framework.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_hdmi_state_helper.c | 56 +++++++++++++++++++++++++
 include/drm/display/drm_hdmi_state_helper.h     |  5 +++
 include/drm/drm_connector.h                     | 16 +++++++
 3 files changed, 77 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index d678c635a6935050ca9c1ccafbb0865f21df5d4e..f4935b3e630cd89ec6373eb67b06e6a3a3b3a55a 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -777,3 +777,59 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con
 	return ret;
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe);
+
+static void
+drm_atomic_helper_connector_hdmi_update(struct drm_connector *connector,
+					enum drm_connector_status status)
+{
+	const struct drm_edid *drm_edid;
+
+	if (status == connector_status_disconnected) {
+		// TODO: also handle CEC and scramber, HDMI sink disconnected.
+		drm_connector_hdmi_audio_plugged_notify(connector, false);
+	}
+
+	if (connector->hdmi.funcs->read_edid)
+		drm_edid = connector->hdmi.funcs->read_edid(connector);
+	else
+		drm_edid = drm_edid_read(connector);
+
+	drm_edid_connector_update(connector, drm_edid);
+
+	drm_edid_free(drm_edid);
+
+	if (status == connector_status_connected) {
+		// TODO: also handle CEC and scramber, HDMI sink is now connected.
+		drm_connector_hdmi_audio_plugged_notify(connector, true);
+	}
+}
+
+/**
+ * drm_atomic_helper_connector_hdmi_hotplug - Handle the hotplug event for the HDMI connector
+ * @connector: A pointer to the HDMI connector
+ * @status: Connection status
+ *
+ * This function should be called as a part of the .detect() / .detect_ctx()
+ * callbacks, updating the HDMI-specific connector's data.
+ */
+void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
+					      enum drm_connector_status status)
+{
+	drm_atomic_helper_connector_hdmi_update(connector, status);
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_hotplug);
+
+/**
+ * drm_atomic_helper_connector_hdmi_force - HDMI Connector implementation of the force callback
+ * @connector: A pointer to the HDMI connector
+ *
+ * This function implements the .force() callback for the HDMI connectors. It
+ * can either be used directly as the callback or should be called from within
+ * the .force() callback implementation to maintain the HDMI-specific
+ * connector's data.
+ */
+void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector)
+{
+	drm_atomic_helper_connector_hdmi_update(connector, connector->status);
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_force);
diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h
index d6d65da6d8f9ee46de33114cce2d6fbe6098a862..9ae19f3caf727f9a0fe06e6afe5fc46db924444f 100644
--- a/include/drm/display/drm_hdmi_state_helper.h
+++ b/include/drm/display/drm_hdmi_state_helper.h
@@ -8,6 +8,8 @@ struct drm_connector;
 struct drm_connector_state;
 struct hdmi_audio_infoframe;
 
+enum drm_connector_status;
+
 void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
 					      struct drm_connector_state *new_conn_state);
 
@@ -19,6 +21,9 @@ int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector
 int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector);
 int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
 						       struct drm_atomic_state *state);
+void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
+					      enum drm_connector_status status);
+void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector);
 
 enum drm_mode_status
 drm_hdmi_connector_mode_valid(struct drm_connector *connector,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ecd3dce94ffcfefacdb554efdc00ea19d6c18f24..9ea08a283018301449895602f3f50ffbf22429ce 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -45,6 +45,7 @@ struct drm_property;
 struct drm_property_blob;
 struct drm_printer;
 struct drm_privacy_screen;
+struct drm_edid;
 struct edid;
 struct hdmi_codec_daifmt;
 struct hdmi_codec_params;
@@ -1247,6 +1248,21 @@ struct drm_connector_hdmi_funcs {
 	int (*write_infoframe)(struct drm_connector *connector,
 			       enum hdmi_infoframe_type type,
 			       const u8 *buffer, size_t len);
+
+	/**
+	 * @read_edid:
+	 *
+	 * This callback is used by the framework as a replacement for reading
+	 * the EDID from connector->ddc. It is still recommended to provide
+	 * connector->ddc instead of implementing this callback. Returned EDID
+	 * should be freed via the drm_edid_free().
+	 *
+	 * The @read_edid callback is optional.
+	 *
+	 * Returns:
+	 * Valid EDID on success, NULL in case of failure.
+	 */
+	const struct drm_edid *(*read_edid)(struct drm_connector *connector);
 };
 
 /**

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:17:04 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:17:04 +0200
Subject: [PATCH v8 07/10] drm/bridge_connector: hook
 drm_atomic_helper_connector_hdmi_hotplug()
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-7-2399dbae2990@linaro.org>

Extend drm_bridge_connector code to read the EDID and use it to update
connector status if the bridge chain implements HDMI bridge. Performing
it from the generic location minimizes individual bridge's code and
enforces standard behaviour from all corresponding drivers.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 39 ++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index cc955ee008d843d73fedb891e97143a4168fd311..66e4ab81fa0c2717490193e896389757f0a903f2 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -17,6 +17,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_hdmi_state_helper.h>
@@ -180,11 +181,15 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
 	struct drm_bridge_connector *bridge_connector =
 		to_drm_bridge_connector(connector);
 	struct drm_bridge *detect = bridge_connector->bridge_detect;
+	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
 	enum drm_connector_status status;
 
 	if (detect) {
 		status = detect->funcs->detect(detect);
 
+		if (hdmi)
+			drm_atomic_helper_connector_hdmi_hotplug(connector, status);
+
 		drm_bridge_connector_hpd_notify(connector, status);
 	} else {
 		switch (connector->connector_type) {
@@ -203,6 +208,16 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
 	return status;
 }
 
+static void drm_bridge_connector_force(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
+
+	if (hdmi)
+		drm_atomic_helper_connector_hdmi_force(connector);
+}
+
 static void drm_bridge_connector_debugfs_init(struct drm_connector *connector,
 					      struct dentry *root)
 {
@@ -231,6 +246,7 @@ static void drm_bridge_connector_reset(struct drm_connector *connector)
 static const struct drm_connector_funcs drm_bridge_connector_funcs = {
 	.reset = drm_bridge_connector_reset,
 	.detect = drm_bridge_connector_detect,
+	.force = drm_bridge_connector_force,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
@@ -276,6 +292,14 @@ static int drm_bridge_connector_get_modes(struct drm_connector *connector)
 		to_drm_bridge_connector(connector);
 	struct drm_bridge *bridge;
 
+	/*
+	 * If there is a HDMI bridge, EDID has been updated as a part of
+	 * the .detect(). Just update the modes here.
+	 */
+	bridge = bridge_connector->bridge_hdmi;
+	if (bridge)
+		return drm_edid_connector_add_modes(connector);
+
 	/*
 	 * If display exposes EDID, then we parse that in the normal way to
 	 * build table of supported modes.
@@ -368,10 +392,25 @@ static int drm_bridge_connector_write_infoframe(struct drm_connector *connector,
 	return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len);
 }
 
+static const struct drm_edid *
+drm_bridge_connector_read_edid(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_edid;
+	if (!bridge)
+		return NULL;
+
+	return drm_bridge_edid_read(bridge, connector);
+}
+
 static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
 	.tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid,
 	.clear_infoframe = drm_bridge_connector_clear_infoframe,
 	.write_infoframe = drm_bridge_connector_write_infoframe,
+	.read_edid = drm_bridge_connector_read_edid,
 };
 
 static int drm_bridge_connector_audio_startup(struct drm_connector *connector)

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:17:05 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:17:05 +0200
Subject: [PATCH v8 08/10] drm/vc4: hdmi: switch to using generic HDMI Codec
 infrastructure
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-8-2399dbae2990@linaro.org>

Drop driver-specific implementation and use the generic HDMI Codec
framework in order to implement the HDMI audio support.

Acked-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 73 +++++++++++-------------------------------
 drivers/gpu/drm/vc4/vc4_hdmi.h |  2 --
 2 files changed, 18 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 203293a8beca738dbfeaaf15f350026e263e646b..24199b511f2ee1bc3aa5f4a30e9d3d928d556ff1 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -584,6 +584,7 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
 };
 
 static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs;
+static const struct drm_connector_hdmi_audio_funcs vc4_hdmi_audio_funcs;
 
 static int vc4_hdmi_connector_init(struct drm_device *dev,
 				   struct vc4_hdmi *vc4_hdmi)
@@ -609,6 +610,12 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	ret = drm_connector_hdmi_audio_init(connector, dev->dev,
+					    &vc4_hdmi_audio_funcs,
+					    8, false, -1);
+	if (ret)
+		return ret;
+
 	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
 
 	/*
@@ -1921,9 +1928,9 @@ static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi)
 	return true;
 }
 
-static int vc4_hdmi_audio_startup(struct device *dev, void *data)
+static int vc4_hdmi_audio_startup(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	unsigned long flags;
 	int ret = 0;
@@ -1985,9 +1992,9 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 	spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 }
 
-static void vc4_hdmi_audio_shutdown(struct device *dev, void *data)
+static void vc4_hdmi_audio_shutdown(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	unsigned long flags;
 	int idx;
@@ -2057,13 +2064,12 @@ static int sample_rate_to_mai_fmt(int samplerate)
 }
 
 /* HDMI audio codec callbacks */
-static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
+static int vc4_hdmi_audio_prepare(struct drm_connector *connector,
 				  struct hdmi_codec_daifmt *daifmt,
 				  struct hdmi_codec_params *params)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	struct drm_connector *connector = &vc4_hdmi->connector;
 	struct vc4_dev *vc4 = to_vc4_dev(drm);
 	unsigned int sample_rate = params->sample_rate;
 	unsigned int channels = params->channels;
@@ -2075,7 +2081,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
 	int ret = 0;
 	int idx;
 
-	dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
+	dev_dbg(&vc4_hdmi->pdev->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
 		sample_rate, params->sample_width, channels);
 
 	mutex_lock(&vc4_hdmi->mutex);
@@ -2214,40 +2220,12 @@ static const struct snd_dmaengine_pcm_config pcm_conf = {
 	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
 };
 
-static int vc4_hdmi_audio_get_eld(struct device *dev, void *data,
-				  uint8_t *buf, size_t len)
-{
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-
-	mutex_lock(&connector->eld_mutex);
-	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
-	mutex_unlock(&connector->eld_mutex);
-
-	return 0;
-}
-
-static const struct hdmi_codec_ops vc4_hdmi_codec_ops = {
-	.get_eld = vc4_hdmi_audio_get_eld,
+static const struct drm_connector_hdmi_audio_funcs vc4_hdmi_audio_funcs = {
+	.startup = vc4_hdmi_audio_startup,
 	.prepare = vc4_hdmi_audio_prepare,
-	.audio_shutdown = vc4_hdmi_audio_shutdown,
-	.audio_startup = vc4_hdmi_audio_startup,
-};
-
-static struct hdmi_codec_pdata vc4_hdmi_codec_pdata = {
-	.ops = &vc4_hdmi_codec_ops,
-	.max_i2s_channels = 8,
-	.i2s = 1,
+	.shutdown = vc4_hdmi_audio_shutdown,
 };
 
-static void vc4_hdmi_audio_codec_release(void *ptr)
-{
-	struct vc4_hdmi *vc4_hdmi = ptr;
-
-	platform_device_unregister(vc4_hdmi->audio.codec_pdev);
-	vc4_hdmi->audio.codec_pdev = NULL;
-}
-
 static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 {
 	const struct vc4_hdmi_register *mai_data =
@@ -2255,7 +2233,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 	struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link;
 	struct snd_soc_card *card = &vc4_hdmi->audio.card;
 	struct device *dev = &vc4_hdmi->pdev->dev;
-	struct platform_device *codec_pdev;
 	const __be32 *addr;
 	int index, len;
 	int ret;
@@ -2348,20 +2325,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 		return ret;
 	}
 
-	codec_pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-						   PLATFORM_DEVID_AUTO,
-						   &vc4_hdmi_codec_pdata,
-						   sizeof(vc4_hdmi_codec_pdata));
-	if (IS_ERR(codec_pdev)) {
-		dev_err(dev, "Couldn't register the HDMI codec: %ld\n", PTR_ERR(codec_pdev));
-		return PTR_ERR(codec_pdev);
-	}
-	vc4_hdmi->audio.codec_pdev = codec_pdev;
-
-	ret = devm_add_action_or_reset(dev, vc4_hdmi_audio_codec_release, vc4_hdmi);
-	if (ret)
-		return ret;
-
 	dai_link->cpus		= &vc4_hdmi->audio.cpu;
 	dai_link->codecs	= &vc4_hdmi->audio.codec;
 	dai_link->platforms	= &vc4_hdmi->audio.platform;
@@ -2374,7 +2337,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 	dai_link->stream_name = "MAI PCM";
 	dai_link->codecs->dai_name = "i2s-hifi";
 	dai_link->cpus->dai_name = dev_name(dev);
-	dai_link->codecs->name = dev_name(&codec_pdev->dev);
+	dai_link->codecs->name = dev_name(&vc4_hdmi->connector.hdmi_audio.codec_pdev->dev);
 	dai_link->platforms->name = dev_name(dev);
 
 	card->dai_link = dai_link;
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index b2424a21da230db99db207efa293417faccd254d..e3d989ca302b72533c374dfa3fd0d5bd7fe64a82 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -104,8 +104,6 @@ struct vc4_hdmi_audio {
 	struct snd_soc_dai_link_component codec;
 	struct snd_soc_dai_link_component platform;
 	struct snd_dmaengine_dai_dma_data dma_data;
-	struct hdmi_audio_infoframe infoframe;
-	struct platform_device *codec_pdev;
 	bool streaming;
 };
 

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:17:06 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:17:06 +0200
Subject: [PATCH v8 09/10] drm/vc4: hdmi: stop rereading EDID in get_modes()
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-9-2399dbae2990@linaro.org>

The vc4_hdmi_connector_detect_ctx() via vc4_hdmi_handle_hotplug()
already reads EDID and propagates it to the drm_connector. Stop
rereading EDID as a part of the .get_modes() callback and just update
the list of modes. This matches the behaviour of the i915 driver.

Acked-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 24199b511f2ee1bc3aa5f4a30e9d3d928d556ff1..5282dd765cc9478361a705dca85f615015b12e8e 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -470,31 +470,10 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
 
 static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
-	const struct drm_edid *drm_edid;
 	int ret = 0;
 
-	/*
-	 * NOTE: This function should really take vc4_hdmi->mutex, but doing so
-	 * results in reentrancy issues since cec_s_phys_addr() might call
-	 * .adap_enable, which leads to that funtion being called with our mutex
-	 * held.
-	 *
-	 * Concurrency isn't an issue at the moment since we don't share
-	 * any state with any of the other frameworks so we can ignore
-	 * the lock for now.
-	 */
-
-	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
-	drm_edid_connector_update(connector, drm_edid);
-	cec_s_phys_addr(vc4_hdmi->cec_adap,
-			connector->display_info.source_physical_address, false);
-	if (!drm_edid)
-		return 0;
-
 	ret = drm_edid_connector_add_modes(connector);
-	drm_edid_free(drm_edid);
 
 	if (!vc4->hvs->vc5_hdmi_enable_hdmi_20) {
 		struct drm_device *drm = connector->dev;

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Fri Dec 20 11:17:07 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 20 Dec 2024 21:17:07 +0200
Subject: [PATCH v8 10/10] drm/vc4: hdmi: use
 drm_atomic_helper_connector_hdmi_hotplug()
In-Reply-To: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
References: <20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990@linaro.org>
Message-ID: <20241220-drm-bridge-hdmi-connector-v8-10-2399dbae2990@linaro.org>

Use the helper function to update the connector's information. This
makes sure that HDMI-related events are handled in a generic way.
Currently it is limited to the HDMI state reporting to the sound system.

Acked-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 5282dd765cc9478361a705dca85f615015b12e8e..82eeb08c183420b000b351da1e05f9a47baeda90 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -383,7 +383,6 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
 				    enum drm_connector_status status)
 {
 	struct drm_connector *connector = &vc4_hdmi->connector;
-	const struct drm_edid *drm_edid;
 	int ret;
 
 	/*
@@ -405,17 +404,14 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
 		return;
 	}
 
-	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
+	drm_atomic_helper_connector_hdmi_hotplug(connector, status);
 
-	drm_edid_connector_update(connector, drm_edid);
 	cec_s_phys_addr(vc4_hdmi->cec_adap,
 			connector->display_info.source_physical_address, false);
 
-	if (!drm_edid)
+	if (status != connector_status_connected)
 		return;
 
-	drm_edid_free(drm_edid);
-
 	for (;;) {
 		ret = vc4_hdmi_reset_link(connector, ctx);
 		if (ret == -EDEADLK) {
@@ -549,6 +545,7 @@ static void vc4_hdmi_connector_reset(struct drm_connector *connector)
 }
 
 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
+	.force = drm_atomic_helper_connector_hdmi_force,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.reset = vc4_hdmi_connector_reset,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,

-- 
2.39.5



From lkp at intel.com  Fri Dec 20 11:30:14 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 03:30:14 +0800
Subject: [PATCH net-next 1/4] net: ti: Kconfig: Select HSR for ICSSG
 Driver
In-Reply-To: <20241216100044.577489-2-danishanwar@ti.com>
References: <20241216100044.577489-2-danishanwar@ti.com>
Message-ID: <202412210336.BmgcX3Td-lkp@intel.com>

Hi MD,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 92c932b9946c1e082406aa0515916adb3e662e24]

url:    https://github.com/intel-lab-lkp/linux/commits/MD-Danish-Anwar/net-ti-Kconfig-Select-HSR-for-ICSSG-Driver/20241216-180412
base:   92c932b9946c1e082406aa0515916adb3e662e24
patch link:    https://lore.kernel.org/r/20241216100044.577489-2-danishanwar%40ti.com
patch subject: [PATCH net-next 1/4] net: ti: Kconfig: Select HSR for ICSSG Driver
config: arm64-kismet-CONFIG_NET_SWITCHDEV-CONFIG_TI_ICSSG_PRUETH-0-0 (https://download.01.org/0day-ci/archive/20241221/202412210336.BmgcX3Td-lkp at intel.com/config)
reproduce: (https://download.01.org/0day-ci/archive/20241221/202412210336.BmgcX3Td-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/202412210336.BmgcX3Td-lkp at intel.com/

kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for NET_SWITCHDEV when selected by TI_ICSSG_PRUETH
   WARNING: unmet direct dependencies detected for NET_SWITCHDEV
     Depends on [n]: NET [=y] && INET [=n]
     Selected by [y]:
     - TI_ICSSG_PRUETH [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_TI [=y] && PRU_REMOTEPROC [=y] && ARCH_K3 [=y] && OF [=y] && TI_K3_UDMA_GLUE_LAYER [=y] && PTP_1588_CLOCK_OPTIONAL [=y]

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


From dave.hansen at intel.com  Fri Dec 20 11:31:51 2024
From: dave.hansen at intel.com (Dave Hansen)
Date: Fri, 20 Dec 2024 11:31:51 -0800
Subject: [PATCH 00/10] Account page tables at all levels
In-Reply-To: <765aec36-55a4-4161-bb30-4ff838bc2d98@arm.com>
References: <20241219164425.2277022-1-kevin.brodsky@arm.com>
 <a7398426-56d1-40b4-a1c9-40ae8c8a4b4b@intel.com>
 <765aec36-55a4-4161-bb30-4ff838bc2d98@arm.com>
Message-ID: <989b55cf-1f9e-4b73-b3dd-d8b6a62be3f2@intel.com>

On 12/20/24 02:58, Kevin Brodsky wrote:
>> One super tiny nit is that the PAE pgd _can_ be allocated using
>> __get_free_pages(). It was originally there for Xen, but I think it's
>> being used for PTI only at this point and the comments are wrong-ish.
>>
>> I kinda think we should just get rid of the 32-bit kmem_cache entirely.
> That would certainly simplify things on the x86 side! I'm not at all
> familiar with that code though, would you be happy with providing a
> patch? I could add it to this series if that's convenient.

I hacked this together yesterday:

> https://git.kernel.org/pub/scm/linux/kernel/git/daveh/devel.git/log/?h=simplify-pae-20241220
It definitely needs some more work. I'm particularly still puzzling
about why SHARED_KERNEL_PMD is used both as a trigger for 32b vs.
PAGE_SIZE PAE pgd allocations _and_ for the actual PMD sharing.

Xen definitely needed the whole page behavior but I'm not sure why PTI did.

Either way, that series should make the PAE PGDs a _bit_ less weird at
the cost of an extra ~2 pages per process for folks who are running
32-bit PAE kernels with PTI disabled.

But I think the diffstat is worth it:

 5 files changed, 16 insertions(+), 96 deletions(-)



From conor at kernel.org  Fri Dec 20 11:41:57 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 20 Dec 2024 19:41:57 +0000
Subject: [PATCH 1/2] dt-bindings: mailbox: add support for referencing
 controllers solely by node
In-Reply-To: <463d5955-a056-40e1-a46e-f89ac0dadccf@linaro.org>
References: <20241219-mbox_request_channel_by_args-v1-0-617a6910f842@linaro.org>
 <20241219-mbox_request_channel_by_args-v1-1-617a6910f842@linaro.org>
 <20241219-recent-everyone-865b19864693@wendy>
 <d9e635c8-de05-4812-bf2b-11651f6da5c1@linaro.org>
 <20241219-strum-cheese-89e5e60d22c3@spud>
 <463d5955-a056-40e1-a46e-f89ac0dadccf@linaro.org>
Message-ID: <20241220-carving-diagram-a27c04aafb10@spud>

On Fri, Dec 20, 2024 at 07:51:32AM +0000, Tudor Ambarus wrote:
> 
> 
> On 12/19/24 6:58 PM, Conor Dooley wrote:
> > On Thu, Dec 19, 2024 at 03:42:11PM +0000, Tudor Ambarus wrote:
> >> Hi, Conor,
> >>
> >> On 12/19/24 2:11 PM, Conor Dooley wrote:
> >>>> There are mailbox clients that can discover the mailbox channel ID at
> >>>> run-time. For such cases passing the channel identifier via DT is
> >>>> redundant. Add support for referencing controllers solely by node.
> >>> I don't really get your implementation, why not just allow #mbox-cells = 0?
> >>> That's what's done for things like fixed frequency clocks that only have
> >>> a single output.
> >>
> >> Ah, indeed!
> >>
> >> instead of:
> >> 	of_parse_phandle(dev->of_node, "mbox", 0);
> >> I can do a:
> >> 	of_parse_phandle_with_args(dev->of_node, "mboxes",
> >>                                    "#mbox-cells", 0, &of_args)
> >> where #mbox-cells = 0;
> >>
> >> Or ... can I pass NULL for cells_name and make the #mbox-cells property
> >> optional and still keeping its requirement of being at least 1?
> > 
> > I think the mbox-cells = 0 approach is preferred, that property is what
> > marks it as a mailbox controller after all. Perhaps Rob or Krzysztof can
> > comment?
> 
> I think using mbox-cells = 0 is better indeed. In my proposal I
> considered the list to always have a single phandle, thus a reference to
> a single mailbox controller, whereas it may be possible that clients to
> reference multiple mailbox controllers. If so, #mbox-cells needs to be
> defined in all the controllers, for consistency reasons, similar to what
> happens with fixed clocks, as you already mentioned.

Oh right, I had totally forgotten about that, that's a solid argument
for the mbox-cells = 0 approach for 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/20241220/ab3799f7/attachment.sig>

From pgwipeout at gmail.com  Fri Dec 20 11:52:09 2024
From: pgwipeout at gmail.com (Peter Geis)
Date: Fri, 20 Dec 2024 14:52:09 -0500
Subject: [PATCH] arm64: dts: rockchip: ROCK3B: Correct clock rates for
 Ethernet PHYs
In-Reply-To: <9a210e3d-90eb-42d4-83fd-7bbad7b00e86@9elements.com>
References: <20241220163227.1501912-1-alicja.michalska@9elements.com>
 <17251add-40b7-4d18-8626-2d74b29532fc@kwiboo.se> <9a210e3d-90eb-42d4-83fd-7bbad7b00e86@9elements.com>
Message-ID: <CAMdYzYoraXsZK3Uwe3QBVjt0cHn_GyOvR=57+qD-UrrwRE2TzA@mail.gmail.com>

Good Afternoon,

On Fri, Dec 20, 2024 at 12:54?PM Alicja Michalska
<alicja.michalska at 9elements.com> wrote:
>
> Hello Jonas,
>
>
> On 20/12/2024 18:09, Jonas Karlman wrote:
> > Have you used mainline or vendor u-boot when testing?
> >
> > There is an existing issue with RTL8211F PHYs that they must be reset
> > before Linux can identify them, see [1] for more details on the issue.
> >
> > Mainline U-Boot will reset the Ethernet PHYs on this board and that
> > should allow for Linux to identify and use the Ethernet PHYs.
> >
> > [1] https://lore.kernel.org/r/47d55aca-bee6-810f-379f-9431649fefa6 at kwiboo.se/
>
> Thank you for the link. I've tested with vendor-provided U-Boot build:
>
> U-Boot latest-2023.10-11-cc60ff40-gcc60ff40 (Aug 14 2024 - 03:56:35 +0000)
>
> I can test with upstream in upcoming days.
>
> > The snps,reset props is deprecated and reset- props should be used in
> > the PHY node.
> >
> > This also changes to use 20/100 ms delay instead of current 20/50ms
> > delay. If anything it could be changed to 20/80ms, I have only seen
> > datasheets for rtl8211f mention minimum 10 ms and minimum 30-76 ms.
> >
> >> +
> >> +    tx_delay = <0x36>;
> >> +    rx_delay = <0x2d>;
> > Are you having issue with use of rgmii-id on your board?
>
> Interesting insight, thank you!
>
> I have to admit that I haven't read the current documentation, just seen that other RK356X boards in the tree used it. My apologies.
>
> I've ran into issues with rgmii-id, but that's with vendor U-Boot (as mentioned above), will try with upstream next and see a follow-up if I will still experience issues.

rgmii-id sets the phy to handle the tx and rx delays. All of the
various rgmii settings require the board to be built to specific
tolerances for the data lines. Rockchip based boards seem to forgo
this design phase, instead using rgmii (no built in delays) and set
the delays in the Rockchip gmac driver instead, using the tx_delay and
rx_delay values in the device tree. The tx_delay and rx_delay value
must be tuned correctly for your hardware. If you wish to use them
you'll need to set rgmii, then find the lowest and highest values that
work for all variations of hardware supported by the device tree then
take the middle value. If you wish to use rgmii-id, these values
should be omitted or set to zero as they are additive to the existing
delays.

>
> >> +
> >>      status = "okay";
> >>  };
> >>
> >>  &gmac1 {
> >>      assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
> >>      assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
> >> -    clock_in_out = "input";
> >> -    phy-handle = <&rgmii_phy1>;
> >> -    phy-mode = "rgmii-id";
> >> +    assigned-clock-rates = <0>, <125000000>;
> >> +    clock_in_out = "output";

Instead, I suspect the clocks here are your issue. Looking at the
schematic at [1] your board is designed to feed the phy clock into the
SoC. This isn't the current clock configuration in your device tree,
you had it set to input, but the clock parents are wrong and will
default to using the internal SoC clock source for the mac. I suspect
setting the assigned clock rate is what fixed your issue.

I wrote the rk3566-quartz64-a.dts to be an example for how the new soc
behaves. I recommend looking at it for an example for how the clocks
are supposed to be set up for proper input [2].

> >>      phy-supply = <&vcc_3v3>;
> >> +    phy-mode = "rgmii";
> >> +    phy-handle = <&rgmii_phy1>;
> >>      pinctrl-names = "default";
> >>      pinctrl-0 = <&gmac1m1_miim
> >>                   &gmac1m1_tx_bus2
> >>                   &gmac1m1_rx_bus2
> >>                   &gmac1m1_rgmii_clk
> >> -                 &gmac1m1_rgmii_bus
> >> -                 &gmac1m1_clkinout>;
> >> +                 &gmac1m1_rgmii_bus>;
> >> +    snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
> >> +    snps,reset-active-low;
> >> +    snps,reset-delays-us = <0 50000 150000>;
> > Same here, but now this is 50/150 ms?
> I wasn't sure about those delays, as I've taken them from vendor's sources. They did seem awfully high, though.
> >> +
> >> +    tx_delay = <0x47>;
> >> +    rx_delay = <0x28>;
> > Same here, is use of rgmii-id causing issues on your boards?
> Answer above :)
> >> +
> >>      status = "okay";
> >>  };
> >>
> >> +&mdio0 {
> >> +    rgmii_phy0: ethernet-phy at 0 {
> >> +            compatible = "ethernet-phy-ieee802.3-c22";
> >> +            reg = <0>;
> > The phy addr used for these boards is 0x1.
> >
> >> +    };
> >> +};
> >> +
> >> +&mdio1 {
> >> +    rgmii_phy1: ethernet-phy at 0 {
> >> +            compatible = "ethernet-phy-ieee802.3-c22";
> >> +            reg = <0>;
> > Same here.
> Makes sense, other boards in the tree had it configured the same way.
> >> +    };
> >> +};
> > There should be no need to move these nodes, they should already be in
> > alphabetical order?
> There's no reason to, just thought moving them closer to PHYs would look cleaner and make a bit more sense. It's just a nitpick though.
> >> +
> >>  &gpu {
> >>      mali-supply = <&vdd_gpu>;
> >>      status = "okay";
> >> @@ -512,26 +540,6 @@ &i2s1m0_sdi0
> >>      status = "okay";
> >>  };
> >>
> >> -&mdio0 {
> >> -    rgmii_phy0: ethernet-phy at 1 {
> >> -            compatible = "ethernet-phy-ieee802.3-c22";
> > If you want to use vendor u-boot you can probably change this to
> > "ethernet-phy-id001c.c916".
> >
> >> -            reg = <1>;
> >> -            reset-assert-us = <20000>;
> >> -            reset-deassert-us = <50000>;
> >> -            reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
> >> -    };
> >> -};
> >> -
> >> -&mdio1 {
> >> -    rgmii_phy1: ethernet-phy at 1 {
> >> -            compatible = "ethernet-phy-ieee802.3-c22";
> > Same here.
>
> True, but in this case it likely wouldn't be accepted in upstream, right?
>
> I really would prefer devicetrees to be passed to the OS by bootloader, just like ACPI does on x86 and some (i.e Ampere) platforms.
>
> This way we wouldn't need to maintain per-board DTs in the tree, and would keep functionality between kernel versions/BSDs... but one can dream, huh? :)

The device-tree is supposed to describe hardware without regards to a
specific operating system. If written correctly, it will work no
matter what software is running on top of it. While there are some
specific tweaks to make the operating systems behave correctly around
broken hardware, a lot of the deviations from this standard are due to
legacy trees and are being cleaned up over time.

>
> Thank you,
>
> Alicja

Very Respectfully,
Peter Geis

[1] https://dl.radxa.com/rock3/docs/hw/3b/Radxa_ROCK_3B_V1.51_SCH.pdf
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts?h=v6.13-rc3#n267

>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From maxime.chevallier at bootlin.com  Fri Dec 20 12:15:01 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 20 Dec 2024 21:15:01 +0100
Subject: [PATCH net-next RFC 2/5] net: ethtool: Introduce ETHTOOL_LINK_MEDIUM_* values
In-Reply-To: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
References: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
Message-ID: <20241220201506.2791940-3-maxime.chevallier@bootlin.com>

In an effort to have a better representation of Ethernet ports,
introduce enumeration values representing the various ethernet Mediums.

This is part of the 802.3 naming convention, for example :

1000 Base T 4
 |    |   | |
 |    |   | \_ lanes (4)
 |    |   \___ Medium (T == Twisted Copper Pairs)
 |    \_______ Baseband transmission
 \____________ Speed

 Other example :

10000 Base K X 4
           | | \_ lanes (4)
           | \___ encoding (BaseX is 8b/10b while BaseR is 66b/64b)
           \_____ Medium (K is backplane ethernet)

In the case of representing a physical port, only the medium and number
of lanes should be relevant. One exception would be 1000BaseX, which is
currently also used as a medium in what appears to be any of
1000BaseSX, 1000BaseFX, 1000BaseCX and 1000BaseLX.

These mediums are set in the net/ethtool/common.c lookup table that
maintains a list of all linkmodes with their number of lanes, medium,
encoding, speed and duplex.

One notable exception to this is 100M BaseT Ethernet. 100BaseTX is a 2-lanes
protocol but it will also work on 4-lanes cables, so the lookup table
contains 2 sets of lane numbers, indicating the min number of lanes for
a protocol to work and the "nominal" number of lanes as well.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
 include/linux/ethtool.h |  48 ++++++++++
 net/ethtool/common.c    | 194 +++++++++++++++++++++-------------------
 net/ethtool/common.h    |   2 +
 3 files changed, 153 insertions(+), 91 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index f711bfd75c4d..dc02a1bef549 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -203,6 +203,54 @@ static inline u8 *ethtool_rxfh_context_key(struct ethtool_rxfh_context *ctx)
 
 void ethtool_rxfh_context_lost(struct net_device *dev, u32 context_id);
 
+enum ethtool_link_medium {
+	ETHTOOL_LINK_MEDIUM_BASET = 0,
+	ETHTOOL_LINK_MEDIUM_BASEK,
+	ETHTOOL_LINK_MEDIUM_BASES,
+	ETHTOOL_LINK_MEDIUM_BASEC,
+	ETHTOOL_LINK_MEDIUM_BASEL,
+	ETHTOOL_LINK_MEDIUM_BASED,
+	ETHTOOL_LINK_MEDIUM_BASEE,
+	ETHTOOL_LINK_MEDIUM_BASEF,
+	ETHTOOL_LINK_MEDIUM_BASEV,
+	ETHTOOL_LINK_MEDIUM_BASEMLD, /* I don't know what that is */
+	ETHTOOL_LINK_MEDIUM_BASEX, /* Not a true medium, but abused... */
+	ETHTOOL_LINK_MEDIUM_NONE,
+
+	__ETHTOOL_LINK_MEDIUM_LAST,
+};
+
+static inline const char *phy_mediums(enum ethtool_link_medium medium)
+{
+	switch (medium) {
+	case ETHTOOL_LINK_MEDIUM_BASET:
+		return "BaseT";
+	case ETHTOOL_LINK_MEDIUM_BASEK:
+		return "BaseK";
+	case ETHTOOL_LINK_MEDIUM_BASES:
+		return "BaseS";
+	case ETHTOOL_LINK_MEDIUM_BASEC:
+		return "BaseC";
+	case ETHTOOL_LINK_MEDIUM_BASEL:
+		return "BaseL";
+	case ETHTOOL_LINK_MEDIUM_BASED:
+		return "BaseD";
+	case ETHTOOL_LINK_MEDIUM_BASEE:
+		return "BaseE";
+	case ETHTOOL_LINK_MEDIUM_BASEF:
+		return "BaseF";
+	case ETHTOOL_LINK_MEDIUM_BASEV:
+		return "BaseV";
+	case ETHTOOL_LINK_MEDIUM_BASEMLD:
+		return "BaseMLD";
+	case ETHTOOL_LINK_MEDIUM_BASEX:
+		return "BaseX";
+	case ETHTOOL_LINK_MEDIUM_NONE:
+		return "None";
+	default: return "unknown";
+	}
+}
+
 /* declare a link mode bitmap */
 #define __ETHTOOL_DECLARE_LINK_MODE_MASK(name)		\
 	DECLARE_BITMAP(name, __ETHTOOL_LINK_MODE_MASK_NBITS)
diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index 5a9c09ce57d5..41e7598f6ed7 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -255,11 +255,22 @@ static_assert(ARRAY_SIZE(link_mode_names) == __ETHTOOL_LINK_MODE_MASK_NBITS);
 #define __LINK_MODE_LANES_DR8_2		8
 #define __LINK_MODE_LANES_T1BRR		1
 
-#define __DEFINE_LINK_MODE_PARAMS(_speed, _type, _duplex)	\
+#define __DEFINE_LINK_MODE_PARAMS_LANES(_speed, _type, _min_lanes, _lanes, _duplex, _medium) \
 	[ETHTOOL_LINK_MODE(_speed, _type, _duplex)] = {		\
 		.speed  = SPEED_ ## _speed, \
+		.min_lanes  = _min_lanes, \
+		.lanes  = _lanes, \
+		.duplex	= __DUPLEX_ ## _duplex, \
+		.medium = ETHTOOL_LINK_MEDIUM_BASE ## _medium \
+	}
+
+#define __DEFINE_LINK_MODE_PARAMS(_speed, _type, _duplex, _medium)	\
+	[ETHTOOL_LINK_MODE(_speed, _type, _duplex)] = {		\
+		.speed  = SPEED_ ## _speed, \
+		.min_lanes  = __LINK_MODE_LANES_ ## _type, \
 		.lanes  = __LINK_MODE_LANES_ ## _type, \
-		.duplex	= __DUPLEX_ ## _duplex \
+		.duplex	= __DUPLEX_ ## _duplex, \
+		.medium = ETHTOOL_LINK_MEDIUM_BASE ## _medium \
 	}
 #define __DUPLEX_Half DUPLEX_HALF
 #define __DUPLEX_Full DUPLEX_FULL
@@ -268,116 +279,117 @@ static_assert(ARRAY_SIZE(link_mode_names) == __ETHTOOL_LINK_MODE_MASK_NBITS);
 		.speed	= SPEED_UNKNOWN, \
 		.lanes	= 0, \
 		.duplex	= DUPLEX_UNKNOWN, \
+		.medium	= ETHTOOL_LINK_MEDIUM_NONE, \
 	}
 
 const struct link_mode_info link_mode_params[] = {
-	__DEFINE_LINK_MODE_PARAMS(10, T, Half),
-	__DEFINE_LINK_MODE_PARAMS(10, T, Full),
-	__DEFINE_LINK_MODE_PARAMS(100, T, Half),
-	__DEFINE_LINK_MODE_PARAMS(100, T, Full),
-	__DEFINE_LINK_MODE_PARAMS(1000, T, Half),
-	__DEFINE_LINK_MODE_PARAMS(1000, T, Full),
+	__DEFINE_LINK_MODE_PARAMS_LANES(10, T, 2, 4, Half, T),
+	__DEFINE_LINK_MODE_PARAMS_LANES(10, T, 2, 4, Full, T),
+	__DEFINE_LINK_MODE_PARAMS_LANES(100, T, 2, 4, Half, T),
+	__DEFINE_LINK_MODE_PARAMS_LANES(100, T, 2, 4, Full, T),
+	__DEFINE_LINK_MODE_PARAMS(1000, T, Half, T),
+	__DEFINE_LINK_MODE_PARAMS(1000, T, Full, T),
 	__DEFINE_SPECIAL_MODE_PARAMS(Autoneg),
 	__DEFINE_SPECIAL_MODE_PARAMS(TP),
 	__DEFINE_SPECIAL_MODE_PARAMS(AUI),
 	__DEFINE_SPECIAL_MODE_PARAMS(MII),
 	__DEFINE_SPECIAL_MODE_PARAMS(FIBRE),
 	__DEFINE_SPECIAL_MODE_PARAMS(BNC),
-	__DEFINE_LINK_MODE_PARAMS(10000, T, Full),
+	__DEFINE_LINK_MODE_PARAMS(10000, T, Full, T),
 	__DEFINE_SPECIAL_MODE_PARAMS(Pause),
 	__DEFINE_SPECIAL_MODE_PARAMS(Asym_Pause),
-	__DEFINE_LINK_MODE_PARAMS(2500, X, Full),
+	__DEFINE_LINK_MODE_PARAMS(2500, X, Full, X),
 	__DEFINE_SPECIAL_MODE_PARAMS(Backplane),
-	__DEFINE_LINK_MODE_PARAMS(1000, KX, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, KX4, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, KR, Full),
+	__DEFINE_LINK_MODE_PARAMS(1000, KX, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(10000, KX4, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(10000, KR, Full, K),
 	[ETHTOOL_LINK_MODE_10000baseR_FEC_BIT] = {
 		.speed	= SPEED_10000,
 		.lanes	= 1,
 		.duplex = DUPLEX_FULL,
 	},
-	__DEFINE_LINK_MODE_PARAMS(20000, MLD2, Full),
-	__DEFINE_LINK_MODE_PARAMS(20000, KR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(40000, KR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(40000, CR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(40000, SR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(40000, LR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(56000, KR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(56000, CR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(56000, SR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(56000, LR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(25000, CR, Full),
-	__DEFINE_LINK_MODE_PARAMS(25000, KR, Full),
-	__DEFINE_LINK_MODE_PARAMS(25000, SR, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, CR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, KR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, KR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, SR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, CR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, LR4_ER4, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, SR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(1000, X, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, CR, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, SR, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, LR, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, LRM, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, ER, Full),
-	__DEFINE_LINK_MODE_PARAMS(2500, T, Full),
-	__DEFINE_LINK_MODE_PARAMS(5000, T, Full),
+	__DEFINE_LINK_MODE_PARAMS(20000, MLD2, Full, MLD),
+	__DEFINE_LINK_MODE_PARAMS(20000, KR2, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(40000, KR4, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(40000, CR4, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(40000, SR4, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(40000, LR4, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(56000, KR4, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(56000, CR4, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(56000, SR4, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(56000, LR4, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(25000, CR, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(25000, KR, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(25000, SR, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(50000, CR2, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(50000, KR2, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(100000, KR4, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(100000, SR4, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(100000, CR4, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(100000, LR4_ER4, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(50000, SR2, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(1000, X, Full, X), /* :( */
+	__DEFINE_LINK_MODE_PARAMS(10000, CR, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(10000, SR, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(10000, LR, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(10000, LRM, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(10000, ER, Full, E),
+	__DEFINE_LINK_MODE_PARAMS(2500, T, Full, T),
+	__DEFINE_LINK_MODE_PARAMS(5000, T, Full, T),
 	__DEFINE_SPECIAL_MODE_PARAMS(FEC_NONE),
 	__DEFINE_SPECIAL_MODE_PARAMS(FEC_RS),
 	__DEFINE_SPECIAL_MODE_PARAMS(FEC_BASER),
-	__DEFINE_LINK_MODE_PARAMS(50000, KR, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, SR, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, CR, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, LR_ER_FR, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, DR, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, KR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, SR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, CR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, LR2_ER2_FR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, DR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, KR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, SR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, LR4_ER4_FR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, DR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, CR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100, T1, Full),
-	__DEFINE_LINK_MODE_PARAMS(1000, T1, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, KR8, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, SR8, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, LR8_ER8_FR8, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, DR8, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, CR8, Full),
+	__DEFINE_LINK_MODE_PARAMS(50000, KR, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(50000, SR, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(50000, CR, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(50000, LR_ER_FR, Full, L), /* I guess ? */
+	__DEFINE_LINK_MODE_PARAMS(50000, DR, Full, D),
+	__DEFINE_LINK_MODE_PARAMS(100000, KR2, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(100000, SR2, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(100000, CR2, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(100000, LR2_ER2_FR2, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(100000, DR2, Full, D),
+	__DEFINE_LINK_MODE_PARAMS(200000, KR4, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(200000, SR4, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(200000, LR4_ER4_FR4, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(200000, DR4, Full, D),
+	__DEFINE_LINK_MODE_PARAMS(200000, CR4, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(100, T1, Full, T),
+	__DEFINE_LINK_MODE_PARAMS(1000, T1, Full, T),
+	__DEFINE_LINK_MODE_PARAMS(400000, KR8, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(400000, SR8, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(400000, LR8_ER8_FR8, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(400000, DR8, Full, D),
+	__DEFINE_LINK_MODE_PARAMS(400000, CR8, Full, C),
 	__DEFINE_SPECIAL_MODE_PARAMS(FEC_LLRS),
-	__DEFINE_LINK_MODE_PARAMS(100000, KR, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, SR, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, LR_ER_FR, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, DR, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, CR, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, KR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, SR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, LR2_ER2_FR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, DR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, CR2, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, KR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, SR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, LR4_ER4_FR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, DR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, CR4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100, FX, Half),
-	__DEFINE_LINK_MODE_PARAMS(100, FX, Full),
-	__DEFINE_LINK_MODE_PARAMS(10, T1L, Full),
-	__DEFINE_LINK_MODE_PARAMS(800000, CR8, Full),
-	__DEFINE_LINK_MODE_PARAMS(800000, KR8, Full),
-	__DEFINE_LINK_MODE_PARAMS(800000, DR8, Full),
-	__DEFINE_LINK_MODE_PARAMS(800000, DR8_2, Full),
-	__DEFINE_LINK_MODE_PARAMS(800000, SR8, Full),
-	__DEFINE_LINK_MODE_PARAMS(800000, VR8, Full),
-	__DEFINE_LINK_MODE_PARAMS(10, T1S, Full),
-	__DEFINE_LINK_MODE_PARAMS(10, T1S, Half),
-	__DEFINE_LINK_MODE_PARAMS(10, T1S_P2MP, Half),
-	__DEFINE_LINK_MODE_PARAMS(10, T1BRR, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, KR, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(100000, SR, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(100000, LR_ER_FR, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(100000, DR, Full, D),
+	__DEFINE_LINK_MODE_PARAMS(100000, CR, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(200000, KR2, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(200000, SR2, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(200000, LR2_ER2_FR2, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(200000, DR2, Full, D),
+	__DEFINE_LINK_MODE_PARAMS(200000, CR2, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(400000, KR4, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(400000, SR4, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(400000, LR4_ER4_FR4, Full, L),
+	__DEFINE_LINK_MODE_PARAMS(400000, DR4, Full, D),
+	__DEFINE_LINK_MODE_PARAMS(400000, CR4, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(100, FX, Half, F),
+	__DEFINE_LINK_MODE_PARAMS(100, FX, Full, F),
+	__DEFINE_LINK_MODE_PARAMS(10, T1L, Full, T),
+	__DEFINE_LINK_MODE_PARAMS(800000, CR8, Full, C),
+	__DEFINE_LINK_MODE_PARAMS(800000, KR8, Full, K),
+	__DEFINE_LINK_MODE_PARAMS(800000, DR8, Full, D),
+	__DEFINE_LINK_MODE_PARAMS(800000, DR8_2, Full, D),
+	__DEFINE_LINK_MODE_PARAMS(800000, SR8, Full, S),
+	__DEFINE_LINK_MODE_PARAMS(800000, VR8, Full, V),
+	__DEFINE_LINK_MODE_PARAMS(10, T1S, Full, T),
+	__DEFINE_LINK_MODE_PARAMS(10, T1S, Half, T),
+	__DEFINE_LINK_MODE_PARAMS(10, T1S_P2MP, Half, T),
+	__DEFINE_LINK_MODE_PARAMS(10, T1BRR, Full, T),
 };
 static_assert(ARRAY_SIZE(link_mode_params) == __ETHTOOL_LINK_MODE_MASK_NBITS);
 
diff --git a/net/ethtool/common.h b/net/ethtool/common.h
index 850eadde4bfc..b25011a05fea 100644
--- a/net/ethtool/common.h
+++ b/net/ethtool/common.h
@@ -16,8 +16,10 @@
 
 struct link_mode_info {
 	int				speed;
+	u8				min_lanes;
 	u8				lanes;
 	u8				duplex;
+	enum ethtool_link_medium	medium;
 };
 
 struct genl_info;
-- 
2.47.1



From maxime.chevallier at bootlin.com  Fri Dec 20 12:15:03 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 20 Dec 2024 21:15:03 +0100
Subject: [PATCH net-next RFC 4/5] net: phy: Introduce PHY ports representation
In-Reply-To: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
References: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
Message-ID: <20241220201506.2791940-5-maxime.chevallier@bootlin.com>

Ethernet provides a wide variety of layer 1 protocols and standards for
data transmission. The front-facing ports of an interface have their own
complexity and configurability.

Introduce a representation of these front-facing ports. The current code
is minimalistic and only support ports controlled by PHY devices, but
the plan is to extend that to SFP as well as raw Ethernet MACs that
don't use PHY devices.

This minimal port representation allows describing the media and number
of lanes of a port. From that information, we can derive the linkmodes
usable on the port, which can be used to limit the capabilities of an
interface.

For now, the port lanes and medium is derived from devicetree, defined
by the PHY driver, or populated with default values (as we assume that
all PHYs expose at least one port).

The typical example is 100M ethernet. 100BaseT can work using only 2
lanes on a Cat 5 cables. However, in the situation where a 10/100/1000
capable PHY is wired to its RJ45 port through 2 lanes only, we have no
way of detecting that. The "max-speed" DT property can be used, but a
more accurate representation can be used :

mdi {
	port at 0 {
		media = "BaseT";
		lanes = <2>;
	};
};

>From that information, we can derive the max speed reachable on the
port.

Another benefit of having that is to avoid vendor-specific DT properties
(micrel,fiber-mode or ti,fiber-mode).

This basic representation is meant to be expanded, by the introduction
of port ops, userspace listing of ports, and support for multi-port
devices.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
 drivers/net/phy/Makefile     |   2 +-
 drivers/net/phy/phy_device.c | 167 +++++++++++++++++++++++++++++++++++
 drivers/net/phy/phy_port.c   | 159 +++++++++++++++++++++++++++++++++
 include/linux/ethtool.h      |   4 +
 include/linux/phy.h          |  31 +++++++
 include/linux/phy_port.h     |  69 +++++++++++++++
 6 files changed, 431 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/phy_port.c
 create mode 100644 include/linux/phy_port.h

diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index e6145153e837..1e324d3ad839 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 phy_link_topology.o
+				   linkmode.o phy_link_topology.o phy_port.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 928dc3c509b6..42cce18970e2 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -706,6 +706,13 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
 
 	dev->state = PHY_DOWN;
 	INIT_LIST_HEAD(&dev->leds);
+	INIT_LIST_HEAD(&dev->ports);
+
+	/* The driver's probe function must change that to the real number
+	 * of ports possible on the PHY. We assume by default we are dealing
+	 * with a single-port PHY
+	 */
+	dev->max_n_ports = 1;
 
 	mutex_init(&dev->lock);
 	INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
@@ -3454,6 +3461,159 @@ static int of_phy_leds(struct phy_device *phydev)
 	return 0;
 }
 
+static int phy_add_port(struct phy_device *phydev, struct phy_port *port)
+{
+	int ret = 0;
+
+	if (phydev->n_ports == phydev->max_n_ports)
+		return -EBUSY;
+
+	/* We set all ports as active by default, PHY drivers may deactivate
+	 * them (when unused)
+	 */
+	port->active = true;
+
+	if (phydev->drv && phydev->drv->attach_port)
+		ret = phydev->drv->attach_port(phydev, port);
+
+	if (ret)
+		return ret;
+
+	/* The PHY driver might have added, removed or set medium/lanes info,
+	 * so update the port supported accordingly.
+	 */
+	phy_port_update_supported(port);
+
+	list_add(&port->head, &phydev->ports);
+
+	phydev->n_ports++;
+
+	return 0;
+}
+
+static void phy_del_port(struct phy_device *phydev, struct phy_port *port)
+{
+	if (!phydev->n_ports)
+		return;
+
+	list_del(&port->head);
+
+	phydev->n_ports--;
+}
+
+static void phy_cleanup_ports(struct phy_device *phydev)
+{
+	struct phy_port *tmp, *port;
+
+	list_for_each_entry_safe(port, tmp, &phydev->ports, head) {
+		phy_del_port(phydev, port);
+		phy_port_destroy(port);
+	}
+}
+
+static int phy_default_setup_single_port(struct phy_device *phydev)
+{
+	struct phy_port *port = phy_port_alloc();
+
+	if (!port)
+		return -ENOMEM;
+
+	port->parent_type = PHY_PORT_PHY;
+	port->phy = phydev;
+	linkmode_copy(port->supported, phydev->supported);
+
+	/* default medium is copper */
+	if (!port->mediums)
+		port->mediums |= BIT(ETHTOOL_LINK_MEDIUM_BASET);
+
+	phy_add_port(phydev, port);
+
+	return 0;
+}
+
+static int of_phy_ports(struct phy_device *phydev)
+{
+	struct device_node *node = phydev->mdio.dev.of_node;
+	struct device_node *mdi;
+	struct phy_port *port;
+	int err;
+
+	if (!IS_ENABLED(CONFIG_OF_MDIO))
+		return 0;
+
+	if (!node)
+		return 0;
+
+	mdi = of_get_child_by_name(node, "mdi");
+	if (!mdi)
+		return 0;
+
+	for_each_available_child_of_node_scoped(mdi, port_node) {
+		port = phy_of_parse_port(port_node);
+		if (IS_ERR(port)) {
+			err = PTR_ERR(port);
+			goto out_err;
+		}
+
+		port->parent_type = PHY_PORT_PHY;
+		port->phy = phydev;
+		err = phy_add_port(phydev, port);
+		if (err)
+			goto out_err;
+	}
+	of_node_put(mdi);
+
+	return 0;
+
+out_err:
+	phy_cleanup_ports(phydev);
+	of_node_put(mdi);
+	return err;
+}
+
+static int phy_setup_ports(struct phy_device *phydev)
+{
+	__ETHTOOL_DECLARE_LINK_MODE_MASK(ports_supported);
+	struct phy_port *port;
+	int ret;
+
+	ret = of_phy_ports(phydev);
+	if (ret)
+		return ret;
+
+	if (phydev->n_ports < phydev->max_n_ports) {
+		ret = phy_default_setup_single_port(phydev);
+		if (ret)
+			goto out;
+	}
+
+	linkmode_zero(ports_supported);
+
+	/* Aggregate the supported modes, which are made-up of :
+	 *  - What the PHY itself supports
+	 *  - What the sum of all ports support
+	 */
+	list_for_each_entry(port, &phydev->ports, head)
+		if (port->active)
+			linkmode_or(ports_supported, ports_supported,
+				    port->supported);
+
+	if (!linkmode_empty(ports_supported))
+		linkmode_and(phydev->supported, phydev->supported,
+			     ports_supported);
+
+	/* For now, the phy->port field is set as the first active port's type */
+	list_for_each_entry(port, &phydev->ports, head)
+		if (port->active)
+			phydev->port = phy_port_get_type(port);
+
+	return 0;
+
+out:
+	phy_cleanup_ports(phydev);
+	return ret;
+}
+
 /**
  * fwnode_mdio_find_device - Given a fwnode, find the mdio_device
  * @fwnode: pointer to the mdio_device's fwnode
@@ -3603,6 +3763,11 @@ static int phy_probe(struct device *dev)
 		phydev->is_gigabit_capable = 1;
 
 	of_set_phy_supported(phydev);
+
+	err = phy_setup_ports(phydev);
+	if (err)
+		goto out;
+
 	phy_advertise_supported(phydev);
 
 	/* Get PHY default EEE advertising modes and handle them as potentially
@@ -3679,6 +3844,8 @@ static int phy_remove(struct device *dev)
 
 	phydev->state = PHY_DOWN;
 
+	phy_cleanup_ports(phydev);
+
 	sfp_bus_del_upstream(phydev->sfp_bus);
 	phydev->sfp_bus = NULL;
 
diff --git a/drivers/net/phy/phy_port.c b/drivers/net/phy/phy_port.c
new file mode 100644
index 000000000000..d89c572623d7
--- /dev/null
+++ b/drivers/net/phy/phy_port.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Framework to drive Ethernet ports
+ *
+ * Copyright (c) 2024 Maxime Chevallier <maxime.chevallier at bootlin.com>
+ */
+
+#include <linux/linkmode.h>
+#include <linux/of.h>
+#include <linux/phy_port.h>
+
+/**
+ * phy_port_alloc: Allocate a new phy_port
+ *
+ * Returns a newly allocated struct phy_port, or NULL.
+ */
+struct phy_port *phy_port_alloc(void)
+{
+	struct phy_port *port;
+
+	port = kzalloc(sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return NULL;
+
+	linkmode_zero(port->supported);
+	INIT_LIST_HEAD(&port->head);
+
+	return port;
+}
+EXPORT_SYMBOL_GPL(phy_port_alloc);
+
+/**
+ * phy_port_destroy: Free a struct phy_port
+ */
+void phy_port_destroy(struct phy_port *port)
+{
+	kfree(port);
+}
+EXPORT_SYMBOL_GPL(phy_port_destroy);
+
+static void ethtool_medium_get_supported(unsigned long *supported,
+					 enum ethtool_link_medium medium,
+					 int lanes)
+{
+	int i;
+
+	for (i = 0; i < __ETHTOOL_LINK_MODE_MASK_NBITS; i++) {
+		/* Special bits such as Autoneg, Pause, Asym_pause, etc. are
+		 * set and will be masked away by the port parent.
+		 */
+		if (link_mode_params[i].medium == ETHTOOL_LINK_MEDIUM_NONE) {
+			linkmode_set_bit(i, supported);
+			continue;
+		}
+
+		/* For most cases, min_lanes == lanes, except for 10/100BaseT that work
+		 * on 2 lanes but are compatible with 4 lanes mediums
+		 */
+		if (link_mode_params[i].medium == medium &&
+		    link_mode_params[i].lanes >= lanes &&
+		    link_mode_params[i].min_lanes <= lanes) {
+			linkmode_set_bit(i, supported);
+		}
+	}
+}
+
+static enum ethtool_link_medium ethtool_str_to_medium(const char *str)
+{
+	int i;
+
+	for (i = 0; i < __ETHTOOL_LINK_MEDIUM_LAST; i++)
+		if (!strcmp(phy_mediums(i), str))
+			return i;
+
+	return ETHTOOL_LINK_MEDIUM_NONE;
+}
+
+/**
+ * phy_of_parse_port: Create a phy_port from a firmware representation
+ *
+ * Returns a newly allocated and initialized phy_port pointer, or an ERR_PTR.
+ */
+struct phy_port *phy_of_parse_port(struct device_node *dn)
+{
+	struct fwnode_handle *fwnode = of_fwnode_handle(dn);
+	enum ethtool_link_medium medium;
+	struct phy_port *port;
+	struct property *prop;
+	const char *med_str;
+	u32 lanes, mediums = 0;
+	int ret;
+
+	ret = fwnode_property_read_u32(fwnode, "lanes", &lanes);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = fwnode_property_read_string(fwnode, "media", &med_str);
+	if (ret)
+		return ERR_PTR(ret);
+
+	of_property_for_each_string(to_of_node(fwnode), "media", prop, med_str) {
+		medium = ethtool_str_to_medium(med_str);
+		if (medium == ETHTOOL_LINK_MEDIUM_NONE)
+			return ERR_PTR(-EINVAL);
+
+		mediums |= BIT(medium);
+	}
+
+	if (!mediums)
+		return ERR_PTR(-EINVAL);
+
+	port = phy_port_alloc();
+	if (!port)
+		return ERR_PTR(-ENOMEM);
+
+	port->lanes = lanes;
+	port->mediums = mediums;
+
+	return port;
+}
+EXPORT_SYMBOL_GPL(phy_of_parse_port);
+
+/**
+ * phy_port_update_supported: Setup the port->supported field
+ * port: the port to update
+ *
+ * Once the port's medium list and number of lanes has been configured based
+ * on firmware, straps and vendor-specific properties, this function may be
+ * called to update the port's supported linkmodes list.
+ *
+ * Any mode that was manually set in the port's supported list remains set.
+ */
+void phy_port_update_supported(struct phy_port *port)
+{
+	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
+	int i;
+
+	for_each_set_bit(i, &port->mediums, __ETHTOOL_LINK_MEDIUM_LAST) {
+		linkmode_zero(supported);
+		ethtool_medium_get_supported(supported, i, port->lanes);
+		linkmode_or(port->supported, port->supported, supported);
+	}
+}
+EXPORT_SYMBOL_GPL(phy_port_update_supported);
+
+/**
+ * phy_port_get_type: get the PORT_* attribut for that port.
+ */
+int phy_port_get_type(struct phy_port *port)
+{
+	if (port->mediums & ETHTOOL_LINK_MEDIUM_BASET)
+		return PORT_TP;
+
+	if (phy_port_is_fiber(port) ||
+	    (port->mediums & BIT(ETHTOOL_LINK_MEDIUM_BASEX)))
+		return PORT_FIBRE;
+
+	return PORT_OTHER;
+}
+EXPORT_SYMBOL_GPL(phy_port_get_type);
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 51d110dfa8ef..fdb47cfd8c79 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -220,6 +220,10 @@ enum ethtool_link_medium {
 	__ETHTOOL_LINK_MEDIUM_LAST,
 };
 
+#define ETHTOOL_MEDIUM_FIBER_BITS (BIT(ETHTOOL_LINK_MEDIUM_BASES) | \
+				   BIT(ETHTOOL_LINK_MEDIUM_BASEL) | \
+				   BIT(ETHTOOL_LINK_MEDIUM_BASEF))
+
 static inline const char *phy_mediums(enum ethtool_link_medium medium)
 {
 	switch (medium) {
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 5bc71d59910c..14ba3eca7382 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -21,6 +21,7 @@
 #include <linux/mii.h>
 #include <linux/mii_timestamper.h>
 #include <linux/module.h>
+#include <linux/phy_port.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 #include <linux/mod_devicetable.h>
@@ -660,6 +661,9 @@ struct macsec_ops;
  * @master_slave_state: Current master/slave configuration
  * @mii_ts: Pointer to time stamper callbacks
  * @psec: Pointer to Power Sourcing Equipment control struct
+ * @ports: List of PHY ports structures
+ * n_ports: Number of ports currently attached to the PHY
+ * @max_n_ports: Max number of ports this PHY can expose
  * @lock:  Mutex for serialization access to PHY
  * @state_queue: Work queue for state machine
  * @link_down_events: Number of times link was lost
@@ -752,6 +756,7 @@ struct phy_device {
 
 	/* Host supported PHY interface types. Should be ignored if empty. */
 	DECLARE_PHY_INTERFACE_MASK(host_interfaces);
+	DECLARE_PHY_INTERFACE_MASK(sfp_bus_interfaces);
 
 #ifdef CONFIG_LED_TRIGGER_PHY
 	struct phy_led_trigger *phy_led_triggers;
@@ -794,6 +799,10 @@ struct phy_device {
 	struct mii_timestamper *mii_ts;
 	struct pse_control *psec;
 
+	struct list_head ports;
+	int n_ports;
+	int max_n_ports;
+
 	u8 mdix;
 	u8 mdix_ctrl;
 
@@ -1244,6 +1253,27 @@ struct phy_driver {
 	 */
 	int (*led_polarity_set)(struct phy_device *dev, int index,
 				unsigned long modes);
+
+	/**
+	 * @attach_port: Indicates to the PHY driver that a port is detected
+	 * @dev: PHY device to notify
+	 * @port: The port being added
+	 *
+	 * Called when a port that needs to be driven by the PHY is found. The
+	 * number of time this will be called depends on phydev->max_n_ports,
+	 * which the driver can change in .probe().
+	 *
+	 * The port that is being passed may or may not be initialized. If it is
+	 * already initialized, it is by the generic port representation from
+	 * devicetree, which superseeds any strapping or vendor-specific
+	 * properties.
+	 *
+	 * If the port isn't initialized, the port->mediums and port->lanes
+	 * fields must be set, possibly according to stapping information.
+	 *
+	 * Returns 0, or an error code.
+	 */
+	int (*attach_port)(struct phy_device *dev, struct phy_port *port);
 };
 #define to_phy_driver(d) container_of_const(to_mdio_common_driver(d),		\
 				      struct phy_driver, mdiodrv)
@@ -2051,6 +2081,7 @@ void phy_trigger_machine(struct phy_device *phydev);
 void phy_mac_interrupt(struct phy_device *phydev);
 void phy_start_machine(struct phy_device *phydev);
 void phy_stop_machine(struct phy_device *phydev);
+
 void phy_ethtool_ksettings_get(struct phy_device *phydev,
 			       struct ethtool_link_ksettings *cmd);
 int phy_ethtool_ksettings_set(struct phy_device *phydev,
diff --git a/include/linux/phy_port.h b/include/linux/phy_port.h
new file mode 100644
index 000000000000..b34c15523adc
--- /dev/null
+++ b/include/linux/phy_port.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <linux/ethtool.h>
+#include <linux/types.h>
+
+#ifndef __PHY_PORT_H
+#define __PHY_PORT_H
+
+struct phy_port;
+
+/**
+ * enum phy_port_parent - The device this port is attached to
+ *
+ * @PHY_PORT_PHY: Indicates that the port is driven by a PHY device
+ */
+enum phy_port_parent {
+	PHY_PORT_PHY,
+};
+
+/**
+ * struct phy_port - A representation of a network device physical interface
+ *
+ * @head: Used by the port's parent to list ports
+ * @parent_type: The type of device this port is directly connected to
+ * @phy: If the parent is PHY_PORT_PHYDEV, the PHY controlling that port
+ * @lanes: The number of lanes (diff pairs) this port has, 0 if not applicable
+ * @medium: The physical medium this port provides access to
+ * @supported: The link modes this port can expose
+ * @active: Indicates if the port is currently part of the active link.
+ */
+struct phy_port {
+	struct list_head head;
+	enum phy_port_parent parent_type;
+	union {
+		struct phy_device *phy;
+	};
+
+	int lanes;
+	unsigned long mediums;
+	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
+
+	bool active;
+};
+
+struct phy_port *phy_port_alloc(void);
+void phy_port_destroy(struct phy_port *port);
+
+static inline struct phy_device *port_phydev(struct phy_port *port)
+{
+	return port->phy;
+}
+
+struct phy_port *phy_of_parse_port(struct device_node *dn);
+
+static inline bool phy_port_is_copper(struct phy_port *port)
+{
+	return port->mediums == BIT(ETHTOOL_LINK_MEDIUM_BASET);
+}
+
+static inline bool phy_port_is_fiber(struct phy_port *port)
+{
+	return !!(port->mediums & ETHTOOL_MEDIUM_FIBER_BITS);
+}
+
+void phy_port_update_supported(struct phy_port *port);
+
+int phy_port_get_type(struct phy_port *port);
+
+#endif
-- 
2.47.1



From maxime.chevallier at bootlin.com  Fri Dec 20 12:15:00 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 20 Dec 2024 21:15:00 +0100
Subject: [PATCH net-next RFC 1/5] net: ethtool: common: Make BaseT a 4-lanes mode
In-Reply-To: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
References: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
Message-ID: <20241220201506.2791940-2-maxime.chevallier@bootlin.com>

When referring to BaseT ethernet, we are most of the time thinking of
BaseT4 ethernet on Cat5/6/7 cables. This is therefore BaseT4, although
BaseT4 is also possible for 100BaseTX. This is even more true now that
we have a special __LINK_MODE_LANES_T1 mode especially for Single Pair
ethernet.

Mark BaseT as being a 4-lanes mode.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
 net/ethtool/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index 02f941f667dd..5a9c09ce57d5 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -244,7 +244,7 @@ static_assert(ARRAY_SIZE(link_mode_names) == __ETHTOOL_LINK_MODE_MASK_NBITS);
 #define __LINK_MODE_LANES_LR8_ER8_FR8	8
 #define __LINK_MODE_LANES_LRM		1
 #define __LINK_MODE_LANES_MLD2		2
-#define __LINK_MODE_LANES_T		1
+#define __LINK_MODE_LANES_T		4
 #define __LINK_MODE_LANES_T1		1
 #define __LINK_MODE_LANES_X		1
 #define __LINK_MODE_LANES_FX		1
-- 
2.47.1



From maxime.chevallier at bootlin.com  Fri Dec 20 12:14:59 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 20 Dec 2024 21:14:59 +0100
Subject: [PATCH net-next RFC 0/5] net: phy: Introduce a port representation
Message-ID: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>

Hello everyone,

This is a long overdue series to kick-off the introduction of a better representation
of front-facing ports for ethernet interfaces.

First, a short disclaimer. This series is RFC, and there are quite a lot of
shortcomings :

 - There's no DT binding although this series adds a generic representation of
   ports
 - The port representation is in a minimal form
 - No SFP support is included, but it will be required for that series to come
   out of RFC as we can't gracefully handle multi-port interfaces without it.

These shortcomigs come from timing constraints, but also because I'd like to
start discussing that topic with some code as a basis.

For now, the only representation we have about the physical ports of an interface
come from the 'port' field (PORT_FIBRE, PORT_TP, PORT_MII, etc.), the presence or
not of an SFP module and the linkmodes reported by the ethtol ksettings ops. This
isn't enough to get a good idea of what the actual interface with the outside world
looks like.

The end-goal of the work this series is a part of is to get support for multi-port
interfaces. My end use-case has 2 ports, each driven by a dedicated PHY, but this
also applies to dual-port PHYs.

The current series introduces the object "struct phy_port". The naming may be
improved, as I think we could consider supporting port representation without
depending on phylib (not the case in this RFC). For now, not only do we integrate
that work in phylib, but only PHY-driven ports are supported.

In some situations, having a good representation of the physical port in devicetree
proves to be quite useful. We're seeing vendor properties to address the lack of
port representation such as micrel,fiber-mode or ti,fiber-mode, but there are needs
for more (glitchy straps that detect fiber mode on a PHY connected to copper,
RJ45 ports connected with 2 lanes only, ...).

As I said this RFC has no binding, sorry about that, but let's take a look at
the proposed DT syntax :

Example 1 : PHY with RJ45 connected with 2 lanes only

&mdio {

	ge_phy: ethernet-phy at 0 {
		reg = <0>;

		mdi {
			port at 0 {
				media = "BaseT",
				lanes = <2>;
			};
		};

	};
};

Example 2 : PHY with a 100BaseFX port, without SFP

&mdio {

	fiber-phy: ethernet-phy at 0 {
		reg = <0>;

		mdi {
			port at 0 {
				media = "BaseF",
				lanes = <1>;
			};
		};

	};
};

These ports may even be used to specify PSE-PD information for PoE ports that
are drivern by a dedicated PoE controller sitting in-between the PHY and the
connector :

&mdio {

	ge_phy: ethernet-phy at 0 {
		reg = <0>;

		mdi {
			port at 0 {
				media = "BaseT",
				lanes = <4>;
				pse = <&pse1>;
			};
		};

	};
};

The ports are initialized using the following sequence :

1: The PHY driver's probe() function indicated the max number of ports the device
can control

2: We parse the devicetree to find generic port representations

3: If we don't have at least one port from DT, we create one

4: We call the phy's .attach_port() for each port created so far. This allows
   the phy driver either to take action based on the generic port devicetree
   indications, or to populate the port information based on straps and
   vendor-specific DT properties (think micrel,fiber-mode and similar)

5: If the ports are still not initialized (no .attach_port, no generic DT), then
   we use snesible default value from what the PHY's supported modes.

6: We reconstruct the PHY's supported field in case there are limitations from the
   port (2 lanes on BaseT for example). This last step will need to be changed
   when SFP gets added.

So, the current work is only about init. The next steps for that work are :

 - Introduce phy_port_ops, including a .configure() and a .read_status() to get
 proper support for multi-port PHYs. This also means maintaining a list of
 advertising/lp_advertising modes for each port.

 - Add SFP support. It's a tricky part, the way I see that and have prototyped is
 by representing the SFP cage itself as a port, as well as the SFP module's port.
 ports therefore become chainable.

 - Add the ability to list the ports in userspace.

Prototype work for the above parts exist, but due to lack of time I couldn't get
them polished enough for inclusion in that RFC.

Let me know if you see this going in the right direction, I'm really all ears
for suggestions on this, it's quite difficult to make sure no current use-case
breaks and no heavy rework is needed in PHY drivers.

Patches 1, 2 and 3 are preparatory work for the mediums representation. Patch 4
introduces the phy_port and patch 5 shows an example of usage in the dp83822 phy.

Thanks,

Maxime

Maxime Chevallier (5):
  net: ethtool: common: Make BaseT a 4-lanes mode
  net: ethtool: Introduce ETHTOOL_LINK_MEDIUM_* values
  net: ethtool: Export the link_mode_params definitions
  net: phy: Introduce PHY ports representation
  net: phy: dp83822: Add support for phy_port representation

 drivers/net/phy/Makefile     |   2 +-
 drivers/net/phy/dp83822.c    |  60 +++++++----
 drivers/net/phy/phy_device.c | 167 +++++++++++++++++++++++++++++
 drivers/net/phy/phy_port.c   | 159 ++++++++++++++++++++++++++++
 include/linux/ethtool.h      |  62 +++++++++++
 include/linux/phy.h          |  31 ++++++
 include/linux/phy_port.h     |  69 ++++++++++++
 net/ethtool/common.c         | 197 +++++++++++++++++++----------------
 net/ethtool/common.h         |   7 --
 9 files changed, 633 insertions(+), 121 deletions(-)
 create mode 100644 drivers/net/phy/phy_port.c
 create mode 100644 include/linux/phy_port.h

-- 
2.47.1



From maxime.chevallier at bootlin.com  Fri Dec 20 12:15:02 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 20 Dec 2024 21:15:02 +0100
Subject: [PATCH net-next RFC 3/5] net: ethtool: Export the link_mode_params definitions
In-Reply-To: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
References: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
Message-ID: <20241220201506.2791940-4-maxime.chevallier@bootlin.com>

link_mode_params contains a lookup table of all 802.3 link modes that
are currently supported with structured data about each mode's speed,
duplex, number of lanes and mediums.

As a preparation for a port representation, export that table for the
rest of the net stack to use.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
 include/linux/ethtool.h | 10 ++++++++++
 net/ethtool/common.c    |  1 +
 net/ethtool/common.h    |  9 ---------
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index dc02a1bef549..51d110dfa8ef 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -251,6 +251,16 @@ static inline const char *phy_mediums(enum ethtool_link_medium medium)
 	}
 }
 
+struct link_mode_info {
+	int                             speed;
+	u8                              min_lanes;
+	u8                              lanes;
+	u8                              duplex;
+	enum ethtool_link_medium        medium;
+};
+
+extern const struct link_mode_info link_mode_params[];
+
 /* declare a link mode bitmap */
 #define __ETHTOOL_DECLARE_LINK_MODE_MASK(name)		\
 	DECLARE_BITMAP(name, __ETHTOOL_LINK_MODE_MASK_NBITS)
diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index 41e7598f6ed7..bded82c0bba4 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -392,6 +392,7 @@ const struct link_mode_info link_mode_params[] = {
 	__DEFINE_LINK_MODE_PARAMS(10, T1BRR, Full, T),
 };
 static_assert(ARRAY_SIZE(link_mode_params) == __ETHTOOL_LINK_MODE_MASK_NBITS);
+EXPORT_SYMBOL_GPL(link_mode_params);
 
 const char netif_msg_class_names[][ETH_GSTRING_LEN] = {
 	[NETIF_MSG_DRV_BIT]		= "drv",
diff --git a/net/ethtool/common.h b/net/ethtool/common.h
index b25011a05fea..ee250a5c5364 100644
--- a/net/ethtool/common.h
+++ b/net/ethtool/common.h
@@ -14,14 +14,6 @@
 
 #define __SOF_TIMESTAMPING_CNT (const_ilog2(SOF_TIMESTAMPING_LAST) + 1)
 
-struct link_mode_info {
-	int				speed;
-	u8				min_lanes;
-	u8				lanes;
-	u8				duplex;
-	enum ethtool_link_medium	medium;
-};
-
 struct genl_info;
 struct hwtstamp_provider_desc;
 
@@ -34,7 +26,6 @@ tunable_strings[__ETHTOOL_TUNABLE_COUNT][ETH_GSTRING_LEN];
 extern const char
 phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN];
 extern const char link_mode_names[][ETH_GSTRING_LEN];
-extern const struct link_mode_info link_mode_params[];
 extern const char netif_msg_class_names[][ETH_GSTRING_LEN];
 extern const char wol_mode_names[][ETH_GSTRING_LEN];
 extern const char sof_timestamping_names[][ETH_GSTRING_LEN];
-- 
2.47.1



From maxime.chevallier at bootlin.com  Fri Dec 20 12:15:04 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 20 Dec 2024 21:15:04 +0100
Subject: [PATCH net-next RFC 5/5] net: phy: dp83822: Add support for phy_port representation
In-Reply-To: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
References: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
Message-ID: <20241220201506.2791940-6-maxime.chevallier@bootlin.com>

With the phy_port representation intrduced, we can use .attach_port to
populate the port information based on either the straps or the
ti,fiber-mode property. This allows simplifying the probe function and
allow users to override the strapping configuration.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
 drivers/net/phy/dp83822.c | 60 +++++++++++++++++++++++++--------------
 1 file changed, 39 insertions(+), 21 deletions(-)

diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
index 334c17a68edd..96a0ad1a0e83 100644
--- a/drivers/net/phy/dp83822.c
+++ b/drivers/net/phy/dp83822.c
@@ -637,17 +637,6 @@ static int dp83822_of_init(struct phy_device *phydev)
 	struct device *dev = &phydev->mdio.dev;
 	const char *of_val;
 
-	/* Signal detection for the PHY is only enabled if the FX_EN and the
-	 * SD_EN pins are strapped. Signal detection can only enabled if FX_EN
-	 * is strapped otherwise signal detection is disabled for the PHY.
-	 */
-	if (dp83822->fx_enabled && dp83822->fx_sd_enable)
-		dp83822->fx_signal_det_low = device_property_present(dev,
-								     "ti,link-loss-low");
-	if (!dp83822->fx_enabled)
-		dp83822->fx_enabled = device_property_present(dev,
-							      "ti,fiber-mode");
-
 	if (!device_property_read_string(dev, "ti,gpio2-clk-out", &of_val)) {
 		if (strcmp(of_val, "mac-if") == 0) {
 			dp83822->gpio2_clk_out = DP83822_CLK_SRC_MAC_IF;
@@ -740,6 +729,44 @@ static int dp83822_read_straps(struct phy_device *phydev)
 	return 0;
 }
 
+static int dp83822_attach_port(struct phy_device *phydev, struct phy_port *port)
+{
+	struct dp83822_private *dp83822 = phydev->priv;
+	struct device *dev = &phydev->mdio.dev;
+	int ret;
+
+	if (port->mediums) {
+		if (phy_port_is_fiber(port) ||
+		    port->mediums & BIT(ETHTOOL_LINK_MEDIUM_BASEX))
+			dp83822->fx_enabled = true;
+	} else {
+		ret = dp83822_read_straps(phydev);
+		if (ret)
+			return ret;
+
+#ifdef CONFIG_OF_MDIO
+		if (dp83822->fx_enabled && dp83822->fx_sd_enable)
+			dp83822->fx_signal_det_low =
+				device_property_present(dev, "ti,link-loss-low");
+		if (!dp83822->fx_enabled)
+			dp83822->fx_enabled =
+				device_property_present(dev, "ti,fiber-mode");
+#endif
+
+		if (dp83822->fx_enabled) {
+			port->lanes = 1;
+			port->mediums = BIT(ETHTOOL_LINK_MEDIUM_BASEF) |
+					BIT(ETHTOOL_LINK_MEDIUM_BASEX);
+		} else {
+			/* This PHY can only to 100BaseTX max, so on 2 lanes */
+			port->lanes = 2;
+			port->mediums = BIT(ETHTOOL_LINK_MEDIUM_BASET);
+		}
+	}
+
+	return 0;
+}
+
 static int dp8382x_probe(struct phy_device *phydev)
 {
 	struct dp83822_private *dp83822;
@@ -756,24 +783,14 @@ static int dp8382x_probe(struct phy_device *phydev)
 
 static int dp83822_probe(struct phy_device *phydev)
 {
-	struct dp83822_private *dp83822;
 	int ret;
 
 	ret = dp8382x_probe(phydev);
 	if (ret)
 		return ret;
 
-	dp83822 = phydev->priv;
-
-	ret = dp83822_read_straps(phydev);
-	if (ret)
-		return ret;
-
 	dp83822_of_init(phydev);
 
-	if (dp83822->fx_enabled)
-		phydev->port = PORT_FIBRE;
-
 	return 0;
 }
 
@@ -831,6 +848,7 @@ static int dp83822_resume(struct phy_device *phydev)
 		.handle_interrupt = dp83822_handle_interrupt,	\
 		.suspend = dp83822_suspend,			\
 		.resume = dp83822_resume,			\
+		.attach_port = dp83822_attach_port		\
 	}
 
 #define DP83825_PHY_DRIVER(_id, _name)				\
-- 
2.47.1



From jonas at kwiboo.se  Fri Dec 20 12:42:57 2024
From: jonas at kwiboo.se (Jonas Karlman)
Date: Fri, 20 Dec 2024 21:42:57 +0100
Subject: [PATCH] arm64: dts: rockchip: ROCK3B: Correct clock rates for
 Ethernet PHYs
In-Reply-To: <CAMdYzYoraXsZK3Uwe3QBVjt0cHn_GyOvR=57+qD-UrrwRE2TzA@mail.gmail.com>
References: <20241220163227.1501912-1-alicja.michalska@9elements.com>
 <17251add-40b7-4d18-8626-2d74b29532fc@kwiboo.se>
 <9a210e3d-90eb-42d4-83fd-7bbad7b00e86@9elements.com>
 <CAMdYzYoraXsZK3Uwe3QBVjt0cHn_GyOvR=57+qD-UrrwRE2TzA@mail.gmail.com>
Message-ID: <09c15a40-a956-46ef-bb54-ac999758a492@kwiboo.se>

Hi,

On 2024-12-20 20:52, Peter Geis wrote:
> Good Afternoon,
> 
> On Fri, Dec 20, 2024 at 12:54?PM Alicja Michalska
> <alicja.michalska at 9elements.com> wrote:
>>
>> Hello Jonas,
>>
>>
>> On 20/12/2024 18:09, Jonas Karlman wrote:
>>> Have you used mainline or vendor u-boot when testing?
>>>
>>> There is an existing issue with RTL8211F PHYs that they must be reset
>>> before Linux can identify them, see [1] for more details on the issue.
>>>
>>> Mainline U-Boot will reset the Ethernet PHYs on this board and that
>>> should allow for Linux to identify and use the Ethernet PHYs.
>>>
>>> [1] https://lore.kernel.org/r/47d55aca-bee6-810f-379f-9431649fefa6 at kwiboo.se/
>>
>> Thank you for the link. I've tested with vendor-provided U-Boot build:
>>
>> U-Boot latest-2023.10-11-cc60ff40-gcc60ff40 (Aug 14 2024 - 03:56:35 +0000)
>>
>> I can test with upstream in upcoming days.
>>
>>> The snps,reset props is deprecated and reset- props should be used in
>>> the PHY node.
>>>
>>> This also changes to use 20/100 ms delay instead of current 20/50ms
>>> delay. If anything it could be changed to 20/80ms, I have only seen
>>> datasheets for rtl8211f mention minimum 10 ms and minimum 30-76 ms.
>>>
>>>> +
>>>> +    tx_delay = <0x36>;
>>>> +    rx_delay = <0x2d>;
>>> Are you having issue with use of rgmii-id on your board?
>>
>> Interesting insight, thank you!
>>
>> I have to admit that I haven't read the current documentation, just seen that other RK356X boards in the tree used it. My apologies.
>>
>> I've ran into issues with rgmii-id, but that's with vendor U-Boot (as mentioned above), will try with upstream next and see a follow-up if I will still experience issues.
> 
> rgmii-id sets the phy to handle the tx and rx delays. All of the
> various rgmii settings require the board to be built to specific
> tolerances for the data lines. Rockchip based boards seem to forgo
> this design phase, instead using rgmii (no built in delays) and set
> the delays in the Rockchip gmac driver instead, using the tx_delay and
> rx_delay values in the device tree. The tx_delay and rx_delay value
> must be tuned correctly for your hardware. If you wish to use them
> you'll need to set rgmii, then find the lowest and highest values that
> work for all variations of hardware supported by the device tree then
> take the middle value. If you wish to use rgmii-id, these values
> should be omitted or set to zero as they are additive to the existing
> delays.
> 
>>
>>>> +
>>>>      status = "okay";
>>>>  };
>>>>
>>>>  &gmac1 {
>>>>      assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
>>>>      assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
>>>> -    clock_in_out = "input";
>>>> -    phy-handle = <&rgmii_phy1>;
>>>> -    phy-mode = "rgmii-id";
>>>> +    assigned-clock-rates = <0>, <125000000>;
>>>> +    clock_in_out = "output";
> 
> Instead, I suspect the clocks here are your issue. Looking at the
> schematic at [1] your board is designed to feed the phy clock into the
> SoC. This isn't the current clock configuration in your device tree,
> you had it set to input, but the clock parents are wrong and will
> default to using the internal SoC clock source for the mac. I suspect
> setting the assigned clock rate is what fixed your issue.

Correct, I should probably have used the gmacX_clkin instead of
clk_macX_2top in the initial ROCK 3B device tree. However, Ethernet was
tested using iperf3 on both interfaces and was working at that time
so did not pay too close attention ;-)

The change to use snps,reset- props is probably what made the PHY work.
As pointed out in the thread I linked, there is an chicken-and-egg
issue with the PHY not being probed unless it has been reset and a
proper phy_id can be read back over mdio bus:

  As I mentioned earlier there is a chicken-and-egg problem to be solved:
  - phy needs to be reset or phy_id read back as 0xffffffff on mdio bus
  - phy device is not created because a valid phy_id is not read back
  - phy device needs to be created before it can be reset

  A reset need to happen before/during this call chain:
  stmmac_mdio_register()
  -> of_mdiobus_register()
  -> of_mdiobus_register_phy()
  -> fwnode_mdiobus_register_phy()
  -> get_phy_device()
  -> get_phy_c22_id()
  -> mdiobus_read(bus, addr, MII_PHYSID1)

  Here mdiobus_read cannot read back the phy_id unless the PHY has been reset.

  This is why the deprecated props work, the reset is issued before/during
  stmmac_mdio_register(). Or at the mdiobus level, the reset is issued
  before/during of_mdiobus_register(). With reset at phy level the reset
  happens after device is created, after phy_id has been read, hence a
  chicken-and-egg problem.

Currently I know of these workarounds:
a) reset PHY before OS, i.e. use mainline U-Boot
b) use a ethernet-phy-id001c.c916 compatible for the onboard RTL8211F
   PHY instead of the generic ethernet-phy-ieee802.3-c22 compatible
c) use deprecated snps,reset- props
d) use reset props on mdiobus level

> 
> I wrote the rk3566-quartz64-a.dts to be an example for how the new soc
> behaves. I recommend looking at it for an example for how the clocks
> are supposed to be set up for proper input [2].

rk3566-quartz64-a.dts use the deprecated snps,reset- props and is not
affected by same Ethernet PHY reset/probe issue.

> 
>>>>      phy-supply = <&vcc_3v3>;
>>>> +    phy-mode = "rgmii";
>>>> +    phy-handle = <&rgmii_phy1>;
>>>>      pinctrl-names = "default";
>>>>      pinctrl-0 = <&gmac1m1_miim
>>>>                   &gmac1m1_tx_bus2
>>>>                   &gmac1m1_rx_bus2
>>>>                   &gmac1m1_rgmii_clk
>>>> -                 &gmac1m1_rgmii_bus
>>>> -                 &gmac1m1_clkinout>;
>>>> +                 &gmac1m1_rgmii_bus>;
>>>> +    snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
>>>> +    snps,reset-active-low;
>>>> +    snps,reset-delays-us = <0 50000 150000>;
>>> Same here, but now this is 50/150 ms?
>> I wasn't sure about those delays, as I've taken them from vendor's sources. They did seem awfully high, though.
>>>> +
>>>> +    tx_delay = <0x47>;
>>>> +    rx_delay = <0x28>;
>>> Same here, is use of rgmii-id causing issues on your boards?
>> Answer above :)
>>>> +
>>>>      status = "okay";
>>>>  };
>>>>
>>>> +&mdio0 {
>>>> +    rgmii_phy0: ethernet-phy at 0 {
>>>> +            compatible = "ethernet-phy-ieee802.3-c22";
>>>> +            reg = <0>;
>>> The phy addr used for these boards is 0x1.
>>>
>>>> +    };
>>>> +};
>>>> +
>>>> +&mdio1 {
>>>> +    rgmii_phy1: ethernet-phy at 0 {
>>>> +            compatible = "ethernet-phy-ieee802.3-c22";
>>>> +            reg = <0>;
>>> Same here.
>> Makes sense, other boards in the tree had it configured the same way.
>>>> +    };
>>>> +};
>>> There should be no need to move these nodes, they should already be in
>>> alphabetical order?
>> There's no reason to, just thought moving them closer to PHYs would look cleaner and make a bit more sense. It's just a nitpick though.
>>>> +
>>>>  &gpu {
>>>>      mali-supply = <&vdd_gpu>;
>>>>      status = "okay";
>>>> @@ -512,26 +540,6 @@ &i2s1m0_sdi0
>>>>      status = "okay";
>>>>  };
>>>>
>>>> -&mdio0 {
>>>> -    rgmii_phy0: ethernet-phy at 1 {
>>>> -            compatible = "ethernet-phy-ieee802.3-c22";
>>> If you want to use vendor u-boot you can probably change this to
>>> "ethernet-phy-id001c.c916".
>>>
>>>> -            reg = <1>;
>>>> -            reset-assert-us = <20000>;
>>>> -            reset-deassert-us = <50000>;
>>>> -            reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
>>>> -    };
>>>> -};
>>>> -
>>>> -&mdio1 {
>>>> -    rgmii_phy1: ethernet-phy at 1 {
>>>> -            compatible = "ethernet-phy-ieee802.3-c22";
>>> Same here.
>>
>> True, but in this case it likely wouldn't be accepted in upstream, right?

Should be fine, as it correctly define the Ethernet PHYs used.

Regards,
Jonas

>>
>> I really would prefer devicetrees to be passed to the OS by bootloader, just like ACPI does on x86 and some (i.e Ampere) platforms.
>>
>> This way we wouldn't need to maintain per-board DTs in the tree, and would keep functionality between kernel versions/BSDs... but one can dream, huh? :)
> 
> The device-tree is supposed to describe hardware without regards to a
> specific operating system. If written correctly, it will work no
> matter what software is running on top of it. While there are some
> specific tweaks to make the operating systems behave correctly around
> broken hardware, a lot of the deviations from this standard are due to
> legacy trees and are being cleaned up over time.
> 
>>
>> Thank you,
>>
>> Alicja
> 
> Very Respectfully,
> Peter Geis
> 
> [1] https://dl.radxa.com/rock3/docs/hw/3b/Radxa_ROCK_3B_V1.51_SCH.pdf
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts?h=v6.13-rc3#n267
> 


From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:11 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:11 -0700
Subject: [PATCH v4 10/13] ARM: dts: at91: Add sama7d65 pinmux
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <8f091eb89b0a0190548136f970ec94e322d90da2.1734723585.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add sama7d65 pin descriptions.

Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
 .../arm/boot/dts/microchip/sama7d65-pinfunc.h | 947 ++++++++++++++++++
 1 file changed, 947 insertions(+)
 create mode 100644 arch/arm/boot/dts/microchip/sama7d65-pinfunc.h

diff --git a/arch/arm/boot/dts/microchip/sama7d65-pinfunc.h b/arch/arm/boot/dts/microchip/sama7d65-pinfunc.h
new file mode 100644
index 000000000000..c591f333cacb
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/sama7d65-pinfunc.h
@@ -0,0 +1,947 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+#define PINMUX_PIN(no, func, ioset) \
+(((no) & 0xffff) | (((func) & 0xf) << 16) | (((ioset) & 0xff) << 20))
+
+#define PIN_PA0				0
+#define PIN_PA0__GPIO			PINMUX_PIN(PIN_PA0, 0, 0)
+#define PIN_PA0__SDMMC0_CK		PINMUX_PIN(PIN_PA0, 1, 1)
+#define PIN_PA0__FLEXCOM3_IO0		PINMUX_PIN(PIN_PA0, 2, 1)
+#define PIN_PA0__NWER0			PINMUX_PIN(PIN_PA0, 3, 1)
+
+#define PIN_PA1				1
+#define PIN_PA1__GPIO			PINMUX_PIN(PIN_PA1, 0, 0)
+#define PIN_PA1__SDMMC0_CMD		PINMUX_PIN(PIN_PA1, 1, 1)
+#define PIN_PA1__FLEXCOM3_IO1		PINMUX_PIN(PIN_PA1, 2, 1)
+#define PIN_PA1__A21			PINMUX_PIN(PIN_PA1, 3, 1)
+
+#define PIN_PA2				2
+#define PIN_PA2__GPIO			PINMUX_PIN(PIN_PA2, 0, 0)
+#define PIN_PA2__SDMMC0_RSTN		PINMUX_PIN(PIN_PA2, 1, 1)
+#define PIN_PA2__FLEXCOM3_IO2		PINMUX_PIN(PIN_PA2, 2, 1)
+#define PIN_PA2__A22			PINMUX_PIN(PIN_PA2, 3, 1)
+
+#define PIN_PA3				3
+#define PIN_PA3__GPIO			PINMUX_PIN(PIN_PA3, 0, 0)
+#define PIN_PA3__SDMMC0_DAT0		PINMUX_PIN(PIN_PA3, 1, 1)
+#define PIN_PA3__FLEXCOM3_IO3		PINMUX_PIN(PIN_PA3, 2, 1)
+#define PIN_PA3__D0			PINMUX_PIN(PIN_PA3, 3, 1)
+
+#define PIN_PA4				4
+#define PIN_PA4__GPIO			PINMUX_PIN(PIN_PA4, 0, 0)
+#define PIN_PA4__SDMMC0_DAT1		PINMUX_PIN(PIN_PA4, 1, 1)
+#define PIN_PA4__FLEXCOM3_IO4		PINMUX_PIN(PIN_PA4, 2, 1)
+#define PIN_PA4__D1			PINMUX_PIN(PIN_PA4, 3, 1)
+
+#define PIN_PA5				5
+#define PIN_PA5__GPIO			PINMUX_PIN(PIN_PA5, 0, 0)
+#define PIN_PA5__SDMMC0_DAT4		PINMUX_PIN(PIN_PA5, 1, 1)
+#define PIN_PA5__FLEXCOM2_IO0		PINMUX_PIN(PIN_PA5, 2, 3)
+#define PIN_PA5__D4			PINMUX_PIN(PIN_PA5, 3, 1)
+#define PIN_PA5__TCLK4			PINMUX_PIN(PIN_PA5, 6, 3)
+
+#define PIN_PA6				6
+#define PIN_PA6__GPIO			PINMUX_PIN(PIN_PA6, 0, 0)
+#define PIN_PA6__SDMMC0_DAT5		PINMUX_PIN(PIN_PA6, 1, 1)
+#define PIN_PA6__FLEXCOM2_IO1		PINMUX_PIN(PIN_PA6, 2, 3)
+#define PIN_PA6__D5			PINMUX_PIN(PIN_PA6, 3, 1)
+#define PIN_PA6__TIOB4			PINMUX_PIN(PIN_PA6, 6, 3)
+
+#define PIN_PA7				7
+#define PIN_PA7__GPIO			PINMUX_PIN(PIN_PA7, 0, 0)
+#define PIN_PA7__SDMMC0_DAT6		PINMUX_PIN(PIN_PA7, 1, 1)
+#define PIN_PA7__FLEXCOM2_IO2		PINMUX_PIN(PIN_PA7, 2, 3)
+#define PIN_PA7__D6			PINMUX_PIN(PIN_PA7, 3, 1)
+#define PIN_PA7__TIOA4			PINMUX_PIN(PIN_PA7, 6, 3)
+
+#define PIN_PA8				8
+#define PIN_PA8__GPIO			PINMUX_PIN(PIN_PA8, 0, 0)
+#define PIN_PA8__SDMMC0_DAT7		PINMUX_PIN(PIN_PA8, 1, 1)
+#define PIN_PA8__FLEXCOM2_IO3		PINMUX_PIN(PIN_PA8, 2, 3)
+#define PIN_PA8__D7			PINMUX_PIN(PIN_PA8, 3, 1)
+#define PIN_PA8__TIOA5			PINMUX_PIN(PIN_PA8, 6, 3)
+
+#define PIN_PA9				9
+#define PIN_PA9__GPIO			PINMUX_PIN(PIN_PA9, 0, 0)
+#define PIN_PA9__SDMMC0_DAT2		PINMUX_PIN(PIN_PA9, 1, 1)
+#define PIN_PA9__FLEXCOM0_IO2		PINMUX_PIN(PIN_PA9, 2, 1)
+#define PIN_PA9__D2			PINMUX_PIN(PIN_PA9, 3, 1)
+#define PIN_PA9__TIOB5			PINMUX_PIN(PIN_PA9, 6, 3)
+
+#define PIN_PA10			10
+#define PIN_PA10__GPIO			PINMUX_PIN(PIN_PA10, 0, 0)
+#define PIN_PA10__SDMMC0_DAT3		PINMUX_PIN(PIN_PA10, 1, 1)
+#define PIN_PA10__FLEXCOM0_IO3		PINMUX_PIN(PIN_PA10, 2, 1)
+#define PIN_PA10__D3			PINMUX_PIN(PIN_PA10, 3, 1)
+#define PIN_PA10__TCLK5			PINMUX_PIN(PIN_PA10, 6, 3)
+
+#define PIN_PA11			11
+#define PIN_PA11__GPIO			PINMUX_PIN(PIN_PA11, 0, 0)
+#define PIN_PA11__SDMMC0_DS		PINMUX_PIN(PIN_PA11, 1, 1)
+#define PIN_PA11__FLEXCOM0_IO4		PINMUX_PIN(PIN_PA11, 2, 1)
+#define PIN_PA11__NANDRDY		PINMUX_PIN(PIN_PA11, 3, 1)
+#define PIN_PA11__TIOB3			PINMUX_PIN(PIN_PA11, 6, 3)
+
+#define PIN_PA12			12
+#define PIN_PA12__GPIO			PINMUX_PIN(PIN_PA12, 0, 0)
+#define PIN_PA12__FLEXCOM0_IO0		PINMUX_PIN(PIN_PA12, 2, 1)
+#define PIN_PA12__NRD			PINMUX_PIN(PIN_PA12, 3, 1)
+#define PIN_PA12__PCK0			PINMUX_PIN(PIN_PA12, 4, 1)
+#define PIN_PA12__EXT_IRQ0		PINMUX_PIN(PIN_PA12, 5, 1)
+#define PIN_PA12__TIOA3			PINMUX_PIN(PIN_PA12, 6, 3)
+
+#define PIN_PA13			13
+#define PIN_PA13__GPIO			PINMUX_PIN(PIN_PA13, 0, 0)
+#define PIN_PA13__FLEXCOM0_IO1		PINMUX_PIN(PIN_PA13, 2, 1)
+#define PIN_PA13__NCS0			PINMUX_PIN(PIN_PA13, 3, 1)
+#define PIN_PA13__PCK1			PINMUX_PIN(PIN_PA13, 4, 1)
+#define PIN_PA13__TCLK3			PINMUX_PIN(PIN_PA13, 6, 3)
+
+#define PIN_PA14			14
+#define PIN_PA14__GPIO			PINMUX_PIN(PIN_PA14, 0, 0)
+#define PIN_PA14__FLEXCOM4_IO4		PINMUX_PIN(PIN_PA14, 1, 1)
+#define PIN_PA14__SDMMC0_WP		PINMUX_PIN(PIN_PA14, 2, 1)
+#define PIN_PA14__FLEXCOM3_IO0		PINMUX_PIN(PIN_PA14, 3, 4)
+
+#define PIN_PA15			15
+#define PIN_PA15__GPIO			PINMUX_PIN(PIN_PA15, 0, 0)
+#define PIN_PA15__FLEXCOM4_IO3		PINMUX_PIN(PIN_PA15, 1, 1)
+#define PIN_PA15__SDMMC0_1V8SEL		PINMUX_PIN(PIN_PA15, 2, 1)
+#define PIN_PA15__FLEXCOM3_IO1		PINMUX_PIN(PIN_PA15, 3, 4)
+
+#define PIN_PA16			16
+#define PIN_PA16__GPIO			PINMUX_PIN(PIN_PA16, 0, 0)
+#define PIN_PA16__FLEXCOM4_IO2		PINMUX_PIN(PIN_PA16, 1, 1)
+#define PIN_PA16__SDMMCo_CD		PINMUX_PIN(PIN_PA16, 2, 1)
+#define PIN_PA16__PCK2			PINMUX_PIN(PIN_PA16, 4, 1)
+#define PIN_PA16__EXT_IRQ1		PINMUX_PIN(PIN_PA16, 5, 1)
+
+#define PIN_PA17			17
+#define PIN_PA17__GPIO			PINMUX_PIN(PIN_PA17, 0, 0)
+#define PIN_PA17__FLEXCOM4_IO1		PINMUX_PIN(PIN_PA17, 1, 1)
+
+#define PIN_PA18			18
+#define PIN_PA18__GPIO			PINMUX_PIN(PIN_PA18, 0, 0)
+#define PIN_PA18__FLEXCOM4_IO0		PINMUX_PIN(PIN_PA18, 1, 1)
+
+#define PIN_PA19			19
+#define PIN_PA19__GPIO			PINMUX_PIN(PIN_PA19, 0, 0)
+#define PIN_PA19__TK0			PINMUX_PIN(PIN_PA19, 1, 1)
+#define PIN_PA19__FLEXCOM4_IO5		PINMUX_PIN(PIN_PA19, 3, 1)
+#define PIN_PA19__PWML0			PINMUX_PIN(PIN_PA19, 4, 3)
+
+#define PIN_PA20			20
+#define PIN_PA20__GPIO			PINMUX_PIN(PIN_PA20, 0, 0)
+#define PIN_PA20__TD0			PINMUX_PIN(PIN_PA20, 1, 1)
+#define PIN_PA20__FLEXCOM3_IO4		PINMUX_PIN(PIN_PA20, 2, 2)
+#define PIN_PA20__FLEXCOM4_IO6		PINMUX_PIN(PIN_PA20, 3, 1)
+#define PIN_PA20__PWMH0			PINMUX_PIN(PIN_PA20, 4, 3)
+
+#define PIN_PA21			21
+#define PIN_PA21__GPIO			PINMUX_PIN(PIN_PA21, 0, 0)
+#define PIN_PA21__TF0			PINMUX_PIN(PIN_PA21, 1, 1)
+#define PIN_PA21__FLEXCOM3_IO3		PINMUX_PIN(PIN_PA21, 2, 2)
+#define PIN_PA21__PWML1			PINMUX_PIN(PIN_PA21, 4, 3)
+
+#define PIN_PA22			22
+#define PIN_PA22__GPIO			PINMUX_PIN(PIN_PA22, 0, 0)
+#define PIN_PA22__RD0			PINMUX_PIN(PIN_PA22, 1, 1)
+#define PIN_PA22__FLEXCOM3_IO2		PINMUX_PIN(PIN_PA22, 2, 2)
+#define PIN_PA22__PDMC0_DS1		PINMUX_PIN(PIN_PA22, 3, 1)
+#define PIN_PA22__PWMH1			PINMUX_PIN(PIN_PA22, 4, 3)
+
+#define PIN_PA23			23
+#define PIN_PA23__GPIO			PINMUX_PIN(PIN_PA23, 0, 0)
+#define PIN_PA23__RK0			PINMUX_PIN(PIN_PA23, 1, 1)
+#define PIN_PA23__FLEXCOM3_IO1		PINMUX_PIN(PIN_PA23, 2, 2)
+#define PIN_PA23__PDMC0_CLK		PINMUX_PIN(PIN_PA23, 3, 1)
+#define PIN_PA23__PWML2			PINMUX_PIN(PIN_PA23, 4, 3)
+
+#define PIN_PA24			24
+#define PIN_PA24__GPIO			PINMUX_PIN(PIN_PA24, 0, 0)
+#define PIN_PA24__RF0			PINMUX_PIN(PIN_PA24, 1, 1)
+#define PIN_PA24__FLEXCOM3_IO0		PINMUX_PIN(PIN_PA24, 2, 2)
+#define PIN_PA24__PDMC0_DS0		PINMUX_PIN(PIN_PA24, 3, 1)
+#define PIN_PA24__PWMH2			PINMUX_PIN(PIN_PA24, 4, 3)
+
+#define PIN_PA25			25
+#define PIN_PA25__GPIO			PINMUX_PIN(PIN_PA25, 0, 0)
+#define PIN_PA25__G0_TXCTL		PINMUX_PIN(PIN_PA25, 1, 1)
+#define PIN_PA25__FLEXCOM6_IO2		PINMUX_PIN(PIN_PA25, 2, 1)
+
+#define PIN_PA26			26
+#define PIN_PA26__GPIO			PINMUX_PIN(PIN_PA26, 0, 0)
+#define PIN_PA26__G0_TX0		PINMUX_PIN(PIN_PA26, 1, 1)
+#define PIN_PA26__FLEXCOM6_IO3		PINMUX_PIN(PIN_PA26, 2, 1)
+
+#define PIN_PA27			27
+#define PIN_PA27__GPIO			PINMUX_PIN(PIN_PA27, 0, 0)
+#define PIN_PA27__G0_TX1		PINMUX_PIN(PIN_PA27, 1, 1)
+#define PIN_PA27__FLEXCOM6_IO4		PINMUX_PIN(PIN_PA27, 2, 1)
+
+#define PIN_PA28			28
+#define PIN_PA28__GPIO			PINMUX_PIN(PIN_PA28, 0, 0)
+#define PIN_PA28__G0_RXCTL		PINMUX_PIN(PIN_PA28, 1, 1)
+#define PIN_PA28__FLEXCOM6_IO0		PINMUX_PIN(PIN_PA28, 2, 1)
+
+#define PIN_PA29			29
+#define PIN_PA29__GPIO			PINMUX_PIN(PIN_PA29, 0, 0)
+#define PIN_PA29__G0_RX0		PINMUX_PIN(PIN_PA29, 1, 1)
+#define PIN_PA29__FLEXCOM6_IO1		PINMUX_PIN(PIN_PA29, 2, 1)
+
+#define PIN_PA30			30
+#define PIN_PA30__GPIO			PINMUX_PIN(PIN_PA30, 0, 0)
+#define PIN_PA30__G0_RX1		PINMUX_PIN(PIN_PA30, 1, 1)
+#define PIN_PA30__FLEXCOM8_IO0		PINMUX_PIN(PIN_PA30, 2, 1)
+
+#define PIN_PA31			31
+#define PIN_PA31__GPIO			PINMUX_PIN(PIN_PA31, 0, 0)
+#define PIN_PA31__G0_MDC		PINMUX_PIN(PIN_PA31, 1, 1)
+#define PIN_PA31__FLEXCOM8_IO1		PINMUX_PIN(PIN_PA31, 2, 1)
+
+#define PIN_PB0				32
+#define PIN_PB0__GPIO			PINMUX_PIN(PIN_PB0, 0, 0)
+#define PIN_PB0__G0_MDIO		PINMUX_PIN(PIN_PB0, 1, 1)
+#define PIN_PB0__FLEXCOM8_IO3		PINMUX_PIN(PIN_PB0, 2, 2)
+
+#define PIN_PB1				33
+#define PIN_PB1__GPIO			PINMUX_PIN(PIN_PB1, 0, 0)
+#define PIN_PB1__G0_REFCK		PINMUX_PIN(PIN_PB1, 1, 2)
+#define PIN_PB1__FLEXCOM8_IO2		PINMUX_PIN(PIN_PB1, 2, 1)
+
+#define PIN_PB2				34
+#define PIN_PB2__GPIO			PINMUX_PIN(PIN_PB2, 0, 0)
+#define PIN_PB2__G0_RX2			PINMUX_PIN(PIN_PB2, 1, 1)
+#define PIN_PB2__FLEXCOM8_IO4		PINMUX_PIN(PIN_PB2, 2, 1)
+#define PIN_PB2__G0_RXER		PINMUX_PIN(PIN_PB2, 3, 2)
+#define PIN_PB2__RK0			PINMUX_PIN(PIN_PB2, 4, 2)
+
+#define PIN_PB3				35
+#define PIN_PB3__GPIO			PINMUX_PIN(PIN_PB3, 0, 0)
+#define PIN_PB3__G0_RXCK		PINMUX_PIN(PIN_PB3, 1, 1)
+#define PIN_PB3__FLEXCOM10_IO2		PINMUX_PIN(PIN_PB3, 2, 2)
+#define PIN_PB3__TK0			PINMUX_PIN(PIN_PB3, 4, 2)
+
+#define PIN_PB4				36
+#define PIN_PB4__GPIO			PINMUX_PIN(PIN_PB4, 0, 0)
+#define PIN_PB4__G0_TX2			PINMUX_PIN(PIN_PB4, 1, 1)
+#define PIN_PB4__FLEXCOM10_IO3		PINMUX_PIN(PIN_PB4, 2, 2)
+#define PIN_PB4__TF0			PINMUX_PIN(PIN_PB4, 4, 2)
+
+#define PIN_PB5				37
+#define PIN_PB5__GPIO			PINMUX_PIN(PIN_PB5, 0, 0)
+#define PIN_PB5__G0_TX3			PINMUX_PIN(PIN_PB5, 1, 1)
+#define PIN_PB5__FLEXCOM10_IO4		PINMUX_PIN(PIN_PB5, 2, 1)
+#define PIN_PB5__TD0			PINMUX_PIN(PIN_PB5, 4, 2)
+
+#define PIN_PB6				38
+#define PIN_PB6__GPIO			PINMUX_PIN(PIN_PB6, 0, 0)
+#define PIN_PB6__G0_RX3			PINMUX_PIN(PIN_PB6, 1, 1)
+#define PIN_PB6__FLEXCOM10_IO0		PINMUX_PIN(PIN_PB6, 2, 2)
+#define PIN_PB6__RD0			PINMUX_PIN(PIN_PB6, 4, 2)
+
+#define PIN_PB7				39
+#define PIN_PB7__GPIO			PINMUX_PIN(PIN_PB7, 0, 0)
+#define PIN_PB7__G0_TSUCOMP		PINMUX_PIN(PIN_PB7, 1, 1)
+#define PIN_PB7__FLEXCOM10_IO1		PINMUX_PIN(PIN_PB7, 2, 2)
+#define PIN_PB7__ADTRG			PINMUX_PIN(PIN_PB7, 3, 1)
+#define PIN_PB7__RF0			PINMUX_PIN(PIN_PB7, 4, 2)
+
+#define PIN_PB8				40
+#define PIN_PB8__GPIO			PINMUX_PIN(PIN_PB8, 0, 0)
+#define PIN_PB8__QSPI0_IO3		PINMUX_PIN(PIN_PB8, 1, 1)
+#define PIN_PB8__PCK3			PINMUX_PIN(PIN_PB8, 2, 1)
+#define PIN_PB8__FLEXCOM2_IO1		PINMUX_PIN(PIN_PB8, 4, 2)
+
+#define PIN_PB9				41
+#define PIN_PB9__GPIO			PINMUX_PIN(PIN_PB9, 0, 0)
+#define PIN_PB9__QSPI0_IO2		PINMUX_PIN(PIN_PB9, 1, 1)
+#define PIN_PB9__FLEXCOM2_IO0		PINMUX_PIN(PIN_PB9, 4, 2)
+#define PIN_PB9__PWMEXTRG0		PINMUX_PIN(PIN_PB9, 5, 1)
+
+#define PIN_PB10			42
+#define PIN_PB10__GPIO			PINMUX_PIN(PIN_PB10, 0, 0)
+#define PIN_PB10__QSPI0_IO1		PINMUX_PIN(PIN_PB10, 1, 1)
+#define PIN_PB10__FLEXCOM2_IO4		PINMUX_PIN(PIN_PB10, 4, 2)
+#define PIN_PB10__PWMEXTRG1		PINMUX_PIN(PIN_PB10, 5, 1)
+
+#define PIN_PB11			43
+#define PIN_PB11__GPIO			PINMUX_PIN(PIN_PB11, 0, 0)
+#define PIN_PB11__QSPI0_IO0		PINMUX_PIN(PIN_PB11, 1, 1)
+#define PIN_PB11__FLEXCOM2_IO5		PINMUX_PIN(PIN_PB11, 4, 2)
+#define PIN_PB11__PWML3			PINMUX_PIN(PIN_PB11, 5, 1)
+#define PIN_PB11__TIOB3			PINMUX_PIN(PIN_PB11, 6, 2)
+
+#define PIN_PB12			44
+#define PIN_PB12__GPIO			PINMUX_PIN(PIN_PB12, 0, 0)
+#define PIN_PB12__QSPI0_CS		PINMUX_PIN(PIN_PB12, 1, 1)
+#define PIN_PB12__FLEXCOM2_IO3		PINMUX_PIN(PIN_PB12, 4, 2)
+#define PIN_PB12__PWMFI1		PINMUX_PIN(PIN_PB12, 6, 1)
+#define PIN_PB12__TIOA3			PINMUX_PIN(PIN_PB12, 6, 2)
+
+#define PIN_PB13			45
+#define PIN_PB13__GPIO			PINMUX_PIN(PIN_PB13, 0, 0)
+#define PIN_PB13__QSPI0_SCK		PINMUX_PIN(PIN_PB13, 1, 1)
+#define PIN_PB13__FLEXCOM2_IO2		PINMUX_PIN(PIN_PB13, 4, 2)
+#define PIN_PB13__PWMFI0		PINMUX_PIN(PIN_PB13, 5, 1)
+#define PIN_PB13__TCLK3			PINMUX_PIN(PIN_PB13, 6, 2)
+
+#define PIN_PB14			46
+#define PIN_PB14__GPIO			PINMUX_PIN(PIN_PB14, 0, 0)
+#define PIN_PB14__QSPI0_SCKN		PINMUX_PIN(PIN_PB14, 1, 1)
+#define PIN_PB14__QSPI1_SCK		PINMUX_PIN(PIN_PB14, 2, 1)
+#define PIN_PB14__I2SMCC0_CK		PINMUX_PIN(PIN_PB14, 3, 3)
+#define PIN_PB14__FLEXCOM10_IO5		PINMUX_PIN(PIN_PB14, 4, 1)
+#define PIN_PB14__PWMH3			PINMUX_PIN(PIN_PB14, 5, 1)
+#define PIN_PB14__FLEXCOM2_IO1		PINMUX_PIN(PIN_PB14, 7, 4)
+
+#define PIN_PB15			47
+#define PIN_PB15__GPIO			PINMUX_PIN(PIN_PB15, 0, 0)
+#define PIN_PB15__QSPI0_IO4		PINMUX_PIN(PIN_PB15, 1, 1)
+#define PIN_PB15__QSPI1_IO0		PINMUX_PIN(PIN_PB15, 2, 1)
+#define PIN_PB15__I2SMCC0_WS		PINMUX_PIN(PIN_PB15, 3, 3)
+#define PIN_PB15__FLEXCOM10_IO6		PINMUX_PIN(PIN_PB15, 4, 1)
+#define PIN_PB15__PWML0			PINMUX_PIN(PIN_PB15, 5, 1)
+#define PIN_PB15__TCLK4			PINMUX_PIN(PIN_PB15, 6, 2)
+#define PIN_PB15__FLEXCOM2_IO0		PINMUX_PIN(PIN_PB15, 7, 4)
+
+#define PIN_PB16			48
+#define PIN_PB16__GPIO			PINMUX_PIN(PIN_PB16, 0, 0)
+#define PIN_PB16__QSPI0_IO5		PINMUX_PIN(PIN_PB16, 1, 1)
+#define PIN_PB16__QSPI1_IO1		PINMUX_PIN(PIN_PB16, 2, 1)
+#define PIN_PB16__I2SMCC0_DIN0		PINMUX_PIN(PIN_PB16, 3, 3)
+#define PIN_PB16__FLEXCOM10_IO4		PINMUX_PIN(PIN_PB16, 4, 1)
+#define PIN_PB16__PWMH0			PINMUX_PIN(PIN_PB16, 5, 1)
+#define PIN_PB16__TIOB4			PINMUX_PIN(PIN_PB16, 6, 2)
+
+#define PIN_PB17			49
+#define PIN_PB17__GPIO			PINMUX_PIN(PIN_PB17, 0, 0)
+#define PIN_PB17__QSPI0_IO6		PINMUX_PIN(PIN_PB17, 1, 1)
+#define PIN_PB17__QSPI1_IO2		PINMUX_PIN(PIN_PB17, 2, 1)
+#define PIN_PB17__I2SMCC0_DOUT0		PINMUX_PIN(PIN_PB17, 3, 3)
+#define PIN_PB17__FLEXCOM10_IO3		PINMUX_PIN(PIN_PB17, 4, 1)
+#define PIN_PB17__PWML1			PINMUX_PIN(PIN_PB17, 5, 1)
+#define PIN_PB17__TIOA4			PINMUX_PIN(PIN_PB17, 6, 2)
+
+#define PIN_PB18			50
+#define PIN_PB18__GPIO			PINMUX_PIN(PIN_PB18, 0, 0)
+#define PIN_PB18__QSPI0_IO7		PINMUX_PIN(PIN_PB18, 1, 1)
+#define PIN_PB18__QSPI1_IO3		PINMUX_PIN(PIN_PB18, 2, 1)
+#define PIN_PB18__I2SMCC0_MCK		PINMUX_PIN(PIN_PB18, 3, 3)
+#define PIN_PB18__FLEXCOM10_IO2		PINMUX_PIN(PIN_PB18, 4, 1)
+#define PIN_PB18__PWMH1			PINMUX_PIN(PIN_PB18, 5, 1)
+#define PIN_PB18__TIOA5			PINMUX_PIN(PIN_PB18, 6, 2)
+
+#define PIN_PB19			51
+#define PIN_PB19__GPIO			PINMUX_PIN(PIN_PB19, 0, 0)
+#define PIN_PB19__QSPI0_DQS		PINMUX_PIN(PIN_PB19, 1, 1)
+#define PIN_PB19__EXT_IRQ1		PINMUX_PIN(PIN_PB19, 2, 2)
+#define PIN_PB19__PCK4			PINMUX_PIN(PIN_PB19, 3, 1)
+#define PIN_PB19__FLEXCOM10_IO1		PINMUX_PIN(PIN_PB19, 4, 1)
+#define PIN_PB19__PWML2			PINMUX_PIN(PIN_PB19, 5, 1)
+#define PIN_PB19__TIOB5			PINMUX_PIN(PIN_PB19, 6, 2)
+
+#define PIN_PB20			52
+#define PIN_PB20__GPIO			PINMUX_PIN(PIN_PB20, 0, 0)
+#define PIN_PB20__QSPI0_INT		PINMUX_PIN(PIN_PB20, 1, 1)
+#define PIN_PB20__QSPI1_CS		PINMUX_PIN(PIN_PB20, 2, 1)
+#define PIN_PB20__FLEXCOM10_IO0		PINMUX_PIN(PIN_PB20, 4, 1)
+#define PIN_PB20__PWMH2			PINMUX_PIN(PIN_PB20, 5, 1)
+#define PIN_PB20__TCLK5			PINMUX_PIN(PIN_PB20, 6, 2)
+
+#define PIN_PB21			53
+#define PIN_PB21__GPIO			PINMUX_PIN(PIN_PB21, 0, 0)
+#define PIN_PB21__SDMMC1_RSTN		PINMUX_PIN(PIN_PB21, 1, 1)
+#define PIN_PB21__FLEXCOM6_IO4		PINMUX_PIN(PIN_PB21, 2, 2)
+#define PIN_PB21__TIOB2			PINMUX_PIN(PIN_PB21, 3, 2)
+#define PIN_PB21__ADTRG			PINMUX_PIN(PIN_PB21, 4, 2)
+#define PIN_PB21__EXT_IRQ0		PINMUX_PIN(PIN_PB21, 5, 2)
+
+#define PIN_PB22			54
+#define PIN_PB22__GPIO			PINMUX_PIN(PIN_PB22, 0, 0)
+#define PIN_PB22__SDMMC1_CMD		PINMUX_PIN(PIN_PB22, 1, 1)
+#define PIN_PB22__FLEXCOM6_IO3		PINMUX_PIN(PIN_PB22, 2, 2)
+#define PIN_PB22__TCLK2			PINMUX_PIN(PIN_PB22, 3, 2)
+
+#define PIN_PB23			55
+#define PIN_PB23__GPIO			PINMUX_PIN(PIN_PB23, 0, 0)
+#define PIN_PB23__SDMMC1_CK		PINMUX_PIN(PIN_PB23, 1, 1)
+#define PIN_PB23__FLEXCOM6_IO2		PINMUX_PIN(PIN_PB23, 2, 2)
+#define PIN_PB23__TIOA2			PINMUX_PIN(PIN_PB23, 3, 2)
+
+#define PIN_PB24			56
+#define PIN_PB24__GPIO			PINMUX_PIN(PIN_PB24, 0, 0)
+#define PIN_PB24__SDMMC1_DAT0		PINMUX_PIN(PIN_PB24, 1, 1)
+#define PIN_PB24__FLEXCOM6_IO0		PINMUX_PIN(PIN_PB24, 2, 2)
+
+#define PIN_PB25			57
+#define PIN_PB25__GPIO			PINMUX_PIN(PIN_PB25, 0, 0)
+#define PIN_PB25__SDMMC1_DAT1		PINMUX_PIN(PIN_PB25, 1, 1)
+#define PIN_PB25__FLEXCOM6_IO1		PINMUX_PIN(PIN_PB25, 2, 2)
+#define PIN_PB25__TIOB2			PINMUX_PIN(PIN_PB25, 3, 1)
+
+#define PIN_PB26			58
+#define PIN_PB26__GPIO			PINMUX_PIN(PIN_PB26, 0, 0)
+#define PIN_PB26__SDMMC1_DAT2		PINMUX_PIN(PIN_PB26, 1, 1)
+#define PIN_PB26__FLEXCOM8_IO0		PINMUX_PIN(PIN_PB26, 2, 3)
+#define PIN_PB26__TCLK2			PINMUX_PIN(PIN_PB26, 3, 1)
+
+#define PIN_PB27			59
+#define PIN_PB27__GPIO			PINMUX_PIN(PIN_PB27, 0, 0)
+#define PIN_PB27__SDMMC1_DAT3		PINMUX_PIN(PIN_PB27, 1, 1)
+#define PIN_PB27__FLEXCOM8_IO1		PINMUX_PIN(PIN_PB27, 2, 3)
+#define PIN_PB27__TIOA2			PINMUX_PIN(PIN_PB27, 3, 1)
+
+#define PIN_PB28			60
+#define PIN_PB28__GPIO			PINMUX_PIN(PIN_PB28, 0, 0)
+#define PIN_PB28__SDMMC1_WP		PINMUX_PIN(PIN_PB28, 1, 1)
+#define PIN_PB28__FLEXCOM1_IO0		PINMUX_PIN(PIN_PB28, 3, 3)
+#define PIN_PB28__D15			PINMUX_PIN(PIN_PB28, 5, 1)
+
+#define PIN_PB29			61
+#define PIN_PB29__GPIO			PINMUX_PIN(PIN_PB29, 0, 0)
+#define PIN_PB29__SDMMC1_CD		PINMUX_PIN(PIN_PB29, 1, 1)
+#define PIN_PB29__I2SMCC0_MCK		PINMUX_PIN(PIN_PB29, 2, 1)
+#define PIN_PB29__FLEXCOM1_IO1		PINMUX_PIN(PIN_PB29, 3, 3)
+#define PIN_PB29__D14			PINMUX_PIN(PIN_PB29, 5, 2)
+
+#define PIN_PB30			62
+#define PIN_PB30__GPIO			PINMUX_PIN(PIN_PB30, 0, 0)
+#define PIN_PB30__SDMMC1_1V8SEL		PINMUX_PIN(PIN_PB30, 1, 1)
+#define PIN_PB30__I2SMCC1_MCK		PINMUX_PIN(PIN_PB30, 2, 2)
+#define PIN_PB30__FLEXCOM1_IO2		PINMUX_PIN(PIN_PB30, 3, 3)
+#define PIN_PB30__TIOA1			PINMUX_PIN(PIN_PB30, 4, 1)
+#define PIN_PB30__NCS1			PINMUX_PIN(PIN_PB30, 5, 1)
+
+#define PIN_PB31			63
+#define PIN_PB31__GPIO			PINMUX_PIN(PIN_PB31, 0, 0)
+#define PIN_PB31__PCK7			PINMUX_PIN(PIN_PB31, 1, 2)
+#define PIN_PB31__I2SMCC1_DIN1		PINMUX_PIN(PIN_PB31, 2, 1)
+#define PIN_PB31__FLEXCOM1_IO3		PINMUX_PIN(PIN_PB31, 3, 3)
+#define PIN_PB31__TCLK1			PINMUX_PIN(PIN_PB31, 4, 1)
+#define PIN_PB31__NWE			PINMUX_PIN(PIN_PB31, 5, 2)
+
+#define PIN_PC0				64
+#define PIN_PC0__GPIO			PINMUX_PIN(PIN_PC0, 0, 0)
+#define PIN_PC0__PCK6			PINMUX_PIN(PIN_PC0, 1, 2)
+#define PIN_PC0__I2SMCC1_DIN2		PINMUX_PIN(PIN_PC0, 2, 1)
+#define PIN_PC0__FLEXCOM9_IO4		PINMUX_PIN(PIN_PC0, 3, 2)
+#define PIN_PC0__TIOB1			PINMUX_PIN(PIN_PC0, 4, 1)
+#define PIN_PC0__NWR1			PINMUX_PIN(PIN_PC0, 5, 1)
+
+#define PIN_PC1				65
+#define PIN_PC1__GPIO			PINMUX_PIN(PIN_PC1, 0, 0)
+#define PIN_PC1__PCK5			PINMUX_PIN(PIN_PC1, 1, 1)
+#define PIN_PC1__FLEXCOM9_IO2		PINMUX_PIN(PIN_PC1, 3, 2)
+#define PIN_PC1__SMCK			PINMUX_PIN(PIN_PC1, 5, 1)
+
+#define PIN_PC2				66
+#define PIN_PC2__GPIO			PINMUX_PIN(PIN_PC2, 0, 0)
+#define PIN_PC2__EXT_IRQ0		PINMUX_PIN(PIN_PC2, 1, 3)
+#define PIN_PC2__FLEXCOM9_IO3		PINMUX_PIN(PIN_PC2, 3, 2)
+#define PIN_PC2__A11			PINMUX_PIN(PIN_PC2, 5, 1)
+
+#define PIN_PC3				67
+#define PIN_PC3__GPIO			PINMUX_PIN(PIN_PC3, 0, 0)
+#define PIN_PC3__SPDIF_RX		PINMUX_PIN(PIN_PC3, 1, 2)
+#define PIN_PC3__FLEXCOM9_IO0		PINMUX_PIN(PIN_PC3, 3, 2)
+#define PIN_PC3__FLEXCOM0_IO4		PINMUX_PIN(PIN_PC3, 4, 2)
+#define PIN_PC3__A10			PINMUX_PIN(PIN_PC3, 5, 1)
+
+#define PIN_PC4				68
+#define PIN_PC4__GPIO			PINMUX_PIN(PIN_PC4, 0, 0)
+#define PIN_PC4__SPDIF_TX		PINMUX_PIN(PIN_PC4, 1, 2)
+#define PIN_PC4__FLEXCOM9_IO1		PINMUX_PIN(PIN_PC4, 3, 2)
+#define PIN_PC4__FLEXCOM0_IO3		PINMUX_PIN(PIN_PC4, 4, 2)
+#define PIN_PC4__D0			PINMUX_PIN(PIN_PC4, 5, 2)
+
+#define PIN_PC5				69
+#define PIN_PC5__GPIO			PINMUX_PIN(PIN_PC5, 0, 0)
+#define PIN_PC5__I3CC_SDASPUE		PINMUX_PIN(PIN_PC5, 1, 1)
+#define PIN_PC5__I2SMCC1_DIN3		PINMUX_PIN(PIN_PC5, 2, 1)
+#define PIN_PC5__FLEXCOM0_IO2		PINMUX_PIN(PIN_PC5, 4, 2)
+#define PIN_PC5__D1			PINMUX_PIN(PIN_PC5, 5, 2)
+
+#define PIN_PC6				70
+#define PIN_PC6__GPIO			PINMUX_PIN(PIN_PC6, 0, 0)
+#define PIN_PC6__I3CC_SCL		PINMUX_PIN(PIN_PC6, 1, 1)
+#define PIN_PC6__FLEXCOM0_IO1		PINMUX_PIN(PIN_PC6, 4, 2)
+#define PIN_PC6__D4			PINMUX_PIN(PIN_PC6, 5, 2)
+
+#define PIN_PC7				71
+#define PIN_PC7__GPIO			PINMUX_PIN(PIN_PC7, 0, 0)
+#define PIN_PC7__I3CC_SDA		PINMUX_PIN(PIN_PC7, 1, 1)
+#define PIN_PC7__FLEXCOM0_IO0		PINMUX_PIN(PIN_PC7, 4, 2)
+#define PIN_PC7__D5			PINMUX_PIN(PIN_PC7, 5, 2)
+
+#define PIN_PC8				72
+#define PIN_PC8__GPIO			PINMUX_PIN(PIN_PC8, 0, 0)
+#define PIN_PC8__I2SMCC0_DIN1		PINMUX_PIN(PIN_PC8, 1, 1)
+#define PIN_PC8__PDMC0_DS1		PINMUX_PIN(PIN_PC8, 2, 2)
+#define PIN_PC8__I2SMCC1_DOUT1		PINMUX_PIN(PIN_PC8, 3, 1)
+#define PIN_PC8__FLEXCOM9_IO0		PINMUX_PIN(PIN_PC8, 4, 1)
+#define PIN_PC8__D6			PINMUX_PIN(PIN_PC8, 5, 2)
+
+#define PIN_PC9				73
+#define PIN_PC9__GPIO			PINMUX_PIN(PIN_PC9, 0, 0)
+#define PIN_PC9__I2SMCC0_DIN2		PINMUX_PIN(PIN_PC9, 1, 1)
+#define PIN_PC9__PDMC0_CLK		PINMUX_PIN(PIN_PC9, 2, 2)
+#define PIN_PC9__I2SMCC1_DOUT2		PINMUX_PIN(PIN_PC9, 3, 1)
+#define PIN_PC9__FLEXCOM9_IO1		PINMUX_PIN(PIN_PC9, 4, 1)
+#define PIN_PC9__D7			PINMUX_PIN(PIN_PC9, 5, 2)
+
+#define PIN_PC10			74
+#define PIN_PC10__GPIO			PINMUX_PIN(PIN_PC10, 0, 0)
+#define PIN_PC10__I2SMCC0_DIN3		PINMUX_PIN(PIN_PC10, 1, 1)
+#define PIN_PC10__PDMC0_DS0		PINMUX_PIN(PIN_PC10, 2, 2)
+#define PIN_PC10__I2SMCC1_DOUT3		PINMUX_PIN(PIN_PC10, 3, 1)
+#define PIN_PC10__FLEXCOM9_IO2		PINMUX_PIN(PIN_PC10, 4, 1)
+#define PIN_PC10__D2			PINMUX_PIN(PIN_PC10, 5, 2)
+
+#define PIN_PC11			75
+#define PIN_PC11__GPIO			PINMUX_PIN(PIN_PC11, 0, 0)
+#define PIN_PC11__I2SMCC0_DOUT1		PINMUX_PIN(PIN_PC11, 1, 1)
+#define PIN_PC11__PDMC1_DS0		PINMUX_PIN(PIN_PC11, 2, 1)
+#define PIN_PC11__FLEXCOM9_IO3		PINMUX_PIN(PIN_PC11, 4, 1)
+#define PIN_PC10__D3			PINMUX_PIN(PIN_PC10, 5, 2)
+
+#define PIN_PC12			76
+#define PIN_PC12__GPIO			PINMUX_PIN(PIN_PC12, 0, 0)
+#define PIN_PC12__I2SMCC0_DOUT2		PINMUX_PIN(PIN_PC12, 1, 1)
+#define PIN_PC12__PDMC1_CLK		PINMUX_PIN(PIN_PC12, 2, 1)
+#define PIN_PC12__FLEXCOM9_IO4		PINMUX_PIN(PIN_PC12, 4, 1)
+#define PIN_PC12__A9			PINMUX_PIN(PIN_PC12, 5, 1)
+
+#define PIN_PC13			77
+#define PIN_PC13__GPIO			PINMUX_PIN(PIN_PC13, 0, 0)
+#define PIN_PC13__I2SMCC0_DOUT3		PINMUX_PIN(PIN_PC13, 1, 1)
+#define PIN_PC13__PDMC1_DS1		PINMUX_PIN(PIN_PC13, 2, 1)
+#define PIN_PC13__A8			PINMUX_PIN(PIN_PC13, 5, 1)
+
+#define PIN_PC14			78
+#define PIN_PC14__GPIO			PINMUX_PIN(PIN_PC14, 0, 0)
+#define PIN_PC14__I2SMCC1_DIN0		PINMUX_PIN(PIN_PC14, 1, 1)
+#define PIN_PC14__SPDIF_RX		PINMUX_PIN(PIN_PC14, 2, 3)
+#define PIN_PC14__FLEXCOM1_IO0		PINMUX_PIN(PIN_PC14, 3, 2)
+#define PIN_PC14__A7			PINMUX_PIN(PIN_PC14, 5, 1)
+
+#define PIN_PC15			79
+#define PIN_PC15__GPIO			PINMUX_PIN(PIN_PC15, 0, 0)
+#define PIN_PC15__I2SMCC1_WS		PINMUX_PIN(PIN_PC15, 1, 1)
+#define PIN_PC15__PDMC1_DS1		PINMUX_PIN(PIN_PC15, 2, 2)
+#define PIN_PC15__FLEXCOM1_IO1		PINMUX_PIN(PIN_PC15, 3, 2)
+#define PIN_PC15__A6			PINMUX_PIN(PIN_PC15, 5, 1)
+
+#define PIN_PC16			80
+#define PIN_PC16__GPIO			PINMUX_PIN(PIN_PC16, 0, 0)
+#define PIN_PC16__I2SMCC1_CK		PINMUX_PIN(PIN_PC16, 1, 1)
+#define PIN_PC16__PDMC1_CLK		PINMUX_PIN(PIN_PC16, 2, 2)
+#define PIN_PC16__FLEXCOM1_IO2		PINMUX_PIN(PIN_PC16, 3, 2)
+#define PIN_PC16__TIOA1			PINMUX_PIN(PIN_PC16, 4, 2)
+#define PIN_PC16__A5			PINMUX_PIN(PIN_PC16, 5, 1)
+
+#define PIN_PC17			81
+#define PIN_PC17__GPIO			PINMUX_PIN(PIN_PC17, 0, 0)
+#define PIN_PC17__I2SMCC1_DOUT0		PINMUX_PIN(PIN_PC17, 1, 1)
+#define PIN_PC17__PDMC1_DS0		PINMUX_PIN(PIN_PC17, 2, 2)
+#define PIN_PC17__FLEXCOM1_IO3		PINMUX_PIN(PIN_PC17, 3, 2)
+#define PIN_PC17__TCLK1			PINMUX_PIN(PIN_PC17, 4, 2)
+#define PIN_PC17__A4			PINMUX_PIN(PIN_PC17, 5, 1)
+
+#define PIN_PC18			82
+#define PIN_PC18__GPIO			PINMUX_PIN(PIN_PC18, 0, 0)
+#define PIN_PC18__I2SMCC0_DIN0		PINMUX_PIN(PIN_PC18, 1, 1)
+#define PIN_PC18__SPDIF_TX		PINMUX_PIN(PIN_PC18, 2, 3)
+#define PIN_PC18__FLEXCOM1_IO4		PINMUX_PIN(PIN_PC18, 3, 2)
+#define PIN_PC18__TIOB1			PINMUX_PIN(PIN_PC18, 4, 2)
+#define PIN_PC18__A3			PINMUX_PIN(PIN_PC18, 5, 1)
+
+#define PIN_PC19			83
+#define PIN_PC19__GPIO			PINMUX_PIN(PIN_PC19, 0, 0)
+#define PIN_PC19__I2SMCC0_WS		PINMUX_PIN(PIN_PC19, 1, 1)
+#define PIN_PC19__PCK6			PINMUX_PIN(PIN_PC19, 2, 1)
+#define PIN_PC19__A2			PINMUX_PIN(PIN_PC19, 5, 1)
+
+#define PIN_PC20			84
+#define PIN_PC20__GPIO			PINMUX_PIN(PIN_PC20, 0, 0)
+#define PIN_PC20__I2SMCC0_DOUT0		PINMUX_PIN(PIN_PC20, 1, 1)
+#define PIN_PC20__A1			PINMUX_PIN(PIN_PC20, 5, 1)
+
+#define PIN_PC21			85
+#define PIN_PC21__GPIO			PINMUX_PIN(PIN_PC21, 0, 0)
+#define PIN_PC21__I2SMCC0_CK		PINMUX_PIN(PIN_PC21, 1, 1)
+#define PIN_PC21__PCK7			PINMUX_PIN(PIN_PC21, 2, 1)
+#define PIN_PC21__A0			PINMUX_PIN(PIN_PC21, 5, 1)
+
+#define PIN_PC22			86
+#define PIN_PC22__GPIO			PINMUX_PIN(PIN_PC22, 0, 0)
+#define PIN_PC22__NTRST			PINMUX_PIN(PIN_PC22, 1, 1)
+#define PIN_PC22__NWAIT			PINMUX_PIN(PIN_PC22, 5, 1)
+
+#define PIN_PC23			87
+#define PIN_PC23__GPIO			PINMUX_PIN(PIN_PC23, 0, 0)
+#define PIN_PC23__TCK_SWCLK		PINMUX_PIN(PIN_PC23, 1, 1)
+
+#define PIN_PC24			88
+#define PIN_PC24__GPIO			PINMUX_PIN(PIN_PC24, 0, 0)
+#define PIN_PC24__TMS_SWDIO		PINMUX_PIN(PIN_PC24, 1, 1)
+
+#define PIN_PC25			89
+#define PIN_PC25__GPIO			PINMUX_PIN(PIN_PC25, 0, 0)
+#define PIN_PC25__TDI			PINMUX_PIN(PIN_PC25, 1, 1)
+
+#define PIN_PC26			90
+#define PIN_PC26__GPIO			PINMUX_PIN(PIN_PC26, 0, 0)
+#define PIN_PC26__TDO			PINMUX_PIN(PIN_PC26, 1, 1)
+#define PIN_PC26__A15			PINMUX_PIN(PIN_PC26, 5, 1)
+
+#define PIN_PC27			91
+#define PIN_PC27__GPIO			PINMUX_PIN(PIN_PC27, 0, 0)
+#define PIN_PC27__SDMMC2_CMD		PINMUX_PIN(PIN_PC27, 1, 1)
+#define PIN_PC27__FLEXCOM8_IO0		PINMUX_PIN(PIN_PC27, 2, 2)
+#define PIN_PC27__TD1			PINMUX_PIN(PIN_PC27, 4, 2)
+#define PIN_PC27__D8			PINMUX_PIN(PIN_PC27, 5, 1)
+
+#define PIN_PC28			92
+#define PIN_PC28__GPIO			PINMUX_PIN(PIN_PC28, 0, 0)
+#define PIN_PC28__SDMMC2_CK		PINMUX_PIN(PIN_PC28, 1, 1)
+#define PIN_PC28__FLEXCOM8_IO1		PINMUX_PIN(PIN_PC28, 2, 2)
+#define PIN_PC28__TF1			PINMUX_PIN(PIN_PC28, 4, 2)
+#define PIN_PC28__D9			PINMUX_PIN(PIN_PC28, 5, 1)
+
+#define PIN_PC29			93
+#define PIN_PC29__GPIO			PINMUX_PIN(PIN_PC29, 0, 0)
+#define PIN_PC29__SDMMC2_DAT0		PINMUX_PIN(PIN_PC29, 1, 1)
+#define PIN_PC29__FLEXCOM8_IO2		PINMUX_PIN(PIN_PC29, 2, 2)
+#define PIN_PC29__TK1			PINMUX_PIN(PIN_PC29, 4, 2)
+#define PIN_PC29__D10			PINMUX_PIN(PIN_PC29, 5, 1)
+#define PIN_PC29__TCLK0			PINMUX_PIN(PIN_PC29, 6, 1)
+
+#define PIN_PC30			94
+#define PIN_PC30__GPIO			PINMUX_PIN(PIN_PC30, 0, 0)
+#define PIN_PC30__SDMMC2_DAT1		PINMUX_PIN(PIN_PC30, 1, 1)
+#define PIN_PC30__FLEXCOM8_IO3		PINMUX_PIN(PIN_PC30, 2, 2)
+#define PIN_PC30__RD1			PINMUX_PIN(PIN_PC30, 4, 2)
+#define PIN_PC30__D11			PINMUX_PIN(PIN_PC30, 5, 1)
+#define PIN_PC30__TIOA0			PINMUX_PIN(PIN_PC30, 6, 1)
+
+#define PIN_PC31			95
+#define PIN_PC31__GPIO			PINMUX_PIN(PIN_PC31, 0, 0)
+#define PIN_PC31__SDMMC2_DAT2		PINMUX_PIN(PIN_PC31, 1, 1)
+#define PIN_PC31__FLEXCOM8_IO4		PINMUX_PIN(PIN_PC31, 2, 2)
+#define PIN_PC31__PCK0			PINMUX_PIN(PIN_PC31, 3, 2)
+#define PIN_PC31__RK1			PINMUX_PIN(PIN_PC31, 4, 2)
+#define PIN_PC31__D12			PINMUX_PIN(PIN_PC31, 5, 1)
+#define PIN_PC31__TIOB0			PINMUX_PIN(PIN_PC31, 6, 1)
+
+#define PIN_PD0				96
+#define PIN_PD0__GPIO			PINMUX_PIN(PIN_PD0, 0, 0)
+#define PIN_PD0__SDMMC2_DAT3		PINMUX_PIN(PIN_PD0, 1, 1)
+#define PIN_PD0__PCK1			PINMUX_PIN(PIN_PD0, 3, 2)
+#define PIN_PD0__RF1			PINMUX_PIN(PIN_PD0, 4, 2)
+#define PIN_PD0__D13			PINMUX_PIN(PIN_PD0, 5, 1)
+
+#define PIN_PD1				97
+#define PIN_PD1__GPIO			PINMUX_PIN(PIN_PD1, 0, 0)
+#define PIN_PD1__SDMMC2_WP		PINMUX_PIN(PIN_PD1, 1, 1)
+#define PIN_PD1__FLEXCOM1_IO5		PINMUX_PIN(PIN_PD1, 2, 1)
+#define PIN_PD1__LCDC_HSYNC		PINMUX_PIN(PIN_PD1, 3, 2)
+#define PIN_PD1__FLEXCOM3_IO0		PINMUX_PIN(PIN_PD1, 4, 3)
+
+#define PIN_PD2				98
+#define PIN_PD2__GPIO			PINMUX_PIN(PIN_PD2, 0, 0)
+#define PIN_PD2__SDMMC2_CD		PINMUX_PIN(PIN_PD2, 1, 1)
+#define PIN_PD2__FLEXCOM1_IO6		PINMUX_PIN(PIN_PD2, 2, 1)
+#define PIN_PD2__LCDC_VSYNC		PINMUX_PIN(PIN_PD2, 3, 2)
+#define PIN_PD2__FLEXCOM3_IO1		PINMUX_PIN(PIN_PD2, 4, 3)
+
+#define PIN_PD3				99
+#define PIN_PD3__GPIO			PINMUX_PIN(PIN_PD3, 0, 0)
+#define PIN_PD3__SDMMC2_1V8SEL		PINMUX_PIN(PIN_PD3, 1, 1)
+#define PIN_PD3__FLEXCOM1_IO4		PINMUX_PIN(PIN_PD3, 2, 1)
+#define PIN_PD3__TIOA0			PINMUX_PIN(PIN_PD3, 3, 2)
+#define PIN_PD3__FLEXCOM3_IO2		PINMUX_PIN(PIN_PD3, 4, 3)
+#define PIN_PD3__EXT_IRQ1		PINMUX_PIN(PIN_PD3, 5, 3)
+
+#define PIN_PD4				100
+#define PIN_PD4__GPIO			PINMUX_PIN(PIN_PD4, 0, 0)
+#define PIN_PD4__LCDC_HSYNC		PINMUX_PIN(PIN_PD4, 1, 1)
+#define PIN_PD4__FLEXCOM1_IO2		PINMUX_PIN(PIN_PD4, 2, 1)
+#define PIN_PD4__TIOB0			PINMUX_PIN(PIN_PD4, 3, 2)
+#define PIN_PD4__FLEXCOM7_IO1		PINMUX_PIN(PIN_PD4, 4, 3)
+
+#define PIN_PD5				101
+#define PIN_PD5__GPIO			PINMUX_PIN(PIN_PD5, 0, 0)
+#define PIN_PD5__LCDC_VSYNC		PINMUX_PIN(PIN_PD5, 1, 1)
+#define PIN_PD5__FLEXCOM1_IO3		PINMUX_PIN(PIN_PD5, 2, 1)
+#define PIN_PD5__TCLK0			PINMUX_PIN(PIN_PD5, 3, 2)
+#define PIN_PD5__FLEXCOM7_IO0		PINMUX_PIN(PIN_PD5, 4, 3)
+
+#define PIN_PD6				102
+#define PIN_PD6__GPIO			PINMUX_PIN(PIN_PD6, 0, 0)
+#define PIN_PD6__LCDC_PWM		PINMUX_PIN(PIN_PD6, 1, 1)
+#define PIN_PD6__FLEXCOM1_IO1		PINMUX_PIN(PIN_PD6, 2, 1)
+#define PIN_PD6__FLEXCOM7_IO2		PINMUX_PIN(PIN_PD6, 4, 3)
+
+#define PIN_PD7				103
+#define PIN_PD7__GPIO			PINMUX_PIN(PIN_PD7, 0, 0)
+#define PIN_PD7__LCDC_DISP		PINMUX_PIN(PIN_PD7, 1, 1)
+#define PIN_PD7__FLEXCOM1_IO0		PINMUX_PIN(PIN_PD7, 2, 1)
+#define PIN_PD7__FLEXCOM7_IO3		PINMUX_PIN(PIN_PD7, 4, 3)
+
+#define PIN_PD8				104
+#define PIN_PD8__GPIO			PINMUX_PIN(PIN_PD8, 0, 0)
+#define PIN_PD8__CANTX0			PINMUX_PIN(PIN_PD8, 1, 1)
+#define PIN_PD8__FLEXCOM7_IO0		PINMUX_PIN(PIN_PD8, 2, 1)
+
+#define PIN_PD9				105
+#define PIN_PD9__GPIO			PINMUX_PIN(PIN_PD9, 0, 0)
+#define PIN_PD9__CANRX0			PINMUX_PIN(PIN_PD9, 1, 1)
+#define PIN_PD9__FLEXCOM7_IO1		PINMUX_PIN(PIN_PD9, 2, 1)
+
+#define PIN_PD10			106
+#define PIN_PD10__GPIO			PINMUX_PIN(PIN_PD10, 0, 0)
+#define PIN_PD10__CANTX1		PINMUX_PIN(PIN_PD10, 1, 1)
+#define PIN_PD10__FLEXCOM7_IO2		PINMUX_PIN(PIN_PD10, 2, 1)
+#define PIN_PD10__TIOA1			PINMUX_PIN(PIN_PD10, 3, 3)
+
+#define PIN_PD11			107
+#define PIN_PD11__GPIO			PINMUX_PIN(PIN_PD11, 0, 0)
+#define PIN_PD11__CANRX1		PINMUX_PIN(PIN_PD11, 1, 1)
+#define PIN_PD11__FLEXCOM7_IO3		PINMUX_PIN(PIN_PD11, 2, 1)
+#define PIN_PD11__TCLK1			PINMUX_PIN(PIN_PD11, 3, 3)
+
+#define PIN_PD12			108
+#define PIN_PD12__GPIO			PINMUX_PIN(PIN_PD12, 0, 0)
+#define PIN_PD12__CANTX2		PINMUX_PIN(PIN_PD12, 1, 1)
+#define PIN_PD12__FLEXCOM7_IO4		PINMUX_PIN(PIN_PD12, 2, 1)
+#define PIN_PD12__TIOB1			PINMUX_PIN(PIN_PD12, 3, 3)
+#define PIN_PD12__PCK2			PINMUX_PIN(PIN_PD12, 4, 2)
+#define PIN_PD12__FLEXCOM3_IO3		PINMUX_PIN(PIN_PD12, 5, 3)
+
+#define PIN_PD13			109
+#define PIN_PD13__GPIO			PINMUX_PIN(PIN_PD13, 0, 0)
+#define PIN_PD13__CANRX2		PINMUX_PIN(PIN_PD13, 1, 1)
+#define PIN_PD13__FLEXCOM5_IO4		PINMUX_PIN(PIN_PD13, 2, 1)
+#define PIN_PD13__TIOA2			PINMUX_PIN(PIN_PD13, 3, 3)
+#define PIN_PD13__PCK3			PINMUX_PIN(PIN_PD13, 4, 2)
+
+#define PIN_PD14			110
+#define PIN_PD14__GPIO			PINMUX_PIN(PIN_PD14, 0, 0)
+#define PIN_PD14__CANTX3		PINMUX_PIN(PIN_PD14, 1, 1)
+#define PIN_PD14__FLEXCOM5_IO2		PINMUX_PIN(PIN_PD14, 2, 1)
+#define PIN_PD14__TIOB2			PINMUX_PIN(PIN_PD14, 3, 3)
+
+#define PIN_PD15			111
+#define PIN_PD15__GPIO			PINMUX_PIN(PIN_PD15, 0, 0)
+#define PIN_PD15__CANRX3		PINMUX_PIN(PIN_PD15, 1, 1)
+#define PIN_PD15__FLEXCOM5_IO3		PINMUX_PIN(PIN_PD15, 2, 1)
+#define PIN_PD15__TCLK2			PINMUX_PIN(PIN_PD15, 3, 3)
+
+#define PIN_PD16			112
+#define PIN_PD16__GPIO			PINMUX_PIN(PIN_PD16, 0, 0)
+#define PIN_PD16__CANTX4		PINMUX_PIN(PIN_PD16, 1, 1)
+#define PIN_PD16__FLEXCOM5_IO0		PINMUX_PIN(PIN_PD16, 2, 1)
+
+#define PIN_PD17			113
+#define PIN_PD17__GPIO			PINMUX_PIN(PIN_PD17, 0, 0)
+#define PIN_PD17__CANRX4		PINMUX_PIN(PIN_PD17, 1, 1)
+#define PIN_PD17__FLEXCOM5_IO1		PINMUX_PIN(PIN_PD17, 2, 1)
+
+#define PIN_PD18			114
+#define PIN_PD18__GPIO			PINMUX_PIN(PIN_PD18, 0, 0)
+#define PIN_PD18__FLEXCOM6_IO0		PINMUX_PIN(PIN_PD18, 2, 4)
+#define PIN_PD18__CANTX1		PINMUX_PIN(PIN_PD18, 3, 2)
+#define PIN_PD18__PCK4			PINMUX_PIN(PIN_PD18, 4, 2)
+
+#define PIN_PD19			115
+#define PIN_PD19__GPIO			PINMUX_PIN(PIN_PD19, 0, 0)
+#define PIN_PD19__FLEXCOM6_IO1		PINMUX_PIN(PIN_PD19, 2, 4)
+#define PIN_PD19__CANRX1		PINMUX_PIN(PIN_PD19, 3, 2)
+#define PIN_PD19__PCK2			PINMUX_PIN(PIN_PD19, 4, 3)
+
+#define PIN_PD20			116
+#define PIN_PD20__GPIO			PINMUX_PIN(PIN_PD20, 0, 0)
+#define PIN_PD20__PFLEXCOM6_IO2		PINMUX_PIN(PIN_PD20, 2, 4)
+#define PIN_PD20__I2SMCC1_MCK		PINMUX_PIN(PIN_PD20, 3, 2)
+#define PIN_PD20__PCK3			PINMUX_PIN(PIN_PD20, 4, 3)
+
+#define PIN_PD21			117
+#define PIN_PD21__GPIO			PINMUX_PIN(PIN_PD21, 0, 0)
+#define PIN_PD21__G1_TXCTL		PINMUX_PIN(PIN_PD21, 1, 2)
+#define PIN_PD21__FLEXCOM6_IO2		PINMUX_PIN(PIN_PD21, 2, 3)
+#define PIN_PD21__TK1			PINMUX_PIN(PIN_PD21, 3, 1)
+
+#define PIN_PD22			118
+#define PIN_PD22__GPIO			PINMUX_PIN(PIN_PD22, 0, 0)
+#define PIN_PD22__G1_TX0		PINMUX_PIN(PIN_PD22, 1, 1)
+#define PIN_PD22__FLEXCOM6_IO3		PINMUX_PIN(PIN_PD22, 2, 3)
+#define PIN_PD22__TF1			PINMUX_PIN(PIN_PD22, 3, 1)
+
+#define PIN_PD23			119
+#define PIN_PD23__GPIO			PINMUX_PIN(PIN_PD23, 0, 0)
+#define PIN_PD23__G1_TX1		PINMUX_PIN(PIN_PD23, 1, 1)
+#define PIN_PD23__FLEXCOM6_IO4		PINMUX_PIN(PIN_PD23, 2, 3)
+#define PIN_PD23__TD1			PINMUX_PIN(PIN_PD23, 3, 1)
+
+#define PIN_PD24			120
+#define PIN_PD24__GPIO			PINMUX_PIN(PIN_PD24, 0, 0)
+#define PIN_PD24__G1_RXCTL		PINMUX_PIN(PIN_PD24, 1, 1)
+#define PIN_PD24__FLEXCOM6_IO0		PINMUX_PIN(PIN_PD24, 2, 3)
+#define PIN_PD24__RD1			PINMUX_PIN(PIN_PD24, 3, 1)
+#define PIN_PD24__PDMC0_DS1		PINMUX_PIN(PIN_PD24, 5, 3)
+
+#define PIN_PD25			121
+#define PIN_PD25__GPIO			PINMUX_PIN(PIN_PD25, 0, 0)
+#define PIN_PD25__G1_MDC		PINMUX_PIN(PIN_PD25, 1, 1)
+#define PIN_PD25__FLEXCOM6_IO1		PINMUX_PIN(PIN_PD25, 2, 3)
+#define PIN_PD25__RK1			PINMUX_PIN(PIN_PD25, 3, 1)
+#define PIN_PD25__PDMC0_CLK		PINMUX_PIN(PIN_PD25, 5, 3)
+
+#define PIN_PD26			122
+#define PIN_PD26__GPIO			PINMUX_PIN(PIN_PD26, 0, 0)
+#define PIN_PD26__G1_MDIO		PINMUX_PIN(PIN_PD26, 1, 1)
+#define PIN_PD26__FLEXCOM7_IO4		PINMUX_PIN(PIN_PD26, 2, 2)
+#define PIN_PD26__RF1			PINMUX_PIN(PIN_PD26, 3, 1)
+#define PIN_PD26__I2SMCC1_DIN2		PINMUX_PIN(PIN_PD26, 4, 2)
+#define PIN_PD26__PDMC0_DS0		PINMUX_PIN(PIN_PD26, 5, 3)
+
+#define PIN_PD27			123
+#define PIN_PD27__GPIO			PINMUX_PIN(PIN_PD27, 0, 0)
+#define PIN_PD27__G1_RX0		PINMUX_PIN(PIN_PD27, 1, 1)
+#define PIN_PD27__FLEXCOM7_IO0		PINMUX_PIN(PIN_PD27, 2, 2)
+#define PIN_PD27__SPDIF_RX		PINMUX_PIN(PIN_PD27, 3, 1)
+#define PIN_PD27__I2SMCC1_DIN3		PINMUX_PIN(PIN_PD27, 4, 2)
+
+#define PIN_PD28			124
+#define PIN_PD28__GPIO			PINMUX_PIN(PIN_PD28, 0, 0)
+#define PIN_PD28__G1_RX1		PINMUX_PIN(PIN_PD28, 1, 1)
+#define PIN_PD28__FLEXCOM7_IO1		PINMUX_PIN(PIN_PD28, 2, 2)
+#define PIN_PD28__SPDIF_TX		PINMUX_PIN(PIN_PD28, 3, 1)
+#define PIN_PD28__I2SMCC1_DIN1		PINMUX_PIN(PIN_PD28, 4, 2)
+
+#define PIN_PD29			125
+#define PIN_PD29__GPIO			PINMUX_PIN(PIN_PD29, 0, 0)
+#define PIN_PD29__G1_REFCK		PINMUX_PIN(PIN_PD29, 1, 2)
+#define PIN_PD29__FLEXCOM7_IO2		PINMUX_PIN(PIN_PD29, 2, 2)
+#define PIN_PD29__I2SMCC1_DOUT3		PINMUX_PIN(PIN_PD29, 3, 2)
+
+#define PIN_PD30			126
+#define PIN_PD30__GPIO			PINMUX_PIN(PIN_PD30, 0, 0)
+#define PIN_PD30__G1_RX2		PINMUX_PIN(PIN_PD30, 1, 1)
+#define PIN_PD30__FLEXCOM7_IO3		PINMUX_PIN(PIN_PD30, 2, 2)
+#define PIN_PD30__I2SMCC1_DOUT1		PINMUX_PIN(PIN_PD30, 3, 2)
+#define PIN_PD30__PDMC1_DS1		PINMUX_PIN(PIN_PD30, 4, 3)
+#define PIN_PD30__G1_RXER		PINMUX_PIN(PIN_PD30, 5, 2)
+
+#define PIN_PD31			127
+#define PIN_PD31__GPIO			PINMUX_PIN(PIN_PD31, 0, 0)
+#define PIN_PD31__G1_RX3		PINMUX_PIN(PIN_PD31, 1, 1)
+#define PIN_PD31__FLEXCOM5_IO4		PINMUX_PIN(PIN_PD31, 2, 2)
+#define PIN_PD31__I2SMCC1_DOUT2		PINMUX_PIN(PIN_PD31, 3, 3)
+#define PIN_PD31__PDMC1_DS0		PINMUX_PIN(PIN_PD31, 4, 3)
+
+#define PIN_PE0				128
+#define PIN_PE0__GPIO			PINMUX_PIN(PIN_PE0, 0, 0)
+#define PIN_PE0__G1_TX2			PINMUX_PIN(PIN_PE0, 1, 1)
+#define PIN_PE0__FLEXCOM5_IO2		PINMUX_PIN(PIN_PE0, 2, 2)
+#define PIN_PE0__I2SMCC1_DIN0		PINMUX_PIN(PIN_PE0, 3, 2)
+#define PIN_PE0__PDMC1_CLK		PINMUX_PIN(PIN_PE0, 4, 3)
+
+#define PIN_PE1				129
+#define PIN_PE1__GPIO			PINMUX_PIN(PIN_PE1, 0, 0)
+#define PIN_PE1__G1_TX3			PINMUX_PIN(PIN_PE1, 1, 1)
+#define PIN_PE1__FLEXCOM5_IO3		PINMUX_PIN(PIN_PE1, 2, 2)
+#define PIN_PE1__I2SMCC1_WS		PINMUX_PIN(PIN_PE1, 3, 2)
+#define PIN_PE1__PDMC0_DS1		PINMUX_PIN(PIN_PE1, 4, 4)
+
+#define PIN_PE2				130
+#define PIN_PE2__GPIO			PINMUX_PIN(PIN_PE2, 0, 0)
+#define PIN_PE2__G1_RXCK		PINMUX_PIN(PIN_PE2, 1, 1)
+#define PIN_PE2__FLEXCOM5_IO1		PINMUX_PIN(PIN_PE2, 2, 2)
+#define PIN_PE2__I2SMCC1_CK		PINMUX_PIN(PIN_PE2, 3, 2)
+#define PIN_PE2__PDMC0_CLK		PINMUX_PIN(PIN_PE2, 4, 4)
+
+#define PIN_PE3				131
+#define PIN_PE3__GPIO			PINMUX_PIN(PIN_PE3, 0, 0)
+#define PIN_PE3__G1_TSUCOMP		PINMUX_PIN(PIN_PE3, 1, 1)
+#define PIN_PE3__FLEXCOM5_IO0		PINMUX_PIN(PIN_PE3, 2, 2)
+#define PIN_PE3__I2SMCC1_DOUT0		PINMUX_PIN(PIN_PE3, 3, 2)
+#define PIN_PE3__PDMC0_DS0		PINMUX_PIN(PIN_PE3, 4, 4)
+
+#define PIN_PE4				132
+#define PIN_PE4__GPIO			PINMUX_PIN(PIN_PE4, 0, 0)
+#define PIN_PE4__LCDC_DAT0		PINMUX_PIN(PIN_PE4, 1, 1)
+#define PIN_PE4__FLEXCOM2_IO2		PINMUX_PIN(PIN_PE4, 2, 1)
+#define PIN_PE4__PWML0			PINMUX_PIN(PIN_PE4, 3, 2)
+#define PIN_PE4__TIOA3			PINMUX_PIN(PIN_PE4, 4, 1)
+#define PIN_PE4__I2SMCC0_DIN1		PINMUX_PIN(PIN_PE4, 5, 2)
+
+#define PIN_PE5				133
+#define PIN_PE5__GPIO			PINMUX_PIN(PIN_PE5, 0, 0)
+#define PIN_PE5__LCDC_DAT1		PINMUX_PIN(PIN_PE5, 1, 1)
+#define PIN_PE5__FLEXCOM2_IO3		PINMUX_PIN(PIN_PE5, 2, 1)
+#define PIN_PE5__PWMH0			PINMUX_PIN(PIN_PE5, 3, 2)
+#define PIN_PE5__TIOB3			PINMUX_PIN(PIN_PE5, 4, 1)
+#define PIN_PE5__I2SMCC0_DIN2		PINMUX_PIN(PIN_PE5, 5, 2)
+
+#define PIN_PE6				134
+#define PIN_PE6__GPIO			PINMUX_PIN(PIN_PE6, 0, 0)
+#define PIN_PE6__LCDC_DAT2		PINMUX_PIN(PIN_PE6, 1, 1)
+#define PIN_PE6__FLEXCOM2_IO4		PINMUX_PIN(PIN_PE6, 2, 1)
+#define PIN_PE6__PWML1			PINMUX_PIN(PIN_PE6, 3, 2)
+#define PIN_PE6__TCLK3			PINMUX_PIN(PIN_PE6, 4, 1)
+#define PIN_PE6__I2SMCC0_DIN3		PINMUX_PIN(PIN_PE6, 5, 2)
+
+#define PIN_PE7				135
+#define PIN_PE7__GPIO			PINMUX_PIN(PIN_PE7, 0, 0)
+#define PIN_PE7__LCDC_DAT3		PINMUX_PIN(PIN_PE7, 1, 1)
+#define PIN_PE7__FLEXCOM2_IO5		PINMUX_PIN(PIN_PE7, 2, 1)
+#define PIN_PE7__PWMH1			PINMUX_PIN(PIN_PE7, 3, 2)
+#define PIN_PE7__TIOA4			PINMUX_PIN(PIN_PE7, 4, 1)
+#define PIN_PE7__I2SMCC0_DOUT1		PINMUX_PIN(PIN_PE7, 5, 2)
+
+#define PIN_PE8				136
+#define PIN_PE8__GPIO			PINMUX_PIN(PIN_PE8, 0, 0)
+#define PIN_PE8__LCDC_DAT4		PINMUX_PIN(PIN_PE8, 1, 1)
+#define PIN_PE8__FLEXCOM2_IO0		PINMUX_PIN(PIN_PE8, 2, 1)
+#define PIN_PE8__PWML2			PINMUX_PIN(PIN_PE8, 3, 2)
+#define PIN_PE8__TIOB4			PINMUX_PIN(PIN_PE8, 4, 1)
+#define PIN_PE8__I2SMCC0_CK		PINMUX_PIN(PIN_PE8, 5, 2)
+
+#define PIN_PE9				137
+#define PIN_PE9__GPIO			PINMUX_PIN(PIN_PE9, 0, 0)
+#define PIN_PE9__LCDC_DAT5		PINMUX_PIN(PIN_PE9, 1, 1)
+#define PIN_PE9__FLEXCOM2_IO1		PINMUX_PIN(PIN_PE9, 2, 1)
+#define PIN_PE9__PWMH2			PINMUX_PIN(PIN_PE9, 3, 2)
+#define PIN_PE9__TCLK4			PINMUX_PIN(PIN_PE9, 4, 1)
+#define PIN_PE9__I2SMCC0_WS		PINMUX_PIN(PIN_PE9, 5, 2)
+
+#define PIN_PE10			138
+#define PIN_PE10__GPIO			PINMUX_PIN(PIN_PE10, 0, 0)
+#define PIN_PE10__LCDC_DAT6		PINMUX_PIN(PIN_PE10, 1, 1)
+#define PIN_PE10__FLEXCOM2_IO6		PINMUX_PIN(PIN_PE10, 2, 1)
+#define PIN_PE10__PWML3			PINMUX_PIN(PIN_PE10, 3, 2)
+#define PIN_PE10__TIOA5			PINMUX_PIN(PIN_PE10, 4, 1)
+#define PIN_PE10__I2SMCC0_DOUT2		PINMUX_PIN(PIN_PE10, 5, 2)
+
+#define PIN_PE11			139
+#define PIN_PE11__GPIO			PINMUX_PIN(PIN_PE11, 0, 0)
+#define PIN_PE11__LCDC_DAT7		PINMUX_PIN(PIN_PE11, 1, 1)
+#define PIN_PE11__PWMH3			PINMUX_PIN(PIN_PE11, 3, 2)
+#define PIN_PE11__TIOB5			PINMUX_PIN(PIN_PE11, 4, 1)
+#define PIN_PE11__I2SMCC0_DOUT3		PINMUX_PIN(PIN_PE11, 5, 2)
+
+#define PIN_PE12			140
+#define PIN_PE12__GPIO			PINMUX_PIN(PIN_PE12, 0, 0)
+#define PIN_PE12__LCDC_DEN		PINMUX_PIN(PIN_PE12, 1, 1)
+#define PIN_PE12__PCK3			PINMUX_PIN(PIN_PE12, 2, 4)
+#define PIN_PE12__PWMEXTRG0		PINMUX_PIN(PIN_PE12, 3, 2)
+#define PIN_PE12__TCLK5			PINMUX_PIN(PIN_PE12, 4, 1)
+#define PIN_PE12__I2SMCC0_DIN0		PINMUX_PIN(PIN_PE12, 5, 2)
+
+#define PIN_PE13			141
+#define PIN_PE13__GPIO			PINMUX_PIN(PIN_PE13, 0, 0)
+#define PIN_PE13__LCDC_PCK		PINMUX_PIN(PIN_PE13, 1, 1)
+#define PIN_PE13__PCK4			PINMUX_PIN(PIN_PE13, 2, 3)
+#define PIN_PE13__PWMEXTRG1		PINMUX_PIN(PIN_PE13, 3, 2)
+#define PIN_PE13__I2SMCC0DOUT0		PINMUX_PIN(PIN_PE13, 5, 2)
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:12 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:12 -0700
Subject: [PATCH v4 11/13] ARM: dts: microchip: add support for sama7d65_curiosity board
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <efe96af1361505be5ec5f409e4c503ccb56379b0.1734723585.git.Ryan.Wanner@microchip.com>

From: Romain Sioen <romain.sioen at microchip.com>

Add device tree support for the SAMA7D65 Curiosity board.
Update the Makefile to include the new device tree file.

uart6 is related to flexcom6, hence not sorted in alphabetical order.

Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
---
 arch/arm/boot/dts/microchip/Makefile          |  3 +
 .../dts/microchip/at91-sama7d65_curiosity.dts | 89 +++++++++++++++++++
 2 files changed, 92 insertions(+)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts

diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
index 470fe46433a9..79cd38fdc7da 100644
--- a/arch/arm/boot/dts/microchip/Makefile
+++ b/arch/arm/boot/dts/microchip/Makefile
@@ -12,6 +12,7 @@ DTC_FLAGS_at91-sama5d2_xplained := -@
 DTC_FLAGS_at91-sama5d3_eds := -@
 DTC_FLAGS_at91-sama5d3_xplained := -@
 DTC_FLAGS_at91-sama5d4_xplained := -@
+DTC_FLAGS_at91-sama7d65_curiosity := -@
 DTC_FLAGS_at91-sama7g54_curiosity := -@
 DTC_FLAGS_at91-sama7g5ek := -@
 dtb-$(CONFIG_SOC_AT91RM9200) += \
@@ -90,6 +91,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
 	at91-sama5d4_xplained.dtb \
 	at91-sama5d4ek.dtb \
 	at91-vinco.dtb
+dtb-$(CONFIG_SOC_SAMA7D65) += \
+	at91-sama7d65_curiosity.dtb
 dtb-$(CONFIG_SOC_SAMA7G5) += \
 	at91-sama7g54_curiosity.dtb \
 	at91-sama7g5ek.dtb
diff --git a/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
new file mode 100644
index 000000000000..ef6a56db8acb
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ *  at91-sama7d65_curiosity.dts - Device Tree file for SAMA7D65 Curiosity board
+ *
+ *  Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries
+ *
+ *  Author: Romain Sioen <romain.sioen at microchip.com>
+ *
+ */
+/dts-v1/;
+#include "sama7d65-pinfunc.h"
+#include "sama7d65.dtsi"
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/pinctrl/at91.h>
+
+/ {
+	model = "Microchip SAMA7D65 Curiosity";
+	compatible = "microchip,sama7d65-curiosity", "microchip,sama7d65",
+		     "microchip,sama7d6", "microchip,sama7";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		serial0 = &uart6;
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;
+	};
+};
+
+&flx6 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+	status = "okay";
+};
+
+&uart6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart6_default>;
+	status = "okay";
+};
+
+&main_xtal {
+	clock-frequency = <24000000>;
+};
+
+&pioa {
+	pinctrl_sdmmc1_default: sdmmc1-default {
+		cmd-data {
+			pinmux = <PIN_PB22__SDMMC1_CMD>,
+				 <PIN_PB24__SDMMC1_DAT0>,
+				 <PIN_PB25__SDMMC1_DAT1>,
+				 <PIN_PB26__SDMMC1_DAT2>,
+				 <PIN_PB27__SDMMC1_DAT3>;
+			slew-rate = <0>;
+			bias-disable;
+		};
+
+		ck-cd-rstn-vddsel {
+			pinmux = <PIN_PB23__SDMMC1_CK>,
+				 <PIN_PB21__SDMMC1_RSTN>,
+				 <PIN_PB30__SDMMC1_1V8SEL>,
+				 <PIN_PB29__SDMMC1_CD>,
+				 <PIN_PB28__SDMMC1_WP>;
+			slew-rate = <0>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_uart6_default: uart6-default {
+		pinmux = <PIN_PD18__FLEXCOM6_IO0>,
+			<PIN_PD19__FLEXCOM6_IO1>;
+		bias-disable;
+	};
+};
+
+&sdmmc1 {
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc1_default>;
+	status = "okay";
+};
+
+&slow_xtal {
+	clock-frequency = <32768>;
+};
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:07 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:07 -0700
Subject: [PATCH v4 06/13] dt-bindings: clocks: atmel,at91sam9x5-sckc: add sama7d65
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <d45866ab6caca970170199af9fd8588e33c2de2a.1734723585.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add bindings for SAMA7D65's slow clock controller.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
 .../devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml         | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
index c2283cd07f05..d4cf8ae2961e 100644
--- a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
+++ b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
@@ -20,6 +20,7 @@ properties:
       - items:
           - enum:
               - microchip,sam9x7-sckc
+              - microchip,sama7d65-sckc
               - microchip,sama7g5-sckc
           - const: microchip,sam9x60-sckc
 
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:02 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:02 -0700
Subject: [PATCH v4 01/13] dt-bindings: ARM: at91: Document Microchip SAMA7D65 Curiosity
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <70d429086fd8e858d79ca2824ad8cc4a09e3fe5d.1734723585.git.Ryan.Wanner@microchip.com>

From: Romain Sioen <romain.sioen at microchip.com>

Document device tree binding of the Microchip SAMA7D65 Curiosity board.

Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index 7160ec80ac1b..0ec29366e6c2 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -180,6 +180,13 @@ properties:
           - const: atmel,sama5d4
           - const: atmel,sama5
 
+      - description: Microchip SAMA7D65 Curiosity Board
+        items:
+          - const: microchip,sama7d65-curiosity
+          - const: microchip,sama7d65
+          - const: microchip,sama7d6
+          - const: microchip,sama7
+
       - items:
           - const: microchip,sama7g5ek # SAMA7G5 Evaluation Kit
           - const: microchip,sama7g5
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:01 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:01 -0700
Subject: [PATCH v4 00/13]  Add support for SAMA7D65
Message-ID: <cover.1734723585.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

This series adds support for the SAMA7D65 SoC.

V2 of this series [1].
V3 of this series [2].

For the pinctrl and pit64 timers those will have DTB warnings due to
those bindings not being in the .yaml format.

Changes v1->v2:
- V1 set was sent incorrectly as multiple seprate patches v2 took all
  those patches and put them in 1 thread.

Changes v2->v3:
- Correct the patch order to follow correct practice.
- Correct flexcom dt-binding commit messge to reflect the changes in the
  coding style.
- Add missing SoB tags to patches.
- Moved export clocks to DT patch to be included with the clock binding
  patch.
- Separate Kconfig changes and defconfig changes into different patches
  and removed unused Kconfig params.
- Correct confusing SoB and Co-developed chain.
- Removed unsued nodes in DTSI file and sorted includes
  alphanumerically.
- Fix incorrect dts formatting.
- Separate dts and pinmux changes into two patches.
- Combine PLL and MCK changes into core clock driver patch.
- Correct formatting in main clock driver.
- MMC dt-binding changes are applied for next so have been removed from
  the set [3].

Changes v3->v4:
- Collect all tags from maintainers.
- Correct compile error on 11/13 and correct location of vendor specific
  properties.
- Add USB and UTMI selections to 12/13 to prevent compile errors due to
  functions in the clock driver that use the USB clock system.
- Add "microchip,sama7g5-pinctrl" compatible string as a fall back in
  9/13.
- Add missing kfree() to 8/13 to correctly handle error case.
- Replace bad spacing with correct tab formatting on 7/13.

1) https://lore.kernel.org/linux-arm-kernel/cover.1732030972.git.Ryan.Wanner at microchip.com/T/#m9691b4d58b62f36f6cbac1d06883c985766c2c0d
2) https://lore.kernel.org/linux-arm-kernel/cover.1733505542.git.Ryan.Wanner at microchip.com/T/#m3b52978236907198f727424e69ef21c8898e95c8
3) https://lore.kernel.org/linux-arm-kernel/cover.1732030972.git.Ryan.Wanner at microchip.com/T/#mccf6521c07e74e1c7dc61b09ae0ebdbbdde73a28


Dharma Balasubiramani (6):
  dt-bindings: mfd: atmel,sama5d2-flexcom: add
    microchip,sama7d65-flexcom
  dt-bindings: atmel-sysreg: add sama7d65 RAM and PIT
  dt-bindings: serial: atmel,at91-usart: add microchip,sama7d65-usart
  dt-bindings: pinctrl: at91-pio4: add microchip,sama7d65-pinctrl
  dt-bindings: clocks: atmel,at91sam9x5-sckc: add sama7d65
  dt-bindings: clock: Add SAMA7D65 PMC compatible string

Romain Sioen (2):
  dt-bindings: ARM: at91: Document Microchip SAMA7D65 Curiosity
  ARM: dts: microchip: add support for sama7d65_curiosity board

Ryan Wanner (5):
  clk: at91: sama7d65: add sama7d65 pmc driver
  ARM: dts: microchip: add sama7d65 SoC DT
  ARM: dts: at91: Add sama7d65 pinmux
  ARM: configs: at91: sama7: add new SoC config
  ARM: at91: add new SoC sama7d65

 .../devicetree/bindings/arm/atmel-at91.yaml   |    7 +
 .../devicetree/bindings/arm/atmel-sysregs.txt |   14 +-
 .../bindings/clock/atmel,at91rm9200-pmc.yaml  |    2 +
 .../bindings/clock/atmel,at91sam9x5-sckc.yaml |    1 +
 .../bindings/mfd/atmel,sama5d2-flexcom.yaml   |    9 +-
 .../pinctrl/atmel,at91-pio4-pinctrl.txt       |    1 +
 .../bindings/serial/atmel,at91-usart.yaml     |    1 +
 arch/arm/boot/dts/microchip/Makefile          |    3 +
 .../dts/microchip/at91-sama7d65_curiosity.dts |   89 ++
 .../arm/boot/dts/microchip/sama7d65-pinfunc.h |  947 ++++++++++++
 arch/arm/boot/dts/microchip/sama7d65.dtsi     |  145 ++
 arch/arm/configs/multi_v7_defconfig           |    1 +
 arch/arm/configs/sama7_defconfig              |    1 +
 arch/arm/mach-at91/Kconfig                    |   11 +
 drivers/clk/at91/Makefile                     |    1 +
 drivers/clk/at91/clk-master.c                 |    2 +-
 drivers/clk/at91/clk-sam9x60-pll.c            |    2 +-
 drivers/clk/at91/pmc.c                        |    1 +
 drivers/clk/at91/sama7d65.c                   | 1375 +++++++++++++++++
 include/dt-bindings/clock/at91.h              |    4 +
 20 files changed, 2604 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7d65_curiosity.dts
 create mode 100644 arch/arm/boot/dts/microchip/sama7d65-pinfunc.h
 create mode 100644 arch/arm/boot/dts/microchip/sama7d65.dtsi
 create mode 100644 drivers/clk/at91/sama7d65.c

-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:03 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:03 -0700
Subject: [PATCH v4 02/13] dt-bindings: mfd: atmel,sama5d2-flexcom: add microchip,sama7d65-flexcom
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <3586d64e42b569c881a53a4ce06f09a9139c6b10.1734723585.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add flexcom binding documentation for sama7d65.

Consolidated entries into one enum to match proper coding style.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml   | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
index 0dc6a40b63f4..c7d6cf96796c 100644
--- a/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
+++ b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
@@ -19,12 +19,11 @@ properties:
     oneOf:
       - const: atmel,sama5d2-flexcom
       - items:
-          - const: microchip,sam9x7-flexcom
+          - enum:
+              - microchip,sam9x7-flexcom
+              - microchip,sama7d65-flexcom
+              - microchip,sama7g5-flexcom
           - const: atmel,sama5d2-flexcom
-      - items:
-          - const: microchip,sama7g5-flexcom
-          - const: atmel,sama5d2-flexcom
-
 
   reg:
     maxItems: 1
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:04 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:04 -0700
Subject: [PATCH v4 03/13] dt-bindings: atmel-sysreg: add sama7d65 RAM and PIT
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <c1b5b4a13f31bd465b69547f29e3ed6f616b2e76.1734723585.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add SAMA7D65 RAM controller, PIT64 DT bindings.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
---
 .../devicetree/bindings/arm/atmel-sysregs.txt      | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
index 76e2b7978250..1a173e92bb13 100644
--- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
@@ -13,6 +13,7 @@ PIT Timer required properties:
 PIT64B Timer required properties:
 - compatible: Should be "microchip,sam9x60-pit64b" or
 			"microchip,sam9x7-pit64b", "microchip,sam9x60-pit64b"
+			"microchip,sama7d65-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.
@@ -27,12 +28,13 @@ Its subnodes can be:
 - watchdog: compatible should be "atmel,at91rm9200-wdt"
 
 RAMC SDRAM/DDR Controller required properties:
-- compatible: Should be "atmel,at91rm9200-sdramc", "syscon"
-			"atmel,at91sam9260-sdramc",
-			"atmel,at91sam9g45-ddramc",
-			"atmel,sama5d3-ddramc",
-			"microchip,sam9x60-ddramc",
-			"microchip,sama7g5-uddrc",
+- compatible: Should be "atmel,at91rm9200-sdramc", "syscon" or
+			"atmel,at91sam9260-sdramc" or
+			"atmel,at91sam9g45-ddramc" or
+			"atmel,sama5d3-ddramc" or
+			"microchip,sam9x60-ddramc" or
+			"microchip,sama7g5-uddrc" or
+			"microchip,sama7d65-uddrc", "microchip,sama7g5-uddrc" or
 			"microchip,sam9x7-ddramc", "atmel,sama5d3-ddramc".
 - reg: Should contain registers location and length
 
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:05 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:05 -0700
Subject: [PATCH v4 04/13] dt-bindings: serial: atmel,at91-usart: add microchip,sama7d65-usart
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <7d2bf43095dd5b8784ec53a45d5f07f3f0481b0a.1734723585.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add SAMA7D65 USART compatible to DT bindings documentation.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
---
 Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
index f466c38518c4..087a8926f8b4 100644
--- a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
+++ b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
@@ -26,6 +26,7 @@ properties:
           - enum:
               - microchip,sam9x60-usart
               - microchip,sam9x7-usart
+              - microchip,sama7d65-usart
           - const: atmel,at91sam9260-usart
       - items:
           - const: microchip,sam9x60-dbgu
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:06 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:06 -0700
Subject: [PATCH v4 05/13] dt-bindings: pinctrl: at91-pio4: add microchip,sama7d65-pinctrl
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <6ec5d56d36c64b7a29e043cee0b5a6c035c0d85c.1734723585.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add pinctrl bindings for microchip sama7d65 SoC.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
---
 .../devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt      | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
index 774c3c269c40..a7d7d2eaf10f 100644
--- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
@@ -6,6 +6,7 @@ configure it.
 Required properties:
 - compatible:
 	"atmel,sama5d2-pinctrl"
+	"microchip,sama7d65-pinctrl"
 	"microchip,sama7g5-pinctrl"
 - reg: base address and length of the PIO controller.
 - interrupts: interrupt outputs from the controller, one for each bank.
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:08 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:08 -0700
Subject: [PATCH v4 07/13] dt-bindings: clock: Add SAMA7D65 PMC compatible string
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <9b8db610f477d5339830d12cd44f783eb5cb16ea.1734723585.git.Ryan.Wanner@microchip.com>

From: Dharma Balasubiramani <dharma.b at microchip.com>

Add the `microchip,sama7d65-pmc` compatible string to the existing binding,
since the SAMA7D65 PMC shares the same properties and clock requirements
as the SAMA7G5.

Export MCK3 and MCK5 to be accessed and referenced in DT to assign to
the clocks property for sama7d65 SoC.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml       | 2 ++
 include/dt-bindings/clock/at91.h                              | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml
index c9eb60776b4d..885d47dd5724 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,sam9x7-pmc
+              - microchip,sama7d65-pmc
               - microchip,sama7g5-pmc
           - const: syscon
 
@@ -90,6 +91,7 @@ allOf:
             enum:
               - microchip,sam9x60-pmc
               - microchip,sam9x7-pmc
+              - microchip,sama7d65-pmc
               - microchip,sama7g5-pmc
     then:
       properties:
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
index 6ede88c3992d..d753559b912b 100644
--- a/include/dt-bindings/clock/at91.h
+++ b/include/dt-bindings/clock/at91.h
@@ -42,6 +42,10 @@
 #define PMC_PLLADIV2		(PMC_MAIN + 11)
 #define PMC_LVDSPLL		(PMC_MAIN + 12)
 
+/* SAMA7D65 */
+#define PMC_MCK3		(PMC_MAIN + 13)
+#define PMC_MCK5		(PMC_MAIN + 14)
+
 #ifndef AT91_PMC_MOSCS
 #define AT91_PMC_MOSCS		0		/* MOSCS Flag */
 #define AT91_PMC_LOCKA		1		/* PLLA Lock */
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:10 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:10 -0700
Subject: [PATCH v4 09/13] ARM: dts: microchip: add sama7d65 SoC DT
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <3f63aebc4b31da1b631ce7e6d76aa0046deeda6a.1734723585.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add Device Tree for sama7d65 SoC.

Co-developed-by: Dharma Balasubiramani <dharma.b at microchip.com>
Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Co-developed-by: Romain Sioen <romain.sioen at microchip.com>
Signed-off-by: Romain Sioen <romain.sioen at microchip.com>
Co-developed-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
 arch/arm/boot/dts/microchip/sama7d65.dtsi | 145 ++++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 arch/arm/boot/dts/microchip/sama7d65.dtsi

diff --git a/arch/arm/boot/dts/microchip/sama7d65.dtsi b/arch/arm/boot/dts/microchip/sama7d65.dtsi
new file mode 100644
index 000000000000..03e1adfdcd34
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/sama7d65.dtsi
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ *  sama7d65.dtsi - Device Tree Include file for SAMA7D65 SoC
+ *
+ *  Copyright (C) 2024 Microchip Technology, Inc. and its subsidiaries
+ *
+ *  Author: Ryan Wanner <Ryan.Wanner at microchip.com>
+ *
+ */
+
+#include <dt-bindings/clock/at91.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/mfd/at91-usart.h>
+
+/ {
+	model = "Microchip SAMA7D65 family SoC";
+	compatible = "microchip,sama7d65";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&gic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+			device_type = "cpu";
+			clocks = <&pmc PMC_TYPE_CORE PMC_CPUPLL>;
+			clock-names = "cpu";
+		};
+	};
+
+	clocks {
+		main_xtal: clock-mainxtal {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+
+		 slow_xtal: clock-slowxtal {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+
+	};
+
+	soc {
+		compatible = "simple-bus";
+		ranges;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		pioa: pinctrl at e0014000 {
+			compatible = "microchip,sama7d65-pinctrl", "microchip,sama7g5-pinctrl";
+			reg = <0xe0014000 0x800>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 10>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		pmc: clock-controller at e0018000 {
+			compatible = "microchip,sama7d65-pmc", "syscon";
+			reg = <0xe0018000 0x200>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#clock-cells = <2>;
+			clocks = <&clk32k 1>, <&clk32k 0>, <&main_xtal>;
+			clock-names = "td_slck", "md_slck", "main_xtal";
+		};
+
+		clk32k: clock-controller at e001d500 {
+			compatible = "microchip,sama7d65-sckc", "microchip,sam9x60-sckc";
+			reg = <0xe001d500 0x4>;
+			clocks = <&slow_xtal>;
+			#clock-cells = <1>;
+		};
+
+		sdmmc1: mmc at e1208000 {
+			compatible = "microchip,sama7d65-sdhci", "microchip,sam9x60-sdhci";
+			reg = <0xe1208000 0x400>;
+			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 76>, <&pmc PMC_TYPE_GCK 76>;
+			clock-names = "hclock", "multclk";
+			assigned-clocks = <&pmc PMC_TYPE_GCK 76>;
+			assigned-clock-rates = <200000000>;
+			assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_MCK1>;
+			status = "disabled";
+		};
+
+		pit64b0: timer at e1800000 {
+			compatible = "microchip,sama7d65-pit64b", "microchip,sam9x60-pit64b";
+			reg = <0xe1800000 0x100>;
+			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 66>, <&pmc PMC_TYPE_GCK 66>;
+			clock-names = "pclk", "gclk";
+		};
+
+		pit64b1: timer at e1804000 {
+			compatible = "microchip,sama7d65-pit64b", "microchip,sam9x60-pit64b";
+			reg = <0xe1804000 0x100>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 67>, <&pmc PMC_TYPE_GCK 67>;
+			clock-names = "pclk", "gclk";
+		};
+
+		flx6: flexcom at e2020000 {
+			compatible = "microchip,sama7d65-flexcom", "atmel,sama5d2-flexcom";
+			reg = <0xe2020000 0x200>;
+			ranges = <0x0 0xe2020000 0x800>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 40>;
+			status = "disabled";
+
+			uart6: serial at 200 {
+				compatible = "microchip,sama7d65-usart", "atmel,at91sam9260-usart";
+				reg = <0x200 0x200>;
+				interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pmc PMC_TYPE_PERIPHERAL 40>;
+				clock-names = "usart";
+				atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
+				atmel,fifo-size = <16>;
+				status = "disabled";
+			};
+		};
+
+		gic: interrupt-controller at e8c11000 {
+			compatible = "arm,cortex-a7-gic";
+			reg = <0xe8c11000 0x1000>,
+			      <0xe8c12000 0x2000>;
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+		};
+	};
+};
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:09 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:09 -0700
Subject: [PATCH v4 08/13] clk: at91: sama7d65: add sama7d65 pmc driver
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <549fa8590fe9b4380e413f8eed87392f28754395.1734723585.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add clock support for SAMA7D65 SoC.

Increase maximum number of valid master clocks. The PMC for the SAMA7D65
requires 9 master clocks.

Increase maximum amount of PLLs to 9 to support SAMA7D65 SoC PLL
requirements.

Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
 drivers/clk/at91/Makefile          |    1 +
 drivers/clk/at91/clk-master.c      |    2 +-
 drivers/clk/at91/clk-sam9x60-pll.c |    2 +-
 drivers/clk/at91/pmc.c             |    1 +
 drivers/clk/at91/sama7d65.c        | 1375 ++++++++++++++++++++++++++++
 5 files changed, 1379 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/at91/sama7d65.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 8e3684ba2c74..5e638eb15aba 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -25,3 +25,4 @@ 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
 obj-$(CONFIG_SOC_SAMA7G5) += sama7g5.o
+obj-$(CONFIG_SOC_SAMA7D65) += sama7d65.o
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index 15c46489ba85..7a544e429d34 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -20,7 +20,7 @@
 
 #define PMC_MCR_CSS_SHIFT	(16)
 
-#define MASTER_MAX_ID		4
+#define MASTER_MAX_ID		9
 
 #define to_clk_master(hw) container_of(hw, struct clk_master, hw)
 
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index fda041102224..cefd9948e103 100644
--- a/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -23,7 +23,7 @@
 #define UPLL_DIV		2
 #define PLL_MUL_MAX		(FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
 
-#define PLL_MAX_ID		7
+#define PLL_MAX_ID		9
 
 struct sam9x60_pll_core {
 	struct regmap *regmap;
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 5aa9c1f1c886..acf780a81589 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -151,6 +151,7 @@ static struct syscore_ops pmc_syscore_ops = {
 static const struct of_device_id pmc_dt_ids[] = {
 	{ .compatible = "atmel,sama5d2-pmc" },
 	{ .compatible = "microchip,sama7g5-pmc", },
+	{ .compatible = "microchip,sama7d65-pmc", },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/clk/at91/sama7d65.c b/drivers/clk/at91/sama7d65.c
new file mode 100644
index 000000000000..917958eabd3a
--- /dev/null
+++ b/drivers/clk/at91/sama7d65.c
@@ -0,0 +1,1375 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SAMA7D65 PMC code.
+ *
+ * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Ryan Wanner <ryan.wanner 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(pmc_mck0_lock);
+static DEFINE_SPINLOCK(pmc_mckX_lock);
+
+#define PMC_INDEX_MAX	25
+
+/*
+ * PLL clocks identifiers
+ * @PLL_ID_CPU:		CPU PLL identifier
+ * @PLL_ID_SYS:		System PLL identifier
+ * @PLL_ID_DDR:		DDR PLL identifier
+ * @PLL_ID_GPU:		Graphics subsystem PLL identifier
+ * @PLL_ID_BAUD:	Baud PLL identifier
+ * @PLL_ID_AUDIO:	Audio PLL identifier
+ * @PLL_ID_ETH:		Ethernet PLL identifier
+ * @PLL_ID_LVDS:	LVDS PLL identifier
+ * @PLL_ID_USB:		USB PLL identifier
+ */
+enum pll_ids {
+	PLL_ID_CPU,
+	PLL_ID_SYS,
+	PLL_ID_DDR,
+	PLL_ID_GPU,
+	PLL_ID_BAUD,
+	PLL_ID_AUDIO,
+	PLL_ID_ETH,
+	PLL_ID_LVDS,
+	PLL_ID_USB,
+	PLL_ID_MAX
+};
+
+/*
+ * PLL component identifier
+ * @PLL_COMPID_FRAC: Fractional PLL component identifier
+ * @PLL_COMPID_DIV0: 1st PLL divider component identifier
+ * @PLL_COMPID_DIV1: 2nd PLL divider component identifier
+ */
+enum pll_component_id {
+	PLL_COMPID_FRAC,
+	PLL_COMPID_DIV0,
+	PLL_COMPID_DIV1,
+	PLL_COMPID_MAX
+};
+
+/*
+ * PLL type identifiers
+ * @PLL_TYPE_FRAC:	fractional PLL identifier
+ * @PLL_TYPE_DIV:	divider PLL identifier
+ */
+enum pll_type {
+	PLL_TYPE_FRAC,
+	PLL_TYPE_DIV
+};
+
+/* Layout for fractional PLLs. */
+static const struct clk_pll_layout pll_layout_frac = {
+	.mul_mask	= GENMASK(31, 24),
+	.frac_mask	= GENMASK(21, 0),
+	.mul_shift	= 24,
+	.frac_shift	= 0,
+};
+
+/* Layout for DIVPMC dividers. */
+static const struct clk_pll_layout pll_layout_divpmc = {
+	.div_mask	= GENMASK(7, 0),
+	.endiv_mask	= BIT(29),
+	.div_shift	= 0,
+	.endiv_shift	= 29,
+};
+
+/* Layout for DIVIO dividers. */
+static const struct clk_pll_layout pll_layout_divio = {
+	.div_mask	= GENMASK(19, 12),
+	.endiv_mask	= BIT(30),
+	.div_shift	= 12,
+	.endiv_shift	= 30,
+};
+
+/*
+ * CPU PLL output range.
+ * Notice: The upper limit has been setup to 1000000002 due to hardware
+ * block which cannot output exactly 1GHz.
+ */
+static const struct clk_range cpu_pll_outputs[] = {
+	{ .min = 2343750, .max = 1000000002 },
+};
+
+/* PLL output range. */
+static const struct clk_range pll_outputs[] = {
+	{ .min = 2343750, .max = 1200000000 },
+};
+
+/*
+ * Min: fCOREPLLCK = 600 MHz, PMC_PLL_CTRL0.DIVPMC = 255
+ * Max: fCOREPLLCK = 800 MHz, PMC_PLL_CTRL0.DIVPMC = 0
+ */
+static const struct clk_range lvdspll_outputs[] = {
+	{ .min = 16406250, .max = 800000000 },
+};
+
+static const struct clk_range upll_outputs[] = {
+	{ .min = 480000000, .max = 480000000 },
+};
+
+/* Fractional PLL core output range. */
+static const struct clk_range core_outputs[] = {
+	{ .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_range lvdspll_core_outputs[] = {
+	{ .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_range upll_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. */
+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,
+};
+
+static const struct clk_pll_characteristics lvdspll_characteristics = {
+	.input = { .min = 12000000, .max = 50000000 },
+	.num_output = ARRAY_SIZE(lvdspll_outputs),
+	.output = lvdspll_outputs,
+	.core_output = lvdspll_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,
+};
+
+/*
+ * SAMA7D65 PLL possible parents
+ * @SAMA7D65_PLL_PARENT_MAINCK: MAINCK is PLL a parent
+ * @SAMA7D65_PLL_PARENT_MAIN_XTAL: MAIN XTAL is a PLL parent
+ * @SAMA7D65_PLL_PARENT_FRACCK: Frac PLL is a PLL parent (for PLL dividers)
+ */
+enum sama7d65_pll_parent {
+	SAMA7D65_PLL_PARENT_MAINCK,
+	SAMA7D65_PLL_PARENT_MAIN_XTAL,
+	SAMA7D65_PLL_PARENT_FRACCK
+};
+
+/*
+ * PLL clocks description
+ * @n:		clock name
+ * @l:		clock layout
+ * @c:		clock characteristics
+ * @hw:		pointer to clk_hw
+ * @t:		clock type
+ * @f:		clock flags
+ * @p:		clock parent
+ * @eid:	export index in sama7d65->chws[] array
+ * @safe_div:	intermediate divider need to be set on PRE_RATE_CHANGE
+ *		notification
+ */
+static struct sama7d65_pll {
+	const char *n;
+	const struct clk_pll_layout *l;
+	const struct clk_pll_characteristics *c;
+	struct clk_hw *hw;
+	unsigned long f;
+	enum sama7d65_pll_parent p;
+	u8 t;
+	u8 eid;
+	u8 safe_div;
+} sama7d65_plls[][PLL_COMPID_MAX] = {
+	[PLL_ID_CPU] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "cpupll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &cpu_pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			/*
+			 * This feeds cpupll_divpmcck which feeds CPU. It should
+			 * not be disabled.
+			 */
+			.f = CLK_IS_CRITICAL,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "cpupll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &cpu_pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			/* This feeds CPU. It should not be disabled. */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			.eid = PMC_CPUPLL,
+			/*
+			 * Safe div=15 should be safe even for switching b/w 1GHz and
+			 * 90MHz (frac pll might go up to 1.2GHz).
+			 */
+			.safe_div = 15,
+		},
+	},
+
+	[PLL_ID_SYS] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "syspll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			/*
+			 * This feeds syspll_divpmcck which may feed critical parts
+			 * of the systems like timers. Therefore it should not be
+			 * disabled.
+			 */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "syspll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			/*
+			 * This may feed critical parts of the systems like timers.
+			 * Therefore it should not be disabled.
+			 */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+			.eid = PMC_SYSPLL,
+		},
+	},
+
+	[PLL_ID_DDR] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "ddrpll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			/*
+			 * This feeds ddrpll_divpmcck which feeds DDR. It should not
+			 * be disabled.
+			 */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "ddrpll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			/* This feeds DDR. It should not be disabled. */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+		},
+	},
+
+	[PLL_ID_GPU] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "gpupll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "gpupll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+		},
+	},
+
+	[PLL_ID_BAUD] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "baudpll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAINCK,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "baudpll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_BAUDPLL,
+		},
+	},
+
+	[PLL_ID_AUDIO] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "audiopll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "audiopll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_AUDIOPMCPLL,
+		},
+
+		[PLL_COMPID_DIV1] = {
+			.n = "audiopll_diviock",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divio,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_AUDIOIOPLL,
+		},
+	},
+
+	[PLL_ID_ETH] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "ethpll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
+			.l = &pll_layout_frac,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "ethpll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &pll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_ETHPLL,
+		},
+	},
+
+	[PLL_ID_LVDS] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "lvdspll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
+			.l = &pll_layout_frac,
+			.c = &lvdspll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "lvdspll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &lvdspll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_LVDSPLL,
+		},
+	},
+
+	[PLL_ID_USB] = {
+		[PLL_COMPID_FRAC] = {
+			.n = "usbpll_fracck",
+			.p = SAMA7D65_PLL_PARENT_MAIN_XTAL,
+			.l = &pll_layout_frac,
+			.c = &upll_characteristics,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+		},
+
+		[PLL_COMPID_DIV0] = {
+			.n = "usbpll_divpmcck",
+			.p = SAMA7D65_PLL_PARENT_FRACCK,
+			.l = &pll_layout_divpmc,
+			.c = &upll_characteristics,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_UTMI,
+		},
+	},
+};
+
+/* Used to create an array entry identifying a PLL by its components. */
+#define PLL_IDS_TO_ARR_ENTRY(_id, _comp) { PLL_ID_##_id, PLL_COMPID_##_comp}
+
+/*
+ * Master clock (MCK[0..9]) description
+ * @n:			clock name
+ * @ep_chg_chg_id:	index in parents array that specifies the changeable
+ * @ep:			extra parents names array (entry formed by PLL components
+ *			identifiers (see enum pll_component_id))
+ * @hw:			pointer to clk_hw
+ *			parent
+ * @ep_count:		extra parents count
+ * @ep_mux_table:	mux table for extra parents
+ * @id:			clock id
+ * @eid:		export index in sama7d65->chws[] array
+ * @c:			true if clock is critical and cannot be disabled
+ */
+static struct {
+	const char *n;
+	struct {
+		int pll_id;
+		int pll_compid;
+	} ep[4];
+	struct clk_hw *hw;
+	int ep_chg_id;
+	u8 ep_count;
+	u8 ep_mux_table[4];
+	u8 id;
+	u8 eid;
+	u8 c;
+} sama7d65_mckx[] = {
+	{ .n = "mck0", }, /* Dummy entry for MCK0 to store hw in probe. */
+	{ .n = "mck1",
+	  .id = 1,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_count = 1,
+	  .ep_chg_id = INT_MIN,
+	  .eid = PMC_MCK1,
+	  .c = 1, },
+
+	{ .n = "mck2",
+	  .id = 2,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), },
+	  .ep_mux_table = { 5, 6, },
+	  .ep_count = 2,
+	  .ep_chg_id = INT_MIN,
+	  .c = 1, },
+
+	{ .n = "mck3",
+	  .id = 3,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), },
+	  .ep_mux_table = { 5, 6, },
+	  .ep_count = 2,
+	  .ep_chg_id = INT_MIN,
+	  .eid = PMC_MCK3,
+	  .c = 1, },
+
+	{ .n = "mck4",
+	  .id = 4,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_count = 1,
+	  .ep_chg_id = INT_MIN,
+	  .c = 1, },
+
+	{ .n = "mck5",
+	  .id = 5,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_count = 1,
+	  .ep_chg_id = INT_MIN,
+	  .eid = PMC_MCK5,
+	  .c = 1, },
+
+	{ .n = "mck6",
+	  .id = 6,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_chg_id = INT_MIN,
+	  .ep_count = 1,
+	  .c = 1, },
+
+	{ .n = "mck7",
+	  .id = 7,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_chg_id = INT_MIN,
+	  .ep_count = 1, },
+
+	{ .n = "mck8",
+	  .id = 8,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_chg_id = INT_MIN,
+	  .ep_count = 1, },
+
+	{ .n = "mck9",
+	  .id = 9,
+	  .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .ep_mux_table = { 5, },
+	  .ep_chg_id = INT_MIN,
+	  .ep_count = 1, },
+};
+
+/*
+ * System clock description
+ * @n:	clock name
+ * @p:	clock parent name
+ * @id: clock id
+ */
+static const struct {
+	const char *n;
+	const char *p;
+	u8 id;
+} sama7d65_systemck[] = {
+	{ .n = "uhpck",		.p = "usbck", .id = 6 },
+	{ .n = "pck0",		.p = "prog0", .id = 8, },
+	{ .n = "pck1",		.p = "prog1", .id = 9, },
+	{ .n = "pck2",		.p = "prog2", .id = 10, },
+	{ .n = "pck3",		.p = "prog3", .id = 11, },
+	{ .n = "pck4",		.p = "prog4", .id = 12, },
+	{ .n = "pck5",		.p = "prog5", .id = 13, },
+	{ .n = "pck6",		.p = "prog6", .id = 14, },
+	{ .n = "pck7",		.p = "prog7", .id = 15, },
+};
+
+/* Mux table for programmable clocks. */
+static u32 sama7d65_prog_mux_table[] = { 0, 1, 2, 5, 7, 8, 9, 10, 12 };
+
+/*
+ * Peripheral clock parent hw identifier (used to index in sama7d65_mckx[])
+ * @PCK_PARENT_HW_MCK0: pck parent hw identifier is MCK0
+ * @PCK_PARENT_HW_MCK1: pck parent hw identifier is MCK1
+ * @PCK_PARENT_HW_MCK2: pck parent hw identifier is MCK2
+ * @PCK_PARENT_HW_MCK3: pck parent hw identifier is MCK3
+ * @PCK_PARENT_HW_MCK4: pck parent hw identifier is MCK4
+ * @PCK_PARENT_HW_MCK5: pck parent hw identifier is MCK5
+ * @PCK_PARENT_HW_MCK6: pck parent hw identifier is MCK6
+ * @PCK_PARENT_HW_MCK7: pck parent hw identifier is MCK7
+ * @PCK_PARENT_HW_MCK8: pck parent hw identifier is MCK8
+ * @PCK_PARENT_HW_MCK9: pck parent hw identifier is MCK9
+ * @PCK_PARENT_HW_MAX: max identifier
+ */
+enum sama7d65_pck_parent_hw_id {
+	PCK_PARENT_HW_MCK0,
+	PCK_PARENT_HW_MCK1,
+	PCK_PARENT_HW_MCK2,
+	PCK_PARENT_HW_MCK3,
+	PCK_PARENT_HW_MCK4,
+	PCK_PARENT_HW_MCK5,
+	PCK_PARENT_HW_MCK6,
+	PCK_PARENT_HW_MCK7,
+	PCK_PARENT_HW_MCK8,
+	PCK_PARENT_HW_MCK9,
+	PCK_PARENT_HW_MAX
+};
+
+/*
+ * Peripheral clock description
+ * @n:		clock name
+ * @p:		clock parent hw id
+ * @r:		clock range values
+ * @id:		clock id
+ * @chgp:	index in parent array of the changeable parent
+ */
+static struct {
+	const char *n;
+	enum sama7d65_pck_parent_hw_id p;
+	struct clk_range r;
+	u8 chgp;
+	u8 id;
+} sama7d65_periphck[] = {
+	{ .n = "pioA_clk",	.p = PCK_PARENT_HW_MCK0, .id = 10, },
+	{ .n = "securam_clk",	.p = PCK_PARENT_HW_MCK0, .id = 17, },
+	{ .n = "sfr_clk",	.p = PCK_PARENT_HW_MCK7, .id = 18, },
+	{ .n = "hsmc_clk",	.p = PCK_PARENT_HW_MCK5, .id = 20, },
+	{ .n = "xdmac0_clk",	.p = PCK_PARENT_HW_MCK6, .id = 21, },
+	{ .n = "xdmac1_clk",	.p = PCK_PARENT_HW_MCK6, .id = 22, },
+	{ .n = "xdmac2_clk",	.p = PCK_PARENT_HW_MCK1, .id = 23, },
+	{ .n = "acc_clk",	.p = PCK_PARENT_HW_MCK7, .id = 24, },
+	{ .n = "aes_clk",	.p = PCK_PARENT_HW_MCK6, .id = 26, },
+	{ .n = "tzaesbasc_clk",	.p = PCK_PARENT_HW_MCK8, .id = 27, },
+	{ .n = "asrc_clk",	.p = PCK_PARENT_HW_MCK9, .id = 29, .r = { .max = 200000000, }, },
+	{ .n = "cpkcc_clk",	.p = PCK_PARENT_HW_MCK0, .id = 30, },
+	{ .n = "eic_clk",	.p = PCK_PARENT_HW_MCK7, .id = 33, },
+	{ .n = "flex0_clk",	.p = PCK_PARENT_HW_MCK7, .id = 34, },
+	{ .n = "flex1_clk",	.p = PCK_PARENT_HW_MCK7, .id = 35, },
+	{ .n = "flex2_clk",	.p = PCK_PARENT_HW_MCK7, .id = 36, },
+	{ .n = "flex3_clk",	.p = PCK_PARENT_HW_MCK7, .id = 37, },
+	{ .n = "flex4_clk",	.p = PCK_PARENT_HW_MCK8, .id = 38, },
+	{ .n = "flex5_clk",	.p = PCK_PARENT_HW_MCK8, .id = 39, },
+	{ .n = "flex6_clk",	.p = PCK_PARENT_HW_MCK8, .id = 40, },
+	{ .n = "flex7_clk",	.p = PCK_PARENT_HW_MCK8, .id = 41, },
+	{ .n = "flex8_clk",	.p = PCK_PARENT_HW_MCK9, .id = 42, },
+	{ .n = "flex9_clk",	.p = PCK_PARENT_HW_MCK9, .id = 43, },
+	{ .n = "flex10_clk",	.p = PCK_PARENT_HW_MCK9, .id = 44, },
+	{ .n = "gmac0_clk",	.p = PCK_PARENT_HW_MCK6, .id = 46, },
+	{ .n = "gmac1_clk",	.p = PCK_PARENT_HW_MCK6, .id = 47, },
+	{ .n = "gmac0_tsu_clk",	.p = PCK_PARENT_HW_MCK1, .id = 49, },
+	{ .n = "gmac1_tsu_clk",	.p = PCK_PARENT_HW_MCK1, .id = 50, },
+	{ .n = "icm_clk",	.p = PCK_PARENT_HW_MCK5, .id = 53, },
+	{ .n = "i2smcc0_clk",	.p = PCK_PARENT_HW_MCK9, .id = 54, .r = { .max = 200000000, }, },
+	{ .n = "i2smcc1_clk",	.p = PCK_PARENT_HW_MCK9, .id = 55, .r = { .max = 200000000, }, },
+	{ .n = "lcd_clk",	.p = PCK_PARENT_HW_MCK3, .id = 56, },
+	{ .n = "matrix_clk",	.p = PCK_PARENT_HW_MCK5, .id = 57, },
+	{ .n = "mcan0_clk",	.p = PCK_PARENT_HW_MCK5, .id = 58, .r = { .max = 200000000, }, },
+	{ .n = "mcan1_clk",	.p = PCK_PARENT_HW_MCK5, .id = 59, .r = { .max = 200000000, }, },
+	{ .n = "mcan2_clk",	.p = PCK_PARENT_HW_MCK5, .id = 60, .r = { .max = 200000000, }, },
+	{ .n = "mcan3_clk",	.p = PCK_PARENT_HW_MCK5, .id = 61, .r = { .max = 200000000, }, },
+	{ .n = "mcan4_clk",	.p = PCK_PARENT_HW_MCK5, .id = 62, .r = { .max = 200000000, }, },
+	{ .n = "pdmc0_clk",	.p = PCK_PARENT_HW_MCK9, .id = 64, .r = { .max = 200000000, }, },
+	{ .n = "pdmc1_clk",	.p = PCK_PARENT_HW_MCK9, .id = 65, .r = { .max = 200000000, }, },
+	{ .n = "pit64b0_clk",	.p = PCK_PARENT_HW_MCK7, .id = 66, },
+	{ .n = "pit64b1_clk",	.p = PCK_PARENT_HW_MCK7, .id = 67, },
+	{ .n = "pit64b2_clk",	.p = PCK_PARENT_HW_MCK7, .id = 68, },
+	{ .n = "pit64b3_clk",	.p = PCK_PARENT_HW_MCK8, .id = 69, },
+	{ .n = "pit64b4_clk",	.p = PCK_PARENT_HW_MCK8, .id = 70, },
+	{ .n = "pit64b5_clk",	.p = PCK_PARENT_HW_MCK8, .id = 71, },
+	{ .n = "pwm_clk",	.p = PCK_PARENT_HW_MCK7, .id = 72, },
+	{ .n = "qspi0_clk",	.p = PCK_PARENT_HW_MCK5, .id = 73, },
+	{ .n = "qspi1_clk",	.p = PCK_PARENT_HW_MCK5, .id = 74, },
+	{ .n = "sdmmc0_clk",	.p = PCK_PARENT_HW_MCK1, .id = 75, },
+	{ .n = "sdmmc1_clk",	.p = PCK_PARENT_HW_MCK1, .id = 76, },
+	{ .n = "sdmmc2_clk",	.p = PCK_PARENT_HW_MCK1, .id = 77, },
+	{ .n = "sha_clk",	.p = PCK_PARENT_HW_MCK6, .id = 78, },
+	{ .n = "spdifrx_clk",	.p = PCK_PARENT_HW_MCK9, .id = 79, .r = { .max = 200000000, }, },
+	{ .n = "spdiftx_clk",	.p = PCK_PARENT_HW_MCK9, .id = 80, .r = { .max = 200000000, }, },
+	{ .n = "ssc0_clk",	.p = PCK_PARENT_HW_MCK7, .id = 81, .r = { .max = 200000000, }, },
+	{ .n = "ssc1_clk",	.p = PCK_PARENT_HW_MCK8, .id = 82, .r = { .max = 200000000, }, },
+	{ .n = "tcb0_ch0_clk",	.p = PCK_PARENT_HW_MCK8, .id = 83, .r = { .max = 200000000, }, },
+	{ .n = "tcb0_ch1_clk",	.p = PCK_PARENT_HW_MCK8, .id = 84, .r = { .max = 200000000, }, },
+	{ .n = "tcb0_ch2_clk",	.p = PCK_PARENT_HW_MCK8, .id = 85, .r = { .max = 200000000, }, },
+	{ .n = "tcb1_ch0_clk",	.p = PCK_PARENT_HW_MCK5, .id = 86, .r = { .max = 200000000, }, },
+	{ .n = "tcb1_ch1_clk",	.p = PCK_PARENT_HW_MCK5, .id = 87, .r = { .max = 200000000, }, },
+	{ .n = "tcb1_ch2_clk",	.p = PCK_PARENT_HW_MCK5, .id = 88, .r = { .max = 200000000, }, },
+	{ .n = "tcpca_clk",	.p = PCK_PARENT_HW_MCK5, .id = 89, },
+	{ .n = "tcpcb_clk",	.p = PCK_PARENT_HW_MCK5, .id = 90, },
+	{ .n = "tdes_clk",	.p = PCK_PARENT_HW_MCK6, .id = 91, },
+	{ .n = "trng_clk",	.p = PCK_PARENT_HW_MCK6, .id = 92, },
+	{ .n = "udphsa_clk",	.p = PCK_PARENT_HW_MCK5, .id = 99, },
+	{ .n = "udphsb_clk",	.p = PCK_PARENT_HW_MCK5, .id = 100, },
+	{ .n = "uhphs_clk",	.p = PCK_PARENT_HW_MCK5, .id = 101, },
+	{ .n = "dsi_clk",	.p = PCK_PARENT_HW_MCK3, .id = 103, },
+	{ .n = "lvdsc_clk",	.p = PCK_PARENT_HW_MCK3, .id = 104, },
+};
+
+/*
+ * Generic clock description
+ * @n:			clock name
+ * @pp:			PLL parents (entry formed by PLL components identifiers
+ *			(see enum pll_component_id))
+ * @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;
+	struct {
+		int pll_id;
+		int pll_compid;
+	} pp[8];
+	const char pp_mux_table[8];
+	struct clk_range r;
+	int pp_chg_id;
+	u8 pp_count;
+	u8 id;
+} sama7d65_gck[] = {
+	{ .n  = "adc_gclk",
+	  .id = 25,
+	  .r = { .max = 100000000, },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 8, 9, },
+	  .pp_count = 2,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "asrc_gclk",
+	  .id = 29,
+	  .r = { .max = 200000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex0_gclk",
+	  .id = 34,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = {8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex1_gclk",
+	  .id = 35,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = {8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex2_gclk",
+	  .id = 36,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = {8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex3_gclk",
+	  .id = 37,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = {8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex4_gclk",
+	  .id = 38,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex5_gclk",
+	  .id = 39,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex6_gclk",
+	  .id = 40,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex7_gclk",
+	  .id = 41,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex8_gclk",
+	  .id = 42,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex9_gclk",
+	  .id = 43,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "flex10_gclk",
+	  .id = 44,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 8, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "gmac0_gclk",
+	  .id = 46,
+	  .r = { .max = 125000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 10, },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "gmac1_gclk",
+	  .id = 47,
+	  .r = { .max = 125000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 10, },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "gmac0_tsu_gclk",
+	  .id = 49,
+	  .r = { .max = 400000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {10, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "gmac1_tsu_gclk",
+	  .id = 50,
+	  .r = { .max = 400000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 10, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "i2smcc0_gclk",
+	  .id = 54,
+	  .r = { .max = 100000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "i2smcc1_gclk",
+	  .id = 55,
+	  .r = { .max = 100000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n = "lcdc_gclk",
+	  .id = 56,
+	  .r = { .max = 90000000 },
+	  .pp_count = 0,
+	  .pp_chg_id = INT_MIN,
+	},
+
+	{ .n  = "mcan0_gclk",
+	  .id = 58,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "mcan1_gclk",
+	  .id = 59,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "mcan2_gclk",
+	  .id = 60,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "mcan3_gclk",
+	  .id = 61,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "mcan4_gclk",
+	  .id = 62,
+	  .r = { .max = 80000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), },
+	  .pp_mux_table = { 12 },
+	  .pp_count = 1,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "pdmc0_gclk",
+	  .id = 64,
+	  .r = { .max = 80000000  },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9 },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pdmc1_gclk",
+	  .id = 65,
+	  .r = { .max = 80000000, },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b0_gclk",
+	  .id = 66,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b1_gclk",
+	  .id = 67,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b2_gclk",
+	  .id = 68,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b3_gclk",
+	  .id = 69,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b4_gclk",
+	  .id = 70,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "pit64b5_gclk",
+	  .id = 71,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "qspi0_gclk",
+	  .id = 73,
+	  .r = { .max = 400000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 5, 8, },
+	  .pp_count = 2,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "qspi1_gclk",
+	  .id = 74,
+	  .r = { .max = 266000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), },
+	  .pp_mux_table = { 5, 8, },
+	  .pp_count = 2,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "sdmmc0_gclk",
+	  .id = 75,
+	  .r = { .max = 208000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 10, },
+	  .pp_count = 2,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "sdmmc1_gclk",
+	  .id = 76,
+	  .r = { .max = 208000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 10, },
+	  .pp_count = 2,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "sdmmc2_gclk",
+	  .id = 77,
+	  .r = { .max = 208000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 10 },
+	  .pp_count = 2,
+	  .pp_chg_id = 4, },
+
+	{ .n  = "spdifrx_gclk",
+	  .id = 79,
+	  .r = { .max = 150000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n = "spdiftx_gclk",
+	  .id = 80,
+	  .r = { .max = 25000000  },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), },
+	  .pp_mux_table = { 9, },
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "tcb0_ch0_gclk",
+	  .id = 83,
+	  .r = { .max = 34000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n  = "tcb1_ch0_gclk",
+	  .id = 86,
+	  .r = { .max = 67000000 },
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = { 8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n = "DSI_gclk",
+	  .id = 103,
+	  .r = {.max = 27000000},
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), },
+	  .pp_mux_table = {5},
+	  .pp_count = 1,
+	  .pp_chg_id = INT_MIN, },
+
+	{ .n = "I3CC_gclk",
+	  .id = 105,
+	  .r = {.max = 125000000},
+	  .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0),
+		  PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), },
+	  .pp_mux_table = {8, 9, 10, },
+	  .pp_count = 3,
+	  .pp_chg_id = INT_MIN, },
+};
+
+/* MCK0 characteristics. */
+static const struct clk_master_characteristics mck0_characteristics = {
+	.output = { .min = 32768, .max = 200000000 },
+	.divisors = { 1, 2, 4, 3, 5 },
+	.have_div3_pres = 1,
+};
+
+/* MCK0 layout. */
+static const struct clk_master_layout mck0_layout = {
+	.mask = 0x773,
+	.pres_shift = 4,
+	.offset = 0x28,
+};
+
+/* Programmable clock layout. */
+static const struct clk_programmable_layout programmable_layout = {
+	.pres_mask = 0xff,
+	.pres_shift = 8,
+	.css_mask = 0x1f,
+	.have_slck_mck = 0,
+	.is_pres_direct = 1,
+};
+
+/* Peripheral clock layout. */
+static const struct clk_pcr_layout sama7d65_pcr_layout = {
+	.offset = 0x88,
+	.cmd = BIT(31),
+	.gckcss_mask = GENMASK(12, 8),
+	.pid_mask = GENMASK(6, 0),
+};
+
+static void __init sama7d65_pmc_setup(struct device_node *np)
+{
+	const char *main_xtal_name = "main_xtal";
+	struct pmc_data *sama7d65_pmc;
+	const char *parent_names[11];
+	void **alloc_mem = NULL;
+	int alloc_mem_size = 0;
+	struct regmap *regmap;
+	struct clk_hw *hw, *main_rc_hw, *main_osc_hw, *main_xtal_hw;
+	struct clk_hw *td_slck_hw, *md_slck_hw;
+	static struct clk_parent_data parent_data;
+	struct clk_hw *parent_hws[10];
+	bool bypass;
+	int i, j;
+
+	td_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "td_slck"));
+	md_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "md_slck"));
+	main_xtal_hw = __clk_get_hw(of_clk_get_by_name(np, main_xtal_name));
+
+	if (!td_slck_hw || !md_slck_hw || !main_xtal_hw)
+		return;
+
+	regmap = device_node_to_regmap(np);
+	if (IS_ERR(regmap))
+		return;
+
+	sama7d65_pmc = pmc_data_allocate(PMC_INDEX_MAX,
+					 nck(sama7d65_systemck),
+					 nck(sama7d65_periphck),
+					 nck(sama7d65_gck), 8);
+	if (!sama7d65_pmc)
+		return;
+
+	alloc_mem = kmalloc(sizeof(void *) *
+			    (ARRAY_SIZE(sama7d65_mckx) + ARRAY_SIZE(sama7d65_gck)),
+			    GFP_KERNEL);
+	if (!alloc_mem)
+		goto err_free;
+
+	main_rc_hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+						   50000000);
+	if (IS_ERR(main_rc_hw))
+		goto err_free;
+
+	bypass = of_property_read_bool(np, "atmel,osc-bypass");
+
+	parent_data.name = main_xtal_name;
+	parent_data.fw_name = main_xtal_name;
+	main_osc_hw = at91_clk_register_main_osc(regmap, "main_osc", NULL,
+						 &parent_data, bypass);
+	if (IS_ERR(main_osc_hw))
+		goto err_free;
+
+	parent_hws[0] = main_rc_hw;
+	parent_hws[1] = main_osc_hw;
+	hw = at91_clk_register_sam9x5_main(regmap, "mainck", NULL, parent_hws, 2);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	sama7d65_pmc->chws[PMC_MAIN] = hw;
+
+	for (i = 0; i < PLL_ID_MAX; i++) {
+		for (j = 0; j < PLL_COMPID_MAX; j++) {
+			struct clk_hw *parent_hw;
+
+			if (!sama7d65_plls[i][j].n)
+				continue;
+
+			switch (sama7d65_plls[i][j].t) {
+			case PLL_TYPE_FRAC:
+				switch (sama7d65_plls[i][j].p) {
+				case SAMA7D65_PLL_PARENT_MAINCK:
+					parent_hw = sama7d65_pmc->chws[PMC_MAIN];
+					break;
+				case SAMA7D65_PLL_PARENT_MAIN_XTAL:
+					parent_hw = main_xtal_hw;
+					break;
+				default:
+					/* Should not happen. */
+					parent_hw = NULL;
+					break;
+				}
+
+				hw = sam9x60_clk_register_frac_pll(regmap,
+					&pmc_pll_lock, sama7d65_plls[i][j].n,
+					NULL, parent_hw, i,
+					sama7d65_plls[i][j].c,
+					sama7d65_plls[i][j].l,
+					sama7d65_plls[i][j].f);
+				break;
+
+			case PLL_TYPE_DIV:
+				hw = sam9x60_clk_register_div_pll(regmap,
+					&pmc_pll_lock, sama7d65_plls[i][j].n,
+					NULL, sama7d65_plls[i][0].hw, i,
+					sama7d65_plls[i][j].c,
+					sama7d65_plls[i][j].l,
+					sama7d65_plls[i][j].f,
+					sama7d65_plls[i][j].safe_div);
+				break;
+
+			default:
+				continue;
+			}
+
+			if (IS_ERR(hw))
+				goto err_free;
+
+			sama7d65_plls[i][j].hw = hw;
+			if (sama7d65_plls[i][j].eid)
+				sama7d65_pmc->chws[sama7d65_plls[i][j].eid] = hw;
+		}
+	}
+
+	hw = at91_clk_register_master_div(regmap, "mck0", NULL,
+					  sama7d65_plls[PLL_ID_CPU][1].hw,
+					  &mck0_layout, &mck0_characteristics,
+					  &pmc_mck0_lock, CLK_GET_RATE_NOCACHE, 5);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	sama7d65_pmc->chws[PMC_MCK] = hw;
+	sama7d65_mckx[PCK_PARENT_HW_MCK0].hw = hw;
+
+	parent_hws[0] = md_slck_hw;
+	parent_hws[1] = td_slck_hw;
+	parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN];
+	for (i = PCK_PARENT_HW_MCK1; i < ARRAY_SIZE(sama7d65_mckx); i++) {
+		u8 num_parents = 3 + sama7d65_mckx[i].ep_count;
+		struct clk_hw *tmp_parent_hws[8];
+		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, 3);
+		PMC_FILL_TABLE(&mux_table[3], sama7d65_mckx[i].ep_mux_table,
+			       sama7d65_mckx[i].ep_count);
+		for (j = 0; j < sama7d65_mckx[i].ep_count; j++) {
+			u8 pll_id = sama7d65_mckx[i].ep[j].pll_id;
+			u8 pll_compid = sama7d65_mckx[i].ep[j].pll_compid;
+
+			tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw;
+		}
+		PMC_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
+			       sama7d65_mckx[i].ep_count);
+
+		hw = at91_clk_sama7g5_register_master(regmap, sama7d65_mckx[i].n,
+						      num_parents, NULL, parent_hws,
+						      mux_table, &pmc_mckX_lock,
+						      sama7d65_mckx[i].id,
+						      sama7d65_mckx[i].c,
+						      sama7d65_mckx[i].ep_chg_id);
+		alloc_mem[alloc_mem_size++] = mux_table;
+
+		if (IS_ERR(hw)) {
+			kfree(mux_table);
+			goto err_free;
+		}
+
+		sama7d65_mckx[i].hw = hw;
+		if (sama7d65_mckx[i].eid)
+			sama7d65_pmc->chws[sama7d65_mckx[i].eid] = hw;
+	}
+
+	parent_names[0] = "syspll_divpmcck";
+	parent_names[1] = "usbpll_divpmcck";
+	parent_names[2] = "main_osc";
+	hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	parent_hws[0] = md_slck_hw;
+	parent_hws[1] = td_slck_hw;
+	parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN];
+	parent_hws[3] = sama7d65_plls[PLL_ID_SYS][PLL_COMPID_DIV0].hw;
+	parent_hws[4] = sama7d65_plls[PLL_ID_DDR][PLL_COMPID_DIV0].hw;
+	parent_hws[5] = sama7d65_plls[PLL_ID_GPU][PLL_COMPID_DIV0].hw;
+	parent_hws[6] = sama7d65_plls[PLL_ID_BAUD][PLL_COMPID_DIV0].hw;
+	parent_hws[7] = sama7d65_plls[PLL_ID_AUDIO][PLL_COMPID_DIV0].hw;
+	parent_hws[8] = sama7d65_plls[PLL_ID_ETH][PLL_COMPID_DIV0].hw;
+
+	for (i = 0; i < 8; i++) {
+		char name[6];
+
+		snprintf(name, sizeof(name), "prog%d", i);
+
+		hw = at91_clk_register_programmable(regmap, name, NULL, parent_hws,
+						    9, i,
+						    &programmable_layout,
+						    sama7d65_prog_mux_table);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sama7d65_pmc->pchws[i] = hw;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sama7d65_systemck); i++) {
+		hw = at91_clk_register_system(regmap, sama7d65_systemck[i].n,
+					      sama7d65_systemck[i].p, NULL,
+					      sama7d65_systemck[i].id, 0);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sama7d65_pmc->shws[sama7d65_systemck[i].id] = hw;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sama7d65_periphck); i++) {
+		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &sama7d65_pcr_layout,
+							 sama7d65_periphck[i].n,
+							 NULL,
+							 sama7d65_mckx[sama7d65_periphck[i].p].hw,
+							 sama7d65_periphck[i].id,
+							 &sama7d65_periphck[i].r,
+							 sama7d65_periphck[i].chgp ? 0 :
+							 INT_MIN, 0);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sama7d65_pmc->phws[sama7d65_periphck[i].id] = hw;
+	}
+
+	parent_hws[0] = md_slck_hw;
+	parent_hws[1] = td_slck_hw;
+	parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN];
+	parent_hws[3] = sama7d65_pmc->chws[PMC_MCK1];
+	for (i = 0; i < ARRAY_SIZE(sama7d65_gck); i++) {
+		u8 num_parents = 4 + sama7d65_gck[i].pp_count;
+		struct clk_hw *tmp_parent_hws[8];
+		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], sama7d65_gck[i].pp_mux_table,
+			       sama7d65_gck[i].pp_count);
+		for (j = 0; j < sama7d65_gck[i].pp_count; j++) {
+			u8 pll_id = sama7d65_gck[i].pp[j].pll_id;
+			u8 pll_compid = sama7d65_gck[i].pp[j].pll_compid;
+
+			tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw;
+		}
+		PMC_FILL_TABLE(&parent_hws[4], tmp_parent_hws,
+			       sama7d65_gck[i].pp_count);
+
+		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
+						 &sama7d65_pcr_layout,
+						 sama7d65_gck[i].n, NULL,
+						 parent_hws, mux_table,
+						 num_parents,
+						 sama7d65_gck[i].id,
+						 &sama7d65_gck[i].r,
+						 sama7d65_gck[i].pp_chg_id);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sama7d65_pmc->ghws[sama7d65_gck[i].id] = hw;
+		alloc_mem[alloc_mem_size++] = mux_table;
+	}
+
+	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7d65_pmc);
+	kfree(alloc_mem);
+
+	return;
+
+err_free:
+	if (alloc_mem) {
+		for (i = 0; i < alloc_mem_size; i++)
+			kfree(alloc_mem[i]);
+		kfree(alloc_mem);
+	}
+
+	kfree(sama7d65_pmc);
+}
+
+/* Some clks are used for a clocksource */
+CLK_OF_DECLARE(sama7d65_pmc, "microchip,sama7d65-pmc", sama7d65_pmc_setup);
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:13 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:13 -0700
Subject: [PATCH v4 12/13] ARM: configs: at91: sama7: add new SoC config
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <ac5ee2a78309f8a21ad99f53e66206f3d163263b.1734723585.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add sama7d65 to the sama7_defconfig.

Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 arch/arm/configs/sama7_defconfig    | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 758276027dbc..b1dcec1a6df5 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -20,6 +20,7 @@ CONFIG_ARCH_AT91=y
 CONFIG_SOC_SAMA5D2=y
 CONFIG_SOC_SAMA5D3=y
 CONFIG_SOC_SAMA5D4=y
+CONFIG_SOC_SAMA7D65=y
 CONFIG_SOC_SAMA7G5=y
 CONFIG_SOC_LAN966=y
 CONFIG_ARCH_BCM=y
diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 1a2e93c8ee71..ea7ddf640ba7 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -12,6 +12,7 @@ CONFIG_EXPERT=y
 # CONFIG_IO_URING is not set
 CONFIG_KALLSYMS_ALL=y
 CONFIG_ARCH_AT91=y
+CONFIG_SOC_SAMA7D65=y
 CONFIG_SOC_SAMA7G5=y
 CONFIG_ATMEL_CLOCKSOURCE_TCB=y
 # CONFIG_CACHE_L2X0 is not set
-- 
2.43.0



From Ryan.Wanner at microchip.com  Fri Dec 20 13:07:14 2024
From: Ryan.Wanner at microchip.com (Ryan.Wanner at microchip.com)
Date: Fri, 20 Dec 2024 14:07:14 -0700
Subject: [PATCH v4 13/13] ARM: at91: add new SoC sama7d65
In-Reply-To: <cover.1734723585.git.Ryan.Wanner@microchip.com>
References: <cover.1734723585.git.Ryan.Wanner@microchip.com>
Message-ID: <aafa6115adc52d30bc83206f8fab5964d4dd7fb7.1734723585.git.Ryan.Wanner@microchip.com>

From: Ryan Wanner <Ryan.Wanner at microchip.com>

Add new SoC from at91 family: sama7d65

Signed-off-by: Ryan Wanner <Ryan.Wanner at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
 arch/arm/mach-at91/Kconfig | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 344f5305f69a..04bd91c72521 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -58,6 +58,17 @@ config SOC_SAMA5D4
 	help
 	  Select this if you are using one of Microchip's SAMA5D4 family SoC.
 
+config SOC_SAMA7D65
+	bool "SAMA7D65 family"
+	depends on ARCH_MULTI_V7
+	select HAVE_AT91_GENERATED_CLK
+	select HAVE_AT91_SAM9X60_PLL
+	select HAVE_AT91_USB_CLK
+	select HAVE_AT91_UTMI
+	select SOC_SAMA7
+	help
+	  Select this if you are using one of Microchip's SAMA7D65 family SoC.
+
 config SOC_SAMA7G5
 	bool "SAMA7G5 family"
 	depends on ARCH_MULTI_V7
-- 
2.43.0



From kuba at kernel.org  Fri Dec 20 14:01:39 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 20 Dec 2024 14:01:39 -0800
Subject: [PATCH] net: dwmac-imx: add imx93 clock input support in RMII
 mode
In-Reply-To: <20241217084942.4071-1-othacehe@gnu.org>
References: <20241217084942.4071-1-othacehe@gnu.org>
Message-ID: <20241220140139.5c0cee2f@kernel.org>

On Tue, 17 Dec 2024 09:49:42 +0100 Mathieu Othacehe wrote:
> +			ret = regmap_update_bits(dwmac->intf_regmap,
> +						 dwmac->intf_reg_off +
> +						 MX93_GPR_CLK_SEL_OFFSET,
> +						 MX93_GPR_ENET_QOS_CLK_SEL_MASK,
> +						 0);

nit: regmap_clear_bits() ?
-- 
pw-bot: cr


From pr-tracker-bot at kernel.org  Fri Dec 20 14:11:54 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 20 Dec 2024 22:11:54 +0000
Subject: [GIT PULL] arm64 fix for 6.13-rc4
In-Reply-To: <Z2W6puapTlYMGeyx@arm.com>
References: <Z2W6puapTlYMGeyx@arm.com>
Message-ID: <173473271491.3035596.7797347508137942205.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 20 Dec 2024 18:42:46 +0000:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/499551201b5f4fd3c0618a3e95e3d0d15ea18f31

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From konrad.dybcio at oss.qualcomm.com  Fri Dec 20 14:35:00 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 20 Dec 2024 23:35:00 +0100
Subject: =?UTF-8?Q?Re=3A_=E2=9D=8C_FAIL=3A_Test_report_for_for-kernelci_=286?=
 =?UTF-8?Q?=2E13=2E0-rc3=2C_upstream-arm-next=2C_06a57361=29?=
In-Reply-To: <20241220134324.GB26731@willie-the-truck>
References: <64955.124121918121002524@us-mta-554.us.mimecast.lan>
 <20241220123526.GA26697@willie-the-truck>
 <CAMj1kXENrzsF6JzvbGSwiJT5nupfJbij86zp0k2+YbqUCqvqNA@mail.gmail.com>
 <CAMj1kXGx+Li4qwh_05Uf-aTtEOLSThv8o3JjKgWrPp9t8rqQyg@mail.gmail.com>
 <20241220132549.GA26731@willie-the-truck>
 <20241220134324.GB26731@willie-the-truck>
Message-ID: <b759d34a-60fc-4b34-a95b-4cc1c4a68bc7@oss.qualcomm.com>

On 20.12.2024 2:43 PM, Will Deacon wrote:
> On Fri, Dec 20, 2024 at 01:25:50PM +0000, Will Deacon wrote:
>> On Fri, Dec 20, 2024 at 02:06:21PM +0100, Ard Biesheuvel wrote:
>>> On Fri, 20 Dec 2024 at 13:49, Ard Biesheuvel <ardb at kernel.org> wrote:
>>>>
>>>> On Fri, 20 Dec 2024 at 13:35, Will Deacon <will at kernel.org> wrote:
>>>>>
>>>>> On Thu, Dec 19, 2024 at 11:12:08PM -0000, cki-project at redhat.com wrote:
>>>>>> Hi, we tested your kernel and here are the results:
>>>>>>
>>>>>>     Overall result: FAILED
>>>>>>              Merge: OK
>>>>>>            Compile: OK
>>>>>>               Test: FAILED (Did not boot)
>>>>>>
>>>>>>
>>>>>> 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/redhat:1596629923
>>>>>>
>>>>>> One or more kernel builds failed:
>>>>>>     Builds that are failing to boot:
>>>>>>          aarch64 - https://datawarehouse.cki-project.org/kcidb/builds/redhat:1596629923-aarch64-kernel
>>>>>
>>>>> Hmm, I can't find any console logs here. Did the machines really fail that
>>>>> early?
>>>>>
>>>>
>>>> This appears to be my fault: commit 32d053d6f5e92efd
>>>>
>>>>   arm64/mm: Drop configurable 48-bit physical address space limit
>>>>
>>>> inadvertently sets CONFIG_ARM64_LPA2 for all VA space sizes. The
>>>> following hunk needs to be applied to address this
>>>>
>>>> --- a/arch/arm64/Kconfig
>>>> +++ b/arch/arm64/Kconfig
>>>> @@ -1418,7 +1418,7 @@ config ARM64_VA_BITS
>>>>
>>>>  config ARM64_LPA2
>>>>         def_bool y
>>>> -       depends on !ARM64_64K_PAGES
>>>> +       depends on ARM64_VA_BITS_52 && !ARM64_64K_PAGES
>>>>
>>>>  choice
>>>>         prompt "Endianness"
>>>
>>> On second thought, let's just omit commit 32d053d6f5e92efd  for now -
>>> it's at the tip of the for-next/mm branch so it can just be dropped.
>>>
>>> I'll revisit this later - I have to double check that non-LPA2 configs
>>> (such as the one this report is about) work correctly on LPA2 capable
>>> hardware, and don't deviate from LPA2 configs booting with arm64.nolva
>>
>> Sure thing, I'll drop it for now. I've managed to repro the failure
>> under qemu using the CKI .config, so I'll check that things are happy
>> again before I pushed the updated branch.
> 
> Ok, now pushed!

FWIW I ran a bisect and this breaks X1E80100 / Oryon as well..

4k pages, CONFIG_ARM64_LPA2=y, id_aa64mmfr0 = 0x2100122100001024

Konrad


From konrad.dybcio at oss.qualcomm.com  Fri Dec 20 14:36:24 2024
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 20 Dec 2024 23:36:24 +0100
Subject: =?UTF-8?Q?Re=3A_=E2=9D=8C_FAIL=3A_Test_report_for_for-kernelci_=286?=
 =?UTF-8?Q?=2E13=2E0-rc3=2C_upstream-arm-next=2C_06a57361=29?=
In-Reply-To: <20241220134324.GB26731@willie-the-truck>
References: <64955.124121918121002524@us-mta-554.us.mimecast.lan>
 <20241220123526.GA26697@willie-the-truck>
 <CAMj1kXENrzsF6JzvbGSwiJT5nupfJbij86zp0k2+YbqUCqvqNA@mail.gmail.com>
 <CAMj1kXGx+Li4qwh_05Uf-aTtEOLSThv8o3JjKgWrPp9t8rqQyg@mail.gmail.com>
 <20241220132549.GA26731@willie-the-truck>
 <20241220134324.GB26731@willie-the-truck>
Message-ID: <8a591019-acee-447c-9636-c4788743c62d@oss.qualcomm.com>

On 20.12.2024 2:43 PM, Will Deacon wrote:
> On Fri, Dec 20, 2024 at 01:25:50PM +0000, Will Deacon wrote:
>> On Fri, Dec 20, 2024 at 02:06:21PM +0100, Ard Biesheuvel wrote:
>>> On Fri, 20 Dec 2024 at 13:49, Ard Biesheuvel <ardb at kernel.org> wrote:
>>>>
>>>> On Fri, 20 Dec 2024 at 13:35, Will Deacon <will at kernel.org> wrote:
>>>>>
>>>>> On Thu, Dec 19, 2024 at 11:12:08PM -0000, cki-project at redhat.com wrote:
>>>>>> Hi, we tested your kernel and here are the results:
>>>>>>
>>>>>>     Overall result: FAILED
>>>>>>              Merge: OK
>>>>>>            Compile: OK
>>>>>>               Test: FAILED (Did not boot)
>>>>>>
>>>>>>
>>>>>> 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/redhat:1596629923
>>>>>>
>>>>>> One or more kernel builds failed:
>>>>>>     Builds that are failing to boot:
>>>>>>          aarch64 - https://datawarehouse.cki-project.org/kcidb/builds/redhat:1596629923-aarch64-kernel
>>>>>
>>>>> Hmm, I can't find any console logs here. Did the machines really fail that
>>>>> early?
>>>>>
>>>>
>>>> This appears to be my fault: commit 32d053d6f5e92efd
>>>>
>>>>   arm64/mm: Drop configurable 48-bit physical address space limit
>>>>
>>>> inadvertently sets CONFIG_ARM64_LPA2 for all VA space sizes. The
>>>> following hunk needs to be applied to address this
>>>>
>>>> --- a/arch/arm64/Kconfig
>>>> +++ b/arch/arm64/Kconfig
>>>> @@ -1418,7 +1418,7 @@ config ARM64_VA_BITS
>>>>
>>>>  config ARM64_LPA2
>>>>         def_bool y
>>>> -       depends on !ARM64_64K_PAGES
>>>> +       depends on ARM64_VA_BITS_52 && !ARM64_64K_PAGES
>>>>
>>>>  choice
>>>>         prompt "Endianness"
>>>
>>> On second thought, let's just omit commit 32d053d6f5e92efd  for now -
>>> it's at the tip of the for-next/mm branch so it can just be dropped.
>>>
>>> I'll revisit this later - I have to double check that non-LPA2 configs
>>> (such as the one this report is about) work correctly on LPA2 capable
>>> hardware, and don't deviate from LPA2 configs booting with arm64.nolva
>>
>> Sure thing, I'll drop it for now. I've managed to repro the failure
>> under qemu using the CKI .config, so I'll check that things are happy
>> again before I pushed the updated branch.
> 
> Ok, now pushed!

(resending as thunderbird prioritizes replying to the list instead of
all correspondents, sorry)

FWIW I ran a bisect and this breaks X1E80100 / Oryon as well..

4k pages, CONFIG_ARM64_LPA2=y, id_aa64mmfr0 = 0x2100122100001024

Konrad



From dianders at chromium.org  Fri Dec 20 14:52:05 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Fri, 20 Dec 2024 14:52:05 -0800
Subject: [PATCH] PCI: mediatek-gen3: Enable async probe by default
Message-ID: <20241220145205.1.Ibf2563896c3b1fc133bb46d3fc96ad0041763922@changeid>

Like other PCIe drivers, the mediatek-gen3 driver has a fairly slow
probe. Turn on async probe since there's no reason to block the rest
of the system.

Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

 drivers/pci/controller/pcie-mediatek-gen3.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index be52e3a123ab..49512786d5e4 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -1301,6 +1301,7 @@ static struct platform_driver mtk_pcie_driver = {
 		.name = "mtk-pcie-gen3",
 		.of_match_table = mtk_pcie_of_match,
 		.pm = &mtk_pcie_pm_ops,
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
 	},
 };
 
-- 
2.47.1.613.gc27f4b7a9f-goog



From cki-project at redhat.com  Fri Dec 20 14:53:02 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Fri, 20 Dec 2024 22:53:02 -0000
Subject: =?utf-8?b?4pyF?= PASS (MISSED 9 of 69): Test report for for-kernelci
 (6.13.0-rc3, upstream-arm-next, 573067a5)
Message-ID: <51385.124122017530400723@us-mta-326.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/redhat:1597713487

One or more kernel tests failed:
    We also see the following known issues which are not related to your changes:
        Issue: [aarch64][coresight_etm4x][kernel 5.19.0] coresight-etm4x: probe of ARMHC500:20 failed with error -17
            URL: https://lore.kernel.org/all/CA+QYu4ogiTa1V20aqxFqBrMH0z927YNNN2O=CKma+=M_8E81iQ at mail.gmail.com/
            Affected tests:
                Boot test [aarch64]
                Reboot test [aarch64]


Tests that were not ran because of internal issues:
    Hardware - Firmware test suite [aarch64]
    Reboot test [aarch64]
    selinux-policy: serge-testsuite [aarch64]
    Storage - blktests - throtl [aarch64]
    Storage - blktests - ublk [aarch64]
    Storage - swraid scsi_raid [aarch64]
    stress: stress-ng - cpu-cache [aarch64]
    stress: stress-ng - memory [aarch64]


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 klarasmodin at gmail.com  Fri Dec 20 15:39:19 2024
From: klarasmodin at gmail.com (Klara Modin)
Date: Sat, 21 Dec 2024 00:39:19 +0100
Subject: [PATCH v3 6/6] arm64/mm: Drop configurable 48-bit physical
 address space limit
In-Reply-To: <20241212081841.2168124-14-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
 <20241212081841.2168124-14-ardb+git@google.com>
Message-ID: <b20c861b-865a-4d77-bb22-98c4ba8ead16@gmail.com>

Hi,

On 2024-12-12 09:18, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb at kernel.org>
> 
> Currently, the maximum supported physical address space can be
> configured as either 48 bits or 52 bits. The only remaining difference
> between these in practice is that the former omits the masking and
> shifting required to construct TTBR and PTE values, which carry bits #48
> and higher disjoint from the rest of the physical address.
> 
> The overhead of performing these additional calculations is negligible,
> and so there is little reason to retain support for two different
> configurations, and we can simply support whatever the hardware
> supports.
> 

With this patch (32d053d6f5e92efd82349e7c481cba5a43dc1a22 in 
next-20241220), my Raspberry Pi 3 won't boot unless I set it to use 
52-bit virtual address space (i.e. neither 39 or 48 work with a 4 KiB 
page size), nothing appears on the serial console. I didn't see anyghing 
suspicious in the kernel log for the 52-bit case but I attached it as I 
don't exactly have much else.

I see that 52 bit physical address space previously depended on either 
64 KiB pages or 52 bit virtual address space, could that be related?

Please let me know if there's anything else you need.

Regards,
Klara Modin

> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
>   arch/arm64/Kconfig                     | 31 +-------------------
>   arch/arm64/include/asm/assembler.h     | 13 ++------
>   arch/arm64/include/asm/cpufeature.h    |  3 +-
>   arch/arm64/include/asm/kvm_pgtable.h   |  3 +-
>   arch/arm64/include/asm/pgtable-hwdef.h |  6 +---
>   arch/arm64/include/asm/pgtable-prot.h  |  4 +--
>   arch/arm64/include/asm/pgtable.h       | 11 +------
>   arch/arm64/include/asm/sysreg.h        |  6 ----
>   arch/arm64/mm/pgd.c                    |  9 +++---
>   arch/arm64/mm/proc.S                   |  2 --
>   scripts/gdb/linux/constants.py.in      |  1 -
>   tools/arch/arm64/include/asm/sysreg.h  |  6 ----
>   12 files changed, 14 insertions(+), 81 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index c1ca21adddc1..7ebd0ba32a32 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1416,38 +1416,9 @@ config ARM64_VA_BITS
>   	default 48 if ARM64_VA_BITS_48
>   	default 52 if ARM64_VA_BITS_52
>   
> -choice
> -	prompt "Physical address space size"
> -	default ARM64_PA_BITS_48
> -	help
> -	  Choose the maximum physical address range that the kernel will
> -	  support.
> -
> -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"
> -	depends on ARM64_64K_PAGES || ARM64_VA_BITS_52
> -	help
> -	  Enable support for a 52-bit physical address space, introduced as
> -	  part of the ARMv8.2-LPA extension.
> -
> -	  With this enabled, the kernel will also continue to work on CPUs that
> -	  do not support ARMv8.2-LPA, but with some added memory overhead (and
> -	  minor performance overhead).
> -
> -endchoice
> -
> -config ARM64_PA_BITS
> -	int
> -	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
> +	depends on !ARM64_64K_PAGES
>   
>   choice
>   	prompt "Endianness"
> diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
> index ad63457a05c5..01a1e3c16283 100644
> --- a/arch/arm64/include/asm/assembler.h
> +++ b/arch/arm64/include/asm/assembler.h
> @@ -342,14 +342,13 @@ alternative_cb_end
>   	mrs	\tmp0, ID_AA64MMFR0_EL1
>   	// Narrow PARange to fit the PS field in TCR_ELx
>   	ubfx	\tmp0, \tmp0, #ID_AA64MMFR0_EL1_PARANGE_SHIFT, #3
> -	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_MAX
>   #ifdef CONFIG_ARM64_LPA2
>   alternative_if_not ARM64_HAS_VA52
>   	mov	\tmp1, #ID_AA64MMFR0_EL1_PARANGE_48
> -alternative_else_nop_endif
> -#endif
>   	cmp	\tmp0, \tmp1
>   	csel	\tmp0, \tmp1, \tmp0, hi
> +alternative_else_nop_endif
> +#endif
>   	bfi	\tcr, \tmp0, \pos, #3
>   	.endm
>   
> @@ -599,21 +598,13 @@ alternative_endif
>    * 	ttbr:	returns the TTBR value
>    */
>   	.macro	phys_to_ttbr, ttbr, phys
> -#ifdef CONFIG_ARM64_PA_BITS_52
>   	orr	\ttbr, \phys, \phys, lsr #46
>   	and	\ttbr, \ttbr, #TTBR_BADDR_MASK_52
> -#else
> -	mov	\ttbr, \phys
> -#endif
>   	.endm
>   
>   	.macro	phys_to_pte, pte, phys
> -#ifdef CONFIG_ARM64_PA_BITS_52
>   	orr	\pte, \phys, \phys, lsr #PTE_ADDR_HIGH_SHIFT
>   	and	\pte, \pte, #PHYS_TO_PTE_ADDR_MASK
> -#else
> -	mov	\pte, \phys
> -#endif
>   	.endm
>   
>   /*
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index b64e49bd9d10..ed327358e734 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -885,9 +885,8 @@ static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
>   	 * However, by the "D10.1.4 Principles of the ID scheme
>   	 * for fields in ID registers", ARM DDI 0487C.a, any new
>   	 * value is guaranteed to be higher than what we know already.
> -	 * As a safe limit, we return the limit supported by the kernel.
>   	 */
> -	default: return CONFIG_ARM64_PA_BITS;
> +	default: return 52;
>   	}
>   }
>   
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index aab04097b505..525aef178cb4 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -30,8 +30,7 @@
>   
>   static inline u64 kvm_get_parange_max(void)
>   {
> -	if (kvm_lpa2_is_enabled() ||
> -	   (IS_ENABLED(CONFIG_ARM64_PA_BITS_52) && PAGE_SHIFT == 16))
> +	if (kvm_lpa2_is_enabled() || PAGE_SHIFT == 16)
>   		return ID_AA64MMFR0_EL1_PARANGE_52;
>   	else
>   		return ID_AA64MMFR0_EL1_PARANGE_48;
> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> index a9136cc551cc..9b34180042b2 100644
> --- a/arch/arm64/include/asm/pgtable-hwdef.h
> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> @@ -176,7 +176,6 @@
>   #define PTE_SWBITS_MASK		_AT(pteval_t, (BIT(63) | GENMASK(58, 55)))
>   
>   #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_HIGH_SHIFT	36
> @@ -186,7 +185,6 @@
>   #define PTE_ADDR_HIGH_SHIFT	42
>   #define PHYS_TO_PTE_ADDR_MASK	GENMASK_ULL(49, 8)
>   #endif
> -#endif
>   
>   /*
>    * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
> @@ -327,12 +325,10 @@
>   /*
>    * TTBR.
>    */
> -#ifdef CONFIG_ARM64_PA_BITS_52
>   /*
> - * TTBR_ELx[1] is RES0 in this configuration.
> + * TTBR_ELx[1] is RES0 when using 52-bit physical addressing
>    */
>   #define TTBR_BADDR_MASK_52	GENMASK_ULL(47, 2)
> -#endif
>   
>   #ifdef CONFIG_ARM64_VA_BITS_52
>   /* Must be at least 64-byte aligned to prevent corruption of the TTBR */
> diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
> index a95f1f77bb39..b73acf25341f 100644
> --- a/arch/arm64/include/asm/pgtable-prot.h
> +++ b/arch/arm64/include/asm/pgtable-prot.h
> @@ -81,7 +81,7 @@ extern unsigned long prot_ns_shared;
>   #define lpa2_is_enabled()	false
>   #define PTE_MAYBE_SHARED	PTE_SHARED
>   #define PMD_MAYBE_SHARED	PMD_SECT_S
> -#define PHYS_MASK_SHIFT		(CONFIG_ARM64_PA_BITS)
> +#define PHYS_MASK_SHIFT		(52)
>   #else
>   static inline bool __pure lpa2_is_enabled(void)
>   {
> @@ -90,7 +90,7 @@ static inline bool __pure lpa2_is_enabled(void)
>   
>   #define PTE_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PTE_SHARED)
>   #define PMD_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PMD_SECT_S)
> -#define PHYS_MASK_SHIFT		(lpa2_is_enabled() ? CONFIG_ARM64_PA_BITS : 48)
> +#define PHYS_MASK_SHIFT		(lpa2_is_enabled() ? 52 : 48)
>   #endif
>   
>   /*
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 6986345b537a..ec8124d66b9c 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -69,10 +69,9 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
>   	pr_err("%s:%d: bad pte %016llx.\n", __FILE__, __LINE__, pte_val(e))
>   
>   /*
> - * Macros to convert between a physical address and its placement in a
> + * Helpers to convert between a physical address and its placement in a
>    * page table entry, taking care of 52-bit addresses.
>    */
> -#ifdef CONFIG_ARM64_PA_BITS_52
>   static inline phys_addr_t __pte_to_phys(pte_t pte)
>   {
>   	pte_val(pte) &= ~PTE_MAYBE_SHARED;
> @@ -83,10 +82,6 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>   {
>   	return (phys | (phys >> PTE_ADDR_HIGH_SHIFT)) & PHYS_TO_PTE_ADDR_MASK;
>   }
> -#else
> -#define __pte_to_phys(pte)	(pte_val(pte) & PTE_ADDR_LOW)
> -#define __phys_to_pte_val(phys)	(phys)
> -#endif
>   
>   #define pte_pfn(pte)		(__pte_to_phys(pte) >> PAGE_SHIFT)
>   #define pfn_pte(pfn,prot)	\
> @@ -1495,11 +1490,7 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
>   	update_mmu_cache_range(NULL, vma, addr, ptep, 1)
>   #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
>   
> -#ifdef CONFIG_ARM64_PA_BITS_52
>   #define phys_to_ttbr(addr)	(((addr) | ((addr) >> 46)) & TTBR_BADDR_MASK_52)
> -#else
> -#define phys_to_ttbr(addr)	(addr)
> -#endif
>   
>   /*
>    * On arm64 without hardware Access Flag, copying from user will fail because
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index b8303a83c0bf..f902893ec903 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -916,12 +916,6 @@
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2		0x3
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX		0x7
>   
> -#ifdef CONFIG_ARM64_PA_BITS_52
> -#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_52
> -#else
> -#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_48
> -#endif
> -
>   #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
> diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
> index 0c501cabc238..8722ab6d4b1c 100644
> --- a/arch/arm64/mm/pgd.c
> +++ b/arch/arm64/mm/pgd.c
> @@ -48,20 +48,21 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
>   
>   void __init pgtable_cache_init(void)
>   {
> +	unsigned int pgd_size = PGD_SIZE;
> +
>   	if (pgdir_is_page_size())
>   		return;
>   
> -#ifdef CONFIG_ARM64_PA_BITS_52
>   	/*
>   	 * With 52-bit physical addresses, the architecture requires the
>   	 * top-level table to be aligned to at least 64 bytes.
>   	 */
> -	BUILD_BUG_ON(PGD_SIZE < 64);
> -#endif
> +	if (PHYS_MASK_SHIFT >= 52)
> +		pgd_size = max(pgd_size, 64);
>   
>   	/*
>   	 * Naturally aligned pgds required by the architecture.
>   	 */
> -	pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
> +	pgd_cache = kmem_cache_create("pgd_cache", pgd_size, pgd_size,
>   				      SLAB_PANIC, NULL);
>   }
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index b8edc5765441..51ed0e9d0a0d 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -197,10 +197,8 @@ SYM_FUNC_ALIAS(__pi_idmap_cpu_replace_ttbr1, idmap_cpu_replace_ttbr1)
>   
>   	.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
> diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
> index fd6bd69c5096..05034c0b8fd7 100644
> --- a/scripts/gdb/linux/constants.py.in
> +++ b/scripts/gdb/linux/constants.py.in
> @@ -141,7 +141,6 @@ LX_CONFIG(CONFIG_ARM64_4K_PAGES)
>   LX_CONFIG(CONFIG_ARM64_16K_PAGES)
>   LX_CONFIG(CONFIG_ARM64_64K_PAGES)
>   if IS_BUILTIN(CONFIG_ARM64):
> -    LX_VALUE(CONFIG_ARM64_PA_BITS)
>       LX_VALUE(CONFIG_ARM64_VA_BITS)
>       LX_VALUE(CONFIG_PAGE_SHIFT)
>       LX_VALUE(CONFIG_ARCH_FORCE_MAX_ORDER)
> diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
> index cd8420e8c3ad..daeecb1a5366 100644
> --- a/tools/arch/arm64/include/asm/sysreg.h
> +++ b/tools/arch/arm64/include/asm/sysreg.h
> @@ -574,12 +574,6 @@
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MIN		0x2
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX		0x7
>   
> -#ifdef CONFIG_ARM64_PA_BITS_52
> -#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_52
> -#else
> -#define ID_AA64MMFR0_EL1_PARANGE_MAX	ID_AA64MMFR0_EL1_PARANGE_48
> -#endif
> -
>   #if defined(CONFIG_ARM64_4K_PAGES)
>   #define ID_AA64MMFR0_EL1_TGRAN_SHIFT		ID_AA64MMFR0_EL1_TGRAN4_SHIFT
>   #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN
-------------- next part --------------
# bad: [8155b4ef3466f0e289e8fcc9e6e62f3f4dceeac2] Add linux-next specific files for 20241220
# good: [8faabc041a001140564f718dabe37753e88b37fa] Merge tag 'net-6.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
git bisect start 'next/master' 'next/stable'
# bad: [d711d1b348a1574a2c24872512067d190b63fd68] Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git
git bisect bad d711d1b348a1574a2c24872512067d190b63fd68
# bad: [3aa602263e025bb42ca8766a16bceff287a8f0ee] Merge branch 'xtensa-for-next' of git://github.com/jcmvbkbc/linux-xtensa.git
git bisect bad 3aa602263e025bb42ca8766a16bceff287a8f0ee
# good: [c4262cd734f8695b217332ed2ca7237a7e753b62] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git
git bisect good c4262cd734f8695b217332ed2ca7237a7e753b62
# bad: [a03c7cb185a0648d4f67fb63acf4b98b6fe8d0f7] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git
git bisect bad a03c7cb185a0648d4f67fb63acf4b98b6fe8d0f7
# bad: [2086880948dccced5110e472a99915913cec1b8b] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git
git bisect bad 2086880948dccced5110e472a99915913cec1b8b
# good: [e7bb49e3f6435ff3611b83f78a61d387f24d80f8] perf x86: Define arch_fetch_insn in NO_AUXTRACE builds
git bisect good e7bb49e3f6435ff3611b83f78a61d387f24d80f8
# bad: [7bdd902c162d5576785095a0f8885df84bb472f5] Merge branch 'for-next/core' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
git bisect bad 7bdd902c162d5576785095a0f8885df84bb472f5
# bad: [d6ab634f1b323db6639b8b776f5d95ae747b342a] Merge branches 'for-next/cpufeature', 'for-next/docs', 'for-next/misc' and 'for-next/mm' into for-next/core
git bisect bad d6ab634f1b323db6639b8b776f5d95ae747b342a
# bad: [32d053d6f5e92efd82349e7c481cba5a43dc1a22] arm64/mm: Drop configurable 48-bit physical address space limit
git bisect bad 32d053d6f5e92efd82349e7c481cba5a43dc1a22
# good: [f0da16992aef7e246b2f3bba1492e3a52c38ca0e] arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
git bisect good f0da16992aef7e246b2f3bba1492e3a52c38ca0e
# good: [92b6919d7fb29691a8bc5aca49044056683542ca] arm64: Kconfig: force ARM64_PAN=y when enabling TTBR0 sw PAN
git bisect good 92b6919d7fb29691a8bc5aca49044056683542ca
# first bad commit: [32d053d6f5e92efd82349e7c481cba5a43dc1a22] arm64/mm: Drop configurable 48-bit physical address space limit
-------------- next part --------------
A non-text attachment was scrubbed...
Name: config.gz
Type: application/gzip
Size: 34839 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241221/7c853777/attachment.gz>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dmesg-52-bit.log.gz
Type: application/gzip
Size: 7734 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20241221/7c853777/attachment-0001.gz>

From ardb at kernel.org  Fri Dec 20 15:41:39 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 21 Dec 2024 00:41:39 +0100
Subject: [PATCH v3 6/6] arm64/mm: Drop configurable 48-bit physical
 address space limit
In-Reply-To: <b20c861b-865a-4d77-bb22-98c4ba8ead16@gmail.com>
References: <20241212081841.2168124-8-ardb+git@google.com> <20241212081841.2168124-14-ardb+git@google.com>
 <b20c861b-865a-4d77-bb22-98c4ba8ead16@gmail.com>
Message-ID: <CAMj1kXF2qYOgHKKK943jvYgOLcRVMwDuA9PGqDwerzhF83-QEQ@mail.gmail.com>

On Sat, 21 Dec 2024 at 00:39, Klara Modin <klarasmodin at gmail.com> wrote:
>
> Hi,
>
> On 2024-12-12 09:18, Ard Biesheuvel wrote:
> > From: Ard Biesheuvel <ardb at kernel.org>
> >
> > Currently, the maximum supported physical address space can be
> > configured as either 48 bits or 52 bits. The only remaining difference
> > between these in practice is that the former omits the masking and
> > shifting required to construct TTBR and PTE values, which carry bits #48
> > and higher disjoint from the rest of the physical address.
> >
> > The overhead of performing these additional calculations is negligible,
> > and so there is little reason to retain support for two different
> > configurations, and we can simply support whatever the hardware
> > supports.
> >
>
> With this patch (32d053d6f5e92efd82349e7c481cba5a43dc1a22 in
> next-20241220), my Raspberry Pi 3 won't boot unless I set it to use
> 52-bit virtual address space (i.e. neither 39 or 48 work with a 4 KiB
> page size), nothing appears on the serial console. I didn't see anyghing
> suspicious in the kernel log for the 52-bit case but I attached it as I
> don't exactly have much else.
>
> I see that 52 bit physical address space previously depended on either
> 64 KiB pages or 52 bit virtual address space, could that be related?
>
> Please let me know if there's anything else you need.
>

Thanks for the report. This patch has already been dropped from the
arm64 tree, so it should be gone from linux-next once it gets
regenerated.


From sboyd at kernel.org  Fri Dec 20 15:43:52 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 20 Dec 2024 15:43:52 -0800
Subject: [PATCH] clk: clk-imx8mp-audiomix: fix function signature
In-Reply-To: <20241219105447.889CB11FE@mail.steuer-voss.de>
References: <20241219105447.889CB11FE@mail.steuer-voss.de>
Message-ID: <ae80d29442890a356289ad1f0caab906.sboyd@kernel.org>

Quoting Nikolaus Voss (2024-12-19 02:54:11)
> clk_imx8mp_audiomix_reset_controller_register() in the
> "if !CONFIG_RESET_CONTROLLER" branch had the first
> argument missing. It is an empty function for this branch
> so it wasn't immediately apparent.
> 
> Fixes: 6f0e817175c5 ("clk: imx: clk-audiomix: Add reset controller")
> Cc: <stable at vger.kernel.org> # 6.12.x
> Signed-off-by: Nikolaus Voss <nv at vosn.de>
> ---

Applied to clk-fixes


From sboyd at kernel.org  Fri Dec 20 15:55:21 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 20 Dec 2024 15:55:21 -0800
Subject: [PATCH 1/3] clk: add a clk_hw helper to get the associate device structure
In-Reply-To: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-1-96dd657cbfbd@baylibre.com>
References: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com> <20241220-amlogic-clk-drop-clk-regmap-tables-v1-1-96dd657cbfbd@baylibre.com>
Message-ID: <6ce3260dafcf3b1ace3d6bb4255e2d9b.sboyd@kernel.org>

Quoting Jerome Brunet (2024-12-20 09:17:42)
> Add an helper function to get the 'struct device' associated with

Add a helper

> an a 'clk_hw'. This can be used by clock drivers to access various

with a 'clk_hw'

> device related functionnalities such as devres, dev_ prints, etc ...

s/functionnalities/functionality/

> 
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
>  drivers/clk/clk.c            | 6 ++++++
>  include/linux/clk-provider.h | 1 +
>  2 files changed, 7 insertions(+)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 9b45fa005030f56e1478b9742715ebcde898133f..7e734d2955978cafd77d911562a26f1646684ec2 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -365,6 +365,12 @@ const char *clk_hw_get_name(const struct clk_hw *hw)
>  }
>  EXPORT_SYMBOL_GPL(clk_hw_get_name);
>  
> +struct device *clk_hw_get_dev(const struct clk_hw *hw)

Please document with kernel doc

> +{
> +       return hw->core->dev;
> +}
> +EXPORT_SYMBOL_GPL(clk_hw_get_dev);

I suspect a quick KUnit test can be written up as well that confirms the
device the clk is registered with is returned.


From sboyd at kernel.org  Fri Dec 20 16:12:03 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 20 Dec 2024 16:12:03 -0800
Subject: [PATCH 2/3] clk: amlogic: drop clk_regmap tables
In-Reply-To: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-2-96dd657cbfbd@baylibre.com>
References: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com> <20241220-amlogic-clk-drop-clk-regmap-tables-v1-2-96dd657cbfbd@baylibre.com>
Message-ID: <9f1d69ebe1ddce5dfc170e986c9213f2.sboyd@kernel.org>

Quoting Jerome Brunet (2024-12-20 09:17:43)
> Remove the big clk_regmap tables that are used to populate the regmap
> field of clk_regmap clocks at runtime. Instead of using tables, use devres
> to allow the clocks to get the necessary regmap.
> 
> A simpler solution would have been to use dev_get_regmap() but this would
> not work with syscon based controllers.

Why not have two init functions, one that uses the syscon approach from
the parent device? Is the typical path to not use a syscon anyway?

> 
> This rework save a bit memory and the result is less of a maintenance
> burden.
> 
> Unfortunately meson8b is left out for now since it is an early clock
> driver that does not have proper device support for now.

We should add a clk_hw_get_of_node() function that returns
hw->core->of_node. Then there can be a similar function that looks at
the of_node of a clk registered with of_clk_hw_register() and tries to
find the regmap either with
syscon_node_to_regmap(clk_hw_get_of_node(hw)) or on the parent of the
node for the clk.

TL;DR: Don't use devres.

> 
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
>  drivers/clk/meson/a1-peripherals.c | 165 +-------------
>  drivers/clk/meson/a1-pll.c         |  18 +-
>  drivers/clk/meson/axg-aoclk.c      |  22 --
>  drivers/clk/meson/axg-audio.c      | 435 +------------------------------------
>  drivers/clk/meson/axg.c            | 131 -----------
>  drivers/clk/meson/c3-peripherals.c | 212 +-----------------
>  drivers/clk/meson/c3-pll.c         |  34 +--
>  drivers/clk/meson/clk-cpu-dyndiv.c |   1 +
>  drivers/clk/meson/clk-dualdiv.c    |   2 +
>  drivers/clk/meson/clk-mpll.c       |   6 +
>  drivers/clk/meson/clk-phase.c      |  11 +
>  drivers/clk/meson/clk-pll.c        |   7 +
>  drivers/clk/meson/clk-regmap.c     |  88 ++++++++
>  drivers/clk/meson/clk-regmap.h     |   7 +
>  drivers/clk/meson/g12a-aoclk.c     |  34 ---
>  drivers/clk/meson/g12a.c           | 261 ----------------------
>  drivers/clk/meson/gxbb-aoclk.c     |  19 --
>  drivers/clk/meson/gxbb.c           | 393 ---------------------------------
>  drivers/clk/meson/meson-aoclk.c    |   7 +-
>  drivers/clk/meson/meson-aoclk.h    |   2 -
>  drivers/clk/meson/meson-eeclk.c    |   6 +-
>  drivers/clk/meson/meson-eeclk.h    |   2 -
>  drivers/clk/meson/meson8-ddr.c     |  11 +-
>  drivers/clk/meson/s4-peripherals.c | 231 +-------------------
>  drivers/clk/meson/s4-pll.c         |  33 +--
>  drivers/clk/meson/sclk-div.c       |   5 +
>  drivers/clk/meson/vclk.c           |   2 +
>  drivers/clk/meson/vid-pll-div.c    |   1 +
>  28 files changed, 165 insertions(+), 1981 deletions(-)

It would be more focused if you split the patch into two. One that
installs the init clk_op and implements the logic to hook up the regmap
and one that removes the arrays that are no longer used.


From nathan at kernel.org  Fri Dec 20 16:29:06 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri, 20 Dec 2024 17:29:06 -0700
Subject: [PATCH v3 6/6] arm64/mm: Drop configurable 48-bit physical
 address space limit
In-Reply-To: <20241212081841.2168124-14-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
 <20241212081841.2168124-14-ardb+git@google.com>
Message-ID: <20241221002906.GA2558963@ax162>

Hi Ard,

On Thu, Dec 12, 2024 at 09:18:48AM +0100, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb at kernel.org>
> 
> Currently, the maximum supported physical address space can be
> configured as either 48 bits or 52 bits. The only remaining difference
> between these in practice is that the former omits the masking and
> shifting required to construct TTBR and PTE values, which carry bits #48
> and higher disjoint from the rest of the physical address.
> 
> The overhead of performing these additional calculations is negligible,
> and so there is little reason to retain support for two different
> configurations, and we can simply support whatever the hardware
> supports.

I am seeing a boot failure after this change as commit 32d053d6f5e9
("arm64/mm: Drop configurable 48-bit physical address space limit") in
next-20241220 with several distribution configurations that all set
ARM64_VA_BITS_48. I can reproduce it on bare metal and in QEMU. Simply:

$ echo 'CONFIG_ARM64_VA_BITS_52=n
CONFIG_ARM64_VA_BITS_48=y' >kernel/configs/repro.config

$ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux- mrproper defconfig repro.config Image.gz

$ git diff --no-index .config.old .config
diff --git a/.config.old b/.config
index c6dfbacfae06..371145bbe022 100644
--- a/.config.old
+++ b/.config
@@ -290,7 +290,7 @@ CONFIG_MMU=y
 CONFIG_ARM64_CONT_PTE_SHIFT=4
 CONFIG_ARM64_CONT_PMD_SHIFT=4
 CONFIG_ARCH_MMAP_RND_BITS_MIN=18
-CONFIG_ARCH_MMAP_RND_BITS_MAX=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=33
 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
 CONFIG_STACKTRACE_SUPPORT=y
@@ -304,7 +304,7 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_SMP=y
 CONFIG_KERNEL_MODE_NEON=y
 CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_PGTABLE_LEVELS=5
+CONFIG_PGTABLE_LEVELS=4
 CONFIG_ARCH_SUPPORTS_UPROBES=y
 CONFIG_ARCH_PROC_KCORE_TEXT=y
 CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
@@ -426,7 +426,9 @@ CONFIG_ARM64_4K_PAGES=y
 # CONFIG_ARM64_16K_PAGES is not set
 # CONFIG_ARM64_64K_PAGES is not set
 # CONFIG_ARM64_VA_BITS_39 is not set
-CONFIG_ARM64_VA_BITS=52
+CONFIG_ARM64_VA_BITS_48=y
+# CONFIG_ARM64_VA_BITS_52 is not set
+CONFIG_ARM64_VA_BITS=48
 CONFIG_ARM64_LPA2=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
@@ -11259,6 +11261,3 @@ CONFIG_MEMTEST=y
 #
 # end of Rust hacking
 # end of Kernel hacking
-
-CONFIG_ARM64_VA_BITS_52=n
-CONFIG_ARM64_VA_BITS_48=y

$ qemu-system-aarch64 --version | head -1
QEMU emulator version 9.2.0 (qemu-9.2.0-1.fc42)

# With TCG, there is a crash
$ qemu-system-aarch64 \
	-display none \
	-nodefaults \
	-cpu max,pauth-impdef=true \
	-machine virt,gic-version=max,virtualization=true \
	-append 'console=ttyAMA0 earlycon' \
	-kernel arch/arm64/boot/Image.gz \
	-initrd rootfs.cpio \
	-m 512m -serial mon:stdio
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x000f0510]
[    0.000000] Linux version 6.13.0-rc2-00006-g32d053d6f5e9 (nathan at c3-large-arm64) (aarch64-linux-gcc (GCC) 14.2.0, GNU ld (GNU Binutils) 2.42) #1 SMP PREEMPT Fri Dec 20 23:42:18 UTC 2024
...
[    0.000000] Unable to handle kernel paging request at virtual address ffff80008001ffe8
[    0.000000] Mem abort info:
[    0.000000]   ESR = 0x0000000096000004
[    0.000000]   EC = 0x25: DABT (current EL), IL = 32 bits
[    0.000000]   SET = 0, FnV = 0
[    0.000000]   EA = 0, S1PTW = 0
[    0.000000]   FSC = 0x04: level 0 translation fault
[    0.000000] Data abort info:
[    0.000000]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[    0.000000]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[    0.000000]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[    0.000000] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000041f10000
[    0.000000] [ffff80008001ffe8] pgd=0000000000000000, p4d=0000000000000000, pud=1000000043017403, pmd=1000000043018403, pte=006800000800f713
[    0.000000] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.13.0-rc2-00006-g32d053d6f5e9 #1
[    0.000000] Hardware name: linux,dummy-virt (DT)
[    0.000000] pstate: 800000c9 (Nzcv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[    0.000000] pc : readl_relaxed+0x0/0x8
[    0.000000] lr : gic_validate_dist_version+0x18/0x3c
[    0.000000] sp : ffffb0df9bf63c90
[    0.000000] x29: ffffb0df9bf63c90 x28: 0000000000000000 x27: 0000000000000000
[    0.000000] x26: ffffb0df9bf63d78 x25: 0000000000000008 x24: dead000000000122
[    0.000000] x23: ffff800080010000 x22: ffffb0df9bf63d88 x21: ffffb0df9bf63d78
[    0.000000] x20: 0000000000000000 x19: ffff39131ff08a68 x18: 0000000000000001
[    0.000000] x17: 0000000000000068 x16: 0000000000000100 x15: ffffb0df9b722ee0
[    0.000000] x14: 0000000000000000 x13: ffff800080021000 x12: ffff80008001ffff
[    0.000000] x11: 0000000000000000 x10: 0000000008010000 x9 : 0000000008010000
[    0.000000] x8 : ffff80008001ffff x7 : ffff391303017008 x6 : ffff800080020000
[    0.000000] x5 : 000000000000003f x4 : 000000000000003f x3 : 0000000000000000
[    0.000000] x2 : 0000000000000000 x1 : 000000000000ffe8 x0 : ffff80008001ffe8
[    0.000000] Call trace:
[    0.000000]  readl_relaxed+0x0/0x8 (P)
[    0.000000]  gic_validate_dist_version+0x18/0x3c (L)
[    0.000000]  gic_of_init+0x98/0x278
[    0.000000]  of_irq_init+0x1d4/0x34c
[    0.000000]  irqchip_init+0x18/0x40
[    0.000000]  init_IRQ+0x9c/0xb4
[    0.000000]  start_kernel+0x528/0x6d4
[    0.000000]  __primary_switched+0x88/0x90
[    0.000000] Code: a8c17bfd d50323bf d65f03c0 d503201f (b9400000)
[    0.000000] ---[ end trace 0000000000000000 ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---

# Using KVM, there is just a hang
$ qemu-system-aarch64 \
	-display none \
	-nodefaults \
	-machine virt,gic-version=max \
	-append 'console=ttyAMA0 earlycon' \
	-kernel arch/arm64/boot/Image.gz \
	-initrd rootfs.cpio \
	-cpu host \
	-enable-kvm \
	-m 512m \
	-smp 8 \
	-serial mon:stdio

Is this a configuration issue? Reverting this change makes everything
work again.

Cheers,
Nathan


From oliver.upton at linux.dev  Fri Dec 20 17:38:28 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 20 Dec 2024 17:38:28 -0800
Subject: [PATCH v2 01/12] KVM: arm64: nv: Add handling of EL2-specific
 timer registers
In-Reply-To: <20241217142321.763801-2-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
 <20241217142321.763801-2-maz@kernel.org>
Message-ID: <Z2Yb8BWnqpt441V-@linux.dev>

On Tue, Dec 17, 2024 at 02:23:09PM +0000, Marc Zyngier wrote:
> @@ -3879,9 +4020,11 @@ static const struct sys_reg_desc cp15_64_regs[] = {
>  	{ SYS_DESC(SYS_AARCH32_CNTPCT),	      access_arch_timer },
>  	{ Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, TTBR1_EL1 },
>  	{ Op1( 1), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_ASGI1R */
> +	{ SYS_DESC(SYS_AARCH32_CNTVCT),	      access_arch_timer },
>  	{ Op1( 2), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI0R */
>  	{ SYS_DESC(SYS_AARCH32_CNTP_CVAL),    access_arch_timer },
>  	{ SYS_DESC(SYS_AARCH32_CNTPCTSS),     access_arch_timer },
> +	{ SYS_DESC(SYS_AARCH32_CNTVCTSS),     access_arch_timer },
>  };

Huh. You know, I had always thought we hid 32-bit EL0 from nested
guests, but I now realize that isn't the case. Of course, we don't have
the necessary trap reflection for exits that came out of a 32-bit EL0,
nor should we bother.

Of the 4 NV2 implementations I'm aware of (Neoverse-V1, Neoverse-V2,
AmpereOne, M2) only Neoverse-V1 supports 32-bit userspace. And even
then, a lot of deployments of V1 have a broken NV2 implementation.

What do you think about advertising a 64-bit only EL0 for nested VMs?

-- 
Thanks,
Oliver


From lkp at intel.com  Fri Dec 20 17:42:42 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 09:42:42 +0800
Subject: [PATCH 1/2] memory/mediatek: Add an interface to get current DDR
 data rate
In-Reply-To: <20241212090029.13692-2-crystal.guo@mediatek.com>
References: <20241212090029.13692-2-crystal.guo@mediatek.com>
Message-ID: <202412210955.FvO0Pee3-lkp@intel.com>

Hi Crystal,

kernel test robot noticed the following build errors:

[auto build test ERROR on krzk-mem-ctrl/for-next]
[also build test ERROR on robh/for-next krzk-dt/for-next linus/master v6.13-rc3 next-20241220]
[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/Crystal-Guo/memory-mediatek-Add-an-interface-to-get-current-DDR-data-rate/20241212-170306
base:   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git for-next
patch link:    https://lore.kernel.org/r/20241212090029.13692-2-crystal.guo%40mediatek.com
patch subject: [PATCH 1/2] memory/mediatek: Add an interface to get current DDR data rate
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20241221/202412210955.FvO0Pee3-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241221/202412210955.FvO0Pee3-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/202412210955.FvO0Pee3-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/memory/mediatek/mtk-dramc.c:300:19: error: initialization of 'void (*)(struct platform_device *)' from incompatible pointer type 'int (*)(struct platform_device *)' [-Wincompatible-pointer-types]
     300 |         .remove = dramc_remove,
         |                   ^~~~~~~~~~~~
   drivers/memory/mediatek/mtk-dramc.c:300:19: note: (near initialization for 'dramc_drv.<anonymous>.remove')


vim +300 drivers/memory/mediatek/mtk-dramc.c

   297	
   298	static struct platform_driver dramc_drv = {
   299		.probe = dramc_probe,
 > 300		.remove = dramc_remove,
   301		.driver = {
   302			.name = "dramc_drv",
   303			.owner = THIS_MODULE,
   304			.of_match_table = dramc_of_ids,
   305		},
   306	};
   307	

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


From jassisinghbrar at gmail.com  Fri Dec 20 18:19:13 2024
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Fri, 20 Dec 2024 20:19:13 -0600
Subject: [PATCH v5 1/3] dt-bindings: mailbox: add google,gs101-mbox
In-Reply-To: <ec3cdfd1-df7a-466c-8581-c9546ca6b089@linaro.org>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
 <20241217-acpm-v4-upstream-mbox-v5-1-cd1d3951fe84@linaro.org> <ec3cdfd1-df7a-466c-8581-c9546ca6b089@linaro.org>
Message-ID: <CABb+yY0rBzP8JPAik5aaXp6GivQKEf++sgiMM9fTPgd_5YXT1w@mail.gmail.com>

On Thu, Dec 19, 2024 at 4:51?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> Hi, Krzysztof, Jassi,
>
> On 12/17/24 9:40 AM, Tudor Ambarus wrote:
>
> > diff --git a/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
>
> cut
>
> > +
> > +  '#mbox-cells':
> > +    description: |
> > +      <&phandle type channel>
> > +      phandle : label name of controller.
> > +      type    : channel type, doorbell or data-transfer.
> > +      channel : channel number.
> > +
> > +      Here is how a client can reference them:
> > +      mboxes = <&ap2apm_mailbox DOORBELL 2>;
> > +      mboxes = <&ap2apm_mailbox DATA 3>;
> > +    const: 2
> > +
>
> Revisiting this, I think that for the ACPM interface mailbox client use
> case, it would be better to introduce a mbox property where I reference
> just the phandle to the controller:
>         mbox = <&ap2apm_mailbox>;
>
> The ACPM interface discovers the mailbox channel IDs at runtime by
> parsing SRAM. And all ACPM's channels are of type DOORBELL, thus
> specifying the type and channel in DT is redundant.
>
> It would require to extend a bit the mailbox core to provide a
> mbox_request_channel_by_args() method. I already wrote a draft and
> tested it.
>
> Do you find the idea fine?
>
Looking at v6, I prefer this version... maybe modify it a bit.

Even if you get the channel number at runtime, the type (Data vs
Doorbell) is static and needs to be passed via DT. You may have
  mbox = <&ap2apm_mailbox DOORBELL>;
and in your custom of_xlate implementation return any available
"virtual" channel. You could use 'void *data' in
exynos_mbox_send_data() to pass the h/w channel-id, instead of the
index of the virtual channel.

Thanks.


From tudor.ambarus at linaro.org  Fri Dec 20 22:45:27 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Sat, 21 Dec 2024 06:45:27 +0000
Subject: [PATCH v5 1/3] dt-bindings: mailbox: add google,gs101-mbox
In-Reply-To: <CABb+yY0rBzP8JPAik5aaXp6GivQKEf++sgiMM9fTPgd_5YXT1w@mail.gmail.com>
References: <20241217-acpm-v4-upstream-mbox-v5-0-cd1d3951fe84@linaro.org>
 <20241217-acpm-v4-upstream-mbox-v5-1-cd1d3951fe84@linaro.org>
 <ec3cdfd1-df7a-466c-8581-c9546ca6b089@linaro.org>
 <CABb+yY0rBzP8JPAik5aaXp6GivQKEf++sgiMM9fTPgd_5YXT1w@mail.gmail.com>
Message-ID: <eaab647a-f6f4-4562-89fa-e64daa80bdf4@linaro.org>

Hi, Jassi,

Thanks for the review!

On 12/21/24 2:19 AM, Jassi Brar wrote:
> On Thu, Dec 19, 2024 at 4:51?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>>
>> Hi, Krzysztof, Jassi,
>>
>> On 12/17/24 9:40 AM, Tudor Ambarus wrote:
>>
>>> diff --git a/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
>>
>> cut
>>
>>> +
>>> +  '#mbox-cells':
>>> +    description: |
>>> +      <&phandle type channel>
>>> +      phandle : label name of controller.
>>> +      type    : channel type, doorbell or data-transfer.
>>> +      channel : channel number.
>>> +
>>> +      Here is how a client can reference them:
>>> +      mboxes = <&ap2apm_mailbox DOORBELL 2>;
>>> +      mboxes = <&ap2apm_mailbox DATA 3>;
>>> +    const: 2
>>> +
>>
>> Revisiting this, I think that for the ACPM interface mailbox client use
>> case, it would be better to introduce a mbox property where I reference
>> just the phandle to the controller:
>>         mbox = <&ap2apm_mailbox>;
>>
>> The ACPM interface discovers the mailbox channel IDs at runtime by
>> parsing SRAM. And all ACPM's channels are of type DOORBELL, thus
>> specifying the type and channel in DT is redundant.
>>
>> It would require to extend a bit the mailbox core to provide a
>> mbox_request_channel_by_args() method. I already wrote a draft and
>> tested it.
>>
>> Do you find the idea fine?
>>
> Looking at v6, I prefer this version... maybe modify it a bit.

Just to summarize for the readers, in the end I chose for the
controllers to allow #mbox-cells = <0>; and for the clients to still use
the mboxes property, but just to reference the phandle to the controller:
	mboxes = <&ap2apm_mailbox>;
Then I updated the mailbox core to allow clients to request channels by
passing some args containing channel identifiers to the controllers,
that the controllers xlate() using their own method.
> 
> Even if you get the channel number at runtime, the type (Data vs
> Doorbell) is static and needs to be passed via DT. You may have
>   mbox = <&ap2apm_mailbox DOORBELL>;

The ACPM interface uses mailbox always in DOORBELL mode. If it has some
data to send, it will always send it via SRAM. Do I still need to
specify the channel type in DT?

For all the other mailbox clients than ACPM, that will reference the
same mailbox controller (same compatible if you want), I'm thinking that
we'll update the #mbox-cells to have an maxItems of 2, where they'll be
able to pass the channel ID and type via DT.

ACPM has its own dedicated mailbox controller ap2apm_mailbox, thus it uses:
	#mbox-cells = <0>;
channels IDs are from SRAM and type is always DOORBELL.

All the other mailbox controllers using the same compatible will use
	#mbox-cells = <2>;

> and in your custom of_xlate implementation return any available
> "virtual" channel. You could use 'void *data' in

Would you please extend this idea a little bit? What is a virtual channel?

In the ACPM interface mailbox client I request all the channels that are
advertised in SRAM, each mailbox channel has a 1 to 1 relation with a
h/w channel ID.

Cheers,
ta

> exynos_mbox_send_data() to pass the h/w channel-id, instead of the
> index of the virtual channel.
> 
> Thanks.


From lkp at intel.com  Sat Dec 21 00:27:12 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 16:27:12 +0800
Subject: [PATCH v6 3/5] mailbox: add support for clients to request
 channels by args
In-Reply-To: <20241220-acpm-v4-upstream-mbox-v6-3-a6942806e52a@linaro.org>
References: <20241220-acpm-v4-upstream-mbox-v6-3-a6942806e52a@linaro.org>
Message-ID: <202412211604.qPMHGnk0-lkp@intel.com>

Hi Tudor,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8]

url:    https://github.com/intel-lab-lkp/linux/commits/Tudor-Ambarus/dt-bindings-mailbox-allow-mbox-cells-0/20241220-215938
base:   78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
patch link:    https://lore.kernel.org/r/20241220-acpm-v4-upstream-mbox-v6-3-a6942806e52a%40linaro.org
patch subject: [PATCH v6 3/5] mailbox: add support for clients to request channels by args
config: x86_64-buildonly-randconfig-001-20241221 (https://download.01.org/0day-ci/archive/20241221/202412211604.qPMHGnk0-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/20241221/202412211604.qPMHGnk0-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/202412211604.qPMHGnk0-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/mailbox/mailbox.c:486: warning: Function parameter or struct member 'mbox_spec' not described in 'mbox_request_channel_by_args'
>> drivers/mailbox/mailbox.c:486: warning: Excess function parameter 'spec' description in 'mbox_request_channel_by_args'


vim +486 drivers/mailbox/mailbox.c

   469	
   470	/**
   471	 * mbox_request_channel_by_args - request a mailbox channel using client's
   472	 * channel identifiers.
   473	 * @cl: identity of the client requesting the channel.
   474	 * @index: index of mailbox specifier in 'mboxes' property.
   475	 * @spec: arguments that describe the channel.
   476	 *
   477	 * Used by clients that can discover the channel identifiers at runtime (by
   478	 * parsing a shared memory for example). The description of
   479	 * mbox_request_channel() applies here as well.
   480	 *
   481	 * Return: Pointer to the channel assigned to the client if successful.
   482	 *         ERR_PTR for request failure.
   483	 */
   484	struct mbox_chan *mbox_request_channel_by_args(struct mbox_client *cl,
   485				int index, const struct mbox_xlate_args *mbox_spec)
 > 486	{
   487		struct of_phandle_args of_args;
   488		struct device *dev = cl->dev;
   489		struct mbox_controller *mbox;
   490		struct mbox_chan *chan;
   491		int ret;
   492	
   493		if (!dev || !dev->of_node) {
   494			pr_debug("%s: No owner device node\n", __func__);
   495			return ERR_PTR(-ENODEV);
   496		}
   497	
   498		if (of_parse_phandle_with_args(dev->of_node, "mboxes",
   499					       "#mbox-cells", index, &of_args)) {
   500			dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__);
   501			return ERR_PTR(-ENODEV);
   502		}
   503	
   504		mutex_lock(&con_mutex);
   505	
   506		chan = ERR_PTR(-EPROBE_DEFER);
   507		list_for_each_entry(mbox, &mbox_cons, node)
   508			if (mbox->dev->of_node == of_args.np && mbox->xlate) {
   509				chan = mbox->xlate(mbox, mbox_spec);
   510				if (!IS_ERR(chan))
   511					break;
   512			}
   513	
   514		of_node_put(of_args.np);
   515	
   516		if (IS_ERR(chan)) {
   517			mutex_unlock(&con_mutex);
   518			return chan;
   519		}
   520	
   521		ret = __mbox_bind_client(chan, cl);
   522		if (ret)
   523			chan = ERR_PTR(ret);
   524	
   525		mutex_unlock(&con_mutex);
   526		return chan;
   527	}
   528	EXPORT_SYMBOL_GPL(mbox_request_channel_by_args);
   529	

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


From lkp at intel.com  Sat Dec 21 00:43:21 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 16:43:21 +0800
Subject: [soc:stm32/dt] BUILD SUCCESS
 8df9bff2788973e16263ca86df7574d527c84405
Message-ID: <202412211614.6WYu3H2H-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git stm32/dt
branch HEAD: 8df9bff2788973e16263ca86df7574d527c84405  arm64: dts: st: enable imx335/csi/dcmipp pipeline on stm32mp257f-ev1

elapsed time: 1449m

configs tested: 206
configs skipped: 5

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

tested configs:
alpha                             allnoconfig    gcc-14.2.0
alpha                            allyesconfig    clang-20
alpha                               defconfig    gcc-14.2.0
arc                              allmodconfig    clang-18
arc                               allnoconfig    gcc-14.2.0
arc                              allyesconfig    clang-18
arc                                 defconfig    gcc-14.2.0
arc                   randconfig-001-20241221    gcc-13.2.0
arc                   randconfig-002-20241221    gcc-13.2.0
arm                              allmodconfig    clang-18
arm                               allnoconfig    gcc-14.2.0
arm                              allyesconfig    clang-18
arm                                 defconfig    gcc-14.2.0
arm                   randconfig-001-20241221    gcc-13.2.0
arm                   randconfig-001-20241221    gcc-14.2.0
arm                   randconfig-002-20241221    gcc-13.2.0
arm                   randconfig-002-20241221    gcc-14.2.0
arm                   randconfig-003-20241221    gcc-13.2.0
arm                   randconfig-003-20241221    gcc-14.2.0
arm                   randconfig-004-20241221    clang-18
arm                   randconfig-004-20241221    gcc-13.2.0
arm64                            allmodconfig    clang-18
arm64                             allnoconfig    gcc-14.2.0
arm64                               defconfig    gcc-14.2.0
arm64                 randconfig-001-20241221    clang-18
arm64                 randconfig-001-20241221    gcc-13.2.0
arm64                 randconfig-002-20241221    clang-16
arm64                 randconfig-002-20241221    gcc-13.2.0
arm64                 randconfig-003-20241221    clang-20
arm64                 randconfig-003-20241221    gcc-13.2.0
arm64                 randconfig-004-20241221    gcc-13.2.0
arm64                 randconfig-004-20241221    gcc-14.2.0
csky                             alldefconfig    gcc-14.2.0
csky                              allnoconfig    gcc-14.2.0
csky                                defconfig    gcc-14.2.0
csky                  randconfig-001-20241221    gcc-14.2.0
csky                  randconfig-002-20241221    gcc-14.2.0
hexagon                          allmodconfig    clang-20
hexagon                           allnoconfig    gcc-14.2.0
hexagon                          allyesconfig    clang-20
hexagon                             defconfig    gcc-14.2.0
hexagon               randconfig-001-20241221    gcc-14.2.0
hexagon               randconfig-002-20241221    clang-20
hexagon               randconfig-002-20241221    gcc-14.2.0
i386                             allmodconfig    clang-19
i386                             allmodconfig    gcc-12
i386                              allnoconfig    clang-19
i386                              allnoconfig    gcc-12
i386                             allyesconfig    clang-19
i386                             allyesconfig    gcc-12
i386        buildonly-randconfig-001-20241221    clang-19
i386        buildonly-randconfig-001-20241221    gcc-12
i386        buildonly-randconfig-002-20241221    clang-19
i386        buildonly-randconfig-002-20241221    gcc-12
i386        buildonly-randconfig-003-20241221    clang-19
i386        buildonly-randconfig-004-20241221    clang-19
i386        buildonly-randconfig-005-20241221    clang-19
i386        buildonly-randconfig-006-20241221    clang-19
i386                                defconfig    clang-19
i386                  randconfig-001-20241221    gcc-12
i386                  randconfig-002-20241221    gcc-12
i386                  randconfig-003-20241221    gcc-12
i386                  randconfig-004-20241221    gcc-12
i386                  randconfig-005-20241221    gcc-12
i386                  randconfig-006-20241221    gcc-12
i386                  randconfig-007-20241221    gcc-12
i386                  randconfig-011-20241221    gcc-12
i386                  randconfig-012-20241221    gcc-12
i386                  randconfig-013-20241221    gcc-12
i386                  randconfig-014-20241221    gcc-12
i386                  randconfig-015-20241221    gcc-12
i386                  randconfig-016-20241221    gcc-12
i386                  randconfig-017-20241221    gcc-12
loongarch                         allnoconfig    gcc-14.2.0
loongarch                           defconfig    gcc-14.2.0
loongarch             randconfig-001-20241221    gcc-14.2.0
loongarch             randconfig-002-20241221    gcc-14.2.0
m68k                             alldefconfig    clang-15
m68k                              allnoconfig    gcc-14.2.0
m68k                                defconfig    gcc-14.2.0
microblaze                        allnoconfig    gcc-14.2.0
microblaze                          defconfig    gcc-14.2.0
microblaze                      mmu_defconfig    clang-15
mips                              allnoconfig    gcc-14.2.0
nios2                             allnoconfig    gcc-14.2.0
nios2                               defconfig    gcc-14.2.0
nios2                 randconfig-001-20241221    gcc-14.2.0
nios2                 randconfig-002-20241221    gcc-14.2.0
openrisc                          allnoconfig    clang-20
openrisc                         allyesconfig    gcc-14.2.0
openrisc                            defconfig    gcc-12
parisc                           allmodconfig    gcc-14.2.0
parisc                            allnoconfig    clang-20
parisc                           allyesconfig    gcc-14.2.0
parisc                              defconfig    gcc-12
parisc                randconfig-001-20241221    gcc-14.2.0
parisc                randconfig-002-20241221    gcc-14.2.0
parisc64                            defconfig    gcc-14.2.0
powerpc                          allmodconfig    gcc-14.2.0
powerpc                           allnoconfig    clang-20
powerpc                          allyesconfig    clang-16
powerpc                          allyesconfig    gcc-14.2.0
powerpc                      arches_defconfig    clang-15
powerpc                      katmai_defconfig    gcc-14.2.0
powerpc                   lite5200b_defconfig    gcc-14.2.0
powerpc                 mpc8315_rdb_defconfig    gcc-14.2.0
powerpc                      pcm030_defconfig    clang-15
powerpc                     ppa8548_defconfig    gcc-14.2.0
powerpc               randconfig-001-20241221    gcc-14.2.0
powerpc               randconfig-002-20241221    gcc-14.2.0
powerpc               randconfig-003-20241221    gcc-14.2.0
powerpc64             randconfig-001-20241221    gcc-14.2.0
powerpc64             randconfig-002-20241221    gcc-14.2.0
powerpc64             randconfig-003-20241221    clang-18
powerpc64             randconfig-003-20241221    gcc-14.2.0
riscv                            allmodconfig    clang-20
riscv                            allmodconfig    gcc-14.2.0
riscv                             allnoconfig    clang-20
riscv                            allyesconfig    clang-20
riscv                            allyesconfig    gcc-14.2.0
riscv                               defconfig    gcc-12
riscv                    nommu_k210_defconfig    clang-15
riscv                 randconfig-001-20241221    clang-18
riscv                 randconfig-001-20241221    gcc-14.2.0
riscv                 randconfig-002-20241221    clang-18
riscv                 randconfig-002-20241221    gcc-14.2.0
s390                             allmodconfig    clang-19
s390                             allmodconfig    gcc-14.2.0
s390                              allnoconfig    clang-20
s390                             allyesconfig    gcc-14.2.0
s390                                defconfig    gcc-12
s390                  randconfig-001-20241221    clang-18
s390                  randconfig-001-20241221    gcc-14.2.0
s390                  randconfig-002-20241221    clang-18
s390                  randconfig-002-20241221    gcc-14.2.0
sh                               allmodconfig    gcc-14.2.0
sh                                allnoconfig    gcc-14.2.0
sh                               allyesconfig    gcc-14.2.0
sh                         apsh4a3a_defconfig    gcc-14.2.0
sh                                  defconfig    gcc-12
sh                ecovec24-romimage_defconfig    clang-15
sh                    randconfig-001-20241221    clang-18
sh                    randconfig-001-20241221    gcc-14.2.0
sh                    randconfig-002-20241221    clang-18
sh                    randconfig-002-20241221    gcc-14.2.0
sh                   secureedge5410_defconfig    clang-15
sh                   sh7724_generic_defconfig    clang-15
sh                   sh7724_generic_defconfig    gcc-14.2.0
sparc                            allmodconfig    gcc-14.2.0
sparc                             allnoconfig    gcc-14.2.0
sparc                 randconfig-001-20241221    clang-18
sparc                 randconfig-001-20241221    gcc-14.2.0
sparc                 randconfig-002-20241221    clang-18
sparc                 randconfig-002-20241221    gcc-14.2.0
sparc64                             defconfig    gcc-12
sparc64               randconfig-001-20241221    clang-18
sparc64               randconfig-001-20241221    gcc-14.2.0
sparc64               randconfig-002-20241221    clang-18
sparc64               randconfig-002-20241221    gcc-14.2.0
um                               allmodconfig    clang-20
um                                allnoconfig    clang-20
um                               allyesconfig    clang-20
um                                  defconfig    gcc-12
um                             i386_defconfig    gcc-12
um                    randconfig-001-20241221    clang-18
um                    randconfig-002-20241221    clang-18
um                    randconfig-002-20241221    gcc-12
um                           x86_64_defconfig    gcc-12
x86_64                            allnoconfig    clang-19
x86_64                           allyesconfig    clang-19
x86_64      buildonly-randconfig-001-20241221    gcc-12
x86_64      buildonly-randconfig-002-20241221    gcc-12
x86_64      buildonly-randconfig-003-20241221    gcc-12
x86_64      buildonly-randconfig-004-20241221    gcc-12
x86_64      buildonly-randconfig-005-20241221    gcc-11
x86_64      buildonly-randconfig-005-20241221    gcc-12
x86_64      buildonly-randconfig-006-20241221    gcc-12
x86_64                              defconfig    clang-19
x86_64                              defconfig    gcc-11
x86_64                                  kexec    clang-19
x86_64                randconfig-001-20241221    gcc-11
x86_64                randconfig-002-20241221    gcc-11
x86_64                randconfig-003-20241221    gcc-11
x86_64                randconfig-004-20241221    gcc-11
x86_64                randconfig-005-20241221    gcc-11
x86_64                randconfig-006-20241221    gcc-11
x86_64                randconfig-007-20241221    gcc-11
x86_64                randconfig-008-20241221    gcc-11
x86_64                randconfig-071-20241221    gcc-12
x86_64                randconfig-072-20241221    gcc-12
x86_64                randconfig-073-20241221    gcc-12
x86_64                randconfig-074-20241221    gcc-12
x86_64                randconfig-075-20241221    gcc-12
x86_64                randconfig-076-20241221    gcc-12
x86_64                randconfig-077-20241221    gcc-12
x86_64                randconfig-078-20241221    gcc-12
x86_64                               rhel-9.4    clang-19
x86_64                           rhel-9.4-bpf    clang-19
x86_64                         rhel-9.4-kunit    clang-19
x86_64                           rhel-9.4-ltp    clang-19
x86_64                          rhel-9.4-rust    clang-19
xtensa                            allnoconfig    gcc-14.2.0
xtensa                randconfig-001-20241221    clang-18
xtensa                randconfig-001-20241221    gcc-14.2.0
xtensa                randconfig-002-20241221    clang-18
xtensa                randconfig-002-20241221    gcc-14.2.0

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


From lkp at intel.com  Sat Dec 21 01:20:49 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 17:20:49 +0800
Subject: [soc:soc/defconfig] BUILD SUCCESS
 2981c62fb6542cf84e5e5eabb40949cd2d038603
Message-ID: <202412211743.OCKTDFBl-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/defconfig
branch HEAD: 2981c62fb6542cf84e5e5eabb40949cd2d038603  Merge tag 'renesas-arm-defconfig-for-v6.14-tag1' of https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/defconfig

elapsed time: 908m

configs tested: 11
configs skipped: 114

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

tested configs:
arm               allmodconfig    gcc-14.2.0
arm               allyesconfig    gcc-14.2.0
arm    randconfig-001-20241221    gcc-14.2.0
arm    randconfig-002-20241221    gcc-14.2.0
arm    randconfig-003-20241221    gcc-14.2.0
arm    randconfig-004-20241221    clang-18
arm64             allmodconfig    clang-18
arm64  randconfig-001-20241221    clang-18
arm64  randconfig-002-20241221    clang-16
arm64  randconfig-003-20241221    clang-20
arm64  randconfig-004-20241221    gcc-14.2.0

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


From ryan at testtoast.com  Sat Dec 21 01:26:31 2024
From: ryan at testtoast.com (Ryan Walklin)
Date: Sat, 21 Dec 2024 22:26:31 +1300
Subject: [PATCH 0/3] ASoC: sun4i-codec: add headphone dectection for Anbernic RG35XX devices
Message-ID: <20241221094122.27325-1-ryan@testtoast.com>

Add support for headphone detection on the Anbernic RG35XX series. 

This series adds the required device tree bindings to describe GPIOs for jack detection in the sun4i-codec driver, adds support for jack detection to the codec machine driver, and describes the hardware configuration in the RG35XX DTS. The existing speaker amplifier GPIO pin can then be used in concert with jack detection to enable userspace sound servers (via an ALSA UCM configuration) to disable the speaker route when headphones are connected.

Thanks to Chris Morgan for his assistance putting this series together.

Regards,

Ryan

Chris Morgan (3):
  ASoC: dt-bindings: sun4i-a10-codec: add hp-det-gpios
  ASoC: sun4i-codec: support hp-det-gpios property
  arm64: dts: allwinner: h700: Add hp-det-gpios for Anbernic RG35XX

 .../sound/allwinner,sun4i-a10-codec.yaml      |  6 ++
 .../sun50i-h700-anbernic-rg35xx-2024.dts      |  5 +-
 sound/soc/sunxi/sun4i-codec.c                 | 59 ++++++++++++++++++-
 3 files changed, 67 insertions(+), 3 deletions(-)

-- 
2.47.1



From ryan at testtoast.com  Sat Dec 21 01:26:32 2024
From: ryan at testtoast.com (Ryan Walklin)
Date: Sat, 21 Dec 2024 22:26:32 +1300
Subject: [PATCH 1/3] ASoC: dt-bindings: sun4i-a10-codec: add hp-det-gpios
In-Reply-To: <20241221094122.27325-1-ryan@testtoast.com>
References: <20241221094122.27325-1-ryan@testtoast.com>
Message-ID: <20241221094122.27325-2-ryan@testtoast.com>

From: Chris Morgan <macromorgan at hotmail.com>

Devices integrating Allwinner SoCs may use line-out or headphone jacks
with jack detection circuits attached to a GPIO. Support defining these
in DTs.

A number of Anbernic devices featuring the H700 SoC use this mechanism
to switch between a headphone jack and an internal speaker, so add these
to the allowed routing items.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Ryan Walklin <ryan at testtoast.com>
---
 .../bindings/sound/allwinner,sun4i-a10-codec.yaml           | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
index ebc9097f936ad..b4b711e80b65a 100644
--- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
@@ -98,6 +98,10 @@ properties:
     maxItems: 1
     description: GPIO to enable the external amplifier
 
+  allwinner,hp-det-gpios:
+    maxItems: 1
+    description: GPIO for headphone/line-out detection
+
 required:
   - "#sound-dai-cells"
   - compatible
@@ -247,8 +251,10 @@ allOf:
         allwinner,audio-routing:
           items:
             enum:
+              - Headphone
               - LINEOUT
               - Line Out
+              - Speaker
 
         dmas:
           items:
-- 
2.47.1



From ryan at testtoast.com  Sat Dec 21 01:26:33 2024
From: ryan at testtoast.com (Ryan Walklin)
Date: Sat, 21 Dec 2024 22:26:33 +1300
Subject: [PATCH 2/3] ASoC: sun4i-codec: support hp-det-gpios property
In-Reply-To: <20241221094122.27325-1-ryan@testtoast.com>
References: <20241221094122.27325-1-ryan@testtoast.com>
Message-ID: <20241221094122.27325-3-ryan@testtoast.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for GPIO headphone detection with the hp-det-gpios
property. In order for this to properly disable the path upon
removal of headphones, the output must be labelled Headphone which
is a common sink in the driver. Note this patch also adds the output
of Headphone for the H616 codec.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Ryan Walklin <ryan at testtoast.com>
---
 sound/soc/sunxi/sun4i-codec.c | 59 +++++++++++++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 933a0913237c8..5f718dd3fcf0a 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -21,6 +21,7 @@
 #include <linux/gpio/consumer.h>
 
 #include <sound/core.h>
+#include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -272,6 +273,7 @@ struct sun4i_codec {
 	struct clk	*clk_module;
 	struct reset_control *rst;
 	struct gpio_desc *gpio_pa;
+	struct gpio_desc *gpio_hp;
 
 	/* ADC_FIFOC register is at different offset on different SoCs */
 	struct regmap_field *reg_adc_fifoc;
@@ -1302,6 +1304,49 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
 	.ops = &dummy_dai_ops,
 };
 
+static struct snd_soc_jack sun4i_headphone_jack;
+
+static struct snd_soc_jack_pin sun4i_headphone_jack_pins[] = {
+	{ .pin = "Headphone", .mask = SND_JACK_HEADPHONE},
+};
+
+static struct snd_soc_jack_gpio sun4i_headphone_jack_gpio = {
+	.name = "hp-det",
+	.report = SND_JACK_HEADPHONE,
+	.debounce_time = 150,
+};
+
+static int sun4i_codec_machine_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_card *card = rtd->card;
+	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
+	int ret;
+
+	if (scodec->gpio_hp) {
+		ret = snd_soc_card_jack_new_pins(card, "Headphone Jack",
+						 SND_JACK_HEADPHONE,
+						 &sun4i_headphone_jack,
+						 sun4i_headphone_jack_pins,
+						 ARRAY_SIZE(sun4i_headphone_jack_pins));
+		if (ret) {
+			dev_err(rtd->dev,
+			        "Headphone jack creation failed: %d\n", ret);
+			return ret;
+		}
+
+		sun4i_headphone_jack_gpio.desc = scodec->gpio_hp;
+		ret = snd_soc_jack_add_gpios(&sun4i_headphone_jack, 1,
+					     &sun4i_headphone_jack_gpio);
+
+		if (ret) {
+			dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
 							int *num_links)
 {
@@ -1327,6 +1372,7 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
 	link->codecs->name	= dev_name(dev);
 	link->platforms->name	= dev_name(dev);
 	link->dai_fmt		= SND_SOC_DAIFMT_I2S;
+	link->init		= sun4i_codec_machine_init;
 
 	*num_links = 1;
 
@@ -1635,10 +1681,11 @@ static const struct snd_soc_component_driver sun50i_h616_codec_codec = {
 };
 
 static const struct snd_kcontrol_new sun50i_h616_card_controls[] = {
-	SOC_DAPM_PIN_SWITCH("LINEOUT"),
+	SOC_DAPM_PIN_SWITCH("Speaker"),
 };
 
 static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = {
+	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_LINE("Line Out", NULL),
 	SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
 };
@@ -1684,7 +1731,7 @@ static struct snd_soc_card *sun50i_h616_codec_create_card(struct device *dev)
 
 	card->dev		= dev;
 	card->owner		= THIS_MODULE;
-	card->name		= "H616 Audio Codec";
+	card->name		= "h616-audio-codec";
 	card->driver_name	= "sun4i-codec";
 	card->controls		= sun50i_h616_card_controls;
 	card->num_controls	= ARRAY_SIZE(sun50i_h616_card_controls);
@@ -1940,6 +1987,14 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "allwinner,hp-det",
+	                                          GPIOD_IN);
+	if (IS_ERR(scodec->gpio_hp)) {
+		ret = PTR_ERR(scodec->gpio_hp);
+		dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n");
+		return ret;
+	}
+
 	/* reg_field setup */
 	scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
 							scodec->regmap,
-- 
2.47.1



From lkp at intel.com  Sat Dec 21 01:40:18 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 17:40:18 +0800
Subject: [PATCH v4 5/6] optee: FF-A: dynamic restricted memory allocation
In-Reply-To: <20241217100809.3962439-6-jens.wiklander@linaro.org>
References: <20241217100809.3962439-6-jens.wiklander@linaro.org>
Message-ID: <202412211952.LOCC8Lbo-lkp@intel.com>

Hi Jens,

kernel test robot noticed the following build errors:

[auto build test ERROR on fac04efc5c793dccbd07e2d59af9f90b7fc0dca4]

url:    https://github.com/intel-lab-lkp/linux/commits/Jens-Wiklander/tee-add-restricted-memory-allocation/20241217-181101
base:   fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
patch link:    https://lore.kernel.org/r/20241217100809.3962439-6-jens.wiklander%40linaro.org
patch subject: [PATCH v4 5/6] optee: FF-A: dynamic restricted memory allocation
config: arm64-randconfig-r112-20241221 (https://download.01.org/0day-ci/archive/20241221/202412211952.LOCC8Lbo-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce: (https://download.01.org/0day-ci/archive/20241221/202412211952.LOCC8Lbo-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/202412211952.LOCC8Lbo-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/tee/optee/rstmem.c:311:67: error: expected ';', ',' or ')' before '__unused'
     311 | static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee __unused,
         |                                                                   ^~~~~~~~
   drivers/tee/optee/rstmem.c: In function 'optee_rstmem_alloc':
>> drivers/tee/optee/rstmem.c:332:24: error: implicit declaration of function 'alloc_rstmem_pool' [-Wimplicit-function-declaration]
     332 |                 pool = alloc_rstmem_pool(optee, use_case);
         |                        ^~~~~~~~~~~~~~~~~
>> drivers/tee/optee/rstmem.c:332:22: error: assignment to 'struct tee_shm_pool *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     332 |                 pool = alloc_rstmem_pool(optee, use_case);
         |                      ^


vim +311 drivers/tee/optee/rstmem.c

   268	
   269	static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee, u32 use_case)
   270	{
   271		struct optee_rstmem_cma_pool *rp;
   272		size_t min_size;
   273		int rc;
   274	
   275		rp = kzalloc(sizeof(*rp), GFP_KERNEL);
   276		if (!rp)
   277			return ERR_PTR(-ENOMEM);
   278		rp->rstmem.use_case = use_case;
   279	
   280		rc = get_rstmem_config(optee, use_case, &min_size, &rp->align, NULL,
   281				       &rp->end_point_count);
   282		if (rc) {
   283			if (rc != -ENOSPC)
   284				goto err;
   285			rp->end_points = kcalloc(rp->end_point_count,
   286						 sizeof(*rp->end_points), GFP_KERNEL);
   287			if (!rp->end_points) {
   288				rc = -ENOMEM;
   289				goto err;
   290			}
   291			rc = get_rstmem_config(optee, use_case, &min_size, &rp->align,
   292					       rp->end_points, &rp->end_point_count);
   293			if (rc)
   294				goto err_kfree_eps;
   295		}
   296	
   297		rp->pool.ops = &rstmem_pool_ops_cma;
   298		rp->optee = optee;
   299		rp->page_count = min_size / PAGE_SIZE;
   300		mutex_init(&rp->mutex);
   301	
   302		return &rp->pool;
   303	
   304	err_kfree_eps:
   305		kfree(rp->end_points);
   306	err:
   307		kfree(rp);
   308		return ERR_PTR(rc);
   309	}
   310	#else /*CONFIG_CMA*/
 > 311	static struct tee_shm_pool *alloc_rstmem_pool(struct optee *optee __unused,
   312						      u32 use_case __unused)
   313	{
   314		return ERR_PTR(-EINVAL);
   315	}
   316	#endif /*CONFIG_CMA*/
   317	
   318	int optee_rstmem_alloc(struct tee_context *ctx, struct tee_shm *shm,
   319			       u32 flags, u32 use_case, size_t size)
   320	{
   321		struct optee *optee = tee_get_drvdata(ctx->teedev);
   322		struct tee_shm_pool *pool;
   323		int rc;
   324	
   325		if (!optee->rstmem_pools)
   326			return -EINVAL;
   327		if (flags)
   328			return -EINVAL;
   329	
   330		pool = xa_load(&optee->rstmem_pools->xa, use_case);
   331		if (!pool) {
 > 332			pool = alloc_rstmem_pool(optee, use_case);
   333			if (IS_ERR(pool))
   334				return PTR_ERR(pool);
   335			rc = xa_insert(&optee->rstmem_pools->xa, use_case, pool,
   336				       GFP_KERNEL);
   337			if (rc) {
   338				pool->ops->destroy_pool(pool);
   339				return rc;
   340			}
   341		}
   342	
   343		return pool->ops->alloc(pool, shm, size, 0);
   344	}
   345	

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


From ryan at testtoast.com  Sat Dec 21 01:26:34 2024
From: ryan at testtoast.com (Ryan Walklin)
Date: Sat, 21 Dec 2024 22:26:34 +1300
Subject: [PATCH 3/3] arm64: dts: allwinner: h700: Add hp-det-gpios for Anbernic RG35XX
In-Reply-To: <20241221094122.27325-1-ryan@testtoast.com>
References: <20241221094122.27325-1-ryan@testtoast.com>
Message-ID: <20241221094122.27325-4-ryan@testtoast.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for headphone insertion detection via GPIO for the
RG35XX series.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Ryan Walklin <macromorgan at hotmail.com>
---
 .../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts  | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
index 89de86b442155..cbab10de760c9 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
@@ -238,8 +238,11 @@ panel_in_rgb: endpoint {
 };
 
 &codec {
-	allwinner,audio-routing = "Line Out", "LINEOUT";
+	/* Both speakers and headphone jack connected to 74HC4052D analog mux*/
+	allwinner,audio-routing = "Speaker", "LINEOUT", 
+				  "Headphone", "LINEOUT";
 	allwinner,pa-gpios = <&pio 8 5 GPIO_ACTIVE_HIGH>; // PI5
+	allwinner,hp-det-gpios = <&pio 8 3 GPIO_ACTIVE_HIGH>; // PI3
 	status = "okay";
 };
 
-- 
2.47.1



From maz at kernel.org  Sat Dec 21 01:57:44 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 21 Dec 2024 09:57:44 +0000
Subject: [PATCH v2 01/12] KVM: arm64: nv: Add handling of EL2-specific timer registers
In-Reply-To: <Z2Yb8BWnqpt441V-@linux.dev>
References: <20241217142321.763801-1-maz@kernel.org>
	<20241217142321.763801-2-maz@kernel.org>
	<Z2Yb8BWnqpt441V-@linux.dev>
Message-ID: <874j2xs6hz.wl-maz@kernel.org>

On Sat, 21 Dec 2024 01:38:28 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Tue, Dec 17, 2024 at 02:23:09PM +0000, Marc Zyngier wrote:
> > @@ -3879,9 +4020,11 @@ static const struct sys_reg_desc cp15_64_regs[] = {
> >  	{ SYS_DESC(SYS_AARCH32_CNTPCT),	      access_arch_timer },
> >  	{ Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, TTBR1_EL1 },
> >  	{ Op1( 1), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_ASGI1R */
> > +	{ SYS_DESC(SYS_AARCH32_CNTVCT),	      access_arch_timer },
> >  	{ Op1( 2), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI0R */
> >  	{ SYS_DESC(SYS_AARCH32_CNTP_CVAL),    access_arch_timer },
> >  	{ SYS_DESC(SYS_AARCH32_CNTPCTSS),     access_arch_timer },
> > +	{ SYS_DESC(SYS_AARCH32_CNTVCTSS),     access_arch_timer },
> >  };
> 
> Huh. You know, I had always thought we hid 32-bit EL0 from nested
> guests, but I now realize that isn't the case. Of course, we don't have
> the necessary trap reflection for exits that came out of a 32-bit EL0,
> nor should we bother.
> 
> Of the 4 NV2 implementations I'm aware of (Neoverse-V1, Neoverse-V2,
> AmpereOne, M2) only Neoverse-V1 supports 32-bit userspace. And even
> then, a lot of deployments of V1 have a broken NV2 implementation.
> 
> What do you think about advertising a 64-bit only EL0 for nested VMs?

I'm completely OK with that.

Actually, we already nuke the guest if exiting from 32bit context, no
matter the EL (vcpu_mode_is_bad_32bit() is where this happens).  But
we're missing the ID_AA64PFR0_EL1.EL0 sanitising, which is a bug. I'll
send a patch shortly.

Now, for this particular patch, I still think we should gracefully
handle access to the EL1 timer from a 32bit capable, non-NV guest.
Just in case we end-up with a CPU with a broken CNTVOFF_EL2 *and*
32bit capability.

In the end, it doesn't cost us much to support this case, and it helps
that we can verify that we handle all registers without exception.

Thoughts?

	M.

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


From maz at kernel.org  Sat Dec 21 02:11:37 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 21 Dec 2024 10:11:37 +0000
Subject: [PATCH] KVM: arm64: nv: Advertise the lack of AArch32 EL0 support
Message-ID: <20241221101137.1405271-1-maz@kernel.org>

Although we never supported 32bit anywhere in NV, we fail to
advertise so for EL0, probably owing to the relative lack of
hardware supporting both NV2 and 32bit EL0.

Add some sanitising to ID_AA64PFR0_EL1.EL0, and reaffirm that
"in 64bit-only we trust".

Reported-by: Oliver Upton <oliver.upton at linux.dev>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/nested.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 9b36218b48def..9e74f7b38e056 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -830,8 +830,10 @@ static void limit_nv_id_regs(struct kvm *kvm)
 		 NV_FTR(PFR0, RAS)	|
 		 NV_FTR(PFR0, EL3)	|
 		 NV_FTR(PFR0, EL2)	|
-		 NV_FTR(PFR0, EL1));
-	/* 64bit EL1/EL2/EL3 only */
+		 NV_FTR(PFR0, EL1)	|
+		 NV_FTR(PFR0, EL0));
+	/* 64bit only at any EL */
+	val |= FIELD_PREP(NV_FTR(PFR0, EL0), 0b0001);
 	val |= FIELD_PREP(NV_FTR(PFR0, EL1), 0b0001);
 	val |= FIELD_PREP(NV_FTR(PFR0, EL2), 0b0001);
 	val |= FIELD_PREP(NV_FTR(PFR0, EL3), 0b0001);
-- 
2.39.2



From andyshrk at 163.com  Sat Dec 21 02:49:07 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sat, 21 Dec 2024 18:49:07 +0800
Subject: [PATCH] arm64: dts: rockchip: aliase sdhci as mmc0 for rk3566 box demo
Message-ID: <20241221104920.4193034-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

Follow most others rk356x based boards, and u-boot only use mmc0/1
as mmc boot targets, so aliase sdhci as mmc0.

Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---

 arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts b/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
index 41b4cd5a4220..7d0eedf1bd0d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
@@ -19,9 +19,9 @@ / {
 
 	aliases {
 		ethernet0 = &gmac1;
-		mmc0 = &sdmmc0;
-		mmc1 = &sdmmc1;
-		mmc2 = &sdhci;
+		mmc0 = &sdhci;
+		mmc1 = &sdmmc0;
+		mmc2 = &sdmmc1;
 	};
 
 	chosen: chosen {
-- 
2.34.1



From lkp at intel.com  Sat Dec 21 03:03:27 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Dec 2024 19:03:27 +0800
Subject: [PATCH 1/2] memory/mediatek: Add an interface to get current DDR
 data rate
In-Reply-To: <20241212090029.13692-2-crystal.guo@mediatek.com>
References: <20241212090029.13692-2-crystal.guo@mediatek.com>
Message-ID: <202412211805.ulwSEmZa-lkp@intel.com>

Hi Crystal,

kernel test robot noticed the following build errors:

[auto build test ERROR on krzk-mem-ctrl/for-next]
[also build test ERROR on robh/for-next krzk-dt/for-next linus/master v6.13-rc3 next-20241220]
[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/Crystal-Guo/memory-mediatek-Add-an-interface-to-get-current-DDR-data-rate/20241212-170306
base:   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git for-next
patch link:    https://lore.kernel.org/r/20241212090029.13692-2-crystal.guo%40mediatek.com
patch subject: [PATCH 1/2] memory/mediatek: Add an interface to get current DDR data rate
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20241221/202412211805.ulwSEmZa-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 9daf10ff8f29ba3a88a105aaa9d2379c21b77d35)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241221/202412211805.ulwSEmZa-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/202412211805.ulwSEmZa-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/memory/mediatek/mtk-dramc.c:300:12: error: incompatible function pointer types initializing 'void (*)(struct platform_device *)' with an expression of type 'int (struct platform_device *)' [-Wincompatible-function-pointer-types]
     300 |         .remove = dramc_remove,
         |                   ^~~~~~~~~~~~
   1 error generated.


vim +300 drivers/memory/mediatek/mtk-dramc.c

   297	
   298	static struct platform_driver dramc_drv = {
   299		.probe = dramc_probe,
 > 300		.remove = dramc_remove,
   301		.driver = {
   302			.name = "dramc_drv",
   303			.owner = THIS_MODULE,
   304			.of_match_table = dramc_of_ids,
   305		},
   306	};
   307	

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


From jbrunet at baylibre.com  Sat Dec 21 03:09:28 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Sat, 21 Dec 2024 12:09:28 +0100
Subject: [PATCH 2/3] clk: amlogic: drop clk_regmap tables
In-Reply-To: <9f1d69ebe1ddce5dfc170e986c9213f2.sboyd@kernel.org> (Stephen
	Boyd's message of "Fri, 20 Dec 2024 16:12:03 -0800")
References: <20241220-amlogic-clk-drop-clk-regmap-tables-v1-0-96dd657cbfbd@baylibre.com>
	<20241220-amlogic-clk-drop-clk-regmap-tables-v1-2-96dd657cbfbd@baylibre.com>
	<9f1d69ebe1ddce5dfc170e986c9213f2.sboyd@kernel.org>
Message-ID: <1ja5cp8f87.fsf@starbuckisacylon.baylibre.com>

On Fri 20 Dec 2024 at 16:12, Stephen Boyd <sboyd at kernel.org> wrote:

> Quoting Jerome Brunet (2024-12-20 09:17:43)
>> Remove the big clk_regmap tables that are used to populate the regmap
>> field of clk_regmap clocks at runtime. Instead of using tables, use devres
>> to allow the clocks to get the necessary regmap.
>> 
>> A simpler solution would have been to use dev_get_regmap() but this would
>> not work with syscon based controllers.
>
> Why not have two init functions, one that uses the syscon approach from
> the parent device?

That would duplicate all the ops and would not scale if anything else
comes along. It would also tie the controller quirks with
clock ops. I would like to keep to clock ops and controllers decoupled as
much as possible

> Is the typical path to not use a syscon anyway?
>

I sure hope there will be no new syscon based controller but, ATM, around
50% are syscon based in drivers/clk/meson. Those are here to stay and I
doubt we can do anything about it.

>> 
>> This rework save a bit memory and the result is less of a maintenance
>> burden.
>> 
>> Unfortunately meson8b is left out for now since it is an early clock
>> driver that does not have proper device support for now.
>
> We should add a clk_hw_get_of_node() function that returns
> hw->core->of_node. Then there can be a similar function that looks at
> the of_node of a clk registered with of_clk_hw_register() and tries to
> find the regmap either with
> syscon_node_to_regmap(clk_hw_get_of_node(hw)) or on the parent of the
> node for the clk.

That's the thing. It means encoding the controller quirk of how to get
regmap in the clock ops. I would be prefer to avoid that.

With what you are suggesting I could make an ops that
* Try dev_get_regmap() first
* Try the syscon/of_node way next

I can make this "trial an error" approach work but I think it is pretty
nasty and encode controller stuff inside the clock driver.

>
> TL;DR: Don't use devres.

Using it makes thing nice and tidy. clk_regmap does not care were regmap
comes from. It just picks it up where it has been prepared

That approach could be extended to support controller with multiple
regmaps, with a name that does not depend on regmap_config and is local
to the clock controller. This will be useful when the name if defined
somewhere else (syscon, auxiliary device, etc ...)

>
>> 
>> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
>> ---
>>  drivers/clk/meson/a1-peripherals.c | 165 +-------------
>>  drivers/clk/meson/a1-pll.c         |  18 +-
>>  drivers/clk/meson/axg-aoclk.c      |  22 --
>>  drivers/clk/meson/axg-audio.c      | 435 +------------------------------------
>>  drivers/clk/meson/axg.c            | 131 -----------
>>  drivers/clk/meson/c3-peripherals.c | 212 +-----------------
>>  drivers/clk/meson/c3-pll.c         |  34 +--
>>  drivers/clk/meson/clk-cpu-dyndiv.c |   1 +
>>  drivers/clk/meson/clk-dualdiv.c    |   2 +
>>  drivers/clk/meson/clk-mpll.c       |   6 +
>>  drivers/clk/meson/clk-phase.c      |  11 +
>>  drivers/clk/meson/clk-pll.c        |   7 +
>>  drivers/clk/meson/clk-regmap.c     |  88 ++++++++
>>  drivers/clk/meson/clk-regmap.h     |   7 +
>>  drivers/clk/meson/g12a-aoclk.c     |  34 ---
>>  drivers/clk/meson/g12a.c           | 261 ----------------------
>>  drivers/clk/meson/gxbb-aoclk.c     |  19 --
>>  drivers/clk/meson/gxbb.c           | 393 ---------------------------------
>>  drivers/clk/meson/meson-aoclk.c    |   7 +-
>>  drivers/clk/meson/meson-aoclk.h    |   2 -
>>  drivers/clk/meson/meson-eeclk.c    |   6 +-
>>  drivers/clk/meson/meson-eeclk.h    |   2 -
>>  drivers/clk/meson/meson8-ddr.c     |  11 +-
>>  drivers/clk/meson/s4-peripherals.c | 231 +-------------------
>>  drivers/clk/meson/s4-pll.c         |  33 +--
>>  drivers/clk/meson/sclk-div.c       |   5 +
>>  drivers/clk/meson/vclk.c           |   2 +
>>  drivers/clk/meson/vid-pll-div.c    |   1 +
>>  28 files changed, 165 insertions(+), 1981 deletions(-)
>
> It would be more focused if you split the patch into two. One that
> installs the init clk_op and implements the logic to hook up the regmap
> and one that removes the arrays that are no longer used.

I should have done so indeed.


-- 
Jerome


From herbert at gondor.apana.org.au  Sat Dec 21 03:37:55 2024
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Sat, 21 Dec 2024 19:37:55 +0800
Subject: [PATCH v11 11/22] crypto: amlogic - Introduce hasher
In-Reply-To: <20241213140755.1298323-12-avromanov@salutedevices.com>
References: <20241213140755.1298323-1-avromanov@salutedevices.com>
 <20241213140755.1298323-12-avromanov@salutedevices.com>
Message-ID: <Z2aokzSrAHpJE_PG@gondor.apana.org.au>

On Fri, Dec 13, 2024 at 05:07:44PM +0300, Alexey Romanov wrote:
>
> +static int meson_sha_digest(struct ahash_request *req)
> +{
> +	struct crypto_wait wait;
> +	int ret;
> +
> +	crypto_init_wait(&wait);
> +	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
> +					CRYPTO_TFM_REQ_MAY_BACKLOG,
> +					crypto_req_done, &wait);
> +
> +	meson_sha_init(req);
> +
> +	ret = crypto_wait_req(meson_sha_update(req), &wait);

You cannot sleep in the digest function.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From maz at kernel.org  Sat Dec 21 03:54:31 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 21 Dec 2024 11:54:31 +0000
Subject: [PATCH v8 6/8] KVM: arm64: coresight: Give TRBE enabled state to KVM
In-Reply-To: <e6b46080-b9ae-4aad-b06d-81407c195e28@linaro.org>
References: <20241127100130.1162639-1-james.clark@linaro.org>
	<20241127100130.1162639-7-james.clark@linaro.org>
	<86ttayp9n9.wl-maz@kernel.org>
	<e6b46080-b9ae-4aad-b06d-81407c195e28@linaro.org>
Message-ID: <86seqhp7yg.wl-maz@kernel.org>

On Fri, 20 Dec 2024 17:32:17 +0000,
James Clark <james.clark at linaro.org> wrote:
> 
> 
> 
> On 20/12/2024 5:05 pm, Marc Zyngier wrote:
> > On Wed, 27 Nov 2024 10:01:23 +0000,
> > James Clark <james.clark at linaro.org> wrote:
> >> 
> >> Currently in nVHE, KVM has to check if TRBE is enabled on every guest
> >> switch even if it was never used. Because it's a debug feature and is
> >> more likely to not be used than used, give KVM the TRBE buffer status to
> >> allow a much simpler and faster do-nothing path in the hyp.
> >> 
> >> This is always called with preemption disabled except for probe/hotplug
> >> which gets wrapped with preempt_disable().
> >> 
> >> Protected mode disables trace regardless of TRBE (because
> >> guest_trfcr_el1 is always 0), which was not previously done. HAS_TRBE
> >> becomes redundant, but HAS_TRF is now required for this.
> >> 
> >> Signed-off-by: James Clark <james.clark at linaro.org>
> >> ---
> >>   arch/arm64/include/asm/kvm_host.h            | 10 +++-
> >>   arch/arm64/kvm/debug.c                       | 25 ++++++++--
> >>   arch/arm64/kvm/hyp/nvhe/debug-sr.c           | 51 +++++++++++---------
> >>   drivers/hwtracing/coresight/coresight-trbe.c |  5 ++
> >>   4 files changed, 65 insertions(+), 26 deletions(-)
> >> 
> >> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> >> index 7e3478386351..ba251caa593b 100644
> >> --- a/arch/arm64/include/asm/kvm_host.h
> >> +++ b/arch/arm64/include/asm/kvm_host.h
> >> @@ -611,7 +611,8 @@ struct cpu_sve_state {
> >>    */
> >>   struct kvm_host_data {
> >>   #define KVM_HOST_DATA_FLAG_HAS_SPE	0
> >> -#define KVM_HOST_DATA_FLAG_HAS_TRBE	1
> >> +#define KVM_HOST_DATA_FLAG_HAS_TRF	1
> >> +#define KVM_HOST_DATA_FLAG_TRBE_ENABLED	2
> >>   	unsigned long flags;
> >>     	struct kvm_cpu_context host_ctxt;
> >> @@ -657,6 +658,9 @@ struct kvm_host_data {
> >>   		u64 mdcr_el2;
> >>   	} host_debug_state;
> >>   +	/* Guest trace filter value */
> >> +	u64 guest_trfcr_el1;
> > 
> > Guest value? Or host state while running the guest? If the former,
> > then this has nothing to do here. If the latter, this should be
> > spelled out (trfcr_in_guest?), and the comment amended.
> > 
> >> +
> >>   	/* Number of programmable event counters (PMCR_EL0.N) for this CPU */
> >>   	unsigned int nr_event_counters;
> >>   };
> >> @@ -1381,6 +1385,8 @@ static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr)
> >>   void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
> >>   void kvm_clr_pmu_events(u64 clr);
> >>   bool kvm_set_pmuserenr(u64 val);
> >> +void kvm_enable_trbe(void);
> >> +void kvm_disable_trbe(void);
> >>   #else
> >>   static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {}
> >>   static inline void kvm_clr_pmu_events(u64 clr) {}
> >> @@ -1388,6 +1394,8 @@ static inline bool kvm_set_pmuserenr(u64 val)
> >>   {
> >>   	return false;
> >>   }
> >> +static inline void kvm_enable_trbe(void) {}
> >> +static inline void kvm_disable_trbe(void) {}
> >>   #endif
> >>     void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
> >> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> >> index dd9e139dfd13..0c340ae7b5d1 100644
> >> --- a/arch/arm64/kvm/debug.c
> >> +++ b/arch/arm64/kvm/debug.c
> >> @@ -314,7 +314,26 @@ void kvm_init_host_debug_data(void)
> >>   	    !(read_sysreg_s(SYS_PMBIDR_EL1) & PMBIDR_EL1_P))
> >>   		host_data_set_flag(HAS_SPE);
> >>   -	if (cpuid_feature_extract_unsigned_field(dfr0,
> >> ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
> >> -	    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
> >> -		host_data_set_flag(HAS_TRBE);
> >> +	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceFilt_SHIFT))
> >> +		host_data_set_flag(HAS_TRF);
> >>   }
> >> +
> >> +void kvm_enable_trbe(void)
> >> +{
> >> +	if (has_vhe() || is_protected_kvm_enabled() ||
> >> +	    WARN_ON_ONCE(preemptible()))
> >> +		return;
> >> +
> >> +	host_data_set_flag(TRBE_ENABLED);
> >> +}
> >> +EXPORT_SYMBOL_GPL(kvm_enable_trbe);
> >> +
> >> +void kvm_disable_trbe(void)
> >> +{
> >> +	if (has_vhe() || is_protected_kvm_enabled() ||
> >> +	    WARN_ON_ONCE(preemptible()))
> >> +		return;
> >> +
> >> +	host_data_clear_flag(TRBE_ENABLED);
> >> +}
> >> +EXPORT_SYMBOL_GPL(kvm_disable_trbe);
> >> diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> >> index 858bb38e273f..9479bee41801 100644
> >> --- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> >> +++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> >> @@ -51,32 +51,39 @@ static void __debug_restore_spe(u64 pmscr_el1)
> >>   	write_sysreg_el1(pmscr_el1, SYS_PMSCR);
> >>   }
> >>   -static void __debug_save_trace(u64 *trfcr_el1)
> >> +static void __trace_do_switch(u64 *saved_trfcr, u64 new_trfcr)
> >>   {
> >> -	*trfcr_el1 = 0;
> >> +	*saved_trfcr = read_sysreg_el1(SYS_TRFCR);
> >> +	write_sysreg_el1(new_trfcr, SYS_TRFCR);
> >>   -	/* Check if the TRBE is enabled */
> >> -	if (!(read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E))
> >> +	/* No need to drain if going to an enabled state or from disabled state */
> >> +	if (new_trfcr || !*saved_trfcr)
> > 
> > What if TRFCR_EL1.TS is set to something non-zero? I'd rather you
> > check for the E*TRE bits instead of assuming things.
> > 
> 
> Yeah it's probably better that way. TS is actually always set when any
> tracing session starts and then never cleared, so doing it the simpler
> way made it always flush even after tracing finished, which probably
> wasn't great.

Quite. Can you please *test* these things?

[...]

> >> @@ -253,8 +256,10 @@ static void trbe_drain_and_disable_local(struct trbe_cpudata *cpudata)
> >>     static void trbe_reset_local(struct trbe_cpudata *cpudata)
> >>   {
> >> +	preempt_disable();
> >>   	trbe_drain_and_disable_local(cpudata);
> >>   	write_sysreg_s(0, SYS_TRBLIMITR_EL1);
> >> +	preempt_enable();
> > 
> > This looks terribly wrong. If you need to disable preemption here, why
> > doesn't the critical section cover all register accesses? Surely you
> > don't want to nuke another CPU's context?
> > 
> > But looking at the calling sites, this makes even less sense. The two
> > callers of this thing mess with *per-CPU* interrupts. Dealing with
> > per-CPU interrupts in preemptible context is a big no-no (hint: they
> > start with a call to smp_processor_id()).
> > 
> > So what is this supposed to ensure?
> > 
> > 	M.
> > 
> 
> These ones are only intended to silence the
> WARN_ON_ONCE(preemptible()) in kvm_enable_trbe() when this is called
> from boot/hotplug (arm_trbe_enable_cpu()). Preemption isn't disabled,
> but a guest can't run at that point either.
>
> The "real" calls to kvm_enable_trbe() _are_ called from an atomic
> context. I think there was a previous review comment about when it was
> safe to call the KVM parts of this change, which is why I added the
> warning making sure it was always called with preemption disabled. But
> actually I could remove the warning and these preempt_disables() and
> replace them with a comment.

You should keep the WARN_ON(), and either *never* end-up calling this
stuff during a CPUHP event, or handle the fact that preemption isn't
initialised yet. For example by checking whether the current CPU is
online.

But this sort of random spreading of preemption disabling is not an
acceptable outcome.

	M.

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


From will at kernel.org  Sat Dec 21 04:10:55 2024
From: will at kernel.org (Will Deacon)
Date: Sat, 21 Dec 2024 12:10:55 +0000
Subject: [PATCH v3 6/6] arm64/mm: Drop configurable 48-bit physical
 address space limit
In-Reply-To: <20241221002906.GA2558963@ax162>
References: <20241212081841.2168124-8-ardb+git@google.com>
 <20241212081841.2168124-14-ardb+git@google.com>
 <20241221002906.GA2558963@ax162>
Message-ID: <20241221121054.GA27495@willie-the-truck>

On Fri, Dec 20, 2024 at 05:29:06PM -0700, Nathan Chancellor wrote:
> On Thu, Dec 12, 2024 at 09:18:48AM +0100, Ard Biesheuvel wrote:
> > From: Ard Biesheuvel <ardb at kernel.org>
> > 
> > Currently, the maximum supported physical address space can be
> > configured as either 48 bits or 52 bits. The only remaining difference
> > between these in practice is that the former omits the masking and
> > shifting required to construct TTBR and PTE values, which carry bits #48
> > and higher disjoint from the rest of the physical address.
> > 
> > The overhead of performing these additional calculations is negligible,
> > and so there is little reason to retain support for two different
> > configurations, and we can simply support whatever the hardware
> > supports.
> 
> I am seeing a boot failure after this change as commit 32d053d6f5e9
> ("arm64/mm: Drop configurable 48-bit physical address space limit") in
> next-20241220 with several distribution configurations that all set
> ARM64_VA_BITS_48. I can reproduce it on bare metal and in QEMU. Simply:

We dropped the patch yesterday, so hopefully things are better today.

Sorry for the bother and thanks for the report,

Will


From maz at kernel.org  Sat Dec 21 04:34:48 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 21 Dec 2024 12:34:48 +0000
Subject: [PATCH v8 7/8] KVM: arm64: Support trace filtering for guests
In-Reply-To: <20241127100130.1162639-8-james.clark@linaro.org>
References: <20241127100130.1162639-1-james.clark@linaro.org>
	<20241127100130.1162639-8-james.clark@linaro.org>
Message-ID: <86r061p63b.wl-maz@kernel.org>

On Wed, 27 Nov 2024 10:01:24 +0000,
James Clark <james.clark at linaro.org> wrote:
> 
> For nVHE, switch the filter value in and out if the Coresight driver
> asks for it. This will support filters for guests when sinks other than
> TRBE are used.
> 
> For VHE, just write the filter directly to TRFCR_EL1 where trace can be
> used even with TRBE sinks.
> 
> Signed-off-by: James Clark <james.clark at linaro.org>
> ---
>  arch/arm64/include/asm/kvm_host.h  |  5 +++++
>  arch/arm64/kvm/debug.c             | 28 ++++++++++++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/debug-sr.c |  1 +
>  3 files changed, 34 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index ba251caa593b..cce07887551b 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -613,6 +613,7 @@ struct kvm_host_data {
>  #define KVM_HOST_DATA_FLAG_HAS_SPE	0
>  #define KVM_HOST_DATA_FLAG_HAS_TRF	1
>  #define KVM_HOST_DATA_FLAG_TRBE_ENABLED	2
> +#define KVM_HOST_DATA_FLAG_GUEST_FILTER	3

Guest filter what? This is meaningless.

>  	unsigned long flags;
>  
>  	struct kvm_cpu_context host_ctxt;
> @@ -1387,6 +1388,8 @@ void kvm_clr_pmu_events(u64 clr);
>  bool kvm_set_pmuserenr(u64 val);
>  void kvm_enable_trbe(void);
>  void kvm_disable_trbe(void);
> +void kvm_set_trfcr(u64 guest_trfcr);
> +void kvm_clear_trfcr(void);
>  #else
>  static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {}
>  static inline void kvm_clr_pmu_events(u64 clr) {}
> @@ -1396,6 +1399,8 @@ static inline bool kvm_set_pmuserenr(u64 val)
>  }
>  static inline void kvm_enable_trbe(void) {}
>  static inline void kvm_disable_trbe(void) {}
> +static inline void kvm_set_trfcr(u64 guest_trfcr) {}
> +static inline void kvm_clear_trfcr(void) {}
>  #endif
>  
>  void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index 0c340ae7b5d1..9266f2776991 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -337,3 +337,31 @@ void kvm_disable_trbe(void)
>  	host_data_clear_flag(TRBE_ENABLED);
>  }
>  EXPORT_SYMBOL_GPL(kvm_disable_trbe);
> +
> +void kvm_set_trfcr(u64 guest_trfcr)

Again. Is this the guest's view? or the host view while running the
guest? I asked the question on the previous patch, and you didn't
reply.

> +{
> +	if (is_protected_kvm_enabled() || WARN_ON_ONCE(preemptible()))
> +		return;
> +
> +	if (has_vhe())
> +		write_sysreg_s(guest_trfcr, SYS_TRFCR_EL12);
> +	else {
> +		*host_data_ptr(guest_trfcr_el1) = guest_trfcr;
> +		host_data_set_flag(GUEST_FILTER);
> +	}

Oh come on. This is basic coding style, see section 3 in
Documentation/process/coding-style.rst.

> +}
> +EXPORT_SYMBOL_GPL(kvm_set_trfcr);
> +
> +void kvm_clear_trfcr(void)
> +{
> +	if (is_protected_kvm_enabled() || WARN_ON_ONCE(preemptible()))
> +		return;
> +
> +	if (has_vhe())
> +		write_sysreg_s(0, SYS_TRFCR_EL12);
> +	else {
> +		*host_data_ptr(guest_trfcr_el1) = 0;
> +		host_data_clear_flag(GUEST_FILTER);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(kvm_clear_trfcr);

Why do we have two helpers? Clearly, calling kvm_set_trfcr() with
E{1,0}TRE=={0,0} should result in *disabling* things.  Except it
doesn't, and you should fix it. Once that is fixed, it becomes obvious
that kvm_clear_trfcr() serves no purpose.

To sum it up, KVM's API should reflect the architecture instead of
making things up.

> diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> index 9479bee41801..7edee7ace433 100644
> --- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> +++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> @@ -67,6 +67,7 @@ static void __trace_do_switch(u64 *saved_trfcr, u64 new_trfcr)
>  static bool __trace_needs_switch(void)
>  {
>  	return host_data_test_flag(TRBE_ENABLED) ||
> +	       host_data_test_flag(GUEST_FILTER) ||
>  	       (is_protected_kvm_enabled() && host_data_test_flag(HAS_TRF));

Wouldn't it make more sense to just force the "GUEST_FILTER" flag in
the pKVM case, and drop the 3rd term altogether?

	M.

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


From heiko at sntech.de  Sat Dec 21 04:55:02 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 21 Dec 2024 13:55:02 +0100
Subject: [PATCH] arm64: dts: rockchip: aliase sdhci as mmc0 for rk3566 box demo
In-Reply-To: <20241221104920.4193034-1-andyshrk@163.com>
References: <20241221104920.4193034-1-andyshrk@163.com>
Message-ID: <24438615.ouqheUzb2q@diego>

Hi Andy,

Am Samstag, 21. Dezember 2024, 11:49:07 CET schrieb Andy Yan:
> From: Andy Yan <andy.yan at rock-chips.com>
> 
> Follow most others rk356x based boards, and u-boot only use mmc0/1
> as mmc boot targets, so aliase sdhci as mmc0.
> 
> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
> ---
> 
>  arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts b/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
> index 41b4cd5a4220..7d0eedf1bd0d 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
> @@ -19,9 +19,9 @@ / {
>  
>  	aliases {
>  		ethernet0 = &gmac1;
> -		mmc0 = &sdmmc0;
> -		mmc1 = &sdmmc1;
> -		mmc2 = &sdhci;
> +		mmc0 = &sdhci;
> +		mmc1 = &sdmmc0;
> +		mmc2 = &sdmmc1;

sorry, but that won't be possible :-( .

The original aliases for the mmc order were added over 2 years ago
(november 2022) and became part of the ABI then.

Imagine someone using that board with a rootfs=/dev/mmcblk2p1 part
in the commandline to mount the old sdhci-part1 as rootfs, but now
you reorder the controllers, so so that commandline would try to access
sdmmc1, so their system won't boot anymore after just a simple kernel
update.

Breaking people's setup is one of those big no-go-s in the kernel, so
sadly you'll need to live with the existing order.


Heiko




From j at jannau.net  Sat Dec 21 05:45:49 2024
From: j at jannau.net (Janne Grunau)
Date: Sat, 21 Dec 2024 14:45:49 +0100
Subject: [PATCH 00/18] KVM: arm64: Support FEAT_PMUv3 on Apple hardware
In-Reply-To: <20241217212048.3709204-1-oliver.upton@linux.dev>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
Message-ID: <20241221134549.GA2917938@robin.jannau.net>

On Tue, Dec 17, 2024 at 01:20:30PM -0800, Oliver Upton wrote:
> One of the interesting features of some Apple M* parts is an IMPDEF trap
> that routes EL1/EL0 accesses of the PMUv3 registers to EL2. This allows
> a hypervisor to emulate an architectural PMUv3 on top of the IMPDEF PMU
> hardware present in the CPU.
> 
> And if you squint, this _might_ look like a CPU erratum :-)
> 
> This series takes advantage of these IMPDEF traps to provide PMUv3 to
> KVM guests. As a starting point, only expose the fixed CPU cycle counter
> and no event counters. Conveniently, this is enough to get Windows
> running as a KVM guest on Apple hardware.
> 
> I've tried to keep the deviation to a minimum by refactoring some of the
> flows used for PMUv3, e.g. computing PMCEID from the arm_pmu bitmap
> instead of reading hardware directly.
> 
> RFC -> v1:
>  - Rebase to 6.13-rc3
>  - Add support for 1 event counter in addition to CPU cycle counter
>  - Don't sneak past the PMU event filter (Marc)
>  - Have the PMU driver provide a PMUv3 -> HW event ID mapping (Marc)
> 
> Tested on my M2 with Linux and Windows guests. If possible, I'd
> appreciate someone testing on an M1 as I haven't added those MIDRs to
> the erratum yet.

Tested on M1 (t8103) with perf in a Linux guest and the patch below

Tested-by: Janne Grunau <j at jannau.net>

I'll import this into the downstream asahi kernel as there was a request
for performance counters to aid FEX-Emu development recently.

Janne

--- 

diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 441ee4ffc7709..45ef67ec970f5 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -195,6 +195,12 @@ has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
 }

 static const struct midr_range impdef_pmuv3_cpus[] = {
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_PRO),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_PRO),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_MAX),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_MAX),
 	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD),
 	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE),
 	MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_PRO),


From ivo.ivanov.ivanov1 at gmail.com  Sat Dec 21 07:19:36 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Sat, 21 Dec 2024 17:19:36 +0200
Subject: [PATCH v2 1/2] dt-bindings: i2c: exynos5: Add samsung,exynos8895-hsi2c compatible
In-Reply-To: <20241221151937.1659139-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241221151937.1659139-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <20241221151937.1659139-2-ivo.ivanov.ivanov1@gmail.com>

Add samsung,exynos8895-hsi2c dedicated compatible for representing
I2C of Exynos8895 SoC. I2C buses may be implemented both as a part
of USIv1 and separately.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
---
 Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
index cc8bba553..70cc2ee9e 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
+++ b/Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml
@@ -25,6 +25,7 @@ properties:
           - samsung,exynos5250-hsi2c    # Exynos5250 and Exynos5420
           - samsung,exynos5260-hsi2c    # Exynos5260
           - samsung,exynos7-hsi2c       # Exynos7
+          - samsung,exynos8895-hsi2c
           - samsung,exynosautov9-hsi2c
       - items:
           - enum:
-- 
2.43.0



From ivo.ivanov.ivanov1 at gmail.com  Sat Dec 21 07:19:35 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Sat, 21 Dec 2024 17:19:35 +0200
Subject: [PATCH v2 0/2] i2c: exynos5: Add support for Exynos8895 SoC
Message-ID: <20241221151937.1659139-1-ivo.ivanov.ivanov1@gmail.com>

Hey folks,

This series adds HSI2C support for Exynos8895 to i2c-exynos5. HSI2C
buses here are mostly available implemented in USIv1 blocks, with 5
available externally - hsi2c_0 to 4. hsi2c_0 is available for PMIC
(although I've never seen it used) and it uses BUSC clocks, which are
still not implemented in the current clock driver, so I've decided to
leave it out for now.

In the next few patchsets support for USIv1 will be added to the
exynos-usi driver and with that the rest of the I2C buses will be made
available in the device tree.

Kind regards,
Ivo

Changes in v2:
 - Dropped nested-if in the binding, keeping in mind we'll always
   provide only a single clock.

Ivaylo Ivanov (2):
  dt-bindings: i2c: exynos5: Add samsung,exynos8895-hsi2c compatible
  i2c: exynos5: Add support for Exynos8895 SoC

 .../devicetree/bindings/i2c/i2c-exynos5.yaml  |  1 +
 drivers/i2c/busses/i2c-exynos5.c              | 31 +++++++++++++++++--
 2 files changed, 30 insertions(+), 2 deletions(-)

-- 
2.43.0



From ivo.ivanov.ivanov1 at gmail.com  Sat Dec 21 07:19:37 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Sat, 21 Dec 2024 17:19:37 +0200
Subject: [PATCH v2 2/2] i2c: exynos5: Add support for Exynos8895 SoC
In-Reply-To: <20241221151937.1659139-1-ivo.ivanov.ivanov1@gmail.com>
References: <20241221151937.1659139-1-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <20241221151937.1659139-3-ivo.ivanov.ivanov1@gmail.com>

Exynos8895 functioning logic mostly follows I2C_TYPE_EXYNOS7, but timing
and temp calculations are slightly changed according to the following
logic:

FPCLK / FI2C = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 2 *
((FLT_CYCLE + 3) - (FLT_CYCLE + 3) % (CLK_DIV + 1))

temp := (FPCLK / FI2C) - (FLT_CYCLE + 3) * 2

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
---
 drivers/i2c/busses/i2c-exynos5.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index e33001508..8d8ee42ba 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -168,6 +168,7 @@ enum i2c_type_exynos {
 	I2C_TYPE_EXYNOS5,
 	I2C_TYPE_EXYNOS7,
 	I2C_TYPE_EXYNOSAUTOV9,
+	I2C_TYPE_EXYNOS8895,
 };
 
 struct exynos5_i2c {
@@ -240,6 +241,11 @@ static const struct exynos_hsi2c_variant exynosautov9_hsi2c_data = {
 	.hw		= I2C_TYPE_EXYNOSAUTOV9,
 };
 
+static const struct exynos_hsi2c_variant exynos8895_hsi2c_data = {
+	.fifo_depth	= 64,
+	.hw		= I2C_TYPE_EXYNOS8895,
+};
+
 static const struct of_device_id exynos5_i2c_match[] = {
 	{
 		.compatible = "samsung,exynos5-hsi2c",
@@ -256,6 +262,9 @@ static const struct of_device_id exynos5_i2c_match[] = {
 	}, {
 		.compatible = "samsung,exynosautov9-hsi2c",
 		.data = &exynosautov9_hsi2c_data
+	}, {
+		.compatible = "samsung,exynos8895-hsi2c",
+		.data = &exynos8895_hsi2c_data
 	}, {},
 };
 MODULE_DEVICE_TABLE(of, exynos5_i2c_match);
@@ -331,6 +340,14 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
 	 * clk_cycle := TSCLK_L + TSCLK_H
 	 * temp := (CLK_DIV + 1) * (clk_cycle + 2)
 	 *
+	 * In case of HSI2C controllers in Exynos8895
+	 * FPCLK / FI2C =
+	 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) +
+	 * 2 * ((FLT_CYCLE + 3) - (FLT_CYCLE + 3) % (CLK_DIV + 1))
+	 *
+	 * clk_cycle := TSCLK_L + TSCLK_H
+	 * temp := (FPCLK / FI2C) - (FLT_CYCLE + 3) * 2
+	 *
 	 * Constraints: 4 <= temp, 0 <= CLK_DIV < 256, 2 <= clk_cycle <= 510
 	 *
 	 * To split SCL clock into low, high periods appropriately, one
@@ -352,11 +369,19 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
 	 *
 	 */
 	t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
-	temp = clkin / op_clk - 8 - t_ftl_cycle;
+	if (i2c->variant->hw == I2C_TYPE_EXYNOS8895)
+		temp = clkin / op_clk - (t_ftl_cycle + 3) * 2;
+	else
+		temp = clkin / op_clk - 8 - t_ftl_cycle;
 	if (i2c->variant->hw != I2C_TYPE_EXYNOS7)
 		temp -= t_ftl_cycle;
 	div = temp / 512;
-	clk_cycle = temp / (div + 1) - 2;
+
+	if (i2c->variant->hw == I2C_TYPE_EXYNOS8895)
+		clk_cycle = (temp + ((t_ftl_cycle + 3) % (div + 1)) * 2) /
+			    (div + 1) - 2;
+	else
+		clk_cycle = temp / (div + 1) - 2;
 	if (temp < 4 || div >= 256 || clk_cycle < 2) {
 		dev_err(i2c->dev, "%s clock set-up failed\n",
 			hs_timings ? "HS" : "FS");
@@ -491,6 +516,8 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
 	switch (i2c->variant->hw) {
 	case I2C_TYPE_EXYNOSAUTOV9:
 		fallthrough;
+	case I2C_TYPE_EXYNOS8895:
+		fallthrough;
 	case I2C_TYPE_EXYNOS7:
 		if (int_status & HSI2C_INT_TRANS_DONE) {
 			i2c->trans_done = 1;
-- 
2.43.0



From ivo.ivanov.ivanov1 at gmail.com  Sat Dec 21 07:28:03 2024
From: ivo.ivanov.ivanov1 at gmail.com (Ivaylo Ivanov)
Date: Sat, 21 Dec 2024 17:28:03 +0200
Subject: [PATCH v2] arm64: dts: exynos8895: Add camera hsi2c nodes
Message-ID: <20241221152803.1663820-1-ivo.ivanov.ivanov1@gmail.com>

Add nodes for hsi2c1-4 (CAM0-3), which allows using them.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
---
Bindings are in another patchset [1].

Changes in v2:
  - Mention the bindings this patch depends on.

[1] https://lore.kernel.org/all/20241221151937.1659139-1-ivo.ivanov.ivanov1 at gmail.com/
---
 arch/arm64/boot/dts/exynos/exynos8895.dtsi | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos8895.dtsi b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
index 90b318b2f..36657abfc 100644
--- a/arch/arm64/boot/dts/exynos/exynos8895.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
@@ -292,6 +292,50 @@ pinctrl_peric1: pinctrl at 10980000 {
 			interrupts = <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		hsi2c_1: i2c at 10990000 {
+			compatible = "samsung,exynos8895-hsi2c";
+			reg = <0x10990000 0x1000>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_HSI2C_CAM0_IPCLK>;
+			clock-names = "hsi2c";
+			interrupts = <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-0 = <&hsi2c1_bus>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
+		hsi2c_2: i2c at 109a0000 {
+			compatible = "samsung,exynos8895-hsi2c";
+			reg = <0x109a0000 0x1000>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_HSI2C_CAM1_IPCLK>;
+			clock-names = "hsi2c";
+			interrupts = <GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-0 = <&hsi2c2_bus>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
+		hsi2c_3: i2c at 109b0000 {
+			compatible = "samsung,exynos8895-hsi2c";
+			reg = <0x109b0000 0x1000>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_HSI2C_CAM2_IPCLK>;
+			clock-names = "hsi2c";
+			interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-0 = <&hsi2c3_bus>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
+		hsi2c_4: i2c at 109c0000 {
+			compatible = "samsung,exynos8895-hsi2c";
+			reg = <0x109c0000 0x1000>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_HSI2C_CAM3_IPCLK>;
+			clock-names = "hsi2c";
+			interrupts = <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-0 = <&hsi2c4_bus>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
 		spi_0: spi at 109d0000 {
 			compatible = "samsung,exynos8895-spi",
 				     "samsung,exynos850-spi";
-- 
2.43.0



From yeoreum.yun at arm.com  Sat Dec 21 08:59:33 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Sat, 21 Dec 2024 16:59:33 +0000
Subject: [PATCH 3/4] coresight/etm3x: disallow altering config via sysfs while enabled
In-Reply-To: <20241221165934.1161856-1-yeoreum.yun@arm.com>
References: <20241221165934.1161856-1-yeoreum.yun@arm.com>
Message-ID: <20241221165934.1161856-4-yeoreum.yun@arm.com>

When etm3x configuration is modified via sysfs while etm3x is being
enabled via perf, enabled etm3x could run with different configuration
from perf_event.

To address this, disallow altering config via sysfs while csdev is enabled.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../coresight/coresight-etm3x-sysfs.c         | 120 ++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index 68c644be9813..b3ae9aba7490 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -75,6 +75,9 @@ static ssize_t reset_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	if (val) {
 		spin_lock(&drvdata->spinlock);
 		memset(config, 0, sizeof(struct etm_config));
@@ -117,6 +120,9 @@ static ssize_t mode_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->mode = val & ETM_MODE_ALL;
 
@@ -202,7 +208,12 @@ static ssize_t trigger_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->trigger_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -232,7 +243,12 @@ static ssize_t enable_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->enable_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -262,7 +278,12 @@ static ssize_t fifofull_level_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->fifofull_level = val;
+	spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -295,6 +316,9 @@ static ssize_t addr_idx_store(struct device *dev,
 	if (val >= drvdata->nr_addr_cmp)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -343,6 +367,9 @@ static ssize_t addr_single_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
@@ -403,6 +430,9 @@ static ssize_t addr_range_store(struct device *dev,
 	if (val1 > val2)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
@@ -464,6 +494,9 @@ static ssize_t addr_start_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
@@ -518,6 +551,9 @@ static ssize_t addr_stop_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
@@ -563,6 +599,9 @@ static ssize_t addr_acctype_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->addr_acctype[config->addr_idx] = val;
 	spin_unlock(&drvdata->spinlock);
@@ -597,6 +636,10 @@ static ssize_t cntr_idx_store(struct device *dev,
 
 	if (val >= drvdata->nr_cntr)
 		return -EINVAL;
+
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -636,6 +679,9 @@ static ssize_t cntr_rld_val_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->cntr_rld_val[config->cntr_idx] = val;
 	spin_unlock(&drvdata->spinlock);
@@ -671,6 +717,9 @@ static ssize_t cntr_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->cntr_event[config->cntr_idx] = val & ETM_EVENT_MASK;
 	spin_unlock(&drvdata->spinlock);
@@ -706,6 +755,9 @@ static ssize_t cntr_rld_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->cntr_rld_event[config->cntr_idx] = val & ETM_EVENT_MASK;
 	spin_unlock(&drvdata->spinlock);
@@ -752,6 +804,9 @@ static ssize_t cntr_val_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->cntr_val[config->cntr_idx] = val;
 	spin_unlock(&drvdata->spinlock);
@@ -784,7 +839,13 @@ static ssize_t seq_12_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_12_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_12_event);
@@ -813,7 +874,13 @@ static ssize_t seq_21_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_21_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_21_event);
@@ -842,7 +909,13 @@ static ssize_t seq_23_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_23_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_23_event);
@@ -871,7 +944,13 @@ static ssize_t seq_31_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_31_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_31_event);
@@ -900,7 +979,13 @@ static ssize_t seq_32_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_32_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_32_event);
@@ -929,7 +1014,13 @@ static ssize_t seq_13_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_13_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_13_event);
@@ -975,7 +1066,12 @@ static ssize_t seq_curr_state_store(struct device *dev,
 	if (val > ETM_SEQ_STATE_MAX_VAL)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_curr_state = val;
+	spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -1008,6 +1104,9 @@ static ssize_t ctxid_idx_store(struct device *dev,
 	if (val >= drvdata->nr_ctxid_cmp)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -1066,6 +1165,9 @@ static ssize_t ctxid_pid_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->ctxid_pid[config->ctxid_idx] = pid;
 	spin_unlock(&drvdata->spinlock);
@@ -1112,7 +1214,13 @@ static ssize_t ctxid_mask_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->ctxid_mask = val;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_mask);
@@ -1141,7 +1249,13 @@ static ssize_t sync_freq_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->sync_freq = val & ETM_SYNC_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(sync_freq);
@@ -1170,7 +1284,13 @@ static ssize_t timestamp_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->timestamp_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(timestamp_event);
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Sat Dec 21 08:59:30 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Sat, 21 Dec 2024 16:59:30 +0000
Subject: [PATCH 0/4] small fix for configuaring etm csdev via sysfs
Message-ID: <20241221165934.1161856-1-yeoreum.yun@arm.com>

when etm csdev's configuration is modified via sysfs while etm is being
enabled via perf, enabled etm could run with different configuration
from perf_event.

Also, there are some redeundant usage of drvdata->spinlock in
etm_starting/dying_cpu() with enable/disable etm device.

This patchset fixes above small problems.

NOTE:
   This patchset based on:
     - https://lore.kernel.org/linux-arm-kernel/20241220104521.809071-1-yeoreum.yun at arm.com/

Yeoreum Yun (4):
  coresight/etm4x: disallow altering config via sysfs while enabled
  coresight/etm4x: remove redundant usage of drvdata->spinlock
  coresight/etm3x: disallow altering config via sysfs while enabled
  coresight/etm3x: remove redundant usage of drvdata->spinlock

 .../coresight/coresight-etm3x-core.c          |  33 ++---
 .../coresight/coresight-etm3x-sysfs.c         | 120 ++++++++++++++++
 .../coresight/coresight-etm4x-core.c          |  20 +--
 .../coresight/coresight-etm4x-sysfs.c         | 132 +++++++++++++++++-
 4 files changed, 272 insertions(+), 33 deletions(-)

--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Sat Dec 21 08:59:31 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Sat, 21 Dec 2024 16:59:31 +0000
Subject: [PATCH 1/4] coresight/etm4x: disallow altering config via sysfs while enabled
In-Reply-To: <20241221165934.1161856-1-yeoreum.yun@arm.com>
References: <20241221165934.1161856-1-yeoreum.yun@arm.com>
Message-ID: <20241221165934.1161856-2-yeoreum.yun@arm.com>

When etm4x configuration is modified via sysfs while etm4x is being
enabled via perf, enabled etm4x could run with different configuration
from perf_event.

To address this, disallow altering config via sysfs while csdev is enabled.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../coresight/coresight-etm4x-sysfs.c         | 132 +++++++++++++++++-
 1 file changed, 128 insertions(+), 4 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index 11e865b8e824..cc1f112921d7 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -174,6 +174,9 @@ static ssize_t reset_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	if (val)
 		config->mode = 0x0;
@@ -300,6 +303,9 @@ static ssize_t mode_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	config->mode = val & ETMv4_MODE_ALL;
 
@@ -466,6 +472,9 @@ static ssize_t pe_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	if (val > drvdata->nr_pe) {
 		raw_spin_unlock(&drvdata->spinlock);
@@ -501,6 +510,9 @@ static ssize_t event_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	switch (drvdata->nr_event) {
 	case 0x0:
@@ -550,6 +562,9 @@ static ssize_t event_instren_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	/* start by clearing all instruction event enable bits */
 	config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;
@@ -608,6 +623,9 @@ static ssize_t event_ts_store(struct device *dev,
 	if (!drvdata->ts_size)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	config->ts_ctrl = val & ETMv4_EVENT_MASK;
 	return size;
 }
@@ -638,6 +656,9 @@ static ssize_t syncfreq_store(struct device *dev,
 	if (drvdata->syncpr == true)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	config->syncfreq = val & ETMv4_SYNC_MASK;
 	return size;
 }
@@ -666,6 +687,9 @@ static ssize_t cyc_threshold_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/* mask off max threshold before checking min value */
 	val &= ETM_CYC_THRESHOLD_MASK;
 	if (val < drvdata->ccitmin)
@@ -703,6 +727,9 @@ static ssize_t bb_ctrl_store(struct device *dev,
 	if (!drvdata->nr_addr_cmp)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Bit[8] controls include(1) / exclude(0), bits[0-7] select
 	 * individual range comparators. If include then at least 1
@@ -739,6 +766,9 @@ static ssize_t event_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	val &= TRCVICTLR_EVENT_MASK >> __bf_shf(TRCVICTLR_EVENT_MASK);
 	config->vinst_ctrl &= ~TRCVICTLR_EVENT_MASK;
@@ -771,6 +801,9 @@ static ssize_t s_exlevel_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	/* clear all EXLEVEL_S bits  */
 	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;
@@ -806,6 +839,9 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	/* clear EXLEVEL_NS bits  */
 	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;
@@ -842,6 +878,9 @@ static ssize_t addr_idx_store(struct device *dev,
 	if (val >= drvdata->nr_addr_cmp * 2)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -888,6 +927,9 @@ static ssize_t addr_instdatatype_store(struct device *dev,
 	if (sscanf(buf, "%s", str) != 1)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!strcmp(str, "instr"))
@@ -913,7 +955,7 @@ static ssize_t addr_single_show(struct device *dev,
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
 		raw_spin_unlock(&drvdata->spinlock);
-		return -EPERM;
+		return -EBUSY;
 	}
 	val = (unsigned long)config->addr_val[idx];
 	raw_spin_unlock(&drvdata->spinlock);
@@ -932,12 +974,15 @@ static ssize_t addr_single_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
 	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
 		raw_spin_unlock(&drvdata->spinlock);
-		return -EPERM;
+		return -EBUSY;
 	}
 
 	config->addr_val[idx] = (u64)val;
@@ -960,14 +1005,14 @@ static ssize_t addr_range_show(struct device *dev,
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
 		raw_spin_unlock(&drvdata->spinlock);
-		return -EPERM;
+		return -EBUSY;
 	}
 	if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
 	      (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
 	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
 		raw_spin_unlock(&drvdata->spinlock);
-		return -EPERM;
+		return -EBUSY;
 	}
 
 	val1 = (unsigned long)config->addr_val[idx];
@@ -995,6 +1040,9 @@ static ssize_t addr_range_store(struct device *dev,
 	if (val1 > val2)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
@@ -1063,6 +1111,9 @@ static ssize_t addr_start_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!drvdata->nr_addr_cmp) {
@@ -1118,6 +1169,9 @@ static ssize_t addr_stop_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!drvdata->nr_addr_cmp) {
@@ -1172,6 +1226,9 @@ static ssize_t addr_ctxtype_store(struct device *dev,
 	if (sscanf(buf, "%s", str) != 1)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!strcmp(str, "none"))
@@ -1238,6 +1295,9 @@ static ssize_t addr_context_store(struct device *dev,
 		     drvdata->numcidc : drvdata->numvmidc))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	/* clear context ID comparator bits[6:4] */
@@ -1276,6 +1336,9 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
 	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	if (val & ~(TRCACATRn_EXLEVEL_MASK >> __bf_shf(TRCACATRn_EXLEVEL_MASK)))
 		return -EINVAL;
 
@@ -1366,6 +1429,9 @@ static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
 	if (!drvdata->nr_pe_cmp)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	config->vipcssctlr = val;
 	raw_spin_unlock(&drvdata->spinlock);
@@ -1398,6 +1464,9 @@ static ssize_t seq_idx_store(struct device *dev,
 	if (val >= drvdata->nrseqstate - 1)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -1434,6 +1503,9 @@ static ssize_t seq_state_store(struct device *dev,
 	if (val >= drvdata->nrseqstate)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	config->seq_state = val;
 	return size;
 }
@@ -1467,6 +1539,9 @@ static ssize_t seq_event_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->seq_idx;
 	/* Seq control has two masks B[15:8] F[7:0] */
@@ -1501,6 +1576,9 @@ static ssize_t seq_reset_event_store(struct device *dev,
 	if (!(drvdata->nrseqstate))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	config->seq_rst = val & ETMv4_EVENT_MASK;
 	return size;
 }
@@ -1531,6 +1609,9 @@ static ssize_t cntr_idx_store(struct device *dev,
 	if (val >= drvdata->nr_cntr)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -1572,6 +1653,9 @@ static ssize_t cntrldvr_store(struct device *dev,
 	if (val > ETM_CNTR_MAX_VAL)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntrldvr[idx] = val;
@@ -1610,6 +1694,9 @@ static ssize_t cntr_val_store(struct device *dev,
 	if (val > ETM_CNTR_MAX_VAL)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntr_val[idx] = val;
@@ -1646,6 +1733,9 @@ static ssize_t cntr_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->cntr_idx;
 	config->cntr_ctrl[idx] = val;
@@ -1676,6 +1766,10 @@ static ssize_t res_idx_store(struct device *dev,
 
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
+
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Resource selector pair 0 is always implemented and reserved,
 	 * namely an idx with 0 and 1 is illegal.
@@ -1722,6 +1816,9 @@ static ssize_t res_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->res_idx;
 	/* For odd idx pair inversal bit is RES0 */
@@ -1761,6 +1858,9 @@ static ssize_t sshot_idx_store(struct device *dev,
 	if (val >= drvdata->nr_ss_cmp)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	config->ss_idx = val;
 	raw_spin_unlock(&drvdata->spinlock);
@@ -1794,6 +1894,9 @@ static ssize_t sshot_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ss_idx;
 	config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
@@ -1844,6 +1947,9 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ss_idx;
 	config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
@@ -1879,6 +1985,9 @@ static ssize_t ctxid_idx_store(struct device *dev,
 	if (val >= drvdata->numcidc)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -1944,6 +2053,9 @@ static ssize_t ctxid_pid_store(struct device *dev,
 	if (kstrtoul(buf, 16, &pid))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	idx = config->ctxid_idx;
 	config->ctxid_pid[idx] = (u64)pid;
@@ -2003,6 +2115,9 @@ static ssize_t ctxid_masks_store(struct device *dev,
 	if ((drvdata->numcidc > 4) && (nr_inputs != 2))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	/*
 	 * each byte[0..3] controls mask value applied to ctxid
@@ -2105,6 +2220,9 @@ static ssize_t vmid_idx_store(struct device *dev,
 	if (val >= drvdata->numvmidc)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -2161,6 +2279,9 @@ static ssize_t vmid_val_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 	config->vmid_val[config->vmid_idx] = (u64)val;
 	raw_spin_unlock(&drvdata->spinlock);
@@ -2217,6 +2338,9 @@ static ssize_t vmid_masks_store(struct device *dev,
 	if ((drvdata->numvmidc > 4) && (nr_inputs != 2))
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	raw_spin_lock(&drvdata->spinlock);
 
 	/*
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Sat Dec 21 08:59:32 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Sat, 21 Dec 2024 16:59:32 +0000
Subject: [PATCH 2/4] coresight/etm4x: remove redundant usage of drvdata->spinlock
In-Reply-To: <20241221165934.1161856-1-yeoreum.yun@arm.com>
References: <20241221165934.1161856-1-yeoreum.yun@arm.com>
Message-ID: <20241221165934.1161856-3-yeoreum.yun@arm.com>

Remove redundant usage of drvdata->spinlock in  etm4_starting/dying_cpu()
by preventing cpu hotplug while enabling etm4x via sysfs since
 - perf and sysfs enable method are serialized by csdev->mode
 - etm4_starting/dying_cpu() aren't called concurrently with
   etm4_enable_perf/sysfs() because they're called in cpu offline status.
 - while etm4x_enable_sysfs(), config isn't altered since csdev->mode
   isn't DISABLED.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../coresight/coresight-etm4x-core.c          | 20 +++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 86893115df17..5c9475b44194 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -799,16 +799,21 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 	unsigned long cfg_hash;
 	int ret, preset;
 
+	cpus_read_lock();
+
+	if (cpu_is_offline(drvdata->cpu)) {
+		ret = -EPERM;
+		goto unlock_sysfs_enable;
+	}
+
 	/* enable any config activated by configfs */
 	cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset);
 	if (cfg_hash) {
 		ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
 		if (ret)
-			return ret;
+			goto unlock_sysfs_enable;
 	}
 
-	raw_spin_lock(&drvdata->spinlock);
-
 	/* sysfs needs to read and allocate a trace ID */
 	ret = etm4_read_alloc_trace_id(drvdata);
 	if (ret < 0)
@@ -830,10 +835,11 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 		etm4_release_trace_id(drvdata);
 
 unlock_sysfs_enable:
-	raw_spin_unlock(&drvdata->spinlock);
+	cpus_read_unlock();
 
 	if (!ret)
 		dev_dbg(&csdev->dev, "ETM tracing enabled\n");
+
 	return ret;
 }
 
@@ -977,7 +983,6 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	 * DYING hotplug callback is serviced by the ETM driver.
 	 */
 	cpus_read_lock();
-	raw_spin_lock(&drvdata->spinlock);
 
 	/*
 	 * Executing etm4_disable_hw on the cpu whose ETM is being disabled
@@ -985,7 +990,6 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
 	 */
 	smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
 
-	raw_spin_unlock(&drvdata->spinlock);
 	cpus_read_unlock();
 
 	/*
@@ -1663,13 +1667,11 @@ static int etm4_starting_cpu(unsigned int cpu)
 	if (!etmdrvdata[cpu])
 		return 0;
 
-	raw_spin_lock(&etmdrvdata[cpu]->spinlock);
 	if (!etmdrvdata[cpu]->os_unlock)
 		etm4_os_unlock(etmdrvdata[cpu]);
 
 	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
 		etm4_enable_hw(etmdrvdata[cpu]);
-	raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
 	return 0;
 }
 
@@ -1678,10 +1680,8 @@ static int etm4_dying_cpu(unsigned int cpu)
 	if (!etmdrvdata[cpu])
 		return 0;
 
-	raw_spin_lock(&etmdrvdata[cpu]->spinlock);
 	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
 		etm4_disable_hw(etmdrvdata[cpu]);
-	raw_spin_unlock(&etmdrvdata[cpu]->spinlock);
 	return 0;
 }
 
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Sat Dec 21 08:59:34 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Sat, 21 Dec 2024 16:59:34 +0000
Subject: [PATCH 4/4] coresight/etm3x: remove redundant usage of drvdata->spinlock
In-Reply-To: <20241221165934.1161856-1-yeoreum.yun@arm.com>
References: <20241221165934.1161856-1-yeoreum.yun@arm.com>
Message-ID: <20241221165934.1161856-5-yeoreum.yun@arm.com>

Remove redundant usage of drvdata->spinlock in etm_starting/dying_cpu()
by preventing cpu hotplug while enabling etm3x via sysfs since
 - perf and sysfs enable method are serialized by csdev->mode
 - etm_starting/dying_cpu() aren't called concurrently with
   etm_enable_perf/sysfs() because they're called in cpu offline status.
 - while etm_enable_sysfs(), config isn't changed since csdev->mode is
   not DISABLED.

Signed-off-by: Yeoreum Yun <yeoreum.yun at arm.com>
---
 .../coresight/coresight-etm3x-core.c          | 33 ++++++++-----------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index c103f4c70f5d..5ec871979ef7 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -519,7 +519,12 @@ static int etm_enable_sysfs(struct coresight_device *csdev)
 	struct etm_enable_arg arg = { };
 	int ret;
 
-	spin_lock(&drvdata->spinlock);
+	cpus_read_lock();
+
+	if (cpu_is_offline(drvdata->cpu)) {
+		ret = -ENODEV;
+		goto unlock_sysfs_enable;
+	}
 
 	/* sysfs needs to allocate and set a trace ID */
 	ret = etm_read_alloc_trace_id(drvdata);
@@ -530,23 +535,19 @@ static int etm_enable_sysfs(struct coresight_device *csdev)
 	 * Configure the ETM only if the CPU is online.  If it isn't online
 	 * hw configuration will take place on the local CPU during bring up.
 	 */
-	if (cpu_online(drvdata->cpu)) {
-		arg.drvdata = drvdata;
-		ret = smp_call_function_single(drvdata->cpu,
-					       etm_enable_hw_smp_call, &arg, 1);
-		if (!ret)
-			ret = arg.rc;
-		if (!ret)
-			drvdata->sticky_enable = true;
-	} else {
-		ret = -ENODEV;
-	}
+	arg.drvdata = drvdata;
+	ret = smp_call_function_single(drvdata->cpu,
+				       etm_enable_hw_smp_call, &arg, 1);
+	if (!ret)
+		ret = arg.rc;
+	if (!ret)
+		drvdata->sticky_enable = true;
 
 	if (ret)
 		etm_release_trace_id(drvdata);
 
 unlock_enable_sysfs:
-	spin_unlock(&drvdata->spinlock);
+	cpus_read_unlock();
 
 	if (!ret)
 		dev_dbg(&csdev->dev, "ETM tracing enabled\n");
@@ -646,7 +647,6 @@ static void etm_disable_sysfs(struct coresight_device *csdev)
 	 * DYING hotplug callback is serviced by the ETM driver.
 	 */
 	cpus_read_lock();
-	spin_lock(&drvdata->spinlock);
 
 	/*
 	 * Executing etm_disable_hw on the cpu whose ETM is being disabled
@@ -654,7 +654,6 @@ static void etm_disable_sysfs(struct coresight_device *csdev)
 	 */
 	smp_call_function_single(drvdata->cpu, etm_disable_hw, drvdata, 1);
 
-	spin_unlock(&drvdata->spinlock);
 	cpus_read_unlock();
 
 	/*
@@ -722,7 +721,6 @@ static int etm_starting_cpu(unsigned int cpu)
 	if (!etmdrvdata[cpu])
 		return 0;
 
-	spin_lock(&etmdrvdata[cpu]->spinlock);
 	if (!etmdrvdata[cpu]->os_unlock) {
 		etm_os_unlock(etmdrvdata[cpu]);
 		etmdrvdata[cpu]->os_unlock = true;
@@ -730,7 +728,6 @@ static int etm_starting_cpu(unsigned int cpu)
 
 	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
 		etm_enable_hw(etmdrvdata[cpu]);
-	spin_unlock(&etmdrvdata[cpu]->spinlock);
 	return 0;
 }
 
@@ -739,10 +736,8 @@ static int etm_dying_cpu(unsigned int cpu)
 	if (!etmdrvdata[cpu])
 		return 0;
 
-	spin_lock(&etmdrvdata[cpu]->spinlock);
 	if (coresight_get_mode(etmdrvdata[cpu]->csdev))
 		etm_disable_hw(etmdrvdata[cpu]);
-	spin_unlock(&etmdrvdata[cpu]->spinlock);
 	return 0;
 }
 
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



From yeoreum.yun at arm.com  Sat Dec 21 09:02:31 2024
From: yeoreum.yun at arm.com (Yeoreum Yun)
Date: Sat, 21 Dec 2024 17:02:31 +0000
Subject: [PATCH v3 0/9] coresight: change some driver' spinlock type to
 raw_spinlock_t
In-Reply-To: <f0c15466-a27f-4cc2-90a1-476ec278d870@arm.com>
References: <20241216115006.415861-1-yeoreum.yun@arm.com>
 <CAJ9a7VhxG_8R6j5uRCzOhLpy4ZmzyVvyW0+ryCcd4w7wqpZ2ew@mail.gmail.com>
 <Z2VJIh2+Z40bZi1e@e129823.arm.com>
 <ac537889-dc0a-4d2e-870b-c5a33279633e@arm.com>
 <Z2VXc/R/nOLGz+Cg@e129823.arm.com>
 <f0c15466-a27f-4cc2-90a1-476ec278d870@arm.com>
Message-ID: <Z2b0p8XiBsa5VM27@e129823.arm.com>

Hi Suzuki.

> On 20/12/2024 11:39, Yeoreum Yun wrote:
> > Hi Suzuki,
> > > On 20/12/2024 10:38, Yeoreum Yun wrote:
> > > > Hi Mike.
> > > >
> > > > > Notably missing is the same changes for the etm3x driver. The ETMv3.x
> > > > > and PTM1.x are supported by this driver, and these trace source
> > > > > variants are also supported in perf in the cs_etm.c code.
> > > >
> > > > But I wonder etmv3 needs to change. Because its spinlock is used only
> > > > via sysfs enable/disable path.
> > > > So, I think it doesn't need to change the lock type.
> > >
> > > ETM3 can be used in perf mode, similar to the ETM4x.
> > >
> > > So, you need to fix it as well.
> >
> > Yes. But etmv3's etmdata->spinlock doesn't used in perf path
> > its usage is only in sysfs interface path.
> > That's why I think it could skip too.
>
> Ok, which I think is a problem, since the sysfs mode could overwrite the
> "config" while perf is preparing the config from the event parsing.
> And we would need it there. So, for the time being, we can accept this
> series, pending other review comments and address this issue separately
>

Here is the patchset fixing above one:
    - https://lore.kernel.org/linux-arm-kernel/20241221165934.1161856-1-yeoreum.yun at arm.com/


From lkp at intel.com  Sat Dec 21 10:19:43 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 22 Dec 2024 02:19:43 +0800
Subject: [soc:soc/dt] BUILD SUCCESS
 45b177c3fe0210e0b113f55d8d4e1fe9c7d02e34
Message-ID: <202412220237.nJk6N3cy-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/dt
branch HEAD: 45b177c3fe0210e0b113f55d8d4e1fe9c7d02e34  Merge tag 'renesas-dts-for-v6.14-tag1' of https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/dt

elapsed time: 1446m

configs tested: 208
configs skipped: 4

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

tested configs:
alpha                             allnoconfig    gcc-14.2.0
alpha                            allyesconfig    clang-20
alpha                               defconfig    gcc-14.2.0
arc                              allmodconfig    gcc-13.2.0
arc                               allnoconfig    gcc-13.2.0
arc                              allyesconfig    gcc-13.2.0
arc                                 defconfig    gcc-14.2.0
arc                            hsdk_defconfig    clang-20
arc                        nsim_700_defconfig    clang-20
arc                   randconfig-001-20241221    gcc-13.2.0
arc                   randconfig-002-20241221    gcc-13.2.0
arm                              allmodconfig    gcc-14.2.0
arm                               allnoconfig    clang-17
arm                              allyesconfig    gcc-14.2.0
arm                                 defconfig    gcc-14.2.0
arm                   randconfig-001-20241221    gcc-13.2.0
arm                   randconfig-001-20241221    gcc-14.2.0
arm                   randconfig-002-20241221    gcc-13.2.0
arm                   randconfig-002-20241221    gcc-14.2.0
arm                   randconfig-003-20241221    gcc-13.2.0
arm                   randconfig-003-20241221    gcc-14.2.0
arm                   randconfig-004-20241221    clang-18
arm                   randconfig-004-20241221    gcc-13.2.0
arm                           sunxi_defconfig    clang-20
arm64                            allmodconfig    clang-18
arm64                             allnoconfig    gcc-14.2.0
arm64                               defconfig    gcc-14.2.0
arm64                 randconfig-001-20241221    clang-18
arm64                 randconfig-001-20241221    gcc-13.2.0
arm64                 randconfig-002-20241221    clang-16
arm64                 randconfig-002-20241221    gcc-13.2.0
arm64                 randconfig-003-20241221    clang-20
arm64                 randconfig-003-20241221    gcc-13.2.0
arm64                 randconfig-004-20241221    gcc-13.2.0
arm64                 randconfig-004-20241221    gcc-14.2.0
csky                             alldefconfig    gcc-14.2.0
csky                              allnoconfig    gcc-14.2.0
csky                                defconfig    gcc-14.2.0
csky                  randconfig-001-20241221    gcc-14.2.0
csky                  randconfig-002-20241221    gcc-14.2.0
hexagon                          allmodconfig    clang-20
hexagon                           allnoconfig    clang-20
hexagon                          allyesconfig    clang-20
hexagon                             defconfig    gcc-14.2.0
hexagon               randconfig-002-20241221    clang-20
i386                             allmodconfig    clang-19
i386                             allmodconfig    gcc-12
i386                              allnoconfig    clang-19
i386                              allnoconfig    gcc-12
i386                             allyesconfig    clang-19
i386                             allyesconfig    gcc-12
i386        buildonly-randconfig-001-20241221    clang-19
i386        buildonly-randconfig-001-20241221    gcc-12
i386        buildonly-randconfig-002-20241221    clang-19
i386        buildonly-randconfig-002-20241221    gcc-12
i386        buildonly-randconfig-003-20241221    clang-19
i386        buildonly-randconfig-004-20241221    clang-19
i386        buildonly-randconfig-005-20241221    clang-19
i386        buildonly-randconfig-006-20241221    clang-19
i386                                defconfig    clang-19
i386                  randconfig-001-20241221    gcc-12
i386                  randconfig-002-20241221    gcc-12
i386                  randconfig-003-20241221    gcc-12
i386                  randconfig-004-20241221    gcc-12
i386                  randconfig-005-20241221    gcc-12
i386                  randconfig-006-20241221    gcc-12
i386                  randconfig-007-20241221    gcc-12
i386                  randconfig-011-20241221    gcc-12
i386                  randconfig-012-20241221    gcc-12
i386                  randconfig-013-20241221    gcc-12
i386                  randconfig-014-20241221    gcc-12
i386                  randconfig-015-20241221    gcc-12
i386                  randconfig-016-20241221    gcc-12
i386                  randconfig-017-20241221    gcc-12
loongarch                        allmodconfig    gcc-14.2.0
loongarch                         allnoconfig    gcc-14.2.0
loongarch                           defconfig    gcc-14.2.0
loongarch             randconfig-001-20241221    gcc-14.2.0
loongarch             randconfig-002-20241221    gcc-14.2.0
m68k                             allmodconfig    gcc-14.2.0
m68k                              allnoconfig    gcc-14.2.0
m68k                             allyesconfig    gcc-14.2.0
m68k                                defconfig    gcc-14.2.0
microblaze                       allmodconfig    gcc-14.2.0
microblaze                        allnoconfig    gcc-14.2.0
microblaze                       allyesconfig    gcc-14.2.0
microblaze                          defconfig    gcc-14.2.0
mips                              allnoconfig    gcc-14.2.0
nios2                             allnoconfig    gcc-14.2.0
nios2                               defconfig    gcc-14.2.0
nios2                 randconfig-001-20241221    gcc-14.2.0
nios2                 randconfig-002-20241221    gcc-14.2.0
openrisc                          allnoconfig    clang-20
openrisc                         allyesconfig    gcc-14.2.0
openrisc                            defconfig    gcc-12
parisc                           allmodconfig    gcc-14.2.0
parisc                            allnoconfig    clang-20
parisc                           allyesconfig    gcc-14.2.0
parisc                              defconfig    gcc-12
parisc                randconfig-001-20241221    gcc-14.2.0
parisc                randconfig-002-20241221    gcc-14.2.0
parisc64                            defconfig    gcc-14.2.0
powerpc                          allmodconfig    gcc-14.2.0
powerpc                           allnoconfig    clang-20
powerpc                          allyesconfig    clang-16
powerpc                          allyesconfig    gcc-14.2.0
powerpc                 canyonlands_defconfig    clang-20
powerpc                      cm5200_defconfig    clang-20
powerpc                    gamecube_defconfig    clang-20
powerpc                        icon_defconfig    clang-20
powerpc                      katmai_defconfig    gcc-14.2.0
powerpc                   lite5200b_defconfig    gcc-14.2.0
powerpc                 mpc8315_rdb_defconfig    gcc-14.2.0
powerpc                  mpc866_ads_defconfig    clang-20
powerpc                     ppa8548_defconfig    gcc-14.2.0
powerpc               randconfig-001-20241221    gcc-14.2.0
powerpc               randconfig-002-20241221    gcc-14.2.0
powerpc               randconfig-003-20241221    gcc-14.2.0
powerpc64             randconfig-001-20241221    gcc-14.2.0
powerpc64             randconfig-002-20241221    gcc-14.2.0
powerpc64             randconfig-003-20241221    clang-18
riscv                            allmodconfig    clang-20
riscv                            allmodconfig    gcc-14.2.0
riscv                             allnoconfig    clang-20
riscv                            allyesconfig    clang-20
riscv                            allyesconfig    gcc-14.2.0
riscv                               defconfig    gcc-12
riscv                 randconfig-001-20241221    clang-18
riscv                 randconfig-001-20241221    gcc-14.2.0
riscv                 randconfig-002-20241221    clang-18
riscv                 randconfig-002-20241221    gcc-14.2.0
s390                             allmodconfig    clang-19
s390                             allmodconfig    gcc-14.2.0
s390                              allnoconfig    clang-20
s390                             allyesconfig    gcc-14.2.0
s390                                defconfig    gcc-12
s390                  randconfig-001-20241221    clang-18
s390                  randconfig-001-20241221    gcc-14.2.0
s390                  randconfig-002-20241221    clang-18
s390                  randconfig-002-20241221    gcc-14.2.0
sh                               allmodconfig    gcc-14.2.0
sh                                allnoconfig    gcc-14.2.0
sh                               allyesconfig    gcc-14.2.0
sh                         apsh4a3a_defconfig    gcc-14.2.0
sh                                  defconfig    gcc-12
sh                    randconfig-001-20241221    clang-18
sh                    randconfig-001-20241221    gcc-14.2.0
sh                    randconfig-002-20241221    clang-18
sh                    randconfig-002-20241221    gcc-14.2.0
sh                   sh7724_generic_defconfig    gcc-14.2.0
sparc                            allmodconfig    gcc-14.2.0
sparc                             allnoconfig    gcc-14.2.0
sparc                 randconfig-001-20241221    clang-18
sparc                 randconfig-001-20241221    gcc-14.2.0
sparc                 randconfig-002-20241221    clang-18
sparc                 randconfig-002-20241221    gcc-14.2.0
sparc64                             defconfig    gcc-12
sparc64               randconfig-001-20241221    clang-18
sparc64               randconfig-001-20241221    gcc-14.2.0
sparc64               randconfig-002-20241221    clang-18
sparc64               randconfig-002-20241221    gcc-14.2.0
um                               allmodconfig    clang-20
um                                allnoconfig    clang-20
um                               allyesconfig    clang-20
um                                  defconfig    gcc-12
um                             i386_defconfig    gcc-12
um                    randconfig-001-20241221    clang-18
um                    randconfig-002-20241221    clang-18
um                    randconfig-002-20241221    gcc-12
um                           x86_64_defconfig    gcc-12
x86_64                            allnoconfig    clang-19
x86_64                           allyesconfig    clang-19
x86_64      buildonly-randconfig-001-20241221    gcc-12
x86_64      buildonly-randconfig-002-20241221    gcc-12
x86_64      buildonly-randconfig-003-20241221    gcc-12
x86_64      buildonly-randconfig-004-20241221    gcc-12
x86_64      buildonly-randconfig-005-20241221    gcc-11
x86_64      buildonly-randconfig-005-20241221    gcc-12
x86_64      buildonly-randconfig-006-20241221    gcc-12
x86_64                              defconfig    clang-19
x86_64                              defconfig    gcc-11
x86_64                                  kexec    clang-19
x86_64                randconfig-001-20241221    gcc-11
x86_64                randconfig-002-20241221    gcc-11
x86_64                randconfig-003-20241221    gcc-11
x86_64                randconfig-004-20241221    gcc-11
x86_64                randconfig-005-20241221    gcc-11
x86_64                randconfig-006-20241221    gcc-11
x86_64                randconfig-007-20241221    gcc-11
x86_64                randconfig-008-20241221    gcc-11
x86_64                randconfig-071-20241221    gcc-12
x86_64                randconfig-072-20241221    gcc-12
x86_64                randconfig-073-20241221    gcc-12
x86_64                randconfig-074-20241221    gcc-12
x86_64                randconfig-075-20241221    gcc-12
x86_64                randconfig-076-20241221    gcc-12
x86_64                randconfig-077-20241221    gcc-12
x86_64                randconfig-078-20241221    gcc-12
x86_64                               rhel-9.4    clang-19
x86_64                           rhel-9.4-bpf    clang-19
x86_64                         rhel-9.4-kunit    clang-19
x86_64                           rhel-9.4-ltp    clang-19
x86_64                          rhel-9.4-rust    clang-19
xtensa                            allnoconfig    gcc-14.2.0
xtensa                randconfig-001-20241221    clang-18
xtensa                randconfig-001-20241221    gcc-14.2.0
xtensa                randconfig-002-20241221    clang-18
xtensa                randconfig-002-20241221    gcc-14.2.0

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


From lkp at intel.com  Sat Dec 21 10:19:21 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 22 Dec 2024 02:19:21 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS
 a31ffd6ed5ee994e1c04dc794499a0c04618dc55
Message-ID: <202412220215.Cy3XSl95-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: a31ffd6ed5ee994e1c04dc794499a0c04618dc55  Merge tag 'arm-soc/for-6.13/devicetree-arm64-fixes' of https://github.com/Broadcom/stblinux into arm/fixes

elapsed time: 1446m

configs tested: 209
configs skipped: 4

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

tested configs:
alpha                             allnoconfig    gcc-14.2.0
alpha                            allyesconfig    clang-20
alpha                               defconfig    gcc-14.2.0
arc                              allmodconfig    gcc-13.2.0
arc                               allnoconfig    gcc-13.2.0
arc                               allnoconfig    gcc-14.2.0
arc                              allyesconfig    gcc-13.2.0
arc                                 defconfig    gcc-14.2.0
arc                            hsdk_defconfig    clang-20
arc                        nsim_700_defconfig    clang-20
arc                   randconfig-001-20241221    gcc-13.2.0
arc                   randconfig-002-20241221    gcc-13.2.0
arm                              allmodconfig    gcc-14.2.0
arm                               allnoconfig    clang-17
arm                               allnoconfig    gcc-14.2.0
arm                              allyesconfig    gcc-14.2.0
arm                                 defconfig    gcc-14.2.0
arm                   randconfig-001-20241221    gcc-13.2.0
arm                   randconfig-001-20241221    gcc-14.2.0
arm                   randconfig-002-20241221    gcc-13.2.0
arm                   randconfig-002-20241221    gcc-14.2.0
arm                   randconfig-003-20241221    gcc-13.2.0
arm                   randconfig-003-20241221    gcc-14.2.0
arm                   randconfig-004-20241221    clang-18
arm                   randconfig-004-20241221    gcc-13.2.0
arm                           sunxi_defconfig    clang-20
arm64                            allmodconfig    clang-18
arm64                             allnoconfig    gcc-14.2.0
arm64                               defconfig    gcc-14.2.0
arm64                 randconfig-001-20241221    clang-18
arm64                 randconfig-001-20241221    gcc-13.2.0
arm64                 randconfig-002-20241221    clang-16
arm64                 randconfig-002-20241221    gcc-13.2.0
arm64                 randconfig-003-20241221    clang-20
arm64                 randconfig-003-20241221    gcc-13.2.0
arm64                 randconfig-004-20241221    gcc-13.2.0
arm64                 randconfig-004-20241221    gcc-14.2.0
csky                             alldefconfig    gcc-14.2.0
csky                              allnoconfig    gcc-14.2.0
csky                                defconfig    gcc-14.2.0
csky                  randconfig-001-20241221    gcc-14.2.0
csky                  randconfig-002-20241221    gcc-14.2.0
hexagon                          allmodconfig    clang-20
hexagon                           allnoconfig    clang-20
hexagon                           allnoconfig    gcc-14.2.0
hexagon                          allyesconfig    clang-20
hexagon                             defconfig    gcc-14.2.0
hexagon               randconfig-002-20241221    clang-20
i386                             allmodconfig    clang-19
i386                             allmodconfig    gcc-12
i386                              allnoconfig    clang-19
i386                              allnoconfig    gcc-12
i386                             allyesconfig    clang-19
i386                             allyesconfig    gcc-12
i386        buildonly-randconfig-001-20241221    clang-19
i386        buildonly-randconfig-001-20241221    gcc-12
i386        buildonly-randconfig-002-20241221    clang-19
i386        buildonly-randconfig-002-20241221    gcc-12
i386        buildonly-randconfig-003-20241221    clang-19
i386        buildonly-randconfig-004-20241221    clang-19
i386        buildonly-randconfig-005-20241221    clang-19
i386        buildonly-randconfig-006-20241221    clang-19
i386                                defconfig    clang-19
i386                  randconfig-001-20241221    gcc-12
i386                  randconfig-002-20241221    gcc-12
i386                  randconfig-003-20241221    gcc-12
i386                  randconfig-004-20241221    gcc-12
i386                  randconfig-005-20241221    gcc-12
i386                  randconfig-006-20241221    gcc-12
i386                  randconfig-007-20241221    gcc-12
i386                  randconfig-011-20241221    gcc-12
i386                  randconfig-012-20241221    gcc-12
i386                  randconfig-013-20241221    gcc-12
i386                  randconfig-014-20241221    gcc-12
i386                  randconfig-015-20241221    gcc-12
i386                  randconfig-016-20241221    gcc-12
i386                  randconfig-017-20241221    gcc-12
loongarch                        allmodconfig    gcc-14.2.0
loongarch                         allnoconfig    gcc-14.2.0
loongarch                           defconfig    gcc-14.2.0
loongarch             randconfig-001-20241221    gcc-14.2.0
loongarch             randconfig-002-20241221    gcc-14.2.0
m68k                             allmodconfig    gcc-14.2.0
m68k                              allnoconfig    gcc-14.2.0
m68k                             allyesconfig    gcc-14.2.0
m68k                                defconfig    gcc-14.2.0
microblaze                        allnoconfig    gcc-14.2.0
microblaze                          defconfig    gcc-14.2.0
mips                              allnoconfig    gcc-14.2.0
nios2                             allnoconfig    gcc-14.2.0
nios2                               defconfig    gcc-14.2.0
nios2                 randconfig-001-20241221    gcc-14.2.0
nios2                 randconfig-002-20241221    gcc-14.2.0
openrisc                          allnoconfig    clang-20
openrisc                         allyesconfig    gcc-14.2.0
openrisc                            defconfig    gcc-12
parisc                           allmodconfig    gcc-14.2.0
parisc                            allnoconfig    clang-20
parisc                           allyesconfig    gcc-14.2.0
parisc                              defconfig    gcc-12
parisc                randconfig-001-20241221    gcc-14.2.0
parisc                randconfig-002-20241221    gcc-14.2.0
parisc64                            defconfig    gcc-14.2.0
powerpc                          allmodconfig    gcc-14.2.0
powerpc                           allnoconfig    clang-20
powerpc                          allyesconfig    clang-16
powerpc                          allyesconfig    gcc-14.2.0
powerpc                 canyonlands_defconfig    clang-20
powerpc                      cm5200_defconfig    clang-20
powerpc                    gamecube_defconfig    clang-20
powerpc                        icon_defconfig    clang-20
powerpc                      katmai_defconfig    gcc-14.2.0
powerpc                   lite5200b_defconfig    gcc-14.2.0
powerpc                 mpc8315_rdb_defconfig    gcc-14.2.0
powerpc                  mpc866_ads_defconfig    clang-20
powerpc                     ppa8548_defconfig    gcc-14.2.0
powerpc               randconfig-001-20241221    gcc-14.2.0
powerpc               randconfig-002-20241221    gcc-14.2.0
powerpc               randconfig-003-20241221    gcc-14.2.0
powerpc64             randconfig-001-20241221    gcc-14.2.0
powerpc64             randconfig-002-20241221    gcc-14.2.0
powerpc64             randconfig-003-20241221    clang-18
riscv                            allmodconfig    clang-20
riscv                            allmodconfig    gcc-14.2.0
riscv                             allnoconfig    clang-20
riscv                            allyesconfig    clang-20
riscv                            allyesconfig    gcc-14.2.0
riscv                               defconfig    gcc-12
riscv                 randconfig-001-20241221    clang-18
riscv                 randconfig-001-20241221    gcc-14.2.0
riscv                 randconfig-002-20241221    clang-18
riscv                 randconfig-002-20241221    gcc-14.2.0
s390                             allmodconfig    clang-19
s390                             allmodconfig    gcc-14.2.0
s390                              allnoconfig    clang-20
s390                             allyesconfig    gcc-14.2.0
s390                                defconfig    gcc-12
s390                  randconfig-001-20241221    clang-18
s390                  randconfig-001-20241221    gcc-14.2.0
s390                  randconfig-002-20241221    clang-18
s390                  randconfig-002-20241221    gcc-14.2.0
sh                               allmodconfig    gcc-14.2.0
sh                                allnoconfig    gcc-14.2.0
sh                               allyesconfig    gcc-14.2.0
sh                         apsh4a3a_defconfig    gcc-14.2.0
sh                                  defconfig    gcc-12
sh                    randconfig-001-20241221    clang-18
sh                    randconfig-001-20241221    gcc-14.2.0
sh                    randconfig-002-20241221    clang-18
sh                    randconfig-002-20241221    gcc-14.2.0
sh                   sh7724_generic_defconfig    gcc-14.2.0
sparc                            allmodconfig    gcc-14.2.0
sparc                             allnoconfig    gcc-14.2.0
sparc                 randconfig-001-20241221    clang-18
sparc                 randconfig-001-20241221    gcc-14.2.0
sparc                 randconfig-002-20241221    clang-18
sparc                 randconfig-002-20241221    gcc-14.2.0
sparc64                             defconfig    gcc-12
sparc64               randconfig-001-20241221    clang-18
sparc64               randconfig-001-20241221    gcc-14.2.0
sparc64               randconfig-002-20241221    clang-18
sparc64               randconfig-002-20241221    gcc-14.2.0
um                               allmodconfig    clang-20
um                                allnoconfig    clang-20
um                               allyesconfig    clang-20
um                                  defconfig    gcc-12
um                             i386_defconfig    gcc-12
um                    randconfig-001-20241221    clang-18
um                    randconfig-002-20241221    clang-18
um                    randconfig-002-20241221    gcc-12
um                           x86_64_defconfig    gcc-12
x86_64                            allnoconfig    clang-19
x86_64                           allyesconfig    clang-19
x86_64      buildonly-randconfig-001-20241221    gcc-12
x86_64      buildonly-randconfig-002-20241221    gcc-12
x86_64      buildonly-randconfig-003-20241221    gcc-12
x86_64      buildonly-randconfig-004-20241221    gcc-12
x86_64      buildonly-randconfig-005-20241221    gcc-11
x86_64      buildonly-randconfig-005-20241221    gcc-12
x86_64      buildonly-randconfig-006-20241221    gcc-12
x86_64                              defconfig    clang-19
x86_64                              defconfig    gcc-11
x86_64                                  kexec    clang-19
x86_64                randconfig-001-20241221    gcc-11
x86_64                randconfig-002-20241221    gcc-11
x86_64                randconfig-003-20241221    gcc-11
x86_64                randconfig-004-20241221    gcc-11
x86_64                randconfig-005-20241221    gcc-11
x86_64                randconfig-006-20241221    gcc-11
x86_64                randconfig-007-20241221    gcc-11
x86_64                randconfig-008-20241221    gcc-11
x86_64                randconfig-071-20241221    gcc-12
x86_64                randconfig-072-20241221    gcc-12
x86_64                randconfig-073-20241221    gcc-12
x86_64                randconfig-074-20241221    gcc-12
x86_64                randconfig-075-20241221    gcc-12
x86_64                randconfig-076-20241221    gcc-12
x86_64                randconfig-077-20241221    gcc-12
x86_64                randconfig-078-20241221    gcc-12
x86_64                               rhel-9.4    clang-19
x86_64                           rhel-9.4-bpf    clang-19
x86_64                         rhel-9.4-kunit    clang-19
x86_64                           rhel-9.4-ltp    clang-19
x86_64                          rhel-9.4-rust    clang-19
xtensa                            allnoconfig    gcc-14.2.0
xtensa                randconfig-001-20241221    clang-18
xtensa                randconfig-001-20241221    gcc-14.2.0
xtensa                randconfig-002-20241221    clang-18
xtensa                randconfig-002-20241221    gcc-14.2.0

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


From lkp at intel.com  Sat Dec 21 10:19:56 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 22 Dec 2024 02:19:56 +0800
Subject: [soc:soc/drivers] BUILD SUCCESS
 220fcc13c0937d7e2b5d0cbfcfa1d45f0d7d896a
Message-ID: <202412220250.bqSFRXvI-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/drivers
branch HEAD: 220fcc13c0937d7e2b5d0cbfcfa1d45f0d7d896a  Merge tag 'renesas-drivers-for-v6.14-tag1' of https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/drivers

elapsed time: 1447m

configs tested: 209
configs skipped: 4

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

tested configs:
alpha                             allnoconfig    gcc-14.2.0
alpha                            allyesconfig    clang-20
alpha                               defconfig    gcc-14.2.0
arc                              allmodconfig    gcc-13.2.0
arc                               allnoconfig    gcc-13.2.0
arc                               allnoconfig    gcc-14.2.0
arc                              allyesconfig    gcc-13.2.0
arc                                 defconfig    gcc-14.2.0
arc                            hsdk_defconfig    clang-20
arc                        nsim_700_defconfig    clang-20
arc                   randconfig-001-20241221    gcc-13.2.0
arc                   randconfig-002-20241221    gcc-13.2.0
arm                              allmodconfig    gcc-14.2.0
arm                               allnoconfig    clang-17
arm                               allnoconfig    gcc-14.2.0
arm                              allyesconfig    gcc-14.2.0
arm                                 defconfig    gcc-14.2.0
arm                   randconfig-001-20241221    gcc-13.2.0
arm                   randconfig-001-20241221    gcc-14.2.0
arm                   randconfig-002-20241221    gcc-13.2.0
arm                   randconfig-002-20241221    gcc-14.2.0
arm                   randconfig-003-20241221    gcc-13.2.0
arm                   randconfig-003-20241221    gcc-14.2.0
arm                   randconfig-004-20241221    clang-18
arm                   randconfig-004-20241221    gcc-13.2.0
arm                           sunxi_defconfig    clang-20
arm64                            allmodconfig    clang-18
arm64                             allnoconfig    gcc-14.2.0
arm64                               defconfig    gcc-14.2.0
arm64                 randconfig-001-20241221    clang-18
arm64                 randconfig-001-20241221    gcc-13.2.0
arm64                 randconfig-002-20241221    clang-16
arm64                 randconfig-002-20241221    gcc-13.2.0
arm64                 randconfig-003-20241221    clang-20
arm64                 randconfig-003-20241221    gcc-13.2.0
arm64                 randconfig-004-20241221    gcc-13.2.0
arm64                 randconfig-004-20241221    gcc-14.2.0
csky                             alldefconfig    gcc-14.2.0
csky                              allnoconfig    gcc-14.2.0
csky                                defconfig    gcc-14.2.0
csky                  randconfig-001-20241221    gcc-14.2.0
csky                  randconfig-002-20241221    gcc-14.2.0
hexagon                          allmodconfig    clang-20
hexagon                           allnoconfig    clang-20
hexagon                           allnoconfig    gcc-14.2.0
hexagon                          allyesconfig    clang-20
hexagon                             defconfig    gcc-14.2.0
hexagon               randconfig-002-20241221    clang-20
i386                             allmodconfig    clang-19
i386                             allmodconfig    gcc-12
i386                              allnoconfig    clang-19
i386                              allnoconfig    gcc-12
i386                             allyesconfig    clang-19
i386                             allyesconfig    gcc-12
i386        buildonly-randconfig-001-20241221    clang-19
i386        buildonly-randconfig-001-20241221    gcc-12
i386        buildonly-randconfig-002-20241221    clang-19
i386        buildonly-randconfig-002-20241221    gcc-12
i386        buildonly-randconfig-003-20241221    clang-19
i386        buildonly-randconfig-004-20241221    clang-19
i386        buildonly-randconfig-005-20241221    clang-19
i386        buildonly-randconfig-006-20241221    clang-19
i386                                defconfig    clang-19
i386                  randconfig-001-20241221    gcc-12
i386                  randconfig-002-20241221    gcc-12
i386                  randconfig-003-20241221    gcc-12
i386                  randconfig-004-20241221    gcc-12
i386                  randconfig-005-20241221    gcc-12
i386                  randconfig-006-20241221    gcc-12
i386                  randconfig-007-20241221    gcc-12
i386                  randconfig-011-20241221    gcc-12
i386                  randconfig-012-20241221    gcc-12
i386                  randconfig-013-20241221    gcc-12
i386                  randconfig-014-20241221    gcc-12
i386                  randconfig-015-20241221    gcc-12
i386                  randconfig-016-20241221    gcc-12
i386                  randconfig-017-20241221    gcc-12
loongarch                        allmodconfig    gcc-14.2.0
loongarch                         allnoconfig    gcc-14.2.0
loongarch                           defconfig    gcc-14.2.0
loongarch             randconfig-001-20241221    gcc-14.2.0
loongarch             randconfig-002-20241221    gcc-14.2.0
m68k                             allmodconfig    gcc-14.2.0
m68k                              allnoconfig    gcc-14.2.0
m68k                             allyesconfig    gcc-14.2.0
m68k                                defconfig    gcc-14.2.0
microblaze                        allnoconfig    gcc-14.2.0
microblaze                          defconfig    gcc-14.2.0
mips                              allnoconfig    gcc-14.2.0
nios2                             allnoconfig    gcc-14.2.0
nios2                               defconfig    gcc-14.2.0
nios2                 randconfig-001-20241221    gcc-14.2.0
nios2                 randconfig-002-20241221    gcc-14.2.0
openrisc                          allnoconfig    clang-20
openrisc                         allyesconfig    gcc-14.2.0
openrisc                            defconfig    gcc-12
parisc                           allmodconfig    gcc-14.2.0
parisc                            allnoconfig    clang-20
parisc                           allyesconfig    gcc-14.2.0
parisc                              defconfig    gcc-12
parisc                randconfig-001-20241221    gcc-14.2.0
parisc                randconfig-002-20241221    gcc-14.2.0
parisc64                            defconfig    gcc-14.2.0
powerpc                          allmodconfig    gcc-14.2.0
powerpc                           allnoconfig    clang-20
powerpc                          allyesconfig    clang-16
powerpc                          allyesconfig    gcc-14.2.0
powerpc                 canyonlands_defconfig    clang-20
powerpc                      cm5200_defconfig    clang-20
powerpc                    gamecube_defconfig    clang-20
powerpc                        icon_defconfig    clang-20
powerpc                      katmai_defconfig    gcc-14.2.0
powerpc                   lite5200b_defconfig    gcc-14.2.0
powerpc                 mpc8315_rdb_defconfig    gcc-14.2.0
powerpc                  mpc866_ads_defconfig    clang-20
powerpc                     ppa8548_defconfig    gcc-14.2.0
powerpc               randconfig-001-20241221    gcc-14.2.0
powerpc               randconfig-002-20241221    gcc-14.2.0
powerpc               randconfig-003-20241221    gcc-14.2.0
powerpc64             randconfig-001-20241221    gcc-14.2.0
powerpc64             randconfig-002-20241221    gcc-14.2.0
powerpc64             randconfig-003-20241221    clang-18
riscv                            allmodconfig    clang-20
riscv                            allmodconfig    gcc-14.2.0
riscv                             allnoconfig    clang-20
riscv                            allyesconfig    clang-20
riscv                            allyesconfig    gcc-14.2.0
riscv                               defconfig    gcc-12
riscv                 randconfig-001-20241221    clang-18
riscv                 randconfig-001-20241221    gcc-14.2.0
riscv                 randconfig-002-20241221    clang-18
riscv                 randconfig-002-20241221    gcc-14.2.0
s390                             allmodconfig    clang-19
s390                             allmodconfig    gcc-14.2.0
s390                              allnoconfig    clang-20
s390                             allyesconfig    gcc-14.2.0
s390                                defconfig    gcc-12
s390                  randconfig-001-20241221    clang-18
s390                  randconfig-001-20241221    gcc-14.2.0
s390                  randconfig-002-20241221    clang-18
s390                  randconfig-002-20241221    gcc-14.2.0
sh                               allmodconfig    gcc-14.2.0
sh                                allnoconfig    gcc-14.2.0
sh                               allyesconfig    gcc-14.2.0
sh                         apsh4a3a_defconfig    gcc-14.2.0
sh                                  defconfig    gcc-12
sh                    randconfig-001-20241221    clang-18
sh                    randconfig-001-20241221    gcc-14.2.0
sh                    randconfig-002-20241221    clang-18
sh                    randconfig-002-20241221    gcc-14.2.0
sh                   sh7724_generic_defconfig    gcc-14.2.0
sparc                            allmodconfig    gcc-14.2.0
sparc                             allnoconfig    gcc-14.2.0
sparc                 randconfig-001-20241221    clang-18
sparc                 randconfig-001-20241221    gcc-14.2.0
sparc                 randconfig-002-20241221    clang-18
sparc                 randconfig-002-20241221    gcc-14.2.0
sparc64                             defconfig    gcc-12
sparc64               randconfig-001-20241221    clang-18
sparc64               randconfig-001-20241221    gcc-14.2.0
sparc64               randconfig-002-20241221    clang-18
sparc64               randconfig-002-20241221    gcc-14.2.0
um                               allmodconfig    clang-20
um                                allnoconfig    clang-20
um                               allyesconfig    clang-20
um                                  defconfig    gcc-12
um                             i386_defconfig    gcc-12
um                    randconfig-001-20241221    clang-18
um                    randconfig-002-20241221    clang-18
um                    randconfig-002-20241221    gcc-12
um                           x86_64_defconfig    gcc-12
x86_64                            allnoconfig    clang-19
x86_64                           allyesconfig    clang-19
x86_64      buildonly-randconfig-001-20241221    gcc-12
x86_64      buildonly-randconfig-002-20241221    gcc-12
x86_64      buildonly-randconfig-003-20241221    gcc-12
x86_64      buildonly-randconfig-004-20241221    gcc-12
x86_64      buildonly-randconfig-005-20241221    gcc-11
x86_64      buildonly-randconfig-005-20241221    gcc-12
x86_64      buildonly-randconfig-006-20241221    gcc-12
x86_64                              defconfig    clang-19
x86_64                              defconfig    gcc-11
x86_64                                  kexec    clang-19
x86_64                randconfig-001-20241221    gcc-11
x86_64                randconfig-002-20241221    gcc-11
x86_64                randconfig-003-20241221    gcc-11
x86_64                randconfig-004-20241221    gcc-11
x86_64                randconfig-005-20241221    gcc-11
x86_64                randconfig-006-20241221    gcc-11
x86_64                randconfig-007-20241221    gcc-11
x86_64                randconfig-008-20241221    gcc-11
x86_64                randconfig-071-20241221    gcc-12
x86_64                randconfig-072-20241221    gcc-12
x86_64                randconfig-073-20241221    gcc-12
x86_64                randconfig-074-20241221    gcc-12
x86_64                randconfig-075-20241221    gcc-12
x86_64                randconfig-076-20241221    gcc-12
x86_64                randconfig-077-20241221    gcc-12
x86_64                randconfig-078-20241221    gcc-12
x86_64                               rhel-9.4    clang-19
x86_64                           rhel-9.4-bpf    clang-19
x86_64                         rhel-9.4-kunit    clang-19
x86_64                           rhel-9.4-ltp    clang-19
x86_64                          rhel-9.4-rust    clang-19
xtensa                            allnoconfig    gcc-14.2.0
xtensa                randconfig-001-20241221    clang-18
xtensa                randconfig-001-20241221    gcc-14.2.0
xtensa                randconfig-002-20241221    clang-18
xtensa                randconfig-002-20241221    gcc-14.2.0

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


From lkp at intel.com  Sat Dec 21 10:20:27 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 22 Dec 2024 02:20:27 +0800
Subject: [soc:for-next] BUILD SUCCESS
 b5d57dcb214665c17dbd8606797a36a2048ae345
Message-ID: <202412220221.VOgu1nPI-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: b5d57dcb214665c17dbd8606797a36a2048ae345  soc: document merges

elapsed time: 1447m

configs tested: 104
configs skipped: 3

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

tested configs:
alpha                            alldefconfig    gcc-14.2.0
alpha                             allnoconfig    gcc-14.2.0
alpha                               defconfig    gcc-14.2.0
arc                              allmodconfig    gcc-13.2.0
arc                               allnoconfig    gcc-13.2.0
arc                              allyesconfig    gcc-13.2.0
arc                                 defconfig    gcc-13.2.0
arc                   randconfig-001-20241221    gcc-13.2.0
arc                   randconfig-002-20241221    gcc-13.2.0
arm                              alldefconfig    gcc-14.2.0
arm                               allnoconfig    clang-17
arm                              allyesconfig    gcc-14.2.0
arm                   randconfig-001-20241221    gcc-14.2.0
arm                   randconfig-002-20241221    gcc-14.2.0
arm                   randconfig-003-20241221    gcc-14.2.0
arm                   randconfig-004-20241221    clang-18
arm                          sp7021_defconfig    gcc-14.2.0
arm64                            allmodconfig    clang-18
arm64                             allnoconfig    gcc-14.2.0
arm64                 randconfig-001-20241221    clang-18
arm64                 randconfig-002-20241221    clang-16
arm64                 randconfig-003-20241221    clang-20
arm64                 randconfig-004-20241221    gcc-14.2.0
csky                              allnoconfig    gcc-14.2.0
csky                  randconfig-001-20241221    gcc-14.2.0
csky                  randconfig-002-20241221    gcc-14.2.0
hexagon                           allnoconfig    clang-20
hexagon               randconfig-002-20241221    clang-20
i386                             allmodconfig    gcc-12
i386                              allnoconfig    gcc-12
i386                             allyesconfig    gcc-12
i386        buildonly-randconfig-001-20241221    gcc-12
i386        buildonly-randconfig-002-20241221    gcc-12
i386        buildonly-randconfig-003-20241221    clang-19
i386        buildonly-randconfig-004-20241221    clang-19
i386        buildonly-randconfig-005-20241221    clang-19
i386        buildonly-randconfig-006-20241221    clang-19
i386                                defconfig    clang-19
loongarch                        allmodconfig    gcc-14.2.0
loongarch                         allnoconfig    gcc-14.2.0
loongarch             randconfig-001-20241221    gcc-14.2.0
loongarch             randconfig-002-20241221    gcc-14.2.0
m68k                             allmodconfig    gcc-14.2.0
m68k                              allnoconfig    gcc-14.2.0
m68k                             allyesconfig    gcc-14.2.0
microblaze                        allnoconfig    gcc-14.2.0
mips                              allnoconfig    gcc-14.2.0
nios2                             allnoconfig    gcc-14.2.0
nios2                 randconfig-001-20241221    gcc-14.2.0
nios2                 randconfig-002-20241221    gcc-14.2.0
openrisc                          allnoconfig    gcc-14.2.0
openrisc                         allyesconfig    gcc-14.2.0
parisc                           allmodconfig    gcc-14.2.0
parisc                            allnoconfig    gcc-14.2.0
parisc                           allyesconfig    gcc-14.2.0
parisc                randconfig-001-20241221    gcc-14.2.0
parisc                randconfig-002-20241221    gcc-14.2.0
powerpc                          allmodconfig    gcc-14.2.0
powerpc                           allnoconfig    gcc-14.2.0
powerpc                      mgcoge_defconfig    clang-20
powerpc               randconfig-001-20241221    gcc-14.2.0
powerpc               randconfig-002-20241221    gcc-14.2.0
powerpc               randconfig-003-20241221    gcc-14.2.0
powerpc                    socrates_defconfig    gcc-14.2.0
powerpc                     tqm5200_defconfig    gcc-14.2.0
powerpc64             randconfig-001-20241221    gcc-14.2.0
powerpc64             randconfig-002-20241221    gcc-14.2.0
powerpc64             randconfig-003-20241221    clang-18
riscv                             allnoconfig    gcc-14.2.0
riscv                 randconfig-001-20241221    gcc-14.2.0
riscv                 randconfig-002-20241221    gcc-14.2.0
s390                             allmodconfig    clang-19
s390                              allnoconfig    clang-20
s390                             allyesconfig    gcc-14.2.0
s390                  randconfig-001-20241221    gcc-14.2.0
s390                  randconfig-002-20241221    gcc-14.2.0
s390                       zfcpdump_defconfig    clang-19
sh                               allmodconfig    gcc-14.2.0
sh                                allnoconfig    gcc-14.2.0
sh                               allyesconfig    gcc-14.2.0
sh                     magicpanelr2_defconfig    gcc-14.2.0
sh                    randconfig-001-20241221    gcc-14.2.0
sh                    randconfig-002-20241221    gcc-14.2.0
sparc                            allmodconfig    gcc-14.2.0
sparc                             allnoconfig    gcc-14.2.0
sparc                 randconfig-001-20241221    gcc-14.2.0
sparc                 randconfig-002-20241221    gcc-14.2.0
sparc64               randconfig-001-20241221    gcc-14.2.0
sparc64               randconfig-002-20241221    gcc-14.2.0
um                                allnoconfig    clang-18
um                    randconfig-001-20241221    clang-18
um                    randconfig-002-20241221    gcc-12
x86_64                            allnoconfig    clang-19
x86_64                           allyesconfig    clang-19
x86_64      buildonly-randconfig-001-20241221    gcc-12
x86_64      buildonly-randconfig-002-20241221    gcc-12
x86_64      buildonly-randconfig-003-20241221    gcc-12
x86_64      buildonly-randconfig-004-20241221    gcc-12
x86_64      buildonly-randconfig-005-20241221    gcc-11
x86_64      buildonly-randconfig-006-20241221    gcc-12
x86_64                              defconfig    gcc-11
xtensa                            allnoconfig    gcc-14.2.0
xtensa                randconfig-001-20241221    gcc-14.2.0
xtensa                randconfig-002-20241221    gcc-14.2.0

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


From lkp at intel.com  Sat Dec 21 10:34:45 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 22 Dec 2024 02:34:45 +0800
Subject: [PATCH 5/7] media: platform: Add Raspberry Pi HEVC decoder driver
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e@raspberrypi.com>
Message-ID: <202412220238.0kZEBbMb-lkp@intel.com>

Hi Dave,

kernel test robot noticed the following build errors:

[auto build test ERROR on e90c9612ac3969cb8206029a26bcd2b6f5d4a942]

url:    https://github.com/intel-lab-lkp/linux/commits/Dave-Stevenson/RFC-media-Add-media_request_-pin-unpin-API/20241221-002633
base:   e90c9612ac3969cb8206029a26bcd2b6f5d4a942
patch link:    https://lore.kernel.org/r/20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e%40raspberrypi.com
patch subject: [PATCH 5/7] media: platform: Add Raspberry Pi HEVC decoder driver
config: sh-allyesconfig (https://download.01.org/0day-ci/archive/20241222/202412220238.0kZEBbMb-lkp at intel.com/config)
compiler: sh4-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241222/202412220238.0kZEBbMb-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/202412220238.0kZEBbMb-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/media/platform/raspberrypi/hevc_dec/hevc_d.c:24:10: fatal error: hevc_d_h265.h: No such file or directory
      24 | #include "hevc_d_h265.h"
         |          ^~~~~~~~~~~~~~~
   compilation terminated.
--
>> drivers/media/platform/raspberrypi/hevc_dec/hevc_d_video.c:21:10: fatal error: hevc_d_h265.h: No such file or directory
      21 | #include "hevc_d_h265.h"
         |          ^~~~~~~~~~~~~~~
   compilation terminated.
--
>> drivers/media/platform/raspberrypi/hevc_dec/hevc_d_h265.c:20:10: fatal error: hevc_d_h265.h: No such file or directory
      20 | #include "hevc_d_h265.h"
         |          ^~~~~~~~~~~~~~~
   compilation terminated.


vim +24 drivers/media/platform/raspberrypi/hevc_dec/hevc_d.c

    22	
    23	#include "hevc_d.h"
  > 24	#include "hevc_d_h265.h"
    25	#include "hevc_d_video.h"
    26	#include "hevc_d_hw.h"
    27	

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


From lkp at intel.com  Sat Dec 21 10:45:57 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 22 Dec 2024 02:45:57 +0800
Subject: [PATCH 5/7] media: platform: Add Raspberry Pi HEVC decoder driver
In-Reply-To: <20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e@raspberrypi.com>
References: <20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e@raspberrypi.com>
Message-ID: <202412220205.Gf2N9CUb-lkp@intel.com>

Hi Dave,

kernel test robot noticed the following build errors:

[auto build test ERROR on e90c9612ac3969cb8206029a26bcd2b6f5d4a942]

url:    https://github.com/intel-lab-lkp/linux/commits/Dave-Stevenson/RFC-media-Add-media_request_-pin-unpin-API/20241221-002633
base:   e90c9612ac3969cb8206029a26bcd2b6f5d4a942
patch link:    https://lore.kernel.org/r/20241220-media-rpi-hevc-dec-v1-5-0ebcc04ed42e%40raspberrypi.com
patch subject: [PATCH 5/7] media: platform: Add Raspberry Pi HEVC decoder driver
config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20241222/202412220205.Gf2N9CUb-lkp at intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241222/202412220205.Gf2N9CUb-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/202412220205.Gf2N9CUb-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/media/platform/raspberrypi/hevc_dec/hevc_d.c:14:
   In file included from include/linux/platform_device.h:13:
   In file included from include/linux/device.h:32:
   In file included from include/linux/device/driver.h:21:
   In file included from include/linux/module.h:19:
   In file included from include/linux/elf.h:6:
   In file included from arch/s390/include/asm/elf.h:181:
   In file included from arch/s390/include/asm/mmu_context.h:11:
   In file included from arch/s390/include/asm/pgalloc.h:18:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/media/platform/raspberrypi/hevc_dec/hevc_d.c:24:10: fatal error: 'hevc_d_h265.h' file not found
      24 | #include "hevc_d_h265.h"
         |          ^~~~~~~~~~~~~~~
   4 warnings and 1 error generated.
--
   In file included from drivers/media/platform/raspberrypi/hevc_dec/hevc_d_video.c:14:
   In file included from include/media/videobuf2-dma-contig.h:16:
   In file included from include/media/videobuf2-v4l2.h:16:
   In file included from include/media/videobuf2-core.h:18:
   In file included from include/linux/dma-buf.h:19:
   In file included from include/linux/scatterlist.h:8:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/media/platform/raspberrypi/hevc_dec/hevc_d_video.c:21:10: fatal error: 'hevc_d_h265.h' file not found
      21 | #include "hevc_d_h265.h"
         |          ^~~~~~~~~~~~~~~
   4 warnings and 1 error generated.
--
   In file included from drivers/media/platform/raspberrypi/hevc_dec/hevc_d_h265.c:17:
   In file included from include/media/videobuf2-dma-contig.h:16:
   In file included from include/media/videobuf2-v4l2.h:16:
   In file included from include/media/videobuf2-core.h:18:
   In file included from include/linux/dma-buf.h:19:
   In file included from include/linux/scatterlist.h:8:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/media/platform/raspberrypi/hevc_dec/hevc_d_h265.c:20:10: fatal error: 'hevc_d_h265.h' file not found
      20 | #include "hevc_d_h265.h"
         |          ^~~~~~~~~~~~~~~
   4 warnings and 1 error generated.


vim +24 drivers/media/platform/raspberrypi/hevc_dec/hevc_d.c

    22	
    23	#include "hevc_d.h"
  > 24	#include "hevc_d_h265.h"
    25	#include "hevc_d_video.h"
    26	#include "hevc_d_hw.h"
    27	

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


From krzk at kernel.org  Sat Dec 21 12:04:09 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 21 Dec 2024 21:04:09 +0100
Subject: [PATCH 1/2] dt-bindings: memory-controller: Document rev c.1.5
 compatible
In-Reply-To: <f906a056-3c6b-4115-9fd0-e50da8fc049b@broadcom.com>
References: <20241217194439.929040-1-florian.fainelli@broadcom.com>
 <20241217194439.929040-2-florian.fainelli@broadcom.com>
 <2e33t7ft5ermsfr7c4ympxrn6l5sqdef3wml4hlbnhdupoouwj@gfjpbmowjadi>
 <93a1333d-442f-4cec-b823-9b1a5ff6dc6b@broadcom.com>
 <wxq5zzfh5jesucbbste2j6x2jtj45wjfc5xzjkqbqqta7cprda@oaf5arr3z6pt>
 <f906a056-3c6b-4115-9fd0-e50da8fc049b@broadcom.com>
Message-ID: <a92ff542-6534-4e2e-bef9-6f10c8362d86@kernel.org>

On 20/12/2024 00:43, Florian Fainelli wrote:
> On 12/19/24 00:58, Krzysztof Kozlowski wrote:
>> On Wed, Dec 18, 2024 at 09:15:08AM -0800, Florian Fainelli wrote:
>>> On 12/18/24 03:37, Krzysztof Kozlowski wrote:
>>>> On Tue, Dec 17, 2024 at 11:44:38AM -0800, Florian Fainelli wrote:
>>>>> Document the revision c.1.5 compatible string that is present on newer
>>>>> Broadcom STB memory controllers (74165 and onwards).
>>>>>
>>>>> Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
>>>>> ---
>>>>>    .../bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml       | 1 +
>>>>>    1 file changed, 1 insertion(+)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
>>>>> index 4b072c879b02..99d79ccd1036 100644
>>>>> --- a/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
>>>>> +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml
>>>>> @@ -29,6 +29,7 @@ properties:
>>>>>              - brcm,brcmstb-memc-ddr-rev-c.1.2
>>>>>              - brcm,brcmstb-memc-ddr-rev-c.1.3
>>>>>              - brcm,brcmstb-memc-ddr-rev-c.1.4
>>>>> +          - brcm,brcmstb-memc-ddr-rev-c.1.5
>>>>
>>>> You should use v2.1 fallback and drop driver patch. Or explain in
>>>> commit briefly why different approach is suitable.
>>>
>>> Are you suggesting that we should have fallback compatible strings, such
>>> that we have something like this:
>>>
>>> compatible = "brcm,brcmstb-memc-ddr-rev-c.1.5",
>>> "brcm,brcmstb-memc-ddr-rev-c", "brcm,brcmstb-memc-ddr"
>>>
>>> and the driver only needs to match on "brcm,brcmstb-memc-ddr-rev-c" and
>>> apply the adequate register offset table?
>>
>> Almost, fallback should be brcm,brcmstb-memc-ddr-rev-b.2.1 or whatever
>> was in the driver first or whatever is the oldest known common
>> interface.
>>
>> brcm,brcmstb-memc-ddr-rev-c is not a specific compatible.
>>
>>> If so, that is not how the current binding, and therefore DTBs are being
>>> deployed, so that will introduce a breakage until we update all DTBs in the
>>> field...
>>
>> No. First, I thought about new comaptible so the one you add here. No
>> breakage, it's new compatible. This saves you these pointless updates of
>> driver everytime you add new compatible.
> 
> Yes, but that is not how the binding has been defined until now, so all 
> of the DTBs out there have:
> 
> compatible = "brcm,brcmstb-memc-ddr-rev-b.2.x", "brcm,brcmstb-memc-ddr"

I don't understand the problem. We talk about new devices here, it does
not matter what existing/old devices have in binding in that matter.

> 
> (where X is in range [1..5])
> 
> and there is no fallback defined to "brcm,brcmstb-memc-ddr-rev-b.2.1", 
> so it is not like we can retrofit that easily by adding one now.
> 
>  > > Second, you can introduce fallbacks to older compatibles as well - 
> there
>> will be no breakage, because you add one more compatible. The old
>> compatibles (covered by fallback) of course stays in the driver, so
>> there is no breakage at all. We did it multiple times for several
>> different bindings in Qualcomm. People were doing exactly the same:
>> adding compatible for new device to binding and driver, without
>> considering the compatibility at all.
>>
>> Except being logically correct choice - using fallbacks - this really
>> has huge benefits when later upstreaming complete, big SoCs, like we do
>> for latest Qualcomm SoCs: several changes will be only bindings updates.
> 
> Yes, there are advantages to using fallbacks and we (ab)use that 
> whenever practical.
> 
> The driver only uses a very limited subset of registers (for now), the 
> registers change between minor revisions as well in a way that using a 
> fallback like "brcm,brcmstb-memc-ddr-rev-b.2.1" is not accurate enough 
> not practical. In particular for some of the changes that I am thinking 
> of adding later on, we would need the precise minor version because the 
> behavior and/or register interface is subtly different that this matters.

Devices work fine now with the same driver data, so they are compatible.
Just because you have some differences or new features does not
invalidate that this is exactly the point for what compatibility was
created.


Best regards,
Krzysztof


From krzk at kernel.org  Sat Dec 21 12:11:21 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 21 Dec 2024 21:11:21 +0100
Subject: [PATCH v4 6/7] arm64: defconfig: enable cpu idle injection and
 cpu idle cooling device
In-Reply-To: <b98cc6ea-d215-2200-1537-1a53c2587c81@quicinc.com>
References: <20241217064856.2772305-1-quic_wasimn@quicinc.com>
 <20241217064856.2772305-7-quic_wasimn@quicinc.com>
 <59e96784-9efc-4958-baf0-a51e766e47e8@kernel.org>
 <b98cc6ea-d215-2200-1537-1a53c2587c81@quicinc.com>
Message-ID: <0af81029-0f68-4034-899f-4294d249f6a4@kernel.org>

On 20/12/2024 12:38, Manaf Meethalavalappu Pallikunhi wrote:
> 
> Hi Krzysztof,
> 
> Thank you for reviewing this patch.
> 
> On 12/18/2024 1:32 PM, Krzysztof Kozlowski wrote:
>> On 17/12/2024 07:48, Wasim Nazir wrote:
>>> From: Manaf Meethalavalappu Pallikunhi <quic_manafm at quicinc.com>
>>>
>>> Enable cpu idle injection framework and thermal cpu idle cooling device
>>> to throttle the cpu by injecting idle cycle during high thermal condition.
>> I know what they do, but why do we need it in the defconfig? This is not
>> a product defconfig, just in case you mirrored downstream patches.
> 
> We believe these defconfigs serve as a generic framework rather than 

No...

> being tied to specific product features. Therefore, we have enabled them 

They are tied to specific products.

> in the defconfig to ensure the end-to-end feature is available in the 
> pristine upstream build. However, if you think this would introduce 

Why would we care about this end-to-end feature?

> overhead for other products, we will exclude this patch in the next 
> revision.

I just did not see here any explanation why this should be added. I
don't need to come with extensive disagreement, because by default we do
not enable everything. We enable only some things because of some
reason. And that's why you have commit msg...

Best regards,
Krzysztof


From krzk at kernel.org  Sat Dec 21 12:22:28 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 21 Dec 2024 21:22:28 +0100
Subject: [PATCH v3 07/33] dt-bindings: display: mediatek: Add binding for
 MT8195 HDMI-TX v2
In-Reply-To: <9a75e88c-d90d-4ea8-b5c3-6d056d4f0498@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
 <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>
 <rsnyljmkdf7i74bkrlf5nesp2sa3n6xcnzsqao4znmczjpfyq2@dsakz56s4ypt>
 <9a75e88c-d90d-4ea8-b5c3-6d056d4f0498@collabora.com>
Message-ID: <425fd1b0-fcba-4547-81f6-84acee5ce7f4@kernel.org>

On 19/12/2024 11:54, AngeloGioacchino Del Regno wrote:
>> hdmi@
>>
>> Best regards,
>> Krzysztof
>>
> 
> Thanks for the great review krzk.
> 
> I was wondering if it'd be more straightforward to just send the bindings in a
> different series, instead of sending another batch of 33 (actually, 34, because
> I forgot one commit adding the DDC binding, ugh!) patches...
> 
> CK, any objections?
Maybe just wait few more days for other people's review and then send v4
of everything? You can split the bindings separately, although there is
a risk we will get confused or we will forgot why they got separated.

Best regards,
Krzysztof


From alpernebiyasak at gmail.com  Sat Dec 21 13:30:57 2024
From: alpernebiyasak at gmail.com (Alper Nebi Yasak)
Date: Sun, 22 Dec 2024 00:30:57 +0300
Subject: mt6358-regulator does not probe automatically on MT8183 and
 MT8186 Chromebooks
In-Reply-To: <f3c6ea1d-da0f-40cc-ba70-7cabb5c3189f@gmail.com>
References: <f3c6ea1d-da0f-40cc-ba70-7cabb5c3189f@gmail.com>
Message-ID: <44580fb7-a0ab-41c9-a4e7-fe053742883a@gmail.com>

Hi,

On 2024-12-21 18:38 +03:00, Alper Nebi Yasak wrote:
> Hello,
> 
> I'm left with one small problem trying to boot Debian on MT8183 and 
> MT8186 Chromebooks (Cozmo and Magneton respectively). I see a lot of 
> probe deferrals and get dropped into an initramfs shell. All of them 
> get resolved if I run `modprobe mt6358-regulator`, after which I can 
> exit the initramfs shell to continue booting.
> 
> It has been happening for a long time, still unsolved as of v6.12 and 
> next-20241220. I am using `softdep mediatek-drm pre: mt6358-regulator`
> and so on in /etc/modprobe.d/ to trigger it to probe, as a workaround. 
> 
> But I would like if it was solved upstream so distro kernels can work 
> "out of the box". Any ideas why isn't it probing automatically, and how
> to make it so it works?
> 
> More info from a serial connection below (on mt8183-kukui-jacuzzi-cozmo):
> 
> [...]

I found this patch [1] from Matthias, sent around 2021 about adding an
OF match table to the driver, which fixes this problem for my boards.

[1]
https://lore.kernel.org/linux-mediatek/20210112100659.19350-1-matthias.bgg at kernel.org/T/#u


There on 2021-01-12 13:52, Mark Brown wrote:
> As previously discussed it'd be better to fix the binding document to
> deprecate the requirement for the compatible and remove the usage from
> the MFD.

This doesn't seem to have happened in the last almost-four years, so
please reconsider resending/applying the patch.


From oliver.upton at linux.dev  Sat Dec 21 13:58:36 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Sat, 21 Dec 2024 13:58:36 -0800
Subject: [PATCH v2 01/12] KVM: arm64: nv: Add handling of EL2-specific
 timer registers
In-Reply-To: <874j2xs6hz.wl-maz@kernel.org>
References: <20241217142321.763801-1-maz@kernel.org>
 <20241217142321.763801-2-maz@kernel.org>
 <Z2Yb8BWnqpt441V-@linux.dev>
 <874j2xs6hz.wl-maz@kernel.org>
Message-ID: <Z2c6DJYW1_sSbFIw@linux.dev>

On Sat, Dec 21, 2024 at 09:57:44AM +0000, Marc Zyngier wrote:
> On Sat, 21 Dec 2024 01:38:28 +0000,
> Oliver Upton <oliver.upton at linux.dev> wrote:
> > 
> > On Tue, Dec 17, 2024 at 02:23:09PM +0000, Marc Zyngier wrote:
> > > @@ -3879,9 +4020,11 @@ static const struct sys_reg_desc cp15_64_regs[] = {
> > >  	{ SYS_DESC(SYS_AARCH32_CNTPCT),	      access_arch_timer },
> > >  	{ Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, TTBR1_EL1 },
> > >  	{ Op1( 1), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_ASGI1R */
> > > +	{ SYS_DESC(SYS_AARCH32_CNTVCT),	      access_arch_timer },
> > >  	{ Op1( 2), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI0R */
> > >  	{ SYS_DESC(SYS_AARCH32_CNTP_CVAL),    access_arch_timer },
> > >  	{ SYS_DESC(SYS_AARCH32_CNTPCTSS),     access_arch_timer },
> > > +	{ SYS_DESC(SYS_AARCH32_CNTVCTSS),     access_arch_timer },
> > >  };
> > 
> > Huh. You know, I had always thought we hid 32-bit EL0 from nested
> > guests, but I now realize that isn't the case. Of course, we don't have
> > the necessary trap reflection for exits that came out of a 32-bit EL0,
> > nor should we bother.
> > 
> > Of the 4 NV2 implementations I'm aware of (Neoverse-V1, Neoverse-V2,
> > AmpereOne, M2) only Neoverse-V1 supports 32-bit userspace. And even
> > then, a lot of deployments of V1 have a broken NV2 implementation.
> > 
> > What do you think about advertising a 64-bit only EL0 for nested VMs?
> 
> I'm completely OK with that.
> 
> Actually, we already nuke the guest if exiting from 32bit context, no
> matter the EL (vcpu_mode_is_bad_32bit() is where this happens).  But
> we're missing the ID_AA64PFR0_EL1.EL0 sanitising, which is a bug. I'll
> send a patch shortly.
> 
> Now, for this particular patch, I still think we should gracefully
> handle access to the EL1 timer from a 32bit capable, non-NV guest.
> Just in case we end-up with a CPU with a broken CNTVOFF_EL2 *and*
> 32bit capability.
> 
> In the end, it doesn't cost us much to support this case, and it helps
> that we can verify that we handle all registers without exception.
> 
> Thoughts?

Absolutely. The only reason I made the comment is because the 32-bit
changes had nudged me into thinking about it. Happy with the patch as
is.

-- 
Thanks,
Oliver


From oliver.upton at linux.dev  Sat Dec 21 13:59:43 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Sat, 21 Dec 2024 13:59:43 -0800
Subject: [PATCH] KVM: arm64: nv: Advertise the lack of AArch32 EL0 support
In-Reply-To: <20241221101137.1405271-1-maz@kernel.org>
References: <20241221101137.1405271-1-maz@kernel.org>
Message-ID: <Z2c6TzM2i3DjtCTY@linux.dev>

On Sat, Dec 21, 2024 at 10:11:37AM +0000, Marc Zyngier wrote:
> Although we never supported 32bit anywhere in NV, we fail to
> advertise so for EL0, probably owing to the relative lack of
> hardware supporting both NV2 and 32bit EL0.
> 
> Add some sanitising to ID_AA64PFR0_EL1.EL0, and reaffirm that
> "in 64bit-only we trust".
> 
> Reported-by: Oliver Upton <oliver.upton at linux.dev>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Thanks!

Acked-by: Oliver Upton <oliver.upton at linux.dev>

-- 
Thanks,
Oliver


From oliver.upton at linux.dev  Sat Dec 21 14:00:55 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Sat, 21 Dec 2024 14:00:55 -0800
Subject: [PATCH 00/18] KVM: arm64: Support FEAT_PMUv3 on Apple hardware
In-Reply-To: <20241221134549.GA2917938@robin.jannau.net>
References: <20241217212048.3709204-1-oliver.upton@linux.dev>
 <20241221134549.GA2917938@robin.jannau.net>
Message-ID: <Z2c6l1cTM7V1Jy7V@linux.dev>

On Sat, Dec 21, 2024 at 02:45:49PM +0100, Janne Grunau wrote:
> On Tue, Dec 17, 2024 at 01:20:30PM -0800, Oliver Upton wrote:
> > One of the interesting features of some Apple M* parts is an IMPDEF trap
> > that routes EL1/EL0 accesses of the PMUv3 registers to EL2. This allows
> > a hypervisor to emulate an architectural PMUv3 on top of the IMPDEF PMU
> > hardware present in the CPU.
> > 
> > And if you squint, this _might_ look like a CPU erratum :-)
> > 
> > This series takes advantage of these IMPDEF traps to provide PMUv3 to
> > KVM guests. As a starting point, only expose the fixed CPU cycle counter
> > and no event counters. Conveniently, this is enough to get Windows
> > running as a KVM guest on Apple hardware.
> > 
> > I've tried to keep the deviation to a minimum by refactoring some of the
> > flows used for PMUv3, e.g. computing PMCEID from the arm_pmu bitmap
> > instead of reading hardware directly.
> > 
> > RFC -> v1:
> >  - Rebase to 6.13-rc3
> >  - Add support for 1 event counter in addition to CPU cycle counter
> >  - Don't sneak past the PMU event filter (Marc)
> >  - Have the PMU driver provide a PMUv3 -> HW event ID mapping (Marc)
> > 
> > Tested on my M2 with Linux and Windows guests. If possible, I'd
> > appreciate someone testing on an M1 as I haven't added those MIDRs to
> > the erratum yet.
> 
> Tested on M1 (t8103) with perf in a Linux guest and the patch below
> 
> Tested-by: Janne Grunau <j at jannau.net>
> 
> I'll import this into the downstream asahi kernel as there was a request
> for performance counters to aid FEX-Emu development recently.
> 
> Janne

Awesome, greatly appreciate the testing Janne. Hopefully we can get this
worked out for upstream too :)

-- 
Thanks,
Oliver


From arnd at arndb.de  Sat Dec 21 14:50:23 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 21 Dec 2024 23:50:23 +0100
Subject: [GIT PULL] soc: fixes for 6.13, part 2
Message-ID: <a54c5c66-5255-4177-a616-a4f39a83d2af@app.fastmail.com>

The following changes since commit f578281000c50cae991c40e1f68b2fc0b1b9e60e:

  Merge tag 'ffa-fix-6.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes (2024-12-13 14:26:32 +0100)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-6.13-2

for you to fetch changes up to a31ffd6ed5ee994e1c04dc794499a0c04618dc55:

  Merge tag 'arm-soc/for-6.13/devicetree-arm64-fixes' of https://github.com/Broadcom/stblinux into arm/fixes (2024-12-20 18:02:27 +0100)

----------------------------------------------------------------
soc: fixes for 6.13, part 2

Two more small fixes, correcting the cacheline size on Raspberry Pi 5
and fixing a logic mistake in the microchip mpfs firmware driver.

----------------------------------------------------------------
Arnd Bergmann (2):
      Merge tag 'riscv-soc-fixes-for-v6.13-rc4' of https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux into arm/fixes
      Merge tag 'arm-soc/for-6.13/devicetree-arm64-fixes' of https://github.com/Broadcom/stblinux into arm/fixes

Valentina Fernandez (1):
      firmware: microchip: fix UL_IAP lock check in mpfs_auto_update_state()

Willow Cunningham (1):
      arm64: dts: broadcom: Fix L2 linesize for Raspberry Pi 5

 arch/arm64/boot/dts/broadcom/bcm2712.dtsi     | 8 ++++----
 drivers/firmware/microchip/mpfs-auto-update.c | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)


From pr-tracker-bot at kernel.org  Sat Dec 21 15:48:59 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Sat, 21 Dec 2024 23:48:59 +0000
Subject: [GIT PULL] soc: fixes for 6.13, part 2
In-Reply-To: <a54c5c66-5255-4177-a616-a4f39a83d2af@app.fastmail.com>
References: <a54c5c66-5255-4177-a616-a4f39a83d2af@app.fastmail.com>
Message-ID: <173482493956.3244160.10724298707654952402.pr-tracker-bot@kernel.org>

The pull request you sent on Sat, 21 Dec 2024 23:50:23 +0100:

> https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-6.13-2

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/48f506ad0b683d3e7e794efa60c5785c4fdc86fa

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From naoki at radxa.com  Sat Dec 21 19:03:53 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 22 Dec 2024 03:03:53 +0000
Subject: [PATCH 1/3] irqchip/gic-v3: Enable Rockchip 3588001 erratum workaround for RK3582
In-Reply-To: <20241222030355.2246-1-naoki@radxa.com>
References: <20241222030355.2246-1-naoki@radxa.com>
Message-ID: <20241222030355.2246-2-naoki@radxa.com>

Rockchip RK3582 is a scaled down version of Rockchip RK3588(S). Apply
Rockchip 3588001 erratum workaround to RK3582.

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 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 92244cfa0464..c59ce9332dc0 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -4861,7 +4861,8 @@ static bool __maybe_unused its_enable_rk3588001(void *data)
 {
 	struct its_node *its = data;
 
-	if (!of_machine_is_compatible("rockchip,rk3588") &&
+	if (!of_machine_is_compatible("rockchip,rk3582") &&
+	    !of_machine_is_compatible("rockchip,rk3588") &&
 	    !of_machine_is_compatible("rockchip,rk3588s"))
 		return false;
 
-- 
2.43.0



From naoki at radxa.com  Sat Dec 21 19:03:54 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 22 Dec 2024 03:03:54 +0000
Subject: [PATCH 2/3] dt-bindings: arm: rockchip: Add Radxa E52C
In-Reply-To: <20241222030355.2246-1-naoki@radxa.com>
References: <20241222030355.2246-1-naoki@radxa.com>
Message-ID: <20241222030355.2246-3-naoki@radxa.com>

Add devicetree binding for the Radxa E52C.

Radxa E52C is a compact network computer based on the Rockchip RK3582
SoC.

Signed-off-by: FUKAUMI Naoki <naoki at radxa.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 753199a12923..0f0c049a2e90 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -812,6 +812,11 @@ properties:
           - const: radxa,e20c
           - const: rockchip,rk3528
 
+      - description: Radxa E52C
+        items:
+          - const: radxa,e52c
+          - const: rockchip,rk3582
+
       - description: Radxa Rock
         items:
           - const: radxa,rock
-- 
2.43.0



From naoki at radxa.com  Sat Dec 21 19:03:55 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 22 Dec 2024 03:03:55 +0000
Subject: [PATCH 3/3] arm64: dts: rockchip: Add Radxa E52C
In-Reply-To: <20241222030355.2246-1-naoki@radxa.com>
References: <20241222030355.2246-1-naoki@radxa.com>
Message-ID: <20241222030355.2246-4-naoki@radxa.com>

Radxa E52C is a compact network computer[1] based on the Rockchip
RK3582 SoC:

- Dual Cortex-A76 and quad Cortex-A55 CPU
- 5TOPS NPU
- 2GB/4GB/8GB LPDDR4 RAM
- 16GB/32GB/64GB on-board eMMC
- microSD card slot
- USB 3.0 Type-A HOST port
- USB Type-C debug port
- USB Type-C power port (5V only)
- 2x 2.5GbE ports

[1] https://radxa.com/products/network-computer/e52c

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3582-radxa-e52c.dts   | 729 ++++++++++++++++++
 2 files changed, 730 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index cac3f39af82a..e6e71e8f5519 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -157,6 +157,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-display-vz.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-io-expander.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3582-radxa-e52c.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-sige7.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-w3.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-coolpi-cm5-evb.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
new file mode 100644
index 000000000000..a278802ace18
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
@@ -0,0 +1,729 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Radxa Computer (Shenzhen) Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3588s.dtsi"
+
+/ {
+	model = "Radxa E52C";
+	compatible = "radxa,e52c", "rockchip,rk3582";
+
+	aliases {
+		mmc0 = &sdhci;
+		mmc1 = &sdmmc;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <18000>;
+		poll-interval = <100>;
+
+		key-vendor {
+			label = "Maskrom";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&btn_user>;
+
+		button-0 {
+			label = "User";
+			gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			wakeup-source;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pin>;
+
+		led-0 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
+			function = LED_FUNCTION_STATUS;
+			gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	pwm-leds {
+		compatible = "pwm-leds";
+
+		led-1 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
+			function = LED_FUNCTION_LAN;
+			linux,default-trigger = "r8169-4-4100:00:link";
+			pwms = <&pwm14 0 1000000 PWM_POLARITY_INVERTED>;
+			max-brightness = <255>;
+		};
+
+		led-2 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
+			function = LED_FUNCTION_WAN;
+			linux,default-trigger = "r8169-3-3100:00:link";
+			pwms = <&pwm11 0 1000000 PWM_POLARITY_INVERTED>;
+			max-brightness = <255>;
+		};
+	};
+
+	/* 5V_DCIN */
+	vbus_typec: regulator-vbus-typec {
+		compatible = "regulator-fixed";
+		regulator-name = "vbus_typec";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	vcc5v0_usb_otg0: regulator-vcc5v0-usb-otg0 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_otg_pwren_h>;
+		regulator-name = "vcc5v0_usb_otg0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc_sysin>;
+	};
+
+	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
+		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 = <&vcc_sysin>;
+	};
+
+	vcc_3v3_pmu: regulator-vcc-3v3-pmu {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_pmu";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	vcc_3v3_s0: regulator-vcc-3v3-s0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	vcc_5v0: regulator-vcc-5v0 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc_5v0_pwren_h>;
+		regulator-name = "vcc_5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc_sysin>;
+	};
+
+	vcc_sysin: regulator-vcc-sysin {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sysin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vbus_typec>;
+	};
+
+	vcca: regulator-vcca {
+		compatible = "regulator-fixed";
+		regulator-name = "vcca";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <4000000>;
+		regulator-max-microvolt = <4000000>;
+		vin-supply = <&vcc_sysin>;
+	};
+};
+
+&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>;
+};
+
+&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 = <&vcc_sysin>;
+
+		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 = <&vcc_sysin>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	eeprom at 50 {
+		compatible = "belling,bl24c16a", "atmel,24c16";
+		reg = <0x50>;
+		pagesize = <16>;
+		vcc-supply = <&vcc_3v3_pmu>;
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	vdd_npu_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_npu_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <950000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc_sysin>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&pcie2x1l1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie20x1_1_perstn_m1>,
+		    <&pcie30x1m1_1_clkreqn>,
+		    <&pcie30x1m1_1_waken>;
+	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc_3v3_s3>;
+	status = "okay";
+};
+
+&pcie2x1l2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie20x1_2_perstn_m0>,
+		    <&pcie20x1m0_clkreqn>,
+		    <&pcie20x1m0_waken>;
+	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc_3v3_s3>;
+	status = "okay";
+};
+
+&pinctrl {
+	keys {
+		btn_user: btn-user {
+			rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	leds {
+		led_pin: led-pin {
+			rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pcie {
+		pcie20x1_1_perstn_m1: pcie20x1-1-perstn-m1 {
+			rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		pcie20x1_2_perstn_m0: pcie20x1-2-perstn-m0 {
+			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		usb_otg_pwren_h: usb-otg-pwren-h {
+			rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	vcc-5v0 {
+		vcc_5v0_pwren_h: vcc-5v0-pwren-h {
+			rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pwm11 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm11m1_pins>;
+	status = "okay";
+};
+
+&pwm14 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm14m1_pins>;
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcca_1v8_s0>;
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-hs400-1_8v;
+	mmc-hs400-enhanced-strobe;
+	no-sd;
+	no-sdio;
+	non-removable;
+	vmmc-supply = <&vcc_3v3_s0>;
+	vqmmc-supply = <&vcc_1v8_s3>;
+	status = "okay";
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	no-sdio;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_3v3_s3>;
+	vqmmc-supply = <&vccio_sd_s0>;
+	status = "okay";
+};
+
+&spi2 {
+	status = "okay";
+	assigned-clocks = <&cru CLK_SPI2>;
+	assigned-clock-rates = <200000000>;
+	num-cs = <1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+
+	pmic at 0 {
+		compatible = "rockchip,rk806";
+		reg = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		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>;
+		spi-max-frequency = <1000000>;
+		system-power-controller;
+
+		vcc1-supply = <&vcc_sysin>;
+		vcc2-supply = <&vcc_sysin>;
+		vcc3-supply = <&vcc_sysin>;
+		vcc4-supply = <&vcc_sysin>;
+		vcc5-supply = <&vcc_sysin>;
+		vcc6-supply = <&vcc_sysin>;
+		vcc7-supply = <&vcc_sysin>;
+		vcc8-supply = <&vcc_sysin>;
+		vcc9-supply = <&vcc_sysin>;
+		vcc10-supply = <&vcc_sysin>;
+		vcc11-supply = <&vcc_2v0_pldo_s3>;
+		vcc12-supply = <&vcc_sysin>;
+		vcc13-supply = <&vcc_1v1_nldo_s3>;
+		vcc14-supply = <&vcc_1v1_nldo_s3>;
+		vcca-supply = <&vcca>;
+
+		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: dcdc-reg1 {
+				regulator-name = "vdd_gpu_s0";
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-enable-ramp-delay = <400>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_lit_s0: dcdc-reg2 {
+				regulator-name = "vdd_cpu_lit_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_logic_s0: dcdc-reg3 {
+				regulator-name = "vdd_logic_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <750000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_vdenc_s0: dcdc-reg4 {
+				regulator-name = "vdd_vdenc_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_ddr_s0: dcdc-reg5 {
+				regulator-name = "vdd_ddr_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <900000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdd2_ddr_s3: dcdc-reg6 {
+				regulator-name = "vdd2_ddr_s3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_2v0_pldo_s3: dcdc-reg7 {
+				regulator-name = "vcc_2v0_pldo_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <2000000>;
+				};
+			};
+
+			vcc_3v3_s3: dcdc-reg8 {
+				regulator-name = "vcc_3v3_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vddq_ddr_s0: dcdc-reg9 {
+				regulator-name = "vddq_ddr_s0";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s3: dcdc-reg10 {
+				regulator-name = "vcc_1v8_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc_1v8_s0: pldo-reg1 {
+				regulator-name = "vcc_1v8_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca_1v8_s0: pldo-reg2 {
+				regulator-name = "vcca_1v8_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdda_1v2_s0: pldo-reg3 {
+				regulator-name = "vdda_1v2_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca_3v3_s0: pldo-reg4 {
+				regulator-name = "vcca_3v3_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vccio_sd_s0: pldo-reg5 {
+				regulator-name = "vccio_sd_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			pldo6_s3: pldo-reg6 {
+				regulator-name = "pldo6_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_0v75_s3: nldo-reg1 {
+				regulator-name = "vdd_0v75_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdda_ddr_pll_s0: nldo-reg2 {
+				regulator-name = "vdda_ddr_pll_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdda_0v75_s0: nldo-reg3 {
+				regulator-name = "vdda_0v75_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdda_0v85_s0: nldo-reg4 {
+				regulator-name = "vdda_0v85_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_0v75_s0: nldo-reg5 {
+				regulator-name = "vdd_0v75_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&tsadc {
+	status = "okay";
+};
+
+&u2phy0 {
+	status = "okay";
+};
+
+&u2phy0_otg {
+	phy-supply = <&vcc5v0_usb_otg0>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
+
+&usb_host0_xhci {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbdp_phy0 {
+	status = "okay";
+};
-- 
2.43.0



From naoki at radxa.com  Sat Dec 21 19:03:52 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 22 Dec 2024 03:03:52 +0000
Subject: [PATCH 0/3] rockchip: Add support for RK3582
Message-ID: <20241222030355.2246-1-naoki@radxa.com>

Rockchip RK3582 is a scaled down version of Rockchip RK3588(S).

- Dual Cortex-A76 and quad Cortex-A55 CPU
- No GPU
- 5TOPS NPU
- H.264/H.265 video encoder up to 4K at 60fps

This patch series adds RK3582 support to the GIC and the Radxa E52C
compact network computer.

FUKAUMI Naoki (3):
  irqchip/gic-v3: Enable Rockchip 3588001 erratum workaround for RK3582
  dt-bindings: arm: rockchip: Add Radxa E52C
  arm64: dts: rockchip: Add Radxa E52C

 .../devicetree/bindings/arm/rockchip.yaml     |   5 +
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3582-radxa-e52c.dts   | 729 ++++++++++++++++++
 drivers/irqchip/irq-gic-v3-its.c              |   3 +-
 4 files changed, 737 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts

-- 
2.43.0



From naoki at radxa.com  Sat Dec 21 19:58:26 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 22 Dec 2024 12:58:26 +0900
Subject: [PATCH 3/3] arm64: dts: rockchip: Add Radxa E52C
In-Reply-To: <20241222030355.2246-4-naoki@radxa.com>
References: <20241222030355.2246-1-naoki@radxa.com>
 <20241222030355.2246-4-naoki@radxa.com>
Message-ID: <F18C5BAF53139C3F+a3f78a00-91cf-44bd-b83f-b4692f0fb388@radxa.com>

In v2 I will change the node names to be more general. Please ignore the 
"node name" part.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 12/22/24 12:03, FUKAUMI Naoki wrote:
> Radxa E52C is a compact network computer[1] based on the Rockchip
> RK3582 SoC:
> 
> - Dual Cortex-A76 and quad Cortex-A55 CPU
> - 5TOPS NPU
> - 2GB/4GB/8GB LPDDR4 RAM
> - 16GB/32GB/64GB on-board eMMC
> - microSD card slot
> - USB 3.0 Type-A HOST port
> - USB Type-C debug port
> - USB Type-C power port (5V only)
> - 2x 2.5GbE ports
> 
> [1] https://radxa.com/products/network-computer/e52c
> 
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>   arch/arm64/boot/dts/rockchip/Makefile         |   1 +
>   .../boot/dts/rockchip/rk3582-radxa-e52c.dts   | 729 ++++++++++++++++++
>   2 files changed, 730 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> 
> diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> index cac3f39af82a..e6e71e8f5519 100644
> --- a/arch/arm64/boot/dts/rockchip/Makefile
> +++ b/arch/arm64/boot/dts/rockchip/Makefile
> @@ -157,6 +157,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5.dtb
>   dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-display-vz.dtbo
>   dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-io-expander.dtbo
>   dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5.dtb
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3582-radxa-e52c.dtb
>   dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-sige7.dtb
>   dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-w3.dtb
>   dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-coolpi-cm5-evb.dtb
> diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> new file mode 100644
> index 000000000000..a278802ace18
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> @@ -0,0 +1,729 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2024 Radxa Computer (Shenzhen) Co., Ltd.
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/leds/common.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include <dt-bindings/pwm/pwm.h>
> +#include "rk3588s.dtsi"
> +
> +/ {
> +	model = "Radxa E52C";
> +	compatible = "radxa,e52c", "rockchip,rk3582";
> +
> +	aliases {
> +		mmc0 = &sdhci;
> +		mmc1 = &sdmmc;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial2:1500000n8";
> +	};
> +
> +	adc-keys {
> +		compatible = "adc-keys";
> +		io-channels = <&saradc 0>;
> +		io-channel-names = "buttons";
> +		keyup-threshold-microvolt = <18000>;
> +		poll-interval = <100>;
> +
> +		key-vendor {
> +			label = "Maskrom";
> +			linux,code = <KEY_VENDOR>;
> +			press-threshold-microvolt = <0>;
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&btn_user>;
> +
> +		button-0 {
> +			label = "User";
> +			gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
> +			linux,code = <BTN_0>;
> +			wakeup-source;
> +		};
> +	};
> +
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&led_pin>;
> +
> +		led-0 {
> +			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
> +			function = LED_FUNCTION_STATUS;
> +			gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "heartbeat";
> +		};
> +	};
> +
> +	pwm-leds {
> +		compatible = "pwm-leds";
> +
> +		led-1 {
> +			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
> +			function = LED_FUNCTION_LAN;
> +			linux,default-trigger = "r8169-4-4100:00:link";
> +			pwms = <&pwm14 0 1000000 PWM_POLARITY_INVERTED>;
> +			max-brightness = <255>;
> +		};
> +
> +		led-2 {
> +			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
> +			function = LED_FUNCTION_WAN;
> +			linux,default-trigger = "r8169-3-3100:00:link";
> +			pwms = <&pwm11 0 1000000 PWM_POLARITY_INVERTED>;
> +			max-brightness = <255>;
> +		};
> +	};
> +
> +	/* 5V_DCIN */
> +	vbus_typec: regulator-vbus-typec {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vbus_typec";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +	};
> +
> +	vcc5v0_usb_otg0: regulator-vcc5v0-usb-otg0 {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&usb_otg_pwren_h>;
> +		regulator-name = "vcc5v0_usb_otg0";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&vcc_sysin>;
> +	};
> +
> +	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
> +		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 = <&vcc_sysin>;
> +	};
> +
> +	vcc_3v3_pmu: regulator-vcc-3v3-pmu {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_3v3_pmu";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&vcc_3v3_s3>;
> +	};
> +
> +	vcc_3v3_s0: regulator-vcc-3v3-s0 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_3v3_s0";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&vcc_3v3_s3>;
> +	};
> +
> +	vcc_5v0: regulator-vcc-5v0 {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&vcc_5v0_pwren_h>;
> +		regulator-name = "vcc_5v0";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&vcc_sysin>;
> +	};
> +
> +	vcc_sysin: regulator-vcc-sysin {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_sysin";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&vbus_typec>;
> +	};
> +
> +	vcca: regulator-vcca {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcca";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <4000000>;
> +		regulator-max-microvolt = <4000000>;
> +		vin-supply = <&vcc_sysin>;
> +	};
> +};
> +
> +&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>;
> +};
> +
> +&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 = <&vcc_sysin>;
> +
> +		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 = <&vcc_sysin>;
> +
> +		regulator-state-mem {
> +			regulator-off-in-suspend;
> +		};
> +	};
> +
> +	eeprom at 50 {
> +		compatible = "belling,bl24c16a", "atmel,24c16";
> +		reg = <0x50>;
> +		pagesize = <16>;
> +		vcc-supply = <&vcc_3v3_pmu>;
> +	};
> +};
> +
> +&i2c2 {
> +	status = "okay";
> +
> +	vdd_npu_s0: regulator at 42 {
> +		compatible = "rockchip,rk8602";
> +		reg = <0x42>;
> +		fcs,suspend-voltage-selector = <1>;
> +		regulator-name = "vdd_npu_s0";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <550000>;
> +		regulator-max-microvolt = <950000>;
> +		regulator-ramp-delay = <2300>;
> +		vin-supply = <&vcc_sysin>;
> +
> +		regulator-state-mem {
> +			regulator-off-in-suspend;
> +		};
> +	};
> +};
> +
> +&pcie2x1l1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie20x1_1_perstn_m1>,
> +		    <&pcie30x1m1_1_clkreqn>,
> +		    <&pcie30x1m1_1_waken>;
> +	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
> +	vpcie3v3-supply = <&vcc_3v3_s3>;
> +	status = "okay";
> +};
> +
> +&pcie2x1l2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie20x1_2_perstn_m0>,
> +		    <&pcie20x1m0_clkreqn>,
> +		    <&pcie20x1m0_waken>;
> +	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
> +	vpcie3v3-supply = <&vcc_3v3_s3>;
> +	status = "okay";
> +};
> +
> +&pinctrl {
> +	keys {
> +		btn_user: btn-user {
> +			rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	leds {
> +		led_pin: led-pin {
> +			rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	pcie {
> +		pcie20x1_1_perstn_m1: pcie20x1-1-perstn-m1 {
> +			rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +
> +		pcie20x1_2_perstn_m0: pcie20x1-2-perstn-m0 {
> +			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	usb {
> +		usb_otg_pwren_h: usb-otg-pwren-h {
> +			rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	vcc-5v0 {
> +		vcc_5v0_pwren_h: vcc-5v0-pwren-h {
> +			rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +};
> +
> +&pwm11 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pwm11m1_pins>;
> +	status = "okay";
> +};
> +
> +&pwm14 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pwm14m1_pins>;
> +	status = "okay";
> +};
> +
> +&saradc {
> +	vref-supply = <&vcca_1v8_s0>;
> +	status = "okay";
> +};
> +
> +&sdhci {
> +	bus-width = <8>;
> +	cap-mmc-highspeed;
> +	mmc-hs400-1_8v;
> +	mmc-hs400-enhanced-strobe;
> +	no-sd;
> +	no-sdio;
> +	non-removable;
> +	vmmc-supply = <&vcc_3v3_s0>;
> +	vqmmc-supply = <&vcc_1v8_s3>;
> +	status = "okay";
> +};
> +
> +&sdmmc {
> +	bus-width = <4>;
> +	cap-mmc-highspeed;
> +	cap-sd-highspeed;
> +	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
> +	disable-wp;
> +	no-sdio;
> +	sd-uhs-sdr104;
> +	vmmc-supply = <&vcc_3v3_s3>;
> +	vqmmc-supply = <&vccio_sd_s0>;
> +	status = "okay";
> +};
> +
> +&spi2 {
> +	status = "okay";
> +	assigned-clocks = <&cru CLK_SPI2>;
> +	assigned-clock-rates = <200000000>;
> +	num-cs = <1>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
> +
> +	pmic at 0 {
> +		compatible = "rockchip,rk806";
> +		reg = <0>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		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>;
> +		spi-max-frequency = <1000000>;
> +		system-power-controller;
> +
> +		vcc1-supply = <&vcc_sysin>;
> +		vcc2-supply = <&vcc_sysin>;
> +		vcc3-supply = <&vcc_sysin>;
> +		vcc4-supply = <&vcc_sysin>;
> +		vcc5-supply = <&vcc_sysin>;
> +		vcc6-supply = <&vcc_sysin>;
> +		vcc7-supply = <&vcc_sysin>;
> +		vcc8-supply = <&vcc_sysin>;
> +		vcc9-supply = <&vcc_sysin>;
> +		vcc10-supply = <&vcc_sysin>;
> +		vcc11-supply = <&vcc_2v0_pldo_s3>;
> +		vcc12-supply = <&vcc_sysin>;
> +		vcc13-supply = <&vcc_1v1_nldo_s3>;
> +		vcc14-supply = <&vcc_1v1_nldo_s3>;
> +		vcca-supply = <&vcca>;
> +
> +		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: dcdc-reg1 {
> +				regulator-name = "vdd_gpu_s0";
> +				regulator-boot-on;
> +				regulator-min-microvolt = <550000>;
> +				regulator-max-microvolt = <950000>;
> +				regulator-ramp-delay = <12500>;
> +				regulator-enable-ramp-delay = <400>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdd_cpu_lit_s0: dcdc-reg2 {
> +				regulator-name = "vdd_cpu_lit_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <550000>;
> +				regulator-max-microvolt = <950000>;
> +				regulator-ramp-delay = <12500>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdd_logic_s0: dcdc-reg3 {
> +				regulator-name = "vdd_logic_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <675000>;
> +				regulator-max-microvolt = <750000>;
> +				regulator-ramp-delay = <12500>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <750000>;
> +				};
> +			};
> +
> +			vdd_vdenc_s0: dcdc-reg4 {
> +				regulator-name = "vdd_vdenc_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <550000>;
> +				regulator-max-microvolt = <950000>;
> +				regulator-ramp-delay = <12500>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdd_ddr_s0: dcdc-reg5 {
> +				regulator-name = "vdd_ddr_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <675000>;
> +				regulator-max-microvolt = <900000>;
> +				regulator-ramp-delay = <12500>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +					regulator-suspend-microvolt = <850000>;
> +				};
> +			};
> +
> +			vdd2_ddr_s3: dcdc-reg6 {
> +				regulator-name = "vdd2_ddr_s3";
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +				};
> +			};
> +
> +			vcc_2v0_pldo_s3: dcdc-reg7 {
> +				regulator-name = "vcc_2v0_pldo_s3";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <2000000>;
> +				regulator-max-microvolt = <2000000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <2000000>;
> +				};
> +			};
> +
> +			vcc_3v3_s3: dcdc-reg8 {
> +				regulator-name = "vcc_3v3_s3";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <3300000>;
> +				};
> +			};
> +
> +			vddq_ddr_s0: dcdc-reg9 {
> +				regulator-name = "vddq_ddr_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc_1v8_s3: dcdc-reg10 {
> +				regulator-name = "vcc_1v8_s3";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <1800000>;
> +				};
> +			};
> +
> +			vcc_1v8_s0: pldo-reg1 {
> +				regulator-name = "vcc_1v8_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <1800000>;
> +				};
> +			};
> +
> +			vcca_1v8_s0: pldo-reg2 {
> +				regulator-name = "vcca_1v8_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <1800000>;
> +				};
> +			};
> +
> +			vdda_1v2_s0: pldo-reg3 {
> +				regulator-name = "vdda_1v2_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1200000>;
> +				regulator-max-microvolt = <1200000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcca_3v3_s0: pldo-reg4 {
> +				regulator-name = "vcca_3v3_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <3300000>;
> +				};
> +			};
> +
> +			vccio_sd_s0: pldo-reg5 {
> +				regulator-name = "vccio_sd_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			pldo6_s3: pldo-reg6 {
> +				regulator-name = "pldo6_s3";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <1800000>;
> +				};
> +			};
> +
> +			vdd_0v75_s3: nldo-reg1 {
> +				regulator-name = "vdd_0v75_s3";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <750000>;
> +				regulator-max-microvolt = <750000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <750000>;
> +				};
> +			};
> +
> +			vdda_ddr_pll_s0: nldo-reg2 {
> +				regulator-name = "vdda_ddr_pll_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <850000>;
> +				regulator-max-microvolt = <850000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <850000>;
> +				};
> +			};
> +
> +			vdda_0v75_s0: nldo-reg3 {
> +				regulator-name = "vdda_0v75_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <750000>;
> +				regulator-max-microvolt = <750000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <750000>;
> +				};
> +			};
> +
> +			vdda_0v85_s0: nldo-reg4 {
> +				regulator-name = "vdda_0v85_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <850000>;
> +				regulator-max-microvolt = <850000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdd_0v75_s0: nldo-reg5 {
> +				regulator-name = "vdd_0v75_s0";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <750000>;
> +				regulator-max-microvolt = <750000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&tsadc {
> +	status = "okay";
> +};
> +
> +&u2phy0 {
> +	status = "okay";
> +};
> +
> +&u2phy0_otg {
> +	phy-supply = <&vcc5v0_usb_otg0>;
> +	status = "okay";
> +};
> +
> +&uart2 {
> +	pinctrl-0 = <&uart2m0_xfer>;
> +	status = "okay";
> +};
> +
> +&usb_host0_xhci {
> +	dr_mode = "host";
> +	status = "okay";
> +};
> +
> +&usbdp_phy0 {
> +	status = "okay";
> +};



From amadeus at jmu.edu.cn  Sat Dec 21 20:30:27 2024
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sun, 22 Dec 2024 12:30:27 +0800
Subject: [PATCH 1/1] arm64: dts: rockchip: default to host mode for USB on Radxa E25
In-Reply-To: <6EFDC4E74A617E25+ed534e8a-fef0-4f09-a24b-a536b7f2f13b@radxa.com>
References: <6EFDC4E74A617E25+ed534e8a-fef0-4f09-a24b-a536b7f2f13b@radxa.com>
Message-ID: <20241222043027.265865-1-amadeus@jmu.edu.cn>

Hi,
> Could you check Product Brief P.4?
>
>  https://dl.radxa.com/cm3i/e25/radxa_e25_product_brief.pdf
>
> There is "USB3.0 OTG Switch".
>
> Best regards,

Oh, sorry, it was covered by the shell so I didn't notice it.
BTW do you see any issues in the sd-uhs-sdr104 mode?

Thanks,
Chukun

-- 
2.25.1



From krzk at kernel.org  Sat Dec 21 22:38:23 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 07:38:23 +0100
Subject: [PATCH v2 3/7] dts: arm64: rockchip: Add rk3576 pcie nodes
In-Reply-To: <20241220101551.3505917-4-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
 <20241220101551.3505917-4-kever.yang@rock-chips.com>
Message-ID: <i54jjqt7uaxrurdapsyxwmb5iokiwzgm5cvlaamlggycrpyd3v@azhmfwgetrzm>

On Fri, Dec 20, 2024 at 06:15:47PM +0800, Kever Yang wrote:
> rk3576 has two pcie controller, both are pcie2x1 used with
> naneng-combphy.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
> ---

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. For bindings, the preferred subjects are
explained here:
https://www.kernel.org/doc/html/latest/devicetree/bindings/submitting-patches.html#i-for-patch-submitters


> 
> Changes in v2:
> - Update clock and reset names and sequence to pass DTB check
> 
>  arch/arm64/boot/dts/rockchip/rk3576.dtsi | 109 +++++++++++++++++++++++
>  1 file changed, 109 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
> index a147879da501..df7dfe702221 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
> @@ -1016,6 +1016,115 @@ qos_npu_m1ro: qos at 27f22100 {
>  			reg = <0x0 0x27f22100 0x0 0x20>;
>  		};
>  
> +		pcie0: pcie at 2a200000 {
> +			compatible = "rockchip,rk3576-pcie", "rockchip,rk3568-pcie";
> +			bus-range = <0x0 0xf>;

Follow DTS coding style in properties order and everything around here.

Best regards,
Krzysztof



From krzk at kernel.org  Sat Dec 21 22:39:10 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 07:39:10 +0100
Subject: [PATCH v2 2/7] dt-bindings: PCI: dwc: rockchip: Add rk3576
 support
In-Reply-To: <20241220101551.3505917-3-kever.yang@rock-chips.com>
References: <20241220101551.3505917-1-kever.yang@rock-chips.com>
 <20241220101551.3505917-3-kever.yang@rock-chips.com>
Message-ID: <n4iwrjmgtpetajccfsaz2nqv2g2of6md4moyus7vdwfcp6tgt2@4qe7qkvjrix2>

On Fri, Dec 20, 2024 at 06:15:46PM +0800, Kever Yang wrote:
> rk3576 is using dwc controller, but use msi interrupt instead of its,
> so the msi-map is not required, and need to add a new 'msi' interrupt name.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
> ---
> 
> Changes in v2:
> - remove required 'msi-map'
> - add interrupt name 'msi'
> 
>  .../devicetree/bindings/pci/rockchip-dw-pcie-common.yaml      | 1 +
>  Documentation/devicetree/bindings/pci/rockchip-dw-pcie.yaml   | 4 +---
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-common.yaml b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-common.yaml
> index cc9adfc7611c..e5e1a2c7ae05 100644
> --- a/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-common.yaml
> +++ b/Documentation/devicetree/bindings/pci/rockchip-dw-pcie-common.yaml
> @@ -81,6 +81,7 @@ properties:
>        - const: msg
>        - const: legacy
>        - const: err
> +      - const: msi

ABI break without clear reasons.

Best regards,
Krzysztof



From andyshrk at 163.com  Sat Dec 21 22:55:09 2024
From: andyshrk at 163.com (Andy Yan)
Date: Sun, 22 Dec 2024 14:55:09 +0800 (CST)
Subject: [PATCH] arm64: dts: rockchip: aliase sdhci as mmc0 for
 rk3566 box demo
In-Reply-To: <24438615.ouqheUzb2q@diego>
References: <20241221104920.4193034-1-andyshrk@163.com>
 <24438615.ouqheUzb2q@diego>
Message-ID: <19b62068.1082.193ed25f901.Coremail.andyshrk@163.com>


Hi Heiko?
At 2024-12-21 20:55:02, "Heiko St?bner" <heiko at sntech.de> wrote:
>Hi Andy,
>
>Am Samstag, 21. Dezember 2024, 11:49:07 CET schrieb Andy Yan:
>> From: Andy Yan <andy.yan at rock-chips.com>
>> 
>> Follow most others rk356x based boards, and u-boot only use mmc0/1
>> as mmc boot targets, so aliase sdhci as mmc0.
>> 
>> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>> ---
>> 
>>  arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>> 
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts b/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
>> index 41b4cd5a4220..7d0eedf1bd0d 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
>> @@ -19,9 +19,9 @@ / {
>>  
>>  	aliases {
>>  		ethernet0 = &gmac1;
>> -		mmc0 = &sdmmc0;
>> -		mmc1 = &sdmmc1;
>> -		mmc2 = &sdhci;
>> +		mmc0 = &sdhci;
>> +		mmc1 = &sdmmc0;
>> +		mmc2 = &sdmmc1;
>
>sorry, but that won't be possible :-( .
>
>The original aliases for the mmc order were added over 2 years ago
>(november 2022) and became part of the ABI then.

Yes,  the patch for this board was submitted by me.
This is a tv box  evaluation demo board that we use internally?and it is not sold to the public.
I submitted it to the mainline because it is small, compact and streamlined, it easy for me
to use it  test the mainline vop2 driver. 
I think i am currently the only user who will use this board run the mainline kernel.
I'm not sure if we can let it go.


>
>Imagine someone using that board with a rootfs=/dev/mmcblk2p1 part
>in the commandline to mount the old sdhci-part1 as rootfs, but now
>you reorder the controllers, so so that commandline would try to access
>sdmmc1, so their system won't boot anymore after just a simple kernel
>update.
>
>Breaking people's setup is one of those big no-go-s in the kernel, so
>sadly you'll need to live with the existing order.
>
>
>Heiko
>
>

From krzysztof.kozlowski at linaro.org  Sun Dec 22 00:19:15 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 09:19:15 +0100
Subject: [PATCH v7 1/5] dt-bindings: clock: qcom: Add CMN PLL clock
 controller for IPQ SoC
In-Reply-To: <20241220-qcom_ipq_cmnpll-v7-1-438a1b5cb98e@quicinc.com>
References: <20241220-qcom_ipq_cmnpll-v7-0-438a1b5cb98e@quicinc.com>
 <20241220-qcom_ipq_cmnpll-v7-1-438a1b5cb98e@quicinc.com>
Message-ID: <yngf4ngbnkcmohjfkd6muynfr72v5yhynmyqfjmxh6qbxidmo7@bsvimplmpwsl>

On Fri, Dec 20, 2024 at 09:22:42PM +0800, Luo Jie wrote:
> The CMN PLL controller provides clocks to networking hardware blocks
> and to GCC on Qualcomm IPQ9574 SoC. It receives input clock from the
> on-chip Wi-Fi, and produces output clocks at fixed rates. These output
> rates are predetermined, and are unrelated to the input clock rate.
> The primary purpose of CMN PLL is to supply clocks to the networking
> hardware such as PPE (packet process engine), PCS and the externally
> connected switch or PHY device. The CMN PLL block also outputs fixed
> rate clocks to GCC, such as 24 MHZ as XO clock and 32 KHZ as sleep
> clock supplied to GCC.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Luo Jie <quic_luoj at quicinc.com>
> ---
>  .../bindings/clock/qcom,ipq9574-cmn-pll.yaml       | 85 ++++++++++++++++++++++
>  include/dt-bindings/clock/qcom,ipq-cmn-pll.h       | 22 ++++++
>  2 files changed, 107 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
> new file mode 100644
> index 000000000000..db8a3ee56067
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
> @@ -0,0 +1,85 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/qcom,ipq9574-cmn-pll.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm CMN PLL Clock Controller on IPQ SoC
> +
> +maintainers:
> +  - Bjorn Andersson <andersson at kernel.org>
> +  - Luo Jie <quic_luoj at quicinc.com>
> +
> +description:
> +  The CMN (or common) PLL clock controller expects a reference
> +  input clock. This reference clock is from the on-board Wi-Fi.
> +  The CMN PLL supplies a number of fixed rate output clocks to
> +  the devices providing networking functions and to GCC. These
> +  networking hardware include PPE (packet process engine), PCS
> +  and the externally connected switch or PHY devices. The CMN
> +  PLL block also outputs fixed rate clocks to GCC. The PLL's
> +  primary function is to enable fixed rate output clocks for
> +  networking hardware functions used with the IPQ SoC.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - qcom,ipq9574-cmn-pll
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: The reference clock. The supported clock rates include
> +          25000000, 31250000, 40000000, 48000000, 50000000 and 96000000 HZ.
> +      - description: The AHB clock
> +      - description: The SYS clock
> +    description:
> +      The reference clock is the source clock of CMN PLL, which is from the
> +      Wi-Fi. The AHB and SYS clocks must be enabled to access CMN PLL
> +      clock registers.
> +
> +  clock-names:
> +    items:
> +      - const: ref
> +      - const: ahb
> +      - const: sys
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  assigned-clocks:

Drop

> +    maxItems: 1
> +
> +  assigned-clock-rates-u64:
> +    maxItems: 1

These wasn't here when you received review. Adding new properties always
invalidates review.

No, drop them.


> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - "#clock-cells"
> +  - assigned-clocks

Drop

> +  - assigned-clock-rates-u64

Drop... or explain

Drop all review tags after making significant changes like that.

Best regards,
Krzysztof



From krzk at kernel.org  Sun Dec 22 00:33:59 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 09:33:59 +0100
Subject: [PATCH v5 1/3] dt-bindings: display: bcm2711-hdmi: Add interrupt
 details for BCM2712
In-Reply-To: <20241220-dt-bcm2712-fixes-v5-1-cbbf13d2e97a@raspberrypi.com>
References: <20241220-dt-bcm2712-fixes-v5-0-cbbf13d2e97a@raspberrypi.com>
 <20241220-dt-bcm2712-fixes-v5-1-cbbf13d2e97a@raspberrypi.com>
Message-ID: <mnvl24bydpajn7dyumq7cqt6dl6iyrzk6e7rksojt3ig2f7qbc@uytpnoa4t76o>

On Fri, Dec 20, 2024 at 06:11:11PM +0000, Dave Stevenson wrote:
> Commit 62948c62abca ("dt-bindings: display: Add BCM2712 HDMI bindings")
> added the compatible strings for BCM2712, but missed out that the
> number of interrupts changed, and for BCM2712 the driver changes[1]
> required that the interrupts are named.

I dopn't get what "interrupts are named" means here and I kept asking
about it, so the explanation is supposed to be in commit msg. Do you
mean that driver requires it? If so, then "the driver requires
interrupt-names since commit foo ("bar")" (and use Linux commit style of
referencing commits).


>  
> Update the schema to correct the interrupt requirements for BCM2712.
> (Requirements for BCM2711 should be unchanged).
> 
> [1] Commit 0b1dbe82e051 ("drm/vc4: hdmi: Add support for BCM2712 HDMI
> controllers")

I cannot find in this commit requirement of interrupt names. There is no
call to anything requiring names. Maybe I miss some context, like other
function introduced that? Can you point me to specific line of that
patch?

Because if you refer to external_irq_controller than I fail to see how
2711 works without the names.

Best regards,
Krzysztof



From krzk at kernel.org  Sun Dec 22 00:39:18 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 09:39:18 +0100
Subject: [PATCH v5 2/3] dt-bindings: display: Fix brcm,bcm2835-hvs
 bindings for BCM2712
In-Reply-To: <20241220-dt-bcm2712-fixes-v5-2-cbbf13d2e97a@raspberrypi.com>
References: <20241220-dt-bcm2712-fixes-v5-0-cbbf13d2e97a@raspberrypi.com>
 <20241220-dt-bcm2712-fixes-v5-2-cbbf13d2e97a@raspberrypi.com>
Message-ID: <874d26cf-af3d-4d24-860e-72573920da27@kernel.org>

On 20/12/2024 19:11, Dave Stevenson wrote:
> Commit 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> added the compatible string for BCM2712, but missed out that
> the number of interrupts and clocks changed too.
> 
> The driver commit adding support for BCM2712 [1] also requires that

The driver commit foo ("bar") ... BCM2712 also requires...



> both interrupts and clocks are named, so the relevant -names
> properties are also added to "required" for BCM2712.
> 
> Update to validate clock, interrupts, and their names for the BCM2712
> variant. (There should be no change in the binding requirements for
> the other variants).
> 
> [1] Commit 7687a12153d3 ("drm/vc4: hvs: Add support for BCM2712 HVS")

And drop this.

> 
> Fixes: 6cfcbe548a3a ("dt-bindings: display: Add BCM2712 HVS bindings")
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> ---
>  .../bindings/display/brcm,bcm2835-hvs.yaml         | 88 ++++++++++++++++++----
>  1 file changed, 74 insertions(+), 14 deletions(-)
> 


...

> +      properties:
> +        compatible:
> +          contains:
> +            const: brcm,bcm2711-hvs
> +
> +    then:
> +      properties:
> +        clocks:
> +          items:
> +            - description: Core Clock
> +        interrupts:
> +          maxItems: 1
> +        clock-names: false
> +        interrupt-names: false
> +
> +      required:
> +        - clocks
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: brcm,bcm2712-hvs
> +
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 2
> +          maxItems: 2
> +        clock-names:
> +          items:
> +            - const: core
> +            - const: disp
> +        interrupts:
> +          items:
> +            - description: Channel 0 End of frame
> +            - description: Channel 1 End of frame
> +            - description: Channel 2 End of frame
> +        interrupt-names:
> +          items:
> +            - const: ch0-eof
> +            - const: ch1-eof
> +            - const: ch2-eof
> +      required:
> +        - clocks
> +        - clock-names
> +        - interrupt-names
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: brcm,bcm2835-hvs
> +
> +    then:
> +      properties:

What about clocks here? Why isn't this a part of block with bcm2711 (as
enum)?

> +        interrupts:
> +          maxItems: 1
> +        clock-names: false
> +        interrupt-names: false
>  
>  examples:
>    - |
> 


Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec 22 00:44:10 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 09:44:10 +0100
Subject: [PATCH v6 2/5] dt-bindings: mailbox: add google,gs101-mbox
In-Reply-To: <20241220-acpm-v4-upstream-mbox-v6-2-a6942806e52a@linaro.org>
References: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
 <20241220-acpm-v4-upstream-mbox-v6-2-a6942806e52a@linaro.org>
Message-ID: <uo4zvw4sl6uxsj2ewvoue7l3obugivq5z74ukwnd4sj3ndtwhu@hxxque3r4nvb>

On Fri, Dec 20, 2024 at 01:49:57PM +0000, Tudor Ambarus wrote:
> Add bindings for the Samsung Exynos Mailbox Controller.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  .../bindings/mailbox/google,gs101-mbox.yaml        | 70 ++++++++++++++++++++++
>  include/dt-bindings/mailbox/google,gs101.h         | 14 +++++

Drop the header, not used.

>  2 files changed, 84 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
> new file mode 100644
> index 000000000000..a1fbc3b2b9de
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
> @@ -0,0 +1,70 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright 2024 Linaro Ltd.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mailbox/google,gs101-mbox.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung Exynos Mailbox Controller
> +
> +maintainers:
> +  - Tudor Ambarus <tudor.ambarus at linaro.org>
> +
> +description: |

Drop |

> +  The Samsung Exynos mailbox controller, used on Google GS101 SoC, has 16 flag
> +  bits for hardware interrupt generation and a shared register for passing
> +  mailbox messages. When the controller is used by the ACPM protocol the shared
> +  register is ignored and the mailbox controller acts as a doorbell.
> +  The controller just raises the interrupt to the firmware after the
> +  ACPM protocol has written the message to SRAM.
> +
> +properties:
> +  compatible:
> +    const: google,gs101-mbox
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    items:
> +      - const: pclk
> +
> +  interrupts:
> +    description: IRQ line for the RX mailbox.
> +    maxItems: 1
> +
> +  '#mbox-cells':
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - interrupts
> +  - '#mbox-cells'
> +
> +additionalProperties: false
> +
> +examples:
> +  # Doorbell mode.

Drop comment, not applicable now, I think.

Best regards,
Krzysztof



From krzk at kernel.org  Sun Dec 22 00:44:25 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 09:44:25 +0100
Subject: [PATCH v6 1/5] dt-bindings: mailbox: allow #mbox-cells = <0>;
In-Reply-To: <20241220-acpm-v4-upstream-mbox-v6-1-a6942806e52a@linaro.org>
References: <20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a@linaro.org>
 <20241220-acpm-v4-upstream-mbox-v6-1-a6942806e52a@linaro.org>
Message-ID: <uj4hxm6ijclixdq7wr5yfa7xnxjrom45ce7iyowf54kebkuelb@24ufqptjlwqg>

On Fri, Dec 20, 2024 at 01:49:56PM +0000, Tudor Ambarus wrote:
> There are mailbox clients that can discover the mailbox channel
> identifiers at runtime. For such cases passing the channel
> identifiers via DT is redundant.

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

Best regards,
Krzysztof



From krzk at kernel.org  Sun Dec 22 00:47:51 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 09:47:51 +0100
Subject: [PATCH v5 0/3] firmware: add Exynos ACPM protocol driver
In-Reply-To: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>
References: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>
Message-ID: <24gb4sffg7qgigtei7ons6hrmdkd7jiby672k6xvwv4y6jmfoo@x52v6iigm6rd>

On Fri, Dec 20, 2024 at 02:32:50PM +0000, Tudor Ambarus wrote:
> Alive Clock and Power Manager (ACPM) Message Protocol is defined for
> the purpose of communication between the ACPM firmware and masters
> (AP, AOC, ...). ACPM firmware operates on the Active Power Management
> (APM) module that handles overall power activities.
> 
> This protocol driver provides the interface for all the client drivers
> making use of the features offered by the APM. Add ACPM protocol support.
> 
> Changes in v5:
> - depends on:
>   - Link: https://lore.kernel.org/all/20241220-acpm-v4-upstream-mbox-v6-0-a6942806e52a at linaro.org/
>   - it uses the newly introduced mbox_request_channel_by_args() API
> - dt-bindings:
>   - drop redundant binding word from the commit subject
>   - remove extra blank line and update example with by complying to
>     #mbox-cells = <0>;
>   - drop Krzysztof's R-b tag as the example was updated.

This does not invalidate review. You just dropped argument from a
phandle, it's not even related to this binding. The format of phandle
depends on provider, not consumer binding.

Best regards,
Krzysztof



From krzk at kernel.org  Sun Dec 22 00:48:01 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 09:48:01 +0100
Subject: [PATCH v5 1/3] dt-bindings: firmware: add google,gs101-acpm-ipc
In-Reply-To: <20241220-gs101-acpm-v5-1-4f26b7fb3f5f@linaro.org>
References: <20241220-gs101-acpm-v5-0-4f26b7fb3f5f@linaro.org>
 <20241220-gs101-acpm-v5-1-4f26b7fb3f5f@linaro.org>
Message-ID: <edoc2enbb4ch3r7nb5b5jykm6f7aqbktqnj5ytke2b5fa5bcgv@ceinrartc3gn>

On Fri, Dec 20, 2024 at 02:32:51PM +0000, Tudor Ambarus wrote:
> Add bindings for the Samsung Exynos ACPM mailbox protocol.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  .../bindings/firmware/google,gs101-acpm-ipc.yaml   | 50 ++++++++++++++++++++++
>  1 file changed, 50 insertions(+)

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

Best regards,
Krzysztof



From maz at kernel.org  Sun Dec 22 01:04:29 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 22 Dec 2024 09:04:29 +0000
Subject: [PATCH 1/3] irqchip/gic-v3: Enable Rockchip 3588001 erratum workaround for RK3582
In-Reply-To: <20241222030355.2246-2-naoki@radxa.com>
References: <20241222030355.2246-1-naoki@radxa.com>
	<20241222030355.2246-2-naoki@radxa.com>
Message-ID: <86msgoozqa.wl-maz@kernel.org>

On Sun, 22 Dec 2024 03:03:53 +0000,
FUKAUMI Naoki <naoki at radxa.com> wrote:
> 
> Rockchip RK3582 is a scaled down version of Rockchip RK3588(S). Apply
> Rockchip 3588001 erratum workaround to RK3582.
> 
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  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 92244cfa0464..c59ce9332dc0 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -4861,7 +4861,8 @@ static bool __maybe_unused its_enable_rk3588001(void *data)
>  {
>  	struct its_node *its = data;
>  
> -	if (!of_machine_is_compatible("rockchip,rk3588") &&
> +	if (!of_machine_is_compatible("rockchip,rk3582") &&
> +	    !of_machine_is_compatible("rockchip,rk3588") &&
>  	    !of_machine_is_compatible("rockchip,rk3588s"))
>  		return false;
>  

Please use the relevant property for that purpose ("dma-noncoherent")
at the distributor and ITS levels. We're not adding extra compatibles
for this anymore, and you might as well fix the core dtsi to expose
such property.

Thanks,

	M.

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


From linus.walleij at linaro.org  Sun Dec 22 01:08:50 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 22 Dec 2024 10:08:50 +0100
Subject: [PATCH RFC 2/3] pinctrl: Add driver support for Amlogic SoCs
In-Reply-To: <23899c54-14ad-4724-9336-2df6fb485fd6@amlogic.com>
References: <20241211-amlogic-pinctrl-v1-0-410727335119@amlogic.com>
 <20241211-amlogic-pinctrl-v1-2-410727335119@amlogic.com> <CACRpkdbuj-_sPpdfcyg3_QNtzt9r7n-0HBGBKgy-rKUMhvGo4w@mail.gmail.com>
 <23899c54-14ad-4724-9336-2df6fb485fd6@amlogic.com>
Message-ID: <CACRpkdZn75ks4Gc7rm8jzkKM6y0JeQmUF3qmbJA+O+cEA9r--Q@mail.gmail.com>

Hi Xianwei!

On Wed, Dec 18, 2024 at 10:37?AM Xianwei Zhao <xianwei.zhao at amlogic.com> wrote:

> [Me]
> > In any way I recommend:
> >
> > - Renaming drivers/pinctrl/sunxi to drivers/pinctrl/amlogic
> >    so we keep this sorted by actual vendor, sunxi is apparently
> >    yours (AMlogic:s) isn't it?
> >
>
> It isn't. Sunxi is Allwinner SoCs.

My apologies. I mixed it up completely. :(

What do you think of the idea of a separate drivers/pinctrl/amlogic directory
though? I think there are already quite a few amlogic SoCs that need
to be supported and more will come.

> >> +       ret = pinconf_generic_parse_dt_config(np, info->pctl, &grp->configs,
> >> +                                             &grp->num_configs);
> >
> > But can't you just move this code around? grp->num_configs give the
> > number of configs, so why do you have to go and look up pinmux
> > above, can't you just use grp->num_configs instead of of_pins
> > and npins above?
> >
> They are different.
> The of_pins(grp->npins) specifies the mux values for pin-mux register
> and pin index in pinctrl. It can include multiple pins in groups.
>
> The grp->configs and grp->num_configs specify the configuration
> information for all pins of this groups(such as bias-pull-up,
> drive-strength-microamp)
>
> uart-d-pins2{
>         pinmux= <AML_PINMUX(AMLOGIC_GPIO_T, 7, AF2)>,
>                 <AML_PINMUX(AMLOGIC_GPIO_T, 8, AF2)>,
>                 <AML_PINMUX(AMLOGIC_GPIO_T, 9, AF2)>,
>                 <AML_PINMUX(AMLOGIC_GPIO_T, 10, AF2)>;
>         bias-pull-up;
>         drive-strength-microamp = <4000>;
> };

OK I get it ... I think. It's nice that you combine muxing and pin config
into the same node like this, it's very readable.

Think about if you even want to add generic helpers for this in
the generic code.

> >> +static void aml_pctl_dt_child_count(struct aml_pinctrl *info,
> >> +                                   struct device_node *np)
> >> +{
> >> +       struct device_node *child;
> >> +
> >> +       for_each_child_of_node(np, child) {
> >> +               if (of_property_read_bool(child, "gpio-controller")) {
> >> +                       info->nbanks++;
> >> +               } else {
> >> +                       info->nfunctions++;
> >> +                       info->ngroups += of_get_child_count(child);
> >> +               }
> >> +       }
> >> +}
> >
> > This looks like a weird dependency between gpio chips and
> > pins that I don't quite understand. Some comments and
> > references to the bindings will be needed so it is clear
> > what is going on.
> >
>
> A pinctrl device contains two types of nodes. The one named GPIO bank
> which includes "gpio-controller" property. The other one named function
> which includes one or more pin groups.
> The pin group include pinmux property(pin index in pinctrl dev,and mux
> vlaue in mux reg) and pin configuration properties.

OK I  guess the binding patch explains why you need several
separate gpio controller "bank" nodes instead of just the base
node being one for all of the pins (which is the most
common). In a way I like it because it often helps to divide
up GPIOs by bank.

Yours,
Linus Walleij


From krzysztof.kozlowski at linaro.org  Sun Dec 22 02:08:17 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 11:08:17 +0100
Subject: [PATCH v2] arm64: dts: exynos: gs101-oriole: configure
 simple-framebuffer
In-Reply-To: <20241220-gs101-simplefb-oriole-v2-1-df60e566932a@linaro.org>
References: <20241220-gs101-simplefb-oriole-v2-1-df60e566932a@linaro.org>
Message-ID: <173486209717.9271.11039463162908346528.b4-ty@linaro.org>


On Fri, 20 Dec 2024 10:32:50 +0000, Andr? Draszik wrote:
> The bootloader configures the display hardware for a framebuffer at the
> given address, let's add a simple-framebuffer node here until we get a
> proper DRM driver.
> 
> This has several benefits since it's an OLED display:
> * energy consumption goes down significantly, as it changes from white
>   (as left by bootloader) to black (linux console), and we generally
>   don't run out of battery anymore when plugged into a USB port
> * less of a burn-in effect I assume
> * phone stays cooler due to reduced energy consumption by display
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: exynos: gs101-oriole: configure simple-framebuffer
      https://git.kernel.org/krzk/linux/c/e32a7fc0b14564f9094f90053c74f500809ddf3c

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



From frank at oltmanns.dev  Sun Dec 22 02:17:09 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Sun, 22 Dec 2024 11:17:09 +0100
Subject: [PATCH 0/3] arm64: allwinner: a64: fix video output on Pinebook
In-Reply-To: <20241215053639.738890-1-anarsoul@gmail.com> (Vasily Khoruzhick's
	message of "Sat, 14 Dec 2024 21:34:56 -0800")
References: <20241215053639.738890-1-anarsoul@gmail.com>
Message-ID: <87pllk58ey.fsf@oltmanns.dev>

Hi Vasily,

On 2024-12-14 at 21:34:56 -0800, Vasily Khoruzhick <anarsoul at gmail.com> wrote:
> Since commit ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux"),
> TCON0 clock parent is always set to PLL_MIPI, but unfortunately it breaks
> video output on Pinebook.
>
> I did an experiment: I manually configured PLL_MIPI and PLL_VIDEO0_2X
> to the same clock rate and flipped the switch with devmem. Experiment clearly
> showed that whenever PLL_MIPI is selected as TCON0 clock parent, the video
> output stops working.
>
> To fix the issue, I partially reverted mentioned commit and added explicit
> TCON0 clock parent assignment to device tree. By default, it will be
> PLL_MIPI, and the only users with RGB output - Pinebook and Teres-I will
> override it in their dts.

I've successfully tested this series on my pinephone where it still
correctly selects PLL_MIPI.

Hence,
Tested-by: Frank Oltmanns <frank at oltmanns.dev> # on pinephone

I've also tested it on Ond?ej's downstream kernel (added him to cc),
where also the HDMI output continues to work.

Thank you and best regards,
  Frank

> Vasily Khoruzhick (3):
>   dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
>   arm64: dts: allwinner: a64: explicitly assign clock parent for TCON0
>   clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent
>
>  arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts |  2 ++
>  arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts  |  2 ++
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi         |  2 ++
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c                 | 11 -----------
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.h                 |  2 --
>  include/dt-bindings/clock/sun50i-a64-ccu.h            |  2 ++
>  6 files changed, 8 insertions(+), 13 deletions(-)


From towinchenmi at gmail.com  Sun Dec 22 04:05:28 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Sun, 22 Dec 2024 20:05:28 +0800
Subject: [PATCH v3 6/6] arm64/mm: Drop configurable 48-bit physical
 address space limit
In-Reply-To: <20241212081841.2168124-14-ardb+git@google.com>
References: <20241212081841.2168124-8-ardb+git@google.com>
 <20241212081841.2168124-14-ardb+git@google.com>
Message-ID: <bf93c563-f331-43c0-a145-1abf143bd0eb@gmail.com>

Hi Ard,

On 12/12/2024 16:18, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb at kernel.org>
> 
> Currently, the maximum supported physical address space can be
> configured as either 48 bits or 52 bits. The only remaining difference
> between these in practice is that the former omits the masking and
> shifting required to construct TTBR and PTE values, which carry bits #48
> and higher disjoint from the rest of the physical address.
> 
> The overhead of performing these additional calculations is negligible,
> and so there is little reason to retain support for two different
> configurations, and we can simply support whatever the hardware
> supports.

I am seeing a boot failure on Apple iPad 7 which uses 
CONFIG_ARM64_16K=y after this change in linux-next as commit
32d053d6f5e9, with nothing appearing on serial console with
earlycon enabled unless I set CONFIG_ARM64_VA_BITS_52=y. Reverting
this patch makes the kernel work again.

Nick Chan



From naoki at radxa.com  Sun Dec 22 04:10:40 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 22 Dec 2024 21:10:40 +0900
Subject: [PATCH 1/3] irqchip/gic-v3: Enable Rockchip 3588001 erratum
 workaround for RK3582
In-Reply-To: <86msgoozqa.wl-maz@kernel.org>
References: <20241222030355.2246-1-naoki@radxa.com>
 <20241222030355.2246-2-naoki@radxa.com> <86msgoozqa.wl-maz@kernel.org>
Message-ID: <88F271690E44F371+28d3216e-0517-4ff7-94bb-f36bbc980b29@radxa.com>

Hi Marc,

On 12/22/24 18:04, Marc Zyngier wrote:
> On Sun, 22 Dec 2024 03:03:53 +0000,
> FUKAUMI Naoki <naoki at radxa.com> wrote:
>>
>> Rockchip RK3582 is a scaled down version of Rockchip RK3588(S). Apply
>> Rockchip 3588001 erratum workaround to RK3582.
>>
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> ---
>>   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 92244cfa0464..c59ce9332dc0 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -4861,7 +4861,8 @@ static bool __maybe_unused its_enable_rk3588001(void *data)
>>   {
>>   	struct its_node *its = data;
>>   
>> -	if (!of_machine_is_compatible("rockchip,rk3588") &&
>> +	if (!of_machine_is_compatible("rockchip,rk3582") &&
>> +	    !of_machine_is_compatible("rockchip,rk3588") &&
>>   	    !of_machine_is_compatible("rockchip,rk3588s"))
>>   		return false;
>>   
> 
> Please use the relevant property for that purpose ("dma-noncoherent")
> at the distributor and ITS levels. We're not adding extra compatibles
> for this anymore, and you might as well fix the core dtsi to expose
> such property.

I see. I'll drop this patch in v2.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Thanks,
> 
> 	M.
> 




From conor at kernel.org  Sun Dec 22 05:11:33 2024
From: conor at kernel.org (Conor Dooley)
Date: Sun, 22 Dec 2024 13:11:33 +0000
Subject: [PATCH 2/3] dt-bindings: arm: rockchip: Add Radxa E52C
In-Reply-To: <20241222030355.2246-3-naoki@radxa.com>
References: <20241222030355.2246-1-naoki@radxa.com>
 <20241222030355.2246-3-naoki@radxa.com>
Message-ID: <20241222-wrench-chill-cbe767f2bd90@spud>

On Sun, Dec 22, 2024 at 03:03:54AM +0000, FUKAUMI Naoki wrote:
> Add devicetree binding for the Radxa E52C.
> 
> Radxa E52C is a compact network computer based on the Rockchip RK3582
> SoC.
> 
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>


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/20241222/f0c1f745/attachment.sig>

From krzk at kernel.org  Sun Dec 22 04:17:18 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 13:17:18 +0100
Subject: [PATCH 4/4] soc: samsung: exynos-pmu: enable CPU hotplug support
 for gs101
In-Reply-To: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-4-c72978f63713@linaro.org>
References: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
 <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-4-c72978f63713@linaro.org>
Message-ID: <fbdeffe0-c908-4df1-9096-350a7d330570@kernel.org>

On 13/12/2024 17:44, Peter Griffin wrote:
>  /*
> @@ -325,6 +328,52 @@ struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
>  }
>  EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
>  
> +/*
> + * CPU_INFORM register hint values which are used by
> + * EL3 firmware (el3mon).
> + */
> +#define CPU_INFORM_CLEAR	0
> +#define CPU_INFORM_C2		1
> +
> +static int cpuhp_pmu_online(unsigned int cpu)

exynos_cpuhp_pmu_online
or gs101_cpuhp_pmu_online
same for offline

> +{
> +	void __iomem *base = pmu_context->pmuintrgen_base;
> +	u32 reg;
> +	u32 mask;
> +
> +	/* clear cpu inform hint */
> +	regmap_write(pmu_context->pmureg, GS101_CPU_INFORM(cpu),
> +		     CPU_INFORM_CLEAR);
> +
> +	mask = (1 << cpu);

BIT(cpu)

> +
> +	writel(((0 << cpu) & mask), base + GS101_GRP2_INTR_BID_ENABLE);

I am not sure if I follow. You want to zero-out all other bits or enable
all other bits?

> +
> +	reg = readl(base + GS101_GRP2_INTR_BID_UPEND) & mask;
> +	writel(reg & mask, base + GS101_GRP2_INTR_BID_CLEAR);

reg is &mask twice.

I don't follow this either, are these auto-cleared? It feels like you
wanted to update some bits, but you are updating entire registers in
both cases.


> +
> +	return 0;
> +}
> +
> +static int cpuhp_pmu_offline(unsigned int cpu)
> +{
> +	void __iomem *base = pmu_context->pmuintrgen_base;
> +	u32 reg, mask;
> +
> +	/* set cpu inform hint */
> +	regmap_write(pmu_context->pmureg, GS101_CPU_INFORM(cpu),
> +		     CPU_INFORM_C2);
> +
> +	writel((1 << cpu), base + GS101_GRP2_INTR_BID_ENABLE);
> +
> +	mask = ((1 << cpu) | (1 << (cpu+8)));

What does 8 stands for?

> +
> +	reg = readl(base + GS101_GRP1_INTR_BID_UPEND) & mask;
> +	writel(reg & mask, base + GS101_GRP1_INTR_BID_CLEAR);
> +
> +	return 0;
> +}
> +
>  static int exynos_pmu_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -377,6 +426,28 @@ static int exynos_pmu_probe(struct platform_device *pdev)
>  	pmu_context->pmureg = regmap;
>  	pmu_context->dev = dev;
>  
> +	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_cpuhp) {
> +

Drop blank line

> +		pmu_context->pmuintrgen_base =
> +			devm_platform_ioremap_resource_byname(pdev, "pmu-intr-gen");
> +		/*
> +		 * To maintain support for older DTs that didn't specify pmu-intr-gen
> +		 * register region, just issue a warning rather than fail to probe.
> +		 */
> +		if (IS_ERR(pmu_context->pmuintrgen_base)) {
> +			dev_warn(&pdev->dev,
> +				 "failed to map pmu-intr-gen registers\n");

Test old DTS, I think you do write() to the ERR_PTR when
offlining/onlining...

> +		} else {
> +			cpuhp_setup_state(CPUHP_BP_PREPARE_DYN,
> +					"soc/exynos-pmu:prepare",
> +					cpuhp_pmu_online, NULL);
> +
> +			cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
> +					"soc/exynos-pmu:online",
> +					NULL, cpuhp_pmu_offline);
> +		}
> +	}
> +
>  	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init)
>  		pmu_context->pmu_data->pmu_init();
>  



Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec 22 03:38:30 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 12:38:30 +0100
Subject: [PATCH v2 1/3] dt-bindings: arm: google: add gs101-raven and
 generic gs101-pixel
In-Reply-To: <20241220-gs101-simplefb-v2-1-c10a8f9e490b@linaro.org>
References: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
 <20241220-gs101-simplefb-v2-1-c10a8f9e490b@linaro.org>
Message-ID: <d0c1511f-b052-4690-aefb-3fb41e1e5875@kernel.org>

On 20/12/2024 12:27, Andr? Draszik wrote:
> Raven is Google's code name for Pixel 6 Pro. Since there are
> differences compared to Pixel 6 (Oriole), we need to add a separate
> compatible for it.
> 
> We also want to support a generic DT, which can work on any type of

There are no such generic DT devices upstream, so we cannot add bindings
for them.

> gs101-based Pixel device, e.g. Pixel 6, or Pixel 6 Pro, or Pixel 6a (as
> a future addition). Such a DT will have certain nodes disabled / not
> added. To facilitate such a generic gs101-based Pixel device, also add
> a more generic gs101-pixel compatible. We can not just use the existing
> google,gs101 for that, as it refers to the SoC, not a board.
> 
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> ---
>  Documentation/devicetree/bindings/arm/google.yaml | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/google.yaml b/Documentation/devicetree/bindings/arm/google.yaml
> index e20b5c9b16bc..a8faf2256242 100644
> --- a/Documentation/devicetree/bindings/arm/google.yaml
> +++ b/Documentation/devicetree/bindings/arm/google.yaml
> @@ -34,11 +34,21 @@ properties:
>      const: '/'
>    compatible:
>      oneOf:
> -      - description: Google Pixel 6 / Oriole
> +      - description: Google GS101 Pixel devices, as generic Pixel, or Pixel 6
> +          (Oriole), or 6 Pro (Raven)
> +        minItems: 2
> +        maxItems: 3
>          items:
> -          - enum:
> -              - google,gs101-oriole
> -          - const: google,gs101
> +          enum:
> +            - google,gs101-oriole
> +            - google,gs101-raven
> +            - google,gs101-pixel
> +            - google,gs101

SoC cannot be a board in the same time.

> +        allOf:
> +          - contains:
> +              const: google,gs101-pixel
> +          - contains:
> +              const: google,gs101

This should be fixed list.


Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec 22 03:42:23 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 12:42:23 +0100
Subject: [PATCH v2 2/3] arm64: dts: exynos: gs101-pixel: add generic
 gs101-based Pixel support
In-Reply-To: <20241220-gs101-simplefb-v2-2-c10a8f9e490b@linaro.org>
References: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
 <20241220-gs101-simplefb-v2-2-c10a8f9e490b@linaro.org>
Message-ID: <33c7a520-dda9-4d3c-aa27-2f48786996a9@kernel.org>

On 20/12/2024 12:27, Andr? Draszik wrote:
> In order to support Pixel 6 (Oriole), Pixel 6 Pro (Raven), and Pixel 6a
> (Bluejay) correctly, we have to be able to distinguish them properly as
> we add support for more features.
> 
> For example, Raven has a larger display. There are other differences,
> like battery design capacity, etc.
> 
> To facilitate this, we create a generic gs101-based Pixel DT that can
> work on any such gs101-based device. At the same time, we move the

No, whatever insanity Android has there, please don't populate it to
upstream.

There is no such thing as "generic board" thus cannot be a
"generic DTS".

> Oriole specific parts that we have at the moment (display) into an
> overlay, making it easy to add support for Raven and Bluejay in a
> similar way.
> 
> Note1:
> Despite being an overlay, we instruct kbuild to create a merged
> gs101-oriole.dtb and a gs101-oriole.dtbo. This way existing scripts can
> keep working, but it also gives the option to just apply the overlay
> before boot (e.g. by the bootloader).
> 
> Note2:
> I've changed the simple-framebuffer node to specify the memory via
> memory-region instead of reg, as that avoids unnecessary duplication
> (of the size), and it avoids having to specify #address-cells
> and #size-cells in the chosen node (and duplicating this in the DTSO),
> which is otherwise necessary to keep dt_binding_check happy and DT
> validation working in general.
> 
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> ---
> Note: MAINTAINERS doesn't need updating, it covers this whole directory
> ---
>  arch/arm64/boot/dts/exynos/google/Makefile         |  6 ++--
>  .../arm64/boot/dts/exynos/google/gs101-oriole.dtso | 33 ++++++++++++++++++++++
>  .../{gs101-oriole.dts => gs101-pixel-generic.dts}  | 24 +++++++---------
>  3 files changed, 47 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/exynos/google/Makefile b/arch/arm64/boot/dts/exynos/google/Makefile
> index 0a6d5e1fe4ee..6e6b5319212a 100644
> --- a/arch/arm64/boot/dts/exynos/google/Makefile
> +++ b/arch/arm64/boot/dts/exynos/google/Makefile
> @@ -1,4 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
>  
> -dtb-$(CONFIG_ARCH_EXYNOS) += \
> -	gs101-oriole.dtb \
> +dtb-$(CONFIG_ARCH_EXYNOS) += gs101-pixel-generic.dtb
> +
> +gs101-oriole-dtbs := gs101-pixel-generic.dtb gs101-oriole.dtbo
> +dtb-$(CONFIG_ARCH_EXYNOS) += gs101-oriole.dtb
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dtso b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dtso
> new file mode 100644
> index 000000000000..43572039cd07
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dtso
> @@ -0,0 +1,33 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Oriole Device Tree
> + *
> + * Copyright 2021-2023 Google LLC
> + * Copyright 2023-2024 Linaro Ltd
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +&{/} {
> +	model = "Oriole";
> +	compatible = "google,gs101-oriole", "google,gs101-pixel", "google,gs101";

Boards are not overlays. Board equals DTB.

> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <1>;
> +
> +		splash at fac00000 {
> +			reg = <0x0 0xfac00000 (1080 * 2400 * 4)>;
> +			status = "okay";
> +		};
> +	};
> +};
> +
> +&framebuffer0 {
> +	width = <1080>;
> +	height = <2400>;
> +	stride = <(1080 * 4)>;
> +	format = "a8r8g8b8";
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-pixel-generic.dts
> similarity index 93%
> rename from arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
> rename to arch/arm64/boot/dts/exynos/google/gs101-pixel-generic.dts
> index 4e1625e3fbb4..48dc37afcb86 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
> +++ b/arch/arm64/boot/dts/exynos/google/gs101-pixel-generic.dts
> @@ -1,6 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * Oriole Device Tree
> + * generic gs101-based Pixel Device Tree
>   *
>   * Copyright 2021-2023 Google LLC
>   * Copyright 2023 Linaro Ltd - <peter.griffin at linaro.org>
> @@ -15,30 +15,24 @@
>  #include "gs101.dtsi"
>  
>  / {
> -	model = "Oriole";
> -	compatible = "google,gs101-oriole", "google,gs101";
> +	model = "GS101-based Pixel or derivative";
> +	compatible = "google,gs101-pixel", "google,gs101";
>  
>  	aliases {
>  		serial0 = &serial_0;
>  	};
>  
>  	chosen {
> -		#address-cells = <2>;
> -		#size-cells = <1>;
> -		ranges;
> -
>  		/* Bootloader expects bootargs specified otherwise it crashes */
>  		bootargs = "";
>  		stdout-path = &serial_0;
>  
>  		/* Use display framebuffer as setup by bootloader */
> -		framebuffer0: framebuffer at fac00000 {

I don't think this exists in current source. It does exist in thing I
was applying, but then this does not make much sense: add a framebuffer
which has to be changed, because it is not correct.

I'll drop the framebuffer patch.



Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec 22 03:43:33 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 12:43:33 +0100
Subject: [PATCH v2 3/3] arm64: dts: exynos: gs101-raven: add new board
 file
In-Reply-To: <20241220-gs101-simplefb-v2-3-c10a8f9e490b@linaro.org>
References: <20241220-gs101-simplefb-v2-0-c10a8f9e490b@linaro.org>
 <20241220-gs101-simplefb-v2-3-c10a8f9e490b@linaro.org>
Message-ID: <dbeb28be-1aac-400b-87c1-9764aca3a799@kernel.org>

On 20/12/2024 12:27, Andr? Draszik wrote:
> Raven is Google's code name for Pixel 6 Pro. Similar to Pixel 6
> (Oriole), this is also based around its Tensor gs101 SoC.
> 
> For now, the relevant difference here is the display resolution:
> 1440 x 3120 instead of 1080 x 2400.
> 
> Create a new board file to reflect this difference.

There is no board file here, I see only overlay.

> 
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> 
> ---
> Note: MAINTAINERS doesn't need updating, it covers this whole directory
> ---
>  arch/arm64/boot/dts/exynos/google/Makefile         |  3 ++
>  arch/arm64/boot/dts/exynos/google/gs101-raven.dtso | 33 ++++++++++++++++++++++

Nope, boards are not overlays. Boards are DTB.



Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec 22 03:47:15 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 12:47:15 +0100
Subject: [PATCH v3 2/4] arm64: dts: exynos: gs101: add AP to APM mailbox
 node
In-Reply-To: <20241220-gs101-acpm-dt-v3-2-642d64daa5d1@linaro.org>
References: <20241220-gs101-acpm-dt-v3-0-642d64daa5d1@linaro.org>
 <20241220-gs101-acpm-dt-v3-2-642d64daa5d1@linaro.org>
Message-ID: <f5e3d00e-8f98-46c6-8f1a-85a2169324ee@kernel.org>

On 20/12/2024 15:45, Tudor Ambarus wrote:
> GS101 has 14 mailbox controllers. Add the AP to APM mailbox node.
> 
> Mailbox controllers have a shared register that can be used for passing
> the mailbox messages. The AP to APM mailbox controller is used just as a
> doorbell mechanism. It raises interrupt to the firmware after the mailbox
> message has been written to SRAM where the TX/RX rings are defined.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> index 1441e9a252c2..6947dd081a0e 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> @@ -1445,6 +1445,15 @@ wakeup-interrupt-controller {
>  			};
>  		};
>  
> +		ap2apm_mailbox: mailbox at 17610000 {
> +			compatible = "google,gs101-mbox";


I don't think I have this in my tree and cover letter does not explain
where I can find bindings. Nothing in next from few days ago. Always
document in DTS patchset where are the bindings, unless it's obvious.

Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec 22 03:48:43 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 12:48:43 +0100
Subject: [PATCH v2 1/2] dt-bindings: i2c: exynos5: Add
 samsung,exynos8895-hsi2c compatible
In-Reply-To: <20241221151937.1659139-2-ivo.ivanov.ivanov1@gmail.com>
References: <20241221151937.1659139-1-ivo.ivanov.ivanov1@gmail.com>
 <20241221151937.1659139-2-ivo.ivanov.ivanov1@gmail.com>
Message-ID: <017c4a8a-4b18-4f7a-b10d-2596dadca8c1@kernel.org>

On 21/12/2024 16:19, Ivaylo Ivanov wrote:
> Add samsung,exynos8895-hsi2c dedicated compatible for representing
> I2C of Exynos8895 SoC. I2C buses may be implemented both as a part
> of USIv1 and separately.
> 
> Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1 at gmail.com>
> ---

Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>

Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec 22 03:51:58 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 12:51:58 +0100
Subject: [PATCH v2 1/1] arm64: dts: exynos990: Add clock management unit
 nodes
In-Reply-To: <20241215170803.1756850-2-igor.belwon@mentallysanemainliners.org>
References: <20241215170803.1756850-1-igor.belwon@mentallysanemainliners.org>
 <20241215170803.1756850-2-igor.belwon@mentallysanemainliners.org>
Message-ID: <9e69c21a-3d97-41e4-addd-d1ebd80f47ff@kernel.org>

On 15/12/2024 18:08, Igor Belwon wrote:
> Add CMU nodes for:
> - cmu_top: provides clocks for other blocks
> - cmu_hsi0: provides clocks for usb31
> 
> Signed-off-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>
> ---
>  arch/arm64/boot/dts/exynos/exynos990.dtsi | 28 +++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos990.dtsi b/arch/arm64/boot/dts/exynos/exynos990.dtsi
> index 2619f821bc7c..d6a8c04e6602 100644
> --- a/arch/arm64/boot/dts/exynos/exynos990.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos990.dtsi
> @@ -5,6 +5,7 @@
>   * Copyright (c) 2024, Igor Belwon <igor.belwon at mentallysanemainliners.org>
>   */
>  
> +#include <dt-bindings/clock/samsung,exynos990.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>  
>  / {
> @@ -199,6 +200,24 @@ pinctrl_peric1: pinctrl at 10730000 {
>  			interrupts = <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>;
>  		};
>  
> +		cmu_hsi0: clock-controller at 10a00000 {
> +			compatible = "samsung,exynos990-cmu-hsi0";

Does it depend on anything? Cover letter is quiet here, but it should
explain any dependencies.

> +			reg = <0x10a00000 0x8000>;
> +			#clock-cells = <1>;
> +
> +			clocks = <&oscclk>,
> +				 <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
> +				 <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
> +				 <&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
> +				 <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
> +			clock-names = "oscclk",
> +				      "bus",
> +				      "usb31drd",
> +				      "usbdp_debug",
> +				      "dpgtc";
> +

Not much improved. Still stray blank line.

> +		};
Best regards,
Krzysztof


From krzk at kernel.org  Sun Dec 22 04:06:50 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 13:06:50 +0100
Subject: [PATCH 2/4] dt-bindings: mfd: syscon: allow two reg regions for
 gs101-pmu
In-Reply-To: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-2-c72978f63713@linaro.org>
References: <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-0-c72978f63713@linaro.org>
 <20241213-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v1-2-c72978f63713@linaro.org>
Message-ID: <1408dcd1-9a46-4cb9-8443-5aa51d61ed56@kernel.org>

On 13/12/2024 17:44, Peter Griffin wrote:
> To avoid dtschema warnings allow google,gs101-pmu to have
> two reg regions.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
> I don't really like this patch, but also didn't want to submit the series
> with a dtschema warning ;-)
> 
> Possibly a better solution is when Robs patch
> `mfd: syscon: Allow syscon nodes without a "syscon" compatible` [1]

PMU which spans over two blocks is not a simple syscon. These would be
two syscon devices.

If you request regmap from such syscon, which regmap you get?

I am not sure whether the PMU is really split here. Usually the main PMU
was only one and additional blocks called PMU were somehow specialized
per each IP block.

Maybe you have here two devices, maybe only one. If it is only one, then
it is not a syscon anymore, IMO.



Best regards,
Krzysztof


From krzysztof.kozlowski at linaro.org  Sun Dec 22 06:26:05 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 15:26:05 +0100
Subject: [PATCH v1 1/1] arm64: dts: exynos990: Add a PMU node for the
 third cluster
In-Reply-To: <20241214115855.49138-2-umer.uddin@mentallysanemainliners.org>
References: <20241214115855.49138-1-umer.uddin@mentallysanemainliners.org>
 <20241214115855.49138-2-umer.uddin@mentallysanemainliners.org>
Message-ID: <173487756559.3738.15589488923856918285.b4-ty@linaro.org>


On Sat, 14 Dec 2024 11:58:55 +0000, Umer Uddin wrote:
> Since we have a PMU compatiable for Samsung's Mongoose cores now, drop
> the comment that explains the lack of it and define the node.
> 
> 

Applied, thanks!

[1/1] arm64: dts: exynos990: Add a PMU node for the third cluster
      https://git.kernel.org/krzk/linux/c/86c0d7f230fe71952cddac9905e4c090e09ecf3c

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



From krzysztof.kozlowski at linaro.org  Sun Dec 22 06:26:07 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 15:26:07 +0100
Subject: [PATCH] arm64: dts: exynos: Specify reserved secure memory
 explicitly
In-Reply-To: <20241211033027.12985-1-semen.protsenko@linaro.org>
References: <20241211033027.12985-1-semen.protsenko@linaro.org>
Message-ID: <173487756773.3738.7711760267747537170.b4-ty@linaro.org>


On Tue, 10 Dec 2024 21:30:27 -0600, Sam Protsenko wrote:
> Instead of carving out the secure area in 'memory' node, let's describe
> it in 'reserved-memory'. That makes it easier to understand both RAM
> regions and particular secure world memory region. Originally the device
> tree was created in a way to make sure it was well aligned with the way
> LittleKernel bootloader modified it. But later it was found the
> LittleKernel works fine with properly described reserved regions, so
> it's possible now to define those in a cleaner way.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: exynos: Specify reserved secure memory explicitly
      https://git.kernel.org/krzk/linux/c/11fd6c9b047c30c72dcea3f79c0acb7deb69c822

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



From krzk at kernel.org  Sun Dec 22 06:46:53 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 15:46:53 +0100
Subject: [PATCH RESEND v4 1/2] arm64: dts: exynos: Add Exynos9810 SoC
 support
In-Reply-To: <20241214-exynos9810-v4-1-4e91fbbc2133@gmail.com>
References: <20241214-exynos9810-v4-0-4e91fbbc2133@gmail.com>
 <20241214-exynos9810-v4-1-4e91fbbc2133@gmail.com>
Message-ID: <d1c6d2f2-f733-4cbe-8108-c9c9aaa417cc@kernel.org>

On 14/12/2024 15:56, Markuss Broks wrote:

> +		pinctrl0 = &pinctrl_alive;
> +		pinctrl1 = &pinctrl_aud;
> +		pinctrl2 = &pinctrl_chub;
> +		pinctrl3 = &pinctrl_cmgp;
> +		pinctrl4 = &pinctrl_fsys0;
> +		pinctrl5 = &pinctrl_fsys1;
> +		pinctrl6 = &pinctrl_peric0;
> +		pinctrl7 = &pinctrl_peric1;
> +		pinctrl8 = &pinctrl_vts;
> +	};
> +
> +	arm-a55-pmu {
> +		compatible = "arm,cortex-a55-pmu";
> +		interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-affinity = <&cpu0>,
> +				     <&cpu1>,
> +				     <&cpu2>,
> +				     <&cpu3>;
> +	};
> +
> +	mongoose-m3-pmu {
So the name chosen by previous people some time ago for arm PMU is
obviously not the best - forces either messed sorting or having PMU
nodes in different places. That's why people should almost always go
with prefix, no suffix. See regulators and clocks.

Fixed and applied.

Best regards,
Krzysztof


From krzysztof.kozlowski at linaro.org  Sun Dec 22 06:47:15 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 15:47:15 +0100
Subject: [PATCH RESEND v4 0/2] Add support for Exynos9810 SoC and
 Samsung Galaxy S9 (SM-G960F)
In-Reply-To: <20241214-exynos9810-v4-0-4e91fbbc2133@gmail.com>
References: <20241214-exynos9810-v4-0-4e91fbbc2133@gmail.com>
Message-ID: <173487883501.18913.4157239259617984127.b4-ty@linaro.org>


On Sat, 14 Dec 2024 16:56:45 +0200, Markuss Broks wrote:
> This series adds initial SoC support for the Samsung Exynos 9810
> SoC and initial board support for Samsung Galaxy S9 phone (SM-G960F),
> codenamed starlte.
> 
> The Exynos 9810 SoC is also used in S9 Plus (star2lte), Note 9 (crownlte),
> and perhaps more devices. Currently only Galaxy S9 DTS file is added but it
> should be fairly simple to add support for other devices based on this SoC,
> considering they're quite similar.
> 
> [...]

Applied, thanks!

[1/2] arm64: dts: exynos: Add Exynos9810 SoC support
      https://git.kernel.org/krzk/linux/c/698be6fe8f89b5edf533a85fba7258339c8b72d6
[2/2] arm64: dts: exynos: Add initial support for Samsung Galaxy S9 (SM-G960F)
      https://git.kernel.org/krzk/linux/c/63da297f0303c39025172cccafca7b55b169ec3c

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



From conor at kernel.org  Sun Dec 22 06:48:56 2024
From: conor at kernel.org (Conor Dooley)
Date: Sun, 22 Dec 2024 14:48:56 +0000
Subject: [PATCH 04/38] dt-bindings: pinctrl: Add rk3562 pinctrl support
In-Reply-To: <20241220103825.3509421-5-kever.yang@rock-chips.com>
References: <20241220103825.3509421-1-kever.yang@rock-chips.com>
 <20241220103825.3509421-5-kever.yang@rock-chips.com>
Message-ID: <20241222-moonscape-humongous-65531a3f1f3d@spud>

On Fri, Dec 20, 2024 at 06:37:50PM +0800, Kever Yang wrote:
> Add the compatible string for the rk3562 SoC.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

> ---
> 
>  Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
> index 6a23d845f1f2..80a2b1934849 100644
> --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
> @@ -44,6 +44,7 @@ properties:
>        - rockchip,rk3328-pinctrl
>        - rockchip,rk3368-pinctrl
>        - rockchip,rk3399-pinctrl
> +      - rockchip,rk3562-pinctrl
>        - rockchip,rk3568-pinctrl
>        - rockchip,rk3576-pinctrl
>        - rockchip,rk3588-pinctrl
> -- 
> 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/20241222/ef4a4b66/attachment.sig>

From conor at kernel.org  Sun Dec 22 06:51:20 2024
From: conor at kernel.org (Conor Dooley)
Date: Sun, 22 Dec 2024 14:51:20 +0000
Subject: [PATCH 01/38] dt-bindings: clock: add rk3562 cru bindings
In-Reply-To: <20241220103825.3509421-2-kever.yang@rock-chips.com>
References: <20241220103825.3509421-1-kever.yang@rock-chips.com>
 <20241220103825.3509421-2-kever.yang@rock-chips.com>
Message-ID: <20241222-grandpa-vessel-66e9ca9cde75@spud>

On Fri, Dec 20, 2024 at 06:37:47PM +0800, Kever Yang wrote:
> Document the device tree bindings of the rockchip rk3562 SoC
> clock and reset unit.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
> ---
> 
>  .../bindings/clock/rockchip,rk3562-cru.yaml   | 62 +++++++++++++++++++
>  1 file changed, 62 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3562-cru.yaml
> 
> diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3562-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3562-cru.yaml
> new file mode 100644
> index 000000000000..aa8dedf2bfce
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3562-cru.yaml
> @@ -0,0 +1,62 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/rockchip,rk3562-cru.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip rk3562 Clock and Reset Control Module
> +
> +maintainers:
> +  - Elaine Zhang <zhangqing at rock-chips.com>
> +  - Heiko Stuebner <heiko at sntech.de>
> +
> +description:
> +  The RK3562 clock controller generates the clock and also implements a reset
> +  controller for SoC peripherals. For example it provides SCLK_UART2 and
> +  PCLK_UART2, as well as SRST_P_UART2 and SRST_S_UART2 for the second UART
> +  module.
> +
> +properties:
> +  compatible:
> +    const: rockchip,rk3562-cru
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  "#reset-cells":
> +    const: 1
> +
> +  clocks:
> +    maxItems: 2
> +
> +  clock-names:
> +    items:
> +      - const: xin24m
> +      - const: xin32k
> +
> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon managing the "general register files" (GRF),
> +      if missing pll rates are not changeable, due to the missing pll
> +      lock status.

Two questions:
- Why would it ever be missing? Seems like you should make it required.
- Why is it not possible to look the grf up by compatible rather than
  phandle?

Cheers,
Conor.

> +
> +required:
> +  - compatible
> +  - reg
> +  - "#clock-cells"
> +  - "#reset-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    clock-controller at ff100000 {
> +      compatible = "rockchip,rk3562-cru";
> +      reg = <0xff100000 0x40000>;
> +      #clock-cells = <1>;
> +      #reset-cells = <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/20241222/79578f55/attachment.sig>

From krzysztof.kozlowski at linaro.org  Sun Dec 22 06:52:57 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 22 Dec 2024 15:52:57 +0100
Subject: [PATCH] arm64: dts: exynos8895: Rename PMU nodes to fixup sorting
Message-ID: <20241222145257.31451-1-krzysztof.kozlowski@linaro.org>

Nodes should be sorted by name but it is also nice to have same class of
devices together, so rename both PMU nodes (A53 and M2) to use "pmu"
prefix, instead of suffix.

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

---

I know we have everywhere else in pure-ARM designs nodes "arm-xxx-pmu",
but this is too trivial and unimportant to change.  I however want to
avoid copying unsorted-style code to new patches.
---
 arch/arm64/boot/dts/exynos/exynos8895.dtsi | 48 +++++++++++-----------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos8895.dtsi b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
index 90b318b2f08a..d31d74cc4580 100644
--- a/arch/arm64/boot/dts/exynos/exynos8895.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos8895.dtsi
@@ -26,30 +26,6 @@ aliases {
 		pinctrl7 = &pinctrl_peric1;
 	};
 
-	arm-a53-pmu {
-		compatible = "arm,cortex-a53-pmu";
-		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-affinity = <&cpu0>,
-				     <&cpu1>,
-				     <&cpu2>,
-				     <&cpu3>;
-	};
-
-	mongoose-m2-pmu {
-		compatible = "samsung,mongoose-pmu";
-		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-affinity = <&cpu4>,
-				     <&cpu5>,
-				     <&cpu6>,
-				     <&cpu7>;
-	};
-
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -149,6 +125,30 @@ oscclk: osc-clock {
 		clock-output-names = "oscclk";
 	};
 
+	pmu-a53 {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>,
+				     <&cpu1>,
+				     <&cpu2>,
+				     <&cpu3>;
+	};
+
+	pmu-mongoose-m2 {
+		compatible = "samsung,mongoose-pmu";
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu4>,
+				     <&cpu5>,
+				     <&cpu6>,
+				     <&cpu7>;
+	};
+
 	psci {
 		compatible = "arm,psci";
 		method = "smc";
-- 
2.43.0



From ardb at kernel.org  Sun Dec 22 07:35:06 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sun, 22 Dec 2024 16:35:06 +0100
Subject: [PATCH v3 6/6] arm64/mm: Drop configurable 48-bit physical
 address space limit
In-Reply-To: <bf93c563-f331-43c0-a145-1abf143bd0eb@gmail.com>
References: <20241212081841.2168124-8-ardb+git@google.com> <20241212081841.2168124-14-ardb+git@google.com>
 <bf93c563-f331-43c0-a145-1abf143bd0eb@gmail.com>
Message-ID: <CAMj1kXH8W=o7yqZjL1QHud8sfA5=-aJ9HGO1opPhwihdi_28pw@mail.gmail.com>

On Sun, 22 Dec 2024 at 13:05, Nick Chan <towinchenmi at gmail.com> wrote:
>
> Hi Ard,
>
> On 12/12/2024 16:18, Ard Biesheuvel wrote:
> > From: Ard Biesheuvel <ardb at kernel.org>
> >
> > Currently, the maximum supported physical address space can be
> > configured as either 48 bits or 52 bits. The only remaining difference
> > between these in practice is that the former omits the masking and
> > shifting required to construct TTBR and PTE values, which carry bits #48
> > and higher disjoint from the rest of the physical address.
> >
> > The overhead of performing these additional calculations is negligible,
> > and so there is little reason to retain support for two different
> > configurations, and we can simply support whatever the hardware
> > supports.
>
> I am seeing a boot failure on Apple iPad 7 which uses
> CONFIG_ARM64_16K=y after this change in linux-next as commit
> 32d053d6f5e9, with nothing appearing on serial console with
> earlycon enabled unless I set CONFIG_ARM64_VA_BITS_52=y. Reverting
> this patch makes the kernel work again.
>

Thanks for the report.

This is a known issue and has been fixed already in the arm64 tree a
couple of days ago.

Once linux-next is regenerated, things should start working again.


From o.rempel at pengutronix.de  Sun Dec 22 07:59:43 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Sun, 22 Dec 2024 16:59:43 +0100
Subject: [PATCH net-next RFC 0/5] net: phy: Introduce a port
 representation
In-Reply-To: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
References: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
Message-ID: <Z2g3b_t3KwMFozR8@pengutronix.de>

Hi Maxime,

On Fri, Dec 20, 2024 at 09:14:59PM +0100, Maxime Chevallier wrote:
> Hello everyone,
> 
> This is a long overdue series to kick-off the introduction of a better representation
> of front-facing ports for ethernet interfaces.
> 
> First, a short disclaimer. This series is RFC, and there are quite a lot of
> shortcomings :
> 
>  - There's no DT binding although this series adds a generic representation of
>    ports
>  - The port representation is in a minimal form
>  - No SFP support is included, but it will be required for that series to come
>    out of RFC as we can't gracefully handle multi-port interfaces without it.
> 
> These shortcomigs come from timing constraints, but also because I'd like to
> start discussing that topic with some code as a basis.
> 
> For now, the only representation we have about the physical ports of an interface
> come from the 'port' field (PORT_FIBRE, PORT_TP, PORT_MII, etc.), the presence or
> not of an SFP module and the linkmodes reported by the ethtol ksettings ops. This
> isn't enough to get a good idea of what the actual interface with the outside world
> looks like.
> 
> The end-goal of the work this series is a part of is to get support for multi-port
> interfaces. My end use-case has 2 ports, each driven by a dedicated PHY, but this
> also applies to dual-port PHYs.
> 
> The current series introduces the object "struct phy_port". The naming may be
> improved, as I think we could consider supporting port representation without
> depending on phylib (not the case in this RFC). For now, not only do we integrate
> that work in phylib, but only PHY-driven ports are supported.
> 
> In some situations, having a good representation of the physical port in devicetree
> proves to be quite useful. We're seeing vendor properties to address the lack of
> port representation such as micrel,fiber-mode or ti,fiber-mode, but there are needs
> for more (glitchy straps that detect fiber mode on a PHY connected to copper,
> RJ45 ports connected with 2 lanes only, ...).
> 
> As I said this RFC has no binding, sorry about that, but let's take a look at
> the proposed DT syntax :
> 
> Example 1 : PHY with RJ45 connected with 2 lanes only
> 
> &mdio {
> 
> 	ge_phy: ethernet-phy at 0 {
> 		reg = <0>;
> 
> 		mdi {
> 			port at 0 {
> 				media = "BaseT",
> 				lanes = <2>;
> 			};
> 		};
> 
> 	};
> };
> 
> Example 2 : PHY with a 100BaseFX port, without SFP
> 
> &mdio {
> 
> 	fiber-phy: ethernet-phy at 0 {
> 		reg = <0>;
> 
> 		mdi {
> 			port at 0 {
> 				media = "BaseF",
> 				lanes = <1>;
> 			};
> 		};
> 
> 	};
> };
> 
> These ports may even be used to specify PSE-PD information for PoE ports that
> are drivern by a dedicated PoE controller sitting in-between the PHY and the
> connector :
> 
> &mdio {
> 
> 	ge_phy: ethernet-phy at 0 {
> 		reg = <0>;
> 
> 		mdi {
> 			port at 0 {
> 				media = "BaseT",
> 				lanes = <4>;
> 				pse = <&pse1>;
> 			};
> 		};
> 
> 	};
> };
> 
> The ports are initialized using the following sequence :
> 
> 1: The PHY driver's probe() function indicated the max number of ports the device
> can control
> 
> 2: We parse the devicetree to find generic port representations
> 
> 3: If we don't have at least one port from DT, we create one
> 
> 4: We call the phy's .attach_port() for each port created so far. This allows
>    the phy driver either to take action based on the generic port devicetree
>    indications, or to populate the port information based on straps and
>    vendor-specific DT properties (think micrel,fiber-mode and similar)
> 
> 5: If the ports are still not initialized (no .attach_port, no generic DT), then
>    we use snesible default value from what the PHY's supported modes.
> 
> 6: We reconstruct the PHY's supported field in case there are limitations from the
>    port (2 lanes on BaseT for example). This last step will need to be changed
>    when SFP gets added.
> 
> So, the current work is only about init. The next steps for that work are :
> 
>  - Introduce phy_port_ops, including a .configure() and a .read_status() to get
>  proper support for multi-port PHYs. This also means maintaining a list of
>  advertising/lp_advertising modes for each port.
> 
>  - Add SFP support. It's a tricky part, the way I see that and have prototyped is
>  by representing the SFP cage itself as a port, as well as the SFP module's port.
>  ports therefore become chainable.
> 
>  - Add the ability to list the ports in userspace.
> 
> Prototype work for the above parts exist, but due to lack of time I couldn't get
> them polished enough for inclusion in that RFC.
> 
> Let me know if you see this going in the right direction, I'm really all ears
> for suggestions on this, it's quite difficult to make sure no current use-case
> breaks and no heavy rework is needed in PHY drivers.
> 
> Patches 1, 2 and 3 are preparatory work for the mediums representation. Patch 4
> introduces the phy_port and patch 5 shows an example of usage in the dp83822 phy.


I love the idea of introducing a port description. It?s a step in the right.
However, in the proposed schema, I see some weak points that could be improved
for better flexibility and usability.

### Weak Points Identified

1. **`lanes` Do Not Provide Enough Information**
   The concept of "lanes" can be ambiguous, as it is context-dependent. For
differential connections, a lane typically refers to a differential pair, but
the schema doesn't clearly define how the lanes map to physical wires or pins.
By describing explicit pin mappings and supported modes, the `lanes` property
becomes obsolete.

2. **`media` Lacks Sufficient Detail**
   The `media` property currently doesn?t add meaningful information for
describing the physical characteristics of a port. By defining the connector
type (e.g., RJ45, BNC, LC) and supported modes explicitly, the need for the
`media` property is removed.

### Proposed Port Description Schema

Here?s how I imagine the port description could look to address these issues:

#### **Device Tree Example**
/* Ports should be in the root of DT */
ports {
    /* Twisted-Pair Example */
    port0: ethernet-port at 0 {
        reg = <0>; /* Port index */
        label = "ETH0"; /* Physical label on the device */
        connector = "RJ45"; /* Connector type */
        supported-modes = <10BaseT 100BaseTX>; /* Supported modes */

        pairs {
            pair at 0 {
                name = "A"; /* Pair A */
                pins = <1 2>; /* Connector pins */
                phy-mapping = <PHY_TX0_P PHY_TX0_N>; /* PHY pin mapping */
                pse-mapping = <PSE_OUT0_P PSE_OUT0_N>; /* PSE pin mapping */
            };
            pair at 1 {
                name = "B"; /* Pair B */
                pins = <3 6>;
                phy-mapping = <PHY_RX0_P PHY_RX0_N>;
                pse-mapping = <PSE_OUT1_P PSE_OUT1_N>;
            };
        };

        pse = <&pse1>; /* Reference to attached PSE controller */

        leds {
            link = <&led0>; /* Link status LED */
            activity = <&led1>; /* Activity LED */
        };
    };

    /* Single-Pair Ethernet (SPE) Example */
    port1: ethernet-port at 1 {
        reg = <1>;
        label = "SPE1";
        connector = "H-MTD"; /* Single-pair connector */
        supported-modes = <1000BaseT1>; /* Supported SPE modes */

        pairs {
            pair at 0 {
                name = "A"; /* Single pair for SPE */
                pins = <1 2>;
                phy-mapping = <PHY_TXRX0_P PHY_TXRX0_N>;
                pse-mapping = <PSE_OUT0_P PSE_OUT0_N>;
            };
        };

        pse = <&pse2>; /* Reference to a different PSE controller */

        leds {
            link = <&led3>;
            activity = <&led4>;
        };
    };

    /* Coaxial Example */
    port2: ethernet-port at 2 {
        reg = <2>;
        label = "COAX0"; /* Physical label for coaxial port */
        connector = "BNC"; /* Connector type for coaxial */
        supported-modes = <10Base2>; /* Supported coaxial modes */

        coaxial {
            pins = <1>; /* Signal pin for coaxial port */
            phy-mapping = <PHY_SIG>; /* Single-ended PHY signal mapping */
            pse-mapping = <PSE_OUT>; /* PSE mapping (if applicable) */
        };
    };

    /* Fiber Example */
    port3: ethernet-port at 3 {
        reg = <3>;
        label = "FIBER0"; /* Physical label for fiber port */
        connector = "LC"; /* Connector type for fiber */
        supported-modes = <100BaseFX>; /* Supported fiber modes */

        fiber {
            tx-pins = <1 2>; /* TX signal pins for fiber */
            rx-pins = <3 4>; /* RX signal pins for fiber */
            phy-mapping = <PHY_TX_P PHY_TX_N PHY_RX_P PHY_RX_N>; /* TX/RX PHY mappings */
        };
    };

    /* SFP Port Example */
    port4: ethernet-port at 4 {
        reg = <4>; /* Port index */
        label = "SFP0"; /* Physical label for the SFP port */
        connector = "SFP"; /* Connector type for SFP */
        supported-modes = <1000BaseX 10GBaseSR>; /* Supported SFP modes */

        sfp {
            tx-pins = <1 2>; /* TX differential pair for SFP module */
            rx-pins = <3 4>; /* RX differential pair for SFP module */
            phy-mapping = <PHY_TX_P PHY_TX_N PHY_RX_P PHY_RX_N>; /* TX/RX PHY mappings */

            i2c = <&i2c0>; /* Reference to the I2C bus for SFP module management */
            mod-def0 = <&gpio1 5 GPIO_ACTIVE_HIGH>; /* GPIO for MOD-DEF0 */
            tx-disable = <&gpio1 6 GPIO_ACTIVE_HIGH>; /* GPIO for TX_DISABLE */
            los = <&gpio1 7 GPIO_ACTIVE_HIGH>; /* GPIO for Loss of Signal (LOS) */
            presence = <&gpio1 8 GPIO_ACTIVE_HIGH>; /* GPIO for module presence */
        };

        leds {
            link = <&led5>; /* Link status LED */
            activity = <&led6>; /* Activity LED */
        };
    };
};

### How This Schema Addresses the Problems

1. **Precise Pair and Pin Mapping** 
   Each pair is explicitly described with its physical connector pins and
corresponding mappings to PHY and PSE pins. This eliminates ambiguity around
lane definitions and allows the PHY to handle pair-specific configurations like
polarity inversion or swapped pairs.

2. **Simplified Media Representation**
   By specifying `connector` (e.g., RJ45, LC, BNC), the schema provides
practical information about the physical interface without requiring an
abstract `media` property.

3. **Support for LEDs and Power Delivery**
   The schema integrates additional hardware elements like LED assignments and
PSE references, making it easier to configure ports for diagnostics and power
delivery (PoE/PoDL).

I hope this feedback helps refine the port description schema. Let me know what
you think, and I?m happy to discuss this further!

Best 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 heiko at sntech.de  Sun Dec 22 08:02:30 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sun, 22 Dec 2024 17:02:30 +0100
Subject: [PATCH 04/38] dt-bindings: pinctrl: Add rk3562 pinctrl support
In-Reply-To: <20241220103825.3509421-5-kever.yang@rock-chips.com>
References: <20241220103825.3509421-1-kever.yang@rock-chips.com>
 <20241220103825.3509421-5-kever.yang@rock-chips.com>
Message-ID: <6755532.4vTCxPXJkl@diego>

Am Freitag, 20. Dezember 2024, 11:37:50 CET schrieb Kever Yang:
> Add the compatible string for the rk3562 SoC.
> 
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>




From macroalpha82 at gmail.com  Sun Dec 22 08:51:24 2024
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Sun, 22 Dec 2024 10:51:24 -0600
Subject: [PATCH 1/3] ASoC: dt-bindings: sun4i-a10-codec: add hp-det-gpios
In-Reply-To: <20241221094122.27325-2-ryan@testtoast.com>
References: <20241221094122.27325-1-ryan@testtoast.com>
 <20241221094122.27325-2-ryan@testtoast.com>
Message-ID: <6768438d.4a0a0220.399c57.89b6@mx.google.com>

On Sat, Dec 21, 2024 at 10:26:32PM +1300, Ryan Walklin wrote:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Devices integrating Allwinner SoCs may use line-out or headphone jacks
> with jack detection circuits attached to a GPIO. Support defining these
> in DTs.
> 
> A number of Anbernic devices featuring the H700 SoC use this mechanism
> to switch between a headphone jack and an internal speaker, so add these
> to the allowed routing items.
> 
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> Signed-off-by: Ryan Walklin <ryan at testtoast.com>
> ---
>  .../bindings/sound/allwinner,sun4i-a10-codec.yaml           | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
> index ebc9097f936ad..b4b711e80b65a 100644
> --- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
> +++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
> @@ -98,6 +98,10 @@ properties:
>      maxItems: 1
>      description: GPIO to enable the external amplifier
>  
> +  allwinner,hp-det-gpios:
> +    maxItems: 1
> +    description: GPIO for headphone/line-out detection
> +

If possible, I wonder if we can keep this without the vendor prefix?
It looks like for now Nvidia and some Rockchip codecs have the vendor
prefix, but audio-graph bindings and Freescale codec bindings have this
as a non-specific property (and it looks like simple-audio-card does it
either as "hp-det-gpios" or "simple-audio-card,hp-det-gpios" depending
upon the circumstances).

Also, the behavior of this is very specific to just the Headphone sink,
so we should drop the line-out text from the description. If someone
sets the routing as `"Headphone", "LINEOUT"` the state of the GPIO will
affect the audio path, but `"Line Out", "LINEOUT"` will not be impacted
by the state of the GPIO.

Thank you,
Chris

>  required:
>    - "#sound-dai-cells"
>    - compatible
> @@ -247,8 +251,10 @@ allOf:
>          allwinner,audio-routing:
>            items:
>              enum:
> +              - Headphone
>                - LINEOUT
>                - Line Out
> +              - Speaker
>  
>          dmas:
>            items:
> -- 
> 2.47.1
> 
> 


From mkl at pengutronix.de  Sun Dec 22 08:53:08 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Sun, 22 Dec 2024 17:53:08 +0100
Subject: [PATCH v6 0/7] can: m_can: Add am62 wakeup support
In-Reply-To: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
References: <20241219-topic-mcan-wakeup-source-v6-12-v6-0-1356c7f7cfda@baylibre.com>
Message-ID: <20241222-opalescent-athletic-cuttlefish-c96337-mkl@pengutronix.de>

On 19.12.2024 20:57:51, Markus Schneider-Pargmann wrote:
> Hi,
> 
> Series
> ------
> am62, am62a and am62p support Partial-IO, a poweroff SoC state with a
> few pin groups being active for wakeup.
> 
> To support mcu_mcan0 and mcu_mcan1 wakeup for the mentioned SoCs, the
> series introduces a notion of wake-on-lan for m_can. If the user decides
> to enable wake-on-lan for a m_can device, the device is set to wakeup
> enabled. A 'wakeup' pinctrl state is selected to enable wakeup flags for
> the relevant pins. If wake-on-lan is disabled the default pinctrl is
> selected.
> 
> After feedback from Nishanth and Krzysztof, I moved to a wakeup-source
> property that can be a list of powerstates in which the device is wakeup
> capable. This describes special cases like Partial-IO where the device
> is powered off but pins can be sensible to changes and trigger a wakeup.
> 
> It is based on v6.13-rc1.
> 
> Partial-IO
> ----------
> This series is part of a bigger topic to support Partial-IO on am62,
> am62a and am62p. Partial-IO is a poweroff state in which some pins are
> able to wakeup the SoC. In detail MCU m_can and two serial port pins can
> trigger the wakeup.
> A documentation can also be found in section 6.2.4 in the TRM:
>   https://www.ti.com/lit/pdf/spruiv7
> 
> This other series is relevant for the support of Partial-IO:
> 
>  - firmware: ti_sci: Partial-IO support
>    https://gitlab.baylibre.com/msp8/linux/-/tree/topic/am62-partialio/v6.13?ref_type=heads
> 
> Testing
> -------
> A test branch is available here that includes all patches required to
> test Partial-IO:
> 
> https://gitlab.baylibre.com/msp8/linux/-/tree/integration/am62-partialio/v6.13?ref_type=heads
> 
> After enabling Wake-on-LAN the system can be powered off and will enter
> the Partial-IO state in which it can be woken up by activity on the
> specific pins:
>     ethtool -s can0 wol p
>     ethtool -s can1 wol p
>     poweroff
> 
> I tested these patches on am62-lp-sk.
> 
> Best,
> Markus
> 
> Previous versions:
>  v1: https://lore.kernel.org/lkml/20240523075347.1282395-1-msp at baylibre.com/
>  v2: https://lore.kernel.org/lkml/20240729074135.3850634-1-msp at baylibre.com/
>  v3: https://lore.kernel.org/lkml/20241011-topic-mcan-wakeup-source-v6-12-v3-0-9752c714ad12 at baylibre.com
>  v4: https://lore.kernel.org/r/20241015-topic-mcan-wakeup-source-v6-12-v4-0-fdac1d1e7aa6 at baylibre.com
>  v5: https://lore.kernel.org/r/20241028-topic-mcan-wakeup-source-v6-12-v5-0-33edc0aba629 at baylibre.com
> 
> Changes in v6:
>  - Rebased to v6.13-rc1
>  - After feedback of the other Partial-IO series, I updated this series
>    and removed all use of regulator-related patches.
>  - wakeup-source is now not only a boolean property but can also be a
>    list of power states in which the device is wakeup capable.
> 
> Changes in v5:
>  - Make the check of wol options nicer to read
> 
> Changes in v4:
>  - Remove leftover testing code that always returned -EIO in a specific
>  - Redesign pincontrol setup to be easier understandable and less nested
>  - Fix missing parantheses around wol_enable expression
>  - Remove | from binding description
> 
> Changes in v3:
>  - Rebase to v6.12-rc1
>  - Change 'wakeup-source' to only 'true'
>  - Simplify m_can_set_wol by returning early on error
>  - Add vio-suuply binding and handling of this optional property.
>    vio-supply is used to reflect the SoC architecture and which power
>    line powers the m_can unit. This is important as some units are
>    powered in special low power modes.
> 
> Changes in v2:
>  - Rebase to v6.11-rc1
>  - Squash these two patches for the binding into one:
>    dt-bindings: can: m_can: Add wakeup-source property
>    dt-bindings: can: m_can: Add wakeup pinctrl state
>  - Add error handling to multiple patches of the m_can driver
>  - Add error handling in m_can_class_allocate_dev(). This also required
>    to add a new patch to return error pointers from
>    m_can_class_allocate_dev().
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>

LGTM, next we need Krzysztof Kozlowski's ACK for DT bindings update. The
dts changes (patches 5...7) will not go via the CAN tree but AFAICS via
Vignesh Raghavendra.

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/20241222/dc668d30/attachment.sig>

From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:16 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:16 +0100
Subject: [PATCH v6 01/18] dt-bindings: clock: imx8mm: add VIDEO_PLL clocks
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-2-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's add the IMX8MM_VIDEO_PLL[_*]
definitions to be consistent with the RM and avoid misunderstandings.

The IMX8MM_VIDEO_PLL1* constants have not been removed to ensure
backward compatibility of the patch.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

---

Changes in v6:
- Add 'Acked-by' tag of Krzysztof Kozlowski

Changes in v5:
- New

 include/dt-bindings/clock/imx8mm-clock.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
index 1f768b2eeb1a..102d8a6cdb55 100644
--- a/include/dt-bindings/clock/imx8mm-clock.h
+++ b/include/dt-bindings/clock/imx8mm-clock.h
@@ -16,7 +16,8 @@
 #define IMX8MM_CLK_EXT4				7
 #define IMX8MM_AUDIO_PLL1_REF_SEL		8
 #define IMX8MM_AUDIO_PLL2_REF_SEL		9
-#define IMX8MM_VIDEO_PLL1_REF_SEL		10
+#define IMX8MM_VIDEO_PLL_REF_SEL		10
+#define IMX8MM_VIDEO_PLL1_REF_SEL		IMX8MM_VIDEO_PLL_REF_SEL
 #define IMX8MM_DRAM_PLL_REF_SEL			11
 #define IMX8MM_GPU_PLL_REF_SEL			12
 #define IMX8MM_VPU_PLL_REF_SEL			13
@@ -26,7 +27,8 @@
 #define IMX8MM_SYS_PLL3_REF_SEL			17
 #define IMX8MM_AUDIO_PLL1			18
 #define IMX8MM_AUDIO_PLL2			19
-#define IMX8MM_VIDEO_PLL1			20
+#define IMX8MM_VIDEO_PLL			20
+#define IMX8MM_VIDEO_PLL1			IMX8MM_VIDEO_PLL
 #define IMX8MM_DRAM_PLL				21
 #define IMX8MM_GPU_PLL				22
 #define IMX8MM_VPU_PLL				23
@@ -36,7 +38,8 @@
 #define IMX8MM_SYS_PLL3				27
 #define IMX8MM_AUDIO_PLL1_BYPASS		28
 #define IMX8MM_AUDIO_PLL2_BYPASS		29
-#define IMX8MM_VIDEO_PLL1_BYPASS		30
+#define IMX8MM_VIDEO_PLL_BYPASS			30
+#define IMX8MM_VIDEO_PLL1_BYPASS		IMX8MM_VIDEO_PLL_BYPASS
 #define IMX8MM_DRAM_PLL_BYPASS			31
 #define IMX8MM_GPU_PLL_BYPASS			32
 #define IMX8MM_VPU_PLL_BYPASS			33
@@ -46,7 +49,8 @@
 #define IMX8MM_SYS_PLL3_BYPASS			37
 #define IMX8MM_AUDIO_PLL1_OUT			38
 #define IMX8MM_AUDIO_PLL2_OUT			39
-#define IMX8MM_VIDEO_PLL1_OUT			40
+#define IMX8MM_VIDEO_PLL_OUT			40
+#define IMX8MM_VIDEO_PLL1_OUT			IMX8MM_VIDEO_PLL_OUT
 #define IMX8MM_DRAM_PLL_OUT			41
 #define IMX8MM_GPU_PLL_OUT			42
 #define IMX8MM_VPU_PLL_OUT			43
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:17 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:17 +0100
Subject: [PATCH v6 02/18] clk: imx8mm: rename video_pll1 to video_pll
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-3-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's rename "video_pll1" to
"video_pll" to be consistent with the RM and avoid misunderstandings.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---
The patch, which simply replaces video_pll1 with video_pll, highlights
many warnings raised by checkpatch.pl. These are not generated by the
changes made but are inherited from how the module was originally
written. Fixing them would have meant "obscuring" the actual changes
introduced.

(no changes since v5)

Changes in v5:
- Split the patch dropping the dt-bindings changes.

Changes in v4:
- New

 drivers/clk/imx/clk-imx8mm.c | 102 +++++++++++++++++------------------
 1 file changed, 51 insertions(+), 51 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index 342049b847b9..8a1fc7e17ba2 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -28,7 +28,7 @@ static u32 share_count_nand;
 static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
 static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
 static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
-static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char *video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
 static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
 static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
 static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
@@ -42,22 +42,22 @@ static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m
 static const char * const imx8mm_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
 
 static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m",
-				       "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+				       "sys_pll1_800m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", };
 
 static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
 					"sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", };
 
 static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
-					  "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					  "sys_pll2_1000m", "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
-					  "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					  "sys_pll2_1000m", "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m",
-					     "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",};
+					     "sys_pll2_1000m", "audio_pll1_out", "video_pll_out", "sys_pll1_100m",};
 
 static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
-					     "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+					     "sys_pll2_200m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", };
 
 static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
 					       "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
@@ -72,28 +72,28 @@ static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pl
 					     "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
 
 static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m",
-					      "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
+					      "audio_pll1_out", "video_pll_out", "clk_ext2", "clk_ext3", };
 
 static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
 					    "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
 
 static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
-					    "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					    "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
-					    "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					    "audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m",
-					"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+					"audio_pll1_out", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m",
-					    "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", };
+					    "sys_pll1_800m", "audio_pll1_out", "video_pll_out", };
 
 static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
-					"sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+					"sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll_out", };
 
 static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m",
-					      "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+					      "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll_out", };
 
 static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m",
 					     "sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", };
@@ -108,10 +108,10 @@ static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_8
 					   "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
 
 static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "dummy", "sys_pll1_800m", "sys_pll2_1000m",
-					      "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+					      "sys_pll1_160m", "video_pll_out", "sys_pll3_out", "audio_pll2_out", };
 
 static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "dummy", "sys_pll1_800m", "sys_pll2_1000m",
-						"sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+						"sys_pll1_160m", "video_pll_out", "sys_pll3_out", "audio_pll2_out", };
 
 static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
 					       "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
@@ -122,47 +122,47 @@ static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_p
 static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
 					      "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
 
-static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out", "audio_pll1_out",
 					     "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
-static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out", "audio_pll1_out",
 						"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
-static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
 
-static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
 
-static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
 
-static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
 
-static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
 
-static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
 
-static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					   "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
 
-static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					   "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
 
 static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
-					     "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
+					     "sys_pll1_160m", "audio_pll1_out", "video_pll_out", "clk_ext4", };
 
 static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
-					       "clk_ext3", "clk_ext4", "video_pll1_out", };
+					       "clk_ext3", "clk_ext4", "video_pll_out", };
 
 static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
-					     "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
+					     "sys_pll2_500m", "video_pll_out", "audio_pll2_out", };
 
 static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
-					 "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
+					 "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll_out", };
 
 static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m",
 					 "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
@@ -174,16 +174,16 @@ static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1
 					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
 
 static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
-					 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+					 "video_pll_out", "audio_pll2_out", "sys_pll1_133m", };
 
 static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
 					  "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
@@ -213,19 +213,19 @@ static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1
 					   "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
 
 static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+					 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll_out", };
 
 static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
-					 "video_pll1_out", "sys_pll1_80m", "audio_pll1_out", "clk_ext1" };
+					 "video_pll_out", "sys_pll1_80m", "audio_pll1_out", "clk_ext1" };
 
 static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
 					 "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
@@ -234,31 +234,31 @@ static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_ou
 					  "sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", };
 
 static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
-					     "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					     "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m",
-					    "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+					    "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m",
-					    "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					    "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
 					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
 
 static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
-					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
-					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
 					     "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
 
 static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
-					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+					      "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
-					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+					     "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll_out", };
 
 static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
 					     "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
@@ -286,9 +286,9 @@ static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }
 static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "dummy", "sys_pll1_200m",
 					  "audio_pll2_out", "sys_pll2_500m", "vpu_pll", "sys_pll1_80m", };
 static const char *imx8mm_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", "sys_pll2_166m",
-					  "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "osc_32k", };
+					  "sys_pll3_out", "audio_pll1_out", "video_pll_out", "osc_32k", };
 
-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
 					   "dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
 					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
 					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
@@ -327,7 +327,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MM_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
@@ -336,7 +336,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MM_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
 	hws[IMX8MM_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
-	hws[IMX8MM_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
+	hws[IMX8MM_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll);
 	hws[IMX8MM_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
 	hws[IMX8MM_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
 	hws[IMX8MM_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
@@ -348,7 +348,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 	/* PLL bypass out */
 	hws[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MM_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MM_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
@@ -358,7 +358,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 	/* PLL out gate */
 	hws[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
 	hws[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
-	hws[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+	hws[IMX8MM_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13);
 	hws[IMX8MM_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
 	hws[IMX8MM_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
 	hws[IMX8MM_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:18 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:18 +0100
Subject: [PATCH v6 03/18] dt-bindings: clock: imx8mp: add VIDEO_PLL clocks
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-4-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's add the IMX8MP_VIDEO_PLL[_*]
definitions to be consistent with the RM and avoid misunderstandings.

The IMX8MP_VIDEO_PLL1* constants have not been removed to ensure
backward compatibility of the patch.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

---

Changes in v6:
- Add 'Acked-by' tag of Krzysztof Kozlowski

Changes in v5:
- New

 include/dt-bindings/clock/imx8mp-clock.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
index 7da4243984b2..3235d7de3b62 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -16,7 +16,8 @@
 #define IMX8MP_CLK_EXT4				7
 #define IMX8MP_AUDIO_PLL1_REF_SEL		8
 #define IMX8MP_AUDIO_PLL2_REF_SEL		9
-#define IMX8MP_VIDEO_PLL1_REF_SEL		10
+#define IMX8MP_VIDEO_PLL_REF_SEL		10
+#define IMX8MP_VIDEO_PLL1_REF_SEL		IMX8MP_VIDEO_PLL_REF_SEL
 #define IMX8MP_DRAM_PLL_REF_SEL			11
 #define IMX8MP_GPU_PLL_REF_SEL			12
 #define IMX8MP_VPU_PLL_REF_SEL			13
@@ -26,7 +27,8 @@
 #define IMX8MP_SYS_PLL3_REF_SEL			17
 #define IMX8MP_AUDIO_PLL1			18
 #define IMX8MP_AUDIO_PLL2			19
-#define IMX8MP_VIDEO_PLL1			20
+#define IMX8MP_VIDEO_PLL			20
+#define IMX8MP_VIDEO_PLL1			IMX8MP_VIDEO_PLL
 #define IMX8MP_DRAM_PLL				21
 #define IMX8MP_GPU_PLL				22
 #define IMX8MP_VPU_PLL				23
@@ -36,7 +38,8 @@
 #define IMX8MP_SYS_PLL3				27
 #define IMX8MP_AUDIO_PLL1_BYPASS		28
 #define IMX8MP_AUDIO_PLL2_BYPASS		29
-#define IMX8MP_VIDEO_PLL1_BYPASS		30
+#define IMX8MP_VIDEO_PLL_BYPASS			30
+#define IMX8MP_VIDEO_PLL1_BYPASS		IMX8MP_VIDEO_PLL_BYPASS
 #define IMX8MP_DRAM_PLL_BYPASS			31
 #define IMX8MP_GPU_PLL_BYPASS			32
 #define IMX8MP_VPU_PLL_BYPASS			33
@@ -46,7 +49,8 @@
 #define IMX8MP_SYS_PLL3_BYPASS			37
 #define IMX8MP_AUDIO_PLL1_OUT			38
 #define IMX8MP_AUDIO_PLL2_OUT			39
-#define IMX8MP_VIDEO_PLL1_OUT			40
+#define IMX8MP_VIDEO_PLL_OUT			40
+#define IMX8MP_VIDEO_PLL1_OUT			IMX8MP_VIDEO_PLL_OUT
 #define IMX8MP_DRAM_PLL_OUT			41
 #define IMX8MP_GPU_PLL_OUT			42
 #define IMX8MP_VPU_PLL_OUT			43
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:19 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:19 +0100
Subject: [PATCH v6 04/18] clk: imx8mp: rename video_pll1 to video_pll
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-5-dario.binacchi@amarulasolutions.com>

Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the
name used in the RM is video_pll. So, let's rename "video_pll1" to
"video_pll" to be consistent with the RM and avoid misunderstandings.

No functional changes intended.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---
The patch, which simply replaces video_pll1 with video_pll, highlights
many warnings raised by checkpatch.pl. These are not generated by the
changes made but are inherited from how the module was originally
written. Fixing them would have meant "obscuring" the actual changes
introduced.

(no changes since v5)

Changes in v5:
- Split the patch dropping the dt-bindings changes.

Changes in v4:
- New

 drivers/clk/imx/clk-imx8mp.c | 118 +++++++++++++++++------------------
 1 file changed, 59 insertions(+), 59 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 516dbd170c8a..e96460534e7d 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -23,7 +23,7 @@ static u32 share_count_audio;
 static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
 static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
 static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
-static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
 static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
 static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
 static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
@@ -40,27 +40,27 @@ static const char * const imx8mp_a53_core_sels[] = {"arm_a53_div", "arm_pll_out"
 
 static const char * const imx8mp_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m",
 					      "vpu_pll_out", "sys_pll1_800m", "audio_pll1_out",
-					      "video_pll1_out", "sys_pll3_out", };
+					      "video_pll_out", "sys_pll3_out", };
 
 static const char * const imx8mp_ml_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 					      "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-					      "video_pll1_out", "audio_pll2_out", };
+					      "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu3d_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						      "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						      "video_pll1_out", "audio_pll2_out", };
+						      "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu3d_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 							"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-							"video_pll1_out", "audio_pll2_out", };
+							"video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						 "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						 "video_pll1_out", "audio_pll2_out", };
+						 "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_audio_axi_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						     "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						     "video_pll1_out", "audio_pll2_out", };
+						     "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_hsio_axi_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
 						    "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
@@ -72,11 +72,11 @@ static const char * const imx8mp_media_isp_sels[] = {"osc_24m", "sys_pll2_1000m"
 
 static const char * const imx8mp_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m",
 						    "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
-						    "video_pll1_out", "sys_pll1_100m",};
+						    "video_pll_out", "sys_pll1_100m",};
 
 static const char * const imx8mp_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
 						    "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
-						    "video_pll1_out", "sys_pll3_out", };
+						    "video_pll_out", "sys_pll3_out", };
 
 static const char * const imx8mp_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
 						      "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
@@ -96,35 +96,35 @@ static const char * const imx8mp_media_apb_sels[] = {"osc_24m", "sys_pll2_125m",
 
 static const char * const imx8mp_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						   "video_pll1_out", "audio_pll2_out", };
+						   "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						   "video_pll1_out", "audio_pll2_out", };
+						   "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
 					       "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
-					       "video_pll1_out", "audio_pll2_out", };
+					       "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_noc_io_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
 						  "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
-						  "video_pll1_out", "audio_pll2_out", };
+						  "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_ml_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						  "video_pll1_out", "audio_pll2_out", };
+						  "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_ml_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
 						  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
-						  "video_pll1_out", "audio_pll2_out", };
+						  "video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m",
 					       "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
-					       "audio_pll1_out", "video_pll1_out", };
+					       "audio_pll1_out", "video_pll_out", };
 
 static const char * const imx8mp_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
 						     "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out",
-						     "audio_pll1_out", "video_pll1_out", };
+						     "audio_pll1_out", "video_pll_out", };
 
 static const char * const imx8mp_mipi_dsi_esc_rx_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
 							   "sys_pll1_800m", "sys_pll2_1000m",
@@ -159,56 +159,56 @@ static const char * const imx8mp_pcie_aux_sels[] = {"osc_24m", "sys_pll2_200m",
 						    "sys_pll1_160m", "sys_pll1_200m", };
 
 static const char * const imx8mp_i2c5_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c6_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext1", "clk_ext2", };
 
 static const char * const imx8mp_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext2", "clk_ext3", };
 
 static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
 
 static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext2", "clk_ext3", };
 
 static const char * const imx8mp_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
 
 static const char * const imx8mp_enet_qos_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
 						    "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
-						    "video_pll1_out", "clk_ext4", };
+						    "video_pll_out", "clk_ext4", };
 
 static const char * const imx8mp_enet_qos_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
 							  "clk_ext1", "clk_ext2", "clk_ext3",
-							  "clk_ext4", "video_pll1_out", };
+							  "clk_ext4", "video_pll_out", };
 
 static const char * const imx8mp_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
 						    "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
-						    "video_pll1_out", "clk_ext4", };
+						    "video_pll_out", "clk_ext4", };
 
 static const char * const imx8mp_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
 						      "clk_ext1", "clk_ext2", "clk_ext3",
-						      "clk_ext4", "video_pll1_out", };
+						      "clk_ext4", "video_pll_out", };
 
 static const char * const imx8mp_enet_phy_ref_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m",
 							"sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out",
-							"video_pll1_out", "audio_pll2_out", };
+							"video_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mp_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
 						"sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
-						"sys_pll2_250m", "video_pll1_out", };
+						"sys_pll2_250m", "video_pll_out", };
 
 static const char * const imx8mp_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m",
 						"sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
@@ -223,19 +223,19 @@ static const char * const imx8mp_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "s
 						  "audio_pll2_out", "sys_pll1_100m", };
 
 static const char * const imx8mp_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						"audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
@@ -276,42 +276,42 @@ static const char * const imx8mp_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "s
 
 static const char * const imx8mp_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
 						"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
-						"sys_pll1_80m", "video_pll1_out", };
+						"sys_pll1_80m", "video_pll_out", };
 
 static const char * const imx8mp_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext1" };
 
 static const char * const imx8mp_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext2" };
 
 static const char * const imx8mp_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext3" };
 
 static const char * const imx8mp_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext1" };
 
 static const char * const imx8mp_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext2" };
 
 static const char * const imx8mp_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
 						"audio_pll1_out", "clk_ext3" };
 
 static const char * const imx8mp_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
@@ -328,19 +328,19 @@ static const char * const imx8mp_ipp_do_clko1_sels[] = {"osc_24m", "sys_pll1_800
 
 static const char * const imx8mp_ipp_do_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m",
 							"sys_pll1_166m", "sys_pll3_out", "audio_pll1_out",
-							"video_pll1_out", "osc_32k" };
+							"video_pll_out", "osc_32k" };
 
 static const char * const imx8mp_hdmi_fdcc_tst_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
 							 "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
-							 "audio_pll2_out", "video_pll1_out", };
+							 "audio_pll2_out", "video_pll_out", };
 
 static const char * const imx8mp_hdmi_24m_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
-						    "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+						    "sys_pll3_out", "audio_pll1_out", "video_pll_out",
 						    "audio_pll2_out", "sys_pll1_133m", };
 
 static const char * const imx8mp_hdmi_ref_266m_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out",
 							 "sys_pll2_333m", "sys_pll1_266m", "sys_pll2_200m",
-							 "audio_pll1_out", "video_pll1_out", };
+							 "audio_pll1_out", "video_pll_out", };
 
 static const char * const imx8mp_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
 						  "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
@@ -349,26 +349,26 @@ static const char * const imx8mp_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "s
 static const char * const imx8mp_media_cam1_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
 							  "sys_pll1_800m", "sys_pll2_1000m",
 							  "sys_pll3_out", "audio_pll2_out",
-							  "video_pll1_out", };
+							  "video_pll_out", };
 
 static const char * const imx8mp_media_mipi_phy1_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
 							       "sys_pll1_800m", "sys_pll2_1000m",
 							       "clk_ext2", "audio_pll2_out",
-							       "video_pll1_out", };
+							       "video_pll_out", };
 
-static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
+static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out",
 							   "audio_pll1_out", "sys_pll1_800m",
 							   "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
 
 static const char * const imx8mp_media_cam2_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
 							  "sys_pll1_800m", "sys_pll2_1000m",
 							  "sys_pll3_out", "audio_pll2_out",
-							  "video_pll1_out", };
+							  "video_pll_out", };
 
 static const char * const imx8mp_media_ldb_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
 						     "sys_pll1_800m", "sys_pll2_1000m",
 						     "clk_ext2", "audio_pll2_out",
-						     "video_pll1_out", };
+						     "video_pll_out", };
 
 static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
 							"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
@@ -392,12 +392,12 @@ static const char * const imx8mp_vpu_vc8000e_sels[] = {"osc_24m", "vpu_pll_out",
 						       "sys_pll3_out", "audio_pll1_out", };
 
 static const char * const imx8mp_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+						"video_pll_out", "sys_pll1_133m", "osc_hdmi",
 						"clk_ext3", "clk_ext4", };
 
 static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
 
-static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
 						  "dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
 						  "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
 						  "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
@@ -440,7 +440,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", anatop_base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", anatop_base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MP_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MP_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", anatop_base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", anatop_base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
 	hws[IMX8MP_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", anatop_base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
@@ -451,7 +451,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", anatop_base, &imx_1443x_pll);
 	hws[IMX8MP_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", anatop_base + 0x14, &imx_1443x_pll);
-	hws[IMX8MP_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
+	hws[IMX8MP_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
 	hws[IMX8MP_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", anatop_base + 0x50, &imx_1443x_dram_pll);
 	hws[IMX8MP_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", anatop_base + 0x64, &imx_1416x_pll);
 	hws[IMX8MP_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", anatop_base + 0x74, &imx_1416x_pll);
@@ -462,7 +462,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MP_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", anatop_base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
@@ -473,7 +473,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
 
 	hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
 	hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
-	hws[IMX8MP_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", anatop_base + 0x28, 13);
+	hws[IMX8MP_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", anatop_base + 0x28, 13);
 	hws[IMX8MP_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", anatop_base + 0x50, 13);
 	hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
 	hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:20 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:20 +0100
Subject: [PATCH v6 05/18] dt-bindings: clock: imx8m-anatop: add oscillators and PLLs
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-6-dario.binacchi@amarulasolutions.com>

Though adding clocks and clock-names properties will break the ABI,
it is required to accurately describe the hardware. Indeed, the anatop
module uses the input oscillators to generate various PLLs. In turn,
the Clock Control Module (CCM) receives clocks from the PLLs and
oscillators and generates clocks for on-chip peripherals.

Furthermore, as agreed in [1], this change represents the first step
toward the implementation of the anatop driver. Currently, in fact,
there is no dedicated anatop driver, but the CCM driver parses the
anatop node and registers the PLLs it produces.

[1] https://lore.kernel.org/imx/20241106090549.3684963-1-dario.binacchi at amarulasolutions.com/
Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v6:
- Improve commit message
- Merge it with patch 10, 11, and 12:
  - 10/20 dt-bindings: clock: imx8mm: add binding definitions for anatop
  - 11/20 dt-bindings: clock: imx8mn: add binding definitions for anatop
  - 12/20 dt-bindings: clock: imx8mp: add binding definitions for anatop

Changes in v4:
- New

 .../bindings/clock/fsl,imx8m-anatop.yaml      | 53 ++++++++++++++-
 include/dt-bindings/clock/imx8mm-clock.h      | 64 +++++++++++++++++
 include/dt-bindings/clock/imx8mn-clock.h      | 64 +++++++++++++++++
 include/dt-bindings/clock/imx8mp-clock.h      | 68 +++++++++++++++++++
 4 files changed, 248 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml b/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
index bbd22e95b319..f439b0a94ce2 100644
--- a/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
+++ b/Documentation/devicetree/bindings/clock/fsl,imx8m-anatop.yaml
@@ -30,22 +30,73 @@ properties:
   interrupts:
     maxItems: 1
 
+  clocks:
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    minItems: 2
+    maxItems: 3
+
   '#clock-cells':
     const: 1
 
 required:
   - compatible
   - reg
+  - clocks
+  - clock-names
   - '#clock-cells'
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx8mq-anatop
+    then:
+      properties:
+        clocks:
+          items:
+            - description: 32k osc
+            - description: 25m osc
+            - description: 27m osc
+        clock-names:
+          items:
+            - const: ckil
+            - const: osc_25m
+            - const: osc_27m
+    else:
+      properties:
+        clocks:
+          items:
+            - description: 32k osc
+            - description: 24m osc
+
+        clock-names:
+          items:
+            - const: osc_32k
+            - const: osc_24m
+
 additionalProperties: false
 
 examples:
   - |
-    anatop: clock-controller at 30360000 {
+    clock-controller at 30360000 {
         compatible = "fsl,imx8mn-anatop", "fsl,imx8mm-anatop";
         reg = <0x30360000 0x10000>;
         #clock-cells = <1>;
+        clocks = <&osc_32k>, <&osc_24m>;
+        clock-names = "osc_32k", "osc_24m";
+    };
+
+  - |
+    clock-controller at 30360000 {
+        compatible = "fsl,imx8mq-anatop";
+        reg = <0x30360000 0x10000>;
+        #clock-cells = <1>;
+        clocks = <&ckil>, <&osc_25m>, <&osc_27m>;
+        clock-names = "ckil", "osc_25m", "osc_27m";
     };
 
 ...
diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
index 102d8a6cdb55..017c06e48430 100644
--- a/include/dt-bindings/clock/imx8mm-clock.h
+++ b/include/dt-bindings/clock/imx8mm-clock.h
@@ -287,4 +287,68 @@
 
 #define IMX8MM_CLK_END				258
 
+#define IMX8MM_ANATOP_CLK_DUMMY			0
+#define IMX8MM_ANATOP_CLK_32K			1
+#define IMX8MM_ANATOP_CLK_24M			2
+#define IMX8MM_ANATOP_AUDIO_PLL1_REF_SEL	3
+#define IMX8MM_ANATOP_AUDIO_PLL2_REF_SEL	4
+#define IMX8MM_ANATOP_VIDEO_PLL_REF_SEL		5
+#define IMX8MM_ANATOP_DRAM_PLL_REF_SEL		6
+#define IMX8MM_ANATOP_GPU_PLL_REF_SEL		7
+#define IMX8MM_ANATOP_VPU_PLL_REF_SEL		8
+#define IMX8MM_ANATOP_ARM_PLL_REF_SEL		9
+#define IMX8MM_ANATOP_SYS_PLL3_REF_SEL		10
+#define IMX8MM_ANATOP_AUDIO_PLL1		11
+#define IMX8MM_ANATOP_AUDIO_PLL2		12
+#define IMX8MM_ANATOP_VIDEO_PLL			13
+#define IMX8MM_ANATOP_DRAM_PLL			14
+#define IMX8MM_ANATOP_GPU_PLL			15
+#define IMX8MM_ANATOP_VPU_PLL			16
+#define IMX8MM_ANATOP_ARM_PLL			17
+#define IMX8MM_ANATOP_SYS_PLL1			18
+#define IMX8MM_ANATOP_SYS_PLL2			19
+#define IMX8MM_ANATOP_SYS_PLL3			20
+#define IMX8MM_ANATOP_AUDIO_PLL1_BYPASS		21
+#define IMX8MM_ANATOP_AUDIO_PLL2_BYPASS		22
+#define IMX8MM_ANATOP_VIDEO_PLL_BYPASS		23
+#define IMX8MM_ANATOP_DRAM_PLL_BYPASS		24
+#define IMX8MM_ANATOP_GPU_PLL_BYPASS		25
+#define IMX8MM_ANATOP_VPU_PLL_BYPASS		26
+#define IMX8MM_ANATOP_ARM_PLL_BYPASS		27
+#define IMX8MM_ANATOP_SYS_PLL3_BYPASS		28
+#define IMX8MM_ANATOP_AUDIO_PLL1_OUT		29
+#define IMX8MM_ANATOP_AUDIO_PLL2_OUT		30
+#define IMX8MM_ANATOP_VIDEO_PLL_OUT		31
+#define IMX8MM_ANATOP_DRAM_PLL_OUT		32
+#define IMX8MM_ANATOP_GPU_PLL_OUT		33
+#define IMX8MM_ANATOP_VPU_PLL_OUT		34
+#define IMX8MM_ANATOP_ARM_PLL_OUT		35
+#define IMX8MM_ANATOP_SYS_PLL3_OUT		36
+#define IMX8MM_ANATOP_SYS_PLL1_OUT		37
+#define IMX8MM_ANATOP_SYS_PLL1_40M		38
+#define IMX8MM_ANATOP_SYS_PLL1_80M		39
+#define IMX8MM_ANATOP_SYS_PLL1_100M		40
+#define IMX8MM_ANATOP_SYS_PLL1_133M		41
+#define IMX8MM_ANATOP_SYS_PLL1_160M		42
+#define IMX8MM_ANATOP_SYS_PLL1_200M		43
+#define IMX8MM_ANATOP_SYS_PLL1_266M		44
+#define IMX8MM_ANATOP_SYS_PLL1_400M		45
+#define IMX8MM_ANATOP_SYS_PLL1_800M		46
+#define IMX8MM_ANATOP_SYS_PLL2_OUT		47
+#define IMX8MM_ANATOP_SYS_PLL2_50M		48
+#define IMX8MM_ANATOP_SYS_PLL2_100M		49
+#define IMX8MM_ANATOP_SYS_PLL2_125M		50
+#define IMX8MM_ANATOP_SYS_PLL2_166M		51
+#define IMX8MM_ANATOP_SYS_PLL2_200M		52
+#define IMX8MM_ANATOP_SYS_PLL2_250M		53
+#define IMX8MM_ANATOP_SYS_PLL2_333M		54
+#define IMX8MM_ANATOP_SYS_PLL2_500M		55
+#define IMX8MM_ANATOP_SYS_PLL2_1000M		56
+#define IMX8MM_ANATOP_CLK_CLKOUT1_SEL		57
+#define IMX8MM_ANATOP_CLK_CLKOUT1_DIV		58
+#define IMX8MM_ANATOP_CLK_CLKOUT1		59
+#define IMX8MM_ANATOP_CLK_CLKOUT2_SEL		60
+#define IMX8MM_ANATOP_CLK_CLKOUT2_DIV		61
+#define IMX8MM_ANATOP_CLK_CLKOUT2		62
+
 #endif
diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
index 04809edab33c..b2fa73803d45 100644
--- a/include/dt-bindings/clock/imx8mn-clock.h
+++ b/include/dt-bindings/clock/imx8mn-clock.h
@@ -267,4 +267,68 @@
 
 #define IMX8MN_CLK_END				235
 
+#define IMX8MN_ANATOP_CLK_DUMMY			0
+#define IMX8MN_ANATOP_CLK_32K			1
+#define IMX8MN_ANATOP_CLK_24M			2
+#define IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL	3
+#define IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL	4
+#define IMX8MN_ANATOP_VIDEO_PLL_REF_SEL		5
+#define IMX8MN_ANATOP_DRAM_PLL_REF_SEL		6
+#define IMX8MN_ANATOP_GPU_PLL_REF_SEL		7
+#define IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL	8
+#define IMX8MN_ANATOP_ARM_PLL_REF_SEL		9
+#define IMX8MN_ANATOP_SYS_PLL3_REF_SEL		10
+#define IMX8MN_ANATOP_AUDIO_PLL1		11
+#define IMX8MN_ANATOP_AUDIO_PLL2		12
+#define IMX8MN_ANATOP_VIDEO_PLL			13
+#define IMX8MN_ANATOP_DRAM_PLL			14
+#define IMX8MN_ANATOP_GPU_PLL			15
+#define IMX8MN_ANATOP_M7_ALT_PLL		16
+#define IMX8MN_ANATOP_ARM_PLL			17
+#define IMX8MN_ANATOP_SYS_PLL1			18
+#define IMX8MN_ANATOP_SYS_PLL2			19
+#define IMX8MN_ANATOP_SYS_PLL3			20
+#define IMX8MN_ANATOP_AUDIO_PLL1_BYPASS		21
+#define IMX8MN_ANATOP_AUDIO_PLL2_BYPASS		22
+#define IMX8MN_ANATOP_VIDEO_PLL_BYPASS		23
+#define IMX8MN_ANATOP_DRAM_PLL_BYPASS		24
+#define IMX8MN_ANATOP_GPU_PLL_BYPASS		25
+#define IMX8MN_ANATOP_M7_ALT_PLL_BYPASS		26
+#define IMX8MN_ANATOP_ARM_PLL_BYPASS		27
+#define IMX8MN_ANATOP_SYS_PLL3_BYPASS		28
+#define IMX8MN_ANATOP_AUDIO_PLL1_OUT		29
+#define IMX8MN_ANATOP_AUDIO_PLL2_OUT		30
+#define IMX8MN_ANATOP_VIDEO_PLL_OUT		31
+#define IMX8MN_ANATOP_DRAM_PLL_OUT		32
+#define IMX8MN_ANATOP_GPU_PLL_OUT		33
+#define IMX8MN_ANATOP_M7_ALT_PLL_OUT		34
+#define IMX8MN_ANATOP_ARM_PLL_OUT		35
+#define IMX8MN_ANATOP_SYS_PLL3_OUT		36
+#define IMX8MN_ANATOP_SYS_PLL1_OUT		37
+#define IMX8MN_ANATOP_SYS_PLL1_40M		38
+#define IMX8MN_ANATOP_SYS_PLL1_80M		39
+#define IMX8MN_ANATOP_SYS_PLL1_100M		40
+#define IMX8MN_ANATOP_SYS_PLL1_133M		41
+#define IMX8MN_ANATOP_SYS_PLL1_160M		42
+#define IMX8MN_ANATOP_SYS_PLL1_200M		43
+#define IMX8MN_ANATOP_SYS_PLL1_266M		44
+#define IMX8MN_ANATOP_SYS_PLL1_400M		45
+#define IMX8MN_ANATOP_SYS_PLL1_800M		46
+#define IMX8MN_ANATOP_SYS_PLL2_OUT		47
+#define IMX8MN_ANATOP_SYS_PLL2_50M		48
+#define IMX8MN_ANATOP_SYS_PLL2_100M		49
+#define IMX8MN_ANATOP_SYS_PLL2_125M		50
+#define IMX8MN_ANATOP_SYS_PLL2_166M		51
+#define IMX8MN_ANATOP_SYS_PLL2_200M		52
+#define IMX8MN_ANATOP_SYS_PLL2_250M		53
+#define IMX8MN_ANATOP_SYS_PLL2_333M		54
+#define IMX8MN_ANATOP_SYS_PLL2_500M		55
+#define IMX8MN_ANATOP_SYS_PLL2_1000M		56
+#define IMX8MN_ANATOP_CLK_CLKOUT1_SEL		57
+#define IMX8MN_ANATOP_CLK_CLKOUT1_DIV		58
+#define IMX8MN_ANATOP_CLK_CLKOUT1		59
+#define IMX8MN_ANATOP_CLK_CLKOUT2_SEL		60
+#define IMX8MN_ANATOP_CLK_CLKOUT2_DIV		61
+#define IMX8MN_ANATOP_CLK_CLKOUT2		62
+
 #endif
diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
index 3235d7de3b62..8c076225fd9e 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -402,4 +402,72 @@
 
 #define IMX8MP_CLK_AUDIOMIX_END			59
 
+#define IMX8MP_ANATOP_CLK_DUMMY			0
+#define IMX8MP_ANATOP_CLK_24M			1
+#define IMX8MP_ANATOP_CLK_32K			2
+#define IMX8MP_ANATOP_AUDIO_PLL1_REF_SEL	3
+#define IMX8MP_ANATOP_AUDIO_PLL2_REF_SEL	4
+#define IMX8MP_ANATOP_VIDEO_PLL_REF_SEL		5
+#define IMX8MP_ANATOP_DRAM_PLL_REF_SEL		6
+#define IMX8MP_ANATOP_GPU_PLL_REF_SEL		7
+#define IMX8MP_ANATOP_VPU_PLL_REF_SEL		8
+#define IMX8MP_ANATOP_ARM_PLL_REF_SEL		9
+#define IMX8MP_ANATOP_SYS_PLL1_REF_SEL		10
+#define IMX8MP_ANATOP_SYS_PLL2_REF_SEL		11
+#define IMX8MP_ANATOP_SYS_PLL3_REF_SEL		12
+#define IMX8MP_ANATOP_AUDIO_PLL1		13
+#define IMX8MP_ANATOP_AUDIO_PLL2		14
+#define IMX8MP_ANATOP_VIDEO_PLL			15
+#define IMX8MP_ANATOP_DRAM_PLL			16
+#define IMX8MP_ANATOP_GPU_PLL			17
+#define IMX8MP_ANATOP_VPU_PLL			18
+#define IMX8MP_ANATOP_ARM_PLL			19
+#define IMX8MP_ANATOP_SYS_PLL1			20
+#define IMX8MP_ANATOP_SYS_PLL2			21
+#define IMX8MP_ANATOP_SYS_PLL3			22
+#define IMX8MP_ANATOP_AUDIO_PLL1_BYPASS		23
+#define IMX8MP_ANATOP_AUDIO_PLL2_BYPASS		24
+#define IMX8MP_ANATOP_VIDEO_PLL_BYPASS		25
+#define IMX8MP_ANATOP_DRAM_PLL_BYPASS		26
+#define IMX8MP_ANATOP_GPU_PLL_BYPASS		27
+#define IMX8MP_ANATOP_VPU_PLL_BYPASS		28
+#define IMX8MP_ANATOP_ARM_PLL_BYPASS		29
+#define IMX8MP_ANATOP_SYS_PLL1_BYPASS		30
+#define IMX8MP_ANATOP_SYS_PLL2_BYPASS		31
+#define IMX8MP_ANATOP_SYS_PLL3_BYPASS		32
+#define IMX8MP_ANATOP_AUDIO_PLL1_OUT		33
+#define IMX8MP_ANATOP_AUDIO_PLL2_OUT		34
+#define IMX8MP_ANATOP_VIDEO_PLL_OUT		35
+#define IMX8MP_ANATOP_DRAM_PLL_OUT		36
+#define IMX8MP_ANATOP_GPU_PLL_OUT		37
+#define IMX8MP_ANATOP_VPU_PLL_OUT		38
+#define IMX8MP_ANATOP_ARM_PLL_OUT		39
+#define IMX8MP_ANATOP_SYS_PLL3_OUT		40
+#define IMX8MP_ANATOP_SYS_PLL1_OUT		41
+#define IMX8MP_ANATOP_SYS_PLL1_40M		42
+#define IMX8MP_ANATOP_SYS_PLL1_80M		43
+#define IMX8MP_ANATOP_SYS_PLL1_100M		44
+#define IMX8MP_ANATOP_SYS_PLL1_133M		45
+#define IMX8MP_ANATOP_SYS_PLL1_160M		46
+#define IMX8MP_ANATOP_SYS_PLL1_200M		47
+#define IMX8MP_ANATOP_SYS_PLL1_266M		48
+#define IMX8MP_ANATOP_SYS_PLL1_400M		49
+#define IMX8MP_ANATOP_SYS_PLL1_800M		50
+#define IMX8MP_ANATOP_SYS_PLL2_OUT		51
+#define IMX8MP_ANATOP_SYS_PLL2_50M		52
+#define IMX8MP_ANATOP_SYS_PLL2_100M		53
+#define IMX8MP_ANATOP_SYS_PLL2_125M		54
+#define IMX8MP_ANATOP_SYS_PLL2_166M		55
+#define IMX8MP_ANATOP_SYS_PLL2_200M		56
+#define IMX8MP_ANATOP_SYS_PLL2_250M		57
+#define IMX8MP_ANATOP_SYS_PLL2_333M		58
+#define IMX8MP_ANATOP_SYS_PLL2_500M		59
+#define IMX8MP_ANATOP_SYS_PLL2_1000M		60
+#define IMX8MP_ANATOP_CLK_CLKOUT1_SEL		61
+#define IMX8MP_ANATOP_CLK_CLKOUT1_DIV		62
+#define IMX8MP_ANATOP_CLK_CLKOUT1		63
+#define IMX8MP_ANATOP_CLK_CLKOUT2_SEL		64
+#define IMX8MP_ANATOP_CLK_CLKOUT2_DIV		65
+#define IMX8MP_ANATOP_CLK_CLKOUT2		66
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:21 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:21 +0100
Subject: [PATCH v6 06/18] arm64: dts: imx8mm: add anatop clocks
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-7-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Add the bindings definitions for the anatop node. The patch is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 4de3bf22902b..597041a05073 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -600,6 +600,8 @@ anatop: clock-controller at 30360000 {
 				compatible = "fsl,imx8mm-anatop";
 				reg = <0x30360000 0x10000>;
 				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>;
+				clock-names = "osc_32k", "osc_24m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:22 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:22 +0100
Subject: [PATCH v6 07/18] arm64: dts: imx8mn: add anatop clocks
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-8-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index a5f9cfb46e5d..49be492b5687 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -606,6 +606,8 @@ anatop: clock-controller at 30360000 {
 				compatible = "fsl,imx8mn-anatop", "fsl,imx8mm-anatop";
 				reg = <0x30360000 0x10000>;
 				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>;
+				clock-names = "osc_32k", "osc_24m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:23 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:23 +0100
Subject: [PATCH v6 08/18] arm64: dts: imx8mp: add anatop clocks
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-9-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index e0d3b8cba221..0b928e173f29 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -709,6 +709,8 @@ anatop: clock-controller at 30360000 {
 				compatible = "fsl,imx8mp-anatop", "fsl,imx8mm-anatop";
 				reg = <0x30360000 0x10000>;
 				#clock-cells = <1>;
+				clocks = <&osc_32k>, <&osc_24m>;
+				clock-names = "osc_32k", "osc_24m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:24 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:24 +0100
Subject: [PATCH v6 09/18] arm64: dts: imx8mq: add anatop clocks
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-10-dario.binacchi@amarulasolutions.com>

Add clocks to anatop node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index d51de8d899b2..1d1424a136f0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -817,6 +817,8 @@ anatop: clock-controller at 30360000 {
 				reg = <0x30360000 0x10000>;
 				interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
+				clocks = <&ckil>, <&osc_25m>, <&osc_27m>;
+				clock-names = "ckil", "osc_25m", "osc_27m";
 			};
 
 			snvs: snvs at 30370000 {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:25 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:25 +0100
Subject: [PATCH v6 10/18] clk: imx: add hw API imx8m_anatop_get_clk_hw
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-11-dario.binacchi@amarulasolutions.com>

Get the hw of a clock registered by the anatop module. This function is
preparatory for future developments.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v5)

Changes in v5:
- Consider CONFIG_CLK_IMX8M{M,N,P,Q}_MODULE to fix compilation errors

Changes in v4:
- New

 drivers/clk/imx/clk.c | 28 ++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h |  7 +++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
index df83bd939492..9a21f233e105 100644
--- a/drivers/clk/imx/clk.c
+++ b/drivers/clk/imx/clk.c
@@ -128,6 +128,34 @@ struct clk_hw *imx_get_clk_hw_by_name(struct device_node *np, const char *name)
 }
 EXPORT_SYMBOL_GPL(imx_get_clk_hw_by_name);
 
+#if defined(CONFIG_CLK_IMX8MM) || defined(CONFIG_CLK_IMX8MM_MODULE) || \
+	defined(CONFIG_CLK_IMX8MN) || defined(CONFIG_CLK_IMX8MN_MODULE) || \
+	defined(CONFIG_CLK_IMX8MP) || defined(CONFIG_CLK_IMX8MP_MODULE) || \
+	defined(CONFIG_CLK_IMX8MQ) || defined(CONFIG_CLK_IMX8MQ_MODULE)
+struct clk_hw *imx8m_anatop_get_clk_hw(int id)
+{
+#if defined(CONFIG_CLK_IMX8MQ) || defined(CONFIG_CLK_IMX8MQ_MODULE)
+	const char *compatible = "fsl,imx8mq-anatop";
+#else
+	const char *compatible = "fsl,imx8mm-anatop";
+#endif
+	struct device_node *np;
+	struct of_phandle_args args;
+	struct clk_hw *hw;
+
+	np = of_find_compatible_node(NULL, NULL, compatible);
+	args.np = np;
+	args.args_count = 1;
+	args.args[0] = id;
+	of_node_put(np);
+
+	hw = __clk_get_hw(of_clk_get_from_provider(&args));
+	pr_debug("%s: got clk: %s\n", __func__, clk_hw_get_name(hw));
+	return hw;
+}
+EXPORT_SYMBOL_GPL(imx8m_anatop_get_clk_hw);
+#endif
+
 /*
  * This fixups the register CCM_CSCMR1 write value.
  * The write/read/divider values of the aclk_podf field
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index aa5202f284f3..52055fda3058 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -487,4 +487,11 @@ struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible,
 			       u32 reg, const char **parent_names,
 			       u8 num_parents, const u32 *mux_table, u32 mask);
 
+#if defined(CONFIG_CLK_IMX8MM) || defined(CONFIG_CLK_IMX8MM_MODULE) || \
+	defined(CONFIG_CLK_IMX8MN) || defined(CONFIG_CLK_IMX8MN_MODULE) || \
+	defined(CONFIG_CLK_IMX8MP) || defined(CONFIG_CLK_IMX8MP_MODULE) || \
+	defined(CONFIG_CLK_IMX8MQ) || defined(CONFIG_CLK_IMX8MQ_MODULE)
+struct clk_hw *imx8m_anatop_get_clk_hw(int id);
+#endif
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:26 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:26 +0100
Subject: [PATCH v6 11/18] clk: imx: add support for i.MX8MN anatop clock driver
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-12-dario.binacchi@amarulasolutions.com>

Support NXP i.MX8M anatop PLL module which generates PLLs to CCM root.
By doing so, we also simplify the CCM driver code. The changes are
backward compatible.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v6:
- Define IMX8MN_ANATOP_CLK_END inside the driver after it has ben
  removed from include/dt-bindings/clock/imx8mn-clock.h.

Changes in v4:
- New

 drivers/clk/imx/Makefile            |   2 +-
 drivers/clk/imx/clk-imx8mn-anatop.c | 283 ++++++++++++++++++++++++++++
 drivers/clk/imx/clk-imx8mn.c        | 175 +++++++----------
 3 files changed, 357 insertions(+), 103 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx8mn-anatop.c

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 03f2b2a1ab63..f0f1d01c68f8 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -26,7 +26,7 @@ mxc-clk-objs += clk-gpr-mux.o
 obj-$(CONFIG_MXC_CLK) += mxc-clk.o
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
-obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
+obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn-anatop.o clk-imx8mn.o
 obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-imx8mp-audiomix.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 
diff --git a/drivers/clk/imx/clk-imx8mn-anatop.c b/drivers/clk/imx/clk-imx8mn-anatop.c
new file mode 100644
index 000000000000..43101b0a758e
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mn-anatop.c
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * clk-imx8mn-anatop.c - NXP i.MX8MN anatop clock driver
+ *
+ * Copyright (c) 2022 Dario Binacchi <dario.binacchi at amarulasolutions.com>
+ */
+
+#include <dt-bindings/clock/imx8mn-clock.h>
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+
+#include "clk.h"
+
+#define IMX8MN_ANATOP_CLK_END		IMX8MN_ANATOP_CLK_CLKOUT2
+
+static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
+static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", };
+static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
+					   "dummy", "dummy", "gpu_pll_out", "dummy",
+					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
+					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
+
+static struct clk_hw_onecell_data *clk_hw_data;
+static struct clk_hw **hws;
+
+static int imx8mn_anatop_clocks_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	void __iomem *base;
+	int ret;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base)) {
+		dev_err(dev, "failed to get base address\n");
+		return PTR_ERR(base);
+	}
+
+	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
+						    IMX8MN_ANATOP_CLK_END),
+				   GFP_KERNEL);
+	if (WARN_ON(!clk_hw_data))
+		return -ENOMEM;
+
+	clk_hw_data->num = IMX8MN_ANATOP_CLK_END;
+	hws = clk_hw_data->hws;
+
+	hws[IMX8MN_ANATOP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
+	hws[IMX8MN_ANATOP_CLK_32K] = imx_get_clk_hw_by_name(np, "osc_32k");
+	hws[IMX8MN_ANATOP_CLK_24M] = imx_get_clk_hw_by_name(np, "osc_24m");
+
+	hws[IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL] =
+		imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL] =
+		imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_VIDEO_PLL_REF_SEL] =
+		imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_DRAM_PLL_REF_SEL] =
+		imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_GPU_PLL_REF_SEL] =
+		imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL] =
+		imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_ARM_PLL_REF_SEL] =
+		imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMX8MN_ANATOP_SYS_PLL3_REF_SEL] =
+		imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2,
+			       pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+	hws[IMX8MN_ANATOP_AUDIO_PLL1] =
+		imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel",
+				   base, &imx_1443x_pll);
+	hws[IMX8MN_ANATOP_AUDIO_PLL2] =
+		imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel",
+				   base + 0x14, &imx_1443x_pll);
+	hws[IMX8MN_ANATOP_VIDEO_PLL] =
+		imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel",
+				   base + 0x28, &imx_1443x_pll);
+	hws[IMX8MN_ANATOP_DRAM_PLL] =
+		imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50,
+				   &imx_1443x_dram_pll);
+	hws[IMX8MN_ANATOP_GPU_PLL] =
+		imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64,
+				   &imx_1416x_pll);
+	hws[IMX8MN_ANATOP_M7_ALT_PLL] =
+		imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel",
+				   base + 0x74, &imx_1416x_pll);
+	hws[IMX8MN_ANATOP_ARM_PLL] =
+		imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84,
+				   &imx_1416x_pll);
+	hws[IMX8MN_ANATOP_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
+	hws[IMX8MN_ANATOP_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
+	hws[IMX8MN_ANATOP_SYS_PLL3] =
+		imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114,
+				   &imx_1416x_pll);
+
+	/* PLL bypass out */
+	hws[IMX8MN_ANATOP_AUDIO_PLL1_BYPASS] =
+		imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1,
+				     audio_pll1_bypass_sels,
+				     ARRAY_SIZE(audio_pll1_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_AUDIO_PLL2_BYPASS] =
+		imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1,
+				     audio_pll2_bypass_sels,
+				     ARRAY_SIZE(audio_pll2_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_VIDEO_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1,
+				     video_pll_bypass_sels,
+				     ARRAY_SIZE(video_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_DRAM_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1,
+				     dram_pll_bypass_sels,
+				     ARRAY_SIZE(dram_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_GPU_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1,
+				     gpu_pll_bypass_sels,
+				     ARRAY_SIZE(gpu_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_M7_ALT_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1,
+				     m7_alt_pll_bypass_sels,
+				     ARRAY_SIZE(m7_alt_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_ARM_PLL_BYPASS] =
+		imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1,
+				     arm_pll_bypass_sels,
+				     ARRAY_SIZE(arm_pll_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+	hws[IMX8MN_ANATOP_SYS_PLL3_BYPASS] =
+		imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1,
+				     sys_pll3_bypass_sels,
+				     ARRAY_SIZE(sys_pll3_bypass_sels),
+				     CLK_SET_RATE_PARENT);
+
+	/* PLL out gate */
+	hws[IMX8MN_ANATOP_AUDIO_PLL1_OUT] =
+		imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass",
+				base, 13);
+	hws[IMX8MN_ANATOP_AUDIO_PLL2_OUT] =
+		imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass",
+				base + 0x14, 13);
+	hws[IMX8MN_ANATOP_VIDEO_PLL_OUT] =
+		imx_clk_hw_gate("video_pll_out", "video_pll_bypass",
+				base + 0x28, 13);
+	hws[IMX8MN_ANATOP_DRAM_PLL_OUT] =
+		imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass",
+				base + 0x50, 13);
+	hws[IMX8MN_ANATOP_GPU_PLL_OUT] =
+		imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass",
+				base + 0x64, 11);
+	hws[IMX8MN_ANATOP_M7_ALT_PLL_OUT] =
+		imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass",
+				base + 0x74, 11);
+	hws[IMX8MN_ANATOP_ARM_PLL_OUT] =
+		imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass",
+				base + 0x84, 11);
+	hws[IMX8MN_ANATOP_SYS_PLL3_OUT] =
+		imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass",
+				base + 0x114, 11);
+
+	/* SYS PLL1 fixed output */
+	hws[IMX8MN_ANATOP_SYS_PLL1_OUT] =
+		imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
+	hws[IMX8MN_ANATOP_SYS_PLL1_40M] =
+		imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
+	hws[IMX8MN_ANATOP_SYS_PLL1_80M] =
+		imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
+	hws[IMX8MN_ANATOP_SYS_PLL1_100M] =
+		imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
+	hws[IMX8MN_ANATOP_SYS_PLL1_133M] =
+		imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
+	hws[IMX8MN_ANATOP_SYS_PLL1_160M] =
+		imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
+	hws[IMX8MN_ANATOP_SYS_PLL1_200M] =
+		imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
+	hws[IMX8MN_ANATOP_SYS_PLL1_266M] =
+		imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
+	hws[IMX8MN_ANATOP_SYS_PLL1_400M] =
+		imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+	hws[IMX8MN_ANATOP_SYS_PLL1_800M] =
+		imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+
+	/* SYS PLL2 fixed output */
+	hws[IMX8MN_ANATOP_SYS_PLL2_OUT] =
+		imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
+	hws[IMX8MN_ANATOP_SYS_PLL2_50M] =
+		imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
+	hws[IMX8MN_ANATOP_SYS_PLL2_100M] =
+		imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
+	hws[IMX8MN_ANATOP_SYS_PLL2_125M] =
+		imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
+	hws[IMX8MN_ANATOP_SYS_PLL2_166M] =
+		imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
+	hws[IMX8MN_ANATOP_SYS_PLL2_200M] =
+		imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
+	hws[IMX8MN_ANATOP_SYS_PLL2_250M] =
+		imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
+	hws[IMX8MN_ANATOP_SYS_PLL2_333M] =
+		imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
+	hws[IMX8MN_ANATOP_SYS_PLL2_500M] =
+		imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+	hws[IMX8MN_ANATOP_SYS_PLL2_1000M] =
+		imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+
+	hws[IMX8MN_ANATOP_CLK_CLKOUT1_SEL] =
+		imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4,
+				clkout_sels, ARRAY_SIZE(clkout_sels));
+	hws[IMX8MN_ANATOP_CLK_CLKOUT1_DIV] =
+		imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128,
+				   0, 4);
+	hws[IMX8MN_ANATOP_CLK_CLKOUT1] =
+		imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8);
+	hws[IMX8MN_ANATOP_CLK_CLKOUT2_SEL] =
+		imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4,
+				clkout_sels, ARRAY_SIZE(clkout_sels));
+	hws[IMX8MN_ANATOP_CLK_CLKOUT2_DIV] =
+		imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128,
+				   16, 4);
+	hws[IMX8MN_ANATOP_CLK_CLKOUT2] =
+		imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24);
+
+	imx_check_clk_hws(hws, IMX8MN_ANATOP_CLK_END);
+
+	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+	if (ret < 0) {
+		imx_unregister_hw_clocks(hws, IMX8MN_ANATOP_CLK_END);
+		return dev_err_probe(dev, ret,
+				     "failed to register anatop clock provider\n");
+	}
+
+	dev_info(dev, "NXP i.MX8MN anatop clock driver probed\n");
+	return 0;
+}
+
+static const struct of_device_id imx8mn_anatop_clk_of_match[] = {
+	{ .compatible = "fsl,imx8mn-anatop" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx8mn_anatop_clk_of_match);
+
+static struct platform_driver imx8mn_anatop_clk_driver = {
+	.probe = imx8mn_anatop_clocks_probe,
+	.driver = {
+		.name = "imx8mn-anatop",
+		/*
+		 * Disable bind attributes: clocks are not removed and
+		 * reloading the driver will crash or break devices.
+		 */
+		.suppress_bind_attrs = true,
+		.of_match_table = imx8mn_anatop_clk_of_match,
+	},
+};
+
+module_platform_driver(imx8mn_anatop_clk_driver);
+
+MODULE_AUTHOR("Dario Binacchi <dario.binacchi at amarulasolutions.com>");
+MODULE_DESCRIPTION("NXP i.MX8MN anatop clock driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index ab77e148e70c..588cebce6c9d 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -24,16 +24,6 @@ static u32 share_count_disp;
 static u32 share_count_pdm;
 static u32 share_count_nand;
 
-static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
-static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
-static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
-static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
-static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
-static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
-static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", };
-static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
-static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
-
 static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m",
 					       "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
 					       "audio_pll1_out", "sys_pll3_out", };
@@ -308,11 +298,6 @@ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sy
 						 "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out",
 						 "video_pll_out", "osc_32k", };
 
-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
-					   "dummy", "dummy", "gpu_pll_out", "dummy",
-					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
-					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
-
 static struct clk_hw_onecell_data *clk_hw_data;
 static struct clk_hw **hws;
 
@@ -323,6 +308,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	void __iomem *base;
 	int ret;
 
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (WARN_ON(IS_ERR(base)))
+		return PTR_ERR(base);
+
 	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
 					  IMX8MN_CLK_END), GFP_KERNEL);
 	if (WARN_ON(!clk_hw_data))
@@ -331,99 +320,84 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	clk_hw_data->num = IMX8MN_CLK_END;
 	hws = clk_hw_data->hws;
 
-	hws[IMX8MN_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
-	hws[IMX8MN_CLK_24M] = imx_get_clk_hw_by_name(np, "osc_24m");
-	hws[IMX8MN_CLK_32K] = imx_get_clk_hw_by_name(np, "osc_32k");
+	hws[IMX8MN_CLK_DUMMY] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_DUMMY);
+	hws[IMX8MN_CLK_24M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_24M);
+	hws[IMX8MN_CLK_32K] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_32K);
 	hws[IMX8MN_CLK_EXT1] = imx_get_clk_hw_by_name(np, "clk_ext1");
 	hws[IMX8MN_CLK_EXT2] = imx_get_clk_hw_by_name(np, "clk_ext2");
 	hws[IMX8MN_CLK_EXT3] = imx_get_clk_hw_by_name(np, "clk_ext3");
 	hws[IMX8MN_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
-	base = devm_of_iomap(dev, np, 0, NULL);
-	of_node_put(np);
-	if (WARN_ON(IS_ERR(base))) {
-		ret = PTR_ERR(base);
-		goto unregister_hws;
-	}
-
-	hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-
-	hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
-	hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
-	hws[IMX8MN_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll);
-	hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
-	hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
-	hws[IMX8MN_M7_ALT_PLL] = imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel", base + 0x74, &imx_1416x_pll);
-	hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
-	hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
-	hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
-	hws[IMX8MN_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
+	hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL);
+	hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL);
+	hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_REF_SEL);
+	hws[IMX8MN_DRAM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_REF_SEL);
+	hws[IMX8MN_GPU_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_REF_SEL);
+	hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL);
+	hws[IMX8MN_ARM_PLL_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_REF_SEL);
+	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_REF_SEL);
+
+	hws[IMX8MN_AUDIO_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1);
+	hws[IMX8MN_AUDIO_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2);
+	hws[IMX8MN_VIDEO_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL);
+	hws[IMX8MN_DRAM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL);
+	hws[IMX8MN_GPU_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL);
+	hws[IMX8MN_M7_ALT_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL);
+	hws[IMX8MN_ARM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL);
+	hws[IMX8MN_SYS_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1);
+	hws[IMX8MN_SYS_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2);
+	hws[IMX8MN_SYS_PLL3] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3);
 
 	/* PLL bypass out */
-	hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1, m7_alt_pll_bypass_sels, ARRAY_SIZE(m7_alt_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_BYPASS);
+	hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_BYPASS);
+	hws[IMX8MN_VIDEO_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_BYPASS);
+	hws[IMX8MN_DRAM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_BYPASS);
+	hws[IMX8MN_GPU_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_BYPASS);
+	hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_BYPASS);
+	hws[IMX8MN_ARM_PLL_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_BYPASS);
+	hws[IMX8MN_SYS_PLL3_BYPASS] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_BYPASS);
 
 	/* PLL out gate */
-	hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
-	hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
-	hws[IMX8MN_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13);
-	hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
-	hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
-	hws[IMX8MN_M7_ALT_PLL_OUT] = imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass", base + 0x74, 11);
-	hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
-	hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
+	hws[IMX8MN_AUDIO_PLL1_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1_OUT);
+	hws[IMX8MN_AUDIO_PLL2_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2_OUT);
+	hws[IMX8MN_VIDEO_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL_OUT);
+	hws[IMX8MN_DRAM_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL_OUT);
+	hws[IMX8MN_GPU_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL_OUT);
+	hws[IMX8MN_M7_ALT_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL_OUT);
+	hws[IMX8MN_ARM_PLL_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL_OUT);
+	hws[IMX8MN_SYS_PLL3_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_OUT);
 
 	/* SYS PLL1 fixed output */
-	hws[IMX8MN_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
-	hws[IMX8MN_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
-	hws[IMX8MN_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
-	hws[IMX8MN_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
-	hws[IMX8MN_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
-	hws[IMX8MN_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
-	hws[IMX8MN_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
-	hws[IMX8MN_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
-	hws[IMX8MN_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
-	hws[IMX8MN_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+	hws[IMX8MN_SYS_PLL1_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_OUT);
+	hws[IMX8MN_SYS_PLL1_40M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_40M);
+	hws[IMX8MN_SYS_PLL1_80M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_80M);
+	hws[IMX8MN_SYS_PLL1_100M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_100M);
+	hws[IMX8MN_SYS_PLL1_133M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_133M);
+	hws[IMX8MN_SYS_PLL1_160M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_160M);
+	hws[IMX8MN_SYS_PLL1_200M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_200M);
+	hws[IMX8MN_SYS_PLL1_266M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_266M);
+	hws[IMX8MN_SYS_PLL1_400M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_400M);
+	hws[IMX8MN_SYS_PLL1_800M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL1_800M);
 
 	/* SYS PLL2 fixed output */
-	hws[IMX8MN_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
-	hws[IMX8MN_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
-	hws[IMX8MN_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
-	hws[IMX8MN_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
-	hws[IMX8MN_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
-	hws[IMX8MN_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
-	hws[IMX8MN_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
-	hws[IMX8MN_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
-	hws[IMX8MN_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
-	hws[IMX8MN_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
-
-	hws[IMX8MN_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
-	hws[IMX8MN_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128, 0, 4);
-	hws[IMX8MN_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8);
-	hws[IMX8MN_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
-	hws[IMX8MN_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128, 16, 4);
-	hws[IMX8MN_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24);
-
-	np = dev->of_node;
-	base = devm_platform_ioremap_resource(pdev, 0);
-	if (WARN_ON(IS_ERR(base))) {
-		ret = PTR_ERR(base);
-		goto unregister_hws;
-	}
+	hws[IMX8MN_SYS_PLL2_OUT] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_OUT);
+	hws[IMX8MN_SYS_PLL2_50M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_50M);
+	hws[IMX8MN_SYS_PLL2_100M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_100M);
+	hws[IMX8MN_SYS_PLL2_125M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_125M);
+	hws[IMX8MN_SYS_PLL2_166M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_166M);
+	hws[IMX8MN_SYS_PLL2_200M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_200M);
+	hws[IMX8MN_SYS_PLL2_250M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_250M);
+	hws[IMX8MN_SYS_PLL2_333M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_333M);
+	hws[IMX8MN_SYS_PLL2_500M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_500M);
+	hws[IMX8MN_SYS_PLL2_1000M] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL2_1000M);
+
+	hws[IMX8MN_CLK_CLKOUT1_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1_SEL);
+	hws[IMX8MN_CLK_CLKOUT1_DIV] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1_DIV);
+	hws[IMX8MN_CLK_CLKOUT1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT1);
+	hws[IMX8MN_CLK_CLKOUT2_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2_SEL);
+	hws[IMX8MN_CLK_CLKOUT2_DIV] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2_DIV);
+	hws[IMX8MN_CLK_CLKOUT2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_CLK_CLKOUT2);
 
 	/* CORE */
 	hws[IMX8MN_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mn_a53_sels, base + 0x8000);
@@ -599,18 +573,15 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 
 	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
 	if (ret < 0) {
-		dev_err(dev, "failed to register hws for i.MX8MN\n");
-		goto unregister_hws;
+		imx_unregister_hw_clocks(hws, IMX8MN_CLK_END);
+		return dev_err_probe(dev, ret,
+				     "failed to register hws for i.MX8MN\n");
 	}
 
 	imx_register_uart_clocks();
 
+	dev_info(dev, "NXP i.MX8MN ccm clock driver probed\n");
 	return 0;
-
-unregister_hws:
-	imx_unregister_hw_clocks(hws, IMX8MN_CLK_END);
-
-	return ret;
 }
 
 static const struct of_device_id imx8mn_clk_of_match[] = {
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:27 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:27 +0100
Subject: [PATCH v6 12/18] dt-bindings: clock: imx8m-clock: add PLLs
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-13-dario.binacchi@amarulasolutions.com>

Though adding the PLLs to clocks and clock-names properties will break
the ABI, it is required to accurately describe the hardware. Indeed,
the Clock Control Module (CCM) receives clocks from the PLLs and
oscillators and generates clocks for on-chip peripherals.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v6:
- New

 .../bindings/clock/imx8m-clock.yaml           | 27 ++++++++++++++-----
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
index c643d4a81478..05bc01960045 100644
--- a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
@@ -29,12 +29,12 @@ properties:
     maxItems: 2
 
   clocks:
-    minItems: 6
-    maxItems: 7
+    minItems: 7
+    maxItems: 10
 
   clock-names:
-    minItems: 6
-    maxItems: 7
+    minItems: 7
+    maxItems: 10
 
   '#clock-cells':
     const: 1
@@ -86,6 +86,10 @@ allOf:
             - description: ext2 clock input
             - description: ext3 clock input
             - description: ext4 clock input
+            - description: audio1 PLL input
+            - description: audio2 PLL input
+            - description: dram PLL input
+            - description: video PLL input
 
         clock-names:
           items:
@@ -95,20 +99,31 @@ allOf:
             - const: clk_ext2
             - const: clk_ext3
             - const: clk_ext4
+            - const: audio_pll1
+            - const: audio_pll2
+            - const: dram_pll
+            - const: video_pll
 
 additionalProperties: false
 
 examples:
   # Clock Control Module node:
   - |
+    #include <dt-bindings/clock/imx8mm-clock.h>
+
     clock-controller at 30380000 {
         compatible = "fsl,imx8mm-ccm";
         reg = <0x30380000 0x10000>;
         #clock-cells = <1>;
         clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-                 <&clk_ext3>, <&clk_ext4>;
+                 <&clk_ext3>, <&clk_ext4>,
+                 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+                 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+                 <&anatop IMX8MM_ANATOP_DRAM_PLL>,
+                 <&anatop IMX8MM_ANATOP_VIDEO_PLL>;
         clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-                      "clk_ext3", "clk_ext4";
+                      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+                      "dram_pll", "video_pll";
     };
 
   - |
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:28 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:28 +0100
Subject: [PATCH v6 13/18] arm64: dts: imx8mm: add PLLs to clock controller module (ccm)
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-14-dario.binacchi@amarulasolutions.com>

Add the PLLs generated by anatop to the clock list of the Clock
Controller Module (CCM) node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 597041a05073..0b35aecb6755 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -642,9 +642,14 @@ clk: clock-controller at 30380000 {
 					     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
 				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-					 <&clk_ext3>, <&clk_ext4>;
+					 <&clk_ext3>, <&clk_ext4>,
+					 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MM_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MM_ANATOP_DRAM_PLL>,
+					 <&anatop IMX8MM_ANATOP_VIDEO_PLL>;
 				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-					      "clk_ext3", "clk_ext4";
+					      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+					      "dram_pll", "video_pll";
 				assigned-clocks = <&clk IMX8MM_CLK_A53_SRC>,
 						<&clk IMX8MM_CLK_A53_CORE>,
 						<&clk IMX8MM_CLK_NOC>,
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:29 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:29 +0100
Subject: [PATCH v6 14/18] arm64: dts: imx8mn: add PLLs to clock controller module (ccm)
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-15-dario.binacchi@amarulasolutions.com>

Add the PLLs generated by anatop to the clock list of the Clock
Controller Module (CCM) node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index 49be492b5687..aaa179784717 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -643,9 +643,14 @@ clk: clock-controller at 30380000 {
 					     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
 				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-					 <&clk_ext3>, <&clk_ext4>;
+					 <&clk_ext3>, <&clk_ext4>,
+					 <&anatop IMX8MN_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MN_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MN_ANATOP_DRAM_PLL>,
+					 <&anatop IMX8MN_ANATOP_VIDEO_PLL>;
 				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-					      "clk_ext3", "clk_ext4";
+					      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+					      "dram_pll", "video_pll";
 				assigned-clocks = <&clk IMX8MN_CLK_A53_SRC>,
 						<&clk IMX8MN_CLK_A53_CORE>,
 						<&clk IMX8MN_CLK_NOC>,
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:30 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:30 +0100
Subject: [PATCH v6 15/18] arm64: dts: imx8mp: add PLLs to clock controller module (ccm)
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-16-dario.binacchi@amarulasolutions.com>

Add the PLLs generated by anatop to the clock list of the Clock
Controller Module (CCM) node.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

(no changes since v4)

Changes in v4:
- New

 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 0b928e173f29..861bd4f4dced 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -751,9 +751,14 @@ clk: clock-controller at 30380000 {
 					     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 				#clock-cells = <1>;
 				clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
-					 <&clk_ext3>, <&clk_ext4>;
+					 <&clk_ext3>, <&clk_ext4>,
+					 <&anatop IMX8MP_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MP_ANATOP_AUDIO_PLL1>,
+					 <&anatop IMX8MP_ANATOP_DRAM_PLL>,
+					 <&anatop IMX8MP_ANATOP_VIDEO_PLL>;
 				clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
-					      "clk_ext3", "clk_ext4";
+					      "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
+					      "dram_pll", "video_pll";
 				assigned-clocks = <&clk IMX8MP_CLK_A53_SRC>,
 						  <&clk IMX8MP_CLK_A53_CORE>,
 						  <&clk IMX8MP_CLK_NOC>,
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:31 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:31 +0100
Subject: [PATCH v6 16/18] dt-bindings: clock: imx8m-clock: support spread spectrum clocking
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-17-dario.binacchi@amarulasolutions.com>

The addition of DT bindings for enabling and tuning spread spectrum
clocking generation can be applied specifically to the PLLs.

The "" value for the fsl,ssc-method property is specifically intended to
specify a "no SSC" case, as in the example, when you don't want to
configure spread spectrum for one of the PLLs, thus avoiding the use of
a method that would only make sense if SSC were being set.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v6:
- Improve the commit message
- change minItems from 7 to 1 for all the ssc properties added
- change maxItems from 10 to 4 for alle the ssc properties added
- update the DTS example

Changes in v4:
- Drop "fsl,ssc-clocks" property. The other added properties now refer
  to the clock list.
- Updated minItems and maxItems of
  - clocks
  - clock-names
  - fsl,ssc-modfreq-hz
  - fsl,ssc-modrate-percent
  - fsl,ssc-modmethod
- Updated the dts examples

Changes in v3:
- Added in v3
- The dt-bindings have been moved from fsl,imx8m-anatop.yaml to
  imx8m-clock.yaml. The anatop device (fsl,imx8m-anatop.yaml) is
  indeed more or less a syscon, so it represents a memory area
  accessible by ccm (imx8m-clock.yaml) to setup the PLLs.

Changes in v2:
- Add "allOf:" and place it after "required:" block, like in the
  example schema.
- Move the properties definition to the top-level.
- Drop unit types as requested by the "make dt_binding_check" command.

 .../bindings/clock/imx8m-clock.yaml           | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
index 05bc01960045..37cc6a6e89d4 100644
--- a/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/imx8m-clock.yaml
@@ -43,6 +43,37 @@ properties:
       ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8m-clock.h
       for the full list of i.MX8M clock IDs.
 
+  fsl,ssc-modfreq-hz:
+    description:
+      The values of modulation frequency (Hz unit) for each clock
+      supporting spread spectrum (i. e. audio_pll1, audio_pll2,
+      dram_pll and video_pll).
+    minItems: 1
+    maxItems: 4
+
+  fsl,ssc-modrate-percent:
+    description:
+      The percentage values of modulation rate for each clock
+      supporting spread spectrum (i. e. audio_pll1, audio_pll2,
+      dram_pll and video_pll).
+    minItems: 1
+    maxItems: 4
+
+  fsl,ssc-modmethod:
+    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+    description:
+      The modulation techniques for each clock supporting spread
+      spectrum (i. e. audio_pll1, audio_pll2, dram_pll and
+      video_pll).
+    minItems: 1
+    maxItems: 4
+    items:
+      enum:
+        - ""
+        - down-spread
+        - up-spread
+        - center-spread
+
 required:
   - compatible
   - reg
@@ -76,6 +107,10 @@ allOf:
             - const: clk_ext2
             - const: clk_ext3
             - const: clk_ext4
+        fsl,ssc-modfreq-hz: false
+        fsl,ssc-modrate-percent: false
+        fsl,ssc-modmethod: false
+
     else:
       properties:
         clocks:
@@ -124,6 +159,9 @@ examples:
         clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
                       "clk_ext3", "clk_ext4", "audio_pll1", "audio_pll2",
                       "dram_pll", "video_pll";
+        fsl,ssc-modfreq-hz = <6818>, <0>, <0>, <2419>;
+        fsl,ssc-modrate-percent = <3>, <0>, <0>, <7>;
+        fsl,ssc-modmethod = "down-spread", "", "", "center-spread";
     };
 
   - |
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:32 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:32 +0100
Subject: [PATCH v6 17/18] clk: imx: pll14xx: support spread spectrum clock generation
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-18-dario.binacchi@amarulasolutions.com>

Add support for spread spectrum clock (SSC) generation to the pll14xxx
driver.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v6:
- Update the code based on the changes made to the DT bindings

 drivers/clk/imx/clk-pll14xx.c | 134 ++++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h         |  16 ++++
 2 files changed, 150 insertions(+)

diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index d63564dbb12c..c20f1ade9dff 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -20,6 +20,8 @@
 #define GNRL_CTL	0x0
 #define DIV_CTL0	0x4
 #define DIV_CTL1	0x8
+#define SSCG_CTRL	0xc
+
 #define LOCK_STATUS	BIT(31)
 #define LOCK_SEL_MASK	BIT(29)
 #define CLKE_MASK	BIT(11)
@@ -31,6 +33,10 @@
 #define KDIV_MASK	GENMASK(15, 0)
 #define KDIV_MIN	SHRT_MIN
 #define KDIV_MAX	SHRT_MAX
+#define SSCG_ENABLE	BIT(31)
+#define MFREQ_CTL_MASK	GENMASK(19, 12)
+#define MRAT_CTL_MASK	GENMASK(9, 4)
+#define SEL_PF_MASK	GENMASK(1, 0)
 
 #define LOCK_TIMEOUT_US		10000
 
@@ -40,6 +46,8 @@ struct clk_pll14xx {
 	enum imx_pll14xx_type		type;
 	const struct imx_pll14xx_rate_table *rate_table;
 	int rate_count;
+	bool                            ssc_enable;
+	struct imx_pll14xx_ssc		ssc_conf;
 };
 
 #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
@@ -347,6 +355,27 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
 	return 0;
 }
 
+static void clk_pll1443x_enable_ssc(struct clk_hw *hw, unsigned long parent_rate,
+				    unsigned int pdiv, unsigned int mdiv)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+	struct imx_pll14xx_ssc *conf = &pll->ssc_conf;
+	u32 sscg_ctrl, mfr, mrr;
+
+	sscg_ctrl = readl_relaxed(pll->base + SSCG_CTRL);
+	sscg_ctrl &=
+		~(SSCG_ENABLE | MFREQ_CTL_MASK | MRAT_CTL_MASK | SEL_PF_MASK);
+
+	mfr = parent_rate / (conf->mod_freq * pdiv * (1 << 5));
+	mrr = (conf->mod_rate * mdiv * (1 << 6)) / (100 * mfr);
+
+	sscg_ctrl |= SSCG_ENABLE | FIELD_PREP(MFREQ_CTL_MASK, mfr) |
+		FIELD_PREP(MRAT_CTL_MASK, mrr) |
+		FIELD_PREP(SEL_PF_MASK, conf->mod_type);
+
+	writel_relaxed(sscg_ctrl, pll->base + SSCG_CTRL);
+}
+
 static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 				 unsigned long prate)
 {
@@ -368,6 +397,9 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 		writel_relaxed(FIELD_PREP(KDIV_MASK, rate.kdiv),
 			       pll->base + DIV_CTL1);
 
+		if (pll->ssc_enable)
+			clk_pll1443x_enable_ssc(hw, prate, rate.pdiv, rate.mdiv);
+
 		return 0;
 	}
 
@@ -408,6 +440,9 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 	gnrl_ctl &= ~BYPASS_MASK;
 	writel_relaxed(gnrl_ctl, pll->base + GNRL_CTL);
 
+	if (pll->ssc_enable)
+		clk_pll1443x_enable_ssc(hw, prate, rate.pdiv, rate.mdiv);
+
 	return 0;
 }
 
@@ -542,3 +577,102 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
 	return hw;
 }
 EXPORT_SYMBOL_GPL(imx_dev_clk_hw_pll14xx);
+
+void imx_clk_pll14xx_enable_ssc(struct clk_hw *hw, struct imx_pll14xx_ssc *conf)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+
+	pll->ssc_enable = true;
+	memcpy(&pll->ssc_conf, conf, sizeof(pll->ssc_conf));
+}
+EXPORT_SYMBOL_GPL(imx_clk_pll14xx_enable_ssc);
+
+static int clk_pll14xx_ssc_mod_type(const char *name,
+				    enum imx_pll14xx_ssc_mod_type *mod_type)
+{
+	int i;
+	struct {
+		const char *name;
+		enum imx_pll14xx_ssc_mod_type id;
+	} mod_types[] = {
+		{ .name = "down-spread", .id = IMX_PLL14XX_SSC_DOWN_SPREAD },
+		{ .name = "up-spread", .id = IMX_PLL14XX_SSC_UP_SPREAD },
+		{ .name = "center-spread", .id = IMX_PLL14XX_SSC_CENTER_SPREAD }
+	};
+
+	for (i = 0; i < ARRAY_SIZE(mod_types); i++) {
+		if (!strcmp(name, mod_types[i].name)) {
+			*mod_type = mod_types[i].id;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int clk_pll14xx_ssc_index(const char *pll_name)
+{
+	static const char *const pll_names[] = {
+		"audio_pll1",
+		"audio_pll2",
+		"dram_pll",
+		"video_pll"
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pll_names); i++) {
+		if (!strcmp(pll_names[i], pll_name))
+			return i;
+	}
+
+	return -ENODEV;
+}
+
+int imx_clk_pll14xx_ssc_parse_dt(struct device_node *np, const char *pll_name,
+				 struct imx_pll14xx_ssc *conf)
+{
+	int index, ret;
+	const char *s;
+
+	if (!conf)
+		return -EINVAL;
+
+	index = clk_pll14xx_ssc_index(pll_name);
+	if (index < 0)
+		return index;
+
+	ret = of_property_read_u32_index(np, "fsl,ssc-modfreq-hz", index,
+					 &conf->mod_freq);
+	if (ret)
+		return ret;
+
+	ret = of_property_read_u32_index(np, "fsl,ssc-modrate-percent", index,
+					 &conf->mod_rate);
+	if (ret) {
+		pr_err("missing fsl,ssc-modrate-percent property for %pOFn\n",
+		       np);
+		return ret;
+	}
+
+	ret = of_property_read_string_index(np, "fsl,ssc-modmethod", index, &s);
+	if (ret) {
+		pr_err("failed to get fsl,ssc-modmethod property for %pOFn\n",
+		       np);
+		return ret;
+	}
+
+	if (strlen(s) == 0)
+		return -ENODEV;
+
+	ret = clk_pll14xx_ssc_mod_type(s, &conf->mod_type);
+	if (ret) {
+		pr_err("wrong fsl,ssc-modmethod property for %pOFn\n", np);
+		return ret;
+	}
+
+	pr_debug("%s: SSC %s settings: mod_freq: %d, mod_rate: %d: mod_method: %s [%d]\n",
+		__func__, pll_name, conf->mod_freq, conf->mod_rate, s, conf->mod_type);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(imx_clk_pll14xx_ssc_parse_dt);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 52055fda3058..edd28b78b115 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -69,6 +69,18 @@ struct imx_pll14xx_clk {
 	int flags;
 };
 
+enum imx_pll14xx_ssc_mod_type {
+	IMX_PLL14XX_SSC_DOWN_SPREAD,
+	IMX_PLL14XX_SSC_UP_SPREAD,
+	IMX_PLL14XX_SSC_CENTER_SPREAD,
+};
+
+struct imx_pll14xx_ssc {
+	unsigned int mod_freq;
+	unsigned int mod_rate;
+	enum imx_pll14xx_ssc_mod_type mod_type;
+};
+
 extern struct imx_pll14xx_clk imx_1416x_pll;
 extern struct imx_pll14xx_clk imx_1443x_pll;
 extern struct imx_pll14xx_clk imx_1443x_dram_pll;
@@ -494,4 +506,8 @@ struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible,
 struct clk_hw *imx8m_anatop_get_clk_hw(int id);
 #endif
 
+void imx_clk_pll14xx_enable_ssc(struct clk_hw *hw, struct imx_pll14xx_ssc *conf);
+int imx_clk_pll14xx_ssc_parse_dt(struct device_node *np, const char *pll_name,
+				 struct imx_pll14xx_ssc *conf);
+
 #endif
-- 
2.43.0



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:33 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:33 +0100
Subject: [PATCH v6 18/18] clk: imx8mn: support spread spectrum clock generation
In-Reply-To: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
References: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20241222170534.3621453-19-dario.binacchi@amarulasolutions.com>

Add support for spread spectrum clock generation for the audio, video,
and DRAM PLLs.

Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

---

Changes in v6:
- Merge patches:
  10/20 dt-bindings: clock: imx8mm: add binding definitions for anatop
  11/20 dt-bindings: clock: imx8mn: add binding definitions for anatop
  12/20 dt-bindings: clock: imx8mp: add binding definitions for anatop
  to
  05/20 dt-bindings: clock: imx8m-anatop: define clocks/clock-names
  now renamed
  05/18 dt-bindings: clock: imx8m-anatop: add oscillators and PLLs
- Split the patch
  15/20 dt-bindings-clock-imx8m-clock-support-spread-spectru.patch
  into
  12/18 dt-bindings: clock: imx8m-clock: add PLLs
  16/18 dt-bindings: clock: imx8m-clock: support spread spectrum clocking

Changes in v5:
- Fix compilation errors.
- Separate driver code from dt-bindings

Changes in v4:
- Add dt-bindings for anatop
- Add anatop driver
- Drop fsl,ssc-clocks from spread spectrum dt-bindings

Changes in v3:
- Patches 1/8 has been added in version 3. The dt-bindings have
  been moved from fsl,imx8m-anatop.yaml to imx8m-clock.yaml. The
  anatop device (fsl,imx8m-anatop.yaml) is indeed more or less a
  syscon, so it represents a memory area accessible by ccm
  (imx8m-clock.yaml) to setup the PLLs.
- Patches {3,5}/8 have been added in version 3.
- Patches {4,6,8}/8 use ccm device node instead of the anatop one.

Changes in v2:
- Add "allOf:" and place it after "required:" block, like in the
  example schema.
- Move the properties definition to the top-level.
- Drop unit types as requested by the "make dt_binding_check" command.

 drivers/clk/imx/clk-imx8mn.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 588cebce6c9d..c61368e724f7 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -306,6 +306,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	void __iomem *base;
+	struct imx_pll14xx_ssc ssc_conf;
 	int ret;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
@@ -338,9 +339,21 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_SYS_PLL3_REF_SEL);
 
 	hws[IMX8MN_AUDIO_PLL1] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL1);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "audio_pll1", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_AUDIO_PLL1], &ssc_conf);
+
 	hws[IMX8MN_AUDIO_PLL2] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_AUDIO_PLL2);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "audio_pll2", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_AUDIO_PLL2], &ssc_conf);
+
 	hws[IMX8MN_VIDEO_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_VIDEO_PLL);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "video_pll", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_VIDEO_PLL], &ssc_conf);
+
 	hws[IMX8MN_DRAM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_DRAM_PLL);
+	if (!imx_clk_pll14xx_ssc_parse_dt(np, "dram_pll", &ssc_conf))
+		imx_clk_pll14xx_enable_ssc(hws[IMX8MN_DRAM_PLL], &ssc_conf);
+
 	hws[IMX8MN_GPU_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_GPU_PLL);
 	hws[IMX8MN_M7_ALT_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_M7_ALT_PLL);
 	hws[IMX8MN_ARM_PLL] = imx8m_anatop_get_clk_hw(IMX8MN_ANATOP_ARM_PLL);
-- 
2.43.0



From wens at csie.org  Sun Dec 22 09:15:13 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Mon, 23 Dec 2024 01:15:13 +0800
Subject: [PATCH 2/3] ASoC: sun4i-codec: support hp-det-gpios property
In-Reply-To: <20241221094122.27325-3-ryan@testtoast.com>
References: <20241221094122.27325-1-ryan@testtoast.com> <20241221094122.27325-3-ryan@testtoast.com>
Message-ID: <CAGb2v64qf0jNv72uHUK+aSj0Xt-bf+DW0NCnsZmLf-6xHZF_ew@mail.gmail.com>

On Sat, Dec 21, 2024 at 5:41?PM Ryan Walklin <ryan at testtoast.com> wrote:
>
> From: Chris Morgan <macromorgan at hotmail.com>
>
> Add support for GPIO headphone detection with the hp-det-gpios
> property. In order for this to properly disable the path upon
> removal of headphones, the output must be labelled Headphone which
> is a common sink in the driver. Note this patch also adds the output
> of Headphone for the H616 codec.
>
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> Signed-off-by: Ryan Walklin <ryan at testtoast.com>
> ---
>  sound/soc/sunxi/sun4i-codec.c | 59 +++++++++++++++++++++++++++++++++--
>  1 file changed, 57 insertions(+), 2 deletions(-)
>
> diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
> index 933a0913237c8..5f718dd3fcf0a 100644
> --- a/sound/soc/sunxi/sun4i-codec.c
> +++ b/sound/soc/sunxi/sun4i-codec.c
> @@ -21,6 +21,7 @@
>  #include <linux/gpio/consumer.h>
>
>  #include <sound/core.h>
> +#include <sound/jack.h>
>  #include <sound/pcm.h>
>  #include <sound/pcm_params.h>
>  #include <sound/soc.h>
> @@ -272,6 +273,7 @@ struct sun4i_codec {
>         struct clk      *clk_module;
>         struct reset_control *rst;
>         struct gpio_desc *gpio_pa;
> +       struct gpio_desc *gpio_hp;
>
>         /* ADC_FIFOC register is at different offset on different SoCs */
>         struct regmap_field *reg_adc_fifoc;
> @@ -1302,6 +1304,49 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
>         .ops = &dummy_dai_ops,
>  };
>
> +static struct snd_soc_jack sun4i_headphone_jack;
> +
> +static struct snd_soc_jack_pin sun4i_headphone_jack_pins[] = {
> +       { .pin = "Headphone", .mask = SND_JACK_HEADPHONE},
> +};
> +
> +static struct snd_soc_jack_gpio sun4i_headphone_jack_gpio = {
> +       .name = "hp-det",
> +       .report = SND_JACK_HEADPHONE,
> +       .debounce_time = 150,
> +};
> +
> +static int sun4i_codec_machine_init(struct snd_soc_pcm_runtime *rtd)
> +{
> +       struct snd_soc_card *card = rtd->card;
> +       struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
> +       int ret;
> +
> +       if (scodec->gpio_hp) {
> +               ret = snd_soc_card_jack_new_pins(card, "Headphone Jack",
> +                                                SND_JACK_HEADPHONE,
> +                                                &sun4i_headphone_jack,
> +                                                sun4i_headphone_jack_pins,
> +                                                ARRAY_SIZE(sun4i_headphone_jack_pins));
> +               if (ret) {
> +                       dev_err(rtd->dev,
> +                               "Headphone jack creation failed: %d\n", ret);
> +                       return ret;
> +               }
> +
> +               sun4i_headphone_jack_gpio.desc = scodec->gpio_hp;
> +               ret = snd_soc_jack_add_gpios(&sun4i_headphone_jack, 1,
> +                                            &sun4i_headphone_jack_gpio);
> +
> +               if (ret) {
> +                       dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret);
> +                       return ret;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
>  static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
>                                                         int *num_links)
>  {
> @@ -1327,6 +1372,7 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
>         link->codecs->name      = dev_name(dev);
>         link->platforms->name   = dev_name(dev);
>         link->dai_fmt           = SND_SOC_DAIFMT_I2S;
> +       link->init              = sun4i_codec_machine_init;
>
>         *num_links = 1;
>
> @@ -1635,10 +1681,11 @@ static const struct snd_soc_component_driver sun50i_h616_codec_codec = {
>  };
>
>  static const struct snd_kcontrol_new sun50i_h616_card_controls[] = {
> -       SOC_DAPM_PIN_SWITCH("LINEOUT"),
> +       SOC_DAPM_PIN_SWITCH("Speaker"),

Why?

>  };
>
>  static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = {
> +       SND_SOC_DAPM_HP("Headphone", NULL),
>         SND_SOC_DAPM_LINE("Line Out", NULL),
>         SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
>  };
> @@ -1684,7 +1731,7 @@ static struct snd_soc_card *sun50i_h616_codec_create_card(struct device *dev)
>
>         card->dev               = dev;
>         card->owner             = THIS_MODULE;
> -       card->name              = "H616 Audio Codec";
> +       card->name              = "h616-audio-codec";

Why?

>         card->driver_name       = "sun4i-codec";
>         card->controls          = sun50i_h616_card_controls;
>         card->num_controls      = ARRAY_SIZE(sun50i_h616_card_controls);
> @@ -1940,6 +1987,14 @@ static int sun4i_codec_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> +       scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "allwinner,hp-det",
> +                                                 GPIOD_IN);

Just put it on the same line. Lines can go up to 100 characters.

> +       if (IS_ERR(scodec->gpio_hp)) {
> +               ret = PTR_ERR(scodec->gpio_hp);
> +               dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n");
> +               return ret;
> +       }
> +
>         /* reg_field setup */
>         scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
>                                                         scodec->regmap,
> --
> 2.47.1
>
>


From wens at csie.org  Sun Dec 22 09:18:18 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Mon, 23 Dec 2024 01:18:18 +0800
Subject: [PATCH v2] ARM: dts: sun8i-r40: remove unused GPIO regulator
In-Reply-To: <20241220172134.GA9899@lemon.iwr.uni-heidelberg.de>
References: <20241213195433.GA1568@lemon.iwr.uni-heidelberg.de>
 <20241214011612.4fd9e4bf@minigeek.lan> <e61c927a4dfe909f4ede4a07dffd9dcd762875be.camel@icenowy.me>
 <20241220172134.GA9899@lemon.iwr.uni-heidelberg.de>
Message-ID: <CAGb2v64ovacuS+G+k3zBvQR+rW2_TSYh4p5frj7fLxz81K9Kmg@mail.gmail.com>

On Sat, Dec 21, 2024 at 1:21?AM Hermann Lauer
<Hermann.Lauer at iwr.uni-heidelberg.de> wrote:
>
> Hi,
>
> On Sat, Dec 14, 2024 at 03:13:23PM +0800, Icenowy Zheng wrote:
> > > CC:ing Icenowy, who added the regulator originally, with commit
> > > 0ca12c1ee43c ("ARM: sun8i: r40: add 5V regulator for Banana Pi M2
> > > Ultra").
> ...
> > > Icenowy: can you clarify what "newer" version this was referring to
> > > in
> > > that commit message? That commit in itself doesn't seem to do
> > > anything,
> > > as the regulator isn't referenced, and it's not always-on. It's only
> > > later when the USB nodes were added that it got used?
> > > So was PH23 really necessary? As Hermann reports, setting PH23 on a
> > > v1.1
> > > makes it reboot.
>
> diagnosed that futher now: PH23 is indeed powering the USB-Ports. Whats
> happens ist that I powered the board through the micro USB port which turned
> out to be limited to 900mA in axp221s. So the setting of reg 0x30 is
> the real culprit: Setting the two lowest bits in this register allows
> unlimited power over micro usb.
>
> In U-Boot:
>  i2c dev 0
>  i2c mw 34 30 63
>
> Or power the board through the barrel connector.
>
> In all cases the kernel turns on USB-A power and boots.
>
> > I am not sure, the schematics I have here (which says V1.0) have PH23
> > as NC... Well, the M2 Berry schematics have PH23 as 5V EN, maybe I
> > messed up M2U and M2B when developing?
>
> While V1.0 didn't need the PH23 setup due to nc, V1.1 needs it. Maybe V1.1
> was already on the horizon...

It seems this patch isn't needed then?


ChenYu

> Thanks for the insights and your support, guys.
>
> With seasons greetings
>   Hermann


From wens at csie.org  Sun Dec 22 09:19:08 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Mon, 23 Dec 2024 01:19:08 +0800
Subject: [PATCH v2 1/2] arm64: dts: allwinner: a64: Add WiFi/BT header on Pine64
In-Reply-To: <20241220120038.3137248-2-pbrobinson@gmail.com>
References: <20241220120038.3137248-1-pbrobinson@gmail.com> <20241220120038.3137248-2-pbrobinson@gmail.com>
Message-ID: <CAGb2v66enf0ybbyW3tW_YRdJB0=aOsXidm_bNHh=wdmm+HPBuw@mail.gmail.com>

On Fri, Dec 20, 2024 at 8:00?PM Peter Robinson <pbrobinson at gmail.com> wrote:
>
> This adds all the pin mappings on the WiFi/BT header on
> the original Pine64. They're disabled by default as the
> modules don't ship by default. This includes, where they
> haven't been already, UART1 for BT and mmc1 for WiFi.
>
> Signed-off-by: Peter Robinson <pbrobinson at gmail.com>
> ---
>  .../boot/dts/allwinner/sun50i-a64-pine64.dts    | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> index 09e71fd60785..f04f0f1badc4 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
> @@ -35,6 +35,11 @@ hdmi_con_in: endpoint {
>                         };
>                 };
>         };
> +
> +       wifi_pwrseq: pwrseq {
> +               compatible = "mmc-pwrseq-simple";
> +               reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
> +       };
>  };
>
>  &codec {
> @@ -124,6 +129,17 @@ &mmc0 {
>         status = "okay";
>  };
>
> +/* On Wifi/BT connector */
> +&mmc1 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&mmc1_pins>;
> +       vmmc-supply = <&reg_dldo4>;
> +       vqmmc-supply = <&reg_eldo1>;
> +       mmc-pwrseq = <&wifi_pwrseq>;
> +       bus-width = <4>;
> +       non-removable;

Please also add an explicit 'status = "disabled"', like what is done
for the uart below.

ChenYu

> +};
> +
>  &ohci0 {
>         status = "okay";
>  };
> @@ -286,6 +302,7 @@ &uart0 {
>  &uart1 {
>         pinctrl-names = "default";
>         pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
> +       uart-has-rtscts;
>         status = "disabled";
>  };
>
> --
> 2.47.1
>
>


From wens at csie.org  Sun Dec 22 09:19:50 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Mon, 23 Dec 2024 01:19:50 +0800
Subject: [PATCH v2 2/2] arm64: dts: allwinner: a64: Add WiFi/BT header on SoPine
In-Reply-To: <20241220120038.3137248-3-pbrobinson@gmail.com>
References: <20241220120038.3137248-1-pbrobinson@gmail.com> <20241220120038.3137248-3-pbrobinson@gmail.com>
Message-ID: <CAGb2v67re8kjHzmPQ1z6Jrvz4x5TBK+hD=DOxtGNTOFOJKAhvg@mail.gmail.com>

On Fri, Dec 20, 2024 at 8:00?PM Peter Robinson <pbrobinson at gmail.com> wrote:
>
> This adds all the pin mappings on the WiFi/BT header on
> the SoPine baseboard/A64-LTS. They're disabled by default
> as the modules don't ship by default. This includes, where
> they haven't been already, UART1 for BT and mmc1 for WiFi.
>
> Signed-off-by: Peter Robinson <pbrobinson at gmail.com>
> ---
>  .../allwinner/sun50i-a64-sopine-baseboard.dts | 24 +++++++++++++++++++
>  1 file changed, 24 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
> index be2347c8f267..752d2aae8465 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
> @@ -42,6 +42,11 @@ reg_vcc1v8: vcc1v8 {
>                 regulator-min-microvolt = <1800000>;
>                 regulator-max-microvolt = <1800000>;
>         };
> +
> +       wifi_pwrseq: pwrseq {
> +               compatible = "mmc-pwrseq-simple";
> +               reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
> +       };
>  };
>
>  &ac_power_supply {
> @@ -103,6 +108,17 @@ ext_rgmii_phy: ethernet-phy at 1 {
>         };
>  };
>
> +/* On Wifi/BT connector */
> +&mmc1 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&mmc1_pins>;
> +       vmmc-supply = <&reg_dldo4>;
> +       vqmmc-supply = <&reg_eldo1>;
> +       mmc-pwrseq = <&wifi_pwrseq>;
> +       bus-width = <4>;
> +       non-removable;

Same here, please explicitly set 'status = "disabled"' like what
you are doing with uart1 below.

ChenYu

> +};
> +
>  &mmc2 {
>         pinctrl-names = "default";
>         pinctrl-0 = <&mmc2_pins>;
> @@ -175,6 +191,14 @@ &uart0 {
>         status = "okay";
>  };
>
> +/* On Wifi/BT connector, with RTS/CTS */
> +&uart1 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
> +       uart-has-rtscts;
> +       status = "disabled";
> +};
> +
>  /* On Pi-2 connector */
>  &uart2 {
>         pinctrl-names = "default";
> --
> 2.47.1
>
>


From towinchenmi at gmail.com  Sun Dec 22 09:26:08 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:26:08 +0800
Subject: [PATCH v2] arm64: dts: apple: Split s8000/s8003 SoC DTS files
Message-ID: <20241222172735.145764-1-towinchenmi@gmail.com>

Despite what the code comments said, the DTS files were not split properly.
Since these two SoCs are now known to have minor differences like in
latencies for cpufreq state transistions, split the DTS files now.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
Changes since v1:
- Drop PMGR nodes file rename. This is now the first patch and other series
that modifies Apple A9 DTS files now depend on this series.

Link to v1: https://lore.kernel.org/asahi/20241206135051.56049-1-towinchenmi at gmail.com/T

Nick Chan

 arch/arm64/boot/dts/apple/s800-0-3.dtsi | 140 ++++++++++++++++++++++++
 arch/arm64/boot/dts/apple/s8000.dtsi    | 133 +---------------------
 arch/arm64/boot/dts/apple/s8003.dtsi    |  10 +-
 3 files changed, 146 insertions(+), 137 deletions(-)
 create mode 100644 arch/arm64/boot/dts/apple/s800-0-3.dtsi

diff --git a/arch/arm64/boot/dts/apple/s800-0-3.dtsi b/arch/arm64/boot/dts/apple/s800-0-3.dtsi
new file mode 100644
index 000000000000..082e5b1733d0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s800-0-3.dtsi
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple S8000/S8003 "A9" SoC
+ *
+ * This file contains parts common to both variants of A9
+ *
+ * Copyright (c) 2022, Konrad Dybcio <konradybcio at kernel.org>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/apple.h>
+
+/ {
+	interrupt-parent = <&aic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clkref: clock-ref {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "clkref";
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			compatible = "apple,twister";
+			reg = <0x0 0x0>;
+			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+
+		cpu1: cpu at 1 {
+			compatible = "apple,twister";
+			reg = <0x0 0x1>;
+			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		nonposted-mmio;
+		ranges;
+
+		serial0: serial at 20a0c0000 {
+			compatible = "apple,s5l-uart";
+			reg = <0x2 0x0a0c0000 0x0 0x4000>;
+			reg-io-width = <4>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 192 IRQ_TYPE_LEVEL_HIGH>;
+			/* Use the bootloader-enabled clocks for now. */
+			clocks = <&clkref>, <&clkref>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		aic: interrupt-controller at 20e100000 {
+			compatible = "apple,s8000-aic", "apple,aic";
+			reg = <0x2 0x0e100000 0x0 0x100000>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+		};
+
+		pinctrl_ap: pinctrl at 20f100000 {
+			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x0f100000 0x0 0x100000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_ap 0 0 208>;
+			apple,npins = <208>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 48 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_aop: pinctrl at 2100f0000 {
+			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x100f0000 0x0 0x100000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_aop 0 0 42>;
+			apple,npins = <42>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 113 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 114 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 115 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 118 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 119 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		wdt: watchdog at 2102b0000 {
+			compatible = "apple,s8000-wdt", "apple,wdt";
+			reg = <0x2 0x102b0000 0x0 0x4000>;
+			clocks = <&clkref>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 4 IRQ_TYPE_LEVEL_HIGH>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&aic>;
+		interrupt-names = "phys", "virt";
+		/* Note that A9 doesn't actually have a hypervisor (EL2 is not implemented). */
+		interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>,
+			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
+
+/*
+ * The A9 was made by two separate fabs on two different process
+ * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
+ * the S8003 (APL1022) on 16nm. There are some minor differences
+ * such as timing in cpufreq state transistions.
+ */
diff --git a/arch/arm64/boot/dts/apple/s8000.dtsi b/arch/arm64/boot/dts/apple/s8000.dtsi
index 6e9046ea106c..c7e39abda7e1 100644
--- a/arch/arm64/boot/dts/apple/s8000.dtsi
+++ b/arch/arm64/boot/dts/apple/s8000.dtsi
@@ -7,138 +7,11 @@
  * Copyright (c) 2022, Konrad Dybcio <konradybcio at kernel.org>
  */
 
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/interrupt-controller/apple-aic.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/pinctrl/apple.h>
-
-/ {
-	interrupt-parent = <&aic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	clkref: clock-ref {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <24000000>;
-		clock-output-names = "clkref";
-	};
-
-	cpus {
-		#address-cells = <2>;
-		#size-cells = <0>;
-
-		cpu0: cpu at 0 {
-			compatible = "apple,twister";
-			reg = <0x0 0x0>;
-			cpu-release-addr = <0 0>; /* To be filled in by loader */
-			enable-method = "spin-table";
-			device_type = "cpu";
-		};
-
-		cpu1: cpu at 1 {
-			compatible = "apple,twister";
-			reg = <0x0 0x1>;
-			cpu-release-addr = <0 0>; /* To be filled in by loader */
-			enable-method = "spin-table";
-			device_type = "cpu";
-		};
-	};
-
-	soc {
-		compatible = "simple-bus";
-		#address-cells = <2>;
-		#size-cells = <2>;
-		nonposted-mmio;
-		ranges;
-
-		serial0: serial at 20a0c0000 {
-			compatible = "apple,s5l-uart";
-			reg = <0x2 0x0a0c0000 0x0 0x4000>;
-			reg-io-width = <4>;
-			interrupt-parent = <&aic>;
-			interrupts = <AIC_IRQ 192 IRQ_TYPE_LEVEL_HIGH>;
-			/* Use the bootloader-enabled clocks for now. */
-			clocks = <&clkref>, <&clkref>;
-			clock-names = "uart", "clk_uart_baud0";
-			status = "disabled";
-		};
-
-		aic: interrupt-controller at 20e100000 {
-			compatible = "apple,s8000-aic", "apple,aic";
-			reg = <0x2 0x0e100000 0x0 0x100000>;
-			#interrupt-cells = <3>;
-			interrupt-controller;
-		};
-
-		pinctrl_ap: pinctrl at 20f100000 {
-			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
-			reg = <0x2 0x0f100000 0x0 0x100000>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio-ranges = <&pinctrl_ap 0 0 208>;
-			apple,npins = <208>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupt-parent = <&aic>;
-			interrupts = <AIC_IRQ 42 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 43 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 44 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 45 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 46 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 47 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 48 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
-		pinctrl_aop: pinctrl at 2100f0000 {
-			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
-			reg = <0x2 0x100f0000 0x0 0x100000>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
-			gpio-ranges = <&pinctrl_aop 0 0 42>;
-			apple,npins = <42>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupt-parent = <&aic>;
-			interrupts = <AIC_IRQ 113 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 114 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 115 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 116 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 117 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 118 IRQ_TYPE_LEVEL_HIGH>,
-				     <AIC_IRQ 119 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
-		wdt: watchdog at 2102b0000 {
-			compatible = "apple,s8000-wdt", "apple,wdt";
-			reg = <0x2 0x102b0000 0x0 0x4000>;
-			clocks = <&clkref>;
-			interrupt-parent = <&aic>;
-			interrupts = <AIC_IRQ 4 IRQ_TYPE_LEVEL_HIGH>;
-		};
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupt-parent = <&aic>;
-		interrupt-names = "phys", "virt";
-		/* Note that A9 doesn't actually have a hypervisor (EL2 is not implemented). */
-		interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>,
-			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
-	};
-};
+#include "s800-0-3.dtsi"
 
 /*
  * The A9 was made by two separate fabs on two different process
  * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
- * the S8003 (APL1022) on 16nm. While they are seemingly the same,
- * they do have distinct part numbers and devices using them have
- * distinct model names. There are currently no known differences
- * between these as far as Linux is concerned, but let's keep things
- * structured properly to make it easier to alter the behaviour of
- * one of the chips if need be.
+ * the S8003 (APL1022) on 16nm. There are some minor differences
+ * such as timing in cpufreq state transistions.
  */
diff --git a/arch/arm64/boot/dts/apple/s8003.dtsi b/arch/arm64/boot/dts/apple/s8003.dtsi
index 7e4ad4f7e499..807e3452f8a7 100644
--- a/arch/arm64/boot/dts/apple/s8003.dtsi
+++ b/arch/arm64/boot/dts/apple/s8003.dtsi
@@ -7,15 +7,11 @@
  * Copyright (c) 2022, Konrad Dybcio <konradybcio at kernel.org>
  */
 
-#include "s8000.dtsi"
+#include "s800-0-3.dtsi"
 
 /*
  * The A9 was made by two separate fabs on two different process
  * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
- * the S8003 (APL1022) on 16nm. While they are seemingly the same,
- * they do have distinct part numbers and devices using them have
- * distinct model names. There are currently no known differences
- * between these as far as Linux is concerned, but let's keep things
- * structured properly to make it easier to alter the behaviour of
- * one of the chips if need be.
+ * the S8003 (APL1022) on 16nm. There are some minor differences
+ * such as timing in cpufreq state transistions.
  */

base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:31:46 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:31:46 +0800
Subject: [PATCH v3 0/2] Device Tree for Apple T2 (T8012) SoC devices
Message-ID: <20241222173240.147675-1-towinchenmi@gmail.com>

This series adds device trees for the Apple T2 Security Chip found on
some Intel Macs released after 2017. This SoC is based on Apple A10
(T8010) SoC and, for many hardware blocks, can share the A10 compatibles.

Changes since v2:
- Drop PMGR nodes, moved to PMGR nodes for A7-A11, T2 SoC series.

Link to v2: https://lore.kernel.org/asahi/20241203051147.110980-1-towinchenmi at gmail.com/T

Changes since v1:
- Use imperative mood in commit messages

Link to v1: https://lore.kernel.org/asahi/20241201161942.36027-1-towinchenmi at gmail.com/T

[1]: https://lore.kernel.org/asahi/20241203050640.109378-1-towinchenmi at gmail.com/T

Cc: Aun-Ali Zaidi <admin at kodeit.net>
---

Nick Chan (2):
  dt-bindings: arm: apple: Add T2 devices
  arm64: dts: apple: Add T2 devices

 .../devicetree/bindings/arm/apple.yaml        |  41 ++++
 arch/arm64/boot/dts/apple/Makefile            |  16 ++
 arch/arm64/boot/dts/apple/t8012-j132.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j137.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j140a.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j140k.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j152f.dts     |  15 ++
 arch/arm64/boot/dts/apple/t8012-j160.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j174.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j185.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j185f.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j213.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j214k.dts     |  15 ++
 arch/arm64/boot/dts/apple/t8012-j215.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j223.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j230k.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j680.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j780.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi     |  44 +++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |  19 ++
 arch/arm64/boot/dts/apple/t8012.dtsi          | 176 ++++++++++++++++++
 21 files changed, 527 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j132.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j137.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140a.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j152f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j160.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j174.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j213.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j214k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j215.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j223.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j230k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j680.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j780.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012.dtsi


base-commit: 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:31:47 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:31:47 +0800
Subject: [PATCH v3 1/2] dt-bindings: arm: apple: Add T2 devices
In-Reply-To: <20241222173240.147675-1-towinchenmi@gmail.com>
References: <20241222173240.147675-1-towinchenmi@gmail.com>
Message-ID: <20241222173240.147675-2-towinchenmi@gmail.com>

Add the following apple,t8012 based platforms:

- Apple T2 MacBookPro15,2 (j132)
- Apple T2 iMacPro1,1 (j137)
- Apple T2 MacBookAir8,2 (j140a)
- Apple T2 MacBookAir8,1 (j140k)
- Apple T2 MacBookPro16,1 (j152f)
- Apple T2 MacPro7,1 (j160)
- Apple T2 Macmini8,1 (j174)
- Apple T2 iMac20,1 (j185)
- Apple T2 iMac20,2 (j185f)
- Apple T2 MacBookPro15,4 (j213)
- Apple T2 MacBookPro16,2 (j214k)
- Apple T2 MacBookPro16,4 (j215)
- Apple T2 MacBookPro16,3 (j223)
- Apple T2 MacBookAir9,1 (j230k)
- Apple T2 MacBookPro15,1 (j680)
- Apple T2 MacBookPro15,3 (j780)

These devices have no offical names, the naming scheme is from
libirecovery.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../devicetree/bindings/arm/apple.yaml        | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/apple.yaml b/Documentation/devicetree/bindings/arm/apple.yaml
index dc9aab19ff11..da60e9de1cfb 100644
--- a/Documentation/devicetree/bindings/arm/apple.yaml
+++ b/Documentation/devicetree/bindings/arm/apple.yaml
@@ -57,6 +57,25 @@ description: |
   - iPad Pro (2nd Generation) (10.5 Inch)
   - iPad Pro (2nd Generation) (12.9 Inch)
 
+  Devices based on the "T2" SoC:
+
+  - Apple T2 MacBookPro15,2 (j132)
+  - Apple T2 iMacPro1,1 (j137)
+  - Apple T2 MacBookAir8,2 (j140a)
+  - Apple T2 MacBookAir8,1 (j140k)
+  - Apple T2 MacBookPro16,1 (j152f)
+  - Apple T2 MacPro7,1 (j160)
+  - Apple T2 Macmini8,1 (j174)
+  - Apple T2 iMac20,1 (j185)
+  - Apple T2 iMac20,2 (j185f)
+  - Apple T2 MacBookPro15,4 (j213)
+  - Apple T2 MacBookPro16,2 (j214k)
+  - Apple T2 MacBookPro16,4 (j215)
+  - Apple T2 MacBookPro16,3 (j223)
+  - Apple T2 MacBookAir9,1 (j230k)
+  - Apple T2 MacBookPro15,1 (j680)
+  - Apple T2 MacBookPro15,3 (j780)
+
   Devices based on the "A11" SoC:
 
   - iPhone 8
@@ -211,6 +230,28 @@ properties:
           - const: apple,t8011
           - const: apple,arm-platform
 
+      - description: Apple T2 SoC based platforms
+        items:
+          - enum:
+              - apple,j132  # Apple T2 MacBookPro15,2 (j132)
+              - apple,j137  # Apple T2 iMacPro1,1 (j137)
+              - apple,j140a # Apple T2 MacBookAir8,2 (j140a)
+              - apple,j140k # Apple T2 MacBookAir8,1 (j140k)
+              - apple,j152f # Apple T2 MacBookPro16,1 (j152f)
+              - apple,j160  # Apple T2 MacPro7,1 (j160)
+              - apple,j174  # Apple T2 Macmini8,1 (j174)
+              - apple,j185  # Apple T2 iMac20,1 (j185)
+              - apple,j185f # Apple T2 iMac20,2 (j185f)
+              - apple,j213  # Apple T2 MacBookPro15,4 (j213)
+              - apple,j214k # Apple T2 MacBookPro16,2 (j214k)
+              - apple,j215  # Apple T2 MacBookPro16,4 (j215)
+              - apple,j223  # Apple T2 MacBookPro16,3 (j223)
+              - apple,j230k # Apple T2 MacBookAir9,1 (j230k)
+              - apple,j680  # Apple T2 MacBookPro15,1 (j680)
+              - apple,j780  # Apple T2 MacBookPro15,3 (j780)
+          - const: apple,t8012
+          - const: apple,arm-platform
+
       - description: Apple A11 SoC based platforms
         items:
           - enum:
-- 
2.47.1



From dario.binacchi at amarulasolutions.com  Sun Dec 22 09:04:15 2024
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Sun, 22 Dec 2024 18:04:15 +0100
Subject: [PATCH v6 00/18] Support spread spectrum clocking for i.MX8N PLLs
Message-ID: <20241222170534.3621453-1-dario.binacchi@amarulasolutions.com>

The series adds support for spread spectrum clocking for i.MX8MN
PLLs (audio, video and DRAM). It has been tested for the video PLL on
a board using i.MX8MN.

The patches added in version 4, such as the dt-bindings and the driver
for anatop, were inspired by the extensive email exchange from version 3:
https://lore.kernel.org/imx/20241106090549.3684963-1-dario.binacchi at amarulasolutions.com/

The series added spectrum spread support for the imx8mn platform only,
but in case it was merged, confirming that the directives and suggestions
made by the maintainers were correctly understood and implemented, I will
extend this support to the imx8mm and imx8mp platforms as well.

Changes in v6:
- Merge patches:
  10/20 dt-bindings: clock: imx8mm: add binding definitions for anatop
  11/20 dt-bindings: clock: imx8mn: add binding definitions for anatop
  12/20 dt-bindings: clock: imx8mp: add binding definitions for anatop
  to
  05/20 dt-bindings: clock: imx8m-anatop: define clocks/clock-names
  now renamed
  05/18 dt-bindings: clock: imx8m-anatop: add oscillators and PLLs
- Split the patch
  15/20 dt-bindings-clock-imx8m-clock-support-spread-spectru.patch
  into
  12/18 dt-bindings: clock: imx8m-clock: add PLLs
  16/18 dt-bindings: clock: imx8m-clock: support spread spectrum clocking

Changes in v5:
- Fix compilation errors.
- Separate driver code from dt-bindings

Changes in v4:
- Add dt-bindings for anatop
- Add anatop driver
- Drop fsl,ssc-clocks from spread spectrum dt-bindings

Changes in v3:
- Patches 1/8 has been added in version 3. The dt-bindings have
  been moved from fsl,imx8m-anatop.yaml to imx8m-clock.yaml. The
  anatop device (fsl,imx8m-anatop.yaml) is indeed more or less a
  syscon, so it represents a memory area accessible by ccm
  (imx8m-clock.yaml) to setup the PLLs.
- Patches {3,5}/8 have been added in version 3.
- Patches {4,6,8}/8 use ccm device node instead of the anatop one.

Changes in v2:
- Add "allOf:" and place it after "required:" block, like in the
  example schema.
- Move the properties definition to the top-level.
- Drop unit types as requested by the "make dt_binding_check" command.

Dario Binacchi (18):
  dt-bindings: clock: imx8mm: add VIDEO_PLL clocks
  clk: imx8mm: rename video_pll1 to video_pll
  dt-bindings: clock: imx8mp: add VIDEO_PLL clocks
  clk: imx8mp: rename video_pll1 to video_pll
  dt-bindings: clock: imx8m-anatop: add oscillators and PLLs
  arm64: dts: imx8mm: add anatop clocks
  arm64: dts: imx8mn: add anatop clocks
  arm64: dts: imx8mp: add anatop clocks
  arm64: dts: imx8mq: add anatop clocks
  clk: imx: add hw API imx8m_anatop_get_clk_hw
  clk: imx: add support for i.MX8MN anatop clock driver
  dt-bindings: clock: imx8m-clock: add PLLs
  arm64: dts: imx8mm: add PLLs to clock controller module (ccm)
  arm64: dts: imx8mn: add PLLs to clock controller module (ccm)
  arm64: dts: imx8mp: add PLLs to clock controller module (ccm)
  dt-bindings: clock: imx8m-clock: support spread spectrum clocking
  clk: imx: pll14xx: support spread spectrum clock generation
  clk: imx8mn: support spread spectrum clock generation

 .../bindings/clock/fsl,imx8m-anatop.yaml      |  53 +++-
 .../bindings/clock/imx8m-clock.yaml           |  65 +++-
 arch/arm64/boot/dts/freescale/imx8mm.dtsi     |  11 +-
 arch/arm64/boot/dts/freescale/imx8mn.dtsi     |  11 +-
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     |  11 +-
 arch/arm64/boot/dts/freescale/imx8mq.dtsi     |   2 +
 drivers/clk/imx/Makefile                      |   2 +-
 drivers/clk/imx/clk-imx8mm.c                  | 102 +++----
 drivers/clk/imx/clk-imx8mn-anatop.c           | 283 ++++++++++++++++++
 drivers/clk/imx/clk-imx8mn.c                  | 188 ++++++------
 drivers/clk/imx/clk-imx8mp.c                  | 118 ++++----
 drivers/clk/imx/clk-pll14xx.c                 | 134 +++++++++
 drivers/clk/imx/clk.c                         |  28 ++
 drivers/clk/imx/clk.h                         |  23 ++
 include/dt-bindings/clock/imx8mm-clock.h      |  76 ++++-
 include/dt-bindings/clock/imx8mn-clock.h      |  64 ++++
 include/dt-bindings/clock/imx8mp-clock.h      |  80 ++++-
 17 files changed, 1017 insertions(+), 234 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx8mn-anatop.c

-- 
2.43.0



From towinchenmi at gmail.com  Sun Dec 22 09:31:48 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:31:48 +0800
Subject: [PATCH v3 2/2] arm64: dts: apple: Add T2 devices
In-Reply-To: <20241222173240.147675-1-towinchenmi@gmail.com>
References: <20241222173240.147675-1-towinchenmi@gmail.com>
Message-ID: <20241222173240.147675-3-towinchenmi@gmail.com>

Add DTS files for the T2 SoC and the following devices based on it:

- Apple T2 MacBookPro15,2 (j132)
- Apple T2 iMacPro1,1 (j137)
- Apple T2 MacBookAir8,2 (j140a)
- Apple T2 MacBookAir8,1 (j140k)
- Apple T2 MacBookPro16,1 (j152f)
- Apple T2 MacPro7,1 (j160)
- Apple T2 Macmini8,1 (j174)
- Apple T2 iMac20,1 (j185)
- Apple T2 iMac20,2 (j185f)
- Apple T2 MacBookPro15,4 (j213)
- Apple T2 MacBookPro16,2 (j214k)
- Apple T2 MacBookPro16,4 (j215)
- Apple T2 MacBookPro16,3 (j223)
- Apple T2 MacBookAir9,1 (j230k)
- Apple T2 MacBookPro15,1 (j680)
- Apple T2 MacBookPro15,3 (j780)

The Apple T2 is an A10-based security chip found on some Intel Macs
from 2017 onwards. On models with a touchbar, the touchbar's
display is wired to it. These devices have no offical names, the
naming scheme is from libirecovery.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/Makefile            |  16 ++
 arch/arm64/boot/dts/apple/t8012-j132.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j137.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j140a.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j140k.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j152f.dts     |  15 ++
 arch/arm64/boot/dts/apple/t8012-j160.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j174.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j185.dts      |  14 ++
 arch/arm64/boot/dts/apple/t8012-j185f.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j213.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j214k.dts     |  15 ++
 arch/arm64/boot/dts/apple/t8012-j215.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j223.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j230k.dts     |  14 ++
 arch/arm64/boot/dts/apple/t8012-j680.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-j780.dts      |  15 ++
 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi     |  44 +++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |  19 ++
 arch/arm64/boot/dts/apple/t8012.dtsi          | 176 ++++++++++++++++++
 20 files changed, 486 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j132.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j137.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140a.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j140k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j152f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j160.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j174.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j185f.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j213.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j214k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j215.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j223.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j230k.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j680.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-j780.dts
 create mode 100644 arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012.dtsi

diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile
index ab6ebb53218a..4f337bff36cd 100644
--- a/arch/arm64/boot/dts/apple/Makefile
+++ b/arch/arm64/boot/dts/apple/Makefile
@@ -46,6 +46,22 @@ dtb-$(CONFIG_ARCH_APPLE) += t8011-j120.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8011-j121.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8011-j207.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8011-j208.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j132.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j137.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j140a.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j140k.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j152f.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j160.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j174.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j185.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j185f.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j213.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j215.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j223.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j230k.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j214k.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j680.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8012-j780.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8015-d201.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8015-d20.dtb
 dtb-$(CONFIG_ARCH_APPLE) += t8015-d211.dtb
diff --git a/arch/arm64/boot/dts/apple/t8012-j132.dts b/arch/arm64/boot/dts/apple/t8012-j132.dts
new file mode 100644
index 000000000000..778a69be18dd
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j132.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,2 (j132), J132, iBridge2,4
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,2 (j132)";
+	compatible = "apple,j132", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j137.dts b/arch/arm64/boot/dts/apple/t8012-j137.dts
new file mode 100644
index 000000000000..dbde1ad7ce14
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j137.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 iMacPro1,1 (j137), J137, iBridge2,1
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 iMacPro1,1 (j137)";
+	compatible = "apple,j137", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j140a.dts b/arch/arm64/boot/dts/apple/t8012-j140a.dts
new file mode 100644
index 000000000000..5df1ff74d2df
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j140a.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookAir8,2 (j140a), J140a, iBridge2,12
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookAir8,2 (j140a)";
+	compatible = "apple,j140a", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j140k.dts b/arch/arm64/boot/dts/apple/t8012-j140k.dts
new file mode 100644
index 000000000000..a0ef1585e5c2
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j140k.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookAir8,1 (j140k), J140k, iBridge2,8
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookAir8,1 (j140k)";
+	compatible = "apple,j140k", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j152f.dts b/arch/arm64/boot/dts/apple/t8012-j152f.dts
new file mode 100644
index 000000000000..261416eaf97e
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j152f.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,1 (j152f), J152f, iBridge2,14
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,1 (j152f)";
+	compatible = "apple,j152f", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j160.dts b/arch/arm64/boot/dts/apple/t8012-j160.dts
new file mode 100644
index 000000000000..fbcc0604f4a0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j160.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacPro7,1 (j160), J160, iBridge2,6
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacPro7,1 (j160)";
+	compatible = "apple,j160", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j174.dts b/arch/arm64/boot/dts/apple/t8012-j174.dts
new file mode 100644
index 000000000000..d11c70f84a71
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j174.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 Macmini8,1 (j174), J174, iBridge2,5
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 Macmini8,1 (j174)";
+	compatible = "apple,j174", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j185.dts b/arch/arm64/boot/dts/apple/t8012-j185.dts
new file mode 100644
index 000000000000..33492f5db46d
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j185.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 iMac20,1 (j185), J185, iBridge2,19
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 iMac20,1 (j185)";
+	compatible = "apple,j185", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j185f.dts b/arch/arm64/boot/dts/apple/t8012-j185f.dts
new file mode 100644
index 000000000000..3a4abdd8f7d7
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j185f.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 iMac20,2 (j185f), J185f, iBridge2,20
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 iMac20,2 (j185f)";
+	compatible = "apple,j185f", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j213.dts b/arch/arm64/boot/dts/apple/t8012-j213.dts
new file mode 100644
index 000000000000..8270812b9a68
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j213.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,4 (j213), J213, iBridge2,10
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,4 (j213)";
+	compatible = "apple,j213", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j214k.dts b/arch/arm64/boot/dts/apple/t8012-j214k.dts
new file mode 100644
index 000000000000..5b8e42512060
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j214k.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,2 (j214k), J214k, iBridge2,16
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,2 (j214k)";
+	compatible = "apple,j214k", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j215.dts b/arch/arm64/boot/dts/apple/t8012-j215.dts
new file mode 100644
index 000000000000..ad574fbf7f92
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j215.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,4 (j215), J215, iBridge2,22
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,4 (j215)";
+	compatible = "apple,j215", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j223.dts b/arch/arm64/boot/dts/apple/t8012-j223.dts
new file mode 100644
index 000000000000..de75d775aac5
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j223.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro16,3 (j223), J223, iBridge2,21
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro16,3 (j223)";
+	compatible = "apple,j223", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j230k.dts b/arch/arm64/boot/dts/apple/t8012-j230k.dts
new file mode 100644
index 000000000000..4b19bc70ab0f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j230k.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookAir9,1 (j230k), J230k, iBridge2,15
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+
+/ {
+	model = "Apple T2 MacBookAir9,1 (j230k)";
+	compatible = "apple,j230k", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j680.dts b/arch/arm64/boot/dts/apple/t8012-j680.dts
new file mode 100644
index 000000000000..aa5a72e07d3f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j680.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,1 (j680), J680, iBridge2,3
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,1 (j680)";
+	compatible = "apple,j680", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-j780.dts b/arch/arm64/boot/dts/apple/t8012-j780.dts
new file mode 100644
index 000000000000..9cee891cb16d
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-j780.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T2 MacBookPro15,3 (j780), J780, iBridge2,7
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "t8012-jxxx.dtsi"
+#include "t8012-touchbar.dtsi"
+
+/ {
+	model = "Apple T2 MacBookPro15,3 (j780)";
+	compatible = "apple,j780", "apple,t8012", "apple,arm-platform";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
new file mode 100644
index 000000000000..36e82633bc52
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Common Device Tree for all T2 devices
+ *
+ * target-type: J132, J137, J140a, J140k, J152f, J160, J174, J185, J185f
+ * J213, J214k, J215, J223, J230k, J680, J780
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include "t8012.dtsi"
+
+/ {
+	chassis-type = "embedded";
+
+	aliases {
+		serial0 = &serial0;
+	};
+
+	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		stdout-path = "serial0";
+	};
+
+	memory at 800000000 {
+		device_type = "memory";
+		reg = <0x8 0 0 0>; /* To be filled by loader */
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* To be filled by loader */
+	};
+};
+
+&serial0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
new file mode 100644
index 000000000000..f4a8b12437f0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Common Device Tree for T2 devices with a Touch Bar
+ *
+ * target-type: J152f, J213, J214k, J215, J223, J680, J780
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/ {
+	chosen {
+		framebuffer0: framebuffer at 0 {
+			compatible = "apple,simple-framebuffer", "simple-framebuffer";
+			reg = <0 0 0 0>; /* To be filled by loader */
+			/* Format properties will be added by loader */
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8012.dtsi b/arch/arm64/boot/dts/apple/t8012.dtsi
new file mode 100644
index 000000000000..45d24ca091b0
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012.dtsi
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple T8012 "T2" SoC
+ *
+ * Other names: H9M, "Gibraltar"
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/apple-aic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/apple.h>
+
+/ {
+	interrupt-parent = <&aic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clkref: clock-ref {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "clkref";
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 10000 {
+			compatible = "apple,hurricane-zephyr";
+			reg = <0x0 0x10000>;
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+
+		cpu1: cpu at 10001 {
+			compatible = "apple,hurricane-zephyr";
+			reg = <0x0 0x10001>;
+			cpu-release-addr = <0 0>; /* To be filled by loader */
+			enable-method = "spin-table";
+			device_type = "cpu";
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		nonposted-mmio;
+		ranges;
+
+		serial0: serial at 20a600000 {
+			compatible = "apple,s5l-uart";
+			reg = <0x2 0x0a600000 0x0 0x4000>;
+			reg-io-width = <4>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 271 IRQ_TYPE_LEVEL_HIGH>;
+			/* Use the bootloader-enabled clocks for now. */
+			clocks = <&clkref>, <&clkref>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		aic: interrupt-controller at 20e100000 {
+			compatible = "apple,t8010-aic", "apple,aic";
+			reg = <0x2 0x0e100000 0x0 0x100000>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+		};
+
+		pinctrl_ap: pinctrl at 20f100000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x0f100000 0x0 0x100000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_ap 0 0 221>;
+			apple,npins = <221>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 46 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 47 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 48 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 50 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 51 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_aop: pinctrl at 2100f0000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x0100f0000 0x0 0x10000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_aop 0 0 41>;
+			apple,npins = <41>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 131 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 132 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 133 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 134 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 135 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 136 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 137 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_nub: pinctrl at 2111f0000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x111f0000 0x0 0x1000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_nub 0 0 19>;
+			apple,npins = <19>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 164 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 165 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 166 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		wdt: watchdog at 2112b0000 {
+			compatible = "apple,t8010-wdt", "apple,wdt";
+			reg = <0x2 0x112b0000 0x0 0x4000>;
+			clocks = <&clkref>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 168 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_smc: pinctrl at 212024000 {
+			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
+			reg = <0x2 0x12024000 0x0 0x1000>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl_smc 0 0 81>;
+			apple,npins = <81>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 195 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 196 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 197 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 198 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 199 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 200 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 201 IRQ_TYPE_LEVEL_HIGH>;
+			/*
+			 * SMC is not yet supported and accessing this pinctrl while SMC is
+			 * suspended results in a hang.
+			 */
+			status = "disabled";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&aic>;
+		interrupt-names = "phys", "virt";
+		/* Note that T2 doesn't actually have a hypervisor (EL2 is not implemented). */
+		interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>,
+			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:58 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:58 +0800
Subject: [PATCH v6 08/11] arm64: dts: apple: t8010: Add PMGR nodes
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-9-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8010-7.dtsi     |   4 +
 arch/arm64/boot/dts/apple/t8010-ipad6.dtsi |   4 +
 arch/arm64/boot/dts/apple/t8010-n112.dts   |   4 +
 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi  | 772 +++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8010.dtsi       |  22 +
 5 files changed, 806 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8010-7.dtsi b/arch/arm64/boot/dts/apple/t8010-7.dtsi
index 1332fd73f50f..91fae47d25d0 100644
--- a/arch/arm64/boot/dts/apple/t8010-7.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010-7.dtsi
@@ -41,3 +41,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
index 81696c6e302c..b83fe153763e 100644
--- a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
@@ -42,3 +42,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0_fe &ps_disp0_be &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-n112.dts b/arch/arm64/boot/dts/apple/t8010-n112.dts
index 6e71c3cb5d92..48fdbedf74da 100644
--- a/arch/arm64/boot/dts/apple/t8010-n112.dts
+++ b/arch/arm64/boot/dts/apple/t8010-n112.dts
@@ -45,3 +45,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
new file mode 100644
index 000000000000..6d451088616a
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
@@ -0,0 +1,772 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8010 "A10" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80160 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80168 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_socuvd: power-controller at 80150 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "socuvd";
+	};
+
+	ps_mca0: power-controller at 80178 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80180 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80188 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80190 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80170 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_isp_sens0: power-controller at 80130 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80138 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_isp_sens2: power-controller at 80140 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens2";
+	};
+
+	ps_usb: power-controller at 80268 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80270 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80278 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80288 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp_sys: power-controller at 802d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 802e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp0_be: power-controller at 802b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_pmp: power-controller at 802f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 802f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_uart3: power-controller at 80200 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80208 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 80210 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80218 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80220 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80228 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80238 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80240 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80248 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80250 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80258 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80260 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80280 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 80290 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 80298 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_dp: power-controller at 802c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_venc_sys: power-controller at 80310 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 80318 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80320 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_vdec0: power-controller at 80300 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec0";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80328 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_dprx: power-controller at 84028 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dprx";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_pipe4: power-controller at 88000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_pipe5: power-controller at 88008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_me0: power-controller at 88010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_cpu &ps_aop_busif &ps_aop_filter>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+	};
+
+	ps_aop_cpu: power-controller at 80048 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80050 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80058 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8010.dtsi b/arch/arm64/boot/dts/apple/t8010.dtsi
index e3d6a8354103..ac1dda92f890 100644
--- a/arch/arm64/boot/dts/apple/t8010.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,t8010-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -95,6 +106,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +125,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 134 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,t8010-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -131,3 +151,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8010-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:59 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:59 +0800
Subject: [PATCH v6 09/11] arm64: dts: apple: t8011: Add PMGR nodes
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-10-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8011-common.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi   | 806 ++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8011-pro2.dtsi   |   8 +
 arch/arm64/boot/dts/apple/t8011.dtsi        |  22 +
 4 files changed, 837 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8011-common.dtsi b/arch/arm64/boot/dts/apple/t8011-common.dtsi
index 44a0d0ea2ee3..2010b56246f1 100644
--- a/arch/arm64/boot/dts/apple/t8011-common.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011-common.dtsi
@@ -22,6 +22,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0_fe &ps_disp0_be &ps_dp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t8011-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
new file mode 100644
index 000000000000..c44e3f9d7087
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
@@ -0,0 +1,806 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8011 "A10X" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu2: power-controller at 80010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu2";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80158 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80160 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80170 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80178 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80180 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80188 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80190 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 801f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80168 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb3host>;
+	};
+
+	ps_isp_sens0: power-controller at 80130 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80138 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_isp_sens2: power-controller at 80140 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens2";
+	};
+
+	ps_usb: power-controller at 80288 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80290 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host: power-controller at 80298 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2dev: power-controller at 802a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2dev";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb3host: power-controller at 802a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb3host";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb3dev: power-controller at 802b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb3dev";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_media: power-controller at 802e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp_sys: power-controller at 802e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+	};
+
+	ps_msr: power-controller at 802f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+	};
+
+	ps_disp0_be: power-controller at 802d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_dpa: power-controller at 80230 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80200 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 80208 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80210 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80218 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80220 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80238 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80240 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80248 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80250 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80258 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80260 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs4: power-controller at 80268 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs4";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs5: power-controller at 80270 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs5";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs6: power-controller at 80278 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs6";
+	};
+
+	ps_dcs7: power-controller at 80280 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs7";
+	};
+
+	ps_smx: power-controller at 802b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_dp: power-controller at 802d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_venc_sys: power-controller at 80320 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_srs: power-controller at 80390 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80390 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "srs";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pms_sram: power-controller at 80308 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_pmp: power-controller at 80300 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pcie: power-controller at 80328 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80330 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_vdec0: power-controller at 80310 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec0";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80338 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_dprx: power-controller at 84028 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dprx";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_pipe4: power-controller at 88000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_pipe5: power-controller at 88008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+		power-domains = <&ps_venc_sys>;
+	};
+
+	ps_venc_me0: power-controller at 88010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_cpu &ps_aop_filter &ps_aop_busif>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+	};
+
+	ps_aop_cpu: power-controller at 80048 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80050 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80058 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8011-pro2.dtsi b/arch/arm64/boot/dts/apple/t8011-pro2.dtsi
index f4e707415003..5eaa0a73350f 100644
--- a/arch/arm64/boot/dts/apple/t8011-pro2.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011-pro2.dtsi
@@ -40,3 +40,11 @@ button-volup {
 		};
 	};
 };
+
+&ps_dcs6 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs7 {
+	apple,always-on; /* LPDDR4 interface */
+};
diff --git a/arch/arm64/boot/dts/apple/t8011.dtsi b/arch/arm64/boot/dts/apple/t8011.dtsi
index 6c4ed9dc4a50..b845fa6f6d64 100644
--- a/arch/arm64/boot/dts/apple/t8011.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011.dtsi
@@ -69,19 +69,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,t8010-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -103,6 +114,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -121,6 +133,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 131 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,t8010-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -139,3 +159,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8011-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:50 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:50 +0800
Subject: [PATCH v6 00/11] Add PMGR nodes for Apple A7-A11, T2 SoCs
Message-ID: <20241222173750.148071-1-towinchenmi@gmail.com>

This series adds the PMGR nodes and all known power state subnodes for
Apple A7-A11 SoCs, along with the associated dt-bindings.

Dependencies:
- Split s8000/s8003 SoC DTS files
https://lore.kernel.org/asahi/20241222172735.145764-1-towinchenmi at gmail.com/T

- Device Tree for Apple T2 (T8012) devices.
https://lore.kernel.org/asahi/20241222173240.147675-1-towinchenmi at gmail.com/T

Changes since v5:
- Rebase the series such that splitting s8000/s8003 device trees is the
first patch to be applied. Now this series depends on Apple A9 device
tree being split, and the T2 SoC PMGR nodes are added in this series.

Link to v5: https://lore.kernel.org/asahi/20241203050640.109378-1-towinchenmi at gmail.com/T

Changes since v4:
- Use imperative mood in commit messages.

Link to v4: https://lore.kernel.org/asahi/20241201161942.36027-1-towinchenmi at gmail.com/T

Changes since v3:
- Add "apple,always-on" property to "ps_spmi" in t8015 power domains.
This is required for cpufreq to function correctly which will be added
in a later series.

Link to v3: https://lore.kernel.org/asahi/20241122095136.35046-1-towinchenmi at gmail.com/T

Changes since v2:
- Removed "apple,always-on" property from "ps_pmp" from s8001, t8011,
t8015 power domains. It is not on at boot. (Mixed up with ps_pms which
is required to be on)
- Add asahi-soc/dt back into the subject prefix, missing from v2.

Link to v2: https://lore.kernel.org/asahi/20241102011004.59339-1-towinchenmi at gmail.com/T

Changes since v1:
- Removed "framebuffer0" dt aliases. It is not standard and not needed.

Link to v1: https://lore.kernel.org/asahi/20241029010526.42052-1-towinchenmi at gmail.com/T

Nick Chan
---

Nick Chan (11):
  dt-bindings: arm: apple: apple,pmgr: Add A7-A11, T2 compatibles
  dt-bindings: arm: apple: apple,pmgr-pwrstate: Add A7-A11, T2
    compatibles
  arm64: dts: apple: s5l8960x: Add PMGR node
  arm64: dts: apple: t7000: Add PMGR node
  arm64: dts: apple: t7001: Add PMGR node
  arm64: dts: apple: s8000: Add PMGR nodes
  arm64: dts: apple: s8001: Add PMGR nodes
  arm64: dts: apple: t8010: Add PMGR nodes
  arm64: dts: apple: t8011: Add PMGR nodes
  arm64: dts: apple: t8012: Add PMGR nodes
  arm64: dts: apple: t8015: Add PMGR nodes

 .../bindings/arm/apple/apple,pmgr.yaml        |   5 +
 .../bindings/power/apple,pmgr-pwrstate.yaml   |   5 +
 arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi  |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi  | 610 ++++++++++++
 arch/arm64/boot/dts/apple/s5l8960x.dtsi       |  13 +
 arch/arm64/boot/dts/apple/s800-0-3-pmgr.dtsi  | 757 ++++++++++++++
 arch/arm64/boot/dts/apple/s800-0-3.dtsi       |  20 +
 arch/arm64/boot/dts/apple/s8001-common.dtsi   |   1 +
 .../arm64/boot/dts/apple/s8001-j98a-j99a.dtsi |  26 +
 arch/arm64/boot/dts/apple/s8001-j98a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-j99a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi     | 822 ++++++++++++++++
 arch/arm64/boot/dts/apple/s8001.dtsi          |  22 +
 arch/arm64/boot/dts/apple/s800x-6s.dtsi       |   4 +
 arch/arm64/boot/dts/apple/s800x-ipad5.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s800x-se.dtsi       |   4 +
 arch/arm64/boot/dts/apple/t7000-6.dtsi        |   4 +
 arch/arm64/boot/dts/apple/t7000-j42d.dts      |   1 +
 arch/arm64/boot/dts/apple/t7000-mini4.dtsi    |   4 +
 arch/arm64/boot/dts/apple/t7000-n102.dts      |   4 +
 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi     | 641 ++++++++++++
 arch/arm64/boot/dts/apple/t7000.dtsi          |  14 +
 arch/arm64/boot/dts/apple/t7001-air2.dtsi     |   1 +
 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi     | 650 ++++++++++++
 arch/arm64/boot/dts/apple/t7001.dtsi          |  13 +
 arch/arm64/boot/dts/apple/t8010-7.dtsi        |   4 +
 arch/arm64/boot/dts/apple/t8010-ipad6.dtsi    |   4 +
 arch/arm64/boot/dts/apple/t8010-n112.dts      |   4 +
 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi     | 772 +++++++++++++++
 arch/arm64/boot/dts/apple/t8010.dtsi          |  22 +
 arch/arm64/boot/dts/apple/t8011-common.dtsi   |   1 +
 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi     | 806 +++++++++++++++
 arch/arm64/boot/dts/apple/t8011-pro2.dtsi     |   8 +
 arch/arm64/boot/dts/apple/t8011.dtsi          |  22 +
 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi     | 837 ++++++++++++++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8012.dtsi          |  22 +
 arch/arm64/boot/dts/apple/t8015-common.dtsi   |   1 +
 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi     | 931 ++++++++++++++++++
 arch/arm64/boot/dts/apple/t8015.dtsi          |  21 +
 42 files changed, 7095 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s800-0-3-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8010-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8011-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi


base-commit: 9a33cbb3b1e4a0b520a131aec028ddeb99da48c3
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:51 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:51 +0800
Subject: [PATCH v6 01/11] dt-bindings: arm: apple: apple,pmgr: Add A7-A11, T2 compatibles
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-2-towinchenmi@gmail.com>

The blocks found on Apple A7-A11 SoCs are compatible with the existing
driver so add their per-SoC compatibles.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
index 673277a7a224..5001f4d5a0dc 100644
--- a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
+++ b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
@@ -22,6 +22,11 @@ properties:
   compatible:
     items:
       - enum:
+          - apple,s5l8960x-pmgr
+          - apple,t7000-pmgr
+          - apple,s8000-pmgr
+          - apple,t8010-pmgr
+          - apple,t8015-pmgr
           - apple,t8103-pmgr
           - apple,t8112-pmgr
           - apple,t6000-pmgr
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:52 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:52 +0800
Subject: [PATCH v6 02/11] dt-bindings: arm: apple: apple,pmgr-pwrstate: Add A7-A11, T2 compatibles
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-3-towinchenmi@gmail.com>

The blocks found on Apple A7-A11 SoCs are compatible with the existing
driver so add their per-SoC compatible.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 .../devicetree/bindings/power/apple,pmgr-pwrstate.yaml       | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
index 59a6af735a21..6e9a670eaf56 100644
--- a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
+++ b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
@@ -31,6 +31,11 @@ properties:
   compatible:
     items:
       - enum:
+          - apple,s5l8960x-pmgr-pwrstate
+          - apple,t7000-pmgr-pwrstate
+          - apple,s8000-pmgr-pwrstate
+          - apple,t8010-pmgr-pwrstate
+          - apple,t8015-pmgr-pwrstate
           - apple,t8103-pmgr-pwrstate
           - apple,t8112-pmgr-pwrstate
           - apple,t6000-pmgr-pwrstate
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:53 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:53 +0800
Subject: [PATCH v6 03/11] arm64: dts: apple: s5l8960x: Add PMGR node
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-4-towinchenmi@gmail.com>

Add the PMGR node and all known power state subnodes. Since there are
a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi    |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi  |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi |   4 +
 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi  | 610 ++++++++++++++++++
 arch/arm64/boot/dts/apple/s5l8960x.dtsi       |  13 +
 5 files changed, 635 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
index 0b16adf07f79..51c081923657 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
index 741c5a9f21dd..7d6e799c933a 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
index b27ef5680626..2ba846db2266 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
new file mode 100644
index 000000000000..da265f484307
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s5l8960x-pmgr.dtsi
@@ -0,0 +1,610 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple S5L8960X "A7" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 20000 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 20008 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_secuart0: power-controller at 200f0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "secuart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_secuart1: power-controller at 200f8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "secuart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_cpm: power-controller at 20010 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_lio: power-controller at 20018 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "lio";
+		apple,always-on; /* Core device */
+	};
+
+	ps_iomux: power-controller at 20020 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_aic: power-controller at 20028 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_debug: power-controller at 20030 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_dwi: power-controller at 20038 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20038 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 20040 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_mca0: power-controller at 20048 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 20050 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 20058 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 20060 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20060 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 20068 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20068 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 20070 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20070 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 20078 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20078 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 20080 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20080 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 20088 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20088 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 20090 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20090 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 20098 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20098 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 200a0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 200a8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 200b0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 200b8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 200c0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 200c8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 200d0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 200d8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 200e0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 200e8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x200e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio_p: power-controller at 20110 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+	};
+
+	ps_usb: power-controller at 20158 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 20160 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 20170 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 20180 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_disp_busmux: power-controller at 201a8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp_busmux";
+	};
+
+	ps_media: power-controller at 201d8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 201d0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+	};
+
+	ps_msr: power-controller at 201e0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 201e8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 201b0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_aes0: power-controller at 20100 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 20108 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 20118 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_hsic1_phy: power-controller at 20120 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_hsic2_phy: power-controller at 20128 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic2_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_ispsens0: power-controller at 20130 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 20138 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_mcc: power-controller at 20140 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Core device */
+	};
+
+	ps_mcu: power-controller at 20148 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcu";
+		apple,always-on; /* Core device */
+	};
+
+	ps_amp: power-controller at 20150 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "amp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb2host0_ohci: power-controller at 20168 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usb2host1_ohci: power-controller at 20178 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1_ohci";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_usbotg: power-controller at 20188 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 20190 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 20198 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_cp: power-controller at 201a0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_mipi_dsi: power-controller at 201b8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_dp: power-controller at 201c0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_disp1: power-controller at 201c8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_vdec: power-controller at 201f0 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc: power-controller at 201f8 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans: power-controller at 20200 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans";
+	};
+
+	ps_ans_dll: power-controller at 20208 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans_dll";
+		power-domains = <&ps_ans>;
+	};
+
+	ps_gfx: power-controller at 20218 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 20268 {
+		compatible = "apple,s5l8960x-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		power-domains = <&ps_secuart1>, <&ps_secuart0>;
+		apple,always-on; /* Locked on */
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x.dtsi b/arch/arm64/boot/dts/apple/s5l8960x.dtsi
index 0218ecac1d83..7705215fbdc7 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x.dtsi
@@ -62,9 +62,18 @@ serial0: serial at 20a0a0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s5l8960x-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x24000>;
+		};
+
 		wdt: watchdog at 20e027000 {
 			compatible = "apple,s5l8960x-wdt", "apple,wdt";
 			reg = <0x2 0x0e027000 0x0 0x1000>;
@@ -78,11 +87,13 @@ aic: interrupt-controller at 20e100000 {
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl: pinctrl at 20e300000 {
 			compatible = "apple,s5l8960x-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0e300000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -111,3 +122,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "s5l8960x-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:54 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:54 +0800
Subject: [PATCH v6 04/11] arm64: dts: apple: t7000: Add PMGR node
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-5-towinchenmi@gmail.com>

Add the PMGR node and all known power state subnodes. Since there are
a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t7000-6.dtsi     |   4 +
 arch/arm64/boot/dts/apple/t7000-j42d.dts   |   1 +
 arch/arm64/boot/dts/apple/t7000-mini4.dtsi |   4 +
 arch/arm64/boot/dts/apple/t7000-n102.dts   |   4 +
 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi  | 641 +++++++++++++++++++++
 arch/arm64/boot/dts/apple/t7000.dtsi       |  14 +
 6 files changed, 668 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t7000-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t7000-6.dtsi b/arch/arm64/boot/dts/apple/t7000-6.dtsi
index f60ea4a4a387..77d74d6af1c4 100644
--- a/arch/arm64/boot/dts/apple/t7000-6.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000-6.dtsi
@@ -48,3 +48,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-j42d.dts b/arch/arm64/boot/dts/apple/t7000-j42d.dts
index 2231db6a739d..4de5e6a3f230 100644
--- a/arch/arm64/boot/dts/apple/t7000-j42d.dts
+++ b/arch/arm64/boot/dts/apple/t7000-j42d.dts
@@ -20,6 +20,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0 &ps_dp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
index c64ddc402fda..e5a9656045f2 100644
--- a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-n102.dts b/arch/arm64/boot/dts/apple/t7000-n102.dts
index 9c55d339ba4e..99eb8a2b8c73 100644
--- a/arch/arm64/boot/dts/apple/t7000-n102.dts
+++ b/arch/arm64/boot/dts/apple/t7000-n102.dts
@@ -46,3 +46,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-pmgr.dtsi b/arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
new file mode 100644
index 000000000000..5948fa7afffc
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t7000-pmgr.dtsi
@@ -0,0 +1,641 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T7000 "A8" SoC
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+&pmgr {
+	ps_cpu0: power-controller at 20000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 20008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 20040 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_p: power-controller at 201f8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+	};
+
+	ps_lio: power-controller at 20100 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "lio";
+		apple,always-on; /* Core device */
+	};
+
+	ps_iomux: power-controller at 20108 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_aic: power-controller at 20110 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_debug: power-controller at 20118 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_dwi: power-controller at 20120 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 20128 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_mca0: power-controller at 20130 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 20138 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 20140 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 20148 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 20150 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 20158 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 20160 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 20168 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 20170 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 20178 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 20180 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 20188 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 20190 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 20198 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 201a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 201a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 201b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 201b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 201c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 201c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 201d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 201d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 201e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 201e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 201f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb: power-controller at 20248 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 20250 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 20258 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 20268 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 20278 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_disp_busmux: power-controller at 202a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp_busmux";
+	};
+
+	ps_media: power-controller at 202d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 202d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+	};
+
+	ps_msr: power-controller at 202e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 202e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 202b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_disp1: power-controller at 202c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_pcie_ref: power-controller at 20220 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_hsic0_phy: power-controller at 20200 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_hsic1_phy: power-controller at 20208 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_ispsens0: power-controller at 20210 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 20218 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_mcc: power-controller at 20230 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_mcu: power-controller at 20238 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcu";
+		apple,always-on; /* Core device */
+	};
+
+	ps_amp: power-controller at 20240 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "amp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb2host0_ohci: power-controller at 20260 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 20288 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 20290 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple Fabric, critical block */
+	};
+
+	ps_sf: power-controller at 20298 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple Fabric, critical block */
+	};
+
+	ps_cp: power-controller at 202a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_mipi_dsi: power-controller at 202b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_dp: power-controller at 202c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_vdec: power-controller at 202f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans: power-controller at 20318 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans";
+	};
+
+	ps_venc: power-controller at 20300 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 20308 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 20310 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_gfx: power-controller at 20320 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 20400 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_venc_pipe: power-controller at 21000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 21008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me1: power-controller at 21010 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+		power-domains = <&ps_venc>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t7000.dtsi b/arch/arm64/boot/dts/apple/t7000.dtsi
index a7cc29e84c84..ed1e9a62ba05 100644
--- a/arch/arm64/boot/dts/apple/t7000.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000.dtsi
@@ -62,6 +62,7 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
@@ -74,9 +75,18 @@ serial6: serial at 20a0d8000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart6>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t7000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x24000>;
+		};
+
 		wdt: watchdog at 20e027000 {
 			compatible = "apple,t7000-wdt", "apple,wdt";
 			reg = <0x2 0x0e027000 0x0 0x1000>;
@@ -90,11 +100,13 @@ aic: interrupt-controller at 20e100000 {
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl: pinctrl at 20e300000 {
 			compatible = "apple,t7000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0e300000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -123,3 +135,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t7000-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:55 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:55 +0800
Subject: [PATCH v6 05/11] arm64: dts: apple: t7001: Add PMGR node
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-6-towinchenmi@gmail.com>

Add the PMGR node and all known power state subnodes. Since there are
a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t7001-air2.dtsi |   1 +
 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi | 650 ++++++++++++++++++++++
 arch/arm64/boot/dts/apple/t7001.dtsi      |  13 +
 3 files changed, 664 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t7001-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t7001-air2.dtsi b/arch/arm64/boot/dts/apple/t7001-air2.dtsi
index 19fabd425c52..e4ec8c1977de 100644
--- a/arch/arm64/boot/dts/apple/t7001-air2.dtsi
+++ b/arch/arm64/boot/dts/apple/t7001-air2.dtsi
@@ -20,6 +20,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0 &ps_dp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t7001-pmgr.dtsi b/arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
new file mode 100644
index 000000000000..7321cfdcd189
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t7001-pmgr.dtsi
@@ -0,0 +1,650 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T7001 "A8X" SoC
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 20000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 20008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu2: power-controller at 20010 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu2";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 20040 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_p: power-controller at 201f8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+	};
+
+	ps_lio: power-controller at 20100 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "lio";
+		apple,always-on; /* Core device */
+	};
+
+	ps_iomux: power-controller at 20108 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_aic: power-controller at 20110 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_debug: power-controller at 20118 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_dwi: power-controller at 20120 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 20128 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_mca0: power-controller at 20130 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 20138 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 20140 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 20148 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 20150 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 20158 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 20160 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 20168 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 20170 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 20178 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 20180 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 20188 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 20190 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 20198 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 201a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 201a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 201b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 201b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 201c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 201c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 201d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 201d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 201e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 201e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 201f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x201f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb: power-controller at 20248 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 20250 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 20258 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 20268 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 20278 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_disp_busmux: power-controller at 202a8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp_busmux";
+	};
+
+	ps_disp1_busmux: power-controller at 202c0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1_busmux";
+	};
+
+	ps_media: power-controller at 202d8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 202d0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+	};
+
+	ps_msr: power-controller at 202e0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 202e8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 202b0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_disp_busmux>;
+	};
+
+	ps_disp1: power-controller at 202c8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp1_busmux>;
+	};
+
+	ps_pcie_ref: power-controller at 20220 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_hsic0_phy: power-controller at 20200 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_hsic1_phy: power-controller at 20208 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_ispsens0: power-controller at 20210 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 20218 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_mcc: power-controller at 20230 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_mcu: power-controller at 20238 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcu";
+		apple,always-on; /* Core device */
+	};
+
+	ps_amp: power-controller at 20240 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "amp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb2host0_ohci: power-controller at 20260 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 20288 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 20290 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 20298 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_cp: power-controller at 202a0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cp";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dp: power-controller at 202b8 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_vdec: power-controller at 202f0 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x202f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans: power-controller at 20318 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans";
+	};
+
+	ps_venc: power-controller at 20300 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 20308 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 20310 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_gfx: power-controller at 20320 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 20400 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x20400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_venc_pipe: power-controller at 21000 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 21008 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me1: power-controller at 21010 {
+		compatible = "apple,t7000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x21010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+		power-domains = <&ps_venc>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t7001.dtsi b/arch/arm64/boot/dts/apple/t7001.dtsi
index a76e034c85e3..c471f57cca0e 100644
--- a/arch/arm64/boot/dts/apple/t7001.dtsi
+++ b/arch/arm64/boot/dts/apple/t7001.dtsi
@@ -72,9 +72,18 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t7000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x24000>;
+		};
+
 		wdt: watchdog at 20e027000 {
 			compatible = "apple,t7000-wdt", "apple,wdt";
 			reg = <0x2 0x0e027000 0x0 0x1000>;
@@ -88,11 +97,13 @@ aic: interrupt-controller at 20e100000 {
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl: pinctrl at 20e300000 {
 			compatible = "apple,t7000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0e300000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -121,3 +132,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t7001-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:56 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:56 +0800
Subject: [PATCH v6 06/11] arm64: dts: apple: s8000: Add PMGR nodes
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-7-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s800-0-3-pmgr.dtsi | 757 +++++++++++++++++++
 arch/arm64/boot/dts/apple/s800-0-3.dtsi      |  20 +
 arch/arm64/boot/dts/apple/s800x-6s.dtsi      |   4 +
 arch/arm64/boot/dts/apple/s800x-ipad5.dtsi   |   4 +
 arch/arm64/boot/dts/apple/s800x-se.dtsi      |   4 +
 5 files changed, 789 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s800-0-3-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/s800-0-3-pmgr.dtsi b/arch/arm64/boot/dts/apple/s800-0-3-pmgr.dtsi
new file mode 100644
index 000000000000..196b8e745a95
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s800-0-3-pmgr.dtsi
@@ -0,0 +1,757 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple S8000/3 "A9" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80150 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80158 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80168 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80170 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80178 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80180 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80188 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 80190 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 80198 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801a0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801b0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 801f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 801f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80160 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_hsic1_phy: power-controller at 80130 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic1_phy";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_isp_sens0: power-controller at 80138 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80140 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_usb: power-controller at 80250 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80258 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80260 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80270 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 80280 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 802c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 802e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0: power-controller at 802b0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_pmp: power-controller at 802e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 802f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_uart5: power-controller at 80200 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80208 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80210 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80218 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 80220 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80228 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80230 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80238 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80240 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80248 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80268 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usb2host1_ohci: power-controller at 80278 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1_ohci";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_usb2host2_ohci: power-controller at 80288 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2_ohci";
+		power-domains = <&ps_usb2host2>;
+	};
+
+	ps_usbotg: power-controller at 80290 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 80298 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_dp: power-controller at 802c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_vdec: power-controller at 802f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc: power-controller at 80308 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 80310 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80318 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_pcie_link0: power-controller at 80320 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link0";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link1: power-controller at 80328 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link1";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link2: power-controller at 80330 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link2";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link3: power-controller at 80338 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link3";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_gfx: power-controller at 80340 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80340 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_venc_pipe: power-controller at 88000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 88008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_busif &ps_aop_cpu &ps_aop_filter>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+		power-domains = <&ps_aop>;
+	};
+
+	ps_aop_cpu: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80048 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80050 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s800-0-3.dtsi b/arch/arm64/boot/dts/apple/s800-0-3.dtsi
index 082e5b1733d0..234259e5d658 100644
--- a/arch/arm64/boot/dts/apple/s800-0-3.dtsi
+++ b/arch/arm64/boot/dts/apple/s800-0-3.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,s8000-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -95,6 +106,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +125,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 119 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,s8000-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
diff --git a/arch/arm64/boot/dts/apple/s800x-6s.dtsi b/arch/arm64/boot/dts/apple/s800x-6s.dtsi
index 49b04db310c6..1dcf80cc2920 100644
--- a/arch/arm64/boot/dts/apple/s800x-6s.dtsi
+++ b/arch/arm64/boot/dts/apple/s800x-6s.dtsi
@@ -47,3 +47,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
diff --git a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi
index 32570ed3cdf0..c1701e81f0c1 100644
--- a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi
+++ b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi
@@ -41,3 +41,7 @@ button-volup {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_dp>;
+};
diff --git a/arch/arm64/boot/dts/apple/s800x-se.dtsi b/arch/arm64/boot/dts/apple/s800x-se.dtsi
index a1a5690e8371..deb7c7cc90f6 100644
--- a/arch/arm64/boot/dts/apple/s800x-se.dtsi
+++ b/arch/arm64/boot/dts/apple/s800x-se.dtsi
@@ -47,3 +47,7 @@ switch-mute {
 		};
 	};
 };
+
+&framebuffer0 {
+	power-domains = <&ps_disp0 &ps_mipi_dsi>;
+};
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:34:57 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:34:57 +0800
Subject: [PATCH v6 07/11] arm64: dts: apple: s8001: Add PMGR nodes
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-8-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s8001-common.dtsi   |   1 +
 .../arm64/boot/dts/apple/s8001-j98a-j99a.dtsi |  26 +
 arch/arm64/boot/dts/apple/s8001-j98a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-j99a.dts      |   1 +
 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi     | 822 ++++++++++++++++++
 arch/arm64/boot/dts/apple/s8001.dtsi          |  22 +
 6 files changed, 873 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s8001-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/s8001-common.dtsi b/arch/arm64/boot/dts/apple/s8001-common.dtsi
index e94d0e77653a..91b06e113894 100644
--- a/arch/arm64/boot/dts/apple/s8001-common.dtsi
+++ b/arch/arm64/boot/dts/apple/s8001-common.dtsi
@@ -24,6 +24,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0 &ps_dp0>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi b/arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
new file mode 100644
index 000000000000..e66a4c1c138f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s8001-j98a-j99a.dtsi
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Apple iPad Pro (12.9-inch)
+ *
+ * This file contains parts common to iPad Pro (12.9-inch).
+ *
+ * target-type: J98a, J99a
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+&ps_dcs4 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs5 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs6 {
+	apple,always-on; /* LPDDR4 interface */
+};
+
+&ps_dcs7 {
+	apple,always-on; /* LPDDR4 interface */
+};
diff --git a/arch/arm64/boot/dts/apple/s8001-j98a.dts b/arch/arm64/boot/dts/apple/s8001-j98a.dts
index 6d6b841e7ab0..162eca05c2d9 100644
--- a/arch/arm64/boot/dts/apple/s8001-j98a.dts
+++ b/arch/arm64/boot/dts/apple/s8001-j98a.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s8001-pro.dtsi"
+#include "s8001-j98a-j99a.dtsi"
 
 / {
 	compatible = "apple,j98a", "apple,s8001", "apple,arm-platform";
diff --git a/arch/arm64/boot/dts/apple/s8001-j99a.dts b/arch/arm64/boot/dts/apple/s8001-j99a.dts
index d20194b1cae7..7b765820c69e 100644
--- a/arch/arm64/boot/dts/apple/s8001-j99a.dts
+++ b/arch/arm64/boot/dts/apple/s8001-j99a.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "s8001-pro.dtsi"
+#include "s8001-j98a-j99a.dtsi"
 
 / {
 	compatible = "apple,j99a", "apple,s8001", "apple,arm-platform";
diff --git a/arch/arm64/boot/dts/apple/s8001-pmgr.dtsi b/arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
new file mode 100644
index 000000000000..859ab77ae92b
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s8001-pmgr.dtsi
@@ -0,0 +1,822 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple S8001 "A9X" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80148 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80150 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pcie_ref: power-controller at 80140 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80160 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80168 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80170 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80178 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80180 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 80188 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 80190 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 80198 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801a0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801b0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 801e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 801f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 801f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80158 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsic0_phy: power-controller at 80128 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsic0_phy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_isp_sens0: power-controller at 80130 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80138 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_usb: power-controller at 80278 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80280 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80288 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80298 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host2: power-controller at 802a8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host2";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802d0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+		apple,always-on; /* Core device */
+	};
+
+	ps_disp1mux: power-controller at 802e8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1mux";
+	};
+
+	ps_disp0: power-controller at 802d8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp1: power-controller at 802f0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp1";
+		power-domains = <&ps_disp1mux>;
+	};
+
+	ps_uart6: power-controller at 80200 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80208 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80210 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_aes0: power-controller at 80218 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aes0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80230 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80238 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80240 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80248 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80250 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs4: power-controller at 80258 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs4";
+	};
+
+	ps_dcs5: power-controller at 80260 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs5";
+	};
+
+	ps_dcs6: power-controller at 80268 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs6";
+	};
+
+	ps_dcs7: power-controller at 80270 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs7";
+	};
+
+	ps_usb2host0_ohci: power-controller at 80290 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 802b8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 802c0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802c8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_dp0: power-controller at 802e0 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp0";
+		power-domains = <&ps_disp0>;
+	};
+
+	ps_dp1: power-controller at 802f8 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp1";
+		power-domains = <&ps_disp1>;
+	};
+
+	ps_dpa0: power-controller at 80220 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa0";
+	};
+
+	ps_dpa1: power-controller at 80228 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa1";
+	};
+
+	ps_media: power-controller at 80308 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp: power-controller at 80300 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 80318 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 80310 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc: power-controller at 80340 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80340 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie: power-controller at 80348 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80348 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_srs: power-controller at 80390 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80390 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "srs";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pcie_aux: power-controller at 80350 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80350 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_pcie_link0: power-controller at 80358 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80358 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link0";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link1: power-controller at 80360 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80360 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link1";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link2: power-controller at 80368 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80368 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link2";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link3: power-controller at 80370 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80370 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link3";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link4: power-controller at 80378 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80378 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link4";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_pcie_link5: power-controller at 80380 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80380 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_link5";
+		power-domains = <&ps_pcie>;
+	};
+
+	ps_vdec: power-controller at 80330 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80388 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80388 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_pmp: power-controller at 80320 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 80328 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on*/
+	};
+
+	ps_venc_pipe: power-controller at 88000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe";
+		power-domains = <&ps_venc>;
+	};
+
+	ps_venc_me0: power-controller at 88008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop: power-controller at 80000 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop";
+		power-domains = <&ps_aop_cpu &ps_aop_filter &ps_aop_busif>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80008 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_gpio: power-controller at 80010 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_gpio";
+	};
+
+	ps_aop_cpu: power-controller at 80040 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80048 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80048 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_aop_busif: power-controller at 80050 {
+		compatible = "apple,s8000-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_busif";
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s8001.dtsi b/arch/arm64/boot/dts/apple/s8001.dtsi
index 23ee3238844d..3963c6d8ca5e 100644
--- a/arch/arm64/boot/dts/apple/s8001.dtsi
+++ b/arch/arm64/boot/dts/apple/s8001.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a0c0000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,s8000-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -95,6 +106,7 @@ pinctrl_ap: pinctrl at 20f100000 {
 		pinctrl_aop: pinctrl at 2100f0000 {
 			compatible = "apple,s8000-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x100f0000 0x0 0x100000>;
+			power-domains = <&ps_aop_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +125,14 @@ pinctrl_aop: pinctrl at 2100f0000 {
 				     <AIC_IRQ 134 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 210200000 {
+			compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x10200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2102b0000 {
 			compatible = "apple,s8000-wdt", "apple,wdt";
 			reg = <0x2 0x102b0000 0x0 0x4000>;
@@ -131,3 +151,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "s8001-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:35:00 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:35:00 +0800
Subject: [PATCH v6 10/11] arm64: dts: apple: t8012: Add PMGR nodes
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-11-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

On models with only 1 GB of memory, only two memory channels are used,
and on models with 2 GB of memory, four memory channels are used. The
"apple,always-on" property of the extra memory channel power domains
(ps_dcs2, ps_dcs3) will be removed by loader on models with 1 GB of
memory.

The amount of memory depends on the storage configuration of the Mac.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi     | 837 ++++++++++++++++++
 arch/arm64/boot/dts/apple/t8012-touchbar.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8012.dtsi          |  22 +
 3 files changed, 860 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8012-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8012-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8012-pmgr.dtsi
new file mode 100644
index 000000000000..35a462edd4af
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8012-pmgr.dtsi
@@ -0,0 +1,837 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8012 "T2" SoC
+ *
+ * Copyright (c) 2024 Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80158 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80160 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_iomux: power-controller at 80150 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80150 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "iomux";
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_gpio: power-controller at 80110 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pcie_down_ref: power-controller at 80138 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_down_ref";
+	};
+
+	ps_pcie_stg0_ref: power-controller at 80140 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg0_ref";
+	};
+
+	ps_pcie_stg1_ref: power-controller at 80148 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg1_ref";
+	};
+
+	ps_mca0: power-controller at 80170 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80178 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80180 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80188 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80190 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca5: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801c0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80168 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_isp_sens0: power-controller at 80120 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens0";
+	};
+
+	ps_isp_sens1: power-controller at 80128 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens1";
+	};
+
+	ps_isp_sens2: power-controller at 80130 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sens2";
+	};
+
+	ps_pms: power-controller at 80118 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_i2c4: power-controller at 801c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c5: power-controller at 801d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c6: power-controller at 801d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_usb: power-controller at 80268 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctrl: power-controller at 80270 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctrl";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80278 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_usb2host1: power-controller at 80288 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_rtmux: power-controller at 802a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802d8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_isp_sys: power-controller at 802d0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 802e8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_jpg: power-controller at 802e0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802b0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp0_be: power-controller at 802b8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_uart0: power-controller at 80200 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 80208 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 80210 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart3: power-controller at 80218 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80220 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_dpa: power-controller at 80228 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80230 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80240 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80240 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80248 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs1: power-controller at 80250 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs2: power-controller at 80258 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		/* Not used on some devicecs, to be disabled by loader */
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_dcs3: power-controller at 80260 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		/* Not used on some devicecs, to be disabled by loader */
+		apple,always-on; /* LPDDR4 interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80280 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usbotg: power-controller at 80290 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbotg";
+		power-domains = <&ps_usbctrl>;
+	};
+
+	ps_smx: power-controller at 80298 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802c8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_pmp: power-controller at 802f0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 802f8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_pcie_up_af: power-controller at 80320 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_up_af";
+		power-domains = <&ps_iomux>;
+	};
+
+	ps_pcie_up: power-controller at 80328 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_up";
+		power-domains = <&ps_pcie_up_af>;
+	};
+
+	ps_venc_sys: power-controller at 80300 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_ans2: power-controller at 80308 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans2";
+		power-domains = <&ps_iomux>;
+	};
+
+	ps_pcie_down: power-controller at 80310 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_down";
+		power-domains = <&ps_iomux>;
+	};
+
+	ps_pcie_down_aux: power-controller at 80318 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_down_aux";
+	};
+
+	ps_pcie_up_aux: power-controller at 80330 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_up_aux";
+		power-domains = <&ps_pcie_up>;
+	};
+
+	ps_pcie_stg0: power-controller at 80338 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg0";
+		power-domains = <&ps_ans2>;
+	};
+
+	ps_pcie_stg0_aux: power-controller at 80340 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80340 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg0_aux";
+	};
+
+	ps_pcie_stg1: power-controller at 80348 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80348 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg1";
+		power-domains = <&ps_ans2>;
+	};
+
+	ps_pcie_stg1_aux: power-controller at 80350 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80350 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_stg1_aux";
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_pipe4: power-controller at 88000 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+	};
+
+	ps_venc_pipe5: power-controller at 88008 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+	};
+
+	ps_venc_me0: power-controller at 88010 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88018 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_spmi: power-controller at 80058 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spmi";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_nub_aon: power-controller at 80060 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80060 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "nub_aon";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_smc_fabric: power-controller at 80030 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_fabric";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_smc_aon: power-controller at 80088 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80088 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_aon";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_debug: power-controller at 80050 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_nub_sram: power-controller at 801a0 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "nub_sram";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_nub_fabric: power-controller at 80198 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "nub_fabric";
+		apple,always-on; /* Core AON device */
+	};
+
+	ps_smc_cpu: power-controller at 801a8 {
+		compatible = "apple,t8010-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_cpu";
+		power-domains = <&ps_smc_fabric &ps_smc_aon>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
index f4a8b12437f0..fc4a80d0c787 100644
--- a/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
+++ b/arch/arm64/boot/dts/apple/t8012-touchbar.dtsi
@@ -12,6 +12,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t8012.dtsi b/arch/arm64/boot/dts/apple/t8012.dtsi
index 45d24ca091b0..907ba127be79 100644
--- a/arch/arm64/boot/dts/apple/t8012.dtsi
+++ b/arch/arm64/boot/dts/apple/t8012.dtsi
@@ -61,19 +61,30 @@ serial0: serial at 20a600000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
+		pmgr: power-management at 20e000000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0xe000000 0 0x8c000>;
+		};
+
 		aic: interrupt-controller at 20e100000 {
 			compatible = "apple,t8010-aic", "apple,aic";
 			reg = <0x2 0x0e100000 0x0 0x100000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
 		};
 
 		pinctrl_ap: pinctrl at 20f100000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x0f100000 0x0 0x100000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -130,6 +141,14 @@ pinctrl_nub: pinctrl at 2111f0000 {
 				     <AIC_IRQ 166 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 211200000 {
+			compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x11200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2112b0000 {
 			compatible = "apple,t8010-wdt", "apple,wdt";
 			reg = <0x2 0x112b0000 0x0 0x4000>;
@@ -141,6 +160,7 @@ wdt: watchdog at 2112b0000 {
 		pinctrl_smc: pinctrl at 212024000 {
 			compatible = "apple,t8010-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x12024000 0x0 0x1000>;
+			power-domains = <&ps_smc_cpu>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -174,3 +194,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8012-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:35:01 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:35:01 +0800
Subject: [PATCH v6 11/11] arm64: dts: apple: t8015: Add PMGR nodes
In-Reply-To: <20241222173750.148071-1-towinchenmi@gmail.com>
References: <20241222173750.148071-1-towinchenmi@gmail.com>
Message-ID: <20241222173750.148071-12-towinchenmi@gmail.com>

Add the two PMGR nodes and all known power state subnodes. Since there
are a large number of them, put them in a separate file to include.

Acked-by: Hector Martin <marcan at marcan.st>
Acked-by: Neal Gompa <neal at gompa.dev>
Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8015-common.dtsi |   1 +
 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi   | 931 ++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8015.dtsi        |  21 +
 3 files changed, 953 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/t8015-pmgr.dtsi

diff --git a/arch/arm64/boot/dts/apple/t8015-common.dtsi b/arch/arm64/boot/dts/apple/t8015-common.dtsi
index 69258a33ea50..498f58fb9715 100644
--- a/arch/arm64/boot/dts/apple/t8015-common.dtsi
+++ b/arch/arm64/boot/dts/apple/t8015-common.dtsi
@@ -24,6 +24,7 @@ chosen {
 		framebuffer0: framebuffer at 0 {
 			compatible = "apple,simple-framebuffer", "simple-framebuffer";
 			reg = <0 0 0 0>; /* To be filled by loader */
+			power-domains = <&ps_disp0_be &ps_mipi_dsi &ps_disp0_hilo &ps_disp0_ppp>;
 			/* Format properties will be added by loader */
 			status = "disabled";
 		};
diff --git a/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi
new file mode 100644
index 000000000000..e238c2d2732f
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi
@@ -0,0 +1,931 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * PMGR Power domains for the Apple T8015 "A11" SoC
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+&pmgr {
+	ps_cpu0: power-controller at 80000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu0";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu1: power-controller at 80008 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu1";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu2: power-controller at 80010 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu2";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu3: power-controller at 80018 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu3";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu4: power-controller at 80020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu4";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpu5: power-controller at 80028 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpu5";
+		apple,always-on; /* Core device */
+	};
+
+	ps_cpm: power-controller at 80040 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80040 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "cpm";
+		apple,always-on; /* Core device */
+	};
+
+	ps_sio_busif: power-controller at 80158 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80158 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_busif";
+	};
+
+	ps_sio_p: power-controller at 80160 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80160 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio_p";
+		power-domains = <&ps_sio_busif>;
+	};
+
+	ps_sbr: power-controller at 80100 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80100 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sbr";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_aic: power-controller at 80108 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80108 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aic";
+		apple,always-on; /* Core device */
+	};
+
+	ps_dwi: power-controller at 80110 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80110 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dwi";
+	};
+
+	ps_gpio: power-controller at 80118 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80118 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gpio";
+	};
+
+	ps_pms: power-controller at 80120 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80120 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms";
+		apple,always-on; /* Core device */
+	};
+
+	ps_pcie_ref: power-controller at 80148 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80148 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_ref";
+	};
+
+	ps_mca0: power-controller at 80170 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80170 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca1: power-controller at 80178 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80178 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca2: power-controller at 80180 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80180 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca3: power-controller at 80188 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80188 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mca4: power-controller at 80190 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80190 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_pwm0: power-controller at 801a0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pwm0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c0: power-controller at 801a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c1: power-controller at 801b0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c2: power-controller at 801b8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_i2c3: power-controller at 801c0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "i2c3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi0: power-controller at 801c8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi1: power-controller at 801d0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi2: power-controller at 801d8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_spi3: power-controller at 801e0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spi3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart0: power-controller at 801e8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801e8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart1: power-controller at 801f0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart1";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart2: power-controller at 801f8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x801f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart2";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_sio: power-controller at 80168 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80168 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sio";
+		power-domains = <&ps_sio_p>;
+		apple,always-on; /* Core device */
+	};
+
+	ps_hsicphy: power-controller at 80128 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80128 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hsicphy";
+		power-domains = <&ps_usb2host1>;
+	};
+
+	ps_ispsens0: power-controller at 80130 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80130 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens0";
+	};
+
+	ps_ispsens1: power-controller at 80138 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80138 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens1";
+	};
+
+	ps_ispsens2: power-controller at 80140 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ispsens2";
+	};
+
+	ps_mca5: power-controller at 80198 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80198 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mca5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_usb: power-controller at 80270 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80270 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb";
+	};
+
+	ps_usbctlreg: power-controller at 80278 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80278 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usbctlreg";
+		power-domains = <&ps_usb>;
+	};
+
+	ps_usb2host0: power-controller at 80280 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80280 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0";
+		power-domains = <&ps_usbctlreg>;
+	};
+
+	ps_usb2host1: power-controller at 80290 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80290 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host1";
+		power-domains = <&ps_usbctlreg>;
+	};
+
+	ps_rtmux: power-controller at 802b0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "rtmux";
+	};
+
+	ps_media: power-controller at 802f0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "media";
+	};
+
+	ps_jpg: power-controller at 802f8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802f8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "jpg";
+		power-domains = <&ps_media>;
+	};
+
+	ps_disp0_fe: power-controller at 802b8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802b8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_fe";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_disp0_be: power-controller at 802c0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be";
+		power-domains = <&ps_disp0_fe>;
+	};
+
+	ps_disp0_gp: power-controller at 802c8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802c8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_gp";
+		power-domains = <&ps_disp0_be>;
+		status = "disabled";
+	};
+
+	ps_uart3: power-controller at 80200 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80200 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart3";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart4: power-controller at 80208 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80208 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart4";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart5: power-controller at 80210 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80210 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart5";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart6: power-controller at 80218 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80218 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart6";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart7: power-controller at 80220 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80220 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart7";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_uart8: power-controller at 80228 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80228 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "uart8";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_hfd0: power-controller at 80238 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80238 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "hfd0";
+		power-domains = <&ps_sio_p>;
+	};
+
+	ps_mcc: power-controller at 80248 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80248 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mcc";
+		apple,always-on; /* Memory cache controller */
+	};
+
+	ps_dcs0: power-controller at 80250 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80250 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs0";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_dcs1: power-controller at 80258 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80258 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs1";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_dcs2: power-controller at 80260 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80260 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs2";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_dcs3: power-controller at 80268 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80268 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dcs3";
+		apple,always-on; /* LPDDR4X interface */
+	};
+
+	ps_usb2host0_ohci: power-controller at 80288 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80288 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2host0_ohci";
+		power-domains = <&ps_usb2host0>;
+	};
+
+	ps_usb2dev: power-controller at 80298 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80298 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "usb2dev";
+		power-domains = <&ps_usbctlreg>;
+	};
+
+	ps_smx: power-controller at 802a0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smx";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_sf: power-controller at 802a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sf";
+		apple,always-on; /* Apple fabric, critical block */
+	};
+
+	ps_mipi_dsi: power-controller at 802d8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "mipi_dsi";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_dp: power-controller at 802e0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802e0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dp";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_dpa: power-controller at 80230 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80230 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dpa";
+	};
+
+	ps_disp0_be_2x: power-controller at 802d0 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x802d0 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_be_2x";
+		power-domains = <&ps_disp0_be>;
+	};
+
+	ps_isp_sys: power-controller at 80350 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80350 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_sys";
+		power-domains = <&ps_rtmux>;
+	};
+
+	ps_msr: power-controller at 80300 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80300 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "msr";
+		power-domains = <&ps_media>;
+	};
+
+	ps_venc_sys: power-controller at 80398 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80398 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_pmp: power-controller at 80308 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80308 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pmp";
+	};
+
+	ps_pms_sram: power-controller at 80310 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80310 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pms_sram";
+	};
+
+	ps_pcie: power-controller at 80318 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80318 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie";
+	};
+
+	ps_pcie_aux: power-controller at 80320 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80320 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_aux";
+	};
+
+	ps_vdec0: power-controller at 80388 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80388 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "vdec0";
+		power-domains = <&ps_media>;
+	};
+
+	ps_gfx: power-controller at 80338 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80338 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "gfx";
+	};
+
+	ps_ans2: power-controller at 80328 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80328 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "ans2";
+		apple,always-on;
+	};
+
+	ps_pcie_direct: power-controller at 80330 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80330 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "pcie_direct";
+		apple,always-on;
+	};
+
+	ps_avd_sys: power-controller at 803a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x803a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "avd_sys";
+		power-domains = <&ps_media>;
+	};
+
+	ps_sep: power-controller at 80400 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80400 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "sep";
+		apple,always-on; /* Locked on */
+	};
+
+	ps_disp0_gp0: power-controller at 80830 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80830 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_gp0";
+		power-domains = <&ps_disp0_gp>;
+		status = "disabled";
+	};
+
+	ps_disp0_gp1: power-controller at 80838 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80838 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_gp1";
+		status = "disabled";
+	};
+
+	ps_disp0_ppp: power-controller at 80840 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80840 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_ppp";
+	};
+
+	ps_disp0_hilo: power-controller at 80848 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80848 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "disp0_hilo";
+	};
+
+	ps_isp_rsts0: power-controller at 84000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts0";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_rsts1: power-controller at 84008 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_rsts1";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_vis: power-controller at 84010 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_vis";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_be: power-controller at 84018 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_be";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_pearl: power-controller at 84020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_pearl";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_dprx: power-controller at 84028 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "dprx";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_isp_cnv: power-controller at 84030 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x84030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "isp_cnv";
+		power-domains = <&ps_isp_sys>;
+	};
+
+	ps_venc_dma: power-controller at 88000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_dma";
+	};
+
+	ps_venc_pipe4: power-controller at 88010 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88010 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe4";
+	};
+
+	ps_venc_pipe5: power-controller at 88018 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88018 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_pipe5";
+	};
+
+	ps_venc_me0: power-controller at 88020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me0";
+	};
+
+	ps_venc_me1: power-controller at 88028 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x88028 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "venc_me1";
+	};
+};
+
+&pmgr_mini {
+	ps_aop_base: power-controller at 80008 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80008 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_base";
+		power-domains = <&ps_aop_cpu &ps_aop_filter>;
+		apple,always-on; /* Always on processor */
+	};
+
+	ps_debug: power-controller at 80050 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80050 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "debug";
+	};
+
+	ps_aop_cpu: power-controller at 80020 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80020 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_cpu";
+	};
+
+	ps_aop_filter: power-controller at 80000 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80000 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "aop_filter";
+	};
+
+	ps_spmi: power-controller at 80058 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80058 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "spmi";
+		apple,always-on; /* System Power Management Interface */
+	};
+
+	ps_smc_i2cm1: power-controller at 800a8 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x800a8 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_i2cm1";
+	};
+
+	ps_smc_fabric: power-controller at 80030 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80030 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_fabric";
+	};
+
+	ps_smc_cpu: power-controller at 80140 {
+		compatible = "apple,t8015-pmgr-pwrstate", "apple,pmgr-pwrstate";
+		reg = <0x80140 4>;
+		#power-domain-cells = <0>;
+		#reset-cells = <0>;
+		label = "smc_cpu";
+		power-domains = <&ps_smc_fabric &ps_smc_i2cm1>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/t8015.dtsi b/arch/arm64/boot/dts/apple/t8015.dtsi
index 8828d830e5be..fbff3a6c0ba4 100644
--- a/arch/arm64/boot/dts/apple/t8015.dtsi
+++ b/arch/arm64/boot/dts/apple/t8015.dtsi
@@ -119,6 +119,7 @@ serial0: serial at 22e600000 {
 			/* Use the bootloader-enabled clocks for now. */
 			clocks = <&clkref>, <&clkref>;
 			clock-names = "uart", "clk_uart_baud0";
+			power-domains = <&ps_uart0>;
 			status = "disabled";
 		};
 
@@ -127,11 +128,21 @@ aic: interrupt-controller at 232100000 {
 			reg = <0x2 0x32100000 0x0 0x8000>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			power-domains = <&ps_aic>;
+		};
+
+		pmgr: power-management at 232000000 {
+			compatible = "apple,t8015-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x32000000 0 0x8c000>;
 		};
 
 		pinctrl_ap: pinctrl at 233100000 {
 			compatible = "apple,t8015-pinctrl", "apple,pinctrl";
 			reg = <0x2 0x33100000 0x0 0x1000>;
+			power-domains = <&ps_gpio>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -188,6 +199,14 @@ pinctrl_nub: pinctrl at 2351f0000 {
 				     <AIC_IRQ 170 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pmgr_mini: power-management at 235200000 {
+			compatible = "apple,t8015-pmgr", "apple,pmgr", "syscon", "simple-mfd";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reg = <0x2 0x35200000 0 0x84000>;
+		};
+
 		wdt: watchdog at 2352b0000 {
 			compatible = "apple,t8015-wdt", "apple,wdt";
 			reg = <0x2 0x352b0000 0x0 0x4000>;
@@ -232,3 +251,5 @@ timer {
 			     <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
+
+#include "t8015-pmgr.dtsi"
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:04 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:04 +0800
Subject: [PATCH 4/9] arm64: dts: apple: Add cpufreq nodes for S8000/S8003
In-Reply-To: <20241222175314.151437-1-towinchenmi@gmail.com>
References: <20241222175314.151437-1-towinchenmi@gmail.com>
Message-ID: <20241222175314.151437-5-towinchenmi@gmail.com>

Add cpufreq nodes for the two variants of Apple A9 SoC. The difference is
that S8000 is slower than S8003 in state transitions.

Change the copyright information in s8000.dtsi and s8003.dtsi as well
since these are now essentially new files with the original content now
being in s800-0-3.dtsi.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s800-0-3.dtsi | 10 +++++
 arch/arm64/boot/dts/apple/s8000.dtsi    | 53 ++++++++++++++++++++++++-
 arch/arm64/boot/dts/apple/s8003.dtsi    | 53 ++++++++++++++++++++++++-
 3 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/apple/s800-0-3.dtsi b/arch/arm64/boot/dts/apple/s800-0-3.dtsi
index 082e5b1733d0..382d7be3f8ce 100644
--- a/arch/arm64/boot/dts/apple/s800-0-3.dtsi
+++ b/arch/arm64/boot/dts/apple/s800-0-3.dtsi
@@ -32,6 +32,8 @@ cpu0: cpu at 0 {
 			compatible = "apple,twister";
 			reg = <0x0 0x0>;
 			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			operating-points-v2 = <&twister_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -40,6 +42,8 @@ cpu1: cpu at 1 {
 			compatible = "apple,twister";
 			reg = <0x0 0x1>;
 			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			operating-points-v2 = <&twister_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -52,6 +56,12 @@ soc {
 		nonposted-mmio;
 		ranges;
 
+		cpufreq: performance-controller at 202220000 {
+			compatible = "apple,s8000-cluster-cpufreq", "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq";
+			reg = <0x2 0x02220000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
 		serial0: serial at 20a0c0000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x0a0c0000 0x0 0x4000>;
diff --git a/arch/arm64/boot/dts/apple/s8000.dtsi b/arch/arm64/boot/dts/apple/s8000.dtsi
index c7e39abda7e1..72322f5677ab 100644
--- a/arch/arm64/boot/dts/apple/s8000.dtsi
+++ b/arch/arm64/boot/dts/apple/s8000.dtsi
@@ -4,11 +4,62 @@
  *
  * Other names: H8P, "Maui"
  *
- * Copyright (c) 2022, Konrad Dybcio <konradybcio at kernel.org>
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
  */
 
 #include "s800-0-3.dtsi"
 
+/ {
+	twister_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-level = <1>;
+			clock-latency-ns = <650>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <396000000>;
+			opp-level = <2>;
+			clock-latency-ns = <75000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-level = <3>;
+			clock-latency-ns = <27000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <912000000>;
+			opp-level = <4>;
+			clock-latency-ns = <32000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-level = <5>;
+			clock-latency-ns = <35000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1512000000>;
+			opp-level = <6>;
+			clock-latency-ns = <45000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <1800000000>;
+			opp-level = <7>;
+			clock-latency-ns = <58000>;
+		};
+#if 0
+		/* Not available until CPU deep sleep is implemented */
+		opp08 {
+			opp-hz = /bits/ 64 <1844000000>;
+			opp-level = <8>;
+			clock-latency-ns = <58000>;
+			turbo-mode;
+		};
+#endif
+	};
+};
+
 /*
  * The A9 was made by two separate fabs on two different process
  * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
diff --git a/arch/arm64/boot/dts/apple/s8003.dtsi b/arch/arm64/boot/dts/apple/s8003.dtsi
index 807e3452f8a7..79df5c783260 100644
--- a/arch/arm64/boot/dts/apple/s8003.dtsi
+++ b/arch/arm64/boot/dts/apple/s8003.dtsi
@@ -4,11 +4,62 @@
  *
  * Other names: H8P, "Malta"
  *
- * Copyright (c) 2022, Konrad Dybcio <konradybcio at kernel.org>
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
  */
 
 #include "s800-0-3.dtsi"
 
+/ {
+	twister_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-level = <1>;
+			clock-latency-ns = <500>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <396000000>;
+			opp-level = <2>;
+			clock-latency-ns = <45000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-level = <3>;
+			clock-latency-ns = <22000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <912000000>;
+			opp-level = <4>;
+			clock-latency-ns = <25000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-level = <5>;
+			clock-latency-ns = <28000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1512000000>;
+			opp-level = <6>;
+			clock-latency-ns = <35000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <1800000000>;
+			opp-level = <7>;
+			clock-latency-ns = <38000>;
+		};
+#if 0
+		/* Not available until CPU deep sleep is implemented */
+		opp08 {
+			opp-hz = /bits/ 64 <1844000000>;
+			opp-level = <8>;
+			clock-latency-ns = <38000>;
+			turbo-mode;
+		};
+#endif
+	};
+};
+
 /*
  * The A9 was made by two separate fabs on two different process
  * nodes: Samsung made the S8000 (APL0898) on 14nm and TSMC made
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:05 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:05 +0800
Subject: [PATCH 5/9] arm64: dts: apple: s8001: Add cpufreq nodes
In-Reply-To: <20241222175314.151437-1-towinchenmi@gmail.com>
References: <20241222175314.151437-1-towinchenmi@gmail.com>
Message-ID: <20241222175314.151437-6-towinchenmi@gmail.com>

Add cpufreq nodes for Apple A9X SoC.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s8001.dtsi | 59 ++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/s8001.dtsi b/arch/arm64/boot/dts/apple/s8001.dtsi
index 23ee3238844d..7f7cb8afd3d3 100644
--- a/arch/arm64/boot/dts/apple/s8001.dtsi
+++ b/arch/arm64/boot/dts/apple/s8001.dtsi
@@ -32,6 +32,8 @@ cpu0: cpu at 0 {
 			compatible = "apple,twister";
 			reg = <0x0 0x0>;
 			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			operating-points-v2 = <&twister_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -40,11 +42,62 @@ cpu1: cpu at 1 {
 			compatible = "apple,twister";
 			reg = <0x0 0x1>;
 			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			operating-points-v2 = <&twister_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
 	};
 
+	twister_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-level = <1>;
+			clock-latency-ns = <800>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <396000000>;
+			opp-level = <2>;
+			clock-latency-ns = <53000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <792000000>;
+			opp-level = <3>;
+			clock-latency-ns = <18000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <1080000000>;
+			opp-level = <4>;
+			clock-latency-ns = <21000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <1440000000>;
+			opp-level = <5>;
+			clock-latency-ns = <25000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1800000000>;
+			opp-level = <6>;
+			clock-latency-ns = <33000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <2160000000>;
+			opp-level = <7>;
+			clock-latency-ns = <45000>;
+		};
+#if 0
+		/* Not available until CPU deep sleep is implemented */
+		opp08 {
+			opp-hz = /bits/ 64 <2160000000>;
+			opp-level = <8>;
+			clock-latency-ns = <45000>;
+			turbo-mode;
+		};
+#endif
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -52,6 +105,12 @@ soc {
 		nonposted-mmio;
 		ranges;
 
+		cpufreq: performance-controller at 202220000 {
+			compatible = "apple,s8000-cluster-cpufreq", "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq";
+			reg = <0x2 0x02220000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
 		serial0: serial at 20a0c0000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x0a0c0000 0x0 0x4000>;
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:06 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:06 +0800
Subject: [PATCH 6/9] arm64: dts: apple: t8010: Add cpufreq nodes
In-Reply-To: <20241222175314.151437-1-towinchenmi@gmail.com>
References: <20241222175314.151437-1-towinchenmi@gmail.com>
Message-ID: <20241222175314.151437-7-towinchenmi@gmail.com>

Add cpufreq nodes for Apple A10 SoC. There is a transparent hardware
big.LITTLE switcher in this SoC. Spoof E-core p-state frequencies such
that CPU capacity does not appear to change when switching between core
types.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8010-7.dtsi     |  8 ++
 arch/arm64/boot/dts/apple/t8010-ipad6.dtsi |  8 ++
 arch/arm64/boot/dts/apple/t8010.dtsi       | 86 ++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8010-7.dtsi b/arch/arm64/boot/dts/apple/t8010-7.dtsi
index 1332fd73f50f..919e067ef073 100644
--- a/arch/arm64/boot/dts/apple/t8010-7.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010-7.dtsi
@@ -41,3 +41,11 @@ switch-mute {
 		};
 	};
 };
+
+&hurricane_opp09 {
+	status = "okay";
+};
+
+&hurricane_opp10 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
index 81696c6e302c..4ea8cf12e430 100644
--- a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi
@@ -42,3 +42,11 @@ button-volup {
 		};
 	};
 };
+
+&hurricane_opp09 {
+	status = "okay";
+};
+
+&hurricane_opp10 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/apple/t8010.dtsi b/arch/arm64/boot/dts/apple/t8010.dtsi
index e3d6a8354103..2547e8c60cad 100644
--- a/arch/arm64/boot/dts/apple/t8010.dtsi
+++ b/arch/arm64/boot/dts/apple/t8010.dtsi
@@ -32,6 +32,8 @@ cpu0: cpu at 0 {
 			compatible = "apple,hurricane-zephyr";
 			reg = <0x0 0x0>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			operating-points-v2 = <&fusion_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -40,11 +42,89 @@ cpu1: cpu at 1 {
 			compatible = "apple,hurricane-zephyr";
 			reg = <0x0 0x1>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			operating-points-v2 = <&fusion_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
 	};
 
+	fusion_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		/*
+		 * Apple Fusion Architecture: Hardware big.LITTLE switcher
+		 * that use p-state transitions to switch between cores.
+		 * Only one type of core can be active at a given time.
+		 *
+		 * The E-core frequencies are adjusted so performance scales
+		 * linearly with reported clock speed.
+		 */
+
+		opp01 {
+			opp-hz = /bits/ 64 <172000000>; /* 300 MHz, E-core */
+			opp-level = <1>;
+			clock-latency-ns = <11000>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <230000000>; /* 396 MHz, E-core */
+			opp-level = <2>;
+			clock-latency-ns = <49000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <425000000>; /* 732 MHz, E-core */
+			opp-level = <3>;
+			clock-latency-ns = <13000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <637000000>; /* 1092 MHz, E-core */
+			opp-level = <4>;
+			clock-latency-ns = <18000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <756000000>;
+			opp-level = <5>;
+			clock-latency-ns = <35000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1056000000>;
+			opp-level = <6>;
+			clock-latency-ns = <31000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <1356000000>;
+			opp-level = <7>;
+			clock-latency-ns = <37000>;
+		};
+		opp08 {
+			opp-hz = /bits/ 64 <1644000000>;
+			opp-level = <8>;
+			clock-latency-ns = <39500>;
+		};
+		hurricane_opp09: opp09 {
+			opp-hz = /bits/ 64 <1944000000>;
+			opp-level = <9>;
+			clock-latency-ns = <46000>;
+			status = "disabled"; /* Not available on N112 */
+		};
+		hurricane_opp10: opp10 {
+			opp-hz = /bits/ 64 <2244000000>;
+			opp-level = <10>;
+			clock-latency-ns = <56000>;
+			status = "disabled"; /* Not available on N112 */
+		};
+#if 0
+		/* Not available until CPU deep sleep is implemented */
+		hurricane_opp11: opp11 {
+			opp-hz = /bits/ 64 <2340000000>;
+			opp-level = <11>;
+			clock-latency-ns = <56000>;
+			turbo-mode;
+			status = "disabled"; /* Not available on N112 */
+		};
+#endif
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -52,6 +132,12 @@ soc {
 		nonposted-mmio;
 		ranges;
 
+		cpufreq: performance-controller at 202f20000 {
+			compatible = "apple,t8010-cluster-cpufreq", "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq";
+			reg = <0x2 0x02f20000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
 		serial0: serial at 20a0c0000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x0a0c0000 0x0 0x4000>;
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:07 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:07 +0800
Subject: [PATCH 7/9] arm64: dts: apple: t8011: Add cpufreq nodes
In-Reply-To: <20241222175314.151437-1-towinchenmi@gmail.com>
References: <20241222175314.151437-1-towinchenmi@gmail.com>
Message-ID: <20241222175314.151437-8-towinchenmi@gmail.com>

Add cpufreq nodes for Apple A10 SoC. There is a transparent hardware
big.LITTLE switcher in this SoC. Spoof E-core p-state frequencies such
that CPU capacity does not appear to change when switching between core
types.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8011.dtsi | 79 ++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8011.dtsi b/arch/arm64/boot/dts/apple/t8011.dtsi
index 6c4ed9dc4a50..3a3d5b615a6a 100644
--- a/arch/arm64/boot/dts/apple/t8011.dtsi
+++ b/arch/arm64/boot/dts/apple/t8011.dtsi
@@ -32,6 +32,8 @@ cpu0: cpu at 0 {
 			compatible = "apple,hurricane-zephyr";
 			reg = <0x0 0x0>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			operating-points-v2 = <&fusion_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -40,6 +42,8 @@ cpu1: cpu at 1 {
 			compatible = "apple,hurricane-zephyr";
 			reg = <0x0 0x1>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			operating-points-v2 = <&fusion_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -48,11 +52,80 @@ cpu2: cpu at 2 {
 			compatible = "apple,hurricane-zephyr";
 			reg = <0x0 0x2>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			operating-points-v2 = <&fusion_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
 	};
 
+	fusion_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		/*
+		 * Apple Fusion Architecture: Hardwired big.LITTLE switcher
+		 * that use p-state transitions to switch between cores.
+		 *
+		 * The E-core frequencies are adjusted so performance scales
+		 * linearly with reported clock speed.
+		 */
+
+		opp01 {
+			opp-hz = /bits/ 64 <172000000>; /* 300 MHz, E-core */
+			opp-level = <1>;
+			clock-latency-ns = <12000>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <230000000>; /* 396 MHz, E-core */
+			opp-level = <2>;
+			clock-latency-ns = <135000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <448000000>; /* 768 MHz, E-core */
+			opp-level = <3>;
+			clock-latency-ns = <105000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <662000000>; /* 1152 MHz, E-core */
+			opp-level = <4>;
+			clock-latency-ns = <115000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <804000000>;
+			opp-level = <5>;
+			clock-latency-ns = <122000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1140000000>;
+			opp-level = <6>;
+			clock-latency-ns = <120000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <1548000000>;
+			opp-level = <7>;
+			clock-latency-ns = <125000>;
+		};
+		opp08 {
+			opp-hz = /bits/ 64 <1956000000>;
+			opp-level = <8>;
+			clock-latency-ns = <135000>;
+		};
+		opp09 {
+			opp-hz = /bits/ 64 <2316000000>;
+			opp-level = <9>;
+			clock-latency-ns = <140000>;
+		};
+#if 0
+		/* Not available until CPU deep sleep is implemented */
+		opp10 {
+			opp-hz = /bits/ 64 <2400000000>;
+			opp-level = <10>;
+			clock-latency-ns = <140000>;
+			turbo-mode;
+		};
+#endif
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -60,6 +133,12 @@ soc {
 		nonposted-mmio;
 		ranges;
 
+		cpufreq: performance-controller at 202f20000 {
+			compatible = "apple,t8010-cluster-cpufreq", "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq";
+			reg = <0x2 0x02f20000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
 		serial0: serial at 20a0c0000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x0a0c0000 0x0 0x4000>;
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:08 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:08 +0800
Subject: [PATCH 8/9] arm64: dts: apple: t8012: Add cpufreq nodes
In-Reply-To: <20241222175314.151437-1-towinchenmi@gmail.com>
References: <20241222175314.151437-1-towinchenmi@gmail.com>
Message-ID: <20241222175314.151437-9-towinchenmi@gmail.com>

Add cpufreq nodes for Apple A10 SoC. There is a transparent hardware
big.LITTLE switcher in this SoC. Spoof E-core p-state frequencies such
that CPU capacity does not appear to change when switching between core
types.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8012.dtsi | 83 ++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8012.dtsi b/arch/arm64/boot/dts/apple/t8012.dtsi
index 45d24ca091b0..0a3d5a6bd047 100644
--- a/arch/arm64/boot/dts/apple/t8012.dtsi
+++ b/arch/arm64/boot/dts/apple/t8012.dtsi
@@ -32,6 +32,8 @@ cpu0: cpu at 10000 {
 			compatible = "apple,hurricane-zephyr";
 			reg = <0x0 0x10000>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			operating-points-v2 = <&fusion_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -40,11 +42,86 @@ cpu1: cpu at 10001 {
 			compatible = "apple,hurricane-zephyr";
 			reg = <0x0 0x10001>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			operating-points-v2 = <&fusion_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
 	};
 
+	fusion_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		/*
+		 * Apple Fusion Architecture: Hardware big.LITTLE switcher
+		 * that use p-state transitions to switch between cores.
+		 * Only one type of core can be active at a given time.
+		 *
+		 * The E-core frequencies are adjusted so performance scales
+		 * linearly with reported clock speed.
+		 */
+
+		opp01 {
+			opp-hz = /bits/ 64 <172000000>; /* 300 MHz, E-core */
+			opp-level = <1>;
+			clock-latency-ns = <11000>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <230000000>; /* 396 MHz, E-core */
+			opp-level = <2>;
+			clock-latency-ns = <140000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <425000000>; /* 732 MHz, E-core */
+			opp-level = <3>;
+			clock-latency-ns = <110000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <637000000>; /* 1092 MHz, E-core */
+			opp-level = <4>;
+			clock-latency-ns = <130000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <756000000>;
+			opp-level = <5>;
+			clock-latency-ns = <130000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1056000000>;
+			opp-level = <6>;
+			clock-latency-ns = <130000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <1356000000>;
+			opp-level = <7>;
+			clock-latency-ns = <130000>;
+		};
+		opp08 {
+			opp-hz = /bits/ 64 <1644000000>;
+			opp-level = <8>;
+			clock-latency-ns = <135000>;
+		};
+		opp09 {
+			opp-hz = /bits/ 64 <1944000000>;
+			opp-level = <9>;
+			clock-latency-ns = <140000>;
+		};
+		opp10 {
+			opp-hz = /bits/ 64 <2244000000>;
+			opp-level = <10>;
+			clock-latency-ns = <150000>;
+		};
+#if 0
+		/* Not available until CPU deep sleep is implemented */
+		opp11 {
+			opp-hz = /bits/ 64 <2340000000>;
+			opp-level = <11>;
+			clock-latency-ns = <150000>;
+			turbo-mode;
+		};
+#endif
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -52,6 +129,12 @@ soc {
 		nonposted-mmio;
 		ranges;
 
+		cpufreq: performance-controller at 202f20000 {
+			compatible = "apple,t8010-cluster-cpufreq", "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq";
+			reg = <0x2 0x02f20000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
 		serial0: serial at 20a600000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x0a600000 0x0 0x4000>;
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:00 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:00 +0800
Subject: [PATCH 0/9] Add Apple A7-A11, T2 SoC cpufreq nodes
Message-ID: <20241222175314.151437-1-towinchenmi@gmail.com>

This series adds performance-controller and operating-points-v2 cpufreq
nodes for Apple A7-A11, T2 SoCs.

Dependencies:

- Apple A7-A11, T2 SoC cpufreq support, in PM tree.
https://lore.kernel.org/asahi/20241218182834.22334-1-towinchenmi at gmail.com/T

- arm64: dts: apple: Split s8000/s8003 SoC DTS files
https://lore.kernel.org/asahi/20241206135051.56049-1-towinchenmi at gmail.com/T

- Device Tree for Apple T2 (T8012) SoC devices
https://lore.kernel.org/asahi/20241203051147.110980-1-towinchenmi at gmail.com/T

Nick Chan

---

Nick Chan (9):
  arm64: dts: apple: s5l8960x: Add cpufreq nodes
  arm64: dts: apple: t7000: Add cpufreq nodes
  arm64: dts: apple: t7001: Add cpufreq nodes
  arm64: dts: apple: Add cpufreq nodes for S8000/S8003
  arm64: dts: apple: s8001: Add cpufreq nodes
  arm64: dts: apple: t8010: Add cpufreq nodes
  arm64: dts: apple: t8011: Add cpufreq nodes
  arm64: dts: apple: t8012: Add cpufreq nodes
  arm64: dts: apple: t8015: Add cpufreq nodes

 arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi    |   1 +
 arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi  |   1 +
 arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi |   1 +
 arch/arm64/boot/dts/apple/s5l8960x-opp.dtsi   |  45 +++++++
 arch/arm64/boot/dts/apple/s5l8960x.dtsi       |  10 ++
 arch/arm64/boot/dts/apple/s5l8965x-opp.dtsi   |  45 +++++++
 arch/arm64/boot/dts/apple/s800-0-3.dtsi       |  10 ++
 arch/arm64/boot/dts/apple/s8000.dtsi          |  53 +++++++-
 arch/arm64/boot/dts/apple/s8001.dtsi          |  59 +++++++++
 arch/arm64/boot/dts/apple/s8003.dtsi          |  53 +++++++-
 arch/arm64/boot/dts/apple/t7000-6.dtsi        |   4 +
 arch/arm64/boot/dts/apple/t7000-j42d.dts      |   4 +
 arch/arm64/boot/dts/apple/t7000-mini4.dtsi    |   4 +
 arch/arm64/boot/dts/apple/t7000.dtsi          |  46 +++++++
 arch/arm64/boot/dts/apple/t7001.dtsi          |  52 ++++++++
 arch/arm64/boot/dts/apple/t8010-7.dtsi        |   8 ++
 arch/arm64/boot/dts/apple/t8010-ipad6.dtsi    |   8 ++
 arch/arm64/boot/dts/apple/t8010.dtsi          |  86 ++++++++++++
 arch/arm64/boot/dts/apple/t8011.dtsi          |  79 +++++++++++
 arch/arm64/boot/dts/apple/t8012.dtsi          |  83 ++++++++++++
 arch/arm64/boot/dts/apple/t8015.dtsi          | 123 ++++++++++++++++++
 21 files changed, 773 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/boot/dts/apple/s5l8960x-opp.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s5l8965x-opp.dtsi


base-commit: 9a33cbb3b1e4a0b520a131aec028ddeb99da48c3
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:01 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:01 +0800
Subject: [PATCH 1/9] arm64: dts: apple: s5l8960x: Add cpufreq nodes
In-Reply-To: <20241222175314.151437-1-towinchenmi@gmail.com>
References: <20241222175314.151437-1-towinchenmi@gmail.com>
Message-ID: <20241222175314.151437-2-towinchenmi@gmail.com>

Add cpufreq nodes for Apple A7 SoC.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi    |  1 +
 arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi  |  1 +
 arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi |  1 +
 arch/arm64/boot/dts/apple/s5l8960x-opp.dtsi   | 45 +++++++++++++++++++
 arch/arm64/boot/dts/apple/s5l8960x.dtsi       | 10 +++++
 arch/arm64/boot/dts/apple/s5l8965x-opp.dtsi   | 45 +++++++++++++++++++
 6 files changed, 103 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apple/s5l8960x-opp.dtsi
 create mode 100644 arch/arm64/boot/dts/apple/s5l8965x-opp.dtsi

diff --git a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
index 0b16adf07f79..83c0a4deb5ba 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi
@@ -8,6 +8,7 @@
 
 #include "s5l8960x.dtsi"
 #include "s5l8960x-common.dtsi"
+#include "s5l8960x-opp.dtsi"
 #include <dt-bindings/input/input.h>
 
 / {
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
index 741c5a9f21dd..d88894e0fce7 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi
@@ -8,6 +8,7 @@
 
 #include "s5l8960x.dtsi"
 #include "s5l8960x-common.dtsi"
+#include "s5l8965x-opp.dtsi"
 #include <dt-bindings/input/input.h>
 
 / {
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
index b27ef5680626..261b5008a6b4 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi
@@ -8,6 +8,7 @@
 
 #include "s5l8960x.dtsi"
 #include "s5l8960x-common.dtsi"
+#include "s5l8960x-opp.dtsi"
 #include <dt-bindings/input/input.h>
 
 / {
diff --git a/arch/arm64/boot/dts/apple/s5l8960x-opp.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-opp.dtsi
new file mode 100644
index 000000000000..e4d568c4a119
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s5l8960x-opp.dtsi
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Operating points for Apple S5L8960X "A7" SoC, Up to 1296 MHz
+ *
+ * target-type: N51, N53, J85, J86. J87, J85m, J86m, J87m
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/ {
+	cyclone_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-level = <1>;
+			clock-latency-ns = <15500>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <396000000>;
+			opp-level = <2>;
+			clock-latency-ns = <43000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-level = <3>;
+			clock-latency-ns = <26000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <840000000>;
+			opp-level = <4>;
+			clock-latency-ns = <30000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <1128000000>;
+			opp-level = <5>;
+			clock-latency-ns = <39500>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1296000000>;
+			opp-level = <6>;
+			clock-latency-ns = <45500>;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/apple/s5l8960x.dtsi b/arch/arm64/boot/dts/apple/s5l8960x.dtsi
index 0218ecac1d83..449c69d0d92f 100644
--- a/arch/arm64/boot/dts/apple/s5l8960x.dtsi
+++ b/arch/arm64/boot/dts/apple/s5l8960x.dtsi
@@ -33,6 +33,8 @@ cpu0: cpu at 0 {
 			compatible = "apple,cyclone";
 			reg = <0x0 0x0>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			operating-points-v2 = <&cyclone_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -41,6 +43,8 @@ cpu1: cpu at 1 {
 			compatible = "apple,cyclone";
 			reg = <0x0 0x1>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			operating-points-v2 = <&cyclone_opp>;
+			performance-domains = <&cpufreq>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -53,6 +57,12 @@ soc {
 		nonposted-mmio;
 		ranges;
 
+		cpufreq: performance-controller at 202220000 {
+			compatible = "apple,s5l8960x-cluster-cpufreq";
+			reg = <0x2 0x02220000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
 		serial0: serial at 20a0a0000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x0a0a0000 0x0 0x4000>;
diff --git a/arch/arm64/boot/dts/apple/s5l8965x-opp.dtsi b/arch/arm64/boot/dts/apple/s5l8965x-opp.dtsi
new file mode 100644
index 000000000000..d34dae74a90c
--- /dev/null
+++ b/arch/arm64/boot/dts/apple/s5l8965x-opp.dtsi
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Operating points for Apple S5L8965X "A7" Rev A SoC, Up to 1392 MHz
+ *
+ * target-type: J71, J72, J73
+ *
+ * Copyright (c) 2024, Nick Chan <towinchenmi at gmail.com>
+ */
+
+/ {
+	cyclone_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-level = <1>;
+			clock-latency-ns = <10000>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-level = <2>;
+			clock-latency-ns = <49000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <840000000>;
+			opp-level = <3>;
+			clock-latency-ns = <30000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <1128000000>;
+			opp-level = <4>;
+			clock-latency-ns = <39500>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <1296000000>;
+			opp-level = <5>;
+			clock-latency-ns = <45500>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1392000000>;
+			opp-level = <6>;
+			clock-latency-ns = <46500>;
+		};
+	};
+};
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:02 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:02 +0800
Subject: [PATCH 2/9] arm64: dts: apple: t7000: Add cpufreq nodes
In-Reply-To: <20241222175314.151437-1-towinchenmi@gmail.com>
References: <20241222175314.151437-1-towinchenmi@gmail.com>
Message-ID: <20241222175314.151437-3-towinchenmi@gmail.com>

Add cpufreq nodes for Apple A8 SoC.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t7000-6.dtsi     |  4 ++
 arch/arm64/boot/dts/apple/t7000-j42d.dts   |  4 ++
 arch/arm64/boot/dts/apple/t7000-mini4.dtsi |  4 ++
 arch/arm64/boot/dts/apple/t7000.dtsi       | 46 ++++++++++++++++++++++
 4 files changed, 58 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t7000-6.dtsi b/arch/arm64/boot/dts/apple/t7000-6.dtsi
index f60ea4a4a387..0d08e2589449 100644
--- a/arch/arm64/boot/dts/apple/t7000-6.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000-6.dtsi
@@ -48,3 +48,7 @@ switch-mute {
 		};
 	};
 };
+
+&typhoon_opp06 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-j42d.dts b/arch/arm64/boot/dts/apple/t7000-j42d.dts
index 2231db6a739d..24fe5a99f3ab 100644
--- a/arch/arm64/boot/dts/apple/t7000-j42d.dts
+++ b/arch/arm64/boot/dts/apple/t7000-j42d.dts
@@ -29,3 +29,7 @@ framebuffer0: framebuffer at 0 {
 &serial6 {
 	status = "okay";
 };
+
+&typhoon_opp06 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
index c64ddc402fda..773c69449902 100644
--- a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi
@@ -49,3 +49,7 @@ switch-mute {
 		};
 	};
 };
+
+&typhoon_opp06 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/apple/t7000.dtsi b/arch/arm64/boot/dts/apple/t7000.dtsi
index a7cc29e84c84..4105cf70391b 100644
--- a/arch/arm64/boot/dts/apple/t7000.dtsi
+++ b/arch/arm64/boot/dts/apple/t7000.dtsi
@@ -33,6 +33,8 @@ cpu0: cpu at 0 {
 			compatible = "apple,typhoon";
 			reg = <0x0 0x0>;
 			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			performance-domains = <&cpufreq>;
+			operating-points-v2 = <&typhoon_opp>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -41,11 +43,49 @@ cpu1: cpu at 1 {
 			compatible = "apple,typhoon";
 			reg = <0x0 0x1>;
 			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			performance-domains = <&cpufreq>;
+			operating-points-v2 = <&typhoon_opp>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
 	};
 
+	typhoon_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-level = <1>;
+			clock-latency-ns = <300>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <396000000>;
+			opp-level = <2>;
+			clock-latency-ns = <50000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-level = <3>;
+			clock-latency-ns = <29000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <840000000>;
+			opp-level = <4>;
+			clock-latency-ns = <29000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <1128000000>;
+			opp-level = <5>;
+			clock-latency-ns = <36000>;
+		};
+		typhoon_opp06: opp06 {
+			opp-hz = /bits/ 64 <1392000000>;
+			opp-level = <6>;
+			clock-latency-ns = <42000>;
+			status = "disabled"; /* Not available on N102 */
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -53,6 +93,12 @@ soc {
 		nonposted-mmio;
 		ranges;
 
+		cpufreq: performance-controller at 202220000 {
+			compatible = "apple,t7000-cluster-cpufreq", "apple,s5l8960x-cluster-cpufreq";
+			reg = <0x2 0x02220000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
 		serial0: serial at 20a0c0000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x0a0c0000 0x0 0x4000>;
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:03 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:03 +0800
Subject: [PATCH 3/9] arm64: dts: apple: t7001: Add cpufreq nodes
In-Reply-To: <20241222175314.151437-1-towinchenmi@gmail.com>
References: <20241222175314.151437-1-towinchenmi@gmail.com>
Message-ID: <20241222175314.151437-4-towinchenmi@gmail.com>

Add the cpufreq nodes for Apple A8X SoC.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t7001.dtsi | 52 ++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t7001.dtsi b/arch/arm64/boot/dts/apple/t7001.dtsi
index a76e034c85e3..15fd91d12f30 100644
--- a/arch/arm64/boot/dts/apple/t7001.dtsi
+++ b/arch/arm64/boot/dts/apple/t7001.dtsi
@@ -35,6 +35,8 @@ cpu0: cpu at 0 {
 			compatible = "apple,typhoon";
 			reg = <0x0 0x0>;
 			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			performance-domains = <&cpufreq>;
+			operating-points-v2 = <&typhoon_opp>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -43,6 +45,8 @@ cpu1: cpu at 1 {
 			compatible = "apple,typhoon";
 			reg = <0x0 0x1>;
 			cpu-release-addr = <0 0>; /* To be filled in by loader */
+			performance-domains = <&cpufreq>;
+			operating-points-v2 = <&typhoon_opp>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -51,11 +55,53 @@ cpu2: cpu at 2 {
 			compatible = "apple,typhoon";
 			reg = <0x0 0x2>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			performance-domains = <&cpufreq>;
+			operating-points-v2 = <&typhoon_opp>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
 	};
 
+	typhoon_opp: opp-table {
+		compatible = "operating-points-v2";
+
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-level = <1>;
+			clock-latency-ns = <300>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <396000000>;
+			opp-level = <2>;
+			clock-latency-ns = <49000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-level = <3>;
+			clock-latency-ns = <31000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <840000000>;
+			opp-level = <4>;
+			clock-latency-ns = <32000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <1128000000>;
+			opp-level = <5>;
+			clock-latency-ns = <32000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1392000000>;
+			opp-level = <6>;
+			clock-latency-ns = <37000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <1512000000>;
+			opp-level = <7>;
+			clock-latency-ns = <41000>;
+		};
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -63,6 +109,12 @@ soc {
 		nonposted-mmio;
 		ranges;
 
+		cpufreq: performance-controller at 202220000 {
+			compatible = "apple,t7000-cluster-cpufreq", "apple,s5l8960x-cluster-cpufreq";
+			reg = <0x2 0x02220000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
 		serial0: serial at 20a0c0000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x0a0c0000 0x0 0x4000>;
-- 
2.47.1



From towinchenmi at gmail.com  Sun Dec 22 09:52:09 2024
From: towinchenmi at gmail.com (Nick Chan)
Date: Mon, 23 Dec 2024 01:52:09 +0800
Subject: [PATCH 9/9] arm64: dts: apple: t8015: Add cpufreq nodes
In-Reply-To: <20241222175314.151437-1-towinchenmi@gmail.com>
References: <20241222175314.151437-1-towinchenmi@gmail.com>
Message-ID: <20241222175314.151437-10-towinchenmi@gmail.com>

Add cpufreq nodes for Apple A11 SoC.

Signed-off-by: Nick Chan <towinchenmi at gmail.com>
---
 arch/arm64/boot/dts/apple/t8015.dtsi | 123 +++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8015.dtsi b/arch/arm64/boot/dts/apple/t8015.dtsi
index 8828d830e5be..f93ce2c8b251 100644
--- a/arch/arm64/boot/dts/apple/t8015.dtsi
+++ b/arch/arm64/boot/dts/apple/t8015.dtsi
@@ -58,6 +58,9 @@ cpu_e0: cpu at 0 {
 			compatible = "apple,mistral";
 			reg = <0x0 0x0>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			performance-domains = <&cpufreq_e>;
+			operating-points-v2 = <&mistral_opp>;
+			capacity-dmips-mhz = <633>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -66,6 +69,9 @@ cpu_e1: cpu at 1 {
 			compatible = "apple,mistral";
 			reg = <0x0 0x1>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			performance-domains = <&cpufreq_e>;
+			operating-points-v2 = <&mistral_opp>;
+			capacity-dmips-mhz = <633>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -74,6 +80,9 @@ cpu_e2: cpu at 2 {
 			compatible = "apple,mistral";
 			reg = <0x0 0x2>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			performance-domains = <&cpufreq_e>;
+			operating-points-v2 = <&mistral_opp>;
+			capacity-dmips-mhz = <633>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -82,6 +91,9 @@ cpu_e3: cpu at 3 {
 			compatible = "apple,mistral";
 			reg = <0x0 0x3>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			performance-domains = <&cpufreq_e>;
+			operating-points-v2 = <&mistral_opp>;
+			capacity-dmips-mhz = <633>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -90,6 +102,9 @@ cpu_p0: cpu at 10004 {
 			compatible = "apple,monsoon";
 			reg = <0x0 0x10004>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			performance-domains = <&cpufreq_p>;
+			operating-points-v2 = <&monsoon_opp>;
+			capacity-dmips-mhz = <1024>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
@@ -98,11 +113,107 @@ cpu_p1: cpu at 10005 {
 			compatible = "apple,monsoon";
 			reg = <0x0 0x10005>;
 			cpu-release-addr = <0 0>; /* To be filled by loader */
+			performance-domains = <&cpufreq_p>;
+			operating-points-v2 = <&monsoon_opp>;
+			capacity-dmips-mhz = <1024>;
 			enable-method = "spin-table";
 			device_type = "cpu";
 		};
 	};
 
+	mistral_opp: opp-table-0 {
+		compatible = "operating-points-v2";
+
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-level = <1>;
+			clock-latency-ns = <1800>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <453000000>;
+			opp-level = <2>;
+			clock-latency-ns = <140000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <672000000>;
+			opp-level = <3>;
+			clock-latency-ns = <105000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <972000000>;
+			opp-level = <4>;
+			clock-latency-ns = <115000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <1272000000>;
+			opp-level = <5>;
+			clock-latency-ns = <125000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <1572000000>;
+			opp-level = <6>;
+			clock-latency-ns = <135000>;
+		};
+#if 0
+		/* Not available until CPU deep sleep is implemented */
+		opp07 {
+			opp-hz = /bits/ 64 <1680000000>;
+			opp-level = <7>;
+			clock-latency-ns = <135000>;
+			turbo-mode;
+		};
+#endif
+	};
+
+	monsoon_opp: opp-table-1 {
+		compatible = "operating-points-v2";
+
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-level = <1>;
+			clock-latency-ns = <1400>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <453000000>;
+			opp-level = <2>;
+			clock-latency-ns = <140000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <853000000>;
+			opp-level = <3>;
+			clock-latency-ns = <110000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <1332000000>;
+			opp-level = <4>;
+			clock-latency-ns = <110000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <1812000000>;
+			opp-level = <5>;
+			clock-latency-ns = <125000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <2064000000>;
+			opp-level = <6>;
+			clock-latency-ns = <130000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <2304000000>;
+			opp-level = <7>;
+			clock-latency-ns = <140000>;
+		};
+#if 0
+		/* Not available until CPU deep sleep is implemented */
+		opp08 {
+			opp-hz = /bits/ 64 <2376000000>;
+			opp-level = <8>;
+			clock-latency-ns = <140000>;
+			turbo-mode;
+		};
+#endif
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
@@ -110,6 +221,18 @@ soc {
 		nonposted-mmio;
 		ranges;
 
+		cpufreq_e: performance-controller at 208e20000 {
+			compatible = "apple,t8015-cluster-cpufreq", "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq";
+			reg = <0x2 0x08e20000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
+		cpufreq_p: performance-controller at 208ea0000 {
+			compatible = "apple,t8015-cluster-cpufreq", "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq";
+			reg = <0x2 0x08ea0000 0 0x1000>;
+			#performance-domain-cells = <0>;
+		};
+
 		serial0: serial at 22e600000 {
 			compatible = "apple,s5l-uart";
 			reg = <0x2 0x2e600000 0x0 0x4000>;
-- 
2.47.1



From dsimic at manjaro.org  Sun Dec 22 10:25:02 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Sun, 22 Dec 2024 19:25:02 +0100
Subject: [PATCH 1/3] irqchip/gic-v3: Enable Rockchip 3588001 erratum
 workaround for RK3582
In-Reply-To: <86msgoozqa.wl-maz@kernel.org>
References: <20241222030355.2246-1-naoki@radxa.com>
 <20241222030355.2246-2-naoki@radxa.com> <86msgoozqa.wl-maz@kernel.org>
Message-ID: <f93b3bfb5151e4b617b1c99c91b4956f@manjaro.org>

Hello Marc,

On 2024-12-22 10:04, Marc Zyngier wrote:
> On Sun, 22 Dec 2024 03:03:53 +0000,
> FUKAUMI Naoki <naoki at radxa.com> wrote:
>> 
>> Rockchip RK3582 is a scaled down version of Rockchip RK3588(S). Apply
>> Rockchip 3588001 erratum workaround to RK3582.
>> 
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> ---
>>  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 92244cfa0464..c59ce9332dc0 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -4861,7 +4861,8 @@ static bool __maybe_unused 
>> its_enable_rk3588001(void *data)
>>  {
>>  	struct its_node *its = data;
>> 
>> -	if (!of_machine_is_compatible("rockchip,rk3588") &&
>> +	if (!of_machine_is_compatible("rockchip,rk3582") &&
>> +	    !of_machine_is_compatible("rockchip,rk3588") &&
>>  	    !of_machine_is_compatible("rockchip,rk3588s"))
>>  		return false;
>> 
> 
> Please use the relevant property for that purpose ("dma-noncoherent")
> at the distributor and ITS levels. We're not adding extra compatibles
> for this anymore, and you might as well fix the core dtsi to expose
> such property.

Thanks for your response.

After a more detailed look into drivers/irqchip/irq-gic-v3-its.c,
it seems that relying on the "dma-noncoherent" DT property may not
be equivalent to adding another compatible check.  Here are a few
quotations from irq-gic-v3-its.c, to illustrate this better:

4746 static bool __maybe_unused its_enable_rk3588001(void *data)
4747 {
4748         struct its_node *its = data;
4749
4750         if (!of_machine_is_compatible("rockchip,rk3588") &&
4751             !of_machine_is_compatible("rockchip,rk3588s"))
4752                 return false;
4753
4754         its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
4755         gic_rdists->flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE;
4756
4757         return true;
4758 }
4759
4760 static bool its_set_non_coherent(void *data)
4761 {
4762         struct its_node *its = data;
4763
4764         its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
4765         return true;
4766 }

4814 #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
4815         {
4816                 .desc   = "ITS: Rockchip erratum RK3588001",
4817                 .iidr   = 0x0201743b,
4818                 .mask   = 0xffffffff,
4819                 .init   = its_enable_rk3588001,
4820         },
4821 #endif
4822         {
4823                 .desc   = "ITS: non-coherent attribute",
4824                 .property = "dma-noncoherent",
4825                 .init   = its_set_non_coherent,
4826         },

As visible above, using the "dma-noncoherent" DT property results
in not setting the RDIST_FLAGS_FORCE_NON_SHAREABLE flag, which the
its_enable_rk3588001() function does.  In other words, it doesn't
seem that "dma-noncoherent" is a "drop-in" replacement for adding
yet another compatible for the RK3582.

Modifying the current behavior of the "dma-noncoherent" DT property
doesn't seem like an option, because it's already used in a couple
of board dts(i) files.  Should we introduce another DT property,
perhaps "dma-noncoherent-rdist" or something similar?

Could you, please, advise on how to move forward with this?  I'm
willing to implement the required patches, but I'd prefer to reduce
the possible back-and-forth on them, to save everyone's time.


From o.rempel at pengutronix.de  Sun Dec 22 10:54:37 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Sun, 22 Dec 2024 19:54:37 +0100
Subject: [PATCH net-next RFC 0/5] net: phy: Introduce a port
 representation
In-Reply-To: <Z2g3b_t3KwMFozR8@pengutronix.de>
References: <20241220201506.2791940-1-maxime.chevallier@bootlin.com>
 <Z2g3b_t3KwMFozR8@pengutronix.de>
Message-ID: <Z2hgbdeTXjqWKa14@pengutronix.de>

On Sun, Dec 22, 2024 at 04:59:43PM +0100, Oleksij Rempel wrote:
> ### Proposed Port Description Schema
> 
> Here?s how I imagine the port description could look to address these issues:
> 
> #### **Device Tree Example**
> /* Ports should be in the root of DT */
> ports {
>     /* Twisted-Pair Example */
>     port0: ethernet-port at 0 {
>         reg = <0>; /* Port index */
>         label = "ETH0"; /* Physical label on the device */
>         connector = "RJ45"; /* Connector type */
>         supported-modes = <10BaseT 100BaseTX>; /* Supported modes */
> 
>         pairs {
>             pair at 0 {
>                 name = "A"; /* Pair A */
>                 pins = <1 2>; /* Connector pins */
>                 phy-mapping = <PHY_TX0_P PHY_TX0_N>; /* PHY pin mapping */
>                 pse-mapping = <PSE_OUT0_P PSE_OUT0_N>; /* PSE pin mapping */
>             };
>             pair at 1 {
>                 name = "B"; /* Pair B */
>                 pins = <3 6>;
>                 phy-mapping = <PHY_RX0_P PHY_RX0_N>;
>                 pse-mapping = <PSE_OUT1_P PSE_OUT1_N>;
>             };
>         };
> 
>         pse = <&pse1>; /* Reference to attached PSE controller */
> 
>         leds {
>             link = <&led0>; /* Link status LED */
>             activity = <&led1>; /* Activity LED */
>         };
>     };

Here is updated version:

ports {
    /* 1000BaseT Port with Ethernet and simple PoE */
    port0: ethernet-port at 0 {
        reg = <0>; /* Port index */
        label = "ETH0"; /* Physical label on the device */
        connector = "RJ45"; /* Connector type */
        supported-modes = <10BaseT 100BaseTX 1000BaseT>; /* Supported modes */

        transformer {
            model = "ABC123"; /* Transformer model number */
            manufacturer = "TransformerCo"; /* Manufacturer name */

            pairs {
                pair at 0 {
                    name = "A"; /* Pair A */
                    pins = <1 2>; /* Connector pins */
                    phy-mapping = <PHY_TX0_P PHY_TX0_N>; /* PHY pin mapping */
                    center-tap = "CT0"; /* Central tap identifier */
                    pse-negative = <PSE_GND>; /* CT0 connected to GND */
                };
                pair at 1 {
                    name = "B"; /* Pair B */
                    pins = <3 6>; /* Connector pins */
                    phy-mapping = <PHY_RX0_P PHY_RX0_N>;
                    center-tap = "CT1"; /* Central tap identifier */
                    pse-positive = <PSE_OUT0>; /* CT1 connected to PSE_OUT0 */
                };
                pair at 2 {
                    name = "C"; /* Pair C */
                    pins = <4 5>; /* Connector pins */
                    phy-mapping = <PHY_TXRX1_P PHY_TXRX1_N>; /* PHY connection only */
                    center-tap = "CT2"; /* Central tap identifier */
                    /* No power connection to CT2 */
                };
                pair at 3 {
                    name = "D"; /* Pair D */
                    pins = <7 8>; /* Connector pins */
                    phy-mapping = <PHY_TXRX2_P PHY_TXRX2_N>; /* PHY connection only */
                    center-tap = "CT3"; /* Central tap identifier */
                    /* No power connection to CT3 */
                };
            };
        };

        pse = <&pse1>; /* Reference to the attached PSE controller */

        leds {
            ethernet-leds {
                link = <&eth_led0>; /* Link status LED */
                activity = <&eth_led1>; /* Activity LED */
                speed = <&eth_led2>; /* Speed indication LED */
            };

            poe-leds {
                power = <&poe_led0>; /* PoE power status LED */
                fault = <&poe_led1>; /* PoE fault indication LED */
                budget = <&poe_led2>; /* PoE budget usage LED */
            };
        };
    };
};

A port with fully configurable PoE support:

ports {
    /* 1000BaseT Port with Fully Configurable PoE */
    port0: ethernet-port at 0 {
        reg = <0>; /* Port index */
        label = "ETH0"; /* Physical label on the device */
        connector = "RJ45"; /* Connector type */
        supported-modes = <10BaseT 100BaseTX 1000BaseT>; /* Supported modes */
        shielding = "grounded"; /* Indicates the connector is shielded */
	/* 
	  grounded: Shield is connected to chassis or earth ground.
	  floating: Shield is not electrically connected.
	  capacitive: Shield is connected to ground via a capacitor.
	  signal: Shield is connected to the signal ground.
         */


        transformer {
            model = "ABC123"; /* Transformer model number */
            manufacturer = "TransformerCo"; /* Manufacturer name */

            pairs {
                pair at 0 {
                    name = "A"; /* Pair A */
                    pins = <1 2>; /* Connector pins */
                    phy-mapping = <PHY_TX0_P PHY_TX0_N>; /* PHY pin mapping */
                    center-tap = "CT0"; /* Central tap identifier */
                    /* if pse-positive and pse-negative are present - polarity is configurable */
                    pse-positive = <PSE_OUT0_0>; /* PSE-controlled positive pin -> CT0 */
                    pse-negative = <PSE_OUT0_1>; /* PSE-controlled negative pin -> CT0 */
                };
                pair at 1 {
                    name = "B"; /* Pair B */
                    pins = <3 6>; /* Connector pins */
                    phy-mapping = <PHY_RX0_P PHY_RX0_N>;
                    center-tap = "CT1"; /* Central tap identifier */
                    pse-positive = <PSE_OUT1_0>;
                    pse-negative = <PSE_OUT1_1>;
                };
                pair at 2 {
                    name = "C"; /* Pair C */
                    pins = <4 5>; /* Connector pins */
                    phy-mapping = <PHY_TXRX1_P PHY_TXRX1_N>; /* PHY connection only */
                    center-tap = "CT2"; /* Central tap identifier */
                    pse-positive = <PSE_OUT2_0>;
                    pse-negative = <PSE_OUT2_1>;
                };
                pair at 3 {
                    name = "D"; /* Pair D */
                    pins = <7 8>; /* Connector pins */
                    phy-mapping = <PHY_TXRX2_P PHY_TXRX2_N>; /* PHY connection only */
                    center-tap = "CT3"; /* Central tap identifier */
                    pse-positive = <PSE_OUT3_0>;
                    pse-negative = <PSE_OUT3_1>;
                };
            };
        };

        pse = <&pse1>; /* Reference to the attached PSE controller */

        thermal {
            temp-sensor = <&tsensor0>; /* Reference to temperature sensor */
            /* or */
            thermal-zone = <&thermal_zone0>; /* Reference to thermal zone */
        }

	fuses {
	    overcurrent-fuse {
	        type = "resettable"; /* Resettable polyfuse */
	        max-current = <1000>; /* Maximum current in milliamps */
	        location = "data-pairs"; /* Fuse protects data pairs */
	    };

	    overvoltage-fuse {
	        type = "tvs-diode"; /* TVS diode for surge protection */
	        clamp-voltage = <60>; /* Clamping voltage in volts */
	        location = "poe-pairs"; /* Fuse protects PoE pairs */
	    };
	};

        leds {
            ethernet-leds {
                link = <&eth_led0>; /* Link status LED */
                activity = <&eth_led1>; /* Activity LED */
                speed = <&eth_led2>; /* Speed indication LED */
            };

            poe-leds {
                power = <&poe_led0>; /* PoE power status LED */
                fault = <&poe_led1>; /* PoE fault indication LED */
                budget = <&poe_led2>; /* PoE budget usage LED */
            };
        };
    };
};

In case of PoDL, we will have something like this:

pair at 0 {
    name = "A"; /* Single pair for 10BaseT1L */
    pins = <1 2>; /* Connector pins */
    phy-mapping = <PHY_TXRX0_P PHY_TXRX0_N>; /* PHY pin mapping */
    podl-mapping = <PODL_OUT0_P PODL_OUT0_N>; /* PoDL mapping: Positive and negative outputs */
};


-- 
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 ryazanov.s.a at gmail.com  Sun Dec 22 13:04:51 2024
From: ryazanov.s.a at gmail.com (Sergey Ryazanov)
Date: Sun, 22 Dec 2024 23:04:51 +0200
Subject: [net v2] net: wwan: t7xx: Fix FSM command timeout issue
In-Reply-To: <20241220085027.7692-1-jinjian.song@fibocom.com>
References: <20241213064720.122615-1-jinjian.song@fibocom.com>
 <20241220085027.7692-1-jinjian.song@fibocom.com>
Message-ID: <6d839f1a-9c38-46a9-aa3b-62afbd75cea7@gmail.com>

Hi Jinjian,

On 20.12.2024 10:50, Jinjian Song wrote:
> From: Sergey Ryazanov <ryazanov.s.a at gmail.com>
> 
>>> Fixes: d785ed945de6 ("net: wwan: t7xx: PCIe reset rescan")
>>
>> The completion waiting was introduced in a different commit. I 
>> believe, the fix tag should be 13e920d93e37 ("net: wwan: t7xx: Add 
>> core components")
>>
> 
> Got it.

[...]

> Yes, the patch works fine, needs some minor modifications, could we 
> feedback to the driver author to merge these changes.

Looks like the drivers authors haven't enough time to maintain it. You 
are the most active developer at the moment. Could formally resend the 
updated patch with refcounter as V3? And, I believe, we can apply it.

--
Sergey


From kw at linux.com  Sun Dec 22 13:12:03 2024
From: kw at linux.com (Krzysztof =?utf-8?Q?Wilczy=C5=84ski?=)
Date: Mon, 23 Dec 2024 06:12:03 +0900
Subject: [PATCH] PCI: dw-rockchip: Enumerate endpoints based on
 dll_link_up irq in the combined sys irq
In-Reply-To: <20241127145041.3531400-2-cassel@kernel.org>
References: <20241127145041.3531400-2-cassel@kernel.org>
Message-ID: <20241222211203.GC3111282@rocinante>

Hello,

> Most boards using the pcie-dw-rockchip PCIe controller lack standard
> hotplug support.
> 
> Thus, when an endpoint is attached to the SoC, users have to rescan the bus
> manually to enumerate the device. This can be avoided by using the
> 'dll_link_up' interrupt in the combined system interrupt 'sys'.
> 
> Once the 'dll_link_up' irq is received, the bus underneath the host bridge
> is scanned to enumerate PCIe endpoint devices.
> 
> This commit implements the same functionality that was implemented in the
> DWC based pcie-qcom driver in commit 4581403f6792 ("PCI: qcom: Enumerate
> endpoints based on Link up event in 'global_irq' interrupt").
> 
> The Root Complex specific device tree binding for pcie-dw-rockchip already
> has the 'sys' interrupt marked as required, so there is no need to update
> the device tree binding. This also means that we can request the 'sys' IRQ
> unconditionally.

Applied to controller/rockchip, thank you!

[01/01] PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ in the combined sys IRQ
        https://git.kernel.org/pci/pci/c/191b732176e7

	Krzysztof


From kw at linux.com  Sun Dec 22 13:15:03 2024
From: kw at linux.com (Krzysztof =?utf-8?Q?Wilczy=C5=84ski?=)
Date: Mon, 23 Dec 2024 06:15:03 +0900
Subject: [PATCH v5 0/6] PCI: mediatek-gen3: mtk_pcie_en7581_power_up()
 code refactoring
In-Reply-To: <20241130-pcie-en7581-fixes-v5-0-dbffe41566b3@kernel.org>
References: <20241130-pcie-en7581-fixes-v5-0-dbffe41566b3@kernel.org>
Message-ID: <20241222211503.GE3111282@rocinante>

Hello,

> Minor fixes and code refactoring in mtk_pcie_en7581_power_up() routine

Applied to controller/mediatek, thank you!

[01/06] PCI: mediatek-gen3: Add missing reset_control_deassert() for mac_rst in mtk_pcie_en7581_power_up()
        https://git.kernel.org/pci/pci/c/3b2ea2d9a669
[02/06] PCI: mediatek-gen3: Use clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up()
        https://git.kernel.org/pci/pci/c/a28adc4d00b7
[03/06] PCI: mediatek-gen3: Move reset/assert callbacks in .power_up()
        https://git.kernel.org/pci/pci/c/599e5a6bc452
[04/06] PCI: mediatek-gen3: Add comment about initialization order in mtk_pcie_en7581_power_up()
        https://git.kernel.org/pci/pci/c/cdd822338f1b
[05/06] PCI: mediatek-gen3: Add reset delay in mtk_pcie_en7581_power_up()
        https://git.kernel.org/pci/pci/c/6c042f72a930
[06/06] PCI: mediatek-gen3: Use msleep() in mtk_pcie_en7581_power_up()
        https://git.kernel.org/pci/pci/c/90fcb3d015ef

	Krzysztof


From kw at linux.com  Sun Dec 22 13:17:59 2024
From: kw at linux.com (Krzysztof =?utf-8?Q?Wilczy=C5=84ski?=)
Date: Mon, 23 Dec 2024 06:17:59 +0900
Subject: [PATCH v3] PCI: mediatek-gen3: Avoid PCIe resetting via
 PCIE_RSTB for Airoha EN7581 SoC
In-Reply-To: <20241113-pcie-en7581-rst-fix-v3-1-23c5082335f7@kernel.org>
References: <20241113-pcie-en7581-rst-fix-v3-1-23c5082335f7@kernel.org>
Message-ID: <20241222211759.GF3111282@rocinante>

Hello,

> Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal
> causing occasional PCIe link down issues. In order to overcome the
> problem, PCIE_RSTB signals are not asserted/released during device probe or
> suspend/resume phase and the PCIe block is reset using REG_PCI_CONTROL
> (0x88) and REG_RESET_CONTROL (0x834) registers available in the clock
> module running clk_bulk_prepare_enable in mtk_pcie_en7581_power_up().
> 
> Introduce flags field in the mtk_gen3_pcie_pdata struct in order to
> specify per-SoC capabilities.

Applied to controller/mediatek, thank you!

[01/01] PCI: mediatek-gen3: Avoid PCIe resetting via PCIE_RSTB for Airoha EN7581 SoC
        https://git.kernel.org/pci/pci/c/0d0a2b74dc08

	Krzysztof


From ryan at testtoast.com  Sun Dec 22 13:20:11 2024
From: ryan at testtoast.com (Ryan Walklin)
Date: Mon, 23 Dec 2024 10:20:11 +1300
Subject: [PATCH 2/3] ASoC: sun4i-codec: support hp-det-gpios property
In-Reply-To: <CAGb2v64qf0jNv72uHUK+aSj0Xt-bf+DW0NCnsZmLf-6xHZF_ew@mail.gmail.com>
References: <20241221094122.27325-1-ryan@testtoast.com>
 <20241221094122.27325-3-ryan@testtoast.com>
 <CAGb2v64qf0jNv72uHUK+aSj0Xt-bf+DW0NCnsZmLf-6xHZF_ew@mail.gmail.com>
Message-ID: <982a7d32-ab58-434e-a125-4f7143928caf@app.fastmail.com>

Hi Chen-Yu,

Thanks for the review!

On Mon, 23 Dec 2024, at 6:15 AM, Chen-Yu Tsai wrote:
> On Sat, Dec 21, 2024 at 5:41?PM Ryan Walklin <ryan at testtoast.com> wrote:

>> @@ -1635,10 +1681,11 @@ static const struct snd_soc_component_driver sun50i_h616_codec_codec = {
>>  };
>>
>>  static const struct snd_kcontrol_new sun50i_h616_card_controls[] = {
>> -       SOC_DAPM_PIN_SWITCH("LINEOUT"),
>> +       SOC_DAPM_PIN_SWITCH("Speaker"),
>
> Why?

The speaker amp is controlled by a GPIO, this needs a specific card control to toggle on and off, discrete from the line-out volume. Muting the output entirely is not what is required, hence the separate control. I also understand (although it is IMO not well documented on the user-space side) that "Speaker" has a specific meaning to the user-space routing. Can add this to the merge message.

>> @@ -1684,7 +1731,7 @@ static struct snd_soc_card *sun50i_h616_codec_create_card(struct device *dev)
>>
>>         card->dev               = dev;
>>         card->owner             = THIS_MODULE;
>> -       card->name              = "H616 Audio Codec";
>> +       card->name              = "h616-audio-codec";
>
> Why?

As mentioned in the cover letter, ALSA UCM in user space uses the card name to detect and apply the relevant configuration, by loading /usr/share/alsa/ucm2/conf.d/<driver_name>/<card_name>.conf. Spaces are therefore removed in the card name to make this easier to manage. Happy to add this to the commit message too, and this could be changed to card->long_name if it is desired to maintain a human-readable card->name.

See https://github.com/alsa-project/alsa-ucm-conf/pull/491/files for the UCM patch.

>> @@ -1940,6 +1987,14 @@ static int sun4i_codec_probe(struct platform_device *pdev)
>>                 return ret;
>>         }
>>
>> +       scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "allwinner,hp-det",
>> +                                                 GPIOD_IN);
>
> Just put it on the same line. Lines can go up to 100 characters.

Thanks, will do.

Regards,

Ryan


From ryan at testtoast.com  Sun Dec 22 13:23:25 2024
From: ryan at testtoast.com (Ryan Walklin)
Date: Mon, 23 Dec 2024 10:23:25 +1300
Subject: [PATCH 1/3] ASoC: dt-bindings: sun4i-a10-codec: add hp-det-gpios
In-Reply-To: <6768438d.4a0a0220.399c57.89b6@mx.google.com>
References: <20241221094122.27325-1-ryan@testtoast.com>
 <20241221094122.27325-2-ryan@testtoast.com>
 <6768438d.4a0a0220.399c57.89b6@mx.google.com>
Message-ID: <c64563ac-ef6e-4d87-a634-9a5edde86a53@app.fastmail.com>

On Mon, 23 Dec 2024, at 5:51 AM, Chris Morgan wrote:
> On Sat, Dec 21, 2024 at 10:26:32PM +1300, Ryan Walklin wrote:
>>  
>> +  allwinner,hp-det-gpios:
>> +    maxItems: 1
>> +    description: GPIO for headphone/line-out detection
>> +
>
> If possible, I wonder if we can keep this without the vendor prefix?
> It looks like for now Nvidia and some Rockchip codecs have the vendor
> prefix, but audio-graph bindings and Freescale codec bindings have this
> as a non-specific property (and it looks like simple-audio-card does it
> either as "hp-det-gpios" or "simple-audio-card,hp-det-gpios" depending
> upon the circumstances).

I'm relaxed about either approach, it does work with the vendor prefix but agree just "hp-det-gpios" is probably appropriate given the intent is the same across vendors and devices.

> Also, the behavior of this is very specific to just the Headphone sink,
> so we should drop the line-out text from the description. If someone
> sets the routing as `"Headphone", "LINEOUT"` the state of the GPIO will
> affect the audio path, but `"Line Out", "LINEOUT"` will not be impacted
> by the state of the GPIO.

Agreed for this device, but this is a more generic description for the H616 generally, so I'm not sure we should remove the "Line Out" given that it may make sense for other H616 boards (Orange Pi etc) where someone may be using a 3.5mm jack as a line-level output rather than via an amp to headphones.

>
> Thank you,
> Chris
>
Regards,

Ryan


From maz at kernel.org  Sun Dec 22 15:16:30 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 22 Dec 2024 23:16:30 +0000
Subject: [PATCH 1/3] irqchip/gic-v3: Enable Rockchip 3588001 erratum workaround for RK3582
In-Reply-To: <f93b3bfb5151e4b617b1c99c91b4956f@manjaro.org>
References: <20241222030355.2246-1-naoki@radxa.com>
	<20241222030355.2246-2-naoki@radxa.com>
	<86msgoozqa.wl-maz@kernel.org>
	<f93b3bfb5151e4b617b1c99c91b4956f@manjaro.org>
Message-ID: <8734ifs3zl.wl-maz@kernel.org>

Dragan,

On Sun, 22 Dec 2024 18:25:02 +0000,
Dragan Simic <dsimic at manjaro.org> wrote:
> 
> Hello Marc,
> 
> On 2024-12-22 10:04, Marc Zyngier wrote:
> > On Sun, 22 Dec 2024 03:03:53 +0000,
> > FUKAUMI Naoki <naoki at radxa.com> wrote:
> >> 
> >> Rockchip RK3582 is a scaled down version of Rockchip RK3588(S). Apply
> >> Rockchip 3588001 erratum workaround to RK3582.
> >> 
> >> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> >> ---
> >>  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 92244cfa0464..c59ce9332dc0 100644
> >> --- a/drivers/irqchip/irq-gic-v3-its.c
> >> +++ b/drivers/irqchip/irq-gic-v3-its.c
> >> @@ -4861,7 +4861,8 @@ static bool __maybe_unused
> >> its_enable_rk3588001(void *data)
> >>  {
> >>  	struct its_node *its = data;
> >> 
> >> -	if (!of_machine_is_compatible("rockchip,rk3588") &&
> >> +	if (!of_machine_is_compatible("rockchip,rk3582") &&
> >> +	    !of_machine_is_compatible("rockchip,rk3588") &&
> >>  	    !of_machine_is_compatible("rockchip,rk3588s"))
> >>  		return false;
> >> 
> > 
> > Please use the relevant property for that purpose ("dma-noncoherent")
> > at the distributor and ITS levels. We're not adding extra compatibles
> > for this anymore, and you might as well fix the core dtsi to expose
> > such property.
> 
> Thanks for your response.
> 
> After a more detailed look into drivers/irqchip/irq-gic-v3-its.c,
> it seems that relying on the "dma-noncoherent" DT property may not
> be equivalent to adding another compatible check.

It is. My email makes it plain what needs doing.

> Here are a few
> quotations from irq-gic-v3-its.c, to illustrate this better:
> 
> 4746 static bool __maybe_unused its_enable_rk3588001(void *data)
> 4747 {
> 4748         struct its_node *its = data;
> 4749
> 4750         if (!of_machine_is_compatible("rockchip,rk3588") &&
> 4751             !of_machine_is_compatible("rockchip,rk3588s"))
> 4752                 return false;
> 4753
> 4754         its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
> 4755         gic_rdists->flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE;
> 4756
> 4757         return true;
> 4758 }
> 4759
> 4760 static bool its_set_non_coherent(void *data)
> 4761 {
> 4762         struct its_node *its = data;
> 4763
> 4764         its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
> 4765         return true;
> 4766 }
> 
> 4814 #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
> 4815         {
> 4816                 .desc   = "ITS: Rockchip erratum RK3588001",
> 4817                 .iidr   = 0x0201743b,
> 4818                 .mask   = 0xffffffff,
> 4819                 .init   = its_enable_rk3588001,
> 4820         },
> 4821 #endif
> 4822         {
> 4823                 .desc   = "ITS: non-coherent attribute",
> 4824                 .property = "dma-noncoherent",
> 4825                 .init   = its_set_non_coherent,
> 4826         },

Nothing tickles me more than having my own work being thrown back at
me.

> 
> As visible above, using the "dma-noncoherent" DT property results
> in not setting the RDIST_FLAGS_FORCE_NON_SHAREABLE flag, which the
> its_enable_rk3588001() function does.  In other words, it doesn't
> seem that "dma-noncoherent" is a "drop-in" replacement for adding
> yet another compatible for the RK3582.

You clearly haven't read what I wrote. Or rather, you read what you
wanted to read, and ignored half of it.

>
> Modifying the current behavior of the "dma-noncoherent" DT property
> doesn't seem like an option, because it's already used in a couple
> of board dts(i) files.  Should we introduce another DT property,
> perhaps "dma-noncoherent-rdist" or something similar?

No. We have everything we need. Believe it or not, I actually know
what I'm talking about. I know, this is surprising. I surprise myself
sometimes.

> Could you, please, advise on how to move forward with this?  I'm

I already have.

> willing to implement the required patches, but I'd prefer to reduce
> the possible back-and-forth on them, to save everyone's time.

May I suggest that you read my email again? How about grepping through
the upstream DT collection and (shock, horror) look at the imx95.dtsi
file, which suffers from the same braindead behaviour as the RK stuff?

For clarity, let me paste it here again, and add some emphasis for
extra clarity:

> > Please use the relevant property for that purpose ("dma-noncoherent")
> > at the distributor and ITS levels. We're not adding extra compatibles
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Now, please go look at the code for real this time, appreciate how the
"dma-noncoherent" property placed at the distributor *AND* ITS levels
combine to give you the effects the hardware requires.

To sum it up: the standard properties and the Rockchip hacks are
strictly equivalent, there is no need for anything extra, and I stand
by my NAK on this very patch.

	M.

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


From peng.fan at oss.nxp.com  Sun Dec 22 16:46:13 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 23 Dec 2024 08:46:13 +0800
Subject: [PATCH v4 1/2] dt-bindings: nvmem: imx-ocotp: Introduce
 #access-controller-cells
In-Reply-To: <20241223-imx-ocotp-v4-0-f504c1420640@nxp.com>
References: <20241223-imx-ocotp-v4-0-f504c1420640@nxp.com>
Message-ID: <20241223-imx-ocotp-v4-1-f504c1420640@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Introduce "#access-controller-cells" to make OCOTP be an accessing
controller, because i.MX Family OCOTP supports a specific peripheral
or function being fused which means being disabled.

Add the i.MX[95,93] OCOTP gate index.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/nvmem/imx-ocotp.yaml       |  5 +++
 include/dt-bindings/nvmem/fsl,imx93-ocotp.h        | 24 ++++++++++++
 include/dt-bindings/nvmem/fsl,imx95-ocotp.h        | 43 ++++++++++++++++++++++
 3 files changed, 72 insertions(+)

diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
index b2cb76cf9053a883a158acaf5eaa108895818afc..c78e202ced22f1c278f7be827b71ba434832d2a7 100644
--- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
+++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
@@ -54,6 +54,11 @@ properties:
   clocks:
     maxItems: 1
 
+  "#access-controller-cells":
+    const: 1
+    description:
+      Contains the gate ID associated to the peripheral.
+
 required:
   - "#address-cells"
   - "#size-cells"
diff --git a/include/dt-bindings/nvmem/fsl,imx93-ocotp.h b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ef525173845fd4ee0e847cf5a17e53a14f71362
--- /dev/null
+++ b/include/dt-bindings/nvmem/fsl,imx93-ocotp.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+#ifndef _DT_BINDINGS_NVMEM_IMX93_OTPC_H
+#define _DT_BINDINGS_NVMEM_IMX93_OTPC_H
+
+#define IMX93_OCOTP_NPU_GATE		0
+#define IMX93_OCOTP_A550_GATE		1
+#define IMX93_OCOTP_A551_GATE		2
+#define IMX93_OCOTP_M33_GATE		3
+#define IMX93_OCOTP_CAN1_FD_GATE	4
+#define IMX93_OCOTP_CAN2_FD_GATE	5
+#define IMX93_OCOTP_CAN1_GATE		6
+#define IMX93_OCOTP_CAN2_GATE		7
+#define IMX93_OCOTP_USB1_GATE		8
+#define IMX93_OCOTP_USB2_GATE		9
+#define IMX93_OCOTP_ENET1_GATE		10
+#define IMX93_OCOTP_ENET2_GATE		11
+#define IMX93_OCOTP_PXP_GATE		12
+#define IMX93_OCOTP_MIPI_CSI1_GATE	13
+#define IMX93_OCOTP_MIPI_DSI1_GATE	14
+#define IMX93_OCOTP_LVDS1_GATE		15
+#define IMX93_OCOTP_ADC1_GATE		16
+
+#endif
diff --git a/include/dt-bindings/nvmem/fsl,imx95-ocotp.h b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d21d1f690974d0215c71352168378a150f489af
--- /dev/null
+++ b/include/dt-bindings/nvmem/fsl,imx95-ocotp.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+#ifndef _DT_BINDINGS_NVMEM_IMX95_OTPC_H
+#define _DT_BINDINGS_NVMEM_IMX95_OTPC_H
+
+#define IMX95_OCOTP_CANFD1_GATE		0
+#define IMX95_OCOTP_CANFD2_GATE		1
+#define IMX95_OCOTP_CANFD3_GATE		2
+#define IMX95_OCOTP_CANFD4_GATE		3
+#define IMX95_OCOTP_CANFD5_GATE		4
+#define IMX95_OCOTP_CAN1_GATE		5
+#define IMX95_OCOTP_CAN2_GATE		6
+#define IMX95_OCOTP_CAN3_GATE		7
+#define IMX95_OCOTP_CAN4_GATE		8
+#define IMX95_OCOTP_CAN5_GATE		9
+#define IMX95_OCOTP_NPU_GATE		10
+#define IMX95_OCOTP_A550_GATE		11
+#define IMX95_OCOTP_A551_GATE		12
+#define IMX95_OCOTP_A552_GATE		13
+#define IMX95_OCOTP_A553_GATE		14
+#define IMX95_OCOTP_A554_GATE		15
+#define IMX95_OCOTP_A555_GATE		16
+#define IMX95_OCOTP_M7_GATE		17
+#define IMX95_OCOTP_DCSS_GATE		18
+#define IMX95_OCOTP_LVDS1_GATE		19
+#define IMX95_OCOTP_ISP_GATE		20
+#define IMX95_OCOTP_USB1_GATE		21
+#define IMX95_OCOTP_USB2_GATE		22
+#define IMX95_OCOTP_NETC_GATE		23
+#define IMX95_OCOTP_PCIE1_GATE		24
+#define IMX95_OCOTP_PCIE2_GATE		25
+#define IMX95_OCOTP_ADC1_GATE		26
+#define IMX95_OCOTP_EARC_RX_GATE	27
+#define IMX95_OCOTP_GPU3D_GATE		28
+#define IMX95_OCOTP_VPU_GATE		29
+#define IMX95_OCOTP_JPEG_ENC_GATE	30
+#define IMX95_OCOTP_JPEG_DEC_GATE	31
+#define IMX95_OCOTP_MIPI_CSI1_GATE	32
+#define IMX95_OCOTP_MIPI_CSI2_GATE	33
+#define IMX95_OCOTP_MIPI_DSI1_GATE	34
+#define IMX95_OCOTP_V2X_GATE		35
+
+#endif

-- 
2.37.1



From peng.fan at oss.nxp.com  Sun Dec 22 16:46:12 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 23 Dec 2024 08:46:12 +0800
Subject: [PATCH v4 0/2] Make i.MX9 OCOTP work as accessing controller
Message-ID: <20241223-imx-ocotp-v4-0-f504c1420640@nxp.com>

Previously there was discussion on using "feature-controller" or
adding a specific node to group the fuse information for U-Boot to
parse and update node. But rejected by DT maintainer(Rob).

Since the STM32 engineers added access controller concept and landed
the support in Linux Kernel, reuse the concept for i.MX.

i.MX OCOTP eFuse has some bits to indicate a specific periphral or
function is avaiable for current chip, for example i.MX93 has variants
that not have NPU. So introduce '#access-controller-cells' for OCOTP,
and add "#access-controllers = <&ocotp [gate_index]>" for periphrals
that needs accessing control checking.

In OCOTP driver, the nodes under "/" will be iterated, and checked
if property "#access-controllers" exsits. If not allow access, detach
the node.

In the end, cpu nodes should still be handled by bootloader.
And I may also update i.MX8M to use same method to support variants
if this patchset is good.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Changes in v4:
- Add missing of_node_put(provider)
- Typo fix in commit log
- Link to v3: https://lore.kernel.org/r/20241219-imx-ocotp-v3-0-b22371098071 at nxp.com

Changes in v3:
- Add A-b for patch 1
- Use scoped API when iterate nodes and address build warning in patch 2
- I am also thinking that to drop patch 2 to let
 bootloader to iterate the nodes that have access-controllers property and
 update the nodes before booting the kernel. Then just need patch 1 for
 the binding updates. Anyway, comments are welcomed.
- Link to v2: https://lore.kernel.org/r/20241217-imx-ocotp-v2-0-3faa6cbff41b at nxp.com

Changes in v2:
- Add R-b for patch 1
- Use '/' root node instead of '/soc' or '/soc at 0' for patch 2
- Link to v1: https://lore.kernel.org/r/20241212-imx-ocotp-v1-0-198bb0af86a0 at nxp.com

---
Peng Fan (2):
      dt-bindings: nvmem: imx-ocotp: Introduce #access-controller-cells
      nvmem: imx-ocotp-ele: Support accessing controller for i.MX9

 .../devicetree/bindings/nvmem/imx-ocotp.yaml       |   5 +
 drivers/nvmem/imx-ocotp-ele.c                      | 184 ++++++++++++++++++++-
 include/dt-bindings/nvmem/fsl,imx93-ocotp.h        |  24 +++
 include/dt-bindings/nvmem/fsl,imx95-ocotp.h        |  43 +++++
 4 files changed, 255 insertions(+), 1 deletion(-)
---
base-commit: 6d13015b67d58ddba56631c56e0a6f376ade0867
change-id: 20241212-imx-ocotp-cbef304140f5

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Sun Dec 22 16:46:14 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 23 Dec 2024 08:46:14 +0800
Subject: [PATCH v4 2/2] nvmem: imx-ocotp-ele: Support accessing controller
 for i.MX9
In-Reply-To: <20241223-imx-ocotp-v4-0-f504c1420640@nxp.com>
References: <20241223-imx-ocotp-v4-0-f504c1420640@nxp.com>
Message-ID: <20241223-imx-ocotp-v4-2-f504c1420640@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX9 OCOTP supports a specific peripheral or function being fused
which means disabled, so
 - Introduce ocotp_access_gates to be container of efuse gate info
 - Iterate all nodes to check accessing permission. If not
   allowed to be accessed, detach the node

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/nvmem/imx-ocotp-ele.c | 184 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 183 insertions(+), 1 deletion(-)

diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index ca6dd71d8a2e29888c6e556aaea116c1a967cb5f..5a07d8b780ecfc13874cff338d6926d0e2a87c8a 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -5,6 +5,8 @@
  * Copyright 2023 NXP
  */
 
+#include <dt-bindings/nvmem/fsl,imx93-ocotp.h>
+#include <dt-bindings/nvmem/fsl,imx95-ocotp.h>
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -27,6 +29,7 @@ struct ocotp_map_entry {
 };
 
 struct ocotp_devtype_data {
+	const struct ocotp_access_gates *access_gates;
 	u32 reg_off;
 	char *name;
 	u32 size;
@@ -36,11 +39,26 @@ struct ocotp_devtype_data {
 	struct ocotp_map_entry entry[];
 };
 
+#define OCOTP_MAX_NUM_GATE_WORDS 4
+#define IMX93_OCOTP_NUM_GATES 17
+#define IMX95_OCOTP_NUM_GATES 36
+
+struct ocotp_access_gates {
+	u32 num_words;
+	u32 words[OCOTP_MAX_NUM_GATE_WORDS];
+	u32 num_gates;
+	struct access_gate {
+		u32 word;
+		u32 mask;
+	} gates[];
+};
+
 struct imx_ocotp_priv {
 	struct device *dev;
 	void __iomem *base;
 	struct nvmem_config config;
 	struct mutex lock;
+	u32 value[OCOTP_MAX_NUM_GATE_WORDS];
 	const struct ocotp_devtype_data *data;
 };
 
@@ -131,6 +149,97 @@ static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem,
 	cell->read_post_process = imx_ocotp_cell_pp;
 }
 
+static int imx_ele_ocotp_check_access(struct platform_device *pdev, u32 id)
+{
+	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
+	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
+	u32 word, mask;
+
+	if (id >= access_gates->num_gates) {
+		dev_err(&pdev->dev, "Index %d too large\n", id);
+		return -EACCES;
+	}
+
+	word = access_gates->gates[id].word;
+	mask = access_gates->gates[id].mask;
+
+	dev_dbg(&pdev->dev, "id:%d word:%d mask:0x%08x\n", id, word, mask);
+	/* true means not allow access */
+	if (priv->value[word] & mask)
+		return -EACCES;
+
+	return 0;
+}
+
+static int imx_ele_ocotp_grant_access(struct platform_device *pdev, struct device_node *parent)
+{
+	struct device *dev = &pdev->dev;
+
+	for_each_available_child_of_node_scoped(parent, child) {
+		struct of_phandle_iterator it;
+		int err;
+		u32 id;
+
+		of_for_each_phandle(&it, err, child, "access-controllers",
+				    "#access-controller-cells", 0) {
+			struct of_phandle_args provider_args;
+			struct device_node *provider = it.node;
+
+			if (err) {
+				dev_err(dev, "Unable to get access-controllers property for node %s\n, err: %d",
+					child->full_name, err);
+				of_node_put(provider);
+				return err;
+			}
+
+			/* Only support one cell */
+			if (of_phandle_iterator_args(&it, provider_args.args, 1) != 1) {
+				dev_err(dev, "wrong args count\n");
+				of_node_put(provider);
+				return -EINVAL;
+			}
+
+			id = provider_args.args[0];
+
+			dev_dbg(dev, "Checking node: %s gate: %d\n", child->full_name, id);
+
+			if (imx_ele_ocotp_check_access(pdev, id)) {
+				of_detach_node(child);
+				dev_err(dev, "%s: Not granted, device driver will not be probed\n",
+					child->full_name);
+			}
+		}
+
+		imx_ele_ocotp_grant_access(pdev, child);
+	}
+
+	return 0;
+}
+
+static int imx_ele_ocotp_access_control(struct platform_device *pdev)
+{
+	struct imx_ocotp_priv *priv = platform_get_drvdata(pdev);
+	struct device_node *root __free(device_node) = of_find_node_by_path("/");
+	const struct ocotp_access_gates *access_gates = priv->data->access_gates;
+	void __iomem *reg = priv->base + priv->data->reg_off;
+	u32 off;
+	int i;
+
+	if (!priv->data->access_gates)
+		return 0;
+
+	/* This should never happen */
+	WARN_ON(!root);
+
+	for (i = 0; i < access_gates->num_words; i++) {
+		off = access_gates->words[i] << 2;
+		priv->value[i] = readl(reg + off);
+		dev_dbg(&pdev->dev, "word:%d 0x%08x\n", access_gates->words[i], priv->value[i]);
+	}
+
+	return imx_ele_ocotp_grant_access(pdev, root);
+}
+
 static int imx_ele_ocotp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -161,14 +270,43 @@ static int imx_ele_ocotp_probe(struct platform_device *pdev)
 	priv->config.fixup_dt_cell_info = imx_ocotp_fixup_dt_cell_info;
 	mutex_init(&priv->lock);
 
+	platform_set_drvdata(pdev, priv);
+
 	nvmem = devm_nvmem_register(dev, &priv->config);
 	if (IS_ERR(nvmem))
 		return PTR_ERR(nvmem);
 
-	return 0;
+
+	return imx_ele_ocotp_access_control(pdev);
 }
 
+static const struct ocotp_access_gates imx93_access_gates = {
+	.num_words = 3,
+	.words = {19, 20, 21},
+	.num_gates = IMX93_OCOTP_NUM_GATES,
+	.gates = {
+		[IMX93_OCOTP_NPU_GATE]		= { .word = 19, .mask = BIT(13) },
+		[IMX93_OCOTP_A550_GATE]		= { .word = 19, .mask = BIT(14) },
+		[IMX93_OCOTP_A551_GATE]		= { .word = 19, .mask = BIT(15) },
+		[IMX93_OCOTP_M33_GATE]		= { .word = 19, .mask = BIT(24) },
+		[IMX93_OCOTP_CAN1_FD_GATE]	= { .word = 19, .mask = BIT(28) },
+		[IMX93_OCOTP_CAN2_FD_GATE]	= { .word = 19, .mask = BIT(29) },
+		[IMX93_OCOTP_CAN1_GATE]		= { .word = 19, .mask = BIT(30) },
+		[IMX93_OCOTP_CAN2_GATE]		= { .word = 19, .mask = BIT(31) },
+		[IMX93_OCOTP_USB1_GATE]		= { .word = 20, .mask = BIT(3) },
+		[IMX93_OCOTP_USB2_GATE]		= { .word = 20, .mask = BIT(4) },
+		[IMX93_OCOTP_ENET1_GATE]	= { .word = 20, .mask = BIT(5) },
+		[IMX93_OCOTP_ENET2_GATE]	= { .word = 20, .mask = BIT(6) },
+		[IMX93_OCOTP_PXP_GATE]		= { .word = 20, .mask = BIT(10) },
+		[IMX93_OCOTP_MIPI_CSI1_GATE]	= { .word = 20, .mask = BIT(17) },
+		[IMX93_OCOTP_MIPI_DSI1_GATE]	= { .word = 20, .mask = BIT(19) },
+		[IMX93_OCOTP_LVDS1_GATE]	= { .word = 20, .mask = BIT(24) },
+		[IMX93_OCOTP_ADC1_GATE]		= { .word = 21, .mask = BIT(7) },
+	},
+};
+
 static const struct ocotp_devtype_data imx93_ocotp_data = {
+	.access_gates = &imx93_access_gates,
 	.reg_off = 0x8000,
 	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,
@@ -183,7 +321,51 @@ static const struct ocotp_devtype_data imx93_ocotp_data = {
 	},
 };
 
+static const struct ocotp_access_gates imx95_access_gates = {
+	.num_words = 3,
+	.words = {17, 18, 19},
+	.num_gates = IMX95_OCOTP_NUM_GATES,
+	.gates = {
+		[IMX95_OCOTP_CANFD1_GATE]	= { .word = 17, .mask = BIT(20) },
+		[IMX95_OCOTP_CANFD2_GATE]	= { .word = 17, .mask = BIT(21) },
+		[IMX95_OCOTP_CANFD3_GATE]	= { .word = 17, .mask = BIT(22) },
+		[IMX95_OCOTP_CANFD4_GATE]	= { .word = 17, .mask = BIT(23) },
+		[IMX95_OCOTP_CANFD5_GATE]	= { .word = 17, .mask = BIT(24) },
+		[IMX95_OCOTP_CAN1_GATE]		= { .word = 17, .mask = BIT(25) },
+		[IMX95_OCOTP_CAN2_GATE]		= { .word = 17, .mask = BIT(26) },
+		[IMX95_OCOTP_CAN3_GATE]		= { .word = 17, .mask = BIT(27) },
+		[IMX95_OCOTP_CAN4_GATE]		= { .word = 17, .mask = BIT(28) },
+		[IMX95_OCOTP_CAN5_GATE]		= { .word = 17, .mask = BIT(29) },
+		[IMX95_OCOTP_NPU_GATE]		= { .word = 18, .mask = BIT(0) },
+		[IMX95_OCOTP_A550_GATE]		= { .word = 18, .mask = BIT(1) },
+		[IMX95_OCOTP_A551_GATE]		= { .word = 18, .mask = BIT(2) },
+		[IMX95_OCOTP_A552_GATE]		= { .word = 18, .mask = BIT(3) },
+		[IMX95_OCOTP_A553_GATE]		= { .word = 18, .mask = BIT(4) },
+		[IMX95_OCOTP_A554_GATE]		= { .word = 18, .mask = BIT(5) },
+		[IMX95_OCOTP_A555_GATE]		= { .word = 18, .mask = BIT(6) },
+		[IMX95_OCOTP_M7_GATE]		= { .word = 18, .mask = BIT(9) },
+		[IMX95_OCOTP_DCSS_GATE]		= { .word = 18, .mask = BIT(22) },
+		[IMX95_OCOTP_LVDS1_GATE]	= { .word = 18, .mask = BIT(27) },
+		[IMX95_OCOTP_ISP_GATE]		= { .word = 18, .mask = BIT(29) },
+		[IMX95_OCOTP_USB1_GATE]		= { .word = 19, .mask = BIT(2) },
+		[IMX95_OCOTP_USB2_GATE]		= { .word = 19, .mask = BIT(3) },
+		[IMX95_OCOTP_NETC_GATE]		= { .word = 19, .mask = BIT(4) },
+		[IMX95_OCOTP_PCIE1_GATE]	= { .word = 19, .mask = BIT(6) },
+		[IMX95_OCOTP_PCIE2_GATE]	= { .word = 19, .mask = BIT(7) },
+		[IMX95_OCOTP_ADC1_GATE]		= { .word = 19, .mask = BIT(8) },
+		[IMX95_OCOTP_EARC_RX_GATE]	= { .word = 19, .mask = BIT(11) },
+		[IMX95_OCOTP_GPU3D_GATE]	= { .word = 19, .mask = BIT(16) },
+		[IMX95_OCOTP_VPU_GATE]		= { .word = 19, .mask = BIT(17) },
+		[IMX95_OCOTP_JPEG_ENC_GATE]	= { .word = 19, .mask = BIT(18) },
+		[IMX95_OCOTP_JPEG_DEC_GATE]	= { .word = 19, .mask = BIT(19) },
+		[IMX95_OCOTP_MIPI_CSI1_GATE]	= { .word = 19, .mask = BIT(21) },
+		[IMX95_OCOTP_MIPI_CSI2_GATE]	= { .word = 19, .mask = BIT(22) },
+		[IMX95_OCOTP_MIPI_DSI1_GATE]	= { .word = 19, .mask = BIT(23) },
+	}
+};
+
 static const struct ocotp_devtype_data imx95_ocotp_data = {
+	.access_gates = &imx95_access_gates,
 	.reg_off = 0x8000,
 	.reg_read = imx_ocotp_reg_read,
 	.size = 2048,

-- 
2.37.1



From inochiama at gmail.com  Sun Dec 22 16:58:38 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Mon, 23 Dec 2024 08:58:38 +0800
Subject: [PATCH net-next v3 2/3] net: stmmac: platform: Add snps,dwmac-5.30a IP compatible string
In-Reply-To: <20241223005843.483805-1-inochiama@gmail.com>
References: <20241223005843.483805-1-inochiama@gmail.com>
Message-ID: <20241223005843.483805-3-inochiama@gmail.com>

Add "snps,dwmac-5.30a" compatible string for 5.30a version that can avoid
to define some platform data in the glue layer.

Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
---
 .../ethernet/stmicro/stmmac/stmmac_platform.c   | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 3ac32444e492..6ce3e538ce0a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -421,6 +421,17 @@ static void stmmac_remove_config_dt(struct platform_device *pdev,
 	of_node_put(plat->mdio_node);
 }
 
+/* Compatible string array for all gmac4 devices */
+static const char * const stmmac_gmac4_compats[] = {
+	"snps,dwmac-4.00",
+	"snps,dwmac-4.10a",
+	"snps,dwmac-4.20a",
+	"snps,dwmac-5.10a",
+	"snps,dwmac-5.20",
+	"snps,dwmac-5.30a",
+	NULL
+};
+
 /**
  * stmmac_probe_config_dt - parse device-tree driver parameters
  * @pdev: platform_device structure
@@ -552,11 +563,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 		plat->pmt = 1;
 	}
 
-	if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
-	    of_device_is_compatible(np, "snps,dwmac-4.10a") ||
-	    of_device_is_compatible(np, "snps,dwmac-4.20a") ||
-	    of_device_is_compatible(np, "snps,dwmac-5.10a") ||
-	    of_device_is_compatible(np, "snps,dwmac-5.20")) {
+	if (of_device_compatible_match(np, stmmac_gmac4_compats)) {
 		plat->has_gmac4 = 1;
 		plat->has_gmac = 0;
 		plat->pmt = 1;
-- 
2.47.1



From inochiama at gmail.com  Sun Dec 22 16:58:36 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Mon, 23 Dec 2024 08:58:36 +0800
Subject: [PATCH net-next v3 0/3] riscv: sophgo: Add ethernet support for SG2044
Message-ID: <20241223005843.483805-1-inochiama@gmail.com>

The ethernet controller of SG2044 is Synopsys DesignWare IP with
custom clock. Add glue layer for it.

Since v2, these patch depends on that following patch that provides
helper function to compute rgmii clock, As for now, this patch is merged
in net/for-next
https://lore.kernel.org/netdev/173380743727.355055.17303486442146316315.git-patchwork-notify at kernel.org/

Changed from RFC:
- https://lore.kernel.org/netdev/20241101014327.513732-1-inochiama at gmail.com/
1. patch 1: apply Krzysztof' tag

Changed from v2:
- https://lore.kernel.org/netdev/20241025011000.244350-1-inochiama at gmail.com/
1. patch 1: merge the first and the second bindings patch to show the all
            compatible change.
2. patch 2: use of_device_compatible_match helper function to perform check.
2. patch 3: remove unused include and sort the left.
3. patch 3: fix wrong variable usage in sophgo_dwmac_fix_mac_speed
4. patch 3: drop unused variable in the patch.

Changed from v1:
- https://lore.kernel.org/netdev/20241021103617.653386-1-inochiama at gmail.com/
1. patch 2: remove sophgo,syscon as this mac delay is resolved.
2. patch 2: apply all the properties unconditionally.
3. patch 4: remove sophgo,syscon code as this mac delay is resolved.
4. patch 4: use the helper function to compute rgmii clock.
5. patch 4: use remove instead of remove_new for the platform driver.


Inochi Amaoto (3):
  dt-bindings: net: Add support for Sophgo SG2044 dwmac
  net: stmmac: platform: Add snps,dwmac-5.30a IP compatible string
  net: stmmac: Add glue layer for Sophgo SG2044 SoC

 .../devicetree/bindings/net/snps,dwmac.yaml   |   4 +
 .../bindings/net/sophgo,sg2044-dwmac.yaml     | 124 ++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../ethernet/stmicro/stmmac/dwmac-sophgo.c    | 105 +++++++++++++++
 .../ethernet/stmicro/stmmac/stmmac_platform.c |  17 ++-
 6 files changed, 257 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c

--
2.47.1



From inochiama at gmail.com  Sun Dec 22 16:58:37 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Mon, 23 Dec 2024 08:58:37 +0800
Subject: [PATCH net-next v3 1/3] dt-bindings: net: Add support for Sophgo SG2044 dwmac
In-Reply-To: <20241223005843.483805-1-inochiama@gmail.com>
References: <20241223005843.483805-1-inochiama@gmail.com>
Message-ID: <20241223005843.483805-2-inochiama@gmail.com>

The GMAC IP on SG2044 is almost a standard Synopsys DesignWare
MAC (version 5.30a) with some extra clock.

Add necessary compatible string for this device.

Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../devicetree/bindings/net/snps,dwmac.yaml   |   4 +
 .../bindings/net/sophgo,sg2044-dwmac.yaml     | 124 ++++++++++++++++++
 2 files changed, 128 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml

diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index eb1f3ae41ab9..cd112ef6b3bf 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -32,6 +32,7 @@ select:
           - snps,dwmac-4.20a
           - snps,dwmac-5.10a
           - snps,dwmac-5.20
+          - snps,dwmac-5.30a
           - snps,dwxgmac
           - snps,dwxgmac-2.10
 
@@ -97,8 +98,10 @@ properties:
         - snps,dwmac-4.20a
         - snps,dwmac-5.10a
         - snps,dwmac-5.20
+        - snps,dwmac-5.30a
         - snps,dwxgmac
         - snps,dwxgmac-2.10
+        - sophgo,sg2044-dwmac
         - starfive,jh7100-dwmac
         - starfive,jh7110-dwmac
         - thead,th1520-gmac
@@ -630,6 +633,7 @@ allOf:
                 - snps,dwmac-4.20a
                 - snps,dwmac-5.10a
                 - snps,dwmac-5.20
+                - snps,dwmac-5.30a
                 - snps,dwxgmac
                 - snps,dwxgmac-2.10
                 - st,spear600-gmac
diff --git a/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml b/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
new file mode 100644
index 000000000000..b7e4216ea45a
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/sophgo,sg2044-dwmac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo SG2044 DWMAC glue layer
+
+maintainers:
+  - Inochi Amaoto <inochiama at gmail.com>
+
+select:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - sophgo,sg2044-dwmac
+  required:
+    - compatible
+
+properties:
+  compatible:
+    items:
+      - const: sophgo,sg2044-dwmac
+      - const: snps,dwmac-5.30a
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: GMAC main clock
+      - description: PTP clock
+      - description: TX clock
+
+  clock-names:
+    items:
+      - const: stmmaceth
+      - const: ptp_ref
+      - const: tx
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-names:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: stmmaceth
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - interrupt-names
+  - resets
+  - reset-names
+
+allOf:
+  - $ref: snps,dwmac.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    ethernet at 30006000 {
+      compatible = "sophgo,sg2044-dwmac", "snps,dwmac-5.30a";
+      reg = <0x30006000 0x4000>;
+      clocks = <&clk 151>, <&clk 152>, <&clk 154>;
+      clock-names = "stmmaceth", "ptp_ref", "tx";
+      interrupt-parent = <&intc>;
+      interrupts = <296 IRQ_TYPE_LEVEL_HIGH>;
+      interrupt-names = "macirq";
+      resets = <&rst 30>;
+      reset-names = "stmmaceth";
+      snps,multicast-filter-bins = <0>;
+      snps,perfect-filter-entries = <1>;
+      snps,aal;
+      snps,tso;
+      snps,txpbl = <32>;
+      snps,rxpbl = <32>;
+      snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
+      snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
+      snps,axi-config = <&gmac0_stmmac_axi_setup>;
+      status = "disabled";
+
+      gmac0_mtl_rx_setup: rx-queues-config {
+        snps,rx-queues-to-use = <8>;
+        snps,rx-sched-wsp;
+        queue0 {};
+        queue1 {};
+        queue2 {};
+        queue3 {};
+        queue4 {};
+        queue5 {};
+        queue6 {};
+        queue7 {};
+      };
+
+      gmac0_mtl_tx_setup: tx-queues-config {
+        snps,tx-queues-to-use = <8>;
+        queue0 {};
+        queue1 {};
+        queue2 {};
+        queue3 {};
+        queue4 {};
+        queue5 {};
+        queue6 {};
+        queue7 {};
+      };
+
+      gmac0_stmmac_axi_setup: stmmac-axi-config {
+        snps,blen = <16 8 4 0 0 0 0>;
+        snps,wr_osr_lmt = <1>;
+        snps,rd_osr_lmt = <2>;
+      };
+    };
-- 
2.47.1



From inochiama at gmail.com  Sun Dec 22 16:58:39 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Mon, 23 Dec 2024 08:58:39 +0800
Subject: [PATCH net-next v3 3/3] net: stmmac: Add glue layer for Sophgo SG2044 SoC
In-Reply-To: <20241223005843.483805-1-inochiama@gmail.com>
References: <20241223005843.483805-1-inochiama@gmail.com>
Message-ID: <20241223005843.483805-4-inochiama@gmail.com>

Adds Sophgo dwmac driver support on the Sophgo SG2044 SoC.

Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../ethernet/stmicro/stmmac/dwmac-sophgo.c    | 105 ++++++++++++++++++
 3 files changed, 117 insertions(+)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 6658536a4e17..23085d27ace6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -169,6 +169,17 @@ config DWMAC_SOCFPGA
 	  for the stmmac device driver. This driver is used for
 	  arria5 and cyclone5 FPGA SoCs.
 
+config DWMAC_SOPHGO
+	tristate "Sophgo dwmac support"
+	depends on OF && (ARCH_SOPHGO || COMPILE_TEST)
+	default m if ARCH_SOPHGO
+	help
+	  Support for ethernet controllers on Sophgo RISC-V SoCs
+
+	  This selects the Sophgo SoC specific glue layer support
+	  for the stmmac device driver. This driver is used for the
+	  ethernet controllers on various Sophgo SoCs.
+
 config DWMAC_STARFIVE
 	tristate "StarFive dwmac support"
 	depends on OF && (ARCH_STARFIVE || COMPILE_TEST)
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 2389fd261344..36f21c86568d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-ethqos.o
 obj-$(CONFIG_DWMAC_ROCKCHIP)	+= dwmac-rk.o
 obj-$(CONFIG_DWMAC_RZN1)	+= dwmac-rzn1.o
 obj-$(CONFIG_DWMAC_SOCFPGA)	+= dwmac-altr-socfpga.o
+obj-$(CONFIG_DWMAC_SOPHGO)	+= dwmac-sophgo.o
 obj-$(CONFIG_DWMAC_STARFIVE)	+= dwmac-starfive.o
 obj-$(CONFIG_DWMAC_STI)		+= dwmac-sti.o
 obj-$(CONFIG_DWMAC_STM32)	+= dwmac-stm32.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c
new file mode 100644
index 000000000000..a4997cc0294a
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Sophgo DWMAC platform driver
+ *
+ * Copyright (C) 2024 Inochi Amaoto <inochiama at gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/mod_devicetable.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+
+#include "stmmac_platform.h"
+
+struct sophgo_dwmac {
+	struct device *dev;
+	struct clk *clk_tx;
+};
+
+static void sophgo_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
+{
+	struct sophgo_dwmac *dwmac = priv;
+	long rate;
+	int ret;
+
+	rate = rgmii_clock(speed);
+	if (rate < 0) {
+		dev_err(dwmac->dev, "invalid speed %u\n", speed);
+		return;
+	}
+
+	ret = clk_set_rate(dwmac->clk_tx, rate);
+	if (ret)
+		dev_err(dwmac->dev, "failed to set tx rate %lu: %pe\n",
+			rate, ERR_PTR(ret));
+}
+
+static int sophgo_sg2044_dwmac_init(struct platform_device *pdev,
+				    struct plat_stmmacenet_data *plat_dat,
+				    struct stmmac_resources *stmmac_res)
+{
+	struct sophgo_dwmac *dwmac;
+
+	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
+	if (!dwmac)
+		return -ENOMEM;
+
+	dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx");
+	if (IS_ERR(dwmac->clk_tx))
+		return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx),
+				     "failed to get tx clock\n");
+
+	dwmac->dev = &pdev->dev;
+	plat_dat->bsp_priv = dwmac;
+	plat_dat->flags |= STMMAC_FLAG_SPH_DISABLE;
+	plat_dat->fix_mac_speed = sophgo_dwmac_fix_mac_speed;
+	plat_dat->multicast_filter_bins = 0;
+	plat_dat->unicast_filter_entries = 1;
+
+	return 0;
+}
+
+static int sophgo_dwmac_probe(struct platform_device *pdev)
+{
+	struct plat_stmmacenet_data *plat_dat;
+	struct stmmac_resources stmmac_res;
+	int ret;
+
+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to get resources\n");
+
+	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	if (IS_ERR(plat_dat))
+		return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
+				     "dt configuration failed\n");
+
+	ret = sophgo_sg2044_dwmac_init(pdev, plat_dat, &stmmac_res);
+	if (ret)
+		return ret;
+
+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+}
+
+static const struct of_device_id sophgo_dwmac_match[] = {
+	{ .compatible = "sophgo,sg2044-dwmac" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sophgo_dwmac_match);
+
+static struct platform_driver sophgo_dwmac_driver = {
+	.probe  = sophgo_dwmac_probe,
+	.remove = stmmac_pltfr_remove,
+	.driver = {
+		.name = "sophgo-dwmac",
+		.pm = &stmmac_pltfr_pm_ops,
+		.of_match_table = sophgo_dwmac_match,
+	},
+};
+module_platform_driver(sophgo_dwmac_driver);
+
+MODULE_AUTHOR("Inochi Amaoto <inochiama at gmail.com>");
+MODULE_DESCRIPTION("Sophgo DWMAC platform driver");
+MODULE_LICENSE("GPL");
-- 
2.47.1



From zmw12306 at gmail.com  Sun Dec 22 18:06:29 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Sun, 22 Dec 2024 21:06:29 -0500
Subject: [PATCH v6] pinctrl: stm32: Add check for clk_enable()
Message-ID: <20241223020629.3471182-1-zmw12306@gmail.com>

Convert the driver to clk_bulk*() API.
Add check for the return value of clk_bulk_enable() to catch
the potential error.

Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested")
Signed-off-by: Mingwei Zheng <zmw12306 at gmail.com>
Signed-off-by: Jiasheng Jiang <jiashengjiangcool at gmail.com>
---
Changelog:
v5 -> v6:
1. Call devm_clk_bulk_get_all in stm32_pctl_probe().

v4 -> v5:
1. Move the clock handling from stm32_gpiolib_register_bank()
and moving it to its caller.
2. Call clk_bulk_prepare_enable() in stm32_pctl_probe() 
and clk_bulk_disable_unprepare() for error.

v3 -> v4:
1. Add initialization for pctl->clks.
2. Adjust alignment.

v2 -> v3:

1. Convert clk_disable_unprepare to clk_bulk_disable
and clk_bulk_unprepare.

v1 -> v2:

1. Move int ret declaration into if block.
---
 drivers/pinctrl/stm32/pinctrl-stm32.c | 64 ++++++++++-----------------
 1 file changed, 24 insertions(+), 40 deletions(-)

diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index 5b7fa77c1184..3efe976adf84 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -86,7 +86,6 @@ struct stm32_pinctrl_group {
 
 struct stm32_gpio_bank {
 	void __iomem *base;
-	struct clk *clk;
 	struct reset_control *rstc;
 	spinlock_t lock;
 	struct gpio_chip gpio_chip;
@@ -108,6 +107,7 @@ struct stm32_pinctrl {
 	unsigned ngroups;
 	const char **grp_names;
 	struct stm32_gpio_bank *banks;
+	struct clk_bulk_data *clks;
 	unsigned nbanks;
 	const struct stm32_pinctrl_match_data *match_data;
 	struct irq_domain	*domain;
@@ -1308,12 +1308,6 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	if (IS_ERR(bank->base))
 		return PTR_ERR(bank->base);
 
-	err = clk_prepare_enable(bank->clk);
-	if (err) {
-		dev_err(dev, "failed to prepare_enable clk (%d)\n", err);
-		return err;
-	}
-
 	bank->gpio_chip = stm32_gpio_template;
 
 	fwnode_property_read_string(fwnode, "st,bank-name", &bank->gpio_chip.label);
@@ -1360,26 +1354,21 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 							   bank->fwnode, &stm32_gpio_domain_ops,
 							   bank);
 
-		if (!bank->domain) {
-			err = -ENODEV;
-			goto err_clk;
-		}
+		if (!bank->domain)
+			return -ENODEV;
 	}
 
 	names = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL);
-	if (!names) {
-		err = -ENOMEM;
-		goto err_clk;
-	}
+	if (!names)
+		return -ENOMEM;
 
 	for (i = 0; i < npins; i++) {
 		stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i);
 		if (stm32_pin && stm32_pin->pin.name) {
 			names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name);
-			if (!names[i]) {
-				err = -ENOMEM;
-				goto err_clk;
-			}
+			if (!names[i])
+				return -ENOMEM;
+
 		} else {
 			names[i] = NULL;
 		}
@@ -1390,15 +1379,11 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 	err = gpiochip_add_data(&bank->gpio_chip, bank);
 	if (err) {
 		dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_nr);
-		goto err_clk;
+		return err;
 	}
 
 	dev_info(dev, "%s bank added\n", bank->gpio_chip.label);
 	return 0;
-
-err_clk:
-	clk_disable_unprepare(bank->clk);
-	return err;
 }
 
 static struct irq_domain *stm32_pctrl_get_irq_domain(struct platform_device *pdev)
@@ -1621,6 +1606,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
 	if (!pctl->banks)
 		return -ENOMEM;
 
+	ret = devm_clk_bulk_get_all(dev, &pctl->clks);
+	if (ret < 0)
+		return ret;
+
 	i = 0;
 	for_each_gpiochip_node(dev, child) {
 		struct stm32_gpio_bank *bank = &pctl->banks[i];
@@ -1631,13 +1620,6 @@ int stm32_pctl_probe(struct platform_device *pdev)
 			fwnode_handle_put(child);
 			return -EPROBE_DEFER;
 		}
-
-		bank->clk = of_clk_get_by_name(np, NULL);
-		if (IS_ERR(bank->clk)) {
-			fwnode_handle_put(child);
-			return dev_err_probe(dev, PTR_ERR(bank->clk),
-					     "failed to get clk\n");
-		}
 		i++;
 	}
 
@@ -1646,15 +1628,18 @@ int stm32_pctl_probe(struct platform_device *pdev)
 		if (ret) {
 			fwnode_handle_put(child);
 
-			for (i = 0; i < pctl->nbanks; i++)
-				clk_disable_unprepare(pctl->banks[i].clk);
-
 			return ret;
 		}
 
 		pctl->nbanks++;
 	}
 
+	ret = clk_bulk_prepare_enable(pctl->nbanks, pctl->clks);
+	if (ret) {
+		dev_err(dev, "failed to prepare_enable clk (%d)\n", ret);
+		return ret;
+	}
+
 	dev_info(dev, "Pinctrl STM32 initialized\n");
 
 	return 0;
@@ -1726,10 +1711,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
 int __maybe_unused stm32_pinctrl_suspend(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
-	int i;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_disable(pctl->banks[i].clk);
+	clk_bulk_disable(pctl->nbanks, pctl->clks);
 
 	return 0;
 }
@@ -1738,10 +1721,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev)
 {
 	struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
 	struct stm32_pinctrl_group *g = pctl->groups;
-	int i;
+	int i, ret;
 
-	for (i = 0; i < pctl->nbanks; i++)
-		clk_enable(pctl->banks[i].clk);
+	ret = clk_bulk_enable(pctl->nbanks, pctl->clks);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < pctl->ngroups; i++, g++)
 		stm32_pinctrl_restore_gpio_regs(pctl, g->pin);
-- 
2.34.1



From pankaj.dubey at samsung.com  Sun Dec 22 18:11:07 2024
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 23 Dec 2024 07:41:07 +0530
Subject: [PATCH v2 1/3] mfd: syscon: Fix race in
 device_node_get_regmap()
In-Reply-To: <20241217-syscon-fixes-v2-1-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
	<CGME20241217181202epcas5p3dfeeea922cd1a71840ac126ddf20c644@epcas5p3.samsung.com>
	<20241217-syscon-fixes-v2-1-4f56d750541d@kernel.org>
Message-ID: <000001db54df$ef602f60$ce208e20$@samsung.com>



> -----Original Message-----
> From: Rob Herring (Arm) <robh at kernel.org>
> Sent: Tuesday, December 17, 2024 11:42 PM
> To: Lee Jones <lee at kernel.org>; Arnd Bergmann <arnd at arndb.de>; Pankaj
> Dubey <pankaj.dubey at samsung.com>; Heiko Stuebner <heiko at sntech.de>;
> Liviu Dudau <liviu.dudau at arm.com>; Sudeep Holla <sudeep.holla at arm.com>;
> Lorenzo Pieralisi <lpieralisi at kernel.org>
> Cc: Peter Griffin <peter.griffin at linaro.org>; Will McVicker
> <willmcvicker at google.com>; John Madieu <john.madieu.xa at bp.renesas.com>;
> Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: [PATCH v2 1/3] mfd: syscon: Fix race in device_node_get_regmap()
> 
> It is possible for multiple, simultaneous callers calling
> device_node_get_regmap() with the same node to fail to find an entry in the
> syscon_list. There is a period of time while the first caller is calling
> of_syscon_register() that subsequent callers also fail to find an entry in the
> syscon_list and then call of_syscon_register() a second time.
> 
> Fix this by keeping the lock held until after of_syscon_register() completes and
> adds the node to syscon_list. Convert the spinlock to a mutex as many of the
> functions called in of_syscon_register() such as
> kzalloc() and of_clk_get() may sleep.
> 
> Fixes: bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform
> devices")
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
> ---

Tested on arm64: Tesla FSD 

Tested-by: Pankaj Dubey <pankaj.dubey at samsung.com>

Thanks.
Pankaj Dubey



From naoki at radxa.com  Sun Dec 22 18:13:34 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 23 Dec 2024 11:13:34 +0900
Subject: [PATCH 2/3] dt-bindings: arm: rockchip: Add Radxa E52C
In-Reply-To: <20241222-wrench-chill-cbe767f2bd90@spud>
References: <20241222030355.2246-1-naoki@radxa.com>
 <20241222030355.2246-3-naoki@radxa.com>
 <20241222-wrench-chill-cbe767f2bd90@spud>
Message-ID: <88BD6226B9AC9C20+0d5797df-2163-44ca-b6f5-4b33a1ff0517@radxa.com>

Hi Conor,

Thank you for your ack.

I fixed the patch so I didn't add your A-b in v2.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 12/22/24 22:11, Conor Dooley wrote:
> On Sun, Dec 22, 2024 at 03:03:54AM +0000, FUKAUMI Naoki wrote:
>> Add devicetree binding for the Radxa E52C.
>>
>> Radxa E52C is a compact network computer based on the Rockchip RK3582
>> SoC.
>>
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> 
> 
> Acked-by: Conor Dooley <conor.dooley at microchip.com>



From pankaj.dubey at samsung.com  Sun Dec 22 18:13:18 2024
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 23 Dec 2024 07:43:18 +0530
Subject: [PATCH v2 2/3] mfd: syscon: Remove the platform driver support
In-Reply-To: <20241217-syscon-fixes-v2-2-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
	<CGME20241217181203epcas5p31615da7f180dd769388c5c8e8afbb1ea@epcas5p3.samsung.com>
	<20241217-syscon-fixes-v2-2-4f56d750541d@kernel.org>
Message-ID: <000101db54e0$3d4b15a0$b7e140e0$@samsung.com>



> -----Original Message-----
> From: Rob Herring (Arm) <robh at kernel.org>
> Sent: Tuesday, December 17, 2024 11:42 PM
> To: Lee Jones <lee at kernel.org>; Arnd Bergmann <arnd at arndb.de>; Pankaj
> Dubey <pankaj.dubey at samsung.com>; Heiko Stuebner <heiko at sntech.de>;
> Liviu Dudau <liviu.dudau at arm.com>; Sudeep Holla <sudeep.holla at arm.com>;
> Lorenzo Pieralisi <lpieralisi at kernel.org>
> Cc: Peter Griffin <peter.griffin at linaro.org>; Will McVicker
> <willmcvicker at google.com>; John Madieu <john.madieu.xa at bp.renesas.com>;
> Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: [PATCH v2 2/3] mfd: syscon: Remove the platform driver support
> 
> The platform driver is dead code. It is not used by DT platforms since commit
> bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform devices")
> which said:
> 
>     For non-DT based platforms, this patch keeps syscon platform driver
>     structure so that syscon can be probed and such non-DT based drivers
>     can use syscon_regmap_lookup_by_pdev API and access regmap handles.
>     Once all users of "syscon_regmap_lookup_by_pdev" migrated to DT based,
>     we can completely remove platform driver of syscon, and keep only helper
>     functions to get regmap handles.
> 
> The last user of syscon_regmap_lookup_by_pdevname() was removed in 2018.
> syscon_regmap_lookup_by_pdevname() was then removed in 2019, but that
> commit failed to remove the rest of the platform driver.
> 
> Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
> ---

Reviewed-by: Pankaj Dubey <pankaj.dubey at samsung.com>

Tested on arm64: Tesla FSD

Tested-by: Pankaj Dubey <pankaj.dubey at samsung.com>

Thanks,
Pankaj Dubey



From pankaj.dubey at samsung.com  Sun Dec 22 18:14:25 2024
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 23 Dec 2024 07:44:25 +0530
Subject: [PATCH v2 1/3] mfd: syscon: Fix race in
 device_node_get_regmap()
In-Reply-To: <20241217-syscon-fixes-v2-1-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
	<CGME20241217181202epcas5p3dfeeea922cd1a71840ac126ddf20c644@epcas5p3.samsung.com>
	<20241217-syscon-fixes-v2-1-4f56d750541d@kernel.org>
Message-ID: <000201db54e0$64f8dc40$2eea94c0$@samsung.com>



> -----Original Message-----
> From: Rob Herring (Arm) <robh at kernel.org>
> Sent: Tuesday, December 17, 2024 11:42 PM
> To: Lee Jones <lee at kernel.org>; Arnd Bergmann <arnd at arndb.de>; Pankaj
> Dubey <pankaj.dubey at samsung.com>; Heiko Stuebner <heiko at sntech.de>;
> Liviu Dudau <liviu.dudau at arm.com>; Sudeep Holla <sudeep.holla at arm.com>;
> Lorenzo Pieralisi <lpieralisi at kernel.org>
> Cc: Peter Griffin <peter.griffin at linaro.org>; Will McVicker
> <willmcvicker at google.com>; John Madieu <john.madieu.xa at bp.renesas.com>;
> Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: [PATCH v2 1/3] mfd: syscon: Fix race in device_node_get_regmap()
> 
> It is possible for multiple, simultaneous callers calling
> device_node_get_regmap() with the same node to fail to find an entry in the
> syscon_list. There is a period of time while the first caller is calling
> of_syscon_register() that subsequent callers also fail to find an entry in the
> syscon_list and then call of_syscon_register() a second time.
> 
> Fix this by keeping the lock held until after of_syscon_register() completes and
> adds the node to syscon_list. Convert the spinlock to a mutex as many of the
> functions called in of_syscon_register() such as
> kzalloc() and of_clk_get() may sleep.
> 
> Fixes: bdb0066df96e ("mfd: syscon: Decouple syscon interface from platform
> devices")
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
> ---

Reviewed-by: Pankaj Dubey <pankaj.dubey at samsung.com>



From pankaj.dubey at samsung.com  Sun Dec 22 18:16:11 2024
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 23 Dec 2024 07:46:11 +0530
Subject: [PATCH v2 3/3] mfd: syscon: Allow syscon nodes without a
 "syscon" compatible
In-Reply-To: <20241217-syscon-fixes-v2-3-4f56d750541d@kernel.org>
References: <20241217-syscon-fixes-v2-0-4f56d750541d@kernel.org>
	<CGME20241217181206epcas5p281ddcf5e06cf1d9a76eb101597d6980e@epcas5p2.samsung.com>
	<20241217-syscon-fixes-v2-3-4f56d750541d@kernel.org>
Message-ID: <000301db54e0$a45912b0$ed0b3810$@samsung.com>



> -----Original Message-----
> From: Rob Herring (Arm) <robh at kernel.org>
> Sent: Tuesday, December 17, 2024 11:42 PM
> To: Lee Jones <lee at kernel.org>; Arnd Bergmann <arnd at arndb.de>; Pankaj
> Dubey <pankaj.dubey at samsung.com>; Heiko Stuebner <heiko at sntech.de>;
> Liviu Dudau <liviu.dudau at arm.com>; Sudeep Holla <sudeep.holla at arm.com>;
> Lorenzo Pieralisi <lpieralisi at kernel.org>
> Cc: Peter Griffin <peter.griffin at linaro.org>; Will McVicker
> <willmcvicker at google.com>; John Madieu <john.madieu.xa at bp.renesas.com>;
> Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: [PATCH v2 3/3] mfd: syscon: Allow syscon nodes without a "syscon"
> compatible
> 
> of_syscon_register_regmap() was added for nodes which need a custom regmap
> setup. It's not really correct for those nodes to claim they are compatible with
> "syscon" as the default handling likely doesn't work in those cases. If
> device_node_get_regmap() happens to be called first, then of_syscon_register()
> will be called and an incorrect regmap will be created (barring some other error).
> That may lead to unknown results in the worst case. In the best case,
> of_syscon_register_regmap() will fail with -EEXIST. This problem remains unless
> these cases drop "syscon" (an ABI issue) or we exclude them using their specific
> compatible. ATM, there is only one user: "google,gs101-pmu"
> 
> There are also cases of adding "syscon" compatible to existing nodes after the
> fact in order to register the syscon. That presents a potential DT ABI problem.
> Instead, if there's a kernel change needing a syscon for a node, then it should be
> possible to allow the kernel to register a syscon without a DT change. That's
> only possible by using
> of_syscon_register_regmap() currently, but in the future we may want to
> support a match list for cases which don't need a custom regmap.
> 
> With this change, the lookup functions will succeed for any node registered by
> of_syscon_register_regmap() regardless of whether the node compatible
> contains "syscon".
> 
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
> ---

Reviewed-by: Pankaj Dubey <pankaj.dubey at samsung.com>

Thanks,
Pankaj Dubey



From naoki at radxa.com  Sun Dec 22 18:18:19 2024
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 23 Dec 2024 11:18:19 +0900
Subject: [PATCH 1/1] arm64: dts: rockchip: default to host mode for USB on
 Radxa E25
In-Reply-To: <20241222043027.265865-1-amadeus@jmu.edu.cn>
References: <6EFDC4E74A617E25+ed534e8a-fef0-4f09-a24b-a536b7f2f13b@radxa.com>
 <20241222043027.265865-1-amadeus@jmu.edu.cn>
Message-ID: <4D8217DF36191C3E+be8bbb4f-ea52-4f81-8501-ff551f54621c@radxa.com>

Hi Chukun,

On 12/22/24 13:30, Chukun Pan wrote:
> Hi,
>> Could you check Product Brief P.4?
>>
>>   https://dl.radxa.com/cm3i/e25/radxa_e25_product_brief.pdf
>>
>> There is "USB3.0 OTG Switch".
>>
>> Best regards,
> 
> Oh, sorry, it was covered by the shell so I didn't notice it.
> BTW do you see any issues in the sd-uhs-sdr104 mode?

I've been using the uSD card for a long time as a bootloader only, so I 
don't know what the problem is.

Do you have any information on how to reproduce the problem?

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Thanks,
> Chukun
> 



From zmw12306 at gmail.com  Sun Dec 22 18:23:43 2024
From: zmw12306 at gmail.com (Mingwei Zheng)
Date: Sun, 22 Dec 2024 21:23:43 -0500
Subject: [PATCH v5] pinctrl: stm32: Add check for clk_enable()
In-Reply-To: <9745b3ee-ae89-4edb-8ff7-b20096dbe1de@denx.de>
References: <20241215204014.4076659-1-zmw12306@gmail.com> <9745b3ee-ae89-4edb-8ff7-b20096dbe1de@denx.de>
Message-ID: <CAN4iqtRuj9M=GzFbY-hY4Ks3ktSKfA2W5yLT19vkJ2CSe1it9Q@mail.gmail.com>

Hi Marek,

On Sun, Dec 15, 2024 at 6:54?PM Marek Vasut <marex at denx.de> wrote:
>
> On 12/15/24 9:40 PM, Mingwei Zheng wrote:
>
> [...]
>
> > @@ -1617,10 +1602,18 @@ int stm32_pctl_probe(struct platform_device *pdev)
> >               return -EINVAL;
> >       }
> >       pctl->banks = devm_kcalloc(dev, banks, sizeof(*pctl->banks),
> > -                     GFP_KERNEL);
> > +                                GFP_KERNEL);
>
> Please drop this one change.

Fixed in PATCH v6.

>
> >       if (!pctl->banks)
> >               return -ENOMEM;
> >
> > +     pctl->clks = devm_kcalloc(dev, banks, sizeof(*pctl->clks),
> > +                               GFP_KERNEL);
> > +     if (!pctl->clks)
> > +             return -ENOMEM;
> > +
> > +     for (i = 0; i < banks; ++i)
> > +             pctl->clks[i].id = "";
>
> Is this ^ assignment necessary ? If so, why ?
>
> [...]

Thanks for pointing this out. We call devm_clk_bulk_get_all in
stm32_pctl_probe() to handle get clk in PATCH v6.

Best,
Mingwei


From jinjian.song at fibocom.com  Sun Dec 22 18:24:18 2024
From: jinjian.song at fibocom.com (Jinjian Song)
Date: Mon, 23 Dec 2024 10:24:18 +0800
Subject: [net v2] net: wwan: t7xx: Fix FSM command timeout issue
In-Reply-To: <20241220085027.7692-1-jinjian.song@fibocom.com>
References: <20241213064720.122615-1-jinjian.song@fibocom.com> <20241220085027.7692-1-jinjian.song@fibocom.com>
Message-ID: <20241223022418.5795-1-jinjian.song@fibocom.com>

From: Sergey Ryazanov <ryazanov.s.a at gmail.com>

>Hi Jinjian,
>
>On 20.12.2024 10:50, Jinjian Song wrote:
>> From: Sergey Ryazanov <ryazanov.s.a at gmail.com>
>> 
>>>> Fixes: d785ed945de6 ("net: wwan: t7xx: PCIe reset rescan")
>>>
>>> The completion waiting was introduced in a different commit. I 
>>> believe, the fix tag should be 13e920d93e37 ("net: wwan: t7xx: Add 
>>> core components")
>>>
>> 
>> Got it.
>
>[...]
>
>> Yes, the patch works fine, needs some minor modifications, could we 
>> feedback to the driver author to merge these changes.
>
>Looks like the drivers authors haven't enough time to maintain it. You 
>are the most active developer at the moment. Could formally resend the 
>updated patch with refcounter as V3? And, I believe, we can apply it.

Hi Sergey,

Yes, please let me resend the updated patch as suggested.

Thanks.

Jinjian,
Best Regards.


From baolu.lu at linux.intel.com  Sun Dec 22 18:28:32 2024
From: baolu.lu at linux.intel.com (Baolu Lu)
Date: Mon, 23 Dec 2024 10:28:32 +0800
Subject: [PATCH v3 07/14] iommufd/viommu: Add iommufd_viommu_get_vdev_id
 helper
In-Reply-To: <Z2OpylDlhLXoo3dt@Asurada-Nvidia>
References: <cover.1734477608.git.nicolinc@nvidia.com>
 <21d7e63b97d81d0acf9127418a67efe386787261.1734477608.git.nicolinc@nvidia.com>
 <56c65e50-5890-42af-85b7-85f8a1bf5cf5@linux.intel.com>
 <Z2OpylDlhLXoo3dt@Asurada-Nvidia>
Message-ID: <74bc9dbe-3420-4f0c-9e32-db49327a723d@linux.intel.com>

On 12/19/24 13:06, Nicolin Chen wrote:
> On Thu, Dec 19, 2024 at 10:05:53AM +0800, Baolu Lu wrote:
>> On 12/18/24 13:00, Nicolin Chen wrote:
>>> This is a reverse search v.s. iommufd_viommu_find_dev, as drivers may want
>>> to convert a struct device pointer (physical) to its virtual device ID for
>>> an event injection to the user space VM.
>>>
>>> Again, this avoids exposing more core structures to the drivers, than the
>>> iommufd_viommu alone.
>>>
>>> Signed-off-by: Nicolin Chen<nicolinc at nvidia.com>
>>> ---
>>>    include/linux/iommufd.h        |  8 ++++++++
>>>    drivers/iommu/iommufd/driver.c | 20 ++++++++++++++++++++
>>>    2 files changed, 28 insertions(+)
>>>
>>> diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
>>> index b082676c9e43..ac1f1897d290 100644
>>> --- a/include/linux/iommufd.h
>>> +++ b/include/linux/iommufd.h
>>> @@ -190,6 +190,8 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
>>>    					     enum iommufd_object_type type);
>>>    struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
>>>    				       unsigned long vdev_id);
>>> +unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
>>> +					 struct device *dev);
>> Hi Nicolin,
>>
>> This series overall looks good to me. But I have a question that might
>> be irrelevant to this series itself.
>>
>> The iommufd provides both IOMMUFD_OBJ_DEVICE and IOMMUFD_OBJ_VDEVICE
>> objects. What is the essential difference between these two from
>> userspace's perspective?
> A quick answer is an IOMMUFD_OBJ_DEVICE being a host physical
> device and an IOMMUFD_OBJ_VDEVICE being an IOMMUFD_OBJ_DEVICE
> related to IOMMUFD_OBJ_VIOMMU. Two of them can be seen in two
> different layers. May refer to this graph:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ 
> Documentation/userspace-api/iommufd.rst?h=v6.13-rc3#n150
> 
>> And, which object ID should the IOMMU device
>> driver provide when reporting other events in the future?
>>
>> Currently, the IOMMUFD uAPI reports IOMMUFD_OBJ_DEVICE in the page
>> fault message, and IOMMUFD_OBJ_VDEVICE (if I understand it correctly) in
>> the vIRQ message. It will be more future-proof if this could be defined
>> clearly.
> A vIRQ is actually reported per-vIOMMU in this design. Although
> in the this series the SMMU driver seems to report a per-device
> vIRQ, it internally converts the vDEVICE to a virtual device ID
> and packs the virtual device ID into a per-vIOMMU event:
> 
> +/**
> + * struct iommu_virq_arm_smmuv3 - ARM SMMUv3 Virtual IRQ
> + *                                (IOMMU_VIRQ_TYPE_ARM_SMMUV3)
> + * @evt: 256-bit ARM SMMUv3 Event record, little-endian.
> + *       (Refer to "7.3 Event records" in SMMUv3 HW Spec)
> + *
> + * StreamID field reports a virtual device ID. To receive a virtual IRQ for a
> + * device, a vDEVICE must be allocated via IOMMU_VDEVICE_ALLOC.
> + */
> +struct iommu_virq_arm_smmuv3 {
> +	__aligned_le64 evt[4];
>   };

Thanks for the explanation. Maybe I am a bit over-considering here.

Initially, my understanding is to report a virtual device ID when the
object originates from a vIOMMU, and an iommufd device ID otherwise.

However, considering page fault scenarios, which are self-contained but
linked to a hardware page table (hwpt), introduces ambiguity. Hwpt can
be created with or without a vIOMMU. This raises the question: should
the page fault message always report the iommufd device ID, or should
the reporting depend on whether the hwpt was created from a vIOMMU?

Thanks,
baolu


From guoqing.jiang at canonical.com  Sun Dec 22 18:32:27 2024
From: guoqing.jiang at canonical.com (Guoqing Jiang)
Date: Mon, 23 Dec 2024 10:32:27 +0800
Subject: [PATCH V2] drm/mediatek: Set private->all_drm_private[i]->drm to NULL if mtk_drm_bind returns err 
Message-ID: <20241223023227.1258112-1-guoqing.jiang@canonical.com>

The pointer need to be set to NULL, otherwise KASAN complains about
use-after-free. Because in mtk_drm_bind, all private's drm are set
as follows.

private->all_drm_private[i]->drm = drm;

And drm will be released by drm_dev_put in case mtk_drm_kms_init returns
failure. However, the shutdown path still accesses the previous allocated
memory in drm_atomic_helper_shutdown.

[   84.874820] watchdog: watchdog0: watchdog did not stop!
[   86.512054] ==================================================================
[   86.513162] BUG: KASAN: use-after-free in drm_atomic_helper_shutdown+0x33c/0x378
[   86.514258] Read of size 8 at addr ffff0000d46fc068 by task shutdown/1
[   86.515213]
[   86.515455] CPU: 1 UID: 0 PID: 1 Comm: shutdown Not tainted 6.13.0-rc1-mtk+gfa1a78e5d24b-dirty #55
[   86.516752] Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10 10/01/2022
[   86.517960] Call trace:
[   86.518333]  show_stack+0x20/0x38 (C)
[   86.518891]  dump_stack_lvl+0x90/0xd0
[   86.519443]  print_report+0xf8/0x5b0
[   86.519985]  kasan_report+0xb4/0x100
[   86.520526]  __asan_report_load8_noabort+0x20/0x30
[   86.521240]  drm_atomic_helper_shutdown+0x33c/0x378
[   86.521966]  mtk_drm_shutdown+0x54/0x80
[   86.522546]  platform_shutdown+0x64/0x90
[   86.523137]  device_shutdown+0x260/0x5b8
[   86.523728]  kernel_restart+0x78/0xf0
[   86.524282]  __do_sys_reboot+0x258/0x2f0
[   86.524871]  __arm64_sys_reboot+0x90/0xd8
[   86.525473]  invoke_syscall+0x74/0x268
[   86.526041]  el0_svc_common.constprop.0+0xb0/0x240
[   86.526751]  do_el0_svc+0x4c/0x70
[   86.527251]  el0_svc+0x4c/0xc0
[   86.527719]  el0t_64_sync_handler+0x144/0x168
[   86.528367]  el0t_64_sync+0x198/0x1a0
[   86.528920]
[   86.529157] The buggy address belongs to the physical page:
[   86.529972] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff0000d46fd4d0 pfn:0x1146fc
[   86.531319] flags: 0xbfffc0000000000(node=0|zone=2|lastcpupid=0xffff)
[   86.532267] raw: 0bfffc0000000000 0000000000000000 dead000000000122 0000000000000000
[   86.533390] raw: ffff0000d46fd4d0 0000000000000000 00000000ffffffff 0000000000000000
[   86.534511] page dumped because: kasan: bad access detected
[   86.535323]
[   86.535559] Memory state around the buggy address:
[   86.536265]  ffff0000d46fbf00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.537314]  ffff0000d46fbf80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.538363] >ffff0000d46fc000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.544733]                                                           ^
[   86.551057]  ffff0000d46fc080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.557510]  ffff0000d46fc100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[   86.563928] ==================================================================
[   86.571093] Disabling lock debugging due to kernel taint
[   86.577642] Unable to handle kernel paging request at virtual address e0e9c0920000000b
[   86.581834] KASAN: maybe wild-memory-access in range [0x0752049000000058-0x075204900000005f]
...

Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
Signed-off-by: Guoqing Jiang <guoqing.jiang at canonical.com>
---
V2 changes:
1. add Fixes tag per CK's comment

 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 9a8ef8558da9..0062374f75d5 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -673,6 +673,8 @@ static int mtk_drm_bind(struct device *dev)
 err_free:
 	private->drm = NULL;
 	drm_dev_put(drm);
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		private->all_drm_private[i]->drm = NULL;
 	return ret;
 }
 
-- 
2.35.3



From ck.hu at mediatek.com  Sun Dec 22 18:56:26 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 23 Dec 2024 02:56:26 +0000
Subject: [PATCH V2] drm/mediatek: Set private->all_drm_private[i]->drm to
 NULL if mtk_drm_bind returns err
In-Reply-To: <20241223023227.1258112-1-guoqing.jiang@canonical.com>
References: <20241223023227.1258112-1-guoqing.jiang@canonical.com>
Message-ID: <7ba402ce91c40bcc33837289b9920ac82684964b.camel@mediatek.com>

Hi, Guoqing:

On Mon, 2024-12-23 at 10:32 +0800, Guoqing Jiang wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> The pointer need to be set to NULL, otherwise KASAN complains about
> use-after-free. Because in mtk_drm_bind, all private's drm are set
> as follows.
> 
> private->all_drm_private[i]->drm = drm;
> 
> And drm will be released by drm_dev_put in case mtk_drm_kms_init returns
> failure. However, the shutdown path still accesses the previous allocated
> memory in drm_atomic_helper_shutdown.
> 
> [   84.874820] watchdog: watchdog0: watchdog did not stop!
> [   86.512054] ==================================================================
> [   86.513162] BUG: KASAN: use-after-free in drm_atomic_helper_shutdown+0x33c/0x378
> [   86.514258] Read of size 8 at addr ffff0000d46fc068 by task shutdown/1
> [   86.515213]
> [   86.515455] CPU: 1 UID: 0 PID: 1 Comm: shutdown Not tainted 6.13.0-rc1-mtk+gfa1a78e5d24b-dirty #55
> [   86.516752] Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10 10/01/2022
> [   86.517960] Call trace:
> [   86.518333]  show_stack+0x20/0x38 (C)
> [   86.518891]  dump_stack_lvl+0x90/0xd0
> [   86.519443]  print_report+0xf8/0x5b0
> [   86.519985]  kasan_report+0xb4/0x100
> [   86.520526]  __asan_report_load8_noabort+0x20/0x30
> [   86.521240]  drm_atomic_helper_shutdown+0x33c/0x378
> [   86.521966]  mtk_drm_shutdown+0x54/0x80
> [   86.522546]  platform_shutdown+0x64/0x90
> [   86.523137]  device_shutdown+0x260/0x5b8
> [   86.523728]  kernel_restart+0x78/0xf0
> [   86.524282]  __do_sys_reboot+0x258/0x2f0
> [   86.524871]  __arm64_sys_reboot+0x90/0xd8
> [   86.525473]  invoke_syscall+0x74/0x268
> [   86.526041]  el0_svc_common.constprop.0+0xb0/0x240
> [   86.526751]  do_el0_svc+0x4c/0x70
> [   86.527251]  el0_svc+0x4c/0xc0
> [   86.527719]  el0t_64_sync_handler+0x144/0x168
> [   86.528367]  el0t_64_sync+0x198/0x1a0
> [   86.528920]
> [   86.529157] The buggy address belongs to the physical page:
> [   86.529972] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff0000d46fd4d0 pfn:0x1146fc
> [   86.531319] flags: 0xbfffc0000000000(node=0|zone=2|lastcpupid=0xffff)
> [   86.532267] raw: 0bfffc0000000000 0000000000000000 dead000000000122 0000000000000000
> [   86.533390] raw: ffff0000d46fd4d0 0000000000000000 00000000ffffffff 0000000000000000
> [   86.534511] page dumped because: kasan: bad access detected
> [   86.535323]
> [   86.535559] Memory state around the buggy address:
> [   86.536265]  ffff0000d46fbf00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.537314]  ffff0000d46fbf80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.538363] >ffff0000d46fc000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.544733]                                                           ^
> [   86.551057]  ffff0000d46fc080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.557510]  ffff0000d46fc100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> [   86.563928] ==================================================================
> [   86.571093] Disabling lock debugging due to kernel taint
> [   86.577642] Unable to handle kernel paging request at virtual address e0e9c0920000000b
> [   86.581834] KASAN: maybe wild-memory-access in range [0x0752049000000058-0x075204900000005f]
> ...

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

> 
> Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
> Signed-off-by: Guoqing Jiang <guoqing.jiang at canonical.com>
> ---
> V2 changes:
> 1. add Fixes tag per CK's comment
> 
>  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 9a8ef8558da9..0062374f75d5 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -673,6 +673,8 @@ static int mtk_drm_bind(struct device *dev)
>  err_free:
>         private->drm = NULL;
>         drm_dev_put(drm);
> +       for (i = 0; i < private->data->mmsys_dev_num; i++)
> +               private->all_drm_private[i]->drm = NULL;
>         return ret;
>  }
> 
> --
> 2.35.3
> 
> 


From dmitry.baryshkov at linaro.org  Sun Dec 22 18:58:51 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:58:51 +0200
Subject: [PATCH v9 00/10] drm: add DRM HDMI Codec framework
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>

While porting lt9611 DSI-to-HDMI bridge driver to use HDMI Connector
framework, I stumbled upon an issue while handling the Audio InfoFrames.
The HDMI codec callbacks weren't receiving the drm_atomic_state, so
there was no simple way to get the drm_connector that stayed at the end
of the bridge chain. At the same point the drm_hdmi_connector functions
expected to get drm_connector instance.

While looking for a way to solve the issue, I stumbled upon several
deficiencies in existing hdmi_codec_ops implementations. Only few of the
implementations were able to handle codec's 'plugged' callback. One
third of the drivers didn't implement the get_eld() callback.

Most of the issues can be solved if drm_connector handles
hdmi-audio-codec on its own, delegating functionality to the actual
implementation, be it a driver that implements drm_connector or
drm_bridge.

Implement such high-level framework, adding proper support for Audio
InfoFrame generation to the LT9611 driver.

Several design decisions to be kept in mind:

- drm_connector_hdmi_codec is kept as simple as possible. It implements
  generic functionality (ELD, hotplug, registration).

- drm_hdmi_connector sets up HDMI codec device if the connector
  is setup correspondingly (either I2S or S/PDIF is marked as
  supported).

- drm_bridge_connector provides a way to link HDMI audio codec
  funcionality in the drm_bridge with the drm_connector_hdmi_codec
  framework.

- It might be worth reverting the no_i2s_capture / no_spdif_capture
  bits. Only TDA889x driver sets them, while it's safe to assume that
  most of HDMI / DP devices do not support ARC / capture. I think the
  drivers should opt-in capture support rather than having to opt-out of
  it.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
Changes in v9:
- Fix a part of the hdmi_audio rename sneaking into the
  drm_bridge_connector patch.
- Move HDMI Audio implementation into drm_display_helper so that it
  doesn't get compiled for driver which do not require it.
- Link to v8: https://lore.kernel.org/r/20241220-drm-bridge-hdmi-connector-v8-0-2399dbae2990 at linaro.org

Changes in v8:
- Mass rename hdmi_codec -> hdmi_audio, drop redundant audio_ prefixes
  from several callbacks (Maxime)
- Fix the commit message to stop mentioning
  drm_atomic_helper_connector_hdmi_update_edid() (Maxime)
- Link to v7: https://lore.kernel.org/r/20241217-drm-bridge-hdmi-connector-v7-0-cb9df2b6a515 at linaro.org

Changes in v7:
- Renamed drm_connector_hdmi_codec_init() to
  drm_connector_hdmi_audio_init() (Maxime)
- Added extra empty line in struct drm_connector_hdmi_codec_funcs
  (Maxime)
- Dropped if/else from drm_bridge_connector_audio_startup() (Maxime)
- Added optional .read_edid() callback and reworked
  drm_atomic_helper_connector_hdmi_hotplug() to use that callback
  instead of having an internal function which accepts EDID (Maxime)
- Made VC4 and drm_bridge_connector use .force() in addition to
  .detect() and .detect_ctx().
- Moved HDMI codec functions out of struct drm_connector_hdmi_funcs.
  Assign them from drm_connector_hdmi_audio_init().
- Documented struct drm_connector_hdmi_codec and its fields.
- Link to v6: https://lore.kernel.org/r/20241206-drm-bridge-hdmi-connector-v6-0-50dc145a9c06 at linaro.org

Changes in v6:
- Dropped extra checks on the EDID (Jani)
- Reworked drmm_connector_hdmi_init(), splitting the codec init to a
  separate optional function rather than passing arguments through
  drm_connector (Maxime)
- Reworked EDID update functions (Maxime, Jani)
- No longer refresh the EDID in vc4_hdmi_connector_get_modes(), it is
  redundant as vc4_hdmi_connector_detect_cxtx() already does that.
- Link to v5: https://lore.kernel.org/r/20241201-drm-bridge-hdmi-connector-v5-0-b5316e82f61a at linaro.org

Changes in v5:
- Moved prototypes from drm_internal.h to
  drm_connector_hdmi_codec_internal.h (Jani)
- Rebased on top of ELD mutex series, resolving the long-standing FIXME
- Converted the VC4 driver (compile-tested only)
- Link to v4: https://lore.kernel.org/r/20241122-drm-bridge-hdmi-connector-v4-0-b4d69d6e3bd9 at linaro.org

Changes in v4:
- Added forward declaration of struct drm_edid (LKP)
- Fixed kerneldoc for drm_atomic_helper_connector_hdmi_update_edid().
- Link to v3: https://lore.kernel.org/r/20241109-drm-bridge-hdmi-connector-v3-0-c15afdca5884 at linaro.org

Changes in v3:
- Dropped RFC status
- Fixed drm_connector_hdmi_codec_init() kerneldoc (LKP)
- Dropped double underscore prefix from
  __drm_atomic_helper_connector_hdmi_update_edid() (Jani)
- Moved drm_edid_free() from
  drm_atomic_helper_connector_hdmi_update_edid() to the caller's side
  (Jani)
- Link to v2: https://lore.kernel.org/r/20241101-drm-bridge-hdmi-connector-v2-0-739ef9addf9e at linaro.org

Changes in v2:
- Use drm_atomic_get_old_connector_for_encoder in atomic_disable() to
  prevent it from crashing
- Reworked HDMI codec init/exit, removing drmm_ calls (Maxime)
- Drafted the helper to be called from .detect_ctx() that performs HDMI
  Connector maintenance duties (Maxime)
- Moved no_capture_mute to struct hdmi_codec_pdata
- Link to v1: https://lore.kernel.org/r/20240615-drm-bridge-hdmi-connector-v1-0-d59fc7865ab2 at linaro.org

---
Dmitry Baryshkov (10):
      ASoC: hdmi-codec: pass data to get_dai_id too
      ASoC: hdmi-codec: move no_capture_mute to struct hdmi_codec_pdata
      drm/connector: implement generic HDMI audio helpers
      drm/bridge: connector: add support for HDMI codec framework
      drm/bridge: lt9611: switch to using the DRM HDMI codec framework
      drm/display/hdmi: implement hotplug functions
      drm/bridge_connector: hook drm_atomic_helper_connector_hdmi_hotplug()
      drm/vc4: hdmi: switch to using generic HDMI Codec infrastructure
      drm/vc4: hdmi: stop rereading EDID in get_modes()
      drm/vc4: hdmi: use drm_atomic_helper_connector_hdmi_hotplug()

 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c     |   3 +-
 drivers/gpu/drm/bridge/analogix/anx7625.c          |   3 +-
 drivers/gpu/drm/bridge/ite-it66121.c               |   2 +-
 drivers/gpu/drm/bridge/lontium-lt9611.c            | 169 ++++++++----------
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c         |   3 +-
 drivers/gpu/drm/bridge/sii902x.c                   |   5 +-
 .../gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c    |   3 +-
 drivers/gpu/drm/display/Kconfig                    |   8 +
 drivers/gpu/drm/display/Makefile                   |   2 +
 drivers/gpu/drm/display/drm_bridge_connector.c     | 137 ++++++++++++++-
 drivers/gpu/drm/display/drm_hdmi_audio_helper.c    | 189 +++++++++++++++++++++
 drivers/gpu/drm/display/drm_hdmi_state_helper.c    |  56 ++++++
 drivers/gpu/drm/drm_connector.c                    |   5 +
 drivers/gpu/drm/exynos/exynos_hdmi.c               |   2 +-
 drivers/gpu/drm/i2c/tda998x_drv.c                  |   2 +-
 drivers/gpu/drm/mediatek/mtk_dp.c                  |   2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c                |   2 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c             |   2 +-
 drivers/gpu/drm/sti/sti_hdmi.c                     |   2 +-
 drivers/gpu/drm/vc4/Kconfig                        |   1 +
 drivers/gpu/drm/vc4/vc4_hdmi.c                     | 103 +++--------
 drivers/gpu/drm/vc4/vc4_hdmi.h                     |   2 -
 include/drm/display/drm_hdmi_state_helper.h        |   5 +
 include/drm/drm_bridge.h                           |  74 ++++++++
 include/drm/drm_connector.h                        | 141 +++++++++++++++
 include/sound/hdmi-codec.h                         |   7 +-
 sound/soc/codecs/hdmi-codec.c                      |   4 +-
 27 files changed, 726 insertions(+), 208 deletions(-)
---
base-commit: 9d2616754ce7e16a9e73ab6c00efc27fe47cb943
change-id: 20240530-drm-bridge-hdmi-connector-9b0f6725973e

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:58:58 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:58:58 +0200
Subject: [PATCH v9 07/10] drm/bridge_connector: hook
 drm_atomic_helper_connector_hdmi_hotplug()
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-7-6ce16bcedb8b@linaro.org>

Extend drm_bridge_connector code to read the EDID and use it to update
connector status if the bridge chain implements HDMI bridge. Performing
it from the generic location minimizes individual bridge's code and
enforces standard behaviour from all corresponding drivers.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 39 ++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index cc955ee008d843d73fedb891e97143a4168fd311..66e4ab81fa0c2717490193e896389757f0a903f2 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -17,6 +17,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_hdmi_state_helper.h>
@@ -180,11 +181,15 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
 	struct drm_bridge_connector *bridge_connector =
 		to_drm_bridge_connector(connector);
 	struct drm_bridge *detect = bridge_connector->bridge_detect;
+	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
 	enum drm_connector_status status;
 
 	if (detect) {
 		status = detect->funcs->detect(detect);
 
+		if (hdmi)
+			drm_atomic_helper_connector_hdmi_hotplug(connector, status);
+
 		drm_bridge_connector_hpd_notify(connector, status);
 	} else {
 		switch (connector->connector_type) {
@@ -203,6 +208,16 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
 	return status;
 }
 
+static void drm_bridge_connector_force(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
+
+	if (hdmi)
+		drm_atomic_helper_connector_hdmi_force(connector);
+}
+
 static void drm_bridge_connector_debugfs_init(struct drm_connector *connector,
 					      struct dentry *root)
 {
@@ -231,6 +246,7 @@ static void drm_bridge_connector_reset(struct drm_connector *connector)
 static const struct drm_connector_funcs drm_bridge_connector_funcs = {
 	.reset = drm_bridge_connector_reset,
 	.detect = drm_bridge_connector_detect,
+	.force = drm_bridge_connector_force,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
@@ -276,6 +292,14 @@ static int drm_bridge_connector_get_modes(struct drm_connector *connector)
 		to_drm_bridge_connector(connector);
 	struct drm_bridge *bridge;
 
+	/*
+	 * If there is a HDMI bridge, EDID has been updated as a part of
+	 * the .detect(). Just update the modes here.
+	 */
+	bridge = bridge_connector->bridge_hdmi;
+	if (bridge)
+		return drm_edid_connector_add_modes(connector);
+
 	/*
 	 * If display exposes EDID, then we parse that in the normal way to
 	 * build table of supported modes.
@@ -368,10 +392,25 @@ static int drm_bridge_connector_write_infoframe(struct drm_connector *connector,
 	return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len);
 }
 
+static const struct drm_edid *
+drm_bridge_connector_read_edid(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_edid;
+	if (!bridge)
+		return NULL;
+
+	return drm_bridge_edid_read(bridge, connector);
+}
+
 static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
 	.tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid,
 	.clear_infoframe = drm_bridge_connector_clear_infoframe,
 	.write_infoframe = drm_bridge_connector_write_infoframe,
+	.read_edid = drm_bridge_connector_read_edid,
 };
 
 static int drm_bridge_connector_audio_startup(struct drm_connector *connector)

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:58:59 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:58:59 +0200
Subject: [PATCH v9 08/10] drm/vc4: hdmi: switch to using generic HDMI Codec
 infrastructure
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-8-6ce16bcedb8b@linaro.org>

Drop driver-specific implementation and use the generic HDMI Codec
framework in order to implement the HDMI audio support.

Acked-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/Kconfig    |  1 +
 drivers/gpu/drm/vc4/vc4_hdmi.c | 73 +++++++++++-------------------------------
 drivers/gpu/drm/vc4/vc4_hdmi.h |  2 --
 3 files changed, 19 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
index c5f30b317698a1285ae14c07c0f12a2ceb08dde4..6cc7b7e6294a1bfa54137ca65296cd47e46b1e1e 100644
--- a/drivers/gpu/drm/vc4/Kconfig
+++ b/drivers/gpu/drm/vc4/Kconfig
@@ -10,6 +10,7 @@ config DRM_VC4
 	depends on COMMON_CLK
 	depends on PM
 	select DRM_CLIENT_SELECTION
+	select DRM_DISPLAY_HDMI_AUDIO_HELPER
 	select DRM_DISPLAY_HDMI_HELPER
 	select DRM_DISPLAY_HDMI_STATE_HELPER
 	select DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 203293a8beca738dbfeaaf15f350026e263e646b..24199b511f2ee1bc3aa5f4a30e9d3d928d556ff1 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -584,6 +584,7 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
 };
 
 static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs;
+static const struct drm_connector_hdmi_audio_funcs vc4_hdmi_audio_funcs;
 
 static int vc4_hdmi_connector_init(struct drm_device *dev,
 				   struct vc4_hdmi *vc4_hdmi)
@@ -609,6 +610,12 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	ret = drm_connector_hdmi_audio_init(connector, dev->dev,
+					    &vc4_hdmi_audio_funcs,
+					    8, false, -1);
+	if (ret)
+		return ret;
+
 	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
 
 	/*
@@ -1921,9 +1928,9 @@ static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi)
 	return true;
 }
 
-static int vc4_hdmi_audio_startup(struct device *dev, void *data)
+static int vc4_hdmi_audio_startup(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	unsigned long flags;
 	int ret = 0;
@@ -1985,9 +1992,9 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 	spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 }
 
-static void vc4_hdmi_audio_shutdown(struct device *dev, void *data)
+static void vc4_hdmi_audio_shutdown(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	unsigned long flags;
 	int idx;
@@ -2057,13 +2064,12 @@ static int sample_rate_to_mai_fmt(int samplerate)
 }
 
 /* HDMI audio codec callbacks */
-static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
+static int vc4_hdmi_audio_prepare(struct drm_connector *connector,
 				  struct hdmi_codec_daifmt *daifmt,
 				  struct hdmi_codec_params *params)
 {
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	struct drm_connector *connector = &vc4_hdmi->connector;
 	struct vc4_dev *vc4 = to_vc4_dev(drm);
 	unsigned int sample_rate = params->sample_rate;
 	unsigned int channels = params->channels;
@@ -2075,7 +2081,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
 	int ret = 0;
 	int idx;
 
-	dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
+	dev_dbg(&vc4_hdmi->pdev->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
 		sample_rate, params->sample_width, channels);
 
 	mutex_lock(&vc4_hdmi->mutex);
@@ -2214,40 +2220,12 @@ static const struct snd_dmaengine_pcm_config pcm_conf = {
 	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
 };
 
-static int vc4_hdmi_audio_get_eld(struct device *dev, void *data,
-				  uint8_t *buf, size_t len)
-{
-	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-
-	mutex_lock(&connector->eld_mutex);
-	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
-	mutex_unlock(&connector->eld_mutex);
-
-	return 0;
-}
-
-static const struct hdmi_codec_ops vc4_hdmi_codec_ops = {
-	.get_eld = vc4_hdmi_audio_get_eld,
+static const struct drm_connector_hdmi_audio_funcs vc4_hdmi_audio_funcs = {
+	.startup = vc4_hdmi_audio_startup,
 	.prepare = vc4_hdmi_audio_prepare,
-	.audio_shutdown = vc4_hdmi_audio_shutdown,
-	.audio_startup = vc4_hdmi_audio_startup,
-};
-
-static struct hdmi_codec_pdata vc4_hdmi_codec_pdata = {
-	.ops = &vc4_hdmi_codec_ops,
-	.max_i2s_channels = 8,
-	.i2s = 1,
+	.shutdown = vc4_hdmi_audio_shutdown,
 };
 
-static void vc4_hdmi_audio_codec_release(void *ptr)
-{
-	struct vc4_hdmi *vc4_hdmi = ptr;
-
-	platform_device_unregister(vc4_hdmi->audio.codec_pdev);
-	vc4_hdmi->audio.codec_pdev = NULL;
-}
-
 static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 {
 	const struct vc4_hdmi_register *mai_data =
@@ -2255,7 +2233,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 	struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link;
 	struct snd_soc_card *card = &vc4_hdmi->audio.card;
 	struct device *dev = &vc4_hdmi->pdev->dev;
-	struct platform_device *codec_pdev;
 	const __be32 *addr;
 	int index, len;
 	int ret;
@@ -2348,20 +2325,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 		return ret;
 	}
 
-	codec_pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-						   PLATFORM_DEVID_AUTO,
-						   &vc4_hdmi_codec_pdata,
-						   sizeof(vc4_hdmi_codec_pdata));
-	if (IS_ERR(codec_pdev)) {
-		dev_err(dev, "Couldn't register the HDMI codec: %ld\n", PTR_ERR(codec_pdev));
-		return PTR_ERR(codec_pdev);
-	}
-	vc4_hdmi->audio.codec_pdev = codec_pdev;
-
-	ret = devm_add_action_or_reset(dev, vc4_hdmi_audio_codec_release, vc4_hdmi);
-	if (ret)
-		return ret;
-
 	dai_link->cpus		= &vc4_hdmi->audio.cpu;
 	dai_link->codecs	= &vc4_hdmi->audio.codec;
 	dai_link->platforms	= &vc4_hdmi->audio.platform;
@@ -2374,7 +2337,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 	dai_link->stream_name = "MAI PCM";
 	dai_link->codecs->dai_name = "i2s-hifi";
 	dai_link->cpus->dai_name = dev_name(dev);
-	dai_link->codecs->name = dev_name(&codec_pdev->dev);
+	dai_link->codecs->name = dev_name(&vc4_hdmi->connector.hdmi_audio.codec_pdev->dev);
 	dai_link->platforms->name = dev_name(dev);
 
 	card->dai_link = dai_link;
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index b2424a21da230db99db207efa293417faccd254d..e3d989ca302b72533c374dfa3fd0d5bd7fe64a82 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -104,8 +104,6 @@ struct vc4_hdmi_audio {
 	struct snd_soc_dai_link_component codec;
 	struct snd_soc_dai_link_component platform;
 	struct snd_dmaengine_dai_dma_data dma_data;
-	struct hdmi_audio_infoframe infoframe;
-	struct platform_device *codec_pdev;
 	bool streaming;
 };
 

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:59:00 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:59:00 +0200
Subject: [PATCH v9 09/10] drm/vc4: hdmi: stop rereading EDID in get_modes()
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-9-6ce16bcedb8b@linaro.org>

The vc4_hdmi_connector_detect_ctx() via vc4_hdmi_handle_hotplug()
already reads EDID and propagates it to the drm_connector. Stop
rereading EDID as a part of the .get_modes() callback and just update
the list of modes. This matches the behaviour of the i915 driver.

Acked-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 24199b511f2ee1bc3aa5f4a30e9d3d928d556ff1..5282dd765cc9478361a705dca85f615015b12e8e 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -470,31 +470,10 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
 
 static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 {
-	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
-	const struct drm_edid *drm_edid;
 	int ret = 0;
 
-	/*
-	 * NOTE: This function should really take vc4_hdmi->mutex, but doing so
-	 * results in reentrancy issues since cec_s_phys_addr() might call
-	 * .adap_enable, which leads to that funtion being called with our mutex
-	 * held.
-	 *
-	 * Concurrency isn't an issue at the moment since we don't share
-	 * any state with any of the other frameworks so we can ignore
-	 * the lock for now.
-	 */
-
-	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
-	drm_edid_connector_update(connector, drm_edid);
-	cec_s_phys_addr(vc4_hdmi->cec_adap,
-			connector->display_info.source_physical_address, false);
-	if (!drm_edid)
-		return 0;
-
 	ret = drm_edid_connector_add_modes(connector);
-	drm_edid_free(drm_edid);
 
 	if (!vc4->hvs->vc5_hdmi_enable_hdmi_20) {
 		struct drm_device *drm = connector->dev;

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:59:01 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:59:01 +0200
Subject: [PATCH v9 10/10] drm/vc4: hdmi: use
 drm_atomic_helper_connector_hdmi_hotplug()
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-10-6ce16bcedb8b@linaro.org>

Use the helper function to update the connector's information. This
makes sure that HDMI-related events are handled in a generic way.
Currently it is limited to the HDMI state reporting to the sound system.

Acked-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 5282dd765cc9478361a705dca85f615015b12e8e..82eeb08c183420b000b351da1e05f9a47baeda90 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -383,7 +383,6 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
 				    enum drm_connector_status status)
 {
 	struct drm_connector *connector = &vc4_hdmi->connector;
-	const struct drm_edid *drm_edid;
 	int ret;
 
 	/*
@@ -405,17 +404,14 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
 		return;
 	}
 
-	drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc);
+	drm_atomic_helper_connector_hdmi_hotplug(connector, status);
 
-	drm_edid_connector_update(connector, drm_edid);
 	cec_s_phys_addr(vc4_hdmi->cec_adap,
 			connector->display_info.source_physical_address, false);
 
-	if (!drm_edid)
+	if (status != connector_status_connected)
 		return;
 
-	drm_edid_free(drm_edid);
-
 	for (;;) {
 		ret = vc4_hdmi_reset_link(connector, ctx);
 		if (ret == -EDEADLK) {
@@ -549,6 +545,7 @@ static void vc4_hdmi_connector_reset(struct drm_connector *connector)
 }
 
 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
+	.force = drm_atomic_helper_connector_hdmi_force,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.reset = vc4_hdmi_connector_reset,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,

-- 
2.39.5



From amadeus at jmu.edu.cn  Sun Dec 22 19:00:06 2024
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Mon, 23 Dec 2024 11:00:06 +0800
Subject: [PATCH 1/1] arm64: dts: rockchip: default to host mode for USB on Radxa E25
In-Reply-To: <4D8217DF36191C3E+be8bbb4f-ea52-4f81-8501-ff551f54621c@radxa.com>
References: <4D8217DF36191C3E+be8bbb4f-ea52-4f81-8501-ff551f54621c@radxa.com>
Message-ID: <20241223030006.852427-1-amadeus@jmu.edu.cn>

Hi,
> I've been using the uSD card for a long time as a bootloader only,
> so I don't know what the problem is.
>
> Do you have any information on how to reproduce the problem?
>
> Best regards,

Not stable on openwrt/lede, sometimes falling to sd-highspeed.
Maybe it would be better to switch to sd-uhs-sdr50 mode.

Thanks,
Chukun

-- 
2.25.1



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:58:52 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:58:52 +0200
Subject: [PATCH v9 01/10] ASoC: hdmi-codec: pass data to get_dai_id too
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-1-6ce16bcedb8b@linaro.org>

The upcoming DRM connector HDMI codec implementation is going to use
codec-specific data in the .get_dai_id to get drm_connector. Pass data
to the callback, as it is done with other hdmi_codec_ops callbacks.

Acked-by: Mark Brown <broonie at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c      | 3 ++-
 drivers/gpu/drm/bridge/analogix/anx7625.c           | 3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611.c             | 3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c          | 3 ++-
 drivers/gpu/drm/bridge/sii902x.c                    | 3 ++-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 3 ++-
 include/sound/hdmi-codec.h                          | 3 ++-
 sound/soc/codecs/hdmi-codec.c                       | 2 +-
 8 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
index 61f4a38e7d2bf6905683cbc9e762b28ecc999d05..51fb9a574b4e28450b2598a92e2930ace5128b71 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -204,7 +204,8 @@ static void audio_shutdown(struct device *dev, void *data)
 }
 
 static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-					struct device_node *endpoint)
+					struct device_node *endpoint,
+					void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 6238eabd23282d5f7e59a05d267737f40211aaf3..d65680d1bc8f2f27927b8a9d6926b72531791614 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1952,7 +1952,8 @@ static void anx7625_audio_shutdown(struct device *dev, void *data)
 }
 
 static int anx7625_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				       struct device_node *endpoint)
+				       struct device_node *endpoint,
+				       void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 74f726efc74613460a6eb9c41f0bbad2ab06208f..698a9a01783d28edc734b6932a7768978de65ffc 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -1057,7 +1057,8 @@ static void lt9611_audio_shutdown(struct device *dev, void *data)
 }
 
 static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				      struct device_node *endpoint)
+				      struct device_node *endpoint,
+				      void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index db9a5466060b663e88d58e85f24bf2d58d74a81c..f4c3ff1fdc6923eb7a8c0d8f7f92e7649c797d77 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -522,7 +522,8 @@ static void lt9611uxc_audio_shutdown(struct device *dev, void *data)
 }
 
 static int lt9611uxc_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-					 struct device_node *endpoint)
+					 struct device_node *endpoint,
+					 void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 127da22011b3235b049c38413e56d50414cf36fb..a02d30c0ba4221d7fee0eb50892ab4d8e8436004 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -815,7 +815,8 @@ static int sii902x_audio_get_eld(struct device *dev, void *data,
 }
 
 static int sii902x_audio_get_dai_id(struct snd_soc_component *component,
-				    struct device_node *endpoint)
+				    struct device_node *endpoint,
+				    void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index f1c5a8d0fa90e2eb2ee488b6a5871b005f797ea1..2c903c9fe8052ab721445188fd2b75270a55f2b0 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -148,7 +148,8 @@ static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, uint8_t *buf,
 }
 
 static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				  struct device_node *endpoint)
+				  struct device_node *endpoint,
+				  void *data)
 {
 	struct of_endpoint of_ep;
 	int ret;
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index 5e1a9eafd10f5d4f831abbb6f4c0fff661909584..b3407b47b4a7878532ecf3b08eeecd443d6fdb07 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -105,7 +105,8 @@ struct hdmi_codec_ops {
 	 * Optional
 	 */
 	int (*get_dai_id)(struct snd_soc_component *comment,
-			  struct device_node *endpoint);
+			  struct device_node *endpoint,
+			  void *data);
 
 	/*
 	 * Hook callback function to handle connector plug event.
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index d9df29a26f4f213a30a2ebcdb63a593f9cf4b901..f536ca60e162dca6b50b37854ca6de2c114bc2a1 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -995,7 +995,7 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
 	int ret = -ENOTSUPP; /* see snd_soc_get_dai_id() */
 
 	if (hcp->hcd.ops->get_dai_id)
-		ret = hcp->hcd.ops->get_dai_id(component, endpoint);
+		ret = hcp->hcd.ops->get_dai_id(component, endpoint, hcp->hcd.data);
 
 	return ret;
 }

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:58:53 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:58:53 +0200
Subject: [PATCH v9 02/10] ASoC: hdmi-codec: move no_capture_mute to struct
 hdmi_codec_pdata
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-2-6ce16bcedb8b@linaro.org>

The no_capture_mute flag might differ from platform to platform,
especially in the case of the wrapping implementations, like the
upcoming DRM HDMI Codec framework. Move the flag next to all other flags
in struct hdmi_codec_pdata.

Acked-by: Mark Brown <broonie at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/ite-it66121.c   | 2 +-
 drivers/gpu/drm/bridge/sii902x.c       | 2 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c   | 2 +-
 drivers/gpu/drm/i2c/tda998x_drv.c      | 2 +-
 drivers/gpu/drm/mediatek/mtk_dp.c      | 2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c    | 2 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +-
 drivers/gpu/drm/sti/sti_hdmi.c         | 2 +-
 include/sound/hdmi-codec.h             | 4 +---
 sound/soc/codecs/hdmi-codec.c          | 2 +-
 10 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c
index 940083e5d2ddbfc56f14e2bdc6ddd0b9dd50b1f8..7734e389ca7692f7880aa9b8650e45aab228c7fd 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -1466,7 +1466,6 @@ static const struct hdmi_codec_ops it66121_audio_codec_ops = {
 	.audio_shutdown = it66121_audio_shutdown,
 	.mute_stream = it66121_audio_mute,
 	.get_eld = it66121_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev)
@@ -1476,6 +1475,7 @@ static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev)
 		.i2s = 1, /* Only i2s support for now */
 		.spdif = 0,
 		.max_i2s_channels = 8,
+		.no_capture_mute = 1,
 	};
 
 	dev_dbg(dev, "%s\n", __func__);
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index a02d30c0ba4221d7fee0eb50892ab4d8e8436004..2a0af0f09defa2994ddece755ecf9742b418473b 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -841,7 +841,6 @@ static const struct hdmi_codec_ops sii902x_audio_codec_ops = {
 	.mute_stream = sii902x_audio_mute,
 	.get_eld = sii902x_audio_get_eld,
 	.get_dai_id = sii902x_audio_get_dai_id,
-	.no_capture_mute = 1,
 };
 
 static int sii902x_audio_codec_init(struct sii902x *sii902x,
@@ -864,6 +863,7 @@ static int sii902x_audio_codec_init(struct sii902x *sii902x,
 		.i2s = 1, /* Only i2s support for now. */
 		.spdif = 0,
 		.max_i2s_channels = 0,
+		.no_capture_mute = 1,
 	};
 	u8 lanes[4];
 	int num_lanes, i;
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 7a57d4a23e410db1d4d3a11bb9285d34c784f2d5..176fd88717597c37824fbf825ca6b893b083e0ca 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1660,7 +1660,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = hdmi_audio_shutdown,
 	.mute_stream = hdmi_audio_mute,
 	.get_eld = hdmi_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int hdmi_register_audio_device(struct hdmi_context *hdata)
@@ -1669,6 +1668,7 @@ static int hdmi_register_audio_device(struct hdmi_context *hdata)
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 6,
 		.i2s = 1,
+		.no_capture_mute = 1,
 	};
 
 	hdata->audio.pdev = platform_device_register_data(
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 57ce77c2be2458fff5b752332ae51e016582ddca..82d4a4e206a584e045a8fcd593fc12b7c1257bfe 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1165,7 +1165,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = tda998x_audio_shutdown,
 	.mute_stream = tda998x_audio_mute_stream,
 	.get_eld = tda998x_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int tda998x_audio_codec_init(struct tda998x_priv *priv,
@@ -1176,6 +1175,7 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
 		.max_i2s_channels = 2,
 		.no_i2s_capture = 1,
 		.no_spdif_capture = 1,
+		.no_capture_mute = 1,
 	};
 
 	if (priv->audio_port_enable[AUDIO_ROUTE_I2S])
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 36713c176cfcf1af2d365280700d06f4c1239e09..5c805094daf6d4678355fec43648552b34508bec 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -2615,7 +2615,6 @@ static const struct hdmi_codec_ops mtk_dp_audio_codec_ops = {
 	.audio_shutdown = mtk_dp_audio_shutdown,
 	.get_eld = mtk_dp_audio_get_eld,
 	.hook_plugged_cb = mtk_dp_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int mtk_dp_register_audio_driver(struct device *dev)
@@ -2626,6 +2625,7 @@ static int mtk_dp_register_audio_driver(struct device *dev)
 		.max_i2s_channels = 8,
 		.i2s = 1,
 		.data = mtk_dp,
+		.no_capture_mute = 1,
 	};
 
 	mtk_dp->audio_pdev = platform_device_register_data(dev,
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 70dc1d4460adfc04b5c40263d11184aae826c658..ca82bc829cb96446d4d34eeef45848df03bd716b 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1660,7 +1660,6 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
 	.mute_stream = mtk_hdmi_audio_mute,
 	.get_eld = mtk_hdmi_audio_get_eld,
 	.hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int mtk_hdmi_register_audio_driver(struct device *dev)
@@ -1671,6 +1670,7 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
 		.max_i2s_channels = 2,
 		.i2s = 1,
 		.data = hdmi,
+		.no_capture_mute = 1,
 	};
 	struct platform_device *pdev;
 
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b76337f690ec2fdfbf4dac08a04aa4de4eff257f..b17de83b988b1f1afb2f6d12b1d155761ff9ca50 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -885,7 +885,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.mute_stream = cdn_dp_audio_mute_stream,
 	.get_eld = cdn_dp_audio_get_eld,
 	.hook_plugged_cb = cdn_dp_audio_hook_plugged_cb,
-	.no_capture_mute = 1,
 };
 
 static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
@@ -896,6 +895,7 @@ static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
 		.spdif = 1,
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 8,
+		.no_capture_mute = 1,
 	};
 
 	dp->audio_pdev = platform_device_register_data(
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index f8bbae6393ef8c0bd1deb75d1e131c1d83c1ebfe..ca2fe17de4a5d1e0199e59a97e6c7601e139ed9e 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -1237,7 +1237,6 @@ static const struct hdmi_codec_ops audio_codec_ops = {
 	.audio_shutdown = hdmi_audio_shutdown,
 	.mute_stream = hdmi_audio_mute,
 	.get_eld = hdmi_audio_get_eld,
-	.no_capture_mute = 1,
 };
 
 static int sti_hdmi_register_audio_driver(struct device *dev,
@@ -1247,6 +1246,7 @@ static int sti_hdmi_register_audio_driver(struct device *dev,
 		.ops = &audio_codec_ops,
 		.max_i2s_channels = 8,
 		.i2s = 1,
+		.no_capture_mute = 1,
 	};
 
 	DRM_DEBUG_DRIVER("\n");
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index b3407b47b4a7878532ecf3b08eeecd443d6fdb07..b220072cfa1baf503efbe2d530d7e8392dc16603 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -115,9 +115,6 @@ struct hdmi_codec_ops {
 	int (*hook_plugged_cb)(struct device *dev, void *data,
 			       hdmi_codec_plugged_cb fn,
 			       struct device *codec_dev);
-
-	/* bit field */
-	unsigned int no_capture_mute:1;
 };
 
 /* HDMI codec initalization data */
@@ -129,6 +126,7 @@ struct hdmi_codec_pdata {
 	uint spdif:1;
 	uint no_spdif_playback:1;
 	uint no_spdif_capture:1;
+	uint no_capture_mute:1;
 	int max_i2s_channels;
 	void *data;
 };
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index f536ca60e162dca6b50b37854ca6de2c114bc2a1..69f98975e14ae367f482862724a358eb138ebf6a 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -714,7 +714,7 @@ static int hdmi_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
 	 */
 	if (hcp->hcd.ops->mute_stream &&
 	    (direction == SNDRV_PCM_STREAM_PLAYBACK ||
-	     !hcp->hcd.ops->no_capture_mute))
+	     !hcp->hcd.no_capture_mute))
 		return hcp->hcd.ops->mute_stream(dai->dev->parent,
 						 hcp->hcd.data,
 						 mute, direction);

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:58:54 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:58:54 +0200
Subject: [PATCH v9 03/10] drm/connector: implement generic HDMI audio
 helpers
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-3-6ce16bcedb8b@linaro.org>

Several DRM drivers implement HDMI codec support (despite its name it
applies to both HDMI and DisplayPort drivers). Implement generic
framework to be used by these drivers. This removes a requirement to
implement get_eld() callback and provides default implementation for
codec's plug handling.

Acked-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/Kconfig                 |   6 +
 drivers/gpu/drm/display/Makefile                |   2 +
 drivers/gpu/drm/display/drm_hdmi_audio_helper.c | 189 ++++++++++++++++++++++++
 drivers/gpu/drm/drm_connector.c                 |   5 +
 include/drm/drm_connector.h                     | 125 ++++++++++++++++
 5 files changed, 327 insertions(+)

diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
index 6a4e892afcf8966b45f50ce1f2530707441eda51..80c1953cac14a088d764acd45df03debfcb95e7c 100644
--- a/drivers/gpu/drm/display/Kconfig
+++ b/drivers/gpu/drm/display/Kconfig
@@ -75,6 +75,12 @@ config DRM_DISPLAY_HDCP_HELPER
 	help
 	  DRM display helpers for HDCP.
 
+config DRM_DISPLAY_HDMI_AUDIO_HELPER
+	bool
+	help
+	  DRM display helpers for HDMI Audio functionality (generic HDMI Codec
+	  implementation).
+
 config DRM_DISPLAY_HDMI_HELPER
 	bool
 	help
diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile
index 629c834c3192c61ab8e071223c6a08b98d295b0c..b17879b957d5401721396e247fa346387cf6c48a 100644
--- a/drivers/gpu/drm/display/Makefile
+++ b/drivers/gpu/drm/display/Makefile
@@ -14,6 +14,8 @@ drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TUNNEL) += \
 drm_display_helper-$(CONFIG_DRM_DISPLAY_DSC_HELPER) += \
 	drm_dsc_helper.o
 drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) += drm_hdcp_helper.o
+drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_AUDIO_HELPER) += \
+	drm_hdmi_audio_helper.o
 drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \
 	drm_hdmi_helper.o \
 	drm_scdc_helper.o
diff --git a/drivers/gpu/drm/display/drm_hdmi_audio_helper.c b/drivers/gpu/drm/display/drm_hdmi_audio_helper.c
new file mode 100644
index 0000000000000000000000000000000000000000..cda9403e49ec35e9d9c118705934908b3ca925b0
--- /dev/null
+++ b/drivers/gpu/drm/display/drm_hdmi_audio_helper.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2024 Linaro Ltd
+ */
+
+#include <linux/mutex.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+
+#include <drm/drm_connector.h>
+#include <drm/drm_device.h>
+
+#include <sound/hdmi-codec.h>
+
+static int drm_connector_hdmi_audio_startup(struct device *dev, void *data)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_audio_funcs *funcs =
+		connector->hdmi_audio.funcs;
+
+	if (funcs->startup)
+		return funcs->startup(connector);
+
+	return 0;
+}
+
+static int drm_connector_hdmi_audio_prepare(struct device *dev, void *data,
+					    struct hdmi_codec_daifmt *fmt,
+					    struct hdmi_codec_params *hparms)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_audio_funcs *funcs =
+		connector->hdmi_audio.funcs;
+
+	return funcs->prepare(connector, fmt, hparms);
+}
+
+static void drm_connector_hdmi_audio_shutdown(struct device *dev, void *data)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_audio_funcs *funcs =
+		connector->hdmi_audio.funcs;
+
+	return funcs->shutdown(connector);
+}
+
+static int drm_connector_hdmi_audio_mute_stream(struct device *dev, void *data,
+						bool enable, int direction)
+{
+	struct drm_connector *connector = data;
+	const struct drm_connector_hdmi_audio_funcs *funcs =
+		connector->hdmi_audio.funcs;
+
+	if (funcs->mute_stream)
+		return funcs->mute_stream(connector, enable, direction);
+
+	return -ENOTSUPP;
+}
+
+static int drm_connector_hdmi_audio_get_dai_id(struct snd_soc_component *comment,
+					       struct device_node *endpoint,
+					       void *data)
+{
+	struct drm_connector *connector = data;
+	struct of_endpoint of_ep;
+	int ret;
+
+	if (connector->hdmi_audio.dai_port < 0)
+		return -ENOTSUPP;
+
+	ret = of_graph_parse_endpoint(endpoint, &of_ep);
+	if (ret < 0)
+		return ret;
+
+	if (of_ep.port == connector->hdmi_audio.dai_port)
+		return 0;
+
+	return -EINVAL;
+}
+
+static int drm_connector_hdmi_audio_get_eld(struct device *dev, void *data,
+					    uint8_t *buf, size_t len)
+{
+	struct drm_connector *connector = data;
+
+	mutex_lock(&connector->eld_mutex);
+	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
+	mutex_unlock(&connector->eld_mutex);
+
+	return 0;
+}
+
+static int drm_connector_hdmi_audio_hook_plugged_cb(struct device *dev,
+						    void *data,
+						    hdmi_codec_plugged_cb fn,
+						    struct device *codec_dev)
+{
+	struct drm_connector *connector = data;
+
+	mutex_lock(&connector->hdmi_audio.lock);
+
+	connector->hdmi_audio.plugged_cb = fn;
+	connector->hdmi_audio.plugged_cb_dev = codec_dev;
+
+	fn(codec_dev, connector->hdmi_audio.last_state);
+
+	mutex_unlock(&connector->hdmi_audio.lock);
+
+	return 0;
+}
+
+void drm_connector_hdmi_audio_plugged_notify(struct drm_connector *connector,
+					     bool plugged)
+{
+	mutex_lock(&connector->hdmi_audio.lock);
+
+	connector->hdmi_audio.last_state = plugged;
+
+	if (connector->hdmi_audio.plugged_cb &&
+	    connector->hdmi_audio.plugged_cb_dev)
+		connector->hdmi_audio.plugged_cb(connector->hdmi_audio.plugged_cb_dev,
+						 connector->hdmi_audio.last_state);
+
+	mutex_unlock(&connector->hdmi_audio.lock);
+}
+EXPORT_SYMBOL(drm_connector_hdmi_audio_plugged_notify);
+
+static const struct hdmi_codec_ops drm_connector_hdmi_audio_ops = {
+	.audio_startup = drm_connector_hdmi_audio_startup,
+	.prepare = drm_connector_hdmi_audio_prepare,
+	.audio_shutdown = drm_connector_hdmi_audio_shutdown,
+	.mute_stream = drm_connector_hdmi_audio_mute_stream,
+	.get_eld = drm_connector_hdmi_audio_get_eld,
+	.get_dai_id = drm_connector_hdmi_audio_get_dai_id,
+	.hook_plugged_cb = drm_connector_hdmi_audio_hook_plugged_cb,
+};
+
+/**
+ * drm_connector_hdmi_audio_init - Initialize HDMI Codec device for the DRM connector
+ * @connector: A pointer to the connector to allocate codec for
+ * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
+ * @funcs: callbacks for this HDMI Codec
+ * @max_i2s_playback_channels: maximum number of playback I2S channels
+ * @spdif_playback: set if HDMI codec has S/PDIF playback port
+ * @dai_port: sound DAI port, -1 if it is not enabled
+ *
+ * Create a HDMI codec device to be used with the specified connector.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_connector_hdmi_audio_init(struct drm_connector *connector,
+				  struct device *hdmi_codec_dev,
+				  const struct drm_connector_hdmi_audio_funcs *funcs,
+				  unsigned int max_i2s_playback_channels,
+				  bool spdif_playback,
+				  int dai_port)
+{
+	struct hdmi_codec_pdata codec_pdata = {
+		.ops = &drm_connector_hdmi_audio_ops,
+		.max_i2s_channels = max_i2s_playback_channels,
+		.i2s = !!max_i2s_playback_channels,
+		.spdif = spdif_playback,
+		.no_i2s_capture = true,
+		.no_spdif_capture = true,
+		.data = connector,
+	};
+	struct platform_device *pdev;
+
+	if (!funcs ||
+	    !funcs->prepare ||
+	    !funcs->shutdown)
+		return -EINVAL;
+
+	connector->hdmi_audio.funcs = funcs;
+	connector->hdmi_audio.dai_port = dai_port;
+
+	pdev = platform_device_register_data(hdmi_codec_dev,
+					     HDMI_CODEC_DRV_NAME,
+					     PLATFORM_DEVID_AUTO,
+					     &codec_pdata, sizeof(codec_pdata));
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	connector->hdmi_audio.codec_pdev = pdev;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_hdmi_audio_init);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index ae6e71305f3000aff1cfe96b050061a300b9478e..1383fa9fff9bcf31488453e209a36c6fe97be2f1 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -33,6 +33,7 @@
 #include <drm/drm_sysfs.h>
 #include <drm/drm_utils.h>
 
+#include <linux/platform_device.h>
 #include <linux/property.h>
 #include <linux/uaccess.h>
 
@@ -281,6 +282,7 @@ static int drm_connector_init_only(struct drm_device *dev,
 	mutex_init(&connector->eld_mutex);
 	mutex_init(&connector->edid_override_mutex);
 	mutex_init(&connector->hdmi.infoframes.lock);
+	mutex_init(&connector->hdmi_audio.lock);
 	connector->edid_blob_ptr = NULL;
 	connector->epoch_counter = 0;
 	connector->tile_blob_ptr = NULL;
@@ -714,6 +716,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		    DRM_CONNECTOR_REGISTERED))
 		drm_connector_unregister(connector);
 
+	platform_device_unregister(connector->hdmi_audio.codec_pdev);
+
 	if (connector->privacy_screen) {
 		drm_privacy_screen_put(connector->privacy_screen);
 		connector->privacy_screen = NULL;
@@ -750,6 +754,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
 		connector->funcs->atomic_destroy_state(connector,
 						       connector->state);
 
+	mutex_destroy(&connector->hdmi_audio.lock);
 	mutex_destroy(&connector->hdmi.infoframes.lock);
 	mutex_destroy(&connector->mutex);
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index d1be19242a5c5d7ab6b38cced1da336830b3848d..19e4256296657b0f1d203266d152cbba42f9726a 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -46,6 +46,8 @@ struct drm_property_blob;
 struct drm_printer;
 struct drm_privacy_screen;
 struct edid;
+struct hdmi_codec_daifmt;
+struct hdmi_codec_params;
 struct i2c_adapter;
 
 enum drm_connector_force {
@@ -1141,6 +1143,53 @@ struct drm_connector_state {
 	struct drm_connector_hdmi_state hdmi;
 };
 
+struct drm_connector_hdmi_audio_funcs {
+	/**
+	 * @startup:
+	 *
+	 * Called when ASoC starts an audio stream setup. The
+	 * @startup() is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*startup)(struct drm_connector *connector);
+
+	/**
+	 * @prepare:
+	 * Configures HDMI-encoder for audio stream. Can be called
+	 * multiple times for each setup. Mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*prepare)(struct drm_connector *connector,
+		       struct hdmi_codec_daifmt *fmt,
+		       struct hdmi_codec_params *hparms);
+
+	/**
+	 * @shutdown:
+	 *
+	 * Shut down the audio stream. Mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	void (*shutdown)(struct drm_connector *connector);
+
+	/**
+	 * @mute_stream:
+	 *
+	 * Mute/unmute HDMI audio stream. The @mute_stream callback is
+	 * optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*mute_stream)(struct drm_connector *connector,
+			   bool enable, int direction);
+};
+
 /**
  * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
  */
@@ -1660,6 +1709,68 @@ struct drm_cmdline_mode {
 	bool tv_mode_specified;
 };
 
+/**
+ * struct drm_connector_hdmi_audio - DRM gemeric HDMI Codec-related structure
+ *
+ * HDMI drivers usually incorporate a HDMI Codec. This structure expresses the
+ * generic HDMI Codec as used by the DRM HDMI Codec framework.
+ */
+struct drm_connector_hdmi_audio {
+	/**
+	 * @funcs:
+	 *
+	 * Implementation of the HDMI codec functionality to be used by the DRM
+	 * HDMI Codec framework.
+	 */
+	const struct drm_connector_hdmi_audio_funcs *funcs;
+
+	/**
+	 * @codec_pdev:
+	 *
+	 * Platform device created to hold the HDMI Codec. It will be
+	 * automatically unregistered during drm_connector_cleanup().
+	 */
+	struct platform_device *codec_pdev;
+
+	/**
+	 * @lock:
+	 *
+	 * Mutex to protect @last_state, @plugged_cb and @plugged_cb_dev.
+	 */
+	struct mutex lock;
+
+	/**
+	 * @plugged_cb:
+	 *
+	 * Callback to be called when the HDMI sink get plugged to or unplugged
+	 * from this connector. This is assigned by the framework when
+	 * requested by the ASoC code.
+	 */
+	void (*plugged_cb)(struct device *dev, bool plugged);
+
+	/**
+	 * @plugged_cb_dev:
+	 *
+	 * The data for @plugged_cb(). It is being provided by the ASoC.
+	 */
+	struct device *plugged_cb_dev;
+
+	/**
+	 * @last_state:
+	 *
+	 * Last plugged state recored by the framework. It is used to correctly
+	 * report the state to @plugged_cb().
+	 */
+	bool last_state;
+
+	/**
+	 * @dai_port:
+	 *
+	 * The port in DT that is used for the Codec DAI.
+	 */
+	int dai_port;
+};
+
 /*
  * struct drm_connector_hdmi - DRM Connector HDMI-related structure
  */
@@ -2121,6 +2232,11 @@ struct drm_connector {
 	 * @hdmi: HDMI-related variable and properties.
 	 */
 	struct drm_connector_hdmi hdmi;
+
+	/**
+	 * @hdmi_audio: HDMI codec properties and non-DRM state.
+	 */
+	struct drm_connector_hdmi_audio hdmi_audio;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -2153,6 +2269,12 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct i2c_adapter *ddc,
 			     unsigned long supported_formats,
 			     unsigned int max_bpc);
+int drm_connector_hdmi_audio_init(struct drm_connector *connector,
+				  struct device *hdmi_codec_dev,
+				  const struct drm_connector_hdmi_audio_funcs *funcs,
+				  unsigned int max_i2s_playback_channels,
+				  bool spdif_playback,
+				  int sound_dai_port);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);
 int drm_connector_dynamic_register(struct drm_connector *connector);
@@ -2160,6 +2282,9 @@ void drm_connector_unregister(struct drm_connector *connector);
 int drm_connector_attach_encoder(struct drm_connector *connector,
 				      struct drm_encoder *encoder);
 
+void drm_connector_hdmi_audio_plugged_notify(struct drm_connector *connector,
+					     bool plugged);
+
 void drm_connector_cleanup(struct drm_connector *connector);
 
 static inline unsigned int drm_connector_index(const struct drm_connector *connector)

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:58:55 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:58:55 +0200
Subject: [PATCH v9 04/10] drm/bridge: connector: add support for HDMI codec
 framework
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-4-6ce16bcedb8b@linaro.org>

Add necessary glue code to be able to use new HDMI codec framework from
the DRM bridge drivers. The drm_bridge implements a limited set of the
hdmi_codec_ops interface, with the functions accepting both
drm_connector and drm_bridge instead of just a generic void pointer.

This framework is integrated with the DRM HDMI Connector framework, but
can also be used for DisplayPort connectors.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/Kconfig                |  1 +
 drivers/gpu/drm/display/drm_bridge_connector.c | 98 ++++++++++++++++++++++++--
 include/drm/drm_bridge.h                       | 74 +++++++++++++++++++
 3 files changed, 169 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
index 80c1953cac14a088d764acd45df03debfcb95e7c..2619fa2476eb149e1befc3135131ed5aaeb5bb4c 100644
--- a/drivers/gpu/drm/display/Kconfig
+++ b/drivers/gpu/drm/display/Kconfig
@@ -15,6 +15,7 @@ if DRM_DISPLAY_HELPER
 
 config DRM_BRIDGE_CONNECTOR
 	bool
+	select DRM_DISPLAY_HDMI_AUDIO_HELPER
 	select DRM_DISPLAY_HDMI_STATE_HELPER
 	help
 	  DRM connector implementation terminating DRM bridge chains.
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 512ced87ea18c74e182a558a686ddd83de891814..cc955ee008d843d73fedb891e97143a4168fd311 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -374,6 +374,75 @@ static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
 	.write_infoframe = drm_bridge_connector_write_infoframe,
 };
 
+static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	if (!bridge->funcs->hdmi_audio_startup)
+		return 0;
+
+	return bridge->funcs->hdmi_audio_startup(connector, bridge);
+}
+
+static int drm_bridge_connector_audio_prepare(struct drm_connector *connector,
+					      struct hdmi_codec_daifmt *fmt,
+					      struct hdmi_codec_params *hparms)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	return bridge->funcs->hdmi_audio_prepare(connector, bridge, fmt, hparms);
+}
+
+static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return;
+
+	bridge->funcs->hdmi_audio_shutdown(connector, bridge);
+}
+
+static int drm_bridge_connector_audio_mute_stream(struct drm_connector *connector,
+					    bool enable, int direction)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	if (bridge->funcs->hdmi_audio_mute_stream)
+		return bridge->funcs->hdmi_audio_mute_stream(connector, bridge,
+							     enable, direction);
+	else
+		return -ENOTSUPP;
+}
+
+static const struct drm_connector_hdmi_audio_funcs drm_bridge_connector_hdmi_audio_funcs = {
+	.startup = drm_bridge_connector_audio_startup,
+	.prepare = drm_bridge_connector_audio_prepare,
+	.shutdown = drm_bridge_connector_audio_shutdown,
+	.mute_stream = drm_bridge_connector_audio_mute_stream,
+};
+
 /* -----------------------------------------------------------------------------
  * Bridge Connector Initialisation
  */
@@ -473,7 +542,9 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
 		return ERR_PTR(-EINVAL);
 
-	if (bridge_connector->bridge_hdmi)
+	if (bridge_connector->bridge_hdmi) {
+		bridge = bridge_connector->bridge_hdmi;
+
 		ret = drmm_connector_hdmi_init(drm, connector,
 					       bridge_connector->bridge_hdmi->vendor,
 					       bridge_connector->bridge_hdmi->product,
@@ -482,12 +553,31 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 					       connector_type, ddc,
 					       supported_formats,
 					       max_bpc);
-	else
+		if (ret)
+			return ERR_PTR(ret);
+
+		if (bridge->hdmi_audio_max_i2s_playback_channels ||
+		    bridge->hdmi_audio_spdif_playback) {
+			if (!bridge->funcs->hdmi_audio_prepare ||
+			    !bridge->funcs->hdmi_audio_shutdown)
+				return ERR_PTR(-EINVAL);
+
+			ret = drm_connector_hdmi_audio_init(connector,
+							    bridge->hdmi_audio_dev,
+							    &drm_bridge_connector_hdmi_audio_funcs,
+							    bridge->hdmi_audio_max_i2s_playback_channels,
+							    bridge->hdmi_audio_spdif_playback,
+							    bridge->hdmi_audio_dai_port);
+			if (ret)
+				return ERR_PTR(ret);
+		}
+	} else {
 		ret = drmm_connector_init(drm, connector,
 					  &drm_bridge_connector_funcs,
 					  connector_type, ddc);
-	if (ret)
-		return ERR_PTR(ret);
+		if (ret)
+			return ERR_PTR(ret);
+	}
 
 	drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs);
 
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index e8d735b7f6a480468c88287e2517b387ceec0f22..4b84faf14e368310dd20aa964e8178ec80aa6fa7 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -41,6 +41,8 @@ struct drm_display_info;
 struct drm_minor;
 struct drm_panel;
 struct edid;
+struct hdmi_codec_daifmt;
+struct hdmi_codec_params;
 struct i2c_adapter;
 
 /**
@@ -676,6 +678,57 @@ struct drm_bridge_funcs {
 				    enum hdmi_infoframe_type type,
 				    const u8 *buffer, size_t len);
 
+	/**
+	 * @hdmi_audio_startup:
+	 *
+	 * Called when ASoC starts an audio stream setup. The
+	 * @hdmi_audio_startup() is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*hdmi_audio_startup)(struct drm_connector *connector,
+				  struct drm_bridge *bridge);
+
+	/**
+	 * @prepare:
+	 * Configures HDMI-encoder for audio stream. Can be called multiple
+	 * times for each setup. Mandatory if HDMI audio is enabled in the
+	 * bridge's configuration.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*hdmi_audio_prepare)(struct drm_connector *connector,
+				  struct drm_bridge *bridge,
+				  struct hdmi_codec_daifmt *fmt,
+				  struct hdmi_codec_params *hparms);
+
+	/**
+	 * @hdmi_audio_shutdown:
+	 *
+	 * Shut down the audio stream. Mandatory if HDMI audio is enabled in
+	 * the bridge's configuration.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	void (*hdmi_audio_shutdown)(struct drm_connector *connector,
+				    struct drm_bridge *bridge);
+
+	/**
+	 * @hdmi_audio_mute_stream:
+	 *
+	 * Mute/unmute HDMI audio stream. The @hdmi_audio_mute_stream callback
+	 * is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*hdmi_audio_mute_stream)(struct drm_connector *connector,
+				      struct drm_bridge *bridge,
+				      bool enable, int direction);
+
 	/**
 	 * @debugfs_init:
 	 *
@@ -859,6 +912,27 @@ struct drm_bridge {
 	 * @DRM_BRIDGE_OP_HDMI is set.
 	 */
 	unsigned int max_bpc;
+
+	/**
+	 * @hdmi_audio_dev: device to be used as a parent for the HDMI Codec
+	 */
+	struct device *hdmi_audio_dev;
+
+	/**
+	 * @hdmi_audio_max_i2s_playback_channels: maximum number of playback
+	 * I2S channels for the HDMI codec
+	 */
+	int hdmi_audio_max_i2s_playback_channels;
+
+	/**
+	 * @hdmi_audio_spdif_playback: set if HDMI codec has S/PDIF playback port
+	 */
+	unsigned int hdmi_audio_spdif_playback : 1;
+
+	/**
+	 * @hdmi_audio_dai_port: sound DAI port, -1 if it is not enabled
+	 */
+	int hdmi_audio_dai_port;
 };
 
 static inline struct drm_bridge *

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:58:56 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:58:56 +0200
Subject: [PATCH v9 05/10] drm/bridge: lt9611: switch to using the DRM HDMI
 codec framework
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-5-6ce16bcedb8b@linaro.org>

Make the Lontium LT9611 DSI-to-HDMI bridge driver use the DRM HDMI Codec
framework. This enables programming of Audio InfoFrames using the HDMI
Connector interface and also enables support for the missing features,
including the ELD retrieval and better hotplug support.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 170 +++++++++++++-------------------
 1 file changed, 68 insertions(+), 102 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 698a9a01783d28edc734b6932a7768978de65ffc..11331e1d48a87c9acb048db5130bf635ec834fe0 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -45,7 +45,6 @@ struct lt9611 {
 	struct device_node *dsi1_node;
 	struct mipi_dsi_device *dsi0;
 	struct mipi_dsi_device *dsi1;
-	struct platform_device *audio_pdev;
 
 	bool ac_mode;
 
@@ -864,6 +863,10 @@ static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge,
 	unsigned int mask;
 
 	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mask = LT9611_INFOFRAME_AUDIO;
+		break;
+
 	case HDMI_INFOFRAME_TYPE_AVI:
 		mask = LT9611_INFOFRAME_AVI;
 		break;
@@ -897,6 +900,11 @@ static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge,
 	int i;
 
 	switch (type) {
+	case HDMI_INFOFRAME_TYPE_AUDIO:
+		mask = LT9611_INFOFRAME_AUDIO;
+		addr = 0x84b2;
+		break;
+
 	case HDMI_INFOFRAME_TYPE_AVI:
 		mask = LT9611_INFOFRAME_AVI;
 		addr = 0x8440;
@@ -940,6 +948,55 @@ lt9611_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,
 	return MODE_OK;
 }
 
+static int lt9611_hdmi_audio_startup(struct drm_connector *connector,
+				     struct drm_bridge *bridge)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	regmap_write(lt9611->regmap, 0x82d6, 0x8c);
+	regmap_write(lt9611->regmap, 0x82d7, 0x04);
+
+	regmap_write(lt9611->regmap, 0x8406, 0x08);
+	regmap_write(lt9611->regmap, 0x8407, 0x10);
+
+	regmap_write(lt9611->regmap, 0x8434, 0xd5);
+
+	return 0;
+}
+
+static int lt9611_hdmi_audio_prepare(struct drm_connector *connector,
+				     struct drm_bridge *bridge,
+				     struct hdmi_codec_daifmt *fmt,
+				     struct hdmi_codec_params *hparms)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	if (hparms->sample_rate == 48000)
+		regmap_write(lt9611->regmap, 0x840f, 0x2b);
+	else if (hparms->sample_rate == 96000)
+		regmap_write(lt9611->regmap, 0x840f, 0xab);
+	else
+		return -EINVAL;
+
+	regmap_write(lt9611->regmap, 0x8435, 0x00);
+	regmap_write(lt9611->regmap, 0x8436, 0x18);
+	regmap_write(lt9611->regmap, 0x8437, 0x00);
+
+	return drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
+								       &hparms->cea);
+}
+
+static void lt9611_hdmi_audio_shutdown(struct drm_connector *connector,
+				       struct drm_bridge *bridge)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+
+	drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector);
+
+	regmap_write(lt9611->regmap, 0x8406, 0x00);
+	regmap_write(lt9611->regmap, 0x8407, 0x00);
+}
+
 static const struct drm_bridge_funcs lt9611_bridge_funcs = {
 	.attach = lt9611_bridge_attach,
 	.mode_valid = lt9611_bridge_mode_valid,
@@ -960,6 +1017,10 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = {
 	.hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid,
 	.hdmi_write_infoframe = lt9611_hdmi_write_infoframe,
 	.hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe,
+
+	.hdmi_audio_startup = lt9611_hdmi_audio_startup,
+	.hdmi_audio_prepare = lt9611_hdmi_audio_prepare,
+	.hdmi_audio_shutdown = lt9611_hdmi_audio_shutdown,
 };
 
 static int lt9611_parse_dt(struct device *dev,
@@ -1013,102 +1074,6 @@ static int lt9611_read_device_rev(struct lt9611 *lt9611)
 	return ret;
 }
 
-static int lt9611_hdmi_hw_params(struct device *dev, void *data,
-				 struct hdmi_codec_daifmt *fmt,
-				 struct hdmi_codec_params *hparms)
-{
-	struct lt9611 *lt9611 = data;
-
-	if (hparms->sample_rate == 48000)
-		regmap_write(lt9611->regmap, 0x840f, 0x2b);
-	else if (hparms->sample_rate == 96000)
-		regmap_write(lt9611->regmap, 0x840f, 0xab);
-	else
-		return -EINVAL;
-
-	regmap_write(lt9611->regmap, 0x8435, 0x00);
-	regmap_write(lt9611->regmap, 0x8436, 0x18);
-	regmap_write(lt9611->regmap, 0x8437, 0x00);
-
-	return 0;
-}
-
-static int lt9611_audio_startup(struct device *dev, void *data)
-{
-	struct lt9611 *lt9611 = data;
-
-	regmap_write(lt9611->regmap, 0x82d6, 0x8c);
-	regmap_write(lt9611->regmap, 0x82d7, 0x04);
-
-	regmap_write(lt9611->regmap, 0x8406, 0x08);
-	regmap_write(lt9611->regmap, 0x8407, 0x10);
-
-	regmap_write(lt9611->regmap, 0x8434, 0xd5);
-
-	return 0;
-}
-
-static void lt9611_audio_shutdown(struct device *dev, void *data)
-{
-	struct lt9611 *lt9611 = data;
-
-	regmap_write(lt9611->regmap, 0x8406, 0x00);
-	regmap_write(lt9611->regmap, 0x8407, 0x00);
-}
-
-static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				      struct device_node *endpoint,
-				      void *data)
-{
-	struct of_endpoint of_ep;
-	int ret;
-
-	ret = of_graph_parse_endpoint(endpoint, &of_ep);
-	if (ret < 0)
-		return ret;
-
-	/*
-	 * HDMI sound should be located as reg = <2>
-	 * Then, it is sound port 0
-	 */
-	if (of_ep.port == 2)
-		return 0;
-
-	return -EINVAL;
-}
-
-static const struct hdmi_codec_ops lt9611_codec_ops = {
-	.hw_params	= lt9611_hdmi_hw_params,
-	.audio_shutdown = lt9611_audio_shutdown,
-	.audio_startup	= lt9611_audio_startup,
-	.get_dai_id	= lt9611_hdmi_i2s_get_dai_id,
-};
-
-static struct hdmi_codec_pdata codec_data = {
-	.ops = &lt9611_codec_ops,
-	.max_i2s_channels = 8,
-	.i2s = 1,
-};
-
-static int lt9611_audio_init(struct device *dev, struct lt9611 *lt9611)
-{
-	codec_data.data = lt9611;
-	lt9611->audio_pdev =
-		platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
-					      PLATFORM_DEVID_AUTO,
-					      &codec_data, sizeof(codec_data));
-
-	return PTR_ERR_OR_ZERO(lt9611->audio_pdev);
-}
-
-static void lt9611_audio_exit(struct lt9611 *lt9611)
-{
-	if (lt9611->audio_pdev) {
-		platform_device_unregister(lt9611->audio_pdev);
-		lt9611->audio_pdev = NULL;
-	}
-}
-
 static int lt9611_probe(struct i2c_client *client)
 {
 	struct lt9611 *lt9611;
@@ -1172,6 +1137,9 @@ static int lt9611_probe(struct i2c_client *client)
 
 	i2c_set_clientdata(client, lt9611);
 
+	/* Disable Audio InfoFrame, enabled by default */
+	regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, 0);
+
 	lt9611->bridge.funcs = &lt9611_bridge_funcs;
 	lt9611->bridge.of_node = client->dev.of_node;
 	lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
@@ -1180,6 +1148,9 @@ static int lt9611_probe(struct i2c_client *client)
 	lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	lt9611->bridge.vendor = "Lontium";
 	lt9611->bridge.product = "LT9611";
+	lt9611->bridge.hdmi_audio_dev = dev;
+	lt9611->bridge.hdmi_audio_max_i2s_playback_channels = 8;
+	lt9611->bridge.hdmi_audio_dai_port = 2;
 
 	drm_bridge_add(&lt9611->bridge);
 
@@ -1201,10 +1172,6 @@ static int lt9611_probe(struct i2c_client *client)
 
 	lt9611_enable_hpd_interrupts(lt9611);
 
-	ret = lt9611_audio_init(dev, lt9611);
-	if (ret)
-		goto err_remove_bridge;
-
 	return 0;
 
 err_remove_bridge:
@@ -1225,7 +1192,6 @@ static void lt9611_remove(struct i2c_client *client)
 	struct lt9611 *lt9611 = i2c_get_clientdata(client);
 
 	disable_irq(client->irq);
-	lt9611_audio_exit(lt9611);
 	drm_bridge_remove(&lt9611->bridge);
 
 	regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);

-- 
2.39.5



From dmitry.baryshkov at linaro.org  Sun Dec 22 18:58:57 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 23 Dec 2024 04:58:57 +0200
Subject: [PATCH v9 06/10] drm/display/hdmi: implement hotplug functions
In-Reply-To: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
References: <20241223-drm-bridge-hdmi-connector-v9-0-6ce16bcedb8b@linaro.org>
Message-ID: <20241223-drm-bridge-hdmi-connector-v9-6-6ce16bcedb8b@linaro.org>

The HDMI Connectors need to perform a variety of tasks when the HDMI
connector state changes. Such tasks include setting or invalidating CEC
address, notifying HDMI codec driver, updating scrambler data, etc.

Implementing such tasks in a driver-specific callbacks is error prone.
Start implementing the generic helper function (currently handling only
the HDMI Codec framework) to be used by drivers utilizing HDMI Connector
framework.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Tested-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/gpu/drm/display/Kconfig                 |  1 +
 drivers/gpu/drm/display/drm_hdmi_state_helper.c | 56 +++++++++++++++++++++++++
 include/drm/display/drm_hdmi_state_helper.h     |  5 +++
 include/drm/drm_connector.h                     | 16 +++++++
 4 files changed, 78 insertions(+)

diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
index 2619fa2476eb149e1befc3135131ed5aaeb5bb4c..8d22b7627d41f7bc015decf24ae02a05bc00f055 100644
--- a/drivers/gpu/drm/display/Kconfig
+++ b/drivers/gpu/drm/display/Kconfig
@@ -89,6 +89,7 @@ config DRM_DISPLAY_HDMI_HELPER
 
 config DRM_DISPLAY_HDMI_STATE_HELPER
 	bool
+	select DRM_DISPLAY_HDMI_AUDIO_HELPER
 	select DRM_DISPLAY_HDMI_HELPER
 	help
 	  DRM KMS state helpers for HDMI.
diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index d678c635a6935050ca9c1ccafbb0865f21df5d4e..f4935b3e630cd89ec6373eb67b06e6a3a3b3a55a 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -777,3 +777,59 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con
 	return ret;
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe);
+
+static void
+drm_atomic_helper_connector_hdmi_update(struct drm_connector *connector,
+					enum drm_connector_status status)
+{
+	const struct drm_edid *drm_edid;
+
+	if (status == connector_status_disconnected) {
+		// TODO: also handle CEC and scramber, HDMI sink disconnected.
+		drm_connector_hdmi_audio_plugged_notify(connector, false);
+	}
+
+	if (connector->hdmi.funcs->read_edid)
+		drm_edid = connector->hdmi.funcs->read_edid(connector);
+	else
+		drm_edid = drm_edid_read(connector);
+
+	drm_edid_connector_update(connector, drm_edid);
+
+	drm_edid_free(drm_edid);
+
+	if (status == connector_status_connected) {
+		// TODO: also handle CEC and scramber, HDMI sink is now connected.
+		drm_connector_hdmi_audio_plugged_notify(connector, true);
+	}
+}
+
+/**
+ * drm_atomic_helper_connector_hdmi_hotplug - Handle the hotplug event for the HDMI connector
+ * @connector: A pointer to the HDMI connector
+ * @status: Connection status
+ *
+ * This function should be called as a part of the .detect() / .detect_ctx()
+ * callbacks, updating the HDMI-specific connector's data.
+ */
+void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
+					      enum drm_connector_status status)
+{
+	drm_atomic_helper_connector_hdmi_update(connector, status);
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_hotplug);
+
+/**
+ * drm_atomic_helper_connector_hdmi_force - HDMI Connector implementation of the force callback
+ * @connector: A pointer to the HDMI connector
+ *
+ * This function implements the .force() callback for the HDMI connectors. It
+ * can either be used directly as the callback or should be called from within
+ * the .force() callback implementation to maintain the HDMI-specific
+ * connector's data.
+ */
+void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector)
+{
+	drm_atomic_helper_connector_hdmi_update(connector, connector->status);
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_force);
diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h
index d6d65da6d8f9ee46de33114cce2d6fbe6098a862..9ae19f3caf727f9a0fe06e6afe5fc46db924444f 100644
--- a/include/drm/display/drm_hdmi_state_helper.h
+++ b/include/drm/display/drm_hdmi_state_helper.h
@@ -8,6 +8,8 @@ struct drm_connector;
 struct drm_connector_state;
 struct hdmi_audio_infoframe;
 
+enum drm_connector_status;
+
 void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
 					      struct drm_connector_state *new_conn_state);
 
@@ -19,6 +21,9 @@ int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector
 int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector);
 int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
 						       struct drm_atomic_state *state);
+void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
+					      enum drm_connector_status status);
+void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector);
 
 enum drm_mode_status
 drm_hdmi_connector_mode_valid(struct drm_connector *connector,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 19e4256296657b0f1d203266d152cbba42f9726a..dac8048c82f913b9cfaf785cafe85080a9b2655c 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -45,6 +45,7 @@ struct drm_property;
 struct drm_property_blob;
 struct drm_printer;
 struct drm_privacy_screen;
+struct drm_edid;
 struct edid;
 struct hdmi_codec_daifmt;
 struct hdmi_codec_params;
@@ -1247,6 +1248,21 @@ struct drm_connector_hdmi_funcs {
 	int (*write_infoframe)(struct drm_connector *connector,
 			       enum hdmi_infoframe_type type,
 			       const u8 *buffer, size_t len);
+
+	/**
+	 * @read_edid:
+	 *
+	 * This callback is used by the framework as a replacement for reading
+	 * the EDID from connector->ddc. It is still recommended to provide
+	 * connector->ddc instead of implementing this callback. Returned EDID
+	 * should be freed via the drm_edid_free().
+	 *
+	 * The @read_edid callback is optional.
+	 *
+	 * Returns:
+	 * Valid EDID on success, NULL in case of failure.
+	 */
+	const struct drm_edid *(*read_edid)(struct drm_connector *connector);
 };
 
 /**

-- 
2.39.5



From ck.hu at mediatek.com  Sun Dec 22 19:06:27 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 23 Dec 2024 03:06:27 +0000
Subject: [PATCH v3 07/33] dt-bindings: display: mediatek: Add binding for
 MT8195 HDMI-TX v2
In-Reply-To: <425fd1b0-fcba-4547-81f6-84acee5ce7f4@kernel.org>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-8-angelogioacchino.delregno@collabora.com>
	 <rsnyljmkdf7i74bkrlf5nesp2sa3n6xcnzsqao4znmczjpfyq2@dsakz56s4ypt>
	 <9a75e88c-d90d-4ea8-b5c3-6d056d4f0498@collabora.com>
	 <425fd1b0-fcba-4547-81f6-84acee5ce7f4@kernel.org>
Message-ID: <47fe777804cc9666422bfd6b492b78fe1953371a.camel@mediatek.com>

On Sat, 2024-12-21 at 21:22 +0100, Krzysztof Kozlowski wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> On 19/12/2024 11:54, AngeloGioacchino Del Regno wrote:
> > > hdmi@
> > > 
> > > Best regards,
> > > Krzysztof
> > > 
> > 
> > Thanks for the great review krzk.
> > 
> > I was wondering if it'd be more straightforward to just send the bindings in a
> > different series, instead of sending another batch of 33 (actually, 34, because
> > I forgot one commit adding the DDC binding, ugh!) patches...
> > 
> > CK, any objections?

I prefer keep binding and driver in the same series.
Of course you could choose to separate them, but in the same series is easier to review.

Regards,
CK

> Maybe just wait few more days for other people's review and then send v4
> of everything? You can split the bindings separately, although there is
> a risk we will get confused or we will forgot why they got separated.
> 
> Best regards,
> Krzysztof


From carlos.song at nxp.com  Sun Dec 22 19:43:43 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Mon, 23 Dec 2024 11:43:43 +0800
Subject: [PATCH v3] i2c: imx: switch different pinctrl state in different system power status
Message-ID: <20241223034343.544002-1-carlos.song@nxp.com>

Switch different pinctrl state in different system power status.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Reviewed-by: Frank Li <Frank.Li at nxp.com>
---
Change fot V3:
- According to Oleksij's comment, return values for
  pinctrl_setect_state.
Change for V2:
- Add Frank reviewed-by. No code change.
---
 drivers/i2c/busses/i2c-imx.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 6fb496a92817..d0cfb8eac580 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -1869,8 +1869,7 @@ static int i2c_imx_runtime_suspend(struct device *dev)
 	struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
 
 	clk_disable(i2c_imx->clk);
-
-	return 0;
+	return pinctrl_pm_select_sleep_state(dev);
 }
 
 static int i2c_imx_runtime_resume(struct device *dev)
@@ -1878,6 +1877,10 @@ static int i2c_imx_runtime_resume(struct device *dev)
 	struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev);
 	int ret;
 
+	ret = pinctrl_pm_select_default_state(dev);
+	if (ret)
+		return ret;
+
 	ret = clk_enable(i2c_imx->clk);
 	if (ret)
 		dev_err(dev, "can't enable I2C clock, ret=%d\n", ret);
-- 
2.34.1



From carlos.song at nxp.com  Sun Dec 22 19:44:16 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Mon, 23 Dec 2024 11:44:16 +0800
Subject: [PATCH v6] i2c: imx: support DMA defer probing
Message-ID: <20241223034416.544022-1-carlos.song@nxp.com>

Return -EPROBE_DEFER when dma_request_slave_channel() because DMA driver
have not ready yet.

Move i2c_imx_dma_request() before registering I2C adapter to avoid
infinite loop of .probe() calls to the same driver, see "e8c220fac415
Revert "i2c: imx: improve the error handling in i2c_imx_dma_request()""
and "Documentation/driver-api/driver-model/driver.rst".

Use CPU mode to avoid stuck registering i2c adapter when DMA resources
are unavailable.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Signed-off-by: Clark Wang <xiaoning.wang at nxp.com>
Acked-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
Acked-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
Change for V6:
- According to Ahmad and Oleksij's comment, use dev_err to print error
  log in failing setting up DMA path and simplify code comment.
Change for V5:
- Add Ahmad Acked-by. No code change.
Change for V4:
- Output "Only use PIO mode" log in debug level when no DMA configure.
Change for V3:
- According to Marc's comment, remove error print when defer probe.
  Add info log when DMA has not been enabled and add error log when
  DMA error, both won't stuck the i2c adapter register, just for reminding,
  i2c adapter is working only in PIO mode.
Change for V2:
- According to Frank's comments, wrap at 75 char and Simplify fix code
  at i2c_imx_dma_request().
- Use strict patch check, fix alignment warning at i2c_imx_dma_request()
---
 drivers/i2c/busses/i2c-imx.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 1f441227bfdc..9ac02640fdff 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -397,17 +397,16 @@ static void i2c_imx_reset_regs(struct imx_i2c_struct *i2c_imx)
 }
 
 /* Functions for DMA support */
-static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
-						dma_addr_t phy_addr)
+static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx, dma_addr_t phy_addr)
 {
 	struct imx_i2c_dma *dma;
 	struct dma_slave_config dma_sconfig;
-	struct device *dev = &i2c_imx->adapter.dev;
+	struct device *dev = i2c_imx->adapter.dev.parent;
 	int ret;
 
 	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
 	if (!dma)
-		return;
+		return -ENOMEM;
 
 	dma->chan_tx = dma_request_chan(dev, "tx");
 	if (IS_ERR(dma->chan_tx)) {
@@ -452,7 +451,7 @@ static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 	dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n",
 		dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx));
 
-	return;
+	return 0;
 
 fail_rx:
 	dma_release_channel(dma->chan_rx);
@@ -460,6 +459,8 @@ static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 	dma_release_channel(dma->chan_tx);
 fail_al:
 	devm_kfree(dev, dma);
+
+	return ret;
 }
 
 static void i2c_imx_dma_callback(void *arg)
@@ -1802,6 +1803,18 @@ static int i2c_imx_probe(struct platform_device *pdev)
 	if (ret == -EPROBE_DEFER)
 		goto clk_notifier_unregister;
 
+	/* As we can always fall back to PIO, let's ignore the error setting up DMA. */
+	ret = i2c_imx_dma_request(i2c_imx, phy_addr);
+	if (ret) {
+		if (ret == -EPROBE_DEFER)
+			goto clk_notifier_unregister;
+		else if (ret == -ENODEV)
+			dev_dbg(&pdev->dev, "Only use PIO mode\n");
+		else
+			dev_err(&pdev->dev, "Failed to setup DMA (%pe), only use PIO mode\n",
+				ERR_PTR(ret));
+	}
+
 	/* Add I2C adapter */
 	ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
 	if (ret < 0)
@@ -1816,9 +1829,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
 		i2c_imx->adapter.name);
 	dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
 
-	/* Init DMA config if supported */
-	i2c_imx_dma_request(i2c_imx, phy_addr);
-
 	return 0;   /* Return OK */
 
 clk_notifier_unregister:
-- 
2.34.1



From wangzhengshu39 at gmail.com  Sun Dec 22 19:34:58 2024
From: wangzhengshu39 at gmail.com (wzs)
Date: Mon, 23 Dec 2024 11:34:58 +0800
Subject: WARNING: kernel stack regs has bad "bp" value
Message-ID: <CAGXGE_LB3RBqujRWE4fai5hrG6WHk-_c9mToEc0Q_1rBY7M9Xg@mail.gmail.com>

Hello,
when fuzzing the Linux Kernel,
i encountered several rare kernel warnings.
It seems that the warning is related to the kernel stack.
The versions in which this appeared are from Linux-6.8.0 to 6.13-rc3.

The two warning messages I provide below are both from the latest
kernel version, Linux-6.13-rc3.
If you need warnings from other versions, I would be happy to provide
them as well.

kernel config :https://pastebin.com/hGFvz9vz
console output1 :https://pastebin.com/7vBkDAvK
console output2 : https://pastebin.com/T8h3Hnrr

The crash reports are as follows:
crash 1:
[71848.072650] WARNING: kernel stack regs at ffffc9001e21f818 in
code:43499 has bad 'bp' value 00000000f710950f
[71848.073989] unwind stack type:0 next_sp:0000000000000000 mask:0x6 graph_idx:0
[71848.073993] ffffc90000e68930: ffffc90000e689d8 (0xffffc90000e689d8)
[71848.074555] ffffc90000e68938: ffffffff913b8b28 (arch_stack_walk+0x88/0x100)
[71848.075718] ffffc90000e68940: 0000000000000000 ...
[71848.075723] ffffc90000e68948: ffffc9001e218000 (0xffffc9001e218000)
[71848.075728] ffffc90000e68950: ffffc9001e220000 (0xffffc9001e220000)
[71848.075730] ffffc90000e68958: 0000000000000000 ...
[71848.075732] ffffc90000e68960: 0000000000000006 (0x6)
[71848.075734] ffffc90000e68968: ffff8881922b5540 (0xffff8881922b5540)
[71848.075736] ffffc90000e68970: 0000000000000000 ...
[71848.075738] ffffc90000e68980: 0000000000000101 (0x101)
[71848.075740] ffffc90000e68988: 0000000000000000 ...
[71848.075741] ffffc90000e68990: ffffc90000e68930 (0xffffc90000e68930)
[71848.075744] ffffc90000e68998: ffffffffc0a920b4
(vmw_send_msg+0x4a4/0x570 [vmwgfx])
[71848.078299] ffffc90000e689a0: 0000000000000000 ...
[71848.078304] ffffc90000e689a8: ffffc9001e21f818 (0xffffc9001e21f818)
[71848.078308] ffffc90000e689b0: 0c85f283dc076700 (0xc85f283dc076700)
[71848.078311] ffffc90000e689b8: fffff520001cd13d (0xfffff520001cd13d)
[71848.078313] ffffc90000e689c0: 0000000000000000 ...
[71848.078315] ffffc90000e689c8: 0000000000000001 (0x1)
[71848.078317] ffffc90000e689d0: ffff888111312020 (0xffff888111312020)
[71848.078319] ffffc90000e689d8: ffffc90000e68a70 (0xffffc90000e68a70)
[71848.078321] ffffc90000e689e0: ffffffff9179b7c3 (stack_trace_save+0x93/0xd0)
[71848.078870] ffffc90000e689e8: 0000000041b58ab3 (0x41b58ab3)
[71848.078873] ffffc90000e689f0: ffffffff9553fd64 (SIGMA2+0x12564/0x128c40)
[71848.080256] ffffc90000e689f8: ffffffff9179b730
(__pfx_stack_trace_save+0x10/0x10)
[71848.080259] ffffc90000e68a00: ffffc90000e689a0 (0xffffc90000e689a0)
[71848.080262] ffffc90000e68a08: ffffc90000e68a80 (0xffffc90000e68a80)
[71848.080263] ffffc90000e68a10: 0000000000000040 (0x40)
[71848.080265] ffffc90000e68a18: 000000000000000f (0xf)
[71848.080266] ffffc90000e68a20: 0c85f283dc076700 (0xc85f283dc076700)
[71848.080268] ffffc90000e68a28: fffff520001cd14b (0xfffff520001cd14b)
[71848.080269] ffffc90000e68a30: 0000000000000000 ...
[71848.080270] ffffc90000e68a38: 0000000000000001 (0x1)
[71848.080272] ffffc90000e68a40: ffff888100ba4ac0 (0xffff888100ba4ac0)
[71848.080273] ffffc90000e68a48: ffffc90000e68ae0 (0xffffc90000e68ae0)
[71848.080274] ffffc90000e68a50: ffffffff9179b7c3 (stack_trace_save+0x93/0xd0)
[71848.080276] ffffc90000e68a58: 0000000041b58ab3 (0x41b58ab3)
[71848.080277] ffffc90000e68a60: 0c85f283dc076700 (0xc85f283dc076700)
[71848.080279] ffffc90000e68a68: ffff8881113120b4 (0xffff8881113120b4)
[71848.080280] ffffc90000e68a70: ffffc90000e68c90 (0xffffc90000e68c90)
[71848.080281] ffffc90000e68a78: ffffffff91f18b18 (kasan_save_stack+0x28/0x60)
[71848.080980] ffffc90000e68a80: ffffffff91f18b18 (kasan_save_stack+0x28/0x60)
[71848.080983] ffffc90000e68a88: ffffffff91f18be8 (kasan_save_track+0x18/0x70)
[71848.080985] ffffc90000e68a90: ffffffff91f1c7cb
(kasan_save_free_info+0x3b/0x60)
[71848.081002] ffffc90000e68a98: ffffffff91f18fd4 (__kasan_slab_free+0x54/0x80)
[71848.081004] ffffc90000e68aa0: ffffffff91e81bb5 (kfree+0x115/0x4b0)
[71848.081237] ffffc90000e68aa8: ffffffff91e86711
(slab_free_after_rcu_debug+0x61/0x370)
[71848.081240] ffffc90000e68ab0: ffffffff9173bc35 (rcu_do_batch+0x405/0xfd0)
[71848.081447] ffffc90000e68ab8: ffffffff91742721 (rcu_core+0x5b1/0xcc0)
[71848.081449] ffffc90000e68ac0: ffffffff917435ee (rcu_core_si+0xe/0x20)
[71848.081452] ffffc90000e68ac8: ffffffff9150c7fb (handle_softirqs+0x1ab/0x680)
[71848.081717] ffffc90000e68ad0: ffffffff9150ceb4 (__irq_exit_rcu+0x1d4/0x240)
[71848.081721] ffffc90000e68ad8: ffffffff9150eace (irq_exit_rcu+0xe/0x20)
[71848.081723] ffffc90000e68ae0: ffffffff945e9156
(sysvec_apic_timer_interrupt+0x96/0xb0)
[71848.082383] ffffc90000e68ae8: ffffffff94800f0b
(asm_sysvec_apic_timer_interrupt+0x1b/0x20)
[71848.082665] ffffc90000e68af0: ffffffffc0a920b4
(vmw_send_msg+0x4a4/0x570 [vmwgfx])
[71848.082693] ffffc90000e68af8: ffffc90000e68b08 (0xffffc90000e68b08)
[71848.082696] ffffc90000e68b00: ffffffff945e7119 (sched_clock_noinstr+0x9/0x10)
[71848.082909] ffffc90000e68b08: ffffc90000e68b18 (0xffffc90000e68b18)
[71848.082912] ffffc90000e68b10: ffffffff9139e0a0 (sched_clock+0x10/0x30)
[71848.083113] ffffc90000e68b18: ffffc90000e68bd8 (0xffffc90000e68bd8)
[71848.083115] ffffc90000e68b20: ffffffff9167850a (sched_clock_cpu+0x6a/0x520)
[71848.083120] ffffc90000e68b28: ffff88862ec47240 (0xffff88862ec47240)
[71848.083121] ffffc90000e68b30: ffffc90000e68b80 (0xffffc90000e68b80)
[71848.083122] ffffc90000e68b38: ffffffff915f3113 (update_curr+0x343/0x5a0)
[71848.083137] ffffc90000e68b40: ffff888107a37400 (0xffff888107a37400)
[71848.083139] ffffc90000e68b48: ffff88862ec47240 (0xffff88862ec47240)
[71848.083140] ffffc90000e68b50: 0000000041b58ab3 (0x41b58ab3)
[71848.083141] ffffc90000e68b58: ffffffff95538f94 (SIGMA2+0xb794/0x128c40)
[71848.083145] ffffc90000e68b60: ffffffff916784a0
(__pfx_sched_clock_cpu+0x10/0x10)
[71848.083147] ffffc90000e68b68: ffff88862ec472c8 (0xffff88862ec472c8)
[71848.083148] ffffc90000e68b70: ffff888107a37450 (0xffff888107a37450)
[71848.083149] ffffc90000e68b78: 0000000000070c49 (0x70c49)
[71848.083151] ffffc90000e68b80: ffffc90000e68c00 (0xffffc90000e68c00)
[71848.083152] ffffc90000e68b88: ffffffff915fea2f (reweight_entity+0x3df/0xad0)
[71848.083165] ffffc90000e68b90: ffff888107a374c8 (0xffff888107a374c8)
[71848.083166] ffffc90000e68b98: ffff888107a374e0 (0xffff888107a374e0)
[71848.083168] ffffc90000e68ba0: ffff88862ec472e0 (0xffff88862ec472e0)
[71848.083169] ffffc90000e68ba8: ffff888107a37410 (0xffff888107a37410)
[71848.083170] ffffc90000e68bb0: ffff88862e747180 (0xffff88862e747180)
[71848.083171] ffffc90000e68bb8: 0c85f283dc076700 (0xc85f283dc076700)
[71848.083173] ffffc90000e68bc0: ffffc90000e68c20 (0xffffc90000e68c20)
[71848.083174] ffffc90000e68bc8: 1ffff920001cd186 (0x1ffff920001cd186)
[71848.083175] ffffc90000e68bd0: ffff88862ec47140 (0xffff88862ec47140)
[71848.083177] ffffc90000e68bd8: ffffc90000e68be8 (0xffffc90000e68be8)
[71848.083178] ffffc90000e68be0: ffffffff945e7119 (sched_clock_noinstr+0x9/0x10)
[71848.083181] ffffc90000e68be8: ffffc90000e68bf8 (0xffffc90000e68bf8)
[71848.083182] ffffc90000e68bf0: ffffffff9139e0a0 (sched_clock+0x10/0x30)
[71848.083184] ffffc90000e68bf8: ffff8881b0d0b200 (0xffff8881b0d0b200)
[71848.083185] ffffc90000e68c00: ffff88862ec47140 (0xffff88862ec47140)
[71848.083186] ffffc90000e68c08: 00000000000050d3 (0x50d3)
[71848.083188] ffffc90000e68c10: ffffc90000e68c60 (0xffffc90000e68c60)
[71848.083189] ffffc90000e68c18: ffffffff915f2e49 (update_curr+0x79/0x5a0)
[71848.083191] ffffc90000e68c20: ffffffff91724b53 (invoke_rcu_core+0x93/0x170)
[71848.083204] ffffc90000e68c28: ffffffff916568c4
(dl_scaled_delta_exec+0xe4/0x300)
[71848.083216] ffffc90000e68c30: 0000000041b58ab3 (0x41b58ab3)
[71848.083217] ffffc90000e68c38: 000000000000cab6 (0xcab6)
[71848.083219] ffffc90000e68c40: ffff88862ec47240 (0xffff88862ec47240)
[71848.083220] ffffc90000e68c48: ffff88862ec472c8 (0xffff88862ec472c8)
[71848.083222] ffffc90000e68c50: ffff8881b0d0b250 (0xffff8881b0d0b250)
[71848.083224] ffffc90000e68c58: 000000000000cab6 (0xcab6)
[71848.083225] ffffc90000e68c60: ffffc90000e68ce0 (0xffffc90000e68ce0)
[71848.083226] ffffc90000e68c68: ffffffff915fea2f (reweight_entity+0x3df/0xad0)
[71848.083229] ffffc90000e68c70: ffff8881b0d0b2c8 (0xffff8881b0d0b2c8)
[71848.083230] ffffc90000e68c78: ffff8881b0d0b2e0 (0xffff8881b0d0b2e0)
[71848.083231] ffffc90000e68c80: ffff888111312020 (0xffff888111312020)
[71848.083233] ffffc90000e68c88: ffff88810004f840 (0xffff88810004f840)
[71848.083234] ffffc90000e68c90: ffffc90000e68cb8 (0xffffc90000e68cb8)
[71848.083235] ffffc90000e68c98: ffffffff91f18be8 (kasan_save_track+0x18/0x70)
[71848.083238] ffffc90000e68ca0: ffffed1022262404 (0xffffed1022262404)
[71848.083239] ffffc90000e68ca8: ffff888111312020 (0xffff888111312020)
[71848.083241] ffffc90000e68cb0: ffff88810004f840 (0xffff88810004f840)
[71848.083242] ffffc90000e68cb8: ffffc90000e68cd0 (0xffffc90000e68cd0)
[71848.083243] ffffc90000e68cc0: ffffffff91f1c7cb
(kasan_save_free_info+0x3b/0x60)
[71848.083246] ffffc90000e68cc8: 0000000000000000 ...
[71848.083247] ffffc90000e68cd0: ffffc90000e68cf0 (0xffffc90000e68cf0)
[71848.083248] ffffc90000e68cd8: ffffffff91f18fd4 (__kasan_slab_free+0x54/0x80)
[71848.083251] ffffc90000e68ce0: ffff88810004f840 (0xffff88810004f840)
[71848.083252] ffffc90000e68ce8: ffffea000444c480 (0xffffea000444c480)
[71848.083253] ffffc90000e68cf0: ffffc90000e68d60 (0xffffc90000e68d60)
[71848.083254] ffffc90000e68cf8: ffffffff91e81bb5 (kfree+0x115/0x4b0)
[71848.083257] ffffc90000e68d00: ffffffff9566ce90
(__per_cpu_offset+0x10/0x10000)
[71848.083270] ffffc90000e68d08: 0000000000000002 (0x2)
[71848.083271] ffffc90000e68d10: ffffffff91e86711
(slab_free_after_rcu_debug+0x61/0x370)
[71848.083274] ffffc90000e68d18: ffffff0091f1d231 (0xffffff0091f1d231)
[71848.083275] ffffc90000e68d20: ffff888111312020 (0xffff888111312020)
[71848.083277] ffffc90000e68d28: 0c85f283dc076700 (0xc85f283dc076700)
[71848.083278] ffffc90000e68d30: ffff88862ec41120 (0xffff88862ec41120)
[71848.083279] ffffc90000e68d38: dffffc0000000000 (0xdffffc0000000000)
[71848.083280] ffffc90000e68d40: ffffea0007941e00 (0xffffea0007941e00)
[71848.083281] ffffc90000e68d48: ffff8881e5078940 (0xffff8881e5078940)
[71848.083283] ffffc90000e68d50: ffff888111312020 (0xffff888111312020)
[71848.083284] ffffc90000e68d58: 0000000000000000 ...
[71848.083285] ffffc90000e68d60: ffffc90000e68db0 (0xffffc90000e68db0)
[71848.083286] ffffc90000e68d68: ffffffff91e86711
(slab_free_after_rcu_debug+0x61/0x370)
[71848.083288] ffffc90000e68d70: ffff8881922b5540 (0xffff8881922b5540)
[71848.083290] ffffc90000e68d78: ffff88862ec47c70 (0xffff88862ec47c70)
[71848.083291] ffffc90000e68d80: 000000000000000c (0xc)
[71848.083292] ffffc90000e68d88: dffffc0000000000 (0xdffffc0000000000)
[71848.083293] ffffc90000e68d90: 0000000000000001 (0x1)
[71848.083294] ffffc90000e68d98: ffff88862ec48080 (0xffff88862ec48080)
[71848.083296] ffffc90000e68da0: ffffc90000e68e48 (0xffffc90000e68e48)
[71848.083297] ffffc90000e68da8: 0000000000000000 ...
[71848.083298] ffffc90000e68db0: ffffc90000e68ed0 (0xffffc90000e68ed0)
[71848.083299] ffffc90000e68db8: ffffffff9173bc35 (rcu_do_batch+0x405/0xfd0)
[71848.083302] ffffc90000e68dc0: ffff88862ec48188 (0xffff88862ec48188)
[71848.083303] ffffc90000e68dc8: ffff88862ec48170 (0xffff88862ec48170)
[71848.083304] ffffc90000e68dd0: 1ffff920001cd1c5 (0x1ffff920001cd1c5)
[71848.083305] ffffc90000e68dd8: ffff88862ec48158 (0xffff88862ec48158)
[71848.083307] ffffc90000e68de0: 000000000189d1cc (0x189d1cc)
[71848.083308] ffffc90000e68de8: ffff88862ec48080 (0xffff88862ec48080)
[71848.083309] ffffc90000e68df0: ffff88862ec48140 (0xffff88862ec48140)
[71848.083310] ffffc90000e68df8: ffff88862ec48168 (0xffff88862ec48168)
[71848.083312] ffffc90000e68e00: ffffed1032456aa8 (0xffffed1032456aa8)
[71848.083313] ffffc90000e68e08: ffff8881922b5540 (0xffff8881922b5540)
[71848.083314] ffffc90000e68e10: ffff88862ec480f8 (0xffff88862ec480f8)
[71848.083315] ffffc90000e68e18: 000000000000000a (0xa)
[71848.083316] ffffc90000e68e20: 0000000000000000 ...
[71848.083317] ffffc90000e68e28: 0000000041b58ab3 (0x41b58ab3)
[71848.083319] ffffc90000e68e30: ffffffff9553d848 (SIGMA2+0x10048/0x128c40)
[71848.083321] ffffc90000e68e38: ffffffff9173b830 (__pfx_rcu_do_batch+0x10/0x10)
[71848.083322] ffffc90000e68e40: ffffffff95b06608 (rcu_state+0x2c8/0x59ba0)
[71848.083632] ffffc90000e68e48: ffff888111313520 (0xffff888111313520)
[71848.083635] ffffc90000e68e50: ffff888148fd7438 (0xffff888148fd7438)
[71848.083637] ffffc90000e68e58: 0000000000000047 (0x47)
[71848.083638] ffffc90000e68e60: 0000000000000000 ...
[71848.083639] ffffc90000e68e68: ffff88862ec35fe8 (0xffff88862ec35fe8)
[71848.083641] ffffc90000e68e70: fffffbfff2cf39ac (0xfffffbfff2cf39ac)
[71848.083642] ffffc90000e68e78: 000000000189d1c5 (0x189d1c5)
[71848.083644] ffffc90000e68e80: ffff88862ec48080 (0xffff88862ec48080)
[71848.083645] ffffc90000e68e88: ffffffff95b06600 (rcu_state+0x2c0/0x59ba0)
[71848.083647] ffffc90000e68e90: 0000000000000246 (0x246)
[71848.083649] ffffc90000e68e98: ffff88862ec48080 (0xffff88862ec48080)
[71848.083650] ffffc90000e68ea0: 0c85f283dc076700 (0xc85f283dc076700)
[71848.083652] ffffc90000e68ea8: ffffffff9679cd60 (__futex_data+0x10/0x10)
[71848.084822] ffffc90000e68eb0: ffff88862ec480f8 (0xffff88862ec480f8)
[71848.084826] ffffc90000e68eb8: ffff88862ec48098 (0xffff88862ec48098)
[71848.084828] ffffc90000e68ec0: 00000000000462c8 (0x462c8)
[71848.084829] ffffc90000e68ec8: ffff88862ec48080 (0xffff88862ec48080)
[71848.084830] ffffc90000e68ed0: ffffc90000e68f30 (0xffffc90000e68f30)
[71848.084832] ffffc90000e68ed8: ffffffff91742721 (rcu_core+0x5b1/0xcc0)
[71848.084835] ffffc90000e68ee0: ffff88862ec36078 (0xffff88862ec36078)
[71848.084836] ffffc90000e68ee8: ffff88862ec360b8 (0xffff88862ec360b8)
[71848.084837] ffffc90000e68ef0: ffffc90000e68f18 (0xffffc90000e68f18)
[71848.084838] ffffc90000e68ef8: ffffffff917e78a8 (tick_program_event+0x68/0xf0)
[71848.084879] ffffc90000e68f00: ffffffff95b06600 (rcu_state+0x2c0/0x59ba0)
[71848.084882] ffffc90000e68f08: 000000000000000a (0xa)
[71848.084883] ffffc90000e68f10: 0000000000000100 (0x100)
[71848.084885] ffffc90000e68f18: 0000000000000009 (0x9)
[71848.084886] ffffc90000e68f20: 0000000000000200 (0x200)
[71848.084887] ffffc90000e68f28: ffffffff9580b108 (softirq_vec+0x48/0x80)
[71848.085174] ffffc90000e68f30: ffffc90000e68f40 (0xffffc90000e68f40)
[71848.085204] ffffc90000e68f38: ffffffff917435ee (rcu_core_si+0xe/0x20)
[71848.085209] ffffc90000e68f40: ffffc90000e68fb8 (0xffffc90000e68fb8)
[71848.085212] ffffc90000e68f48: ffffffff9150c7fb (handle_softirqs+0x1ab/0x680)
[71848.085217] ffffc90000e68f50: 004000402ec35f8c (0x4000402ec35f8c)
[71848.085219] ffffc90000e68f58: ffffed1032456aa8 (0xffffed1032456aa8)
[71848.085222] ffffc90000e68f60: ffff8881922b5540 (0xffff8881922b5540)
[71848.085259] ffffc90000e68f68: 000000010442ee5c (0x10442ee5c)
[71848.085263] ffffc90000e68f70: 00ff88860000000a (0xff88860000000a)
[71848.085265] ffffc90000e68f78: 000041587e022fc0 (0x41587e022fc0)
[71848.085268] ffffc90000e68f80: fffffbfff2cf39ac (0xfffffbfff2cf39ac)
[71848.085270] ffffc90000e68f88: ffffed1000000009 (0xffffed1000000009)
[71848.085272] ffffc90000e68f90: 0000000000000000 ...
[71848.085274] ffffc90000e68f98: ffffc9001e21f818 (0xffffc9001e21f818)
[71848.085276] ffffc90000e68fa0: 0000000000000000 ...
[71848.085278] ffffc90000e68fb8: ffffc90000e68fd8 (0xffffc90000e68fd8)
[71848.085280] ffffc90000e68fc0: ffffffff9150ceb4 (__irq_exit_rcu+0x1d4/0x240)
[71848.085286] ffffc90000e68fc8: 0000000000000000 ...
[71848.085288] ffffc90000e68fd0: ffffc9001e21f818 (0xffffc9001e21f818)
[71848.085290] ffffc90000e68fd8: ffffc90000e68fe8 (0xffffc90000e68fe8)
[71848.085292] ffffc90000e68fe0: ffffffff9150eace (irq_exit_rcu+0xe/0x20)
[71848.085295] ffffc90000e68fe8: ffffc9001e21f808 (0xffffc9001e21f808)
[71848.085298] ffffc90000e68ff0: ffffffff945e9156
(sysvec_apic_timer_interrupt+0x96/0xb0)
[71848.085302] ffffc90000e68ff8: ffffc9001e21f7f8 (0xffffc9001e21f7f8)
[71848.085304] ffffc9001e21f7f8: 0000000000000000 ...
[71848.085306] ffffc9001e21f808: ffffc9001e21f819 (0xffffc9001e21f819)
[71848.085308] ffffc9001e21f810: ffffffff94800f0b
(asm_sysvec_apic_timer_interrupt+0x1b/0x20)
[71848.085313] ffffc9001e21f818: dffffc0000000000 (0xdffffc0000000000)
[71848.085315] ffffc9001e21f820: ffffc9001e21f9b0 (0xffffc9001e21f9b0)
[71848.085317] ffffc9001e21f828: 000000000e58a269 (0xe58a269)
[71848.085319] ffffc9001e21f830: ffffc9001e21fa88 (0xffffc9001e21fa88)
[71848.085321] ffffc9001e21f838: 00000000f710950f (0xf710950f)
[71848.085323] ffffc9001e21f840: 0000000000010000 (0x10000)
[71848.085325] ffffc9001e21f848: 0000000000000000 ...
[71848.085327] ffffc9001e21f850: 0000000000000029 (0x29)
[71848.085329] ffffc9001e21f858: 0000000000000000 ...
[71848.085330] ffffc9001e21f860: 00000000f710950f (0xf710950f)
[71848.085332] ffffc9001e21f868: 00000000564d5868 (0x564d5868)
[71848.085334] ffffc9001e21f870: 0000000000000000 ...
[71848.085336] ffffc9001e21f878: 0000000000025659 (0x25659)
[71848.085337] ffffc9001e21f880: ffff88820a139029 (0xffff88820a139029)
[71848.085340] ffffc9001e21f888: 000000000e58a269 (0xe58a269)
[71848.085341] ffffc9001e21f890: ffffffffffffffff (0xffffffffffffffff)
[71848.085346] ffffc9001e21f898: ffffffffc0a920b4
(vmw_send_msg+0x4a4/0x570 [vmwgfx])
[71848.085381] ffffc9001e21f8a0: 0000000000000010 (0x10)
[71848.085383] ffffc9001e21f8a8: 0000000000000206 (0x206)
[71848.085385] ffffc9001e21f8b0: ffffc9001e21f8c8 (0xffffc9001e21f8c8)
[71848.085387] ffffc9001e21f8b8: 0000000000000018 (0x18)
[71848.085389] ffffc9001e21f8c0: ffffc9001e21f9d8 (0xffffc9001e21f9d8)
[71848.085391] ffffc9001e21f8c8: ffffc9001e21f9d8 (0xffffc9001e21f9d8)
[71848.085393] ffffc9001e21f8d0: ffffffff9167dbe5 (local_clock+0x15/0x30)
[71848.085398] ffffc9001e21f8d8: ffffc9001e21f900 (0xffffc9001e21f900)
[71848.085400] ffffc9001e21f8e0: ffffc9001e21fa90 (0xffffc9001e21fa90)
[71848.085402] ffffc9001e21f8e8: 1ffff92003c43f26 (0x1ffff92003c43f26)
[71848.085404] ffffc9001e21f8f0: 0000000000000029 (0x29)
[71848.085406] ffffc9001e21f8f8: 0000000000000cc0 (0xcc0)
[71848.085408] ffffc9001e21f900: ffff88820a139000 (0xffff88820a139000)
[71848.085410] ffffc9001e21f908: ffffffff91f1c758
(kasan_save_alloc_info+0x38/0x60)
[71848.085414] ffffc9001e21f910: 0307000000000000 (0x307000000000000)
[71848.085417] ffffc9001e21f918: fffff52003c43f52 (0xfffff52003c43f52)
[71848.085419] ffffc9001e21f920: ffffc9001e21fa8c (0xffffc9001e21fa8c)
[71848.085421] ffffc9001e21f928: 0000000000000029 (0x29)
[71848.085423] ffffc9001e21f930: 0000000041b58ab3 (0x41b58ab3)
[71848.085425] ffffc9001e21f938: ffffffffc09107c8
(g_SVGA3dSurfaceDescs+0x8428/0x15480 [vmwgfx])
[71848.085451] ffffc9001e21f940: ffffffffc0a91c10
(__pfx_vmw_send_msg+0x10/0x10 [vmwgfx])
[71848.085478] ffffc9001e21f948: ffffc90000010000 (0xffffc90000010000)
[71848.085480] ffffc9001e21f950: ffffffff00810000 (0xffffffff00810000)
[71848.085482] ffffc9001e21f958: ffffffff00020000 (0xffffffff00020000)
[71848.085484] ffffc9001e21f960: 0000000000000000 ...
[71848.085485] ffffc9001e21f968: ffffc900f710950f (0xffffc900f710950f)
[71848.085487] ffffc9001e21f970: ffffc9001e21fac8 (0xffffc9001e21fac8)
[71848.085490] ffffc9001e21f978: 00000f640e58a269 (0xf640e58a269)
[71848.085492] ffffc9001e21f980: ffff88820a139000 (0xffff88820a139000)
[71848.085494] ffffc9001e21f988: ffff888117930000 (0xffff888117930000)
[71848.085496] ffffc9001e21f990: ffffc9001e21f9d8 (0xffffc9001e21f9d8)
[71848.085498] ffffc9001e21f998: ffffffff92c97209 (strncpy_from_user+0x39/0x230)
[71848.086544] ffffc9001e21f9a0: ffffc9001e21fc50 (0xffffc9001e21fc50)
[71848.086547] ffffc9001e21f9a8: 0c85f283dc076700 (0xc85f283dc076700)
[71848.086549] ffffc9001e21f9b0: ffffc9001e21fc50 (0xffffc9001e21fc50)
[71848.086551] ffffc9001e21f9b8: ffffc9001e21fac8 (0xffffc9001e21fac8)
[71848.086553] ffffc9001e21f9c0: ffff88820a139000 (0xffff88820a139000)
[71848.086554] ffffc9001e21f9c8: ffffc9001e21fb78 (0xffffc9001e21fb78)
[71848.086556] ffffc9001e21f9d0: ffffc9001e21fa88 (0xffffc9001e21fa88)
[71848.086557] ffffc9001e21f9d8: ffffc9001e21faf0 (0xffffc9001e21faf0)
[71848.086558] ffffc9001e21f9e0: ffffffffc0a931fb
(vmw_msg_ioctl+0x17b/0x4b0 [vmwgfx])
[71848.086585] ffffc9001e21f9e8: ffffc9001e21fab0 (0xffffc9001e21fab0)
[71848.086587] ffffc9001e21f9f0: ffffffff971cd9a0 (iw_table+0x40/0x40)
[71848.087090] ffffc9001e21f9f8: ffffc9001e21fa38 (0xffffc9001e21fa38)
[71848.087093] ffffc9001e21fa00: 1ffff92003c43f41 (0x1ffff92003c43f41)
[71848.087094] ffffc9001e21fa08: 0000000041b58ab3 (0x41b58ab3)
[71848.087096] ffffc9001e21fa10: ffffffffc09108e0
(g_SVGA3dSurfaceDescs+0x8540/0x15480 [vmwgfx])
[71848.087115] ffffc9001e21fa18: ffffffffc0a93080
(__pfx_vmw_msg_ioctl+0x10/0x10 [vmwgfx])
[71848.087139] ffffc9001e21fa20: 0000000000140dca (0x140dca)
[71848.087140] ffffc9001e21fa28: 0000000000000000 ...
[71848.087142] ffffc9001e21fa30: ffffc9001e21faf0 (0xffffc9001e21faf0)
[71848.087143] ffffc9001e21fa38: ffffc9001e21fb18 (0xffffc9001e21fb18)
[71848.087145] ffffc9001e21fa40: ffffffff91ef46c0
(alloc_pages_mpol_noprof+0x260/0x610)
[71848.087176] ffffc9001e21fa48: ffffea00166062c0 (0xffffea00166062c0)
[71848.087178] ffffc9001e21fa50: ffffea00166062f4 (0xffffea00166062f4)
[71848.087179] ffffc9001e21fa58: ffffc9001e21fb88 (0xffffc9001e21fb88)
[71848.087180] ffffc9001e21fa60: 0000000000000000 ...
[71848.087181] ffffc9001e21fa68: 1ffff92003c43f54 (0x1ffff92003c43f54)
[71848.087183] ffffc9001e21fa70: ffffea00124cc1e8 (0xffffea00124cc1e8)
[71848.087184] ffffc9001e21fa78: ffff888103018008 (0xffff888103018008)
[71848.087186] ffffc9001e21fa80: 0000000000000088 (0x88)
[71848.087187] ffffc9001e21fa88: f710950f00000002 (0xf710950f00000002)
[71848.087188] ffffc9001e21fa90: 000000000e58a269 (0xe58a269)
[71848.087190] ffffc9001e21fa98: 00006079cd84e880 (0x6079cd84e880)
[71848.087191] ffffc9001e21faa0: 0000000041b58ab3 (0x41b58ab3)
[71848.087192] ffffc9001e21faa8: ffffffff9560e358 (SIGMA2+0xe0b58/0x128c40)
[71848.087195] ffffc9001e21fab0: ffffffff933876c0
(__pfx___drm_dev_dbg+0x10/0x10)
[71848.087452] ffffc9001e21fab8: 0000001100000001 (0x1100000001)
[71848.087454] ffffc9001e21fac0: 0c85f283dc076700 (0xc85f283dc076700)
[71848.087455] ffffc9001e21fac8: 0000000000000020 (0x20)
[71848.087457] ffffc9001e21fad0: 1ffff92003c43f63 (0x1ffff92003c43f63)
[71848.087458] ffffc9001e21fad8: ffff888137306200 (0xffff888137306200)
[71848.087460] ffffc9001e21fae0: ffffc9001e21fb78 (0xffffc9001e21fb78)
[71848.087461] ffffc9001e21fae8: ffff888117930000 (0xffff888117930000)
[71848.087462] ffffc9001e21faf0: ffffc9001e21fba0 (0xffffc9001e21fba0)
[71848.087464] ffffc9001e21faf8: ffffffff933578fd (drm_ioctl_kernel+0x17d/0x310)
[71848.087477] ffffc9001e21fb00: ffff888137306248 (0xffff888137306248)
[71848.087478] ffffc9001e21fb08: ffffc9001e21fc50 (0xffffc9001e21fc50)
[71848.087479] ffffc9001e21fb10: ffffffffc0a93080
(__pfx_vmw_msg_ioctl+0x10/0x10 [vmwgfx])
[71848.087500] ffffc9001e21fb18: 0000000041b58ab3 (0x41b58ab3)
[71848.087502] ffffc9001e21fb20: ffffffff9560d6d3 (SIGMA2+0xdfed3/0x128c40)
[71848.087504] ffffc9001e21fb28: ffffffff93357780
(__pfx_drm_ioctl_kernel+0x10/0x10)
[71848.087507] ffffc9001e21fb30: 0000000000000018 (0x18)
[71848.087508] ffffc9001e21fb38: ffffc90000000000 (0xffffc90000000000)
[71848.087509] ffffc9001e21fb40: 0000000000000000 ...
[71848.087510] ffffc9001e21fb48: ffffc9001e21fc50 (0xffffc9001e21fc50)
[71848.087511] ffffc9001e21fb50: 0000000000000018 (0x18)
[71848.087512] ffffc9001e21fb58: 00007ffdc141d2a0 (0x7ffdc141d2a0)
[71848.087514] ffffc9001e21fb60: ffffc9001e21fb70 (0xffffc9001e21fb70)
[71848.087515] ffffc9001e21fb68: ffffffff91f1d264
(__kasan_check_write+0x14/0x30)
[71848.087518] ffffc9001e21fb70: 0c85f283dc076700 (0xc85f283dc076700)
[71848.087519] ffffc9001e21fb78: ffff888137306200 (0xffff888137306200)
[71848.087520] ffffc9001e21fb80: ffff888117930000 (0xffff888117930000)
[71848.087521] ffffc9001e21fb88: 0000000000000018 (0x18)
[71848.087522] ffffc9001e21fb90: ffffffffc0a93080
(__pfx_vmw_msg_ioctl+0x10/0x10 [vmwgfx])
[71848.087540] ffffc9001e21fb98: ffffc9001e21fc50 (0xffffc9001e21fc50)
[71848.087542] ffffc9001e21fba0: ffffc9001e21fd38 (0xffffc9001e21fd38)
[71848.087543] ffffc9001e21fba8: ffffffff93357fe3 (drm_ioctl+0x543/0xd20)
[71848.087546] ffffc9001e21fbb0: 0c85f283dc076700 (0xc85f283dc076700)
[71848.087547] ffffc9001e21fbb8: 80000003e92d2867 (0x80000003e92d2867)
[71848.087548] ffffc9001e21fbc0: 8000000300000018 (0x8000000300000018)
[71848.087550] ffffc9001e21fbc8: ffffffffc08fce58
(vmw_ioctls+0x2b8/0x960 [vmwgfx])
[71848.087565] ffffc9001e21fbd0: ffffc9001e21fc50 (0xffffc9001e21fc50)
[71848.087597] ffffc9001e21fbd8: ffffffffc08fce58
(vmw_ioctls+0x2b8/0x960 [vmwgfx])
[71848.087612] ffffc9001e21fbe0: ffff888137306248 (0xffff888137306248)
[71848.087613] ffffc9001e21fbe8: 00007ffdc141d2a0 (0x7ffdc141d2a0)
[71848.087615] ffffc9001e21fbf0: 1ffff92003c43f82 (0x1ffff92003c43f82)
[71848.087616] ffffc9001e21fbf8: ffff88810534f4c0 (0xffff88810534f4c0)
[71848.087617] ffffc9001e21fc00: 0000005d00000018 (0x5d00000018)
[71848.087619] ffffc9001e21fc08: ffffffffc018645d (0xffffffffc018645d)
[71848.087620] ffffc9001e21fc10: 0000000041b58ab3 (0x41b58ab3)
[71848.087622] ffffc9001e21fc18: ffffffff9560deb0 (SIGMA2+0xe06b0/0x128c40)
[71848.087624] ffffc9001e21fc20: ffffffff93357aa0 (__pfx_drm_ioctl+0x10/0x10)
[71848.087626] ffffc9001e21fc28: ffffc9001e21fd98 (0xffffc9001e21fd98)
[71848.087628] ffffc9001e21fc30: ffffc9001e21fdd0 (0xffffc9001e21fdd0)
[71848.087629] ffffc9001e21fc38: ffff88818783f918 (0xffff88818783f918)
[71848.087630] ffffc9001e21fc40: ffff888100000000 (0xffff888100000000)
[71848.087632] ffffc9001e21fc48: ffff888100000000 (0xffff888100000000)
[71848.087633] ffffc9001e21fc50: 00000f640033ba80 (0xf640033ba80)
[71848.087635] ffffc9001e21fc58: 0000000000000000 ...
[71848.087636] ffffc9001e21fc60: 0000000000000001 (0x1)
[71848.087637] ffffc9001e21fc68: ffffc9001e21fdd0 (0xffffc9001e21fdd0)
[71848.087639] ffffc9001e21fc70: ffff888103018008 (0xffff888103018008)
[71848.087640] ffffc9001e21fc78: ffffc9001e21fe20 (0xffffc9001e21fe20)
[71848.087642] ffffc9001e21fc80: ffffc9001e21fe48 (0xffffc9001e21fe48)
[71848.087643] ffffc9001e21fc88: ffffffff91dc94f5
(__handle_mm_fault+0x15b5/0x2080)
[71848.087675] ffffc9001e21fc90: ffffc9001e21ff58 (0xffffc9001e21ff58)
[71848.087676] ffffc9001e21fc98: 0000000000000009 (0x9)
[71848.087677] ffffc9001e21fca0: 0000000000000009 (0x9)
[71848.087679] ffffc9001e21fca8: ffffc9001e21ff48 (0xffffc9001e21ff48)
[71848.087680] ffffc9001e21fcb0: ffff88818783f968 (0xffff88818783f968)
[71848.087681] ffffc9001e21fcb8: ffff88818783f918 (0xffff88818783f918)
[71848.087682] ffffc9001e21fcc0: 1ffff92003c43fa0 (0x1ffff92003c43fa0)
[71848.087684] ffffc9001e21fcc8: ffffed1030f07f2d (0xffffed1030f07f2d)
[71848.087685] ffffc9001e21fcd0: ffff8881eea125c0 (0xffff8881eea125c0)
[71848.087686] ffffc9001e21fcd8: 0000000008100073 (0x8100073)
[71848.087688] ffffc9001e21fce0: 00000f6400361000 (0xf6400361000)
[71848.087689] ffffc9001e21fce8: ffffc90000001255 (0xffffc90000001255)
[71848.087690] ffffc9001e21fcf0: 0000000103018067 (0x103018067)
[71848.087691] ffffc9001e21fcf8: 0000000000000008 (0x8)
[71848.087693] ffffc9001e21fd00: 0000000041b58ab3 (0x41b58ab3)
[71848.087694] ffffc9001e21fd08: 0c85f283dc076700 (0xc85f283dc076700)
[71848.087695] ffffc9001e21fd10: 1ffff92003c43fad (0x1ffff92003c43fad)
[71848.087696] ffffc9001e21fd18: ffff88810534f4c0 (0xffff88810534f4c0)
[71848.087698] ffffc9001e21fd20: 00000000c018645d (0xc018645d)
[71848.087699] ffffc9001e21fd28: ffffffff93357aa0 (__pfx_drm_ioctl+0x10/0x10)
[71848.087701] ffffc9001e21fd30: 00007ffdc141d2a0 (0x7ffdc141d2a0)
[71848.087703] ffffc9001e21fd38: ffffc9001e21fdf0 (0xffffc9001e21fdf0)
[71848.087704] ffffc9001e21fd40: ffffffffc0a24eec
(vmw_generic_ioctl+0x20c/0x460 [vmwgfx])
[71848.087723] ffffc9001e21fd48: 0000654136f88fff (0x654136f88fff)
[71848.087725] ffffc9001e21fd50: 0000000493307067 (0x493307067)
[71848.087726] ffffc9001e21fd58: dffffc0000000000 (0xdffffc0000000000)
[71848.087727] ffffc9001e21fd60: ffff88818783f8f8 (0xffff88818783f8f8)
[71848.087728] ffffc9001e21fd68: 0000000041b58ab3 (0x41b58ab3)
[71848.087730] ffffc9001e21fd70: ffffffffc090c08b
(g_SVGA3dSurfaceDescs+0x3ceb/0x15480 [vmwgfx])
[71848.087747] ffffc9001e21fd78: ffffffffc0a24ce0
(__pfx_vmw_generic_ioctl+0x10/0x10 [vmwgfx])
[71848.087765] ffffc9001e21fd80: 00000000f6400361 (0xf6400361)
[71848.087767] ffffc9001e21fd88: ffff888100000020 (0xffff888100000020)
[71848.087768] ffffc9001e21fd90: ffff88810534f4c0 (0xffff88810534f4c0)
[71848.087769] ffffc9001e21fd98: ffff8881f4b6d2c0 (0xffff8881f4b6d2c0)
[71848.087770] ffffc9001e21fda0: ffff88810534f4c0 (0xffff88810534f4c0)
[71848.087772] ffffc9001e21fda8: 0000000000000019 (0x19)
[71848.087773] ffffc9001e21fdb0: ffffc9001e21fe00 (0xffffc9001e21fe00)
[71848.087774] ffffc9001e21fdb8: ffffffff9207164c (fdget+0x2dc/0x3f0)
[71848.087813] ffffc9001e21fdc0: 0c85f283dc076700 (0xc85f283dc076700)
[71848.087814] ffffc9001e21fdc8: ffff88810534f4c1 (0xffff88810534f4c1)
[71848.087815] ffffc9001e21fdd0: ffffffffc08fb320 (driver+0x100/0x100 [vmwgfx])
[71848.087830] ffffc9001e21fdd8: 00000000c018645d (0xc018645d)
[71848.087831] ffffc9001e21fde0: 00007ffdc141d2a0 (0x7ffdc141d2a0)
[71848.087833] ffffc9001e21fde8: ffff88810534f4c0 (0xffff88810534f4c0)
[71848.087834] ffffc9001e21fdf0: ffffc9001e21fe00 (0xffffc9001e21fe00)
[71848.087835] ffffc9001e21fdf8: ffffffffc0a251a5
(vmw_unlocked_ioctl+0x15/0x30 [vmwgfx])
[71848.087852] ffffc9001e21fe00: ffffc9001e21fe38 (0xffffc9001e21fe38)
[71848.087854] ffffc9001e21fe08: ffffffff92044231 (__x64_sys_ioctl+0x141/0x1b0)
[71848.087866] ffffc9001e21fe10: ffffc9001e21ff58 (0xffffc9001e21ff58)
[71848.087867] ffffc9001e21fe18: 0000000000000010 (0x10)
[71848.087869] ffffc9001e21fe20: 0000000000000010 (0x10)
[71848.087870] ffffc9001e21fe28: 0000000000000000 ...
[71848.087871] ffffc9001e21fe38: ffffc9001e21fe48 (0xffffc9001e21fe48)
[71848.087872] ffffc9001e21fe40: ffffffff912b4d13 (x64_sys_call+0x13b3/0x26f0)
[71848.088179] ffffc9001e21fe48: ffffc9001e21ff48 (0xffffc9001e21ff48)
[71848.088181] ffffc9001e21fe50: ffffffff945e34dc (do_syscall_64+0x7c/0x170)
[71848.088184] ffffc9001e21fe58: ffff8881ba5a03c8 (0xffff8881ba5a03c8)
[71848.088185] ffffc9001e21fe60: ffff8881eea125c0 (0xffff8881eea125c0)
[71848.088187] ffffc9001e21fe68: ffffc9001e21fe78 (0xffffc9001e21fe78)
[71848.088188] ffffc9001e21fe70: ffffffff91f1d264
(__kasan_check_write+0x14/0x30)
[71848.088191] ffffc9001e21fe78: ffffc9001e21fe98 (0xffffc9001e21fe98)
[71848.088192] ffffc9001e21fe80: 0000000000000255 (0x255)
[71848.088193] ffffc9001e21fe88: 0000000000000006 (0x6)
[71848.088195] ffffc9001e21fe90: ffff8881eea125c0 (0xffff8881eea125c0)
[71848.088196] ffffc9001e21fe98: ffff8881922b5540 (0xffff8881922b5540)
[71848.088197] ffffc9001e21fea0: ffffc9001e21ff58 (0xffffc9001e21ff58)
[71848.088199] ffffc9001e21fea8: ffff8881922b5540 (0xffff8881922b5540)
[71848.088200] ffffc9001e21feb0: ffffc9001e21fec0 (0xffffc9001e21fec0)
[71848.088201] ffffc9001e21feb8: ffffffff91f1d231 (__kasan_check_read+0x11/0x20)
[71848.088203] ffffc9001e21fec0: ffffc9001e21fee0 (0xffffc9001e21fee0)
[71848.088205] ffffc9001e21fec8: ffffffff913a54e1
(fpregs_assert_state_consistent+0x21/0xb0)
[71848.088208] ffffc9001e21fed0: 0000000000000000 ...
[71848.088209] ffffc9001e21fed8: ffffc9001e21ff58 (0xffffc9001e21ff58)
[71848.088210] ffffc9001e21fee0: ffffc9001e21ff08 (0xffffc9001e21ff08)
[71848.088212] ffffc9001e21fee8: ffffffff945ea0b3
(irqentry_exit_to_user_mode+0x43/0x260)
[71848.088214] ffffc9001e21fef0: 0000000000000000 ...
[71848.088215] ffffc9001e21fef8: ffffc9001e21ff58 (0xffffc9001e21ff58)
[71848.088216] ffffc9001e21ff00: 0000000000000006 (0x6)
[71848.088218] ffffc9001e21ff08: ffffc9001e21ff18 (0xffffc9001e21ff18)
[71848.088219] ffffc9001e21ff10: ffffffff945ea323 (irqentry_exit+0x43/0x50)
[71848.088222] ffffc9001e21ff18: ffffffff948018c5 (clear_bhb_loop+0x15/0x70)
[71848.088224] ffffc9001e21ff20: ffffffff948018c5 (clear_bhb_loop+0x15/0x70)
[71848.088226] ffffc9001e21ff28: ffffffff948018c5 (clear_bhb_loop+0x15/0x70)
[71848.088228] ffffc9001e21ff30: 0000000000000000 ...
[71848.088229] ffffc9001e21ff50: ffffffff9480012b
(entry_SYSCALL_64_after_hwframe+0x76/0x7e)
[71848.088231] ffffc9001e21ff58: 0000730d0910aa50 (0x730d0910aa50)
[71848.088233] ffffc9001e21ff60: 0000000000000041 (0x41)
[71848.088234] ffffc9001e21ff68: 0000000000000019 (0x19)
[71848.088235] ffffc9001e21ff70: 00000f6400043980 (0xf6400043980)
[71848.088237] ffffc9001e21ff78: 00000000c018645d (0xc018645d)
[71848.088238] ffffc9001e21ff80: 00007ffdc141d2a0 (0x7ffdc141d2a0)
[71848.088239] ffffc9001e21ff88: 0000000000000246 (0x246)
[71848.088240] ffffc9001e21ff90: 0000000000000000 ...
[71848.088241] ffffc9001e21ff98: 000000007fffffff (0x7fffffff)
[71848.088242] ffffc9001e21ffa0: 0000730d1f5d1460 (0x730d1f5d1460)
[71848.088244] ffffc9001e21ffa8: ffffffffffffffda (0xffffffffffffffda)
[71848.088246] ffffc9001e21ffb0: 0000730d1f51a94f (0x730d1f51a94f)
[71848.088247] ffffc9001e21ffb8: 00007ffdc141d2a0 (0x7ffdc141d2a0)
[71848.088248] ffffc9001e21ffc0: 00000000c018645d (0xc018645d)
[71848.088250] ffffc9001e21ffc8: 0000000000000019 (0x19)
[71848.088251] ffffc9001e21ffd0: 0000000000000010 (0x10)
[71848.088252] ffffc9001e21ffd8: 0000730d1f51a94f (0x730d1f51a94f)
[71848.088253] ffffc9001e21ffe0: 0000000000000033 (0x33)
[71848.088254] ffffc9001e21ffe8: 0000000000000246 (0x246)
[71848.088255] ffffc9001e21fff0: 00007ffdc141d1f0 (0x7ffdc141d1f0)
[71848.088257] ffffc9001e21fff8: 000000000000002b (0x2b)


crash 2:
[   60.422691] WARNING: kernel stack regs at ffffc90006a476e8 in
Xwayland:3264 has bad 'bp' value 000000009d3c9256
[   60.422698] unwind stack type:0 next_sp:0000000000000000 mask:0x6 graph_idx:0
[   60.422699] ffffc90000c60930: ffffc90000c609d8 (0xffffc90000c609d8)
[   60.422703] ffffc90000c60938: ffffffff8450fec8 (arch_stack_walk+0x88/0x100)
[   60.422709] ffffc90000c60940: 0000000000000000 ...
[   60.422710] ffffc90000c60948: ffffc90006a40000 (0xffffc90006a40000)
[   60.422711] ffffc90000c60950: ffffc90006a48000 (0xffffc90006a48000)
[   60.422711] ffffc90000c60958: 0000000000000000 ...
[   60.422712] ffffc90000c60960: 0000000000000006 (0x6)
[   60.422713] ffffc90000c60968: ffff8881df0d8040 (0xffff8881df0d8040)
[   60.422714] ffffc90000c60970: 0000000000000000 ...
[   60.422714] ffffc90000c60980: 0000000000000101 (0x101)
[   60.422715] ffffc90000c60988: 0000000000000000 ...
[   60.422716] ffffc90000c60990: ffffc90000c60930 (0xffffc90000c60930)
[   60.422716] ffffc90000c60998: ffffffffc07ed034
(vmw_send_msg+0x4a4/0x570 [vmwgfx])
[   60.422741] ffffc90000c609a0: 0000000000000000 ...
[   60.422741] ffffc90000c609a8: ffffc90006a476e8 (0xffffc90006a476e8)
[   60.422742] ffffc90000c609b0: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.422743] ffffc90000c609b8: fffff5200018c13d (0xfffff5200018c13d)
[   60.422744] ffffc90000c609c0: 0000000000000000 ...
[   60.422744] ffffc90000c609c8: 0000000000000001 (0x1)
[   60.422745] ffffc90000c609d0: 0000000000000000 ...
[   60.422746] ffffc90000c609d8: ffffc90000c60a70 (0xffffc90000c60a70)
[   60.422747] ffffc90000c609e0: ffffffff848ea6f3 (stack_trace_save+0x93/0xd0)
[   60.422750] ffffc90000c609e8: 0000000041b58ab3 (0x41b58ab3)
[   60.422751] ffffc90000c609f0: ffffffff8852e534 (SIGMA2+0x12074/0x1258c0)
[   60.422757] ffffc90000c609f8: ffffffff848ea660
(__pfx_stack_trace_save+0x10/0x10)
[   60.422758] ffffc90000c60a00: ffffc900059b7980 (0xffffc900059b7980)
[   60.422759] ffffc90000c60a08: ffffc90000c60a80 (0xffffc90000c60a80)
[   60.422760] ffffc90000c60a10: 0000000000000040 (0x40)
[   60.422761] ffffc90000c60a18: 000000000000000f (0xf)
[   60.422762] ffffc90000c60a20: ffffffff847301bd
(default_wake_function+0x3d/0x70)
[   60.422764] ffffc90000c60a28: 0000000000000000 ...
[   60.422765] ffffc90000c60a30: ffffc90000c60af8 (0xffffc90000c60af8)
[   60.422765] ffffc90000c60a38: ffffc90000c60b18 (0xffffc90000c60b18)
[   60.422766] ffffc90000c60a40: ffffffff8518098e (pollwake+0x15e/0x250)
[   60.422769] ffffc90000c60a48: 0000000000000046 (0x46)
[   60.422769] ffffc90000c60a50: 00000000000472c0 (0x472c0)
[   60.422770] ffffc90000c60a58: 0000000041b58ab3 (0x41b58ab3)
[   60.422771] ffffc90000c60a60: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.422772] ffffc90000c60a68: ffff88812a6af3a8 (0xffff88812a6af3a8)
[   60.422773] ffffc90000c60a70: ffffc90000c60c90 (0xffffc90000c60c90)
[   60.422773] ffffc90000c60a78: ffffffff85053648 (kasan_save_stack+0x28/0x60)
[   60.422776] ffffc90000c60a80: ffffffff85053648 (kasan_save_stack+0x28/0x60)
[   60.422778] ffffc90000c60a88: ffffffff85053718 (kasan_save_track+0x18/0x70)
[   60.422779] ffffc90000c60a90: ffffffff850573ab
(kasan_save_free_info+0x3b/0x60)
[   60.422781] ffffc90000c60a98: ffffffff85053b04 (__kasan_slab_free+0x54/0x80)
[   60.422783] ffffc90000c60aa0: ffffffff84fbd8c5 (kfree+0x115/0x480)
[   60.422785] ffffc90000c60aa8: ffffffff84fbf9a1
(slab_free_after_rcu_debug+0x61/0x350)
[   60.422788] ffffc90000c60ab0: ffffffff8488e735 (rcu_do_batch+0x405/0xfd0)
[   60.422789] ffffc90000c60ab8: ffffffff8489814f (rcu_core+0x5af/0xcc0)
[   60.422791] ffffc90000c60ac0: ffffffff8489901e (rcu_core_si+0xe/0x20)
[   60.422792] ffffc90000c60ac8: ffffffff846640b7 (handle_softirqs+0x1a7/0x670)
[   60.422795] ffffc90000c60ad0: ffffffff84664721 (__irq_exit_rcu+0x191/0x1f0)
[   60.422797] ffffc90000c60ad8: ffffffff84664d8e (irq_exit_rcu+0xe/0x20)
[   60.422799] ffffc90000c60ae0: ffffffff87786306
(sysvec_apic_timer_interrupt+0x96/0xb0)
[   60.422802] ffffc90000c60ae8: ffffffff87800f0b
(asm_sysvec_apic_timer_interrupt+0x1b/0x20)
[   60.422806] ffffc90000c60af0: ffffffffc07ed034
(vmw_send_msg+0x4a4/0x570 [vmwgfx])
[   60.422819] ffffc90000c60af8: 0000000000000000 ...
[   60.422820] ffffc90000c60b00: ffff88817f74a4a0 (0xffff88817f74a4a0)
[   60.422821] ffffc90000c60b08: 0000000000000000 ...
[   60.422821] ffffc90000c60b18: ffffc90000c60b68 (0xffffc90000c60b68)
[   60.422822] ffffc90000c60b20: ffffffff847babec (__wake_up_common+0xfc/0x180)
[   60.422824] ffffc90000c60b28: 0000000000000020 (0x20)
[   60.422825] ffffc90000c60b30: 0000000300000001 (0x300000001)
[   60.422826] ffffc90000c60b38: ffff88817f74a4b8 (0xffff88817f74a4b8)
[   60.422827] ffffc90000c60b40: 0000000000000001 (0x1)
[   60.422827] ffffc90000c60b48: ffff88817f74a4b0 (0xffff88817f74a4b0)
[   60.422828] ffffc90000c60b50: 0000000000000003 (0x3)
[   60.422829] ffffc90000c60b58: 0000000000000046 (0x46)
[   60.422830] ffffc90000c60b60: 0000000000000000 ...
[   60.422830] ffffc90000c60b68: ffffc90000c60ba0 (0xffffc90000c60ba0)
[   60.422831] ffffc90000c60b70: ffffffff847cb5d5 (__wake_up+0x45/0x70)
[   60.422833] ffffc90000c60b78: ffff88817f74a440 (0xffff88817f74a440)
[   60.422833] ffffc90000c60b80: ffffc90000c60c20 (0xffffc90000c60c20)
[   60.422834] ffffc90000c60b88: ffffc90000c60c80 (0xffffc90000c60c80)
[   60.422835] ffffc90000c60b90: 00000000017d4bf6 (0x17d4bf6)
[   60.422836] ffffc90000c60b98: ffff88817f74a488 (0xffff88817f74a488)
[   60.422837] ffffc90000c60ba0: ffffc90000c60ca8 (0xffffc90000c60ca8)
[   60.422838] ffffc90000c60ba8: ffffffffc08fdb41
(snd_timer_user_tinterrupt+0x391/0x6d0 [snd_timer])
[   60.422842] ffffc90000c60bb0: ffffffff877ada36
(_raw_spin_lock_irqsave+0x96/0x110)
[   60.422844] ffffc90000c60bb8: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.422845] ffffc90000c60bc0: ffff88817f74a490 (0xffff88817f74a490)
[   60.422845] ffffc90000c60bc8: 1ffff9200018c186 (0x1ffff9200018c186)
[   60.422846] ffffc90000c60bd0: ffff88862e9c72c0 (0xffff88862e9c72c0)
[   60.422847] ffffc90000c60bd8: ffffc90000c60be8 (0xffffc90000c60be8)
[   60.422848] ffffc90000c60be0: ffffffff87784119 (sched_clock_noinstr+0x9/0x10)
[   60.422850] ffffc90000c60be8: ffffc90000c60bf8 (0xffffc90000c60bf8)
[   60.422851] ffffc90000c60bf0: ffffffff844f5490 (sched_clock+0x10/0x30)
[   60.422853] ffffc90000c60bf8: ffff888199d38800 (0xffff888199d38800)
[   60.422854] ffffc90000c60c00: ffff88862e9c72c0 (0xffff88862e9c72c0)
[   60.422855] ffffc90000c60c08: 00000000000011fc (0x11fc)
[   60.422855] ffffc90000c60c10: ffffc90000c60c60 (0xffffc90000c60c60)
[   60.422856] ffffc90000c60c18: ffffffff847485e9 (update_curr+0x79/0x5a0)
[   60.422859] ffffc90000c60c20: 00000000000030c5 (0x30c5)
[   60.422859] ffffc90000c60c28: ffffffff847ac554
(dl_scaled_delta_exec+0xe4/0x300)
[   60.422862] ffffc90000c60c30: 0000000041b58ab3 (0x41b58ab3)
[   60.422863] ffffc90000c60c38: 0000000000038f03 (0x38f03)
[   60.422863] ffffc90000c60c40: ffff88862e9c73c0 (0xffff88862e9c73c0)
[   60.422864] ffffc90000c60c48: 1ffff9200018c190 (0x1ffff9200018c190)
[   60.422865] ffffc90000c60c50: ffffffff89294e98 (input_pool+0x78/0xa0)
[   60.422869] ffffc90000c60c58: 0000000000000246 (0x246)
[   60.422870] ffffc90000c60c60: ffffc90000c60c70 (0xffffc90000c60c70)
[   60.422871] ffffc90000c60c68: ffffffff85057e44
(__kasan_check_write+0x14/0x30)
[   60.422873] ffffc90000c60c70: ffffc90000c60cf8 (0xffffc90000c60cf8)
[   60.422874] ffffc90000c60c78: ffffffff89294e20 (pm_notifier+0x40/0x40)
[   60.422875] ffffc90000c60c80: ffff88812a6af3a0 (0xffff88812a6af3a0)
[   60.422876] ffffc90000c60c88: ffff888100059540 (0xffff888100059540)
[   60.422877] ffffc90000c60c90: ffffc90000c60cb8 (0xffffc90000c60cb8)
[   60.422877] ffffc90000c60c98: ffffffff85053718 (kasan_save_track+0x18/0x70)
[   60.422879] ffffc90000c60ca0: ffffed10254d5e74 (0xffffed10254d5e74)
[   60.422880] ffffc90000c60ca8: ffff88812a6af3a0 (0xffff88812a6af3a0)
[   60.422881] ffffc90000c60cb0: ffff888100059540 (0xffff888100059540)
[   60.422882] ffffc90000c60cb8: ffffc90000c60cd0 (0xffffc90000c60cd0)
[   60.422882] ffffc90000c60cc0: ffffffff850573ab
(kasan_save_free_info+0x3b/0x60)
[   60.422884] ffffc90000c60cc8: 0000000000000000 ...
[   60.422884] ffffc90000c60cd0: ffffc90000c60cf0 (0xffffc90000c60cf0)
[   60.422885] ffffc90000c60cd8: ffffffff85053b04 (__kasan_slab_free+0x54/0x80)
[   60.422887] ffffc90000c60ce0: ffff888100059540 (0xffff888100059540)
[   60.422888] ffffc90000c60ce8: ffffea0004a9ab80 (0xffffea0004a9ab80)
[   60.422888] ffffc90000c60cf0: ffffc90000c60d60 (0xffffc90000c60d60)
[   60.422889] ffffc90000c60cf8: ffffffff84fbd8c5 (kfree+0x115/0x480)
[   60.422891] ffffc90000c60d00: ffffffff863248c4
(mix_interrupt_randomness+0x194/0x200)
[   60.422894] ffffc90000c60d08: 0000000041b58ab3 (0x41b58ab3)
[   60.422894] ffffc90000c60d10: ffffffff84fbf9a1
(slab_free_after_rcu_debug+0x61/0x350)
[   60.422896] ffffc90000c60d18: 1ffff9000018c1aa (0x1ffff9000018c1aa)
[   60.422897] ffffc90000c60d20: ffff88812a6af3a0 (0xffff88812a6af3a0)
[   60.422898] ffffc90000c60d28: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.422898] ffffc90000c60d30: ffff888100e51a00 (0xffff888100e51a00)
[   60.422899] ffffc90000c60d38: dffffc0000000000 (0xdffffc0000000000)
[   60.422900] ffffc90000c60d40: ffffea0004ae4d00 (0xffffea0004ae4d00)
[   60.422901] ffffc90000c60d48: ffff88812b934340 (0xffff88812b934340)
[   60.422902] ffffc90000c60d50: ffff88812a6af3a0 (0xffff88812a6af3a0)
[   60.422902] ffffc90000c60d58: 0000000000000000 ...
[   60.422903] ffffc90000c60d60: ffffc90000c60db0 (0xffffc90000c60db0)
[   60.422904] ffffc90000c60d68: ffffffff84fbf9a1
(slab_free_after_rcu_debug+0x61/0x350)
[   60.422905] ffffc90000c60d70: ffff888600000000 (0xffff888600000000)
[   60.422906] ffffc90000c60d78: ffffffff86324730
(__pfx_mix_interrupt_randomness+0x10/0x10)
[   60.422907] ffffc90000c60d80: ffff88862e9b2800 (0xffff88862e9b2800)
[   60.422908] ffffc90000c60d88: dffffc0000000000 (0xdffffc0000000000)
[   60.422909] ffffc90000c60d90: 0000000000000001 (0x1)
[   60.422910] ffffc90000c60d98: ffff88862e9c8200 (0xffff88862e9c8200)
[   60.422911] ffffc90000c60da0: ffffc90000c60e48 (0xffffc90000c60e48)
[   60.422911] ffffc90000c60da8: 0000000000000000 ...
[   60.422912] ffffc90000c60db0: ffffc90000c60ed0 (0xffffc90000c60ed0)
[   60.422913] ffffc90000c60db8: ffffffff8488e735 (rcu_do_batch+0x405/0xfd0)
[   60.422914] ffffc90000c60dc0: ffff88862e9c8308 (0xffff88862e9c8308)
[   60.422914] ffffc90000c60dc8: ffff88862e9c82f0 (0xffff88862e9c82f0)
[   60.422915] ffffc90000c60dd0: 1ffff9200018c1c5 (0x1ffff9200018c1c5)
[   60.422916] ffffc90000c60dd8: ffff88862e9c82d8 (0xffff88862e9c82d8)
[   60.422917] ffffc90000c60de0: 00000000000030c8 (0x30c8)
[   60.422917] ffffc90000c60de8: ffff88862e9c8200 (0xffff88862e9c8200)
[   60.422918] ffffc90000c60df0: ffff88862e9c82c0 (0xffff88862e9c82c0)
[   60.422919] ffffc90000c60df8: ffff88862e9c82e8 (0xffff88862e9c82e8)
[   60.422920] ffffc90000c60e00: ffffed103be1b008 (0xffffed103be1b008)
[   60.422921] ffffc90000c60e08: ffff8881df0d8040 (0xffff8881df0d8040)
[   60.422921] ffffc90000c60e10: ffff88862e9c8278 (0xffff88862e9c8278)
[   60.422922] ffffc90000c60e18: 000000000000000a (0xa)
[   60.422923] ffffc90000c60e20: 0000000000000000 ...
[   60.422923] ffffc90000c60e28: 0000000041b58ab3 (0x41b58ab3)
[   60.422924] ffffc90000c60e30: ffffffff8852c421 (SIGMA2+0xff61/0x1258c0)
[   60.422926] ffffc90000c60e38: ffffffff8488e330 (__pfx_rcu_do_batch+0x10/0x10)
[   60.422927] ffffc90000c60e40: ffffffff88b03548 (rcu_state+0x2c8/0x59ba0)
[   60.422930] ffffc90000c60e48: ffff88812a6af9a0 (0xffff88812a6af9a0)
[   60.422931] ffffc90000c60e50: ffff8881ece32b08 (0xffff8881ece32b08)
[   60.422932] ffffc90000c60e58: 0000000000000066 (0x66)
[   60.422933] ffffc90000c60e60: 0000000000000000 ...
[   60.422933] ffffc90000c60e68: ffff88862e9b6028 (0xffff88862e9b6028)
[   60.422934] ffffc90000c60e70: 1ffff9200018c1d5 (0x1ffff9200018c1d5)
[   60.422935] ffffc90000c60e78: 00000000000030c1 (0x30c1)
[   60.422936] ffffc90000c60e80: ffff88862e9c8200 (0xffff88862e9c8200)
[   60.422937] ffffc90000c60e88: ffffffff88b03540 (rcu_state+0x2c0/0x59ba0)
[   60.422938] ffffc90000c60e90: 0000000000000246 (0x246)
[   60.422939] ffffc90000c60e98: ffff88862e9c8200 (0xffff88862e9c8200)
[   60.422939] ffffc90000c60ea0: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.422940] ffffc90000c60ea8: ffffffff89789f20 (__futex_data+0x10/0x10)
[   60.422944] ffffc90000c60eb0: 0000000000046448 (0x46448)
[   60.422944] ffffc90000c60eb8: ffff88862e9c8278 (0xffff88862e9c8278)
[   60.422945] ffffc90000c60ec0: ffff88862e9c8218 (0xffff88862e9c8218)
[   60.422946] ffffc90000c60ec8: ffff88862e9c8200 (0xffff88862e9c8200)
[   60.422947] ffffc90000c60ed0: ffffc90000c60f30 (0xffffc90000c60f30)
[   60.422948] ffffc90000c60ed8: ffffffff8489814f (rcu_core+0x5af/0xcc0)
[   60.422949] ffffc90000c60ee0: ffff88862e9b6078 (0xffff88862e9b6078)
[   60.422949] ffffc90000c60ee8: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.422950] ffffc90000c60ef0: 00000000fffc53e8 (0xfffc53e8)
[   60.422951] ffffc90000c60ef8: ffff88862e9b4d00 (0xffff88862e9b4d00)
[   60.422952] ffffc90000c60f00: ffffffff88b03540 (rcu_state+0x2c0/0x59ba0)
[   60.422953] ffffc90000c60f08: 0000000000000008 (0x8)
[   60.422954] ffffc90000c60f10: 0000000000000100 (0x100)
[   60.422954] ffffc90000c60f18: 0000000000000009 (0x9)
[   60.422955] ffffc90000c60f20: 0000000000000080 (0x80)
[   60.422956] ffffc90000c60f28: ffffffff8880a108 (softirq_vec+0x48/0x80)
[   60.422958] ffffc90000c60f30: ffffc90000c60f40 (0xffffc90000c60f40)
[   60.422959] ffffc90000c60f38: ffffffff8489901e (rcu_core_si+0xe/0x20)
[   60.422960] ffffc90000c60f40: ffffc90000c60fb8 (0xffffc90000c60fb8)
[   60.422961] ffffc90000c60f48: ffffffff846640b7 (handle_softirqs+0x1a7/0x670)
[   60.422963] ffffc90000c60f50: 004000002e9b5f8c (0x4000002e9b5f8c)
[   60.422964] ffffc90000c60f58: ffffed103be1b008 (0xffffed103be1b008)
[   60.422965] ffffc90000c60f60: ffff8881df0d8040 (0xffff8881df0d8040)
[   60.422965] ffffc90000c60f68: 00000000fffc53ea (0xfffc53ea)
[   60.422966] ffffc90000c60f70: 00ff88860000000a (0xff88860000000a)
[   60.422967] ffffc90000c60f78: 0000000df0a63800 (0xdf0a63800)
[   60.422968] ffffc90000c60f80: fffffbfff12f13e4 (0xfffffbfff12f13e4)
[   60.422968] ffffc90000c60f88: ffffed1000000009 (0xffffed1000000009)
[   60.422969] ffffc90000c60f90: 0000000000000000 ...
[   60.422970] ffffc90000c60f98: ffffc90006a476e8 (0xffffc90006a476e8)
[   60.422971] ffffc90000c60fa0: 0000000000000000 ...
[   60.422971] ffffc90000c60fb8: ffffc90000c60fd8 (0xffffc90000c60fd8)
[   60.422972] ffffc90000c60fc0: ffffffff84664721 (__irq_exit_rcu+0x191/0x1f0)
[   60.422974] ffffc90000c60fc8: 0000000000000000 ...
[   60.422975] ffffc90000c60fd0: ffffc90006a476e8 (0xffffc90006a476e8)
[   60.422975] ffffc90000c60fd8: ffffc90000c60fe8 (0xffffc90000c60fe8)
[   60.422976] ffffc90000c60fe0: ffffffff84664d8e (irq_exit_rcu+0xe/0x20)
[   60.422978] ffffc90000c60fe8: ffffc90006a476d8 (0xffffc90006a476d8)
[   60.422979] ffffc90000c60ff0: ffffffff87786306
(sysvec_apic_timer_interrupt+0x96/0xb0)
[   60.422980] ffffc90000c60ff8: ffffc90006a476c8 (0xffffc90006a476c8)
[   60.422981] ffffc90006a476c8: 0000000000000000 ...
[   60.422981] ffffc90006a476d8: ffffc90006a476e9 (0xffffc90006a476e9)
[   60.422982] ffffc90006a476e0: ffffffff87800f0b
(asm_sysvec_apic_timer_interrupt+0x1b/0x20)
[   60.422984] ffffc90006a476e8: dffffc0000000000 (0xdffffc0000000000)
[   60.422985] ffffc90006a476f0: ffffc90006a47880 (0xffffc90006a47880)
[   60.422985] ffffc90006a476f8: 000000007344ca1a (0x7344ca1a)
[   60.422986] ffffc90006a47700: ffffc90006a47958 (0xffffc90006a47958)
[   60.422987] ffffc90006a47708: 000000009d3c9256 (0x9d3c9256)
[   60.422988] ffffc90006a47710: 0000000000010000 (0x10000)
[   60.422988] ffffc90006a47718: 0000000000000000 ...
[   60.422989] ffffc90006a47720: 0000000000000029 (0x29)
[   60.422990] ffffc90006a47728: 0000000000000000 ...
[   60.422990] ffffc90006a47730: 000000009d3c9256 (0x9d3c9256)
[   60.422991] ffffc90006a47738: 00000000564d5868 (0x564d5868)
[   60.422992] ffffc90006a47740: 0000000000000000 ...
[   60.422992] ffffc90006a47748: 0000000000015659 (0x15659)
[   60.422993] ffffc90006a47750: ffff888107cec029 (0xffff888107cec029)
[   60.422994] ffffc90006a47758: 000000007344ca1a (0x7344ca1a)
[   60.422995] ffffc90006a47760: ffffffffffffffff (0xffffffffffffffff)
[   60.422997] ffffc90006a47768: ffffffffc07ed034
(vmw_send_msg+0x4a4/0x570 [vmwgfx])
[   60.423010] ffffc90006a47770: 0000000000000010 (0x10)
[   60.423011] ffffc90006a47778: 0000000000000206 (0x206)
[   60.423011] ffffc90006a47780: ffffc90006a47798 (0xffffc90006a47798)
[   60.423012] ffffc90006a47788: 0000000000000018 (0x18)
[   60.423013] ffffc90006a47790: ffffc90006a478a8 (0xffffc90006a478a8)
[   60.423014] ffffc90006a47798: ffffc90006a478a8 (0xffffc90006a478a8)
[   60.423015] ffffc90006a477a0: 0000000004220291 (0x4220291)
[   60.423016] ffffc90006a477a8: ffffc90006a477b8 (0xffffc90006a477b8)
[   60.423016] ffffc90006a477b0: ffffc90006a47960 (0xffffc90006a47960)
[   60.423017] ffffc90006a477b8: 1ffff92000d48f00 (0x1ffff92000d48f00)
[   60.423018] ffffc90006a477c0: 0000000000000029 (0x29)
[   60.423019] ffffc90006a477c8: ffff888107cec000 (0xffff888107cec000)
[   60.423019] ffffc90006a477d0: ffff888107cec000 (0xffff888107cec000)
[   60.423020] ffffc90006a477d8: 0000000000000cc0 (0xcc0)
[   60.423021] ffffc90006a477e0: 0307c90000000000 (0x307c90000000000)
[   60.423022] ffffc90006a477e8: fffff52000d48f2c (0xfffff52000d48f2c)
[   60.423023] ffffc90006a477f0: ffffc90006a4795c (0xffffc90006a4795c)
[   60.423023] ffffc90006a477f8: 0000000000000029 (0x29)
[   60.423024] ffffc90006a47800: 0000000041b58ab3 (0x41b58ab3)
[   60.423025] ffffc90006a47808: ffffffffc086a890
(g_SVGA3dSurfaceDescs+0x8430/0xfffffffffffa4ba0 [vmwgfx])
[   60.423036] ffffc90006a47810: ffffffffc07ecb90
(__pfx_vmw_send_msg+0x10/0x10 [vmwgfx])
[   60.423048] ffffc90006a47818: ffff888100010000 (0xffff888100010000)
[   60.423049] ffffc90006a47820: 0000000000810000 (0x810000)
[   60.423050] ffffc90006a47828: ffff888100010000 (0xffff888100010000)
[   60.423051] ffffc90006a47830: ffffc90006a478a0 (0xffffc90006a478a0)
[   60.423051] ffffc90006a47838: ffffffff9d3c9256 (0xffffffff9d3c9256)
[   60.423052] ffffc90006a47840: ffff88872d444480 (0xffff88872d444480)
[   60.423053] ffffc90006a47848: ffffc9007344ca1a (0xffffc9007344ca1a)
[   60.423054] ffffc90006a47850: ffffc90000001000 (0xffffc90000001000)
[   60.423055] ffffc90006a47858: ffff888107cec000 (0xffff888107cec000)
[   60.423055] ffffc90006a47860: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.423056] ffffc90006a47868: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.423057] ffffc90006a47870: ffffc90006a47b20 (0xffffc90006a47b20)
[   60.423058] ffffc90006a47878: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.423058] ffffc90006a47880: ffffc90006a47b20 (0xffffc90006a47b20)
[   60.423059] ffffc90006a47888: ffffc90006a47998 (0xffffc90006a47998)
[   60.423060] ffffc90006a47890: ffff888107cec000 (0xffff888107cec000)
[   60.423061] ffffc90006a47898: ffffc90006a47a48 (0xffffc90006a47a48)
[   60.423062] ffffc90006a478a0: ffffc90006a47958 (0xffffc90006a47958)
[   60.423062] ffffc90006a478a8: ffffc90006a479c0 (0xffffc90006a479c0)
[   60.423063] ffffc90006a478b0: ffffffffc07ee17b
(vmw_msg_ioctl+0x17b/0x4b0 [vmwgfx])
[   60.423076] ffffc90006a478b8: 1ffff92000d48f21 (0x1ffff92000d48f21)
[   60.423076] ffffc90006a478c0: ffffc90006a47960 (0xffffc90006a47960)
[   60.423077] ffffc90006a478c8: 1ffff92000d48f22 (0x1ffff92000d48f22)
[   60.423078] ffffc90006a478d0: 1ffff92000d48f1b (0x1ffff92000d48f1b)
[   60.423079] ffffc90006a478d8: 0000000041b58ab3 (0x41b58ab3)
[   60.423079] ffffc90006a478e0: ffffffffc086a9a8
(g_SVGA3dSurfaceDescs+0x8548/0xfffffffffffa4ba0 [vmwgfx])
[   60.423091] ffffc90006a478e8: ffffffffc07ee000
(__pfx_vmw_msg_ioctl+0x10/0x10 [vmwgfx])
[   60.423102] ffffc90006a478f0: ffffffff885544d0 (SIGMA2+0x38010/0x1258c0)
[   60.423104] ffffc90006a478f8: ffffffff84fcc770
(__pfx_madvise_vma_behavior+0x10/0x10)
[   60.423106] ffffc90006a47900: 00140dca00000000 (0x140dca00000000)
[   60.423107] ffffc90006a47908: 0000000000000001 (0x1)
[   60.423108] ffffc90006a47910: 0000000041b58ab3 (0x41b58ab3)
[   60.423108] ffffc90006a47918: ffffffff88552ac0 (SIGMA2+0x36600/0x1258c0)
[   60.423110] ffffc90006a47920: ffffffff84f9ea90
(__pfx___alloc_pages_noprof+0x10/0x10)
[   60.423113] ffffc90006a47928: dffffc0000000000 (0xdffffc0000000000)
[   60.423113] ffffc90006a47930: ffffc90006a47940 (0xffffc90006a47940)
[   60.423114] ffffc90006a47938: 1ffff92000d48f2e (0x1ffff92000d48f2e)
[   60.423115] ffffc90006a47940: ffffea000448a868 (0xffffea000448a868)
[   60.423116] ffffc90006a47948: ffff888126939cb8 (0xffff888126939cb8)
[   60.423117] ffffc90006a47950: ffffc90006a47960 (0xffffc90006a47960)
[   60.423117] ffffc90006a47958: 9d3c925685050001 (0x9d3c925685050001)
[   60.423118] ffffc90006a47960: ffffc9007344ca1a (0xffffc9007344ca1a)
[   60.423119] ffffc90006a47968: ffffffff877ae732 (_raw_spin_lock+0x82/0xf0)
[   60.423120] ffffc90006a47970: 0000000041b58ab3 (0x41b58ab3)
[   60.423121] ffffc90006a47978: ffffffff885fa450 (SIGMA2+0xddf90/0x1258c0)
[   60.423123] ffffc90006a47980: ffffffff864ae700
(__pfx___drm_dev_dbg+0x10/0x10)
[   60.423126] ffffc90006a47988: ffffffff876c3e93 (xas_load+0x23/0x350)
[   60.423129] ffffc90006a47990: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.423130] ffffc90006a47998: 0000000000000020 (0x20)
[   60.423131] ffffc90006a479a0: 1ffff92000d48f3d (0x1ffff92000d48f3d)
[   60.423132] ffffc90006a479a8: ffff88810bc42c00 (0xffff88810bc42c00)
[   60.423132] ffffc90006a479b0: ffffc90006a47a48 (0xffffc90006a47a48)
[   60.423133] ffffc90006a479b8: ffff8881fda20000 (0xffff8881fda20000)
[   60.423134] ffffc90006a479c0: ffffc90006a47a70 (0xffffc90006a47a70)
[   60.423135] ffffc90006a479c8: ffffffff8647eafd (drm_ioctl_kernel+0x17d/0x310)
[   60.423136] ffffc90006a479d0: ffff88810bc42c48 (0xffff88810bc42c48)
[   60.423137] ffffc90006a479d8: ffffc90006a47b20 (0xffffc90006a47b20)
[   60.423138] ffffc90006a479e0: ffffffffc07ee000
(__pfx_vmw_msg_ioctl+0x10/0x10 [vmwgfx])
[   60.423150] ffffc90006a479e8: 0000000041b58ab3 (0x41b58ab3)
[   60.423150] ffffc90006a479f0: ffffffff885f97cb (SIGMA2+0xdd30b/0x1258c0)
[   60.423152] ffffc90006a479f8: ffffffff8647e980
(__pfx_drm_ioctl_kernel+0x10/0x10)
[   60.423153] ffffc90006a47a00: 0000000000000018 (0x18)
[   60.423154] ffffc90006a47a08: ffffc90000000000 (0xffffc90000000000)
[   60.423155] ffffc90006a47a10: 0000000000000000 ...
[   60.423155] ffffc90006a47a18: ffffc90006a47b20 (0xffffc90006a47b20)
[   60.423156] ffffc90006a47a20: 0000000000000018 (0x18)
[   60.423157] ffffc90006a47a28: 00007fff5004cf70 (0x7fff5004cf70)
[   60.423158] ffffc90006a47a30: ffffc90006a47a40 (0xffffc90006a47a40)
[   60.423159] ffffc90006a47a38: ffffffff85057e44
(__kasan_check_write+0x14/0x30)
[   60.423160] ffffc90006a47a40: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.423161] ffffc90006a47a48: ffff88810bc42c00 (0xffff88810bc42c00)
[   60.423162] ffffc90006a47a50: ffff8881fda20000 (0xffff8881fda20000)
[   60.423162] ffffc90006a47a58: 0000000000000018 (0x18)
[   60.423163] ffffc90006a47a60: ffffffffc07ee000
(__pfx_vmw_msg_ioctl+0x10/0x10 [vmwgfx])
[   60.423175] ffffc90006a47a68: ffffc90006a47b20 (0xffffc90006a47b20)
[   60.423175] ffffc90006a47a70: ffffc90006a47c08 (0xffffc90006a47c08)
[   60.423176] ffffc90006a47a78: ffffffff8647f1e3 (drm_ioctl+0x543/0xd20)
[   60.423177] ffffc90006a47a80: 0000000000000000 ...
[   60.423178] ffffc90006a47a88: ffff888105c16440 (0xffff888105c16440)
[   60.423179] ffffc90006a47a90: 0000000000000018 (0x18)
[   60.423179] ffffc90006a47a98: ffffffffc0856e98
(vmw_ioctls+0x2b8/0xfffffffffffb0420 [vmwgfx])
[   60.423192] ffffc90006a47aa0: ffffc90006a47b20 (0xffffc90006a47b20)
[   60.423192] ffffc90006a47aa8: ffffffffc0856e98
(vmw_ioctls+0x2b8/0xfffffffffffb0420 [vmwgfx])
[   60.423204] ffffc90006a47ab0: ffff88810bc42c48 (0xffff88810bc42c48)
[   60.423205] ffffc90006a47ab8: 00007fff5004cf70 (0x7fff5004cf70)
[   60.423205] ffffc90006a47ac0: 1ffff92000d48f5c (0x1ffff92000d48f5c)
[   60.423206] ffffc90006a47ac8: ffff88812b9377c0 (0xffff88812b9377c0)
[   60.423207] ffffc90006a47ad0: 0000005d00000018 (0x5d00000018)
[   60.423208] ffffc90006a47ad8: ffffffffc018645d (0xffffffffc018645d)
[   60.423209] ffffc90006a47ae0: 0000000041b58ab3 (0x41b58ab3)
[   60.423210] ffffc90006a47ae8: ffffffff885f9fa8 (SIGMA2+0xddae8/0x1258c0)
[   60.423212] ffffc90006a47af0: ffffffff8647eca0 (__pfx_drm_ioctl+0x10/0x10)
[   60.423213] ffffc90006a47af8: 0000000000000a5f (0xa5f)
[   60.423214] ffffc90006a47b00: 000000000000000f (0xf)
[   60.423214] ffffc90006a47b08: 0000000000000a5f (0xa5f)
[   60.423215] ffffc90006a47b10: ffffc90000000000 (0xffffc90000000000)
[   60.423216] ffffc90006a47b18: 1ffff92000d48f6e (0x1ffff92000d48f6e)
[   60.423217] ffffc90006a47b20: 00005ff5b00713d0 (0x5ff5b00713d0)
[   60.423217] ffffc90006a47b28: 0000000000000000 ...
[   60.423218] ffffc90006a47b30: 0000000000000001 (0x1)
[   60.423219] ffffc90006a47b38: 0000000000000a50 (0xa50)
[   60.423219] ffffc90006a47b40: 00000000000418c0 (0x418c0)
[   60.423220] ffffc90006a47b48: ffffc90006a47b58 (0xffffc90006a47b58)
[   60.423221] ffffc90006a47b50: ffff8881212df640 (0xffff8881212df640)
[   60.423222] ffffc90006a47b58: ffff888124f8a5f8 (0xffff888124f8a5f8)
[   60.423222] ffffc90006a47b60: 0000000000000a5f (0xa5f)
[   60.423223] ffffc90006a47b68: fffff52000d48fb9 (0xfffff52000d48fb9)
[   60.423224] ffffc90006a47b70: 0000000041b58ab3 (0x41b58ab3)
[   60.423225] ffffc90006a47b78: ffffffff885482ef (SIGMA2+0x2be2f/0x1258c0)
[   60.423226] ffffc90006a47b80: ffffffff84ddec70
(__pfx_filemap_map_pages+0x10/0x10)
[   60.423229] ffffc90006a47b88: ffffffff84edc6c0
(__pfx_set_ptes.constprop.0+0x10/0x10)
[   60.423231] ffffc90006a47b90: ffff88812a3902a8 (0xffff88812a3902a8)
[   60.423232] ffffc90006a47b98: 0000000000000a60 (0xa60)
[   60.423232] ffffc90006a47ba0: ffffea0000200000 (0xffffea0000200000)
[   60.423233] ffffc90006a47ba8: ffff88812a2fd468 (0xffff88812a2fd468)
[   60.423234] ffffc90006a47bb0: 0000000000000000 ...
[   60.423235] ffffc90006a47bc8: ffffc90006a47c08 (0xffffc90006a47c08)
[   60.423235] ffffc90006a47bd0: ffffffff84f3d0b4 (__pte_offset_map+0x24/0x340)
[   60.423238] ffffc90006a47bd8: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.423238] ffffc90006a47be0: 1ffff92000d48f87 (0x1ffff92000d48f87)
[   60.423239] ffffc90006a47be8: ffff88812b9377c0 (0xffff88812b9377c0)
[   60.423240] ffffc90006a47bf0: 00000000c018645d (0xc018645d)
[   60.423241] ffffc90006a47bf8: ffffffff8647eca0 (__pfx_drm_ioctl+0x10/0x10)
[   60.423242] ffffc90006a47c00: 00007fff5004cf70 (0x7fff5004cf70)
[   60.423243] ffffc90006a47c08: ffffc90006a47cc0 (0xffffc90006a47cc0)
[   60.423243] ffffc90006a47c10: ffffffffc077f20c
(vmw_generic_ioctl+0x20c/0x460 [vmwgfx])
[   60.423256] ffffc90006a47c18: 0000000000000060 (0x60)
[   60.423256] ffffc90006a47c20: ffffc90006a47d70 (0xffffc90006a47d70)
[   60.423257] ffffc90006a47c28: 0000000000000060 (0x60)
[   60.423258] ffffc90006a47c30: 0000000000000100 (0x100)
[   60.423259] ffffc90006a47c38: 0000000041b58ab3 (0x41b58ab3)
[   60.423259] ffffc90006a47c40: ffffffffc086614b
(g_SVGA3dSurfaceDescs+0x3ceb/0xfffffffffffa4ba0 [vmwgfx])
[   60.423270] ffffc90006a47c48: ffffffffc077f000
(__pfx_vmw_generic_ioctl+0x10/0x10 [vmwgfx])
[   60.423282] ffffc90006a47c50: 800000012a7cd067 (0x800000012a7cd067)
[   60.423283] ffffc90006a47c58: ffff888100000020 (0xffff888100000020)
[   60.423283] ffffc90006a47c60: 000000000000000b (0xb)
[   60.423284] ffffc90006a47c68: 00000000c018645d (0xc018645d)
[   60.423285] ffffc90006a47c70: ffffc90006a47c80 (0xffffc90006a47c80)
[   60.423286] ffffc90006a47c78: ffffffff85057e11 (__kasan_check_read+0x11/0x20)
[   60.423288] ffffc90006a47c80: ffffc90006a47cd0 (0xffffc90006a47cd0)
[   60.423288] ffffc90006a47c88: ffffffff851a5957 (fdget+0x57/0x500)
[   60.423291] ffffc90006a47c90: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.423292] ffffc90006a47c98: ffff88812b9377c0 (0xffff88812b9377c0)
[   60.423293] ffffc90006a47ca0: ffffffffc0855360
(driver+0x100/0xfffffffffffb1da0 [vmwgfx])
[   60.423304] ffffc90006a47ca8: 00000000c018645d (0xc018645d)
[   60.423305] ffffc90006a47cb0: 00007fff5004cf70 (0x7fff5004cf70)
[   60.423306] ffffc90006a47cb8: ffff88812b9377c0 (0xffff88812b9377c0)
[   60.423307] ffffc90006a47cc0: ffffc90006a47cd0 (0xffffc90006a47cd0)
[   60.423308] ffffc90006a47cc8: ffffffffc077f4c5
(vmw_unlocked_ioctl+0x15/0x30 [vmwgfx])
[   60.423319] ffffc90006a47cd0: ffffc90006a47d08 (0xffffc90006a47d08)
[   60.423320] ffffc90006a47cd8: ffffffff8517c84a (__x64_sys_ioctl+0x13a/0x1c0)
[   60.423323] ffffc90006a47ce0: ffffc90006a47f58 (0xffffc90006a47f58)
[   60.423324] ffffc90006a47ce8: 0000000000000010 (0x10)
[   60.423324] ffffc90006a47cf0: 0000000000000010 (0x10)
[   60.423325] ffffc90006a47cf8: 0000000000000000 ...
[   60.423326] ffffc90006a47d08: ffffc90006a47d18 (0xffffc90006a47d18)
[   60.423326] ffffc90006a47d10: ffffffff8440d8f5 (x64_sys_call+0x1395/0x2670)
[   60.423329] ffffc90006a47d18: ffffc90006a47f48 (0xffffc90006a47f48)
[   60.423330] ffffc90006a47d20: ffffffff8778020c (do_syscall_64+0x7c/0x170)
[   60.423331] ffffc90006a47d28: ffffffff885508f8 (SIGMA2+0x34438/0x1258c0)
[   60.423333] ffffc90006a47d30: ffffffff84f03800
(__pfx___handle_mm_fault+0x10/0x10)
[   60.423335] ffffc90006a47d38: fffff52000d48fc0 (0xfffff52000d48fc0)
[   60.423336] ffffc90006a47d40: fffff52000d48fbd (0xfffff52000d48fbd)
[   60.423336] ffffc90006a47d48: 000076bab44dafff (0x76bab44dafff)
[   60.423337] ffffc90006a47d50: a1d8da26754d4e00 (0xa1d8da26754d4e00)
[   60.423338] ffffc90006a47d58: dffffc0000000000 (0xdffffc0000000000)
[   60.423339] ffffc90006a47d60: ffff888124f8a5f8 (0xffff888124f8a5f8)
[   60.423340] ffffc90006a47d68: dffffc0000000000 (0xdffffc0000000000)
[   60.423340] ffffc90006a47d70: ffff888124f8a5f8 (0xffff888124f8a5f8)
[   60.423341] ffffc90006a47d78: 0000000000100cca (0x100cca)
[   60.423342] ffffc90006a47d80: 0000000000000a52 (0xa52)
[   60.423343] ffffc90006a47d88: 000076bab2e52000 (0x76bab2e52000)
[   60.423343] ffffc90006a47d90: 000076bab2e52710 (0x76bab2e52710)
[   60.423344] ffffc90006a47d98: 0000000000001b54 (0x1b54)
[   60.423345] ffffc90006a47da0: ffff888126939cb8 (0xffff888126939cb8)
[   60.423346] ffffc90006a47da8: ffff88812a7cd750 (0xffff88812a7cd750)
[   60.423346] ffffc90006a47db0: 0000000000000000 ...
[   60.423347] ffffc90006a47db8: 0000000000000006 (0x6)
[   60.423348] ffffc90006a47dc0: 0000000000000001 (0x1)
[   60.423348] ffffc90006a47dc8: 00006079cd852dc0 (0x6079cd852dc0)
[   60.423349] ffffc90006a47dd0: ffff8881e97b8800 (0xffff8881e97b8800)
[   60.423350] ffffc90006a47dd8: 0000000000000006 (0x6)
[   60.423351] ffffc90006a47de0: ffffc90006a47e30 (0xffffc90006a47e30)
[   60.423351] ffffc90006a47de8: ffffffff850c1065
(__count_memcg_events+0x115/0x3d0)
[   60.423355] ffffc90006a47df0: fffffbfff12f1120 (0xfffffbfff12f1120)
[   60.423355] ffffc90006a47df8: ffff8881eca1160c (0xffff8881eca1160c)
[   60.423356] ffffc90006a47e00: ffff8881e97b8d48 (0xffff8881e97b8d48)
[   60.423357] ffffc90006a47e08: 0000000000000286 (0x286)
[   60.423358] ffffc90006a47e10: ffff8881df0d8040 (0xffff8881df0d8040)
[   60.423358] ffffc90006a47e18: 000076bab2e52710 (0x76bab2e52710)
[   60.423359] ffffc90006a47e20: 0000000000000100 (0x100)
[   60.423360] ffffc90006a47e28: 0000000000000000 ...
[   60.423360] ffffc90006a47e30: 0000000000001354 (0x1354)
[   60.423361] ffffc90006a47e38: ffff8881df0d8040 (0xffff8881df0d8040)
[   60.423362] ffffc90006a47e40: 000076bab2e52710 (0x76bab2e52710)
[   60.423363] ffffc90006a47e48: ffffc90006a47e98 (0xffffc90006a47e98)
[   60.423364] ffffc90006a47e50: 0000000000000354 (0x354)
[   60.423364] ffffc90006a47e58: ffff8881729bbdc8 (0xffff8881729bbdc8)
[   60.423365] ffffc90006a47e60: ffff888105c16440 (0xffff888105c16440)
[   60.423366] ffffc90006a47e68: ffffc90006a47e78 (0xffffc90006a47e78)
[   60.423367] ffffc90006a47e70: ffffffff85057e44
(__kasan_check_write+0x14/0x30)
[   60.423368] ffffc90006a47e78: ffffc90006a47e98 (0xffffc90006a47e98)
[   60.423369] ffffc90006a47e80: 0000000000000354 (0x354)
[   60.423370] ffffc90006a47e88: 0000000000000014 (0x14)
[   60.423370] ffffc90006a47e90: ffff888105c16440 (0xffff888105c16440)
[   60.423371] ffffc90006a47e98: ffff8881df0d8040 (0xffff8881df0d8040)
[   60.423372] ffffc90006a47ea0: ffffc90006a47f58 (0xffffc90006a47f58)
[   60.423373] ffffc90006a47ea8: ffff8881df0d8040 (0xffff8881df0d8040)
[   60.423374] ffffc90006a47eb0: ffffc90006a47ec0 (0xffffc90006a47ec0)
[   60.423374] ffffc90006a47eb8: ffffffff85057e11 (__kasan_check_read+0x11/0x20)
[   60.423376] ffffc90006a47ec0: ffffc90006a47ee0 (0xffffc90006a47ee0)
[   60.423377] ffffc90006a47ec8: ffffffff844fc8d1
(fpregs_assert_state_consistent+0x21/0xb0)
[   60.423379] ffffc90006a47ed0: 0000000000000000 ...
[   60.423380] ffffc90006a47ed8: ffffc90006a47f58 (0xffffc90006a47f58)
[   60.423381] ffffc90006a47ee0: ffffc90006a47f08 (0xffffc90006a47f08)
[   60.423381] ffffc90006a47ee8: ffffffff87787263
(irqentry_exit_to_user_mode+0x43/0x260)
[   60.423383] ffffc90006a47ef0: 0000000000000000 ...
[   60.423384] ffffc90006a47ef8: ffffc90006a47f58 (0xffffc90006a47f58)
[   60.423384] ffffc90006a47f00: 0000000000000014 (0x14)
[   60.423385] ffffc90006a47f08: ffffc90006a47f18 (0xffffc90006a47f18)
[   60.423386] ffffc90006a47f10: ffffffff877874d3 (irqentry_exit+0x43/0x50)
[   60.423387] ffffc90006a47f18: ffffffff878018c5 (clear_bhb_loop+0x15/0x70)
[   60.423389] ffffc90006a47f20: ffffffff878018c5 (clear_bhb_loop+0x15/0x70)
[   60.423391] ffffc90006a47f28: ffffffff878018c5 (clear_bhb_loop+0x15/0x70)
[   60.423392] ffffc90006a47f30: 0000000000000000 ...
[   60.423393] ffffc90006a47f50: ffffffff8780012b
(entry_SYSCALL_64_after_hwframe+0x76/0x7e)
[   60.423394] ffffc90006a47f58: 000076bab430aa50 (0x76bab430aa50)
[   60.423395] ffffc90006a47f60: 0000000000000041 (0x41)
[   60.423396] ffffc90006a47f68: 000000000000000b (0xb)
[   60.423396] ffffc90006a47f70: 00005ff5b00716c0 (0x5ff5b00716c0)
[   60.423397] ffffc90006a47f78: 00000000c018645d (0xc018645d)
[   60.423398] ffffc90006a47f80: 00007fff5004cf70 (0x7fff5004cf70)
[   60.423399] ffffc90006a47f88: 0000000000000246 (0x246)
[   60.423400] ffffc90006a47f90: 0000000000000000 ...
[   60.423400] ffffc90006a47f98: 000000007fffffff (0x7fffffff)
[   60.423401] ffffc90006a47fa0: 000076bac03d1460 (0x76bac03d1460)
[   60.423402] ffffc90006a47fa8: ffffffffffffffda (0xffffffffffffffda)
[   60.423403] ffffc90006a47fb0: 000076bac031a94f (0x76bac031a94f)
[   60.423403] ffffc90006a47fb8: 00007fff5004cf70 (0x7fff5004cf70)
[   60.423404] ffffc90006a47fc0: 00000000c018645d (0xc018645d)
[   60.423405] ffffc90006a47fc8: 000000000000000b (0xb)
[   60.423406] ffffc90006a47fd0: 0000000000000010 (0x10)
[   60.423406] ffffc90006a47fd8: 000076bac031a94f (0x76bac031a94f)
[   60.423407] ffffc90006a47fe0: 0000000000000033 (0x33)
[   60.423408] ffffc90006a47fe8: 0000000000000246 (0x246)
[   60.423408] ffffc90006a47ff0: 00007fff5004cec0 (0x7fff5004cec0)
[   60.423409] ffffc90006a47ff8: 000000000000002b (0x2b)

...


From ck.hu at mediatek.com  Sun Dec 22 21:22:22 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 23 Dec 2024 05:22:22 +0000
Subject: [PATCH v3 11/33] drm/mediatek: mtk_hdmi: Unregister audio
 platform device on failure
In-Reply-To: <20241217154345.276919-12-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-12-angelogioacchino.delregno@collabora.com>
Message-ID: <8c5857cc3602342e9d1b4cf6689a0d5a044d9a1d.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> The probe function of this driver may fail after registering the
> audio platform device: in that case, the state is not getting
> cleaned up, leaving this device registered.
> 
> Adding up to the mix, should the probe function of this driver
> return a probe deferral for N times, we're registering up to N
> audio platform devices and, again, never freeing them up.
> 
> To fix this, add a pointer to the audio platform device in the
> mtk_hdmi structure, and add a devm action to unregister it upon
> driver removal or probe failure.
> 
> Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_hdmi.c | 27 +++++++++++++++++++++------
>  1 file changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index 59a8a81fa0ec..9131c2fdfba8 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -172,6 +172,7 @@ struct mtk_hdmi {
>         unsigned int sys_offset;
>         void __iomem *regs;
>         enum hdmi_colorspace csp;
> +       struct platform_device *audio_pdev;
>         struct hdmi_audio_param aud_param;
>         bool audio_enable;
>         bool powered;
> @@ -1662,6 +1663,11 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
>         .no_capture_mute = 1,
>  };
> 
> +static void mtk_hdmi_unregister_audio_driver(void *data)
> +{
> +       platform_device_unregister(data);
> +}
> +
>  static int mtk_hdmi_register_audio_driver(struct device *dev)
>  {
>         struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> @@ -1671,13 +1677,22 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
>                 .i2s = 1,
>                 .data = hdmi,
>         };
> -       struct platform_device *pdev;
> +       int ret;
> 
> -       pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
> -                                            PLATFORM_DEVID_AUTO, &codec_data,
> -                                            sizeof(codec_data));
> -       if (IS_ERR(pdev))
> -               return PTR_ERR(pdev);
> +       hdmi->audio_pdev = platform_device_register_data(dev,
> +                                                        HDMI_CODEC_DRV_NAME,
> +                                                        PLATFORM_DEVID_AUTO,
> +                                                        &codec_data,
> +                                                        sizeof(codec_data));
> +       if (IS_ERR(hdmi->audio_pdev))
> +               return PTR_ERR(hdmi->audio_pdev);
> +
> +       ret = devm_add_action_or_reset(dev, mtk_hdmi_unregister_audio_driver,
> +                                      hdmi->audio_pdev);
> +       if (ret) {
> +               platform_device_unregister(hdmi->audio_pdev);

When devm_add_action_or_reset() fail, it would call mtk_hdmi_unregister_audio_driver() inside it.
So it's not necessary to call platform_device_unregister() here.

Regards,
CK

> +               return ret;
> +       }
> 
>         DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
>         return 0;
> --
> 2.47.0
> 


From manivannan.sadhasivam at linaro.org  Sun Dec 22 22:00:44 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Mon, 23 Dec 2024 11:30:44 +0530
Subject: [PATCH] PCI: mediatek-gen3: Enable async probe by default
In-Reply-To: <20241220145205.1.Ibf2563896c3b1fc133bb46d3fc96ad0041763922@changeid>
References: <20241220145205.1.Ibf2563896c3b1fc133bb46d3fc96ad0041763922@changeid>
Message-ID: <20241223060044.4dux3xym7gjyd3pl@thinkpad>

On Fri, Dec 20, 2024 at 02:52:05PM -0800, Douglas Anderson wrote:
> Like other PCIe drivers, the mediatek-gen3 driver has a fairly slow
> probe. Turn on async probe since there's no reason to block the rest
> of the system.
> 
> Signed-off-by: Douglas Anderson <dianders at chromium.org>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

- Mani

> ---
> 
>  drivers/pci/controller/pcie-mediatek-gen3.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
> index be52e3a123ab..49512786d5e4 100644
> --- a/drivers/pci/controller/pcie-mediatek-gen3.c
> +++ b/drivers/pci/controller/pcie-mediatek-gen3.c
> @@ -1301,6 +1301,7 @@ static struct platform_driver mtk_pcie_driver = {
>  		.name = "mtk-pcie-gen3",
>  		.of_match_table = mtk_pcie_of_match,
>  		.pm = &mtk_pcie_pm_ops,
> +		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
>  	},
>  };
>  
> -- 
> 2.47.1.613.gc27f4b7a9f-goog
> 

-- 
????????? ????????


From dsimic at manjaro.org  Sun Dec 22 22:10:21 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 23 Dec 2024 07:10:21 +0100
Subject: [PATCH 1/3] irqchip/gic-v3: Enable Rockchip 3588001 erratum
 workaround for RK3582
In-Reply-To: <8734ifs3zl.wl-maz@kernel.org>
References: <20241222030355.2246-1-naoki@radxa.com>
 <20241222030355.2246-2-naoki@radxa.com> <86msgoozqa.wl-maz@kernel.org>
 <f93b3bfb5151e4b617b1c99c91b4956f@manjaro.org>
 <8734ifs3zl.wl-maz@kernel.org>
Message-ID: <e3498590dd81b150670e36561d99b6f4@manjaro.org>

Hello Marc,

On 2024-12-23 00:16, Marc Zyngier wrote:
> On Sun, 22 Dec 2024 18:25:02 +0000,
> Dragan Simic <dsimic at manjaro.org> wrote:
>> On 2024-12-22 10:04, Marc Zyngier wrote:
>> > On Sun, 22 Dec 2024 03:03:53 +0000,
>> > FUKAUMI Naoki <naoki at radxa.com> wrote:
>> >>
>> >> Rockchip RK3582 is a scaled down version of Rockchip RK3588(S). Apply
>> >> Rockchip 3588001 erratum workaround to RK3582.
>> >>
>> >> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> >> ---
>> >>  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 92244cfa0464..c59ce9332dc0 100644
>> >> --- a/drivers/irqchip/irq-gic-v3-its.c
>> >> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> >> @@ -4861,7 +4861,8 @@ static bool __maybe_unused
>> >> its_enable_rk3588001(void *data)
>> >>  {
>> >>  	struct its_node *its = data;
>> >>
>> >> -	if (!of_machine_is_compatible("rockchip,rk3588") &&
>> >> +	if (!of_machine_is_compatible("rockchip,rk3582") &&
>> >> +	    !of_machine_is_compatible("rockchip,rk3588") &&
>> >>  	    !of_machine_is_compatible("rockchip,rk3588s"))
>> >>  		return false;
>> >>
>> >
>> > Please use the relevant property for that purpose ("dma-noncoherent")
>> > at the distributor and ITS levels. We're not adding extra compatibles
>> > for this anymore, and you might as well fix the core dtsi to expose
>> > such property.
>> 
>> Thanks for your response.
>> 
>> After a more detailed look into drivers/irqchip/irq-gic-v3-its.c,
>> it seems that relying on the "dma-noncoherent" DT property may not
>> be equivalent to adding another compatible check.
> 
> It is. My email makes it plain what needs doing.
> 
>> Here are a few
>> quotations from irq-gic-v3-its.c, to illustrate this better:
>> 
>> 4746 static bool __maybe_unused its_enable_rk3588001(void *data)
>> 4747 {
>> 4748         struct its_node *its = data;
>> 4749
>> 4750         if (!of_machine_is_compatible("rockchip,rk3588") &&
>> 4751             !of_machine_is_compatible("rockchip,rk3588s"))
>> 4752                 return false;
>> 4753
>> 4754         its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
>> 4755         gic_rdists->flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE;
>> 4756
>> 4757         return true;
>> 4758 }
>> 4759
>> 4760 static bool its_set_non_coherent(void *data)
>> 4761 {
>> 4762         struct its_node *its = data;
>> 4763
>> 4764         its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
>> 4765         return true;
>> 4766 }
>> 
>> 4814 #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
>> 4815         {
>> 4816                 .desc   = "ITS: Rockchip erratum RK3588001",
>> 4817                 .iidr   = 0x0201743b,
>> 4818                 .mask   = 0xffffffff,
>> 4819                 .init   = its_enable_rk3588001,
>> 4820         },
>> 4821 #endif
>> 4822         {
>> 4823                 .desc   = "ITS: non-coherent attribute",
>> 4824                 .property = "dma-noncoherent",
>> 4825                 .init   = its_set_non_coherent,
>> 4826         },
> 
> Nothing tickles me more than having my own work being thrown back at
> me.

I'm sorry, that wasn't my intention.  I just wanted to make
referencing to what I was talking about a bit easier.  Though,
I now see that I was wrong, and I apologize for the noise.

>> As visible above, using the "dma-noncoherent" DT property results
>> in not setting the RDIST_FLAGS_FORCE_NON_SHAREABLE flag, which the
>> its_enable_rk3588001() function does.  In other words, it doesn't
>> seem that "dma-noncoherent" is a "drop-in" replacement for adding
>> yet another compatible for the RK3582.
> 
> You clearly haven't read what I wrote. Or rather, you read what you
> wanted to read, and ignored half of it.

No, it an honest mistake, nothing else.  My intention is never to
twist the reality in any way.

>> Modifying the current behavior of the "dma-noncoherent" DT property
>> doesn't seem like an option, because it's already used in a couple
>> of board dts(i) files.  Should we introduce another DT property,
>> perhaps "dma-noncoherent-rdist" or something similar?
> 
> No. We have everything we need. Believe it or not, I actually know
> what I'm talking about. I know, this is surprising. I surprise myself
> sometimes.

It wasn't my intention to insult you in any way.  I highly respect
everyone's work, including yours, of course.  I am a human being,
so perhaps I am allowed to be tired a bit and, as a result, make
an honest mistake from time to time?

>> Could you, please, advise on how to move forward with this?  I'm
> 
> I already have.

Yes, I see it now.  I'm sorry for not reading the code more carefully
the first time.  I read your earlier response carefully, but I missed
to read the code carefully as well.

>> willing to implement the required patches, but I'd prefer to reduce
>> the possible back-and-forth on them, to save everyone's time.
> 
> May I suggest that you read my email again? How about grepping through
> the upstream DT collection and (shock, horror) look at the imx95.dtsi
> file, which suffers from the same braindead behaviour as the RK stuff?
> 
> For clarity, let me paste it here again, and add some emphasis for
> extra clarity:
> 
>> > Please use the relevant property for that purpose ("dma-noncoherent")
>> > at the distributor and ITS levels. We're not adding extra compatibles
>        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> Now, please go look at the code for real this time, appreciate how the
> "dma-noncoherent" property placed at the distributor *AND* ITS levels
> combine to give you the effects the hardware requires.

You're absolutely right, and I should've read the code more carefully.
I stand corrected, and I appreciate your additional explanation.

> To sum it up: the standard properties and the Rockchip hacks are
> strictly equivalent, there is no need for anything extra, and I stand
> by my NAK on this very patch.

Please note that I never questioned that this patch shouldn't be 
dropped.
I just missed some parts of the code, as an honest mistake, for which I
apologize once again.


From o.rempel at pengutronix.de  Sun Dec 22 22:24:58 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Mon, 23 Dec 2024 07:24:58 +0100
Subject: [PATCH v3] i2c: imx: switch different pinctrl state in different
 system power status
In-Reply-To: <20241223034343.544002-1-carlos.song@nxp.com>
References: <20241223034343.544002-1-carlos.song@nxp.com>
Message-ID: <Z2kCOpE9ohyOfHyD@pengutronix.de>

On Mon, Dec 23, 2024 at 11:43:43AM +0800, Carlos Song wrote:
> Switch different pinctrl state in different system power status.
> 
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Reviewed-by: Frank Li <Frank.Li at nxp.com>

Acked-by: Oleksij Rempel <o.rempel at pengutronix.de>

Thank you!

-- 
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 danishanwar at ti.com  Sun Dec 22 22:30:58 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 23 Dec 2024 12:00:58 +0530
Subject: [PATCH net-next 1/4] net: ti: Kconfig: Select HSR for ICSSG
 Driver
In-Reply-To: <73bc878e-a323-44ef-b90f-11723ce129e3@ti.com>
References: <20241216100044.577489-1-danishanwar@ti.com>
 <20241216100044.577489-2-danishanwar@ti.com>
 <Z2L/hwH5pgBV9pSB@lzaremba-mobl.ger.corp.intel.com>
 <c6254178-6e2a-47e1-ac16-22af5affc8ca@ti.com>
 <Z2RQ7xj6IwPXsqHO@lzaremba-mobl.ger.corp.intel.com>
 <73bc878e-a323-44ef-b90f-11723ce129e3@ti.com>
Message-ID: <45ed487e-7489-4e4f-9e41-ac741ca7882d@ti.com>

Hi,

On 20/12/24 11:01 am, Anwar, Md Danish wrote:
> Hi,
> 
> On 12/19/2024 10:29 PM, Larysa Zaremba wrote:
>> On Thu, Dec 19, 2024 at 10:36:57AM +0530, MD Danish Anwar wrote:
>>>
>>>
>>> On 18/12/24 10:29 pm, Larysa Zaremba wrote:
>>>> On Mon, Dec 16, 2024 at 03:30:41PM +0530, MD Danish Anwar wrote:
>>>>> HSR offloading is supported by ICSSG driver. Select the symbol HSR for
>>>>> TI_ICSSG_PRUETH. Also select NET_SWITCHDEV instead of depending on it to
>>>>> remove recursive dependency.
>>>>>
>>>>
>>>> 2 things:
>>>> 1) The explanation from the cover should have been included in the commit 
>>>>    message.
>>>
>>> I wanted to keep the commit message brief so I provided the actual
>>> errors in cover letter. I will add the logs here as well.
>>>
>>
>> Commit message has to be as verbose as needed to provide enough context for 
>> whoever needs to explore the code history later.
>>  
> 
> Sure I will update the commit message.
> 
>>>> 2) Why not `depends on HSR`?
>>>
>>> Adding `depends on HSR` in `config TI_ICSSG_PRUETH` is not setting HSR.
>>> I have tried below scenarios and only one of them work.
>>>
>>> 1) depends on NET_SWITCHDEV
>>>    depends on HSR
>>>
>>> 	HSR doesn't get set in .config - `# CONFIG_HSR is not set`. Even the
>>> CONFIG_TI_ICSSG_PRUETH also gets unset although this is set to =m in
>>> defconfig. But keeping both as `depends on` makes CONFIG_TI_ICSSG_PRUETH
>>> disabled.
>>
>> I do not understand your problem with this option, CONFIG_HSR is a visible 
>> option that you can enable manually only then you will be able to successfully 
>> set CONFIG_TI_ICSSG_PRUETH to m/y, this is how the relation with NET_SWITCHDEV 
>> currently works.
>>
> 
> The only problem with this option is that when I do `make defconfig`, it
> will unset CONFIG_TI_ICSSG_PRUETH.
> 
> I will have to manually change the arch/arm64/configs/defconfig to set
> HSR=m and then only `make defconfig` will enable CONFIG_TI_ICSSG_PRUETH
> 
> Currently HSR is not enabled in defconfig. I will have to send out a
> patch to set HSR=m in defconfig
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index c62831e61586..ff3e5d960e2a 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -129,6 +129,7 @@ CONFIG_MEMORY_FAILURE=y
>  CONFIG_TRANSPARENT_HUGEPAGE=y
>  CONFIG_NET=y
>  CONFIG_PACKET=y
> +CONFIG_HSR=m
>  CONFIG_UNIX=y
>  CONFIG_INET=y
>  CONFIG_IP_MULTICAST=y
> 
> 
> Since I am the only one needing HSR, I thought it would be better if I
> select HSR and it only gets built if CONFIG_TI_ICSSG_PRUETH is enabled
> instead of always getting built.
> 
> For this reason I thought selecting HSR would be good choice, since just
> selecting HSR wasn't enough and resulted in recursive dependency,  I had
> to change NET_SWITCHDEV also to select.
> 
> BTW `NET_DSA` selects `NET_SWITCHDEV` (net/dsa/Kconfig:9)
> 
>> Just 'depends on' is still a preferred way for me, as there is not a single 
>> driver that does 'select NET_SWITCHDEV'
>>
>>>
>>> 2) select NET_SWITCHDEV
>>>    depends on HSR
>>>
>>> 	HSR doesn't get set in .config - `# CONFIG_HSR is not set`. Even the
>>> CONFIG_TI_ICSSG_PRUETH also gets unset although this is set to =m in
>>> defconfig. But keeping both as `depends on` makes CONFIG_TI_ICSSG_PRUETH
>>> disabled.
>>>
>>> 3) depends on NET_SWITCHDEV
>>>    select HSR
>>> 	
>>> 	Results in recursive dependency
>>>
>>> error: recursive dependency detected!
>>> 	symbol NET_DSA depends on HSR
>>> 	symbol HSR is selected by TI_ICSSG_PRUETH
>>> 	symbol TI_ICSSG_PRUETH depends on NET_SWITCHDEV
>>> 	symbol NET_SWITCHDEV is selected by NET_DSA
>>> For a resolution refer to Documentation/kbuild/kconfig-language.rst
>>> subsection "Kconfig recursive dependency limitations"
>>>
>>> make[2]: *** [scripts/kconfig/Makefile:95: defconfig] Error 1
>>> make[1]: *** [/home/danish/workspace/net-next/Makefile:733: defconfig]
>>> Error 2
>>> make: *** [Makefile:251: __sub-make] Error 2
>>>
>>> 4) select NET_SWITCHDEV
>>>    select HSR
>>>
>>> 	HSR is set as `m` along with `CONFIG_TI_ICSSG_PRUETH`
>>>
>>> CONFIG_HSR=m
>>> CONFIG_NET_SWITCHDEV=y
>>> CONFIG_TI_ICSSG_PRUETH=m
>>>
>>> #4 is the only secnario where HSR gets built. That's why I sent the
>>> patch with `select NET_SWITCHDEV` and `select HSR`
>>>
> 
> I still think 4 is the best option. Only difference here is that we have
> to `select NET_SWITCHDEV` as well.
> 

I see there is some issue seen
https://lore.kernel.org/all/202412210336.BmgcX3Td-lkp at intel.com/ with
this patch.

For now I'll drop this patch and send out a separate patch to defconfig
to set HSR=m.

Once the defconfig patch gets merged, I will add `depends on HSR` in
Kconfig for TI_ICSSG_PRUETH (the method suggested by you)

Thanks for the review.

>>>>  
>>>>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>>>>> ---
>>>>>  drivers/net/ethernet/ti/Kconfig | 3 ++-
>>>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
>>>>> index 0d5a862cd78a..ad366abfa746 100644
>>>>> --- a/drivers/net/ethernet/ti/Kconfig
>>>>> +++ b/drivers/net/ethernet/ti/Kconfig
>>>>> @@ -187,8 +187,9 @@ config TI_ICSSG_PRUETH
>>>>>  	select PHYLIB
>>>>>  	select TI_ICSS_IEP
>>>>>  	select TI_K3_CPPI_DESC_POOL
>>>>> +	select NET_SWITCHDEV
>>>>> +	select HSR
>>>>>  	depends on PRU_REMOTEPROC
>>>>> -	depends on NET_SWITCHDEV
>>>>>  	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
>>>>>  	depends on PTP_1588_CLOCK_OPTIONAL
>>>>>  	help
>>>>> -- 
>>>>> 2.34.1
>>>>>
>>>>>
>>>
>>> -- 
>>> Thanks and Regards,
>>> Danish
> 

-- 
Thanks and Regards,
Danish


From ck.hu at mediatek.com  Sun Dec 22 22:35:36 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 23 Dec 2024 06:35:36 +0000
Subject: [PATCH v3 24/33] drm/mediatek: mtk_hdmi: Remove ifdef for
 CONFIG_PM_SLEEP
In-Reply-To: <20241217154345.276919-25-angelogioacchino.delregno@collabora.com>
References: <20241217154345.276919-1-angelogioacchino.delregno@collabora.com>
	 <20241217154345.276919-25-angelogioacchino.delregno@collabora.com>
Message-ID: <498667e57b24c754d87742854bfbedfc821931cf.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-12-17 at 16:43 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until you have verified the sender or the content.
> 
> 
> Since the SIMPLE_DEV_PM_OPS macro and the pm pointer are anyway
> defined when CONFIG_PM_SLEEP is not set, remove the ifdef for it
> and indicate that the mtk_hdmi_{remove,suspend} functions may be
> unused (as they are, in case PM support is not built-in).

I see many driver use CONFIG_PM_SLEEP,
and SIMPLE_DEV_PM_OPS() is defined to support suspend/resume function is not exist when CONFIG_PM_SLEEP is not defined,
so there is no strong purpose to apply this patch.

> 
> While at it, to improve readability, also compress the
> SIMPLE_DEV_PM_OPS declaration as it even fits in less
> than 80 columns.

You have many typesetting in some patches.
But I think typesetting is not related to the main purpose of that patch.
I would like you to gather these typesetting modification to a readability patch.

Regards,
CK

> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_hdmi.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index 5d46d486c68f..7e4536391cfb 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -1694,8 +1694,7 @@ static void mtk_hdmi_remove(struct platform_device *pdev)
>         mtk_hdmi_clk_disable_audio(hdmi);
>  }
> 
> -#ifdef CONFIG_PM_SLEEP
> -static int mtk_hdmi_suspend(struct device *dev)
> +static __maybe_unused int mtk_hdmi_suspend(struct device *dev)
>  {
>         struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> 
> @@ -1704,7 +1703,7 @@ static int mtk_hdmi_suspend(struct device *dev)
>         return 0;
>  }
> 
> -static int mtk_hdmi_resume(struct device *dev)
> +static __maybe_unused int mtk_hdmi_resume(struct device *dev)
>  {
>         struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
>         int ret = 0;
> @@ -1717,9 +1716,8 @@ static int mtk_hdmi_resume(struct device *dev)
> 
>         return 0;
>  }
> -#endif
> -static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops,
> -                        mtk_hdmi_suspend, mtk_hdmi_resume);
> +
> +static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops, mtk_hdmi_suspend, mtk_hdmi_resume);
> 
>  static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = {
>         .tz_disabled = true,
> --
> 2.47.0
> 


From victor.liu at nxp.com  Sun Dec 22 22:41:30 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:30 +0800
Subject: [PATCH v7 02/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller blit engine
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-3-victor.liu@nxp.com>

i.MX8qxp Display Controller contains a blit engine for raster graphics.
It may read up to 3 source images from memory and computes one destination
image from it, which is written back to memory.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Add instance numbers to blit engine internel devices' compatible strings.
  (Rob)
* Drop some Rob's R-b tag.

v6:
* No change.

v5:
* No change.

v4:
* Collect Rob's R-b tag.

v3:
* New patch. (Rob)

 .../imx/fsl,imx8qxp-dc-blit-engine.yaml       | 204 ++++++++++++++++++
 1 file changed, 204 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml
new file mode 100644
index 000000000000..6c14ce653619
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml
@@ -0,0 +1,204 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blit-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Blit Engine
+
+description: |
+  A blit operation (block based image transfer) reads up to 3 source images
+  from memory and computes one destination image from it, which is written
+  back to memory. The following basic operations are supported:
+
+  * Buffer Fill
+    Fills a buffer with constant color
+
+  * Buffer Copy
+    Copies one source to a destination buffer.
+
+  * Image Blend
+    Combines two source images by a blending equation and writes result to
+    destination (which can be one of the sources).
+
+  * Image Rop2/3
+    Combines up to three source images by a logical equation (raster operation)
+    and writes result to destination (which can be one of the sources).
+
+  * Image Flip
+    Mirrors the source image in horizontal and/or vertical direction.
+
+  * Format Convert
+    Convert between the supported color and buffer formats.
+
+  * Color Transform
+    Modify colors by linear or non-linear transformations.
+
+  * Image Scale
+    Changes size of the source image.
+
+  * Image Rotate
+    Rotates the source image by any angle.
+
+  * Image Filter
+    Performs an FIR filter operation on the source image.
+
+  * Image Warp
+    Performs a re-sampling of the source image with any pattern. The sample
+    point positions are read from a compressed coordinate buffer.
+
+  * Buffer Pack
+    Writes an image with color components stored in up to three different
+    buffers (planar formats) into a single buffer (packed format).
+
+  * Chroma Resample
+    Converts between different YUV formats that differ in chroma sampling rate
+    (4:4:4, 4:2:2, 4:2:0).
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-blit-engine
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^blitblend@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-blitblend9
+
+  "^clut@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-clut9
+
+  "^fetchdecode@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchdecode9
+
+  "^fetcheco@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetcheco9
+
+  "^fetchwarp@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchwarp9
+
+  "^filter@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-filter9
+
+  "^hscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-hscaler9
+
+  "^matrix@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-matrix9
+
+  "^rop@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-rop9
+
+  "^store@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-store9
+
+  "^vscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-vscaler9
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    blit-engine at 56180820 {
+        compatible = "fsl,imx8qxp-dc-blit-engine";
+        reg = <0x56180820 0x13c>, <0x56181000 0x3400>;
+        reg-names = "pec", "cfg";
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        fetchdecode at 56180820 {
+            compatible = "fsl,imx8qxp-dc-fetchdecode9";
+            reg = <0x56180820 0x10>, <0x56181000 0x404>;
+            reg-names = "pec", "cfg";
+        };
+
+        store at 56180940 {
+            compatible = "fsl,imx8qxp-dc-store9";
+            reg = <0x56180940 0x1c>, <0x56184000 0x5c>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <0>, <1>, <2>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:28 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:28 +0800
Subject: [PATCH v7 00/19] Add Freescale i.MX8qxp Display Controller support
Message-ID: <20241223064147.3961652-1-victor.liu@nxp.com>

Hi,

This patch series aims to add Freescale i.MX8qxp Display Controller support.

The controller is comprised of three main components that include a blit
engine for 2D graphics accelerations, display controller for display output
processing, as well as a command sequencer.

Previous patch series attempts to do that can be found at:
https://patchwork.freedesktop.org/series/84524/

This series addresses Maxime's comments on the previous one:
a. Split the display controller into multiple internal devices.
   1) List display engine, pixel engine, interrupt controller and more as the
      controller's child devices.
   2) List display engine and pixel engine's processing units as their child
      devices.

b. Add minimal feature support.
   Only support two display pipelines with primary planes with XR24 fb,
   backed by two fetchunits.  No fetchunit dynamic allocation logic(to be done
   when necessary).

c. Use drm_dev_{enter, exit}().

Since this series changes a lot comparing to the previous one, I choose to
send it with a new patch series, not a new version.

To follow up i.MX8qxp TRM, I changed the controller name to "Display Controller"
instead of the previous "DPU".  "DPU" is only mentioned in the SoC block
diagram and represents the whole display subsystem which includes the display
controller and prefech engines, etc.

With an additional patch[1] for simple-pm-bus.c, this series facilitates
testing a LVDS panel on i.MX8qxp MEK.

Please do NOT merge patch 14-19.  They are only used to facilitate testing
the LVDS panel.

[1] https://lkml.org/lkml/2023/1/25/120

v7:
* Drop using DT aliases for display controller internal devices and add
  instance numbers to display controller internel devices' compatible
  strings. Drop Rob's R-b tags on some DT bindings patches. (Rob)
* Drop using typeof in macros and explicitly define variable types in patch 12.
  (Dmitry)
* Add a comment for disable_irq_nosync() to explain why _nosync in patch 12.
  (Dmitry)
* Inline dc_crtc_check_clock() in patch 12. (Dmitry)
* Use global drm_dc->pe in patch 12. (Dmitry)
* Drop dc_crtc_disable_at_unbind() from KMS driver in patch 12. (Dmitry)
* Add kernel doc for struct dc_{crtc,drm_device,plane} in patch 9/10/12.
  (Dmitry)
* Define common IRQ handlers separately for each IRQs in patch 12. (Dmitry)
* Rebase this series upon next-20241220, so drop date entry from drm_driver
  and correctly include drm/clients/drm_client_setup.h.
* Fix regmap_config definitions for display controller internal device drivers
  in patch 9/10/11 by correcting name field, correcting read ranges and setting
  max_register field.
* Get instance numbers from device data(compatible strings) instead of OF
  aliases in display controller internal device drivers in patch 9/10/11.
* Collect Maxime's R-b tags on interrupt controller driver and display drivers.
* Trivial tweaks.

v6:
* Fix build warning by expanding sizeof(fu->name) from 13 to 21 in patch 10.
  (kernel test robot)

v5:
* Document display controller device's and some display controller internal
  devices' aliases in DT bindings. Hence, drop collected R-b tags from some
  patches for DT bindings. (Maxime)
* Replace .remove_new with .remove in all drivers. (Uwe)
* Select REGMAP and REGMAP_MMIO options in patch 9.
* Fix patch 9 & 10's commit message to state that display engine driver and
  pixel engine driver are component drivers instead of master/aggregate drivers.

v4:
* Collect Rob's R-b tags on DT binding patches(patch 1-5).
* Replace "fsl,iram" property with standard "sram" property in
  fsl,imx8qxp-dc-command-sequencer.yaml in patch 6. (Rob)
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Inline some small functions. (Dmitry)
* Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
  function calls from KMS routine to initialization stage. (Dmitry)
* Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
  appropriate .h header files or .c source files. (Dmitry)
* Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
* Drop dc_drm->pe_rpm_count. (Dmitry)
* Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
* Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
  Instead, put it in struct dc_crtc.  (Dmitry)
* Call devm_request_irq() to request IRQs, instead of using drmm action.
  (Dmitry)
* Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
* Select DRM_CLIENT_SELECTION due to rebase.
* Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
* Drop unnecessary private struct dc_*_priv from DC internal device drivers.
* Set suppress_bind_attrs driver flag to true in DC internal device drivers
  to avoid unnecessary sys interfaces to bind/unbind the drivers.
* Make some fetch unit operations be aware of fractional fetch unit index(0-7).
* Take DC interrupt controller driver as a standalone driver instead of a
  component driver.
* Replace drmm_kcalloc() with devm_kcalloc() to allocate an array for
  struct dc_ic_entry.
* Call platform_get_irq() from DC interrupt controller driver to make sure
  parent interrupt controller driver is probed first.
* Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
* Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
  rebase.
* Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
  register dc_drm_component_unbind_all() action.
* Request interrupts in dc_crtc_post_init() after encoder initialization to
  make sure next bridge is found first.
* Trivial tweaks.

v3:
* Collect Rob's R-b tag on the patch for adding fsl,imx8qxp-dc-intc.yaml.
* Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
  fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
  into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
* Document all processing units, command sequencer, axi performance counter
  and blit engine. (Rob)

v2:
* Drop fsl,dc-*-id DT properties from fsl,imx8qxp-dc*.yaml. (Krzysztof)
* Move port property from fsl,imx8qxp-dc-display-engine.yaml to
  fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
* Drop unneeded "|" from fsl,imx8qxp-dc-intc.yaml. (Krzysztof)
* Use generic pmu pattern property in fsl,imx8qxp-dc.yaml. (Krzysztof)
* Fix register range size in fsl,imx8qxp-dc*.yaml.
* Use OF alias id to get instance id from display driver.
* Find next bridge from TCon's port from display driver.
* Drop drm/drm_module.h include from dc-drv.c.
* Improve file list in MAINTAINERS. (Frank)
* Add entire i.MX8qxp display controller device tree for review. (Krzysztof)
* Add MIPI/LVDS subsystems device tree and a DT overlay for imx8qxp
  MEK to test a LVDS panel as an example. (Francesco)

Liu Ying (19):
  dt-bindings: display: imx: Add i.MX8qxp Display Controller processing
    units
  dt-bindings: display: imx: Add i.MX8qxp Display Controller blit engine
  dt-bindings: display: imx: Add i.MX8qxp Display Controller display
    engine
  dt-bindings: display: imx: Add i.MX8qxp Display Controller pixel
    engine
  dt-bindings: display: imx: Add i.MX8qxp Display Controller AXI
    performance counter
  dt-bindings: display: imx: Add i.MX8qxp Display Controller command
    sequencer
  dt-bindings: interrupt-controller: Add i.MX8qxp Display Controller
    interrupt controller
  dt-bindings: display: imx: Add i.MX8qxp Display Controller
  drm/imx: Add i.MX8qxp Display Controller display engine
  drm/imx: Add i.MX8qxp Display Controller pixel engine
  drm/imx: Add i.MX8qxp Display Controller interrupt controller
  drm/imx: Add i.MX8qxp Display Controller KMS
  MAINTAINERS: Add maintainer for i.MX8qxp Display Controller
  dt-bindings: phy: mixel, mipi-dsi-phy: Allow assigned-clock*
    properties
  dt-bindings: firmware: imx: Add SCU controlled display pixel link
    nodes
  arm64: dts: imx8qxp: Add display controller subsystem
  arm64: dts: imx8qxp: Add MIPI-LVDS combo subsystems
  arm64: dts: imx8qxp-mek: Enable display controller
  arm64: dts: imx8qxp-mek: Add MX8-DLVDS-LCD1 display module support

 ...sl,imx8qxp-dc-axi-performance-counter.yaml |  57 ++
 .../imx/fsl,imx8qxp-dc-blit-engine.yaml       | 204 +++++++
 .../imx/fsl,imx8qxp-dc-blitblend9.yaml        |  41 ++
 .../display/imx/fsl,imx8qxp-dc-clut9.yaml     |  44 ++
 .../imx/fsl,imx8qxp-dc-command-sequencer.yaml |  67 +++
 .../imx/fsl,imx8qxp-dc-constframe0.yaml       |  48 ++
 .../imx/fsl,imx8qxp-dc-display-engine0.yaml   | 235 ++++++++
 .../display/imx/fsl,imx8qxp-dc-dither0.yaml   |  47 ++
 .../display/imx/fsl,imx8qxp-dc-extdst0.yaml   |  76 +++
 .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 +++++
 .../display/imx/fsl,imx8qxp-dc-filter9.yaml   |  43 ++
 .../display/imx/fsl,imx8qxp-dc-framegen0.yaml |  66 +++
 .../display/imx/fsl,imx8qxp-dc-gammacor0.yaml |  34 ++
 .../imx/fsl,imx8qxp-dc-layerblend0.yaml       |  43 ++
 .../display/imx/fsl,imx8qxp-dc-matrix0.yaml   |  76 +++
 .../imx/fsl,imx8qxp-dc-pixel-engine.yaml      | 273 +++++++++
 .../display/imx/fsl,imx8qxp-dc-rop9.yaml      |  43 ++
 .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++
 .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  87 +++
 .../imx/fsl,imx8qxp-dc-signature0.yaml        |  55 ++
 .../display/imx/fsl,imx8qxp-dc-store9.yaml    |  96 +++
 .../display/imx/fsl,imx8qxp-dc-tcon0.yaml     |  47 ++
 .../bindings/display/imx/fsl,imx8qxp-dc.yaml  | 238 ++++++++
 .../devicetree/bindings/firmware/fsl,scu.yaml |  20 +
 .../fsl,imx8qxp-dc-intc.yaml                  | 318 ++++++++++
 .../bindings/phy/mixel,mipi-dsi-phy.yaml      |   5 -
 MAINTAINERS                                   |   8 +
 arch/arm64/boot/dts/freescale/Makefile        |   4 +
 .../arm64/boot/dts/freescale/imx8-ss-dc0.dtsi | 408 +++++++++++++
 .../imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso | 183 ++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |  34 ++
 .../boot/dts/freescale/imx8qxp-ss-dc.dtsi     | 240 ++++++++
 .../dts/freescale/imx8qxp-ss-mipi-lvds.dtsi   | 437 ++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   7 +-
 drivers/gpu/drm/imx/Kconfig                   |   1 +
 drivers/gpu/drm/imx/Makefile                  |   1 +
 drivers/gpu/drm/imx/dc/Kconfig                |  13 +
 drivers/gpu/drm/imx/dc/Makefile               |   7 +
 drivers/gpu/drm/imx/dc/dc-cf.c                | 173 ++++++
 drivers/gpu/drm/imx/dc/dc-crtc.c              | 556 ++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-de.c                | 153 +++++
 drivers/gpu/drm/imx/dc/dc-de.h                |  65 ++
 drivers/gpu/drm/imx/dc/dc-drv.c               | 277 +++++++++
 drivers/gpu/drm/imx/dc/dc-drv.h               |  61 ++
 drivers/gpu/drm/imx/dc/dc-ed.c                | 292 +++++++++
 drivers/gpu/drm/imx/dc/dc-fg.c                | 378 ++++++++++++
 drivers/gpu/drm/imx/dc/dc-fl.c                | 182 ++++++
 drivers/gpu/drm/imx/dc/dc-fu.c                | 268 +++++++++
 drivers/gpu/drm/imx/dc/dc-fu.h                | 129 ++++
 drivers/gpu/drm/imx/dc/dc-fw.c                | 223 +++++++
 drivers/gpu/drm/imx/dc/dc-ic.c                | 282 +++++++++
 drivers/gpu/drm/imx/dc/dc-kms.c               | 143 +++++
 drivers/gpu/drm/imx/dc/dc-kms.h               | 131 +++++
 drivers/gpu/drm/imx/dc/dc-lb.c                | 324 ++++++++++
 drivers/gpu/drm/imx/dc/dc-pe.c                | 133 +++++
 drivers/gpu/drm/imx/dc/dc-pe.h                | 107 ++++
 drivers/gpu/drm/imx/dc/dc-plane.c             | 241 ++++++++
 drivers/gpu/drm/imx/dc/dc-tc.c                | 142 +++++
 58 files changed, 8041 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blit-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-mek-mx8-dlvds-lcd1-lvds0-odd.dtso
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi
 create mode 100644 drivers/gpu/drm/imx/dc/Kconfig
 create mode 100644 drivers/gpu/drm/imx/dc/Makefile
 create mode 100644 drivers/gpu/drm/imx/dc/dc-cf.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ed.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fg.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fl.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fw.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ic.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-lb.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-tc.c

-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:29 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:29 +0800
Subject: [PATCH v7 01/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller processing units
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-2-victor.liu@nxp.com>

Freescale i.MX8qxp Display Controller is implemented as construction set of
building blocks with unified concept and standardized interfaces.  Document
all existing processing units.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Drop DT alias documentations and add instance numbers to compatible strings.
  (Rob)

v6:
* No change.

v5:
* Document aliases for processing units which have multiple instances in
  the Display Controller.  Drop Rob's previous R-b tag. (Maxime)

v4:
* Collect Rob's R-b tag.

v3:
* Combine fsl,imx8qxp-dc-fetchunit-common.yaml,
  fsl,imx8qxp-dc-fetchlayer.yaml and fsl,imx8qxp-dc-fetchwarp.yaml
  into 1 schema doc fsl,imx8qxp-dc-fetchunit.yaml. (Rob)
* Document all processing units. (Rob)

v2:
* Drop fsl,dc-*-id DT properties. (Krzysztof)
* Add port property to fsl,imx8qxp-dc-tcon.yaml. (Krzysztof)
* Fix register range sizes in examples.

 .../imx/fsl,imx8qxp-dc-blitblend9.yaml        |  41 +++++
 .../display/imx/fsl,imx8qxp-dc-clut9.yaml     |  44 ++++++
 .../imx/fsl,imx8qxp-dc-constframe0.yaml       |  48 ++++++
 .../display/imx/fsl,imx8qxp-dc-dither0.yaml   |  47 ++++++
 .../display/imx/fsl,imx8qxp-dc-extdst0.yaml   |  76 +++++++++
 .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 147 ++++++++++++++++++
 .../display/imx/fsl,imx8qxp-dc-filter9.yaml   |  43 +++++
 .../display/imx/fsl,imx8qxp-dc-framegen0.yaml |  66 ++++++++
 .../display/imx/fsl,imx8qxp-dc-gammacor0.yaml |  34 ++++
 .../imx/fsl,imx8qxp-dc-layerblend0.yaml       |  43 +++++
 .../display/imx/fsl,imx8qxp-dc-matrix0.yaml   |  76 +++++++++
 .../display/imx/fsl,imx8qxp-dc-rop9.yaml      |  43 +++++
 .../display/imx/fsl,imx8qxp-dc-safety.yaml    |  34 ++++
 .../imx/fsl,imx8qxp-dc-scaling-engine.yaml    |  87 +++++++++++
 .../imx/fsl,imx8qxp-dc-signature0.yaml        |  55 +++++++
 .../display/imx/fsl,imx8qxp-dc-store9.yaml    |  96 ++++++++++++
 .../display/imx/fsl,imx8qxp-dc-tcon0.yaml     |  47 ++++++
 17 files changed, 1027 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature0.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store9.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon0.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend9.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend9.yaml
new file mode 100644
index 000000000000..621f8b30efcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-blitblend9.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blitblend9.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Blit Blend Unit
+
+description:
+  Combines two input frames to a single output frame, all frames having the
+  same dimension.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-blitblend9
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    blitblend at 56180920 {
+        compatible = "fsl,imx8qxp-dc-blitblend9";
+        reg = <0x56180920 0x10>, <0x56183c00 0x3c>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut9.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut9.yaml
new file mode 100644
index 000000000000..00e748d39a72
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-clut9.yaml
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-clut9.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Color Lookup Table
+
+description: |
+  The unit implements 3 look-up tables with 256 x 10 bit entries each. These
+  can be used for different kinds of applications. From 10-bit input values
+  only upper 8 bits are used.
+
+  The unit supports color lookup, index lookup, dithering and alpha masking.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-clut9
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    clut at 56180880 {
+        compatible = "fsl,imx8qxp-dc-clut9";
+        reg = <0x56180880 0x10>, <0x56182400 0x404>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe0.yaml
new file mode 100644
index 000000000000..aeaf65b126cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe0.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-constframe0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Constant Frame
+
+description: |
+  The Constant Frame unit is used instead of a Fetch unit where generation of
+  constant color frames only is sufficient. This is the case for the background
+  planes of content and safety streams in a Display Controller.
+
+  The color can be setup to any RGBA value.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-constframe0
+      - fsl,imx8qxp-dc-constframe1
+      - fsl,imx8qxp-dc-constframe4
+      - fsl,imx8qxp-dc-constframe5
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    constframe at 56180960 {
+        compatible = "fsl,imx8qxp-dc-constframe0";
+        reg = <0x56180960 0xc>, <0x56184400 0x20>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither0.yaml
new file mode 100644
index 000000000000..aff739f23244
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-dither0.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-dither0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Dither Unit
+
+description: |
+  The unit can increase the physical color resolution of a display from 5, 6, 7
+  or 8 bits per RGB channel to a virtual resolution of 10 bits. The physical
+  resolution can be set individually for each channel.
+
+  The resolution is increased by mixing the two physical colors that are nearest
+  to the virtual color code in a variable ratio either by time (temporal
+  dithering) or by position (spatial dithering).
+
+  An optimized algorithm for temporal dithering minimizes noise artifacts on the
+  output image.
+
+  The dither operation can be individually enabled or disabled for each pixel
+  using the alpha input bit.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-dither0
+      - fsl,imx8qxp-dc-dither1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    dither at 5618c400 {
+        compatible = "fsl,imx8qxp-dc-dither0";
+        reg = <0x5618c400 0x14>;
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst0.yaml
new file mode 100644
index 000000000000..5c64e897bc35
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst0.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-extdst0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller External Destination Interface
+
+description: |
+  The External Destination unit is the interface between the internal pixel
+  processing pipeline of the Pixel Engine, which is 30-bit RGB plus 8-bit Alpha,
+  and a Display Engine.
+
+  It comprises the following built-in Gamma apply function.
+
+  +------X-----------------------+
+  |      |          ExtDst Unit  |
+  |      V                       |
+  |  +-------+                   |
+  |  | Gamma |                   |
+  |  +-------+                   |
+  |      |                       |
+  |      V                       +
+  +------X-----------------------+
+
+  The output format is 24-bit RGB plus 1-bit Alpha. Conversion from 10 to 8
+  bits is done by LSBit truncation.  Alpha output bit is 1 for input 255, 0
+  otherwise.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-extdst0
+      - fsl,imx8qxp-dc-extdst1
+      - fsl,imx8qxp-dc-extdst4
+      - fsl,imx8qxp-dc-extdst5
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: framecomplete
+      - const: seqcomplete
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    extdst at 56180980 {
+        compatible = "fsl,imx8qxp-dc-extdst0";
+        reg = <0x56180980 0x1c>, <0x56184800 0x28>;
+        reg-names = "pec", "cfg";
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <3>, <4>, <5>;
+        interrupt-names = "shdload", "framecomplete", "seqcomplete";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
new file mode 100644
index 000000000000..92f6600af49e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-fetchunit.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Fetch Unit
+
+description: |
+  The Fetch Unit is the interface between the AXI bus for source buffer access
+  and the internal pixel processing pipeline, which is 30-bit RGB plus 8-bit
+  Alpha.
+
+  It is used to generate foreground planes in Display Controllers and source
+  planes in Blit Engines, and comprises the following built-in functions to
+  convert a wide range of frame buffer types.
+
+  +---------X-----------------------------------------+
+  |         |                           Fetch Unit    |
+  |         V                                         |
+  |    +---------+                                    |
+  |    |         |                                    |
+  |    | Decode  | Decompression [Decode]             |
+  |    |         |                                    |
+  |    +---------+                                    |
+  |         |                                         |
+  |         V                                         |
+  |    +---------+                                    |
+  |    | Clip &  | Clip Window [All]                  |
+  |    | Overlay | Plane composition [Layer, Warp]    |
+  |    |         |                                    |
+  |    +---------+                                    |
+  |         |                                         |
+  |         V                                         |
+  |    +---------+                                    |
+  |    | Re-     | Flip/Rotate/Repl./Drop [All]       |
+  X--> | sample  | Perspective/Affine warping [Persp] |
+  | |  |         | Arbitrary warping [Warp, Persp]    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         |                                    |
+  | |  | Palette | Color Palette [Layer, Decode]      |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  | Extract | Raw to RGBA/YUV [All]              |
+  | |  | &       | Bit width expansion [All]          |
+  | |  | Expand  |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | Planar to packed                   |
+  | |->| Combine | [Decode, Warp, Persp]              |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | YUV422 to YUV444                   |
+  | |  | Chroma  | [Decode, Persp]                    |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | YUV to RGB                         |
+  | |  | Color   | [Warp, Persp, Decode, Layer]       |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | Gamma removal                      |
+  | |  | Gamma   | [Warp, Persp, Decode, Layer]       |
+  | |  |         |                                    |
+  | |  +---------+                                    |
+  | |       |                                         |
+  | |       V                                         |
+  | |  +---------+                                    |
+  | |  |         | Alpla multiply, RGB pre-multiply   |
+  |  ->| Multiply| [Warp, Persp, Decode, Layer]       |
+  |    |         |                                    |
+  |     ---------                                     |
+  |         |                                         |
+  |         V                                         |
+  |    +---------+                                    |
+  |    |         | Bilinear filter                    |
+  |    | Filter  | [Warp, Persp]                      |
+  |    |         |                                    |
+  |    +---------+                                    |
+  |         |                                         |
+  |         V                                         |
+  +---------X-----------------------------------------+
+
+  Note that different derivatives of the Fetch Unit exist. Each implements a
+  specific subset only of the pipeline stages shown above. Restrictions for the
+  units are specified in [square brackets].
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-fetchdecode0
+      - fsl,imx8qxp-dc-fetchdecode1
+      - fsl,imx8qxp-dc-fetchdecode9
+      - fsl,imx8qxp-dc-fetcheco0
+      - fsl,imx8qxp-dc-fetcheco1
+      - fsl,imx8qxp-dc-fetcheco2
+      - fsl,imx8qxp-dc-fetcheco9
+      - fsl,imx8qxp-dc-fetchlayer0
+      - fsl,imx8qxp-dc-fetchwarp2
+      - fsl,imx8qxp-dc-fetchwarp9
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  fsl,prg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Optional Prefetch Resolve Gasket associated with the Fetch Unit.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    fetchlayer at 56180ac0 {
+        compatible = "fsl,imx8qxp-dc-fetchlayer0";
+        reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter9.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter9.yaml
new file mode 100644
index 000000000000..fbdac4526b7b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-filter9.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-filter9.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Filter Unit
+
+description: |
+  5x5 FIR filter with 25 programmable coefficients.
+
+  Typical applications are image blurring, sharpening or support for edge
+  detection algorithms.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-filter9
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    filter at 56180900 {
+        compatible = "fsl,imx8qxp-dc-filter9";
+        reg = <0x56180900 0x10>, <0x56183800 0x30>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen0.yaml
new file mode 100644
index 000000000000..72e88bbffb17
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen0.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-framegen0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Frame Generator
+
+description:
+  The Frame Generator (FrameGen) module generates a programmable video timing
+  and optionally allows to synchronize the generated video timing to external
+  synchronization signals.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-framegen0
+      - fsl,imx8qxp-dc-framegen1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 8
+
+  interrupt-names:
+    items:
+      - const: int0
+      - const: int1
+      - const: int2
+      - const: int3
+      - const: primsync_on
+      - const: primsync_off
+      - const: secsync_on
+      - const: secsync_off
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    framegen at 5618b800 {
+        compatible = "fsl,imx8qxp-dc-framegen0";
+        reg = <0x5618b800 0x98>;
+        clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <18>, <19>, <20>, <21>, <41>, <42>, <43>, <44>;
+        interrupt-names = "int0", "int1", "int2", "int3",
+                          "primsync_on", "primsync_off",
+                          "secsync_on", "secsync_off";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor0.yaml
new file mode 100644
index 000000000000..0eab18192966
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-gammacor0.yaml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-gammacor0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Gamma Correction Unit
+
+description: The unit supports non-linear color transformation.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-gammacor0
+      - fsl,imx8qxp-dc-gammacor1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    gammacor at 5618c000 {
+        compatible = "fsl,imx8qxp-dc-gammacor0";
+        reg = <0x5618c000 0x20>;
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend0.yaml
new file mode 100644
index 000000000000..228cd0a9e9f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend0.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-layerblend0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Layer Blend Unit
+
+description: Combines two input frames to a single output frame.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-layerblend0
+      - fsl,imx8qxp-dc-layerblend1
+      - fsl,imx8qxp-dc-layerblend2
+      - fsl,imx8qxp-dc-layerblend3
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    layerblend at 56180ba0 {
+        compatible = "fsl,imx8qxp-dc-layerblend0";
+        reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix0.yaml
new file mode 100644
index 000000000000..fe2a77b518f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-matrix0.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-matrix0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Color Matrix
+
+description:
+  The unit supports linear color transformation, alpha pre-multiply and
+  alpha masking.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-matrix0
+      - fsl,imx8qxp-dc-matrix1
+      - fsl,imx8qxp-dc-matrix4
+      - fsl,imx8qxp-dc-matrix5
+      - fsl,imx8qxp-dc-matrix9
+
+  reg:
+    minItems: 1
+    maxItems: 2
+
+  reg-names:
+    oneOf:
+      - const: cfg      # matrix in display engine
+      - items:          # matrix in pixel engine
+          - const: pec
+          - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx8qxp-dc-matrix0
+              - fsl,imx8qxp-dc-matrix1
+    then:
+      properties:
+        reg:
+          minItems: 1
+          maxItems: 1
+
+        reg-names:
+          const: cfg
+    else:
+      properties:
+        reg:
+          minItems: 2
+          maxItems: 2
+
+        reg-names:
+          items:
+            - const: pec
+            - const: cfg
+
+additionalProperties: false
+
+examples:
+  - |
+    matrix at 5618bc00 {
+        compatible = "fsl,imx8qxp-dc-matrix0";
+        reg = <0x5618bc00 0x3c>;
+        reg-names = "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop9.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop9.yaml
new file mode 100644
index 000000000000..371bff3aaede
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-rop9.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-rop9.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Raster Operation Unit
+
+description: |
+  The unit can combine up to three input frames to a single output frame, all
+  having the same dimension.
+
+  The unit supports logic operations, arithmetic operations and packing.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-rop9
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    rop at 56180860 {
+        compatible = "fsl,imx8qxp-dc-rop9";
+        reg = <0x56180860 0x10>, <0x56182000 0x20>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
new file mode 100644
index 000000000000..66c12948ab09
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-safety.yaml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-safety.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Safety Unit
+
+description:
+  The unit allows corresponding processing units to be configured in a path
+  leading to multiple endpoints.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-safety
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    safety at 56180800 {
+        compatible = "fsl,imx8qxp-dc-safety";
+        reg = <0x56180800 0x1c>;
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
new file mode 100644
index 000000000000..f9cd25488584
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Scaling Engine
+
+description: |
+  The unit can change the dimension of the input frame by nearest or linear
+  re-sampling with 1/32 sub pixel precision.
+
+  Internally it consist of two independent blocks for horizontal and vertical
+  scaling. The sequence of both operations is arbitrary.
+
+  Any frame dimensions between 1 and 16384 pixels in width and height are
+  supported, except that the vertical scaler has a frame width maximum
+  depending of the system's functional limitations.
+
+  In general all scale factors are supported inside the supported frame
+  dimensions. In range of scale factors 1/16..16 the filtered output colors
+  are LSBit precise (e.g. DC ripple free).
+
+                       +-----------+
+                       |   Line    |
+                       |  Buffer   |
+                       +-----------+
+                             ^
+                             |
+                             V
+                 |\    +-----------+
+           ------+ |   |           |
+          |      | +-->| Vertical  |----
+          |  ----+ |   |  Scaler   |    |
+          | |    |/    +-----------+    |
+          | |                           |
+          | |                           |
+          | |                           |     |\
+          |  ------------- -------------+-----+ |
+  Input --+               X                   | +--> Output
+          |  ------------- -------------+-----+ |
+          | |                           |     |/
+          | |                           |
+          | |    |\    +-----------+    |
+          |  ----+ |   |           |    |
+          |      | +-->| Horizontal|----
+           ------+ |   |  Scaler   |
+                 |/    +-----------+
+
+  The unit supports downscaling, upscaling, sub pixel translation and bob
+  de-interlacing.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-hscaler4
+      - fsl,imx8qxp-dc-hscaler5
+      - fsl,imx8qxp-dc-hscaler9
+      - fsl,imx8qxp-dc-vscaler4
+      - fsl,imx8qxp-dc-vscaler5
+      - fsl,imx8qxp-dc-vscaler9
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    hscaler at 561808c0 {
+        compatible = "fsl,imx8qxp-dc-hscaler9";
+        reg = <0x561808c0 0x10>, <0x56183000 0x18>;
+        reg-names = "pec", "cfg";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature0.yaml
new file mode 100644
index 000000000000..5add40dd7edd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-signature0.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/imx/fsl,imx8qxp-dc-signature0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Signature Unit
+
+description: |
+  In order to control the correctness of display output, signature values can
+  be computed for each frame and compared against reference values. In case of
+  a mismatch (signature violation) a HW event can be triggered, for example a
+  SW interrupt.
+
+  This unit supports signature computation, reference check, evaluation windows,
+  alpha masking and panic modes.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-signature0
+      - fsl,imx8qxp-dc-signature1
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: valid
+      - const: error
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    signature at 5618d000 {
+        compatible = "fsl,imx8qxp-dc-signature0";
+        reg = <0x5618d000 0x140>;
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <22>, <23>, <24>;
+        interrupt-names = "shdload", "valid", "error";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store9.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store9.yaml
new file mode 100644
index 000000000000..3228b5206f0f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-store9.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-store9.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Store Unit
+
+description: |
+  The Store unit is the interface between the internal pixel processing
+  pipeline, which is 30-bit RGB plus 8-bit Alpha, and the AXI bus for
+  destination buffer access. It is used for the destination of Blit Engines.
+  It comprises a set of built-in functions to generate a wide range of buffer
+  formats. Note, that these are exactly inverse to corresponding functions in
+  the Fetch Unit.
+
+  +------X-------------------------+
+  |      |              Store Unit |
+  |      V                         |
+  |  +-------+                     |
+  |  | Gamma | Gamma apply         |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Color | RGB to YUV          |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Chroma| YUV444 to 422       |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Reduce| Bit width reduction |
+  |  |       | dithering           |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  |  +-------+                     |
+  |  | Pack  | RGBA/YUV to RAW     |
+  |  | Encode| or Compression      |
+  |  +-------+                     |
+  |      |                         |
+  |      V                         |
+  +------X-------------------------+
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-store9
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pec
+      - const: cfg
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: framecomplete
+      - const: seqcomplete
+
+  fsl,lts:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Optional Linear Tile Store associated with the Store Unit.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    store at 56180940 {
+        compatible = "fsl,imx8qxp-dc-store9";
+        reg = <0x56180940 0x1c>, <0x56184000 0x5c>;
+        reg-names = "pec", "cfg";
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <0>, <1>, <2>;
+        interrupt-names = "shdload", "framecomplete", "seqcomplete";
+    };
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon0.yaml
new file mode 100644
index 000000000000..fc771c067f74
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon0.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-tcon0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Timing Controller
+
+description:
+  The TCon can generate a wide range of customized synchronization signals and
+  does the mapping of the color bits to the output.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-tcon0
+      - fsl,imx8qxp-dc-tcon1
+
+  reg:
+    maxItems: 1
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description: video output
+
+required:
+  - compatible
+  - reg
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    tcon at 5618c800 {
+        compatible = "fsl,imx8qxp-dc-tcon0";
+        reg = <0x5618c800 0x588>;
+
+        port {
+            dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
+                remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
+            };
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:31 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:31 +0800
Subject: [PATCH v7 03/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller display engine
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-4-victor.liu@nxp.com>

i.MX8qxp Display Controller display engine consists of all processing units
that operate in a display clock domain.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Drop DT alias documentations and add instance numbers to compatible strings.
  (Rob)

v6:
* No change.

v5:
* Document aliases.  Drop Rob's previous R-b tag. (Maxime)

v4:
* Collect Rob's R-b tag.

v3:
* No change.

v2:
* Drop fsl,dc-*-id DT properties. (Krzysztof)
* Drop port property. (Krzysztof)
* Fix register range sizes in example.

 .../imx/fsl,imx8qxp-dc-display-engine0.yaml   | 235 ++++++++++++++++++
 1 file changed, 235 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine0.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine0.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine0.yaml
new file mode 100644
index 000000000000..60d1e0a4a5dd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine0.yaml
@@ -0,0 +1,235 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-display-engine0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Display Engine
+
+description:
+  All Processing Units that operate in a display clock domain. Pixel pipeline
+  is driven by a video timing and cannot be stalled. Implements all display
+  specific processing.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-dc-display-engine0
+      - fsl,imx8qxp-dc-display-engine1
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: top
+      - const: cfg
+
+  resets:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: shdload
+      - const: framecomplete
+      - const: seqcomplete
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^dither@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-dither0
+          - fsl,imx8qxp-dc-dither1
+
+  "^framegen@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-framegen0
+          - fsl,imx8qxp-dc-framegen1
+
+  "^gammacor@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-gammacor0
+          - fsl,imx8qxp-dc-gammacor1
+
+  "^matrix@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-matrix0
+          - fsl,imx8qxp-dc-matrix1
+
+  "^signature@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-signature0
+          - fsl,imx8qxp-dc-signature1
+
+  "^tcon@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-tcon0
+          - fsl,imx8qxp-dc-tcon1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+  - power-domains
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx8qxp-dc-display-engine0
+    then:
+      patternProperties:
+        "^dither@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-dither0
+
+        "^framegen@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-framegen0
+
+        "^gammacor@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-gammacor0
+
+        "^matrix@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-matrix0
+
+        "^signature@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-signature0
+
+        "^tcon@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-tcon0
+    else:
+      patternProperties:
+        "^dither@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-dither1
+
+        "^framegen@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-framegen1
+
+        "^gammacor@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-gammacor1
+
+        "^matrix@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-matrix1
+
+        "^signature@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-signature1
+
+        "^tcon@[0-9a-f]+$":
+          properties:
+            compatible:
+              const: fsl,imx8qxp-dc-tcon1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    display-engine at 5618b400 {
+        compatible = "fsl,imx8qxp-dc-display-engine0";
+        reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
+        reg-names = "top", "cfg";
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <15>, <16>, <17>;
+        interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        framegen at 5618b800 {
+            compatible = "fsl,imx8qxp-dc-framegen0";
+            reg = <0x5618b800 0x98>;
+            clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <18>, <19>, <20>, <21>, <41>, <42>, <43>, <44>;
+            interrupt-names = "int0", "int1", "int2", "int3",
+                              "primsync_on", "primsync_off",
+                              "secsync_on", "secsync_off";
+        };
+
+        tcon at 5618c800 {
+            compatible = "fsl,imx8qxp-dc-tcon0";
+            reg = <0x5618c800 0x588>;
+
+            port {
+                dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
+                    remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
+                };
+            };
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:44 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:44 +0800
Subject: [DO NOT MERGE PATCH v7 16/19] arm64: dts: imx8qxp: Add display controller subsystem
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-17-victor.liu@nxp.com>

Add display controller subsystem in i.MX8qxp SoC.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Add instance numbers to display controller internel devices' compatible
  strings.
* Drop aliases.

v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Krzysztof)

 .../arm64/boot/dts/freescale/imx8-ss-dc0.dtsi | 408 ++++++++++++++++++
 .../boot/dts/freescale/imx8qxp-ss-dc.dtsi     | 236 ++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   4 +-
 3 files changed, 647 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
new file mode 100644
index 000000000000..0db345204b89
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-dc0.dtsi
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+dc0_axi_ext_clk: clock-dc0-axi-ext {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <800000000>;
+	clock-output-names = "dc0_axi_ext_clk";
+};
+
+dc0_axi_int_clk: clock-dc0-axi-int {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <400000000>;
+	clock-output-names = "dc0_axi_int_clk";
+};
+
+dc0_cfg_clk: clock-dc0-cfg {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <100000000>;
+	clock-output-names = "dc0_cfg_clk";
+};
+
+dc0_subsys: bus at 56000000 {
+	compatible = "simple-bus";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0x56000000 0x0 0x56000000 0x1000000>;
+
+	dc0_irqsteer: interrupt-controller at 56000000 {
+		compatible = "fsl,imx-irqsteer";
+		reg = <0x56000000 0x1000>;
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		#interrupt-cells = <1>;
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&dc0_lis_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+		fsl,channel = <0>;
+		fsl,num-irqs = <512>;
+	};
+
+	dc0_disp_lpcg: clock-controller at 56010000 {
+		reg = <0x56010000 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_DC_0 IMX_SC_PM_CLK_MISC0>,
+			 <&clk IMX_SC_R_DC_0 IMX_SC_PM_CLK_MISC1>;
+		clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>;
+		clock-output-names = "dc0_disp0_lpcg_clk", "dc0_disp1_lpcg_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_lis_lpcg: clock-controller at 56010004 {
+		reg = <0x56010004 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "dc0_lis_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_disp_ctrl_link_mst0_lpcg: clock-controller at 56010008 {
+		reg = <0x56010008 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "dc0_disp_ctrl_link_mst0_lpcg_msi_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_pixel_combiner_lpcg: clock-controller at 56010010 {
+		reg = <0x56010010 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "dc0_pixel_combiner_lpcg_apb_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_lpcg: clock-controller at 56010014 {
+		reg = <0x56010014 0x4>;
+		#clock-cells = <1>;
+		clocks = <&dc0_cfg_clk>, <&dc0_axi_int_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_5>;
+		clock-output-names = "dc0_lpcg_cfg_clk",
+				     "dc0_lpcg_axi_clk";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+
+	dc0_pc: pixel-combiner at 56020000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x56020000 0x10000>;
+		clocks = <&dc0_pixel_combiner_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "apb";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+		status = "disabled";
+
+		channel at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			status = "disabled";
+
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_combiner_ch0_dc0_disp0: endpoint {
+					remote-endpoint = <&dc0_disp0_dc0_pixel_combiner_ch0>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				dc0_pixel_combiner_ch0_dc0_pixel_link0: endpoint {
+					remote-endpoint = <&dc0_pixel_link0_dc0_pixel_combiner_ch0>;
+				};
+			};
+		};
+
+		channel at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			status = "disabled";
+
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_combiner_ch1_dc0_disp1: endpoint {
+					remote-endpoint = <&dc0_disp1_dc0_pixel_combiner_ch1>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				dc0_pixel_combiner_ch1_dc0_pixel_link1: endpoint {
+					remote-endpoint = <&dc0_pixel_link1_dc0_pixel_combiner_ch1>;
+				};
+			};
+		};
+	};
+
+	dc0: display-controller at 56180000 {
+		reg = <0x56180000 0x40000>;
+		clocks = <&dc0_lpcg IMX_LPCG_CLK_4>;
+		power-domains = <&pd IMX_SC_R_DC_0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		status = "disabled";
+
+		dc0_intc: interrupt-controller at 56180040 {
+			reg = <0x56180040 0x60>;
+			clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+			interrupt-controller;
+			interrupt-parent = <&dc0_irqsteer>;
+			#interrupt-cells = <1>;
+			interrupts = <448>, <449>, <450>,  <64>,
+				      <65>,  <66>,  <67>,  <68>,
+				      <69>,  <70>, <193>, <194>,
+				     <195>, <196>, <197>,  <72>,
+				      <73>,  <74>,  <75>,  <76>,
+				      <77>,  <78>,  <79>,  <80>,
+				      <81>, <199>, <200>, <201>,
+				     <202>, <203>, <204>, <205>,
+				     <206>, <207>, <208>,   <5>,
+				       <0>,   <1>,   <2>,   <3>,
+				       <4>,  <82>,  <83>,  <84>,
+				      <85>, <209>, <210>, <211>,
+				     <212>;
+			interrupt-names = "store9_shdload",
+					  "store9_framecomplete",
+					  "store9_seqcomplete",
+					  "extdst0_shdload",
+					  "extdst0_framecomplete",
+					  "extdst0_seqcomplete",
+					  "extdst4_shdload",
+					  "extdst4_framecomplete",
+					  "extdst4_seqcomplete",
+					  "extdst1_shdload",
+					  "extdst1_framecomplete",
+					  "extdst1_seqcomplete",
+					  "extdst5_shdload",
+					  "extdst5_framecomplete",
+					  "extdst5_seqcomplete",
+					  "disengcfg_shdload0",
+					  "disengcfg_framecomplete0",
+					  "disengcfg_seqcomplete0",
+					  "framegen0_int0",
+					  "framegen0_int1",
+					  "framegen0_int2",
+					  "framegen0_int3",
+					  "sig0_shdload",
+					  "sig0_valid",
+					  "sig0_error",
+					  "disengcfg_shdload1",
+					  "disengcfg_framecomplete1",
+					  "disengcfg_seqcomplete1",
+					  "framegen1_int0",
+					  "framegen1_int1",
+					  "framegen1_int2",
+					  "framegen1_int3",
+					  "sig1_shdload",
+					  "sig1_valid",
+					  "sig1_error",
+					  "reserved",
+					  "cmdseq_error",
+					  "comctrl_sw0",
+					  "comctrl_sw1",
+					  "comctrl_sw2",
+					  "comctrl_sw3",
+					  "framegen0_primsync_on",
+					  "framegen0_primsync_off",
+					  "framegen0_secsync_on",
+					  "framegen0_secsync_off",
+					  "framegen1_primsync_on",
+					  "framegen1_primsync_off",
+					  "framegen1_secsync_on",
+					  "framegen1_secsync_off";
+		};
+
+		dc0_pixel_engine: pixel-engine at 56180800 {
+			reg = <0x56180800 0xac00>;
+			clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			dc0_constframe0: constframe at 56180960 {
+				reg = <0x56180960 0xc>, <0x56184400 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst0: extdst at 56180980 {
+				reg = <0x56180980 0x1c>, <0x56184800 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <3>, <4>, <5>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_constframe4: constframe at 561809a0 {
+				reg = <0x561809a0 0xc>, <0x56184c00 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst4: extdst at 561809c0 {
+				reg = <0x561809c0 0x1c>, <0x56185000 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <6>, <7>, <8>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_constframe1: constframe at 561809e0 {
+				reg = <0x561809e0 0xc>, <0x56185400 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst1: extdst at 56180a00 {
+				reg = <0x56180a00 0x1c>, <0x56185800 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <9>, <10>, <11>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_constframe5: constframe at 56180a20 {
+				reg = <0x56180a20 0xc>, <0x56185c00 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_extdst5: extdst at 56180a40 {
+				reg = <0x56180a40 0x1c>, <0x56186000 0x28>;
+				reg-names = "pec", "cfg";
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <12>, <13>, <14>;
+				interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			};
+
+			dc0_fetchwarp2: fetchwarp at 56180a60 {
+				reg = <0x56180a60 0x10>, <0x56186400 0x190>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_fetchlayer0: fetchlayer at 56180ac0 {
+				reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend0: layerblend at 56180ba0 {
+				reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend1: layerblend at 56180bc0 {
+				reg = <0x56180bc0 0x10>, <0x5618a800 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend2: layerblend at 56180be0 {
+				reg = <0x56180be0 0x10>, <0x5618ac00 0x20>;
+				reg-names = "pec", "cfg";
+			};
+
+			dc0_layerblend3: layerblend at 56180c00 {
+				reg = <0x56180c00 0x10>, <0x5618b000 0x20>;
+				reg-names = "pec", "cfg";
+			};
+		};
+
+		dc0_display_engine0: display-engine at 5618b400 {
+			reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
+			reg-names = "top", "cfg";
+			interrupt-parent = <&dc0_intc>;
+			interrupts = <15>, <16>, <17>;
+			interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			dc0_framegen0: framegen at 5618b800 {
+				reg = <0x5618b800 0x98>;
+				clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <18>, <19>, <20>, <21>,
+					     <41>, <42>, <43>, <44>;
+				interrupt-names = "int0", "int1", "int2", "int3",
+						  "primsync_on", "primsync_off",
+						  "secsync_on", "secsync_off";
+			};
+
+			dc0_tcon0: tcon at 5618c800 {
+				reg = <0x5618c800 0x588>;
+
+				port {
+					dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
+						remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
+					};
+				};
+			};
+		};
+
+		dc0_display_engine1: display-engine at 5618b420 {
+			reg = <0x5618b420 0x14>, <0x5618d400 0x1c00>;
+			reg-names = "top", "cfg";
+			interrupt-parent = <&dc0_intc>;
+			interrupts = <25>, <26>, <27>;
+			interrupt-names = "shdload", "framecomplete", "seqcomplete";
+			power-domains = <&pd IMX_SC_R_DC_0_PLL_1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			dc0_framegen1: framegen at 5618d400 {
+				reg = <0x5618d400 0x98>;
+				clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_1>;
+				interrupt-parent = <&dc0_intc>;
+				interrupts = <28>, <29>, <30>, <31>,
+					     <45>, <46>, <47>, <48>;
+				interrupt-names = "int0", "int1", "int2", "int3",
+						  "primsync_on", "primsync_off",
+						  "secsync_on", "secsync_off";
+			};
+
+			dc0_tcon1: tcon at 5618e400 {
+				reg = <0x5618e400 0x588>;
+
+				port {
+					dc0_disp1_dc0_pixel_combiner_ch1: endpoint {
+						remote-endpoint = <&dc0_pixel_combiner_ch1_dc0_disp1>;
+					};
+				};
+			};
+		};
+	};
+
+	dc0_pl_msi_bus: bus at 56200000 {
+		reg = <0x56200000 0x100000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&dc0_irqsteer>;
+		interrupts = <320>;
+		ranges;
+		clocks = <&dc0_disp_ctrl_link_mst0_lpcg IMX_LPCG_CLK_4>,
+			 <&dc0_disp_ctrl_link_mst0_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "msi", "ahb";
+		power-domains = <&pd IMX_SC_R_DC_0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
new file mode 100644
index 000000000000..ab84ae3198c8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+&dc0 {
+	compatible = "fsl,imx8qxp-dc";
+};
+
+&dc0_constframe0 {
+	compatible = "fsl,imx8qxp-dc-constframe0";
+};
+
+&dc0_constframe1 {
+	compatible = "fsl,imx8qxp-dc-constframe1";
+};
+
+&dc0_constframe4 {
+	compatible = "fsl,imx8qxp-dc-constframe4";
+};
+
+&dc0_constframe5 {
+	compatible = "fsl,imx8qxp-dc-constframe5";
+};
+
+&dc0_disp_ctrl_link_mst0_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_disp_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_display_engine0 {
+	compatible = "fsl,imx8qxp-dc-display-engine0";
+};
+
+&dc0_display_engine1 {
+	compatible = "fsl,imx8qxp-dc-display-engine1";
+};
+
+&dc0_extdst0 {
+	compatible = "fsl,imx8qxp-dc-extdst0";
+};
+
+&dc0_extdst1 {
+	compatible = "fsl,imx8qxp-dc-extdst1";
+};
+
+&dc0_extdst4 {
+	compatible = "fsl,imx8qxp-dc-extdst4";
+};
+
+&dc0_extdst5 {
+	compatible = "fsl,imx8qxp-dc-extdst5";
+};
+
+&dc0_fetchlayer0 {
+	compatible = "fsl,imx8qxp-dc-fetchlayer0";
+};
+
+&dc0_fetchwarp2 {
+	compatible = "fsl,imx8qxp-dc-fetchwarp2";
+};
+
+&dc0_framegen0 {
+	compatible = "fsl,imx8qxp-dc-framegen0";
+};
+
+&dc0_framegen1 {
+	compatible = "fsl,imx8qxp-dc-framegen1";
+};
+
+&dc0_intc {
+	compatible = "fsl,imx8qxp-dc-intc";
+};
+
+&dc0_layerblend0 {
+	compatible = "fsl,imx8qxp-dc-layerblend0";
+};
+
+&dc0_layerblend1 {
+	compatible = "fsl,imx8qxp-dc-layerblend1";
+};
+
+&dc0_layerblend2 {
+	compatible = "fsl,imx8qxp-dc-layerblend2";
+};
+
+&dc0_layerblend3 {
+	compatible = "fsl,imx8qxp-dc-layerblend3";
+};
+
+&dc0_lis_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_pc {
+	compatible = "fsl,imx8qxp-pixel-combiner";
+};
+
+&dc0_pixel_combiner_lpcg {
+	compatible = "fsl,imx8qxp-lpcg";
+};
+
+&dc0_pixel_engine {
+	compatible = "fsl,imx8qxp-dc-pixel-engine";
+};
+
+&dc0_pl_msi_bus {
+	compatible = "fsl,imx8qxp-display-pixel-link-msi-bus", "simple-pm-bus";
+};
+
+&dc0_tcon0 {
+	compatible = "fsl,imx8qxp-dc-tcon0";
+};
+
+&dc0_tcon1 {
+	compatible = "fsl,imx8qxp-dc-tcon1";
+};
+
+&scu {
+	dc0_pixel_link0: dc0-pixel-link0 {
+		compatible = "fsl,imx8qxp-dc-pixel-link";
+		fsl,dc-id = /bits/ 8 <0>;
+		fsl,dc-stream-id = /bits/ 8 <0>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* from dc0 pixel combiner channel0 */
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_link0_dc0_pixel_combiner_ch0: endpoint {
+					remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_pixel_link0>;
+				};
+			};
+
+			/* to PXL2DPIs in MIPI/LVDS combo subsystems */
+			port at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				status = "disabled";
+
+				dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint at 0 {
+					reg = <0>;
+				};
+
+				dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint at 1 {
+					reg = <1>;
+				};
+			};
+
+			/* unused */
+			port at 2 {
+				reg = <2>;
+				status = "disabled";
+			};
+
+			/* unused */
+			port at 3 {
+				reg = <3>;
+				status = "disabled";
+			};
+
+			/* to imaging subsystem */
+			port at 4 {
+				reg = <4>;
+				status = "disabled";
+			};
+		};
+	};
+
+	dc0_pixel_link1: dc0-pixel-link1 {
+		compatible = "fsl,imx8qxp-dc-pixel-link";
+		fsl,dc-id = /bits/ 8 <0>;
+		fsl,dc-stream-id = /bits/ 8 <1>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* from dc0 pixel combiner channel1 */
+			port at 0 {
+				reg = <0>;
+
+				dc0_pixel_link1_dc0_pixel_combiner_ch1: endpoint {
+					remote-endpoint = <&dc0_pixel_combiner_ch1_dc0_pixel_link1>;
+				};
+			};
+
+			/* to PXL2DPIs in MIPI/LVDS combo subsystems */
+			port at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				status = "disabled";
+
+				dc0_pixel_link1_mipi_lvds_1_pxl2dpi: endpoint at 0 {
+					reg = <0>;
+				};
+
+				dc0_pixel_link1_mipi_lvds_0_pxl2dpi: endpoint at 1 {
+					reg = <1>;
+				};
+			};
+
+			/* to parallel display interface in ADMA subsystem */
+			port at 2 {
+				reg = <2>;
+				status = "disabled";
+			};
+
+			/* unused */
+			port at 3 {
+				reg = <3>;
+				status = "disabled";
+			};
+
+			/* unused */
+			port at 4 {
+				reg = <4>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 05138326f0a5..9fb4bac708a0 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -206,7 +206,7 @@ psci {
 		method = "smc";
 	};
 
-	system-controller {
+	scu: system-controller {
 		compatible = "fsl,imx-scu";
 		mbox-names = "tx0",
 			     "rx0",
@@ -323,6 +323,7 @@ map0 {
 	#include "imx8-ss-vpu.dtsi"
 	#include "imx8-ss-cm40.dtsi"
 	#include "imx8-ss-gpu0.dtsi"
+	#include "imx8-ss-dc0.dtsi"
 	#include "imx8-ss-adma.dtsi"
 	#include "imx8-ss-conn.dtsi"
 	#include "imx8-ss-ddr.dtsi"
@@ -332,6 +333,7 @@ map0 {
 
 #include "imx8qxp-ss-img.dtsi"
 #include "imx8qxp-ss-vpu.dtsi"
+#include "imx8qxp-ss-dc.dtsi"
 #include "imx8qxp-ss-adma.dtsi"
 #include "imx8qxp-ss-conn.dtsi"
 #include "imx8qxp-ss-lsio.dtsi"
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:32 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:32 +0800
Subject: [PATCH v7 04/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller pixel engine
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-5-victor.liu@nxp.com>

i.MX8qxp Display Controller pixel engine consists of all processing units
that operate in the AXI bus clock domain.  Command sequencer and interrupt
controller of the Display Controller work with AXI bus clock, but they are
not in pixel engine.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Add instance numbers to pixel engine internel devices' compatible strings.
  (Rob)
* Drop some Rob's R-b tag.

v6:
* No change.

v5:
* No change.

v4:
* Collect Rob's R-b tag.

v3:
* No change.

v2:
* Drop fsl,dc-*-id DT properties from example. (Krzysztof)
* Fix register range sizes in example.

 .../imx/fsl,imx8qxp-dc-pixel-engine.yaml      | 273 ++++++++++++++++++
 1 file changed, 273 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
new file mode 100644
index 000000000000..668c9c9eccb5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
@@ -0,0 +1,273 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Pixel Engine
+
+description:
+  All Processing Units that operate in the AXI bus clock domain. Pixel
+  pipelines have the ability to stall when a destination is busy. Implements
+  all communication to memory resources and most of the image processing
+  functions. Interconnection of Processing Units is re-configurable.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-pixel-engine
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^blit-engine@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-blit-engine
+
+  "^constframe@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-constframe0
+          - fsl,imx8qxp-dc-constframe1
+          - fsl,imx8qxp-dc-constframe4
+          - fsl,imx8qxp-dc-constframe5
+
+  "^extdst@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-extdst0
+          - fsl,imx8qxp-dc-extdst1
+          - fsl,imx8qxp-dc-extdst4
+          - fsl,imx8qxp-dc-extdst5
+
+  "^fetchdecode@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-fetchdecode0
+          - fsl,imx8qxp-dc-fetchdecode1
+
+  "^fetcheco@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-fetcheco0
+          - fsl,imx8qxp-dc-fetcheco1
+          - fsl,imx8qxp-dc-fetcheco2
+
+  "^fetchlayer@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchlayer0
+
+  "^fetchwarp@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-fetchwarp2
+
+  "^hscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-hscaler4
+          - fsl,imx8qxp-dc-hscaler5
+
+  "^layerblend@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-layerblend0
+          - fsl,imx8qxp-dc-layerblend1
+          - fsl,imx8qxp-dc-layerblend2
+          - fsl,imx8qxp-dc-layerblend3
+
+  "^matrix@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-matrix4
+          - fsl,imx8qxp-dc-matrix5
+
+  "^safety@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-safety
+
+  "^vscaler@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-vscaler4
+          - fsl,imx8qxp-dc-vscaler5
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    pixel-engine at 56180800 {
+        compatible = "fsl,imx8qxp-dc-pixel-engine";
+        reg = <0x56180800 0xac00>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        constframe at 56180960 {
+            compatible = "fsl,imx8qxp-dc-constframe0";
+            reg = <0x56180960 0xc>, <0x56184400 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 56180980 {
+            compatible = "fsl,imx8qxp-dc-extdst0";
+            reg = <0x56180980 0x1c>, <0x56184800 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <3>, <4>, <5>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        constframe at 561809a0 {
+            compatible = "fsl,imx8qxp-dc-constframe4";
+            reg = <0x561809a0 0xc>, <0x56184c00 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 561809c0 {
+            compatible = "fsl,imx8qxp-dc-extdst4";
+            reg = <0x561809c0 0x1c>, <0x56185000 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <6>, <7>, <8>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        constframe at 561809e0 {
+            compatible = "fsl,imx8qxp-dc-constframe1";
+            reg = <0x561809e0 0xc>, <0x56185400 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 56180a00 {
+            compatible = "fsl,imx8qxp-dc-extdst1";
+            reg = <0x56180a00 0x1c>, <0x56185800 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <9>, <10>, <11>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        constframe at 56180a20 {
+            compatible = "fsl,imx8qxp-dc-constframe5";
+            reg = <0x56180a20 0xc>, <0x56185c00 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        extdst at 56180a40 {
+            compatible = "fsl,imx8qxp-dc-extdst5";
+            reg = <0x56180a40 0x1c>, <0x56186000 0x28>;
+            reg-names = "pec", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <12>, <13>, <14>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+        };
+
+        fetchwarp at 56180a60 {
+            compatible = "fsl,imx8qxp-dc-fetchwarp2";
+            reg = <0x56180a60 0x10>, <0x56186400 0x190>;
+            reg-names = "pec", "cfg";
+        };
+
+        fetchlayer at 56180ac0 {
+            compatible = "fsl,imx8qxp-dc-fetchlayer0";
+            reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180ba0 {
+            compatible = "fsl,imx8qxp-dc-layerblend0";
+            reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180bc0 {
+            compatible = "fsl,imx8qxp-dc-layerblend1";
+            reg = <0x56180bc0 0x10>, <0x5618a800 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180be0 {
+            compatible = "fsl,imx8qxp-dc-layerblend2";
+            reg = <0x56180be0 0x10>, <0x5618ac00 0x20>;
+            reg-names = "pec", "cfg";
+        };
+
+        layerblend at 56180c00 {
+            compatible = "fsl,imx8qxp-dc-layerblend3";
+            reg = <0x56180c00 0x10>, <0x5618b000 0x20>;
+            reg-names = "pec", "cfg";
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:33 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:33 +0800
Subject: [PATCH v7 05/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller AXI performance counter
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-6-victor.liu@nxp.com>

i.MX8qxp Display Controller contains a AXI performance counter which allows
measurement of average bandwidth and latency during operation.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v7:
* No change.

v6:
* No change.

v5:
* No change.

v4:
* Collect Rob's R-b tag.

v3:
* New patch. (Rob)

 ...sl,imx8qxp-dc-axi-performance-counter.yaml | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml
new file mode 100644
index 000000000000..1d6501afc7f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller AXI Performance Counter
+
+description: |
+  Performance counters are provided to allow measurement of average bandwidth
+  and latency during operation. The following features are supported:
+
+  * Manual and timer controlled measurement mode.
+
+  * Measurement counters:
+    - GLOBAL_COUNTER for overall measurement time
+    - BUSY_COUNTER for number of data bus busy cycles
+    - DATA_COUNTER for number of data transfer cycles
+    - TRANSFER_COUNTER for number of transfers
+    - ADDRBUSY_COUNTER for number of address bus busy cycles
+    - LATENCY_COUNTER for average latency
+
+  * Counter overflow detection.
+
+  * Outstanding Transfer Counters (OTC) which are used for latency measurement
+    have to run immediately after reset, but can be disabled by software when
+    there is no need for latency measurement.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-axi-performance-counter
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    pmu at 5618f000 {
+        compatible = "fsl,imx8qxp-dc-axi-performance-counter";
+        reg = <0x5618f000 0x90>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:34 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:34 +0800
Subject: [PATCH v7 06/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller command sequencer
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-7-victor.liu@nxp.com>

i.MX8qxp Display Controller contains a command sequencer is designed to
autonomously process command lists.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* No change.

v6:
* No change.

v5:
* No change.

v4:
* Replace "fsl,iram" property with standard "sram" property. (Rob)

v3:
* New patch. (Rob)

 .../imx/fsl,imx8qxp-dc-command-sequencer.yaml | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml
new file mode 100644
index 000000000000..27118f4c0d28
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller Command Sequencer
+
+description: |
+  The Command Sequencer is designed to autonomously process command lists.
+  By that it can load setups into the DC configuration and synchronize to
+  hardware events.  This releases a system's CPU from workload, because it
+  does not need to wait for certain events.  Also it simplifies SW architecture,
+  because no interrupt handlers are required.  Setups are read via AXI bus,
+  while write access to configuration registers occurs directly via an internal
+  bus.  This saves bandwidth for the AXI interconnect and improves the system
+  architecture in terms of safety aspects.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-command-sequencer
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 5
+
+  interrupt-names:
+    items:
+      - const: error
+      - const: sw0
+      - const: sw1
+      - const: sw2
+      - const: sw3
+
+  sram:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle pointing to the mmio-sram device node
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    command-sequencer at 56180400 {
+        compatible = "fsl,imx8qxp-dc-command-sequencer";
+        reg = <0x56180400 0x1a4>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+        interrupt-parent = <&dc0_intc>;
+        interrupts = <36>, <37>, <38>, <39>, <40>;
+        interrupt-names = "error", "sw0", "sw1", "sw2", "sw3";
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:35 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:35 +0800
Subject: [PATCH v7 07/19] dt-bindings: interrupt-controller: Add i.MX8qxp Display Controller interrupt controller
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-8-victor.liu@nxp.com>

i.MX8qxp Display Controller has a built-in interrupt controller to support
Enable/Status/Preset/Clear interrupt bit.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
---
v7:
* No change.

v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* Collect Rob's R-b tag.

v2:
* Drop unneeded "|". (Krzysztof)

 .../fsl,imx8qxp-dc-intc.yaml                  | 318 ++++++++++++++++++
 1 file changed, 318 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml
new file mode 100644
index 000000000000..6985ee644a25
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,imx8qxp-dc-intc.yaml
@@ -0,0 +1,318 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/fsl,imx8qxp-dc-intc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller interrupt controller
+
+description: |
+  The Display Controller has a built-in interrupt controller with the following
+  features for all relevant HW events:
+
+  * Enable bit (mask)
+  * Status bit (set by an HW event)
+  * Preset bit (can be used by SW to set status)
+  * Clear bit (used by SW to reset the status)
+
+  Each interrupt can be connected as IRQ (maskable) and/or NMI (non-maskable).
+  Alternatively the un-masked trigger signals for all HW events are provided,
+  allowing it to use a global interrupt controller instead.
+
+  Each interrupt can be protected against SW running in user mode. In that case,
+  only privileged AHB access can control the interrupt status.
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc-intc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 1
+
+  interrupts:
+    items:
+      - description: store9 shadow load interrupt(blit engine)
+      - description: store9 frame complete interrupt(blit engine)
+      - description: store9 sequence complete interrupt(blit engine)
+      - description:
+          extdst0 shadow load interrupt
+          (display controller, content stream 0)
+      - description:
+          extdst0 frame complete interrupt
+          (display controller, content stream 0)
+      - description:
+          extdst0 sequence complete interrupt
+          (display controller, content stream 0)
+      - description:
+          extdst4 shadow load interrupt
+          (display controller, safety stream 0)
+      - description:
+          extdst4 frame complete interrupt
+          (display controller, safety stream 0)
+      - description:
+          extdst4 sequence complete interrupt
+          (display controller, safety stream 0)
+      - description:
+          extdst1 shadow load interrupt
+          (display controller, content stream 1)
+      - description:
+          extdst1 frame complete interrupt
+          (display controller, content stream 1)
+      - description:
+          extdst1 sequence complete interrupt
+          (display controller, content stream 1)
+      - description:
+          extdst5 shadow load interrupt
+          (display controller, safety stream 1)
+      - description:
+          extdst5 frame complete interrupt
+          (display controller, safety stream 1)
+      - description:
+          extdst5 sequence complete interrupt
+          (display controller, safety stream 1)
+      - description:
+          disengcfg0 shadow load interrupt
+          (display controller, display stream 0)
+      - description:
+          disengcfg0 frame complete interrupt
+          (display controller, display stream 0)
+      - description:
+          disengcfg0 sequence complete interrupt
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt0
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt1
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt2
+          (display controller, display stream 0)
+      - description:
+          framegen0 programmable interrupt3
+          (display controller, display stream 0)
+      - description:
+          signature0 shadow load interrupt
+          (display controller, display stream 0)
+      - description:
+          signature0 measurement valid interrupt
+          (display controller, display stream 0)
+      - description:
+          signature0 error condition interrupt
+          (display controller, display stream 0)
+      - description:
+          disengcfg1 shadow load interrupt
+          (display controller, display stream 1)
+      - description:
+          disengcfg1 frame complete interrupt
+          (display controller, display stream 1)
+      - description:
+          disengcfg1 sequence complete interrupt
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt0
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt1
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt2
+          (display controller, display stream 1)
+      - description:
+          framegen1 programmable interrupt3
+          (display controller, display stream 1)
+      - description:
+          signature1 shadow load interrupt
+          (display controller, display stream 1)
+      - description:
+          signature1 measurement valid interrupt
+          (display controller, display stream 1)
+      - description:
+          signature1 error condition interrupt
+          (display controller, display stream 1)
+      - description: reserved
+      - description:
+          command sequencer error condition interrupt(command sequencer)
+      - description:
+          common control software interrupt0(common control)
+      - description:
+          common control software interrupt1(common control)
+      - description:
+          common control software interrupt2(common control)
+      - description:
+          common control software interrupt3(common control)
+      - description:
+          framegen0 synchronization status activated interrupt
+          (display controller, safety stream 0)
+      - description:
+          framegen0 synchronization status deactivated interrupt
+          (display controller, safety stream 0)
+      - description:
+          framegen0 synchronization status activated interrupt
+          (display controller, content stream 0)
+      - description:
+          framegen0 synchronization status deactivated interrupt
+          (display controller, content stream 0)
+      - description:
+          framegen1 synchronization status activated interrupt
+          (display controller, safety stream 1)
+      - description:
+          framegen1 synchronization status deactivated interrupt
+          (display controller, safety stream 1)
+      - description:
+          framegen1 synchronization status activated interrupt
+          (display controller, content stream 1)
+      - description:
+          framegen1 synchronization status deactivated interrupt
+          (display controller, content stream 1)
+    minItems: 49
+
+  interrupt-names:
+    items:
+      - const: store9_shdload
+      - const: store9_framecomplete
+      - const: store9_seqcomplete
+      - const: extdst0_shdload
+      - const: extdst0_framecomplete
+      - const: extdst0_seqcomplete
+      - const: extdst4_shdload
+      - const: extdst4_framecomplete
+      - const: extdst4_seqcomplete
+      - const: extdst1_shdload
+      - const: extdst1_framecomplete
+      - const: extdst1_seqcomplete
+      - const: extdst5_shdload
+      - const: extdst5_framecomplete
+      - const: extdst5_seqcomplete
+      - const: disengcfg_shdload0
+      - const: disengcfg_framecomplete0
+      - const: disengcfg_seqcomplete0
+      - const: framegen0_int0
+      - const: framegen0_int1
+      - const: framegen0_int2
+      - const: framegen0_int3
+      - const: sig0_shdload
+      - const: sig0_valid
+      - const: sig0_error
+      - const: disengcfg_shdload1
+      - const: disengcfg_framecomplete1
+      - const: disengcfg_seqcomplete1
+      - const: framegen1_int0
+      - const: framegen1_int1
+      - const: framegen1_int2
+      - const: framegen1_int3
+      - const: sig1_shdload
+      - const: sig1_valid
+      - const: sig1_error
+      - const: reserved
+      - const: cmdseq_error
+      - const: comctrl_sw0
+      - const: comctrl_sw1
+      - const: comctrl_sw2
+      - const: comctrl_sw3
+      - const: framegen0_primsync_on
+      - const: framegen0_primsync_off
+      - const: framegen0_secsync_on
+      - const: framegen0_secsync_off
+      - const: framegen1_primsync_on
+      - const: framegen1_primsync_off
+      - const: framegen1_secsync_on
+      - const: framegen1_secsync_off
+    minItems: 49
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupt-controller
+  - "#interrupt-cells"
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+
+    interrupt-controller at 56180040 {
+        compatible = "fsl,imx8qxp-dc-intc";
+        reg = <0x56180040 0x60>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+        interrupt-controller;
+        interrupt-parent = <&dc0_irqsteer>;
+        #interrupt-cells = <1>;
+        interrupts = <448>, <449>, <450>,  <64>,
+                      <65>,  <66>,  <67>,  <68>,
+                      <69>,  <70>, <193>, <194>,
+                     <195>, <196>, <197>,  <72>,
+                      <73>,  <74>,  <75>,  <76>,
+                      <77>,  <78>,  <79>,  <80>,
+                      <81>, <199>, <200>, <201>,
+                     <202>, <203>, <204>, <205>,
+                     <206>, <207>, <208>,   <5>,
+                       <0>,   <1>,   <2>,   <3>,
+                       <4>,  <82>,  <83>,  <84>,
+                      <85>, <209>, <210>, <211>,
+                     <212>;
+        interrupt-names = "store9_shdload",
+                          "store9_framecomplete",
+                          "store9_seqcomplete",
+                          "extdst0_shdload",
+                          "extdst0_framecomplete",
+                          "extdst0_seqcomplete",
+                          "extdst4_shdload",
+                          "extdst4_framecomplete",
+                          "extdst4_seqcomplete",
+                          "extdst1_shdload",
+                          "extdst1_framecomplete",
+                          "extdst1_seqcomplete",
+                          "extdst5_shdload",
+                          "extdst5_framecomplete",
+                          "extdst5_seqcomplete",
+                          "disengcfg_shdload0",
+                          "disengcfg_framecomplete0",
+                          "disengcfg_seqcomplete0",
+                          "framegen0_int0",
+                          "framegen0_int1",
+                          "framegen0_int2",
+                          "framegen0_int3",
+                          "sig0_shdload",
+                          "sig0_valid",
+                          "sig0_error",
+                          "disengcfg_shdload1",
+                          "disengcfg_framecomplete1",
+                          "disengcfg_seqcomplete1",
+                          "framegen1_int0",
+                          "framegen1_int1",
+                          "framegen1_int2",
+                          "framegen1_int3",
+                          "sig1_shdload",
+                          "sig1_valid",
+                          "sig1_error",
+                          "reserved",
+                          "cmdseq_error",
+                          "comctrl_sw0",
+                          "comctrl_sw1",
+                          "comctrl_sw2",
+                          "comctrl_sw3",
+                          "framegen0_primsync_on",
+                          "framegen0_primsync_off",
+                          "framegen0_secsync_on",
+                          "framegen0_secsync_off",
+                          "framegen1_primsync_on",
+                          "framegen1_primsync_off",
+                          "framegen1_secsync_on",
+                          "framegen1_secsync_off";
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:36 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:36 +0800
Subject: [PATCH v7 08/19] dt-bindings: display: imx: Add i.MX8qxp Display Controller
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-9-victor.liu@nxp.com>

i.MX8qxp Display Controller(DC) is comprised of three main components that
include a blit engine for 2D graphics accelerations, display controller for
display output processing, as well as a command sequencer.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Drop DT alias documentations and add instance numbers to display engine
  compatible strings. (Rob)

v6:
* No change.

v5:
* Document aliases.  Drop Rob's previous R-b tag. (Maxime)

v4:
* Collect Rob's R-b tag.

v3:
* No change.

v2:
* Drop fsl,dc-*-id DT properties from example. (Krzysztof)
* Use generic pmu pattern property. (Krzysztof)

 .../bindings/display/imx/fsl,imx8qxp-dc.yaml  | 238 ++++++++++++++++++
 1 file changed, 238 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
new file mode 100644
index 000000000000..0f49053d148e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
@@ -0,0 +1,238 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8qxp Display Controller
+
+description: |
+  The Freescale i.MX8qxp Display Controller(DC) is comprised of three main
+  components that include a blit engine for 2D graphics accelerations, display
+  controller for display output processing, as well as a command sequencer.
+
+                                  Display buffers              Source buffers
+                                 (AXI read master)            (AXI read master)
+                                  | .......... |                  | | |
+      +---------------------------+------------+------------------+-+-+------+
+      | Display Controller (DC)   | .......... |                  | | |      |
+      |                           |            |                  | | |      |
+      |   @@@@@@@@@@@  +----------+------------+------------+     | | |      |
+  A   |  | Command   | |          V            V            |     | | |      |
+  X <-+->| Sequencer | |    @@@@@@@@@@@@@@@@@@@@@@@@@@@@    |     V V V      |
+  I   |  | (AXI CLK) | |   |                            |   |   @@@@@@@@@@   |
+      |   @@@@@@@@@@@  |   |       Pixel Engine         |   |  |          |  |
+      |       |        |   |         (AXI CLK)          |   |  |          |  |
+      |       V        |    @@@@@@@@@@@@@@@@@@@@@@@@@@@@    |  |          |  |
+  A   |   ***********  |       |   |            |   |       |  |   Blit   |  |
+  H <-+->| Configure | |       V   V            V   V       |  |  Engine  |  |
+  B   |  | (CFG CLK) | |    00000000000      11111111111    |  | (AXI CLK)|  |
+      |   ***********  |   |  Display  |    |  Display  |   |  |          |  |
+      |                |   |  Engine   |    |  Engine   |   |  |          |  |
+      |                |   | (Disp CLK)|    | (Disp CLK)|   |  |          |  |
+      |   @@@@@@@@@@@  |    00000000000      11111111111    |   @@@@@@@@@@   |
+  I   |  |  Common   | |         |                |         |       |        |
+  R <-+--|  Control  | |         |    Display     |         |       |        |
+  Q   |  | (AXI CLK) | |         |   Controller   |         |       |        |
+      |   @@@@@@@@@@@  +------------------------------------+       |        |
+      |                          |                |       ^         |        |
+      +--------------------------+----------------+-------+---------+--------+
+              ^                  |                |       |         |
+              |                  V                V       |         V
+       Clocks & Resets        Display          Display  Panic   Destination
+                              Output0          Output1 Control    buffer
+                                                              (AXI write master)
+
+maintainers:
+  - Liu Ying <victor.liu at nxp.com>
+
+properties:
+  compatible:
+    const: fsl,imx8qxp-dc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: axi
+      - const: cfg
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^command-sequencer@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-command-sequencer
+
+  "^display-engine@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        enum:
+          - fsl,imx8qxp-dc-display-engine0
+          - fsl,imx8qxp-dc-display-engine1
+
+  "^interrupt-controller@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-intc
+
+  "^pixel-engine@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-pixel-engine
+
+  "^pmu@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        const: fsl,imx8qxp-dc-axi-performance-counter
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - power-domains
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8-lpcg.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    display-controller at 56180000 {
+        compatible = "fsl,imx8qxp-dc";
+        reg = <0x56180000 0x40000>;
+        clocks = <&dc0_lpcg IMX_LPCG_CLK_4>;
+        power-domains = <&pd IMX_SC_R_DC_0>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        interrupt-controller at 56180040 {
+            compatible = "fsl,imx8qxp-dc-intc";
+            reg = <0x56180040 0x60>;
+            clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+            interrupt-controller;
+            interrupt-parent = <&dc0_irqsteer>;
+            #interrupt-cells = <1>;
+            interrupts = <448>, <449>, <450>,  <64>,
+                          <65>,  <66>,  <67>,  <68>,
+                          <69>,  <70>, <193>, <194>,
+                         <195>, <196>, <197>,  <72>,
+                          <73>,  <74>,  <75>,  <76>,
+                          <77>,  <78>,  <79>,  <80>,
+                          <81>, <199>, <200>, <201>,
+                         <202>, <203>, <204>, <205>,
+                         <206>, <207>, <208>,   <5>,
+                           <0>,   <1>,   <2>,   <3>,
+                           <4>,  <82>,  <83>,  <84>,
+                          <85>, <209>, <210>, <211>,
+                         <212>;
+            interrupt-names = "store9_shdload",
+                              "store9_framecomplete",
+                              "store9_seqcomplete",
+                              "extdst0_shdload",
+                              "extdst0_framecomplete",
+                              "extdst0_seqcomplete",
+                              "extdst4_shdload",
+                              "extdst4_framecomplete",
+                              "extdst4_seqcomplete",
+                              "extdst1_shdload",
+                              "extdst1_framecomplete",
+                              "extdst1_seqcomplete",
+                              "extdst5_shdload",
+                              "extdst5_framecomplete",
+                              "extdst5_seqcomplete",
+                              "disengcfg_shdload0",
+                              "disengcfg_framecomplete0",
+                              "disengcfg_seqcomplete0",
+                              "framegen0_int0",
+                              "framegen0_int1",
+                              "framegen0_int2",
+                              "framegen0_int3",
+                              "sig0_shdload",
+                              "sig0_valid",
+                              "sig0_error",
+                              "disengcfg_shdload1",
+                              "disengcfg_framecomplete1",
+                              "disengcfg_seqcomplete1",
+                              "framegen1_int0",
+                              "framegen1_int1",
+                              "framegen1_int2",
+                              "framegen1_int3",
+                              "sig1_shdload",
+                              "sig1_valid",
+                              "sig1_error",
+                              "reserved",
+                              "cmdseq_error",
+                              "comctrl_sw0",
+                              "comctrl_sw1",
+                              "comctrl_sw2",
+                              "comctrl_sw3",
+                              "framegen0_primsync_on",
+                              "framegen0_primsync_off",
+                              "framegen0_secsync_on",
+                              "framegen0_secsync_off",
+                              "framegen1_primsync_on",
+                              "framegen1_primsync_off",
+                              "framegen1_secsync_on",
+                              "framegen1_secsync_off";
+        };
+
+        pixel-engine at 56180800 {
+            compatible = "fsl,imx8qxp-dc-pixel-engine";
+            reg = <0x56180800 0xac00>;
+            clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges;
+        };
+
+        display-engine at 5618b400 {
+            compatible = "fsl,imx8qxp-dc-display-engine0";
+            reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
+            reg-names = "top", "cfg";
+            interrupt-parent = <&dc0_intc>;
+            interrupts = <15>, <16>, <17>;
+            interrupt-names = "shdload", "framecomplete", "seqcomplete";
+            power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges;
+        };
+    };
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:37 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:37 +0800
Subject: [PATCH v7 09/19] drm/imx: Add i.MX8qxp Display Controller display engine
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-10-victor.liu@nxp.com>

i.MX8qxp Display Controller display engine consists of all processing
units that operate in a display clock domain.  Add minimal feature
support with FrameGen and TCon so that the engine can output display
timings.  The FrameGen driver, TCon driver and display engine driver
are components to be aggregated by a master registered in the upcoming
DRM driver.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Add kernel doc for struct dc_drm_device. (Dmitry)
* Fix regmap_config definitions by correcting name field, correcting read
  ranges and setting max_register field.
* Get instance numbers from device data(compatible strings) instead of OF
  aliases.
* Collect Maxime's R-b tag.
* Trivial tweaks.

v6:
* No change.

v5:
* Replace .remove_new with .remove in dc-{de,fg,tc}.c. (Uwe)
* Select REGMAP and REGMAP_MMIO Kconfig options.
* Fix commit message to state that display engine driver is a component driver
  instead of a master/aggregate driver.

v4:
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Inline some small functions. (Dmitry)
* Move dc_fg_displaymode() and dc_fg_panic_displaymode() function calls from
  KMS routine to initialization stage. (Dmitry)
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
* Drop unnecessary private struct dc_*_priv.
* Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
  interfaces to bind/unbind the drivers.

v3:
* No change.

v2:
* Use OF alias id to get instance id.
* Add dev member to struct dc_tc.

 drivers/gpu/drm/imx/Kconfig     |   1 +
 drivers/gpu/drm/imx/Makefile    |   1 +
 drivers/gpu/drm/imx/dc/Kconfig  |   7 +
 drivers/gpu/drm/imx/dc/Makefile |   5 +
 drivers/gpu/drm/imx/dc/dc-de.c  | 153 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-de.h  |  62 ++++++
 drivers/gpu/drm/imx/dc/dc-drv.c |  32 +++
 drivers/gpu/drm/imx/dc/dc-drv.h |  29 +++
 drivers/gpu/drm/imx/dc/dc-fg.c  | 378 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-tc.c  | 142 ++++++++++++
 10 files changed, 810 insertions(+)
 create mode 100644 drivers/gpu/drm/imx/dc/Kconfig
 create mode 100644 drivers/gpu/drm/imx/dc/Makefile
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-de.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-drv.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fg.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-tc.c

diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
index 03535a15dd8f..3e8c6edbc17c 100644
--- a/drivers/gpu/drm/imx/Kconfig
+++ b/drivers/gpu/drm/imx/Kconfig
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
+source "drivers/gpu/drm/imx/dc/Kconfig"
 source "drivers/gpu/drm/imx/dcss/Kconfig"
 source "drivers/gpu/drm/imx/ipuv3/Kconfig"
 source "drivers/gpu/drm/imx/lcdc/Kconfig"
diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index 86f38e7c7422..c7b317640d71 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
+obj-$(CONFIG_DRM_IMX8_DC) += dc/
 obj-$(CONFIG_DRM_IMX_DCSS) += dcss/
 obj-$(CONFIG_DRM_IMX) += ipuv3/
 obj-$(CONFIG_DRM_IMX_LCDC) += lcdc/
diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
new file mode 100644
index 000000000000..e1ef76d82830
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -0,0 +1,7 @@
+config DRM_IMX8_DC
+	tristate "Freescale i.MX8 Display Controller Graphics"
+	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
+	select REGMAP
+	select REGMAP_MMIO
+	help
+	  enable Freescale i.MX8 Display Controller(DC) graphics support
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
new file mode 100644
index 000000000000..56de82d53d4d
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+imx8-dc-drm-objs := dc-de.o dc-drv.o dc-fg.o dc-tc.o
+
+obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-de.c b/drivers/gpu/drm/imx/dc/dc-de.c
new file mode 100644
index 000000000000..1eaa7db56a9d
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-de.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+
+#define POLARITYCTRL		0xc
+#define  POLEN_HIGH		BIT(2)
+
+static const struct regmap_range dc_de_regmap_ranges[] = {
+	regmap_reg_range(POLARITYCTRL, POLARITYCTRL),
+};
+
+static const struct regmap_access_table dc_de_regmap_access_table = {
+	.yes_ranges = dc_de_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_de_regmap_ranges),
+};
+
+static const struct regmap_config dc_de_top_regmap_config = {
+	.name = "top",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_de_regmap_access_table,
+	.rd_table = &dc_de_regmap_access_table,
+	.max_register = POLARITYCTRL,
+};
+
+static inline void dc_dec_init(struct dc_de *de)
+{
+	regmap_write_bits(de->reg_top, POLARITYCTRL, POLARITYCTRL, POLEN_HIGH);
+}
+
+static int dc_de_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	void __iomem *base_top;
+	struct dc_de *de;
+	int ret;
+
+	de = devm_kzalloc(dev, sizeof(*de), GFP_KERNEL);
+	if (!de)
+		return -ENOMEM;
+
+	de->id = (enum dc_de_id)(uintptr_t)device_get_match_data(dev);
+
+	base_top = devm_platform_ioremap_resource_byname(pdev, "top");
+	if (IS_ERR(base_top))
+		return PTR_ERR(base_top);
+
+	de->reg_top = devm_regmap_init_mmio(dev, base_top,
+					    &dc_de_top_regmap_config);
+	if (IS_ERR(de->reg_top))
+		return PTR_ERR(de->reg_top);
+
+	de->irq_shdld = platform_get_irq_byname(pdev, "shdload");
+	if (de->irq_shdld < 0)
+		return de->irq_shdld;
+
+	de->irq_framecomplete = platform_get_irq_byname(pdev, "framecomplete");
+	if (de->irq_framecomplete < 0)
+		return de->irq_framecomplete;
+
+	de->irq_seqcomplete = platform_get_irq_byname(pdev, "seqcomplete");
+	if (de->irq_seqcomplete < 0)
+		return de->irq_seqcomplete;
+
+	de->dev = dev;
+
+	dev_set_drvdata(dev, de);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	dc_drm->de[de->id] = de;
+
+	return 0;
+}
+
+static const struct component_ops dc_de_ops = {
+	.bind = dc_de_bind,
+};
+
+static int dc_de_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = component_add(&pdev->dev, &dc_de_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_de_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_de_ops);
+}
+
+static int dc_de_runtime_resume(struct device *dev)
+{
+	struct dc_de *de = dev_get_drvdata(dev);
+
+	dc_dec_init(de);
+	dc_fg_init(de->fg);
+	dc_tc_init(de->tc);
+
+	return 0;
+}
+
+static const struct dev_pm_ops dc_de_pm_ops = {
+	RUNTIME_PM_OPS(NULL, dc_de_runtime_resume, NULL)
+};
+
+static const struct of_device_id dc_de_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-display-engine0",
+	  .data = (const void *)DC_DE0, },
+	{ .compatible = "fsl,imx8qxp-dc-display-engine1",
+	  .data = (const void *)DC_DE1, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_de_dt_ids);
+
+struct platform_driver dc_de_driver = {
+	.probe = dc_de_probe,
+	.remove = dc_de_remove,
+	.driver = {
+		.name = "imx8-dc-display-engine",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_de_dt_ids,
+		.pm = pm_sleep_ptr(&dc_de_pm_ops),
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
new file mode 100644
index 000000000000..b504de5589a5
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_DISPLAY_ENGINE_H__
+#define __DC_DISPLAY_ENGINE_H__
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <drm/drm_modes.h>
+
+#define DC_DISPLAYS	2
+
+enum dc_de_id {
+	DC_DE0,
+	DC_DE1,
+};
+
+struct dc_fg {
+	struct device *dev;
+	struct regmap *reg;
+	struct clk *clk_disp;
+};
+
+struct dc_tc {
+	struct device *dev;
+	struct regmap *reg;
+};
+
+struct dc_de {
+	struct device *dev;
+	struct regmap *reg_top;
+	struct dc_fg *fg;
+	struct dc_tc *tc;
+	int irq_shdld;
+	int irq_framecomplete;
+	int irq_seqcomplete;
+	enum dc_de_id id;
+};
+
+/* Frame Generator Unit */
+void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m);
+void dc_fg_enable(struct dc_fg *fg);
+void dc_fg_disable(struct dc_fg *fg);
+void dc_fg_shdtokgen(struct dc_fg *fg);
+u32 dc_fg_get_frame_index(struct dc_fg *fg);
+u32 dc_fg_get_line_index(struct dc_fg *fg);
+bool dc_fg_wait_for_frame_index_moving(struct dc_fg *fg);
+bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg);
+void dc_fg_secondary_clear_channel_status(struct dc_fg *fg);
+int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg);
+void dc_fg_enable_clock(struct dc_fg *fg);
+void dc_fg_disable_clock(struct dc_fg *fg);
+enum drm_mode_status dc_fg_check_clock(struct dc_fg *fg, int clk_khz);
+void dc_fg_init(struct dc_fg *fg);
+
+/* Timing Controller Unit */
+void dc_tc_init(struct dc_tc *tc);
+
+#endif /* __DC_DISPLAY_ENGINE_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
new file mode 100644
index 000000000000..e5910a82dd4d
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "dc-drv.h"
+
+static struct platform_driver * const dc_drivers[] = {
+	&dc_de_driver,
+	&dc_fg_driver,
+	&dc_tc_driver,
+};
+
+static int __init dc_drm_init(void)
+{
+	return platform_register_drivers(dc_drivers, ARRAY_SIZE(dc_drivers));
+}
+
+static void __exit dc_drm_exit(void)
+{
+	platform_unregister_drivers(dc_drivers, ARRAY_SIZE(dc_drivers));
+}
+
+module_init(dc_drm_init);
+module_exit(dc_drm_exit);
+
+MODULE_DESCRIPTION("i.MX8 Display Controller DRM Driver");
+MODULE_AUTHOR("Liu Ying <victor.liu at nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
new file mode 100644
index 000000000000..23ef715f5cd1
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_DRV_H__
+#define __DC_DRV_H__
+
+#include <linux/platform_device.h>
+
+#include <drm/drm_device.h>
+
+#include "dc-de.h"
+
+/**
+ * struct dc_drm_device - DC specific drm_device
+ */
+struct dc_drm_device {
+	/** @base: base drm_device structure */
+	struct drm_device base;
+	/** @de: display engine list */
+	struct dc_de *de[DC_DISPLAYS];
+};
+
+extern struct platform_driver dc_de_driver;
+extern struct platform_driver dc_fg_driver;
+extern struct platform_driver dc_tc_driver;
+
+#endif /* __DC_DRV_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
new file mode 100644
index 000000000000..b5a0441b2b13
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fg.c
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/units.h>
+
+#include <drm/drm_modes.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+
+#define FGSTCTRL		0x8
+#define  FGSYNCMODE_MASK	GENMASK(2, 1)
+#define  FGSYNCMODE(x)		FIELD_PREP(FGSYNCMODE_MASK, (x))
+#define  SHDEN			BIT(0)
+
+#define HTCFG1			0xc
+#define  HTOTAL(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  HACT(x)		FIELD_PREP(GENMASK(13, 0), (x))
+
+#define HTCFG2			0x10
+#define  HSEN			BIT(31)
+#define  HSBP(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  HSYNC(x)		FIELD_PREP(GENMASK(13, 0), ((x) - 1))
+
+#define VTCFG1			0x14
+#define  VTOTAL(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  VACT(x)		FIELD_PREP(GENMASK(13, 0), (x))
+
+#define VTCFG2			0x18
+#define  VSEN			BIT(31)
+#define  VSBP(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  VSYNC(x)		FIELD_PREP(GENMASK(13, 0), ((x) - 1))
+
+#define PKICKCONFIG		0x2c
+#define SKICKCONFIG		0x30
+#define  EN			BIT(31)
+#define  ROW(x)			FIELD_PREP(GENMASK(29, 16), (x))
+#define  COL(x)			FIELD_PREP(GENMASK(13, 0), (x))
+
+#define PACFG			0x54
+#define SACFG			0x58
+#define  STARTY(x)		FIELD_PREP(GENMASK(29, 16), ((x) + 1))
+#define  STARTX(x)		FIELD_PREP(GENMASK(13, 0), ((x) + 1))
+
+#define FGINCTRL		0x5c
+#define FGINCTRLPANIC		0x60
+#define  FGDM_MASK		GENMASK(2, 0)
+#define  ENPRIMALPHA		BIT(3)
+#define  ENSECALPHA		BIT(4)
+
+#define FGCCR			0x64
+#define  CCGREEN(x)		FIELD_PREP(GENMASK(19, 10), (x))
+
+#define FGENABLE		0x68
+#define  FGEN			BIT(0)
+
+#define FGSLR			0x6c
+#define  SHDTOKGEN		BIT(0)
+
+#define FGTIMESTAMP		0x74
+#define  FRAMEINDEX(x)		FIELD_GET(GENMASK(31, 14), (x))
+#define  LINEINDEX(x)		FIELD_GET(GENMASK(13, 0), (x))
+
+#define FGCHSTAT		0x78
+#define  SECSYNCSTAT		BIT(24)
+#define  SFIFOEMPTY		BIT(16)
+
+#define FGCHSTATCLR		0x7c
+#define  CLRSECSTAT		BIT(16)
+
+enum dc_fg_id {
+	DC_FG0,
+	DC_FG1,
+};
+
+enum dc_fg_syncmode {
+	FG_SYNCMODE_OFF,	/* No side-by-side synchronization. */
+};
+
+enum dc_fg_dm {
+	FG_DM_CONSTCOL = 0x1,	/* Constant Color Background is shown. */
+	FG_DM_SEC_ON_TOP = 0x5,	/* Both inputs overlaid with secondary on top. */
+};
+
+static const struct regmap_range dc_fg_regmap_write_ranges[] = {
+	regmap_reg_range(FGSTCTRL, VTCFG2),
+	regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
+	regmap_reg_range(PACFG, FGSLR),
+	regmap_reg_range(FGCHSTATCLR, FGCHSTATCLR),
+};
+
+static const struct regmap_range dc_fg_regmap_read_ranges[] = {
+	regmap_reg_range(FGSTCTRL, VTCFG2),
+	regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
+	regmap_reg_range(PACFG, FGENABLE),
+	regmap_reg_range(FGTIMESTAMP, FGCHSTAT),
+};
+
+static const struct regmap_access_table dc_fg_regmap_write_table = {
+	.yes_ranges = dc_fg_regmap_write_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_write_ranges),
+};
+
+static const struct regmap_access_table dc_fg_regmap_read_table = {
+	.yes_ranges = dc_fg_regmap_read_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_read_ranges),
+};
+
+static const struct regmap_config dc_fg_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fg_regmap_write_table,
+	.rd_table = &dc_fg_regmap_read_table,
+	.max_register = FGCHSTATCLR,
+};
+
+static inline void dc_fg_enable_shden(struct dc_fg *fg)
+{
+	regmap_write_bits(fg->reg, FGSTCTRL, SHDEN, SHDEN);
+}
+
+static inline void dc_fg_syncmode(struct dc_fg *fg, enum dc_fg_syncmode mode)
+{
+	regmap_write_bits(fg->reg, FGSTCTRL, FGSYNCMODE_MASK, FGSYNCMODE(mode));
+}
+
+void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
+{
+	u32 hact, htotal, hsync, hsbp;
+	u32 vact, vtotal, vsync, vsbp;
+	u32 kick_row, kick_col;
+	int ret;
+
+	hact = m->crtc_hdisplay;
+	htotal = m->crtc_htotal;
+	hsync = m->crtc_hsync_end - m->crtc_hsync_start;
+	hsbp = m->crtc_htotal - m->crtc_hsync_start;
+
+	vact = m->crtc_vdisplay;
+	vtotal = m->crtc_vtotal;
+	vsync = m->crtc_vsync_end - m->crtc_vsync_start;
+	vsbp = m->crtc_vtotal - m->crtc_vsync_start;
+
+	/* video mode */
+	regmap_write(fg->reg, HTCFG1, HACT(hact)   | HTOTAL(htotal));
+	regmap_write(fg->reg, HTCFG2, HSYNC(hsync) | HSBP(hsbp) | HSEN);
+	regmap_write(fg->reg, VTCFG1, VACT(vact)   | VTOTAL(vtotal));
+	regmap_write(fg->reg, VTCFG2, VSYNC(vsync) | VSBP(vsbp) | VSEN);
+
+	kick_col = hact + 1;
+	kick_row = vact;
+
+	/* pkickconfig */
+	regmap_write(fg->reg, PKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
+
+	/* skikconfig */
+	regmap_write(fg->reg, SKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
+
+	/* primary and secondary area position configuration */
+	regmap_write(fg->reg, PACFG, STARTX(0) | STARTY(0));
+	regmap_write(fg->reg, SACFG, STARTX(0) | STARTY(0));
+
+	/* alpha */
+	regmap_write_bits(fg->reg, FGINCTRL,      ENPRIMALPHA | ENSECALPHA, 0);
+	regmap_write_bits(fg->reg, FGINCTRLPANIC, ENPRIMALPHA | ENSECALPHA, 0);
+
+	/* constant color is green(used in panic mode)  */
+	regmap_write(fg->reg, FGCCR, CCGREEN(0x3ff));
+
+	ret = clk_set_rate(fg->clk_disp, m->clock * HZ_PER_KHZ);
+	if (ret < 0)
+		dev_err(fg->dev, "failed to set display clock rate: %d\n", ret);
+}
+
+static inline void dc_fg_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
+{
+	regmap_write_bits(fg->reg, FGINCTRL, FGDM_MASK, mode);
+}
+
+static inline void dc_fg_panic_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
+{
+	regmap_write_bits(fg->reg, FGINCTRLPANIC, FGDM_MASK, mode);
+}
+
+void dc_fg_enable(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGENABLE, FGEN);
+}
+
+void dc_fg_disable(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGENABLE, 0);
+}
+
+void dc_fg_shdtokgen(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGSLR, SHDTOKGEN);
+}
+
+u32 dc_fg_get_frame_index(struct dc_fg *fg)
+{
+	u32 val;
+
+	regmap_read(fg->reg, FGTIMESTAMP, &val);
+
+	return FRAMEINDEX(val);
+}
+
+u32 dc_fg_get_line_index(struct dc_fg *fg)
+{
+	u32 val;
+
+	regmap_read(fg->reg, FGTIMESTAMP, &val);
+
+	return LINEINDEX(val);
+}
+
+bool dc_fg_wait_for_frame_index_moving(struct dc_fg *fg)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(100);
+	u32 frame_index, last_frame_index;
+
+	frame_index = dc_fg_get_frame_index(fg);
+	do {
+		last_frame_index = frame_index;
+		frame_index = dc_fg_get_frame_index(fg);
+	} while (last_frame_index == frame_index &&
+		 time_before(jiffies, timeout));
+
+	return last_frame_index != frame_index;
+}
+
+bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg)
+{
+	u32 val;
+
+	regmap_read(fg->reg, FGCHSTAT, &val);
+
+	return !!(val & SFIFOEMPTY);
+}
+
+void dc_fg_secondary_clear_channel_status(struct dc_fg *fg)
+{
+	regmap_write(fg->reg, FGCHSTATCLR, CLRSECSTAT);
+}
+
+int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg)
+{
+	unsigned int val;
+
+	return regmap_read_poll_timeout(fg->reg, FGCHSTAT, val,
+					val & SECSYNCSTAT, 5, 100000);
+}
+
+void dc_fg_enable_clock(struct dc_fg *fg)
+{
+	int ret;
+
+	ret = clk_prepare_enable(fg->clk_disp);
+	if (ret)
+		dev_err(fg->dev, "failed to enable display clock: %d\n", ret);
+}
+
+void dc_fg_disable_clock(struct dc_fg *fg)
+{
+	clk_disable_unprepare(fg->clk_disp);
+}
+
+enum drm_mode_status dc_fg_check_clock(struct dc_fg *fg, int clk_khz)
+{
+	unsigned long rounded_rate;
+
+	rounded_rate = clk_round_rate(fg->clk_disp, clk_khz * HZ_PER_KHZ);
+
+	if (rounded_rate != clk_khz * HZ_PER_KHZ)
+		return MODE_NOCLOCK;
+
+	return MODE_OK;
+}
+
+void dc_fg_init(struct dc_fg *fg)
+{
+	dc_fg_enable_shden(fg);
+	dc_fg_syncmode(fg, FG_SYNCMODE_OFF);
+	dc_fg_displaymode(fg, FG_DM_SEC_ON_TOP);
+	dc_fg_panic_displaymode(fg, FG_DM_CONSTCOL);
+}
+
+static int dc_fg_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	void __iomem *base;
+	enum dc_fg_id id;
+	struct dc_fg *fg;
+	struct dc_de *de;
+
+	fg = devm_kzalloc(dev, sizeof(*fg), GFP_KERNEL);
+	if (!fg)
+		return -ENOMEM;
+
+	id = (enum dc_fg_id)(uintptr_t)device_get_match_data(dev);
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	fg->reg = devm_regmap_init_mmio(dev, base, &dc_fg_regmap_config);
+	if (IS_ERR(fg->reg))
+		return PTR_ERR(fg->reg);
+
+	fg->clk_disp = devm_clk_get(dev, NULL);
+	if (IS_ERR(fg->clk_disp))
+		return dev_err_probe(dev, PTR_ERR(fg->clk_disp),
+				     "failed to get display clock\n");
+
+	fg->dev = dev;
+
+	de = dc_drm->de[id];
+	de->fg = fg;
+
+	return 0;
+}
+
+static const struct component_ops dc_fg_ops = {
+	.bind = dc_fg_bind,
+};
+
+static int dc_fg_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_fg_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_fg_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_fg_ops);
+}
+
+static const struct of_device_id dc_fg_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-framegen0",
+	  .data = (const void *)DC_FG0, },
+	{ .compatible = "fsl,imx8qxp-dc-framegen1",
+	  .data = (const void *)DC_FG1, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_fg_dt_ids);
+
+struct platform_driver dc_fg_driver = {
+	.probe = dc_fg_probe,
+	.remove = dc_fg_remove,
+	.driver = {
+		.name = "imx8-dc-framegen",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_fg_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-tc.c b/drivers/gpu/drm/imx/dc/dc-tc.c
new file mode 100644
index 000000000000..a7d04e6eb8bf
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-tc.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include "dc-drv.h"
+#include "dc-de.h"
+
+#define TCON_CTRL	0x410
+#define  CTRL_RST_VAL	0x01401408
+
+/* red: MAPBIT 29-20, green: MAPBIT 19-10, blue: MAPBIT 9-0 */
+#define MAPBIT3_0	0x418
+#define MAPBIT7_4	0x41c
+#define MAPBIT11_8	0x420
+#define MAPBIT15_12	0x424
+#define MAPBIT19_16	0x428
+#define MAPBIT23_20	0x42c
+#define MAPBIT27_24	0x430
+#define MAPBIT31_28	0x434
+
+enum dc_tc_id {
+	DC_TC0,
+	DC_TC1,
+};
+
+static const struct regmap_range dc_tc_regmap_ranges[] = {
+	regmap_reg_range(TCON_CTRL, TCON_CTRL),
+	regmap_reg_range(MAPBIT3_0, MAPBIT31_28),
+};
+
+static const struct regmap_access_table dc_tc_regmap_access_table = {
+	.yes_ranges = dc_tc_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_tc_regmap_ranges),
+};
+
+static const struct regmap_config dc_tc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_tc_regmap_access_table,
+	.rd_table = &dc_tc_regmap_access_table,
+	.max_register = MAPBIT31_28,
+};
+
+/*
+ * The pixels reach TCON are always in 30-bit BGR format.
+ * The first bridge always receives pixels in 30-bit RGB format.
+ * So, map the format to MEDIA_BUS_FMT_RGB101010_1X30.
+ */
+static const u32 dc_tc_mapbit[] = {
+	0x17161514, 0x1b1a1918, 0x0b0a1d1c, 0x0f0e0d0c,
+	0x13121110, 0x03020100, 0x07060504, 0x00000908,
+};
+
+void dc_tc_init(struct dc_tc *tc)
+{
+	/* reset TCON_CTRL to POR default so that TCON works in bypass mode */
+	regmap_write(tc->reg, TCON_CTRL, CTRL_RST_VAL);
+
+	/* set format */
+	regmap_bulk_write(tc->reg, MAPBIT3_0, dc_tc_mapbit,
+			  ARRAY_SIZE(dc_tc_mapbit));
+}
+
+static int dc_tc_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	void __iomem *base;
+	enum dc_tc_id id;
+	struct dc_tc *tc;
+	struct dc_de *de;
+
+	tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL);
+	if (!tc)
+		return -ENOMEM;
+
+	id = (enum dc_tc_id)(uintptr_t)device_get_match_data(dev);
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	tc->reg = devm_regmap_init_mmio(dev, base, &dc_tc_regmap_config);
+	if (IS_ERR(tc->reg))
+		return PTR_ERR(tc->reg);
+
+	de = dc_drm->de[id];
+	de->tc = tc;
+	de->tc->dev = dev;
+
+	return 0;
+}
+
+static const struct component_ops dc_tc_ops = {
+	.bind = dc_tc_bind,
+};
+
+static int dc_tc_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_tc_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_tc_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_tc_ops);
+}
+
+static const struct of_device_id dc_tc_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-tcon0",
+	  .data = (const void *)DC_TC0, },
+	{ .compatible = "fsl,imx8qxp-dc-tcon1",
+	  .data = (const void *)DC_TC1, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_tc_dt_ids);
+
+struct platform_driver dc_tc_driver = {
+	.probe = dc_tc_probe,
+	.remove = dc_tc_remove,
+	.driver = {
+		.name = "imx8-dc-tcon",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_tc_dt_ids,
+	},
+};
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:38 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:38 +0800
Subject: [PATCH v7 10/19] drm/imx: Add i.MX8qxp Display Controller pixel engine
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-11-victor.liu@nxp.com>

i.MX8qxp Display Controller pixel engine consists of all processing
units that operate in the AXI bus clock domain.  Add drivers for
ConstFrame, ExtDst, FetchLayer, FetchWarp and LayerBlend units, as
well as a pixel engine driver, so that two displays with primary
planes can be supported.  The pixel engine driver and those unit
drivers are components to be aggregated by a master registered in
the upcoming DRM driver.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Add kernel doc for struct dc_drm_device. (Dmitry)
* Fix regmap_config definitions by correcting name field, correcting read
  ranges and setting max_register field.
* Get instance numbers from device data(compatible strings) instead of OF
  aliases.
* Collect Maxime's R-b tag.
* Trivial tweaks.

v6:
* Fix build warning by expanding sizeof(fu->name) from 13 to 21.
  (kernel test robot)

v5:
* Replace .remove_new with .remove in dc-{cf,de,fl,fw,lb,pe}.c. (Uwe)
* Fix commit message to state that pixel engine driver is a component driver
  instead of a master/aggregate driver.

v4:
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Inline some small functions. (Dmitry)
* Move dc_lb_blendcontrol() function call from KMS routine to initialization
  stage. (Dmitry)
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
* Drop unnecessary private struct dc_*_priv.
* Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
  interfaces to bind/unbind the drivers.
* Make some fetch unit operations be aware of fractional fetch unit index(0-7).

v3:
* No change.

v2:
* Use OF alias id to get instance id.

 drivers/gpu/drm/imx/dc/Makefile |   3 +-
 drivers/gpu/drm/imx/dc/dc-cf.c  | 173 +++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-drv.c |   6 +
 drivers/gpu/drm/imx/dc/dc-drv.h |   9 +
 drivers/gpu/drm/imx/dc/dc-ed.c  | 292 ++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-fl.c  | 182 ++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-fu.c  | 268 ++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-fu.h  | 129 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-fw.c  | 223 ++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-lb.c  | 324 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-pe.c  | 133 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-pe.h  | 107 +++++++++++
 12 files changed, 1848 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/imx/dc/dc-cf.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ed.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fl.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fu.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-fw.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-lb.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-pe.h

diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index 56de82d53d4d..2942ae6fd5bd 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-imx8-dc-drm-objs := dc-de.o dc-drv.o dc-fg.o dc-tc.o
+imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
+		    dc-fw.o dc-lb.o dc-pe.o dc-tc.o
 
 obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
new file mode 100644
index 000000000000..55e6186533da
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-cf.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define STATICCONTROL		0x8
+
+#define FRAMEDIMENSIONS		0xc
+#define  HEIGHT(x)		FIELD_PREP(GENMASK(29, 16), ((x) - 1))
+#define  WIDTH(x)		FIELD_PREP(GENMASK(13, 0), ((x) - 1))
+
+#define CONSTANTCOLOR		0x10
+#define  BLUE(x)		FIELD_PREP(GENMASK(15, 8), (x))
+
+enum dc_cf_id {
+	DC_CF0 = 0,
+	DC_CF1 = 1,
+	DC_CF4 = 4,
+	DC_CF5 = 5,
+};
+
+static const struct regmap_range dc_cf_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, CONSTANTCOLOR),
+};
+
+static const struct regmap_access_table dc_cf_regmap_access_table = {
+	.yes_ranges = dc_cf_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_cf_regmap_ranges),
+};
+
+static const struct regmap_config dc_cf_cfg_regmap_config = {
+	.name = "cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_cf_regmap_access_table,
+	.rd_table = &dc_cf_regmap_access_table,
+	.max_register = CONSTANTCOLOR,
+};
+
+static inline void dc_cf_enable_shden(struct dc_cf *cf)
+{
+	regmap_write(cf->reg_cfg, STATICCONTROL, SHDEN);
+}
+
+enum dc_link_id dc_cf_get_link_id(struct dc_cf *cf)
+{
+	return cf->link;
+}
+
+void dc_cf_framedimensions(struct dc_cf *cf, unsigned int w,
+			   unsigned int h)
+{
+	regmap_write(cf->reg_cfg, FRAMEDIMENSIONS, WIDTH(w) | HEIGHT(h));
+}
+
+void dc_cf_constantcolor_black(struct dc_cf *cf)
+{
+	regmap_write(cf->reg_cfg, CONSTANTCOLOR, 0);
+}
+
+void dc_cf_constantcolor_blue(struct dc_cf *cf)
+{
+	regmap_write(cf->reg_cfg, CONSTANTCOLOR, BLUE(0xff));
+}
+
+void dc_cf_init(struct dc_cf *cf)
+{
+	dc_cf_enable_shden(cf);
+}
+
+static int dc_cf_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_cfg;
+	enum dc_cf_id id;
+	struct dc_cf *cf;
+
+	cf = devm_kzalloc(dev, sizeof(*cf), GFP_KERNEL);
+	if (!cf)
+		return -ENOMEM;
+
+	id = (enum dc_cf_id)(uintptr_t)device_get_match_data(dev);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	cf->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_cf_cfg_regmap_config);
+	if (IS_ERR(cf->reg_cfg))
+		return PTR_ERR(cf->reg_cfg);
+
+	switch (id) {
+	case DC_CF0:
+		pe->cf_cont[0] = cf;
+		cf->link = LINK_ID_CONSTFRAME0;
+		break;
+	case DC_CF1:
+		pe->cf_cont[1] = cf;
+		cf->link = LINK_ID_CONSTFRAME1;
+		break;
+	case DC_CF4:
+		pe->cf_safe[0] = cf;
+		cf->link = LINK_ID_CONSTFRAME4;
+		break;
+	case DC_CF5:
+		pe->cf_safe[1] = cf;
+		cf->link = LINK_ID_CONSTFRAME5;
+		break;
+	}
+
+	return 0;
+}
+
+static const struct component_ops dc_cf_ops = {
+	.bind = dc_cf_bind,
+};
+
+static int dc_cf_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_cf_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_cf_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_cf_ops);
+}
+
+static const struct of_device_id dc_cf_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-constframe0",
+	  .data = (const void *)DC_CF0, },
+	{ .compatible = "fsl,imx8qxp-dc-constframe1",
+	  .data = (const void *)DC_CF1, },
+	{ .compatible = "fsl,imx8qxp-dc-constframe4",
+	  .data = (const void *)DC_CF4, },
+	{ .compatible = "fsl,imx8qxp-dc-constframe5",
+	  .data = (const void *)DC_CF5, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_cf_dt_ids);
+
+struct platform_driver dc_cf_driver = {
+	.probe = dc_cf_probe,
+	.remove = dc_cf_remove,
+	.driver = {
+		.name = "imx8-dc-constframe",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_cf_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index e5910a82dd4d..7c64acc863ad 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -9,8 +9,14 @@
 #include "dc-drv.h"
 
 static struct platform_driver * const dc_drivers[] = {
+	&dc_cf_driver,
 	&dc_de_driver,
+	&dc_ed_driver,
 	&dc_fg_driver,
+	&dc_fl_driver,
+	&dc_fw_driver,
+	&dc_lb_driver,
+	&dc_pe_driver,
 	&dc_tc_driver,
 };
 
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index 23ef715f5cd1..e618a4228590 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -11,6 +11,7 @@
 #include <drm/drm_device.h>
 
 #include "dc-de.h"
+#include "dc-pe.h"
 
 /**
  * struct dc_drm_device - DC specific drm_device
@@ -20,10 +21,18 @@ struct dc_drm_device {
 	struct drm_device base;
 	/** @de: display engine list */
 	struct dc_de *de[DC_DISPLAYS];
+	/** @pe: pixel engine */
+	struct dc_pe *pe;
 };
 
+extern struct platform_driver dc_cf_driver;
+extern struct platform_driver dc_ed_driver;
 extern struct platform_driver dc_de_driver;
 extern struct platform_driver dc_fg_driver;
+extern struct platform_driver dc_fl_driver;
+extern struct platform_driver dc_fw_driver;
+extern struct platform_driver dc_lb_driver;
+extern struct platform_driver dc_pe_driver;
 extern struct platform_driver dc_tc_driver;
 
 #endif /* __DC_DRV_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
new file mode 100644
index 000000000000..8a370b7e70f0
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-ed.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_STATIC	0x8
+#define  POWERDOWN		BIT(4)
+#define  SYNC_MODE		BIT(8)
+#define  SINGLE			0
+#define  DIV_MASK		GENMASK(23, 16)
+#define  DIV(x)			FIELD_PREP(DIV_MASK, (x))
+#define  DIV_RESET		0x80
+
+#define PIXENGCFG_DYNAMIC	0xc
+
+#define PIXENGCFG_TRIGGER	0x14
+#define  SYNC_TRIGGER		BIT(0)
+
+#define STATICCONTROL		0x8
+#define  KICK_MODE		BIT(8)
+#define  EXTERNAL		BIT(8)
+#define  PERFCOUNTMODE		BIT(12)
+
+#define CONTROL			0xc
+#define  GAMMAAPPLYENABLE	BIT(0)
+
+enum dc_ed_id {
+	DC_ED0 = 0,
+	DC_ED1 = 1,
+	DC_ED4 = 4,
+	DC_ED5 = 5,
+};
+
+static const struct regmap_range dc_ed_pec_regmap_write_ranges[] = {
+	regmap_reg_range(PIXENGCFG_STATIC, PIXENGCFG_STATIC),
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+	regmap_reg_range(PIXENGCFG_TRIGGER, PIXENGCFG_TRIGGER),
+};
+
+static const struct regmap_access_table dc_ed_pec_regmap_write_table = {
+	.yes_ranges = dc_ed_pec_regmap_write_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_pec_regmap_write_ranges),
+};
+
+static const struct regmap_range dc_ed_pec_regmap_read_ranges[] = {
+	regmap_reg_range(PIXENGCFG_STATIC, PIXENGCFG_STATIC),
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+};
+
+static const struct regmap_access_table dc_ed_pec_regmap_read_table = {
+	.yes_ranges = dc_ed_pec_regmap_read_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_pec_regmap_read_ranges),
+};
+
+static const struct regmap_range dc_ed_pec_regmap_volatile_ranges[] = {
+	regmap_reg_range(PIXENGCFG_TRIGGER, PIXENGCFG_TRIGGER),
+};
+
+static const struct regmap_access_table dc_ed_pec_regmap_volatile_table = {
+	.yes_ranges = dc_ed_pec_regmap_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_pec_regmap_volatile_ranges),
+};
+
+static const struct regmap_config dc_ed_pec_regmap_config = {
+	.name = "pec",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_ed_pec_regmap_write_table,
+	.rd_table = &dc_ed_pec_regmap_read_table,
+	.volatile_table = &dc_ed_pec_regmap_volatile_table,
+	.max_register = PIXENGCFG_TRIGGER,
+};
+
+static const struct regmap_range dc_ed_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, STATICCONTROL),
+	regmap_reg_range(CONTROL, CONTROL),
+};
+
+static const struct regmap_access_table dc_ed_regmap_access_table = {
+	.yes_ranges = dc_ed_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ed_regmap_ranges),
+};
+
+static const struct regmap_config dc_ed_cfg_regmap_config = {
+	.name = "cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_ed_regmap_access_table,
+	.rd_table = &dc_ed_regmap_access_table,
+	.max_register = CONTROL,
+};
+
+static const enum dc_link_id src_sels[] = {
+	LINK_ID_NONE,
+	LINK_ID_CONSTFRAME0,
+	LINK_ID_CONSTFRAME1,
+	LINK_ID_CONSTFRAME4,
+	LINK_ID_CONSTFRAME5,
+	LINK_ID_LAYERBLEND3,
+	LINK_ID_LAYERBLEND2,
+	LINK_ID_LAYERBLEND1,
+	LINK_ID_LAYERBLEND0,
+};
+
+static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SHDEN, SHDEN);
+}
+
+static inline void dc_ed_pec_poweron(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, POWERDOWN, 0);
+}
+
+static inline void dc_ed_pec_sync_mode_single(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SYNC_MODE, SINGLE);
+}
+
+static inline void dc_ed_pec_div_reset(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, DIV_MASK,
+			  DIV(DIV_RESET));
+}
+
+void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(src_sels); i++) {
+		if (src_sels[i] == src) {
+			regmap_write(ed->reg_pec, PIXENGCFG_DYNAMIC, src);
+			return;
+		}
+	}
+}
+
+void dc_ed_pec_sync_trigger(struct dc_ed *ed)
+{
+	regmap_write(ed->reg_pec, PIXENGCFG_TRIGGER, SYNC_TRIGGER);
+}
+
+static inline void dc_ed_enable_shden(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_ed_kick_mode_external(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, STATICCONTROL, KICK_MODE, EXTERNAL);
+}
+
+static inline void dc_ed_disable_perfcountmode(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, STATICCONTROL, PERFCOUNTMODE, 0);
+}
+
+static inline void dc_ed_disable_gamma_apply(struct dc_ed *ed)
+{
+	regmap_write_bits(ed->reg_cfg, CONTROL, GAMMAAPPLYENABLE, 0);
+}
+
+void dc_ed_init(struct dc_ed *ed)
+{
+	dc_ed_pec_src_sel(ed, LINK_ID_NONE);
+	dc_ed_pec_enable_shden(ed);
+	dc_ed_pec_poweron(ed);
+	dc_ed_pec_sync_mode_single(ed);
+	dc_ed_pec_div_reset(ed);
+	dc_ed_enable_shden(ed);
+	dc_ed_disable_perfcountmode(ed);
+	dc_ed_kick_mode_external(ed);
+	dc_ed_disable_gamma_apply(ed);
+}
+
+static int dc_ed_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_pec;
+	void __iomem *base_cfg;
+	enum dc_ed_id id;
+	struct dc_ed *ed;
+
+	ed = devm_kzalloc(dev, sizeof(*ed), GFP_KERNEL);
+	if (!ed)
+		return -ENOMEM;
+
+	id = (enum dc_ed_id)(uintptr_t)device_get_match_data(dev);
+
+	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
+	if (IS_ERR(base_pec))
+		return PTR_ERR(base_pec);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	ed->reg_pec = devm_regmap_init_mmio(dev, base_pec,
+					    &dc_ed_pec_regmap_config);
+	if (IS_ERR(ed->reg_pec))
+		return PTR_ERR(ed->reg_pec);
+
+	ed->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_ed_cfg_regmap_config);
+	if (IS_ERR(ed->reg_cfg))
+		return PTR_ERR(ed->reg_cfg);
+
+	ed->irq_shdld = platform_get_irq_byname(pdev, "shdload");
+	if (ed->irq_shdld < 0)
+		return ed->irq_shdld;
+
+	ed->dev = dev;
+
+	switch (id) {
+	case DC_ED0:
+		pe->ed_cont[0] = ed;
+		break;
+	case DC_ED1:
+		pe->ed_cont[1] = ed;
+		break;
+	case DC_ED4:
+		pe->ed_safe[0] = ed;
+		break;
+	case DC_ED5:
+		pe->ed_safe[1] = ed;
+		break;
+	}
+
+	return 0;
+}
+
+static const struct component_ops dc_ed_ops = {
+	.bind = dc_ed_bind,
+};
+
+static int dc_ed_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_ed_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_ed_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_ed_ops);
+}
+
+static const struct of_device_id dc_ed_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-extdst0",
+	  .data = (const void *)DC_ED0, },
+	{ .compatible = "fsl,imx8qxp-dc-extdst1",
+	  .data = (const void *)DC_ED1, },
+	{ .compatible = "fsl,imx8qxp-dc-extdst4",
+	  .data = (const void *)DC_ED4, },
+	{ .compatible = "fsl,imx8qxp-dc-extdst5",
+	  .data = (const void *)DC_ED5, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_ed_dt_ids);
+
+struct platform_driver dc_ed_driver = {
+	.probe = dc_ed_probe,
+	.remove = dc_ed_remove,
+	.driver = {
+		.name = "imx8-dc-extdst",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_ed_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
new file mode 100644
index 000000000000..81f4255709af
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fl.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+#define BASEADDRESS(x)			(0x10 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERATTRIBUTES(x)	(0x14 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERDIMENSION(x)	(0x18 + FRAC_OFFSET * (x))
+#define COLORCOMPONENTBITS(x)		(0x1c + FRAC_OFFSET * (x))
+#define COLORCOMPONENTSHIFT(x)		(0x20 + FRAC_OFFSET * (x))
+#define LAYEROFFSET(x)			(0x24 + FRAC_OFFSET * (x))
+#define CLIPWINDOWOFFSET(x)		(0x28 + FRAC_OFFSET * (x))
+#define CLIPWINDOWDIMENSIONS(x)		(0x2c + FRAC_OFFSET * (x))
+#define CONSTANTCOLOR(x)		(0x30 + FRAC_OFFSET * (x))
+#define LAYERPROPERTY(x)		(0x34 + FRAC_OFFSET * (x))
+#define FRAMEDIMENSIONS			0x150
+
+enum dc_fl_id {
+	DC_FL0,
+};
+
+struct dc_fl {
+	struct dc_fu fu;
+};
+
+static const struct regmap_range dc_fl_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS),
+};
+
+static const struct regmap_access_table dc_fl_regmap_access_table = {
+	.yes_ranges = dc_fl_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fl_regmap_ranges),
+};
+
+static const struct regmap_config dc_fl_cfg_regmap_config = {
+	.name = "cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fl_regmap_access_table,
+	.rd_table = &dc_fl_regmap_access_table,
+	.max_register = FRAMEDIMENSIONS,
+};
+
+static void dc_fl_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
+			  const struct drm_format_info *format)
+{
+	u32 bits = 0, shifts = 0;
+
+	dc_fu_set_src_bpp(fu, frac, format->cpp[0] * 8);
+
+	regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
+			  YUVCONVERSIONMODE_MASK,
+			  YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
+
+	dc_fu_get_pixel_format_bits(fu, format->format, &bits);
+	dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
+
+	regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
+	regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
+}
+
+static void dc_fl_set_framedimensions(struct dc_fu *fu, int w, int h)
+{
+	regmap_write(fu->reg_cfg, FRAMEDIMENSIONS,
+		     FRAMEWIDTH(w) | FRAMEHEIGHT(h));
+}
+
+static void dc_fl_init(struct dc_fu *fu)
+{
+	dc_fu_common_hw_init(fu);
+	dc_fu_shdldreq_sticky(fu, 0xff);
+}
+
+static void dc_fl_set_ops(struct dc_fu *fu)
+{
+	memcpy(&fu->ops, &dc_fu_common_ops, sizeof(dc_fu_common_ops));
+	fu->ops.init = dc_fl_init;
+	fu->ops.set_fmt = dc_fl_set_fmt;
+	fu->ops.set_framedimensions = dc_fl_set_framedimensions;
+}
+
+static int dc_fl_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_cfg;
+	enum dc_fl_id id;
+	struct dc_fl *fl;
+	struct dc_fu *fu;
+	int i;
+
+	fl = devm_kzalloc(dev, sizeof(*fl), GFP_KERNEL);
+	if (!fl)
+		return -ENOMEM;
+
+	id = (enum dc_fl_id)(uintptr_t)device_get_match_data(dev);
+
+	fu = &fl->fu;
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_fl_cfg_regmap_config);
+	if (IS_ERR(fu->reg_cfg))
+		return PTR_ERR(fu->reg_cfg);
+
+	fu->link_id = LINK_ID_FETCHLAYER0;
+	fu->id = DC_FETCHUNIT_FL0;
+	for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
+		fu->reg_baseaddr[i]		  = BASEADDRESS(i);
+		fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
+		fu->reg_sourcebufferdimension[i]  = SOURCEBUFFERDIMENSION(i);
+		fu->reg_layeroffset[i]		  = LAYEROFFSET(i);
+		fu->reg_clipwindowoffset[i]	  = CLIPWINDOWOFFSET(i);
+		fu->reg_clipwindowdimensions[i]	  = CLIPWINDOWDIMENSIONS(i);
+		fu->reg_constantcolor[i]	  = CONSTANTCOLOR(i);
+		fu->reg_layerproperty[i]	  = LAYERPROPERTY(i);
+	}
+	snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", id);
+
+	dc_fl_set_ops(fu);
+
+	pe->fu_disp[fu->id] = fu;
+
+	return 0;
+}
+
+static const struct component_ops dc_fl_ops = {
+	.bind = dc_fl_bind,
+};
+
+static int dc_fl_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_fl_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_fl_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_fl_ops);
+}
+
+static const struct of_device_id dc_fl_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-fetchlayer0",
+	  .data = (const void *)DC_FL0, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_fl_dt_ids);
+
+struct platform_driver dc_fl_driver = {
+	.probe = dc_fl_probe,
+	.remove = dc_fl_remove,
+	.driver = {
+		.name = "imx8-dc-fetchlayer",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_fl_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.c b/drivers/gpu/drm/imx/dc/dc-fu.c
new file mode 100644
index 000000000000..dda8e6c52be8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fu.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/math.h>
+
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+/* STATICCONTROL */
+#define SHDLDREQSTICKY_MASK		GENMASK(31, 24)
+#define SHDLDREQSTICKY(x)		FIELD_PREP(SHDLDREQSTICKY_MASK, (x))
+#define BASEADDRESSAUTOUPDATE_MASK	GENMASK(23, 16)
+#define BASEADDRESSAUTOUPDATE(x)	FIELD_PREP(BASEADDRESSAUTOUPDATE_MASK, (x))
+
+/* BURSTBUFFERMANAGEMENT */
+#define SETBURSTLENGTH_MASK		GENMASK(12, 8)
+#define SETBURSTLENGTH(x)		FIELD_PREP(SETBURSTLENGTH_MASK, (x))
+#define SETNUMBUFFERS_MASK		GENMASK(7, 0)
+#define SETNUMBUFFERS(x)		FIELD_PREP(SETNUMBUFFERS_MASK, (x))
+#define LINEMODE_MASK			BIT(31)
+
+/* SOURCEBUFFERATTRIBUTES */
+#define BITSPERPIXEL_MASK		GENMASK(21, 16)
+#define BITSPERPIXEL(x)			FIELD_PREP(BITSPERPIXEL_MASK, (x))
+#define STRIDE_MASK			GENMASK(15, 0)
+#define STRIDE(x)			FIELD_PREP(STRIDE_MASK, (x) - 1)
+
+/* SOURCEBUFFERDIMENSION */
+#define LINEWIDTH(x)			FIELD_PREP(GENMASK(13, 0), (x))
+#define LINECOUNT(x)			FIELD_PREP(GENMASK(29, 16), (x))
+
+/* LAYEROFFSET */
+#define LAYERXOFFSET(x)			FIELD_PREP(GENMASK(14, 0), (x))
+#define LAYERYOFFSET(x)			FIELD_PREP(GENMASK(30, 16), (x))
+
+/* CLIPWINDOWOFFSET */
+#define CLIPWINDOWXOFFSET(x)		FIELD_PREP(GENMASK(14, 0), (x))
+#define CLIPWINDOWYOFFSET(x)		FIELD_PREP(GENMASK(30, 16), (x))
+
+/* CLIPWINDOWDIMENSIONS */
+#define CLIPWINDOWWIDTH(x)		FIELD_PREP(GENMASK(13, 0), (x) - 1)
+#define CLIPWINDOWHEIGHT(x)		FIELD_PREP(GENMASK(29, 16), (x) - 1)
+
+static const enum dc_fu_frac dc_fetchunit_all_fracs[] = {
+	DC_FETCHUNIT_FRAC0, DC_FETCHUNIT_FRAC1,
+	DC_FETCHUNIT_FRAC2, DC_FETCHUNIT_FRAC3,
+	DC_FETCHUNIT_FRAC4, DC_FETCHUNIT_FRAC5,
+	DC_FETCHUNIT_FRAC6, DC_FETCHUNIT_FRAC7
+};
+
+enum dc_linemode {
+	/*
+	 * Mandatory setting for operation in the Display Controller.
+	 * Works also for Blit Engine with marginal performance impact.
+	 */
+	LINEMODE_DISPLAY = 0,
+};
+
+struct dc_fu_pixel_format {
+	u32 pixel_format;
+	u32 bits;
+	u32 shifts;
+};
+
+static const struct dc_fu_pixel_format pixel_formats[] = {
+	{
+		DRM_FORMAT_XRGB8888,
+		R_BITS(8)   | G_BITS(8)   | B_BITS(8)   | A_BITS(0),
+		R_SHIFT(16) | G_SHIFT(8)  | B_SHIFT(0)  | A_SHIFT(0),
+	},
+};
+
+void dc_fu_get_pixel_format_bits(struct dc_fu *fu, u32 format, u32 *bits)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+		if (pixel_formats[i].pixel_format == format) {
+			*bits = pixel_formats[i].bits;
+			return;
+		}
+	}
+}
+
+void
+dc_fu_get_pixel_format_shifts(struct dc_fu *fu, u32 format, u32 *shifts)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_formats); i++) {
+		if (pixel_formats[i].pixel_format == format) {
+			*shifts = pixel_formats[i].shifts;
+			return;
+		}
+	}
+}
+
+static inline void dc_fu_enable_shden(struct dc_fu *fu)
+{
+	regmap_write_bits(fu->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_fu_baddr_autoupdate(struct dc_fu *fu, u8 layer_mask)
+{
+	regmap_write_bits(fu->reg_cfg, STATICCONTROL,
+			  BASEADDRESSAUTOUPDATE_MASK,
+			  BASEADDRESSAUTOUPDATE(layer_mask));
+}
+
+void dc_fu_shdldreq_sticky(struct dc_fu *fu, u8 layer_mask)
+{
+	regmap_write_bits(fu->reg_cfg, STATICCONTROL, SHDLDREQSTICKY_MASK,
+			  SHDLDREQSTICKY(layer_mask));
+}
+
+static inline void dc_fu_set_linemode(struct dc_fu *fu, enum dc_linemode mode)
+{
+	regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT, LINEMODE_MASK,
+			  mode);
+}
+
+static inline void dc_fu_set_numbuffers(struct dc_fu *fu, unsigned int num)
+{
+	regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
+			  SETNUMBUFFERS_MASK, SETNUMBUFFERS(num));
+}
+
+static void dc_fu_set_burstlength(struct dc_fu *fu, dma_addr_t baddr)
+{
+	unsigned int burst_size, burst_length;
+
+	burst_size = 1 << __ffs(baddr);
+	burst_size = round_up(burst_size, 8);
+	burst_size = min(burst_size, 128U);
+	burst_length = burst_size / 8;
+
+	regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
+			  SETBURSTLENGTH_MASK, SETBURSTLENGTH(burst_length));
+}
+
+static void dc_fu_set_baseaddress(struct dc_fu *fu, enum dc_fu_frac frac,
+				  dma_addr_t baddr)
+{
+	regmap_write(fu->reg_cfg, fu->reg_baseaddr[frac], baddr);
+}
+
+void dc_fu_set_src_bpp(struct dc_fu *fu, enum dc_fu_frac frac, unsigned int bpp)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_sourcebufferattributes[frac],
+			  BITSPERPIXEL_MASK, BITSPERPIXEL(bpp));
+}
+
+static void dc_fu_set_src_stride(struct dc_fu *fu, enum dc_fu_frac frac,
+				 unsigned int stride)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_sourcebufferattributes[frac],
+			  STRIDE_MASK, STRIDE(stride));
+}
+
+static void dc_fu_set_src_buf_dimensions(struct dc_fu *fu, enum dc_fu_frac frac,
+					 int w, int h)
+{
+	regmap_write(fu->reg_cfg, fu->reg_sourcebufferdimension[frac],
+		     LINEWIDTH(w) | LINECOUNT(h));
+}
+
+static inline void dc_fu_layeroffset(struct dc_fu *fu, enum dc_fu_frac frac,
+				     unsigned int x, unsigned int y)
+{
+	regmap_write(fu->reg_cfg, fu->reg_layeroffset[frac],
+		     LAYERXOFFSET(x) | LAYERYOFFSET(y));
+}
+
+static inline void dc_fu_clipoffset(struct dc_fu *fu, enum dc_fu_frac frac,
+				    unsigned int x, unsigned int y)
+{
+	regmap_write(fu->reg_cfg, fu->reg_clipwindowoffset[frac],
+		     CLIPWINDOWXOFFSET(x) | CLIPWINDOWYOFFSET(y));
+}
+
+static inline void dc_fu_clipdimensions(struct dc_fu *fu, enum dc_fu_frac frac,
+					unsigned int w, unsigned int h)
+{
+	regmap_write(fu->reg_cfg, fu->reg_clipwindowdimensions[frac],
+		     CLIPWINDOWWIDTH(w) | CLIPWINDOWHEIGHT(h));
+}
+
+static inline void
+dc_fu_set_pixel_blend_mode(struct dc_fu *fu, enum dc_fu_frac frac)
+{
+	regmap_write(fu->reg_cfg, fu->reg_layerproperty[frac], 0);
+	regmap_write(fu->reg_cfg, fu->reg_constantcolor[frac], 0);
+}
+
+static void dc_fu_enable_src_buf(struct dc_fu *fu, enum dc_fu_frac frac)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
+			  SOURCEBUFFERENABLE, SOURCEBUFFERENABLE);
+}
+
+static void dc_fu_disable_src_buf(struct dc_fu *fu, enum dc_fu_frac frac)
+{
+	regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
+			  SOURCEBUFFERENABLE, 0);
+
+	if (fu->lb) {
+		dc_lb_pec_clken(fu->lb, CLKEN_DISABLE);
+		dc_lb_mode(fu->lb, LB_NEUTRAL);
+	}
+}
+
+static void dc_fu_set_layerblend(struct dc_fu *fu, struct dc_lb *lb)
+{
+	fu->lb = lb;
+}
+
+static enum dc_link_id dc_fu_get_link_id(struct dc_fu *fu)
+{
+	return fu->link_id;
+}
+
+static const char *dc_fu_get_name(struct dc_fu *fu)
+{
+	return fu->name;
+}
+
+const struct dc_fu_ops dc_fu_common_ops = {
+	.set_burstlength	= dc_fu_set_burstlength,
+	.set_baseaddress	= dc_fu_set_baseaddress,
+	.set_src_stride		= dc_fu_set_src_stride,
+	.set_src_buf_dimensions = dc_fu_set_src_buf_dimensions,
+	.enable_src_buf		= dc_fu_enable_src_buf,
+	.disable_src_buf	= dc_fu_disable_src_buf,
+	.set_layerblend		= dc_fu_set_layerblend,
+	.get_link_id		= dc_fu_get_link_id,
+	.get_name		= dc_fu_get_name,
+};
+
+const struct dc_fu_ops *dc_fu_get_ops(struct dc_fu *fu)
+{
+	return &fu->ops;
+}
+
+void dc_fu_common_hw_init(struct dc_fu *fu)
+{
+	enum dc_fu_frac frac;
+	int i;
+
+	dc_fu_baddr_autoupdate(fu, 0x0);
+	dc_fu_enable_shden(fu);
+	dc_fu_set_linemode(fu, LINEMODE_DISPLAY);
+	dc_fu_set_numbuffers(fu, 16);
+
+	for (i = 0; i < ARRAY_SIZE(dc_fetchunit_all_fracs); i++) {
+		frac = dc_fetchunit_all_fracs[i];
+
+		dc_fu_layeroffset(fu, frac, 0, 0);
+		dc_fu_clipoffset(fu, frac, 0, 0);
+		dc_fu_clipdimensions(fu, frac, 1, 1);
+		dc_fu_disable_src_buf(fu, frac);
+		dc_fu_set_pixel_blend_mode(fu, frac);
+	}
+}
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.h b/drivers/gpu/drm/imx/dc/dc-fu.h
new file mode 100644
index 000000000000..cab71965964e
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fu.h
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_FETCHUNIT_H__
+#define __DC_FETCHUNIT_H__
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "dc-pe.h"
+
+#define FRAC_OFFSET			0x28
+
+#define STATICCONTROL			0x8
+#define BURSTBUFFERMANAGEMENT		0xc
+
+/* COLORCOMPONENTBITS */
+#define R_BITS(x)			FIELD_PREP_CONST(GENMASK(27, 24), (x))
+#define G_BITS(x)			FIELD_PREP_CONST(GENMASK(19, 16), (x))
+#define B_BITS(x)			FIELD_PREP_CONST(GENMASK(11, 8), (x))
+#define A_BITS(x)			FIELD_PREP_CONST(GENMASK(3, 0), (x))
+
+/* COLORCOMPONENTSHIFT */
+#define R_SHIFT(x)			FIELD_PREP_CONST(GENMASK(28, 24), (x))
+#define G_SHIFT(x)			FIELD_PREP_CONST(GENMASK(20, 16), (x))
+#define B_SHIFT(x)			FIELD_PREP_CONST(GENMASK(12, 8), (x))
+#define A_SHIFT(x)			FIELD_PREP_CONST(GENMASK(4, 0), (x))
+
+/* LAYERPROPERTY */
+#define YUVCONVERSIONMODE_MASK		GENMASK(18, 17)
+#define YUVCONVERSIONMODE(x)		FIELD_PREP(YUVCONVERSIONMODE_MASK, (x))
+#define SOURCEBUFFERENABLE		BIT(31)
+
+/* FRAMEDIMENSIONS */
+#define FRAMEWIDTH(x)			FIELD_PREP(GENMASK(13, 0), (x))
+#define FRAMEHEIGHT(x)			FIELD_PREP(GENMASK(29, 16), (x))
+
+/* CONTROL */
+#define INPUTSELECT_MASK		GENMASK(4, 3)
+#define INPUTSELECT(x)			FIELD_PREP(INPUTSELECT_MASK, (x))
+#define RASTERMODE_MASK			GENMASK(2, 0)
+#define RASTERMODE(x)			FIELD_PREP(RASTERMODE_MASK, (x))
+
+enum dc_yuvconversionmode {
+	YUVCONVERSIONMODE_OFF,
+};
+
+enum dc_inputselect {
+	INPUTSELECT_INACTIVE,
+};
+
+enum dc_rastermode {
+	RASTERMODE_NORMAL,
+};
+
+enum {
+	DC_FETCHUNIT_FL0,
+	DC_FETCHUNIT_FW2,
+};
+
+enum dc_fu_frac {
+	DC_FETCHUNIT_FRAC0,
+	DC_FETCHUNIT_FRAC1,
+	DC_FETCHUNIT_FRAC2,
+	DC_FETCHUNIT_FRAC3,
+	DC_FETCHUNIT_FRAC4,
+	DC_FETCHUNIT_FRAC5,
+	DC_FETCHUNIT_FRAC6,
+	DC_FETCHUNIT_FRAC7,
+	DC_FETCHUNIT_FRAC_NUM,
+};
+
+struct dc_fu;
+struct dc_lb;
+
+struct dc_fu_ops {
+	void (*init)(struct dc_fu *fu);
+	void (*set_burstlength)(struct dc_fu *fu, dma_addr_t baddr);
+	void (*set_baseaddress)(struct dc_fu *fu, enum dc_fu_frac frac,
+				dma_addr_t baddr);
+	void (*set_src_stride)(struct dc_fu *fu, enum dc_fu_frac frac,
+			       unsigned int stride);
+	void (*set_src_buf_dimensions)(struct dc_fu *fu, enum dc_fu_frac frac,
+				       int w, int h);
+	void (*set_fmt)(struct dc_fu *fu, enum dc_fu_frac frac,
+			const struct drm_format_info *format);
+	void (*enable_src_buf)(struct dc_fu *fu, enum dc_fu_frac frac);
+	void (*disable_src_buf)(struct dc_fu *fu, enum dc_fu_frac frac);
+	void (*set_framedimensions)(struct dc_fu *fu, int w, int h);
+	void (*set_layerblend)(struct dc_fu *fu, struct dc_lb *lb);
+	enum dc_link_id (*get_link_id)(struct dc_fu *fu);
+	const char *(*get_name)(struct dc_fu *fu);
+};
+
+struct dc_fu {
+	struct regmap *reg_pec;
+	struct regmap *reg_cfg;
+	char name[21];
+	u32 reg_baseaddr[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_sourcebufferattributes[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_sourcebufferdimension[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_layeroffset[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_clipwindowoffset[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_clipwindowdimensions[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_constantcolor[DC_FETCHUNIT_FRAC_NUM];
+	u32 reg_layerproperty[DC_FETCHUNIT_FRAC_NUM];
+	unsigned int id;
+	enum dc_link_id link_id;
+	struct dc_fu_ops ops;
+	struct dc_lb *lb;
+};
+
+extern const struct dc_fu_ops dc_fu_common_ops;
+
+void dc_fu_get_pixel_format_bits(struct dc_fu *fu, u32 format, u32 *bits);
+void dc_fu_get_pixel_format_shifts(struct dc_fu *fu, u32 format, u32 *shifts);
+void dc_fu_shdldreq_sticky(struct dc_fu *fu, u8 layer_mask);
+void dc_fu_set_src_bpp(struct dc_fu *fu, enum dc_fu_frac frac, unsigned int bpp);
+void dc_fu_common_hw_init(struct dc_fu *fu);
+
+const struct dc_fu_ops *dc_fu_get_ops(struct dc_fu *fu);
+
+#endif /* __DC_FETCHUNIT_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-fw.c b/drivers/gpu/drm/imx/dc/dc-fw.c
new file mode 100644
index 000000000000..6800f6c9f785
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-fw.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_DYNAMIC		0x8
+
+#define BASEADDRESS(x)			(0x10 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERATTRIBUTES(x)	(0x14 + FRAC_OFFSET * (x))
+#define SOURCEBUFFERDIMENSION(x)	(0x18 + FRAC_OFFSET * (x))
+#define COLORCOMPONENTBITS(x)		(0x1c + FRAC_OFFSET * (x))
+#define COLORCOMPONENTSHIFT(x)		(0x20 + FRAC_OFFSET * (x))
+#define LAYEROFFSET(x)			(0x24 + FRAC_OFFSET * (x))
+#define CLIPWINDOWOFFSET(x)		(0x28 + FRAC_OFFSET * (x))
+#define CLIPWINDOWDIMENSIONS(x)		(0x2c + FRAC_OFFSET * (x))
+#define CONSTANTCOLOR(x)		(0x30 + FRAC_OFFSET * (x))
+#define LAYERPROPERTY(x)		(0x34 + FRAC_OFFSET * (x))
+#define FRAMEDIMENSIONS			0x150
+#define CONTROL				0x170
+
+enum dc_fw_id {
+	DC_FW2 = 2,
+	DC_FW9 = 9,
+};
+
+struct dc_fw {
+	struct dc_fu fu;
+};
+
+static const struct regmap_range dc_fw_pec_regmap_access_ranges[] = {
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+};
+
+static const struct regmap_access_table dc_fw_pec_regmap_access_table = {
+	.yes_ranges = dc_fw_pec_regmap_access_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fw_pec_regmap_access_ranges),
+};
+
+static const struct regmap_config dc_fw_pec_regmap_config = {
+	.name = "pec",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fw_pec_regmap_access_table,
+	.rd_table = &dc_fw_pec_regmap_access_table,
+	.max_register = PIXENGCFG_DYNAMIC,
+};
+
+static const struct regmap_range dc_fw_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS),
+	regmap_reg_range(CONTROL, CONTROL),
+};
+
+static const struct regmap_access_table dc_fw_regmap_access_table = {
+	.yes_ranges = dc_fw_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_fw_regmap_ranges),
+};
+
+static const struct regmap_config dc_fw_cfg_regmap_config = {
+	.name = "cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_fw_regmap_access_table,
+	.rd_table = &dc_fw_regmap_access_table,
+	.max_register = CONTROL,
+};
+
+static void dc_fw_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
+			  const struct drm_format_info *format)
+{
+	u32 bits = 0, shifts = 0;
+
+	dc_fu_set_src_bpp(fu, frac, format->cpp[0] * 8);
+
+	regmap_write_bits(fu->reg_cfg, CONTROL, INPUTSELECT_MASK,
+			  INPUTSELECT(INPUTSELECT_INACTIVE));
+	regmap_write_bits(fu->reg_cfg, CONTROL, RASTERMODE_MASK,
+			  RASTERMODE(RASTERMODE_NORMAL));
+
+	regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
+			  YUVCONVERSIONMODE_MASK,
+			  YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
+
+	dc_fu_get_pixel_format_bits(fu, format->format, &bits);
+	dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
+
+	regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
+	regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
+}
+
+static void dc_fw_set_framedimensions(struct dc_fu *fu, int w, int h)
+{
+	regmap_write(fu->reg_cfg, FRAMEDIMENSIONS,
+		     FRAMEWIDTH(w) | FRAMEHEIGHT(h));
+}
+
+static void dc_fw_init(struct dc_fu *fu)
+{
+	regmap_write(fu->reg_pec, PIXENGCFG_DYNAMIC, LINK_ID_NONE);
+	dc_fu_common_hw_init(fu);
+	dc_fu_shdldreq_sticky(fu, 0xff);
+}
+
+static void dc_fw_set_ops(struct dc_fu *fu)
+{
+	memcpy(&fu->ops, &dc_fu_common_ops, sizeof(dc_fu_common_ops));
+	fu->ops.init = dc_fw_init;
+	fu->ops.set_fmt	= dc_fw_set_fmt;
+	fu->ops.set_framedimensions = dc_fw_set_framedimensions;
+}
+
+static int dc_fw_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_pec;
+	void __iomem *base_cfg;
+	enum dc_fw_id id;
+	struct dc_fw *fw;
+	struct dc_fu *fu;
+	int i;
+
+	fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
+	if (!fw)
+		return -ENOMEM;
+
+	id = (enum dc_fw_id)(uintptr_t)device_get_match_data(dev);
+
+	fu = &fw->fu;
+
+	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
+	if (IS_ERR(base_pec))
+		return PTR_ERR(base_pec);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	fu->reg_pec = devm_regmap_init_mmio(dev, base_pec,
+					    &dc_fw_pec_regmap_config);
+	if (IS_ERR(fu->reg_pec))
+		return PTR_ERR(fu->reg_pec);
+
+	fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_fw_cfg_regmap_config);
+	if (IS_ERR(fu->reg_cfg))
+		return PTR_ERR(fu->reg_cfg);
+
+	fu->link_id = LINK_ID_FETCHWARP2;
+	fu->id = DC_FETCHUNIT_FW2;
+	for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
+		fu->reg_baseaddr[i]		  = BASEADDRESS(i);
+		fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
+		fu->reg_sourcebufferdimension[i]  = SOURCEBUFFERDIMENSION(i);
+		fu->reg_layeroffset[i]		  = LAYEROFFSET(i);
+		fu->reg_clipwindowoffset[i]	  = CLIPWINDOWOFFSET(i);
+		fu->reg_clipwindowdimensions[i]	  = CLIPWINDOWDIMENSIONS(i);
+		fu->reg_constantcolor[i]	  = CONSTANTCOLOR(i);
+		fu->reg_layerproperty[i]	  = LAYERPROPERTY(i);
+	}
+	snprintf(fu->name, sizeof(fu->name), "FetchWarp%d", id);
+
+	dc_fw_set_ops(fu);
+
+	pe->fu_disp[fu->id] = fu;
+
+	return 0;
+}
+
+static const struct component_ops dc_fw_ops = {
+	.bind = dc_fw_bind,
+};
+
+static int dc_fw_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_fw_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_fw_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_fw_ops);
+}
+
+static const struct of_device_id dc_fw_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-fetchwarp2",
+	  .data = (const void *)DC_FW2, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_fw_dt_ids);
+
+struct platform_driver dc_fw_driver = {
+	.probe = dc_fw_probe,
+	.remove = dc_fw_remove,
+	.driver = {
+		.name = "imx8-dc-fetchwarp",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_fw_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
new file mode 100644
index 000000000000..7bac6cf4ee48
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-lb.c
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_blend.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_DYNAMIC			0x8
+#define  PIXENGCFG_DYNAMIC_PRIM_SEL_MASK	GENMASK(5, 0)
+#define  PIXENGCFG_DYNAMIC_PRIM_SEL(x)		\
+		FIELD_PREP(PIXENGCFG_DYNAMIC_PRIM_SEL_MASK, (x))
+#define  PIXENGCFG_DYNAMIC_SEC_SEL_MASK		GENMASK(13, 8)
+#define  PIXENGCFG_DYNAMIC_SEC_SEL(x)		\
+		FIELD_PREP(PIXENGCFG_DYNAMIC_SEC_SEL_MASK, (x))
+
+#define STATICCONTROL				0x8
+#define  SHDTOKSEL_MASK				GENMASK(4, 3)
+#define  SHDTOKSEL(x)				FIELD_PREP(SHDTOKSEL_MASK, (x))
+#define  SHDLDSEL_MASK				GENMASK(2, 1)
+#define  SHDLDSEL(x)				FIELD_PREP(SHDLDSEL_MASK, (x))
+
+#define CONTROL					0xc
+#define  CTRL_MODE_MASK				BIT(0)
+#define  CTRL_MODE(x)				FIELD_PREP(CTRL_MODE_MASK, (x))
+
+#define BLENDCONTROL				0x10
+#define  ALPHA_MASK				GENMASK(23, 16)
+#define  ALPHA(x)				FIELD_PREP(ALPHA_MASK, (x))
+#define  PRIM_C_BLD_FUNC_MASK			GENMASK(2, 0)
+#define  PRIM_C_BLD_FUNC(x)			\
+		FIELD_PREP(PRIM_C_BLD_FUNC_MASK, (x))
+#define  SEC_C_BLD_FUNC_MASK			GENMASK(6, 4)
+#define  SEC_C_BLD_FUNC(x)			\
+		FIELD_PREP(SEC_C_BLD_FUNC_MASK, (x))
+#define  PRIM_A_BLD_FUNC_MASK			GENMASK(10, 8)
+#define  PRIM_A_BLD_FUNC(x)			\
+		FIELD_PREP(PRIM_A_BLD_FUNC_MASK, (x))
+#define  SEC_A_BLD_FUNC_MASK			GENMASK(14, 12)
+#define  SEC_A_BLD_FUNC(x)			\
+		FIELD_PREP(SEC_A_BLD_FUNC_MASK, (x))
+
+#define POSITION				0x14
+#define  XPOS_MASK				GENMASK(15, 0)
+#define  XPOS(x)				FIELD_PREP(XPOS_MASK, (x))
+#define  YPOS_MASK				GENMASK(31, 16)
+#define  YPOS(x)				FIELD_PREP(YPOS_MASK, (x))
+
+enum dc_lb_blend_func {
+	DC_LAYERBLEND_BLEND_ZERO,
+	DC_LAYERBLEND_BLEND_ONE,
+	DC_LAYERBLEND_BLEND_PRIM_ALPHA,
+	DC_LAYERBLEND_BLEND_ONE_MINUS_PRIM_ALPHA,
+	DC_LAYERBLEND_BLEND_SEC_ALPHA,
+	DC_LAYERBLEND_BLEND_ONE_MINUS_SEC_ALPHA,
+	DC_LAYERBLEND_BLEND_CONST_ALPHA,
+	DC_LAYERBLEND_BLEND_ONE_MINUS_CONST_ALPHA,
+};
+
+enum dc_lb_shadow_sel {
+	BOTH = 0x2,
+};
+
+static const struct regmap_range dc_lb_pec_regmap_access_ranges[] = {
+	regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
+};
+
+static const struct regmap_access_table dc_lb_pec_regmap_access_table = {
+	.yes_ranges = dc_lb_pec_regmap_access_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_lb_pec_regmap_access_ranges),
+};
+
+static const struct regmap_config dc_lb_pec_regmap_config = {
+	.name = "pec",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_lb_pec_regmap_access_table,
+	.rd_table = &dc_lb_pec_regmap_access_table,
+	.max_register = PIXENGCFG_DYNAMIC,
+};
+
+static const struct regmap_range dc_lb_regmap_ranges[] = {
+	regmap_reg_range(STATICCONTROL, POSITION),
+};
+
+static const struct regmap_access_table dc_lb_regmap_access_table = {
+	.yes_ranges = dc_lb_regmap_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_lb_regmap_ranges),
+};
+
+static const struct regmap_config dc_lb_cfg_regmap_config = {
+	.name = "cfg",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_lb_regmap_access_table,
+	.rd_table = &dc_lb_regmap_access_table,
+	.max_register = POSITION,
+};
+
+static const enum dc_link_id lb_links[] = {
+	LINK_ID_LAYERBLEND0,
+	LINK_ID_LAYERBLEND1,
+	LINK_ID_LAYERBLEND2,
+	LINK_ID_LAYERBLEND3,
+};
+
+static const enum dc_link_id prim_sels[] = {
+	/* common options */
+	LINK_ID_NONE,
+	LINK_ID_CONSTFRAME0,
+	LINK_ID_CONSTFRAME1,
+	LINK_ID_CONSTFRAME4,
+	LINK_ID_CONSTFRAME5,
+	/*
+	 * special options:
+	 * layerblend(n) has n special options,
+	 * from layerblend0 to layerblend(n - 1), e.g.,
+	 * layerblend3 has 3 special options -
+	 * layerblend0/1/2.
+	 */
+	LINK_ID_LAYERBLEND0,
+	LINK_ID_LAYERBLEND1,
+	LINK_ID_LAYERBLEND2,
+	LINK_ID_LAYERBLEND3,
+};
+
+static const enum dc_link_id sec_sels[] = {
+	LINK_ID_NONE,
+	LINK_ID_FETCHWARP2,
+	LINK_ID_FETCHLAYER0,
+};
+
+enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
+{
+	return lb->link;
+}
+
+void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim)
+{
+	int fixed_sels_num = ARRAY_SIZE(prim_sels) - 4;
+	int i;
+
+	for (i = 0; i < fixed_sels_num + lb->id; i++) {
+		if (prim_sels[i] == prim) {
+			regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
+					  PIXENGCFG_DYNAMIC_PRIM_SEL_MASK,
+					  PIXENGCFG_DYNAMIC_PRIM_SEL(prim));
+			return;
+		}
+	}
+}
+
+void dc_lb_pec_dynamic_sec_sel(struct dc_lb *lb, enum dc_link_id sec)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sec_sels); i++) {
+		if (sec_sels[i] == sec) {
+			regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
+					  PIXENGCFG_DYNAMIC_SEC_SEL_MASK,
+					  PIXENGCFG_DYNAMIC_SEC_SEL(sec));
+			return;
+		}
+	}
+}
+
+void dc_lb_pec_clken(struct dc_lb *lb, enum dc_pec_clken clken)
+{
+	regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC, CLKEN_MASK,
+			  CLKEN(clken));
+}
+
+static inline void dc_lb_enable_shden(struct dc_lb *lb)
+{
+	regmap_write_bits(lb->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_lb_shdtoksel(struct dc_lb *lb, enum dc_lb_shadow_sel sel)
+{
+	regmap_write_bits(lb->reg_cfg, STATICCONTROL, SHDTOKSEL_MASK,
+			  SHDTOKSEL(sel));
+}
+
+static inline void dc_lb_shdldsel(struct dc_lb *lb, enum dc_lb_shadow_sel sel)
+{
+	regmap_write_bits(lb->reg_cfg, STATICCONTROL, SHDLDSEL_MASK,
+			  SHDLDSEL(sel));
+}
+
+void dc_lb_mode(struct dc_lb *lb, enum dc_lb_mode mode)
+{
+	regmap_write_bits(lb->reg_cfg, CONTROL, CTRL_MODE_MASK, mode);
+}
+
+static inline void dc_lb_blendcontrol(struct dc_lb *lb)
+{
+	u32 val = PRIM_A_BLD_FUNC(DC_LAYERBLEND_BLEND_ZERO) |
+		  SEC_A_BLD_FUNC(DC_LAYERBLEND_BLEND_ZERO) |
+		  PRIM_C_BLD_FUNC(DC_LAYERBLEND_BLEND_ZERO) |
+		  SEC_C_BLD_FUNC(DC_LAYERBLEND_BLEND_CONST_ALPHA) |
+		  ALPHA(DRM_BLEND_ALPHA_OPAQUE >> 8);
+
+	regmap_write(lb->reg_cfg, BLENDCONTROL, val);
+}
+
+void dc_lb_position(struct dc_lb *lb, int x, int y)
+{
+	regmap_write(lb->reg_cfg, POSITION, XPOS(x) | YPOS(y));
+}
+
+enum dc_lb_id dc_lb_get_id(struct dc_lb *lb)
+{
+	return lb->id;
+}
+
+void dc_lb_init(struct dc_lb *lb)
+{
+	dc_lb_pec_dynamic_prim_sel(lb, LINK_ID_NONE);
+	dc_lb_pec_dynamic_sec_sel(lb, LINK_ID_NONE);
+	dc_lb_pec_clken(lb, CLKEN_DISABLE);
+	dc_lb_shdldsel(lb, BOTH);
+	dc_lb_shdtoksel(lb, BOTH);
+	dc_lb_blendcontrol(lb);
+	dc_lb_enable_shden(lb);
+}
+
+static int dc_lb_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe = dc_drm->pe;
+	void __iomem *base_pec;
+	void __iomem *base_cfg;
+	struct dc_lb *lb;
+
+	lb = devm_kzalloc(dev, sizeof(*lb), GFP_KERNEL);
+	if (!lb)
+		return -ENOMEM;
+
+	lb->id = (enum dc_lb_id)(uintptr_t)device_get_match_data(dev);
+
+	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
+	if (IS_ERR(base_pec))
+		return PTR_ERR(base_pec);
+
+	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
+	if (IS_ERR(base_cfg))
+		return PTR_ERR(base_cfg);
+
+	lb->reg_pec = devm_regmap_init_mmio(dev, base_pec,
+					    &dc_lb_pec_regmap_config);
+	if (IS_ERR(lb->reg_pec))
+		return PTR_ERR(lb->reg_pec);
+
+	lb->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+					    &dc_lb_cfg_regmap_config);
+	if (IS_ERR(lb->reg_cfg))
+		return PTR_ERR(lb->reg_cfg);
+
+	lb->link = lb_links[lb->id];
+
+	pe->lb[lb->id] = lb;
+
+	return 0;
+}
+
+static const struct component_ops dc_lb_ops = {
+	.bind = dc_lb_bind,
+};
+
+static int dc_lb_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = component_add(&pdev->dev, &dc_lb_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_lb_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_lb_ops);
+}
+
+static const struct of_device_id dc_lb_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-layerblend0",
+	  .data = (const void *)DC_LB0, },
+	{ .compatible = "fsl,imx8qxp-dc-layerblend1",
+	  .data = (const void *)DC_LB1, },
+	{ .compatible = "fsl,imx8qxp-dc-layerblend2",
+	  .data = (const void *)DC_LB2, },
+	{ .compatible = "fsl,imx8qxp-dc-layerblend3",
+	  .data = (const void *)DC_LB3, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_lb_dt_ids);
+
+struct platform_driver dc_lb_driver = {
+	.probe = dc_lb_probe,
+	.remove = dc_lb_remove,
+	.driver = {
+		.name = "imx8-dc-layerblend",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_lb_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.c b/drivers/gpu/drm/imx/dc/dc-pe.c
new file mode 100644
index 000000000000..459fc3823953
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-pe.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+static int dc_pe_bind(struct device *dev, struct device *master, void *data)
+{
+	struct dc_drm_device *dc_drm = data;
+	struct dc_pe *pe;
+	int ret;
+
+	pe = devm_kzalloc(dev, sizeof(*pe), GFP_KERNEL);
+	if (!pe)
+		return -ENOMEM;
+
+	pe->clk_axi = devm_clk_get(dev, NULL);
+	if (IS_ERR(pe->clk_axi))
+		return dev_err_probe(dev, PTR_ERR(pe->clk_axi),
+				     "failed to get AXI clock\n");
+
+	pe->dev = dev;
+
+	dev_set_drvdata(dev, pe);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	dc_drm->pe = pe;
+
+	return 0;
+}
+
+static const struct component_ops dc_pe_ops = {
+	.bind = dc_pe_bind,
+};
+
+static int dc_pe_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = component_add(&pdev->dev, &dc_pe_ops);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component\n");
+
+	return 0;
+}
+
+static void dc_pe_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dc_pe_ops);
+}
+
+static int dc_pe_runtime_suspend(struct device *dev)
+{
+	struct dc_pe *pe = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(pe->clk_axi);
+
+	return 0;
+}
+
+static int dc_pe_runtime_resume(struct device *dev)
+{
+	struct dc_pe *pe = dev_get_drvdata(dev);
+	int i, ret;
+
+	ret = clk_prepare_enable(pe->clk_axi);
+	if (ret) {
+		dev_err(dev, "failed to enable AXI clock: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pe->cf_safe); i++)
+		dc_cf_init(pe->cf_safe[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->cf_cont); i++)
+		dc_cf_init(pe->cf_cont[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->ed_safe); i++)
+		dc_ed_init(pe->ed_safe[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->ed_cont); i++)
+		dc_ed_init(pe->ed_cont[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->fu_disp); i++)
+		pe->fu_disp[i]->ops.init(pe->fu_disp[i]);
+
+	for (i = 0; i < ARRAY_SIZE(pe->lb); i++)
+		dc_lb_init(pe->lb[i]);
+
+	return 0;
+}
+
+static const struct dev_pm_ops dc_pe_pm_ops = {
+	RUNTIME_PM_OPS(dc_pe_runtime_suspend, dc_pe_runtime_resume, NULL)
+};
+
+static const struct of_device_id dc_pe_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-pixel-engine", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_pe_dt_ids);
+
+struct platform_driver dc_pe_driver = {
+	.probe = dc_pe_probe,
+	.remove = dc_pe_remove,
+	.driver = {
+		.name = "imx8-dc-pixel-engine",
+		.suppress_bind_attrs = true,
+		.of_match_table = dc_pe_dt_ids,
+		.pm = pm_sleep_ptr(&dc_pe_pm_ops),
+	},
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
new file mode 100644
index 000000000000..7951c2d85441
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-pe.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_PIXEL_ENGINE_H__
+#define __DC_PIXEL_ENGINE_H__
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+#include "dc-de.h"
+
+#define SHDEN			BIT(0)
+
+#define CLKEN_MASK_SHIFT	24
+#define CLKEN_MASK		(0x3 << CLKEN_MASK_SHIFT)
+#define CLKEN(n)		((n) << CLKEN_MASK_SHIFT)
+
+#define DC_DISP_FU_CNT		2
+
+enum dc_link_id {
+	LINK_ID_NONE		= 0x00,
+	LINK_ID_CONSTFRAME0	= 0x0c,
+	LINK_ID_CONSTFRAME4	= 0x0e,
+	LINK_ID_CONSTFRAME1	= 0x10,
+	LINK_ID_CONSTFRAME5	= 0x12,
+	LINK_ID_FETCHWARP2	= 0x14,
+	LINK_ID_FETCHLAYER0	= 0x1a,
+	LINK_ID_LAYERBLEND0	= 0x21,
+	LINK_ID_LAYERBLEND1	= 0x22,
+	LINK_ID_LAYERBLEND2	= 0x23,
+	LINK_ID_LAYERBLEND3	= 0x24,
+};
+
+enum dc_lb_id {
+	DC_LB0,
+	DC_LB1,
+	DC_LB2,
+	DC_LB3,
+	DC_LB_CNT
+};
+
+enum dc_lb_mode {
+	LB_NEUTRAL,	/* Output is same as primary input. */
+	LB_BLEND,
+};
+
+enum dc_pec_clken {
+	CLKEN_DISABLE,
+	CLKEN_AUTOMATIC,
+};
+
+struct dc_cf {
+	struct regmap *reg_cfg;
+	enum dc_link_id link;
+};
+
+struct dc_ed {
+	struct device *dev;
+	struct regmap *reg_pec;
+	struct regmap *reg_cfg;
+	int irq_shdld;
+};
+
+struct dc_lb {
+	struct regmap *reg_pec;
+	struct regmap *reg_cfg;
+	int id;
+	enum dc_link_id link;
+};
+
+struct dc_pe {
+	struct device *dev;
+	struct clk *clk_axi;
+	struct dc_cf *cf_safe[DC_DISPLAYS];
+	struct dc_cf *cf_cont[DC_DISPLAYS];
+	struct dc_ed *ed_safe[DC_DISPLAYS];
+	struct dc_ed *ed_cont[DC_DISPLAYS];
+	struct dc_fu *fu_disp[DC_DISP_FU_CNT];
+	struct dc_lb *lb[DC_LB_CNT];
+};
+
+/* Constant Frame Unit */
+enum dc_link_id dc_cf_get_link_id(struct dc_cf *cf);
+void dc_cf_framedimensions(struct dc_cf *cf, unsigned int w, unsigned int h);
+void dc_cf_constantcolor_black(struct dc_cf *cf);
+void dc_cf_constantcolor_blue(struct dc_cf *cf);
+void dc_cf_init(struct dc_cf *cf);
+
+/* External Destination Unit */
+void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src);
+void dc_ed_pec_sync_trigger(struct dc_ed *ed);
+void dc_ed_init(struct dc_ed *ed);
+
+/* Layer Blend Unit */
+enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb);
+void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim);
+void dc_lb_pec_dynamic_sec_sel(struct dc_lb *lb, enum dc_link_id sec);
+void dc_lb_pec_clken(struct dc_lb *lb, enum dc_pec_clken clken);
+void dc_lb_mode(struct dc_lb *lb, enum dc_lb_mode mode);
+void dc_lb_position(struct dc_lb *lb, int x, int y);
+enum dc_lb_id dc_lb_get_id(struct dc_lb *lb);
+void dc_lb_init(struct dc_lb *lb);
+
+#endif /* __DC_PIXEL_ENGINE_H__ */
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:39 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:39 +0800
Subject: [PATCH v7 11/19] drm/imx: Add i.MX8qxp Display Controller interrupt controller
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-12-victor.liu@nxp.com>

i.MX8qxp Display Controller has a built-in interrupt controller to support
Enable/Status/Preset/Clear interrupt bit.  Add driver for it.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Fix regmap_config definition by removing name field, correcting read ranges
  and setting max_register field.
* Collect Maxime's R-b tag.

v6:
* No change.

v5:
* Replace .remove_new with .remove in dc-ic.c. (Uwe)

v4:
* Use regmap to define register map for all registers. (Dmitry)
* Use regmap APIs to access registers. (Dmitry)
* Use devm_kzalloc() to drmm_kzalloc() to allocate dc_ic_data data strutures.
* Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
  interfaces to bind/unbind the driver.
* Take DC interrupt controller driver as a standalone driver instead of a
  component driver.
* Replace drmm_kcalloc() with devm_kcalloc() to allocate an array for
  struct dc_ic_entry.
* Call platform_get_irq() from DC interrupt controller driver to make sure
  parent interrupt controller driver is probed first.

v3:
* No change.

v2:
* No change.

 drivers/gpu/drm/imx/dc/Kconfig  |   1 +
 drivers/gpu/drm/imx/dc/Makefile |   2 +-
 drivers/gpu/drm/imx/dc/dc-drv.c |   1 +
 drivers/gpu/drm/imx/dc/dc-drv.h |   1 +
 drivers/gpu/drm/imx/dc/dc-ic.c  | 282 ++++++++++++++++++++++++++++++++
 5 files changed, 286 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/imx/dc/dc-ic.c

diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
index e1ef76d82830..1fc84c7475de 100644
--- a/drivers/gpu/drm/imx/dc/Kconfig
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -1,6 +1,7 @@
 config DRM_IMX8_DC
 	tristate "Freescale i.MX8 Display Controller Graphics"
 	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
+	select GENERIC_IRQ_CHIP
 	select REGMAP
 	select REGMAP_MMIO
 	help
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index 2942ae6fd5bd..1ce3e8a8db22 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
 imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
-		    dc-fw.o dc-lb.o dc-pe.o dc-tc.o
+		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
 
 obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index 7c64acc863ad..fd68861f770a 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -15,6 +15,7 @@ static struct platform_driver * const dc_drivers[] = {
 	&dc_fg_driver,
 	&dc_fl_driver,
 	&dc_fw_driver,
+	&dc_ic_driver,
 	&dc_lb_driver,
 	&dc_pe_driver,
 	&dc_tc_driver,
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index e618a4228590..01f3c355beba 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -31,6 +31,7 @@ extern struct platform_driver dc_de_driver;
 extern struct platform_driver dc_fg_driver;
 extern struct platform_driver dc_fl_driver;
 extern struct platform_driver dc_fw_driver;
+extern struct platform_driver dc_ic_driver;
 extern struct platform_driver dc_lb_driver;
 extern struct platform_driver dc_pe_driver;
 extern struct platform_driver dc_tc_driver;
diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
new file mode 100644
index 000000000000..66884ce72b5b
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-ic.c
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#define USERINTERRUPTMASK(n)	(0x8 + 4 * (n))
+#define INTERRUPTENABLE(n)	(0x10 + 4 * (n))
+#define INTERRUPTPRESET(n)	(0x18 + 4 * (n))
+#define INTERRUPTCLEAR(n)	(0x20 + 4 * (n))
+#define INTERRUPTSTATUS(n)	(0x28 + 4 * (n))
+#define USERINTERRUPTENABLE(n)	(0x40 + 4 * (n))
+#define USERINTERRUPTPRESET(n)	(0x48 + 4 * (n))
+#define USERINTERRUPTCLEAR(n)	(0x50 + 4 * (n))
+#define USERINTERRUPTSTATUS(n)	(0x58 + 4 * (n))
+
+#define IRQ_COUNT	49
+#define IRQ_RESERVED	35
+#define REG_NUM		2
+
+struct dc_ic_data {
+	struct regmap		*regs;
+	struct clk		*clk_axi;
+	int			irq[IRQ_COUNT];
+	struct irq_domain	*domain;
+};
+
+struct dc_ic_entry {
+	struct dc_ic_data *data;
+	int irq;
+};
+
+static const struct regmap_range dc_ic_regmap_write_ranges[] = {
+	regmap_reg_range(USERINTERRUPTMASK(0), INTERRUPTCLEAR(1)),
+	regmap_reg_range(USERINTERRUPTENABLE(0), USERINTERRUPTCLEAR(1)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_write_table = {
+	.yes_ranges = dc_ic_regmap_write_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_write_ranges),
+};
+
+static const struct regmap_range dc_ic_regmap_read_ranges[] = {
+	regmap_reg_range(USERINTERRUPTMASK(0), INTERRUPTENABLE(1)),
+	regmap_reg_range(INTERRUPTSTATUS(0), INTERRUPTSTATUS(1)),
+	regmap_reg_range(USERINTERRUPTENABLE(0), USERINTERRUPTENABLE(1)),
+	regmap_reg_range(USERINTERRUPTSTATUS(0), USERINTERRUPTSTATUS(1)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_read_table = {
+	.yes_ranges = dc_ic_regmap_read_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_read_ranges),
+};
+
+static const struct regmap_range dc_ic_regmap_volatile_ranges[] = {
+	regmap_reg_range(INTERRUPTPRESET(0), INTERRUPTCLEAR(1)),
+	regmap_reg_range(USERINTERRUPTPRESET(0), USERINTERRUPTCLEAR(1)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_volatile_table = {
+	.yes_ranges = dc_ic_regmap_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_volatile_ranges),
+};
+
+static const struct regmap_config dc_ic_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.wr_table = &dc_ic_regmap_write_table,
+	.rd_table = &dc_ic_regmap_read_table,
+	.volatile_table = &dc_ic_regmap_volatile_table,
+	.max_register = USERINTERRUPTSTATUS(1),
+};
+
+static void dc_ic_irq_handler(struct irq_desc *desc)
+{
+	struct dc_ic_entry *entry = irq_desc_get_handler_data(desc);
+	struct dc_ic_data *data = entry->data;
+	unsigned int status, enable;
+	unsigned int virq;
+
+	chained_irq_enter(irq_desc_get_chip(desc), desc);
+
+	regmap_read(data->regs, USERINTERRUPTSTATUS(entry->irq / 32), &status);
+	regmap_read(data->regs, USERINTERRUPTENABLE(entry->irq / 32), &enable);
+
+	status &= enable;
+
+	if (status & BIT(entry->irq % 32)) {
+		virq = irq_linear_revmap(data->domain, entry->irq);
+		if (virq)
+			generic_handle_irq(virq);
+	}
+
+	chained_irq_exit(irq_desc_get_chip(desc), desc);
+}
+
+static const unsigned long unused_irq[REG_NUM] = {0x00000000, 0xfffe0008};
+
+static int dc_ic_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct irq_chip_generic *gc;
+	struct dc_ic_entry *entry;
+	struct irq_chip_type *ct;
+	struct dc_ic_data *data;
+	void __iomem *base;
+	int i, ret;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	entry = devm_kcalloc(dev, IRQ_COUNT, sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base)) {
+		dev_err(dev, "failed to initialize reg\n");
+		return PTR_ERR(base);
+	}
+
+	data->regs = devm_regmap_init_mmio(dev, base, &dc_ic_regmap_config);
+	if (IS_ERR(data->regs))
+		return PTR_ERR(data->regs);
+
+	data->clk_axi = devm_clk_get(dev, NULL);
+	if (IS_ERR(data->clk_axi))
+		return dev_err_probe(dev, PTR_ERR(data->clk_axi),
+				     "failed to get AXI clock\n");
+
+	for (i = 0; i < IRQ_COUNT; i++) {
+		/* skip the reserved IRQ */
+		if (i == IRQ_RESERVED)
+			continue;
+
+		ret = platform_get_irq(pdev, i);
+		if (ret < 0)
+			return ret;
+	}
+
+	dev_set_drvdata(dev, data);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0) {
+		dev_err(dev, "failed to get runtime PM sync: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < REG_NUM; i++) {
+		/* mask and clear all interrupts */
+		regmap_write(data->regs, USERINTERRUPTENABLE(i), 0x0);
+		regmap_write(data->regs, INTERRUPTENABLE(i), 0x0);
+		regmap_write(data->regs, USERINTERRUPTCLEAR(i), 0xffffffff);
+		regmap_write(data->regs, INTERRUPTCLEAR(i), 0xffffffff);
+
+		/* set all interrupts to user mode */
+		regmap_write(data->regs, USERINTERRUPTMASK(i), 0xffffffff);
+	}
+
+	data->domain = irq_domain_add_linear(dev->of_node, IRQ_COUNT,
+					     &irq_generic_chip_ops, data);
+	if (!data->domain) {
+		dev_err(dev, "failed to create IRQ domain\n");
+		pm_runtime_put(dev);
+		return -ENOMEM;
+	}
+	irq_domain_set_pm_device(data->domain, dev);
+
+	ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, "DC",
+					     handle_level_irq, 0, 0, 0);
+	if (ret) {
+		dev_err(dev, "failed to alloc generic IRQ chips: %d\n", ret);
+		irq_domain_remove(data->domain);
+		pm_runtime_put(dev);
+		return ret;
+	}
+
+	for (i = 0; i < IRQ_COUNT; i += 32) {
+		gc = irq_get_domain_generic_chip(data->domain, i);
+		gc->reg_base = base;
+		gc->unused = unused_irq[i / 32];
+		ct = gc->chip_types;
+		ct->chip.irq_ack = irq_gc_ack_set_bit;
+		ct->chip.irq_mask = irq_gc_mask_clr_bit;
+		ct->chip.irq_unmask = irq_gc_mask_set_bit;
+		ct->regs.ack = USERINTERRUPTCLEAR(i / 32);
+		ct->regs.mask = USERINTERRUPTENABLE(i / 32);
+	}
+
+	for (i = 0; i < IRQ_COUNT; i++) {
+		/* skip the reserved IRQ */
+		if (i == IRQ_RESERVED)
+			continue;
+
+		data->irq[i] = irq_of_parse_and_map(dev->of_node, i);
+
+		entry[i].data = data;
+		entry[i].irq = i;
+
+		irq_set_chained_handler_and_data(data->irq[i],
+						 dc_ic_irq_handler, &entry[i]);
+	}
+
+	return 0;
+}
+
+static void dc_ic_remove(struct platform_device *pdev)
+{
+	struct dc_ic_data *data = dev_get_drvdata(&pdev->dev);
+	int i;
+
+	for (i = 0; i < IRQ_COUNT; i++) {
+		if (i == IRQ_RESERVED)
+			continue;
+
+		irq_set_chained_handler_and_data(data->irq[i], NULL, NULL);
+	}
+
+	irq_domain_remove(data->domain);
+
+	pm_runtime_put_sync(&pdev->dev);
+}
+
+static int dc_ic_runtime_suspend(struct device *dev)
+{
+	struct dc_ic_data *data = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(data->clk_axi);
+
+	return 0;
+}
+
+static int dc_ic_runtime_resume(struct device *dev)
+{
+	struct dc_ic_data *data = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(data->clk_axi);
+	if (ret)
+		dev_err(dev, "failed to enable AXI clock: %d\n", ret);
+
+	return ret;
+}
+
+static const struct dev_pm_ops dc_ic_pm_ops = {
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				      pm_runtime_force_resume)
+	RUNTIME_PM_OPS(dc_ic_runtime_suspend, dc_ic_runtime_resume, NULL)
+};
+
+static const struct of_device_id dc_ic_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc-intc", },
+	{ /* sentinel */ }
+};
+
+struct platform_driver dc_ic_driver = {
+	.probe = dc_ic_probe,
+	.remove = dc_ic_remove,
+	.driver = {
+		.name = "imx8-dc-intc",
+		.suppress_bind_attrs = true,
+		.of_match_table	= dc_ic_dt_ids,
+		.pm = pm_sleep_ptr(&dc_ic_pm_ops),
+	},
+};
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:40 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:40 +0800
Subject: [PATCH v7 12/19] drm/imx: Add i.MX8qxp Display Controller KMS
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-13-victor.liu@nxp.com>

i.MX8qxp Display Controller(DC) is comprised of three main components that
include a blit engine for 2D graphics accelerations, display controller for
display output processing, as well as a command sequencer.  Add kernel
mode setting support for the display controller part with two CRTCs and
two primary planes(backed by FetchLayer and FetchWarp respectively).  The
registers of the display controller are accessed without command sequencer
involved, instead just by using CPU.  The command sequencer is supposed to
be used by the blit engine.

Reviewed-by: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* Drop using typeof in macros and explicitly define variable types. (Dmitry)
* Add a comment for disable_irq_nosync() to explain why _nosync. (Dmitry)
* Inline dc_crtc_check_clock(). (Dmitry)
* Use global drm_dc->pe. (Dmitry)
* Drop dc_crtc_disable_at_unbind(). (Dmitry)
* Add kernel doc for struct dc_{crtc,drm_device,plane}. (Dmitry)
* Define common IRQ handlers separately for each IRQs. (Dmitry)
* Rebase this patch upon next-20241220, so drop date entry from drm_driver
  and correctly include drm/clients/drm_client_setup.h.
* Collect Maxime's R-b tag.

v6:
* No change.

v5:
* Replace .remove_new with .remove in dc-drv.c. (Uwe)

v4:
* Move dc_fg_displaymode(), dc_fg_panic_displaymode() and dc_lb_blendcontrol()
  function calls from KMS routine to initialization stage. (Dmitry)
* Drop dc-crtc.h and dc-plane.h header files and move relevant defines to
  appropriate .h header files or .c source files. (Dmitry)
* Drop futile "else" clause from dc_crtc_common_irq_handler(). (Dmitry)
* Drop dc_drm->pe_rpm_count. (Dmitry)
* Drop DC_{CRTCS,ENCODERS,PRIMARYS} macros and only use DC_DISPLAYS. (Dmitry)
* Drop drmm_kcalloc() function call to allocate an array for storing IRQs.
  Instead, put it in struct dc_crtc.  (Dmitry)
* Call devm_request_irq() to request IRQs, instead of using drmm action.
  (Dmitry)
* Call devm_drm_of_get_bridge() to find the next bridge. (Dmitry)
* Select DRM_CLIENT_SELECTION due to rebase.
* Select the missing DRM_DISPLAY_HELPER and DRM_BRIDGE_CONNECTOR.
* Use DRM_FBDEV_DMA_DRIVER_OPS due to rebase.
* Replace drm_fbdev_dma_setup() with drm_client_setup_with_fourcc() due to
  rebase.
* Replace drmm_add_action_or_reset() with devm_add_action_or_reset() to
  register dc_drm_component_unbind_all() action.
* Request interrupts in dc_crtc_post_init() after encoder initialization to
  make sure next bridge is found first.

v3:
* No change.

v2:
* Find next bridge from TCon's port.
* Drop drm/drm_module.h include from dc-drv.c.

 drivers/gpu/drm/imx/dc/Kconfig    |   5 +
 drivers/gpu/drm/imx/dc/Makefile   |   5 +-
 drivers/gpu/drm/imx/dc/dc-crtc.c  | 556 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/dc/dc-de.h    |   3 +
 drivers/gpu/drm/imx/dc/dc-drv.c   | 238 +++++++++++++
 drivers/gpu/drm/imx/dc/dc-drv.h   |  22 ++
 drivers/gpu/drm/imx/dc/dc-kms.c   | 143 ++++++++
 drivers/gpu/drm/imx/dc/dc-kms.h   | 131 +++++++
 drivers/gpu/drm/imx/dc/dc-plane.c | 241 +++++++++++++
 9 files changed, 1342 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/imx/dc/dc-crtc.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.c
 create mode 100644 drivers/gpu/drm/imx/dc/dc-kms.h
 create mode 100644 drivers/gpu/drm/imx/dc/dc-plane.c

diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
index 1fc84c7475de..415993207f2e 100644
--- a/drivers/gpu/drm/imx/dc/Kconfig
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -1,6 +1,11 @@
 config DRM_IMX8_DC
 	tristate "Freescale i.MX8 Display Controller Graphics"
 	depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
+	select DRM_CLIENT_SELECTION
+	select DRM_GEM_DMA_HELPER
+	select DRM_KMS_HELPER
+	select DRM_DISPLAY_HELPER
+	select DRM_BRIDGE_CONNECTOR
 	select GENERIC_IRQ_CHIP
 	select REGMAP
 	select REGMAP_MMIO
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index 1ce3e8a8db22..b9d33c074984 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
-imx8-dc-drm-objs := dc-cf.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o dc-fu.o \
-		    dc-fw.o dc-ic.o dc-lb.o dc-pe.o dc-tc.o
+imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
+		    dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
+		    dc-plane.o dc-tc.o
 
 obj-$(CONFIG_DRM_IMX8_DC) += imx8-dc-drm.o
diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
new file mode 100644
index 000000000000..519db7634ce9
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
@@ -0,0 +1,556 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/completion.h>
+#include <linux/container_of.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/pm_runtime.h>
+#include <linux/spinlock.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_device.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_print.h>
+#include <drm/drm_vblank.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+#include "dc-kms.h"
+#include "dc-pe.h"
+
+#define dc_crtc_dbg(crtc, fmt, ...)					\
+do {									\
+	struct drm_crtc *_crtc = (crtc);				\
+	drm_dbg_kms(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
+		    _crtc->base.id, _crtc->name, ##__VA_ARGS__);	\
+} while (0)
+
+#define dc_crtc_err(crtc, fmt, ...)					\
+do {									\
+	struct drm_crtc *_crtc = (crtc);				\
+	drm_err(_crtc->dev, "[CRTC:%d:%s] " fmt,			\
+		_crtc->base.id, _crtc->name, ##__VA_ARGS__);		\
+} while (0)
+
+#define DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(c)				\
+do {									\
+	unsigned long ret;						\
+	ret = wait_for_completion_timeout(&dc_crtc->c, HZ);		\
+	if (ret == 0)							\
+		dc_crtc_err(crtc, "%s: wait for " #c " timeout\n",	\
+							__func__);	\
+} while (0)
+
+#define DC_CRTC_CHECK_FRAMEGEN_FIFO(fg)					\
+do {									\
+	struct dc_fg *_fg = (fg);					\
+	if (dc_fg_secondary_requests_to_read_empty_fifo(_fg)) {		\
+		dc_fg_secondary_clear_channel_status(_fg);		\
+		dc_crtc_err(crtc, "%s: FrameGen FIFO empty\n",		\
+							__func__);	\
+	}								\
+} while (0)
+
+#define DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(fg)			\
+do {									\
+	if (dc_fg_wait_for_secondary_syncup(fg))			\
+		dc_crtc_err(crtc,					\
+			"%s: FrameGen secondary channel isn't syncup\n",\
+							__func__);	\
+} while (0)
+
+static inline struct dc_crtc *to_dc_crtc(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct dc_crtc, base);
+}
+
+static u32 dc_crtc_get_vblank_counter(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	return dc_fg_get_frame_index(dc_crtc->fg);
+}
+
+static int dc_crtc_enable_vblank(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	enable_irq(dc_crtc->irq_dec_framecomplete);
+
+	return 0;
+}
+
+static void dc_crtc_disable_vblank(struct drm_crtc *crtc)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	/* nosync due to atomic context */
+	disable_irq_nosync(dc_crtc->irq_dec_framecomplete);
+}
+
+static const struct drm_crtc_funcs dc_crtc_funcs = {
+	.reset			= drm_atomic_helper_crtc_reset,
+	.destroy		= drm_crtc_cleanup,
+	.set_config		= drm_atomic_helper_set_config,
+	.page_flip		= drm_atomic_helper_page_flip,
+	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
+	.get_vblank_counter	= dc_crtc_get_vblank_counter,
+	.enable_vblank		= dc_crtc_enable_vblank,
+	.disable_vblank		= dc_crtc_disable_vblank,
+	.get_vblank_timestamp	= drm_crtc_vblank_helper_get_vblank_timestamp,
+};
+
+static void dc_crtc_queue_state_event(struct drm_crtc_state *crtc_state)
+{
+	struct drm_crtc *crtc = crtc_state->crtc;
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+
+	spin_lock_irq(&crtc->dev->event_lock);
+	if (crtc_state->event) {
+		WARN_ON(drm_crtc_vblank_get(crtc));
+		WARN_ON(dc_crtc->event);
+		dc_crtc->event = crtc_state->event;
+		crtc_state->event = NULL;
+	}
+	spin_unlock_irq(&crtc->dev->event_lock);
+}
+
+static inline enum drm_mode_status
+dc_crtc_check_clock(struct dc_crtc *dc_crtc, int clk_khz)
+{
+	return dc_fg_check_clock(dc_crtc->fg, clk_khz);
+}
+
+static enum drm_mode_status
+dc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	enum drm_mode_status status;
+
+	status = dc_crtc_check_clock(dc_crtc, mode->clock);
+	if (status != MODE_OK)
+		return status;
+
+	if (mode->crtc_clock > DC_FRAMEGEN_MAX_CLOCK_KHZ)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static int
+dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	enum drm_mode_status status;
+
+	status = dc_crtc_check_clock(dc_crtc, adj->clock);
+	if (status != MODE_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void
+dc_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct dc_drm_device *dc_drm = to_dc_drm_device(crtc->dev);
+	int idx, ret;
+
+	if (!drm_atomic_crtc_needs_modeset(new_crtc_state) ||
+	    !new_crtc_state->active)
+		return;
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		return;
+
+	/* request pixel engine power-on when CRTC starts to be active */
+	ret = pm_runtime_resume_and_get(dc_drm->pe->dev);
+	if (ret)
+		dc_crtc_err(crtc, "failed to get DC pixel engine RPM: %d\n",
+			    ret);
+
+	drm_dev_exit(idx);
+}
+
+static void
+dc_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *old_crtc_state =
+				drm_atomic_get_old_crtc_state(state, crtc);
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int idx;
+
+	if (drm_atomic_crtc_needs_modeset(new_crtc_state) ||
+	    (!old_crtc_state->active && !new_crtc_state->active))
+		return;
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		goto out;
+
+	enable_irq(dc_crtc->irq_ed_cont_shdld);
+
+	/* flush plane update out to display */
+	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
+
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
+
+	disable_irq(dc_crtc->irq_ed_cont_shdld);
+
+	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
+
+	drm_dev_exit(idx);
+
+out:
+	dc_crtc_queue_state_event(new_crtc_state);
+}
+
+static void
+dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct drm_display_mode *adj = &new_crtc_state->adjusted_mode;
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	enum dc_link_id cf_link;
+	int idx, ret;
+
+	dc_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
+
+	drm_crtc_vblank_on(crtc);
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		goto out;
+
+	/* request display engine power-on when CRTC is enabled */
+	ret = pm_runtime_resume_and_get(dc_crtc->de->dev);
+	if (ret < 0)
+		dc_crtc_err(crtc, "failed to get DC display engine RPM: %d\n",
+			    ret);
+
+	enable_irq(dc_crtc->irq_dec_shdld);
+	enable_irq(dc_crtc->irq_ed_cont_shdld);
+	enable_irq(dc_crtc->irq_ed_safe_shdld);
+
+	dc_fg_cfg_videomode(dc_crtc->fg, adj);
+
+	dc_cf_framedimensions(dc_crtc->cf_cont,
+			      adj->crtc_hdisplay, adj->crtc_vdisplay);
+	dc_cf_framedimensions(dc_crtc->cf_safe,
+			      adj->crtc_hdisplay, adj->crtc_vdisplay);
+
+	/* constframe in safety stream shows blue frame */
+	dc_cf_constantcolor_blue(dc_crtc->cf_safe);
+	cf_link = dc_cf_get_link_id(dc_crtc->cf_safe);
+	dc_ed_pec_src_sel(dc_crtc->ed_safe, cf_link);
+
+	/* show CRTC background if no plane is enabled */
+	if (new_crtc_state->plane_mask == 0) {
+		/* constframe in content stream shows black frame */
+		dc_cf_constantcolor_black(dc_crtc->cf_cont);
+
+		cf_link = dc_cf_get_link_id(dc_crtc->cf_cont);
+		dc_ed_pec_src_sel(dc_crtc->ed_cont, cf_link);
+	}
+
+	dc_fg_enable_clock(dc_crtc->fg);
+	dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
+	dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
+	dc_fg_shdtokgen(dc_crtc->fg);
+	dc_fg_enable(dc_crtc->fg);
+
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_safe_shdld_done);
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(ed_cont_shdld_done);
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_shdld_done);
+
+	disable_irq(dc_crtc->irq_ed_safe_shdld);
+	disable_irq(dc_crtc->irq_ed_cont_shdld);
+	disable_irq(dc_crtc->irq_dec_shdld);
+
+	DC_CRTC_WAIT_FOR_FRAMEGEN_SECONDARY_SYNCUP(dc_crtc->fg);
+
+	DC_CRTC_CHECK_FRAMEGEN_FIFO(dc_crtc->fg);
+
+	drm_dev_exit(idx);
+
+out:
+	dc_crtc_queue_state_event(new_crtc_state);
+}
+
+static void
+dc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *new_crtc_state =
+				drm_atomic_get_new_crtc_state(state, crtc);
+	struct dc_drm_device *dc_drm = to_dc_drm_device(crtc->dev);
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int idx, ret;
+
+	if (!drm_dev_enter(crtc->dev, &idx))
+		goto out;
+
+	enable_irq(dc_crtc->irq_dec_seqcomplete);
+	dc_fg_disable(dc_crtc->fg);
+	DC_CRTC_WAIT_FOR_COMPLETION_TIMEOUT(dec_seqcomplete_done);
+	disable_irq(dc_crtc->irq_dec_seqcomplete);
+
+	dc_fg_disable_clock(dc_crtc->fg);
+
+	/* request pixel engine power-off as plane is off too */
+	ret = pm_runtime_put(dc_drm->pe->dev);
+	if (ret)
+		dc_crtc_err(crtc, "failed to put DC pixel engine RPM: %d\n",
+			    ret);
+
+	/* request display engine power-off when CRTC is disabled */
+	ret = pm_runtime_put(dc_crtc->de->dev);
+	if (ret < 0)
+		dc_crtc_err(crtc, "failed to put DC display engine RPM: %d\n",
+			    ret);
+
+	drm_dev_exit(idx);
+
+out:
+	drm_crtc_vblank_off(crtc);
+
+	spin_lock_irq(&crtc->dev->event_lock);
+	if (new_crtc_state->event && !new_crtc_state->active) {
+		drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
+		new_crtc_state->event = NULL;
+	}
+	spin_unlock_irq(&crtc->dev->event_lock);
+}
+
+static bool dc_crtc_get_scanout_position(struct drm_crtc *crtc,
+					 bool in_vblank_irq,
+					 int *vpos, int *hpos,
+					 ktime_t *stime, ktime_t *etime,
+					 const struct drm_display_mode *mode)
+{
+	struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
+	int vdisplay = mode->crtc_vdisplay;
+	int vtotal = mode->crtc_vtotal;
+	bool reliable;
+	int line;
+	int idx;
+
+	if (stime)
+		*stime = ktime_get();
+
+	if (!drm_dev_enter(crtc->dev, &idx)) {
+		reliable = false;
+		*vpos = 0;
+		*hpos = 0;
+		goto out;
+	}
+
+	/* line index starts with 0 for the first active output line */
+	line = dc_fg_get_line_index(dc_crtc->fg);
+
+	if (line < vdisplay)
+		/* active scanout area - positive */
+		*vpos = line + 1;
+	else
+		/* inside vblank - negative */
+		*vpos = line - (vtotal - 1);
+
+	*hpos = 0;
+
+	reliable = true;
+
+	drm_dev_exit(idx);
+out:
+	if (etime)
+		*etime = ktime_get();
+
+	return reliable;
+}
+
+static const struct drm_crtc_helper_funcs dc_helper_funcs = {
+	.mode_valid		= dc_crtc_mode_valid,
+	.atomic_check		= dc_crtc_atomic_check,
+	.atomic_begin		= dc_crtc_atomic_begin,
+	.atomic_flush		= dc_crtc_atomic_flush,
+	.atomic_enable		= dc_crtc_atomic_enable,
+	.atomic_disable		= dc_crtc_atomic_disable,
+	.get_scanout_position	= dc_crtc_get_scanout_position,
+};
+
+static irqreturn_t dc_crtc_irq_handler_dec_framecomplete(int irq, void *dev_id)
+{
+	struct dc_crtc *dc_crtc = dev_id;
+	struct drm_crtc *crtc = &dc_crtc->base;
+	unsigned long flags;
+
+	drm_crtc_handle_vblank(crtc);
+
+	spin_lock_irqsave(&crtc->dev->event_lock, flags);
+	if (dc_crtc->event) {
+		drm_crtc_send_vblank_event(crtc, dc_crtc->event);
+		dc_crtc->event = NULL;
+		drm_crtc_vblank_put(crtc);
+	}
+	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+dc_crtc_irq_handler_dec_seqcomplete_done(int irq, void *dev_id)
+{
+	struct dc_crtc *dc_crtc = dev_id;
+
+	complete(&dc_crtc->dec_seqcomplete_done);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dc_crtc_irq_handler_dec_shdld_done(int irq, void *dev_id)
+{
+	struct dc_crtc *dc_crtc = dev_id;
+
+	complete(&dc_crtc->dec_shdld_done);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dc_crtc_irq_handler_ed_cont_shdld_done(int irq, void *dev_id)
+{
+	struct dc_crtc *dc_crtc = dev_id;
+
+	complete(&dc_crtc->ed_cont_shdld_done);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dc_crtc_irq_handler_ed_safe_shdld_done(int irq, void *dev_id)
+{
+	struct dc_crtc *dc_crtc = dev_id;
+
+	complete(&dc_crtc->ed_safe_shdld_done);
+
+	return IRQ_HANDLED;
+}
+
+static int dc_crtc_request_irqs(struct drm_device *drm, struct dc_crtc *dc_crtc)
+{
+	struct {
+		struct device *dev;
+		unsigned int irq;
+		irqreturn_t (*irq_handler)(int irq, void *dev_id);
+	} irqs[DC_CRTC_IRQS] = {
+		{
+			dc_crtc->de->dev,
+			dc_crtc->irq_dec_framecomplete,
+			dc_crtc_irq_handler_dec_framecomplete,
+		}, {
+			dc_crtc->de->dev,
+			dc_crtc->irq_dec_seqcomplete,
+			dc_crtc_irq_handler_dec_seqcomplete_done,
+		}, {
+			dc_crtc->de->dev,
+			dc_crtc->irq_dec_shdld,
+			dc_crtc_irq_handler_dec_shdld_done,
+		}, {
+			dc_crtc->ed_cont->dev,
+			dc_crtc->irq_ed_cont_shdld,
+			dc_crtc_irq_handler_ed_cont_shdld_done,
+		}, {
+			dc_crtc->ed_safe->dev,
+			dc_crtc->irq_ed_safe_shdld,
+			dc_crtc_irq_handler_ed_safe_shdld_done,
+		},
+	};
+	int i, ret;
+
+	for (i = 0; i < DC_CRTC_IRQS; i++) {
+		struct dc_crtc_irq *irq = &dc_crtc->irqs[i];
+
+		ret = devm_request_irq(irqs[i].dev, irqs[i].irq,
+				       irqs[i].irq_handler, IRQF_NO_AUTOEN,
+				       dev_name(irqs[i].dev), dc_crtc);
+		if (ret) {
+			dev_err(irqs[i].dev, "failed to request irq(%u): %d\n",
+				irqs[i].irq, ret);
+			return ret;
+		}
+
+		irq->dc_crtc = dc_crtc;
+		irq->irq = irqs[i].irq;
+	}
+
+	return 0;
+}
+
+int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
+{
+	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
+	struct drm_device *drm = &dc_drm->base;
+	struct dc_de *de = dc_drm->de[crtc_index];
+	struct dc_pe *pe = dc_drm->pe;
+	struct dc_plane *dc_primary;
+	int ret;
+
+	dc_crtc->de = de;
+
+	init_completion(&dc_crtc->dec_seqcomplete_done);
+	init_completion(&dc_crtc->dec_shdld_done);
+	init_completion(&dc_crtc->ed_cont_shdld_done);
+	init_completion(&dc_crtc->ed_safe_shdld_done);
+
+	dc_crtc->cf_cont = pe->cf_cont[crtc_index];
+	dc_crtc->cf_safe = pe->cf_safe[crtc_index];
+	dc_crtc->ed_cont = pe->ed_cont[crtc_index];
+	dc_crtc->ed_safe = pe->ed_safe[crtc_index];
+	dc_crtc->fg = de->fg;
+
+	dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
+	dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
+	dc_crtc->irq_dec_shdld = de->irq_shdld;
+	dc_crtc->irq_ed_safe_shdld = dc_crtc->ed_safe->irq_shdld;
+	dc_crtc->irq_ed_cont_shdld = dc_crtc->ed_cont->irq_shdld;
+
+	dc_primary = &dc_drm->dc_primary[crtc_index];
+	ret = dc_plane_init(dc_drm, dc_primary);
+	if (ret) {
+		dev_err(drm->dev,
+			"failed to init primary plane for display engine%u: %d\n",
+			de->id, ret);
+		return ret;
+	}
+
+	drm_crtc_helper_add(&dc_crtc->base, &dc_helper_funcs);
+
+	ret = drm_crtc_init_with_planes(drm, &dc_crtc->base, &dc_primary->base,
+					NULL, &dc_crtc_funcs, NULL);
+	if (ret)
+		dev_err(drm->dev,
+			"failed to add CRTC for display engine%u: %d\n",
+			de->id, ret);
+
+	return ret;
+}
+
+int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index)
+{
+	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
+	struct drm_device *drm = &dc_drm->base;
+
+	return dc_crtc_request_irqs(drm, dc_crtc);
+}
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
index b504de5589a5..6b9d0c107c0b 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.h
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -13,6 +13,9 @@
 
 #define DC_DISPLAYS	2
 
+#define DC_FRAMEGEN_MAX_FRAME_INDEX	0x3ffff
+#define DC_FRAMEGEN_MAX_CLOCK_KHZ	300000
+
 enum dc_de_id {
 	DC_DE0,
 	DC_DE1,
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index fd68861f770a..986badce0a6f 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -3,11 +3,248 @@
  * Copyright 2024 NXP
  */
 
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
 
+#include <drm/clients/drm_client_setup.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fbdev_dma.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_modeset_helper.h>
+#include <drm/drm_of.h>
+
+#include "dc-de.h"
 #include "dc-drv.h"
 
+struct dc_priv {
+	struct drm_device *drm;
+	struct clk *clk_cfg;
+};
+
+DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
+
+static struct drm_driver dc_drm_driver = {
+	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
+	DRM_GEM_DMA_DRIVER_OPS,
+	DRM_FBDEV_DMA_DRIVER_OPS,
+	.fops = &dc_drm_driver_fops,
+	.name = "imx8-dc",
+	.desc = "i.MX8 DC DRM graphics",
+	.major = 1,
+	.minor = 0,
+	.patchlevel = 0,
+};
+
+static void
+dc_add_components(struct device *dev, struct component_match **matchptr)
+{
+	struct device_node *child, *grandchild;
+
+	for_each_available_child_of_node(dev->of_node, child) {
+		/* The interrupt controller is not a component. */
+		if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
+			continue;
+
+		drm_of_component_match_add(dev, matchptr, component_compare_of,
+					   child);
+
+		for_each_available_child_of_node(child, grandchild)
+			drm_of_component_match_add(dev, matchptr,
+						   component_compare_of,
+						   grandchild);
+	}
+}
+
+static void dc_drm_component_unbind_all(void *ptr)
+{
+	struct dc_drm_device *dc_drm = ptr;
+	struct drm_device *drm = &dc_drm->base;
+
+	component_unbind_all(drm->dev, dc_drm);
+}
+
+static int dc_drm_bind(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+	struct dc_drm_device *dc_drm;
+	struct drm_device *drm;
+	int ret;
+
+	dc_drm = devm_drm_dev_alloc(dev, &dc_drm_driver, struct dc_drm_device,
+				    base);
+	if (IS_ERR(dc_drm))
+		return PTR_ERR(dc_drm);
+
+	drm = &dc_drm->base;
+
+	ret = component_bind_all(dev, dc_drm);
+	if (ret)
+		return ret;
+
+	ret = devm_add_action_or_reset(dev, dc_drm_component_unbind_all,
+				       dc_drm);
+	if (ret)
+		return ret;
+
+	ret = dc_kms_init(dc_drm);
+	if (ret)
+		return ret;
+
+	ret = drm_dev_register(drm, 0);
+	if (ret) {
+		dev_err(dev, "failed to register drm device: %d\n", ret);
+		goto err;
+	}
+
+	drm_client_setup_with_fourcc(drm, DRM_FORMAT_XRGB8888);
+
+	priv->drm = drm;
+
+	return 0;
+
+err:
+	dc_kms_uninit(dc_drm);
+
+	return ret;
+}
+
+static void dc_drm_unbind(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+	struct dc_drm_device *dc_drm = to_dc_drm_device(priv->drm);
+	struct drm_device *drm = &dc_drm->base;
+
+	priv->drm = NULL;
+	drm_dev_unplug(drm);
+	dc_kms_uninit(dc_drm);
+	drm_atomic_helper_shutdown(drm);
+}
+
+static const struct component_master_ops dc_drm_ops = {
+	.bind = dc_drm_bind,
+	.unbind = dc_drm_unbind,
+};
+
+static int dc_probe(struct platform_device *pdev)
+{
+	struct component_match *match = NULL;
+	struct dc_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->clk_cfg))
+		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
+				     "failed to get cfg clock\n");
+
+	dev_set_drvdata(&pdev->dev, priv);
+
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret)
+		return ret;
+
+	dc_add_components(&pdev->dev, &match);
+
+	ret = component_master_add_with_match(&pdev->dev, &dc_drm_ops, match);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to add component master\n");
+
+	return 0;
+}
+
+static void dc_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &dc_drm_ops);
+}
+
+static int dc_runtime_suspend(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(priv->clk_cfg);
+
+	return 0;
+}
+
+static int dc_runtime_resume(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(priv->clk_cfg);
+	if (ret)
+		dev_err(dev, "failed to enable cfg clock: %d\n", ret);
+
+	return ret;
+}
+
+static int dc_suspend(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+
+	return drm_mode_config_helper_suspend(priv->drm);
+}
+
+static int dc_resume(struct device *dev)
+{
+	struct dc_priv *priv = dev_get_drvdata(dev);
+
+	return drm_mode_config_helper_resume(priv->drm);
+}
+
+static void dc_shutdown(struct platform_device *pdev)
+{
+	struct dc_priv *priv = dev_get_drvdata(&pdev->dev);
+
+	drm_atomic_helper_shutdown(priv->drm);
+}
+
+static const struct dev_pm_ops dc_pm_ops = {
+	RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
+	SYSTEM_SLEEP_PM_OPS(dc_suspend, dc_resume)
+};
+
+static const struct of_device_id dc_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-dc", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_dt_ids);
+
+static struct platform_driver dc_driver = {
+	.probe = dc_probe,
+	.remove = dc_remove,
+	.shutdown = dc_shutdown,
+	.driver = {
+		.name = "imx8-dc",
+		.of_match_table	= dc_dt_ids,
+		.pm = pm_sleep_ptr(&dc_pm_ops),
+	},
+};
+
 static struct platform_driver * const dc_drivers[] = {
 	&dc_cf_driver,
 	&dc_de_driver,
@@ -19,6 +256,7 @@ static struct platform_driver * const dc_drivers[] = {
 	&dc_lb_driver,
 	&dc_pe_driver,
 	&dc_tc_driver,
+	&dc_driver,
 };
 
 static int __init dc_drm_init(void)
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index 01f3c355beba..34d2b927fe43 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -6,11 +6,14 @@
 #ifndef __DC_DRV_H__
 #define __DC_DRV_H__
 
+#include <linux/container_of.h>
 #include <linux/platform_device.h>
 
 #include <drm/drm_device.h>
+#include <drm/drm_encoder.h>
 
 #include "dc-de.h"
+#include "dc-kms.h"
 #include "dc-pe.h"
 
 /**
@@ -19,12 +22,31 @@
 struct dc_drm_device {
 	/** @base: base drm_device structure */
 	struct drm_device base;
+	/** @dc_crtc: DC specific CRTC list */
+	struct dc_crtc dc_crtc[DC_DISPLAYS];
+	/** @dc_primary: DC specific primary plane list */
+	struct dc_plane dc_primary[DC_DISPLAYS];
+	/** @encoder: encoder list */
+	struct drm_encoder encoder[DC_DISPLAYS];
 	/** @de: display engine list */
 	struct dc_de *de[DC_DISPLAYS];
 	/** @pe: pixel engine */
 	struct dc_pe *pe;
 };
 
+static inline struct dc_drm_device *to_dc_drm_device(struct drm_device *drm)
+{
+	return container_of(drm, struct dc_drm_device, base);
+}
+
+int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index);
+int dc_crtc_post_init(struct dc_drm_device *dc_drm, int crtc_index);
+
+int dc_kms_init(struct dc_drm_device *dc_drm);
+void dc_kms_uninit(struct dc_drm_device *dc_drm);
+
+int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
+
 extern struct platform_driver dc_cf_driver;
 extern struct platform_driver dc_ed_driver;
 extern struct platform_driver dc_de_driver;
diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
new file mode 100644
index 000000000000..2b18aa37a4a8
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-kms.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/of.h>
+#include <linux/of_graph.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_device.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_mode_config.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_vblank.h>
+
+#include "dc-de.h"
+#include "dc-drv.h"
+#include "dc-kms.h"
+
+static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
+	.fb_create = drm_gem_fb_create,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
+};
+
+static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
+					int crtc_index)
+{
+	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
+	struct drm_device *drm = &dc_drm->base;
+	struct drm_crtc *crtc = &dc_crtc->base;
+	struct drm_connector *connector;
+	struct device *dev = drm->dev;
+	struct drm_encoder *encoder;
+	struct drm_bridge *bridge;
+	int ret;
+
+	bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
+					0, 0);
+	if (IS_ERR(bridge)) {
+		ret = PTR_ERR(bridge);
+		if (ret == -ENODEV)
+			return 0;
+
+		return dev_err_probe(dev, ret,
+				     "failed to find bridge for CRTC%u\n",
+				     crtc->index);
+	}
+
+	encoder = &dc_drm->encoder[crtc_index];
+	ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
+	if (ret) {
+		dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
+			crtc->index, ret);
+		return ret;
+	}
+
+	encoder->possible_crtcs = drm_crtc_mask(crtc);
+
+	ret = drm_bridge_attach(encoder, bridge, NULL,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret) {
+		dev_err(dev,
+			"failed to attach bridge to encoder for CRTC%u: %d\n",
+			crtc->index, ret);
+		return ret;
+	}
+
+	connector = drm_bridge_connector_init(drm, encoder);
+	if (IS_ERR(connector)) {
+		ret = PTR_ERR(connector);
+		dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
+			crtc->index, ret);
+		return ret;
+	}
+
+	ret = drm_connector_attach_encoder(connector, encoder);
+	if (ret)
+		dev_err(dev,
+			"failed to attach encoder to connector for CRTC%u: %d\n",
+			crtc->index, ret);
+
+	return ret;
+}
+
+int dc_kms_init(struct dc_drm_device *dc_drm)
+{
+	struct drm_device *drm = &dc_drm->base;
+	int ret, i;
+
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
+
+	drm->mode_config.min_width = 60;
+	drm->mode_config.min_height = 60;
+	drm->mode_config.max_width = 8192;
+	drm->mode_config.max_height = 8192;
+	drm->mode_config.funcs = &dc_drm_mode_config_funcs;
+
+	drm->vblank_disable_immediate = true;
+	drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
+
+	for (i = 0; i < DC_DISPLAYS; i++) {
+		ret = dc_crtc_init(dc_drm, i);
+		if (ret)
+			return ret;
+
+		ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < DC_DISPLAYS; i++) {
+		ret = dc_crtc_post_init(dc_drm, i);
+		if (ret)
+			return ret;
+	}
+
+	ret = drm_vblank_init(drm, DC_DISPLAYS);
+	if (ret) {
+		dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
+		return ret;
+	}
+
+	drm_mode_config_reset(drm);
+
+	drm_kms_helper_poll_init(drm);
+
+	return 0;
+}
+
+void dc_kms_uninit(struct dc_drm_device *dc_drm)
+{
+	drm_kms_helper_poll_fini(&dc_drm->base);
+}
diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
new file mode 100644
index 000000000000..4ebfbb07a5e9
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-kms.h
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DC_KMS_H__
+#define __DC_KMS_H__
+
+#include <linux/completion.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_vblank.h>
+
+#include "dc-de.h"
+#include "dc-fu.h"
+#include "dc-pe.h"
+
+#define DC_CRTC_IRQS	5
+
+struct dc_crtc_irq {
+	struct dc_crtc *dc_crtc;
+	unsigned int irq;
+};
+
+/**
+ * struct dc_crtc - DC specific drm_crtc
+ *
+ * Each display controller contains one content stream and one safety stream.
+ * In general, the two streams have the same functionality. One stream is
+ * overlaid on the other by @fg. This driver chooses to generate black constant
+ * color from the content stream as background color, build plane(s) on the
+ * content stream by using layerblend(s) and always generate a constant color
+ * from the safety stream. Note that due to the decoupled timing, the safety
+ * stream still works to show the constant color properly even when the content
+ * stream has completely hung up due to mal-function of this driver.
+ */
+struct dc_crtc {
+	/** @base: base drm_crtc structure */
+	struct drm_crtc base;
+	/** @de: display engine */
+	struct dc_de *de;
+	/** @cf_cont: content stream constframe */
+	struct dc_cf *cf_cont;
+	/** @cf_safe: safety stream constframe */
+	struct dc_cf *cf_safe;
+	/** @ed_cont: content stream extdst */
+	struct dc_ed *ed_cont;
+	/** @ed_safe: safety stream extdst */
+	struct dc_ed *ed_safe;
+	/** @fg: framegen */
+	struct dc_fg *fg;
+	/**
+	 * @irq_dec_framecomplete:
+	 *
+	 * display engine configuration frame complete interrupt
+	 */
+	unsigned int irq_dec_framecomplete;
+	/**
+	 * @irq_dec_seqcomplete:
+	 *
+	 * display engine configuration sequence complete interrupt
+	 */
+	unsigned int irq_dec_seqcomplete;
+	/**
+	 * @irq_dec_shdld:
+	 *
+	 * display engine configuration shadow load interrupt
+	 */
+	unsigned int irq_dec_shdld;
+	/**
+	 * @irq_ed_cont_shdld:
+	 *
+	 * content stream extdst shadow load interrupt
+	 */
+	unsigned int irq_ed_cont_shdld;
+	/**
+	 * @irq_ed_safe_shdld:
+	 *
+	 * safety stream extdst shadow load interrupt
+	 */
+	unsigned int irq_ed_safe_shdld;
+	/**
+	 * @dec_seqcomplete_done:
+	 *
+	 * display engine configuration sequence completion
+	 */
+	struct completion dec_seqcomplete_done;
+	/**
+	 * @dec_shdld_done:
+	 *
+	 * display engine configuration shadow load completion
+	 */
+	struct completion dec_shdld_done;
+	/**
+	 * @ed_cont_shdld_done:
+	 *
+	 * content stream extdst shadow load completion
+	 */
+	struct completion ed_cont_shdld_done;
+	/**
+	 * @ed_safe_shdld_done:
+	 *
+	 * safety stream extdst shadow load completion
+	 */
+	struct completion ed_safe_shdld_done;
+	/** @event: cached pending vblank event */
+	struct drm_pending_vblank_event *event;
+	/** @irqs: interrupt list */
+	struct dc_crtc_irq irqs[DC_CRTC_IRQS];
+};
+
+/**
+ * struct dc_plane - DC specific drm_plane
+ *
+ * Build a plane on content stream with a fetchunit and a layerblend.
+ */
+struct dc_plane {
+	/** @base: base drm_plane structure */
+	struct drm_plane base;
+	/** @fu: fetchunit */
+	struct dc_fu *fu;
+	/** @cf: content stream constframe */
+	struct dc_cf *cf;
+	/** @lb: layerblend */
+	struct dc_lb *lb;
+	/** @ed: content stream extdst */
+	struct dc_ed *ed;
+};
+
+#endif /* __DC_KMS_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
new file mode 100644
index 000000000000..0ccd77d2daae
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-plane.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <linux/container_of.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fb_dma_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_print.h>
+
+#include "dc-drv.h"
+#include "dc-fu.h"
+#include "dc-kms.h"
+
+#define DC_PLANE_MAX_PITCH	0x10000
+#define DC_PLANE_MAX_PIX_CNT	8192
+
+#define dc_plane_dbg(plane, fmt, ...)					\
+do {									\
+	struct drm_plane *_plane = (plane);				\
+	drm_dbg_kms(_plane->dev, "[PLANE:%d:%s] " fmt,			\
+		    _plane->base.id, _plane->name, ##__VA_ARGS__);	\
+} while (0)
+
+static const uint32_t dc_plane_formats[] = {
+	DRM_FORMAT_XRGB8888,
+};
+
+static const struct drm_plane_funcs dc_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,
+};
+
+static inline struct dc_plane *to_dc_plane(struct drm_plane *plane)
+{
+	return container_of(plane, struct dc_plane, base);
+}
+
+static int dc_plane_check_no_off_screen(struct drm_plane_state *state,
+					struct drm_crtc_state *crtc_state)
+{
+	if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
+	    state->dst.x2 > crtc_state->adjusted_mode.hdisplay ||
+	    state->dst.y2 > crtc_state->adjusted_mode.vdisplay) {
+		dc_plane_dbg(state->plane, "no off screen\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dc_plane_check_max_source_resolution(struct drm_plane_state *state)
+{
+	int src_h = drm_rect_height(&state->src) >> 16;
+	int src_w = drm_rect_width(&state->src) >> 16;
+
+	if (src_w > DC_PLANE_MAX_PIX_CNT || src_h > DC_PLANE_MAX_PIX_CNT) {
+		dc_plane_dbg(state->plane, "invalid source resolution\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dc_plane_check_fb(struct drm_plane_state *state)
+{
+	struct drm_framebuffer *fb = state->fb;
+	dma_addr_t baseaddr = drm_fb_dma_get_gem_addr(fb, state, 0);
+
+	/* base address alignment */
+	if (baseaddr & 0x3) {
+		dc_plane_dbg(state->plane, "fb bad baddr alignment\n");
+		return -EINVAL;
+	}
+
+	/* pitches[0] range */
+	if (fb->pitches[0] > DC_PLANE_MAX_PITCH) {
+		dc_plane_dbg(state->plane, "fb pitches[0] is out of range\n");
+		return -EINVAL;
+	}
+
+	/* pitches[0] alignment */
+	if (fb->pitches[0] & 0x3) {
+		dc_plane_dbg(state->plane, "fb bad pitches[0] alignment\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+dc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
+{
+	struct drm_plane_state *plane_state =
+				drm_atomic_get_new_plane_state(state, plane);
+	struct drm_crtc_state *crtc_state;
+	int ret;
+
+	/* ok to disable */
+	if (!plane_state->fb)
+		return 0;
+
+	if (!plane_state->crtc) {
+		dc_plane_dbg(plane, "no CRTC in plane state\n");
+		return -EINVAL;
+	}
+
+	crtc_state =
+		drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return -EINVAL;
+
+	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
+						  DRM_PLANE_NO_SCALING,
+						  DRM_PLANE_NO_SCALING,
+						  true, false);
+	if (ret) {
+		dc_plane_dbg(plane, "failed to check plane state: %d\n", ret);
+		return ret;
+	}
+
+	ret = dc_plane_check_no_off_screen(plane_state, crtc_state);
+	if (ret)
+		return ret;
+
+	ret = dc_plane_check_max_source_resolution(plane_state);
+	if (ret)
+		return ret;
+
+	return dc_plane_check_fb(plane_state);
+}
+
+static void
+dc_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_state =
+				drm_atomic_get_new_plane_state(state, plane);
+	struct dc_plane *dplane = to_dc_plane(plane);
+	struct drm_framebuffer *fb = new_state->fb;
+	const struct dc_fu_ops *fu_ops;
+	struct dc_lb *lb = dplane->lb;
+	struct dc_fu *fu = dplane->fu;
+	dma_addr_t baseaddr;
+	int src_w, src_h;
+	int idx;
+
+	if (!drm_dev_enter(plane->dev, &idx))
+		return;
+
+	src_w = drm_rect_width(&new_state->src) >> 16;
+	src_h = drm_rect_height(&new_state->src) >> 16;
+
+	baseaddr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
+
+	fu_ops = dc_fu_get_ops(dplane->fu);
+
+	fu_ops->set_layerblend(fu, lb);
+	fu_ops->set_burstlength(fu, baseaddr);
+	fu_ops->set_src_stride(fu, DC_FETCHUNIT_FRAC0, fb->pitches[0]);
+	fu_ops->set_src_buf_dimensions(fu, DC_FETCHUNIT_FRAC0, src_w, src_h);
+	fu_ops->set_fmt(fu, DC_FETCHUNIT_FRAC0, fb->format);
+	fu_ops->set_framedimensions(fu, src_w, src_h);
+	fu_ops->set_baseaddress(fu, DC_FETCHUNIT_FRAC0, baseaddr);
+	fu_ops->enable_src_buf(fu, DC_FETCHUNIT_FRAC0);
+
+	dc_plane_dbg(plane, "uses %s\n", fu_ops->get_name(fu));
+
+	dc_lb_pec_dynamic_prim_sel(lb, dc_cf_get_link_id(dplane->cf));
+	dc_lb_pec_dynamic_sec_sel(lb, fu_ops->get_link_id(fu));
+	dc_lb_mode(lb, LB_BLEND);
+	dc_lb_position(lb, new_state->dst.x1, new_state->dst.y1);
+	dc_lb_pec_clken(lb, CLKEN_AUTOMATIC);
+
+	dc_plane_dbg(plane, "uses LayerBlend%d\n", dc_lb_get_id(lb));
+
+	/* set ExtDst's source to LayerBlend */
+	dc_ed_pec_src_sel(dplane->ed, dc_lb_get_link_id(lb));
+
+	drm_dev_exit(idx);
+}
+
+static void dc_plane_atomic_disable(struct drm_plane *plane,
+				    struct drm_atomic_state *state)
+{
+	struct dc_plane *dplane = to_dc_plane(plane);
+	const struct dc_fu_ops *fu_ops;
+	int idx;
+
+	if (!drm_dev_enter(plane->dev, &idx))
+		return;
+
+	/* disable fetchunit in shadow */
+	fu_ops = dc_fu_get_ops(dplane->fu);
+	fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
+
+	/* set ExtDst's source to ConstFrame */
+	dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
+
+	drm_dev_exit(idx);
+}
+
+static const struct drm_plane_helper_funcs dc_plane_helper_funcs = {
+	.atomic_check = dc_plane_atomic_check,
+	.atomic_update = dc_plane_atomic_update,
+	.atomic_disable = dc_plane_atomic_disable,
+};
+
+int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
+{
+	struct drm_plane *plane = &dc_plane->base;
+	int ret;
+
+	ret = drm_universal_plane_init(&dc_drm->base, plane, 0, &dc_plane_funcs,
+				       dc_plane_formats,
+				       ARRAY_SIZE(dc_plane_formats),
+				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
+	if (ret)
+		return ret;
+
+	drm_plane_helper_add(plane, &dc_plane_helper_funcs);
+
+	dc_plane->fu = dc_drm->pe->fu_disp[plane->index];
+	dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
+	dc_plane->lb = dc_drm->pe->lb[plane->index];
+	dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
+
+	return 0;
+}
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:41 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:41 +0800
Subject: [PATCH v7 13/19] MAINTAINERS: Add maintainer for i.MX8qxp Display Controller
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-14-victor.liu@nxp.com>

Add myself as the maintainer of i.MX8qxp Display Controller.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* No change.

v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* Improve file list. (Frank)

 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d2ab799a0659..0459878925df 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7735,6 +7735,14 @@ F:	Documentation/devicetree/bindings/display/imx/
 F:	drivers/gpu/drm/imx/ipuv3/
 F:	drivers/gpu/ipu-v3/
 
+DRM DRIVERS FOR FREESCALE IMX8 DISPLAY CONTROLLER
+M:	Liu Ying <victor.liu at nxp.com>
+L:	dri-devel at lists.freedesktop.org
+S:	Maintained
+T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
+F:	Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc*.yaml
+F:	drivers/gpu/drm/imx/dc/
+
 DRM DRIVERS FOR FREESCALE IMX BRIDGE
 M:	Liu Ying <victor.liu at nxp.com>
 L:	dri-devel at lists.freedesktop.org
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:42 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:42 +0800
Subject: [DO NOT MERGE PATCH v7 14/19] dt-bindings: phy: mixel, mipi-dsi-phy: Allow assigned-clock* properties
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-15-victor.liu@nxp.com>

assigned-clock* properties can be used by default now, so allow them.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* No change.

v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch as needed by MIPI/LVDS subsystems device tree.

 .../devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml          | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
index 3c28ec50f097..286a4fcc977d 100644
--- a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
@@ -72,11 +72,6 @@ allOf:
           contains:
             const: fsl,imx8qxp-mipi-dphy
     then:
-      properties:
-        assigned-clocks: false
-        assigned-clock-parents: false
-        assigned-clock-rates: false
-
       required:
         - fsl,syscon
 
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:43 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:43 +0800
Subject: [DO NOT MERGE PATCH v7 15/19] dt-bindings: firmware: imx: Add SCU controlled display pixel link nodes
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-16-victor.liu@nxp.com>

Document SCU controlled display pixel link child nodes.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* No change.

v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch as needed by display controller subsystem device tree.

 .../devicetree/bindings/firmware/fsl,scu.yaml | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
index 557e524786c2..1a920f013ad2 100644
--- a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
+++ b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
@@ -30,6 +30,26 @@ properties:
       Clock controller node that provides the clocks controlled by the SCU
     $ref: /schemas/clock/fsl,scu-clk.yaml
 
+  dc0-pixel-link0:
+    description:
+      Display pixel link0 in display controller subsystem0 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
+  dc0-pixel-link1:
+    description:
+      Display pixel link1 in display controller subsystem0 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
+  dc1-pixel-link0:
+    description:
+      Display pixel link0 in display controller subsystem1 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
+  dc1-pixel-link1:
+    description:
+      Display pixel link1 in display controller subsystem1 controlled by the SCU
+    $ref: /schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml
+
   gpio:
     description:
       Control the GPIO PINs on SCU domain over the firmware APIs
-- 
2.34.1



From victor.liu at nxp.com  Sun Dec 22 22:41:45 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 23 Dec 2024 14:41:45 +0800
Subject: [DO NOT MERGE PATCH v7 17/19] arm64: dts: imx8qxp: Add MIPI-LVDS combo subsystems
In-Reply-To: <20241223064147.3961652-1-victor.liu@nxp.com>
References: <20241223064147.3961652-1-victor.liu@nxp.com>
Message-ID: <20241223064147.3961652-18-victor.liu@nxp.com>

The MIPI-LVDS combo subsystems are peripherals of pixel link MSI
bus in i.MX8qxp display controller subsystem.  Add the MIPI-LVDS
combo subsystems.

Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v7:
* No change.

v6:
* No change.

v5:
* No change.

v4:
* No change.

v3:
* No change.

v2:
* New patch. (Francesco)

 .../boot/dts/freescale/imx8qxp-ss-dc.dtsi     |   4 +
 .../dts/freescale/imx8qxp-ss-mipi-lvds.dtsi   | 437 ++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   3 +
 3 files changed, 444 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
index ab84ae3198c8..4a3e4724be75 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-dc.dtsi
@@ -152,10 +152,12 @@ port at 1 {
 
 				dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint at 0 {
 					reg = <0>;
+					remote-endpoint = <&mipi_lvds_0_pxl2dpi_dc0_pixel_link0>;
 				};
 
 				dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint at 1 {
 					reg = <1>;
+					remote-endpoint = <&mipi_lvds_1_pxl2dpi_dc0_pixel_link0>;
 				};
 			};
 
@@ -207,10 +209,12 @@ port at 1 {
 
 				dc0_pixel_link1_mipi_lvds_1_pxl2dpi: endpoint at 0 {
 					reg = <0>;
+					remote-endpoint = <&mipi_lvds_1_pxl2dpi_dc0_pixel_link1>;
 				};
 
 				dc0_pixel_link1_mipi_lvds_0_pxl2dpi: endpoint at 1 {
 					reg = <1>;
+					remote-endpoint = <&mipi_lvds_0_pxl2dpi_dc0_pixel_link1>;
 				};
 			};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi
new file mode 100644
index 000000000000..fa7e7c33518e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-mipi-lvds.dtsi
@@ -0,0 +1,437 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/firmware/imx/rsrc.h>
+
+/ {
+	mipi_lvds_0_ipg_clk: clock-mipi-lvds0-ipg {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <120000000>;
+		clock-output-names = "mipi_lvds_0_ipg_clk";
+	};
+
+	mipi_lvds_1_ipg_clk: clock-mipi-lvds1-ipg {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <120000000>;
+		clock-output-names = "mipi_lvds_1_ipg_clk";
+	};
+};
+
+&dc0_pl_msi_bus {
+	mipi_lvds_0_irqsteer: interrupt-controller at 56220000 {
+		compatible = "fsl,imx-irqsteer";
+		reg = <0x56220000 0x1000>;
+		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		#interrupt-cells = <1>;
+		clocks = <&mipi_lvds_0_lis_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+		fsl,channel = <0>;
+		fsl,num-irqs = <32>;
+	};
+
+	mipi_lvds_0_csr: syscon at 56221000 {
+		compatible = "fsl,imx8qxp-mipi-lvds-csr", "syscon", "simple-mfd";
+		reg = <0x56221000 0x1000>;
+		clocks = <&mipi_lvds_0_di_mipi_lvds_regs_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+
+		mipi_lvds_0_pxl2dpi: pxl2dpi {
+			compatible = "fsl,imx8qxp-pxl2dpi";
+			fsl,sc-resource = <IMX_SC_R_MIPI_0>;
+			power-domains = <&pd IMX_SC_R_MIPI_0>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					mipi_lvds_0_pxl2dpi_dc0_pixel_link0: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&dc0_pixel_link0_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_0_pxl2dpi_dc0_pixel_link1: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&dc0_pixel_link1_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+
+				port at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+			};
+		};
+
+		mipi_lvds_0_ldb: ldb {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,imx8qxp-ldb";
+			clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>,
+				 <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+			clock-names = "pixel", "bypass";
+			assigned-clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>;
+			assigned-clock-parents = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+			power-domains = <&pd IMX_SC_R_LVDS_0>;
+			status = "disabled";
+
+			channel at 0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				phys = <&mipi_lvds_0_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0>;
+					};
+				};
+			};
+
+			channel at 1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <1>;
+				phys = <&mipi_lvds_0_phy>;
+				phy-names = "lvds_phy";
+				status = "disabled";
+
+				port at 0 {
+					reg = <0>;
+
+					mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi: endpoint {
+						remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1>;
+					};
+				};
+			};
+		};
+	};
+
+	mipi_lvds_0_lis_lpcg: clock-controller at 56223000 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56223000 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_0_lis_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0>;
+	};
+
+	mipi_lvds_0_di_mipi_lvds_regs_lpcg: clock-controller at 56223004 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56223004 0x4>;
+		#clock-cells = <1>;
+		clocks = <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_0_di_mipi_lvds_regs_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0>;
+	};
+
+	mipi_lvds_0_pwm_lpcg: clock-controller at 5622300c {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x5622300c 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_0_PWM_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_0_ipg_clk>,
+			 <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>,
+				<IMX_LPCG_CLK_1>;
+		clock-output-names = "mipi_lvds_0_pwm_lpcg_clk",
+				     "mipi_lvds_0_pwm_lpcg_ipg_clk",
+				     "mipi_lvds_0_pwm_lpcg_32k_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0_PWM_0>;
+	};
+
+	mipi_lvds_0_i2c0_lpcg: clock-controller at 56223010 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x56223010 0x4>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_MIPI_0_I2C_0 IMX_SC_PM_CLK_PER>,
+			 <&mipi_lvds_0_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>,
+				<IMX_LPCG_CLK_4>;
+		clock-output-names = "mipi_lvds_0_i2c0_lpcg_clk",
+				     "mipi_lvds_0_i2c0_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_MIPI_0_I2C_0>;
+	};
+
+	mipi_lvds_0_pwm: pwm at 56224000 {
+		compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
+		reg = <0x56224000 0x1000>;
+		interrupt-parent = <&mipi_lvds_0_irqsteer>;
+		interrupts = <12>;
+		clocks = <&mipi_lvds_0_pwm_lpcg IMX_LPCG_CLK_4>,
+			 <&mipi_lvds_0_pwm_lpcg IMX_LPCG_CLK_0>;
+		clock-names = "ipg", "per";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_0_PWM_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		#pwm-cells = <3>;
+		power-domains = <&pd IMX_SC_R_MIPI_0_PWM_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_0_i2c0: i2c at 56226000 {
+		compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x56226000 0x1000>;
+		interrupt-parent = <&mipi_lvds_0_irqsteer>;
+		interrupts = <8>;
+		clocks = <&mipi_lvds_0_i2c0_lpcg IMX_LPCG_CLK_0>,
+			 <&mipi_lvds_0_i2c0_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX_SC_R_MIPI_0_I2C_0 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd IMX_SC_R_MIPI_0_I2C_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_0_phy: phy at 56228300 {
+		compatible = "fsl,imx8qxp-mipi-dphy";
+		reg = <0x56228300 0x100>;
+		clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_PHY>;
+		clock-names = "phy_ref";
+		assigned-clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_PHY>;
+		assigned-clock-parents = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+		#phy-cells = <0>;
+		fsl,syscon = <&mipi_lvds_0_csr>;
+		power-domains = <&pd IMX_SC_R_MIPI_0>;
+		status = "disabled";
+	};
+
+	mipi_lvds_1_irqsteer: interrupt-controller at 56240000 {
+		compatible = "fsl,imx-irqsteer";
+		reg = <0x56240000 0x1000>;
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		interrupt-parent = <&gic>;
+		#interrupt-cells = <1>;
+		clocks = <&mipi_lvds_1_lis_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+		fsl,channel = <0>;
+		fsl,num-irqs = <32>;
+	};
+
+	mipi_lvds_1_csr: syscon at 56241000 {
+		compatible = "fsl,imx8qxp-mipi-lvds-csr", "syscon", "simple-mfd";
+		reg = <0x56241000 0x1000>;
+		clocks = <&mipi_lvds_1_di_mipi_lvds_regs_lpcg IMX_LPCG_CLK_4>;
+		clock-names = "ipg";
+
+		mipi_lvds_1_pxl2dpi: pxl2dpi {
+			compatible = "fsl,imx8qxp-pxl2dpi";
+			fsl,sc-resource = <IMX_SC_R_MIPI_1>;
+			power-domains = <&pd IMX_SC_R_MIPI_1>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					mipi_lvds_1_pxl2dpi_dc0_pixel_link1: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&dc0_pixel_link1_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_1_pxl2dpi_dc0_pixel_link0: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&dc0_pixel_link0_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+
+				port at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch0: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&mipi_lvds_1_ldb_ch0_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+
+					mipi_lvds_1_pxl2dpi_mipi_lvds_1_ldb_ch1: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&mipi_lvds_1_ldb_ch1_mipi_lvds_1_pxl2dpi>;
+						status = "disabled";
+					};
+				};
+			};
+		};
+
+		mipi_lvds_1_ldb: ldb {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,imx8qxp-ldb";
+			clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_MISC2>,
+				 <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_BYPASS>;
+			clock-names = "pixel", "bypass";
+			assigned-clocks = <&clk IMX_SC_R_LVDS_1 IMX_SC_PM_CLK_MISC2>;
+			assigned-clock-parents = <&clk IMX_SC_R_